Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (74 commits)
  [SCSI] sg: fix q->queue_lock on scsi_error_handler path
  [SCSI] replace __inline with inline
  [SCSI] a2091: make 2 functions static
  [SCSI] a3000: make 2 functions static
  [SCSI] ses: #if 0 the unused ses_match_host()
  [SCSI] use kmem_cache_zalloc instead of kmem_cache_alloc/memset
  [SCSI] sg: fix iovec bugs introduced by the block layer conversion
  [SCSI] qlogicpti: use request_firmware
  [SCSI] advansys: use request_firmware
  [SCSI] qla1280: use request_firmware
  [SCSI] libiscsi: fix iscsi pool error path
  [SCSI] cxgb3i: call ddp release function directly
  [SCSI] cxgb3i: merge cxgb3i_ddp into cxgb3i module
  [SCSI] cxgb3i: close all tcp connections upon chip reset
  [SCSI] cxgb3i: re-read ddp settings information after chip reset
  [SCSI] cxgb3i: re-initialize ddp settings after chip reset
  [SCSI] cxgb3i: subscribe to error notification from cxgb3 driver
  [SCSI] aacraid driver update
  [SCSI] mptsas: remove unneeded check
  [SCSI] config: Make need for SCSI_CDROM clearer
  ...
diff --git a/CREDITS b/CREDITS
index 9a93e3e2..2520ba6 100644
--- a/CREDITS
+++ b/CREDITS
@@ -1412,8 +1412,8 @@
 D: National Language Support
 D: Linux Internationalization Project
 D: German Localization for Linux and GNU software
-S: Kriemhildring 12a
-S: 65795 Hattersheim am Main
+S: Auf der Fittel 18
+S: 53347 Alfter
 S: Germany
 
 N: Christoph Hellwig
@@ -3580,6 +3580,12 @@
 D: Co-author of German book ``Linux-Kernel-Programmierung''
 D: Co-founder of Berlin Linux User Group
 
+N: Riku Voipio
+E: riku.voipio@iki.fi
+D: Author of PCA9532 LED and Fintek f75375s hwmon driver
+D: Some random ARM board patches
+S: Finland
+
 N: Patrick Volkerding
 E: volkerdi@ftp.cdrom.com
 D: Produced the Slackware distribution, updated the SVGAlib
diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index 2a39aeb..d05737a 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -86,6 +86,8 @@
 	- describes the cache/TLB flushing interfaces Linux uses.
 cdrom/
 	- directory with information on the CD-ROM drivers that Linux has.
+cgroups/
+	- cgroups features, including cpusets and memory controller.
 connector/
 	- docs on the netlink based userspace<->kernel space communication mod.
 console/
@@ -98,8 +100,6 @@
 	- document describing how CPU load statistics are collected.
 cpuidle/
 	- info on CPU_IDLE, CPU idle state management subsystem.
-cpusets.txt
-	- documents the cpusets feature; assign CPUs and Mem to a set of tasks.
 cputopology.txt
 	- documentation on how CPU topology info is exported via sysfs.
 cris/
diff --git a/Documentation/ABI/testing/debugfs-kmemtrace b/Documentation/ABI/testing/debugfs-kmemtrace
new file mode 100644
index 0000000..5e6a92a
--- /dev/null
+++ b/Documentation/ABI/testing/debugfs-kmemtrace
@@ -0,0 +1,71 @@
+What:		/sys/kernel/debug/kmemtrace/
+Date:		July 2008
+Contact:	Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>
+Description:
+
+In kmemtrace-enabled kernels, the following files are created:
+
+/sys/kernel/debug/kmemtrace/
+	cpu<n>		(0400)	Per-CPU tracing data, see below. (binary)
+	total_overruns	(0400)	Total number of bytes which were dropped from
+				cpu<n> files because of full buffer condition,
+				non-binary. (text)
+	abi_version	(0400)	Kernel's kmemtrace ABI version. (text)
+
+Each per-CPU file should be read according to the relay interface. That is,
+the reader should set affinity to that specific CPU and, as currently done by
+the userspace application (though there are other methods), use poll() with
+an infinite timeout before every read(). Otherwise, erroneous data may be
+read. The binary data has the following _core_ format:
+
+	Event ID	(1 byte)	Unsigned integer, one of:
+		0 - represents an allocation (KMEMTRACE_EVENT_ALLOC)
+		1 - represents a freeing of previously allocated memory
+		    (KMEMTRACE_EVENT_FREE)
+	Type ID		(1 byte)	Unsigned integer, one of:
+		0 - this is a kmalloc() / kfree()
+		1 - this is a kmem_cache_alloc() / kmem_cache_free()
+		2 - this is a __get_free_pages() et al.
+	Event size	(2 bytes)	Unsigned integer representing the
+					size of this event. Used to extend
+					kmemtrace. Discard the bytes you
+					don't know about.
+	Sequence number	(4 bytes)	Signed integer used to reorder data
+					logged on SMP machines. Wraparound
+					must be taken into account, although
+					it is unlikely.
+	Caller address	(8 bytes)	Return address to the caller.
+	Pointer to mem	(8 bytes)	Pointer to target memory area. Can be
+					NULL, but not all such calls might be
+					recorded.
+
+In case of KMEMTRACE_EVENT_ALLOC events, the next fields follow:
+
+	Requested bytes	(8 bytes)	Total number of requested bytes,
+					unsigned, must not be zero.
+	Allocated bytes (8 bytes)	Total number of actually allocated
+					bytes, unsigned, must not be lower
+					than requested bytes.
+	Requested flags	(4 bytes)	GFP flags supplied by the caller.
+	Target CPU	(4 bytes)	Signed integer, valid for event id 1.
+					If equal to -1, target CPU is the same
+					as origin CPU, but the reverse might
+					not be true.
+
+The data is made available in the same endianness the machine has.
+
+Other event ids and type ids may be defined and added. Other fields may be
+added by increasing event size, but see below for details.
+Every modification to the ABI, including new id definitions, are followed
+by bumping the ABI version by one.
+
+Adding new data to the packet (features) is done at the end of the mandatory
+data:
+	Feature size	(2 byte)
+	Feature ID	(1 byte)
+	Feature data	(Feature size - 3 bytes)
+
+
+Users:
+	kmemtrace-user - git://repo.or.cz/kmemtrace-user.git
+
diff --git a/Documentation/ABI/testing/sysfs-class-regulator b/Documentation/ABI/testing/sysfs-class-regulator
index 873ef1f..e091fa8 100644
--- a/Documentation/ABI/testing/sysfs-class-regulator
+++ b/Documentation/ABI/testing/sysfs-class-regulator
@@ -4,8 +4,8 @@
 Contact:	Liam Girdwood <lrg@slimlogic.co.uk>
 Description:
 		Some regulator directories will contain a field called
-		state. This reports the regulator enable status, for
-		regulators which can report that value.
+		state. This reports the regulator enable control, for
+		regulators which can report that input value.
 
 		This will be one of the following strings:
 
@@ -14,16 +14,54 @@
 		'unknown'
 
 		'enabled' means the regulator output is ON and is supplying
-		power to the system.
+		power to the system (assuming no error prevents it).
 
 		'disabled' means the regulator output is OFF and is not
-		supplying power to the system..
+		supplying power to the system (unless some non-Linux
+		control has enabled it).
 
 		'unknown' means software cannot determine the state, or
 		the reported state is invalid.
 
 		NOTE: this field can be used in conjunction with microvolts
-		and microamps to determine regulator output levels.
+		or microamps to determine configured regulator output levels.
+
+
+What:		/sys/class/regulator/.../status
+Description:
+		Some regulator directories will contain a field called
+		"status". This reports the current regulator status, for
+		regulators which can report that output value.
+
+		This will be one of the following strings:
+
+			off
+			on
+			error
+			fast
+			normal
+			idle
+			standby
+
+		"off" means the regulator is not supplying power to the
+		system.
+
+		"on" means the regulator is supplying power to the system,
+		and the regulator can't report a detailed operation mode.
+
+		"error" indicates an out-of-regulation status such as being
+		disabled due to thermal shutdown, or voltage being unstable
+		because of problems with the input power supply.
+
+		"fast", "normal", "idle", and "standby" are all detailed
+		regulator operation modes (described elsewhere).  They
+		imply "on", but provide more detail.
+
+		Note that regulator status is a function of many inputs,
+		not limited to control inputs from Linux.  For example,
+		the actual load presented may trigger "error" status; or
+		a regulator may be enabled by another user, even though
+		Linux did not enable it.
 
 
 What:		/sys/class/regulator/.../type
@@ -58,7 +96,7 @@
 		Some regulator directories will contain a field called
 		microvolts. This holds the regulator output voltage setting
 		measured in microvolts (i.e. E-6 Volts), for regulators
-		which can report that voltage.
+		which can report the control input for voltage.
 
 		NOTE: This value should not be used to determine the regulator
 		output voltage level as this value is the same regardless of
@@ -73,7 +111,7 @@
 		Some regulator directories will contain a field called
 		microamps. This holds the regulator output current limit
 		setting measured in microamps (i.e. E-6 Amps), for regulators
-		which can report that current.
+		which can report the control input for a current limit.
 
 		NOTE: This value should not be used to determine the regulator
 		output current level as this value is the same regardless of
@@ -87,7 +125,7 @@
 Description:
 		Some regulator directories will contain a field called
 		opmode. This holds the current regulator operating mode,
-		for regulators which can report it.
+		for regulators which can report that control input value.
 
 		The opmode value can be one of the following strings:
 
@@ -101,7 +139,8 @@
 
 		NOTE: This value should not be used to determine the regulator
 		output operating mode as this value is the same regardless of
-		whether the regulator is enabled or disabled.
+		whether the regulator is enabled or disabled.  A "status"
+		attribute may be available to determine the actual mode.
 
 
 What:		/sys/class/regulator/.../min_microvolts
diff --git a/Documentation/RCU/listRCU.txt b/Documentation/RCU/listRCU.txt
index 1fd1753..4349c14 100644
--- a/Documentation/RCU/listRCU.txt
+++ b/Documentation/RCU/listRCU.txt
@@ -118,7 +118,7 @@
 		list_for_each_entry(e, list, list) {
 			if (!audit_compare_rule(rule, &e->rule)) {
 				list_del_rcu(&e->list);
-				call_rcu(&e->rcu, audit_free_rule, e);
+				call_rcu(&e->rcu, audit_free_rule);
 				return 0;
 			}
 		}
@@ -206,7 +206,7 @@
 				ne->rule.action = newaction;
 				ne->rule.file_count = newfield_count;
 				list_replace_rcu(e, ne);
-				call_rcu(&e->rcu, audit_free_rule, e);
+				call_rcu(&e->rcu, audit_free_rule);
 				return 0;
 			}
 		}
@@ -283,7 +283,7 @@
 				list_del_rcu(&e->list);
 				e->deleted = 1;
 				spin_unlock(&e->lock);
-				call_rcu(&e->rcu, audit_free_rule, e);
+				call_rcu(&e->rcu, audit_free_rule);
 				return 0;
 			}
 		}
diff --git a/Documentation/RCU/rcu.txt b/Documentation/RCU/rcu.txt
index 95821a2..7aa2002 100644
--- a/Documentation/RCU/rcu.txt
+++ b/Documentation/RCU/rcu.txt
@@ -81,7 +81,7 @@
 	This work is largely completed.  Realtime-friendly RCU can be
 	enabled via the CONFIG_PREEMPT_RCU kernel configuration parameter.
 	However, work is in progress for enabling priority boosting of
-	preempted RCU read-side critical sections.This is needed if you
+	preempted RCU read-side critical sections.  This is needed if you
 	have CPU-bound realtime threads.
 
 o	Where can I find more information on RCU?
diff --git a/Documentation/RCU/rculist_nulls.txt b/Documentation/RCU/rculist_nulls.txt
index 239f542..6389dec 100644
--- a/Documentation/RCU/rculist_nulls.txt
+++ b/Documentation/RCU/rculist_nulls.txt
@@ -21,7 +21,7 @@
   /*
    * Because a writer could delete object, and a writer could
    * reuse these object before the RCU grace period, we
-   * must check key after geting the reference on object
+   * must check key after getting the reference on object
    */
   if (obj->key != key) { // not the object we expected
      put_ref(obj);
@@ -117,7 +117,7 @@
 to another chain) checking the final 'nulls' value if
 the lookup met the end of chain. If final 'nulls' value
 is not the slot number, then we must restart the lookup at
-the begining. If the object was moved to same chain,
+the beginning. If the object was moved to the same chain,
 then the reader doesnt care : It might eventually
 scan the list again without harm.
 
diff --git a/Documentation/cgroups/00-INDEX b/Documentation/cgroups/00-INDEX
new file mode 100644
index 0000000..3f58fa3
--- /dev/null
+++ b/Documentation/cgroups/00-INDEX
@@ -0,0 +1,18 @@
+00-INDEX
+	- this file
+cgroups.txt
+	- Control Groups definition, implementation details, examples and API.
+cpuacct.txt
+	- CPU Accounting Controller; account CPU usage for groups of tasks.
+cpusets.txt
+	- documents the cpusets feature; assign CPUs and Mem to a set of tasks.
+devices.txt
+	- Device Whitelist Controller; description, interface and security.
+freezer-subsystem.txt
+	- checkpointing; rationale to not use signals, interface.
+memcg_test.txt
+	- Memory Resource Controller; implementation details.
+memory.txt
+	- Memory Resource Controller; design, accounting, interface, testing.
+resource_counter.txt
+	- Resource Counter API.
diff --git a/Documentation/cgroups/cgroups.txt b/Documentation/cgroups/cgroups.txt
index 4ea8523..6eb1a97 100644
--- a/Documentation/cgroups/cgroups.txt
+++ b/Documentation/cgroups/cgroups.txt
@@ -56,7 +56,7 @@
 state attached to each cgroup in the hierarchy.  Each hierarchy has
 an instance of the cgroup virtual filesystem associated with it.
 
-At any one time there may be multiple active hierachies of task
+At any one time there may be multiple active hierarchies of task
 cgroups. Each hierarchy is a partition of all tasks in the system.
 
 User level code may create and destroy cgroups by name in an
@@ -124,10 +124,10 @@
                                / \
                        Prof (15%) students (5%)
 
-Browsers like firefox/lynx go into the WWW network class, while (k)nfsd go
+Browsers like Firefox/Lynx go into the WWW network class, while (k)nfsd go
 into NFS network class.
 
-At the same time firefox/lynx will share an appropriate CPU/Memory class
+At the same time Firefox/Lynx will share an appropriate CPU/Memory class
 depending on who launched it (prof/student).
 
 With the ability to classify tasks differently for different resources
@@ -325,7 +325,7 @@
 Creating, modifying, using the cgroups can be done through the cgroup
 virtual filesystem.
 
-To mount a cgroup hierarchy will all available subsystems, type:
+To mount a cgroup hierarchy with all available subsystems, type:
 # mount -t cgroup xxx /dev/cgroup
 
 The "xxx" is not interpreted by the cgroup code, but will appear in
@@ -539,7 +539,7 @@
 void post_clone(struct cgroup_subsys *ss, struct cgroup *cgrp)
 (cgroup_mutex held by caller)
 
-Called at the end of cgroup_clone() to do any paramater
+Called at the end of cgroup_clone() to do any parameter
 initialization which might be required before a task could attach.  For
 example in cpusets, no task may attach before 'cpus' and 'mems' are set
 up.
diff --git a/Documentation/cgroups/cpusets.txt b/Documentation/cgroups/cpusets.txt
index 0611e95..f9ca389 100644
--- a/Documentation/cgroups/cpusets.txt
+++ b/Documentation/cgroups/cpusets.txt
@@ -131,7 +131,7 @@
  - The hierarchy of cpusets can be mounted at /dev/cpuset, for
    browsing and manipulation from user space.
  - A cpuset may be marked exclusive, which ensures that no other
-   cpuset (except direct ancestors and descendents) may contain
+   cpuset (except direct ancestors and descendants) may contain
    any overlapping CPUs or Memory Nodes.
  - You can list all the tasks (by pid) attached to any cpuset.
 
@@ -226,7 +226,7 @@
 --------------------------------
 
 If a cpuset is cpu or mem exclusive, no other cpuset, other than
-a direct ancestor or descendent, may share any of the same CPUs or
+a direct ancestor or descendant, may share any of the same CPUs or
 Memory Nodes.
 
 A cpuset that is mem_exclusive *or* mem_hardwall is "hardwalled",
@@ -427,7 +427,7 @@
 When doing this, you don't usually want to leave any unpinned tasks in
 the top cpuset that might use non-trivial amounts of CPU, as such tasks
 may be artificially constrained to some subset of CPUs, depending on
-the particulars of this flag setting in descendent cpusets.  Even if
+the particulars of this flag setting in descendant cpusets.  Even if
 such a task could use spare CPU cycles in some other CPUs, the kernel
 scheduler might not consider the possibility of load balancing that
 task to that underused CPU.
@@ -531,9 +531,9 @@
 
 Of course it takes some searching cost to find movable tasks and/or
 idle CPUs, the scheduler might not search all CPUs in the domain
-everytime.  In fact, in some architectures, the searching ranges on
+every time.  In fact, in some architectures, the searching ranges on
 events are limited in the same socket or node where the CPU locates,
-while the load balance on tick searchs all.
+while the load balance on tick searches all.
 
 For example, assume CPU Z is relatively far from CPU X.  Even if CPU Z
 is idle while CPU X and the siblings are busy, scheduler can't migrate
@@ -601,7 +601,7 @@
 of MPOL_BIND nodes are still allowed in the new cpuset.  If the task
 was using MPOL_BIND and now none of its MPOL_BIND nodes are allowed
 in the new cpuset, then the task will be essentially treated as if it
-was MPOL_BIND bound to the new cpuset (even though its numa placement,
+was MPOL_BIND bound to the new cpuset (even though its NUMA placement,
 as queried by get_mempolicy(), doesn't change).  If a task is moved
 from one cpuset to another, then the kernel will adjust the tasks
 memory placement, as above, the next time that the kernel attempts
diff --git a/Documentation/cgroups/devices.txt b/Documentation/cgroups/devices.txt
index 7cc6e6a..57ca4c8 100644
--- a/Documentation/cgroups/devices.txt
+++ b/Documentation/cgroups/devices.txt
@@ -42,7 +42,7 @@
 movement as people get some experience with this.  We may just want
 to require CAP_SYS_ADMIN, which at least is a separate bit from
 CAP_MKNOD.  We may want to just refuse moving to a cgroup which
-isn't a descendent of the current one.  Or we may want to use
+isn't a descendant of the current one.  Or we may want to use
 CAP_MAC_ADMIN, since we really are trying to lock down root.
 
 CAP_SYS_ADMIN is needed to modify the whitelist or move another
diff --git a/Documentation/cgroups/memcg_test.txt b/Documentation/cgroups/memcg_test.txt
index 8a11caf..72db89e 100644
--- a/Documentation/cgroups/memcg_test.txt
+++ b/Documentation/cgroups/memcg_test.txt
@@ -356,7 +356,7 @@
 	(Shell-B)
 	# move all tasks in /cgroup/test to /cgroup
 	# /sbin/swapoff -a
-	# rmdir /test/cgroup
+	# rmdir /cgroup/test
 	# kill malloc task.
 
 	Of course, tmpfs v.s. swapoff test should be tested, too.
diff --git a/Documentation/cgroups/memory.txt b/Documentation/cgroups/memory.txt
index e150196..a98a7fe 100644
--- a/Documentation/cgroups/memory.txt
+++ b/Documentation/cgroups/memory.txt
@@ -302,7 +302,7 @@
 	unevictable		- # of pages cannot be reclaimed.(mlocked etc)
 
 	Below is depend on CONFIG_DEBUG_VM.
-	inactive_ratio		- VM inernal parameter. (see mm/page_alloc.c)
+	inactive_ratio		- VM internal parameter. (see mm/page_alloc.c)
 	recent_rotated_anon	- VM internal parameter. (see mm/vmscan.c)
 	recent_rotated_file	- VM internal parameter. (see mm/vmscan.c)
 	recent_scanned_anon 	- VM internal parameter. (see mm/vmscan.c)
diff --git a/Documentation/devices.txt b/Documentation/devices.txt
index 62254d4..327de16 100644
--- a/Documentation/devices.txt
+++ b/Documentation/devices.txt
@@ -1,7 +1,7 @@
 
 		    LINUX ALLOCATED DEVICES (2.6+ version)
 
-	     Maintained by Torben Mathiasen <device@lanana.org>
+	     Maintained by Alan Cox <device@lanana.org>
 
 		      Last revised: 29 November 2006
 
@@ -67,6 +67,11 @@
 in "batch mode", so there is likely additional registrations that
 haven't been listed yet.
 
+Fourth, remember that Linux now has extensive support for dynamic allocation
+of device numbering and can use sysfs and udev to handle the naming needs.
+There are still some exceptions in the serial and boot device area. Before
+asking for a device number make sure you actually need one.
+
 Finally, sometimes I have to play "namespace police."  Please don't be
 offended.  I often get submissions for /dev names that would be bound
 to cause conflicts down the road.  I am trying to avoid getting in a
@@ -101,7 +106,7 @@
 		  0 = /dev/ram0		First RAM disk
 		  1 = /dev/ram1		Second RAM disk
 		    ...
-		250 = /dev/initrd	Initial RAM disk {2.6}
+		250 = /dev/initrd	Initial RAM disk
 
 		Older kernels had /dev/ramdisk (1, 1) here.
 		/dev/initrd refers to a RAM disk which was preloaded
@@ -340,7 +345,7 @@
 		 14 = /dev/touchscreen/ucb1x00  UCB 1x00 touchscreen
 		 15 = /dev/touchscreen/mk712	MK712 touchscreen
 		128 = /dev/beep		Fancy beep device
-		129 = /dev/modreq	Kernel module load request {2.6}
+		129 =
 		130 = /dev/watchdog	Watchdog timer port
 		131 = /dev/temperature	Machine internal temperature
 		132 = /dev/hwtrap	Hardware fault trap
@@ -350,10 +355,10 @@
 		139 = /dev/openprom	SPARC OpenBoot PROM
 		140 = /dev/relay8	Berkshire Products Octal relay card
 		141 = /dev/relay16	Berkshire Products ISO-16 relay card
-		142 = /dev/msr		x86 model-specific registers {2.6}
+		142 =
 		143 = /dev/pciconf	PCI configuration space
 		144 = /dev/nvram	Non-volatile configuration RAM
-		145 = /dev/hfmodem	Soundcard shortwave modem control {2.6}
+		145 = /dev/hfmodem	Soundcard shortwave modem control
 		146 = /dev/graphics	Linux/SGI graphics device
 		147 = /dev/opengl	Linux/SGI OpenGL pipe
 		148 = /dev/gfx		Linux/SGI graphics effects device
@@ -435,6 +440,9 @@
 		228 = /dev/hpet		HPET driver
 		229 = /dev/fuse		Fuse (virtual filesystem in user-space)
 		230 = /dev/midishare	MidiShare driver
+		231 = /dev/snapshot	System memory snapshot device
+		232 = /dev/kvm		Kernel-based virtual machine (hardware virtualization extensions)
+		233 = /dev/kmview	View-OS A process with a view
 		240-254			Reserved for local use
 		255			Reserved for MISC_DYNAMIC_MINOR
 
@@ -466,10 +474,7 @@
 		The device names specified are proposed -- if there
 		are "standard" names for these devices, please let me know.
 
- 12 block	MSCDEX CD-ROM callback support {2.6}
-		  0 = /dev/dos_cd0	First MSCDEX CD-ROM
-		  1 = /dev/dos_cd1	Second MSCDEX CD-ROM
-		    ...
+ 12 block
 
  13 char	Input core
 		  0 = /dev/input/js0	First joystick
@@ -498,7 +503,7 @@
 		  2 = /dev/midi00	First MIDI port
 		  3 = /dev/dsp		Digital audio
 		  4 = /dev/audio	Sun-compatible digital audio
-		  6 = /dev/sndstat	Sound card status information {2.6}
+		  6 =
 		  7 = /dev/audioctl	SPARC audio control device
 		  8 = /dev/sequencer2	Sequencer -- alternate device
 		 16 = /dev/mixer1	Second soundcard mixer control
@@ -510,14 +515,7 @@
 		 34 = /dev/midi02	Third MIDI port
 		 50 = /dev/midi03	Fourth MIDI port
 
- 14 block	BIOS harddrive callback support {2.6}
-		  0 = /dev/dos_hda	First BIOS harddrive whole disk
-		 64 = /dev/dos_hdb	Second BIOS harddrive whole disk
-		128 = /dev/dos_hdc	Third BIOS harddrive whole disk
-		192 = /dev/dos_hdd	Fourth BIOS harddrive whole disk
-
-		Partitions are handled in the same way as IDE disks
-		(see major number 3).
+ 14 block
 
  15 char	Joystick
 		  0 = /dev/js0		First analog joystick
@@ -535,14 +533,14 @@
  16 block	GoldStar CD-ROM
 		  0 = /dev/gscd		GoldStar CD-ROM
 
- 17 char	Chase serial card
+ 17 char	OBSOLETE (was Chase serial card)
 		  0 = /dev/ttyH0	First Chase port
 		  1 = /dev/ttyH1	Second Chase port
 		    ...
  17 block	Optics Storage CD-ROM
 		  0 = /dev/optcd	Optics Storage CD-ROM
 
- 18 char	Chase serial card - alternate devices
+ 18 char	OBSOLETE (was Chase serial card - alternate devices)
 		  0 = /dev/cuh0		Callout device for ttyH0
 		  1 = /dev/cuh1		Callout device for ttyH1
 		    ...
@@ -644,8 +642,7 @@
 		  2 = /dev/sbpcd2	Panasonic CD-ROM controller 0 unit 2
 		  3 = /dev/sbpcd3	Panasonic CD-ROM controller 0 unit 3
 
- 26 char	Quanta WinVision frame grabber {2.6}
-		  0 = /dev/wvisfgrab	Quanta WinVision frame grabber
+ 26 char
 
  26 block	Second Matsushita (Panasonic/SoundBlaster) CD-ROM
 		  0 = /dev/sbpcd4	Panasonic CD-ROM controller 1 unit 0
@@ -872,7 +869,7 @@
 		and "user level packet I/O."  This board is also
 		accessible as a standard networking "eth" device.
 
- 38 block	Reserved for Linux/AP+
+ 38 block	OBSOLETE (was Linux/AP+)
 
  39 char	ML-16P experimental I/O board
 		  0 = /dev/ml16pa-a0	First card, first analog channel
@@ -892,29 +889,16 @@
 		 50 = /dev/ml16pb-c1	Second card, second counter/timer
 		 51 = /dev/ml16pb-c2	Second card, third counter/timer
 		      ...
- 39 block	Reserved for Linux/AP+
+ 39 block
 
- 40 char	Matrox Meteor frame grabber {2.6}
-		  0 = /dev/mmetfgrab	Matrox Meteor frame grabber
+ 40 char
 
- 40 block	Syquest EZ135 parallel port removable drive
-		  0 = /dev/eza		Parallel EZ135 drive, whole disk
-
-		This device is obsolete and will be removed in a
-		future version of Linux.  It has been replaced with
-		the parallel port IDE disk driver at major number 45.
-		Partitions are handled in the same way as IDE disks
-		(see major number 3).
+ 40 block
 
  41 char	Yet Another Micro Monitor
 		  0 = /dev/yamm		Yet Another Micro Monitor
 
- 41 block	MicroSolutions BackPack parallel port CD-ROM
-		  0 = /dev/bpcd		BackPack CD-ROM
-
-		This device is obsolete and will be removed in a
-		future version of Linux.  It has been replaced with
-		the parallel port ATAPI CD-ROM driver at major number 46.
+ 41 block
 
  42 char	Demo/sample use
 
@@ -1681,13 +1665,7 @@
 		disks (see major number 3) except that the limit on
 		partitions is 15.
 
- 93 char	IBM Smart Capture Card frame grabber {2.6}
-		  0 = /dev/iscc0	First Smart Capture Card
-		  1 = /dev/iscc1	Second Smart Capture Card
-		    ...
-		128 = /dev/isccctl0	First Smart Capture Card control
-		129 = /dev/isccctl1	Second Smart Capture Card control
-		    ...
+ 93 char
 
  93 block	NAND Flash Translation Layer filesystem
 		  0 = /dev/nftla	First NFTL layer
@@ -1695,10 +1673,7 @@
 		    ...
 		240 = /dev/nftlp	16th NTFL layer
 
- 94 char	miroVIDEO DC10/30 capture/playback device {2.6}
-		  0 = /dev/dcxx0	First capture card
-		  1 = /dev/dcxx1	Second capture card
-		    ...
+ 94 char
 
  94 block	IBM S/390 DASD block storage
     		  0 = /dev/dasda First DASD device, major
@@ -1791,11 +1766,7 @@
 		    ...
 		 15 = /dev/amiraid/ar?p15 15th partition
 
-102 char	Philips SAA5249 Teletext signal decoder {2.6}
-		  0 = /dev/tlk0		First Teletext decoder
-		  1 = /dev/tlk1		Second Teletext decoder
-		  2 = /dev/tlk2		Third Teletext decoder
-		  3 = /dev/tlk3		Fourth Teletext decoder
+102 char
 
 102 block	Compressed block device
 		  0 = /dev/cbd/a	First compressed block device, whole device
@@ -1916,10 +1887,7 @@
 		DAC960 (see major number 48) except that the limit on
 		partitions is 15.
 
-111 char	Philips SAA7146-based audio/video card {2.6}
-		  0 = /dev/av0		First A/V card
-		  1 = /dev/av1		Second A/V card
-		    ...
+111 char
 
 111 block	Compaq Next Generation Drive Array, eighth controller
 		  0 = /dev/cciss/c7d0	First logical drive, whole disk
@@ -2079,8 +2047,8 @@
 		    ...
 
 119 char	VMware virtual network control
-		  0 = /dev/vmnet0	1st virtual network
-		  1 = /dev/vmnet1	2nd virtual network
+		  0 = /dev/vnet0	1st virtual network
+		  1 = /dev/vnet1	2nd virtual network
 		    ...
 
 120-127 char	LOCAL/EXPERIMENTAL USE
@@ -2450,7 +2418,7 @@
 		  2 = /dev/raw/raw2	Second raw I/O device
 		    ...
 
-163 char	UNASSIGNED (was Radio Tech BIM-XXX-RS232 radio modem - see 51)
+163 char
 
 164 char	Chase Research AT/PCI-Fast serial card
 		  0 = /dev/ttyCH0	AT/PCI-Fast board 0, port 0
@@ -2542,6 +2510,12 @@
 		  1 = /dev/clanvi1	Second cLAN adapter
 		    ...
 
+179 block       MMC block devices
+		  0 = /dev/mmcblk0      First SD/MMC card
+		  1 = /dev/mmcblk0p1    First partition on first MMC card
+		  8 = /dev/mmcblk1      Second SD/MMC card
+		    ...
+
 179 char	CCube DVXChip-based PCI products
 		  0 = /dev/dvxirq0	First DVX device
 		  1 = /dev/dvxirq1	Second DVX device
@@ -2560,6 +2534,9 @@
 		 96 = /dev/usb/hiddev0	1st USB HID device
 		    ...
 		111 = /dev/usb/hiddev15	16th USB HID device
+		112 = /dev/usb/auer0	1st auerswald ISDN device
+		    ...
+		127 = /dev/usb/auer15	16th auerswald ISDN device
 		128 = /dev/usb/brlvgr0	First Braille Voyager device
 		    ...
 		131 = /dev/usb/brlvgr3	Fourth Braille Voyager device
@@ -2810,6 +2787,16 @@
 		    ...
 		 190 = /dev/ttyUL3		Xilinx uartlite - port 3
 		 191 = /dev/xvc0		Xen virtual console - port 0
+		 192 = /dev/ttyPZ0		pmac_zilog - port 0
+		    ...
+		 195 = /dev/ttyPZ3		pmac_zilog - port 3
+		 196 = /dev/ttyTX0		TX39/49 serial port 0
+		    ...
+		 204 = /dev/ttyTX7		TX39/49 serial port 7
+		 205 = /dev/ttySC0		SC26xx serial port 0
+		 206 = /dev/ttySC1		SC26xx serial port 1
+		 207 = /dev/ttySC2		SC26xx serial port 2
+		 208 = /dev/ttySC3		SC26xx serial port 3
 
 205 char	Low-density serial ports (alternate device)
 		  0 = /dev/culu0		Callout device for ttyLU0
@@ -3145,6 +3132,14 @@
 		  1 = /dev/blockrom1	Second ROM card's translation layer interface
 		  ...
 
+259 block	Block Extended Major
+		  Used dynamically to hold additional partition minor
+		  numbers and allow large numbers of partitions per device
+
+259 char	FPGA configuration interfaces
+		  0 = /dev/icap0	First Xilinx internal configuration
+		  1 = /dev/icap1	Second Xilinx internal configuration
+
 260 char	OSD (Object-based-device) SCSI Device
 		  0 = /dev/osd0		First OSD Device
 		  1 = /dev/osd1		Second OSD Device
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index a23361e..39246fc 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -283,13 +283,6 @@
 
 ---------------------------
 
-What:	remove HID compat support
-When:	2.6.29
-Why:	needed only as a temporary solution until distros fix themselves up
-Who:	Jiri Slaby <jirislaby@gmail.com>
-
----------------------------
-
 What: print_fn_descriptor_symbol()
 When: October 2009
 Why:  The %pF vsprintf format provides the same functionality in a
diff --git a/Documentation/filesystems/caching/backend-api.txt b/Documentation/filesystems/caching/backend-api.txt
new file mode 100644
index 0000000..382d52c
--- /dev/null
+++ b/Documentation/filesystems/caching/backend-api.txt
@@ -0,0 +1,658 @@
+			  ==========================
+			  FS-CACHE CACHE BACKEND API
+			  ==========================
+
+The FS-Cache system provides an API by which actual caches can be supplied to
+FS-Cache for it to then serve out to network filesystems and other interested
+parties.
+
+This API is declared in <linux/fscache-cache.h>.
+
+
+====================================
+INITIALISING AND REGISTERING A CACHE
+====================================
+
+To start off, a cache definition must be initialised and registered for each
+cache the backend wants to make available.  For instance, CacheFS does this in
+the fill_super() operation on mounting.
+
+The cache definition (struct fscache_cache) should be initialised by calling:
+
+	void fscache_init_cache(struct fscache_cache *cache,
+				struct fscache_cache_ops *ops,
+				const char *idfmt,
+				...);
+
+Where:
+
+ (*) "cache" is a pointer to the cache definition;
+
+ (*) "ops" is a pointer to the table of operations that the backend supports on
+     this cache; and
+
+ (*) "idfmt" is a format and printf-style arguments for constructing a label
+     for the cache.
+
+
+The cache should then be registered with FS-Cache by passing a pointer to the
+previously initialised cache definition to:
+
+	int fscache_add_cache(struct fscache_cache *cache,
+			      struct fscache_object *fsdef,
+			      const char *tagname);
+
+Two extra arguments should also be supplied:
+
+ (*) "fsdef" which should point to the object representation for the FS-Cache
+     master index in this cache.  Netfs primary index entries will be created
+     here.  FS-Cache keeps the caller's reference to the index object if
+     successful and will release it upon withdrawal of the cache.
+
+ (*) "tagname" which, if given, should be a text string naming this cache.  If
+     this is NULL, the identifier will be used instead.  For CacheFS, the
+     identifier is set to name the underlying block device and the tag can be
+     supplied by mount.
+
+This function may return -ENOMEM if it ran out of memory or -EEXIST if the tag
+is already in use.  0 will be returned on success.
+
+
+=====================
+UNREGISTERING A CACHE
+=====================
+
+A cache can be withdrawn from the system by calling this function with a
+pointer to the cache definition:
+
+	void fscache_withdraw_cache(struct fscache_cache *cache);
+
+In CacheFS's case, this is called by put_super().
+
+
+========
+SECURITY
+========
+
+The cache methods are executed one of two contexts:
+
+ (1) that of the userspace process that issued the netfs operation that caused
+     the cache method to be invoked, or
+
+ (2) that of one of the processes in the FS-Cache thread pool.
+
+In either case, this may not be an appropriate context in which to access the
+cache.
+
+The calling process's fsuid, fsgid and SELinux security identities may need to
+be masqueraded for the duration of the cache driver's access to the cache.
+This is left to the cache to handle; FS-Cache makes no effort in this regard.
+
+
+===================================
+CONTROL AND STATISTICS PRESENTATION
+===================================
+
+The cache may present data to the outside world through FS-Cache's interfaces
+in sysfs and procfs - the former for control and the latter for statistics.
+
+A sysfs directory called /sys/fs/fscache/<cachetag>/ is created if CONFIG_SYSFS
+is enabled.  This is accessible through the kobject struct fscache_cache::kobj
+and is for use by the cache as it sees fit.
+
+
+========================
+RELEVANT DATA STRUCTURES
+========================
+
+ (*) Index/Data file FS-Cache representation cookie:
+
+	struct fscache_cookie {
+		struct fscache_object_def	*def;
+		struct fscache_netfs		*netfs;
+		void				*netfs_data;
+		...
+	};
+
+     The fields that might be of use to the backend describe the object
+     definition, the netfs definition and the netfs's data for this cookie.
+     The object definition contain functions supplied by the netfs for loading
+     and matching index entries; these are required to provide some of the
+     cache operations.
+
+
+ (*) In-cache object representation:
+
+	struct fscache_object {
+		int				debug_id;
+		enum {
+			FSCACHE_OBJECT_RECYCLING,
+			...
+		}				state;
+		spinlock_t			lock
+		struct fscache_cache		*cache;
+		struct fscache_cookie		*cookie;
+		...
+	};
+
+     Structures of this type should be allocated by the cache backend and
+     passed to FS-Cache when requested by the appropriate cache operation.  In
+     the case of CacheFS, they're embedded in CacheFS's internal object
+     structures.
+
+     The debug_id is a simple integer that can be used in debugging messages
+     that refer to a particular object.  In such a case it should be printed
+     using "OBJ%x" to be consistent with FS-Cache.
+
+     Each object contains a pointer to the cookie that represents the object it
+     is backing.  An object should retired when put_object() is called if it is
+     in state FSCACHE_OBJECT_RECYCLING.  The fscache_object struct should be
+     initialised by calling fscache_object_init(object).
+
+
+ (*) FS-Cache operation record:
+
+	struct fscache_operation {
+		atomic_t		usage;
+		struct fscache_object	*object;
+		unsigned long		flags;
+	#define FSCACHE_OP_EXCLUSIVE
+		void (*processor)(struct fscache_operation *op);
+		void (*release)(struct fscache_operation *op);
+		...
+	};
+
+     FS-Cache has a pool of threads that it uses to give CPU time to the
+     various asynchronous operations that need to be done as part of driving
+     the cache.  These are represented by the above structure.  The processor
+     method is called to give the op CPU time, and the release method to get
+     rid of it when its usage count reaches 0.
+
+     An operation can be made exclusive upon an object by setting the
+     appropriate flag before enqueuing it with fscache_enqueue_operation().  If
+     an operation needs more processing time, it should be enqueued again.
+
+
+ (*) FS-Cache retrieval operation record:
+
+	struct fscache_retrieval {
+		struct fscache_operation op;
+		struct address_space	*mapping;
+		struct list_head	*to_do;
+		...
+	};
+
+     A structure of this type is allocated by FS-Cache to record retrieval and
+     allocation requests made by the netfs.  This struct is then passed to the
+     backend to do the operation.  The backend may get extra refs to it by
+     calling fscache_get_retrieval() and refs may be discarded by calling
+     fscache_put_retrieval().
+
+     A retrieval operation can be used by the backend to do retrieval work.  To
+     do this, the retrieval->op.processor method pointer should be set
+     appropriately by the backend and fscache_enqueue_retrieval() called to
+     submit it to the thread pool.  CacheFiles, for example, uses this to queue
+     page examination when it detects PG_lock being cleared.
+
+     The to_do field is an empty list available for the cache backend to use as
+     it sees fit.
+
+
+ (*) FS-Cache storage operation record:
+
+	struct fscache_storage {
+		struct fscache_operation op;
+		pgoff_t			store_limit;
+		...
+	};
+
+     A structure of this type is allocated by FS-Cache to record outstanding
+     writes to be made.  FS-Cache itself enqueues this operation and invokes
+     the write_page() method on the object at appropriate times to effect
+     storage.
+
+
+================
+CACHE OPERATIONS
+================
+
+The cache backend provides FS-Cache with a table of operations that can be
+performed on the denizens of the cache.  These are held in a structure of type:
+
+	struct fscache_cache_ops
+
+ (*) Name of cache provider [mandatory]:
+
+	const char *name
+
+     This isn't strictly an operation, but should be pointed at a string naming
+     the backend.
+
+
+ (*) Allocate a new object [mandatory]:
+
+	struct fscache_object *(*alloc_object)(struct fscache_cache *cache,
+					       struct fscache_cookie *cookie)
+
+     This method is used to allocate a cache object representation to back a
+     cookie in a particular cache.  fscache_object_init() should be called on
+     the object to initialise it prior to returning.
+
+     This function may also be used to parse the index key to be used for
+     multiple lookup calls to turn it into a more convenient form.  FS-Cache
+     will call the lookup_complete() method to allow the cache to release the
+     form once lookup is complete or aborted.
+
+
+ (*) Look up and create object [mandatory]:
+
+	void (*lookup_object)(struct fscache_object *object)
+
+     This method is used to look up an object, given that the object is already
+     allocated and attached to the cookie.  This should instantiate that object
+     in the cache if it can.
+
+     The method should call fscache_object_lookup_negative() as soon as
+     possible if it determines the object doesn't exist in the cache.  If the
+     object is found to exist and the netfs indicates that it is valid then
+     fscache_obtained_object() should be called once the object is in a
+     position to have data stored in it.  Similarly, fscache_obtained_object()
+     should also be called once a non-present object has been created.
+
+     If a lookup error occurs, fscache_object_lookup_error() should be called
+     to abort the lookup of that object.
+
+
+ (*) Release lookup data [mandatory]:
+
+	void (*lookup_complete)(struct fscache_object *object)
+
+     This method is called to ask the cache to release any resources it was
+     using to perform a lookup.
+
+
+ (*) Increment object refcount [mandatory]:
+
+	struct fscache_object *(*grab_object)(struct fscache_object *object)
+
+     This method is called to increment the reference count on an object.  It
+     may fail (for instance if the cache is being withdrawn) by returning NULL.
+     It should return the object pointer if successful.
+
+
+ (*) Lock/Unlock object [mandatory]:
+
+	void (*lock_object)(struct fscache_object *object)
+	void (*unlock_object)(struct fscache_object *object)
+
+     These methods are used to exclusively lock an object.  It must be possible
+     to schedule with the lock held, so a spinlock isn't sufficient.
+
+
+ (*) Pin/Unpin object [optional]:
+
+	int (*pin_object)(struct fscache_object *object)
+	void (*unpin_object)(struct fscache_object *object)
+
+     These methods are used to pin an object into the cache.  Once pinned an
+     object cannot be reclaimed to make space.  Return -ENOSPC if there's not
+     enough space in the cache to permit this.
+
+
+ (*) Update object [mandatory]:
+
+	int (*update_object)(struct fscache_object *object)
+
+     This is called to update the index entry for the specified object.  The
+     new information should be in object->cookie->netfs_data.  This can be
+     obtained by calling object->cookie->def->get_aux()/get_attr().
+
+
+ (*) Discard object [mandatory]:
+
+	void (*drop_object)(struct fscache_object *object)
+
+     This method is called to indicate that an object has been unbound from its
+     cookie, and that the cache should release the object's resources and
+     retire it if it's in state FSCACHE_OBJECT_RECYCLING.
+
+     This method should not attempt to release any references held by the
+     caller.  The caller will invoke the put_object() method as appropriate.
+
+
+ (*) Release object reference [mandatory]:
+
+	void (*put_object)(struct fscache_object *object)
+
+     This method is used to discard a reference to an object.  The object may
+     be freed when all the references to it are released.
+
+
+ (*) Synchronise a cache [mandatory]:
+
+	void (*sync)(struct fscache_cache *cache)
+
+     This is called to ask the backend to synchronise a cache with its backing
+     device.
+
+
+ (*) Dissociate a cache [mandatory]:
+
+	void (*dissociate_pages)(struct fscache_cache *cache)
+
+     This is called to ask a cache to perform any page dissociations as part of
+     cache withdrawal.
+
+
+ (*) Notification that the attributes on a netfs file changed [mandatory]:
+
+	int (*attr_changed)(struct fscache_object *object);
+
+     This is called to indicate to the cache that certain attributes on a netfs
+     file have changed (for example the maximum size a file may reach).  The
+     cache can read these from the netfs by calling the cookie's get_attr()
+     method.
+
+     The cache may use the file size information to reserve space on the cache.
+     It should also call fscache_set_store_limit() to indicate to FS-Cache the
+     highest byte it's willing to store for an object.
+
+     This method may return -ve if an error occurred or the cache object cannot
+     be expanded.  In such a case, the object will be withdrawn from service.
+
+     This operation is run asynchronously from FS-Cache's thread pool, and
+     storage and retrieval operations from the netfs are excluded during the
+     execution of this operation.
+
+
+ (*) Reserve cache space for an object's data [optional]:
+
+	int (*reserve_space)(struct fscache_object *object, loff_t size);
+
+     This is called to request that cache space be reserved to hold the data
+     for an object and the metadata used to track it.  Zero size should be
+     taken as request to cancel a reservation.
+
+     This should return 0 if successful, -ENOSPC if there isn't enough space
+     available, or -ENOMEM or -EIO on other errors.
+
+     The reservation may exceed the current size of the object, thus permitting
+     future expansion.  If the amount of space consumed by an object would
+     exceed the reservation, it's permitted to refuse requests to allocate
+     pages, but not required.  An object may be pruned down to its reservation
+     size if larger than that already.
+
+
+ (*) Request page be read from cache [mandatory]:
+
+	int (*read_or_alloc_page)(struct fscache_retrieval *op,
+				  struct page *page,
+				  gfp_t gfp)
+
+     This is called to attempt to read a netfs page from the cache, or to
+     reserve a backing block if not.  FS-Cache will have done as much checking
+     as it can before calling, but most of the work belongs to the backend.
+
+     If there's no page in the cache, then -ENODATA should be returned if the
+     backend managed to reserve a backing block; -ENOBUFS or -ENOMEM if it
+     didn't.
+
+     If there is suitable data in the cache, then a read operation should be
+     queued and 0 returned.  When the read finishes, fscache_end_io() should be
+     called.
+
+     The fscache_mark_pages_cached() should be called for the page if any cache
+     metadata is retained.  This will indicate to the netfs that the page needs
+     explicit uncaching.  This operation takes a pagevec, thus allowing several
+     pages to be marked at once.
+
+     The retrieval record pointed to by op should be retained for each page
+     queued and released when I/O on the page has been formally ended.
+     fscache_get/put_retrieval() are available for this purpose.
+
+     The retrieval record may be used to get CPU time via the FS-Cache thread
+     pool.  If this is desired, the op->op.processor should be set to point to
+     the appropriate processing routine, and fscache_enqueue_retrieval() should
+     be called at an appropriate point to request CPU time.  For instance, the
+     retrieval routine could be enqueued upon the completion of a disk read.
+     The to_do field in the retrieval record is provided to aid in this.
+
+     If an I/O error occurs, fscache_io_error() should be called and -ENOBUFS
+     returned if possible or fscache_end_io() called with a suitable error
+     code..
+
+
+ (*) Request pages be read from cache [mandatory]:
+
+	int (*read_or_alloc_pages)(struct fscache_retrieval *op,
+				   struct list_head *pages,
+				   unsigned *nr_pages,
+				   gfp_t gfp)
+
+     This is like the read_or_alloc_page() method, except it is handed a list
+     of pages instead of one page.  Any pages on which a read operation is
+     started must be added to the page cache for the specified mapping and also
+     to the LRU.  Such pages must also be removed from the pages list and
+     *nr_pages decremented per page.
+
+     If there was an error such as -ENOMEM, then that should be returned; else
+     if one or more pages couldn't be read or allocated, then -ENOBUFS should
+     be returned; else if one or more pages couldn't be read, then -ENODATA
+     should be returned.  If all the pages are dispatched then 0 should be
+     returned.
+
+
+ (*) Request page be allocated in the cache [mandatory]:
+
+	int (*allocate_page)(struct fscache_retrieval *op,
+			     struct page *page,
+			     gfp_t gfp)
+
+     This is like the read_or_alloc_page() method, except that it shouldn't
+     read from the cache, even if there's data there that could be retrieved.
+     It should, however, set up any internal metadata required such that
+     the write_page() method can write to the cache.
+
+     If there's no backing block available, then -ENOBUFS should be returned
+     (or -ENOMEM if there were other problems).  If a block is successfully
+     allocated, then the netfs page should be marked and 0 returned.
+
+
+ (*) Request pages be allocated in the cache [mandatory]:
+
+	int (*allocate_pages)(struct fscache_retrieval *op,
+			      struct list_head *pages,
+			      unsigned *nr_pages,
+			      gfp_t gfp)
+
+     This is an multiple page version of the allocate_page() method.  pages and
+     nr_pages should be treated as for the read_or_alloc_pages() method.
+
+
+ (*) Request page be written to cache [mandatory]:
+
+	int (*write_page)(struct fscache_storage *op,
+			  struct page *page);
+
+     This is called to write from a page on which there was a previously
+     successful read_or_alloc_page() call or similar.  FS-Cache filters out
+     pages that don't have mappings.
+
+     This method is called asynchronously from the FS-Cache thread pool.  It is
+     not required to actually store anything, provided -ENODATA is then
+     returned to the next read of this page.
+
+     If an error occurred, then a negative error code should be returned,
+     otherwise zero should be returned.  FS-Cache will take appropriate action
+     in response to an error, such as withdrawing this object.
+
+     If this method returns success then FS-Cache will inform the netfs
+     appropriately.
+
+
+ (*) Discard retained per-page metadata [mandatory]:
+
+	void (*uncache_page)(struct fscache_object *object, struct page *page)
+
+     This is called when a netfs page is being evicted from the pagecache.  The
+     cache backend should tear down any internal representation or tracking it
+     maintains for this page.
+
+
+==================
+FS-CACHE UTILITIES
+==================
+
+FS-Cache provides some utilities that a cache backend may make use of:
+
+ (*) Note occurrence of an I/O error in a cache:
+
+	void fscache_io_error(struct fscache_cache *cache)
+
+     This tells FS-Cache that an I/O error occurred in the cache.  After this
+     has been called, only resource dissociation operations (object and page
+     release) will be passed from the netfs to the cache backend for the
+     specified cache.
+
+     This does not actually withdraw the cache.  That must be done separately.
+
+
+ (*) Invoke the retrieval I/O completion function:
+
+	void fscache_end_io(struct fscache_retrieval *op, struct page *page,
+			    int error);
+
+     This is called to note the end of an attempt to retrieve a page.  The
+     error value should be 0 if successful and an error otherwise.
+
+
+ (*) Set highest store limit:
+
+	void fscache_set_store_limit(struct fscache_object *object,
+				     loff_t i_size);
+
+     This sets the limit FS-Cache imposes on the highest byte it's willing to
+     try and store for a netfs.  Any page over this limit is automatically
+     rejected by fscache_read_alloc_page() and co with -ENOBUFS.
+
+
+ (*) Mark pages as being cached:
+
+	void fscache_mark_pages_cached(struct fscache_retrieval *op,
+				       struct pagevec *pagevec);
+
+     This marks a set of pages as being cached.  After this has been called,
+     the netfs must call fscache_uncache_page() to unmark the pages.
+
+
+ (*) Perform coherency check on an object:
+
+	enum fscache_checkaux fscache_check_aux(struct fscache_object *object,
+						const void *data,
+						uint16_t datalen);
+
+     This asks the netfs to perform a coherency check on an object that has
+     just been looked up.  The cookie attached to the object will determine the
+     netfs to use.  data and datalen should specify where the auxiliary data
+     retrieved from the cache can be found.
+
+     One of three values will be returned:
+
+	(*) FSCACHE_CHECKAUX_OKAY
+
+	    The coherency data indicates the object is valid as is.
+
+	(*) FSCACHE_CHECKAUX_NEEDS_UPDATE
+
+	    The coherency data needs updating, but otherwise the object is
+	    valid.
+
+	(*) FSCACHE_CHECKAUX_OBSOLETE
+
+	    The coherency data indicates that the object is obsolete and should
+	    be discarded.
+
+
+ (*) Initialise a freshly allocated object:
+
+	void fscache_object_init(struct fscache_object *object);
+
+     This initialises all the fields in an object representation.
+
+
+ (*) Indicate the destruction of an object:
+
+	void fscache_object_destroyed(struct fscache_cache *cache);
+
+     This must be called to inform FS-Cache that an object that belonged to a
+     cache has been destroyed and deallocated.  This will allow continuation
+     of the cache withdrawal process when it is stopped pending destruction of
+     all the objects.
+
+
+ (*) Indicate negative lookup on an object:
+
+	void fscache_object_lookup_negative(struct fscache_object *object);
+
+     This is called to indicate to FS-Cache that a lookup process for an object
+     found a negative result.
+
+     This changes the state of an object to permit reads pending on lookup
+     completion to go off and start fetching data from the netfs server as it's
+     known at this point that there can't be any data in the cache.
+
+     This may be called multiple times on an object.  Only the first call is
+     significant - all subsequent calls are ignored.
+
+
+ (*) Indicate an object has been obtained:
+
+	void fscache_obtained_object(struct fscache_object *object);
+
+     This is called to indicate to FS-Cache that a lookup process for an object
+     produced a positive result, or that an object was created.  This should
+     only be called once for any particular object.
+
+     This changes the state of an object to indicate:
+
+	(1) if no call to fscache_object_lookup_negative() has been made on
+	    this object, that there may be data available, and that reads can
+	    now go and look for it; and
+
+        (2) that writes may now proceed against this object.
+
+
+ (*) Indicate that object lookup failed:
+
+	void fscache_object_lookup_error(struct fscache_object *object);
+
+     This marks an object as having encountered a fatal error (usually EIO)
+     and causes it to move into a state whereby it will be withdrawn as soon
+     as possible.
+
+
+ (*) Get and release references on a retrieval record:
+
+	void fscache_get_retrieval(struct fscache_retrieval *op);
+	void fscache_put_retrieval(struct fscache_retrieval *op);
+
+     These two functions are used to retain a retrieval record whilst doing
+     asynchronous data retrieval and block allocation.
+
+
+ (*) Enqueue a retrieval record for processing.
+
+	void fscache_enqueue_retrieval(struct fscache_retrieval *op);
+
+     This enqueues a retrieval record for processing by the FS-Cache thread
+     pool.  One of the threads in the pool will invoke the retrieval record's
+     op->op.processor callback function.  This function may be called from
+     within the callback function.
+
+
+ (*) List of object state names:
+
+	const char *fscache_object_states[];
+
+     For debugging purposes, this may be used to turn the state that an object
+     is in into a text string for display purposes.
diff --git a/Documentation/filesystems/caching/cachefiles.txt b/Documentation/filesystems/caching/cachefiles.txt
new file mode 100644
index 0000000..c78a49b
--- /dev/null
+++ b/Documentation/filesystems/caching/cachefiles.txt
@@ -0,0 +1,501 @@
+	       ===============================================
+	       CacheFiles: CACHE ON ALREADY MOUNTED FILESYSTEM
+	       ===============================================
+
+Contents:
+
+ (*) Overview.
+
+ (*) Requirements.
+
+ (*) Configuration.
+
+ (*) Starting the cache.
+
+ (*) Things to avoid.
+
+ (*) Cache culling.
+
+ (*) Cache structure.
+
+ (*) Security model and SELinux.
+
+ (*) A note on security.
+
+ (*) Statistical information.
+
+ (*) Debugging.
+
+
+========
+OVERVIEW
+========
+
+CacheFiles is a caching backend that's meant to use as a cache a directory on
+an already mounted filesystem of a local type (such as Ext3).
+
+CacheFiles uses a userspace daemon to do some of the cache management - such as
+reaping stale nodes and culling.  This is called cachefilesd and lives in
+/sbin.
+
+The filesystem and data integrity of the cache are only as good as those of the
+filesystem providing the backing services.  Note that CacheFiles does not
+attempt to journal anything since the journalling interfaces of the various
+filesystems are very specific in nature.
+
+CacheFiles creates a misc character device - "/dev/cachefiles" - that is used
+to communication with the daemon.  Only one thing may have this open at once,
+and whilst it is open, a cache is at least partially in existence.  The daemon
+opens this and sends commands down it to control the cache.
+
+CacheFiles is currently limited to a single cache.
+
+CacheFiles attempts to maintain at least a certain percentage of free space on
+the filesystem, shrinking the cache by culling the objects it contains to make
+space if necessary - see the "Cache Culling" section.  This means it can be
+placed on the same medium as a live set of data, and will expand to make use of
+spare space and automatically contract when the set of data requires more
+space.
+
+
+============
+REQUIREMENTS
+============
+
+The use of CacheFiles and its daemon requires the following features to be
+available in the system and in the cache filesystem:
+
+	- dnotify.
+
+	- extended attributes (xattrs).
+
+	- openat() and friends.
+
+	- bmap() support on files in the filesystem (FIBMAP ioctl).
+
+	- The use of bmap() to detect a partial page at the end of the file.
+
+It is strongly recommended that the "dir_index" option is enabled on Ext3
+filesystems being used as a cache.
+
+
+=============
+CONFIGURATION
+=============
+
+The cache is configured by a script in /etc/cachefilesd.conf.  These commands
+set up cache ready for use.  The following script commands are available:
+
+ (*) brun <N>%
+ (*) bcull <N>%
+ (*) bstop <N>%
+ (*) frun <N>%
+ (*) fcull <N>%
+ (*) fstop <N>%
+
+	Configure the culling limits.  Optional.  See the section on culling
+	The defaults are 7% (run), 5% (cull) and 1% (stop) respectively.
+
+	The commands beginning with a 'b' are file space (block) limits, those
+	beginning with an 'f' are file count limits.
+
+ (*) dir <path>
+
+	Specify the directory containing the root of the cache.  Mandatory.
+
+ (*) tag <name>
+
+	Specify a tag to FS-Cache to use in distinguishing multiple caches.
+	Optional.  The default is "CacheFiles".
+
+ (*) debug <mask>
+
+	Specify a numeric bitmask to control debugging in the kernel module.
+	Optional.  The default is zero (all off).  The following values can be
+	OR'd into the mask to collect various information:
+
+		1	Turn on trace of function entry (_enter() macros)
+		2	Turn on trace of function exit (_leave() macros)
+		4	Turn on trace of internal debug points (_debug())
+
+	This mask can also be set through sysfs, eg:
+
+		echo 5 >/sys/modules/cachefiles/parameters/debug
+
+
+==================
+STARTING THE CACHE
+==================
+
+The cache is started by running the daemon.  The daemon opens the cache device,
+configures the cache and tells it to begin caching.  At that point the cache
+binds to fscache and the cache becomes live.
+
+The daemon is run as follows:
+
+	/sbin/cachefilesd [-d]* [-s] [-n] [-f <configfile>]
+
+The flags are:
+
+ (*) -d
+
+	Increase the debugging level.  This can be specified multiple times and
+	is cumulative with itself.
+
+ (*) -s
+
+	Send messages to stderr instead of syslog.
+
+ (*) -n
+
+	Don't daemonise and go into background.
+
+ (*) -f <configfile>
+
+	Use an alternative configuration file rather than the default one.
+
+
+===============
+THINGS TO AVOID
+===============
+
+Do not mount other things within the cache as this will cause problems.  The
+kernel module contains its own very cut-down path walking facility that ignores
+mountpoints, but the daemon can't avoid them.
+
+Do not create, rename or unlink files and directories in the cache whilst the
+cache is active, as this may cause the state to become uncertain.
+
+Renaming files in the cache might make objects appear to be other objects (the
+filename is part of the lookup key).
+
+Do not change or remove the extended attributes attached to cache files by the
+cache as this will cause the cache state management to get confused.
+
+Do not create files or directories in the cache, lest the cache get confused or
+serve incorrect data.
+
+Do not chmod files in the cache.  The module creates things with minimal
+permissions to prevent random users being able to access them directly.
+
+
+=============
+CACHE CULLING
+=============
+
+The cache may need culling occasionally to make space.  This involves
+discarding objects from the cache that have been used less recently than
+anything else.  Culling is based on the access time of data objects.  Empty
+directories are culled if not in use.
+
+Cache culling is done on the basis of the percentage of blocks and the
+percentage of files available in the underlying filesystem.  There are six
+"limits":
+
+ (*) brun
+ (*) frun
+
+     If the amount of free space and the number of available files in the cache
+     rises above both these limits, then culling is turned off.
+
+ (*) bcull
+ (*) fcull
+
+     If the amount of available space or the number of available files in the
+     cache falls below either of these limits, then culling is started.
+
+ (*) bstop
+ (*) fstop
+
+     If the amount of available space or the number of available files in the
+     cache falls below either of these limits, then no further allocation of
+     disk space or files is permitted until culling has raised things above
+     these limits again.
+
+These must be configured thusly:
+
+	0 <= bstop < bcull < brun < 100
+	0 <= fstop < fcull < frun < 100
+
+Note that these are percentages of available space and available files, and do
+_not_ appear as 100 minus the percentage displayed by the "df" program.
+
+The userspace daemon scans the cache to build up a table of cullable objects.
+These are then culled in least recently used order.  A new scan of the cache is
+started as soon as space is made in the table.  Objects will be skipped if
+their atimes have changed or if the kernel module says it is still using them.
+
+
+===============
+CACHE STRUCTURE
+===============
+
+The CacheFiles module will create two directories in the directory it was
+given:
+
+ (*) cache/
+
+ (*) graveyard/
+
+The active cache objects all reside in the first directory.  The CacheFiles
+kernel module moves any retired or culled objects that it can't simply unlink
+to the graveyard from which the daemon will actually delete them.
+
+The daemon uses dnotify to monitor the graveyard directory, and will delete
+anything that appears therein.
+
+
+The module represents index objects as directories with the filename "I..." or
+"J...".  Note that the "cache/" directory is itself a special index.
+
+Data objects are represented as files if they have no children, or directories
+if they do.  Their filenames all begin "D..." or "E...".  If represented as a
+directory, data objects will have a file in the directory called "data" that
+actually holds the data.
+
+Special objects are similar to data objects, except their filenames begin
+"S..." or "T...".
+
+
+If an object has children, then it will be represented as a directory.
+Immediately in the representative directory are a collection of directories
+named for hash values of the child object keys with an '@' prepended.  Into
+this directory, if possible, will be placed the representations of the child
+objects:
+
+	INDEX     INDEX      INDEX                             DATA FILES
+	========= ========== ================================= ================
+	cache/@4a/I03nfs/@30/Ji000000000000000--fHg8hi8400
+	cache/@4a/I03nfs/@30/Ji000000000000000--fHg8hi8400/@75/Es0g000w...DB1ry
+	cache/@4a/I03nfs/@30/Ji000000000000000--fHg8hi8400/@75/Es0g000w...N22ry
+	cache/@4a/I03nfs/@30/Ji000000000000000--fHg8hi8400/@75/Es0g000w...FP1ry
+
+
+If the key is so long that it exceeds NAME_MAX with the decorations added on to
+it, then it will be cut into pieces, the first few of which will be used to
+make a nest of directories, and the last one of which will be the objects
+inside the last directory.  The names of the intermediate directories will have
+'+' prepended:
+
+	J1223/@23/+xy...z/+kl...m/Epqr
+
+
+Note that keys are raw data, and not only may they exceed NAME_MAX in size,
+they may also contain things like '/' and NUL characters, and so they may not
+be suitable for turning directly into a filename.
+
+To handle this, CacheFiles will use a suitably printable filename directly and
+"base-64" encode ones that aren't directly suitable.  The two versions of
+object filenames indicate the encoding:
+
+	OBJECT TYPE	PRINTABLE	ENCODED
+	===============	===============	===============
+	Index		"I..."		"J..."
+	Data		"D..."		"E..."
+	Special		"S..."		"T..."
+
+Intermediate directories are always "@" or "+" as appropriate.
+
+
+Each object in the cache has an extended attribute label that holds the object
+type ID (required to distinguish special objects) and the auxiliary data from
+the netfs.  The latter is used to detect stale objects in the cache and update
+or retire them.
+
+
+Note that CacheFiles will erase from the cache any file it doesn't recognise or
+any file of an incorrect type (such as a FIFO file or a device file).
+
+
+==========================
+SECURITY MODEL AND SELINUX
+==========================
+
+CacheFiles is implemented to deal properly with the LSM security features of
+the Linux kernel and the SELinux facility.
+
+One of the problems that CacheFiles faces is that it is generally acting on
+behalf of a process, and running in that process's context, and that includes a
+security context that is not appropriate for accessing the cache - either
+because the files in the cache are inaccessible to that process, or because if
+the process creates a file in the cache, that file may be inaccessible to other
+processes.
+
+The way CacheFiles works is to temporarily change the security context (fsuid,
+fsgid and actor security label) that the process acts as - without changing the
+security context of the process when it the target of an operation performed by
+some other process (so signalling and suchlike still work correctly).
+
+
+When the CacheFiles module is asked to bind to its cache, it:
+
+ (1) Finds the security label attached to the root cache directory and uses
+     that as the security label with which it will create files.  By default,
+     this is:
+
+	cachefiles_var_t
+
+ (2) Finds the security label of the process which issued the bind request
+     (presumed to be the cachefilesd daemon), which by default will be:
+
+	cachefilesd_t
+
+     and asks LSM to supply a security ID as which it should act given the
+     daemon's label.  By default, this will be:
+
+	cachefiles_kernel_t
+
+     SELinux transitions the daemon's security ID to the module's security ID
+     based on a rule of this form in the policy.
+
+	type_transition <daemon's-ID> kernel_t : process <module's-ID>;
+
+     For instance:
+
+	type_transition cachefilesd_t kernel_t : process cachefiles_kernel_t;
+
+
+The module's security ID gives it permission to create, move and remove files
+and directories in the cache, to find and access directories and files in the
+cache, to set and access extended attributes on cache objects, and to read and
+write files in the cache.
+
+The daemon's security ID gives it only a very restricted set of permissions: it
+may scan directories, stat files and erase files and directories.  It may
+not read or write files in the cache, and so it is precluded from accessing the
+data cached therein; nor is it permitted to create new files in the cache.
+
+
+There are policy source files available in:
+
+	http://people.redhat.com/~dhowells/fscache/cachefilesd-0.8.tar.bz2
+
+and later versions.  In that tarball, see the files:
+
+	cachefilesd.te
+	cachefilesd.fc
+	cachefilesd.if
+
+They are built and installed directly by the RPM.
+
+If a non-RPM based system is being used, then copy the above files to their own
+directory and run:
+
+	make -f /usr/share/selinux/devel/Makefile
+	semodule -i cachefilesd.pp
+
+You will need checkpolicy and selinux-policy-devel installed prior to the
+build.
+
+
+By default, the cache is located in /var/fscache, but if it is desirable that
+it should be elsewhere, than either the above policy files must be altered, or
+an auxiliary policy must be installed to label the alternate location of the
+cache.
+
+For instructions on how to add an auxiliary policy to enable the cache to be
+located elsewhere when SELinux is in enforcing mode, please see:
+
+	/usr/share/doc/cachefilesd-*/move-cache.txt
+
+When the cachefilesd rpm is installed; alternatively, the document can be found
+in the sources.
+
+
+==================
+A NOTE ON SECURITY
+==================
+
+CacheFiles makes use of the split security in the task_struct.  It allocates
+its own task_security structure, and redirects current->act_as to point to it
+when it acts on behalf of another process, in that process's context.
+
+The reason it does this is that it calls vfs_mkdir() and suchlike rather than
+bypassing security and calling inode ops directly.  Therefore the VFS and LSM
+may deny the CacheFiles access to the cache data because under some
+circumstances the caching code is running in the security context of whatever
+process issued the original syscall on the netfs.
+
+Furthermore, should CacheFiles create a file or directory, the security
+parameters with that object is created (UID, GID, security label) would be
+derived from that process that issued the system call, thus potentially
+preventing other processes from accessing the cache - including CacheFiles's
+cache management daemon (cachefilesd).
+
+What is required is to temporarily override the security of the process that
+issued the system call.  We can't, however, just do an in-place change of the
+security data as that affects the process as an object, not just as a subject.
+This means it may lose signals or ptrace events for example, and affects what
+the process looks like in /proc.
+
+So CacheFiles makes use of a logical split in the security between the
+objective security (task->sec) and the subjective security (task->act_as).  The
+objective security holds the intrinsic security properties of a process and is
+never overridden.  This is what appears in /proc, and is what is used when a
+process is the target of an operation by some other process (SIGKILL for
+example).
+
+The subjective security holds the active security properties of a process, and
+may be overridden.  This is not seen externally, and is used whan a process
+acts upon another object, for example SIGKILLing another process or opening a
+file.
+
+LSM hooks exist that allow SELinux (or Smack or whatever) to reject a request
+for CacheFiles to run in a context of a specific security label, or to create
+files and directories with another security label.
+
+
+=======================
+STATISTICAL INFORMATION
+=======================
+
+If FS-Cache is compiled with the following option enabled:
+
+	CONFIG_CACHEFILES_HISTOGRAM=y
+
+then it will gather certain statistics and display them through a proc file.
+
+ (*) /proc/fs/cachefiles/histogram
+
+	cat /proc/fs/cachefiles/histogram
+	JIFS  SECS  LOOKUPS   MKDIRS    CREATES
+	===== ===== ========= ========= =========
+
+     This shows the breakdown of the number of times each amount of time
+     between 0 jiffies and HZ-1 jiffies a variety of tasks took to run.  The
+     columns are as follows:
+
+	COLUMN		TIME MEASUREMENT
+	=======		=======================================================
+	LOOKUPS		Length of time to perform a lookup on the backing fs
+	MKDIRS		Length of time to perform a mkdir on the backing fs
+	CREATES		Length of time to perform a create on the backing fs
+
+     Each row shows the number of events that took a particular range of times.
+     Each step is 1 jiffy in size.  The JIFS column indicates the particular
+     jiffy range covered, and the SECS field the equivalent number of seconds.
+
+
+=========
+DEBUGGING
+=========
+
+If CONFIG_CACHEFILES_DEBUG is enabled, the CacheFiles facility can have runtime
+debugging enabled by adjusting the value in:
+
+	/sys/module/cachefiles/parameters/debug
+
+This is a bitmask of debugging streams to enable:
+
+	BIT	VALUE	STREAM				POINT
+	=======	=======	===============================	=======================
+	0	1	General				Function entry trace
+	1	2					Function exit trace
+	2	4					General
+
+The appropriate set of values should be OR'd together and the result written to
+the control file.  For example:
+
+	echo $((1|4|8)) >/sys/module/cachefiles/parameters/debug
+
+will turn on all function entry debugging.
diff --git a/Documentation/filesystems/caching/fscache.txt b/Documentation/filesystems/caching/fscache.txt
new file mode 100644
index 0000000..9e94b94
--- /dev/null
+++ b/Documentation/filesystems/caching/fscache.txt
@@ -0,0 +1,333 @@
+			  ==========================
+			  General Filesystem Caching
+			  ==========================
+
+========
+OVERVIEW
+========
+
+This facility is a general purpose cache for network filesystems, though it
+could be used for caching other things such as ISO9660 filesystems too.
+
+FS-Cache mediates between cache backends (such as CacheFS) and network
+filesystems:
+
+	+---------+
+	|         |                        +--------------+
+	|   NFS   |--+                     |              |
+	|         |  |                 +-->|   CacheFS    |
+	+---------+  |   +----------+  |   |  /dev/hda5   |
+	             |   |          |  |   +--------------+
+	+---------+  +-->|          |  |
+	|         |      |          |--+
+	|   AFS   |----->| FS-Cache |
+	|         |      |          |--+
+	+---------+  +-->|          |  |
+	             |   |          |  |   +--------------+
+	+---------+  |   +----------+  |   |              |
+	|         |  |                 +-->|  CacheFiles  |
+	|  ISOFS  |--+                     |  /var/cache  |
+	|         |                        +--------------+
+	+---------+
+
+Or to look at it another way, FS-Cache is a module that provides a caching
+facility to a network filesystem such that the cache is transparent to the
+user:
+
+	+---------+
+	|         |
+	| Server  |
+	|         |
+	+---------+
+	     |                  NETWORK
+	~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	     |
+	     |           +----------+
+	     V           |          |
+	+---------+      |          |
+	|         |      |          |
+	|   NFS   |----->| FS-Cache |
+	|         |      |          |--+
+	+---------+      |          |  |   +--------------+   +--------------+
+	     |           |          |  |   |              |   |              |
+	     V           +----------+  +-->|  CacheFiles  |-->|  Ext3        |
+	+---------+                        |  /var/cache  |   |  /dev/sda6   |
+	|         |                        +--------------+   +--------------+
+	|   VFS   |                                ^                     ^
+	|         |                                |                     |
+	+---------+                                +--------------+      |
+	     |                  KERNEL SPACE                      |      |
+	~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~|~~~~
+	     |                  USER SPACE                        |      |
+	     V                                                    |      |
+	+---------+                                           +--------------+
+	|         |                                           |              |
+	| Process |                                           | cachefilesd  |
+	|         |                                           |              |
+	+---------+                                           +--------------+
+
+
+FS-Cache does not follow the idea of completely loading every netfs file
+opened in its entirety into a cache before permitting it to be accessed and
+then serving the pages out of that cache rather than the netfs inode because:
+
+ (1) It must be practical to operate without a cache.
+
+ (2) The size of any accessible file must not be limited to the size of the
+     cache.
+
+ (3) The combined size of all opened files (this includes mapped libraries)
+     must not be limited to the size of the cache.
+
+ (4) The user should not be forced to download an entire file just to do a
+     one-off access of a small portion of it (such as might be done with the
+     "file" program).
+
+It instead serves the cache out in PAGE_SIZE chunks as and when requested by
+the netfs('s) using it.
+
+
+FS-Cache provides the following facilities:
+
+ (1) More than one cache can be used at once.  Caches can be selected
+     explicitly by use of tags.
+
+ (2) Caches can be added / removed at any time.
+
+ (3) The netfs is provided with an interface that allows either party to
+     withdraw caching facilities from a file (required for (2)).
+
+ (4) The interface to the netfs returns as few errors as possible, preferring
+     rather to let the netfs remain oblivious.
+
+ (5) Cookies are used to represent indices, files and other objects to the
+     netfs.  The simplest cookie is just a NULL pointer - indicating nothing
+     cached there.
+
+ (6) The netfs is allowed to propose - dynamically - any index hierarchy it
+     desires, though it must be aware that the index search function is
+     recursive, stack space is limited, and indices can only be children of
+     indices.
+
+ (7) Data I/O is done direct to and from the netfs's pages.  The netfs
+     indicates that page A is at index B of the data-file represented by cookie
+     C, and that it should be read or written.  The cache backend may or may
+     not start I/O on that page, but if it does, a netfs callback will be
+     invoked to indicate completion.  The I/O may be either synchronous or
+     asynchronous.
+
+ (8) Cookies can be "retired" upon release.  At this point FS-Cache will mark
+     them as obsolete and the index hierarchy rooted at that point will get
+     recycled.
+
+ (9) The netfs provides a "match" function for index searches.  In addition to
+     saying whether a match was made or not, this can also specify that an
+     entry should be updated or deleted.
+
+(10) As much as possible is done asynchronously.
+
+
+FS-Cache maintains a virtual indexing tree in which all indices, files, objects
+and pages are kept.  Bits of this tree may actually reside in one or more
+caches.
+
+                                           FSDEF
+                                             |
+                        +------------------------------------+
+                        |                                    |
+                       NFS                                  AFS
+                        |                                    |
+           +--------------------------+                +-----------+
+           |                          |                |           |
+        homedir                     mirror          afs.org   redhat.com
+           |                          |                            |
+     +------------+           +---------------+              +----------+
+     |            |           |               |              |          |
+   00001        00002       00007           00125        vol00001   vol00002
+     |            |           |               |                         |
+ +---+---+     +-----+      +---+      +------+------+            +-----+----+
+ |   |   |     |     |      |   |      |      |      |            |     |    |
+PG0 PG1 PG2   PG0  XATTR   PG0 PG1   DIRENT DIRENT DIRENT        R/W   R/O  Bak
+                     |                                            |
+                    PG0                                       +-------+
+                                                              |       |
+                                                            00001   00003
+                                                              |
+                                                          +---+---+
+                                                          |   |   |
+                                                         PG0 PG1 PG2
+
+In the example above, you can see two netfs's being backed: NFS and AFS.  These
+have different index hierarchies:
+
+ (*) The NFS primary index contains per-server indices.  Each server index is
+     indexed by NFS file handles to get data file objects.  Each data file
+     objects can have an array of pages, but may also have further child
+     objects, such as extended attributes and directory entries.  Extended
+     attribute objects themselves have page-array contents.
+
+ (*) The AFS primary index contains per-cell indices.  Each cell index contains
+     per-logical-volume indices.  Each of volume index contains up to three
+     indices for the read-write, read-only and backup mirrors of those volumes.
+     Each of these contains vnode data file objects, each of which contains an
+     array of pages.
+
+The very top index is the FS-Cache master index in which individual netfs's
+have entries.
+
+Any index object may reside in more than one cache, provided it only has index
+children.  Any index with non-index object children will be assumed to only
+reside in one cache.
+
+
+The netfs API to FS-Cache can be found in:
+
+	Documentation/filesystems/caching/netfs-api.txt
+
+The cache backend API to FS-Cache can be found in:
+
+	Documentation/filesystems/caching/backend-api.txt
+
+A description of the internal representations and object state machine can be
+found in:
+
+	Documentation/filesystems/caching/object.txt
+
+
+=======================
+STATISTICAL INFORMATION
+=======================
+
+If FS-Cache is compiled with the following options enabled:
+
+	CONFIG_FSCACHE_STATS=y
+	CONFIG_FSCACHE_HISTOGRAM=y
+
+then it will gather certain statistics and display them through a number of
+proc files.
+
+ (*) /proc/fs/fscache/stats
+
+     This shows counts of a number of events that can happen in FS-Cache:
+
+	CLASS	EVENT	MEANING
+	=======	=======	=======================================================
+	Cookies	idx=N	Number of index cookies allocated
+		dat=N	Number of data storage cookies allocated
+		spc=N	Number of special cookies allocated
+	Objects	alc=N	Number of objects allocated
+		nal=N	Number of object allocation failures
+		avl=N	Number of objects that reached the available state
+		ded=N	Number of objects that reached the dead state
+	ChkAux	non=N	Number of objects that didn't have a coherency check
+		ok=N	Number of objects that passed a coherency check
+		upd=N	Number of objects that needed a coherency data update
+		obs=N	Number of objects that were declared obsolete
+	Pages	mrk=N	Number of pages marked as being cached
+		unc=N	Number of uncache page requests seen
+	Acquire	n=N	Number of acquire cookie requests seen
+		nul=N	Number of acq reqs given a NULL parent
+		noc=N	Number of acq reqs rejected due to no cache available
+		ok=N	Number of acq reqs succeeded
+		nbf=N	Number of acq reqs rejected due to error
+		oom=N	Number of acq reqs failed on ENOMEM
+	Lookups	n=N	Number of lookup calls made on cache backends
+		neg=N	Number of negative lookups made
+		pos=N	Number of positive lookups made
+		crt=N	Number of objects created by lookup
+	Updates	n=N	Number of update cookie requests seen
+		nul=N	Number of upd reqs given a NULL parent
+		run=N	Number of upd reqs granted CPU time
+	Relinqs	n=N	Number of relinquish cookie requests seen
+		nul=N	Number of rlq reqs given a NULL parent
+		wcr=N	Number of rlq reqs waited on completion of creation
+	AttrChg	n=N	Number of attribute changed requests seen
+		ok=N	Number of attr changed requests queued
+		nbf=N	Number of attr changed rejected -ENOBUFS
+		oom=N	Number of attr changed failed -ENOMEM
+		run=N	Number of attr changed ops given CPU time
+	Allocs	n=N	Number of allocation requests seen
+		ok=N	Number of successful alloc reqs
+		wt=N	Number of alloc reqs that waited on lookup completion
+		nbf=N	Number of alloc reqs rejected -ENOBUFS
+		ops=N	Number of alloc reqs submitted
+		owt=N	Number of alloc reqs waited for CPU time
+	Retrvls	n=N	Number of retrieval (read) requests seen
+		ok=N	Number of successful retr reqs
+		wt=N	Number of retr reqs that waited on lookup completion
+		nod=N	Number of retr reqs returned -ENODATA
+		nbf=N	Number of retr reqs rejected -ENOBUFS
+		int=N	Number of retr reqs aborted -ERESTARTSYS
+		oom=N	Number of retr reqs failed -ENOMEM
+		ops=N	Number of retr reqs submitted
+		owt=N	Number of retr reqs waited for CPU time
+	Stores	n=N	Number of storage (write) requests seen
+		ok=N	Number of successful store reqs
+		agn=N	Number of store reqs on a page already pending storage
+		nbf=N	Number of store reqs rejected -ENOBUFS
+		oom=N	Number of store reqs failed -ENOMEM
+		ops=N	Number of store reqs submitted
+		run=N	Number of store reqs granted CPU time
+	Ops	pend=N	Number of times async ops added to pending queues
+		run=N	Number of times async ops given CPU time
+		enq=N	Number of times async ops queued for processing
+		dfr=N	Number of async ops queued for deferred release
+		rel=N	Number of async ops released
+		gc=N	Number of deferred-release async ops garbage collected
+
+
+ (*) /proc/fs/fscache/histogram
+
+	cat /proc/fs/fscache/histogram
+	JIFS  SECS  OBJ INST  OP RUNS   OBJ RUNS  RETRV DLY RETRIEVLS
+	===== ===== ========= ========= ========= ========= =========
+
+     This shows the breakdown of the number of times each amount of time
+     between 0 jiffies and HZ-1 jiffies a variety of tasks took to run.  The
+     columns are as follows:
+
+	COLUMN		TIME MEASUREMENT
+	=======		=======================================================
+	OBJ INST	Length of time to instantiate an object
+	OP RUNS		Length of time a call to process an operation took
+	OBJ RUNS	Length of time a call to process an object event took
+	RETRV DLY	Time between an requesting a read and lookup completing
+	RETRIEVLS	Time between beginning and end of a retrieval
+
+     Each row shows the number of events that took a particular range of times.
+     Each step is 1 jiffy in size.  The JIFS column indicates the particular
+     jiffy range covered, and the SECS field the equivalent number of seconds.
+
+
+=========
+DEBUGGING
+=========
+
+If CONFIG_FSCACHE_DEBUG is enabled, the FS-Cache facility can have runtime
+debugging enabled by adjusting the value in:
+
+	/sys/module/fscache/parameters/debug
+
+This is a bitmask of debugging streams to enable:
+
+	BIT	VALUE	STREAM				POINT
+	=======	=======	===============================	=======================
+	0	1	Cache management		Function entry trace
+	1	2					Function exit trace
+	2	4					General
+	3	8	Cookie management		Function entry trace
+	4	16					Function exit trace
+	5	32					General
+	6	64	Page handling			Function entry trace
+	7	128					Function exit trace
+	8	256					General
+	9	512	Operation management		Function entry trace
+	10	1024					Function exit trace
+	11	2048					General
+
+The appropriate set of values should be OR'd together and the result written to
+the control file.  For example:
+
+	echo $((1|8|64)) >/sys/module/fscache/parameters/debug
+
+will turn on all function entry debugging.
diff --git a/Documentation/filesystems/caching/netfs-api.txt b/Documentation/filesystems/caching/netfs-api.txt
new file mode 100644
index 0000000..4db125b
--- /dev/null
+++ b/Documentation/filesystems/caching/netfs-api.txt
@@ -0,0 +1,778 @@
+			===============================
+			FS-CACHE NETWORK FILESYSTEM API
+			===============================
+
+There's an API by which a network filesystem can make use of the FS-Cache
+facilities.  This is based around a number of principles:
+
+ (1) Caches can store a number of different object types.  There are two main
+     object types: indices and files.  The first is a special type used by
+     FS-Cache to make finding objects faster and to make retiring of groups of
+     objects easier.
+
+ (2) Every index, file or other object is represented by a cookie.  This cookie
+     may or may not have anything associated with it, but the netfs doesn't
+     need to care.
+
+ (3) Barring the top-level index (one entry per cached netfs), the index
+     hierarchy for each netfs is structured according the whim of the netfs.
+
+This API is declared in <linux/fscache.h>.
+
+This document contains the following sections:
+
+	 (1) Network filesystem definition
+	 (2) Index definition
+	 (3) Object definition
+	 (4) Network filesystem (un)registration
+	 (5) Cache tag lookup
+	 (6) Index registration
+	 (7) Data file registration
+	 (8) Miscellaneous object registration
+	 (9) Setting the data file size
+	(10) Page alloc/read/write
+	(11) Page uncaching
+	(12) Index and data file update
+	(13) Miscellaneous cookie operations
+	(14) Cookie unregistration
+	(15) Index and data file invalidation
+	(16) FS-Cache specific page flags.
+
+
+=============================
+NETWORK FILESYSTEM DEFINITION
+=============================
+
+FS-Cache needs a description of the network filesystem.  This is specified
+using a record of the following structure:
+
+	struct fscache_netfs {
+		uint32_t			version;
+		const char			*name;
+		struct fscache_cookie		*primary_index;
+		...
+	};
+
+This first two fields should be filled in before registration, and the third
+will be filled in by the registration function; any other fields should just be
+ignored and are for internal use only.
+
+The fields are:
+
+ (1) The name of the netfs (used as the key in the toplevel index).
+
+ (2) The version of the netfs (if the name matches but the version doesn't, the
+     entire in-cache hierarchy for this netfs will be scrapped and begun
+     afresh).
+
+ (3) The cookie representing the primary index will be allocated according to
+     another parameter passed into the registration function.
+
+For example, kAFS (linux/fs/afs/) uses the following definitions to describe
+itself:
+
+	struct fscache_netfs afs_cache_netfs = {
+		.version	= 0,
+		.name		= "afs",
+	};
+
+
+================
+INDEX DEFINITION
+================
+
+Indices are used for two purposes:
+
+ (1) To aid the finding of a file based on a series of keys (such as AFS's
+     "cell", "volume ID", "vnode ID").
+
+ (2) To make it easier to discard a subset of all the files cached based around
+     a particular key - for instance to mirror the removal of an AFS volume.
+
+However, since it's unlikely that any two netfs's are going to want to define
+their index hierarchies in quite the same way, FS-Cache tries to impose as few
+restraints as possible on how an index is structured and where it is placed in
+the tree.  The netfs can even mix indices and data files at the same level, but
+it's not recommended.
+
+Each index entry consists of a key of indeterminate length plus some auxilliary
+data, also of indeterminate length.
+
+There are some limits on indices:
+
+ (1) Any index containing non-index objects should be restricted to a single
+     cache.  Any such objects created within an index will be created in the
+     first cache only.  The cache in which an index is created can be
+     controlled by cache tags (see below).
+
+ (2) The entry data must be atomically journallable, so it is limited to about
+     400 bytes at present.  At least 400 bytes will be available.
+
+ (3) The depth of the index tree should be judged with care as the search
+     function is recursive.  Too many layers will run the kernel out of stack.
+
+
+=================
+OBJECT DEFINITION
+=================
+
+To define an object, a structure of the following type should be filled out:
+
+	struct fscache_cookie_def
+	{
+		uint8_t name[16];
+		uint8_t type;
+
+		struct fscache_cache_tag *(*select_cache)(
+			const void *parent_netfs_data,
+			const void *cookie_netfs_data);
+
+		uint16_t (*get_key)(const void *cookie_netfs_data,
+				    void *buffer,
+				    uint16_t bufmax);
+
+		void (*get_attr)(const void *cookie_netfs_data,
+				 uint64_t *size);
+
+		uint16_t (*get_aux)(const void *cookie_netfs_data,
+				    void *buffer,
+				    uint16_t bufmax);
+
+		enum fscache_checkaux (*check_aux)(void *cookie_netfs_data,
+						   const void *data,
+						   uint16_t datalen);
+
+		void (*get_context)(void *cookie_netfs_data, void *context);
+
+		void (*put_context)(void *cookie_netfs_data, void *context);
+
+		void (*mark_pages_cached)(void *cookie_netfs_data,
+					  struct address_space *mapping,
+					  struct pagevec *cached_pvec);
+
+		void (*now_uncached)(void *cookie_netfs_data);
+	};
+
+This has the following fields:
+
+ (1) The type of the object [mandatory].
+
+     This is one of the following values:
+
+	(*) FSCACHE_COOKIE_TYPE_INDEX
+
+	    This defines an index, which is a special FS-Cache type.
+
+	(*) FSCACHE_COOKIE_TYPE_DATAFILE
+
+	    This defines an ordinary data file.
+
+	(*) Any other value between 2 and 255
+
+	    This defines an extraordinary object such as an XATTR.
+
+ (2) The name of the object type (NUL terminated unless all 16 chars are used)
+     [optional].
+
+ (3) A function to select the cache in which to store an index [optional].
+
+     This function is invoked when an index needs to be instantiated in a cache
+     during the instantiation of a non-index object.  Only the immediate index
+     parent for the non-index object will be queried.  Any indices above that
+     in the hierarchy may be stored in multiple caches.  This function does not
+     need to be supplied for any non-index object or any index that will only
+     have index children.
+
+     If this function is not supplied or if it returns NULL then the first
+     cache in the parent's list will be chosed, or failing that, the first
+     cache in the master list.
+
+ (4) A function to retrieve an object's key from the netfs [mandatory].
+
+     This function will be called with the netfs data that was passed to the
+     cookie acquisition function and the maximum length of key data that it may
+     provide.  It should write the required key data into the given buffer and
+     return the quantity it wrote.
+
+ (5) A function to retrieve attribute data from the netfs [optional].
+
+     This function will be called with the netfs data that was passed to the
+     cookie acquisition function.  It should return the size of the file if
+     this is a data file.  The size may be used to govern how much cache must
+     be reserved for this file in the cache.
+
+     If the function is absent, a file size of 0 is assumed.
+
+ (6) A function to retrieve auxilliary data from the netfs [optional].
+
+     This function will be called with the netfs data that was passed to the
+     cookie acquisition function and the maximum length of auxilliary data that
+     it may provide.  It should write the auxilliary data into the given buffer
+     and return the quantity it wrote.
+
+     If this function is absent, the auxilliary data length will be set to 0.
+
+     The length of the auxilliary data buffer may be dependent on the key
+     length.  A netfs mustn't rely on being able to provide more than 400 bytes
+     for both.
+
+ (7) A function to check the auxilliary data [optional].
+
+     This function will be called to check that a match found in the cache for
+     this object is valid.  For instance with AFS it could check the auxilliary
+     data against the data version number returned by the server to determine
+     whether the index entry in a cache is still valid.
+
+     If this function is absent, it will be assumed that matching objects in a
+     cache are always valid.
+
+     If present, the function should return one of the following values:
+
+	(*) FSCACHE_CHECKAUX_OKAY		- the entry is okay as is
+	(*) FSCACHE_CHECKAUX_NEEDS_UPDATE	- the entry requires update
+	(*) FSCACHE_CHECKAUX_OBSOLETE		- the entry should be deleted
+
+     This function can also be used to extract data from the auxilliary data in
+     the cache and copy it into the netfs's structures.
+
+ (8) A pair of functions to manage contexts for the completion callback
+     [optional].
+
+     The cache read/write functions are passed a context which is then passed
+     to the I/O completion callback function.  To ensure this context remains
+     valid until after the I/O completion is called, two functions may be
+     provided: one to get an extra reference on the context, and one to drop a
+     reference to it.
+
+     If the context is not used or is a type of object that won't go out of
+     scope, then these functions are not required.  These functions are not
+     required for indices as indices may not contain data.  These functions may
+     be called in interrupt context and so may not sleep.
+
+ (9) A function to mark a page as retaining cache metadata [optional].
+
+     This is called by the cache to indicate that it is retaining in-memory
+     information for this page and that the netfs should uncache the page when
+     it has finished.  This does not indicate whether there's data on the disk
+     or not.  Note that several pages at once may be presented for marking.
+
+     The PG_fscache bit is set on the pages before this function would be
+     called, so the function need not be provided if this is sufficient.
+
+     This function is not required for indices as they're not permitted data.
+
+(10) A function to unmark all the pages retaining cache metadata [mandatory].
+
+     This is called by FS-Cache to indicate that a backing store is being
+     unbound from a cookie and that all the marks on the pages should be
+     cleared to prevent confusion.  Note that the cache will have torn down all
+     its tracking information so that the pages don't need to be explicitly
+     uncached.
+
+     This function is not required for indices as they're not permitted data.
+
+
+===================================
+NETWORK FILESYSTEM (UN)REGISTRATION
+===================================
+
+The first step is to declare the network filesystem to the cache.  This also
+involves specifying the layout of the primary index (for AFS, this would be the
+"cell" level).
+
+The registration function is:
+
+	int fscache_register_netfs(struct fscache_netfs *netfs);
+
+It just takes a pointer to the netfs definition.  It returns 0 or an error as
+appropriate.
+
+For kAFS, registration is done as follows:
+
+	ret = fscache_register_netfs(&afs_cache_netfs);
+
+The last step is, of course, unregistration:
+
+	void fscache_unregister_netfs(struct fscache_netfs *netfs);
+
+
+================
+CACHE TAG LOOKUP
+================
+
+FS-Cache permits the use of more than one cache.  To permit particular index
+subtrees to be bound to particular caches, the second step is to look up cache
+representation tags.  This step is optional; it can be left entirely up to
+FS-Cache as to which cache should be used.  The problem with doing that is that
+FS-Cache will always pick the first cache that was registered.
+
+To get the representation for a named tag:
+
+	struct fscache_cache_tag *fscache_lookup_cache_tag(const char *name);
+
+This takes a text string as the name and returns a representation of a tag.  It
+will never return an error.  It may return a dummy tag, however, if it runs out
+of memory; this will inhibit caching with this tag.
+
+Any representation so obtained must be released by passing it to this function:
+
+	void fscache_release_cache_tag(struct fscache_cache_tag *tag);
+
+The tag will be retrieved by FS-Cache when it calls the object definition
+operation select_cache().
+
+
+==================
+INDEX REGISTRATION
+==================
+
+The third step is to inform FS-Cache about part of an index hierarchy that can
+be used to locate files.  This is done by requesting a cookie for each index in
+the path to the file:
+
+	struct fscache_cookie *
+	fscache_acquire_cookie(struct fscache_cookie *parent,
+			       const struct fscache_object_def *def,
+			       void *netfs_data);
+
+This function creates an index entry in the index represented by parent,
+filling in the index entry by calling the operations pointed to by def.
+
+Note that this function never returns an error - all errors are handled
+internally.  It may, however, return NULL to indicate no cookie.  It is quite
+acceptable to pass this token back to this function as the parent to another
+acquisition (or even to the relinquish cookie, read page and write page
+functions - see below).
+
+Note also that no indices are actually created in a cache until a non-index
+object needs to be created somewhere down the hierarchy.  Furthermore, an index
+may be created in several different caches independently at different times.
+This is all handled transparently, and the netfs doesn't see any of it.
+
+For example, with AFS, a cell would be added to the primary index.  This index
+entry would have a dependent inode containing a volume location index for the
+volume mappings within this cell:
+
+	cell->cache =
+		fscache_acquire_cookie(afs_cache_netfs.primary_index,
+				       &afs_cell_cache_index_def,
+				       cell);
+
+Then when a volume location was accessed, it would be entered into the cell's
+index and an inode would be allocated that acts as a volume type and hash chain
+combination:
+
+	vlocation->cache =
+		fscache_acquire_cookie(cell->cache,
+				       &afs_vlocation_cache_index_def,
+				       vlocation);
+
+And then a particular flavour of volume (R/O for example) could be added to
+that index, creating another index for vnodes (AFS inode equivalents):
+
+	volume->cache =
+		fscache_acquire_cookie(vlocation->cache,
+				       &afs_volume_cache_index_def,
+				       volume);
+
+
+======================
+DATA FILE REGISTRATION
+======================
+
+The fourth step is to request a data file be created in the cache.  This is
+identical to index cookie acquisition.  The only difference is that the type in
+the object definition should be something other than index type.
+
+	vnode->cache =
+		fscache_acquire_cookie(volume->cache,
+				       &afs_vnode_cache_object_def,
+				       vnode);
+
+
+=================================
+MISCELLANEOUS OBJECT REGISTRATION
+=================================
+
+An optional step is to request an object of miscellaneous type be created in
+the cache.  This is almost identical to index cookie acquisition.  The only
+difference is that the type in the object definition should be something other
+than index type.  Whilst the parent object could be an index, it's more likely
+it would be some other type of object such as a data file.
+
+	xattr->cache =
+		fscache_acquire_cookie(vnode->cache,
+				       &afs_xattr_cache_object_def,
+				       xattr);
+
+Miscellaneous objects might be used to store extended attributes or directory
+entries for example.
+
+
+==========================
+SETTING THE DATA FILE SIZE
+==========================
+
+The fifth step is to set the physical attributes of the file, such as its size.
+This doesn't automatically reserve any space in the cache, but permits the
+cache to adjust its metadata for data tracking appropriately:
+
+	int fscache_attr_changed(struct fscache_cookie *cookie);
+
+The cache will return -ENOBUFS if there is no backing cache or if there is no
+space to allocate any extra metadata required in the cache.  The attributes
+will be accessed with the get_attr() cookie definition operation.
+
+Note that attempts to read or write data pages in the cache over this size may
+be rebuffed with -ENOBUFS.
+
+This operation schedules an attribute adjustment to happen asynchronously at
+some point in the future, and as such, it may happen after the function returns
+to the caller.  The attribute adjustment excludes read and write operations.
+
+
+=====================
+PAGE READ/ALLOC/WRITE
+=====================
+
+And the sixth step is to store and retrieve pages in the cache.  There are
+three functions that are used to do this.
+
+Note:
+
+ (1) A page should not be re-read or re-allocated without uncaching it first.
+
+ (2) A read or allocated page must be uncached when the netfs page is released
+     from the pagecache.
+
+ (3) A page should only be written to the cache if previous read or allocated.
+
+This permits the cache to maintain its page tracking in proper order.
+
+
+PAGE READ
+---------
+
+Firstly, the netfs should ask FS-Cache to examine the caches and read the
+contents cached for a particular page of a particular file if present, or else
+allocate space to store the contents if not:
+
+	typedef
+	void (*fscache_rw_complete_t)(struct page *page,
+				      void *context,
+				      int error);
+
+	int fscache_read_or_alloc_page(struct fscache_cookie *cookie,
+				       struct page *page,
+				       fscache_rw_complete_t end_io_func,
+				       void *context,
+				       gfp_t gfp);
+
+The cookie argument must specify a cookie for an object that isn't an index,
+the page specified will have the data loaded into it (and is also used to
+specify the page number), and the gfp argument is used to control how any
+memory allocations made are satisfied.
+
+If the cookie indicates the inode is not cached:
+
+ (1) The function will return -ENOBUFS.
+
+Else if there's a copy of the page resident in the cache:
+
+ (1) The mark_pages_cached() cookie operation will be called on that page.
+
+ (2) The function will submit a request to read the data from the cache's
+     backing device directly into the page specified.
+
+ (3) The function will return 0.
+
+ (4) When the read is complete, end_io_func() will be invoked with:
+
+     (*) The netfs data supplied when the cookie was created.
+
+     (*) The page descriptor.
+
+     (*) The context argument passed to the above function.  This will be
+         maintained with the get_context/put_context functions mentioned above.
+
+     (*) An argument that's 0 on success or negative for an error code.
+
+     If an error occurs, it should be assumed that the page contains no usable
+     data.
+
+     end_io_func() will be called in process context if the read is results in
+     an error, but it might be called in interrupt context if the read is
+     successful.
+
+Otherwise, if there's not a copy available in cache, but the cache may be able
+to store the page:
+
+ (1) The mark_pages_cached() cookie operation will be called on that page.
+
+ (2) A block may be reserved in the cache and attached to the object at the
+     appropriate place.
+
+ (3) The function will return -ENODATA.
+
+This function may also return -ENOMEM or -EINTR, in which case it won't have
+read any data from the cache.
+
+
+PAGE ALLOCATE
+-------------
+
+Alternatively, if there's not expected to be any data in the cache for a page
+because the file has been extended, a block can simply be allocated instead:
+
+	int fscache_alloc_page(struct fscache_cookie *cookie,
+			       struct page *page,
+			       gfp_t gfp);
+
+This is similar to the fscache_read_or_alloc_page() function, except that it
+never reads from the cache.  It will return 0 if a block has been allocated,
+rather than -ENODATA as the other would.  One or the other must be performed
+before writing to the cache.
+
+The mark_pages_cached() cookie operation will be called on the page if
+successful.
+
+
+PAGE WRITE
+----------
+
+Secondly, if the netfs changes the contents of the page (either due to an
+initial download or if a user performs a write), then the page should be
+written back to the cache:
+
+	int fscache_write_page(struct fscache_cookie *cookie,
+			       struct page *page,
+			       gfp_t gfp);
+
+The cookie argument must specify a data file cookie, the page specified should
+contain the data to be written (and is also used to specify the page number),
+and the gfp argument is used to control how any memory allocations made are
+satisfied.
+
+The page must have first been read or allocated successfully and must not have
+been uncached before writing is performed.
+
+If the cookie indicates the inode is not cached then:
+
+ (1) The function will return -ENOBUFS.
+
+Else if space can be allocated in the cache to hold this page:
+
+ (1) PG_fscache_write will be set on the page.
+
+ (2) The function will submit a request to write the data to cache's backing
+     device directly from the page specified.
+
+ (3) The function will return 0.
+
+ (4) When the write is complete PG_fscache_write is cleared on the page and
+     anyone waiting for that bit will be woken up.
+
+Else if there's no space available in the cache, -ENOBUFS will be returned.  It
+is also possible for the PG_fscache_write bit to be cleared when no write took
+place if unforeseen circumstances arose (such as a disk error).
+
+Writing takes place asynchronously.
+
+
+MULTIPLE PAGE READ
+------------------
+
+A facility is provided to read several pages at once, as requested by the
+readpages() address space operation:
+
+	int fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
+					struct address_space *mapping,
+					struct list_head *pages,
+					int *nr_pages,
+					fscache_rw_complete_t end_io_func,
+					void *context,
+					gfp_t gfp);
+
+This works in a similar way to fscache_read_or_alloc_page(), except:
+
+ (1) Any page it can retrieve data for is removed from pages and nr_pages and
+     dispatched for reading to the disk.  Reads of adjacent pages on disk may
+     be merged for greater efficiency.
+
+ (2) The mark_pages_cached() cookie operation will be called on several pages
+     at once if they're being read or allocated.
+
+ (3) If there was an general error, then that error will be returned.
+
+     Else if some pages couldn't be allocated or read, then -ENOBUFS will be
+     returned.
+
+     Else if some pages couldn't be read but were allocated, then -ENODATA will
+     be returned.
+
+     Otherwise, if all pages had reads dispatched, then 0 will be returned, the
+     list will be empty and *nr_pages will be 0.
+
+ (4) end_io_func will be called once for each page being read as the reads
+     complete.  It will be called in process context if error != 0, but it may
+     be called in interrupt context if there is no error.
+
+Note that a return of -ENODATA, -ENOBUFS or any other error does not preclude
+some of the pages being read and some being allocated.  Those pages will have
+been marked appropriately and will need uncaching.
+
+
+==============
+PAGE UNCACHING
+==============
+
+To uncache a page, this function should be called:
+
+	void fscache_uncache_page(struct fscache_cookie *cookie,
+				  struct page *page);
+
+This function permits the cache to release any in-memory representation it
+might be holding for this netfs page.  This function must be called once for
+each page on which the read or write page functions above have been called to
+make sure the cache's in-memory tracking information gets torn down.
+
+Note that pages can't be explicitly deleted from the a data file.  The whole
+data file must be retired (see the relinquish cookie function below).
+
+Furthermore, note that this does not cancel the asynchronous read or write
+operation started by the read/alloc and write functions, so the page
+invalidation and release functions must use:
+
+	bool fscache_check_page_write(struct fscache_cookie *cookie,
+				      struct page *page);
+
+to see if a page is being written to the cache, and:
+
+	void fscache_wait_on_page_write(struct fscache_cookie *cookie,
+					struct page *page);
+
+to wait for it to finish if it is.
+
+
+==========================
+INDEX AND DATA FILE UPDATE
+==========================
+
+To request an update of the index data for an index or other object, the
+following function should be called:
+
+	void fscache_update_cookie(struct fscache_cookie *cookie);
+
+This function will refer back to the netfs_data pointer stored in the cookie by
+the acquisition function to obtain the data to write into each revised index
+entry.  The update method in the parent index definition will be called to
+transfer the data.
+
+Note that partial updates may happen automatically at other times, such as when
+data blocks are added to a data file object.
+
+
+===============================
+MISCELLANEOUS COOKIE OPERATIONS
+===============================
+
+There are a number of operations that can be used to control cookies:
+
+ (*) Cookie pinning:
+
+	int fscache_pin_cookie(struct fscache_cookie *cookie);
+	void fscache_unpin_cookie(struct fscache_cookie *cookie);
+
+     These operations permit data cookies to be pinned into the cache and to
+     have the pinning removed.  They are not permitted on index cookies.
+
+     The pinning function will return 0 if successful, -ENOBUFS in the cookie
+     isn't backed by a cache, -EOPNOTSUPP if the cache doesn't support pinning,
+     -ENOSPC if there isn't enough space to honour the operation, -ENOMEM or
+     -EIO if there's any other problem.
+
+ (*) Data space reservation:
+
+	int fscache_reserve_space(struct fscache_cookie *cookie, loff_t size);
+
+     This permits a netfs to request cache space be reserved to store up to the
+     given amount of a file.  It is permitted to ask for more than the current
+     size of the file to allow for future file expansion.
+
+     If size is given as zero then the reservation will be cancelled.
+
+     The function will return 0 if successful, -ENOBUFS in the cookie isn't
+     backed by a cache, -EOPNOTSUPP if the cache doesn't support reservations,
+     -ENOSPC if there isn't enough space to honour the operation, -ENOMEM or
+     -EIO if there's any other problem.
+
+     Note that this doesn't pin an object in a cache; it can still be culled to
+     make space if it's not in use.
+
+
+=====================
+COOKIE UNREGISTRATION
+=====================
+
+To get rid of a cookie, this function should be called.
+
+	void fscache_relinquish_cookie(struct fscache_cookie *cookie,
+				       int retire);
+
+If retire is non-zero, then the object will be marked for recycling, and all
+copies of it will be removed from all active caches in which it is present.
+Not only that but all child objects will also be retired.
+
+If retire is zero, then the object may be available again when next the
+acquisition function is called.  Retirement here will overrule the pinning on a
+cookie.
+
+One very important note - relinquish must NOT be called for a cookie unless all
+the cookies for "child" indices, objects and pages have been relinquished
+first.
+
+
+================================
+INDEX AND DATA FILE INVALIDATION
+================================
+
+There is no direct way to invalidate an index subtree or a data file.  To do
+this, the caller should relinquish and retire the cookie they have, and then
+acquire a new one.
+
+
+===========================
+FS-CACHE SPECIFIC PAGE FLAG
+===========================
+
+FS-Cache makes use of a page flag, PG_private_2, for its own purpose.  This is
+given the alternative name PG_fscache.
+
+PG_fscache is used to indicate that the page is known by the cache, and that
+the cache must be informed if the page is going to go away.  It's an indication
+to the netfs that the cache has an interest in this page, where an interest may
+be a pointer to it, resources allocated or reserved for it, or I/O in progress
+upon it.
+
+The netfs can use this information in methods such as releasepage() to
+determine whether it needs to uncache a page or update it.
+
+Furthermore, if this bit is set, releasepage() and invalidatepage() operations
+will be called on a page to get rid of it, even if PG_private is not set.  This
+allows caching to attempted on a page before read_cache_pages() to be called
+after fscache_read_or_alloc_pages() as the former will try and release pages it
+was given under certain circumstances.
+
+This bit does not overlap with such as PG_private.  This means that FS-Cache
+can be used with a filesystem that uses the block buffering code.
+
+There are a number of operations defined on this flag:
+
+	int PageFsCache(struct page *page);
+	void SetPageFsCache(struct page *page)
+	void ClearPageFsCache(struct page *page)
+	int TestSetPageFsCache(struct page *page)
+	int TestClearPageFsCache(struct page *page)
+
+These functions are bit test, bit set, bit clear, bit test and set and bit
+test and clear operations on PG_fscache.
diff --git a/Documentation/filesystems/caching/object.txt b/Documentation/filesystems/caching/object.txt
new file mode 100644
index 0000000..e8b0a35
--- /dev/null
+++ b/Documentation/filesystems/caching/object.txt
@@ -0,0 +1,313 @@
+	     ====================================================
+	     IN-KERNEL CACHE OBJECT REPRESENTATION AND MANAGEMENT
+	     ====================================================
+
+By: David Howells <dhowells@redhat.com>
+
+Contents:
+
+ (*) Representation
+
+ (*) Object management state machine.
+
+     - Provision of cpu time.
+     - Locking simplification.
+
+ (*) The set of states.
+
+ (*) The set of events.
+
+
+==============
+REPRESENTATION
+==============
+
+FS-Cache maintains an in-kernel representation of each object that a netfs is
+currently interested in.  Such objects are represented by the fscache_cookie
+struct and are referred to as cookies.
+
+FS-Cache also maintains a separate in-kernel representation of the objects that
+a cache backend is currently actively caching.  Such objects are represented by
+the fscache_object struct.  The cache backends allocate these upon request, and
+are expected to embed them in their own representations.  These are referred to
+as objects.
+
+There is a 1:N relationship between cookies and objects.  A cookie may be
+represented by multiple objects - an index may exist in more than one cache -
+or even by no objects (it may not be cached).
+
+Furthermore, both cookies and objects are hierarchical.  The two hierarchies
+correspond, but the cookies tree is a superset of the union of the object trees
+of multiple caches:
+
+	    NETFS INDEX TREE               :      CACHE 1     :      CACHE 2
+	                                   :                  :
+	                                   :   +-----------+  :
+	                          +----------->|  IObject  |  :
+	      +-----------+       |        :   +-----------+  :
+	      |  ICookie  |-------+        :         |        :
+	      +-----------+       |        :         |        :   +-----------+
+	            |             +------------------------------>|  IObject  |
+	            |                      :         |        :   +-----------+
+	            |                      :         V        :         |
+	            |                      :   +-----------+  :         |
+	            V             +----------->|  IObject  |  :         |
+	      +-----------+       |        :   +-----------+  :         |
+	      |  ICookie  |-------+        :         |        :         V
+	      +-----------+       |        :         |        :   +-----------+
+	            |             +------------------------------>|  IObject  |
+	      +-----+-----+                :         |        :   +-----------+
+	      |           |                :         |        :         |
+	      V           |                :         V        :         |
+	+-----------+     |                :   +-----------+  :         |
+	|  ICookie  |------------------------->|  IObject  |  :         |
+	+-----------+     |                :   +-----------+  :         |
+	      |           V                :         |        :         V
+	      |     +-----------+          :         |        :   +-----------+
+	      |     |  ICookie  |-------------------------------->|  IObject  |
+	      |     +-----------+          :         |        :   +-----------+
+	      V           |                :         V        :         |
+	+-----------+     |                :   +-----------+  :         |
+	|  DCookie  |------------------------->|  DObject  |  :         |
+	+-----------+     |                :   +-----------+  :         |
+	                  |                :                  :         |
+	          +-------+-------+        :                  :         |
+	          |               |        :                  :         |
+	          V               V        :                  :         V
+	    +-----------+   +-----------+  :                  :   +-----------+
+	    |  DCookie  |   |  DCookie  |------------------------>|  DObject  |
+	    +-----------+   +-----------+  :                  :   +-----------+
+	                                   :                  :
+
+In the above illustration, ICookie and IObject represent indices and DCookie
+and DObject represent data storage objects.  Indices may have representation in
+multiple caches, but currently, non-index objects may not.  Objects of any type
+may also be entirely unrepresented.
+
+As far as the netfs API goes, the netfs is only actually permitted to see
+pointers to the cookies.  The cookies themselves and any objects attached to
+those cookies are hidden from it.
+
+
+===============================
+OBJECT MANAGEMENT STATE MACHINE
+===============================
+
+Within FS-Cache, each active object is managed by its own individual state
+machine.  The state for an object is kept in the fscache_object struct, in
+object->state.  A cookie may point to a set of objects that are in different
+states.
+
+Each state has an action associated with it that is invoked when the machine
+wakes up in that state.  There are four logical sets of states:
+
+ (1) Preparation: states that wait for the parent objects to become ready.  The
+     representations are hierarchical, and it is expected that an object must
+     be created or accessed with respect to its parent object.
+
+ (2) Initialisation: states that perform lookups in the cache and validate
+     what's found and that create on disk any missing metadata.
+
+ (3) Normal running: states that allow netfs operations on objects to proceed
+     and that update the state of objects.
+
+ (4) Termination: states that detach objects from their netfs cookies, that
+     delete objects from disk, that handle disk and system errors and that free
+     up in-memory resources.
+
+
+In most cases, transitioning between states is in response to signalled events.
+When a state has finished processing, it will usually set the mask of events in
+which it is interested (object->event_mask) and relinquish the worker thread.
+Then when an event is raised (by calling fscache_raise_event()), if the event
+is not masked, the object will be queued for processing (by calling
+fscache_enqueue_object()).
+
+
+PROVISION OF CPU TIME
+---------------------
+
+The work to be done by the various states is given CPU time by the threads of
+the slow work facility (see Documentation/slow-work.txt).  This is used in
+preference to the workqueue facility because:
+
+ (1) Threads may be completely occupied for very long periods of time by a
+     particular work item.  These state actions may be doing sequences of
+     synchronous, journalled disk accesses (lookup, mkdir, create, setxattr,
+     getxattr, truncate, unlink, rmdir, rename).
+
+ (2) Threads may do little actual work, but may rather spend a lot of time
+     sleeping on I/O.  This means that single-threaded and 1-per-CPU-threaded
+     workqueues don't necessarily have the right numbers of threads.
+
+
+LOCKING SIMPLIFICATION
+----------------------
+
+Because only one worker thread may be operating on any particular object's
+state machine at once, this simplifies the locking, particularly with respect
+to disconnecting the netfs's representation of a cache object (fscache_cookie)
+from the cache backend's representation (fscache_object) - which may be
+requested from either end.
+
+
+=================
+THE SET OF STATES
+=================
+
+The object state machine has a set of states that it can be in.  There are
+preparation states in which the object sets itself up and waits for its parent
+object to transit to a state that allows access to its children:
+
+ (1) State FSCACHE_OBJECT_INIT.
+
+     Initialise the object and wait for the parent object to become active.  In
+     the cache, it is expected that it will not be possible to look an object
+     up from the parent object, until that parent object itself has been looked
+     up.
+
+There are initialisation states in which the object sets itself up and accesses
+disk for the object metadata:
+
+ (2) State FSCACHE_OBJECT_LOOKING_UP.
+
+     Look up the object on disk, using the parent as a starting point.
+     FS-Cache expects the cache backend to probe the cache to see whether this
+     object is represented there, and if it is, to see if it's valid (coherency
+     management).
+
+     The cache should call fscache_object_lookup_negative() to indicate lookup
+     failure for whatever reason, and should call fscache_obtained_object() to
+     indicate success.
+
+     At the completion of lookup, FS-Cache will let the netfs go ahead with
+     read operations, no matter whether the file is yet cached.  If not yet
+     cached, read operations will be immediately rejected with ENODATA until
+     the first known page is uncached - as to that point there can be no data
+     to be read out of the cache for that file that isn't currently also held
+     in the pagecache.
+
+ (3) State FSCACHE_OBJECT_CREATING.
+
+     Create an object on disk, using the parent as a starting point.  This
+     happens if the lookup failed to find the object, or if the object's
+     coherency data indicated what's on disk is out of date.  In this state,
+     FS-Cache expects the cache to create
+
+     The cache should call fscache_obtained_object() if creation completes
+     successfully, fscache_object_lookup_negative() otherwise.
+
+     At the completion of creation, FS-Cache will start processing write
+     operations the netfs has queued for an object.  If creation failed, the
+     write ops will be transparently discarded, and nothing recorded in the
+     cache.
+
+There are some normal running states in which the object spends its time
+servicing netfs requests:
+
+ (4) State FSCACHE_OBJECT_AVAILABLE.
+
+     A transient state in which pending operations are started, child objects
+     are permitted to advance from FSCACHE_OBJECT_INIT state, and temporary
+     lookup data is freed.
+
+ (5) State FSCACHE_OBJECT_ACTIVE.
+
+     The normal running state.  In this state, requests the netfs makes will be
+     passed on to the cache.
+
+ (6) State FSCACHE_OBJECT_UPDATING.
+
+     The state machine comes here to update the object in the cache from the
+     netfs's records.  This involves updating the auxiliary data that is used
+     to maintain coherency.
+
+And there are terminal states in which an object cleans itself up, deallocates
+memory and potentially deletes stuff from disk:
+
+ (7) State FSCACHE_OBJECT_LC_DYING.
+
+     The object comes here if it is dying because of a lookup or creation
+     error.  This would be due to a disk error or system error of some sort.
+     Temporary data is cleaned up, and the parent is released.
+
+ (8) State FSCACHE_OBJECT_DYING.
+
+     The object comes here if it is dying due to an error, because its parent
+     cookie has been relinquished by the netfs or because the cache is being
+     withdrawn.
+
+     Any child objects waiting on this one are given CPU time so that they too
+     can destroy themselves.  This object waits for all its children to go away
+     before advancing to the next state.
+
+ (9) State FSCACHE_OBJECT_ABORT_INIT.
+
+     The object comes to this state if it was waiting on its parent in
+     FSCACHE_OBJECT_INIT, but its parent died.  The object will destroy itself
+     so that the parent may proceed from the FSCACHE_OBJECT_DYING state.
+
+(10) State FSCACHE_OBJECT_RELEASING.
+(11) State FSCACHE_OBJECT_RECYCLING.
+
+     The object comes to one of these two states when dying once it is rid of
+     all its children, if it is dying because the netfs relinquished its
+     cookie.  In the first state, the cached data is expected to persist, and
+     in the second it will be deleted.
+
+(12) State FSCACHE_OBJECT_WITHDRAWING.
+
+     The object transits to this state if the cache decides it wants to
+     withdraw the object from service, perhaps to make space, but also due to
+     error or just because the whole cache is being withdrawn.
+
+(13) State FSCACHE_OBJECT_DEAD.
+
+     The object transits to this state when the in-memory object record is
+     ready to be deleted.  The object processor shouldn't ever see an object in
+     this state.
+
+
+THE SET OF EVENTS
+-----------------
+
+There are a number of events that can be raised to an object state machine:
+
+ (*) FSCACHE_OBJECT_EV_UPDATE
+
+     The netfs requested that an object be updated.  The state machine will ask
+     the cache backend to update the object, and the cache backend will ask the
+     netfs for details of the change through its cookie definition ops.
+
+ (*) FSCACHE_OBJECT_EV_CLEARED
+
+     This is signalled in two circumstances:
+
+     (a) when an object's last child object is dropped and
+
+     (b) when the last operation outstanding on an object is completed.
+
+     This is used to proceed from the dying state.
+
+ (*) FSCACHE_OBJECT_EV_ERROR
+
+     This is signalled when an I/O error occurs during the processing of some
+     object.
+
+ (*) FSCACHE_OBJECT_EV_RELEASE
+ (*) FSCACHE_OBJECT_EV_RETIRE
+
+     These are signalled when the netfs relinquishes a cookie it was using.
+     The event selected depends on whether the netfs asks for the backing
+     object to be retired (deleted) or retained.
+
+ (*) FSCACHE_OBJECT_EV_WITHDRAW
+
+     This is signalled when the cache backend wants to withdraw an object.
+     This means that the object will have to be detached from the netfs's
+     cookie.
+
+Because the withdrawing releasing/retiring events are all handled by the object
+state machine, it doesn't matter if there's a collision with both ends trying
+to sever the connection at the same time.  The state machine can just pick
+which one it wants to honour, and that effects the other.
diff --git a/Documentation/filesystems/caching/operations.txt b/Documentation/filesystems/caching/operations.txt
new file mode 100644
index 0000000..b6b070c
--- /dev/null
+++ b/Documentation/filesystems/caching/operations.txt
@@ -0,0 +1,213 @@
+		       ================================
+		       ASYNCHRONOUS OPERATIONS HANDLING
+		       ================================
+
+By: David Howells <dhowells@redhat.com>
+
+Contents:
+
+ (*) Overview.
+
+ (*) Operation record initialisation.
+
+ (*) Parameters.
+
+ (*) Procedure.
+
+ (*) Asynchronous callback.
+
+
+========
+OVERVIEW
+========
+
+FS-Cache has an asynchronous operations handling facility that it uses for its
+data storage and retrieval routines.  Its operations are represented by
+fscache_operation structs, though these are usually embedded into some other
+structure.
+
+This facility is available to and expected to be be used by the cache backends,
+and FS-Cache will create operations and pass them off to the appropriate cache
+backend for completion.
+
+To make use of this facility, <linux/fscache-cache.h> should be #included.
+
+
+===============================
+OPERATION RECORD INITIALISATION
+===============================
+
+An operation is recorded in an fscache_operation struct:
+
+	struct fscache_operation {
+		union {
+			struct work_struct fast_work;
+			struct slow_work slow_work;
+		};
+		unsigned long		flags;
+		fscache_operation_processor_t processor;
+		...
+	};
+
+Someone wanting to issue an operation should allocate something with this
+struct embedded in it.  They should initialise it by calling:
+
+	void fscache_operation_init(struct fscache_operation *op,
+				    fscache_operation_release_t release);
+
+with the operation to be initialised and the release function to use.
+
+The op->flags parameter should be set to indicate the CPU time provision and
+the exclusivity (see the Parameters section).
+
+The op->fast_work, op->slow_work and op->processor flags should be set as
+appropriate for the CPU time provision (see the Parameters section).
+
+FSCACHE_OP_WAITING may be set in op->flags prior to each submission of the
+operation and waited for afterwards.
+
+
+==========
+PARAMETERS
+==========
+
+There are a number of parameters that can be set in the operation record's flag
+parameter.  There are three options for the provision of CPU time in these
+operations:
+
+ (1) The operation may be done synchronously (FSCACHE_OP_MYTHREAD).  A thread
+     may decide it wants to handle an operation itself without deferring it to
+     another thread.
+
+     This is, for example, used in read operations for calling readpages() on
+     the backing filesystem in CacheFiles.  Although readpages() does an
+     asynchronous data fetch, the determination of whether pages exist is done
+     synchronously - and the netfs does not proceed until this has been
+     determined.
+
+     If this option is to be used, FSCACHE_OP_WAITING must be set in op->flags
+     before submitting the operation, and the operating thread must wait for it
+     to be cleared before proceeding:
+
+		wait_on_bit(&op->flags, FSCACHE_OP_WAITING,
+			    fscache_wait_bit, TASK_UNINTERRUPTIBLE);
+
+
+ (2) The operation may be fast asynchronous (FSCACHE_OP_FAST), in which case it
+     will be given to keventd to process.  Such an operation is not permitted
+     to sleep on I/O.
+
+     This is, for example, used by CacheFiles to copy data from a backing fs
+     page to a netfs page after the backing fs has read the page in.
+
+     If this option is used, op->fast_work and op->processor must be
+     initialised before submitting the operation:
+
+		INIT_WORK(&op->fast_work, do_some_work);
+
+
+ (3) The operation may be slow asynchronous (FSCACHE_OP_SLOW), in which case it
+     will be given to the slow work facility to process.  Such an operation is
+     permitted to sleep on I/O.
+
+     This is, for example, used by FS-Cache to handle background writes of
+     pages that have just been fetched from a remote server.
+
+     If this option is used, op->slow_work and op->processor must be
+     initialised before submitting the operation:
+
+		fscache_operation_init_slow(op, processor)
+
+
+Furthermore, operations may be one of two types:
+
+ (1) Exclusive (FSCACHE_OP_EXCLUSIVE).  Operations of this type may not run in
+     conjunction with any other operation on the object being operated upon.
+
+     An example of this is the attribute change operation, in which the file
+     being written to may need truncation.
+
+ (2) Shareable.  Operations of this type may be running simultaneously.  It's
+     up to the operation implementation to prevent interference between other
+     operations running at the same time.
+
+
+=========
+PROCEDURE
+=========
+
+Operations are used through the following procedure:
+
+ (1) The submitting thread must allocate the operation and initialise it
+     itself.  Normally this would be part of a more specific structure with the
+     generic op embedded within.
+
+ (2) The submitting thread must then submit the operation for processing using
+     one of the following two functions:
+
+	int fscache_submit_op(struct fscache_object *object,
+			      struct fscache_operation *op);
+
+	int fscache_submit_exclusive_op(struct fscache_object *object,
+					struct fscache_operation *op);
+
+     The first function should be used to submit non-exclusive ops and the
+     second to submit exclusive ones.  The caller must still set the
+     FSCACHE_OP_EXCLUSIVE flag.
+
+     If successful, both functions will assign the operation to the specified
+     object and return 0.  -ENOBUFS will be returned if the object specified is
+     permanently unavailable.
+
+     The operation manager will defer operations on an object that is still
+     undergoing lookup or creation.  The operation will also be deferred if an
+     operation of conflicting exclusivity is in progress on the object.
+
+     If the operation is asynchronous, the manager will retain a reference to
+     it, so the caller should put their reference to it by passing it to:
+
+	void fscache_put_operation(struct fscache_operation *op);
+
+ (3) If the submitting thread wants to do the work itself, and has marked the
+     operation with FSCACHE_OP_MYTHREAD, then it should monitor
+     FSCACHE_OP_WAITING as described above and check the state of the object if
+     necessary (the object might have died whilst the thread was waiting).
+
+     When it has finished doing its processing, it should call
+     fscache_put_operation() on it.
+
+ (4) The operation holds an effective lock upon the object, preventing other
+     exclusive ops conflicting until it is released.  The operation can be
+     enqueued for further immediate asynchronous processing by adjusting the
+     CPU time provisioning option if necessary, eg:
+
+	op->flags &= ~FSCACHE_OP_TYPE;
+	op->flags |= ~FSCACHE_OP_FAST;
+
+     and calling:
+
+	void fscache_enqueue_operation(struct fscache_operation *op)
+
+     This can be used to allow other things to have use of the worker thread
+     pools.
+
+
+=====================
+ASYNCHRONOUS CALLBACK
+=====================
+
+When used in asynchronous mode, the worker thread pool will invoke the
+processor method with a pointer to the operation.  This should then get at the
+container struct by using container_of():
+
+	static void fscache_write_op(struct fscache_operation *_op)
+	{
+		struct fscache_storage *op =
+			container_of(_op, struct fscache_storage, op);
+	...
+	}
+
+The caller holds a reference on the operation, and will invoke
+fscache_put_operation() when the processor function returns.  The processor
+function is at liberty to call fscache_enqueue_operation() or to take extra
+references.
diff --git a/Documentation/filesystems/exofs.txt b/Documentation/filesystems/exofs.txt
new file mode 100644
index 0000000..0ced74c
--- /dev/null
+++ b/Documentation/filesystems/exofs.txt
@@ -0,0 +1,176 @@
+===============================================================================
+WHAT IS EXOFS?
+===============================================================================
+
+exofs is a file system that uses an OSD and exports the API of a normal Linux
+file system. Users access exofs like any other local file system, and exofs
+will in turn issue commands to the local OSD initiator.
+
+OSD is a new T10 command set that views storage devices not as a large/flat
+array of sectors but as a container of objects, each having a length, quota,
+time attributes and more. Each object is addressed by a 64bit ID, and is
+contained in a 64bit ID partition. Each object has associated attributes
+attached to it, which are integral part of the object and provide metadata about
+the object. The standard defines some common obligatory attributes, but user
+attributes can be added as needed.
+
+===============================================================================
+ENVIRONMENT
+===============================================================================
+
+To use this file system, you need to have an object store to run it on.  You
+may download a target from:
+http://open-osd.org
+
+See Documentation/scsi/osd.txt for how to setup a working osd environment.
+
+===============================================================================
+USAGE
+===============================================================================
+
+1. Download and compile exofs and open-osd initiator:
+  You need an external Kernel source tree or kernel headers from your
+  distribution. (anything based on 2.6.26 or later).
+
+  a. download open-osd including exofs source using:
+     [parent-directory]$ git clone git://git.open-osd.org/open-osd.git
+
+  b. Build the library module like this:
+     [parent-directory]$ make -C KSRC=$(KER_DIR) open-osd
+
+     This will build both the open-osd initiator as well as the exofs kernel
+     module. Use whatever parameters you compiled your Kernel with and
+     $(KER_DIR) above pointing to the Kernel you compile against. See the file
+     open-osd/top-level-Makefile for an example.
+
+2. Get the OSD initiator and target set up properly, and login to the target.
+  See Documentation/scsi/osd.txt for farther instructions. Also see ./do-osd
+  for example script that does all these steps.
+
+3. Insmod the exofs.ko module:
+   [exofs]$ insmod exofs.ko
+
+4. Make sure the directory where you want to mount exists. If not, create it.
+   (For example, mkdir /mnt/exofs)
+
+5. At first run you will need to invoke the mkfs.exofs application
+
+   As an example, this will create the file system on:
+   /dev/osd0 partition ID 65536
+
+   mkfs.exofs --pid=65536 --format /dev/osd0
+
+   The --format is optional if not specified no OSD_FORMAT will be
+   preformed and a clean file system will be created in the specified pid,
+   in the available space of the target. (Use --format=size_in_meg to limit
+   the total LUN space available)
+
+   If pid already exist it will be deleted and a new one will be created in it's
+   place. Be careful.
+
+   An exofs lives inside a single OSD partition. You can create multiple exofs
+   filesystems on the same device using multiple pids.
+
+   (run mkfs.exofs without any parameters for usage help message)
+
+6. Mount the file system.
+
+   For example, to mount /dev/osd0, partition ID 0x10000 on /mnt/exofs:
+
+	mount -t exofs -o pid=65536 /dev/osd0 /mnt/exofs/
+
+7. For reference (See do-exofs example script):
+	do-exofs start - an example of how to perform the above steps.
+	do-exofs stop -  an example of how to unmount the file system.
+	do-exofs format - an example of how to format and mkfs a new exofs.
+
+8. Extra compilation flags (uncomment in fs/exofs/Kbuild):
+	CONFIG_EXOFS_DEBUG - for debug messages and extra checks.
+
+===============================================================================
+exofs mount options
+===============================================================================
+Similar to any mount command:
+	mount -t exofs -o exofs_options /dev/osdX mount_exofs_directory
+
+Where:
+    -t exofs: specifies the exofs file system
+
+    /dev/osdX: X is a decimal number. /dev/osdX was created after a successful
+               login into an OSD target.
+
+    mount_exofs_directory: The directory to mount the file system on
+
+    exofs specific options: Options are separated by commas (,)
+		pid=<integer> - The partition number to mount/create as
+                                container of the filesystem.
+                                This option is mandatory
+                to=<integer>  - Timeout in ticks for a single command
+                                default is (60 * HZ) [for debugging only]
+
+===============================================================================
+DESIGN
+===============================================================================
+
+* The file system control block (AKA on-disk superblock) resides in an object
+  with a special ID (defined in common.h).
+  Information included in the file system control block is used to fill the
+  in-memory superblock structure at mount time. This object is created before
+  the file system is used by mkexofs.c It contains information such as:
+	- The file system's magic number
+	- The next inode number to be allocated
+
+* Each file resides in its own object and contains the data (and it will be
+  possible to extend the file over multiple objects, though this has not been
+  implemented yet).
+
+* A directory is treated as a file, and essentially contains a list of <file
+  name, inode #> pairs for files that are found in that directory. The object
+  IDs correspond to the files' inode numbers and will be allocated according to
+  a bitmap (stored in a separate object). Now they are allocated using a
+  counter.
+
+* Each file's control block (AKA on-disk inode) is stored in its object's
+  attributes. This applies to both regular files and other types (directories,
+  device files, symlinks, etc.).
+
+* Credentials are generated per object (inode and superblock) when they is
+  created in memory (read off disk or created). The credential works for all
+  operations and is used as long as the object remains in memory.
+
+* Async OSD operations are used whenever possible, but the target may execute
+  them out of order. The operations that concern us are create, delete,
+  readpage, writepage, update_inode, and truncate. The following pairs of
+  operations should execute in the order written, and we need to prevent them
+  from executing in reverse order:
+	- The following are handled with the OBJ_CREATED and OBJ_2BCREATED
+	  flags. OBJ_CREATED is set when we know the object exists on the OSD -
+	  in create's callback function, and when we successfully do a read_inode.
+	  OBJ_2BCREATED is set in the beginning of the create function, so we
+	  know that we should wait.
+		- create/delete: delete should wait until the object is created
+		  on the OSD.
+		- create/readpage: readpage should be able to return a page
+		  full of zeroes in this case. If there was a write already
+		  en-route (i.e. create, writepage, readpage) then the page
+		  would be locked, and so it would really be the same as
+		  create/writepage.
+		- create/writepage: if writepage is called for a sync write, it
+		  should wait until the object is created on the OSD.
+		  Otherwise, it should just return.
+		- create/truncate: truncate should wait until the object is
+		  created on the OSD.
+		- create/update_inode: update_inode should wait until the
+		  object is created on the OSD.
+	- Handled by VFS locks:
+		- readpage/delete: shouldn't happen because of page lock.
+		- writepage/delete: shouldn't happen because of page lock.
+		- readpage/writepage: shouldn't happen because of page lock.
+
+===============================================================================
+LICENSE/COPYRIGHT
+===============================================================================
+The exofs file system is based on ext2 v0.5b (distributed with the Linux kernel
+version 2.6.10).  All files include the original copyrights, and the license
+is GPL version 2 (only version 2, as is true for the Linux kernel).  The
+Linux kernel can be downloaded from www.kernel.org.
diff --git a/Documentation/filesystems/ext3.txt b/Documentation/filesystems/ext3.txt
index e5f3833..570f9bd 100644
--- a/Documentation/filesystems/ext3.txt
+++ b/Documentation/filesystems/ext3.txt
@@ -14,6 +14,11 @@
 When mounting an ext3 filesystem, the following option are accepted:
 (*) == default
 
+ro			Mount filesystem read only. Note that ext3 will replay
+			the journal (and thus write to the partition) even when
+			mounted "read only". Mount options "ro,noload" can be
+			used to prevent writes to the filesystem.
+
 journal=update		Update the ext3 file system's journal to the current
 			format.
 
@@ -27,7 +32,9 @@
 			identified through its new major/minor numbers encoded
 			in devnum.
 
-noload			Don't load the journal on mounting.
+noload			Don't load the journal on mounting. Note that this forces
+			mount of inconsistent filesystem, which can lead to
+			various problems.
 
 data=journal		All data are committed into the journal prior to being
 			written into the main file system.
@@ -92,9 +99,12 @@
 
 debug			Extra debugging information is sent to syslog.
 
-errors=remount-ro(*)	Remount the filesystem read-only on an error.
+errors=remount-ro	Remount the filesystem read-only on an error.
 errors=continue		Keep going on a filesystem error.
 errors=panic		Panic and halt the machine if an error occurs.
+			(These mount options override the errors behavior
+			specified in the superblock, which can be
+			configured using tune2fs.)
 
 data_err=ignore(*)	Just print an error message if an error occurs
 			in a file data buffer in ordered mode.
diff --git a/Documentation/filesystems/pohmelfs/design_notes.txt b/Documentation/filesystems/pohmelfs/design_notes.txt
new file mode 100644
index 0000000..6d6db60
--- /dev/null
+++ b/Documentation/filesystems/pohmelfs/design_notes.txt
@@ -0,0 +1,70 @@
+POHMELFS: Parallel Optimized Host Message Exchange Layered File System.
+
+		Evgeniy Polyakov <zbr@ioremap.net>
+
+Homepage: http://www.ioremap.net/projects/pohmelfs
+
+POHMELFS first began as a network filesystem with coherent local data and
+metadata caches but is now evolving into a parallel distributed filesystem.
+
+Main features of this FS include:
+ * Locally coherent cache for data and metadata with (potentially) byte-range locks.
+	Since all Linux filesystems lock the whole inode during writing, algorithm
+	is very simple and does not use byte-ranges, although they are sent in
+	locking messages.
+ * Completely async processing of all events except creation of hard and symbolic
+	links, and rename events.
+	Object creation and data reading and writing are processed asynchronously.
+ * Flexible object architecture optimized for network processing.
+	Ability to create long paths to objects and remove arbitrarily huge
+	directories with a single network command.
+	(like removing the whole kernel tree via a single network command).
+ * Very high performance.
+ * Fast and scalable multithreaded userspace server. Being in userspace it works
+	with any underlying filesystem and still is much faster than async in-kernel NFS one.
+ * Client is able to switch between different servers (if one goes down, client
+	automatically reconnects to second and so on).
+ * Transactions support. Full failover for all operations.
+	Resending transactions to different servers on timeout or error.
+ * Read request (data read, directory listing, lookup requests) balancing between multiple servers.
+ * Write requests are replicated to multiple servers and completed only when all of them are acked.
+ * Ability to add and/or remove servers from the working set at run-time.
+ * Strong authentification and possible data encryption in network channel.
+ * Extended attributes support.
+
+POHMELFS is based on transactions, which are potentially long-standing objects that live
+in the client's memory. Each transaction contains all the information needed to process a given
+command (or set of commands, which is frequently used during data writing: single transactions
+can contain creation and data writing commands). Transactions are committed by all the servers
+to which they are sent and, in case of failures, are eventually resent or dropped with an error.
+For example, reading will return an error if no servers are available.
+
+POHMELFS uses a asynchronous approach to data processing. Courtesy of transactions, it is
+possible to detach replies from requests and, if the command requires data to be received, the
+caller sleeps waiting for it. Thus, it is possible to issue multiple read commands to different
+servers and async threads will pick up replies in parallel, find appropriate transactions in the
+system and put the data where it belongs (like the page or inode cache).
+
+The main feature of POHMELFS is writeback data and the metadata cache.
+Only a few non-performance critical operations use the write-through cache and
+are synchronous: hard and symbolic link creation, and object rename. Creation,
+removal of objects and data writing are asynchronous and are sent to
+the server during system writeback. Only one writer at a time is allowed for any
+given inode, which is guarded by an appropriate locking protocol.
+Because of this feature, POHMELFS is extremely fast at metadata intensive
+workloads and can fully utilize the bandwidth to the servers when doing bulk
+data transfers.
+
+POHMELFS clients operate with a working set of servers and are capable of balancing read-only
+operations (like lookups or directory listings) between them.
+Administrators can add or remove servers from the set at run-time via special commands (described
+in Documentation/pohmelfs/info.txt file). Writes are replicated to all servers.
+
+POHMELFS is capable of full data channel encryption and/or strong crypto hashing.
+One can select any kernel supported cipher, encryption mode, hash type and operation mode
+(hmac or digest). It is also possible to use both or neither (default). Crypto configuration
+is checked during mount time and, if the server does not support it, appropriate capabilities
+will be disabled or mount will fail (if 'crypto_fail_unsupported' mount option is specified).
+Crypto performance heavily depends on the number of crypto threads, which asynchronously perform
+crypto operations and send the resulting data to server or submit it up the stack. This number
+can be controlled via a mount option.
diff --git a/Documentation/filesystems/pohmelfs/info.txt b/Documentation/filesystems/pohmelfs/info.txt
new file mode 100644
index 0000000..4e3d501
--- /dev/null
+++ b/Documentation/filesystems/pohmelfs/info.txt
@@ -0,0 +1,86 @@
+POHMELFS usage information.
+
+Mount options:
+idx=%u
+ Each mountpoint is associated with a special index via this option.
+ Administrator can add or remove servers from the given index, so all mounts,
+ which were attached to it, are updated.
+ Default it is 0.
+
+trans_scan_timeout=%u
+ This timeout, expressed in milliseconds, specifies time to scan transaction
+ trees looking for stale requests, which have to be resent, or if number of
+ retries exceed specified limit, dropped with error.
+ Default is 5 seconds.
+
+drop_scan_timeout=%u
+ Internal timeout, expressed in milliseconds, which specifies how frequently
+ inodes marked to be dropped are freed. It also specifies how frequently
+ the system checks that servers have to be added or removed from current working set.
+ Default is 1 second.
+
+wait_on_page_timeout=%u
+ Number of milliseconds to wait for reply from remote server for data reading command.
+ If this timeout is exceeded, reading returns an error.
+ Default is 5 seconds.
+
+trans_retries=%u
+ This is the number of times that a transaction will be resent to a server that did
+ not answer for the last @trans_scan_timeout milliseconds.
+ When the number of resends exceeds this limit, the transaction is completed with error.
+ Default is 5 resends.
+
+crypto_thread_num=%u
+ Number of crypto processing threads. Threads are used both for RX and TX traffic.
+ Default is 2, or no threads if crypto operations are not supported.
+
+trans_max_pages=%u
+ Maximum number of pages in a single transaction. This parameter also controls
+ the number of pages,  allocated for crypto processing (each crypto thread has
+ pool of pages, the number of which is equal to 'trans_max_pages'.
+ Default is 100 pages.
+
+crypto_fail_unsupported
+ If specified, mount will fail if the server does not support requested crypto operations.
+ By default mount will disable non-matching crypto operations.
+
+mcache_timeout=%u
+ Maximum number of milliseconds to wait for the mcache objects to be processed.
+ Mcache includes locks (given lock should be granted by server), attributes (they should be
+ fully received in the given timeframe).
+ Default is 5 seconds.
+
+Usage examples.
+
+Add (or remove if it already exists) server server1.net:1025 into the working set with index $idx
+with appropriate hash algorithm and key file and cipher algorithm, mode and key file:
+$cfg -a server1.net -p 1025 -i $idx -K $hash_key -k $cipher_key
+
+Mount filesystem with given index $idx to /mnt mountpoint.
+Client will connect to all servers specified in the working set via previous command:
+mount -t pohmel -o idx=$idx q /mnt
+
+One can add or remove servers from working set after mounting too.
+
+
+Server installation.
+
+Creating a server, which listens at port 1025 and 0.0.0.0 address.
+Working root directory (note, that server chroots there, so you have to have appropriate permissions)
+is set to /mnt, server will negotiate hash/cipher with client, in case client requested it, there
+are appropriate key files.
+Number of working threads is set to 10.
+
+# ./fserver -a 0.0.0.0 -p 1025 -r /mnt -w 10 -K hash_key -k cipher_key
+
+ -A 6			 - listen on ipv6 address. Default: Disabled.
+ -r root                 - path to root directory. Default: /tmp.
+ -a addr                 - listen address. Default: 0.0.0.0.
+ -p port                 - listen port. Default: 1025.
+ -w workers              - number of workers per connected client. Default: 1.
+ -K file		 - hash key size. Default: none.
+ -k file		 - cipher key size. Default: none.
+ -h                      - this help.
+
+Number of worker threads specifies how many workers will be created for each client.
+Bulk single-client transafers usually are better handled with smaller number (like 1-3).
diff --git a/Documentation/filesystems/pohmelfs/network_protocol.txt b/Documentation/filesystems/pohmelfs/network_protocol.txt
new file mode 100644
index 0000000..40ea6c2
--- /dev/null
+++ b/Documentation/filesystems/pohmelfs/network_protocol.txt
@@ -0,0 +1,227 @@
+POHMELFS network protocol.
+
+Basic structure used in network communication is following command:
+
+struct netfs_cmd
+{
+	__u16			cmd;	/* Command number */
+	__u16			csize;	/* Attached crypto information size */
+	__u16			cpad;	/* Attached padding size */
+	__u16			ext;	/* External flags */
+	__u32			size;	/* Size of the attached data */
+	__u32			trans;	/* Transaction id */
+	__u64			id;	/* Object ID to operate on. Used for feedback.*/
+	__u64			start;	/* Start of the object. */
+	__u64			iv;	/* IV sequence */
+	__u8			data[0];
+};
+
+Commands can be embedded into transaction command (which in turn has own command),
+so one can extend protocol as needed without breaking backward compatibility as long
+as old commands are supported. All string lengths include tail 0 byte.
+
+All commans are transfered over the network in big-endian. CPU endianess is used at the end peers.
+
+@cmd - command number, which specifies command to be processed. Following
+	commands are used currently:
+
+	NETFS_READDIR	= 1,	/* Read directory for given inode number */
+	NETFS_READ_PAGE,	/* Read data page from the server */
+	NETFS_WRITE_PAGE,	/* Write data page to the server */
+	NETFS_CREATE,		/* Create directory entry */
+	NETFS_REMOVE,		/* Remove directory entry */
+	NETFS_LOOKUP,		/* Lookup single object */
+	NETFS_LINK,		/* Create a link */
+	NETFS_TRANS,		/* Transaction */
+	NETFS_OPEN,		/* Open intent */
+	NETFS_INODE_INFO,	/* Metadata cache coherency synchronization message */
+	NETFS_PAGE_CACHE,	/* Page cache invalidation message */
+	NETFS_READ_PAGES,	/* Read multiple contiguous pages in one go */
+	NETFS_RENAME,		/* Rename object */
+	NETFS_CAPABILITIES,	/* Capabilities of the client, for example supported crypto */
+	NETFS_LOCK,		/* Distributed lock message */
+	NETFS_XATTR_SET,	/* Set extended attribute */
+	NETFS_XATTR_GET,	/* Get extended attribute */
+
+@ext - external flags. Used by different commands to specify some extra arguments
+	like partial size of the embedded objects or creation flags.
+
+@size - size of the attached data. For NETFS_READ_PAGE and NETFS_READ_PAGES no data is attached,
+	but size of the requested data is incorporated here. It does not include size of the command
+	header (struct netfs_cmd) itself.
+
+@id - id of the object this command operates on. Each command can use it for own purpose.
+
+@start - start of the object this command operates on. Each command can use it for own purpose.
+
+@csize, @cpad - size and padding size of the (attached if needed) crypto information.
+
+Command specifications.
+
+@NETFS_READDIR
+This command is used to sync content of the remote dir to the client.
+
+@ext - length of the path to object.
+@size - the same.
+@id - local inode number of the directory to read.
+@start - zero.
+
+
+@NETFS_READ_PAGE
+This command is used to read data from remote server.
+Data size does not exceed local page cache size.
+
+@id - inode number.
+@start - first byte offset.
+@size - number of bytes to read plus length of the path to object.
+@ext - object path length.
+
+
+@NETFS_CREATE
+Used to create object.
+It does not require that all directories on top of the object were
+already created, it will create them automatically. Each object has
+associated @netfs_path_entry data structure, which contains creation
+mode (permissions and type) and length of the name as long as name itself.
+
+@start - 0
+@size - size of the all data structures needed to create a path
+@id - local inode number
+@ext - 0
+
+
+@NETFS_REMOVE
+Used to remove object.
+
+@ext - length of the path to object.
+@size - the same.
+@id - local inode number.
+@start - zero.
+
+
+@NETFS_LOOKUP
+Lookup information about object on server.
+
+@ext - length of the path to object.
+@size - the same.
+@id - local inode number of the directory to look object in.
+@start - local inode number of the object to look at.
+
+
+@NETFS_LINK
+Create hard of symlink.
+Command is sent as "object_path|target_path".
+
+@size - size of the above string.
+@id - parent local inode number.
+@start - 1 for symlink, 0 for hardlink.
+@ext - size of the "object_path" above.
+
+
+@NETFS_TRANS
+Transaction header.
+
+@size - incorporates all embedded command sizes including theirs header sizes.
+@start - transaction generation number - unique id used to find transaction.
+@ext - transaction flags. Unused at the moment.
+@id - 0.
+
+
+@NETFS_OPEN
+Open intent for given transaction.
+
+@id - local inode number.
+@start - 0.
+@size - path length to the object.
+@ext - open flags (O_RDWR and so on).
+
+
+@NETFS_INODE_INFO
+Metadata update command.
+It is sent to servers when attributes of the object are changed and received
+when data or metadata were updated. It operates with the following structure:
+
+struct netfs_inode_info
+{
+	unsigned int		mode;
+	unsigned int		nlink;
+	unsigned int		uid;
+	unsigned int		gid;
+	unsigned int		blocksize;
+	unsigned int		padding;
+	__u64			ino;
+	__u64			blocks;
+	__u64			rdev;
+	__u64			size;
+	__u64			version;
+};
+
+It effectively mirrors stat(2) returned data.
+
+
+@ext - path length to the object.
+@size - the same plus size of the netfs_inode_info structure.
+@id - local inode number.
+@start - 0.
+
+
+@NETFS_PAGE_CACHE
+Command is only received by clients. It contains information about
+page to be marked as not up-to-date.
+
+@id - client's inode number.
+@start - last byte of the page to be invalidated. If it is not equal to
+	current inode size, it will be vmtruncated().
+@size - 0
+@ext - 0
+
+
+@NETFS_READ_PAGES
+Used to read multiple contiguous pages in one go.
+
+@start - first byte of the contiguous region to read.
+@size - contains of two fields: lower 8 bits are used to represent page cache shift
+	used by client, another 3 bytes are used to get number of pages.
+@id - local inode number.
+@ext - path length to the object.
+
+
+@NETFS_RENAME
+Used to rename object.
+Attached data is formed into following string: "old_path|new_path".
+
+@id - local inode number.
+@start - parent inode number.
+@size - length of the above string.
+@ext - length of the old path part.
+
+
+@NETFS_CAPABILITIES
+Used to exchange crypto capabilities with server.
+If crypto capabilities are not supported by server, then client will disable it
+or fail (if 'crypto_fail_unsupported' mount options was specified).
+
+@id - superblock index. Used to specify crypto information for group of servers.
+@size - size of the attached capabilities structure.
+@start - 0.
+@size - 0.
+@scsize - 0.
+
+@NETFS_LOCK
+Used to send lock request/release messages. Although it sends byte range request
+and is capable of flushing pages based on that, it is not used, since all Linux
+filesystems lock the whole inode.
+
+@id - lock generation number.
+@start - start of the locked range.
+@size - size of the locked range.
+@ext - lock type: read/write. Not used actually. 15'th bit is used to determine,
+	if it is lock request (1) or release (0).
+
+@NETFS_XATTR_SET
+@NETFS_XATTR_GET
+Used to set/get extended attributes for given inode.
+@id - attribute generation number or xattr setting type
+@start - size of the attribute (request or attached)
+@size - name length, path len and data size for given attribute
+@ext - path length for given object
diff --git a/Documentation/filesystems/udf.txt b/Documentation/filesystems/udf.txt
index fde829a..902b95d 100644
--- a/Documentation/filesystems/udf.txt
+++ b/Documentation/filesystems/udf.txt
@@ -24,6 +24,8 @@
 
 	gid=		Set the default group.
 	umask=		Set the default umask.
+	mode=		Set the default file permissions.
+	dmode=		Set the default directory permissions.
 	uid=		Set the default user.
 	bs=		Set the block size.
 	unhide		Show otherwise hidden files.
diff --git a/Documentation/ftrace.txt b/Documentation/ftrace.txt
index 803b131..fd9a3e6 100644
--- a/Documentation/ftrace.txt
+++ b/Documentation/ftrace.txt
@@ -15,31 +15,31 @@
 
 Ftrace is an internal tracer designed to help out developers and
 designers of systems to find what is going on inside the kernel.
-It can be used for debugging or analyzing latencies and performance
-issues that take place outside of user-space.
+It can be used for debugging or analyzing latencies and
+performance issues that take place outside of user-space.
 
 Although ftrace is the function tracer, it also includes an
-infrastructure that allows for other types of tracing. Some of the
-tracers that are currently in ftrace include a tracer to trace
-context switches, the time it takes for a high priority task to
-run after it was woken up, the time interrupts are disabled, and
-more (ftrace allows for tracer plugins, which means that the list of
-tracers can always grow).
+infrastructure that allows for other types of tracing. Some of
+the tracers that are currently in ftrace include a tracer to
+trace context switches, the time it takes for a high priority
+task to run after it was woken up, the time interrupts are
+disabled, and more (ftrace allows for tracer plugins, which
+means that the list of tracers can always grow).
 
 
 The File System
 ---------------
 
-Ftrace uses the debugfs file system to hold the control files as well
-as the files to display output.
+Ftrace uses the debugfs file system to hold the control files as
+well as the files to display output.
 
 To mount the debugfs system:
 
   # mkdir /debug
   # mount -t debugfs nodev /debug
 
-(Note: it is more common to mount at /sys/kernel/debug, but for simplicity
- this document will use /debug)
+( Note: it is more common to mount at /sys/kernel/debug, but for
+  simplicity this document will use /debug)
 
 That's it! (assuming that you have ftrace configured into your kernel)
 
@@ -50,90 +50,124 @@
 
  Note: all time values are in microseconds.
 
-  current_tracer: This is used to set or display the current tracer
-		that is configured.
+  current_tracer:
 
-  available_tracers: This holds the different types of tracers that
-		have been compiled into the kernel. The tracers
-		listed here can be configured by echoing their name
-		into current_tracer.
+	This is used to set or display the current tracer
+	that is configured.
 
-  tracing_enabled: This sets or displays whether the current_tracer
-		is activated and tracing or not. Echo 0 into this
-		file to disable the tracer or 1 to enable it.
+  available_tracers:
 
-  trace: This file holds the output of the trace in a human readable
-		format (described below).
+	This holds the different types of tracers that
+	have been compiled into the kernel. The
+	tracers listed here can be configured by
+	echoing their name into current_tracer.
 
-  latency_trace: This file shows the same trace but the information
-		is organized more to display possible latencies
-		in the system (described below).
+  tracing_enabled:
 
-  trace_pipe: The output is the same as the "trace" file but this
-		file is meant to be streamed with live tracing.
-		Reads from this file will block until new data
-		is retrieved. Unlike the "trace" and "latency_trace"
-		files, this file is a consumer. This means reading
-		from this file causes sequential reads to display
-		more current data. Once data is read from this
-		file, it is consumed, and will not be read
-		again with a sequential read. The "trace" and
-		"latency_trace" files are static, and if the
-		tracer is not adding more data, they will display
-		the same information every time they are read.
+	This sets or displays whether the current_tracer
+	is activated and tracing or not. Echo 0 into this
+	file to disable the tracer or 1 to enable it.
 
-  trace_options: This file lets the user control the amount of data
-		that is displayed in one of the above output
-		files.
+  trace:
 
-  trace_max_latency: Some of the tracers record the max latency.
-		For example, the time interrupts are disabled.
-		This time is saved in this file. The max trace
-		will also be stored, and displayed by either
-		"trace" or "latency_trace".  A new max trace will
-		only be recorded if the latency is greater than
-		the value in this file. (in microseconds)
+	This file holds the output of the trace in a human
+	readable format (described below).
 
-  buffer_size_kb: This sets or displays the number of kilobytes each CPU
-		buffer can hold. The tracer buffers are the same size
-		for each CPU. The displayed number is the size of the
-		CPU buffer and not total size of all buffers. The
-		trace buffers are allocated in pages (blocks of memory
-		that the kernel uses for allocation, usually 4 KB in size).
-		If the last page allocated has room for more bytes
-		than requested, the rest of the page will be used,
-		making the actual allocation bigger than requested.
-		(Note, the size may not be a multiple of the page size due
-		to buffer managment overhead.)
+  latency_trace:
 
-		This can only be updated when the current_tracer
-		is set to "nop".
+	This file shows the same trace but the information
+	is organized more to display possible latencies
+	in the system (described below).
 
-  tracing_cpumask: This is a mask that lets the user only trace
-		on specified CPUS. The format is a hex string
-		representing the CPUS.
+  trace_pipe:
 
-  set_ftrace_filter: When dynamic ftrace is configured in (see the
-		section below "dynamic ftrace"), the code is dynamically
-		modified (code text rewrite) to disable calling of the
-		function profiler (mcount). This lets tracing be configured
-		in with practically no overhead in performance.  This also
-		has a side effect of enabling or disabling specific functions
-		to be traced. Echoing names of functions into this file
-		will limit the trace to only those functions.
+	The output is the same as the "trace" file but this
+	file is meant to be streamed with live tracing.
+	Reads from this file will block until new data
+	is retrieved. Unlike the "trace" and "latency_trace"
+	files, this file is a consumer. This means reading
+	from this file causes sequential reads to display
+	more current data. Once data is read from this
+	file, it is consumed, and will not be read
+	again with a sequential read. The "trace" and
+	"latency_trace" files are static, and if the
+	tracer is not adding more data, they will display
+	the same information every time they are read.
 
-  set_ftrace_notrace: This has an effect opposite to that of
-		set_ftrace_filter. Any function that is added here will not
-		be traced. If a function exists in both set_ftrace_filter
-		and set_ftrace_notrace,	the function will _not_ be traced.
+  trace_options:
 
-  set_ftrace_pid: Have the function tracer only trace a single thread.
+	This file lets the user control the amount of data
+	that is displayed in one of the above output
+	files.
 
-  available_filter_functions: This lists the functions that ftrace
-		has processed and can trace. These are the function
-		names that you can pass to "set_ftrace_filter" or
-		"set_ftrace_notrace". (See the section "dynamic ftrace"
-		below for more details.)
+  tracing_max_latency:
+
+	Some of the tracers record the max latency.
+	For example, the time interrupts are disabled.
+	This time is saved in this file. The max trace
+	will also be stored, and displayed by either
+	"trace" or "latency_trace".  A new max trace will
+	only be recorded if the latency is greater than
+	the value in this file. (in microseconds)
+
+  buffer_size_kb:
+
+	This sets or displays the number of kilobytes each CPU
+	buffer can hold. The tracer buffers are the same size
+	for each CPU. The displayed number is the size of the
+	CPU buffer and not total size of all buffers. The
+	trace buffers are allocated in pages (blocks of memory
+	that the kernel uses for allocation, usually 4 KB in size).
+	If the last page allocated has room for more bytes
+	than requested, the rest of the page will be used,
+	making the actual allocation bigger than requested.
+	( Note, the size may not be a multiple of the page size
+	  due to buffer managment overhead. )
+
+	This can only be updated when the current_tracer
+	is set to "nop".
+
+  tracing_cpumask:
+
+	This is a mask that lets the user only trace
+	on specified CPUS. The format is a hex string
+	representing the CPUS.
+
+  set_ftrace_filter:
+
+	When dynamic ftrace is configured in (see the
+	section below "dynamic ftrace"), the code is dynamically
+	modified (code text rewrite) to disable calling of the
+	function profiler (mcount). This lets tracing be configured
+	in with practically no overhead in performance.  This also
+	has a side effect of enabling or disabling specific functions
+	to be traced. Echoing names of functions into this file
+	will limit the trace to only those functions.
+
+  set_ftrace_notrace:
+
+	This has an effect opposite to that of
+	set_ftrace_filter. Any function that is added here will not
+	be traced. If a function exists in both set_ftrace_filter
+	and set_ftrace_notrace,	the function will _not_ be traced.
+
+  set_ftrace_pid:
+
+	Have the function tracer only trace a single thread.
+
+  set_graph_function:
+
+	Set a "trigger" function where tracing should start
+	with the function graph tracer (See the section
+	"dynamic ftrace" for more details).
+
+  available_filter_functions:
+
+	This lists the functions that ftrace
+	has processed and can trace. These are the function
+	names that you can pass to "set_ftrace_filter" or
+	"set_ftrace_notrace". (See the section "dynamic ftrace"
+	below for more details.)
 
 
 The Tracers
@@ -141,36 +175,66 @@
 
 Here is the list of current tracers that may be configured.
 
-  function - function tracer that uses mcount to trace all functions.
+  "function"
 
-  sched_switch - traces the context switches between tasks.
+	Function call tracer to trace all kernel functions.
 
-  irqsoff - traces the areas that disable interrupts and saves
-  		the trace with the longest max latency.
-		See tracing_max_latency.  When a new max is recorded,
-		it replaces the old trace. It is best to view this
-		trace via the latency_trace file.
+  "function_graph_tracer"
 
-  preemptoff - Similar to irqsoff but traces and records the amount of
-		time for which preemption is disabled.
+	Similar to the function tracer except that the
+	function tracer probes the functions on their entry
+	whereas the function graph tracer traces on both entry
+	and exit of the functions. It then provides the ability
+	to draw a graph of function calls similar to C code
+	source.
 
-  preemptirqsoff - Similar to irqsoff and preemptoff, but traces and
-		 records the largest time for which irqs and/or preemption
-		 is disabled.
+  "sched_switch"
 
-  wakeup - Traces and records the max latency that it takes for
-		the highest priority task to get scheduled after
-		it has been woken up.
+	Traces the context switches and wakeups between tasks.
 
-  nop - This is not a tracer. To remove all tracers from tracing
-		simply echo "nop" into current_tracer.
+  "irqsoff"
+
+	Traces the areas that disable interrupts and saves
+	the trace with the longest max latency.
+	See tracing_max_latency. When a new max is recorded,
+	it replaces the old trace. It is best to view this
+	trace via the latency_trace file.
+
+  "preemptoff"
+
+	Similar to irqsoff but traces and records the amount of
+	time for which preemption is disabled.
+
+  "preemptirqsoff"
+
+	Similar to irqsoff and preemptoff, but traces and
+	records the largest time for which irqs and/or preemption
+	is disabled.
+
+  "wakeup"
+
+	Traces and records the max latency that it takes for
+	the highest priority task to get scheduled after
+	it has been woken up.
+
+  "hw-branch-tracer"
+
+	Uses the BTS CPU feature on x86 CPUs to traces all
+	branches executed.
+
+  "nop"
+
+	This is the "trace nothing" tracer. To remove all
+	tracers from tracing simply echo "nop" into
+	current_tracer.
 
 
 Examples of using the tracer
 ----------------------------
 
-Here are typical examples of using the tracers when controlling them only
-with the debugfs interface (without using any user-land utilities).
+Here are typical examples of using the tracers when controlling
+them only with the debugfs interface (without using any
+user-land utilities).
 
 Output format:
 --------------
@@ -187,16 +251,16 @@
             bash-4251  [01] 10152.583855: _atomic_dec_and_lock <-dput
                              --------
 
-A header is printed with the tracer name that is represented by the trace.
-In this case the tracer is "function". Then a header showing the format. Task
-name "bash", the task PID "4251", the CPU that it was running on
-"01", the timestamp in <secs>.<usecs> format, the function name that was
-traced "path_put" and the parent function that called this function
-"path_walk". The timestamp is the time at which the function was
-entered.
+A header is printed with the tracer name that is represented by
+the trace. In this case the tracer is "function". Then a header
+showing the format. Task name "bash", the task PID "4251", the
+CPU that it was running on "01", the timestamp in <secs>.<usecs>
+format, the function name that was traced "path_put" and the
+parent function that called this function "path_walk". The
+timestamp is the time at which the function was entered.
 
-The sched_switch tracer also includes tracing of task wakeups and
-context switches.
+The sched_switch tracer also includes tracing of task wakeups
+and context switches.
 
      ksoftirqd/1-7     [01]  1453.070013:      7:115:R   +  2916:115:S
      ksoftirqd/1-7     [01]  1453.070013:      7:115:R   +    10:115:S
@@ -205,8 +269,8 @@
      kondemand/1-2916  [01]  1453.070013:   2916:115:S ==>     7:115:R
      ksoftirqd/1-7     [01]  1453.070013:      7:115:S ==>     0:140:R
 
-Wake ups are represented by a "+" and the context switches are shown as
-"==>".  The format is:
+Wake ups are represented by a "+" and the context switches are
+shown as "==>".  The format is:
 
  Context switches:
 
@@ -220,19 +284,20 @@
 
   <pid>:<prio>:<state>    +  <pid>:<prio>:<state>
 
-The prio is the internal kernel priority, which is the inverse of the
-priority that is usually displayed by user-space tools. Zero represents
-the highest priority (99). Prio 100 starts the "nice" priorities with
-100 being equal to nice -20 and 139 being nice 19. The prio "140" is
-reserved for the idle task which is the lowest priority thread (pid 0).
+The prio is the internal kernel priority, which is the inverse
+of the priority that is usually displayed by user-space tools.
+Zero represents the highest priority (99). Prio 100 starts the
+"nice" priorities with 100 being equal to nice -20 and 139 being
+nice 19. The prio "140" is reserved for the idle task which is
+the lowest priority thread (pid 0).
 
 
 Latency trace format
 --------------------
 
-For traces that display latency times, the latency_trace file gives
-somewhat more information to see why a latency happened. Here is a typical
-trace.
+For traces that display latency times, the latency_trace file
+gives somewhat more information to see why a latency happened.
+Here is a typical trace.
 
 # tracer: irqsoff
 #
@@ -259,20 +324,20 @@
   <idle>-0     0d.s1   98us : trace_hardirqs_on (do_softirq)
 
 
+This shows that the current tracer is "irqsoff" tracing the time
+for which interrupts were disabled. It gives the trace version
+and the version of the kernel upon which this was executed on
+(2.6.26-rc8). Then it displays the max latency in microsecs (97
+us). The number of trace entries displayed and the total number
+recorded (both are three: #3/3). The type of preemption that was
+used (PREEMPT). VP, KP, SP, and HP are always zero and are
+reserved for later use. #P is the number of online CPUS (#P:2).
 
-This shows that the current tracer is "irqsoff" tracing the time for which
-interrupts were disabled. It gives the trace version and the version
-of the kernel upon which this was executed on (2.6.26-rc8). Then it displays
-the max latency in microsecs (97 us). The number of trace entries displayed
-and the total number recorded (both are three: #3/3). The type of
-preemption that was used (PREEMPT). VP, KP, SP, and HP are always zero
-and are reserved for later use. #P is the number of online CPUS (#P:2).
+The task is the process that was running when the latency
+occurred. (swapper pid: 0).
 
-The task is the process that was running when the latency occurred.
-(swapper pid: 0).
-
-The start and stop (the functions in which the interrupts were disabled and
-enabled respectively) that caused the latencies:
+The start and stop (the functions in which the interrupts were
+disabled and enabled respectively) that caused the latencies:
 
   apic_timer_interrupt is where the interrupts were disabled.
   do_softirq is where they were enabled again.
@@ -308,12 +373,12 @@
 	latency_trace file is relative to the start of the trace.
 
   delay: This is just to help catch your eye a bit better. And
-	needs to be fixed to be only relative to the same CPU.
-	The marks are determined by the difference between this
-	current trace and the next trace.
-	 '!' - greater than preempt_mark_thresh (default 100)
-	 '+' - greater than 1 microsecond
-	 ' ' - less than or equal to 1 microsecond.
+	 needs to be fixed to be only relative to the same CPU.
+	 The marks are determined by the difference between this
+	 current trace and the next trace.
+	  '!' - greater than preempt_mark_thresh (default 100)
+	  '+' - greater than 1 microsecond
+	  ' ' - less than or equal to 1 microsecond.
 
   The rest is the same as the 'trace' file.
 
@@ -321,14 +386,15 @@
 trace_options
 -------------
 
-The trace_options file is used to control what gets printed in the trace
-output. To see what is available, simply cat the file:
+The trace_options file is used to control what gets printed in
+the trace output. To see what is available, simply cat the file:
 
   cat /debug/tracing/trace_options
   print-parent nosym-offset nosym-addr noverbose noraw nohex nobin \
- noblock nostacktrace nosched-tree nouserstacktrace nosym-userobj
+  noblock nostacktrace nosched-tree nouserstacktrace nosym-userobj
 
-To disable one of the options, echo in the option prepended with "no".
+To disable one of the options, echo in the option prepended with
+"no".
 
   echo noprint-parent > /debug/tracing/trace_options
 
@@ -338,8 +404,8 @@
 
 Here are the available options:
 
-  print-parent - On function traces, display the calling function
-		as well as the function being traced.
+  print-parent - On function traces, display the calling (parent)
+		 function as well as the function being traced.
 
   print-parent:
    bash-4000  [01]  1477.606694: simple_strtoul <-strict_strtoul
@@ -348,15 +414,16 @@
    bash-4000  [01]  1477.606694: simple_strtoul
 
 
-  sym-offset - Display not only the function name, but also the offset
-		in the function. For example, instead of seeing just
-		"ktime_get", you will see "ktime_get+0xb/0x20".
+  sym-offset - Display not only the function name, but also the
+	       offset in the function. For example, instead of
+	       seeing just "ktime_get", you will see
+	       "ktime_get+0xb/0x20".
 
   sym-offset:
    bash-4000  [01]  1477.606694: simple_strtoul+0x6/0xa0
 
-  sym-addr - this will also display the function address as well as
-		the function name.
+  sym-addr - this will also display the function address as well
+	     as the function name.
 
   sym-addr:
    bash-4000  [01]  1477.606694: simple_strtoul <c0339346>
@@ -366,35 +433,41 @@
     bash  4000 1 0 00000000 00010a95 [58127d26] 1720.415ms \
     (+0.000ms): simple_strtoul (strict_strtoul)
 
-  raw - This will display raw numbers. This option is best for use with
-	user applications that can translate the raw numbers better than
-	having it done in the kernel.
+  raw - This will display raw numbers. This option is best for
+	use with user applications that can translate the raw
+	numbers better than having it done in the kernel.
 
-  hex - Similar to raw, but the numbers will be in a hexadecimal format.
+  hex - Similar to raw, but the numbers will be in a hexadecimal
+	format.
 
   bin - This will print out the formats in raw binary.
 
   block - TBD (needs update)
 
-  stacktrace - This is one of the options that changes the trace itself.
-		When a trace is recorded, so is the stack of functions.
-		This allows for back traces of trace sites.
+  stacktrace - This is one of the options that changes the trace
+	       itself. When a trace is recorded, so is the stack
+	       of functions. This allows for back traces of
+	       trace sites.
 
-  userstacktrace - This option changes the trace.
-		   It records a stacktrace of the current userspace thread.
+  userstacktrace - This option changes the trace. It records a
+		   stacktrace of the current userspace thread.
 
-  sym-userobj - when user stacktrace are enabled, look up which object the
-		address belongs to, and print a relative address
-		This is especially useful when ASLR is on, otherwise you don't
-		get a chance to resolve the address to object/file/line after the app is no
-		longer running
+  sym-userobj - when user stacktrace are enabled, look up which
+		object the address belongs to, and print a
+		relative address. This is especially useful when
+		ASLR is on, otherwise you don't get a chance to
+		resolve the address to object/file/line after
+		the app is no longer running
 
-		The lookup is performed when you read trace,trace_pipe,latency_trace. Example:
+		The lookup is performed when you read
+		trace,trace_pipe,latency_trace. Example:
 
 		a.out-1623  [000] 40874.465068: /root/a.out[+0x480] <-/root/a.out[+0
 x494] <- /root/a.out[+0x4a8] <- /lib/libc-2.7.so[+0x1e1a6]
 
-  sched-tree - TBD (any users??)
+  sched-tree - trace all tasks that are on the runqueue, at
+	       every scheduling event. Will add overhead if
+	       there's a lot of tasks running at once.
 
 
 sched_switch
@@ -431,18 +504,19 @@
  [...]
 
 
-As we have discussed previously about this format, the header shows
-the name of the trace and points to the options. The "FUNCTION"
-is a misnomer since here it represents the wake ups and context
-switches.
+As we have discussed previously about this format, the header
+shows the name of the trace and points to the options. The
+"FUNCTION" is a misnomer since here it represents the wake ups
+and context switches.
 
-The sched_switch file only lists the wake ups (represented with '+')
-and context switches ('==>') with the previous task or current task
-first followed by the next task or task waking up. The format for both
-of these is PID:KERNEL-PRIO:TASK-STATE. Remember that the KERNEL-PRIO
-is the inverse of the actual priority with zero (0) being the highest
-priority and the nice values starting at 100 (nice -20). Below is
-a quick chart to map the kernel priority to user land priorities.
+The sched_switch file only lists the wake ups (represented with
+'+') and context switches ('==>') with the previous task or
+current task first followed by the next task or task waking up.
+The format for both of these is PID:KERNEL-PRIO:TASK-STATE.
+Remember that the KERNEL-PRIO is the inverse of the actual
+priority with zero (0) being the highest priority and the nice
+values starting at 100 (nice -20). Below is a quick chart to map
+the kernel priority to user land priorities.
 
   Kernel priority: 0 to 99    ==> user RT priority 99 to 0
   Kernel priority: 100 to 139 ==> user nice -20 to 19
@@ -463,10 +537,10 @@
 ftrace_enabled
 --------------
 
-The following tracers (listed below) give different output depending
-on whether or not the sysctl ftrace_enabled is set. To set ftrace_enabled,
-one can either use the sysctl function or set it via the proc
-file system interface.
+The following tracers (listed below) give different output
+depending on whether or not the sysctl ftrace_enabled is set. To
+set ftrace_enabled, one can either use the sysctl function or
+set it via the proc file system interface.
 
   sysctl kernel.ftrace_enabled=1
 
@@ -474,12 +548,12 @@
 
   echo 1 > /proc/sys/kernel/ftrace_enabled
 
-To disable ftrace_enabled simply replace the '1' with '0' in
-the above commands.
+To disable ftrace_enabled simply replace the '1' with '0' in the
+above commands.
 
-When ftrace_enabled is set the tracers will also record the functions
-that are within the trace. The descriptions of the tracers
-will also show an example with ftrace enabled.
+When ftrace_enabled is set the tracers will also record the
+functions that are within the trace. The descriptions of the
+tracers will also show an example with ftrace enabled.
 
 
 irqsoff
@@ -487,17 +561,18 @@
 
 When interrupts are disabled, the CPU can not react to any other
 external event (besides NMIs and SMIs). This prevents the timer
-interrupt from triggering or the mouse interrupt from letting the
-kernel know of a new mouse event. The result is a latency with the
-reaction time.
+interrupt from triggering or the mouse interrupt from letting
+the kernel know of a new mouse event. The result is a latency
+with the reaction time.
 
-The irqsoff tracer tracks the time for which interrupts are disabled.
-When a new maximum latency is hit, the tracer saves the trace leading up
-to that latency point so that every time a new maximum is reached, the old
-saved trace is discarded and the new trace is saved.
+The irqsoff tracer tracks the time for which interrupts are
+disabled. When a new maximum latency is hit, the tracer saves
+the trace leading up to that latency point so that every time a
+new maximum is reached, the old saved trace is discarded and the
+new trace is saved.
 
-To reset the maximum, echo 0 into tracing_max_latency. Here is an
-example:
+To reset the maximum, echo 0 into tracing_max_latency. Here is
+an example:
 
  # echo irqsoff > /debug/tracing/current_tracer
  # echo 0 > /debug/tracing/tracing_max_latency
@@ -532,10 +607,11 @@
 
 
 Here we see that that we had a latency of 12 microsecs (which is
-very good). The _write_lock_irq in sys_setpgid disabled interrupts.
-The difference between the 12 and the displayed timestamp 14us occurred
-because the clock was incremented between the time of recording the max
-latency and the time of recording the function that had that latency.
+very good). The _write_lock_irq in sys_setpgid disabled
+interrupts. The difference between the 12 and the displayed
+timestamp 14us occurred because the clock was incremented
+between the time of recording the max latency and the time of
+recording the function that had that latency.
 
 Note the above example had ftrace_enabled not set. If we set the
 ftrace_enabled, we get a much larger output:
@@ -586,24 +662,24 @@
 
 
 Here we traced a 50 microsecond latency. But we also see all the
-functions that were called during that time. Note that by enabling
-function tracing, we incur an added overhead. This overhead may
-extend the latency times. But nevertheless, this trace has provided
-some very helpful debugging information.
+functions that were called during that time. Note that by
+enabling function tracing, we incur an added overhead. This
+overhead may extend the latency times. But nevertheless, this
+trace has provided some very helpful debugging information.
 
 
 preemptoff
 ----------
 
-When preemption is disabled, we may be able to receive interrupts but
-the task cannot be preempted and a higher priority task must wait
-for preemption to be enabled again before it can preempt a lower
-priority task.
+When preemption is disabled, we may be able to receive
+interrupts but the task cannot be preempted and a higher
+priority task must wait for preemption to be enabled again
+before it can preempt a lower priority task.
 
 The preemptoff tracer traces the places that disable preemption.
-Like the irqsoff tracer, it records the maximum latency for which preemption
-was disabled. The control of preemptoff tracer is much like the irqsoff
-tracer.
+Like the irqsoff tracer, it records the maximum latency for
+which preemption was disabled. The control of preemptoff tracer
+is much like the irqsoff tracer.
 
  # echo preemptoff > /debug/tracing/current_tracer
  # echo 0 > /debug/tracing/tracing_max_latency
@@ -637,11 +713,12 @@
     sshd-4261  0d.s1   30us : trace_preempt_on (__do_softirq)
 
 
-This has some more changes. Preemption was disabled when an interrupt
-came in (notice the 'h'), and was enabled while doing a softirq.
-(notice the 's'). But we also see that interrupts have been disabled
-when entering the preempt off section and leaving it (the 'd').
-We do not know if interrupts were enabled in the mean time.
+This has some more changes. Preemption was disabled when an
+interrupt came in (notice the 'h'), and was enabled while doing
+a softirq. (notice the 's'). But we also see that interrupts
+have been disabled when entering the preempt off section and
+leaving it (the 'd'). We do not know if interrupts were enabled
+in the mean time.
 
 # tracer: preemptoff
 #
@@ -700,28 +777,30 @@
     sshd-4261  0d.s1   64us : trace_preempt_on (__do_softirq)
 
 
-The above is an example of the preemptoff trace with ftrace_enabled
-set. Here we see that interrupts were disabled the entire time.
-The irq_enter code lets us know that we entered an interrupt 'h'.
-Before that, the functions being traced still show that it is not
-in an interrupt, but we can see from the functions themselves that
-this is not the case.
+The above is an example of the preemptoff trace with
+ftrace_enabled set. Here we see that interrupts were disabled
+the entire time. The irq_enter code lets us know that we entered
+an interrupt 'h'. Before that, the functions being traced still
+show that it is not in an interrupt, but we can see from the
+functions themselves that this is not the case.
 
-Notice that __do_softirq when called does not have a preempt_count.
-It may seem that we missed a preempt enabling. What really happened
-is that the preempt count is held on the thread's stack and we
-switched to the softirq stack (4K stacks in effect). The code
-does not copy the preempt count, but because interrupts are disabled,
-we do not need to worry about it. Having a tracer like this is good
-for letting people know what really happens inside the kernel.
+Notice that __do_softirq when called does not have a
+preempt_count. It may seem that we missed a preempt enabling.
+What really happened is that the preempt count is held on the
+thread's stack and we switched to the softirq stack (4K stacks
+in effect). The code does not copy the preempt count, but
+because interrupts are disabled, we do not need to worry about
+it. Having a tracer like this is good for letting people know
+what really happens inside the kernel.
 
 
 preemptirqsoff
 --------------
 
-Knowing the locations that have interrupts disabled or preemption
-disabled for the longest times is helpful. But sometimes we would
-like to know when either preemption and/or interrupts are disabled.
+Knowing the locations that have interrupts disabled or
+preemption disabled for the longest times is helpful. But
+sometimes we would like to know when either preemption and/or
+interrupts are disabled.
 
 Consider the following code:
 
@@ -741,11 +820,13 @@
 call_function_with_irqs_and_preemption_off() and
 call_function_with_preemption_off().
 
-But neither will trace the time that interrupts and/or preemption
-is disabled. This total time is the time that we can not schedule.
-To record this time, use the preemptirqsoff tracer.
+But neither will trace the time that interrupts and/or
+preemption is disabled. This total time is the time that we can
+not schedule. To record this time, use the preemptirqsoff
+tracer.
 
-Again, using this trace is much like the irqsoff and preemptoff tracers.
+Again, using this trace is much like the irqsoff and preemptoff
+tracers.
 
  # echo preemptirqsoff > /debug/tracing/current_tracer
  # echo 0 > /debug/tracing/tracing_max_latency
@@ -781,9 +862,10 @@
 
 
 The trace_hardirqs_off_thunk is called from assembly on x86 when
-interrupts are disabled in the assembly code. Without the function
-tracing, we do not know if interrupts were enabled within the preemption
-points. We do see that it started with preemption enabled.
+interrupts are disabled in the assembly code. Without the
+function tracing, we do not know if interrupts were enabled
+within the preemption points. We do see that it started with
+preemption enabled.
 
 Here is a trace with ftrace_enabled set:
 
@@ -871,40 +953,42 @@
     sshd-4261  0d.s1  105us : trace_preempt_on (__do_softirq)
 
 
-This is a very interesting trace. It started with the preemption of
-the ls task. We see that the task had the "need_resched" bit set
-via the 'N' in the trace.  Interrupts were disabled before the spin_lock
-at the beginning of the trace. We see that a schedule took place to run
-sshd.  When the interrupts were enabled, we took an interrupt.
-On return from the interrupt handler, the softirq ran. We took another
-interrupt while running the softirq as we see from the capital 'H'.
+This is a very interesting trace. It started with the preemption
+of the ls task. We see that the task had the "need_resched" bit
+set via the 'N' in the trace.  Interrupts were disabled before
+the spin_lock at the beginning of the trace. We see that a
+schedule took place to run sshd.  When the interrupts were
+enabled, we took an interrupt. On return from the interrupt
+handler, the softirq ran. We took another interrupt while
+running the softirq as we see from the capital 'H'.
 
 
 wakeup
 ------
 
-In a Real-Time environment it is very important to know the wakeup
-time it takes for the highest priority task that is woken up to the
-time that it executes. This is also known as "schedule latency".
-I stress the point that this is about RT tasks. It is also important
-to know the scheduling latency of non-RT tasks, but the average
-schedule latency is better for non-RT tasks. Tools like
-LatencyTop are more appropriate for such measurements.
+In a Real-Time environment it is very important to know the
+wakeup time it takes for the highest priority task that is woken
+up to the time that it executes. This is also known as "schedule
+latency". I stress the point that this is about RT tasks. It is
+also important to know the scheduling latency of non-RT tasks,
+but the average schedule latency is better for non-RT tasks.
+Tools like LatencyTop are more appropriate for such
+measurements.
 
 Real-Time environments are interested in the worst case latency.
-That is the longest latency it takes for something to happen, and
-not the average. We can have a very fast scheduler that may only
-have a large latency once in a while, but that would not work well
-with Real-Time tasks.  The wakeup tracer was designed to record
-the worst case wakeups of RT tasks. Non-RT tasks are not recorded
-because the tracer only records one worst case and tracing non-RT
-tasks that are unpredictable will overwrite the worst case latency
-of RT tasks.
+That is the longest latency it takes for something to happen,
+and not the average. We can have a very fast scheduler that may
+only have a large latency once in a while, but that would not
+work well with Real-Time tasks.  The wakeup tracer was designed
+to record the worst case wakeups of RT tasks. Non-RT tasks are
+not recorded because the tracer only records one worst case and
+tracing non-RT tasks that are unpredictable will overwrite the
+worst case latency of RT tasks.
 
-Since this tracer only deals with RT tasks, we will run this slightly
-differently than we did with the previous tracers. Instead of performing
-an 'ls', we will run 'sleep 1' under 'chrt' which changes the
-priority of the task.
+Since this tracer only deals with RT tasks, we will run this
+slightly differently than we did with the previous tracers.
+Instead of performing an 'ls', we will run 'sleep 1' under
+'chrt' which changes the priority of the task.
 
  # echo wakeup > /debug/tracing/current_tracer
  # echo 0 > /debug/tracing/tracing_max_latency
@@ -934,17 +1018,16 @@
   <idle>-0     1d..4    4us : schedule (cpu_idle)
 
 
+Running this on an idle system, we see that it only took 4
+microseconds to perform the task switch.  Note, since the trace
+marker in the schedule is before the actual "switch", we stop
+the tracing when the recorded task is about to schedule in. This
+may change if we add a new marker at the end of the scheduler.
 
-Running this on an idle system, we see that it only took 4 microseconds
-to perform the task switch.  Note, since the trace marker in the
-schedule is before the actual "switch", we stop the tracing when
-the recorded task is about to schedule in. This may change if
-we add a new marker at the end of the scheduler.
-
-Notice that the recorded task is 'sleep' with the PID of 4901 and it
-has an rt_prio of 5. This priority is user-space priority and not
-the internal kernel priority. The policy is 1 for SCHED_FIFO and 2
-for SCHED_RR.
+Notice that the recorded task is 'sleep' with the PID of 4901
+and it has an rt_prio of 5. This priority is user-space priority
+and not the internal kernel priority. The policy is 1 for
+SCHED_FIFO and 2 for SCHED_RR.
 
 Doing the same with chrt -r 5 and ftrace_enabled set.
 
@@ -1001,24 +1084,25 @@
 ksoftirq-7     1d..6   49us : sub_preempt_count (_spin_unlock)
 ksoftirq-7     1d..4   50us : schedule (__cond_resched)
 
-The interrupt went off while running ksoftirqd. This task runs at
-SCHED_OTHER. Why did not we see the 'N' set early? This may be
-a harmless bug with x86_32 and 4K stacks. On x86_32 with 4K stacks
-configured, the interrupt and softirq run with their own stack.
-Some information is held on the top of the task's stack (need_resched
-and preempt_count are both stored there). The setting of the NEED_RESCHED
-bit is done directly to the task's stack, but the reading of the
-NEED_RESCHED is done by looking at the current stack, which in this case
-is the stack for the hard interrupt. This hides the fact that NEED_RESCHED
-has been set. We do not see the 'N' until we switch back to the task's
+The interrupt went off while running ksoftirqd. This task runs
+at SCHED_OTHER. Why did not we see the 'N' set early? This may
+be a harmless bug with x86_32 and 4K stacks. On x86_32 with 4K
+stacks configured, the interrupt and softirq run with their own
+stack. Some information is held on the top of the task's stack
+(need_resched and preempt_count are both stored there). The
+setting of the NEED_RESCHED bit is done directly to the task's
+stack, but the reading of the NEED_RESCHED is done by looking at
+the current stack, which in this case is the stack for the hard
+interrupt. This hides the fact that NEED_RESCHED has been set.
+We do not see the 'N' until we switch back to the task's
 assigned stack.
 
 function
 --------
 
 This tracer is the function tracer. Enabling the function tracer
-can be done from the debug file system. Make sure the ftrace_enabled is
-set; otherwise this tracer is a nop.
+can be done from the debug file system. Make sure the
+ftrace_enabled is set; otherwise this tracer is a nop.
 
  # sysctl kernel.ftrace_enabled=1
  # echo function > /debug/tracing/current_tracer
@@ -1048,14 +1132,15 @@
 [...]
 
 
-Note: function tracer uses ring buffers to store the above entries.
-The newest data may overwrite the oldest data. Sometimes using echo to
-stop the trace is not sufficient because the tracing could have overwritten
-the data that you wanted to record. For this reason, it is sometimes better to
-disable tracing directly from a program. This allows you to stop the
-tracing at the point that you hit the part that you are interested in.
-To disable the tracing directly from a C program, something like following
-code snippet can be used:
+Note: function tracer uses ring buffers to store the above
+entries. The newest data may overwrite the oldest data.
+Sometimes using echo to stop the trace is not sufficient because
+the tracing could have overwritten the data that you wanted to
+record. For this reason, it is sometimes better to disable
+tracing directly from a program. This allows you to stop the
+tracing at the point that you hit the part that you are
+interested in. To disable the tracing directly from a C program,
+something like following code snippet can be used:
 
 int trace_fd;
 [...]
@@ -1070,10 +1155,10 @@
 }
 
 Note: Here we hard coded the path name. The debugfs mount is not
-guaranteed to be at /debug (and is more commonly at /sys/kernel/debug).
-For simple one time traces, the above is sufficent. For anything else,
-a search through /proc/mounts may be needed to find where the debugfs
-file-system is mounted.
+guaranteed to be at /debug (and is more commonly at
+/sys/kernel/debug). For simple one time traces, the above is
+sufficent. For anything else, a search through /proc/mounts may
+be needed to find where the debugfs file-system is mounted.
 
 
 Single thread tracing
@@ -1152,49 +1237,297 @@
         return 0;
 }
 
+
+hw-branch-tracer (x86 only)
+---------------------------
+
+This tracer uses the x86 last branch tracing hardware feature to
+collect a branch trace on all cpus with relatively low overhead.
+
+The tracer uses a fixed-size circular buffer per cpu and only
+traces ring 0 branches. The trace file dumps that buffer in the
+following format:
+
+# tracer: hw-branch-tracer
+#
+# CPU#        TO  <-  FROM
+   0  scheduler_tick+0xb5/0x1bf	  <-  task_tick_idle+0x5/0x6
+   2  run_posix_cpu_timers+0x2b/0x72a	  <-  run_posix_cpu_timers+0x25/0x72a
+   0  scheduler_tick+0x139/0x1bf	  <-  scheduler_tick+0xed/0x1bf
+   0  scheduler_tick+0x17c/0x1bf	  <-  scheduler_tick+0x148/0x1bf
+   2  run_posix_cpu_timers+0x9e/0x72a	  <-  run_posix_cpu_timers+0x5e/0x72a
+   0  scheduler_tick+0x1b6/0x1bf	  <-  scheduler_tick+0x1aa/0x1bf
+
+
+The tracer may be used to dump the trace for the oops'ing cpu on
+a kernel oops into the system log. To enable this,
+ftrace_dump_on_oops must be set. To set ftrace_dump_on_oops, one
+can either use the sysctl function or set it via the proc system
+interface.
+
+  sysctl kernel.ftrace_dump_on_oops=1
+
+or
+
+  echo 1 > /proc/sys/kernel/ftrace_dump_on_oops
+
+
+Here's an example of such a dump after a null pointer
+dereference in a kernel module:
+
+[57848.105921] BUG: unable to handle kernel NULL pointer dereference at 0000000000000000
+[57848.106019] IP: [<ffffffffa0000006>] open+0x6/0x14 [oops]
+[57848.106019] PGD 2354e9067 PUD 2375e7067 PMD 0
+[57848.106019] Oops: 0002 [#1] SMP
+[57848.106019] last sysfs file: /sys/devices/pci0000:00/0000:00:1e.0/0000:20:05.0/local_cpus
+[57848.106019] Dumping ftrace buffer:
+[57848.106019] ---------------------------------
+[...]
+[57848.106019]    0  chrdev_open+0xe6/0x165	  <-  cdev_put+0x23/0x24
+[57848.106019]    0  chrdev_open+0x117/0x165	  <-  chrdev_open+0xfa/0x165
+[57848.106019]    0  chrdev_open+0x120/0x165	  <-  chrdev_open+0x11c/0x165
+[57848.106019]    0  chrdev_open+0x134/0x165	  <-  chrdev_open+0x12b/0x165
+[57848.106019]    0  open+0x0/0x14 [oops]	  <-  chrdev_open+0x144/0x165
+[57848.106019]    0  page_fault+0x0/0x30	  <-  open+0x6/0x14 [oops]
+[57848.106019]    0  error_entry+0x0/0x5b	  <-  page_fault+0x4/0x30
+[57848.106019]    0  error_kernelspace+0x0/0x31	  <-  error_entry+0x59/0x5b
+[57848.106019]    0  error_sti+0x0/0x1	  <-  error_kernelspace+0x2d/0x31
+[57848.106019]    0  page_fault+0x9/0x30	  <-  error_sti+0x0/0x1
+[57848.106019]    0  do_page_fault+0x0/0x881	  <-  page_fault+0x1a/0x30
+[...]
+[57848.106019]    0  do_page_fault+0x66b/0x881	  <-  is_prefetch+0x1ee/0x1f2
+[57848.106019]    0  do_page_fault+0x6e0/0x881	  <-  do_page_fault+0x67a/0x881
+[57848.106019]    0  oops_begin+0x0/0x96	  <-  do_page_fault+0x6e0/0x881
+[57848.106019]    0  trace_hw_branch_oops+0x0/0x2d	  <-  oops_begin+0x9/0x96
+[...]
+[57848.106019]    0  ds_suspend_bts+0x2a/0xe3	  <-  ds_suspend_bts+0x1a/0xe3
+[57848.106019] ---------------------------------
+[57848.106019] CPU 0
+[57848.106019] Modules linked in: oops
+[57848.106019] Pid: 5542, comm: cat Tainted: G        W  2.6.28 #23
+[57848.106019] RIP: 0010:[<ffffffffa0000006>]  [<ffffffffa0000006>] open+0x6/0x14 [oops]
+[57848.106019] RSP: 0018:ffff880235457d48  EFLAGS: 00010246
+[...]
+
+
+function graph tracer
+---------------------------
+
+This tracer is similar to the function tracer except that it
+probes a function on its entry and its exit. This is done by
+using a dynamically allocated stack of return addresses in each
+task_struct. On function entry the tracer overwrites the return
+address of each function traced to set a custom probe. Thus the
+original return address is stored on the stack of return address
+in the task_struct.
+
+Probing on both ends of a function leads to special features
+such as:
+
+- measure of a function's time execution
+- having a reliable call stack to draw function calls graph
+
+This tracer is useful in several situations:
+
+- you want to find the reason of a strange kernel behavior and
+  need to see what happens in detail on any areas (or specific
+  ones).
+
+- you are experiencing weird latencies but it's difficult to
+  find its origin.
+
+- you want to find quickly which path is taken by a specific
+  function
+
+- you just want to peek inside a working kernel and want to see
+  what happens there.
+
+# tracer: function_graph
+#
+# CPU  DURATION                  FUNCTION CALLS
+# |     |   |                     |   |   |   |
+
+ 0)               |  sys_open() {
+ 0)               |    do_sys_open() {
+ 0)               |      getname() {
+ 0)               |        kmem_cache_alloc() {
+ 0)   1.382 us    |          __might_sleep();
+ 0)   2.478 us    |        }
+ 0)               |        strncpy_from_user() {
+ 0)               |          might_fault() {
+ 0)   1.389 us    |            __might_sleep();
+ 0)   2.553 us    |          }
+ 0)   3.807 us    |        }
+ 0)   7.876 us    |      }
+ 0)               |      alloc_fd() {
+ 0)   0.668 us    |        _spin_lock();
+ 0)   0.570 us    |        expand_files();
+ 0)   0.586 us    |        _spin_unlock();
+
+
+There are several columns that can be dynamically
+enabled/disabled. You can use every combination of options you
+want, depending on your needs.
+
+- The cpu number on which the function executed is default
+  enabled.  It is sometimes better to only trace one cpu (see
+  tracing_cpu_mask file) or you might sometimes see unordered
+  function calls while cpu tracing switch.
+
+	hide: echo nofuncgraph-cpu > /debug/tracing/trace_options
+	show: echo funcgraph-cpu > /debug/tracing/trace_options
+
+- The duration (function's time of execution) is displayed on
+  the closing bracket line of a function or on the same line
+  than the current function in case of a leaf one. It is default
+  enabled.
+
+	hide: echo nofuncgraph-duration > /debug/tracing/trace_options
+	show: echo funcgraph-duration > /debug/tracing/trace_options
+
+- The overhead field precedes the duration field in case of
+  reached duration thresholds.
+
+	hide: echo nofuncgraph-overhead > /debug/tracing/trace_options
+	show: echo funcgraph-overhead > /debug/tracing/trace_options
+	depends on: funcgraph-duration
+
+  ie:
+
+  0)               |    up_write() {
+  0)   0.646 us    |      _spin_lock_irqsave();
+  0)   0.684 us    |      _spin_unlock_irqrestore();
+  0)   3.123 us    |    }
+  0)   0.548 us    |    fput();
+  0) + 58.628 us   |  }
+
+  [...]
+
+  0)               |      putname() {
+  0)               |        kmem_cache_free() {
+  0)   0.518 us    |          __phys_addr();
+  0)   1.757 us    |        }
+  0)   2.861 us    |      }
+  0) ! 115.305 us  |    }
+  0) ! 116.402 us  |  }
+
+  + means that the function exceeded 10 usecs.
+  ! means that the function exceeded 100 usecs.
+
+
+- The task/pid field displays the thread cmdline and pid which
+  executed the function. It is default disabled.
+
+	hide: echo nofuncgraph-proc > /debug/tracing/trace_options
+	show: echo funcgraph-proc > /debug/tracing/trace_options
+
+  ie:
+
+  # tracer: function_graph
+  #
+  # CPU  TASK/PID        DURATION                  FUNCTION CALLS
+  # |    |    |           |   |                     |   |   |   |
+  0)    sh-4802     |               |                  d_free() {
+  0)    sh-4802     |               |                    call_rcu() {
+  0)    sh-4802     |               |                      __call_rcu() {
+  0)    sh-4802     |   0.616 us    |                        rcu_process_gp_end();
+  0)    sh-4802     |   0.586 us    |                        check_for_new_grace_period();
+  0)    sh-4802     |   2.899 us    |                      }
+  0)    sh-4802     |   4.040 us    |                    }
+  0)    sh-4802     |   5.151 us    |                  }
+  0)    sh-4802     | + 49.370 us   |                }
+
+
+- The absolute time field is an absolute timestamp given by the
+  system clock since it started. A snapshot of this time is
+  given on each entry/exit of functions
+
+	hide: echo nofuncgraph-abstime > /debug/tracing/trace_options
+	show: echo funcgraph-abstime > /debug/tracing/trace_options
+
+  ie:
+
+  #
+  #      TIME       CPU  DURATION                  FUNCTION CALLS
+  #       |         |     |   |                     |   |   |   |
+  360.774522 |   1)   0.541 us    |                                          }
+  360.774522 |   1)   4.663 us    |                                        }
+  360.774523 |   1)   0.541 us    |                                        __wake_up_bit();
+  360.774524 |   1)   6.796 us    |                                      }
+  360.774524 |   1)   7.952 us    |                                    }
+  360.774525 |   1)   9.063 us    |                                  }
+  360.774525 |   1)   0.615 us    |                                  journal_mark_dirty();
+  360.774527 |   1)   0.578 us    |                                  __brelse();
+  360.774528 |   1)               |                                  reiserfs_prepare_for_journal() {
+  360.774528 |   1)               |                                    unlock_buffer() {
+  360.774529 |   1)               |                                      wake_up_bit() {
+  360.774529 |   1)               |                                        bit_waitqueue() {
+  360.774530 |   1)   0.594 us    |                                          __phys_addr();
+
+
+You can put some comments on specific functions by using
+trace_printk() For example, if you want to put a comment inside
+the __might_sleep() function, you just have to include
+<linux/ftrace.h> and call trace_printk() inside __might_sleep()
+
+trace_printk("I'm a comment!\n")
+
+will produce:
+
+ 1)               |             __might_sleep() {
+ 1)               |                /* I'm a comment! */
+ 1)   1.449 us    |             }
+
+
+You might find other useful features for this tracer in the
+following "dynamic ftrace" section such as tracing only specific
+functions or tasks.
+
 dynamic ftrace
 --------------
 
 If CONFIG_DYNAMIC_FTRACE is set, the system will run with
 virtually no overhead when function tracing is disabled. The way
 this works is the mcount function call (placed at the start of
-every kernel function, produced by the -pg switch in gcc), starts
-of pointing to a simple return. (Enabling FTRACE will include the
--pg switch in the compiling of the kernel.)
+every kernel function, produced by the -pg switch in gcc),
+starts of pointing to a simple return. (Enabling FTRACE will
+include the -pg switch in the compiling of the kernel.)
 
 At compile time every C file object is run through the
 recordmcount.pl script (located in the scripts directory). This
 script will process the C object using objdump to find all the
-locations in the .text section that call mcount. (Note, only
-the .text section is processed, since processing other sections
-like .init.text may cause races due to those sections being freed).
+locations in the .text section that call mcount. (Note, only the
+.text section is processed, since processing other sections like
+.init.text may cause races due to those sections being freed).
 
-A new section called "__mcount_loc" is created that holds references
-to all the mcount call sites in the .text section. This section is
-compiled back into the original object. The final linker will add
-all these references into a single table.
+A new section called "__mcount_loc" is created that holds
+references to all the mcount call sites in the .text section.
+This section is compiled back into the original object. The
+final linker will add all these references into a single table.
 
 On boot up, before SMP is initialized, the dynamic ftrace code
-scans this table and updates all the locations into nops. It also
-records the locations, which are added to the available_filter_functions
-list.  Modules are processed as they are loaded and before they are
-executed.  When a module is unloaded, it also removes its functions from
-the ftrace function list. This is automatic in the module unload
-code, and the module author does not need to worry about it.
+scans this table and updates all the locations into nops. It
+also records the locations, which are added to the
+available_filter_functions list.  Modules are processed as they
+are loaded and before they are executed.  When a module is
+unloaded, it also removes its functions from the ftrace function
+list. This is automatic in the module unload code, and the
+module author does not need to worry about it.
 
-When tracing is enabled, kstop_machine is called to prevent races
-with the CPUS executing code being modified (which can cause the
-CPU to do undesireable things), and the nops are patched back
-to calls. But this time, they do not call mcount (which is just
-a function stub). They now call into the ftrace infrastructure.
+When tracing is enabled, kstop_machine is called to prevent
+races with the CPUS executing code being modified (which can
+cause the CPU to do undesireable things), and the nops are
+patched back to calls. But this time, they do not call mcount
+(which is just a function stub). They now call into the ftrace
+infrastructure.
 
 One special side-effect to the recording of the functions being
 traced is that we can now selectively choose which functions we
-wish to trace and which ones we want the mcount calls to remain as
-nops.
+wish to trace and which ones we want the mcount calls to remain
+as nops.
 
-Two files are used, one for enabling and one for disabling the tracing
-of specified functions. They are:
+Two files are used, one for enabling and one for disabling the
+tracing of specified functions. They are:
 
   set_ftrace_filter
 
@@ -1202,8 +1535,8 @@
 
   set_ftrace_notrace
 
-A list of available functions that you can add to these files is listed
-in:
+A list of available functions that you can add to these files is
+listed in:
 
    available_filter_functions
 
@@ -1240,8 +1573,8 @@
 sys_nanosleep
 
 
-Perhaps this is not enough. The filters also allow simple wild cards.
-Only the following are currently available
+Perhaps this is not enough. The filters also allow simple wild
+cards. Only the following are currently available
 
   <match>*  - will match functions that begin with <match>
   *<match>  - will match functions that end with <match>
@@ -1251,9 +1584,9 @@
 
   <match>*<match> will not work.
 
-Note: It is better to use quotes to enclose the wild cards, otherwise
-  the shell may expand the parameters into names of files in the local
-  directory.
+Note: It is better to use quotes to enclose the wild cards,
+      otherwise the shell may expand the parameters into names
+      of files in the local directory.
 
  # echo 'hrtimer_*' > /debug/tracing/set_ftrace_filter
 
@@ -1299,7 +1632,8 @@
 To rewrite the filters, use '>'
 To append to the filters, use '>>'
 
-To clear out a filter so that all functions will be recorded again:
+To clear out a filter so that all functions will be recorded
+again:
 
  # echo > /debug/tracing/set_ftrace_filter
  # cat /debug/tracing/set_ftrace_filter
@@ -1331,7 +1665,8 @@
 hrtimer_init_sleeper
 
 
-The set_ftrace_notrace prevents those functions from being traced.
+The set_ftrace_notrace prevents those functions from being
+traced.
 
  # echo '*preempt*' '*lock*' > /debug/tracing/set_ftrace_notrace
 
@@ -1353,13 +1688,75 @@
 
 We can see that there's no more lock or preempt tracing.
 
+
+Dynamic ftrace with the function graph tracer
+---------------------------------------------
+
+Although what has been explained above concerns both the
+function tracer and the function-graph-tracer, there are some
+special features only available in the function-graph tracer.
+
+If you want to trace only one function and all of its children,
+you just have to echo its name into set_graph_function:
+
+ echo __do_fault > set_graph_function
+
+will produce the following "expanded" trace of the __do_fault()
+function:
+
+ 0)               |  __do_fault() {
+ 0)               |    filemap_fault() {
+ 0)               |      find_lock_page() {
+ 0)   0.804 us    |        find_get_page();
+ 0)               |        __might_sleep() {
+ 0)   1.329 us    |        }
+ 0)   3.904 us    |      }
+ 0)   4.979 us    |    }
+ 0)   0.653 us    |    _spin_lock();
+ 0)   0.578 us    |    page_add_file_rmap();
+ 0)   0.525 us    |    native_set_pte_at();
+ 0)   0.585 us    |    _spin_unlock();
+ 0)               |    unlock_page() {
+ 0)   0.541 us    |      page_waitqueue();
+ 0)   0.639 us    |      __wake_up_bit();
+ 0)   2.786 us    |    }
+ 0) + 14.237 us   |  }
+ 0)               |  __do_fault() {
+ 0)               |    filemap_fault() {
+ 0)               |      find_lock_page() {
+ 0)   0.698 us    |        find_get_page();
+ 0)               |        __might_sleep() {
+ 0)   1.412 us    |        }
+ 0)   3.950 us    |      }
+ 0)   5.098 us    |    }
+ 0)   0.631 us    |    _spin_lock();
+ 0)   0.571 us    |    page_add_file_rmap();
+ 0)   0.526 us    |    native_set_pte_at();
+ 0)   0.586 us    |    _spin_unlock();
+ 0)               |    unlock_page() {
+ 0)   0.533 us    |      page_waitqueue();
+ 0)   0.638 us    |      __wake_up_bit();
+ 0)   2.793 us    |    }
+ 0) + 14.012 us   |  }
+
+You can also expand several functions at once:
+
+ echo sys_open > set_graph_function
+ echo sys_close >> set_graph_function
+
+Now if you want to go back to trace all functions you can clear
+this special filter via:
+
+ echo > set_graph_function
+
+
 trace_pipe
 ----------
 
-The trace_pipe outputs the same content as the trace file, but the effect
-on the tracing is different. Every read from trace_pipe is consumed.
-This means that subsequent reads will be different. The trace
-is live.
+The trace_pipe outputs the same content as the trace file, but
+the effect on the tracing is different. Every read from
+trace_pipe is consumed. This means that subsequent reads will be
+different. The trace is live.
 
  # echo function > /debug/tracing/current_tracer
  # cat /debug/tracing/trace_pipe > /tmp/trace.out &
@@ -1387,38 +1784,45 @@
             bash-4043  [00] 41.267111: select_task_rq_rt <-try_to_wake_up
 
 
-Note, reading the trace_pipe file will block until more input is added.
-By changing the tracer, trace_pipe will issue an EOF. We needed
-to set the function tracer _before_ we "cat" the trace_pipe file.
+Note, reading the trace_pipe file will block until more input is
+added. By changing the tracer, trace_pipe will issue an EOF. We
+needed to set the function tracer _before_ we "cat" the
+trace_pipe file.
 
 
 trace entries
 -------------
 
-Having too much or not enough data can be troublesome in diagnosing
-an issue in the kernel. The file buffer_size_kb is used to modify
-the size of the internal trace buffers. The number listed
-is the number of entries that can be recorded per CPU. To know
-the full size, multiply the number of possible CPUS with the
-number of entries.
+Having too much or not enough data can be troublesome in
+diagnosing an issue in the kernel. The file buffer_size_kb is
+used to modify the size of the internal trace buffers. The
+number listed is the number of entries that can be recorded per
+CPU. To know the full size, multiply the number of possible CPUS
+with the number of entries.
 
  # cat /debug/tracing/buffer_size_kb
 1408 (units kilobytes)
 
-Note, to modify this, you must have tracing completely disabled. To do that,
-echo "nop" into the current_tracer. If the current_tracer is not set
-to "nop", an EINVAL error will be returned.
+Note, to modify this, you must have tracing completely disabled.
+To do that, echo "nop" into the current_tracer. If the
+current_tracer is not set to "nop", an EINVAL error will be
+returned.
 
  # echo nop > /debug/tracing/current_tracer
  # echo 10000 > /debug/tracing/buffer_size_kb
  # cat /debug/tracing/buffer_size_kb
 10000 (units kilobytes)
 
-The number of pages which will be allocated is limited to a percentage
-of available memory. Allocating too much will produce an error.
+The number of pages which will be allocated is limited to a
+percentage of available memory. Allocating too much will produce
+an error.
 
  # echo 1000000000000 > /debug/tracing/buffer_size_kb
 -bash: echo: write error: Cannot allocate memory
  # cat /debug/tracing/buffer_size_kb
 85
 
+-----------
+
+More details can be found in the source code, in the
+kernel/tracing/*.c files.
diff --git a/Documentation/ia64/kvm.txt b/Documentation/ia64/kvm.txt
index 84f7cb3..ffb5c80 100644
--- a/Documentation/ia64/kvm.txt
+++ b/Documentation/ia64/kvm.txt
@@ -42,7 +42,7 @@
 		hg clone http://xenbits.xensource.com/ext/efi-vfirmware.hg
 	    you can get the firmware's binary in the directory of efi-vfirmware.hg/binaries.
 
-	(3) Rename the firware you owned to Flash.fd, and copy it to /usr/local/share/qemu
+	(3) Rename the firmware you owned to Flash.fd, and copy it to /usr/local/share/qemu
 
 4. Boot up Linux or Windows guests:
 	4.1 Create or install a image for guest boot. If you have xen experience, it should be easy.
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 240257d..2895ce2 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -50,6 +50,7 @@
 	ISAPNP	ISA PnP code is enabled.
 	ISDN	Appropriate ISDN support is enabled.
 	JOY	Appropriate joystick support is enabled.
+	KMEMTRACE kmemtrace is enabled.
 	LIBATA  Libata driver is enabled
 	LP	Printer support is enabled.
 	LOOP	Loopback device support is enabled.
@@ -259,6 +260,22 @@
 			to assume that this machine's pmtimer latches its value
 			and always returns good values.
 
+	acpi_enforce_resources=	[ACPI]
+			{ strict | lax | no }
+			Check for resource conflicts between native drivers
+			and ACPI OperationRegions (SystemIO and SystemMemory
+			only). IO ports and memory declared in ACPI might be
+			used by the ACPI subsystem in arbitrary AML code and
+			can interfere with legacy drivers.
+			strict (default): access to resources claimed by ACPI
+			is denied; legacy drivers trying to access reserved
+			resources will fail to bind to device using them.
+			lax: access to resources claimed by ACPI is allowed;
+			legacy drivers trying to access reserved resources
+			will bind successfully but a warning message is logged.
+			no: ACPI OperationRegions are not marked as reserved,
+			no further checks are performed.
+
 	agp=		[AGP]
 			{ off | try_unsupported }
 			off: disable AGP support
@@ -617,6 +634,9 @@
 
 	debug_objects	[KNL] Enable object debugging
 
+	no_debug_objects
+			[KNL] Disable object debugging
+
 	debugpat	[X86] Enable PAT debugging
 
 	decnet.addr=	[HW,NET]
@@ -1078,6 +1098,15 @@
 			use the HighMem zone if it exists, and the Normal
 			zone if it does not.
 
+	kmemtrace.enable=	[KNL,KMEMTRACE] Format: { yes | no }
+				Controls whether kmemtrace is enabled
+				at boot-time.
+
+	kmemtrace.subbufs=n	[KNL,KMEMTRACE] Overrides the number of
+			subbufs kmemtrace's relay channel has. Set this
+			higher than default (KMEMTRACE_N_SUBBUFS in code) if
+			you experience buffer overruns.
+
 	movablecore=nn[KMG]	[KNL,X86-32,IA-64,PPC,X86-64] This parameter
 			is similar to kernelcore except it specifies the
 			amount of memory used for migratable allocations.
@@ -1523,7 +1552,9 @@
 
 	noclflush	[BUGS=X86] Don't use the CLFLUSH instruction
 
-	nohlt		[BUGS=ARM,SH]
+	nohlt		[BUGS=ARM,SH] Tells the kernel that the sleep(SH) or
+			wfi(ARM) instruction doesn't work correctly and not to
+			use it. This is also useful when using JTAG debugger.
 
 	no-hlt		[BUGS=X86-32] Tells the kernel that the hlt
 			instruction doesn't work correctly and not to
@@ -1544,6 +1575,8 @@
 			Valid arguments: on, off
 			Default: on
 
+	noiotrap	[SH] Disables trapped I/O port accesses.
+
 	noirqdebug	[X86-32] Disables the code which attempts to detect and
 			disable unhandled interrupt sources.
 
@@ -1603,7 +1636,7 @@
 	nosoftlockup	[KNL] Disable the soft-lockup detector.
 
 	noswapaccount	[KNL] Disable accounting of swap in memory resource
-			controller. (See Documentation/controllers/memory.txt)
+			controller. (See Documentation/cgroups/memory.txt)
 
 	nosync		[HW,M68K] Disables sync negotiation for all devices.
 
@@ -1953,7 +1986,7 @@
 
 	relax_domain_level=
 			[KNL, SMP] Set scheduler's default relax_domain_level.
-			See Documentation/cpusets.txt.
+			See Documentation/cgroups/cpusets.txt.
 
 	reserve=	[KNL,BUGS] Force the kernel to ignore some iomem area
 
@@ -2362,6 +2395,8 @@
 
 	tp720=		[HW,PS2]
 
+	trace_buf_size=nn[KMG] [ftrace] will set tracing buffer size.
+
 	trix=		[HW,OSS] MediaTrix AudioTrix Pro
 			Format:
 			<io>,<irq>,<dma>,<dma2>,<sb_io>,<sb_irq>,<sb_dma>,<mpu_io>,<mpu_irq>
diff --git a/Documentation/laptops/acer-wmi.txt b/Documentation/laptops/acer-wmi.txt
index 2b3a6b5..5ee2a02 100644
--- a/Documentation/laptops/acer-wmi.txt
+++ b/Documentation/laptops/acer-wmi.txt
@@ -1,9 +1,9 @@
 Acer Laptop WMI Extras Driver
 http://code.google.com/p/aceracpi
-Version 0.2
-18th August 2008
+Version 0.3
+4th April 2009
 
-Copyright 2007-2008 Carlos Corbacho <carlos@strangeworlds.co.uk>
+Copyright 2007-2009 Carlos Corbacho <carlos@strangeworlds.co.uk>
 
 acer-wmi is a driver to allow you to control various parts of your Acer laptop
 hardware under Linux which are exposed via ACPI-WMI.
@@ -36,6 +36,10 @@
 Supported Hardware
 ******************
 
+NOTE: The Acer Aspire One is not supported hardware. It cannot work with
+acer-wmi until Acer fix their ACPI-WMI implementation on them, so has been
+blacklisted until that happens.
+
 Please see the website for the current list of known working hardare:
 
 http://code.google.com/p/aceracpi/wiki/SupportedHardware
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt
index 41bc99f..3d76507 100644
--- a/Documentation/laptops/thinkpad-acpi.txt
+++ b/Documentation/laptops/thinkpad-acpi.txt
@@ -20,7 +20,8 @@
 kernel 2.6.29 and release 0.22.
 
 The driver is named "thinkpad-acpi".  In some places, like module
-names, "thinkpad_acpi" is used because of userspace issues.
+names and log messages, "thinkpad_acpi" is used because of userspace
+issues.
 
 "tpacpi" is used as a shorthand where "thinkpad-acpi" would be too
 long due to length limitations on some Linux kernel versions.
@@ -37,7 +38,7 @@
 	- ThinkLight on and off
 	- limited docking and undocking
 	- UltraBay eject
-	- CMOS control
+	- CMOS/UCMS control
 	- LED control
 	- ACPI sounds
 	- temperature sensors
@@ -46,6 +47,7 @@
 	- Volume control
 	- Fan control and monitoring: fan speed, fan enable/disable
 	- WAN enable and disable
+	- UWB enable and disable
 
 A compatibility table by model and feature is maintained on the web
 site, http://ibm-acpi.sf.net/. I appreciate any success or failure
@@ -53,7 +55,7 @@
 Please include the following information in your report:
 
 	- ThinkPad model name
-	- a copy of your DSDT, from /proc/acpi/dsdt
+	- a copy of your ACPI tables, using the "acpidump" utility
 	- a copy of the output of dmidecode, with serial numbers
 	  and UUIDs masked off
 	- which driver features work and which don't
@@ -66,17 +68,18 @@
 ------------
 
 If you are compiling this driver as included in the Linux kernel
-sources, simply enable the CONFIG_THINKPAD_ACPI option, and optionally
-enable the CONFIG_THINKPAD_ACPI_BAY option if you want the
-thinkpad-specific bay functionality.
+sources, look for the CONFIG_THINKPAD_ACPI Kconfig option.
+It is located on the menu path: "Device Drivers" -> "X86 Platform
+Specific Device Drivers" -> "ThinkPad ACPI Laptop Extras".
+
 
 Features
 --------
 
 The driver exports two different interfaces to userspace, which can be
 used to access the features it provides.  One is a legacy procfs-based
-interface, which will be removed at some time in the distant future.
-The other is a new sysfs-based interface which is not complete yet.
+interface, which will be removed at some time in the future.  The other
+is a new sysfs-based interface which is not complete yet.
 
 The procfs interface creates the /proc/acpi/ibm directory.  There is a
 file under that directory for each feature it supports.  The procfs
@@ -111,15 +114,17 @@
 as a driver attribute (see below).
 
 Sysfs driver attributes are on the driver's sysfs attribute space,
-for 2.6.23 this is /sys/bus/platform/drivers/thinkpad_acpi/ and
+for 2.6.23+ this is /sys/bus/platform/drivers/thinkpad_acpi/ and
 /sys/bus/platform/drivers/thinkpad_hwmon/
 
 Sysfs device attributes are on the thinkpad_acpi device sysfs attribute
-space, for 2.6.23 this is /sys/devices/platform/thinkpad_acpi/.
+space, for 2.6.23+ this is /sys/devices/platform/thinkpad_acpi/.
 
 Sysfs device attributes for the sensors and fan are on the
 thinkpad_hwmon device's sysfs attribute space, but you should locate it
-looking for a hwmon device with the name attribute of "thinkpad".
+looking for a hwmon device with the name attribute of "thinkpad", or
+better yet, through libsensors.
+
 
 Driver version
 --------------
@@ -129,6 +134,7 @@
 
 The driver name and version. No commands can be written to this file.
 
+
 Sysfs interface version
 -----------------------
 
@@ -160,6 +166,7 @@
 (an attribute not being there *is* a valid way to make it clear that a
 feature is not available in sysfs).
 
+
 Hot keys
 --------
 
@@ -172,17 +179,14 @@
 firmware that such a driver is present, and modifies how the ThinkPad
 firmware will behave in many situations.
 
-The driver enables the hot key feature automatically when loaded.  The
-feature can later be disabled and enabled back at runtime.  The driver
-will also restore the hot key feature to its previous state and mask
-when it is unloaded.
+The driver enables the HKEY ("hot key") event reporting automatically
+when loaded, and disables it when it is removed.
 
-When the hotkey feature is enabled and the hot key mask is set (see
-below), the driver will report HKEY events in the following format:
+The driver will report HKEY events in the following format:
 
 	ibm/hotkey HKEY 00000080 0000xxxx
 
-Some of these events refer to hot key presses, but not all.
+Some of these events refer to hot key presses, but not all of them.
 
 The driver will generate events over the input layer for hot keys and
 radio switches, and over the ACPI netlink layer for other events.  The
@@ -214,13 +218,17 @@
 
 The following commands can be written to the /proc/acpi/ibm/hotkey file:
 
-	echo enable > /proc/acpi/ibm/hotkey -- enable the hot keys feature
-	echo disable > /proc/acpi/ibm/hotkey -- disable the hot keys feature
 	echo 0xffffffff > /proc/acpi/ibm/hotkey -- enable all hot keys
 	echo 0 > /proc/acpi/ibm/hotkey -- disable all possible hot keys
 	... any other 8-hex-digit mask ...
 	echo reset > /proc/acpi/ibm/hotkey -- restore the original mask
 
+The following commands have been deprecated and will cause the kernel
+to log a warning:
+
+	echo enable > /proc/acpi/ibm/hotkey -- does nothing
+	echo disable > /proc/acpi/ibm/hotkey -- returns an error
+
 The procfs interface does not support NVRAM polling control.  So as to
 maintain maximum bug-to-bug compatibility, it does not report any masks,
 nor does it allow one to manipulate the hot key mask when the firmware
@@ -229,12 +237,9 @@
 sysfs notes:
 
 	hotkey_bios_enabled:
-		Returns the status of the hot keys feature when
-		thinkpad-acpi was loaded.  Upon module unload, the hot
-		key feature status will be restored to this value.
+		DEPRECATED, WILL BE REMOVED SOON.
 
-		0: hot keys were disabled
-		1: hot keys were enabled (unusual)
+		Returns 0.
 
 	hotkey_bios_mask:
 		Returns the hot keys mask when thinkpad-acpi was loaded.
@@ -242,13 +247,10 @@
 		to this value.
 
 	hotkey_enable:
-		Enables/disables the hot keys feature in the ACPI
-		firmware, and reports current status of the hot keys
-		feature.  Has no effect on the NVRAM hot key polling
-		functionality.
+		DEPRECATED, WILL BE REMOVED SOON.
 
-		0: disables the hot keys feature / feature disabled
-		1: enables the hot keys feature / feature enabled
+		0: returns -EPERM
+		1: does nothing
 
 	hotkey_mask:
 		bit mask to enable driver-handling (and depending on
@@ -618,6 +620,7 @@
    and map them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN.  Process
    these keys on userspace somehow (e.g. by calling xbacklight).
 
+
 Bluetooth
 ---------
 
@@ -628,6 +631,9 @@
 This feature shows the presence and current state of a ThinkPad
 Bluetooth device in the internal ThinkPad CDC slot.
 
+If the ThinkPad supports it, the Bluetooth state is stored in NVRAM,
+so it is kept across reboots and power-off.
+
 Procfs notes:
 
 If Bluetooth is installed, the following commands can be used:
@@ -652,6 +658,7 @@
 	rfkill controller switch "tpacpi_bluetooth_sw": refer to
 	Documentation/rfkill.txt for details.
 
+
 Video output control -- /proc/acpi/ibm/video
 --------------------------------------------
 
@@ -693,11 +700,8 @@
 features of this driver, as it uses the same ACPI methods as
 Fn-F7. Video switching on the console should still work.
 
-UPDATE: There's now a patch for the X.org Radeon driver which
-addresses this issue. Some people are reporting success with the patch
-while others are still having problems. For more information:
+UPDATE: refer to https://bugs.freedesktop.org/show_bug.cgi?id=2000
 
-https://bugs.freedesktop.org/show_bug.cgi?id=2000
 
 ThinkLight control
 ------------------
@@ -720,10 +724,11 @@
 documentation, in Documentation/leds-class.txt.  The ThinkLight LED name
 is "tpacpi::thinklight".
 
-Due to limitations in the sysfs LED class, if the status of the thinklight
+Due to limitations in the sysfs LED class, if the status of the ThinkLight
 cannot be read or if it is unknown, thinkpad-acpi will report it as "off".
 It is impossible to know if the status returned through sysfs is valid.
 
+
 Docking / undocking -- /proc/acpi/ibm/dock
 ------------------------------------------
 
@@ -784,6 +789,7 @@
 UltraBase docks and "dumb" port replicators like the Mini Dock (the
 latter don't need any ACPI support, actually).
 
+
 UltraBay eject -- /proc/acpi/ibm/bay
 ------------------------------------
 
@@ -847,8 +853,9 @@
 Note: the UltraBay eject support on the 600e/x, A22p and A3x is
 EXPERIMENTAL and may not work as expected. USE WITH CAUTION!
 
-CMOS control
-------------
+
+CMOS/UCMS control
+-----------------
 
 procfs: /proc/acpi/ibm/cmos
 sysfs device attribute: cmos_command
@@ -882,6 +889,7 @@
 in newer ThinkPads it is just a compatibility layer.  Do not use it, it is
 exported just as a debug tool.
 
+
 LED control
 -----------
 
@@ -893,6 +901,17 @@
 LED indicators as well.  Newer ThinkPads cannot query the real status
 of the LED indicators.
 
+Because misuse of the LEDs could induce an unaware user to perform
+dangerous actions (like undocking or ejecting a bay device while the
+buses are still active), or mask an important alarm (such as a nearly
+empty battery, or a broken battery), access to most LEDs is
+restricted.
+
+Unrestricted access to all LEDs requires that thinkpad-acpi be
+compiled with the CONFIG_THINKPAD_ACPI_UNSAFE_LEDS option enabled.
+Distributions must never enable this option.  Individual users that
+are aware of the consequences are welcome to enabling it.
+
 procfs notes:
 
 The available commands are:
@@ -939,6 +958,7 @@
 "timer" trigger, and leave the delay_on and delay_off parameters set to
 zero (to request hardware acceleration autodetection).
 
+
 ACPI sounds -- /proc/acpi/ibm/beep
 ----------------------------------
 
@@ -968,6 +988,7 @@
 	16 - one medium-pitched beep repeating constantly, stop with 17
 	17 - stop 16
 
+
 Temperature sensors
 -------------------
 
@@ -1115,6 +1136,7 @@
 with this, do send me your results (including some complete dumps with
 a description of the conditions when they were taken.)
 
+
 LCD brightness control
 ----------------------
 
@@ -1124,10 +1146,9 @@
 This feature allows software control of the LCD brightness on ThinkPad
 models which don't have a hardware brightness slider.
 
-It has some limitations: the LCD backlight cannot be actually turned on or
-off by this interface, and in many ThinkPad models, the "dim while on
-battery" functionality will be enabled by the BIOS when this interface is
-used, and cannot be controlled.
+It has some limitations: the LCD backlight cannot be actually turned
+on or off by this interface, it just controls the backlight brightness
+level.
 
 On IBM (and some of the earlier Lenovo) ThinkPads, the backlight control
 has eight brightness levels, ranging from 0 to 7.  Some of the levels
@@ -1136,10 +1157,15 @@
 from 0 to 15.
 
 There are two interfaces to the firmware for direct brightness control,
-EC and CMOS.  To select which one should be used, use the
+EC and UCMS (or CMOS).  To select which one should be used, use the
 brightness_mode module parameter: brightness_mode=1 selects EC mode,
-brightness_mode=2 selects CMOS mode, brightness_mode=3 selects both EC
-and CMOS.  The driver tries to auto-detect which interface to use.
+brightness_mode=2 selects UCMS mode, brightness_mode=3 selects EC
+mode with NVRAM backing (so that brightness changes are remembered
+across shutdown/reboot).
+
+The driver tries to select which interface to use from a table of
+defaults for each ThinkPad model.  If it makes a wrong choice, please
+report this as a bug, so that we can fix it.
 
 When display backlight brightness controls are available through the
 standard ACPI interface, it is best to use it instead of this direct
@@ -1201,6 +1227,7 @@
     and maybe reduce the life of the backlight lamps by needlessly kicking
     its level up and down at every change.
 
+
 Volume control -- /proc/acpi/ibm/volume
 ---------------------------------------
 
@@ -1217,6 +1244,11 @@
 up or down command (the level command will not unmute the volume).
 The current volume level and mute state is shown in the file.
 
+The ALSA mixer interface to this feature is still missing, but patches
+to add it exist.  That problem should be addressed in the not so
+distant future.
+
+
 Fan control and monitoring: fan speed, fan enable/disable
 ---------------------------------------------------------
 
@@ -1383,8 +1415,11 @@
 sysfs device attribute: wwan_enable (deprecated)
 sysfs rfkill class: switch "tpacpi_wwan_sw"
 
-This feature shows the presence and current state of a W-WAN (Sierra
-Wireless EV-DO) device.
+This feature shows the presence and current state of the built-in
+Wireless WAN device.
+
+If the ThinkPad supports it, the WWAN state is stored in NVRAM,
+so it is kept across reboots and power-off.
 
 It was tested on a Lenovo ThinkPad X60. It should probably work on other
 ThinkPad models which come with this module installed.
@@ -1413,6 +1448,7 @@
 	rfkill controller switch "tpacpi_wwan_sw": refer to
 	Documentation/rfkill.txt for details.
 
+
 EXPERIMENTAL: UWB
 -----------------
 
@@ -1431,6 +1467,7 @@
 	rfkill controller switch "tpacpi_uwb_sw": refer to
 	Documentation/rfkill.txt for details.
 
+
 Multiple Commands, Module Parameters
 ------------------------------------
 
@@ -1445,6 +1482,7 @@
 
 	modprobe thinkpad_acpi hotkey=enable,0xffff video=auto_disable
 
+
 Enabling debugging output
 -------------------------
 
@@ -1457,8 +1495,15 @@
 to enable more than one output class, just add their values.
 
 	Debug bitmask		Description
+	0x8000			Disclose PID of userspace programs
+				accessing some functions of the driver
 	0x0001			Initialization and probing
 	0x0002			Removal
+	0x0004			RF Transmitter control (RFKILL)
+				(bluetooth, WWAN, UWB...)
+	0x0008			HKEY event interface, hotkeys
+	0x0010			Fan control
+	0x0020			Backlight brightness
 
 There is also a kernel build option to enable more debugging
 information, which may be necessary to debug driver problems.
@@ -1467,6 +1512,7 @@
 at runtime through sysfs, using the driver attribute debug_level.  The
 attribute takes the same bitmask as the debug module parameter above.
 
+
 Force loading of module
 -----------------------
 
@@ -1505,3 +1551,7 @@
 
 0x020200:	Add poll()/select() support to the following attributes:
 		hotkey_radio_sw, wakeup_hotunplug_complete, wakeup_reason
+
+0x020300:	hotkey enable/disable support removed, attributes
+		hotkey_bios_enabled and hotkey_enable deprecated and
+		marked for removal.
diff --git a/Documentation/md.txt b/Documentation/md.txt
index 1da9d1b..4edd39e 100644
--- a/Documentation/md.txt
+++ b/Documentation/md.txt
@@ -164,15 +164,19 @@
   raid_disks
      a text file with a simple number indicating the number of devices
      in a fully functional array.  If this is not yet known, the file
-     will be empty.  If an array is being resized (not currently
-     possible) this will contain the larger of the old and new sizes.
-     Some raid level (RAID1) allow this value to be set while the
-     array is active.  This will reconfigure the array.   Otherwise
-     it can only be set while assembling an array.
+     will be empty.  If an array is being resized this will contain
+     the new number of devices.
+     Some raid levels allow this value to be set while the array is
+     active.  This will reconfigure the array.   Otherwise it can only
+     be set while assembling an array.
+     A change to this attribute will not be permitted if it would
+     reduce the size of the array.  To reduce the number of drives
+     in an e.g. raid5, the array size must first be reduced by
+     setting the 'array_size' attribute.
 
   chunk_size
-     This is the size if bytes for 'chunks' and is only relevant to
-     raid levels that involve striping (1,4,5,6,10). The address space
+     This is the size in bytes for 'chunks' and is only relevant to
+     raid levels that involve striping (0,4,5,6,10). The address space
      of the array is conceptually divided into chunks and consecutive
      chunks are striped onto neighbouring devices.
      The size should be at least PAGE_SIZE (4k) and should be a power
@@ -183,6 +187,20 @@
      simply a number that is interpretted differently by different
      levels.  It can be written while assembling an array.
 
+  array_size
+     This can be used to artificially constrain the available space in
+     the array to be less than is actually available on the combined
+     devices.  Writing a number (in Kilobytes) which is less than
+     the available size will set the size.  Any reconfiguration of the
+     array (e.g. adding devices) will not cause the size to change.
+     Writing the word 'default' will cause the effective size of the
+     array to be whatever size is actually available based on
+     'level', 'chunk_size' and 'component_size'.
+
+     This can be used to reduce the size of the array before reducing
+     the number of devices in a raid4/5/6, or to support external
+     metadata formats which mandate such clipping.
+
   reshape_position
      This is either "none" or a sector number within the devices of
      the array where "reshape" is up to.  If this is set, the three
@@ -207,6 +225,11 @@
      about the array.  It can be 0.90 (traditional format), 1.0, 1.1,
      1.2 (newer format in varying locations) or "none" indicating that
      the kernel isn't managing metadata at all.
+     Alternately it can be "external:" followed by a string which
+     is set by user-space.  This indicates that metadata is managed
+     by a user-space program.  Any device failure or other event that
+     requires a metadata update will cause array activity to be
+     suspended until the event is acknowledged.
 
   resync_start
      The point at which resync should start.  If no resync is needed,
diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt
index 6c238f5..249db3a 100644
--- a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt
+++ b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt
@@ -1,6 +1,6 @@
 * Uploaded QE firmware
 
-      If a new firwmare has been uploaded to the QE (usually by the
+      If a new firmware has been uploaded to the QE (usually by the
       boot loader), then a 'firmware' child node should be added to the QE
       node.  This node provides information on the uploaded firmware that
       device drivers may need.
diff --git a/Documentation/powerpc/dts-bindings/gpio/led.txt b/Documentation/powerpc/dts-bindings/gpio/led.txt
index ff51f4c0..4fe14de 100644
--- a/Documentation/powerpc/dts-bindings/gpio/led.txt
+++ b/Documentation/powerpc/dts-bindings/gpio/led.txt
@@ -1,15 +1,43 @@
-LED connected to GPIO
+LEDs connected to GPIO lines
 
 Required properties:
-- compatible : should be "gpio-led".
-- label : (optional) the label for this LED. If omitted, the label is
+- compatible : should be "gpio-leds".
+
+Each LED is represented as a sub-node of the gpio-leds device.  Each
+node's name represents the name of the corresponding LED.
+
+LED sub-node properties:
+- gpios :  Should specify the LED's GPIO, see "Specifying GPIO information
+  for devices" in Documentation/powerpc/booting-without-of.txt.  Active
+  low LEDs should be indicated using flags in the GPIO specifier.
+- label :  (optional) The label for this LED.  If omitted, the label is
   taken from the node name (excluding the unit address).
-- gpios : should specify LED GPIO.
+- linux,default-trigger :  (optional) This parameter, if present, is a
+  string defining the trigger assigned to the LED.  Current triggers are:
+    "backlight" - LED will act as a back-light, controlled by the framebuffer
+		  system
+    "default-on" - LED will turn on
+    "heartbeat" - LED "double" flashes at a load average based rate
+    "ide-disk" - LED indicates disk activity
+    "timer" - LED flashes at a fixed, configurable rate
 
-Example:
+Examples:
 
-led@0 {
-	compatible = "gpio-led";
-	label = "hdd";
-	gpios = <&mcu_pio 0 1>;
+leds {
+	compatible = "gpio-leds";
+	hdd {
+		label = "IDE Activity";
+		gpios = <&mcu_pio 0 1>; /* Active low */
+		linux,default-trigger = "ide-disk";
+	};
 };
+
+run-control {
+	compatible = "gpio-leds";
+	red {
+		gpios = <&mpc8572 6 0>;
+	};
+	green {
+		gpios = <&mpc8572 7 0>;
+	};
+}
diff --git a/Documentation/scheduler/sched-rt-group.txt b/Documentation/scheduler/sched-rt-group.txt
index 3ef339f..5ba4d3f 100644
--- a/Documentation/scheduler/sched-rt-group.txt
+++ b/Documentation/scheduler/sched-rt-group.txt
@@ -126,7 +126,7 @@
 to control the CPU time reserved for each control group instead.
 
 For more information on working with control groups, you should read
-Documentation/cgroups.txt as well.
+Documentation/cgroups/cgroups.txt as well.
 
 Group settings are checked against the following limits in order to keep the configuration
 schedulable:
diff --git a/Documentation/slow-work.txt b/Documentation/slow-work.txt
new file mode 100644
index 0000000..ebc50f8
--- /dev/null
+++ b/Documentation/slow-work.txt
@@ -0,0 +1,174 @@
+		     ====================================
+		     SLOW WORK ITEM EXECUTION THREAD POOL
+		     ====================================
+
+By: David Howells <dhowells@redhat.com>
+
+The slow work item execution thread pool is a pool of threads for performing
+things that take a relatively long time, such as making mkdir calls.
+Typically, when processing something, these items will spend a lot of time
+blocking a thread on I/O, thus making that thread unavailable for doing other
+work.
+
+The standard workqueue model is unsuitable for this class of work item as that
+limits the owner to a single thread or a single thread per CPU.  For some
+tasks, however, more threads - or fewer - are required.
+
+There is just one pool per system.  It contains no threads unless something
+wants to use it - and that something must register its interest first.  When
+the pool is active, the number of threads it contains is dynamic, varying
+between a maximum and minimum setting, depending on the load.
+
+
+====================
+CLASSES OF WORK ITEM
+====================
+
+This pool support two classes of work items:
+
+ (*) Slow work items.
+
+ (*) Very slow work items.
+
+The former are expected to finish much quicker than the latter.
+
+An operation of the very slow class may do a batch combination of several
+lookups, mkdirs, and a create for instance.
+
+An operation of the ordinarily slow class may, for example, write stuff or
+expand files, provided the time taken to do so isn't too long.
+
+Operations of both types may sleep during execution, thus tying up the thread
+loaned to it.
+
+
+THREAD-TO-CLASS ALLOCATION
+--------------------------
+
+Not all the threads in the pool are available to work on very slow work items.
+The number will be between one and one fewer than the number of active threads.
+This is configurable (see the "Pool Configuration" section).
+
+All the threads are available to work on ordinarily slow work items, but a
+percentage of the threads will prefer to work on very slow work items.
+
+The configuration ensures that at least one thread will be available to work on
+very slow work items, and at least one thread will be available that won't work
+on very slow work items at all.
+
+
+=====================
+USING SLOW WORK ITEMS
+=====================
+
+Firstly, a module or subsystem wanting to make use of slow work items must
+register its interest:
+
+	 int ret = slow_work_register_user();
+
+This will return 0 if successful, or a -ve error upon failure.
+
+
+Slow work items may then be set up by:
+
+ (1) Declaring a slow_work struct type variable:
+
+	#include <linux/slow-work.h>
+
+	struct slow_work myitem;
+
+ (2) Declaring the operations to be used for this item:
+
+	struct slow_work_ops myitem_ops = {
+		.get_ref = myitem_get_ref,
+		.put_ref = myitem_put_ref,
+		.execute = myitem_execute,
+	};
+
+     [*] For a description of the ops, see section "Item Operations".
+
+ (3) Initialising the item:
+
+	slow_work_init(&myitem, &myitem_ops);
+
+     or:
+
+	vslow_work_init(&myitem, &myitem_ops);
+
+     depending on its class.
+
+A suitably set up work item can then be enqueued for processing:
+
+	int ret = slow_work_enqueue(&myitem);
+
+This will return a -ve error if the thread pool is unable to gain a reference
+on the item, 0 otherwise.
+
+
+The items are reference counted, so there ought to be no need for a flush
+operation.  When all a module's slow work items have been processed, and the
+module has no further interest in the facility, it should unregister its
+interest:
+
+	slow_work_unregister_user();
+
+
+===============
+ITEM OPERATIONS
+===============
+
+Each work item requires a table of operations of type struct slow_work_ops.
+All members are required:
+
+ (*) Get a reference on an item:
+
+	int (*get_ref)(struct slow_work *work);
+
+     This allows the thread pool to attempt to pin an item by getting a
+     reference on it.  This function should return 0 if the reference was
+     granted, or a -ve error otherwise.  If an error is returned,
+     slow_work_enqueue() will fail.
+
+     The reference is held whilst the item is queued and whilst it is being
+     executed.  The item may then be requeued with the same reference held, or
+     the reference will be released.
+
+ (*) Release a reference on an item:
+
+	void (*put_ref)(struct slow_work *work);
+
+     This allows the thread pool to unpin an item by releasing the reference on
+     it.  The thread pool will not touch the item again once this has been
+     called.
+
+ (*) Execute an item:
+
+	void (*execute)(struct slow_work *work);
+
+     This should perform the work required of the item.  It may sleep, it may
+     perform disk I/O and it may wait for locks.
+
+
+==================
+POOL CONFIGURATION
+==================
+
+The slow-work thread pool has a number of configurables:
+
+ (*) /proc/sys/kernel/slow-work/min-threads
+
+     The minimum number of threads that should be in the pool whilst it is in
+     use.  This may be anywhere between 2 and max-threads.
+
+ (*) /proc/sys/kernel/slow-work/max-threads
+
+     The maximum number of threads that should in the pool.  This may be
+     anywhere between min-threads and 255 or NR_CPUS * 2, whichever is greater.
+
+ (*) /proc/sys/kernel/slow-work/vslow-percentage
+
+     The percentage of active threads in the pool that may be used to execute
+     very slow work items.  This may be between 1 and 99.  The resultant number
+     is bounded to between 1 and one fewer than the number of active threads.
+     This ensures there is always at least one thread that can process very
+     slow work items, and always at least one thread that won't.
diff --git a/Documentation/sysrq.txt b/Documentation/sysrq.txt
index afa2946..cf42b82 100644
--- a/Documentation/sysrq.txt
+++ b/Documentation/sysrq.txt
@@ -115,6 +115,8 @@
 
 'x'	- Used by xmon interface on ppc/powerpc platforms.
 
+'z'	- Dump the ftrace buffer
+
 '0'-'9' - Sets the console log level, controlling which kernel messages
           will be printed to your console. ('0', for example would make
           it so that only emergency messages like PANICs or OOPSes would
diff --git a/Documentation/tracepoints.txt b/Documentation/tracepoints.txt
index 6f0a044..c0e1cee 100644
--- a/Documentation/tracepoints.txt
+++ b/Documentation/tracepoints.txt
@@ -45,8 +45,8 @@
 #include <linux/tracepoint.h>
 
 DECLARE_TRACE(subsys_eventname,
-	TPPROTO(int firstarg, struct task_struct *p),
-	TPARGS(firstarg, p));
+	TP_PROTO(int firstarg, struct task_struct *p),
+	TP_ARGS(firstarg, p));
 
 In subsys/file.c (where the tracing statement must be added) :
 
@@ -66,10 +66,10 @@
     - subsys is the name of your subsystem.
     - eventname is the name of the event to trace.
 
-- TPPROTO(int firstarg, struct task_struct *p) is the prototype of the
+- TP_PROTO(int firstarg, struct task_struct *p) is the prototype of the
   function called by this tracepoint.
 
-- TPARGS(firstarg, p) are the parameters names, same as found in the
+- TP_ARGS(firstarg, p) are the parameters names, same as found in the
   prototype.
 
 Connecting a function (probe) to a tracepoint is done by providing a
@@ -103,13 +103,14 @@
 
 * Probe / tracepoint example
 
-See the example provided in samples/tracepoints/src
+See the example provided in samples/tracepoints
 
-Compile them with your kernel.
+Compile them with your kernel.  They are built during 'make' (not
+'make modules') when CONFIG_SAMPLE_TRACEPOINTS=m.
 
 Run, as root :
-modprobe tracepoint-example (insmod order is not important)
-modprobe tracepoint-probe-example
-cat /proc/tracepoint-example (returns an expected error)
-rmmod tracepoint-example tracepoint-probe-example
+modprobe tracepoint-sample (insmod order is not important)
+modprobe tracepoint-probe-sample
+cat /proc/tracepoint-sample (returns an expected error)
+rmmod tracepoint-sample tracepoint-probe-sample
 dmesg
diff --git a/Documentation/vm/kmemtrace.txt b/Documentation/vm/kmemtrace.txt
new file mode 100644
index 0000000..a956d9b
--- /dev/null
+++ b/Documentation/vm/kmemtrace.txt
@@ -0,0 +1,126 @@
+			kmemtrace - Kernel Memory Tracer
+
+			  by Eduard - Gabriel Munteanu
+			     <eduard.munteanu@linux360.ro>
+
+I. Introduction
+===============
+
+kmemtrace helps kernel developers figure out two things:
+1) how different allocators (SLAB, SLUB etc.) perform
+2) how kernel code allocates memory and how much
+
+To do this, we trace every allocation and export information to the userspace
+through the relay interface. We export things such as the number of requested
+bytes, the number of bytes actually allocated (i.e. including internal
+fragmentation), whether this is a slab allocation or a plain kmalloc() and so
+on.
+
+The actual analysis is performed by a userspace tool (see section III for
+details on where to get it from). It logs the data exported by the kernel,
+processes it and (as of writing this) can provide the following information:
+- the total amount of memory allocated and fragmentation per call-site
+- the amount of memory allocated and fragmentation per allocation
+- total memory allocated and fragmentation in the collected dataset
+- number of cross-CPU allocation and frees (makes sense in NUMA environments)
+
+Moreover, it can potentially find inconsistent and erroneous behavior in
+kernel code, such as using slab free functions on kmalloc'ed memory or
+allocating less memory than requested (but not truly failed allocations).
+
+kmemtrace also makes provisions for tracing on some arch and analysing the
+data on another.
+
+II. Design and goals
+====================
+
+kmemtrace was designed to handle rather large amounts of data. Thus, it uses
+the relay interface to export whatever is logged to userspace, which then
+stores it. Analysis and reporting is done asynchronously, that is, after the
+data is collected and stored. By design, it allows one to log and analyse
+on different machines and different arches.
+
+As of writing this, the ABI is not considered stable, though it might not
+change much. However, no guarantees are made about compatibility yet. When
+deemed stable, the ABI should still allow easy extension while maintaining
+backward compatibility. This is described further in Documentation/ABI.
+
+Summary of design goals:
+	- allow logging and analysis to be done across different machines
+	- be fast and anticipate usage in high-load environments (*)
+	- be reasonably extensible
+	- make it possible for GNU/Linux distributions to have kmemtrace
+	included in their repositories
+
+(*) - one of the reasons Pekka Enberg's original userspace data analysis
+    tool's code was rewritten from Perl to C (although this is more than a
+    simple conversion)
+
+
+III. Quick usage guide
+======================
+
+1) Get a kernel that supports kmemtrace and build it accordingly (i.e. enable
+CONFIG_KMEMTRACE).
+
+2) Get the userspace tool and build it:
+$ git-clone git://repo.or.cz/kmemtrace-user.git		# current repository
+$ cd kmemtrace-user/
+$ ./autogen.sh
+$ ./configure
+$ make
+
+3) Boot the kmemtrace-enabled kernel if you haven't, preferably in the
+'single' runlevel (so that relay buffers don't fill up easily), and run
+kmemtrace:
+# '$' does not mean user, but root here.
+$ mount -t debugfs none /sys/kernel/debug
+$ mount -t proc none /proc
+$ cd path/to/kmemtrace-user/
+$ ./kmemtraced
+Wait a bit, then stop it with CTRL+C.
+$ cat /sys/kernel/debug/kmemtrace/total_overruns	# Check if we didn't
+							# overrun, should
+							# be zero.
+$ (Optionally) [Run kmemtrace_check separately on each cpu[0-9]*.out file to
+		check its correctness]
+$ ./kmemtrace-report
+
+Now you should have a nice and short summary of how the allocator performs.
+
+IV. FAQ and known issues
+========================
+
+Q: 'cat /sys/kernel/debug/kmemtrace/total_overruns' is non-zero, how do I fix
+this? Should I worry?
+A: If it's non-zero, this affects kmemtrace's accuracy, depending on how
+large the number is. You can fix it by supplying a higher
+'kmemtrace.subbufs=N' kernel parameter.
+---
+
+Q: kmemtrace_check reports errors, how do I fix this? Should I worry?
+A: This is a bug and should be reported. It can occur for a variety of
+reasons:
+	- possible bugs in relay code
+	- possible misuse of relay by kmemtrace
+	- timestamps being collected unorderly
+Or you may fix it yourself and send us a patch.
+---
+
+Q: kmemtrace_report shows many errors, how do I fix this? Should I worry?
+A: This is a known issue and I'm working on it. These might be true errors
+in kernel code, which may have inconsistent behavior (e.g. allocating memory
+with kmem_cache_alloc() and freeing it with kfree()). Pekka Enberg pointed
+out this behavior may work with SLAB, but may fail with other allocators.
+
+It may also be due to lack of tracing in some unusual allocator functions.
+
+We don't want bug reports regarding this issue yet.
+---
+
+V. See also
+===========
+
+Documentation/kernel-parameters.txt
+Documentation/ABI/testing/debugfs-kmemtrace
+
diff --git a/Documentation/vm/numa_memory_policy.txt b/Documentation/vm/numa_memory_policy.txt
index 6aaaeb3..be45dbb 100644
--- a/Documentation/vm/numa_memory_policy.txt
+++ b/Documentation/vm/numa_memory_policy.txt
@@ -8,7 +8,8 @@
 document attempts to describe the concepts and APIs of the 2.6 memory policy
 support.
 
-Memory policies should not be confused with cpusets (Documentation/cpusets.txt)
+Memory policies should not be confused with cpusets
+(Documentation/cgroups/cpusets.txt)
 which is an administrative mechanism for restricting the nodes from which
 memory may be allocated by a set of processes. Memory policies are a
 programming interface that a NUMA-aware application can take advantage of.  When
diff --git a/Documentation/vm/page_migration b/Documentation/vm/page_migration
index d5fdfd3..6513fe2 100644
--- a/Documentation/vm/page_migration
+++ b/Documentation/vm/page_migration
@@ -37,7 +37,8 @@
 
 Larger installations usually partition the system using cpusets into
 sections of nodes. Paul Jackson has equipped cpusets with the ability to
-move pages when a task is moved to another cpuset (See ../cpusets.txt).
+move pages when a task is moved to another cpuset (See
+Documentation/cgroups/cpusets.txt).
 Cpusets allows the automation of process locality. If a task is moved to
 a new cpuset then also all its pages are moved with it so that the
 performance of the process does not sink dramatically. Also the pages
diff --git a/Documentation/x86/x86_64/fake-numa-for-cpusets b/Documentation/x86/x86_64/fake-numa-for-cpusets
index 33bb566..0f11d9be 100644
--- a/Documentation/x86/x86_64/fake-numa-for-cpusets
+++ b/Documentation/x86/x86_64/fake-numa-for-cpusets
@@ -7,7 +7,8 @@
 assign them to cpusets and their attached tasks.  This is a way of limiting the
 amount of system memory that are available to a certain class of tasks.
 
-For more information on the features of cpusets, see Documentation/cpusets.txt.
+For more information on the features of cpusets, see
+Documentation/cgroups/cpusets.txt.
 There are a number of different configurations you can use for your needs.  For
 more information on the numa=fake command line option and its various ways of
 configuring fake nodes, see Documentation/x86/x86_64/boot-options.txt.
@@ -32,7 +33,7 @@
 	On node 3 totalpages: 131072
 
 Now following the instructions for mounting the cpusets filesystem from
-Documentation/cpusets.txt, you can assign fake nodes (i.e. contiguous memory
+Documentation/cgroups/cpusets.txt, you can assign fake nodes (i.e. contiguous memory
 address spaces) to individual cpusets:
 
 	[root@xroads /]# mkdir exampleset
diff --git a/MAINTAINERS b/MAINTAINERS
index ebaf77e..9673cd2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1422,6 +1422,11 @@
 M:	Douglas_Warzecha@dell.com
 S:	Maintained
 
+DELL WMI EXTRAS DRIVER
+P:	Matthew Garrett
+M:	mjg59@srcf.ucam.org
+S:	Maintained
+
 DEVICE NUMBER REGISTRY
 P:	Torben Mathiasen
 M:	device@lanana.org
@@ -1763,6 +1768,12 @@
 L:	linux-fsdevel@vger.kernel.org
 S:	Maintained
 
+FINTEK F75375S HARDWARE MONITOR AND FAN CONTROLLER DRIVER
+P:	Riku Voipio
+M:	riku.vipio@iki.fi
+L:	lm-sensors@lm-sensors.org
+S:	Maintained
+
 FIREWIRE SUBSYSTEM (drivers/firewire, <linux/firewire*.h>)
 P:	Kristian Hoegsberg, Stefan Richter
 M:	krh@redhat.com, stefanr@s5r6.in-berlin.de
@@ -2648,6 +2659,12 @@
 L:	kgdb-bugreport@lists.sourceforge.net
 S:	Maintained
 
+KMEMTRACE
+P:	Eduard - Gabriel Munteanu
+M:	eduard.munteanu@linux360.ro
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+
 KPROBES
 P:	Ananth N Mavinakayanahalli
 M:	ananth@in.ibm.com
@@ -2918,6 +2935,12 @@
 L:	netdev@vger.kernel.org
 S:	Supported
 
+MARVELL SOC MMC/SD/SDIO CONTROLLER DRIVER
+P:	Nicolas Pitre
+M:	nico@cam.org
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+
 MARVELL YUKON / SYSKONNECT DRIVER
 P:	Mirko Lindner
 M:	mlindner@syskonnect.de
@@ -3028,8 +3051,9 @@
 
 MULTIFUNCTION DEVICES (MFD)
 P:	Samuel Ortiz
-M:	sameo@openedhand.com
+M:	sameo@linux.intel.com
 L:	linux-kernel@vger.kernel.org
+T:	git kernel.org:/pub/scm/linux/kernel/git/sameo/mfd-2.6.git
 S:	Supported
 
 MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND SDIO SUBSYSTEM
@@ -3408,6 +3432,11 @@
 M:	jim.cromie@gmail.com
 S:	Maintained
 
+PCA9532 LED DRIVER
+P:	Riku Voipio
+M:	riku.voipio@iki.fi
+S:	Maintained
+
 PCI ERROR RECOVERY
 P:	Linas Vepstas
 M:	linas@austin.ibm.com
@@ -3905,7 +3934,14 @@
 SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) DRIVER
 P:	Pierre Ossman
 M:	drzeus-sdhci@drzeus.cx
-L:	sdhci-devel@list.drzeus.cx
+L:	sdhci-devel@lists.ossman.eu
+S:	Maintained
+
+SECURE DIGITAL HOST CONTROLLER INTERFACE, OPEN FIRMWARE BINDINGS (SDHCI-OF)
+P:	Anton Vorontsov
+M:	avorontsov@ru.mvista.com
+L:	linuxppc-dev@ozlabs.org
+L:	sdhci-devel@lists.ossman.eu
 S:	Maintained
 
 SECURITY SUBSYSTEM
@@ -4371,10 +4407,7 @@
 S:	Maintained
 
 TOSHIBA ACPI EXTRAS DRIVER
-P:	John Belmonte
-M:	toshiba_acpi@memebeam.org
-W:	http://memebeam.org/toys/ToshibaAcpiDriver
-S:	Maintained
+S:	Orphan
 
 TOSHIBA SMM DRIVER
 P:	Jonathan Buzzard
@@ -4383,6 +4416,11 @@
 W:	http://www.buzzard.org.uk/toshiba/
 S:	Maintained
 
+TMIO MMC DRIVER
+P:	Ian Molton
+M:	ian@mnementh.co.uk
+S:	Maintained
+
 TPM DEVICE DRIVER
 P:	Debora Velarde
 M:	debora@linux.vnet.ibm.com
@@ -4847,7 +4885,7 @@
 P:	Mark Brown
 M:	broonie@opensource.wolfsonmicro.com
 W:	http://opensource.wolfsonmicro.com/node/15
-W:	http://www.slimlogic.co.uk/?page_id=5
+W:	http://www.slimlogic.co.uk/?p=48
 T:	git kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6.git
 S:	Supported
 
@@ -4969,7 +5007,8 @@
 
 XFS FILESYSTEM
 P:	Silicon Graphics Inc
-P:	Bill O'Donnell
+P:	Felix Blyakher
+M:	felixb@sgi.com
 M:	xfs-masters@oss.sgi.com
 L:	xfs@oss.sgi.com
 W:	http://oss.sgi.com/projects/xfs
diff --git a/arch/Kconfig b/arch/Kconfig
index 830c16a..dc81b34 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -6,6 +6,7 @@
 	tristate "OProfile system profiling (EXPERIMENTAL)"
 	depends on PROFILING
 	depends on HAVE_OPROFILE
+	depends on TRACING_SUPPORT
 	select TRACING
 	select RING_BUFFER
 	help
diff --git a/arch/alpha/include/asm/ftrace.h b/arch/alpha/include/asm/ftrace.h
new file mode 100644
index 0000000..40a8c17
--- /dev/null
+++ b/arch/alpha/include/asm/ftrace.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/alpha/include/asm/hardirq.h b/arch/alpha/include/asm/hardirq.h
index d953e23..8897146 100644
--- a/arch/alpha/include/asm/hardirq.h
+++ b/arch/alpha/include/asm/hardirq.h
@@ -14,17 +14,4 @@
 
 void ack_bad_irq(unsigned int irq);
 
-#define HARDIRQ_BITS	12
-
-/*
- * The hardirq mask has to be large enough to have
- * space for potentially nestable IRQ sources in the system
- * to nest on a single CPU. On Alpha, interrupts are masked at the CPU
- * by IPL as well as at the system level. We only have 8 IPLs (UNIX PALcode)
- * so we really only have 8 nestable IRQs, but allow some overhead
- */
-#if (1 << HARDIRQ_BITS) < 16
-#error HARDIRQ_BITS is too low!
-#endif
-
 #endif /* _ALPHA_HARDIRQ_H */
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c
index 393c816..9e6e512 100644
--- a/arch/arm/boot/compressed/misc.c
+++ b/arch/arm/boot/compressed/misc.c
@@ -18,7 +18,10 @@
 
 unsigned int __machine_arch_type;
 
-#include <linux/string.h>
+#include <linux/compiler.h>	/* for inline */
+#include <linux/types.h>	/* for size_t */
+#include <linux/stddef.h>	/* for NULL */
+#include <asm/string.h>
 
 #ifdef STANDALONE_DEBUG
 #define putstr printf
diff --git a/arch/arm/configs/omap_ldp_defconfig b/arch/arm/configs/omap_ldp_defconfig
index aa9d34f..679a4a3 100644
--- a/arch/arm/configs/omap_ldp_defconfig
+++ b/arch/arm/configs/omap_ldp_defconfig
@@ -474,14 +474,34 @@
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_VETH is not set
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_AX88796 is not set
 # CONFIG_SMC91X is not set
 # CONFIG_DM9000 is not set
 # CONFIG_ENC28J60 is not set
-CONFIG_SMC911X=y
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
diff --git a/arch/arm/configs/pcm037_defconfig b/arch/arm/configs/pcm037_defconfig
index 6274745..6e37c77 100644
--- a/arch/arm/configs/pcm037_defconfig
+++ b/arch/arm/configs/pcm037_defconfig
@@ -465,12 +465,33 @@
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_VETH is not set
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_AX88796 is not set
 CONFIG_SMC91X=y
 # CONFIG_DM9000 is not set
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
diff --git a/arch/arm/configs/realview-smp_defconfig b/arch/arm/configs/realview-smp_defconfig
index cd29824..21db4b3 100644
--- a/arch/arm/configs/realview-smp_defconfig
+++ b/arch/arm/configs/realview-smp_defconfig
@@ -496,13 +496,33 @@
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_VETH is not set
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_AX88796 is not set
 CONFIG_SMC91X=y
 # CONFIG_DM9000 is not set
-CONFIG_SMC911X=y
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
diff --git a/arch/arm/configs/realview_defconfig b/arch/arm/configs/realview_defconfig
index 7e253f5..9a75c30 100644
--- a/arch/arm/configs/realview_defconfig
+++ b/arch/arm/configs/realview_defconfig
@@ -490,13 +490,33 @@
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_VETH is not set
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_AX88796 is not set
 CONFIG_SMC91X=y
 # CONFIG_DM9000 is not set
-CONFIG_SMC911X=y
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 7ac812d..e26c4fe 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -198,17 +198,17 @@
 	/* USB must not be using PLLB */
 	if (cpu_is_at91rm9200()) {
 		if ((scsr & (AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP)) != 0) {
-			pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n");
+			pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
 			return 0;
 		}
 	} else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) {
 		if ((scsr & (AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP)) != 0) {
-			pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n");
+			pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
 			return 0;
 		}
 	} else if (cpu_is_at91cap9()) {
 		if ((scsr & AT91CAP9_PMC_UHP) != 0) {
-			pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n");
+			pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
 			return 0;
 		}
 	}
@@ -223,7 +223,7 @@
 
 		css = at91_sys_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
 		if (css != AT91_PMC_CSS_SLOW) {
-			pr_debug("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css);
+			pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css);
 			return 0;
 		}
 	}
diff --git a/arch/arm/mach-gemini/include/mach/system.h b/arch/arm/mach-gemini/include/mach/system.h
index bbbd727..4d9c1f8 100644
--- a/arch/arm/mach-gemini/include/mach/system.h
+++ b/arch/arm/mach-gemini/include/mach/system.h
@@ -28,7 +28,7 @@
 	cpu_do_idle();
 }
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	__raw_writel(RESET_GLOBAL | RESET_CPU1,
 		     IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_RESET);
diff --git a/arch/arm/mach-mmp/include/mach/system.h b/arch/arm/mach-mmp/include/mach/system.h
index 001edfe..4f5b0e0 100644
--- a/arch/arm/mach-mmp/include/mach/system.h
+++ b/arch/arm/mach-mmp/include/mach/system.h
@@ -14,7 +14,7 @@
 	cpu_do_idle();
 }
 
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	cpu_reset(0);
 }
diff --git a/arch/arm/mach-mx3/pcm037.c b/arch/arm/mach-mx3/pcm037.c
index 5fce022..c3648ef 100644
--- a/arch/arm/mach-mx3/pcm037.c
+++ b/arch/arm/mach-mx3/pcm037.c
@@ -24,7 +24,7 @@
 #include <linux/mtd/plat-ram.h>
 #include <linux/memory.h>
 #include <linux/gpio.h>
-#include <linux/smc911x.h>
+#include <linux/smsc911x.h>
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
 #include <linux/i2c/at24.h>
@@ -70,7 +70,7 @@
 	.flags = IMXUART_HAVE_RTSCTS,
 };
 
-static struct resource smc911x_resources[] = {
+static struct resource smsc911x_resources[] = {
 	[0] = {
 		.start		= CS1_BASE_ADDR + 0x300,
 		.end		= CS1_BASE_ADDR + 0x300 + SZ_64K - 1,
@@ -79,22 +79,25 @@
 	[1] = {
 		.start		= IOMUX_TO_IRQ(MX31_PIN_GPIO3_1),
 		.end		= IOMUX_TO_IRQ(MX31_PIN_GPIO3_1),
-		.flags		= IORESOURCE_IRQ,
+		.flags		= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
 	},
 };
 
-static struct smc911x_platdata smc911x_info = {
-	.flags		= SMC911X_USE_32BIT,
-	.irq_flags	= IRQF_SHARED | IRQF_TRIGGER_LOW,
+static struct smsc911x_platform_config smsc911x_info = {
+	.flags		= SMSC911X_USE_32BIT | SMSC911X_FORCE_INTERNAL_PHY |
+			  SMSC911X_SAVE_MAC_ADDRESS,
+	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+	.phy_interface	= PHY_INTERFACE_MODE_MII,
 };
 
 static struct platform_device pcm037_eth = {
-	.name		= "smc911x",
+	.name		= "smsc911x",
 	.id		= -1,
-	.num_resources	= ARRAY_SIZE(smc911x_resources),
-	.resource	= smc911x_resources,
+	.num_resources	= ARRAY_SIZE(smsc911x_resources),
+	.resource	= smsc911x_resources,
 	.dev		= {
-		.platform_data = &smc911x_info,
+		.platform_data = &smsc911x_info,
 	},
 };
 
diff --git a/arch/arm/mach-netx/include/mach/netx-regs.h b/arch/arm/mach-netx/include/mach/netx-regs.h
index 08c60ff..5a03e7c 100644
--- a/arch/arm/mach-netx/include/mach/netx-regs.h
+++ b/arch/arm/mach-netx/include/mach/netx-regs.h
@@ -80,7 +80,7 @@
 #define NETX_PA_XPEC(no) (NETX_IO_PHYS + NETX_OFS_XPEC(no))
 #define NETX_PA_VIC      (NETX_IO_PHYS + NETX_OFS_VIC)
 
-/* virual addresses */
+/* virtual addresses */
 #define NETX_VA_SYSTEM   (NETX_IO_VIRT + NETX_OFS_SYSTEM)
 #define NETX_VA_MEMCR    (NETX_IO_VIRT + NETX_OFS_MEMCR)
 #define NETX_VA_DPMAS    (NETX_IO_VIRT + NETX_OFS_DPMAS)
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index 3f325d3..cd8de89 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -109,7 +109,7 @@
 	help
 	 Support for the Palm Zire71 PDA. To boot the kernel,
 	 you'll need a PalmOS compatible bootloader; check out
-	 http://hackndev.com/palm/z71 for more informations.
+	 http://hackndev.com/palm/z71 for more information.
 	 Say Y here if you have such a PDA, say N otherwise.
 
 config MACH_OMAP_PALMTT
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index a2c3fcc..c49d9bf 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -47,6 +47,8 @@
 
 obj-$(CONFIG_MACH_NOKIA_RX51)		+= board-rx51.o \
 					   board-rx51-peripherals.o \
+					   mmc-twl4030.o
+
 # Platform specific device init code
 ifeq ($(CONFIG_USB_MUSB_SOC),y)
 obj-y					+= usb-musb.o
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index e096f77..da57b0f 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -23,6 +23,7 @@
 #include <linux/spi/ads7846.h>
 #include <linux/i2c/twl4030.h>
 #include <linux/io.h>
+#include <linux/smsc911x.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -41,12 +42,12 @@
 
 #include "mmc-twl4030.h"
 
-#define LDP_SMC911X_CS		1
-#define LDP_SMC911X_GPIO	152
+#define LDP_SMSC911X_CS		1
+#define LDP_SMSC911X_GPIO	152
 #define DEBUG_BASE		0x08000000
 #define LDP_ETHR_START		DEBUG_BASE
 
-static struct resource ldp_smc911x_resources[] = {
+static struct resource ldp_smsc911x_resources[] = {
 	[0] = {
 		.start	= LDP_ETHR_START,
 		.end	= LDP_ETHR_START + SZ_4K,
@@ -59,40 +60,50 @@
 	},
 };
 
-static struct platform_device ldp_smc911x_device = {
-	.name		= "smc911x",
+static struct smsc911x_platform_config ldp_smsc911x_config = {
+	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+	.flags		= SMSC911X_USE_32BIT,
+	.phy_interface	= PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device ldp_smsc911x_device = {
+	.name		= "smsc911x",
 	.id		= -1,
-	.num_resources	= ARRAY_SIZE(ldp_smc911x_resources),
-	.resource	= ldp_smc911x_resources,
+	.num_resources	= ARRAY_SIZE(ldp_smsc911x_resources),
+	.resource	= ldp_smsc911x_resources,
+	.dev		= {
+		.platform_data = &ldp_smsc911x_config,
+	},
 };
 
 static struct platform_device *ldp_devices[] __initdata = {
-	&ldp_smc911x_device,
+	&ldp_smsc911x_device,
 };
 
-static inline void __init ldp_init_smc911x(void)
+static inline void __init ldp_init_smsc911x(void)
 {
 	int eth_cs;
 	unsigned long cs_mem_base;
 	int eth_gpio = 0;
 
-	eth_cs = LDP_SMC911X_CS;
+	eth_cs = LDP_SMSC911X_CS;
 
 	if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) {
-		printk(KERN_ERR "Failed to request GPMC mem for smc911x\n");
+		printk(KERN_ERR "Failed to request GPMC mem for smsc911x\n");
 		return;
 	}
 
-	ldp_smc911x_resources[0].start = cs_mem_base + 0x0;
-	ldp_smc911x_resources[0].end   = cs_mem_base + 0xff;
+	ldp_smsc911x_resources[0].start = cs_mem_base + 0x0;
+	ldp_smsc911x_resources[0].end   = cs_mem_base + 0xff;
 	udelay(100);
 
-	eth_gpio = LDP_SMC911X_GPIO;
+	eth_gpio = LDP_SMSC911X_GPIO;
 
-	ldp_smc911x_resources[1].start = OMAP_GPIO_IRQ(eth_gpio);
+	ldp_smsc911x_resources[1].start = OMAP_GPIO_IRQ(eth_gpio);
 
-	if (gpio_request(eth_gpio, "smc911x irq") < 0) {
-		printk(KERN_ERR "Failed to request GPIO%d for smc911x IRQ\n",
+	if (gpio_request(eth_gpio, "smsc911x irq") < 0) {
+		printk(KERN_ERR "Failed to request GPIO%d for smsc911x IRQ\n",
 				eth_gpio);
 		return;
 	}
@@ -104,7 +115,7 @@
 	omap2_init_common_hw(NULL);
 	omap_init_irq();
 	omap_gpio_init();
-	ldp_init_smc911x();
+	ldp_init_smsc911x();
 }
 
 static struct omap_uart_config ldp_uart_config __initdata = {
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index b3f6e9d..b1f23be 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -57,6 +57,9 @@
 #define GPMC_CS0_BASE  0x60
 #define GPMC_CS_SIZE   0x30
 
+#define OVERO_SMSC911X_CS      5
+#define OVERO_SMSC911X_GPIO    176
+
 #if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
 	defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
 
@@ -116,6 +119,67 @@
 static inline void __init overo_ads7846_init(void) { return; }
 #endif
 
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+
+#include <linux/smsc911x.h>
+
+static struct resource overo_smsc911x_resources[] = {
+	{
+		.name	= "smsc911x-memory",
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+	},
+};
+
+static struct smsc911x_platform_config overo_smsc911x_config = {
+	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+	.flags		= SMSC911X_USE_32BIT ,
+	.phy_interface	= PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device overo_smsc911x_device = {
+	.name		= "smsc911x",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(overo_smsc911x_resources),
+	.resource	= &overo_smsc911x_resources,
+	.dev		= {
+		.platform_data = &overo_smsc911x_config,
+	},
+};
+
+static inline void __init overo_init_smsc911x(void)
+{
+	unsigned long cs_mem_base;
+
+	if (gpmc_cs_request(OVERO_SMSC911X_CS, SZ_16M, &cs_mem_base) < 0) {
+		printk(KERN_ERR "Failed request for GPMC mem for smsc911x\n");
+		return;
+	}
+
+	overo_smsc911x_resources[0].start = cs_mem_base + 0x0;
+	overo_smsc911x_resources[0].end   = cs_mem_base + 0xff;
+
+	if ((gpio_request(OVERO_SMSC911X_GPIO, "SMSC911X IRQ") == 0) &&
+	    (gpio_direction_input(OVERO_SMSC911X_GPIO) == 0)) {
+		gpio_export(OVERO_SMSC911X_GPIO, 0);
+	} else {
+		printk(KERN_ERR "could not obtain gpio for SMSC911X IRQ\n");
+		return;
+	}
+
+	overo_smsc911x_resources[1].start = OMAP_GPIO_IRQ(OVERO_SMSC911X_GPIO);
+	overo_smsc911x_resources[1].end	  = 0;
+
+	platform_device_register(&overo_smsc911x_device);
+}
+
+#else
+static inline void __init overo_init_smsc911x(void) { return; }
+#endif
+
 static struct mtd_partition overo_nand_partitions[] = {
 	{
 		.name           = "xloader",
@@ -290,6 +354,7 @@
 	overo_flash_init();
 	usb_musb_init();
 	overo_ads7846_init();
+	overo_init_smsc911x();
 
 	if ((gpio_request(OVERO_GPIO_W2W_NRESET,
 			  "OVERO_GPIO_W2W_NRESET") == 0) &&
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index d46b367..deeea1c 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -507,7 +507,6 @@
 };
 
 static struct pasic3_platform_data pasic3_platform_data = {
-	.bus_shift  = 2,
 	.led_pdata  = &pasic3_leds_info,
 	.clock_rate = 4000000,
 };
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index d676668..9ab947c 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -28,7 +28,7 @@
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 #include <linux/io.h>
-#include <linux/smc911x.h>
+#include <linux/smsc911x.h>
 #include <linux/ata_platform.h>
 
 #include <asm/clkdev.h>
@@ -128,14 +128,15 @@
 	return platform_device_register(&realview_flash_device);
 }
 
-static struct smc911x_platdata realview_smc911x_platdata = {
-	.flags		= SMC911X_USE_32BIT,
-	.irq_flags	= IRQF_SHARED,
-	.irq_polarity	= 1,
+static struct smsc911x_platform_config smsc911x_config = {
+	.flags		= SMSC911X_USE_32BIT,
+	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
+	.irq_type	= SMSC911X_IRQ_TYPE_PUSH_PULL,
+	.phy_interface	= PHY_INTERFACE_MODE_MII,
 };
 
 static struct platform_device realview_eth_device = {
-	.name		= "smc911x",
+	.name		= "smsc911x",
 	.id		= 0,
 	.num_resources	= 2,
 };
@@ -145,8 +146,8 @@
 	if (name)
 		realview_eth_device.name = name;
 	realview_eth_device.resource = res;
-	if (strcmp(realview_eth_device.name, "smc911x") == 0)
-		realview_eth_device.dev.platform_data = &realview_smc911x_platdata;
+	if (strcmp(realview_eth_device.name, "smsc911x") == 0)
+		realview_eth_device.dev.platform_data = &smsc911x_config;
 
 	return platform_device_register(&realview_eth_device);
 }
diff --git a/arch/arm/mach-realview/localtimer.c b/arch/arm/mach-realview/localtimer.c
index 67d6d9c..d0d39ad 100644
--- a/arch/arm/mach-realview/localtimer.c
+++ b/arch/arm/mach-realview/localtimer.c
@@ -191,6 +191,7 @@
 	clk->name		= "dummy_timer";
 	clk->features		= CLOCK_EVT_FEAT_DUMMY;
 	clk->rating		= 200;
+	clk->mult               = 1;
 	clk->set_mode		= dummy_timer_set_mode;
 	clk->broadcast		= smp_timer_broadcast;
 	clk->cpumask		= cpumask_of(cpu);
diff --git a/arch/arm/mm/abort-ev6.S b/arch/arm/mm/abort-ev6.S
index 94077fb..6f7e709 100644
--- a/arch/arm/mm/abort-ev6.S
+++ b/arch/arm/mm/abort-ev6.S
@@ -29,10 +29,10 @@
 	mrc	p15, 0, r1, c5, c0, 0		@ get FSR
 	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
 /*
- * Faulty SWP instruction on 1136 doesn't set bit 11 in DFSR.
+ * Faulty SWP instruction on 1136 doesn't set bit 11 in DFSR (erratum 326103).
  * The test below covers all the write situations, including Java bytecodes
  */
-	bic	r1, r1, #1 << 11 | 1 << 10	@ clear bits 11 and 10 of FSR
+	bic	r1, r1, #1 << 11		@ clear bit 11 of FSR
 	tst	r3, #PSR_J_BIT			@ Java?
 	movne	pc, lr
 	do_thumb_abort
diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c
index d6dd838..6e77c04 100644
--- a/arch/arm/mm/cache-feroceon-l2.c
+++ b/arch/arm/mm/cache-feroceon-l2.c
@@ -115,6 +115,10 @@
 	raw_local_irq_restore(flags);
 }
 
+static inline void l2_inv_all(void)
+{
+	__asm__("mcr p15, 1, %0, c15, c11, 0" : : "r" (0));
+}
 
 /*
  * Linux primitives.
@@ -254,9 +258,7 @@
 
 static void __init __invalidate_icache(void)
 {
-	int dummy;
-
-	__asm__ __volatile__("mcr p15, 0, %0, c7, c5, 0" : "=r" (dummy));
+	__asm__("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
 }
 
 static int __init invalidate_and_disable_icache(void)
@@ -321,6 +323,7 @@
 
 		d = flush_and_disable_dcache();
 		i = invalidate_and_disable_icache();
+		l2_inv_all();
 		write_extra_features(u | 0x00400000);
 		if (i)
 			enable_icache();
diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S
index ba592a9..a2bed62 100644
--- a/arch/arm/vfp/entry.S
+++ b/arch/arm/vfp/entry.S
@@ -15,13 +15,16 @@
  *  r10 = thread_info structure
  *  lr  = failure return
  */
-#include <linux/linkage.h>
-#include <linux/init.h>
-#include <asm/asm-offsets.h>
-#include <asm/assembler.h>
+#include <asm/thread_info.h>
 #include <asm/vfpmacros.h>
+#include "../kernel/entry-header.S"
 
 ENTRY(do_vfp)
+#ifdef CONFIG_PREEMPT
+	ldr	r4, [r10, #TI_PREEMPT]	@ get preempt count
+	add	r11, r4, #1		@ increment it
+	str	r11, [r10, #TI_PREEMPT]
+#endif
 	enable_irq
  	ldr	r4, .LCvfp
 	ldr	r11, [r10, #TI_CPU]	@ CPU number
@@ -30,6 +33,12 @@
 ENDPROC(do_vfp)
 
 ENTRY(vfp_null_entry)
+#ifdef CONFIG_PREEMPT
+	get_thread_info	r10
+	ldr	r4, [r10, #TI_PREEMPT]	@ get preempt count
+	sub	r11, r4, #1		@ decrement it
+	str	r11, [r10, #TI_PREEMPT]
+#endif
 	mov	pc, lr
 ENDPROC(vfp_null_entry)
 
@@ -41,6 +50,12 @@
 
 	__INIT
 ENTRY(vfp_testing_entry)
+#ifdef CONFIG_PREEMPT
+	get_thread_info	r10
+	ldr	r4, [r10, #TI_PREEMPT]	@ get preempt count
+	sub	r11, r4, #1		@ decrement it
+	str	r11, [r10, #TI_PREEMPT]
+#endif
 	ldr	r0, VFP_arch_address
 	str	r5, [r0]		@ known non-zero value
 	mov	pc, r9			@ we have handled the fault
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S
index a5a4e57..83c4e38 100644
--- a/arch/arm/vfp/vfphw.S
+++ b/arch/arm/vfp/vfphw.S
@@ -137,6 +137,12 @@
 	VFPFMXR	FPEXC, r1		@ restore FPEXC last
 	sub	r2, r2, #4
 	str	r2, [sp, #S_PC]		@ retry the instruction
+#ifdef CONFIG_PREEMPT
+	get_thread_info	r10
+	ldr	r4, [r10, #TI_PREEMPT]	@ get preempt count
+	sub	r11, r4, #1		@ decrement it
+	str	r11, [r10, #TI_PREEMPT]
+#endif
 	mov	pc, r9			@ we think we have handled things
 
 
@@ -155,6 +161,12 @@
 	@ not recognised by VFP
 
 	DBGSTR	"not VFP"
+#ifdef CONFIG_PREEMPT
+	get_thread_info	r10
+	ldr	r4, [r10, #TI_PREEMPT]	@ get preempt count
+	sub	r11, r4, #1		@ decrement it
+	str	r11, [r10, #TI_PREEMPT]
+#endif
 	mov	pc, lr
 
 process_exception:
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 75457b3..01599c4 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -266,7 +266,7 @@
 		 * on VFP subarch 1.
 		 */
 		 vfp_raise_exceptions(VFP_EXCEPTION_ERROR, trigger, fpscr, regs);
-		 return;
+		goto exit;
 	}
 
 	/*
@@ -297,7 +297,7 @@
 	 * the FPEXC.FP2V bit is valid only if FPEXC.EX is 1.
 	 */
 	if (fpexc ^ (FPEXC_EX | FPEXC_FP2V))
-		return;
+		goto exit;
 
 	/*
 	 * The barrier() here prevents fpinst2 being read
@@ -310,6 +310,8 @@
 	exceptions = vfp_emulate_instruction(trigger, orig_fpscr, regs);
 	if (exceptions)
 		vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs);
+ exit:
+	preempt_enable();
 }
 
 static void vfp_enable(void *unused)
diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig
index 05fe305..35e3bd9 100644
--- a/arch/avr32/Kconfig
+++ b/arch/avr32/Kconfig
@@ -127,13 +127,13 @@
 	select CPU_AT32AP7000
 	select USB_ARCH_HAS_HCD
 	help
-	  The Hammerhead platform is built around a AVR32 32-bit microcontroller from Atmel.
+	  The Hammerhead platform is built around an AVR32 32-bit microcontroller from Atmel.
 	  It offers versatile peripherals, such as ethernet, usb device, usb host etc.
 
-	  The board also incooperates a power supply and is a Power over Ethernet (PoE) Powered
+	  The board also incorporates a power supply and is a Power over Ethernet (PoE) Powered
 	  Device (PD).
 
-	  Additonally, a Cyclone III FPGA from Altera is integrated on the board. The FPGA is
+	  Additionally, a Cyclone III FPGA from Altera is integrated on the board. The FPGA is
 	  mapped into the 32-bit AVR memory bus. The FPGA offers two DDR2 SDRAM interfaces, which
 	  will cover even the most exceptional need of memory bandwidth. Together with the onboard
 	  video decoder the board is ready for video processing.
@@ -144,6 +144,19 @@
 	bool "Favr-32 LCD-board"
 	select CPU_AT32AP7000
 
+config BOARD_MERISC
+	bool "Merisc board"
+	select CPU_AT32AP7000
+	help
+	  Merisc is the family name for a range of AVR32-based boards.
+
+	  The boards are designed to be used in a man-machine
+	  interfacing environment, utilizing a touch-based graphical
+	  user interface. They host a vast range of I/O peripherals as
+	  well as a large SDRAM & Flash memory bank.
+
+	  For more information see: http://www.martinsson.se/merisc
+
 config BOARD_MIMC200
 	bool "MIMC200 CPU board"
 	select CPU_AT32AP7000
@@ -153,6 +166,7 @@
 source "arch/avr32/boards/atngw100/Kconfig"
 source "arch/avr32/boards/hammerhead/Kconfig"
 source "arch/avr32/boards/favr-32/Kconfig"
+source "arch/avr32/boards/merisc/Kconfig"
 
 choice
 	prompt "Boot loader type"
diff --git a/arch/avr32/Makefile b/arch/avr32/Makefile
index f3ef3bb..0b97e14 100644
--- a/arch/avr32/Makefile
+++ b/arch/avr32/Makefile
@@ -35,6 +35,7 @@
 core-$(CONFIG_BOARD_ATNGW100)		+= arch/avr32/boards/atngw100/
 core-$(CONFIG_BOARD_HAMMERHEAD)		+= arch/avr32/boards/hammerhead/
 core-$(CONFIG_BOARD_FAVR_32)		+= arch/avr32/boards/favr-32/
+core-$(CONFIG_BOARD_MERISC)		+= arch/avr32/boards/merisc/
 core-$(CONFIG_BOARD_MIMC200)		+= arch/avr32/boards/mimc200/
 core-$(CONFIG_LOADER_U_BOOT)		+= arch/avr32/boot/u-boot/
 core-y					+= arch/avr32/kernel/
diff --git a/arch/avr32/boards/atngw100/evklcd10x.c b/arch/avr32/boards/atngw100/evklcd10x.c
index 8140b22..0033711 100644
--- a/arch/avr32/boards/atngw100/evklcd10x.c
+++ b/arch/avr32/boards/atngw100/evklcd10x.c
@@ -11,6 +11,7 @@
 
 #include <linux/init.h>
 #include <linux/linkage.h>
+#include <linux/gpio.h>
 #include <linux/fb.h>
 #include <linux/platform_device.h>
 
@@ -19,26 +20,26 @@
 #include <asm/setup.h>
 
 #include <mach/at32ap700x.h>
+#include <mach/portmux.h>
 #include <mach/board.h>
 
+#include <sound/atmel-ac97c.h>
+
 static struct ac97c_platform_data __initdata ac97c0_data = {
-	.dma_rx_periph_id	= 3,
-	.dma_tx_periph_id	= 4,
-	.dma_controller_id	= 0,
-	.reset_pin		= GPIO_PIN_PB(19),
+	.reset_pin = GPIO_PIN_PB(19),
 };
 
 #ifdef CONFIG_BOARD_ATNGW100_EVKLCD10X_VGA
 static struct fb_videomode __initdata tcg057vglad_modes[] = {
 	{
-		.name		= "640x480 @ 60",
-		.refresh	= 60,
+		.name		= "640x480 @ 50",
+		.refresh	= 50,
 		.xres		= 640,		.yres		= 480,
 		.pixclock	= KHZ2PICOS(25180),
 
-		.left_margin	= 64,		.right_margin	= 31,
-		.upper_margin	= 34,		.lower_margin	= 2,
-		.hsync_len	= 96,		.vsync_len	= 4,
+		.left_margin	= 64,		.right_margin	= 96,
+		.upper_margin	= 34,		.lower_margin	= 11,
+		.hsync_len	= 64,		.vsync_len	= 15,
 
 		.sync		= 0,
 		.vmode		= FB_VMODE_NONINTERLACED,
@@ -69,14 +70,14 @@
 #elif CONFIG_BOARD_ATNGW100_EVKLCD10X_QVGA
 static struct fb_videomode __initdata tcg057qvlad_modes[] = {
 	{
-		.name		= "320x240 @ 60",
-		.refresh	= 60,
+		.name		= "320x240 @ 50",
+		.refresh	= 50,
 		.xres		= 320,		.yres		= 240,
 		.pixclock	= KHZ2PICOS(6300),
 
-		.left_margin	= 52,		.right_margin	= 28,
-		.upper_margin	= 7,		.lower_margin	= 2,
-		.hsync_len	= 96,		.vsync_len	= 4,
+		.left_margin	= 34,		.right_margin	= 46,
+		.upper_margin	= 7,		.lower_margin	= 15,
+		.hsync_len	= 64,		.vsync_len	= 12,
 
 		.sync		= 0,
 		.vmode		= FB_VMODE_NONINTERLACED,
@@ -144,12 +145,29 @@
 };
 #endif
 
+static void atevklcd10x_lcdc_power_control(int on)
+{
+	gpio_set_value(GPIO_PIN_PB(15), on);
+}
+
 static int __init atevklcd10x_init(void)
 {
-	at32_add_device_ac97c(0, &ac97c0_data);
+	/* PB15 is connected to the enable line on the boost regulator
+	 * controlling the backlight for the LCD panel.
+	 */
+	at32_select_gpio(GPIO_PIN_PB(15), AT32_GPIOF_OUTPUT);
+	gpio_request(GPIO_PIN_PB(15), "backlight");
+	gpio_direction_output(GPIO_PIN_PB(15), 0);
+
+	atevklcd10x_lcdc_data.atmel_lcdfb_power_control =
+		atevklcd10x_lcdc_power_control;
 
 	at32_add_device_lcdc(0, &atevklcd10x_lcdc_data,
-			fbmem_start, fbmem_size, 1);
+			fbmem_start, fbmem_size,
+			ATMEL_LCDC_ALT_18BIT | ATMEL_LCDC_PE_DVAL);
+
+	at32_add_device_ac97c(0, &ac97c0_data, AC97C_BOTH);
+
 	return 0;
 }
 postcore_initcall(atevklcd10x_init);
diff --git a/arch/avr32/boards/atngw100/setup.c b/arch/avr32/boards/atngw100/setup.c
index 05d3722..5b022aa 100644
--- a/arch/avr32/boards/atngw100/setup.c
+++ b/arch/avr32/boards/atngw100/setup.c
@@ -56,13 +56,8 @@
 static struct mci_platform_data __initdata mci0_data = {
 	.slot[0] = {
 		.bus_width	= 4,
-#ifndef CONFIG_BOARD_ATNGW100_EVKLCD10X
 		.detect_pin	= GPIO_PIN_PC(25),
 		.wp_pin		= GPIO_PIN_PE(0),
-#else
-		.detect_pin	= GPIO_PIN_NONE,
-		.wp_pin		= GPIO_PIN_NONE,
-#endif
 	},
 };
 
@@ -123,7 +118,7 @@
 
 void __init setup_board(void)
 {
-	at32_map_usart(1, 0);	/* USART 1: /dev/ttyS0, DB9 */
+	at32_map_usart(1, 0, 0);	/* USART 1: /dev/ttyS0, DB9 */
 	at32_setup_serial_console(0);
 }
 
diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c
index 1f33a10..2adc261 100644
--- a/arch/avr32/boards/atstk1000/atstk1002.c
+++ b/arch/avr32/boards/atstk1000/atstk1002.c
@@ -252,12 +252,12 @@
 void __init setup_board(void)
 {
 #ifdef	CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
-	at32_map_usart(0, 1);	/* USART 0/B: /dev/ttyS1, IRDA */
+	at32_map_usart(0, 1, 0);	/* USART 0/B: /dev/ttyS1, IRDA */
 #else
-	at32_map_usart(1, 0);	/* USART 1/A: /dev/ttyS0, DB9 */
+	at32_map_usart(1, 0, 0);	/* USART 1/A: /dev/ttyS0, DB9 */
 #endif
 	/* USART 2/unused: expansion connector */
-	at32_map_usart(3, 2);	/* USART 3/C: /dev/ttyS2, DB9 */
+	at32_map_usart(3, 2, 0);	/* USART 3/C: /dev/ttyS2, DB9 */
 
 	at32_setup_serial_console(0);
 }
diff --git a/arch/avr32/boards/atstk1000/atstk1003.c b/arch/avr32/boards/atstk1000/atstk1003.c
index b3a23c8..ff7e232 100644
--- a/arch/avr32/boards/atstk1000/atstk1003.c
+++ b/arch/avr32/boards/atstk1000/atstk1003.c
@@ -115,12 +115,12 @@
 void __init setup_board(void)
 {
 #ifdef	CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
-	at32_map_usart(0, 1);	/* USART 0/B: /dev/ttyS1, IRDA */
+	at32_map_usart(0, 1, 0);	/* USART 0/B: /dev/ttyS1, IRDA */
 #else
-	at32_map_usart(1, 0);	/* USART 1/A: /dev/ttyS0, DB9 */
+	at32_map_usart(1, 0, 0);	/* USART 1/A: /dev/ttyS0, DB9 */
 #endif
 	/* USART 2/unused: expansion connector */
-	at32_map_usart(3, 2);	/* USART 3/C: /dev/ttyS2, DB9 */
+	at32_map_usart(3, 2, 0);	/* USART 3/C: /dev/ttyS2, DB9 */
 
 	at32_setup_serial_console(0);
 }
diff --git a/arch/avr32/boards/atstk1000/atstk1004.c b/arch/avr32/boards/atstk1000/atstk1004.c
index 29b35ac..69a9f0f 100644
--- a/arch/avr32/boards/atstk1000/atstk1004.c
+++ b/arch/avr32/boards/atstk1000/atstk1004.c
@@ -120,12 +120,12 @@
 void __init setup_board(void)
 {
 #ifdef	CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
-	at32_map_usart(0, 1);	/* USART 0/B: /dev/ttyS1, IRDA */
+	at32_map_usart(0, 1, 0);	/* USART 0/B: /dev/ttyS1, IRDA */
 #else
-	at32_map_usart(1, 0);	/* USART 1/A: /dev/ttyS0, DB9 */
+	at32_map_usart(1, 0, 0);	/* USART 1/A: /dev/ttyS0, DB9 */
 #endif
 	/* USART 2/unused: expansion connector */
-	at32_map_usart(3, 2);	/* USART 3/C: /dev/ttyS2, DB9 */
+	at32_map_usart(3, 2, 0);	/* USART 3/C: /dev/ttyS2, DB9 */
 
 	at32_setup_serial_console(0);
 }
diff --git a/arch/avr32/boards/favr-32/setup.c b/arch/avr32/boards/favr-32/setup.c
index 745c408..46c9b0a 100644
--- a/arch/avr32/boards/favr-32/setup.c
+++ b/arch/avr32/boards/favr-32/setup.c
@@ -22,6 +22,8 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
 
+#include <sound/atmel-abdac.h>
+
 #include <video/atmel_lcdc.h>
 
 #include <asm/setup.h>
@@ -41,6 +43,9 @@
 /* Initialized by bootloader-specific startup code. */
 struct tag *bootloader_tags __initdata;
 
+static struct atmel_abdac_pdata __initdata abdac0_data = {
+};
+
 struct eth_addr {
 	u8 addr[6];
 };
@@ -245,7 +250,7 @@
 
 void __init setup_board(void)
 {
-	at32_map_usart(3, 0);	/* USART 3 => /dev/ttyS0 */
+	at32_map_usart(3, 0, 0);	/* USART 3 => /dev/ttyS0 */
 	at32_setup_serial_console(0);
 }
 
@@ -326,7 +331,7 @@
 
 	spi1_board_info[0].irq = gpio_to_irq(GPIO_PIN_PB(3));
 
-	set_abdac_rate(at32_add_device_abdac(0));
+	set_abdac_rate(at32_add_device_abdac(0, &abdac0_data));
 
 	at32_add_device_pwm(1 << atmel_pwm_bl_pdata.pwm_channel);
 	at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
diff --git a/arch/avr32/boards/hammerhead/setup.c b/arch/avr32/boards/hammerhead/setup.c
index 4d2fe82..dd009875 100644
--- a/arch/avr32/boards/hammerhead/setup.c
+++ b/arch/avr32/boards/hammerhead/setup.c
@@ -29,6 +29,8 @@
 #include <mach/init.h>
 #include <mach/portmux.h>
 
+#include <sound/atmel-ac97c.h>
+
 #include "../../mach-at32ap/clock.h"
 #include "flash.h"
 
@@ -163,7 +165,7 @@
 
 void __init setup_board(void)
 {
-	at32_map_usart(1, 0);	/* USART 1: /dev/ttyS0, DB9 */
+	at32_map_usart(1, 0, 0);	/* USART 1: /dev/ttyS0, DB9 */
 	at32_setup_serial_console(0);
 }
 
@@ -233,7 +235,7 @@
 	i2c_register_board_info(0, i2c_info, ARRAY_SIZE(i2c_info));
 
 #ifdef CONFIG_BOARD_HAMMERHEAD_SND
-	at32_add_device_ac97c(0, &ac97c_data);
+	at32_add_device_ac97c(0, &ac97c_data, AC97C_BOTH);
 #endif
 
 	/* Select the Touchscreen interrupt pin mode */
diff --git a/arch/avr32/boards/merisc/Kconfig b/arch/avr32/boards/merisc/Kconfig
new file mode 100644
index 0000000..7e04327
--- /dev/null
+++ b/arch/avr32/boards/merisc/Kconfig
@@ -0,0 +1,5 @@
+# Merisc customization
+
+if BOARD_MERISC
+
+endif	# BOARD_MERISC
diff --git a/arch/avr32/boards/merisc/Makefile b/arch/avr32/boards/merisc/Makefile
new file mode 100644
index 0000000..d24c787
--- /dev/null
+++ b/arch/avr32/boards/merisc/Makefile
@@ -0,0 +1 @@
+obj-y					+= setup.o flash.o display.o merisc_sysfs.o
diff --git a/arch/avr32/boards/merisc/display.c b/arch/avr32/boards/merisc/display.c
new file mode 100644
index 0000000..85a543c
--- /dev/null
+++ b/arch/avr32/boards/merisc/display.c
@@ -0,0 +1,65 @@
+/*
+ * Display setup code for the Merisc board
+ *
+ * Copyright (C) 2008 Martinsson Elektronik AB
+ *
+ * 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/init.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <video/atmel_lcdc.h>
+#include <asm/setup.h>
+#include <mach/board.h>
+#include "merisc.h"
+
+static struct fb_videomode merisc_fb_videomode[] = {
+	{
+		.refresh	= 44,
+		.xres		= 640,
+		.yres		= 480,
+		.left_margin	= 96,
+		.right_margin	= 96,
+		.upper_margin	= 34,
+		.lower_margin	= 8,
+		.hsync_len	= 64,
+		.vsync_len	= 64,
+		.name		= "640x480 @ 44",
+		.pixclock	= KHZ2PICOS(25180),
+		.sync		= 0,
+		.vmode		= FB_VMODE_NONINTERLACED,
+	},
+};
+
+static struct fb_monspecs merisc_fb_monspecs = {
+	.manufacturer	= "Kyo",
+	.monitor	= "TCG075VG2AD",
+	.modedb		= merisc_fb_videomode,
+	.modedb_len	= ARRAY_SIZE(merisc_fb_videomode),
+	.hfmin		= 30000,
+	.hfmax		= 33333,
+	.vfmin		= 60,
+	.vfmax		= 90,
+	.dclkmax	= 30000000,
+};
+
+struct atmel_lcdfb_info merisc_lcdc_data = {
+	.default_bpp		= 24,
+	.default_dmacon		= ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
+	.default_lcdcon2	= (ATMEL_LCDC_DISTYPE_TFT
+				   | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE
+				   | ATMEL_LCDC_MEMOR_BIG),
+	.default_monspecs	= &merisc_fb_monspecs,
+	.guard_time		= 2,
+};
+
+static int __init merisc_display_init(void)
+{
+	at32_add_device_lcdc(0, &merisc_lcdc_data, fbmem_start,
+			     fbmem_size, 0);
+
+	return 0;
+}
+device_initcall(merisc_display_init);
diff --git a/arch/avr32/boards/merisc/flash.c b/arch/avr32/boards/merisc/flash.c
new file mode 100644
index 0000000..8e856fd
--- /dev/null
+++ b/arch/avr32/boards/merisc/flash.c
@@ -0,0 +1,139 @@
+/*
+ * Merisc board-specific flash initialization
+ *
+ * Copyright (C) 2008 Martinsson Elektronik AB
+ *
+ * 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/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <mach/smc.h>
+
+/* Will be translated to units of 14.3 ns, rounded up */
+static struct smc_timing flash_timing __initdata = {
+	.ncs_read_setup		= 1 * 14,
+	.nrd_setup		= 5 * 14,
+	.ncs_write_setup	= 1 * 14,
+	.nwe_setup		= 2 * 14,
+
+	.ncs_read_pulse		= 12 * 14,
+	.nrd_pulse		= 7 * 14,
+	.ncs_write_pulse	= 8 * 14,
+	.nwe_pulse		= 4 * 14,
+
+	.read_cycle		= 14 * 14,
+	.write_cycle		= 10 * 14,
+};
+
+static struct smc_config flash_config __initdata = {
+	.bus_width	= 2,
+	.nrd_controlled	= 1,
+	.nwe_controlled	= 1,
+	.byte_write	= 1,
+	.tdf_cycles	= 3,
+};
+
+static struct mtd_partition flash_0_parts[] = {
+	{
+		.name		= "boot",
+		.offset		= 0x00000000,
+		.size		= 0x00060000,
+		.mask_flags	= 0,
+	},
+	{
+		.name		= "kernel",
+		.offset		= 0x00060000,
+		.size		= 0x00200000,
+		.mask_flags	= 0,
+	},
+	{
+		.name		= "root",
+		.offset		= 0x00260000,
+		.size		= MTDPART_SIZ_FULL,
+		.mask_flags	= 0,
+	},
+};
+
+static struct mtd_partition flash_1_parts[] = {
+	{
+		.name		= "2ndflash",
+		.offset		= 0x00000000,
+		.size		= MTDPART_SIZ_FULL,
+		.mask_flags	= 0,
+	},
+};
+
+static struct physmap_flash_data flash_data[] = {
+	{
+		.width		= 2,
+		.nr_parts	= ARRAY_SIZE(flash_0_parts),
+		.parts		= flash_0_parts,
+	},
+	{
+		.width		= 2,
+		.nr_parts	= ARRAY_SIZE(flash_1_parts),
+		.parts		= flash_1_parts,
+	}
+};
+
+static struct resource flash_resource[] = {
+	{
+		.start		= 0x00000000,
+		.end		= 0x03ffffff,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= 0x04000000,
+		.end		= 0x07ffffff,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device flash_device[] = {
+	{
+		.name		= "physmap-flash",
+		.id		= 0,
+		.resource	= &flash_resource[0],
+		.num_resources	= 1,
+		.dev		= {
+			.platform_data	= &flash_data[0],
+		},
+	},
+	{
+		.name		= "physmap-flash",
+		.id		= 1,
+		.resource	= &flash_resource[1],
+		.num_resources	= 1,
+		.dev		= {
+			.platform_data	= &flash_data[1],
+		},
+	},
+};
+
+static int __init merisc_flash_init(void)
+{
+	int ret;
+	smc_set_timing(&flash_config, &flash_timing);
+
+	ret = smc_set_configuration(0, &flash_config);
+	if (ret < 0) {
+		printk(KERN_ERR "Merisc: failed to set NOR flash timing #0\n");
+		return ret;
+	}
+
+	ret = smc_set_configuration(4, &flash_config);
+	if (ret < 0) {
+		printk(KERN_ERR "Merisc: failed to set NOR flash timing #1\n");
+		return ret;
+	}
+
+	platform_device_register(&flash_device[0]);
+	platform_device_register(&flash_device[1]);
+	return 0;
+}
+device_initcall(merisc_flash_init);
diff --git a/arch/avr32/boards/merisc/merisc.h b/arch/avr32/boards/merisc/merisc.h
new file mode 100644
index 0000000..50ffb2f
--- /dev/null
+++ b/arch/avr32/boards/merisc/merisc.h
@@ -0,0 +1,18 @@
+/*
+ * Merisc exports
+ *
+ * Copyright (C) 2008 Martinsson Elektronik AB
+ *
+ * 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 __ARCH_AVR32_BOARDS_MERISC_MERISC_H
+#define __ARCH_AVR32_BOARDS_MERISC_MERISC_H
+
+const char *merisc_revision(void);
+const char *merisc_model(void);
+
+extern struct class merisc_class;
+
+#endif /* __ARCH_AVR32_BOARDS_MERISC_MERISC_H */
diff --git a/arch/avr32/boards/merisc/merisc_sysfs.c b/arch/avr32/boards/merisc/merisc_sysfs.c
new file mode 100644
index 0000000..df431fd
--- /dev/null
+++ b/arch/avr32/boards/merisc/merisc_sysfs.c
@@ -0,0 +1,65 @@
+/*
+ * Merisc sysfs exports
+ *
+ * Copyright (C) 2008 Martinsson Elektronik AB
+ *
+ * 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/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+#include <linux/timer.h>
+#include <linux/err.h>
+#include <linux/ctype.h>
+#include "merisc.h"
+
+static ssize_t merisc_model_show(struct class *class, char *buf)
+{
+	ssize_t ret = 0;
+
+	sprintf(buf, "%s\n", merisc_model());
+	ret = strlen(buf) + 1;
+
+	return ret;
+}
+
+static ssize_t merisc_revision_show(struct class *class, char *buf)
+{
+	ssize_t ret = 0;
+
+	sprintf(buf, "%s\n", merisc_revision());
+	ret = strlen(buf) + 1;
+
+	return ret;
+}
+
+static struct class_attribute merisc_class_attrs[] = {
+	__ATTR(model, S_IRUGO, merisc_model_show, NULL),
+	__ATTR(revision, S_IRUGO, merisc_revision_show, NULL),
+	__ATTR_NULL,
+};
+
+struct class merisc_class = {
+	.name =		"merisc",
+	.owner =	THIS_MODULE,
+	.class_attrs =	merisc_class_attrs,
+};
+
+static int __init merisc_sysfs_init(void)
+{
+	int status;
+
+	status = class_register(&merisc_class);
+	if (status < 0)
+		return status;
+
+	return 0;
+}
+
+postcore_initcall(merisc_sysfs_init);
diff --git a/arch/avr32/boards/merisc/setup.c b/arch/avr32/boards/merisc/setup.c
new file mode 100644
index 0000000..20b300c
--- /dev/null
+++ b/arch/avr32/boards/merisc/setup.c
@@ -0,0 +1,297 @@
+/*
+ * Board-specific setup code for the Merisc
+ *
+ * Copyright (C) 2008 Martinsson Elektronik AB
+ *
+ * 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/clk.h>
+#include <linux/etherdevice.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/leds.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/irq.h>
+#include <linux/fb.h>
+#include <linux/atmel-mci.h>
+
+#include <asm/io.h>
+#include <asm/setup.h>
+#include <asm/gpio.h>
+
+#include <mach/at32ap700x.h>
+#include <mach/board.h>
+#include <mach/init.h>
+#include <mach/portmux.h>
+
+#include "merisc.h"
+
+/* Holds the autodetected board model and revision */
+static int merisc_board_id;
+
+/* Initialized by bootloader-specific startup code. */
+struct tag *bootloader_tags __initdata;
+
+/* Oscillator frequencies. These are board specific */
+unsigned long at32_board_osc_rates[3] = {
+	[0]	= 32768,	/* 32.768 kHz on RTC osc */
+	[1]	= 20000000,	/* 20 MHz on osc0 */
+	[2]	= 12000000,	/* 12 MHz on osc1 */
+};
+
+struct eth_addr {
+	u8 addr[6];
+};
+
+static struct eth_addr __initdata hw_addr[2];
+static struct eth_platform_data __initdata eth_data[2];
+
+static int ads7846_get_pendown_state_PB26(void)
+{
+	return !gpio_get_value(GPIO_PIN_PB(26));
+}
+
+static int ads7846_get_pendown_state_PB28(void)
+{
+	return !gpio_get_value(GPIO_PIN_PB(28));
+}
+
+static struct ads7846_platform_data __initdata ads7846_data = {
+	.model				= 7846,
+	.vref_delay_usecs		= 100,
+	.vref_mv			= 0,
+	.keep_vref_on			= 0,
+	.settle_delay_usecs		= 150,
+	.penirq_recheck_delay_usecs	= 1,
+	.x_plate_ohms			= 800,
+	.debounce_rep			= 4,
+	.debounce_max			= 10,
+	.debounce_tol			= 50,
+	.get_pendown_state		= ads7846_get_pendown_state_PB26,
+	.filter_init			= NULL,
+	.filter				= NULL,
+	.filter_cleanup			= NULL,
+};
+
+static struct spi_board_info __initdata spi0_board_info[] = {
+	{
+		.modalias	= "ads7846",
+		.max_speed_hz	= 3250000,
+		.chip_select	= 0,
+		.bus_num	= 0,
+		.platform_data	= &ads7846_data,
+		.mode		= SPI_MODE_0,
+	},
+};
+
+static struct mci_platform_data __initdata mci0_data = {
+	.slot[0] = {
+		.bus_width	= 4,
+		.detect_pin	= GPIO_PIN_PE(19),
+		.wp_pin		= GPIO_PIN_PE(20),
+	},
+};
+
+static int __init parse_tag_ethernet(struct tag *tag)
+{
+	int i;
+
+	i = tag->u.ethernet.mac_index;
+	if (i < ARRAY_SIZE(hw_addr)) {
+		memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address,
+		       sizeof(hw_addr[i].addr));
+	}
+
+	return 0;
+}
+__tagtable(ATAG_ETHERNET, parse_tag_ethernet);
+
+static void __init set_hw_addr(struct platform_device *pdev)
+{
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	const u8 *addr;
+	void __iomem *regs;
+	struct clk *pclk;
+
+	if (!res)
+		return;
+
+	if (pdev->id >= ARRAY_SIZE(hw_addr))
+		return;
+
+	addr = hw_addr[pdev->id].addr;
+	if (!is_valid_ether_addr(addr))
+		return;
+
+	regs = (void __iomem __force *)res->start;
+	pclk = clk_get(&pdev->dev, "pclk");
+	if (!pclk)
+		return;
+
+	clk_enable(pclk);
+	__raw_writel((addr[3] << 24) | (addr[2] << 16)
+		     | (addr[1] << 8) | addr[0], regs + 0x98);
+	__raw_writel((addr[5] << 8) | addr[4], regs + 0x9c);
+	clk_disable(pclk);
+	clk_put(pclk);
+}
+
+static struct i2c_gpio_platform_data i2c_gpio_data = {
+	.sda_pin		= GPIO_PIN_PA(6),
+	.scl_pin		= GPIO_PIN_PA(7),
+	.sda_is_open_drain	= 1,
+	.scl_is_open_drain	= 1,
+	.udelay			= 2,
+};
+
+static struct platform_device i2c_gpio_device = {
+	.name	= "i2c-gpio",
+	.id	= 0,
+	.dev	= {
+		.platform_data	= &i2c_gpio_data,
+	},
+};
+
+static struct i2c_board_info __initdata i2c_info[] = {
+	{
+		I2C_BOARD_INFO("pcf8563", 0x51)
+	},
+};
+
+#ifdef CONFIG_LEDS_ATMEL_PWM
+static struct gpio_led stk_pwm_led[] = {
+	{
+		.name	= "backlight",
+		.gpio	= 0,		/* PWM channel 0 (LCD backlight) */
+	},
+};
+
+static struct gpio_led_platform_data stk_pwm_led_data = {
+	.num_leds	= ARRAY_SIZE(stk_pwm_led),
+	.leds		= stk_pwm_led,
+};
+
+static struct platform_device stk_pwm_led_dev = {
+	.name	= "leds-atmel-pwm",
+	.id	= -1,
+	.dev	= {
+		.platform_data	= &stk_pwm_led_data,
+	},
+};
+#endif
+
+const char *merisc_model(void)
+{
+	switch (merisc_board_id) {
+	case 0:
+	case 1:
+		return "500-01";
+	case 2:
+		return "BT";
+	default:
+		return "Unknown";
+	}
+}
+
+const char *merisc_revision(void)
+{
+	switch (merisc_board_id) {
+	case 0:
+		return "B";
+	case 1:
+		return "D";
+	case 2:
+		return "A";
+	default:
+		return "Unknown";
+	}
+}
+
+static void detect_merisc_board_id(void)
+{
+	/* Board ID pins MUST be set as input or the board may be damaged */
+	at32_select_gpio(GPIO_PIN_PA(24), AT32_GPIOF_PULLUP);
+	at32_select_gpio(GPIO_PIN_PA(25), AT32_GPIOF_PULLUP);
+	at32_select_gpio(GPIO_PIN_PA(26), AT32_GPIOF_PULLUP);
+	at32_select_gpio(GPIO_PIN_PA(27), AT32_GPIOF_PULLUP);
+
+	merisc_board_id = !gpio_get_value(GPIO_PIN_PA(24)) +
+		!gpio_get_value(GPIO_PIN_PA(25)) * 2 +
+		!gpio_get_value(GPIO_PIN_PA(26)) * 4 +
+		!gpio_get_value(GPIO_PIN_PA(27)) * 8;
+}
+
+void __init setup_board(void)
+{
+	at32_map_usart(0, 0, 0);
+	at32_map_usart(1, 1, 0);
+	at32_map_usart(3, 3, 0);
+	at32_setup_serial_console(1);
+}
+
+static int __init merisc_init(void)
+{
+	detect_merisc_board_id();
+
+	printk(KERN_NOTICE "BOARD: Merisc %s revision %s\n", merisc_model(),
+	       merisc_revision());
+
+	/* Reserve pins for SDRAM */
+	at32_reserve_pin(GPIO_PIOE_BASE, ATMEL_EBI_PE_DATA_ALL | (1 << 26));
+
+	if (merisc_board_id >= 1)
+		at32_map_usart(2, 2, 0);
+
+	at32_add_device_usart(0);
+	at32_add_device_usart(1);
+	if (merisc_board_id >= 1)
+		at32_add_device_usart(2);
+	at32_add_device_usart(3);
+	set_hw_addr(at32_add_device_eth(0, &eth_data[0]));
+
+	/* ADS7846 PENIRQ */
+	if (merisc_board_id == 0) {
+		ads7846_data.get_pendown_state = ads7846_get_pendown_state_PB26;
+		at32_select_periph(GPIO_PIOB_BASE, 1 << 26,
+				   GPIO_PERIPH_A, AT32_GPIOF_PULLUP);
+		spi0_board_info[0].irq = AT32_EXTINT(1);
+	} else {
+		ads7846_data.get_pendown_state = ads7846_get_pendown_state_PB28;
+		at32_select_periph(GPIO_PIOB_BASE, 1 << 28, GPIO_PERIPH_A,
+				   AT32_GPIOF_PULLUP);
+		spi0_board_info[0].irq = AT32_EXTINT(3);
+	}
+
+	/* ADS7846 busy pin */
+	at32_select_gpio(GPIO_PIN_PA(4), AT32_GPIOF_PULLUP);
+
+	at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
+
+	at32_add_device_mci(0, &mci0_data);
+
+#ifdef CONFIG_LEDS_ATMEL_PWM
+	at32_add_device_pwm((1 << 0) | (1 << 2));
+	platform_device_register(&stk_pwm_led_dev);
+#else
+	at32_add_device_pwm((1 << 2));
+#endif
+
+	at32_select_gpio(i2c_gpio_data.sda_pin,
+		AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
+	at32_select_gpio(i2c_gpio_data.scl_pin,
+		AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
+	platform_device_register(&i2c_gpio_device);
+
+	i2c_register_board_info(0, i2c_info, ARRAY_SIZE(i2c_info));
+
+	return 0;
+}
+postcore_initcall(merisc_init);
diff --git a/arch/avr32/boards/mimc200/setup.c b/arch/avr32/boards/mimc200/setup.c
index 2b58d61..c1b2175 100644
--- a/arch/avr32/boards/mimc200/setup.c
+++ b/arch/avr32/boards/mimc200/setup.c
@@ -175,10 +175,10 @@
 
 void __init setup_board(void)
 {
-	at32_map_usart(0, 0);	/* USART 0: /dev/ttyS0 (TTL --> Altera) */
-	at32_map_usart(1, 1);	/* USART 1: /dev/ttyS1 (RS232) */
-	at32_map_usart(2, 2);	/* USART 2: /dev/ttyS2 (RS485) */
-	at32_map_usart(3, 3);	/* USART 3: /dev/ttyS3 (RS422 Multidrop) */
+	at32_map_usart(0, 0, 0);	/* USART 0: /dev/ttyS0 (TTL --> Altera) */
+	at32_map_usart(1, 1, 0);	/* USART 1: /dev/ttyS1 (RS232) */
+	at32_map_usart(2, 2, 0);	/* USART 2: /dev/ttyS2 (RS485) */
+	at32_map_usart(3, 3, 0);	/* USART 3: /dev/ttyS3 (RS422 Multidrop) */
 }
 
 static struct i2c_gpio_platform_data i2c_gpio_data = {
diff --git a/arch/avr32/configs/merisc_defconfig b/arch/avr32/configs/merisc_defconfig
new file mode 100644
index 0000000..41554db
--- /dev/null
+++ b/arch/avr32/configs/merisc_defconfig
@@ -0,0 +1,1237 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc1
+# Wed Mar 25 14:06:15 2009
+#
+CONFIG_AVR32=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_BASE_FULL is not set
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_CLK=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=1
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+# CONFIG_FREEZER is not set
+
+#
+# System Type and features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_SUBARCH_AVR32B=y
+CONFIG_MMU=y
+CONFIG_PERFORMANCE_COUNTERS=y
+CONFIG_PLATFORM_AT32AP=y
+CONFIG_CPU_AT32AP700X=y
+CONFIG_CPU_AT32AP7000=y
+# CONFIG_BOARD_ATSTK1000 is not set
+# CONFIG_BOARD_ATNGW100 is not set
+# CONFIG_BOARD_HAMMERHEAD is not set
+# CONFIG_BOARD_FAVR_32 is not set
+# CONFIG_BOARD_MIMC200 is not set
+CONFIG_BOARD_MERISC=y
+CONFIG_LOADER_U_BOOT=y
+
+#
+# Atmel AVR32 AP options
+#
+CONFIG_AP700X_32_BIT_SMC=y
+# CONFIG_AP700X_16_BIT_SMC is not set
+# CONFIG_AP700X_8_BIT_SMC is not set
+CONFIG_LOAD_ADDRESS=0x10000000
+CONFIG_ENTRY_ADDRESS=0x90000000
+CONFIG_PHYS_OFFSET=0x10000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_QUICKLIST=y
+# CONFIG_HAVE_ARCH_BOOTMEM_NODE is not set
+# CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set
+# CONFIG_NEED_NODE_MEMMAP_SIZE is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+# CONFIG_ARCH_SPARSEMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+# CONFIG_OWNERSHIP_TRACE is not set
+# CONFIG_NMI_DEBUGGING is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_CMDLINE=""
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Bus options
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=y
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+# CONFIG_IP_PIMSM_V2 is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_CAN=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_BCM=y
+
+#
+# CAN Device Drivers
+#
+# CONFIG_CAN_VCAN is not set
+# CONFIG_CAN_DEBUG_DEVICES is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+CONFIG_MTD_ABSENT=y
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+CONFIG_MTD_BLOCK2MTD=y
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_QINFO_PROBE is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+CONFIG_ATMEL_PWM=y
+# CONFIG_ATMEL_TCLIB is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ICS932S401 is not set
+CONFIG_ATMEL_SSC=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+CONFIG_MACB=y
+# CONFIG_ENC28J60 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+# CONFIG_CONSOLE_TRANSLATIONS is not set
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_SERIAL_ATMEL_PDC=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_GPIO=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_ATMEL=y
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+CONFIG_SPI_SPIDEV=y
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_AT32AP700X_WDT is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_REGULATOR is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_ATMEL=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=y
+
+#
+# Display hardware drivers
+#
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+# CONFIG_HID_PID is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+CONFIG_USB_SUPPORT=y
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+
+#
+# Enable Host or Gadget support to see Inventra options
+#
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_ATMELMCI=y
+CONFIG_MMC_ATMELMCI_DMA=y
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+CONFIG_LEDS_ATMEL_PWM=y
+# CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_GPIO is not set
+# CONFIG_LEDS_PCA955X is not set
+
+#
+# LED Triggers
+#
+# CONFIG_LEDS_TRIGGERS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_HCTOSYS is not set
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+CONFIG_RTC_DRV_PCF8563=y
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_AT32AP700X is not set
+CONFIG_DMADEVICES=y
+
+#
+# DMA Devices
+#
+CONFIG_DW_DMAC=y
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_DMATEST is not set
+CONFIG_UIO=y
+# CONFIG_UIO_PDRV is not set
+# CONFIG_UIO_PDRV_GENIRQ is not set
+# CONFIG_UIO_SMX is not set
+# CONFIG_UIO_SERCOS3 is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_FS_WBUF_VERIFY=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+
+#
+# Tracers
+#
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/avr32/include/asm/ftrace.h b/arch/avr32/include/asm/ftrace.h
new file mode 100644
index 0000000..40a8c17
--- /dev/null
+++ b/arch/avr32/include/asm/ftrace.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/avr32/include/asm/hardirq.h b/arch/avr32/include/asm/hardirq.h
index 2673543..015bc75 100644
--- a/arch/avr32/include/asm/hardirq.h
+++ b/arch/avr32/include/asm/hardirq.h
@@ -20,15 +20,4 @@
 
 #endif /* __ASSEMBLY__ */
 
-#define HARDIRQ_BITS	12
-
-/*
- * The hardirq mask has to be large enough to have
- * space for potentially all IRQ sources in the system
- * nesting on a single CPU:
- */
-#if (1 << HARDIRQ_BITS) < NR_IRQS
-# error HARDIRQ_BITS is too low!
-#endif
-
 #endif /* __ASM_AVR32_HARDIRQ_H */
diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c
index 3fbfd1e..7cc6537 100644
--- a/arch/avr32/mach-at32ap/at32ap700x.c
+++ b/arch/avr32/mach-at32ap/at32ap700x.c
@@ -26,6 +26,9 @@
 #include <mach/portmux.h>
 #include <mach/sram.h>
 
+#include <sound/atmel-abdac.h>
+#include <sound/atmel-ac97c.h>
+
 #include <video/atmel_lcdc.h>
 
 #include "clock.h"
@@ -963,56 +966,68 @@
 DEFINE_DEV_DATA(atmel_usart, 3);
 DEV_CLK(usart, atmel_usart3, pba, 6);
 
-static inline void configure_usart0_pins(void)
+static inline void configure_usart0_pins(int flags)
 {
 	u32 pin_mask = (1 << 8) | (1 << 9); /* RXD & TXD */
+	if (flags & ATMEL_USART_RTS)	pin_mask |= (1 << 6);
+	if (flags & ATMEL_USART_CTS)	pin_mask |= (1 << 7);
+	if (flags & ATMEL_USART_CLK)	pin_mask |= (1 << 10);
 
 	select_peripheral(PIOA, pin_mask, PERIPH_B, AT32_GPIOF_PULLUP);
 }
 
-static inline void configure_usart1_pins(void)
+static inline void configure_usart1_pins(int flags)
 {
 	u32 pin_mask = (1 << 17) | (1 << 18); /* RXD & TXD */
+	if (flags & ATMEL_USART_RTS)	pin_mask |= (1 << 19);
+	if (flags & ATMEL_USART_CTS)	pin_mask |= (1 << 20);
+	if (flags & ATMEL_USART_CLK)	pin_mask |= (1 << 16);
 
 	select_peripheral(PIOA, pin_mask, PERIPH_A, AT32_GPIOF_PULLUP);
 }
 
-static inline void configure_usart2_pins(void)
+static inline void configure_usart2_pins(int flags)
 {
 	u32 pin_mask = (1 << 26) | (1 << 27); /* RXD & TXD */
+	if (flags & ATMEL_USART_RTS)	pin_mask |= (1 << 30);
+	if (flags & ATMEL_USART_CTS)	pin_mask |= (1 << 29);
+	if (flags & ATMEL_USART_CLK)	pin_mask |= (1 << 28);
 
 	select_peripheral(PIOB, pin_mask, PERIPH_B, AT32_GPIOF_PULLUP);
 }
 
-static inline void configure_usart3_pins(void)
+static inline void configure_usart3_pins(int flags)
 {
 	u32 pin_mask = (1 << 18) | (1 << 17); /* RXD & TXD */
+	if (flags & ATMEL_USART_RTS)	pin_mask |= (1 << 16);
+	if (flags & ATMEL_USART_CTS)	pin_mask |= (1 << 15);
+	if (flags & ATMEL_USART_CLK)	pin_mask |= (1 << 19);
 
 	select_peripheral(PIOB, pin_mask, PERIPH_B, AT32_GPIOF_PULLUP);
 }
 
 static struct platform_device *__initdata at32_usarts[4];
 
-void __init at32_map_usart(unsigned int hw_id, unsigned int line)
+void __init at32_map_usart(unsigned int hw_id, unsigned int line, int flags)
 {
 	struct platform_device *pdev;
 
 	switch (hw_id) {
 	case 0:
 		pdev = &atmel_usart0_device;
-		configure_usart0_pins();
+		configure_usart0_pins(flags);
 		break;
 	case 1:
 		pdev = &atmel_usart1_device;
-		configure_usart1_pins();
+		configure_usart1_pins(flags);
 		break;
 	case 2:
 		pdev = &atmel_usart2_device;
-		configure_usart2_pins();
+		configure_usart2_pins(flags);
 		break;
 	case 3:
 		pdev = &atmel_usart3_device;
-		configure_usart3_pins();
+		configure_usart3_pins(flags);
 		break;
 	default:
 		return;
@@ -1753,7 +1768,7 @@
 	if (platform_device_add_data(pdev, data, sizeof(usba_data)))
 		goto out_free_pdev;
 
-	if (data->vbus_pin >= 0)
+	if (gpio_is_valid(data->vbus_pin))
 		at32_select_gpio(data->vbus_pin, 0);
 
 	usba0_pclk.dev = &pdev->dev;
@@ -1980,11 +1995,14 @@
 };
 
 struct platform_device *__init
-at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data)
+at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data,
+		      unsigned int flags)
 {
-	struct platform_device *pdev;
-	struct ac97c_platform_data _data;
-	u32 pin_mask;
+	struct platform_device		*pdev;
+	struct dw_dma_slave		*rx_dws;
+	struct dw_dma_slave		*tx_dws;
+	struct ac97c_platform_data	_data;
+	u32				pin_mask;
 
 	if (id != 0)
 		return NULL;
@@ -1995,37 +2013,52 @@
 
 	if (platform_device_add_resources(pdev, atmel_ac97c0_resource,
 				ARRAY_SIZE(atmel_ac97c0_resource)))
-		goto fail;
+		goto out_free_resources;
 
 	if (!data) {
 		data = &_data;
 		memset(data, 0, sizeof(struct ac97c_platform_data));
-		data->reset_pin = GPIO_PIN_NONE;
+		data->reset_pin = -ENODEV;
 	}
 
-	data->dma_rx_periph_id = 3;
-	data->dma_tx_periph_id = 4;
-	data->dma_controller_id = 0;
+	rx_dws = &data->rx_dws;
+	tx_dws = &data->tx_dws;
+
+	/* Check if DMA slave interface for capture should be configured. */
+	if (flags & AC97C_CAPTURE) {
+		rx_dws->dma_dev = &dw_dmac0_device.dev;
+		rx_dws->reg_width = DW_DMA_SLAVE_WIDTH_16BIT;
+		rx_dws->cfg_hi = DWC_CFGH_SRC_PER(3);
+		rx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL);
+	}
+
+	/* Check if DMA slave interface for playback should be configured. */
+	if (flags & AC97C_PLAYBACK) {
+		tx_dws->dma_dev = &dw_dmac0_device.dev;
+		tx_dws->reg_width = DW_DMA_SLAVE_WIDTH_16BIT;
+		tx_dws->cfg_hi = DWC_CFGH_DST_PER(4);
+		tx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL);
+	}
 
 	if (platform_device_add_data(pdev, data,
 				sizeof(struct ac97c_platform_data)))
-		goto fail;
+		goto out_free_resources;
 
-	pin_mask  = (1 << 20) | (1 << 21);	/* SDO & SYNC */
-	pin_mask |= (1 << 22) | (1 << 23);	/* SCLK & SDI */
+	/* SDO | SYNC | SCLK | SDI */
+	pin_mask = (1 << 20) | (1 << 21) | (1 << 22) | (1 << 23);
 
 	select_peripheral(PIOB, pin_mask, PERIPH_B, 0);
 
-	/* TODO: gpio_is_valid(data->reset_pin) with kernel 2.6.26. */
-	if (data->reset_pin != GPIO_PIN_NONE)
-		at32_select_gpio(data->reset_pin, 0);
+	if (gpio_is_valid(data->reset_pin))
+		at32_select_gpio(data->reset_pin, AT32_GPIOF_OUTPUT
+				| AT32_GPIOF_HIGH);
 
 	atmel_ac97c0_pclk.dev = &pdev->dev;
 
 	platform_device_add(pdev);
 	return pdev;
 
-fail:
+out_free_resources:
 	platform_device_put(pdev);
 	return NULL;
 }
@@ -2053,21 +2086,34 @@
 	.index		= 6,
 };
 
-struct platform_device *__init at32_add_device_abdac(unsigned int id)
+struct platform_device *__init
+at32_add_device_abdac(unsigned int id, struct atmel_abdac_pdata *data)
 {
-	struct platform_device *pdev;
-	u32 pin_mask;
+	struct platform_device	*pdev;
+	struct dw_dma_slave	*dws;
+	u32			pin_mask;
 
-	if (id != 0)
+	if (id != 0 || !data)
 		return NULL;
 
-	pdev = platform_device_alloc("abdac", id);
+	pdev = platform_device_alloc("atmel_abdac", id);
 	if (!pdev)
 		return NULL;
 
 	if (platform_device_add_resources(pdev, abdac0_resource,
 				ARRAY_SIZE(abdac0_resource)))
-		goto err_add_resources;
+		goto out_free_resources;
+
+	dws = &data->dws;
+
+	dws->dma_dev = &dw_dmac0_device.dev;
+	dws->reg_width = DW_DMA_SLAVE_WIDTH_32BIT;
+	dws->cfg_hi = DWC_CFGH_DST_PER(2);
+	dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL);
+
+	if (platform_device_add_data(pdev, data,
+				sizeof(struct atmel_abdac_pdata)))
+		goto out_free_resources;
 
 	pin_mask  = (1 << 20) | (1 << 22);	/* DATA1 & DATAN1 */
 	pin_mask |= (1 << 21) | (1 << 23);	/* DATA0 & DATAN0 */
@@ -2080,7 +2126,7 @@
 	platform_device_add(pdev);
 	return pdev;
 
-err_add_resources:
+out_free_resources:
 	platform_device_put(pdev);
 	return NULL;
 }
diff --git a/arch/avr32/mach-at32ap/include/mach/at32ap700x.h b/arch/avr32/mach-at32ap/include/mach/at32ap700x.h
index 5c4c971..b9222bf 100644
--- a/arch/avr32/mach-at32ap/include/mach/at32ap700x.h
+++ b/arch/avr32/mach-at32ap/include/mach/at32ap700x.h
@@ -171,25 +171,49 @@
 		ATMEL_LCDC(PE, DATA20) | ATMEL_LCDC(PE, DATA21) |	\
 		ATMEL_LCDC(PD, DATA22) | ATMEL_LCDC(PD, DATA23))
 
-#define ATMEL_LCDC_PRI_15B_DATA (					\
-		ATMEL_LCDC(PC, DATA0)  | ATMEL_LCDC(PC, DATA1)  |	\
+#define ATMEL_LCDC_PRI_18B_DATA (					\
 		ATMEL_LCDC(PC, DATA2)  | ATMEL_LCDC(PC, DATA3)  |	\
 		ATMEL_LCDC(PC, DATA4)  | ATMEL_LCDC(PC, DATA5)  |	\
-		ATMEL_LCDC(PD, DATA8)  | ATMEL_LCDC(PD, DATA9)  |	\
+		ATMEL_LCDC(PD, DATA6)  | ATMEL_LCDC(PD, DATA7)  |	\
 		ATMEL_LCDC(PD, DATA10) | ATMEL_LCDC(PD, DATA11) |	\
-		ATMEL_LCDC(PD, DATA12) | ATMEL_LCDC(PD, DATA16) |	\
-		ATMEL_LCDC(PD, DATA17) | ATMEL_LCDC(PD, DATA18) |	\
-		ATMEL_LCDC(PD, DATA19) | ATMEL_LCDC(PD, DATA20))
+		ATMEL_LCDC(PD, DATA12) | ATMEL_LCDC(PD, DATA13) |	\
+		ATMEL_LCDC(PD, DATA14) | ATMEL_LCDC(PD, DATA15) |	\
+		ATMEL_LCDC(PD, DATA18) | ATMEL_LCDC(PD, DATA19) |	\
+		ATMEL_LCDC(PD, DATA20) | ATMEL_LCDC(PD, DATA21) |	\
+		ATMEL_LCDC(PD, DATA22) | ATMEL_LCDC(PD, DATA23))
 
-#define ATMEL_LCDC_ALT_15B_DATA	(					\
-		ATMEL_LCDC(PE, DATA0)  | ATMEL_LCDC(PE, DATA1)  |	\
+#define ATMEL_LCDC_ALT_18B_DATA	(					\
 		ATMEL_LCDC(PE, DATA2)  | ATMEL_LCDC(PE, DATA3)  |	\
 		ATMEL_LCDC(PE, DATA4)  | ATMEL_LCDC(PC, DATA5)  |	\
-		ATMEL_LCDC(PE, DATA8)  | ATMEL_LCDC(PE, DATA9)  |	\
+		ATMEL_LCDC(PD, DATA6)  | ATMEL_LCDC(PD, DATA7)  |	\
 		ATMEL_LCDC(PE, DATA10) | ATMEL_LCDC(PE, DATA11) |	\
-		ATMEL_LCDC(PE, DATA12) | ATMEL_LCDC(PE, DATA16) |	\
-		ATMEL_LCDC(PE, DATA17) | ATMEL_LCDC(PE, DATA18) |	\
-		ATMEL_LCDC(PE, DATA19) | ATMEL_LCDC(PE, DATA20))
+		ATMEL_LCDC(PE, DATA12) | ATMEL_LCDC(PD, DATA13) |	\
+		ATMEL_LCDC(PD, DATA14) | ATMEL_LCDC(PD, DATA15) |	\
+		ATMEL_LCDC(PE, DATA18) | ATMEL_LCDC(PE, DATA19) |	\
+		ATMEL_LCDC(PE, DATA20) | ATMEL_LCDC(PE, DATA21) |	\
+		ATMEL_LCDC(PD, DATA22) | ATMEL_LCDC(PD, DATA23))
+
+#define ATMEL_LCDC_PRI_15B_DATA (					\
+		ATMEL_LCDC(PC, DATA3)  | ATMEL_LCDC(PC, DATA4)  |	\
+		ATMEL_LCDC(PC, DATA5)  | ATMEL_LCDC(PD, DATA6)  |	\
+		ATMEL_LCDC(PD, DATA7)  |				\
+		ATMEL_LCDC(PD, DATA11) | ATMEL_LCDC(PD, DATA12) |	\
+		ATMEL_LCDC(PD, DATA13) | ATMEL_LCDC(PD, DATA14) |	\
+		ATMEL_LCDC(PD, DATA15) |				\
+		ATMEL_LCDC(PD, DATA19) | ATMEL_LCDC(PD, DATA20) |	\
+		ATMEL_LCDC(PD, DATA21) | ATMEL_LCDC(PD, DATA22) |	\
+		ATMEL_LCDC(PD, DATA23))
+
+#define ATMEL_LCDC_ALT_15B_DATA	(					\
+		ATMEL_LCDC(PE, DATA3)  | ATMEL_LCDC(PE, DATA4)  |	\
+		ATMEL_LCDC(PC, DATA5)  | ATMEL_LCDC(PD, DATA6)  |	\
+		ATMEL_LCDC(PD, DATA7)  |				\
+		ATMEL_LCDC(PE, DATA11) | ATMEL_LCDC(PE, DATA12) |	\
+		ATMEL_LCDC(PD, DATA13) | ATMEL_LCDC(PD, DATA14) |	\
+		ATMEL_LCDC(PD, DATA15) |				\
+		ATMEL_LCDC(PE, DATA19) | ATMEL_LCDC(PE, DATA20) |	\
+		ATMEL_LCDC(PE, DATA21) | ATMEL_LCDC(PD, DATA22) |	\
+		ATMEL_LCDC(PD, DATA23))
 
 #define ATMEL_LCDC_PRI_CONTROL (					\
 		ATMEL_LCDC(PC, CC)   | ATMEL_LCDC(PC, DVAL) |		\
@@ -207,6 +231,10 @@
 
 #define ATMEL_LCDC_ALT_24BIT	(ATMEL_LCDC_CONTROL | ATMEL_LCDC_ALT_24B_DATA)
 
+#define ATMEL_LCDC_PRI_18BIT	(ATMEL_LCDC_CONTROL | ATMEL_LCDC_PRI_18B_DATA)
+
+#define ATMEL_LCDC_ALT_18BIT	(ATMEL_LCDC_CONTROL | ATMEL_LCDC_ALT_18B_DATA)
+
 #define ATMEL_LCDC_PRI_15BIT	(ATMEL_LCDC_CONTROL | ATMEL_LCDC_PRI_15B_DATA)
 
 #define ATMEL_LCDC_ALT_15BIT	(ATMEL_LCDC_CONTROL | ATMEL_LCDC_ALT_15B_DATA)
diff --git a/arch/avr32/mach-at32ap/include/mach/board.h b/arch/avr32/mach-at32ap/include/mach/board.h
index cff8e84f..0b81642 100644
--- a/arch/avr32/mach-at32ap/include/mach/board.h
+++ b/arch/avr32/mach-at32ap/include/mach/board.h
@@ -13,7 +13,7 @@
  * in this array is chip-dependent.
  */
 extern unsigned long at32_board_osc_rates[];
-  
+
 /*
  * This used to add essential system devices, but this is now done
  * automatically. Please don't use it in new board code.
@@ -26,12 +26,17 @@
 #define ATMEL_MAX_UART	4
 extern struct platform_device *atmel_default_console_device;
 
+/* Flags for selecting USART extra pins */
+#define	ATMEL_USART_RTS		0x01
+#define	ATMEL_USART_CTS		0x02
+#define	ATMEL_USART_CLK		0x03
+
 struct atmel_uart_data {
 	short		use_dma_tx;	/* use transmit DMA? */
 	short		use_dma_rx;	/* use receive DMA? */
 	void __iomem	*regs;		/* virtual base address, if any */
 };
-void at32_map_usart(unsigned int hw_id, unsigned int line);
+void at32_map_usart(unsigned int hw_id, unsigned int line, int flags);
 struct platform_device *at32_add_device_usart(unsigned int id);
 
 struct eth_platform_data {
@@ -88,16 +93,15 @@
 struct platform_device *
 at32_add_device_mci(unsigned int id, struct mci_platform_data *data);
 
-struct ac97c_platform_data {
-	unsigned short dma_rx_periph_id;
-	unsigned short dma_tx_periph_id;
-	unsigned short dma_controller_id;
-	int reset_pin;
-};
+struct ac97c_platform_data;
 struct platform_device *
-at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data);
+at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data,
+		      unsigned int flags);
 
-struct platform_device *at32_add_device_abdac(unsigned int id);
+struct atmel_abdac_pdata;
+struct platform_device *
+at32_add_device_abdac(unsigned int id, struct atmel_abdac_pdata *data);
+
 struct platform_device *at32_add_device_psif(unsigned int id);
 
 struct cf_platform_data {
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index 0c1f86e..3640cdc3 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -777,7 +777,7 @@
 	default n if BF54x
 	depends on !BF531
 	help
-	  If enabled, cacheline_anligned data is linked
+	  If enabled, cacheline_aligned data is linked
 	  into L1 data memory. (less latency)
 
 config SYSCALL_TAB_L1
@@ -957,7 +957,7 @@
 	  memory they do not own.  This comes at a performance penalty
 	  and is recommended only for debugging.
 
-comment "Asynchonous Memory Configuration"
+comment "Asynchronous Memory Configuration"
 
 menu "EBIU_AMGCTL Global Control"
 config C_AMCKEN
@@ -989,7 +989,7 @@
 	default n
 
 choice
-	prompt"Enable Asynchonous Memory Banks"
+	prompt "Enable Asynchronous Memory Banks"
 	default C_AMBEN_ALL
 
 config C_AMBEN
diff --git a/arch/blackfin/include/asm/ftrace.h b/arch/blackfin/include/asm/ftrace.h
new file mode 100644
index 0000000..40a8c17
--- /dev/null
+++ b/arch/blackfin/include/asm/ftrace.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index 3462245..7adac388 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -438,7 +438,7 @@
 	help
 	  Enables the DMA1 input channel for ser0 (ttyS0).
 	  If you do not enable DMA, an interrupt for each character will be
-	  used when receiveing data.
+	  used when receiving data.
 	  Normally you want to use DMA, unless you use the DMA channel for
 	  something else.
 
@@ -565,7 +565,7 @@
 	help
 	  Enables the DMA7 input channel for ser2 (ttyS2).
 	  If you do not enable DMA, an interrupt for each character will be
-	  used when receiveing data.
+	  used when receiving data.
 	  Normally you want to use DMA, unless you use the DMA channel for
 	  something else.
 
@@ -604,7 +604,7 @@
 	help
 	  Enables the DMA3 input channel for ser3 (ttyS3).
 	  If you do not enable DMA, an interrupt for each character will be
-	  used when receiveing data.
+	  used when receiving data.
 	  Normally you want to use DMA, unless you use the DMA channel for
 	  something else.
 
diff --git a/arch/cris/arch-v10/kernel/irq.c b/arch/cris/arch-v10/kernel/irq.c
index 65ed803..5d75f77 100644
--- a/arch/cris/arch-v10/kernel/irq.c
+++ b/arch/cris/arch-v10/kernel/irq.c
@@ -132,7 +132,7 @@
 {
 }
 
-static struct hw_interrupt_type crisv10_irq_type = {
+static struct irq_chip crisv10_irq_type = {
 	.typename =    "CRISv10",
 	.startup =     startup_crisv10_irq,
 	.shutdown =    shutdown_crisv10_irq,
diff --git a/arch/cris/arch-v32/Kconfig b/arch/cris/arch-v32/Kconfig
index 005ed2b..21bbd93 100644
--- a/arch/cris/arch-v32/Kconfig
+++ b/arch/cris/arch-v32/Kconfig
@@ -28,7 +28,7 @@
 	help
 	  Select this if you want one Ethernet LED group. This LED group
 	  can be used for one or more Ethernet interfaces. However, it is
-	  recomended that each Ethernet interface use a dedicated LED group.
+	  recommended that each Ethernet interface use a dedicated LED group.
 
 config	ETRAX_NBR_LED_GRP_TWO
 	bool "Use two LED groups"
diff --git a/arch/cris/arch-v32/boot/compressed/Makefile b/arch/cris/arch-v32/boot/compressed/Makefile
index 5a1b31c..e176b8b 100644
--- a/arch/cris/arch-v32/boot/compressed/Makefile
+++ b/arch/cris/arch-v32/boot/compressed/Makefile
@@ -2,9 +2,9 @@
 # arch/cris/arch-v32/boot/compressed/Makefile
 #
 
-asflags-y += -I $(srctree)/include/asm/mach/ -I $(srctree)/include/asm/arch
-ccflags-y += -O2 -I $(srctree)/include/asm/mach/ -I $(srctree)/include/asm/arch
-ldflags-y += -T $(srctree)/$(src)/decompress.lds
+asflags-y += -I$(srctree)/include/asm/mach/ -I$(srctree)/include/asm/arch
+ccflags-y += -O2 -I$(srctree)/include/asm/mach/ -I$(srctree)/include/asm/arch
+ldflags-y += -T$(srctree)/$(src)/decompress.lds
 OBJECTS = $(obj)/head.o $(obj)/misc.o
 OBJCOPYFLAGS = -O binary --remove-section=.bss
 
diff --git a/arch/cris/arch-v32/drivers/Kconfig b/arch/cris/arch-v32/drivers/Kconfig
index 7a64fce..b9e328e 100644
--- a/arch/cris/arch-v32/drivers/Kconfig
+++ b/arch/cris/arch-v32/drivers/Kconfig
@@ -342,7 +342,7 @@
 	help
 	  Enables the DMA9 input channel for ser4 (ttyS4).
 	  If you do not enable DMA, an interrupt for each character will be
-	  used when receiveing data.
+	  used when receiving data.
 	  Normally you want to use DMA, unless you use the DMA channel for
 	  something else.
 
diff --git a/arch/cris/arch-v32/kernel/irq.c b/arch/cris/arch-v32/kernel/irq.c
index 295131f..df3925c 100644
--- a/arch/cris/arch-v32/kernel/irq.c
+++ b/arch/cris/arch-v32/kernel/irq.c
@@ -333,7 +333,7 @@
 	spin_unlock_irqrestore(&irq_lock, flags);
 }
 
-static struct hw_interrupt_type crisv32_irq_type = {
+static struct irq_chip crisv32_irq_type = {
 	.typename =    "CRISv32",
 	.startup =     startup_crisv32_irq,
 	.shutdown =    shutdown_crisv32_irq,
diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c
index f59a973..d2a3ff8 100644
--- a/arch/cris/arch-v32/kernel/smp.c
+++ b/arch/cris/arch-v32/kernel/smp.c
@@ -97,9 +97,9 @@
 	SUPP_BANK_SEL(2);
 	SUPP_REG_WR(RW_MM_TLB_PGD, pgd);
 
-	cpu_set(0, cpu_online_map);
+	set_cpu_online(0, true);
 	cpu_set(0, phys_cpu_present_map);
-	cpu_set(0, cpu_possible_map);
+	set_cpu_possible(0, true);
 }
 
 void __init smp_cpus_done(unsigned int max_cpus)
@@ -231,7 +231,7 @@
 	cpumask_t cpu_mask;
 
 	spin_lock_irqsave(&tlbstate_lock, flags);
-	cpu_mask = (mm == FLUSH_ALL ? CPU_MASK_ALL : mm->cpu_vm_mask);
+	cpu_mask = (mm == FLUSH_ALL ? cpu_all_mask : *mm_cpumask(mm));
 	cpu_clear(smp_processor_id(), cpu_mask);
 	flush_mm = mm;
 	flush_vma = vma;
@@ -251,8 +251,8 @@
 	__flush_tlb_mm(mm);
 	flush_tlb_common(mm, FLUSH_ALL, 0);
 	/* No more mappings in other CPUs */
-	cpus_clear(mm->cpu_vm_mask);
-	cpu_set(smp_processor_id(), mm->cpu_vm_mask);
+	cpumask_clear(mm_cpumask(mm));
+	cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
 }
 
 void flush_tlb_page(struct vm_area_struct *vma,
diff --git a/arch/cris/arch-v32/mach-fs/Kconfig b/arch/cris/arch-v32/mach-fs/Kconfig
index f6d7447..774de82 100644
--- a/arch/cris/arch-v32/mach-fs/Kconfig
+++ b/arch/cris/arch-v32/mach-fs/Kconfig
@@ -59,7 +59,7 @@
 	depends on ETRAX_ARCH_V32
 	default "0"
 	help
-	  SDRAM configuration for group 1. The defult value is 0
+	  SDRAM configuration for group 1. The default value is 0
 	  because group 1 is not used in the default configuration,
 	  described in the help for SDRAM_GRP0_CONFIG.
 
diff --git a/arch/cris/arch-v32/mm/tlb.c b/arch/cris/arch-v32/mm/tlb.c
index 55ade36..6779bcb 100644
--- a/arch/cris/arch-v32/mm/tlb.c
+++ b/arch/cris/arch-v32/mm/tlb.c
@@ -185,7 +185,7 @@
 		/* Make sure there is a MMU context. */
 		spin_lock(&mmu_context_lock);
 		get_mmu_context(next);
-		cpu_set(cpu, next->cpu_vm_mask);
+		cpumask_set_cpu(cpu, mm_cpumask(next));
 		spin_unlock(&mmu_context_lock);
 
 		/*
diff --git a/arch/cris/include/asm/ftrace.h b/arch/cris/include/asm/ftrace.h
new file mode 100644
index 0000000..40a8c17
--- /dev/null
+++ b/arch/cris/include/asm/ftrace.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/cris/kernel/setup.c b/arch/cris/kernel/setup.c
index 04d48dd..b712f49 100644
--- a/arch/cris/kernel/setup.c
+++ b/arch/cris/kernel/setup.c
@@ -166,7 +166,7 @@
 
 static void *c_start(struct seq_file *m, loff_t *pos)
 {
-	return *pos < NR_CPUS ? (void *)(int)(*pos + 1): NULL;
+	return *pos < nr_cpu_ids ? (void *)(int)(*pos + 1) : NULL;
 }
 
 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
diff --git a/arch/cris/mm/init.c b/arch/cris/mm/init.c
index 2fdd212..514f46a 100644
--- a/arch/cris/mm/init.c
+++ b/arch/cris/mm/init.c
@@ -25,8 +25,7 @@
 	int codesize, reservedpages, datasize, initsize;
 	unsigned long tmp;
 
-	if(!mem_map)
-		BUG();
+	BUG_ON(!mem_map);
 
 	/* max/min_low_pfn was set by setup.c
 	 * now we just copy it to some other necessary places...
diff --git a/arch/h8300/include/asm/ftrace.h b/arch/h8300/include/asm/ftrace.h
new file mode 100644
index 0000000..40a8c17
--- /dev/null
+++ b/arch/h8300/include/asm/ftrace.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/h8300/kernel/timer/tpu.c b/arch/h8300/kernel/timer/tpu.c
index ad383ca..e7c6e61 100644
--- a/arch/h8300/kernel/timer/tpu.c
+++ b/arch/h8300/kernel/timer/tpu.c
@@ -67,7 +67,7 @@
 	.flags		= IRQF_DISABLED | IRQF_TIMER,
 };
 
-const static int __initdata divide_rate[] = {
+static const int __initdata divide_rate[] = {
 #if CONFIG_H8300_TPU_CH == 0
 	1,4,16,64,0,0,0,0,
 #elif (CONFIG_H8300_TPU_CH == 1) || (CONFIG_H8300_TPU_CH == 5)
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 153e727..294a3b1 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -22,6 +22,9 @@
 	select HAVE_OPROFILE
 	select HAVE_KPROBES
 	select HAVE_KRETPROBES
+	select HAVE_FTRACE_MCOUNT_RECORD
+	select HAVE_DYNAMIC_FTRACE if (!ITANIUM)
+	select HAVE_FUNCTION_TRACER
 	select HAVE_DMA_ATTRS
 	select HAVE_KVM
 	select HAVE_ARCH_TRACEHOOK
diff --git a/arch/ia64/include/asm/ftrace.h b/arch/ia64/include/asm/ftrace.h
new file mode 100644
index 0000000..d20db3c2
--- /dev/null
+++ b/arch/ia64/include/asm/ftrace.h
@@ -0,0 +1,28 @@
+#ifndef _ASM_IA64_FTRACE_H
+#define _ASM_IA64_FTRACE_H
+
+#ifdef CONFIG_FUNCTION_TRACER
+#define MCOUNT_INSN_SIZE        32 /* sizeof mcount call */
+
+#ifndef __ASSEMBLY__
+extern void _mcount(unsigned long pfs, unsigned long r1, unsigned long b0, unsigned long r0);
+#define mcount _mcount
+
+#include <asm/kprobes.h>
+/* In IA64, MCOUNT_ADDR is set in link time, so it's not a constant at compile time */
+#define MCOUNT_ADDR (((struct fnptr *)mcount)->ip)
+#define FTRACE_ADDR (((struct fnptr *)ftrace_caller)->ip)
+
+static inline unsigned long ftrace_call_adjust(unsigned long addr)
+{
+	/* second bundle, insn 2 */
+	return addr - 0x12;
+}
+
+struct dyn_arch_ftrace {
+};
+#endif
+
+#endif /* CONFIG_FUNCTION_TRACER */
+
+#endif /* _ASM_IA64_FTRACE_H */
diff --git a/arch/ia64/include/asm/hardirq.h b/arch/ia64/include/asm/hardirq.h
index 140e495..d514cd9 100644
--- a/arch/ia64/include/asm/hardirq.h
+++ b/arch/ia64/include/asm/hardirq.h
@@ -20,16 +20,6 @@
 
 #define local_softirq_pending()		(local_cpu_data->softirq_pending)
 
-#define HARDIRQ_BITS	14
-
-/*
- * The hardirq mask has to be large enough to have space for potentially all IRQ sources
- * in the system nesting on a single CPU:
- */
-#if (1 << HARDIRQ_BITS) < NR_IRQS
-# error HARDIRQ_BITS is too low!
-#endif
-
 extern void __iomem *ipi_base_addr;
 
 void ack_bad_irq(unsigned int irq);
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
index 5628e9a..6b7edca 100644
--- a/arch/ia64/kernel/Makefile
+++ b/arch/ia64/kernel/Makefile
@@ -2,6 +2,10 @@
 # Makefile for the linux kernel.
 #
 
+ifdef CONFIG_DYNAMIC_FTRACE
+CFLAGS_REMOVE_ftrace.o = -pg
+endif
+
 extra-y	:= head.o init_task.o vmlinux.lds
 
 obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o	\
@@ -28,6 +32,7 @@
 obj-$(CONFIG_CPU_FREQ)		+= cpufreq/
 obj-$(CONFIG_IA64_MCA_RECOVERY)	+= mca_recovery.o
 obj-$(CONFIG_KPROBES)		+= kprobes.o jprobes.o
+obj-$(CONFIG_DYNAMIC_FTRACE)	+= ftrace.o
 obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o crash.o
 obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
 obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR)	+= uncached.o
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index ccfdeee..8dc6966 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -47,6 +47,7 @@
 #include <asm/processor.h>
 #include <asm/thread_info.h>
 #include <asm/unistd.h>
+#include <asm/ftrace.h>
 
 #include "minstate.h"
 
@@ -1404,6 +1405,105 @@
 	br.ret.sptk.many rp
 END(unw_init_running)
 
+#ifdef CONFIG_FUNCTION_TRACER
+#ifdef CONFIG_DYNAMIC_FTRACE
+GLOBAL_ENTRY(_mcount)
+	br ftrace_stub
+END(_mcount)
+
+.here:
+	br.ret.sptk.many b0
+
+GLOBAL_ENTRY(ftrace_caller)
+	alloc out0 = ar.pfs, 8, 0, 4, 0
+	mov out3 = r0
+	;;
+	mov out2 = b0
+	add r3 = 0x20, r3
+	mov out1 = r1;
+	br.call.sptk.many b0 = ftrace_patch_gp
+	//this might be called from module, so we must patch gp
+ftrace_patch_gp:
+	movl gp=__gp
+	mov b0 = r3
+	;;
+.global ftrace_call;
+ftrace_call:
+{
+	.mlx
+	nop.m 0x0
+	movl r3 = .here;;
+}
+	alloc loc0 = ar.pfs, 4, 4, 2, 0
+	;;
+	mov loc1 = b0
+	mov out0 = b0
+	mov loc2 = r8
+	mov loc3 = r15
+	;;
+	adds out0 = -MCOUNT_INSN_SIZE, out0
+	mov out1 = in2
+	mov b6 = r3
+
+	br.call.sptk.many b0 = b6
+	;;
+	mov ar.pfs = loc0
+	mov b0 = loc1
+	mov r8 = loc2
+	mov r15 = loc3
+	br ftrace_stub
+	;;
+END(ftrace_caller)
+
+#else
+GLOBAL_ENTRY(_mcount)
+	movl r2 = ftrace_stub
+	movl r3 = ftrace_trace_function;;
+	ld8 r3 = [r3];;
+	ld8 r3 = [r3];;
+	cmp.eq p7,p0 = r2, r3
+(p7)	br.sptk.many ftrace_stub
+	;;
+
+	alloc loc0 = ar.pfs, 4, 4, 2, 0
+	;;
+	mov loc1 = b0
+	mov out0 = b0
+	mov loc2 = r8
+	mov loc3 = r15
+	;;
+	adds out0 = -MCOUNT_INSN_SIZE, out0
+	mov out1 = in2
+	mov b6 = r3
+
+	br.call.sptk.many b0 = b6
+	;;
+	mov ar.pfs = loc0
+	mov b0 = loc1
+	mov r8 = loc2
+	mov r15 = loc3
+	br ftrace_stub
+	;;
+END(_mcount)
+#endif
+
+GLOBAL_ENTRY(ftrace_stub)
+	mov r3 = b0
+	movl r2 = _mcount_ret_helper
+	;;
+	mov b6 = r2
+	mov b7 = r3
+	br.ret.sptk.many b6
+
+_mcount_ret_helper:
+	mov b0 = r42
+	mov r1 = r41
+	mov ar.pfs = r40
+	br b7
+END(ftrace_stub)
+
+#endif /* CONFIG_FUNCTION_TRACER */
+
 	.rodata
 	.align 8
 	.globl sys_call_table
diff --git a/arch/ia64/kernel/ftrace.c b/arch/ia64/kernel/ftrace.c
new file mode 100644
index 0000000..7fc8c96
--- /dev/null
+++ b/arch/ia64/kernel/ftrace.c
@@ -0,0 +1,206 @@
+/*
+ * Dynamic function tracing support.
+ *
+ * Copyright (C) 2008 Shaohua Li <shaohua.li@intel.com>
+ *
+ * For licencing details, see COPYING.
+ *
+ * Defines low-level handling of mcount calls when the kernel
+ * is compiled with the -pg flag. When using dynamic ftrace, the
+ * mcount call-sites get patched lazily with NOP till they are
+ * enabled. All code mutation routines here take effect atomically.
+ */
+
+#include <linux/uaccess.h>
+#include <linux/ftrace.h>
+
+#include <asm/cacheflush.h>
+#include <asm/patch.h>
+
+/* In IA64, each function will be added below two bundles with -pg option */
+static unsigned char __attribute__((aligned(8)))
+ftrace_orig_code[MCOUNT_INSN_SIZE] = {
+	0x02, 0x40, 0x31, 0x10, 0x80, 0x05, /* alloc r40=ar.pfs,12,8,0 */
+	0xb0, 0x02, 0x00, 0x00, 0x42, 0x40, /* mov r43=r0;; */
+	0x05, 0x00, 0xc4, 0x00,             /* mov r42=b0 */
+	0x11, 0x48, 0x01, 0x02, 0x00, 0x21, /* mov r41=r1 */
+	0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
+	0x08, 0x00, 0x00, 0x50              /* br.call.sptk.many b0 = _mcount;; */
+};
+
+struct ftrace_orig_insn {
+	u64 dummy1, dummy2, dummy3;
+	u64 dummy4:64-41+13;
+	u64 imm20:20;
+	u64 dummy5:3;
+	u64 sign:1;
+	u64 dummy6:4;
+};
+
+/* mcount stub will be converted below for nop */
+static unsigned char ftrace_nop_code[MCOUNT_INSN_SIZE] = {
+	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0x0 */
+	0x30, 0x00, 0x00, 0x60, 0x00, 0x00, /* mov r3=ip */
+	0x00, 0x00, 0x04, 0x00,             /* nop.i 0x0 */
+	0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0x0 */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* nop.x 0x0;; */
+	0x00, 0x00, 0x04, 0x00
+};
+
+static unsigned char *ftrace_nop_replace(void)
+{
+	return ftrace_nop_code;
+}
+
+/*
+ * mcount stub will be converted below for call
+ * Note: Just the last instruction is changed against nop
+ * */
+static unsigned char __attribute__((aligned(8)))
+ftrace_call_code[MCOUNT_INSN_SIZE] = {
+	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0x0 */
+	0x30, 0x00, 0x00, 0x60, 0x00, 0x00, /* mov r3=ip */
+	0x00, 0x00, 0x04, 0x00,             /* nop.i 0x0 */
+	0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0x0 */
+	0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, /* brl.many .;;*/
+	0xf8, 0xff, 0xff, 0xc8
+};
+
+struct ftrace_call_insn {
+	u64 dummy1, dummy2;
+	u64 dummy3:48;
+	u64 imm39_l:16;
+	u64 imm39_h:23;
+	u64 dummy4:13;
+	u64 imm20:20;
+	u64 dummy5:3;
+	u64 i:1;
+	u64 dummy6:4;
+};
+
+static unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr)
+{
+	struct ftrace_call_insn *code = (void *)ftrace_call_code;
+	unsigned long offset = addr - (ip + 0x10);
+
+	code->imm39_l = offset >> 24;
+	code->imm39_h = offset >> 40;
+	code->imm20 = offset >> 4;
+	code->i = offset >> 63;
+	return ftrace_call_code;
+}
+
+static int
+ftrace_modify_code(unsigned long ip, unsigned char *old_code,
+		   unsigned char *new_code, int do_check)
+{
+	unsigned char replaced[MCOUNT_INSN_SIZE];
+
+	/*
+	 * Note: Due to modules and __init, code can
+	 *  disappear and change, we need to protect against faulting
+	 *  as well as code changing. We do this by using the
+	 *  probe_kernel_* functions.
+	 *
+	 * No real locking needed, this code is run through
+	 * kstop_machine, or before SMP starts.
+	 */
+
+	if (!do_check)
+		goto skip_check;
+
+	/* read the text we want to modify */
+	if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE))
+		return -EFAULT;
+
+	/* Make sure it is what we expect it to be */
+	if (memcmp(replaced, old_code, MCOUNT_INSN_SIZE) != 0)
+		return -EINVAL;
+
+skip_check:
+	/* replace the text with the new text */
+	if (probe_kernel_write(((void *)ip), new_code, MCOUNT_INSN_SIZE))
+		return -EPERM;
+	flush_icache_range(ip, ip + MCOUNT_INSN_SIZE);
+
+	return 0;
+}
+
+static int ftrace_make_nop_check(struct dyn_ftrace *rec, unsigned long addr)
+{
+	unsigned char __attribute__((aligned(8))) replaced[MCOUNT_INSN_SIZE];
+	unsigned long ip = rec->ip;
+
+	if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE))
+		return -EFAULT;
+	if (rec->flags & FTRACE_FL_CONVERTED) {
+		struct ftrace_call_insn *call_insn, *tmp_call;
+
+		call_insn = (void *)ftrace_call_code;
+		tmp_call = (void *)replaced;
+		call_insn->imm39_l = tmp_call->imm39_l;
+		call_insn->imm39_h = tmp_call->imm39_h;
+		call_insn->imm20 = tmp_call->imm20;
+		call_insn->i = tmp_call->i;
+		if (memcmp(replaced, ftrace_call_code, MCOUNT_INSN_SIZE) != 0)
+			return -EINVAL;
+		return 0;
+	} else {
+		struct ftrace_orig_insn *call_insn, *tmp_call;
+
+		call_insn = (void *)ftrace_orig_code;
+		tmp_call = (void *)replaced;
+		call_insn->sign = tmp_call->sign;
+		call_insn->imm20 = tmp_call->imm20;
+		if (memcmp(replaced, ftrace_orig_code, MCOUNT_INSN_SIZE) != 0)
+			return -EINVAL;
+		return 0;
+	}
+}
+
+int ftrace_make_nop(struct module *mod,
+		    struct dyn_ftrace *rec, unsigned long addr)
+{
+	int ret;
+	char *new;
+
+	ret = ftrace_make_nop_check(rec, addr);
+	if (ret)
+		return ret;
+	new = ftrace_nop_replace();
+	return ftrace_modify_code(rec->ip, NULL, new, 0);
+}
+
+int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+{
+	unsigned long ip = rec->ip;
+	unsigned char *old, *new;
+
+	old=  ftrace_nop_replace();
+	new = ftrace_call_replace(ip, addr);
+	return ftrace_modify_code(ip, old, new, 1);
+}
+
+/* in IA64, _mcount can't directly call ftrace_stub. Only jump is ok */
+int ftrace_update_ftrace_func(ftrace_func_t func)
+{
+	unsigned long ip;
+	unsigned long addr = ((struct fnptr *)ftrace_call)->ip;
+
+	if (func == ftrace_stub)
+		return 0;
+	ip = ((struct fnptr *)func)->ip;
+
+	ia64_patch_imm64(addr + 2, ip);
+
+	flush_icache_range(addr, addr + 16);
+	return 0;
+}
+
+/* run from kstop_machine */
+int __init ftrace_dyn_arch_init(void *data)
+{
+	*(unsigned long *)data = 0;
+
+	return 0;
+}
diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c
index 6da1f20..2d31186 100644
--- a/arch/ia64/kernel/ia64_ksyms.c
+++ b/arch/ia64/kernel/ia64_ksyms.c
@@ -112,3 +112,9 @@
 #endif
 extern char ia64_ivt[];
 EXPORT_SYMBOL(ia64_ivt);
+
+#include <asm/ftrace.h>
+#ifdef CONFIG_FUNCTION_TRACER
+/* mcount is defined in assembly */
+EXPORT_SYMBOL(_mcount);
+#endif
diff --git a/arch/m68k/include/asm/bootinfo.h b/arch/m68k/include/asm/bootinfo.h
index fedf3e3..fb8a06b 100644
--- a/arch/m68k/include/asm/bootinfo.h
+++ b/arch/m68k/include/asm/bootinfo.h
@@ -1,5 +1,378 @@
-#ifdef __uClinux__
-#include "bootinfo_no.h"
-#else
-#include "bootinfo_mm.h"
+/*
+** asm/bootinfo.h -- Definition of the Linux/m68k boot information structure
+**
+** Copyright 1992 by Greg Harp
+**
+** 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.
+**
+** Created 09/29/92 by Greg Harp
+**
+** 5/2/94 Roman Hodek:
+**   Added bi_atari part of the machine dependent union bi_un; for now it
+**   contains just a model field to distinguish between TT and Falcon.
+** 26/7/96 Roman Zippel:
+**   Renamed to setup.h; added some useful macros to allow gcc some
+**   optimizations if possible.
+** 5/10/96 Geert Uytterhoeven:
+**   Redesign of the boot information structure; renamed to bootinfo.h again
+** 27/11/96 Geert Uytterhoeven:
+**   Backwards compatibility with bootinfo interface version 1.0
+*/
+
+#ifndef _M68K_BOOTINFO_H
+#define _M68K_BOOTINFO_H
+
+
+    /*
+     *  Bootinfo definitions
+     *
+     *  This is an easily parsable and extendable structure containing all
+     *  information to be passed from the bootstrap to the kernel.
+     *
+     *  This way I hope to keep all future changes back/forewards compatible.
+     *  Thus, keep your fingers crossed...
+     *
+     *  This structure is copied right after the kernel bss by the bootstrap
+     *  routine.
+     */
+
+#ifndef __ASSEMBLY__
+
+struct bi_record {
+    unsigned short tag;			/* tag ID */
+    unsigned short size;		/* size of record (in bytes) */
+    unsigned long data[0];		/* data */
+};
+
+#endif /* __ASSEMBLY__ */
+
+
+    /*
+     *  Tag Definitions
+     *
+     *  Machine independent tags start counting from 0x0000
+     *  Machine dependent tags start counting from 0x8000
+     */
+
+#define BI_LAST			0x0000	/* last record (sentinel) */
+#define BI_MACHTYPE		0x0001	/* machine type (u_long) */
+#define BI_CPUTYPE		0x0002	/* cpu type (u_long) */
+#define BI_FPUTYPE		0x0003	/* fpu type (u_long) */
+#define BI_MMUTYPE		0x0004	/* mmu type (u_long) */
+#define BI_MEMCHUNK		0x0005	/* memory chunk address and size */
+					/* (struct mem_info) */
+#define BI_RAMDISK		0x0006	/* ramdisk address and size */
+					/* (struct mem_info) */
+#define BI_COMMAND_LINE		0x0007	/* kernel command line parameters */
+					/* (string) */
+
+    /*
+     *  Amiga-specific tags
+     */
+
+#define BI_AMIGA_MODEL		0x8000	/* model (u_long) */
+#define BI_AMIGA_AUTOCON	0x8001	/* AutoConfig device */
+					/* (struct ConfigDev) */
+#define BI_AMIGA_CHIP_SIZE	0x8002	/* size of Chip RAM (u_long) */
+#define BI_AMIGA_VBLANK		0x8003	/* VBLANK frequency (u_char) */
+#define BI_AMIGA_PSFREQ		0x8004	/* power supply frequency (u_char) */
+#define BI_AMIGA_ECLOCK		0x8005	/* EClock frequency (u_long) */
+#define BI_AMIGA_CHIPSET	0x8006	/* native chipset present (u_long) */
+#define BI_AMIGA_SERPER		0x8007	/* serial port period (u_short) */
+
+    /*
+     *  Atari-specific tags
+     */
+
+#define BI_ATARI_MCH_COOKIE	0x8000	/* _MCH cookie from TOS (u_long) */
+#define BI_ATARI_MCH_TYPE	0x8001	/* special machine type (u_long) */
+					/* (values are ATARI_MACH_* defines */
+
+/* mch_cookie values (upper word) */
+#define ATARI_MCH_ST		0
+#define ATARI_MCH_STE		1
+#define ATARI_MCH_TT		2
+#define ATARI_MCH_FALCON	3
+
+/* mch_type values */
+#define ATARI_MACH_NORMAL	0	/* no special machine type */
+#define ATARI_MACH_MEDUSA	1	/* Medusa 040 */
+#define ATARI_MACH_HADES	2	/* Hades 040 or 060 */
+#define ATARI_MACH_AB40		3	/* Afterburner040 on Falcon */
+
+    /*
+     *  VME-specific tags
+     */
+
+#define BI_VME_TYPE		0x8000	/* VME sub-architecture (u_long) */
+#define BI_VME_BRDINFO		0x8001	/* VME board information (struct) */
+
+/* BI_VME_TYPE codes */
+#define	VME_TYPE_TP34V		0x0034	/* Tadpole TP34V */
+#define VME_TYPE_MVME147	0x0147	/* Motorola MVME147 */
+#define VME_TYPE_MVME162	0x0162	/* Motorola MVME162 */
+#define VME_TYPE_MVME166	0x0166	/* Motorola MVME166 */
+#define VME_TYPE_MVME167	0x0167	/* Motorola MVME167 */
+#define VME_TYPE_MVME172	0x0172	/* Motorola MVME172 */
+#define VME_TYPE_MVME177	0x0177	/* Motorola MVME177 */
+#define VME_TYPE_BVME4000	0x4000	/* BVM Ltd. BVME4000 */
+#define VME_TYPE_BVME6000	0x6000	/* BVM Ltd. BVME6000 */
+
+/* BI_VME_BRDINFO is a 32 byte struct as returned by the Bug code on
+ * Motorola VME boards.  Contains board number, Bug version, board
+ * configuration options, etc.  See include/asm/mvme16xhw.h for details.
+ */
+
+
+    /*
+     *  Macintosh-specific tags (all u_long)
+     */
+
+#define BI_MAC_MODEL		0x8000	/* Mac Gestalt ID (model type) */
+#define BI_MAC_VADDR		0x8001	/* Mac video base address */
+#define BI_MAC_VDEPTH		0x8002	/* Mac video depth */
+#define BI_MAC_VROW		0x8003	/* Mac video rowbytes */
+#define BI_MAC_VDIM		0x8004	/* Mac video dimensions */
+#define BI_MAC_VLOGICAL		0x8005	/* Mac video logical base */
+#define BI_MAC_SCCBASE		0x8006	/* Mac SCC base address */
+#define BI_MAC_BTIME		0x8007	/* Mac boot time */
+#define BI_MAC_GMTBIAS		0x8008	/* Mac GMT timezone offset */
+#define BI_MAC_MEMSIZE		0x8009	/* Mac RAM size (sanity check) */
+#define BI_MAC_CPUID		0x800a	/* Mac CPU type (sanity check) */
+#define BI_MAC_ROMBASE		0x800b	/* Mac system ROM base address */
+
+    /*
+     *  Macintosh hardware profile data - unused, see macintosh.h for
+     *  resonable type values
+     */
+
+#define BI_MAC_VIA1BASE		0x8010	/* Mac VIA1 base address (always present) */
+#define BI_MAC_VIA2BASE		0x8011	/* Mac VIA2 base address (type varies) */
+#define BI_MAC_VIA2TYPE		0x8012	/* Mac VIA2 type (VIA, RBV, OSS) */
+#define BI_MAC_ADBTYPE		0x8013	/* Mac ADB interface type */
+#define BI_MAC_ASCBASE		0x8014	/* Mac Apple Sound Chip base address */
+#define BI_MAC_SCSI5380		0x8015	/* Mac NCR 5380 SCSI (base address, multi) */
+#define BI_MAC_SCSIDMA		0x8016	/* Mac SCSI DMA (base address) */
+#define BI_MAC_SCSI5396		0x8017	/* Mac NCR 53C96 SCSI (base address, multi) */
+#define BI_MAC_IDETYPE		0x8018	/* Mac IDE interface type */
+#define BI_MAC_IDEBASE		0x8019	/* Mac IDE interface base address */
+#define BI_MAC_NUBUS		0x801a	/* Mac Nubus type (none, regular, pseudo) */
+#define BI_MAC_SLOTMASK		0x801b	/* Mac Nubus slots present */
+#define BI_MAC_SCCTYPE		0x801c	/* Mac SCC serial type (normal, IOP) */
+#define BI_MAC_ETHTYPE		0x801d	/* Mac builtin ethernet type (Sonic, MACE */
+#define BI_MAC_ETHBASE		0x801e	/* Mac builtin ethernet base address */
+#define BI_MAC_PMU		0x801f	/* Mac power management / poweroff hardware */
+#define BI_MAC_IOP_SWIM		0x8020	/* Mac SWIM floppy IOP */
+#define BI_MAC_IOP_ADB		0x8021	/* Mac ADB IOP */
+
+    /*
+     * Mac: compatibility with old booter data format (temporarily)
+     * Fields unused with the new bootinfo can be deleted now; instead of
+     * adding new fields the struct might be splitted into a hardware address
+     * part and a hardware type part
+     */
+
+#ifndef __ASSEMBLY__
+
+struct mac_booter_data
+{
+	unsigned long videoaddr;
+	unsigned long videorow;
+	unsigned long videodepth;
+	unsigned long dimensions;
+	unsigned long args;
+	unsigned long boottime;
+	unsigned long gmtbias;
+	unsigned long bootver;
+	unsigned long videological;
+	unsigned long sccbase;
+	unsigned long id;
+	unsigned long memsize;
+	unsigned long serialmf;
+	unsigned long serialhsk;
+	unsigned long serialgpi;
+	unsigned long printmf;
+	unsigned long printhsk;
+	unsigned long printgpi;
+	unsigned long cpuid;
+	unsigned long rombase;
+	unsigned long adbdelay;
+	unsigned long timedbra;
+};
+
+extern struct mac_booter_data
+	mac_bi_data;
+
 #endif
+
+    /*
+     *  Apollo-specific tags
+     */
+
+#define BI_APOLLO_MODEL         0x8000  /* model (u_long) */
+
+    /*
+     *  HP300-specific tags
+     */
+
+#define BI_HP300_MODEL		0x8000	/* model (u_long) */
+#define BI_HP300_UART_SCODE	0x8001	/* UART select code (u_long) */
+#define BI_HP300_UART_ADDR	0x8002	/* phys. addr of UART (u_long) */
+
+    /*
+     * Stuff for bootinfo interface versioning
+     *
+     * At the start of kernel code, a 'struct bootversion' is located.
+     * bootstrap checks for a matching version of the interface before booting
+     * a kernel, to avoid user confusion if kernel and bootstrap don't work
+     * together :-)
+     *
+     * If incompatible changes are made to the bootinfo interface, the major
+     * number below should be stepped (and the minor reset to 0) for the
+     * appropriate machine. If a change is backward-compatible, the minor
+     * should be stepped. "Backwards-compatible" means that booting will work,
+     * but certain features may not.
+     */
+
+#define BOOTINFOV_MAGIC			0x4249561A	/* 'BIV^Z' */
+#define MK_BI_VERSION(major,minor)	(((major)<<16)+(minor))
+#define BI_VERSION_MAJOR(v)		(((v) >> 16) & 0xffff)
+#define BI_VERSION_MINOR(v)		((v) & 0xffff)
+
+#ifndef __ASSEMBLY__
+
+struct bootversion {
+    unsigned short branch;
+    unsigned long magic;
+    struct {
+	unsigned long machtype;
+	unsigned long version;
+    } machversions[0];
+};
+
+#endif /* __ASSEMBLY__ */
+
+#define AMIGA_BOOTI_VERSION    MK_BI_VERSION( 2, 0 )
+#define ATARI_BOOTI_VERSION    MK_BI_VERSION( 2, 1 )
+#define MAC_BOOTI_VERSION      MK_BI_VERSION( 2, 0 )
+#define MVME147_BOOTI_VERSION  MK_BI_VERSION( 2, 0 )
+#define MVME16x_BOOTI_VERSION  MK_BI_VERSION( 2, 0 )
+#define BVME6000_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
+#define Q40_BOOTI_VERSION      MK_BI_VERSION( 2, 0 )
+#define HP300_BOOTI_VERSION    MK_BI_VERSION( 2, 0 )
+
+#ifdef BOOTINFO_COMPAT_1_0
+
+    /*
+     *  Backwards compatibility with bootinfo interface version 1.0
+     */
+
+#define COMPAT_AMIGA_BOOTI_VERSION    MK_BI_VERSION( 1, 0 )
+#define COMPAT_ATARI_BOOTI_VERSION    MK_BI_VERSION( 1, 0 )
+#define COMPAT_MAC_BOOTI_VERSION      MK_BI_VERSION( 1, 0 )
+
+#include <linux/zorro.h>
+
+#define COMPAT_NUM_AUTO    16
+
+struct compat_bi_Amiga {
+    int model;
+    int num_autocon;
+    struct ConfigDev autocon[COMPAT_NUM_AUTO];
+    unsigned long chip_size;
+    unsigned char vblank;
+    unsigned char psfreq;
+    unsigned long eclock;
+    unsigned long chipset;
+    unsigned long hw_present;
+};
+
+struct compat_bi_Atari {
+    unsigned long hw_present;
+    unsigned long mch_cookie;
+};
+
+#ifndef __ASSEMBLY__
+
+struct compat_bi_Macintosh
+{
+	unsigned long videoaddr;
+	unsigned long videorow;
+	unsigned long videodepth;
+	unsigned long dimensions;
+	unsigned long args;
+	unsigned long boottime;
+	unsigned long gmtbias;
+	unsigned long bootver;
+	unsigned long videological;
+	unsigned long sccbase;
+	unsigned long id;
+	unsigned long memsize;
+	unsigned long serialmf;
+	unsigned long serialhsk;
+	unsigned long serialgpi;
+	unsigned long printmf;
+	unsigned long printhsk;
+	unsigned long printgpi;
+	unsigned long cpuid;
+	unsigned long rombase;
+	unsigned long adbdelay;
+	unsigned long timedbra;
+};
+
+#endif
+
+struct compat_mem_info {
+    unsigned long addr;
+    unsigned long size;
+};
+
+#define COMPAT_NUM_MEMINFO  4
+
+#define COMPAT_CPUB_68020 0
+#define COMPAT_CPUB_68030 1
+#define COMPAT_CPUB_68040 2
+#define COMPAT_CPUB_68060 3
+#define COMPAT_FPUB_68881 5
+#define COMPAT_FPUB_68882 6
+#define COMPAT_FPUB_68040 7
+#define COMPAT_FPUB_68060 8
+
+#define COMPAT_CPU_68020    (1<<COMPAT_CPUB_68020)
+#define COMPAT_CPU_68030    (1<<COMPAT_CPUB_68030)
+#define COMPAT_CPU_68040    (1<<COMPAT_CPUB_68040)
+#define COMPAT_CPU_68060    (1<<COMPAT_CPUB_68060)
+#define COMPAT_CPU_MASK     (31)
+#define COMPAT_FPU_68881    (1<<COMPAT_FPUB_68881)
+#define COMPAT_FPU_68882    (1<<COMPAT_FPUB_68882)
+#define COMPAT_FPU_68040    (1<<COMPAT_FPUB_68040)
+#define COMPAT_FPU_68060    (1<<COMPAT_FPUB_68060)
+#define COMPAT_FPU_MASK     (0xfe0)
+
+#define COMPAT_CL_SIZE      (256)
+
+struct compat_bootinfo {
+    unsigned long machtype;
+    unsigned long cputype;
+    struct compat_mem_info memory[COMPAT_NUM_MEMINFO];
+    int num_memory;
+    unsigned long ramdisk_size;
+    unsigned long ramdisk_addr;
+    char command_line[COMPAT_CL_SIZE];
+    union {
+	struct compat_bi_Amiga     bi_ami;
+	struct compat_bi_Atari     bi_ata;
+	struct compat_bi_Macintosh bi_mac;
+    } bi_un;
+};
+
+#define bi_amiga	bi_un.bi_ami
+#define bi_atari	bi_un.bi_ata
+#define bi_mac		bi_un.bi_mac
+
+#endif /* BOOTINFO_COMPAT_1_0 */
+
+
+#endif /* _M68K_BOOTINFO_H */
diff --git a/arch/m68k/include/asm/bootinfo_mm.h b/arch/m68k/include/asm/bootinfo_mm.h
deleted file mode 100644
index fb8a06b..0000000
--- a/arch/m68k/include/asm/bootinfo_mm.h
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
-** asm/bootinfo.h -- Definition of the Linux/m68k boot information structure
-**
-** Copyright 1992 by Greg Harp
-**
-** 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.
-**
-** Created 09/29/92 by Greg Harp
-**
-** 5/2/94 Roman Hodek:
-**   Added bi_atari part of the machine dependent union bi_un; for now it
-**   contains just a model field to distinguish between TT and Falcon.
-** 26/7/96 Roman Zippel:
-**   Renamed to setup.h; added some useful macros to allow gcc some
-**   optimizations if possible.
-** 5/10/96 Geert Uytterhoeven:
-**   Redesign of the boot information structure; renamed to bootinfo.h again
-** 27/11/96 Geert Uytterhoeven:
-**   Backwards compatibility with bootinfo interface version 1.0
-*/
-
-#ifndef _M68K_BOOTINFO_H
-#define _M68K_BOOTINFO_H
-
-
-    /*
-     *  Bootinfo definitions
-     *
-     *  This is an easily parsable and extendable structure containing all
-     *  information to be passed from the bootstrap to the kernel.
-     *
-     *  This way I hope to keep all future changes back/forewards compatible.
-     *  Thus, keep your fingers crossed...
-     *
-     *  This structure is copied right after the kernel bss by the bootstrap
-     *  routine.
-     */
-
-#ifndef __ASSEMBLY__
-
-struct bi_record {
-    unsigned short tag;			/* tag ID */
-    unsigned short size;		/* size of record (in bytes) */
-    unsigned long data[0];		/* data */
-};
-
-#endif /* __ASSEMBLY__ */
-
-
-    /*
-     *  Tag Definitions
-     *
-     *  Machine independent tags start counting from 0x0000
-     *  Machine dependent tags start counting from 0x8000
-     */
-
-#define BI_LAST			0x0000	/* last record (sentinel) */
-#define BI_MACHTYPE		0x0001	/* machine type (u_long) */
-#define BI_CPUTYPE		0x0002	/* cpu type (u_long) */
-#define BI_FPUTYPE		0x0003	/* fpu type (u_long) */
-#define BI_MMUTYPE		0x0004	/* mmu type (u_long) */
-#define BI_MEMCHUNK		0x0005	/* memory chunk address and size */
-					/* (struct mem_info) */
-#define BI_RAMDISK		0x0006	/* ramdisk address and size */
-					/* (struct mem_info) */
-#define BI_COMMAND_LINE		0x0007	/* kernel command line parameters */
-					/* (string) */
-
-    /*
-     *  Amiga-specific tags
-     */
-
-#define BI_AMIGA_MODEL		0x8000	/* model (u_long) */
-#define BI_AMIGA_AUTOCON	0x8001	/* AutoConfig device */
-					/* (struct ConfigDev) */
-#define BI_AMIGA_CHIP_SIZE	0x8002	/* size of Chip RAM (u_long) */
-#define BI_AMIGA_VBLANK		0x8003	/* VBLANK frequency (u_char) */
-#define BI_AMIGA_PSFREQ		0x8004	/* power supply frequency (u_char) */
-#define BI_AMIGA_ECLOCK		0x8005	/* EClock frequency (u_long) */
-#define BI_AMIGA_CHIPSET	0x8006	/* native chipset present (u_long) */
-#define BI_AMIGA_SERPER		0x8007	/* serial port period (u_short) */
-
-    /*
-     *  Atari-specific tags
-     */
-
-#define BI_ATARI_MCH_COOKIE	0x8000	/* _MCH cookie from TOS (u_long) */
-#define BI_ATARI_MCH_TYPE	0x8001	/* special machine type (u_long) */
-					/* (values are ATARI_MACH_* defines */
-
-/* mch_cookie values (upper word) */
-#define ATARI_MCH_ST		0
-#define ATARI_MCH_STE		1
-#define ATARI_MCH_TT		2
-#define ATARI_MCH_FALCON	3
-
-/* mch_type values */
-#define ATARI_MACH_NORMAL	0	/* no special machine type */
-#define ATARI_MACH_MEDUSA	1	/* Medusa 040 */
-#define ATARI_MACH_HADES	2	/* Hades 040 or 060 */
-#define ATARI_MACH_AB40		3	/* Afterburner040 on Falcon */
-
-    /*
-     *  VME-specific tags
-     */
-
-#define BI_VME_TYPE		0x8000	/* VME sub-architecture (u_long) */
-#define BI_VME_BRDINFO		0x8001	/* VME board information (struct) */
-
-/* BI_VME_TYPE codes */
-#define	VME_TYPE_TP34V		0x0034	/* Tadpole TP34V */
-#define VME_TYPE_MVME147	0x0147	/* Motorola MVME147 */
-#define VME_TYPE_MVME162	0x0162	/* Motorola MVME162 */
-#define VME_TYPE_MVME166	0x0166	/* Motorola MVME166 */
-#define VME_TYPE_MVME167	0x0167	/* Motorola MVME167 */
-#define VME_TYPE_MVME172	0x0172	/* Motorola MVME172 */
-#define VME_TYPE_MVME177	0x0177	/* Motorola MVME177 */
-#define VME_TYPE_BVME4000	0x4000	/* BVM Ltd. BVME4000 */
-#define VME_TYPE_BVME6000	0x6000	/* BVM Ltd. BVME6000 */
-
-/* BI_VME_BRDINFO is a 32 byte struct as returned by the Bug code on
- * Motorola VME boards.  Contains board number, Bug version, board
- * configuration options, etc.  See include/asm/mvme16xhw.h for details.
- */
-
-
-    /*
-     *  Macintosh-specific tags (all u_long)
-     */
-
-#define BI_MAC_MODEL		0x8000	/* Mac Gestalt ID (model type) */
-#define BI_MAC_VADDR		0x8001	/* Mac video base address */
-#define BI_MAC_VDEPTH		0x8002	/* Mac video depth */
-#define BI_MAC_VROW		0x8003	/* Mac video rowbytes */
-#define BI_MAC_VDIM		0x8004	/* Mac video dimensions */
-#define BI_MAC_VLOGICAL		0x8005	/* Mac video logical base */
-#define BI_MAC_SCCBASE		0x8006	/* Mac SCC base address */
-#define BI_MAC_BTIME		0x8007	/* Mac boot time */
-#define BI_MAC_GMTBIAS		0x8008	/* Mac GMT timezone offset */
-#define BI_MAC_MEMSIZE		0x8009	/* Mac RAM size (sanity check) */
-#define BI_MAC_CPUID		0x800a	/* Mac CPU type (sanity check) */
-#define BI_MAC_ROMBASE		0x800b	/* Mac system ROM base address */
-
-    /*
-     *  Macintosh hardware profile data - unused, see macintosh.h for
-     *  resonable type values
-     */
-
-#define BI_MAC_VIA1BASE		0x8010	/* Mac VIA1 base address (always present) */
-#define BI_MAC_VIA2BASE		0x8011	/* Mac VIA2 base address (type varies) */
-#define BI_MAC_VIA2TYPE		0x8012	/* Mac VIA2 type (VIA, RBV, OSS) */
-#define BI_MAC_ADBTYPE		0x8013	/* Mac ADB interface type */
-#define BI_MAC_ASCBASE		0x8014	/* Mac Apple Sound Chip base address */
-#define BI_MAC_SCSI5380		0x8015	/* Mac NCR 5380 SCSI (base address, multi) */
-#define BI_MAC_SCSIDMA		0x8016	/* Mac SCSI DMA (base address) */
-#define BI_MAC_SCSI5396		0x8017	/* Mac NCR 53C96 SCSI (base address, multi) */
-#define BI_MAC_IDETYPE		0x8018	/* Mac IDE interface type */
-#define BI_MAC_IDEBASE		0x8019	/* Mac IDE interface base address */
-#define BI_MAC_NUBUS		0x801a	/* Mac Nubus type (none, regular, pseudo) */
-#define BI_MAC_SLOTMASK		0x801b	/* Mac Nubus slots present */
-#define BI_MAC_SCCTYPE		0x801c	/* Mac SCC serial type (normal, IOP) */
-#define BI_MAC_ETHTYPE		0x801d	/* Mac builtin ethernet type (Sonic, MACE */
-#define BI_MAC_ETHBASE		0x801e	/* Mac builtin ethernet base address */
-#define BI_MAC_PMU		0x801f	/* Mac power management / poweroff hardware */
-#define BI_MAC_IOP_SWIM		0x8020	/* Mac SWIM floppy IOP */
-#define BI_MAC_IOP_ADB		0x8021	/* Mac ADB IOP */
-
-    /*
-     * Mac: compatibility with old booter data format (temporarily)
-     * Fields unused with the new bootinfo can be deleted now; instead of
-     * adding new fields the struct might be splitted into a hardware address
-     * part and a hardware type part
-     */
-
-#ifndef __ASSEMBLY__
-
-struct mac_booter_data
-{
-	unsigned long videoaddr;
-	unsigned long videorow;
-	unsigned long videodepth;
-	unsigned long dimensions;
-	unsigned long args;
-	unsigned long boottime;
-	unsigned long gmtbias;
-	unsigned long bootver;
-	unsigned long videological;
-	unsigned long sccbase;
-	unsigned long id;
-	unsigned long memsize;
-	unsigned long serialmf;
-	unsigned long serialhsk;
-	unsigned long serialgpi;
-	unsigned long printmf;
-	unsigned long printhsk;
-	unsigned long printgpi;
-	unsigned long cpuid;
-	unsigned long rombase;
-	unsigned long adbdelay;
-	unsigned long timedbra;
-};
-
-extern struct mac_booter_data
-	mac_bi_data;
-
-#endif
-
-    /*
-     *  Apollo-specific tags
-     */
-
-#define BI_APOLLO_MODEL         0x8000  /* model (u_long) */
-
-    /*
-     *  HP300-specific tags
-     */
-
-#define BI_HP300_MODEL		0x8000	/* model (u_long) */
-#define BI_HP300_UART_SCODE	0x8001	/* UART select code (u_long) */
-#define BI_HP300_UART_ADDR	0x8002	/* phys. addr of UART (u_long) */
-
-    /*
-     * Stuff for bootinfo interface versioning
-     *
-     * At the start of kernel code, a 'struct bootversion' is located.
-     * bootstrap checks for a matching version of the interface before booting
-     * a kernel, to avoid user confusion if kernel and bootstrap don't work
-     * together :-)
-     *
-     * If incompatible changes are made to the bootinfo interface, the major
-     * number below should be stepped (and the minor reset to 0) for the
-     * appropriate machine. If a change is backward-compatible, the minor
-     * should be stepped. "Backwards-compatible" means that booting will work,
-     * but certain features may not.
-     */
-
-#define BOOTINFOV_MAGIC			0x4249561A	/* 'BIV^Z' */
-#define MK_BI_VERSION(major,minor)	(((major)<<16)+(minor))
-#define BI_VERSION_MAJOR(v)		(((v) >> 16) & 0xffff)
-#define BI_VERSION_MINOR(v)		((v) & 0xffff)
-
-#ifndef __ASSEMBLY__
-
-struct bootversion {
-    unsigned short branch;
-    unsigned long magic;
-    struct {
-	unsigned long machtype;
-	unsigned long version;
-    } machversions[0];
-};
-
-#endif /* __ASSEMBLY__ */
-
-#define AMIGA_BOOTI_VERSION    MK_BI_VERSION( 2, 0 )
-#define ATARI_BOOTI_VERSION    MK_BI_VERSION( 2, 1 )
-#define MAC_BOOTI_VERSION      MK_BI_VERSION( 2, 0 )
-#define MVME147_BOOTI_VERSION  MK_BI_VERSION( 2, 0 )
-#define MVME16x_BOOTI_VERSION  MK_BI_VERSION( 2, 0 )
-#define BVME6000_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
-#define Q40_BOOTI_VERSION      MK_BI_VERSION( 2, 0 )
-#define HP300_BOOTI_VERSION    MK_BI_VERSION( 2, 0 )
-
-#ifdef BOOTINFO_COMPAT_1_0
-
-    /*
-     *  Backwards compatibility with bootinfo interface version 1.0
-     */
-
-#define COMPAT_AMIGA_BOOTI_VERSION    MK_BI_VERSION( 1, 0 )
-#define COMPAT_ATARI_BOOTI_VERSION    MK_BI_VERSION( 1, 0 )
-#define COMPAT_MAC_BOOTI_VERSION      MK_BI_VERSION( 1, 0 )
-
-#include <linux/zorro.h>
-
-#define COMPAT_NUM_AUTO    16
-
-struct compat_bi_Amiga {
-    int model;
-    int num_autocon;
-    struct ConfigDev autocon[COMPAT_NUM_AUTO];
-    unsigned long chip_size;
-    unsigned char vblank;
-    unsigned char psfreq;
-    unsigned long eclock;
-    unsigned long chipset;
-    unsigned long hw_present;
-};
-
-struct compat_bi_Atari {
-    unsigned long hw_present;
-    unsigned long mch_cookie;
-};
-
-#ifndef __ASSEMBLY__
-
-struct compat_bi_Macintosh
-{
-	unsigned long videoaddr;
-	unsigned long videorow;
-	unsigned long videodepth;
-	unsigned long dimensions;
-	unsigned long args;
-	unsigned long boottime;
-	unsigned long gmtbias;
-	unsigned long bootver;
-	unsigned long videological;
-	unsigned long sccbase;
-	unsigned long id;
-	unsigned long memsize;
-	unsigned long serialmf;
-	unsigned long serialhsk;
-	unsigned long serialgpi;
-	unsigned long printmf;
-	unsigned long printhsk;
-	unsigned long printgpi;
-	unsigned long cpuid;
-	unsigned long rombase;
-	unsigned long adbdelay;
-	unsigned long timedbra;
-};
-
-#endif
-
-struct compat_mem_info {
-    unsigned long addr;
-    unsigned long size;
-};
-
-#define COMPAT_NUM_MEMINFO  4
-
-#define COMPAT_CPUB_68020 0
-#define COMPAT_CPUB_68030 1
-#define COMPAT_CPUB_68040 2
-#define COMPAT_CPUB_68060 3
-#define COMPAT_FPUB_68881 5
-#define COMPAT_FPUB_68882 6
-#define COMPAT_FPUB_68040 7
-#define COMPAT_FPUB_68060 8
-
-#define COMPAT_CPU_68020    (1<<COMPAT_CPUB_68020)
-#define COMPAT_CPU_68030    (1<<COMPAT_CPUB_68030)
-#define COMPAT_CPU_68040    (1<<COMPAT_CPUB_68040)
-#define COMPAT_CPU_68060    (1<<COMPAT_CPUB_68060)
-#define COMPAT_CPU_MASK     (31)
-#define COMPAT_FPU_68881    (1<<COMPAT_FPUB_68881)
-#define COMPAT_FPU_68882    (1<<COMPAT_FPUB_68882)
-#define COMPAT_FPU_68040    (1<<COMPAT_FPUB_68040)
-#define COMPAT_FPU_68060    (1<<COMPAT_FPUB_68060)
-#define COMPAT_FPU_MASK     (0xfe0)
-
-#define COMPAT_CL_SIZE      (256)
-
-struct compat_bootinfo {
-    unsigned long machtype;
-    unsigned long cputype;
-    struct compat_mem_info memory[COMPAT_NUM_MEMINFO];
-    int num_memory;
-    unsigned long ramdisk_size;
-    unsigned long ramdisk_addr;
-    char command_line[COMPAT_CL_SIZE];
-    union {
-	struct compat_bi_Amiga     bi_ami;
-	struct compat_bi_Atari     bi_ata;
-	struct compat_bi_Macintosh bi_mac;
-    } bi_un;
-};
-
-#define bi_amiga	bi_un.bi_ami
-#define bi_atari	bi_un.bi_ata
-#define bi_mac		bi_un.bi_mac
-
-#endif /* BOOTINFO_COMPAT_1_0 */
-
-
-#endif /* _M68K_BOOTINFO_H */
diff --git a/arch/m68k/include/asm/bootinfo_no.h b/arch/m68k/include/asm/bootinfo_no.h
deleted file mode 100644
index c12e526..0000000
--- a/arch/m68k/include/asm/bootinfo_no.h
+++ /dev/null
@@ -1,2 +0,0 @@
-
-/* Nothing for m68knommu */
diff --git a/arch/m68k/include/asm/bug.h b/arch/m68k/include/asm/bug.h
index 997e094..ef9a2e4 100644
--- a/arch/m68k/include/asm/bug.h
+++ b/arch/m68k/include/asm/bug.h
@@ -1,5 +1,30 @@
-#ifdef __uClinux__
-#include "bug_no.h"
+#ifndef _M68K_BUG_H
+#define _M68K_BUG_H
+
+#ifdef CONFIG_MMU
+#ifdef CONFIG_BUG
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+#ifndef CONFIG_SUN3
+#define BUG() do { \
+	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+	__builtin_trap(); \
+} while (0)
 #else
-#include "bug_mm.h"
+#define BUG() do { \
+	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+	panic("BUG!"); \
+} while (0)
+#endif
+#else
+#define BUG() do { \
+	__builtin_trap(); \
+} while (0)
+#endif
+
+#define HAVE_ARCH_BUG
+#endif
+#endif /* CONFIG_MMU */
+
+#include <asm-generic/bug.h>
+
 #endif
diff --git a/arch/m68k/include/asm/bug_mm.h b/arch/m68k/include/asm/bug_mm.h
deleted file mode 100644
index e5b528d..0000000
--- a/arch/m68k/include/asm/bug_mm.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef _M68K_BUG_H
-#define _M68K_BUG_H
-
-
-#ifdef CONFIG_BUG
-#ifdef CONFIG_DEBUG_BUGVERBOSE
-#ifndef CONFIG_SUN3
-#define BUG() do { \
-	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
-	__builtin_trap(); \
-} while (0)
-#else
-#define BUG() do { \
-	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
-	panic("BUG!"); \
-} while (0)
-#endif
-#else
-#define BUG() do { \
-	__builtin_trap(); \
-} while (0)
-#endif
-
-#define HAVE_ARCH_BUG
-#endif
-
-#include <asm-generic/bug.h>
-
-#endif
diff --git a/arch/m68k/include/asm/bug_no.h b/arch/m68k/include/asm/bug_no.h
deleted file mode 100644
index 70e7dc0..0000000
--- a/arch/m68k/include/asm/bug_no.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef _M68KNOMMU_BUG_H
-#define _M68KNOMMU_BUG_H
-#include <asm-generic/bug.h>
-#endif
diff --git a/arch/m68k/include/asm/bugs.h b/arch/m68k/include/asm/bugs.h
index 01f047d..d06207b 100644
--- a/arch/m68k/include/asm/bugs.h
+++ b/arch/m68k/include/asm/bugs.h
@@ -1,5 +1,20 @@
-#ifdef __uClinux__
-#include "bugs_no.h"
+/*
+ *  include/asm-m68k/bugs.h
+ *
+ *  Copyright (C) 1994  Linus Torvalds
+ */
+
+/*
+ * This is included by init/main.c to check for architecture-dependent bugs.
+ *
+ * Needs:
+ *	void check_bugs(void);
+ */
+
+#ifdef CONFIG_MMU
+extern void check_bugs(void);	/* in arch/m68k/kernel/setup.c */
 #else
-#include "bugs_mm.h"
+static void check_bugs(void)
+{
+}
 #endif
diff --git a/arch/m68k/include/asm/bugs_mm.h b/arch/m68k/include/asm/bugs_mm.h
deleted file mode 100644
index d019355..0000000
--- a/arch/m68k/include/asm/bugs_mm.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- *  include/asm-m68k/bugs.h
- *
- *  Copyright (C) 1994  Linus Torvalds
- */
-
-/*
- * This is included by init/main.c to check for architecture-dependent bugs.
- *
- * Needs:
- *	void check_bugs(void);
- */
-
-extern void check_bugs(void);	/* in arch/m68k/kernel/setup.c */
diff --git a/arch/m68k/include/asm/bugs_no.h b/arch/m68k/include/asm/bugs_no.h
deleted file mode 100644
index 5f382da..0000000
--- a/arch/m68k/include/asm/bugs_no.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- *  include/asm-m68k/bugs.h
- *
- *  Copyright (C) 1994  Linus Torvalds
- */
-
-/*
- * This is included by init/main.c to check for architecture-dependent bugs.
- *
- * Needs:
- *	void check_bugs(void);
- */
-
-static void check_bugs(void)
-{
-}
diff --git a/arch/m68k/include/asm/cache.h b/arch/m68k/include/asm/cache.h
index 599c29b..fed3fd3 100644
--- a/arch/m68k/include/asm/cache.h
+++ b/arch/m68k/include/asm/cache.h
@@ -1,5 +1,11 @@
-#ifdef __uClinux__
-#include "cache_no.h"
-#else
-#include "cache_mm.h"
+/*
+ * include/asm-m68k/cache.h
+ */
+#ifndef __ARCH_M68K_CACHE_H
+#define __ARCH_M68K_CACHE_H
+
+/* bytes per L1 cache line */
+#define        L1_CACHE_SHIFT  4
+#define        L1_CACHE_BYTES  (1<< L1_CACHE_SHIFT)
+
 #endif
diff --git a/arch/m68k/include/asm/cache_mm.h b/arch/m68k/include/asm/cache_mm.h
deleted file mode 100644
index fed3fd3..0000000
--- a/arch/m68k/include/asm/cache_mm.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * include/asm-m68k/cache.h
- */
-#ifndef __ARCH_M68K_CACHE_H
-#define __ARCH_M68K_CACHE_H
-
-/* bytes per L1 cache line */
-#define        L1_CACHE_SHIFT  4
-#define        L1_CACHE_BYTES  (1<< L1_CACHE_SHIFT)
-
-#endif
diff --git a/arch/m68k/include/asm/cache_no.h b/arch/m68k/include/asm/cache_no.h
deleted file mode 100644
index 24e9eac..0000000
--- a/arch/m68k/include/asm/cache_no.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef __ARCH_M68KNOMMU_CACHE_H
-#define __ARCH_M68KNOMMU_CACHE_H
-
-/* bytes per L1 cache line */
-#define        L1_CACHE_BYTES  16	/* this need to be at least 1 */
-
-/* m68k-elf-gcc  2.95.2 doesn't like these */
-
-#define __cacheline_aligned
-#define ____cacheline_aligned
-
-#endif
diff --git a/arch/m68k/include/asm/current.h b/arch/m68k/include/asm/current.h
index 51b056d..91fcc53 100644
--- a/arch/m68k/include/asm/current.h
+++ b/arch/m68k/include/asm/current.h
@@ -1,5 +1,28 @@
-#ifdef __uClinux__
-#include "current_no.h"
+#ifndef _M68K_CURRENT_H
+#define _M68K_CURRENT_H
+
+#ifdef CONFIG_MMU
+
+register struct task_struct *current __asm__("%a2");
+
 #else
-#include "current_mm.h"
-#endif
+
+/*
+ *	Rather than dedicate a register (as the m68k source does), we
+ *	just keep a global,  we should probably just change it all to be
+ *	current and lose _current_task.
+ */
+#include <linux/thread_info.h>
+
+struct task_struct;
+
+static inline struct task_struct *get_current(void)
+{
+	return(current_thread_info()->task);
+}
+
+#define	current	get_current()
+
+#endif /* CONFNIG_MMU */
+
+#endif /* !(_M68K_CURRENT_H) */
diff --git a/arch/m68k/include/asm/current_mm.h b/arch/m68k/include/asm/current_mm.h
deleted file mode 100644
index 8de8f8c..0000000
--- a/arch/m68k/include/asm/current_mm.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _M68K_CURRENT_H
-#define _M68K_CURRENT_H
-
-register struct task_struct *current __asm__("%a2");
-
-#endif /* !(_M68K_CURRENT_H) */
diff --git a/arch/m68k/include/asm/current_no.h b/arch/m68k/include/asm/current_no.h
deleted file mode 100644
index 53ee0f9..0000000
--- a/arch/m68k/include/asm/current_no.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef _M68KNOMMU_CURRENT_H
-#define _M68KNOMMU_CURRENT_H
-/*
- *	current.h
- *	(C) Copyright 2000, Lineo, David McCullough <davidm@uclinux.org>
- *	(C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
- *
- *	rather than dedicate a register (as the m68k source does), we
- *	just keep a global,  we should probably just change it all to be
- *	current and lose _current_task.
- */
-
-#include <linux/thread_info.h>
-
-struct task_struct;
-
-static inline struct task_struct *get_current(void)
-{
-	return(current_thread_info()->task);
-}
-
-#define	current	get_current()
-
-#endif /* _M68KNOMMU_CURRENT_H */
diff --git a/arch/m68k/include/asm/div64.h b/arch/m68k/include/asm/div64.h
index d211d9f5..edb6614 100644
--- a/arch/m68k/include/asm/div64.h
+++ b/arch/m68k/include/asm/div64.h
@@ -1,5 +1,34 @@
-#ifdef __uClinux__
-#include "div64_no.h"
+#ifndef _M68K_DIV64_H
+#define _M68K_DIV64_H
+
+#ifdef CONFIG_MMU
+
+#include <linux/types.h>
+
+/* n = n / base; return rem; */
+
+#define do_div(n, base) ({					\
+	union {							\
+		unsigned long n32[2];				\
+		unsigned long long n64;				\
+	} __n;							\
+	unsigned long __rem, __upper;				\
+								\
+	__n.n64 = (n);						\
+	if ((__upper = __n.n32[0])) {				\
+		asm ("divul.l %2,%1:%0"				\
+			: "=d" (__n.n32[0]), "=d" (__upper)	\
+			: "d" (base), "0" (__n.n32[0]));	\
+	}							\
+	asm ("divu.l %2,%1:%0"					\
+		: "=d" (__n.n32[1]), "=d" (__rem)		\
+		: "d" (base), "1" (__upper), "0" (__n.n32[1]));	\
+	(n) = __n.n64;						\
+	__rem;							\
+})
+
 #else
-#include "div64_mm.h"
-#endif
+#include <asm-generic/div64.h>
+#endif /* CONFIG_MMU */
+
+#endif /* _M68K_DIV64_H */
diff --git a/arch/m68k/include/asm/div64_mm.h b/arch/m68k/include/asm/div64_mm.h
deleted file mode 100644
index 8243c93..0000000
--- a/arch/m68k/include/asm/div64_mm.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef _M68K_DIV64_H
-#define _M68K_DIV64_H
-
-#include <linux/types.h>
-
-/* n = n / base; return rem; */
-
-#define do_div(n, base) ({					\
-	union {							\
-		unsigned long n32[2];				\
-		unsigned long long n64;				\
-	} __n;							\
-	unsigned long __rem, __upper;				\
-								\
-	__n.n64 = (n);						\
-	if ((__upper = __n.n32[0])) {				\
-		asm ("divul.l %2,%1:%0"				\
-			: "=d" (__n.n32[0]), "=d" (__upper)	\
-			: "d" (base), "0" (__n.n32[0]));	\
-	}							\
-	asm ("divu.l %2,%1:%0"					\
-		: "=d" (__n.n32[1]), "=d" (__rem)		\
-		: "d" (base), "1" (__upper), "0" (__n.n32[1]));	\
-	(n) = __n.n64;						\
-	__rem;							\
-})
-
-#endif /* _M68K_DIV64_H */
diff --git a/arch/m68k/include/asm/div64_no.h b/arch/m68k/include/asm/div64_no.h
deleted file mode 100644
index 6cd978c..0000000
--- a/arch/m68k/include/asm/div64_no.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/div64.h>
diff --git a/arch/m68k/include/asm/dma-mapping.h b/arch/m68k/include/asm/dma-mapping.h
index f4a4c76..26f5054 100644
--- a/arch/m68k/include/asm/dma-mapping.h
+++ b/arch/m68k/include/asm/dma-mapping.h
@@ -1,5 +1,112 @@
-#ifdef __uClinux__
-#include "dma-mapping_no.h"
+#ifndef _M68K_DMA_MAPPING_H
+#define _M68K_DMA_MAPPING_H
+
+#include <asm/cache.h>
+
+struct scatterlist;
+
+#ifndef CONFIG_MMU_SUN3
+static inline int dma_supported(struct device *dev, u64 mask)
+{
+	return 1;
+}
+
+static inline int dma_set_mask(struct device *dev, u64 mask)
+{
+	return 0;
+}
+
+static inline int dma_get_cache_alignment(void)
+{
+	return 1 << L1_CACHE_SHIFT;
+}
+
+static inline int dma_is_consistent(struct device *dev, dma_addr_t dma_addr)
+{
+	return 0;
+}
+
+extern void *dma_alloc_coherent(struct device *, size_t,
+				dma_addr_t *, gfp_t);
+extern void dma_free_coherent(struct device *, size_t,
+			      void *, dma_addr_t);
+
+static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
+					  dma_addr_t *handle, gfp_t flag)
+{
+	return dma_alloc_coherent(dev, size, handle, flag);
+}
+static inline void dma_free_noncoherent(struct device *dev, size_t size,
+					void *addr, dma_addr_t handle)
+{
+	dma_free_coherent(dev, size, addr, handle);
+}
+static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
+				  enum dma_data_direction dir)
+{
+	/* we use coherent allocation, so not much to do here. */
+}
+
+extern dma_addr_t dma_map_single(struct device *, void *, size_t,
+				 enum dma_data_direction);
+static inline void dma_unmap_single(struct device *dev, dma_addr_t addr,
+				    size_t size, enum dma_data_direction dir)
+{
+}
+
+extern dma_addr_t dma_map_page(struct device *, struct page *,
+			       unsigned long, size_t size,
+			       enum dma_data_direction);
+static inline void dma_unmap_page(struct device *dev, dma_addr_t address,
+				  size_t size, enum dma_data_direction dir)
+{
+}
+
+extern int dma_map_sg(struct device *, struct scatterlist *, int,
+		      enum dma_data_direction);
+static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+				int nhwentries, enum dma_data_direction dir)
+{
+}
+
+extern void dma_sync_single_for_device(struct device *, dma_addr_t, size_t,
+				       enum dma_data_direction);
+extern void dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
+				   enum dma_data_direction);
+
+static inline void dma_sync_single_range_for_device(struct device *dev,
+		dma_addr_t dma_handle, unsigned long offset, size_t size,
+		enum dma_data_direction direction)
+{
+	/* just sync everything for now */
+	dma_sync_single_for_device(dev, dma_handle, offset + size, direction);
+}
+
+static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle,
+					   size_t size, enum dma_data_direction dir)
+{
+}
+
+static inline void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
+				       int nents, enum dma_data_direction dir)
+{
+}
+
+static inline void dma_sync_single_range_for_cpu(struct device *dev,
+		dma_addr_t dma_handle, unsigned long offset, size_t size,
+		enum dma_data_direction direction)
+{
+	/* just sync everything for now */
+	dma_sync_single_for_cpu(dev, dma_handle, offset + size, direction);
+}
+
+static inline int dma_mapping_error(struct device *dev, dma_addr_t handle)
+{
+	return 0;
+}
+
 #else
-#include "dma-mapping_mm.h"
+#include <asm-generic/dma-mapping-broken.h>
 #endif
+
+#endif  /* _M68K_DMA_MAPPING_H */
diff --git a/arch/m68k/include/asm/dma-mapping_mm.h b/arch/m68k/include/asm/dma-mapping_mm.h
deleted file mode 100644
index 26f5054..0000000
--- a/arch/m68k/include/asm/dma-mapping_mm.h
+++ /dev/null
@@ -1,112 +0,0 @@
-#ifndef _M68K_DMA_MAPPING_H
-#define _M68K_DMA_MAPPING_H
-
-#include <asm/cache.h>
-
-struct scatterlist;
-
-#ifndef CONFIG_MMU_SUN3
-static inline int dma_supported(struct device *dev, u64 mask)
-{
-	return 1;
-}
-
-static inline int dma_set_mask(struct device *dev, u64 mask)
-{
-	return 0;
-}
-
-static inline int dma_get_cache_alignment(void)
-{
-	return 1 << L1_CACHE_SHIFT;
-}
-
-static inline int dma_is_consistent(struct device *dev, dma_addr_t dma_addr)
-{
-	return 0;
-}
-
-extern void *dma_alloc_coherent(struct device *, size_t,
-				dma_addr_t *, gfp_t);
-extern void dma_free_coherent(struct device *, size_t,
-			      void *, dma_addr_t);
-
-static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
-					  dma_addr_t *handle, gfp_t flag)
-{
-	return dma_alloc_coherent(dev, size, handle, flag);
-}
-static inline void dma_free_noncoherent(struct device *dev, size_t size,
-					void *addr, dma_addr_t handle)
-{
-	dma_free_coherent(dev, size, addr, handle);
-}
-static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
-				  enum dma_data_direction dir)
-{
-	/* we use coherent allocation, so not much to do here. */
-}
-
-extern dma_addr_t dma_map_single(struct device *, void *, size_t,
-				 enum dma_data_direction);
-static inline void dma_unmap_single(struct device *dev, dma_addr_t addr,
-				    size_t size, enum dma_data_direction dir)
-{
-}
-
-extern dma_addr_t dma_map_page(struct device *, struct page *,
-			       unsigned long, size_t size,
-			       enum dma_data_direction);
-static inline void dma_unmap_page(struct device *dev, dma_addr_t address,
-				  size_t size, enum dma_data_direction dir)
-{
-}
-
-extern int dma_map_sg(struct device *, struct scatterlist *, int,
-		      enum dma_data_direction);
-static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
-				int nhwentries, enum dma_data_direction dir)
-{
-}
-
-extern void dma_sync_single_for_device(struct device *, dma_addr_t, size_t,
-				       enum dma_data_direction);
-extern void dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
-				   enum dma_data_direction);
-
-static inline void dma_sync_single_range_for_device(struct device *dev,
-		dma_addr_t dma_handle, unsigned long offset, size_t size,
-		enum dma_data_direction direction)
-{
-	/* just sync everything for now */
-	dma_sync_single_for_device(dev, dma_handle, offset + size, direction);
-}
-
-static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle,
-					   size_t size, enum dma_data_direction dir)
-{
-}
-
-static inline void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
-				       int nents, enum dma_data_direction dir)
-{
-}
-
-static inline void dma_sync_single_range_for_cpu(struct device *dev,
-		dma_addr_t dma_handle, unsigned long offset, size_t size,
-		enum dma_data_direction direction)
-{
-	/* just sync everything for now */
-	dma_sync_single_for_cpu(dev, dma_handle, offset + size, direction);
-}
-
-static inline int dma_mapping_error(struct device *dev, dma_addr_t handle)
-{
-	return 0;
-}
-
-#else
-#include <asm-generic/dma-mapping-broken.h>
-#endif
-
-#endif  /* _M68K_DMA_MAPPING_H */
diff --git a/arch/m68k/include/asm/dma-mapping_no.h b/arch/m68k/include/asm/dma-mapping_no.h
deleted file mode 100644
index 1748f2b..0000000
--- a/arch/m68k/include/asm/dma-mapping_no.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _M68KNOMMU_DMA_MAPPING_H
-#define _M68KNOMMU_DMA_MAPPING_H
-
-#include <asm-generic/dma-mapping-broken.h>
-
-#endif  /* _M68KNOMMU_DMA_MAPPING_H */
diff --git a/arch/m68k/include/asm/elf.h b/arch/m68k/include/asm/elf.h
index 04ce488..0b0f49e 100644
--- a/arch/m68k/include/asm/elf.h
+++ b/arch/m68k/include/asm/elf.h
@@ -1,5 +1,119 @@
-#ifdef __uClinux__
-#include "elf_no.h"
+#ifndef __ASMm68k_ELF_H
+#define __ASMm68k_ELF_H
+
+/*
+ * ELF register definitions..
+ */
+
+#include <asm/ptrace.h>
+#include <asm/user.h>
+
+/*
+ * 68k ELF relocation types
+ */
+#define R_68K_NONE	0
+#define R_68K_32	1
+#define R_68K_16	2
+#define R_68K_8		3
+#define R_68K_PC32	4
+#define R_68K_PC16	5
+#define R_68K_PC8	6
+#define R_68K_GOT32	7
+#define R_68K_GOT16	8
+#define R_68K_GOT8	9
+#define R_68K_GOT32O	10
+#define R_68K_GOT16O	11
+#define R_68K_GOT8O	12
+#define R_68K_PLT32	13
+#define R_68K_PLT16	14
+#define R_68K_PLT8	15
+#define R_68K_PLT32O	16
+#define R_68K_PLT16O	17
+#define R_68K_PLT8O	18
+#define R_68K_COPY	19
+#define R_68K_GLOB_DAT	20
+#define R_68K_JMP_SLOT	21
+#define R_68K_RELATIVE	22
+
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct user_m68kfp_struct elf_fpregset_t;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ((x)->e_machine == EM_68K)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS	ELFCLASS32
+#define ELF_DATA	ELFDATA2MSB
+#define ELF_ARCH	EM_68K
+
+/* For SVR4/m68k the function pointer to be registered with `atexit' is
+   passed in %a1.  Although my copy of the ABI has no such statement, it
+   is actually used on ASV.  */
+#define ELF_PLAT_INIT(_r, load_addr)	_r->a1 = 0
+
+#define USE_ELF_CORE_DUMP
+#ifndef CONFIG_SUN3
+#define ELF_EXEC_PAGESIZE	4096
 #else
-#include "elf_mm.h"
+#define ELF_EXEC_PAGESIZE	8192
+#endif
+
+/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
+   use of this is to invoke "./ld.so someprog" to test out a new version of
+   the loader.  We need to make sure that it is out of the way of the program
+   that it will "exec", and that there is sufficient room for the brk.  */
+
+#ifndef CONFIG_SUN3
+#define ELF_ET_DYN_BASE         0xD0000000UL
+#else
+#define ELF_ET_DYN_BASE         0x0D800000UL
+#endif
+
+#define ELF_CORE_COPY_REGS(pr_reg, regs)				\
+	/* Bleech. */							\
+	pr_reg[0] = regs->d1;						\
+	pr_reg[1] = regs->d2;						\
+	pr_reg[2] = regs->d3;						\
+	pr_reg[3] = regs->d4;						\
+	pr_reg[4] = regs->d5;						\
+	pr_reg[7] = regs->a0;						\
+	pr_reg[8] = regs->a1;						\
+	pr_reg[9] = regs->a2;						\
+	pr_reg[14] = regs->d0;						\
+	pr_reg[15] = rdusp();						\
+	pr_reg[16] = regs->orig_d0;					\
+	pr_reg[17] = regs->sr;						\
+	pr_reg[18] = regs->pc;						\
+	pr_reg[19] = (regs->format << 12) | regs->vector;		\
+	{								\
+	  struct switch_stack *sw = ((struct switch_stack *)regs) - 1;	\
+	  pr_reg[5] = sw->d6;						\
+	  pr_reg[6] = sw->d7;						\
+	  pr_reg[10] = sw->a3;						\
+	  pr_reg[11] = sw->a4;						\
+	  pr_reg[12] = sw->a5;						\
+	  pr_reg[13] = sw->a6;						\
+	}
+
+/* This yields a mask that user programs can use to figure out what
+   instruction set this cpu supports.  */
+
+#define ELF_HWCAP	(0)
+
+/* This yields a string that ld.so will use to load implementation
+   specific libraries for optimization.  This is more specific in
+   intent than poking at uname or /proc/cpuinfo.  */
+
+#define ELF_PLATFORM  (NULL)
+
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+
 #endif
diff --git a/arch/m68k/include/asm/elf_mm.h b/arch/m68k/include/asm/elf_mm.h
deleted file mode 100644
index 0b0f49e..0000000
--- a/arch/m68k/include/asm/elf_mm.h
+++ /dev/null
@@ -1,119 +0,0 @@
-#ifndef __ASMm68k_ELF_H
-#define __ASMm68k_ELF_H
-
-/*
- * ELF register definitions..
- */
-
-#include <asm/ptrace.h>
-#include <asm/user.h>
-
-/*
- * 68k ELF relocation types
- */
-#define R_68K_NONE	0
-#define R_68K_32	1
-#define R_68K_16	2
-#define R_68K_8		3
-#define R_68K_PC32	4
-#define R_68K_PC16	5
-#define R_68K_PC8	6
-#define R_68K_GOT32	7
-#define R_68K_GOT16	8
-#define R_68K_GOT8	9
-#define R_68K_GOT32O	10
-#define R_68K_GOT16O	11
-#define R_68K_GOT8O	12
-#define R_68K_PLT32	13
-#define R_68K_PLT16	14
-#define R_68K_PLT8	15
-#define R_68K_PLT32O	16
-#define R_68K_PLT16O	17
-#define R_68K_PLT8O	18
-#define R_68K_COPY	19
-#define R_68K_GLOB_DAT	20
-#define R_68K_JMP_SLOT	21
-#define R_68K_RELATIVE	22
-
-typedef unsigned long elf_greg_t;
-
-#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-typedef struct user_m68kfp_struct elf_fpregset_t;
-
-/*
- * This is used to ensure we don't load something for the wrong architecture.
- */
-#define elf_check_arch(x) ((x)->e_machine == EM_68K)
-
-/*
- * These are used to set parameters in the core dumps.
- */
-#define ELF_CLASS	ELFCLASS32
-#define ELF_DATA	ELFDATA2MSB
-#define ELF_ARCH	EM_68K
-
-/* For SVR4/m68k the function pointer to be registered with `atexit' is
-   passed in %a1.  Although my copy of the ABI has no such statement, it
-   is actually used on ASV.  */
-#define ELF_PLAT_INIT(_r, load_addr)	_r->a1 = 0
-
-#define USE_ELF_CORE_DUMP
-#ifndef CONFIG_SUN3
-#define ELF_EXEC_PAGESIZE	4096
-#else
-#define ELF_EXEC_PAGESIZE	8192
-#endif
-
-/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
-   use of this is to invoke "./ld.so someprog" to test out a new version of
-   the loader.  We need to make sure that it is out of the way of the program
-   that it will "exec", and that there is sufficient room for the brk.  */
-
-#ifndef CONFIG_SUN3
-#define ELF_ET_DYN_BASE         0xD0000000UL
-#else
-#define ELF_ET_DYN_BASE         0x0D800000UL
-#endif
-
-#define ELF_CORE_COPY_REGS(pr_reg, regs)				\
-	/* Bleech. */							\
-	pr_reg[0] = regs->d1;						\
-	pr_reg[1] = regs->d2;						\
-	pr_reg[2] = regs->d3;						\
-	pr_reg[3] = regs->d4;						\
-	pr_reg[4] = regs->d5;						\
-	pr_reg[7] = regs->a0;						\
-	pr_reg[8] = regs->a1;						\
-	pr_reg[9] = regs->a2;						\
-	pr_reg[14] = regs->d0;						\
-	pr_reg[15] = rdusp();						\
-	pr_reg[16] = regs->orig_d0;					\
-	pr_reg[17] = regs->sr;						\
-	pr_reg[18] = regs->pc;						\
-	pr_reg[19] = (regs->format << 12) | regs->vector;		\
-	{								\
-	  struct switch_stack *sw = ((struct switch_stack *)regs) - 1;	\
-	  pr_reg[5] = sw->d6;						\
-	  pr_reg[6] = sw->d7;						\
-	  pr_reg[10] = sw->a3;						\
-	  pr_reg[11] = sw->a4;						\
-	  pr_reg[12] = sw->a5;						\
-	  pr_reg[13] = sw->a6;						\
-	}
-
-/* This yields a mask that user programs can use to figure out what
-   instruction set this cpu supports.  */
-
-#define ELF_HWCAP	(0)
-
-/* This yields a string that ld.so will use to load implementation
-   specific libraries for optimization.  This is more specific in
-   intent than poking at uname or /proc/cpuinfo.  */
-
-#define ELF_PLATFORM  (NULL)
-
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
-
-#endif
diff --git a/arch/m68k/include/asm/elf_no.h b/arch/m68k/include/asm/elf_no.h
deleted file mode 100644
index b804683..0000000
--- a/arch/m68k/include/asm/elf_no.h
+++ /dev/null
@@ -1,110 +0,0 @@
-#ifndef __ASMm68k_ELF_H
-#define __ASMm68k_ELF_H
-
-/*
- * ELF register definitions..
- */
-
-#include <asm/ptrace.h>
-#include <asm/user.h>
-
-/*
- * 68k ELF relocation types
- */
-#define R_68K_NONE  0
-#define R_68K_32    1
-#define R_68K_16    2
-#define R_68K_8     3
-#define R_68K_PC32  4
-#define R_68K_PC16  5
-#define R_68K_PC8   6
-#define R_68K_GOT32 7
-#define R_68K_GOT16 8
-#define R_68K_GOT8  9
-#define R_68K_GOT32O    10
-#define R_68K_GOT16O    11
-#define R_68K_GOT8O 12
-#define R_68K_PLT32 13
-#define R_68K_PLT16 14
-#define R_68K_PLT8  15
-#define R_68K_PLT32O    16
-#define R_68K_PLT16O    17
-#define R_68K_PLT8O 18
-#define R_68K_COPY  19
-#define R_68K_GLOB_DAT  20
-#define R_68K_JMP_SLOT  21
-#define R_68K_RELATIVE  22
-
-typedef unsigned long elf_greg_t;
-
-#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-typedef struct user_m68kfp_struct elf_fpregset_t;
-
-/*
- * This is used to ensure we don't load something for the wrong architecture.
- */
-#define elf_check_arch(x) ((x)->e_machine == EM_68K)
-
-/*
- * These are used to set parameters in the core dumps.
- */
-#define ELF_CLASS	ELFCLASS32
-#define ELF_DATA	ELFDATA2MSB
-#define ELF_ARCH	EM_68K
-
-/* For SVR4/m68k the function pointer to be registered with `atexit' is
-   passed in %a1.  Although my copy of the ABI has no such statement, it
-   is actually used on ASV.  */
-#define ELF_PLAT_INIT(_r, load_addr)	_r->a1 = 0
-
-#define USE_ELF_CORE_DUMP
-#define ELF_EXEC_PAGESIZE	4096
-
-/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
-   use of this is to invoke "./ld.so someprog" to test out a new version of
-   the loader.  We need to make sure that it is out of the way of the program
-   that it will "exec", and that there is sufficient room for the brk.  */
-
-#define ELF_ET_DYN_BASE         0xD0000000UL
-
-#define ELF_CORE_COPY_REGS(pr_reg, regs)				\
-	/* Bleech. */							\
-	pr_reg[0] = regs->d1;						\
-	pr_reg[1] = regs->d2;						\
-	pr_reg[2] = regs->d3;						\
-	pr_reg[3] = regs->d4;						\
-	pr_reg[4] = regs->d5;						\
-	pr_reg[7] = regs->a0;						\
-	pr_reg[8] = regs->a1;						\
-	pr_reg[14] = regs->d0;						\
-	pr_reg[15] = rdusp();						\
-	pr_reg[16] = 0 /* regs->orig_d0 */;				\
-	pr_reg[17] = regs->sr;						\
-	pr_reg[18] = regs->pc;						\
-	/* pr_reg[19] = (regs->format << 12) | regs->vector; */		\
-	{								\
-	  struct switch_stack *sw = ((struct switch_stack *)regs) - 1;	\
-	  pr_reg[5] = sw->d6;						\
-	  pr_reg[6] = sw->d7;						\
-	  pr_reg[10] = sw->a3;						\
-	  pr_reg[11] = sw->a4;						\
-	  pr_reg[12] = sw->a5;						\
-	  pr_reg[13] = sw->a6;						\
-	}
-
-/* This yields a mask that user programs can use to figure out what
-   instruction set this cpu supports.  */
-
-#define ELF_HWCAP	(0)
-
-/* This yields a string that ld.so will use to load implementation
-   specific libraries for optimization.  This is more specific in
-   intent than poking at uname or /proc/cpuinfo.  */
-
-#define ELF_PLATFORM  (NULL)
-
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
-
-#endif
diff --git a/arch/m68k/include/asm/fb.h b/arch/m68k/include/asm/fb.h
index 97bcaef..be4e4c6 100644
--- a/arch/m68k/include/asm/fb.h
+++ b/arch/m68k/include/asm/fb.h
@@ -1,5 +1,38 @@
-#ifdef __uClinux__
-#include "fb_no.h"
+#ifndef _ASM_FB_H_
+#define _ASM_FB_H_
+
+#include <linux/fb.h>
+#include <linux/fs.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+
+#ifdef CONFIG_MMU
+#ifdef CONFIG_SUN3
+static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
+				unsigned long off)
+{
+	pgprot_val(vma->vm_page_prot) |= SUN3_PAGE_NOCACHE;
+}
 #else
-#include "fb_mm.h"
-#endif
+static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
+				unsigned long off)
+{
+	if (CPU_IS_020_OR_030)
+		pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE030;
+	if (CPU_IS_040_OR_060) {
+		pgprot_val(vma->vm_page_prot) &= _CACHEMASK040;
+		/* Use no-cache mode, serialized */
+		pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE_S;
+	}
+}
+#endif /* CONFIG_SUN3 */
+#else
+#define fb_pgprotect(...) do {} while (0)
+#endif /* CONFIG_MMU */
+
+static inline int fb_is_primary_device(struct fb_info *info)
+{
+	return 0;
+}
+
+#endif /* _ASM_FB_H_ */
diff --git a/arch/m68k/include/asm/fb_mm.h b/arch/m68k/include/asm/fb_mm.h
deleted file mode 100644
index 380b97a..0000000
--- a/arch/m68k/include/asm/fb_mm.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
-
-#include <linux/fb.h>
-#include <linux/fs.h>
-#include <asm/page.h>
-#include <asm/setup.h>
-
-#ifdef CONFIG_SUN3
-static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
-				unsigned long off)
-{
-	pgprot_val(vma->vm_page_prot) |= SUN3_PAGE_NOCACHE;
-}
-#else
-static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
-				unsigned long off)
-{
-	if (CPU_IS_020_OR_030)
-		pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE030;
-	if (CPU_IS_040_OR_060) {
-		pgprot_val(vma->vm_page_prot) &= _CACHEMASK040;
-		/* Use no-cache mode, serialized */
-		pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE_S;
-	}
-}
-#endif /* CONFIG_SUN3 */
-
-static inline int fb_is_primary_device(struct fb_info *info)
-{
-	return 0;
-}
-
-#endif /* _ASM_FB_H_ */
diff --git a/arch/m68k/include/asm/fb_no.h b/arch/m68k/include/asm/fb_no.h
deleted file mode 100644
index c7df380..0000000
--- a/arch/m68k/include/asm/fb_no.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
-#include <linux/fb.h>
-
-#define fb_pgprotect(...) do {} while (0)
-
-static inline int fb_is_primary_device(struct fb_info *info)
-{
-	return 0;
-}
-
-#endif /* _ASM_FB_H_ */
diff --git a/arch/m68k/include/asm/fpu.h b/arch/m68k/include/asm/fpu.h
index e19bc5e..ffb6b8c 100644
--- a/arch/m68k/include/asm/fpu.h
+++ b/arch/m68k/include/asm/fpu.h
@@ -1,5 +1,21 @@
-#ifdef __uClinux__
-#include "fpu_no.h"
+#ifndef __M68K_FPU_H
+#define __M68K_FPU_H
+
+
+/*
+ * MAX floating point unit state size (FSAVE/FRESTORE)
+ */
+
+#if defined(CONFIG_M68020) || defined(CONFIG_M68030)
+#define FPSTATESIZE (216)
+#elif defined(CONFIG_M68040)
+#define FPSTATESIZE (96)
+#elif defined(CONFIG_M68KFPU_EMU)
+#define FPSTATESIZE (28)
+#elif defined(CONFIG_M68060)
+#define FPSTATESIZE (12)
 #else
-#include "fpu_mm.h"
+#define FPSTATESIZE (0)
 #endif
+
+#endif /* __M68K_FPU_H */
diff --git a/arch/m68k/include/asm/fpu_mm.h b/arch/m68k/include/asm/fpu_mm.h
deleted file mode 100644
index ffb6b8c..0000000
--- a/arch/m68k/include/asm/fpu_mm.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef __M68K_FPU_H
-#define __M68K_FPU_H
-
-
-/*
- * MAX floating point unit state size (FSAVE/FRESTORE)
- */
-
-#if defined(CONFIG_M68020) || defined(CONFIG_M68030)
-#define FPSTATESIZE (216)
-#elif defined(CONFIG_M68040)
-#define FPSTATESIZE (96)
-#elif defined(CONFIG_M68KFPU_EMU)
-#define FPSTATESIZE (28)
-#elif defined(CONFIG_M68060)
-#define FPSTATESIZE (12)
-#else
-#define FPSTATESIZE (0)
-#endif
-
-#endif /* __M68K_FPU_H */
diff --git a/arch/m68k/include/asm/fpu_no.h b/arch/m68k/include/asm/fpu_no.h
deleted file mode 100644
index b16b2e4..0000000
--- a/arch/m68k/include/asm/fpu_no.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef __M68KNOMMU_FPU_H
-#define __M68KNOMMU_FPU_H
-
-
-/*
- * MAX floating point unit state size (FSAVE/FRESTORE)
- */
-#if defined(CONFIG_M68020) || defined(CONFIG_M68030)
-#define FPSTATESIZE (216/sizeof(unsigned char))
-#elif defined(CONFIG_M68040)
-#define FPSTATESIZE (96/sizeof(unsigned char))
-#elif defined(CONFIG_M68KFPU_EMU)
-#define FPSTATESIZE (28/sizeof(unsigned char))
-#elif defined(CONFIG_M68060)
-#define FPSTATESIZE (12/sizeof(unsigned char))
-#else
-/* Assume no FP unit present then... */
-#define FPSTATESIZE (2) /* dummy size */
-#endif
-
-#endif /* __M68K_FPU_H */
diff --git a/arch/m68k/include/asm/ftrace.h b/arch/m68k/include/asm/ftrace.h
new file mode 100644
index 0000000..40a8c17
--- /dev/null
+++ b/arch/m68k/include/asm/ftrace.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/m68k/include/asm/hw_irq.h b/arch/m68k/include/asm/hw_irq.h
index e195260..eacef09 100644
--- a/arch/m68k/include/asm/hw_irq.h
+++ b/arch/m68k/include/asm/hw_irq.h
@@ -1,5 +1,6 @@
-#ifdef __uClinux__
-#include "hw_irq_no.h"
-#else
-#include "hw_irq_mm.h"
+#ifndef __ASM_M68K_HW_IRQ_H
+#define __ASM_M68K_HW_IRQ_H
+
+/* Dummy include. */
+
 #endif
diff --git a/arch/m68k/include/asm/hw_irq_mm.h b/arch/m68k/include/asm/hw_irq_mm.h
deleted file mode 100644
index eacef09..0000000
--- a/arch/m68k/include/asm/hw_irq_mm.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __ASM_M68K_HW_IRQ_H
-#define __ASM_M68K_HW_IRQ_H
-
-/* Dummy include. */
-
-#endif
diff --git a/arch/m68k/include/asm/hw_irq_no.h b/arch/m68k/include/asm/hw_irq_no.h
deleted file mode 100644
index f3ec9e5..0000000
--- a/arch/m68k/include/asm/hw_irq_no.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef __M68KNOMMU_HW_IRQ_H__
-#define __M68KNOMMU_HW_IRQ_H__
-
-#endif /* __M68KNOMMU_HW_IRQ_H__ */
diff --git a/arch/m68k/include/asm/kmap_types.h b/arch/m68k/include/asm/kmap_types.h
index 045d9fd..c843c63 100644
--- a/arch/m68k/include/asm/kmap_types.h
+++ b/arch/m68k/include/asm/kmap_types.h
@@ -1,5 +1,21 @@
-#ifdef __uClinux__
-#include "kmap_types_no.h"
-#else
-#include "kmap_types_mm.h"
-#endif
+#ifndef __ASM_M68K_KMAP_TYPES_H
+#define __ASM_M68K_KMAP_TYPES_H
+
+enum km_type {
+	KM_BOUNCE_READ,
+	KM_SKB_SUNRPC_DATA,
+	KM_SKB_DATA_SOFTIRQ,
+	KM_USER0,
+	KM_USER1,
+	KM_BIO_SRC_IRQ,
+	KM_BIO_DST_IRQ,
+	KM_PTE0,
+	KM_PTE1,
+	KM_IRQ0,
+	KM_IRQ1,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,
+	KM_TYPE_NR
+};
+
+#endif	/* __ASM_M68K_KMAP_TYPES_H */
diff --git a/arch/m68k/include/asm/kmap_types_mm.h b/arch/m68k/include/asm/kmap_types_mm.h
deleted file mode 100644
index c843c63..0000000
--- a/arch/m68k/include/asm/kmap_types_mm.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef __ASM_M68K_KMAP_TYPES_H
-#define __ASM_M68K_KMAP_TYPES_H
-
-enum km_type {
-	KM_BOUNCE_READ,
-	KM_SKB_SUNRPC_DATA,
-	KM_SKB_DATA_SOFTIRQ,
-	KM_USER0,
-	KM_USER1,
-	KM_BIO_SRC_IRQ,
-	KM_BIO_DST_IRQ,
-	KM_PTE0,
-	KM_PTE1,
-	KM_IRQ0,
-	KM_IRQ1,
-	KM_SOFTIRQ0,
-	KM_SOFTIRQ1,
-	KM_TYPE_NR
-};
-
-#endif	/* __ASM_M68K_KMAP_TYPES_H */
diff --git a/arch/m68k/include/asm/kmap_types_no.h b/arch/m68k/include/asm/kmap_types_no.h
deleted file mode 100644
index bfb6707..0000000
--- a/arch/m68k/include/asm/kmap_types_no.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef __ASM_M68K_KMAP_TYPES_H
-#define __ASM_M68K_KMAP_TYPES_H
-
-enum km_type {
-	KM_BOUNCE_READ,
-	KM_SKB_SUNRPC_DATA,
-	KM_SKB_DATA_SOFTIRQ,
-	KM_USER0,
-	KM_USER1,
-	KM_BIO_SRC_IRQ,
-	KM_BIO_DST_IRQ,
-	KM_PTE0,
-	KM_PTE1,
-	KM_IRQ0,
-	KM_IRQ1,
-	KM_SOFTIRQ0,
-	KM_SOFTIRQ1,
-	KM_TYPE_NR
-};
-
-#endif
diff --git a/arch/m68k/include/asm/m532xsim.h b/arch/m68k/include/asm/m532xsim.h
index 1835fd2..ce60345 100644
--- a/arch/m68k/include/asm/m532xsim.h
+++ b/arch/m68k/include/asm/m532xsim.h
@@ -16,6 +16,7 @@
 #define MCFINT_VECBASE      64
 #define MCFINT_UART0        26          /* Interrupt number for UART0 */
 #define MCFINT_UART1        27          /* Interrupt number for UART1 */
+#define MCFINT_UART2        28          /* Interrupt number for UART2 */
 
 #define MCF_WTM_WCR	MCF_REG16(0xFC098000)
 
diff --git a/arch/m68k/include/asm/mc146818rtc.h b/arch/m68k/include/asm/mc146818rtc.h
index fb90dcf..9f70a01 100644
--- a/arch/m68k/include/asm/mc146818rtc.h
+++ b/arch/m68k/include/asm/mc146818rtc.h
@@ -1,5 +1,26 @@
-#ifdef __uClinux__
-#include "mc146818rtc_no.h"
-#else
-#include "mc146818rtc_mm.h"
-#endif
+/*
+ * Machine dependent access functions for RTC registers.
+ */
+#ifndef _ASM_MC146818RTC_H
+#define _ASM_MC146818RTC_H
+
+
+#ifdef CONFIG_ATARI
+/* RTC in Atari machines */
+
+#include <asm/atarihw.h>
+
+#define RTC_PORT(x)	(TT_RTC_BAS + 2*(x))
+#define RTC_ALWAYS_BCD	0
+
+#define CMOS_READ(addr) ({ \
+atari_outb_p((addr),RTC_PORT(0)); \
+atari_inb_p(RTC_PORT(1)); \
+})
+#define CMOS_WRITE(val, addr) ({ \
+atari_outb_p((addr),RTC_PORT(0)); \
+atari_outb_p((val),RTC_PORT(1)); \
+})
+#endif /* CONFIG_ATARI */
+
+#endif /* _ASM_MC146818RTC_H */
diff --git a/arch/m68k/include/asm/mc146818rtc_mm.h b/arch/m68k/include/asm/mc146818rtc_mm.h
deleted file mode 100644
index 9f70a01..0000000
--- a/arch/m68k/include/asm/mc146818rtc_mm.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Machine dependent access functions for RTC registers.
- */
-#ifndef _ASM_MC146818RTC_H
-#define _ASM_MC146818RTC_H
-
-
-#ifdef CONFIG_ATARI
-/* RTC in Atari machines */
-
-#include <asm/atarihw.h>
-
-#define RTC_PORT(x)	(TT_RTC_BAS + 2*(x))
-#define RTC_ALWAYS_BCD	0
-
-#define CMOS_READ(addr) ({ \
-atari_outb_p((addr),RTC_PORT(0)); \
-atari_inb_p(RTC_PORT(1)); \
-})
-#define CMOS_WRITE(val, addr) ({ \
-atari_outb_p((addr),RTC_PORT(0)); \
-atari_outb_p((val),RTC_PORT(1)); \
-})
-#endif /* CONFIG_ATARI */
-
-#endif /* _ASM_MC146818RTC_H */
diff --git a/arch/m68k/include/asm/mc146818rtc_no.h b/arch/m68k/include/asm/mc146818rtc_no.h
deleted file mode 100644
index 907a0481..0000000
--- a/arch/m68k/include/asm/mc146818rtc_no.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * Machine dependent access functions for RTC registers.
- */
-#ifndef _M68KNOMMU_MC146818RTC_H
-#define _M68KNOMMU_MC146818RTC_H
-
-/* empty include file to satisfy the include in genrtc.c/ide-geometry.c */
-
-#endif /* _M68KNOMMU_MC146818RTC_H */
diff --git a/arch/m68k/include/asm/mcfpci.h b/arch/m68k/include/asm/mcfpci.h
deleted file mode 100644
index f1507dd..0000000
--- a/arch/m68k/include/asm/mcfpci.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/****************************************************************************/
-
-/*
- *	mcfpci.h -- PCI bridge on ColdFire eval boards.
- *
- *	(C) Copyright 2000, Greg Ungerer (gerg@snapgear.com)
- *	(C) Copyright 2000, Lineo Inc. (www.lineo.com)
- */
-
-/****************************************************************************/
-#ifndef	mcfpci_h
-#define	mcfpci_h
-/****************************************************************************/
-
-
-#ifdef CONFIG_PCI
-
-/*
- *	Address regions in the PCI address space are not mapped into the
- *	normal memory space of the ColdFire. They must be accessed via
- *	handler routines. This is easy for I/O space (inb/outb/etc) but
- *	needs some code changes to support ordinary memory. Interrupts
- *	also need to be vectored through the PCI handler first, then it
- *	will call the actual driver sub-handlers.
- */
-
-/*
- *	Un-define all the standard I/O access routines.
- */
-#undef	inb
-#undef	inw
-#undef	inl
-#undef	inb_p
-#undef	inw_p
-#undef	insb
-#undef	insw
-#undef	insl
-#undef	outb
-#undef	outw
-#undef	outl
-#undef	outb_p
-#undef	outw_p
-#undef	outsb
-#undef	outsw
-#undef	outsl
-
-#undef	request_irq
-#undef	free_irq
-
-#undef	bus_to_virt
-#undef	virt_to_bus
-
-
-/*
- *	Re-direct all I/O memory accesses functions to PCI specific ones.
- */
-#define	inb	pci_inb
-#define	inw	pci_inw
-#define	inl	pci_inl
-#define	inb_p	pci_inb
-#define	inw_p	pci_inw
-#define	insb	pci_insb
-#define	insw	pci_insw
-#define	insl	pci_insl
-
-#define	outb	pci_outb
-#define	outw	pci_outw
-#define	outl	pci_outl
-#define	outb_p	pci_outb
-#define	outw_p	pci_outw
-#define	outsb	pci_outsb
-#define	outsw	pci_outsw
-#define	outsl	pci_outsl
-
-#define	request_irq	pci_request_irq
-#define	free_irq	pci_free_irq
-
-#define	virt_to_bus	pci_virt_to_bus
-#define	bus_to_virt	pci_bus_to_virt
-
-#define	CONFIG_COMEMPCI	1
-
-
-/*
- *	Prototypes of the real PCI functions (defined in bios32.c).
- */
-unsigned char	pci_inb(unsigned int addr);
-unsigned short	pci_inw(unsigned int addr);
-unsigned int	pci_inl(unsigned int addr);
-void		pci_insb(void *addr, void *buf, int len);
-void		pci_insw(void *addr, void *buf, int len);
-void		pci_insl(void *addr, void *buf, int len);
-
-void		pci_outb(unsigned char val, unsigned int addr);
-void		pci_outw(unsigned short val, unsigned int addr);
-void		pci_outl(unsigned int val, unsigned int addr);
-void		pci_outsb(void *addr, void *buf, int len);
-void		pci_outsw(void *addr, void *buf, int len);
-void		pci_outsl(void *addr, void *buf, int len);
-
-int		pci_request_irq(unsigned int irq,
-			void (*handler)(int, void *, struct pt_regs *),
-			unsigned long flags,
-			const char *device,
-			void *dev_id);
-void		pci_free_irq(unsigned int irq, void *dev_id);
-
-void		*pci_bmalloc(int size);
-void		pci_bmfree(void *bmp, int len);
-void		pci_copytoshmem(unsigned long bmp, void *src, int size);
-void		pci_copyfromshmem(void *dst, unsigned long bmp, int size);
-unsigned long	pci_virt_to_bus(volatile void *address);
-void		*pci_bus_to_virt(unsigned long address);
-void		pci_bmcpyto(void *dst, void *src, int len);
-void		pci_bmcpyfrom(void *dst, void *src, int len);
-
-#endif /* CONFIG_PCI */
-/****************************************************************************/
-#endif	/* mcfpci_h */
diff --git a/arch/m68k/include/asm/mmu.h b/arch/m68k/include/asm/mmu.h
index a81d394..8a11a63 100644
--- a/arch/m68k/include/asm/mmu.h
+++ b/arch/m68k/include/asm/mmu.h
@@ -1,5 +1,13 @@
-#ifdef __uClinux__
-#include "mmu_no.h"
+#ifndef __MMU_H
+#define __MMU_H
+
+#ifdef CONFIG_MMU
+/* Default "unsigned long" context */
+typedef unsigned long mm_context_t;
 #else
-#include "mmu_mm.h"
+typedef struct {
+	unsigned long		end_brk;
+} mm_context_t;
+#endif
+
 #endif
diff --git a/arch/m68k/include/asm/mmu_context.h b/arch/m68k/include/asm/mmu_context.h
index b440928..7d4341e 100644
--- a/arch/m68k/include/asm/mmu_context.h
+++ b/arch/m68k/include/asm/mmu_context.h
@@ -1,5 +1,175 @@
-#ifdef __uClinux__
-#include "mmu_context_no.h"
+#ifndef __M68K_MMU_CONTEXT_H
+#define __M68K_MMU_CONTEXT_H
+
+#include <asm-generic/mm_hooks.h>
+
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+}
+
+#ifdef CONFIG_MMU
+#ifndef CONFIG_SUN3
+
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+
+static inline int init_new_context(struct task_struct *tsk,
+				   struct mm_struct *mm)
+{
+	mm->context = virt_to_phys(mm->pgd);
+	return 0;
+}
+
+#define destroy_context(mm)		do { } while(0)
+
+static inline void switch_mm_0230(struct mm_struct *mm)
+{
+	unsigned long crp[2] = {
+		0x80000000 | _PAGE_TABLE, mm->context
+	};
+	unsigned long tmp;
+
+	asm volatile (".chip 68030");
+
+	/* flush MC68030/MC68020 caches (they are virtually addressed) */
+	asm volatile (
+		"movec %%cacr,%0;"
+		"orw %1,%0; "
+		"movec %0,%%cacr"
+		: "=d" (tmp) : "di" (FLUSH_I_AND_D));
+
+	/* Switch the root pointer. For a 030-only kernel,
+	 * avoid flushing the whole ATC, we only need to
+	 * flush the user entries. The 68851 does this by
+	 * itself. Avoid a runtime check here.
+	 */
+	asm volatile (
+#ifdef CPU_M68030_ONLY
+		"pmovefd %0,%%crp; "
+		"pflush #0,#4"
 #else
-#include "mmu_context_mm.h"
+		"pmove %0,%%crp"
 #endif
+		: : "m" (crp[0]));
+
+	asm volatile (".chip 68k");
+}
+
+static inline void switch_mm_0460(struct mm_struct *mm)
+{
+	asm volatile (".chip 68040");
+
+	/* flush address translation cache (user entries) */
+	asm volatile ("pflushan");
+
+	/* switch the root pointer */
+	asm volatile ("movec %0,%%urp" : : "r" (mm->context));
+
+	if (CPU_IS_060) {
+		unsigned long tmp;
+
+		/* clear user entries in the branch cache */
+		asm volatile (
+			"movec %%cacr,%0; "
+		        "orl %1,%0; "
+		        "movec %0,%%cacr"
+			: "=d" (tmp): "di" (0x00200000));
+	}
+
+	asm volatile (".chip 68k");
+}
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
+{
+	if (prev != next) {
+		if (CPU_IS_020_OR_030)
+			switch_mm_0230(next);
+		else
+			switch_mm_0460(next);
+	}
+}
+
+#define deactivate_mm(tsk,mm)	do { } while (0)
+
+static inline void activate_mm(struct mm_struct *prev_mm,
+			       struct mm_struct *next_mm)
+{
+	next_mm->context = virt_to_phys(next_mm->pgd);
+
+	if (CPU_IS_020_OR_030)
+		switch_mm_0230(next_mm);
+	else
+		switch_mm_0460(next_mm);
+}
+
+#else  /* CONFIG_SUN3 */
+#include <asm/sun3mmu.h>
+#include <linux/sched.h>
+
+extern unsigned long get_free_context(struct mm_struct *mm);
+extern void clear_context(unsigned long context);
+
+/* set the context for a new task to unmapped */
+static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+	mm->context = SUN3_INVALID_CONTEXT;
+	return 0;
+}
+
+/* find the context given to this process, and if it hasn't already
+   got one, go get one for it. */
+static inline void get_mmu_context(struct mm_struct *mm)
+{
+	if(mm->context == SUN3_INVALID_CONTEXT)
+		mm->context = get_free_context(mm);
+}
+
+/* flush context if allocated... */
+static inline void destroy_context(struct mm_struct *mm)
+{
+	if(mm->context != SUN3_INVALID_CONTEXT)
+		clear_context(mm->context);
+}
+
+static inline void activate_context(struct mm_struct *mm)
+{
+	get_mmu_context(mm);
+	sun3_put_context(mm->context);
+}
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
+{
+	activate_context(tsk->mm);
+}
+
+#define deactivate_mm(tsk,mm)	do { } while (0)
+
+static inline void activate_mm(struct mm_struct *prev_mm,
+			       struct mm_struct *next_mm)
+{
+	activate_context(next_mm);
+}
+
+#endif
+#else /* !CONFIG_MMU */
+
+static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+	return 0;
+}
+
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
+{
+}
+
+#define destroy_context(mm)	do { } while (0)
+#define deactivate_mm(tsk,mm)	do { } while (0)
+
+static inline void activate_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm)
+{
+}
+
+#endif /* CONFIG_MMU */
+#endif /* __M68K_MMU_CONTEXT_H */
diff --git a/arch/m68k/include/asm/mmu_context_mm.h b/arch/m68k/include/asm/mmu_context_mm.h
deleted file mode 100644
index 894dacb..0000000
--- a/arch/m68k/include/asm/mmu_context_mm.h
+++ /dev/null
@@ -1,154 +0,0 @@
-#ifndef __M68K_MMU_CONTEXT_H
-#define __M68K_MMU_CONTEXT_H
-
-#include <asm-generic/mm_hooks.h>
-
-static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
-{
-}
-
-#ifndef CONFIG_SUN3
-
-#include <asm/setup.h>
-#include <asm/page.h>
-#include <asm/pgalloc.h>
-
-static inline int init_new_context(struct task_struct *tsk,
-				   struct mm_struct *mm)
-{
-	mm->context = virt_to_phys(mm->pgd);
-	return 0;
-}
-
-#define destroy_context(mm)		do { } while(0)
-
-static inline void switch_mm_0230(struct mm_struct *mm)
-{
-	unsigned long crp[2] = {
-		0x80000000 | _PAGE_TABLE, mm->context
-	};
-	unsigned long tmp;
-
-	asm volatile (".chip 68030");
-
-	/* flush MC68030/MC68020 caches (they are virtually addressed) */
-	asm volatile (
-		"movec %%cacr,%0;"
-		"orw %1,%0; "
-		"movec %0,%%cacr"
-		: "=d" (tmp) : "di" (FLUSH_I_AND_D));
-
-	/* Switch the root pointer. For a 030-only kernel,
-	 * avoid flushing the whole ATC, we only need to
-	 * flush the user entries. The 68851 does this by
-	 * itself. Avoid a runtime check here.
-	 */
-	asm volatile (
-#ifdef CPU_M68030_ONLY
-		"pmovefd %0,%%crp; "
-		"pflush #0,#4"
-#else
-		"pmove %0,%%crp"
-#endif
-		: : "m" (crp[0]));
-
-	asm volatile (".chip 68k");
-}
-
-static inline void switch_mm_0460(struct mm_struct *mm)
-{
-	asm volatile (".chip 68040");
-
-	/* flush address translation cache (user entries) */
-	asm volatile ("pflushan");
-
-	/* switch the root pointer */
-	asm volatile ("movec %0,%%urp" : : "r" (mm->context));
-
-	if (CPU_IS_060) {
-		unsigned long tmp;
-
-		/* clear user entries in the branch cache */
-		asm volatile (
-			"movec %%cacr,%0; "
-		        "orl %1,%0; "
-		        "movec %0,%%cacr"
-			: "=d" (tmp): "di" (0x00200000));
-	}
-
-	asm volatile (".chip 68k");
-}
-
-static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
-{
-	if (prev != next) {
-		if (CPU_IS_020_OR_030)
-			switch_mm_0230(next);
-		else
-			switch_mm_0460(next);
-	}
-}
-
-#define deactivate_mm(tsk,mm)	do { } while (0)
-
-static inline void activate_mm(struct mm_struct *prev_mm,
-			       struct mm_struct *next_mm)
-{
-	next_mm->context = virt_to_phys(next_mm->pgd);
-
-	if (CPU_IS_020_OR_030)
-		switch_mm_0230(next_mm);
-	else
-		switch_mm_0460(next_mm);
-}
-
-#else  /* CONFIG_SUN3 */
-#include <asm/sun3mmu.h>
-#include <linux/sched.h>
-
-extern unsigned long get_free_context(struct mm_struct *mm);
-extern void clear_context(unsigned long context);
-
-/* set the context for a new task to unmapped */
-static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-{
-	mm->context = SUN3_INVALID_CONTEXT;
-	return 0;
-}
-
-/* find the context given to this process, and if it hasn't already
-   got one, go get one for it. */
-static inline void get_mmu_context(struct mm_struct *mm)
-{
-	if(mm->context == SUN3_INVALID_CONTEXT)
-		mm->context = get_free_context(mm);
-}
-
-/* flush context if allocated... */
-static inline void destroy_context(struct mm_struct *mm)
-{
-	if(mm->context != SUN3_INVALID_CONTEXT)
-		clear_context(mm->context);
-}
-
-static inline void activate_context(struct mm_struct *mm)
-{
-	get_mmu_context(mm);
-	sun3_put_context(mm->context);
-}
-
-static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
-{
-	activate_context(tsk->mm);
-}
-
-#define deactivate_mm(tsk,mm)	do { } while (0)
-
-static inline void activate_mm(struct mm_struct *prev_mm,
-			       struct mm_struct *next_mm)
-{
-	activate_context(next_mm);
-}
-
-#endif
-#endif
diff --git a/arch/m68k/include/asm/mmu_context_no.h b/arch/m68k/include/asm/mmu_context_no.h
deleted file mode 100644
index 9ccee42..0000000
--- a/arch/m68k/include/asm/mmu_context_no.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef __M68KNOMMU_MMU_CONTEXT_H
-#define __M68KNOMMU_MMU_CONTEXT_H
-
-#include <asm/setup.h>
-#include <asm/page.h>
-#include <asm/pgalloc.h>
-#include <asm-generic/mm_hooks.h>
-
-static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
-{
-}
-
-static inline int
-init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-{
-	// mm->context = virt_to_phys(mm->pgd);
-	return(0);
-}
-
-#define destroy_context(mm)		do { } while(0)
-
-static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
-{
-}
-
-#define deactivate_mm(tsk,mm)	do { } while (0)
-
-static inline void activate_mm(struct mm_struct *prev_mm,
-			       struct mm_struct *next_mm)
-{
-}
-
-#endif
diff --git a/arch/m68k/include/asm/mmu_mm.h b/arch/m68k/include/asm/mmu_mm.h
deleted file mode 100644
index ccd36d2..0000000
--- a/arch/m68k/include/asm/mmu_mm.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __MMU_H
-#define __MMU_H
-
-/* Default "unsigned long" context */
-typedef unsigned long mm_context_t;
-
-#endif
diff --git a/arch/m68k/include/asm/mmu_no.h b/arch/m68k/include/asm/mmu_no.h
deleted file mode 100644
index e2da1e6..0000000
--- a/arch/m68k/include/asm/mmu_no.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef __M68KNOMMU_MMU_H
-#define __M68KNOMMU_MMU_H
-
-/* Copyright (C) 2002, David McCullough <davidm@snapgear.com> */
-
-typedef struct {
-	unsigned long		end_brk;
-} mm_context_t;
-
-#endif /* __M68KNOMMU_MMU_H */
diff --git a/arch/m68k/include/asm/module.h b/arch/m68k/include/asm/module.h
index 79b59d13..5f21e11 100644
--- a/arch/m68k/include/asm/module.h
+++ b/arch/m68k/include/asm/module.h
@@ -1,5 +1,48 @@
-#ifdef __uClinux__
-#include "module_no.h"
+#ifndef _ASM_M68K_MODULE_H
+#define _ASM_M68K_MODULE_H
+
+#ifdef CONFIG_MMU
+
+struct mod_arch_specific {
+	struct m68k_fixup_info *fixup_start, *fixup_end;
+};
+
+#define MODULE_ARCH_INIT {				\
+	.fixup_start		= __start_fixup,	\
+	.fixup_end		= __stop_fixup,		\
+}
+
+
+enum m68k_fixup_type {
+	m68k_fixup_memoffset,
+	m68k_fixup_vnode_shift,
+};
+
+struct m68k_fixup_info {
+	enum m68k_fixup_type type;
+	void *addr;
+};
+
+#define m68k_fixup(type, addr)			\
+	"	.section \".m68k_fixup\",\"aw\"\n"	\
+	"	.long " #type "," #addr "\n"	\
+	"	.previous\n"
+
+extern struct m68k_fixup_info __start_fixup[], __stop_fixup[];
+
+struct module;
+extern void module_fixup(struct module *mod, struct m68k_fixup_info *start,
+			 struct m68k_fixup_info *end);
+
 #else
-#include "module_mm.h"
-#endif
+
+struct mod_arch_specific {
+};
+
+#endif /* CONFIG_MMU */
+
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Sym Elf32_Sym
+#define Elf_Ehdr Elf32_Ehdr
+
+#endif /* _ASM_M68K_MODULE_H */
diff --git a/arch/m68k/include/asm/module_mm.h b/arch/m68k/include/asm/module_mm.h
deleted file mode 100644
index 382d20a..0000000
--- a/arch/m68k/include/asm/module_mm.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef _ASM_M68K_MODULE_H
-#define _ASM_M68K_MODULE_H
-
-struct mod_arch_specific {
-	struct m68k_fixup_info *fixup_start, *fixup_end;
-};
-
-#define MODULE_ARCH_INIT {				\
-	.fixup_start		= __start_fixup,	\
-	.fixup_end		= __stop_fixup,		\
-}
-
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Ehdr Elf32_Ehdr
-
-
-enum m68k_fixup_type {
-	m68k_fixup_memoffset,
-	m68k_fixup_vnode_shift,
-};
-
-struct m68k_fixup_info {
-	enum m68k_fixup_type type;
-	void *addr;
-};
-
-#define m68k_fixup(type, addr)			\
-	"	.section \".m68k_fixup\",\"aw\"\n"	\
-	"	.long " #type "," #addr "\n"	\
-	"	.previous\n"
-
-extern struct m68k_fixup_info __start_fixup[], __stop_fixup[];
-
-struct module;
-extern void module_fixup(struct module *mod, struct m68k_fixup_info *start,
-			 struct m68k_fixup_info *end);
-
-#endif /* _ASM_M68K_MODULE_H */
diff --git a/arch/m68k/include/asm/module_no.h b/arch/m68k/include/asm/module_no.h
deleted file mode 100644
index 2e45ab5..0000000
--- a/arch/m68k/include/asm/module_no.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef ASM_M68KNOMMU_MODULE_H
-#define ASM_M68KNOMMU_MODULE_H
-
-struct mod_arch_specific {
-};
-
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Ehdr Elf32_Ehdr
-
-#endif /* ASM_M68KNOMMU_MODULE_H */
diff --git a/arch/m68k/include/asm/page_offset.h b/arch/m68k/include/asm/page_offset.h
index 66455c8..1780152 100644
--- a/arch/m68k/include/asm/page_offset.h
+++ b/arch/m68k/include/asm/page_offset.h
@@ -1,5 +1,11 @@
-#ifdef __uClinux__
-#include "page_offset_no.h"
+/* This handles the memory map.. */
+
+#ifdef CONFIG_MMU
+#ifndef CONFIG_SUN3
+#define PAGE_OFFSET_RAW		0x00000000
 #else
-#include "page_offset_mm.h"
+#define PAGE_OFFSET_RAW		0x0E000000
+#endif
+#else
+#define	PAGE_OFFSET_RAW		CONFIG_RAMBASE
 #endif
diff --git a/arch/m68k/include/asm/page_offset_mm.h b/arch/m68k/include/asm/page_offset_mm.h
deleted file mode 100644
index 1cbdb7f..0000000
--- a/arch/m68k/include/asm/page_offset_mm.h
+++ /dev/null
@@ -1,8 +0,0 @@
-
-/* This handles the memory map.. */
-#ifndef CONFIG_SUN3
-#define PAGE_OFFSET_RAW		0x00000000
-#else
-#define PAGE_OFFSET_RAW		0x0E000000
-#endif
-
diff --git a/arch/m68k/include/asm/page_offset_no.h b/arch/m68k/include/asm/page_offset_no.h
deleted file mode 100644
index d4e73e0..0000000
--- a/arch/m68k/include/asm/page_offset_no.h
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-/* This handles the memory map.. */
-#define	PAGE_OFFSET_RAW		CONFIG_RAMBASE
-
diff --git a/arch/m68k/include/asm/pci.h b/arch/m68k/include/asm/pci.h
index dbea953..4ad0aea 100644
--- a/arch/m68k/include/asm/pci.h
+++ b/arch/m68k/include/asm/pci.h
@@ -1,5 +1,12 @@
-#ifdef __uClinux__
-#include "pci_no.h"
-#else
-#include "pci_mm.h"
-#endif
+#ifndef _ASM_M68K_PCI_H
+#define _ASM_M68K_PCI_H
+
+#include <asm-generic/pci-dma-compat.h>
+
+/* The PCI address space does equal the physical memory
+ * address space.  The networking and block device layers use
+ * this boolean for bounce buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS	(1)
+
+#endif /* _ASM_M68K_PCI_H */
diff --git a/arch/m68k/include/asm/pci_mm.h b/arch/m68k/include/asm/pci_mm.h
deleted file mode 100644
index 4ad0aea..0000000
--- a/arch/m68k/include/asm/pci_mm.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _ASM_M68K_PCI_H
-#define _ASM_M68K_PCI_H
-
-#include <asm-generic/pci-dma-compat.h>
-
-/* The PCI address space does equal the physical memory
- * address space.  The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS	(1)
-
-#endif /* _ASM_M68K_PCI_H */
diff --git a/arch/m68k/include/asm/pci_no.h b/arch/m68k/include/asm/pci_no.h
deleted file mode 100644
index 9abbc03..0000000
--- a/arch/m68k/include/asm/pci_no.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef M68KNOMMU_PCI_H
-#define	M68KNOMMU_PCI_H
-
-#include <asm/pci_mm.h>
-
-#ifdef CONFIG_COMEMPCI
-/*
- *	These are pretty much arbitary with the CoMEM implementation.
- *	We have the whole address space to ourselves.
- */
-#define PCIBIOS_MIN_IO		0x100
-#define PCIBIOS_MIN_MEM		0x00010000
-
-#define pcibios_scan_all_fns(a, b)	0
-
-/*
- * Return whether the given PCI device DMA address mask can
- * be supported properly.  For example, if your device can
- * only drive the low 24-bits during PCI bus mastering, then
- * you would pass 0x00ffffff as the mask to this function.
- */
-static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
-{
-	return 1;
-}
-
-#endif /* CONFIG_COMEMPCI */
-
-#endif /* M68KNOMMU_PCI_H */
diff --git a/arch/m68k/include/asm/pgalloc.h b/arch/m68k/include/asm/pgalloc.h
index 059cb73..c294aad 100644
--- a/arch/m68k/include/asm/pgalloc.h
+++ b/arch/m68k/include/asm/pgalloc.h
@@ -1,5 +1,19 @@
-#ifdef __uClinux__
-#include "pgalloc_no.h"
+#ifndef M68K_PGALLOC_H
+#define M68K_PGALLOC_H
+
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <asm/setup.h>
+
+#ifdef CONFIG_MMU
+#include <asm/virtconvert.h>
+#ifdef CONFIG_SUN3
+#include <asm/sun3_pgalloc.h>
 #else
-#include "pgalloc_mm.h"
+#include <asm/motorola_pgalloc.h>
 #endif
+
+extern void m68k_setup_node(int node);
+#endif
+
+#endif /* M68K_PGALLOC_H */
diff --git a/arch/m68k/include/asm/pgalloc_mm.h b/arch/m68k/include/asm/pgalloc_mm.h
deleted file mode 100644
index 4cb1a57..0000000
--- a/arch/m68k/include/asm/pgalloc_mm.h
+++ /dev/null
@@ -1,19 +0,0 @@
-
-#ifndef M68K_PGALLOC_H
-#define M68K_PGALLOC_H
-
-#include <linux/mm.h>
-#include <linux/highmem.h>
-#include <asm/setup.h>
-#include <asm/virtconvert.h>
-
-
-#ifdef CONFIG_SUN3
-#include <asm/sun3_pgalloc.h>
-#else
-#include <asm/motorola_pgalloc.h>
-#endif
-
-extern void m68k_setup_node(int node);
-
-#endif /* M68K_PGALLOC_H */
diff --git a/arch/m68k/include/asm/pgalloc_no.h b/arch/m68k/include/asm/pgalloc_no.h
deleted file mode 100644
index d6352f6..0000000
--- a/arch/m68k/include/asm/pgalloc_no.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _M68KNOMMU_PGALLOC_H
-#define _M68KNOMMU_PGALLOC_H
-
-#include <asm/setup.h>
-
-#define check_pgt_cache()	do { } while (0)
-
-#endif /* _M68KNOMMU_PGALLOC_H */
diff --git a/arch/m68k/include/asm/pgtable_no.h b/arch/m68k/include/asm/pgtable_no.h
index 4625101..bf86b29 100644
--- a/arch/m68k/include/asm/pgtable_no.h
+++ b/arch/m68k/include/asm/pgtable_no.h
@@ -67,4 +67,6 @@
 
 #include <asm-generic/pgtable.h>
 
+#define check_pgt_cache()	do { } while (0)
+
 #endif /* _M68KNOMMU_PGTABLE_H */
diff --git a/arch/m68k/include/asm/rtc.h b/arch/m68k/include/asm/rtc.h
index 5d3e038..a4d08ea 100644
--- a/arch/m68k/include/asm/rtc.h
+++ b/arch/m68k/include/asm/rtc.h
@@ -36,13 +36,16 @@
 	 * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
 	 * by the RTC when initially set to a non-zero value.
 	 */
-	mach_hwclk(0, time);
+	if (mach_hwclk)
+		mach_hwclk(0, time);
 	return RTC_24H;
 }
 
 static inline int set_rtc_time(struct rtc_time *time)
 {
-	return mach_hwclk(1, time);
+	if (mach_hwclk)
+		return mach_hwclk(1, time);
+	return -EINVAL;
 }
 
 static inline unsigned int get_rtc_ss(void)
diff --git a/arch/m68k/include/asm/scatterlist.h b/arch/m68k/include/asm/scatterlist.h
index b7e5286..e27ad90 100644
--- a/arch/m68k/include/asm/scatterlist.h
+++ b/arch/m68k/include/asm/scatterlist.h
@@ -1,5 +1,23 @@
-#ifdef __uClinux__
-#include "scatterlist_no.h"
-#else
-#include "scatterlist_mm.h"
+#ifndef _M68K_SCATTERLIST_H
+#define _M68K_SCATTERLIST_H
+
+#include <linux/types.h>
+
+struct scatterlist {
+#ifdef CONFIG_DEBUG_SG
+	unsigned long sg_magic;
 #endif
+	unsigned long page_link;
+	unsigned int offset;
+	unsigned int length;
+
+	dma_addr_t dma_address;	/* A place to hang host-specific addresses at. */
+};
+
+/* This is bogus and should go away. */
+#define ISA_DMA_THRESHOLD (0x00ffffff)
+
+#define sg_dma_address(sg)	((sg)->dma_address)
+#define sg_dma_len(sg)		((sg)->length)
+
+#endif /* !(_M68K_SCATTERLIST_H) */
diff --git a/arch/m68k/include/asm/scatterlist_mm.h b/arch/m68k/include/asm/scatterlist_mm.h
deleted file mode 100644
index d3a7a0e..0000000
--- a/arch/m68k/include/asm/scatterlist_mm.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef _M68K_SCATTERLIST_H
-#define _M68K_SCATTERLIST_H
-
-#include <linux/types.h>
-
-struct scatterlist {
-#ifdef CONFIG_DEBUG_SG
-	unsigned long sg_magic;
-#endif
-	unsigned long page_link;
-	unsigned int offset;
-	unsigned int length;
-
-	__u32 dma_address;	/* A place to hang host-specific addresses at. */
-};
-
-/* This is bogus and should go away. */
-#define ISA_DMA_THRESHOLD (0x00ffffff)
-
-#define sg_dma_address(sg)	((sg)->dma_address)
-#define sg_dma_len(sg)		((sg)->length)
-
-#endif /* !(_M68K_SCATTERLIST_H) */
diff --git a/arch/m68k/include/asm/scatterlist_no.h b/arch/m68k/include/asm/scatterlist_no.h
deleted file mode 100644
index afc4788..0000000
--- a/arch/m68k/include/asm/scatterlist_no.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef _M68KNOMMU_SCATTERLIST_H
-#define _M68KNOMMU_SCATTERLIST_H
-
-#include <linux/mm.h>
-#include <asm/types.h>
-
-struct scatterlist {
-#ifdef CONFIG_DEBUG_SG
-	unsigned long	sg_magic;
-#endif
-	unsigned long	page_link;
-	unsigned int	offset;
-	dma_addr_t	dma_address;
-	unsigned int	length;
-};
-
-#define sg_dma_address(sg)      ((sg)->dma_address)
-#define sg_dma_len(sg)          ((sg)->length)
-
-#define ISA_DMA_THRESHOLD	(0xffffffff)
-
-#endif /* !(_M68KNOMMU_SCATTERLIST_H) */
diff --git a/arch/m68k/include/asm/segment.h b/arch/m68k/include/asm/segment.h
index 82583bc..ee95921 100644
--- a/arch/m68k/include/asm/segment.h
+++ b/arch/m68k/include/asm/segment.h
@@ -1,5 +1,63 @@
-#ifdef __uClinux__
-#include "segment_no.h"
-#else
-#include "segment_mm.h"
+#ifndef _M68K_SEGMENT_H
+#define _M68K_SEGMENT_H
+
+/* define constants */
+/* Address spaces (FC0-FC2) */
+#define USER_DATA     (1)
+#ifndef __USER_DS
+#define __USER_DS     (USER_DATA)
 #endif
+#define USER_PROGRAM  (2)
+#define SUPER_DATA    (5)
+#ifndef __KERNEL_DS
+#define __KERNEL_DS   (SUPER_DATA)
+#endif
+#define SUPER_PROGRAM (6)
+#define CPU_SPACE     (7)
+
+#ifndef __ASSEMBLY__
+
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
+#define MAKE_MM_SEG(s)	((mm_segment_t) { (s) })
+#define USER_DS		MAKE_MM_SEG(__USER_DS)
+#define KERNEL_DS	MAKE_MM_SEG(__KERNEL_DS)
+
+/*
+ * Get/set the SFC/DFC registers for MOVES instructions
+ */
+
+static inline mm_segment_t get_fs(void)
+{
+#ifdef CONFIG_MMU
+	mm_segment_t _v;
+	__asm__ ("movec %/dfc,%0":"=r" (_v.seg):);
+
+	return _v;
+#else
+	return USER_DS;
+#endif
+}
+
+static inline mm_segment_t get_ds(void)
+{
+    /* return the supervisor data space code */
+    return KERNEL_DS;
+}
+
+static inline void set_fs(mm_segment_t val)
+{
+#ifdef CONFIG_MMU
+	__asm__ __volatile__ ("movec %0,%/sfc\n\t"
+			      "movec %0,%/dfc\n\t"
+			      : /* no outputs */ : "r" (val.seg) : "memory");
+#endif
+}
+
+#define segment_eq(a,b)	((a).seg == (b).seg)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _M68K_SEGMENT_H */
diff --git a/arch/m68k/include/asm/segment_mm.h b/arch/m68k/include/asm/segment_mm.h
deleted file mode 100644
index 7b0b2d3..0000000
--- a/arch/m68k/include/asm/segment_mm.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef _M68K_SEGMENT_H
-#define _M68K_SEGMENT_H
-
-/* define constants */
-/* Address spaces (FC0-FC2) */
-#define USER_DATA     (1)
-#ifndef __USER_DS
-#define __USER_DS     (USER_DATA)
-#endif
-#define USER_PROGRAM  (2)
-#define SUPER_DATA    (5)
-#ifndef __KERNEL_DS
-#define __KERNEL_DS   (SUPER_DATA)
-#endif
-#define SUPER_PROGRAM (6)
-#define CPU_SPACE     (7)
-
-#ifndef __ASSEMBLY__
-
-typedef struct {
-	unsigned long seg;
-} mm_segment_t;
-
-#define MAKE_MM_SEG(s)	((mm_segment_t) { (s) })
-#define USER_DS		MAKE_MM_SEG(__USER_DS)
-#define KERNEL_DS	MAKE_MM_SEG(__KERNEL_DS)
-
-/*
- * Get/set the SFC/DFC registers for MOVES instructions
- */
-
-static inline mm_segment_t get_fs(void)
-{
-	mm_segment_t _v;
-	__asm__ ("movec %/dfc,%0":"=r" (_v.seg):);
-
-	return _v;
-}
-
-static inline mm_segment_t get_ds(void)
-{
-    /* return the supervisor data space code */
-    return KERNEL_DS;
-}
-
-static inline void set_fs(mm_segment_t val)
-{
-	__asm__ __volatile__ ("movec %0,%/sfc\n\t"
-			      "movec %0,%/dfc\n\t"
-			      : /* no outputs */ : "r" (val.seg) : "memory");
-}
-
-#define segment_eq(a,b)	((a).seg == (b).seg)
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _M68K_SEGMENT_H */
diff --git a/arch/m68k/include/asm/segment_no.h b/arch/m68k/include/asm/segment_no.h
deleted file mode 100644
index 42318eb..0000000
--- a/arch/m68k/include/asm/segment_no.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef _M68K_SEGMENT_H
-#define _M68K_SEGMENT_H
-
-/* define constants */
-/* Address spaces (FC0-FC2) */
-#define USER_DATA     (1)
-#ifndef __USER_DS
-#define __USER_DS     (USER_DATA)
-#endif
-#define USER_PROGRAM  (2)
-#define SUPER_DATA    (5)
-#ifndef __KERNEL_DS
-#define __KERNEL_DS   (SUPER_DATA)
-#endif
-#define SUPER_PROGRAM (6)
-#define CPU_SPACE     (7)
-
-#ifndef __ASSEMBLY__
-
-typedef struct {
-	unsigned long seg;
-} mm_segment_t;
-
-#define MAKE_MM_SEG(s)	((mm_segment_t) { (s) })
-#define USER_DS		MAKE_MM_SEG(__USER_DS)
-#define KERNEL_DS	MAKE_MM_SEG(__KERNEL_DS)
-
-/*
- * Get/set the SFC/DFC registers for MOVES instructions
- */
-
-static inline mm_segment_t get_fs(void)
-{
-    return USER_DS;
-}
-
-static inline mm_segment_t get_ds(void)
-{
-    /* return the supervisor data space code */
-    return KERNEL_DS;
-}
-
-static inline void set_fs(mm_segment_t val)
-{
-}
-
-#define segment_eq(a,b)	((a).seg == (b).seg)
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _M68K_SEGMENT_H */
diff --git a/arch/m68k/include/asm/timex.h b/arch/m68k/include/asm/timex.h
index 7197629..b87f2f2 100644
--- a/arch/m68k/include/asm/timex.h
+++ b/arch/m68k/include/asm/timex.h
@@ -1,5 +1,18 @@
-#ifdef __uClinux__
-#include "timex_no.h"
-#else
-#include "timex_mm.h"
+/*
+ * linux/include/asm-m68k/timex.h
+ *
+ * m68k architecture timex specifications
+ */
+#ifndef _ASMm68k_TIMEX_H
+#define _ASMm68k_TIMEX_H
+
+#define CLOCK_TICK_RATE	1193180 /* Underlying HZ */
+
+typedef unsigned long cycles_t;
+
+static inline cycles_t get_cycles(void)
+{
+	return 0;
+}
+
 #endif
diff --git a/arch/m68k/include/asm/timex_mm.h b/arch/m68k/include/asm/timex_mm.h
deleted file mode 100644
index b87f2f2..0000000
--- a/arch/m68k/include/asm/timex_mm.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * linux/include/asm-m68k/timex.h
- *
- * m68k architecture timex specifications
- */
-#ifndef _ASMm68k_TIMEX_H
-#define _ASMm68k_TIMEX_H
-
-#define CLOCK_TICK_RATE	1193180 /* Underlying HZ */
-
-typedef unsigned long cycles_t;
-
-static inline cycles_t get_cycles(void)
-{
-	return 0;
-}
-
-#endif
diff --git a/arch/m68k/include/asm/timex_no.h b/arch/m68k/include/asm/timex_no.h
deleted file mode 100644
index 109050f..0000000
--- a/arch/m68k/include/asm/timex_no.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * linux/include/asm-m68knommu/timex.h
- *
- * m68knommu architecture timex specifications
- */
-#ifndef _ASM_M68KNOMMU_TIMEX_H
-#define _ASM_M68KNOMMU_TIMEX_H
-
-#ifdef CONFIG_COLDFIRE
-#include <asm/coldfire.h>
-#define CLOCK_TICK_RATE	MCF_CLK
-#else
-#define CLOCK_TICK_RATE	1193180 /* Underlying HZ */
-#endif
-
-typedef unsigned long cycles_t;
-
-static inline cycles_t get_cycles(void)
-{
-	return 0;
-}
-
-#endif
diff --git a/arch/m68k/include/asm/tlbflush.h b/arch/m68k/include/asm/tlbflush.h
index b6f93b3..a6b4ed4 100644
--- a/arch/m68k/include/asm/tlbflush.h
+++ b/arch/m68k/include/asm/tlbflush.h
@@ -1,5 +1,267 @@
-#ifdef __uClinux__
-#include "tlbflush_no.h"
+#ifndef _M68K_TLBFLUSH_H
+#define _M68K_TLBFLUSH_H
+
+#ifdef CONFIG_MMU
+#ifndef CONFIG_SUN3
+
+#include <asm/current.h>
+
+static inline void flush_tlb_kernel_page(void *addr)
+{
+	if (CPU_IS_040_OR_060) {
+		mm_segment_t old_fs = get_fs();
+		set_fs(KERNEL_DS);
+		__asm__ __volatile__(".chip 68040\n\t"
+				     "pflush (%0)\n\t"
+				     ".chip 68k"
+				     : : "a" (addr));
+		set_fs(old_fs);
+	} else if (CPU_IS_020_OR_030)
+		__asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr));
+}
+
+/*
+ * flush all user-space atc entries.
+ */
+static inline void __flush_tlb(void)
+{
+	if (CPU_IS_040_OR_060)
+		__asm__ __volatile__(".chip 68040\n\t"
+				     "pflushan\n\t"
+				     ".chip 68k");
+	else if (CPU_IS_020_OR_030)
+		__asm__ __volatile__("pflush #0,#4");
+}
+
+static inline void __flush_tlb040_one(unsigned long addr)
+{
+	__asm__ __volatile__(".chip 68040\n\t"
+			     "pflush (%0)\n\t"
+			     ".chip 68k"
+			     : : "a" (addr));
+}
+
+static inline void __flush_tlb_one(unsigned long addr)
+{
+	if (CPU_IS_040_OR_060)
+		__flush_tlb040_one(addr);
+	else if (CPU_IS_020_OR_030)
+		__asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr));
+}
+
+#define flush_tlb() __flush_tlb()
+
+/*
+ * flush all atc entries (both kernel and user-space entries).
+ */
+static inline void flush_tlb_all(void)
+{
+	if (CPU_IS_040_OR_060)
+		__asm__ __volatile__(".chip 68040\n\t"
+				     "pflusha\n\t"
+				     ".chip 68k");
+	else if (CPU_IS_020_OR_030)
+		__asm__ __volatile__("pflusha");
+}
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+	if (mm == current->active_mm)
+		__flush_tlb();
+}
+
+static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
+{
+	if (vma->vm_mm == current->active_mm) {
+		mm_segment_t old_fs = get_fs();
+		set_fs(USER_DS);
+		__flush_tlb_one(addr);
+		set_fs(old_fs);
+	}
+}
+
+static inline void flush_tlb_range(struct vm_area_struct *vma,
+				   unsigned long start, unsigned long end)
+{
+	if (vma->vm_mm == current->active_mm)
+		__flush_tlb();
+}
+
+static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+	flush_tlb_all();
+}
+
 #else
-#include "tlbflush_mm.h"
+
+
+/* Reserved PMEGs. */
+extern char sun3_reserved_pmeg[SUN3_PMEGS_NUM];
+extern unsigned long pmeg_vaddr[SUN3_PMEGS_NUM];
+extern unsigned char pmeg_alloc[SUN3_PMEGS_NUM];
+extern unsigned char pmeg_ctx[SUN3_PMEGS_NUM];
+
+/* Flush all userspace mappings one by one...  (why no flush command,
+   sun?) */
+static inline void flush_tlb_all(void)
+{
+       unsigned long addr;
+       unsigned char ctx, oldctx;
+
+       oldctx = sun3_get_context();
+       for(addr = 0x00000000; addr < TASK_SIZE; addr += SUN3_PMEG_SIZE) {
+	       for(ctx = 0; ctx < 8; ctx++) {
+		       sun3_put_context(ctx);
+		       sun3_put_segmap(addr, SUN3_INVALID_PMEG);
+	       }
+       }
+
+       sun3_put_context(oldctx);
+       /* erase all of the userspace pmeg maps, we've clobbered them
+	  all anyway */
+       for(addr = 0; addr < SUN3_INVALID_PMEG; addr++) {
+	       if(pmeg_alloc[addr] == 1) {
+		       pmeg_alloc[addr] = 0;
+		       pmeg_ctx[addr] = 0;
+		       pmeg_vaddr[addr] = 0;
+	       }
+       }
+
+}
+
+/* Clear user TLB entries within the context named in mm */
+static inline void flush_tlb_mm (struct mm_struct *mm)
+{
+     unsigned char oldctx;
+     unsigned char seg;
+     unsigned long i;
+
+     oldctx = sun3_get_context();
+     sun3_put_context(mm->context);
+
+     for(i = 0; i < TASK_SIZE; i += SUN3_PMEG_SIZE) {
+	     seg = sun3_get_segmap(i);
+	     if(seg == SUN3_INVALID_PMEG)
+		     continue;
+
+	     sun3_put_segmap(i, SUN3_INVALID_PMEG);
+	     pmeg_alloc[seg] = 0;
+	     pmeg_ctx[seg] = 0;
+	     pmeg_vaddr[seg] = 0;
+     }
+
+     sun3_put_context(oldctx);
+
+}
+
+/* Flush a single TLB page. In this case, we're limited to flushing a
+   single PMEG */
+static inline void flush_tlb_page (struct vm_area_struct *vma,
+				   unsigned long addr)
+{
+	unsigned char oldctx;
+	unsigned char i;
+
+	oldctx = sun3_get_context();
+	sun3_put_context(vma->vm_mm->context);
+	addr &= ~SUN3_PMEG_MASK;
+	if((i = sun3_get_segmap(addr)) != SUN3_INVALID_PMEG)
+	{
+		pmeg_alloc[i] = 0;
+		pmeg_ctx[i] = 0;
+		pmeg_vaddr[i] = 0;
+		sun3_put_segmap (addr,  SUN3_INVALID_PMEG);
+	}
+	sun3_put_context(oldctx);
+
+}
+/* Flush a range of pages from TLB. */
+
+static inline void flush_tlb_range (struct vm_area_struct *vma,
+		      unsigned long start, unsigned long end)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned char seg, oldctx;
+
+	start &= ~SUN3_PMEG_MASK;
+
+	oldctx = sun3_get_context();
+	sun3_put_context(mm->context);
+
+	while(start < end)
+	{
+		if((seg = sun3_get_segmap(start)) == SUN3_INVALID_PMEG)
+		     goto next;
+		if(pmeg_ctx[seg] == mm->context) {
+			pmeg_alloc[seg] = 0;
+			pmeg_ctx[seg] = 0;
+			pmeg_vaddr[seg] = 0;
+		}
+		sun3_put_segmap(start, SUN3_INVALID_PMEG);
+	next:
+		start += SUN3_PMEG_SIZE;
+	}
+}
+
+static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+	flush_tlb_all();
+}
+
+/* Flush kernel page from TLB. */
+static inline void flush_tlb_kernel_page (unsigned long addr)
+{
+	sun3_put_segmap (addr & ~(SUN3_PMEG_SIZE - 1), SUN3_INVALID_PMEG);
+}
+
 #endif
+
+#else /* !CONFIG_MMU */
+
+/*
+ * flush all user-space atc entries.
+ */
+static inline void __flush_tlb(void)
+{
+	BUG();
+}
+
+static inline void __flush_tlb_one(unsigned long addr)
+{
+	BUG();
+}
+
+#define flush_tlb() __flush_tlb()
+
+/*
+ * flush all atc entries (both kernel and user-space entries).
+ */
+static inline void flush_tlb_all(void)
+{
+	BUG();
+}
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+	BUG();
+}
+
+static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
+{
+	BUG();
+}
+
+static inline void flush_tlb_range(struct mm_struct *mm,
+				   unsigned long start, unsigned long end)
+{
+	BUG();
+}
+
+static inline void flush_tlb_kernel_page(unsigned long addr)
+{
+	BUG();
+}
+
+#endif /* CONFIG_MMU */
+
+#endif /* _M68K_TLBFLUSH_H */
diff --git a/arch/m68k/include/asm/tlbflush_mm.h b/arch/m68k/include/asm/tlbflush_mm.h
deleted file mode 100644
index acb6bf2..0000000
--- a/arch/m68k/include/asm/tlbflush_mm.h
+++ /dev/null
@@ -1,219 +0,0 @@
-#ifndef _M68K_TLBFLUSH_H
-#define _M68K_TLBFLUSH_H
-
-
-#ifndef CONFIG_SUN3
-
-#include <asm/current.h>
-
-static inline void flush_tlb_kernel_page(void *addr)
-{
-	if (CPU_IS_040_OR_060) {
-		mm_segment_t old_fs = get_fs();
-		set_fs(KERNEL_DS);
-		__asm__ __volatile__(".chip 68040\n\t"
-				     "pflush (%0)\n\t"
-				     ".chip 68k"
-				     : : "a" (addr));
-		set_fs(old_fs);
-	} else if (CPU_IS_020_OR_030)
-		__asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr));
-}
-
-/*
- * flush all user-space atc entries.
- */
-static inline void __flush_tlb(void)
-{
-	if (CPU_IS_040_OR_060)
-		__asm__ __volatile__(".chip 68040\n\t"
-				     "pflushan\n\t"
-				     ".chip 68k");
-	else if (CPU_IS_020_OR_030)
-		__asm__ __volatile__("pflush #0,#4");
-}
-
-static inline void __flush_tlb040_one(unsigned long addr)
-{
-	__asm__ __volatile__(".chip 68040\n\t"
-			     "pflush (%0)\n\t"
-			     ".chip 68k"
-			     : : "a" (addr));
-}
-
-static inline void __flush_tlb_one(unsigned long addr)
-{
-	if (CPU_IS_040_OR_060)
-		__flush_tlb040_one(addr);
-	else if (CPU_IS_020_OR_030)
-		__asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr));
-}
-
-#define flush_tlb() __flush_tlb()
-
-/*
- * flush all atc entries (both kernel and user-space entries).
- */
-static inline void flush_tlb_all(void)
-{
-	if (CPU_IS_040_OR_060)
-		__asm__ __volatile__(".chip 68040\n\t"
-				     "pflusha\n\t"
-				     ".chip 68k");
-	else if (CPU_IS_020_OR_030)
-		__asm__ __volatile__("pflusha");
-}
-
-static inline void flush_tlb_mm(struct mm_struct *mm)
-{
-	if (mm == current->active_mm)
-		__flush_tlb();
-}
-
-static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
-{
-	if (vma->vm_mm == current->active_mm) {
-		mm_segment_t old_fs = get_fs();
-		set_fs(USER_DS);
-		__flush_tlb_one(addr);
-		set_fs(old_fs);
-	}
-}
-
-static inline void flush_tlb_range(struct vm_area_struct *vma,
-				   unsigned long start, unsigned long end)
-{
-	if (vma->vm_mm == current->active_mm)
-		__flush_tlb();
-}
-
-static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end)
-{
-	flush_tlb_all();
-}
-
-#else
-
-
-/* Reserved PMEGs. */
-extern char sun3_reserved_pmeg[SUN3_PMEGS_NUM];
-extern unsigned long pmeg_vaddr[SUN3_PMEGS_NUM];
-extern unsigned char pmeg_alloc[SUN3_PMEGS_NUM];
-extern unsigned char pmeg_ctx[SUN3_PMEGS_NUM];
-
-/* Flush all userspace mappings one by one...  (why no flush command,
-   sun?) */
-static inline void flush_tlb_all(void)
-{
-       unsigned long addr;
-       unsigned char ctx, oldctx;
-
-       oldctx = sun3_get_context();
-       for(addr = 0x00000000; addr < TASK_SIZE; addr += SUN3_PMEG_SIZE) {
-	       for(ctx = 0; ctx < 8; ctx++) {
-		       sun3_put_context(ctx);
-		       sun3_put_segmap(addr, SUN3_INVALID_PMEG);
-	       }
-       }
-
-       sun3_put_context(oldctx);
-       /* erase all of the userspace pmeg maps, we've clobbered them
-	  all anyway */
-       for(addr = 0; addr < SUN3_INVALID_PMEG; addr++) {
-	       if(pmeg_alloc[addr] == 1) {
-		       pmeg_alloc[addr] = 0;
-		       pmeg_ctx[addr] = 0;
-		       pmeg_vaddr[addr] = 0;
-	       }
-       }
-
-}
-
-/* Clear user TLB entries within the context named in mm */
-static inline void flush_tlb_mm (struct mm_struct *mm)
-{
-     unsigned char oldctx;
-     unsigned char seg;
-     unsigned long i;
-
-     oldctx = sun3_get_context();
-     sun3_put_context(mm->context);
-
-     for(i = 0; i < TASK_SIZE; i += SUN3_PMEG_SIZE) {
-	     seg = sun3_get_segmap(i);
-	     if(seg == SUN3_INVALID_PMEG)
-		     continue;
-
-	     sun3_put_segmap(i, SUN3_INVALID_PMEG);
-	     pmeg_alloc[seg] = 0;
-	     pmeg_ctx[seg] = 0;
-	     pmeg_vaddr[seg] = 0;
-     }
-
-     sun3_put_context(oldctx);
-
-}
-
-/* Flush a single TLB page. In this case, we're limited to flushing a
-   single PMEG */
-static inline void flush_tlb_page (struct vm_area_struct *vma,
-				   unsigned long addr)
-{
-	unsigned char oldctx;
-	unsigned char i;
-
-	oldctx = sun3_get_context();
-	sun3_put_context(vma->vm_mm->context);
-	addr &= ~SUN3_PMEG_MASK;
-	if((i = sun3_get_segmap(addr)) != SUN3_INVALID_PMEG)
-	{
-		pmeg_alloc[i] = 0;
-		pmeg_ctx[i] = 0;
-		pmeg_vaddr[i] = 0;
-		sun3_put_segmap (addr,  SUN3_INVALID_PMEG);
-	}
-	sun3_put_context(oldctx);
-
-}
-/* Flush a range of pages from TLB. */
-
-static inline void flush_tlb_range (struct vm_area_struct *vma,
-		      unsigned long start, unsigned long end)
-{
-	struct mm_struct *mm = vma->vm_mm;
-	unsigned char seg, oldctx;
-
-	start &= ~SUN3_PMEG_MASK;
-
-	oldctx = sun3_get_context();
-	sun3_put_context(mm->context);
-
-	while(start < end)
-	{
-		if((seg = sun3_get_segmap(start)) == SUN3_INVALID_PMEG)
-		     goto next;
-		if(pmeg_ctx[seg] == mm->context) {
-			pmeg_alloc[seg] = 0;
-			pmeg_ctx[seg] = 0;
-			pmeg_vaddr[seg] = 0;
-		}
-		sun3_put_segmap(start, SUN3_INVALID_PMEG);
-	next:
-		start += SUN3_PMEG_SIZE;
-	}
-}
-
-static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end)
-{
-	flush_tlb_all();
-}
-
-/* Flush kernel page from TLB. */
-static inline void flush_tlb_kernel_page (unsigned long addr)
-{
-	sun3_put_segmap (addr & ~(SUN3_PMEG_SIZE - 1), SUN3_INVALID_PMEG);
-}
-
-#endif
-
-#endif /* _M68K_TLBFLUSH_H */
diff --git a/arch/m68k/include/asm/tlbflush_no.h b/arch/m68k/include/asm/tlbflush_no.h
deleted file mode 100644
index a470cfb..0000000
--- a/arch/m68k/include/asm/tlbflush_no.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef _M68KNOMMU_TLBFLUSH_H
-#define _M68KNOMMU_TLBFLUSH_H
-
-/*
- * Copyright (C) 2000 Lineo, David McCullough <davidm@uclinux.org>
- * Copyright (C) 2000-2002, Greg Ungerer <gerg@snapgear.com>
- */
-
-#include <asm/setup.h>
-
-/*
- * flush all user-space atc entries.
- */
-static inline void __flush_tlb(void)
-{
-	BUG();
-}
-
-static inline void __flush_tlb_one(unsigned long addr)
-{
-	BUG();
-}
-
-#define flush_tlb() __flush_tlb()
-
-/*
- * flush all atc entries (both kernel and user-space entries).
- */
-static inline void flush_tlb_all(void)
-{
-	BUG();
-}
-
-static inline void flush_tlb_mm(struct mm_struct *mm)
-{
-	BUG();
-}
-
-static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
-{
-	BUG();
-}
-
-static inline void flush_tlb_range(struct mm_struct *mm,
-				   unsigned long start, unsigned long end)
-{
-	BUG();
-}
-
-static inline void flush_tlb_kernel_page(unsigned long addr)
-{
-	BUG();
-}
-
-#endif /* _M68KNOMMU_TLBFLUSH_H */
diff --git a/arch/m68k/include/asm/ucontext.h b/arch/m68k/include/asm/ucontext.h
index b53cd16..e4e2266 100644
--- a/arch/m68k/include/asm/ucontext.h
+++ b/arch/m68k/include/asm/ucontext.h
@@ -1,5 +1,30 @@
-#ifdef __uClinux__
-#include "ucontext_no.h"
-#else
-#include "ucontext_mm.h"
+#ifndef _M68K_UCONTEXT_H
+#define _M68K_UCONTEXT_H
+
+typedef int greg_t;
+#define NGREG 18
+typedef greg_t gregset_t[NGREG];
+
+typedef struct fpregset {
+	int f_fpcntl[3];
+	int f_fpregs[8*3];
+} fpregset_t;
+
+struct mcontext {
+	int version;
+	gregset_t gregs;
+	fpregset_t fpregs;
+};
+
+#define MCONTEXT_VERSION 2
+
+struct ucontext {
+	unsigned long	  uc_flags;
+	struct ucontext  *uc_link;
+	stack_t		  uc_stack;
+	struct mcontext	  uc_mcontext;
+	unsigned long	  uc_filler[80];
+	sigset_t	  uc_sigmask;	/* mask last for extensibility */
+};
+
 #endif
diff --git a/arch/m68k/include/asm/ucontext_mm.h b/arch/m68k/include/asm/ucontext_mm.h
deleted file mode 100644
index e4e2266..0000000
--- a/arch/m68k/include/asm/ucontext_mm.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef _M68K_UCONTEXT_H
-#define _M68K_UCONTEXT_H
-
-typedef int greg_t;
-#define NGREG 18
-typedef greg_t gregset_t[NGREG];
-
-typedef struct fpregset {
-	int f_fpcntl[3];
-	int f_fpregs[8*3];
-} fpregset_t;
-
-struct mcontext {
-	int version;
-	gregset_t gregs;
-	fpregset_t fpregs;
-};
-
-#define MCONTEXT_VERSION 2
-
-struct ucontext {
-	unsigned long	  uc_flags;
-	struct ucontext  *uc_link;
-	stack_t		  uc_stack;
-	struct mcontext	  uc_mcontext;
-	unsigned long	  uc_filler[80];
-	sigset_t	  uc_sigmask;	/* mask last for extensibility */
-};
-
-#endif
diff --git a/arch/m68k/include/asm/ucontext_no.h b/arch/m68k/include/asm/ucontext_no.h
deleted file mode 100644
index 713a27f..0000000
--- a/arch/m68k/include/asm/ucontext_no.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef _M68KNOMMU_UCONTEXT_H
-#define _M68KNOMMU_UCONTEXT_H
-
-typedef int greg_t;
-#define NGREG 18
-typedef greg_t gregset_t[NGREG];
-
-typedef struct fpregset {
-	int f_pcr;
-	int f_psr;
-	int f_fpiaddr;
-	int f_fpregs[8][3];
-} fpregset_t;
-
-struct mcontext {
-	int version;
-	gregset_t gregs;
-	fpregset_t fpregs;
-};
-
-#define MCONTEXT_VERSION 2
-
-struct ucontext {
-	unsigned long	  uc_flags;
-	struct ucontext  *uc_link;
-	stack_t		  uc_stack;
-	struct mcontext	  uc_mcontext;
-	unsigned long	  uc_filler[80];
-	sigset_t	  uc_sigmask;	/* mask last for extensibility */
-};
-
-#endif
diff --git a/arch/m68k/include/asm/unaligned.h b/arch/m68k/include/asm/unaligned.h
index c640bba..019caa7 100644
--- a/arch/m68k/include/asm/unaligned.h
+++ b/arch/m68k/include/asm/unaligned.h
@@ -1,5 +1,25 @@
-#ifdef __uClinux__
-#include "unaligned_no.h"
+#ifndef _ASM_M68K_UNALIGNED_H
+#define _ASM_M68K_UNALIGNED_H
+
+
+#ifdef CONFIG_COLDFIRE
+#include <linux/unaligned/be_struct.h>
+#include <linux/unaligned/le_byteshift.h>
+#include <linux/unaligned/generic.h>
+
+#define get_unaligned	__get_unaligned_be
+#define put_unaligned	__put_unaligned_be
+
 #else
-#include "unaligned_mm.h"
+/*
+ * The m68k can do unaligned accesses itself. 
+ */
+#include <linux/unaligned/access_ok.h>
+#include <linux/unaligned/generic.h>
+
+#define get_unaligned	__get_unaligned_be
+#define put_unaligned	__put_unaligned_be
+
 #endif
+
+#endif /* _ASM_M68K_UNALIGNED_H */
diff --git a/arch/m68k/include/asm/unaligned_mm.h b/arch/m68k/include/asm/unaligned_mm.h
deleted file mode 100644
index 77698f2..0000000
--- a/arch/m68k/include/asm/unaligned_mm.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef _ASM_M68K_UNALIGNED_H
-#define _ASM_M68K_UNALIGNED_H
-
-/*
- * The m68k can do unaligned accesses itself.
- */
-#include <linux/unaligned/access_ok.h>
-#include <linux/unaligned/generic.h>
-
-#define get_unaligned	__get_unaligned_be
-#define put_unaligned	__put_unaligned_be
-
-#endif /* _ASM_M68K_UNALIGNED_H */
diff --git a/arch/m68k/include/asm/unaligned_no.h b/arch/m68k/include/asm/unaligned_no.h
deleted file mode 100644
index eb1ea4c..0000000
--- a/arch/m68k/include/asm/unaligned_no.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef _ASM_M68KNOMMU_UNALIGNED_H
-#define _ASM_M68KNOMMU_UNALIGNED_H
-
-
-#ifdef CONFIG_COLDFIRE
-#include <linux/unaligned/be_struct.h>
-#include <linux/unaligned/le_byteshift.h>
-#include <linux/unaligned/generic.h>
-
-#define get_unaligned	__get_unaligned_be
-#define put_unaligned	__put_unaligned_be
-
-#else
-/*
- * The m68k can do unaligned accesses itself. 
- */
-#include <linux/unaligned/access_ok.h>
-#include <linux/unaligned/generic.h>
-
-#define get_unaligned	__get_unaligned_be
-#define put_unaligned	__put_unaligned_be
-
-#endif
-
-#endif /* _ASM_M68KNOMMU_UNALIGNED_H */
diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c
index 7db4159..54d9807 100644
--- a/arch/m68k/kernel/time.c
+++ b/arch/m68k/kernel/time.c
@@ -18,6 +18,7 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/rtc.h>
+#include <linux/platform_device.h>
 
 #include <asm/machdep.h>
 #include <asm/io.h>
@@ -159,3 +160,20 @@
 }
 
 EXPORT_SYMBOL(do_settimeofday);
+
+
+static int __init rtc_init(void)
+{
+	struct platform_device *pdev;
+
+	if (!mach_hwclk)
+		return -ENODEV;
+
+	pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0);
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	return 0;
+}
+
+module_init(rtc_init);
diff --git a/arch/m68knommu/Makefile b/arch/m68knommu/Makefile
index fd0fb30..ce404bc 100644
--- a/arch/m68knommu/Makefile
+++ b/arch/m68knommu/Makefile
@@ -88,18 +88,18 @@
 #
 # Some CFLAG additions based on specific CPU type.
 #
-cflags-$(CONFIG_M5206)		:= -m5200
-cflags-$(CONFIG_M5206e)		:= -m5200
-cflags-$(CONFIG_M520x)		:= -m5307
+cflags-$(CONFIG_M5206)		:= $(call cc-option,-mcpu=5206,-m5200)
+cflags-$(CONFIG_M5206e)		:= $(call cc-option,-m5206e,-m5200)
+cflags-$(CONFIG_M520x)		:= $(call cc-option,-mcpu=5208,-m5200)
 cflags-$(CONFIG_M523x)		:= $(call cc-option,-mcpu=523x,-m5307)
-cflags-$(CONFIG_M5249)		:= -m5200
+cflags-$(CONFIG_M5249)		:= $(call cc-option,-mcpu=5249,-m5200)
 cflags-$(CONFIG_M5271)		:= $(call cc-option,-mcpu=5271,-m5307)
-cflags-$(CONFIG_M5272)		:= -m5307
+cflags-$(CONFIG_M5272)		:= $(call cc-option,-mcpu=5271,-m5200)
 cflags-$(CONFIG_M5275)		:= $(call cc-option,-mcpu=5275,-m5307)
 cflags-$(CONFIG_M528x)		:= $(call cc-option,-m528x,-m5307)
-cflags-$(CONFIG_M5307)		:= -m5307
+cflags-$(CONFIG_M5307)		:= $(call cc-option,-m5307,-m5200)
 cflags-$(CONFIG_M532x)		:= $(call cc-option,-mcpu=532x,-m5307)
-cflags-$(CONFIG_M5407)		:= -m5200
+cflags-$(CONFIG_M5407)		:= $(call cc-option,-m5407,-m5200)
 cflags-$(CONFIG_M68328)		:= -m68000
 cflags-$(CONFIG_M68EZ328)	:= -m68000
 cflags-$(CONFIG_M68VZ328)	:= -m68000
diff --git a/arch/m68knommu/kernel/dma.c b/arch/m68knommu/kernel/dma.c
index e10eafc..9361258 100644
--- a/arch/m68knommu/kernel/dma.c
+++ b/arch/m68knommu/kernel/dma.c
@@ -9,10 +9,11 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 #include <linux/device.h>
+#include <linux/dma-mapping.h>
 #include <asm/io.h>
 
 void *dma_alloc_coherent(struct device *dev, size_t size,
-			   dma_addr_t *dma_handle, int gfp)
+			   dma_addr_t *dma_handle, gfp_t gfp)
 {
 	void *ret;
 	/* ignore region specifiers */
@@ -34,3 +35,8 @@
 {
 	free_pages((unsigned long)vaddr, get_order(size));
 }
+
+void dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+}
+
diff --git a/arch/m68knommu/kernel/irq.c b/arch/m68knommu/kernel/irq.c
index bba1bb4..56e0f4c5 100644
--- a/arch/m68knommu/kernel/irq.c
+++ b/arch/m68knommu/kernel/irq.c
@@ -23,7 +23,7 @@
 	struct pt_regs *oldregs = set_irq_regs(regs);
 
 	irq_enter();
-	__do_IRQ(irq);
+	generic_handle_irq(irq);
 	irq_exit();
 
 	set_irq_regs(oldregs);
diff --git a/arch/m68knommu/mm/init.c b/arch/m68knommu/mm/init.c
index 3bf249c..7befc0c 100644
--- a/arch/m68knommu/mm/init.c
+++ b/arch/m68knommu/mm/init.c
@@ -111,11 +111,7 @@
 	{
 		unsigned long zones_size[MAX_NR_ZONES] = {0, };
 
-		zones_size[ZONE_DMA] = 0 >> PAGE_SHIFT;
-		zones_size[ZONE_NORMAL] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
-#ifdef CONFIG_HIGHMEM
-		zones_size[ZONE_HIGHMEM] = 0;
-#endif
+		zones_size[ZONE_DMA] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
 		free_area_init(zones_size);
 	}
 }
diff --git a/arch/m68knommu/platform/5249/config.c b/arch/m68knommu/platform/5249/config.c
index d299f7b..9eab19d 100644
--- a/arch/m68knommu/platform/5249/config.c
+++ b/arch/m68knommu/platform/5249/config.c
@@ -32,7 +32,8 @@
 	{
 		.mapbase 	= MCF_MBAR + MCFUART_BASE2,
 		.irq		= 74,
-	}
+	},
+	{ },
 };
 
 static struct platform_device m5249_uart = {
@@ -50,12 +51,12 @@
 static void __init m5249_uart_init_line(int line, int irq)
 {
 	if (line == 0) {
-		writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
-		writeb(irq, MCFUART_BASE1 + MCFUART_UIVR);
+		writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
+		writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR);
 		mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
 	} else if (line == 1) {
-		writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
-		writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
+		writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
+		writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR);
 		mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
 	}
 }
diff --git a/arch/m68knommu/platform/5307/config.c b/arch/m68knommu/platform/5307/config.c
index 724faf0..44803bf 100644
--- a/arch/m68knommu/platform/5307/config.c
+++ b/arch/m68knommu/platform/5307/config.c
@@ -65,12 +65,12 @@
 static void __init m5307_uart_init_line(int line, int irq)
 {
 	if (line == 0) {
-		writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
-		writeb(irq, MCFUART_BASE1 + MCFUART_UIVR);
+		writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
+		writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR);
 		mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
 	} else if (line == 1) {
-		writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
-		writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
+		writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
+		writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR);
 		mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
 	}
 }
diff --git a/arch/m68knommu/platform/5407/config.c b/arch/m68knommu/platform/5407/config.c
index 648b8b7..0ee8c1a 100644
--- a/arch/m68knommu/platform/5407/config.c
+++ b/arch/m68knommu/platform/5407/config.c
@@ -56,12 +56,12 @@
 static void __init m5407_uart_init_line(int line, int irq)
 {
 	if (line == 0) {
-		writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
-		writeb(irq, MCFUART_BASE1 + MCFUART_UIVR);
+		writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
+		writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR);
 		mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
 	} else if (line == 1) {
-		writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
-		writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
+		writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
+		writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR);
 		mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
 	}
 }
diff --git a/arch/m68knommu/platform/coldfire/Makefile b/arch/m68knommu/platform/coldfire/Makefile
index 4f416a9..1bcb937 100644
--- a/arch/m68knommu/platform/coldfire/Makefile
+++ b/arch/m68knommu/platform/coldfire/Makefile
@@ -14,7 +14,7 @@
 
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
-obj-$(CONFIG_COLDFIRE)	+= dma.o entry.o vectors.o
+obj-$(CONFIG_COLDFIRE)	+= clk.o dma.o entry.o vectors.o
 obj-$(CONFIG_M5206)	+= timers.o
 obj-$(CONFIG_M5206e)	+= timers.o
 obj-$(CONFIG_M520x)	+= pit.o
diff --git a/arch/m68knommu/platform/coldfire/clk.c b/arch/m68knommu/platform/coldfire/clk.c
new file mode 100644
index 0000000..7cdbf44
--- /dev/null
+++ b/arch/m68knommu/platform/coldfire/clk.c
@@ -0,0 +1,40 @@
+/***************************************************************************/
+
+/*
+ *	clk.c -- general ColdFire CPU kernel clk handling
+ *
+ *	Copyright (C) 2009, Greg Ungerer (gerg@snapgear.com)
+ */
+
+/***************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <asm/coldfire.h>
+
+/***************************************************************************/
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+	return NULL;
+}
+
+int clk_enable(struct clk *clk)
+{
+	return 0;
+}
+
+void clk_disable(struct clk *clk)
+{
+}
+
+void clk_put(struct clk *clk)
+{
+}
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	return MCF_CLK;
+}
+
+/***************************************************************************/
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index dc78719..998e5db 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -134,7 +134,7 @@
 	help
 	 This a family of machines based on the MIPS R4030 chipset which was
 	 used by several vendors to build RISC/os and Windows NT workstations.
-	 Members include the Acer PICA, MIPS Magnum 4000, MIPS Millenium and
+	 Members include the Acer PICA, MIPS Magnum 4000, MIPS Millennium and
 	 Olivetti M700-10 workstations.
 
 config LASAT
diff --git a/arch/mips/include/asm/ftrace.h b/arch/mips/include/asm/ftrace.h
new file mode 100644
index 0000000..40a8c17
--- /dev/null
+++ b/arch/mips/include/asm/ftrace.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c
index 5b47d6b..cbcd7eb 100644
--- a/arch/mips/sgi-ip27/ip27-smp.c
+++ b/arch/mips/sgi-ip27/ip27-smp.c
@@ -221,7 +221,7 @@
 	 * Assumption to be fixed: we're always booted on logical / physical
 	 * processor 0.  While we're always running on logical processor 0
 	 * this still means this is physical processor zero; it might for
-	 * example be disabled in the firwware.
+	 * example be disabled in the firmware.
 	 */
 	alloc_cpupda(0, 0);
 }
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index aacf11d..9038f39d 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -9,9 +9,13 @@
 	def_bool y
 	select HAVE_IDE
 	select HAVE_OPROFILE
+	select HAVE_FUNCTION_TRACER if 64BIT
+	select HAVE_FUNCTION_GRAPH_TRACER if 64BIT
+	select HAVE_FUNCTION_TRACE_MCOUNT_TEST if 64BIT
 	select RTC_CLASS
-	select RTC_DRV_PARISC
+	select RTC_DRV_GENERIC
 	select INIT_ALL_POSSIBLE
+	select BUG
 	help
 	  The PA-RISC microprocessor is designed by Hewlett-Packard and used
 	  in many of their workstations & servers (HP9000 700 and 800 series,
@@ -75,6 +79,9 @@
 config GENERIC_IRQ_PROBE
 	def_bool y
 
+config HAVE_LATENCYTOP_SUPPORT
+        def_bool y
+
 config IRQ_PER_CPU
 	bool
 	default y
@@ -83,6 +90,9 @@
 config PM
 	bool
 
+config STACKTRACE_SUPPORT
+	def_bool y
+
 config ISA_DMA_API
 	bool
 
diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile
index 0d42827..da6f669 100644
--- a/arch/parisc/Makefile
+++ b/arch/parisc/Makefile
@@ -56,7 +56,9 @@
 
 # Without this, "ld -r" results in .text sections that are too big
 # (> 0x40000) for branches to reach stubs.
-cflags-y	+= -ffunction-sections
+ifndef CONFIG_FUNCTION_TRACER
+  cflags-y	+= -ffunction-sections
+endif
 
 # select which processor to optimise for
 cflags-$(CONFIG_PA7100)		+= -march=1.1 -mschedule=7100
diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h
index edbfe25c..ada3e53 100644
--- a/arch/parisc/include/asm/atomic.h
+++ b/arch/parisc/include/asm/atomic.h
@@ -25,7 +25,7 @@
  * Since "a" is usually an address, use one spinlock per cacheline.
  */
 #  define ATOMIC_HASH_SIZE 4
-#  define ATOMIC_HASH(a) (&(__atomic_hash[ (((unsigned long) a)/L1_CACHE_BYTES) & (ATOMIC_HASH_SIZE-1) ]))
+#  define ATOMIC_HASH(a) (&(__atomic_hash[ (((unsigned long) (a))/L1_CACHE_BYTES) & (ATOMIC_HASH_SIZE-1) ]))
 
 extern raw_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned;
 
@@ -222,13 +222,13 @@
 
 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
 
-#define atomic_add(i,v)	((void)(__atomic_add_return( ((int)i),(v))))
-#define atomic_sub(i,v)	((void)(__atomic_add_return(-((int)i),(v))))
+#define atomic_add(i,v)	((void)(__atomic_add_return( ((int)(i)),(v))))
+#define atomic_sub(i,v)	((void)(__atomic_add_return(-((int)(i)),(v))))
 #define atomic_inc(v)	((void)(__atomic_add_return(   1,(v))))
 #define atomic_dec(v)	((void)(__atomic_add_return(  -1,(v))))
 
-#define atomic_add_return(i,v)	(__atomic_add_return( ((int)i),(v)))
-#define atomic_sub_return(i,v)	(__atomic_add_return(-((int)i),(v)))
+#define atomic_add_return(i,v)	(__atomic_add_return( ((int)(i)),(v)))
+#define atomic_sub_return(i,v)	(__atomic_add_return(-((int)(i)),(v)))
 #define atomic_inc_return(v)	(__atomic_add_return(   1,(v)))
 #define atomic_dec_return(v)	(__atomic_add_return(  -1,(v)))
 
@@ -289,13 +289,13 @@
 	return v->counter;
 }
 
-#define atomic64_add(i,v)	((void)(__atomic64_add_return( ((s64)i),(v))))
-#define atomic64_sub(i,v)	((void)(__atomic64_add_return(-((s64)i),(v))))
+#define atomic64_add(i,v)	((void)(__atomic64_add_return( ((s64)(i)),(v))))
+#define atomic64_sub(i,v)	((void)(__atomic64_add_return(-((s64)(i)),(v))))
 #define atomic64_inc(v)		((void)(__atomic64_add_return(   1,(v))))
 #define atomic64_dec(v)		((void)(__atomic64_add_return(  -1,(v))))
 
-#define atomic64_add_return(i,v)	(__atomic64_add_return( ((s64)i),(v)))
-#define atomic64_sub_return(i,v)	(__atomic64_add_return(-((s64)i),(v)))
+#define atomic64_add_return(i,v)	(__atomic64_add_return( ((s64)(i)),(v)))
+#define atomic64_sub_return(i,v)	(__atomic64_add_return(-((s64)(i)),(v)))
 #define atomic64_inc_return(v)		(__atomic64_add_return(   1,(v)))
 #define atomic64_dec_return(v)		(__atomic64_add_return(  -1,(v)))
 
diff --git a/arch/parisc/include/asm/cacheflush.h b/arch/parisc/include/asm/cacheflush.h
index b7ca6dc..7243951 100644
--- a/arch/parisc/include/asm/cacheflush.h
+++ b/arch/parisc/include/asm/cacheflush.h
@@ -97,6 +97,9 @@
 
 #ifdef CONFIG_PA8X00
 /* Only pa8800, pa8900 needs this */
+
+#include <asm/kmap_types.h>
+
 #define ARCH_HAS_KMAP
 
 void kunmap_parisc(void *addr);
diff --git a/arch/parisc/include/asm/elf.h b/arch/parisc/include/asm/elf.h
index 7fa6757..9c802eb 100644
--- a/arch/parisc/include/asm/elf.h
+++ b/arch/parisc/include/asm/elf.h
@@ -168,6 +168,16 @@
 	__u64	gp;
 } Elf64_Fdesc;
 
+#ifdef __KERNEL__
+
+#ifdef CONFIG_64BIT
+#define Elf_Fdesc	Elf64_Fdesc
+#else
+#define Elf_Fdesc	Elf32_Fdesc
+#endif /*CONFIG_64BIT*/
+
+#endif /*__KERNEL__*/
+
 /* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr.  */
 
 #define PT_HP_TLS		(PT_LOOS + 0x0)
diff --git a/arch/parisc/include/asm/ftrace.h b/arch/parisc/include/asm/ftrace.h
new file mode 100644
index 0000000..2fa05dd
--- /dev/null
+++ b/arch/parisc/include/asm/ftrace.h
@@ -0,0 +1,25 @@
+#ifndef _ASM_PARISC_FTRACE_H
+#define _ASM_PARISC_FTRACE_H
+
+#ifndef __ASSEMBLY__
+extern void mcount(void);
+
+/*
+ * Stack of return addresses for functions of a thread.
+ * Used in struct thread_info
+ */
+struct ftrace_ret_stack {
+	unsigned long ret;
+	unsigned long func;
+	unsigned long long calltime;
+};
+
+/*
+ * Primary handler of a function return.
+ * It relays on ftrace_return_to_handler.
+ * Defined in entry.S
+ */
+extern void return_to_handler(void);
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_PARISC_FTRACE_H */
diff --git a/arch/parisc/include/asm/page.h b/arch/parisc/include/asm/page.h
index c3941f0..7bc5125 100644
--- a/arch/parisc/include/asm/page.h
+++ b/arch/parisc/include/asm/page.h
@@ -36,16 +36,7 @@
  */
 #define STRICT_MM_TYPECHECKS
 #ifdef STRICT_MM_TYPECHECKS
-typedef struct { unsigned long pte;
-#if !defined(CONFIG_64BIT)
-                 unsigned long future_flags;
- /* XXX: it's possible to remove future_flags and change BITS_PER_PTE_ENTRY
-	 to 2, but then strangely the identical 32bit kernel boots on a
-	 c3000(pa20), but not any longer on a 715(pa11).
-	 Still investigating... HelgeD.
-  */
-#endif
-} pte_t; /* either 32 or 64bit */
+typedef struct { unsigned long pte; } pte_t; /* either 32 or 64bit */
 
 /* NOTE: even on 64 bits, these entries are __u32 because we allocate
  * the pmd and pgd in ZONE_DMA (i.e. under 4GB) */
@@ -111,7 +102,7 @@
 #define BITS_PER_PMD_ENTRY	2
 #define BITS_PER_PGD_ENTRY	2
 #else
-#define BITS_PER_PTE_ENTRY	3
+#define BITS_PER_PTE_ENTRY	2
 #define BITS_PER_PMD_ENTRY	2
 #define BITS_PER_PGD_ENTRY	BITS_PER_PMD_ENTRY
 #endif
diff --git a/arch/parisc/include/asm/pdc.h b/arch/parisc/include/asm/pdc.h
index 430f1ae..4ca510b 100644
--- a/arch/parisc/include/asm/pdc.h
+++ b/arch/parisc/include/asm/pdc.h
@@ -49,6 +49,8 @@
 #define PDC_MODEL_CPU_ID	6	/* returns cpu-id (only newer machines!) */
 #define PDC_MODEL_CAPABILITIES	7	/* returns OS32/OS64-flags	*/
 /* Values for PDC_MODEL_CAPABILITIES non-equivalent virtual aliasing support */
+#define  PDC_MODEL_OS64			(1 << 0)
+#define  PDC_MODEL_OS32			(1 << 1)
 #define  PDC_MODEL_IOPDIR_FDC		(1 << 2)
 #define  PDC_MODEL_NVA_MASK		(3 << 4)
 #define  PDC_MODEL_NVA_SUPPORTED	(0 << 4)
@@ -341,6 +343,8 @@
 
 #ifdef __KERNEL__
 
+#include <asm/page.h> /* for __PAGE_OFFSET */
+
 extern int pdc_type;
 
 /* Values for pdc_type */
diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h
index 470a4b8..a27d2e2 100644
--- a/arch/parisc/include/asm/pgtable.h
+++ b/arch/parisc/include/asm/pgtable.h
@@ -50,11 +50,7 @@
 	printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, (unsigned long)pgd_val(e))
 
 /* This is the size of the initially mapped kernel memory */
-#ifdef CONFIG_64BIT
 #define KERNEL_INITIAL_ORDER	24	/* 0 to 1<<24 = 16MB */
-#else
-#define KERNEL_INITIAL_ORDER	23	/* 0 to 1<<23 = 8MB */
-#endif
 #define KERNEL_INITIAL_SIZE	(1 << KERNEL_INITIAL_ORDER)
 
 #if defined(CONFIG_64BIT) && defined(CONFIG_PARISC_PAGE_SIZE_4KB)
@@ -91,16 +87,25 @@
 
 /* Definitions for 1st level */
 #define PGDIR_SHIFT	(PMD_SHIFT + BITS_PER_PMD)
+#if (PGDIR_SHIFT + PAGE_SHIFT + PGD_ORDER - BITS_PER_PGD_ENTRY) > BITS_PER_LONG
+#define BITS_PER_PGD	(BITS_PER_LONG - PGDIR_SHIFT)
+#else
 #define BITS_PER_PGD	(PAGE_SHIFT + PGD_ORDER - BITS_PER_PGD_ENTRY)
+#endif
 #define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
 #define PGDIR_MASK	(~(PGDIR_SIZE-1))
 #define PTRS_PER_PGD    (1UL << BITS_PER_PGD)
 #define USER_PTRS_PER_PGD       PTRS_PER_PGD
 
+#ifdef CONFIG_64BIT
 #define MAX_ADDRBITS	(PGDIR_SHIFT + BITS_PER_PGD)
 #define MAX_ADDRESS	(1UL << MAX_ADDRBITS)
-
 #define SPACEID_SHIFT	(MAX_ADDRBITS - 32)
+#else
+#define MAX_ADDRBITS	(BITS_PER_LONG)
+#define MAX_ADDRESS	(1UL << MAX_ADDRBITS)
+#define SPACEID_SHIFT	0
+#endif
 
 /* This calculates the number of initial pages we need for the initial
  * page tables */
diff --git a/arch/parisc/include/asm/smp.h b/arch/parisc/include/asm/smp.h
index 6ef4b78..21eb45a 100644
--- a/arch/parisc/include/asm/smp.h
+++ b/arch/parisc/include/asm/smp.h
@@ -29,7 +29,8 @@
 extern void smp_send_all_nop(void);
 
 extern void arch_send_call_function_single_ipi(int cpu);
-extern void arch_send_call_function_ipi(cpumask_t mask);
+extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
+#define arch_send_call_function_ipi_mask arch_send_call_function_ipi_mask
 
 #endif /* !ASSEMBLY */
 
diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile
index 016d3fc..67db072 100644
--- a/arch/parisc/kernel/Makefile
+++ b/arch/parisc/kernel/Makefile
@@ -11,10 +11,25 @@
 		   process.o processor.o pdc_cons.o pdc_chassis.o unwind.o \
 		   topology.o
 
+ifdef CONFIG_FUNCTION_TRACER
+# Do not profile debug and lowlevel utilities
+CFLAGS_REMOVE_ftrace.o = -pg
+CFLAGS_REMOVE_cache.o = -pg
+CFLAGS_REMOVE_irq.o = -pg
+CFLAGS_REMOVE_pacache.o = -pg
+CFLAGS_REMOVE_perf.o = -pg
+CFLAGS_REMOVE_traps.o = -pg
+CFLAGS_REMOVE_unaligned.o = -pg
+CFLAGS_REMOVE_unwind.o = -pg
+endif
+
 obj-$(CONFIG_SMP)	+= smp.o
 obj-$(CONFIG_PA11)	+= pci-dma.o
 obj-$(CONFIG_PCI)	+= pci.o
 obj-$(CONFIG_MODULES)	+= module.o
 obj-$(CONFIG_64BIT)	+= binfmt_elf32.o sys_parisc32.o signal32.o
+obj-$(CONFIG_STACKTRACE)+= stacktrace.o
 # only supported for PCX-W/U in 64-bit mode at the moment
 obj-$(CONFIG_64BIT)	+= perf.o perf_asm.o
+obj-$(CONFIG_FUNCTION_TRACER)		+= ftrace.o
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER)	+= ftrace.o
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index 0db9fdc..ae3e70cd 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -505,6 +505,18 @@
 	STREG		\pte,0(\ptep)
 	.endm
 
+	/* bitshift difference between a PFN (based on kernel's PAGE_SIZE)
+	 * to a CPU TLB 4k PFN (4k => 12 bits to shift) */
+	#define PAGE_ADD_SHIFT  (PAGE_SHIFT-12)
+
+	/* Drop prot bits and convert to page addr for iitlbt and idtlbt */
+	.macro		convert_for_tlb_insert20 pte
+	extrd,u		\pte,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\
+				64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte
+	depdi		_PAGE_SIZE_ENCODING_DEFAULT,63,\
+				(63-58)+PAGE_ADD_SHIFT,\pte
+	.endm
+
 	/* Convert the pte and prot to tlb insertion values.  How
 	 * this happens is quite subtle, read below */
 	.macro		make_insert_tlb	spc,pte,prot
@@ -544,8 +556,7 @@
 	depi		1,12,1,\prot
 
 	/* Drop prot bits and convert to page addr for iitlbt and idtlbt */
-	extrd,u		\pte,(63-ASM_PFN_PTE_SHIFT)+(63-58),64-PAGE_SHIFT,\pte
-	depdi		_PAGE_SIZE_ENCODING_DEFAULT,63,63-58,\pte
+	convert_for_tlb_insert20 \pte
 	.endm
 
 	/* Identical macro to make_insert_tlb above, except it
@@ -563,8 +574,8 @@
 
 	/* Get rid of prot bits and convert to page addr for iitlba */
 
-	depi		_PAGE_SIZE_ENCODING_DEFAULT,31,ASM_PFN_PTE_SHIFT,\pte
-	extru		\pte,24,25,\pte
+	depi		0,31,ASM_PFN_PTE_SHIFT,\pte
+	SHRREG		\pte,(ASM_PFN_PTE_SHIFT-(31-26)),\pte
 	.endm
 
 	/* This is for ILP32 PA2.0 only.  The TLB insertion needs
@@ -1244,10 +1255,9 @@
 	depdi,z         7,7,3,prot
 	depdi           1,10,1,prot
 
-	/* Get rid of prot bits and convert to page addr for idtlbt */
+	/* Drop prot bits from pte and convert to page addr for idtlbt */
+	convert_for_tlb_insert20 pte
 
-	depdi		0,63,12,pte
-	extrd,u         pte,56,52,pte
 	idtlbt          pte,prot
 
 	rfir
@@ -1337,8 +1347,8 @@
 
 	/* Get rid of prot bits and convert to page addr for idtlba */
 
-	depi		0,31,12,pte
-	extru		pte,24,25,pte
+	depi		0,31,ASM_PFN_PTE_SHIFT,pte
+	SHRREG		pte,(ASM_PFN_PTE_SHIFT-(31-26)),pte
 
 	mfsp		%sr1,t0  /* Save sr1 so we can use it in tlb inserts */
 	mtsp		spc,%sr1
@@ -1403,10 +1413,9 @@
 	depdi,z         7,7,3,prot
 	depdi           1,10,1,prot
 
-	/* Get rid of prot bits and convert to page addr for idtlbt */
+	/* Drop prot bits from pte and convert to page addr for idtlbt */
+	convert_for_tlb_insert20 pte
 
-	depdi		0,63,12,pte
-	extrd,u         pte,56,32,pte
 	idtlbt          pte,prot
 
 	rfir
@@ -2176,6 +2185,33 @@
 ENDPROC(syscall_exit)
 
 
+#ifdef CONFIG_FUNCTION_TRACER
+	.import ftrace_function_trampoline,code
+ENTRY(_mcount)
+	copy	%r3, %arg2
+	b	ftrace_function_trampoline
+	nop
+ENDPROC(_mcount)
+
+ENTRY(return_to_handler)
+	load32	return_trampoline, %rp
+	copy	%ret0, %arg0
+	copy	%ret1, %arg1
+	b	ftrace_return_to_handler
+	nop
+return_trampoline:
+	copy	%ret0, %rp
+	copy	%r23, %ret0
+	copy	%r24, %ret1
+
+.globl ftrace_stub
+ftrace_stub:
+	bv	%r0(%rp)
+	nop
+ENDPROC(return_to_handler)
+#endif	/* CONFIG_FUNCTION_TRACER */
+
+
 get_register:
 	/*
 	 * get_register is used by the non access tlb miss handlers to
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
index f6d2412..4c247e0 100644
--- a/arch/parisc/kernel/firmware.c
+++ b/arch/parisc/kernel/firmware.c
@@ -527,7 +527,11 @@
         pdc_result[0] = 0; /* preset zero (call may not be implemented!) */
         retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES, __pa(pdc_result), 0);
         convert_to_wide(pdc_result);
-        *capabilities = pdc_result[0];
+        if (retval == PDC_OK) {
+                *capabilities = pdc_result[0];
+        } else {
+                *capabilities = PDC_MODEL_OS32;
+        }
         spin_unlock_irqrestore(&pdc_lock, flags);
 
         return retval;
diff --git a/arch/parisc/kernel/ftrace.c b/arch/parisc/kernel/ftrace.c
new file mode 100644
index 0000000..9877372
--- /dev/null
+++ b/arch/parisc/kernel/ftrace.c
@@ -0,0 +1,185 @@
+/*
+ * Code for tracing calls in Linux kernel.
+ * Copyright (C) 2009 Helge Deller <deller@gmx.de>
+ *
+ * based on code for x86 which is:
+ * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
+ *
+ * future possible enhancements:
+ * 	- add CONFIG_DYNAMIC_FTRACE
+ *	- add CONFIG_STACK_TRACER
+ */
+
+#include <linux/init.h>
+#include <linux/ftrace.h>
+
+#include <asm/sections.h>
+#include <asm/ftrace.h>
+
+
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+
+/* Add a function return address to the trace stack on thread info.*/
+static int push_return_trace(unsigned long ret, unsigned long long time,
+				unsigned long func, int *depth)
+{
+	int index;
+
+	if (!current->ret_stack)
+		return -EBUSY;
+
+	/* The return trace stack is full */
+	if (current->curr_ret_stack == FTRACE_RETFUNC_DEPTH - 1) {
+		atomic_inc(&current->trace_overrun);
+		return -EBUSY;
+	}
+
+	index = ++current->curr_ret_stack;
+	barrier();
+	current->ret_stack[index].ret = ret;
+	current->ret_stack[index].func = func;
+	current->ret_stack[index].calltime = time;
+	*depth = index;
+
+	return 0;
+}
+
+/* Retrieve a function return address to the trace stack on thread info.*/
+static void pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret)
+{
+	int index;
+
+	index = current->curr_ret_stack;
+
+	if (unlikely(index < 0)) {
+		ftrace_graph_stop();
+		WARN_ON(1);
+		/* Might as well panic, otherwise we have no where to go */
+		*ret = (unsigned long)
+			dereference_function_descriptor(&panic);
+		return;
+	}
+
+	*ret = current->ret_stack[index].ret;
+	trace->func = current->ret_stack[index].func;
+	trace->calltime = current->ret_stack[index].calltime;
+	trace->overrun = atomic_read(&current->trace_overrun);
+	trace->depth = index;
+	barrier();
+	current->curr_ret_stack--;
+
+}
+
+/*
+ * Send the trace to the ring-buffer.
+ * @return the original return address.
+ */
+unsigned long ftrace_return_to_handler(unsigned long retval0,
+				       unsigned long retval1)
+{
+	struct ftrace_graph_ret trace;
+	unsigned long ret;
+
+	pop_return_trace(&trace, &ret);
+	trace.rettime = cpu_clock(raw_smp_processor_id());
+	ftrace_graph_return(&trace);
+
+	if (unlikely(!ret)) {
+		ftrace_graph_stop();
+		WARN_ON(1);
+		/* Might as well panic. What else to do? */
+		ret = (unsigned long)
+			dereference_function_descriptor(&panic);
+	}
+
+	/* HACK: we hand over the old functions' return values
+	   in %r23 and %r24. Assembly in entry.S will take care
+	   and move those to their final registers %ret0 and %ret1 */
+	asm( "copy %0, %%r23 \n\t"
+	     "copy %1, %%r24 \n" : : "r" (retval0), "r" (retval1) );
+
+	return ret;
+}
+
+/*
+ * Hook the return address and push it in the stack of return addrs
+ * in current thread info.
+ */
+void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
+{
+	unsigned long old;
+	unsigned long long calltime;
+	struct ftrace_graph_ent trace;
+
+	if (unlikely(atomic_read(&current->tracing_graph_pause)))
+		return;
+
+	old = *parent;
+	*parent = (unsigned long)
+		  dereference_function_descriptor(&return_to_handler);
+
+	if (unlikely(!__kernel_text_address(old))) {
+		ftrace_graph_stop();
+		*parent = old;
+		WARN_ON(1);
+		return;
+	}
+
+	calltime = cpu_clock(raw_smp_processor_id());
+
+	if (push_return_trace(old, calltime,
+				self_addr, &trace.depth) == -EBUSY) {
+		*parent = old;
+		return;
+	}
+
+	trace.func = self_addr;
+
+	/* Only trace if the calling function expects to */
+	if (!ftrace_graph_entry(&trace)) {
+		current->curr_ret_stack--;
+		*parent = old;
+	}
+}
+
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
+
+void ftrace_function_trampoline(unsigned long parent,
+				unsigned long self_addr,
+				unsigned long org_sp_gr3)
+{
+	extern ftrace_func_t ftrace_trace_function;
+
+	if (function_trace_stop)
+		return;
+
+	if (ftrace_trace_function != ftrace_stub) {
+		ftrace_trace_function(parent, self_addr);
+		return;
+	}
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+	if (ftrace_graph_entry && ftrace_graph_return) {
+		unsigned long sp;
+		unsigned long *parent_rp;
+
+                asm volatile ("copy %%r30, %0" : "=r"(sp));
+		/* sanity check: is stack pointer which we got from
+		   assembler function in entry.S in a reasonable
+		   range compared to current stack pointer? */
+		if ((sp - org_sp_gr3) > 0x400)
+			return;
+
+		/* calculate pointer to %rp in stack */
+		parent_rp = (unsigned long *) org_sp_gr3 - 0x10;
+		/* sanity check: parent_rp should hold parent */
+		if (*parent_rp != parent)
+			return;
+		
+		prepare_ftrace_return(parent_rp, self_addr);
+		return;
+	}
+#endif
+}
+
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index 1c740f5..4ea4229 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -311,12 +311,12 @@
 	next_cpu++; /* assign to "next" CPU we want this bugger on */
 
 	/* validate entry */
-	while ((next_cpu < NR_CPUS) &&
+	while ((next_cpu < nr_cpu_ids) &&
 		(!per_cpu(cpu_data, next_cpu).txn_addr ||
 		 !cpu_online(next_cpu)))
 		next_cpu++;
 
-	if (next_cpu >= NR_CPUS) 
+	if (next_cpu >= nr_cpu_ids) 
 		next_cpu = 0;	/* nothing else, assign monarch */
 
 	return txn_affinity_addr(virt_irq, next_cpu);
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
index 9013243..ecd1c50 100644
--- a/arch/parisc/kernel/module.c
+++ b/arch/parisc/kernel/module.c
@@ -61,9 +61,7 @@
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/bug.h>
-#include <linux/uaccess.h>
 
-#include <asm/sections.h>
 #include <asm/unwind.h>
 
 #if 0
@@ -115,8 +113,6 @@
 	Elf32_Addr addr;
 };
 
-#define Elf_Fdesc	Elf32_Fdesc
-
 struct stub_entry {
 	Elf32_Word insns[2]; /* each stub entry has two insns */
 };
@@ -125,8 +121,6 @@
 	Elf64_Addr addr;
 };
 
-#define Elf_Fdesc	Elf64_Fdesc
-
 struct stub_entry {
 	Elf64_Word insns[4]; /* each stub entry has four insns */
 };
@@ -916,15 +910,3 @@
 	deregister_unwind_table(mod);
 	module_bug_cleanup(mod);
 }
-
-#ifdef CONFIG_64BIT
-void *dereference_function_descriptor(void *ptr)
-{
-	Elf64_Fdesc *desc = ptr;
-	void *p;
-
-	if (!probe_kernel_address(&desc->addr, p))
-		ptr = p;
-	return ptr;
-}
-#endif
diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c
index 0eecfbbc..df65366 100644
--- a/arch/parisc/kernel/parisc_ksyms.c
+++ b/arch/parisc/kernel/parisc_ksyms.c
@@ -153,5 +153,10 @@
 EXPORT_SYMBOL(pfnnid_map);
 #endif
 
+#ifdef CONFIG_FUNCTION_TRACER
+extern void _mcount(void);
+EXPORT_SYMBOL(_mcount);
+#endif
+
 /* from pacache.S -- needed for copy_page */
 EXPORT_SYMBOL(copy_user_page_asm);
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 8aa591e..6f69101 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -46,14 +46,15 @@
 #include <linux/stddef.h>
 #include <linux/unistd.h>
 #include <linux/kallsyms.h>
+#include <linux/uaccess.h>
 
 #include <asm/io.h>
 #include <asm/asm-offsets.h>
 #include <asm/pdc.h>
 #include <asm/pdc_chassis.h>
 #include <asm/pgalloc.h>
-#include <asm/uaccess.h>
 #include <asm/unwind.h>
+#include <asm/sections.h>
 
 /*
  * The idle thread. There's no useful work to be
@@ -231,8 +232,8 @@
 	   
 	   However, these last 3 args are only examined
 	   if the proper flags are set. */
-	int __user *child_tidptr;
-	int __user *parent_tidptr;
+	int __user *parent_tidptr = (int __user *)regs->gr[24];
+	int __user *child_tidptr  = (int __user *)regs->gr[22];
 
 	/* usp must be word aligned.  This also prevents users from
 	 * passing in the value 1 (which is the signal for a special
@@ -243,16 +244,6 @@
 	if (usp == 0)
 	  usp = regs->gr[30];
 
-	if (clone_flags & CLONE_PARENT_SETTID)
-	  parent_tidptr = (int __user *)regs->gr[24];
-	else
-	  parent_tidptr = NULL;
-	
-	if (clone_flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID))
-	  child_tidptr = (int __user *)regs->gr[22];
-	else
-	  child_tidptr = NULL;
-
 	return do_fork(clone_flags, usp, regs, 0, parent_tidptr, child_tidptr);
 }
 
@@ -400,3 +391,15 @@
 	} while (count++ < 16);
 	return 0;
 }
+
+#ifdef CONFIG_64BIT
+void *dereference_function_descriptor(void *ptr)
+{
+	Elf64_Fdesc *desc = ptr;
+	void *p;
+
+	if (!probe_kernel_address(&desc->addr, p))
+		ptr = p;
+	return ptr;
+}
+#endif
diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
index ecb6093..e09d0f7 100644
--- a/arch/parisc/kernel/processor.c
+++ b/arch/parisc/kernel/processor.c
@@ -100,8 +100,8 @@
 	struct cpuinfo_parisc *p;
 
 #ifdef CONFIG_SMP
-	if (num_online_cpus() >= NR_CPUS) {
-		printk(KERN_INFO "num_online_cpus() >= NR_CPUS\n");
+	if (num_online_cpus() >= nr_cpu_ids) {
+		printk(KERN_INFO "num_online_cpus() >= nr_cpu_ids\n");
 		return 1;
 	}
 #else
@@ -214,7 +214,7 @@
 	 */
 #ifdef CONFIG_SMP
 	if (cpuid) {
-		cpu_set(cpuid, cpu_present_map);
+		set_cpu_present(cpuid, true);
 		cpu_up(cpuid);
 	}
 #endif
@@ -364,6 +364,13 @@
 				 boot_cpu_data.cpu_hz / 1000000,
 				 boot_cpu_data.cpu_hz % 1000000  );
 
+		seq_printf(m, "capabilities\t:");
+		if (boot_cpu_data.pdc.capabilities & PDC_MODEL_OS32)
+			seq_printf(m, " os32");
+		if (boot_cpu_data.pdc.capabilities & PDC_MODEL_OS64)
+			seq_printf(m, " os64");
+		seq_printf(m, "\n");
+
 		seq_printf(m, "model\t\t: %s\n"
 				"model name\t: %s\n",
 				 boot_cpu_data.pdc.sys_model_name,
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index 9995d7e..1fd0f0c 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -31,6 +31,7 @@
 #include <linux/err.h>
 #include <linux/delay.h>
 #include <linux/bitops.h>
+#include <linux/ftrace.h>
 
 #include <asm/system.h>
 #include <asm/atomic.h>
@@ -113,14 +114,14 @@
 {
 	/* REVISIT : redirect I/O Interrupts to another CPU? */
 	/* REVISIT : does PM *know* this CPU isn't available? */
-	cpu_clear(smp_processor_id(), cpu_online_map);
+	set_cpu_online(smp_processor_id(), false);
 	local_irq_disable();
 	for (;;)
 		;
 }
 
 
-irqreturn_t
+irqreturn_t __irq_entry
 ipi_interrupt(int irq, void *dev_id) 
 {
 	int this_cpu = smp_processor_id();
@@ -214,11 +215,11 @@
 }
 
 static void
-send_IPI_mask(cpumask_t mask, enum ipi_message_type op)
+send_IPI_mask(const struct cpumask *mask, enum ipi_message_type op)
 {
 	int cpu;
 
-	for_each_cpu_mask(cpu, mask)
+	for_each_cpu(cpu, mask)
 		ipi_send(cpu, op);
 }
 
@@ -257,7 +258,7 @@
 	send_IPI_allbutself(IPI_NOP);
 }
 
-void arch_send_call_function_ipi(cpumask_t mask)
+void arch_send_call_function_ipi_mask(const struct cpumask *mask)
 {
 	send_IPI_mask(mask, IPI_CALL_FUNC);
 }
@@ -296,13 +297,14 @@
 	mb();
 
 	/* Well, support 2.4 linux scheme as well. */
-	if (cpu_test_and_set(cpunum, cpu_online_map))
+	if (cpu_isset(cpunum, cpu_online_map))
 	{
 		extern void machine_halt(void); /* arch/parisc.../process.c */
 
 		printk(KERN_CRIT "CPU#%d already initialized!\n", cpunum);
 		machine_halt();
 	}  
+	set_cpu_online(cpunum, true);
 
 	/* Initialise the idle task for this CPU */
 	atomic_inc(&init_mm.mm_count);
@@ -424,8 +426,8 @@
 	/* Setup BSP mappings */
 	printk(KERN_INFO "SMP: bootstrap CPU ID is %d\n", bootstrap_processor);
 
-	cpu_set(bootstrap_processor, cpu_online_map);
-	cpu_set(bootstrap_processor, cpu_present_map);
+	set_cpu_online(bootstrap_processor, true);
+	set_cpu_present(bootstrap_processor, true);
 }
 
 
@@ -436,8 +438,7 @@
 */
 void __init smp_prepare_cpus(unsigned int max_cpus)
 {
-	cpus_clear(cpu_present_map);
-	cpu_set(0, cpu_present_map);
+	init_cpu_present(cpumask_of(0));
 
 	parisc_max_cpus = max_cpus;
 	if (!max_cpus)
diff --git a/arch/parisc/kernel/stacktrace.c b/arch/parisc/kernel/stacktrace.c
new file mode 100644
index 0000000..2fe914c
--- /dev/null
+++ b/arch/parisc/kernel/stacktrace.c
@@ -0,0 +1,63 @@
+/*
+ * Stack trace management functions
+ *
+ *  Copyright (C) 2009 Helge Deller <deller@gmx.de>
+ *  based on arch/x86/kernel/stacktrace.c by Ingo Molnar <mingo@redhat.com>
+ *  and parisc unwind functions by Randolph Chung <tausq@debian.org>
+ *
+ *  TODO: Userspace stacktrace (CONFIG_USER_STACKTRACE_SUPPORT)
+ */
+#include <linux/module.h>
+#include <linux/stacktrace.h>
+
+#include <asm/unwind.h>
+
+static void dump_trace(struct task_struct *task, struct stack_trace *trace)
+{
+	struct unwind_frame_info info;
+
+	/* initialize unwind info */
+	if (task == current) {
+		unsigned long sp;
+		struct pt_regs r;
+HERE:
+		asm volatile ("copy %%r30, %0" : "=r"(sp));
+		memset(&r, 0, sizeof(struct pt_regs));
+		r.iaoq[0] = (unsigned long)&&HERE;
+		r.gr[2] = (unsigned long)__builtin_return_address(0);
+		r.gr[30] = sp;
+		unwind_frame_init(&info, task, &r);
+	} else {
+		unwind_frame_init_from_blocked_task(&info, task);
+	}
+
+	/* unwind stack and save entries in stack_trace struct */
+	trace->nr_entries = 0;
+	while (trace->nr_entries < trace->max_entries) {
+		if (unwind_once(&info) < 0 || info.ip == 0)
+			break;
+
+		if (__kernel_text_address(info.ip))
+			trace->entries[trace->nr_entries++] = info.ip;
+	}
+}
+
+
+/*
+ * Save stack-backtrace addresses into a stack_trace buffer.
+ */
+void save_stack_trace(struct stack_trace *trace)
+{
+	dump_trace(current, trace);
+	if (trace->nr_entries < trace->max_entries)
+		trace->entries[trace->nr_entries++] = ULONG_MAX;
+}
+EXPORT_SYMBOL_GPL(save_stack_trace);
+
+void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
+{
+	dump_trace(tsk, trace);
+	if (trace->nr_entries < trace->max_entries)
+		trace->entries[trace->nr_entries++] = ULONG_MAX;
+}
+EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
index 69b6eeb..59fc1a43 100644
--- a/arch/parisc/kernel/syscall.S
+++ b/arch/parisc/kernel/syscall.S
@@ -365,17 +365,51 @@
 
 
 	/*********************************************************
-		Light-weight-syscall code
+		32/64-bit Light-Weight-Syscall ABI
 
-		r20 - lws number
-		r26,r25,r24,r23,r22 - Input registers
-		r28 - Function return register
-		r21 - Error code.
+		* - Indicates a hint for userspace inline asm
+		implementations.
 
-		Scracth: Any of the above that aren't being
-		currently used, including r1. 
+		Syscall number (caller-saves)
+	        - %r20
+	        * In asm clobber.
 
-		Return pointer: r31 (Not usable)
+		Argument registers (caller-saves)
+	        - %r26, %r25, %r24, %r23, %r22
+	        * In asm input.
+
+		Return registers (caller-saves)
+	        - %r28 (return), %r21 (errno)
+	        * In asm output.
+
+		Caller-saves registers
+	        - %r1, %r27, %r29
+	        - %r2 (return pointer)
+	        - %r31 (ble link register)
+	        * In asm clobber.
+
+		Callee-saves registers
+	        - %r3-%r18
+	        - %r30 (stack pointer)
+	        * Not in asm clobber.
+
+		If userspace is 32-bit:
+		Callee-saves registers
+	        - %r19 (32-bit PIC register)
+
+		Differences from 32-bit calling convention:
+		- Syscall number in %r20
+		- Additional argument register %r22 (arg4)
+		- Callee-saves %r19.
+
+		If userspace is 64-bit:
+		Callee-saves registers
+		- %r27 (64-bit PIC register)
+
+		Differences from 64-bit calling convention:
+		- Syscall number in %r20
+		- Additional argument register %r22 (arg4)
+		- Callee-saves %r27.
 
 		Error codes returned by entry path:
 
@@ -473,7 +507,8 @@
 	b,n	lws_compare_and_swap
 #else
 	/* If we are not a 64-bit kernel, then we don't
-	 * implement having 64-bit input registers
+	 * have 64-bit input registers, and calling
+	 * the 64-bit LWS CAS returns ENOSYS.
 	 */
 	b,n	lws_exit_nosys
 #endif
@@ -635,12 +670,15 @@
 	/*
 		All light-weight-syscall atomic operations 
 		will use this set of locks 
+
+		NOTE: The lws_lock_start symbol must be
+		at least 16-byte aligned for safe use
+		with ldcw.
 	*/
 	.section .data
 	.align	PAGE_SIZE
 ENTRY(lws_lock_start)
 	/* lws locks */
-	.align 16
 	.rept 16
 	/* Keep locks aligned at 16-bytes */
 	.word 1
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index e75cae6..d4dd056 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c
@@ -24,6 +24,7 @@
 #include <linux/profile.h>
 #include <linux/clocksource.h>
 #include <linux/platform_device.h>
+#include <linux/ftrace.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -53,7 +54,7 @@
  * held off for an arbitrarily long period of time by interrupts being
  * disabled, so we may miss one or more ticks.
  */
-irqreturn_t timer_interrupt(int irq, void *dev_id)
+irqreturn_t __irq_entry timer_interrupt(int irq, void *dev_id)
 {
 	unsigned long now;
 	unsigned long next_tick;
@@ -216,14 +217,14 @@
 	per_cpu(cpu_data, cpu).it_value = next_tick;
 }
 
-static struct platform_device rtc_parisc_dev = {
-	.name = "rtc-parisc",
+static struct platform_device rtc_generic_dev = {
+	.name = "rtc-generic",
 	.id = -1,
 };
 
 static int __init rtc_init(void)
 {
-	if (platform_device_register(&rtc_parisc_dev) < 0)
+	if (platform_device_register(&rtc_generic_dev) < 0)
 		printk(KERN_ERR "unable to register rtc device...\n");
 
 	/* not necessarily an error */
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index ba658d2..c32f5d6 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -247,6 +247,8 @@
 
 	oops_in_progress = 1;
 
+	oops_enter();
+
 	/* Amuse the user in a SPARC fashion */
 	if (err) printk(
 KERN_CRIT "      _______________________________ \n"
@@ -293,6 +295,7 @@
 		panic("Fatal exception");
 	}
 
+	oops_exit();
 	do_exit(SIGSEGV);
 }
 
@@ -494,7 +497,7 @@
 	panic(msg);
 }
 
-void handle_interruption(int code, struct pt_regs *regs)
+void notrace handle_interruption(int code, struct pt_regs *regs)
 {
 	unsigned long fault_address = 0;
 	unsigned long fault_space = 0;
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index 1a3b6cc..fd2cc4f 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -54,6 +54,8 @@
 		TEXT_TEXT
 		SCHED_TEXT
 		LOCK_TEXT
+		KPROBES_TEXT
+		IRQENTRY_TEXT
 		*(.text.do_softirq)
 		*(.text.sys_exit)
 		*(.text.do_sigaltstack)
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index 9d704d9..4356ceb 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -456,6 +456,13 @@
 {
 	int codesize, reservedpages, datasize, initsize;
 
+	/* Do sanity checks on page table constants */
+	BUILD_BUG_ON(PTE_ENTRY_SIZE != sizeof(pte_t));
+	BUILD_BUG_ON(PMD_ENTRY_SIZE != sizeof(pmd_t));
+	BUILD_BUG_ON(PGD_ENTRY_SIZE != sizeof(pgd_t));
+	BUILD_BUG_ON(PAGE_SHIFT + BITS_PER_PTE + BITS_PER_PMD + BITS_PER_PGD
+			> BITS_PER_LONG);
+
 	high_memory = __va((max_pfn << PAGE_SHIFT));
 
 #ifndef CONFIG_DISCONTIGMEM
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 45192dc..9e08d8a6 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -346,7 +346,7 @@
 	help
 	  Hypervisor-assisted dump is meant to be a kdump replacement
 	  offering robustness and speed not possible without system
-	  hypervisor assistence.
+	  hypervisor assistance.
 
 	  If unsure, say "N"
 
diff --git a/arch/powerpc/include/asm/mmzone.h b/arch/powerpc/include/asm/mmzone.h
index 19f299b..35acac9 100644
--- a/arch/powerpc/include/asm/mmzone.h
+++ b/arch/powerpc/include/asm/mmzone.h
@@ -8,6 +8,7 @@
 #define _ASM_MMZONE_H_
 #ifdef __KERNEL__
 
+#include <linux/cpumask.h>
 
 /*
  * generic non-linear memory support:
diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/ps3.h
index 67f1812..cdb6fd8 100644
--- a/arch/powerpc/include/asm/ps3.h
+++ b/arch/powerpc/include/asm/ps3.h
@@ -50,6 +50,9 @@
 
 enum ps3_param_av_multi_out ps3_os_area_get_av_multi_out(void);
 
+extern u64 ps3_os_area_get_rtc_diff(void);
+extern void ps3_os_area_set_rtc_diff(u64 rtc_diff);
+
 /* dma routines */
 
 enum ps3_dma_page_size {
diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c
index 5b5d16b..5455943 100644
--- a/arch/powerpc/kernel/ftrace.c
+++ b/arch/powerpc/kernel/ftrace.c
@@ -557,7 +557,6 @@
 void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
 {
 	unsigned long old;
-	unsigned long long calltime;
 	int faulted;
 	struct ftrace_graph_ent trace;
 	unsigned long return_hooker = (unsigned long)&return_to_handler;
@@ -606,10 +605,7 @@
 		return;
 	}
 
-	calltime = cpu_clock(raw_smp_processor_id());
-
-	if (ftrace_push_return_trace(old, calltime,
-				self_addr, &trace.depth) == -EBUSY) {
+	if (ftrace_push_return_trace(old, self_addr, &trace.depth) == -EBUSY) {
 		*parent = old;
 		return;
 	}
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index c956403..926ea86 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -1127,3 +1127,19 @@
 	dr->result_low  = ((u64)y << 32) + z;
 
 }
+
+static int __init rtc_init(void)
+{
+	struct platform_device *pdev;
+
+	if (!ppc_md.get_rtc_time)
+		return -ENODEV;
+
+	pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0);
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	return 0;
+}
+
+module_init(rtc_init);
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index ffa2a9f..e3e8707 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -293,7 +293,7 @@
 config OF_RTC
 	bool
 	help
-	  Uses information from the OF or flattened device tree to instatiate
+	  Uses information from the OF or flattened device tree to instantiate
 	  platform devices for direct mapped RTC chips like the DS1742 or DS1743.
 
 source "arch/powerpc/sysdev/bestcomm/Kconfig"
diff --git a/arch/powerpc/platforms/ps3/os-area.c b/arch/powerpc/platforms/ps3/os-area.c
index e1c83c2..86e392b1 100644
--- a/arch/powerpc/platforms/ps3/os-area.c
+++ b/arch/powerpc/platforms/ps3/os-area.c
@@ -808,6 +808,7 @@
 {
 	return saved_params.rtc_diff;
 }
+EXPORT_SYMBOL(ps3_os_area_get_rtc_diff);
 
 /**
  * ps3_os_area_set_rtc_diff - Set the rtc diff value.
@@ -823,6 +824,7 @@
 		os_area_queue_work();
 	}
 }
+EXPORT_SYMBOL(ps3_os_area_set_rtc_diff);
 
 /**
  * ps3_os_area_get_av_multi_out - Returns the default video mode.
diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h
index 235c13e..136aa06 100644
--- a/arch/powerpc/platforms/ps3/platform.h
+++ b/arch/powerpc/platforms/ps3/platform.h
@@ -64,8 +64,6 @@
 
 void __init ps3_os_area_save_params(void);
 void __init ps3_os_area_init(void);
-u64 ps3_os_area_get_rtc_diff(void);
-void ps3_os_area_set_rtc_diff(u64 rtc_diff);
 
 /* spu */
 
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index 3331ccb..6618182 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -270,8 +270,6 @@
 	.init_IRQ			= ps3_init_IRQ,
 	.panic				= ps3_panic,
 	.get_boot_time			= ps3_get_boot_time,
-	.set_rtc_time			= ps3_set_rtc_time,
-	.get_rtc_time			= ps3_get_rtc_time,
 	.set_dabr			= ps3_set_dabr,
 	.calibrate_decr			= ps3_calibrate_decr,
 	.progress			= ps3_progress,
diff --git a/arch/powerpc/platforms/ps3/time.c b/arch/powerpc/platforms/ps3/time.c
index d0daf7d..b178a1e 100644
--- a/arch/powerpc/platforms/ps3/time.c
+++ b/arch/powerpc/platforms/ps3/time.c
@@ -19,6 +19,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/platform_device.h>
 
 #include <asm/rtc.h>
 #include <asm/lv1call.h>
@@ -74,23 +75,20 @@
 	return rtc_val;
 }
 
-int ps3_set_rtc_time(struct rtc_time *tm)
-{
-	u64 now = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
-		tm->tm_hour, tm->tm_min, tm->tm_sec);
-
-	ps3_os_area_set_rtc_diff(now - read_rtc());
-	return 0;
-}
-
-void ps3_get_rtc_time(struct rtc_time *tm)
-{
-	to_tm(read_rtc() + ps3_os_area_get_rtc_diff(), tm);
-	tm->tm_year -= 1900;
-	tm->tm_mon -= 1;
-}
-
 unsigned long __init ps3_get_boot_time(void)
 {
 	return read_rtc() + ps3_os_area_get_rtc_diff();
 }
+
+static int __init ps3_rtc_init(void)
+{
+	struct platform_device *pdev;
+
+	pdev = platform_device_register_simple("rtc-ps3", -1, NULL, 0);
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	return 0;
+}
+
+module_init(ps3_rtc_init);
diff --git a/arch/powerpc/sysdev/bestcomm/Kconfig b/arch/powerpc/sysdev/bestcomm/Kconfig
index 0b192a1..29e4270 100644
--- a/arch/powerpc/sysdev/bestcomm/Kconfig
+++ b/arch/powerpc/sysdev/bestcomm/Kconfig
@@ -9,8 +9,8 @@
 	select PPC_LIB_RHEAP
 	help
 	  BestComm is the name of the communication coprocessor found
-	  on the Freescale MPC5200 family of processor. It's usage is
-	  optionnal for some drivers (like ATA), but required for
+	  on the Freescale MPC5200 family of processor.  Its usage is
+	  optional for some drivers (like ATA), but required for
 	  others (like FEC).
 
 	  If you want to use drivers that require DMA operations,
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h
index 2009158..72137bc 100644
--- a/arch/s390/include/asm/smp.h
+++ b/arch/s390/include/asm/smp.h
@@ -92,12 +92,6 @@
 #endif
 
 #ifndef CONFIG_SMP
-static inline void smp_send_stop(void)
-{
-	/* Disable all interrupts/machine checks */
-	__load_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK);
-}
-
 #define hard_smp_processor_id()		0
 #define smp_cpu_not_running(cpu)	1
 #endif
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 8d50d52..5e4babe 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -28,6 +28,7 @@
 	select HAVE_FTRACE_MCOUNT_RECORD
 	select HAVE_DYNAMIC_FTRACE
 	select HAVE_ARCH_KGDB
+	select ARCH_HIBERNATION_POSSIBLE if MMU
 
 config SUPERH64
 	def_bool y if CPU_SH5
@@ -129,6 +130,9 @@
 config ARCH_NO_VIRT_TO_BUS
 	def_bool y
 
+config ARCH_HAS_DEFAULT_IDLE
+	def_bool y
+
 config IO_TRAPPED
 	bool
 
@@ -530,7 +534,7 @@
 
 config KEXEC
 	bool "kexec system call (EXPERIMENTAL)"
-	depends on SUPERH32 && EXPERIMENTAL
+	depends on SUPERH32 && EXPERIMENTAL && MMU
 	help
 	  kexec is a system call that implements the ability to shutdown your
 	  current kernel, and to start another kernel.  It is like a reboot
@@ -640,10 +644,10 @@
 	depends on GUSA && CPU_SH3 || (CPU_SH4 && !CPU_SH4A)
 	help
 	  Enabling this option will allow the kernel to implement some
-	  atomic operations using a software implemention of load-locked/
+	  atomic operations using a software implementation of load-locked/
 	  store-conditional (LLSC). On machines which do not have hardware
 	  LLSC, this should be more efficient than the other alternative of
-	  disabling insterrupts around the atomic sequence.
+	  disabling interrupts around the atomic sequence.
 
 endmenu
 
diff --git a/arch/sh/boards/board-ap325rxa.c b/arch/sh/boards/board-ap325rxa.c
index e27655b..912458f 100644
--- a/arch/sh/boards/board-ap325rxa.c
+++ b/arch/sh/boards/board-ap325rxa.c
@@ -22,6 +22,7 @@
 #include <linux/gpio.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_gpio.h>
+#include <media/ov772x.h>
 #include <media/soc_camera.h>
 #include <media/soc_camera_platform.h>
 #include <media/sh_mobile_ceu.h>
@@ -235,6 +236,7 @@
 }
 
 #ifdef CONFIG_I2C
+/* support for the old ncm03j camera */
 static unsigned char camera_ncm03j_magic[] =
 {
 	0x87, 0x00, 0x88, 0x08, 0x89, 0x01, 0x8A, 0xE8,
@@ -255,6 +257,23 @@
 	0x63, 0xD4, 0x64, 0xEA, 0xD6, 0x0F,
 };
 
+static int camera_probe(void)
+{
+	struct i2c_adapter *a = i2c_get_adapter(0);
+	struct i2c_msg msg;
+	int ret;
+
+	camera_power(1);
+	msg.addr = 0x6e;
+	msg.buf = camera_ncm03j_magic;
+	msg.len = 2;
+	msg.flags = 0;
+	ret = i2c_transfer(a, &msg, 1);
+	camera_power(0);
+
+	return ret;
+}
+
 static int camera_set_capture(struct soc_camera_platform_info *info,
 			      int enable)
 {
@@ -306,12 +325,37 @@
 		.platform_data	= &camera_info,
 	},
 };
+
+static int __init camera_setup(void)
+{
+	if (camera_probe() > 0)
+		platform_device_register(&camera_device);
+
+	return 0;
+}
+late_initcall(camera_setup);
+
 #endif /* CONFIG_I2C */
 
+static int ov7725_power(struct device *dev, int mode)
+{
+	camera_power(0);
+	if (mode)
+		camera_power(1);
+
+	return 0;
+}
+
+static struct ov772x_camera_info ov7725_info = {
+	.buswidth  = SOCAM_DATAWIDTH_8,
+	.flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP,
+	.link = {
+		.power  = ov7725_power,
+	},
+};
+
 static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
-	.flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
-	SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_HIGH | SOCAM_MASTER |
-	SOCAM_DATAWIDTH_8,
+	.flags = SH_CEU_FLAG_USE_8BIT_BUS,
 };
 
 static struct resource ceu_resources[] = {
@@ -359,9 +403,6 @@
 	&ap325rxa_nor_flash_device,
 	&lcdc_device,
 	&ceu_device,
-#ifdef CONFIG_I2C
-	&camera_device,
-#endif
 	&nand_flash_device,
 	&sdcard_cn3_device,
 };
@@ -370,6 +411,10 @@
 	{
 		I2C_BOARD_INFO("pcf8563", 0x51),
 	},
+	{
+		I2C_BOARD_INFO("ov772x", 0x21),
+		.platform_data = &ov7725_info,
+	},
 };
 
 static struct spi_board_info ap325rxa_spi_devices[] = {
diff --git a/arch/sh/boards/board-urquell.c b/arch/sh/boards/board-urquell.c
index 17036ce..8367d1d 100644
--- a/arch/sh/boards/board-urquell.c
+++ b/arch/sh/boards/board-urquell.c
@@ -129,6 +129,10 @@
 	gpio_request(GPIO_FN_USB_OVC0,  NULL);
 	gpio_request(GPIO_FN_USB_PENC0, NULL);
 
+	/* enable LAN */
+	__raw_writew(__raw_readw(UBOARDREG(IRL2MSKR)) & ~0x00000001,
+		  UBOARDREG(IRL2MSKR));
+
 	return platform_add_devices(urquell_devices,
 				    ARRAY_SIZE(urquell_devices));
 }
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index 4fd6a72..1ee1de0 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -352,9 +352,7 @@
 }
 
 static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
-	.flags = SOCAM_MASTER | SOCAM_DATAWIDTH_8 | SOCAM_PCLK_SAMPLE_RISING
-	| SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH
-	| SOCAM_DATA_ACTIVE_HIGH,
+	.flags = SH_CEU_FLAG_USE_8BIT_BUS,
 };
 
 static struct resource migor_ceu_resources[] = {
diff --git a/arch/sh/configs/ap325rxa_defconfig b/arch/sh/configs/ap325rxa_defconfig
index 352f87d..c8d982a 100644
--- a/arch/sh/configs/ap325rxa_defconfig
+++ b/arch/sh/configs/ap325rxa_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Tue Jan 27 11:45:08 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 17:46:53 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -16,14 +16,16 @@
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
-# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -43,6 +45,15 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -58,6 +69,7 @@
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -66,10 +78,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -77,6 +87,7 @@
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -115,11 +126,6 @@
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -128,6 +134,7 @@
 CONFIG_CPU_SH4=y
 CONFIG_CPU_SH4A=y
 CONFIG_CPU_SHX2=y
+CONFIG_ARCH_SHMOBILE=y
 # CONFIG_CPU_SUBTYPE_SH7619 is not set
 # CONFIG_CPU_SUBTYPE_SH7201 is not set
 # CONFIG_CPU_SUBTYPE_SH7203 is not set
@@ -156,6 +163,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -198,11 +206,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -228,6 +237,7 @@
 # Timer and clock configuration
 #
 CONFIG_SH_TMU=y
+# CONFIG_SH_TIMER_CMT is not set
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=33333333
 CONFIG_TICK_ONESHOT=y
@@ -304,7 +314,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -359,6 +368,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -371,7 +381,6 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -483,7 +492,6 @@
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -510,10 +518,18 @@
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -559,9 +575,11 @@
 # CONFIG_LIBFC is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -594,8 +612,10 @@
 # CONFIG_STNIC is not set
 # CONFIG_SMC91X is not set
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 CONFIG_SMSC911X=y
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -612,7 +632,6 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -687,6 +706,7 @@
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
@@ -723,12 +743,9 @@
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_AT24 is not set
-# CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
@@ -748,7 +765,6 @@
 #
 # SPI Protocol Masters
 #
-# CONFIG_SPI_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
@@ -822,7 +838,7 @@
 #
 # CONFIG_MEDIA_ATTACH is not set
 CONFIG_MEDIA_TUNER=y
-# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
 CONFIG_MEDIA_TUNER_SIMPLE=y
 CONFIG_MEDIA_TUNER_TDA8290=y
 CONFIG_MEDIA_TUNER_TDA9887=y
@@ -831,6 +847,7 @@
 CONFIG_MEDIA_TUNER_MT20XX=y
 CONFIG_MEDIA_TUNER_XC2028=y
 CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_MC44S803=y
 CONFIG_VIDEO_V4L2=y
 CONFIG_VIDEOBUF_GEN=y
 CONFIG_VIDEOBUF_DMA_CONTIG=y
@@ -886,6 +903,7 @@
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -995,6 +1013,7 @@
 #
 # CONFIG_RTC_DRV_SH is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 CONFIG_UIO=y
 # CONFIG_UIO_PDRV is not set
 CONFIG_UIO_PDRV_GENIRQ=y
@@ -1096,7 +1115,6 @@
 CONFIG_EXPORTFS=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1177,7 +1195,6 @@
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -1204,10 +1221,12 @@
 CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -1276,6 +1295,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1296,7 +1316,7 @@
 CONFIG_CRC32=y
 CONFIG_CRC7=y
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/cayman_defconfig b/arch/sh/configs/cayman_defconfig
index 9289501..fa5fc1e 100644
--- a/arch/sh/configs/cayman_defconfig
+++ b/arch/sh/configs/cayman_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27
-# Wed Oct 22 18:04:52 2008
+# Linux kernel version: 2.6.29
+# Thu Apr  2 17:49:14 2009
 #
 CONFIG_SUPERH=y
 # CONFIG_SUPERH32 is not set
@@ -16,6 +16,8 @@
 # CONFIG_GENERIC_GPIO is not set
 # CONFIG_GENERIC_TIME is not set
 # CONFIG_GENERIC_CLOCKEVENTS is not set
+# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
+# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -23,6 +25,7 @@
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -40,10 +43,19 @@
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -51,6 +63,7 @@
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -61,10 +74,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -73,18 +84,18 @@
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -92,11 +103,9 @@
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -112,7 +121,6 @@
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_CLASSIC_RCU=y
 # CONFIG_FREEZER is not set
 
 #
@@ -120,6 +128,7 @@
 #
 CONFIG_CPU_SH5=y
 # CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7201 is not set
 # CONFIG_CPU_SUBTYPE_SH7203 is not set
 # CONFIG_CPU_SUBTYPE_SH7206 is not set
 # CONFIG_CPU_SUBTYPE_SH7263 is not set
@@ -146,6 +155,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -188,16 +198,16 @@
 CONFIG_SPARSEMEM_STATIC=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_RESOURCES_64BIT=y
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_CACHE_WRITEBACK is not set
 # CONFIG_CACHE_WRITETHROUGH is not set
 CONFIG_CACHE_OFF=y
@@ -256,7 +266,6 @@
 # CONFIG_PREEMPT_NONE is not set
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
-# CONFIG_PREEMPT_RCU is not set
 
 #
 # Boot options
@@ -272,9 +281,12 @@
 CONFIG_SH_PCIDMA_NONCOHERENT=y
 CONFIG_PCI_AUTO=y
 CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
+# CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 
@@ -285,6 +297,12 @@
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 # CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+# CONFIG_CPU_IDLE is not set
 CONFIG_NET=y
 
 #
@@ -344,7 +362,9 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -355,13 +375,13 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -400,11 +420,20 @@
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -447,6 +476,7 @@
 # CONFIG_SCSI_SRP_ATTRS is not set
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_CXGB3_ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
@@ -459,7 +489,10 @@
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
 # CONFIG_SCSI_HPTIOP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_FCOE is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
@@ -478,6 +511,7 @@
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 # CONFIG_FUSION is not set
@@ -493,6 +527,7 @@
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -510,7 +545,10 @@
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -543,9 +581,11 @@
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
 # CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_CHELSIO_T3 is not set
 # CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
@@ -554,11 +594,13 @@
 # CONFIG_MYRI10GE is not set
 # CONFIG_NETXEN_NIC is not set
 # CONFIG_NIU is not set
+# CONFIG_MLX4_EN is not set
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 
 #
@@ -566,7 +608,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -636,10 +681,12 @@
 # CONFIG_SERIAL_SH_SCI is not set
 # CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -700,12 +747,9 @@
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
@@ -725,8 +769,10 @@
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
 # CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -747,10 +793,14 @@
 # CONFIG_SENSORS_LM90 is not set
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_MAX6650 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -786,11 +836,11 @@
 #
 # CONFIG_PCIPCWATCHDOG is not set
 # CONFIG_WDTPCI is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
@@ -802,6 +852,8 @@
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_REGULATOR is not set
 
 #
 # Multimedia devices
@@ -822,7 +874,7 @@
 #
 # CONFIG_MEDIA_ATTACH is not set
 CONFIG_MEDIA_TUNER=m
-# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
 CONFIG_MEDIA_TUNER_SIMPLE=m
 CONFIG_MEDIA_TUNER_TDA8290=m
 CONFIG_MEDIA_TUNER_TDA9887=m
@@ -831,6 +883,7 @@
 CONFIG_MEDIA_TUNER_MT20XX=m
 CONFIG_MEDIA_TUNER_XC2028=m
 CONFIG_MEDIA_TUNER_XC5000=m
+CONFIG_MEDIA_TUNER_MC44S803=m
 CONFIG_VIDEO_V4L2=m
 CONFIG_VIDEO_V4L1=m
 CONFIG_VIDEO_CAPTURE_DRIVERS=y
@@ -853,6 +906,7 @@
 # CONFIG_VIDEO_CAFE_CCIC is not set
 # CONFIG_SOC_CAMERA is not set
 # CONFIG_RADIO_ADAPTERS is not set
+# CONFIG_DVB_DYNAMIC_MINORS is not set
 CONFIG_DVB_CAPTURE_DRIVERS=y
 
 #
@@ -884,89 +938,7 @@
 #
 # Supported DVB Frontends
 #
-
-#
-# Customise DVB Frontends
-#
 # CONFIG_DVB_FE_CUSTOMISE is not set
-
-#
-# DVB-S (satellite) frontends
-#
-# CONFIG_DVB_CX24110 is not set
-# CONFIG_DVB_CX24123 is not set
-# CONFIG_DVB_MT312 is not set
-# CONFIG_DVB_S5H1420 is not set
-# CONFIG_DVB_STV0288 is not set
-# CONFIG_DVB_STB6000 is not set
-# CONFIG_DVB_STV0299 is not set
-# CONFIG_DVB_TDA8083 is not set
-# CONFIG_DVB_TDA10086 is not set
-# CONFIG_DVB_VES1X93 is not set
-# CONFIG_DVB_TUNER_ITD1000 is not set
-# CONFIG_DVB_TDA826X is not set
-# CONFIG_DVB_TUA6100 is not set
-# CONFIG_DVB_CX24116 is not set
-# CONFIG_DVB_SI21XX is not set
-
-#
-# DVB-T (terrestrial) frontends
-#
-# CONFIG_DVB_SP8870 is not set
-# CONFIG_DVB_SP887X is not set
-# CONFIG_DVB_CX22700 is not set
-# CONFIG_DVB_CX22702 is not set
-# CONFIG_DVB_DRX397XD is not set
-# CONFIG_DVB_L64781 is not set
-# CONFIG_DVB_TDA1004X is not set
-# CONFIG_DVB_NXT6000 is not set
-# CONFIG_DVB_MT352 is not set
-# CONFIG_DVB_ZL10353 is not set
-# CONFIG_DVB_DIB3000MB is not set
-# CONFIG_DVB_DIB3000MC is not set
-# CONFIG_DVB_DIB7000M is not set
-# CONFIG_DVB_DIB7000P is not set
-# CONFIG_DVB_TDA10048 is not set
-
-#
-# DVB-C (cable) frontends
-#
-# CONFIG_DVB_VES1820 is not set
-# CONFIG_DVB_TDA10021 is not set
-# CONFIG_DVB_TDA10023 is not set
-# CONFIG_DVB_STV0297 is not set
-
-#
-# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
-#
-# CONFIG_DVB_NXT200X is not set
-# CONFIG_DVB_OR51211 is not set
-# CONFIG_DVB_OR51132 is not set
-# CONFIG_DVB_BCM3510 is not set
-# CONFIG_DVB_LGDT330X is not set
-# CONFIG_DVB_S5H1409 is not set
-# CONFIG_DVB_AU8522 is not set
-# CONFIG_DVB_S5H1411 is not set
-
-#
-# Digital terrestrial only tuners/PLL
-#
-# CONFIG_DVB_PLL is not set
-# CONFIG_DVB_TUNER_DIB0070 is not set
-
-#
-# SEC control devices for DVB-S
-#
-# CONFIG_DVB_LNBP21 is not set
-# CONFIG_DVB_ISL6405 is not set
-# CONFIG_DVB_ISL6421 is not set
-# CONFIG_DVB_LGS8GL5 is not set
-
-#
-# Tools to develop new frontends
-#
-# CONFIG_DVB_DUMMY_FE is not set
-# CONFIG_DVB_AF9013 is not set
 CONFIG_DAB=y
 
 #
@@ -979,15 +951,16 @@
 CONFIG_FIRMWARE_EDID=y
 # CONFIG_FB_DDC is not set
 # CONFIG_FB_BOOT_VESA_SUPPORT is not set
-CONFIG_FB_CFB_FILLRECT=m
-CONFIG_FB_CFB_COPYAREA=m
-CONFIG_FB_CFB_IMAGEBLIT=m
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
 # CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
-# CONFIG_FB_SYS_FILLRECT is not set
-# CONFIG_FB_SYS_COPYAREA is not set
-# CONFIG_FB_SYS_IMAGEBLIT is not set
+CONFIG_FB_SYS_FILLRECT=m
+CONFIG_FB_SYS_COPYAREA=m
+CONFIG_FB_SYS_IMAGEBLIT=m
 # CONFIG_FB_FOREIGN_ENDIAN is not set
-# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_SYS_FOPS=m
+CONFIG_FB_DEFERRED_IO=y
 # CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_BACKLIGHT is not set
@@ -1025,6 +998,8 @@
 CONFIG_FB_SH_MOBILE_LCDC=m
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -1081,9 +1056,14 @@
 #
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -1091,6 +1071,7 @@
 # CONFIG_INFINIBAND is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -1114,6 +1095,7 @@
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1148,10 +1130,7 @@
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 # CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
@@ -1160,6 +1139,7 @@
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
 # CONFIG_OMFS_FS is not set
@@ -1179,7 +1159,6 @@
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1252,6 +1231,7 @@
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
 CONFIG_FRAME_POINTER=y
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
@@ -1260,17 +1240,25 @@
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_PAGE_POISONING is not set
+
+#
+# Tracers
+#
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_DEBUG_BOOTMEM is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_4KSTACKS is not set
-CONFIG_SH64_PROC_ASIDS=y
+# CONFIG_SH_NO_BSS_INIT is not set
+# CONFIG_MORE_COMPILE_OPTIONS is not set
 CONFIG_SH64_SR_WATCH=y
 # CONFIG_POOR_MANS_STRACE is not set
-# CONFIG_SH_ALPHANUMERIC is not set
-# CONFIG_SH_NO_BSS_INIT is not set
 
 #
 # Security options
@@ -1286,6 +1274,7 @@
 #
 # CONFIG_CRYPTO_FIPS is not set
 # CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_CRYPTD is not set
@@ -1356,6 +1345,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1369,6 +1359,7 @@
 # Library routines
 #
 CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
@@ -1376,7 +1367,7 @@
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/dreamcast_defconfig b/arch/sh/configs/dreamcast_defconfig
index 2d86e04..5c11236 100644
--- a/arch/sh/configs/dreamcast_defconfig
+++ b/arch/sh/configs/dreamcast_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 16:54:55 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 17:51:48 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -44,10 +45,19 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -55,6 +65,7 @@
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 # CONFIG_SYSCTL_SYSCALL is not set
@@ -64,10 +75,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -76,6 +85,7 @@
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -116,11 +126,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -155,6 +160,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -202,11 +208,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -263,9 +270,12 @@
 #
 CONFIG_SH_DMA_API=y
 CONFIG_SH_DMA=y
-CONFIG_NR_ONCHIP_DMA_CHANNELS=4
+CONFIG_SH_DMA_IRQ_MULTI=y
+CONFIG_NR_ONCHIP_DMA_CHANNELS=6
 CONFIG_NR_DMA_CHANNELS_BOOL=y
 CONFIG_NR_DMA_CHANNELS=9
+# CONFIG_PVR2_DMA is not set
+# CONFIG_G2_DMA is not set
 
 #
 # Companion Chips
@@ -314,6 +324,8 @@
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 
@@ -335,7 +347,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -387,6 +398,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -399,13 +411,13 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -439,12 +451,16 @@
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -470,6 +486,7 @@
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -487,8 +504,10 @@
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -532,7 +551,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -628,6 +650,7 @@
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -746,6 +769,7 @@
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -802,9 +826,13 @@
 #
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -813,6 +841,7 @@
 # CONFIG_INFINIBAND is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -828,6 +857,7 @@
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 # CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -871,6 +901,7 @@
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -920,7 +951,6 @@
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -1012,6 +1042,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1033,7 +1064,7 @@
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/edosk7705_defconfig b/arch/sh/configs/edosk7705_defconfig
index 461bfb35..f4c34b0 100644
--- a/arch/sh/configs/edosk7705_defconfig
+++ b/arch/sh/configs/edosk7705_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 16:55:29 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 17:54:02 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -16,13 +16,14 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -35,6 +36,15 @@
 # CONFIG_LOCALVERSION_AUTO is not set
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=17
 # CONFIG_CGROUPS is not set
@@ -50,7 +60,6 @@
 # CONFIG_PRINTK is not set
 # CONFIG_BUG is not set
 # CONFIG_ELF_CORE is not set
-# CONFIG_COMPAT_BRK is not set
 # CONFIG_BASE_FULL is not set
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
@@ -60,6 +69,7 @@
 CONFIG_SHMEM=y
 # CONFIG_AIO is not set
 # CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
@@ -74,11 +84,6 @@
 CONFIG_BASE_SMALL=1
 # CONFIG_MODULES is not set
 # CONFIG_BLOCK is not set
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -113,6 +118,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -157,12 +163,13 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
 CONFIG_SH7705_CACHE_32KB=y
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -243,7 +250,6 @@
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 # CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_NET is not set
@@ -361,6 +367,7 @@
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
diff --git a/arch/sh/configs/edosk7760_defconfig b/arch/sh/configs/edosk7760_defconfig
index 14d4b35..7825c26 100644
--- a/arch/sh/configs/edosk7760_defconfig
+++ b/arch/sh/configs/edosk7760_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 16:55:48 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 17:54:57 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -43,34 +44,45 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -79,6 +91,7 @@
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
@@ -118,11 +131,6 @@
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -157,6 +165,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -198,11 +207,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -245,7 +255,7 @@
 #
 CONFIG_SH_DMA_API=y
 CONFIG_SH_DMA=y
-CONFIG_NR_ONCHIP_DMA_CHANNELS=4
+CONFIG_NR_ONCHIP_DMA_CHANNELS=8
 # CONFIG_NR_DMA_CHANNELS_BOOL is not set
 # CONFIG_SH_DMABRG is not set
 
@@ -310,7 +320,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -360,6 +369,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -372,13 +382,13 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -402,6 +412,7 @@
 CONFIG_MTD_DEBUG_VERBOSE=0
 CONFIG_MTD_CONCAT=y
 CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 # CONFIG_MTD_AR7_PARTS is not set
@@ -454,9 +465,7 @@
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0xffffffff
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=4
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -477,6 +486,11 @@
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -506,6 +520,7 @@
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -518,8 +533,10 @@
 # CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 CONFIG_SMC91X=y
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -536,7 +553,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -607,6 +627,7 @@
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
@@ -643,12 +664,9 @@
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 CONFIG_I2C_DEBUG_CORE=y
@@ -680,6 +698,7 @@
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
 # CONFIG_REGULATOR is not set
 
 #
@@ -732,6 +751,7 @@
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -750,6 +770,7 @@
 CONFIG_SND=y
 CONFIG_SND_TIMER=y
 CONFIG_SND_PCM=y
+CONFIG_SND_JACK=y
 # CONFIG_SND_SEQUENCER is not set
 # CONFIG_SND_MIXER_OSS is not set
 # CONFIG_SND_PCM_OSS is not set
@@ -781,6 +802,7 @@
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -806,6 +828,7 @@
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -851,6 +874,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -868,7 +892,6 @@
 CONFIG_LOCKD=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -974,6 +997,7 @@
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -989,7 +1013,6 @@
 # CONFIG_BOOT_TRACER is not set
 # CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1095,6 +1118,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1115,7 +1139,9 @@
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/espt_defconfig b/arch/sh/configs/espt_defconfig
index 873ec42..ebb4c37 100644
--- a/arch/sh/configs/espt_defconfig
+++ b/arch/sh/configs/espt_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc7
-# Tue Mar 17 13:25:58 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 17:58:18 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -71,6 +72,7 @@
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 # CONFIG_SYSCTL_SYSCALL is not set
@@ -80,10 +82,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -91,6 +91,7 @@
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -213,11 +214,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -318,7 +320,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -373,6 +374,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -380,12 +382,12 @@
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 # CONFIG_WIRELESS is not set
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
@@ -548,9 +550,11 @@
 # CONFIG_LIBFC is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -583,8 +587,10 @@
 # CONFIG_STNIC is not set
 CONFIG_SH_ETH=y
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -601,7 +607,6 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -685,6 +690,7 @@
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
@@ -764,6 +770,7 @@
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -817,6 +824,7 @@
 # CONFIG_USB_C67X00_HCD is not set
 # CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
 # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
@@ -834,11 +842,11 @@
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -880,7 +888,6 @@
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
@@ -894,12 +901,14 @@
 #
 # OTG and related infrastructure
 #
+# CONFIG_NOP_USB_XCEIV is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -987,7 +996,6 @@
 CONFIG_LOCKD=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1071,7 +1079,7 @@
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -1163,6 +1171,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1184,7 +1193,7 @@
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/hp6xx_defconfig b/arch/sh/configs/hp6xx_defconfig
index 847a251..82b113a 100644
--- a/arch/sh/configs/hp6xx_defconfig
+++ b/arch/sh/configs/hp6xx_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 16:56:55 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:01:05 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -39,11 +40,20 @@
 # CONFIG_SYSVIPC is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -51,6 +61,7 @@
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 # CONFIG_SYSCTL_SYSCALL is not set
@@ -60,10 +71,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -71,6 +80,7 @@
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -104,11 +114,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_FREEZER=y
 
 #
@@ -143,6 +148,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -184,11 +190,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -208,6 +215,7 @@
 #
 # CONFIG_SH_SOLUTION_ENGINE is not set
 CONFIG_SH_HP6XX=y
+# CONFIG_SH_POLARIS is not set
 
 #
 # Timer and clock configuration
@@ -229,7 +237,7 @@
 #
 CONFIG_SH_DMA_API=y
 CONFIG_SH_DMA=y
-CONFIG_NR_ONCHIP_DMA_CHANNELS=4
+CONFIG_NR_ONCHIP_DMA_CHANNELS=6
 # CONFIG_NR_DMA_CHANNELS_BOOL is not set
 
 #
@@ -302,6 +310,7 @@
 CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
 CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
 CONFIG_APM_EMULATION=y
 # CONFIG_CPU_IDLE is not set
 # CONFIG_NET is not set
@@ -329,9 +338,13 @@
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -375,6 +388,7 @@
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
@@ -471,6 +485,7 @@
 CONFIG_LEGACY_PTY_COUNT=64
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 
 #
@@ -554,12 +569,13 @@
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=y
 # CONFIG_LCD_ILI9320 is not set
 # CONFIG_LCD_PLATFORM is not set
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_GENERIC=y
 CONFIG_BACKLIGHT_HP680=y
 
 #
@@ -631,6 +647,7 @@
 #
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -647,6 +664,7 @@
 # CONFIG_FS_POSIX_ACL is not set
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -692,6 +710,7 @@
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -771,7 +790,6 @@
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -799,10 +817,12 @@
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 
@@ -870,6 +890,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -890,7 +911,6 @@
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
diff --git a/arch/sh/configs/landisk_defconfig b/arch/sh/configs/landisk_defconfig
index d3bbbb0..b6fa4a7 100644
--- a/arch/sh/configs/landisk_defconfig
+++ b/arch/sh/configs/landisk_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 16:58:46 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:02:54 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -42,10 +43,19 @@
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -53,6 +63,7 @@
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 # CONFIG_SYSCTL_SYSCALL is not set
@@ -62,10 +73,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -74,6 +83,7 @@
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -113,11 +123,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -152,6 +157,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -193,11 +199,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -290,6 +297,8 @@
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 CONFIG_PCCARD=y
 # CONFIG_PCMCIA_DEBUG is not set
 CONFIG_PCMCIA=y
@@ -329,7 +338,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -410,6 +418,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -422,13 +431,13 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -468,18 +477,23 @@
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
 
 #
 # Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
+CONFIG_IDE_XFER_MODE=y
 CONFIG_IDE_ATAPI=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_IDE_GD=y
@@ -585,6 +599,7 @@
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_LIBFC is not set
 # CONFIG_FCOE is not set
@@ -607,6 +622,7 @@
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
@@ -631,6 +647,7 @@
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -648,8 +665,10 @@
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -700,6 +719,7 @@
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
 # CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
@@ -718,6 +738,7 @@
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 
 #
@@ -725,7 +746,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 
 #
 # USB Network Adapters
@@ -814,6 +838,7 @@
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 
@@ -898,6 +923,7 @@
 CONFIG_V4L_USB_DRIVERS=y
 # CONFIG_USB_VIDEO_CLASS is not set
 # CONFIG_USB_GSPCA is not set
+# CONFIG_VIDEO_HDPVR is not set
 CONFIG_VIDEO_USBVIDEO=m
 CONFIG_USB_VICAM=m
 CONFIG_USB_IBMCAM=m
@@ -911,6 +937,7 @@
 # CONFIG_USB_ZC0301 is not set
 CONFIG_USB_PWC=m
 # CONFIG_USB_PWC_DEBUG is not set
+CONFIG_USB_PWC_INPUT_EVDEV=y
 # CONFIG_USB_ZR364XX is not set
 # CONFIG_USB_STKWEBCAM is not set
 # CONFIG_USB_S2255 is not set
@@ -1020,6 +1047,7 @@
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
 CONFIG_USB_OHCI_HCD=y
@@ -1041,22 +1069,21 @@
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
 CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
-CONFIG_USB_STORAGE_DATAFAB=y
-CONFIG_USB_STORAGE_FREECOM=y
-CONFIG_USB_STORAGE_ISD200=y
-CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_DATAFAB=m
+CONFIG_USB_STORAGE_FREECOM=m
+CONFIG_USB_STORAGE_ISD200=m
 # CONFIG_USB_STORAGE_USBAT is not set
-CONFIG_USB_STORAGE_SDDR09=y
-CONFIG_USB_STORAGE_SDDR55=y
-CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_SDDR09=m
+CONFIG_USB_STORAGE_SDDR55=m
+CONFIG_USB_STORAGE_JUMPSHOT=m
 # CONFIG_USB_STORAGE_ALAUDA is not set
 # CONFIG_USB_STORAGE_ONETOUCH is not set
 # CONFIG_USB_STORAGE_KARMA is not set
@@ -1081,7 +1108,7 @@
 # CONFIG_USB_SERIAL_CH341 is not set
 # CONFIG_USB_SERIAL_WHITEHEAT is not set
 # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_CP2101 is not set
+# CONFIG_USB_SERIAL_CP210X is not set
 # CONFIG_USB_SERIAL_CYPRESS_M8 is not set
 # CONFIG_USB_SERIAL_EMPEG is not set
 CONFIG_USB_SERIAL_FTDI_SIO=m
@@ -1105,15 +1132,19 @@
 # CONFIG_USB_SERIAL_NAVMAN is not set
 CONFIG_USB_SERIAL_PL2303=m
 # CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QUALCOMM is not set
 # CONFIG_USB_SERIAL_SPCP8X5 is not set
 # CONFIG_USB_SERIAL_HP4X is not set
 # CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
 # CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_SYMBOL is not set
 # CONFIG_USB_SERIAL_TI is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
 # CONFIG_USB_SERIAL_OPTION is not set
 # CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_OPTICON is not set
 # CONFIG_USB_SERIAL_DEBUG is not set
 
 #
@@ -1130,7 +1161,6 @@
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
@@ -1143,6 +1173,11 @@
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1151,6 +1186,7 @@
 # CONFIG_INFINIBAND is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -1176,6 +1212,7 @@
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1226,6 +1263,7 @@
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -1250,7 +1288,6 @@
 CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1331,7 +1368,6 @@
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_SH_STANDARD_BIOS=y
@@ -1424,6 +1460,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1445,7 +1482,7 @@
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/lboxre2_defconfig b/arch/sh/configs/lboxre2_defconfig
index d5c5a1d..92c515c 100644
--- a/arch/sh/configs/lboxre2_defconfig
+++ b/arch/sh/configs/lboxre2_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:02:46 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:06:51 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -42,10 +43,19 @@
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -53,6 +63,7 @@
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 # CONFIG_SYSCTL_SYSCALL is not set
@@ -62,10 +73,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -74,6 +83,7 @@
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -113,11 +123,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -152,6 +157,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -193,11 +199,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -291,6 +298,8 @@
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 CONFIG_PCCARD=y
 CONFIG_PCMCIA_DEBUG=y
 CONFIG_PCMCIA=y
@@ -329,7 +338,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -408,6 +416,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -420,13 +429,13 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -465,12 +474,16 @@
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -526,6 +539,7 @@
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_LIBFC is not set
 # CONFIG_FCOE is not set
@@ -549,6 +563,7 @@
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
@@ -624,6 +639,7 @@
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -641,8 +657,10 @@
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -697,6 +715,7 @@
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
 # CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
@@ -715,6 +734,7 @@
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 
 #
@@ -722,7 +742,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 CONFIG_NET_PCMCIA=y
 # CONFIG_PCMCIA_3C589 is not set
 # CONFIG_PCMCIA_3C574 is not set
@@ -810,6 +833,7 @@
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 
@@ -921,9 +945,13 @@
 #
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -968,6 +996,7 @@
 #
 # CONFIG_RTC_DRV_SH is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -990,6 +1019,7 @@
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1036,6 +1066,7 @@
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -1124,7 +1155,6 @@
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_SH_STANDARD_BIOS=y
@@ -1217,6 +1247,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1238,7 +1269,7 @@
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/magicpanelr2_defconfig b/arch/sh/configs/magicpanelr2_defconfig
index 125d801..26586c2 100644
--- a/arch/sh/configs/magicpanelr2_defconfig
+++ b/arch/sh/configs/magicpanelr2_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:03:37 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:07:39 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -43,33 +44,44 @@
 # CONFIG_TASKSTATS is not set
 CONFIG_AUDIT=y
 # CONFIG_AUDITSYSCALL is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_RELAY=y
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -77,6 +89,7 @@
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -116,11 +129,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -155,6 +163,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -196,11 +205,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -309,7 +319,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -359,6 +368,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -371,13 +381,13 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -402,6 +412,7 @@
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
 CONFIG_MTD_REDBOOT_PARTS=y
 CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
 # CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
@@ -452,9 +463,7 @@
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0000000
-CONFIG_MTD_PHYSMAP_LEN=0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=0
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -475,6 +484,11 @@
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -491,9 +505,13 @@
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -507,6 +525,7 @@
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -538,8 +557,10 @@
 # CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 CONFIG_SMSC911X=y
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -556,7 +577,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -778,6 +802,7 @@
 #
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -797,6 +822,7 @@
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 # CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY is not set
 # CONFIG_QUOTA is not set
@@ -849,6 +875,7 @@
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -868,7 +895,6 @@
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -970,6 +996,7 @@
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -984,7 +1011,6 @@
 # CONFIG_BOOT_TRACER is not set
 # CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1025,7 +1051,8 @@
 CONFIG_AUDIT_GENERIC=y
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/microdev_defconfig b/arch/sh/configs/microdev_defconfig
index 5a1c048..7517835 100644
--- a/arch/sh/configs/microdev_defconfig
+++ b/arch/sh/configs/microdev_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:06:47 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:11:13 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -42,18 +43,32 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 # CONFIG_SYSCTL_SYSCALL is not set
@@ -63,10 +78,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -74,6 +87,7 @@
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -107,11 +121,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -146,6 +155,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -193,11 +203,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -239,7 +250,7 @@
 #
 CONFIG_SH_DMA_API=y
 CONFIG_SH_DMA=y
-CONFIG_NR_ONCHIP_DMA_CHANNELS=4
+CONFIG_NR_ONCHIP_DMA_CHANNELS=6
 # CONFIG_NR_DMA_CHANNELS_BOOL is not set
 
 #
@@ -304,7 +315,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_PACKET is not set
 # CONFIG_UNIX is not set
 CONFIG_XFRM=y
@@ -358,6 +368,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -370,13 +381,13 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -407,9 +418,13 @@
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
 
@@ -443,6 +458,7 @@
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -455,8 +471,10 @@
 # CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 CONFIG_SMC91X=y
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -473,7 +491,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -520,6 +541,7 @@
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
@@ -601,15 +623,20 @@
 #
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -632,6 +659,7 @@
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -678,6 +706,7 @@
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -698,7 +727,6 @@
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -778,7 +806,6 @@
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -806,10 +833,12 @@
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 
@@ -877,6 +906,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -897,7 +927,9 @@
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/migor_defconfig b/arch/sh/configs/migor_defconfig
index 6785767..a8720f9 100644
--- a/arch/sh/configs/migor_defconfig
+++ b/arch/sh/configs/migor_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc1
-# Thu Jan 22 09:16:16 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:14:03 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -16,15 +16,17 @@
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
-# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_NUMA=y
+CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -42,14 +44,19 @@
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_GROUP_SCHED is not set
-
-#
-# Control Group support
-#
 # CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
@@ -57,8 +64,13 @@
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 # CONFIG_SYSCTL_SYSCALL is not set
@@ -68,10 +80,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -79,6 +89,7 @@
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -120,11 +131,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -134,6 +140,7 @@
 CONFIG_CPU_SH4A=y
 CONFIG_CPU_SH4AL_DSP=y
 CONFIG_CPU_SHX2=y
+CONFIG_ARCH_SHMOBILE=y
 # CONFIG_CPU_SUBTYPE_SH7619 is not set
 # CONFIG_CPU_SUBTYPE_SH7201 is not set
 # CONFIG_CPU_SUBTYPE_SH7203 is not set
@@ -162,6 +169,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 CONFIG_CPU_SUBTYPE_SH7722=y
@@ -209,11 +217,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -243,6 +252,7 @@
 # Timer and clock configuration
 #
 CONFIG_SH_TMU=y
+# CONFIG_SH_TIMER_CMT is not set
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=33333333
 # CONFIG_NO_HZ is not set
@@ -318,7 +328,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -373,6 +382,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -380,12 +390,12 @@
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -495,7 +505,6 @@
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -514,10 +523,17 @@
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -563,9 +579,11 @@
 # CONFIG_LIBFC is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -578,8 +596,10 @@
 # CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 CONFIG_SMC91X=y
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -596,7 +616,6 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -679,6 +698,7 @@
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
@@ -715,12 +735,9 @@
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
@@ -797,7 +814,7 @@
 #
 # CONFIG_MEDIA_ATTACH is not set
 CONFIG_MEDIA_TUNER=y
-# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
 CONFIG_MEDIA_TUNER_SIMPLE=y
 CONFIG_MEDIA_TUNER_TDA8290=y
 CONFIG_MEDIA_TUNER_TDA9887=y
@@ -806,6 +823,7 @@
 CONFIG_MEDIA_TUNER_MT20XX=y
 CONFIG_MEDIA_TUNER_XC2028=y
 CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_MC44S803=y
 CONFIG_VIDEO_V4L2=y
 CONFIG_VIDEOBUF_GEN=y
 CONFIG_VIDEOBUF_DMA_CONTIG=y
@@ -866,7 +884,7 @@
 # CONFIG_USB_GADGET_MUSB_HDRC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 CONFIG_USB_GADGET=y
 # CONFIG_USB_GADGET_DEBUG_FILES is not set
@@ -905,6 +923,7 @@
 # OTG and related infrastructure
 #
 # CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -964,6 +983,7 @@
 #
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 CONFIG_UIO=y
 # CONFIG_UIO_PDRV is not set
 CONFIG_UIO_PDRV_GENIRQ=y
@@ -1045,7 +1065,6 @@
 CONFIG_LOCKD=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1090,7 +1109,7 @@
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -1117,10 +1136,12 @@
 CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -1189,6 +1210,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1209,7 +1231,9 @@
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/polaris_defconfig b/arch/sh/configs/polaris_defconfig
index 320def2..df2d177d 100644
--- a/arch/sh/configs/polaris_defconfig
+++ b/arch/sh/configs/polaris_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc4
-# Wed Feb 11 18:41:59 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:16:48 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -68,6 +69,7 @@
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -78,10 +80,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -89,6 +89,7 @@
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -162,6 +163,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -203,11 +205,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -251,7 +254,7 @@
 #
 CONFIG_SH_DMA_API=y
 CONFIG_SH_DMA=y
-CONFIG_NR_ONCHIP_DMA_CHANNELS=4
+CONFIG_NR_ONCHIP_DMA_CHANNELS=6
 # CONFIG_NR_DMA_CHANNELS_BOOL is not set
 
 #
@@ -314,7 +317,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -362,6 +364,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -374,7 +377,6 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 # CONFIG_WIRELESS is not set
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
@@ -481,7 +483,6 @@
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -517,6 +518,7 @@
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -548,8 +550,10 @@
 # CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 CONFIG_SMSC911X=y
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -566,7 +570,6 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -750,6 +753,7 @@
 #
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -837,7 +841,6 @@
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -907,6 +910,7 @@
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -922,7 +926,6 @@
 # CONFIG_BOOT_TRACER is not set
 # CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -963,7 +966,7 @@
 CONFIG_AUDIT_GENERIC=y
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/r7780mp_defconfig b/arch/sh/configs/r7780mp_defconfig
index 65b01a9..7def4df 100644
--- a/arch/sh/configs/r7780mp_defconfig
+++ b/arch/sh/configs/r7780mp_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:10:19 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:20:17 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_IO_TRAPPED=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -45,15 +46,24 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 CONFIG_GROUP_SCHED=y
 CONFIG_FAIR_GROUP_SCHED=y
 # CONFIG_RT_GROUP_SCHED is not set
 CONFIG_USER_SCHED=y
 # CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -61,6 +71,7 @@
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 # CONFIG_SYSCTL_SYSCALL is not set
@@ -71,10 +82,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
 # CONFIG_EPOLL is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -83,6 +92,7 @@
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -124,11 +134,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -164,6 +169,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 CONFIG_CPU_SUBTYPE_SH7780=y
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -179,8 +185,11 @@
 CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
-CONFIG_29BIT=y
+# CONFIG_29BIT is not set
+CONFIG_32BIT=y
+CONFIG_PMB_ENABLE=y
 # CONFIG_PMB is not set
+CONFIG_PMB_FIXED=y
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -212,11 +221,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -309,6 +319,8 @@
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 
@@ -330,7 +342,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -392,6 +403,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -399,12 +411,12 @@
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -412,6 +424,7 @@
 CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -451,13 +464,20 @@
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
-CONFIG_EEPROM_93CX6=y
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+CONFIG_EEPROM_93CX6=y
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -513,6 +533,7 @@
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_LIBFC is not set
 # CONFIG_FCOE is not set
@@ -535,6 +556,7 @@
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
@@ -609,6 +631,7 @@
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -627,8 +650,10 @@
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -684,6 +709,7 @@
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
 # CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
@@ -702,6 +728,7 @@
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 
 #
@@ -709,7 +736,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -796,6 +826,7 @@
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -857,12 +888,9 @@
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
@@ -885,6 +913,7 @@
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
 # CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -905,10 +934,14 @@
 # CONFIG_SENSORS_LM90 is not set
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_MAX6650 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -949,6 +982,7 @@
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
 # CONFIG_REGULATOR is not set
 
 #
@@ -1007,9 +1041,13 @@
 #
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1071,6 +1109,7 @@
 #
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -1094,6 +1133,7 @@
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1142,6 +1182,7 @@
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
 # CONFIG_OMFS_FS is not set
@@ -1166,7 +1207,6 @@
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1269,6 +1309,7 @@
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_PAGE_POISONING is not set
 CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
@@ -1288,7 +1329,7 @@
 # CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_FTRACE_STARTUP_TEST is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1325,10 +1366,12 @@
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -1397,6 +1440,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1421,3 +1465,4 @@
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/r7785rp_defconfig b/arch/sh/configs/r7785rp_defconfig
index 8defaa5..cb134ff 100644
--- a/arch/sh/configs/r7785rp_defconfig
+++ b/arch/sh/configs/r7785rp_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:14:41 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:24:35 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_NUMA=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -26,6 +26,7 @@
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_IO_TRAPPED=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -48,11 +49,21 @@
 CONFIG_AUDIT=y
 CONFIG_AUDITSYSCALL=y
 CONFIG_AUDIT_TREE=y
+
+#
+# RCU Subsystem
+#
+# CONFIG_CLASSIC_RCU is not set
+# CONFIG_TREE_RCU is not set
+CONFIG_PREEMPT_RCU=y
+CONFIG_RCU_TRACE=y
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_PREEMPT_RCU_TRACE=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -60,21 +71,19 @@
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -83,6 +92,7 @@
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -126,12 +136,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-# CONFIG_CLASSIC_RCU is not set
-# CONFIG_TREE_RCU is not set
-CONFIG_PREEMPT_RCU=y
-CONFIG_RCU_TRACE=y
-# CONFIG_TREE_RCU_TRACE is not set
-CONFIG_PREEMPT_RCU_TRACE=y
 # CONFIG_FREEZER is not set
 
 #
@@ -168,6 +172,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 CONFIG_CPU_SUBTYPE_SH7785=y
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -183,8 +188,11 @@
 CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
-CONFIG_29BIT=y
+# CONFIG_29BIT is not set
+CONFIG_32BIT=y
+CONFIG_PMB_ENABLE=y
 # CONFIG_PMB is not set
+CONFIG_PMB_FIXED=y
 # CONFIG_X2TLB is not set
 CONFIG_VSYSCALL=y
 # CONFIG_NUMA is not set
@@ -222,11 +230,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -334,6 +343,8 @@
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 # CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 
@@ -355,7 +366,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -417,6 +427,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -425,12 +436,12 @@
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_NET_TCPPROBE is not set
+# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -438,6 +449,7 @@
 CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -477,13 +489,20 @@
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
-CONFIG_EEPROM_93CX6=y
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+CONFIG_EEPROM_93CX6=y
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -539,6 +558,7 @@
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_LIBFC is not set
 # CONFIG_FCOE is not set
@@ -561,6 +581,7 @@
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
@@ -635,6 +656,7 @@
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -653,8 +675,10 @@
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -687,6 +711,7 @@
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
 # CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
@@ -705,6 +730,7 @@
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 
 #
@@ -712,7 +738,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -800,6 +829,7 @@
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -862,12 +892,9 @@
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
@@ -914,6 +941,7 @@
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
 # CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -934,10 +962,14 @@
 # CONFIG_SENSORS_LM90 is not set
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_MAX6650 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_DME1737 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
@@ -979,6 +1011,7 @@
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
 # CONFIG_REGULATOR is not set
 
 #
@@ -1055,6 +1088,7 @@
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -1089,9 +1123,13 @@
 #
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1153,6 +1191,7 @@
 #
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -1176,6 +1215,7 @@
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1224,6 +1264,7 @@
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
 # CONFIG_OMFS_FS is not set
@@ -1248,7 +1289,6 @@
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1354,6 +1394,7 @@
 # CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_PAGE_POISONING is not set
 CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
@@ -1373,7 +1414,7 @@
 # CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_FTRACE_STARTUP_TEST is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1410,10 +1451,12 @@
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -1482,6 +1525,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1504,7 +1548,7 @@
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_AUDIT_GENERIC=y
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/rsk7201_defconfig b/arch/sh/configs/rsk7201_defconfig
index 64ee69e..a037c74 100644
--- a/arch/sh/configs/rsk7201_defconfig
+++ b/arch/sh/configs/rsk7201_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:19:04 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:29:08 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -24,6 +24,7 @@
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -38,11 +39,20 @@
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 # CONFIG_IKCONFIG_PROC is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 CONFIG_NAMESPACES=y
@@ -52,8 +62,13 @@
 CONFIG_PID_NS=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -63,16 +78,15 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 # CONFIG_AIO is not set
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 # CONFIG_SLUB is not set
 CONFIG_SLOB=y
@@ -112,11 +126,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -152,6 +161,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -190,11 +200,11 @@
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -217,7 +227,6 @@
 #
 # Timer and clock configuration
 #
-# CONFIG_SH_CMT is not set
 CONFIG_SH_MTU2=y
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=40000000
@@ -251,7 +260,6 @@
 CONFIG_HZ_1000=y
 CONFIG_HZ=1000
 # CONFIG_SCHED_HRTICK is not set
-# CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
 # CONFIG_SECCOMP is not set
 CONFIG_PREEMPT_NONE=y
@@ -308,6 +316,7 @@
 # CONFIG_MTD_DEBUG is not set
 CONFIG_MTD_CONCAT=y
 CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
 CONFIG_MTD_REDBOOT_PARTS=y
 CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
 # CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
@@ -358,9 +367,7 @@
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=4
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -381,6 +388,11 @@
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -392,9 +404,13 @@
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -562,6 +578,7 @@
 #
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -577,6 +594,7 @@
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_FILE_LOCKING is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_BTRFS_FS is not set
 # CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY is not set
 # CONFIG_QUOTA is not set
@@ -626,6 +644,7 @@
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -671,7 +690,7 @@
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -701,7 +720,7 @@
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
diff --git a/arch/sh/configs/rsk7203_defconfig b/arch/sh/configs/rsk7203_defconfig
index 8d7a597..9ae28e8 100644
--- a/arch/sh/configs/rsk7203_defconfig
+++ b/arch/sh/configs/rsk7203_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:20:31 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:30:34 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -18,12 +18,14 @@
 # CONFIG_GENERIC_CLOCKEVENTS is not set
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 # CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -41,11 +43,20 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 # CONFIG_IKCONFIG_PROC is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 CONFIG_NAMESPACES=y
@@ -53,31 +64,35 @@
 CONFIG_IPC_NS=y
 CONFIG_USER_NS=y
 CONFIG_PID_NS=y
+# CONFIG_NET_NS is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 # CONFIG_SLUB is not set
 CONFIG_SLOB=y
@@ -117,11 +132,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -157,6 +167,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -195,11 +206,11 @@
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -271,7 +282,6 @@
 CONFIG_HZ_1000=y
 CONFIG_HZ=1000
 # CONFIG_SCHED_HRTICK is not set
-# CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
 # CONFIG_SECCOMP is not set
 CONFIG_PREEMPT_NONE=y
@@ -315,8 +325,6 @@
 #
 # Networking options
 #
-# CONFIG_NET_NS is not set
-CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_PACKET is not set
 # CONFIG_UNIX is not set
 # CONFIG_NET_KEY is not set
@@ -364,6 +372,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -371,18 +380,19 @@
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -405,6 +415,7 @@
 # CONFIG_MTD_DEBUG is not set
 CONFIG_MTD_CONCAT=y
 CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
 CONFIG_MTD_REDBOOT_PARTS=y
 CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
 # CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
@@ -455,9 +466,7 @@
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=4
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -478,6 +487,11 @@
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -492,9 +506,13 @@
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -508,6 +526,7 @@
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -539,8 +558,10 @@
 # CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 CONFIG_SMSC911X=y
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -557,7 +578,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 
 #
 # USB Network Adapters
@@ -777,7 +801,9 @@
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
 CONFIG_USB_R8A66597_HCD=y
 # CONFIG_USB_HWA_HCD is not set
@@ -791,11 +817,11 @@
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
 # CONFIG_USB_LIBUSUAL is not set
 
@@ -823,7 +849,6 @@
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
@@ -834,6 +859,12 @@
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 CONFIG_NEW_LEDS=y
@@ -852,6 +883,10 @@
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_LEDS_TRIGGER_BACKLIGHT=y
 CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
 # CONFIG_ACCESSIBILITY is not set
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=y
@@ -891,6 +926,7 @@
 #
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -906,6 +942,7 @@
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 # CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY is not set
 # CONFIG_QUOTA is not set
@@ -945,6 +982,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -962,7 +1000,6 @@
 CONFIG_LOCKD=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1018,6 +1055,7 @@
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_INFO=y
 CONFIG_DEBUG_VM=y
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
 CONFIG_DEBUG_WRITECOUNT=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 CONFIG_DEBUG_LIST=y
@@ -1031,6 +1069,7 @@
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
 CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
@@ -1048,7 +1087,7 @@
 # CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_FTRACE_STARTUP_TEST is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1086,7 +1125,8 @@
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/rts7751r2d1_defconfig b/arch/sh/configs/rts7751r2d1_defconfig
index d6680f4..c0f741a 100644
--- a/arch/sh/configs/rts7751r2d1_defconfig
+++ b/arch/sh/configs/rts7751r2d1_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:23:15 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:33:25 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_IO_TRAPPED=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -43,10 +44,19 @@
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -54,6 +64,7 @@
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 # CONFIG_SYSCTL_SYSCALL is not set
@@ -63,10 +74,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -75,6 +84,7 @@
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -116,11 +126,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -155,6 +160,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -196,11 +202,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -300,6 +307,8 @@
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 CONFIG_HOTPLUG_PCI=y
 # CONFIG_HOTPLUG_PCI_FAKE is not set
@@ -324,7 +333,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -376,6 +384,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -383,12 +392,12 @@
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -396,6 +405,7 @@
 CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -434,12 +444,17 @@
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -495,6 +510,7 @@
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_LIBFC is not set
 # CONFIG_FCOE is not set
@@ -517,6 +533,7 @@
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
@@ -591,6 +608,7 @@
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -609,8 +627,10 @@
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -665,6 +685,7 @@
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
 # CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
@@ -683,6 +704,7 @@
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 
 #
@@ -690,7 +712,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 
 #
 # USB Network Adapters
@@ -780,6 +805,7 @@
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -798,7 +824,6 @@
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
 # CONFIG_W1 is not set
@@ -822,6 +847,7 @@
 # CONFIG_SENSORS_VT8231 is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 # CONFIG_THERMAL is not set
 # CONFIG_THERMAL_HWMON is not set
@@ -918,6 +944,7 @@
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -996,6 +1023,8 @@
 # CONFIG_SND_INDIGO is not set
 # CONFIG_SND_INDIGOIO is not set
 # CONFIG_SND_INDIGODJ is not set
+# CONFIG_SND_INDIGOIOX is not set
+# CONFIG_SND_INDIGODJX is not set
 # CONFIG_SND_EMU10K1 is not set
 # CONFIG_SND_EMU10K1X is not set
 # CONFIG_SND_ENS1370 is not set
@@ -1101,6 +1130,7 @@
 #
 # CONFIG_USB_C67X00_HCD is not set
 # CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
 CONFIG_USB_OHCI_HCD=y
@@ -1122,18 +1152,17 @@
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
 # CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
 # CONFIG_USB_STORAGE_USBAT is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
@@ -1169,7 +1198,6 @@
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
@@ -1179,6 +1207,11 @@
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1230,6 +1263,7 @@
 #
 # CONFIG_RTC_DRV_SH is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -1247,6 +1281,7 @@
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1293,6 +1328,7 @@
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
 # CONFIG_OMFS_FS is not set
@@ -1385,7 +1421,7 @@
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -1479,6 +1515,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1500,7 +1537,7 @@
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/rts7751r2dplus_defconfig b/arch/sh/configs/rts7751r2dplus_defconfig
index 3fca10e..8feef62 100644
--- a/arch/sh/configs/rts7751r2dplus_defconfig
+++ b/arch/sh/configs/rts7751r2dplus_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:26:10 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:34:12 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_IO_TRAPPED=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -43,10 +44,19 @@
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -54,6 +64,7 @@
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 # CONFIG_SYSCTL_SYSCALL is not set
@@ -63,10 +74,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -75,6 +84,7 @@
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -116,11 +126,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -155,6 +160,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -196,11 +202,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -300,6 +307,8 @@
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 CONFIG_HOTPLUG_PCI=y
 # CONFIG_HOTPLUG_PCI_FAKE is not set
@@ -324,7 +333,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -376,6 +384,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -383,12 +392,12 @@
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -396,6 +405,7 @@
 CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -434,12 +444,17 @@
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -495,6 +510,7 @@
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_LIBFC is not set
 # CONFIG_FCOE is not set
@@ -517,6 +533,7 @@
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
@@ -591,6 +608,7 @@
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -609,8 +627,10 @@
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -665,6 +685,7 @@
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
 # CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
@@ -683,6 +704,7 @@
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 
 #
@@ -690,7 +712,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 
 #
 # USB Network Adapters
@@ -780,6 +805,7 @@
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -798,7 +824,6 @@
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
 # CONFIG_W1 is not set
@@ -822,6 +847,7 @@
 # CONFIG_SENSORS_VT8231 is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 # CONFIG_THERMAL is not set
 # CONFIG_THERMAL_HWMON is not set
@@ -918,6 +944,7 @@
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -996,6 +1023,8 @@
 # CONFIG_SND_INDIGO is not set
 # CONFIG_SND_INDIGOIO is not set
 # CONFIG_SND_INDIGODJ is not set
+# CONFIG_SND_INDIGOIOX is not set
+# CONFIG_SND_INDIGODJX is not set
 # CONFIG_SND_EMU10K1 is not set
 # CONFIG_SND_EMU10K1X is not set
 # CONFIG_SND_ENS1370 is not set
@@ -1101,6 +1130,7 @@
 #
 # CONFIG_USB_C67X00_HCD is not set
 # CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
 CONFIG_USB_OHCI_HCD=y
@@ -1122,18 +1152,17 @@
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
 # CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
 # CONFIG_USB_STORAGE_USBAT is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
@@ -1169,7 +1198,6 @@
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
@@ -1179,6 +1207,11 @@
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1230,6 +1263,7 @@
 #
 # CONFIG_RTC_DRV_SH is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -1247,6 +1281,7 @@
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1293,6 +1328,7 @@
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
 # CONFIG_OMFS_FS is not set
@@ -1385,7 +1421,7 @@
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -1479,6 +1515,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1500,7 +1537,7 @@
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/sdk7780_defconfig b/arch/sh/configs/sdk7780_defconfig
index 5d6b067..739e229 100644
--- a/arch/sh/configs/sdk7780_defconfig
+++ b/arch/sh/configs/sdk7780_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:26:40 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:34:43 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -44,11 +45,20 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=18
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_RELAY=y
@@ -56,21 +66,19 @@
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -80,6 +88,7 @@
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
@@ -119,11 +128,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -159,6 +163,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 CONFIG_CPU_SUBTYPE_SH7780=y
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -174,8 +179,11 @@
 CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
-CONFIG_29BIT=y
+# CONFIG_29BIT is not set
+CONFIG_32BIT=y
+CONFIG_PMB_ENABLE=y
 # CONFIG_PMB is not set
+CONFIG_PMB_FIXED=y
 CONFIG_VSYSCALL=y
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -207,11 +215,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -257,6 +266,7 @@
 #
 CONFIG_SH_DMA_API=y
 CONFIG_SH_DMA=y
+CONFIG_SH_DMA_IRQ_MULTI=y
 CONFIG_NR_ONCHIP_DMA_CHANNELS=12
 # CONFIG_NR_DMA_CHANNELS_BOOL is not set
 
@@ -306,6 +316,8 @@
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 # CONFIG_PCI_LEGACY is not set
 CONFIG_PCI_DEBUG=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 CONFIG_PCCARD=y
 # CONFIG_PCMCIA_DEBUG is not set
 CONFIG_PCMCIA=y
@@ -348,7 +360,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -427,6 +438,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 CONFIG_NET_SCHED=y
 
 #
@@ -471,13 +483,13 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -631,6 +643,7 @@
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_LIBFC is not set
 # CONFIG_FCOE is not set
@@ -654,6 +667,7 @@
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
@@ -739,6 +753,7 @@
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -756,8 +771,10 @@
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 CONFIG_SMC91X=y
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -780,7 +797,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 
 #
 # USB Network Adapters
@@ -840,7 +860,6 @@
 CONFIG_MOUSE_PS2_ALPS=y
 CONFIG_MOUSE_PS2_LOGIPS2PP=y
 CONFIG_MOUSE_PS2_SYNAPTICS=y
-CONFIG_MOUSE_PS2_LIFEBOOK=y
 CONFIG_MOUSE_PS2_TRACKPOINT=y
 # CONFIG_MOUSE_PS2_ELANTECH is not set
 # CONFIG_MOUSE_PS2_TOUCHKIT is not set
@@ -899,6 +918,7 @@
 # CONFIG_PPDEV is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 
@@ -1023,6 +1043,7 @@
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -1123,6 +1144,7 @@
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
 # CONFIG_USB_OHCI_HCD is not set
@@ -1141,18 +1163,17 @@
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
 # CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
 # CONFIG_USB_STORAGE_USBAT is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
@@ -1189,7 +1210,6 @@
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
@@ -1201,6 +1221,11 @@
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1243,7 +1268,9 @@
 CONFIG_FS_POSIX_ACL=y
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1295,6 +1322,7 @@
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
 # CONFIG_OMFS_FS is not set
@@ -1318,7 +1346,6 @@
 CONFIG_EXPORTFS=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1424,6 +1451,7 @@
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -1439,7 +1467,6 @@
 # CONFIG_BOOT_TRACER is not set
 # CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1544,6 +1571,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1565,7 +1593,7 @@
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7206_defconfig b/arch/sh/configs/se7206_defconfig
index e5b55b6..d30e0a7 100644
--- a/arch/sh/configs/se7206_defconfig
+++ b/arch/sh/configs/se7206_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:31:27 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:39:37 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -18,12 +18,14 @@
 # CONFIG_GENERIC_CLOCKEVENTS is not set
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 # CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -43,18 +45,28 @@
 # CONFIG_TASKSTATS is not set
 CONFIG_AUDIT=y
 CONFIG_AUDITSYSCALL=y
+
+#
+# RCU Subsystem
+#
+# CONFIG_CLASSIC_RCU is not set
+# CONFIG_TREE_RCU is not set
+CONFIG_PREEMPT_RCU=y
+CONFIG_RCU_TRACE=y
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_PREEMPT_RCU_TRACE=y
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
 CONFIG_CGROUPS=y
 CONFIG_CGROUP_DEBUG=y
 CONFIG_CGROUP_NS=y
 # CONFIG_CGROUP_FREEZER is not set
 CONFIG_CGROUP_DEVICE=y
-# CONFIG_GROUP_SCHED is not set
 CONFIG_CGROUP_CPUACCT=y
 CONFIG_RESOURCE_COUNTERS=y
-CONFIG_MM_OWNER=y
 CONFIG_CGROUP_MEM_RES_CTLR=y
+CONFIG_MM_OWNER=y
 # CONFIG_SYSFS_DEPRECATED_V2 is not set
 CONFIG_RELAY=y
 CONFIG_NAMESPACES=y
@@ -62,31 +74,35 @@
 CONFIG_IPC_NS=y
 CONFIG_USER_NS=y
 CONFIG_PID_NS=y
+# CONFIG_NET_NS is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 # CONFIG_UID16 is not set
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
-# CONFIG_COMPAT_BRK is not set
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_COMPAT_BRK is not set
 # CONFIG_SLAB is not set
 # CONFIG_SLUB is not set
 CONFIG_SLOB=y
@@ -127,12 +143,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-# CONFIG_CLASSIC_RCU is not set
-# CONFIG_TREE_RCU is not set
-CONFIG_PREEMPT_RCU=y
-CONFIG_RCU_TRACE=y
-# CONFIG_TREE_RCU_TRACE is not set
-CONFIG_PREEMPT_RCU_TRACE=y
 # CONFIG_FREEZER is not set
 
 #
@@ -168,6 +178,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -206,11 +217,11 @@
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -280,7 +291,6 @@
 CONFIG_HZ_1000=y
 CONFIG_HZ=1000
 # CONFIG_SCHED_HRTICK is not set
-CONFIG_KEXEC=y
 # CONFIG_CRASH_DUMP is not set
 # CONFIG_SECCOMP is not set
 # CONFIG_PREEMPT_NONE is not set
@@ -322,8 +332,6 @@
 #
 # Networking options
 #
-# CONFIG_NET_NS is not set
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -378,6 +386,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -385,18 +394,19 @@
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -419,6 +429,7 @@
 # CONFIG_MTD_DEBUG is not set
 CONFIG_MTD_CONCAT=y
 CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
 # CONFIG_MTD_AR7_PARTS is not set
@@ -466,9 +477,7 @@
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x20000000
-CONFIG_MTD_PHYSMAP_LEN=0x01000000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=4
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -489,6 +498,11 @@
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -506,9 +520,13 @@
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-CONFIG_EEPROM_93CX6=y
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+CONFIG_EEPROM_93CX6=y
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -522,6 +540,7 @@
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -534,8 +553,10 @@
 # CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 CONFIG_SMC91X=y
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -552,7 +573,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -696,6 +720,7 @@
 #
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -712,6 +737,7 @@
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 # CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY is not set
 # CONFIG_QUOTA is not set
@@ -752,6 +778,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -771,7 +798,6 @@
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -824,6 +850,7 @@
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 CONFIG_DEBUG_VM=y
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
 CONFIG_DEBUG_LIST=y
@@ -835,6 +862,7 @@
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_PAGE_POISONING is not set
 CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
@@ -852,7 +880,7 @@
 # CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_FTRACE_STARTUP_TEST is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -955,6 +983,7 @@
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
 CONFIG_CRYPTO_LZO=y
 
 #
@@ -980,7 +1009,8 @@
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_LZO_COMPRESS=y
 CONFIG_LZO_DECOMPRESS=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7343_defconfig b/arch/sh/configs/se7343_defconfig
index 3900525..fbb72d0 100644
--- a/arch/sh/configs/se7343_defconfig
+++ b/arch/sh/configs/se7343_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:33:53 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:42:00 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -16,14 +16,16 @@
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
-# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -41,14 +43,23 @@
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 CONFIG_GROUP_SCHED=y
 CONFIG_FAIR_GROUP_SCHED=y
 # CONFIG_RT_GROUP_SCHED is not set
 CONFIG_USER_SCHED=y
 # CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -56,6 +67,7 @@
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 # CONFIG_SYSCTL_SYSCALL is not set
@@ -65,10 +77,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
 # CONFIG_EPOLL is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -76,6 +86,7 @@
 # CONFIG_SHMEM is not set
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -114,11 +125,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="deadline"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -127,6 +133,7 @@
 CONFIG_CPU_SH4=y
 CONFIG_CPU_SH4A=y
 CONFIG_CPU_SH4AL_DSP=y
+CONFIG_ARCH_SHMOBILE=y
 # CONFIG_CPU_SUBTYPE_SH7619 is not set
 # CONFIG_CPU_SUBTYPE_SH7201 is not set
 # CONFIG_CPU_SUBTYPE_SH7203 is not set
@@ -155,6 +162,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 CONFIG_CPU_SUBTYPE_SH7343=y
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -196,11 +204,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -227,6 +236,7 @@
 # Timer and clock configuration
 #
 CONFIG_SH_TMU=y
+# CONFIG_SH_TIMER_CMT is not set
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=33333333
 # CONFIG_NO_HZ is not set
@@ -302,7 +312,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -353,6 +362,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -365,13 +375,13 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -394,6 +404,7 @@
 # CONFIG_MTD_DEBUG is not set
 CONFIG_MTD_CONCAT=y
 CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
 # CONFIG_MTD_AR7_PARTS is not set
@@ -441,9 +452,7 @@
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=0
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -464,6 +473,11 @@
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -520,9 +534,11 @@
 # CONFIG_SCSI_SRP_ATTRS is not set
 # CONFIG_SCSI_LOWLEVEL is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -539,7 +555,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 
 #
 # USB Network Adapters
@@ -633,6 +652,7 @@
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
@@ -669,12 +689,9 @@
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
@@ -706,6 +723,7 @@
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
 # CONFIG_REGULATOR is not set
 
 #
@@ -727,7 +745,7 @@
 #
 # CONFIG_MEDIA_ATTACH is not set
 CONFIG_MEDIA_TUNER=y
-# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
 CONFIG_MEDIA_TUNER_SIMPLE=y
 CONFIG_MEDIA_TUNER_TDA8290=y
 CONFIG_MEDIA_TUNER_TDA9887=y
@@ -736,6 +754,7 @@
 CONFIG_MEDIA_TUNER_MT20XX=y
 CONFIG_MEDIA_TUNER_XC2028=y
 CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_MC44S803=y
 CONFIG_VIDEO_V4L2=y
 CONFIG_VIDEO_V4L1=y
 CONFIG_VIDEO_CAPTURE_DRIVERS=y
@@ -757,6 +776,7 @@
 # CONFIG_USB_GSPCA_ETOMS is not set
 # CONFIG_USB_GSPCA_FINEPIX is not set
 # CONFIG_USB_GSPCA_MARS is not set
+# CONFIG_USB_GSPCA_MR97310A is not set
 # CONFIG_USB_GSPCA_OV519 is not set
 # CONFIG_USB_GSPCA_OV534 is not set
 # CONFIG_USB_GSPCA_PAC207 is not set
@@ -769,6 +789,8 @@
 # CONFIG_USB_GSPCA_SPCA506 is not set
 # CONFIG_USB_GSPCA_SPCA508 is not set
 # CONFIG_USB_GSPCA_SPCA561 is not set
+# CONFIG_USB_GSPCA_SQ905 is not set
+# CONFIG_USB_GSPCA_SQ905C is not set
 # CONFIG_USB_GSPCA_STK014 is not set
 # CONFIG_USB_GSPCA_SUNPLUS is not set
 # CONFIG_USB_GSPCA_T613 is not set
@@ -776,6 +798,7 @@
 # CONFIG_USB_GSPCA_VC032X is not set
 # CONFIG_USB_GSPCA_ZC3XX is not set
 # CONFIG_VIDEO_PVRUSB2 is not set
+# CONFIG_VIDEO_HDPVR is not set
 # CONFIG_VIDEO_EM28XX is not set
 # CONFIG_VIDEO_USBVISION is not set
 # CONFIG_USB_VICAM is not set
@@ -833,6 +856,7 @@
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -940,7 +964,9 @@
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
 CONFIG_USB_ISP116X_HCD=y
+# CONFIG_USB_ISP1760_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
 # CONFIG_USB_R8A66597_HCD is not set
 # CONFIG_USB_HWA_HCD is not set
@@ -954,11 +980,11 @@
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
 # CONFIG_USB_STORAGE is not set
 # CONFIG_USB_LIBUSUAL is not set
@@ -988,7 +1014,6 @@
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
@@ -999,12 +1024,18 @@
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 CONFIG_UIO=y
 # CONFIG_UIO_PDRV is not set
 # CONFIG_UIO_PDRV_GENIRQ is not set
@@ -1031,6 +1062,7 @@
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 # CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY is not set
 # CONFIG_QUOTA is not set
@@ -1084,6 +1116,7 @@
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -1105,7 +1138,6 @@
 CONFIG_EXPORTFS=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1146,7 +1178,6 @@
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -1240,6 +1271,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1265,3 +1297,4 @@
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7619_defconfig b/arch/sh/configs/se7619_defconfig
index 932b023..125304e 100644
--- a/arch/sh/configs/se7619_defconfig
+++ b/arch/sh/configs/se7619_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:36:46 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:44:53 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -18,12 +18,14 @@
 # CONFIG_GENERIC_CLOCKEVENTS is not set
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
 # CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -36,15 +38,25 @@
 # CONFIG_LOCALVERSION_AUTO is not set
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 # CONFIG_UID16 is not set
 # CONFIG_SYSCTL_SYSCALL is not set
@@ -53,16 +65,15 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 # CONFIG_ELF_CORE is not set
-CONFIG_COMPAT_BRK=y
 # CONFIG_BASE_FULL is not set
 # CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
 # CONFIG_EPOLL is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_AIO=y
 # CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -93,11 +104,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -132,6 +138,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -170,11 +177,11 @@
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 # CONFIG_CACHE_WRITEBACK is not set
 CONFIG_CACHE_WRITETHROUGH=y
 # CONFIG_CACHE_OFF is not set
@@ -228,7 +235,6 @@
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=100
 # CONFIG_SCHED_HRTICK is not set
-# CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
 # CONFIG_SECCOMP is not set
 CONFIG_PREEMPT_NONE=y
@@ -329,9 +335,7 @@
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0xa0000000
-CONFIG_MTD_PHYSMAP_LEN=0x01000000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_SOLUTIONENGINE is not set
 # CONFIG_MTD_PLATRAM is not set
 
@@ -353,6 +357,11 @@
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -364,9 +373,13 @@
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -514,15 +527,20 @@
 #
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -537,6 +555,7 @@
 # CONFIG_FS_POSIX_ACL is not set
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_BTRFS_FS is not set
 # CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY is not set
 # CONFIG_QUOTA is not set
@@ -575,6 +594,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -614,7 +634,6 @@
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
diff --git a/arch/sh/configs/se7705_defconfig b/arch/sh/configs/se7705_defconfig
index 8574d6e..0308abf 100644
--- a/arch/sh/configs/se7705_defconfig
+++ b/arch/sh/configs/se7705_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:37:50 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:45:56 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -41,16 +42,30 @@
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 # CONFIG_SYSCTL_SYSCALL is not set
@@ -59,10 +74,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -70,6 +83,7 @@
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -106,11 +120,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -145,6 +154,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -186,12 +196,13 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
 CONFIG_SH7705_CACHE_32KB=y
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -292,7 +303,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -347,6 +357,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -359,13 +370,13 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -384,6 +395,7 @@
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
 # CONFIG_MTD_AR7_PARTS is not set
@@ -451,6 +463,11 @@
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -467,9 +484,13 @@
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -483,6 +504,7 @@
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -495,8 +517,10 @@
 # CONFIG_AX88796 is not set
 CONFIG_STNIC=y
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -513,7 +537,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 CONFIG_PPP=y
 # CONFIG_PPP_MULTILINK is not set
@@ -593,6 +620,7 @@
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
@@ -684,15 +712,20 @@
 #
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -709,6 +742,7 @@
 # CONFIG_FS_POSIX_ACL is not set
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -761,6 +795,7 @@
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -778,7 +813,6 @@
 CONFIG_LOCKD=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -817,7 +851,6 @@
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -908,6 +941,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -930,7 +964,8 @@
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7712_defconfig b/arch/sh/configs/se7712_defconfig
index e31ea84..a8c24b7 100644
--- a/arch/sh/configs/se7712_defconfig
+++ b/arch/sh/configs/se7712_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:40:12 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:48:18 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -16,13 +16,14 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -41,10 +42,19 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -52,21 +62,19 @@
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 # CONFIG_BUG is not set
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 # CONFIG_BASE_FULL is not set
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -74,6 +82,7 @@
 # CONFIG_SHMEM is not set
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -112,11 +121,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -151,6 +155,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -192,11 +197,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -300,7 +306,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -364,6 +369,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 CONFIG_NET_SCHED=y
 
 #
@@ -411,7 +417,6 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_FIB_RULES=y
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
@@ -419,6 +424,7 @@
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -443,6 +449,7 @@
 # CONFIG_MTD_DEBUG is not set
 CONFIG_MTD_CONCAT=y
 CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
 # CONFIG_MTD_AR7_PARTS is not set
@@ -510,6 +517,11 @@
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -523,9 +535,13 @@
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -571,6 +587,7 @@
 # CONFIG_LIBFC is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
@@ -579,6 +596,7 @@
 CONFIG_PATA_PLATFORM=y
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -611,8 +629,10 @@
 # CONFIG_STNIC is not set
 CONFIG_SH_ETH=y
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -629,7 +649,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -675,6 +698,7 @@
 # CONFIG_LEGACY_PTYS is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=m
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
@@ -744,9 +768,13 @@
 #
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 CONFIG_NEW_LEDS=y
@@ -764,9 +792,14 @@
 # CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
 # CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
 # CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -791,6 +824,7 @@
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 # CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY is not set
 # CONFIG_QUOTA is not set
@@ -844,6 +878,7 @@
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -861,7 +896,6 @@
 CONFIG_LOCKD=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -923,6 +957,7 @@
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -937,7 +972,6 @@
 # CONFIG_BOOT_TRACER is not set
 # CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -974,10 +1008,12 @@
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=y
 # CONFIG_CRYPTO_TEST is not set
@@ -1046,6 +1082,7 @@
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1068,7 +1105,7 @@
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7721_defconfig b/arch/sh/configs/se7721_defconfig
index ad1bace..4b79c25 100644
--- a/arch/sh/configs/se7721_defconfig
+++ b/arch/sh/configs/se7721_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:43:33 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:51:44 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -16,13 +16,14 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -41,14 +42,23 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 CONFIG_GROUP_SCHED=y
 CONFIG_FAIR_GROUP_SCHED=y
 # CONFIG_RT_GROUP_SCHED is not set
 CONFIG_USER_SCHED=y
 # CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -56,21 +66,19 @@
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 # CONFIG_BUG is not set
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 # CONFIG_BASE_FULL is not set
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -78,6 +86,7 @@
 # CONFIG_SHMEM is not set
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -116,11 +125,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -155,6 +159,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -196,11 +201,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -303,7 +309,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -367,6 +372,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 CONFIG_NET_SCHED=y
 
 #
@@ -414,7 +420,6 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_FIB_RULES=y
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
@@ -422,6 +427,7 @@
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -446,6 +452,7 @@
 # CONFIG_MTD_DEBUG is not set
 CONFIG_MTD_CONCAT=y
 CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
 # CONFIG_MTD_AR7_PARTS is not set
@@ -513,6 +520,11 @@
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -527,9 +539,13 @@
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -572,6 +588,7 @@
 # CONFIG_SCSI_SRP_ATTRS is not set
 # CONFIG_SCSI_LOWLEVEL is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
@@ -580,6 +597,7 @@
 CONFIG_PATA_PLATFORM=y
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -595,7 +613,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 
 #
 # USB Network Adapters
@@ -805,7 +826,9 @@
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
 # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
@@ -823,18 +846,17 @@
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
 # CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
 # CONFIG_USB_STORAGE_USBAT is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
@@ -870,7 +892,6 @@
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
@@ -880,6 +901,11 @@
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 CONFIG_NEW_LEDS=y
@@ -897,9 +923,14 @@
 # CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
 # CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
 # CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -924,6 +955,7 @@
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 # CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY is not set
 # CONFIG_QUOTA is not set
@@ -980,6 +1012,7 @@
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -1082,6 +1115,7 @@
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -1096,7 +1130,6 @@
 # CONFIG_BOOT_TRACER is not set
 # CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1133,10 +1166,12 @@
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=y
 # CONFIG_CRYPTO_TEST is not set
@@ -1205,6 +1240,7 @@
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1227,7 +1263,7 @@
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7722_defconfig b/arch/sh/configs/se7722_defconfig
index abb189a..82bdaac 100644
--- a/arch/sh/configs/se7722_defconfig
+++ b/arch/sh/configs/se7722_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:46:59 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:55:10 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -16,15 +16,17 @@
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
-# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_NUMA=y
+CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -44,19 +46,33 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -66,10 +82,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -78,6 +92,7 @@
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
@@ -118,11 +133,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -132,6 +142,7 @@
 CONFIG_CPU_SH4A=y
 CONFIG_CPU_SH4AL_DSP=y
 CONFIG_CPU_SHX2=y
+CONFIG_ARCH_SHMOBILE=y
 # CONFIG_CPU_SUBTYPE_SH7619 is not set
 # CONFIG_CPU_SUBTYPE_SH7201 is not set
 # CONFIG_CPU_SUBTYPE_SH7203 is not set
@@ -160,6 +171,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 CONFIG_CPU_SUBTYPE_SH7722=y
@@ -213,11 +225,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -246,6 +259,7 @@
 # Timer and clock configuration
 #
 CONFIG_SH_TMU=y
+# CONFIG_SH_TIMER_CMT is not set
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=33333333
 CONFIG_TICK_ONESHOT=y
@@ -321,7 +335,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -373,6 +386,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -385,13 +399,13 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -422,9 +436,13 @@
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -470,6 +488,7 @@
 # CONFIG_LIBFC is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
@@ -478,6 +497,7 @@
 CONFIG_PATA_PLATFORM=y
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -490,8 +510,10 @@
 # CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 CONFIG_SMC91X=y
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -508,7 +530,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -589,6 +614,7 @@
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
@@ -680,9 +706,13 @@
 #
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -725,6 +755,7 @@
 #
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -748,6 +779,7 @@
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -791,6 +823,7 @@
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -843,7 +876,7 @@
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_SH_STANDARD_BIOS=y
@@ -936,6 +969,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -956,7 +990,9 @@
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7750_defconfig b/arch/sh/configs/se7750_defconfig
index ac874f6..ceef6d9 100644
--- a/arch/sh/configs/se7750_defconfig
+++ b/arch/sh/configs/se7750_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:49:22 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:57:31 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -42,11 +43,20 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -54,6 +64,7 @@
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 # CONFIG_SYSCTL_SYSCALL is not set
@@ -63,10 +74,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -74,6 +83,7 @@
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -112,11 +122,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -151,6 +156,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -192,11 +198,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -299,7 +306,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -355,6 +361,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -367,13 +374,13 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -392,6 +399,7 @@
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
 # CONFIG_MTD_AR7_PARTS is not set
@@ -459,6 +467,11 @@
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -472,9 +485,13 @@
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
 
@@ -538,9 +555,11 @@
 # CONFIG_LIBFC is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -553,8 +572,10 @@
 # CONFIG_AX88796 is not set
 CONFIG_STNIC=y
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -571,7 +592,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -622,6 +646,7 @@
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
@@ -711,15 +736,20 @@
 #
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -735,6 +765,7 @@
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -789,6 +820,7 @@
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -806,7 +838,6 @@
 CONFIG_LOCKD=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -859,7 +890,6 @@
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -951,6 +981,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -973,7 +1004,7 @@
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7751_defconfig b/arch/sh/configs/se7751_defconfig
index f54ae05..67fc26b3 100644
--- a/arch/sh/configs/se7751_defconfig
+++ b/arch/sh/configs/se7751_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:51:47 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 18:59:59 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -42,18 +43,32 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 # CONFIG_SYSCTL_SYSCALL is not set
@@ -63,10 +78,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -74,6 +87,7 @@
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -112,11 +126,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -151,6 +160,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -192,11 +202,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -301,7 +312,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -376,6 +386,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -388,13 +399,13 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -413,6 +424,7 @@
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
 # CONFIG_MTD_AR7_PARTS is not set
@@ -480,6 +492,11 @@
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -496,9 +513,13 @@
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -512,6 +533,7 @@
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -524,8 +546,10 @@
 # CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -542,7 +566,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -585,6 +612,7 @@
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
@@ -673,15 +701,20 @@
 #
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -699,6 +732,7 @@
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -753,6 +787,7 @@
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -802,7 +837,6 @@
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -894,6 +928,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -916,7 +951,8 @@
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7780_defconfig b/arch/sh/configs/se7780_defconfig
index 7504978..ebce23c 100644
--- a/arch/sh/configs/se7780_defconfig
+++ b/arch/sh/configs/se7780_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:53:50 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 19:02:05 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -41,6 +42,15 @@
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
@@ -52,6 +62,7 @@
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -60,10 +71,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 # CONFIG_EPOLL is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -72,6 +81,7 @@
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -108,11 +118,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="deadline"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -148,6 +153,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 CONFIG_CPU_SUBTYPE_SH7780=y
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -192,11 +198,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -283,6 +290,8 @@
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 
 #
 # Executable file formats
@@ -296,7 +305,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -351,6 +359,7 @@
 # CONFIG_LLC2 is not set
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -362,13 +371,13 @@
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 
 #
@@ -386,6 +395,7 @@
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
 # CONFIG_MTD_AR7_PARTS is not set
@@ -460,6 +470,11 @@
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -479,10 +494,14 @@
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -536,6 +555,7 @@
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_LIBFC is not set
 # CONFIG_FCOE is not set
@@ -557,6 +577,7 @@
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
@@ -565,6 +586,7 @@
 CONFIG_ATA_SFF=y
 # CONFIG_SATA_SVW is not set
 # CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
 # CONFIG_SATA_NV is not set
 # CONFIG_PDC_ADMA is not set
 # CONFIG_SATA_QSTOR is not set
@@ -619,6 +641,7 @@
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
@@ -654,8 +677,10 @@
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 CONFIG_SMC91X=y
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -693,7 +718,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 
 #
 # USB Network Adapters
@@ -885,6 +913,7 @@
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -978,6 +1007,7 @@
 # CONFIG_USB_C67X00_HCD is not set
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
@@ -996,18 +1026,17 @@
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
 # CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
 # CONFIG_USB_STORAGE_USBAT is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
@@ -1043,7 +1072,6 @@
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
@@ -1055,6 +1083,11 @@
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -1062,6 +1095,7 @@
 # CONFIG_INFINIBAND is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -1120,6 +1154,7 @@
 # CONFIG_HFSPLUS_FS is not set
 # CONFIG_JFFS2_FS is not set
 CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -1214,7 +1249,7 @@
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -1301,6 +1336,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1323,7 +1359,7 @@
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/sh03_defconfig b/arch/sh/configs/sh03_defconfig
index 04bde1e..6fcdb09 100644
--- a/arch/sh/configs/sh03_defconfig
+++ b/arch/sh/configs/sh03_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 17:56:46 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 19:04:59 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -44,18 +45,32 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 # CONFIG_SYSCTL_SYSCALL is not set
@@ -65,10 +80,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -77,6 +90,7 @@
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -119,11 +133,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -158,6 +167,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -199,11 +209,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -294,6 +305,8 @@
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 CONFIG_HOTPLUG_PCI=m
 # CONFIG_HOTPLUG_PCI_FAKE is not set
@@ -318,7 +331,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -375,6 +387,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -382,18 +395,19 @@
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -430,12 +444,16 @@
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
 
@@ -541,6 +559,7 @@
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_LIBFC is not set
 # CONFIG_FCOE is not set
@@ -562,6 +581,7 @@
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 # CONFIG_FUSION is not set
@@ -577,6 +597,7 @@
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -594,8 +615,10 @@
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -646,6 +669,7 @@
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
 # CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
@@ -664,6 +688,7 @@
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 
 #
@@ -671,7 +696,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -754,6 +782,7 @@
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -872,9 +901,13 @@
 #
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -883,6 +916,7 @@
 # CONFIG_INFINIBAND is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -908,6 +942,7 @@
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -957,6 +992,7 @@
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -981,7 +1017,6 @@
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1081,7 +1116,7 @@
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_SH_STANDARD_BIOS=y
@@ -1110,10 +1145,12 @@
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -1182,6 +1219,7 @@
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1205,7 +1243,8 @@
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/sh7710voipgw_defconfig b/arch/sh/configs/sh7710voipgw_defconfig
index 1b869f4..1ab37c0 100644
--- a/arch/sh/configs/sh7710voipgw_defconfig
+++ b/arch/sh/configs/sh7710voipgw_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 18:00:31 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 19:09:01 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -41,14 +42,23 @@
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 CONFIG_GROUP_SCHED=y
 CONFIG_FAIR_GROUP_SCHED=y
 # CONFIG_RT_GROUP_SCHED is not set
 CONFIG_USER_SCHED=y
 # CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -56,6 +66,7 @@
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 # CONFIG_SYSCTL_SYSCALL is not set
@@ -65,10 +76,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
 # CONFIG_EPOLL is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -76,6 +85,7 @@
 # CONFIG_SHMEM is not set
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -114,11 +124,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="deadline"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -153,6 +158,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -194,11 +200,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -299,7 +306,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -369,6 +375,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 CONFIG_NET_SCHED=y
 
 #
@@ -418,13 +425,13 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -447,6 +454,7 @@
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
 # CONFIG_MTD_AR7_PARTS is not set
@@ -514,6 +522,11 @@
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -527,9 +540,13 @@
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -543,6 +560,7 @@
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -556,8 +574,10 @@
 # CONFIG_STNIC is not set
 # CONFIG_SH_ETH is not set
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -574,7 +594,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -640,6 +663,7 @@
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
@@ -718,15 +742,20 @@
 #
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -742,6 +771,7 @@
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 # CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY is not set
 # CONFIG_QUOTA is not set
@@ -795,6 +825,7 @@
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -844,7 +875,7 @@
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -936,6 +967,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -961,3 +993,4 @@
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/sh7763rdp_defconfig b/arch/sh/configs/sh7763rdp_defconfig
index ba33aca..c79bb84 100644
--- a/arch/sh/configs/sh7763rdp_defconfig
+++ b/arch/sh/configs/sh7763rdp_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 18:02:28 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 19:10:57 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -41,15 +42,24 @@
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 CONFIG_GROUP_SCHED=y
 CONFIG_FAIR_GROUP_SCHED=y
 # CONFIG_RT_GROUP_SCHED is not set
 CONFIG_USER_SCHED=y
 # CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -58,9 +68,11 @@
 CONFIG_IPC_NS=y
 # CONFIG_USER_NS is not set
 # CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 # CONFIG_SYSCTL_SYSCALL is not set
@@ -70,10 +82,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -81,6 +91,7 @@
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -122,11 +133,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -162,6 +168,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -207,11 +214,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -231,6 +239,7 @@
 # Board support
 #
 CONFIG_SH_SH7763RDP=y
+# CONFIG_SH_ESPT is not set
 
 #
 # Timer and clock configuration
@@ -311,8 +320,6 @@
 #
 # Networking options
 #
-# CONFIG_NET_NS is not set
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -367,6 +374,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -374,12 +382,12 @@
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -387,6 +395,7 @@
 CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -409,6 +418,7 @@
 # CONFIG_MTD_DEBUG is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 # CONFIG_MTD_AR7_PARTS is not set
@@ -462,9 +472,7 @@
 #
 CONFIG_MTD_COMPLEX_MAPPINGS=y
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x8000000
-CONFIG_MTD_PHYSMAP_LEN=0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -485,6 +493,11 @@
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -544,9 +557,11 @@
 # CONFIG_LIBFC is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -579,8 +594,10 @@
 # CONFIG_STNIC is not set
 CONFIG_SH_ETH=y
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -597,7 +614,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 
 #
 # USB Network Adapters
@@ -677,6 +697,7 @@
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
@@ -756,6 +777,7 @@
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -807,7 +829,9 @@
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
 # CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
@@ -825,18 +849,17 @@
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
 # CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
 # CONFIG_USB_STORAGE_USBAT is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
@@ -872,7 +895,6 @@
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
@@ -882,6 +904,11 @@
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
 CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
 # CONFIG_MMC_UNSAFE_RESUME is not set
@@ -903,6 +930,7 @@
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -926,6 +954,7 @@
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -974,6 +1003,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -991,7 +1021,6 @@
 CONFIG_LOCKD=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1075,7 +1104,7 @@
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -1167,6 +1196,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1187,7 +1217,7 @@
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/sh7785lcr_32bit_defconfig b/arch/sh/configs/sh7785lcr_32bit_defconfig
index 54e1dee..a6cf4505 100644
--- a/arch/sh/configs/sh7785lcr_32bit_defconfig
+++ b/arch/sh/configs/sh7785lcr_32bit_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc4
-# Fri Feb 20 18:25:29 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 19:12:18 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_NUMA=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -26,6 +26,7 @@
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_IO_TRAPPED=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -71,6 +72,7 @@
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -81,10 +83,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -93,6 +93,7 @@
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -169,6 +170,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 CONFIG_CPU_SUBTYPE_SH7785=y
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -220,11 +222,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -314,6 +317,7 @@
 CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 
@@ -335,7 +339,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -395,6 +398,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -407,7 +411,6 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -512,7 +515,6 @@
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -578,6 +580,7 @@
 # CONFIG_SCSI_SRP_ATTRS is not set
 # CONFIG_SCSI_LOWLEVEL is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
@@ -652,6 +655,7 @@
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -681,6 +685,7 @@
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
 # CONFIG_JME is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
@@ -690,7 +695,6 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -789,6 +793,7 @@
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -854,7 +859,6 @@
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
@@ -964,6 +968,7 @@
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -1079,11 +1084,11 @@
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -1125,7 +1130,6 @@
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
@@ -1141,6 +1145,7 @@
 #
 # OTG and related infrastructure
 #
+# CONFIG_NOP_USB_XCEIV is not set
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1202,6 +1207,7 @@
 #
 # CONFIG_RTC_DRV_SH is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -1299,7 +1305,6 @@
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1404,6 +1409,7 @@
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -1419,7 +1425,6 @@
 # CONFIG_BOOT_TRACER is not set
 # CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1455,10 +1460,12 @@
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -1527,6 +1534,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1547,7 +1555,7 @@
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/sh7785lcr_defconfig b/arch/sh/configs/sh7785lcr_defconfig
index 1d63628..8a42bbe 100644
--- a/arch/sh/configs/sh7785lcr_defconfig
+++ b/arch/sh/configs/sh7785lcr_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 18:05:18 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 19:15:58 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_NUMA=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -26,6 +26,7 @@
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_IO_TRAPPED=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
@@ -46,15 +47,24 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 CONFIG_GROUP_SCHED=y
 CONFIG_FAIR_GROUP_SCHED=y
 # CONFIG_RT_GROUP_SCHED is not set
 CONFIG_USER_SCHED=y
 # CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -62,6 +72,7 @@
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -72,10 +83,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -84,6 +93,7 @@
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -124,11 +134,6 @@
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -165,6 +170,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 CONFIG_CPU_SUBTYPE_SH7785=y
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -180,8 +186,11 @@
 CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
-CONFIG_29BIT=y
+# CONFIG_29BIT is not set
+CONFIG_32BIT=y
+CONFIG_PMB_ENABLE=y
 # CONFIG_PMB is not set
+CONFIG_PMB_FIXED=y
 # CONFIG_X2TLB is not set
 CONFIG_VSYSCALL=y
 # CONFIG_NUMA is not set
@@ -213,11 +222,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -239,7 +249,6 @@
 #
 # CONFIG_SH_HIGHLANDER is not set
 CONFIG_SH_SH7785LCR=y
-CONFIG_SH_SH7785LCR_29BIT_PHYSMAPS=y
 
 #
 # Timer and clock configuration
@@ -307,6 +316,8 @@
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 
@@ -328,7 +339,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -388,6 +398,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -400,7 +411,6 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -408,6 +418,7 @@
 CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -430,6 +441,7 @@
 # CONFIG_MTD_DEBUG is not set
 CONFIG_MTD_CONCAT=y
 CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
 # CONFIG_MTD_AR7_PARTS is not set
@@ -477,9 +489,7 @@
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x00000000
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=0
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_INTEL_VR_NOR is not set
 # CONFIG_MTD_PLATRAM is not set
 
@@ -502,6 +512,11 @@
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -565,6 +580,7 @@
 # CONFIG_SCSI_SRP_ATTRS is not set
 # CONFIG_SCSI_LOWLEVEL is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
@@ -639,6 +655,7 @@
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -668,6 +685,7 @@
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
 # CONFIG_JME is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
@@ -677,7 +695,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 
 #
 # USB Network Adapters
@@ -772,6 +793,7 @@
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -834,12 +856,9 @@
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
@@ -871,6 +890,7 @@
 # CONFIG_PMIC_DA903X is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
 # CONFIG_REGULATOR is not set
 
 #
@@ -948,6 +968,7 @@
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -1041,6 +1062,7 @@
 CONFIG_USB_EHCI_HCD=m
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
 CONFIG_USB_OHCI_HCD=m
@@ -1062,18 +1084,17 @@
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
 # CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
 # CONFIG_USB_STORAGE_USBAT is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
@@ -1109,7 +1130,6 @@
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
@@ -1121,6 +1141,11 @@
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1182,6 +1207,7 @@
 #
 # CONFIG_RTC_DRV_SH is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -1204,6 +1230,7 @@
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1253,6 +1280,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
 # CONFIG_OMFS_FS is not set
@@ -1277,7 +1305,6 @@
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1382,6 +1409,7 @@
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -1397,7 +1425,6 @@
 # CONFIG_BOOT_TRACER is not set
 # CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1433,10 +1460,12 @@
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -1505,6 +1534,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1525,7 +1555,7 @@
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/shmin_defconfig b/arch/sh/configs/shmin_defconfig
index 8ba10e1..d695e90 100644
--- a/arch/sh/configs/shmin_defconfig
+++ b/arch/sh/configs/shmin_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 18:09:00 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 19:19:03 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -16,13 +16,14 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -39,15 +40,25 @@
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 # CONFIG_UID16 is not set
 # CONFIG_SYSCTL_SYSCALL is not set
@@ -56,10 +67,8 @@
 CONFIG_PRINTK=y
 # CONFIG_BUG is not set
 # CONFIG_ELF_CORE is not set
-CONFIG_COMPAT_BRK=y
 # CONFIG_BASE_FULL is not set
 # CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
 # CONFIG_EPOLL is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -67,6 +76,7 @@
 # CONFIG_SHMEM is not set
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 # CONFIG_SLUB is not set
 CONFIG_SLOB=y
@@ -97,11 +107,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -136,6 +141,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -177,11 +183,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -267,7 +274,6 @@
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 # CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 
@@ -281,7 +287,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_PACKET is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
@@ -335,6 +340,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -347,13 +353,13 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -419,9 +425,7 @@
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0xa0000000
-CONFIG_MTD_PHYSMAP_LEN=0x80000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=1
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
 # CONFIG_MTD_PLATRAM is not set
 
 #
@@ -442,6 +446,11 @@
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -456,9 +465,13 @@
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -472,6 +485,7 @@
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -484,8 +498,10 @@
 # CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -502,7 +518,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -549,6 +568,7 @@
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
@@ -618,15 +638,20 @@
 #
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -641,6 +666,7 @@
 # CONFIG_FS_POSIX_ACL is not set
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_BTRFS_FS is not set
 # CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY is not set
 # CONFIG_QUOTA is not set
@@ -683,6 +709,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -702,7 +729,6 @@
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -740,7 +766,6 @@
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_SH_STANDARD_BIOS=y
@@ -831,6 +856,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -855,3 +881,4 @@
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/shx3_defconfig b/arch/sh/configs/shx3_defconfig
index ed90a7e..e3651f5 100644
--- a/arch/sh/configs/shx3_defconfig
+++ b/arch/sh/configs/shx3_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 18:10:57 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 19:20:54 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -19,7 +19,7 @@
 CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
 CONFIG_GENERIC_LOCKBREAK=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_SMP=y
 CONFIG_SYS_SUPPORTS_NUMA=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -27,6 +27,7 @@
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -47,24 +48,35 @@
 CONFIG_AUDIT=y
 CONFIG_AUDITSYSCALL=y
 CONFIG_AUDIT_TREE=y
+
+#
+# RCU Subsystem
+#
+# CONFIG_CLASSIC_RCU is not set
+# CONFIG_TREE_RCU is not set
+CONFIG_PREEMPT_RCU=y
+CONFIG_RCU_TRACE=y
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_PREEMPT_RCU_TRACE=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
 CONFIG_CGROUPS=y
 # CONFIG_CGROUP_DEBUG is not set
 CONFIG_CGROUP_NS=y
 CONFIG_CGROUP_FREEZER=y
 CONFIG_CGROUP_DEVICE=y
 # CONFIG_CPUSETS is not set
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_RT_GROUP_SCHED=y
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 CONFIG_CGROUP_CPUACCT=y
 CONFIG_RESOURCE_COUNTERS=y
-CONFIG_MM_OWNER=y
 CONFIG_CGROUP_MEM_RES_CTLR=y
+# CONFIG_CGROUP_MEM_RES_CTLR_SWAP is not set
+CONFIG_MM_OWNER=y
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_RELAY=y
@@ -73,24 +85,23 @@
 CONFIG_IPC_NS=y
 CONFIG_USER_NS=y
 CONFIG_PID_NS=y
+# CONFIG_NET_NS is not set
 # CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -98,6 +109,7 @@
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 # CONFIG_SLUB is not set
 CONFIG_SLOB=y
@@ -142,12 +154,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-# CONFIG_CLASSIC_RCU is not set
-# CONFIG_TREE_RCU is not set
-CONFIG_PREEMPT_RCU=y
-CONFIG_RCU_TRACE=y
-# CONFIG_TREE_RCU_TRACE is not set
-CONFIG_PREEMPT_RCU_TRACE=y
 CONFIG_FREEZER=y
 
 #
@@ -184,6 +190,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 CONFIG_CPU_SUBTYPE_SHX3=y
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -240,11 +247,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -361,8 +369,6 @@
 #
 # Networking options
 #
-# CONFIG_NET_NS is not set
-CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_PACKET is not set
 # CONFIG_UNIX is not set
 CONFIG_XFRM=y
@@ -434,6 +440,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -442,6 +449,7 @@
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_NET_TCPPROBE is not set
+# CONFIG_NET_DROP_MONITOR is not set
 # CONFIG_HAMRADIO is not set
 CONFIG_CAN=m
 CONFIG_CAN_RAW=m
@@ -455,8 +463,8 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 # CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -490,10 +498,18 @@
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -539,6 +555,7 @@
 # CONFIG_LIBFC is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
@@ -547,6 +564,7 @@
 CONFIG_PATA_PLATFORM=y
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -560,8 +578,10 @@
 # CONFIG_STNIC is not set
 CONFIG_SMC91X=y
 # CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -578,7 +598,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 
 #
 # USB Network Adapters
@@ -670,12 +693,9 @@
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
@@ -695,7 +715,6 @@
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
 # CONFIG_W1 is not set
@@ -732,6 +751,7 @@
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
 # CONFIG_REGULATOR is not set
 
 #
@@ -788,7 +808,9 @@
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
 CONFIG_USB_R8A66597_HCD=m
 # CONFIG_USB_HWA_HCD is not set
@@ -803,11 +825,11 @@
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
 # CONFIG_USB_STORAGE is not set
 # CONFIG_USB_LIBUSUAL is not set
@@ -837,7 +859,6 @@
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
@@ -860,10 +881,12 @@
 # CONFIG_USB_GADGET_PXA25X is not set
 # CONFIG_USB_GADGET_PXA27X is not set
 # CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_IMX is not set
 CONFIG_USB_GADGET_M66592=y
 CONFIG_USB_M66592=y
 # CONFIG_USB_GADGET_AMD5536UDC is not set
 # CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
 # CONFIG_USB_GADGET_NET2280 is not set
 # CONFIG_USB_GADGET_GOKU is not set
 # CONFIG_USB_GADGET_DUMMY_HCD is not set
@@ -876,6 +899,11 @@
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
 # CONFIG_USB_CDC_COMPOSITE is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -942,6 +970,7 @@
 #
 CONFIG_RTC_DRV_SH=y
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 CONFIG_UIO=m
 # CONFIG_UIO_PDRV is not set
 # CONFIG_UIO_PDRV_GENIRQ is not set
@@ -969,6 +998,7 @@
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1012,6 +1042,7 @@
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -1086,6 +1117,7 @@
 # CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
 CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
@@ -1105,7 +1137,7 @@
 # CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_FTRACE_STARTUP_TEST is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1205,6 +1237,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1226,7 +1259,7 @@
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_AUDIT_GENERIC=y
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/snapgear_defconfig b/arch/sh/configs/snapgear_defconfig
index 98377e5..6960f60 100644
--- a/arch/sh/configs/snapgear_defconfig
+++ b/arch/sh/configs/snapgear_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 18:14:08 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 19:21:39 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -41,18 +42,32 @@
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 # CONFIG_SYSCTL_SYSCALL is not set
@@ -62,10 +77,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -74,6 +87,7 @@
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -107,11 +121,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -146,6 +155,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -187,11 +197,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -239,6 +250,7 @@
 #
 CONFIG_SH_DMA_API=y
 CONFIG_SH_DMA=y
+CONFIG_SH_DMA_IRQ_MULTI=y
 CONFIG_NR_ONCHIP_DMA_CHANNELS=8
 # CONFIG_NR_DMA_CHANNELS_BOOL is not set
 
@@ -288,6 +300,8 @@
 # CONFIG_PCIEPORTBUS is not set
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 
 #
 # Executable file formats
@@ -307,7 +321,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_PACKET is not set
 # CONFIG_UNIX is not set
 # CONFIG_NET_KEY is not set
@@ -352,6 +365,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -364,13 +378,13 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -464,6 +478,11 @@
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -509,6 +528,7 @@
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -526,8 +546,10 @@
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -571,7 +593,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -711,6 +736,7 @@
 # CONFIG_INFINIBAND is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -728,6 +754,7 @@
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 # CONFIG_DNOTIFY is not set
 # CONFIG_INOTIFY is not set
 # CONFIG_QUOTA is not set
@@ -771,6 +798,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -820,7 +848,6 @@
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -849,7 +876,8 @@
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/systemh_defconfig b/arch/sh/configs/systemh_defconfig
index 72703bf..7ea639b 100644
--- a/arch/sh/configs/systemh_defconfig
+++ b/arch/sh/configs/systemh_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 18:15:56 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 19:23:31 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -38,18 +39,32 @@
 CONFIG_SWAP=y
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 # CONFIG_SYSCTL_SYSCALL is not set
@@ -59,10 +74,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -70,6 +83,7 @@
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -109,11 +123,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -148,6 +157,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -189,11 +199,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -318,9 +329,13 @@
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -372,6 +387,7 @@
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
@@ -452,15 +468,20 @@
 #
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -475,6 +496,7 @@
 # CONFIG_FS_POSIX_ACL is not set
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -518,6 +540,7 @@
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
 CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -558,7 +581,6 @@
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -587,7 +609,7 @@
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
diff --git a/arch/sh/configs/titan_defconfig b/arch/sh/configs/titan_defconfig
index 01fc1de..bbeb4c6 100644
--- a/arch/sh/configs/titan_defconfig
+++ b/arch/sh/configs/titan_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 18:17:19 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 19:24:55 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_PCI=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -42,19 +43,33 @@
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=16
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 # CONFIG_SYSCTL_SYSCALL is not set
@@ -65,10 +80,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -77,6 +90,7 @@
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -116,11 +130,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -155,6 +164,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -196,11 +206,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -248,6 +259,7 @@
 #
 CONFIG_SH_DMA_API=y
 CONFIG_SH_DMA=y
+CONFIG_SH_DMA_IRQ_MULTI=y
 CONFIG_NR_ONCHIP_DMA_CHANNELS=8
 # CONFIG_NR_DMA_CHANNELS_BOOL is not set
 
@@ -299,6 +311,8 @@
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 CONFIG_HOTPLUG_PCI=y
 # CONFIG_HOTPLUG_PCI_FAKE is not set
@@ -323,7 +337,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -406,6 +419,7 @@
 CONFIG_NETFILTER_XTABLES=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 # CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+CONFIG_NETFILTER_XT_TARGET_HL=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 # CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
 CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
@@ -418,6 +432,7 @@
 # CONFIG_NETFILTER_XT_MATCH_DSCP is not set
 CONFIG_NETFILTER_XT_MATCH_ESP=m
 # CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+CONFIG_NETFILTER_XT_MATCH_HL=m
 # CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
 CONFIG_NETFILTER_XT_MATCH_LENGTH=m
 CONFIG_NETFILTER_XT_MATCH_LIMIT=m
@@ -475,11 +490,11 @@
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
 # CONFIG_IP6_NF_MATCH_MH is not set
 CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
 CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_REJECT=m
 CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_HL=m
 CONFIG_IP6_NF_RAW=m
 # CONFIG_BRIDGE_NF_EBTABLES is not set
 # CONFIG_IP_DCCP is not set
@@ -500,6 +515,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 CONFIG_NET_SCHED=y
 
 #
@@ -565,7 +581,6 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_FIB_RULES=y
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
@@ -574,6 +589,7 @@
 CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_LIB80211 is not set
 # CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -599,6 +615,7 @@
 CONFIG_MTD_DEBUG_VERBOSE=0
 # CONFIG_MTD_CONCAT is not set
 # CONFIG_MTD_PARTITIONS is not set
+# CONFIG_MTD_TESTS is not set
 
 #
 # User Modules And Translation Layers
@@ -675,6 +692,11 @@
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -698,12 +720,16 @@
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -760,6 +786,7 @@
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
 # CONFIG_SCSI_HPTIOP is not set
 # CONFIG_LIBFC is not set
 # CONFIG_FCOE is not set
@@ -781,6 +808,7 @@
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 # CONFIG_FUSION is not set
@@ -796,6 +824,7 @@
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_IFB is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
@@ -832,8 +861,10 @@
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -888,6 +919,7 @@
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
 # CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
@@ -906,6 +938,7 @@
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 
 #
@@ -913,7 +946,10 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 
 #
 # USB Network Adapters
@@ -1025,6 +1061,7 @@
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -1174,6 +1211,7 @@
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
 CONFIG_USB_OHCI_HCD=y
@@ -1195,18 +1233,17 @@
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
 # CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
 # CONFIG_USB_STORAGE_USBAT is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
@@ -1235,7 +1272,7 @@
 # CONFIG_USB_SERIAL_CH341 is not set
 # CONFIG_USB_SERIAL_WHITEHEAT is not set
 # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_CP2101 is not set
+# CONFIG_USB_SERIAL_CP210X is not set
 # CONFIG_USB_SERIAL_CYPRESS_M8 is not set
 # CONFIG_USB_SERIAL_EMPEG is not set
 # CONFIG_USB_SERIAL_FTDI_SIO is not set
@@ -1259,15 +1296,19 @@
 # CONFIG_USB_SERIAL_NAVMAN is not set
 CONFIG_USB_SERIAL_PL2303=m
 # CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QUALCOMM is not set
 # CONFIG_USB_SERIAL_SPCP8X5 is not set
 # CONFIG_USB_SERIAL_HP4X is not set
 # CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
 # CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_SYMBOL is not set
 # CONFIG_USB_SERIAL_TI is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
 # CONFIG_USB_SERIAL_OPTION is not set
 # CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_OPTICON is not set
 # CONFIG_USB_SERIAL_DEBUG is not set
 
 #
@@ -1284,7 +1325,6 @@
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
@@ -1296,6 +1336,11 @@
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
 # CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -1337,6 +1382,7 @@
 #
 CONFIG_RTC_DRV_SH=m
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -1363,6 +1409,7 @@
 # CONFIG_XFS_RT is not set
 # CONFIG_XFS_DEBUG is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1413,6 +1460,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -1436,7 +1484,6 @@
 CONFIG_EXPORTFS=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1559,6 +1606,7 @@
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+# CONFIG_PAGE_POISONING is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -1573,7 +1621,6 @@
 # CONFIG_BOOT_TRACER is not set
 # CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1610,10 +1657,12 @@
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=y
 # CONFIG_CRYPTO_TEST is not set
@@ -1683,6 +1732,7 @@
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1706,11 +1756,12 @@
 CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_TEXTSEARCH=y
 CONFIG_TEXTSEARCH_KMP=m
 CONFIG_TEXTSEARCH_BM=m
 CONFIG_TEXTSEARCH_FSM=m
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/ul2_defconfig b/arch/sh/configs/ul2_defconfig
index 27f968a..34f5192 100644
--- a/arch/sh/configs/ul2_defconfig
+++ b/arch/sh/configs/ul2_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan  9 18:22:53 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 19:30:27 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -16,15 +16,17 @@
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
-# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_NUMA=y
+CONFIG_SYS_SUPPORTS_CMT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -44,19 +46,33 @@
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
 # CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -66,10 +82,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -78,6 +92,7 @@
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
@@ -118,11 +133,6 @@
 # CONFIG_DEFAULT_CFQ is not set
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 
 #
@@ -132,6 +142,7 @@
 CONFIG_CPU_SH4A=y
 CONFIG_CPU_SH4AL_DSP=y
 CONFIG_CPU_SHX2=y
+CONFIG_ARCH_SHMOBILE=y
 # CONFIG_CPU_SUBTYPE_SH7619 is not set
 # CONFIG_CPU_SUBTYPE_SH7201 is not set
 # CONFIG_CPU_SUBTYPE_SH7203 is not set
@@ -160,6 +171,7 @@
 # CONFIG_CPU_SUBTYPE_SH7770 is not set
 # CONFIG_CPU_SUBTYPE_SH7780 is not set
 # CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
 # CONFIG_CPU_SUBTYPE_SHX3 is not set
 # CONFIG_CPU_SUBTYPE_SH7343 is not set
 # CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -213,11 +225,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -243,6 +256,7 @@
 # Timer and clock configuration
 #
 CONFIG_SH_TMU=y
+# CONFIG_SH_TIMER_CMT is not set
 CONFIG_SH_TIMER_IRQ=16
 CONFIG_SH_PCLK_FREQ=33333333
 CONFIG_TICK_ONESHOT=y
@@ -319,7 +333,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -374,6 +387,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -386,15 +400,14 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 CONFIG_CFG80211=y
 # CONFIG_CFG80211_REG_DEBUG is not set
-CONFIG_NL80211=y
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
 CONFIG_WIRELESS_EXT=y
 CONFIG_WIRELESS_EXT_SYSFS=y
 CONFIG_LIB80211=m
+# CONFIG_LIB80211_DEBUG is not set
 CONFIG_MAC80211=y
 
 #
@@ -408,6 +421,7 @@
 # CONFIG_MAC80211_MESH is not set
 # CONFIG_MAC80211_LEDS is not set
 # CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -430,6 +444,7 @@
 # CONFIG_MTD_DEBUG is not set
 CONFIG_MTD_CONCAT=y
 CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
 # CONFIG_MTD_AR7_PARTS is not set
@@ -497,6 +512,11 @@
 # CONFIG_MTD_ONENAND is not set
 
 #
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
 # UBI - Unsorted block images
 #
 # CONFIG_MTD_UBI is not set
@@ -514,9 +534,13 @@
 # CONFIG_ATA_OVER_ETH is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -562,6 +586,7 @@
 # CONFIG_LIBFC is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
@@ -570,6 +595,7 @@
 CONFIG_PATA_PLATFORM=y
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -582,8 +608,10 @@
 # CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 # CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -605,12 +633,13 @@
 CONFIG_LIBERTAS_SDIO=m
 CONFIG_LIBERTAS_DEBUG=y
 # CONFIG_LIBERTAS_THINFIRM is not set
+# CONFIG_AT76C50X_USB is not set
 # CONFIG_USB_ZD1201 is not set
 # CONFIG_USB_NET_RNDIS_WLAN is not set
 # CONFIG_RTL8187 is not set
 # CONFIG_MAC80211_HWSIM is not set
 # CONFIG_P54_COMMON is not set
-# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_AR9170_USB is not set
 # CONFIG_HOSTAP is not set
 # CONFIG_B43 is not set
 # CONFIG_B43LEGACY is not set
@@ -618,6 +647,10 @@
 # CONFIG_RT2X00 is not set
 
 #
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
 # USB Network Adapters
 #
 # CONFIG_USB_CATC is not set
@@ -794,7 +827,9 @@
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
 CONFIG_USB_R8A66597_HCD=y
 # CONFIG_SUPERH_ON_CHIP_R8A66597 is not set
@@ -809,18 +844,17 @@
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
 # CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
 # CONFIG_USB_STORAGE_USBAT is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
@@ -856,7 +890,6 @@
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
@@ -866,6 +899,11 @@
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
 CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
 # CONFIG_MMC_UNSAFE_RESUME is not set
@@ -887,6 +925,7 @@
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -909,6 +948,7 @@
 CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -956,6 +996,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS2_FS is not set
 CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_OMFS_FS is not set
@@ -976,7 +1017,6 @@
 CONFIG_EXPORTFS=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1059,7 +1099,6 @@
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -1087,10 +1126,12 @@
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -1159,6 +1200,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1180,7 +1222,8 @@
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/urquell_defconfig b/arch/sh/configs/urquell_defconfig
index be726c7c..d174b1a 100644
--- a/arch/sh/configs/urquell_defconfig
+++ b/arch/sh/configs/urquell_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc4
-# Thu Mar  5 17:28:13 2009
+# Linux kernel version: 2.6.29
+# Thu Apr  2 19:33:39 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 # CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_SYS_SUPPORTS_NUMA=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -69,6 +70,7 @@
 # CONFIG_BLK_DEV_INITRD is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -78,10 +80,8 @@
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -89,6 +89,7 @@
 CONFIG_SHMEM=y
 CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -213,11 +214,12 @@
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=2
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 
 #
 # Cache configuration
 #
-# CONFIG_SH_DIRECT_MAPPED is not set
 CONFIG_CACHE_WRITEBACK=y
 # CONFIG_CACHE_WRITETHROUGH is not set
 # CONFIG_CACHE_OFF is not set
@@ -231,6 +233,7 @@
 CONFIG_SH_STORE_QUEUES=y
 CONFIG_CPU_HAS_INTEVT=y
 CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_PTEAEX=y
 CONFIG_CPU_HAS_FPU=y
 
 #
@@ -318,7 +321,6 @@
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -378,6 +380,7 @@
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -390,7 +393,6 @@
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -491,7 +493,6 @@
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -553,6 +554,7 @@
 # CONFIG_SCSI_SRP_ATTRS is not set
 # CONFIG_SCSI_LOWLEVEL is not set
 # CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
@@ -561,6 +563,7 @@
 # CONFIG_PATA_PLATFORM is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -592,8 +595,10 @@
 # CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
 CONFIG_SMC91X=y
+# CONFIG_ETHOC is not set
 # CONFIG_SMC911X is not set
 # CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -610,7 +615,6 @@
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -705,6 +709,7 @@
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
@@ -746,7 +751,6 @@
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
@@ -855,6 +859,7 @@
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -922,7 +927,7 @@
 CONFIG_ZEROPLUS_FF=m
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
-# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_OHCI=y
 # CONFIG_USB_ARCH_HAS_EHCI is not set
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
@@ -947,6 +952,8 @@
 # CONFIG_USB_C67X00_HCD is not set
 # CONFIG_USB_OXU210HP_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
 # CONFIG_USB_R8A66597_HCD is not set
 # CONFIG_USB_HWA_HCD is not set
@@ -960,11 +967,11 @@
 # CONFIG_USB_TMC is not set
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 
 #
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
 #
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -1006,7 +1013,6 @@
 # CONFIG_USB_LED is not set
 # CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
@@ -1022,12 +1028,14 @@
 # OTG and related infrastructure
 #
 # CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -1125,7 +1133,6 @@
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1206,7 +1213,6 @@
 #
 # Tracers
 #
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
@@ -1234,10 +1240,12 @@
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -1306,6 +1314,7 @@
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1326,7 +1335,7 @@
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/drivers/dma/Kconfig b/arch/sh/drivers/dma/Kconfig
index f13a052..666713a 100644
--- a/arch/sh/drivers/dma/Kconfig
+++ b/arch/sh/drivers/dma/Kconfig
@@ -12,21 +12,25 @@
 config SH_DMA_IRQ_MULTI
 	bool
 	depends on SH_DMA
-	default y if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7751 || \
-		CPU_SUBTYPE_SH7750S || CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R || \
-		CPU_SUBTYPE_SH7091 || CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7764 || \
-		CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785
+	default y if CPU_SUBTYPE_SH7750  || CPU_SUBTYPE_SH7751  || \
+		     CPU_SUBTYPE_SH7750S || CPU_SUBTYPE_SH7750R || \
+		     CPU_SUBTYPE_SH7751R || CPU_SUBTYPE_SH7091  || \
+		     CPU_SUBTYPE_SH7763  || CPU_SUBTYPE_SH7764  || \
+		     CPU_SUBTYPE_SH7780  || CPU_SUBTYPE_SH7785
 
 config NR_ONCHIP_DMA_CHANNELS
 	int
 	depends on SH_DMA
-	default "4" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7751 || CPU_SUBTYPE_SH7750S
-	default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R || CPU_SUBTYPE_SH7760
-	default "12" if CPU_SUBTYPE_SH7723 || CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785
+	default "4" if CPU_SUBTYPE_SH7750  || CPU_SUBTYPE_SH7751  || \
+		       CPU_SUBTYPE_SH7750S || CPU_SUBTYPE_SH7091
+	default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R || \
+		       CPU_SUBTYPE_SH7760
+	default "12" if CPU_SUBTYPE_SH7723 || CPU_SUBTYPE_SH7780  || \
+			CPU_SUBTYPE_SH7785
 	default "6"
 	help
 	  This allows you to specify the number of channels that the on-chip
-	  DMAC supports. This will be 4 for SH7750/SH7751 and 8 for the
+	  DMAC supports. This will be 4 for SH7091/SH7750/SH7751 and 8 for the
 	  SH7750R/SH7751R.
 
 config NR_DMA_CHANNELS_BOOL
diff --git a/arch/sh/drivers/pci/ops-sh7785lcr.c b/arch/sh/drivers/pci/ops-sh7785lcr.c
index b3bd6870..e8b7446 100644
--- a/arch/sh/drivers/pci/ops-sh7785lcr.c
+++ b/arch/sh/drivers/pci/ops-sh7785lcr.c
@@ -48,13 +48,8 @@
 
 static struct sh4_pci_address_map sh7785_pci_map = {
 	.window0	= {
-		.base	= SH7780_CS2_BASE_ADDR,
-		.size	= 0x04000000,
-	},
-
-	.window1	= {
-		.base	= SH7780_CS3_BASE_ADDR,
-		.size	= 0x04000000,
+		.base	= SH7780_CS0_BASE_ADDR,
+		.size	= 0x20000000,
 	},
 
 	.flags	= SH4_PCIC_NO_RESET,
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c
index 773d575..bae6a2c 100644
--- a/arch/sh/drivers/pci/pci-sh7780.c
+++ b/arch/sh/drivers/pci/pci-sh7780.c
@@ -120,19 +120,15 @@
 
 	/* Set IO and Mem windows to local address
 	 * Make PCI and local address the same for easy 1 to 1 mapping
-	 * Window0 = map->window0.size @ non-cached area base = SDRAM
-	 * Window1 = map->window1.size @ cached area base = SDRAM
 	 */
-	word = (CONFIG_MEMORY_SIZE - 0x00100000) | 0x00000001;
-	pci_write_reg(word, SH4_PCILSR0);
-	pci_write_reg(0x00000001, SH4_PCILSR1);
+	pci_write_reg(map->window0.size - 0xfffff, SH4_PCILSR0);
+	pci_write_reg(map->window1.size - 0xfffff, SH4_PCILSR1);
 	/* Set the values on window 0 PCI config registers */
-	word = CONFIG_MEMORY_START | (CONFIG_MEMORY_SIZE - 0x01000000);
-	pci_write_reg(word, SH4_PCILAR0);
-	pci_write_reg(word, SH7780_PCIMBAR0);
+	pci_write_reg(map->window0.base, SH4_PCILAR0);
+	pci_write_reg(map->window0.base, SH7780_PCIMBAR0);
 	/* Set the values on window 1 PCI config registers */
-	pci_write_reg(0x00000000, SH4_PCILAR1);
-	pci_write_reg(0x00000000, SH7780_PCIMBAR1);
+	pci_write_reg(map->window1.base, SH4_PCILAR1);
+	pci_write_reg(map->window1.base, SH7780_PCIMBAR1);
 
 	/* Map IO space into PCI IO window
 	 * The IO window is 64K-PCIBIOS_MIN_IO in size
diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h
index 6c43625..f596303 100644
--- a/arch/sh/include/asm/mmu.h
+++ b/arch/sh/include/asm/mmu.h
@@ -1,22 +1,6 @@
 #ifndef __MMU_H
 #define __MMU_H
 
-/* Default "unsigned long" context */
-typedef unsigned long mm_context_id_t[NR_CPUS];
-
-typedef struct {
-#ifdef CONFIG_MMU
-	mm_context_id_t		id;
-	void			*vdso;
-#else
-	unsigned long		end_brk;
-#endif
-#ifdef CONFIG_BINFMT_ELF_FDPIC
-	unsigned long		exec_fdpic_loadmap;
-	unsigned long		interp_fdpic_loadmap;
-#endif
-} mm_context_t;
-
 /*
  * Privileged Space Mapping Buffer (PMB) definitions
  */
@@ -41,6 +25,24 @@
 
 #define PMB_NO_ENTRY		(-1)
 
+#ifndef __ASSEMBLY__
+
+/* Default "unsigned long" context */
+typedef unsigned long mm_context_id_t[NR_CPUS];
+
+typedef struct {
+#ifdef CONFIG_MMU
+	mm_context_id_t		id;
+	void			*vdso;
+#else
+	unsigned long		end_brk;
+#endif
+#ifdef CONFIG_BINFMT_ELF_FDPIC
+	unsigned long		exec_fdpic_loadmap;
+	unsigned long		interp_fdpic_loadmap;
+#endif
+} mm_context_t;
+
 struct pmb_entry;
 
 struct pmb_entry {
@@ -70,6 +72,7 @@
 long pmb_remap(unsigned long virt, unsigned long phys,
 	       unsigned long size, unsigned long flags);
 void pmb_unmap(unsigned long addr);
+#endif /* __ASSEMBLY__ */
 
 #endif /* __MMU_H */
 
diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h
index efdd78a..9a87149 100644
--- a/arch/sh/include/asm/processor_32.h
+++ b/arch/sh/include/asm/processor_32.h
@@ -58,6 +58,14 @@
 #define SR_FD		0x00008000
 
 /*
+ * DSP structure and data
+ */
+struct sh_dsp_struct {
+	unsigned long dsp_regs[14];
+	long status;
+};
+
+/*
  * FPU structure and data
  */
 
@@ -96,6 +104,11 @@
 
 	/* floating point info */
 	union sh_fpu_union fpu;
+
+#ifdef CONFIG_SH_DSP
+	/* Dsp status information */
+	struct sh_dsp_struct dsp_status;
+#endif
 };
 
 /* Count of active tasks with UBC settings */
diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h
index 81c6568..d3f6caa 100644
--- a/arch/sh/include/asm/ptrace.h
+++ b/arch/sh/include/asm/ptrace.h
@@ -119,16 +119,8 @@
 extern void user_enable_single_step(struct task_struct *);
 extern void user_disable_single_step(struct task_struct *);
 
-#ifdef CONFIG_SH_DSP
-#define task_pt_regs(task) \
-	((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE \
-		 - sizeof(struct pt_dspregs)) - 1)
-#define task_pt_dspregs(task) \
-	((struct pt_dspregs *) (task_stack_page(task) + THREAD_SIZE) - 1)
-#else
 #define task_pt_regs(task) \
 	((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE) - 1)
-#endif
 
 static inline unsigned long profile_pc(struct pt_regs *regs)
 {
diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h
index c9ec6af..a88895e 100644
--- a/arch/sh/include/asm/system.h
+++ b/arch/sh/include/asm/system.h
@@ -153,6 +153,7 @@
 extern struct dentry *sh_debugfs_root;
 
 void per_cpu_trap_init(void);
+void default_idle(void);
 
 asmlinkage void break_point_trap(void);
 
diff --git a/arch/sh/include/asm/system_32.h b/arch/sh/include/asm/system_32.h
index a726d5d..240b31e 100644
--- a/arch/sh/include/asm/system_32.h
+++ b/arch/sh/include/asm/system_32.h
@@ -3,59 +3,135 @@
 
 #include <linux/types.h>
 
+#ifdef CONFIG_SH_DSP
+
+#define is_dsp_enabled(tsk)						\
+	(!!(tsk->thread.dsp_status.status & SR_DSP))
+
+#define __restore_dsp(tsk)						\
+do {									\
+	register u32 *__ts2 __asm__ ("r2") =				\
+			(u32 *)&tsk->thread.dsp_status;			\
+	__asm__ __volatile__ (						\
+		".balign 4\n\t"						\
+		"movs.l	@r2+, a1\n\t"					\
+		"movs.l	@r2+, a0g\n\t"					\
+		"movs.l	@r2+, a1g\n\t"					\
+		"movs.l	@r2+, m0\n\t"					\
+		"movs.l	@r2+, m1\n\t"					\
+		"movs.l	@r2+, a0\n\t"					\
+		"movs.l	@r2+, x0\n\t"					\
+		"movs.l	@r2+, x1\n\t"					\
+		"movs.l	@r2+, y0\n\t"					\
+		"movs.l	@r2+, y1\n\t"					\
+		"lds.l	@r2+, dsr\n\t"					\
+		"ldc.l	@r2+, rs\n\t"					\
+		"ldc.l	@r2+, re\n\t"					\
+		"ldc.l	@r2+, mod\n\t"					\
+		: : "r" (__ts2));					\
+} while (0)
+
+
+#define __save_dsp(tsk)							\
+do {									\
+	register u32 *__ts2 __asm__ ("r2") =				\
+			(u32 *)&tsk->thread.dsp_status + 14;		\
+									\
+	__asm__ __volatile__ (						\
+		".balign 4\n\t"						\
+		"stc.l	mod, @-r2\n\t"				\
+		"stc.l	re, @-r2\n\t"					\
+		"stc.l	rs, @-r2\n\t"					\
+		"sts.l	dsr, @-r2\n\t"				\
+		"sts.l	y1, @-r2\n\t"					\
+		"sts.l	y0, @-r2\n\t"					\
+		"sts.l	x1, @-r2\n\t"					\
+		"sts.l	x0, @-r2\n\t"					\
+		"sts.l	a0, @-r2\n\t"					\
+		".word	0xf653		! movs.l	a1, @-r2\n\t"	\
+		".word	0xf6f3		! movs.l	a0g, @-r2\n\t"	\
+		".word	0xf6d3		! movs.l	a1g, @-r2\n\t"	\
+		".word	0xf6c3		! movs.l        m0, @-r2\n\t"	\
+		".word	0xf6e3		! movs.l        m1, @-r2\n\t"	\
+		: : "r" (__ts2));					\
+} while (0)
+
+#else
+
+#define is_dsp_enabled(tsk)	(0)
+#define __save_dsp(tsk)		do { } while (0)
+#define __restore_dsp(tsk)	do { } while (0)
+#endif
+
 struct task_struct *__switch_to(struct task_struct *prev,
 				struct task_struct *next);
 
 /*
  *	switch_to() should switch tasks to task nr n, first
  */
-#define switch_to(prev, next, last)					\
-do {									\
-	register u32 *__ts1 __asm__ ("r1") = (u32 *)&prev->thread.sp;	\
-	register u32 *__ts2 __asm__ ("r2") = (u32 *)&prev->thread.pc;	\
-	register u32 *__ts4 __asm__ ("r4") = (u32 *)prev;		\
-	register u32 *__ts5 __asm__ ("r5") = (u32 *)next;		\
-	register u32 *__ts6 __asm__ ("r6") = (u32 *)&next->thread.sp;	\
-	register u32 __ts7 __asm__ ("r7") = next->thread.pc;		\
-	struct task_struct *__last;					\
-									\
-	__asm__ __volatile__ (						\
-		".balign 4\n\t"						\
-		"stc.l	gbr, @-r15\n\t"					\
-		"sts.l	pr, @-r15\n\t"					\
-		"mov.l	r8, @-r15\n\t"					\
-		"mov.l	r9, @-r15\n\t"					\
-		"mov.l	r10, @-r15\n\t"					\
-		"mov.l	r11, @-r15\n\t"					\
-		"mov.l	r12, @-r15\n\t"					\
-		"mov.l	r13, @-r15\n\t"					\
-		"mov.l	r14, @-r15\n\t"					\
-		"mov.l	r15, @r1\t! save SP\n\t"			\
-		"mov.l	@r6, r15\t! change to new stack\n\t"		\
-		"mova	1f, %0\n\t"					\
-		"mov.l	%0, @r2\t! save PC\n\t"				\
-		"mov.l	2f, %0\n\t"					\
-		"jmp	@%0\t! call __switch_to\n\t"			\
-		" lds	r7, pr\t!  with return to new PC\n\t"		\
-		".balign	4\n"					\
-		"2:\n\t"						\
-		".long	__switch_to\n"					\
-		"1:\n\t"						\
-		"mov.l	@r15+, r14\n\t"					\
-		"mov.l	@r15+, r13\n\t"					\
-		"mov.l	@r15+, r12\n\t"					\
-		"mov.l	@r15+, r11\n\t"					\
-		"mov.l	@r15+, r10\n\t"					\
-		"mov.l	@r15+, r9\n\t"					\
-		"mov.l	@r15+, r8\n\t"					\
-		"lds.l	@r15+, pr\n\t"					\
-		"ldc.l	@r15+, gbr\n\t"					\
-		: "=z" (__last)						\
-		: "r" (__ts1), "r" (__ts2), "r" (__ts4),		\
-		  "r" (__ts5), "r" (__ts6), "r" (__ts7)			\
-		: "r3", "t");						\
-									\
-	last = __last;							\
+#define switch_to(prev, next, last)				\
+do {								\
+	register u32 *__ts1 __asm__ ("r1");			\
+	register u32 *__ts2 __asm__ ("r2");			\
+	register u32 *__ts4 __asm__ ("r4");			\
+	register u32 *__ts5 __asm__ ("r5");			\
+	register u32 *__ts6 __asm__ ("r6");			\
+	register u32 __ts7 __asm__ ("r7");			\
+	struct task_struct *__last;				\
+								\
+	if (is_dsp_enabled(prev))				\
+		__save_dsp(prev);				\
+								\
+	__ts1 = (u32 *)&prev->thread.sp;			\
+	__ts2 = (u32 *)&prev->thread.pc;			\
+	__ts4 = (u32 *)prev;					\
+	__ts5 = (u32 *)next;					\
+	__ts6 = (u32 *)&next->thread.sp;			\
+	__ts7 = next->thread.pc;				\
+								\
+	__asm__ __volatile__ (					\
+		".balign 4\n\t"					\
+		"stc.l	gbr, @-r15\n\t"				\
+		"sts.l	pr, @-r15\n\t"				\
+		"mov.l	r8, @-r15\n\t"				\
+		"mov.l	r9, @-r15\n\t"				\
+		"mov.l	r10, @-r15\n\t"				\
+		"mov.l	r11, @-r15\n\t"				\
+		"mov.l	r12, @-r15\n\t"				\
+		"mov.l	r13, @-r15\n\t"				\
+		"mov.l	r14, @-r15\n\t"				\
+		"mov.l	r15, @r1\t! save SP\n\t"		\
+		"mov.l	@r6, r15\t! change to new stack\n\t"	\
+		"mova	1f, %0\n\t"				\
+		"mov.l	%0, @r2\t! save PC\n\t"			\
+		"mov.l	2f, %0\n\t"				\
+		"jmp	@%0\t! call __switch_to\n\t"		\
+		" lds	r7, pr\t!  with return to new PC\n\t"	\
+		".balign	4\n"				\
+		"2:\n\t"					\
+		".long	__switch_to\n"				\
+		"1:\n\t"					\
+		"mov.l	@r15+, r14\n\t"				\
+		"mov.l	@r15+, r13\n\t"				\
+		"mov.l	@r15+, r12\n\t"				\
+		"mov.l	@r15+, r11\n\t"				\
+		"mov.l	@r15+, r10\n\t"				\
+		"mov.l	@r15+, r9\n\t"				\
+		"mov.l	@r15+, r8\n\t"				\
+		"lds.l	@r15+, pr\n\t"				\
+		"ldc.l	@r15+, gbr\n\t"				\
+		: "=z" (__last)					\
+		: "r" (__ts1), "r" (__ts2), "r" (__ts4),	\
+		  "r" (__ts5), "r" (__ts6), "r" (__ts7)		\
+		: "r3", "t");					\
+								\
+	last = __last;						\
+} while (0)
+
+#define finish_arch_switch(prev)				\
+do {								\
+	if (is_dsp_enabled(prev))				\
+		__restore_dsp(prev);				\
 } while (0)
 
 #define __uses_jump_to_uncached \
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7786.h b/arch/sh/include/cpu-sh4/cpu/sh7786.h
index 48688ad..977862f 100644
--- a/arch/sh/include/cpu-sh4/cpu/sh7786.h
+++ b/arch/sh/include/cpu-sh4/cpu/sh7786.h
@@ -51,142 +51,86 @@
 	GPIO_PJ7, GPIO_PJ6, GPIO_PJ5, GPIO_PJ4,
 	GPIO_PJ3, GPIO_PJ2, GPIO_PJ1, GPIO_PJ0,
 
-	GPIO_FN_CDE,
-	GPIO_FN_ETH_MAGIC,
-	GPIO_FN_DISP,
-	GPIO_FN_ETH_LINK,
-	GPIO_FN_DR5,
-	GPIO_FN_ETH_TX_ER,
-	GPIO_FN_DR4,
-	GPIO_FN_ETH_TX_EN,
-	GPIO_FN_DR3,
-	GPIO_FN_ETH_TXD3,
-	GPIO_FN_DR2,
-	GPIO_FN_ETH_TXD2,
-	GPIO_FN_DR1,
-	GPIO_FN_ETH_TXD1,
-	GPIO_FN_DR0,
-	GPIO_FN_ETH_TXD0,
-	GPIO_FN_VSYNC,
-	GPIO_FN_HSPI_CLK,
-	GPIO_FN_ODDF,
-	GPIO_FN_HSPI_CS,
-	GPIO_FN_DG5,
-	GPIO_FN_ETH_MDIO,
-	GPIO_FN_DG4,
-	GPIO_FN_ETH_RX_CLK,
-	GPIO_FN_DG3,
-	GPIO_FN_ETH_MDC,
-	GPIO_FN_DG2,
-	GPIO_FN_ETH_COL,
-	GPIO_FN_DG1,
-	GPIO_FN_ETH_TX_CLK,
-	GPIO_FN_DG0,
-	GPIO_FN_ETH_CRS,
-	GPIO_FN_DCLKIN,
-	GPIO_FN_HSPI_RX,
-	GPIO_FN_HSYNC,
-	GPIO_FN_HSPI_TX,
-	GPIO_FN_DB5,
-	GPIO_FN_ETH_RXD3,
-	GPIO_FN_DB4,
-	GPIO_FN_ETH_RXD2,
-	GPIO_FN_DB3,
-	GPIO_FN_ETH_RXD1,
-	GPIO_FN_DB2,
-	GPIO_FN_ETH_RXD0,
-	GPIO_FN_DB1,
-	GPIO_FN_ETH_RX_DV,
-	GPIO_FN_DB0,
-	GPIO_FN_ETH_RX_ER,
-	GPIO_FN_DCLKOUT,
-	GPIO_FN_SCIF1_SLK,
-	GPIO_FN_SCIF1_RXD,
-	GPIO_FN_SCIF1_TXD,
-	GPIO_FN_DACK1,
-	GPIO_FN_BACK,
-	GPIO_FN_FALE,
-	GPIO_FN_DACK0,
-	GPIO_FN_FCLE,
-	GPIO_FN_DREQ1,
-	GPIO_FN_BREQ,
-	GPIO_FN_USB_OVC1,
-	GPIO_FN_DREQ0,
-	GPIO_FN_USB_OVC0,
-	GPIO_FN_USB_PENC1,
-	GPIO_FN_USB_PENC0,
-	GPIO_FN_HAC1_SDOUT,
-	GPIO_FN_SSI1_SDATA,
-	GPIO_FN_SDIF1CMD,
-	GPIO_FN_HAC1_SDIN,
-	GPIO_FN_SSI1_SCK,
-	GPIO_FN_SDIF1CD,
-	GPIO_FN_HAC1_SYNC,
-	GPIO_FN_SSI1_WS,
-	GPIO_FN_SDIF1WP,
-	GPIO_FN_HAC1_BITCLK,
-	GPIO_FN_SSI1_CLK,
-	GPIO_FN_SDIF1CLK,
-	GPIO_FN_HAC0_SDOUT,
-	GPIO_FN_SSI0_SDATA,
-	GPIO_FN_SDIF1D3,
-	GPIO_FN_HAC0_SDIN,
-	GPIO_FN_SSI0_SCK,
-	GPIO_FN_SDIF1D2,
-	GPIO_FN_HAC0_SYNC,
-	GPIO_FN_SSI0_WS,
-	GPIO_FN_SDIF1D1,
-	GPIO_FN_HAC0_BITCLK,
-	GPIO_FN_SSI0_CLK,
-	GPIO_FN_SDIF1D0,
-	GPIO_FN_SCIF3_SCK,
-	GPIO_FN_SSI2_SDATA,
-	GPIO_FN_SCIF3_RXD,
-	GPIO_FN_TCLK,
-	GPIO_FN_SSI2_SCK,
-	GPIO_FN_SCIF3_TXD,
+	/* DU */
+	GPIO_FN_DCLKIN, GPIO_FN_DCLKOUT, GPIO_FN_ODDF,
+	GPIO_FN_VSYNC, GPIO_FN_HSYNC, GPIO_FN_CDE, GPIO_FN_DISP,
+	GPIO_FN_DR0, GPIO_FN_DG0, GPIO_FN_DB0,
+	GPIO_FN_DR1, GPIO_FN_DG1, GPIO_FN_DB1,
+	GPIO_FN_DR2, GPIO_FN_DG2, GPIO_FN_DB2,
+	GPIO_FN_DR3, GPIO_FN_DG3, GPIO_FN_DB3,
+	GPIO_FN_DR4, GPIO_FN_DG4, GPIO_FN_DB4,
+	GPIO_FN_DR5, GPIO_FN_DG5, GPIO_FN_DB5,
+
+	/* Eth */
+	GPIO_FN_ETH_MAGIC, GPIO_FN_ETH_LINK, GPIO_FN_ETH_TX_ER,
+	GPIO_FN_ETH_TX_EN, GPIO_FN_ETH_MDIO, GPIO_FN_ETH_RX_CLK,
+	GPIO_FN_ETH_MDC, GPIO_FN_ETH_COL, GPIO_FN_ETH_TX_CLK,
+	GPIO_FN_ETH_CRS, GPIO_FN_ETH_RX_DV, GPIO_FN_ETH_RX_ER,
+	GPIO_FN_ETH_TXD3, GPIO_FN_ETH_TXD2, GPIO_FN_ETH_TXD1, GPIO_FN_ETH_TXD0,
+	GPIO_FN_ETH_RXD3, GPIO_FN_ETH_RXD2, GPIO_FN_ETH_RXD1, GPIO_FN_ETH_RXD0,
+
+	/* HSPI */
+	GPIO_FN_HSPI_CLK, GPIO_FN_HSPI_CS, GPIO_FN_HSPI_RX, GPIO_FN_HSPI_TX,
+
+	/* SCIF0 */
+	GPIO_FN_SCIF0_CTS, GPIO_FN_SCIF0_RTS, GPIO_FN_SCIF0_SCK,
+	GPIO_FN_SCIF0_RXD, GPIO_FN_SCIF0_TXD,
+
+	/* SCIF1 */
+	GPIO_FN_SCIF1_SCK, GPIO_FN_SCIF1_RXD, GPIO_FN_SCIF1_TXD,
+
+	/* SCIF3 */
+	GPIO_FN_SCIF3_SCK, GPIO_FN_SCIF3_RXD, GPIO_FN_SCIF3_TXD,
+
+	/* SCIF4 */
+	GPIO_FN_SCIF4_SCK, GPIO_FN_SCIF4_RXD, GPIO_FN_SCIF4_TXD,
+
+	/* SCIF5 */
+	GPIO_FN_SCIF5_SCK, GPIO_FN_SCIF5_RXD, GPIO_FN_SCIF5_TXD,
+
+	/* LBSC */
+	GPIO_FN_BREQ, GPIO_FN_IOIS16, GPIO_FN_CE2B, GPIO_FN_CE2A, GPIO_FN_BACK,
+
+	/* FLCTL */
+	GPIO_FN_FALE, GPIO_FN_FRB, GPIO_FN_FSTATUS,
+	GPIO_FN_FSE, GPIO_FN_FCLE,
+
+	/* DMAC */
+	GPIO_FN_DACK0, GPIO_FN_DREQ0, GPIO_FN_DRAK0,
+	GPIO_FN_DACK1, GPIO_FN_DREQ1, GPIO_FN_DRAK1,
+	GPIO_FN_DACK2, GPIO_FN_DREQ2, GPIO_FN_DRAK2,
+	GPIO_FN_DACK3, GPIO_FN_DREQ3, GPIO_FN_DRAK3,
+
+	/* USB */
+	GPIO_FN_USB_OVC0, GPIO_FN_USB_PENC0,
+	GPIO_FN_USB_OVC1, GPIO_FN_USB_PENC1,
+
+	/* HAC */
 	GPIO_FN_HAC_RES,
-	GPIO_FN_SSI2_WS,
-	GPIO_FN_DACK3,
-	GPIO_FN_SDIF0CMD,
-	GPIO_FN_DACK2,
-	GPIO_FN_SDIF0CD,
-	GPIO_FN_DREQ3,
-	GPIO_FN_SDIF0WP,
-	GPIO_FN_SCIF0_CTS,
-	GPIO_FN_DREQ2,
-	GPIO_FN_SDIF0CLK,
-	GPIO_FN_SCIF0_RTS,
-	GPIO_FN_IRL7,
-	GPIO_FN_SDIF0D3,
-	GPIO_FN_SCIF0_SCK,
-	GPIO_FN_IRL6,
-	GPIO_FN_SDIF0D2,
-	GPIO_FN_SCIF0_RXD,
-	GPIO_FN_IRL5,
-	GPIO_FN_SDIF0D1,
-	GPIO_FN_SCIF0_TXD,
-	GPIO_FN_IRL4,
-	GPIO_FN_SDIF0D0,
-	GPIO_FN_SCIF5_SCK,
-	GPIO_FN_FRB,
-	GPIO_FN_SCIF5_RXD,
-	GPIO_FN_IOIS16,
-	GPIO_FN_SCIF5_TXD,
-	GPIO_FN_CE2B,
-	GPIO_FN_DRAK3,
-	GPIO_FN_CE2A,
-	GPIO_FN_SCIF4_SCK,
-	GPIO_FN_DRAK2,
-	GPIO_FN_SSI3_WS,
-	GPIO_FN_SCIF4_RXD,
-	GPIO_FN_DRAK1,
-	GPIO_FN_SSI3_SDATA,
-	GPIO_FN_FSTATUS,
-	GPIO_FN_SCIF4_TXD,
-	GPIO_FN_DRAK0,
-	GPIO_FN_SSI3_SCK,
-	GPIO_FN_FSE,
+	GPIO_FN_HAC0_SDOUT, GPIO_FN_HAC0_SDIN,
+	GPIO_FN_HAC0_SYNC, GPIO_FN_HAC0_BITCLK,
+	GPIO_FN_HAC1_SDOUT, GPIO_FN_HAC1_SDIN,
+	GPIO_FN_HAC1_SYNC, GPIO_FN_HAC1_BITCLK,
+
+	/* SSI */
+	GPIO_FN_SSI0_SDATA, GPIO_FN_SSI0_SCK, GPIO_FN_SSI0_WS, GPIO_FN_SSI0_CLK,
+	GPIO_FN_SSI1_SDATA, GPIO_FN_SSI1_SCK, GPIO_FN_SSI1_WS, GPIO_FN_SSI1_CLK,
+	GPIO_FN_SSI2_SDATA, GPIO_FN_SSI2_SCK, GPIO_FN_SSI2_WS,
+	GPIO_FN_SSI3_SDATA, GPIO_FN_SSI3_SCK, GPIO_FN_SSI3_WS,
+
+	/* SDIF1 */
+	GPIO_FN_SDIF1CMD, GPIO_FN_SDIF1CD, GPIO_FN_SDIF1WP, GPIO_FN_SDIF1CLK,
+	GPIO_FN_SDIF1D3, GPIO_FN_SDIF1D2, GPIO_FN_SDIF1D1, GPIO_FN_SDIF1D0,
+
+	/* SDIF0 */
+	GPIO_FN_SDIF0CMD, GPIO_FN_SDIF0CD, GPIO_FN_SDIF0WP, GPIO_FN_SDIF0CLK,
+	GPIO_FN_SDIF0D3, GPIO_FN_SDIF0D2, GPIO_FN_SDIF0D1, GPIO_FN_SDIF0D0,
+
+	/* TMU */
+	GPIO_FN_TCLK,
+
+	/* INTC */
+	GPIO_FN_IRL7, GPIO_FN_IRL6, GPIO_FN_IRL5, GPIO_FN_IRL4,
 };
 
 #endif /* __CPU_SH7786_H__ */
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S
index 55da0ff..3cb531f 100644
--- a/arch/sh/kernel/cpu/sh3/entry.S
+++ b/arch/sh/kernel/cpu/sh3/entry.S
@@ -254,40 +254,6 @@
 
 	lds	k2, pr			! restore pr
 	!
-#ifdef CONFIG_SH_DSP
-	mov.l	@r15+, k0		! DSP mode marker
-	mov.l	5f, k1
-	cmp/eq	k0, k1			! Do we have a DSP stack frame?
-	bf	skip_restore
-
-	stc	sr, k0			! Enable CPU DSP mode
-	or	k1, k0			! (within kernel it may be disabled)
-	ldc	k0, sr
-	mov	r2, k0			! Backup r2
-
-	! Restore DSP registers from stack
-	mov	r15, r2
-	movs.l	@r2+, a1
-	movs.l	@r2+, a0g
-	movs.l	@r2+, a1g
-	movs.l	@r2+, m0
-	movs.l	@r2+, m1
-	mov	r2, r15
-
-	lds.l	@r15+, a0
-	lds.l	@r15+, x0
-	lds.l	@r15+, x1
-	lds.l	@r15+, y0
-	lds.l	@r15+, y1
-	lds.l	@r15+, dsr
-	ldc.l	@r15+, rs
-	ldc.l	@r15+, re
-	ldc.l	@r15+, mod
-
-	mov	k0, r2			! Restore r2
-skip_restore:
-#endif
-	!
 	! Calculate new SR value
 	mov	k3, k2			! original SR value
 	mov	#0xf0, k1
@@ -358,7 +324,7 @@
 	add	k0, k4
 0:
 	! Setup stack and save DSP context (k0 contains original r15 on return)
-	bsr	prepare_stack_save_dsp
+	bsr	prepare_stack
 	 nop
 
 	! Save registers / Switch to bank 0
@@ -374,15 +340,14 @@
 1:	.long	EXPEVT
 #endif
 
-! prepare_stack_save_dsp()
+! prepare_stack()
 ! - roll back gRB
 ! - switch to kernel stack
-! - save DSP
 ! k0 returns original sp (after roll back)
 ! k1 trashed
 ! k2 trashed
 
-prepare_stack_save_dsp:
+prepare_stack:
 #ifdef CONFIG_GUSA
 	! Check for roll back gRB (User and Kernel)
 	mov	r15, k0
@@ -416,47 +381,9 @@
 	mov	k1, r15		! change to kernel stack
 	!
 1:
-#ifdef CONFIG_SH_DSP
-	! Save DSP context if needed
-	stc	sr, k1
-	mov	#0x10, k2
-	shll8   k2			! DSP=1 (0x00001000)
-	tst	k2, k1			! Check if in DSP mode (passed in k2)
-	bt/s	skip_save
-	 mov	#0, k1			! Set marker for no stack frame
-
-	mov	k2, k1			! Save has-frame marker
-
-	! Save DSP registers on stack
-	stc.l	mod, @-r15
-	stc.l	re, @-r15
-	stc.l	rs, @-r15
-	sts.l	dsr, @-r15
-	sts.l	y1, @-r15
-	sts.l	y0, @-r15
-	sts.l	x1, @-r15
-	sts.l	x0, @-r15
-	sts.l	a0, @-r15
-
-	! GAS is broken, does not generate correct "movs.l Ds,@-As" instr.
-
-	! FIXME: Make sure that this is still the case with newer toolchains,
-	! as we're not at all interested in supporting ancient toolchains at
-	! this point. -- PFM.
-
-	mov	r15, k2
-	.word	0xf653			! movs.l	a1, @-r2
-	.word	0xf6f3			! movs.l	a0g, @-r2
-	.word	0xf6d3			! movs.l	a1g, @-r2
-	.word	0xf6c3			! movs.l	m0, @-r2
-	.word	0xf6e3			! movs.l	m1, @-r2
-	mov	k2, r15
-
-skip_save:
-	mov.l	k1, @-r15		! Push DSP mode marker onto stack
-#endif
 	rts
 	 nop
+
 !
 ! 0x400: Instruction and Data TLB miss exception vector
 !
@@ -468,7 +395,7 @@
 	mova	exception_data, k0
 
 	! Setup stack and save DSP context (k0 contains original r15 on return)
-	bsr	prepare_stack_save_dsp
+	bsr	prepare_stack
 	 PREF(k0)
 
 	! Save registers / Switch to bank 0
@@ -572,7 +499,7 @@
 	mova	exception_data, k0
 
 	! Setup stack and save DSP context (k0 contains original r15 on return)
-	bsr	prepare_stack_save_dsp
+	bsr	prepare_stack
 	 PREF(k0)
 
 	! Save registers / Switch to bank 0
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
index 3d3a3c4..91e3677 100644
--- a/arch/sh/kernel/cpu/sh4/probe.c
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -199,11 +199,6 @@
 		break;
 	}
 
-#ifdef CONFIG_SH_DIRECT_MAPPED
-	boot_cpu_data.icache.ways = 1;
-	boot_cpu_data.dcache.ways = 1;
-#endif
-
 #ifdef CONFIG_CPU_HAS_PTEA
 	boot_cpu_data.flags |= CPU_HAS_PTEA;
 #endif
diff --git a/arch/sh/kernel/cpu/sh4a/pinmux-sh7786.c b/arch/sh/kernel/cpu/sh4a/pinmux-sh7786.c
index 373b344..4229e07 100644
--- a/arch/sh/kernel/cpu/sh4a/pinmux-sh7786.c
+++ b/arch/sh/kernel/cpu/sh4a/pinmux-sh7786.c
@@ -149,150 +149,44 @@
 	PINMUX_FUNCTION_END,
 
 	PINMUX_MARK_BEGIN,
-	CDE_MARK,
-	ETH_MAGIC_MARK,
-	DISP_MARK,
-	ETH_LINK_MARK,
-	DR5_MARK,
-	ETH_TX_ER_MARK,
-	DR4_MARK,
-	ETH_TX_EN_MARK,
-	DR3_MARK,
-	ETH_TXD3_MARK,
-	DR2_MARK,
-	ETH_TXD2_MARK,
-	DR1_MARK,
-	ETH_TXD1_MARK,
-	DR0_MARK,
-	ETH_TXD0_MARK,
-
-	VSYNC_MARK,
-	HSPI_CLK_MARK,
-	ODDF_MARK,
-	HSPI_CS_MARK,
-	DG5_MARK,
-	ETH_MDIO_MARK,
-	DG4_MARK,
-	ETH_RX_CLK_MARK,
-	DG3_MARK,
-	ETH_MDC_MARK,
-	DG2_MARK,
-	ETH_COL_MARK,
-	DG1_MARK,
-	ETH_TX_CLK_MARK,
-	DG0_MARK,
-	ETH_CRS_MARK,
-
-	DCLKIN_MARK,
-	HSPI_RX_MARK,
-	HSYNC_MARK,
-	HSPI_TX_MARK,
-	DB5_MARK,
-	ETH_RXD3_MARK,
-	DB4_MARK,
-	ETH_RXD2_MARK,
-	DB3_MARK,
-	ETH_RXD1_MARK,
-	DB2_MARK,
-	ETH_RXD0_MARK,
-	DB1_MARK,
-	ETH_RX_DV_MARK,
-	DB0_MARK,
-	ETH_RX_ER_MARK,
-
-	DCLKOUT_MARK,
-	SCIF1_SLK_MARK,
-	SCIF1_RXD_MARK,
-	SCIF1_TXD_MARK,
-	DACK1_MARK,
-	BACK_MARK,
-	FALE_MARK,
-	DACK0_MARK,
-	FCLE_MARK,
-	DREQ1_MARK,
-	BREQ_MARK,
-	USB_OVC1_MARK,
-	DREQ0_MARK,
-	USB_OVC0_MARK,
-
-	USB_PENC1_MARK,
-	USB_PENC0_MARK,
-
-	HAC1_SDOUT_MARK,
-	SSI1_SDATA_MARK,
-	SDIF1CMD_MARK,
-	HAC1_SDIN_MARK,
-	SSI1_SCK_MARK,
-	SDIF1CD_MARK,
-	HAC1_SYNC_MARK,
-	SSI1_WS_MARK,
-	SDIF1WP_MARK,
-	HAC1_BITCLK_MARK,
-	SSI1_CLK_MARK,
-	SDIF1CLK_MARK,
-	HAC0_SDOUT_MARK,
-	SSI0_SDATA_MARK,
-	SDIF1D3_MARK,
-	HAC0_SDIN_MARK,
-	SSI0_SCK_MARK,
-	SDIF1D2_MARK,
-	HAC0_SYNC_MARK,
-	SSI0_WS_MARK,
-	SDIF1D1_MARK,
-	HAC0_BITCLK_MARK,
-	SSI0_CLK_MARK,
-	SDIF1D0_MARK,
-
-	SCIF3_SCK_MARK,
-	SSI2_SDATA_MARK,
-	SCIF3_RXD_MARK,
-	TCLK_MARK,
-	SSI2_SCK_MARK,
-	SCIF3_TXD_MARK,
+	DCLKIN_MARK, DCLKOUT_MARK, ODDF_MARK,
+	VSYNC_MARK, HSYNC_MARK, CDE_MARK, DISP_MARK,
+	DR0_MARK, DR1_MARK, DR2_MARK, DR3_MARK, DR4_MARK, DR5_MARK,
+	DG0_MARK, DG1_MARK, DG2_MARK, DG3_MARK, DG4_MARK, DG5_MARK,
+	DB0_MARK, DB1_MARK, DB2_MARK, DB3_MARK, DB4_MARK, DB5_MARK,
+	ETH_MAGIC_MARK, ETH_LINK_MARK, ETH_TX_ER_MARK, ETH_TX_EN_MARK,
+	ETH_MDIO_MARK, ETH_RX_CLK_MARK, ETH_MDC_MARK, ETH_COL_MARK,
+	ETH_TX_CLK_MARK, ETH_CRS_MARK, ETH_RX_DV_MARK, ETH_RX_ER_MARK,
+	ETH_TXD3_MARK, ETH_TXD2_MARK, ETH_TXD1_MARK, ETH_TXD0_MARK,
+	ETH_RXD3_MARK, ETH_RXD2_MARK, ETH_RXD1_MARK, ETH_RXD0_MARK,
+	HSPI_CLK_MARK, HSPI_CS_MARK, HSPI_RX_MARK, HSPI_TX_MARK,
+	SCIF0_CTS_MARK, SCIF0_RTS_MARK,
+	SCIF0_SCK_MARK, SCIF0_RXD_MARK, SCIF0_TXD_MARK,
+	SCIF1_SCK_MARK, SCIF1_RXD_MARK, SCIF1_TXD_MARK,
+	SCIF3_SCK_MARK, SCIF3_RXD_MARK, SCIF3_TXD_MARK,
+	SCIF4_SCK_MARK, SCIF4_RXD_MARK, SCIF4_TXD_MARK,
+	SCIF5_SCK_MARK, SCIF5_RXD_MARK, SCIF5_TXD_MARK,
+	BREQ_MARK, IOIS16_MARK, CE2B_MARK, CE2A_MARK, BACK_MARK,
+	FALE_MARK, FRB_MARK, FSTATUS_MARK,
+	FSE_MARK, FCLE_MARK,
+	DACK0_MARK, DACK1_MARK, DACK2_MARK, DACK3_MARK,
+	DREQ0_MARK, DREQ1_MARK, DREQ2_MARK, DREQ3_MARK,
+	DRAK0_MARK, DRAK1_MARK, DRAK2_MARK, DRAK3_MARK,
+	USB_OVC1_MARK, USB_OVC0_MARK,
+	USB_PENC1_MARK, USB_PENC0_MARK,
 	HAC_RES_MARK,
-	SSI2_WS_MARK,
-
-	DACK3_MARK,
-	SDIF0CMD_MARK,
-	DACK2_MARK,
-	SDIF0CD_MARK,
-	DREQ3_MARK,
-	SDIF0WP_MARK,
-	SCIF0_CTS_MARK,
-	DREQ2_MARK,
-	SDIF0CLK_MARK,
-	SCIF0_RTS_MARK,
-	IRL7_MARK,
-	SDIF0D3_MARK,
-	SCIF0_SCK_MARK,
-	IRL6_MARK,
-	SDIF0D2_MARK,
-	SCIF0_RXD_MARK,
-	IRL5_MARK,
-	SDIF0D1_MARK,
-	SCIF0_TXD_MARK,
-	IRL4_MARK,
-	SDIF0D0_MARK,
-
-	SCIF5_SCK_MARK,
-	FRB_MARK,
-	SCIF5_RXD_MARK,
-	IOIS16_MARK,
-	SCIF5_TXD_MARK,
-	CE2B_MARK,
-	DRAK3_MARK,
-	CE2A_MARK,
-	SCIF4_SCK_MARK,
-	DRAK2_MARK,
-	SSI3_WS_MARK,
-	SCIF4_RXD_MARK,
-	DRAK1_MARK,
-	SSI3_SDATA_MARK,
-	FSTATUS_MARK,
-	SCIF4_TXD_MARK,
-	DRAK0_MARK,
-	SSI3_SCK_MARK,
-	FSE_MARK,
+	HAC1_SDOUT_MARK, HAC1_SDIN_MARK, HAC1_SYNC_MARK, HAC1_BITCLK_MARK,
+	HAC0_SDOUT_MARK, HAC0_SDIN_MARK, HAC0_SYNC_MARK, HAC0_BITCLK_MARK,
+	SSI0_SDATA_MARK, SSI0_SCK_MARK, SSI0_WS_MARK, SSI0_CLK_MARK,
+	SSI1_SDATA_MARK, SSI1_SCK_MARK, SSI1_WS_MARK, SSI1_CLK_MARK,
+	SSI2_SDATA_MARK, SSI2_SCK_MARK, SSI2_WS_MARK,
+	SSI3_SDATA_MARK, SSI3_SCK_MARK, SSI3_WS_MARK,
+	SDIF1CMD_MARK, SDIF1CD_MARK, SDIF1WP_MARK, SDIF1CLK_MARK,
+	SDIF1D3_MARK, SDIF1D2_MARK, SDIF1D1_MARK, SDIF1D0_MARK,
+	SDIF0CMD_MARK, SDIF0CD_MARK, SDIF0WP_MARK, SDIF0CLK_MARK,
+	SDIF0D3_MARK, SDIF0D2_MARK, SDIF0D1_MARK, SDIF0D0_MARK,
+	TCLK_MARK,
+	IRL7_MARK, IRL6_MARK, IRL5_MARK, IRL4_MARK,
 	PINMUX_MARK_END,
 };
 
@@ -377,7 +271,6 @@
 	PINMUX_DATA(PJ1_DATA, PJ1_IN, PJ1_OUT, PJ1_IN_PU),
 
 	/* PA FN */
-	PINMUX_MARK_BEGIN,
 	PINMUX_DATA(CDE_MARK,		P1MSEL2_0, PA7_FN),
 	PINMUX_DATA(DISP_MARK,		P1MSEL2_0, PA6_FN),
 	PINMUX_DATA(DR5_MARK,		P1MSEL2_0, PA5_FN),
@@ -434,7 +327,7 @@
 
 	/* PD FN */
 	PINMUX_DATA(DCLKOUT_MARK,	PD7_FN),
-	PINMUX_DATA(SCIF1_SLK_MARK,	PD6_FN),
+	PINMUX_DATA(SCIF1_SCK_MARK,	PD6_FN),
 	PINMUX_DATA(SCIF1_RXD_MARK,	PD5_FN),
 	PINMUX_DATA(SCIF1_TXD_MARK,	PD4_FN),
 	PINMUX_DATA(DACK1_MARK,		P1MSEL13_1, P1MSEL12_0, PD3_FN),
@@ -662,7 +555,7 @@
 	PINMUX_GPIO(GPIO_FN_DB0,		DB0_MARK),
 	PINMUX_GPIO(GPIO_FN_ETH_RX_ER,		ETH_RX_ER_MARK),
 	PINMUX_GPIO(GPIO_FN_DCLKOUT,		DCLKOUT_MARK),
-	PINMUX_GPIO(GPIO_FN_SCIF1_SLK,		SCIF1_SLK_MARK),
+	PINMUX_GPIO(GPIO_FN_SCIF1_SCK,		SCIF1_SCK_MARK),
 	PINMUX_GPIO(GPIO_FN_SCIF1_RXD,		SCIF1_RXD_MARK),
 	PINMUX_GPIO(GPIO_FN_SCIF1_TXD,		SCIF1_TXD_MARK),
 	PINMUX_GPIO(GPIO_FN_DACK1,		DACK1_MARK),
diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c
index fe59ccf..f35ed03 100644
--- a/arch/sh/kernel/idle.c
+++ b/arch/sh/kernel/idle.c
@@ -38,7 +38,7 @@
 }
 __setup("hlt", hlt_setup);
 
-static void default_idle(void)
+void default_idle(void)
 {
 	if (!hlt_counter) {
 		clear_thread_flag(TIF_POLLING_NRFLAG);
diff --git a/arch/sh/kernel/io_trapped.c b/arch/sh/kernel/io_trapped.c
index 39cd7f3..c22853b 100644
--- a/arch/sh/kernel/io_trapped.c
+++ b/arch/sh/kernel/io_trapped.c
@@ -14,6 +14,7 @@
 #include <linux/bitops.h>
 #include <linux/vmalloc.h>
 #include <linux/module.h>
+#include <linux/init.h>
 #include <asm/system.h>
 #include <asm/mmu_context.h>
 #include <asm/uaccess.h>
@@ -32,6 +33,15 @@
 #endif
 static DEFINE_SPINLOCK(trapped_lock);
 
+static int trapped_io_disable __read_mostly;
+
+static int __init trapped_io_setup(char *__unused)
+{
+	trapped_io_disable = 1;
+	return 1;
+}
+__setup("noiotrap", trapped_io_setup);
+
 int register_trapped_io(struct trapped_io *tiop)
 {
 	struct resource *res;
@@ -39,6 +49,9 @@
 	struct page *pages[TRAPPED_PAGES_MAX];
 	int k, n;
 
+	if (unlikely(trapped_io_disable))
+		return 0;
+
 	/* structure must be page aligned */
 	if ((unsigned long)tiop & (PAGE_SIZE - 1))
 		goto bad;
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c
index 694bc15..6d94725 100644
--- a/arch/sh/kernel/process_32.c
+++ b/arch/sh/kernel/process_32.c
@@ -176,14 +176,26 @@
 {
 	struct thread_info *ti = task_thread_info(p);
 	struct pt_regs *childregs;
-#if defined(CONFIG_SH_FPU)
+#if defined(CONFIG_SH_FPU) || defined(CONFIG_SH_DSP)
 	struct task_struct *tsk = current;
+#endif
 
+#if defined(CONFIG_SH_FPU)
 	unlazy_fpu(tsk, regs);
 	p->thread.fpu = tsk->thread.fpu;
 	copy_to_stopped_child_used_math(p);
 #endif
 
+#if defined(CONFIG_SH_DSP)
+	if (is_dsp_enabled(tsk)) {
+		/* We can use the __save_dsp or just copy the struct:
+		 * __save_dsp(p);
+		 * p->thread.dsp_status.status |= SR_DSP
+		 */
+		p->thread.dsp_status = tsk->thread.dsp_status;
+	}
+#endif
+
 	childregs = task_pt_regs(p);
 	*childregs = *regs;
 
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c
index 29ca09d..f7b22dd 100644
--- a/arch/sh/kernel/ptrace_32.c
+++ b/arch/sh/kernel/ptrace_32.c
@@ -200,7 +200,8 @@
 		       unsigned int pos, unsigned int count,
 		       void *kbuf, void __user *ubuf)
 {
-	const struct pt_dspregs *regs = task_pt_dspregs(target);
+	const struct pt_dspregs *regs =
+		(struct pt_dspregs *)&target->thread.dsp_status.dsp_regs;
 	int ret;
 
 	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, regs,
@@ -217,7 +218,8 @@
 		       unsigned int pos, unsigned int count,
 		       const void *kbuf, const void __user *ubuf)
 {
-	struct pt_dspregs *regs = task_pt_dspregs(target);
+	struct pt_dspregs *regs =
+		(struct pt_dspregs *)&target->thread.dsp_status.dsp_regs;
 	int ret;
 
 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, regs,
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 24c6025..04a6004 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -103,12 +103,11 @@
 	size = memparse(p, &p);
 
 	if (size > __MEMORY_SIZE) {
-		static char msg[] __initdata = KERN_ERR
+		printk(KERN_ERR
 			"Using mem= to increase the size of kernel memory "
 			"is not allowed.\n"
 			"  Recompile the kernel with the correct value for "
-			"CONFIG_MEMORY_SIZE.\n";
-		printk(msg);
+			"CONFIG_MEMORY_SIZE.\n");
 		return 0;
 	}
 
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index 60dcf87..30ca9c5 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -664,6 +664,8 @@
 	if (is_dsp_inst(regs)) {
 		/* Enable DSP mode, and restart instruction. */
 		regs->sr |= SR_DSP;
+		/* Save DSP mode */
+		tsk->thread.dsp_status.status |= SR_DSP;
 		return;
 	}
 #endif
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
index 10c2435..d4079ca 100644
--- a/arch/sh/mm/Kconfig
+++ b/arch/sh/mm/Kconfig
@@ -251,18 +251,6 @@
 	depends on CPU_SUBTYPE_SH7705
 	default y
 
-config SH_DIRECT_MAPPED
-	bool "Use direct-mapped caching"
-	default n
-	help
-	  Selecting this option will configure the caches to be direct-mapped,
-	  even if the cache supports a 2 or 4-way mode. This is useful primarily
-	  for debugging on platforms with 2 and 4-way caches (SH7750R/SH7751R,
-	  SH4-202, SH4-501, etc.)
-
-	  Turn this option off for platforms that do not have a direct-mapped
-	  cache, and you have no need to run the caches in such a configuration.
-
 choice
 	prompt "Cache mode"
 	default CACHE_WRITEBACK if CPU_SH2A || CPU_SH3 || CPU_SH4 || CPU_SH5
diff --git a/arch/sparc/include/asm/mmzone.h b/arch/sparc/include/asm/mmzone.h
index ebf5986..e8c6487 100644
--- a/arch/sparc/include/asm/mmzone.h
+++ b/arch/sparc/include/asm/mmzone.h
@@ -3,6 +3,8 @@
 
 #ifdef CONFIG_NEED_MULTIPLE_NODES
 
+#include <linux/cpumask.h>
+
 extern struct pglist_data *node_data[];
 
 #define NODE_DATA(nid)		(node_data[nid])
diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S
index a46c3a2..3a1b7bf 100644
--- a/arch/sparc/kernel/head_64.S
+++ b/arch/sparc/kernel/head_64.S
@@ -686,7 +686,7 @@
 	 * point.
 	 *
 	 * There used to be enormous complexity wrt. transferring
-	 * over from the firwmare's trap table to the Linux kernel's.
+	 * over from the firmware's trap table to the Linux kernel's.
 	 * For example, there was a chicken & egg problem wrt. building
 	 * the OBP page tables, yet needing to be on the Linux kernel
 	 * trap table (to translate PAGE_OFFSET addresses) in order to
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index d42f826..f934225 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -22,6 +22,7 @@
 #include "linux/kernel.h"
 #include "linux/module.h"
 #include "linux/blkdev.h"
+#include "linux/ata.h"
 #include "linux/hdreg.h"
 #include "linux/init.h"
 #include "linux/cdrom.h"
@@ -1308,16 +1309,15 @@
 		     unsigned int cmd, unsigned long arg)
 {
 	struct ubd *ubd_dev = bdev->bd_disk->private_data;
-	struct hd_driveid ubd_id = {
-		.cyls		= 0,
-		.heads		= 128,
-		.sectors	= 32,
-	};
+	u16 ubd_id[ATA_ID_WORDS];
 
 	switch (cmd) {
 		struct cdrom_volctrl volume;
 	case HDIO_GET_IDENTITY:
-		ubd_id.cyls = ubd_dev->size / (128 * 32 * 512);
+		memset(&ubd_id, 0, ATA_ID_WORDS * 2);
+		ubd_id[ATA_ID_CYLS]	= ubd_dev->size / (128 * 32 * 512);
+		ubd_id[ATA_ID_HEADS]	= 128;
+		ubd_id[ATA_ID_SECTORS]	= 32;
 		if(copy_to_user((char __user *) arg, (char *) &ubd_id,
 				 sizeof(ubd_id)))
 			return -EFAULT;
diff --git a/arch/um/include/asm/ftrace.h b/arch/um/include/asm/ftrace.h
new file mode 100644
index 0000000..40a8c17
--- /dev/null
+++ b/arch/um/include/asm/ftrace.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 748e50a..5b2196a 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -34,6 +34,8 @@
 	select HAVE_FUNCTION_TRACER
 	select HAVE_FUNCTION_GRAPH_TRACER
 	select HAVE_FUNCTION_TRACE_MCOUNT_TEST
+	select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE
+	select HAVE_FTRACE_SYSCALLS
 	select HAVE_KVM
 	select HAVE_ARCH_KGDB
 	select HAVE_ARCH_TRACEHOOK
@@ -1144,7 +1146,7 @@
 	depends on NEED_MULTIPLE_NODES
 	---help---
 	  Specify the maximum number of NUMA Nodes available on the target
-	  system.  Increases memory reserved to accomodate various tables.
+	  system.  Increases memory reserved to accommodate various tables.
 
 config HAVE_ARCH_BOOTMEM
 	def_bool y
@@ -1322,7 +1324,7 @@
 	  add writeback entries.
 
 	  Can be disabled with disable_mtrr_cleanup on the kernel command line.
-	  The largest mtrr entry size for a continous block can be set with
+	  The largest mtrr entry size for a continuous block can be set with
 	  mtrr_chunk_size.
 
 	  If unsure, say Y.
@@ -1837,8 +1839,8 @@
 
 config DMAR
 	bool "Support for DMA Remapping Devices (EXPERIMENTAL)"
-	depends on X86_64 && PCI_MSI && ACPI && EXPERIMENTAL
-	---help---
+	depends on PCI_MSI && ACPI && EXPERIMENTAL
+	help
 	  DMA remapping (DMAR) devices support enables independent address
 	  translations for Direct Memory Access (DMA) from devices.
 	  These DMA remapping devices are reported via ACPI tables
diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile
index fb737ce..6633b6e 100644
--- a/arch/x86/boot/Makefile
+++ b/arch/x86/boot/Makefile
@@ -57,6 +57,7 @@
 # How to compile the 16-bit code.  Note we always compile for -march=i386,
 # that way we can complain to the user if the CPU is insufficient.
 KBUILD_CFLAGS	:= $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
+		   -DDISABLE_BRANCH_PROFILING \
 		   -Wall -Wstrict-prototypes \
 		   -march=i386 -mregparm=3 \
 		   -include $(srctree)/$(src)/code16gcc.h \
@@ -66,7 +67,7 @@
 			$(call cc-option, -fno-unit-at-a-time)) \
 		   $(call cc-option, -fno-stack-protector) \
 		   $(call cc-option, -mpreferred-stack-boundary=2)
-KBUILD_CFLAGS +=   $(call cc-option,-m32)
+KBUILD_CFLAGS	+= $(call cc-option, -m32)
 KBUILD_AFLAGS	:= $(KBUILD_CFLAGS) -D__ASSEMBLY__
 
 $(obj)/bzImage: asflags-y  := $(SVGA_MODE)
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index 3ca4c19..65551c9 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -8,6 +8,7 @@
 
 KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2
 KBUILD_CFLAGS += -fno-strict-aliasing -fPIC
+KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
 cflags-$(CONFIG_X86_64) := -mcmodel=small
 KBUILD_CFLAGS += $(cflags-y)
 KBUILD_CFLAGS += $(call cc-option,-ffreestanding)
diff --git a/arch/x86/include/asm/cacheflush.h b/arch/x86/include/asm/cacheflush.h
index b3894bf..e55dfc1 100644
--- a/arch/x86/include/asm/cacheflush.h
+++ b/arch/x86/include/asm/cacheflush.h
@@ -126,6 +126,11 @@
 #ifdef CONFIG_DEBUG_RODATA
 void mark_rodata_ro(void);
 extern const int rodata_test_data;
+void set_kernel_text_rw(void);
+void set_kernel_text_ro(void);
+#else
+static inline void set_kernel_text_rw(void) { }
+static inline void set_kernel_text_ro(void) { }
 #endif
 
 #ifdef CONFIG_DEBUG_RODATA_TEST
diff --git a/arch/x86/include/asm/cpumask.h b/arch/x86/include/asm/cpumask.h
index a7f3c75..61c852f 100644
--- a/arch/x86/include/asm/cpumask.h
+++ b/arch/x86/include/asm/cpumask.h
@@ -3,8 +3,6 @@
 #ifndef __ASSEMBLY__
 #include <linux/cpumask.h>
 
-#ifdef CONFIG_X86_64
-
 extern cpumask_var_t cpu_callin_mask;
 extern cpumask_var_t cpu_callout_mask;
 extern cpumask_var_t cpu_initialized_mask;
@@ -12,21 +10,5 @@
 
 extern void setup_cpu_local_masks(void);
 
-#else /* CONFIG_X86_32 */
-
-extern cpumask_t cpu_callin_map;
-extern cpumask_t cpu_callout_map;
-extern cpumask_t cpu_initialized;
-extern cpumask_t cpu_sibling_setup_map;
-
-#define cpu_callin_mask		((struct cpumask *)&cpu_callin_map)
-#define cpu_callout_mask	((struct cpumask *)&cpu_callout_map)
-#define cpu_initialized_mask	((struct cpumask *)&cpu_initialized)
-#define cpu_sibling_setup_mask	((struct cpumask *)&cpu_sibling_setup_map)
-
-static inline void setup_cpu_local_masks(void) { }
-
-#endif /* CONFIG_X86_32 */
-
 #endif /* __ASSEMBLY__ */
 #endif /* _ASM_X86_CPUMASK_H */
diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h
index 63a79c7..81937a5 100644
--- a/arch/x86/include/asm/fixmap.h
+++ b/arch/x86/include/asm/fixmap.h
@@ -111,6 +111,8 @@
 #ifdef CONFIG_PARAVIRT
 	FIX_PARAVIRT_BOOTMAP,
 #endif
+	FIX_TEXT_POKE0,	/* reserve 2 pages for text_poke() */
+	FIX_TEXT_POKE1,
 	__end_of_permanent_fixed_addresses,
 #ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
 	FIX_OHCI1394_BASE,
diff --git a/arch/x86/include/asm/ftrace.h b/arch/x86/include/asm/ftrace.h
index db24c22..bd2c651 100644
--- a/arch/x86/include/asm/ftrace.h
+++ b/arch/x86/include/asm/ftrace.h
@@ -28,6 +28,13 @@
 
 #endif
 
+/* FIXME: I don't want to stay hardcoded */
+#ifdef CONFIG_X86_64
+# define FTRACE_SYSCALL_MAX     296
+#else
+# define FTRACE_SYSCALL_MAX     333
+#endif
+
 #ifdef CONFIG_FUNCTION_TRACER
 #define MCOUNT_ADDR		((long)(mcount))
 #define MCOUNT_INSN_SIZE	5 /* sizeof mcount call */
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index a0301bf..b51a1e8 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -89,12 +89,40 @@
 /* MSI arch hook */
 #define arch_setup_msi_irqs arch_setup_msi_irqs
 
+#define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
+
+#if defined(CONFIG_X86_64) || defined(CONFIG_DMA_API_DEBUG)
+
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)       \
+	        dma_addr_t ADDR_NAME;
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)         \
+	        __u32 LEN_NAME;
+#define pci_unmap_addr(PTR, ADDR_NAME)                  \
+	        ((PTR)->ADDR_NAME)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)         \
+	        (((PTR)->ADDR_NAME) = (VAL))
+#define pci_unmap_len(PTR, LEN_NAME)                    \
+	        ((PTR)->LEN_NAME)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL)           \
+	        (((PTR)->LEN_NAME) = (VAL))
+
+#else
+
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)       dma_addr_t ADDR_NAME[0];
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) unsigned LEN_NAME[0];
+#define pci_unmap_addr(PTR, ADDR_NAME)  sizeof((PTR)->ADDR_NAME)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
+	        do { break; } while (pci_unmap_addr(PTR, ADDR_NAME))
+#define pci_unmap_len(PTR, LEN_NAME)            sizeof((PTR)->LEN_NAME)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
+	        do { break; } while (pci_unmap_len(PTR, LEN_NAME))
+
+#endif
+
 #endif  /* __KERNEL__ */
 
-#ifdef CONFIG_X86_32
-# include "pci_32.h"
-#else
-# include "pci_64.h"
+#ifdef CONFIG_X86_64
+#include "pci_64.h"
 #endif
 
 /* implement the pci_ DMA API in terms of the generic device dma_ one */
@@ -112,11 +140,6 @@
 	return sd->node;
 }
 
-static inline cpumask_t __pcibus_to_cpumask(struct pci_bus *bus)
-{
-	return node_to_cpumask(__pcibus_to_node(bus));
-}
-
 static inline const struct cpumask *
 cpumask_of_pcibus(const struct pci_bus *bus)
 {
diff --git a/arch/x86/include/asm/pci_32.h b/arch/x86/include/asm/pci_32.h
deleted file mode 100644
index 6f1213a..0000000
--- a/arch/x86/include/asm/pci_32.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef _ASM_X86_PCI_32_H
-#define _ASM_X86_PCI_32_H
-
-
-#ifdef __KERNEL__
-
-
-/* Dynamic DMA mapping stuff.
- * i386 has everything mapped statically.
- */
-
-struct pci_dev;
-
-/* The PCI address space does equal the physical memory
- * address space.  The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS	(1)
-
-/* pci_unmap_{page,single} is a nop so... */
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)	dma_addr_t ADDR_NAME[0];
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)	unsigned LEN_NAME[0];
-#define pci_unmap_addr(PTR, ADDR_NAME)	sizeof((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
-	do { break; } while (pci_unmap_addr(PTR, ADDR_NAME))
-#define pci_unmap_len(PTR, LEN_NAME)		sizeof((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
-	do { break; } while (pci_unmap_len(PTR, LEN_NAME))
-
-
-#endif /* __KERNEL__ */
-
-
-#endif /* _ASM_X86_PCI_32_H */
diff --git a/arch/x86/include/asm/pci_64.h b/arch/x86/include/asm/pci_64.h
index 4da2079..ae5e40f 100644
--- a/arch/x86/include/asm/pci_64.h
+++ b/arch/x86/include/asm/pci_64.h
@@ -24,28 +24,6 @@
 
 extern void dma32_reserve_bootmem(void);
 
-/* The PCI address space does equal the physical memory
- * address space.  The networking and block device layers use
- * this boolean for bounce buffer decisions
- *
- * On AMD64 it mostly equals, but we set it to zero if a hardware
- * IOMMU (gart) of sotware IOMMU (swiotlb) is available.
- */
-#define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
-
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)	\
-	dma_addr_t ADDR_NAME;
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)		\
-	__u32 LEN_NAME;
-#define pci_unmap_addr(PTR, ADDR_NAME)			\
-	((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)		\
-	(((PTR)->ADDR_NAME) = (VAL))
-#define pci_unmap_len(PTR, LEN_NAME)			\
-	((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL)		\
-	(((PTR)->LEN_NAME) = (VAL))
-
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_X86_PCI_64_H */
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index ae85a8d..34c5237 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -94,7 +94,7 @@
 	unsigned long		loops_per_jiffy;
 #ifdef CONFIG_SMP
 	/* cpus sharing the last level cache: */
-	cpumask_t		llc_shared_map;
+	cpumask_var_t		llc_shared_map;
 #endif
 	/* cpuid returned max cores value: */
 	u16			 x86_max_cores;
@@ -736,6 +736,7 @@
 extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
 
 extern void select_idle_routine(const struct cpuinfo_x86 *c);
+extern void init_c1e_mask(void);
 
 extern unsigned long		boot_option_idle_override;
 extern unsigned long		idle_halt;
diff --git a/arch/x86/include/asm/ptrace-abi.h b/arch/x86/include/asm/ptrace-abi.h
index 8e0f8d1..8672303 100644
--- a/arch/x86/include/asm/ptrace-abi.h
+++ b/arch/x86/include/asm/ptrace-abi.h
@@ -80,8 +80,6 @@
 
 #define PTRACE_SINGLEBLOCK	33	/* resume execution until next branch */
 
-#ifdef CONFIG_X86_PTRACE_BTS
-
 #ifndef __ASSEMBLY__
 #include <linux/types.h>
 
@@ -140,6 +138,5 @@
    BTS records are read from oldest to newest.
    Returns number of BTS records drained.
 */
-#endif /* CONFIG_X86_PTRACE_BTS */
 
 #endif /* _ASM_X86_PTRACE_ABI_H */
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
index 47d0e21..19e0d88 100644
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -21,19 +21,19 @@
 extern int smp_num_siblings;
 extern unsigned int num_processors;
 
-DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
-DECLARE_PER_CPU(cpumask_t, cpu_core_map);
+DECLARE_PER_CPU(cpumask_var_t, cpu_sibling_map);
+DECLARE_PER_CPU(cpumask_var_t, cpu_core_map);
 DECLARE_PER_CPU(u16, cpu_llc_id);
 DECLARE_PER_CPU(int, cpu_number);
 
 static inline struct cpumask *cpu_sibling_mask(int cpu)
 {
-	return &per_cpu(cpu_sibling_map, cpu);
+	return per_cpu(cpu_sibling_map, cpu);
 }
 
 static inline struct cpumask *cpu_core_mask(int cpu)
 {
-	return &per_cpu(cpu_core_map, cpu);
+	return per_cpu(cpu_core_map, cpu);
 }
 
 DECLARE_EARLY_PER_CPU(u16, x86_cpu_to_apicid);
@@ -121,9 +121,10 @@
 	smp_ops.send_call_func_single_ipi(cpu);
 }
 
-static inline void arch_send_call_function_ipi(cpumask_t mask)
+#define arch_send_call_function_ipi_mask arch_send_call_function_ipi_mask
+static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask)
 {
-	smp_ops.send_call_func_ipi(&mask);
+	smp_ops.send_call_func_ipi(mask);
 }
 
 void cpu_disable_common(void);
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index df9d5f7..8820a73 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -94,6 +94,7 @@
 #define TIF_FORCED_TF		24	/* true if TF in eflags artificially */
 #define TIF_DEBUGCTLMSR		25	/* uses thread_struct.debugctlmsr */
 #define TIF_DS_AREA_MSR		26      /* uses thread_struct.ds_area_msr */
+#define TIF_SYSCALL_FTRACE	27	/* for ftrace syscall instrumentation */
 
 #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
@@ -115,15 +116,17 @@
 #define _TIF_FORCED_TF		(1 << TIF_FORCED_TF)
 #define _TIF_DEBUGCTLMSR	(1 << TIF_DEBUGCTLMSR)
 #define _TIF_DS_AREA_MSR	(1 << TIF_DS_AREA_MSR)
+#define _TIF_SYSCALL_FTRACE	(1 << TIF_SYSCALL_FTRACE)
 
 /* work to do in syscall_trace_enter() */
 #define _TIF_WORK_SYSCALL_ENTRY	\
-	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU | \
+	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU | _TIF_SYSCALL_FTRACE |	\
 	 _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | _TIF_SINGLESTEP)
 
 /* work to do in syscall_trace_leave() */
 #define _TIF_WORK_SYSCALL_EXIT	\
-	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP)
+	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP |	\
+	 _TIF_SYSCALL_FTRACE)
 
 /* work to do on interrupt/exception return */
 #define _TIF_WORK_MASK							\
@@ -132,7 +135,7 @@
 	   _TIF_SINGLESTEP|_TIF_SECCOMP|_TIF_SYSCALL_EMU))
 
 /* work to do on any return to user space */
-#define _TIF_ALLWORK_MASK (0x0000FFFF & ~_TIF_SECCOMP)
+#define _TIF_ALLWORK_MASK ((0x0000FFFF & ~_TIF_SECCOMP) | _TIF_SYSCALL_FTRACE)
 
 /* Only used for 64 bit */
 #define _TIF_DO_NOTIFY_MASK						\
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index 744299c..892b119 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -44,9 +44,6 @@
 
 #ifdef CONFIG_X86_32
 
-/* Mappings between node number and cpus on that node. */
-extern cpumask_t node_to_cpumask_map[];
-
 /* Mappings between logical cpu number and node number */
 extern int cpu_to_node_map[];
 
@@ -57,30 +54,8 @@
 }
 #define early_cpu_to_node(cpu)	cpu_to_node(cpu)
 
-/* Returns a bitmask of CPUs on Node 'node'.
- *
- * Side note: this function creates the returned cpumask on the stack
- * so with a high NR_CPUS count, excessive stack space is used.  The
- * cpumask_of_node function should be used whenever possible.
- */
-static inline cpumask_t node_to_cpumask(int node)
-{
-	return node_to_cpumask_map[node];
-}
-
-/* Returns a bitmask of CPUs on Node 'node'. */
-static inline const struct cpumask *cpumask_of_node(int node)
-{
-	return &node_to_cpumask_map[node];
-}
-
-static inline void setup_node_to_cpumask_map(void) { }
-
 #else /* CONFIG_X86_64 */
 
-/* Mappings between node number and cpus on that node. */
-extern cpumask_t *node_to_cpumask_map;
-
 /* Mappings between logical cpu number and node number */
 DECLARE_EARLY_PER_CPU(int, x86_cpu_to_node_map);
 
@@ -91,8 +66,6 @@
 #ifdef CONFIG_DEBUG_PER_CPU_MAPS
 extern int cpu_to_node(int cpu);
 extern int early_cpu_to_node(int cpu);
-extern const cpumask_t *cpumask_of_node(int node);
-extern cpumask_t node_to_cpumask(int node);
 
 #else	/* !CONFIG_DEBUG_PER_CPU_MAPS */
 
@@ -108,42 +81,32 @@
 	return early_per_cpu(x86_cpu_to_node_map, cpu);
 }
 
-/* Returns a pointer to the cpumask of CPUs on Node 'node'. */
-static inline const cpumask_t *cpumask_of_node(int node)
-{
-	return &node_to_cpumask_map[node];
-}
+#endif /* !CONFIG_DEBUG_PER_CPU_MAPS */
 
-/* Returns a bitmask of CPUs on Node 'node'. */
-static inline cpumask_t node_to_cpumask(int node)
+#endif /* CONFIG_X86_64 */
+
+/* Mappings between node number and cpus on that node. */
+extern cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
+
+#ifdef CONFIG_DEBUG_PER_CPU_MAPS
+extern 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 /* !CONFIG_DEBUG_PER_CPU_MAPS */
+#endif
 
 extern void setup_node_to_cpumask_map(void);
 
 /*
- * Replace default node_to_cpumask_ptr with optimized version
- * Deprecated: use "const struct cpumask *mask = cpumask_of_node(node)"
- */
-#define node_to_cpumask_ptr(v, node)		\
-		const cpumask_t *v = cpumask_of_node(node)
-
-#define node_to_cpumask_ptr_next(v, node)	\
-			   v = cpumask_of_node(node)
-
-#endif /* CONFIG_X86_64 */
-
-/*
  * Returns the number of the node containing Node 'node'. This
  * architecture is flat, so it is a pretty simple function!
  */
 #define parent_node(node) (node)
 
 #define pcibus_to_node(bus) __pcibus_to_node(bus)
-#define pcibus_to_cpumask(bus) __pcibus_to_cpumask(bus)
 
 #ifdef CONFIG_X86_32
 extern unsigned long node_start_pfn[];
@@ -209,40 +172,24 @@
 	return 0;
 }
 
-static inline const cpumask_t *cpumask_of_node(int node)
+static inline const struct cpumask *cpumask_of_node(int node)
 {
-	return &cpu_online_map;
-}
-static inline cpumask_t node_to_cpumask(int node)
-{
-	return cpu_online_map;
+	return cpu_online_mask;
 }
 
 static inline void setup_node_to_cpumask_map(void) { }
 
-/*
- * Replace default node_to_cpumask_ptr with optimized version
- * Deprecated: use "const struct cpumask *mask = cpumask_of_node(node)"
- */
-#define node_to_cpumask_ptr(v, node)		\
-		const cpumask_t *v = cpumask_of_node(node)
-
-#define node_to_cpumask_ptr_next(v, node)	\
-			   v = cpumask_of_node(node)
 #endif
 
 #include <asm-generic/topology.h>
 
-extern cpumask_t cpu_coregroup_map(int cpu);
 extern const struct cpumask *cpu_coregroup_mask(int cpu);
 
 #ifdef ENABLE_TOPO_DEFINES
 #define topology_physical_package_id(cpu)	(cpu_data(cpu).phys_proc_id)
 #define topology_core_id(cpu)			(cpu_data(cpu).cpu_core_id)
-#define topology_core_siblings(cpu)		(per_cpu(cpu_core_map, cpu))
-#define topology_thread_siblings(cpu)		(per_cpu(cpu_sibling_map, cpu))
-#define topology_core_cpumask(cpu)		(&per_cpu(cpu_core_map, cpu))
-#define topology_thread_cpumask(cpu)		(&per_cpu(cpu_sibling_map, cpu))
+#define topology_core_cpumask(cpu)		(per_cpu(cpu_core_map, cpu))
+#define topology_thread_cpumask(cpu)		(per_cpu(cpu_sibling_map, cpu))
 
 /* indicates that pointers to the topology cpumask_t maps are valid */
 #define arch_provides_topology_pointers		yes
@@ -256,7 +203,7 @@
 void set_pci_bus_resources_arch_default(struct pci_bus *b);
 
 #ifdef CONFIG_SMP
-#define mc_capable()	(cpus_weight(per_cpu(cpu_core_map, 0)) != nr_cpu_ids)
+#define mc_capable()	(cpumask_weight(cpu_core_mask(0)) != nr_cpu_ids)
 #define smt_capable()			(smp_num_siblings > 1)
 #endif
 
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index c611ad6..145cce7 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -66,7 +66,8 @@
 obj-y				+= apic/
 obj-$(CONFIG_X86_REBOOTFIXUPS)	+= reboot_fixups_32.o
 obj-$(CONFIG_DYNAMIC_FTRACE)	+= ftrace.o
-obj-$(CONFIG_FUNCTION_GRAPH_TRACER)	+= ftrace.o
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
+obj-$(CONFIG_FTRACE_SYSCALLS)	+= ftrace.o
 obj-$(CONFIG_KEXEC)		+= machine_kexec_$(BITS).o
 obj-$(CONFIG_KEXEC)		+= relocate_kernel_$(BITS).o crash.o
 obj-$(CONFIG_CRASH_DUMP)	+= crash_dump_$(BITS).o
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index a18eb7c..723989d7 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -230,6 +230,35 @@
 }
 
 static int __init
+acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)
+{
+	struct acpi_madt_local_x2apic *processor = NULL;
+
+	processor = (struct acpi_madt_local_x2apic *)header;
+
+	if (BAD_MADT_ENTRY(processor, end))
+		return -EINVAL;
+
+	acpi_table_print_madt_entry(header);
+
+#ifdef CONFIG_X86_X2APIC
+	/*
+	 * We need to register disabled CPU as well to permit
+	 * counting disabled CPUs. This allows us to size
+	 * cpus_possible_map more accurately, to permit
+	 * to not preallocating memory for all NR_CPUS
+	 * when we use CPU hotplug.
+	 */
+	acpi_register_lapic(processor->local_apic_id,	/* APIC ID */
+			    processor->lapic_flags & ACPI_MADT_ENABLED);
+#else
+	printk(KERN_WARNING PREFIX "x2apic entry ignored\n");
+#endif
+
+	return 0;
+}
+
+static int __init
 acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long end)
 {
 	struct acpi_madt_local_apic *processor = NULL;
@@ -289,6 +318,25 @@
 }
 
 static int __init
+acpi_parse_x2apic_nmi(struct acpi_subtable_header *header,
+		      const unsigned long end)
+{
+	struct acpi_madt_local_x2apic_nmi *x2apic_nmi = NULL;
+
+	x2apic_nmi = (struct acpi_madt_local_x2apic_nmi *)header;
+
+	if (BAD_MADT_ENTRY(x2apic_nmi, end))
+		return -EINVAL;
+
+	acpi_table_print_madt_entry(header);
+
+	if (x2apic_nmi->lint != 1)
+		printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n");
+
+	return 0;
+}
+
+static int __init
 acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long end)
 {
 	struct acpi_madt_local_apic_nmi *lapic_nmi = NULL;
@@ -793,6 +841,7 @@
 static int __init acpi_parse_madt_lapic_entries(void)
 {
 	int count;
+	int x2count = 0;
 
 	if (!cpu_has_apic)
 		return -ENODEV;
@@ -816,22 +865,28 @@
 	count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC,
 				      acpi_parse_sapic, MAX_APICS);
 
-	if (!count)
+	if (!count) {
+		x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC,
+						acpi_parse_x2apic, MAX_APICS);
 		count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC,
 					      acpi_parse_lapic, MAX_APICS);
-	if (!count) {
+	}
+	if (!count && !x2count) {
 		printk(KERN_ERR PREFIX "No LAPIC entries present\n");
 		/* TBD: Cleanup to allow fallback to MPS */
 		return -ENODEV;
-	} else if (count < 0) {
+	} else if (count < 0 || x2count < 0) {
 		printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n");
 		/* TBD: Cleanup to allow fallback to MPS */
 		return count;
 	}
 
+	x2count =
+	    acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC_NMI,
+				  acpi_parse_x2apic_nmi, 0);
 	count =
 	    acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_NMI, acpi_parse_lapic_nmi, 0);
-	if (count < 0) {
+	if (count < 0 || x2count < 0) {
 		printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
 		/* TBD: Cleanup to allow fallback to MPS */
 		return count;
@@ -1470,7 +1525,7 @@
 
 /*
  * If your system is blacklisted here, but you find that acpi=force
- * works for you, please contact acpi-devel@sourceforge.net
+ * works for you, please contact linux-acpi@vger.kernel.org
  */
 static struct dmi_system_id __initdata acpi_dmi_table[] = {
 	/*
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index 4c80f15..f576587 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -5,6 +5,7 @@
 #include <linux/kprobes.h>
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
+#include <linux/memory.h>
 #include <asm/alternative.h>
 #include <asm/sections.h>
 #include <asm/pgtable.h>
@@ -12,7 +13,9 @@
 #include <asm/nmi.h>
 #include <asm/vsyscall.h>
 #include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
 #include <asm/io.h>
+#include <asm/fixmap.h>
 
 #define MAX_PATCH_LEN (255-1)
 
@@ -226,6 +229,7 @@
 {
 	u8 **ptr;
 
+	mutex_lock(&text_mutex);
 	for (ptr = start; ptr < end; ptr++) {
 		if (*ptr < text)
 			continue;
@@ -234,6 +238,7 @@
 		/* turn DS segment override prefix into lock prefix */
 		text_poke(*ptr, ((unsigned char []){0xf0}), 1);
 	};
+	mutex_unlock(&text_mutex);
 }
 
 static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end)
@@ -243,6 +248,7 @@
 	if (noreplace_smp)
 		return;
 
+	mutex_lock(&text_mutex);
 	for (ptr = start; ptr < end; ptr++) {
 		if (*ptr < text)
 			continue;
@@ -251,6 +257,7 @@
 		/* turn lock prefix into DS segment override prefix */
 		text_poke(*ptr, ((unsigned char []){0x3E}), 1);
 	};
+	mutex_unlock(&text_mutex);
 }
 
 struct smp_alt_module {
@@ -500,15 +507,16 @@
  * It means the size must be writable atomically and the address must be aligned
  * in a way that permits an atomic write. It also makes sure we fit on a single
  * page.
+ *
+ * Note: Must be called under text_mutex.
  */
 void *__kprobes text_poke(void *addr, const void *opcode, size_t len)
 {
+	unsigned long flags;
 	char *vaddr;
-	int nr_pages = 2;
 	struct page *pages[2];
 	int i;
 
-	might_sleep();
 	if (!core_kernel_text((unsigned long)addr)) {
 		pages[0] = vmalloc_to_page(addr);
 		pages[1] = vmalloc_to_page(addr + PAGE_SIZE);
@@ -518,18 +526,21 @@
 		pages[1] = virt_to_page(addr + PAGE_SIZE);
 	}
 	BUG_ON(!pages[0]);
-	if (!pages[1])
-		nr_pages = 1;
-	vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL);
-	BUG_ON(!vaddr);
-	local_irq_disable();
+	local_irq_save(flags);
+	set_fixmap(FIX_TEXT_POKE0, page_to_phys(pages[0]));
+	if (pages[1])
+		set_fixmap(FIX_TEXT_POKE1, page_to_phys(pages[1]));
+	vaddr = (char *)fix_to_virt(FIX_TEXT_POKE0);
 	memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len);
-	local_irq_enable();
-	vunmap(vaddr);
+	clear_fixmap(FIX_TEXT_POKE0);
+	if (pages[1])
+		clear_fixmap(FIX_TEXT_POKE1);
+	local_flush_tlb();
 	sync_core();
 	/* Could also do a CLFLUSH here to speed up CPU recovery; but
 	   that causes hangs on some VIA CPUs. */
 	for (i = 0; i < len; i++)
 		BUG_ON(((char *)addr)[i] != ((char *)opcode)[i]);
+	local_irq_restore(flags);
 	return addr;
 }
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index c5962fe..a97db99 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -1928,6 +1928,12 @@
 	return paddr;
 }
 
+static int amd_iommu_domain_has_cap(struct iommu_domain *domain,
+				    unsigned long cap)
+{
+	return 0;
+}
+
 static struct iommu_ops amd_iommu_ops = {
 	.domain_init = amd_iommu_domain_init,
 	.domain_destroy = amd_iommu_domain_destroy,
@@ -1936,5 +1942,6 @@
 	.map = amd_iommu_map_range,
 	.unmap = amd_iommu_unmap_range,
 	.iova_to_phys = amd_iommu_iova_to_phys,
+	.domain_has_cap = amd_iommu_domain_has_cap,
 };
 
diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c
index d806eca..676cdac 100644
--- a/arch/x86/kernel/apic/bigsmp_32.c
+++ b/arch/x86/kernel/apic/bigsmp_32.c
@@ -26,12 +26,12 @@
 	return 1;
 }
 
-static const cpumask_t *bigsmp_target_cpus(void)
+static const struct cpumask *bigsmp_target_cpus(void)
 {
 #ifdef CONFIG_SMP
-	return &cpu_online_map;
+	return cpu_online_mask;
 #else
-	return &cpumask_of_cpu(0);
+	return cpumask_of(0);
 #endif
 }
 
@@ -118,9 +118,9 @@
 }
 
 /* As we are using single CPU as destination, pick only one CPU here */
-static unsigned int bigsmp_cpu_mask_to_apicid(const cpumask_t *cpumask)
+static unsigned int bigsmp_cpu_mask_to_apicid(const struct cpumask *cpumask)
 {
-	return bigsmp_cpu_to_logical_apicid(first_cpu(*cpumask));
+	return bigsmp_cpu_to_logical_apicid(cpumask_first(cpumask));
 }
 
 static unsigned int bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
@@ -188,10 +188,10 @@
 	{ } /* NULL entry stops DMI scanning */
 };
 
-static void bigsmp_vector_allocation_domain(int cpu, cpumask_t *retmask)
+static void bigsmp_vector_allocation_domain(int cpu, struct cpumask *retmask)
 {
-	cpus_clear(*retmask);
-	cpu_set(cpu, *retmask);
+	cpumask_clear(retmask);
+	cpumask_set_cpu(cpu, retmask);
 }
 
 static int probe_bigsmp(void)
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c
index 19588f2..1c11b81 100644
--- a/arch/x86/kernel/apic/es7000_32.c
+++ b/arch/x86/kernel/apic/es7000_32.c
@@ -410,7 +410,7 @@
 		WARN(1, "Command failed, status = %x\n", mip_status);
 }
 
-static void es7000_vector_allocation_domain(int cpu, cpumask_t *retmask)
+static void es7000_vector_allocation_domain(int cpu, struct cpumask *retmask)
 {
 	/* Careful. Some cpus do not strictly honor the set of cpus
 	 * specified in the interrupt destination when using lowest
@@ -420,7 +420,8 @@
 	 * deliver interrupts to the wrong hyperthread when only one
 	 * hyperthread was specified in the interrupt desitination.
 	 */
-	*retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } };
+	cpumask_clear(retmask);
+	cpumask_bits(retmask)[0] = APIC_ALL_CPUS;
 }
 
 
@@ -455,14 +456,14 @@
 	return 1;
 }
 
-static const cpumask_t *target_cpus_cluster(void)
+static const struct cpumask *target_cpus_cluster(void)
 {
-	return &CPU_MASK_ALL;
+	return cpu_all_mask;
 }
 
-static const cpumask_t *es7000_target_cpus(void)
+static const struct cpumask *es7000_target_cpus(void)
 {
-	return &cpumask_of_cpu(smp_processor_id());
+	return cpumask_of(smp_processor_id());
 }
 
 static unsigned long
@@ -517,7 +518,7 @@
 	  "Enabling APIC mode:  %s. Using %d I/O APICs, target cpus %lx\n",
 		(apic_version[apic] == 0x14) ?
 			"Physical Cluster" : "Logical Cluster",
-		nr_ioapics, cpus_addr(*es7000_target_cpus())[0]);
+		nr_ioapics, cpumask_bits(es7000_target_cpus())[0]);
 }
 
 static int es7000_apicid_to_node(int logical_apicid)
@@ -572,7 +573,7 @@
 	return 1;
 }
 
-static unsigned int es7000_cpu_mask_to_apicid(const cpumask_t *cpumask)
+static unsigned int es7000_cpu_mask_to_apicid(const struct cpumask *cpumask)
 {
 	unsigned int round = 0;
 	int cpu, uninitialized_var(apicid);
diff --git a/arch/x86/kernel/apic/nmi.c b/arch/x86/kernel/apic/nmi.c
index bdfad80..d6bd624 100644
--- a/arch/x86/kernel/apic/nmi.c
+++ b/arch/x86/kernel/apic/nmi.c
@@ -39,7 +39,7 @@
 int unknown_nmi_panic;
 int nmi_watchdog_enabled;
 
-static cpumask_t backtrace_mask = CPU_MASK_NONE;
+static cpumask_var_t backtrace_mask;
 
 /* nmi_active:
  * >0: the lapic NMI watchdog is active, but can be disabled
@@ -138,6 +138,7 @@
 	if (!prev_nmi_count)
 		goto error;
 
+	alloc_cpumask_var(&backtrace_mask, GFP_KERNEL);
 	printk(KERN_INFO "Testing NMI watchdog ... ");
 
 #ifdef CONFIG_SMP
@@ -413,14 +414,14 @@
 		touched = 1;
 	}
 
-	if (cpu_isset(cpu, backtrace_mask)) {
+	if (cpumask_test_cpu(cpu, backtrace_mask)) {
 		static DEFINE_SPINLOCK(lock);	/* Serialise the printks */
 
 		spin_lock(&lock);
 		printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu);
 		dump_stack();
 		spin_unlock(&lock);
-		cpu_clear(cpu, backtrace_mask);
+		cpumask_clear_cpu(cpu, backtrace_mask);
 	}
 
 	/* Could check oops_in_progress here too, but it's safer not to */
@@ -554,10 +555,10 @@
 {
 	int i;
 
-	backtrace_mask = cpu_online_map;
+	cpumask_copy(backtrace_mask, cpu_online_mask);
 	/* Wait for up to 10 seconds for all CPUs to do the backtrace */
 	for (i = 0; i < 10 * 1000; i++) {
-		if (cpus_empty(backtrace_mask))
+		if (cpumask_empty(backtrace_mask))
 			break;
 		mdelay(1);
 	}
diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c
index ba2fc64..533e59c 100644
--- a/arch/x86/kernel/apic/numaq_32.c
+++ b/arch/x86/kernel/apic/numaq_32.c
@@ -334,9 +334,9 @@
 	clear_local_APIC();
 }
 
-static inline const cpumask_t *numaq_target_cpus(void)
+static inline const struct cpumask *numaq_target_cpus(void)
 {
-	return &CPU_MASK_ALL;
+	return cpu_all_mask;
 }
 
 static inline unsigned long
@@ -427,7 +427,7 @@
  * We use physical apicids here, not logical, so just return the default
  * physical broadcast to stop people from breaking us
  */
-static inline unsigned int numaq_cpu_mask_to_apicid(const cpumask_t *cpumask)
+static unsigned int numaq_cpu_mask_to_apicid(const struct cpumask *cpumask)
 {
 	return 0x0F;
 }
@@ -462,7 +462,7 @@
 	return found_numaq;
 }
 
-static void numaq_vector_allocation_domain(int cpu, cpumask_t *retmask)
+static void numaq_vector_allocation_domain(int cpu, struct cpumask *retmask)
 {
 	/* Careful. Some cpus do not strictly honor the set of cpus
 	 * specified in the interrupt destination when using lowest
@@ -472,7 +472,8 @@
 	 * deliver interrupts to the wrong hyperthread when only one
 	 * hyperthread was specified in the interrupt desitination.
 	 */
-	*retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } };
+	cpumask_clear(retmask);
+	cpumask_bits(retmask)[0] = APIC_ALL_CPUS;
 }
 
 static void numaq_setup_portio_remap(void)
diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c
index 141c99a..01eda2a 100644
--- a/arch/x86/kernel/apic/probe_32.c
+++ b/arch/x86/kernel/apic/probe_32.c
@@ -83,7 +83,8 @@
 	 * deliver interrupts to the wrong hyperthread when only one
 	 * hyperthread was specified in the interrupt desitination.
 	 */
-	*retmask = (cpumask_t) { { [0] = APIC_ALL_CPUS } };
+	cpumask_clear(retmask);
+	cpumask_bits(retmask)[0] = APIC_ALL_CPUS;
 }
 
 /* should be called last. */
diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c
index aac52fa..9cfe1f4 100644
--- a/arch/x86/kernel/apic/summit_32.c
+++ b/arch/x86/kernel/apic/summit_32.c
@@ -53,23 +53,19 @@
 	return (x >> 24) & 0xFF;
 }
 
-static inline void summit_send_IPI_mask(const cpumask_t *mask, int vector)
+static inline void summit_send_IPI_mask(const struct cpumask *mask, int vector)
 {
 	default_send_IPI_mask_sequence_logical(mask, vector);
 }
 
 static void summit_send_IPI_allbutself(int vector)
 {
-	cpumask_t mask = cpu_online_map;
-	cpu_clear(smp_processor_id(), mask);
-
-	if (!cpus_empty(mask))
-		summit_send_IPI_mask(&mask, vector);
+	default_send_IPI_mask_allbutself_logical(cpu_online_mask, vector);
 }
 
 static void summit_send_IPI_all(int vector)
 {
-	summit_send_IPI_mask(&cpu_online_map, vector);
+	summit_send_IPI_mask(cpu_online_mask, vector);
 }
 
 #include <asm/tsc.h>
@@ -186,13 +182,13 @@
 
 #define SUMMIT_APIC_DFR_VALUE	(APIC_DFR_CLUSTER)
 
-static const cpumask_t *summit_target_cpus(void)
+static const struct cpumask *summit_target_cpus(void)
 {
 	/* CPU_MASK_ALL (0xff) has undefined behaviour with
 	 * dest_LowestPrio mode logical clustered apic interrupt routing
 	 * Just start on cpu 0.  IRQ balancing will spread load
 	 */
-	return &cpumask_of_cpu(0);
+	return cpumask_of(0);
 }
 
 static unsigned long summit_check_apicid_used(physid_mask_t bitmap, int apicid)
@@ -289,7 +285,7 @@
 	return 1;
 }
 
-static unsigned int summit_cpu_mask_to_apicid(const cpumask_t *cpumask)
+static unsigned int summit_cpu_mask_to_apicid(const struct cpumask *cpumask)
 {
 	unsigned int round = 0;
 	int cpu, apicid = 0;
@@ -346,7 +342,7 @@
 	return 0;
 }
 
-static void summit_vector_allocation_domain(int cpu, cpumask_t *retmask)
+static void summit_vector_allocation_domain(int cpu, struct cpumask *retmask)
 {
 	/* Careful. Some cpus do not strictly honor the set of cpus
 	 * specified in the interrupt destination when using lowest
@@ -356,7 +352,8 @@
 	 * deliver interrupts to the wrong hyperthread when only one
 	 * hyperthread was specified in the interrupt desitination.
 	 */
-	*retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } };
+	cpumask_clear(retmask);
+	cpumask_bits(retmask)[0] = APIC_ALL_CPUS;
 }
 
 #ifdef CONFIG_X86_SUMMIT_NUMA
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index ac7783a..49e0939 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -466,7 +466,7 @@
  *	@err: APM BIOS return code
  *
  *	Write a meaningful log entry to the kernel log in the event of
- *	an APM error.
+ *	an APM error.  Note that this also handles (negative) kernel errors.
  */
 
 static void apm_error(char *str, int err)
@@ -478,43 +478,14 @@
 			break;
 	if (i < ERROR_COUNT)
 		printk(KERN_NOTICE "apm: %s: %s\n", str, error_table[i].msg);
+	else if (err < 0)
+		printk(KERN_NOTICE "apm: %s: linux error code %i\n", str, err);
 	else
 		printk(KERN_NOTICE "apm: %s: unknown error code %#2.2x\n",
 		       str, err);
 }
 
 /*
- * Lock APM functionality to physical CPU 0
- */
-
-#ifdef CONFIG_SMP
-
-static cpumask_t apm_save_cpus(void)
-{
-	cpumask_t x = current->cpus_allowed;
-	/* Some bioses don't like being called from CPU != 0 */
-	set_cpus_allowed(current, cpumask_of_cpu(0));
-	BUG_ON(smp_processor_id() != 0);
-	return x;
-}
-
-static inline void apm_restore_cpus(cpumask_t mask)
-{
-	set_cpus_allowed(current, mask);
-}
-
-#else
-
-/*
- *	No CPU lockdown needed on a uniprocessor
- */
-
-#define apm_save_cpus()		(current->cpus_allowed)
-#define apm_restore_cpus(x)	(void)(x)
-
-#endif
-
-/*
  * These are the actual BIOS calls.  Depending on APM_ZERO_SEGS and
  * apm_info.allow_ints, we are being really paranoid here!  Not only
  * are interrupts disabled, but all the segment registers (except SS)
@@ -568,16 +539,23 @@
 #	define APM_DO_RESTORE_SEGS
 #endif
 
+struct apm_bios_call {
+	u32 func;
+	/* In and out */
+	u32 ebx;
+	u32 ecx;
+	/* Out only */
+	u32 eax;
+	u32 edx;
+	u32 esi;
+
+	/* Error: -ENOMEM, or bits 8-15 of eax */
+	int err;
+};
+
 /**
- *	apm_bios_call	-	Make an APM BIOS 32bit call
- *	@func: APM function to execute
- *	@ebx_in: EBX register for call entry
- *	@ecx_in: ECX register for call entry
- *	@eax: EAX register return
- *	@ebx: EBX register return
- *	@ecx: ECX register return
- *	@edx: EDX register return
- *	@esi: ESI register return
+ *	__apm_bios_call - Make an APM BIOS 32bit call
+ *	@_call: pointer to struct apm_bios_call.
  *
  *	Make an APM call using the 32bit protected mode interface. The
  *	caller is responsible for knowing if APM BIOS is configured and
@@ -586,35 +564,109 @@
  *	flag is loaded into AL.  If there is an error, then the error
  *	code is returned in AH (bits 8-15 of eax) and this function
  *	returns non-zero.
+ *
+ *	Note: this makes the call on the current CPU.
  */
-
-static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in,
-	u32 *eax, u32 *ebx, u32 *ecx, u32 *edx, u32 *esi)
+static long __apm_bios_call(void *_call)
 {
 	APM_DECL_SEGS
 	unsigned long		flags;
-	cpumask_t		cpus;
 	int			cpu;
 	struct desc_struct	save_desc_40;
 	struct desc_struct	*gdt;
-
-	cpus = apm_save_cpus();
+	struct apm_bios_call	*call = _call;
 
 	cpu = get_cpu();
+	BUG_ON(cpu != 0);
 	gdt = get_cpu_gdt_table(cpu);
 	save_desc_40 = gdt[0x40 / 8];
 	gdt[0x40 / 8] = bad_bios_desc;
 
 	apm_irq_save(flags);
 	APM_DO_SAVE_SEGS;
-	apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
+	apm_bios_call_asm(call->func, call->ebx, call->ecx,
+			  &call->eax, &call->ebx, &call->ecx, &call->edx,
+			  &call->esi);
 	APM_DO_RESTORE_SEGS;
 	apm_irq_restore(flags);
 	gdt[0x40 / 8] = save_desc_40;
 	put_cpu();
-	apm_restore_cpus(cpus);
 
-	return *eax & 0xff;
+	return call->eax & 0xff;
+}
+
+/* Run __apm_bios_call or __apm_bios_call_simple on CPU 0 */
+static int on_cpu0(long (*fn)(void *), struct apm_bios_call *call)
+{
+	int ret;
+
+	/* Don't bother with work_on_cpu in the common case, so we don't
+	 * have to worry about OOM or overhead. */
+	if (get_cpu() == 0) {
+		ret = fn(call);
+		put_cpu();
+	} else {
+		put_cpu();
+		ret = work_on_cpu(0, fn, call);
+	}
+
+	/* work_on_cpu can fail with -ENOMEM */
+	if (ret < 0)
+		call->err = ret;
+	else
+		call->err = (call->eax >> 8) & 0xff;
+
+	return ret;
+}
+
+/**
+ *	apm_bios_call	-	Make an APM BIOS 32bit call (on CPU 0)
+ *	@call: the apm_bios_call registers.
+ *
+ *	If there is an error, it is returned in @call.err.
+ */
+static int apm_bios_call(struct apm_bios_call *call)
+{
+	return on_cpu0(__apm_bios_call, call);
+}
+
+/**
+ *	__apm_bios_call_simple - Make an APM BIOS 32bit call (on CPU 0)
+ *	@_call: pointer to struct apm_bios_call.
+ *
+ *	Make a BIOS call that returns one value only, or just status.
+ *	If there is an error, then the error code is returned in AH
+ *	(bits 8-15 of eax) and this function returns non-zero (it can
+ *	also return -ENOMEM). This is used for simpler BIOS operations.
+ *	This call may hold interrupts off for a long time on some laptops.
+ *
+ *	Note: this makes the call on the current CPU.
+ */
+static long __apm_bios_call_simple(void *_call)
+{
+	u8			error;
+	APM_DECL_SEGS
+	unsigned long		flags;
+	int			cpu;
+	struct desc_struct	save_desc_40;
+	struct desc_struct	*gdt;
+	struct apm_bios_call	*call = _call;
+
+	cpu = get_cpu();
+	BUG_ON(cpu != 0);
+	gdt = get_cpu_gdt_table(cpu);
+	save_desc_40 = gdt[0x40 / 8];
+	gdt[0x40 / 8] = bad_bios_desc;
+
+	apm_irq_save(flags);
+	APM_DO_SAVE_SEGS;
+	error = apm_bios_call_simple_asm(call->func, call->ebx, call->ecx,
+					 &call->eax);
+	APM_DO_RESTORE_SEGS;
+	apm_irq_restore(flags);
+	gdt[0x40 / 8] = save_desc_40;
+	put_cpu();
+	return error;
 }
 
 /**
@@ -623,40 +675,28 @@
  *	@ebx_in: EBX register value for BIOS call
  *	@ecx_in: ECX register value for BIOS call
  *	@eax: EAX register on return from the BIOS call
+ *	@err: bits
  *
  *	Make a BIOS call that returns one value only, or just status.
- *	If there is an error, then the error code is returned in AH
- *	(bits 8-15 of eax) and this function returns non-zero. This is
- *	used for simpler BIOS operations. This call may hold interrupts
- *	off for a long time on some laptops.
+ *	If there is an error, then the error code is returned in @err
+ *	and this function returns non-zero. This is used for simpler
+ *	BIOS operations.  This call may hold interrupts off for a long
+ *	time on some laptops.
  */
-
-static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax)
+static int apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax,
+				int *err)
 {
-	u8			error;
-	APM_DECL_SEGS
-	unsigned long		flags;
-	cpumask_t		cpus;
-	int			cpu;
-	struct desc_struct	save_desc_40;
-	struct desc_struct	*gdt;
+	struct apm_bios_call call;
+	int ret;
 
-	cpus = apm_save_cpus();
+	call.func = func;
+	call.ebx = ebx_in;
+	call.ecx = ecx_in;
 
-	cpu = get_cpu();
-	gdt = get_cpu_gdt_table(cpu);
-	save_desc_40 = gdt[0x40 / 8];
-	gdt[0x40 / 8] = bad_bios_desc;
-
-	apm_irq_save(flags);
-	APM_DO_SAVE_SEGS;
-	error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
-	APM_DO_RESTORE_SEGS;
-	apm_irq_restore(flags);
-	gdt[0x40 / 8] = save_desc_40;
-	put_cpu();
-	apm_restore_cpus(cpus);
-	return error;
+	ret = on_cpu0(__apm_bios_call_simple, &call);
+	*eax = call.eax;
+	*err = call.err;
+	return ret;
 }
 
 /**
@@ -678,9 +718,10 @@
 static int apm_driver_version(u_short *val)
 {
 	u32 eax;
+	int err;
 
-	if (apm_bios_call_simple(APM_FUNC_VERSION, 0, *val, &eax))
-		return (eax >> 8) & 0xff;
+	if (apm_bios_call_simple(APM_FUNC_VERSION, 0, *val, &eax, &err))
+		return err;
 	*val = eax;
 	return APM_SUCCESS;
 }
@@ -701,22 +742,21 @@
  *	that APM 1.2 is in use. If no messges are pending the value 0x80
  *	is returned (No power management events pending).
  */
-
 static int apm_get_event(apm_event_t *event, apm_eventinfo_t *info)
 {
-	u32 eax;
-	u32 ebx;
-	u32 ecx;
-	u32 dummy;
+	struct apm_bios_call call;
 
-	if (apm_bios_call(APM_FUNC_GET_EVENT, 0, 0, &eax, &ebx, &ecx,
-			  &dummy, &dummy))
-		return (eax >> 8) & 0xff;
-	*event = ebx;
+	call.func = APM_FUNC_GET_EVENT;
+	call.ebx = call.ecx = 0;
+
+	if (apm_bios_call(&call))
+		return call.err;
+
+	*event = call.ebx;
 	if (apm_info.connection_version < 0x0102)
 		*info = ~0; /* indicate info not valid */
 	else
-		*info = ecx;
+		*info = call.ecx;
 	return APM_SUCCESS;
 }
 
@@ -737,9 +777,10 @@
 static int set_power_state(u_short what, u_short state)
 {
 	u32 eax;
+	int err;
 
-	if (apm_bios_call_simple(APM_FUNC_SET_STATE, what, state, &eax))
-		return (eax >> 8) & 0xff;
+	if (apm_bios_call_simple(APM_FUNC_SET_STATE, what, state, &eax, &err))
+		return err;
 	return APM_SUCCESS;
 }
 
@@ -770,6 +811,7 @@
 	u8 ret = 0;
 	int idled = 0;
 	int polling;
+	int err;
 
 	polling = !!(current_thread_info()->status & TS_POLLING);
 	if (polling) {
@@ -782,7 +824,7 @@
 	}
 	if (!need_resched()) {
 		idled = 1;
-		ret = apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax);
+		ret = apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax, &err);
 	}
 	if (polling)
 		current_thread_info()->status |= TS_POLLING;
@@ -797,8 +839,7 @@
 		 * Only report the failure the first 5 times.
 		 */
 		if (++t < 5) {
-			printk(KERN_DEBUG "apm_do_idle failed (%d)\n",
-			       (eax >> 8) & 0xff);
+			printk(KERN_DEBUG "apm_do_idle failed (%d)\n", err);
 			t = jiffies;
 		}
 		return -1;
@@ -816,9 +857,10 @@
 static void apm_do_busy(void)
 {
 	u32 dummy;
+	int err;
 
 	if (clock_slowed || ALWAYS_CALL_BUSY) {
-		(void)apm_bios_call_simple(APM_FUNC_BUSY, 0, 0, &dummy);
+		(void)apm_bios_call_simple(APM_FUNC_BUSY, 0, 0, &dummy, &err);
 		clock_slowed = 0;
 	}
 }
@@ -937,7 +979,7 @@
 
 	/* Some bioses don't like being called from CPU != 0 */
 	if (apm_info.realmode_power_off) {
-		(void)apm_save_cpus();
+		set_cpus_allowed_ptr(current, cpumask_of(0));
 		machine_real_restart(po_bios_call, sizeof(po_bios_call));
 	} else {
 		(void)set_system_power_state(APM_STATE_OFF);
@@ -956,12 +998,13 @@
 static int apm_enable_power_management(int enable)
 {
 	u32 eax;
+	int err;
 
 	if ((enable == 0) && (apm_info.bios.flags & APM_BIOS_DISENGAGED))
 		return APM_NOT_ENGAGED;
 	if (apm_bios_call_simple(APM_FUNC_ENABLE_PM, APM_DEVICE_BALL,
-				 enable, &eax))
-		return (eax >> 8) & 0xff;
+				 enable, &eax, &err))
+		return err;
 	if (enable)
 		apm_info.bios.flags &= ~APM_BIOS_DISABLED;
 	else
@@ -986,24 +1029,23 @@
 
 static int apm_get_power_status(u_short *status, u_short *bat, u_short *life)
 {
-	u32 eax;
-	u32 ebx;
-	u32 ecx;
-	u32 edx;
-	u32 dummy;
+	struct apm_bios_call call;
+
+	call.func = APM_FUNC_GET_STATUS;
+	call.ebx = APM_DEVICE_ALL;
+	call.ecx = 0;
 
 	if (apm_info.get_power_status_broken)
 		return APM_32_UNSUPPORTED;
-	if (apm_bios_call(APM_FUNC_GET_STATUS, APM_DEVICE_ALL, 0,
-			  &eax, &ebx, &ecx, &edx, &dummy))
-		return (eax >> 8) & 0xff;
-	*status = ebx;
-	*bat = ecx;
+	if (apm_bios_call(&call))
+		return call.err;
+	*status = call.ebx;
+	*bat = call.ecx;
 	if (apm_info.get_power_status_swabinminutes) {
-		*life = swab16((u16)edx);
+		*life = swab16((u16)call.edx);
 		*life |= 0x8000;
 	} else
-		*life = edx;
+		*life = call.edx;
 	return APM_SUCCESS;
 }
 
@@ -1048,12 +1090,14 @@
 static int apm_engage_power_management(u_short device, int enable)
 {
 	u32 eax;
+	int err;
 
 	if ((enable == 0) && (device == APM_DEVICE_ALL)
 	    && (apm_info.bios.flags & APM_BIOS_DISABLED))
 		return APM_DISABLED;
-	if (apm_bios_call_simple(APM_FUNC_ENGAGE_PM, device, enable, &eax))
-		return (eax >> 8) & 0xff;
+	if (apm_bios_call_simple(APM_FUNC_ENGAGE_PM, device, enable,
+				 &eax, &err))
+		return err;
 	if (device == APM_DEVICE_ALL) {
 		if (enable)
 			apm_info.bios.flags &= ~APM_BIOS_DISENGAGED;
@@ -1689,16 +1733,14 @@
 	char 		*power_stat;
 	char 		*bat_stat;
 
-#ifdef CONFIG_SMP
 	/* 2002/08/01 - WT
 	 * This is to avoid random crashes at boot time during initialization
 	 * on SMP systems in case of "apm=power-off" mode. Seen on ASUS A7M266D.
 	 * Some bioses don't like being called from CPU != 0.
 	 * Method suggested by Ingo Molnar.
 	 */
-	set_cpus_allowed(current, cpumask_of_cpu(0));
+	set_cpus_allowed_ptr(current, cpumask_of(0));
 	BUG_ON(smp_processor_id() != 0);
-#endif
 
 	if (apm_info.connection_version == 0) {
 		apm_info.connection_version = apm_info.bios.version;
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index e2962cc..c4f6678 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -41,8 +41,6 @@
 
 #include "cpu.h"
 
-#ifdef CONFIG_X86_64
-
 /* all of these masks are initialized in setup_cpu_local_masks() */
 cpumask_var_t cpu_initialized_mask;
 cpumask_var_t cpu_callout_mask;
@@ -60,16 +58,6 @@
 	alloc_bootmem_cpumask_var(&cpu_sibling_setup_mask);
 }
 
-#else /* CONFIG_X86_32 */
-
-cpumask_t cpu_sibling_setup_map;
-cpumask_t cpu_callout_map;
-cpumask_t cpu_initialized;
-cpumask_t cpu_callin_map;
-
-#endif /* CONFIG_X86_32 */
-
-
 static const struct cpu_dev *this_cpu __cpuinitdata;
 
 DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
@@ -859,6 +847,7 @@
 void __init identify_boot_cpu(void)
 {
 	identify_cpu(&boot_cpu_data);
+	init_c1e_mask();
 #ifdef CONFIG_X86_32
 	sysenter_setup();
 	enable_sep_cpu();
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
index 23da96e..19f6b9d 100644
--- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -33,7 +33,7 @@
 #include <linux/cpufreq.h>
 #include <linux/compiler.h>
 #include <linux/dmi.h>
-#include <linux/ftrace.h>
+#include <trace/power.h>
 
 #include <linux/acpi.h>
 #include <linux/io.h>
@@ -72,6 +72,8 @@
 
 static DEFINE_PER_CPU(struct acpi_cpufreq_data *, drv_data);
 
+DEFINE_TRACE(power_mark);
+
 /* acpi_perf_data is a pointer to percpu data. */
 static struct acpi_processor_performance *acpi_perf_data;
 
@@ -680,6 +682,18 @@
 			    perf->states[i].transition_latency * 1000;
 	}
 
+	/* Check for high latency (>20uS) from buggy BIOSes, like on T42 */
+	if (perf->control_register.space_id == ACPI_ADR_SPACE_FIXED_HARDWARE &&
+	    policy->cpuinfo.transition_latency > 20 * 1000) {
+		static int print_once;
+		policy->cpuinfo.transition_latency = 20 * 1000;
+		if (!print_once) {
+			print_once = 1;
+			printk(KERN_INFO "Capping off P-state tranision latency"
+				" at 20 uS\n");
+		}
+	}
+
 	data->max_freq = perf->states[0].core_frequency * 1000;
 	/* table init */
 	for (i = 0; i < perf->state_count; i++) {
diff --git a/arch/x86/kernel/cpu/cpufreq/longhaul.c b/arch/x86/kernel/cpu/cpufreq/longhaul.c
index f1c51ae..0bd48e6 100644
--- a/arch/x86/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/x86/kernel/cpu/cpufreq/longhaul.c
@@ -305,7 +305,7 @@
 		outb(3, 0x22);
 	} else if ((pr != NULL) && pr->flags.bm_control) {
 		/* Disable bus master arbitration */
-		acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
+		acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1);
 	}
 	switch (longhaul_version) {
 
@@ -328,7 +328,7 @@
 	case TYPE_POWERSAVER:
 		if (longhaul_flags & USE_ACPI_C3) {
 			/* Don't allow wakeup */
-			acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
+			acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
 			do_powersaver(cx->address, mults_index, dir);
 		} else {
 			do_powersaver(0, mults_index, dir);
@@ -341,7 +341,7 @@
 		outb(0, 0x22);
 	} else if ((pr != NULL) && pr->flags.bm_control) {
 		/* Enable bus master arbitration */
-		acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
+		acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0);
 	}
 	outb(pic2_mask, 0xA1);	/* restore mask */
 	outb(pic1_mask, 0x21);
diff --git a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
index 41ed949..6ac55bd 100644
--- a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
+++ b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
@@ -211,7 +211,7 @@
 	unsigned int i;
 
 #ifdef CONFIG_SMP
-	cpumask_copy(policy->cpus, &per_cpu(cpu_sibling_map, policy->cpu));
+	cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu));
 #endif
 
 	/* Errata workaround */
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
index a15ac94..4709ead 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
@@ -54,7 +54,10 @@
 static int cpu_family = CPU_OPTERON;
 
 #ifndef CONFIG_SMP
-DEFINE_PER_CPU(cpumask_t, cpu_core_map);
+static inline const struct cpumask *cpu_core_mask(int cpu)
+{
+	return cpumask_of(0);
+}
 #endif
 
 /* Return a frequency in MHz, given an input fid */
@@ -699,7 +702,7 @@
 
 	dprintk("cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid);
 	data->powernow_table = powernow_table;
-	if (first_cpu(per_cpu(cpu_core_map, data->cpu)) == data->cpu)
+	if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu)
 		print_basics(data);
 
 	for (j = 0; j < data->numps; j++)
@@ -862,7 +865,7 @@
 
 	/* fill in data */
 	data->numps = data->acpi_data.state_count;
-	if (first_cpu(per_cpu(cpu_core_map, data->cpu)) == data->cpu)
+	if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu)
 		print_basics(data);
 	powernow_k8_acpi_pst_values(data, 0);
 
@@ -1300,7 +1303,7 @@
 	if (cpu_family == CPU_HW_PSTATE)
 		cpumask_copy(pol->cpus, cpumask_of(pol->cpu));
 	else
-		cpumask_copy(pol->cpus, &per_cpu(cpu_core_map, pol->cpu));
+		cpumask_copy(pol->cpus, cpu_core_mask(pol->cpu));
 	data->available_cores = pol->cpus;
 
 	if (cpu_family == CPU_HW_PSTATE)
@@ -1365,7 +1368,7 @@
 	unsigned int khz = 0;
 	unsigned int first;
 
-	first = first_cpu(per_cpu(cpu_core_map, cpu));
+	first = cpumask_first(cpu_core_mask(cpu));
 	data = per_cpu(powernow_data, first);
 
 	if (!data)
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
index 8bbb11a..016c1a4 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
@@ -321,7 +321,7 @@
 
 	/* only run on CPU to be set, or on its sibling */
 #ifdef CONFIG_SMP
-	cpumask_copy(policy->cpus, &per_cpu(cpu_sibling_map, policy->cpu));
+	cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu));
 #endif
 
 	cpus_allowed = current->cpus_allowed;
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index c471eb1..483eda9 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -159,7 +159,7 @@
 	unsigned long can_disable;
 };
 
-#ifdef CONFIG_PCI
+#if defined(CONFIG_PCI) && defined(CONFIG_SYSFS)
 static struct pci_device_id k8_nb_id[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1103) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1203) },
@@ -324,15 +324,6 @@
 	return 0;
 }
 
-static int
-__cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
-{
-	struct _cpuid4_info_regs *leaf_regs =
-		(struct _cpuid4_info_regs *)this_leaf;
-
-	return cpuid4_cache_lookup_regs(index, leaf_regs);
-}
-
 static int __cpuinit find_num_cache_leaves(void)
 {
 	unsigned int		eax, ebx, ecx, edx;
@@ -508,6 +499,8 @@
 	return l2;
 }
 
+#ifdef CONFIG_SYSFS
+
 /* pointer to _cpuid4_info array (for each cache leaf) */
 static DEFINE_PER_CPU(struct _cpuid4_info *, cpuid4_info);
 #define CPUID4_INFO_IDX(x, y)	(&((per_cpu(cpuid4_info, x))[y]))
@@ -571,6 +564,15 @@
 	per_cpu(cpuid4_info, cpu) = NULL;
 }
 
+static int
+__cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
+{
+	struct _cpuid4_info_regs *leaf_regs =
+		(struct _cpuid4_info_regs *)this_leaf;
+
+	return cpuid4_cache_lookup_regs(index, leaf_regs);
+}
+
 static void __cpuinit get_cpu_leaves(void *_retval)
 {
 	int j, *retval = _retval, cpu = smp_processor_id();
@@ -612,8 +614,6 @@
 	return retval;
 }
 
-#ifdef CONFIG_SYSFS
-
 #include <linux/kobject.h>
 #include <linux/sysfs.h>
 
diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c
index ca14604..863f895 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_64.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_64.c
@@ -990,7 +990,7 @@
 	NULL
 };
 
-static cpumask_t mce_device_initialized = CPU_MASK_NONE;
+static cpumask_var_t mce_device_initialized;
 
 /* Per cpu sysdev init.  All of the cpus still share the same ctl bank */
 static __cpuinit int mce_create_device(unsigned int cpu)
@@ -1021,7 +1021,7 @@
 		if (err)
 			goto error2;
 	}
-	cpu_set(cpu, mce_device_initialized);
+	cpumask_set_cpu(cpu, mce_device_initialized);
 
 	return 0;
 error2:
@@ -1043,7 +1043,7 @@
 {
 	int i;
 
-	if (!cpu_isset(cpu, mce_device_initialized))
+	if (!cpumask_test_cpu(cpu, mce_device_initialized))
 		return;
 
 	for (i = 0; mce_attributes[i]; i++)
@@ -1053,7 +1053,7 @@
 		sysdev_remove_file(&per_cpu(device_mce, cpu),
 			&bank_attrs[i]);
 	sysdev_unregister(&per_cpu(device_mce,cpu));
-	cpu_clear(cpu, mce_device_initialized);
+	cpumask_clear_cpu(cpu, mce_device_initialized);
 }
 
 /* Make sure there are no machine checks on offlined CPUs. */
@@ -1162,6 +1162,8 @@
 	if (!mce_available(&boot_cpu_data))
 		return -EIO;
 
+	alloc_cpumask_var(&mce_device_initialized, GFP_KERNEL);
+
 	err = mce_init_banks();
 	if (err)
 		return err;
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c
index 7d01be8..56dde9c 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c
@@ -485,7 +485,7 @@
 
 #ifdef CONFIG_SMP
 	if (cpu_data(cpu).cpu_core_id && shared_bank[bank]) {	/* symlink */
-		i = cpumask_first(&per_cpu(cpu_core_map, cpu));
+		i = cpumask_first(cpu_core_mask(cpu));
 
 		/* first core not up yet */
 		if (cpu_data(i).cpu_core_id)
@@ -505,7 +505,7 @@
 		if (err)
 			goto out;
 
-		cpumask_copy(b->cpus, &per_cpu(cpu_core_map, cpu));
+		cpumask_copy(b->cpus, cpu_core_mask(cpu));
 		per_cpu(threshold_banks, cpu)[bank] = b;
 		goto out;
 	}
@@ -529,7 +529,7 @@
 #ifndef CONFIG_SMP
 	cpumask_setall(b->cpus);
 #else
-	cpumask_copy(b->cpus, &per_cpu(cpu_core_map, cpu));
+	cpumask_copy(b->cpus, cpu_core_mask(cpu));
 #endif
 
 	per_cpu(threshold_banks, cpu)[bank] = b;
diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c
index 57df3d3..d6b72df 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c
@@ -249,7 +249,7 @@
 	for_each_online_cpu (cpu) {
 		if (cpu == dying)
 			continue;
-		if (set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu)))
+		if (set_cpus_allowed_ptr(current, cpumask_of(cpu)))
 			continue;
 		/* Recheck banks in case CPUs don't all have the same */
 		if (cmci_supported(&banks))
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
index 37f28fc..0b776c0 100644
--- a/arch/x86/kernel/cpu/mtrr/generic.c
+++ b/arch/x86/kernel/cpu/mtrr/generic.c
@@ -462,9 +462,6 @@
 	*base = base_hi << (32 - PAGE_SHIFT) | base_lo >> PAGE_SHIFT;
 	*type = base_lo & 0xff;
 
-	printk(KERN_DEBUG "  get_mtrr: cpu%d reg%02d base=%010lx size=%010lx %s\n",
-			cpu, reg, *base, *size,
-			mtrr_attrib_to_str(*type & 0xff));
 out_put_cpu:
 	put_cpu();
 }
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
index d67e0e4..f93047fe 100644
--- a/arch/x86/kernel/cpu/proc.c
+++ b/arch/x86/kernel/cpu/proc.c
@@ -14,7 +14,7 @@
 	if (c->x86_max_cores * smp_num_siblings > 1) {
 		seq_printf(m, "physical id\t: %d\n", c->phys_proc_id);
 		seq_printf(m, "siblings\t: %d\n",
-			   cpus_weight(per_cpu(cpu_core_map, cpu)));
+			   cpumask_weight(cpu_sibling_mask(cpu)));
 		seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id);
 		seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
 		seq_printf(m, "apicid\t\t: %d\n", c->apicid);
@@ -143,9 +143,9 @@
 static void *c_start(struct seq_file *m, loff_t *pos)
 {
 	if (*pos == 0)	/* just in case, cpu 0 is not the first */
-		*pos = first_cpu(cpu_online_map);
+		*pos = cpumask_first(cpu_online_mask);
 	else
-		*pos = next_cpu_nr(*pos - 1, cpu_online_map);
+		*pos = cpumask_next(*pos - 1, cpu_online_mask);
 	if ((*pos) < nr_cpu_ids)
 		return &cpu_data(*pos);
 	return NULL;
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
index dd2130b..95ea5fa 100644
--- a/arch/x86/kernel/dumpstack.c
+++ b/arch/x86/kernel/dumpstack.c
@@ -15,6 +15,7 @@
 #include <linux/bug.h>
 #include <linux/nmi.h>
 #include <linux/sysfs.h>
+#include <linux/ftrace.h>
 
 #include <asm/stacktrace.h>
 
@@ -196,6 +197,11 @@
 	int cpu;
 	unsigned long flags;
 
+	/* notify the hw-branch tracer so it may disable tracing and
+	   add the last trace to the trace buffer -
+	   the earlier this happens, the more useful the trace. */
+	trace_hw_branch_oops();
+
 	oops_enter();
 
 	/* racy, but better than risking deadlock. */
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
index 76f7141..61df775 100644
--- a/arch/x86/kernel/ftrace.c
+++ b/arch/x86/kernel/ftrace.c
@@ -18,6 +18,7 @@
 #include <linux/init.h>
 #include <linux/list.h>
 
+#include <asm/cacheflush.h>
 #include <asm/ftrace.h>
 #include <linux/ftrace.h>
 #include <asm/nops.h>
@@ -26,6 +27,18 @@
 
 #ifdef CONFIG_DYNAMIC_FTRACE
 
+int ftrace_arch_code_modify_prepare(void)
+{
+	set_kernel_text_rw();
+	return 0;
+}
+
+int ftrace_arch_code_modify_post_process(void)
+{
+	set_kernel_text_ro();
+	return 0;
+}
+
 union ftrace_code_union {
 	char code[MCOUNT_INSN_SIZE];
 	struct {
@@ -66,11 +79,11 @@
  *
  * 1) Put the instruction pointer into the IP buffer
  *    and the new code into the "code" buffer.
- * 2) Set a flag that says we are modifying code
- * 3) Wait for any running NMIs to finish.
- * 4) Write the code
- * 5) clear the flag.
- * 6) Wait for any running NMIs to finish.
+ * 2) Wait for any running NMIs to finish and set a flag that says
+ *    we are modifying code, it is done in an atomic operation.
+ * 3) Write the code
+ * 4) clear the flag.
+ * 5) Wait for any running NMIs to finish.
  *
  * If an NMI is executed, the first thing it does is to call
  * "ftrace_nmi_enter". This will check if the flag is set to write
@@ -82,9 +95,9 @@
  * are the same as what exists.
  */
 
-static atomic_t in_nmi = ATOMIC_INIT(0);
+#define MOD_CODE_WRITE_FLAG (1 << 31)	/* set when NMI should do the write */
+static atomic_t nmi_running = ATOMIC_INIT(0);
 static int mod_code_status;		/* holds return value of text write */
-static int mod_code_write;		/* set when NMI should do the write */
 static void *mod_code_ip;		/* holds the IP to write to */
 static void *mod_code_newcode;		/* holds the text to write to the IP */
 
@@ -101,6 +114,20 @@
 	return r;
 }
 
+static void clear_mod_flag(void)
+{
+	int old = atomic_read(&nmi_running);
+
+	for (;;) {
+		int new = old & ~MOD_CODE_WRITE_FLAG;
+
+		if (old == new)
+			break;
+
+		old = atomic_cmpxchg(&nmi_running, old, new);
+	}
+}
+
 static void ftrace_mod_code(void)
 {
 	/*
@@ -111,37 +138,52 @@
 	 */
 	mod_code_status = probe_kernel_write(mod_code_ip, mod_code_newcode,
 					     MCOUNT_INSN_SIZE);
+
+	/* if we fail, then kill any new writers */
+	if (mod_code_status)
+		clear_mod_flag();
 }
 
 void ftrace_nmi_enter(void)
 {
-	atomic_inc(&in_nmi);
-	/* Must have in_nmi seen before reading write flag */
-	smp_mb();
-	if (mod_code_write) {
+	if (atomic_inc_return(&nmi_running) & MOD_CODE_WRITE_FLAG) {
+		smp_rmb();
 		ftrace_mod_code();
 		atomic_inc(&nmi_update_count);
 	}
+	/* Must have previous changes seen before executions */
+	smp_mb();
 }
 
 void ftrace_nmi_exit(void)
 {
-	/* Finish all executions before clearing in_nmi */
-	smp_wmb();
-	atomic_dec(&in_nmi);
+	/* Finish all executions before clearing nmi_running */
+	smp_mb();
+	atomic_dec(&nmi_running);
+}
+
+static void wait_for_nmi_and_set_mod_flag(void)
+{
+	if (!atomic_cmpxchg(&nmi_running, 0, MOD_CODE_WRITE_FLAG))
+		return;
+
+	do {
+		cpu_relax();
+	} while (atomic_cmpxchg(&nmi_running, 0, MOD_CODE_WRITE_FLAG));
+
+	nmi_wait_count++;
 }
 
 static void wait_for_nmi(void)
 {
-	int waited = 0;
+	if (!atomic_read(&nmi_running))
+		return;
 
-	while (atomic_read(&in_nmi)) {
-		waited = 1;
+	do {
 		cpu_relax();
-	}
+	} while (atomic_read(&nmi_running));
 
-	if (waited)
-		nmi_wait_count++;
+	nmi_wait_count++;
 }
 
 static int
@@ -151,14 +193,9 @@
 	mod_code_newcode = new_code;
 
 	/* The buffers need to be visible before we let NMIs write them */
-	smp_wmb();
-
-	mod_code_write = 1;
-
-	/* Make sure write bit is visible before we wait on NMIs */
 	smp_mb();
 
-	wait_for_nmi();
+	wait_for_nmi_and_set_mod_flag();
 
 	/* Make sure all running NMIs have finished before we write the code */
 	smp_mb();
@@ -166,13 +203,9 @@
 	ftrace_mod_code();
 
 	/* Make sure the write happens before clearing the bit */
-	smp_wmb();
-
-	mod_code_write = 0;
-
-	/* make sure NMIs see the cleared bit */
 	smp_mb();
 
+	clear_mod_flag();
 	wait_for_nmi();
 
 	return mod_code_status;
@@ -368,25 +401,6 @@
 	return ftrace_mod_jmp(ip, old_offset, new_offset);
 }
 
-#else /* CONFIG_DYNAMIC_FTRACE */
-
-/*
- * These functions are picked from those used on
- * this page for dynamic ftrace. They have been
- * simplified to ignore all traces in NMI context.
- */
-static atomic_t in_nmi;
-
-void ftrace_nmi_enter(void)
-{
-	atomic_inc(&in_nmi);
-}
-
-void ftrace_nmi_exit(void)
-{
-	atomic_dec(&in_nmi);
-}
-
 #endif /* !CONFIG_DYNAMIC_FTRACE */
 
 /*
@@ -396,14 +410,13 @@
 void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
 {
 	unsigned long old;
-	unsigned long long calltime;
 	int faulted;
 	struct ftrace_graph_ent trace;
 	unsigned long return_hooker = (unsigned long)
 				&return_to_handler;
 
 	/* Nmi's are currently unsupported */
-	if (unlikely(atomic_read(&in_nmi)))
+	if (unlikely(in_nmi()))
 		return;
 
 	if (unlikely(atomic_read(&current->tracing_graph_pause)))
@@ -439,17 +452,7 @@
 		return;
 	}
 
-	if (unlikely(!__kernel_text_address(old))) {
-		ftrace_graph_stop();
-		*parent = old;
-		WARN_ON(1);
-		return;
-	}
-
-	calltime = cpu_clock(raw_smp_processor_id());
-
-	if (ftrace_push_return_trace(old, calltime,
-				self_addr, &trace.depth) == -EBUSY) {
+	if (ftrace_push_return_trace(old, self_addr, &trace.depth) == -EBUSY) {
 		*parent = old;
 		return;
 	}
@@ -463,3 +466,66 @@
 	}
 }
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
+#ifdef CONFIG_FTRACE_SYSCALLS
+
+extern unsigned long __start_syscalls_metadata[];
+extern unsigned long __stop_syscalls_metadata[];
+extern unsigned long *sys_call_table;
+
+static struct syscall_metadata **syscalls_metadata;
+
+static struct syscall_metadata *find_syscall_meta(unsigned long *syscall)
+{
+	struct syscall_metadata *start;
+	struct syscall_metadata *stop;
+	char str[KSYM_SYMBOL_LEN];
+
+
+	start = (struct syscall_metadata *)__start_syscalls_metadata;
+	stop = (struct syscall_metadata *)__stop_syscalls_metadata;
+	kallsyms_lookup((unsigned long) syscall, NULL, NULL, NULL, str);
+
+	for ( ; start < stop; start++) {
+		if (start->name && !strcmp(start->name, str))
+			return start;
+	}
+	return NULL;
+}
+
+struct syscall_metadata *syscall_nr_to_meta(int nr)
+{
+	if (!syscalls_metadata || nr >= FTRACE_SYSCALL_MAX || nr < 0)
+		return NULL;
+
+	return syscalls_metadata[nr];
+}
+
+void arch_init_ftrace_syscalls(void)
+{
+	int i;
+	struct syscall_metadata *meta;
+	unsigned long **psys_syscall_table = &sys_call_table;
+	static atomic_t refs;
+
+	if (atomic_inc_return(&refs) != 1)
+		goto end;
+
+	syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) *
+					FTRACE_SYSCALL_MAX, GFP_KERNEL);
+	if (!syscalls_metadata) {
+		WARN_ON(1);
+		return;
+	}
+
+	for (i = 0; i < FTRACE_SYSCALL_MAX; i++) {
+		meta = find_syscall_meta(psys_syscall_table[i]);
+		syscalls_metadata[i] = meta;
+	}
+	return;
+
+	/* Paranoid: avoid overflow */
+end:
+	atomic_dec(&refs);
+}
+#endif
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
index 55b9461..7b5169d 100644
--- a/arch/x86/kernel/kprobes.c
+++ b/arch/x86/kernel/kprobes.c
@@ -638,13 +638,13 @@
 #else
 			"	pushf\n"
 			/*
-			 * Skip cs, ip, orig_ax.
+			 * Skip cs, ip, orig_ax and gs.
 			 * trampoline_handler() will plug in these values
 			 */
-			"	subl $12, %esp\n"
+			"	subl $16, %esp\n"
 			"	pushl %fs\n"
-			"	pushl %ds\n"
 			"	pushl %es\n"
+			"	pushl %ds\n"
 			"	pushl %eax\n"
 			"	pushl %ebp\n"
 			"	pushl %edi\n"
@@ -655,10 +655,10 @@
 			"	movl %esp, %eax\n"
 			"	call trampoline_handler\n"
 			/* Move flags to cs */
-			"	movl 52(%esp), %edx\n"
-			"	movl %edx, 48(%esp)\n"
+			"	movl 56(%esp), %edx\n"
+			"	movl %edx, 52(%esp)\n"
 			/* Replace saved flags with true return address. */
-			"	movl %eax, 52(%esp)\n"
+			"	movl %eax, 56(%esp)\n"
 			"	popl %ebx\n"
 			"	popl %ecx\n"
 			"	popl %edx\n"
@@ -666,8 +666,8 @@
 			"	popl %edi\n"
 			"	popl %ebp\n"
 			"	popl %eax\n"
-			/* Skip ip, orig_ax, es, ds, fs */
-			"	addl $20, %esp\n"
+			/* Skip ds, es, fs, gs, orig_ax and ip */
+			"	addl $24, %esp\n"
 			"	popf\n"
 #endif
 			"	ret\n");
@@ -691,6 +691,7 @@
 	regs->cs = __KERNEL_CS;
 #else
 	regs->cs = __KERNEL_CS | get_kernel_rpl();
+	regs->gs = 0;
 #endif
 	regs->ip = trampoline_address;
 	regs->orig_ax = ~0UL;
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c
index c25fdb3..453b579 100644
--- a/arch/x86/kernel/microcode_amd.c
+++ b/arch/x86/kernel/microcode_amd.c
@@ -12,31 +12,30 @@
  *
  *  Licensed under the terms of the GNU General Public
  *  License version 2. See file COPYING for details.
-*/
-
-#include <linux/capability.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/cpumask.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/miscdevice.h>
-#include <linux/spinlock.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
-#include <linux/mutex.h>
-#include <linux/cpu.h>
-#include <linux/firmware.h>
+ */
 #include <linux/platform_device.h>
-#include <linux/pci.h>
+#include <linux/capability.h>
+#include <linux/miscdevice.h>
+#include <linux/firmware.h>
+#include <linux/spinlock.h>
+#include <linux/cpumask.h>
 #include <linux/pci_ids.h>
 #include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/cpu.h>
+#include <linux/pci.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
 
-#include <asm/msr.h>
-#include <asm/processor.h>
 #include <asm/microcode.h>
+#include <asm/processor.h>
+#include <asm/msr.h>
 
 MODULE_DESCRIPTION("AMD Microcode Update Driver");
 MODULE_AUTHOR("Peter Oruba");
@@ -72,8 +71,8 @@
 } __attribute__((packed));
 
 struct microcode_amd {
-	struct microcode_header_amd hdr;
-	unsigned int mpb[0];
+	struct microcode_header_amd	hdr;
+	unsigned int			mpb[0];
 };
 
 #define UCODE_MAX_SIZE			2048
@@ -184,8 +183,8 @@
 	return 0;
 }
 
-static void *get_next_ucode(const u8 *buf, unsigned int size,
-			    unsigned int *mc_size)
+static void *
+get_next_ucode(const u8 *buf, unsigned int size, unsigned int *mc_size)
 {
 	unsigned int total_size;
 	u8 section_hdr[UCODE_CONTAINER_SECTION_HDR];
@@ -223,7 +222,6 @@
 	return mc;
 }
 
-
 static int install_equiv_cpu_table(const u8 *buf)
 {
 	u8 *container_hdr[UCODE_CONTAINER_HEADER_SIZE];
@@ -372,4 +370,3 @@
 {
 	return &microcode_amd_ops;
 }
-
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c
index c9b721b..a0f3851 100644
--- a/arch/x86/kernel/microcode_core.c
+++ b/arch/x86/kernel/microcode_core.c
@@ -70,67 +70,78 @@
  *		Fix sigmatch() macro to handle old CPUs with pf == 0.
  *		Thanks to Stuart Swales for pointing out this bug.
  */
-#include <linux/capability.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/smp_lock.h>
-#include <linux/cpumask.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/miscdevice.h>
-#include <linux/spinlock.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
-#include <linux/mutex.h>
-#include <linux/cpu.h>
-#include <linux/firmware.h>
 #include <linux/platform_device.h>
+#include <linux/capability.h>
+#include <linux/miscdevice.h>
+#include <linux/firmware.h>
+#include <linux/smp_lock.h>
+#include <linux/spinlock.h>
+#include <linux/cpumask.h>
+#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/cpu.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
 
-#include <asm/msr.h>
-#include <asm/uaccess.h>
-#include <asm/processor.h>
 #include <asm/microcode.h>
+#include <asm/processor.h>
+#include <asm/msr.h>
 
 MODULE_DESCRIPTION("Microcode Update Driver");
 MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
 MODULE_LICENSE("GPL");
 
-#define MICROCODE_VERSION 	"2.00"
+#define MICROCODE_VERSION	"2.00"
 
-static struct microcode_ops *microcode_ops;
+static struct microcode_ops	*microcode_ops;
 
 /* no concurrent ->write()s are allowed on /dev/cpu/microcode */
 static DEFINE_MUTEX(microcode_mutex);
 
-struct ucode_cpu_info ucode_cpu_info[NR_CPUS];
+struct ucode_cpu_info		ucode_cpu_info[NR_CPUS];
 EXPORT_SYMBOL_GPL(ucode_cpu_info);
 
 #ifdef CONFIG_MICROCODE_OLD_INTERFACE
+struct update_for_cpu {
+	const void __user	*buf;
+	size_t			size;
+};
+
+static long update_for_cpu(void *_ufc)
+{
+	struct update_for_cpu *ufc = _ufc;
+	int error;
+
+	error = microcode_ops->request_microcode_user(smp_processor_id(),
+						      ufc->buf, ufc->size);
+	if (error < 0)
+		return error;
+	if (!error)
+		microcode_ops->apply_microcode(smp_processor_id());
+	return error;
+}
+
 static int do_microcode_update(const void __user *buf, size_t size)
 {
-	cpumask_t old;
 	int error = 0;
 	int cpu;
-
-	old = current->cpus_allowed;
+	struct update_for_cpu ufc = { .buf = buf, .size = size };
 
 	for_each_online_cpu(cpu) {
 		struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
 
 		if (!uci->valid)
 			continue;
-
-		set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu));
-		error = microcode_ops->request_microcode_user(cpu, buf, size);
+		error = work_on_cpu(cpu, update_for_cpu, &ufc);
 		if (error < 0)
-			goto out;
-		if (!error)
-			microcode_ops->apply_microcode(cpu);
+			break;
 	}
-out:
-	set_cpus_allowed_ptr(current, &old);
 	return error;
 }
 
@@ -198,18 +209,33 @@
 
 MODULE_ALIAS_MISCDEV(MICROCODE_MINOR);
 #else
-#define microcode_dev_init() 0
-#define microcode_dev_exit() do { } while (0)
+#define microcode_dev_init()	0
+#define microcode_dev_exit()	do { } while (0)
 #endif
 
 /* fake device for request_firmware */
-static struct platform_device *microcode_pdev;
+static struct platform_device	*microcode_pdev;
+
+static long reload_for_cpu(void *unused)
+{
+	struct ucode_cpu_info *uci = ucode_cpu_info + smp_processor_id();
+	int err = 0;
+
+	mutex_lock(&microcode_mutex);
+	if (uci->valid) {
+		err = microcode_ops->request_microcode_fw(smp_processor_id(),
+							  &microcode_pdev->dev);
+		if (!err)
+			microcode_ops->apply_microcode(smp_processor_id());
+	}
+	mutex_unlock(&microcode_mutex);
+	return err;
+}
 
 static ssize_t reload_store(struct sys_device *dev,
 			    struct sysdev_attribute *attr,
 			    const char *buf, size_t sz)
 {
-	struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
 	char *end;
 	unsigned long val = simple_strtoul(buf, &end, 0);
 	int err = 0;
@@ -218,21 +244,9 @@
 	if (end == buf)
 		return -EINVAL;
 	if (val == 1) {
-		cpumask_t old = current->cpus_allowed;
-
 		get_online_cpus();
-		if (cpu_online(cpu)) {
-			set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu));
-			mutex_lock(&microcode_mutex);
-			if (uci->valid) {
-				err = microcode_ops->request_microcode_fw(cpu,
-						&microcode_pdev->dev);
-				if (!err)
-					microcode_ops->apply_microcode(cpu);
-			}
-			mutex_unlock(&microcode_mutex);
-			set_cpus_allowed_ptr(current, &old);
-		}
+		if (cpu_online(cpu))
+			err = work_on_cpu(cpu, reload_for_cpu, NULL);
 		put_online_cpus();
 	}
 	if (err)
@@ -268,8 +282,8 @@
 };
 
 static struct attribute_group mc_attr_group = {
-	.attrs = mc_default_attrs,
-	.name = "microcode",
+	.attrs		= mc_default_attrs,
+	.name		= "microcode",
 };
 
 static void __microcode_fini_cpu(int cpu)
@@ -328,9 +342,9 @@
 	return 0;
 }
 
-static void microcode_update_cpu(int cpu)
+static long microcode_update_cpu(void *unused)
 {
-	struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
+	struct ucode_cpu_info *uci = ucode_cpu_info + smp_processor_id();
 	int err = 0;
 
 	/*
@@ -338,30 +352,27 @@
 	 * otherwise just request a firmware:
 	 */
 	if (uci->valid) {
-		err = microcode_resume_cpu(cpu);
-	} else {	
-		collect_cpu_info(cpu);
+		err = microcode_resume_cpu(smp_processor_id());
+	} else {
+		collect_cpu_info(smp_processor_id());
 		if (uci->valid && system_state == SYSTEM_RUNNING)
-			err = microcode_ops->request_microcode_fw(cpu,
+			err = microcode_ops->request_microcode_fw(
+					smp_processor_id(),
 					&microcode_pdev->dev);
 	}
 	if (!err)
-		microcode_ops->apply_microcode(cpu);
+		microcode_ops->apply_microcode(smp_processor_id());
+	return err;
 }
 
-static void microcode_init_cpu(int cpu)
+static int microcode_init_cpu(int cpu)
 {
-	cpumask_t old = current->cpus_allowed;
-
-	set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu));
-	/* We should bind the task to the CPU */
-	BUG_ON(raw_smp_processor_id() != cpu);
-
+	int err;
 	mutex_lock(&microcode_mutex);
-	microcode_update_cpu(cpu);
+	err = work_on_cpu(cpu, microcode_update_cpu, NULL);
 	mutex_unlock(&microcode_mutex);
 
-	set_cpus_allowed_ptr(current, &old);
+	return err;
 }
 
 static int mc_sysdev_add(struct sys_device *sys_dev)
@@ -379,8 +390,11 @@
 	if (err)
 		return err;
 
-	microcode_init_cpu(cpu);
-	return 0;
+	err = microcode_init_cpu(cpu);
+	if (err)
+		sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);
+
+	return err;
 }
 
 static int mc_sysdev_remove(struct sys_device *sys_dev)
@@ -404,14 +418,14 @@
 		return 0;
 
 	/* only CPU 0 will apply ucode here */
-	microcode_update_cpu(0);
+	microcode_update_cpu(NULL);
 	return 0;
 }
 
 static struct sysdev_driver mc_sysdev_driver = {
-	.add = mc_sysdev_add,
-	.remove = mc_sysdev_remove,
-	.resume = mc_sysdev_resume,
+	.add		= mc_sysdev_add,
+	.remove		= mc_sysdev_remove,
+	.resume		= mc_sysdev_resume,
 };
 
 static __cpuinit int
@@ -424,7 +438,9 @@
 	switch (action) {
 	case CPU_ONLINE:
 	case CPU_ONLINE_FROZEN:
-		microcode_init_cpu(cpu);
+		if (microcode_init_cpu(cpu))
+			printk(KERN_ERR "microcode: failed to init CPU%d\n",
+			       cpu);
 	case CPU_DOWN_FAILED:
 	case CPU_DOWN_FAILED_FROZEN:
 		pr_debug("microcode: CPU%d added\n", cpu);
@@ -448,7 +464,7 @@
 }
 
 static struct notifier_block __refdata mc_cpu_notifier = {
-	.notifier_call = mc_cpu_callback,
+	.notifier_call	= mc_cpu_callback,
 };
 
 static int __init microcode_init(void)
diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c
index 5e9f4fc..149b9ec 100644
--- a/arch/x86/kernel/microcode_intel.c
+++ b/arch/x86/kernel/microcode_intel.c
@@ -70,28 +70,28 @@
  *		Fix sigmatch() macro to handle old CPUs with pf == 0.
  *		Thanks to Stuart Swales for pointing out this bug.
  */
-#include <linux/capability.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/smp_lock.h>
-#include <linux/cpumask.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/miscdevice.h>
-#include <linux/spinlock.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
-#include <linux/mutex.h>
-#include <linux/cpu.h>
-#include <linux/firmware.h>
 #include <linux/platform_device.h>
+#include <linux/capability.h>
+#include <linux/miscdevice.h>
+#include <linux/firmware.h>
+#include <linux/smp_lock.h>
+#include <linux/spinlock.h>
+#include <linux/cpumask.h>
 #include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/cpu.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
 
-#include <asm/msr.h>
-#include <asm/processor.h>
 #include <asm/microcode.h>
+#include <asm/processor.h>
+#include <asm/msr.h>
 
 MODULE_DESCRIPTION("Microcode Update Driver");
 MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
@@ -129,12 +129,13 @@
 	struct extended_signature sigs[0];
 };
 
-#define DEFAULT_UCODE_DATASIZE 	(2000)
+#define DEFAULT_UCODE_DATASIZE	(2000)
 #define MC_HEADER_SIZE		(sizeof(struct microcode_header_intel))
 #define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE)
 #define EXT_HEADER_SIZE		(sizeof(struct extended_sigtable))
 #define EXT_SIGNATURE_SIZE	(sizeof(struct extended_signature))
 #define DWSIZE			(sizeof(u32))
+
 #define get_totalsize(mc) \
 	(((struct microcode_intel *)mc)->hdr.totalsize ? \
 	 ((struct microcode_intel *)mc)->hdr.totalsize : \
@@ -197,30 +198,31 @@
 }
 
 static inline int
-update_match_revision(struct microcode_header_intel *mc_header,	int rev)
+update_match_revision(struct microcode_header_intel *mc_header, int rev)
 {
 	return (mc_header->rev <= rev) ? 0 : 1;
 }
 
 static int microcode_sanity_check(void *mc)
 {
+	unsigned long total_size, data_size, ext_table_size;
 	struct microcode_header_intel *mc_header = mc;
 	struct extended_sigtable *ext_header = NULL;
-	struct extended_signature *ext_sig;
-	unsigned long total_size, data_size, ext_table_size;
 	int sum, orig_sum, ext_sigcount = 0, i;
+	struct extended_signature *ext_sig;
 
 	total_size = get_totalsize(mc_header);
 	data_size = get_datasize(mc_header);
+
 	if (data_size + MC_HEADER_SIZE > total_size) {
 		printk(KERN_ERR "microcode: error! "
-			"Bad data size in microcode data file\n");
+				"Bad data size in microcode data file\n");
 		return -EINVAL;
 	}
 
 	if (mc_header->ldrver != 1 || mc_header->hdrver != 1) {
 		printk(KERN_ERR "microcode: error! "
-			"Unknown microcode update format\n");
+				"Unknown microcode update format\n");
 		return -EINVAL;
 	}
 	ext_table_size = total_size - (MC_HEADER_SIZE + data_size);
@@ -318,11 +320,15 @@
 
 static void apply_microcode(int cpu)
 {
+	struct microcode_intel *mc_intel;
+	struct ucode_cpu_info *uci;
 	unsigned long flags;
 	unsigned int val[2];
-	int cpu_num = raw_smp_processor_id();
-	struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
-	struct microcode_intel *mc_intel = uci->mc;
+	int cpu_num;
+
+	cpu_num = raw_smp_processor_id();
+	uci = ucode_cpu_info + cpu;
+	mc_intel = uci->mc;
 
 	/* We should bind the task to the CPU */
 	BUG_ON(cpu_num != cpu);
@@ -348,15 +354,17 @@
 	spin_unlock_irqrestore(&microcode_update_lock, flags);
 	if (val[1] != mc_intel->hdr.rev) {
 		printk(KERN_ERR "microcode: CPU%d update from revision "
-			"0x%x to 0x%x failed\n", cpu_num, uci->cpu_sig.rev, val[1]);
+				"0x%x to 0x%x failed\n",
+			cpu_num, uci->cpu_sig.rev, val[1]);
 		return;
 	}
 	printk(KERN_INFO "microcode: CPU%d updated from revision "
-	       "0x%x to 0x%x, date = %04x-%02x-%02x \n",
+			 "0x%x to 0x%x, date = %04x-%02x-%02x \n",
 		cpu_num, uci->cpu_sig.rev, val[1],
 		mc_intel->hdr.date & 0xffff,
 		mc_intel->hdr.date >> 24,
 		(mc_intel->hdr.date >> 16) & 0xff);
+
 	uci->cpu_sig.rev = val[1];
 }
 
@@ -404,18 +412,23 @@
 		leftover  -= mc_size;
 	}
 
-	if (new_mc) {
-		if (!leftover) {
-			if (uci->mc)
-				vfree(uci->mc);
-			uci->mc = (struct microcode_intel *)new_mc;
-			pr_debug("microcode: CPU%d found a matching microcode update with"
-				 " version 0x%x (current=0x%x)\n",
-				cpu, new_rev, uci->cpu_sig.rev);
-		} else
-			vfree(new_mc);
+	if (!new_mc)
+		goto out;
+
+	if (leftover) {
+		vfree(new_mc);
+		goto out;
 	}
 
+	if (uci->mc)
+		vfree(uci->mc);
+	uci->mc = (struct microcode_intel *)new_mc;
+
+	pr_debug("microcode: CPU%d found a matching microcode update with"
+		 " version 0x%x (current=0x%x)\n",
+			cpu, new_rev, uci->cpu_sig.rev);
+
+ out:
 	return (int)leftover;
 }
 
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 156f8758..ca98915 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -8,7 +8,7 @@
 #include <linux/module.h>
 #include <linux/pm.h>
 #include <linux/clockchips.h>
-#include <linux/ftrace.h>
+#include <trace/power.h>
 #include <asm/system.h>
 #include <asm/apic.h>
 #include <asm/idle.h>
@@ -22,6 +22,9 @@
 
 struct kmem_cache *task_xstate_cachep;
 
+DEFINE_TRACE(power_start);
+DEFINE_TRACE(power_end);
+
 int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
 {
 	*dst = *src;
@@ -325,7 +328,7 @@
 	/*
 	 * Remove this CPU:
 	 */
-	cpu_clear(smp_processor_id(), cpu_online_map);
+	set_cpu_online(smp_processor_id(), false);
 	disable_local_APIC();
 
 	for (;;) {
@@ -475,12 +478,13 @@
 	return 1;
 }
 
-static cpumask_t c1e_mask = CPU_MASK_NONE;
+static cpumask_var_t c1e_mask;
 static int c1e_detected;
 
 void c1e_remove_cpu(int cpu)
 {
-	cpu_clear(cpu, c1e_mask);
+	if (c1e_mask != NULL)
+		cpumask_clear_cpu(cpu, c1e_mask);
 }
 
 /*
@@ -509,8 +513,8 @@
 	if (c1e_detected) {
 		int cpu = smp_processor_id();
 
-		if (!cpu_isset(cpu, c1e_mask)) {
-			cpu_set(cpu, c1e_mask);
+		if (!cpumask_test_cpu(cpu, c1e_mask)) {
+			cpumask_set_cpu(cpu, c1e_mask);
 			/*
 			 * Force broadcast so ACPI can not interfere. Needs
 			 * to run with interrupts enabled as it uses
@@ -562,6 +566,15 @@
 		pm_idle = default_idle;
 }
 
+void __init init_c1e_mask(void)
+{
+	/* If we're using c1e_idle, we need to allocate c1e_mask. */
+	if (pm_idle == c1e_idle) {
+		alloc_cpumask_var(&c1e_mask, GFP_KERNEL);
+		cpumask_clear(c1e_mask);
+	}
+}
+
 static int __init idle_setup(char *str)
 {
 	if (!str)
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index b7cc21b..fe9345c 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -21,6 +21,7 @@
 #include <linux/audit.h>
 #include <linux/seccomp.h>
 #include <linux/signal.h>
+#include <linux/ftrace.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -1415,6 +1416,9 @@
 	    tracehook_report_syscall_entry(regs))
 		ret = -1L;
 
+	if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE)))
+		ftrace_syscall_enter(regs);
+
 	if (unlikely(current->audit_context)) {
 		if (IS_IA32)
 			audit_syscall_entry(AUDIT_ARCH_I386,
@@ -1438,6 +1442,9 @@
 	if (unlikely(current->audit_context))
 		audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax);
 
+	if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE)))
+		ftrace_syscall_exit(regs);
+
 	if (test_thread_flag(TIF_SYSCALL_TRACE))
 		tracehook_report_syscall_exit(regs, 0);
 
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index 400331b..3a97a4c 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -153,7 +153,6 @@
 static ssize_t __init setup_pcpu_remap(size_t static_size)
 {
 	static struct vm_struct vm;
-	pg_data_t *last;
 	size_t ptrs_size, dyn_size;
 	unsigned int cpu;
 	ssize_t ret;
@@ -162,22 +161,9 @@
 	 * If large page isn't supported, there's no benefit in doing
 	 * this.  Also, on non-NUMA, embedding is better.
 	 */
-	if (!cpu_has_pse || pcpu_need_numa())
+	if (!cpu_has_pse || !pcpu_need_numa())
 		return -EINVAL;
 
-	last = NULL;
-	for_each_possible_cpu(cpu) {
-		int node = early_cpu_to_node(cpu);
-
-		if (node_online(node) && NODE_DATA(node) &&
-		    last && last != NODE_DATA(node))
-			goto proceed;
-
-		last = NODE_DATA(node);
-	}
-	return -EINVAL;
-
-proceed:
 	/*
 	 * Currently supports only single page.  Supporting multiple
 	 * pages won't be too difficult if it ever becomes necessary.
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index dfcc74a..1442516 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -221,7 +221,7 @@
 	if (!onsigstack) {
 		/* This is the X/Open sanctioned signal stack switching.  */
 		if (ka->sa.sa_flags & SA_ONSTACK) {
-			if (sas_ss_flags(sp) == 0)
+			if (current->sas_ss_size)
 				sp = current->sas_ss_sp + current->sas_ss_size;
 		} else {
 #ifdef CONFIG_X86_32
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index ef7d101..58d24ef 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -101,11 +101,11 @@
 DEFINE_PER_CPU(u16, cpu_llc_id) = BAD_APICID;
 
 /* representing HT siblings of each logical CPU */
-DEFINE_PER_CPU(cpumask_t, cpu_sibling_map);
+DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map);
 EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
 
 /* representing HT and core siblings of each logical CPU */
-DEFINE_PER_CPU(cpumask_t, cpu_core_map);
+DEFINE_PER_CPU(cpumask_var_t, cpu_core_map);
 EXPORT_PER_CPU_SYMBOL(cpu_core_map);
 
 /* Per CPU bogomips and other parameters */
@@ -115,11 +115,6 @@
 atomic_t init_deasserted;
 
 #if defined(CONFIG_NUMA) && defined(CONFIG_X86_32)
-
-/* which logical CPUs are on which nodes */
-cpumask_t node_to_cpumask_map[MAX_NUMNODES] __read_mostly =
-				{ [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE };
-EXPORT_SYMBOL(node_to_cpumask_map);
 /* which node each logical CPU is on */
 int cpu_to_node_map[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 };
 EXPORT_SYMBOL(cpu_to_node_map);
@@ -128,7 +123,7 @@
 static void map_cpu_to_node(int cpu, int node)
 {
 	printk(KERN_INFO "Mapping cpu %d to node %d\n", cpu, node);
-	cpumask_set_cpu(cpu, &node_to_cpumask_map[node]);
+	cpumask_set_cpu(cpu, node_to_cpumask_map[node]);
 	cpu_to_node_map[cpu] = node;
 }
 
@@ -139,7 +134,7 @@
 
 	printk(KERN_INFO "Unmapping cpu %d from all nodes\n", cpu);
 	for (node = 0; node < MAX_NUMNODES; node++)
-		cpumask_clear_cpu(cpu, &node_to_cpumask_map[node]);
+		cpumask_clear_cpu(cpu, node_to_cpumask_map[node]);
 	cpu_to_node_map[cpu] = 0;
 }
 #else /* !(CONFIG_NUMA && CONFIG_X86_32) */
@@ -301,7 +296,7 @@
 	__flush_tlb_all();
 #endif
 
-	/* This must be done before setting cpu_online_map */
+	/* This must be done before setting cpu_online_mask */
 	set_cpu_sibling_map(raw_smp_processor_id());
 	wmb();
 
@@ -334,6 +329,23 @@
 	cpu_idle();
 }
 
+#ifdef CONFIG_CPUMASK_OFFSTACK
+/* In this case, llc_shared_map is a pointer to a cpumask. */
+static inline void copy_cpuinfo_x86(struct cpuinfo_x86 *dst,
+				    const struct cpuinfo_x86 *src)
+{
+	struct cpumask *llc = dst->llc_shared_map;
+	*dst = *src;
+	dst->llc_shared_map = llc;
+}
+#else
+static inline void copy_cpuinfo_x86(struct cpuinfo_x86 *dst,
+				    const struct cpuinfo_x86 *src)
+{
+	*dst = *src;
+}
+#endif /* CONFIG_CPUMASK_OFFSTACK */
+
 /*
  * The bootstrap kernel entry code has set these up. Save them for
  * a given CPU
@@ -343,7 +355,7 @@
 {
 	struct cpuinfo_x86 *c = &cpu_data(id);
 
-	*c = boot_cpu_data;
+	copy_cpuinfo_x86(c, &boot_cpu_data);
 	c->cpu_index = id;
 	if (id != 0)
 		identify_secondary_cpu(c);
@@ -367,15 +379,15 @@
 				cpumask_set_cpu(cpu, cpu_sibling_mask(i));
 				cpumask_set_cpu(i, cpu_core_mask(cpu));
 				cpumask_set_cpu(cpu, cpu_core_mask(i));
-				cpumask_set_cpu(i, &c->llc_shared_map);
-				cpumask_set_cpu(cpu, &o->llc_shared_map);
+				cpumask_set_cpu(i, c->llc_shared_map);
+				cpumask_set_cpu(cpu, o->llc_shared_map);
 			}
 		}
 	} else {
 		cpumask_set_cpu(cpu, cpu_sibling_mask(cpu));
 	}
 
-	cpumask_set_cpu(cpu, &c->llc_shared_map);
+	cpumask_set_cpu(cpu, c->llc_shared_map);
 
 	if (current_cpu_data.x86_max_cores == 1) {
 		cpumask_copy(cpu_core_mask(cpu), cpu_sibling_mask(cpu));
@@ -386,8 +398,8 @@
 	for_each_cpu(i, cpu_sibling_setup_mask) {
 		if (per_cpu(cpu_llc_id, cpu) != BAD_APICID &&
 		    per_cpu(cpu_llc_id, cpu) == per_cpu(cpu_llc_id, i)) {
-			cpumask_set_cpu(i, &c->llc_shared_map);
-			cpumask_set_cpu(cpu, &cpu_data(i).llc_shared_map);
+			cpumask_set_cpu(i, c->llc_shared_map);
+			cpumask_set_cpu(cpu, cpu_data(i).llc_shared_map);
 		}
 		if (c->phys_proc_id == cpu_data(i).phys_proc_id) {
 			cpumask_set_cpu(i, cpu_core_mask(cpu));
@@ -425,12 +437,7 @@
 	if (sched_mc_power_savings || sched_smt_power_savings)
 		return cpu_core_mask(cpu);
 	else
-		return &c->llc_shared_map;
-}
-
-cpumask_t cpu_coregroup_map(int cpu)
-{
-	return *cpu_coregroup_mask(cpu);
+		return c->llc_shared_map;
 }
 
 static void impress_friends(void)
@@ -897,9 +904,8 @@
  */
 static __init void disable_smp(void)
 {
-	/* use the read/write pointers to the present and possible maps */
-	cpumask_copy(&cpu_present_map, cpumask_of(0));
-	cpumask_copy(&cpu_possible_map, cpumask_of(0));
+	init_cpu_present(cpumask_of(0));
+	init_cpu_possible(cpumask_of(0));
 	smpboot_clear_io_apic_irqs();
 
 	if (smp_found_config)
@@ -1031,6 +1037,8 @@
  */
 void __init native_smp_prepare_cpus(unsigned int max_cpus)
 {
+	unsigned int i;
+
 	preempt_disable();
 	smp_cpu_index_default();
 	current_cpu_data = boot_cpu_data;
@@ -1044,6 +1052,14 @@
 	boot_cpu_logical_apicid = logical_smp_processor_id();
 #endif
 	current_thread_info()->cpu = 0;  /* needed? */
+	for_each_possible_cpu(i) {
+		alloc_cpumask_var(&per_cpu(cpu_sibling_map, i), GFP_KERNEL);
+		alloc_cpumask_var(&per_cpu(cpu_core_map, i), GFP_KERNEL);
+		alloc_cpumask_var(&cpu_data(i).llc_shared_map, GFP_KERNEL);
+		cpumask_clear(per_cpu(cpu_core_map, i));
+		cpumask_clear(per_cpu(cpu_sibling_map, i));
+		cpumask_clear(cpu_data(i).llc_shared_map);
+	}
 	set_cpu_sibling_map(0);
 
 	enable_IR_x2apic();
@@ -1132,11 +1148,11 @@
 
 
 /*
- * cpu_possible_map should be static, it cannot change as cpu's
+ * cpu_possible_mask should be static, it cannot change as cpu's
  * are onlined, or offlined. The reason is per-cpu data-structures
  * are allocated by some modules at init time, and dont expect to
  * do this dynamically on cpu arrival/departure.
- * cpu_present_map on the other hand can change dynamically.
+ * cpu_present_mask on the other hand can change dynamically.
  * In case when cpu_hotplug is not compiled, then we resort to current
  * behaviour, which is cpu_possible == cpu_present.
  * - Ashok Raj
diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c
index 79c0732..deb5ebb 100644
--- a/arch/x86/kernel/tlb_uv.c
+++ b/arch/x86/kernel/tlb_uv.c
@@ -275,6 +275,8 @@
 	return NULL;
 }
 
+static DEFINE_PER_CPU(cpumask_var_t, uv_flush_tlb_mask);
+
 /**
  * uv_flush_tlb_others - globally purge translation cache of a virtual
  * address or all TLB's
@@ -304,8 +306,7 @@
 					  struct mm_struct *mm,
 					  unsigned long va, unsigned int cpu)
 {
-	static DEFINE_PER_CPU(cpumask_t, flush_tlb_mask);
-	struct cpumask *flush_mask = &__get_cpu_var(flush_tlb_mask);
+	struct cpumask *flush_mask = __get_cpu_var(uv_flush_tlb_mask);
 	int i;
 	int bit;
 	int blade;
@@ -755,6 +756,10 @@
 	if (!is_uv_system())
 		return 0;
 
+	for_each_possible_cpu(cur_cpu)
+		alloc_cpumask_var_node(&per_cpu(uv_flush_tlb_mask, cur_cpu),
+				       GFP_KERNEL, cpu_to_node(cur_cpu));
+
 	uv_bau_retry_limit = 1;
 	uv_nshift = uv_hub_info->n_val;
 	uv_mmask = (1UL << uv_hub_info->n_val) - 1;
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index 0a303c3e..a58504e 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -59,7 +59,8 @@
 
 config KVM_TRACE
 	bool "KVM trace support"
-	depends on KVM && MARKERS && SYSFS
+	depends on KVM && SYSFS
+	select MARKERS
 	select RELAY
 	select DEBUG_FS
 	default n
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index 0853774..fdd30d0 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -14,7 +14,7 @@
 mmiotrace-y			:= kmmio.o pf_in.o mmio-mod.o
 obj-$(CONFIG_MMIOTRACE_TEST)	+= testmmiotrace.o
 
-obj-$(CONFIG_NUMA)		+= numa_$(BITS).o
+obj-$(CONFIG_NUMA)		+= numa.o numa_$(BITS).o
 obj-$(CONFIG_K8_NUMA)		+= k8topology_64.o
 obj-$(CONFIG_ACPI_NUMA)		+= srat_$(BITS).o
 
diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c
index 5bc5d16..8126e8d 100644
--- a/arch/x86/mm/highmem_32.c
+++ b/arch/x86/mm/highmem_32.c
@@ -40,7 +40,6 @@
 
 	debug_kmap_atomic(type);
 
-	debug_kmap_atomic(type);
 	idx = type + KM_TYPE_NR*smp_processor_id();
 	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
 	BUG_ON(!pte_none(*(kmap_pte-idx)));
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index db81e9a..749559e 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -1054,17 +1054,47 @@
 const int rodata_test_data = 0xC3;
 EXPORT_SYMBOL_GPL(rodata_test_data);
 
+static int kernel_set_to_readonly;
+
+void set_kernel_text_rw(void)
+{
+	unsigned long start = PFN_ALIGN(_text);
+	unsigned long size = PFN_ALIGN(_etext) - start;
+
+	if (!kernel_set_to_readonly)
+		return;
+
+	pr_debug("Set kernel text: %lx - %lx for read write\n",
+		 start, start+size);
+
+	set_pages_rw(virt_to_page(start), size >> PAGE_SHIFT);
+}
+
+void set_kernel_text_ro(void)
+{
+	unsigned long start = PFN_ALIGN(_text);
+	unsigned long size = PFN_ALIGN(_etext) - start;
+
+	if (!kernel_set_to_readonly)
+		return;
+
+	pr_debug("Set kernel text: %lx - %lx for read only\n",
+		 start, start+size);
+
+	set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
+}
+
 void mark_rodata_ro(void)
 {
 	unsigned long start = PFN_ALIGN(_text);
 	unsigned long size = PFN_ALIGN(_etext) - start;
 
-#ifndef CONFIG_DYNAMIC_FTRACE
-	/* Dynamic tracing modifies the kernel text section */
 	set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
 	printk(KERN_INFO "Write protecting the kernel text: %luk\n",
 		size >> 10);
 
+	kernel_set_to_readonly = 1;
+
 #ifdef CONFIG_CPA_DEBUG
 	printk(KERN_INFO "Testing CPA: Reverting %lx-%lx\n",
 		start, start+size);
@@ -1073,7 +1103,6 @@
 	printk(KERN_INFO "Testing CPA: write protecting again\n");
 	set_pages_ro(virt_to_page(start), size>>PAGE_SHIFT);
 #endif
-#endif /* CONFIG_DYNAMIC_FTRACE */
 
 	start += size;
 	size = (unsigned long)__end_rodata - start;
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 54efa57d..1753e80 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -734,21 +734,48 @@
 const int rodata_test_data = 0xC3;
 EXPORT_SYMBOL_GPL(rodata_test_data);
 
+static int kernel_set_to_readonly;
+
+void set_kernel_text_rw(void)
+{
+	unsigned long start = PFN_ALIGN(_stext);
+	unsigned long end = PFN_ALIGN(__start_rodata);
+
+	if (!kernel_set_to_readonly)
+		return;
+
+	pr_debug("Set kernel text: %lx - %lx for read write\n",
+		 start, end);
+
+	set_memory_rw(start, (end - start) >> PAGE_SHIFT);
+}
+
+void set_kernel_text_ro(void)
+{
+	unsigned long start = PFN_ALIGN(_stext);
+	unsigned long end = PFN_ALIGN(__start_rodata);
+
+	if (!kernel_set_to_readonly)
+		return;
+
+	pr_debug("Set kernel text: %lx - %lx for read only\n",
+		 start, end);
+
+	set_memory_ro(start, (end - start) >> PAGE_SHIFT);
+}
+
 void mark_rodata_ro(void)
 {
 	unsigned long start = PFN_ALIGN(_stext), end = PFN_ALIGN(__end_rodata);
 	unsigned long rodata_start =
 		((unsigned long)__start_rodata + PAGE_SIZE - 1) & PAGE_MASK;
 
-#ifdef CONFIG_DYNAMIC_FTRACE
-	/* Dynamic tracing modifies the kernel text section */
-	start = rodata_start;
-#endif
-
 	printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
 	       (end - start) >> 10);
 	set_memory_ro(start, (end - start) >> PAGE_SHIFT);
 
+	kernel_set_to_readonly = 1;
+
 	/*
 	 * The rodata section (but not the kernel text!) should also be
 	 * not-executable.
diff --git a/arch/x86/mm/iomap_32.c b/arch/x86/mm/iomap_32.c
index bff0c90..8056545 100644
--- a/arch/x86/mm/iomap_32.c
+++ b/arch/x86/mm/iomap_32.c
@@ -23,7 +23,7 @@
 
 int is_io_mapping_possible(resource_size_t base, unsigned long size)
 {
-#ifndef CONFIG_X86_PAE
+#if !defined(CONFIG_X86_PAE) && defined(CONFIG_PHYS_ADDR_T_64BIT)
 	/* There is no way to map greater than 1 << 32 address without PAE */
 	if (base + size > 0x100000000ULL)
 		return 0;
@@ -39,6 +39,7 @@
 
 	pagefault_disable();
 
+	debug_kmap_atomic(type);
 	idx = type + KM_TYPE_NR * smp_processor_id();
 	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
 	set_pte(kmap_pte - idx, pfn_pte(pfn, prot));
@@ -72,7 +73,6 @@
 	unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
 	enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
 
-	debug_kmap_atomic(type);
 	/*
 	 * Force other mappings to Oops if they'll try to access this pte
 	 * without first remap it.  Keeping stale mappings around is a bad idea
diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c
index 2c4baa8..c9342ed 100644
--- a/arch/x86/mm/mmio-mod.c
+++ b/arch/x86/mm/mmio-mod.c
@@ -378,27 +378,34 @@
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
-static cpumask_t downed_cpus;
+static cpumask_var_t downed_cpus;
 
 static void enter_uniprocessor(void)
 {
 	int cpu;
 	int err;
 
+	if (downed_cpus == NULL &&
+	    !alloc_cpumask_var(&downed_cpus, GFP_KERNEL)) {
+		pr_notice(NAME "Failed to allocate mask\n");
+		goto out;
+	}
+
 	get_online_cpus();
-	downed_cpus = cpu_online_map;
-	cpu_clear(first_cpu(cpu_online_map), downed_cpus);
+	cpumask_copy(downed_cpus, cpu_online_mask);
+	cpumask_clear_cpu(cpumask_first(cpu_online_mask), downed_cpus);
 	if (num_online_cpus() > 1)
 		pr_notice(NAME "Disabling non-boot CPUs...\n");
 	put_online_cpus();
 
-	for_each_cpu_mask(cpu, downed_cpus) {
+	for_each_cpu(cpu, downed_cpus) {
 		err = cpu_down(cpu);
 		if (!err)
 			pr_info(NAME "CPU%d is down.\n", cpu);
 		else
 			pr_err(NAME "Error taking CPU%d down: %d\n", cpu, err);
 	}
+out:
 	if (num_online_cpus() > 1)
 		pr_warning(NAME "multiple CPUs still online, "
 						"may miss events.\n");
@@ -411,10 +418,10 @@
 	int cpu;
 	int err;
 
-	if (cpus_weight(downed_cpus) == 0)
+	if (downed_cpus == NULL || cpumask_weight(downed_cpus) == 0)
 		return;
 	pr_notice(NAME "Re-enabling CPUs...\n");
-	for_each_cpu_mask(cpu, downed_cpus) {
+	for_each_cpu(cpu, downed_cpus) {
 		err = cpu_up(cpu);
 		if (!err)
 			pr_info(NAME "enabled CPU%d.\n", cpu);
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
new file mode 100644
index 0000000..550df48
--- /dev/null
+++ b/arch/x86/mm/numa.c
@@ -0,0 +1,67 @@
+/* Common code for 32 and 64-bit NUMA */
+#include <linux/topology.h>
+#include <linux/module.h>
+#include <linux/bootmem.h>
+
+#ifdef CONFIG_DEBUG_PER_CPU_MAPS
+# define DBG(x...) printk(KERN_DEBUG x)
+#else
+# define DBG(x...)
+#endif
+
+/*
+ * Which logical CPUs are on which nodes
+ */
+cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
+EXPORT_SYMBOL(node_to_cpumask_map);
+
+/*
+ * Allocate node_to_cpumask_map based on number of available nodes
+ * Requires node_possible_map to be valid.
+ *
+ * Note: node_to_cpumask() is not valid until after this is done.
+ * (Use CONFIG_DEBUG_PER_CPU_MAPS to check this.)
+ */
+void __init setup_node_to_cpumask_map(void)
+{
+	unsigned int node, num = 0;
+
+	/* setup nr_node_ids if not done yet */
+	if (nr_node_ids == MAX_NUMNODES) {
+		for_each_node_mask(node, node_possible_map)
+			num = node;
+		nr_node_ids = num + 1;
+	}
+
+	/* allocate the map */
+	for (node = 0; node < nr_node_ids; node++)
+		alloc_bootmem_cpumask_var(&node_to_cpumask_map[node]);
+
+	/* cpumask_of_node() will now work */
+	pr_debug("Node to cpumask map for %d nodes\n", nr_node_ids);
+}
+
+#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 (node >= nr_node_ids) {
+		printk(KERN_WARNING
+			"cpumask_of_node(%d): node > nr_node_ids(%d)\n",
+			node, nr_node_ids);
+		dump_stack();
+		return cpu_none_mask;
+	}
+	if (node_to_cpumask_map[node] == NULL) {
+		printk(KERN_WARNING
+			"cpumask_of_node(%d): no node_to_cpumask_map!\n",
+			node);
+		dump_stack();
+		return cpu_online_mask;
+	}
+	return node_to_cpumask_map[node];
+}
+EXPORT_SYMBOL(cpumask_of_node);
+#endif
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
index 64c9cf0..d73aaa8 100644
--- a/arch/x86/mm/numa_64.c
+++ b/arch/x86/mm/numa_64.c
@@ -20,12 +20,6 @@
 #include <asm/acpi.h>
 #include <asm/k8.h>
 
-#ifdef CONFIG_DEBUG_PER_CPU_MAPS
-# define DBG(x...) printk(KERN_DEBUG x)
-#else
-# define DBG(x...)
-#endif
-
 struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
 EXPORT_SYMBOL(node_data);
 
@@ -49,12 +43,6 @@
 EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_node_map);
 
 /*
- * Which logical CPUs are on which nodes
- */
-cpumask_t *node_to_cpumask_map;
-EXPORT_SYMBOL(node_to_cpumask_map);
-
-/*
  * Given a shift value, try to populate memnodemap[]
  * Returns :
  * 1 if OK
@@ -661,36 +649,6 @@
 #endif
 
 
-/*
- * Allocate node_to_cpumask_map based on number of available nodes
- * Requires node_possible_map to be valid.
- *
- * Note: node_to_cpumask() is not valid until after this is done.
- * (Use CONFIG_DEBUG_PER_CPU_MAPS to check this.)
- */
-void __init setup_node_to_cpumask_map(void)
-{
-	unsigned int node, num = 0;
-	cpumask_t *map;
-
-	/* setup nr_node_ids if not done yet */
-	if (nr_node_ids == MAX_NUMNODES) {
-		for_each_node_mask(node, node_possible_map)
-			num = node;
-		nr_node_ids = num + 1;
-	}
-
-	/* allocate the map */
-	map = alloc_bootmem_low(nr_node_ids * sizeof(cpumask_t));
-	DBG("node_to_cpumask_map at %p for %d nodes\n", map, nr_node_ids);
-
-	pr_debug("Node to cpumask map at %p for %d nodes\n",
-		 map, nr_node_ids);
-
-	/* node_to_cpumask() will now work */
-	node_to_cpumask_map = map;
-}
-
 void __cpuinit numa_set_node(int cpu, int node)
 {
 	int *cpu_to_node_map = early_per_cpu_ptr(x86_cpu_to_node_map);
@@ -723,12 +681,12 @@
 
 void __cpuinit numa_add_cpu(int cpu)
 {
-	cpu_set(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]);
+	cpumask_set_cpu(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]);
 }
 
 void __cpuinit numa_remove_cpu(int cpu)
 {
-	cpu_clear(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]);
+	cpumask_clear_cpu(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]);
 }
 
 #else /* CONFIG_DEBUG_PER_CPU_MAPS */
@@ -739,20 +697,20 @@
 static void __cpuinit numa_set_cpumask(int cpu, int enable)
 {
 	int node = early_cpu_to_node(cpu);
-	cpumask_t *mask;
+	struct cpumask *mask;
 	char buf[64];
 
-	if (node_to_cpumask_map == NULL) {
-		printk(KERN_ERR "node_to_cpumask_map NULL\n");
+	mask = node_to_cpumask_map[node];
+	if (mask == NULL) {
+		printk(KERN_ERR "node_to_cpumask_map[%i] NULL\n", node);
 		dump_stack();
 		return;
 	}
 
-	mask = &node_to_cpumask_map[node];
 	if (enable)
-		cpu_set(cpu, *mask);
+		cpumask_set_cpu(cpu, mask);
 	else
-		cpu_clear(cpu, *mask);
+		cpumask_clear_cpu(cpu, mask);
 
 	cpulist_scnprintf(buf, sizeof(buf), mask);
 	printk(KERN_DEBUG "%s cpu %d node %d: mask now %s\n",
@@ -799,59 +757,6 @@
 	return per_cpu(x86_cpu_to_node_map, cpu);
 }
 
-
-/* empty cpumask */
-static const cpumask_t cpu_mask_none;
-
-/*
- * Returns a pointer to the bitmask of CPUs on Node 'node'.
- */
-const cpumask_t *cpumask_of_node(int node)
-{
-	if (node_to_cpumask_map == NULL) {
-		printk(KERN_WARNING
-			"cpumask_of_node(%d): no node_to_cpumask_map!\n",
-			node);
-		dump_stack();
-		return (const cpumask_t *)&cpu_online_map;
-	}
-	if (node >= nr_node_ids) {
-		printk(KERN_WARNING
-			"cpumask_of_node(%d): node > nr_node_ids(%d)\n",
-			node, nr_node_ids);
-		dump_stack();
-		return &cpu_mask_none;
-	}
-	return &node_to_cpumask_map[node];
-}
-EXPORT_SYMBOL(cpumask_of_node);
-
-/*
- * Returns a bitmask of CPUs on Node 'node'.
- *
- * Side note: this function creates the returned cpumask on the stack
- * so with a high NR_CPUS count, excessive stack space is used.  The
- * node_to_cpumask_ptr function should be used whenever possible.
- */
-cpumask_t node_to_cpumask(int node)
-{
-	if (node_to_cpumask_map == NULL) {
-		printk(KERN_WARNING
-			"node_to_cpumask(%d): no node_to_cpumask_map!\n", node);
-		dump_stack();
-		return cpu_online_map;
-	}
-	if (node >= nr_node_ids) {
-		printk(KERN_WARNING
-			"node_to_cpumask(%d): node > nr_node_ids(%d)\n",
-			node, nr_node_ids);
-		dump_stack();
-		return cpu_mask_none;
-	}
-	return node_to_cpumask_map[node];
-}
-EXPORT_SYMBOL(node_to_cpumask);
-
 /*
  * --------- end of debug versions of the numa functions ---------
  */
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c
index 574c8bc..c7d272b 100644
--- a/arch/x86/mm/srat_64.c
+++ b/arch/x86/mm/srat_64.c
@@ -116,6 +116,36 @@
 	reserve_early(phys, phys + length, "ACPI SLIT");
 }
 
+/* Callback for Proximity Domain -> x2APIC mapping */
+void __init
+acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
+{
+	int pxm, node;
+	int apic_id;
+
+	if (srat_disabled())
+		return;
+	if (pa->header.length < sizeof(struct acpi_srat_x2apic_cpu_affinity)) {
+		bad_srat();
+		return;
+	}
+	if ((pa->flags & ACPI_SRAT_CPU_ENABLED) == 0)
+		return;
+	pxm = pa->proximity_domain;
+	node = setup_node(pxm);
+	if (node < 0) {
+		printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm);
+		bad_srat();
+		return;
+	}
+
+	apic_id = pa->apic_id;
+	apicid_to_node[apic_id] = node;
+	acpi_numa = 1;
+	printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> Node %u\n",
+	       pxm, apic_id, node);
+}
+
 /* Callback for Proximity Domain -> LAPIC mapping */
 void __init
 acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
diff --git a/arch/x86/oprofile/op_model_p4.c b/arch/x86/oprofile/op_model_p4.c
index 4c4a51c..819b131 100644
--- a/arch/x86/oprofile/op_model_p4.c
+++ b/arch/x86/oprofile/op_model_p4.c
@@ -380,7 +380,7 @@
 {
 #ifdef CONFIG_SMP
 	int cpu = smp_processor_id();
-	return (cpu != first_cpu(per_cpu(cpu_sibling_map, cpu)));
+	return cpu != cpumask_first(__get_cpu_var(cpu_sibling_map));
 #endif
 	return 0;
 }
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index f234a37..f1817f7 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -258,24 +258,7 @@
 	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
 }
 
-static void pci_unmap_page_range(struct vm_area_struct *vma)
-{
-	u64 addr = (u64)vma->vm_pgoff << PAGE_SHIFT;
-	free_memtype(addr, addr + vma->vm_end - vma->vm_start);
-}
-
-static void pci_track_mmap_page_range(struct vm_area_struct *vma)
-{
-	u64 addr = (u64)vma->vm_pgoff << PAGE_SHIFT;
-	unsigned long flags = pgprot_val(vma->vm_page_prot)
-						& _PAGE_CACHE_MASK;
-
-	reserve_memtype(addr, addr + vma->vm_end - vma->vm_start, flags, NULL);
-}
-
 static struct vm_operations_struct pci_mmap_ops = {
-	.open  = pci_track_mmap_page_range,
-	.close = pci_unmap_page_range,
 	.access = generic_access_phys,
 };
 
@@ -283,11 +266,6 @@
 			enum pci_mmap_state mmap_state, int write_combine)
 {
 	unsigned long prot;
-	u64 addr = vma->vm_pgoff << PAGE_SHIFT;
-	unsigned long len = vma->vm_end - vma->vm_start;
-	unsigned long flags;
-	unsigned long new_flags;
-	int retval;
 
 	/* I/O space cannot be accessed via normal processor loads and
 	 * stores on this platform.
@@ -308,30 +286,6 @@
 
 	vma->vm_page_prot = __pgprot(prot);
 
-	flags = pgprot_val(vma->vm_page_prot) & _PAGE_CACHE_MASK;
-	retval = reserve_memtype(addr, addr + len, flags, &new_flags);
-	if (retval)
-		return retval;
-
-	if (flags != new_flags) {
-		if (!is_new_memtype_allowed(flags, new_flags)) {
-			free_memtype(addr, addr+len);
-			return -EINVAL;
-		}
-		flags = new_flags;
-		vma->vm_page_prot = __pgprot(
-			(pgprot_val(vma->vm_page_prot) & ~_PAGE_CACHE_MASK) |
-			flags);
-	}
-
-	if (((vma->vm_pgoff < max_low_pfn_mapped) ||
-	     (vma->vm_pgoff >= (1UL<<(32 - PAGE_SHIFT)) &&
-	      vma->vm_pgoff < max_pfn_mapped)) &&
-	    ioremap_change_attr((unsigned long)__va(addr), len, flags)) {
-		free_memtype(addr, addr + len);
-		return -EINVAL;
-	}
-
 	if (io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
 			       vma->vm_end - vma->vm_start,
 			       vma->vm_page_prot))
diff --git a/arch/x86/power/Makefile b/arch/x86/power/Makefile
index 9ff4d5b..58b32db 100644
--- a/arch/x86/power/Makefile
+++ b/arch/x86/power/Makefile
@@ -1,2 +1,7 @@
+# __restore_processor_state() restores %gs after S3 resume and so should not
+# itself be stack-protected
+nostackp := $(call cc-option, -fno-stack-protector)
+CFLAGS_cpu_$(BITS).o	:= $(nostackp)
+
 obj-$(CONFIG_PM_SLEEP)		+= cpu_$(BITS).o
 obj-$(CONFIG_HIBERNATION)	+= hibernate_$(BITS).o hibernate_asm_$(BITS).o
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 8d47056..585a6e3 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -158,7 +158,7 @@
 		rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL);
 		if (rc >= 0) {
 			num_processors++;
-			cpu_set(i, cpu_possible_map);
+			set_cpu_possible(i, true);
 		}
 	}
 }
@@ -197,7 +197,7 @@
 	while ((num_possible_cpus() > 1) && (num_possible_cpus() > max_cpus)) {
 		for (cpu = nr_cpu_ids - 1; !cpu_possible(cpu); cpu--)
 			continue;
-		cpu_clear(cpu, cpu_possible_map);
+		set_cpu_possible(cpu, false);
 	}
 
 	for_each_possible_cpu (cpu) {
@@ -210,7 +210,7 @@
 		if (IS_ERR(idle))
 			panic("failed fork for CPU %d", cpu);
 
-		cpu_set(cpu, cpu_present_map);
+		set_cpu_present(cpu, true);
 	}
 }
 
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 9812008..fa6dc4d 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -4,16 +4,13 @@
 mainmenu "Linux/Xtensa Kernel Configuration"
 
 config FRAME_POINTER
-	bool
-	default n
+	def_bool n
 
 config ZONE_DMA
-	bool
-	default y
+	def_bool y
 
 config XTENSA
-	bool
-	default y
+	def_bool y
 	select HAVE_IDE
 	help
 	  Xtensa processors are 32-bit RISC machines designed by Tensilica
@@ -24,28 +21,25 @@
 	  a home page at <http://xtensa.sourceforge.net/>.
 
 config RWSEM_XCHGADD_ALGORITHM
-	bool
-	default y
+	def_bool y
 
 config GENERIC_FIND_NEXT_BIT
-	bool
-	default y
+	def_bool y
 
 config GENERIC_HWEIGHT
-	bool
-	default y
+	def_bool y
 
 config GENERIC_HARDIRQS
-	bool
-	default y
+	def_bool y
+
+config GENERIC_GPIO
+	def_bool y
 
 config ARCH_HAS_ILOG2_U32
-	bool
-	default n
+	def_bool n
 
 config ARCH_HAS_ILOG2_U64
-	bool
-	default n
+	def_bool n
 
 config NO_IOPORT
 	def_bool y
@@ -54,9 +48,18 @@
 	int
 	default 100
 
+config GENERIC_TIME
+	def_bool y
+
 source "init/Kconfig"
 source "kernel/Kconfig.freezer"
 
+config MMU
+	def_bool n
+
+config VARIANT_IRQ_SWITCH
+	def_bool n
+
 menu "Processor type and features"
 
 choice
@@ -65,38 +68,41 @@
 
 config XTENSA_VARIANT_FSF
 	bool "fsf - default (not generic) configuration"
+	select MMU
 
 config XTENSA_VARIANT_DC232B
 	bool "dc232b - Diamond 232L Standard Core Rev.B (LE)"
+	select MMU
 	help
-	This variant refers to Tensilica's Diamond 232L Standard core Rev.B (LE).
-endchoice
+	  This variant refers to Tensilica's Diamond 232L Standard core Rev.B (LE).
 
-config MMU
-	bool
-	default y
+config XTENSA_VARIANT_S6000
+	bool "s6000 - Stretch software configurable processor"
+	select VARIANT_IRQ_SWITCH
+	select ARCH_REQUIRE_GPIOLIB
+endchoice
 
 config XTENSA_UNALIGNED_USER
 	bool "Unaligned memory access in use space"
-	---help---
-	   The Xtensa architecture currently does not handle unaligned
-	   memory accesses in hardware but through an exception handler.
-	   Per default, unaligned memory accesses are disabled in user space.
+	help
+	  The Xtensa architecture currently does not handle unaligned
+	  memory accesses in hardware but through an exception handler.
+	  Per default, unaligned memory accesses are disabled in user space.
 
-	   Say Y here to enable unaligned memory access in user space.
+	  Say Y here to enable unaligned memory access in user space.
 
 config PREEMPT
 	bool "Preemptible Kernel"
-	---help---
-           This option reduces the latency of the kernel when reacting to
-           real-time or interactive events by allowing a low priority process to
-           be preempted even if it is in kernel mode executing a system call.
-           Unfortunately the kernel code has some race conditions if both
-           CONFIG_SMP and CONFIG_PREEMPT are enabled, so this option is
-           currently disabled if you are building an SMP kernel.
+	help
+          This option reduces the latency of the kernel when reacting to
+          real-time or interactive events by allowing a low priority process to
+          be preempted even if it is in kernel mode executing a system call.
+          Unfortunately the kernel code has some race conditions if both
+          CONFIG_SMP and CONFIG_PREEMPT are enabled, so this option is
+          currently disabled if you are building an SMP kernel.
 
-           Say Y here if you are building a kernel for a desktop, embedded
-           or real-time system.  Say N if you are unsure.
+          Say Y here if you are building a kernel for a desktop, embedded
+          or real-time system.  Say N if you are unsure.
 
 config MATH_EMULATION
 	bool "Math emulation"
@@ -105,6 +111,32 @@
 
 endmenu
 
+config XTENSA_CALIBRATE_CCOUNT
+	def_bool n
+	help
+	  On some platforms (XT2000, for example), the CPU clock rate can
+	  vary.  The frequency can be determined, however, by measuring
+	  against a well known, fixed frequency, such as an UART oscillator.
+
+config SERIAL_CONSOLE
+	def_bool n
+
+config XTENSA_ISS_NETWORK
+	def_bool n
+
+menu "Bus options"
+
+config PCI
+	bool "PCI support"
+	default y
+	help
+	  Find out whether you have a PCI motherboard. PCI is the name of a
+	  bus system, i.e. the way the CPU talks to the other stuff inside
+	  your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
+	  VESA. If you have PCI, say Y, otherwise N.
+
+source "drivers/pci/Kconfig"
+
 menu "Platform options"
 
 choice
@@ -113,33 +145,35 @@
 
 config XTENSA_PLATFORM_ISS
 	bool "ISS"
+	select XTENSA_CALIBRATE_CCOUNT
+	select SERIAL_CONSOLE
+	select XTENSA_ISS_NETWORK
 	help
 	  ISS is an acronym for Tensilica's Instruction Set Simulator.
 
 config XTENSA_PLATFORM_XT2000
 	bool "XT2000"
+	select XTENSA_CALIBRATE_CCOUNT
+	select PCI
 	help
 	  XT2000 is the name of Tensilica's feature-rich emulation platform.
 	  This hardware is capable of running a full Linux distribution.
 
+config XTENSA_PLATFORM_S6105
+	bool "S6105"
+	select SERIAL_CONSOLE
+
 endchoice
 
 
-config XTENSA_CALIBRATE_CCOUNT
-	bool "Auto calibration of the CPU clock rate"
-	---help---
-	  On some platforms (XT2000, for example), the CPU clock rate can
-	  vary.  The frequency can be determined, however, by measuring
-	  against a well known, fixed frequency, such as an UART oscillator.
-
 config XTENSA_CPU_CLOCK
 	int "CPU clock rate [MHz]"
 	depends on !XTENSA_CALIBRATE_CCOUNT
-	default "16"
+	default 16
 
 config GENERIC_CALIBRATE_DELAY
 	bool "Auto calibration of the BogoMIPS value"
-	---help---
+	help
 	  The BogoMIPS value can easily be derived from the CPU frequency.
 
 config CMDLINE_BOOL
@@ -156,52 +190,27 @@
 	  time by entering them here. As a minimum, you should specify the
 	  memory size and the root device (e.g., mem=64M root=/dev/nfs).
 
-config SERIAL_CONSOLE
-	bool
-	depends on XTENSA_PLATFORM_ISS
-	default y
-
-config XTENSA_ISS_NETWORK
-	bool
-	depends on XTENSA_PLATFORM_ISS
-	default y
-
 source "mm/Kconfig"
 
 endmenu
 
-menu "Bus options"
-
-config PCI
-	bool "PCI support" if !XTENSA_PLATFORM_ISS
-	depends on !XTENSA_PLATFORM_ISS
-	default y
-	help
-	  Find out whether you have a PCI motherboard. PCI is the name of a
-	  bus system, i.e. the way the CPU talks to the other stuff inside
-	  your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
-	  VESA. If you have PCI, say Y, otherwise N.
-
-source "drivers/pci/Kconfig"
-
 config HOTPLUG
-
 	bool "Support for hot-pluggable devices"
-	---help---
-	Say Y here if you want to plug devices into your computer while
-	the system is running, and be able to use them quickly.  In many
-	cases, the devices can likewise be unplugged at any time too.
+	help
+	  Say Y here if you want to plug devices into your computer while
+	  the system is running, and be able to use them quickly.  In many
+	  cases, the devices can likewise be unplugged at any time too.
 
-	One well known example of this is PCMCIA- or PC-cards, credit-card
-	size devices such as network cards, modems or hard drives which are
-	plugged into slots found on all modern laptop computers.  Another
-	example, used on modern desktops as well as laptops, is USB.
+	  One well known example of this is PCMCIA- or PC-cards, credit-card
+	  size devices such as network cards, modems or hard drives which are
+	  plugged into slots found on all modern laptop computers.  Another
+	  example, used on modern desktops as well as laptops, is USB.
 
-	Enable HOTPLUG and build a modular kernel.  Get agent software
-	(from <http://linux-hotplug.sourceforge.net/>) and install it.
-	Then your kernel will automatically call out to a user mode "policy
-	agent" (/sbin/hotplug) to load modules and set up software needed
-	to use devices as you hotplug them.
+	  Enable HOTPLUG and build a modular kernel.  Get agent software
+	  (from <http://linux-hotplug.sourceforge.net/>) and install it.
+	  Then your kernel will automatically call out to a user mode "policy
+	  agent" (/sbin/hotplug) to load modules and set up software needed
+	  to use devices as you hotplug them.
 
 source "drivers/pcmcia/Kconfig"
 
@@ -213,9 +222,8 @@
 
 # only elf supported
 config KCORE_ELF
-        bool
+	def_bool y
         depends on PROC_FS
-        default y
         help
           If you enabled support for /proc file system then the file
           /proc/kcore will contain the kernel core image in ELF format. This
@@ -240,7 +248,7 @@
 menu "Xtensa initrd options"
 	depends on BLK_DEV_INITRD
 
-	config EMBEDDED_RAMDISK
+config EMBEDDED_RAMDISK
 	bool "Embed root filesystem ramdisk into the kernel"
 
 config EMBEDDED_RAMDISK_IMAGE
diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile
index 1da55fe..4caffac 100644
--- a/arch/xtensa/Makefile
+++ b/arch/xtensa/Makefile
@@ -15,6 +15,7 @@
 
 variant-$(CONFIG_XTENSA_VARIANT_FSF)		:= fsf
 variant-$(CONFIG_XTENSA_VARIANT_DC232B)		:= dc232b
+variant-$(CONFIG_XTENSA_VARIANT_S6000)		:= s6000
 variant-$(CONFIG_XTENSA_VARIANT_LINUX_CUSTOM)	:= custom
 
 VARIANT = $(variant-y)
@@ -24,6 +25,7 @@
 
 platform-$(CONFIG_XTENSA_PLATFORM_XT2000)	:= xt2000
 platform-$(CONFIG_XTENSA_PLATFORM_ISS)		:= iss
+platform-$(CONFIG_XTENSA_PLATFORM_S6105)	:= s6105
 
 PLATFORM = $(platform-y)
 export PLATFORM
@@ -62,20 +64,23 @@
   endif
 endif
 
-#
+# Only build variant and/or platform if it includes a Makefile
+
+buildvar := $(shell test -a $(srctree)/arch/xtensa/variants/$(VARIANT)/Makefile && echo arch/xtensa/variants/$(VARIANT)/)
+buildplf := $(shell test -a $(srctree)/arch/xtensa/platforms/$(PLATFORM)/Makefile && echo arch/xtensa/platforms/$(PLATFORM)/)
+
+# Find libgcc.a
 
 LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
 
 head-y		:= arch/xtensa/kernel/head.o
 core-y		+= arch/xtensa/kernel/ arch/xtensa/mm/
-ifneq ($(PLATFORM),)
-core-y		+= arch/xtensa/platforms/$(PLATFORM)/
-endif
+core-y		+= $(buildvar) $(buildplf)
+
 libs-y		+= arch/xtensa/lib/ $(LIBGCC)
 
 boot		:= arch/xtensa/boot
 
-
 all: zImage
 
 bzImage : zImage
diff --git a/arch/xtensa/configs/s6105_defconfig b/arch/xtensa/configs/s6105_defconfig
new file mode 100644
index 0000000..6e1deff
--- /dev/null
+++ b/arch/xtensa/configs/s6105_defconfig
@@ -0,0 +1,530 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc7-s6
+# Tue Mar 10 11:09:26 2009
+#
+# CONFIG_FRAME_POINTER is not set
+CONFIG_ZONE_DMA=y
+CONFIG_XTENSA=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_NO_IOPORT=y
+CONFIG_HZ=100
+CONFIG_GENERIC_TIME=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+# CONFIG_CLASSIC_RCU is not set
+# CONFIG_TREE_RCU is not set
+CONFIG_PREEMPT_RCU=y
+# CONFIG_RCU_TRACE is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+# CONFIG_MMU is not set
+CONFIG_VARIANT_IRQ_SWITCH=y
+
+#
+# Processor type and features
+#
+# CONFIG_XTENSA_VARIANT_FSF is not set
+# CONFIG_XTENSA_VARIANT_DC232B is not set
+CONFIG_XTENSA_VARIANT_S6000=y
+# CONFIG_XTENSA_UNALIGNED_USER is not set
+CONFIG_PREEMPT=y
+# CONFIG_MATH_EMULATION is not set
+# CONFIG_HIGHMEM is not set
+# CONFIG_XTENSA_CALIBRATE_CCOUNT is not set
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_XTENSA_ISS_NETWORK is not set
+
+#
+# Bus options
+#
+# CONFIG_PCI is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+
+#
+# Platform options
+#
+# CONFIG_XTENSA_PLATFORM_ISS is not set
+# CONFIG_XTENSA_PLATFORM_XT2000 is not set
+CONFIG_XTENSA_PLATFORM_S6105=y
+CONFIG_XTENSA_CPU_CLOCK=300
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS1,38400 debug bootmem_debug loglevel=7"
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_VIRT_TO_BUS=y
+
+#
+# Executable file formats
+#
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_FLAT=y
+# CONFIG_BINFMT_ZFLAT is not set
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_NETDEVICES is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_SOUND is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+# CONFIG_DLM is not set
+
+#
+# Xtensa initrd options
+#
+# CONFIG_EMBEDDED_RAMDISK is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_DEBUG_NOMMU_REGIONS=y
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+
+#
+# Tracers
+#
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_DMA=y
diff --git a/arch/xtensa/include/asm/cacheflush.h b/arch/xtensa/include/asm/cacheflush.h
index 94c4c53..8fc1c0c 100644
--- a/arch/xtensa/include/asm/cacheflush.h
+++ b/arch/xtensa/include/asm/cacheflush.h
@@ -65,13 +65,17 @@
 # define __flush_invalidate_dcache_range(p,s)	__invalidate_dcache_range(p,s)
 #endif
 
-#if (DCACHE_WAY_SIZE > PAGE_SIZE)
+#if defined(CONFIG_MMU) && (DCACHE_WAY_SIZE > PAGE_SIZE)
 extern void __flush_invalidate_dcache_page_alias(unsigned long, unsigned long);
+#else
+static inline void __flush_invalidate_dcache_page_alias(unsigned long virt,
+							unsigned long phys) { }
 #endif
-#if (ICACHE_WAY_SIZE > PAGE_SIZE)
+#if defined(CONFIG_MMU) && (ICACHE_WAY_SIZE > PAGE_SIZE)
 extern void __invalidate_icache_page_alias(unsigned long, unsigned long);
 #else
-# define __invalidate_icache_page_alias(v,p)	do { } while(0)
+static inline void __invalidate_icache_page_alias(unsigned long virt,
+						unsigned long phys) { }
 #endif
 
 /*
diff --git a/arch/xtensa/include/asm/dma.h b/arch/xtensa/include/asm/dma.h
index e30f3ab..137ca39 100644
--- a/arch/xtensa/include/asm/dma.h
+++ b/arch/xtensa/include/asm/dma.h
@@ -44,8 +44,9 @@
  *	the value desired).
  */
 
+#ifndef MAX_DMA_ADDRESS
 #define MAX_DMA_ADDRESS		(PAGE_OFFSET + XCHAL_KIO_SIZE - 1)
-
+#endif
 
 /* Reserve and release a DMA channel */
 extern int request_dma(unsigned int dmanr, const char * device_id);
diff --git a/arch/xtensa/include/asm/flat.h b/arch/xtensa/include/asm/flat.h
new file mode 100644
index 0000000..94c44ab
--- /dev/null
+++ b/arch/xtensa/include/asm/flat.h
@@ -0,0 +1,12 @@
+#ifndef __ASM_XTENSA_FLAT_H
+#define __ASM_XTENSA_FLAT_H
+
+#define flat_argvp_envp_on_stack()			0
+#define flat_old_ram_flag(flags)			(flags)
+#define flat_reloc_valid(reloc, size)			((reloc) <= (size))
+#define flat_get_addr_from_rp(rp, relval, flags, p)	get_unaligned(rp)
+#define flat_put_addr_at_rp(rp, val, relval	)	put_unaligned(val, rp)
+#define flat_get_relocate_addr(rel)			(rel)
+#define flat_set_persistent(relval, p)			0
+
+#endif /* __ASM_XTENSA_FLAT_H */
diff --git a/arch/xtensa/include/asm/ftrace.h b/arch/xtensa/include/asm/ftrace.h
new file mode 100644
index 0000000..40a8c17
--- /dev/null
+++ b/arch/xtensa/include/asm/ftrace.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/xtensa/include/asm/gpio.h b/arch/xtensa/include/asm/gpio.h
new file mode 100644
index 0000000..0763b07
--- /dev/null
+++ b/arch/xtensa/include/asm/gpio.h
@@ -0,0 +1,56 @@
+/*
+ * Generic GPIO API implementation for xtensa.
+ *
+ * Stolen from x86, which is derived from the generic GPIO API for powerpc:
+ *
+ * Copyright (c) 2007-2008  MontaVista Software, Inc.
+ *
+ * Author: Anton Vorontsov <avorontsov@ru.mvista.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.
+ */
+
+#ifndef _ASM_XTENSA_GPIO_H
+#define _ASM_XTENSA_GPIO_H
+
+#include <asm-generic/gpio.h>
+
+#ifdef CONFIG_GPIOLIB
+
+/*
+ * Just call gpiolib.
+ */
+static inline int gpio_get_value(unsigned int gpio)
+{
+	return __gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned int gpio, int value)
+{
+	__gpio_set_value(gpio, value);
+}
+
+static inline int gpio_cansleep(unsigned int gpio)
+{
+	return __gpio_cansleep(gpio);
+}
+
+/*
+ * Not implemented, yet.
+ */
+static inline int gpio_to_irq(unsigned int gpio)
+{
+	return -ENOSYS;
+}
+
+static inline int irq_to_gpio(unsigned int irq)
+{
+	return -EINVAL;
+}
+
+#endif /* CONFIG_GPIOLIB */
+
+#endif /* _ASM_XTENSA_GPIO_H */
diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h
index 07b7299..d04cd3a 100644
--- a/arch/xtensa/include/asm/io.h
+++ b/arch/xtensa/include/asm/io.h
@@ -69,21 +69,28 @@
 
 static inline void *ioremap(unsigned long offset, unsigned long size)
 {
+#ifdef CONFIG_MMU
 	if (offset >= XCHAL_KIO_PADDR
 	    && offset < XCHAL_KIO_PADDR + XCHAL_KIO_SIZE)
 		return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_BYPASS_VADDR);
-
 	else
 		BUG();
+#else
+	return (void *)offset;
+#endif
 }
 
 static inline void *ioremap_nocache(unsigned long offset, unsigned long size)
 {
+#ifdef CONFIG_MMU
 	if (offset >= XCHAL_KIO_PADDR
 	    && offset < XCHAL_KIO_PADDR + XCHAL_KIO_SIZE)
 		return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_CACHED_VADDR);
 	else
 		BUG();
+#else
+	return (void *)offset;
+#endif
 }
 
 static inline void iounmap(void *addr)
diff --git a/arch/xtensa/include/asm/irq.h b/arch/xtensa/include/asm/irq.h
index 1620d1e..dfac82d 100644
--- a/arch/xtensa/include/asm/irq.h
+++ b/arch/xtensa/include/asm/irq.h
@@ -14,6 +14,13 @@
 #include <platform/hardware.h>
 #include <variant/core.h>
 
+#ifdef CONFIG_VARIANT_IRQ_SWITCH
+#include <variant/irq.h>
+#else
+static inline void variant_irq_enable(unsigned int irq) { }
+static inline void variant_irq_disable(unsigned int irq) { }
+#endif
+
 #ifndef PLATFORM_NR_IRQS
 # define PLATFORM_NR_IRQS 0
 #endif
diff --git a/arch/xtensa/include/asm/mmu.h b/arch/xtensa/include/asm/mmu.h
index 44c5bb0..04890d6 100644
--- a/arch/xtensa/include/asm/mmu.h
+++ b/arch/xtensa/include/asm/mmu.h
@@ -11,7 +11,12 @@
 #ifndef _XTENSA_MMU_H
 #define _XTENSA_MMU_H
 
+#ifndef CONFIG_MMU
+#include <asm/nommu.h>
+#else
+
 /* Default "unsigned long" context */
 typedef unsigned long mm_context_t;
 
+#endif /* CONFIG_MMU */
 #endif	/* _XTENSA_MMU_H */
diff --git a/arch/xtensa/include/asm/mmu_context.h b/arch/xtensa/include/asm/mmu_context.h
index c0fd8e5..dbd8731 100644
--- a/arch/xtensa/include/asm/mmu_context.h
+++ b/arch/xtensa/include/asm/mmu_context.h
@@ -13,16 +13,20 @@
 #ifndef _XTENSA_MMU_CONTEXT_H
 #define _XTENSA_MMU_CONTEXT_H
 
+#ifndef CONFIG_MMU
+#include <asm/nommu_context.h>
+#else
+
 #include <linux/stringify.h>
 #include <linux/sched.h>
 
+#include <variant/core.h>
+
 #include <asm/pgtable.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 #include <asm-generic/mm_hooks.h>
 
-#define XCHAL_MMU_ASID_BITS	8
-
 #if (XCHAL_HAVE_TLBS != 1)
 # error "Linux must have an MMU!"
 #endif
@@ -133,4 +137,5 @@
 
 }
 
+#endif /* CONFIG_MMU */
 #endif /* _XTENSA_MMU_CONTEXT_H */
diff --git a/arch/xtensa/include/asm/nommu.h b/arch/xtensa/include/asm/nommu.h
new file mode 100644
index 0000000..dce2c43
--- /dev/null
+++ b/arch/xtensa/include/asm/nommu.h
@@ -0,0 +1,3 @@
+typedef struct {
+	unsigned long end_brk;
+} mm_context_t;
diff --git a/arch/xtensa/include/asm/nommu_context.h b/arch/xtensa/include/asm/nommu_context.h
new file mode 100644
index 0000000..599e7a2
--- /dev/null
+++ b/arch/xtensa/include/asm/nommu_context.h
@@ -0,0 +1,25 @@
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+}
+
+static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+	return 0;
+}
+
+static inline void destroy_context(struct mm_struct *mm)
+{
+}
+
+static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next)
+{
+}
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+				struct task_struct *tsk)
+{
+}
+
+static inline void deactivate_mm(struct task_struct *tsk, struct mm_struct *mm)
+{
+}
diff --git a/arch/xtensa/include/asm/page.h b/arch/xtensa/include/asm/page.h
index 11f7dc2..17e0c53 100644
--- a/arch/xtensa/include/asm/page.h
+++ b/arch/xtensa/include/asm/page.h
@@ -14,6 +14,7 @@
 #include <asm/processor.h>
 #include <asm/types.h>
 #include <asm/cache.h>
+#include <platform/hardware.h>
 
 /*
  * Fixed TLB translations in the processor.
@@ -32,8 +33,14 @@
 #define PAGE_SIZE		(__XTENSA_UL_CONST(1) << PAGE_SHIFT)
 #define PAGE_MASK		(~(PAGE_SIZE-1))
 
+#ifdef CONFIG_MMU
 #define PAGE_OFFSET		XCHAL_KSEG_CACHED_VADDR
 #define MAX_MEM_PFN		XCHAL_KSEG_SIZE
+#else
+#define PAGE_OFFSET		0
+#define MAX_MEM_PFN		(PLATFORM_DEFAULT_MEM_START + PLATFORM_DEFAULT_MEM_SIZE)
+#endif
+
 #define PGTABLE_START		0x80000000
 
 /*
@@ -150,9 +157,11 @@
  * addresses.
  */
 
+#define ARCH_PFN_OFFSET		(PLATFORM_DEFAULT_MEM_START >> PAGE_SHIFT)
+
 #define __pa(x)			((unsigned long) (x) - PAGE_OFFSET)
 #define __va(x)			((void *)((unsigned long) (x) + PAGE_OFFSET))
-#define pfn_valid(pfn)		((unsigned long)pfn < max_mapnr)
+#define pfn_valid(pfn)		((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr)
 #ifdef CONFIG_DISCONTIGMEM
 # error CONFIG_DISCONTIGMEM not supported
 #endif
@@ -162,8 +171,9 @@
 #define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
 #define page_to_phys(page)	(page_to_pfn(page) << PAGE_SHIFT)
 
+#ifdef CONFIG_MMU
 #define WANT_PAGE_VIRTUAL
-
+#endif
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/xtensa/include/asm/pgtable.h b/arch/xtensa/include/asm/pgtable.h
index 8014d96..a138770 100644
--- a/arch/xtensa/include/asm/pgtable.h
+++ b/arch/xtensa/include/asm/pgtable.h
@@ -183,7 +183,15 @@
 
 #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
 
+#ifdef CONFIG_MMU
 extern pgd_t swapper_pg_dir[PAGE_SIZE/sizeof(pgd_t)];
+extern void paging_init(void);
+extern void pgtable_cache_init(void);
+#else
+# define swapper_pg_dir NULL
+static inline void paging_init(void) { }
+static inline void pgtable_cache_init(void) { }
+#endif
 
 /*
  * The pmd contains the kernel virtual address of the pte page.
@@ -383,8 +391,6 @@
 
 #else
 
-extern void paging_init(void);
-
 #define kern_addr_valid(addr)	(1)
 
 extern  void update_mmu_cache(struct vm_area_struct * vma,
@@ -398,9 +404,6 @@
 #define io_remap_pfn_range(vma,from,pfn,size,prot) \
                 remap_pfn_range(vma, from, pfn, size, prot)
 
-
-extern void pgtable_cache_init(void);
-
 typedef pte_t *pte_addr_t;
 
 #endif /* !defined (__ASSEMBLY__) */
diff --git a/arch/xtensa/include/asm/platform.h b/arch/xtensa/include/asm/platform.h
index e3d5a48..7d936e5 100644
--- a/arch/xtensa/include/asm/platform.h
+++ b/arch/xtensa/include/asm/platform.h
@@ -74,16 +74,5 @@
  */
 extern void platform_calibrate_ccount (void);
 
-/*
- * platform_get_rtc_time returns RTC seconds (returns 0 for no error)
- */
-extern int platform_get_rtc_time(time_t*);
-
-/*
- * platform_set_rtc_time set RTC seconds (returns 0 for no error)
- */
-extern int platform_set_rtc_time(time_t);
-
-
 #endif	/* _XTENSA_PLATFORM_H */
 
diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h
index 07387d3..0ea4937 100644
--- a/arch/xtensa/include/asm/processor.h
+++ b/arch/xtensa/include/asm/processor.h
@@ -13,6 +13,7 @@
 
 #include <variant/core.h>
 #include <asm/coprocessor.h>
+#include <platform/hardware.h>
 
 #include <linux/compiler.h>
 #include <asm/ptrace.h>
@@ -25,6 +26,8 @@
 # error Linux requires the Xtensa Windowed Registers Option.
 #endif
 
+#define ARCH_SLAB_MINALIGN	XCHAL_DATA_WIDTH
+
 /*
  * User space process size: 1 GB.
  * Windowed call ABI requires caller and callee to be located within the same
@@ -33,7 +36,12 @@
  * the 1 GB requirement applies to the stack as well.
  */
 
+#ifdef CONFIG_MMU
 #define TASK_SIZE	__XTENSA_UL_CONST(0x40000000)
+#else
+#define TASK_SIZE	(PLATFORM_DEFAULT_MEM_START + PLATFORM_DEFAULT_MEM_SIZE)
+#endif
+
 #define STACK_TOP	TASK_SIZE
 #define STACK_TOP_MAX	STACK_TOP
 
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index a51d36a..80d24c4 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -1463,6 +1463,7 @@
 	callx0	a0		# should not return
 1:	j	1b
 
+#ifdef CONFIG_MMU
 /*
  * We should never get here. Bail out!
  */
@@ -1775,7 +1776,7 @@
 	bbsi.l	a2, PS_UM_BIT, 1f
 	j	_kernel_exception
 1:	j	_user_exception
-
+#endif /* CONFIG_MMU */
 
 /*
  * System Calls.
diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S
index 67e6913..0817f9d 100644
--- a/arch/xtensa/kernel/head.S
+++ b/arch/xtensa/kernel/head.S
@@ -53,7 +53,7 @@
 2:	l32r	a0, 1b
 	jx	a0
 
-	.text
+	.section .init.text, "ax"
 	.align 4
 _startup:
 
@@ -235,8 +235,9 @@
  */
 	
 .section ".bss.page_aligned", "w"
+#ifdef CONFIG_MMU
 ENTRY(swapper_pg_dir)
 	.fill	PAGE_SIZE, 1, 0
+#endif
 ENTRY(empty_zero_page)
 	.fill	PAGE_SIZE, 1, 0
-
diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c
index f3b66fb..a36c85ed 100644
--- a/arch/xtensa/kernel/irq.c
+++ b/arch/xtensa/kernel/irq.c
@@ -132,6 +132,18 @@
 	set_sr (cached_irq_mask, INTENABLE);
 }
 
+static void xtensa_irq_enable(unsigned int irq)
+{
+	variant_irq_enable(irq);
+	xtensa_irq_unmask(irq);
+}
+
+static void xtensa_irq_disable(unsigned int irq)
+{
+	xtensa_irq_mask(irq);
+	variant_irq_disable(irq);
+}
+
 static void xtensa_irq_ack(unsigned int irq)
 {
 	set_sr(1 << irq, INTCLEAR);
@@ -146,6 +158,8 @@
 
 static struct irq_chip xtensa_irq_chip = {
 	.name		= "xtensa",
+	.enable		= xtensa_irq_enable,
+	.disable	= xtensa_irq_disable,
 	.mask		= xtensa_irq_mask,
 	.unmask		= xtensa_irq_unmask,
 	.ack		= xtensa_irq_ack,
diff --git a/arch/xtensa/kernel/platform.c b/arch/xtensa/kernel/platform.c
index 69675f2..1b91a97 100644
--- a/arch/xtensa/kernel/platform.c
+++ b/arch/xtensa/kernel/platform.c
@@ -36,8 +36,6 @@
 _F(void, idle, (void), { __asm__ __volatile__ ("waiti 0" ::: "memory"); });
 _F(void, heartbeat, (void), { });
 _F(int,  pcibios_fixup, (void), { return 0; });
-_F(int, get_rtc_time, (time_t* t), { return 0; });
-_F(int, set_rtc_time, (time_t t), { return 0; });
 
 #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
 _F(void, calibrate_ccount, (void),
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
index 4ec1633..1e5a034 100644
--- a/arch/xtensa/kernel/setup.c
+++ b/arch/xtensa/kernel/setup.c
@@ -84,7 +84,13 @@
 int initrd_is_mapped;
 #endif
 
+#ifdef CONFIG_MMU
 extern void init_mmu(void);
+#else
+static inline void init_mmu(void) { }
+#endif
+
+extern void zones_init(void);
 
 /*
  * Boot parameter parsing.
@@ -286,6 +292,7 @@
 
 
 	paging_init();
+	zones_init();
 
 #ifdef CONFIG_VT
 # if defined(CONFIG_VGA_CONSOLE)
diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c
index 8df1e842..8848120 100644
--- a/arch/xtensa/kernel/time.c
+++ b/arch/xtensa/kernel/time.c
@@ -14,7 +14,7 @@
 
 #include <linux/errno.h>
 #include <linux/time.h>
-#include <linux/timex.h>
+#include <linux/clocksource.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -25,27 +25,31 @@
 #include <asm/timex.h>
 #include <asm/platform.h>
 
-
-DEFINE_SPINLOCK(rtc_lock);
-EXPORT_SYMBOL(rtc_lock);
-
-
 #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
 unsigned long ccount_per_jiffy;		/* per 1/HZ */
 unsigned long nsec_per_ccount;		/* nsec per ccount increment */
 #endif
 
-static long last_rtc_update = 0;
-
-/*
- * Scheduler clock - returns current tim in nanosec units.
- */
-
-unsigned long long sched_clock(void)
+static cycle_t ccount_read(void)
 {
-	return (unsigned long long)jiffies * (1000000000 / HZ);
+	return (cycle_t)get_ccount();
 }
 
+static struct clocksource ccount_clocksource = {
+	.name = "ccount",
+	.rating = 200,
+	.read = ccount_read,
+	.mask = CLOCKSOURCE_MASK(32),
+	/*
+	 * With a shift of 22 the lower limit of the cpu clock is
+	 * 1MHz, where NSEC_PER_CCOUNT is 1000 or a bit less than
+	 * 2^10: Since we have 32 bits and the multiplicator can
+	 * already take up as much as 10 bits, this leaves us with
+	 * remaining upper 22 bits.
+	 */
+	.shift = 22,
+};
+
 static irqreturn_t timer_interrupt(int irq, void *dev_id);
 static struct irqaction timer_irqaction = {
 	.handler =	timer_interrupt,
@@ -55,11 +59,11 @@
 
 void __init time_init(void)
 {
-	time_t sec_o, sec_n = 0;
+	xtime.tv_nsec = 0;
+	xtime.tv_sec = read_persistent_clock();
 
-	/* The platform must provide a function to calibrate the processor
-	 * speed for the CALIBRATE.
-	 */
+	set_normalized_timespec(&wall_to_monotonic,
+		-xtime.tv_sec, -xtime.tv_nsec);
 
 #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
 	printk("Calibrating CPU frequency ");
@@ -67,19 +71,10 @@
 	printk("%d.%02d MHz\n", (int)ccount_per_jiffy/(1000000/HZ),
 			(int)(ccount_per_jiffy/(10000/HZ))%100);
 #endif
-
-	/* Set time from RTC (if provided) */
-
-	if (platform_get_rtc_time(&sec_o) == 0)
-		while (platform_get_rtc_time(&sec_n))
-			if (sec_o != sec_n)
-				break;
-
-	xtime.tv_nsec = 0;
-	last_rtc_update = xtime.tv_sec = sec_n;
-
-	set_normalized_timespec(&wall_to_monotonic,
-		-xtime.tv_sec, -xtime.tv_nsec);
+	ccount_clocksource.mult =
+		clocksource_hz2mult(CCOUNT_PER_JIFFY * HZ,
+				ccount_clocksource.shift);
+	clocksource_register(&ccount_clocksource);
 
 	/* Initialize the linux timer interrupt. */
 
@@ -87,69 +82,6 @@
 	set_linux_timer(get_ccount() + CCOUNT_PER_JIFFY);
 }
 
-
-int do_settimeofday(struct timespec *tv)
-{
-	time_t wtm_sec, sec = tv->tv_sec;
-	long wtm_nsec, nsec = tv->tv_nsec;
-	unsigned long delta;
-
-	if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
-		return -EINVAL;
-
-	write_seqlock_irq(&xtime_lock);
-
-	/* This is revolting. We need to set "xtime" correctly. However, the
-	 * value in this location is the value at the most recent update of
-	 * wall time.  Discover what correction gettimeofday() would have
-	 * made, and then undo it!
-	 */
-
-	delta = CCOUNT_PER_JIFFY;
-	delta += get_ccount() - get_linux_timer();
-	nsec -= delta * NSEC_PER_CCOUNT;
-
-	wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
-	wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
-	set_normalized_timespec(&xtime, sec, nsec);
-	set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
-	ntp_clear();
-	write_sequnlock_irq(&xtime_lock);
-	return 0;
-}
-
-EXPORT_SYMBOL(do_settimeofday);
-
-
-void do_gettimeofday(struct timeval *tv)
-{
-	unsigned long flags;
-	unsigned long volatile sec, usec, delta, seq;
-
-	do {
-		seq = read_seqbegin_irqsave(&xtime_lock, flags);
-
-		sec = xtime.tv_sec;
-		usec = (xtime.tv_nsec / NSEC_PER_USEC);
-
-		delta = get_linux_timer() - get_ccount();
-
-	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
-	usec += (((unsigned long) CCOUNT_PER_JIFFY - delta)
-		 * (unsigned long) NSEC_PER_CCOUNT) / NSEC_PER_USEC;
-
-	for (; usec >= 1000000; sec++, usec -= 1000000)
-		;
-
-	tv->tv_sec = sec;
-	tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
 /*
  * The timer interrupt is called HZ times per second.
  */
@@ -178,16 +110,6 @@
 		next += CCOUNT_PER_JIFFY;
 		set_linux_timer(next);
 
-		if (ntp_synced() &&
-		    xtime.tv_sec - last_rtc_update >= 659 &&
-		    abs((xtime.tv_nsec/1000)-(1000000-1000000/HZ))<5000000/HZ) {
-
-			if (platform_set_rtc_time(xtime.tv_sec+1) == 0)
-				last_rtc_update = xtime.tv_sec+1;
-			else
-				/* Do it again in 60 s */
-				last_rtc_update += 60;
-		}
 		write_sequnlock(&xtime_lock);
 	}
 
@@ -213,4 +135,3 @@
 	       (loops_per_jiffy/(10000/HZ)) % 100);
 }
 #endif
-
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
index c44f830..9f0b711 100644
--- a/arch/xtensa/kernel/traps.c
+++ b/arch/xtensa/kernel/traps.c
@@ -104,6 +104,7 @@
 #endif
 { EXCCAUSE_UNALIGNED,		KRNL,	   fast_unaligned },
 #endif
+#ifdef CONFIG_MMU
 { EXCCAUSE_ITLB_MISS,		0,	   do_page_fault },
 { EXCCAUSE_ITLB_MISS,		USER|KRNL, fast_second_level_miss},
 { EXCCAUSE_ITLB_MULTIHIT,		0,	   do_multihit },
@@ -118,6 +119,7 @@
 { EXCCAUSE_STORE_CACHE_ATTRIBUTE,	USER|KRNL, fast_store_prohibited },
 { EXCCAUSE_STORE_CACHE_ATTRIBUTE,	0,	   do_page_fault },
 { EXCCAUSE_LOAD_CACHE_ATTRIBUTE,	0,	   do_page_fault },
+#endif /* CONFIG_MMU */
 /* XCCHAL_EXCCAUSE_FLOATING_POINT unhandled */
 #if XTENSA_HAVE_COPROCESSOR(0)
 COPROCESSOR(0),
@@ -372,11 +374,10 @@
 	unsigned long a0, a1, pc;
 	unsigned long sp_start, sp_end;
 
-	a1 = (unsigned long)sp;
-
-	if (a1 == 0)
-		__asm__ __volatile__ ("mov %0, a1\n" : "=a"(a1));
-
+	if (sp)
+		a1 = (unsigned long)sp;
+	else
+		a1 = task->thread.sp;
 
 	sp_start = a1 & ~(THREAD_SIZE-1);
 	sp_end = sp_start + THREAD_SIZE;
@@ -418,9 +419,8 @@
 	int i = 0;
 	unsigned long *stack;
 
-	if (sp == 0)
-		__asm__ __volatile__ ("mov %0, a1\n" : "=a"(sp));
-
+	if (!sp)
+		sp = (unsigned long *)task->thread.sp;
  	stack = sp;
 
 	printk("\nStack: ");
diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S
index eb2d7bb..74a7518 100644
--- a/arch/xtensa/kernel/vectors.S
+++ b/arch/xtensa/kernel/vectors.S
@@ -309,6 +309,7 @@
 	 * All other exceptions are unexpected and thus unrecoverable!
 	 */
 
+#ifdef CONFIG_MMU
 	.extern fast_second_level_miss_double_kernel
 
 .Lksp:	/* a0: a0, a1: a1, a2: a2, a3: trashed, depc: depc, excsave: a3 */
@@ -319,6 +320,9 @@
 	bnez	a3, .Lunrecoverable
 1:	movi	a3, fast_second_level_miss_double_kernel
 	jx	a3
+#else
+.equ	.Lksp,	.Lunrecoverable
+#endif
 
 	/* Critical! We can't handle this situation. PANIC! */
 
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
index d506774..c1be9a4 100644
--- a/arch/xtensa/kernel/vmlinux.lds.S
+++ b/arch/xtensa/kernel/vmlinux.lds.S
@@ -17,6 +17,7 @@
 #include <asm-generic/vmlinux.lds.h>
 
 #include <variant/core.h>
+#include <platform/hardware.h>
 OUTPUT_ARCH(xtensa)
 ENTRY(_start)
 
@@ -26,7 +27,9 @@
 jiffies = jiffies_64;
 #endif
 
+#ifndef KERNELOFFSET
 #define KERNELOFFSET 0xd0001000
+#endif
 
 /* Note: In the following macros, it would be nice to specify only the
    vector name and section kind and construct "sym" and "section" using
diff --git a/arch/xtensa/mm/Makefile b/arch/xtensa/mm/Makefile
index 64e304a..f0b646d 100644
--- a/arch/xtensa/mm/Makefile
+++ b/arch/xtensa/mm/Makefile
@@ -2,4 +2,5 @@
 # Makefile for the Linux/Xtensa-specific parts of the memory manager.
 #
 
-obj-y	 := init.o fault.o tlb.o misc.o cache.o
+obj-y			:= init.o cache.o misc.o
+obj-$(CONFIG_MMU)	+= fault.o mmu.o tlb.o
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c
index 34163cf..427e14f 100644
--- a/arch/xtensa/mm/init.c
+++ b/arch/xtensa/mm/init.c
@@ -24,15 +24,8 @@
 #include <linux/mm.h>
 #include <linux/slab.h>
 
-#include <asm/pgtable.h>
 #include <asm/bootparam.h>
-#include <asm/mmu_context.h>
-#include <asm/tlb.h>
 #include <asm/page.h>
-#include <asm/pgalloc.h>
-
-
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 
 /* References to section boundaries */
 
@@ -130,7 +123,8 @@
 
 	/* Find an area to use for the bootmem bitmap. */
 
-	bootmap_size = bootmem_bootmap_pages(max_low_pfn) << PAGE_SHIFT;
+	bootmap_size = bootmem_bootmap_pages(max_low_pfn - min_low_pfn);
+	bootmap_size <<= PAGE_SHIFT;
 	bootmap_start = ~0;
 
 	for (i=0; i<sysmem.nr_banks; i++)
@@ -145,8 +139,9 @@
 	/* Reserve the bootmem bitmap area */
 
 	mem_reserve(bootmap_start, bootmap_start + bootmap_size, 1);
-	bootmap_size = init_bootmem_node(NODE_DATA(0), min_low_pfn,
+	bootmap_size = init_bootmem_node(NODE_DATA(0),
 					 bootmap_start >> PAGE_SHIFT,
+					 min_low_pfn,
 					 max_low_pfn);
 
 	/* Add all remaining memory pieces into the bootmem map */
@@ -158,14 +153,14 @@
 }
 
 
-void __init paging_init(void)
+void __init zones_init(void)
 {
 	unsigned long zones_size[MAX_NR_ZONES];
 	int i;
 
 	/* All pages are DMA-able, so we put them all in the DMA zone. */
 
-	zones_size[ZONE_DMA] = max_low_pfn;
+	zones_size[ZONE_DMA] = max_low_pfn - ARCH_PFN_OFFSET;
 	for (i = 1; i < MAX_NR_ZONES; i++)
 		zones_size[i] = 0;
 
@@ -173,40 +168,7 @@
 	zones_size[ZONE_HIGHMEM] = max_pfn - max_low_pfn;
 #endif
 
-	/* Initialize the kernel's page tables. */
-
-	memset(swapper_pg_dir, 0, PAGE_SIZE);
-
-	free_area_init(zones_size);
-}
-
-/*
- * Flush the mmu and reset associated register to default values.
- */
-
-void __init init_mmu (void)
-{
-	/* Writing zeros to the <t>TLBCFG special registers ensure
-	 * that valid values exist in the register.  For existing
-	 * PGSZID<w> fields, zero selects the first element of the
-	 * page-size array.  For nonexistent PGSZID<w> fields, zero is
-	 * the best value to write.  Also, when changing PGSZID<w>
-	 * fields, the corresponding TLB must be flushed.
-	 */
-	set_itlbcfg_register (0);
-	set_dtlbcfg_register (0);
-	flush_tlb_all ();
-
-	/* Set rasid register to a known value. */
-
-	set_rasid_register (ASID_USER_FIRST);
-
-	/* Set PTEVADDR special register to the start of the page
-	 * table, which is in kernel mappable space (ie. not
-	 * statically mapped).  This register's value is undefined on
-	 * reset.
-	 */
-	set_ptevaddr_register (PGTABLE_START);
+	free_area_init_node(0, zones_size, ARCH_PFN_OFFSET, NULL);
 }
 
 /*
@@ -218,8 +180,8 @@
 	unsigned long codesize, reservedpages, datasize, initsize;
 	unsigned long highmemsize, tmp, ram;
 
-	max_mapnr = num_physpages = max_low_pfn;
-	high_memory = (void *) __va(max_mapnr << PAGE_SHIFT);
+	max_mapnr = num_physpages = max_low_pfn - ARCH_PFN_OFFSET;
+	high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
 	highmemsize = 0;
 
 #ifdef CONFIG_HIGHMEM
@@ -229,7 +191,7 @@
 	totalram_pages += free_all_bootmem();
 
 	reservedpages = ram = 0;
-	for (tmp = 0; tmp < max_low_pfn; tmp++) {
+	for (tmp = 0; tmp < max_mapnr; tmp++) {
 		ram++;
 		if (PageReserved(mem_map+tmp))
 			reservedpages++;
@@ -279,23 +241,3 @@
 	printk("Freeing unused kernel memory: %dk freed\n",
 	       (&__init_end - &__init_begin) >> 10);
 }
-
-struct kmem_cache *pgtable_cache __read_mostly;
-
-static void pgd_ctor(void* addr)
-{
-	pte_t* ptep = (pte_t*)addr;
-	int i;
-
-	for (i = 0; i < 1024; i++, ptep++)
-		pte_clear(NULL, 0, ptep);
-
-}
-
-void __init pgtable_cache_init(void)
-{
-	pgtable_cache = kmem_cache_create("pgd",
-			PAGE_SIZE, PAGE_SIZE,
-			SLAB_HWCACHE_ALIGN,
-			pgd_ctor);
-}
diff --git a/arch/xtensa/mm/misc.S b/arch/xtensa/mm/misc.S
index c885664..b048406 100644
--- a/arch/xtensa/mm/misc.S
+++ b/arch/xtensa/mm/misc.S
@@ -84,6 +84,7 @@
 
 	retw
 
+#ifdef CONFIG_MMU
 /*
  * If we have to deal with cache aliasing, we use temporary memory mappings
  * to ensure that the source and destination pages have the same color as
@@ -311,6 +312,7 @@
 /* End of special treatment in tlb miss exception */
 
 ENTRY(__tlbtemp_mapping_end)
+#endif /* CONFIG_MMU
 
 /*
  * void __invalidate_icache_page(ulong start)
diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c
new file mode 100644
index 0000000..4bb91a9
--- /dev/null
+++ b/arch/xtensa/mm/mmu.c
@@ -0,0 +1,70 @@
+/*
+ * xtensa mmu stuff
+ *
+ * Extracted from init.c
+ */
+#include <linux/percpu.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/cache.h>
+
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+#include <asm/mmu_context.h>
+#include <asm/page.h>
+
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
+
+void __init paging_init(void)
+{
+	memset(swapper_pg_dir, 0, PAGE_SIZE);
+}
+
+/*
+ * Flush the mmu and reset associated register to default values.
+ */
+void __init init_mmu(void)
+{
+	/* Writing zeros to the <t>TLBCFG special registers ensure
+	 * that valid values exist in the register.  For existing
+	 * PGSZID<w> fields, zero selects the first element of the
+	 * page-size array.  For nonexistent PGSZID<w> fields, zero is
+	 * the best value to write.  Also, when changing PGSZID<w>
+	 * fields, the corresponding TLB must be flushed.
+	 */
+	set_itlbcfg_register(0);
+	set_dtlbcfg_register(0);
+	flush_tlb_all();
+
+	/* Set rasid register to a known value. */
+
+	set_rasid_register(ASID_USER_FIRST);
+
+	/* Set PTEVADDR special register to the start of the page
+	 * table, which is in kernel mappable space (ie. not
+	 * statically mapped).  This register's value is undefined on
+	 * reset.
+	 */
+	set_ptevaddr_register(PGTABLE_START);
+}
+
+struct kmem_cache *pgtable_cache __read_mostly;
+
+static void pgd_ctor(void *addr)
+{
+	pte_t *ptep = (pte_t *)addr;
+	int i;
+
+	for (i = 0; i < 1024; i++, ptep++)
+		pte_clear(NULL, 0, ptep);
+
+}
+
+void __init pgtable_cache_init(void)
+{
+	pgtable_cache = kmem_cache_create("pgd",
+			PAGE_SIZE, PAGE_SIZE,
+			SLAB_HWCACHE_ALIGN,
+			pgd_ctor);
+}
diff --git a/arch/xtensa/platforms/s6105/Makefile b/arch/xtensa/platforms/s6105/Makefile
new file mode 100644
index 0000000..0be6194
--- /dev/null
+++ b/arch/xtensa/platforms/s6105/Makefile
@@ -0,0 +1,3 @@
+# Makefile for the Stretch S6105 eval board
+
+obj-y		:= setup.o device.o
diff --git a/arch/xtensa/platforms/s6105/device.c b/arch/xtensa/platforms/s6105/device.c
new file mode 100644
index 0000000..78b08be
--- /dev/null
+++ b/arch/xtensa/platforms/s6105/device.c
@@ -0,0 +1,67 @@
+/*
+ * s6105 platform devices
+ *
+ * Copyright (c) 2009 emlix GmbH
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+
+#include <variant/hardware.h>
+
+#define UART_INTNUM		4
+
+static const signed char uart_irq_mappings[] = {
+	S6_INTC_UART(0),
+	S6_INTC_UART(1),
+	-1,
+};
+
+const signed char *platform_irq_mappings[NR_IRQS] = {
+	[UART_INTNUM] = uart_irq_mappings,
+};
+
+static struct plat_serial8250_port serial_platform_data[] = {
+	{
+		.membase = (void *)S6_REG_UART + 0x0000,
+		.mapbase = S6_REG_UART + 0x0000,
+		.irq = UART_INTNUM,
+		.uartclk = S6_SCLK,
+		.regshift = 2,
+		.iotype = SERIAL_IO_MEM,
+		.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST,
+	},
+	{
+		.membase = (void *)S6_REG_UART + 0x1000,
+		.mapbase = S6_REG_UART + 0x1000,
+		.irq = UART_INTNUM,
+		.uartclk = S6_SCLK,
+		.regshift = 2,
+		.iotype = SERIAL_IO_MEM,
+		.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST,
+	},
+	{ },
+};
+
+static struct platform_device platform_devices[] = {
+	{
+		.name = "serial8250",
+		.id = PLAT8250_DEV_PLATFORM,
+		.dev = {
+			.platform_data = serial_platform_data,
+		},
+	},
+};
+
+static int __init device_init(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(platform_devices); i++)
+		platform_device_register(&platform_devices[i]);
+	return 0;
+}
+arch_initcall_sync(device_init);
diff --git a/arch/xtensa/platforms/s6105/include/platform/gpio.h b/arch/xtensa/platforms/s6105/include/platform/gpio.h
new file mode 100644
index 0000000..fa11aa4
--- /dev/null
+++ b/arch/xtensa/platforms/s6105/include/platform/gpio.h
@@ -0,0 +1,27 @@
+#ifndef __ASM_XTENSA_S6105_GPIO_H
+#define __ASM_XTENSA_S6105_GPIO_H
+
+#define GPIO_BP_TEMP_ALARM	0
+#define GPIO_PB_RESET_IN	1
+#define GPIO_EXP_IRQ		2
+#define GPIO_TRIGGER_IRQ	3
+#define GPIO_RTC_IRQ		4
+#define GPIO_PHY_IRQ		5
+#define GPIO_IMAGER_RESET	6
+#define GPIO_SD_IRQ		7
+#define GPIO_MINI_BOOT_INH	8
+#define GPIO_BOARD_RESET	9
+#define GPIO_EXP_PRESENT	10
+#define GPIO_LED1_NGREEN	12
+#define GPIO_LED1_RED		13
+#define GPIO_LED0_NGREEN	14
+#define GPIO_LED0_NRED		15
+#define GPIO_SPI_CS0		16
+#define GPIO_SPI_CS1		17
+#define GPIO_SPI_CS3		19
+#define GPIO_SPI_CS4		20
+#define GPIO_SD_WP		21
+#define GPIO_BP_RESET		22
+#define GPIO_ALARM_OUT		23
+
+#endif /* __ASM_XTENSA_S6105_GPIO_H */
diff --git a/arch/xtensa/platforms/s6105/include/platform/hardware.h b/arch/xtensa/platforms/s6105/include/platform/hardware.h
new file mode 100644
index 0000000..d628efa
--- /dev/null
+++ b/arch/xtensa/platforms/s6105/include/platform/hardware.h
@@ -0,0 +1,11 @@
+#ifndef __XTENSA_S6105_HARDWARE_H
+#define __XTENSA_S6105_HARDWARE_H
+
+#define PLATFORM_DEFAULT_MEM_START	0x40000000
+#define PLATFORM_DEFAULT_MEM_SIZE	0x08000000
+
+#define MAX_DMA_ADDRESS			0
+
+#define KERNELOFFSET			(PLATFORM_DEFAULT_MEM_START + 0x1000)
+
+#endif /* __XTENSA_S6105_HARDWARE_H */
diff --git a/arch/xtensa/platforms/s6105/include/platform/serial.h b/arch/xtensa/platforms/s6105/include/platform/serial.h
new file mode 100644
index 0000000..c8a771e5
--- /dev/null
+++ b/arch/xtensa/platforms/s6105/include/platform/serial.h
@@ -0,0 +1,8 @@
+#ifndef __ASM_XTENSA_S6105_SERIAL_H
+#define __ASM_XTENSA_S6105_SERIAL_H
+
+#include <variant/hardware.h>
+
+#define BASE_BAUD (S6_SCLK / 16)
+
+#endif /* __ASM_XTENSA_S6105_SERIAL_H */
diff --git a/arch/xtensa/platforms/s6105/setup.c b/arch/xtensa/platforms/s6105/setup.c
new file mode 100644
index 0000000..ae041d5
--- /dev/null
+++ b/arch/xtensa/platforms/s6105/setup.c
@@ -0,0 +1,61 @@
+/*
+ * s6105 control routines
+ *
+ * Copyright (c) 2009 emlix GmbH
+ */
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <asm/bootparam.h>
+
+#include <variant/hardware.h>
+#include <platform/gpio.h>
+
+void platform_halt(void)
+{
+	local_irq_disable();
+	while (1)
+		;
+}
+
+void platform_power_off(void)
+{
+	platform_halt();
+}
+
+void platform_restart(void)
+{
+	platform_halt();
+}
+
+void __init platform_setup(char **cmdline)
+{
+	unsigned long reg;
+
+	reg = readl(S6_REG_GREG1 + S6_GREG1_CLKGATE);
+	reg &= ~(1 << S6_GREG1_BLOCK_SB);
+	writel(reg, S6_REG_GREG1 + S6_GREG1_CLKGATE);
+
+	reg = readl(S6_REG_GREG1 + S6_GREG1_BLOCKENA);
+	reg |= 1 << S6_GREG1_BLOCK_SB;
+	writel(reg, S6_REG_GREG1 + S6_GREG1_BLOCKENA);
+
+	printk(KERN_NOTICE "S6105 on Stretch S6000 - "
+		"Copyright (C) 2009 emlix GmbH <info@emlix.com>\n");
+}
+
+void __init platform_init(bp_tag_t *first)
+{
+	gpio_request(GPIO_LED1_NGREEN, "led1_green");
+	gpio_request(GPIO_LED1_RED, "led1_red");
+	gpio_direction_output(GPIO_LED1_NGREEN, 1);
+}
+
+void platform_heartbeat(void)
+{
+	static unsigned int c;
+
+	if (!(++c & 0x4F))
+		gpio_direction_output(GPIO_LED1_RED, !(c & 0x10));
+}
diff --git a/arch/xtensa/platforms/xt2000/include/platform/hardware.h b/arch/xtensa/platforms/xt2000/include/platform/hardware.h
index 41459ad..886ef15 100644
--- a/arch/xtensa/platforms/xt2000/include/platform/hardware.h
+++ b/arch/xtensa/platforms/xt2000/include/platform/hardware.h
@@ -16,7 +16,6 @@
 #define _XTENSA_XT2000_HARDWARE_H
 
 #include <variant/core.h>
-#include <asm/io.h>
 
 /* 
  * Memory configuration.
diff --git a/arch/xtensa/variants/s6000/Makefile b/arch/xtensa/variants/s6000/Makefile
new file mode 100644
index 0000000..03b3975
--- /dev/null
+++ b/arch/xtensa/variants/s6000/Makefile
@@ -0,0 +1,3 @@
+# s6000 Makefile
+
+obj-y		+= irq.o gpio.o
diff --git a/arch/xtensa/variants/s6000/gpio.c b/arch/xtensa/variants/s6000/gpio.c
new file mode 100644
index 0000000..33a8d95
--- /dev/null
+++ b/arch/xtensa/variants/s6000/gpio.c
@@ -0,0 +1,71 @@
+/*
+ * s6000 gpio driver
+ *
+ * Copyright (c) 2009 emlix GmbH
+ * Authors:	Oskar Schirmer <os@emlix.com>
+ *		Johannes Weiner <jw@emlix.com>
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <variant/hardware.h>
+
+#define S6_GPIO_DATA		0x000
+#define S6_GPIO_IS		0x404
+#define S6_GPIO_IBE		0x408
+#define S6_GPIO_IEV		0x40C
+#define S6_GPIO_IE		0x410
+#define S6_GPIO_RIS		0x414
+#define S6_GPIO_MIS		0x418
+#define S6_GPIO_IC		0x41C
+#define S6_GPIO_AFSEL		0x420
+#define S6_GPIO_DIR		0x800
+#define S6_GPIO_BANK(nr)	((nr) * 0x1000)
+#define S6_GPIO_MASK(nr)	(4 << (nr))
+#define S6_GPIO_OFFSET(nr) \
+		(S6_GPIO_BANK((nr) >> 3) + S6_GPIO_MASK((nr) & 7))
+
+static int direction_input(struct gpio_chip *chip, unsigned int off)
+{
+	writeb(0, S6_REG_GPIO + S6_GPIO_DIR + S6_GPIO_OFFSET(off));
+	return 0;
+}
+
+static int get(struct gpio_chip *chip, unsigned int off)
+{
+	return readb(S6_REG_GPIO + S6_GPIO_DATA + S6_GPIO_OFFSET(off));
+}
+
+static int direction_output(struct gpio_chip *chip, unsigned int off, int val)
+{
+	unsigned rel = S6_GPIO_OFFSET(off);
+	writeb(~0, S6_REG_GPIO + S6_GPIO_DIR + rel);
+	writeb(val ? ~0 : 0, S6_REG_GPIO + S6_GPIO_DATA + rel);
+	return 0;
+}
+
+static void set(struct gpio_chip *chip, unsigned int off, int val)
+{
+	writeb(val ? ~0 : 0, S6_REG_GPIO + S6_GPIO_DATA + S6_GPIO_OFFSET(off));
+}
+
+static struct gpio_chip gpiochip = {
+	.owner = THIS_MODULE,
+	.direction_input = direction_input,
+	.get = get,
+	.direction_output = direction_output,
+	.set = set,
+	.base = 0,
+	.ngpio = 24,
+	.can_sleep = 0, /* no blocking io needed */
+	.exported = 0, /* no exporting to userspace */
+};
+
+static int gpio_init(void)
+{
+	return gpiochip_add(&gpiochip);
+}
+device_initcall(gpio_init);
diff --git a/arch/xtensa/variants/s6000/include/variant/core.h b/arch/xtensa/variants/s6000/include/variant/core.h
new file mode 100644
index 0000000..af00795
--- /dev/null
+++ b/arch/xtensa/variants/s6000/include/variant/core.h
@@ -0,0 +1,431 @@
+/*
+ * Xtensa processor core configuration information.
+ *
+ * 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) 1999-2008 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_CORE_CONFIGURATION_H
+#define _XTENSA_CORE_CONFIGURATION_H
+
+
+/****************************************************************************
+	    Parameters Useful for Any Code, USER or PRIVILEGED
+ ****************************************************************************/
+
+/*
+ *  Note:  Macros of the form XCHAL_HAVE_*** have a value of 1 if the option is
+ *  configured, and a value of 0 otherwise.  These macros are always defined.
+ */
+
+
+/*----------------------------------------------------------------------
+				ISA
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_BE			0	/* big-endian byte ordering */
+#define XCHAL_HAVE_WINDOWED		1	/* windowed registers option */
+#define XCHAL_NUM_AREGS			64	/* num of physical addr regs */
+#define XCHAL_NUM_AREGS_LOG2		6	/* log2(XCHAL_NUM_AREGS) */
+#define XCHAL_MAX_INSTRUCTION_SIZE	8	/* max instr bytes (3..8) */
+#define XCHAL_HAVE_DEBUG		1	/* debug option */
+#define XCHAL_HAVE_DENSITY		1	/* 16-bit instructions */
+#define XCHAL_HAVE_LOOPS		1	/* zero-overhead loops */
+#define XCHAL_HAVE_NSA			1	/* NSA/NSAU instructions */
+#define XCHAL_HAVE_MINMAX		1	/* MIN/MAX instructions */
+#define XCHAL_HAVE_SEXT			1	/* SEXT instruction */
+#define XCHAL_HAVE_CLAMPS		1	/* CLAMPS instruction */
+#define XCHAL_HAVE_MUL16		1	/* MUL16S/MUL16U instructions */
+#define XCHAL_HAVE_MUL32		1	/* MULL instruction */
+#define XCHAL_HAVE_MUL32_HIGH		1	/* MULUH/MULSH instructions */
+#define XCHAL_HAVE_DIV32		0	/* QUOS/QUOU/REMS/REMU instructions */
+#define XCHAL_HAVE_L32R			1	/* L32R instruction */
+#define XCHAL_HAVE_ABSOLUTE_LITERALS	1	/* non-PC-rel (extended) L32R */
+#define XCHAL_HAVE_CONST16		0	/* CONST16 instruction */
+#define XCHAL_HAVE_ADDX			1	/* ADDX#/SUBX# instructions */
+#define XCHAL_HAVE_WIDE_BRANCHES	0	/* B*.W18 or B*.W15 instr's */
+#define XCHAL_HAVE_PREDICTED_BRANCHES	0	/* B[EQ/EQZ/NE/NEZ]T instr's */
+#define XCHAL_HAVE_CALL4AND12		1	/* (obsolete option) */
+#define XCHAL_HAVE_ABS			1	/* ABS instruction */
+/*#define XCHAL_HAVE_POPC		0*/	/* POPC instruction */
+/*#define XCHAL_HAVE_CRC		0*/	/* CRC instruction */
+#define XCHAL_HAVE_RELEASE_SYNC		0	/* L32AI/S32RI instructions */
+#define XCHAL_HAVE_S32C1I		0	/* S32C1I instruction */
+#define XCHAL_HAVE_SPECULATION		0	/* speculation */
+#define XCHAL_HAVE_FULL_RESET		0	/* all regs/state reset */
+#define XCHAL_NUM_CONTEXTS		1	/* */
+#define XCHAL_NUM_MISC_REGS		4	/* num of scratch regs (0..4) */
+#define XCHAL_HAVE_TAP_MASTER		0	/* JTAG TAP control instr's */
+#define XCHAL_HAVE_PRID			0	/* processor ID register */
+#define XCHAL_HAVE_THREADPTR		0	/* THREADPTR register */
+#define XCHAL_HAVE_BOOLEANS		1	/* boolean registers */
+#define XCHAL_HAVE_CP			1	/* CPENABLE reg (coprocessor) */
+#define XCHAL_CP_MAXCFG			8	/* max allowed cp id plus one */
+#define XCHAL_HAVE_MAC16		0	/* MAC16 package */
+#define XCHAL_HAVE_VECTORFPU2005	0	/* vector floating-point pkg */
+#define XCHAL_HAVE_FP			1	/* floating point pkg */
+#define XCHAL_HAVE_VECTRA1		0	/* Vectra I  pkg */
+#define XCHAL_HAVE_VECTRALX		0	/* Vectra LX pkg */
+#define XCHAL_HAVE_HIFI2		0	/* HiFi2 Audio Engine pkg */
+
+
+/*----------------------------------------------------------------------
+				MISC
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_NUM_WRITEBUFFER_ENTRIES	8	/* size of write buffer */
+#define XCHAL_INST_FETCH_WIDTH		8	/* instr-fetch width in bytes */
+#define XCHAL_DATA_WIDTH		16	/* data width in bytes */
+/*  In T1050, applies to selected core load and store instructions (see ISA): */
+#define XCHAL_UNALIGNED_LOAD_EXCEPTION	1	/* unaligned loads cause exc. */
+#define XCHAL_UNALIGNED_STORE_EXCEPTION	1	/* unaligned stores cause exc.*/
+
+#define XCHAL_SW_VERSION		701001	/* sw version of this header */
+
+#define XCHAL_CORE_ID			"stretch_bali"	/* alphanum core name
+						   (CoreID) set in the Xtensa
+						   Processor Generator */
+
+#define XCHAL_BUILD_UNIQUE_ID		0x000104B9	/* 22-bit sw build ID */
+
+/*
+ *  These definitions describe the hardware targeted by this software.
+ */
+#define XCHAL_HW_CONFIGID0		0xC2F3F9FE	/* ConfigID hi 32 bits*/
+#define XCHAL_HW_CONFIGID1		0x054104B9	/* ConfigID lo 32 bits*/
+#define XCHAL_HW_VERSION_NAME		"LX1.0.2"	/* full version name */
+#define XCHAL_HW_VERSION_MAJOR		2100	/* major ver# of targeted hw */
+#define XCHAL_HW_VERSION_MINOR		2	/* minor ver# of targeted hw */
+#define XCHAL_HW_VERSION		210002	/* major*100+minor */
+#define XCHAL_HW_REL_LX1		1
+#define XCHAL_HW_REL_LX1_0		1
+#define XCHAL_HW_REL_LX1_0_2		1
+#define XCHAL_HW_CONFIGID_RELIABLE	1
+/*  If software targets a *range* of hardware versions, these are the bounds: */
+#define XCHAL_HW_MIN_VERSION_MAJOR	2100	/* major v of earliest tgt hw */
+#define XCHAL_HW_MIN_VERSION_MINOR	2	/* minor v of earliest tgt hw */
+#define XCHAL_HW_MIN_VERSION		210002	/* earliest targeted hw */
+#define XCHAL_HW_MAX_VERSION_MAJOR	2100	/* major v of latest tgt hw */
+#define XCHAL_HW_MAX_VERSION_MINOR	2	/* minor v of latest tgt hw */
+#define XCHAL_HW_MAX_VERSION		210002	/* latest targeted hw */
+
+
+/*----------------------------------------------------------------------
+				CACHE
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_ICACHE_LINESIZE		16	/* I-cache line size in bytes */
+#define XCHAL_DCACHE_LINESIZE		16	/* D-cache line size in bytes */
+#define XCHAL_ICACHE_LINEWIDTH		4	/* log2(I line size in bytes) */
+#define XCHAL_DCACHE_LINEWIDTH		4	/* log2(D line size in bytes) */
+
+#define XCHAL_ICACHE_SIZE		32768	/* I-cache size in bytes or 0 */
+#define XCHAL_DCACHE_SIZE		32768	/* D-cache size in bytes or 0 */
+
+#define XCHAL_DCACHE_IS_WRITEBACK	1	/* writeback feature */
+
+
+
+
+/****************************************************************************
+    Parameters Useful for PRIVILEGED (Supervisory or Non-Virtualized) Code
+ ****************************************************************************/
+
+
+#ifndef XTENSA_HAL_NON_PRIVILEGED_ONLY
+
+/*----------------------------------------------------------------------
+				CACHE
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_PIF			1	/* any outbound PIF present */
+
+/*  If present, cache size in bytes == (ways * 2^(linewidth + setwidth)).  */
+
+/*  Number of cache sets in log2(lines per way):  */
+#define XCHAL_ICACHE_SETWIDTH		9
+#define XCHAL_DCACHE_SETWIDTH		10
+
+/*  Cache set associativity (number of ways):  */
+#define XCHAL_ICACHE_WAYS		4
+#define XCHAL_DCACHE_WAYS		2
+
+/*  Cache features:  */
+#define XCHAL_ICACHE_LINE_LOCKABLE	1
+#define XCHAL_DCACHE_LINE_LOCKABLE	0
+#define XCHAL_ICACHE_ECC_PARITY		0
+#define XCHAL_DCACHE_ECC_PARITY		0
+
+/*  Number of encoded cache attr bits (see <xtensa/hal.h> for decoded bits):  */
+#define XCHAL_CA_BITS			4
+
+
+/*----------------------------------------------------------------------
+			INTERNAL I/D RAM/ROMs and XLMI
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_NUM_INSTROM		0	/* number of core instr. ROMs */
+#define XCHAL_NUM_INSTRAM		0	/* number of core instr. RAMs */
+#define XCHAL_NUM_DATAROM		0	/* number of core data ROMs */
+#define XCHAL_NUM_DATARAM		1	/* number of core data RAMs */
+#define XCHAL_NUM_URAM			0	/* number of core unified RAMs*/
+#define XCHAL_NUM_XLMI			1	/* number of core XLMI ports */
+
+/*  Data RAM 0:  */
+#define XCHAL_DATARAM0_VADDR		0x3FFF0000
+#define XCHAL_DATARAM0_PADDR		0x3FFF0000
+#define XCHAL_DATARAM0_SIZE		65536
+#define XCHAL_DATARAM0_ECC_PARITY	0
+
+/*  XLMI Port 0:  */
+#define XCHAL_XLMI0_VADDR		0x37F80000
+#define XCHAL_XLMI0_PADDR		0x37F80000
+#define XCHAL_XLMI0_SIZE		262144
+#define XCHAL_XLMI0_ECC_PARITY	0
+
+
+/*----------------------------------------------------------------------
+			INTERRUPTS and TIMERS
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_INTERRUPTS		1	/* interrupt option */
+#define XCHAL_HAVE_HIGHPRI_INTERRUPTS	1	/* med/high-pri. interrupts */
+#define XCHAL_HAVE_NMI			1	/* non-maskable interrupt */
+#define XCHAL_HAVE_CCOUNT		1	/* CCOUNT reg. (timer option) */
+#define XCHAL_NUM_TIMERS		3	/* number of CCOMPAREn regs */
+#define XCHAL_NUM_INTERRUPTS		27	/* number of interrupts */
+#define XCHAL_NUM_INTERRUPTS_LOG2	5	/* ceil(log2(NUM_INTERRUPTS)) */
+#define XCHAL_NUM_EXTINTERRUPTS		20	/* num of external interrupts */
+#define XCHAL_NUM_INTLEVELS		4	/* number of interrupt levels
+						   (not including level zero) */
+#define XCHAL_EXCM_LEVEL		1	/* level masked by PS.EXCM */
+	/* (always 1 in XEA1; levels 2 .. EXCM_LEVEL are "medium priority") */
+
+/*  Masks of interrupts at each interrupt level:  */
+#define XCHAL_INTLEVEL1_MASK		0x01F07FFF
+#define XCHAL_INTLEVEL2_MASK		0x02018000
+#define XCHAL_INTLEVEL3_MASK		0x04060000
+#define XCHAL_INTLEVEL4_MASK		0x00000000
+#define XCHAL_INTLEVEL5_MASK		0x00080000
+#define XCHAL_INTLEVEL6_MASK		0x00000000
+#define XCHAL_INTLEVEL7_MASK		0x00000000
+
+/*  Masks of interrupts at each range 1..n of interrupt levels:  */
+#define XCHAL_INTLEVEL1_ANDBELOW_MASK	0x01F07FFF
+#define XCHAL_INTLEVEL2_ANDBELOW_MASK	0x03F1FFFF
+#define XCHAL_INTLEVEL3_ANDBELOW_MASK	0x07F7FFFF
+#define XCHAL_INTLEVEL4_ANDBELOW_MASK	0x07F7FFFF
+#define XCHAL_INTLEVEL5_ANDBELOW_MASK	0x07FFFFFF
+#define XCHAL_INTLEVEL6_ANDBELOW_MASK	0x07FFFFFF
+#define XCHAL_INTLEVEL7_ANDBELOW_MASK	0x07FFFFFF
+
+/*  Level of each interrupt:  */
+#define XCHAL_INT0_LEVEL		1
+#define XCHAL_INT1_LEVEL		1
+#define XCHAL_INT2_LEVEL		1
+#define XCHAL_INT3_LEVEL		1
+#define XCHAL_INT4_LEVEL		1
+#define XCHAL_INT5_LEVEL		1
+#define XCHAL_INT6_LEVEL		1
+#define XCHAL_INT7_LEVEL		1
+#define XCHAL_INT8_LEVEL		1
+#define XCHAL_INT9_LEVEL		1
+#define XCHAL_INT10_LEVEL		1
+#define XCHAL_INT11_LEVEL		1
+#define XCHAL_INT12_LEVEL		1
+#define XCHAL_INT13_LEVEL		1
+#define XCHAL_INT14_LEVEL		1
+#define XCHAL_INT15_LEVEL		2
+#define XCHAL_INT16_LEVEL		2
+#define XCHAL_INT17_LEVEL		3
+#define XCHAL_INT18_LEVEL		3
+#define XCHAL_INT19_LEVEL		5
+#define XCHAL_INT20_LEVEL		1
+#define XCHAL_INT21_LEVEL		1
+#define XCHAL_INT22_LEVEL		1
+#define XCHAL_INT23_LEVEL		1
+#define XCHAL_INT24_LEVEL		1
+#define XCHAL_INT25_LEVEL		2
+#define XCHAL_INT26_LEVEL		3
+#define XCHAL_DEBUGLEVEL		4	/* debug interrupt level */
+#define XCHAL_HAVE_DEBUG_EXTERN_INT	1	/* OCD external db interrupt */
+#define XCHAL_NMILEVEL			5	/* NMI "level" (for use with
+						   EXCSAVE/EPS/EPC_n, RFI n) */
+
+/*  Type of each interrupt:  */
+#define XCHAL_INT0_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT1_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT2_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT3_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT4_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT5_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT6_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT7_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT8_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT9_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT10_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT11_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT12_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT13_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT14_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT15_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT16_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT17_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT18_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT19_TYPE 	XTHAL_INTTYPE_NMI
+#define XCHAL_INT20_TYPE 	XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT21_TYPE 	XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT22_TYPE 	XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT23_TYPE 	XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT24_TYPE 	XTHAL_INTTYPE_TIMER
+#define XCHAL_INT25_TYPE 	XTHAL_INTTYPE_TIMER
+#define XCHAL_INT26_TYPE 	XTHAL_INTTYPE_TIMER
+
+/*  Masks of interrupts for each type of interrupt:  */
+#define XCHAL_INTTYPE_MASK_UNCONFIGURED	0xF8000000
+#define XCHAL_INTTYPE_MASK_SOFTWARE	0x00F00000
+#define XCHAL_INTTYPE_MASK_EXTERN_EDGE	0x00000000
+#define XCHAL_INTTYPE_MASK_EXTERN_LEVEL	0x0007FFFF
+#define XCHAL_INTTYPE_MASK_TIMER	0x07000000
+#define XCHAL_INTTYPE_MASK_NMI		0x00080000
+#define XCHAL_INTTYPE_MASK_WRITE_ERROR	0x00000000
+
+/*  Interrupt numbers assigned to specific interrupt sources:  */
+#define XCHAL_TIMER0_INTERRUPT		24	/* CCOMPARE0 */
+#define XCHAL_TIMER1_INTERRUPT		25	/* CCOMPARE1 */
+#define XCHAL_TIMER2_INTERRUPT		26	/* CCOMPARE2 */
+#define XCHAL_TIMER3_INTERRUPT		XTHAL_TIMER_UNCONFIGURED
+#define XCHAL_NMI_INTERRUPT		19	/* non-maskable interrupt */
+
+/*  Interrupt numbers for levels at which only one interrupt is configured:  */
+#define XCHAL_INTLEVEL5_NUM		19
+/*  (There are many interrupts each at level(s) 1, 2, 3.)  */
+
+
+/*
+ *  External interrupt vectors/levels.
+ *  These macros describe how Xtensa processor interrupt numbers
+ *  (as numbered internally, eg. in INTERRUPT and INTENABLE registers)
+ *  map to external BInterrupt<n> pins, for those interrupts
+ *  configured as external (level-triggered, edge-triggered, or NMI).
+ *  See the Xtensa processor databook for more details.
+ */
+
+/*  Core interrupt numbers mapped to each EXTERNAL interrupt number:  */
+#define XCHAL_EXTINT0_NUM		0	/* (intlevel 1) */
+#define XCHAL_EXTINT1_NUM		1	/* (intlevel 1) */
+#define XCHAL_EXTINT2_NUM		2	/* (intlevel 1) */
+#define XCHAL_EXTINT3_NUM		3	/* (intlevel 1) */
+#define XCHAL_EXTINT4_NUM		4	/* (intlevel 1) */
+#define XCHAL_EXTINT5_NUM		5	/* (intlevel 1) */
+#define XCHAL_EXTINT6_NUM		6	/* (intlevel 1) */
+#define XCHAL_EXTINT7_NUM		7	/* (intlevel 1) */
+#define XCHAL_EXTINT8_NUM		8	/* (intlevel 1) */
+#define XCHAL_EXTINT9_NUM		9	/* (intlevel 1) */
+#define XCHAL_EXTINT10_NUM		10	/* (intlevel 1) */
+#define XCHAL_EXTINT11_NUM		11	/* (intlevel 1) */
+#define XCHAL_EXTINT12_NUM		12	/* (intlevel 1) */
+#define XCHAL_EXTINT13_NUM		13	/* (intlevel 1) */
+#define XCHAL_EXTINT14_NUM		14	/* (intlevel 1) */
+#define XCHAL_EXTINT15_NUM		15	/* (intlevel 2) */
+#define XCHAL_EXTINT16_NUM		16	/* (intlevel 2) */
+#define XCHAL_EXTINT17_NUM		17	/* (intlevel 3) */
+#define XCHAL_EXTINT18_NUM		18	/* (intlevel 3) */
+#define XCHAL_EXTINT19_NUM		19	/* (intlevel 5) */
+
+
+/*----------------------------------------------------------------------
+			EXCEPTIONS and VECTORS
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_XEA_VERSION		2	/* Xtensa Exception Architecture
+						   number: 1 == XEA1 (old)
+							   2 == XEA2 (new)
+							   0 == XEAX (extern) */
+#define XCHAL_HAVE_XEA1			0	/* Exception Architecture 1 */
+#define XCHAL_HAVE_XEA2			1	/* Exception Architecture 2 */
+#define XCHAL_HAVE_XEAX			0	/* External Exception Arch. */
+#define XCHAL_HAVE_EXCEPTIONS		1	/* exception option */
+#define XCHAL_HAVE_MEM_ECC_PARITY	0	/* local memory ECC/parity */
+#define XCHAL_HAVE_VECTOR_SELECT	0	/* relocatable vectors */
+#define XCHAL_HAVE_VECBASE		0	/* relocatable vectors */
+
+#define XCHAL_RESET_VECOFS		0x00000000
+#define XCHAL_RESET_VECTOR_VADDR	0x3FFE03D0
+#define XCHAL_RESET_VECTOR_PADDR	0x3FFE03D0
+#define XCHAL_USER_VECOFS		0x00000000
+#define XCHAL_USER_VECTOR_VADDR		0x40000220
+#define XCHAL_USER_VECTOR_PADDR		0x40000220
+#define XCHAL_KERNEL_VECOFS		0x00000000
+#define XCHAL_KERNEL_VECTOR_VADDR	0x40000200
+#define XCHAL_KERNEL_VECTOR_PADDR	0x40000200
+#define XCHAL_DOUBLEEXC_VECOFS		0x00000000
+#define XCHAL_DOUBLEEXC_VECTOR_VADDR	0x400002A0
+#define XCHAL_DOUBLEEXC_VECTOR_PADDR	0x400002A0
+#define XCHAL_WINDOW_OF4_VECOFS		0x00000000
+#define XCHAL_WINDOW_UF4_VECOFS		0x00000040
+#define XCHAL_WINDOW_OF8_VECOFS		0x00000080
+#define XCHAL_WINDOW_UF8_VECOFS		0x000000C0
+#define XCHAL_WINDOW_OF12_VECOFS	0x00000100
+#define XCHAL_WINDOW_UF12_VECOFS	0x00000140
+#define XCHAL_WINDOW_VECTORS_VADDR	0x40000000
+#define XCHAL_WINDOW_VECTORS_PADDR	0x40000000
+#define XCHAL_INTLEVEL2_VECOFS		0x00000000
+#define XCHAL_INTLEVEL2_VECTOR_VADDR	0x40000240
+#define XCHAL_INTLEVEL2_VECTOR_PADDR	0x40000240
+#define XCHAL_INTLEVEL3_VECOFS		0x00000000
+#define XCHAL_INTLEVEL3_VECTOR_VADDR	0x40000260
+#define XCHAL_INTLEVEL3_VECTOR_PADDR	0x40000260
+#define XCHAL_INTLEVEL4_VECOFS		0x00000000
+#define XCHAL_INTLEVEL4_VECTOR_VADDR	0x40000390
+#define XCHAL_INTLEVEL4_VECTOR_PADDR	0x40000390
+#define XCHAL_DEBUG_VECOFS		XCHAL_INTLEVEL4_VECOFS
+#define XCHAL_DEBUG_VECTOR_VADDR	XCHAL_INTLEVEL4_VECTOR_VADDR
+#define XCHAL_DEBUG_VECTOR_PADDR	XCHAL_INTLEVEL4_VECTOR_PADDR
+#define XCHAL_NMI_VECOFS		0x00000000
+#define XCHAL_NMI_VECTOR_VADDR		0x400003B0
+#define XCHAL_NMI_VECTOR_PADDR		0x400003B0
+#define XCHAL_INTLEVEL5_VECOFS		XCHAL_NMI_VECOFS
+#define XCHAL_INTLEVEL5_VECTOR_VADDR	XCHAL_NMI_VECTOR_VADDR
+#define XCHAL_INTLEVEL5_VECTOR_PADDR	XCHAL_NMI_VECTOR_PADDR
+
+
+/*----------------------------------------------------------------------
+				DEBUG
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_OCD			1	/* OnChipDebug option */
+#define XCHAL_NUM_IBREAK		2	/* number of IBREAKn regs */
+#define XCHAL_NUM_DBREAK		2	/* number of DBREAKn regs */
+#define XCHAL_HAVE_OCD_DIR_ARRAY	1	/* faster OCD option */
+
+
+/*----------------------------------------------------------------------
+				MMU
+  ----------------------------------------------------------------------*/
+
+/*  See core-matmap.h header file for more details.  */
+
+#define XCHAL_HAVE_TLBS			1	/* inverse of HAVE_CACHEATTR */
+#define XCHAL_HAVE_SPANNING_WAY		1	/* one way maps I+D 4GB vaddr */
+#define XCHAL_HAVE_IDENTITY_MAP		1	/* vaddr == paddr always */
+#define XCHAL_HAVE_CACHEATTR		0	/* CACHEATTR register present */
+#define XCHAL_HAVE_MIMIC_CACHEATTR	1	/* region protection */
+#define XCHAL_HAVE_XLT_CACHEATTR	0	/* region prot. w/translation */
+#define XCHAL_HAVE_PTP_MMU		0	/* full MMU (with page table
+						   [autorefill] and protection)
+						   usable for an MMU-based OS */
+/*  If none of the above last 4 are set, it's a custom TLB configuration.  */
+
+#define XCHAL_MMU_ASID_BITS		0	/* number of bits in ASIDs */
+#define XCHAL_MMU_RINGS			1	/* number of rings (1..4) */
+#define XCHAL_MMU_RING_BITS		0	/* num of bits in RING field */
+
+#endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */
+
+
+#endif /* _XTENSA_CORE_CONFIGURATION_H */
+
diff --git a/arch/xtensa/variants/s6000/include/variant/hardware.h b/arch/xtensa/variants/s6000/include/variant/hardware.h
new file mode 100644
index 0000000..5d9ba09
--- /dev/null
+++ b/arch/xtensa/variants/s6000/include/variant/hardware.h
@@ -0,0 +1,259 @@
+#ifndef __XTENSA_S6000_HARDWARE_H
+#define __XTENSA_S6000_HARDWARE_H
+
+#define S6_SCLK			1843200
+
+#define S6_MEM_REG              0x20000000
+#define S6_MEM_EFI              0x33F00000
+#define S6_MEM_PCIE_DATARAM1    0x34000000
+#define S6_MEM_XLMI             0x37F80000
+#define S6_MEM_PIF_DATARAM1     0x37FFC000
+#define S6_MEM_GMAC             0x38000000
+#define S6_MEM_I2S              0x3A000000
+#define S6_MEM_EGIB             0x3C000000
+#define S6_MEM_PCIE_CFG         0x3E000000
+#define S6_MEM_PIF_DATARAM      0x3FFE0000
+#define S6_MEM_XLMI_DATARAM     0x3FFF0000
+#define S6_MEM_DDR              0x40000000
+#define S6_MEM_PCIE_APER        0xC0000000
+#define S6_MEM_AUX              0xF0000000
+
+/* Device addresses */
+
+#define S6_REG_SCB              S6_MEM_REG
+#define S6_REG_NB               (S6_REG_SCB + 0x10000)
+#define S6_REG_LMSDMA           (S6_REG_SCB + 0x20000)
+#define S6_REG_NI               (S6_REG_SCB + 0x30000)
+#define S6_REG_NIDMA            (S6_REG_SCB + 0x40000)
+#define S6_REG_NS               (S6_REG_SCB + 0x50000)
+#define S6_REG_DDR              (S6_REG_SCB + 0x60000)
+#define S6_REG_GREG1            (S6_REG_SCB + 0x70000)
+#define S6_REG_DP               (S6_REG_SCB + 0x80000)
+#define S6_REG_DPDMA            (S6_REG_SCB + 0x90000)
+#define S6_REG_EGIB             (S6_REG_SCB + 0xA0000)
+#define S6_REG_PCIE             (S6_REG_SCB + 0xB0000)
+#define S6_REG_I2S              (S6_REG_SCB + 0xC0000)
+#define S6_REG_GMAC             (S6_REG_SCB + 0xD0000)
+#define S6_REG_HIFDMA           (S6_REG_SCB + 0xE0000)
+#define S6_REG_GREG2            (S6_REG_SCB + 0xF0000)
+
+#define S6_REG_APB              S6_REG_SCB
+#define S6_REG_UART             (S6_REG_APB + 0x0000)
+#define S6_REG_INTC             (S6_REG_APB + 0x2000)
+#define S6_REG_SPI              (S6_REG_APB + 0x3000)
+#define S6_REG_I2C              (S6_REG_APB + 0x4000)
+#define S6_REG_GPIO             (S6_REG_APB + 0x8000)
+
+/* Global register block */
+
+#define S6_GREG1_PLL_LOCKCLEAR	0x000
+#define S6_GREG1_PLL_LOCK_SYS		0
+#define S6_GREG1_PLL_LOCK_IO		1
+#define S6_GREG1_PLL_LOCK_AIM		2
+#define S6_GREG1_PLL_LOCK_DP0		3
+#define S6_GREG1_PLL_LOCK_DP2		4
+#define S6_GREG1_PLL_LOCK_DDR		5
+#define S6_GREG1_PLL_LOCKSTAT	0x004
+#define S6_GREG1_PLL_LOCKSTAT_CURLOCK	0
+#define S6_GREG1_PLL_LOCKSTAT_EVERUNLCK	8
+#define S6_GREG1_PLLSEL		0x010
+#define S6_GREG1_PLLSEL_AIM		0
+#define S6_GREG1_PLLSEL_AIM_DDR2		0
+#define S6_GREG1_PLLSEL_AIM_300MHZ		1
+#define S6_GREG1_PLLSEL_AIM_240MHZ		2
+#define S6_GREG1_PLLSEL_AIM_200MHZ		3
+#define S6_GREG1_PLLSEL_AIM_150MHZ		4
+#define S6_GREG1_PLLSEL_AIM_120MHZ		5
+#define S6_GREG1_PLLSEL_AIM_40MHZ		6
+#define S6_GREG1_PLLSEL_AIM_PLLAIMREF		7
+#define S6_GREG1_PLLSEL_AIM_MASK		7
+#define S6_GREG1_PLLSEL_DDR		8
+#define S6_GREG1_PLLSEL_DDR_HS			0
+#define S6_GREG1_PLLSEL_DDR_333MHZ		1
+#define S6_GREG1_PLLSEL_DDR_250MHZ		2
+#define S6_GREG1_PLLSEL_DDR_200MHZ		3
+#define S6_GREG1_PLLSEL_DDR_167MHZ		4
+#define S6_GREG1_PLLSEL_DDR_100MHZ		5
+#define S6_GREG1_PLLSEL_DDR_33MHZ		6
+#define S6_GREG1_PLLSEL_DDR_PLLIOREF		7
+#define S6_GREG1_PLLSEL_DDR_MASK		7
+#define S6_GREG1_PLLSEL_GMAC		16
+#define S6_GREG1_PLLSEL_GMAC_125MHZ		0
+#define S6_GREG1_PLLSEL_GMAC_25MHZ		1
+#define S6_GREG1_PLLSEL_GMAC_2500KHZ		2
+#define S6_GREG1_PLLSEL_GMAC_EXTERN		3
+#define S6_GREG1_PLLSEL_GMAC_MASK		3
+#define S6_GREG1_PLLSEL_GMII		18
+#define S6_GREG1_PLLSEL_GMII_111MHZ		0
+#define S6_GREG1_PLLSEL_GMII_IOREF		1
+#define S6_GREG1_PLLSEL_GMII_NONE		2
+#define S6_GREG1_PLLSEL_GMII_125MHZ		3
+#define S6_GREG1_PLLSEL_GMII_MASK		3
+#define S6_GREG1_SYSUNLOCKCNT	0x020
+#define S6_GREG1_IOUNLOCKCNT	0x024
+#define S6_GREG1_AIMUNLOCKCNT	0x028
+#define S6_GREG1_DP0UNLOCKCNT	0x02C
+#define S6_GREG1_DP2UNLOCKCNT	0x030
+#define S6_GREG1_DDRUNLOCKCNT	0x034
+#define S6_GREG1_CLKBAL0	0x040
+#define S6_GREG1_CLKBAL0_LSGB		0
+#define S6_GREG1_CLKBAL0_LSPX		8
+#define S6_GREG1_CLKBAL0_MEMDO		16
+#define S6_GREG1_CLKBAL0_HSXT1		24
+#define S6_GREG1_CLKBAL1	0x044
+#define S6_GREG1_CLKBAL1_HSISEF		0
+#define S6_GREG1_CLKBAL1_HSNI		8
+#define S6_GREG1_CLKBAL1_HSNS		16
+#define S6_GREG1_CLKBAL1_HSISEFCFG	24
+#define S6_GREG1_CLKBAL2	0x048
+#define S6_GREG1_CLKBAL2_LSNB		0
+#define S6_GREG1_CLKBAL2_LSSB		8
+#define S6_GREG1_CLKBAL2_LSREST		24
+#define S6_GREG1_CLKBAL3	0x04C
+#define S6_GREG1_CLKBAL3_ISEFXAD	0
+#define S6_GREG1_CLKBAL3_ISEFLMS	8
+#define S6_GREG1_CLKBAL3_ISEFISEF	16
+#define S6_GREG1_CLKBAL3_DDRDD		24
+#define S6_GREG1_CLKBAL4	0x050
+#define S6_GREG1_CLKBAL4_DDRDP		0
+#define S6_GREG1_CLKBAL4_DDRDO		8
+#define S6_GREG1_CLKBAL4_DDRNB		16
+#define S6_GREG1_CLKBAL4_DDRLMS		24
+#define S6_GREG1_BLOCKENA	0x100
+#define S6_GREG1_BLOCK_DDR		0
+#define S6_GREG1_BLOCK_DP		1
+#define S6_GREG1_BLOCK_NSNI		2
+#define S6_GREG1_BLOCK_PCIE		3
+#define S6_GREG1_BLOCK_GMAC		4
+#define S6_GREG1_BLOCK_I2S		5
+#define S6_GREG1_BLOCK_EGIB		6
+#define S6_GREG1_BLOCK_SB		7
+#define S6_GREG1_BLOCK_XT1		8
+#define S6_GREG1_CLKGATE	0x104
+#define S6_GREG1_BGATE_AIMNORTH		9
+#define S6_GREG1_BGATE_AIMEAST		10
+#define S6_GREG1_BGATE_AIMWEST		11
+#define S6_GREG1_BGATE_AIMSOUTH		12
+#define S6_GREG1_CHIPRES	0x108
+#define S6_GREG1_CHIPRES_SOFTRES	0
+#define S6_GREG1_CHIPRES_LOSTLOCK	1
+#define S6_GREG1_RESETCAUSE	0x10C
+#define S6_GREG1_RESETCAUSE_RESETN	0
+#define S6_GREG1_RESETCAUSE_GLOBAL	1
+#define S6_GREG1_RESETCAUSE_WDOGTIMER	2
+#define S6_GREG1_RESETCAUSE_SWCHIP	3
+#define S6_GREG1_RESETCAUSE_PLLSYSLOSS	4
+#define S6_GREG1_RESETCAUSE_PCIE	5
+#define S6_GREG1_RESETCAUSE_CREATEDGLOB	6
+#define S6_GREG1_REFCLOCKCNT	0x110
+#define S6_GREG1_RESETTIMER	0x114
+#define S6_GREG1_NMITIMER	0x118
+#define S6_GREG1_GLOBAL_TIMER	0x11C
+#define S6_GREG1_TIMER0		0x180
+#define S6_GREG1_TIMER1		0x184
+#define S6_GREG1_UARTCLOCKSEL	0x204
+#define S6_GREG1_CHIPVERSPACKG	0x208
+#define S6_GREG1_CHIPVERSPACKG_CHIPVID	0
+#define S6_GREG1_CHIPVERSPACKG_PACKSEL	8
+#define S6_GREG1_ONDIETERMCTRL	0x20C
+#define S6_GREG1_ONDIETERMCTRL_WEST	0
+#define S6_GREG1_ONDIETERMCTRL_NORTH	2
+#define S6_GREG1_ONDIETERMCTRL_EAST	4
+#define S6_GREG1_ONDIETERMCTRL_SOUTH	6
+#define S6_GREG1_ONDIETERMCTRL_NONE		0
+#define S6_GREG1_ONDIETERMCTRL_75OHM		2
+#define S6_GREG1_ONDIETERMCTRL_MASK		3
+#define S6_GREG1_BOOT_CFG0	0x210
+#define S6_GREG1_BOOT_CFG0_AIMSTRONG	1
+#define S6_GREG1_BOOT_CFG0_MINIBOOTDL	2
+#define S6_GREG1_BOOT_CFG0_OCDGPIO8SET	5
+#define S6_GREG1_BOOT_CFG0_OCDGPIOENA	6
+#define S6_GREG1_BOOT_CFG0_DOWNSTREAM	7
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV	8
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_300MHZ	1
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_240MHZ	2
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_200MHZ	3
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_150MHZ	4
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_120MHZ	5
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_40MHZ	6
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_MASK	7
+#define S6_GREG1_BOOT_CFG0_BALHSLMS	12
+#define S6_GREG1_BOOT_CFG0_BALHSNB	18
+#define S6_GREG1_BOOT_CFG0_BALHSXAD	24
+#define S6_GREG1_BOOT_CFG1	0x214
+#define S6_GREG1_BOOT_CFG1_PCIE1LANE	1
+#define S6_GREG1_BOOT_CFG1_MPLLPRESCALE	2
+#define S6_GREG1_BOOT_CFG1_MPLLNCY	4
+#define S6_GREG1_BOOT_CFG1_MPLLNCY5	9
+#define S6_GREG1_BOOT_CFG1_BALHSREST	14
+#define S6_GREG1_BOOT_CFG1_BALHSPSMEMS	20
+#define S6_GREG1_BOOT_CFG1_BALLSGI	26
+#define S6_GREG1_BOOT_CFG2	0x218
+#define S6_GREG1_BOOT_CFG2_PEID		0
+#define S6_GREG1_BOOT_CFG3	0x21C
+#define S6_GREG1_DRAMBUSYHOLDOF	0x220
+#define S6_GREG1_DRAMBUSYHOLDOF_XT0	0
+#define S6_GREG1_DRAMBUSYHOLDOF_XT1	4
+#define S6_GREG1_DRAMBUSYHOLDOF_XT_MASK		7
+#define S6_GREG1_PCIEBAR1SIZE	0x224
+#define S6_GREG1_PCIEBAR2SIZE	0x228
+#define S6_GREG1_PCIEVENDOR	0x22C
+#define S6_GREG1_PCIEDEVICE	0x230
+#define S6_GREG1_PCIEREV	0x234
+#define S6_GREG1_PCIECLASS	0x238
+#define S6_GREG1_XT1DCACHEMISS	0x240
+#define S6_GREG1_XT1ICACHEMISS	0x244
+#define S6_GREG1_HWSEMAPHORE(n)	(0x400 + 4 * (n))
+#define S6_GREG1_HWSEMAPHORE_NB		16
+
+/* peripheral interrupt numbers */
+
+#define S6_INTC_GPIO(n)			(n)		/* 0..3 */
+#define S6_INTC_I2C			4
+#define S6_INTC_SPI			5
+#define S6_INTC_NB_ERR			6
+#define S6_INTC_DMA_LMSERR		7
+#define S6_INTC_DMA_LMSLOWWMRK(n)	(8 + (n))	/* 0..11 */
+#define S6_INTC_DMA_LMSPENDCNT(n)	(20 + (n))	/* 0..11 */
+#define S6_INTC_DMA HOSTLOWWMRK(n)	(32 + (n))	/* 0..6 */
+#define S6_INTC_DMA_HOSTPENDCNT(n)	(39 + (n))	/* 0..6 */
+#define S6_INTC_DMA_HOSTERR		46
+#define S6_INTC_UART(n)			(47 + (n))	/* 0..1 */
+#define S6_INTC_XAD			49
+#define S6_INTC_NI_ERR			50
+#define S6_INTC_NI_INFIFOFULL		51
+#define S6_INTC_DMA_NIERR		52
+#define S6_INTC_DMA_NILOWWMRK(n)	(53 + (n))	/* 0..3 */
+#define S6_INTC_DMA_NIPENDCNT(n)	(57 + (n))	/* 0..3 */
+#define S6_INTC_DDR			61
+#define S6_INTC_NS_ERR			62
+#define S6_INTC_EFI_CFGERR		63
+#define S6_INTC_EFI_ISEFTEST		64
+#define S6_INTC_EFI_WRITEERR		65
+#define S6_INTC_NMI_TIMER		66
+#define S6_INTC_PLLLOCK_SYS		67
+#define S6_INTC_PLLLOCK_IO		68
+#define S6_INTC_PLLLOCK_AIM		69
+#define S6_INTC_PLLLOCK_DP0		70
+#define S6_INTC_PLLLOCK_DP2		71
+#define S6_INTC_I2S_ERR			72
+#define S6_INTC_GMAC_STAT		73
+#define S6_INTC_GMAC_ERR		74
+#define S6_INTC_GIB_ERR			75
+#define S6_INTC_PCIE_ERR		76
+#define S6_INTC_PCIE_MSI(n)		(77 + (n))	/* 0..3 */
+#define S6_INTC_PCIE_INTA		81
+#define S6_INTC_PCIE_INTB		82
+#define S6_INTC_PCIE_INTC		83
+#define S6_INTC_PCIE_INTD		84
+#define S6_INTC_SW(n)			(85 + (n))	/* 0..9 */
+#define S6_INTC_SW_ENABLE(n)		(85 + 256 + (n))
+#define S6_INTC_DMA_DP_ERR		95
+#define S6_INTC_DMA_DPLOWWMRK(n)	(96 + (n))	/* 0..3 */
+#define S6_INTC_DMA_DPPENDCNT(n)	(100 + (n))	/* 0..3 */
+#define S6_INTC_DMA_DPTERMCNT(n)	(104 + (n))	/* 0..3 */
+#define S6_INTC_TIMER0			108
+#define S6_INTC_TIMER1			109
+#define S6_INTC_DMA_HOSTTERMCNT(n)	(110 + (n))	/* 0..6 */
+
+#endif /* __XTENSA_S6000_HARDWARE_H */
diff --git a/arch/xtensa/variants/s6000/include/variant/irq.h b/arch/xtensa/variants/s6000/include/variant/irq.h
new file mode 100644
index 0000000..fa031cb
--- /dev/null
+++ b/arch/xtensa/variants/s6000/include/variant/irq.h
@@ -0,0 +1,9 @@
+#ifndef __XTENSA_S6000_IRQ_H
+#define __XTENSA_S6000_IRQ_H
+
+#define NO_IRQ		(-1)
+
+extern void variant_irq_enable(unsigned int irq);
+extern void variant_irq_disable(unsigned int irq);
+
+#endif /* __XTENSA_S6000_IRQ_H */
diff --git a/arch/xtensa/variants/s6000/include/variant/tie-asm.h b/arch/xtensa/variants/s6000/include/variant/tie-asm.h
new file mode 100644
index 0000000..f02d0a3
--- /dev/null
+++ b/arch/xtensa/variants/s6000/include/variant/tie-asm.h
@@ -0,0 +1,304 @@
+/*
+ * This header file contains assembly-language definitions (assembly
+ * macros, etc.) for this specific Xtensa processor's TIE extensions
+ * and options.  It is customized to this Xtensa processor configuration.
+ *
+ * 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) 1999-2008 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_CORE_TIE_ASM_H
+#define _XTENSA_CORE_TIE_ASM_H
+
+/*  Selection parameter values for save-area save/restore macros:  */
+/*  Option vs. TIE:  */
+#define XTHAL_SAS_TIE	0x0001	/* custom extension or coprocessor */
+#define XTHAL_SAS_OPT	0x0002	/* optional (and not a coprocessor) */
+/*  Whether used automatically by compiler:  */
+#define XTHAL_SAS_NOCC	0x0004	/* not used by compiler w/o special opts/code */
+#define XTHAL_SAS_CC	0x0008	/* used by compiler without special opts/code */
+/*  ABI handling across function calls:  */
+#define XTHAL_SAS_CALR	0x0010	/* caller-saved */
+#define XTHAL_SAS_CALE	0x0020	/* callee-saved */
+#define XTHAL_SAS_GLOB	0x0040	/* global across function calls (in thread) */
+/*  Misc  */
+#define XTHAL_SAS_ALL	0xFFFF	/* include all default NCP contents */
+
+
+
+/* Macro to save all non-coprocessor (extra) custom TIE and optional state
+ * (not including zero-overhead loop registers).
+ * Save area ptr (clobbered):  ptr  (16 byte aligned)
+ * Scratch regs  (clobbered):  at1..at4  (only first XCHAL_NCP_NUM_ATMPS needed)
+ */
+	.macro xchal_ncp_store  ptr at1 at2 at3 at4  continue=0 ofs=-1 select=XTHAL_SAS_ALL
+	xchal_sa_start	\continue, \ofs
+	.ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+	xchal_sa_align	\ptr, 0, 1024-4, 4, 4
+	rsr	\at1, BR		// boolean option
+	s32i	\at1, \ptr, .Lxchal_ofs_ + 0
+	.set	.Lxchal_ofs_, .Lxchal_ofs_ + 4
+	.endif
+	.endm	// xchal_ncp_store
+
+/* Macro to save all non-coprocessor (extra) custom TIE and optional state
+ * (not including zero-overhead loop registers).
+ * Save area ptr (clobbered):  ptr  (16 byte aligned)
+ * Scratch regs  (clobbered):  at1..at4  (only first XCHAL_NCP_NUM_ATMPS needed)
+ */
+	.macro xchal_ncp_load  ptr at1 at2 at3 at4  continue=0 ofs=-1 select=XTHAL_SAS_ALL
+	xchal_sa_start	\continue, \ofs
+	.ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+	xchal_sa_align	\ptr, 0, 1024-4, 4, 4
+	l32i	\at1, \ptr, .Lxchal_ofs_ + 0
+	wsr	\at1, BR		// boolean option
+	.set	.Lxchal_ofs_, .Lxchal_ofs_ + 4
+	.endif
+	.endm	// xchal_ncp_load
+
+
+
+#define XCHAL_NCP_NUM_ATMPS	1
+
+
+
+/* Macro to save the state of TIE coprocessor FPU.
+ * Save area ptr (clobbered):  ptr  (16 byte aligned)
+ * Scratch regs  (clobbered):  at1..at4  (only first XCHAL_CP0_NUM_ATMPS needed)
+ */
+#define xchal_cp_FPU_store	xchal_cp0_store
+/* #define xchal_cp_FPU_store_a2	xchal_cp0_store a2 a3 a4 a5 a6 */
+	.macro	xchal_cp0_store  ptr at1 at2 at3 at4  continue=0 ofs=-1 select=XTHAL_SAS_ALL
+	xchal_sa_start \continue, \ofs
+	.ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+	xchal_sa_align	\ptr, 0, 0, 1, 16
+	rur232	\at1		// FCR
+	s32i	\at1, \ptr, 0
+	rur233	\at1		// FSR
+	s32i	\at1, \ptr, 4
+	SSI f0, \ptr,  8
+	SSI f1, \ptr,  12
+	SSI f2, \ptr,  16
+	SSI f3, \ptr,  20
+	SSI f4, \ptr,  24
+	SSI f5, \ptr,  28
+	SSI f6, \ptr,  32
+	SSI f7, \ptr,  36
+	SSI f8, \ptr,  40
+	SSI f9, \ptr,  44
+	SSI f10, \ptr,  48
+	SSI f11, \ptr,  52
+	SSI f12, \ptr,  56
+	SSI f13, \ptr,  60
+	SSI f14, \ptr,  64
+	SSI f15, \ptr,  68
+	.set	.Lxchal_ofs_, .Lxchal_ofs_ + 72
+	.endif
+	.endm	// xchal_cp0_store
+
+/* Macro to restore the state of TIE coprocessor FPU.
+ * Save area ptr (clobbered):  ptr  (16 byte aligned)
+ * Scratch regs  (clobbered):  at1..at4  (only first XCHAL_CP0_NUM_ATMPS needed)
+ */
+#define xchal_cp_FPU_load	xchal_cp0_load
+/* #define xchal_cp_FPU_load_a2	xchal_cp0_load a2 a3 a4 a5 a6 */
+	.macro	xchal_cp0_load  ptr at1 at2 at3 at4  continue=0 ofs=-1 select=XTHAL_SAS_ALL
+	xchal_sa_start \continue, \ofs
+	.ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+	xchal_sa_align	\ptr, 0, 0, 1, 16
+	l32i	\at1, \ptr, 0
+	wur232	\at1		// FCR
+	l32i	\at1, \ptr, 4
+	wur233	\at1		// FSR
+	LSI f0, \ptr,  8
+	LSI f1, \ptr,  12
+	LSI f2, \ptr,  16
+	LSI f3, \ptr,  20
+	LSI f4, \ptr,  24
+	LSI f5, \ptr,  28
+	LSI f6, \ptr,  32
+	LSI f7, \ptr,  36
+	LSI f8, \ptr,  40
+	LSI f9, \ptr,  44
+	LSI f10, \ptr,  48
+	LSI f11, \ptr,  52
+	LSI f12, \ptr,  56
+	LSI f13, \ptr,  60
+	LSI f14, \ptr,  64
+	LSI f15, \ptr,  68
+	.set	.Lxchal_ofs_, .Lxchal_ofs_ + 72
+	.endif
+	.endm	// xchal_cp0_load
+
+#define XCHAL_CP0_NUM_ATMPS	1
+
+/* Macro to save the state of TIE coprocessor XAD.
+ * Save area ptr (clobbered):  ptr  (16 byte aligned)
+ * Scratch regs  (clobbered):  at1..at4  (only first XCHAL_CP6_NUM_ATMPS needed)
+ */
+#define xchal_cp_XAD_store	xchal_cp6_store
+/* #define xchal_cp_XAD_store_a2	xchal_cp6_store a2 a3 a4 a5 a6 */
+	.macro	xchal_cp6_store  ptr at1 at2 at3 at4  continue=0 ofs=-1 select=XTHAL_SAS_ALL
+	xchal_sa_start \continue, \ofs
+	.ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+	xchal_sa_align	\ptr, 0, 0, 1, 16
+	rur0	\at1		// LDCBHI
+	s32i	\at1, \ptr, 0
+	rur1	\at1		// LDCBLO
+	s32i	\at1, \ptr, 4
+	rur2	\at1		// STCBHI
+	s32i	\at1, \ptr, 8
+	rur3	\at1		// STCBLO
+	s32i	\at1, \ptr, 12
+	rur8	\at1		// LDBRBASE
+	s32i	\at1, \ptr, 16
+	rur9	\at1		// LDBROFF
+	s32i	\at1, \ptr, 20
+	rur10	\at1		// LDBRINC
+	s32i	\at1, \ptr, 24
+	rur11	\at1		// STBRBASE
+	s32i	\at1, \ptr, 28
+	rur12	\at1		// STBROFF
+	s32i	\at1, \ptr, 32
+	rur13	\at1		// STBRINC
+	s32i	\at1, \ptr, 36
+	rur24	\at1		// SCRATCH0
+	s32i	\at1, \ptr, 40
+	rur25	\at1		// SCRATCH1
+	s32i	\at1, \ptr, 44
+	rur26	\at1		// SCRATCH2
+	s32i	\at1, \ptr, 48
+	rur27	\at1		// SCRATCH3
+	s32i	\at1, \ptr, 52
+	WRAS128I wra0, \ptr,  64
+	WRAS128I wra1, \ptr,  80
+	WRAS128I wra2, \ptr,  96
+	WRAS128I wra3, \ptr,  112
+	WRAS128I wra4, \ptr,  128
+	WRAS128I wra5, \ptr,  144
+	WRAS128I wra6, \ptr,  160
+	WRAS128I wra7, \ptr,  176
+	WRAS128I wra8, \ptr,  192
+	WRAS128I wra9, \ptr,  208
+	WRAS128I wra10, \ptr,  224
+	WRAS128I wra11, \ptr,  240
+	WRAS128I wra12, \ptr,  256
+	WRAS128I wra13, \ptr,  272
+	WRAS128I wra14, \ptr,  288
+	WRAS128I wra15, \ptr,  304
+	WRBS128I wrb0, \ptr,  320
+	WRBS128I wrb1, \ptr,  336
+	WRBS128I wrb2, \ptr,  352
+	WRBS128I wrb3, \ptr,  368
+	WRBS128I wrb4, \ptr,  384
+	WRBS128I wrb5, \ptr,  400
+	WRBS128I wrb6, \ptr,  416
+	WRBS128I wrb7, \ptr,  432
+	WRBS128I wrb8, \ptr,  448
+	WRBS128I wrb9, \ptr,  464
+	WRBS128I wrb10, \ptr,  480
+	WRBS128I wrb11, \ptr,  496
+	WRBS128I wrb12, \ptr,  512
+	WRBS128I wrb13, \ptr,  528
+	WRBS128I wrb14, \ptr,  544
+	WRBS128I wrb15, \ptr,  560
+	.set	.Lxchal_ofs_, .Lxchal_ofs_ + 576
+	.endif
+	.endm	// xchal_cp6_store
+
+/* Macro to restore the state of TIE coprocessor XAD.
+ * Save area ptr (clobbered):  ptr  (16 byte aligned)
+ * Scratch regs  (clobbered):  at1..at4  (only first XCHAL_CP6_NUM_ATMPS needed)
+ */
+#define xchal_cp_XAD_load	xchal_cp6_load
+/* #define xchal_cp_XAD_load_a2	xchal_cp6_load a2 a3 a4 a5 a6 */
+	.macro	xchal_cp6_load  ptr at1 at2 at3 at4  continue=0 ofs=-1 select=XTHAL_SAS_ALL
+	xchal_sa_start \continue, \ofs
+	.ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+	xchal_sa_align	\ptr, 0, 0, 1, 16
+	l32i	\at1, \ptr, 0
+	wur0	\at1		// LDCBHI
+	l32i	\at1, \ptr, 4
+	wur1	\at1		// LDCBLO
+	l32i	\at1, \ptr, 8
+	wur2	\at1		// STCBHI
+	l32i	\at1, \ptr, 12
+	wur3	\at1		// STCBLO
+	l32i	\at1, \ptr, 16
+	wur8	\at1		// LDBRBASE
+	l32i	\at1, \ptr, 20
+	wur9	\at1		// LDBROFF
+	l32i	\at1, \ptr, 24
+	wur10	\at1		// LDBRINC
+	l32i	\at1, \ptr, 28
+	wur11	\at1		// STBRBASE
+	l32i	\at1, \ptr, 32
+	wur12	\at1		// STBROFF
+	l32i	\at1, \ptr, 36
+	wur13	\at1		// STBRINC
+	l32i	\at1, \ptr, 40
+	wur24	\at1		// SCRATCH0
+	l32i	\at1, \ptr, 44
+	wur25	\at1		// SCRATCH1
+	l32i	\at1, \ptr, 48
+	wur26	\at1		// SCRATCH2
+	l32i	\at1, \ptr, 52
+	wur27	\at1		// SCRATCH3
+	WRBL128I wrb0, \ptr,  320
+	WRBL128I wrb1, \ptr,  336
+	WRBL128I wrb2, \ptr,  352
+	WRBL128I wrb3, \ptr,  368
+	WRBL128I wrb4, \ptr,  384
+	WRBL128I wrb5, \ptr,  400
+	WRBL128I wrb6, \ptr,  416
+	WRBL128I wrb7, \ptr,  432
+	WRBL128I wrb8, \ptr,  448
+	WRBL128I wrb9, \ptr,  464
+	WRBL128I wrb10, \ptr,  480
+	WRBL128I wrb11, \ptr,  496
+	WRBL128I wrb12, \ptr,  512
+	WRBL128I wrb13, \ptr,  528
+	WRBL128I wrb14, \ptr,  544
+	WRBL128I wrb15, \ptr,  560
+	WRAL128I wra0, \ptr,  64
+	WRAL128I wra1, \ptr,  80
+	WRAL128I wra2, \ptr,  96
+	WRAL128I wra3, \ptr,  112
+	WRAL128I wra4, \ptr,  128
+	WRAL128I wra5, \ptr,  144
+	WRAL128I wra6, \ptr,  160
+	WRAL128I wra7, \ptr,  176
+	WRAL128I wra8, \ptr,  192
+	WRAL128I wra9, \ptr,  208
+	WRAL128I wra10, \ptr,  224
+	WRAL128I wra11, \ptr,  240
+	WRAL128I wra12, \ptr,  256
+	WRAL128I wra13, \ptr,  272
+	WRAL128I wra14, \ptr,  288
+	WRAL128I wra15, \ptr,  304
+	.set	.Lxchal_ofs_, .Lxchal_ofs_ + 576
+	.endif
+	.endm	// xchal_cp6_load
+
+#define XCHAL_CP6_NUM_ATMPS	1
+#define XCHAL_SA_NUM_ATMPS	1
+
+	/*  Empty macros for unconfigured coprocessors:  */
+	.macro xchal_cp1_store	p a b c d continue=0 ofs=-1 select=-1 ; .endm
+	.macro xchal_cp1_load	p a b c d continue=0 ofs=-1 select=-1 ; .endm
+	.macro xchal_cp2_store	p a b c d continue=0 ofs=-1 select=-1 ; .endm
+	.macro xchal_cp2_load	p a b c d continue=0 ofs=-1 select=-1 ; .endm
+	.macro xchal_cp3_store	p a b c d continue=0 ofs=-1 select=-1 ; .endm
+	.macro xchal_cp3_load	p a b c d continue=0 ofs=-1 select=-1 ; .endm
+	.macro xchal_cp4_store	p a b c d continue=0 ofs=-1 select=-1 ; .endm
+	.macro xchal_cp4_load	p a b c d continue=0 ofs=-1 select=-1 ; .endm
+	.macro xchal_cp5_store	p a b c d continue=0 ofs=-1 select=-1 ; .endm
+	.macro xchal_cp5_load	p a b c d continue=0 ofs=-1 select=-1 ; .endm
+	.macro xchal_cp7_store	p a b c d continue=0 ofs=-1 select=-1 ; .endm
+	.macro xchal_cp7_load	p a b c d continue=0 ofs=-1 select=-1 ; .endm
+
+#endif /*_XTENSA_CORE_TIE_ASM_H*/
+
diff --git a/arch/xtensa/variants/s6000/include/variant/tie.h b/arch/xtensa/variants/s6000/include/variant/tie.h
new file mode 100644
index 0000000..be7ea84
--- /dev/null
+++ b/arch/xtensa/variants/s6000/include/variant/tie.h
@@ -0,0 +1,191 @@
+/*
+ * This header file describes this specific Xtensa processor's TIE extensions
+ * that extend basic Xtensa core functionality.  It is customized to this
+ * Xtensa processor configuration.
+ *
+ * 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) 1999-2008 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_CORE_TIE_H
+#define _XTENSA_CORE_TIE_H
+
+#define XCHAL_CP_NUM			2	/* number of coprocessors */
+#define XCHAL_CP_MAX			7	/* max CP ID + 1 (0 if none) */
+#define XCHAL_CP_MASK			0x41	/* bitmask of all CPs by ID */
+#define XCHAL_CP_PORT_MASK		0x00	/* bitmask of only port CPs */
+
+/*  Basic parameters of each coprocessor:  */
+#define XCHAL_CP0_NAME			"FPU"
+#define XCHAL_CP0_IDENT			FPU
+#define XCHAL_CP0_SA_SIZE		72	/* size of state save area */
+#define XCHAL_CP0_SA_ALIGN		4	/* min alignment of save area */
+#define XCHAL_CP_ID_FPU			0	/* coprocessor ID (0..7) */
+#define XCHAL_CP6_NAME			"XAD"
+#define XCHAL_CP6_IDENT			XAD
+#define XCHAL_CP6_SA_SIZE		576	/* size of state save area */
+#define XCHAL_CP6_SA_ALIGN		16	/* min alignment of save area */
+#define XCHAL_CP_ID_XAD			6	/* coprocessor ID (0..7) */
+
+/*  Filler info for unassigned coprocessors, to simplify arrays etc:  */
+#define XCHAL_CP1_SA_SIZE		0
+#define XCHAL_CP1_SA_ALIGN		1
+#define XCHAL_CP2_SA_SIZE		0
+#define XCHAL_CP2_SA_ALIGN		1
+#define XCHAL_CP3_SA_SIZE		0
+#define XCHAL_CP3_SA_ALIGN		1
+#define XCHAL_CP4_SA_SIZE		0
+#define XCHAL_CP4_SA_ALIGN		1
+#define XCHAL_CP5_SA_SIZE		0
+#define XCHAL_CP5_SA_ALIGN		1
+#define XCHAL_CP7_SA_SIZE		0
+#define XCHAL_CP7_SA_ALIGN		1
+
+/*  Save area for non-coprocessor optional and custom (TIE) state:  */
+#define XCHAL_NCP_SA_SIZE		4
+#define XCHAL_NCP_SA_ALIGN		4
+
+/*  Total save area for optional and custom state (NCP + CPn):  */
+#define XCHAL_TOTAL_SA_SIZE		672	/* with 16-byte align padding */
+#define XCHAL_TOTAL_SA_ALIGN		16	/* actual minimum alignment */
+
+/*
+ * Detailed contents of save areas.
+ * NOTE:  caller must define the XCHAL_SA_REG macro (not defined here)
+ * before expanding the XCHAL_xxx_SA_LIST() macros.
+ *
+ * XCHAL_SA_REG(s,ccused,abikind,kind,opt,name,galign,align,asize,
+ *		dbnum,base,regnum,bitsz,gapsz,reset,x...)
+ *
+ *	s = passed from XCHAL_*_LIST(s), eg. to select how to expand
+ *	ccused = set if used by compiler without special options or code
+ *	abikind = 0 (caller-saved), 1 (callee-saved), or 2 (thread-global)
+ *	kind = 0 (special reg), 1 (TIE user reg), or 2 (TIE regfile reg)
+ *	opt = 0 (custom TIE extension or coprocessor), or 1 (optional reg)
+ *	name = lowercase reg name (no quotes)
+ *	galign = group byte alignment (power of 2) (galign >= align)
+ *	align = register byte alignment (power of 2)
+ *	asize = allocated size in bytes (asize*8 == bitsz + gapsz + padsz)
+ *	  (not including any pad bytes required to galign this or next reg)
+ *	dbnum = unique target number f/debug (see <xtensa-libdb-macros.h>)
+ *	base = reg shortname w/o index (or sr=special, ur=TIE user reg)
+ *	regnum = reg index in regfile, or special/TIE-user reg number
+ *	bitsz = number of significant bits (regfile width, or ur/sr mask bits)
+ *	gapsz = intervening bits, if bitsz bits not stored contiguously
+ *	(padsz = pad bits at end [TIE regfile] or at msbits [ur,sr] of asize)
+ *	reset = register reset value (or 0 if undefined at reset)
+ *	x = reserved for future use (0 until then)
+ *
+ *  To filter out certain registers, e.g. to expand only the non-global
+ *  registers used by the compiler, you can do something like this:
+ *
+ *  #define XCHAL_SA_REG(s,ccused,p...)	SELCC##ccused(p)
+ *  #define SELCC0(p...)
+ *  #define SELCC1(abikind,p...)	SELAK##abikind(p)
+ *  #define SELAK0(p...)		REG(p)
+ *  #define SELAK1(p...)		REG(p)
+ *  #define SELAK2(p...)
+ *  #define REG(kind,tie,name,galn,aln,asz,csz,dbnum,base,rnum,bsz,rst,x...) \
+ *		...what you want to expand...
+ */
+
+#define XCHAL_NCP_SA_NUM	1
+#define XCHAL_NCP_SA_LIST(s)	\
+ XCHAL_SA_REG(s,0,0,0,1,             br, 4, 4, 4,0x0204,  sr,4  , 16,0,0,0)
+
+#define XCHAL_CP0_SA_NUM	18
+#define XCHAL_CP0_SA_LIST(s)	\
+ XCHAL_SA_REG(s,0,0,1,0,            fcr, 4, 4, 4,0x03E8,  ur,232, 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,            fsr, 4, 4, 4,0x03E9,  ur,233, 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,             f0, 4, 4, 4,0x0030,   f,0  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,             f1, 4, 4, 4,0x0031,   f,1  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,             f2, 4, 4, 4,0x0032,   f,2  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,             f3, 4, 4, 4,0x0033,   f,3  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,             f4, 4, 4, 4,0x0034,   f,4  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,             f5, 4, 4, 4,0x0035,   f,5  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,             f6, 4, 4, 4,0x0036,   f,6  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,             f7, 4, 4, 4,0x0037,   f,7  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,             f8, 4, 4, 4,0x0038,   f,8  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,             f9, 4, 4, 4,0x0039,   f,9  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,            f10, 4, 4, 4,0x003A,   f,10 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,            f11, 4, 4, 4,0x003B,   f,11 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,            f12, 4, 4, 4,0x003C,   f,12 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,            f13, 4, 4, 4,0x003D,   f,13 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,            f14, 4, 4, 4,0x003E,   f,14 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,            f15, 4, 4, 4,0x003F,   f,15 , 32,0,0,0)
+
+#define XCHAL_CP1_SA_NUM	0
+#define XCHAL_CP1_SA_LIST(s)	/* empty */
+
+#define XCHAL_CP2_SA_NUM	0
+#define XCHAL_CP2_SA_LIST(s)	/* empty */
+
+#define XCHAL_CP3_SA_NUM	0
+#define XCHAL_CP3_SA_LIST(s)	/* empty */
+
+#define XCHAL_CP4_SA_NUM	0
+#define XCHAL_CP4_SA_LIST(s)	/* empty */
+
+#define XCHAL_CP5_SA_NUM	0
+#define XCHAL_CP5_SA_LIST(s)	/* empty */
+
+#define XCHAL_CP6_SA_NUM	46
+#define XCHAL_CP6_SA_LIST(s)	\
+ XCHAL_SA_REG(s,0,0,1,0,         ldcbhi,16, 4, 4,0x0300,  ur,0  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,         ldcblo, 4, 4, 4,0x0301,  ur,1  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,         stcbhi, 4, 4, 4,0x0302,  ur,2  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,         stcblo, 4, 4, 4,0x0303,  ur,3  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,       ldbrbase, 4, 4, 4,0x0308,  ur,8  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,        ldbroff, 4, 4, 4,0x0309,  ur,9  , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,        ldbrinc, 4, 4, 4,0x030A,  ur,10 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,       stbrbase, 4, 4, 4,0x030B,  ur,11 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,        stbroff, 4, 4, 4,0x030C,  ur,12 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,        stbrinc, 4, 4, 4,0x030D,  ur,13 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,       scratch0, 4, 4, 4,0x0318,  ur,24 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,       scratch1, 4, 4, 4,0x0319,  ur,25 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,       scratch2, 4, 4, 4,0x031A,  ur,26 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0,       scratch3, 4, 4, 4,0x031B,  ur,27 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wra0,16,16,16,0x1010, wra,0  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wra1,16,16,16,0x1011, wra,1  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wra2,16,16,16,0x1012, wra,2  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wra3,16,16,16,0x1013, wra,3  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wra4,16,16,16,0x1014, wra,4  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wra5,16,16,16,0x1015, wra,5  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wra6,16,16,16,0x1016, wra,6  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wra7,16,16,16,0x1017, wra,7  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wra8,16,16,16,0x1018, wra,8  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wra9,16,16,16,0x1019, wra,9  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,          wra10,16,16,16,0x101A, wra,10 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,          wra11,16,16,16,0x101B, wra,11 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,          wra12,16,16,16,0x101C, wra,12 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,          wra13,16,16,16,0x101D, wra,13 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,          wra14,16,16,16,0x101E, wra,14 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,          wra15,16,16,16,0x101F, wra,15 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wrb0,16,16,16,0x1020, wrb,0  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wrb1,16,16,16,0x1021, wrb,1  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wrb2,16,16,16,0x1022, wrb,2  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wrb3,16,16,16,0x1023, wrb,3  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wrb4,16,16,16,0x1024, wrb,4  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wrb5,16,16,16,0x1025, wrb,5  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wrb6,16,16,16,0x1026, wrb,6  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wrb7,16,16,16,0x1027, wrb,7  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wrb8,16,16,16,0x1028, wrb,8  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,           wrb9,16,16,16,0x1029, wrb,9  ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,          wrb10,16,16,16,0x102A, wrb,10 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,          wrb11,16,16,16,0x102B, wrb,11 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,          wrb12,16,16,16,0x102C, wrb,12 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,          wrb13,16,16,16,0x102D, wrb,13 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,          wrb14,16,16,16,0x102E, wrb,14 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0,          wrb15,16,16,16,0x102F, wrb,15 ,128,0,0,0)
+
+#define XCHAL_CP7_SA_NUM	0
+#define XCHAL_CP7_SA_LIST(s)	/* empty */
+
+/* Byte length of instruction from its first nibble (op0 field), per FLIX.  */
+#define XCHAL_OP0_FORMAT_LENGTHS	3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8
+
+#endif /*_XTENSA_CORE_TIE_H*/
+
diff --git a/arch/xtensa/variants/s6000/irq.c b/arch/xtensa/variants/s6000/irq.c
new file mode 100644
index 0000000..6651e32
--- /dev/null
+++ b/arch/xtensa/variants/s6000/irq.c
@@ -0,0 +1,74 @@
+/*
+ * s6000 irq crossbar
+ *
+ * Copyright (c) 2009 emlix GmbH
+ * Authors:	Johannes Weiner <jw@emlix.com>
+ *		Oskar Schirmer <os@emlix.com>
+ */
+#include <linux/io.h>
+#include <asm/irq.h>
+#include <variant/hardware.h>
+
+/* S6_REG_INTC */
+#define INTC_STATUS	0x000
+#define INTC_RAW	0x010
+#define INTC_STATUS_AG	0x100
+#define INTC_CFG(n)	(0x200 + 4 * (n))
+
+/*
+ * The s6000 has a crossbar that multiplexes interrupt output lines
+ * from the peripherals to input lines on the xtensa core.
+ *
+ * We leave the mapping decisions to the platform as it depends on the
+ * actually connected peripherals which distribution makes sense.
+ */
+extern const signed char *platform_irq_mappings[NR_IRQS];
+
+static unsigned long scp_to_intc_enable[] = {
+#define	TO_INTC_ENABLE(n)	(((n) << 1) + 1)
+	TO_INTC_ENABLE(0),
+	TO_INTC_ENABLE(1),
+	TO_INTC_ENABLE(2),
+	TO_INTC_ENABLE(3),
+	TO_INTC_ENABLE(4),
+	TO_INTC_ENABLE(5),
+	TO_INTC_ENABLE(6),
+	TO_INTC_ENABLE(7),
+	TO_INTC_ENABLE(8),
+	TO_INTC_ENABLE(9),
+	TO_INTC_ENABLE(10),
+	TO_INTC_ENABLE(11),
+	TO_INTC_ENABLE(12),
+	-1,
+	-1,
+	TO_INTC_ENABLE(13),
+	-1,
+	TO_INTC_ENABLE(14),
+	-1,
+	TO_INTC_ENABLE(15),
+#undef	TO_INTC_ENABLE
+};
+
+static void irq_set(unsigned int irq, int enable)
+{
+	unsigned long en;
+	const signed char *m = platform_irq_mappings[irq];
+
+	if (!m)
+		return;
+	en = enable ? scp_to_intc_enable[irq] : 0;
+	while (*m >= 0) {
+		writel(en, S6_REG_INTC + INTC_CFG(*m));
+		m++;
+	}
+}
+
+void variant_irq_enable(unsigned int irq)
+{
+	irq_set(irq, 1);
+}
+
+void variant_irq_disable(unsigned int irq)
+{
+	irq_set(irq, 0);
+}
diff --git a/block/Kconfig b/block/Kconfig
index 0cbb3b8..e7d1278 100644
--- a/block/Kconfig
+++ b/block/Kconfig
@@ -44,22 +44,6 @@
 
 	  If unsure, say N.
 
-config BLK_DEV_IO_TRACE
-	bool "Support for tracing block io actions"
-	depends on SYSFS
-	select RELAY
-	select DEBUG_FS
-	select TRACEPOINTS
-	help
-	  Say Y here if you want to be able to trace the block layer actions
-	  on a given queue. Tracing allows you to see any traffic happening
-	  on a block device queue. For more information (and the userspace
-	  support tools needed), fetch the blktrace tools from:
-
-	  git://git.kernel.dk/blktrace.git
-
-	  If unsure, say N.
-
 config BLK_DEV_BSG
 	bool "Block layer SG support v4 (EXPERIMENTAL)"
 	depends on EXPERIMENTAL
diff --git a/block/Makefile b/block/Makefile
index bfe7304..e9fa4dd 100644
--- a/block/Makefile
+++ b/block/Makefile
@@ -13,6 +13,5 @@
 obj-$(CONFIG_IOSCHED_DEADLINE)	+= deadline-iosched.o
 obj-$(CONFIG_IOSCHED_CFQ)	+= cfq-iosched.o
 
-obj-$(CONFIG_BLK_DEV_IO_TRACE)	+= blktrace.o
 obj-$(CONFIG_BLOCK_COMPAT)	+= compat_ioctl.o
 obj-$(CONFIG_BLK_DEV_INTEGRITY)	+= blk-integrity.o
diff --git a/block/blk-core.c b/block/blk-core.c
index 996ed90..2557280 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -484,11 +484,11 @@
 {
 	struct request_list *rl = &q->rq;
 
-	rl->count[READ] = rl->count[WRITE] = 0;
-	rl->starved[READ] = rl->starved[WRITE] = 0;
+	rl->count[BLK_RW_SYNC] = rl->count[BLK_RW_ASYNC] = 0;
+	rl->starved[BLK_RW_SYNC] = rl->starved[BLK_RW_ASYNC] = 0;
 	rl->elvpriv = 0;
-	init_waitqueue_head(&rl->wait[READ]);
-	init_waitqueue_head(&rl->wait[WRITE]);
+	init_waitqueue_head(&rl->wait[BLK_RW_SYNC]);
+	init_waitqueue_head(&rl->wait[BLK_RW_ASYNC]);
 
 	rl->rq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
 				mempool_free_slab, request_cachep, q->node);
@@ -699,18 +699,18 @@
 	ioc->last_waited = jiffies;
 }
 
-static void __freed_request(struct request_queue *q, int rw)
+static void __freed_request(struct request_queue *q, int sync)
 {
 	struct request_list *rl = &q->rq;
 
-	if (rl->count[rw] < queue_congestion_off_threshold(q))
-		blk_clear_queue_congested(q, rw);
+	if (rl->count[sync] < queue_congestion_off_threshold(q))
+		blk_clear_queue_congested(q, sync);
 
-	if (rl->count[rw] + 1 <= q->nr_requests) {
-		if (waitqueue_active(&rl->wait[rw]))
-			wake_up(&rl->wait[rw]);
+	if (rl->count[sync] + 1 <= q->nr_requests) {
+		if (waitqueue_active(&rl->wait[sync]))
+			wake_up(&rl->wait[sync]);
 
-		blk_clear_queue_full(q, rw);
+		blk_clear_queue_full(q, sync);
 	}
 }
 
@@ -718,18 +718,18 @@
  * A request has just been released.  Account for it, update the full and
  * congestion status, wake up any waiters.   Called under q->queue_lock.
  */
-static void freed_request(struct request_queue *q, int rw, int priv)
+static void freed_request(struct request_queue *q, int sync, int priv)
 {
 	struct request_list *rl = &q->rq;
 
-	rl->count[rw]--;
+	rl->count[sync]--;
 	if (priv)
 		rl->elvpriv--;
 
-	__freed_request(q, rw);
+	__freed_request(q, sync);
 
-	if (unlikely(rl->starved[rw ^ 1]))
-		__freed_request(q, rw ^ 1);
+	if (unlikely(rl->starved[sync ^ 1]))
+		__freed_request(q, sync ^ 1);
 }
 
 /*
@@ -743,15 +743,15 @@
 	struct request *rq = NULL;
 	struct request_list *rl = &q->rq;
 	struct io_context *ioc = NULL;
-	const int rw = rw_flags & 0x01;
+	const bool is_sync = rw_is_sync(rw_flags) != 0;
 	int may_queue, priv;
 
 	may_queue = elv_may_queue(q, rw_flags);
 	if (may_queue == ELV_MQUEUE_NO)
 		goto rq_starved;
 
-	if (rl->count[rw]+1 >= queue_congestion_on_threshold(q)) {
-		if (rl->count[rw]+1 >= q->nr_requests) {
+	if (rl->count[is_sync]+1 >= queue_congestion_on_threshold(q)) {
+		if (rl->count[is_sync]+1 >= q->nr_requests) {
 			ioc = current_io_context(GFP_ATOMIC, q->node);
 			/*
 			 * The queue will fill after this allocation, so set
@@ -759,9 +759,9 @@
 			 * This process will be allowed to complete a batch of
 			 * requests, others will be blocked.
 			 */
-			if (!blk_queue_full(q, rw)) {
+			if (!blk_queue_full(q, is_sync)) {
 				ioc_set_batching(q, ioc);
-				blk_set_queue_full(q, rw);
+				blk_set_queue_full(q, is_sync);
 			} else {
 				if (may_queue != ELV_MQUEUE_MUST
 						&& !ioc_batching(q, ioc)) {
@@ -774,7 +774,7 @@
 				}
 			}
 		}
-		blk_set_queue_congested(q, rw);
+		blk_set_queue_congested(q, is_sync);
 	}
 
 	/*
@@ -782,11 +782,11 @@
 	 * limit of requests, otherwise we could have thousands of requests
 	 * allocated with any setting of ->nr_requests
 	 */
-	if (rl->count[rw] >= (3 * q->nr_requests / 2))
+	if (rl->count[is_sync] >= (3 * q->nr_requests / 2))
 		goto out;
 
-	rl->count[rw]++;
-	rl->starved[rw] = 0;
+	rl->count[is_sync]++;
+	rl->starved[is_sync] = 0;
 
 	priv = !test_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
 	if (priv)
@@ -804,7 +804,7 @@
 		 * wait queue, but this is pretty rare.
 		 */
 		spin_lock_irq(q->queue_lock);
-		freed_request(q, rw, priv);
+		freed_request(q, is_sync, priv);
 
 		/*
 		 * in the very unlikely event that allocation failed and no
@@ -814,8 +814,8 @@
 		 * rq mempool into READ and WRITE
 		 */
 rq_starved:
-		if (unlikely(rl->count[rw] == 0))
-			rl->starved[rw] = 1;
+		if (unlikely(rl->count[is_sync] == 0))
+			rl->starved[is_sync] = 1;
 
 		goto out;
 	}
@@ -829,7 +829,7 @@
 	if (ioc_batching(q, ioc))
 		ioc->nr_batch_requests--;
 
-	trace_block_getrq(q, bio, rw);
+	trace_block_getrq(q, bio, rw_flags & 1);
 out:
 	return rq;
 }
@@ -843,7 +843,7 @@
 static struct request *get_request_wait(struct request_queue *q, int rw_flags,
 					struct bio *bio)
 {
-	const int rw = rw_flags & 0x01;
+	const bool is_sync = rw_is_sync(rw_flags) != 0;
 	struct request *rq;
 
 	rq = get_request(q, rw_flags, bio, GFP_NOIO);
@@ -852,10 +852,10 @@
 		struct io_context *ioc;
 		struct request_list *rl = &q->rq;
 
-		prepare_to_wait_exclusive(&rl->wait[rw], &wait,
+		prepare_to_wait_exclusive(&rl->wait[is_sync], &wait,
 				TASK_UNINTERRUPTIBLE);
 
-		trace_block_sleeprq(q, bio, rw);
+		trace_block_sleeprq(q, bio, rw_flags & 1);
 
 		__generic_unplug_device(q);
 		spin_unlock_irq(q->queue_lock);
@@ -871,7 +871,7 @@
 		ioc_set_batching(q, ioc);
 
 		spin_lock_irq(q->queue_lock);
-		finish_wait(&rl->wait[rw], &wait);
+		finish_wait(&rl->wait[is_sync], &wait);
 
 		rq = get_request(q, rw_flags, bio, GFP_NOIO);
 	};
@@ -1070,14 +1070,14 @@
 	 * it didn't come out of our reserved rq pools
 	 */
 	if (req->cmd_flags & REQ_ALLOCED) {
-		int rw = rq_data_dir(req);
+		int is_sync = rq_is_sync(req) != 0;
 		int priv = req->cmd_flags & REQ_ELVPRIV;
 
 		BUG_ON(!list_empty(&req->queuelist));
 		BUG_ON(!hlist_unhashed(&req->hash));
 
 		blk_free_request(q, req);
-		freed_request(q, rw, priv);
+		freed_request(q, is_sync, priv);
 	}
 }
 EXPORT_SYMBOL_GPL(__blk_put_request);
@@ -1128,6 +1128,8 @@
 		req->cmd_flags |= REQ_UNPLUG;
 	if (bio_rw_meta(bio))
 		req->cmd_flags |= REQ_RW_META;
+	if (bio_noidle(bio))
+		req->cmd_flags |= REQ_NOIDLE;
 
 	req->errors = 0;
 	req->hard_sector = req->sector = bio->bi_sector;
@@ -1136,6 +1138,15 @@
 	blk_rq_bio_prep(req->q, req, bio);
 }
 
+/*
+ * Only disabling plugging for non-rotational devices if it does tagging
+ * as well, otherwise we do need the proper merging
+ */
+static inline bool queue_should_plug(struct request_queue *q)
+{
+	return !(blk_queue_nonrot(q) && blk_queue_tagged(q));
+}
+
 static int __make_request(struct request_queue *q, struct bio *bio)
 {
 	struct request *req;
@@ -1242,11 +1253,11 @@
 	if (test_bit(QUEUE_FLAG_SAME_COMP, &q->queue_flags) ||
 	    bio_flagged(bio, BIO_CPU_AFFINE))
 		req->cpu = blk_cpu_to_group(smp_processor_id());
-	if (!blk_queue_nonrot(q) && elv_queue_empty(q))
+	if (queue_should_plug(q) && elv_queue_empty(q))
 		blk_plug_device(q);
 	add_request(q, req);
 out:
-	if (unplug || blk_queue_nonrot(q))
+	if (unplug || !queue_should_plug(q))
 		__generic_unplug_device(q);
 	spin_unlock_irq(q->queue_lock);
 	return 0;
diff --git a/block/blk-softirq.c b/block/blk-softirq.c
index ce0efc6..ee9c216 100644
--- a/block/blk-softirq.c
+++ b/block/blk-softirq.c
@@ -64,7 +64,7 @@
 		data->info = rq;
 		data->flags = 0;
 
-		__smp_call_function_single(cpu, data);
+		__smp_call_function_single(cpu, data, 0);
 		return 0;
 	}
 
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index e29ddfc..3ff9bba 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -48,28 +48,28 @@
 	q->nr_requests = nr;
 	blk_queue_congestion_threshold(q);
 
-	if (rl->count[READ] >= queue_congestion_on_threshold(q))
-		blk_set_queue_congested(q, READ);
-	else if (rl->count[READ] < queue_congestion_off_threshold(q))
-		blk_clear_queue_congested(q, READ);
+	if (rl->count[BLK_RW_SYNC] >= queue_congestion_on_threshold(q))
+		blk_set_queue_congested(q, BLK_RW_SYNC);
+	else if (rl->count[BLK_RW_SYNC] < queue_congestion_off_threshold(q))
+		blk_clear_queue_congested(q, BLK_RW_SYNC);
 
-	if (rl->count[WRITE] >= queue_congestion_on_threshold(q))
-		blk_set_queue_congested(q, WRITE);
-	else if (rl->count[WRITE] < queue_congestion_off_threshold(q))
-		blk_clear_queue_congested(q, WRITE);
+	if (rl->count[BLK_RW_ASYNC] >= queue_congestion_on_threshold(q))
+		blk_set_queue_congested(q, BLK_RW_ASYNC);
+	else if (rl->count[BLK_RW_ASYNC] < queue_congestion_off_threshold(q))
+		blk_clear_queue_congested(q, BLK_RW_ASYNC);
 
-	if (rl->count[READ] >= q->nr_requests) {
-		blk_set_queue_full(q, READ);
-	} else if (rl->count[READ]+1 <= q->nr_requests) {
-		blk_clear_queue_full(q, READ);
-		wake_up(&rl->wait[READ]);
+	if (rl->count[BLK_RW_SYNC] >= q->nr_requests) {
+		blk_set_queue_full(q, BLK_RW_SYNC);
+	} else if (rl->count[BLK_RW_SYNC]+1 <= q->nr_requests) {
+		blk_clear_queue_full(q, BLK_RW_SYNC);
+		wake_up(&rl->wait[BLK_RW_SYNC]);
 	}
 
-	if (rl->count[WRITE] >= q->nr_requests) {
-		blk_set_queue_full(q, WRITE);
-	} else if (rl->count[WRITE]+1 <= q->nr_requests) {
-		blk_clear_queue_full(q, WRITE);
-		wake_up(&rl->wait[WRITE]);
+	if (rl->count[BLK_RW_ASYNC] >= q->nr_requests) {
+		blk_set_queue_full(q, BLK_RW_ASYNC);
+	} else if (rl->count[BLK_RW_ASYNC]+1 <= q->nr_requests) {
+		blk_clear_queue_full(q, BLK_RW_ASYNC);
+		wake_up(&rl->wait[BLK_RW_ASYNC]);
 	}
 	spin_unlock_irq(q->queue_lock);
 	return ret;
diff --git a/block/blk.h b/block/blk.h
index 0dce92c..3ee9435 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -102,7 +102,7 @@
 	const struct cpumask *mask = cpu_coregroup_mask(cpu);
 	return cpumask_first(mask);
 #elif defined(CONFIG_SCHED_SMT)
-	return first_cpu(per_cpu(cpu_sibling_map, cpu));
+	return cpumask_first(topology_thread_cpumask(cpu));
 #else
 	return cpu;
 #endif
diff --git a/block/blktrace.c b/block/blktrace.c
deleted file mode 100644
index 028120a..0000000
--- a/block/blktrace.c
+++ /dev/null
@@ -1,860 +0,0 @@
-/*
- * Copyright (C) 2006 Jens Axboe <axboe@kernel.dk>
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-#include <linux/kernel.h>
-#include <linux/blkdev.h>
-#include <linux/blktrace_api.h>
-#include <linux/percpu.h>
-#include <linux/init.h>
-#include <linux/mutex.h>
-#include <linux/debugfs.h>
-#include <linux/time.h>
-#include <trace/block.h>
-#include <asm/uaccess.h>
-
-static unsigned int blktrace_seq __read_mostly = 1;
-
-/* Global reference count of probes */
-static DEFINE_MUTEX(blk_probe_mutex);
-static atomic_t blk_probes_ref = ATOMIC_INIT(0);
-
-static int blk_register_tracepoints(void);
-static void blk_unregister_tracepoints(void);
-
-/*
- * Send out a notify message.
- */
-static void trace_note(struct blk_trace *bt, pid_t pid, int action,
-		       const void *data, size_t len)
-{
-	struct blk_io_trace *t;
-
-	t = relay_reserve(bt->rchan, sizeof(*t) + len);
-	if (t) {
-		const int cpu = smp_processor_id();
-
-		t->magic = BLK_IO_TRACE_MAGIC | BLK_IO_TRACE_VERSION;
-		t->time = ktime_to_ns(ktime_get());
-		t->device = bt->dev;
-		t->action = action;
-		t->pid = pid;
-		t->cpu = cpu;
-		t->pdu_len = len;
-		memcpy((void *) t + sizeof(*t), data, len);
-	}
-}
-
-/*
- * Send out a notify for this process, if we haven't done so since a trace
- * started
- */
-static void trace_note_tsk(struct blk_trace *bt, struct task_struct *tsk)
-{
-	tsk->btrace_seq = blktrace_seq;
-	trace_note(bt, tsk->pid, BLK_TN_PROCESS, tsk->comm, sizeof(tsk->comm));
-}
-
-static void trace_note_time(struct blk_trace *bt)
-{
-	struct timespec now;
-	unsigned long flags;
-	u32 words[2];
-
-	getnstimeofday(&now);
-	words[0] = now.tv_sec;
-	words[1] = now.tv_nsec;
-
-	local_irq_save(flags);
-	trace_note(bt, 0, BLK_TN_TIMESTAMP, words, sizeof(words));
-	local_irq_restore(flags);
-}
-
-void __trace_note_message(struct blk_trace *bt, const char *fmt, ...)
-{
-	int n;
-	va_list args;
-	unsigned long flags;
-	char *buf;
-
-	local_irq_save(flags);
-	buf = per_cpu_ptr(bt->msg_data, smp_processor_id());
-	va_start(args, fmt);
-	n = vscnprintf(buf, BLK_TN_MAX_MSG, fmt, args);
-	va_end(args);
-
-	trace_note(bt, 0, BLK_TN_MESSAGE, buf, n);
-	local_irq_restore(flags);
-}
-EXPORT_SYMBOL_GPL(__trace_note_message);
-
-static int act_log_check(struct blk_trace *bt, u32 what, sector_t sector,
-			 pid_t pid)
-{
-	if (((bt->act_mask << BLK_TC_SHIFT) & what) == 0)
-		return 1;
-	if (sector < bt->start_lba || sector > bt->end_lba)
-		return 1;
-	if (bt->pid && pid != bt->pid)
-		return 1;
-
-	return 0;
-}
-
-/*
- * Data direction bit lookup
- */
-static u32 ddir_act[2] __read_mostly = { BLK_TC_ACT(BLK_TC_READ), BLK_TC_ACT(BLK_TC_WRITE) };
-
-/* The ilog2() calls fall out because they're constant */
-#define MASK_TC_BIT(rw, __name) ( (rw & (1 << BIO_RW_ ## __name)) << \
-	  (ilog2(BLK_TC_ ## __name) + BLK_TC_SHIFT - BIO_RW_ ## __name) )
-
-/*
- * The worker for the various blk_add_trace*() types. Fills out a
- * blk_io_trace structure and places it in a per-cpu subbuffer.
- */
-static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
-		     int rw, u32 what, int error, int pdu_len, void *pdu_data)
-{
-	struct task_struct *tsk = current;
-	struct blk_io_trace *t;
-	unsigned long flags;
-	unsigned long *sequence;
-	pid_t pid;
-	int cpu;
-
-	if (unlikely(bt->trace_state != Blktrace_running))
-		return;
-
-	what |= ddir_act[rw & WRITE];
-	what |= MASK_TC_BIT(rw, BARRIER);
-	what |= MASK_TC_BIT(rw, SYNCIO);
-	what |= MASK_TC_BIT(rw, AHEAD);
-	what |= MASK_TC_BIT(rw, META);
-	what |= MASK_TC_BIT(rw, DISCARD);
-
-	pid = tsk->pid;
-	if (unlikely(act_log_check(bt, what, sector, pid)))
-		return;
-
-	/*
-	 * A word about the locking here - we disable interrupts to reserve
-	 * some space in the relay per-cpu buffer, to prevent an irq
-	 * from coming in and stepping on our toes.
-	 */
-	local_irq_save(flags);
-
-	if (unlikely(tsk->btrace_seq != blktrace_seq))
-		trace_note_tsk(bt, tsk);
-
-	t = relay_reserve(bt->rchan, sizeof(*t) + pdu_len);
-	if (t) {
-		cpu = smp_processor_id();
-		sequence = per_cpu_ptr(bt->sequence, cpu);
-
-		t->magic = BLK_IO_TRACE_MAGIC | BLK_IO_TRACE_VERSION;
-		t->sequence = ++(*sequence);
-		t->time = ktime_to_ns(ktime_get());
-		t->sector = sector;
-		t->bytes = bytes;
-		t->action = what;
-		t->pid = pid;
-		t->device = bt->dev;
-		t->cpu = cpu;
-		t->error = error;
-		t->pdu_len = pdu_len;
-
-		if (pdu_len)
-			memcpy((void *) t + sizeof(*t), pdu_data, pdu_len);
-	}
-
-	local_irq_restore(flags);
-}
-
-static struct dentry *blk_tree_root;
-static DEFINE_MUTEX(blk_tree_mutex);
-
-static void blk_trace_cleanup(struct blk_trace *bt)
-{
-	debugfs_remove(bt->msg_file);
-	debugfs_remove(bt->dropped_file);
-	relay_close(bt->rchan);
-	free_percpu(bt->sequence);
-	free_percpu(bt->msg_data);
-	kfree(bt);
-	mutex_lock(&blk_probe_mutex);
-	if (atomic_dec_and_test(&blk_probes_ref))
-		blk_unregister_tracepoints();
-	mutex_unlock(&blk_probe_mutex);
-}
-
-int blk_trace_remove(struct request_queue *q)
-{
-	struct blk_trace *bt;
-
-	bt = xchg(&q->blk_trace, NULL);
-	if (!bt)
-		return -EINVAL;
-
-	if (bt->trace_state == Blktrace_setup ||
-	    bt->trace_state == Blktrace_stopped)
-		blk_trace_cleanup(bt);
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(blk_trace_remove);
-
-static int blk_dropped_open(struct inode *inode, struct file *filp)
-{
-	filp->private_data = inode->i_private;
-
-	return 0;
-}
-
-static ssize_t blk_dropped_read(struct file *filp, char __user *buffer,
-				size_t count, loff_t *ppos)
-{
-	struct blk_trace *bt = filp->private_data;
-	char buf[16];
-
-	snprintf(buf, sizeof(buf), "%u\n", atomic_read(&bt->dropped));
-
-	return simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf));
-}
-
-static const struct file_operations blk_dropped_fops = {
-	.owner =	THIS_MODULE,
-	.open =		blk_dropped_open,
-	.read =		blk_dropped_read,
-};
-
-static int blk_msg_open(struct inode *inode, struct file *filp)
-{
-	filp->private_data = inode->i_private;
-
-	return 0;
-}
-
-static ssize_t blk_msg_write(struct file *filp, const char __user *buffer,
-				size_t count, loff_t *ppos)
-{
-	char *msg;
-	struct blk_trace *bt;
-
-	if (count > BLK_TN_MAX_MSG)
-		return -EINVAL;
-
-	msg = kmalloc(count, GFP_KERNEL);
-	if (msg == NULL)
-		return -ENOMEM;
-
-	if (copy_from_user(msg, buffer, count)) {
-		kfree(msg);
-		return -EFAULT;
-	}
-
-	bt = filp->private_data;
-	__trace_note_message(bt, "%s", msg);
-	kfree(msg);
-
-	return count;
-}
-
-static const struct file_operations blk_msg_fops = {
-	.owner =	THIS_MODULE,
-	.open =		blk_msg_open,
-	.write =	blk_msg_write,
-};
-
-/*
- * Keep track of how many times we encountered a full subbuffer, to aid
- * the user space app in telling how many lost events there were.
- */
-static int blk_subbuf_start_callback(struct rchan_buf *buf, void *subbuf,
-				     void *prev_subbuf, size_t prev_padding)
-{
-	struct blk_trace *bt;
-
-	if (!relay_buf_full(buf))
-		return 1;
-
-	bt = buf->chan->private_data;
-	atomic_inc(&bt->dropped);
-	return 0;
-}
-
-static int blk_remove_buf_file_callback(struct dentry *dentry)
-{
-	struct dentry *parent = dentry->d_parent;
-	debugfs_remove(dentry);
-
-	/*
-	* this will fail for all but the last file, but that is ok. what we
-	* care about is the top level buts->name directory going away, when
-	* the last trace file is gone. Then we don't have to rmdir() that
-	* manually on trace stop, so it nicely solves the issue with
-	* force killing of running traces.
-	*/
-
-	debugfs_remove(parent);
-	return 0;
-}
-
-static struct dentry *blk_create_buf_file_callback(const char *filename,
-						   struct dentry *parent,
-						   int mode,
-						   struct rchan_buf *buf,
-						   int *is_global)
-{
-	return debugfs_create_file(filename, mode, parent, buf,
-					&relay_file_operations);
-}
-
-static struct rchan_callbacks blk_relay_callbacks = {
-	.subbuf_start		= blk_subbuf_start_callback,
-	.create_buf_file	= blk_create_buf_file_callback,
-	.remove_buf_file	= blk_remove_buf_file_callback,
-};
-
-/*
- * Setup everything required to start tracing
- */
-int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
-			struct blk_user_trace_setup *buts)
-{
-	struct blk_trace *old_bt, *bt = NULL;
-	struct dentry *dir = NULL;
-	int ret, i;
-
-	if (!buts->buf_size || !buts->buf_nr)
-		return -EINVAL;
-
-	strncpy(buts->name, name, BLKTRACE_BDEV_SIZE);
-	buts->name[BLKTRACE_BDEV_SIZE - 1] = '\0';
-
-	/*
-	 * some device names have larger paths - convert the slashes
-	 * to underscores for this to work as expected
-	 */
-	for (i = 0; i < strlen(buts->name); i++)
-		if (buts->name[i] == '/')
-			buts->name[i] = '_';
-
-	ret = -ENOMEM;
-	bt = kzalloc(sizeof(*bt), GFP_KERNEL);
-	if (!bt)
-		goto err;
-
-	bt->sequence = alloc_percpu(unsigned long);
-	if (!bt->sequence)
-		goto err;
-
-	bt->msg_data = __alloc_percpu(BLK_TN_MAX_MSG, __alignof__(char));
-	if (!bt->msg_data)
-		goto err;
-
-	ret = -ENOENT;
-
-	if (!blk_tree_root) {
-		blk_tree_root = debugfs_create_dir("block", NULL);
-		if (!blk_tree_root)
-			return -ENOMEM;
-	}
-
-	dir = debugfs_create_dir(buts->name, blk_tree_root);
-
-	if (!dir)
-		goto err;
-
-	bt->dir = dir;
-	bt->dev = dev;
-	atomic_set(&bt->dropped, 0);
-
-	ret = -EIO;
-	bt->dropped_file = debugfs_create_file("dropped", 0444, dir, bt, &blk_dropped_fops);
-	if (!bt->dropped_file)
-		goto err;
-
-	bt->msg_file = debugfs_create_file("msg", 0222, dir, bt, &blk_msg_fops);
-	if (!bt->msg_file)
-		goto err;
-
-	bt->rchan = relay_open("trace", dir, buts->buf_size,
-				buts->buf_nr, &blk_relay_callbacks, bt);
-	if (!bt->rchan)
-		goto err;
-
-	bt->act_mask = buts->act_mask;
-	if (!bt->act_mask)
-		bt->act_mask = (u16) -1;
-
-	bt->start_lba = buts->start_lba;
-	bt->end_lba = buts->end_lba;
-	if (!bt->end_lba)
-		bt->end_lba = -1ULL;
-
-	bt->pid = buts->pid;
-	bt->trace_state = Blktrace_setup;
-
-	mutex_lock(&blk_probe_mutex);
-	if (atomic_add_return(1, &blk_probes_ref) == 1) {
-		ret = blk_register_tracepoints();
-		if (ret)
-			goto probe_err;
-	}
-	mutex_unlock(&blk_probe_mutex);
-
-	ret = -EBUSY;
-	old_bt = xchg(&q->blk_trace, bt);
-	if (old_bt) {
-		(void) xchg(&q->blk_trace, old_bt);
-		goto err;
-	}
-
-	return 0;
-probe_err:
-	atomic_dec(&blk_probes_ref);
-	mutex_unlock(&blk_probe_mutex);
-err:
-	if (bt) {
-		if (bt->msg_file)
-			debugfs_remove(bt->msg_file);
-		if (bt->dropped_file)
-			debugfs_remove(bt->dropped_file);
-		free_percpu(bt->sequence);
-		free_percpu(bt->msg_data);
-		if (bt->rchan)
-			relay_close(bt->rchan);
-		kfree(bt);
-	}
-	return ret;
-}
-
-int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
-		    char __user *arg)
-{
-	struct blk_user_trace_setup buts;
-	int ret;
-
-	ret = copy_from_user(&buts, arg, sizeof(buts));
-	if (ret)
-		return -EFAULT;
-
-	ret = do_blk_trace_setup(q, name, dev, &buts);
-	if (ret)
-		return ret;
-
-	if (copy_to_user(arg, &buts, sizeof(buts)))
-		return -EFAULT;
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(blk_trace_setup);
-
-int blk_trace_startstop(struct request_queue *q, int start)
-{
-	struct blk_trace *bt;
-	int ret;
-
-	if ((bt = q->blk_trace) == NULL)
-		return -EINVAL;
-
-	/*
-	 * For starting a trace, we can transition from a setup or stopped
-	 * trace. For stopping a trace, the state must be running
-	 */
-	ret = -EINVAL;
-	if (start) {
-		if (bt->trace_state == Blktrace_setup ||
-		    bt->trace_state == Blktrace_stopped) {
-			blktrace_seq++;
-			smp_mb();
-			bt->trace_state = Blktrace_running;
-
-			trace_note_time(bt);
-			ret = 0;
-		}
-	} else {
-		if (bt->trace_state == Blktrace_running) {
-			bt->trace_state = Blktrace_stopped;
-			relay_flush(bt->rchan);
-			ret = 0;
-		}
-	}
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(blk_trace_startstop);
-
-/**
- * blk_trace_ioctl: - handle the ioctls associated with tracing
- * @bdev:	the block device
- * @cmd: 	the ioctl cmd
- * @arg:	the argument data, if any
- *
- **/
-int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
-{
-	struct request_queue *q;
-	int ret, start = 0;
-	char b[BDEVNAME_SIZE];
-
-	q = bdev_get_queue(bdev);
-	if (!q)
-		return -ENXIO;
-
-	mutex_lock(&bdev->bd_mutex);
-
-	switch (cmd) {
-	case BLKTRACESETUP:
-		bdevname(bdev, b);
-		ret = blk_trace_setup(q, b, bdev->bd_dev, arg);
-		break;
-	case BLKTRACESTART:
-		start = 1;
-	case BLKTRACESTOP:
-		ret = blk_trace_startstop(q, start);
-		break;
-	case BLKTRACETEARDOWN:
-		ret = blk_trace_remove(q);
-		break;
-	default:
-		ret = -ENOTTY;
-		break;
-	}
-
-	mutex_unlock(&bdev->bd_mutex);
-	return ret;
-}
-
-/**
- * blk_trace_shutdown: - stop and cleanup trace structures
- * @q:    the request queue associated with the device
- *
- **/
-void blk_trace_shutdown(struct request_queue *q)
-{
-	if (q->blk_trace) {
-		blk_trace_startstop(q, 0);
-		blk_trace_remove(q);
-	}
-}
-
-/*
- * blktrace probes
- */
-
-/**
- * blk_add_trace_rq - Add a trace for a request oriented action
- * @q:		queue the io is for
- * @rq:		the source request
- * @what:	the action
- *
- * Description:
- *     Records an action against a request. Will log the bio offset + size.
- *
- **/
-static void blk_add_trace_rq(struct request_queue *q, struct request *rq,
-				    u32 what)
-{
-	struct blk_trace *bt = q->blk_trace;
-	int rw = rq->cmd_flags & 0x03;
-
-	if (likely(!bt))
-		return;
-
-	if (blk_discard_rq(rq))
-		rw |= (1 << BIO_RW_DISCARD);
-
-	if (blk_pc_request(rq)) {
-		what |= BLK_TC_ACT(BLK_TC_PC);
-		__blk_add_trace(bt, 0, rq->data_len, rw, what, rq->errors,
-				sizeof(rq->cmd), rq->cmd);
-	} else  {
-		what |= BLK_TC_ACT(BLK_TC_FS);
-		__blk_add_trace(bt, rq->hard_sector, rq->hard_nr_sectors << 9,
-				rw, what, rq->errors, 0, NULL);
-	}
-}
-
-static void blk_add_trace_rq_abort(struct request_queue *q, struct request *rq)
-{
-	blk_add_trace_rq(q, rq, BLK_TA_ABORT);
-}
-
-static void blk_add_trace_rq_insert(struct request_queue *q, struct request *rq)
-{
-	blk_add_trace_rq(q, rq, BLK_TA_INSERT);
-}
-
-static void blk_add_trace_rq_issue(struct request_queue *q, struct request *rq)
-{
-	blk_add_trace_rq(q, rq, BLK_TA_ISSUE);
-}
-
-static void blk_add_trace_rq_requeue(struct request_queue *q, struct request *rq)
-{
-	blk_add_trace_rq(q, rq, BLK_TA_REQUEUE);
-}
-
-static void blk_add_trace_rq_complete(struct request_queue *q, struct request *rq)
-{
-	blk_add_trace_rq(q, rq, BLK_TA_COMPLETE);
-}
-
-/**
- * blk_add_trace_bio - Add a trace for a bio oriented action
- * @q:		queue the io is for
- * @bio:	the source bio
- * @what:	the action
- *
- * Description:
- *     Records an action against a bio. Will log the bio offset + size.
- *
- **/
-static void blk_add_trace_bio(struct request_queue *q, struct bio *bio,
-				     u32 what)
-{
-	struct blk_trace *bt = q->blk_trace;
-
-	if (likely(!bt))
-		return;
-
-	__blk_add_trace(bt, bio->bi_sector, bio->bi_size, bio->bi_rw, what,
-			!bio_flagged(bio, BIO_UPTODATE), 0, NULL);
-}
-
-static void blk_add_trace_bio_bounce(struct request_queue *q, struct bio *bio)
-{
-	blk_add_trace_bio(q, bio, BLK_TA_BOUNCE);
-}
-
-static void blk_add_trace_bio_complete(struct request_queue *q, struct bio *bio)
-{
-	blk_add_trace_bio(q, bio, BLK_TA_COMPLETE);
-}
-
-static void blk_add_trace_bio_backmerge(struct request_queue *q, struct bio *bio)
-{
-	blk_add_trace_bio(q, bio, BLK_TA_BACKMERGE);
-}
-
-static void blk_add_trace_bio_frontmerge(struct request_queue *q, struct bio *bio)
-{
-	blk_add_trace_bio(q, bio, BLK_TA_FRONTMERGE);
-}
-
-static void blk_add_trace_bio_queue(struct request_queue *q, struct bio *bio)
-{
-	blk_add_trace_bio(q, bio, BLK_TA_QUEUE);
-}
-
-static void blk_add_trace_getrq(struct request_queue *q, struct bio *bio, int rw)
-{
-	if (bio)
-		blk_add_trace_bio(q, bio, BLK_TA_GETRQ);
-	else {
-		struct blk_trace *bt = q->blk_trace;
-
-		if (bt)
-			__blk_add_trace(bt, 0, 0, rw, BLK_TA_GETRQ, 0, 0, NULL);
-	}
-}
-
-
-static void blk_add_trace_sleeprq(struct request_queue *q, struct bio *bio, int rw)
-{
-	if (bio)
-		blk_add_trace_bio(q, bio, BLK_TA_SLEEPRQ);
-	else {
-		struct blk_trace *bt = q->blk_trace;
-
-		if (bt)
-			__blk_add_trace(bt, 0, 0, rw, BLK_TA_SLEEPRQ, 0, 0, NULL);
-	}
-}
-
-static void blk_add_trace_plug(struct request_queue *q)
-{
-	struct blk_trace *bt = q->blk_trace;
-
-	if (bt)
-		__blk_add_trace(bt, 0, 0, 0, BLK_TA_PLUG, 0, 0, NULL);
-}
-
-static void blk_add_trace_unplug_io(struct request_queue *q)
-{
-	struct blk_trace *bt = q->blk_trace;
-
-	if (bt) {
-		unsigned int pdu = q->rq.count[READ] + q->rq.count[WRITE];
-		__be64 rpdu = cpu_to_be64(pdu);
-
-		__blk_add_trace(bt, 0, 0, 0, BLK_TA_UNPLUG_IO, 0,
-				sizeof(rpdu), &rpdu);
-	}
-}
-
-static void blk_add_trace_unplug_timer(struct request_queue *q)
-{
-	struct blk_trace *bt = q->blk_trace;
-
-	if (bt) {
-		unsigned int pdu = q->rq.count[READ] + q->rq.count[WRITE];
-		__be64 rpdu = cpu_to_be64(pdu);
-
-		__blk_add_trace(bt, 0, 0, 0, BLK_TA_UNPLUG_TIMER, 0,
-				sizeof(rpdu), &rpdu);
-	}
-}
-
-static void blk_add_trace_split(struct request_queue *q, struct bio *bio,
-				unsigned int pdu)
-{
-	struct blk_trace *bt = q->blk_trace;
-
-	if (bt) {
-		__be64 rpdu = cpu_to_be64(pdu);
-
-		__blk_add_trace(bt, bio->bi_sector, bio->bi_size, bio->bi_rw,
-				BLK_TA_SPLIT, !bio_flagged(bio, BIO_UPTODATE),
-				sizeof(rpdu), &rpdu);
-	}
-}
-
-/**
- * blk_add_trace_remap - Add a trace for a remap operation
- * @q:		queue the io is for
- * @bio:	the source bio
- * @dev:	target device
- * @from:	source sector
- * @to:		target sector
- *
- * Description:
- *     Device mapper or raid target sometimes need to split a bio because
- *     it spans a stripe (or similar). Add a trace for that action.
- *
- **/
-static void blk_add_trace_remap(struct request_queue *q, struct bio *bio,
-				       dev_t dev, sector_t from, sector_t to)
-{
-	struct blk_trace *bt = q->blk_trace;
-	struct blk_io_trace_remap r;
-
-	if (likely(!bt))
-		return;
-
-	r.device = cpu_to_be32(dev);
-	r.device_from = cpu_to_be32(bio->bi_bdev->bd_dev);
-	r.sector = cpu_to_be64(to);
-
-	__blk_add_trace(bt, from, bio->bi_size, bio->bi_rw, BLK_TA_REMAP,
-			!bio_flagged(bio, BIO_UPTODATE), sizeof(r), &r);
-}
-
-/**
- * blk_add_driver_data - Add binary message with driver-specific data
- * @q:		queue the io is for
- * @rq:		io request
- * @data:	driver-specific data
- * @len:	length of driver-specific data
- *
- * Description:
- *     Some drivers might want to write driver-specific data per request.
- *
- **/
-void blk_add_driver_data(struct request_queue *q,
-			 struct request *rq,
-			 void *data, size_t len)
-{
-	struct blk_trace *bt = q->blk_trace;
-
-	if (likely(!bt))
-		return;
-
-	if (blk_pc_request(rq))
-		__blk_add_trace(bt, 0, rq->data_len, 0, BLK_TA_DRV_DATA,
-				rq->errors, len, data);
-	else
-		__blk_add_trace(bt, rq->hard_sector, rq->hard_nr_sectors << 9,
-				0, BLK_TA_DRV_DATA, rq->errors, len, data);
-}
-EXPORT_SYMBOL_GPL(blk_add_driver_data);
-
-static int blk_register_tracepoints(void)
-{
-	int ret;
-
-	ret = register_trace_block_rq_abort(blk_add_trace_rq_abort);
-	WARN_ON(ret);
-	ret = register_trace_block_rq_insert(blk_add_trace_rq_insert);
-	WARN_ON(ret);
-	ret = register_trace_block_rq_issue(blk_add_trace_rq_issue);
-	WARN_ON(ret);
-	ret = register_trace_block_rq_requeue(blk_add_trace_rq_requeue);
-	WARN_ON(ret);
-	ret = register_trace_block_rq_complete(blk_add_trace_rq_complete);
-	WARN_ON(ret);
-	ret = register_trace_block_bio_bounce(blk_add_trace_bio_bounce);
-	WARN_ON(ret);
-	ret = register_trace_block_bio_complete(blk_add_trace_bio_complete);
-	WARN_ON(ret);
-	ret = register_trace_block_bio_backmerge(blk_add_trace_bio_backmerge);
-	WARN_ON(ret);
-	ret = register_trace_block_bio_frontmerge(blk_add_trace_bio_frontmerge);
-	WARN_ON(ret);
-	ret = register_trace_block_bio_queue(blk_add_trace_bio_queue);
-	WARN_ON(ret);
-	ret = register_trace_block_getrq(blk_add_trace_getrq);
-	WARN_ON(ret);
-	ret = register_trace_block_sleeprq(blk_add_trace_sleeprq);
-	WARN_ON(ret);
-	ret = register_trace_block_plug(blk_add_trace_plug);
-	WARN_ON(ret);
-	ret = register_trace_block_unplug_timer(blk_add_trace_unplug_timer);
-	WARN_ON(ret);
-	ret = register_trace_block_unplug_io(blk_add_trace_unplug_io);
-	WARN_ON(ret);
-	ret = register_trace_block_split(blk_add_trace_split);
-	WARN_ON(ret);
-	ret = register_trace_block_remap(blk_add_trace_remap);
-	WARN_ON(ret);
-	return 0;
-}
-
-static void blk_unregister_tracepoints(void)
-{
-	unregister_trace_block_remap(blk_add_trace_remap);
-	unregister_trace_block_split(blk_add_trace_split);
-	unregister_trace_block_unplug_io(blk_add_trace_unplug_io);
-	unregister_trace_block_unplug_timer(blk_add_trace_unplug_timer);
-	unregister_trace_block_plug(blk_add_trace_plug);
-	unregister_trace_block_sleeprq(blk_add_trace_sleeprq);
-	unregister_trace_block_getrq(blk_add_trace_getrq);
-	unregister_trace_block_bio_queue(blk_add_trace_bio_queue);
-	unregister_trace_block_bio_frontmerge(blk_add_trace_bio_frontmerge);
-	unregister_trace_block_bio_backmerge(blk_add_trace_bio_backmerge);
-	unregister_trace_block_bio_complete(blk_add_trace_bio_complete);
-	unregister_trace_block_bio_bounce(blk_add_trace_bio_bounce);
-	unregister_trace_block_rq_complete(blk_add_trace_rq_complete);
-	unregister_trace_block_rq_requeue(blk_add_trace_rq_requeue);
-	unregister_trace_block_rq_issue(blk_add_trace_rq_issue);
-	unregister_trace_block_rq_insert(blk_add_trace_rq_insert);
-	unregister_trace_block_rq_abort(blk_add_trace_rq_abort);
-
-	tracepoint_synchronize_unregister();
-}
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 664ebfd..9e80934 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -1992,8 +1992,10 @@
 		}
 		if (cfq_slice_used(cfqq) || cfq_class_idle(cfqq))
 			cfq_slice_expired(cfqd, 1);
-		else if (sync && RB_EMPTY_ROOT(&cfqq->sort_list))
+		else if (sync && !rq_noidle(rq) &&
+			 RB_EMPTY_ROOT(&cfqq->sort_list)) {
 			cfq_arm_slice_timer(cfqd);
+		}
 	}
 
 	if (!cfqd->rq_in_driver)
diff --git a/block/elevator.c b/block/elevator.c
index 98259ed..ca6788a 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -677,7 +677,7 @@
 	}
 
 	if (unplug_it && blk_queue_plugged(q)) {
-		int nrq = q->rq.count[READ] + q->rq.count[WRITE]
+		int nrq = q->rq.count[BLK_RW_SYNC] + q->rq.count[BLK_RW_ASYNC]
 			- q->in_flight;
 
 		if (nrq >= q->unplug_thresh)
diff --git a/crypto/async_tx/async_tx.c b/crypto/async_tx/async_tx.c
index f21147f..06eb6cc 100644
--- a/crypto/async_tx/async_tx.c
+++ b/crypto/async_tx/async_tx.c
@@ -30,7 +30,7 @@
 #ifdef CONFIG_DMA_ENGINE
 static int __init async_tx_init(void)
 {
-	dmaengine_get();
+	async_dmaengine_get();
 
 	printk(KERN_INFO "async_tx: api initialized (async)\n");
 
@@ -39,7 +39,7 @@
 
 static void __exit async_tx_exit(void)
 {
-	dmaengine_put();
+	async_dmaengine_put();
 }
 
 /**
@@ -56,7 +56,7 @@
 	if (depend_tx &&
 	    dma_has_cap(tx_type, depend_tx->chan->device->cap_mask))
 		return depend_tx->chan;
-	return dma_find_channel(tx_type);
+	return async_dma_find_channel(tx_type);
 }
 EXPORT_SYMBOL_GPL(__async_tx_find_channel);
 #else
diff --git a/crypto/async_tx/async_xor.c b/crypto/async_tx/async_xor.c
index 595b786..95fe2c8 100644
--- a/crypto/async_tx/async_xor.c
+++ b/crypto/async_tx/async_xor.c
@@ -30,11 +30,8 @@
 #include <linux/raid/xor.h>
 #include <linux/async_tx.h>
 
-/* do_async_xor - dma map the pages and perform the xor with an engine.
- * 	This routine is marked __always_inline so it can be compiled away
- * 	when CONFIG_DMA_ENGINE=n
- */
-static __always_inline struct dma_async_tx_descriptor *
+/* do_async_xor - dma map the pages and perform the xor with an engine */
+static __async_inline struct dma_async_tx_descriptor *
 do_async_xor(struct dma_chan *chan, struct page *dest, struct page **src_list,
 	     unsigned int offset, int src_cnt, size_t len,
 	     enum async_tx_flags flags,
diff --git a/crypto/shash.c b/crypto/shash.c
index 7a65973..2ccc8b0 100644
--- a/crypto/shash.c
+++ b/crypto/shash.c
@@ -77,6 +77,9 @@
 	u8 buf[shash_align_buffer_size(unaligned_len, alignmask)]
 		__attribute__ ((aligned));
 
+	if (unaligned_len > len)
+		unaligned_len = len;
+
 	memcpy(buf, data, unaligned_len);
 
 	return shash->update(desc, buf, unaligned_len) ?:
diff --git a/crypto/xor.c b/crypto/xor.c
index b2e6db0..996b6ee 100644
--- a/crypto/xor.c
+++ b/crypto/xor.c
@@ -18,8 +18,8 @@
 
 #define BH_TRACE 0
 #include <linux/module.h>
-#include <linux/raid/md.h>
 #include <linux/raid/xor.h>
+#include <linux/jiffies.h>
 #include <asm/xor.h>
 
 /* The xor routines to use.  */
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 8a851d0..431f8b4 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -11,9 +11,9 @@
 	select PNP
 	select CPU_IDLE
 	default y
-	---help---
+	help
 	  Advanced Configuration and Power Interface (ACPI) support for 
-	  Linux requires an ACPI compliant platform (hardware/firmware),
+	  Linux requires an ACPI-compliant platform (hardware/firmware),
 	  and assumes the presence of OS-directed configuration and power
 	  management (OSPM) software.  This option will enlarge your 
 	  kernel by about 70K.
@@ -23,20 +23,19 @@
 	  the Plug-and-Play BIOS specification (PnP BIOS), the 
 	  MultiProcessor Specification (MPS), and the Advanced Power 
 	  Management (APM) specification.  If both ACPI and APM support 
-	  are configured, whichever is loaded first shall be used.
+	  are configured, ACPI is used.
 
-	  The ACPI SourceForge project contains the latest source code, 
-	  documentation, tools, mailing list subscription, and other 
-	  information.  This project is available at:
-	  <http://sourceforge.net/projects/acpi>
+	  The project home page for the Linux ACPI subsystem is here:
+	  <http://www.lesswatts.org/projects/acpi/>
 
 	  Linux support for ACPI is based on Intel Corporation's ACPI
-	  Component Architecture (ACPI CA).  For more information see:
-	  <http://developer.intel.com/technology/iapc/acpi>
+	  Component Architecture (ACPI CA).  For more information on the
+	  ACPI CA, see:
+	  <http://acpica.org/>
 
-	  ACPI is an open industry specification co-developed by Compaq, 
-	  Intel, Microsoft, Phoenix, and Toshiba.  The specification is 
-	  available at:
+	  ACPI is an open industry specification co-developed by
+	  Hewlett-Packard, Intel, Microsoft, Phoenix, and Toshiba.
+	  The specification is available at:
 	  <http://www.acpi.info>
 
 if ACPI
@@ -49,14 +48,14 @@
 config ACPI_PROCFS
 	bool "Deprecated /proc/acpi files"
 	depends on PROC_FS
-	---help---
+	help
 	  For backwards compatibility, this option allows
 	  deprecated /proc/acpi/ files to exist, even when
 	  they have been replaced by functions in /sys.
 	  The deprecated files (and their replacements) include:
 
 	  /proc/acpi/sleep (/sys/power/state)
-	  /proc/acpi/info (/sys/modules/acpi/parameters/acpica_version)
+	  /proc/acpi/info (/sys/module/acpi/parameters/acpica_version)
 	  /proc/acpi/dsdt (/sys/firmware/acpi/tables/DSDT)
 	  /proc/acpi/fadt (/sys/firmware/acpi/tables/FACP)
 	  /proc/acpi/debug_layer (/sys/module/acpi/parameters/debug_layer)
@@ -66,11 +65,12 @@
 	  and functions which do not yet exist in /sys.
 
 	  Say N to delete /proc/acpi/ files that have moved to /sys/
+
 config ACPI_PROCFS_POWER
 	bool "Deprecated power /proc/acpi directories"
 	depends on PROC_FS
 	default y
-	---help---
+	help
 	  For backwards compatibility, this option allows
           deprecated power /proc/acpi/ directories to exist, even when
           they have been replaced by functions in /sys.
@@ -86,19 +86,19 @@
 	bool "Future power /sys interface"
 	select POWER_SUPPLY
 	default y
-	---help---
+	help
 	  Say N to disable power /sys interface
 
 config ACPI_PROC_EVENT
 	bool "Deprecated /proc/acpi/event support"
 	depends on PROC_FS
 	default y
-	---help---
-	  A user-space daemon, acpi, typically read /proc/acpi/event
-	  and handled all ACPI sub-system generated events.
+	help
+	  A user-space daemon, acpid, typically reads /proc/acpi/event
+	  and handles all ACPI-generated events.
 
-	  These events are now delivered to user-space via
-	  either the input layer, or as netlink events.
+	  These events are now delivered to user-space either
+	  via the input layer or as netlink events.
 
 	  This build option enables the old code for legacy
 	  user-space implementation.  After some time, this will
@@ -112,10 +112,13 @@
 	depends on X86
 	default y
 	help
-	  This driver adds support for the AC Adapter object, which indicates
-	  whether a system is on AC, or not. If you have a system that can
+	  This driver supports the AC Adapter object, which indicates
+	  whether a system is on AC or not.  If you have a system that can
 	  switch between A/C and battery, say Y.
 
+	  To compile this driver as a module, choose M here:
+	  the module will be called ac.
+
 config ACPI_BATTERY
 	tristate "Battery"
 	depends on X86
@@ -125,15 +128,21 @@
 	  /proc/acpi/battery. If you have a mobile system with a battery, 
 	  say Y.
 
+	  To compile this driver as a module, choose M here:
+	  the module will be called battery.
+
 config ACPI_BUTTON
 	tristate "Button"
 	depends on INPUT
 	default y
 	help
-	  This driver handles events on the power, sleep and lid buttons.
+	  This driver handles events on the power, sleep, and lid buttons.
 	  A daemon reads /proc/acpi/event and perform user-defined actions
 	  such as shutting down the system.  This is necessary for
-	  software controlled poweroff.
+	  software-controlled poweroff.
+
+	  To compile this driver as a module, choose M here:
+	  the module will be called button.
 
 config ACPI_VIDEO
 	tristate "Video"
@@ -141,38 +150,45 @@
 	depends on INPUT
 	select THERMAL
 	help
-	  This driver implement the ACPI Extensions For Display Adapters
+	  This driver implements the ACPI Extensions For Display Adapters
 	  for integrated graphics devices on motherboard, as specified in
-	  ACPI 2.0 Specification, Appendix B, allowing to perform some basic
-	  control like defining the video POST device, retrieving EDID information
-	  or to setup a video output, etc.
-	  Note that this is an ref. implementation only.  It may or may not work
-	  for your integrated video device.
+	  ACPI 2.0 Specification, Appendix B.  This supports basic operations
+	  such as defining the video POST device, retrieving EDID information,
+	  and setting up a video output.
+
+	  To compile this driver as a module, choose M here:
+	  the module will be called video.
 
 config ACPI_FAN
 	tristate "Fan"
 	select THERMAL
 	default y
 	help
-	  This driver adds support for ACPI fan devices, allowing user-mode 
+	  This driver supports ACPI fan devices, allowing user-mode
 	  applications to perform basic fan control (on, off, status).
 
+	  To compile this driver as a module, choose M here:
+	  the module will be called fan.
+
 config ACPI_DOCK
 	bool "Dock"
 	depends on EXPERIMENTAL
 	help
-	  This driver adds support for ACPI controlled docking stations and removable
-	  drive bays such as the IBM ultrabay or the Dell Module Bay.
+	  This driver supports ACPI-controlled docking stations and removable
+	  drive bays such as the IBM Ultrabay and the Dell Module Bay.
 
 config ACPI_PROCESSOR
 	tristate "Processor"
 	select THERMAL
 	default y
 	help
-	  This driver installs ACPI as the idle handler for Linux, and uses
-	  ACPI C2 and C3 processor states to save power, on systems that
+	  This driver installs ACPI as the idle handler for Linux and uses
+	  ACPI C2 and C3 processor states to save power on systems that
 	  support it.  It is required by several flavors of cpufreq
-	  Performance-state drivers.
+	  performance-state drivers.
+
+	  To compile this driver as a module, choose M here:
+	  the module will be called processor.
 
 config ACPI_HOTPLUG_CPU
 	bool
@@ -186,11 +202,14 @@
 	select THERMAL
 	default y
 	help
-	  This driver adds support for ACPI thermal zones.  Most mobile and
+	  This driver supports ACPI thermal zones.  Most mobile and
 	  some desktop systems support ACPI thermal zones.  It is HIGHLY
 	  recommended that this option be enabled, as your processor(s)
 	  may be damaged without it.
 
+	  To compile this driver as a module, choose M here:
+	  the module will be called thermal.
+
 config ACPI_NUMA
 	bool "NUMA support"
 	depends on NUMA
@@ -218,7 +237,7 @@
 	int "Disable ACPI for systems before Jan 1st this year" if X86_32
 	default 0
 	help
-	  enter a 4-digit year, eg. 2001 to disable ACPI by default
+	  Enter a 4-digit year, e.g., 2001, to disable ACPI by default
 	  on platforms with DMI BIOS date before January 1st that year.
 	  "acpi=force" can be used to override this mechanism.
 
@@ -249,10 +268,13 @@
 	tristate "PCI slot detection driver"
 	default n
 	help
-	  This driver will attempt to discover all PCI slots in your system,
-	  and creates entries in /sys/bus/pci/slots/. This feature can
-	  help you correlate PCI bus addresses with the physical geography
-	  of your slots. If you are unsure, say N.
+	  This driver creates entries in /sys/bus/pci/slots/ for all PCI
+	  slots in the system.  This can help correlate PCI bus addresses,
+	  i.e., segment/bus/device/function tuples, with physical slots in
+	  the system.  If you are unsure, say N.
+
+	  To compile this driver as a module, choose M here:
+	  the module will be called pci_slot.
 
 config X86_PM_TIMER
 	bool "Power Management Timer Support" if EMBEDDED
@@ -271,43 +293,43 @@
 	  systems require this timer. 
 
 config ACPI_CONTAINER
-	tristate "ACPI0004,PNP0A05 and PNP0A06 Container Driver (EXPERIMENTAL)"
+	tristate "Container and Module Devices (EXPERIMENTAL)"
 	depends on EXPERIMENTAL
 	default (ACPI_HOTPLUG_MEMORY || ACPI_HOTPLUG_CPU || ACPI_HOTPLUG_IO)
-	 ---help---
-	  This allows _physical_ insertion and removal of CPUs and memory.
-	  This can be useful, for example, on NUMA machines that support
-	  ACPI based physical hotplug of nodes, or non-NUMA machines that
-	  support physical cpu/memory hot-plug.
+	help
+	  This driver supports ACPI Container and Module devices (IDs
+	  ACPI0004, PNP0A05, and PNP0A06).
 
-	  If one selects "m", this driver can be loaded with
-	  "modprobe container".
+	  This helps support hotplug of nodes, CPUs, and memory.
+
+	  To compile this driver as a module, choose M here:
+	  the module will be called container.
 
 config ACPI_HOTPLUG_MEMORY
 	tristate "Memory Hotplug"
 	depends on MEMORY_HOTPLUG
 	default n
 	help
-	  This driver adds supports for ACPI Memory Hotplug.  This driver
-	  provides support for fielding notifications on ACPI memory
-	  devices (PNP0C80) which represent memory ranges that may be
-	  onlined or offlined during runtime.  
+	  This driver supports ACPI memory hotplug.  The driver
+	  fields notifications on ACPI memory devices (PNP0C80),
+	  which represent memory ranges that may be onlined or
+	  offlined during runtime.
 
-	  Enabling this driver assumes that your platform hardware
-	  and firmware have support for hot-plugging physical memory. If
-	  your system does not support physically adding or ripping out 
-	  memory DIMMs at some platform defined granularity (individually 
-	  or as a bank) at runtime, then you need not enable this driver.
+	  If your hardware and firmware do not support adding or
+	  removing memory devices at runtime, you need not enable
+	  this driver.
 
-	  If one selects "m," this driver can be loaded using the following
-	  command: 
-		$>modprobe acpi_memhotplug 
+	  To compile this driver as a module, choose M here:
+	  the module will be called acpi_memhotplug.
 
 config ACPI_SBS
 	tristate "Smart Battery System"
 	depends on X86
 	help
-	  This driver adds support for the Smart Battery System, another
+	  This driver supports the Smart Battery System, another
 	  type of access to battery information, found on some laptops.
 
+	  To compile this driver as a module, choose M here:
+	  the modules will be called sbs and sbshc.
+
 endif	# ACPI
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index b130ea0..03a985b 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -14,48 +14,50 @@
 #
 # ACPI Core Subsystem (Interpreter)
 #
-obj-y				+= osl.o utils.o reboot.o\
+obj-y				+= acpi.o \
 					acpica/
 
+# All the builtin files are in the "acpi." module_param namespace.
+acpi-y				+= osl.o utils.o reboot.o
+
 # sleep related files
-obj-y				+= wakeup.o
-obj-y				+= sleep.o
-obj-$(CONFIG_ACPI_SLEEP)	+= proc.o
+acpi-y				+= wakeup.o
+acpi-y				+= sleep.o
+acpi-$(CONFIG_ACPI_SLEEP)	+= proc.o
 
 
 #
 # ACPI Bus and Device Drivers
 #
-processor-objs	+= processor_core.o processor_throttling.o \
-				processor_idle.o processor_thermal.o
-ifdef CONFIG_CPU_FREQ
-processor-objs	+= processor_perflib.o
+acpi-y				+= bus.o glue.o
+acpi-y				+= scan.o
+acpi-y				+= ec.o
+acpi-$(CONFIG_ACPI_DOCK)	+= dock.o
+acpi-y				+= pci_root.o pci_link.o pci_irq.o pci_bind.o
+acpi-y				+= power.o
+acpi-y				+= system.o event.o
+acpi-$(CONFIG_ACPI_DEBUG)	+= debug.o
+acpi-$(CONFIG_ACPI_NUMA)	+= numa.o
+acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
+ifdef CONFIG_ACPI_VIDEO
+acpi-y				+= video_detect.o
 endif
 
-obj-y				+= bus.o glue.o
-obj-y				+= scan.o
-# Keep EC driver first. Initialization of others depend on it.
-obj-y				+= ec.o
+# These are (potentially) separate modules
 obj-$(CONFIG_ACPI_AC) 		+= ac.o
-obj-$(CONFIG_ACPI_BATTERY)	+= battery.o
 obj-$(CONFIG_ACPI_BUTTON)	+= button.o
 obj-$(CONFIG_ACPI_FAN)		+= fan.o
-obj-$(CONFIG_ACPI_DOCK)		+= dock.o
 obj-$(CONFIG_ACPI_VIDEO)	+= video.o
-ifdef CONFIG_ACPI_VIDEO
-obj-y				+= video_detect.o
-endif
-
-obj-y				+= pci_root.o pci_link.o pci_irq.o pci_bind.o
 obj-$(CONFIG_ACPI_PCI_SLOT)	+= pci_slot.o
 obj-$(CONFIG_ACPI_PROCESSOR)	+= processor.o
 obj-$(CONFIG_ACPI_CONTAINER)	+= container.o
 obj-$(CONFIG_ACPI_THERMAL)	+= thermal.o
-obj-y				+= power.o
-obj-y				+= system.o event.o
-obj-$(CONFIG_ACPI_DEBUG)	+= debug.o
-obj-$(CONFIG_ACPI_NUMA)		+= numa.o
-obj-$(CONFIG_ACPI_HOTPLUG_MEMORY)	+= acpi_memhotplug.o
-obj-$(CONFIG_ACPI_PROCFS_POWER)	+= cm_sbs.o
+obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
+obj-$(CONFIG_ACPI_BATTERY)	+= battery.o
 obj-$(CONFIG_ACPI_SBS)		+= sbshc.o
 obj-$(CONFIG_ACPI_SBS)		+= sbs.o
+
+# processor has its own "processor." module_param namespace
+processor-y			:= processor_core.o processor_throttling.o
+processor-y			+= processor_idle.o processor_thermal.o
+processor-$(CONFIG_CPU_FREQ)	+= processor_perflib.o
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile
index 3f23298..17e5082 100644
--- a/drivers/acpi/acpica/Makefile
+++ b/drivers/acpi/acpica/Makefile
@@ -18,7 +18,7 @@
 	 excreate.o  exmisc.o   exoparg2.o  exregion.o  exstore.o   exutils.o \
 	 exdump.o    exmutex.o  exoparg3.o  exresnte.o  exstoren.o
 
-obj-y += hwacpi.o  hwgpe.o  hwregs.o  hwsleep.o hwxface.o
+obj-y += hwacpi.o  hwgpe.o  hwregs.o  hwsleep.o hwxface.o hwvalid.o
 
 obj-$(ACPI_FUTURE_USAGE) += hwtimer.o
 
@@ -41,4 +41,4 @@
 
 obj-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \
 		utcopy.o utdelete.o utglobal.o utmath.o utobject.o \
-		utstate.o utmutex.o utobject.o utresrc.o
+		utstate.o utmutex.o utobject.o utresrc.o utlock.o
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index ddb40f5..16e5210 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -148,9 +148,12 @@
 ACPI_EXTERN struct acpi_table_fadt acpi_gbl_FADT;
 ACPI_EXTERN struct acpi_table_facs *acpi_gbl_FACS;
 
-/* These addresses are calculated from FADT address values */
+/* These addresses are calculated from the FADT Event Block addresses */
 
+ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_status;
 ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable;
+
+ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_status;
 ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable;
 
 /*
@@ -162,6 +165,10 @@
 ACPI_EXTERN u8 acpi_gbl_integer_byte_width;
 ACPI_EXTERN u8 acpi_gbl_integer_nybble_width;
 
+/* Reader/Writer lock is used for namespace walk and dynamic table unload */
+
+ACPI_EXTERN struct acpi_rw_lock acpi_gbl_namespace_rw_lock;
+
 /*****************************************************************************
  *
  * Mutual exlusion within ACPICA subsystem
@@ -245,6 +252,7 @@
 ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present;
 ACPI_EXTERN u8 acpi_gbl_events_initialized;
 ACPI_EXTERN u8 acpi_gbl_system_awake_and_running;
+ACPI_EXTERN u8 acpi_gbl_osi_data;
 
 #ifndef DEFINE_ACPI_GLOBALS
 
@@ -371,7 +379,6 @@
 ACPI_EXTERN char *acpi_gbl_db_filename;
 ACPI_EXTERN u32 acpi_gbl_db_debug_level;
 ACPI_EXTERN u32 acpi_gbl_db_console_debug_level;
-ACPI_EXTERN struct acpi_table_header *acpi_gbl_db_table_ptr;
 ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_db_scope_node;
 
 /*
diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h
index 58c69dc..4afa3d8 100644
--- a/drivers/acpi/acpica/achware.h
+++ b/drivers/acpi/acpica/achware.h
@@ -64,14 +64,22 @@
  */
 struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id);
 
-acpi_status
-acpi_hw_register_read(u32 register_id, u32 * return_value);
+acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control);
+
+acpi_status acpi_hw_register_read(u32 register_id, u32 *return_value);
 
 acpi_status acpi_hw_register_write(u32 register_id, u32 value);
 
 acpi_status acpi_hw_clear_acpi_status(void);
 
 /*
+ * hwvalid - Port I/O with validation
+ */
+acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width);
+
+acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width);
+
+/*
  * hwgpe - GPE support
  */
 acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info);
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index 492d027..772ee5c 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -108,6 +108,14 @@
 #endif
 #endif
 
+/* Lock structure for reader/writer interfaces */
+
+struct acpi_rw_lock {
+	acpi_mutex writer_mutex;
+	acpi_mutex reader_mutex;
+	u32 num_readers;
+};
+
 /*
  * Predefined handles for spinlocks used within the subsystem.
  * These spinlocks are created by acpi_ut_mutex_initialize
@@ -772,7 +780,19 @@
  * must be preserved.
  */
 #define ACPI_PM1_STATUS_PRESERVED_BITS          0x0800	/* Bit 11 */
-#define ACPI_PM1_CONTROL_PRESERVED_BITS         0x0200	/* Bit 9 (whatever) */
+
+/* Write-only bits must be zeroed by software */
+
+#define ACPI_PM1_CONTROL_WRITEONLY_BITS         0x2004	/* Bits 13, 2 */
+
+/* For control registers, both ignored and reserved bits must be preserved */
+
+#define ACPI_PM1_CONTROL_IGNORED_BITS           0x0201	/* Bits 9, 0(SCI_EN) */
+#define ACPI_PM1_CONTROL_RESERVED_BITS          0xC1F8	/* Bits 14-15, 3-8 */
+#define ACPI_PM1_CONTROL_PRESERVED_BITS \
+	       (ACPI_PM1_CONTROL_IGNORED_BITS | ACPI_PM1_CONTROL_RESERVED_BITS)
+
+#define ACPI_PM2_CONTROL_PRESERVED_BITS         0xFFFFFFFE	/* All except bit 0 */
 
 /*
  * Register IDs
@@ -781,12 +801,10 @@
 #define ACPI_REGISTER_PM1_STATUS                0x01
 #define ACPI_REGISTER_PM1_ENABLE                0x02
 #define ACPI_REGISTER_PM1_CONTROL               0x03
-#define ACPI_REGISTER_PM1A_CONTROL              0x04
-#define ACPI_REGISTER_PM1B_CONTROL              0x05
-#define ACPI_REGISTER_PM2_CONTROL               0x06
-#define ACPI_REGISTER_PM_TIMER                  0x07
-#define ACPI_REGISTER_PROCESSOR_BLOCK           0x08
-#define ACPI_REGISTER_SMI_COMMAND_BLOCK         0x09
+#define ACPI_REGISTER_PM2_CONTROL               0x04
+#define ACPI_REGISTER_PM_TIMER                  0x05
+#define ACPI_REGISTER_PROCESSOR_BLOCK           0x06
+#define ACPI_REGISTER_SMI_COMMAND_BLOCK         0x07
 
 /* Masks used to access the bit_registers */
 
@@ -818,7 +836,7 @@
 #define ACPI_BITMASK_SCI_ENABLE                 0x0001
 #define ACPI_BITMASK_BUS_MASTER_RLD             0x0002
 #define ACPI_BITMASK_GLOBAL_LOCK_RELEASE        0x0004
-#define ACPI_BITMASK_SLEEP_TYPE_X               0x1C00
+#define ACPI_BITMASK_SLEEP_TYPE                 0x1C00
 #define ACPI_BITMASK_SLEEP_ENABLE               0x2000
 
 #define ACPI_BITMASK_ARB_DISABLE                0x0001
@@ -844,11 +862,35 @@
 #define ACPI_BITPOSITION_SCI_ENABLE             0x00
 #define ACPI_BITPOSITION_BUS_MASTER_RLD         0x01
 #define ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE    0x02
-#define ACPI_BITPOSITION_SLEEP_TYPE_X           0x0A
+#define ACPI_BITPOSITION_SLEEP_TYPE             0x0A
 #define ACPI_BITPOSITION_SLEEP_ENABLE           0x0D
 
 #define ACPI_BITPOSITION_ARB_DISABLE            0x00
 
+/* Structs and definitions for _OSI support and I/O port validation */
+
+#define ACPI_OSI_WIN_2000               0x01
+#define ACPI_OSI_WIN_XP                 0x02
+#define ACPI_OSI_WIN_XP_SP1             0x03
+#define ACPI_OSI_WINSRV_2003            0x04
+#define ACPI_OSI_WIN_XP_SP2             0x05
+#define ACPI_OSI_WINSRV_2003_SP1        0x06
+#define ACPI_OSI_WIN_VISTA              0x07
+
+#define ACPI_ALWAYS_ILLEGAL             0x00
+
+struct acpi_interface_info {
+	char *name;
+	u8 value;
+};
+
+struct acpi_port_info {
+	char *name;
+	u16 start;
+	u16 end;
+	u8 osi_dependency;
+};
+
 /*****************************************************************************
  *
  * Resource descriptors
diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h
index 9c127e8..91ac7d7 100644
--- a/drivers/acpi/acpica/acmacros.h
+++ b/drivers/acpi/acpica/acmacros.h
@@ -292,10 +292,6 @@
 #define ACPI_GET_DESCRIPTOR_TYPE(d)     (((union acpi_descriptor *)(void *)(d))->common.descriptor_type)
 #define ACPI_SET_DESCRIPTOR_TYPE(d, t)  (((union acpi_descriptor *)(void *)(d))->common.descriptor_type = t)
 
-/* Macro to test the object type */
-
-#define ACPI_GET_OBJECT_TYPE(d)         (((union acpi_operand_object *)(void *)(d))->common.type)
-
 /*
  * Macros for the master AML opcode table
  */
diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h
index eb6f038b..544dcf8 100644
--- a/drivers/acpi/acpica/acobject.h
+++ b/drivers/acpi/acpica/acobject.h
@@ -97,7 +97,6 @@
 #define AOPOBJ_OBJECT_INITIALIZED   0x08
 #define AOPOBJ_SETUP_COMPLETE       0x10
 #define AOPOBJ_SINGLE_DATUM         0x20
-#define AOPOBJ_INVALID              0x40	/* Used if host OS won't allow an op_region address */
 
 /******************************************************************************
  *
diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h
index 16a9ca9..63f656a 100644
--- a/drivers/acpi/acpica/acpredef.h
+++ b/drivers/acpi/acpica/acpredef.h
@@ -52,41 +52,44 @@
  * 1) PTYPE1 packages do not contain sub-packages.
  *
  * ACPI_PTYPE1_FIXED: Fixed length, 1 or 2 object types:
- *     object type
- *     count
- *     object type
- *     count
+ *      object type
+ *      count
+ *      object type
+ *      count
  *
  * ACPI_PTYPE1_VAR: Variable length:
- *    object type (Int/Buf/Ref)
+ *      object type (Int/Buf/Ref)
  *
- * ACPI_PTYPE1_OPTION: Package has some required and some optional elements:
- *      Used for _PRW
+ * ACPI_PTYPE1_OPTION: Package has some required and some optional elements
+ *      (Used for _PRW)
  *
  *
  * 2) PTYPE2 packages contain a variable number of sub-packages. Each of the
  *    different types describe the contents of each of the sub-packages.
  *
  * ACPI_PTYPE2: Each subpackage contains 1 or 2 object types:
- *     object type
- *     count
- *     object type
- *     count
+ *      object type
+ *      count
+ *      object type
+ *      count
+ *      (Used for _ALR,_MLS,_PSS,_TRT,_TSS)
  *
  * ACPI_PTYPE2_COUNT: Each subpackage has a count as first element:
- *     object type
+ *      object type
+ *      (Used for _CSD,_PSD,_TSD)
  *
  * ACPI_PTYPE2_PKG_COUNT: Count of subpackages at start, 1 or 2 object types:
- *     object type
- *     count
- *     object type
- *     count
+ *      object type
+ *      count
+ *      object type
+ *      count
+ *      (Used for _CST)
  *
- * ACPI_PTYPE2_FIXED: Each subpackage is of fixed length:
- *      Used for _PRT
+ * ACPI_PTYPE2_FIXED: Each subpackage is of fixed length
+ *      (Used for _PRT)
  *
  * ACPI_PTYPE2_MIN: Each subpackage has a variable but minimum length
- *      Used for _HPX
+ *      (Used for _HPX)
  *
  *****************************************************************************/
 
diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h
index 7ce6e33..01c76b8 100644
--- a/drivers/acpi/acpica/actables.h
+++ b/drivers/acpi/acpica/actables.h
@@ -49,7 +49,7 @@
 /*
  * tbfadt - FADT parse/convert/validate
  */
-void acpi_tb_parse_fadt(u32 table_index, u8 flags);
+void acpi_tb_parse_fadt(u32 table_index);
 
 void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length);
 
@@ -79,7 +79,7 @@
 
 void acpi_tb_terminate(void);
 
-void acpi_tb_delete_namespace_by_owner(u32 table_index);
+acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index);
 
 acpi_status acpi_tb_allocate_owner_id(u32 table_index);
 
@@ -109,9 +109,8 @@
 
 void
 acpi_tb_install_table(acpi_physical_address address,
-		      u8 flags, char *signature, u32 table_index);
+		      char *signature, u32 table_index);
 
-acpi_status
-acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags);
+acpi_status acpi_tb_parse_root_table(acpi_physical_address rsdp_address);
 
 #endif				/* __ACTABLES_H__ */
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h
index 80d8813..897810b 100644
--- a/drivers/acpi/acpica/acutils.h
+++ b/drivers/acpi/acpica/acutils.h
@@ -346,6 +346,21 @@
 acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest);
 
 /*
+ * utlock - reader/writer locks
+ */
+acpi_status acpi_ut_create_rw_lock(struct acpi_rw_lock *lock);
+
+void acpi_ut_delete_rw_lock(struct acpi_rw_lock *lock);
+
+acpi_status acpi_ut_acquire_read_lock(struct acpi_rw_lock *lock);
+
+acpi_status acpi_ut_release_read_lock(struct acpi_rw_lock *lock);
+
+acpi_status acpi_ut_acquire_write_lock(struct acpi_rw_lock *lock);
+
+void acpi_ut_release_write_lock(struct acpi_rw_lock *lock);
+
+/*
  * utobject - internal object create/delete/cache routines
  */
 union acpi_operand_object *acpi_ut_create_internal_object_dbg(const char
diff --git a/drivers/acpi/acpica/dsinit.c b/drivers/acpi/acpica/dsinit.c
index eb144b1..3aae13f 100644
--- a/drivers/acpi/acpica/dsinit.c
+++ b/drivers/acpi/acpica/dsinit.c
@@ -180,11 +180,23 @@
 
 	/* Walk entire namespace from the supplied root */
 
-	status = acpi_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
-				     acpi_ds_init_one_object, &info, NULL);
+	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	/*
+	 * We don't use acpi_walk_namespace since we do not want to acquire
+	 * the namespace reader lock.
+	 */
+	status =
+	    acpi_ns_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
+				   ACPI_NS_WALK_UNLOCK, acpi_ds_init_one_object,
+				   &info, NULL);
 	if (ACPI_FAILURE(status)) {
 		ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
 	}
+	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 
 	status = acpi_get_table_by_index(table_index, &table);
 	if (ACPI_FAILURE(status)) {
diff --git a/drivers/acpi/acpica/dsmthdat.c b/drivers/acpi/acpica/dsmthdat.c
index da0f546..22b1a3c 100644
--- a/drivers/acpi/acpica/dsmthdat.c
+++ b/drivers/acpi/acpica/dsmthdat.c
@@ -713,6 +713,6 @@
 
 	/* Get the object type */
 
-	return_VALUE(ACPI_GET_OBJECT_TYPE(object));
+	return_VALUE(object->type);
 }
 #endif
diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c
index 15c628e..dab3f48 100644
--- a/drivers/acpi/acpica/dsobject.c
+++ b/drivers/acpi/acpica/dsobject.c
@@ -565,7 +565,7 @@
 
 	/* Re-type the object according to its argument */
 
-	node->type = ACPI_GET_OBJECT_TYPE(obj_desc);
+	node->type = obj_desc->common.type;
 
 	/* Attach obj to node */
 
@@ -619,7 +619,7 @@
 
 	/* Perform per-object initialization */
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_BUFFER:
 
 		/*
@@ -803,7 +803,7 @@
 	default:
 
 		ACPI_ERROR((AE_INFO, "Unimplemented data type: %X",
-			    ACPI_GET_OBJECT_TYPE(obj_desc)));
+			    obj_desc->common.type));
 
 		status = AE_AML_OPERAND_TYPE;
 		break;
diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c
index 0c3b4dd..b4c87b5 100644
--- a/drivers/acpi/acpica/dsopcode.c
+++ b/drivers/acpi/acpica/dsopcode.c
@@ -397,30 +397,6 @@
 	status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node),
 					   extra_desc->extra.aml_length,
 					   extra_desc->extra.aml_start);
-	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
-	}
-
-	/* Validate the region address/length via the host OS */
-
-	status = acpi_os_validate_address(obj_desc->region.space_id,
-					  obj_desc->region.address,
-					  (acpi_size) obj_desc->region.length,
-					  acpi_ut_get_node_name(node));
-
-	if (ACPI_FAILURE(status)) {
-		/*
-		 * Invalid address/length. We will emit an error message and mark
-		 * the region as invalid, so that it will cause an additional error if
-		 * it is ever used. Then return AE_OK.
-		 */
-		ACPI_EXCEPTION((AE_INFO, status,
-				"During address validation of OpRegion [%4.4s]",
-				node->name.ascii));
-		obj_desc->common.flags |= AOPOBJ_INVALID;
-		status = AE_OK;
-	}
-
 	return_ACPI_STATUS(status);
 }
 
@@ -484,7 +460,7 @@
 
 	/* Host object must be a Buffer */
 
-	if (ACPI_GET_OBJECT_TYPE(buffer_desc) != ACPI_TYPE_BUFFER) {
+	if (buffer_desc->common.type != ACPI_TYPE_BUFFER) {
 		ACPI_ERROR((AE_INFO,
 			    "Target of Create Field is not a Buffer object - %s",
 			    acpi_ut_get_object_type_name(buffer_desc)));
@@ -1365,10 +1341,8 @@
 			if ((ACPI_GET_DESCRIPTOR_TYPE
 			     (walk_state->results->results.obj_desc[0]) ==
 			     ACPI_DESC_TYPE_OPERAND)
-			    &&
-			    (ACPI_GET_OBJECT_TYPE
-			     (walk_state->results->results.obj_desc[0]) ==
-			     ACPI_TYPE_LOCAL_REFERENCE)
+			    && ((walk_state->results->results.obj_desc[0])->
+				common.type == ACPI_TYPE_LOCAL_REFERENCE)
 			    && ((walk_state->results->results.obj_desc[0])->
 				reference.class != ACPI_REFCLASS_INDEX)) {
 				status =
diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c
index dabc23a..dfa1041 100644
--- a/drivers/acpi/acpica/dsutils.c
+++ b/drivers/acpi/acpica/dsutils.c
@@ -816,7 +816,7 @@
 		goto push_result;
 	}
 
-	type = ACPI_GET_OBJECT_TYPE(*operand);
+	type = (*operand)->common.type;
 
 	status = acpi_ex_resolve_to_value(operand, walk_state);
 	if (ACPI_FAILURE(status)) {
diff --git a/drivers/acpi/acpica/dswexec.c b/drivers/acpi/acpica/dswexec.c
index 350e6656..f028085 100644
--- a/drivers/acpi/acpica/dswexec.c
+++ b/drivers/acpi/acpica/dswexec.c
@@ -138,11 +138,10 @@
 		goto cleanup;
 	}
 
-	if (ACPI_GET_OBJECT_TYPE(local_obj_desc) != ACPI_TYPE_INTEGER) {
+	if (local_obj_desc->common.type != ACPI_TYPE_INTEGER) {
 		ACPI_ERROR((AE_INFO,
 			    "Bad predicate (not an integer) ObjDesc=%p State=%p Type=%X",
-			    obj_desc, walk_state,
-			    ACPI_GET_OBJECT_TYPE(obj_desc)));
+			    obj_desc, walk_state, obj_desc->common.type));
 
 		status = AE_AML_OPERAND_TYPE;
 		goto cleanup;
diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c
index 803edd9..cd55c77 100644
--- a/drivers/acpi/acpica/evevent.c
+++ b/drivers/acpi/acpica/evevent.c
@@ -183,7 +183,7 @@
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Install the fixed event handlers and enable the fixed events.
+ * DESCRIPTION: Install the fixed event handlers and disable all fixed events.
  *
  ******************************************************************************/
 
@@ -200,12 +200,13 @@
 		acpi_gbl_fixed_event_handlers[i].handler = NULL;
 		acpi_gbl_fixed_event_handlers[i].context = NULL;
 
-		/* Enable the fixed event */
+		/* Disable the fixed event */
 
 		if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) {
 			status =
-			    acpi_set_register(acpi_gbl_fixed_event_info[i].
-					      enable_register_id, 0);
+			    acpi_write_bit_register(acpi_gbl_fixed_event_info
+						    [i].enable_register_id,
+						    ACPI_DISABLE_EVENT);
 			if (ACPI_FAILURE(status)) {
 				return (status);
 			}
@@ -288,16 +289,17 @@
 
 	/* Clear the status bit */
 
-	(void)acpi_set_register(acpi_gbl_fixed_event_info[event].
-				status_register_id, 1);
+	(void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+				      status_register_id, ACPI_CLEAR_STATUS);
 
 	/*
 	 * Make sure we've got a handler. If not, report an error. The event is
 	 * disabled to prevent further interrupts.
 	 */
 	if (NULL == acpi_gbl_fixed_event_handlers[event].handler) {
-		(void)acpi_set_register(acpi_gbl_fixed_event_info[event].
-					enable_register_id, 0);
+		(void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+					      enable_register_id,
+					      ACPI_DISABLE_EVENT);
 
 		ACPI_ERROR((AE_INFO,
 			    "No installed handler for fixed event [%08X]",
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c
index f345ced..b9d8ee69 100644
--- a/drivers/acpi/acpica/evgpe.c
+++ b/drivers/acpi/acpica/evgpe.c
@@ -88,10 +88,10 @@
 
 	status = acpi_ev_disable_gpe(gpe_event_info);
 
-	/* Type was validated above */
+	/* Clear the type bits and insert the new Type */
 
-	gpe_event_info->flags &= ~ACPI_GPE_TYPE_MASK;	/* Clear type bits */
-	gpe_event_info->flags |= type;	/* Insert type */
+	gpe_event_info->flags &= ~ACPI_GPE_TYPE_MASK;
+	gpe_event_info->flags |= type;
 	return_ACPI_STATUS(status);
 }
 
@@ -122,6 +122,7 @@
 	if (!gpe_register_info) {
 		return_ACPI_STATUS(AE_NOT_EXIST);
 	}
+
 	register_bit = (u8)
 	    (1 <<
 	     (gpe_event_info->gpe_number - gpe_register_info->base_gpe_number));
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c
index 484cc05..7b34636 100644
--- a/drivers/acpi/acpica/evgpeblk.c
+++ b/drivers/acpi/acpica/evgpeblk.c
@@ -104,9 +104,9 @@
 
 		while (gpe_block) {
 			if ((&gpe_block->event_info[0] <= gpe_event_info) &&
-			    (&gpe_block->
-			     event_info[((acpi_size) gpe_block->
-					 register_count) * 8] >
+			    (&gpe_block->event_info[((acpi_size)
+						     gpe_block->
+						     register_count) * 8] >
 			     gpe_event_info)) {
 				return (TRUE);
 			}
@@ -210,10 +210,9 @@
 		/* Now look at the individual GPEs in this byte register */
 
 		for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
-			gpe_event_info =
-			    &gpe_block->
-			    event_info[((acpi_size) i *
-					ACPI_GPE_REGISTER_WIDTH) + j];
+			gpe_event_info = &gpe_block->event_info[((acpi_size) i *
+								 ACPI_GPE_REGISTER_WIDTH)
+								+ j];
 
 			if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
 			    ACPI_GPE_DISPATCH_HANDLER) {
@@ -293,8 +292,8 @@
 		/* Unknown method type, just ignore it! */
 
 		ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
-				  "Ignoring unknown GPE method type: %s (name not of form _Lxx or _Exx)",
-				  name));
+				  "Ignoring unknown GPE method type: %s "
+				  "(name not of form _Lxx or _Exx)", name));
 		return_ACPI_STATUS(AE_OK);
 	}
 
@@ -306,17 +305,16 @@
 		/* Conversion failed; invalid method, just ignore it */
 
 		ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
-				  "Could not extract GPE number from name: %s (name is not of form _Lxx or _Exx)",
-				  name));
+				  "Could not extract GPE number from name: %s "
+				  "(name is not of form _Lxx or _Exx)", name));
 		return_ACPI_STATUS(AE_OK);
 	}
 
 	/* Ensure that we have a valid GPE number for this GPE block */
 
 	if ((gpe_number < gpe_block->block_base_number) ||
-	    (gpe_number >=
-	     (gpe_block->block_base_number +
-	      (gpe_block->register_count * 8)))) {
+	    (gpe_number >= (gpe_block->block_base_number +
+			    (gpe_block->register_count * 8)))) {
 		/*
 		 * Not valid for this GPE block, just ignore it. However, it may be
 		 * valid for a different GPE block, since GPE0 and GPE1 methods both
@@ -408,7 +406,7 @@
 	 */
 	obj_desc = pkg_desc->package.elements[0];
 
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
+	if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
 
 		/* Use FADT-defined GPE device (from definition of _PRW) */
 
@@ -417,15 +415,15 @@
 		/* Integer is the GPE number in the FADT described GPE blocks */
 
 		gpe_number = (u32) obj_desc->integer.value;
-	} else if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
+	} else if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
 
 		/* Package contains a GPE reference and GPE number within a GPE block */
 
 		if ((obj_desc->package.count < 2) ||
-		    (ACPI_GET_OBJECT_TYPE(obj_desc->package.elements[0]) !=
-		     ACPI_TYPE_LOCAL_REFERENCE)
-		    || (ACPI_GET_OBJECT_TYPE(obj_desc->package.elements[1]) !=
-			ACPI_TYPE_INTEGER)) {
+		    ((obj_desc->package.elements[0])->common.type !=
+		     ACPI_TYPE_LOCAL_REFERENCE) ||
+		    ((obj_desc->package.elements[1])->common.type !=
+		     ACPI_TYPE_INTEGER)) {
 			goto cleanup;
 		}
 
@@ -450,11 +448,11 @@
 	 */
 	if ((gpe_device == target_gpe_device) &&
 	    (gpe_number >= gpe_block->block_base_number) &&
-	    (gpe_number <
-	     gpe_block->block_base_number + (gpe_block->register_count * 8))) {
-		gpe_event_info =
-		    &gpe_block->event_info[gpe_number -
-					   gpe_block->block_base_number];
+	    (gpe_number < gpe_block->block_base_number +
+	     (gpe_block->register_count * 8))) {
+		gpe_event_info = &gpe_block->event_info[gpe_number -
+							gpe_block->
+							block_base_number];
 
 		/* Mark GPE for WAKE-ONLY but WAKE_DISABLED */
 
@@ -1033,8 +1031,8 @@
 	 * 1) are "runtime" or "run/wake" GPEs, and
 	 * 2) have a corresponding _Lxx or _Exx method
 	 *
-	 * Any other GPEs within this block must be enabled via the acpi_enable_gpe()
-	 * external interface.
+	 * Any other GPEs within this block must be enabled via the
+	 * acpi_enable_gpe() external interface.
 	 */
 	wake_gpe_count = 0;
 	gpe_enabled_count = 0;
@@ -1044,14 +1042,13 @@
 
 			/* Get the info block for this particular GPE */
 
-			gpe_event_info =
-			    &gpe_block->
-			    event_info[((acpi_size) i *
-					ACPI_GPE_REGISTER_WIDTH) + j];
+			gpe_event_info = &gpe_block->event_info[((acpi_size) i *
+								 ACPI_GPE_REGISTER_WIDTH)
+								+ j];
 
 			if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
-			     ACPI_GPE_DISPATCH_METHOD)
-			    && (gpe_event_info->flags & ACPI_GPE_TYPE_RUNTIME)) {
+			     ACPI_GPE_DISPATCH_METHOD) &&
+			    (gpe_event_info->flags & ACPI_GPE_TYPE_RUNTIME)) {
 				gpe_enabled_count++;
 			}
 
@@ -1105,8 +1102,8 @@
 	/*
 	 * Initialize the GPE Block(s) defined in the FADT
 	 *
-	 * Why the GPE register block lengths are divided by 2:  From the ACPI Spec,
-	 * section "General-Purpose Event Registers", we have:
+	 * Why the GPE register block lengths are divided by 2:  From the ACPI
+	 * Spec, section "General-Purpose Event Registers", we have:
 	 *
 	 * "Each register block contains two registers of equal length
 	 *  GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the
@@ -1163,7 +1160,8 @@
 		if ((register_count0) &&
 		    (gpe_number_max >= acpi_gbl_FADT.gpe1_base)) {
 			ACPI_ERROR((AE_INFO,
-				    "GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1",
+				    "GPE0 block (GPE 0 to %d) overlaps the GPE1 block "
+				    "(GPE %d to %d) - Ignoring GPE1",
 				    gpe_number_max, acpi_gbl_FADT.gpe1_base,
 				    acpi_gbl_FADT.gpe1_base +
 				    ((register_count1 *
diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c
index 5f89305..ce224e1 100644
--- a/drivers/acpi/acpica/evmisc.c
+++ b/drivers/acpi/acpica/evmisc.c
@@ -163,10 +163,10 @@
 	 * 2) Global device notify handler
 	 * 3) Per-device notify handler
 	 */
-	if ((acpi_gbl_system_notify.handler
-	     && (notify_value <= ACPI_MAX_SYS_NOTIFY))
-	    || (acpi_gbl_device_notify.handler
-		&& (notify_value > ACPI_MAX_SYS_NOTIFY)) || handler_obj) {
+	if ((acpi_gbl_system_notify.handler &&
+	     (notify_value <= ACPI_MAX_SYS_NOTIFY)) ||
+	    (acpi_gbl_device_notify.handler &&
+	     (notify_value > ACPI_MAX_SYS_NOTIFY)) || handler_obj) {
 		notify_info = acpi_ut_create_generic_state();
 		if (!notify_info) {
 			return (AE_NO_MEMORY);
@@ -174,7 +174,8 @@
 
 		if (!handler_obj) {
 			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-					  "Executing system notify handler for Notify (%4.4s, %X) node %p\n",
+					  "Executing system notify handler for Notify (%4.4s, %X) "
+					  "node %p\n",
 					  acpi_ut_get_node_name(node),
 					  notify_value, node));
 		}
@@ -534,8 +535,9 @@
 		 */
 		if (pending) {
 			status =
-			    acpi_set_register(ACPI_BITREG_GLOBAL_LOCK_RELEASE,
-					      1);
+			    acpi_write_bit_register
+			    (ACPI_BITREG_GLOBAL_LOCK_RELEASE,
+			     ACPI_ENABLE_EVENT);
 		}
 
 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c
index 665c088..538d632 100644
--- a/drivers/acpi/acpica/evregion.c
+++ b/drivers/acpi/acpica/evregion.c
@@ -691,7 +691,7 @@
 
 	/* Devices are handled different than regions */
 
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_DEVICE) {
+	if (obj_desc->common.type == ACPI_TYPE_DEVICE) {
 
 		/* Check if this Device already has a handler for this address space */
 
@@ -703,7 +703,8 @@
 			if (next_handler_obj->address_space.space_id ==
 			    handler_obj->address_space.space_id) {
 				ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
-						  "Found handler for region [%s] in device %p(%p) handler %p\n",
+						  "Found handler for region [%s] in device %p(%p) "
+						  "handler %p\n",
 						  acpi_ut_get_region_name
 						  (handler_obj->address_space.
 						   space_id), obj_desc,
diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c
index f3f1fb4..284a7be 100644
--- a/drivers/acpi/acpica/evrgnini.c
+++ b/drivers/acpi/acpica/evrgnini.c
@@ -241,7 +241,8 @@
 						status = AE_OK;
 					} else {
 						ACPI_EXCEPTION((AE_INFO, status,
-								"Could not install PciConfig handler for Root Bridge %4.4s",
+								"Could not install PciConfig handler "
+								"for Root Bridge %4.4s",
 								acpi_ut_get_node_name
 								(pci_root_node)));
 					}
@@ -293,9 +294,8 @@
 	 * Get the PCI device and function numbers from the _ADR object contained
 	 * in the parent's scope.
 	 */
-	status =
-	    acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, pci_device_node,
-					    &pci_value);
+	status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR,
+						 pci_device_node, &pci_value);
 
 	/*
 	 * The default is zero, and since the allocation above zeroed the data,
@@ -308,18 +308,16 @@
 
 	/* The PCI segment number comes from the _SEG method */
 
-	status =
-	    acpi_ut_evaluate_numeric_object(METHOD_NAME__SEG, pci_root_node,
-					    &pci_value);
+	status = acpi_ut_evaluate_numeric_object(METHOD_NAME__SEG,
+						 pci_root_node, &pci_value);
 	if (ACPI_SUCCESS(status)) {
 		pci_id->segment = ACPI_LOWORD(pci_value);
 	}
 
 	/* The PCI bus number comes from the _BBN method */
 
-	status =
-	    acpi_ut_evaluate_numeric_object(METHOD_NAME__BBN, pci_root_node,
-					    &pci_value);
+	status = acpi_ut_evaluate_numeric_object(METHOD_NAME__BBN,
+						 pci_root_node, &pci_value);
 	if (ACPI_SUCCESS(status)) {
 		pci_id->bus = ACPI_LOWORD(pci_value);
 	}
@@ -632,8 +630,8 @@
 								  acpi_ns_locked);
 
 					/*
-					 * Tell all users that this region is usable by running the _REG
-					 * method
+					 * Tell all users that this region is usable by
+					 * running the _REG method
 					 */
 					if (acpi_ns_locked) {
 						status =
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c
index 3aca901..10b8543d 100644
--- a/drivers/acpi/acpica/evxface.c
+++ b/drivers/acpi/acpica/evxface.c
@@ -631,7 +631,8 @@
 
 	/* Setup up dispatch flags to indicate handler (vs. method) */
 
-	gpe_event_info->flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);	/* Clear bits */
+	gpe_event_info->flags &=
+	    ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
 	gpe_event_info->flags |= (u8) (type | ACPI_GPE_DISPATCH_HANDLER);
 
 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c
index 35485e4..d0a080747 100644
--- a/drivers/acpi/acpica/evxfevnt.c
+++ b/drivers/acpi/acpica/evxfevnt.c
@@ -172,8 +172,8 @@
 	 * register bit)
 	 */
 	status =
-	    acpi_set_register(acpi_gbl_fixed_event_info[event].
-			      enable_register_id, 1);
+	    acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+				    enable_register_id, ACPI_ENABLE_EVENT);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -181,8 +181,8 @@
 	/* Make sure that the hardware responded */
 
 	status =
-	    acpi_get_register(acpi_gbl_fixed_event_info[event].
-			      enable_register_id, &value);
+	    acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
+				   enable_register_id, &value);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -354,15 +354,15 @@
 	 * register bit)
 	 */
 	status =
-	    acpi_set_register(acpi_gbl_fixed_event_info[event].
-			      enable_register_id, 0);
+	    acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+				    enable_register_id, ACPI_DISABLE_EVENT);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
 
 	status =
-	    acpi_get_register(acpi_gbl_fixed_event_info[event].
-			      enable_register_id, &value);
+	    acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
+				   enable_register_id, &value);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -407,8 +407,8 @@
 	 * register bit)
 	 */
 	status =
-	    acpi_set_register(acpi_gbl_fixed_event_info[event].
-			      status_register_id, 1);
+	    acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+				    status_register_id, ACPI_CLEAR_STATUS);
 
 	return_ACPI_STATUS(status);
 }
@@ -495,7 +495,7 @@
 	/* Get the status of the requested fixed event */
 
 	status =
-	    acpi_get_register(acpi_gbl_fixed_event_info[event].
+	    acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
 			      enable_register_id, &value);
 	if (ACPI_FAILURE(status))
 		return_ACPI_STATUS(status);
@@ -503,7 +503,7 @@
 	*event_status = value;
 
 	status =
-	    acpi_get_register(acpi_gbl_fixed_event_info[event].
+	    acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
 			      status_register_id, &value);
 	if (ACPI_FAILURE(status))
 		return_ACPI_STATUS(status);
diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c
index 479e7a3..7c3d2d3 100644
--- a/drivers/acpi/acpica/evxfregn.c
+++ b/drivers/acpi/acpica/evxfregn.c
@@ -193,7 +193,8 @@
 			/* Matched space_id, first dereference this in the Regions */
 
 			ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
-					  "Removing address handler %p(%p) for region %s on Device %p(%p)\n",
+					  "Removing address handler %p(%p) for region %s "
+					  "on Device %p(%p)\n",
 					  handler_obj, handler,
 					  acpi_ut_get_region_name(space_id),
 					  node, obj_desc));
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c
index 932bbc2..3deb20a 100644
--- a/drivers/acpi/acpica/exconfig.c
+++ b/drivers/acpi/acpica/exconfig.c
@@ -291,7 +291,7 @@
 
 	/* Source Object can be either an op_region or a Buffer/Field */
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_REGION:
 
 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
@@ -501,7 +501,7 @@
 	 */
 	if ((!ddb_handle) ||
 	    (ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) ||
-	    (ACPI_GET_OBJECT_TYPE(ddb_handle) != ACPI_TYPE_LOCAL_REFERENCE)) {
+	    (ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE)) {
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
@@ -520,13 +520,14 @@
 		}
 	}
 
-	/*
-	 * Delete the entire namespace under this table Node
-	 * (Offset contains the table_id)
-	 */
-	acpi_tb_delete_namespace_by_owner(table_index);
-	(void)acpi_tb_release_owner_id(table_index);
+	/* Delete the portion of the namespace owned by this table */
 
+	status = acpi_tb_delete_namespace_by_owner(table_index);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	(void)acpi_tb_release_owner_id(table_index);
 	acpi_tb_set_table_loaded_flag(table_index, FALSE);
 
 	/* Table unloaded, remove a reference to the ddb_handle object */
diff --git a/drivers/acpi/acpica/exconvrt.c b/drivers/acpi/acpica/exconvrt.c
index 0be1018..37d0d39 100644
--- a/drivers/acpi/acpica/exconvrt.c
+++ b/drivers/acpi/acpica/exconvrt.c
@@ -82,7 +82,7 @@
 
 	ACPI_FUNCTION_TRACE_PTR(ex_convert_to_integer, obj_desc);
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_INTEGER:
 
 		/* No conversion necessary */
@@ -116,7 +116,7 @@
 
 	/* String conversion is different than Buffer conversion */
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_STRING:
 
 		/*
@@ -206,7 +206,7 @@
 
 	ACPI_FUNCTION_TRACE_PTR(ex_convert_to_buffer, obj_desc);
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_BUFFER:
 
 		/* No conversion necessary */
@@ -409,7 +409,7 @@
 
 	ACPI_FUNCTION_TRACE_PTR(ex_convert_to_string, obj_desc);
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_STRING:
 
 		/* No conversion necessary */
@@ -605,8 +605,7 @@
 		default:
 			/* No conversion allowed for these types */
 
-			if (destination_type !=
-			    ACPI_GET_OBJECT_TYPE(source_desc)) {
+			if (destination_type != source_desc->common.type) {
 				ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 						  "Explicit operator, will store (%s) over existing type (%s)\n",
 						  acpi_ut_get_object_type_name
diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c
index aa31357..89d141f 100644
--- a/drivers/acpi/acpica/exdump.c
+++ b/drivers/acpi/acpica/exdump.c
@@ -350,6 +350,7 @@
 			break;
 
 		case ACPI_EXD_TYPE:
+
 			acpi_ex_out_string("Type",
 					   acpi_ut_get_object_type_name
 					   (obj_desc));
@@ -422,6 +423,7 @@
 			break;
 
 		default:
+
 			acpi_os_printf("**** Invalid table opcode [%X] ****\n",
 				       info->opcode);
 			return;
@@ -492,7 +494,7 @@
 
 	/* Decode object type */
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_LOCAL_REFERENCE:
 
 		acpi_os_printf("Reference: [%s] ",
@@ -527,46 +529,18 @@
 							     type));
 			break;
 
-		case ACPI_REFCLASS_ARG:
-
-			acpi_os_printf("%X", obj_desc->reference.value);
-
-			if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
-
-				/* Value is an Integer */
-
-				acpi_os_printf(" value is [%8.8X%8.8x]",
-					       ACPI_FORMAT_UINT64(obj_desc->
-								  integer.
-								  value));
-			}
-
-			acpi_os_printf("\n");
-			break;
-
-		case ACPI_REFCLASS_LOCAL:
-
-			acpi_os_printf("%X", obj_desc->reference.value);
-
-			if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
-
-				/* Value is an Integer */
-
-				acpi_os_printf(" value is [%8.8X%8.8x]",
-					       ACPI_FORMAT_UINT64(obj_desc->
-								  integer.
-								  value));
-			}
-
-			acpi_os_printf("\n");
-			break;
-
 		case ACPI_REFCLASS_NAME:
 
 			acpi_os_printf("- [%4.4s]\n",
 				       obj_desc->reference.node->name.ascii);
 			break;
 
+		case ACPI_REFCLASS_ARG:
+		case ACPI_REFCLASS_LOCAL:
+
+			acpi_os_printf("%X\n", obj_desc->reference.value);
+			break;
+
 		default:	/* Unknown reference class */
 
 			acpi_os_printf("%2.2X\n", obj_desc->reference.class);
@@ -661,8 +635,8 @@
 	case ACPI_TYPE_LOCAL_REGION_FIELD:
 
 		acpi_os_printf
-		    ("RegionField: Bits=%X AccWidth=%X Lock=%X Update=%X at byte=%X bit=%X of below:\n",
-		     obj_desc->field.bit_length,
+		    ("RegionField: Bits=%X AccWidth=%X Lock=%X Update=%X at "
+		     "byte=%X bit=%X of below:\n", obj_desc->field.bit_length,
 		     obj_desc->field.access_byte_width,
 		     obj_desc->field.field_flags & AML_FIELD_LOCK_RULE_MASK,
 		     obj_desc->field.field_flags & AML_FIELD_UPDATE_RULE_MASK,
@@ -686,9 +660,8 @@
 
 		if (!obj_desc->buffer_field.buffer_obj) {
 			ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "*NULL*\n"));
-		} else
-		    if (ACPI_GET_OBJECT_TYPE(obj_desc->buffer_field.buffer_obj)
-			!= ACPI_TYPE_BUFFER) {
+		} else if ((obj_desc->buffer_field.buffer_obj)->common.type !=
+			   ACPI_TYPE_BUFFER) {
 			acpi_os_printf("*not a Buffer*\n");
 		} else {
 			acpi_ex_dump_operand(obj_desc->buffer_field.buffer_obj,
@@ -737,8 +710,7 @@
 	default:
 		/* Unknown Type */
 
-		acpi_os_printf("Unknown Type %X\n",
-			       ACPI_GET_OBJECT_TYPE(obj_desc));
+		acpi_os_printf("Unknown Type %X\n", obj_desc->common.type);
 		break;
 	}
 
@@ -939,7 +911,7 @@
 
 	/* Packages may only contain a few object types */
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_INTEGER:
 
 		acpi_os_printf("[Integer] = %8.8X%8.8X\n",
@@ -990,8 +962,7 @@
 
 	default:
 
-		acpi_os_printf("[Unknown Type] %X\n",
-			       ACPI_GET_OBJECT_TYPE(obj_desc));
+		acpi_os_printf("[Unknown Type] %X\n", obj_desc->common.type);
 		break;
 	}
 }
diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c
index a352d02..546dcdd 100644
--- a/drivers/acpi/acpica/exfield.c
+++ b/drivers/acpi/acpica/exfield.c
@@ -84,7 +84,7 @@
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
+	if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) {
 		/*
 		 * If the buffer_field arguments have not been previously evaluated,
 		 * evaluate them now and save the results.
@@ -95,9 +95,8 @@
 				return_ACPI_STATUS(status);
 			}
 		}
-	} else
-	    if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REGION_FIELD)
-		&& (obj_desc->field.region_obj->region.space_id ==
+	} else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) &&
+		   (obj_desc->field.region_obj->region.space_id ==
 		    ACPI_ADR_SPACE_SMBUS)) {
 		/*
 		 * This is an SMBus read.  We must create a buffer to hold the data
@@ -163,7 +162,7 @@
 
 	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
 			  "FieldRead [TO]:   Obj %p, Type %X, Buf %p, ByteLen %X\n",
-			  obj_desc, ACPI_GET_OBJECT_TYPE(obj_desc), buffer,
+			  obj_desc, obj_desc->common.type, buffer,
 			  (u32) length));
 	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
 			  "FieldRead [FROM]: BitLen %X, BitOff %X, ByteOff %X\n",
@@ -222,7 +221,7 @@
 		return_ACPI_STATUS(AE_AML_NO_OPERAND);
 	}
 
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
+	if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) {
 		/*
 		 * If the buffer_field arguments have not been previously evaluated,
 		 * evaluate them now and save the results.
@@ -233,9 +232,8 @@
 				return_ACPI_STATUS(status);
 			}
 		}
-	} else
-	    if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REGION_FIELD)
-		&& (obj_desc->field.region_obj->region.space_id ==
+	} else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) &&
+		   (obj_desc->field.region_obj->region.space_id ==
 		    ACPI_ADR_SPACE_SMBUS)) {
 		/*
 		 * This is an SMBus write.  We will bypass the entire field mechanism
@@ -243,7 +241,7 @@
 		 *
 		 * Source must be a buffer of sufficient size (ACPI_SMBUS_BUFFER_SIZE).
 		 */
-		if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) {
+		if (source_desc->common.type != ACPI_TYPE_BUFFER) {
 			ACPI_ERROR((AE_INFO,
 				    "SMBus write requires Buffer, found type %s",
 				    acpi_ut_get_object_type_name(source_desc)));
@@ -291,7 +289,7 @@
 
 	/* Get a pointer to the data to be written */
 
-	switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
+	switch (source_desc->common.type) {
 	case ACPI_TYPE_INTEGER:
 		buffer = &source_desc->integer.value;
 		length = sizeof(source_desc->integer.value);
@@ -314,15 +312,14 @@
 	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
 			  "FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n",
 			  source_desc,
-			  acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE
-						(source_desc)),
-			  ACPI_GET_OBJECT_TYPE(source_desc), buffer, length));
+			  acpi_ut_get_type_name(source_desc->common.type),
+			  source_desc->common.type, buffer, length));
 
 	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
 			  "FieldWrite [TO]:   Obj %p (%s:%X), BitLen %X, BitOff %X, ByteOff %X\n",
 			  obj_desc,
-			  acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE(obj_desc)),
-			  ACPI_GET_OBJECT_TYPE(obj_desc),
+			  acpi_ut_get_type_name(obj_desc->common.type),
+			  obj_desc->common.type,
 			  obj_desc->common_field.bit_length,
 			  obj_desc->common_field.start_field_bit_offset,
 			  obj_desc->common_field.base_byte_offset));
diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c
index ef58ac4..99cee61 100644
--- a/drivers/acpi/acpica/exfldio.c
+++ b/drivers/acpi/acpica/exfldio.c
@@ -94,9 +94,9 @@
 
 	/* We must have a valid region */
 
-	if (ACPI_GET_OBJECT_TYPE(rgn_desc) != ACPI_TYPE_REGION) {
+	if (rgn_desc->common.type != ACPI_TYPE_REGION) {
 		ACPI_ERROR((AE_INFO, "Needed Region, found type %X (%s)",
-			    ACPI_GET_OBJECT_TYPE(rgn_desc),
+			    rgn_desc->common.type,
 			    acpi_ut_get_object_type_name(rgn_desc)));
 
 		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
@@ -113,12 +113,6 @@
 		}
 	}
 
-	/* Exit if Address/Length have been disallowed by the host OS */
-
-	if (rgn_desc->common.flags & AOPOBJ_INVALID) {
-		return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
-	}
-
 	/*
 	 * Exit now for SMBus address space, it has a non-linear address space
 	 * and the request cannot be directly validated
@@ -390,7 +384,7 @@
 	 * index_field - Write to an Index Register, then read/write from/to a
 	 *               Data Register
 	 */
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_BUFFER_FIELD:
 		/*
 		 * If the buffer_field arguments have not been previously evaluated,
@@ -527,7 +521,7 @@
 	default:
 
 		ACPI_ERROR((AE_INFO, "Wrong object type in field I/O %X",
-			    ACPI_GET_OBJECT_TYPE(obj_desc)));
+			    obj_desc->common.type));
 		status = AE_AML_INTERNAL;
 		break;
 	}
diff --git a/drivers/acpi/acpica/exmisc.c b/drivers/acpi/acpica/exmisc.c
index 6b0747ac..998eac3 100644
--- a/drivers/acpi/acpica/exmisc.c
+++ b/drivers/acpi/acpica/exmisc.c
@@ -80,7 +80,7 @@
 	switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
 	case ACPI_DESC_TYPE_OPERAND:
 
-		if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_LOCAL_REFERENCE) {
+		if (obj_desc->common.type != ACPI_TYPE_LOCAL_REFERENCE) {
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 		}
 
@@ -260,7 +260,7 @@
 	 * guaranteed to be either Integer/String/Buffer by the operand
 	 * resolution mechanism.
 	 */
-	switch (ACPI_GET_OBJECT_TYPE(operand0)) {
+	switch (operand0->common.type) {
 	case ACPI_TYPE_INTEGER:
 		status =
 		    acpi_ex_convert_to_integer(operand1, &local_operand1, 16);
@@ -277,7 +277,7 @@
 
 	default:
 		ACPI_ERROR((AE_INFO, "Invalid object type: %X",
-			    ACPI_GET_OBJECT_TYPE(operand0)));
+			    operand0->common.type));
 		status = AE_AML_INTERNAL;
 	}
 
@@ -298,7 +298,7 @@
 	 * 2) Two Strings concatenated to produce a new String
 	 * 3) Two Buffers concatenated to produce a new Buffer
 	 */
-	switch (ACPI_GET_OBJECT_TYPE(operand0)) {
+	switch (operand0->common.type) {
 	case ACPI_TYPE_INTEGER:
 
 		/* Result of two Integers is a Buffer */
@@ -379,7 +379,7 @@
 		/* Invalid object type, should not happen here */
 
 		ACPI_ERROR((AE_INFO, "Invalid object type: %X",
-			    ACPI_GET_OBJECT_TYPE(operand0)));
+			    operand0->common.type));
 		status = AE_AML_INTERNAL;
 		goto cleanup;
 	}
@@ -581,7 +581,7 @@
 	 * guaranteed to be either Integer/String/Buffer by the operand
 	 * resolution mechanism.
 	 */
-	switch (ACPI_GET_OBJECT_TYPE(operand0)) {
+	switch (operand0->common.type) {
 	case ACPI_TYPE_INTEGER:
 		status =
 		    acpi_ex_convert_to_integer(operand1, &local_operand1, 16);
@@ -608,7 +608,7 @@
 	/*
 	 * Two cases: 1) Both Integers, 2) Both Strings or Buffers
 	 */
-	if (ACPI_GET_OBJECT_TYPE(operand0) == ACPI_TYPE_INTEGER) {
+	if (operand0->common.type == ACPI_TYPE_INTEGER) {
 		/*
 		 * 1) Both operands are of type integer
 		 *    Note: local_operand1 may have changed above
diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c
index b530480..9635d21 100644
--- a/drivers/acpi/acpica/exoparg1.c
+++ b/drivers/acpi/acpica/exoparg1.c
@@ -807,11 +807,9 @@
 							 acpi_namespace_node *)
 							operand[0]);
 			if (temp_desc
-			    &&
-			    ((ACPI_GET_OBJECT_TYPE(temp_desc) ==
-			      ACPI_TYPE_STRING)
-			     || (ACPI_GET_OBJECT_TYPE(temp_desc) ==
-				 ACPI_TYPE_LOCAL_REFERENCE))) {
+			    && ((temp_desc->common.type == ACPI_TYPE_STRING)
+				|| (temp_desc->common.type ==
+				    ACPI_TYPE_LOCAL_REFERENCE))) {
 				operand[0] = temp_desc;
 				acpi_ut_add_reference(temp_desc);
 			} else {
@@ -819,7 +817,7 @@
 				goto cleanup;
 			}
 		} else {
-			switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
+			switch ((operand[0])->common.type) {
 			case ACPI_TYPE_LOCAL_REFERENCE:
 				/*
 				 * This is a deref_of (local_x | arg_x)
@@ -877,8 +875,7 @@
 
 		if (ACPI_GET_DESCRIPTOR_TYPE(operand[0]) !=
 		    ACPI_DESC_TYPE_NAMED) {
-			if (ACPI_GET_OBJECT_TYPE(operand[0]) ==
-			    ACPI_TYPE_STRING) {
+			if ((operand[0])->common.type == ACPI_TYPE_STRING) {
 				/*
 				 * This is a deref_of (String). The string is a reference
 				 * to a named ACPI object.
diff --git a/drivers/acpi/acpica/exoparg2.c b/drivers/acpi/acpica/exoparg2.c
index 0b4f513..85d95c9 100644
--- a/drivers/acpi/acpica/exoparg2.c
+++ b/drivers/acpi/acpica/exoparg2.c
@@ -399,7 +399,7 @@
 		 * At this point, the Source operand is a String, Buffer, or Package.
 		 * Verify that the index is within range.
 		 */
-		switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
+		switch ((operand[0])->common.type) {
 		case ACPI_TYPE_STRING:
 
 			if (index >= operand[0]->string.length) {
diff --git a/drivers/acpi/acpica/exoparg3.c b/drivers/acpi/acpica/exoparg3.c
index c6520bb..253f9e1 100644
--- a/drivers/acpi/acpica/exoparg3.c
+++ b/drivers/acpi/acpica/exoparg3.c
@@ -161,9 +161,8 @@
 		 * Create the return object.  The Source operand is guaranteed to be
 		 * either a String or a Buffer, so just use its type.
 		 */
-		return_desc =
-		    acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE
-						   (operand[0]));
+		return_desc = acpi_ut_create_internal_object((operand[0])->
+							     common.type);
 		if (!return_desc) {
 			status = AE_NO_MEMORY;
 			goto cleanup;
@@ -191,7 +190,7 @@
 
 		/* Strings always have a sub-pointer, not so for buffers */
 
-		switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
+		switch ((operand[0])->common.type) {
 		case ACPI_TYPE_STRING:
 
 			/* Always allocate a new buffer for the String */
diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c
index a226f74..52fec07 100644
--- a/drivers/acpi/acpica/exprep.c
+++ b/drivers/acpi/acpica/exprep.c
@@ -279,7 +279,7 @@
 		return_UINT32(0);
 	}
 
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
+	if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) {
 		/*
 		 * buffer_field access can be on any byte boundary, so the
 		 * byte_alignment is always 1 byte -- regardless of any byte_alignment
diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c
index 76ec8ff..3a54b73 100644
--- a/drivers/acpi/acpica/exregion.c
+++ b/drivers/acpi/acpica/exregion.c
@@ -294,14 +294,14 @@
 	switch (function) {
 	case ACPI_READ:
 
-		status = acpi_os_read_port((acpi_io_address) address,
+		status = acpi_hw_read_port((acpi_io_address) address,
 					   &value32, bit_width);
 		*value = value32;
 		break;
 
 	case ACPI_WRITE:
 
-		status = acpi_os_write_port((acpi_io_address) address,
+		status = acpi_hw_write_port((acpi_io_address) address,
 					    (u32) * value, bit_width);
 		break;
 
diff --git a/drivers/acpi/acpica/exresnte.c b/drivers/acpi/acpica/exresnte.c
index a063a74..607958f 100644
--- a/drivers/acpi/acpica/exresnte.c
+++ b/drivers/acpi/acpica/exresnte.c
@@ -136,7 +136,7 @@
 	switch (entry_type) {
 	case ACPI_TYPE_PACKAGE:
 
-		if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_PACKAGE) {
+		if (source_desc->common.type != ACPI_TYPE_PACKAGE) {
 			ACPI_ERROR((AE_INFO, "Object not a Package, type %s",
 				    acpi_ut_get_object_type_name(source_desc)));
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
@@ -154,7 +154,7 @@
 
 	case ACPI_TYPE_BUFFER:
 
-		if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) {
+		if (source_desc->common.type != ACPI_TYPE_BUFFER) {
 			ACPI_ERROR((AE_INFO, "Object not a Buffer, type %s",
 				    acpi_ut_get_object_type_name(source_desc)));
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
@@ -172,7 +172,7 @@
 
 	case ACPI_TYPE_STRING:
 
-		if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_STRING) {
+		if (source_desc->common.type != ACPI_TYPE_STRING) {
 			ACPI_ERROR((AE_INFO, "Object not a String, type %s",
 				    acpi_ut_get_object_type_name(source_desc)));
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
@@ -186,7 +186,7 @@
 
 	case ACPI_TYPE_INTEGER:
 
-		if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_INTEGER) {
+		if (source_desc->common.type != ACPI_TYPE_INTEGER) {
 			ACPI_ERROR((AE_INFO, "Object not a Integer, type %s",
 				    acpi_ut_get_object_type_name(source_desc)));
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
diff --git a/drivers/acpi/acpica/exresolv.c b/drivers/acpi/acpica/exresolv.c
index f6105a6..c93b54c 100644
--- a/drivers/acpi/acpica/exresolv.c
+++ b/drivers/acpi/acpica/exresolv.c
@@ -149,7 +149,7 @@
 
 	/* This is a union acpi_operand_object    */
 
-	switch (ACPI_GET_OBJECT_TYPE(stack_desc)) {
+	switch (stack_desc->common.type) {
 	case ACPI_TYPE_LOCAL_REFERENCE:
 
 		ref_type = stack_desc->reference.class;
@@ -297,8 +297,7 @@
 
 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 				  "FieldRead SourceDesc=%p Type=%X\n",
-				  stack_desc,
-				  ACPI_GET_OBJECT_TYPE(stack_desc)));
+				  stack_desc, stack_desc->common.type));
 
 		status =
 		    acpi_ex_read_data_from_field(walk_state, stack_desc,
@@ -386,7 +385,7 @@
 	 * specification of the object_type and size_of operators). This means
 	 * traversing the list of possibly many nested references.
 	 */
-	while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) {
+	while (obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
 		switch (obj_desc->reference.class) {
 		case ACPI_REFCLASS_REFOF:
 		case ACPI_REFCLASS_NAME:
@@ -518,7 +517,7 @@
 	 * Now we are guaranteed to have an object that has not been created
 	 * via the ref_of or Index operators.
 	 */
-	type = ACPI_GET_OBJECT_TYPE(obj_desc);
+	type = obj_desc->common.type;
 
       exit:
 	/* Convert internal types to external types */
diff --git a/drivers/acpi/acpica/exresop.c b/drivers/acpi/acpica/exresop.c
index 3c38027..5c729a9 100644
--- a/drivers/acpi/acpica/exresop.c
+++ b/drivers/acpi/acpica/exresop.c
@@ -212,7 +212,7 @@
 
 			/* ACPI internal object */
 
-			object_type = ACPI_GET_OBJECT_TYPE(obj_desc);
+			object_type = obj_desc->common.type;
 
 			/* Check for bad acpi_object_type */
 
@@ -287,8 +287,7 @@
 
 			if ((ACPI_GET_DESCRIPTOR_TYPE(obj_desc) ==
 			     ACPI_DESC_TYPE_OPERAND)
-			    && (ACPI_GET_OBJECT_TYPE(obj_desc) ==
-				ACPI_TYPE_STRING)) {
+			    && (obj_desc->common.type == ACPI_TYPE_STRING)) {
 				/*
 				 * String found - the string references a named object and
 				 * must be resolved to a node
@@ -336,7 +335,7 @@
 			 * -- All others must be resolved below.
 			 */
 			if ((opcode == AML_STORE_OP) &&
-			    (ACPI_GET_OBJECT_TYPE(*stack_ptr) ==
+			    ((*stack_ptr)->common.type ==
 			     ACPI_TYPE_LOCAL_REFERENCE)
 			    && ((*stack_ptr)->reference.class == ACPI_REFCLASS_INDEX)) {
 				goto next_operand;
@@ -490,7 +489,7 @@
 
 			/* Need an operand of type INTEGER, STRING or BUFFER */
 
-			switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+			switch (obj_desc->common.type) {
 			case ACPI_TYPE_INTEGER:
 			case ACPI_TYPE_STRING:
 			case ACPI_TYPE_BUFFER:
@@ -512,7 +511,7 @@
 
 			/* Need an operand of type STRING or BUFFER */
 
-			switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+			switch (obj_desc->common.type) {
 			case ACPI_TYPE_STRING:
 			case ACPI_TYPE_BUFFER:
 
@@ -553,7 +552,7 @@
 			 * The only reference allowed here is a direct reference to
 			 * a namespace node.
 			 */
-			switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+			switch (obj_desc->common.type) {
 			case ACPI_TYPE_PACKAGE:
 			case ACPI_TYPE_STRING:
 			case ACPI_TYPE_BUFFER:
@@ -576,7 +575,7 @@
 
 			/* Need a buffer or package or (ACPI 2.0) String */
 
-			switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+			switch (obj_desc->common.type) {
 			case ACPI_TYPE_PACKAGE:
 			case ACPI_TYPE_STRING:
 			case ACPI_TYPE_BUFFER:
@@ -598,7 +597,7 @@
 
 			/* Need an operand of type REGION or a BUFFER (which could be a resolved region field) */
 
-			switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+			switch (obj_desc->common.type) {
 			case ACPI_TYPE_BUFFER:
 			case ACPI_TYPE_REGION:
 
@@ -619,7 +618,7 @@
 
 			/* Used by the Store() operator only */
 
-			switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+			switch (obj_desc->common.type) {
 			case ACPI_TYPE_INTEGER:
 			case ACPI_TYPE_PACKAGE:
 			case ACPI_TYPE_STRING:
@@ -677,8 +676,8 @@
 		 * required object type (Simple cases only).
 		 */
 		status = acpi_ex_check_object_type(type_needed,
-						   ACPI_GET_OBJECT_TYPE
-						   (*stack_ptr), *stack_ptr);
+						   (*stack_ptr)->common.type,
+						   *stack_ptr);
 		if (ACPI_FAILURE(status)) {
 			return_ACPI_STATUS(status);
 		}
diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c
index e35e9b4..90d6061 100644
--- a/drivers/acpi/acpica/exstore.c
+++ b/drivers/acpi/acpica/exstore.c
@@ -129,7 +129,7 @@
 
 	/* source_desc is of type ACPI_DESC_TYPE_OPERAND */
 
-	switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
+	switch (source_desc->common.type) {
 	case ACPI_TYPE_INTEGER:
 
 		/* Output correct integer width */
@@ -324,7 +324,7 @@
 
 	/* Destination object must be a Reference or a Constant object */
 
-	switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {
+	switch (dest_desc->common.type) {
 	case ACPI_TYPE_LOCAL_REFERENCE:
 		break;
 
@@ -460,9 +460,8 @@
 		 */
 		obj_desc = *(index_desc->reference.where);
 
-		if (ACPI_GET_OBJECT_TYPE(source_desc) ==
-		    ACPI_TYPE_LOCAL_REFERENCE
-		    && source_desc->reference.class == ACPI_REFCLASS_TABLE) {
+		if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE &&
+		    source_desc->reference.class == ACPI_REFCLASS_TABLE) {
 
 			/* This is a DDBHandle, just add a reference to it */
 
@@ -520,8 +519,8 @@
 		 * by the INDEX_OP code.
 		 */
 		obj_desc = index_desc->reference.object;
-		if ((ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_BUFFER) &&
-		    (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_STRING)) {
+		if ((obj_desc->common.type != ACPI_TYPE_BUFFER) &&
+		    (obj_desc->common.type != ACPI_TYPE_STRING)) {
 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 		}
 
@@ -529,7 +528,7 @@
 		 * The assignment of the individual elements will be slightly
 		 * different for each source type.
 		 */
-		switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
+		switch (source_desc->common.type) {
 		case ACPI_TYPE_INTEGER:
 
 			/* Use the least-significant byte of the integer */
@@ -707,8 +706,7 @@
 		/* No conversions for all other types.  Just attach the source object */
 
 		status = acpi_ns_attach_object(node, source_desc,
-					       ACPI_GET_OBJECT_TYPE
-					       (source_desc));
+					       source_desc->common.type);
 		break;
 	}
 
diff --git a/drivers/acpi/acpica/exstoren.c b/drivers/acpi/acpica/exstoren.c
index 145d153..608e838 100644
--- a/drivers/acpi/acpica/exstoren.c
+++ b/drivers/acpi/acpica/exstoren.c
@@ -96,8 +96,7 @@
 		 * are all essentially the same.  This case handles the
 		 * "interchangeable" types Integer, String, and Buffer.
 		 */
-		if (ACPI_GET_OBJECT_TYPE(source_desc) ==
-		    ACPI_TYPE_LOCAL_REFERENCE) {
+		if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
 
 			/* Resolve a reference object first */
 
@@ -117,13 +116,11 @@
 
 		/* Must have a Integer, Buffer, or String */
 
-		if ((ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_INTEGER) &&
-		    (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) &&
-		    (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_STRING) &&
-		    !((ACPI_GET_OBJECT_TYPE(source_desc) ==
-		       ACPI_TYPE_LOCAL_REFERENCE)
-		      && (source_desc->reference.class ==
-			  ACPI_REFCLASS_TABLE))) {
+		if ((source_desc->common.type != ACPI_TYPE_INTEGER) &&
+		    (source_desc->common.type != ACPI_TYPE_BUFFER) &&
+		    (source_desc->common.type != ACPI_TYPE_STRING) &&
+		    !((source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
+		      (source_desc->reference.class == ACPI_REFCLASS_TABLE))) {
 
 			/* Conversion successful but still not a valid type */
 
@@ -218,8 +215,7 @@
 		return_ACPI_STATUS(status);
 	}
 
-	if (ACPI_GET_OBJECT_TYPE(source_desc) !=
-	    ACPI_GET_OBJECT_TYPE(dest_desc)) {
+	if (source_desc->common.type != dest_desc->common.type) {
 		/*
 		 * The source type does not match the type of the destination.
 		 * Perform the "implicit conversion" of the source to the current type
@@ -229,11 +225,10 @@
 		 * Otherwise, actual_src_desc is a temporary object to hold the
 		 * converted object.
 		 */
-		status =
-		    acpi_ex_convert_to_target_type(ACPI_GET_OBJECT_TYPE
-						   (dest_desc), source_desc,
-						   &actual_src_desc,
-						   walk_state);
+		status = acpi_ex_convert_to_target_type(dest_desc->common.type,
+							source_desc,
+							&actual_src_desc,
+							walk_state);
 		if (ACPI_FAILURE(status)) {
 			return_ACPI_STATUS(status);
 		}
@@ -252,7 +247,7 @@
 	 * We now have two objects of identical types, and we can perform a
 	 * copy of the *value* of the source object.
 	 */
-	switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {
+	switch (dest_desc->common.type) {
 	case ACPI_TYPE_INTEGER:
 
 		dest_desc->integer.value = actual_src_desc->integer.value;
diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c
index 32b85d6..87730e9 100644
--- a/drivers/acpi/acpica/exutils.c
+++ b/drivers/acpi/acpica/exutils.c
@@ -221,7 +221,7 @@
 	 */
 	if ((!obj_desc) ||
 	    (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) ||
-	    (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) {
+	    (obj_desc->common.type != ACPI_TYPE_INTEGER)) {
 		return;
 	}
 
diff --git a/drivers/acpi/acpica/hwacpi.c b/drivers/acpi/acpica/hwacpi.c
index a9d4fea..9af361a 100644
--- a/drivers/acpi/acpica/hwacpi.c
+++ b/drivers/acpi/acpica/hwacpi.c
@@ -86,7 +86,8 @@
 	 */
 	if (!acpi_gbl_FADT.acpi_enable && !acpi_gbl_FADT.acpi_disable) {
 		ACPI_ERROR((AE_INFO,
-			    "No ACPI mode transition supported in this system (enable/disable both zero)"));
+			    "No ACPI mode transition supported in this system "
+			    "(enable/disable both zero)"));
 		return_ACPI_STATUS(AE_OK);
 	}
 
@@ -95,7 +96,7 @@
 
 		/* BIOS should have disabled ALL fixed and GP events */
 
-		status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
+		status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
 					    (u32) acpi_gbl_FADT.acpi_enable, 8);
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 				  "Attempting to enable ACPI mode\n"));
@@ -107,7 +108,7 @@
 		 * BIOS should clear all fixed status bits and restore fixed event
 		 * enable bits to default
 		 */
-		status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
+		status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
 					    (u32) acpi_gbl_FADT.acpi_disable,
 					    8);
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -172,7 +173,7 @@
 		return_UINT32(ACPI_SYS_MODE_ACPI);
 	}
 
-	status = acpi_get_register(ACPI_BITREG_SCI_ENABLE, &value);
+	status = acpi_read_bit_register(ACPI_BITREG_SCI_ENABLE, &value);
 	if (ACPI_FAILURE(status)) {
 		return_UINT32(ACPI_SYS_MODE_LEGACY);
 	}
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c
index 2013b66..d3b7e37 100644
--- a/drivers/acpi/acpica/hwgpe.c
+++ b/drivers/acpi/acpica/hwgpe.c
@@ -89,10 +89,9 @@
 
 	/* Clear just the bit that corresponds to this GPE */
 
-	ACPI_CLEAR_BIT(enable_mask,
-		       ((u32) 1 <<
-			(gpe_event_info->gpe_number -
-			 gpe_register_info->base_gpe_number)));
+	ACPI_CLEAR_BIT(enable_mask, ((u32)1 <<
+				     (gpe_event_info->gpe_number -
+				      gpe_register_info->base_gpe_number)));
 
 	/* Write the updated enable mask */
 
@@ -156,10 +155,9 @@
 
 	ACPI_FUNCTION_ENTRY();
 
-	register_bit = (u8)
-	    (1 <<
-	     (gpe_event_info->gpe_number -
-	      gpe_event_info->register_info->base_gpe_number));
+	register_bit = (u8)(1 <<
+			    (gpe_event_info->gpe_number -
+			     gpe_event_info->register_info->base_gpe_number));
 
 	/*
 	 * Write a one to the appropriate bit in the status register to
@@ -206,10 +204,9 @@
 
 	/* Get the register bitmask for this GPE */
 
-	register_bit = (u8)
-	    (1 <<
-	     (gpe_event_info->gpe_number -
-	      gpe_event_info->register_info->base_gpe_number));
+	register_bit = (u8)(1 <<
+			    (gpe_event_info->gpe_number -
+			     gpe_event_info->register_info->base_gpe_number));
 
 	/* GPE currently enabled? (enabled for runtime?) */
 
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c
index 4dc43b0..7b2fb60 100644
--- a/drivers/acpi/acpica/hwregs.c
+++ b/drivers/acpi/acpica/hwregs.c
@@ -51,6 +51,17 @@
 #define _COMPONENT          ACPI_HARDWARE
 ACPI_MODULE_NAME("hwregs")
 
+/* Local Prototypes */
+static acpi_status
+acpi_hw_read_multiple(u32 *value,
+		      struct acpi_generic_address *register_a,
+		      struct acpi_generic_address *register_b);
+
+static acpi_status
+acpi_hw_write_multiple(u32 value,
+		       struct acpi_generic_address *register_a,
+		       struct acpi_generic_address *register_b);
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_hw_clear_acpi_status
@@ -60,9 +71,9 @@
  * RETURN:      Status
  *
  * DESCRIPTION: Clears all fixed and general purpose status bits
- *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
  *
  ******************************************************************************/
+
 acpi_status acpi_hw_clear_acpi_status(void)
 {
 	acpi_status status;
@@ -70,28 +81,20 @@
 
 	ACPI_FUNCTION_TRACE(hw_clear_acpi_status);
 
-	ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n",
+	ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %0llX\n",
 			  ACPI_BITMASK_ALL_FIXED_STATUS,
-			  (u16) acpi_gbl_FADT.xpm1a_event_block.address));
+			  acpi_gbl_xpm1a_status.address));
 
 	lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
 
+	/* Clear the fixed events in PM1 A/B */
+
 	status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
 					ACPI_BITMASK_ALL_FIXED_STATUS);
 	if (ACPI_FAILURE(status)) {
 		goto unlock_and_exit;
 	}
 
-	/* Clear the fixed events */
-
-	if (acpi_gbl_FADT.xpm1b_event_block.address) {
-		status = acpi_write(ACPI_BITMASK_ALL_FIXED_STATUS,
-				    &acpi_gbl_FADT.xpm1b_event_block);
-		if (ACPI_FAILURE(status)) {
-			goto unlock_and_exit;
-		}
-	}
-
 	/* Clear the GPE Bits in all GPE registers in all GPE blocks */
 
 	status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block, NULL);
@@ -128,6 +131,42 @@
 
 /******************************************************************************
  *
+ * FUNCTION:    acpi_hw_write_pm1_control
+ *
+ * PARAMETERS:  pm1a_control        - Value to be written to PM1A control
+ *              pm1b_control        - Value to be written to PM1B control
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Write the PM1 A/B control registers. These registers are
+ *              different than than the PM1 A/B status and enable registers
+ *              in that different values can be written to the A/B registers.
+ *              Most notably, the SLP_TYP bits can be different, as per the
+ *              values returned from the _Sx predefined methods.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control)
+{
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE(hw_write_pm1_control);
+
+	status = acpi_write(pm1a_control, &acpi_gbl_FADT.xpm1a_control_block);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	if (acpi_gbl_FADT.xpm1b_control_block.address) {
+		status =
+		    acpi_write(pm1b_control,
+			       &acpi_gbl_FADT.xpm1b_control_block);
+	}
+	return_ACPI_STATUS(status);
+}
+
+/******************************************************************************
+ *
  * FUNCTION:    acpi_hw_register_read
  *
  * PARAMETERS:  register_id         - ACPI Register ID
@@ -141,64 +180,56 @@
 acpi_status
 acpi_hw_register_read(u32 register_id, u32 * return_value)
 {
-	u32 value1 = 0;
-	u32 value2 = 0;
+	u32 value = 0;
 	acpi_status status;
 
 	ACPI_FUNCTION_TRACE(hw_register_read);
 
 	switch (register_id) {
-	case ACPI_REGISTER_PM1_STATUS:	/* 16-bit access */
+	case ACPI_REGISTER_PM1_STATUS:	/* PM1 A/B: 16-bit access each */
 
-		status = acpi_read(&value1, &acpi_gbl_FADT.xpm1a_event_block);
-		if (ACPI_FAILURE(status)) {
-			goto exit;
-		}
-
-		/* PM1B is optional */
-
-		status = acpi_read(&value2, &acpi_gbl_FADT.xpm1b_event_block);
-		value1 |= value2;
+		status = acpi_hw_read_multiple(&value,
+					       &acpi_gbl_xpm1a_status,
+					       &acpi_gbl_xpm1b_status);
 		break;
 
-	case ACPI_REGISTER_PM1_ENABLE:	/* 16-bit access */
+	case ACPI_REGISTER_PM1_ENABLE:	/* PM1 A/B: 16-bit access each */
 
-		status = acpi_read(&value1, &acpi_gbl_xpm1a_enable);
-		if (ACPI_FAILURE(status)) {
-			goto exit;
-		}
-
-		/* PM1B is optional */
-
-		status = acpi_read(&value2, &acpi_gbl_xpm1b_enable);
-		value1 |= value2;
+		status = acpi_hw_read_multiple(&value,
+					       &acpi_gbl_xpm1a_enable,
+					       &acpi_gbl_xpm1b_enable);
 		break;
 
-	case ACPI_REGISTER_PM1_CONTROL:	/* 16-bit access */
+	case ACPI_REGISTER_PM1_CONTROL:	/* PM1 A/B: 16-bit access each */
 
-		status = acpi_read(&value1, &acpi_gbl_FADT.xpm1a_control_block);
-		if (ACPI_FAILURE(status)) {
-			goto exit;
-		}
+		status = acpi_hw_read_multiple(&value,
+					       &acpi_gbl_FADT.
+					       xpm1a_control_block,
+					       &acpi_gbl_FADT.
+					       xpm1b_control_block);
 
-		status = acpi_read(&value2, &acpi_gbl_FADT.xpm1b_control_block);
-		value1 |= value2;
+		/*
+		 * Zero the write-only bits. From the ACPI specification, "Hardware
+		 * Write-Only Bits": "Upon reads to registers with write-only bits,
+		 * software masks out all write-only bits."
+		 */
+		value &= ~ACPI_PM1_CONTROL_WRITEONLY_BITS;
 		break;
 
 	case ACPI_REGISTER_PM2_CONTROL:	/* 8-bit access */
 
-		status = acpi_read(&value1, &acpi_gbl_FADT.xpm2_control_block);
+		status = acpi_read(&value, &acpi_gbl_FADT.xpm2_control_block);
 		break;
 
 	case ACPI_REGISTER_PM_TIMER:	/* 32-bit access */
 
-		status = acpi_read(&value1, &acpi_gbl_FADT.xpm_timer_block);
+		status = acpi_read(&value, &acpi_gbl_FADT.xpm_timer_block);
 		break;
 
 	case ACPI_REGISTER_SMI_COMMAND_BLOCK:	/* 8-bit access */
 
 		status =
-		    acpi_os_read_port(acpi_gbl_FADT.smi_command, &value1, 8);
+		    acpi_hw_read_port(acpi_gbl_FADT.smi_command, &value, 8);
 		break;
 
 	default:
@@ -207,10 +238,8 @@
 		break;
 	}
 
-      exit:
-
 	if (ACPI_SUCCESS(status)) {
-		*return_value = value1;
+		*return_value = value;
 	}
 
 	return_ACPI_STATUS(status);
@@ -250,52 +279,42 @@
 	ACPI_FUNCTION_TRACE(hw_register_write);
 
 	switch (register_id) {
-	case ACPI_REGISTER_PM1_STATUS:	/* 16-bit access */
+	case ACPI_REGISTER_PM1_STATUS:	/* PM1 A/B: 16-bit access each */
+		/*
+		 * Handle the "ignored" bit in PM1 Status. According to the ACPI
+		 * specification, ignored bits are to be preserved when writing.
+		 * Normally, this would mean a read/modify/write sequence. However,
+		 * preserving a bit in the status register is different. Writing a
+		 * one clears the status, and writing a zero preserves the status.
+		 * Therefore, we must always write zero to the ignored bit.
+		 *
+		 * This behavior is clarified in the ACPI 4.0 specification.
+		 */
+		value &= ~ACPI_PM1_STATUS_PRESERVED_BITS;
 
-		/* Perform a read first to preserve certain bits (per ACPI spec) */
-
-		status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS,
-					       &read_value);
-		if (ACPI_FAILURE(status)) {
-			goto exit;
-		}
-
-		/* Insert the bits to be preserved */
-
-		ACPI_INSERT_BITS(value, ACPI_PM1_STATUS_PRESERVED_BITS,
-				 read_value);
-
-		/* Now we can write the data */
-
-		status = acpi_write(value, &acpi_gbl_FADT.xpm1a_event_block);
-		if (ACPI_FAILURE(status)) {
-			goto exit;
-		}
-
-		/* PM1B is optional */
-
-		status = acpi_write(value, &acpi_gbl_FADT.xpm1b_event_block);
+		status = acpi_hw_write_multiple(value,
+						&acpi_gbl_xpm1a_status,
+						&acpi_gbl_xpm1b_status);
 		break;
 
-	case ACPI_REGISTER_PM1_ENABLE:	/* 16-bit access */
+	case ACPI_REGISTER_PM1_ENABLE:	/* PM1 A/B: 16-bit access */
 
-		status = acpi_write(value, &acpi_gbl_xpm1a_enable);
-		if (ACPI_FAILURE(status)) {
-			goto exit;
-		}
-
-		/* PM1B is optional */
-
-		status = acpi_write(value, &acpi_gbl_xpm1b_enable);
+		status = acpi_hw_write_multiple(value,
+						&acpi_gbl_xpm1a_enable,
+						&acpi_gbl_xpm1b_enable);
 		break;
 
-	case ACPI_REGISTER_PM1_CONTROL:	/* 16-bit access */
+	case ACPI_REGISTER_PM1_CONTROL:	/* PM1 A/B: 16-bit access each */
 
 		/*
 		 * Perform a read first to preserve certain bits (per ACPI spec)
+		 * Note: This includes SCI_EN, we never want to change this bit
 		 */
-		status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
-					       &read_value);
+		status = acpi_hw_read_multiple(&read_value,
+					       &acpi_gbl_FADT.
+					       xpm1a_control_block,
+					       &acpi_gbl_FADT.
+					       xpm1b_control_block);
 		if (ACPI_FAILURE(status)) {
 			goto exit;
 		}
@@ -307,25 +326,29 @@
 
 		/* Now we can write the data */
 
-		status = acpi_write(value, &acpi_gbl_FADT.xpm1a_control_block);
+		status = acpi_hw_write_multiple(value,
+						&acpi_gbl_FADT.
+						xpm1a_control_block,
+						&acpi_gbl_FADT.
+						xpm1b_control_block);
+		break;
+
+	case ACPI_REGISTER_PM2_CONTROL:	/* 8-bit access */
+
+		/*
+		 * For control registers, all reserved bits must be preserved,
+		 * as per the ACPI spec.
+		 */
+		status =
+		    acpi_read(&read_value, &acpi_gbl_FADT.xpm2_control_block);
 		if (ACPI_FAILURE(status)) {
 			goto exit;
 		}
 
-		status = acpi_write(value, &acpi_gbl_FADT.xpm1b_control_block);
-		break;
+		/* Insert the bits to be preserved */
 
-	case ACPI_REGISTER_PM1A_CONTROL:	/* 16-bit access */
-
-		status = acpi_write(value, &acpi_gbl_FADT.xpm1a_control_block);
-		break;
-
-	case ACPI_REGISTER_PM1B_CONTROL:	/* 16-bit access */
-
-		status = acpi_write(value, &acpi_gbl_FADT.xpm1b_control_block);
-		break;
-
-	case ACPI_REGISTER_PM2_CONTROL:	/* 8-bit access */
+		ACPI_INSERT_BITS(value, ACPI_PM2_CONTROL_PRESERVED_BITS,
+				 read_value);
 
 		status = acpi_write(value, &acpi_gbl_FADT.xpm2_control_block);
 		break;
@@ -340,10 +363,11 @@
 		/* SMI_CMD is currently always in IO space */
 
 		status =
-		    acpi_os_write_port(acpi_gbl_FADT.smi_command, value, 8);
+		    acpi_hw_write_port(acpi_gbl_FADT.smi_command, value, 8);
 		break;
 
 	default:
+		ACPI_ERROR((AE_INFO, "Unknown Register ID: %X", register_id));
 		status = AE_BAD_PARAMETER;
 		break;
 	}
@@ -351,3 +375,103 @@
       exit:
 	return_ACPI_STATUS(status);
 }
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_read_multiple
+ *
+ * PARAMETERS:  Value               - Where the register value is returned
+ *              register_a           - First ACPI register (required)
+ *              register_b           - Second ACPI register (optional)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Read from the specified two-part ACPI register (such as PM1 A/B)
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_hw_read_multiple(u32 *value,
+		      struct acpi_generic_address *register_a,
+		      struct acpi_generic_address *register_b)
+{
+	u32 value_a = 0;
+	u32 value_b = 0;
+	acpi_status status;
+
+	/* The first register is always required */
+
+	status = acpi_read(&value_a, register_a);
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
+
+	/* Second register is optional */
+
+	if (register_b->address) {
+		status = acpi_read(&value_b, register_b);
+		if (ACPI_FAILURE(status)) {
+			return (status);
+		}
+	}
+
+	/*
+	 * OR the two return values together. No shifting or masking is necessary,
+	 * because of how the PM1 registers are defined in the ACPI specification:
+	 *
+	 * "Although the bits can be split between the two register blocks (each
+	 * register block has a unique pointer within the FADT), the bit positions
+	 * are maintained. The register block with unimplemented bits (that is,
+	 * those implemented in the other register block) always returns zeros,
+	 * and writes have no side effects"
+	 */
+	*value = (value_a | value_b);
+	return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_write_multiple
+ *
+ * PARAMETERS:  Value               - The value to write
+ *              register_a           - First ACPI register (required)
+ *              register_b           - Second ACPI register (optional)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Write to the specified two-part ACPI register (such as PM1 A/B)
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_hw_write_multiple(u32 value,
+		       struct acpi_generic_address *register_a,
+		       struct acpi_generic_address *register_b)
+{
+	acpi_status status;
+
+	/* The first register is always required */
+
+	status = acpi_write(value, register_a);
+	if (ACPI_FAILURE(status)) {
+		return (status);
+	}
+
+	/*
+	 * Second register is optional
+	 *
+	 * No bit shifting or clearing is necessary, because of how the PM1
+	 * registers are defined in the ACPI specification:
+	 *
+	 * "Although the bits can be split between the two register blocks (each
+	 * register block has a unique pointer within the FADT), the bit positions
+	 * are maintained. The register block with unimplemented bits (that is,
+	 * those implemented in the other register block) always returns zeros,
+	 * and writes have no side effects"
+	 */
+	if (register_b->address) {
+		status = acpi_write(value, register_b);
+	}
+
+	return (status);
+}
diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c
index a2af2a4..baa5fc0 100644
--- a/drivers/acpi/acpica/hwsleep.c
+++ b/drivers/acpi/acpica/hwsleep.c
@@ -90,6 +90,7 @@
 
 ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector)
 
+#if ACPI_MACHINE_WIDTH == 64
 /*******************************************************************************
  *
  * FUNCTION:    acpi_set_firmware_waking_vector64
@@ -100,7 +101,8 @@
  * RETURN:      Status
  *
  * DESCRIPTION: Sets the 64-bit X_firmware_waking_vector field of the FACS, if
- *              it exists in the table.
+ *              it exists in the table. This function is intended for use with
+ *              64-bit host operating systems.
  *
  ******************************************************************************/
 acpi_status
@@ -124,6 +126,7 @@
 }
 
 ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector64)
+#endif
 
 /*******************************************************************************
  *
@@ -147,9 +150,8 @@
 
 	ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_prep);
 
-	/*
-	 * _PSW methods could be run here to enable wake-on keyboard, LAN, etc.
-	 */
+	/* _PSW methods could be run here to enable wake-on keyboard, LAN, etc. */
+
 	status = acpi_get_sleep_type_data(sleep_state,
 					  &acpi_gbl_sleep_type_a,
 					  &acpi_gbl_sleep_type_b);
@@ -223,8 +225,8 @@
  ******************************************************************************/
 acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
 {
-	u32 PM1Acontrol;
-	u32 PM1Bcontrol;
+	u32 pm1a_control;
+	u32 pm1b_control;
 	struct acpi_bit_register_info *sleep_type_reg_info;
 	struct acpi_bit_register_info *sleep_enable_reg_info;
 	u32 in_value;
@@ -242,13 +244,14 @@
 	}
 
 	sleep_type_reg_info =
-	    acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE_A);
+	    acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE);
 	sleep_enable_reg_info =
 	    acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE);
 
 	/* Clear wake status */
 
-	status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
+	status =
+	    acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -289,24 +292,25 @@
 
 	/* Get current value of PM1A control */
 
-	status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
+	status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
+				       &pm1a_control);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
 	ACPI_DEBUG_PRINT((ACPI_DB_INIT,
 			  "Entering sleep state [S%d]\n", sleep_state));
 
-	/* Clear SLP_EN and SLP_TYP fields */
+	/* Clear the SLP_EN and SLP_TYP fields */
 
-	PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask |
-			 sleep_enable_reg_info->access_bit_mask);
-	PM1Bcontrol = PM1Acontrol;
+	pm1a_control &= ~(sleep_type_reg_info->access_bit_mask |
+			  sleep_enable_reg_info->access_bit_mask);
+	pm1b_control = pm1a_control;
 
-	/* Insert SLP_TYP bits */
+	/* Insert the SLP_TYP bits */
 
-	PM1Acontrol |=
+	pm1a_control |=
 	    (acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position);
-	PM1Bcontrol |=
+	pm1b_control |=
 	    (acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position);
 
 	/*
@@ -314,37 +318,25 @@
 	 * poorly implemented hardware.
 	 */
 
-	/* Write #1: fill in SLP_TYP data */
+	/* Write #1: write the SLP_TYP data to the PM1 Control registers */
 
-	status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
-					PM1Acontrol);
+	status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
 
-	status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
-					PM1Bcontrol);
-	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
-	}
+	/* Insert the sleep enable (SLP_EN) bit */
 
-	/* Insert SLP_ENABLE bit */
+	pm1a_control |= sleep_enable_reg_info->access_bit_mask;
+	pm1b_control |= sleep_enable_reg_info->access_bit_mask;
 
-	PM1Acontrol |= sleep_enable_reg_info->access_bit_mask;
-	PM1Bcontrol |= sleep_enable_reg_info->access_bit_mask;
-
-	/* Write #2: SLP_TYP + SLP_EN */
+	/* Flush caches, as per ACPI specification */
 
 	ACPI_FLUSH_CPU_CACHE();
 
-	status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
-					PM1Acontrol);
-	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
-	}
+	/* Write #2: Write both SLP_TYP + SLP_EN */
 
-	status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
-					PM1Bcontrol);
+	status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -357,8 +349,8 @@
 		 * Wait ten seconds, then try again. This is to get S4/S5 to work on
 		 * all machines.
 		 *
-		 * We wait so long to allow chipsets that poll this reg very slowly to
-		 * still read the right value. Ideally, this block would go
+		 * We wait so long to allow chipsets that poll this reg very slowly
+		 * to still read the right value. Ideally, this block would go
 		 * away entirely.
 		 */
 		acpi_os_stall(10000000);
@@ -374,7 +366,7 @@
 	/* Wait until we enter sleep state */
 
 	do {
-		status = acpi_get_register_unlocked(ACPI_BITREG_WAKE_STATUS,
+		status = acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS,
 						    &in_value);
 		if (ACPI_FAILURE(status)) {
 			return_ACPI_STATUS(status);
@@ -408,7 +400,10 @@
 
 	ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios);
 
-	status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
+	/* Clear the wake status bit (PM1) */
+
+	status =
+	    acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -435,12 +430,13 @@
 
 	ACPI_FLUSH_CPU_CACHE();
 
-	status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
+	status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
 				    (u32) acpi_gbl_FADT.S4bios_request, 8);
 
 	do {
 		acpi_os_stall(1000);
-		status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value);
+		status =
+		    acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS, &in_value);
 		if (ACPI_FAILURE(status)) {
 			return_ACPI_STATUS(status);
 		}
@@ -471,8 +467,8 @@
 	acpi_status status;
 	struct acpi_bit_register_info *sleep_type_reg_info;
 	struct acpi_bit_register_info *sleep_enable_reg_info;
-	u32 PM1Acontrol;
-	u32 PM1Bcontrol;
+	u32 pm1a_control;
+	u32 pm1b_control;
 
 	ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep);
 
@@ -486,38 +482,34 @@
 					  &acpi_gbl_sleep_type_b);
 	if (ACPI_SUCCESS(status)) {
 		sleep_type_reg_info =
-		    acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE_A);
+		    acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE);
 		sleep_enable_reg_info =
 		    acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE);
 
 		/* Get current value of PM1A control */
 
 		status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
-					       &PM1Acontrol);
+					       &pm1a_control);
 		if (ACPI_SUCCESS(status)) {
 
-			/* Clear SLP_EN and SLP_TYP fields */
+			/* Clear the SLP_EN and SLP_TYP fields */
 
-			PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask |
-					 sleep_enable_reg_info->
-					 access_bit_mask);
-			PM1Bcontrol = PM1Acontrol;
+			pm1a_control &= ~(sleep_type_reg_info->access_bit_mask |
+					  sleep_enable_reg_info->
+					  access_bit_mask);
+			pm1b_control = pm1a_control;
 
-			/* Insert SLP_TYP bits */
+			/* Insert the SLP_TYP bits */
 
-			PM1Acontrol |=
-			    (acpi_gbl_sleep_type_a << sleep_type_reg_info->
-			     bit_position);
-			PM1Bcontrol |=
-			    (acpi_gbl_sleep_type_b << sleep_type_reg_info->
-			     bit_position);
+			pm1a_control |= (acpi_gbl_sleep_type_a <<
+					 sleep_type_reg_info->bit_position);
+			pm1b_control |= (acpi_gbl_sleep_type_b <<
+					 sleep_type_reg_info->bit_position);
 
-			/* Just ignore any errors */
+			/* Write the control registers and ignore any errors */
 
-			(void)acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
-						     PM1Acontrol);
-			(void)acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
-						     PM1Bcontrol);
+			(void)acpi_hw_write_pm1_control(pm1a_control,
+							pm1b_control);
 		}
 	}
 
@@ -603,19 +595,21 @@
 	 * it to determine whether the system is rebooting or resuming. Clear
 	 * it for compatibility.
 	 */
-	acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
+	acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, 1);
 
 	acpi_gbl_system_awake_and_running = TRUE;
 
 	/* Enable power button */
 
 	(void)
-	    acpi_set_register(acpi_gbl_fixed_event_info
-			      [ACPI_EVENT_POWER_BUTTON].enable_register_id, 1);
+	    acpi_write_bit_register(acpi_gbl_fixed_event_info
+			      [ACPI_EVENT_POWER_BUTTON].
+			      enable_register_id, ACPI_ENABLE_EVENT);
 
 	(void)
-	    acpi_set_register(acpi_gbl_fixed_event_info
-			      [ACPI_EVENT_POWER_BUTTON].status_register_id, 1);
+	    acpi_write_bit_register(acpi_gbl_fixed_event_info
+			      [ACPI_EVENT_POWER_BUTTON].
+			      status_register_id, ACPI_CLEAR_STATUS);
 
 	arg.integer.value = ACPI_SST_WORKING;
 	status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL);
diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c
new file mode 100644
index 0000000..bd3c937
--- /dev/null
+++ b/drivers/acpi/acpica/hwvalid.c
@@ -0,0 +1,258 @@
+
+/******************************************************************************
+ *
+ * Module Name: hwvalid - I/O request validation
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2009, Intel Corp.
+ * All rights reserved.
+ *
+ * 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,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * 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 MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+
+#define _COMPONENT          ACPI_HARDWARE
+ACPI_MODULE_NAME("hwvalid")
+
+/* Local prototypes */
+static acpi_status
+acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width);
+
+/*
+ * Protected I/O ports. Some ports are always illegal, and some are
+ * conditionally illegal. This table must remain ordered by port address.
+ *
+ * The table is used to implement the Microsoft port access rules that
+ * first appeared in Windows XP. Some ports are always illegal, and some
+ * ports are only illegal if the BIOS calls _OSI with a win_xP string or
+ * later (meaning that the BIOS itelf is post-XP.)
+ *
+ * This provides ACPICA with the desired port protections and
+ * Microsoft compatibility.
+ *
+ * Description of port entries:
+ *  DMA:   DMA controller
+ *  PIC0:  Programmable Interrupt Controller (8259_a)
+ *  PIT1:  System Timer 1
+ *  PIT2:  System Timer 2 failsafe
+ *  RTC:   Real-time clock
+ *  CMOS:  Extended CMOS
+ *  DMA1:  DMA 1 page registers
+ *  DMA1L: DMA 1 Ch 0 low page
+ *  DMA2:  DMA 2 page registers
+ *  DMA2L: DMA 2 low page refresh
+ *  ARBC:  Arbitration control
+ *  SETUP: Reserved system board setup
+ *  POS:   POS channel select
+ *  PIC1:  Cascaded PIC
+ *  IDMA:  ISA DMA
+ *  ELCR:  PIC edge/level registers
+ *  PCI:   PCI configuration space
+ */
+static const struct acpi_port_info acpi_protected_ports[] = {
+	{"DMA", 0x0000, 0x000F, ACPI_OSI_WIN_XP},
+	{"PIC0", 0x0020, 0x0021, ACPI_ALWAYS_ILLEGAL},
+	{"PIT1", 0x0040, 0x0043, ACPI_OSI_WIN_XP},
+	{"PIT2", 0x0048, 0x004B, ACPI_OSI_WIN_XP},
+	{"RTC", 0x0070, 0x0071, ACPI_OSI_WIN_XP},
+	{"CMOS", 0x0074, 0x0076, ACPI_OSI_WIN_XP},
+	{"DMA1", 0x0081, 0x0083, ACPI_OSI_WIN_XP},
+	{"DMA1L", 0x0087, 0x0087, ACPI_OSI_WIN_XP},
+	{"DMA2", 0x0089, 0x008B, ACPI_OSI_WIN_XP},
+	{"DMA2L", 0x008F, 0x008F, ACPI_OSI_WIN_XP},
+	{"ARBC", 0x0090, 0x0091, ACPI_OSI_WIN_XP},
+	{"SETUP", 0x0093, 0x0094, ACPI_OSI_WIN_XP},
+	{"POS", 0x0096, 0x0097, ACPI_OSI_WIN_XP},
+	{"PIC1", 0x00A0, 0x00A1, ACPI_ALWAYS_ILLEGAL},
+	{"IDMA", 0x00C0, 0x00DF, ACPI_OSI_WIN_XP},
+	{"ELCR", 0x04D0, 0x04D1, ACPI_ALWAYS_ILLEGAL},
+	{"PCI", 0x0CF8, 0x0CFF, ACPI_OSI_WIN_XP}
+};
+
+#define ACPI_PORT_INFO_ENTRIES  ACPI_ARRAY_LENGTH (acpi_protected_ports)
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_validate_io_request
+ *
+ * PARAMETERS:  Address             Address of I/O port/register
+ *              bit_width           Number of bits (8,16,32)
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Validates an I/O request (address/length). Certain ports are
+ *              always illegal and some ports are only illegal depending on
+ *              the requests the BIOS AML code makes to the predefined
+ *              _OSI method.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width)
+{
+	u32 i;
+	u32 byte_width;
+	acpi_io_address last_address;
+	const struct acpi_port_info *port_info;
+
+	ACPI_FUNCTION_TRACE(hw_validate_io_request);
+
+	/* Supported widths are 8/16/32 */
+
+	if ((bit_width != 8) && (bit_width != 16) && (bit_width != 32)) {
+		return AE_BAD_PARAMETER;
+	}
+
+	port_info = acpi_protected_ports;
+	byte_width = ACPI_DIV_8(bit_width);
+	last_address = address + byte_width - 1;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_IO, "Address %p LastAddress %p Length %X",
+			  ACPI_CAST_PTR(void, address), ACPI_CAST_PTR(void,
+								      last_address),
+			  byte_width));
+
+	/* Maximum 16-bit address in I/O space */
+
+	if (last_address > ACPI_UINT16_MAX) {
+		ACPI_ERROR((AE_INFO,
+			    "Illegal I/O port address/length above 64K: 0x%p/%X",
+			    ACPI_CAST_PTR(void, address), byte_width));
+		return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
+	}
+
+	/* Exit if requested address is not within the protected port table */
+
+	if (address > acpi_protected_ports[ACPI_PORT_INFO_ENTRIES - 1].end) {
+		return_ACPI_STATUS(AE_OK);
+	}
+
+	/* Check request against the list of protected I/O ports */
+
+	for (i = 0; i < ACPI_PORT_INFO_ENTRIES; i++, port_info++) {
+		/*
+		 * Check if the requested address range will write to a reserved
+		 * port. Four cases to consider:
+		 *
+		 * 1) Address range is contained completely in the port address range
+		 * 2) Address range overlaps port range at the port range start
+		 * 3) Address range overlaps port range at the port range end
+		 * 4) Address range completely encompasses the port range
+		 */
+		if ((address <= port_info->end)
+		    && (last_address >= port_info->start)) {
+
+			/* Port illegality may depend on the _OSI calls made by the BIOS */
+
+			if (acpi_gbl_osi_data >= port_info->osi_dependency) {
+				ACPI_ERROR((AE_INFO,
+					    "Denied AML access to port 0x%p/%X (%s 0x%.4X-0x%.4X)",
+					    ACPI_CAST_PTR(void, address),
+					    byte_width, port_info->name,
+					    port_info->start, port_info->end));
+
+				return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
+			}
+		}
+
+		/* Finished if address range ends before the end of this port */
+
+		if (last_address <= port_info->end) {
+			break;
+		}
+	}
+
+	return_ACPI_STATUS(AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_read_port
+ *
+ * PARAMETERS:  Address             Address of I/O port/register to read
+ *              Value               Where value is placed
+ *              Width               Number of bits
+ *
+ * RETURN:      Value read from port
+ *
+ * DESCRIPTION: Read data from an I/O port or register. This is a front-end
+ *              to acpi_os_read_port that performs validation on both the port
+ *              address and the length.
+ *
+ *****************************************************************************/
+
+acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width)
+{
+	acpi_status status;
+
+	status = acpi_hw_validate_io_request(address, width);
+	if (ACPI_FAILURE(status)) {
+		return status;
+	}
+
+	status = acpi_os_read_port(address, value, width);
+	return status;
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_write_port
+ *
+ * PARAMETERS:  Address             Address of I/O port/register to write
+ *              Value               Value to write
+ *              Width               Number of bits
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Write data to an I/O port or register. This is a front-end
+ *              to acpi_os_write_port that performs validation on both the port
+ *              address and the length.
+ *
+ *****************************************************************************/
+
+acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width)
+{
+	acpi_status status;
+
+	status = acpi_hw_validate_io_request(address, width);
+	if (ACPI_FAILURE(status)) {
+		return status;
+	}
+
+	status = acpi_os_write_port(address, value, width);
+	return status;
+}
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c
index ae597c0..9829979 100644
--- a/drivers/acpi/acpica/hwxface.c
+++ b/drivers/acpi/acpica/hwxface.c
@@ -107,19 +107,18 @@
 	ACPI_FUNCTION_NAME(acpi_read);
 
 	/*
-	 * Must have a valid pointer to a GAS structure, and
-	 * a non-zero address within. However, don't return an error
-	 * because the PM1A/B code must not fail if B isn't present.
+	 * Must have a valid pointer to a GAS structure, and a non-zero address
+	 * within.
 	 */
 	if (!reg) {
-		return (AE_OK);
+		return (AE_BAD_PARAMETER);
 	}
 
 	/* Get a local copy of the address. Handles possible alignment issues */
 
 	ACPI_MOVE_64_TO_64(&address, &reg->address);
 	if (!address) {
-		return (AE_OK);
+		return (AE_BAD_ADDRESS);
 	}
 
 	/* Supported widths are 8/16/32 */
@@ -134,8 +133,8 @@
 	*value = 0;
 
 	/*
-	 * Two address spaces supported: Memory or IO.
-	 * PCI_Config is not supported here because the GAS struct is insufficient
+	 * Two address spaces supported: Memory or IO. PCI_Config is
+	 * not supported here because the GAS structure is insufficient
 	 */
 	switch (reg->space_id) {
 	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
@@ -147,7 +146,7 @@
 	case ACPI_ADR_SPACE_SYSTEM_IO:
 
 		status =
-		    acpi_os_read_port((acpi_io_address) address, value, width);
+		    acpi_hw_read_port((acpi_io_address) address, value, width);
 		break;
 
 	default:
@@ -187,19 +186,18 @@
 	ACPI_FUNCTION_NAME(acpi_write);
 
 	/*
-	 * Must have a valid pointer to a GAS structure, and
-	 * a non-zero address within. However, don't return an error
-	 * because the PM1A/B code must not fail if B isn't present.
+	 * Must have a valid pointer to a GAS structure, and a non-zero address
+	 * within.
 	 */
 	if (!reg) {
-		return (AE_OK);
+		return (AE_BAD_PARAMETER);
 	}
 
 	/* Get a local copy of the address. Handles possible alignment issues */
 
 	ACPI_MOVE_64_TO_64(&address, &reg->address);
 	if (!address) {
-		return (AE_OK);
+		return (AE_BAD_ADDRESS);
 	}
 
 	/* Supported widths are 8/16/32 */
@@ -222,7 +220,7 @@
 
 	case ACPI_ADR_SPACE_SYSTEM_IO:
 
-		status = acpi_os_write_port((acpi_io_address) address, value,
+		status = acpi_hw_write_port((acpi_io_address) address, value,
 					    width);
 		break;
 
@@ -244,24 +242,36 @@
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_get_register_unlocked
+ * FUNCTION:    acpi_read_bit_register
  *
- * PARAMETERS:  register_id     - ID of ACPI bit_register to access
- *              return_value    - Value that was read from the register
+ * PARAMETERS:  register_id     - ID of ACPI Bit Register to access
+ *              return_value    - Value that was read from the register,
+ *                                normalized to bit position zero.
  *
- * RETURN:      Status and the value read from specified Register. Value
+ * RETURN:      Status and the value read from the specified Register. Value
  *              returned is normalized to bit0 (is shifted all the way right)
  *
  * DESCRIPTION: ACPI bit_register read function. Does not acquire the HW lock.
  *
+ * SUPPORTS:    Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
+ *              PM2 Control.
+ *
+ * Note: The hardware lock is not required when reading the ACPI bit registers
+ *       since almost all of them are single bit and it does not matter that
+ *       the parent hardware register can be split across two physical
+ *       registers. The only multi-bit field is SLP_TYP in the PM1 control
+ *       register, but this field does not cross an 8-bit boundary (nor does
+ *       it make much sense to actually read this field.)
+ *
  ******************************************************************************/
-acpi_status acpi_get_register_unlocked(u32 register_id, u32 *return_value)
+acpi_status acpi_read_bit_register(u32 register_id, u32 *return_value)
 {
-	u32 register_value = 0;
 	struct acpi_bit_register_info *bit_reg_info;
+	u32 register_value;
+	u32 value;
 	acpi_status status;
 
-	ACPI_FUNCTION_TRACE(acpi_get_register_unlocked);
+	ACPI_FUNCTION_TRACE_U32(acpi_read_bit_register, register_id);
 
 	/* Get the info structure corresponding to the requested ACPI Register */
 
@@ -270,209 +280,133 @@
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
-	/* Read from the register */
+	/* Read the entire parent register */
 
 	status = acpi_hw_register_read(bit_reg_info->parent_register,
 				       &register_value);
-
-	if (ACPI_SUCCESS(status)) {
-
-		/* Normalize the value that was read */
-
-		register_value =
-		    ((register_value & bit_reg_info->access_bit_mask)
-		     >> bit_reg_info->bit_position);
-
-		*return_value = register_value;
-
-		ACPI_DEBUG_PRINT((ACPI_DB_IO, "Read value %8.8X register %X\n",
-				  register_value,
-				  bit_reg_info->parent_register));
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
 	}
 
-	return_ACPI_STATUS(status);
+	/* Normalize the value that was read, mask off other bits */
+
+	value = ((register_value & bit_reg_info->access_bit_mask)
+		 >> bit_reg_info->bit_position);
+
+	ACPI_DEBUG_PRINT((ACPI_DB_IO,
+			  "BitReg %X, ParentReg %X, Actual %8.8X, ReturnValue %8.8X\n",
+			  register_id, bit_reg_info->parent_register,
+			  register_value, value));
+
+	*return_value = value;
+	return_ACPI_STATUS(AE_OK);
 }
 
-ACPI_EXPORT_SYMBOL(acpi_get_register_unlocked)
+ACPI_EXPORT_SYMBOL(acpi_read_bit_register)
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_get_register
+ * FUNCTION:    acpi_write_bit_register
  *
- * PARAMETERS:  register_id     - ID of ACPI bit_register to access
- *              return_value    - Value that was read from the register
- *
- * RETURN:      Status and the value read from specified Register. Value
- *              returned is normalized to bit0 (is shifted all the way right)
- *
- * DESCRIPTION: ACPI bit_register read function.
- *
- ******************************************************************************/
-acpi_status acpi_get_register(u32 register_id, u32 *return_value)
-{
-	acpi_status status;
-	acpi_cpu_flags flags;
-
-	flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
-	status = acpi_get_register_unlocked(register_id, return_value);
-	acpi_os_release_lock(acpi_gbl_hardware_lock, flags);
-
-	return (status);
-}
-
-ACPI_EXPORT_SYMBOL(acpi_get_register)
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_set_register
- *
- * PARAMETERS:  register_id     - ID of ACPI bit_register to access
- *              Value           - (only used on write) value to write to the
- *                                Register, NOT pre-normalized to the bit pos
+ * PARAMETERS:  register_id     - ID of ACPI Bit Register to access
+ *              Value           - Value to write to the register, in bit
+ *                                position zero. The bit is automaticallly
+ *                                shifted to the correct position.
  *
  * RETURN:      Status
  *
- * DESCRIPTION: ACPI Bit Register write function.
+ * DESCRIPTION: ACPI Bit Register write function. Acquires the hardware lock
+ *              since most operations require a read/modify/write sequence.
+ *
+ * SUPPORTS:    Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
+ *              PM2 Control.
+ *
+ * Note that at this level, the fact that there may be actually two
+ * hardware registers (A and B - and B may not exist) is abstracted.
  *
  ******************************************************************************/
-acpi_status acpi_set_register(u32 register_id, u32 value)
+acpi_status acpi_write_bit_register(u32 register_id, u32 value)
 {
-	u32 register_value = 0;
 	struct acpi_bit_register_info *bit_reg_info;
-	acpi_status status;
 	acpi_cpu_flags lock_flags;
+	u32 register_value;
+	acpi_status status = AE_OK;
 
-	ACPI_FUNCTION_TRACE_U32(acpi_set_register, register_id);
+	ACPI_FUNCTION_TRACE_U32(acpi_write_bit_register, register_id);
 
 	/* Get the info structure corresponding to the requested ACPI Register */
 
 	bit_reg_info = acpi_hw_get_bit_register_info(register_id);
 	if (!bit_reg_info) {
-		ACPI_ERROR((AE_INFO, "Bad ACPI HW RegisterId: %X",
-			    register_id));
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
 	lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
 
-	/* Always do a register read first so we can insert the new bits  */
-
-	status = acpi_hw_register_read(bit_reg_info->parent_register,
-				       &register_value);
-	if (ACPI_FAILURE(status)) {
-		goto unlock_and_exit;
-	}
-
 	/*
-	 * Decode the Register ID
-	 * Register ID = [Register block ID] | [bit ID]
-	 *
-	 * Check bit ID to fine locate Register offset.
-	 * Check Mask to determine Register offset, and then read-write.
+	 * At this point, we know that the parent register is one of the
+	 * following: PM1 Status, PM1 Enable, PM1 Control, or PM2 Control
 	 */
-	switch (bit_reg_info->parent_register) {
-	case ACPI_REGISTER_PM1_STATUS:
-
+	if (bit_reg_info->parent_register != ACPI_REGISTER_PM1_STATUS) {
 		/*
-		 * Status Registers are different from the rest. Clear by
-		 * writing 1, and writing 0 has no effect. So, the only relevant
-		 * information is the single bit we're interested in, all others should
-		 * be written as 0 so they will be left unchanged.
+		 * 1) Case for PM1 Enable, PM1 Control, and PM2 Control
+		 *
+		 * Perform a register read to preserve the bits that we are not
+		 * interested in
 		 */
-		value = ACPI_REGISTER_PREPARE_BITS(value,
-						   bit_reg_info->bit_position,
-						   bit_reg_info->
-						   access_bit_mask);
-		if (value) {
-			status =
-			    acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
-						   (u16) value);
-			register_value = 0;
-		}
-		break;
-
-	case ACPI_REGISTER_PM1_ENABLE:
-
-		ACPI_REGISTER_INSERT_VALUE(register_value,
-					   bit_reg_info->bit_position,
-					   bit_reg_info->access_bit_mask,
-					   value);
-
-		status = acpi_hw_register_write(ACPI_REGISTER_PM1_ENABLE,
-						(u16) register_value);
-		break;
-
-	case ACPI_REGISTER_PM1_CONTROL:
-
-		/*
-		 * Write the PM1 Control register.
-		 * Note that at this level, the fact that there are actually TWO
-		 * registers (A and B - and B may not exist) is abstracted.
-		 */
-		ACPI_DEBUG_PRINT((ACPI_DB_IO, "PM1 control: Read %X\n",
-				  register_value));
-
-		ACPI_REGISTER_INSERT_VALUE(register_value,
-					   bit_reg_info->bit_position,
-					   bit_reg_info->access_bit_mask,
-					   value);
-
-		status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL,
-						(u16) register_value);
-		break;
-
-	case ACPI_REGISTER_PM2_CONTROL:
-
-		status = acpi_hw_register_read(ACPI_REGISTER_PM2_CONTROL,
+		status = acpi_hw_register_read(bit_reg_info->parent_register,
 					       &register_value);
 		if (ACPI_FAILURE(status)) {
 			goto unlock_and_exit;
 		}
 
-		ACPI_DEBUG_PRINT((ACPI_DB_IO,
-				  "PM2 control: Read %X from %8.8X%8.8X\n",
-				  register_value,
-				  ACPI_FORMAT_UINT64(acpi_gbl_FADT.
-						     xpm2_control_block.
-						     address)));
-
+		/*
+		 * Insert the input bit into the value that was just read
+		 * and write the register
+		 */
 		ACPI_REGISTER_INSERT_VALUE(register_value,
 					   bit_reg_info->bit_position,
 					   bit_reg_info->access_bit_mask,
 					   value);
 
-		ACPI_DEBUG_PRINT((ACPI_DB_IO,
-				  "About to write %4.4X to %8.8X%8.8X\n",
-				  register_value,
-				  ACPI_FORMAT_UINT64(acpi_gbl_FADT.
-						     xpm2_control_block.
-						     address)));
+		status = acpi_hw_register_write(bit_reg_info->parent_register,
+						register_value);
+	} else {
+		/*
+		 * 2) Case for PM1 Status
+		 *
+		 * The Status register is different from the rest. Clear an event
+		 * by writing 1, writing 0 has no effect. So, the only relevant
+		 * information is the single bit we're interested in, all others
+		 * should be written as 0 so they will be left unchanged.
+		 */
+		register_value = ACPI_REGISTER_PREPARE_BITS(value,
+							    bit_reg_info->
+							    bit_position,
+							    bit_reg_info->
+							    access_bit_mask);
 
-		status = acpi_hw_register_write(ACPI_REGISTER_PM2_CONTROL,
-						(u8) (register_value));
-		break;
+		/* No need to write the register if value is all zeros */
 
-	default:
-		break;
+		if (register_value) {
+			status =
+			    acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
+						   register_value);
+		}
 	}
 
-      unlock_and_exit:
+	ACPI_DEBUG_PRINT((ACPI_DB_IO,
+			  "BitReg %X, ParentReg %X, Value %8.8X, Actual %8.8X\n",
+			  register_id, bit_reg_info->parent_register, value,
+			  register_value));
+
+unlock_and_exit:
 
 	acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
-
-	/* Normalize the value that was read */
-
-	ACPI_DEBUG_EXEC(register_value =
-			((register_value & bit_reg_info->access_bit_mask) >>
-			 bit_reg_info->bit_position));
-
-	ACPI_DEBUG_PRINT((ACPI_DB_IO,
-			  "Set bits: %8.8X actual %8.8X register %X\n", value,
-			  register_value, bit_reg_info->parent_register));
 	return_ACPI_STATUS(status);
 }
 
-ACPI_EXPORT_SYMBOL(acpi_set_register)
+ACPI_EXPORT_SYMBOL(acpi_write_bit_register)
 
 /*******************************************************************************
  *
@@ -534,7 +468,7 @@
 
 	/* It must be of type Package */
 
-	else if (ACPI_GET_OBJECT_TYPE(info->return_object) != ACPI_TYPE_PACKAGE) {
+	else if (info->return_object->common.type != ACPI_TYPE_PACKAGE) {
 		ACPI_ERROR((AE_INFO,
 			    "Sleep State return object is not a Package"));
 		status = AE_AML_OPERAND_TYPE;
@@ -555,12 +489,13 @@
 
 	/* The first two elements must both be of type Integer */
 
-	else if ((ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[0])
+	else if (((info->return_object->package.elements[0])->common.type
 		  != ACPI_TYPE_INTEGER) ||
-		 (ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[1])
+		 ((info->return_object->package.elements[1])->common.type
 		  != ACPI_TYPE_INTEGER)) {
 		ACPI_ERROR((AE_INFO,
-			    "Sleep State return package elements are not both Integers (%s, %s)",
+			    "Sleep State return package elements are not both Integers "
+			    "(%s, %s)",
 			    acpi_ut_get_object_type_name(info->return_object->
 							 package.elements[0]),
 			    acpi_ut_get_object_type_name(info->return_object->
diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c
index 88303eb..9c3cdbe 100644
--- a/drivers/acpi/acpica/nsaccess.c
+++ b/drivers/acpi/acpica/nsaccess.c
@@ -118,9 +118,8 @@
 		}
 
 		/*
-		 * Name entered successfully.
-		 * If entry in pre_defined_names[] specifies an
-		 * initial value, create the initial value.
+		 * Name entered successfully. If entry in pre_defined_names[] specifies
+		 * an initial value, create the initial value.
 		 */
 		if (init_val->val) {
 			status = acpi_os_predefined_override(init_val, &val);
@@ -178,9 +177,8 @@
 
 			case ACPI_TYPE_STRING:
 
-				/*
-				 * Build an object around the static string
-				 */
+				/* Build an object around the static string */
+
 				obj_desc->string.length =
 				    (u32) ACPI_STRLEN(val);
 				obj_desc->string.pointer = val;
@@ -234,8 +232,7 @@
 			/* Store pointer to value descriptor in the Node */
 
 			status = acpi_ns_attach_object(new_node, obj_desc,
-						       ACPI_GET_OBJECT_TYPE
-						       (obj_desc));
+						       obj_desc->common.type);
 
 			/* Remove local reference to the object */
 
@@ -315,10 +312,8 @@
 		return_ACPI_STATUS(AE_NO_NAMESPACE);
 	}
 
-	/*
-	 * Get the prefix scope.
-	 * A null scope means use the root scope
-	 */
+	/* Get the prefix scope. A null scope means use the root scope */
+
 	if ((!scope_info) || (!scope_info->scope.node)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 				  "Null scope prefix, using root node (%p)\n",
@@ -338,8 +333,8 @@
 		if (!(flags & ACPI_NS_PREFIX_IS_SCOPE)) {
 			/*
 			 * This node might not be a actual "scope" node (such as a
-			 * Device/Method, etc.)  It could be a Package or other object node.
-			 * Backup up the tree to find the containing scope node.
+			 * Device/Method, etc.)  It could be a Package or other object
+			 * node. Backup up the tree to find the containing scope node.
 			 */
 			while (!acpi_ns_opens_scope(prefix_node->type) &&
 			       prefix_node->type != ACPI_TYPE_ANY) {
@@ -349,7 +344,7 @@
 		}
 	}
 
-	/* Save type   TBD: may be no longer necessary */
+	/* Save type. TBD: may be no longer necessary */
 
 	type_to_check_for = type;
 
@@ -414,6 +409,7 @@
 				/* Name is fully qualified, no search rules apply */
 
 				search_parent_flag = ACPI_NS_NO_UPSEARCH;
+
 				/*
 				 * Point past this prefix to the name segment
 				 * part or the next Parent Prefix
@@ -429,7 +425,8 @@
 					/* Current scope has no parent scope */
 
 					ACPI_ERROR((AE_INFO,
-						    "ACPI path has too many parent prefixes (^) - reached beyond root node"));
+						    "ACPI path has too many parent prefixes (^) "
+						    "- reached beyond root node"));
 					return_ACPI_STATUS(AE_NOT_FOUND);
 				}
 			}
@@ -531,9 +528,9 @@
 	while (num_segments && current_node) {
 		num_segments--;
 		if (!num_segments) {
-			/*
-			 * This is the last segment, enable typechecking
-			 */
+
+			/* This is the last segment, enable typechecking */
+
 			this_search_type = type;
 
 			/*
@@ -584,9 +581,9 @@
 		if (num_segments > 0) {
 			/*
 			 * If we have an alias to an object that opens a scope (such as a
-			 * device or processor), we need to dereference the alias here so that
-			 * we can access any children of the original node (via the remaining
-			 * segments).
+			 * device or processor), we need to dereference the alias here so
+			 * that we can access any children of the original node (via the
+			 * remaining segments).
 			 */
 			if (this_node->type == ACPI_TYPE_LOCAL_ALIAS) {
 				if (!this_node->object) {
@@ -594,8 +591,8 @@
 				}
 
 				if (acpi_ns_opens_scope
-				    (((struct acpi_namespace_node *)this_node->
-				      object)->type)) {
+				    (((struct acpi_namespace_node *)
+				      this_node->object)->type)) {
 					this_node =
 					    (struct acpi_namespace_node *)
 					    this_node->object;
@@ -639,8 +636,8 @@
 
 			/*
 			 * If this is the last name segment and we are not looking for a
-			 * specific type, but the type of found object is known, use that type
-			 * to (later) see if it opens a scope.
+			 * specific type, but the type of found object is known, use that
+			 * type to (later) see if it opens a scope.
 			 */
 			if (type == ACPI_TYPE_ANY) {
 				type = this_node->type;
@@ -653,9 +650,8 @@
 		current_node = this_node;
 	}
 
-	/*
-	 * Always check if we need to open a new scope
-	 */
+	/* Always check if we need to open a new scope */
+
 	if (!(flags & ACPI_NS_DONT_OPEN_SCOPE) && (walk_state)) {
 		/*
 		 * If entry is a type which opens a scope, push the new scope on the
diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c
index f976d84..aceb9311 100644
--- a/drivers/acpi/acpica/nsalloc.c
+++ b/drivers/acpi/acpica/nsalloc.c
@@ -76,8 +76,7 @@
 	ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_allocated++);
 
 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
-	temp =
-	    acpi_gbl_ns_node_list->total_allocated -
+	temp = acpi_gbl_ns_node_list->total_allocated -
 	    acpi_gbl_ns_node_list->total_freed;
 	if (temp > acpi_gbl_ns_node_list->max_occupied) {
 		acpi_gbl_ns_node_list->max_occupied = temp;
@@ -145,9 +144,8 @@
 
 	ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++);
 
-	/*
-	 * Detach an object if there is one, then delete the node
-	 */
+	/* Detach an object if there is one, then delete the node */
+
 	acpi_ns_detach_object(node);
 	(void)acpi_os_release_object(acpi_gbl_namespace_cache, node);
 	return_VOID;
@@ -183,9 +181,8 @@
 	ACPI_FUNCTION_TRACE(ns_install_node);
 
 	/*
-	 * Get the owner ID from the Walk state
-	 * The owner ID is used to track table deletion and
-	 * deletion of objects created by methods
+	 * Get the owner ID from the Walk state. The owner ID is used to track
+	 * table deletion and deletion of objects created by methods.
 	 */
 	if (walk_state) {
 		owner_id = walk_state->owner_id;
@@ -260,9 +257,8 @@
 		return_VOID;
 	}
 
-	/*
-	 * Deallocate all children at this level
-	 */
+	/* Deallocate all children at this level */
+
 	do {
 
 		/* Get the things we need */
@@ -285,9 +281,8 @@
 				  "Object %p, Remaining %X\n", child_node,
 				  acpi_gbl_current_node_count));
 
-		/*
-		 * Detach an object if there is one, then free the child node
-		 */
+		/* Detach an object if there is one, then free the child node */
+
 		acpi_ns_detach_object(child_node);
 
 		/* Now we can delete the node */
@@ -304,7 +299,6 @@
 	/* Clear the parent's child pointer */
 
 	parent_node->child = NULL;
-
 	return_VOID;
 }
 
diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c
index 0da33c8..2bad613 100644
--- a/drivers/acpi/acpica/nsdump.c
+++ b/drivers/acpi/acpica/nsdump.c
@@ -181,6 +181,12 @@
 	}
 
 	this_node = acpi_ns_map_handle_to_node(obj_handle);
+	if (!this_node) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid object handle %p\n",
+				  obj_handle));
+		return (AE_OK);
+	}
+
 	type = this_node->type;
 
 	/* Check if the owner matches */
@@ -214,9 +220,8 @@
 		acpi_os_printf("%4.4s", acpi_ut_get_node_name(this_node));
 	}
 
-	/*
-	 * Now we can print out the pertinent information
-	 */
+	/* Now we can print out the pertinent information */
+
 	acpi_os_printf(" %-12s %p %2.2X ",
 		       acpi_ut_get_type_name(type), this_node,
 		       this_node->owner_id);
@@ -509,7 +514,7 @@
 
 		case ACPI_DESC_TYPE_OPERAND:
 
-			obj_type = ACPI_GET_OBJECT_TYPE(obj_desc);
+			obj_type = obj_desc->common.type;
 
 			if (obj_type > ACPI_TYPE_LOCAL_MAX) {
 				acpi_os_printf
@@ -539,9 +544,8 @@
 			goto cleanup;
 		}
 
-		/*
-		 * Valid object, get the pointer to next level, if any
-		 */
+		/* Valid object, get the pointer to next level, if any */
+
 		switch (obj_type) {
 		case ACPI_TYPE_BUFFER:
 		case ACPI_TYPE_STRING:
@@ -602,14 +606,14 @@
  *              display_type        - 0 or ACPI_DISPLAY_SUMMARY
  *              max_depth           - Maximum depth of dump. Use ACPI_UINT32_MAX
  *                                    for an effectively unlimited depth.
- *              owner_id            - Dump only objects owned by this ID.  Use
+ *              owner_id            - Dump only objects owned by this ID. Use
  *                                    ACPI_UINT32_MAX to match all owners.
  *              start_handle        - Where in namespace to start/end search
  *
  * RETURN:      None
  *
- * DESCRIPTION: Dump typed objects within the loaded namespace.
- *              Uses acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object.
+ * DESCRIPTION: Dump typed objects within the loaded namespace. Uses
+ *              acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object.
  *
  ******************************************************************************/
 
diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c
index 0f3d5f9..8e7dec1 100644
--- a/drivers/acpi/acpica/nseval.c
+++ b/drivers/acpi/acpica/nseval.c
@@ -155,7 +155,7 @@
 		}
 
 
-		ACPI_DUMP_PATHNAME(info->resolved_node, "Execute Method:",
+		ACPI_DUMP_PATHNAME(info->resolved_node, "ACPI: Execute Method",
 				   ACPI_LV_INFO, _COMPONENT);
 
 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c
index 13501cb..2adfcf3 100644
--- a/drivers/acpi/acpica/nsinit.c
+++ b/drivers/acpi/acpica/nsinit.c
@@ -103,7 +103,8 @@
 	}
 
 	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
-			      "\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd Buffers %hd/%hd Packages (%hd nodes)\n",
+			      "\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd "
+			      "Buffers %hd/%hd Packages (%hd nodes)\n",
 			      info.op_region_init, info.op_region_count,
 			      info.field_init, info.field_count,
 			      info.buffer_init, info.buffer_count,
@@ -148,7 +149,8 @@
 	info.num_INI = 0;
 
 	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
-			      "Initializing Device/Processor/Thermal objects by executing _INI methods:"));
+			      "Initializing Device/Processor/Thermal objects "
+			      "by executing _INI methods:"));
 
 	/* Tree analysis: find all subtrees that contain _INI methods */
 
@@ -180,7 +182,8 @@
 	}
 
 	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
-			      "\nExecuted %hd _INI methods requiring %hd _STA executions (examined %hd objects)\n",
+			      "\nExecuted %hd _INI methods requiring %hd _STA executions "
+			      "(examined %hd objects)\n",
 			      info.num_INI, info.num_STA, info.device_count));
 
 	return_ACPI_STATUS(status);
@@ -263,16 +266,14 @@
 		return (AE_OK);
 	}
 
-	/*
-	 * If the object is already initialized, nothing else to do
-	 */
+	/* If the object is already initialized, nothing else to do */
+
 	if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
 		return (AE_OK);
 	}
 
-	/*
-	 * Must lock the interpreter before executing AML code
-	 */
+	/* Must lock the interpreter before executing AML code */
+
 	acpi_ex_enter_interpreter();
 
 	/*
diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c
index a0ba9e1..dcd7a6a 100644
--- a/drivers/acpi/acpica/nsload.c
+++ b/drivers/acpi/acpica/nsload.c
@@ -128,12 +128,12 @@
 	 * parse trees.
 	 */
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-			  "**** Begin Table Method Parsing and Object Initialization ****\n"));
+			  "**** Begin Table Method Parsing and Object Initialization\n"));
 
 	status = acpi_ds_initialize_objects(table_index, node);
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-			  "**** Completed Table Method Parsing and Object Initialization ****\n"));
+			  "**** Completed Table Method Parsing and Object Initialization\n"));
 
 	return_ACPI_STATUS(status);
 }
diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c
index 08a97a5..3eb20bf 100644
--- a/drivers/acpi/acpica/nsobject.c
+++ b/drivers/acpi/acpica/nsobject.c
@@ -209,8 +209,7 @@
 
 	obj_desc = node->object;
 
-	if (!obj_desc ||
-	    (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA)) {
+	if (!obj_desc || (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA)) {
 		return_VOID;
 	}
 
@@ -220,8 +219,7 @@
 	if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_OPERAND) {
 		node->object = obj_desc->common.next_object;
 		if (node->object &&
-		    (ACPI_GET_OBJECT_TYPE(node->object) !=
-		     ACPI_TYPE_LOCAL_DATA)) {
+		    ((node->object)->common.type != ACPI_TYPE_LOCAL_DATA)) {
 			node->object = node->object->common.next_object;
 		}
 	}
@@ -267,7 +265,7 @@
 	    ((ACPI_GET_DESCRIPTOR_TYPE(node->object) != ACPI_DESC_TYPE_OPERAND)
 	     && (ACPI_GET_DESCRIPTOR_TYPE(node->object) !=
 		 ACPI_DESC_TYPE_NAMED))
-	    || (ACPI_GET_OBJECT_TYPE(node->object) == ACPI_TYPE_LOCAL_DATA)) {
+	    || ((node->object)->common.type == ACPI_TYPE_LOCAL_DATA)) {
 		return_PTR(NULL);
 	}
 
@@ -294,9 +292,9 @@
 	ACPI_FUNCTION_TRACE_PTR(ns_get_secondary_object, obj_desc);
 
 	if ((!obj_desc) ||
-	    (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) ||
+	    (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) ||
 	    (!obj_desc->common.next_object) ||
-	    (ACPI_GET_OBJECT_TYPE(obj_desc->common.next_object) ==
+	    ((obj_desc->common.next_object)->common.type ==
 	     ACPI_TYPE_LOCAL_DATA)) {
 		return_PTR(NULL);
 	}
@@ -331,7 +329,7 @@
 	prev_obj_desc = NULL;
 	obj_desc = node->object;
 	while (obj_desc) {
-		if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
+		if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
 		    (obj_desc->data.handler == handler)) {
 			return (AE_ALREADY_EXISTS);
 		}
@@ -385,7 +383,7 @@
 	prev_obj_desc = NULL;
 	obj_desc = node->object;
 	while (obj_desc) {
-		if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
+		if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
 		    (obj_desc->data.handler == handler)) {
 			if (prev_obj_desc) {
 				prev_obj_desc->common.next_object =
@@ -428,7 +426,7 @@
 
 	obj_desc = node->object;
 	while (obj_desc) {
-		if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
+		if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
 		    (obj_desc->data.handler == handler)) {
 			*data = obj_desc->data.pointer;
 			return (AE_OK);
diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c
index b9e8d00..662a4bd 100644
--- a/drivers/acpi/acpica/nsparse.c
+++ b/drivers/acpi/acpica/nsparse.c
@@ -176,9 +176,8 @@
 	 * performs another complete parse of the AML.
 	 */
 	ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n"));
-	status =
-	    acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1, table_index,
-				       start_node);
+	status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1,
+					    table_index, start_node);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
@@ -193,9 +192,8 @@
 	 * parse objects are all cached.
 	 */
 	ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n"));
-	status =
-	    acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2, table_index,
-				       start_node);
+	status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2,
+					    table_index, start_node);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c
index 45270329..d9e8cbc 100644
--- a/drivers/acpi/acpica/nspredef.c
+++ b/drivers/acpi/acpica/nspredef.c
@@ -79,7 +79,9 @@
 static acpi_status
 acpi_ns_check_package_elements(char *pathname,
 			       union acpi_operand_object **elements,
-			       u8 type1, u32 count1, u8 type2, u32 count2);
+			       u8 type1,
+			       u32 count1,
+			       u8 type2, u32 count2, u32 start_index);
 
 static acpi_status
 acpi_ns_check_object_type(char *pathname,
@@ -221,7 +223,7 @@
 
 	/* For returned Package objects, check the type of all sub-objects */
 
-	if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_PACKAGE) {
+	if (return_object->common.type == ACPI_TYPE_PACKAGE) {
 		status =
 		    acpi_ns_check_package(pathname, return_object_ptr,
 					  predefined);
@@ -302,7 +304,8 @@
 		if ((user_param_count != required_params_current) &&
 		    (user_param_count != required_params_old)) {
 			ACPI_WARNING((AE_INFO,
-				      "%s: Parameter count mismatch - caller passed %d, ACPI requires %d",
+				      "%s: Parameter count mismatch - "
+				      "caller passed %d, ACPI requires %d",
 				      pathname, user_param_count,
 				      required_params_current));
 		}
@@ -472,7 +475,7 @@
 							package->ret_info.
 							object_type2,
 							package->ret_info.
-							count2);
+							count2, 0);
 		if (ACPI_FAILURE(status)) {
 			return (status);
 		}
@@ -623,7 +626,7 @@
 								   object_type2,
 								   package->
 								   ret_info.
-								   count2);
+								   count2, 0);
 				if (ACPI_FAILURE(status)) {
 					return (status);
 				}
@@ -672,7 +675,8 @@
 								   object_type1,
 								   sub_package->
 								   package.
-								   count, 0, 0);
+								   count, 0, 0,
+								   0);
 				if (ACPI_FAILURE(status)) {
 					return (status);
 				}
@@ -710,7 +714,8 @@
 								   ret_info.
 								   object_type1,
 								   (expected_count
-								    - 1), 0, 0);
+								    - 1), 0, 0,
+								   1);
 				if (ACPI_FAILURE(status)) {
 					return (status);
 				}
@@ -758,6 +763,7 @@
  *              Count1          - Count for first group
  *              Type2           - Object type for second group
  *              Count2          - Count for second group
+ *              start_index     - Start of the first group of elements
  *
  * RETURN:      Status
  *
@@ -769,7 +775,9 @@
 static acpi_status
 acpi_ns_check_package_elements(char *pathname,
 			       union acpi_operand_object **elements,
-			       u8 type1, u32 count1, u8 type2, u32 count2)
+			       u8 type1,
+			       u32 count1,
+			       u8 type2, u32 count2, u32 start_index)
 {
 	union acpi_operand_object **this_element = elements;
 	acpi_status status;
@@ -782,7 +790,7 @@
 	 */
 	for (i = 0; i < count1; i++) {
 		status = acpi_ns_check_object_type(pathname, this_element,
-						   type1, i);
+						   type1, i + start_index);
 		if (ACPI_FAILURE(status)) {
 			return (status);
 		}
@@ -791,7 +799,8 @@
 
 	for (i = 0; i < count2; i++) {
 		status = acpi_ns_check_object_type(pathname, this_element,
-						   type2, (i + count1));
+						   type2,
+						   (i + count1 + start_index));
 		if (ACPI_FAILURE(status)) {
 			return (status);
 		}
@@ -858,7 +867,7 @@
 	 * from all of the predefined names (including elements of returned
 	 * packages)
 	 */
-	switch (ACPI_GET_OBJECT_TYPE(return_object)) {
+	switch (return_object->common.type) {
 	case ACPI_TYPE_INTEGER:
 		return_btype = ACPI_RTYPE_INTEGER;
 		break;
@@ -901,7 +910,7 @@
 
 	/* For reference objects, check that the reference type is correct */
 
-	if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_LOCAL_REFERENCE) {
+	if (return_object->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
 		status = acpi_ns_check_reference(pathname, return_object);
 	}
 
@@ -974,7 +983,8 @@
 	}
 
 	ACPI_WARNING((AE_INFO,
-		      "%s: Return type mismatch - unexpected reference object type [%s] %2.2X",
+		      "%s: Return type mismatch - "
+		      "unexpected reference object type [%s] %2.2X",
 		      pathname, acpi_ut_get_reference_name(return_object),
 		      return_object->reference.class));
 
@@ -1006,7 +1016,7 @@
 	union acpi_operand_object *new_object;
 	acpi_size length;
 
-	switch (ACPI_GET_OBJECT_TYPE(return_object)) {
+	switch (return_object->common.type) {
 	case ACPI_TYPE_BUFFER:
 
 		if (!(expected_btypes & ACPI_RTYPE_STRING)) {
diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c
index 6fea13f..f9b4f51 100644
--- a/drivers/acpi/acpica/nssearch.c
+++ b/drivers/acpi/acpica/nssearch.c
@@ -167,7 +167,8 @@
 	/* Searched entire namespace level, not found */
 
 	ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
-			  "Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n",
+			  "Name [%4.4s] (%s) not found in search in scope [%4.4s] "
+			  "%p first child %p\n",
 			  ACPI_CAST_PTR(char, &target_name),
 			  acpi_ut_get_type_name(type),
 			  acpi_ut_get_node_name(parent_node), parent_node,
@@ -239,9 +240,8 @@
 			  acpi_ut_get_node_name(parent_node),
 			  ACPI_CAST_PTR(char, &target_name)));
 
-	/*
-	 * Search parents until target is found or we have backed up to the root
-	 */
+	/* Search parents until target is found or we have backed up to the root */
+
 	while (parent_node) {
 		/*
 		 * Search parent scope. Use TYPE_ANY because we don't care about the
@@ -395,9 +395,9 @@
 		return_ACPI_STATUS(AE_NO_MEMORY);
 	}
 #ifdef ACPI_ASL_COMPILER
-	/*
-	 * Node is an object defined by an External() statement
-	 */
+
+	/* Node is an object defined by an External() statement */
+
 	if (flags & ACPI_NS_EXTERNAL) {
 		new_node->flags |= ANOBJ_IS_EXTERNAL;
 	}
diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c
index 3e1149b..78277ed 100644
--- a/drivers/acpi/acpica/nsutils.c
+++ b/drivers/acpi/acpica/nsutils.c
@@ -325,9 +325,8 @@
 			next_external_char++;
 		}
 	} else {
-		/*
-		 * Handle Carat prefixes
-		 */
+		/* Handle Carat prefixes */
+
 		while (*next_external_char == '^') {
 			info->num_carats++;
 			next_external_char++;
@@ -552,9 +551,8 @@
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
 	}
 
-	/*
-	 * Check for a prefix (one '\' | one or more '^').
-	 */
+	/* Check for a prefix (one '\' | one or more '^') */
+
 	switch (internal_name[0]) {
 	case '\\':
 		prefix_length = 1;
@@ -580,7 +578,7 @@
 	}
 
 	/*
-	 * Check for object names.  Note that there could be 0-255 of these
+	 * Check for object names. Note that there could be 0-255 of these
 	 * 4-byte elements.
 	 */
 	if (prefix_length < internal_name_length) {
@@ -637,9 +635,8 @@
 		return_ACPI_STATUS(AE_BAD_PATHNAME);
 	}
 
-	/*
-	 * Build converted_name
-	 */
+	/* Build the converted_name */
+
 	*converted_name = ACPI_ALLOCATE_ZEROED(required_length);
 	if (!(*converted_name)) {
 		return_ACPI_STATUS(AE_NO_MEMORY);
@@ -685,6 +682,9 @@
  *       and keep all pointers within this subsystem - however this introduces
  *       more (and perhaps unnecessary) overhead.
  *
+ * The current implemenation is basically a placeholder until such time comes
+ * that it is needed.
+ *
  ******************************************************************************/
 
 struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle)
@@ -692,9 +692,8 @@
 
 	ACPI_FUNCTION_ENTRY();
 
-	/*
-	 * Simple implementation
-	 */
+	/* Parameter validation */
+
 	if ((!handle) || (handle == ACPI_ROOT_OBJECT)) {
 		return (acpi_gbl_root_node);
 	}
@@ -872,7 +871,7 @@
 				(flags | ACPI_NS_DONT_OPEN_SCOPE), NULL,
 				return_node);
 	if (ACPI_FAILURE(status)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s, %s\n",
+		ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s, %s\n",
 				  pathname, acpi_format_exception(status)));
 	}
 
diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c
index 200895f..83e3aa6 100644
--- a/drivers/acpi/acpica/nswalk.c
+++ b/drivers/acpi/acpica/nswalk.c
@@ -135,8 +135,8 @@
  *              starting (and ending) at the node specified by start_handle.
  *              The user_function is called whenever a node that matches
  *              the type parameter is found.  If the user function returns
- *              a non-zero value, the search is terminated immediately and this
- *              value is returned to the caller.
+ *              a non-zero value, the search is terminated immediately and
+ *              this value is returned to the caller.
  *
  *              The point of this procedure is to provide a generic namespace
  *              walk routine that can be called from multiple places to
@@ -200,10 +200,10 @@
 			/*
 			 * Ignore all temporary namespace nodes (created during control
 			 * method execution) unless told otherwise. These temporary nodes
-			 * can cause a race condition because they can be deleted during the
-			 * execution of the user function (if the namespace is unlocked before
-			 * invocation of the user function.) Only the debugger namespace dump
-			 * will examine the temporary nodes.
+			 * can cause a race condition because they can be deleted during
+			 * the execution of the user function (if the namespace is
+			 * unlocked before invocation of the user function.) Only the
+			 * debugger namespace dump will examine the temporary nodes.
 			 */
 			if ((child_node->flags & ANOBJ_TEMPORARY) &&
 			    !(flags & ACPI_NS_WALK_TEMP_NODES)) {
diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c
index 22a7171..0450540 100644
--- a/drivers/acpi/acpica/nsxfeval.c
+++ b/drivers/acpi/acpica/nsxfeval.c
@@ -387,8 +387,7 @@
 
 	/* We are interested in reference objects only */
 
-	if (ACPI_GET_OBJECT_TYPE(info->return_object) !=
-	    ACPI_TYPE_LOCAL_REFERENCE) {
+	if ((info->return_object)->common.type != ACPI_TYPE_LOCAL_REFERENCE) {
 		return;
 	}
 
@@ -476,21 +475,40 @@
 	}
 
 	/*
-	 * Lock the namespace around the walk.
-	 * The namespace will be unlocked/locked around each call
-	 * to the user function - since this function
-	 * must be allowed to make Acpi calls itself.
+	 * Need to acquire the namespace reader lock to prevent interference
+	 * with any concurrent table unloads (which causes the deletion of
+	 * namespace objects). We cannot allow the deletion of a namespace node
+	 * while the user function is using it. The exception to this are the
+	 * nodes created and deleted during control method execution -- these
+	 * nodes are marked as temporary nodes and are ignored by the namespace
+	 * walk. Thus, control methods can be executed while holding the
+	 * namespace deletion lock (and the user function can execute control
+	 * methods.)
+	 */
+	status = acpi_ut_acquire_read_lock(&acpi_gbl_namespace_rw_lock);
+	if (ACPI_FAILURE(status)) {
+		return status;
+	}
+
+	/*
+	 * Lock the namespace around the walk. The namespace will be
+	 * unlocked/locked around each call to the user function - since the user
+	 * function must be allowed to make ACPICA calls itself (for example, it
+	 * will typically execute control methods during device enumeration.)
 	 */
 	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
 	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
+		goto unlock_and_exit;
 	}
 
 	status = acpi_ns_walk_namespace(type, start_object, max_depth,
-					ACPI_NS_WALK_UNLOCK,
-					user_function, context, return_value);
+					ACPI_NS_WALK_UNLOCK, user_function,
+					context, return_value);
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+
+      unlock_and_exit:
+	(void)acpi_ut_release_read_lock(&acpi_gbl_namespace_rw_lock);
 	return_ACPI_STATUS(status);
 }
 
diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c
index 52865ee..b6667ff 100644
--- a/drivers/acpi/acpica/rscalc.c
+++ b/drivers/acpi/acpica/rscalc.c
@@ -557,9 +557,9 @@
 		     table_index++) {
 			if (*sub_object_list &&	/* Null object allowed */
 			    ((ACPI_TYPE_STRING ==
-			      ACPI_GET_OBJECT_TYPE(*sub_object_list)) ||
+			      (*sub_object_list)->common.type) ||
 			     ((ACPI_TYPE_LOCAL_REFERENCE ==
-			       ACPI_GET_OBJECT_TYPE(*sub_object_list)) &&
+			       (*sub_object_list)->common.type) &&
 			      ((*sub_object_list)->reference.class ==
 			       ACPI_REFCLASS_NAME)))) {
 				name_found = TRUE;
@@ -575,8 +575,7 @@
 		/* Was a String type found? */
 
 		if (name_found) {
-			if (ACPI_GET_OBJECT_TYPE(*sub_object_list) ==
-			    ACPI_TYPE_STRING) {
+			if ((*sub_object_list)->common.type == ACPI_TYPE_STRING) {
 				/*
 				 * The length String.Length field does not include the
 				 * terminating NULL, add 1
diff --git a/drivers/acpi/acpica/rscreate.c b/drivers/acpi/acpica/rscreate.c
index 61566b1..663f692 100644
--- a/drivers/acpi/acpica/rscreate.c
+++ b/drivers/acpi/acpica/rscreate.c
@@ -212,7 +212,7 @@
 
 		/* Each element of the top-level package must also be a package */
 
-		if (ACPI_GET_OBJECT_TYPE(*top_object_list) != ACPI_TYPE_PACKAGE) {
+		if ((*top_object_list)->common.type != ACPI_TYPE_PACKAGE) {
 			ACPI_ERROR((AE_INFO,
 				    "(PRT[%X]) Need sub-package, found %s",
 				    index,
@@ -240,7 +240,7 @@
 		/* 1) First subobject: Dereference the PRT.Address */
 
 		obj_desc = sub_object_list[0];
-		if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
+		if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
 			ACPI_ERROR((AE_INFO,
 				    "(PRT[%X].Address) Need Integer, found %s",
 				    index,
@@ -253,7 +253,7 @@
 		/* 2) Second subobject: Dereference the PRT.Pin */
 
 		obj_desc = sub_object_list[1];
-		if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
+		if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
 			ACPI_ERROR((AE_INFO,
 				    "(PRT[%X].Pin) Need Integer, found %s",
 				    index,
@@ -265,7 +265,7 @@
 		 * If BIOS erroneously reversed the _PRT source_name and source_index,
 		 * then reverse them back.
 		 */
-		if (ACPI_GET_OBJECT_TYPE(sub_object_list[3]) !=
+		if ((sub_object_list[3])->common.type !=
 		    ACPI_TYPE_INTEGER) {
 			if (acpi_gbl_enable_interpreter_slack) {
 				source_name_index = 3;
@@ -291,8 +291,7 @@
 		 * other ACPI implementations.
 		 */
 		obj_desc = sub_object_list[3];
-		if (!obj_desc
-		    || (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) {
+		if (!obj_desc || (obj_desc->common.type != ACPI_TYPE_INTEGER)) {
 			sub_object_list[3] = sub_object_list[2];
 			sub_object_list[2] = obj_desc;
 
@@ -307,7 +306,7 @@
 		 */
 		obj_desc = sub_object_list[source_name_index];
 		if (obj_desc) {
-			switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+			switch (obj_desc->common.type) {
 			case ACPI_TYPE_LOCAL_REFERENCE:
 
 				if (obj_desc->reference.class !=
@@ -380,7 +379,7 @@
 		/* 4) Fourth subobject: Dereference the PRT.source_index */
 
 		obj_desc = sub_object_list[source_index_index];
-		if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
+		if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
 			ACPI_ERROR((AE_INFO,
 				    "(PRT[%X].SourceIndex) Need Integer, found %s",
 				    index,
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c
index 3636e4f..71e655d 100644
--- a/drivers/acpi/acpica/tbfadt.c
+++ b/drivers/acpi/acpica/tbfadt.c
@@ -57,6 +57,8 @@
 
 static void acpi_tb_validate_fadt(void);
 
+static void acpi_tb_setup_fadt_registers(void);
+
 /* Table for conversion of FADT to common internal format and FADT validation */
 
 typedef struct acpi_fadt_info {
@@ -130,7 +132,38 @@
 	 ACPI_FADT_SEPARATE_LENGTH}
 };
 
-#define ACPI_FADT_INFO_ENTRIES        (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info))
+#define ACPI_FADT_INFO_ENTRIES \
+			(sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info))
+
+/* Table used to split Event Blocks into separate status/enable registers */
+
+typedef struct acpi_fadt_pm_info {
+	struct acpi_generic_address *target;
+	u8 source;
+	u8 register_num;
+
+} acpi_fadt_pm_info;
+
+static struct acpi_fadt_pm_info fadt_pm_info_table[] = {
+	{&acpi_gbl_xpm1a_status,
+	 ACPI_FADT_OFFSET(xpm1a_event_block),
+	 0},
+
+	{&acpi_gbl_xpm1a_enable,
+	 ACPI_FADT_OFFSET(xpm1a_event_block),
+	 1},
+
+	{&acpi_gbl_xpm1b_status,
+	 ACPI_FADT_OFFSET(xpm1b_event_block),
+	 0},
+
+	{&acpi_gbl_xpm1b_enable,
+	 ACPI_FADT_OFFSET(xpm1b_event_block),
+	 1}
+};
+
+#define ACPI_FADT_PM_INFO_ENTRIES \
+			(sizeof (fadt_pm_info_table) / sizeof (struct acpi_fadt_pm_info))
 
 /*******************************************************************************
  *
@@ -172,7 +205,6 @@
  * FUNCTION:    acpi_tb_parse_fadt
  *
  * PARAMETERS:  table_index         - Index for the FADT
- *              Flags               - Flags
  *
  * RETURN:      None
  *
@@ -181,7 +213,7 @@
  *
  ******************************************************************************/
 
-void acpi_tb_parse_fadt(u32 table_index, u8 flags)
+void acpi_tb_parse_fadt(u32 table_index)
 {
 	u32 length;
 	struct acpi_table_header *table;
@@ -208,7 +240,7 @@
 	 */
 	(void)acpi_tb_verify_checksum(table, length);
 
-	/* Obtain a local copy of the FADT in common ACPI 2.0+ format */
+	/* Create a local copy of the FADT in common ACPI 2.0+ format */
 
 	acpi_tb_create_local_fadt(table, length);
 
@@ -219,10 +251,10 @@
 	/* Obtain the DSDT and FACS tables via their addresses within the FADT */
 
 	acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt,
-			      flags, ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);
+			      ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);
 
 	acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xfacs,
-			      flags, ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS);
+			      ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS);
 }
 
 /*******************************************************************************
@@ -266,11 +298,17 @@
 	ACPI_MEMCPY(&acpi_gbl_FADT, table,
 		    ACPI_MIN(length, sizeof(struct acpi_table_fadt)));
 
-	/*
-	 * 1) Convert the local copy of the FADT to the common internal format
-	 * 2) Validate some of the important values within the FADT
-	 */
+	/* Convert the local copy of the FADT to the common internal format */
+
 	acpi_tb_convert_fadt();
+
+	/* Validate FADT values now, before we make any changes */
+
+	acpi_tb_validate_fadt();
+
+	/* Initialize the global ACPI register structures */
+
+	acpi_tb_setup_fadt_registers();
 }
 
 /*******************************************************************************
@@ -282,31 +320,35 @@
  * RETURN:      None
  *
  * DESCRIPTION: Converts all versions of the FADT to a common internal format.
- *              Expand all 32-bit addresses to 64-bit.
+ *              Expand 32-bit addresses to 64-bit as necessary.
  *
  * NOTE:        acpi_gbl_FADT must be of size (struct acpi_table_fadt),
  *              and must contain a copy of the actual FADT.
  *
- * ACPICA will use the "X" fields of the FADT for all addresses.
+ * Notes on 64-bit register addresses:
  *
- * "X" fields are optional extensions to the original V1.0 fields. Even if
- * they are present in the structure, they can be optionally not used by
- * setting them to zero. Therefore, we must selectively expand V1.0 fields
- * if the corresponding X field is zero.
+ * After this FADT conversion, later ACPICA code will only use the 64-bit "X"
+ * fields of the FADT for all ACPI register addresses.
  *
- * For ACPI 1.0 FADTs, all address fields are expanded to the corresponding
- * "X" fields.
+ * The 64-bit "X" fields are optional extensions to the original 32-bit FADT
+ * V1.0 fields. Even if they are present in the FADT, they are optional and
+ * are unused if the BIOS sets them to zero. Therefore, we must copy/expand
+ * 32-bit V1.0 fields if the corresponding X field is zero.
  *
- * For ACPI 2.0 FADTs, any "X" fields that are NULL are filled in by
- * expanding the corresponding ACPI 1.0 field.
+ * For ACPI 1.0 FADTs, all 32-bit address fields are expanded to the
+ * corresponding "X" fields in the internal FADT.
+ *
+ * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded
+ * to the corresponding 64-bit X fields. For compatibility with other ACPI
+ * implementations, we ignore the 64-bit field if the 32-bit field is valid,
+ * regardless of whether the host OS is 32-bit or 64-bit.
  *
  ******************************************************************************/
 
 static void acpi_tb_convert_fadt(void)
 {
-	u8 pm1_register_bit_width;
-	u8 pm1_register_byte_width;
-	struct acpi_generic_address *target64;
+	struct acpi_generic_address *address64;
+	u32 address32;
 	u32 i;
 
 	/* Update the local FADT table header length */
@@ -355,35 +397,193 @@
 	 * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
 	 * generic address structures as necessary. Later code will always use
 	 * the 64-bit address structures.
+	 *
+	 * March 2009:
+	 * We now always use the 32-bit address if it is valid (non-null). This
+	 * is not in accordance with the ACPI specification which states that
+	 * the 64-bit address supersedes the 32-bit version, but we do this for
+	 * compatibility with other ACPI implementations. Most notably, in the
+	 * case where both the 32 and 64 versions are non-null, we use the 32-bit
+	 * version. This is the only address that is guaranteed to have been
+	 * tested by the BIOS manufacturer.
 	 */
 	for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
-		target64 =
-		    ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT,
-				 fadt_info_table[i].address64);
+		address32 = *ACPI_ADD_PTR(u32,
+					  &acpi_gbl_FADT,
+					  fadt_info_table[i].address32);
 
-		/* Expand only if the 64-bit X target is null */
+		address64 = ACPI_ADD_PTR(struct acpi_generic_address,
+					 &acpi_gbl_FADT,
+					 fadt_info_table[i].address64);
 
-		if (!target64->address) {
+		/*
+		 * If both 32- and 64-bit addresses are valid (non-zero),
+		 * they must match.
+		 */
+		if (address64->address && address32 &&
+		    (address64->address != (u64) address32)) {
+			ACPI_ERROR((AE_INFO,
+				    "32/64X address mismatch in %s: %8.8X/%8.8X%8.8X, using 32",
+				    fadt_info_table[i].name, address32,
+				    ACPI_FORMAT_UINT64(address64->address)));
+		}
 
-			/* The space_id is always I/O for the 32-bit legacy address fields */
+		/* Always use 32-bit address if it is valid (non-null) */
 
-			acpi_tb_init_generic_address(target64,
+		if (address32) {
+			/*
+			 * Copy the 32-bit address to the 64-bit GAS structure. The
+			 * Space ID is always I/O for 32-bit legacy address fields
+			*/
+			acpi_tb_init_generic_address(address64,
 						     ACPI_ADR_SPACE_SYSTEM_IO,
 						     *ACPI_ADD_PTR(u8,
 								   &acpi_gbl_FADT,
 								   fadt_info_table
 								   [i].length),
-						     (u64) * ACPI_ADD_PTR(u32,
-									  &acpi_gbl_FADT,
-									  fadt_info_table
-									  [i].
-									  address32));
+						     address32);
 		}
 	}
+}
 
-	/* Validate FADT values now, before we make any changes */
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_validate_fadt
+ *
+ * PARAMETERS:  Table           - Pointer to the FADT to be validated
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Validate various important fields within the FADT. If a problem
+ *              is found, issue a message, but no status is returned.
+ *              Used by both the table manager and the disassembler.
+ *
+ * Possible additional checks:
+ * (acpi_gbl_FADT.pm1_event_length >= 4)
+ * (acpi_gbl_FADT.pm1_control_length >= 2)
+ * (acpi_gbl_FADT.pm_timer_length >= 4)
+ * Gpe block lengths must be multiple of 2
+ *
+ ******************************************************************************/
 
-	acpi_tb_validate_fadt();
+static void acpi_tb_validate_fadt(void)
+{
+	char *name;
+	u32 *address32;
+	struct acpi_generic_address *address64;
+	u8 length;
+	u32 i;
+
+	/*
+	 * Check for FACS and DSDT address mismatches. An address mismatch between
+	 * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and
+	 * DSDT/X_DSDT) would indicate the presence of two FACS or two DSDT tables.
+	 */
+	if (acpi_gbl_FADT.facs &&
+	    (acpi_gbl_FADT.Xfacs != (u64) acpi_gbl_FADT.facs)) {
+		ACPI_WARNING((AE_INFO,
+			      "32/64X FACS address mismatch in FADT - "
+			      "%8.8X/%8.8X%8.8X, using 32",
+			      acpi_gbl_FADT.facs,
+			      ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xfacs)));
+
+		acpi_gbl_FADT.Xfacs = (u64) acpi_gbl_FADT.facs;
+	}
+
+	if (acpi_gbl_FADT.dsdt &&
+	    (acpi_gbl_FADT.Xdsdt != (u64) acpi_gbl_FADT.dsdt)) {
+		ACPI_WARNING((AE_INFO,
+			      "32/64X DSDT address mismatch in FADT - "
+			      "%8.8X/%8.8X%8.8X, using 32",
+			      acpi_gbl_FADT.dsdt,
+			      ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xdsdt)));
+
+		acpi_gbl_FADT.Xdsdt = (u64) acpi_gbl_FADT.dsdt;
+	}
+
+	/* Examine all of the 64-bit extended address fields (X fields) */
+
+	for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
+		/*
+		 * Generate pointers to the 32-bit and 64-bit addresses, get the
+		 * register length (width), and the register name
+		 */
+		address64 = ACPI_ADD_PTR(struct acpi_generic_address,
+					 &acpi_gbl_FADT,
+					 fadt_info_table[i].address64);
+		address32 =
+		    ACPI_ADD_PTR(u32, &acpi_gbl_FADT,
+				 fadt_info_table[i].address32);
+		length =
+		    *ACPI_ADD_PTR(u8, &acpi_gbl_FADT,
+				  fadt_info_table[i].length);
+		name = fadt_info_table[i].name;
+
+		/*
+		 * For each extended field, check for length mismatch between the
+		 * legacy length field and the corresponding 64-bit X length field.
+		 */
+		if (address64->address &&
+		    (address64->bit_width != ACPI_MUL_8(length))) {
+			ACPI_WARNING((AE_INFO,
+				      "32/64X length mismatch in %s: %d/%d",
+				      name, ACPI_MUL_8(length),
+				      address64->bit_width));
+		}
+
+		if (fadt_info_table[i].type & ACPI_FADT_REQUIRED) {
+			/*
+			 * Field is required (Pm1a_event, Pm1a_control, pm_timer).
+			 * Both the address and length must be non-zero.
+			 */
+			if (!address64->address || !length) {
+				ACPI_ERROR((AE_INFO,
+					    "Required field %s has zero address and/or length:"
+					    " %8.8X%8.8X/%X",
+					    name,
+					    ACPI_FORMAT_UINT64(address64->
+							       address),
+					    length));
+			}
+		} else if (fadt_info_table[i].type & ACPI_FADT_SEPARATE_LENGTH) {
+			/*
+			 * Field is optional (PM2Control, GPE0, GPE1) AND has its own
+			 * length field. If present, both the address and length must
+			 * be valid.
+			 */
+			if ((address64->address && !length) ||
+			    (!address64->address && length)) {
+				ACPI_WARNING((AE_INFO,
+					      "Optional field %s has zero address or length: "
+					      "%8.8X%8.8X/%X",
+					      name,
+					      ACPI_FORMAT_UINT64(address64->
+								 address),
+					      length));
+			}
+		}
+	}
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_setup_fadt_registers
+ *
+ * PARAMETERS:  None, uses acpi_gbl_FADT.
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Initialize global ACPI PM1 register definitions. Optionally,
+ *              force FADT register definitions to their default lengths.
+ *
+ ******************************************************************************/
+
+static void acpi_tb_setup_fadt_registers(void)
+{
+	struct acpi_generic_address *target64;
+	struct acpi_generic_address *source64;
+	u8 pm1_register_byte_width;
+	u32 i;
 
 	/*
 	 * Optionally check all register lengths against the default values and
@@ -421,190 +621,39 @@
 
 	/*
 	 * Get the length of the individual PM1 registers (enable and status).
-	 * Each register is defined to be (event block length / 2).
+	 * Each register is defined to be (event block length / 2). Extra divide
+	 * by 8 converts bits to bytes.
 	 */
-	pm1_register_bit_width =
-	    (u8)ACPI_DIV_2(acpi_gbl_FADT.xpm1a_event_block.bit_width);
-	pm1_register_byte_width = (u8)ACPI_DIV_8(pm1_register_bit_width);
+	pm1_register_byte_width = (u8)
+	    ACPI_DIV_16(acpi_gbl_FADT.xpm1a_event_block.bit_width);
 
 	/*
-	 * Adjust the lengths of the PM1 Event Blocks so that they can be used to
-	 * access the PM1 status register(s). Use (width / 2)
-	 */
-	acpi_gbl_FADT.xpm1a_event_block.bit_width = pm1_register_bit_width;
-	acpi_gbl_FADT.xpm1b_event_block.bit_width = pm1_register_bit_width;
-
-	/*
-	 * Calculate separate GAS structs for the PM1 Enable registers.
-	 * These addresses do not appear (directly) in the FADT, so it is
-	 * useful to calculate them once, here.
+	 * Calculate separate GAS structs for the PM1x (A/B) Status and Enable
+	 * registers. These addresses do not appear (directly) in the FADT, so it
+	 * is useful to pre-calculate them from the PM1 Event Block definitions.
 	 *
 	 * The PM event blocks are split into two register blocks, first is the
 	 * PM Status Register block, followed immediately by the PM Enable
-	 * Register block. Each is of length (xpm1x_event_block.bit_width/2).
+	 * Register block. Each is of length (pm1_event_length/2)
 	 *
-	 * On various systems the v2 fields (and particularly the bit widths)
-	 * cannot be relied upon, though. Hence resort to using the v1 length
-	 * here (and warn about the inconsistency).
+	 * Note: The PM1A event block is required by the ACPI specification.
+	 * However, the PM1B event block is optional and is rarely, if ever,
+	 * used.
 	 */
-	if (acpi_gbl_FADT.xpm1a_event_block.bit_width
-	    != acpi_gbl_FADT.pm1_event_length * 8)
-		printk(KERN_WARNING "FADT: "
-		       "X_PM1a_EVT_BLK.bit_width (%u) does not match"
-		       " PM1_EVT_LEN (%u)\n",
-		       acpi_gbl_FADT.xpm1a_event_block.bit_width,
-		       acpi_gbl_FADT.pm1_event_length);
 
-	/* The PM1A register block is required */
+	for (i = 0; i < ACPI_FADT_PM_INFO_ENTRIES; i++) {
+		source64 =
+		    ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT,
+				 fadt_pm_info_table[i].source);
 
-	acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable,
-				     acpi_gbl_FADT.xpm1a_event_block.space_id,
-				     pm1_register_byte_width,
-				     (acpi_gbl_FADT.xpm1a_event_block.address +
-				      pm1_register_byte_width));
-	/* Don't forget to copy space_id of the GAS */
-	acpi_gbl_xpm1a_enable.space_id =
-	    acpi_gbl_FADT.xpm1a_event_block.space_id;
-
-	/* The PM1B register block is optional, ignore if not present */
-
-	if (acpi_gbl_FADT.xpm1b_event_block.address) {
-		if (acpi_gbl_FADT.xpm1b_event_block.bit_width
-		    != acpi_gbl_FADT.pm1_event_length * 8)
-			printk(KERN_WARNING "FADT: "
-			       "X_PM1b_EVT_BLK.bit_width (%u) does not match"
-			       " PM1_EVT_LEN (%u)\n",
-			       acpi_gbl_FADT.xpm1b_event_block.bit_width,
-			       acpi_gbl_FADT.pm1_event_length);
-		acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable,
-					     acpi_gbl_FADT.xpm1b_event_block.space_id,
-					     pm1_register_byte_width,
-					     (acpi_gbl_FADT.xpm1b_event_block.
-					      address + pm1_register_byte_width));
-		/* Don't forget to copy space_id of the GAS */
-		acpi_gbl_xpm1b_enable.space_id =
-		    acpi_gbl_FADT.xpm1b_event_block.space_id;
-
-	}
-}
-
-/******************************************************************************
- *
- * FUNCTION:    acpi_tb_validate_fadt
- *
- * PARAMETERS:  Table           - Pointer to the FADT to be validated
- *
- * RETURN:      None
- *
- * DESCRIPTION: Validate various important fields within the FADT. If a problem
- *              is found, issue a message, but no status is returned.
- *              Used by both the table manager and the disassembler.
- *
- * Possible additional checks:
- * (acpi_gbl_FADT.pm1_event_length >= 4)
- * (acpi_gbl_FADT.pm1_control_length >= 2)
- * (acpi_gbl_FADT.pm_timer_length >= 4)
- * Gpe block lengths must be multiple of 2
- *
- ******************************************************************************/
-
-static void acpi_tb_validate_fadt(void)
-{
-	char *name;
-	u32 *address32;
-	struct acpi_generic_address *address64;
-	u8 length;
-	u32 i;
-
-	/*
-	 * Check for FACS and DSDT address mismatches. An address mismatch between
-	 * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and
-	 * DSDT/X_DSDT) would indicate the presence of two FACS or two DSDT tables.
-	 */
-	if (acpi_gbl_FADT.facs &&
-	    (acpi_gbl_FADT.Xfacs != (u64) acpi_gbl_FADT.facs)) {
-		ACPI_WARNING((AE_INFO,
-			      "32/64X FACS address mismatch in FADT - "
-			      "two FACS tables! %8.8X/%8.8X%8.8X",
-			      acpi_gbl_FADT.facs,
-			      ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xfacs)));
-	}
-
-	if (acpi_gbl_FADT.dsdt &&
-	    (acpi_gbl_FADT.Xdsdt != (u64) acpi_gbl_FADT.dsdt)) {
-		ACPI_WARNING((AE_INFO,
-			      "32/64X DSDT address mismatch in FADT - "
-			      "two DSDT tables! %8.8X/%8.8X%8.8X",
-			      acpi_gbl_FADT.dsdt,
-			      ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xdsdt)));
-	}
-
-	/* Examine all of the 64-bit extended address fields (X fields) */
-
-	for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
-		/*
-		 * Generate pointers to the 32-bit and 64-bit addresses, get the
-		 * register length (width), and the register name
-		 */
-		address64 = ACPI_ADD_PTR(struct acpi_generic_address,
-					 &acpi_gbl_FADT,
-					 fadt_info_table[i].address64);
-		address32 =
-		    ACPI_ADD_PTR(u32, &acpi_gbl_FADT,
-				 fadt_info_table[i].address32);
-		length =
-		    *ACPI_ADD_PTR(u8, &acpi_gbl_FADT,
-				  fadt_info_table[i].length);
-		name = fadt_info_table[i].name;
-
-		/*
-		 * For each extended field, check for length mismatch between the
-		 * legacy length field and the corresponding 64-bit X length field.
-		 */
-		if (address64 && (address64->bit_width != ACPI_MUL_8(length))) {
-			ACPI_WARNING((AE_INFO,
-				      "32/64X length mismatch in %s: %d/%d",
-				      name, ACPI_MUL_8(length),
-				      address64->bit_width));
-		}
-
-		if (fadt_info_table[i].type & ACPI_FADT_REQUIRED) {
-			/*
-			 * Field is required (Pm1a_event, Pm1a_control, pm_timer).
-			 * Both the address and length must be non-zero.
-			 */
-			if (!address64->address || !length) {
-				ACPI_ERROR((AE_INFO,
-					    "Required field %s has zero address and/or length: %8.8X%8.8X/%X",
-					    name,
-					    ACPI_FORMAT_UINT64(address64->
-							       address),
-					    length));
-			}
-		} else if (fadt_info_table[i].type & ACPI_FADT_SEPARATE_LENGTH) {
-			/*
-			 * Field is optional (PM2Control, GPE0, GPE1) AND has its own
-			 * length field. If present, both the address and length must be valid.
-			 */
-			if ((address64->address && !length)
-			    || (!address64->address && length)) {
-				ACPI_WARNING((AE_INFO,
-					      "Optional field %s has zero address or length: %8.8X%8.8X/%X",
-					      name,
-					      ACPI_FORMAT_UINT64(address64->
-								 address),
-					      length));
-			}
-		}
-
-		/* If both 32- and 64-bit addresses are valid (non-zero), they must match */
-
-		if (address64->address && *address32 &&
-		    (address64->address != (u64) * address32)) {
-			ACPI_ERROR((AE_INFO,
-				    "32/64X address mismatch in %s: %8.8X/%8.8X%8.8X, using 64X",
-				    name, *address32,
-				    ACPI_FORMAT_UINT64(address64->address)));
+		if (source64->address) {
+			acpi_tb_init_generic_address(fadt_pm_info_table[i].
+						     target, source64->space_id,
+						     pm1_register_byte_width,
+						     source64->address +
+						     (fadt_pm_info_table[i].
+						      register_num *
+						      pm1_register_byte_width));
 		}
 	}
 }
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index 37374b2..f865d5a 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -103,7 +103,9 @@
  *
  * RETURN:      Status
  *
- * DESCRIPTION: This function is called to add the ACPI table
+ * DESCRIPTION: This function is called to add an ACPI table. It is used to
+ *              dynamically load tables via the Load and load_table AML
+ *              operators.
  *
  ******************************************************************************/
 
@@ -112,6 +114,7 @@
 {
 	u32 i;
 	acpi_status status = AE_OK;
+	struct acpi_table_header *override_table = NULL;
 
 	ACPI_FUNCTION_TRACE(tb_add_table);
 
@@ -201,6 +204,29 @@
 		}
 	}
 
+	/*
+	 * ACPI Table Override:
+	 * Allow the host to override dynamically loaded tables.
+	 */
+	status = acpi_os_table_override(table_desc->pointer, &override_table);
+	if (ACPI_SUCCESS(status) && override_table) {
+		ACPI_INFO((AE_INFO,
+			   "%4.4s @ 0x%p Table override, replaced with:",
+			   table_desc->pointer->signature,
+			   ACPI_CAST_PTR(void, table_desc->address)));
+
+		/* We can delete the table that was passed as a parameter */
+
+		acpi_tb_delete_table(table_desc);
+
+		/* Setup descriptor for the new table */
+
+		table_desc->address = ACPI_PTR_TO_PHYSADDR(override_table);
+		table_desc->pointer = override_table;
+		table_desc->length = override_table->length;
+		table_desc->flags = ACPI_TABLE_ORIGIN_OVERRIDE;
+	}
+
 	/* Add the table to the global root table list */
 
 	status = acpi_tb_store_table(table_desc->address, table_desc->pointer,
@@ -247,8 +273,9 @@
 	/* Increase the Table Array size */
 
 	tables = ACPI_ALLOCATE_ZEROED(((acpi_size) acpi_gbl_root_table_list.
-				       size + ACPI_ROOT_TABLE_SIZE_INCREMENT)
-				      * sizeof(struct acpi_table_desc));
+				       size +
+				       ACPI_ROOT_TABLE_SIZE_INCREMENT) *
+				      sizeof(struct acpi_table_desc));
 	if (!tables) {
 		ACPI_ERROR((AE_INFO,
 			    "Could not allocate new root table array"));
@@ -407,27 +434,56 @@
  *
  * PARAMETERS:  table_index         - Table index
  *
- * RETURN:      None
+ * RETURN:      Status
  *
  * DESCRIPTION: Delete all namespace objects created when this table was loaded.
  *
  ******************************************************************************/
 
-void acpi_tb_delete_namespace_by_owner(u32 table_index)
+acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index)
 {
 	acpi_owner_id owner_id;
+	acpi_status status;
 
-	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
-	if (table_index < acpi_gbl_root_table_list.count) {
-		owner_id =
-		    acpi_gbl_root_table_list.tables[table_index].owner_id;
-	} else {
-		(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
-		return;
+	ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner);
+
+	status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
 	}
 
+	if (table_index >= acpi_gbl_root_table_list.count) {
+
+		/* The table index does not exist */
+
+		(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+		return_ACPI_STATUS(AE_NOT_EXIST);
+	}
+
+	/* Get the owner ID for this table, used to delete namespace nodes */
+
+	owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id;
 	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+
+	/*
+	 * Need to acquire the namespace writer lock to prevent interference
+	 * with any concurrent namespace walks. The interpreter must be
+	 * released during the deletion since the acquisition of the deletion
+	 * lock may block, and also since the execution of a namespace walk
+	 * must be allowed to use the interpreter.
+	 */
+	acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
+	status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock);
+
 	acpi_ns_delete_namespace_by_owner(owner_id);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock);
+
+	status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
+	return_ACPI_STATUS(status);
 }
 
 /*******************************************************************************
@@ -535,8 +591,8 @@
 	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 	if (table_index < acpi_gbl_root_table_list.count) {
 		is_loaded = (u8)
-		    (acpi_gbl_root_table_list.tables[table_index].
-		     flags & ACPI_TABLE_IS_LOADED);
+		    (acpi_gbl_root_table_list.tables[table_index].flags &
+		     ACPI_TABLE_IS_LOADED);
 	}
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c
index 22ce4898..ef7d2c2 100644
--- a/drivers/acpi/acpica/tbutils.c
+++ b/drivers/acpi/acpica/tbutils.c
@@ -177,19 +177,23 @@
 			   struct acpi_table_header *header)
 {
 
+	/*
+	 * The reason that the Address is cast to a void pointer is so that we
+	 * can use %p which will work properly on both 32-bit and 64-bit hosts.
+	 */
 	if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) {
 
-		/* FACS only has signature and length fields of common table header */
+		/* FACS only has signature and length fields */
 
-		ACPI_INFO((AE_INFO, "%4.4s %08lX, %04X",
-			   header->signature, (unsigned long)address,
+		ACPI_INFO((AE_INFO, "%4.4s %p %05X",
+			   header->signature, ACPI_CAST_PTR(void, address),
 			   header->length));
 	} else if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_RSDP)) {
 
 		/* RSDP has no common fields */
 
-		ACPI_INFO((AE_INFO, "RSDP %08lX, %04X (r%d %6.6s)",
-			   (unsigned long)address,
+		ACPI_INFO((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)",
+			   ACPI_CAST_PTR (void, address),
 			   (ACPI_CAST_PTR(struct acpi_table_rsdp, header)->
 			    revision >
 			    0) ? ACPI_CAST_PTR(struct acpi_table_rsdp,
@@ -202,8 +206,8 @@
 		/* Standard ACPI table with full common header */
 
 		ACPI_INFO((AE_INFO,
-			   "%4.4s %08lX, %04X (r%d %6.6s %8.8s %8X %4.4s %8X)",
-			   header->signature, (unsigned long)address,
+			   "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)",
+			   header->signature, ACPI_CAST_PTR (void, address),
 			   header->length, header->revision, header->oem_id,
 			   header->oem_table_id, header->oem_revision,
 			   header->asl_compiler_id,
@@ -280,22 +284,28 @@
  * FUNCTION:    acpi_tb_install_table
  *
  * PARAMETERS:  Address                 - Physical address of DSDT or FACS
- *              Flags                   - Flags
  *              Signature               - Table signature, NULL if no need to
  *                                        match
  *              table_index             - Index into root table array
  *
  * RETURN:      None
  *
- * DESCRIPTION: Install an ACPI table into the global data structure.
+ * DESCRIPTION: Install an ACPI table into the global data structure. The
+ *              table override mechanism is implemented here to allow the host
+ *              OS to replace any table before it is installed in the root
+ *              table array.
  *
  ******************************************************************************/
 
 void
 acpi_tb_install_table(acpi_physical_address address,
-		      u8 flags, char *signature, u32 table_index)
+		      char *signature, u32 table_index)
 {
-	struct acpi_table_header *table;
+	u8 flags;
+	acpi_status status;
+	struct acpi_table_header *table_to_install;
+	struct acpi_table_header *mapped_table;
+	struct acpi_table_header *override_table = NULL;
 
 	if (!address) {
 		ACPI_ERROR((AE_INFO,
@@ -306,41 +316,69 @@
 
 	/* Map just the table header */
 
-	table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
-	if (!table) {
+	mapped_table =
+	    acpi_os_map_memory(address, sizeof(struct acpi_table_header));
+	if (!mapped_table) {
 		return;
 	}
 
-	/* If a particular signature is expected, signature must match */
+	/* If a particular signature is expected (DSDT/FACS), it must match */
 
-	if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) {
+	if (signature && !ACPI_COMPARE_NAME(mapped_table->signature, signature)) {
 		ACPI_ERROR((AE_INFO,
-			    "Invalid signature 0x%X for ACPI table [%s]",
-			    *ACPI_CAST_PTR(u32, table->signature), signature));
+			    "Invalid signature 0x%X for ACPI table, expected [%s]",
+			    *ACPI_CAST_PTR(u32, mapped_table->signature),
+			    signature));
 		goto unmap_and_exit;
 	}
 
+	/*
+	 * ACPI Table Override:
+	 *
+	 * Before we install the table, let the host OS override it with a new
+	 * one if desired. Any table within the RSDT/XSDT can be replaced,
+	 * including the DSDT which is pointed to by the FADT.
+	 */
+	status = acpi_os_table_override(mapped_table, &override_table);
+	if (ACPI_SUCCESS(status) && override_table) {
+		ACPI_INFO((AE_INFO,
+			   "%4.4s @ 0x%p Table override, replaced with:",
+			   mapped_table->signature, ACPI_CAST_PTR(void,
+								  address)));
+
+		acpi_gbl_root_table_list.tables[table_index].pointer =
+		    override_table;
+		address = ACPI_PTR_TO_PHYSADDR(override_table);
+
+		table_to_install = override_table;
+		flags = ACPI_TABLE_ORIGIN_OVERRIDE;
+	} else {
+		table_to_install = mapped_table;
+		flags = ACPI_TABLE_ORIGIN_MAPPED;
+	}
+
 	/* Initialize the table entry */
 
 	acpi_gbl_root_table_list.tables[table_index].address = address;
-	acpi_gbl_root_table_list.tables[table_index].length = table->length;
+	acpi_gbl_root_table_list.tables[table_index].length =
+	    table_to_install->length;
 	acpi_gbl_root_table_list.tables[table_index].flags = flags;
 
 	ACPI_MOVE_32_TO_32(&
 			   (acpi_gbl_root_table_list.tables[table_index].
-			    signature), table->signature);
+			    signature), table_to_install->signature);
 
-	acpi_tb_print_table_header(address, table);
+	acpi_tb_print_table_header(address, table_to_install);
 
 	if (table_index == ACPI_TABLE_INDEX_DSDT) {
 
 		/* Global integer width is based upon revision of the DSDT */
 
-		acpi_ut_set_integer_width(table->revision);
+		acpi_ut_set_integer_width(table_to_install->revision);
 	}
 
       unmap_and_exit:
-	acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
+	acpi_os_unmap_memory(mapped_table, sizeof(struct acpi_table_header));
 }
 
 /*******************************************************************************
@@ -379,7 +417,8 @@
 	} else {
 		/*
 		 * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return
-		 * 64-bit platform, XSDT: Move (unaligned) 64-bit to local, return 64-bit
+		 * 64-bit platform, XSDT: Move (unaligned) 64-bit to local,
+		 *  return 64-bit
 		 */
 		ACPI_MOVE_64_TO_64(&address64, table_entry);
 
@@ -389,7 +428,8 @@
 			/* Will truncate 64-bit address to 32 bits, issue warning */
 
 			ACPI_WARNING((AE_INFO,
-				      "64-bit Physical Address in XSDT is too large (%8.8X%8.8X), truncating",
+				      "64-bit Physical Address in XSDT is too large (%8.8X%8.8X),"
+				      " truncating",
 				      ACPI_FORMAT_UINT64(address64)));
 		}
 #endif
@@ -402,7 +442,6 @@
  * FUNCTION:    acpi_tb_parse_root_table
  *
  * PARAMETERS:  Rsdp                    - Pointer to the RSDP
- *              Flags                   - Flags
  *
  * RETURN:      Status
  *
@@ -416,7 +455,7 @@
  ******************************************************************************/
 
 acpi_status __init
-acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
+acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
 {
 	struct acpi_table_rsdp *rsdp;
 	u32 table_entry_size;
@@ -513,13 +552,12 @@
 
 	/* Calculate the number of tables described in the root table */
 
-	table_count =
-	    (u32) ((table->length -
-		    sizeof(struct acpi_table_header)) / table_entry_size);
-
+	table_count = (u32)((table->length - sizeof(struct acpi_table_header)) /
+			    table_entry_size);
 	/*
-	 * First two entries in the table array are reserved for the DSDT and FACS,
-	 * which are not actually present in the RSDT/XSDT - they come from the FADT
+	 * First two entries in the table array are reserved for the DSDT
+	 * and FACS, which are not actually present in the RSDT/XSDT - they
+	 * come from the FADT
 	 */
 	table_entry =
 	    ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header);
@@ -567,14 +605,14 @@
 	 */
 	for (i = 2; i < acpi_gbl_root_table_list.count; i++) {
 		acpi_tb_install_table(acpi_gbl_root_table_list.tables[i].
-				      address, flags, NULL, i);
+				      address, NULL, i);
 
 		/* Special case for FADT - get the DSDT and FACS */
 
 		if (ACPI_COMPARE_NAME
 		    (&acpi_gbl_root_table_list.tables[i].signature,
 		     ACPI_SIG_FADT)) {
-			acpi_tb_parse_fadt(i, flags);
+			acpi_tb_parse_fadt(i);
 		}
 	}
 
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
index ab0aff3..a88f02b 100644
--- a/drivers/acpi/acpica/tbxface.c
+++ b/drivers/acpi/acpica/tbxface.c
@@ -150,8 +150,7 @@
 	 * Root Table Array. This array contains the information of the RSDT/XSDT
 	 * in a common, more useable format.
 	 */
-	status =
-	    acpi_tb_parse_root_table(rsdp_address, ACPI_TABLE_ORIGIN_MAPPED);
+	status = acpi_tb_parse_root_table(rsdp_address);
 	return_ACPI_STATUS(status);
 }
 
@@ -247,7 +246,7 @@
 
 ACPI_EXPORT_SYMBOL(acpi_load_table)
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_get_table_header
  *
@@ -262,7 +261,7 @@
  * NOTE:        Caller is responsible in unmapping the header with
  *              acpi_os_unmap_memory
  *
- *****************************************************************************/
+ ******************************************************************************/
 acpi_status
 acpi_get_table_header(char *signature,
 		      u32 instance, struct acpi_table_header *out_table_header)
@@ -277,9 +276,8 @@
 		return (AE_BAD_PARAMETER);
 	}
 
-	/*
-	 * Walk the root table list
-	 */
+	/* Walk the root table list */
+
 	for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) {
 		if (!ACPI_COMPARE_NAME
 		    (&(acpi_gbl_root_table_list.tables[i].signature),
@@ -292,8 +290,8 @@
 		}
 
 		if (!acpi_gbl_root_table_list.tables[i].pointer) {
-			if ((acpi_gbl_root_table_list.tables[i].
-			     flags & ACPI_TABLE_ORIGIN_MASK) ==
+			if ((acpi_gbl_root_table_list.tables[i].flags &
+			     ACPI_TABLE_ORIGIN_MASK) ==
 			    ACPI_TABLE_ORIGIN_MAPPED) {
 				header =
 				    acpi_os_map_memory(acpi_gbl_root_table_list.
@@ -324,7 +322,7 @@
 
 ACPI_EXPORT_SYMBOL(acpi_get_table_header)
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_unload_table_id
  *
@@ -375,7 +373,7 @@
  *
  * DESCRIPTION: Finds and verifies an ACPI table.
  *
- *****************************************************************************/
+ ******************************************************************************/
 acpi_status
 acpi_get_table_with_size(char *signature,
 	       u32 instance, struct acpi_table_header **out_table,
@@ -391,9 +389,8 @@
 		return (AE_BAD_PARAMETER);
 	}
 
-	/*
-	 * Walk the root table list
-	 */
+	/* Walk the root table list */
+
 	for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) {
 		if (!ACPI_COMPARE_NAME
 		    (&(acpi_gbl_root_table_list.tables[i].signature),
@@ -502,7 +499,6 @@
 static acpi_status acpi_tb_load_namespace(void)
 {
 	acpi_status status;
-	struct acpi_table_header *table;
 	u32 i;
 
 	ACPI_FUNCTION_TRACE(tb_load_namespace);
@@ -526,58 +522,28 @@
 		goto unlock_and_exit;
 	}
 
-	/*
-	 * Find DSDT table
-	 */
-	status =
-	    acpi_os_table_override(acpi_gbl_root_table_list.
-				   tables[ACPI_TABLE_INDEX_DSDT].pointer,
-				   &table);
-	if (ACPI_SUCCESS(status) && table) {
-		/*
-		 * DSDT table has been found
-		 */
-		acpi_tb_delete_table(&acpi_gbl_root_table_list.
-				     tables[ACPI_TABLE_INDEX_DSDT]);
-		acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer =
-		    table;
-		acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length =
-		    table->length;
-		acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags =
-		    ACPI_TABLE_ORIGIN_UNKNOWN;
-
-		ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS"));
-		acpi_tb_print_table_header(0, table);
-
-		if (no_auto_ssdt == 0) {
-			printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"\n");
-		}
-	}
+	/* A valid DSDT is required */
 
 	status =
 	    acpi_tb_verify_table(&acpi_gbl_root_table_list.
 				 tables[ACPI_TABLE_INDEX_DSDT]);
 	if (ACPI_FAILURE(status)) {
 
-		/* A valid DSDT is required */
-
 		status = AE_NO_ACPI_TABLES;
 		goto unlock_and_exit;
 	}
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
 
-	/*
-	 * Load and parse tables.
-	 */
+	/* Load and parse tables */
+
 	status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node);
 	if (ACPI_FAILURE(status)) {
 		return_ACPI_STATUS(status);
 	}
 
-	/*
-	 * Load any SSDT or PSDT tables. Note: Loop leaves tables locked
-	 */
+	/* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */
+
 	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 	for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
 		if ((!ACPI_COMPARE_NAME
@@ -630,9 +596,8 @@
 
 	ACPI_FUNCTION_TRACE(acpi_load_tables);
 
-	/*
-	 * Load the namespace from the tables
-	 */
+	/* Load the namespace from the tables */
+
 	status = acpi_tb_load_namespace();
 	if (ACPI_FAILURE(status)) {
 		ACPI_EXCEPTION((AE_INFO, status,
diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c
index b7fc8dd..85ea834 100644
--- a/drivers/acpi/acpica/tbxfroot.c
+++ b/drivers/acpi/acpica/tbxfroot.c
@@ -75,8 +75,8 @@
 	 * Note: Sometimes there exists more than one RSDP in memory; the valid
 	 * RSDP has a valid checksum, all others have an invalid checksum.
 	 */
-	if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP, sizeof(ACPI_SIG_RSDP) - 1)
-	    != 0) {
+	if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP,
+			 sizeof(ACPI_SIG_RSDP) - 1) != 0) {
 
 		/* Nope, BAD Signature */
 
diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c
index b0dcfd3c..919624f 100644
--- a/drivers/acpi/acpica/utcopy.c
+++ b/drivers/acpi/acpica/utcopy.c
@@ -135,11 +135,11 @@
 	 * In general, the external object will be the same type as
 	 * the internal object
 	 */
-	external_object->type = ACPI_GET_OBJECT_TYPE(internal_object);
+	external_object->type = internal_object->common.type;
 
 	/* However, only a limited number of external types are supported */
 
-	switch (ACPI_GET_OBJECT_TYPE(internal_object)) {
+	switch (internal_object->common.type) {
 	case ACPI_TYPE_STRING:
 
 		external_object->string.pointer = (char *)data_space;
@@ -222,8 +222,8 @@
 		 */
 		ACPI_ERROR((AE_INFO,
 			    "Unsupported object type, cannot convert to external object: %s",
-			    acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE
-						  (internal_object))));
+			    acpi_ut_get_type_name(internal_object->common.
+						  type)));
 
 		return_ACPI_STATUS(AE_SUPPORT);
 	}
@@ -355,7 +355,7 @@
 	info.object_space = 0;
 	info.num_packages = 1;
 
-	external_object->type = ACPI_GET_OBJECT_TYPE(internal_object);
+	external_object->type = internal_object->common.type;
 	external_object->package.count = internal_object->package.count;
 	external_object->package.elements = ACPI_CAST_PTR(union acpi_object,
 							  info.free_space);
@@ -399,7 +399,7 @@
 
 	ACPI_FUNCTION_TRACE(ut_copy_iobject_to_eobject);
 
-	if (ACPI_GET_OBJECT_TYPE(internal_object) == ACPI_TYPE_PACKAGE) {
+	if (internal_object->common.type == ACPI_TYPE_PACKAGE) {
 		/*
 		 * Package object:  Copy all subobjects (including
 		 * nested packages)
@@ -496,8 +496,9 @@
 	case ACPI_TYPE_STRING:
 
 		internal_object->string.pointer =
-		    ACPI_ALLOCATE_ZEROED((acpi_size) external_object->string.
-					 length + 1);
+		    ACPI_ALLOCATE_ZEROED((acpi_size)
+					 external_object->string.length + 1);
+
 		if (!internal_object->string.pointer) {
 			goto error_exit;
 		}
@@ -697,7 +698,7 @@
 
 	/* Handle the objects with extra data */
 
-	switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {
+	switch (dest_desc->common.type) {
 	case ACPI_TYPE_BUFFER:
 		/*
 		 * Allocate and copy the actual buffer if and only if:
@@ -814,8 +815,8 @@
 			 * This is a simple object, just copy it
 			 */
 			target_object =
-			    acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE
-							   (source_object));
+			    acpi_ut_create_internal_object(source_object->
+							   common.type);
 			if (!target_object) {
 				return (AE_NO_MEMORY);
 			}
@@ -892,7 +893,7 @@
 
 	ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_ipackage);
 
-	dest_obj->common.type = ACPI_GET_OBJECT_TYPE(source_obj);
+	dest_obj->common.type = source_obj->common.type;
 	dest_obj->common.flags = source_obj->common.flags;
 	dest_obj->package.count = source_obj->package.count;
 
@@ -950,15 +951,14 @@
 
 	/* Create the top level object */
 
-	*dest_desc =
-	    acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE(source_desc));
+	*dest_desc = acpi_ut_create_internal_object(source_desc->common.type);
 	if (!*dest_desc) {
 		return_ACPI_STATUS(AE_NO_MEMORY);
 	}
 
 	/* Copy the object and possible subobjects */
 
-	if (ACPI_GET_OBJECT_TYPE(source_desc) == ACPI_TYPE_PACKAGE) {
+	if (source_desc->common.type == ACPI_TYPE_PACKAGE) {
 		status =
 		    acpi_ut_copy_ipackage_to_ipackage(source_desc, *dest_desc,
 						      walk_state);
diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c
index a0be9e3..a5ee23b 100644
--- a/drivers/acpi/acpica/utdelete.c
+++ b/drivers/acpi/acpica/utdelete.c
@@ -86,7 +86,7 @@
 	 * Must delete or free any pointers within the object that are not
 	 * actual ACPI objects (for example, a raw buffer pointer).
 	 */
-	switch (ACPI_GET_OBJECT_TYPE(object)) {
+	switch (object->common.type) {
 	case ACPI_TYPE_STRING:
 
 		ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
@@ -382,7 +382,7 @@
 					  object, new_count));
 		}
 
-		if (ACPI_GET_OBJECT_TYPE(object) == ACPI_TYPE_METHOD) {
+		if (object->common.type == ACPI_TYPE_METHOD) {
 			ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
 					  "Method Obj %p Refs=%X, [Decremented]\n",
 					  object, new_count));
@@ -469,7 +469,7 @@
 		 * All sub-objects must have their reference count incremented also.
 		 * Different object types have different subobjects.
 		 */
-		switch (ACPI_GET_OBJECT_TYPE(object)) {
+		switch (object->common.type) {
 		case ACPI_TYPE_DEVICE:
 		case ACPI_TYPE_PROCESSOR:
 		case ACPI_TYPE_POWER:
diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c
index 9c9897d..006b16c 100644
--- a/drivers/acpi/acpica/uteval.c
+++ b/drivers/acpi/acpica/uteval.c
@@ -59,26 +59,35 @@
 
 /*
  * Strings supported by the _OSI predefined (internal) method.
+ *
+ * March 2009: Removed "Linux" as this host no longer wants to respond true
+ * for this string. Basically, the only safe OS strings are windows-related
+ * and in many or most cases represent the only test path within the
+ * BIOS-provided ASL code.
+ *
+ * The second element of each entry is used to track the newest version of
+ * Windows that the BIOS has requested.
  */
-static char *acpi_interfaces_supported[] = {
+static struct acpi_interface_info acpi_interfaces_supported[] = {
 	/* Operating System Vendor Strings */
 
-	"Windows 2000",		/* Windows 2000 */
-	"Windows 2001",		/* Windows XP */
-	"Windows 2001 SP1",	/* Windows XP SP1 */
-	"Windows 2001 SP2",	/* Windows XP SP2 */
-	"Windows 2001.1",	/* Windows Server 2003 */
-	"Windows 2001.1 SP1",	/* Windows Server 2003 SP1 - Added 03/2006 */
-	"Windows 2006",		/* Windows Vista - Added 03/2006 */
+	{"Windows 2000", ACPI_OSI_WIN_2000},	/* Windows 2000 */
+	{"Windows 2001", ACPI_OSI_WIN_XP},	/* Windows XP */
+	{"Windows 2001 SP1", ACPI_OSI_WIN_XP_SP1},	/* Windows XP SP1 */
+	{"Windows 2001.1", ACPI_OSI_WINSRV_2003},	/* Windows Server 2003 */
+	{"Windows 2001 SP2", ACPI_OSI_WIN_XP_SP2},	/* Windows XP SP2 */
+	{"Windows 2001.1 SP1", ACPI_OSI_WINSRV_2003_SP1},	/* Windows Server 2003 SP1 - Added 03/2006 */
+	{"Windows 2006", ACPI_OSI_WIN_VISTA},	/* Windows Vista - Added 03/2006 */
 
 	/* Feature Group Strings */
 
-	"Extended Address Space Descriptor"
-	    /*
-	     * All "optional" feature group strings (features that are implemented
-	     * by the host) should be implemented in the host version of
-	     * acpi_os_validate_interface and should not be added here.
-	     */
+	{"Extended Address Space Descriptor", 0}
+
+	/*
+	 * All "optional" feature group strings (features that are implemented
+	 * by the host) should be implemented in the host version of
+	 * acpi_os_validate_interface and should not be added here.
+	 */
 };
 
 /*******************************************************************************
@@ -98,6 +107,7 @@
 	acpi_status status;
 	union acpi_operand_object *string_desc;
 	union acpi_operand_object *return_desc;
+	u32 return_value;
 	u32 i;
 
 	ACPI_FUNCTION_TRACE(ut_osi_implementation);
@@ -116,19 +126,28 @@
 		return_ACPI_STATUS(AE_NO_MEMORY);
 	}
 
-	/* Default return value is 0, NOT-SUPPORTED */
+	/* Default return value is 0, NOT SUPPORTED */
 
-	return_desc->integer.value = 0;
-	walk_state->return_desc = return_desc;
+	return_value = 0;
 
 	/* Compare input string to static table of supported interfaces */
 
 	for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
-		if (!ACPI_STRCMP
-		    (string_desc->string.pointer,
-		     acpi_interfaces_supported[i])) {
-			return_desc->integer.value = ACPI_UINT32_MAX;
-			goto done;
+		if (!ACPI_STRCMP(string_desc->string.pointer,
+				 acpi_interfaces_supported[i].name)) {
+			/*
+			 * The interface is supported.
+			 * Update the osi_data if necessary. We keep track of the latest
+			 * version of Windows that has been requested by the BIOS.
+			 */
+			if (acpi_interfaces_supported[i].value >
+			    acpi_gbl_osi_data) {
+				acpi_gbl_osi_data =
+				    acpi_interfaces_supported[i].value;
+			}
+
+			return_value = ACPI_UINT32_MAX;
+			goto exit;
 		}
 	}
 
@@ -139,15 +158,22 @@
 	 */
 	status = acpi_os_validate_interface(string_desc->string.pointer);
 	if (ACPI_SUCCESS(status)) {
-		return_desc->integer.value = ACPI_UINT32_MAX;
+
+		/* The interface is supported */
+
+		return_value = ACPI_UINT32_MAX;
 	}
 
-done:
-	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, "ACPI: BIOS _OSI(%s) %ssupported\n",
-		string_desc->string.pointer,
-		return_desc->integer.value == 0 ? "not-" : ""));
+exit:
+	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO,
+		"ACPI: BIOS _OSI(%s) is %ssupported\n",
+		string_desc->string.pointer, return_value == 0 ? "not " : ""));
 
-	return_ACPI_STATUS(AE_OK);
+	/* Complete the return value */
+
+	return_desc->integer.value = return_value;
+	walk_state->return_desc = return_desc;
+	return_ACPI_STATUS (AE_OK);
 }
 
 /*******************************************************************************
@@ -167,8 +193,8 @@
 	int i;
 
 	for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
-		if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i])) {
-			*acpi_interfaces_supported[i] = '\0';
+		if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i].name)) {
+			*acpi_interfaces_supported[i].name = '\0';
 			return AE_OK;
 		}
 	}
@@ -248,7 +274,7 @@
 
 	/* Map the return object type to the bitmapped type */
 
-	switch (ACPI_GET_OBJECT_TYPE(info->return_object)) {
+	switch ((info->return_object)->common.type) {
 	case ACPI_TYPE_INTEGER:
 		return_btype = ACPI_BTYPE_INTEGER;
 		break;
@@ -418,7 +444,7 @@
 		return_ACPI_STATUS(status);
 	}
 
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
+	if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
 
 		/* Convert the Numeric HID to string */
 
@@ -459,7 +485,7 @@
 			  struct acpi_compatible_id *one_cid)
 {
 
-	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+	switch (obj_desc->common.type) {
 	case ACPI_TYPE_INTEGER:
 
 		/* Convert the Numeric CID to string */
@@ -527,7 +553,7 @@
 	/* Get the number of _CIDs returned */
 
 	count = 1;
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
+	if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
 		count = obj_desc->package.count;
 	}
 
@@ -555,7 +581,7 @@
 
 	/* The _CID object can be either a single CID or a package (list) of CIDs */
 
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
+	if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
 
 		/* Translate each package element */
 
@@ -620,7 +646,7 @@
 		return_ACPI_STATUS(status);
 	}
 
-	if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
+	if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
 
 		/* Convert the Numeric UID to string */
 
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c
index a3ab9d9..59e46f2 100644
--- a/drivers/acpi/acpica/utglobal.c
+++ b/drivers/acpi/acpica/utglobal.c
@@ -294,12 +294,9 @@
 	/* ACPI_BITREG_GLOBAL_LOCK_RELEASE  */ {ACPI_REGISTER_PM1_CONTROL,
 						ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE,
 						ACPI_BITMASK_GLOBAL_LOCK_RELEASE},
-	/* ACPI_BITREG_SLEEP_TYPE_A         */ {ACPI_REGISTER_PM1_CONTROL,
-						ACPI_BITPOSITION_SLEEP_TYPE_X,
-						ACPI_BITMASK_SLEEP_TYPE_X},
-	/* ACPI_BITREG_SLEEP_TYPE_B         */ {ACPI_REGISTER_PM1_CONTROL,
-						ACPI_BITPOSITION_SLEEP_TYPE_X,
-						ACPI_BITMASK_SLEEP_TYPE_X},
+	/* ACPI_BITREG_SLEEP_TYPE           */ {ACPI_REGISTER_PM1_CONTROL,
+						ACPI_BITPOSITION_SLEEP_TYPE,
+						ACPI_BITMASK_SLEEP_TYPE},
 	/* ACPI_BITREG_SLEEP_ENABLE         */ {ACPI_REGISTER_PM1_CONTROL,
 						ACPI_BITPOSITION_SLEEP_ENABLE,
 						ACPI_BITMASK_SLEEP_ENABLE},
@@ -476,7 +473,7 @@
 		return ("[NULL Object Descriptor]");
 	}
 
-	return (acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE(obj_desc)));
+	return (acpi_ut_get_type_name(obj_desc->common.type));
 }
 
 /*******************************************************************************
@@ -749,7 +746,10 @@
 	for (i = 0; i < ACPI_NUM_OWNERID_MASKS; i++) {
 		acpi_gbl_owner_id_mask[i] = 0;
 	}
-	acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000;	/* Last ID is never valid */
+
+	/* Last owner_iD is never valid */
+
+	acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000;
 
 	/* GPE support */
 
@@ -789,6 +789,7 @@
 	acpi_gbl_trace_dbg_layer = 0;
 	acpi_gbl_debugger_configuration = DEBUGGER_THREADING;
 	acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT;
+	acpi_gbl_osi_data = 0;
 
 	/* Hardware oriented */
 
diff --git a/drivers/acpi/acpica/utlock.c b/drivers/acpi/acpica/utlock.c
new file mode 100644
index 0000000..25e0312
--- /dev/null
+++ b/drivers/acpi/acpica/utlock.c
@@ -0,0 +1,175 @@
+/******************************************************************************
+ *
+ * Module Name: utlock - Reader/Writer lock interfaces
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2009, Intel Corp.
+ * All rights reserved.
+ *
+ * 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,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * 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 MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+
+#define _COMPONENT          ACPI_UTILITIES
+ACPI_MODULE_NAME("utlock")
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_create_rw_lock
+ *              acpi_ut_delete_rw_lock
+ *
+ * PARAMETERS:  Lock                - Pointer to a valid RW lock
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Reader/writer lock creation and deletion interfaces.
+ *
+ ******************************************************************************/
+acpi_status acpi_ut_create_rw_lock(struct acpi_rw_lock *lock)
+{
+	acpi_status status;
+
+	lock->num_readers = 0;
+	status = acpi_os_create_mutex(&lock->reader_mutex);
+	if (ACPI_FAILURE(status)) {
+		return status;
+	}
+
+	status = acpi_os_create_mutex(&lock->writer_mutex);
+	return status;
+}
+
+void acpi_ut_delete_rw_lock(struct acpi_rw_lock *lock)
+{
+
+	acpi_os_delete_mutex(lock->reader_mutex);
+	acpi_os_delete_mutex(lock->writer_mutex);
+
+	lock->num_readers = 0;
+	lock->reader_mutex = NULL;
+	lock->writer_mutex = NULL;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_acquire_read_lock
+ *              acpi_ut_release_read_lock
+ *
+ * PARAMETERS:  Lock                - Pointer to a valid RW lock
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Reader interfaces for reader/writer locks. On acquisition,
+ *              only the first reader acquires the write mutex. On release,
+ *              only the last reader releases the write mutex. Although this
+ *              algorithm can in theory starve writers, this should not be a
+ *              problem with ACPICA since the subsystem is infrequently used
+ *              in comparison to (for example) an I/O system.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ut_acquire_read_lock(struct acpi_rw_lock *lock)
+{
+	acpi_status status;
+
+	status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER);
+	if (ACPI_FAILURE(status)) {
+		return status;
+	}
+
+	/* Acquire the write lock only for the first reader */
+
+	lock->num_readers++;
+	if (lock->num_readers == 1) {
+		status =
+		    acpi_os_acquire_mutex(lock->writer_mutex,
+					  ACPI_WAIT_FOREVER);
+	}
+
+	acpi_os_release_mutex(lock->reader_mutex);
+	return status;
+}
+
+acpi_status acpi_ut_release_read_lock(struct acpi_rw_lock *lock)
+{
+	acpi_status status;
+
+	status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER);
+	if (ACPI_FAILURE(status)) {
+		return status;
+	}
+
+	/* Release the write lock only for the very last reader */
+
+	lock->num_readers--;
+	if (lock->num_readers == 0) {
+		acpi_os_release_mutex(lock->writer_mutex);
+	}
+
+	acpi_os_release_mutex(lock->reader_mutex);
+	return status;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_acquire_write_lock
+ *              acpi_ut_release_write_lock
+ *
+ * PARAMETERS:  Lock                - Pointer to a valid RW lock
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Writer interfaces for reader/writer locks. Simply acquire or
+ *              release the writer mutex associated with the lock. Acquisition
+ *              of the lock is fully exclusive and will block all readers and
+ *              writers until it is released.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ut_acquire_write_lock(struct acpi_rw_lock *lock)
+{
+	acpi_status status;
+
+	status = acpi_os_acquire_mutex(lock->writer_mutex, ACPI_WAIT_FOREVER);
+	return status;
+}
+
+void acpi_ut_release_write_lock(struct acpi_rw_lock *lock)
+{
+
+	acpi_os_release_mutex(lock->writer_mutex);
+}
diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c
index c1f7f4e..1c9e250 100644
--- a/drivers/acpi/acpica/utmisc.c
+++ b/drivers/acpi/acpica/utmisc.c
@@ -938,8 +938,7 @@
 		if ((!this_source_obj) ||
 		    (ACPI_GET_DESCRIPTOR_TYPE(this_source_obj) !=
 		     ACPI_DESC_TYPE_OPERAND)
-		    || (ACPI_GET_OBJECT_TYPE(this_source_obj) !=
-			ACPI_TYPE_PACKAGE)) {
+		    || (this_source_obj->common.type != ACPI_TYPE_PACKAGE)) {
 			status =
 			    walk_callback(ACPI_COPY_TYPE_SIMPLE,
 					  this_source_obj, state, context);
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c
index 14eb52c..26c93a7 100644
--- a/drivers/acpi/acpica/utmutex.c
+++ b/drivers/acpi/acpica/utmutex.c
@@ -60,7 +60,8 @@
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Create the system mutex objects.
+ * DESCRIPTION: Create the system mutex objects. This includes mutexes,
+ *              spin locks, and reader/writer locks.
  *
  ******************************************************************************/
 
@@ -71,9 +72,8 @@
 
 	ACPI_FUNCTION_TRACE(ut_mutex_initialize);
 
-	/*
-	 * Create each of the predefined mutex objects
-	 */
+	/* Create each of the predefined mutex objects */
+
 	for (i = 0; i < ACPI_NUM_MUTEX; i++) {
 		status = acpi_ut_create_mutex(i);
 		if (ACPI_FAILURE(status)) {
@@ -86,6 +86,9 @@
 	spin_lock_init(acpi_gbl_gpe_lock);
 	spin_lock_init(acpi_gbl_hardware_lock);
 
+	/* Create the reader/writer lock for namespace access */
+
+	status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock);
 	return_ACPI_STATUS(status);
 }
 
@@ -97,7 +100,8 @@
  *
  * RETURN:      None.
  *
- * DESCRIPTION: Delete all of the system mutex objects.
+ * DESCRIPTION: Delete all of the system mutex objects. This includes mutexes,
+ *              spin locks, and reader/writer locks.
  *
  ******************************************************************************/
 
@@ -107,9 +111,8 @@
 
 	ACPI_FUNCTION_TRACE(ut_mutex_terminate);
 
-	/*
-	 * Delete each predefined mutex object
-	 */
+	/* Delete each predefined mutex object */
+
 	for (i = 0; i < ACPI_NUM_MUTEX; i++) {
 		(void)acpi_ut_delete_mutex(i);
 	}
@@ -118,6 +121,10 @@
 
 	acpi_os_delete_lock(acpi_gbl_gpe_lock);
 	acpi_os_delete_lock(acpi_gbl_hardware_lock);
+
+	/* Delete the reader/writer lock */
+
+	acpi_ut_delete_rw_lock(&acpi_gbl_namespace_rw_lock);
 	return_VOID;
 }
 
diff --git a/drivers/acpi/acpica/utobject.c b/drivers/acpi/acpica/utobject.c
index fd5ea75..0207b62 100644
--- a/drivers/acpi/acpica/utobject.c
+++ b/drivers/acpi/acpica/utobject.c
@@ -310,7 +310,7 @@
 	/* Check for a null pointer */
 
 	if (!object) {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Null Object Ptr\n"));
+		ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "**** Null Object Ptr\n"));
 		return (FALSE);
 	}
 
@@ -324,7 +324,7 @@
 		return (TRUE);
 
 	default:
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 				  "%p is not not an ACPI operand obj [%s]\n",
 				  object, acpi_ut_get_descriptor_name(object)));
 		break;
@@ -457,7 +457,7 @@
 	 * must be accessed bytewise or there may be alignment problems on
 	 * certain processors
 	 */
-	switch (ACPI_GET_OBJECT_TYPE(internal_object)) {
+	switch (internal_object->common.type) {
 	case ACPI_TYPE_STRING:
 
 		length += (acpi_size) internal_object->string.length + 1;
@@ -518,8 +518,7 @@
 		ACPI_ERROR((AE_INFO, "Cannot convert to external object - "
 			    "unsupported type [%s] %X in object %p",
 			    acpi_ut_get_object_type_name(internal_object),
-			    ACPI_GET_OBJECT_TYPE(internal_object),
-			    internal_object));
+			    internal_object->common.type, internal_object));
 		status = AE_TYPE;
 		break;
 	}
@@ -664,7 +663,7 @@
 
 	if ((ACPI_GET_DESCRIPTOR_TYPE(internal_object) ==
 	     ACPI_DESC_TYPE_OPERAND)
-	    && (ACPI_GET_OBJECT_TYPE(internal_object) == ACPI_TYPE_PACKAGE)) {
+	    && (internal_object->common.type == ACPI_TYPE_PACKAGE)) {
 		status =
 		    acpi_ut_get_package_object_size(internal_object,
 						    obj_length);
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 3bcb5bf..b0de631 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -30,6 +30,7 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/jiffies.h>
+#include <linux/async.h>
 
 #ifdef CONFIG_ACPI_PROCFS_POWER
 #include <linux/proc_fs.h>
@@ -92,7 +93,7 @@
 #endif
 	struct acpi_device *device;
 	unsigned long update_time;
-	int current_now;
+	int rate_now;
 	int capacity_now;
 	int voltage_now;
 	int design_capacity;
@@ -196,7 +197,8 @@
 		val->intval = battery->voltage_now * 1000;
 		break;
 	case POWER_SUPPLY_PROP_CURRENT_NOW:
-		val->intval = battery->current_now * 1000;
+	case POWER_SUPPLY_PROP_POWER_NOW:
+		val->intval = battery->rate_now * 1000;
 		break;
 	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
 	case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
@@ -247,6 +249,7 @@
 	POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
 	POWER_SUPPLY_PROP_CURRENT_NOW,
+	POWER_SUPPLY_PROP_POWER_NOW,
 	POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
 	POWER_SUPPLY_PROP_ENERGY_FULL,
 	POWER_SUPPLY_PROP_ENERGY_NOW,
@@ -273,7 +276,7 @@
 
 static struct acpi_offsets state_offsets[] = {
 	{offsetof(struct acpi_battery, state), 0},
-	{offsetof(struct acpi_battery, current_now), 0},
+	{offsetof(struct acpi_battery, rate_now), 0},
 	{offsetof(struct acpi_battery, capacity_now), 0},
 	{offsetof(struct acpi_battery, voltage_now), 0},
 };
@@ -605,11 +608,11 @@
 	else
 		seq_printf(seq, "charging state:          charged\n");
 
-	if (battery->current_now == ACPI_BATTERY_VALUE_UNKNOWN)
+	if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "present rate:            unknown\n");
 	else
 		seq_printf(seq, "present rate:            %d %s\n",
-			   battery->current_now, acpi_battery_units(battery));
+			   battery->rate_now, acpi_battery_units(battery));
 
 	if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
 		seq_printf(seq, "remaining capacity:      unknown\n");
@@ -740,7 +743,7 @@
 static struct battery_file {
 	struct file_operations ops;
 	mode_t mode;
-	char *name;
+	const char *name;
 } acpi_battery_file[] = {
 	FILE_DESCRIPTION_RO(info),
 	FILE_DESCRIPTION_RO(state),
@@ -900,21 +903,27 @@
 		},
 };
 
-static int __init acpi_battery_init(void)
+static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)
 {
 	if (acpi_disabled)
-		return -ENODEV;
+		return;
 #ifdef CONFIG_ACPI_PROCFS_POWER
 	acpi_battery_dir = acpi_lock_battery_dir();
 	if (!acpi_battery_dir)
-		return -ENODEV;
+		return;
 #endif
 	if (acpi_bus_register_driver(&acpi_battery_driver) < 0) {
 #ifdef CONFIG_ACPI_PROCFS_POWER
 		acpi_unlock_battery_dir(acpi_battery_dir);
 #endif
-		return -ENODEV;
+		return;
 	}
+	return;
+}
+
+static int __init acpi_battery_init(void)
+{
+	async_schedule(acpi_battery_init_async, NULL);
 	return 0;
 }
 
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index bee64b7..e8f7b64 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -39,6 +39,8 @@
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
+#include "internal.h"
+
 #define _COMPONENT		ACPI_BUS_COMPONENT
 ACPI_MODULE_NAME("bus");
 
@@ -846,6 +848,7 @@
 		acpi_kobj = NULL;
 	}
 
+	init_acpi_device_notify();
 	result = acpi_bus_init();
 
 	if (!result) {
@@ -860,11 +863,23 @@
 		}
 	} else
 		disable_acpi();
+
+	if (acpi_disabled)
+		return result;
+
 	/*
 	 * If the laptop falls into the DMI check table, the power state check
 	 * will be disabled in the course of device power transistion.
 	 */
 	dmi_check_system(power_nocheck_dmi_table);
+
+	acpi_scan_init();
+	acpi_ec_init();
+	acpi_power_init();
+	acpi_system_init();
+	acpi_debug_init();
+	acpi_sleep_proc_init();
+	acpi_wakeup_device_init();
 	return result;
 }
 
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index c2f0606..d73c94b 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -78,6 +78,7 @@
 static int acpi_button_add(struct acpi_device *device);
 static int acpi_button_remove(struct acpi_device *device, int type);
 static int acpi_button_resume(struct acpi_device *device);
+static void acpi_button_notify(struct acpi_device *device, u32 event);
 static int acpi_button_info_open_fs(struct inode *inode, struct file *file);
 static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
 
@@ -89,6 +90,7 @@
 		.add = acpi_button_add,
 		.resume = acpi_button_resume,
 		.remove = acpi_button_remove,
+		.notify = acpi_button_notify,
 	},
 };
 
@@ -263,15 +265,18 @@
 	return 0;
 }
 
-static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_button_notify(struct acpi_device *device, u32 event)
 {
-	struct acpi_button *button = data;
+	struct acpi_button *button = acpi_driver_data(device);
 	struct input_dev *input;
 
 	if (!button || !button->device)
 		return;
 
 	switch (event) {
+	case ACPI_FIXED_HARDWARE_EVENT:
+		event = ACPI_BUTTON_NOTIFY_STATUS;
+		/* fall through */
 	case ACPI_BUTTON_NOTIFY_STATUS:
 		input = button->input;
 		if (button->type == ACPI_BUTTON_TYPE_LID) {
@@ -298,46 +303,6 @@
 	return;
 }
 
-static acpi_status acpi_button_notify_fixed(void *data)
-{
-	struct acpi_button *button = data;
-
-	if (!button)
-		return AE_BAD_PARAMETER;
-
-	acpi_button_notify(button->device->handle, ACPI_BUTTON_NOTIFY_STATUS, button);
-
-	return AE_OK;
-}
-
-static int acpi_button_install_notify_handlers(struct acpi_button *button)
-{
-	acpi_status status;
-
-	switch (button->type) {
-	case ACPI_BUTTON_TYPE_POWERF:
-		status =
-		    acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
-						     acpi_button_notify_fixed,
-						     button);
-		break;
-	case ACPI_BUTTON_TYPE_SLEEPF:
-		status =
-		    acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
-						     acpi_button_notify_fixed,
-						     button);
-		break;
-	default:
-		status = acpi_install_notify_handler(button->device->handle,
-						     ACPI_DEVICE_NOTIFY,
-						     acpi_button_notify,
-						     button);
-		break;
-	}
-
-	return ACPI_FAILURE(status) ? -ENODEV : 0;
-}
-
 static int acpi_button_resume(struct acpi_device *device)
 {
 	struct acpi_button *button;
@@ -349,25 +314,6 @@
 	return 0;
 }
 
-static void acpi_button_remove_notify_handlers(struct acpi_button *button)
-{
-	switch (button->type) {
-	case ACPI_BUTTON_TYPE_POWERF:
-		acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
-						acpi_button_notify_fixed);
-		break;
-	case ACPI_BUTTON_TYPE_SLEEPF:
-		acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
-						acpi_button_notify_fixed);
-		break;
-	default:
-		acpi_remove_notify_handler(button->device->handle,
-					   ACPI_DEVICE_NOTIFY,
-					   acpi_button_notify);
-		break;
-	}
-}
-
 static int acpi_button_add(struct acpi_device *device)
 {
 	int error;
@@ -432,10 +378,6 @@
 	if (error)
 		goto err_free_input;
 
-	error = acpi_button_install_notify_handlers(button);
-	if (error)
-		goto err_remove_fs;
-
 	snprintf(button->phys, sizeof(button->phys),
 		 "%s/button/input0", acpi_device_hid(device));
 
@@ -466,7 +408,7 @@
 
 	error = input_register_device(input);
 	if (error)
-		goto err_remove_handlers;
+		goto err_remove_fs;
 	if (button->type == ACPI_BUTTON_TYPE_LID)
 		acpi_lid_send_state(button);
 
@@ -485,8 +427,6 @@
 
 	return 0;
 
- err_remove_handlers:
-	acpi_button_remove_notify_handlers(button);
  err_remove_fs:
 	acpi_button_remove_fs(device);
  err_free_input:
@@ -505,7 +445,6 @@
 
 	button = acpi_driver_data(device);
 
-	acpi_button_remove_notify_handlers(button);
 	acpi_button_remove_fs(device);
 	input_unregister_device(button->input);
 	kfree(button);
diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c
index 20223cb..a8287be 100644
--- a/drivers/acpi/debug.c
+++ b/drivers/acpi/debug.c
@@ -13,11 +13,6 @@
 #define _COMPONENT		ACPI_SYSTEM_COMPONENT
 ACPI_MODULE_NAME("debug");
 
-#ifdef MODULE_PARAM_PREFIX
-#undef MODULE_PARAM_PREFIX
-#endif
-#define MODULE_PARAM_PREFIX "acpi."
-
 struct acpi_dlayer {
 	const char *name;
 	unsigned long value;
@@ -297,17 +292,15 @@
 
 	return count;
 }
+#endif
 
-static int __init acpi_debug_init(void)
+int __init acpi_debug_init(void)
 {
+#ifdef CONFIG_ACPI_PROCFS
 	struct proc_dir_entry *entry;
 	int error = 0;
 	char *name;
 
-
-	if (acpi_disabled)
-		return 0;
-
 	/* 'debug_layer' [R/W] */
 	name = ACPI_SYSTEM_FILE_DEBUG_LAYER;
 	entry =
@@ -338,7 +331,7 @@
 	remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LAYER, acpi_root_dir);
 	error = -ENODEV;
 	goto Done;
-}
-
-subsys_initcall(acpi_debug_init);
+#else
+	return 0;
 #endif
+}
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 7af7db1..efb959d 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -1146,9 +1146,10 @@
 static void __exit dock_exit(void)
 {
 	struct dock_station *dock_station;
+	struct dock_station *tmp;
 
 	unregister_acpi_bus_notifier(&dock_acpi_notifier);
-	list_for_each_entry(dock_station, &dock_stations, sibiling)
+	list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibiling)
 		dock_remove(dock_station);
 }
 
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 2fe1506..04e9044 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -67,7 +67,7 @@
 
 #define ACPI_EC_DELAY		500	/* Wait 500ms max. during EC ops */
 #define ACPI_EC_UDELAY_GLK	1000	/* Wait 1ms max. to get global lock */
-#define ACPI_EC_UDELAY		100	/* Wait 100us before polling EC again */
+#define ACPI_EC_CDELAY		10	/* Wait 10us before polling EC */
 
 #define ACPI_EC_STORM_THRESHOLD 8	/* number of false interrupts
 					   per one transaction */
@@ -236,13 +236,23 @@
 	return 0;
 }
 
+static void ec_delay(void)
+{
+	/* EC in MSI notebooks don't tolerate delays other than 550 usec */
+	if (EC_FLAGS_MSI)
+		udelay(ACPI_EC_DELAY);
+	else
+		/* Use shortest sleep available */
+		msleep(1);
+}
+
 static int ec_poll(struct acpi_ec *ec)
 {
 	unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
-	udelay(ACPI_EC_UDELAY);
+	udelay(ACPI_EC_CDELAY);
 	while (time_before(jiffies, delay)) {
 		gpe_transaction(ec, acpi_ec_read_status(ec));
-		udelay(ACPI_EC_UDELAY);
+		ec_delay();
 		if (ec_transaction_done(ec))
 			return 0;
 	}
@@ -672,7 +682,7 @@
 	return single_open(file, acpi_ec_read_info, PDE(inode)->data);
 }
 
-static struct file_operations acpi_ec_info_ops = {
+static const struct file_operations acpi_ec_info_ops = {
 	.open = acpi_ec_info_open_fs,
 	.read = seq_read,
 	.llseek = seq_lseek,
@@ -755,6 +765,10 @@
 	unsigned long long tmp = 0;
 
 	struct acpi_ec *ec = context;
+
+	/* clear addr values, ec_parse_io_ports depend on it */
+	ec->command_addr = ec->data_addr = 0;
+
 	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
 				     ec_parse_io_ports, ec);
 	if (ACPI_FAILURE(status))
@@ -804,11 +818,11 @@
 		ec = make_acpi_ec();
 		if (!ec)
 			return -ENOMEM;
-		if (ec_parse_device(device->handle, 0, ec, NULL) !=
-		    AE_CTRL_TERMINATE) {
+	}
+	if (ec_parse_device(device->handle, 0, ec, NULL) !=
+		AE_CTRL_TERMINATE) {
 			kfree(ec);
 			return -EINVAL;
-		}
 	}
 
 	ec->handle = device->handle;
@@ -986,12 +1000,12 @@
 		boot_ec->handle = ACPI_ROOT_OBJECT;
 		acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle);
 		/* Don't trust ECDT, which comes from ASUSTek */
-		if (!dmi_name_in_vendors("ASUS"))
+		if (!dmi_name_in_vendors("ASUS") && EC_FLAGS_MSI == 0)
 			goto install;
 		saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
 		if (!saved_ec)
 			return -ENOMEM;
-		memcpy(saved_ec, boot_ec, sizeof(*saved_ec));
+		memcpy(saved_ec, boot_ec, sizeof(struct acpi_ec));
 	/* fall through */
 	}
 	/* This workaround is needed only on some broken machines,
@@ -1069,13 +1083,10 @@
 		},
 };
 
-static int __init acpi_ec_init(void)
+int __init acpi_ec_init(void)
 {
 	int result = 0;
 
-	if (acpi_disabled)
-		return 0;
-
 	acpi_ec_dir = proc_mkdir(ACPI_EC_CLASS, acpi_root_dir);
 	if (!acpi_ec_dir)
 		return -ENODEV;
@@ -1090,8 +1101,6 @@
 	return result;
 }
 
-subsys_initcall(acpi_ec_init);
-
 /* EC driver currently not unloadable */
 #if 0
 static void __exit acpi_ec_exit(void)
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index 8a02944..53698ea 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -68,31 +68,35 @@
 };
 
 /* thermal cooling device callbacks */
-static int fan_get_max_state(struct thermal_cooling_device *cdev, char *buf)
+static int fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long
+			     *state)
 {
 	/* ACPI fan device only support two states: ON/OFF */
-	return sprintf(buf, "1\n");
+	*state = 1;
+	return 0;
 }
 
-static int fan_get_cur_state(struct thermal_cooling_device *cdev, char *buf)
+static int fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long
+			     *state)
 {
 	struct acpi_device *device = cdev->devdata;
-	int state;
 	int result;
+	int acpi_state;
 
 	if (!device)
 		return -EINVAL;
 
-	result = acpi_bus_get_power(device->handle, &state);
+	result = acpi_bus_get_power(device->handle, &acpi_state);
 	if (result)
 		return result;
 
-	return sprintf(buf, "%s\n", state == ACPI_STATE_D3 ? "0" :
-			 (state == ACPI_STATE_D0 ? "1" : "unknown"));
+	*state = (acpi_state == ACPI_STATE_D3 ? 0 :
+		 (acpi_state == ACPI_STATE_D0 ? 1 : -1));
+	return 0;
 }
 
 static int
-fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state)
+fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
 {
 	struct acpi_device *device = cdev->devdata;
 	int result;
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 5479b9f..8bd2c2a 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -286,10 +286,8 @@
 	return 0;
 }
 
-static int __init init_acpi_device_notify(void)
+int __init init_acpi_device_notify(void)
 {
-	if (acpi_disabled)
-		return 0;
 	if (platform_notify || platform_notify_remove) {
 		printk(KERN_ERR PREFIX "Can't use platform_notify\n");
 		return 0;
@@ -298,5 +296,3 @@
 	platform_notify_remove = acpi_platform_notify_remove;
 	return 0;
 }
-
-arch_initcall(init_acpi_device_notify);
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
new file mode 100644
index 0000000..11a69b5
--- /dev/null
+++ b/drivers/acpi/internal.h
@@ -0,0 +1,43 @@
+/* For use by Linux/ACPI infrastructure, not drivers */
+
+int init_acpi_device_notify(void);
+int acpi_scan_init(void);
+int acpi_system_init(void);
+
+#ifdef CONFIG_ACPI_DEBUG
+int acpi_debug_init(void);
+#else
+static inline int acpi_debug_init(void) { return 0; }
+#endif
+
+/* --------------------------------------------------------------------------
+                                  Power Resource
+   -------------------------------------------------------------------------- */
+int acpi_power_init(void);
+int acpi_device_sleep_wake(struct acpi_device *dev,
+                           int enable, int sleep_state, int dev_state);
+int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state);
+int acpi_disable_wakeup_device_power(struct acpi_device *dev);
+int acpi_power_get_inferred_state(struct acpi_device *device);
+int acpi_power_transition(struct acpi_device *device, int state);
+extern int acpi_power_nocheck;
+
+int acpi_wakeup_device_init(void);
+
+/* --------------------------------------------------------------------------
+                                  Embedded Controller
+   -------------------------------------------------------------------------- */
+int acpi_ec_init(void);
+int acpi_ec_ecdt_probe(void);
+int acpi_boot_ec_enable(void);
+
+/*--------------------------------------------------------------------------
+                                  Suspend/Resume
+  -------------------------------------------------------------------------- */
+extern int acpi_sleep_init(void);
+
+#ifdef CONFIG_ACPI_SLEEP
+int acpi_sleep_proc_init(void);
+#else
+static inline int acpi_sleep_proc_init(void) { return 0; }
+#endif
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index 3a0d8ef..d440ccd 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -131,6 +131,21 @@
 #endif				/* ACPI_DEBUG_OUTPUT */
 		break;
 
+	case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
+#ifdef ACPI_DEBUG_OUTPUT
+		{
+			struct acpi_srat_x2apic_cpu_affinity *p =
+			    (struct acpi_srat_x2apic_cpu_affinity *)header;
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+					  "SRAT Processor (x2apicid[0x%08x]) in"
+					  " proximity domain %d %s\n",
+					  p->apic_id,
+					  p->proximity_domain,
+					  (p->flags & ACPI_SRAT_CPU_ENABLED) ?
+					  "enabled" : "disabled"));
+		}
+#endif				/* ACPI_DEBUG_OUTPUT */
+		break;
 	default:
 		printk(KERN_WARNING PREFIX
 		       "Found unsupported SRAT entry (type = 0x%x)\n",
@@ -180,8 +195,35 @@
 	return 0;
 }
 
+void __init __attribute__ ((weak))
+acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
+{
+	printk(KERN_WARNING PREFIX
+	       "Found unsupported x2apic [0x%08x] SRAT entry\n", pa->apic_id);
+	return;
+}
+
+
 static int __init
-acpi_parse_processor_affinity(struct acpi_subtable_header * header,
+acpi_parse_x2apic_affinity(struct acpi_subtable_header *header,
+			   const unsigned long end)
+{
+	struct acpi_srat_x2apic_cpu_affinity *processor_affinity;
+
+	processor_affinity = (struct acpi_srat_x2apic_cpu_affinity *)header;
+	if (!processor_affinity)
+		return -EINVAL;
+
+	acpi_table_print_srat_entry(header);
+
+	/* let architecture-dependent part to do it */
+	acpi_numa_x2apic_affinity_init(processor_affinity);
+
+	return 0;
+}
+
+static int __init
+acpi_parse_processor_affinity(struct acpi_subtable_header *header,
 			      const unsigned long end)
 {
 	struct acpi_srat_cpu_affinity *processor_affinity;
@@ -241,6 +283,8 @@
 {
 	/* 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, NR_CPUS);
 		acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY,
 				      acpi_parse_processor_affinity, NR_CPUS);
 		acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY,
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index eb8980d..d59f08e 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -1070,9 +1070,9 @@
  * in arbitrary AML code and can interfere with legacy drivers.
  * acpi_enforce_resources= can be set to:
  *
- *   - strict           (2)
+ *   - strict (default) (2)
  *     -> further driver trying to access the resources will not load
- *   - lax (default)    (1)
+ *   - lax              (1)
  *     -> further driver trying to access the resources will load, but you
  *     get a system message that something might go wrong...
  *
@@ -1084,7 +1084,7 @@
 #define ENFORCE_RESOURCES_LAX    1
 #define ENFORCE_RESOURCES_NO     0
 
-static unsigned int acpi_enforce_resources = ENFORCE_RESOURCES_LAX;
+static unsigned int acpi_enforce_resources = ENFORCE_RESOURCES_STRICT;
 
 static int __init acpi_enforce_resources_setup(char *str)
 {
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 891bdf6..51b9f82 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -86,7 +86,7 @@
 }
 
 /* http://bugzilla.kernel.org/show_bug.cgi?id=4773 */
-static struct dmi_system_id medion_md9580[] = {
+static const struct dmi_system_id medion_md9580[] = {
 	{
 		.ident = "Medion MD9580-F laptop",
 		.matches = {
@@ -98,7 +98,7 @@
 };
 
 /* http://bugzilla.kernel.org/show_bug.cgi?id=5044 */
-static struct dmi_system_id dell_optiplex[] = {
+static const struct dmi_system_id dell_optiplex[] = {
 	{
 		.ident = "Dell Optiplex GX1",
 		.matches = {
@@ -110,7 +110,7 @@
 };
 
 /* http://bugzilla.kernel.org/show_bug.cgi?id=10138 */
-static struct dmi_system_id hp_t5710[] = {
+static const struct dmi_system_id hp_t5710[] = {
 	{
 		.ident = "HP t5710",
 		.matches = {
@@ -123,13 +123,13 @@
 };
 
 struct prt_quirk {
-	struct dmi_system_id	*system;
+	const struct dmi_system_id *system;
 	unsigned int		segment;
 	unsigned int		bus;
 	unsigned int		device;
 	unsigned char		pin;
-	char			*source;	/* according to BIOS */
-	char			*actual_source;
+	const char		*source;	/* according to BIOS */
+	const char		*actual_source;
 };
 
 #define PCI_INTX_PIN(c)		(c - 'A' + 1)
@@ -139,7 +139,7 @@
  * interrupt at the listed segment/bus/device/pin is connected to the first
  * link device, but it is actually connected to the second.
  */
-static struct prt_quirk prt_quirks[] = {
+static const struct prt_quirk prt_quirks[] = {
 	{ medion_md9580, 0, 0, 9, PCI_INTX_PIN('A'),
 		"\\_SB_.PCI0.ISA_.LNKA",
 		"\\_SB_.PCI0.ISA_.LNKB"},
@@ -155,7 +155,7 @@
 			  struct acpi_pci_routing_table *prt)
 {
 	int i;
-	struct prt_quirk *quirk;
+	const struct prt_quirk *quirk;
 
 	for (i = 0; i < ARRAY_SIZE(prt_quirks); i++) {
 		quirk = &prt_quirks[i];
@@ -319,7 +319,7 @@
 	 */
 	bridge = dev->bus->self;
 	while (bridge) {
-		pin = (((pin - 1) + PCI_SLOT(dev->devfn)) % 4) + 1;
+		pin = pci_swizzle_interrupt_pin(dev, pin);
 
 		if ((bridge->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) {
 			/* PC card has the same IRQ as its cardbridge */
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 6c772ca..16e0f9d 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -43,13 +43,14 @@
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
-#define _COMPONENT		ACPI_PCI_COMPONENT
+#define _COMPONENT			ACPI_PCI_COMPONENT
 ACPI_MODULE_NAME("pci_link");
 #define ACPI_PCI_LINK_CLASS		"pci_irq_routing"
 #define ACPI_PCI_LINK_DEVICE_NAME	"PCI Interrupt Link"
 #define ACPI_PCI_LINK_FILE_INFO		"info"
 #define ACPI_PCI_LINK_FILE_STATUS	"state"
-#define ACPI_PCI_LINK_MAX_POSSIBLE 16
+#define ACPI_PCI_LINK_MAX_POSSIBLE	16
+
 static int acpi_pci_link_add(struct acpi_device *device);
 static int acpi_pci_link_remove(struct acpi_device *device, int type);
 
@@ -66,7 +67,7 @@
 	.ops = {
 		.add = acpi_pci_link_add,
 		.remove = acpi_pci_link_remove,
-		},
+	},
 };
 
 /*
@@ -76,7 +77,7 @@
 struct acpi_pci_link_irq {
 	u8 active;		/* Current IRQ */
 	u8 triggering;		/* All IRQs */
-	u8 polarity;	/* All IRQs */
+	u8 polarity;		/* All IRQs */
 	u8 resource_type;
 	u8 possible_count;
 	u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE];
@@ -85,16 +86,13 @@
 };
 
 struct acpi_pci_link {
-	struct list_head node;
-	struct acpi_device *device;
-	struct acpi_pci_link_irq irq;
-	int refcnt;
+	struct list_head		list;
+	struct acpi_device		*device;
+	struct acpi_pci_link_irq	irq;
+	int				refcnt;
 };
 
-static struct {
-	int count;
-	struct list_head entries;
-} acpi_link;
+static LIST_HEAD(acpi_link_list);
 static DEFINE_MUTEX(acpi_link_lock);
 
 /* --------------------------------------------------------------------------
@@ -104,12 +102,11 @@
 /*
  * set context (link) possible list from resource list
  */
-static acpi_status
-acpi_pci_link_check_possible(struct acpi_resource *resource, void *context)
+static acpi_status acpi_pci_link_check_possible(struct acpi_resource *resource,
+						void *context)
 {
 	struct acpi_pci_link *link = context;
-	u32 i = 0;
-
+	u32 i;
 
 	switch (resource->type) {
 	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -179,10 +176,6 @@
 {
 	acpi_status status;
 
-
-	if (!link)
-		return -EINVAL;
-
 	status = acpi_walk_resources(link->device->handle, METHOD_NAME__PRS,
 				     acpi_pci_link_check_possible, link);
 	if (ACPI_FAILURE(status)) {
@@ -197,11 +190,10 @@
 	return 0;
 }
 
-static acpi_status
-acpi_pci_link_check_current(struct acpi_resource *resource, void *context)
+static acpi_status acpi_pci_link_check_current(struct acpi_resource *resource,
+					       void *context)
 {
-	int *irq = (int *)context;
-
+	int *irq = context;
 
 	switch (resource->type) {
 	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -258,12 +250,9 @@
 static int acpi_pci_link_get_current(struct acpi_pci_link *link)
 {
 	int result = 0;
-	acpi_status status = AE_OK;
+	acpi_status status;
 	int irq = 0;
 
-	if (!link)
-		return -EINVAL;
-
 	link->irq.active = 0;
 
 	/* in practice, status disabled is meaningless, ignore it */
@@ -308,16 +297,15 @@
 
 static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
 {
-	int result = 0;
-	acpi_status status = AE_OK;
+	int result;
+	acpi_status status;
 	struct {
 		struct acpi_resource res;
 		struct acpi_resource end;
 	} *resource;
 	struct acpi_buffer buffer = { 0, NULL };
 
-
-	if (!link || !irq)
+	if (!irq)
 		return -EINVAL;
 
 	resource = kzalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);
@@ -479,30 +467,22 @@
 	PIRQ_PENALTY_PCI_AVAILABLE,	/* IRQ9  PCI, often acpi */
 	PIRQ_PENALTY_PCI_AVAILABLE,	/* IRQ10 PCI */
 	PIRQ_PENALTY_PCI_AVAILABLE,	/* IRQ11 PCI */
-	PIRQ_PENALTY_ISA_USED,	/* IRQ12 mouse */
-	PIRQ_PENALTY_ISA_USED,	/* IRQ13 fpe, sometimes */
-	PIRQ_PENALTY_ISA_USED,	/* IRQ14 ide0 */
-	PIRQ_PENALTY_ISA_USED,	/* IRQ15 ide1 */
+	PIRQ_PENALTY_ISA_USED,		/* IRQ12 mouse */
+	PIRQ_PENALTY_ISA_USED,		/* IRQ13 fpe, sometimes */
+	PIRQ_PENALTY_ISA_USED,		/* IRQ14 ide0 */
+	PIRQ_PENALTY_ISA_USED,		/* IRQ15 ide1 */
 	/* >IRQ15 */
 };
 
 int __init acpi_irq_penalty_init(void)
 {
-	struct list_head *node = NULL;
-	struct acpi_pci_link *link = NULL;
-	int i = 0;
-
+	struct acpi_pci_link *link;
+	int i;
 
 	/*
 	 * Update penalties to facilitate IRQ balancing.
 	 */
-	list_for_each(node, &acpi_link.entries) {
-
-		link = list_entry(node, struct acpi_pci_link, node);
-		if (!link) {
-			printk(KERN_ERR PREFIX "Invalid link context\n");
-			continue;
-		}
+	list_for_each_entry(link, &acpi_link_list, list) {
 
 		/*
 		 * reflect the possible and active irqs in the penalty table --
@@ -527,7 +507,6 @@
 	}
 	/* Add a penalty for the SCI */
 	acpi_irq_penalty[acpi_gbl_FADT.sci_interrupt] += PIRQ_PENALTY_PCI_USING;
-
 	return 0;
 }
 
@@ -538,7 +517,6 @@
 	int irq;
 	int i;
 
-
 	if (link->irq.initialized) {
 		if (link->refcnt == 0)
 			/* This means the link is disabled but initialized */
@@ -566,11 +544,10 @@
 	/*
 	 * if active found, use it; else pick entry from end of possible list.
 	 */
-	if (link->irq.active) {
+	if (link->irq.active)
 		irq = link->irq.active;
-	} else {
+	else
 		irq = link->irq.possible[link->irq.possible_count - 1];
-	}
 
 	if (acpi_irq_balance || !link->irq.active) {
 		/*
@@ -599,7 +576,6 @@
 	}
 
 	link->irq.initialized = 1;
-
 	return 0;
 }
 
@@ -608,16 +584,12 @@
  * success: return IRQ >= 0
  * failure: return -1
  */
-
-int
-acpi_pci_link_allocate_irq(acpi_handle handle,
-			   int index,
-			   int *triggering, int *polarity, char **name)
+int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *triggering,
+			       int *polarity, char **name)
 {
-	int result = 0;
-	struct acpi_device *device = NULL;
-	struct acpi_pci_link *link = NULL;
-
+	int result;
+	struct acpi_device *device;
+	struct acpi_pci_link *link;
 
 	result = acpi_bus_get_device(handle, &device);
 	if (result) {
@@ -669,11 +641,10 @@
  */
 int acpi_pci_link_free_irq(acpi_handle handle)
 {
-	struct acpi_device *device = NULL;
-	struct acpi_pci_link *link = NULL;
+	struct acpi_device *device;
+	struct acpi_pci_link *link;
 	acpi_status result;
 
-
 	result = acpi_bus_get_device(handle, &device);
 	if (result) {
 		printk(KERN_ERR PREFIX "Invalid link device\n");
@@ -708,9 +679,9 @@
 			  "Link %s is dereferenced\n",
 			  acpi_device_bid(link->device)));
 
-	if (link->refcnt == 0) {
+	if (link->refcnt == 0)
 		acpi_evaluate_object(link->device->handle, "_DIS", NULL, NULL);
-	}
+
 	mutex_unlock(&acpi_link_lock);
 	return (link->irq.active);
 }
@@ -721,15 +692,11 @@
 
 static int acpi_pci_link_add(struct acpi_device *device)
 {
-	int result = 0;
-	struct acpi_pci_link *link = NULL;
-	int i = 0;
+	int result;
+	struct acpi_pci_link *link;
+	int i;
 	int found = 0;
 
-
-	if (!device)
-		return -EINVAL;
-
 	link = kzalloc(sizeof(struct acpi_pci_link), GFP_KERNEL);
 	if (!link)
 		return -ENOMEM;
@@ -767,9 +734,7 @@
 
 	printk("\n");
 
-	/* TBD: Acquire/release lock */
-	list_add_tail(&link->node, &acpi_link.entries);
-	acpi_link.count++;
+	list_add_tail(&link->list, &acpi_link_list);
 
       end:
 	/* disable all links -- to be activated on use */
@@ -784,24 +749,17 @@
 
 static int acpi_pci_link_resume(struct acpi_pci_link *link)
 {
-
 	if (link->refcnt && link->irq.active && link->irq.initialized)
 		return (acpi_pci_link_set(link, link->irq.active));
-	else
-		return 0;
+
+	return 0;
 }
 
 static int irqrouter_resume(struct sys_device *dev)
 {
-	struct list_head *node = NULL;
-	struct acpi_pci_link *link = NULL;
+	struct acpi_pci_link *link;
 
-	list_for_each(node, &acpi_link.entries) {
-		link = list_entry(node, struct acpi_pci_link, node);
-		if (!link) {
-			printk(KERN_ERR PREFIX "Invalid link context\n");
-			continue;
-		}
+	list_for_each_entry(link, &acpi_link_list, list) {
 		acpi_pci_link_resume(link);
 	}
 	return 0;
@@ -809,20 +767,15 @@
 
 static int acpi_pci_link_remove(struct acpi_device *device, int type)
 {
-	struct acpi_pci_link *link = NULL;
-
-
-	if (!device || !acpi_driver_data(device))
-		return -EINVAL;
+	struct acpi_pci_link *link;
 
 	link = acpi_driver_data(device);
 
 	mutex_lock(&acpi_link_lock);
-	list_del(&link->node);
+	list_del(&link->list);
 	mutex_unlock(&acpi_link_lock);
 
 	kfree(link);
-
 	return 0;
 }
 
@@ -931,7 +884,6 @@
 {
 	int error;
 
-
 	if (acpi_disabled || acpi_noirq)
 		return 0;
 
@@ -957,9 +909,6 @@
 			acpi_irq_balance = 0;
 	}
 
-	acpi_link.count = 0;
-	INIT_LIST_HEAD(&acpi_link.entries);
-
 	if (acpi_bus_register_driver(&acpi_pci_link_driver) < 0)
 		return -ENODEV;
 
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index c926e7d..56665a6 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -54,10 +54,6 @@
 #define ACPI_POWER_RESOURCE_STATE_ON	0x01
 #define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF
 
-#ifdef MODULE_PARAM_PREFIX
-#undef MODULE_PARAM_PREFIX
-#endif
-#define MODULE_PARAM_PREFIX "acpi."
 int acpi_power_nocheck;
 module_param_named(power_nocheck, acpi_power_nocheck, bool, 000);
 
@@ -773,14 +769,10 @@
 	return 0;
 }
 
-static int __init acpi_power_init(void)
+int __init acpi_power_init(void)
 {
 	int result = 0;
 
-
-	if (acpi_disabled)
-		return 0;
-
 	INIT_LIST_HEAD(&acpi_power_resource_list);
 
 	acpi_power_dir = proc_mkdir(ACPI_POWER_CLASS, acpi_root_dir);
@@ -795,5 +787,3 @@
 
 	return 0;
 }
-
-subsys_initcall(acpi_power_init);
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c
index 428c911d..05dfdc9 100644
--- a/drivers/acpi/proc.c
+++ b/drivers/acpi/proc.c
@@ -496,11 +496,8 @@
 }
 #endif				/* HAVE_ACPI_LEGACY_ALARM */
 
-static int __init acpi_sleep_proc_init(void)
+int __init acpi_sleep_proc_init(void)
 {
-	if (acpi_disabled)
-		return 0;
-
 #ifdef	CONFIG_ACPI_PROCFS
 	/* 'sleep' [R/W] */
 	proc_create("sleep", S_IFREG | S_IRUGO | S_IWUSR,
@@ -527,5 +524,3 @@
 
 	return 0;
 }
-
-late_initcall(acpi_sleep_proc_init);
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index fa2f742..45ad328 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -82,7 +82,7 @@
 static int acpi_processor_start(struct acpi_device *device);
 static int acpi_processor_remove(struct acpi_device *device, int type);
 static int acpi_processor_info_open_fs(struct inode *inode, struct file *file);
-static void acpi_processor_notify(acpi_handle handle, u32 event, void *data);
+static void acpi_processor_notify(struct acpi_device *device, u32 event);
 static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu);
 static int acpi_processor_handle_eject(struct acpi_processor *pr);
 
@@ -104,6 +104,7 @@
 		.start = acpi_processor_start,
 		.suspend = acpi_processor_suspend,
 		.resume = acpi_processor_resume,
+		.notify = acpi_processor_notify,
 		},
 };
 
@@ -426,6 +427,29 @@
 	return 0;
 }
 
+static int map_x2apic_id(struct acpi_subtable_header *entry,
+			 int device_declaration, u32 acpi_id, int *apic_id)
+{
+	struct acpi_madt_local_x2apic *apic =
+		(struct acpi_madt_local_x2apic *)entry;
+	u32 tmp = apic->local_apic_id;
+
+	/* Only check enabled APICs*/
+	if (!(apic->lapic_flags & ACPI_MADT_ENABLED))
+		return 0;
+
+	/* Device statement declaration type */
+	if (device_declaration) {
+		if (apic->uid == acpi_id)
+			goto found;
+	}
+
+	return 0;
+found:
+	*apic_id = tmp;
+	return 1;
+}
+
 static int map_lsapic_id(struct acpi_subtable_header *entry,
 		int device_declaration, u32 acpi_id, int *apic_id)
 {
@@ -475,6 +499,9 @@
 		if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) {
 			if (map_lapic_id(header, acpi_id, &apic_id))
 				break;
+		} else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) {
+			if (map_x2apic_id(header, type, acpi_id, &apic_id))
+				break;
 		} else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
 			if (map_lsapic_id(header, type, acpi_id, &apic_id))
 				break;
@@ -665,7 +692,6 @@
 static int __cpuinit acpi_processor_start(struct acpi_device *device)
 {
 	int result = 0;
-	acpi_status status = AE_OK;
 	struct acpi_processor *pr;
 	struct sys_device *sysdev;
 
@@ -702,9 +728,6 @@
 	if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev"))
 		return -EFAULT;
 
-	status = acpi_install_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY,
-					     acpi_processor_notify, pr);
-
 	/* _PDC call should be done before doing anything else (if reqd.). */
 	arch_acpi_processor_init_pdc(pr);
 	acpi_processor_set_pdc(pr);
@@ -750,18 +773,14 @@
 	return result;
 }
 
-static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_processor_notify(struct acpi_device *device, u32 event)
 {
-	struct acpi_processor *pr = data;
-	struct acpi_device *device = NULL;
+	struct acpi_processor *pr = acpi_driver_data(device);
 	int saved;
 
 	if (!pr)
 		return;
 
-	if (acpi_bus_get_device(pr->handle, &device))
-		return;
-
 	switch (event) {
 	case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
 		saved = pr->performance_platform_limit;
@@ -840,7 +859,6 @@
 
 static int acpi_processor_remove(struct acpi_device *device, int type)
 {
-	acpi_status status = AE_OK;
 	struct acpi_processor *pr = NULL;
 
 
@@ -859,9 +877,6 @@
 
 	acpi_processor_power_exit(pr, device);
 
-	status = acpi_remove_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY,
-					    acpi_processor_notify);
-
 	sysfs_remove_link(&device->dev.kobj, "sysdev");
 
 	acpi_processor_remove_fs(device);
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 7bc22a4..4e6e758 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -64,7 +64,6 @@
 #define _COMPONENT              ACPI_PROCESSOR_COMPONENT
 ACPI_MODULE_NAME("processor_idle");
 #define ACPI_PROCESSOR_FILE_POWER	"power"
-#define US_TO_PM_TIMER_TICKS(t)		((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
 #define PM_TIMER_TICK_NS		(1000000000ULL/PM_TIMER_FREQUENCY)
 #define C2_OVERHEAD			1	/* 1us */
 #define C3_OVERHEAD			1	/* 1us */
@@ -78,6 +77,10 @@
 static unsigned int latency_factor __read_mostly = 2;
 module_param(latency_factor, uint, 0644);
 
+static s64 us_to_pm_timer_ticks(s64 t)
+{
+	return div64_u64(t * PM_TIMER_FREQUENCY, 1000000);
+}
 /*
  * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3.
  * For now disable this. Probably a bug somewhere else.
@@ -101,57 +104,6 @@
 /* Actually this shouldn't be __cpuinitdata, would be better to fix the
    callers to only run once -AK */
 static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = {
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET70WW")}, (void *)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW")}, (void *)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET43WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET45WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET47WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET50WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET52WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET55WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET56WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET59WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET61WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET62WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET64WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET65WW") }, (void*)1},
-	{ set_max_cstate, "IBM ThinkPad R40e", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET68WW") }, (void*)1},
-	{ set_max_cstate, "Medion 41700", {
-	  DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J")}, (void *)1},
 	{ set_max_cstate, "Clevo 5600D", {
 	  DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
 	  DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
@@ -159,25 +111,6 @@
 	{},
 };
 
-static inline u32 ticks_elapsed(u32 t1, u32 t2)
-{
-	if (t2 >= t1)
-		return (t2 - t1);
-	else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER))
-		return (((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
-	else
-		return ((0xFFFFFFFF - t1) + t2);
-}
-
-static inline u32 ticks_elapsed_in_us(u32 t1, u32 t2)
-{
-	if (t2 >= t1)
-		return PM_TIMER_TICKS_TO_US(t2 - t1);
-	else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER))
-		return PM_TIMER_TICKS_TO_US(((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
-	else
-		return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2);
-}
 
 /*
  * Callers should disable interrupts before the call and enable
@@ -630,7 +563,7 @@
 	 * In either case, the proper way to
 	 * handle BM_RLD is to set it and leave it set.
 	 */
-	acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
+	acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
 
 	return;
 }
@@ -800,9 +733,9 @@
 {
 	u32 bm_status = 0;
 
-	acpi_get_register_unlocked(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
+	acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
 	if (bm_status)
-		acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
+		acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
 	/*
 	 * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect
 	 * the true state of bus mastering activity; forcing us to
@@ -853,7 +786,8 @@
 static int acpi_idle_enter_c1(struct cpuidle_device *dev,
 			      struct cpuidle_state *state)
 {
-	u32 t1, t2;
+	ktime_t  kt1, kt2;
+	s64 idle_time;
 	struct acpi_processor *pr;
 	struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
 
@@ -871,14 +805,15 @@
 		return 0;
 	}
 
-	t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+	kt1 = ktime_get_real();
 	acpi_idle_do_entry(cx);
-	t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+	kt2 = ktime_get_real();
+	idle_time =  ktime_to_us(ktime_sub(kt2, kt1));
 
 	local_irq_enable();
 	cx->usage++;
 
-	return ticks_elapsed_in_us(t1, t2);
+	return idle_time;
 }
 
 /**
@@ -891,8 +826,9 @@
 {
 	struct acpi_processor *pr;
 	struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
-	u32 t1, t2;
-	int sleep_ticks = 0;
+	ktime_t  kt1, kt2;
+	s64 idle_time;
+	s64 sleep_ticks = 0;
 
 	pr = __get_cpu_var(processors);
 
@@ -925,18 +861,19 @@
 	if (cx->type == ACPI_STATE_C3)
 		ACPI_FLUSH_CPU_CACHE();
 
-	t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+	kt1 = ktime_get_real();
 	/* Tell the scheduler that we are going deep-idle: */
 	sched_clock_idle_sleep_event();
 	acpi_idle_do_entry(cx);
-	t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+	kt2 = ktime_get_real();
+	idle_time =  ktime_to_us(ktime_sub(kt2, kt1));
 
 #if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
 	/* TSC could halt in idle, so notify users */
 	if (tsc_halts_in_c(cx->type))
 		mark_tsc_unstable("TSC halts in idle");;
 #endif
-	sleep_ticks = ticks_elapsed(t1, t2);
+	sleep_ticks = us_to_pm_timer_ticks(idle_time);
 
 	/* Tell the scheduler how much we idled: */
 	sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
@@ -948,7 +885,7 @@
 
 	acpi_state_timer_broadcast(pr, cx, 0);
 	cx->time += sleep_ticks;
-	return ticks_elapsed_in_us(t1, t2);
+	return idle_time;
 }
 
 static int c3_cpu_count;
@@ -966,8 +903,10 @@
 {
 	struct acpi_processor *pr;
 	struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
-	u32 t1, t2;
-	int sleep_ticks = 0;
+	ktime_t  kt1, kt2;
+	s64 idle_time;
+	s64 sleep_ticks = 0;
+
 
 	pr = __get_cpu_var(processors);
 
@@ -1028,20 +967,21 @@
 		c3_cpu_count++;
 		/* Disable bus master arbitration when all CPUs are in C3 */
 		if (c3_cpu_count == num_online_cpus())
-			acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
+			acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1);
 		spin_unlock(&c3_lock);
 	} else if (!pr->flags.bm_check) {
 		ACPI_FLUSH_CPU_CACHE();
 	}
 
-	t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+	kt1 = ktime_get_real();
 	acpi_idle_do_entry(cx);
-	t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+	kt2 = ktime_get_real();
+	idle_time =  ktime_to_us(ktime_sub(kt2, kt1));
 
 	/* Re-enable bus master arbitration */
 	if (pr->flags.bm_check && pr->flags.bm_control) {
 		spin_lock(&c3_lock);
-		acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
+		acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0);
 		c3_cpu_count--;
 		spin_unlock(&c3_lock);
 	}
@@ -1051,7 +991,7 @@
 	if (tsc_halts_in_c(ACPI_STATE_C3))
 		mark_tsc_unstable("TSC halts in idle");
 #endif
-	sleep_ticks = ticks_elapsed(t1, t2);
+	sleep_ticks = us_to_pm_timer_ticks(idle_time);
 	/* Tell the scheduler how much we idled: */
 	sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
 
@@ -1062,7 +1002,7 @@
 
 	acpi_state_timer_broadcast(pr, cx, 0);
 	cx->time += sleep_ticks;
-	return ticks_elapsed_in_us(t1, t2);
+	return idle_time;
 }
 
 struct cpuidle_driver acpi_idle_driver = {
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 68fd3d2..cafb410 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -479,6 +479,13 @@
 		goto end;
 	}
 
+	if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL &&
+	    pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY &&
+	    pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) {
+		printk(KERN_ERR PREFIX "Invalid _PSD:coord_type\n");
+		result = -EFAULT;
+		goto end;
+	}
 end:
 	kfree(buffer.pointer);
 	return result;
@@ -501,9 +508,10 @@
 
 	mutex_lock(&performance_mutex);
 
-	retval = 0;
-
-	/* Call _PSD for all CPUs */
+	/*
+	 * Check if another driver has already registered, and abort before
+	 * changing pr->performance if it has. Check input data as well.
+	 */
 	for_each_possible_cpu(i) {
 		pr = per_cpu(processors, i);
 		if (!pr) {
@@ -513,13 +521,20 @@
 
 		if (pr->performance) {
 			retval = -EBUSY;
-			continue;
+			goto err_out;
 		}
 
 		if (!performance || !per_cpu_ptr(performance, i)) {
 			retval = -EINVAL;
-			continue;
+			goto err_out;
 		}
+	}
+
+	/* Call _PSD for all CPUs */
+	for_each_possible_cpu(i) {
+		pr = per_cpu(processors, i);
+		if (!pr)
+			continue;
 
 		pr->performance = per_cpu_ptr(performance, i);
 		cpumask_set_cpu(i, pr->performance->shared_cpu_map);
@@ -535,26 +550,6 @@
 	 * Now that we have _PSD data from all CPUs, lets setup P-state 
 	 * domain info.
 	 */
-	for_each_possible_cpu(i) {
-		pr = per_cpu(processors, i);
-		if (!pr)
-			continue;
-
-		/* Basic validity check for domain info */
-		pdomain = &(pr->performance->domain_info);
-		if ((pdomain->revision != ACPI_PSD_REV0_REVISION) ||
-		    (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES)) {
-			retval = -EINVAL;
-			goto err_ret;
-		}
-		if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL &&
-		    pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY &&
-		    pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) {
-			retval = -EINVAL;
-			goto err_ret;
-		}
-	}
-
 	cpumask_clear(covered_cpus);
 	for_each_possible_cpu(i) {
 		pr = per_cpu(processors, i);
@@ -643,6 +638,7 @@
 		pr->performance = NULL; /* Will be set for real in register */
 	}
 
+err_out:
 	mutex_unlock(&performance_mutex);
 	free_cpumask_var(covered_cpus);
 	return retval;
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index b1eb376..39838c6 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -373,7 +373,8 @@
 	return max_state;
 }
 static int
-processor_get_max_state(struct thermal_cooling_device *cdev, char *buf)
+processor_get_max_state(struct thermal_cooling_device *cdev,
+			unsigned long *state)
 {
 	struct acpi_device *device = cdev->devdata;
 	struct acpi_processor *pr = acpi_driver_data(device);
@@ -381,28 +382,29 @@
 	if (!device || !pr)
 		return -EINVAL;
 
-	return sprintf(buf, "%d\n", acpi_processor_max_state(pr));
+	*state = acpi_processor_max_state(pr);
+	return 0;
 }
 
 static int
-processor_get_cur_state(struct thermal_cooling_device *cdev, char *buf)
+processor_get_cur_state(struct thermal_cooling_device *cdev,
+			unsigned long *cur_state)
 {
 	struct acpi_device *device = cdev->devdata;
 	struct acpi_processor *pr = acpi_driver_data(device);
-	int cur_state;
 
 	if (!device || !pr)
 		return -EINVAL;
 
-	cur_state = cpufreq_get_cur_state(pr->id);
+	*cur_state = cpufreq_get_cur_state(pr->id);
 	if (pr->flags.throttling)
-		cur_state += pr->throttling.state;
-
-	return sprintf(buf, "%d\n", cur_state);
+		*cur_state += pr->throttling.state;
+	return 0;
 }
 
 static int
-processor_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state)
+processor_set_cur_state(struct thermal_cooling_device *cdev,
+			unsigned long state)
 {
 	struct acpi_device *device = cdev->devdata;
 	struct acpi_processor *pr = acpi_driver_data(device);
@@ -507,7 +509,7 @@
 	return count;
 }
 
-struct file_operations acpi_processor_limit_fops = {
+const struct file_operations acpi_processor_limit_fops = {
 	.owner = THIS_MODULE,
 	.open = acpi_processor_limit_open_fs,
 	.read = seq_read,
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index d278381..d0d1f4d 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -783,11 +783,9 @@
 		    (struct acpi_processor_tx_tss *)&(pr->throttling.
 						      states_tss[i]);
 		if (tx->control == value)
-			break;
+			return i;
 	}
-	if (i > pr->throttling.state_count)
-		i = -1;
-	return i;
+	return -1;
 }
 
 static int acpi_get_throttling_value(struct acpi_processor *pr,
@@ -1291,7 +1289,7 @@
 	return count;
 }
 
-struct file_operations acpi_processor_throttling_fops = {
+const struct file_operations acpi_processor_throttling_fops = {
 	.owner = THIS_MODULE,
 	.open = acpi_processor_throttling_open_fs,
 	.read = seq_read,
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 59afd52..4b214b7 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -102,8 +102,8 @@
 	u16 cycle_count;
 	u16 temp_now;
 	u16 voltage_now;
-	s16 current_now;
-	s16 current_avg;
+	s16 rate_now;
+	s16 rate_avg;
 	u16 capacity_now;
 	u16 state_of_charge;
 	u16 state;
@@ -202,9 +202,9 @@
 		return -ENODEV;
 	switch (psp) {
 	case POWER_SUPPLY_PROP_STATUS:
-		if (battery->current_now < 0)
+		if (battery->rate_now < 0)
 			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
-		else if (battery->current_now > 0)
+		else if (battery->rate_now > 0)
 			val->intval = POWER_SUPPLY_STATUS_CHARGING;
 		else
 			val->intval = POWER_SUPPLY_STATUS_FULL;
@@ -224,11 +224,13 @@
 				acpi_battery_vscale(battery) * 1000;
 		break;
 	case POWER_SUPPLY_PROP_CURRENT_NOW:
-		val->intval = abs(battery->current_now) *
+	case POWER_SUPPLY_PROP_POWER_NOW:
+		val->intval = abs(battery->rate_now) *
 				acpi_battery_ipscale(battery) * 1000;
 		break;
 	case POWER_SUPPLY_PROP_CURRENT_AVG:
-		val->intval = abs(battery->current_avg) *
+	case POWER_SUPPLY_PROP_POWER_AVG:
+		val->intval = abs(battery->rate_avg) *
 				acpi_battery_ipscale(battery) * 1000;
 		break;
 	case POWER_SUPPLY_PROP_CAPACITY:
@@ -293,6 +295,8 @@
 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
 	POWER_SUPPLY_PROP_CURRENT_NOW,
 	POWER_SUPPLY_PROP_CURRENT_AVG,
+	POWER_SUPPLY_PROP_POWER_NOW,
+	POWER_SUPPLY_PROP_POWER_AVG,
 	POWER_SUPPLY_PROP_CAPACITY,
 	POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
 	POWER_SUPPLY_PROP_ENERGY_FULL,
@@ -301,6 +305,7 @@
 	POWER_SUPPLY_PROP_MODEL_NAME,
 	POWER_SUPPLY_PROP_MANUFACTURER,
 };
+
 #endif
 
 /* --------------------------------------------------------------------------
@@ -330,8 +335,8 @@
 static struct acpi_battery_reader state_readers[] = {
 	{0x08, SMBUS_READ_WORD, offsetof(struct acpi_battery, temp_now)},
 	{0x09, SMBUS_READ_WORD, offsetof(struct acpi_battery, voltage_now)},
-	{0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_now)},
-	{0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_avg)},
+	{0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, rate_now)},
+	{0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, rate_avg)},
 	{0x0f, SMBUS_READ_WORD, offsetof(struct acpi_battery, capacity_now)},
 	{0x0e, SMBUS_READ_WORD, offsetof(struct acpi_battery, state_of_charge)},
 	{0x16, SMBUS_READ_WORD, offsetof(struct acpi_battery, state)},
@@ -479,9 +484,9 @@
 acpi_sbs_add_fs(struct proc_dir_entry **dir,
 		struct proc_dir_entry *parent_dir,
 		char *dir_name,
-		struct file_operations *info_fops,
-		struct file_operations *state_fops,
-		struct file_operations *alarm_fops, void *data)
+		const struct file_operations *info_fops,
+		const struct file_operations *state_fops,
+		const struct file_operations *alarm_fops, void *data)
 {
 	if (!*dir) {
 		*dir = proc_mkdir(dir_name, parent_dir);
@@ -588,9 +593,9 @@
 	seq_printf(seq, "capacity state:          %s\n",
 		   (battery->state & 0x0010) ? "critical" : "ok");
 	seq_printf(seq, "charging state:          %s\n",
-		   (battery->current_now < 0) ? "discharging" :
-		   ((battery->current_now > 0) ? "charging" : "charged"));
-	rate = abs(battery->current_now) * acpi_battery_ipscale(battery);
+		   (battery->rate_now < 0) ? "discharging" :
+		   ((battery->rate_now > 0) ? "charging" : "charged"));
+	rate = abs(battery->rate_now) * acpi_battery_ipscale(battery);
 	rate *= (acpi_battery_mode(battery))?(battery->voltage_now *
 			acpi_battery_vscale(battery)/1000):1;
 	seq_printf(seq, "present rate:            %d%s\n", rate,
@@ -676,7 +681,7 @@
 	return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
 }
 
-static struct file_operations acpi_battery_info_fops = {
+static const struct file_operations acpi_battery_info_fops = {
 	.open = acpi_battery_info_open_fs,
 	.read = seq_read,
 	.llseek = seq_lseek,
@@ -684,7 +689,7 @@
 	.owner = THIS_MODULE,
 };
 
-static struct file_operations acpi_battery_state_fops = {
+static const struct file_operations acpi_battery_state_fops = {
 	.open = acpi_battery_state_open_fs,
 	.read = seq_read,
 	.llseek = seq_lseek,
@@ -692,7 +697,7 @@
 	.owner = THIS_MODULE,
 };
 
-static struct file_operations acpi_battery_alarm_fops = {
+static const struct file_operations acpi_battery_alarm_fops = {
 	.open = acpi_battery_alarm_open_fs,
 	.read = seq_read,
 	.write = acpi_battery_write_alarm,
@@ -724,7 +729,7 @@
 	return single_open(file, acpi_ac_read_state, PDE(inode)->data);
 }
 
-static struct file_operations acpi_ac_state_fops = {
+static const struct file_operations acpi_ac_state_fops = {
 	.open = acpi_ac_state_open_fs,
 	.read = seq_read,
 	.llseek = seq_lseek,
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index c54d7b6..20c23c0 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -11,6 +11,8 @@
 
 #include <acpi/acpi_drivers.h>
 
+#include "internal.h"
+
 #define _COMPONENT		ACPI_BUS_COMPONENT
 ACPI_MODULE_NAME("scan");
 #define STRUCT_TO_INT(s)	(*((int*)&s))
@@ -357,6 +359,61 @@
 	return 0;
 }
 
+static void acpi_device_notify(acpi_handle handle, u32 event, void *data)
+{
+	struct acpi_device *device = data;
+
+	device->driver->ops.notify(device, event);
+}
+
+static acpi_status acpi_device_notify_fixed(void *data)
+{
+	struct acpi_device *device = data;
+
+	acpi_device_notify(device->handle, ACPI_FIXED_HARDWARE_EVENT, device);
+	return AE_OK;
+}
+
+static int acpi_device_install_notify_handler(struct acpi_device *device)
+{
+	acpi_status status;
+	char *hid;
+
+	hid = acpi_device_hid(device);
+	if (!strcmp(hid, ACPI_BUTTON_HID_POWERF))
+		status =
+		    acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
+						     acpi_device_notify_fixed,
+						     device);
+	else if (!strcmp(hid, ACPI_BUTTON_HID_SLEEPF))
+		status =
+		    acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
+						     acpi_device_notify_fixed,
+						     device);
+	else
+		status = acpi_install_notify_handler(device->handle,
+						     ACPI_DEVICE_NOTIFY,
+						     acpi_device_notify,
+						     device);
+
+	if (ACPI_FAILURE(status))
+		return -EINVAL;
+	return 0;
+}
+
+static void acpi_device_remove_notify_handler(struct acpi_device *device)
+{
+	if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWERF))
+		acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
+						acpi_device_notify_fixed);
+	else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEPF))
+		acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
+						acpi_device_notify_fixed);
+	else
+		acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
+					   acpi_device_notify);
+}
+
 static int acpi_bus_driver_init(struct acpi_device *, struct acpi_driver *);
 static int acpi_start_single_object(struct acpi_device *);
 static int acpi_device_probe(struct device * dev)
@@ -369,6 +426,20 @@
 	if (!ret) {
 		if (acpi_dev->bus_ops.acpi_op_start)
 			acpi_start_single_object(acpi_dev);
+
+		if (acpi_drv->ops.notify) {
+			ret = acpi_device_install_notify_handler(acpi_dev);
+			if (ret) {
+				if (acpi_drv->ops.stop)
+					acpi_drv->ops.stop(acpi_dev,
+						   acpi_dev->removal_type);
+				if (acpi_drv->ops.remove)
+					acpi_drv->ops.remove(acpi_dev,
+						     acpi_dev->removal_type);
+				return ret;
+			}
+		}
+
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 			"Found driver [%s] for device [%s]\n",
 			acpi_drv->name, acpi_dev->pnp.bus_id));
@@ -383,6 +454,8 @@
 	struct acpi_driver *acpi_drv = acpi_dev->driver;
 
 	if (acpi_drv) {
+		if (acpi_drv->ops.notify)
+			acpi_device_remove_notify_handler(acpi_dev);
 		if (acpi_drv->ops.stop)
 			acpi_drv->ops.stop(acpi_dev, acpi_dev->removal_type);
 		if (acpi_drv->ops.remove)
@@ -395,22 +468,10 @@
 	return 0;
 }
 
-static void acpi_device_shutdown(struct device *dev)
-{
-	struct acpi_device *acpi_dev = to_acpi_device(dev);
-	struct acpi_driver *acpi_drv = acpi_dev->driver;
-
-	if (acpi_drv && acpi_drv->ops.shutdown)
-		acpi_drv->ops.shutdown(acpi_dev);
-
-	return ;
-}
-
 struct bus_type acpi_bus_type = {
 	.name		= "acpi",
 	.suspend	= acpi_device_suspend,
 	.resume		= acpi_device_resume,
-	.shutdown	= acpi_device_shutdown,
 	.match		= acpi_bus_match,
 	.probe		= acpi_device_probe,
 	.remove		= acpi_device_remove,
@@ -1524,16 +1585,11 @@
 	return result;
 }
 
-
-static int __init acpi_scan_init(void)
+int __init acpi_scan_init(void)
 {
 	int result;
 	struct acpi_bus_ops ops;
 
-
-	if (acpi_disabled)
-		return 0;
-
 	memset(&ops, 0, sizeof(ops));
 	ops.acpi_op_add = 1;
 	ops.acpi_op_start = 1;
@@ -1566,5 +1622,3 @@
       Done:
 	return result;
 }
-
-subsys_initcall(acpi_scan_init);
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 00456fc..779e4e5 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -21,6 +21,8 @@
 
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
+
+#include "internal.h"
 #include "sleep.h"
 
 u8 sleep_states[ACPI_S_STATE_COUNT];
@@ -248,7 +250,7 @@
 
 	/* If ACPI is not enabled by the BIOS, we need to enable it here. */
 	if (set_sci_en_on_resume)
-		acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1);
+		acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1);
 	else
 		acpi_enable();
 
@@ -394,6 +396,15 @@
 		DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L300"),
 		},
 	},
+	{
+	.callback = init_old_suspend_ordering,
+	.ident = "Panasonic CF51-2L",
+	.matches = {
+		DMI_MATCH(DMI_BOARD_VENDOR,
+				"Matsushita Electric Industrial Co.,Ltd."),
+		DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"),
+		},
+	},
 	{},
 };
 #endif /* CONFIG_SUSPEND */
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index 391d035..da51f05 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -33,10 +33,6 @@
 
 #define _COMPONENT		ACPI_SYSTEM_COMPONENT
 ACPI_MODULE_NAME("system");
-#ifdef MODULE_PARAM_PREFIX
-#undef MODULE_PARAM_PREFIX
-#endif
-#define MODULE_PARAM_PREFIX "acpi."
 
 #define ACPI_SYSTEM_CLASS		"system"
 #define ACPI_SYSTEM_DEVICE_NAME		"System"
@@ -62,6 +58,7 @@
    -------------------------------------------------------------------------- */
 static LIST_HEAD(acpi_table_attr_list);
 static struct kobject *tables_kobj;
+static struct kobject *dynamic_tables_kobj;
 
 struct acpi_table_attr {
 	struct bin_attribute attr;
@@ -128,6 +125,40 @@
 	return;
 }
 
+static acpi_status
+acpi_sysfs_table_handler(u32 event, void *table, void *context)
+{
+	struct acpi_table_attr *table_attr;
+
+	switch (event) {
+	case ACPI_TABLE_EVENT_LOAD:
+		table_attr =
+			kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL);
+		if (!table_attr)
+			return AE_NO_MEMORY;
+
+		acpi_table_attr_init(table_attr, table);
+		if (sysfs_create_bin_file(dynamic_tables_kobj,
+					&table_attr->attr)) {
+			kfree(table_attr);
+			return AE_ERROR;
+		} else
+			list_add_tail(&table_attr->node,
+					&acpi_table_attr_list);
+		break;
+	case ACPI_TABLE_EVENT_UNLOAD:
+		/*
+		 * we do not need to do anything right now
+		 * because the table is not deleted from the
+		 * global table list when unloading it.
+		 */
+		break;
+	default:
+		return AE_BAD_PARAMETER;
+	}
+	return AE_OK;
+}
+
 static int acpi_system_sysfs_init(void)
 {
 	struct acpi_table_attr *table_attr;
@@ -137,7 +168,11 @@
 
 	tables_kobj = kobject_create_and_add("tables", acpi_kobj);
 	if (!tables_kobj)
-		return -ENOMEM;
+		goto err;
+
+	dynamic_tables_kobj = kobject_create_and_add("dynamic", tables_kobj);
+	if (!dynamic_tables_kobj)
+		goto err_dynamic_tables;
 
 	do {
 		result = acpi_get_table_by_index(table_index, &table_header);
@@ -162,8 +197,14 @@
 		}
 	} while (!result);
 	kobject_uevent(tables_kobj, KOBJ_ADD);
+	kobject_uevent(dynamic_tables_kobj, KOBJ_ADD);
+	result = acpi_install_table_handler(acpi_sysfs_table_handler, NULL);
 
-	return 0;
+	return result == AE_OK ? 0 : -EINVAL;
+err_dynamic_tables:
+	kobject_put(tables_kobj);
+err:
+	return -ENOMEM;
 }
 
 /*
@@ -571,12 +612,9 @@
 }
 #endif
 
-static int __init acpi_system_init(void)
+int __init acpi_system_init(void)
 {
-	int result = 0;
-
-	if (acpi_disabled)
-		return 0;
+	int result;
 
 	result = acpi_system_procfs_init();
 	if (result)
@@ -586,5 +624,3 @@
 
 	return result;
 }
-
-subsys_initcall(acpi_system_init);
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index fec1ae3..646d39c 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -62,6 +62,18 @@
 		}
 		break;
 
+	case ACPI_MADT_TYPE_LOCAL_X2APIC:
+		{
+			struct acpi_madt_local_x2apic *p =
+			    (struct acpi_madt_local_x2apic *)header;
+			printk(KERN_INFO PREFIX
+			       "X2APIC (apic_id[0x%02x] uid[0x%02x] %s)\n",
+			       p->local_apic_id, p->uid,
+			       (p->lapic_flags & ACPI_MADT_ENABLED) ?
+			       "enabled" : "disabled");
+		}
+		break;
+
 	case ACPI_MADT_TYPE_IO_APIC:
 		{
 			struct acpi_madt_io_apic *p =
@@ -116,6 +128,24 @@
 		}
 		break;
 
+	case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
+		{
+			u16 polarity, trigger;
+			struct acpi_madt_local_x2apic_nmi *p =
+			    (struct acpi_madt_local_x2apic_nmi *)header;
+
+			polarity = p->inti_flags & ACPI_MADT_POLARITY_MASK;
+			trigger = (p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2;
+
+			printk(KERN_INFO PREFIX
+			       "X2APIC_NMI (uid[0x%02x] %s %s lint[0x%x])\n",
+			       p->uid,
+			       mps_inti_flags_polarity[polarity],
+			       mps_inti_flags_trigger[trigger],
+			       p->lint);
+		}
+		break;
+
 	case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
 		{
 			struct acpi_madt_local_apic_override *p =
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index c11f9ae..e8c143c 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -37,11 +37,11 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/proc_fs.h>
-#include <linux/timer.h>
 #include <linux/jiffies.h>
 #include <linux/kmod.h>
 #include <linux/seq_file.h>
 #include <linux/reboot.h>
+#include <linux/device.h>
 #include <asm/uaccess.h>
 #include <linux/thermal.h>
 #include <acpi/acpi_bus.h>
@@ -190,7 +190,6 @@
 	struct acpi_thermal_state state;
 	struct acpi_thermal_trips trips;
 	struct acpi_handle_list devices;
-	struct timer_list timer;
 	struct thermal_zone_device *thermal_zone;
 	int tz_enabled;
 	struct mutex lock;
@@ -290,6 +289,11 @@
 
 	tz->polling_frequency = seconds * 10;	/* Convert value to deci-seconds */
 
+	tz->thermal_zone->polling_delay = seconds * 1000;
+
+	if (tz->tz_enabled)
+		thermal_zone_device_update(tz->thermal_zone);
+
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 			  "Polling frequency set to %lu seconds\n",
 			  tz->polling_frequency/10));
@@ -367,7 +371,7 @@
 		/*
 		 * Treat freezing temperatures as invalid as well; some
 		 * BIOSes return really low values and cause reboots at startup.
-		 * Below zero (Celcius) values clearly aren't right for sure..
+		 * Below zero (Celsius) values clearly aren't right for sure..
 		 * ... so lets discard those as invalid.
 		 */
 		if (ACPI_FAILURE(status) ||
@@ -569,392 +573,18 @@
 	return acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT);
 }
 
-static int acpi_thermal_critical(struct acpi_thermal *tz)
-{
-	if (!tz || !tz->trips.critical.flags.valid)
-		return -EINVAL;
-
-	if (tz->temperature >= tz->trips.critical.temperature) {
-		printk(KERN_WARNING PREFIX "Critical trip point\n");
-		tz->trips.critical.flags.enabled = 1;
-	} else if (tz->trips.critical.flags.enabled)
-		tz->trips.critical.flags.enabled = 0;
-
-	acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL,
-				tz->trips.critical.flags.enabled);
-	acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
-					  dev_name(&tz->device->dev),
-					  ACPI_THERMAL_NOTIFY_CRITICAL,
-					  tz->trips.critical.flags.enabled);
-
-	/* take no action if nocrt is set */
-	if(!nocrt) {
-		printk(KERN_EMERG
-			"Critical temperature reached (%ld C), shutting down.\n",
-			KELVIN_TO_CELSIUS(tz->temperature));
-		orderly_poweroff(true);
-	}
-
-	return 0;
-}
-
-static int acpi_thermal_hot(struct acpi_thermal *tz)
-{
-	if (!tz || !tz->trips.hot.flags.valid)
-		return -EINVAL;
-
-	if (tz->temperature >= tz->trips.hot.temperature) {
-		printk(KERN_WARNING PREFIX "Hot trip point\n");
-		tz->trips.hot.flags.enabled = 1;
-	} else if (tz->trips.hot.flags.enabled)
-		tz->trips.hot.flags.enabled = 0;
-
-	acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_HOT,
-				tz->trips.hot.flags.enabled);
-	acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
-					  dev_name(&tz->device->dev),
-					  ACPI_THERMAL_NOTIFY_HOT,
-					  tz->trips.hot.flags.enabled);
-
-	/* TBD: Call user-mode "sleep(S4)" function if nocrt is cleared */
-
-	return 0;
-}
-
-static void acpi_thermal_passive(struct acpi_thermal *tz)
-{
-	int result = 1;
-	struct acpi_thermal_passive *passive = NULL;
-	int trend = 0;
-	int i = 0;
-
-
-	if (!tz || !tz->trips.passive.flags.valid)
-		return;
-
-	passive = &(tz->trips.passive);
-
-	/*
-	 * Above Trip?
-	 * -----------
-	 * Calculate the thermal trend (using the passive cooling equation)
-	 * and modify the performance limit for all passive cooling devices
-	 * accordingly.  Note that we assume symmetry.
-	 */
-	if (tz->temperature >= passive->temperature) {
-		trend =
-		    (passive->tc1 * (tz->temperature - tz->last_temperature)) +
-		    (passive->tc2 * (tz->temperature - passive->temperature));
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "trend[%d]=(tc1[%lu]*(tmp[%lu]-last[%lu]))+(tc2[%lu]*(tmp[%lu]-psv[%lu]))\n",
-				  trend, passive->tc1, tz->temperature,
-				  tz->last_temperature, passive->tc2,
-				  tz->temperature, passive->temperature));
-		passive->flags.enabled = 1;
-		/* Heating up? */
-		if (trend > 0)
-			for (i = 0; i < passive->devices.count; i++)
-				acpi_processor_set_thermal_limit(passive->
-								 devices.
-								 handles[i],
-								 ACPI_PROCESSOR_LIMIT_INCREMENT);
-		/* Cooling off? */
-		else if (trend < 0) {
-			for (i = 0; i < passive->devices.count; i++)
-				/*
-				 * assume that we are on highest
-				 * freq/lowest thrott and can leave
-				 * passive mode, even in error case
-				 */
-				if (!acpi_processor_set_thermal_limit
-				    (passive->devices.handles[i],
-				     ACPI_PROCESSOR_LIMIT_DECREMENT))
-					result = 0;
-			/*
-			 * Leave cooling mode, even if the temp might
-			 * higher than trip point This is because some
-			 * machines might have long thermal polling
-			 * frequencies (tsp) defined. We will fall back
-			 * into passive mode in next cycle (probably quicker)
-			 */
-			if (result) {
-				passive->flags.enabled = 0;
-				ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-						  "Disabling passive cooling, still above threshold,"
-						  " but we are cooling down\n"));
-			}
-		}
-		return;
-	}
-
-	/*
-	 * Below Trip?
-	 * -----------
-	 * Implement passive cooling hysteresis to slowly increase performance
-	 * and avoid thrashing around the passive trip point.  Note that we
-	 * assume symmetry.
-	 */
-	if (!passive->flags.enabled)
-		return;
-	for (i = 0; i < passive->devices.count; i++)
-		if (!acpi_processor_set_thermal_limit
-		    (passive->devices.handles[i],
-		     ACPI_PROCESSOR_LIMIT_DECREMENT))
-			result = 0;
-	if (result) {
-		passive->flags.enabled = 0;
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "Disabling passive cooling (zone is cool)\n"));
-	}
-}
-
-static void acpi_thermal_active(struct acpi_thermal *tz)
-{
-	int result = 0;
-	struct acpi_thermal_active *active = NULL;
-	int i = 0;
-	int j = 0;
-	unsigned long maxtemp = 0;
-
-
-	if (!tz)
-		return;
-
-	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
-		active = &(tz->trips.active[i]);
-		if (!active || !active->flags.valid)
-			break;
-		if (tz->temperature >= active->temperature) {
-			/*
-			 * Above Threshold?
-			 * ----------------
-			 * If not already enabled, turn ON all cooling devices
-			 * associated with this active threshold.
-			 */
-			if (active->temperature > maxtemp)
-				tz->state.active_index = i;
-			maxtemp = active->temperature;
-			if (active->flags.enabled)
-				continue;
-			for (j = 0; j < active->devices.count; j++) {
-				result =
-				    acpi_bus_set_power(active->devices.
-						       handles[j],
-						       ACPI_STATE_D0);
-				if (result) {
-					printk(KERN_WARNING PREFIX
-						      "Unable to turn cooling device [%p] 'on'\n",
-						      active->devices.
-						      handles[j]);
-					continue;
-				}
-				active->flags.enabled = 1;
-				ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-						  "Cooling device [%p] now 'on'\n",
-						  active->devices.handles[j]));
-			}
-			continue;
-		}
-		if (!active->flags.enabled)
-			continue;
-		/*
-		 * Below Threshold?
-		 * ----------------
-		 * Turn OFF all cooling devices associated with this
-		 * threshold.
-		 */
-		for (j = 0; j < active->devices.count; j++) {
-			result = acpi_bus_set_power(active->devices.handles[j],
-						    ACPI_STATE_D3);
-			if (result) {
-				printk(KERN_WARNING PREFIX
-					      "Unable to turn cooling device [%p] 'off'\n",
-					      active->devices.handles[j]);
-				continue;
-			}
-			active->flags.enabled = 0;
-			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-					  "Cooling device [%p] now 'off'\n",
-					  active->devices.handles[j]));
-		}
-	}
-}
-
-static void acpi_thermal_check(void *context);
-
-static void acpi_thermal_run(unsigned long data)
-{
-	struct acpi_thermal *tz = (struct acpi_thermal *)data;
-	if (!tz->zombie)
-		acpi_os_execute(OSL_GPE_HANDLER, acpi_thermal_check, (void *)data);
-}
-
-static void acpi_thermal_active_off(void *data)
-{
-	int result = 0;
-	struct acpi_thermal *tz = data;
-	int i = 0;
-	int j = 0;
-	struct acpi_thermal_active *active = NULL;
-
-	if (!tz) {
-		printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
-		return;
-	}
-
-	result = acpi_thermal_get_temperature(tz);
-	if (result)
-		return;
-
-	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
-		active = &(tz->trips.active[i]);
-		if (!active || !active->flags.valid)
-			break;
-		if (tz->temperature >= active->temperature) {
-			/*
-			 * If the thermal temperature is greater than the
-			 * active threshod, unnecessary to turn off the
-			 * the active cooling device.
-			 */
-			continue;
-		}
-		/*
-		 * Below Threshold?
-		 * ----------------
-		 * Turn OFF all cooling devices associated with this
-		 * threshold.
-		 */
-		for (j = 0; j < active->devices.count; j++)
-			result = acpi_bus_set_power(active->devices.handles[j],
-						    ACPI_STATE_D3);
-	}
-}
-
 static void acpi_thermal_check(void *data)
 {
-	int result = 0;
 	struct acpi_thermal *tz = data;
-	unsigned long sleep_time = 0;
-	unsigned long timeout_jiffies = 0;
-	int i = 0;
-	struct acpi_thermal_state state;
 
-
-	if (!tz) {
-		printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
-		return;
-	}
-
-	/* Check if someone else is already running */
-	if (!mutex_trylock(&tz->lock))
-		return;
-
-	state = tz->state;
-
-	result = acpi_thermal_get_temperature(tz);
-	if (result)
-		goto unlock;
-
-	if (!tz->tz_enabled)
-		goto unlock;
-
-	memset(&tz->state, 0, sizeof(tz->state));
-
-	/*
-	 * Check Trip Points
-	 * -----------------
-	 * Compare the current temperature to the trip point values to see
-	 * if we've entered one of the thermal policy states.  Note that
-	 * this function determines when a state is entered, but the 
-	 * individual policy decides when it is exited (e.g. hysteresis).
-	 */
-	if (tz->trips.critical.flags.valid)
-		state.critical |=
-		    (tz->temperature >= tz->trips.critical.temperature);
-	if (tz->trips.hot.flags.valid)
-		state.hot |= (tz->temperature >= tz->trips.hot.temperature);
-	if (tz->trips.passive.flags.valid)
-		state.passive |=
-		    (tz->temperature >= tz->trips.passive.temperature);
-	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
-		if (tz->trips.active[i].flags.valid)
-			state.active |=
-			    (tz->temperature >=
-			     tz->trips.active[i].temperature);
-
-	/*
-	 * Invoke Policy
-	 * -------------
-	 * Separated from the above check to allow individual policy to 
-	 * determine when to exit a given state.
-	 */
-	if (state.critical)
-		acpi_thermal_critical(tz);
-	if (state.hot)
-		acpi_thermal_hot(tz);
-	if (state.passive)
-		acpi_thermal_passive(tz);
-	if (state.active)
-		acpi_thermal_active(tz);
-
-	/*
-	 * Calculate State
-	 * ---------------
-	 * Again, separated from the above two to allow independent policy
-	 * decisions.
-	 */
-	tz->state.critical = tz->trips.critical.flags.enabled;
-	tz->state.hot = tz->trips.hot.flags.enabled;
-	tz->state.passive = tz->trips.passive.flags.enabled;
-	tz->state.active = 0;
-	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
-		tz->state.active |= tz->trips.active[i].flags.enabled;
-
-	/*
-	 * Calculate Sleep Time
-	 * --------------------
-	 * If we're in the passive state, use _TSP's value.  Otherwise
-	 * use the default polling frequency (e.g. _TZP).  If no polling
-	 * frequency is specified then we'll wait forever (at least until
-	 * a thermal event occurs).  Note that _TSP and _TZD values are
-	 * given in 1/10th seconds (we must covert to milliseconds).
-	 */
-	if (tz->state.passive) {
-		sleep_time = tz->trips.passive.tsp * 100;
-		timeout_jiffies =  jiffies + (HZ * sleep_time) / 1000;
-	} else if (tz->polling_frequency > 0) {
-		sleep_time = tz->polling_frequency * 100;
-		timeout_jiffies =  round_jiffies(jiffies + (HZ * sleep_time) / 1000);
-	}
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n",
-			  tz->name, tz->temperature, sleep_time));
-
-	/*
-	 * Schedule Next Poll
-	 * ------------------
-	 */
-	if (!sleep_time) {
-		if (timer_pending(&(tz->timer)))
-			del_timer(&(tz->timer));
-	} else {
-		if (timer_pending(&(tz->timer)))
-			mod_timer(&(tz->timer), timeout_jiffies);
-		else {
-			tz->timer.data = (unsigned long)tz;
-			tz->timer.function = acpi_thermal_run;
-			tz->timer.expires = timeout_jiffies;
-			add_timer(&(tz->timer));
-		}
-	}
-      unlock:
-	mutex_unlock(&tz->lock);
+	thermal_zone_device_update(tz->thermal_zone);
 }
 
 /* sys I/F for generic thermal sysfs support */
 #define KELVIN_TO_MILLICELSIUS(t) (t * 100 - 273200)
 
-static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf)
+static int thermal_get_temp(struct thermal_zone_device *thermal,
+			    unsigned long *temp)
 {
 	struct acpi_thermal *tz = thermal->devdata;
 	int result;
@@ -966,25 +596,28 @@
 	if (result)
 		return result;
 
-	return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(tz->temperature));
+	*temp = KELVIN_TO_MILLICELSIUS(tz->temperature);
+	return 0;
 }
 
 static const char enabled[] = "kernel";
 static const char disabled[] = "user";
 static int thermal_get_mode(struct thermal_zone_device *thermal,
-				char *buf)
+				enum thermal_device_mode *mode)
 {
 	struct acpi_thermal *tz = thermal->devdata;
 
 	if (!tz)
 		return -EINVAL;
 
-	return sprintf(buf, "%s\n", tz->tz_enabled ?
-			enabled : disabled);
+	*mode = tz->tz_enabled ? THERMAL_DEVICE_ENABLED :
+		THERMAL_DEVICE_DISABLED;
+
+	return 0;
 }
 
 static int thermal_set_mode(struct thermal_zone_device *thermal,
-				const char *buf)
+				enum thermal_device_mode mode)
 {
 	struct acpi_thermal *tz = thermal->devdata;
 	int enable;
@@ -995,9 +628,9 @@
 	/*
 	 * enable/disable thermal management from ACPI thermal driver
 	 */
-	if (!strncmp(buf, enabled, sizeof enabled - 1))
+	if (mode == THERMAL_DEVICE_ENABLED)
 		enable = 1;
-	else if (!strncmp(buf, disabled, sizeof disabled - 1))
+	else if (mode == THERMAL_DEVICE_DISABLED)
 		enable = 0;
 	else
 		return -EINVAL;
@@ -1013,7 +646,7 @@
 }
 
 static int thermal_get_trip_type(struct thermal_zone_device *thermal,
-				 int trip, char *buf)
+				 int trip, enum thermal_trip_type *type)
 {
 	struct acpi_thermal *tz = thermal->devdata;
 	int i;
@@ -1022,27 +655,35 @@
 		return -EINVAL;
 
 	if (tz->trips.critical.flags.valid) {
-		if (!trip)
-			return sprintf(buf, "critical\n");
+		if (!trip) {
+			*type = THERMAL_TRIP_CRITICAL;
+			return 0;
+		}
 		trip--;
 	}
 
 	if (tz->trips.hot.flags.valid) {
-		if (!trip)
-			return sprintf(buf, "hot\n");
+		if (!trip) {
+			*type = THERMAL_TRIP_HOT;
+			return 0;
+		}
 		trip--;
 	}
 
 	if (tz->trips.passive.flags.valid) {
-		if (!trip)
-			return sprintf(buf, "passive\n");
+		if (!trip) {
+			*type = THERMAL_TRIP_PASSIVE;
+			return 0;
+		}
 		trip--;
 	}
 
 	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
 		tz->trips.active[i].flags.valid; i++) {
-		if (!trip)
-			return sprintf(buf, "active%d\n", i);
+		if (!trip) {
+			*type = THERMAL_TRIP_ACTIVE;
+			return 0;
+		}
 		trip--;
 	}
 
@@ -1050,7 +691,7 @@
 }
 
 static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
-				 int trip, char *buf)
+				 int trip, unsigned long *temp)
 {
 	struct acpi_thermal *tz = thermal->devdata;
 	int i;
@@ -1059,31 +700,39 @@
 		return -EINVAL;
 
 	if (tz->trips.critical.flags.valid) {
-		if (!trip)
-			return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
-				tz->trips.critical.temperature));
+		if (!trip) {
+			*temp = KELVIN_TO_MILLICELSIUS(
+				tz->trips.critical.temperature);
+			return 0;
+		}
 		trip--;
 	}
 
 	if (tz->trips.hot.flags.valid) {
-		if (!trip)
-			return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
-					tz->trips.hot.temperature));
+		if (!trip) {
+			*temp = KELVIN_TO_MILLICELSIUS(
+				tz->trips.hot.temperature);
+			return 0;
+		}
 		trip--;
 	}
 
 	if (tz->trips.passive.flags.valid) {
-		if (!trip)
-			return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
-					tz->trips.passive.temperature));
+		if (!trip) {
+			*temp = KELVIN_TO_MILLICELSIUS(
+				tz->trips.passive.temperature);
+			return 0;
+		}
 		trip--;
 	}
 
 	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
 		tz->trips.active[i].flags.valid; i++) {
-		if (!trip)
-			return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
-					tz->trips.active[i].temperature));
+		if (!trip) {
+			*temp = KELVIN_TO_MILLICELSIUS(
+				tz->trips.active[i].temperature);
+			return 0;
+		}
 		trip--;
 	}
 
@@ -1102,6 +751,29 @@
 		return -EINVAL;
 }
 
+static int thermal_notify(struct thermal_zone_device *thermal, int trip,
+			   enum thermal_trip_type trip_type)
+{
+	u8 type = 0;
+	struct acpi_thermal *tz = thermal->devdata;
+
+	if (trip_type == THERMAL_TRIP_CRITICAL)
+		type = ACPI_THERMAL_NOTIFY_CRITICAL;
+	else if (trip_type == THERMAL_TRIP_HOT)
+		type = ACPI_THERMAL_NOTIFY_HOT;
+	else
+		return 0;
+
+	acpi_bus_generate_proc_event(tz->device, type, 1);
+	acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
+					dev_name(&tz->device->dev), type, 1);
+
+	if (trip_type == THERMAL_TRIP_CRITICAL && nocrt)
+		return 1;
+
+	return 0;
+}
+
 typedef int (*cb)(struct thermal_zone_device *, int,
 		  struct thermal_cooling_device *);
 static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
@@ -1194,6 +866,7 @@
 	.get_trip_type = thermal_get_trip_type,
 	.get_trip_temp = thermal_get_trip_temp,
 	.get_crit_temp = thermal_get_crit_temp,
+	.notify = thermal_notify,
 };
 
 static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
@@ -1214,8 +887,21 @@
 
 	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
 			tz->trips.active[i].flags.valid; i++, trips++);
-	tz->thermal_zone = thermal_zone_device_register("acpitz",
-					trips, tz, &acpi_thermal_zone_ops);
+
+	if (tz->trips.passive.flags.valid)
+		tz->thermal_zone =
+			thermal_zone_device_register("acpitz", trips, tz,
+						     &acpi_thermal_zone_ops,
+						     tz->trips.passive.tc1,
+						     tz->trips.passive.tc2,
+						     tz->trips.passive.tsp*100,
+						     tz->polling_frequency*100);
+	else
+		tz->thermal_zone =
+			thermal_zone_device_register("acpitz", trips, tz,
+						     &acpi_thermal_zone_ops,
+						     0, 0, 0,
+						     tz->polling_frequency);
 	if (IS_ERR(tz->thermal_zone))
 		return -ENODEV;
 
@@ -1447,13 +1133,13 @@
 	if (!tz)
 		goto end;
 
-	if (!tz->polling_frequency) {
+	if (!tz->thermal_zone->polling_delay) {
 		seq_puts(seq, "<polling disabled>\n");
 		goto end;
 	}
 
-	seq_printf(seq, "polling frequency:       %lu seconds\n",
-		   (tz->polling_frequency / 10));
+	seq_printf(seq, "polling frequency:       %d seconds\n",
+		   (tz->thermal_zone->polling_delay / 1000));
 
       end:
 	return 0;
@@ -1682,12 +1368,6 @@
 	if (result)
 		goto unregister_thermal_zone;
 
-	init_timer(&tz->timer);
-
-	acpi_thermal_active_off(tz);
-
-	acpi_thermal_check(tz);
-
 	status = acpi_install_notify_handler(device->handle,
 					     ACPI_DEVICE_NOTIFY,
 					     acpi_thermal_notify, tz);
@@ -1716,36 +1396,15 @@
 	acpi_status status = AE_OK;
 	struct acpi_thermal *tz = NULL;
 
-
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
 
 	tz = acpi_driver_data(device);
 
-	/* avoid timer adding new defer task */
-	tz->zombie = 1;
-	/* wait for running timer (on other CPUs) finish */
-	del_timer_sync(&(tz->timer));
-	/* synchronize deferred task */
-	acpi_os_wait_events_complete(NULL);
-	/* deferred task may reinsert timer */
-	del_timer_sync(&(tz->timer));
-
 	status = acpi_remove_notify_handler(device->handle,
 					    ACPI_DEVICE_NOTIFY,
 					    acpi_thermal_notify);
 
-	/* Terminate policy */
-	if (tz->trips.passive.flags.valid && tz->trips.passive.flags.enabled) {
-		tz->trips.passive.flags.enabled = 0;
-		acpi_thermal_passive(tz);
-	}
-	if (tz->trips.active[0].flags.valid
-	    && tz->trips.active[0].flags.enabled) {
-		tz->trips.active[0].flags.enabled = 0;
-		acpi_thermal_active(tz);
-	}
-
 	acpi_thermal_remove_fs(device);
 	acpi_thermal_unregister_thermal_zone(tz);
 	mutex_destroy(&tz->lock);
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 67cc36d..ab06143 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -37,6 +37,8 @@
 #include <linux/thermal.h>
 #include <linux/video_output.h>
 #include <linux/sort.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
 #include <asm/uaccess.h>
 
 #include <acpi/acpi_bus.h>
@@ -162,16 +164,26 @@
 	u8 _BCL:1;		/*Query list of brightness control levels supported */
 	u8 _BCM:1;		/*Set the brightness level */
 	u8 _BQC:1;		/* Get current brightness level */
+	u8 _BCQ:1;		/* Some buggy BIOS uses _BCQ instead of _BQC */
 	u8 _DDC:1;		/*Return the EDID for this device */
 	u8 _DCS:1;		/*Return status of output device */
 	u8 _DGS:1;		/*Query graphics state */
 	u8 _DSS:1;		/*Device state set */
 };
 
+struct acpi_video_brightness_flags {
+	u8 _BCL_no_ac_battery_levels:1;	/* no AC/Battery levels in _BCL */
+	u8 _BCL_reversed:1;		/* _BCL package is in a reversed order*/
+	u8 _BCL_use_index:1;		/* levels in _BCL are index values */
+	u8 _BCM_use_index:1;		/* input of _BCM is an index value */
+	u8 _BQC_use_index:1;		/* _BQC returns an index value */
+};
+
 struct acpi_video_device_brightness {
 	int curr;
 	int count;
 	int *levels;
+	struct acpi_video_brightness_flags flags;
 };
 
 struct acpi_video_device {
@@ -189,7 +201,7 @@
 
 /* bus */
 static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_video_bus_info_fops = {
+static const struct file_operations acpi_video_bus_info_fops = {
 	.owner = THIS_MODULE,
 	.open = acpi_video_bus_info_open_fs,
 	.read = seq_read,
@@ -198,7 +210,7 @@
 };
 
 static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_video_bus_ROM_fops = {
+static const struct file_operations acpi_video_bus_ROM_fops = {
 	.owner = THIS_MODULE,
 	.open = acpi_video_bus_ROM_open_fs,
 	.read = seq_read,
@@ -208,7 +220,7 @@
 
 static int acpi_video_bus_POST_info_open_fs(struct inode *inode,
 					    struct file *file);
-static struct file_operations acpi_video_bus_POST_info_fops = {
+static const struct file_operations acpi_video_bus_POST_info_fops = {
 	.owner = THIS_MODULE,
 	.open = acpi_video_bus_POST_info_open_fs,
 	.read = seq_read,
@@ -217,19 +229,25 @@
 };
 
 static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_video_bus_POST_fops = {
+static ssize_t acpi_video_bus_write_POST(struct file *file,
+	const char __user *buffer, size_t count, loff_t *data);
+static const struct file_operations acpi_video_bus_POST_fops = {
 	.owner = THIS_MODULE,
 	.open = acpi_video_bus_POST_open_fs,
 	.read = seq_read,
+	.write = acpi_video_bus_write_POST,
 	.llseek = seq_lseek,
 	.release = single_release,
 };
 
 static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_video_bus_DOS_fops = {
+static ssize_t acpi_video_bus_write_DOS(struct file *file,
+	const char __user *buffer, size_t count, loff_t *data);
+static const struct file_operations acpi_video_bus_DOS_fops = {
 	.owner = THIS_MODULE,
 	.open = acpi_video_bus_DOS_open_fs,
 	.read = seq_read,
+	.write = acpi_video_bus_write_DOS,
 	.llseek = seq_lseek,
 	.release = single_release,
 };
@@ -237,7 +255,7 @@
 /* device */
 static int acpi_video_device_info_open_fs(struct inode *inode,
 					  struct file *file);
-static struct file_operations acpi_video_device_info_fops = {
+static const struct file_operations acpi_video_device_info_fops = {
 	.owner = THIS_MODULE,
 	.open = acpi_video_device_info_open_fs,
 	.read = seq_read,
@@ -247,27 +265,33 @@
 
 static int acpi_video_device_state_open_fs(struct inode *inode,
 					   struct file *file);
-static struct file_operations acpi_video_device_state_fops = {
+static ssize_t acpi_video_device_write_state(struct file *file,
+	const char __user *buffer, size_t count, loff_t *data);
+static const struct file_operations acpi_video_device_state_fops = {
 	.owner = THIS_MODULE,
 	.open = acpi_video_device_state_open_fs,
 	.read = seq_read,
+	.write = acpi_video_device_write_state,
 	.llseek = seq_lseek,
 	.release = single_release,
 };
 
 static int acpi_video_device_brightness_open_fs(struct inode *inode,
 						struct file *file);
+static ssize_t acpi_video_device_write_brightness(struct file *file,
+	const char __user *buffer, size_t count, loff_t *data);
 static struct file_operations acpi_video_device_brightness_fops = {
 	.owner = THIS_MODULE,
 	.open = acpi_video_device_brightness_open_fs,
 	.read = seq_read,
+	.write = acpi_video_device_write_brightness,
 	.llseek = seq_lseek,
 	.release = single_release,
 };
 
 static int acpi_video_device_EDID_open_fs(struct inode *inode,
 					  struct file *file);
-static struct file_operations acpi_video_device_EDID_fops = {
+static const struct file_operations acpi_video_device_EDID_fops = {
 	.owner = THIS_MODULE,
 	.open = acpi_video_device_EDID_open_fs,
 	.read = seq_read,
@@ -275,7 +299,7 @@
 	.release = single_release,
 };
 
-static char device_decode[][30] = {
+static const char device_decode[][30] = {
 	"motherboard VGA device",
 	"PCI VGA device",
 	"AGP VGA device",
@@ -294,7 +318,7 @@
 			unsigned long long *level);
 static int acpi_video_get_next_level(struct acpi_video_device *device,
 				     u32 level_current, u32 event);
-static void acpi_video_switch_brightness(struct acpi_video_device *device,
+static int acpi_video_switch_brightness(struct acpi_video_device *device,
 					 int event);
 static int acpi_video_device_get_state(struct acpi_video_device *device,
 			    unsigned long long *state);
@@ -308,7 +332,9 @@
 	int i;
 	struct acpi_video_device *vd =
 		(struct acpi_video_device *)bl_get_data(bd);
-	acpi_video_device_lcd_get_level_current(vd, &cur_level);
+
+	if (acpi_video_device_lcd_get_level_current(vd, &cur_level))
+		return -EINVAL;
 	for (i = 2; i < vd->brightness->count; i++) {
 		if (vd->brightness->levels[i] == cur_level)
 			/* The first two entries are special - see page 575
@@ -320,12 +346,12 @@
 
 static int acpi_video_set_brightness(struct backlight_device *bd)
 {
-	int request_level = bd->props.brightness+2;
+	int request_level = bd->props.brightness + 2;
 	struct acpi_video_device *vd =
 		(struct acpi_video_device *)bl_get_data(bd);
-	acpi_video_device_lcd_set_level(vd,
-					vd->brightness->levels[request_level]);
-	return 0;
+
+	return acpi_video_device_lcd_set_level(vd,
+				vd->brightness->levels[request_level]);
 }
 
 static struct backlight_ops acpi_backlight_ops = {
@@ -358,32 +384,37 @@
 
 
 /* thermal cooling device callbacks */
-static int video_get_max_state(struct thermal_cooling_device *cdev, char *buf)
+static int video_get_max_state(struct thermal_cooling_device *cdev, unsigned
+			       long *state)
 {
 	struct acpi_device *device = cdev->devdata;
 	struct acpi_video_device *video = acpi_driver_data(device);
 
-	return sprintf(buf, "%d\n", video->brightness->count - 3);
+	*state = video->brightness->count - 3;
+	return 0;
 }
 
-static int video_get_cur_state(struct thermal_cooling_device *cdev, char *buf)
+static int video_get_cur_state(struct thermal_cooling_device *cdev, unsigned
+			       long *state)
 {
 	struct acpi_device *device = cdev->devdata;
 	struct acpi_video_device *video = acpi_driver_data(device);
 	unsigned long long level;
-	int state;
+	int offset;
 
-	acpi_video_device_lcd_get_level_current(video, &level);
-	for (state = 2; state < video->brightness->count; state++)
-		if (level == video->brightness->levels[state])
-			return sprintf(buf, "%d\n",
-				       video->brightness->count - state - 1);
+	if (acpi_video_device_lcd_get_level_current(video, &level))
+		return -EINVAL;
+	for (offset = 2; offset < video->brightness->count; offset++)
+		if (level == video->brightness->levels[offset]) {
+			*state = video->brightness->count - offset - 1;
+			return 0;
+		}
 
 	return -EINVAL;
 }
 
 static int
-video_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state)
+video_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
 {
 	struct acpi_device *device = cdev->devdata;
 	struct acpi_video_device *video = acpi_driver_data(device);
@@ -479,34 +510,68 @@
 static int
 acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
 {
-	int status = AE_OK;
+	int status;
 	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
 	struct acpi_object_list args = { 1, &arg0 };
 	int state;
 
-
 	arg0.integer.value = level;
 
-	if (device->cap._BCM)
-		status = acpi_evaluate_object(device->dev->handle, "_BCM",
-					      &args, NULL);
+	status = acpi_evaluate_object(device->dev->handle, "_BCM",
+				      &args, NULL);
+	if (ACPI_FAILURE(status)) {
+		ACPI_ERROR((AE_INFO, "Evaluating _BCM failed"));
+		return -EIO;
+	}
+
 	device->brightness->curr = level;
 	for (state = 2; state < device->brightness->count; state++)
-		if (level == device->brightness->levels[state])
-			device->backlight->props.brightness = state - 2;
+		if (level == device->brightness->levels[state]) {
+			if (device->backlight)
+				device->backlight->props.brightness = state - 2;
+			return 0;
+		}
 
-	return status;
+	ACPI_ERROR((AE_INFO, "Current brightness invalid"));
+	return -EINVAL;
 }
 
 static int
 acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
 					unsigned long long *level)
 {
-	if (device->cap._BQC)
-		return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL,
-					     level);
+	acpi_status status = AE_OK;
+
+	if (device->cap._BQC || device->cap._BCQ) {
+		char *buf = device->cap._BQC ? "_BQC" : "_BCQ";
+
+		status = acpi_evaluate_integer(device->dev->handle, buf,
+						NULL, level);
+		if (ACPI_SUCCESS(status)) {
+			if (device->brightness->flags._BQC_use_index) {
+				if (device->brightness->flags._BCL_reversed)
+					*level = device->brightness->count
+								 - 3 - (*level);
+				*level = device->brightness->levels[*level + 2];
+
+			}
+			device->brightness->curr = *level;
+			return 0;
+		} else {
+			/* Fixme:
+			 * should we return an error or ignore this failure?
+			 * dev->brightness->curr is a cached value which stores
+			 * the correct current backlight level in most cases.
+			 * ACPI video backlight still works w/ buggy _BQC.
+			 * http://bugzilla.kernel.org/show_bug.cgi?id=12233
+			 */
+			ACPI_WARNING((AE_INFO, "Evaluating %s failed", buf));
+			device->cap._BQC = device->cap._BCQ = 0;
+		}
+	}
+
 	*level = device->brightness->curr;
-	return AE_OK;
+	return 0;
 }
 
 static int
@@ -655,9 +720,11 @@
 acpi_video_init_brightness(struct acpi_video_device *device)
 {
 	union acpi_object *obj = NULL;
-	int i, max_level = 0, count = 0;
+	int i, max_level = 0, count = 0, level_ac_battery = 0;
+	unsigned long long level, level_old;
 	union acpi_object *o;
 	struct acpi_video_device_brightness *br = NULL;
+	int result = -EINVAL;
 
 	if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available "
@@ -671,13 +738,16 @@
 	br = kzalloc(sizeof(*br), GFP_KERNEL);
 	if (!br) {
 		printk(KERN_ERR "can't allocate memory\n");
+		result = -ENOMEM;
 		goto out;
 	}
 
-	br->levels = kmalloc(obj->package.count * sizeof *(br->levels),
+	br->levels = kmalloc((obj->package.count + 2) * sizeof *(br->levels),
 				GFP_KERNEL);
-	if (!br->levels)
+	if (!br->levels) {
+		result = -ENOMEM;
 		goto out_free;
+	}
 
 	for (i = 0; i < obj->package.count; i++) {
 		o = (union acpi_object *)&obj->package.elements[i];
@@ -692,18 +762,86 @@
 		count++;
 	}
 
-	/* don't sort the first two brightness levels */
-	sort(&br->levels[2], count - 2, sizeof(br->levels[2]),
-		acpi_video_cmp_level, NULL);
+	/*
+	 * some buggy BIOS don't export the levels
+	 * when machine is on AC/Battery in _BCL package.
+	 * In this case, the first two elements in _BCL packages
+	 * are also supported brightness levels that OS should take care of.
+	 */
+	for (i = 2; i < count; i++)
+		if (br->levels[i] == br->levels[0] ||
+		    br->levels[i] == br->levels[1])
+			level_ac_battery++;
 
-	if (count < 2)
-		goto out_free_levels;
+	if (level_ac_battery < 2) {
+		level_ac_battery = 2 - level_ac_battery;
+		br->flags._BCL_no_ac_battery_levels = 1;
+		for (i = (count - 1 + level_ac_battery); i >= 2; i--)
+			br->levels[i] = br->levels[i - level_ac_battery];
+		count += level_ac_battery;
+	} else if (level_ac_battery > 2)
+		ACPI_ERROR((AE_INFO, "Too many duplicates in _BCL package\n"));
+
+	/* Check if the _BCL package is in a reversed order */
+	if (max_level == br->levels[2]) {
+		br->flags._BCL_reversed = 1;
+		sort(&br->levels[2], count - 2, sizeof(br->levels[2]),
+			acpi_video_cmp_level, NULL);
+	} else if (max_level != br->levels[count - 1])
+		ACPI_ERROR((AE_INFO,
+			    "Found unordered _BCL package\n"));
 
 	br->count = count;
 	device->brightness = br;
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count));
+
+	/* Check the input/output of _BQC/_BCL/_BCM */
+	if ((max_level < 100) && (max_level <= (count - 2)))
+		br->flags._BCL_use_index = 1;
+
+	/*
+	 * _BCM is always consistent with _BCL,
+	 * at least for all the laptops we have ever seen.
+	 */
+	br->flags._BCM_use_index = br->flags._BCL_use_index;
+
+	/* _BQC uses INDEX while _BCL uses VALUE in some laptops */
+	br->curr = max_level;
+	result = acpi_video_device_lcd_get_level_current(device, &level_old);
+	if (result)
+		goto out_free_levels;
+
+	result = acpi_video_device_lcd_set_level(device, br->curr);
+	if (result)
+		goto out_free_levels;
+
+	result = acpi_video_device_lcd_get_level_current(device, &level);
+	if (result)
+		goto out_free_levels;
+
+	if ((level != level_old) && !br->flags._BCM_use_index) {
+		/* Note:
+		 * This piece of code does not work correctly if the current
+		 * brightness levels is 0.
+		 * But I guess boxes that boot with such a dark screen are rare
+		 * and no more code is needed to cover this specifial case.
+		 */
+
+		if (level_ac_battery != 2) {
+			/*
+			 * For now, we don't support the _BCL like this:
+			 * 16, 15, 0, 1, 2, 3, ..., 14, 15, 16
+			 * because we may mess up the index returned by _BQC.
+			 * Plus: we have not got a box like this.
+			 */
+			ACPI_ERROR((AE_INFO, "_BCL not supported\n"));
+		}
+		br->flags._BQC_use_index = 1;
+	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			  "found %d brightness levels\n", count - 2));
 	kfree(obj);
-	return max_level;
+	return result;
 
 out_free_levels:
 	kfree(br->levels);
@@ -712,7 +850,7 @@
 out:
 	device->brightness = NULL;
 	kfree(obj);
-	return 0;
+	return result;
 }
 
 /*
@@ -729,7 +867,6 @@
 static void acpi_video_device_find_cap(struct acpi_video_device *device)
 {
 	acpi_handle h_dummy1;
-	u32 max_level = 0;
 
 
 	memset(&device->cap, 0, sizeof(device->cap));
@@ -745,6 +882,12 @@
 	}
 	if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1)))
 		device->cap._BQC = 1;
+	else if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCQ",
+				&h_dummy1))) {
+		printk(KERN_WARNING FW_BUG "_BCQ is used instead of _BQC\n");
+		device->cap._BCQ = 1;
+	}
+
 	if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) {
 		device->cap._DDC = 1;
 	}
@@ -758,13 +901,14 @@
 		device->cap._DSS = 1;
 	}
 
-	if (acpi_video_backlight_support())
-		max_level = acpi_video_init_brightness(device);
-
-	if (device->cap._BCL && device->cap._BCM && max_level > 0) {
+	if (acpi_video_backlight_support()) {
 		int result;
 		static int count = 0;
 		char *name;
+
+		result = acpi_video_init_brightness(device);
+		if (result)
+			return;
 		name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
 		if (!name)
 			return;
@@ -773,18 +917,6 @@
 		device->backlight = backlight_device_register(name,
 			NULL, device, &acpi_backlight_ops);
 		device->backlight->props.max_brightness = device->brightness->count-3;
-		/*
-		 * If there exists the _BQC object, the _BQC object will be
-		 * called to get the current backlight brightness. Otherwise
-		 * the brightness will be set to the maximum.
-		 */
-		if (device->cap._BQC)
-			device->backlight->props.brightness =
-				acpi_video_get_brightness(device->backlight);
-		else
-			device->backlight->props.brightness =
-				device->backlight->props.max_brightness;
-		backlight_update_status(device->backlight);
 		kfree(name);
 
 		device->cdev = thermal_cooling_device_register("LCD",
@@ -1061,13 +1193,12 @@
 	/* validate through the list of available levels */
 	for (i = 2; i < dev->brightness->count; i++)
 		if (level == dev->brightness->levels[i]) {
-			if (ACPI_SUCCESS
-			    (acpi_video_device_lcd_set_level(dev, level)))
-				dev->brightness->curr = level;
+			if (!acpi_video_device_lcd_set_level(dev, level))
+				return count;
 			break;
 		}
 
-	return count;
+	return -EINVAL;
 }
 
 static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset)
@@ -1132,7 +1263,6 @@
 		goto err_remove_dir;
 
 	/* 'state' [R/W] */
-	acpi_video_device_state_fops.write = acpi_video_device_write_state;
 	entry = proc_create_data("state", S_IFREG | S_IRUGO | S_IWUSR,
 				 device_dir,
 				 &acpi_video_device_state_fops,
@@ -1141,8 +1271,6 @@
 		goto err_remove_info;
 
 	/* 'brightness' [R/W] */
-	acpi_video_device_brightness_fops.write =
-		acpi_video_device_write_brightness;
 	entry = proc_create_data("brightness", S_IFREG | S_IRUGO | S_IWUSR,
 				 device_dir,
 				 &acpi_video_device_brightness_fops,
@@ -1423,7 +1551,6 @@
 		goto err_remove_rom;
 
 	/* 'POST' [R/W] */
-	acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST;
 	entry = proc_create_data("POST", S_IFREG | S_IRUGO | S_IWUSR,
 				 device_dir,
 				 &acpi_video_bus_POST_fops,
@@ -1432,7 +1559,6 @@
 		goto err_remove_post_info;
 
 	/* 'DOS' [R/W] */
-	acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS;
 	entry = proc_create_data("DOS", S_IFREG | S_IRUGO | S_IWUSR,
 				 device_dir,
 				 &acpi_video_bus_DOS_fops,
@@ -1745,15 +1871,29 @@
 	}
 }
 
-static void
+static int
 acpi_video_switch_brightness(struct acpi_video_device *device, int event)
 {
 	unsigned long long level_current, level_next;
+	int result = -EINVAL;
+
 	if (!device->brightness)
-		return;
-	acpi_video_device_lcd_get_level_current(device, &level_current);
+		goto out;
+
+	result = acpi_video_device_lcd_get_level_current(device,
+							 &level_current);
+	if (result)
+		goto out;
+
 	level_next = acpi_video_get_next_level(device, level_current, event);
-	acpi_video_device_lcd_set_level(device, level_next);
+
+	result = acpi_video_device_lcd_set_level(device, level_next);
+
+out:
+	if (result)
+		printk(KERN_ERR PREFIX "Failed to switch the brightness\n");
+
+	return result;
 }
 
 static int
@@ -2120,7 +2260,27 @@
 	return 0;
 }
 
-static int __init acpi_video_init(void)
+static int __init intel_opregion_present(void)
+{
+#if defined(CONFIG_DRM_I915) || defined(CONFIG_DRM_I915_MODULE)
+	struct pci_dev *dev = NULL;
+	u32 address;
+
+	for_each_pci_dev(dev) {
+		if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
+			continue;
+		if (dev->vendor != PCI_VENDOR_ID_INTEL)
+			continue;
+		pci_read_config_dword(dev, 0xfc, &address);
+		if (!address)
+			continue;
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+int acpi_video_register(void)
 {
 	int result = 0;
 
@@ -2136,6 +2296,22 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(acpi_video_register);
+
+/*
+ * This is kind of nasty. Hardware using Intel chipsets may require
+ * the video opregion code to be run first in order to initialise
+ * state before any ACPI video calls are made. To handle this we defer
+ * registration of the video class until the opregion code has run.
+ */
+
+static int __init acpi_video_init(void)
+{
+	if (intel_opregion_present())
+		return 0;
+
+	return acpi_video_register();
+}
 
 static void __exit acpi_video_exit(void)
 {
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index 50e3d2d..0973727 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -55,6 +55,9 @@
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight "
 				  "support\n"));
 		*cap |= ACPI_VIDEO_BACKLIGHT;
+		if (ACPI_FAILURE(acpi_get_handle(handle, "_BQC", &h_dummy)))
+			printk(KERN_WARNING FW_BUG PREFIX "ACPI brightness "
+					"control misses _BQC function\n");
 		/* We have backlight support, no need to scan further */
 		return AE_CTRL_TERMINATE;
 	}
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c
index 2d34806..5aee8c2 100644
--- a/drivers/acpi/wakeup.c
+++ b/drivers/acpi/wakeup.c
@@ -8,6 +8,8 @@
 #include <acpi/acpi_drivers.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
+
+#include "internal.h"
 #include "sleep.h"
 
 #define _COMPONENT		ACPI_SYSTEM_COMPONENT
@@ -136,13 +138,10 @@
 	spin_unlock(&acpi_device_lock);
 }
 
-static int __init acpi_wakeup_device_init(void)
+int __init acpi_wakeup_device_init(void)
 {
 	struct list_head *node, *next;
 
-	if (acpi_disabled)
-		return 0;
-
 	spin_lock(&acpi_device_lock);
 	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
 		struct acpi_device *dev = container_of(node,
@@ -163,5 +162,3 @@
 	spin_unlock(&acpi_device_lock);
 	return 0;
 }
-
-late_initcall(acpi_wakeup_device_init);
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 0bcf264..9120717 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -86,7 +86,7 @@
 
 	  For users with exclusively modern controllers like AHCI,
 	  Silicon Image 3124, or Marvell 6440, you may choose to
-	  disable this uneeded SFF support.
+	  disable this unneeded SFF support.
 
 	  If unsure, say Y.
 
diff --git a/drivers/base/iommu.c b/drivers/base/iommu.c
index c2d1eed..9f0e672 100644
--- a/drivers/base/iommu.c
+++ b/drivers/base/iommu.c
@@ -98,3 +98,10 @@
 	return iommu_ops->iova_to_phys(domain, iova);
 }
 EXPORT_SYMBOL_GPL(iommu_iova_to_phys);
+
+int iommu_domain_has_cap(struct iommu_domain *domain,
+			 unsigned long cap)
+{
+	return iommu_ops->domain_has_cap(domain, cap);
+}
+EXPORT_SYMBOL_GPL(iommu_domain_has_cap);
diff --git a/drivers/base/node.c b/drivers/base/node.c
index f8f578a..40b8097 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -24,7 +24,7 @@
 static ssize_t node_read_cpumap(struct sys_device *dev, int type, char *buf)
 {
 	struct node *node_dev = to_node(dev);
-	node_to_cpumask_ptr(mask, node_dev->sysdev.id);
+	const struct cpumask *mask = cpumask_of_node(node_dev->sysdev.id);
 	int len;
 
 	/* 2008/04/07: buf currently PAGE_SIZE, need 9 chars per 32 bits. */
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
index 76ce75b..3236b43 100644
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -300,7 +300,7 @@
  *	and the class driver.
  *
  *	Note: The list is iterated in reverse order, so that we shut down
- *	child devices before we shut down thier parents. The list ordering
+ *	child devices before we shut down their parents. The list ordering
  *	is guaranteed by virtue of the fact that child devices are registered
  *	after their parents.
  */
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 45c5a33..31693bc 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -4,6 +4,7 @@
  * Filesystem request handling methods
  */
 
+#include <linux/ata.h>
 #include <linux/hdreg.h>
 #include <linux/blkdev.h>
 #include <linux/skbuff.h>
@@ -267,7 +268,7 @@
 		writebit = 0;
 	}
 
-	ah->cmdstat = WIN_READ | writebit | extbit;
+	ah->cmdstat = ATA_CMD_PIO_READ | writebit | extbit;
 
 	/* mark all tracking fields and load out */
 	buf->nframesout += 1;
@@ -362,10 +363,10 @@
 	switch (ah->cmdstat) {
 	default:
 		break;
-	case WIN_READ:
-	case WIN_READ_EXT:
-	case WIN_WRITE:
-	case WIN_WRITE_EXT:
+	case ATA_CMD_PIO_READ:
+	case ATA_CMD_PIO_READ_EXT:
+	case ATA_CMD_PIO_WRITE:
+	case ATA_CMD_PIO_WRITE_EXT:
 		put_lba(ah, f->lba);
 
 		n = f->bcnt;
@@ -812,8 +813,8 @@
 			d->htgt = NULL;
 		n = ahout->scnt << 9;
 		switch (ahout->cmdstat) {
-		case WIN_READ:
-		case WIN_READ_EXT:
+		case ATA_CMD_PIO_READ:
+		case ATA_CMD_PIO_READ_EXT:
 			if (skb->len - sizeof *hin - sizeof *ahin < n) {
 				printk(KERN_ERR
 					"aoe: %s.  skb->len=%d need=%ld\n",
@@ -823,8 +824,8 @@
 				return;
 			}
 			memcpy(f->bufaddr, ahin+1, n);
-		case WIN_WRITE:
-		case WIN_WRITE_EXT:
+		case ATA_CMD_PIO_WRITE:
+		case ATA_CMD_PIO_WRITE_EXT:
 			ifp = getif(t, skb->dev);
 			if (ifp) {
 				ifp->lost = 0;
@@ -838,7 +839,7 @@
 				goto xmit;
 			}
 			break;
-		case WIN_IDENTIFY:
+		case ATA_CMD_ID_ATA:
 			if (skb->len - sizeof *hin - sizeof *ahin < 512) {
 				printk(KERN_INFO
 					"aoe: runt data size in ataid.  skb->len=%d\n",
@@ -914,7 +915,7 @@
 
 	/* set up ata header */
 	ah->scnt = 1;
-	ah->cmdstat = WIN_IDENTIFY;
+	ah->cmdstat = ATA_CMD_ID_ATA;
 	ah->lba3 = 0xa0;
 
 	skb->dev = t->ifp->nd;
diff --git a/drivers/block/hd.c b/drivers/block/hd.c
index 482c0c4..3c11f06 100644
--- a/drivers/block/hd.c
+++ b/drivers/block/hd.c
@@ -42,6 +42,8 @@
 #include <linux/ata.h>
 #include <linux/hdreg.h>
 
+#define HD_IRQ 14
+
 #define REALLY_SLOW_IO
 #include <asm/system.h>
 #include <asm/io.h>
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index 119be34..6cccdc3 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -89,6 +89,7 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/blkdev.h>
+#include <linux/ata.h>
 #include <linux/hdreg.h>
 #include <linux/platform_device.h>
 #if defined(CONFIG_OF)
@@ -208,7 +209,7 @@
 	struct gendisk *gd;
 
 	/* Inserted CF card parameters */
-	struct hd_driveid cf_id;
+	u16 cf_id[ATA_ID_WORDS];
 };
 
 static int ace_major;
@@ -402,21 +403,14 @@
 		 ace_in32(ace, ACE_CFGLBA), ace_in(ace, ACE_FATSTAT));
 }
 
-void ace_fix_driveid(struct hd_driveid *id)
+void ace_fix_driveid(u16 *id)
 {
 #if defined(__BIG_ENDIAN)
-	u16 *buf = (void *)id;
 	int i;
 
 	/* All half words have wrong byte order; swap the bytes */
-	for (i = 0; i < sizeof(struct hd_driveid); i += 2, buf++)
-		*buf = le16_to_cpu(*buf);
-
-	/* Some of the data values are 32bit; swap the half words  */
-	id->lba_capacity = ((id->lba_capacity >> 16) & 0x0000FFFF) |
-	    ((id->lba_capacity << 16) & 0xFFFF0000);
-	id->spg = ((id->spg >> 16) & 0x0000FFFF) |
-	    ((id->spg << 16) & 0xFFFF0000);
+	for (i = 0; i < ATA_ID_WORDS; i++, id++)
+		*id = le16_to_cpu(*id);
 #endif
 }
 
@@ -614,7 +608,7 @@
 		break;
 
 	case ACE_FSM_STATE_IDENTIFY_COMPLETE:
-		ace_fix_driveid(&ace->cf_id);
+		ace_fix_driveid(&ace->cf_id[0]);
 		ace_dump_mem(&ace->cf_id, 512);	/* Debug: Dump out disk ID */
 
 		if (ace->data_result) {
@@ -627,9 +621,10 @@
 			ace->media_change = 0;
 
 			/* Record disk parameters */
-			set_capacity(ace->gd, ace->cf_id.lba_capacity);
+			set_capacity(ace->gd,
+				ata_id_u32(&ace->cf_id, ATA_ID_LBA_CAPACITY));
 			dev_info(ace->dev, "capacity: %i sectors\n",
-				 ace->cf_id.lba_capacity);
+				ata_id_u32(&ace->cf_id, ATA_ID_LBA_CAPACITY));
 		}
 
 		/* We're done, drop to IDLE state and notify waiters */
@@ -928,12 +923,13 @@
 static int ace_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 {
 	struct ace_device *ace = bdev->bd_disk->private_data;
+	u16 *cf_id = &ace->cf_id[0];
 
 	dev_dbg(ace->dev, "ace_getgeo()\n");
 
-	geo->heads = ace->cf_id.heads;
-	geo->sectors = ace->cf_id.sectors;
-	geo->cylinders = ace->cf_id.cyls;
+	geo->heads	= cf_id[ATA_ID_HEADS];
+	geo->sectors	= cf_id[ATA_ID_SECTORS];
+	geo->cylinders	= cf_id[ATA_ID_CYLS];
 
 	return 0;
 }
diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c
index f6094ae..140ea10 100644
--- a/drivers/char/bsr.c
+++ b/drivers/char/bsr.c
@@ -140,7 +140,7 @@
 	return 0;
 }
 
-const static struct file_operations bsr_fops = {
+static const struct file_operations bsr_fops = {
 	.owner = THIS_MODULE,
 	.mmap  = bsr_mmap,
 	.open  = bsr_open,
diff --git a/drivers/char/hw_random/timeriomem-rng.c b/drivers/char/hw_random/timeriomem-rng.c
index 10ad41b..dcd352a 100644
--- a/drivers/char/hw_random/timeriomem-rng.c
+++ b/drivers/char/hw_random/timeriomem-rng.c
@@ -90,10 +90,30 @@
 
 static int __init timeriomem_rng_probe(struct platform_device *pdev)
 {
+	struct resource *res, *mem;
 	int ret;
 
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	if (!res)
+		return -ENOENT;
+
+	mem = request_mem_region(res->start, res->end - res->start + 1,
+				 pdev->name);
+	if (mem == NULL)
+		return -EBUSY;
+
+	dev_set_drvdata(&pdev->dev, mem);
+
 	timeriomem_rng_data = pdev->dev.platform_data;
 
+	timeriomem_rng_data->address = ioremap(res->start,
+						res->end - res->start + 1);
+	if (!timeriomem_rng_data->address) {
+		ret = -ENOMEM;
+		goto err_ioremap;
+	}
+
 	if (timeriomem_rng_data->period != 0
 		&& usecs_to_jiffies(timeriomem_rng_data->period) > 0) {
 		timeriomem_rng_timer.expires = jiffies;
@@ -104,23 +124,34 @@
 	timeriomem_rng_data->present = 1;
 
 	ret = hwrng_register(&timeriomem_rng_ops);
-	if (ret) {
-		dev_err(&pdev->dev, "problem registering\n");
-		return ret;
-	}
+	if (ret)
+		goto err_register;
 
 	dev_info(&pdev->dev, "32bits from 0x%p @ %dus\n",
 			timeriomem_rng_data->address,
 			timeriomem_rng_data->period);
 
 	return 0;
+
+err_register:
+	dev_err(&pdev->dev, "problem registering\n");
+	iounmap(timeriomem_rng_data->address);
+err_ioremap:
+	release_resource(mem);
+
+	return ret;
 }
 
 static int __devexit timeriomem_rng_remove(struct platform_device *pdev)
 {
+	struct resource *mem = dev_get_drvdata(&pdev->dev);
+
 	del_timer_sync(&timeriomem_rng_timer);
 	hwrng_unregister(&timeriomem_rng_ops);
 
+	iounmap(timeriomem_rng_data->address);
+	release_resource(mem);
+
 	return 0;
 }
 
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index ebea9b2c..6de020d 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -283,7 +283,7 @@
 }
 static struct sysrq_key_op sysrq_ftrace_dump_op = {
 	.handler	= sysrq_ftrace_dump,
-	.help_msg	= "dumpZ-ftrace-buffer",
+	.help_msg	= "dump-ftrace-buffer(Z)",
 	.action_msg	= "Dump ftrace buffer",
 	.enable_mask	= SYSRQ_ENABLE_DUMP,
 };
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 7783b42..1c92c39 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -465,7 +465,6 @@
 	ced->set_mode = sh_cmt_clock_event_mode;
 
 	pr_info("sh_cmt: %s used for clock events\n", ced->name);
-	ced->mult = 1; /* work around misplaced WARN_ON() in clockevents.c */
 	clockevents_register_device(ced);
 }
 
@@ -557,7 +556,7 @@
 			       cfg->clockevent_rating,
 			       cfg->clocksource_rating);
  err2:
-	free_irq(irq, p);
+	remove_irq(irq, &p->irqaction);
  err1:
 	iounmap(p->mapbase);
  err0:
diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c
index d9e751b..af9761c 100644
--- a/drivers/crypto/ixp4xx_crypto.c
+++ b/drivers/crypto/ixp4xx_crypto.c
@@ -101,6 +101,7 @@
 	u32 phys_addr;
 	u32 __reserved[4];
 	struct buffer_desc *next;
+	enum dma_data_direction dir;
 };
 
 struct crypt_ctl {
@@ -132,14 +133,10 @@
 struct ablk_ctx {
 	struct buffer_desc *src;
 	struct buffer_desc *dst;
-	unsigned src_nents;
-	unsigned dst_nents;
 };
 
 struct aead_ctx {
 	struct buffer_desc *buffer;
-	unsigned short assoc_nents;
-	unsigned short src_nents;
 	struct scatterlist ivlist;
 	/* used when the hmac is not on one sg entry */
 	u8 *hmac_virt;
@@ -312,7 +309,7 @@
 	}
 }
 
-static void free_buf_chain(struct buffer_desc *buf, u32 phys)
+static void free_buf_chain(struct device *dev, struct buffer_desc *buf,u32 phys)
 {
 	while (buf) {
 		struct buffer_desc *buf1;
@@ -320,6 +317,7 @@
 
 		buf1 = buf->next;
 		phys1 = buf->phys_next;
+		dma_unmap_single(dev, buf->phys_next, buf->buf_len, buf->dir);
 		dma_pool_free(buffer_pool, buf, phys);
 		buf = buf1;
 		phys = phys1;
@@ -348,7 +346,6 @@
 	struct crypt_ctl *crypt;
 	struct ixp_ctx *ctx;
 	int failed;
-	enum dma_data_direction src_direction = DMA_BIDIRECTIONAL;
 
 	failed = phys & 0x1 ? -EBADMSG : 0;
 	phys &= ~0x3;
@@ -358,13 +355,8 @@
 	case CTL_FLAG_PERFORM_AEAD: {
 		struct aead_request *req = crypt->data.aead_req;
 		struct aead_ctx *req_ctx = aead_request_ctx(req);
-		dma_unmap_sg(dev, req->assoc, req_ctx->assoc_nents,
-				DMA_TO_DEVICE);
-		dma_unmap_sg(dev, &req_ctx->ivlist, 1, DMA_BIDIRECTIONAL);
-		dma_unmap_sg(dev, req->src, req_ctx->src_nents,
-				DMA_BIDIRECTIONAL);
 
-		free_buf_chain(req_ctx->buffer, crypt->src_buf);
+		free_buf_chain(dev, req_ctx->buffer, crypt->src_buf);
 		if (req_ctx->hmac_virt) {
 			finish_scattered_hmac(crypt);
 		}
@@ -374,16 +366,11 @@
 	case CTL_FLAG_PERFORM_ABLK: {
 		struct ablkcipher_request *req = crypt->data.ablk_req;
 		struct ablk_ctx *req_ctx = ablkcipher_request_ctx(req);
-		int nents;
+
 		if (req_ctx->dst) {
-			nents = req_ctx->dst_nents;
-			dma_unmap_sg(dev, req->dst, nents, DMA_FROM_DEVICE);
-			free_buf_chain(req_ctx->dst, crypt->dst_buf);
-			src_direction = DMA_TO_DEVICE;
+			free_buf_chain(dev, req_ctx->dst, crypt->dst_buf);
 		}
-		nents = req_ctx->src_nents;
-		dma_unmap_sg(dev, req->src, nents, src_direction);
-		free_buf_chain(req_ctx->src, crypt->src_buf);
+		free_buf_chain(dev, req_ctx->src, crypt->src_buf);
 		req->base.complete(&req->base, failed);
 		break;
 	}
@@ -750,56 +737,35 @@
 	return 0;
 }
 
-static int count_sg(struct scatterlist *sg, int nbytes)
+static struct buffer_desc *chainup_buffers(struct device *dev,
+		struct scatterlist *sg,	unsigned nbytes,
+		struct buffer_desc *buf, gfp_t flags,
+		enum dma_data_direction dir)
 {
-	int i;
-	for (i = 0; nbytes > 0; i++, sg = sg_next(sg))
-		nbytes -= sg->length;
-	return i;
-}
-
-static struct buffer_desc *chainup_buffers(struct scatterlist *sg,
-			unsigned nbytes, struct buffer_desc *buf, gfp_t flags)
-{
-	int nents = 0;
-
-	while (nbytes > 0) {
+	for (;nbytes > 0; sg = scatterwalk_sg_next(sg)) {
+		unsigned len = min(nbytes, sg->length);
 		struct buffer_desc *next_buf;
 		u32 next_buf_phys;
-		unsigned len = min(nbytes, sg_dma_len(sg));
+		void *ptr;
 
-		nents++;
 		nbytes -= len;
-		if (!buf->phys_addr) {
-			buf->phys_addr = sg_dma_address(sg);
-			buf->buf_len = len;
-			buf->next = NULL;
-			buf->phys_next = 0;
-			goto next;
-		}
-		/* Two consecutive chunks on one page may be handled by the old
-		 * buffer descriptor, increased by the length of the new one
-		 */
-		if (sg_dma_address(sg) == buf->phys_addr + buf->buf_len) {
-			buf->buf_len += len;
-			goto next;
-		}
+		ptr = page_address(sg_page(sg)) + sg->offset;
 		next_buf = dma_pool_alloc(buffer_pool, flags, &next_buf_phys);
-		if (!next_buf)
-			return NULL;
+		if (!next_buf) {
+			buf = NULL;
+			break;
+		}
+		sg_dma_address(sg) = dma_map_single(dev, ptr, len, dir);
 		buf->next = next_buf;
 		buf->phys_next = next_buf_phys;
-
 		buf = next_buf;
-		buf->next = NULL;
-		buf->phys_next = 0;
+
 		buf->phys_addr = sg_dma_address(sg);
 		buf->buf_len = len;
-next:
-		if (nbytes > 0) {
-			sg = sg_next(sg);
-		}
+		buf->dir = dir;
 	}
+	buf->next = NULL;
+	buf->phys_next = 0;
 	return buf;
 }
 
@@ -860,12 +826,12 @@
 	struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
 	struct ixp_ctx *ctx = crypto_ablkcipher_ctx(tfm);
 	unsigned ivsize = crypto_ablkcipher_ivsize(tfm);
-	int ret = -ENOMEM;
 	struct ix_sa_dir *dir;
 	struct crypt_ctl *crypt;
-	unsigned int nbytes = req->nbytes, nents;
+	unsigned int nbytes = req->nbytes;
 	enum dma_data_direction src_direction = DMA_BIDIRECTIONAL;
 	struct ablk_ctx *req_ctx = ablkcipher_request_ctx(req);
+	struct buffer_desc src_hook;
 	gfp_t flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
 				GFP_KERNEL : GFP_ATOMIC;
 
@@ -878,7 +844,7 @@
 
 	crypt = get_crypt_desc();
 	if (!crypt)
-		return ret;
+		return -ENOMEM;
 
 	crypt->data.ablk_req = req;
 	crypt->crypto_ctx = dir->npe_ctx_phys;
@@ -891,53 +857,41 @@
 	BUG_ON(ivsize && !req->info);
 	memcpy(crypt->iv, req->info, ivsize);
 	if (req->src != req->dst) {
+		struct buffer_desc dst_hook;
 		crypt->mode |= NPE_OP_NOT_IN_PLACE;
-		nents = count_sg(req->dst, nbytes);
 		/* This was never tested by Intel
 		 * for more than one dst buffer, I think. */
-		BUG_ON(nents != 1);
-		req_ctx->dst_nents = nents;
-		dma_map_sg(dev, req->dst, nents, DMA_FROM_DEVICE);
-		req_ctx->dst = dma_pool_alloc(buffer_pool, flags,&crypt->dst_buf);
-		if (!req_ctx->dst)
-			goto unmap_sg_dest;
-		req_ctx->dst->phys_addr = 0;
-		if (!chainup_buffers(req->dst, nbytes, req_ctx->dst, flags))
+		BUG_ON(req->dst->length < nbytes);
+		req_ctx->dst = NULL;
+		if (!chainup_buffers(dev, req->dst, nbytes, &dst_hook,
+					flags, DMA_FROM_DEVICE))
 			goto free_buf_dest;
 		src_direction = DMA_TO_DEVICE;
+		req_ctx->dst = dst_hook.next;
+		crypt->dst_buf = dst_hook.phys_next;
 	} else {
 		req_ctx->dst = NULL;
-		req_ctx->dst_nents = 0;
 	}
-	nents = count_sg(req->src, nbytes);
-	req_ctx->src_nents = nents;
-	dma_map_sg(dev, req->src, nents, src_direction);
-
-	req_ctx->src = dma_pool_alloc(buffer_pool, flags, &crypt->src_buf);
-	if (!req_ctx->src)
-		goto unmap_sg_src;
-	req_ctx->src->phys_addr = 0;
-	if (!chainup_buffers(req->src, nbytes, req_ctx->src, flags))
+	req_ctx->src = NULL;
+	if (!chainup_buffers(dev, req->src, nbytes, &src_hook,
+				flags, src_direction))
 		goto free_buf_src;
 
+	req_ctx->src = src_hook.next;
+	crypt->src_buf = src_hook.phys_next;
 	crypt->ctl_flags |= CTL_FLAG_PERFORM_ABLK;
 	qmgr_put_entry(SEND_QID, crypt_virt2phys(crypt));
 	BUG_ON(qmgr_stat_overflow(SEND_QID));
 	return -EINPROGRESS;
 
 free_buf_src:
-	free_buf_chain(req_ctx->src, crypt->src_buf);
-unmap_sg_src:
-	dma_unmap_sg(dev, req->src, req_ctx->src_nents, src_direction);
+	free_buf_chain(dev, req_ctx->src, crypt->src_buf);
 free_buf_dest:
 	if (req->src != req->dst) {
-		free_buf_chain(req_ctx->dst, crypt->dst_buf);
-unmap_sg_dest:
-		dma_unmap_sg(dev, req->src, req_ctx->dst_nents,
-			DMA_FROM_DEVICE);
+		free_buf_chain(dev, req_ctx->dst, crypt->dst_buf);
 	}
 	crypt->ctl_flags = CTL_FLAG_UNUSED;
-	return ret;
+	return -ENOMEM;
 }
 
 static int ablk_encrypt(struct ablkcipher_request *req)
@@ -985,7 +939,7 @@
 			break;
 
 		offset += sg->length;
-		sg = sg_next(sg);
+		sg = scatterwalk_sg_next(sg);
 	}
 	return (start + nbytes > offset + sg->length);
 }
@@ -997,11 +951,10 @@
 	struct ixp_ctx *ctx = crypto_aead_ctx(tfm);
 	unsigned ivsize = crypto_aead_ivsize(tfm);
 	unsigned authsize = crypto_aead_authsize(tfm);
-	int ret = -ENOMEM;
 	struct ix_sa_dir *dir;
 	struct crypt_ctl *crypt;
-	unsigned int cryptlen, nents;
-	struct buffer_desc *buf;
+	unsigned int cryptlen;
+	struct buffer_desc *buf, src_hook;
 	struct aead_ctx *req_ctx = aead_request_ctx(req);
 	gfp_t flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
 				GFP_KERNEL : GFP_ATOMIC;
@@ -1022,7 +975,7 @@
 	}
 	crypt = get_crypt_desc();
 	if (!crypt)
-		return ret;
+		return -ENOMEM;
 
 	crypt->data.aead_req = req;
 	crypt->crypto_ctx = dir->npe_ctx_phys;
@@ -1041,31 +994,27 @@
 		BUG(); /* -ENOTSUP because of my lazyness */
 	}
 
-	req_ctx->buffer = dma_pool_alloc(buffer_pool, flags, &crypt->src_buf);
-	if (!req_ctx->buffer)
-		goto out;
-	req_ctx->buffer->phys_addr = 0;
 	/* ASSOC data */
-	nents = count_sg(req->assoc, req->assoclen);
-	req_ctx->assoc_nents = nents;
-	dma_map_sg(dev, req->assoc, nents, DMA_TO_DEVICE);
-	buf = chainup_buffers(req->assoc, req->assoclen, req_ctx->buffer,flags);
+	buf = chainup_buffers(dev, req->assoc, req->assoclen, &src_hook,
+		flags, DMA_TO_DEVICE);
+	req_ctx->buffer = src_hook.next;
+	crypt->src_buf = src_hook.phys_next;
 	if (!buf)
-		goto unmap_sg_assoc;
+		goto out;
 	/* IV */
 	sg_init_table(&req_ctx->ivlist, 1);
 	sg_set_buf(&req_ctx->ivlist, iv, ivsize);
-	dma_map_sg(dev, &req_ctx->ivlist, 1, DMA_BIDIRECTIONAL);
-	buf = chainup_buffers(&req_ctx->ivlist, ivsize, buf, flags);
+	buf = chainup_buffers(dev, &req_ctx->ivlist, ivsize, buf, flags,
+			DMA_BIDIRECTIONAL);
 	if (!buf)
-		goto unmap_sg_iv;
+		goto free_chain;
 	if (unlikely(hmac_inconsistent(req->src, cryptlen, authsize))) {
 		/* The 12 hmac bytes are scattered,
 		 * we need to copy them into a safe buffer */
 		req_ctx->hmac_virt = dma_pool_alloc(buffer_pool, flags,
 				&crypt->icv_rev_aes);
 		if (unlikely(!req_ctx->hmac_virt))
-			goto unmap_sg_iv;
+			goto free_chain;
 		if (!encrypt) {
 			scatterwalk_map_and_copy(req_ctx->hmac_virt,
 				req->src, cryptlen, authsize, 0);
@@ -1075,33 +1024,28 @@
 		req_ctx->hmac_virt = NULL;
 	}
 	/* Crypt */
-	nents = count_sg(req->src, cryptlen + authsize);
-	req_ctx->src_nents = nents;
-	dma_map_sg(dev, req->src, nents, DMA_BIDIRECTIONAL);
-	buf = chainup_buffers(req->src, cryptlen + authsize, buf, flags);
+	buf = chainup_buffers(dev, req->src, cryptlen + authsize, buf, flags,
+			DMA_BIDIRECTIONAL);
 	if (!buf)
-		goto unmap_sg_src;
+		goto free_hmac_virt;
 	if (!req_ctx->hmac_virt) {
 		crypt->icv_rev_aes = buf->phys_addr + buf->buf_len - authsize;
 	}
+
 	crypt->ctl_flags |= CTL_FLAG_PERFORM_AEAD;
 	qmgr_put_entry(SEND_QID, crypt_virt2phys(crypt));
 	BUG_ON(qmgr_stat_overflow(SEND_QID));
 	return -EINPROGRESS;
-unmap_sg_src:
-	dma_unmap_sg(dev, req->src, req_ctx->src_nents, DMA_BIDIRECTIONAL);
+free_hmac_virt:
 	if (req_ctx->hmac_virt) {
 		dma_pool_free(buffer_pool, req_ctx->hmac_virt,
 				crypt->icv_rev_aes);
 	}
-unmap_sg_iv:
-	dma_unmap_sg(dev, &req_ctx->ivlist, 1, DMA_BIDIRECTIONAL);
-unmap_sg_assoc:
-	dma_unmap_sg(dev, req->assoc, req_ctx->assoc_nents, DMA_TO_DEVICE);
-	free_buf_chain(req_ctx->buffer, crypt->src_buf);
+free_chain:
+	free_buf_chain(dev, req_ctx->buffer, crypt->src_buf);
 out:
 	crypt->ctl_flags = CTL_FLAG_UNUSED;
-	return ret;
+	return -ENOMEM;
 }
 
 static int aead_setup(struct crypto_aead *tfm, unsigned int authsize)
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 48ea59e..3b3c01b 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -98,6 +98,17 @@
 	  Say Y here if you enabled INTEL_IOATDMA or FSL_DMA, otherwise
 	  say N.
 
+config ASYNC_TX_DMA
+	bool "Async_tx: Offload support for the async_tx api"
+	depends on DMA_ENGINE
+	help
+	  This allows the async_tx api to take advantage of offload engines for
+	  memcpy, memset, xor, and raid6 p+q operations.  If your platform has
+	  a dma engine that can perform raid operations and you have enabled
+	  MD_RAID456 say Y.
+
+	  If unsure, say N.
+
 config DMATEST
 	tristate "DMA Test client"
 	depends on DMA_ENGINE
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 280a9d2..92438e9 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -507,6 +507,7 @@
 			 * published in the general-purpose allocator
 			 */
 			dma_cap_set(DMA_PRIVATE, device->cap_mask);
+			device->privatecnt++;
 			err = dma_chan_get(chan);
 
 			if (err == -ENODEV) {
@@ -518,6 +519,8 @@
 				       dma_chan_name(chan), err);
 			else
 				break;
+			if (--device->privatecnt == 0)
+				dma_cap_clear(DMA_PRIVATE, device->cap_mask);
 			chan->private = NULL;
 			chan = NULL;
 		}
@@ -537,6 +540,9 @@
 	WARN_ONCE(chan->client_count != 1,
 		  "chan reference count %d != 1\n", chan->client_count);
 	dma_chan_put(chan);
+	/* drop PRIVATE cap enabled by __dma_request_channel() */
+	if (--chan->device->privatecnt == 0)
+		dma_cap_clear(DMA_PRIVATE, chan->device->cap_mask);
 	chan->private = NULL;
 	mutex_unlock(&dma_list_mutex);
 }
@@ -602,6 +608,24 @@
 }
 EXPORT_SYMBOL(dmaengine_put);
 
+static int get_dma_id(struct dma_device *device)
+{
+	int rc;
+
+ idr_retry:
+	if (!idr_pre_get(&dma_idr, GFP_KERNEL))
+		return -ENOMEM;
+	mutex_lock(&dma_list_mutex);
+	rc = idr_get_new(&dma_idr, NULL, &device->dev_id);
+	mutex_unlock(&dma_list_mutex);
+	if (rc == -EAGAIN)
+		goto idr_retry;
+	else if (rc != 0)
+		return rc;
+
+	return 0;
+}
+
 /**
  * dma_async_device_register - registers DMA devices found
  * @device: &dma_device
@@ -640,27 +664,25 @@
 	idr_ref = kmalloc(sizeof(*idr_ref), GFP_KERNEL);
 	if (!idr_ref)
 		return -ENOMEM;
-	atomic_set(idr_ref, 0);
- idr_retry:
-	if (!idr_pre_get(&dma_idr, GFP_KERNEL))
-		return -ENOMEM;
-	mutex_lock(&dma_list_mutex);
-	rc = idr_get_new(&dma_idr, NULL, &device->dev_id);
-	mutex_unlock(&dma_list_mutex);
-	if (rc == -EAGAIN)
-		goto idr_retry;
-	else if (rc != 0)
+	rc = get_dma_id(device);
+	if (rc != 0) {
+		kfree(idr_ref);
 		return rc;
+	}
+
+	atomic_set(idr_ref, 0);
 
 	/* represent channels in sysfs. Probably want devs too */
 	list_for_each_entry(chan, &device->channels, device_node) {
+		rc = -ENOMEM;
 		chan->local = alloc_percpu(typeof(*chan->local));
 		if (chan->local == NULL)
-			continue;
+			goto err_out;
 		chan->dev = kzalloc(sizeof(*chan->dev), GFP_KERNEL);
 		if (chan->dev == NULL) {
 			free_percpu(chan->local);
-			continue;
+			chan->local = NULL;
+			goto err_out;
 		}
 
 		chan->chan_id = chancnt++;
@@ -677,6 +699,8 @@
 		if (rc) {
 			free_percpu(chan->local);
 			chan->local = NULL;
+			kfree(chan->dev);
+			atomic_dec(idr_ref);
 			goto err_out;
 		}
 		chan->client_count = 0;
@@ -701,12 +725,23 @@
 			}
 		}
 	list_add_tail_rcu(&device->global_node, &dma_device_list);
+	if (dma_has_cap(DMA_PRIVATE, device->cap_mask))
+		device->privatecnt++;	/* Always private */
 	dma_channel_rebalance();
 	mutex_unlock(&dma_list_mutex);
 
 	return 0;
 
 err_out:
+	/* if we never registered a channel just release the idr */
+	if (atomic_read(idr_ref) == 0) {
+		mutex_lock(&dma_list_mutex);
+		idr_remove(&dma_idr, device->dev_id);
+		mutex_unlock(&dma_list_mutex);
+		kfree(idr_ref);
+		return rc;
+	}
+
 	list_for_each_entry(chan, &device->channels, device_node) {
 		if (chan->local == NULL)
 			continue;
@@ -893,6 +928,7 @@
 {
 	tx->chan = chan;
 	spin_lock_init(&tx->lock);
+	INIT_LIST_HEAD(&tx->tx_list);
 }
 EXPORT_SYMBOL(dma_async_tx_descriptor_init);
 
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index e190d8b..a27c0fb 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -38,6 +38,11 @@
 MODULE_PARM_DESC(max_channels,
 		"Maximum number of channels to use (default: all)");
 
+static unsigned int xor_sources = 3;
+module_param(xor_sources, uint, S_IRUGO);
+MODULE_PARM_DESC(xor_sources,
+		"Number of xor source buffers (default: 3)");
+
 /*
  * Initialization patterns. All bytes in the source buffer has bit 7
  * set, all bytes in the destination buffer has bit 7 cleared.
@@ -59,8 +64,9 @@
 	struct list_head	node;
 	struct task_struct	*task;
 	struct dma_chan		*chan;
-	u8			*srcbuf;
-	u8			*dstbuf;
+	u8			**srcs;
+	u8			**dsts;
+	enum dma_transaction_type type;
 };
 
 struct dmatest_chan {
@@ -98,30 +104,37 @@
 	return buf;
 }
 
-static void dmatest_init_srcbuf(u8 *buf, unsigned int start, unsigned int len)
+static void dmatest_init_srcs(u8 **bufs, unsigned int start, unsigned int len)
 {
 	unsigned int i;
+	u8 *buf;
 
-	for (i = 0; i < start; i++)
-		buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
-	for ( ; i < start + len; i++)
-		buf[i] = PATTERN_SRC | PATTERN_COPY
-			| (~i & PATTERN_COUNT_MASK);;
-	for ( ; i < test_buf_size; i++)
-		buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
+	for (; (buf = *bufs); bufs++) {
+		for (i = 0; i < start; i++)
+			buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
+		for ( ; i < start + len; i++)
+			buf[i] = PATTERN_SRC | PATTERN_COPY
+				| (~i & PATTERN_COUNT_MASK);;
+		for ( ; i < test_buf_size; i++)
+			buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
+		buf++;
+	}
 }
 
-static void dmatest_init_dstbuf(u8 *buf, unsigned int start, unsigned int len)
+static void dmatest_init_dsts(u8 **bufs, unsigned int start, unsigned int len)
 {
 	unsigned int i;
+	u8 *buf;
 
-	for (i = 0; i < start; i++)
-		buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
-	for ( ; i < start + len; i++)
-		buf[i] = PATTERN_DST | PATTERN_OVERWRITE
-			| (~i & PATTERN_COUNT_MASK);
-	for ( ; i < test_buf_size; i++)
-		buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
+	for (; (buf = *bufs); bufs++) {
+		for (i = 0; i < start; i++)
+			buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
+		for ( ; i < start + len; i++)
+			buf[i] = PATTERN_DST | PATTERN_OVERWRITE
+				| (~i & PATTERN_COUNT_MASK);
+		for ( ; i < test_buf_size; i++)
+			buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
+	}
 }
 
 static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index,
@@ -150,23 +163,30 @@
 				thread_name, index, expected, actual);
 }
 
-static unsigned int dmatest_verify(u8 *buf, unsigned int start,
+static unsigned int dmatest_verify(u8 **bufs, unsigned int start,
 		unsigned int end, unsigned int counter, u8 pattern,
 		bool is_srcbuf)
 {
 	unsigned int i;
 	unsigned int error_count = 0;
 	u8 actual;
+	u8 expected;
+	u8 *buf;
+	unsigned int counter_orig = counter;
 
-	for (i = start; i < end; i++) {
-		actual = buf[i];
-		if (actual != (pattern | (~counter & PATTERN_COUNT_MASK))) {
-			if (error_count < 32)
-				dmatest_mismatch(actual, pattern, i, counter,
-						is_srcbuf);
-			error_count++;
+	for (; (buf = *bufs); bufs++) {
+		counter = counter_orig;
+		for (i = start; i < end; i++) {
+			actual = buf[i];
+			expected = pattern | (~counter & PATTERN_COUNT_MASK);
+			if (actual != expected) {
+				if (error_count < 32)
+					dmatest_mismatch(actual, pattern, i,
+							 counter, is_srcbuf);
+				error_count++;
+			}
+			counter++;
 		}
-		counter++;
 	}
 
 	if (error_count > 32)
@@ -176,12 +196,17 @@
 	return error_count;
 }
 
+static void dmatest_callback(void *completion)
+{
+	complete(completion);
+}
+
 /*
  * This function repeatedly tests DMA transfers of various lengths and
- * offsets until it is told to exit by kthread_stop(). There may be
- * multiple threads running this function in parallel for a single
- * channel, and there may be multiple channels being tested in
- * parallel.
+ * offsets for a given operation type until it is told to exit by
+ * kthread_stop(). There may be multiple threads running this function
+ * in parallel for a single channel, and there may be multiple channels
+ * being tested in parallel.
  *
  * Before each test, the source and destination buffer is initialized
  * with a known pattern. This pattern is different depending on
@@ -201,25 +226,57 @@
 	unsigned int		total_tests = 0;
 	dma_cookie_t		cookie;
 	enum dma_status		status;
+	enum dma_ctrl_flags 	flags;
 	int			ret;
+	int			src_cnt;
+	int			dst_cnt;
+	int			i;
 
 	thread_name = current->comm;
 
 	ret = -ENOMEM;
-	thread->srcbuf = kmalloc(test_buf_size, GFP_KERNEL);
-	if (!thread->srcbuf)
-		goto err_srcbuf;
-	thread->dstbuf = kmalloc(test_buf_size, GFP_KERNEL);
-	if (!thread->dstbuf)
-		goto err_dstbuf;
 
 	smp_rmb();
 	chan = thread->chan;
+	if (thread->type == DMA_MEMCPY)
+		src_cnt = dst_cnt = 1;
+	else if (thread->type == DMA_XOR) {
+		src_cnt = xor_sources | 1; /* force odd to ensure dst = src */
+		dst_cnt = 1;
+	} else
+		goto err_srcs;
+
+	thread->srcs = kcalloc(src_cnt+1, sizeof(u8 *), GFP_KERNEL);
+	if (!thread->srcs)
+		goto err_srcs;
+	for (i = 0; i < src_cnt; i++) {
+		thread->srcs[i] = kmalloc(test_buf_size, GFP_KERNEL);
+		if (!thread->srcs[i])
+			goto err_srcbuf;
+	}
+	thread->srcs[i] = NULL;
+
+	thread->dsts = kcalloc(dst_cnt+1, sizeof(u8 *), GFP_KERNEL);
+	if (!thread->dsts)
+		goto err_dsts;
+	for (i = 0; i < dst_cnt; i++) {
+		thread->dsts[i] = kmalloc(test_buf_size, GFP_KERNEL);
+		if (!thread->dsts[i])
+			goto err_dstbuf;
+	}
+	thread->dsts[i] = NULL;
+
+	set_user_nice(current, 10);
+
+	flags = DMA_CTRL_ACK | DMA_COMPL_SKIP_DEST_UNMAP | DMA_PREP_INTERRUPT;
 
 	while (!kthread_should_stop()) {
 		struct dma_device *dev = chan->device;
-		struct dma_async_tx_descriptor *tx;
-		dma_addr_t dma_src, dma_dest;
+		struct dma_async_tx_descriptor *tx = NULL;
+		dma_addr_t dma_srcs[src_cnt];
+		dma_addr_t dma_dsts[dst_cnt];
+		struct completion cmp;
+		unsigned long tmo = msecs_to_jiffies(3000);
 
 		total_tests++;
 
@@ -227,22 +284,41 @@
 		src_off = dmatest_random() % (test_buf_size - len + 1);
 		dst_off = dmatest_random() % (test_buf_size - len + 1);
 
-		dmatest_init_srcbuf(thread->srcbuf, src_off, len);
-		dmatest_init_dstbuf(thread->dstbuf, dst_off, len);
+		dmatest_init_srcs(thread->srcs, src_off, len);
+		dmatest_init_dsts(thread->dsts, dst_off, len);
 
-		dma_src = dma_map_single(dev->dev, thread->srcbuf + src_off,
-				len, DMA_TO_DEVICE);
+		for (i = 0; i < src_cnt; i++) {
+			u8 *buf = thread->srcs[i] + src_off;
+
+			dma_srcs[i] = dma_map_single(dev->dev, buf, len,
+						     DMA_TO_DEVICE);
+		}
 		/* map with DMA_BIDIRECTIONAL to force writeback/invalidate */
-		dma_dest = dma_map_single(dev->dev, thread->dstbuf,
-				test_buf_size, DMA_BIDIRECTIONAL);
+		for (i = 0; i < dst_cnt; i++) {
+			dma_dsts[i] = dma_map_single(dev->dev, thread->dsts[i],
+						     test_buf_size,
+						     DMA_BIDIRECTIONAL);
+		}
 
-		tx = dev->device_prep_dma_memcpy(chan, dma_dest + dst_off,
-				dma_src, len,
-				DMA_CTRL_ACK | DMA_COMPL_SKIP_DEST_UNMAP);
+		if (thread->type == DMA_MEMCPY)
+			tx = dev->device_prep_dma_memcpy(chan,
+							 dma_dsts[0] + dst_off,
+							 dma_srcs[0], len,
+							 flags);
+		else if (thread->type == DMA_XOR)
+			tx = dev->device_prep_dma_xor(chan,
+						      dma_dsts[0] + dst_off,
+						      dma_srcs, xor_sources,
+						      len, flags);
+
 		if (!tx) {
-			dma_unmap_single(dev->dev, dma_src, len, DMA_TO_DEVICE);
-			dma_unmap_single(dev->dev, dma_dest,
-					test_buf_size, DMA_BIDIRECTIONAL);
+			for (i = 0; i < src_cnt; i++)
+				dma_unmap_single(dev->dev, dma_srcs[i], len,
+						 DMA_TO_DEVICE);
+			for (i = 0; i < dst_cnt; i++)
+				dma_unmap_single(dev->dev, dma_dsts[i],
+						 test_buf_size,
+						 DMA_BIDIRECTIONAL);
 			pr_warning("%s: #%u: prep error with src_off=0x%x "
 					"dst_off=0x%x len=0x%x\n",
 					thread_name, total_tests - 1,
@@ -251,7 +327,10 @@
 			failed_tests++;
 			continue;
 		}
-		tx->callback = NULL;
+
+		init_completion(&cmp);
+		tx->callback = dmatest_callback;
+		tx->callback_param = &cmp;
 		cookie = tx->tx_submit(tx);
 
 		if (dma_submit_error(cookie)) {
@@ -263,44 +342,50 @@
 			failed_tests++;
 			continue;
 		}
-		dma_async_memcpy_issue_pending(chan);
+		dma_async_issue_pending(chan);
 
-		do {
-			msleep(1);
-			status = dma_async_memcpy_complete(
-					chan, cookie, NULL, NULL);
-		} while (status == DMA_IN_PROGRESS);
+		tmo = wait_for_completion_timeout(&cmp, tmo);
+		status = dma_async_is_tx_complete(chan, cookie, NULL, NULL);
 
-		if (status == DMA_ERROR) {
-			pr_warning("%s: #%u: error during copy\n",
-					thread_name, total_tests - 1);
+		if (tmo == 0) {
+			pr_warning("%s: #%u: test timed out\n",
+				   thread_name, total_tests - 1);
+			failed_tests++;
+			continue;
+		} else if (status != DMA_SUCCESS) {
+			pr_warning("%s: #%u: got completion callback,"
+				   " but status is \'%s\'\n",
+				   thread_name, total_tests - 1,
+				   status == DMA_ERROR ? "error" : "in progress");
 			failed_tests++;
 			continue;
 		}
+
 		/* Unmap by myself (see DMA_COMPL_SKIP_DEST_UNMAP above) */
-		dma_unmap_single(dev->dev, dma_dest,
-				test_buf_size, DMA_BIDIRECTIONAL);
+		for (i = 0; i < dst_cnt; i++)
+			dma_unmap_single(dev->dev, dma_dsts[i], test_buf_size,
+					 DMA_BIDIRECTIONAL);
 
 		error_count = 0;
 
 		pr_debug("%s: verifying source buffer...\n", thread_name);
-		error_count += dmatest_verify(thread->srcbuf, 0, src_off,
+		error_count += dmatest_verify(thread->srcs, 0, src_off,
 				0, PATTERN_SRC, true);
-		error_count += dmatest_verify(thread->srcbuf, src_off,
+		error_count += dmatest_verify(thread->srcs, src_off,
 				src_off + len, src_off,
 				PATTERN_SRC | PATTERN_COPY, true);
-		error_count += dmatest_verify(thread->srcbuf, src_off + len,
+		error_count += dmatest_verify(thread->srcs, src_off + len,
 				test_buf_size, src_off + len,
 				PATTERN_SRC, true);
 
 		pr_debug("%s: verifying dest buffer...\n",
 				thread->task->comm);
-		error_count += dmatest_verify(thread->dstbuf, 0, dst_off,
+		error_count += dmatest_verify(thread->dsts, 0, dst_off,
 				0, PATTERN_DST, false);
-		error_count += dmatest_verify(thread->dstbuf, dst_off,
+		error_count += dmatest_verify(thread->dsts, dst_off,
 				dst_off + len, src_off,
 				PATTERN_SRC | PATTERN_COPY, false);
-		error_count += dmatest_verify(thread->dstbuf, dst_off + len,
+		error_count += dmatest_verify(thread->dsts, dst_off + len,
 				test_buf_size, dst_off + len,
 				PATTERN_DST, false);
 
@@ -319,10 +404,16 @@
 	}
 
 	ret = 0;
-	kfree(thread->dstbuf);
+	for (i = 0; thread->dsts[i]; i++)
+		kfree(thread->dsts[i]);
 err_dstbuf:
-	kfree(thread->srcbuf);
+	kfree(thread->dsts);
+err_dsts:
+	for (i = 0; thread->srcs[i]; i++)
+		kfree(thread->srcs[i]);
 err_srcbuf:
+	kfree(thread->srcs);
+err_srcs:
 	pr_notice("%s: terminating after %u tests, %u failures (status %d)\n",
 			thread_name, total_tests, failed_tests, ret);
 	return ret;
@@ -344,11 +435,54 @@
 	kfree(dtc);
 }
 
+static int dmatest_add_threads(struct dmatest_chan *dtc, enum dma_transaction_type type)
+{
+	struct dmatest_thread *thread;
+	struct dma_chan *chan = dtc->chan;
+	char *op;
+	unsigned int i;
+
+	if (type == DMA_MEMCPY)
+		op = "copy";
+	else if (type == DMA_XOR)
+		op = "xor";
+	else
+		return -EINVAL;
+
+	for (i = 0; i < threads_per_chan; i++) {
+		thread = kzalloc(sizeof(struct dmatest_thread), GFP_KERNEL);
+		if (!thread) {
+			pr_warning("dmatest: No memory for %s-%s%u\n",
+				   dma_chan_name(chan), op, i);
+
+			break;
+		}
+		thread->chan = dtc->chan;
+		thread->type = type;
+		smp_wmb();
+		thread->task = kthread_run(dmatest_func, thread, "%s-%s%u",
+				dma_chan_name(chan), op, i);
+		if (IS_ERR(thread->task)) {
+			pr_warning("dmatest: Failed to run thread %s-%s%u\n",
+					dma_chan_name(chan), op, i);
+			kfree(thread);
+			break;
+		}
+
+		/* srcbuf and dstbuf are allocated by the thread itself */
+
+		list_add_tail(&thread->node, &dtc->threads);
+	}
+
+	return i;
+}
+
 static int dmatest_add_channel(struct dma_chan *chan)
 {
 	struct dmatest_chan	*dtc;
-	struct dmatest_thread	*thread;
-	unsigned int		i;
+	struct dma_device	*dma_dev = chan->device;
+	unsigned int		thread_count = 0;
+	unsigned int		cnt;
 
 	dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL);
 	if (!dtc) {
@@ -359,30 +493,17 @@
 	dtc->chan = chan;
 	INIT_LIST_HEAD(&dtc->threads);
 
-	for (i = 0; i < threads_per_chan; i++) {
-		thread = kzalloc(sizeof(struct dmatest_thread), GFP_KERNEL);
-		if (!thread) {
-			pr_warning("dmatest: No memory for %s-test%u\n",
-				   dma_chan_name(chan), i);
-			break;
-		}
-		thread->chan = dtc->chan;
-		smp_wmb();
-		thread->task = kthread_run(dmatest_func, thread, "%s-test%u",
-				dma_chan_name(chan), i);
-		if (IS_ERR(thread->task)) {
-			pr_warning("dmatest: Failed to run thread %s-test%u\n",
-					dma_chan_name(chan), i);
-			kfree(thread);
-			break;
-		}
-
-		/* srcbuf and dstbuf are allocated by the thread itself */
-
-		list_add_tail(&thread->node, &dtc->threads);
+	if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask)) {
+		cnt = dmatest_add_threads(dtc, DMA_MEMCPY);
+		thread_count += cnt > 0 ?: 0;
+	}
+	if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) {
+		cnt = dmatest_add_threads(dtc, DMA_XOR);
+		thread_count += cnt > 0 ?: 0;
 	}
 
-	pr_info("dmatest: Started %u threads using %s\n", i, dma_chan_name(chan));
+	pr_info("dmatest: Started %u threads using %s\n",
+		thread_count, dma_chan_name(chan));
 
 	list_add_tail(&dtc->node, &dmatest_channels);
 	nr_channels++;
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index 20ad3d2..98c9a84 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -363,6 +363,82 @@
 	dwc_descriptor_complete(dwc, bad_desc);
 }
 
+/* --------------------- Cyclic DMA API extensions -------------------- */
+
+inline dma_addr_t dw_dma_get_src_addr(struct dma_chan *chan)
+{
+	struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+	return channel_readl(dwc, SAR);
+}
+EXPORT_SYMBOL(dw_dma_get_src_addr);
+
+inline dma_addr_t dw_dma_get_dst_addr(struct dma_chan *chan)
+{
+	struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+	return channel_readl(dwc, DAR);
+}
+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_block, u32 status_err, u32 status_xfer)
+{
+	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;
+		if (callback) {
+			spin_unlock(&dwc->lock);
+			callback(callback_param);
+			spin_lock(&dwc->lock);
+		}
+	}
+
+	/*
+	 * Error and transfer complete are highly unlikely, and will most
+	 * likely be due to a configuration error by the user.
+	 */
+	if (unlikely(status_err & dwc->mask) ||
+			unlikely(status_xfer & dwc->mask)) {
+		int i;
+
+		dev_err(chan2dev(&dwc->chan), "cyclic DMA unexpected %s "
+				"interrupt, stopping DMA transfer\n",
+				status_xfer ? "xfer" : "error");
+		dev_err(chan2dev(&dwc->chan),
+			"  SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n",
+			channel_readl(dwc, SAR),
+			channel_readl(dwc, DAR),
+			channel_readl(dwc, LLP),
+			channel_readl(dwc, CTL_HI),
+			channel_readl(dwc, CTL_LO));
+
+		channel_clear_bit(dw, CH_EN, dwc->mask);
+		while (dma_readl(dw, CH_EN) & dwc->mask)
+			cpu_relax();
+
+		/* make sure DMA does not restart by loading a new list */
+		channel_writel(dwc, LLP, 0);
+		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);
+
+		for (i = 0; i < dwc->cdesc->periods; i++)
+			dwc_dump_lli(dwc, &dwc->cdesc->desc[i]->lli);
+	}
+}
+
+/* ------------------------------------------------------------------------- */
+
 static void dw_dma_tasklet(unsigned long data)
 {
 	struct dw_dma *dw = (struct dw_dma *)data;
@@ -382,7 +458,10 @@
 	for (i = 0; i < dw->dma.chancnt; i++) {
 		dwc = &dw->chan[i];
 		spin_lock(&dwc->lock);
-		if (status_err & (1 << i))
+		if (test_bit(DW_DMA_IS_CYCLIC, &dwc->flags))
+			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_block | status_xfer) & (1 << i))
 			dwc_scan_descriptors(dw, dwc);
@@ -826,7 +905,6 @@
 		dma_async_tx_descriptor_init(&desc->txd, chan);
 		desc->txd.tx_submit = dwc_tx_submit;
 		desc->txd.flags = DMA_CTRL_ACK;
-		INIT_LIST_HEAD(&desc->txd.tx_list);
 		desc->txd.phys = dma_map_single(chan2parent(chan), &desc->lli,
 				sizeof(desc->lli), DMA_TO_DEVICE);
 		dwc_desc_put(dwc, desc);
@@ -884,6 +962,257 @@
 	dev_vdbg(chan2dev(chan), "free_chan_resources done\n");
 }
 
+/* --------------------- Cyclic DMA API extensions -------------------- */
+
+/**
+ * dw_dma_cyclic_start - start the cyclic DMA transfer
+ * @chan: the DMA channel to start
+ *
+ * Must be called with soft interrupts disabled. Returns zero on success or
+ * -errno on failure.
+ */
+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);
+
+	if (!test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) {
+		dev_err(chan2dev(&dwc->chan), "missing prep for cyclic DMA\n");
+		return -ENODEV;
+	}
+
+	spin_lock(&dwc->lock);
+
+	/* assert channel is idle */
+	if (dma_readl(dw, CH_EN) & dwc->mask) {
+		dev_err(chan2dev(&dwc->chan),
+			"BUG: Attempted to start non-idle channel\n");
+		dev_err(chan2dev(&dwc->chan),
+			"  SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n",
+			channel_readl(dwc, SAR),
+			channel_readl(dwc, DAR),
+			channel_readl(dwc, LLP),
+			channel_readl(dwc, CTL_HI),
+			channel_readl(dwc, CTL_LO));
+		spin_unlock(&dwc->lock);
+		return -EBUSY;
+	}
+
+	dma_writel(dw, CLEAR.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);
+
+	spin_unlock(&dwc->lock);
+
+	return 0;
+}
+EXPORT_SYMBOL(dw_dma_cyclic_start);
+
+/**
+ * dw_dma_cyclic_stop - stop the cyclic DMA transfer
+ * @chan: the DMA channel to stop
+ *
+ * Must be called with soft interrupts disabled.
+ */
+void dw_dma_cyclic_stop(struct dma_chan *chan)
+{
+	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
+	struct dw_dma		*dw = to_dw_dma(dwc->chan.device);
+
+	spin_lock(&dwc->lock);
+
+	channel_clear_bit(dw, CH_EN, dwc->mask);
+	while (dma_readl(dw, CH_EN) & dwc->mask)
+		cpu_relax();
+
+	spin_unlock(&dwc->lock);
+}
+EXPORT_SYMBOL(dw_dma_cyclic_stop);
+
+/**
+ * dw_dma_cyclic_prep - prepare the cyclic DMA transfer
+ * @chan: the DMA channel to prepare
+ * @buf_addr: physical DMA address where the buffer starts
+ * @buf_len: total number of bytes for the entire buffer
+ * @period_len: number of bytes for each period
+ * @direction: transfer direction, to or from device
+ *
+ * Must be called before trying to start the transfer. Returns a valid struct
+ * dw_cyclic_desc if successful or an ERR_PTR(-errno) if not successful.
+ */
+struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan,
+		dma_addr_t buf_addr, size_t buf_len, size_t period_len,
+		enum dma_data_direction direction)
+{
+	struct dw_dma_chan		*dwc = to_dw_dma_chan(chan);
+	struct dw_cyclic_desc		*cdesc;
+	struct dw_cyclic_desc		*retval = NULL;
+	struct dw_desc			*desc;
+	struct dw_desc			*last = NULL;
+	struct dw_dma_slave		*dws = chan->private;
+	unsigned long			was_cyclic;
+	unsigned int			reg_width;
+	unsigned int			periods;
+	unsigned int			i;
+
+	spin_lock_bh(&dwc->lock);
+	if (!list_empty(&dwc->queue) || !list_empty(&dwc->active_list)) {
+		spin_unlock_bh(&dwc->lock);
+		dev_dbg(chan2dev(&dwc->chan),
+				"queue and/or active list are not empty\n");
+		return ERR_PTR(-EBUSY);
+	}
+
+	was_cyclic = test_and_set_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
+	spin_unlock_bh(&dwc->lock);
+	if (was_cyclic) {
+		dev_dbg(chan2dev(&dwc->chan),
+				"channel already prepared for cyclic DMA\n");
+		return ERR_PTR(-EBUSY);
+	}
+
+	retval = ERR_PTR(-EINVAL);
+	reg_width = dws->reg_width;
+	periods = buf_len / period_len;
+
+	/* Check for too big/unaligned periods and unaligned DMA buffer. */
+	if (period_len > (DWC_MAX_COUNT << reg_width))
+		goto out_err;
+	if (unlikely(period_len & ((1 << reg_width) - 1)))
+		goto out_err;
+	if (unlikely(buf_addr & ((1 << reg_width) - 1)))
+		goto out_err;
+	if (unlikely(!(direction & (DMA_TO_DEVICE | DMA_FROM_DEVICE))))
+		goto out_err;
+
+	retval = ERR_PTR(-ENOMEM);
+
+	if (periods > NR_DESCS_PER_CHANNEL)
+		goto out_err;
+
+	cdesc = kzalloc(sizeof(struct dw_cyclic_desc), GFP_KERNEL);
+	if (!cdesc)
+		goto out_err;
+
+	cdesc->desc = kzalloc(sizeof(struct dw_desc *) * periods, GFP_KERNEL);
+	if (!cdesc->desc)
+		goto out_err_alloc;
+
+	for (i = 0; i < periods; i++) {
+		desc = dwc_desc_get(dwc);
+		if (!desc)
+			goto out_err_desc_get;
+
+		switch (direction) {
+		case DMA_TO_DEVICE:
+			desc->lli.dar = dws->tx_reg;
+			desc->lli.sar = buf_addr + (period_len * i);
+			desc->lli.ctllo = (DWC_DEFAULT_CTLLO
+					| DWC_CTLL_DST_WIDTH(reg_width)
+					| DWC_CTLL_SRC_WIDTH(reg_width)
+					| DWC_CTLL_DST_FIX
+					| DWC_CTLL_SRC_INC
+					| DWC_CTLL_FC_M2P
+					| DWC_CTLL_INT_EN);
+			break;
+		case DMA_FROM_DEVICE:
+			desc->lli.dar = buf_addr + (period_len * i);
+			desc->lli.sar = dws->rx_reg;
+			desc->lli.ctllo = (DWC_DEFAULT_CTLLO
+					| DWC_CTLL_SRC_WIDTH(reg_width)
+					| DWC_CTLL_DST_WIDTH(reg_width)
+					| DWC_CTLL_DST_INC
+					| DWC_CTLL_SRC_FIX
+					| DWC_CTLL_FC_P2M
+					| DWC_CTLL_INT_EN);
+			break;
+		default:
+			break;
+		}
+
+		desc->lli.ctlhi = (period_len >> reg_width);
+		cdesc->desc[i] = desc;
+
+		if (last) {
+			last->lli.llp = desc->txd.phys;
+			dma_sync_single_for_device(chan2parent(chan),
+					last->txd.phys, sizeof(last->lli),
+					DMA_TO_DEVICE);
+		}
+
+		last = desc;
+	}
+
+	/* lets make a cyclic list */
+	last->lli.llp = cdesc->desc[0]->txd.phys;
+	dma_sync_single_for_device(chan2parent(chan), last->txd.phys,
+			sizeof(last->lli), DMA_TO_DEVICE);
+
+	dev_dbg(chan2dev(&dwc->chan), "cyclic prepared buf 0x%08x len %zu "
+			"period %zu periods %d\n", buf_addr, buf_len,
+			period_len, periods);
+
+	cdesc->periods = periods;
+	dwc->cdesc = cdesc;
+
+	return cdesc;
+
+out_err_desc_get:
+	while (i--)
+		dwc_desc_put(dwc, cdesc->desc[i]);
+out_err_alloc:
+	kfree(cdesc);
+out_err:
+	clear_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
+	return (struct dw_cyclic_desc *)retval;
+}
+EXPORT_SYMBOL(dw_dma_cyclic_prep);
+
+/**
+ * dw_dma_cyclic_free - free a prepared cyclic DMA transfer
+ * @chan: the DMA channel to free
+ */
+void dw_dma_cyclic_free(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_cyclic_desc	*cdesc = dwc->cdesc;
+	int			i;
+
+	dev_dbg(chan2dev(&dwc->chan), "cyclic free\n");
+
+	if (!cdesc)
+		return;
+
+	spin_lock_bh(&dwc->lock);
+
+	channel_clear_bit(dw, CH_EN, dwc->mask);
+	while (dma_readl(dw, CH_EN) & dwc->mask)
+		cpu_relax();
+
+	dma_writel(dw, CLEAR.BLOCK, dwc->mask);
+	dma_writel(dw, CLEAR.ERROR, dwc->mask);
+	dma_writel(dw, CLEAR.XFER, dwc->mask);
+
+	spin_unlock_bh(&dwc->lock);
+
+	for (i = 0; i < cdesc->periods; i++)
+		dwc_desc_put(dwc, cdesc->desc[i]);
+
+	kfree(cdesc->desc);
+	kfree(cdesc);
+
+	clear_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
+}
+EXPORT_SYMBOL(dw_dma_cyclic_free);
+
 /*----------------------------------------------------------------------*/
 
 static void dw_dma_off(struct dw_dma *dw)
diff --git a/drivers/dma/dw_dmac_regs.h b/drivers/dma/dw_dmac_regs.h
index b252b20..13a5807 100644
--- a/drivers/dma/dw_dmac_regs.h
+++ b/drivers/dma/dw_dmac_regs.h
@@ -126,6 +126,10 @@
 
 #define DW_REGLEN		0x400
 
+enum dw_dmac_flags {
+	DW_DMA_IS_CYCLIC = 0,
+};
+
 struct dw_dma_chan {
 	struct dma_chan		chan;
 	void __iomem		*ch_regs;
@@ -134,10 +138,12 @@
 	spinlock_t		lock;
 
 	/* these other elements are all protected by lock */
+	unsigned long		flags;
 	dma_cookie_t		completed;
 	struct list_head	active_list;
 	struct list_head	queue;
 	struct list_head	free_list;
+	struct dw_cyclic_desc	*cdesc;
 
 	unsigned int		descs_allocated;
 };
@@ -158,7 +164,6 @@
 	return container_of(chan, struct dw_dma_chan, chan);
 }
 
-
 struct dw_dma {
 	struct dma_device	dma;
 	void __iomem		*regs;
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index 86d6da47..da8a8ed 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -354,7 +354,6 @@
 		dma_async_tx_descriptor_init(&desc_sw->async_tx,
 						&fsl_chan->common);
 		desc_sw->async_tx.tx_submit = fsl_dma_tx_submit;
-		INIT_LIST_HEAD(&desc_sw->async_tx.tx_list);
 		desc_sw->async_tx.phys = pdesc;
 	}
 
diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c
index 5905cd3..e4fc33c 100644
--- a/drivers/dma/ioat_dma.c
+++ b/drivers/dma/ioat_dma.c
@@ -693,7 +693,6 @@
 		desc_sw->async_tx.tx_submit = ioat2_tx_submit;
 		break;
 	}
-	INIT_LIST_HEAD(&desc_sw->async_tx.tx_list);
 
 	desc_sw->hw = desc;
 	desc_sw->async_tx.phys = phys;
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index 16adbe6..2f05226 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -498,7 +498,6 @@
 		slot->async_tx.tx_submit = iop_adma_tx_submit;
 		INIT_LIST_HEAD(&slot->chain_node);
 		INIT_LIST_HEAD(&slot->slot_node);
-		INIT_LIST_HEAD(&slot->async_tx.tx_list);
 		hw_desc = (char *) iop_chan->device->dma_desc_pool;
 		slot->async_tx.phys =
 			(dma_addr_t) &hw_desc[idx * IOP_ADMA_SLOT_SIZE];
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
index da781d1..e202a6c 100644
--- a/drivers/dma/ipu/ipu_idmac.c
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -28,6 +28,9 @@
 #define FS_VF_IN_VALID	0x00000002
 #define FS_ENC_IN_VALID	0x00000001
 
+static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan,
+			       bool wait_for_stop);
+
 /*
  * There can be only one, we could allocate it dynamically, but then we'd have
  * to add an extra parameter to some functions, and use something as ugly as
@@ -107,7 +110,7 @@
 	}
 }
 
-/* Enable / disable direct write to memory by the Camera Sensor Interface */
+/* Enable direct write to memory by the Camera Sensor Interface */
 static void ipu_ic_enable_task(struct ipu *ipu, enum ipu_channel channel)
 {
 	uint32_t ic_conf, mask;
@@ -126,6 +129,7 @@
 	idmac_write_icreg(ipu, ic_conf, IC_CONF);
 }
 
+/* Called under spin_lock_irqsave(&ipu_data.lock) */
 static void ipu_ic_disable_task(struct ipu *ipu, enum ipu_channel channel)
 {
 	uint32_t ic_conf, mask;
@@ -422,7 +426,7 @@
 		break;
 	default:
 		dev_err(ipu_data.dev,
-			"mxc ipu: unimplemented pixel format %d\n", pixel_fmt);
+			"mx3 ipu: unimplemented pixel format %d\n", pixel_fmt);
 		break;
 	}
 
@@ -433,20 +437,20 @@
 					uint16_t burst_pixels)
 {
 	params->pp.npb = burst_pixels - 1;
-};
+}
 
 static void ipu_ch_param_set_buffer(union chan_param_mem *params,
 				    dma_addr_t buf0, dma_addr_t buf1)
 {
 	params->pp.eba0 = buf0;
 	params->pp.eba1 = buf1;
-};
+}
 
 static void ipu_ch_param_set_rotation(union chan_param_mem *params,
 				      enum ipu_rotate_mode rotate)
 {
 	params->pp.bam = rotate;
-};
+}
 
 static void ipu_write_param_mem(uint32_t addr, uint32_t *data,
 				uint32_t num_words)
@@ -571,7 +575,7 @@
 {
 	/* Channel Parameter Memory */
 	return 0x10000 | (dma_ch << 4);
-};
+}
 
 static void ipu_channel_set_priority(struct ipu *ipu, enum ipu_channel channel,
 				     bool prio)
@@ -611,7 +615,8 @@
 
 /**
  * ipu_enable_channel() - enable an IPU channel.
- * @channel:	channel ID.
+ * @idmac:	IPU DMAC context.
+ * @ichan:	IDMAC channel.
  * @return:	0 on success or negative error code on failure.
  */
 static int ipu_enable_channel(struct idmac *idmac, struct idmac_channel *ichan)
@@ -649,7 +654,7 @@
 
 /**
  * ipu_init_channel_buffer() - initialize a buffer for logical IPU channel.
- * @channel:	channel ID.
+ * @ichan:	IDMAC channel.
  * @pixel_fmt:	pixel format of buffer. Pixel format is a FOURCC ASCII code.
  * @width:	width of buffer in pixels.
  * @height:	height of buffer in pixels.
@@ -687,7 +692,7 @@
 	}
 
 	/* IC channel's stride must be a multiple of 8 pixels */
-	if ((channel <= 13) && (stride % 8)) {
+	if ((channel <= IDMAC_IC_13) && (stride % 8)) {
 		dev_err(ipu->dev, "Stride must be 8 pixel multiple\n");
 		return -EINVAL;
 	}
@@ -752,7 +757,7 @@
 
 /**
  * ipu_update_channel_buffer() - update physical address of a channel buffer.
- * @channel:	channel ID.
+ * @ichan:	IDMAC channel.
  * @buffer_n:	buffer number to update.
  *		0 or 1 are the only valid values.
  * @phyaddr:	buffer physical address.
@@ -760,9 +765,10 @@
  *              function will fail if the buffer is set to ready.
  */
 /* Called under spin_lock(_irqsave)(&ichan->lock) */
-static int ipu_update_channel_buffer(enum ipu_channel channel,
+static int ipu_update_channel_buffer(struct idmac_channel *ichan,
 				     int buffer_n, dma_addr_t phyaddr)
 {
+	enum ipu_channel channel = ichan->dma_chan.chan_id;
 	uint32_t reg;
 	unsigned long flags;
 
@@ -771,8 +777,8 @@
 	if (buffer_n == 0) {
 		reg = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF0_RDY);
 		if (reg & (1UL << channel)) {
-			spin_unlock_irqrestore(&ipu_data.lock, flags);
-			return -EACCES;
+			ipu_ic_disable_task(&ipu_data, channel);
+			ichan->status = IPU_CHANNEL_READY;
 		}
 
 		/* 44.3.3.1.9 - Row Number 1 (WORD1, offset 0) */
@@ -782,8 +788,8 @@
 	} else {
 		reg = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF1_RDY);
 		if (reg & (1UL << channel)) {
-			spin_unlock_irqrestore(&ipu_data.lock, flags);
-			return -EACCES;
+			ipu_ic_disable_task(&ipu_data, channel);
+			ichan->status = IPU_CHANNEL_READY;
 		}
 
 		/* Check if double-buffering is already enabled */
@@ -805,6 +811,39 @@
 }
 
 /* Called under spin_lock_irqsave(&ichan->lock) */
+static int ipu_submit_buffer(struct idmac_channel *ichan,
+	struct idmac_tx_desc *desc, struct scatterlist *sg, int buf_idx)
+{
+	unsigned int chan_id = ichan->dma_chan.chan_id;
+	struct device *dev = &ichan->dma_chan.dev->device;
+	int ret;
+
+	if (async_tx_test_ack(&desc->txd))
+		return -EINTR;
+
+	/*
+	 * On first invocation this shouldn't be necessary, the call to
+	 * ipu_init_channel_buffer() above will set addresses for us, so we
+	 * could make it conditional on status >= IPU_CHANNEL_ENABLED, but
+	 * doing it again shouldn't hurt either.
+	 */
+	ret = ipu_update_channel_buffer(ichan, buf_idx,
+					sg_dma_address(sg));
+
+	if (ret < 0) {
+		dev_err(dev, "Updating sg %p on channel 0x%x buffer %d failed!\n",
+			sg, chan_id, buf_idx);
+		return ret;
+	}
+
+	ipu_select_buffer(chan_id, buf_idx);
+	dev_dbg(dev, "Updated sg %p on channel 0x%x buffer %d\n",
+		sg, chan_id, buf_idx);
+
+	return 0;
+}
+
+/* Called under spin_lock_irqsave(&ichan->lock) */
 static int ipu_submit_channel_buffers(struct idmac_channel *ichan,
 				      struct idmac_tx_desc *desc)
 {
@@ -815,20 +854,10 @@
 		if (!ichan->sg[i]) {
 			ichan->sg[i] = sg;
 
-			/*
-			 * On first invocation this shouldn't be necessary, the
-			 * call to ipu_init_channel_buffer() above will set
-			 * addresses for us, so we could make it conditional
-			 * on status >= IPU_CHANNEL_ENABLED, but doing it again
-			 * shouldn't hurt either.
-			 */
-			ret = ipu_update_channel_buffer(ichan->dma_chan.chan_id, i,
-							sg_dma_address(sg));
+			ret = ipu_submit_buffer(ichan, desc, sg, i);
 			if (ret < 0)
 				return ret;
 
-			ipu_select_buffer(ichan->dma_chan.chan_id, i);
-
 			sg = sg_next(sg);
 		}
 	}
@@ -842,19 +871,22 @@
 	struct idmac_channel *ichan = to_idmac_chan(tx->chan);
 	struct idmac *idmac = to_idmac(tx->chan->device);
 	struct ipu *ipu = to_ipu(idmac);
+	struct device *dev = &ichan->dma_chan.dev->device;
 	dma_cookie_t cookie;
 	unsigned long flags;
+	int ret;
 
 	/* Sanity check */
 	if (!list_empty(&desc->list)) {
 		/* The descriptor doesn't belong to client */
-		dev_err(&ichan->dma_chan.dev->device,
-			"Descriptor %p not prepared!\n", tx);
+		dev_err(dev, "Descriptor %p not prepared!\n", tx);
 		return -EBUSY;
 	}
 
 	mutex_lock(&ichan->chan_mutex);
 
+	async_tx_clear_ack(tx);
+
 	if (ichan->status < IPU_CHANNEL_READY) {
 		struct idmac_video_param *video = &ichan->params.video;
 		/*
@@ -878,16 +910,7 @@
 			goto out;
 	}
 
-	/* ipu->lock can be taken under ichan->lock, but not v.v. */
-	spin_lock_irqsave(&ichan->lock, flags);
-
-	/* submit_buffers() atomically verifies and fills empty sg slots */
-	cookie = ipu_submit_channel_buffers(ichan, desc);
-
-	spin_unlock_irqrestore(&ichan->lock, flags);
-
-	if (cookie < 0)
-		goto out;
+	dev_dbg(dev, "Submitting sg %p\n", &desc->sg[0]);
 
 	cookie = ichan->dma_chan.cookie;
 
@@ -897,24 +920,40 @@
 	/* from dmaengine.h: "last cookie value returned to client" */
 	ichan->dma_chan.cookie = cookie;
 	tx->cookie = cookie;
+
+	/* ipu->lock can be taken under ichan->lock, but not v.v. */
 	spin_lock_irqsave(&ichan->lock, flags);
+
 	list_add_tail(&desc->list, &ichan->queue);
+	/* submit_buffers() atomically verifies and fills empty sg slots */
+	ret = ipu_submit_channel_buffers(ichan, desc);
+
 	spin_unlock_irqrestore(&ichan->lock, flags);
 
+	if (ret < 0) {
+		cookie = ret;
+		goto dequeue;
+	}
+
 	if (ichan->status < IPU_CHANNEL_ENABLED) {
-		int ret = ipu_enable_channel(idmac, ichan);
+		ret = ipu_enable_channel(idmac, ichan);
 		if (ret < 0) {
 			cookie = ret;
-			spin_lock_irqsave(&ichan->lock, flags);
-			list_del_init(&desc->list);
-			spin_unlock_irqrestore(&ichan->lock, flags);
-			tx->cookie = cookie;
-			ichan->dma_chan.cookie = cookie;
+			goto dequeue;
 		}
 	}
 
 	dump_idmac_reg(ipu);
 
+dequeue:
+	if (cookie < 0) {
+		spin_lock_irqsave(&ichan->lock, flags);
+		list_del_init(&desc->list);
+		spin_unlock_irqrestore(&ichan->lock, flags);
+		tx->cookie = cookie;
+		ichan->dma_chan.cookie = cookie;
+	}
+
 out:
 	mutex_unlock(&ichan->chan_mutex);
 
@@ -944,8 +983,6 @@
 		memset(txd, 0, sizeof(*txd));
 		dma_async_tx_descriptor_init(txd, &ichan->dma_chan);
 		txd->tx_submit		= idmac_tx_submit;
-		txd->chan		= &ichan->dma_chan;
-		INIT_LIST_HEAD(&txd->tx_list);
 
 		list_add(&desc->list, &ichan->free_list);
 
@@ -1161,6 +1198,24 @@
 	return 0;
 }
 
+static struct scatterlist *idmac_sg_next(struct idmac_channel *ichan,
+	struct idmac_tx_desc **desc, struct scatterlist *sg)
+{
+	struct scatterlist *sgnew = sg ? sg_next(sg) : NULL;
+
+	if (sgnew)
+		/* next sg-element in this list */
+		return sgnew;
+
+	if ((*desc)->list.next == &ichan->queue)
+		/* No more descriptors on the queue */
+		return NULL;
+
+	/* Fetch next descriptor */
+	*desc = list_entry((*desc)->list.next, struct idmac_tx_desc, list);
+	return (*desc)->sg;
+}
+
 /*
  * We have several possibilities here:
  * current BUF		next BUF
@@ -1176,23 +1231,46 @@
 static irqreturn_t idmac_interrupt(int irq, void *dev_id)
 {
 	struct idmac_channel *ichan = dev_id;
+	struct device *dev = &ichan->dma_chan.dev->device;
 	unsigned int chan_id = ichan->dma_chan.chan_id;
 	struct scatterlist **sg, *sgnext, *sgnew = NULL;
 	/* Next transfer descriptor */
-	struct idmac_tx_desc *desc = NULL, *descnew;
+	struct idmac_tx_desc *desc, *descnew;
 	dma_async_tx_callback callback;
 	void *callback_param;
 	bool done = false;
-	u32	ready0 = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF0_RDY),
-		ready1 = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF1_RDY),
-		curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF);
+	u32 ready0, ready1, curbuf, err;
+	unsigned long flags;
 
 	/* IDMAC has cleared the respective BUFx_RDY bit, we manage the buffer */
 
-	pr_debug("IDMAC irq %d\n", irq);
+	dev_dbg(dev, "IDMAC irq %d, buf %d\n", irq, ichan->active_buffer);
+
+	spin_lock_irqsave(&ipu_data.lock, flags);
+
+	ready0	= idmac_read_ipureg(&ipu_data, IPU_CHA_BUF0_RDY);
+	ready1	= idmac_read_ipureg(&ipu_data, IPU_CHA_BUF1_RDY);
+	curbuf	= idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF);
+	err	= idmac_read_ipureg(&ipu_data, IPU_INT_STAT_4);
+
+	if (err & (1 << chan_id)) {
+		idmac_write_ipureg(&ipu_data, 1 << chan_id, IPU_INT_STAT_4);
+		spin_unlock_irqrestore(&ipu_data.lock, flags);
+		/*
+		 * Doing this
+		 * ichan->sg[0] = ichan->sg[1] = NULL;
+		 * you can force channel re-enable on the next tx_submit(), but
+		 * this is dirty - think about descriptors with multiple
+		 * sg elements.
+		 */
+		dev_warn(dev, "NFB4EOF on channel %d, ready %x, %x, cur %x\n",
+			 chan_id, ready0, ready1, curbuf);
+		return IRQ_HANDLED;
+	}
+	spin_unlock_irqrestore(&ipu_data.lock, flags);
+
 	/* Other interrupts do not interfere with this channel */
 	spin_lock(&ichan->lock);
-
 	if (unlikely(chan_id != IDMAC_SDC_0 && chan_id != IDMAC_SDC_1 &&
 		     ((curbuf >> chan_id) & 1) == ichan->active_buffer)) {
 		int i = 100;
@@ -1207,19 +1285,23 @@
 
 		if (!i) {
 			spin_unlock(&ichan->lock);
-			dev_dbg(ichan->dma_chan.device->dev,
+			dev_dbg(dev,
 				"IRQ on active buffer on channel %x, active "
 				"%d, ready %x, %x, current %x!\n", chan_id,
 				ichan->active_buffer, ready0, ready1, curbuf);
 			return IRQ_NONE;
-		}
+		} else
+			dev_dbg(dev,
+				"Buffer deactivated on channel %x, active "
+				"%d, ready %x, %x, current %x, rest %d!\n", chan_id,
+				ichan->active_buffer, ready0, ready1, curbuf, i);
 	}
 
 	if (unlikely((ichan->active_buffer && (ready1 >> chan_id) & 1) ||
 		     (!ichan->active_buffer && (ready0 >> chan_id) & 1)
 		     )) {
 		spin_unlock(&ichan->lock);
-		dev_dbg(ichan->dma_chan.device->dev,
+		dev_dbg(dev,
 			"IRQ with active buffer still ready on channel %x, "
 			"active %d, ready %x, %x!\n", chan_id,
 			ichan->active_buffer, ready0, ready1);
@@ -1227,8 +1309,9 @@
 	}
 
 	if (unlikely(list_empty(&ichan->queue))) {
+		ichan->sg[ichan->active_buffer] = NULL;
 		spin_unlock(&ichan->lock);
-		dev_err(ichan->dma_chan.device->dev,
+		dev_err(dev,
 			"IRQ without queued buffers on channel %x, active %d, "
 			"ready %x, %x!\n", chan_id,
 			ichan->active_buffer, ready0, ready1);
@@ -1243,40 +1326,44 @@
 	sg = &ichan->sg[ichan->active_buffer];
 	sgnext = ichan->sg[!ichan->active_buffer];
 
+	if (!*sg) {
+		spin_unlock(&ichan->lock);
+		return IRQ_HANDLED;
+	}
+
+	desc = list_entry(ichan->queue.next, struct idmac_tx_desc, list);
+	descnew = desc;
+
+	dev_dbg(dev, "IDMAC irq %d, dma 0x%08x, next dma 0x%08x, current %d, curbuf 0x%08x\n",
+		irq, sg_dma_address(*sg), sgnext ? sg_dma_address(sgnext) : 0, ichan->active_buffer, curbuf);
+
+	/* Find the descriptor of sgnext */
+	sgnew = idmac_sg_next(ichan, &descnew, *sg);
+	if (sgnext != sgnew)
+		dev_err(dev, "Submitted buffer %p, next buffer %p\n", sgnext, sgnew);
+
 	/*
 	 * if sgnext == NULL sg must be the last element in a scatterlist and
 	 * queue must be empty
 	 */
 	if (unlikely(!sgnext)) {
-		if (unlikely(sg_next(*sg))) {
-			dev_err(ichan->dma_chan.device->dev,
-				"Broken buffer-update locking on channel %x!\n",
-				chan_id);
-			/* We'll let the user catch up */
+		if (!WARN_ON(sg_next(*sg)))
+			dev_dbg(dev, "Underrun on channel %x\n", chan_id);
+		ichan->sg[!ichan->active_buffer] = sgnew;
+
+		if (unlikely(sgnew)) {
+			ipu_submit_buffer(ichan, descnew, sgnew, !ichan->active_buffer);
 		} else {
-			/* Underrun */
+			spin_lock_irqsave(&ipu_data.lock, flags);
 			ipu_ic_disable_task(&ipu_data, chan_id);
-			dev_dbg(ichan->dma_chan.device->dev,
-				"Underrun on channel %x\n", chan_id);
+			spin_unlock_irqrestore(&ipu_data.lock, flags);
 			ichan->status = IPU_CHANNEL_READY;
 			/* Continue to check for complete descriptor */
 		}
 	}
 
-	desc = list_entry(ichan->queue.next, struct idmac_tx_desc, list);
-
-	/* First calculate and submit the next sg element */
-	if (likely(sgnext))
-		sgnew = sg_next(sgnext);
-
-	if (unlikely(!sgnew)) {
-		/* Start a new scatterlist, if any queued */
-		if (likely(desc->list.next != &ichan->queue)) {
-			descnew = list_entry(desc->list.next,
-					     struct idmac_tx_desc, list);
-			sgnew = &descnew->sg[0];
-		}
-	}
+	/* Calculate and submit the next sg element */
+	sgnew = idmac_sg_next(ichan, &descnew, sgnew);
 
 	if (unlikely(!sg_next(*sg)) || !sgnext) {
 		/*
@@ -1289,17 +1376,13 @@
 
 	*sg = sgnew;
 
-	if (likely(sgnew)) {
-		int ret;
-
-		ret = ipu_update_channel_buffer(chan_id, ichan->active_buffer,
-						sg_dma_address(*sg));
-		if (ret < 0)
-			dev_err(ichan->dma_chan.device->dev,
-				"Failed to update buffer on channel %x buffer %d!\n",
-				chan_id, ichan->active_buffer);
-		else
-			ipu_select_buffer(chan_id, ichan->active_buffer);
+	if (likely(sgnew) &&
+	    ipu_submit_buffer(ichan, descnew, sgnew, ichan->active_buffer) < 0) {
+		callback = desc->txd.callback;
+		callback_param = desc->txd.callback_param;
+		spin_unlock(&ichan->lock);
+		callback(callback_param);
+		spin_lock(&ichan->lock);
 	}
 
 	/* Flip the active buffer - even if update above failed */
@@ -1327,13 +1410,20 @@
 		struct idmac_channel *ichan = ipu->channel + i;
 		struct idmac_tx_desc *desc;
 		unsigned long flags;
-		int j;
+		struct scatterlist *sg;
+		int j, k;
 
 		for (j = 0; j < ichan->n_tx_desc; j++) {
 			desc = ichan->desc + j;
 			spin_lock_irqsave(&ichan->lock, flags);
 			if (async_tx_test_ack(&desc->txd)) {
 				list_move(&desc->list, &ichan->free_list);
+				for_each_sg(desc->sg, sg, desc->sg_len, k) {
+					if (ichan->sg[0] == sg)
+						ichan->sg[0] = NULL;
+					else if (ichan->sg[1] == sg)
+						ichan->sg[1] = NULL;
+				}
 				async_tx_clear_ack(&desc->txd);
 			}
 			spin_unlock_irqrestore(&ichan->lock, flags);
@@ -1341,13 +1431,7 @@
 	}
 }
 
-/*
- * At the time .device_alloc_chan_resources() method is called, we cannot know,
- * whether the client will accept the channel. Thus we must only check, if we
- * can satisfy client's request but the only real criterion to verify, whether
- * the client has accepted our offer is the client_count. That's why we have to
- * perform the rest of our allocation tasks on the first call to this function.
- */
+/* Allocate and initialise a transfer descriptor. */
 static struct dma_async_tx_descriptor *idmac_prep_slave_sg(struct dma_chan *chan,
 		struct scatterlist *sgl, unsigned int sg_len,
 		enum dma_data_direction direction, unsigned long tx_flags)
@@ -1358,8 +1442,8 @@
 	unsigned long flags;
 
 	/* We only can handle these three channels so far */
-	if (ichan->dma_chan.chan_id != IDMAC_SDC_0 && ichan->dma_chan.chan_id != IDMAC_SDC_1 &&
-	    ichan->dma_chan.chan_id != IDMAC_IC_7)
+	if (chan->chan_id != IDMAC_SDC_0 && chan->chan_id != IDMAC_SDC_1 &&
+	    chan->chan_id != IDMAC_IC_7)
 		return NULL;
 
 	if (direction != DMA_FROM_DEVICE && direction != DMA_TO_DEVICE) {
@@ -1400,7 +1484,7 @@
 
 	/* This is not always needed, but doesn't hurt either */
 	spin_lock_irqsave(&ipu->lock, flags);
-	ipu_select_buffer(ichan->dma_chan.chan_id, ichan->active_buffer);
+	ipu_select_buffer(chan->chan_id, ichan->active_buffer);
 	spin_unlock_irqrestore(&ipu->lock, flags);
 
 	/*
@@ -1432,8 +1516,7 @@
 			struct idmac_tx_desc *desc = ichan->desc + i;
 			if (list_empty(&desc->list))
 				/* Descriptor was prepared, but not submitted */
-				list_add(&desc->list,
-					 &ichan->free_list);
+				list_add(&desc->list, &ichan->free_list);
 
 			async_tx_clear_ack(&desc->txd);
 		}
@@ -1458,6 +1541,28 @@
 	mutex_unlock(&ichan->chan_mutex);
 }
 
+#ifdef DEBUG
+static irqreturn_t ic_sof_irq(int irq, void *dev_id)
+{
+	struct idmac_channel *ichan = dev_id;
+	printk(KERN_DEBUG "Got SOF IRQ %d on Channel %d\n",
+	       irq, ichan->dma_chan.chan_id);
+	disable_irq(irq);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t ic_eof_irq(int irq, void *dev_id)
+{
+	struct idmac_channel *ichan = dev_id;
+	printk(KERN_DEBUG "Got EOF IRQ %d on Channel %d\n",
+	       irq, ichan->dma_chan.chan_id);
+	disable_irq(irq);
+	return IRQ_HANDLED;
+}
+
+static int ic_sof = -EINVAL, ic_eof = -EINVAL;
+#endif
+
 static int idmac_alloc_chan_resources(struct dma_chan *chan)
 {
 	struct idmac_channel *ichan = to_idmac_chan(chan);
@@ -1471,31 +1576,49 @@
 	chan->cookie		= 1;
 	ichan->completed	= -ENXIO;
 
-	ret = ipu_irq_map(ichan->dma_chan.chan_id);
+	ret = ipu_irq_map(chan->chan_id);
 	if (ret < 0)
 		goto eimap;
 
 	ichan->eof_irq = ret;
-	ret = request_irq(ichan->eof_irq, idmac_interrupt, 0,
-			  ichan->eof_name, ichan);
-	if (ret < 0)
-		goto erirq;
+
+	/*
+	 * Important to first disable the channel, because maybe someone
+	 * used it before us, e.g., the bootloader
+	 */
+	ipu_disable_channel(idmac, ichan, true);
 
 	ret = ipu_init_channel(idmac, ichan);
 	if (ret < 0)
 		goto eichan;
 
+	ret = request_irq(ichan->eof_irq, idmac_interrupt, 0,
+			  ichan->eof_name, ichan);
+	if (ret < 0)
+		goto erirq;
+
+#ifdef DEBUG
+	if (chan->chan_id == IDMAC_IC_7) {
+		ic_sof = ipu_irq_map(69);
+		if (ic_sof > 0)
+			request_irq(ic_sof, ic_sof_irq, 0, "IC SOF", ichan);
+		ic_eof = ipu_irq_map(70);
+		if (ic_eof > 0)
+			request_irq(ic_eof, ic_eof_irq, 0, "IC EOF", ichan);
+	}
+#endif
+
 	ichan->status = IPU_CHANNEL_INITIALIZED;
 
-	dev_dbg(&ichan->dma_chan.dev->device, "Found channel 0x%x, irq %d\n",
-		ichan->dma_chan.chan_id, ichan->eof_irq);
+	dev_dbg(&chan->dev->device, "Found channel 0x%x, irq %d\n",
+		chan->chan_id, ichan->eof_irq);
 
 	return ret;
 
-eichan:
-	free_irq(ichan->eof_irq, ichan);
 erirq:
-	ipu_irq_unmap(ichan->dma_chan.chan_id);
+	ipu_uninit_channel(idmac, ichan);
+eichan:
+	ipu_irq_unmap(chan->chan_id);
 eimap:
 	return ret;
 }
@@ -1510,8 +1633,22 @@
 	__idmac_terminate_all(chan);
 
 	if (ichan->status > IPU_CHANNEL_FREE) {
+#ifdef DEBUG
+		if (chan->chan_id == IDMAC_IC_7) {
+			if (ic_sof > 0) {
+				free_irq(ic_sof, ichan);
+				ipu_irq_unmap(69);
+				ic_sof = -EINVAL;
+			}
+			if (ic_eof > 0) {
+				free_irq(ic_eof, ichan);
+				ipu_irq_unmap(70);
+				ic_eof = -EINVAL;
+			}
+		}
+#endif
 		free_irq(ichan->eof_irq, ichan);
-		ipu_irq_unmap(ichan->dma_chan.chan_id);
+		ipu_irq_unmap(chan->chan_id);
 	}
 
 	ichan->status = IPU_CHANNEL_FREE;
@@ -1573,7 +1710,7 @@
 		dma_chan->device	= &idmac->dma;
 		dma_chan->cookie	= 1;
 		dma_chan->chan_id	= i;
-		list_add_tail(&ichan->dma_chan.device_node, &dma->channels);
+		list_add_tail(&dma_chan->device_node, &dma->channels);
 	}
 
 	idmac_write_icreg(ipu, 0x00000070, IDMAC_CONF);
@@ -1581,7 +1718,7 @@
 	return dma_async_device_register(&idmac->dma);
 }
 
-static void ipu_idmac_exit(struct ipu *ipu)
+static void __exit ipu_idmac_exit(struct ipu *ipu)
 {
 	int i;
 	struct idmac *idmac = &ipu->idmac;
@@ -1600,7 +1737,7 @@
  * IPU common probe / remove
  */
 
-static int ipu_probe(struct platform_device *pdev)
+static int __init ipu_probe(struct platform_device *pdev)
 {
 	struct ipu_platform_data *pdata = pdev->dev.platform_data;
 	struct resource *mem_ipu, *mem_ic;
@@ -1700,7 +1837,7 @@
 	return ret;
 }
 
-static int ipu_remove(struct platform_device *pdev)
+static int __exit ipu_remove(struct platform_device *pdev)
 {
 	struct ipu *ipu = platform_get_drvdata(pdev);
 
@@ -1725,7 +1862,7 @@
 		.name	= "ipu-core",
 		.owner	= THIS_MODULE,
 	},
-	.remove		= ipu_remove,
+	.remove		= __exit_p(ipu_remove),
 };
 
 static int __init ipu_init(void)
diff --git a/drivers/dma/ipu/ipu_irq.c b/drivers/dma/ipu/ipu_irq.c
index 83f532c..dd8ebc7 100644
--- a/drivers/dma/ipu/ipu_irq.c
+++ b/drivers/dma/ipu/ipu_irq.c
@@ -352,7 +352,7 @@
 };
 
 /* Install the IRQ handler */
-int ipu_irq_attach_irq(struct ipu *ipu, struct platform_device *dev)
+int __init ipu_irq_attach_irq(struct ipu *ipu, struct platform_device *dev)
 {
 	struct ipu_platform_data *pdata = dev->dev.platform_data;
 	unsigned int irq, irq_base, i;
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index cb7f26f..ddab94f 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -632,7 +632,6 @@
 		slot->async_tx.tx_submit = mv_xor_tx_submit;
 		INIT_LIST_HEAD(&slot->chain_node);
 		INIT_LIST_HEAD(&slot->slot_node);
-		INIT_LIST_HEAD(&slot->async_tx.tx_list);
 		hw_desc = (char *) mv_chan->device->dma_desc_pool;
 		slot->async_tx.phys =
 			(dma_addr_t) &hw_desc[idx * MV_XOR_SLOT_SIZE];
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 3d25654..edb0253 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -42,9 +42,9 @@
 	depends on DEBUG_KERNEL
 	help
 	  Say Y here to add some extra checks and diagnostics to GPIO calls.
-	  The checks help ensure that GPIOs have been properly initialized
-	  before they are used and that sleeping calls aren not made from
-	  nonsleeping contexts.  They can make bitbanged serial protocols
+	  These checks help ensure that GPIOs have been properly initialized
+	  before they are used, and that sleeping calls are not made from
+	  non-sleeping contexts.  They can make bitbanged serial protocols
 	  slower.  The diagnostics help catch the type of setup errors
 	  that are most common when setting up new platforms or boards.
 
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index c23b3a9..a000cf0 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1179,8 +1179,6 @@
 	if (!IS_I945G(dev) && !IS_I945GM(dev))
 		pci_enable_msi(dev->pdev);
 
-	intel_opregion_init(dev);
-
 	spin_lock_init(&dev_priv->user_irq_lock);
 	dev_priv->user_irq_refcount = 0;
 
@@ -1199,6 +1197,9 @@
 		}
 	}
 
+	/* Must be done after probing outputs */
+	intel_opregion_init(dev, 0);
+
 	return 0;
 
 out_iomapfree:
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 2c01676..6503e22 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -101,7 +101,7 @@
 
 	i915_restore_state(dev);
 
-	intel_opregion_init(dev);
+	intel_opregion_init(dev, 1);
 
 	/* KMS EnterVT equivalent */
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 317b122..3750d80 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -666,12 +666,12 @@
 
 #ifdef CONFIG_ACPI
 /* i915_opregion.c */
-extern int intel_opregion_init(struct drm_device *dev);
+extern int intel_opregion_init(struct drm_device *dev, int resume);
 extern void intel_opregion_free(struct drm_device *dev);
 extern void opregion_asle_intr(struct drm_device *dev);
 extern void opregion_enable_asle(struct drm_device *dev);
 #else
-static inline int intel_opregion_init(struct drm_device *dev) { return 0; }
+static inline int intel_opregion_init(struct drm_device *dev, int resume) { return 0; }
 static inline void intel_opregion_free(struct drm_device *dev) { return; }
 static inline void opregion_asle_intr(struct drm_device *dev) { return; }
 static inline void opregion_enable_asle(struct drm_device *dev) { return; }
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c
index ff01283..6942772 100644
--- a/drivers/gpu/drm/i915/i915_opregion.c
+++ b/drivers/gpu/drm/i915/i915_opregion.c
@@ -26,6 +26,7 @@
  */
 
 #include <linux/acpi.h>
+#include <acpi/video.h>
 
 #include "drmP.h"
 #include "i915_drm.h"
@@ -136,6 +137,12 @@
 
 #define ASLE_CBLV_VALID         (1<<31)
 
+#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)
+
 static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -282,7 +289,58 @@
 	.notifier_call = intel_opregion_video_event,
 };
 
-int intel_opregion_init(struct drm_device *dev)
+/*
+ * 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 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;
+	int i = 0;
+
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		int output_type = ACPI_OTHER_OUTPUT;
+		if (i >= 8) {
+			dev_printk (KERN_ERR, &dev->pdev->dev,
+				    "More than 8 outputs detected\n");
+			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;
+		}
+		opregion->acpi->didl[i] |= (1<<31) | output_type | i;
+		i++;
+	}
+
+	/* If fewer than 8 outputs, the list must be null terminated */
+	if (i < 8)
+		opregion->acpi->didl[i] = 0;
+}
+
+int intel_opregion_init(struct drm_device *dev, int resume)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_opregion *opregion = &dev_priv->opregion;
@@ -312,6 +370,11 @@
 	if (mboxes & MBOX_ACPI) {
 		DRM_DEBUG("Public ACPI methods supported\n");
 		opregion->acpi = base + OPREGION_ACPI_OFFSET;
+		if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+			intel_didl_outputs(dev);
+			if (!resume)
+				acpi_video_register();
+		}
 	} else {
 		DRM_DEBUG("Public ACPI methods not supported\n");
 		err = -ENOTSUPP;
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index e85c8fe..7e67dcb 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -29,11 +29,11 @@
 
 	  For docs and specs, see http://www.usb.org/developers/hidpage/
 
-	  If unsure, say Y
+	  If unsure, say Y.
 
 config HID_DEBUG
 	bool "HID debugging support"
-	default y if !EMBEDDED
+	default y
 	depends on HID
 	---help---
 	This option lets the HID layer output diagnostics about its internal
@@ -44,7 +44,7 @@
 	This feature is useful for those who are either debugging the HID parser
 	or any HID hardware device.
 
-	If unsure, say N
+	If unsure, say Y.
 
 config HIDRAW
 	bool "/dev/hidraw raw HID device support"
@@ -70,18 +70,6 @@
 menu "Special HID drivers"
 	depends on HID
 
-config HID_COMPAT
-	bool "Load all HID drivers on hid core load"
-	default y
-	---help---
-	Compatible option for older userspace. If you have system without udev
-	support of module loading through aliases and also old
-	module-init-tools which can't handle hid bus, choose Y here. Otherwise
-	say N. If you say N and your userspace is old enough, the only
-	functionality you lose is modules autoloading.
-
-	If unsure, say Y.
-
 config HID_A4TECH
 	tristate "A4 tech" if EMBEDDED
 	depends on USB_HID
@@ -128,6 +116,14 @@
 	---help---
 	Support for cypress mouse and barcode readers.
 
+config DRAGONRISE_FF
+	tristate "DragonRise Inc. force feedback support"
+	depends on USB_HID
+	select INPUT_FF_MEMLESS
+	---help---
+	Say Y here if you want to enable force feedback support for DragonRise Inc.
+	game controllers.
+
 config HID_EZKEY
 	tristate "Ezkey" if EMBEDDED
 	depends on USB_HID
@@ -135,6 +131,13 @@
 	---help---
 	Support for Ezkey BTC 8193 keyboard.
 
+config HID_KYE
+	tristate "Kye" if EMBEDDED
+	depends on USB_HID
+	default !EMBEDDED
+	---help---
+	Support for Kye/Genius Ergo Mouse.
+
 config HID_GYRATION
 	tristate "Gyration" if EMBEDDED
 	depends on USB_HID
@@ -142,6 +145,13 @@
 	---help---
 	Support for Gyration remote control.
 
+config HID_KENSINGTON
+	tristate "Kensington" if EMBEDDED
+	depends on USB_HID
+	default !EMBEDDED
+	---help---
+	Support for Kensington Slimblade Trackball.
+
 config HID_LOGITECH
 	tristate "Logitech" if EMBEDDED
 	depends on USB_HID
@@ -243,7 +253,7 @@
 	select INPUT_FF_MEMLESS
 	---help---
 	Say Y here if you have a GreenAsia (Product ID 0x12) based game controller
-	(like MANTA Warior MM816 and SpeedLink Strike2 SL-6635) or adapter
+	(like MANTA Warrior MM816 and SpeedLink Strike2 SL-6635) or adapter
 	and want to enable force feedback support for it.
 
 config HID_TOPSEED
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index fbd021f..1f7cb0f 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -8,10 +8,6 @@
 hid-$(CONFIG_HID_DEBUG)		+= hid-debug.o
 hid-$(CONFIG_HIDRAW)		+= hidraw.o
 
-ifdef CONFIG_HID_COMPAT
-obj-m				+= hid-dummy.o
-endif
-
 hid-logitech-objs		:= hid-lg.o
 ifdef CONFIG_LOGITECH_FF
 	hid-logitech-objs	+= hid-lgff.o
@@ -26,8 +22,11 @@
 obj-$(CONFIG_HID_CHERRY)	+= hid-cherry.o
 obj-$(CONFIG_HID_CHICONY)	+= hid-chicony.o
 obj-$(CONFIG_HID_CYPRESS)	+= hid-cypress.o
+obj-$(CONFIG_DRAGONRISE_FF)	+= hid-drff.o
 obj-$(CONFIG_HID_EZKEY)		+= hid-ezkey.o
 obj-$(CONFIG_HID_GYRATION)	+= hid-gyration.o
+obj-$(CONFIG_HID_KENSINGTON)	+= hid-kensington.o
+obj-$(CONFIG_HID_KYE)		+= hid-kye.o
 obj-$(CONFIG_HID_LOGITECH)	+= hid-logitech.o
 obj-$(CONFIG_HID_MICROSOFT)	+= hid-microsoft.o
 obj-$(CONFIG_HID_MONTEREY)	+= hid-monterey.o
diff --git a/drivers/hid/hid-a4tech.c b/drivers/hid/hid-a4tech.c
index ebca00e..42ea359 100644
--- a/drivers/hid/hid-a4tech.c
+++ b/drivers/hid/hid-a4tech.c
@@ -158,5 +158,3 @@
 module_init(a4_init);
 module_exit(a4_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(a4tech);
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
index aa28aed..7359d9d 100644
--- a/drivers/hid/hid-apple.c
+++ b/drivers/hid/hid-apple.c
@@ -53,7 +53,7 @@
 	u8 flags;
 };
 
-static struct apple_key_translation apple_fn_keys[] = {
+static const struct apple_key_translation apple_fn_keys[] = {
 	{ KEY_BACKSPACE, KEY_DELETE },
 	{ KEY_ENTER,	KEY_INSERT },
 	{ KEY_F1,	KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
@@ -75,7 +75,7 @@
 	{ }
 };
 
-static struct apple_key_translation powerbook_fn_keys[] = {
+static const struct apple_key_translation powerbook_fn_keys[] = {
 	{ KEY_BACKSPACE, KEY_DELETE },
 	{ KEY_F1,	KEY_BRIGHTNESSDOWN,     APPLE_FLAG_FKEY },
 	{ KEY_F2,	KEY_BRIGHTNESSUP,       APPLE_FLAG_FKEY },
@@ -94,7 +94,7 @@
 	{ }
 };
 
-static struct apple_key_translation powerbook_numlock_keys[] = {
+static const struct apple_key_translation powerbook_numlock_keys[] = {
 	{ KEY_J,	KEY_KP1 },
 	{ KEY_K,	KEY_KP2 },
 	{ KEY_L,	KEY_KP3 },
@@ -117,16 +117,16 @@
 	{ }
 };
 
-static struct apple_key_translation apple_iso_keyboard[] = {
+static const struct apple_key_translation apple_iso_keyboard[] = {
 	{ KEY_GRAVE,	KEY_102ND },
 	{ KEY_102ND,	KEY_GRAVE },
 	{ }
 };
 
-static struct apple_key_translation *apple_find_translation(
-		struct apple_key_translation *table, u16 from)
+static const struct apple_key_translation *apple_find_translation(
+		const struct apple_key_translation *table, u16 from)
 {
-	struct apple_key_translation *trans;
+	const struct apple_key_translation *trans;
 
 	/* Look for the translation */
 	for (trans = table; trans->from; trans++)
@@ -140,7 +140,7 @@
 		struct hid_usage *usage, __s32 value)
 {
 	struct apple_sc *asc = hid_get_drvdata(hid);
-	struct apple_key_translation *trans;
+	const struct apple_key_translation *trans;
 
 	if (usage->code == KEY_FN) {
 		asc->fn_on = !!value;
@@ -253,7 +253,7 @@
 
 static void apple_setup_input(struct input_dev *input)
 {
-	struct apple_key_translation *trans;
+	const struct apple_key_translation *trans;
 
 	set_bit(KEY_NUMLOCK, input->keybit);
 
@@ -387,6 +387,12 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS),
 		.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
 			APPLE_RDESC_JIS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ANSI),
+		.driver_data = APPLE_HAS_FN },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ISO),
+		.driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_JIS),
+		.driver_data = APPLE_HAS_FN },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI),
 		.driver_data = APPLE_HAS_FN },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO),
@@ -468,5 +474,3 @@
 module_init(apple_init);
 module_exit(apple_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(apple);
diff --git a/drivers/hid/hid-belkin.c b/drivers/hid/hid-belkin.c
index 12c8a9b..2f67231 100644
--- a/drivers/hid/hid-belkin.c
+++ b/drivers/hid/hid-belkin.c
@@ -101,5 +101,3 @@
 module_init(belkin_init);
 module_exit(belkin_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(belkin);
diff --git a/drivers/hid/hid-cherry.c b/drivers/hid/hid-cherry.c
index b833b97..ab8209e 100644
--- a/drivers/hid/hid-cherry.c
+++ b/drivers/hid/hid-cherry.c
@@ -83,5 +83,3 @@
 module_init(ch_init);
 module_exit(ch_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(cherry);
diff --git a/drivers/hid/hid-chicony.c b/drivers/hid/hid-chicony.c
index a54d409..7f91076 100644
--- a/drivers/hid/hid-chicony.c
+++ b/drivers/hid/hid-chicony.c
@@ -76,5 +76,3 @@
 module_init(ch_init);
 module_exit(ch_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(chicony);
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 1cc9674..5746a59 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1236,6 +1236,9 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ANSI) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ISO) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_JIS) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS) },
@@ -1262,6 +1265,7 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) },
@@ -1269,6 +1273,8 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },
@@ -1813,14 +1819,21 @@
 }
 EXPORT_SYMBOL_GPL(hid_unregister_driver);
 
-#ifdef CONFIG_HID_COMPAT
-static void hid_compat_load(struct work_struct *ws)
+int hid_check_keys_pressed(struct hid_device *hid)
 {
-	request_module("hid-dummy");
+	struct hid_input *hidinput;
+	int i;
+
+	list_for_each_entry(hidinput, &hid->inputs, list) {
+		for (i = 0; i < BITS_TO_LONGS(KEY_MAX); i++)
+			if (hidinput->input->key[i])
+				return 1;
+	}
+
+	return 0;
 }
-static DECLARE_WORK(hid_compat_work, hid_compat_load);
-static struct workqueue_struct *hid_compat_wq;
-#endif
+
+EXPORT_SYMBOL_GPL(hid_check_keys_pressed);
 
 static int __init hid_init(void)
 {
@@ -1836,15 +1849,6 @@
 	if (ret)
 		goto err_bus;
 
-#ifdef CONFIG_HID_COMPAT
-	hid_compat_wq = create_singlethread_workqueue("hid_compat");
-	if (!hid_compat_wq) {
-		hidraw_exit();
-		goto err;
-	}
-	queue_work(hid_compat_wq, &hid_compat_work);
-#endif
-
 	return 0;
 err_bus:
 	bus_unregister(&hid_bus_type);
@@ -1854,9 +1858,6 @@
 
 static void __exit hid_exit(void)
 {
-#ifdef CONFIG_HID_COMPAT
-	destroy_workqueue(hid_compat_wq);
-#endif
 	hidraw_exit();
 	bus_unregister(&hid_bus_type);
 }
diff --git a/drivers/hid/hid-cypress.c b/drivers/hid/hid-cypress.c
index 5d69d27..9d6d3b9 100644
--- a/drivers/hid/hid-cypress.c
+++ b/drivers/hid/hid-cypress.c
@@ -154,5 +154,3 @@
 module_init(cp_init);
 module_exit(cp_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(cypress);
diff --git a/drivers/hid/hid-drff.c b/drivers/hid/hid-drff.c
new file mode 100644
index 0000000..34f3eb65
--- /dev/null
+++ b/drivers/hid/hid-drff.c
@@ -0,0 +1,188 @@
+/*
+ * Force feedback support for DragonRise Inc. game controllers
+ *
+ * From what I have gathered, these devices are mass produced in China and are
+ * distributed under several vendors. They often share the same design as
+ * the original PlayStation DualShock controller.
+ *
+ * 0079:0006 "DragonRise Inc.   Generic   USB  Joystick  "
+ *  - tested with a Tesun USB-703 game controller.
+ *
+ * Copyright (c) 2009 Richard Walmsley <richwalm@gmail.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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/input.h>
+#include <linux/usb.h>
+#include <linux/hid.h>
+
+#include "hid-ids.h"
+#include "usbhid/usbhid.h"
+
+struct drff_device {
+	struct hid_report *report;
+};
+
+static int drff_play(struct input_dev *dev, void *data,
+				 struct ff_effect *effect)
+{
+	struct hid_device *hid = input_get_drvdata(dev);
+	struct drff_device *drff = data;
+	int strong, weak;
+
+	strong = effect->u.rumble.strong_magnitude;
+	weak = effect->u.rumble.weak_magnitude;
+
+	dbg_hid("called with 0x%04x 0x%04x", strong, weak);
+
+	if (strong || weak) {
+		strong = strong * 0xff / 0xffff;
+		weak = weak * 0xff / 0xffff;
+
+		/* While reverse engineering this device, I found that when
+		   this value is set, it causes the strong rumble to function
+		   at a near maximum speed, so we'll bypass it. */
+		if (weak == 0x0a)
+			weak = 0x0b;
+
+		drff->report->field[0]->value[0] = 0x51;
+		drff->report->field[0]->value[1] = 0x00;
+		drff->report->field[0]->value[2] = weak;
+		drff->report->field[0]->value[4] = strong;
+		usbhid_submit_report(hid, drff->report, USB_DIR_OUT);
+
+		drff->report->field[0]->value[0] = 0xfa;
+		drff->report->field[0]->value[1] = 0xfe;
+	} else {
+		drff->report->field[0]->value[0] = 0xf3;
+		drff->report->field[0]->value[1] = 0x00;
+	}
+
+	drff->report->field[0]->value[2] = 0x00;
+	drff->report->field[0]->value[4] = 0x00;
+	dbg_hid("running with 0x%02x 0x%02x", strong, weak);
+	usbhid_submit_report(hid, drff->report, USB_DIR_OUT);
+
+	return 0;
+}
+
+static int drff_init(struct hid_device *hid)
+{
+	struct drff_device *drff;
+	struct hid_report *report;
+	struct hid_input *hidinput = list_first_entry(&hid->inputs,
+						struct hid_input, list);
+	struct list_head *report_list =
+			&hid->report_enum[HID_OUTPUT_REPORT].report_list;
+	struct input_dev *dev = hidinput->input;
+	int error;
+
+	if (list_empty(report_list)) {
+		dev_err(&hid->dev, "no output reports found\n");
+		return -ENODEV;
+	}
+
+	report = list_first_entry(report_list, struct hid_report, list);
+	if (report->maxfield < 1) {
+		dev_err(&hid->dev, "no fields in the report\n");
+		return -ENODEV;
+	}
+
+	if (report->field[0]->report_count < 7) {
+		dev_err(&hid->dev, "not enough values in the field\n");
+		return -ENODEV;
+	}
+
+	drff = kzalloc(sizeof(struct drff_device), GFP_KERNEL);
+	if (!drff)
+		return -ENOMEM;
+
+	set_bit(FF_RUMBLE, dev->ffbit);
+
+	error = input_ff_create_memless(dev, drff, drff_play);
+	if (error) {
+		kfree(drff);
+		return error;
+	}
+
+	drff->report = report;
+	drff->report->field[0]->value[0] = 0xf3;
+	drff->report->field[0]->value[1] = 0x00;
+	drff->report->field[0]->value[2] = 0x00;
+	drff->report->field[0]->value[3] = 0x00;
+	drff->report->field[0]->value[4] = 0x00;
+	drff->report->field[0]->value[5] = 0x00;
+	drff->report->field[0]->value[6] = 0x00;
+	usbhid_submit_report(hid, drff->report, USB_DIR_OUT);
+
+	dev_info(&hid->dev, "Force Feedback for DragonRise Inc. game "
+	       "controllers by Richard Walmsley <richwalm@gmail.com>\n");
+
+	return 0;
+}
+
+static int dr_probe(struct hid_device *hdev, const struct hid_device_id *id)
+{
+	int ret;
+
+	dev_dbg(&hdev->dev, "DragonRise Inc. HID hardware probe...");
+
+	ret = hid_parse(hdev);
+	if (ret) {
+		dev_err(&hdev->dev, "parse failed\n");
+		goto err;
+	}
+
+	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
+	if (ret) {
+		dev_err(&hdev->dev, "hw start failed\n");
+		goto err;
+	}
+
+	drff_init(hdev);
+
+	return 0;
+err:
+	return ret;
+}
+
+static const struct hid_device_id dr_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006),  },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, dr_devices);
+
+static struct hid_driver dr_driver = {
+	.name = "dragonrise",
+	.id_table = dr_devices,
+	.probe = dr_probe,
+};
+
+static int __init dr_init(void)
+{
+	return hid_register_driver(&dr_driver);
+}
+
+static void __exit dr_exit(void)
+{
+	hid_unregister_driver(&dr_driver);
+}
+
+module_init(dr_init);
+module_exit(dr_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-dummy.c b/drivers/hid/hid-dummy.c
deleted file mode 100644
index b4cc0f7..0000000
--- a/drivers/hid/hid-dummy.c
+++ /dev/null
@@ -1,78 +0,0 @@
-#include <linux/autoconf.h>
-#include <linux/module.h>
-#include <linux/hid.h>
-
-static int __init hid_dummy_init(void)
-{
-#ifdef CONFIG_HID_A4TECH_MODULE
-	HID_COMPAT_CALL_DRIVER(a4tech);
-#endif
-#ifdef CONFIG_HID_APPLE_MODULE
-	HID_COMPAT_CALL_DRIVER(apple);
-#endif
-#ifdef CONFIG_HID_BELKIN_MODULE
-	HID_COMPAT_CALL_DRIVER(belkin);
-#endif
-#ifdef CONFIG_HID_BRIGHT_MODULE
-	HID_COMPAT_CALL_DRIVER(bright);
-#endif
-#ifdef CONFIG_HID_CHERRY_MODULE
-	HID_COMPAT_CALL_DRIVER(cherry);
-#endif
-#ifdef CONFIG_HID_CHICONY_MODULE
-	HID_COMPAT_CALL_DRIVER(chicony);
-#endif
-#ifdef CONFIG_HID_CYPRESS_MODULE
-	HID_COMPAT_CALL_DRIVER(cypress);
-#endif
-#ifdef CONFIG_HID_DELL_MODULE
-	HID_COMPAT_CALL_DRIVER(dell);
-#endif
-#ifdef CONFIG_HID_EZKEY_MODULE
-	HID_COMPAT_CALL_DRIVER(ezkey);
-#endif
-#ifdef CONFIG_HID_GYRATION_MODULE
-	HID_COMPAT_CALL_DRIVER(gyration);
-#endif
-#ifdef CONFIG_HID_LOGITECH_MODULE
-	HID_COMPAT_CALL_DRIVER(logitech);
-#endif
-#ifdef CONFIG_HID_MICROSOFT_MODULE
-	HID_COMPAT_CALL_DRIVER(microsoft);
-#endif
-#ifdef CONFIG_HID_MONTEREY_MODULE
-	HID_COMPAT_CALL_DRIVER(monterey);
-#endif
-#ifdef CONFIG_HID_NTRIG_MODULE
-	HID_COMPAT_CALL_DRIVER(ntrig);
-#endif
-#ifdef CONFIG_HID_PANTHERLORD_MODULE
-	HID_COMPAT_CALL_DRIVER(pantherlord);
-#endif
-#ifdef CONFIG_HID_PETALYNX_MODULE
-	HID_COMPAT_CALL_DRIVER(petalynx);
-#endif
-#ifdef CONFIG_HID_SAMSUNG_MODULE
-	HID_COMPAT_CALL_DRIVER(samsung);
-#endif
-#ifdef CONFIG_HID_SONY_MODULE
-	HID_COMPAT_CALL_DRIVER(sony);
-#endif
-#ifdef CONFIG_HID_SUNPLUS_MODULE
-	HID_COMPAT_CALL_DRIVER(sunplus);
-#endif
-#ifdef CONFIG_GREENASIA_FF_MODULE
-	HID_COMPAT_CALL_DRIVER(greenasia);
-#endif
-#ifdef CONFIG_THRUSTMASTER_FF_MODULE
-	HID_COMPAT_CALL_DRIVER(thrustmaster);
-#endif
-#ifdef CONFIG_ZEROPLUS_FF_MODULE
-	HID_COMPAT_CALL_DRIVER(zeroplus);
-#endif
-
-	return -EIO;
-}
-module_init(hid_dummy_init);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-ezkey.c b/drivers/hid/hid-ezkey.c
index deb42f9..0a1fe05 100644
--- a/drivers/hid/hid-ezkey.c
+++ b/drivers/hid/hid-ezkey.c
@@ -91,5 +91,3 @@
 module_init(ez_init);
 module_exit(ez_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(ezkey);
diff --git a/drivers/hid/hid-gaff.c b/drivers/hid/hid-gaff.c
index 71211f6..510ad3a 100644
--- a/drivers/hid/hid-gaff.c
+++ b/drivers/hid/hid-gaff.c
@@ -181,5 +181,3 @@
 module_init(ga_init);
 module_exit(ga_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(greenasia);
diff --git a/drivers/hid/hid-gyration.c b/drivers/hid/hid-gyration.c
index 04a0afe..d42d222 100644
--- a/drivers/hid/hid-gyration.c
+++ b/drivers/hid/hid-gyration.c
@@ -94,5 +94,3 @@
 module_init(gyration_init);
 module_exit(gyration_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(gyration);
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 8851197..bdeda4c 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -67,6 +67,9 @@
 #define USB_DEVICE_ID_APPLE_GEYSER4_ANSI	0x021a
 #define USB_DEVICE_ID_APPLE_GEYSER4_ISO	0x021b
 #define USB_DEVICE_ID_APPLE_GEYSER4_JIS	0x021c
+#define USB_DEVICE_ID_APPLE_ALU_MINI_ANSI	0x021d
+#define USB_DEVICE_ID_APPLE_ALU_MINI_ISO	0x021e
+#define USB_DEVICE_ID_APPLE_ALU_MINI_JIS	0x021f
 #define USB_DEVICE_ID_APPLE_ALU_ANSI	0x0220
 #define USB_DEVICE_ID_APPLE_ALU_ISO	0x0221
 #define USB_DEVICE_ID_APPLE_ALU_JIS	0x0222
@@ -148,6 +151,8 @@
 #define USB_VENDOR_ID_DMI		0x0c0b
 #define USB_DEVICE_ID_DMI_ENC		0x5fab
 
+#define USB_VENDOR_ID_DRAGONRISE	0x0079
+
 #define USB_VENDOR_ID_ELO		0x04E7
 #define USB_DEVICE_ID_ELO_TS2700	0x0020
 
@@ -272,6 +277,9 @@
 #define USB_DEVICE_ID_LD_POWERCONTROL	0x2030
 #define USB_DEVICE_ID_LD_MACHINETEST	0x2040
 
+#define USB_VENDOR_ID_KENSINGTON	0x047d
+#define USB_DEVICE_ID_KS_SLIMBLADE	0x2041
+
 #define USB_VENDOR_ID_LOGITECH		0x046d
 #define USB_DEVICE_ID_LOGITECH_RECEIVER	0xc101
 #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST  0xc110
@@ -418,6 +426,8 @@
 #define USB_VENDOR_ID_ZEROPLUS		0x0c12
 
 #define USB_VENDOR_ID_KYE		0x0458
+#define USB_DEVICE_ID_KYE_ERGO_525V	0x0087
 #define USB_DEVICE_ID_KYE_GPEN_560	0x5003
 
+
 #endif
diff --git a/drivers/hid/hid-kensington.c b/drivers/hid/hid-kensington.c
new file mode 100644
index 0000000..7353bd7
--- /dev/null
+++ b/drivers/hid/hid-kensington.c
@@ -0,0 +1,63 @@
+/*
+ *  HID driver for Kensigton Slimblade Trackball
+ *
+ *  Copyright (c) 2009 Jiri Kosina
+ */
+
+/*
+ * 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/device.h>
+#include <linux/input.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+
+#include "hid-ids.h"
+
+#define ks_map_key(c)	hid_map_usage(hi, usage, bit, max, EV_KEY, (c))
+
+static int ks_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+		struct hid_field *field, struct hid_usage *usage,
+		unsigned long **bit, int *max)
+{
+	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
+		return 0;
+
+	switch (usage->hid & HID_USAGE) {
+	case 0x01: ks_map_key(BTN_MIDDLE);	break;
+	case 0x02: ks_map_key(BTN_SIDE);	break;
+	default:
+		return 0;
+	}
+	return 1;
+}
+
+static const struct hid_device_id ks_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, ks_devices);
+
+static struct hid_driver ks_driver = {
+	.name = "kensington",
+	.id_table = ks_devices,
+	.input_mapping = ks_input_mapping,
+};
+
+static int ks_init(void)
+{
+	return hid_register_driver(&ks_driver);
+}
+
+static void ks_exit(void)
+{
+	hid_unregister_driver(&ks_driver);
+}
+
+module_init(ks_init);
+module_exit(ks_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-kye.c b/drivers/hid/hid-kye.c
new file mode 100644
index 0000000..72ee3fe
--- /dev/null
+++ b/drivers/hid/hid-kye.c
@@ -0,0 +1,69 @@
+/*
+ *  HID driver for Kye/Genius devices not fully compliant with HID standard
+ *
+ *  Copyright (c) 2009 Jiri Kosina
+ *  Copyright (c) 2009 Tomas Hanak
+ */
+
+/*
+ * 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/device.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+
+#include "hid-ids.h"
+
+/* the fixups that need to be done:
+ *   - change led usage page to button for extra buttons
+ *   - report size 8 count 1 must be size 1 count 8 for button bitfield
+ *   - change the button usage range to 4-7 for the extra buttons
+ */
+static void kye_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+		unsigned int rsize)
+{
+	if (rsize >= 74 &&
+		rdesc[61] == 0x05 && rdesc[62] == 0x08 &&
+		rdesc[63] == 0x19 && rdesc[64] == 0x08 &&
+		rdesc[65] == 0x29 && rdesc[66] == 0x0f &&
+		rdesc[71] == 0x75 && rdesc[72] == 0x08 &&
+		rdesc[73] == 0x95 && rdesc[74] == 0x01) {
+		dev_info(&hdev->dev, "fixing up Kye/Genius Ergo Mouse report "
+				"descriptor\n");
+		rdesc[62] = 0x09;
+		rdesc[64] = 0x04;
+		rdesc[66] = 0x07;
+		rdesc[72] = 0x01;
+		rdesc[74] = 0x08;
+	}
+}
+
+static const struct hid_device_id kye_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, kye_devices);
+
+static struct hid_driver kye_driver = {
+	.name = "kye",
+	.id_table = kye_devices,
+	.report_fixup = kye_report_fixup,
+};
+
+static int kye_init(void)
+{
+	return hid_register_driver(&kye_driver);
+}
+
+static void kye_exit(void)
+{
+	hid_unregister_driver(&kye_driver);
+}
+
+module_init(kye_init);
+module_exit(kye_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
index 83e07c9..7b80cb6 100644
--- a/drivers/hid/hid-lg.c
+++ b/drivers/hid/hid-lg.c
@@ -326,5 +326,3 @@
 module_init(lg_init);
 module_exit(lg_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(logitech);
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 25b10dc..5e9e37a 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -210,5 +210,3 @@
 module_init(ms_init);
 module_exit(ms_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(microsoft);
diff --git a/drivers/hid/hid-monterey.c b/drivers/hid/hid-monterey.c
index f3a85a0..240f876 100644
--- a/drivers/hid/hid-monterey.c
+++ b/drivers/hid/hid-monterey.c
@@ -78,5 +78,3 @@
 module_init(mr_init);
 module_exit(mr_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(monterey);
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c
index db44fbd..c5b252b 100644
--- a/drivers/hid/hid-ntrig.c
+++ b/drivers/hid/hid-ntrig.c
@@ -78,5 +78,3 @@
 module_init(ntrig_init);
 module_exit(ntrig_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(ntrig);
diff --git a/drivers/hid/hid-petalynx.c b/drivers/hid/hid-petalynx.c
index 10945fe..2e83e8f 100644
--- a/drivers/hid/hid-petalynx.c
+++ b/drivers/hid/hid-petalynx.c
@@ -118,5 +118,3 @@
 module_init(pl_init);
 module_exit(pl_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(petalynx);
diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c
index 46941f9..4db9a34 100644
--- a/drivers/hid/hid-pl.c
+++ b/drivers/hid/hid-pl.c
@@ -9,9 +9,12 @@
  *   - contains two reports, one for each port (HID_QUIRK_MULTI_INPUT)
  *
  *  0e8f:0003 "GreenAsia Inc.    USB Joystick     "
- *   - tested with K??ng Gaming gamepad
+ *   - tested with König Gaming gamepad
  *
- *  Copyright (c) 2007 Anssi Hannula <anssi.hannula@gmail.com>
+ *  0e8f:0003 "GASIA USB Gamepad"
+ *   - another version of the König gamepad
+ *
+ *  Copyright (c) 2007, 2009 Anssi Hannula <anssi.hannula@gmail.com>
  */
 
 /*
@@ -46,6 +49,8 @@
 
 struct plff_device {
 	struct hid_report *report;
+	s32 *strong;
+	s32 *weak;
 };
 
 static int hid_plff_play(struct input_dev *dev, void *data,
@@ -62,8 +67,8 @@
 	left = left * 0x7f / 0xffff;
 	right = right * 0x7f / 0xffff;
 
-	plff->report->field[0]->value[2] = left;
-	plff->report->field[0]->value[3] = right;
+	*plff->strong = left;
+	*plff->weak = right;
 	debug("running with 0x%02x 0x%02x", left, right);
 	usbhid_submit_report(hid, plff->report, USB_DIR_OUT);
 
@@ -80,6 +85,8 @@
 	struct list_head *report_ptr = report_list;
 	struct input_dev *dev;
 	int error;
+	s32 *strong;
+	s32 *weak;
 
 	/* The device contains one output report per physical device, all
 	   containing 1 field, which contains 4 ff00.0002 usages and 4 16bit
@@ -87,7 +94,12 @@
 
 	   The input reports also contain a field which contains
 	   8 ff00.0001 usages and 8 boolean values. Their meaning is
-	   currently unknown. */
+	   currently unknown.
+	   
+	   A version of the 0e8f:0003 exists that has all the values in
+	   separate fields and misses the extra input field, thus resembling
+	   Zeroplus (hid-zpff) devices.
+	*/
 
 	if (list_empty(report_list)) {
 		dev_err(&hid->dev, "no output reports found\n");
@@ -110,8 +122,21 @@
 			return -ENODEV;
 		}
 
-		if (report->field[0]->report_count < 4) {
-			dev_err(&hid->dev, "not enough values in the field\n");
+		if (report->field[0]->report_count >= 4) {
+			report->field[0]->value[0] = 0x00;
+			report->field[0]->value[1] = 0x00;
+			strong = &report->field[0]->value[2];
+			weak = &report->field[0]->value[3];
+			debug("detected single-field device");
+		} else if (report->maxfield >= 4 && report->field[0]->maxusage == 1 &&
+				report->field[0]->usage[0].hid == (HID_UP_LED | 0x43)) {
+			report->field[0]->value[0] = 0x00;
+			report->field[1]->value[0] = 0x00;
+			strong = &report->field[2]->value[0];
+			weak = &report->field[3]->value[0];
+			debug("detected 4-field device");
+		} else {
+			dev_err(&hid->dev, "not enough fields or values\n");
 			return -ENODEV;
 		}
 
@@ -130,10 +155,11 @@
 		}
 
 		plff->report = report;
-		plff->report->field[0]->value[0] = 0x00;
-		plff->report->field[0]->value[1] = 0x00;
-		plff->report->field[0]->value[2] = 0x00;
-		plff->report->field[0]->value[3] = 0x00;
+		plff->strong = strong;
+		plff->weak = weak;
+
+		*strong = 0x00;
+		*weak = 0x00;
 		usbhid_submit_report(hid, plff->report, USB_DIR_OUT);
 	}
 
@@ -180,7 +206,7 @@
 		.driver_data = 1 }, /* Twin USB Joystick */
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR),
 		.driver_data = 1 }, /* Twin USB Joystick */
-	{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003), }, /* GreenAsia Inc. USB Joystick */
+	{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003), },
 	{ }
 };
 MODULE_DEVICE_TABLE(hid, pl_devices);
@@ -204,5 +230,3 @@
 module_init(pl_init);
 module_exit(pl_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(pantherlord);
diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c
index 15f3c04..07083aa 100644
--- a/drivers/hid/hid-samsung.c
+++ b/drivers/hid/hid-samsung.c
@@ -96,5 +96,3 @@
 module_init(samsung_init);
 module_exit(samsung_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(samsung);
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index dd5a397..c259938 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -148,5 +148,3 @@
 module_init(sony_init);
 module_exit(sony_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(sony);
diff --git a/drivers/hid/hid-sunplus.c b/drivers/hid/hid-sunplus.c
index 5ba68f7..e0a8fd3 100644
--- a/drivers/hid/hid-sunplus.c
+++ b/drivers/hid/hid-sunplus.c
@@ -78,5 +78,3 @@
 module_init(sp_init);
 module_exit(sp_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(sunplus);
diff --git a/drivers/hid/hid-tmff.c b/drivers/hid/hid-tmff.c
index 1b7cba0..7c1f7b5 100644
--- a/drivers/hid/hid-tmff.c
+++ b/drivers/hid/hid-tmff.c
@@ -265,5 +265,3 @@
 module_init(tm_init);
 module_exit(tm_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(thrustmaster);
diff --git a/drivers/hid/hid-topseed.c b/drivers/hid/hid-topseed.c
index cca64a0..152ccfa 100644
--- a/drivers/hid/hid-topseed.c
+++ b/drivers/hid/hid-topseed.c
@@ -73,5 +73,3 @@
 module_init(ts_init);
 module_exit(ts_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(topseed);
diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c
index ea82f37..85a198a 100644
--- a/drivers/hid/hid-zpff.c
+++ b/drivers/hid/hid-zpff.c
@@ -158,5 +158,3 @@
 module_init(zp_init);
 module_exit(zp_exit);
 MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(zeroplus);
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 02b19db..e263d47 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -181,9 +181,17 @@
 
 	dev = hidraw_table[minor];
 	if (!dev->open++) {
+		if (dev->hid->ll_driver->power) {
+			err = dev->hid->ll_driver->power(dev->hid, PM_HINT_FULLON);
+			if (err < 0)
+				goto out_unlock;
+		}
 		err = dev->hid->ll_driver->open(dev->hid);
-		if (err < 0)
+		if (err < 0) {
+			if (dev->hid->ll_driver->power)
+				dev->hid->ll_driver->power(dev->hid, PM_HINT_NORMAL);
 			dev->open--;
+		}
 	}
 
 out_unlock:
@@ -209,10 +217,13 @@
 	list_del(&list->node);
 	dev = hidraw_table[minor];
 	if (!--dev->open) {
-		if (list->hidraw->exist)
+		if (list->hidraw->exist) {
+			if (dev->hid->ll_driver->power)
+				dev->hid->ll_driver->power(dev->hid, PM_HINT_NORMAL);
 			dev->hid->ll_driver->close(dev->hid);
-		else
+		} else {
 			kfree(list->hidraw);
+		}
 	}
 
 	kfree(list);
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index f0a0f72..4306cb1 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -5,6 +5,7 @@
  *  Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
  *  Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
  *  Copyright (c) 2006-2008 Jiri Kosina
+ *  Copyright (c) 2007-2008 Oliver Neukum
  */
 
 /*
@@ -27,6 +28,7 @@
 #include <asm/byteorder.h>
 #include <linux/input.h>
 #include <linux/wait.h>
+#include <linux/workqueue.h>
 
 #include <linux/usb.h>
 
@@ -53,6 +55,10 @@
 module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644);
 MODULE_PARM_DESC(mousepoll, "Polling interval of mice");
 
+static unsigned int ignoreled;
+module_param_named(ignoreled, ignoreled, uint, 0644);
+MODULE_PARM_DESC(ignoreled, "Autosuspend with active leds");
+
 /* Quirks specified at module load time */
 static char *quirks_param[MAX_USBHID_BOOT_QUIRKS] = { [ 0 ... (MAX_USBHID_BOOT_QUIRKS - 1) ] = NULL };
 module_param_array_named(quirks, quirks_param, charp, NULL, 0444);
@@ -63,8 +69,13 @@
 /*
  * Input submission and I/O error handler.
  */
+static DEFINE_MUTEX(hid_open_mut);
+static struct workqueue_struct *resumption_waker;
 
 static void hid_io_error(struct hid_device *hid);
+static int hid_submit_out(struct hid_device *hid);
+static int hid_submit_ctrl(struct hid_device *hid);
+static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid);
 
 /* Start up the input URB */
 static int hid_start_in(struct hid_device *hid)
@@ -73,15 +84,16 @@
 	int rc = 0;
 	struct usbhid_device *usbhid = hid->driver_data;
 
-	spin_lock_irqsave(&usbhid->inlock, flags);
-	if (hid->open > 0 && !test_bit(HID_SUSPENDED, &usbhid->iofl) &&
+	spin_lock_irqsave(&usbhid->lock, flags);
+	if (hid->open > 0 &&
 			!test_bit(HID_DISCONNECTED, &usbhid->iofl) &&
+			!test_bit(HID_REPORTED_IDLE, &usbhid->iofl) &&
 			!test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) {
 		rc = usb_submit_urb(usbhid->urbin, GFP_ATOMIC);
 		if (rc != 0)
 			clear_bit(HID_IN_RUNNING, &usbhid->iofl);
 	}
-	spin_unlock_irqrestore(&usbhid->inlock, flags);
+	spin_unlock_irqrestore(&usbhid->lock, flags);
 	return rc;
 }
 
@@ -145,7 +157,7 @@
 	unsigned long flags;
 	struct usbhid_device *usbhid = hid->driver_data;
 
-	spin_lock_irqsave(&usbhid->inlock, flags);
+	spin_lock_irqsave(&usbhid->lock, flags);
 
 	/* Stop when disconnected */
 	if (test_bit(HID_DISCONNECTED, &usbhid->iofl))
@@ -175,7 +187,51 @@
 	mod_timer(&usbhid->io_retry,
 			jiffies + msecs_to_jiffies(usbhid->retry_delay));
 done:
-	spin_unlock_irqrestore(&usbhid->inlock, flags);
+	spin_unlock_irqrestore(&usbhid->lock, flags);
+}
+
+static void usbhid_mark_busy(struct usbhid_device *usbhid)
+{
+	struct usb_interface *intf = usbhid->intf;
+
+	usb_mark_last_busy(interface_to_usbdev(intf));
+}
+
+static int usbhid_restart_out_queue(struct usbhid_device *usbhid)
+{
+	struct hid_device *hid = usb_get_intfdata(usbhid->intf);
+	int kicked;
+
+	if (!hid)
+		return 0;
+
+	if ((kicked = (usbhid->outhead != usbhid->outtail))) {
+		dbg("Kicking head %d tail %d", usbhid->outhead, usbhid->outtail);
+		if (hid_submit_out(hid)) {
+			clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
+			wake_up(&usbhid->wait);
+		}
+	}
+	return kicked;
+}
+
+static int usbhid_restart_ctrl_queue(struct usbhid_device *usbhid)
+{
+	struct hid_device *hid = usb_get_intfdata(usbhid->intf);
+	int kicked;
+
+	WARN_ON(hid == NULL);
+	if (!hid)
+		return 0;
+
+	if ((kicked = (usbhid->ctrlhead != usbhid->ctrltail))) {
+		dbg("Kicking head %d tail %d", usbhid->ctrlhead, usbhid->ctrltail);
+		if (hid_submit_ctrl(hid)) {
+			clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
+			wake_up(&usbhid->wait);
+		}
+	}
+	return kicked;
 }
 
 /*
@@ -190,12 +246,23 @@
 
 	switch (urb->status) {
 	case 0:			/* success */
+		usbhid_mark_busy(usbhid);
 		usbhid->retry_delay = 0;
 		hid_input_report(urb->context, HID_INPUT_REPORT,
 				 urb->transfer_buffer,
 				 urb->actual_length, 1);
+		/*
+		 * autosuspend refused while keys are pressed
+		 * because most keyboards don't wake up when
+		 * a key is released
+		 */
+		if (hid_check_keys_pressed(hid))
+			set_bit(HID_KEYS_PRESSED, &usbhid->iofl);
+		else
+			clear_bit(HID_KEYS_PRESSED, &usbhid->iofl);
 		break;
 	case -EPIPE:		/* stall */
+		usbhid_mark_busy(usbhid);
 		clear_bit(HID_IN_RUNNING, &usbhid->iofl);
 		set_bit(HID_CLEAR_HALT, &usbhid->iofl);
 		schedule_work(&usbhid->reset_work);
@@ -209,6 +276,7 @@
 	case -EPROTO:		/* protocol error or unplug */
 	case -ETIME:		/* protocol error or unplug */
 	case -ETIMEDOUT:	/* Should never happen, but... */
+		usbhid_mark_busy(usbhid);
 		clear_bit(HID_IN_RUNNING, &usbhid->iofl);
 		hid_io_error(hid);
 		return;
@@ -239,16 +307,25 @@
 	report = usbhid->out[usbhid->outtail].report;
 	raw_report = usbhid->out[usbhid->outtail].raw_report;
 
-	usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
-	usbhid->urbout->dev = hid_to_usb_dev(hid);
-	memcpy(usbhid->outbuf, raw_report, usbhid->urbout->transfer_buffer_length);
-	kfree(raw_report);
+	if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) {
+		usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
+		usbhid->urbout->dev = hid_to_usb_dev(hid);
+		memcpy(usbhid->outbuf, raw_report, usbhid->urbout->transfer_buffer_length);
+		kfree(raw_report);
 
-	dbg_hid("submitting out urb\n");
+		dbg_hid("submitting out urb\n");
 
-	if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) {
-		err_hid("usb_submit_urb(out) failed");
-		return -1;
+		if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) {
+			err_hid("usb_submit_urb(out) failed");
+			return -1;
+		}
+	} else {
+		/*
+		 * queue work to wake up the device.
+		 * as the work queue is freezeable, this is safe
+		 * with respect to STD and STR
+		 */
+		queue_work(resumption_waker, &usbhid->restart_work);
 	}
 
 	return 0;
@@ -266,41 +343,50 @@
 	raw_report = usbhid->ctrl[usbhid->ctrltail].raw_report;
 	dir = usbhid->ctrl[usbhid->ctrltail].dir;
 
-	len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
-	if (dir == USB_DIR_OUT) {
-		usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0);
-		usbhid->urbctrl->transfer_buffer_length = len;
-		memcpy(usbhid->ctrlbuf, raw_report, len);
-		kfree(raw_report);
+	if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) {
+		len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
+		if (dir == USB_DIR_OUT) {
+			usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0);
+			usbhid->urbctrl->transfer_buffer_length = len;
+			memcpy(usbhid->ctrlbuf, raw_report, len);
+			kfree(raw_report);
+		} else {
+			int maxpacket, padlen;
+
+			usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0);
+			maxpacket = usb_maxpacket(hid_to_usb_dev(hid), usbhid->urbctrl->pipe, 0);
+			if (maxpacket > 0) {
+				padlen = DIV_ROUND_UP(len, maxpacket);
+				padlen *= maxpacket;
+				if (padlen > usbhid->bufsize)
+					padlen = usbhid->bufsize;
+			} else
+				padlen = 0;
+			usbhid->urbctrl->transfer_buffer_length = padlen;
+		}
+		usbhid->urbctrl->dev = hid_to_usb_dev(hid);
+
+		usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
+		usbhid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT;
+		usbhid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id);
+		usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum);
+		usbhid->cr->wLength = cpu_to_le16(len);
+
+		dbg_hid("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n",
+			usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report",
+			usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);
+
+		if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) {
+			err_hid("usb_submit_urb(ctrl) failed");
+			return -1;
+		}
 	} else {
-		int maxpacket, padlen;
-
-		usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0);
-		maxpacket = usb_maxpacket(hid_to_usb_dev(hid), usbhid->urbctrl->pipe, 0);
-		if (maxpacket > 0) {
-			padlen = DIV_ROUND_UP(len, maxpacket);
-			padlen *= maxpacket;
-			if (padlen > usbhid->bufsize)
-				padlen = usbhid->bufsize;
-		} else
-			padlen = 0;
-		usbhid->urbctrl->transfer_buffer_length = padlen;
-	}
-	usbhid->urbctrl->dev = hid_to_usb_dev(hid);
-
-	usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
-	usbhid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT;
-	usbhid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id);
-	usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum);
-	usbhid->cr->wLength = cpu_to_le16(len);
-
-	dbg_hid("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n",
-		usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report",
-		usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);
-
-	if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) {
-		err_hid("usb_submit_urb(ctrl) failed");
-		return -1;
+		/*
+		 * queue work to wake up the device.
+		 * as the work queue is freezeable, this is safe
+		 * with respect to STD and STR
+		 */
+		queue_work(resumption_waker, &usbhid->restart_work);
 	}
 
 	return 0;
@@ -332,7 +418,7 @@
 				"received\n", urb->status);
 	}
 
-	spin_lock_irqsave(&usbhid->outlock, flags);
+	spin_lock_irqsave(&usbhid->lock, flags);
 
 	if (unplug)
 		usbhid->outtail = usbhid->outhead;
@@ -344,12 +430,12 @@
 			clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
 			wake_up(&usbhid->wait);
 		}
-		spin_unlock_irqrestore(&usbhid->outlock, flags);
+		spin_unlock_irqrestore(&usbhid->lock, flags);
 		return;
 	}
 
 	clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
-	spin_unlock_irqrestore(&usbhid->outlock, flags);
+	spin_unlock_irqrestore(&usbhid->lock, flags);
 	wake_up(&usbhid->wait);
 }
 
@@ -361,12 +447,11 @@
 {
 	struct hid_device *hid = urb->context;
 	struct usbhid_device *usbhid = hid->driver_data;
-	unsigned long flags;
-	int unplug = 0;
+	int unplug = 0, status = urb->status;
 
-	spin_lock_irqsave(&usbhid->ctrllock, flags);
+	spin_lock(&usbhid->lock);
 
-	switch (urb->status) {
+	switch (status) {
 	case 0:			/* success */
 		if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN)
 			hid_input_report(urb->context,
@@ -383,7 +468,7 @@
 		break;
 	default:		/* error */
 		dev_warn(&urb->dev->dev, "ctrl urb status %d "
-				"received\n", urb->status);
+				"received\n", status);
 	}
 
 	if (unplug)
@@ -396,19 +481,18 @@
 			clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
 			wake_up(&usbhid->wait);
 		}
-		spin_unlock_irqrestore(&usbhid->ctrllock, flags);
+		spin_unlock(&usbhid->lock);
 		return;
 	}
 
 	clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
-	spin_unlock_irqrestore(&usbhid->ctrllock, flags);
+	spin_unlock(&usbhid->lock);
 	wake_up(&usbhid->wait);
 }
 
-void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
+void __usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
 {
 	int head;
-	unsigned long flags;
 	struct usbhid_device *usbhid = hid->driver_data;
 	int len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
 
@@ -416,18 +500,13 @@
 		return;
 
 	if (usbhid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) {
-
-		spin_lock_irqsave(&usbhid->outlock, flags);
-
 		if ((head = (usbhid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == usbhid->outtail) {
-			spin_unlock_irqrestore(&usbhid->outlock, flags);
 			dev_warn(&hid->dev, "output queue full\n");
 			return;
 		}
 
 		usbhid->out[usbhid->outhead].raw_report = kmalloc(len, GFP_ATOMIC);
 		if (!usbhid->out[usbhid->outhead].raw_report) {
-			spin_unlock_irqrestore(&usbhid->outlock, flags);
 			dev_warn(&hid->dev, "output queueing failed\n");
 			return;
 		}
@@ -438,15 +517,10 @@
 		if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl))
 			if (hid_submit_out(hid))
 				clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
-
-		spin_unlock_irqrestore(&usbhid->outlock, flags);
 		return;
 	}
 
-	spin_lock_irqsave(&usbhid->ctrllock, flags);
-
 	if ((head = (usbhid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == usbhid->ctrltail) {
-		spin_unlock_irqrestore(&usbhid->ctrllock, flags);
 		dev_warn(&hid->dev, "control queue full\n");
 		return;
 	}
@@ -454,7 +528,6 @@
 	if (dir == USB_DIR_OUT) {
 		usbhid->ctrl[usbhid->ctrlhead].raw_report = kmalloc(len, GFP_ATOMIC);
 		if (!usbhid->ctrl[usbhid->ctrlhead].raw_report) {
-			spin_unlock_irqrestore(&usbhid->ctrllock, flags);
 			dev_warn(&hid->dev, "control queueing failed\n");
 			return;
 		}
@@ -467,15 +540,25 @@
 	if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl))
 		if (hid_submit_ctrl(hid))
 			clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
+}
 
-	spin_unlock_irqrestore(&usbhid->ctrllock, flags);
+void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
+{
+	struct usbhid_device *usbhid = hid->driver_data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&usbhid->lock, flags);
+	__usbhid_submit_report(hid, report, dir);
+	spin_unlock_irqrestore(&usbhid->lock, flags);
 }
 EXPORT_SYMBOL_GPL(usbhid_submit_report);
 
 static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
 {
 	struct hid_device *hid = input_get_drvdata(dev);
+	struct usbhid_device *usbhid = hid->driver_data;
 	struct hid_field *field;
+	unsigned long flags;
 	int offset;
 
 	if (type == EV_FF)
@@ -490,6 +573,15 @@
 	}
 
 	hid_set_field(field, offset, value);
+	if (value) {
+		spin_lock_irqsave(&usbhid->lock, flags);
+		usbhid->ledcount++;
+		spin_unlock_irqrestore(&usbhid->lock, flags);
+	} else {
+		spin_lock_irqsave(&usbhid->lock, flags);
+		usbhid->ledcount--;
+		spin_unlock_irqrestore(&usbhid->lock, flags);
+	}
 	usbhid_submit_report(hid, field->report, USB_DIR_OUT);
 
 	return 0;
@@ -538,15 +630,22 @@
 	struct usbhid_device *usbhid = hid->driver_data;
 	int res;
 
+	mutex_lock(&hid_open_mut);
 	if (!hid->open++) {
 		res = usb_autopm_get_interface(usbhid->intf);
+		/* the device must be awake to reliable request remote wakeup */
 		if (res < 0) {
 			hid->open--;
+			mutex_unlock(&hid_open_mut);
 			return -EIO;
 		}
+		usbhid->intf->needs_remote_wakeup = 1;
+		if (hid_start_in(hid))
+			hid_io_error(hid);
+ 
+		usb_autopm_put_interface(usbhid->intf);
 	}
-	if (hid_start_in(hid))
-		hid_io_error(hid);
+	mutex_unlock(&hid_open_mut);
 	return 0;
 }
 
@@ -554,10 +653,22 @@
 {
 	struct usbhid_device *usbhid = hid->driver_data;
 
+	mutex_lock(&hid_open_mut);
+
+	/* protecting hid->open to make sure we don't restart
+	 * data acquistion due to a resumption we no longer
+	 * care about
+	 */
+	spin_lock_irq(&usbhid->lock);
 	if (!--hid->open) {
+		spin_unlock_irq(&usbhid->lock);
 		usb_kill_urb(usbhid->urbin);
-		usb_autopm_put_interface(usbhid->intf);
+		flush_scheduled_work();
+		usbhid->intf->needs_remote_wakeup = 0;
+	} else {
+		spin_unlock_irq(&usbhid->lock);
 	}
+	mutex_unlock(&hid_open_mut);
 }
 
 /*
@@ -687,6 +798,25 @@
 	return ret;
 }
 
+static void usbhid_restart_queues(struct usbhid_device *usbhid)
+{
+	if (usbhid->urbout)
+		usbhid_restart_out_queue(usbhid);
+	usbhid_restart_ctrl_queue(usbhid);
+}
+
+static void __usbhid_restart_queues(struct work_struct *work)
+{
+	struct usbhid_device *usbhid =
+		container_of(work, struct usbhid_device, restart_work);
+	int r;
+
+	r = usb_autopm_get_interface(usbhid->intf);
+	if (r < 0)
+		return;
+	usb_autopm_put_interface(usbhid->intf);
+}
+
 static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
 {
 	struct usbhid_device *usbhid = hid->driver_data;
@@ -711,6 +841,9 @@
 	quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor),
 			le16_to_cpu(dev->descriptor.idProduct));
 
+	if (quirks & HID_QUIRK_IGNORE)
+		return -ENODEV;
+
 	/* Many keyboards and mice don't like to be polled for reports,
 	 * so we will always set the HID_QUIRK_NOGET flag for them. */
 	if (interface->desc.bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT) {
@@ -850,11 +983,11 @@
 
 	init_waitqueue_head(&usbhid->wait);
 	INIT_WORK(&usbhid->reset_work, hid_reset);
+	INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues);
 	setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
 
-	spin_lock_init(&usbhid->inlock);
-	spin_lock_init(&usbhid->outlock);
-	spin_lock_init(&usbhid->ctrllock);
+	spin_lock_init(&usbhid->lock);
+	spin_lock_init(&usbhid->lock);
 
 	usbhid->intf = intf;
 	usbhid->ifnum = interface->desc.bInterfaceNumber;
@@ -906,15 +1039,14 @@
 		return;
 
 	clear_bit(HID_STARTED, &usbhid->iofl);
-	spin_lock_irq(&usbhid->inlock);	/* Sync with error handler */
+	spin_lock_irq(&usbhid->lock);	/* Sync with error handler */
 	set_bit(HID_DISCONNECTED, &usbhid->iofl);
-	spin_unlock_irq(&usbhid->inlock);
+	spin_unlock_irq(&usbhid->lock);
 	usb_kill_urb(usbhid->urbin);
 	usb_kill_urb(usbhid->urbout);
 	usb_kill_urb(usbhid->urbctrl);
 
-	del_timer_sync(&usbhid->io_retry);
-	cancel_work_sync(&usbhid->reset_work);
+	hid_cancel_delayed_stuff(usbhid);
 
 	if (hid->claimed & HID_CLAIMED_INPUT)
 		hidinput_disconnect(hid);
@@ -935,12 +1067,28 @@
 	hid_free_buffers(hid_to_usb_dev(hid), hid);
 }
 
+static int usbhid_power(struct hid_device *hid, int lvl)
+{
+	int r = 0;
+
+	switch (lvl) {
+	case PM_HINT_FULLON:
+		r = usbhid_get_power(hid);
+		break;
+	case PM_HINT_NORMAL:
+		usbhid_put_power(hid);
+		break;
+	}
+	return r;
+}
+
 static struct hid_ll_driver usb_hid_driver = {
 	.parse = usbhid_parse,
 	.start = usbhid_start,
 	.stop = usbhid_stop,
 	.open = usbhid_open,
 	.close = usbhid_close,
+	.power = usbhid_power,
 	.hidinput_input_event = usb_hidinput_input_event,
 };
 
@@ -1049,19 +1197,126 @@
 	kfree(usbhid);
 }
 
-static int hid_suspend(struct usb_interface *intf, pm_message_t message)
+static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid)
 {
-	struct hid_device *hid = usb_get_intfdata (intf);
+	del_timer_sync(&usbhid->io_retry);
+	cancel_work_sync(&usbhid->restart_work);
+	cancel_work_sync(&usbhid->reset_work);
+}
+
+static void hid_cease_io(struct usbhid_device *usbhid)
+{
+	del_timer(&usbhid->io_retry);
+	usb_kill_urb(usbhid->urbin);
+	usb_kill_urb(usbhid->urbctrl);
+	usb_kill_urb(usbhid->urbout);
+}
+
+/* Treat USB reset pretty much the same as suspend/resume */
+static int hid_pre_reset(struct usb_interface *intf)
+{
+	struct hid_device *hid = usb_get_intfdata(intf);
 	struct usbhid_device *usbhid = hid->driver_data;
 
-	if (!test_bit(HID_STARTED, &usbhid->iofl))
-		return 0;
+	spin_lock_irq(&usbhid->lock);
+	set_bit(HID_RESET_PENDING, &usbhid->iofl);
+	spin_unlock_irq(&usbhid->lock);
+	cancel_work_sync(&usbhid->restart_work);
+	hid_cease_io(usbhid);
 
-	spin_lock_irq(&usbhid->inlock);	/* Sync with error handler */
-	set_bit(HID_SUSPENDED, &usbhid->iofl);
-	spin_unlock_irq(&usbhid->inlock);
-	del_timer_sync(&usbhid->io_retry);
-	usb_kill_urb(usbhid->urbin);
+	return 0;
+}
+
+/* Same routine used for post_reset and reset_resume */
+static int hid_post_reset(struct usb_interface *intf)
+{
+	struct usb_device *dev = interface_to_usbdev (intf);
+	struct hid_device *hid = usb_get_intfdata(intf);
+	struct usbhid_device *usbhid = hid->driver_data;
+	int status;
+ 
+	spin_lock_irq(&usbhid->lock);
+	clear_bit(HID_RESET_PENDING, &usbhid->iofl);
+	spin_unlock_irq(&usbhid->lock);
+	hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
+	/* FIXME: Any more reinitialization needed? */
+	status = hid_start_in(hid);
+	if (status < 0)
+		hid_io_error(hid);
+	usbhid_restart_queues(usbhid);
+
+	return 0;
+}
+
+int usbhid_get_power(struct hid_device *hid)
+{
+	struct usbhid_device *usbhid = hid->driver_data;
+ 
+	return usb_autopm_get_interface(usbhid->intf);
+}
+
+void usbhid_put_power(struct hid_device *hid)
+{
+	struct usbhid_device *usbhid = hid->driver_data;
+ 
+	usb_autopm_put_interface(usbhid->intf);
+}
+
+
+#ifdef CONFIG_PM
+static int hid_suspend(struct usb_interface *intf, pm_message_t message)
+{
+	struct hid_device *hid = usb_get_intfdata(intf);
+	struct usbhid_device *usbhid = hid->driver_data;
+	struct usb_device *udev = interface_to_usbdev(intf);
+	int status;
+
+	if (udev->auto_pm) {
+		spin_lock_irq(&usbhid->lock);	/* Sync with error handler */
+		if (!test_bit(HID_RESET_PENDING, &usbhid->iofl)
+		    && !test_bit(HID_CLEAR_HALT, &usbhid->iofl)
+		    && !test_bit(HID_OUT_RUNNING, &usbhid->iofl)
+		    && !test_bit(HID_CTRL_RUNNING, &usbhid->iofl)
+		    && !test_bit(HID_KEYS_PRESSED, &usbhid->iofl)
+		    && (!usbhid->ledcount || ignoreled))
+		{
+			set_bit(HID_REPORTED_IDLE, &usbhid->iofl);
+			spin_unlock_irq(&usbhid->lock);
+		} else {
+			usbhid_mark_busy(usbhid);
+			spin_unlock_irq(&usbhid->lock);
+			return -EBUSY;
+		}
+
+	} else {
+		spin_lock_irq(&usbhid->lock);
+		set_bit(HID_REPORTED_IDLE, &usbhid->iofl);
+		spin_unlock_irq(&usbhid->lock);
+		if (usbhid_wait_io(hid) < 0)
+			return -EIO;
+	}
+
+	if (!ignoreled && udev->auto_pm) {
+		spin_lock_irq(&usbhid->lock);
+		if (test_bit(HID_LED_ON, &usbhid->iofl)) {
+			spin_unlock_irq(&usbhid->lock);
+			usbhid_mark_busy(usbhid);
+			return -EBUSY;
+		}
+		spin_unlock_irq(&usbhid->lock);
+	}
+
+	hid_cancel_delayed_stuff(usbhid);
+	hid_cease_io(usbhid);
+
+	if (udev->auto_pm && test_bit(HID_KEYS_PRESSED, &usbhid->iofl)) {
+		/* lost race against keypresses */
+		status = hid_start_in(hid);
+		if (status < 0)
+			hid_io_error(hid);
+		usbhid_mark_busy(usbhid);
+		return -EBUSY;
+	}
 	dev_dbg(&intf->dev, "suspend\n");
 	return 0;
 }
@@ -1075,32 +1330,33 @@
 	if (!test_bit(HID_STARTED, &usbhid->iofl))
 		return 0;
 
-	clear_bit(HID_SUSPENDED, &usbhid->iofl);
+	clear_bit(HID_REPORTED_IDLE, &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;
 	status = hid_start_in(hid);
-	dev_dbg(&intf->dev, "resume status %d\n", status);
-	return status;
-}
+	if (status < 0)
+		hid_io_error(hid);
+	usbhid_restart_queues(usbhid);
 
-/* Treat USB reset pretty much the same as suspend/resume */
-static int hid_pre_reset(struct usb_interface *intf)
-{
-	/* FIXME: What if the interface is already suspended? */
-	hid_suspend(intf, PMSG_ON);
+	dev_dbg(&intf->dev, "resume status %d\n", status);
 	return 0;
 }
 
-/* Same routine used for post_reset and reset_resume */
-static int hid_post_reset(struct usb_interface *intf)
+static int hid_reset_resume(struct usb_interface *intf)
 {
-	struct usb_device *dev = interface_to_usbdev (intf);
+	struct hid_device *hid = usb_get_intfdata(intf);
+	struct usbhid_device *usbhid = hid->driver_data;
 
-	hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
-	/* FIXME: Any more reinitialization needed? */
-
-	return hid_resume(intf);
+	clear_bit(HID_REPORTED_IDLE, &usbhid->iofl);
+	return hid_post_reset(intf);
 }
 
+#endif /* CONFIG_PM */
+
 static struct usb_device_id hid_usb_ids [] = {
 	{ .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
 		.bInterfaceClass = USB_INTERFACE_CLASS_HID },
@@ -1113,9 +1369,11 @@
 	.name =		"usbhid",
 	.probe =	hid_probe,
 	.disconnect =	hid_disconnect,
+#ifdef CONFIG_PM
 	.suspend =	hid_suspend,
 	.resume =	hid_resume,
-	.reset_resume =	hid_post_reset,
+	.reset_resume =	hid_reset_resume,
+#endif
 	.pre_reset =	hid_pre_reset,
 	.post_reset =	hid_post_reset,
 	.id_table =	hid_usb_ids,
@@ -1134,7 +1392,11 @@
 
 static int __init hid_init(void)
 {
-	int retval;
+	int retval = -ENOMEM;
+
+	resumption_waker = create_freezeable_workqueue("usbhid_resumer");
+	if (!resumption_waker)
+		goto no_queue;
 	retval = hid_register_driver(&hid_usb_driver);
 	if (retval)
 		goto hid_register_fail;
@@ -1158,6 +1420,8 @@
 usbhid_quirks_init_fail:
 	hid_unregister_driver(&hid_usb_driver);
 hid_register_fail:
+	destroy_workqueue(resumption_waker);
+no_queue:
 	return retval;
 }
 
@@ -1167,6 +1431,7 @@
 	hiddev_exit();
 	usbhid_quirks_exit();
 	hid_unregister_driver(&hid_usb_driver);
+	destroy_workqueue(resumption_waker);
 }
 
 module_init(hid_init);
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index aa21417..e9b436d 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -246,10 +246,12 @@
 	spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
 
 	if (!--list->hiddev->open) {
-		if (list->hiddev->exist)
+		if (list->hiddev->exist) {
 			usbhid_close(list->hiddev->hid);
-		else
+			usbhid_put_power(list->hiddev->hid);
+		} else {
 			kfree(list->hiddev);
+		}
 	}
 
 	kfree(list);
@@ -300,6 +302,17 @@
 	list_add_tail(&list->node, &hiddev_table[i]->list);
 	spin_unlock_irq(&list->hiddev->list_lock);
 
+	if (!list->hiddev->open++)
+		if (list->hiddev->exist) {
+			struct hid_device *hid = hiddev_table[i]->hid;
+			res = usbhid_get_power(hid);
+			if (res < 0) {
+				res = -EIO;
+				goto bail;
+			}
+			usbhid_open(hid);
+		}
+
 	return 0;
 bail:
 	file->private_data = NULL;
@@ -875,16 +888,21 @@
 	hiddev->hid = hid;
 	hiddev->exist = 1;
 
+	/* when lock_kernel() usage is fixed in usb_open(),
+	 * we could also fix it here */
+	lock_kernel();
 	retval = usb_register_dev(usbhid->intf, &hiddev_class);
 	if (retval) {
 		err_hid("Not able to get a minor for this device.");
 		hid->hiddev = NULL;
+		unlock_kernel();
 		kfree(hiddev);
 		return -1;
 	} else {
 		hid->minor = usbhid->intf->minor;
 		hiddev_table[usbhid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
 	}
+	unlock_kernel();
 
 	return 0;
 }
diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h
index 9eb30564..08f505c 100644
--- a/drivers/hid/usbhid/usbhid.h
+++ b/drivers/hid/usbhid/usbhid.h
@@ -38,7 +38,10 @@
 void usbhid_close(struct hid_device *hid);
 int usbhid_open(struct hid_device *hid);
 void usbhid_init_reports(struct hid_device *hid);
-void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir);
+void usbhid_submit_report
+(struct hid_device *hid, struct hid_report *report, unsigned char dir);
+int usbhid_get_power(struct hid_device *hid);
+void usbhid_put_power(struct hid_device *hid);
 
 /* iofl flags */
 #define HID_CTRL_RUNNING	1
@@ -49,6 +52,9 @@
 #define HID_CLEAR_HALT		6
 #define HID_DISCONNECTED	7
 #define HID_STARTED		8
+#define HID_REPORTED_IDLE	9
+#define HID_KEYS_PRESSED	10
+#define HID_LED_ON		11
 
 /*
  * USB-specific HID struct, to be pointed to
@@ -66,7 +72,6 @@
 	struct urb *urbin;                                              /* Input URB */
 	char *inbuf;                                                    /* Input buffer */
 	dma_addr_t inbuf_dma;                                           /* Input buffer dma */
-	spinlock_t inlock;                                              /* Input fifo spinlock */
 
 	struct urb *urbctrl;                                            /* Control URB */
 	struct usb_ctrlrequest *cr;                                     /* Control request struct */
@@ -75,21 +80,22 @@
 	unsigned char ctrlhead, ctrltail;                               /* Control fifo head & tail */
 	char *ctrlbuf;                                                  /* Control buffer */
 	dma_addr_t ctrlbuf_dma;                                         /* Control buffer dma */
-	spinlock_t ctrllock;                                            /* Control fifo spinlock */
 
 	struct urb *urbout;                                             /* Output URB */
 	struct hid_output_fifo out[HID_CONTROL_FIFO_SIZE];              /* Output pipe fifo */
 	unsigned char outhead, outtail;                                 /* Output pipe fifo head & tail */
 	char *outbuf;                                                   /* Output buffer */
 	dma_addr_t outbuf_dma;                                          /* Output buffer dma */
-	spinlock_t outlock;                                             /* Output fifo spinlock */
 
+	spinlock_t lock;						/* fifo spinlock */
 	unsigned long iofl;                                             /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
 	struct timer_list io_retry;                                     /* Retry timer */
 	unsigned long stop_retry;                                       /* Time to give up, in jiffies */
 	unsigned int retry_delay;                                       /* Delay length in ms */
 	struct work_struct reset_work;                                  /* Task context for resets */
+	struct work_struct restart_work;				/* waking up for output to be done in a task */
 	wait_queue_head_t wait;						/* For sleeping */
+	int ledcount;							/* counting the number of active leds */
 };
 
 #define	hid_to_usb_dev(hid_dev) \
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
index 18a1ba8..e2107e5 100644
--- a/drivers/hwmon/f75375s.c
+++ b/drivers/hwmon/f75375s.c
@@ -1,7 +1,7 @@
 /*
  * f75375s.c - driver for the Fintek F75375/SP and F75373
  *             hardware monitoring features
- * Copyright (C) 2006-2007  Riku Voipio <riku.voipio@movial.fi>
+ * Copyright (C) 2006-2007  Riku Voipio
  *
  * Datasheets available at:
  *
@@ -721,7 +721,7 @@
 	i2c_del_driver(&f75375_driver);
 }
 
-MODULE_AUTHOR("Riku Voipio <riku.voipio@movial.fi>");
+MODULE_AUTHOR("Riku Voipio");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("F75373/F75375 hardware monitoring driver");
 
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index 5f9d860..cd50c00 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -143,7 +143,7 @@
 	---help---
 	  Say Y here if you want suspend key events to trigger a user
 	  requested suspend through APM. This is useful on embedded
-	  systems where such behviour is desired without userspace
+	  systems where such behaviour is desired without userspace
 	  interaction. If unsure, say N.
 
 	  To compile this driver as a module, choose M here: the
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c
index e1480fb..cea70e6 100644
--- a/drivers/input/keyboard/sh_keysc.c
+++ b/drivers/input/keyboard/sh_keysc.c
@@ -259,12 +259,15 @@
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct sh_keysc_priv *priv = platform_get_drvdata(pdev);
+	int irq = platform_get_irq(pdev, 0);
 	unsigned short value;
 
 	value = ioread16(priv->iomem_base + KYCR1_OFFS);
 
-	if (device_may_wakeup(dev))
+	if (device_may_wakeup(dev)) {
 		value |= 0x80;
+		enable_irq_wake(irq);
+	}
 	else
 		value &= ~0x80;
 
@@ -272,8 +275,20 @@
 	return 0;
 }
 
+static int sh_keysc_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	int irq = platform_get_irq(pdev, 0);
+
+	if (device_may_wakeup(dev))
+		disable_irq_wake(irq);
+
+	return 0;
+}
+
 static struct dev_pm_ops sh_keysc_dev_pm_ops = {
 	.suspend = sh_keysc_suspend,
+	.resume = sh_keysc_resume,
 };
 
 struct platform_driver sh_keysc_device_driver = {
diff --git a/drivers/input/mouse/gpio_mouse.c b/drivers/input/mouse/gpio_mouse.c
index 0db8d16..5e5eb88 100644
--- a/drivers/input/mouse/gpio_mouse.c
+++ b/drivers/input/mouse/gpio_mouse.c
@@ -18,7 +18,7 @@
 
 /*
  * Timer function which is run every scan_ms ms when the device is opened.
- * The dev input varaible is set to the the input_dev pointer.
+ * The dev input variable is set to the the input_dev pointer.
  */
 static void gpio_mouse_scan(struct input_polled_dev *dev)
 {
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 7c27c8b..056ac77 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -295,7 +295,7 @@
 static DEVICE_ATTR(name, S_IRUGO, name ## _show, NULL);
 
 
-/* Sysfs conventions report temperatures in millidegrees Celcius.
+/* Sysfs conventions report temperatures in millidegrees Celsius.
  * ADS7846 could use the low-accuracy two-sample scheme, but can't do the high
  * accuracy scheme without calibration data.  For now we won't try either;
  * userspace sees raw sensor values, and must scale/calibrate appropriately.
diff --git a/drivers/input/touchscreen/migor_ts.c b/drivers/input/touchscreen/migor_ts.c
index 504ca11..141dd58 100644
--- a/drivers/input/touchscreen/migor_ts.c
+++ b/drivers/input/touchscreen/migor_ts.c
@@ -198,6 +198,7 @@
 		goto err2;
 	}
 
+	device_init_wakeup(&client->dev, 1);
 	return 0;
 
  err2:
@@ -224,6 +225,26 @@
 	return 0;
 }
 
+static int migor_ts_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+	struct migor_ts_priv *priv = dev_get_drvdata(&client->dev);
+
+	if (device_may_wakeup(&client->dev))
+		enable_irq_wake(priv->irq);
+
+	return 0;
+}
+
+static int migor_ts_resume(struct i2c_client *client)
+{
+	struct migor_ts_priv *priv = dev_get_drvdata(&client->dev);
+
+	if (device_may_wakeup(&client->dev))
+		disable_irq_wake(priv->irq);
+
+	return 0;
+}
+
 static const struct i2c_device_id migor_ts_id[] = {
 	{ "migor_ts", 0 },
 	{ }
@@ -236,6 +257,8 @@
 	},
 	.probe = migor_ts_probe,
 	.remove = migor_ts_remove,
+	.suspend = migor_ts_suspend,
+	.resume = migor_ts_resume,
 	.id_table = migor_ts_id,
 };
 
diff --git a/drivers/isdn/mISDN/Kconfig b/drivers/isdn/mISDN/Kconfig
index 4938355..1747a02 100644
--- a/drivers/isdn/mISDN/Kconfig
+++ b/drivers/isdn/mISDN/Kconfig
@@ -14,13 +14,15 @@
 	depends on MISDN
 	help
 	  Enable support for digital audio processing capability.
+
 	  This module may be used for special applications that require
-	  cross connecting of bchannels, conferencing, dtmf decoding
+	  cross connecting of bchannels, conferencing, dtmf decoding,
 	  echo cancelation, tone generation, and Blowfish encryption and
-	  decryption.
-	  It may use hardware features if available.
+	  decryption. It may use hardware features if available.
+
 	  E.g. it is required for PBX4Linux. Go to http://isdn.eversberg.eu
-	  and get more informations about this module and it's usage.
+	  and get more information about this module and its usage.
+
 	  If unsure, say 'N'.
 
 config MISDN_L1OIP
diff --git a/drivers/isdn/mISDN/l1oip_codec.c b/drivers/isdn/mISDN/l1oip_codec.c
index 2ec4b28..e4ecba3 100644
--- a/drivers/isdn/mISDN/l1oip_codec.c
+++ b/drivers/isdn/mISDN/l1oip_codec.c
@@ -331,7 +331,7 @@
 	/* alloc conversion tables */
 	table_com = vmalloc(65536);
 	table_dec = vmalloc(512);
-	if (!table_com | !table_dec) {
+	if (!table_com || !table_dec) {
 		l1oip_4bit_free();
 		return -ENOMEM;
 	}
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 556aeca..9b60b6b 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -31,6 +31,13 @@
 	  This option enables support for the LEDs on Sharp Locomo.
 	  Zaurus models SL-5500 and SL-5600.
 
+config LEDS_MIKROTIK_RB532
+	tristate "LED Support for Mikrotik Routerboard 532"
+	depends on LEDS_CLASS && MIKROTIK_RB532
+	help
+	  This option enables support for the so called "User LED" of
+	  Mikrotik's Routerboard 532.
+
 config LEDS_S3C24XX
 	tristate "LED Support for Samsung S3C24XX GPIO LEDs"
 	depends on LEDS_CLASS && ARCH_S3C2410
@@ -100,7 +107,7 @@
 	tristate "LED Support for the HP Jornada 6xx"
 	depends on LEDS_CLASS && SH_HP6XX
 	help
-	  This option enables led support for the handheld
+	  This option enables LED support for the handheld
 	  HP Jornada 620/660/680/690.
 
 config LEDS_PCA9532
@@ -108,7 +115,7 @@
 	depends on LEDS_CLASS && I2C && INPUT && EXPERIMENTAL
 	help
 	  This option enables support for NXP pca9532
-	  led controller. It is generally only usefull
+	  LED controller. It is generally only useful
 	  as a platform driver
 
 config LEDS_GPIO
@@ -117,11 +124,40 @@
 	help
 	  This option enables support for the LEDs connected to GPIO
 	  outputs. To be useful the particular board must have LEDs
-	  and they must be connected to the GPIO lines.
+	  and they must be connected to the GPIO lines.  The LEDs must be
+	  defined as platform devices and/or OpenFirmware platform devices.
+	  The code to use these bindings can be selected below.
+
+config LEDS_GPIO_PLATFORM
+	bool "Platform device bindings for GPIO LEDs"
+	depends on LEDS_GPIO
+	default y
+	help
+	  Let the leds-gpio driver drive LEDs which have been defined as
+	  platform devices.  If you don't know what this means, say yes.
+
+config LEDS_GPIO_OF
+	bool "OpenFirmware platform device bindings for GPIO LEDs"
+	depends on LEDS_GPIO && OF_DEVICE
+	default y
+	help
+	  Let the leds-gpio driver drive LEDs which have been defined as
+	  of_platform devices.  For instance, LEDs which are listed in a "dts"
+	  file.
+
+config LEDS_LP5521
+	tristate "LED Support for the LP5521 LEDs"
+	depends on LEDS_CLASS && I2C
+	help
+	  If you say 'Y' here you get support for the National Semiconductor
+	  LP5521 LED driver used in n8x0 boards.
+
+	  This driver can be built as a module by choosing 'M'. The module
+	  will be called leds-lp5521.
 
 config LEDS_CLEVO_MAIL
-	tristate "Mail LED on Clevo notebook (EXPERIMENTAL)"
-	depends on LEDS_CLASS && X86 && SERIO_I8042 && DMI && EXPERIMENTAL
+	tristate "Mail LED on Clevo notebook"
+	depends on LEDS_CLASS && X86 && SERIO_I8042 && DMI
 	help
 	  This driver makes the mail LED accessible from userspace
 	  programs through the leds subsystem. This LED have three
@@ -144,7 +180,7 @@
 	  	Positivo Mobile (Clevo M5x0V)
 
 	  If your model is not listed here you can try the "nodetect"
-	  module paramter.
+	  module parameter.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called leds-clevo-mail.
@@ -171,6 +207,26 @@
 	  This option enables support for on-chip LED drivers found
 	  on Dialog Semiconductor DA9030/DA9034 PMICs.
 
+config LEDS_DAC124S085
+	tristate "LED Support for DAC124S085 SPI DAC"
+	depends on LEDS_CLASS && SPI
+	help
+	  This option enables support for DAC124S085 SPI DAC from NatSemi,
+	  which can be used to control up to four LEDs.
+
+config LEDS_PWM
+	tristate "PWM driven LED Support"
+	depends on LEDS_CLASS && HAVE_PWM
+	help
+	  This option enables support for pwm driven LEDs
+
+config LEDS_BD2802
+	tristate "LED driver for BD2802 RGB LED"
+	depends on LEDS_CLASS && I2C
+	help
+	  This option enables support for BD2802GU RGB LED driver chips
+	  accessed via the I2C bus.
+
 comment "LED Triggers"
 
 config LEDS_TRIGGERS
@@ -216,6 +272,19 @@
 
 	  If unsure, say N.
 
+config LEDS_TRIGGER_GPIO
+	tristate "LED GPIO Trigger"
+	depends on LEDS_TRIGGERS
+	depends on GPIOLIB
+	help
+	  This allows LEDs to be controlled by gpio events. It's good
+	  when using gpios as switches and triggering the needed LEDs
+	  from there. One use case is n810's keypad LEDs that could
+	  be triggered by this trigger when user slides up to show
+	  keypad.
+
+	  If unsure, say N.
+
 config LEDS_TRIGGER_DEFAULT_ON
 	tristate "LED Default ON Trigger"
 	depends on LEDS_TRIGGERS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 9d76f0f..2d41c4d 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -6,7 +6,9 @@
 
 # LED Platform Drivers
 obj-$(CONFIG_LEDS_ATMEL_PWM)		+= leds-atmel-pwm.o
+obj-$(CONFIG_LEDS_BD2802)		+= leds-bd2802.o
 obj-$(CONFIG_LEDS_LOCOMO)		+= leds-locomo.o
+obj-$(CONFIG_LEDS_MIKROTIK_RB532)	+= leds-rb532.o
 obj-$(CONFIG_LEDS_S3C24XX)		+= leds-s3c24xx.o
 obj-$(CONFIG_LEDS_AMS_DELTA)		+= leds-ams-delta.o
 obj-$(CONFIG_LEDS_NET48XX)		+= leds-net48xx.o
@@ -24,10 +26,15 @@
 obj-$(CONFIG_LEDS_PCA955X)		+= leds-pca955x.o
 obj-$(CONFIG_LEDS_DA903X)		+= leds-da903x.o
 obj-$(CONFIG_LEDS_WM8350)		+= leds-wm8350.o
+obj-$(CONFIG_LEDS_PWM)			+= leds-pwm.o
+
+# LED SPI Drivers
+obj-$(CONFIG_LEDS_DAC124S085)		+= leds-dac124s085.o
 
 # LED Triggers
 obj-$(CONFIG_LEDS_TRIGGER_TIMER)	+= ledtrig-timer.o
 obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK)	+= ledtrig-ide-disk.o
 obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT)	+= ledtrig-heartbeat.o
 obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT)	+= ledtrig-backlight.o
+obj-$(CONFIG_LEDS_TRIGGER_GPIO)		+= ledtrig-gpio.o
 obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON)	+= ledtrig-default-on.o
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index 52f82e3..f2cc13d 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -64,7 +64,16 @@
 	return ret;
 }
 
+static ssize_t led_max_brightness_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct led_classdev *led_cdev = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%u\n", led_cdev->max_brightness);
+}
+
 static DEVICE_ATTR(brightness, 0644, led_brightness_show, led_brightness_store);
+static DEVICE_ATTR(max_brightness, 0444, led_max_brightness_show, NULL);
 #ifdef CONFIG_LEDS_TRIGGERS
 static DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store);
 #endif
@@ -138,6 +147,13 @@
 	list_add_tail(&led_cdev->node, &leds_list);
 	up_write(&leds_list_lock);
 
+	if (!led_cdev->max_brightness)
+		led_cdev->max_brightness = LED_FULL;
+
+	rc = device_create_file(led_cdev->dev, &dev_attr_max_brightness);
+	if (rc)
+		goto err_out_attr_max;
+
 	led_update_brightness(led_cdev);
 
 #ifdef CONFIG_LEDS_TRIGGERS
@@ -155,9 +171,11 @@
 
 #ifdef CONFIG_LEDS_TRIGGERS
 err_out_led_list:
+	device_remove_file(led_cdev->dev, &dev_attr_max_brightness);
+#endif
+err_out_attr_max:
 	device_remove_file(led_cdev->dev, &dev_attr_brightness);
 	list_del(&led_cdev->node);
-#endif
 err_out:
 	device_unregister(led_cdev->dev);
 	return rc;
@@ -172,6 +190,7 @@
  */
 void led_classdev_unregister(struct led_classdev *led_cdev)
 {
+	device_remove_file(led_cdev->dev, &dev_attr_max_brightness);
 	device_remove_file(led_cdev->dev, &dev_attr_brightness);
 #ifdef CONFIG_LEDS_TRIGGERS
 	device_remove_file(led_cdev->dev, &dev_attr_trigger);
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index f910eaf..d8ddd9e 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -156,12 +156,20 @@
 int led_trigger_register(struct led_trigger *trigger)
 {
 	struct led_classdev *led_cdev;
+	struct led_trigger *trig;
 
 	rwlock_init(&trigger->leddev_list_lock);
 	INIT_LIST_HEAD(&trigger->led_cdevs);
 
-	/* Add to the list of led triggers */
 	down_write(&triggers_list_lock);
+	/* Make sure the trigger's name isn't already in use */
+	list_for_each_entry(trig, &trigger_list, next_trig) {
+		if (!strcmp(trig->name, trigger->name)) {
+			up_write(&triggers_list_lock);
+			return -EEXIST;
+		}
+	}
+	/* Add to the list of led triggers */
 	list_add_tail(&trigger->next_trig, &trigger_list);
 	up_write(&triggers_list_lock);
 
diff --git a/drivers/leds/leds-bd2802.c b/drivers/leds/leds-bd2802.c
new file mode 100644
index 0000000..4149ecb
--- /dev/null
+++ b/drivers/leds/leds-bd2802.c
@@ -0,0 +1,765 @@
+/*
+ * leds-bd2802.c - RGB LED Driver
+ *
+ * Copyright (C) 2009 Samsung Electronics
+ * Kim Kyuwon <q1.kim@samsung.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.
+ *
+ * Datasheet: http://www.rohm.com/products/databook/driver/pdf/bd2802gu-e.pdf
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/leds.h>
+#include <linux/leds-bd2802.h>
+
+
+#define LED_CTL(rgb2en, rgb1en) ((rgb2en) << 4 | ((rgb1en) << 0))
+
+#define BD2802_LED_OFFSET		0xa
+#define BD2802_COLOR_OFFSET		0x3
+
+#define BD2802_REG_CLKSETUP 		0x00
+#define BD2802_REG_CONTROL 		0x01
+#define BD2802_REG_HOURSETUP		0x02
+#define BD2802_REG_CURRENT1SETUP	0x03
+#define BD2802_REG_CURRENT2SETUP	0x04
+#define BD2802_REG_WAVEPATTERN		0x05
+
+#define BD2802_CURRENT_032		0x10 /* 3.2mA */
+#define BD2802_CURRENT_000		0x00 /* 0.0mA */
+
+#define BD2802_PATTERN_FULL		0x07
+#define BD2802_PATTERN_HALF		0x03
+
+enum led_ids {
+	LED1,
+	LED2,
+	LED_NUM,
+};
+
+enum led_colors {
+	RED,
+	GREEN,
+	BLUE,
+};
+
+enum led_bits {
+	BD2802_OFF,
+	BD2802_BLINK,
+	BD2802_ON,
+};
+
+/*
+ * State '0' : 'off'
+ * State '1' : 'blink'
+ * State '2' : 'on'.
+ */
+struct led_state {
+	unsigned r:2;
+	unsigned g:2;
+	unsigned b:2;
+};
+
+struct bd2802_led {
+	struct bd2802_led_platform_data	*pdata;
+	struct i2c_client		*client;
+	struct rw_semaphore		rwsem;
+	struct work_struct		work;
+
+	struct led_state		led[2];
+
+	/*
+	 * Making led_classdev as array is not recommended, because array
+	 * members prevent using 'container_of' macro. So repetitive works
+	 * are needed.
+	 */
+	struct led_classdev		cdev_led1r;
+	struct led_classdev		cdev_led1g;
+	struct led_classdev		cdev_led1b;
+	struct led_classdev		cdev_led2r;
+	struct led_classdev		cdev_led2g;
+	struct led_classdev		cdev_led2b;
+
+	/*
+	 * Advanced Configuration Function(ADF) mode:
+	 * In ADF mode, user can set registers of BD2802GU directly,
+	 * therefore BD2802GU doesn't enter reset state.
+	 */
+	int 				adf_on;
+
+	enum led_ids			led_id;
+	enum led_colors			color;
+	enum led_bits			state;
+};
+
+
+/*--------------------------------------------------------------*/
+/*	BD2802GU helper functions					*/
+/*--------------------------------------------------------------*/
+
+static inline int bd2802_is_rgb_off(struct bd2802_led *led, enum led_ids id,
+							enum led_colors color)
+{
+	switch (color) {
+	case RED:
+		return !led->led[id].r;
+	case GREEN:
+		return !led->led[id].g;
+	case BLUE:
+		return !led->led[id].b;
+	default:
+		dev_err(&led->client->dev, "%s: Invalid color\n", __func__);
+		return -EINVAL;
+	}
+}
+
+static inline int bd2802_is_led_off(struct bd2802_led *led, enum led_ids id)
+{
+	if (led->led[id].r || led->led[id].g || led->led[id].b)
+		return 0;
+
+	return 1;
+}
+
+static inline int bd2802_is_all_off(struct bd2802_led *led)
+{
+	int i;
+
+	for (i = 0; i < LED_NUM; i++)
+		if (!bd2802_is_led_off(led, i))
+			return 0;
+
+	return 1;
+}
+
+static inline u8 bd2802_get_base_offset(enum led_ids id, enum led_colors color)
+{
+	return id * BD2802_LED_OFFSET + color * BD2802_COLOR_OFFSET;
+}
+
+static inline u8 bd2802_get_reg_addr(enum led_ids id, enum led_colors color,
+								u8 reg_offset)
+{
+	return reg_offset + bd2802_get_base_offset(id, color);
+}
+
+
+/*--------------------------------------------------------------*/
+/*	BD2802GU core functions					*/
+/*--------------------------------------------------------------*/
+
+static int bd2802_write_byte(struct i2c_client *client, u8 reg, u8 val)
+{
+	int ret = i2c_smbus_write_byte_data(client, reg, val);
+	if (ret >= 0)
+		return 0;
+
+	dev_err(&client->dev, "%s: reg 0x%x, val 0x%x, err %d\n",
+						__func__, reg, val, ret);
+
+	return ret;
+}
+
+static void bd2802_update_state(struct bd2802_led *led, enum led_ids id,
+				enum led_colors color, enum led_bits led_bit)
+{
+	int i;
+	u8 value;
+
+	for (i = 0; i < LED_NUM; i++) {
+		if (i == id) {
+			switch (color) {
+			case RED:
+				led->led[i].r = led_bit;
+				break;
+			case GREEN:
+				led->led[i].g = led_bit;
+				break;
+			case BLUE:
+				led->led[i].b = led_bit;
+				break;
+			default:
+				dev_err(&led->client->dev,
+					"%s: Invalid color\n", __func__);
+				return;
+			}
+		}
+	}
+
+	if (led_bit == BD2802_BLINK || led_bit == BD2802_ON)
+		return;
+
+	if (!bd2802_is_led_off(led, id))
+		return;
+
+	if (bd2802_is_all_off(led) && !led->adf_on) {
+		gpio_set_value(led->pdata->reset_gpio, 0);
+		return;
+	}
+
+	/*
+	 * In this case, other led is turned on, and current led is turned
+	 * off. So set RGB LED Control register to stop the current RGB LED
+	 */
+	value = (id == LED1) ? LED_CTL(1, 0) : LED_CTL(0, 1);
+	bd2802_write_byte(led->client, BD2802_REG_CONTROL, value);
+}
+
+static void bd2802_configure(struct bd2802_led *led)
+{
+	struct bd2802_led_platform_data *pdata = led->pdata;
+	u8 reg;
+
+	reg = bd2802_get_reg_addr(LED1, RED, BD2802_REG_HOURSETUP);
+	bd2802_write_byte(led->client, reg, pdata->rgb_time);
+
+	reg = bd2802_get_reg_addr(LED2, RED, BD2802_REG_HOURSETUP);
+	bd2802_write_byte(led->client, reg, pdata->rgb_time);
+}
+
+static void bd2802_reset_cancel(struct bd2802_led *led)
+{
+	gpio_set_value(led->pdata->reset_gpio, 1);
+	udelay(100);
+	bd2802_configure(led);
+}
+
+static void bd2802_enable(struct bd2802_led *led, enum led_ids id)
+{
+	enum led_ids other_led = (id == LED1) ? LED2 : LED1;
+	u8 value, other_led_on;
+
+	other_led_on = !bd2802_is_led_off(led, other_led);
+	if (id == LED1)
+		value = LED_CTL(other_led_on, 1);
+	else
+		value = LED_CTL(1 , other_led_on);
+
+	bd2802_write_byte(led->client, BD2802_REG_CONTROL, value);
+}
+
+static void bd2802_set_on(struct bd2802_led *led, enum led_ids id,
+							enum led_colors color)
+{
+	u8 reg;
+
+	if (bd2802_is_all_off(led) && !led->adf_on)
+		bd2802_reset_cancel(led);
+
+	reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP);
+	bd2802_write_byte(led->client, reg, BD2802_CURRENT_032);
+	reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP);
+	bd2802_write_byte(led->client, reg, BD2802_CURRENT_000);
+	reg = bd2802_get_reg_addr(id, color, BD2802_REG_WAVEPATTERN);
+	bd2802_write_byte(led->client, reg, BD2802_PATTERN_FULL);
+
+	bd2802_enable(led, id);
+	bd2802_update_state(led, id, color, BD2802_ON);
+}
+
+static void bd2802_set_blink(struct bd2802_led *led, enum led_ids id,
+							enum led_colors color)
+{
+	u8 reg;
+
+	if (bd2802_is_all_off(led) && !led->adf_on)
+		bd2802_reset_cancel(led);
+
+	reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP);
+	bd2802_write_byte(led->client, reg, BD2802_CURRENT_000);
+	reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP);
+	bd2802_write_byte(led->client, reg, BD2802_CURRENT_032);
+	reg = bd2802_get_reg_addr(id, color, BD2802_REG_WAVEPATTERN);
+	bd2802_write_byte(led->client, reg, BD2802_PATTERN_HALF);
+
+	bd2802_enable(led, id);
+	bd2802_update_state(led, id, color, BD2802_BLINK);
+}
+
+static void bd2802_turn_on(struct bd2802_led *led, enum led_ids id,
+				enum led_colors color, enum led_bits led_bit)
+{
+	if (led_bit == BD2802_OFF) {
+		dev_err(&led->client->dev,
+					"Only 'blink' and 'on' are allowed\n");
+		return;
+	}
+
+	if (led_bit == BD2802_BLINK)
+		bd2802_set_blink(led, id, color);
+	else
+		bd2802_set_on(led, id, color);
+}
+
+static void bd2802_turn_off(struct bd2802_led *led, enum led_ids id,
+							enum led_colors color)
+{
+	u8 reg;
+
+	if (bd2802_is_rgb_off(led, id, color))
+		return;
+
+	reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP);
+	bd2802_write_byte(led->client, reg, BD2802_CURRENT_000);
+	reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP);
+	bd2802_write_byte(led->client, reg, BD2802_CURRENT_000);
+
+	bd2802_update_state(led, id, color, BD2802_OFF);
+}
+
+static void bd2802_restore_state(struct bd2802_led *led)
+{
+	int i;
+
+	for (i = 0; i < LED_NUM; i++) {
+		if (led->led[i].r)
+			bd2802_turn_on(led, i, RED, led->led[i].r);
+		if (led->led[i].g)
+			bd2802_turn_on(led, i, GREEN, led->led[i].g);
+		if (led->led[i].b)
+			bd2802_turn_on(led, i, BLUE, led->led[i].b);
+	}
+}
+
+#define BD2802_SET_REGISTER(reg_addr, reg_name)				\
+static ssize_t bd2802_store_reg##reg_addr(struct device *dev,		\
+	struct device_attribute *attr, const char *buf, size_t count)	\
+{									\
+	struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));\
+	unsigned long val;						\
+	int ret;							\
+	if (!count)							\
+		return -EINVAL;						\
+	ret = strict_strtoul(buf, 16, &val);				\
+	if (ret)							\
+		return ret;						\
+	down_write(&led->rwsem);					\
+	bd2802_write_byte(led->client, reg_addr, (u8) val);		\
+	up_write(&led->rwsem);						\
+	return count;							\
+}									\
+static struct device_attribute bd2802_reg##reg_addr##_attr = {		\
+	.attr = {.name = reg_name, .mode = 0644, .owner = THIS_MODULE},	\
+	.store = bd2802_store_reg##reg_addr,				\
+};
+
+BD2802_SET_REGISTER(0x00, "0x00");
+BD2802_SET_REGISTER(0x01, "0x01");
+BD2802_SET_REGISTER(0x02, "0x02");
+BD2802_SET_REGISTER(0x03, "0x03");
+BD2802_SET_REGISTER(0x04, "0x04");
+BD2802_SET_REGISTER(0x05, "0x05");
+BD2802_SET_REGISTER(0x06, "0x06");
+BD2802_SET_REGISTER(0x07, "0x07");
+BD2802_SET_REGISTER(0x08, "0x08");
+BD2802_SET_REGISTER(0x09, "0x09");
+BD2802_SET_REGISTER(0x0a, "0x0a");
+BD2802_SET_REGISTER(0x0b, "0x0b");
+BD2802_SET_REGISTER(0x0c, "0x0c");
+BD2802_SET_REGISTER(0x0d, "0x0d");
+BD2802_SET_REGISTER(0x0e, "0x0e");
+BD2802_SET_REGISTER(0x0f, "0x0f");
+BD2802_SET_REGISTER(0x10, "0x10");
+BD2802_SET_REGISTER(0x11, "0x11");
+BD2802_SET_REGISTER(0x12, "0x12");
+BD2802_SET_REGISTER(0x13, "0x13");
+BD2802_SET_REGISTER(0x14, "0x14");
+BD2802_SET_REGISTER(0x15, "0x15");
+
+static struct device_attribute *bd2802_addr_attributes[] = {
+	&bd2802_reg0x00_attr,
+	&bd2802_reg0x01_attr,
+	&bd2802_reg0x02_attr,
+	&bd2802_reg0x03_attr,
+	&bd2802_reg0x04_attr,
+	&bd2802_reg0x05_attr,
+	&bd2802_reg0x06_attr,
+	&bd2802_reg0x07_attr,
+	&bd2802_reg0x08_attr,
+	&bd2802_reg0x09_attr,
+	&bd2802_reg0x0a_attr,
+	&bd2802_reg0x0b_attr,
+	&bd2802_reg0x0c_attr,
+	&bd2802_reg0x0d_attr,
+	&bd2802_reg0x0e_attr,
+	&bd2802_reg0x0f_attr,
+	&bd2802_reg0x10_attr,
+	&bd2802_reg0x11_attr,
+	&bd2802_reg0x12_attr,
+	&bd2802_reg0x13_attr,
+	&bd2802_reg0x14_attr,
+	&bd2802_reg0x15_attr,
+};
+
+static void bd2802_enable_adv_conf(struct bd2802_led *led)
+{
+	int i, ret;
+
+	for (i = 0; i < ARRAY_SIZE(bd2802_addr_attributes); i++) {
+		ret = device_create_file(&led->client->dev,
+						bd2802_addr_attributes[i]);
+		if (ret) {
+			dev_err(&led->client->dev, "failed to sysfs file %s\n",
+					bd2802_addr_attributes[i]->attr.name);
+			goto failed_remove_files;
+		}
+	}
+
+	if (bd2802_is_all_off(led))
+		bd2802_reset_cancel(led);
+
+	led->adf_on = 1;
+
+	return;
+
+failed_remove_files:
+	for (i--; i >= 0; i--)
+		device_remove_file(&led->client->dev,
+						bd2802_addr_attributes[i]);
+}
+
+static void bd2802_disable_adv_conf(struct bd2802_led *led)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(bd2802_addr_attributes); i++)
+		device_remove_file(&led->client->dev,
+						bd2802_addr_attributes[i]);
+
+	if (bd2802_is_all_off(led))
+		gpio_set_value(led->pdata->reset_gpio, 0);
+
+	led->adf_on = 0;
+}
+
+static ssize_t bd2802_show_adv_conf(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));
+	ssize_t ret;
+
+	down_read(&led->rwsem);
+	if (led->adf_on)
+		ret = sprintf(buf, "on\n");
+	else
+		ret = sprintf(buf, "off\n");
+	up_read(&led->rwsem);
+
+	return ret;
+}
+
+static ssize_t bd2802_store_adv_conf(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));
+
+	if (!count)
+		return -EINVAL;
+
+	down_write(&led->rwsem);
+	if (!led->adf_on && !strncmp(buf, "on", 2))
+		bd2802_enable_adv_conf(led);
+	else if (led->adf_on && !strncmp(buf, "off", 3))
+		bd2802_disable_adv_conf(led);
+	up_write(&led->rwsem);
+
+	return count;
+}
+
+static struct device_attribute bd2802_adv_conf_attr = {
+	.attr = {
+		.name = "advanced_configuration",
+		.mode = 0644,
+		.owner = THIS_MODULE
+	},
+	.show = bd2802_show_adv_conf,
+	.store = bd2802_store_adv_conf,
+};
+
+static void bd2802_led_work(struct work_struct *work)
+{
+	struct bd2802_led *led = container_of(work, struct bd2802_led, work);
+
+	if (led->state)
+		bd2802_turn_on(led, led->led_id, led->color, led->state);
+	else
+		bd2802_turn_off(led, led->led_id, led->color);
+}
+
+#define BD2802_CONTROL_RGBS(name, id, clr)				\
+static void bd2802_set_##name##_brightness(struct led_classdev *led_cdev,\
+					enum led_brightness value)	\
+{									\
+	struct bd2802_led *led =					\
+		container_of(led_cdev, struct bd2802_led, cdev_##name);	\
+	led->led_id = id;						\
+	led->color = clr;						\
+	if (value == LED_OFF)						\
+		led->state = BD2802_OFF;				\
+	else								\
+		led->state = BD2802_ON;					\
+	schedule_work(&led->work);					\
+}									\
+static int bd2802_set_##name##_blink(struct led_classdev *led_cdev,	\
+		unsigned long *delay_on, unsigned long *delay_off)	\
+{									\
+	struct bd2802_led *led =					\
+		container_of(led_cdev, struct bd2802_led, cdev_##name);	\
+	if (*delay_on == 0 || *delay_off == 0)				\
+		return -EINVAL;						\
+	led->led_id = id;						\
+	led->color = clr;						\
+	led->state = BD2802_BLINK;					\
+	schedule_work(&led->work);					\
+	return 0;							\
+}
+
+BD2802_CONTROL_RGBS(led1r, LED1, RED);
+BD2802_CONTROL_RGBS(led1g, LED1, GREEN);
+BD2802_CONTROL_RGBS(led1b, LED1, BLUE);
+BD2802_CONTROL_RGBS(led2r, LED2, RED);
+BD2802_CONTROL_RGBS(led2g, LED2, GREEN);
+BD2802_CONTROL_RGBS(led2b, LED2, BLUE);
+
+static int bd2802_register_led_classdev(struct bd2802_led *led)
+{
+	int ret;
+
+	INIT_WORK(&led->work, bd2802_led_work);
+
+	led->cdev_led1r.name = "led1_R";
+	led->cdev_led1r.brightness = LED_OFF;
+	led->cdev_led1r.brightness_set = bd2802_set_led1r_brightness;
+	led->cdev_led1r.blink_set = bd2802_set_led1r_blink;
+	led->cdev_led1r.flags |= LED_CORE_SUSPENDRESUME;
+
+	ret = led_classdev_register(&led->client->dev, &led->cdev_led1r);
+	if (ret < 0) {
+		dev_err(&led->client->dev, "couldn't register LED %s\n",
+							led->cdev_led1r.name);
+		goto failed_unregister_led1_R;
+	}
+
+	led->cdev_led1g.name = "led1_G";
+	led->cdev_led1g.brightness = LED_OFF;
+	led->cdev_led1g.brightness_set = bd2802_set_led1g_brightness;
+	led->cdev_led1g.blink_set = bd2802_set_led1g_blink;
+	led->cdev_led1g.flags |= LED_CORE_SUSPENDRESUME;
+
+	ret = led_classdev_register(&led->client->dev, &led->cdev_led1g);
+	if (ret < 0) {
+		dev_err(&led->client->dev, "couldn't register LED %s\n",
+							led->cdev_led1g.name);
+		goto failed_unregister_led1_G;
+	}
+
+	led->cdev_led1b.name = "led1_B";
+	led->cdev_led1b.brightness = LED_OFF;
+	led->cdev_led1b.brightness_set = bd2802_set_led1b_brightness;
+	led->cdev_led1b.blink_set = bd2802_set_led1b_blink;
+	led->cdev_led1b.flags |= LED_CORE_SUSPENDRESUME;
+
+	ret = led_classdev_register(&led->client->dev, &led->cdev_led1b);
+	if (ret < 0) {
+		dev_err(&led->client->dev, "couldn't register LED %s\n",
+							led->cdev_led1b.name);
+		goto failed_unregister_led1_B;
+	}
+
+	led->cdev_led2r.name = "led2_R";
+	led->cdev_led2r.brightness = LED_OFF;
+	led->cdev_led2r.brightness_set = bd2802_set_led2r_brightness;
+	led->cdev_led2r.blink_set = bd2802_set_led2r_blink;
+	led->cdev_led2r.flags |= LED_CORE_SUSPENDRESUME;
+
+	ret = led_classdev_register(&led->client->dev, &led->cdev_led2r);
+	if (ret < 0) {
+		dev_err(&led->client->dev, "couldn't register LED %s\n",
+							led->cdev_led2r.name);
+		goto failed_unregister_led2_R;
+	}
+
+	led->cdev_led2g.name = "led2_G";
+	led->cdev_led2g.brightness = LED_OFF;
+	led->cdev_led2g.brightness_set = bd2802_set_led2g_brightness;
+	led->cdev_led2g.blink_set = bd2802_set_led2g_blink;
+	led->cdev_led2g.flags |= LED_CORE_SUSPENDRESUME;
+
+	ret = led_classdev_register(&led->client->dev, &led->cdev_led2g);
+	if (ret < 0) {
+		dev_err(&led->client->dev, "couldn't register LED %s\n",
+							led->cdev_led2g.name);
+		goto failed_unregister_led2_G;
+	}
+
+	led->cdev_led2b.name = "led2_B";
+	led->cdev_led2b.brightness = LED_OFF;
+	led->cdev_led2b.brightness_set = bd2802_set_led2b_brightness;
+	led->cdev_led2b.blink_set = bd2802_set_led2b_blink;
+	led->cdev_led2b.flags |= LED_CORE_SUSPENDRESUME;
+
+	ret = led_classdev_register(&led->client->dev, &led->cdev_led2b);
+	if (ret < 0) {
+		dev_err(&led->client->dev, "couldn't register LED %s\n",
+							led->cdev_led2b.name);
+		goto failed_unregister_led2_B;
+	}
+
+	return 0;
+
+failed_unregister_led2_B:
+	led_classdev_unregister(&led->cdev_led2g);
+failed_unregister_led2_G:
+	led_classdev_unregister(&led->cdev_led2r);
+failed_unregister_led2_R:
+	led_classdev_unregister(&led->cdev_led1b);
+failed_unregister_led1_B:
+	led_classdev_unregister(&led->cdev_led1g);
+failed_unregister_led1_G:
+	led_classdev_unregister(&led->cdev_led1r);
+failed_unregister_led1_R:
+
+	return ret;
+}
+
+static void bd2802_unregister_led_classdev(struct bd2802_led *led)
+{
+	cancel_work_sync(&led->work);
+	led_classdev_unregister(&led->cdev_led1r);
+}
+
+static int __devinit bd2802_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct bd2802_led *led;
+	struct bd2802_led_platform_data *pdata;
+	int ret;
+
+	led = kzalloc(sizeof(struct bd2802_led), GFP_KERNEL);
+	if (!led) {
+		dev_err(&client->dev, "failed to allocate driver data\n");
+		return -ENOMEM;
+	}
+
+	led->client = client;
+	pdata = led->pdata = client->dev.platform_data;
+	i2c_set_clientdata(client, led);
+
+	/* Configure RESET GPIO (L: RESET, H: RESET cancel) */
+	gpio_request(pdata->reset_gpio, "RGB_RESETB");
+	gpio_direction_output(pdata->reset_gpio, 1);
+
+	/* Tacss = min 0.1ms */
+	udelay(100);
+
+	/* Detect BD2802GU */
+	ret = bd2802_write_byte(client, BD2802_REG_CLKSETUP, 0x00);
+	if (ret < 0) {
+		dev_err(&client->dev, "failed to detect device\n");
+		goto failed_free;
+	} else
+		dev_info(&client->dev, "return 0x%02x\n", ret);
+
+	/* To save the power, reset BD2802 after detecting */
+	gpio_set_value(led->pdata->reset_gpio, 0);
+
+	init_rwsem(&led->rwsem);
+
+	ret = device_create_file(&client->dev, &bd2802_adv_conf_attr);
+	if (ret) {
+		dev_err(&client->dev, "failed to create sysfs file %s\n",
+					bd2802_adv_conf_attr.attr.name);
+		goto failed_free;
+	}
+
+	ret = bd2802_register_led_classdev(led);
+	if (ret < 0)
+		goto failed_unregister_dev_file;
+
+	return 0;
+
+failed_unregister_dev_file:
+	device_remove_file(&client->dev, &bd2802_adv_conf_attr);
+failed_free:
+	i2c_set_clientdata(client, NULL);
+	kfree(led);
+
+	return ret;
+}
+
+static int __exit bd2802_remove(struct i2c_client *client)
+{
+	struct bd2802_led *led = i2c_get_clientdata(client);
+
+	bd2802_unregister_led_classdev(led);
+	gpio_set_value(led->pdata->reset_gpio, 0);
+	if (led->adf_on)
+		bd2802_disable_adv_conf(led);
+	device_remove_file(&client->dev, &bd2802_adv_conf_attr);
+	i2c_set_clientdata(client, NULL);
+	kfree(led);
+
+	return 0;
+}
+
+static int bd2802_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+	struct bd2802_led *led = i2c_get_clientdata(client);
+
+	gpio_set_value(led->pdata->reset_gpio, 0);
+
+	return 0;
+}
+
+static int bd2802_resume(struct i2c_client *client)
+{
+	struct bd2802_led *led = i2c_get_clientdata(client);
+
+	if (!bd2802_is_all_off(led) || led->adf_on) {
+		gpio_set_value(led->pdata->reset_gpio, 1);
+		udelay(100);
+		bd2802_restore_state(led);
+	}
+
+	return 0;
+}
+
+static const struct i2c_device_id bd2802_id[] = {
+	{ "BD2802", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, bd2802_id);
+
+static struct i2c_driver bd2802_i2c_driver = {
+	.driver	= {
+		.name	= "BD2802",
+	},
+	.probe		= bd2802_probe,
+	.remove		= __exit_p(bd2802_remove),
+	.suspend	= bd2802_suspend,
+	.resume		= bd2802_resume,
+	.id_table	= bd2802_id,
+};
+
+static int __init bd2802_init(void)
+{
+	return i2c_add_driver(&bd2802_i2c_driver);
+}
+module_init(bd2802_init);
+
+static void __exit bd2802_exit(void)
+{
+	i2c_del_driver(&bd2802_i2c_driver);
+}
+module_exit(bd2802_exit);
+
+MODULE_AUTHOR("Kim Kyuwon <q1.kim@samsung.com>");
+MODULE_DESCRIPTION("BD2802 LED driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/leds/leds-dac124s085.c b/drivers/leds/leds-dac124s085.c
new file mode 100644
index 0000000..098d9aa
--- /dev/null
+++ b/drivers/leds/leds-dac124s085.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2008
+ * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License.  See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * LED driver for the DAC124S085 SPI DAC
+ */
+
+#include <linux/gfp.h>
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <linux/spi/spi.h>
+
+struct dac124s085_led {
+	struct led_classdev	ldev;
+	struct spi_device	*spi;
+	int			id;
+	int			brightness;
+	char			name[sizeof("dac124s085-3")];
+
+	struct mutex		mutex;
+	struct work_struct	work;
+	spinlock_t		lock;
+};
+
+struct dac124s085 {
+	struct dac124s085_led leds[4];
+};
+
+#define REG_WRITE		(0 << 12)
+#define REG_WRITE_UPDATE	(1 << 12)
+#define ALL_WRITE_UPDATE	(2 << 12)
+#define POWER_DOWN_OUTPUT	(3 << 12)
+
+static void dac124s085_led_work(struct work_struct *work)
+{
+	struct dac124s085_led *led = container_of(work, struct dac124s085_led,
+						  work);
+	u16 word;
+
+	mutex_lock(&led->mutex);
+	word = cpu_to_le16(((led->id) << 14) | REG_WRITE_UPDATE |
+			   (led->brightness & 0xfff));
+	spi_write(led->spi, (const u8 *)&word, sizeof(word));
+	mutex_unlock(&led->mutex);
+}
+
+static void dac124s085_set_brightness(struct led_classdev *ldev,
+				      enum led_brightness brightness)
+{
+	struct dac124s085_led *led = container_of(ldev, struct dac124s085_led,
+						  ldev);
+
+	spin_lock(&led->lock);
+	led->brightness = brightness;
+	schedule_work(&led->work);
+	spin_unlock(&led->lock);
+}
+
+static int dac124s085_probe(struct spi_device *spi)
+{
+	struct dac124s085	*dac;
+	struct dac124s085_led	*led;
+	int i, ret;
+
+	dac = kzalloc(sizeof(*dac), GFP_KERNEL);
+	if (!dac)
+		return -ENOMEM;
+
+	spi->bits_per_word = 16;
+
+	for (i = 0; i < ARRAY_SIZE(dac->leds); i++) {
+		led		= dac->leds + i;
+		led->id		= i;
+		led->brightness	= LED_OFF;
+		led->spi	= spi;
+		snprintf(led->name, sizeof(led->name), "dac124s085-%d", i);
+		spin_lock_init(&led->lock);
+		INIT_WORK(&led->work, dac124s085_led_work);
+		mutex_init(&led->mutex);
+		led->ldev.name = led->name;
+		led->ldev.brightness = LED_OFF;
+		led->ldev.max_brightness = 0xfff;
+		led->ldev.brightness_set = dac124s085_set_brightness;
+		ret = led_classdev_register(&spi->dev, &led->ldev);
+		if (ret < 0)
+			goto eledcr;
+	}
+
+	spi_set_drvdata(spi, dac);
+
+	return 0;
+
+eledcr:
+	while (i--)
+		led_classdev_unregister(&dac->leds[i].ldev);
+
+	spi_set_drvdata(spi, NULL);
+	kfree(dac);
+	return ret;
+}
+
+static int dac124s085_remove(struct spi_device *spi)
+{
+	struct dac124s085	*dac = spi_get_drvdata(spi);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(dac->leds); i++) {
+		led_classdev_unregister(&dac->leds[i].ldev);
+		cancel_work_sync(&dac->leds[i].work);
+	}
+
+	spi_set_drvdata(spi, NULL);
+	kfree(dac);
+
+	return 0;
+}
+
+static struct spi_driver dac124s085_driver = {
+	.probe		= dac124s085_probe,
+	.remove		= dac124s085_remove,
+	.driver = {
+		.name	= "dac124s085",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init dac124s085_leds_init(void)
+{
+	return spi_register_driver(&dac124s085_driver);
+}
+
+static void __exit dac124s085_leds_exit(void)
+{
+	spi_unregister_driver(&dac124s085_driver);
+}
+
+module_init(dac124s085_leds_init);
+module_exit(dac124s085_leds_exit);
+
+MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
+MODULE_DESCRIPTION("DAC124S085 LED driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index 2e3df08..102ef4a 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2007 8D Technologies inc.
  * Raphael Assenat <raph@8d.com>
+ * Copyright (C) 2008 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 version 2 as
@@ -71,11 +72,67 @@
 	return led_dat->platform_gpio_blink_set(led_dat->gpio, delay_on, delay_off);
 }
 
+static int __devinit create_gpio_led(const struct gpio_led *template,
+	struct gpio_led_data *led_dat, struct device *parent,
+	int (*blink_set)(unsigned, unsigned long *, unsigned long *))
+{
+	int ret;
+
+	/* skip leds that aren't available */
+	if (!gpio_is_valid(template->gpio)) {
+		printk(KERN_INFO "Skipping unavilable LED gpio %d (%s)\n", 
+				template->gpio, template->name);
+		return;
+	}
+
+	ret = gpio_request(template->gpio, template->name);
+	if (ret < 0)
+		return ret;
+
+	led_dat->cdev.name = template->name;
+	led_dat->cdev.default_trigger = template->default_trigger;
+	led_dat->gpio = template->gpio;
+	led_dat->can_sleep = gpio_cansleep(template->gpio);
+	led_dat->active_low = template->active_low;
+	if (blink_set) {
+		led_dat->platform_gpio_blink_set = blink_set;
+		led_dat->cdev.blink_set = gpio_blink_set;
+	}
+	led_dat->cdev.brightness_set = gpio_led_set;
+	led_dat->cdev.brightness = LED_OFF;
+	if (!template->retain_state_suspended)
+		led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
+
+	ret = gpio_direction_output(led_dat->gpio, led_dat->active_low);
+	if (ret < 0)
+		goto err;
+
+	INIT_WORK(&led_dat->work, gpio_led_work);
+
+	ret = led_classdev_register(parent, &led_dat->cdev);
+	if (ret < 0)
+		goto err;
+
+	return 0;
+err:
+	gpio_free(led_dat->gpio);
+	return ret;
+}
+
+static void delete_gpio_led(struct gpio_led_data *led)
+{
+	if (!gpio_is_valid(led->gpio))
+		return;
+	led_classdev_unregister(&led->cdev);
+	cancel_work_sync(&led->work);
+	gpio_free(led->gpio);
+}
+
+#ifdef CONFIG_LEDS_GPIO_PLATFORM
 static int gpio_led_probe(struct platform_device *pdev)
 {
 	struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
-	struct gpio_led *cur_led;
-	struct gpio_led_data *leds_data, *led_dat;
+	struct gpio_led_data *leds_data;
 	int i, ret = 0;
 
 	if (!pdata)
@@ -87,35 +144,10 @@
 		return -ENOMEM;
 
 	for (i = 0; i < pdata->num_leds; i++) {
-		cur_led = &pdata->leds[i];
-		led_dat = &leds_data[i];
-
-		ret = gpio_request(cur_led->gpio, cur_led->name);
+		ret = create_gpio_led(&pdata->leds[i], &leds_data[i],
+				      &pdev->dev, pdata->gpio_blink_set);
 		if (ret < 0)
 			goto err;
-
-		led_dat->cdev.name = cur_led->name;
-		led_dat->cdev.default_trigger = cur_led->default_trigger;
-		led_dat->gpio = cur_led->gpio;
-		led_dat->can_sleep = gpio_cansleep(cur_led->gpio);
-		led_dat->active_low = cur_led->active_low;
-		if (pdata->gpio_blink_set) {
-			led_dat->platform_gpio_blink_set = pdata->gpio_blink_set;
-			led_dat->cdev.blink_set = gpio_blink_set;
-		}
-		led_dat->cdev.brightness_set = gpio_led_set;
-		led_dat->cdev.brightness = LED_OFF;
-		led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
-
-		gpio_direction_output(led_dat->gpio, led_dat->active_low);
-
-		INIT_WORK(&led_dat->work, gpio_led_work);
-
-		ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
-		if (ret < 0) {
-			gpio_free(led_dat->gpio);
-			goto err;
-		}
 	}
 
 	platform_set_drvdata(pdev, leds_data);
@@ -123,13 +155,8 @@
 	return 0;
 
 err:
-	if (i > 0) {
-		for (i = i - 1; i >= 0; i--) {
-			led_classdev_unregister(&leds_data[i].cdev);
-			cancel_work_sync(&leds_data[i].work);
-			gpio_free(leds_data[i].gpio);
-		}
-	}
+	for (i = i - 1; i >= 0; i--)
+		delete_gpio_led(&leds_data[i]);
 
 	kfree(leds_data);
 
@@ -144,11 +171,8 @@
 
 	leds_data = platform_get_drvdata(pdev);
 
-	for (i = 0; i < pdata->num_leds; i++) {
-		led_classdev_unregister(&leds_data[i].cdev);
-		cancel_work_sync(&leds_data[i].work);
-		gpio_free(leds_data[i].gpio);
-	}
+	for (i = 0; i < pdata->num_leds; i++)
+		delete_gpio_led(&leds_data[i]);
 
 	kfree(leds_data);
 
@@ -164,20 +188,133 @@
 	},
 };
 
+MODULE_ALIAS("platform:leds-gpio");
+#endif /* CONFIG_LEDS_GPIO_PLATFORM */
+
+/* Code to create from OpenFirmware platform devices */
+#ifdef CONFIG_LEDS_GPIO_OF
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
+
+struct gpio_led_of_platform_data {
+	int num_leds;
+	struct gpio_led_data led_data[];
+};
+
+static int __devinit of_gpio_leds_probe(struct of_device *ofdev,
+					const struct of_device_id *match)
+{
+	struct device_node *np = ofdev->node, *child;
+	struct gpio_led led;
+	struct gpio_led_of_platform_data *pdata;
+	int count = 0, ret;
+
+	/* count LEDs defined by this device, so we know how much to allocate */
+	for_each_child_of_node(np, child)
+		count++;
+	if (!count)
+		return 0; /* or ENODEV? */
+
+	pdata = kzalloc(sizeof(*pdata) + sizeof(struct gpio_led_data) * count,
+			GFP_KERNEL);
+	if (!pdata)
+		return -ENOMEM;
+
+	memset(&led, 0, sizeof(led));
+	for_each_child_of_node(np, child) {
+		enum of_gpio_flags flags;
+
+		led.gpio = of_get_gpio_flags(child, 0, &flags);
+		led.active_low = flags & OF_GPIO_ACTIVE_LOW;
+		led.name = of_get_property(child, "label", NULL) ? : child->name;
+		led.default_trigger =
+			of_get_property(child, "linux,default-trigger", NULL);
+
+		ret = create_gpio_led(&led, &pdata->led_data[pdata->num_leds++],
+				      &ofdev->dev, NULL);
+		if (ret < 0) {
+			of_node_put(child);
+			goto err;
+		}
+	}
+
+	dev_set_drvdata(&ofdev->dev, pdata);
+
+	return 0;
+
+err:
+	for (count = pdata->num_leds - 2; count >= 0; count--)
+		delete_gpio_led(&pdata->led_data[count]);
+
+	kfree(pdata);
+
+	return ret;
+}
+
+static int __devexit of_gpio_leds_remove(struct of_device *ofdev)
+{
+	struct gpio_led_of_platform_data *pdata = dev_get_drvdata(&ofdev->dev);
+	int i;
+
+	for (i = 0; i < pdata->num_leds; i++)
+		delete_gpio_led(&pdata->led_data[i]);
+
+	kfree(pdata);
+
+	dev_set_drvdata(&ofdev->dev, NULL);
+
+	return 0;
+}
+
+static const struct of_device_id of_gpio_leds_match[] = {
+	{ .compatible = "gpio-leds", },
+	{},
+};
+
+static struct of_platform_driver of_gpio_leds_driver = {
+	.driver = {
+		.name = "of_gpio_leds",
+		.owner = THIS_MODULE,
+	},
+	.match_table = of_gpio_leds_match,
+	.probe = of_gpio_leds_probe,
+	.remove = __devexit_p(of_gpio_leds_remove),
+};
+#endif
+
 static int __init gpio_led_init(void)
 {
-	return platform_driver_register(&gpio_led_driver);
+	int ret;
+
+#ifdef CONFIG_LEDS_GPIO_PLATFORM	
+	ret = platform_driver_register(&gpio_led_driver);
+	if (ret)
+		return ret;
+#endif
+#ifdef CONFIG_LEDS_GPIO_OF
+	ret = of_register_platform_driver(&of_gpio_leds_driver);
+#endif
+#ifdef CONFIG_LEDS_GPIO_PLATFORM	
+	if (ret)
+		platform_driver_unregister(&gpio_led_driver);
+#endif
+
+	return ret;
 }
 
 static void __exit gpio_led_exit(void)
 {
+#ifdef CONFIG_LEDS_GPIO_PLATFORM
 	platform_driver_unregister(&gpio_led_driver);
+#endif
+#ifdef CONFIG_LEDS_GPIO_OF
+	of_unregister_platform_driver(&of_gpio_leds_driver);
+#endif
 }
 
 module_init(gpio_led_init);
 module_exit(gpio_led_exit);
 
-MODULE_AUTHOR("Raphael Assenat <raph@8d.com>");
+MODULE_AUTHOR("Raphael Assenat <raph@8d.com>, Trent Piepho <tpiepho@freescale.com>");
 MODULE_DESCRIPTION("GPIO LED driver");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:leds-gpio");
diff --git a/drivers/leds/leds-h1940.c b/drivers/leds/leds-h1940.c
index 11b77a7..1aa46a3 100644
--- a/drivers/leds/leds-h1940.c
+++ b/drivers/leds/leds-h1940.c
@@ -104,7 +104,7 @@
 	.default_trigger	= "h1940-bluetooth",
 };
 
-static int __init h1940leds_probe(struct platform_device *pdev)
+static int __devinit h1940leds_probe(struct platform_device *pdev)
 {
 	int ret;
 
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c
index 76ec749..3937244 100644
--- a/drivers/leds/leds-pca9532.c
+++ b/drivers/leds/leds-pca9532.c
@@ -1,7 +1,7 @@
 /*
  * pca9532.c - 16-bit Led dimmer
  *
- * Copyright (C) 2008 Riku Voipio <riku.voipio@movial.fi>
+ * Copyright (C) 2008 Riku Voipio
  *
  * 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
@@ -169,7 +169,7 @@
 {
 	struct pca9532_data *data = input_get_drvdata(dev);
 
-	if (type != EV_SND && (code != SND_BELL || code != SND_TONE))
+	if (!(type == EV_SND && (code == SND_BELL || code == SND_TONE)))
 		return -1;
 
 	/* XXX: allow different kind of beeps with psc/pwm modifications */
@@ -367,7 +367,7 @@
 	i2c_del_driver(&pca9532_driver);
 }
 
-MODULE_AUTHOR("Riku Voipio <riku.voipio@movial.fi>");
+MODULE_AUTHOR("Riku Voipio");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("PCA 9532 LED dimmer");
 
diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
new file mode 100644
index 0000000..cdfdc87
--- /dev/null
+++ b/drivers/leds/leds-pwm.c
@@ -0,0 +1,153 @@
+/*
+ * linux/drivers/leds-pwm.c
+ *
+ * simple PWM based LED control
+ *
+ * Copyright 2009 Luotao Fu @ Pengutronix (l.fu@pengutronix.de)
+ *
+ * based on leds-gpio.c by Raphael Assenat <raph@8d.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/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/leds.h>
+#include <linux/err.h>
+#include <linux/pwm.h>
+#include <linux/leds_pwm.h>
+
+struct led_pwm_data {
+	struct led_classdev	cdev;
+	struct pwm_device	*pwm;
+	unsigned int 		active_low;
+	unsigned int		period;
+	unsigned int		max_brightness;
+};
+
+static void led_pwm_set(struct led_classdev *led_cdev,
+	enum led_brightness brightness)
+{
+	struct led_pwm_data *led_dat =
+		container_of(led_cdev, struct led_pwm_data, cdev);
+	unsigned int max = led_dat->max_brightness;
+	unsigned int period =  led_dat->period;
+
+	if (brightness == 0) {
+		pwm_config(led_dat->pwm, 0, period);
+		pwm_disable(led_dat->pwm);
+	} else {
+		pwm_config(led_dat->pwm, brightness * period / max, period);
+		pwm_enable(led_dat->pwm);
+	}
+}
+
+static int led_pwm_probe(struct platform_device *pdev)
+{
+	struct led_pwm_platform_data *pdata = pdev->dev.platform_data;
+	struct led_pwm *cur_led;
+	struct led_pwm_data *leds_data, *led_dat;
+	int i, ret = 0;
+
+	if (!pdata)
+		return -EBUSY;
+
+	leds_data = kzalloc(sizeof(struct led_pwm_data) * pdata->num_leds,
+				GFP_KERNEL);
+	if (!leds_data)
+		return -ENOMEM;
+
+	for (i = 0; i < pdata->num_leds; i++) {
+		cur_led = &pdata->leds[i];
+		led_dat = &leds_data[i];
+
+		led_dat->pwm = pwm_request(cur_led->pwm_id,
+				cur_led->name);
+		if (IS_ERR(led_dat->pwm)) {
+			dev_err(&pdev->dev, "unable to request PWM %d\n",
+					cur_led->pwm_id);
+			goto err;
+		}
+
+		led_dat->cdev.name = cur_led->name;
+		led_dat->cdev.default_trigger = cur_led->default_trigger;
+		led_dat->active_low = cur_led->active_low;
+		led_dat->max_brightness = cur_led->max_brightness;
+		led_dat->period = cur_led->pwm_period_ns;
+		led_dat->cdev.brightness_set = led_pwm_set;
+		led_dat->cdev.brightness = LED_OFF;
+		led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
+
+		ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
+		if (ret < 0) {
+			pwm_free(led_dat->pwm);
+			goto err;
+		}
+	}
+
+	platform_set_drvdata(pdev, leds_data);
+
+	return 0;
+
+err:
+	if (i > 0) {
+		for (i = i - 1; i >= 0; i--) {
+			led_classdev_unregister(&leds_data[i].cdev);
+			pwm_free(leds_data[i].pwm);
+		}
+	}
+
+	kfree(leds_data);
+
+	return ret;
+}
+
+static int __devexit led_pwm_remove(struct platform_device *pdev)
+{
+	int i;
+	struct led_pwm_platform_data *pdata = pdev->dev.platform_data;
+	struct led_pwm_data *leds_data;
+
+	leds_data = platform_get_drvdata(pdev);
+
+	for (i = 0; i < pdata->num_leds; i++) {
+		led_classdev_unregister(&leds_data[i].cdev);
+		pwm_free(leds_data[i].pwm);
+	}
+
+	kfree(leds_data);
+
+	return 0;
+}
+
+static struct platform_driver led_pwm_driver = {
+	.probe		= led_pwm_probe,
+	.remove		= __devexit_p(led_pwm_remove),
+	.driver		= {
+		.name	= "leds_pwm",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init led_pwm_init(void)
+{
+	return platform_driver_register(&led_pwm_driver);
+}
+
+static void __exit led_pwm_exit(void)
+{
+	platform_driver_unregister(&led_pwm_driver);
+}
+
+module_init(led_pwm_init);
+module_exit(led_pwm_exit);
+
+MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>");
+MODULE_DESCRIPTION("PWM LED driver for PXA");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:leds-pwm");
diff --git a/drivers/leds/leds-rb532.c b/drivers/leds/leds-rb532.c
new file mode 100644
index 0000000..c3525f3
--- /dev/null
+++ b/drivers/leds/leds-rb532.c
@@ -0,0 +1,77 @@
+/*
+ * LEDs driver for the "User LED" on Routerboard532
+ *
+ * Copyright (C) 2009 Phil Sutter <n0-1@freewrt.org>
+ *
+ * Based on leds-cobalt-qube.c by Florian Fainelly and
+ * rb-diag.c (my own standalone driver for both LED and
+ * button of Routerboard532).
+ */
+
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-rc32434/gpio.h>
+#include <asm/mach-rc32434/rb.h>
+
+static void rb532_led_set(struct led_classdev *cdev,
+                          enum led_brightness brightness)
+{
+	if (brightness)
+		set_latch_u5(LO_ULED, 0);
+
+	else
+		set_latch_u5(0, LO_ULED);
+}
+
+static enum led_brightness rb532_led_get(struct led_classdev *cdev)
+{
+	return (get_latch_u5() & LO_ULED) ? LED_FULL : LED_OFF;
+}
+
+static struct led_classdev rb532_uled = {
+	.name = "uled",
+	.brightness_set = rb532_led_set,
+	.brightness_get = rb532_led_get,
+	.default_trigger = "nand-disk",
+};
+
+static int __devinit rb532_led_probe(struct platform_device *pdev)
+{
+	return led_classdev_register(&pdev->dev, &rb532_uled);
+}
+
+static int __devexit rb532_led_remove(struct platform_device *pdev)
+{
+	led_classdev_unregister(&rb532_uled);
+	return 0;
+}
+
+static struct platform_driver rb532_led_driver = {
+	.probe = rb532_led_probe,
+	.remove = __devexit_p(rb532_led_remove),
+	.driver = {
+		.name = "rb532-led",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init rb532_led_init(void)
+{
+	return platform_driver_register(&rb532_led_driver);
+}
+
+static void __exit rb532_led_exit(void)
+{
+	platform_driver_unregister(&rb532_led_driver);
+}
+
+module_init(rb532_led_init);
+module_exit(rb532_led_exit);
+
+MODULE_ALIAS("platform:rb532-led");
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("User LED support for Routerboard532");
+MODULE_AUTHOR("Phil Sutter <n0-1@freewrt.org>");
diff --git a/drivers/leds/leds-s3c24xx.c b/drivers/leds/leds-s3c24xx.c
index 4d81131..aa2e7ae 100644
--- a/drivers/leds/leds-s3c24xx.c
+++ b/drivers/leds/leds-s3c24xx.c
@@ -102,14 +102,11 @@
 	ret = led_classdev_register(&dev->dev, &led->cdev);
 	if (ret < 0) {
 		dev_err(&dev->dev, "led_classdev_register failed\n");
-		goto exit_err1;
+		kfree(led);
+		return ret;
 	}
 
 	return 0;
-
- exit_err1:
-	kfree(led);
-	return ret;
 }
 
 static struct platform_driver s3c24xx_led_driver = {
diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h
index 5edbf52..2dd8ecb 100644
--- a/drivers/leds/leds.h
+++ b/drivers/leds/leds.h
@@ -20,8 +20,8 @@
 static inline void led_set_brightness(struct led_classdev *led_cdev,
 					enum led_brightness value)
 {
-	if (value > LED_FULL)
-		value = LED_FULL;
+	if (value > led_cdev->max_brightness)
+		value = led_cdev->max_brightness;
 	led_cdev->brightness = value;
 	if (!(led_cdev->flags & LED_SUSPENDED))
 		led_cdev->brightness_set(led_cdev, value);
diff --git a/drivers/leds/ledtrig-default-on.c b/drivers/leds/ledtrig-default-on.c
index 92995e4..a4ef54b 100644
--- a/drivers/leds/ledtrig-default-on.c
+++ b/drivers/leds/ledtrig-default-on.c
@@ -19,7 +19,7 @@
 
 static void defon_trig_activate(struct led_classdev *led_cdev)
 {
-	led_set_brightness(led_cdev, LED_FULL);
+	led_set_brightness(led_cdev, led_cdev->max_brightness);
 }
 
 static struct led_trigger defon_led_trigger = {
diff --git a/drivers/leds/ledtrig-gpio.c b/drivers/leds/ledtrig-gpio.c
new file mode 100644
index 0000000..a247ae6
--- /dev/null
+++ b/drivers/leds/ledtrig-gpio.c
@@ -0,0 +1,239 @@
+/*
+ * ledtrig-gio.c - LED Trigger Based on GPIO events
+ *
+ * Copyright 2009 Felipe Balbi <me@felipebalbi.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/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/leds.h>
+#include "leds.h"
+
+struct gpio_trig_data {
+	struct led_classdev *led;
+	struct work_struct work;
+
+	unsigned desired_brightness;	/* desired brightness when led is on */
+	unsigned inverted;		/* true when gpio is inverted */
+	unsigned gpio;			/* gpio that triggers the leds */
+};
+
+static irqreturn_t gpio_trig_irq(int irq, void *_led)
+{
+	struct led_classdev *led = _led;
+	struct gpio_trig_data *gpio_data = led->trigger_data;
+
+	/* just schedule_work since gpio_get_value can sleep */
+	schedule_work(&gpio_data->work);
+
+	return IRQ_HANDLED;
+};
+
+static void gpio_trig_work(struct work_struct *work)
+{
+	struct gpio_trig_data *gpio_data = container_of(work,
+			struct gpio_trig_data, work);
+	int tmp;
+
+       if (!gpio_data->gpio)
+	       return;
+
+       tmp = gpio_get_value(gpio_data->gpio);
+       if (gpio_data->inverted)
+	       tmp = !tmp;
+
+       if (tmp) {
+               if (gpio_data->desired_brightness)
+                       led_set_brightness(gpio_data->led,
+                                       gpio_data->desired_brightness);
+               else
+                       led_set_brightness(gpio_data->led, LED_FULL);
+       } else {
+               led_set_brightness(gpio_data->led, LED_OFF);
+       }
+}
+
+static ssize_t gpio_trig_brightness_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct led_classdev *led = dev_get_drvdata(dev);
+	struct gpio_trig_data *gpio_data = led->trigger_data;
+
+	return sprintf(buf, "%u\n", gpio_data->desired_brightness);
+}
+
+static ssize_t gpio_trig_brightness_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t n)
+{
+	struct led_classdev *led = dev_get_drvdata(dev);
+	struct gpio_trig_data *gpio_data = led->trigger_data;
+	unsigned desired_brightness;
+	int ret;
+
+	ret = sscanf(buf, "%u", &desired_brightness);
+	if (ret < 1 || desired_brightness > 255) {
+		dev_err(dev, "invalid value\n");
+		return -EINVAL;
+	}
+
+	gpio_data->desired_brightness = desired_brightness;
+
+	return n;
+}
+static DEVICE_ATTR(desired_brightness, 0644, gpio_trig_brightness_show,
+		gpio_trig_brightness_store);
+
+static ssize_t gpio_trig_inverted_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct led_classdev *led = dev_get_drvdata(dev);
+	struct gpio_trig_data *gpio_data = led->trigger_data;
+
+	return sprintf(buf, "%s\n", gpio_data->inverted ? "yes" : "no");
+}
+
+static ssize_t gpio_trig_inverted_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t n)
+{
+	struct led_classdev *led = dev_get_drvdata(dev);
+	struct gpio_trig_data *gpio_data = led->trigger_data;
+	unsigned inverted;
+	int ret;
+
+	ret = sscanf(buf, "%u", &inverted);
+	if (ret < 1) {
+		dev_err(dev, "invalid value\n");
+		return -EINVAL;
+	}
+
+	gpio_data->inverted = !!inverted;
+
+	return n;
+}
+static DEVICE_ATTR(inverted, 0644, gpio_trig_inverted_show,
+		gpio_trig_inverted_store);
+
+static ssize_t gpio_trig_gpio_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct led_classdev *led = dev_get_drvdata(dev);
+	struct gpio_trig_data *gpio_data = led->trigger_data;
+
+	return sprintf(buf, "%u\n", gpio_data->gpio);
+}
+
+static ssize_t gpio_trig_gpio_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t n)
+{
+	struct led_classdev *led = dev_get_drvdata(dev);
+	struct gpio_trig_data *gpio_data = led->trigger_data;
+	unsigned gpio;
+	int ret;
+
+	ret = sscanf(buf, "%u", &gpio);
+	if (ret < 1) {
+		dev_err(dev, "couldn't read gpio number\n");
+		flush_work(&gpio_data->work);
+		return -EINVAL;
+	}
+
+	if (!gpio) {
+		free_irq(gpio_to_irq(gpio_data->gpio), led);
+		return n;
+	}
+
+	if (gpio_data->gpio > 0 && gpio_data->gpio != gpio)
+		free_irq(gpio_to_irq(gpio_data->gpio), led);
+
+	gpio_data->gpio = gpio;
+	ret = request_irq(gpio_to_irq(gpio), gpio_trig_irq,
+			IRQF_SHARED | IRQF_TRIGGER_RISING
+			| IRQF_TRIGGER_FALLING, "ledtrig-gpio", led);
+	if (ret)
+		dev_err(dev, "request_irq failed with error %d\n", ret);
+
+	return ret ? ret : n;
+}
+static DEVICE_ATTR(gpio, 0644, gpio_trig_gpio_show, gpio_trig_gpio_store);
+
+static void gpio_trig_activate(struct led_classdev *led)
+{
+	struct gpio_trig_data *gpio_data;
+	int ret;
+
+	gpio_data = kzalloc(sizeof(*gpio_data), GFP_KERNEL);
+	if (!gpio_data)
+		return;
+
+	ret = device_create_file(led->dev, &dev_attr_gpio);
+	if (ret)
+		goto err_gpio;
+
+	ret = device_create_file(led->dev, &dev_attr_inverted);
+	if (ret)
+		goto err_inverted;
+
+	ret = device_create_file(led->dev, &dev_attr_desired_brightness);
+	if (ret)
+		goto err_brightness;
+
+	gpio_data->led = led;
+	led->trigger_data = gpio_data;
+	INIT_WORK(&gpio_data->work, gpio_trig_work);
+
+	return;
+
+err_brightness:
+	device_remove_file(led->dev, &dev_attr_inverted);
+
+err_inverted:
+	device_remove_file(led->dev, &dev_attr_gpio);
+
+err_gpio:
+	kfree(gpio_data);
+}
+
+static void gpio_trig_deactivate(struct led_classdev *led)
+{
+	struct gpio_trig_data *gpio_data = led->trigger_data;
+
+	if (gpio_data) {
+		device_remove_file(led->dev, &dev_attr_gpio);
+		device_remove_file(led->dev, &dev_attr_inverted);
+		device_remove_file(led->dev, &dev_attr_desired_brightness);
+		flush_work(&gpio_data->work);
+		free_irq(gpio_to_irq(gpio_data->gpio),led);
+		kfree(gpio_data);
+	}
+}
+
+static struct led_trigger gpio_led_trigger = {
+	.name		= "gpio",
+	.activate	= gpio_trig_activate,
+	.deactivate	= gpio_trig_deactivate,
+};
+
+static int __init gpio_trig_init(void)
+{
+	return led_trigger_register(&gpio_led_trigger);
+}
+module_init(gpio_trig_init);
+
+static void __exit gpio_trig_exit(void)
+{
+	led_trigger_unregister(&gpio_led_trigger);
+}
+module_exit(gpio_trig_exit);
+
+MODULE_AUTHOR("Felipe Balbi <me@felipebalbi.com>");
+MODULE_DESCRIPTION("GPIO LED trigger");
+MODULE_LICENSE("GPL");
diff --git a/drivers/leds/ledtrig-heartbeat.c b/drivers/leds/ledtrig-heartbeat.c
index 4bf8cec..c1c1ea6 100644
--- a/drivers/leds/ledtrig-heartbeat.c
+++ b/drivers/leds/ledtrig-heartbeat.c
@@ -47,7 +47,7 @@
 			msecs_to_jiffies(heartbeat_data->period);
 		delay = msecs_to_jiffies(70);
 		heartbeat_data->phase++;
-		brightness = LED_FULL;
+		brightness = led_cdev->max_brightness;
 		break;
 	case 1:
 		delay = heartbeat_data->period / 4 - msecs_to_jiffies(70);
@@ -56,7 +56,7 @@
 	case 2:
 		delay = msecs_to_jiffies(70);
 		heartbeat_data->phase++;
-		brightness = LED_FULL;
+		brightness = led_cdev->max_brightness;
 		break;
 	default:
 		delay = heartbeat_data->period - heartbeat_data->period / 4 -
diff --git a/drivers/leds/ledtrig-ide-disk.c b/drivers/leds/ledtrig-ide-disk.c
index 883a577..ec099fc 100644
--- a/drivers/leds/ledtrig-ide-disk.c
+++ b/drivers/leds/ledtrig-ide-disk.c
@@ -37,7 +37,8 @@
 {
 	if (ide_lastactivity != ide_activity) {
 		ide_lastactivity = ide_activity;
-		led_trigger_event(ledtrig_ide, LED_FULL);
+		/* INT_MAX will set each LED to its maximum brightness */
+		led_trigger_event(ledtrig_ide, INT_MAX);
 		mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10));
 	} else {
 		led_trigger_event(ledtrig_ide, LED_OFF);
diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c
index 3d65313..3b83406 100644
--- a/drivers/leds/ledtrig-timer.c
+++ b/drivers/leds/ledtrig-timer.c
@@ -166,7 +166,7 @@
 
 	timer_data->brightness_on = led_get_brightness(led_cdev);
 	if (timer_data->brightness_on == LED_OFF)
-		timer_data->brightness_on = LED_FULL;
+		timer_data->brightness_on = led_cdev->max_brightness;
 	led_cdev->trigger_data = timer_data;
 
 	init_timer(&timer_data->timer);
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
index 2281b50..36e0675 100644
--- a/drivers/md/Kconfig
+++ b/drivers/md/Kconfig
@@ -121,6 +121,7 @@
 config MD_RAID456
 	tristate "RAID-4/RAID-5/RAID-6 mode"
 	depends on BLK_DEV_MD
+	select MD_RAID6_PQ
 	select ASYNC_MEMCPY
 	select ASYNC_XOR
 	---help---
@@ -151,34 +152,8 @@
 
 	  If unsure, say Y.
 
-config MD_RAID5_RESHAPE
-	bool "Support adding drives to a raid-5 array"
-	depends on MD_RAID456
-	default y
-	---help---
-	  A RAID-5 set can be expanded by adding extra drives. This
-	  requires "restriping" the array which means (almost) every
-	  block must be written to a different place.
-
-          This option allows such restriping to be done while the array
-	  is online.
-
-	  You will need mdadm version 2.4.1 or later to use this
-	  feature safely.  During the early stage of reshape there is
-	  a critical section where live data is being over-written.  A
-	  crash during this time needs extra care for recovery.  The
-	  newer mdadm takes a copy of the data in the critical section
-	  and will restore it, if necessary, after a crash.
-
-	  The mdadm usage is e.g.
-	       mdadm --grow /dev/md1 --raid-disks=6
-	  to grow '/dev/md1' to having 6 disks.
-
-	  Note: The array can only be expanded, not contracted.
-	  There should be enough spares already present to make the new
-	  array workable.
-
-	  If unsure, say Y.
+config MD_RAID6_PQ
+	tristate
 
 config MD_MULTIPATH
 	tristate "Multipath I/O support"
diff --git a/drivers/md/Makefile b/drivers/md/Makefile
index 72880b7..45cc595 100644
--- a/drivers/md/Makefile
+++ b/drivers/md/Makefile
@@ -2,20 +2,21 @@
 # Makefile for the kernel software RAID and LVM drivers.
 #
 
-dm-mod-objs	:= dm.o dm-table.o dm-target.o dm-linear.o dm-stripe.o \
+dm-mod-y	+= dm.o dm-table.o dm-target.o dm-linear.o dm-stripe.o \
 		   dm-ioctl.o dm-io.o dm-kcopyd.o dm-sysfs.o
-dm-multipath-objs := dm-path-selector.o dm-mpath.o
-dm-snapshot-objs := dm-snap.o dm-exception-store.o dm-snap-transient.o \
+dm-multipath-y	+= dm-path-selector.o dm-mpath.o
+dm-snapshot-y	+= dm-snap.o dm-exception-store.o dm-snap-transient.o \
 		    dm-snap-persistent.o
-dm-mirror-objs	:= dm-raid1.o
-md-mod-objs     := md.o bitmap.o
-raid456-objs	:= raid5.o raid6algos.o raid6recov.o raid6tables.o \
+dm-mirror-y	+= dm-raid1.o
+md-mod-y	+= md.o bitmap.o
+raid456-y	+= raid5.o
+raid6_pq-y	+= raid6algos.o raid6recov.o raid6tables.o \
 		   raid6int1.o raid6int2.o raid6int4.o \
 		   raid6int8.o raid6int16.o raid6int32.o \
 		   raid6altivec1.o raid6altivec2.o raid6altivec4.o \
 		   raid6altivec8.o \
 		   raid6mmx.o raid6sse1.o raid6sse2.o
-hostprogs-y	:= mktables
+hostprogs-y	+= mktables
 
 # Note: link order is important.  All raid personalities
 # and must come before md.o, as they each initialise 
@@ -26,6 +27,7 @@
 obj-$(CONFIG_MD_RAID0)		+= raid0.o
 obj-$(CONFIG_MD_RAID1)		+= raid1.o
 obj-$(CONFIG_MD_RAID10)		+= raid10.o
+obj-$(CONFIG_MD_RAID6_PQ)	+= raid6_pq.o
 obj-$(CONFIG_MD_RAID456)	+= raid456.o
 obj-$(CONFIG_MD_MULTIPATH)	+= multipath.o
 obj-$(CONFIG_MD_FAULTY)		+= faulty.o
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 7199437..f8a9f7a 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -16,6 +16,7 @@
  * wait if count gets too high, wake when it drops to half.
  */
 
+#include <linux/blkdev.h>
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
@@ -26,8 +27,8 @@
 #include <linux/file.h>
 #include <linux/mount.h>
 #include <linux/buffer_head.h>
-#include <linux/raid/md.h>
-#include <linux/raid/bitmap.h>
+#include "md.h"
+#include "bitmap.h"
 
 /* debug macros */
 
@@ -111,9 +112,10 @@
 	unsigned char *mappage;
 
 	if (page >= bitmap->pages) {
-		printk(KERN_ALERT
-			"%s: invalid bitmap page request: %lu (> %lu)\n",
-			bmname(bitmap), page, bitmap->pages-1);
+		/* This can happen if bitmap_start_sync goes beyond
+		 * End-of-device while looking for a whole page.
+		 * It is harmless.
+		 */
 		return -EINVAL;
 	}
 
@@ -265,7 +267,6 @@
 	list_for_each_continue_rcu(pos, &mddev->disks) {
 		rdev = list_entry(pos, mdk_rdev_t, same_set);
 		if (rdev->raid_disk >= 0 &&
-		    test_bit(In_sync, &rdev->flags) &&
 		    !test_bit(Faulty, &rdev->flags)) {
 			/* this is a usable devices */
 			atomic_inc(&rdev->nr_pending);
@@ -297,7 +298,7 @@
 				    + size/512 > 0)
 					/* bitmap runs in to metadata */
 					goto bad_alignment;
-				if (rdev->data_offset + mddev->size*2
+				if (rdev->data_offset + mddev->dev_sectors
 				    > rdev->sb_start + bitmap->offset)
 					/* data runs in to bitmap */
 					goto bad_alignment;
@@ -570,7 +571,7 @@
 	else if (le32_to_cpu(sb->version) < BITMAP_MAJOR_LO ||
 		 le32_to_cpu(sb->version) > BITMAP_MAJOR_HI)
 		reason = "unrecognized superblock version";
-	else if (chunksize < PAGE_SIZE)
+	else if (chunksize < 512)
 		reason = "bitmap chunksize too small";
 	else if ((1 << ffz(~chunksize)) != chunksize)
 		reason = "bitmap chunksize not a power of 2";
@@ -1306,6 +1307,9 @@
 		PRINTK(KERN_DEBUG "dec write-behind count %d/%d\n",
 		  atomic_read(&bitmap->behind_writes), bitmap->max_write_behind);
 	}
+	if (bitmap->mddev->degraded)
+		/* Never clear bits or update events_cleared when degraded */
+		success = 0;
 
 	while (sectors) {
 		int blocks;
@@ -1345,8 +1349,8 @@
 	}
 }
 
-int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
-			int degraded)
+static int __bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
+			       int degraded)
 {
 	bitmap_counter_t *bmc;
 	int rv;
@@ -1374,6 +1378,29 @@
 	return rv;
 }
 
+int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
+		      int degraded)
+{
+	/* bitmap_start_sync must always report on multiples of whole
+	 * pages, otherwise resync (which is very PAGE_SIZE based) will
+	 * get confused.
+	 * So call __bitmap_start_sync repeatedly (if needed) until
+	 * At least PAGE_SIZE>>9 blocks are covered.
+	 * Return the 'or' of the result.
+	 */
+	int rv = 0;
+	int blocks1;
+
+	*blocks = 0;
+	while (*blocks < (PAGE_SIZE>>9)) {
+		rv |= __bitmap_start_sync(bitmap, offset,
+					  &blocks1, degraded);
+		offset += blocks1;
+		*blocks += blocks1;
+	}
+	return rv;
+}
+
 void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted)
 {
 	bitmap_counter_t *bmc;
@@ -1443,6 +1470,8 @@
 	wait_event(bitmap->mddev->recovery_wait,
 		   atomic_read(&bitmap->mddev->recovery_active) == 0);
 
+	bitmap->mddev->curr_resync_completed = bitmap->mddev->curr_resync;
+	set_bit(MD_CHANGE_CLEAN, &bitmap->mddev->flags);
 	sector &= ~((1ULL << CHUNK_BLOCK_SHIFT(bitmap)) - 1);
 	s = 0;
 	while (s < sector && s < bitmap->mddev->resync_max_sectors) {
diff --git a/include/linux/raid/bitmap.h b/drivers/md/bitmap.h
similarity index 100%
rename from include/linux/raid/bitmap.h
rename to drivers/md/bitmap.h
diff --git a/drivers/md/dm-bio-list.h b/drivers/md/dm-bio-list.h
index d4509be..345098b 100644
--- a/drivers/md/dm-bio-list.h
+++ b/drivers/md/dm-bio-list.h
@@ -52,6 +52,16 @@
 	bl->tail = bio;
 }
 
+static inline void bio_list_add_head(struct bio_list *bl, struct bio *bio)
+{
+	bio->bi_next = bl->head;
+
+	bl->head = bio;
+
+	if (!bl->tail)
+		bl->tail = bio;
+}
+
 static inline void bio_list_merge(struct bio_list *bl, struct bio_list *bl2)
 {
 	if (!bl2->head)
diff --git a/drivers/md/dm-bio-record.h b/drivers/md/dm-bio-record.h
index d3ec217..3a8cfa2 100644
--- a/drivers/md/dm-bio-record.h
+++ b/drivers/md/dm-bio-record.h
@@ -16,30 +16,56 @@
  * functions in this file help the target record and restore the
  * original bio state.
  */
+
+struct dm_bio_vec_details {
+#if PAGE_SIZE < 65536
+	__u16 bv_len;
+	__u16 bv_offset;
+#else
+	unsigned bv_len;
+	unsigned bv_offset;
+#endif
+};
+
 struct dm_bio_details {
 	sector_t bi_sector;
 	struct block_device *bi_bdev;
 	unsigned int bi_size;
 	unsigned short bi_idx;
 	unsigned long bi_flags;
+	struct dm_bio_vec_details bi_io_vec[BIO_MAX_PAGES];
 };
 
 static inline void dm_bio_record(struct dm_bio_details *bd, struct bio *bio)
 {
+	unsigned i;
+
 	bd->bi_sector = bio->bi_sector;
 	bd->bi_bdev = bio->bi_bdev;
 	bd->bi_size = bio->bi_size;
 	bd->bi_idx = bio->bi_idx;
 	bd->bi_flags = bio->bi_flags;
+
+	for (i = 0; i < bio->bi_vcnt; i++) {
+		bd->bi_io_vec[i].bv_len = bio->bi_io_vec[i].bv_len;
+		bd->bi_io_vec[i].bv_offset = bio->bi_io_vec[i].bv_offset;
+	}
 }
 
 static inline void dm_bio_restore(struct dm_bio_details *bd, struct bio *bio)
 {
+	unsigned i;
+
 	bio->bi_sector = bd->bi_sector;
 	bio->bi_bdev = bd->bi_bdev;
 	bio->bi_size = bd->bi_size;
 	bio->bi_idx = bd->bi_idx;
 	bio->bi_flags = bd->bi_flags;
+
+	for (i = 0; i < bio->bi_vcnt; i++) {
+		bio->bi_io_vec[i].bv_len = bd->bi_io_vec[i].bv_len;
+		bio->bi_io_vec[i].bv_offset = bd->bi_io_vec[i].bv_offset;
+	}
 }
 
 #endif
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index bfefd07..53394e8 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -1156,8 +1156,7 @@
 	crypto_free_ablkcipher(tfm);
 bad_cipher:
 	/* Must zero key material before freeing */
-	memset(cc, 0, sizeof(*cc) + cc->key_size * sizeof(u8));
-	kfree(cc);
+	kzfree(cc);
 	return -EINVAL;
 }
 
@@ -1183,8 +1182,7 @@
 	dm_put_device(ti, cc->dev);
 
 	/* Must zero key material before freeing */
-	memset(cc, 0, sizeof(*cc) + cc->key_size * sizeof(u8));
-	kfree(cc);
+	kzfree(cc);
 }
 
 static int crypt_map(struct dm_target *ti, struct bio *bio,
diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c
index dccbfb0..a2e26c2 100644
--- a/drivers/md/dm-exception-store.c
+++ b/drivers/md/dm-exception-store.c
@@ -7,6 +7,7 @@
 
 #include "dm-exception-store.h"
 
+#include <linux/ctype.h>
 #include <linux/mm.h>
 #include <linux/pagemap.h>
 #include <linux/vmalloc.h>
@@ -14,6 +15,257 @@
 
 #define DM_MSG_PREFIX "snapshot exception stores"
 
+static LIST_HEAD(_exception_store_types);
+static DEFINE_SPINLOCK(_lock);
+
+static struct dm_exception_store_type *__find_exception_store_type(const char *name)
+{
+	struct dm_exception_store_type *type;
+
+	list_for_each_entry(type, &_exception_store_types, list)
+		if (!strcmp(name, type->name))
+			return type;
+
+	return NULL;
+}
+
+static struct dm_exception_store_type *_get_exception_store_type(const char *name)
+{
+	struct dm_exception_store_type *type;
+
+	spin_lock(&_lock);
+
+	type = __find_exception_store_type(name);
+
+	if (type && !try_module_get(type->module))
+		type = NULL;
+
+	spin_unlock(&_lock);
+
+	return type;
+}
+
+/*
+ * get_type
+ * @type_name
+ *
+ * Attempt to retrieve the dm_exception_store_type by name.  If not already
+ * available, attempt to load the appropriate module.
+ *
+ * Exstore modules are named "dm-exstore-" followed by the 'type_name'.
+ * Modules may contain multiple types.
+ * This function will first try the module "dm-exstore-<type_name>",
+ * then truncate 'type_name' on the last '-' and try again.
+ *
+ * For example, if type_name was "clustered-shared", it would search
+ * 'dm-exstore-clustered-shared' then 'dm-exstore-clustered'.
+ *
+ * 'dm-exception-store-<type_name>' is too long of a name in my
+ * opinion, which is why I've chosen to have the files
+ * containing exception store implementations be 'dm-exstore-<type_name>'.
+ * If you want your module to be autoloaded, you will follow this
+ * naming convention.
+ *
+ * Returns: dm_exception_store_type* on success, NULL on failure
+ */
+static struct dm_exception_store_type *get_type(const char *type_name)
+{
+	char *p, *type_name_dup;
+	struct dm_exception_store_type *type;
+
+	type = _get_exception_store_type(type_name);
+	if (type)
+		return type;
+
+	type_name_dup = kstrdup(type_name, GFP_KERNEL);
+	if (!type_name_dup) {
+		DMERR("No memory left to attempt load for \"%s\"", type_name);
+		return NULL;
+	}
+
+	while (request_module("dm-exstore-%s", type_name_dup) ||
+	       !(type = _get_exception_store_type(type_name))) {
+		p = strrchr(type_name_dup, '-');
+		if (!p)
+			break;
+		p[0] = '\0';
+	}
+
+	if (!type)
+		DMWARN("Module for exstore type \"%s\" not found.", type_name);
+
+	kfree(type_name_dup);
+
+	return type;
+}
+
+static void put_type(struct dm_exception_store_type *type)
+{
+	spin_lock(&_lock);
+	module_put(type->module);
+	spin_unlock(&_lock);
+}
+
+int dm_exception_store_type_register(struct dm_exception_store_type *type)
+{
+	int r = 0;
+
+	spin_lock(&_lock);
+	if (!__find_exception_store_type(type->name))
+		list_add(&type->list, &_exception_store_types);
+	else
+		r = -EEXIST;
+	spin_unlock(&_lock);
+
+	return r;
+}
+EXPORT_SYMBOL(dm_exception_store_type_register);
+
+int dm_exception_store_type_unregister(struct dm_exception_store_type *type)
+{
+	spin_lock(&_lock);
+
+	if (!__find_exception_store_type(type->name)) {
+		spin_unlock(&_lock);
+		return -EINVAL;
+	}
+
+	list_del(&type->list);
+
+	spin_unlock(&_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL(dm_exception_store_type_unregister);
+
+/*
+ * Round a number up to the nearest 'size' boundary.  size must
+ * be a power of 2.
+ */
+static ulong round_up(ulong n, ulong size)
+{
+	size--;
+	return (n + size) & ~size;
+}
+
+static int set_chunk_size(struct dm_exception_store *store,
+			  const char *chunk_size_arg, char **error)
+{
+	unsigned long chunk_size_ulong;
+	char *value;
+
+	chunk_size_ulong = simple_strtoul(chunk_size_arg, &value, 10);
+	if (*chunk_size_arg == '\0' || *value != '\0') {
+		*error = "Invalid chunk size";
+		return -EINVAL;
+	}
+
+	if (!chunk_size_ulong) {
+		store->chunk_size = store->chunk_mask = store->chunk_shift = 0;
+		return 0;
+	}
+
+	/*
+	 * Chunk size must be multiple of page size.  Silently
+	 * round up if it's not.
+	 */
+	chunk_size_ulong = round_up(chunk_size_ulong, PAGE_SIZE >> 9);
+
+	/* Check chunk_size is a power of 2 */
+	if (!is_power_of_2(chunk_size_ulong)) {
+		*error = "Chunk size is not a power of 2";
+		return -EINVAL;
+	}
+
+	/* Validate the chunk size against the device block size */
+	if (chunk_size_ulong % (bdev_hardsect_size(store->cow->bdev) >> 9)) {
+		*error = "Chunk size is not a multiple of device blocksize";
+		return -EINVAL;
+	}
+
+	store->chunk_size = chunk_size_ulong;
+	store->chunk_mask = chunk_size_ulong - 1;
+	store->chunk_shift = ffs(chunk_size_ulong) - 1;
+
+	return 0;
+}
+
+int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
+			      unsigned *args_used,
+			      struct dm_exception_store **store)
+{
+	int r = 0;
+	struct dm_exception_store_type *type;
+	struct dm_exception_store *tmp_store;
+	char persistent;
+
+	if (argc < 3) {
+		ti->error = "Insufficient exception store arguments";
+		return -EINVAL;
+	}
+
+	tmp_store = kmalloc(sizeof(*tmp_store), GFP_KERNEL);
+	if (!tmp_store) {
+		ti->error = "Exception store allocation failed";
+		return -ENOMEM;
+	}
+
+	persistent = toupper(*argv[1]);
+	if (persistent != 'P' && persistent != 'N') {
+		ti->error = "Persistent flag is not P or N";
+		return -EINVAL;
+	}
+
+	type = get_type(argv[1]);
+	if (!type) {
+		ti->error = "Exception store type not recognised";
+		r = -EINVAL;
+		goto bad_type;
+	}
+
+	tmp_store->type = type;
+	tmp_store->ti = ti;
+
+	r = dm_get_device(ti, argv[0], 0, 0,
+			  FMODE_READ | FMODE_WRITE, &tmp_store->cow);
+	if (r) {
+		ti->error = "Cannot get COW device";
+		goto bad_cow;
+	}
+
+	r = set_chunk_size(tmp_store, argv[2], &ti->error);
+	if (r)
+		goto bad_cow;
+
+	r = type->ctr(tmp_store, 0, NULL);
+	if (r) {
+		ti->error = "Exception store type constructor failed";
+		goto bad_ctr;
+	}
+
+	*args_used = 3;
+	*store = tmp_store;
+	return 0;
+
+bad_ctr:
+	dm_put_device(ti, tmp_store->cow);
+bad_cow:
+	put_type(type);
+bad_type:
+	kfree(tmp_store);
+	return r;
+}
+EXPORT_SYMBOL(dm_exception_store_create);
+
+void dm_exception_store_destroy(struct dm_exception_store *store)
+{
+	store->type->dtr(store);
+	dm_put_device(store->ti, store->cow);
+	put_type(store->type);
+	kfree(store);
+}
+EXPORT_SYMBOL(dm_exception_store_destroy);
+
 int dm_exception_store_init(void)
 {
 	int r;
diff --git a/drivers/md/dm-exception-store.h b/drivers/md/dm-exception-store.h
index bb9f33d..0a2e6e7 100644
--- a/drivers/md/dm-exception-store.h
+++ b/drivers/md/dm-exception-store.h
@@ -37,11 +37,18 @@
  * Abstraction to handle the meta/layout of exception stores (the
  * COW device).
  */
-struct dm_exception_store {
+struct dm_exception_store;
+struct dm_exception_store_type {
+	const char *name;
+	struct module *module;
+
+	int (*ctr) (struct dm_exception_store *store,
+		    unsigned argc, char **argv);
+
 	/*
 	 * Destroys this object when you've finished with it.
 	 */
-	void (*destroy) (struct dm_exception_store *store);
+	void (*dtr) (struct dm_exception_store *store);
 
 	/*
 	 * The target shouldn't read the COW device until this is
@@ -72,8 +79,9 @@
 	 */
 	void (*drop_snapshot) (struct dm_exception_store *store);
 
-	int (*status) (struct dm_exception_store *store, status_type_t status,
-		       char *result, unsigned int maxlen);
+	unsigned (*status) (struct dm_exception_store *store,
+			    status_type_t status, char *result,
+			    unsigned maxlen);
 
 	/*
 	 * Return how full the snapshot is.
@@ -82,7 +90,21 @@
 			       sector_t *numerator,
 			       sector_t *denominator);
 
-	struct dm_snapshot *snap;
+	/* For internal device-mapper use only. */
+	struct list_head list;
+};
+
+struct dm_exception_store {
+	struct dm_exception_store_type *type;
+	struct dm_target *ti;
+
+	struct dm_dev *cow;
+
+	/* Size of data blocks saved - must be a power of 2 */
+	chunk_t chunk_size;
+	chunk_t chunk_mask;
+	chunk_t chunk_shift;
+
 	void *context;
 };
 
@@ -129,6 +151,28 @@
 
 #  endif
 
+/*
+ * Return the number of sectors in the device.
+ */
+static inline sector_t get_dev_size(struct block_device *bdev)
+{
+	return bdev->bd_inode->i_size >> SECTOR_SHIFT;
+}
+
+static inline chunk_t sector_to_chunk(struct dm_exception_store *store,
+				      sector_t sector)
+{
+	return (sector & ~store->chunk_mask) >> store->chunk_shift;
+}
+
+int dm_exception_store_type_register(struct dm_exception_store_type *type);
+int dm_exception_store_type_unregister(struct dm_exception_store_type *type);
+
+int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
+			      unsigned *args_used,
+			      struct dm_exception_store **store);
+void dm_exception_store_destroy(struct dm_exception_store *store);
+
 int dm_exception_store_init(void);
 void dm_exception_store_exit(void);
 
@@ -141,8 +185,4 @@
 int dm_transient_snapshot_init(void);
 void dm_transient_snapshot_exit(void);
 
-int dm_create_persistent(struct dm_exception_store *store);
-
-int dm_create_transient(struct dm_exception_store *store);
-
 #endif /* _LINUX_DM_EXCEPTION_STORE */
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index 36e2b5e..e73aabd 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -370,16 +370,13 @@
 	while (1) {
 		set_current_state(TASK_UNINTERRUPTIBLE);
 
-		if (!atomic_read(&io.count) || signal_pending(current))
+		if (!atomic_read(&io.count))
 			break;
 
 		io_schedule();
 	}
 	set_current_state(TASK_RUNNING);
 
-	if (atomic_read(&io.count))
-		return -EINTR;
-
 	if (error_bits)
 		*error_bits = io.error_bits;
 
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c
index 737961f..be233bc 100644
--- a/drivers/md/dm-log.c
+++ b/drivers/md/dm-log.c
@@ -16,40 +16,29 @@
 
 #define DM_MSG_PREFIX "dirty region log"
 
-struct dm_dirty_log_internal {
-	struct dm_dirty_log_type *type;
-
-	struct list_head list;
-	long use;
-};
-
 static LIST_HEAD(_log_types);
 static DEFINE_SPINLOCK(_lock);
 
-static struct dm_dirty_log_internal *__find_dirty_log_type(const char *name)
+static struct dm_dirty_log_type *__find_dirty_log_type(const char *name)
 {
-	struct dm_dirty_log_internal *log_type;
+	struct dm_dirty_log_type *log_type;
 
 	list_for_each_entry(log_type, &_log_types, list)
-		if (!strcmp(name, log_type->type->name))
+		if (!strcmp(name, log_type->name))
 			return log_type;
 
 	return NULL;
 }
 
-static struct dm_dirty_log_internal *_get_dirty_log_type(const char *name)
+static struct dm_dirty_log_type *_get_dirty_log_type(const char *name)
 {
-	struct dm_dirty_log_internal *log_type;
+	struct dm_dirty_log_type *log_type;
 
 	spin_lock(&_lock);
 
 	log_type = __find_dirty_log_type(name);
-	if (log_type) {
-		if (!log_type->use && !try_module_get(log_type->type->module))
-			log_type = NULL;
-		else
-			log_type->use++;
-	}
+	if (log_type && !try_module_get(log_type->module))
+		log_type = NULL;
 
 	spin_unlock(&_lock);
 
@@ -76,14 +65,14 @@
 static struct dm_dirty_log_type *get_type(const char *type_name)
 {
 	char *p, *type_name_dup;
-	struct dm_dirty_log_internal *log_type;
+	struct dm_dirty_log_type *log_type;
 
 	if (!type_name)
 		return NULL;
 
 	log_type = _get_dirty_log_type(type_name);
 	if (log_type)
-		return log_type->type;
+		return log_type;
 
 	type_name_dup = kstrdup(type_name, GFP_KERNEL);
 	if (!type_name_dup) {
@@ -105,56 +94,33 @@
 
 	kfree(type_name_dup);
 
-	return log_type ? log_type->type : NULL;
+	return log_type;
 }
 
 static void put_type(struct dm_dirty_log_type *type)
 {
-	struct dm_dirty_log_internal *log_type;
-
 	if (!type)
 		return;
 
 	spin_lock(&_lock);
-	log_type = __find_dirty_log_type(type->name);
-	if (!log_type)
+	if (!__find_dirty_log_type(type->name))
 		goto out;
 
-	if (!--log_type->use)
-		module_put(type->module);
-
-	BUG_ON(log_type->use < 0);
+	module_put(type->module);
 
 out:
 	spin_unlock(&_lock);
 }
 
-static struct dm_dirty_log_internal *_alloc_dirty_log_type(struct dm_dirty_log_type *type)
-{
-	struct dm_dirty_log_internal *log_type = kzalloc(sizeof(*log_type),
-							 GFP_KERNEL);
-
-	if (log_type)
-		log_type->type = type;
-
-	return log_type;
-}
-
 int dm_dirty_log_type_register(struct dm_dirty_log_type *type)
 {
-	struct dm_dirty_log_internal *log_type = _alloc_dirty_log_type(type);
 	int r = 0;
 
-	if (!log_type)
-		return -ENOMEM;
-
 	spin_lock(&_lock);
 	if (!__find_dirty_log_type(type->name))
-		list_add(&log_type->list, &_log_types);
-	else {
-		kfree(log_type);
+		list_add(&type->list, &_log_types);
+	else
 		r = -EEXIST;
-	}
 	spin_unlock(&_lock);
 
 	return r;
@@ -163,25 +129,16 @@
 
 int dm_dirty_log_type_unregister(struct dm_dirty_log_type *type)
 {
-	struct dm_dirty_log_internal *log_type;
-
 	spin_lock(&_lock);
 
-	log_type = __find_dirty_log_type(type->name);
-	if (!log_type) {
+	if (!__find_dirty_log_type(type->name)) {
 		spin_unlock(&_lock);
 		return -EINVAL;
 	}
 
-	if (log_type->use) {
-		spin_unlock(&_lock);
-		return -ETXTBSY;
-	}
-
-	list_del(&log_type->list);
+	list_del(&type->list);
 
 	spin_unlock(&_lock);
-	kfree(log_type);
 
 	return 0;
 }
diff --git a/drivers/md/dm-path-selector.c b/drivers/md/dm-path-selector.c
index 96ea226..42c04f0 100644
--- a/drivers/md/dm-path-selector.c
+++ b/drivers/md/dm-path-selector.c
@@ -17,9 +17,7 @@
 
 struct ps_internal {
 	struct path_selector_type pst;
-
 	struct list_head list;
-	long use;
 };
 
 #define pst_to_psi(__pst) container_of((__pst), struct ps_internal, pst)
@@ -45,12 +43,8 @@
 
 	down_read(&_ps_lock);
 	psi = __find_path_selector_type(name);
-	if (psi) {
-		if ((psi->use == 0) && !try_module_get(psi->pst.module))
-			psi = NULL;
-		else
-			psi->use++;
-	}
+	if (psi && !try_module_get(psi->pst.module))
+		psi = NULL;
 	up_read(&_ps_lock);
 
 	return psi;
@@ -84,11 +78,7 @@
 	if (!psi)
 		goto out;
 
-	if (--psi->use == 0)
-		module_put(psi->pst.module);
-
-	BUG_ON(psi->use < 0);
-
+	module_put(psi->pst.module);
 out:
 	up_read(&_ps_lock);
 }
@@ -136,11 +126,6 @@
 		return -EINVAL;
 	}
 
-	if (psi->use) {
-		up_write(&_ps_lock);
-		return -ETXTBSY;
-	}
-
 	list_del(&psi->list);
 
 	up_write(&_ps_lock);
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 4d6bc10..536ef0b 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -145,6 +145,8 @@
 	struct dm_bio_details details;
 };
 
+static struct kmem_cache *_dm_raid1_read_record_cache;
+
 /*
  * Every mirror should look like this one.
  */
@@ -586,6 +588,9 @@
 	int state;
 	struct bio *bio;
 	struct bio_list sync, nosync, recover, *this_list = NULL;
+	struct bio_list requeue;
+	struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh);
+	region_t region;
 
 	if (!writes->head)
 		return;
@@ -596,10 +601,18 @@
 	bio_list_init(&sync);
 	bio_list_init(&nosync);
 	bio_list_init(&recover);
+	bio_list_init(&requeue);
 
 	while ((bio = bio_list_pop(writes))) {
-		state = dm_rh_get_state(ms->rh,
-					dm_rh_bio_to_region(ms->rh, bio), 1);
+		region = dm_rh_bio_to_region(ms->rh, bio);
+
+		if (log->type->is_remote_recovering &&
+		    log->type->is_remote_recovering(log, region)) {
+			bio_list_add(&requeue, bio);
+			continue;
+		}
+
+		state = dm_rh_get_state(ms->rh, region, 1);
 		switch (state) {
 		case DM_RH_CLEAN:
 		case DM_RH_DIRTY:
@@ -619,6 +632,16 @@
 	}
 
 	/*
+	 * Add bios that are delayed due to remote recovery
+	 * back on to the write queue
+	 */
+	if (unlikely(requeue.head)) {
+		spin_lock_irq(&ms->lock);
+		bio_list_merge(&ms->writes, &requeue);
+		spin_unlock_irq(&ms->lock);
+	}
+
+	/*
 	 * Increment the pending counts for any regions that will
 	 * be written to (writes to recover regions are going to
 	 * be delayed).
@@ -764,9 +787,9 @@
 	atomic_set(&ms->suspend, 0);
 	atomic_set(&ms->default_mirror, DEFAULT_MIRROR);
 
-	len = sizeof(struct dm_raid1_read_record);
-	ms->read_record_pool = mempool_create_kmalloc_pool(MIN_READ_RECORDS,
-							   len);
+	ms->read_record_pool = mempool_create_slab_pool(MIN_READ_RECORDS,
+						_dm_raid1_read_record_cache);
+
 	if (!ms->read_record_pool) {
 		ti->error = "Error creating mirror read_record_pool";
 		kfree(ms);
@@ -1279,16 +1302,31 @@
 {
 	int r;
 
-	r = dm_register_target(&mirror_target);
-	if (r < 0)
-		DMERR("Failed to register mirror target");
+	_dm_raid1_read_record_cache = KMEM_CACHE(dm_raid1_read_record, 0);
+	if (!_dm_raid1_read_record_cache) {
+		DMERR("Can't allocate dm_raid1_read_record cache");
+		r = -ENOMEM;
+		goto bad_cache;
+	}
 
+	r = dm_register_target(&mirror_target);
+	if (r < 0) {
+		DMERR("Failed to register mirror target");
+		goto bad_target;
+	}
+
+	return 0;
+
+bad_target:
+	kmem_cache_destroy(_dm_raid1_read_record_cache);
+bad_cache:
 	return r;
 }
 
 static void __exit dm_mirror_exit(void)
 {
 	dm_unregister_target(&mirror_target);
+	kmem_cache_destroy(_dm_raid1_read_record_cache);
 }
 
 /* Module hooks */
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c
index 936b34e..e75c6dd 100644
--- a/drivers/md/dm-snap-persistent.c
+++ b/drivers/md/dm-snap-persistent.c
@@ -6,7 +6,6 @@
  */
 
 #include "dm-exception-store.h"
-#include "dm-snap.h"
 
 #include <linux/mm.h>
 #include <linux/pagemap.h>
@@ -89,7 +88,7 @@
  * The top level structure for a persistent exception store.
  */
 struct pstore {
-	struct dm_snapshot *snap;	/* up pointer to my snapshot */
+	struct dm_exception_store *store;
 	int version;
 	int valid;
 	uint32_t exceptions_per_area;
@@ -141,7 +140,7 @@
 	int r = -ENOMEM;
 	size_t len;
 
-	len = ps->snap->chunk_size << SECTOR_SHIFT;
+	len = ps->store->chunk_size << SECTOR_SHIFT;
 
 	/*
 	 * Allocate the chunk_size block of memory that will hold
@@ -163,9 +162,12 @@
 
 static void free_area(struct pstore *ps)
 {
-	vfree(ps->area);
+	if (ps->area)
+		vfree(ps->area);
 	ps->area = NULL;
-	vfree(ps->zero_area);
+
+	if (ps->zero_area)
+		vfree(ps->zero_area);
 	ps->zero_area = NULL;
 }
 
@@ -189,9 +191,9 @@
 static int chunk_io(struct pstore *ps, chunk_t chunk, int rw, int metadata)
 {
 	struct dm_io_region where = {
-		.bdev = ps->snap->cow->bdev,
-		.sector = ps->snap->chunk_size * chunk,
-		.count = ps->snap->chunk_size,
+		.bdev = ps->store->cow->bdev,
+		.sector = ps->store->chunk_size * chunk,
+		.count = ps->store->chunk_size,
 	};
 	struct dm_io_request io_req = {
 		.bi_rw = rw,
@@ -247,15 +249,15 @@
 
 static void zero_memory_area(struct pstore *ps)
 {
-	memset(ps->area, 0, ps->snap->chunk_size << SECTOR_SHIFT);
+	memset(ps->area, 0, ps->store->chunk_size << SECTOR_SHIFT);
 }
 
 static int zero_disk_area(struct pstore *ps, chunk_t area)
 {
 	struct dm_io_region where = {
-		.bdev = ps->snap->cow->bdev,
-		.sector = ps->snap->chunk_size * area_location(ps, area),
-		.count = ps->snap->chunk_size,
+		.bdev = ps->store->cow->bdev,
+		.sector = ps->store->chunk_size * area_location(ps, area),
+		.count = ps->store->chunk_size,
 	};
 	struct dm_io_request io_req = {
 		.bi_rw = WRITE,
@@ -278,15 +280,15 @@
 	/*
 	 * Use default chunk size (or hardsect_size, if larger) if none supplied
 	 */
-	if (!ps->snap->chunk_size) {
-		ps->snap->chunk_size = max(DM_CHUNK_SIZE_DEFAULT_SECTORS,
-		    bdev_hardsect_size(ps->snap->cow->bdev) >> 9);
-		ps->snap->chunk_mask = ps->snap->chunk_size - 1;
-		ps->snap->chunk_shift = ffs(ps->snap->chunk_size) - 1;
+	if (!ps->store->chunk_size) {
+		ps->store->chunk_size = max(DM_CHUNK_SIZE_DEFAULT_SECTORS,
+		    bdev_hardsect_size(ps->store->cow->bdev) >> 9);
+		ps->store->chunk_mask = ps->store->chunk_size - 1;
+		ps->store->chunk_shift = ffs(ps->store->chunk_size) - 1;
 		chunk_size_supplied = 0;
 	}
 
-	ps->io_client = dm_io_client_create(sectors_to_pages(ps->snap->
+	ps->io_client = dm_io_client_create(sectors_to_pages(ps->store->
 							     chunk_size));
 	if (IS_ERR(ps->io_client))
 		return PTR_ERR(ps->io_client);
@@ -317,22 +319,22 @@
 	ps->version = le32_to_cpu(dh->version);
 	chunk_size = le32_to_cpu(dh->chunk_size);
 
-	if (!chunk_size_supplied || ps->snap->chunk_size == chunk_size)
+	if (!chunk_size_supplied || ps->store->chunk_size == chunk_size)
 		return 0;
 
 	DMWARN("chunk size %llu in device metadata overrides "
 	       "table chunk size of %llu.",
 	       (unsigned long long)chunk_size,
-	       (unsigned long long)ps->snap->chunk_size);
+	       (unsigned long long)ps->store->chunk_size);
 
 	/* We had a bogus chunk_size. Fix stuff up. */
 	free_area(ps);
 
-	ps->snap->chunk_size = chunk_size;
-	ps->snap->chunk_mask = chunk_size - 1;
-	ps->snap->chunk_shift = ffs(chunk_size) - 1;
+	ps->store->chunk_size = chunk_size;
+	ps->store->chunk_mask = chunk_size - 1;
+	ps->store->chunk_shift = ffs(chunk_size) - 1;
 
-	r = dm_io_client_resize(sectors_to_pages(ps->snap->chunk_size),
+	r = dm_io_client_resize(sectors_to_pages(ps->store->chunk_size),
 				ps->io_client);
 	if (r)
 		return r;
@@ -349,13 +351,13 @@
 {
 	struct disk_header *dh;
 
-	memset(ps->area, 0, ps->snap->chunk_size << SECTOR_SHIFT);
+	memset(ps->area, 0, ps->store->chunk_size << SECTOR_SHIFT);
 
 	dh = (struct disk_header *) ps->area;
 	dh->magic = cpu_to_le32(SNAP_MAGIC);
 	dh->valid = cpu_to_le32(ps->valid);
 	dh->version = cpu_to_le32(ps->version);
-	dh->chunk_size = cpu_to_le32(ps->snap->chunk_size);
+	dh->chunk_size = cpu_to_le32(ps->store->chunk_size);
 
 	return chunk_io(ps, 0, WRITE, 1);
 }
@@ -474,18 +476,25 @@
 static void persistent_fraction_full(struct dm_exception_store *store,
 				     sector_t *numerator, sector_t *denominator)
 {
-	*numerator = get_info(store)->next_free * store->snap->chunk_size;
-	*denominator = get_dev_size(store->snap->cow->bdev);
+	*numerator = get_info(store)->next_free * store->chunk_size;
+	*denominator = get_dev_size(store->cow->bdev);
 }
 
-static void persistent_destroy(struct dm_exception_store *store)
+static void persistent_dtr(struct dm_exception_store *store)
 {
 	struct pstore *ps = get_info(store);
 
 	destroy_workqueue(ps->metadata_wq);
-	dm_io_client_destroy(ps->io_client);
-	vfree(ps->callbacks);
+
+	/* Created in read_header */
+	if (ps->io_client)
+		dm_io_client_destroy(ps->io_client);
 	free_area(ps);
+
+	/* Allocated in persistent_read_metadata */
+	if (ps->callbacks)
+		vfree(ps->callbacks);
+
 	kfree(ps);
 }
 
@@ -507,7 +516,7 @@
 	/*
 	 * Now we know correct chunk_size, complete the initialisation.
 	 */
-	ps->exceptions_per_area = (ps->snap->chunk_size << SECTOR_SHIFT) /
+	ps->exceptions_per_area = (ps->store->chunk_size << SECTOR_SHIFT) /
 				  sizeof(struct disk_exception);
 	ps->callbacks = dm_vcalloc(ps->exceptions_per_area,
 			sizeof(*ps->callbacks));
@@ -564,10 +573,10 @@
 	struct pstore *ps = get_info(store);
 	uint32_t stride;
 	chunk_t next_free;
-	sector_t size = get_dev_size(store->snap->cow->bdev);
+	sector_t size = get_dev_size(store->cow->bdev);
 
 	/* Is there enough room ? */
-	if (size < ((ps->next_free + 1) * store->snap->chunk_size))
+	if (size < ((ps->next_free + 1) * store->chunk_size))
 		return -ENOSPC;
 
 	e->new_chunk = ps->next_free;
@@ -656,16 +665,17 @@
 		DMWARN("write header failed");
 }
 
-int dm_create_persistent(struct dm_exception_store *store)
+static int persistent_ctr(struct dm_exception_store *store,
+			  unsigned argc, char **argv)
 {
 	struct pstore *ps;
 
 	/* allocate the pstore */
-	ps = kmalloc(sizeof(*ps), GFP_KERNEL);
+	ps = kzalloc(sizeof(*ps), GFP_KERNEL);
 	if (!ps)
 		return -ENOMEM;
 
-	ps->snap = store->snap;
+	ps->store = store;
 	ps->valid = 1;
 	ps->version = SNAPSHOT_DISK_VERSION;
 	ps->area = NULL;
@@ -683,22 +693,77 @@
 		return -ENOMEM;
 	}
 
-	store->destroy = persistent_destroy;
-	store->read_metadata = persistent_read_metadata;
-	store->prepare_exception = persistent_prepare_exception;
-	store->commit_exception = persistent_commit_exception;
-	store->drop_snapshot = persistent_drop_snapshot;
-	store->fraction_full = persistent_fraction_full;
 	store->context = ps;
 
 	return 0;
 }
 
+static unsigned persistent_status(struct dm_exception_store *store,
+				  status_type_t status, char *result,
+				  unsigned maxlen)
+{
+	unsigned sz = 0;
+
+	switch (status) {
+	case STATUSTYPE_INFO:
+		break;
+	case STATUSTYPE_TABLE:
+		DMEMIT(" %s P %llu", store->cow->name,
+		       (unsigned long long)store->chunk_size);
+	}
+
+	return sz;
+}
+
+static struct dm_exception_store_type _persistent_type = {
+	.name = "persistent",
+	.module = THIS_MODULE,
+	.ctr = persistent_ctr,
+	.dtr = persistent_dtr,
+	.read_metadata = persistent_read_metadata,
+	.prepare_exception = persistent_prepare_exception,
+	.commit_exception = persistent_commit_exception,
+	.drop_snapshot = persistent_drop_snapshot,
+	.fraction_full = persistent_fraction_full,
+	.status = persistent_status,
+};
+
+static struct dm_exception_store_type _persistent_compat_type = {
+	.name = "P",
+	.module = THIS_MODULE,
+	.ctr = persistent_ctr,
+	.dtr = persistent_dtr,
+	.read_metadata = persistent_read_metadata,
+	.prepare_exception = persistent_prepare_exception,
+	.commit_exception = persistent_commit_exception,
+	.drop_snapshot = persistent_drop_snapshot,
+	.fraction_full = persistent_fraction_full,
+	.status = persistent_status,
+};
+
 int dm_persistent_snapshot_init(void)
 {
-	return 0;
+	int r;
+
+	r = dm_exception_store_type_register(&_persistent_type);
+	if (r) {
+		DMERR("Unable to register persistent exception store type");
+		return r;
+	}
+
+	r = dm_exception_store_type_register(&_persistent_compat_type);
+	if (r) {
+		DMERR("Unable to register old-style persistent exception "
+		      "store type");
+		dm_exception_store_type_unregister(&_persistent_type);
+		return r;
+	}
+
+	return r;
 }
 
 void dm_persistent_snapshot_exit(void)
 {
+	dm_exception_store_type_unregister(&_persistent_type);
+	dm_exception_store_type_unregister(&_persistent_compat_type);
 }
diff --git a/drivers/md/dm-snap-transient.c b/drivers/md/dm-snap-transient.c
index 7f6e2e6..cde5aa5 100644
--- a/drivers/md/dm-snap-transient.c
+++ b/drivers/md/dm-snap-transient.c
@@ -6,7 +6,6 @@
  */
 
 #include "dm-exception-store.h"
-#include "dm-snap.h"
 
 #include <linux/mm.h>
 #include <linux/pagemap.h>
@@ -23,7 +22,7 @@
 	sector_t next_free;
 };
 
-static void transient_destroy(struct dm_exception_store *store)
+static void transient_dtr(struct dm_exception_store *store)
 {
 	kfree(store->context);
 }
@@ -39,14 +38,14 @@
 static int transient_prepare_exception(struct dm_exception_store *store,
 				       struct dm_snap_exception *e)
 {
-	struct transient_c *tc = (struct transient_c *) store->context;
-	sector_t size = get_dev_size(store->snap->cow->bdev);
+	struct transient_c *tc = store->context;
+	sector_t size = get_dev_size(store->cow->bdev);
 
-	if (size < (tc->next_free + store->snap->chunk_size))
+	if (size < (tc->next_free + store->chunk_size))
 		return -1;
 
-	e->new_chunk = sector_to_chunk(store->snap, tc->next_free);
-	tc->next_free += store->snap->chunk_size;
+	e->new_chunk = sector_to_chunk(store, tc->next_free);
+	tc->next_free += store->chunk_size;
 
 	return 0;
 }
@@ -64,20 +63,14 @@
 				    sector_t *numerator, sector_t *denominator)
 {
 	*numerator = ((struct transient_c *) store->context)->next_free;
-	*denominator = get_dev_size(store->snap->cow->bdev);
+	*denominator = get_dev_size(store->cow->bdev);
 }
 
-int dm_create_transient(struct dm_exception_store *store)
+static int transient_ctr(struct dm_exception_store *store,
+			 unsigned argc, char **argv)
 {
 	struct transient_c *tc;
 
-	store->destroy = transient_destroy;
-	store->read_metadata = transient_read_metadata;
-	store->prepare_exception = transient_prepare_exception;
-	store->commit_exception = transient_commit_exception;
-	store->drop_snapshot = NULL;
-	store->fraction_full = transient_fraction_full;
-
 	tc = kmalloc(sizeof(struct transient_c), GFP_KERNEL);
 	if (!tc)
 		return -ENOMEM;
@@ -88,11 +81,70 @@
 	return 0;
 }
 
+static unsigned transient_status(struct dm_exception_store *store,
+				 status_type_t status, char *result,
+				 unsigned maxlen)
+{
+	unsigned sz = 0;
+
+	switch (status) {
+	case STATUSTYPE_INFO:
+		break;
+	case STATUSTYPE_TABLE:
+		DMEMIT(" %s N %llu", store->cow->name,
+		       (unsigned long long)store->chunk_size);
+	}
+
+	return sz;
+}
+
+static struct dm_exception_store_type _transient_type = {
+	.name = "transient",
+	.module = THIS_MODULE,
+	.ctr = transient_ctr,
+	.dtr = transient_dtr,
+	.read_metadata = transient_read_metadata,
+	.prepare_exception = transient_prepare_exception,
+	.commit_exception = transient_commit_exception,
+	.fraction_full = transient_fraction_full,
+	.status = transient_status,
+};
+
+static struct dm_exception_store_type _transient_compat_type = {
+	.name = "N",
+	.module = THIS_MODULE,
+	.ctr = transient_ctr,
+	.dtr = transient_dtr,
+	.read_metadata = transient_read_metadata,
+	.prepare_exception = transient_prepare_exception,
+	.commit_exception = transient_commit_exception,
+	.fraction_full = transient_fraction_full,
+	.status = transient_status,
+};
+
 int dm_transient_snapshot_init(void)
 {
-	return 0;
+	int r;
+
+	r = dm_exception_store_type_register(&_transient_type);
+	if (r) {
+		DMWARN("Unable to register transient exception store type");
+		return r;
+	}
+
+	r = dm_exception_store_type_register(&_transient_compat_type);
+	if (r) {
+		DMWARN("Unable to register old-style transient "
+		       "exception store type");
+		dm_exception_store_type_unregister(&_transient_type);
+		return r;
+	}
+
+	return r;
 }
 
 void dm_transient_snapshot_exit(void)
 {
+	dm_exception_store_type_unregister(&_transient_type);
+	dm_exception_store_type_unregister(&_transient_compat_type);
 }
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 65ff82f..981a041 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -7,7 +7,6 @@
  */
 
 #include <linux/blkdev.h>
-#include <linux/ctype.h>
 #include <linux/device-mapper.h>
 #include <linux/delay.h>
 #include <linux/fs.h>
@@ -20,9 +19,9 @@
 #include <linux/vmalloc.h>
 #include <linux/log2.h>
 #include <linux/dm-kcopyd.h>
+#include <linux/workqueue.h>
 
 #include "dm-exception-store.h"
-#include "dm-snap.h"
 #include "dm-bio-list.h"
 
 #define DM_MSG_PREFIX "snapshots"
@@ -47,9 +46,76 @@
  */
 #define MIN_IOS 256
 
+#define DM_TRACKED_CHUNK_HASH_SIZE	16
+#define DM_TRACKED_CHUNK_HASH(x)	((unsigned long)(x) & \
+					 (DM_TRACKED_CHUNK_HASH_SIZE - 1))
+
+struct exception_table {
+	uint32_t hash_mask;
+	unsigned hash_shift;
+	struct list_head *table;
+};
+
+struct dm_snapshot {
+	struct rw_semaphore lock;
+
+	struct dm_dev *origin;
+
+	/* List of snapshots per Origin */
+	struct list_head list;
+
+	/* You can't use a snapshot if this is 0 (e.g. if full) */
+	int valid;
+
+	/* Origin writes don't trigger exceptions until this is set */
+	int active;
+
+	mempool_t *pending_pool;
+
+	atomic_t pending_exceptions_count;
+
+	struct exception_table pending;
+	struct exception_table complete;
+
+	/*
+	 * pe_lock protects all pending_exception operations and access
+	 * as well as the snapshot_bios list.
+	 */
+	spinlock_t pe_lock;
+
+	/* The on disk metadata handler */
+	struct dm_exception_store *store;
+
+	struct dm_kcopyd_client *kcopyd_client;
+
+	/* Queue of snapshot writes for ksnapd to flush */
+	struct bio_list queued_bios;
+	struct work_struct queued_bios_work;
+
+	/* Chunks with outstanding reads */
+	mempool_t *tracked_chunk_pool;
+	spinlock_t tracked_chunk_lock;
+	struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE];
+};
+
 static struct workqueue_struct *ksnapd;
 static void flush_queued_bios(struct work_struct *work);
 
+static sector_t chunk_to_sector(struct dm_exception_store *store,
+				chunk_t chunk)
+{
+	return chunk << store->chunk_shift;
+}
+
+static int bdev_equal(struct block_device *lhs, struct block_device *rhs)
+{
+	/*
+	 * There is only ever one instance of a particular block
+	 * device so we can compare pointers safely.
+	 */
+	return lhs == rhs;
+}
+
 struct dm_snap_pending_exception {
 	struct dm_snap_exception e;
 
@@ -476,11 +542,11 @@
 	 * Calculate based on the size of the original volume or
 	 * the COW volume...
 	 */
-	cow_dev_size = get_dev_size(s->cow->bdev);
+	cow_dev_size = get_dev_size(s->store->cow->bdev);
 	origin_dev_size = get_dev_size(s->origin->bdev);
 	max_buckets = calc_max_buckets();
 
-	hash_size = min(origin_dev_size, cow_dev_size) >> s->chunk_shift;
+	hash_size = min(origin_dev_size, cow_dev_size) >> s->store->chunk_shift;
 	hash_size = min(hash_size, max_buckets);
 
 	hash_size = rounddown_pow_of_two(hash_size);
@@ -505,58 +571,6 @@
 }
 
 /*
- * Round a number up to the nearest 'size' boundary.  size must
- * be a power of 2.
- */
-static ulong round_up(ulong n, ulong size)
-{
-	size--;
-	return (n + size) & ~size;
-}
-
-static int set_chunk_size(struct dm_snapshot *s, const char *chunk_size_arg,
-			  char **error)
-{
-	unsigned long chunk_size;
-	char *value;
-
-	chunk_size = simple_strtoul(chunk_size_arg, &value, 10);
-	if (*chunk_size_arg == '\0' || *value != '\0') {
-		*error = "Invalid chunk size";
-		return -EINVAL;
-	}
-
-	if (!chunk_size) {
-		s->chunk_size = s->chunk_mask = s->chunk_shift = 0;
-		return 0;
-	}
-
-	/*
-	 * Chunk size must be multiple of page size.  Silently
-	 * round up if it's not.
-	 */
-	chunk_size = round_up(chunk_size, PAGE_SIZE >> 9);
-
-	/* Check chunk_size is a power of 2 */
-	if (!is_power_of_2(chunk_size)) {
-		*error = "Chunk size is not a power of 2";
-		return -EINVAL;
-	}
-
-	/* Validate the chunk size against the device block size */
-	if (chunk_size % (bdev_hardsect_size(s->cow->bdev) >> 9)) {
-		*error = "Chunk size is not a multiple of device blocksize";
-		return -EINVAL;
-	}
-
-	s->chunk_size = chunk_size;
-	s->chunk_mask = chunk_size - 1;
-	s->chunk_shift = ffs(chunk_size) - 1;
-
-	return 0;
-}
-
-/*
  * Construct a snapshot mapping: <origin_dev> <COW-dev> <p/n> <chunk-size>
  */
 static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
@@ -564,91 +578,68 @@
 	struct dm_snapshot *s;
 	int i;
 	int r = -EINVAL;
-	char persistent;
 	char *origin_path;
-	char *cow_path;
+	struct dm_exception_store *store;
+	unsigned args_used;
 
 	if (argc != 4) {
 		ti->error = "requires exactly 4 arguments";
 		r = -EINVAL;
-		goto bad1;
+		goto bad_args;
 	}
 
 	origin_path = argv[0];
-	cow_path = argv[1];
-	persistent = toupper(*argv[2]);
+	argv++;
+	argc--;
 
-	if (persistent != 'P' && persistent != 'N') {
-		ti->error = "Persistent flag is not P or N";
+	r = dm_exception_store_create(ti, argc, argv, &args_used, &store);
+	if (r) {
+		ti->error = "Couldn't create exception store";
 		r = -EINVAL;
-		goto bad1;
+		goto bad_args;
 	}
 
+	argv += args_used;
+	argc -= args_used;
+
 	s = kmalloc(sizeof(*s), GFP_KERNEL);
-	if (s == NULL) {
+	if (!s) {
 		ti->error = "Cannot allocate snapshot context private "
 		    "structure";
 		r = -ENOMEM;
-		goto bad1;
+		goto bad_snap;
 	}
 
 	r = dm_get_device(ti, origin_path, 0, ti->len, FMODE_READ, &s->origin);
 	if (r) {
 		ti->error = "Cannot get origin device";
-		goto bad2;
+		goto bad_origin;
 	}
 
-	r = dm_get_device(ti, cow_path, 0, 0,
-			  FMODE_READ | FMODE_WRITE, &s->cow);
-	if (r) {
-		dm_put_device(ti, s->origin);
-		ti->error = "Cannot get COW device";
-		goto bad2;
-	}
-
-	r = set_chunk_size(s, argv[3], &ti->error);
-	if (r)
-		goto bad3;
-
-	s->type = persistent;
-
+	s->store = store;
 	s->valid = 1;
 	s->active = 0;
 	atomic_set(&s->pending_exceptions_count, 0);
 	init_rwsem(&s->lock);
 	spin_lock_init(&s->pe_lock);
-	s->ti = ti;
 
 	/* Allocate hash table for COW data */
 	if (init_hash_tables(s)) {
 		ti->error = "Unable to allocate hash table space";
 		r = -ENOMEM;
-		goto bad3;
-	}
-
-	s->store.snap = s;
-
-	if (persistent == 'P')
-		r = dm_create_persistent(&s->store);
-	else
-		r = dm_create_transient(&s->store);
-
-	if (r) {
-		ti->error = "Couldn't create exception store";
-		r = -EINVAL;
-		goto bad4;
+		goto bad_hash_tables;
 	}
 
 	r = dm_kcopyd_client_create(SNAPSHOT_PAGES, &s->kcopyd_client);
 	if (r) {
 		ti->error = "Could not create kcopyd client";
-		goto bad5;
+		goto bad_kcopyd;
 	}
 
 	s->pending_pool = mempool_create_slab_pool(MIN_IOS, pending_cache);
 	if (!s->pending_pool) {
 		ti->error = "Could not allocate mempool for pending exceptions";
-		goto bad6;
+		goto bad_pending_pool;
 	}
 
 	s->tracked_chunk_pool = mempool_create_slab_pool(MIN_IOS,
@@ -665,7 +656,8 @@
 	spin_lock_init(&s->tracked_chunk_lock);
 
 	/* Metadata must only be loaded into one table at once */
-	r = s->store.read_metadata(&s->store, dm_add_exception, (void *)s);
+	r = s->store->type->read_metadata(s->store, dm_add_exception,
+					  (void *)s);
 	if (r < 0) {
 		ti->error = "Failed to read snapshot metadata";
 		goto bad_load_and_register;
@@ -686,34 +678,33 @@
 	}
 
 	ti->private = s;
-	ti->split_io = s->chunk_size;
+	ti->split_io = s->store->chunk_size;
 
 	return 0;
 
- bad_load_and_register:
+bad_load_and_register:
 	mempool_destroy(s->tracked_chunk_pool);
 
- bad_tracked_chunk_pool:
+bad_tracked_chunk_pool:
 	mempool_destroy(s->pending_pool);
 
- bad6:
+bad_pending_pool:
 	dm_kcopyd_client_destroy(s->kcopyd_client);
 
- bad5:
-	s->store.destroy(&s->store);
-
- bad4:
+bad_kcopyd:
 	exit_exception_table(&s->pending, pending_cache);
 	exit_exception_table(&s->complete, exception_cache);
 
- bad3:
-	dm_put_device(ti, s->cow);
+bad_hash_tables:
 	dm_put_device(ti, s->origin);
 
- bad2:
+bad_origin:
 	kfree(s);
 
- bad1:
+bad_snap:
+	dm_exception_store_destroy(store);
+
+bad_args:
 	return r;
 }
 
@@ -724,8 +715,6 @@
 
 	exit_exception_table(&s->pending, pending_cache);
 	exit_exception_table(&s->complete, exception_cache);
-
-	s->store.destroy(&s->store);
 }
 
 static void snapshot_dtr(struct dm_target *ti)
@@ -761,7 +750,8 @@
 	mempool_destroy(s->pending_pool);
 
 	dm_put_device(ti, s->origin);
-	dm_put_device(ti, s->cow);
+
+	dm_exception_store_destroy(s->store);
 
 	kfree(s);
 }
@@ -820,12 +810,12 @@
 	else if (err == -ENOMEM)
 		DMERR("Invalidating snapshot: Unable to allocate exception.");
 
-	if (s->store.drop_snapshot)
-		s->store.drop_snapshot(&s->store);
+	if (s->store->type->drop_snapshot)
+		s->store->type->drop_snapshot(s->store);
 
 	s->valid = 0;
 
-	dm_table_event(s->ti->table);
+	dm_table_event(s->store->ti->table);
 }
 
 static void get_pending_exception(struct dm_snap_pending_exception *pe)
@@ -943,8 +933,8 @@
 
 	else
 		/* Update the metadata if we are persistent */
-		s->store.commit_exception(&s->store, &pe->e, commit_callback,
-					  pe);
+		s->store->type->commit_exception(s->store, &pe->e,
+						 commit_callback, pe);
 }
 
 /*
@@ -960,11 +950,11 @@
 	dev_size = get_dev_size(bdev);
 
 	src.bdev = bdev;
-	src.sector = chunk_to_sector(s, pe->e.old_chunk);
-	src.count = min(s->chunk_size, dev_size - src.sector);
+	src.sector = chunk_to_sector(s->store, pe->e.old_chunk);
+	src.count = min(s->store->chunk_size, dev_size - src.sector);
 
-	dest.bdev = s->cow->bdev;
-	dest.sector = chunk_to_sector(s, pe->e.new_chunk);
+	dest.bdev = s->store->cow->bdev;
+	dest.sector = chunk_to_sector(s->store, pe->e.new_chunk);
 	dest.count = src.count;
 
 	/* Hand over to kcopyd */
@@ -972,6 +962,17 @@
 		    &src, 1, &dest, 0, copy_callback, pe);
 }
 
+static struct dm_snap_pending_exception *
+__lookup_pending_exception(struct dm_snapshot *s, chunk_t chunk)
+{
+	struct dm_snap_exception *e = lookup_exception(&s->pending, chunk);
+
+	if (!e)
+		return NULL;
+
+	return container_of(e, struct dm_snap_pending_exception, e);
+}
+
 /*
  * Looks to see if this snapshot already has a pending exception
  * for this chunk, otherwise it allocates a new one and inserts
@@ -981,40 +982,15 @@
  * this.
  */
 static struct dm_snap_pending_exception *
-__find_pending_exception(struct dm_snapshot *s, struct bio *bio)
+__find_pending_exception(struct dm_snapshot *s,
+			 struct dm_snap_pending_exception *pe, chunk_t chunk)
 {
-	struct dm_snap_exception *e;
-	struct dm_snap_pending_exception *pe;
-	chunk_t chunk = sector_to_chunk(s, bio->bi_sector);
+	struct dm_snap_pending_exception *pe2;
 
-	/*
-	 * Is there a pending exception for this already ?
-	 */
-	e = lookup_exception(&s->pending, chunk);
-	if (e) {
-		/* cast the exception to a pending exception */
-		pe = container_of(e, struct dm_snap_pending_exception, e);
-		goto out;
-	}
-
-	/*
-	 * Create a new pending exception, we don't want
-	 * to hold the lock while we do this.
-	 */
-	up_write(&s->lock);
-	pe = alloc_pending_exception(s);
-	down_write(&s->lock);
-
-	if (!s->valid) {
+	pe2 = __lookup_pending_exception(s, chunk);
+	if (pe2) {
 		free_pending_exception(pe);
-		return NULL;
-	}
-
-	e = lookup_exception(&s->pending, chunk);
-	if (e) {
-		free_pending_exception(pe);
-		pe = container_of(e, struct dm_snap_pending_exception, e);
-		goto out;
+		return pe2;
 	}
 
 	pe->e.old_chunk = chunk;
@@ -1024,7 +1000,7 @@
 	atomic_set(&pe->ref_count, 0);
 	pe->started = 0;
 
-	if (s->store.prepare_exception(&s->store, &pe->e)) {
+	if (s->store->type->prepare_exception(s->store, &pe->e)) {
 		free_pending_exception(pe);
 		return NULL;
 	}
@@ -1032,17 +1008,18 @@
 	get_pending_exception(pe);
 	insert_exception(&s->pending, &pe->e);
 
- out:
 	return pe;
 }
 
 static void remap_exception(struct dm_snapshot *s, struct dm_snap_exception *e,
 			    struct bio *bio, chunk_t chunk)
 {
-	bio->bi_bdev = s->cow->bdev;
-	bio->bi_sector = chunk_to_sector(s, dm_chunk_number(e->new_chunk) +
-			 (chunk - e->old_chunk)) +
-			 (bio->bi_sector & s->chunk_mask);
+	bio->bi_bdev = s->store->cow->bdev;
+	bio->bi_sector = chunk_to_sector(s->store,
+					 dm_chunk_number(e->new_chunk) +
+					 (chunk - e->old_chunk)) +
+					 (bio->bi_sector &
+					  s->store->chunk_mask);
 }
 
 static int snapshot_map(struct dm_target *ti, struct bio *bio,
@@ -1054,7 +1031,7 @@
 	chunk_t chunk;
 	struct dm_snap_pending_exception *pe = NULL;
 
-	chunk = sector_to_chunk(s, bio->bi_sector);
+	chunk = sector_to_chunk(s->store, bio->bi_sector);
 
 	/* Full snapshots are not usable */
 	/* To get here the table must be live so s->active is always set. */
@@ -1083,11 +1060,31 @@
 	 * writeable.
 	 */
 	if (bio_rw(bio) == WRITE) {
-		pe = __find_pending_exception(s, bio);
+		pe = __lookup_pending_exception(s, chunk);
 		if (!pe) {
-			__invalidate_snapshot(s, -ENOMEM);
-			r = -EIO;
-			goto out_unlock;
+			up_write(&s->lock);
+			pe = alloc_pending_exception(s);
+			down_write(&s->lock);
+
+			if (!s->valid) {
+				free_pending_exception(pe);
+				r = -EIO;
+				goto out_unlock;
+			}
+
+			e = lookup_exception(&s->complete, chunk);
+			if (e) {
+				free_pending_exception(pe);
+				remap_exception(s, e, bio, chunk);
+				goto out_unlock;
+			}
+
+			pe = __find_pending_exception(s, pe, chunk);
+			if (!pe) {
+				__invalidate_snapshot(s, -ENOMEM);
+				r = -EIO;
+				goto out_unlock;
+			}
 		}
 
 		remap_exception(s, &pe->e, bio, chunk);
@@ -1137,24 +1134,25 @@
 static int snapshot_status(struct dm_target *ti, status_type_t type,
 			   char *result, unsigned int maxlen)
 {
+	unsigned sz = 0;
 	struct dm_snapshot *snap = ti->private;
 
 	switch (type) {
 	case STATUSTYPE_INFO:
 		if (!snap->valid)
-			snprintf(result, maxlen, "Invalid");
+			DMEMIT("Invalid");
 		else {
-			if (snap->store.fraction_full) {
+			if (snap->store->type->fraction_full) {
 				sector_t numerator, denominator;
-				snap->store.fraction_full(&snap->store,
-							  &numerator,
-							  &denominator);
-				snprintf(result, maxlen, "%llu/%llu",
-					(unsigned long long)numerator,
-					(unsigned long long)denominator);
+				snap->store->type->fraction_full(snap->store,
+								 &numerator,
+								 &denominator);
+				DMEMIT("%llu/%llu",
+				       (unsigned long long)numerator,
+				       (unsigned long long)denominator);
 			}
 			else
-				snprintf(result, maxlen, "Unknown");
+				DMEMIT("Unknown");
 		}
 		break;
 
@@ -1164,10 +1162,9 @@
 		 * to make private copies if the output is to
 		 * make sense.
 		 */
-		snprintf(result, maxlen, "%s %s %c %llu",
-			 snap->origin->name, snap->cow->name,
-			 snap->type,
-			 (unsigned long long)snap->chunk_size);
+		DMEMIT("%s", snap->origin->name);
+		snap->store->type->status(snap->store, type, result + sz,
+					  maxlen - sz);
 		break;
 	}
 
@@ -1196,14 +1193,14 @@
 			goto next_snapshot;
 
 		/* Nothing to do if writing beyond end of snapshot */
-		if (bio->bi_sector >= dm_table_get_size(snap->ti->table))
+		if (bio->bi_sector >= dm_table_get_size(snap->store->ti->table))
 			goto next_snapshot;
 
 		/*
 		 * Remember, different snapshots can have
 		 * different chunk sizes.
 		 */
-		chunk = sector_to_chunk(snap, bio->bi_sector);
+		chunk = sector_to_chunk(snap->store, bio->bi_sector);
 
 		/*
 		 * Check exception table to see if block
@@ -1217,10 +1214,28 @@
 		if (e)
 			goto next_snapshot;
 
-		pe = __find_pending_exception(snap, bio);
+		pe = __lookup_pending_exception(snap, chunk);
 		if (!pe) {
-			__invalidate_snapshot(snap, -ENOMEM);
-			goto next_snapshot;
+			up_write(&snap->lock);
+			pe = alloc_pending_exception(snap);
+			down_write(&snap->lock);
+
+			if (!snap->valid) {
+				free_pending_exception(pe);
+				goto next_snapshot;
+			}
+
+			e = lookup_exception(&snap->complete, chunk);
+			if (e) {
+				free_pending_exception(pe);
+				goto next_snapshot;
+			}
+
+			pe = __find_pending_exception(snap, pe, chunk);
+			if (!pe) {
+				__invalidate_snapshot(snap, -ENOMEM);
+				goto next_snapshot;
+			}
 		}
 
 		if (!primary_pe) {
@@ -1360,7 +1375,8 @@
 	o = __lookup_origin(dev->bdev);
 	if (o)
 		list_for_each_entry (snap, &o->snapshots, list)
-			chunk_size = min_not_zero(chunk_size, snap->chunk_size);
+			chunk_size = min_not_zero(chunk_size,
+						  snap->store->chunk_size);
 	up_read(&_origins_lock);
 
 	ti->split_io = chunk_size;
diff --git a/drivers/md/dm-snap.h b/drivers/md/dm-snap.h
deleted file mode 100644
index d9e62b4..0000000
--- a/drivers/md/dm-snap.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2001-2002 Sistina Software (UK) Limited.
- *
- * This file is released under the GPL.
- */
-
-#ifndef DM_SNAPSHOT_H
-#define DM_SNAPSHOT_H
-
-#include <linux/device-mapper.h>
-#include "dm-exception-store.h"
-#include "dm-bio-list.h"
-#include <linux/blkdev.h>
-#include <linux/workqueue.h>
-
-struct exception_table {
-	uint32_t hash_mask;
-	unsigned hash_shift;
-	struct list_head *table;
-};
-
-#define DM_TRACKED_CHUNK_HASH_SIZE	16
-#define DM_TRACKED_CHUNK_HASH(x)	((unsigned long)(x) & \
-					 (DM_TRACKED_CHUNK_HASH_SIZE - 1))
-
-struct dm_snapshot {
-	struct rw_semaphore lock;
-	struct dm_target *ti;
-
-	struct dm_dev *origin;
-	struct dm_dev *cow;
-
-	/* List of snapshots per Origin */
-	struct list_head list;
-
-	/* Size of data blocks saved - must be a power of 2 */
-	chunk_t chunk_size;
-	chunk_t chunk_mask;
-	chunk_t chunk_shift;
-
-	/* You can't use a snapshot if this is 0 (e.g. if full) */
-	int valid;
-
-	/* Origin writes don't trigger exceptions until this is set */
-	int active;
-
-	/* Used for display of table */
-	char type;
-
-	mempool_t *pending_pool;
-
-	atomic_t pending_exceptions_count;
-
-	struct exception_table pending;
-	struct exception_table complete;
-
-	/*
-	 * pe_lock protects all pending_exception operations and access
-	 * as well as the snapshot_bios list.
-	 */
-	spinlock_t pe_lock;
-
-	/* The on disk metadata handler */
-	struct dm_exception_store store;
-
-	struct dm_kcopyd_client *kcopyd_client;
-
-	/* Queue of snapshot writes for ksnapd to flush */
-	struct bio_list queued_bios;
-	struct work_struct queued_bios_work;
-
-	/* Chunks with outstanding reads */
-	mempool_t *tracked_chunk_pool;
-	spinlock_t tracked_chunk_lock;
-	struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE];
-};
-
-/*
- * Return the number of sectors in the device.
- */
-static inline sector_t get_dev_size(struct block_device *bdev)
-{
-	return bdev->bd_inode->i_size >> SECTOR_SHIFT;
-}
-
-static inline chunk_t sector_to_chunk(struct dm_snapshot *s, sector_t sector)
-{
-	return (sector & ~s->chunk_mask) >> s->chunk_shift;
-}
-
-static inline sector_t chunk_to_sector(struct dm_snapshot *s, chunk_t chunk)
-{
-	return chunk << s->chunk_shift;
-}
-
-static inline int bdev_equal(struct block_device *lhs, struct block_device *rhs)
-{
-	/*
-	 * There is only ever one instance of a particular block
-	 * device so we can compare pointers safely.
-	 */
-	return lhs == rhs;
-}
-
-#endif
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 2fd66c3..e8361b1 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -399,28 +399,30 @@
 }
 
 /*
- * This upgrades the mode on an already open dm_dev.  Being
+ * This upgrades the mode on an already open dm_dev, being
  * careful to leave things as they were if we fail to reopen the
- * device.
+ * device and not to touch the existing bdev field in case
+ * it is accessed concurrently inside dm_table_any_congested().
  */
 static int upgrade_mode(struct dm_dev_internal *dd, fmode_t new_mode,
 			struct mapped_device *md)
 {
 	int r;
-	struct dm_dev_internal dd_copy;
-	dev_t dev = dd->dm_dev.bdev->bd_dev;
+	struct dm_dev_internal dd_new, dd_old;
 
-	dd_copy = *dd;
+	dd_new = dd_old = *dd;
+
+	dd_new.dm_dev.mode |= new_mode;
+	dd_new.dm_dev.bdev = NULL;
+
+	r = open_dev(&dd_new, dd->dm_dev.bdev->bd_dev, md);
+	if (r)
+		return r;
 
 	dd->dm_dev.mode |= new_mode;
-	dd->dm_dev.bdev = NULL;
-	r = open_dev(dd, dev, md);
-	if (!r)
-		close_dev(&dd_copy, md);
-	else
-		*dd = dd_copy;
+	close_dev(&dd_old, md);
 
-	return r;
+	return 0;
 }
 
 /*
diff --git a/drivers/md/dm-target.c b/drivers/md/dm-target.c
index 7decf10..04feccf 100644
--- a/drivers/md/dm-target.c
+++ b/drivers/md/dm-target.c
@@ -14,45 +14,34 @@
 
 #define DM_MSG_PREFIX "target"
 
-struct tt_internal {
-	struct target_type tt;
-
-	struct list_head list;
-	long use;
-};
-
 static LIST_HEAD(_targets);
 static DECLARE_RWSEM(_lock);
 
 #define DM_MOD_NAME_SIZE 32
 
-static inline struct tt_internal *__find_target_type(const char *name)
+static inline struct target_type *__find_target_type(const char *name)
 {
-	struct tt_internal *ti;
+	struct target_type *tt;
 
-	list_for_each_entry (ti, &_targets, list)
-		if (!strcmp(name, ti->tt.name))
-			return ti;
+	list_for_each_entry(tt, &_targets, list)
+		if (!strcmp(name, tt->name))
+			return tt;
 
 	return NULL;
 }
 
-static struct tt_internal *get_target_type(const char *name)
+static struct target_type *get_target_type(const char *name)
 {
-	struct tt_internal *ti;
+	struct target_type *tt;
 
 	down_read(&_lock);
 
-	ti = __find_target_type(name);
-	if (ti) {
-		if ((ti->use == 0) && !try_module_get(ti->tt.module))
-			ti = NULL;
-		else
-			ti->use++;
-	}
+	tt = __find_target_type(name);
+	if (tt && !try_module_get(tt->module))
+		tt = NULL;
 
 	up_read(&_lock);
-	return ti;
+	return tt;
 }
 
 static void load_module(const char *name)
@@ -62,92 +51,59 @@
 
 struct target_type *dm_get_target_type(const char *name)
 {
-	struct tt_internal *ti = get_target_type(name);
+	struct target_type *tt = get_target_type(name);
 
-	if (!ti) {
+	if (!tt) {
 		load_module(name);
-		ti = get_target_type(name);
+		tt = get_target_type(name);
 	}
 
-	return ti ? &ti->tt : NULL;
+	return tt;
 }
 
-void dm_put_target_type(struct target_type *t)
+void dm_put_target_type(struct target_type *tt)
 {
-	struct tt_internal *ti = (struct tt_internal *) t;
-
 	down_read(&_lock);
-	if (--ti->use == 0)
-		module_put(ti->tt.module);
-
-	BUG_ON(ti->use < 0);
+	module_put(tt->module);
 	up_read(&_lock);
-
-	return;
 }
 
-static struct tt_internal *alloc_target(struct target_type *t)
-{
-	struct tt_internal *ti = kzalloc(sizeof(*ti), GFP_KERNEL);
-
-	if (ti)
-		ti->tt = *t;
-
-	return ti;
-}
-
-
 int dm_target_iterate(void (*iter_func)(struct target_type *tt,
 					void *param), void *param)
 {
-	struct tt_internal *ti;
+	struct target_type *tt;
 
 	down_read(&_lock);
-	list_for_each_entry (ti, &_targets, list)
-		iter_func(&ti->tt, param);
+	list_for_each_entry(tt, &_targets, list)
+		iter_func(tt, param);
 	up_read(&_lock);
 
 	return 0;
 }
 
-int dm_register_target(struct target_type *t)
+int dm_register_target(struct target_type *tt)
 {
 	int rv = 0;
-	struct tt_internal *ti = alloc_target(t);
-
-	if (!ti)
-		return -ENOMEM;
 
 	down_write(&_lock);
-	if (__find_target_type(t->name))
+	if (__find_target_type(tt->name))
 		rv = -EEXIST;
 	else
-		list_add(&ti->list, &_targets);
+		list_add(&tt->list, &_targets);
 
 	up_write(&_lock);
-	if (rv)
-		kfree(ti);
 	return rv;
 }
 
-void dm_unregister_target(struct target_type *t)
+void dm_unregister_target(struct target_type *tt)
 {
-	struct tt_internal *ti;
-
 	down_write(&_lock);
-	if (!(ti = __find_target_type(t->name))) {
-		DMCRIT("Unregistering unrecognised target: %s", t->name);
+	if (!__find_target_type(tt->name)) {
+		DMCRIT("Unregistering unrecognised target: %s", tt->name);
 		BUG();
 	}
 
-	if (ti->use) {
-		DMCRIT("Attempt to unregister target still in use: %s",
-		       t->name);
-		BUG();
-	}
-
-	list_del(&ti->list);
-	kfree(ti);
+	list_del(&tt->list);
 
 	up_write(&_lock);
 }
@@ -156,17 +112,17 @@
  * io-err: always fails an io, useful for bringing
  * up LVs that have holes in them.
  */
-static int io_err_ctr(struct dm_target *ti, unsigned int argc, char **args)
+static int io_err_ctr(struct dm_target *tt, unsigned int argc, char **args)
 {
 	return 0;
 }
 
-static void io_err_dtr(struct dm_target *ti)
+static void io_err_dtr(struct dm_target *tt)
 {
 	/* empty */
 }
 
-static int io_err_map(struct dm_target *ti, struct bio *bio,
+static int io_err_map(struct dm_target *tt, struct bio *bio,
 		      union map_info *map_context)
 {
 	return -EIO;
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 8d40f27..788ba96 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -99,19 +99,9 @@
 /*
  * Work processed by per-device workqueue.
  */
-struct dm_wq_req {
-	enum {
-		DM_WQ_FLUSH_DEFERRED,
-	} type;
-	struct work_struct work;
-	struct mapped_device *md;
-	void *context;
-};
-
 struct mapped_device {
 	struct rw_semaphore io_lock;
 	struct mutex suspend_lock;
-	spinlock_t pushback_lock;
 	rwlock_t map_lock;
 	atomic_t holders;
 	atomic_t open_count;
@@ -129,8 +119,9 @@
 	 */
 	atomic_t pending;
 	wait_queue_head_t wait;
+	struct work_struct work;
 	struct bio_list deferred;
-	struct bio_list pushback;
+	spinlock_t deferred_lock;
 
 	/*
 	 * Processing queue (flush/barriers)
@@ -453,7 +444,9 @@
 		return 1;
 	}
 
+	spin_lock_irq(&md->deferred_lock);
 	bio_list_add(&md->deferred, bio);
+	spin_unlock_irq(&md->deferred_lock);
 
 	up_write(&md->io_lock);
 	return 0;		/* deferred successfully */
@@ -537,16 +530,14 @@
 		if (io->error == DM_ENDIO_REQUEUE) {
 			/*
 			 * Target requested pushing back the I/O.
-			 * This must be handled before the sleeper on
-			 * suspend queue merges the pushback list.
 			 */
-			spin_lock_irqsave(&md->pushback_lock, flags);
+			spin_lock_irqsave(&md->deferred_lock, flags);
 			if (__noflush_suspending(md))
-				bio_list_add(&md->pushback, io->bio);
+				bio_list_add(&md->deferred, io->bio);
 			else
 				/* noflush suspend was interrupted. */
 				io->error = -EIO;
-			spin_unlock_irqrestore(&md->pushback_lock, flags);
+			spin_unlock_irqrestore(&md->deferred_lock, flags);
 		}
 
 		end_io_acct(io);
@@ -834,20 +825,22 @@
 }
 
 /*
- * Split the bio into several clones.
+ * Split the bio into several clones and submit it to targets.
  */
-static int __split_bio(struct mapped_device *md, struct bio *bio)
+static void __split_and_process_bio(struct mapped_device *md, struct bio *bio)
 {
 	struct clone_info ci;
 	int error = 0;
 
 	ci.map = dm_get_table(md);
-	if (unlikely(!ci.map))
-		return -EIO;
+	if (unlikely(!ci.map)) {
+		bio_io_error(bio);
+		return;
+	}
 	if (unlikely(bio_barrier(bio) && !dm_table_barrier_ok(ci.map))) {
 		dm_table_put(ci.map);
 		bio_endio(bio, -EOPNOTSUPP);
-		return 0;
+		return;
 	}
 	ci.md = md;
 	ci.bio = bio;
@@ -867,8 +860,6 @@
 	/* drop the extra reference count */
 	dec_pending(ci.io, error);
 	dm_table_put(ci.map);
-
-	return 0;
 }
 /*-----------------------------------------------------------------
  * CRUD END
@@ -959,8 +950,9 @@
 		down_read(&md->io_lock);
 	}
 
-	r = __split_bio(md, bio);
+	__split_and_process_bio(md, bio);
 	up_read(&md->io_lock);
+	return 0;
 
 out_req:
 	if (r < 0)
@@ -1074,6 +1066,8 @@
 
 static struct block_device_operations dm_blk_dops;
 
+static void dm_wq_work(struct work_struct *work);
+
 /*
  * Allocate and initialise a blank device with a given minor.
  */
@@ -1101,7 +1095,7 @@
 
 	init_rwsem(&md->io_lock);
 	mutex_init(&md->suspend_lock);
-	spin_lock_init(&md->pushback_lock);
+	spin_lock_init(&md->deferred_lock);
 	rwlock_init(&md->map_lock);
 	atomic_set(&md->holders, 1);
 	atomic_set(&md->open_count, 0);
@@ -1118,6 +1112,7 @@
 	md->queue->backing_dev_info.congested_fn = dm_any_congested;
 	md->queue->backing_dev_info.congested_data = md;
 	blk_queue_make_request(md->queue, dm_request);
+	blk_queue_ordered(md->queue, QUEUE_ORDERED_DRAIN, NULL);
 	blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY);
 	md->queue->unplug_fn = dm_unplug_all;
 	blk_queue_merge_bvec(md->queue, dm_merge_bvec);
@@ -1140,6 +1135,7 @@
 
 	atomic_set(&md->pending, 0);
 	init_waitqueue_head(&md->wait);
+	INIT_WORK(&md->work, dm_wq_work);
 	init_waitqueue_head(&md->eventq);
 
 	md->disk->major = _major;
@@ -1379,18 +1375,24 @@
 }
 EXPORT_SYMBOL_GPL(dm_put);
 
-static int dm_wait_for_completion(struct mapped_device *md)
+static int dm_wait_for_completion(struct mapped_device *md, int interruptible)
 {
 	int r = 0;
+	DECLARE_WAITQUEUE(wait, current);
+
+	dm_unplug_all(md->queue);
+
+	add_wait_queue(&md->wait, &wait);
 
 	while (1) {
-		set_current_state(TASK_INTERRUPTIBLE);
+		set_current_state(interruptible);
 
 		smp_mb();
 		if (!atomic_read(&md->pending))
 			break;
 
-		if (signal_pending(current)) {
+		if (interruptible == TASK_INTERRUPTIBLE &&
+		    signal_pending(current)) {
 			r = -EINTR;
 			break;
 		}
@@ -1399,67 +1401,40 @@
 	}
 	set_current_state(TASK_RUNNING);
 
+	remove_wait_queue(&md->wait, &wait);
+
 	return r;
 }
 
 /*
  * Process the deferred bios
  */
-static void __flush_deferred_io(struct mapped_device *md)
+static void dm_wq_work(struct work_struct *work)
 {
+	struct mapped_device *md = container_of(work, struct mapped_device,
+						work);
 	struct bio *c;
 
-	while ((c = bio_list_pop(&md->deferred))) {
-		if (__split_bio(md, c))
-			bio_io_error(c);
+	down_write(&md->io_lock);
+
+next_bio:
+	spin_lock_irq(&md->deferred_lock);
+	c = bio_list_pop(&md->deferred);
+	spin_unlock_irq(&md->deferred_lock);
+
+	if (c) {
+		__split_and_process_bio(md, c);
+		goto next_bio;
 	}
 
 	clear_bit(DMF_BLOCK_IO, &md->flags);
-}
 
-static void __merge_pushback_list(struct mapped_device *md)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&md->pushback_lock, flags);
-	clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags);
-	bio_list_merge_head(&md->deferred, &md->pushback);
-	bio_list_init(&md->pushback);
-	spin_unlock_irqrestore(&md->pushback_lock, flags);
-}
-
-static void dm_wq_work(struct work_struct *work)
-{
-	struct dm_wq_req *req = container_of(work, struct dm_wq_req, work);
-	struct mapped_device *md = req->md;
-
-	down_write(&md->io_lock);
-	switch (req->type) {
-	case DM_WQ_FLUSH_DEFERRED:
-		__flush_deferred_io(md);
-		break;
-	default:
-		DMERR("dm_wq_work: unrecognised work type %d", req->type);
-		BUG();
-	}
 	up_write(&md->io_lock);
 }
 
-static void dm_wq_queue(struct mapped_device *md, int type, void *context,
-			struct dm_wq_req *req)
+static void dm_queue_flush(struct mapped_device *md)
 {
-	req->type = type;
-	req->md = md;
-	req->context = context;
-	INIT_WORK(&req->work, dm_wq_work);
-	queue_work(md->wq, &req->work);
-}
-
-static void dm_queue_flush(struct mapped_device *md, int type, void *context)
-{
-	struct dm_wq_req req;
-
-	dm_wq_queue(md, type, context, &req);
+	queue_work(md->wq, &md->work);
 	flush_workqueue(md->wq);
 }
 
@@ -1534,7 +1509,6 @@
 int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
 {
 	struct dm_table *map = NULL;
-	DECLARE_WAITQUEUE(wait, current);
 	int r = 0;
 	int do_lockfs = suspend_flags & DM_SUSPEND_LOCKFS_FLAG ? 1 : 0;
 	int noflush = suspend_flags & DM_SUSPEND_NOFLUSH_FLAG ? 1 : 0;
@@ -1584,28 +1558,22 @@
 	down_write(&md->io_lock);
 	set_bit(DMF_BLOCK_IO, &md->flags);
 
-	add_wait_queue(&md->wait, &wait);
 	up_write(&md->io_lock);
 
-	/* unplug */
-	if (map)
-		dm_table_unplug_all(map);
-
 	/*
 	 * Wait for the already-mapped ios to complete.
 	 */
-	r = dm_wait_for_completion(md);
+	r = dm_wait_for_completion(md, TASK_INTERRUPTIBLE);
 
 	down_write(&md->io_lock);
-	remove_wait_queue(&md->wait, &wait);
 
 	if (noflush)
-		__merge_pushback_list(md);
+		clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags);
 	up_write(&md->io_lock);
 
 	/* were we interrupted ? */
 	if (r < 0) {
-		dm_queue_flush(md, DM_WQ_FLUSH_DEFERRED, NULL);
+		dm_queue_flush(md);
 
 		unlock_fs(md);
 		goto out; /* pushback list is already flushed, so skip flush */
@@ -1645,7 +1613,7 @@
 	if (r)
 		goto out;
 
-	dm_queue_flush(md, DM_WQ_FLUSH_DEFERRED, NULL);
+	dm_queue_flush(md);
 
 	unlock_fs(md);
 
diff --git a/drivers/md/dm.h b/drivers/md/dm.h
index 20194e0..b48397c0 100644
--- a/drivers/md/dm.h
+++ b/drivers/md/dm.h
@@ -60,7 +60,7 @@
 int dm_target_init(void);
 void dm_target_exit(void);
 struct target_type *dm_get_target_type(const char *name);
-void dm_put_target_type(struct target_type *t);
+void dm_put_target_type(struct target_type *tt);
 int dm_target_iterate(void (*iter_func)(struct target_type *tt,
 					void *param), void *param);
 
diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c
index 86d9adf..8695809b2 100644
--- a/drivers/md/faulty.c
+++ b/drivers/md/faulty.c
@@ -62,7 +62,10 @@
 #define	ModeShift	5
 
 #define MaxFault	50
-#include <linux/raid/md.h>
+#include <linux/blkdev.h>
+#include <linux/raid/md_u.h>
+#include "md.h"
+#include <linux/seq_file.h>
 
 
 static void faulty_fail(struct bio *bio, int error)
@@ -280,6 +283,17 @@
 	return 0;
 }
 
+static sector_t faulty_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+	WARN_ONCE(raid_disks,
+		  "%s does not support generic reshape\n", __func__);
+
+	if (sectors == 0)
+		return mddev->dev_sectors;
+
+	return sectors;
+}
+
 static int run(mddev_t *mddev)
 {
 	mdk_rdev_t *rdev;
@@ -298,7 +312,7 @@
 	list_for_each_entry(rdev, &mddev->disks, same_set)
 		conf->rdev = rdev;
 
-	mddev->array_sectors = mddev->size * 2;
+	md_set_array_sectors(mddev, faulty_size(mddev, 0, 0));
 	mddev->private = conf;
 
 	reconfig(mddev, mddev->layout, -1);
@@ -325,6 +339,7 @@
 	.stop		= stop,
 	.status		= status,
 	.reconfig	= reconfig,
+	.size		= faulty_size,
 };
 
 static int __init raid_init(void)
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index 09658b2..7a36e38 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -16,7 +16,11 @@
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
 */
 
-#include <linux/raid/linear.h>
+#include <linux/blkdev.h>
+#include <linux/raid/md_u.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "linear.h"
 
 /*
  * find which device holds a particular offset 
@@ -97,6 +101,16 @@
 	return ret;
 }
 
+static sector_t linear_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+	linear_conf_t *conf = mddev_to_conf(mddev);
+
+	WARN_ONCE(sectors || raid_disks,
+		  "%s does not support generic reshape\n", __func__);
+
+	return conf->array_sectors;
+}
+
 static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
 {
 	linear_conf_t *conf;
@@ -135,8 +149,8 @@
 		    mddev->queue->max_sectors > (PAGE_SIZE>>9))
 			blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
 
-		disk->num_sectors = rdev->size * 2;
-		conf->array_sectors += rdev->size * 2;
+		disk->num_sectors = rdev->sectors;
+		conf->array_sectors += rdev->sectors;
 
 		cnt++;
 	}
@@ -249,7 +263,7 @@
 	if (!conf)
 		return 1;
 	mddev->private = conf;
-	mddev->array_sectors = conf->array_sectors;
+	md_set_array_sectors(mddev, linear_size(mddev, 0, 0));
 
 	blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec);
 	mddev->queue->unplug_fn = linear_unplug;
@@ -283,7 +297,7 @@
 	newconf->prev = mddev_to_conf(mddev);
 	mddev->private = newconf;
 	mddev->raid_disks++;
-	mddev->array_sectors = newconf->array_sectors;
+	md_set_array_sectors(mddev, linear_size(mddev, 0, 0));
 	set_capacity(mddev->gendisk, mddev->array_sectors);
 	return 0;
 }
@@ -381,6 +395,7 @@
 	.stop		= linear_stop,
 	.status		= linear_status,
 	.hot_add_disk	= linear_add,
+	.size		= linear_size,
 };
 
 static int __init linear_init (void)
diff --git a/drivers/md/linear.h b/drivers/md/linear.h
new file mode 100644
index 0000000..bf81795
--- /dev/null
+++ b/drivers/md/linear.h
@@ -0,0 +1,29 @@
+#ifndef _LINEAR_H
+#define _LINEAR_H
+
+struct dev_info {
+	mdk_rdev_t	*rdev;
+	sector_t	num_sectors;
+	sector_t	start_sector;
+};
+
+typedef struct dev_info dev_info_t;
+
+struct linear_private_data
+{
+	struct linear_private_data *prev;	/* earlier version */
+	dev_info_t		**hash_table;
+	sector_t		spacing;
+	sector_t		array_sectors;
+	int			sector_shift;	/* shift before dividing
+						 * by spacing
+						 */
+	dev_info_t		disks[0];
+};
+
+
+typedef struct linear_private_data linear_conf_t;
+
+#define mddev_to_conf(mddev) ((linear_conf_t *) mddev->private)
+
+#endif
diff --git a/drivers/md/md.c b/drivers/md/md.c
index a307f87..ed5727c 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -33,9 +33,9 @@
 */
 
 #include <linux/kthread.h>
-#include <linux/raid/md.h>
-#include <linux/raid/bitmap.h>
+#include <linux/blkdev.h>
 #include <linux/sysctl.h>
+#include <linux/seq_file.h>
 #include <linux/buffer_head.h> /* for invalidate_bdev */
 #include <linux/poll.h>
 #include <linux/ctype.h>
@@ -45,11 +45,10 @@
 #include <linux/reboot.h>
 #include <linux/file.h>
 #include <linux/delay.h>
-
-#define MAJOR_NR MD_MAJOR
-
-/* 63 partitions with the alternate major number (mdp) */
-#define MdpMinorShift 6
+#include <linux/raid/md_p.h>
+#include <linux/raid/md_u.h>
+#include "md.h"
+#include "bitmap.h"
 
 #define DEBUG 0
 #define dprintk(x...) ((void)(DEBUG && printk(x)))
@@ -202,12 +201,68 @@
 		)
 
 
-static int md_fail_request(struct request_queue *q, struct bio *bio)
+/* Rather than calling directly into the personality make_request function,
+ * IO requests come here first so that we can check if the device is
+ * being suspended pending a reconfiguration.
+ * We hold a refcount over the call to ->make_request.  By the time that
+ * call has finished, the bio has been linked into some internal structure
+ * and so is visible to ->quiesce(), so we don't need the refcount any more.
+ */
+static int md_make_request(struct request_queue *q, struct bio *bio)
 {
-	bio_io_error(bio);
-	return 0;
+	mddev_t *mddev = q->queuedata;
+	int rv;
+	if (mddev == NULL || mddev->pers == NULL) {
+		bio_io_error(bio);
+		return 0;
+	}
+	rcu_read_lock();
+	if (mddev->suspended) {
+		DEFINE_WAIT(__wait);
+		for (;;) {
+			prepare_to_wait(&mddev->sb_wait, &__wait,
+					TASK_UNINTERRUPTIBLE);
+			if (!mddev->suspended)
+				break;
+			rcu_read_unlock();
+			schedule();
+			rcu_read_lock();
+		}
+		finish_wait(&mddev->sb_wait, &__wait);
+	}
+	atomic_inc(&mddev->active_io);
+	rcu_read_unlock();
+	rv = mddev->pers->make_request(q, bio);
+	if (atomic_dec_and_test(&mddev->active_io) && mddev->suspended)
+		wake_up(&mddev->sb_wait);
+
+	return rv;
 }
 
+static void mddev_suspend(mddev_t *mddev)
+{
+	BUG_ON(mddev->suspended);
+	mddev->suspended = 1;
+	synchronize_rcu();
+	wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0);
+	mddev->pers->quiesce(mddev, 1);
+	md_unregister_thread(mddev->thread);
+	mddev->thread = NULL;
+	/* we now know that no code is executing in the personality module,
+	 * except possibly the tail end of a ->bi_end_io function, but that
+	 * is certain to complete before the module has a chance to get
+	 * unloaded
+	 */
+}
+
+static void mddev_resume(mddev_t *mddev)
+{
+	mddev->suspended = 0;
+	wake_up(&mddev->sb_wait);
+	mddev->pers->quiesce(mddev, 0);
+}
+
+
 static inline mddev_t *mddev_get(mddev_t *mddev)
 {
 	atomic_inc(&mddev->active);
@@ -310,6 +365,7 @@
 	init_timer(&new->safemode_timer);
 	atomic_set(&new->active, 1);
 	atomic_set(&new->openers, 0);
+	atomic_set(&new->active_io, 0);
 	spin_lock_init(&new->write_lock);
 	init_waitqueue_head(&new->sb_wait);
 	init_waitqueue_head(&new->recovery_wait);
@@ -326,6 +382,11 @@
 	return mutex_lock_interruptible(&mddev->reconfig_mutex);
 }
 
+static inline int mddev_is_locked(mddev_t *mddev)
+{
+	return mutex_is_locked(&mddev->reconfig_mutex);
+}
+
 static inline int mddev_trylock(mddev_t * mddev)
 {
 	return mutex_trylock(&mddev->reconfig_mutex);
@@ -409,7 +470,7 @@
 		rdev->sb_loaded = 0;
 		rdev->sb_page = NULL;
 		rdev->sb_start = 0;
-		rdev->size = 0;
+		rdev->sectors = 0;
 	}
 }
 
@@ -775,9 +836,9 @@
 		else 
 			ret = 0;
 	}
-	rdev->size = calc_num_sectors(rdev, sb->chunk_size) / 2;
+	rdev->sectors = calc_num_sectors(rdev, sb->chunk_size);
 
-	if (rdev->size < sb->size && sb->level > 1)
+	if (rdev->sectors < sb->size * 2 && sb->level > 1)
 		/* "this cannot possibly happen" ... */
 		ret = -EINVAL;
 
@@ -812,7 +873,7 @@
 		mddev->clevel[0] = 0;
 		mddev->layout = sb->layout;
 		mddev->raid_disks = sb->raid_disks;
-		mddev->size = sb->size;
+		mddev->dev_sectors = sb->size * 2;
 		mddev->events = ev1;
 		mddev->bitmap_offset = 0;
 		mddev->default_bitmap_offset = MD_SB_BYTES >> 9;
@@ -926,7 +987,7 @@
 
 	sb->ctime = mddev->ctime;
 	sb->level = mddev->level;
-	sb->size  = mddev->size;
+	sb->size = mddev->dev_sectors / 2;
 	sb->raid_disks = mddev->raid_disks;
 	sb->md_minor = mddev->md_minor;
 	sb->not_persistent = 0;
@@ -1024,7 +1085,7 @@
 static unsigned long long
 super_90_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors)
 {
-	if (num_sectors && num_sectors < rdev->mddev->size * 2)
+	if (num_sectors && num_sectors < rdev->mddev->dev_sectors)
 		return 0; /* component must fit device */
 	if (rdev->mddev->bitmap_offset)
 		return 0; /* can't move bitmap */
@@ -1180,16 +1241,17 @@
 			ret = 0;
 	}
 	if (minor_version)
-		rdev->size = ((rdev->bdev->bd_inode->i_size>>9) - le64_to_cpu(sb->data_offset)) / 2;
+		rdev->sectors = (rdev->bdev->bd_inode->i_size >> 9) -
+			le64_to_cpu(sb->data_offset);
 	else
-		rdev->size = rdev->sb_start / 2;
-	if (rdev->size < le64_to_cpu(sb->data_size)/2)
+		rdev->sectors = rdev->sb_start;
+	if (rdev->sectors < le64_to_cpu(sb->data_size))
 		return -EINVAL;
-	rdev->size = le64_to_cpu(sb->data_size)/2;
+	rdev->sectors = le64_to_cpu(sb->data_size);
 	if (le32_to_cpu(sb->chunksize))
-		rdev->size &= ~((sector_t)le32_to_cpu(sb->chunksize)/2 - 1);
+		rdev->sectors &= ~((sector_t)le32_to_cpu(sb->chunksize) - 1);
 
-	if (le64_to_cpu(sb->size) > rdev->size*2)
+	if (le64_to_cpu(sb->size) > rdev->sectors)
 		return -EINVAL;
 	return ret;
 }
@@ -1216,7 +1278,7 @@
 		mddev->clevel[0] = 0;
 		mddev->layout = le32_to_cpu(sb->layout);
 		mddev->raid_disks = le32_to_cpu(sb->raid_disks);
-		mddev->size = le64_to_cpu(sb->size)/2;
+		mddev->dev_sectors = le64_to_cpu(sb->size);
 		mddev->events = ev1;
 		mddev->bitmap_offset = 0;
 		mddev->default_bitmap_offset = 1024 >> 9;
@@ -1312,7 +1374,7 @@
 	sb->cnt_corrected_read = cpu_to_le32(atomic_read(&rdev->corrected_errors));
 
 	sb->raid_disks = cpu_to_le32(mddev->raid_disks);
-	sb->size = cpu_to_le64(mddev->size<<1);
+	sb->size = cpu_to_le64(mddev->dev_sectors);
 
 	if (mddev->bitmap && mddev->bitmap_file == NULL) {
 		sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset);
@@ -1320,10 +1382,15 @@
 	}
 
 	if (rdev->raid_disk >= 0 &&
-	    !test_bit(In_sync, &rdev->flags) &&
-	    rdev->recovery_offset > 0) {
-		sb->feature_map |= cpu_to_le32(MD_FEATURE_RECOVERY_OFFSET);
-		sb->recovery_offset = cpu_to_le64(rdev->recovery_offset);
+	    !test_bit(In_sync, &rdev->flags)) {
+		if (mddev->curr_resync_completed > rdev->recovery_offset)
+			rdev->recovery_offset = mddev->curr_resync_completed;
+		if (rdev->recovery_offset > 0) {
+			sb->feature_map |=
+				cpu_to_le32(MD_FEATURE_RECOVERY_OFFSET);
+			sb->recovery_offset =
+				cpu_to_le64(rdev->recovery_offset);
+		}
 	}
 
 	if (mddev->reshape_position != MaxSector) {
@@ -1365,7 +1432,7 @@
 {
 	struct mdp_superblock_1 *sb;
 	sector_t max_sectors;
-	if (num_sectors && num_sectors < rdev->mddev->size * 2)
+	if (num_sectors && num_sectors < rdev->mddev->dev_sectors)
 		return 0; /* component must fit device */
 	if (rdev->sb_start < rdev->data_offset) {
 		/* minor versions 1 and 2; superblock before data */
@@ -1381,7 +1448,7 @@
 		sector_t sb_start;
 		sb_start = (rdev->bdev->bd_inode->i_size >> 9) - 8*2;
 		sb_start &= ~(sector_t)(4*2 - 1);
-		max_sectors = rdev->size * 2 + sb_start - rdev->sb_start;
+		max_sectors = rdev->sectors + sb_start - rdev->sb_start;
 		if (!num_sectors || num_sectors > max_sectors)
 			num_sectors = max_sectors;
 		rdev->sb_start = sb_start;
@@ -1433,6 +1500,38 @@
 
 static LIST_HEAD(pending_raid_disks);
 
+static void md_integrity_check(mdk_rdev_t *rdev, mddev_t *mddev)
+{
+	struct mdk_personality *pers = mddev->pers;
+	struct gendisk *disk = mddev->gendisk;
+	struct blk_integrity *bi_rdev = bdev_get_integrity(rdev->bdev);
+	struct blk_integrity *bi_mddev = blk_get_integrity(disk);
+
+	/* Data integrity passthrough not supported on RAID 4, 5 and 6 */
+	if (pers && pers->level >= 4 && pers->level <= 6)
+		return;
+
+	/* If rdev is integrity capable, register profile for mddev */
+	if (!bi_mddev && bi_rdev) {
+		if (blk_integrity_register(disk, bi_rdev))
+			printk(KERN_ERR "%s: %s Could not register integrity!\n",
+			       __func__, disk->disk_name);
+		else
+			printk(KERN_NOTICE "Enabling data integrity on %s\n",
+			       disk->disk_name);
+		return;
+	}
+
+	/* Check that mddev and rdev have matching profiles */
+	if (blk_integrity_compare(disk, rdev->bdev->bd_disk) < 0) {
+		printk(KERN_ERR "%s: %s/%s integrity mismatch!\n", __func__,
+		       disk->disk_name, rdev->bdev->bd_disk->disk_name);
+		printk(KERN_NOTICE "Disabling data integrity on %s\n",
+		       disk->disk_name);
+		blk_integrity_unregister(disk);
+	}
+}
+
 static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
 {
 	char b[BDEVNAME_SIZE];
@@ -1449,8 +1548,9 @@
 	if (find_rdev(mddev, rdev->bdev->bd_dev))
 		return -EEXIST;
 
-	/* make sure rdev->size exceeds mddev->size */
-	if (rdev->size && (mddev->size == 0 || rdev->size < mddev->size)) {
+	/* make sure rdev->sectors exceeds mddev->dev_sectors */
+	if (rdev->sectors && (mddev->dev_sectors == 0 ||
+			rdev->sectors < mddev->dev_sectors)) {
 		if (mddev->pers) {
 			/* Cannot change size, so fail
 			 * If mddev->level <= 0, then we don't care
@@ -1459,7 +1559,7 @@
 			if (mddev->level > 0)
 				return -ENOSPC;
 		} else
-			mddev->size = rdev->size;
+			mddev->dev_sectors = rdev->sectors;
 	}
 
 	/* Verify rdev->desc_nr is unique.
@@ -1503,6 +1603,8 @@
 
 	/* May as well allow recovery to be retried once */
 	mddev->recovery_disabled = 0;
+
+	md_integrity_check(rdev, mddev);
 	return 0;
 
  fail:
@@ -1713,8 +1815,8 @@
 static void print_rdev(mdk_rdev_t *rdev, int major_version)
 {
 	char b[BDEVNAME_SIZE];
-	printk(KERN_INFO "md: rdev %s, SZ:%08llu F:%d S:%d DN:%u\n",
-		bdevname(rdev->bdev,b), (unsigned long long)rdev->size,
+	printk(KERN_INFO "md: rdev %s, Sect:%08llu F:%d S:%d DN:%u\n",
+		bdevname(rdev->bdev, b), (unsigned long long)rdev->sectors,
 	        test_bit(Faulty, &rdev->flags), test_bit(In_sync, &rdev->flags),
 	        rdev->desc_nr);
 	if (rdev->sb_loaded) {
@@ -2153,7 +2255,7 @@
 		return -EINVAL;
 	if (rdev->mddev->pers && rdev->raid_disk >= 0)
 		return -EBUSY;
-	if (rdev->size && rdev->mddev->external)
+	if (rdev->sectors && rdev->mddev->external)
 		/* Must set offset before size, so overlap checks
 		 * can be sane */
 		return -EBUSY;
@@ -2167,7 +2269,7 @@
 static ssize_t
 rdev_size_show(mdk_rdev_t *rdev, char *page)
 {
-	return sprintf(page, "%llu\n", (unsigned long long)rdev->size);
+	return sprintf(page, "%llu\n", (unsigned long long)rdev->sectors / 2);
 }
 
 static int overlaps(sector_t s1, sector_t l1, sector_t s2, sector_t l2)
@@ -2180,34 +2282,52 @@
 	return 1;
 }
 
+static int strict_blocks_to_sectors(const char *buf, sector_t *sectors)
+{
+	unsigned long long blocks;
+	sector_t new;
+
+	if (strict_strtoull(buf, 10, &blocks) < 0)
+		return -EINVAL;
+
+	if (blocks & 1ULL << (8 * sizeof(blocks) - 1))
+		return -EINVAL; /* sector conversion overflow */
+
+	new = blocks * 2;
+	if (new != blocks * 2)
+		return -EINVAL; /* unsigned long long to sector_t overflow */
+
+	*sectors = new;
+	return 0;
+}
+
 static ssize_t
 rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
 {
-	unsigned long long size;
-	unsigned long long oldsize = rdev->size;
 	mddev_t *my_mddev = rdev->mddev;
+	sector_t oldsectors = rdev->sectors;
+	sector_t sectors;
 
-	if (strict_strtoull(buf, 10, &size) < 0)
+	if (strict_blocks_to_sectors(buf, &sectors) < 0)
 		return -EINVAL;
 	if (my_mddev->pers && rdev->raid_disk >= 0) {
 		if (my_mddev->persistent) {
-			size = super_types[my_mddev->major_version].
-				rdev_size_change(rdev, size * 2);
-			if (!size)
+			sectors = super_types[my_mddev->major_version].
+				rdev_size_change(rdev, sectors);
+			if (!sectors)
 				return -EBUSY;
-		} else if (!size) {
-			size = (rdev->bdev->bd_inode->i_size >> 10);
-			size -= rdev->data_offset/2;
-		}
+		} else if (!sectors)
+			sectors = (rdev->bdev->bd_inode->i_size >> 9) -
+				rdev->data_offset;
 	}
-	if (size < my_mddev->size)
+	if (sectors < my_mddev->dev_sectors)
 		return -EINVAL; /* component must fit device */
 
-	rdev->size = size;
-	if (size > oldsize && my_mddev->external) {
+	rdev->sectors = sectors;
+	if (sectors > oldsectors && my_mddev->external) {
 		/* need to check that all other rdevs with the same ->bdev
 		 * do not overlap.  We need to unlock the mddev to avoid
-		 * a deadlock.  We have already changed rdev->size, and if
+		 * a deadlock.  We have already changed rdev->sectors, and if
 		 * we have to change it back, we will have the lock again.
 		 */
 		mddev_t *mddev;
@@ -2223,9 +2343,9 @@
 				if (test_bit(AllReserved, &rdev2->flags) ||
 				    (rdev->bdev == rdev2->bdev &&
 				     rdev != rdev2 &&
-				     overlaps(rdev->data_offset, rdev->size * 2,
+				     overlaps(rdev->data_offset, rdev->sectors,
 					      rdev2->data_offset,
-					      rdev2->size * 2))) {
+					      rdev2->sectors))) {
 					overlap = 1;
 					break;
 				}
@@ -2239,11 +2359,11 @@
 		if (overlap) {
 			/* Someone else could have slipped in a size
 			 * change here, but doing so is just silly.
-			 * We put oldsize back because we *know* it is
+			 * We put oldsectors back because we *know* it is
 			 * safe, and trust userspace not to race with
 			 * itself
 			 */
-			rdev->size = oldsize;
+			rdev->sectors = oldsectors;
 			return -EBUSY;
 		}
 	}
@@ -2547,18 +2667,101 @@
 static ssize_t
 level_store(mddev_t *mddev, const char *buf, size_t len)
 {
+	char level[16];
 	ssize_t rv = len;
-	if (mddev->pers)
+	struct mdk_personality *pers;
+	void *priv;
+
+	if (mddev->pers == NULL) {
+		if (len == 0)
+			return 0;
+		if (len >= sizeof(mddev->clevel))
+			return -ENOSPC;
+		strncpy(mddev->clevel, buf, len);
+		if (mddev->clevel[len-1] == '\n')
+			len--;
+		mddev->clevel[len] = 0;
+		mddev->level = LEVEL_NONE;
+		return rv;
+	}
+
+	/* request to change the personality.  Need to ensure:
+	 *  - array is not engaged in resync/recovery/reshape
+	 *  - old personality can be suspended
+	 *  - new personality will access other array.
+	 */
+
+	if (mddev->sync_thread || mddev->reshape_position != MaxSector)
 		return -EBUSY;
-	if (len == 0)
-		return 0;
-	if (len >= sizeof(mddev->clevel))
-		return -ENOSPC;
-	strncpy(mddev->clevel, buf, len);
-	if (mddev->clevel[len-1] == '\n')
+
+	if (!mddev->pers->quiesce) {
+		printk(KERN_WARNING "md: %s: %s does not support online personality change\n",
+		       mdname(mddev), mddev->pers->name);
+		return -EINVAL;
+	}
+
+	/* Now find the new personality */
+	if (len == 0 || len >= sizeof(level))
+		return -EINVAL;
+	strncpy(level, buf, len);
+	if (level[len-1] == '\n')
 		len--;
-	mddev->clevel[len] = 0;
-	mddev->level = LEVEL_NONE;
+	level[len] = 0;
+
+	request_module("md-%s", level);
+	spin_lock(&pers_lock);
+	pers = find_pers(LEVEL_NONE, level);
+	if (!pers || !try_module_get(pers->owner)) {
+		spin_unlock(&pers_lock);
+		printk(KERN_WARNING "md: personality %s not loaded\n", level);
+		return -EINVAL;
+	}
+	spin_unlock(&pers_lock);
+
+	if (pers == mddev->pers) {
+		/* Nothing to do! */
+		module_put(pers->owner);
+		return rv;
+	}
+	if (!pers->takeover) {
+		module_put(pers->owner);
+		printk(KERN_WARNING "md: %s: %s does not support personality takeover\n",
+		       mdname(mddev), level);
+		return -EINVAL;
+	}
+
+	/* ->takeover must set new_* and/or delta_disks
+	 * if it succeeds, and may set them when it fails.
+	 */
+	priv = pers->takeover(mddev);
+	if (IS_ERR(priv)) {
+		mddev->new_level = mddev->level;
+		mddev->new_layout = mddev->layout;
+		mddev->new_chunk = mddev->chunk_size;
+		mddev->raid_disks -= mddev->delta_disks;
+		mddev->delta_disks = 0;
+		module_put(pers->owner);
+		printk(KERN_WARNING "md: %s: %s would not accept array\n",
+		       mdname(mddev), level);
+		return PTR_ERR(priv);
+	}
+
+	/* Looks like we have a winner */
+	mddev_suspend(mddev);
+	mddev->pers->stop(mddev);
+	module_put(mddev->pers->owner);
+	mddev->pers = pers;
+	mddev->private = priv;
+	strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel));
+	mddev->level = mddev->new_level;
+	mddev->layout = mddev->new_layout;
+	mddev->chunk_size = mddev->new_chunk;
+	mddev->delta_disks = 0;
+	pers->run(mddev);
+	mddev_resume(mddev);
+	set_bit(MD_CHANGE_DEVS, &mddev->flags);
+	set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+	md_wakeup_thread(mddev->thread);
 	return rv;
 }
 
@@ -2586,12 +2789,18 @@
 	if (!*buf || (*e && *e != '\n'))
 		return -EINVAL;
 
-	if (mddev->pers)
-		return -EBUSY;
-	if (mddev->reshape_position != MaxSector)
+	if (mddev->pers) {
+		int err;
+		if (mddev->pers->reconfig == NULL)
+			return -EBUSY;
+		err = mddev->pers->reconfig(mddev, n, -1);
+		if (err)
+			return err;
+	} else {
 		mddev->new_layout = n;
-	else
-		mddev->layout = n;
+		if (mddev->reshape_position == MaxSector)
+			mddev->layout = n;
+	}
 	return len;
 }
 static struct md_sysfs_entry md_layout =
@@ -2648,19 +2857,24 @@
 static ssize_t
 chunk_size_store(mddev_t *mddev, const char *buf, size_t len)
 {
-	/* can only set chunk_size if array is not yet active */
 	char *e;
 	unsigned long n = simple_strtoul(buf, &e, 10);
 
 	if (!*buf || (*e && *e != '\n'))
 		return -EINVAL;
 
-	if (mddev->pers)
-		return -EBUSY;
-	else if (mddev->reshape_position != MaxSector)
+	if (mddev->pers) {
+		int err;
+		if (mddev->pers->reconfig == NULL)
+			return -EBUSY;
+		err = mddev->pers->reconfig(mddev, -1, n);
+		if (err)
+			return err;
+	} else {
 		mddev->new_chunk = n;
-	else
-		mddev->chunk_size = n;
+		if (mddev->reshape_position == MaxSector)
+			mddev->chunk_size = n;
+	}
 	return len;
 }
 static struct md_sysfs_entry md_chunk_size =
@@ -2669,6 +2883,8 @@
 static ssize_t
 resync_start_show(mddev_t *mddev, char *page)
 {
+	if (mddev->recovery_cp == MaxSector)
+		return sprintf(page, "none\n");
 	return sprintf(page, "%llu\n", (unsigned long long)mddev->recovery_cp);
 }
 
@@ -2766,7 +2982,7 @@
 	else {
 		if (list_empty(&mddev->disks) &&
 		    mddev->raid_disks == 0 &&
-		    mddev->size == 0)
+		    mddev->dev_sectors == 0)
 			st = clear;
 		else
 			st = inactive;
@@ -2973,7 +3189,8 @@
 static ssize_t
 size_show(mddev_t *mddev, char *page)
 {
-	return sprintf(page, "%llu\n", (unsigned long long)mddev->size);
+	return sprintf(page, "%llu\n",
+		(unsigned long long)mddev->dev_sectors / 2);
 }
 
 static int update_size(mddev_t *mddev, sector_t num_sectors);
@@ -2985,20 +3202,18 @@
 	 * not increase it (except from 0).
 	 * If array is active, we can try an on-line resize
 	 */
-	char *e;
-	int err = 0;
-	unsigned long long size = simple_strtoull(buf, &e, 10);
-	if (!*buf || *buf == '\n' ||
-	    (*e && *e != '\n'))
-		return -EINVAL;
+	sector_t sectors;
+	int err = strict_blocks_to_sectors(buf, &sectors);
 
+	if (err < 0)
+		return err;
 	if (mddev->pers) {
-		err = update_size(mddev, size * 2);
+		err = update_size(mddev, sectors);
 		md_update_sb(mddev, 1);
 	} else {
-		if (mddev->size == 0 ||
-		    mddev->size > size)
-			mddev->size = size;
+		if (mddev->dev_sectors == 0 ||
+		    mddev->dev_sectors > sectors)
+			mddev->dev_sectors = sectors;
 		else
 			err = -ENOSPC;
 	}
@@ -3251,6 +3466,8 @@
 sync_speed_show(mddev_t *mddev, char *page)
 {
 	unsigned long resync, dt, db;
+	if (mddev->curr_resync == 0)
+		return sprintf(page, "none\n");
 	resync = mddev->curr_mark_cnt - atomic_read(&mddev->recovery_active);
 	dt = (jiffies - mddev->resync_mark) / HZ;
 	if (!dt) dt++;
@@ -3263,15 +3480,15 @@
 static ssize_t
 sync_completed_show(mddev_t *mddev, char *page)
 {
-	unsigned long max_blocks, resync;
+	unsigned long max_sectors, resync;
 
 	if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
-		max_blocks = mddev->resync_max_sectors;
+		max_sectors = mddev->resync_max_sectors;
 	else
-		max_blocks = mddev->size << 1;
+		max_sectors = mddev->dev_sectors;
 
 	resync = (mddev->curr_resync - atomic_read(&mddev->recovery_active));
-	return sprintf(page, "%lu / %lu\n", resync, max_blocks);
+	return sprintf(page, "%lu / %lu\n", resync, max_sectors);
 }
 
 static struct md_sysfs_entry md_sync_completed = __ATTR_RO(sync_completed);
@@ -3431,6 +3648,57 @@
 __ATTR(reshape_position, S_IRUGO|S_IWUSR, reshape_position_show,
        reshape_position_store);
 
+static ssize_t
+array_size_show(mddev_t *mddev, char *page)
+{
+	if (mddev->external_size)
+		return sprintf(page, "%llu\n",
+			       (unsigned long long)mddev->array_sectors/2);
+	else
+		return sprintf(page, "default\n");
+}
+
+static ssize_t
+array_size_store(mddev_t *mddev, const char *buf, size_t len)
+{
+	sector_t sectors;
+
+	if (strncmp(buf, "default", 7) == 0) {
+		if (mddev->pers)
+			sectors = mddev->pers->size(mddev, 0, 0);
+		else
+			sectors = mddev->array_sectors;
+
+		mddev->external_size = 0;
+	} else {
+		if (strict_blocks_to_sectors(buf, &sectors) < 0)
+			return -EINVAL;
+		if (mddev->pers && mddev->pers->size(mddev, 0, 0) < sectors)
+			return -EINVAL;
+
+		mddev->external_size = 1;
+	}
+
+	mddev->array_sectors = sectors;
+	set_capacity(mddev->gendisk, mddev->array_sectors);
+	if (mddev->pers) {
+		struct block_device *bdev = bdget_disk(mddev->gendisk, 0);
+
+		if (bdev) {
+			mutex_lock(&bdev->bd_inode->i_mutex);
+			i_size_write(bdev->bd_inode,
+				     (loff_t)mddev->array_sectors << 9);
+			mutex_unlock(&bdev->bd_inode->i_mutex);
+			bdput(bdev);
+		}
+	}
+
+	return len;
+}
+
+static struct md_sysfs_entry md_array_size =
+__ATTR(array_size, S_IRUGO|S_IWUSR, array_size_show,
+       array_size_store);
 
 static struct attribute *md_default_attrs[] = {
 	&md_level.attr,
@@ -3444,6 +3712,7 @@
 	&md_safe_delay.attr,
 	&md_array_state.attr,
 	&md_reshape_position.attr,
+	&md_array_size.attr,
 	NULL,
 };
 
@@ -3602,10 +3871,12 @@
 		mddev_put(mddev);
 		return -ENOMEM;
 	}
+	mddev->queue->queuedata = mddev;
+
 	/* Can be unlocked because the queue is new: no concurrency */
 	queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, mddev->queue);
 
-	blk_queue_make_request(mddev->queue, md_fail_request);
+	blk_queue_make_request(mddev->queue, md_make_request);
 
 	disk = alloc_disk(1 << shift);
 	if (!disk) {
@@ -3731,13 +4002,13 @@
 		list_for_each_entry(rdev, &mddev->disks, same_set) {
 			if (test_bit(Faulty, &rdev->flags))
 				continue;
-			if (rdev->size < chunk_size / 1024) {
+			if (rdev->sectors < chunk_size / 512) {
 				printk(KERN_WARNING
 					"md: Dev %s smaller than chunk_size:"
-					" %lluk < %dk\n",
+					" %llu < %d\n",
 					bdevname(rdev->bdev,b),
-					(unsigned long long)rdev->size,
-					chunk_size / 1024);
+					(unsigned long long)rdev->sectors,
+					chunk_size / 512);
 				return -EINVAL;
 			}
 		}
@@ -3761,11 +4032,11 @@
 
 		/* perform some consistency tests on the device.
 		 * We don't want the data to overlap the metadata,
-		 * Internal Bitmap issues has handled elsewhere.
+		 * Internal Bitmap issues have been handled elsewhere.
 		 */
 		if (rdev->data_offset < rdev->sb_start) {
-			if (mddev->size &&
-			    rdev->data_offset + mddev->size*2
+			if (mddev->dev_sectors &&
+			    rdev->data_offset + mddev->dev_sectors
 			    > rdev->sb_start) {
 				printk("md: %s: data overlaps metadata\n",
 				       mdname(mddev));
@@ -3801,9 +4072,16 @@
 	}
 	mddev->pers = pers;
 	spin_unlock(&pers_lock);
-	mddev->level = pers->level;
+	if (mddev->level != pers->level) {
+		mddev->level = pers->level;
+		mddev->new_level = pers->level;
+	}
 	strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel));
 
+	if (pers->level >= 4 && pers->level <= 6)
+		/* Cannot support integrity (yet) */
+		blk_integrity_unregister(mddev->gendisk);
+
 	if (mddev->reshape_position != MaxSector &&
 	    pers->start_reshape == NULL) {
 		/* This personality cannot handle reshaping... */
@@ -3843,7 +4121,9 @@
 	}
 
 	mddev->recovery = 0;
-	mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */
+	/* may be over-ridden by personality */
+	mddev->resync_max_sectors = mddev->dev_sectors;
+
 	mddev->barriers_work = 1;
 	mddev->ok_start_degraded = start_dirty_degraded;
 
@@ -3853,7 +4133,17 @@
 	err = mddev->pers->run(mddev);
 	if (err)
 		printk(KERN_ERR "md: pers->run() failed ...\n");
-	else if (mddev->pers->sync_request) {
+	else if (mddev->pers->size(mddev, 0, 0) < mddev->array_sectors) {
+		WARN_ONCE(!mddev->external_size, "%s: default size too small,"
+			  " but 'external_size' not in effect?\n", __func__);
+		printk(KERN_ERR
+		       "md: invalid array_size %llu > default size %llu\n",
+		       (unsigned long long)mddev->array_sectors / 2,
+		       (unsigned long long)mddev->pers->size(mddev, 0, 0) / 2);
+		err = -EINVAL;
+		mddev->pers->stop(mddev);
+	}
+	if (err == 0 && mddev->pers->sync_request) {
 		err = bitmap_create(mddev);
 		if (err) {
 			printk(KERN_ERR "%s: failed to create bitmap (%d)\n",
@@ -3899,16 +4189,6 @@
 
 	set_capacity(disk, mddev->array_sectors);
 
-	/* If we call blk_queue_make_request here, it will
-	 * re-initialise max_sectors etc which may have been
-	 * refined inside -> run.  So just set the bits we need to set.
-	 * Most initialisation happended when we called
-	 * blk_queue_make_request(..., md_fail_request)
-	 * earlier.
-	 */
-	mddev->queue->queuedata = mddev;
-	mddev->queue->make_request_fn = mddev->pers->make_request;
-
 	/* If there is a partially-recovered drive we need to
 	 * start recovery here.  If we leave it to md_check_recovery,
 	 * it will remove the drives and not do the right thing
@@ -4038,7 +4318,7 @@
 			md_super_wait(mddev);
 			if (mddev->ro)
 				set_disk_ro(disk, 0);
-			blk_queue_make_request(mddev->queue, md_fail_request);
+
 			mddev->pers->stop(mddev);
 			mddev->queue->merge_bvec_fn = NULL;
 			mddev->queue->unplug_fn = NULL;
@@ -4095,7 +4375,8 @@
 		export_array(mddev);
 
 		mddev->array_sectors = 0;
-		mddev->size = 0;
+		mddev->external_size = 0;
+		mddev->dev_sectors = 0;
 		mddev->raid_disks = 0;
 		mddev->recovery_cp = 0;
 		mddev->resync_min = 0;
@@ -4135,6 +4416,7 @@
 		printk(KERN_INFO "md: %s switched to read-only mode.\n",
 			mdname(mddev));
 	err = 0;
+	blk_integrity_unregister(disk);
 	md_new_event(mddev);
 	sysfs_notify_dirent(mddev->sysfs_state);
 out:
@@ -4300,8 +4582,8 @@
 	info.patch_version = MD_PATCHLEVEL_VERSION;
 	info.ctime         = mddev->ctime;
 	info.level         = mddev->level;
-	info.size          = mddev->size;
-	if (info.size != mddev->size) /* overflow */
+	info.size          = mddev->dev_sectors / 2;
+	if (info.size != mddev->dev_sectors / 2) /* overflow */
 		info.size = -1;
 	info.nr_disks      = nr;
 	info.raid_disks    = mddev->raid_disks;
@@ -4480,6 +4762,8 @@
 		clear_bit(In_sync, &rdev->flags); /* just to be sure */
 		if (info->state & (1<<MD_DISK_WRITEMOSTLY))
 			set_bit(WriteMostly, &rdev->flags);
+		else
+			clear_bit(WriteMostly, &rdev->flags);
 
 		rdev->raid_disk = -1;
 		err = bind_rdev_to_array(rdev, mddev);
@@ -4543,7 +4827,7 @@
 			rdev->sb_start = rdev->bdev->bd_inode->i_size / 512;
 		} else 
 			rdev->sb_start = calc_dev_sboffset(rdev->bdev);
-		rdev->size = calc_num_sectors(rdev, mddev->chunk_size) / 2;
+		rdev->sectors = calc_num_sectors(rdev, mddev->chunk_size);
 
 		err = bind_rdev_to_array(rdev, mddev);
 		if (err) {
@@ -4613,7 +4897,7 @@
 	else
 		rdev->sb_start = rdev->bdev->bd_inode->i_size / 512;
 
-	rdev->size = calc_num_sectors(rdev, mddev->chunk_size) / 2;
+	rdev->sectors = calc_num_sectors(rdev, mddev->chunk_size);
 
 	if (test_bit(Faulty, &rdev->flags)) {
 		printk(KERN_WARNING 
@@ -4749,7 +5033,7 @@
 
 	mddev->level         = info->level;
 	mddev->clevel[0]     = 0;
-	mddev->size          = info->size;
+	mddev->dev_sectors   = 2 * (sector_t)info->size;
 	mddev->raid_disks    = info->raid_disks;
 	/* don't set md_minor, it is determined by which /dev/md* was
 	 * openned
@@ -4788,6 +5072,17 @@
 	return 0;
 }
 
+void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors)
+{
+	WARN(!mddev_is_locked(mddev), "%s: unlocked mddev!\n", __func__);
+
+	if (mddev->external_size)
+		return;
+
+	mddev->array_sectors = array_sectors;
+}
+EXPORT_SYMBOL(md_set_array_sectors);
+
 static int update_size(mddev_t *mddev, sector_t num_sectors)
 {
 	mdk_rdev_t *rdev;
@@ -4814,8 +5109,7 @@
 		 */
 		return -EBUSY;
 	list_for_each_entry(rdev, &mddev->disks, same_set) {
-		sector_t avail;
-		avail = rdev->size * 2;
+		sector_t avail = rdev->sectors;
 
 		if (fit && (num_sectors == 0 || num_sectors > avail))
 			num_sectors = avail;
@@ -4887,12 +5181,18 @@
 		)
 		return -EINVAL;
 	/* Check there is only one change */
-	if (info->size >= 0 && mddev->size != info->size) cnt++;
-	if (mddev->raid_disks != info->raid_disks) cnt++;
-	if (mddev->layout != info->layout) cnt++;
-	if ((state ^ info->state) & (1<<MD_SB_BITMAP_PRESENT)) cnt++;
-	if (cnt == 0) return 0;
-	if (cnt > 1) return -EINVAL;
+	if (info->size >= 0 && mddev->dev_sectors / 2 != info->size)
+		cnt++;
+	if (mddev->raid_disks != info->raid_disks)
+		cnt++;
+	if (mddev->layout != info->layout)
+		cnt++;
+	if ((state ^ info->state) & (1<<MD_SB_BITMAP_PRESENT))
+		cnt++;
+	if (cnt == 0)
+		return 0;
+	if (cnt > 1)
+		return -EINVAL;
 
 	if (mddev->layout != info->layout) {
 		/* Change layout
@@ -4904,7 +5204,7 @@
 		else
 			return mddev->pers->reconfig(mddev, info->layout, -1);
 	}
-	if (info->size >= 0 && mddev->size != info->size)
+	if (info->size >= 0 && mddev->dev_sectors / 2 != info->size)
 		rv = update_size(mddev, (sector_t)info->size * 2);
 
 	if (mddev->raid_disks    != info->raid_disks)
@@ -5331,6 +5631,8 @@
 
 void md_unregister_thread(mdk_thread_t *thread)
 {
+	if (!thread)
+		return;
 	dprintk("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk));
 
 	kthread_stop(thread->tsk);
@@ -5404,7 +5706,7 @@
 	if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
 		max_blocks = mddev->resync_max_sectors >> 1;
 	else
-		max_blocks = mddev->size;
+		max_blocks = mddev->dev_sectors / 2;
 
 	/*
 	 * Should not happen.
@@ -5537,7 +5839,7 @@
 static int md_seq_show(struct seq_file *seq, void *v)
 {
 	mddev_t *mddev = v;
-	sector_t size;
+	sector_t sectors;
 	mdk_rdev_t *rdev;
 	struct mdstat_info *mi = seq->private;
 	struct bitmap *bitmap;
@@ -5573,7 +5875,7 @@
 			seq_printf(seq, " %s", mddev->pers->name);
 		}
 
-		size = 0;
+		sectors = 0;
 		list_for_each_entry(rdev, &mddev->disks, same_set) {
 			char b[BDEVNAME_SIZE];
 			seq_printf(seq, " %s[%d]",
@@ -5585,7 +5887,7 @@
 				continue;
 			} else if (rdev->raid_disk < 0)
 				seq_printf(seq, "(S)"); /* spare */
-			size += rdev->size;
+			sectors += rdev->sectors;
 		}
 
 		if (!list_empty(&mddev->disks)) {
@@ -5595,7 +5897,7 @@
 					   mddev->array_sectors / 2);
 			else
 				seq_printf(seq, "\n      %llu blocks",
-					   (unsigned long long)size);
+					   (unsigned long long)sectors / 2);
 		}
 		if (mddev->persistent) {
 			if (mddev->major_version != 0 ||
@@ -5722,19 +6024,19 @@
 	return 0;
 }
 
-static int is_mddev_idle(mddev_t *mddev)
+static int is_mddev_idle(mddev_t *mddev, int init)
 {
 	mdk_rdev_t * rdev;
 	int idle;
-	long curr_events;
+	int curr_events;
 
 	idle = 1;
 	rcu_read_lock();
 	rdev_for_each_rcu(rdev, mddev) {
 		struct gendisk *disk = rdev->bdev->bd_contains->bd_disk;
-		curr_events = part_stat_read(&disk->part0, sectors[0]) +
-				part_stat_read(&disk->part0, sectors[1]) -
-				atomic_read(&disk->sync_io);
+		curr_events = (int)part_stat_read(&disk->part0, sectors[0]) +
+			      (int)part_stat_read(&disk->part0, sectors[1]) -
+			      atomic_read(&disk->sync_io);
 		/* sync IO will cause sync_io to increase before the disk_stats
 		 * as sync_io is counted when a request starts, and
 		 * disk_stats is counted when it completes.
@@ -5757,7 +6059,7 @@
 		 * always make curr_events less than last_events.
 		 *
 		 */
-		if (curr_events - rdev->last_events > 4096) {
+		if (init || curr_events - rdev->last_events > 64) {
 			rdev->last_events = curr_events;
 			idle = 0;
 		}
@@ -5980,10 +6282,10 @@
 			j = mddev->recovery_cp;
 
 	} else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
-		max_sectors = mddev->size << 1;
+		max_sectors = mddev->dev_sectors;
 	else {
 		/* recovery follows the physical size of devices */
-		max_sectors = mddev->size << 1;
+		max_sectors = mddev->dev_sectors;
 		j = MaxSector;
 		list_for_each_entry(rdev, &mddev->disks, same_set)
 			if (rdev->raid_disk >= 0 &&
@@ -6000,7 +6302,7 @@
 	       "(but not more than %d KB/sec) for %s.\n",
 	       speed_max(mddev), desc);
 
-	is_mddev_idle(mddev); /* this also initializes IO event counters */
+	is_mddev_idle(mddev, 1); /* this initializes IO event counters */
 
 	io_sectors = 0;
 	for (m = 0; m < SYNC_MARKS; m++) {
@@ -6040,6 +6342,18 @@
 		}
 		if (kthread_should_stop())
 			goto interrupted;
+
+		if (mddev->curr_resync > mddev->curr_resync_completed &&
+		    (mddev->curr_resync - mddev->curr_resync_completed)
+		    > (max_sectors >> 4)) {
+			/* time to update curr_resync_completed */
+			blk_unplug(mddev->queue);
+			wait_event(mddev->recovery_wait,
+				   atomic_read(&mddev->recovery_active) == 0);
+			mddev->curr_resync_completed =
+				mddev->curr_resync;
+			set_bit(MD_CHANGE_CLEAN, &mddev->flags);
+		}
 		sectors = mddev->pers->sync_request(mddev, j, &skipped,
 						  currspeed < speed_min(mddev));
 		if (sectors == 0) {
@@ -6102,7 +6416,7 @@
 
 		if (currspeed > speed_min(mddev)) {
 			if ((currspeed > speed_max(mddev)) ||
-					!is_mddev_idle(mddev)) {
+					!is_mddev_idle(mddev, 0)) {
 				msleep(500);
 				goto repeat;
 			}
@@ -6173,6 +6487,8 @@
 	mdk_rdev_t *rdev;
 	int spares = 0;
 
+	mddev->curr_resync_completed = 0;
+
 	list_for_each_entry(rdev, &mddev->disks, same_set)
 		if (rdev->raid_disk >= 0 &&
 		    !test_bit(Blocked, &rdev->flags) &&
@@ -6327,6 +6643,9 @@
 					sysfs_notify(&mddev->kobj, NULL,
 						     "degraded");
 			}
+			if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) &&
+			    mddev->pers->finish_reshape)
+				mddev->pers->finish_reshape(mddev);
 			md_update_sb(mddev, 1);
 
 			/* if array is no-longer degraded, then any saved_raid_disk
@@ -6470,13 +6789,13 @@
 
 static int __init md_init(void)
 {
-	if (register_blkdev(MAJOR_NR, "md"))
+	if (register_blkdev(MD_MAJOR, "md"))
 		return -1;
 	if ((mdp_major=register_blkdev(0, "mdp"))<=0) {
-		unregister_blkdev(MAJOR_NR, "md");
+		unregister_blkdev(MD_MAJOR, "md");
 		return -1;
 	}
-	blk_register_region(MKDEV(MAJOR_NR, 0), 1UL<<MINORBITS, THIS_MODULE,
+	blk_register_region(MKDEV(MD_MAJOR, 0), 1UL<<MINORBITS, THIS_MODULE,
 			    md_probe, NULL, NULL);
 	blk_register_region(MKDEV(mdp_major, 0), 1UL<<MINORBITS, THIS_MODULE,
 			    md_probe, NULL, NULL);
@@ -6562,10 +6881,10 @@
 	mddev_t *mddev;
 	struct list_head *tmp;
 
-	blk_unregister_region(MKDEV(MAJOR_NR,0), 1U << MINORBITS);
+	blk_unregister_region(MKDEV(MD_MAJOR,0), 1U << MINORBITS);
 	blk_unregister_region(MKDEV(mdp_major,0), 1U << MINORBITS);
 
-	unregister_blkdev(MAJOR_NR,"md");
+	unregister_blkdev(MD_MAJOR,"md");
 	unregister_blkdev(mdp_major, "mdp");
 	unregister_reboot_notifier(&md_notifier);
 	unregister_sysctl_table(raid_table_header);
diff --git a/drivers/md/md.h b/drivers/md/md.h
new file mode 100644
index 0000000..e9b7f54
--- /dev/null
+++ b/drivers/md/md.h
@@ -0,0 +1,436 @@
+/*
+   md_k.h : kernel internal structure of the Linux MD driver
+          Copyright (C) 1996-98 Ingo Molnar, Gadi Oxman
+	  
+   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.
+   
+   You should have received a copy of the GNU General Public License
+   (for example /usr/src/linux/COPYING); if not, write to the Free
+   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
+*/
+
+#ifndef _MD_K_H
+#define _MD_K_H
+
+#ifdef CONFIG_BLOCK
+
+#define MaxSector (~(sector_t)0)
+
+typedef struct mddev_s mddev_t;
+typedef struct mdk_rdev_s mdk_rdev_t;
+
+/*
+ * options passed in raidrun:
+ */
+
+/* Currently this must fit in an 'int' */
+#define MAX_CHUNK_SIZE (1<<30)
+
+/*
+ * MD's 'extended' device
+ */
+struct mdk_rdev_s
+{
+	struct list_head same_set;	/* RAID devices within the same set */
+
+	sector_t sectors;		/* Device size (in 512bytes sectors) */
+	mddev_t *mddev;			/* RAID array if running */
+	int last_events;		/* IO event timestamp */
+
+	struct block_device *bdev;	/* block device handle */
+
+	struct page	*sb_page;
+	int		sb_loaded;
+	__u64		sb_events;
+	sector_t	data_offset;	/* start of data in array */
+	sector_t 	sb_start;	/* offset of the super block (in 512byte sectors) */
+	int		sb_size;	/* bytes in the superblock */
+	int		preferred_minor;	/* autorun support */
+
+	struct kobject	kobj;
+
+	/* A device can be in one of three states based on two flags:
+	 * Not working:   faulty==1 in_sync==0
+	 * Fully working: faulty==0 in_sync==1
+	 * Working, but not
+	 * in sync with array
+	 *                faulty==0 in_sync==0
+	 *
+	 * It can never have faulty==1, in_sync==1
+	 * This reduces the burden of testing multiple flags in many cases
+	 */
+
+	unsigned long	flags;
+#define	Faulty		1		/* device is known to have a fault */
+#define	In_sync		2		/* device is in_sync with rest of array */
+#define	WriteMostly	4		/* Avoid reading if at all possible */
+#define	BarriersNotsupp	5		/* BIO_RW_BARRIER is not supported */
+#define	AllReserved	6		/* If whole device is reserved for
+					 * one array */
+#define	AutoDetected	7		/* added by auto-detect */
+#define Blocked		8		/* An error occured on an externally
+					 * managed array, don't allow writes
+					 * until it is cleared */
+#define StateChanged	9		/* Faulty or Blocked has changed during
+					 * interrupt, so it needs to be
+					 * notified by the thread */
+	wait_queue_head_t blocked_wait;
+
+	int desc_nr;			/* descriptor index in the superblock */
+	int raid_disk;			/* role of device in array */
+	int saved_raid_disk;		/* role that device used to have in the
+					 * array and could again if we did a partial
+					 * resync from the bitmap
+					 */
+	sector_t	recovery_offset;/* If this device has been partially
+					 * recovered, this is where we were
+					 * up to.
+					 */
+
+	atomic_t	nr_pending;	/* number of pending requests.
+					 * only maintained for arrays that
+					 * support hot removal
+					 */
+	atomic_t	read_errors;	/* number of consecutive read errors that
+					 * we have tried to ignore.
+					 */
+	atomic_t	corrected_errors; /* number of corrected read errors,
+					   * for reporting to userspace and storing
+					   * in superblock.
+					   */
+	struct work_struct del_work;	/* used for delayed sysfs removal */
+
+	struct sysfs_dirent *sysfs_state; /* handle for 'state'
+					   * sysfs entry */
+};
+
+struct mddev_s
+{
+	void				*private;
+	struct mdk_personality		*pers;
+	dev_t				unit;
+	int				md_minor;
+	struct list_head 		disks;
+	unsigned long			flags;
+#define MD_CHANGE_DEVS	0	/* Some device status has changed */
+#define MD_CHANGE_CLEAN 1	/* transition to or from 'clean' */
+#define MD_CHANGE_PENDING 2	/* superblock update in progress */
+
+	int				suspended;
+	atomic_t			active_io;
+	int				ro;
+
+	struct gendisk			*gendisk;
+
+	struct kobject			kobj;
+	int				hold_active;
+#define	UNTIL_IOCTL	1
+#define	UNTIL_STOP	2
+
+	/* Superblock information */
+	int				major_version,
+					minor_version,
+					patch_version;
+	int				persistent;
+	int 				external;	/* metadata is
+							 * managed externally */
+	char				metadata_type[17]; /* externally set*/
+	int				chunk_size;
+	time_t				ctime, utime;
+	int				level, layout;
+	char				clevel[16];
+	int				raid_disks;
+	int				max_disks;
+	sector_t			dev_sectors; 	/* used size of
+							 * component devices */
+	sector_t			array_sectors; /* exported array size */
+	int				external_size; /* size managed
+							* externally */
+	__u64				events;
+
+	char				uuid[16];
+
+	/* If the array is being reshaped, we need to record the
+	 * new shape and an indication of where we are up to.
+	 * This is written to the superblock.
+	 * If reshape_position is MaxSector, then no reshape is happening (yet).
+	 */
+	sector_t			reshape_position;
+	int				delta_disks, new_level, new_layout, new_chunk;
+
+	struct mdk_thread_s		*thread;	/* management thread */
+	struct mdk_thread_s		*sync_thread;	/* doing resync or reconstruct */
+	sector_t			curr_resync;	/* last block scheduled */
+	/* As resync requests can complete out of order, we cannot easily track
+	 * how much resync has been completed.  So we occasionally pause until
+	 * everything completes, then set curr_resync_completed to curr_resync.
+	 * As such it may be well behind the real resync mark, but it is a value
+	 * we are certain of.
+	 */
+	sector_t			curr_resync_completed;
+	unsigned long			resync_mark;	/* a recent timestamp */
+	sector_t			resync_mark_cnt;/* blocks written at resync_mark */
+	sector_t			curr_mark_cnt; /* blocks scheduled now */
+
+	sector_t			resync_max_sectors; /* may be set by personality */
+
+	sector_t			resync_mismatches; /* count of sectors where
+							    * parity/replica mismatch found
+							    */
+
+	/* allow user-space to request suspension of IO to regions of the array */
+	sector_t			suspend_lo;
+	sector_t			suspend_hi;
+	/* if zero, use the system-wide default */
+	int				sync_speed_min;
+	int				sync_speed_max;
+
+	/* resync even though the same disks are shared among md-devices */
+	int				parallel_resync;
+
+	int				ok_start_degraded;
+	/* recovery/resync flags 
+	 * NEEDED:   we might need to start a resync/recover
+	 * RUNNING:  a thread is running, or about to be started
+	 * SYNC:     actually doing a resync, not a recovery
+	 * RECOVER:  doing recovery, or need to try it.
+	 * INTR:     resync needs to be aborted for some reason
+	 * DONE:     thread is done and is waiting to be reaped
+	 * REQUEST:  user-space has requested a sync (used with SYNC)
+	 * CHECK:    user-space request for for check-only, no repair
+	 * RESHAPE:  A reshape is happening
+	 *
+	 * If neither SYNC or RESHAPE are set, then it is a recovery.
+	 */
+#define	MD_RECOVERY_RUNNING	0
+#define	MD_RECOVERY_SYNC	1
+#define	MD_RECOVERY_RECOVER	2
+#define	MD_RECOVERY_INTR	3
+#define	MD_RECOVERY_DONE	4
+#define	MD_RECOVERY_NEEDED	5
+#define	MD_RECOVERY_REQUESTED	6
+#define	MD_RECOVERY_CHECK	7
+#define MD_RECOVERY_RESHAPE	8
+#define	MD_RECOVERY_FROZEN	9
+
+	unsigned long			recovery;
+	int				recovery_disabled; /* if we detect that recovery
+							    * will always fail, set this
+							    * so we don't loop trying */
+
+	int				in_sync;	/* know to not need resync */
+	struct mutex			reconfig_mutex;
+	atomic_t			active;		/* general refcount */
+	atomic_t			openers;	/* number of active opens */
+
+	int				changed;	/* true if we might need to reread partition info */
+	int				degraded;	/* whether md should consider
+							 * adding a spare
+							 */
+	int				barriers_work;	/* initialised to true, cleared as soon
+							 * as a barrier request to slave
+							 * fails.  Only supported
+							 */
+	struct bio			*biolist; 	/* bios that need to be retried
+							 * because BIO_RW_BARRIER is not supported
+							 */
+
+	atomic_t			recovery_active; /* blocks scheduled, but not written */
+	wait_queue_head_t		recovery_wait;
+	sector_t			recovery_cp;
+	sector_t			resync_min;	/* user requested sync
+							 * starts here */
+	sector_t			resync_max;	/* resync should pause
+							 * when it gets here */
+
+	struct sysfs_dirent		*sysfs_state;	/* handle for 'array_state'
+							 * file in sysfs.
+							 */
+	struct sysfs_dirent		*sysfs_action;  /* handle for 'sync_action' */
+
+	struct work_struct del_work;	/* used for delayed sysfs removal */
+
+	spinlock_t			write_lock;
+	wait_queue_head_t		sb_wait;	/* for waiting on superblock updates */
+	atomic_t			pending_writes;	/* number of active superblock writes */
+
+	unsigned int			safemode;	/* if set, update "clean" superblock
+							 * when no writes pending.
+							 */ 
+	unsigned int			safemode_delay;
+	struct timer_list		safemode_timer;
+	atomic_t			writes_pending; 
+	struct request_queue		*queue;	/* for plugging ... */
+
+	atomic_t                        write_behind; /* outstanding async IO */
+	unsigned int                    max_write_behind; /* 0 = sync */
+
+	struct bitmap                   *bitmap; /* the bitmap for the device */
+	struct file			*bitmap_file; /* the bitmap file */
+	long				bitmap_offset; /* offset from superblock of
+							* start of bitmap. May be
+							* negative, but not '0'
+							*/
+	long				default_bitmap_offset; /* this is the offset to use when
+								* hot-adding a bitmap.  It should
+								* eventually be settable by sysfs.
+								*/
+
+	struct list_head		all_mddevs;
+};
+
+
+static inline void rdev_dec_pending(mdk_rdev_t *rdev, mddev_t *mddev)
+{
+	int faulty = test_bit(Faulty, &rdev->flags);
+	if (atomic_dec_and_test(&rdev->nr_pending) && faulty)
+		set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+}
+
+static inline void md_sync_acct(struct block_device *bdev, unsigned long nr_sectors)
+{
+        atomic_add(nr_sectors, &bdev->bd_contains->bd_disk->sync_io);
+}
+
+struct mdk_personality
+{
+	char *name;
+	int level;
+	struct list_head list;
+	struct module *owner;
+	int (*make_request)(struct request_queue *q, struct bio *bio);
+	int (*run)(mddev_t *mddev);
+	int (*stop)(mddev_t *mddev);
+	void (*status)(struct seq_file *seq, mddev_t *mddev);
+	/* error_handler must set ->faulty and clear ->in_sync
+	 * if appropriate, and should abort recovery if needed 
+	 */
+	void (*error_handler)(mddev_t *mddev, mdk_rdev_t *rdev);
+	int (*hot_add_disk) (mddev_t *mddev, mdk_rdev_t *rdev);
+	int (*hot_remove_disk) (mddev_t *mddev, int number);
+	int (*spare_active) (mddev_t *mddev);
+	sector_t (*sync_request)(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster);
+	int (*resize) (mddev_t *mddev, sector_t sectors);
+	sector_t (*size) (mddev_t *mddev, sector_t sectors, int raid_disks);
+	int (*check_reshape) (mddev_t *mddev);
+	int (*start_reshape) (mddev_t *mddev);
+	void (*finish_reshape) (mddev_t *mddev);
+	int (*reconfig) (mddev_t *mddev, int layout, int chunk_size);
+	/* quiesce moves between quiescence states
+	 * 0 - fully active
+	 * 1 - no new requests allowed
+	 * others - reserved
+	 */
+	void (*quiesce) (mddev_t *mddev, int state);
+	/* takeover is used to transition an array from one
+	 * personality to another.  The new personality must be able
+	 * to handle the data in the current layout.
+	 * e.g. 2drive raid1 -> 2drive raid5
+	 *      ndrive raid5 -> degraded n+1drive raid6 with special layout
+	 * If the takeover succeeds, a new 'private' structure is returned.
+	 * This needs to be installed and then ->run used to activate the
+	 * array.
+	 */
+	void *(*takeover) (mddev_t *mddev);
+};
+
+
+struct md_sysfs_entry {
+	struct attribute attr;
+	ssize_t (*show)(mddev_t *, char *);
+	ssize_t (*store)(mddev_t *, const char *, size_t);
+};
+
+
+static inline char * mdname (mddev_t * mddev)
+{
+	return mddev->gendisk ? mddev->gendisk->disk_name : "mdX";
+}
+
+/*
+ * iterates through some rdev ringlist. It's safe to remove the
+ * current 'rdev'. Dont touch 'tmp' though.
+ */
+#define rdev_for_each_list(rdev, tmp, head)				\
+	list_for_each_entry_safe(rdev, tmp, head, same_set)
+
+/*
+ * iterates through the 'same array disks' ringlist
+ */
+#define rdev_for_each(rdev, tmp, mddev)				\
+	list_for_each_entry_safe(rdev, tmp, &((mddev)->disks), same_set)
+
+#define rdev_for_each_rcu(rdev, mddev)				\
+	list_for_each_entry_rcu(rdev, &((mddev)->disks), same_set)
+
+typedef struct mdk_thread_s {
+	void			(*run) (mddev_t *mddev);
+	mddev_t			*mddev;
+	wait_queue_head_t	wqueue;
+	unsigned long           flags;
+	struct task_struct	*tsk;
+	unsigned long		timeout;
+} mdk_thread_t;
+
+#define THREAD_WAKEUP  0
+
+#define __wait_event_lock_irq(wq, condition, lock, cmd) 		\
+do {									\
+	wait_queue_t __wait;						\
+	init_waitqueue_entry(&__wait, current);				\
+									\
+	add_wait_queue(&wq, &__wait);					\
+	for (;;) {							\
+		set_current_state(TASK_UNINTERRUPTIBLE);		\
+		if (condition)						\
+			break;						\
+		spin_unlock_irq(&lock);					\
+		cmd;							\
+		schedule();						\
+		spin_lock_irq(&lock);					\
+	}								\
+	current->state = TASK_RUNNING;					\
+	remove_wait_queue(&wq, &__wait);				\
+} while (0)
+
+#define wait_event_lock_irq(wq, condition, lock, cmd) 			\
+do {									\
+	if (condition)	 						\
+		break;							\
+	__wait_event_lock_irq(wq, condition, lock, cmd);		\
+} while (0)
+
+static inline void safe_put_page(struct page *p)
+{
+	if (p) put_page(p);
+}
+
+#endif /* CONFIG_BLOCK */
+#endif
+
+
+extern int register_md_personality(struct mdk_personality *p);
+extern int unregister_md_personality(struct mdk_personality *p);
+extern mdk_thread_t * md_register_thread(void (*run) (mddev_t *mddev),
+				mddev_t *mddev, const char *name);
+extern void md_unregister_thread(mdk_thread_t *thread);
+extern void md_wakeup_thread(mdk_thread_t *thread);
+extern void md_check_recovery(mddev_t *mddev);
+extern void md_write_start(mddev_t *mddev, struct bio *bi);
+extern void md_write_end(mddev_t *mddev);
+extern void md_done_sync(mddev_t *mddev, int blocks, int ok);
+extern void md_error(mddev_t *mddev, mdk_rdev_t *rdev);
+
+extern void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
+			   sector_t sector, int size, struct page *page);
+extern void md_super_wait(mddev_t *mddev);
+extern int sync_page_io(struct block_device *bdev, sector_t sector, int size,
+			struct page *page, int rw);
+extern void md_do_sync(mddev_t *mddev);
+extern void md_new_event(mddev_t *mddev);
+extern int md_allow_write(mddev_t *mddev);
+extern void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev);
+extern void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors);
diff --git a/drivers/md/mktables.c b/drivers/md/mktables.c
index b61d576..3b15008 100644
--- a/drivers/md/mktables.c
+++ b/drivers/md/mktables.c
@@ -59,7 +59,7 @@
 	uint8_t v;
 	uint8_t exptbl[256], invtbl[256];
 
-	printf("#include \"raid6.h\"\n");
+	printf("#include <linux/raid/pq.h>\n");
 
 	/* Compute multiplication table */
 	printf("\nconst u8  __attribute__((aligned(256)))\n"
@@ -76,6 +76,9 @@
 		printf("\t},\n");
 	}
 	printf("};\n");
+	printf("#ifdef __KERNEL__\n");
+	printf("EXPORT_SYMBOL(raid6_gfmul);\n");
+	printf("#endif\n");
 
 	/* Compute power-of-2 table (exponent) */
 	v = 1;
@@ -92,6 +95,9 @@
 		}
 	}
 	printf("};\n");
+	printf("#ifdef __KERNEL__\n");
+	printf("EXPORT_SYMBOL(raid6_gfexp);\n");
+	printf("#endif\n");
 
 	/* Compute inverse table x^-1 == x^254 */
 	printf("\nconst u8 __attribute__((aligned(256)))\n"
@@ -104,6 +110,9 @@
 		}
 	}
 	printf("};\n");
+	printf("#ifdef __KERNEL__\n");
+	printf("EXPORT_SYMBOL(raid6_gfinv);\n");
+	printf("#endif\n");
 
 	/* Compute inv(2^x + 1) (exponent-xor-inverse) table */
 	printf("\nconst u8 __attribute__((aligned(256)))\n"
@@ -115,6 +124,9 @@
 			       (j == 7) ? '\n' : ' ');
 	}
 	printf("};\n");
+	printf("#ifdef __KERNEL__\n");
+	printf("EXPORT_SYMBOL(raid6_gfexi);\n");
+	printf("#endif\n");
 
 	return 0;
 }
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index f6d08f2..41ced0c 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -19,7 +19,11 @@
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/raid/multipath.h>
+#include <linux/blkdev.h>
+#include <linux/raid/md_u.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "multipath.h"
 
 #define MAX_WORK_PER_DISK 128
 
@@ -402,6 +406,14 @@
 	spin_unlock_irqrestore(&conf->device_lock, flags);
 }
 
+static sector_t multipath_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+	WARN_ONCE(sectors || raid_disks,
+		  "%s does not support generic reshape\n", __func__);
+
+	return mddev->dev_sectors;
+}
+
 static int multipath_run (mddev_t *mddev)
 {
 	multipath_conf_t *conf;
@@ -498,7 +510,7 @@
 	/*
 	 * Ok, everything is just fine now
 	 */
-	mddev->array_sectors = mddev->size * 2;
+	md_set_array_sectors(mddev, multipath_size(mddev, 0, 0));
 
 	mddev->queue->unplug_fn = multipath_unplug;
 	mddev->queue->backing_dev_info.congested_fn = multipath_congested;
@@ -543,6 +555,7 @@
 	.error_handler	= multipath_error,
 	.hot_add_disk	= multipath_add_disk,
 	.hot_remove_disk= multipath_remove_disk,
+	.size		= multipath_size,
 };
 
 static int __init multipath_init (void)
diff --git a/drivers/md/multipath.h b/drivers/md/multipath.h
new file mode 100644
index 0000000..6fa70b4
--- /dev/null
+++ b/drivers/md/multipath.h
@@ -0,0 +1,40 @@
+#ifndef _MULTIPATH_H
+#define _MULTIPATH_H
+
+struct multipath_info {
+	mdk_rdev_t	*rdev;
+};
+
+struct multipath_private_data {
+	mddev_t			*mddev;
+	struct multipath_info	*multipaths;
+	int			raid_disks;
+	int			working_disks;
+	spinlock_t		device_lock;
+	struct list_head	retry_list;
+
+	mempool_t		*pool;
+};
+
+typedef struct multipath_private_data multipath_conf_t;
+
+/*
+ * this is the only point in the RAID code where we violate
+ * C type safety. mddev->private is an 'opaque' pointer.
+ */
+#define mddev_to_conf(mddev) ((multipath_conf_t *) mddev->private)
+
+/*
+ * this is our 'private' 'collective' MULTIPATH buffer head.
+ * it contains information about what kind of IO operations were started
+ * for this MULTIPATH operation, and about their status:
+ */
+
+struct multipath_bh {
+	mddev_t			*mddev;
+	struct bio		*master_bio;
+	struct bio		bio;
+	int			path;
+	struct list_head	retry_list;
+};
+#endif
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index c605ba8..c08d7559 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -18,7 +18,10 @@
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
 */
 
-#include <linux/raid/raid0.h>
+#include <linux/blkdev.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "raid0.h"
 
 static void raid0_unplug(struct request_queue *q)
 {
@@ -73,16 +76,15 @@
 		list_for_each_entry(rdev2, &mddev->disks, same_set) {
 			printk(KERN_INFO "raid0:   comparing %s(%llu)",
 			       bdevname(rdev1->bdev,b),
-			       (unsigned long long)rdev1->size);
+			       (unsigned long long)rdev1->sectors);
 			printk(KERN_INFO " with %s(%llu)\n",
 			       bdevname(rdev2->bdev,b),
-			       (unsigned long long)rdev2->size);
+			       (unsigned long long)rdev2->sectors);
 			if (rdev2 == rdev1) {
 				printk(KERN_INFO "raid0:   END\n");
 				break;
 			}
-			if (rdev2->size == rdev1->size)
-			{
+			if (rdev2->sectors == rdev1->sectors) {
 				/*
 				 * Not unique, don't count it as a new
 				 * group
@@ -145,7 +147,7 @@
 		    mddev->queue->max_sectors > (PAGE_SIZE>>9))
 			blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
 
-		if (!smallest || (rdev1->size <smallest->size))
+		if (!smallest || (rdev1->sectors < smallest->sectors))
 			smallest = rdev1;
 		cnt++;
 	}
@@ -155,10 +157,10 @@
 		goto abort;
 	}
 	zone->nb_dev = cnt;
-	zone->sectors = smallest->size * cnt * 2;
+	zone->sectors = smallest->sectors * cnt;
 	zone->zone_start = 0;
 
-	current_start = smallest->size * 2;
+	current_start = smallest->sectors;
 	curr_zone_start = zone->sectors;
 
 	/* now do the other zones */
@@ -177,29 +179,29 @@
 			rdev = conf->strip_zone[0].dev[j];
 			printk(KERN_INFO "raid0: checking %s ...",
 				bdevname(rdev->bdev, b));
-			if (rdev->size > current_start / 2) {
-				printk(KERN_INFO " contained as device %d\n",
-					c);
-				zone->dev[c] = rdev;
-				c++;
-				if (!smallest || (rdev->size <smallest->size)) {
-					smallest = rdev;
-					printk(KERN_INFO "  (%llu) is smallest!.\n",
-						(unsigned long long)rdev->size);
-				}
-			} else
+			if (rdev->sectors <= current_start) {
 				printk(KERN_INFO " nope.\n");
+				continue;
+			}
+			printk(KERN_INFO " contained as device %d\n", c);
+			zone->dev[c] = rdev;
+			c++;
+			if (!smallest || rdev->sectors < smallest->sectors) {
+				smallest = rdev;
+				printk(KERN_INFO "  (%llu) is smallest!.\n",
+					(unsigned long long)rdev->sectors);
+			}
 		}
 
 		zone->nb_dev = c;
-		zone->sectors = (smallest->size * 2 - current_start) * c;
+		zone->sectors = (smallest->sectors - current_start) * c;
 		printk(KERN_INFO "raid0: zone->nb_dev: %d, sectors: %llu\n",
 			zone->nb_dev, (unsigned long long)zone->sectors);
 
 		zone->zone_start = curr_zone_start;
 		curr_zone_start += zone->sectors;
 
-		current_start = smallest->size * 2;
+		current_start = smallest->sectors;
 		printk(KERN_INFO "raid0: current zone start: %llu\n",
 			(unsigned long long)current_start);
 	}
@@ -261,12 +263,25 @@
 		return max;
 }
 
+static sector_t raid0_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+	sector_t array_sectors = 0;
+	mdk_rdev_t *rdev;
+
+	WARN_ONCE(sectors || raid_disks,
+		  "%s does not support generic reshape\n", __func__);
+
+	list_for_each_entry(rdev, &mddev->disks, same_set)
+		array_sectors += rdev->sectors;
+
+	return array_sectors;
+}
+
 static int raid0_run (mddev_t *mddev)
 {
 	unsigned  cur=0, i=0, nb_zone;
 	s64 sectors;
 	raid0_conf_t *conf;
-	mdk_rdev_t *rdev;
 
 	if (mddev->chunk_size == 0) {
 		printk(KERN_ERR "md/raid0: non-zero chunk size required.\n");
@@ -291,16 +306,14 @@
 		goto out_free_conf;
 
 	/* calculate array device size */
-	mddev->array_sectors = 0;
-	list_for_each_entry(rdev, &mddev->disks, same_set)
-		mddev->array_sectors += rdev->size * 2;
+	md_set_array_sectors(mddev, raid0_size(mddev, 0, 0));
 
 	printk(KERN_INFO "raid0 : md_size is %llu sectors.\n",
 		(unsigned long long)mddev->array_sectors);
 	printk(KERN_INFO "raid0 : conf->spacing is %llu sectors.\n",
 		(unsigned long long)conf->spacing);
 	{
-		sector_t s = mddev->array_sectors;
+		sector_t s = raid0_size(mddev, 0, 0);
 		sector_t space = conf->spacing;
 		int round;
 		conf->sector_shift = 0;
@@ -509,6 +522,7 @@
 	.run		= raid0_run,
 	.stop		= raid0_stop,
 	.status		= raid0_status,
+	.size		= raid0_size,
 };
 
 static int __init raid0_init (void)
diff --git a/drivers/md/raid0.h b/drivers/md/raid0.h
new file mode 100644
index 0000000..824b12e
--- /dev/null
+++ b/drivers/md/raid0.h
@@ -0,0 +1,28 @@
+#ifndef _RAID0_H
+#define _RAID0_H
+
+struct strip_zone
+{
+	sector_t zone_start;	/* Zone offset in md_dev (in sectors) */
+	sector_t dev_start;	/* Zone offset in real dev (in sectors) */
+	sector_t sectors;	/* Zone size in sectors */
+	int nb_dev;		/* # of devices attached to the zone */
+	mdk_rdev_t **dev;	/* Devices attached to the zone */
+};
+
+struct raid0_private_data
+{
+	struct strip_zone **hash_table; /* Table of indexes into strip_zone */
+	struct strip_zone *strip_zone;
+	mdk_rdev_t **devlist; /* lists of rdevs, pointed to by strip_zone->dev */
+	int nr_strip_zones;
+
+	sector_t spacing;
+	int sector_shift; /* shift this before divide by spacing */
+};
+
+typedef struct raid0_private_data raid0_conf_t;
+
+#define mddev_to_conf(mddev) ((raid0_conf_t *) mddev->private)
+
+#endif
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index e246642..b4f4bad 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -31,10 +31,13 @@
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include "dm-bio-list.h"
 #include <linux/delay.h>
-#include <linux/raid/raid1.h>
-#include <linux/raid/bitmap.h>
+#include <linux/blkdev.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "dm-bio-list.h"
+#include "raid1.h"
+#include "bitmap.h"
 
 #define DEBUG 0
 #if DEBUG
@@ -1723,7 +1726,7 @@
 			return 0;
 	}
 
-	max_sector = mddev->size << 1;
+	max_sector = mddev->dev_sectors;
 	if (sector_nr >= max_sector) {
 		/* If we aborted, we need to abort the
 		 * sync on the 'current' bitmap chunk (there will
@@ -1919,6 +1922,14 @@
 	return nr_sectors;
 }
 
+static sector_t raid1_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+	if (sectors)
+		return sectors;
+
+	return mddev->dev_sectors;
+}
+
 static int run(mddev_t *mddev)
 {
 	conf_t *conf;
@@ -2048,7 +2059,7 @@
 	/*
 	 * Ok, everything is just fine now
 	 */
-	mddev->array_sectors = mddev->size * 2;
+	md_set_array_sectors(mddev, raid1_size(mddev, 0, 0));
 
 	mddev->queue->unplug_fn = raid1_unplug;
 	mddev->queue->backing_dev_info.congested_fn = raid1_congested;
@@ -2089,6 +2100,9 @@
 		/* need to kick something here to make sure I/O goes? */
 	}
 
+	raise_barrier(conf);
+	lower_barrier(conf);
+
 	md_unregister_thread(mddev->thread);
 	mddev->thread = NULL;
 	blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
@@ -2110,15 +2124,17 @@
 	 * any io in the removed space completes, but it hardly seems
 	 * worth it.
 	 */
-	mddev->array_sectors = sectors;
+	md_set_array_sectors(mddev, raid1_size(mddev, sectors, 0));
+	if (mddev->array_sectors > raid1_size(mddev, sectors, 0))
+		return -EINVAL;
 	set_capacity(mddev->gendisk, mddev->array_sectors);
 	mddev->changed = 1;
-	if (mddev->array_sectors / 2 > mddev->size &&
+	if (sectors > mddev->dev_sectors &&
 	    mddev->recovery_cp == MaxSector) {
-		mddev->recovery_cp = mddev->size << 1;
+		mddev->recovery_cp = mddev->dev_sectors;
 		set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
 	}
-	mddev->size = mddev->array_sectors / 2;
+	mddev->dev_sectors = sectors;
 	mddev->resync_max_sectors = sectors;
 	return 0;
 }
@@ -2264,6 +2280,7 @@
 	.spare_active	= raid1_spare_active,
 	.sync_request	= sync_request,
 	.resize		= raid1_resize,
+	.size		= raid1_size,
 	.check_reshape	= raid1_reshape,
 	.quiesce	= raid1_quiesce,
 };
diff --git a/drivers/md/raid1.h b/drivers/md/raid1.h
new file mode 100644
index 0000000..1620eea
--- /dev/null
+++ b/drivers/md/raid1.h
@@ -0,0 +1,132 @@
+#ifndef _RAID1_H
+#define _RAID1_H
+
+typedef struct mirror_info mirror_info_t;
+
+struct mirror_info {
+	mdk_rdev_t	*rdev;
+	sector_t	head_position;
+};
+
+/*
+ * memory pools need a pointer to the mddev, so they can force an unplug
+ * when memory is tight, and a count of the number of drives that the
+ * pool was allocated for, so they know how much to allocate and free.
+ * mddev->raid_disks cannot be used, as it can change while a pool is active
+ * These two datums are stored in a kmalloced struct.
+ */
+
+struct pool_info {
+	mddev_t *mddev;
+	int	raid_disks;
+};
+
+
+typedef struct r1bio_s r1bio_t;
+
+struct r1_private_data_s {
+	mddev_t			*mddev;
+	mirror_info_t		*mirrors;
+	int			raid_disks;
+	int			last_used;
+	sector_t		next_seq_sect;
+	spinlock_t		device_lock;
+
+	struct list_head	retry_list;
+	/* queue pending writes and submit them on unplug */
+	struct bio_list		pending_bio_list;
+	/* queue of writes that have been unplugged */
+	struct bio_list		flushing_bio_list;
+
+	/* for use when syncing mirrors: */
+
+	spinlock_t		resync_lock;
+	int			nr_pending;
+	int			nr_waiting;
+	int			nr_queued;
+	int			barrier;
+	sector_t		next_resync;
+	int			fullsync;  /* set to 1 if a full sync is needed,
+					    * (fresh device added).
+					    * Cleared when a sync completes.
+					    */
+
+	wait_queue_head_t	wait_barrier;
+
+	struct pool_info	*poolinfo;
+
+	struct page		*tmppage;
+
+	mempool_t *r1bio_pool;
+	mempool_t *r1buf_pool;
+};
+
+typedef struct r1_private_data_s conf_t;
+
+/*
+ * this is the only point in the RAID code where we violate
+ * C type safety. mddev->private is an 'opaque' pointer.
+ */
+#define mddev_to_conf(mddev) ((conf_t *) mddev->private)
+
+/*
+ * this is our 'private' RAID1 bio.
+ *
+ * it contains information about what kind of IO operations were started
+ * for this RAID1 operation, and about their status:
+ */
+
+struct r1bio_s {
+	atomic_t		remaining; /* 'have we finished' count,
+					    * used from IRQ handlers
+					    */
+	atomic_t		behind_remaining; /* number of write-behind ios remaining
+						 * in this BehindIO request
+						 */
+	sector_t		sector;
+	int			sectors;
+	unsigned long		state;
+	mddev_t			*mddev;
+	/*
+	 * original bio going to /dev/mdx
+	 */
+	struct bio		*master_bio;
+	/*
+	 * if the IO is in READ direction, then this is where we read
+	 */
+	int			read_disk;
+
+	struct list_head	retry_list;
+	struct bitmap_update	*bitmap_update;
+	/*
+	 * if the IO is in WRITE direction, then multiple bios are used.
+	 * We choose the number when they are allocated.
+	 */
+	struct bio		*bios[0];
+	/* DO NOT PUT ANY NEW FIELDS HERE - bios array is contiguously alloced*/
+};
+
+/* when we get a read error on a read-only array, we redirect to another
+ * device without failing the first device, or trying to over-write to
+ * correct the read error.  To keep track of bad blocks on a per-bio
+ * level, we store IO_BLOCKED in the appropriate 'bios' pointer
+ */
+#define IO_BLOCKED ((struct bio*)1)
+
+/* bits for r1bio.state */
+#define	R1BIO_Uptodate	0
+#define	R1BIO_IsSync	1
+#define	R1BIO_Degraded	2
+#define	R1BIO_BehindIO	3
+#define	R1BIO_Barrier	4
+#define R1BIO_BarrierRetry 5
+/* For write-behind requests, we call bi_end_io when
+ * the last non-write-behind device completes, providing
+ * any write was successful.  Otherwise we call when
+ * any write-behind write succeeds, otherwise we call
+ * with failure when last write completes (and all failed).
+ * Record that bi_end_io was called with this flag...
+ */
+#define	R1BIO_Returned 6
+
+#endif
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 7301631..e293d92 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -18,10 +18,13 @@
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include "dm-bio-list.h"
 #include <linux/delay.h>
-#include <linux/raid/raid10.h>
-#include <linux/raid/bitmap.h>
+#include <linux/blkdev.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "dm-bio-list.h"
+#include "raid10.h"
+#include "bitmap.h"
 
 /*
  * RAID10 provides a combination of RAID0 and RAID1 functionality.
@@ -1695,7 +1698,7 @@
 			return 0;
 
  skipped:
-	max_sector = mddev->size << 1;
+	max_sector = mddev->dev_sectors;
 	if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
 		max_sector = mddev->resync_max_sectors;
 	if (sector_nr >= max_sector) {
@@ -2020,6 +2023,25 @@
 	goto skipped;
 }
 
+static sector_t
+raid10_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+	sector_t size;
+	conf_t *conf = mddev_to_conf(mddev);
+
+	if (!raid_disks)
+		raid_disks = mddev->raid_disks;
+	if (!sectors)
+		sectors = mddev->dev_sectors;
+
+	size = sectors >> conf->chunk_shift;
+	sector_div(size, conf->far_copies);
+	size = size * raid_disks;
+	sector_div(size, conf->near_copies);
+
+	return size << conf->chunk_shift;
+}
+
 static int run(mddev_t *mddev)
 {
 	conf_t *conf;
@@ -2076,7 +2098,7 @@
 	conf->far_offset = fo;
 	conf->chunk_mask = (sector_t)(mddev->chunk_size>>9)-1;
 	conf->chunk_shift = ffz(~mddev->chunk_size) - 9;
-	size = mddev->size >> (conf->chunk_shift-1);
+	size = mddev->dev_sectors >> conf->chunk_shift;
 	sector_div(size, fc);
 	size = size * conf->raid_disks;
 	sector_div(size, nc);
@@ -2089,7 +2111,7 @@
 	 */
 	stride += conf->raid_disks - 1;
 	sector_div(stride, conf->raid_disks);
-	mddev->size = stride  << (conf->chunk_shift-1);
+	mddev->dev_sectors = stride << conf->chunk_shift;
 
 	if (fo)
 		stride = 1;
@@ -2171,8 +2193,8 @@
 	/*
 	 * Ok, everything is just fine now
 	 */
-	mddev->array_sectors = size << conf->chunk_shift;
-	mddev->resync_max_sectors = size << conf->chunk_shift;
+	md_set_array_sectors(mddev, raid10_size(mddev, 0, 0));
+	mddev->resync_max_sectors = raid10_size(mddev, 0, 0);
 
 	mddev->queue->unplug_fn = raid10_unplug;
 	mddev->queue->backing_dev_info.congested_fn = raid10_congested;
@@ -2208,6 +2230,9 @@
 {
 	conf_t *conf = mddev_to_conf(mddev);
 
+	raise_barrier(conf, 0);
+	lower_barrier(conf);
+
 	md_unregister_thread(mddev->thread);
 	mddev->thread = NULL;
 	blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
@@ -2255,6 +2280,7 @@
 	.spare_active	= raid10_spare_active,
 	.sync_request	= sync_request,
 	.quiesce	= raid10_quiesce,
+	.size		= raid10_size,
 };
 
 static int __init raid_init(void)
diff --git a/drivers/md/raid10.h b/drivers/md/raid10.h
new file mode 100644
index 0000000..244dbe5
--- /dev/null
+++ b/drivers/md/raid10.h
@@ -0,0 +1,121 @@
+#ifndef _RAID10_H
+#define _RAID10_H
+
+typedef struct mirror_info mirror_info_t;
+
+struct mirror_info {
+	mdk_rdev_t	*rdev;
+	sector_t	head_position;
+};
+
+typedef struct r10bio_s r10bio_t;
+
+struct r10_private_data_s {
+	mddev_t			*mddev;
+	mirror_info_t		*mirrors;
+	int			raid_disks;
+	spinlock_t		device_lock;
+
+	/* geometry */
+	int			near_copies;  /* number of copies layed out raid0 style */
+	int 			far_copies;   /* number of copies layed out
+					       * at large strides across drives
+					       */
+	int			far_offset;   /* far_copies are offset by 1 stripe
+					       * instead of many
+					       */
+	int			copies;	      /* near_copies * far_copies.
+					       * must be <= raid_disks
+					       */
+	sector_t		stride;	      /* distance between far copies.
+					       * This is size / far_copies unless
+					       * far_offset, in which case it is
+					       * 1 stripe.
+					       */
+
+	int chunk_shift; /* shift from chunks to sectors */
+	sector_t chunk_mask;
+
+	struct list_head	retry_list;
+	/* queue pending writes and submit them on unplug */
+	struct bio_list		pending_bio_list;
+
+
+	spinlock_t		resync_lock;
+	int nr_pending;
+	int nr_waiting;
+	int nr_queued;
+	int barrier;
+	sector_t		next_resync;
+	int			fullsync;  /* set to 1 if a full sync is needed,
+					    * (fresh device added).
+					    * Cleared when a sync completes.
+					    */
+
+	wait_queue_head_t	wait_barrier;
+
+	mempool_t *r10bio_pool;
+	mempool_t *r10buf_pool;
+	struct page		*tmppage;
+};
+
+typedef struct r10_private_data_s conf_t;
+
+/*
+ * this is the only point in the RAID code where we violate
+ * C type safety. mddev->private is an 'opaque' pointer.
+ */
+#define mddev_to_conf(mddev) ((conf_t *) mddev->private)
+
+/*
+ * this is our 'private' RAID10 bio.
+ *
+ * it contains information about what kind of IO operations were started
+ * for this RAID10 operation, and about their status:
+ */
+
+struct r10bio_s {
+	atomic_t		remaining; /* 'have we finished' count,
+					    * used from IRQ handlers
+					    */
+	sector_t		sector;	/* virtual sector number */
+	int			sectors;
+	unsigned long		state;
+	mddev_t			*mddev;
+	/*
+	 * original bio going to /dev/mdx
+	 */
+	struct bio		*master_bio;
+	/*
+	 * if the IO is in READ direction, then this is where we read
+	 */
+	int			read_slot;
+
+	struct list_head	retry_list;
+	/*
+	 * if the IO is in WRITE direction, then multiple bios are used,
+	 * one for each copy.
+	 * When resyncing we also use one for each copy.
+	 * When reconstructing, we use 2 bios, one for read, one for write.
+	 * We choose the number when they are allocated.
+	 */
+	struct {
+		struct bio		*bio;
+		sector_t addr;
+		int devnum;
+	} devs[0];
+};
+
+/* when we get a read error on a read-only array, we redirect to another
+ * device without failing the first device, or trying to over-write to
+ * correct the read error.  To keep track of bad blocks on a per-bio
+ * level, we store IO_BLOCKED in the appropriate 'bios' pointer
+ */
+#define IO_BLOCKED ((struct bio*)1)
+
+/* bits for r10bio.state */
+#define	R10BIO_Uptodate	0
+#define	R10BIO_IsSync	1
+#define	R10BIO_IsRecover 2
+#define	R10BIO_Degraded 3
+#endif
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index a5ba080..3bbc6d6 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -43,11 +43,14 @@
  * miss any bits.
  */
 
+#include <linux/blkdev.h>
 #include <linux/kthread.h>
-#include "raid6.h"
-
-#include <linux/raid/bitmap.h>
+#include <linux/raid/pq.h>
 #include <linux/async_tx.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "raid5.h"
+#include "bitmap.h"
 
 /*
  * Stripe cache
@@ -91,11 +94,6 @@
 
 #define printk_rl(args...) ((void) (printk_ratelimit() && printk(args)))
 
-#if !RAID6_USE_EMPTY_ZERO_PAGE
-/* In .bss so it's zeroed */
-const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(256)));
-#endif
-
 /*
  * We maintain a biased count of active stripes in the bottom 16 bits of
  * bi_phys_segments, and a count of processed stripes in the upper 16 bits
@@ -130,12 +128,42 @@
 	bio->bi_phys_segments = raid5_bi_phys_segments(bio) || (cnt << 16);
 }
 
+/* Find first data disk in a raid6 stripe */
+static inline int raid6_d0(struct stripe_head *sh)
+{
+	if (sh->ddf_layout)
+		/* ddf always start from first device */
+		return 0;
+	/* md starts just after Q block */
+	if (sh->qd_idx == sh->disks - 1)
+		return 0;
+	else
+		return sh->qd_idx + 1;
+}
 static inline int raid6_next_disk(int disk, int raid_disks)
 {
 	disk++;
 	return (disk < raid_disks) ? disk : 0;
 }
 
+/* When walking through the disks in a raid5, starting at raid6_d0,
+ * We need to map each disk to a 'slot', where the data disks are slot
+ * 0 .. raid_disks-3, the parity disk is raid_disks-2 and the Q disk
+ * is raid_disks-1.  This help does that mapping.
+ */
+static int raid6_idx_to_slot(int idx, struct stripe_head *sh,
+			     int *count, int syndrome_disks)
+{
+	int slot;
+
+	if (idx == sh->pd_idx)
+		return syndrome_disks;
+	if (idx == sh->qd_idx)
+		return syndrome_disks + 1;
+	slot = (*count)++;
+	return slot;
+}
+
 static void return_io(struct bio *return_bi)
 {
 	struct bio *bi = return_bi;
@@ -193,6 +221,7 @@
 		}
 	}
 }
+
 static void release_stripe(struct stripe_head *sh)
 {
 	raid5_conf_t *conf = sh->raid_conf;
@@ -270,9 +299,11 @@
 	return 0;
 }
 
-static void raid5_build_block(struct stripe_head *sh, int i);
+static void raid5_build_block(struct stripe_head *sh, int i, int previous);
+static void stripe_set_idx(sector_t stripe, raid5_conf_t *conf, int previous,
+			    struct stripe_head *sh);
 
-static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int disks)
+static void init_stripe(struct stripe_head *sh, sector_t sector, int previous)
 {
 	raid5_conf_t *conf = sh->raid_conf;
 	int i;
@@ -287,11 +318,12 @@
 
 	remove_hash(sh);
 
+	sh->generation = conf->generation - previous;
+	sh->disks = previous ? conf->previous_raid_disks : conf->raid_disks;
 	sh->sector = sector;
-	sh->pd_idx = pd_idx;
+	stripe_set_idx(sector, conf, previous, sh);
 	sh->state = 0;
 
-	sh->disks = disks;
 
 	for (i = sh->disks; i--; ) {
 		struct r5dev *dev = &sh->dev[i];
@@ -305,12 +337,13 @@
 			BUG();
 		}
 		dev->flags = 0;
-		raid5_build_block(sh, i);
+		raid5_build_block(sh, i, previous);
 	}
 	insert_hash(conf, sh);
 }
 
-static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector, int disks)
+static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector,
+					 short generation)
 {
 	struct stripe_head *sh;
 	struct hlist_node *hn;
@@ -318,7 +351,7 @@
 	CHECK_DEVLOCK();
 	pr_debug("__find_stripe, sector %llu\n", (unsigned long long)sector);
 	hlist_for_each_entry(sh, hn, stripe_hash(conf, sector), hash)
-		if (sh->sector == sector && sh->disks == disks)
+		if (sh->sector == sector && sh->generation == generation)
 			return sh;
 	pr_debug("__stripe %llu not in cache\n", (unsigned long long)sector);
 	return NULL;
@@ -327,8 +360,9 @@
 static void unplug_slaves(mddev_t *mddev);
 static void raid5_unplug_device(struct request_queue *q);
 
-static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector, int disks,
-					     int pd_idx, int noblock)
+static struct stripe_head *
+get_active_stripe(raid5_conf_t *conf, sector_t sector,
+		  int previous, int noblock)
 {
 	struct stripe_head *sh;
 
@@ -340,7 +374,7 @@
 		wait_event_lock_irq(conf->wait_for_stripe,
 				    conf->quiesce == 0,
 				    conf->device_lock, /* nothing */);
-		sh = __find_stripe(conf, sector, disks);
+		sh = __find_stripe(conf, sector, conf->generation - previous);
 		if (!sh) {
 			if (!conf->inactive_blocked)
 				sh = get_free_stripe(conf);
@@ -358,10 +392,11 @@
 					);
 				conf->inactive_blocked = 0;
 			} else
-				init_stripe(sh, sector, pd_idx, disks);
+				init_stripe(sh, sector, previous);
 		} else {
 			if (atomic_read(&sh->count)) {
-			  BUG_ON(!list_empty(&sh->lru));
+				BUG_ON(!list_empty(&sh->lru)
+				    && !test_bit(STRIPE_EXPANDING, &sh->state));
 			} else {
 				if (!test_bit(STRIPE_HANDLE, &sh->state))
 					atomic_inc(&conf->active_stripes);
@@ -895,8 +930,10 @@
 	struct kmem_cache *sc;
 	int devs = conf->raid_disks;
 
-	sprintf(conf->cache_name[0], "raid5-%s", mdname(conf->mddev));
-	sprintf(conf->cache_name[1], "raid5-%s-alt", mdname(conf->mddev));
+	sprintf(conf->cache_name[0],
+		"raid%d-%s", conf->level, mdname(conf->mddev));
+	sprintf(conf->cache_name[1],
+		"raid%d-%s-alt", conf->level, mdname(conf->mddev));
 	conf->active_name = 0;
 	sc = kmem_cache_create(conf->cache_name[conf->active_name],
 			       sizeof(struct stripe_head)+(devs-1)*sizeof(struct r5dev),
@@ -911,7 +948,6 @@
 	return 0;
 }
 
-#ifdef CONFIG_MD_RAID5_RESHAPE
 static int resize_stripes(raid5_conf_t *conf, int newsize)
 {
 	/* Make all the stripes able to hold 'newsize' devices.
@@ -1036,7 +1072,6 @@
 	conf->pool_size = newsize;
 	return err;
 }
-#endif
 
 static int drop_one_stripe(raid5_conf_t *conf)
 {
@@ -1066,7 +1101,7 @@
 
 static void raid5_end_read_request(struct bio * bi, int error)
 {
- 	struct stripe_head *sh = bi->bi_private;
+	struct stripe_head *sh = bi->bi_private;
 	raid5_conf_t *conf = sh->raid_conf;
 	int disks = sh->disks, i;
 	int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags);
@@ -1148,7 +1183,7 @@
 
 static void raid5_end_write_request(struct bio *bi, int error)
 {
- 	struct stripe_head *sh = bi->bi_private;
+	struct stripe_head *sh = bi->bi_private;
 	raid5_conf_t *conf = sh->raid_conf;
 	int disks = sh->disks, i;
 	int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags);
@@ -1176,9 +1211,9 @@
 }
 
 
-static sector_t compute_blocknr(struct stripe_head *sh, int i);
+static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous);
 	
-static void raid5_build_block(struct stripe_head *sh, int i)
+static void raid5_build_block(struct stripe_head *sh, int i, int previous)
 {
 	struct r5dev *dev = &sh->dev[i];
 
@@ -1194,7 +1229,7 @@
 	dev->req.bi_private = sh;
 
 	dev->flags = 0;
-	dev->sector = compute_blocknr(sh, i);
+	dev->sector = compute_blocknr(sh, i, previous);
 }
 
 static void error(mddev_t *mddev, mdk_rdev_t *rdev)
@@ -1227,15 +1262,23 @@
  * Input: a 'big' sector number,
  * Output: index of the data and parity disk, and the sector # in them.
  */
-static sector_t raid5_compute_sector(sector_t r_sector, unsigned int raid_disks,
-			unsigned int data_disks, unsigned int * dd_idx,
-			unsigned int * pd_idx, raid5_conf_t *conf)
+static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
+				     int previous, int *dd_idx,
+				     struct stripe_head *sh)
 {
 	long stripe;
 	unsigned long chunk_number;
 	unsigned int chunk_offset;
+	int pd_idx, qd_idx;
+	int ddf_layout = 0;
 	sector_t new_sector;
-	int sectors_per_chunk = conf->chunk_size >> 9;
+	int algorithm = previous ? conf->prev_algo
+				 : conf->algorithm;
+	int sectors_per_chunk = previous ? (conf->prev_chunk >> 9)
+					 : (conf->chunk_size >> 9);
+	int raid_disks = previous ? conf->previous_raid_disks
+				  : conf->raid_disks;
+	int data_disks = raid_disks - conf->max_degraded;
 
 	/* First compute the information on this sector */
 
@@ -1259,68 +1302,170 @@
 	/*
 	 * Select the parity disk based on the user selected algorithm.
 	 */
+	pd_idx = qd_idx = ~0;
 	switch(conf->level) {
 	case 4:
-		*pd_idx = data_disks;
+		pd_idx = data_disks;
 		break;
 	case 5:
-		switch (conf->algorithm) {
+		switch (algorithm) {
 		case ALGORITHM_LEFT_ASYMMETRIC:
-			*pd_idx = data_disks - stripe % raid_disks;
-			if (*dd_idx >= *pd_idx)
+			pd_idx = data_disks - stripe % raid_disks;
+			if (*dd_idx >= pd_idx)
 				(*dd_idx)++;
 			break;
 		case ALGORITHM_RIGHT_ASYMMETRIC:
-			*pd_idx = stripe % raid_disks;
-			if (*dd_idx >= *pd_idx)
+			pd_idx = stripe % raid_disks;
+			if (*dd_idx >= pd_idx)
 				(*dd_idx)++;
 			break;
 		case ALGORITHM_LEFT_SYMMETRIC:
-			*pd_idx = data_disks - stripe % raid_disks;
-			*dd_idx = (*pd_idx + 1 + *dd_idx) % raid_disks;
+			pd_idx = data_disks - stripe % raid_disks;
+			*dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
 			break;
 		case ALGORITHM_RIGHT_SYMMETRIC:
-			*pd_idx = stripe % raid_disks;
-			*dd_idx = (*pd_idx + 1 + *dd_idx) % raid_disks;
+			pd_idx = stripe % raid_disks;
+			*dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
+			break;
+		case ALGORITHM_PARITY_0:
+			pd_idx = 0;
+			(*dd_idx)++;
+			break;
+		case ALGORITHM_PARITY_N:
+			pd_idx = data_disks;
 			break;
 		default:
 			printk(KERN_ERR "raid5: unsupported algorithm %d\n",
-				conf->algorithm);
+				algorithm);
+			BUG();
 		}
 		break;
 	case 6:
 
-		/**** FIX THIS ****/
-		switch (conf->algorithm) {
+		switch (algorithm) {
 		case ALGORITHM_LEFT_ASYMMETRIC:
-			*pd_idx = raid_disks - 1 - (stripe % raid_disks);
-			if (*pd_idx == raid_disks-1)
-				(*dd_idx)++; 	/* Q D D D P */
-			else if (*dd_idx >= *pd_idx)
+			pd_idx = raid_disks - 1 - (stripe % raid_disks);
+			qd_idx = pd_idx + 1;
+			if (pd_idx == raid_disks-1) {
+				(*dd_idx)++;	/* Q D D D P */
+				qd_idx = 0;
+			} else if (*dd_idx >= pd_idx)
 				(*dd_idx) += 2; /* D D P Q D */
 			break;
 		case ALGORITHM_RIGHT_ASYMMETRIC:
-			*pd_idx = stripe % raid_disks;
-			if (*pd_idx == raid_disks-1)
-				(*dd_idx)++; 	/* Q D D D P */
-			else if (*dd_idx >= *pd_idx)
+			pd_idx = stripe % raid_disks;
+			qd_idx = pd_idx + 1;
+			if (pd_idx == raid_disks-1) {
+				(*dd_idx)++;	/* Q D D D P */
+				qd_idx = 0;
+			} else if (*dd_idx >= pd_idx)
 				(*dd_idx) += 2; /* D D P Q D */
 			break;
 		case ALGORITHM_LEFT_SYMMETRIC:
-			*pd_idx = raid_disks - 1 - (stripe % raid_disks);
-			*dd_idx = (*pd_idx + 2 + *dd_idx) % raid_disks;
+			pd_idx = raid_disks - 1 - (stripe % raid_disks);
+			qd_idx = (pd_idx + 1) % raid_disks;
+			*dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks;
 			break;
 		case ALGORITHM_RIGHT_SYMMETRIC:
-			*pd_idx = stripe % raid_disks;
-			*dd_idx = (*pd_idx + 2 + *dd_idx) % raid_disks;
+			pd_idx = stripe % raid_disks;
+			qd_idx = (pd_idx + 1) % raid_disks;
+			*dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks;
 			break;
+
+		case ALGORITHM_PARITY_0:
+			pd_idx = 0;
+			qd_idx = 1;
+			(*dd_idx) += 2;
+			break;
+		case ALGORITHM_PARITY_N:
+			pd_idx = data_disks;
+			qd_idx = data_disks + 1;
+			break;
+
+		case ALGORITHM_ROTATING_ZERO_RESTART:
+			/* Exactly the same as RIGHT_ASYMMETRIC, but or
+			 * of blocks for computing Q is different.
+			 */
+			pd_idx = stripe % raid_disks;
+			qd_idx = pd_idx + 1;
+			if (pd_idx == raid_disks-1) {
+				(*dd_idx)++;	/* Q D D D P */
+				qd_idx = 0;
+			} else if (*dd_idx >= pd_idx)
+				(*dd_idx) += 2; /* D D P Q D */
+			ddf_layout = 1;
+			break;
+
+		case ALGORITHM_ROTATING_N_RESTART:
+			/* Same a left_asymmetric, by first stripe is
+			 * D D D P Q  rather than
+			 * Q D D D P
+			 */
+			pd_idx = raid_disks - 1 - ((stripe + 1) % raid_disks);
+			qd_idx = pd_idx + 1;
+			if (pd_idx == raid_disks-1) {
+				(*dd_idx)++;	/* Q D D D P */
+				qd_idx = 0;
+			} else if (*dd_idx >= pd_idx)
+				(*dd_idx) += 2; /* D D P Q D */
+			ddf_layout = 1;
+			break;
+
+		case ALGORITHM_ROTATING_N_CONTINUE:
+			/* Same as left_symmetric but Q is before P */
+			pd_idx = raid_disks - 1 - (stripe % raid_disks);
+			qd_idx = (pd_idx + raid_disks - 1) % raid_disks;
+			*dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
+			ddf_layout = 1;
+			break;
+
+		case ALGORITHM_LEFT_ASYMMETRIC_6:
+			/* RAID5 left_asymmetric, with Q on last device */
+			pd_idx = data_disks - stripe % (raid_disks-1);
+			if (*dd_idx >= pd_idx)
+				(*dd_idx)++;
+			qd_idx = raid_disks - 1;
+			break;
+
+		case ALGORITHM_RIGHT_ASYMMETRIC_6:
+			pd_idx = stripe % (raid_disks-1);
+			if (*dd_idx >= pd_idx)
+				(*dd_idx)++;
+			qd_idx = raid_disks - 1;
+			break;
+
+		case ALGORITHM_LEFT_SYMMETRIC_6:
+			pd_idx = data_disks - stripe % (raid_disks-1);
+			*dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1);
+			qd_idx = raid_disks - 1;
+			break;
+
+		case ALGORITHM_RIGHT_SYMMETRIC_6:
+			pd_idx = stripe % (raid_disks-1);
+			*dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1);
+			qd_idx = raid_disks - 1;
+			break;
+
+		case ALGORITHM_PARITY_0_6:
+			pd_idx = 0;
+			(*dd_idx)++;
+			qd_idx = raid_disks - 1;
+			break;
+
+
 		default:
 			printk(KERN_CRIT "raid6: unsupported algorithm %d\n",
-			       conf->algorithm);
+			       algorithm);
+			BUG();
 		}
 		break;
 	}
 
+	if (sh) {
+		sh->pd_idx = pd_idx;
+		sh->qd_idx = qd_idx;
+		sh->ddf_layout = ddf_layout;
+	}
 	/*
 	 * Finally, compute the new sector number
 	 */
@@ -1329,17 +1474,21 @@
 }
 
 
-static sector_t compute_blocknr(struct stripe_head *sh, int i)
+static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous)
 {
 	raid5_conf_t *conf = sh->raid_conf;
 	int raid_disks = sh->disks;
 	int data_disks = raid_disks - conf->max_degraded;
 	sector_t new_sector = sh->sector, check;
-	int sectors_per_chunk = conf->chunk_size >> 9;
+	int sectors_per_chunk = previous ? (conf->prev_chunk >> 9)
+					 : (conf->chunk_size >> 9);
+	int algorithm = previous ? conf->prev_algo
+				 : conf->algorithm;
 	sector_t stripe;
 	int chunk_offset;
-	int chunk_number, dummy1, dummy2, dd_idx = i;
+	int chunk_number, dummy1, dd_idx = i;
 	sector_t r_sector;
+	struct stripe_head sh2;
 
 
 	chunk_offset = sector_div(new_sector, sectors_per_chunk);
@@ -1351,7 +1500,7 @@
 	switch(conf->level) {
 	case 4: break;
 	case 5:
-		switch (conf->algorithm) {
+		switch (algorithm) {
 		case ALGORITHM_LEFT_ASYMMETRIC:
 		case ALGORITHM_RIGHT_ASYMMETRIC:
 			if (i > sh->pd_idx)
@@ -1363,19 +1512,27 @@
 				i += raid_disks;
 			i -= (sh->pd_idx + 1);
 			break;
+		case ALGORITHM_PARITY_0:
+			i -= 1;
+			break;
+		case ALGORITHM_PARITY_N:
+			break;
 		default:
 			printk(KERN_ERR "raid5: unsupported algorithm %d\n",
-			       conf->algorithm);
+			       algorithm);
+			BUG();
 		}
 		break;
 	case 6:
-		if (i == raid6_next_disk(sh->pd_idx, raid_disks))
+		if (i == sh->qd_idx)
 			return 0; /* It is the Q disk */
-		switch (conf->algorithm) {
+		switch (algorithm) {
 		case ALGORITHM_LEFT_ASYMMETRIC:
 		case ALGORITHM_RIGHT_ASYMMETRIC:
-		  	if (sh->pd_idx == raid_disks-1)
-				i--; 	/* Q D D D P */
+		case ALGORITHM_ROTATING_ZERO_RESTART:
+		case ALGORITHM_ROTATING_N_RESTART:
+			if (sh->pd_idx == raid_disks-1)
+				i--;	/* Q D D D P */
 			else if (i > sh->pd_idx)
 				i -= 2; /* D D P Q D */
 			break;
@@ -1390,9 +1547,35 @@
 				i -= (sh->pd_idx + 2);
 			}
 			break;
+		case ALGORITHM_PARITY_0:
+			i -= 2;
+			break;
+		case ALGORITHM_PARITY_N:
+			break;
+		case ALGORITHM_ROTATING_N_CONTINUE:
+			if (sh->pd_idx == 0)
+				i--;	/* P D D D Q */
+			else if (i > sh->pd_idx)
+				i -= 2; /* D D Q P D */
+			break;
+		case ALGORITHM_LEFT_ASYMMETRIC_6:
+		case ALGORITHM_RIGHT_ASYMMETRIC_6:
+			if (i > sh->pd_idx)
+				i--;
+			break;
+		case ALGORITHM_LEFT_SYMMETRIC_6:
+		case ALGORITHM_RIGHT_SYMMETRIC_6:
+			if (i < sh->pd_idx)
+				i += data_disks + 1;
+			i -= (sh->pd_idx + 1);
+			break;
+		case ALGORITHM_PARITY_0_6:
+			i -= 1;
+			break;
 		default:
 			printk(KERN_CRIT "raid6: unsupported algorithm %d\n",
-			       conf->algorithm);
+			       algorithm);
+			BUG();
 		}
 		break;
 	}
@@ -1400,8 +1583,10 @@
 	chunk_number = stripe * data_disks + i;
 	r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset;
 
-	check = raid5_compute_sector(r_sector, raid_disks, data_disks, &dummy1, &dummy2, conf);
-	if (check != sh->sector || dummy1 != dd_idx || dummy2 != sh->pd_idx) {
+	check = raid5_compute_sector(conf, r_sector,
+				     previous, &dummy1, &sh2);
+	if (check != sh->sector || dummy1 != dd_idx || sh2.pd_idx != sh->pd_idx
+		|| sh2.qd_idx != sh->qd_idx) {
 		printk(KERN_ERR "compute_blocknr: map not correct\n");
 		return 0;
 	}
@@ -1468,14 +1653,16 @@
 
 static void compute_parity6(struct stripe_head *sh, int method)
 {
-	raid6_conf_t *conf = sh->raid_conf;
-	int i, pd_idx = sh->pd_idx, qd_idx, d0_idx, disks = sh->disks, count;
+	raid5_conf_t *conf = sh->raid_conf;
+	int i, pd_idx, qd_idx, d0_idx, disks = sh->disks, count;
+	int syndrome_disks = sh->ddf_layout ? disks : (disks - 2);
 	struct bio *chosen;
 	/**** FIX THIS: This could be very bad if disks is close to 256 ****/
-	void *ptrs[disks];
+	void *ptrs[syndrome_disks+2];
 
-	qd_idx = raid6_next_disk(pd_idx, disks);
-	d0_idx = raid6_next_disk(qd_idx, disks);
+	pd_idx = sh->pd_idx;
+	qd_idx = sh->qd_idx;
+	d0_idx = raid6_d0(sh);
 
 	pr_debug("compute_parity, stripe %llu, method %d\n",
 		(unsigned long long)sh->sector, method);
@@ -1513,24 +1700,29 @@
 			set_bit(R5_UPTODATE, &sh->dev[i].flags);
 		}
 
-//	switch(method) {
-//	case RECONSTRUCT_WRITE:
-//	case CHECK_PARITY:
-//	case UPDATE_PARITY:
-		/* Note that unlike RAID-5, the ordering of the disks matters greatly. */
-		/* FIX: Is this ordering of drives even remotely optimal? */
-		count = 0;
-		i = d0_idx;
-		do {
-			ptrs[count++] = page_address(sh->dev[i].page);
-			if (count <= disks-2 && !test_bit(R5_UPTODATE, &sh->dev[i].flags))
-				printk("block %d/%d not uptodate on parity calc\n", i,count);
-			i = raid6_next_disk(i, disks);
-		} while ( i != d0_idx );
-//		break;
-//	}
+	/* Note that unlike RAID-5, the ordering of the disks matters greatly.*/
 
-	raid6_call.gen_syndrome(disks, STRIPE_SIZE, ptrs);
+	for (i = 0; i < disks; i++)
+		ptrs[i] = (void *)raid6_empty_zero_page;
+
+	count = 0;
+	i = d0_idx;
+	do {
+		int slot = raid6_idx_to_slot(i, sh, &count, syndrome_disks);
+
+		ptrs[slot] = page_address(sh->dev[i].page);
+		if (slot < syndrome_disks &&
+		    !test_bit(R5_UPTODATE, &sh->dev[i].flags)) {
+			printk(KERN_ERR "block %d/%d not uptodate "
+			       "on parity calc\n", i, count);
+			BUG();
+		}
+
+		i = raid6_next_disk(i, disks);
+	} while (i != d0_idx);
+	BUG_ON(count != syndrome_disks);
+
+	raid6_call.gen_syndrome(syndrome_disks+2, STRIPE_SIZE, ptrs);
 
 	switch(method) {
 	case RECONSTRUCT_WRITE:
@@ -1552,8 +1744,7 @@
 {
 	int i, count, disks = sh->disks;
 	void *ptr[MAX_XOR_BLOCKS], *dest, *p;
-	int pd_idx = sh->pd_idx;
-	int qd_idx = raid6_next_disk(pd_idx, disks);
+	int qd_idx = sh->qd_idx;
 
 	pr_debug("compute_block_1, stripe %llu, idx %d\n",
 		(unsigned long long)sh->sector, dd_idx);
@@ -1589,63 +1780,65 @@
 static void compute_block_2(struct stripe_head *sh, int dd_idx1, int dd_idx2)
 {
 	int i, count, disks = sh->disks;
-	int pd_idx = sh->pd_idx;
-	int qd_idx = raid6_next_disk(pd_idx, disks);
-	int d0_idx = raid6_next_disk(qd_idx, disks);
-	int faila, failb;
+	int syndrome_disks = sh->ddf_layout ? disks : disks-2;
+	int d0_idx = raid6_d0(sh);
+	int faila = -1, failb = -1;
+	/**** FIX THIS: This could be very bad if disks is close to 256 ****/
+	void *ptrs[syndrome_disks+2];
 
-	/* faila and failb are disk numbers relative to d0_idx */
-	/* pd_idx become disks-2 and qd_idx become disks-1 */
-	faila = (dd_idx1 < d0_idx) ? dd_idx1+(disks-d0_idx) : dd_idx1-d0_idx;
-	failb = (dd_idx2 < d0_idx) ? dd_idx2+(disks-d0_idx) : dd_idx2-d0_idx;
+	for (i = 0; i < disks ; i++)
+		ptrs[i] = (void *)raid6_empty_zero_page;
+	count = 0;
+	i = d0_idx;
+	do {
+		int slot = raid6_idx_to_slot(i, sh, &count, syndrome_disks);
+
+		ptrs[slot] = page_address(sh->dev[i].page);
+
+		if (i == dd_idx1)
+			faila = slot;
+		if (i == dd_idx2)
+			failb = slot;
+		i = raid6_next_disk(i, disks);
+	} while (i != d0_idx);
+	BUG_ON(count != syndrome_disks);
 
 	BUG_ON(faila == failb);
 	if ( failb < faila ) { int tmp = faila; faila = failb; failb = tmp; }
 
 	pr_debug("compute_block_2, stripe %llu, idx %d,%d (%d,%d)\n",
-	       (unsigned long long)sh->sector, dd_idx1, dd_idx2, faila, failb);
+		 (unsigned long long)sh->sector, dd_idx1, dd_idx2,
+		 faila, failb);
 
-	if ( failb == disks-1 ) {
+	if (failb == syndrome_disks+1) {
 		/* Q disk is one of the missing disks */
-		if ( faila == disks-2 ) {
+		if (faila == syndrome_disks) {
 			/* Missing P+Q, just recompute */
 			compute_parity6(sh, UPDATE_PARITY);
 			return;
 		} else {
 			/* We're missing D+Q; recompute D from P */
-			compute_block_1(sh, (dd_idx1 == qd_idx) ? dd_idx2 : dd_idx1, 0);
+			compute_block_1(sh, ((dd_idx1 == sh->qd_idx) ?
+					     dd_idx2 : dd_idx1),
+					0);
 			compute_parity6(sh, UPDATE_PARITY); /* Is this necessary? */
 			return;
 		}
 	}
 
-	/* We're missing D+P or D+D; build pointer table */
-	{
-		/**** FIX THIS: This could be very bad if disks is close to 256 ****/
-		void *ptrs[disks];
-
-		count = 0;
-		i = d0_idx;
-		do {
-			ptrs[count++] = page_address(sh->dev[i].page);
-			i = raid6_next_disk(i, disks);
-			if (i != dd_idx1 && i != dd_idx2 &&
-			    !test_bit(R5_UPTODATE, &sh->dev[i].flags))
-				printk("compute_2 with missing block %d/%d\n", count, i);
-		} while ( i != d0_idx );
-
-		if ( failb == disks-2 ) {
-			/* We're missing D+P. */
-			raid6_datap_recov(disks, STRIPE_SIZE, faila, ptrs);
-		} else {
-			/* We're missing D+D. */
-			raid6_2data_recov(disks, STRIPE_SIZE, faila, failb, ptrs);
-		}
-
-		/* Both the above update both missing blocks */
-		set_bit(R5_UPTODATE, &sh->dev[dd_idx1].flags);
-		set_bit(R5_UPTODATE, &sh->dev[dd_idx2].flags);
+	/* We're missing D+P or D+D; */
+	if (failb == syndrome_disks) {
+		/* We're missing D+P. */
+		raid6_datap_recov(syndrome_disks+2, STRIPE_SIZE, faila, ptrs);
+	} else {
+		/* We're missing D+D. */
+		raid6_2data_recov(syndrome_disks+2, STRIPE_SIZE, faila, failb,
+				  ptrs);
 	}
+
+	/* Both the above update both missing blocks */
+	set_bit(R5_UPTODATE, &sh->dev[dd_idx1].flags);
+	set_bit(R5_UPTODATE, &sh->dev[dd_idx2].flags);
 }
 
 static void
@@ -1800,17 +1993,21 @@
 		memcmp(a, a+4, STRIPE_SIZE-4)==0);
 }
 
-static int stripe_to_pdidx(sector_t stripe, raid5_conf_t *conf, int disks)
+static void stripe_set_idx(sector_t stripe, raid5_conf_t *conf, int previous,
+			    struct stripe_head *sh)
 {
-	int sectors_per_chunk = conf->chunk_size >> 9;
-	int pd_idx, dd_idx;
+	int sectors_per_chunk =
+		previous ? (conf->prev_chunk >> 9)
+			 : (conf->chunk_size >> 9);
+	int dd_idx;
 	int chunk_offset = sector_div(stripe, sectors_per_chunk);
+	int disks = previous ? conf->previous_raid_disks : conf->raid_disks;
 
-	raid5_compute_sector(stripe * (disks - conf->max_degraded)
+	raid5_compute_sector(conf,
+			     stripe * (disks - conf->max_degraded)
 			     *sectors_per_chunk + chunk_offset,
-			     disks, disks - conf->max_degraded,
-			     &dd_idx, &pd_idx, conf);
-	return pd_idx;
+			     previous,
+			     &dd_idx, sh);
 }
 
 static void
@@ -2181,7 +2378,7 @@
 		struct r6_state *r6s, int disks)
 {
 	int rcw = 0, must_compute = 0, pd_idx = sh->pd_idx, i;
-	int qd_idx = r6s->qd_idx;
+	int qd_idx = sh->qd_idx;
 	for (i = disks; i--; ) {
 		struct r5dev *dev = &sh->dev[i];
 		/* Would I have to read this buffer for reconstruct_write */
@@ -2371,7 +2568,7 @@
 	int update_p = 0, update_q = 0;
 	struct r5dev *dev;
 	int pd_idx = sh->pd_idx;
-	int qd_idx = r6s->qd_idx;
+	int qd_idx = sh->qd_idx;
 
 	set_bit(STRIPE_HANDLE, &sh->state);
 
@@ -2467,17 +2664,14 @@
 	struct dma_async_tx_descriptor *tx = NULL;
 	clear_bit(STRIPE_EXPAND_SOURCE, &sh->state);
 	for (i = 0; i < sh->disks; i++)
-		if (i != sh->pd_idx && (!r6s || i != r6s->qd_idx)) {
-			int dd_idx, pd_idx, j;
+		if (i != sh->pd_idx && i != sh->qd_idx) {
+			int dd_idx, j;
 			struct stripe_head *sh2;
 
-			sector_t bn = compute_blocknr(sh, i);
-			sector_t s = raid5_compute_sector(bn, conf->raid_disks,
-						conf->raid_disks -
-						conf->max_degraded, &dd_idx,
-						&pd_idx, conf);
-			sh2 = get_active_stripe(conf, s, conf->raid_disks,
-						pd_idx, 1);
+			sector_t bn = compute_blocknr(sh, i, 1);
+			sector_t s = raid5_compute_sector(conf, bn, 0,
+							  &dd_idx, NULL);
+			sh2 = get_active_stripe(conf, s, 0, 1);
 			if (sh2 == NULL)
 				/* so far only the early blocks of this stripe
 				 * have been requested.  When later blocks
@@ -2500,8 +2694,7 @@
 			set_bit(R5_UPTODATE, &sh2->dev[dd_idx].flags);
 			for (j = 0; j < conf->raid_disks; j++)
 				if (j != sh2->pd_idx &&
-				    (!r6s || j != raid6_next_disk(sh2->pd_idx,
-								 sh2->disks)) &&
+				    (!r6s || j != sh2->qd_idx) &&
 				    !test_bit(R5_Expanded, &sh2->dev[j].flags))
 					break;
 			if (j == conf->raid_disks) {
@@ -2750,6 +2943,23 @@
 
 	/* Finish reconstruct operations initiated by the expansion process */
 	if (sh->reconstruct_state == reconstruct_state_result) {
+		struct stripe_head *sh2
+			= get_active_stripe(conf, sh->sector, 1, 1);
+		if (sh2 && test_bit(STRIPE_EXPAND_SOURCE, &sh2->state)) {
+			/* sh cannot be written until sh2 has been read.
+			 * so arrange for sh to be delayed a little
+			 */
+			set_bit(STRIPE_DELAYED, &sh->state);
+			set_bit(STRIPE_HANDLE, &sh->state);
+			if (!test_and_set_bit(STRIPE_PREREAD_ACTIVE,
+					      &sh2->state))
+				atomic_inc(&conf->preread_active_stripes);
+			release_stripe(sh2);
+			goto unlock;
+		}
+		if (sh2)
+			release_stripe(sh2);
+
 		sh->reconstruct_state = reconstruct_state_idle;
 		clear_bit(STRIPE_EXPANDING, &sh->state);
 		for (i = conf->raid_disks; i--; ) {
@@ -2763,8 +2973,7 @@
 	    !sh->reconstruct_state) {
 		/* Need to write out all blocks after computing parity */
 		sh->disks = conf->raid_disks;
-		sh->pd_idx = stripe_to_pdidx(sh->sector, conf,
-			conf->raid_disks);
+		stripe_set_idx(sh->sector, conf, 0, sh);
 		schedule_reconstruction5(sh, &s, 1, 1);
 	} else if (s.expanded && !sh->reconstruct_state && s.locked == 0) {
 		clear_bit(STRIPE_EXPAND_READY, &sh->state);
@@ -2796,20 +3005,19 @@
 
 static bool handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
 {
-	raid6_conf_t *conf = sh->raid_conf;
+	raid5_conf_t *conf = sh->raid_conf;
 	int disks = sh->disks;
 	struct bio *return_bi = NULL;
-	int i, pd_idx = sh->pd_idx;
+	int i, pd_idx = sh->pd_idx, qd_idx = sh->qd_idx;
 	struct stripe_head_state s;
 	struct r6_state r6s;
 	struct r5dev *dev, *pdev, *qdev;
 	mdk_rdev_t *blocked_rdev = NULL;
 
-	r6s.qd_idx = raid6_next_disk(pd_idx, disks);
 	pr_debug("handling stripe %llu, state=%#lx cnt=%d, "
 		"pd_idx=%d, qd_idx=%d\n",
 	       (unsigned long long)sh->sector, sh->state,
-	       atomic_read(&sh->count), pd_idx, r6s.qd_idx);
+	       atomic_read(&sh->count), pd_idx, qd_idx);
 	memset(&s, 0, sizeof(s));
 
 	spin_lock(&sh->lock);
@@ -2920,9 +3128,9 @@
 	pdev = &sh->dev[pd_idx];
 	r6s.p_failed = (s.failed >= 1 && r6s.failed_num[0] == pd_idx)
 		|| (s.failed >= 2 && r6s.failed_num[1] == pd_idx);
-	qdev = &sh->dev[r6s.qd_idx];
-	r6s.q_failed = (s.failed >= 1 && r6s.failed_num[0] == r6s.qd_idx)
-		|| (s.failed >= 2 && r6s.failed_num[1] == r6s.qd_idx);
+	qdev = &sh->dev[qd_idx];
+	r6s.q_failed = (s.failed >= 1 && r6s.failed_num[0] == qd_idx)
+		|| (s.failed >= 2 && r6s.failed_num[1] == qd_idx);
 
 	if ( s.written &&
 	     ( r6s.p_failed || ((test_bit(R5_Insync, &pdev->flags)
@@ -2980,10 +3188,26 @@
 		}
 
 	if (s.expanded && test_bit(STRIPE_EXPANDING, &sh->state)) {
+		struct stripe_head *sh2
+			= get_active_stripe(conf, sh->sector, 1, 1);
+		if (sh2 && test_bit(STRIPE_EXPAND_SOURCE, &sh2->state)) {
+			/* sh cannot be written until sh2 has been read.
+			 * so arrange for sh to be delayed a little
+			 */
+			set_bit(STRIPE_DELAYED, &sh->state);
+			set_bit(STRIPE_HANDLE, &sh->state);
+			if (!test_and_set_bit(STRIPE_PREREAD_ACTIVE,
+					      &sh2->state))
+				atomic_inc(&conf->preread_active_stripes);
+			release_stripe(sh2);
+			goto unlock;
+		}
+		if (sh2)
+			release_stripe(sh2);
+
 		/* Need to write out all blocks after computing P&Q */
 		sh->disks = conf->raid_disks;
-		sh->pd_idx = stripe_to_pdidx(sh->sector, conf,
-					     conf->raid_disks);
+		stripe_set_idx(sh->sector, conf, 0, sh);
 		compute_parity6(sh, RECONSTRUCT_WRITE);
 		for (i = conf->raid_disks ; i-- ;  ) {
 			set_bit(R5_LOCKED, &sh->dev[i].flags);
@@ -3134,6 +3358,8 @@
 	if ((bvm->bi_rw & 1) == WRITE)
 		return biovec->bv_len; /* always allow writes to be mergeable */
 
+	if (mddev->new_chunk < mddev->chunk_size)
+		chunk_sectors = mddev->new_chunk >> 9;
 	max =  (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9;
 	if (max < 0) max = 0;
 	if (max <= biovec->bv_len && bio_sectors == 0)
@@ -3149,6 +3375,8 @@
 	unsigned int chunk_sectors = mddev->chunk_size >> 9;
 	unsigned int bio_sectors = bio->bi_size >> 9;
 
+	if (mddev->new_chunk < mddev->chunk_size)
+		chunk_sectors = mddev->new_chunk >> 9;
 	return  chunk_sectors >=
 		((sector & (chunk_sectors - 1)) + bio_sectors);
 }
@@ -3255,9 +3483,7 @@
 {
 	mddev_t *mddev = q->queuedata;
 	raid5_conf_t *conf = mddev_to_conf(mddev);
-	const unsigned int raid_disks = conf->raid_disks;
-	const unsigned int data_disks = raid_disks - conf->max_degraded;
-	unsigned int dd_idx, pd_idx;
+	unsigned int dd_idx;
 	struct bio* align_bi;
 	mdk_rdev_t *rdev;
 
@@ -3266,7 +3492,7 @@
 		return 0;
 	}
 	/*
- 	 * use bio_clone to make a copy of the bio
+	 * use bio_clone to make a copy of the bio
 	 */
 	align_bi = bio_clone(raid_bio, GFP_NOIO);
 	if (!align_bi)
@@ -3280,12 +3506,9 @@
 	/*
 	 *	compute position
 	 */
-	align_bi->bi_sector =  raid5_compute_sector(raid_bio->bi_sector,
-					raid_disks,
-					data_disks,
-					&dd_idx,
-					&pd_idx,
-					conf);
+	align_bi->bi_sector =  raid5_compute_sector(conf, raid_bio->bi_sector,
+						    0,
+						    &dd_idx, NULL);
 
 	rcu_read_lock();
 	rdev = rcu_dereference(conf->disks[dd_idx].rdev);
@@ -3377,7 +3600,7 @@
 {
 	mddev_t *mddev = q->queuedata;
 	raid5_conf_t *conf = mddev_to_conf(mddev);
-	unsigned int dd_idx, pd_idx;
+	int dd_idx;
 	sector_t new_sector;
 	sector_t logical_sector, last_sector;
 	struct stripe_head *sh;
@@ -3400,7 +3623,7 @@
 	if (rw == READ &&
 	     mddev->reshape_position == MaxSector &&
 	     chunk_aligned_read(q,bi))
-            	return 0;
+		return 0;
 
 	logical_sector = bi->bi_sector & ~((sector_t)STRIPE_SECTORS-1);
 	last_sector = bi->bi_sector + (bi->bi_size>>9);
@@ -3410,26 +3633,31 @@
 	for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) {
 		DEFINE_WAIT(w);
 		int disks, data_disks;
+		int previous;
 
 	retry:
+		previous = 0;
+		disks = conf->raid_disks;
 		prepare_to_wait(&conf->wait_for_overlap, &w, TASK_UNINTERRUPTIBLE);
-		if (likely(conf->expand_progress == MaxSector))
-			disks = conf->raid_disks;
-		else {
-			/* spinlock is needed as expand_progress may be
+		if (unlikely(conf->reshape_progress != MaxSector)) {
+			/* spinlock is needed as reshape_progress may be
 			 * 64bit on a 32bit platform, and so it might be
 			 * possible to see a half-updated value
-			 * Ofcourse expand_progress could change after
+			 * Ofcourse reshape_progress could change after
 			 * the lock is dropped, so once we get a reference
 			 * to the stripe that we think it is, we will have
 			 * to check again.
 			 */
 			spin_lock_irq(&conf->device_lock);
-			disks = conf->raid_disks;
-			if (logical_sector >= conf->expand_progress)
+			if (mddev->delta_disks < 0
+			    ? logical_sector < conf->reshape_progress
+			    : logical_sector >= conf->reshape_progress) {
 				disks = conf->previous_raid_disks;
-			else {
-				if (logical_sector >= conf->expand_lo) {
+				previous = 1;
+			} else {
+				if (mddev->delta_disks < 0
+				    ? logical_sector < conf->reshape_safe
+				    : logical_sector >= conf->reshape_safe) {
 					spin_unlock_irq(&conf->device_lock);
 					schedule();
 					goto retry;
@@ -3439,15 +3667,17 @@
 		}
 		data_disks = disks - conf->max_degraded;
 
- 		new_sector = raid5_compute_sector(logical_sector, disks, data_disks,
-						  &dd_idx, &pd_idx, conf);
+		new_sector = raid5_compute_sector(conf, logical_sector,
+						  previous,
+						  &dd_idx, NULL);
 		pr_debug("raid5: make_request, sector %llu logical %llu\n",
 			(unsigned long long)new_sector, 
 			(unsigned long long)logical_sector);
 
-		sh = get_active_stripe(conf, new_sector, disks, pd_idx, (bi->bi_rw&RWA_MASK));
+		sh = get_active_stripe(conf, new_sector, previous,
+				       (bi->bi_rw&RWA_MASK));
 		if (sh) {
-			if (unlikely(conf->expand_progress != MaxSector)) {
+			if (unlikely(previous)) {
 				/* expansion might have moved on while waiting for a
 				 * stripe, so we must do the range check again.
 				 * Expansion could still move past after this
@@ -3458,8 +3688,9 @@
 				 */
 				int must_retry = 0;
 				spin_lock_irq(&conf->device_lock);
-				if (logical_sector <  conf->expand_progress &&
-				    disks == conf->previous_raid_disks)
+				if (mddev->delta_disks < 0
+				    ? logical_sector >= conf->reshape_progress
+				    : logical_sector < conf->reshape_progress)
 					/* mismatch, need to try again */
 					must_retry = 1;
 				spin_unlock_irq(&conf->device_lock);
@@ -3514,6 +3745,8 @@
 	return 0;
 }
 
+static sector_t raid5_size(mddev_t *mddev, sector_t sectors, int raid_disks);
+
 static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped)
 {
 	/* reshaping is quite different to recovery/resync so it is
@@ -3527,61 +3760,118 @@
 	 */
 	raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
 	struct stripe_head *sh;
-	int pd_idx;
 	sector_t first_sector, last_sector;
 	int raid_disks = conf->previous_raid_disks;
 	int data_disks = raid_disks - conf->max_degraded;
 	int new_data_disks = conf->raid_disks - conf->max_degraded;
 	int i;
 	int dd_idx;
-	sector_t writepos, safepos, gap;
+	sector_t writepos, readpos, safepos;
+	sector_t stripe_addr;
+	int reshape_sectors;
+	struct list_head stripes;
 
-	if (sector_nr == 0 &&
-	    conf->expand_progress != 0) {
-		/* restarting in the middle, skip the initial sectors */
-		sector_nr = conf->expand_progress;
+	if (sector_nr == 0) {
+		/* If restarting in the middle, skip the initial sectors */
+		if (mddev->delta_disks < 0 &&
+		    conf->reshape_progress < raid5_size(mddev, 0, 0)) {
+			sector_nr = raid5_size(mddev, 0, 0)
+				- conf->reshape_progress;
+		} else if (mddev->delta_disks > 0 &&
+			   conf->reshape_progress > 0)
+			sector_nr = conf->reshape_progress;
 		sector_div(sector_nr, new_data_disks);
-		*skipped = 1;
-		return sector_nr;
+		if (sector_nr) {
+			*skipped = 1;
+			return sector_nr;
+		}
 	}
 
+	/* We need to process a full chunk at a time.
+	 * If old and new chunk sizes differ, we need to process the
+	 * largest of these
+	 */
+	if (mddev->new_chunk > mddev->chunk_size)
+		reshape_sectors = mddev->new_chunk / 512;
+	else
+		reshape_sectors = mddev->chunk_size / 512;
+
 	/* we update the metadata when there is more than 3Meg
 	 * in the block range (that is rather arbitrary, should
 	 * probably be time based) or when the data about to be
 	 * copied would over-write the source of the data at
 	 * the front of the range.
-	 * i.e. one new_stripe forward from expand_progress new_maps
-	 * to after where expand_lo old_maps to
+	 * i.e. one new_stripe along from reshape_progress new_maps
+	 * to after where reshape_safe old_maps to
 	 */
-	writepos = conf->expand_progress +
-		conf->chunk_size/512*(new_data_disks);
+	writepos = conf->reshape_progress;
 	sector_div(writepos, new_data_disks);
-	safepos = conf->expand_lo;
+	readpos = conf->reshape_progress;
+	sector_div(readpos, data_disks);
+	safepos = conf->reshape_safe;
 	sector_div(safepos, data_disks);
-	gap = conf->expand_progress - conf->expand_lo;
+	if (mddev->delta_disks < 0) {
+		writepos -= reshape_sectors;
+		readpos += reshape_sectors;
+		safepos += reshape_sectors;
+	} else {
+		writepos += reshape_sectors;
+		readpos -= reshape_sectors;
+		safepos -= reshape_sectors;
+	}
 
-	if (writepos >= safepos ||
-	    gap > (new_data_disks)*3000*2 /*3Meg*/) {
+	/* 'writepos' is the most advanced device address we might write.
+	 * 'readpos' is the least advanced device address we might read.
+	 * 'safepos' is the least address recorded in the metadata as having
+	 *     been reshaped.
+	 * If 'readpos' is behind 'writepos', then there is no way that we can
+	 * ensure safety in the face of a crash - that must be done by userspace
+	 * making a backup of the data.  So in that case there is no particular
+	 * rush to update metadata.
+	 * Otherwise if 'safepos' is behind 'writepos', then we really need to
+	 * update the metadata to advance 'safepos' to match 'readpos' so that
+	 * we can be safe in the event of a crash.
+	 * So we insist on updating metadata if safepos is behind writepos and
+	 * readpos is beyond writepos.
+	 * In any case, update the metadata every 10 seconds.
+	 * Maybe that number should be configurable, but I'm not sure it is
+	 * worth it.... maybe it could be a multiple of safemode_delay???
+	 */
+	if ((mddev->delta_disks < 0
+	     ? (safepos > writepos && readpos < writepos)
+	     : (safepos < writepos && readpos > writepos)) ||
+	    time_after(jiffies, conf->reshape_checkpoint + 10*HZ)) {
 		/* Cannot proceed until we've updated the superblock... */
 		wait_event(conf->wait_for_overlap,
 			   atomic_read(&conf->reshape_stripes)==0);
-		mddev->reshape_position = conf->expand_progress;
+		mddev->reshape_position = conf->reshape_progress;
+		conf->reshape_checkpoint = jiffies;
 		set_bit(MD_CHANGE_DEVS, &mddev->flags);
 		md_wakeup_thread(mddev->thread);
 		wait_event(mddev->sb_wait, mddev->flags == 0 ||
 			   kthread_should_stop());
 		spin_lock_irq(&conf->device_lock);
-		conf->expand_lo = mddev->reshape_position;
+		conf->reshape_safe = mddev->reshape_position;
 		spin_unlock_irq(&conf->device_lock);
 		wake_up(&conf->wait_for_overlap);
 	}
 
-	for (i=0; i < conf->chunk_size/512; i+= STRIPE_SECTORS) {
+	if (mddev->delta_disks < 0) {
+		BUG_ON(conf->reshape_progress == 0);
+		stripe_addr = writepos;
+		BUG_ON((mddev->dev_sectors &
+			~((sector_t)reshape_sectors - 1))
+		       - reshape_sectors - stripe_addr
+		       != sector_nr);
+	} else {
+		BUG_ON(writepos != sector_nr + reshape_sectors);
+		stripe_addr = sector_nr;
+	}
+	INIT_LIST_HEAD(&stripes);
+	for (i = 0; i < reshape_sectors; i += STRIPE_SECTORS) {
 		int j;
 		int skipped = 0;
-		pd_idx = stripe_to_pdidx(sector_nr+i, conf, conf->raid_disks);
-		sh = get_active_stripe(conf, sector_nr+i,
-				       conf->raid_disks, pd_idx, 0);
+		sh = get_active_stripe(conf, stripe_addr+i, 0, 0);
 		set_bit(STRIPE_EXPANDING, &sh->state);
 		atomic_inc(&conf->reshape_stripes);
 		/* If any of this stripe is beyond the end of the old
@@ -3592,10 +3882,10 @@
 			if (j == sh->pd_idx)
 				continue;
 			if (conf->level == 6 &&
-			    j == raid6_next_disk(sh->pd_idx, sh->disks))
+			    j == sh->qd_idx)
 				continue;
-			s = compute_blocknr(sh, j);
-			if (s < mddev->array_sectors) {
+			s = compute_blocknr(sh, j, 0);
+			if (s < raid5_size(mddev, 0, 0)) {
 				skipped = 1;
 				continue;
 			}
@@ -3607,10 +3897,13 @@
 			set_bit(STRIPE_EXPAND_READY, &sh->state);
 			set_bit(STRIPE_HANDLE, &sh->state);
 		}
-		release_stripe(sh);
+		list_add(&sh->lru, &stripes);
 	}
 	spin_lock_irq(&conf->device_lock);
-	conf->expand_progress = (sector_nr + i) * new_data_disks;
+	if (mddev->delta_disks < 0)
+		conf->reshape_progress -= reshape_sectors * new_data_disks;
+	else
+		conf->reshape_progress += reshape_sectors * new_data_disks;
 	spin_unlock_irq(&conf->device_lock);
 	/* Ok, those stripe are ready. We can start scheduling
 	 * reads on the source stripes.
@@ -3618,46 +3911,50 @@
 	 * block on the destination stripes.
 	 */
 	first_sector =
-		raid5_compute_sector(sector_nr*(new_data_disks),
-				     raid_disks, data_disks,
-				     &dd_idx, &pd_idx, conf);
+		raid5_compute_sector(conf, stripe_addr*(new_data_disks),
+				     1, &dd_idx, NULL);
 	last_sector =
-		raid5_compute_sector((sector_nr+conf->chunk_size/512)
-				     *(new_data_disks) -1,
-				     raid_disks, data_disks,
-				     &dd_idx, &pd_idx, conf);
-	if (last_sector >= (mddev->size<<1))
-		last_sector = (mddev->size<<1)-1;
+		raid5_compute_sector(conf, ((stripe_addr+conf->chunk_size/512)
+					    *(new_data_disks) - 1),
+				     1, &dd_idx, NULL);
+	if (last_sector >= mddev->dev_sectors)
+		last_sector = mddev->dev_sectors - 1;
 	while (first_sector <= last_sector) {
-		pd_idx = stripe_to_pdidx(first_sector, conf,
-					 conf->previous_raid_disks);
-		sh = get_active_stripe(conf, first_sector,
-				       conf->previous_raid_disks, pd_idx, 0);
+		sh = get_active_stripe(conf, first_sector, 1, 0);
 		set_bit(STRIPE_EXPAND_SOURCE, &sh->state);
 		set_bit(STRIPE_HANDLE, &sh->state);
 		release_stripe(sh);
 		first_sector += STRIPE_SECTORS;
 	}
+	/* Now that the sources are clearly marked, we can release
+	 * the destination stripes
+	 */
+	while (!list_empty(&stripes)) {
+		sh = list_entry(stripes.next, struct stripe_head, lru);
+		list_del_init(&sh->lru);
+		release_stripe(sh);
+	}
 	/* If this takes us to the resync_max point where we have to pause,
 	 * then we need to write out the superblock.
 	 */
-	sector_nr += conf->chunk_size>>9;
+	sector_nr += reshape_sectors;
 	if (sector_nr >= mddev->resync_max) {
 		/* Cannot proceed until we've updated the superblock... */
 		wait_event(conf->wait_for_overlap,
 			   atomic_read(&conf->reshape_stripes) == 0);
-		mddev->reshape_position = conf->expand_progress;
+		mddev->reshape_position = conf->reshape_progress;
+		conf->reshape_checkpoint = jiffies;
 		set_bit(MD_CHANGE_DEVS, &mddev->flags);
 		md_wakeup_thread(mddev->thread);
 		wait_event(mddev->sb_wait,
 			   !test_bit(MD_CHANGE_DEVS, &mddev->flags)
 			   || kthread_should_stop());
 		spin_lock_irq(&conf->device_lock);
-		conf->expand_lo = mddev->reshape_position;
+		conf->reshape_safe = mddev->reshape_position;
 		spin_unlock_irq(&conf->device_lock);
 		wake_up(&conf->wait_for_overlap);
 	}
-	return conf->chunk_size>>9;
+	return reshape_sectors;
 }
 
 /* FIXME go_faster isn't used */
@@ -3665,9 +3962,7 @@
 {
 	raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
 	struct stripe_head *sh;
-	int pd_idx;
-	int raid_disks = conf->raid_disks;
-	sector_t max_sector = mddev->size << 1;
+	sector_t max_sector = mddev->dev_sectors;
 	int sync_blocks;
 	int still_degraded = 0;
 	int i;
@@ -3675,6 +3970,7 @@
 	if (sector_nr >= max_sector) {
 		/* just being told to finish up .. nothing much to do */
 		unplug_slaves(mddev);
+
 		if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) {
 			end_reshape(conf);
 			return 0;
@@ -3705,7 +4001,7 @@
 	 */
 	if (mddev->degraded >= conf->max_degraded &&
 	    test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
-		sector_t rv = (mddev->size << 1) - sector_nr;
+		sector_t rv = mddev->dev_sectors - sector_nr;
 		*skipped = 1;
 		return rv;
 	}
@@ -3721,10 +4017,9 @@
 
 	bitmap_cond_end_sync(mddev->bitmap, sector_nr);
 
-	pd_idx = stripe_to_pdidx(sector_nr, conf, raid_disks);
-	sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 1);
+	sh = get_active_stripe(conf, sector_nr, 0, 1);
 	if (sh == NULL) {
-		sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 0);
+		sh = get_active_stripe(conf, sector_nr, 0, 0);
 		/* make sure we don't swamp the stripe cache if someone else
 		 * is trying to get access
 		 */
@@ -3766,19 +4061,15 @@
 	 * it will be only one 'dd_idx' and only need one call to raid5_compute_sector.
 	 */
 	struct stripe_head *sh;
-	int dd_idx, pd_idx;
+	int dd_idx;
 	sector_t sector, logical_sector, last_sector;
 	int scnt = 0;
 	int remaining;
 	int handled = 0;
 
 	logical_sector = raid_bio->bi_sector & ~((sector_t)STRIPE_SECTORS-1);
-	sector = raid5_compute_sector(	logical_sector,
-					conf->raid_disks,
-					conf->raid_disks - conf->max_degraded,
-					&dd_idx,
-					&pd_idx,
-					conf);
+	sector = raid5_compute_sector(conf, logical_sector,
+				      0, &dd_idx, NULL);
 	last_sector = raid_bio->bi_sector + (raid_bio->bi_size>>9);
 
 	for (; logical_sector < last_sector;
@@ -3790,7 +4081,7 @@
 			/* already done this stripe */
 			continue;
 
-		sh = get_active_stripe(conf, sector, conf->raid_disks, pd_idx, 1);
+		sh = get_active_stripe(conf, sector, 0, 1);
 
 		if (!sh) {
 			/* failed to get a stripe - must wait */
@@ -3992,89 +4283,69 @@
 	.attrs = raid5_attrs,
 };
 
-static int run(mddev_t *mddev)
+static sector_t
+raid5_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+	raid5_conf_t *conf = mddev_to_conf(mddev);
+
+	if (!sectors)
+		sectors = mddev->dev_sectors;
+	if (!raid_disks) {
+		/* size is defined by the smallest of previous and new size */
+		if (conf->raid_disks < conf->previous_raid_disks)
+			raid_disks = conf->raid_disks;
+		else
+			raid_disks = conf->previous_raid_disks;
+	}
+
+	sectors &= ~((sector_t)mddev->chunk_size/512 - 1);
+	sectors &= ~((sector_t)mddev->new_chunk/512 - 1);
+	return sectors * (raid_disks - conf->max_degraded);
+}
+
+static raid5_conf_t *setup_conf(mddev_t *mddev)
 {
 	raid5_conf_t *conf;
 	int raid_disk, memory;
 	mdk_rdev_t *rdev;
 	struct disk_info *disk;
-	int working_disks = 0;
 
-	if (mddev->level != 5 && mddev->level != 4 && mddev->level != 6) {
+	if (mddev->new_level != 5
+	    && mddev->new_level != 4
+	    && mddev->new_level != 6) {
 		printk(KERN_ERR "raid5: %s: raid level not set to 4/5/6 (%d)\n",
-		       mdname(mddev), mddev->level);
-		return -EIO;
+		       mdname(mddev), mddev->new_level);
+		return ERR_PTR(-EIO);
+	}
+	if ((mddev->new_level == 5
+	     && !algorithm_valid_raid5(mddev->new_layout)) ||
+	    (mddev->new_level == 6
+	     && !algorithm_valid_raid6(mddev->new_layout))) {
+		printk(KERN_ERR "raid5: %s: layout %d not supported\n",
+		       mdname(mddev), mddev->new_layout);
+		return ERR_PTR(-EIO);
+	}
+	if (mddev->new_level == 6 && mddev->raid_disks < 4) {
+		printk(KERN_ERR "raid6: not enough configured devices for %s (%d, minimum 4)\n",
+		       mdname(mddev), mddev->raid_disks);
+		return ERR_PTR(-EINVAL);
 	}
 
-	if (mddev->chunk_size < PAGE_SIZE) {
-		printk(KERN_ERR "md/raid5: chunk_size must be at least "
-		       "PAGE_SIZE but %d < %ld\n",
-		       mddev->chunk_size, PAGE_SIZE);
-		return -EINVAL;
+	if (!mddev->new_chunk || mddev->new_chunk % PAGE_SIZE) {
+		printk(KERN_ERR "raid5: invalid chunk size %d for %s\n",
+			mddev->new_chunk, mdname(mddev));
+		return ERR_PTR(-EINVAL);
 	}
 
-	if (mddev->reshape_position != MaxSector) {
-		/* Check that we can continue the reshape.
-		 * Currently only disks can change, it must
-		 * increase, and we must be past the point where
-		 * a stripe over-writes itself
-		 */
-		sector_t here_new, here_old;
-		int old_disks;
-		int max_degraded = (mddev->level == 5 ? 1 : 2);
-
-		if (mddev->new_level != mddev->level ||
-		    mddev->new_layout != mddev->layout ||
-		    mddev->new_chunk != mddev->chunk_size) {
-			printk(KERN_ERR "raid5: %s: unsupported reshape "
-			       "required - aborting.\n",
-			       mdname(mddev));
-			return -EINVAL;
-		}
-		if (mddev->delta_disks <= 0) {
-			printk(KERN_ERR "raid5: %s: unsupported reshape "
-			       "(reduce disks) required - aborting.\n",
-			       mdname(mddev));
-			return -EINVAL;
-		}
-		old_disks = mddev->raid_disks - mddev->delta_disks;
-		/* reshape_position must be on a new-stripe boundary, and one
-		 * further up in new geometry must map after here in old
-		 * geometry.
-		 */
-		here_new = mddev->reshape_position;
-		if (sector_div(here_new, (mddev->chunk_size>>9)*
-			       (mddev->raid_disks - max_degraded))) {
-			printk(KERN_ERR "raid5: reshape_position not "
-			       "on a stripe boundary\n");
-			return -EINVAL;
-		}
-		/* here_new is the stripe we will write to */
-		here_old = mddev->reshape_position;
-		sector_div(here_old, (mddev->chunk_size>>9)*
-			   (old_disks-max_degraded));
-		/* here_old is the first stripe that we might need to read
-		 * from */
-		if (here_new >= here_old) {
-			/* Reading from the same stripe as writing to - bad */
-			printk(KERN_ERR "raid5: reshape_position too early for "
-			       "auto-recovery - aborting.\n");
-			return -EINVAL;
-		}
-		printk(KERN_INFO "raid5: reshape will continue\n");
-		/* OK, we should be able to continue; */
-	}
-
-
-	mddev->private = kzalloc(sizeof (raid5_conf_t), GFP_KERNEL);
-	if ((conf = mddev->private) == NULL)
+	conf = kzalloc(sizeof(raid5_conf_t), GFP_KERNEL);
+	if (conf == NULL)
 		goto abort;
-	if (mddev->reshape_position == MaxSector) {
-		conf->previous_raid_disks = conf->raid_disks = mddev->raid_disks;
-	} else {
-		conf->raid_disks = mddev->raid_disks;
+
+	conf->raid_disks = mddev->raid_disks;
+	if (mddev->reshape_position == MaxSector)
+		conf->previous_raid_disks = mddev->raid_disks;
+	else
 		conf->previous_raid_disks = mddev->raid_disks - mddev->delta_disks;
-	}
 
 	conf->disks = kzalloc(conf->raid_disks * sizeof(struct disk_info),
 			      GFP_KERNEL);
@@ -4086,13 +4357,12 @@
 	if ((conf->stripe_hashtbl = kzalloc(PAGE_SIZE, GFP_KERNEL)) == NULL)
 		goto abort;
 
-	if (mddev->level == 6) {
+	if (mddev->new_level == 6) {
 		conf->spare_page = alloc_page(GFP_KERNEL);
 		if (!conf->spare_page)
 			goto abort;
 	}
 	spin_lock_init(&conf->device_lock);
-	mddev->queue->queue_lock = &conf->device_lock;
 	init_waitqueue_head(&conf->wait_for_stripe);
 	init_waitqueue_head(&conf->wait_for_overlap);
 	INIT_LIST_HEAD(&conf->handle_list);
@@ -4121,47 +4391,134 @@
 			printk(KERN_INFO "raid5: device %s operational as raid"
 				" disk %d\n", bdevname(rdev->bdev,b),
 				raid_disk);
-			working_disks++;
 		} else
 			/* Cannot rely on bitmap to complete recovery */
 			conf->fullsync = 1;
 	}
 
-	/*
-	 * 0 for a fully functional array, 1 or 2 for a degraded array.
-	 */
-	mddev->degraded = conf->raid_disks - working_disks;
-	conf->mddev = mddev;
-	conf->chunk_size = mddev->chunk_size;
-	conf->level = mddev->level;
+	conf->chunk_size = mddev->new_chunk;
+	conf->level = mddev->new_level;
 	if (conf->level == 6)
 		conf->max_degraded = 2;
 	else
 		conf->max_degraded = 1;
-	conf->algorithm = mddev->layout;
+	conf->algorithm = mddev->new_layout;
 	conf->max_nr_stripes = NR_STRIPES;
-	conf->expand_progress = mddev->reshape_position;
+	conf->reshape_progress = mddev->reshape_position;
+	if (conf->reshape_progress != MaxSector) {
+		conf->prev_chunk = mddev->chunk_size;
+		conf->prev_algo = mddev->layout;
+	}
 
-	/* device size must be a multiple of chunk size */
-	mddev->size &= ~(mddev->chunk_size/1024 -1);
-	mddev->resync_max_sectors = mddev->size << 1;
+	memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
+		 conf->raid_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024;
+	if (grow_stripes(conf, conf->max_nr_stripes)) {
+		printk(KERN_ERR
+			"raid5: couldn't allocate %dkB for buffers\n", memory);
+		goto abort;
+	} else
+		printk(KERN_INFO "raid5: allocated %dkB for %s\n",
+			memory, mdname(mddev));
 
-	if (conf->level == 6 && conf->raid_disks < 4) {
-		printk(KERN_ERR "raid6: not enough configured devices for %s (%d, minimum 4)\n",
-		       mdname(mddev), conf->raid_disks);
+	conf->thread = md_register_thread(raid5d, mddev, "%s_raid5");
+	if (!conf->thread) {
+		printk(KERN_ERR
+		       "raid5: couldn't allocate thread for %s\n",
+		       mdname(mddev));
 		goto abort;
 	}
-	if (!conf->chunk_size || conf->chunk_size % 4) {
-		printk(KERN_ERR "raid5: invalid chunk size %d for %s\n",
-			conf->chunk_size, mdname(mddev));
-		goto abort;
+
+	return conf;
+
+ abort:
+	if (conf) {
+		shrink_stripes(conf);
+		safe_put_page(conf->spare_page);
+		kfree(conf->disks);
+		kfree(conf->stripe_hashtbl);
+		kfree(conf);
+		return ERR_PTR(-EIO);
+	} else
+		return ERR_PTR(-ENOMEM);
+}
+
+static int run(mddev_t *mddev)
+{
+	raid5_conf_t *conf;
+	int working_disks = 0;
+	mdk_rdev_t *rdev;
+
+	if (mddev->reshape_position != MaxSector) {
+		/* Check that we can continue the reshape.
+		 * Currently only disks can change, it must
+		 * increase, and we must be past the point where
+		 * a stripe over-writes itself
+		 */
+		sector_t here_new, here_old;
+		int old_disks;
+		int max_degraded = (mddev->level == 6 ? 2 : 1);
+
+		if (mddev->new_level != mddev->level) {
+			printk(KERN_ERR "raid5: %s: unsupported reshape "
+			       "required - aborting.\n",
+			       mdname(mddev));
+			return -EINVAL;
+		}
+		old_disks = mddev->raid_disks - mddev->delta_disks;
+		/* reshape_position must be on a new-stripe boundary, and one
+		 * further up in new geometry must map after here in old
+		 * geometry.
+		 */
+		here_new = mddev->reshape_position;
+		if (sector_div(here_new, (mddev->new_chunk>>9)*
+			       (mddev->raid_disks - max_degraded))) {
+			printk(KERN_ERR "raid5: reshape_position not "
+			       "on a stripe boundary\n");
+			return -EINVAL;
+		}
+		/* here_new is the stripe we will write to */
+		here_old = mddev->reshape_position;
+		sector_div(here_old, (mddev->chunk_size>>9)*
+			   (old_disks-max_degraded));
+		/* here_old is the first stripe that we might need to read
+		 * from */
+		if (here_new >= here_old) {
+			/* Reading from the same stripe as writing to - bad */
+			printk(KERN_ERR "raid5: reshape_position too early for "
+			       "auto-recovery - aborting.\n");
+			return -EINVAL;
+		}
+		printk(KERN_INFO "raid5: reshape will continue\n");
+		/* OK, we should be able to continue; */
+	} else {
+		BUG_ON(mddev->level != mddev->new_level);
+		BUG_ON(mddev->layout != mddev->new_layout);
+		BUG_ON(mddev->chunk_size != mddev->new_chunk);
+		BUG_ON(mddev->delta_disks != 0);
 	}
-	if (conf->algorithm > ALGORITHM_RIGHT_SYMMETRIC) {
-		printk(KERN_ERR 
-			"raid5: unsupported parity algorithm %d for %s\n",
-			conf->algorithm, mdname(mddev));
-		goto abort;
-	}
+
+	if (mddev->private == NULL)
+		conf = setup_conf(mddev);
+	else
+		conf = mddev->private;
+
+	if (IS_ERR(conf))
+		return PTR_ERR(conf);
+
+	mddev->thread = conf->thread;
+	conf->thread = NULL;
+	mddev->private = conf;
+
+	/*
+	 * 0 for a fully functional array, 1 or 2 for a degraded array.
+	 */
+	list_for_each_entry(rdev, &mddev->disks, same_set)
+		if (rdev->raid_disk >= 0 &&
+		    test_bit(In_sync, &rdev->flags))
+			working_disks++;
+
+	mddev->degraded = conf->raid_disks - working_disks;
+
 	if (mddev->degraded > conf->max_degraded) {
 		printk(KERN_ERR "raid5: not enough operational devices for %s"
 			" (%d/%d failed)\n",
@@ -4169,6 +4526,10 @@
 		goto abort;
 	}
 
+	/* device size must be a multiple of chunk size */
+	mddev->dev_sectors &= ~(mddev->chunk_size / 512 - 1);
+	mddev->resync_max_sectors = mddev->dev_sectors;
+
 	if (mddev->degraded > 0 &&
 	    mddev->recovery_cp != MaxSector) {
 		if (mddev->ok_start_degraded)
@@ -4184,43 +4545,22 @@
 		}
 	}
 
-	{
-		mddev->thread = md_register_thread(raid5d, mddev, "%s_raid5");
-		if (!mddev->thread) {
-			printk(KERN_ERR 
-				"raid5: couldn't allocate thread for %s\n",
-				mdname(mddev));
-			goto abort;
-		}
-	}
-	memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
-		 conf->raid_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024;
-	if (grow_stripes(conf, conf->max_nr_stripes)) {
-		printk(KERN_ERR 
-			"raid5: couldn't allocate %dkB for buffers\n", memory);
-		shrink_stripes(conf);
-		md_unregister_thread(mddev->thread);
-		goto abort;
-	} else
-		printk(KERN_INFO "raid5: allocated %dkB for %s\n",
-			memory, mdname(mddev));
-
 	if (mddev->degraded == 0)
 		printk("raid5: raid level %d set %s active with %d out of %d"
-			" devices, algorithm %d\n", conf->level, mdname(mddev), 
-			mddev->raid_disks-mddev->degraded, mddev->raid_disks,
-			conf->algorithm);
+		       " devices, algorithm %d\n", conf->level, mdname(mddev),
+		       mddev->raid_disks-mddev->degraded, mddev->raid_disks,
+		       mddev->new_layout);
 	else
 		printk(KERN_ALERT "raid5: raid level %d set %s active with %d"
 			" out of %d devices, algorithm %d\n", conf->level,
 			mdname(mddev), mddev->raid_disks - mddev->degraded,
-			mddev->raid_disks, conf->algorithm);
+			mddev->raid_disks, mddev->new_layout);
 
 	print_raid5_conf(conf);
 
-	if (conf->expand_progress != MaxSector) {
+	if (conf->reshape_progress != MaxSector) {
 		printk("...ok start reshape thread\n");
-		conf->expand_lo = conf->expand_progress;
+		conf->reshape_safe = conf->reshape_progress;
 		atomic_set(&conf->reshape_stripes, 0);
 		clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
 		clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
@@ -4247,18 +4587,22 @@
 		       "raid5: failed to create sysfs attributes for %s\n",
 		       mdname(mddev));
 
+	mddev->queue->queue_lock = &conf->device_lock;
+
 	mddev->queue->unplug_fn = raid5_unplug_device;
 	mddev->queue->backing_dev_info.congested_data = mddev;
 	mddev->queue->backing_dev_info.congested_fn = raid5_congested;
 
-	mddev->array_sectors = 2 * mddev->size * (conf->previous_raid_disks -
-					    conf->max_degraded);
+	md_set_array_sectors(mddev, raid5_size(mddev, 0, 0));
 
 	blk_queue_merge_bvec(mddev->queue, raid5_mergeable_bvec);
 
 	return 0;
 abort:
+	md_unregister_thread(mddev->thread);
+	mddev->thread = NULL;
 	if (conf) {
+		shrink_stripes(conf);
 		print_raid5_conf(conf);
 		safe_put_page(conf->spare_page);
 		kfree(conf->disks);
@@ -4396,6 +4740,10 @@
 	print_raid5_conf(conf);
 	rdev = p->rdev;
 	if (rdev) {
+		if (number >= conf->raid_disks &&
+		    conf->reshape_progress == MaxSector)
+			clear_bit(In_sync, &rdev->flags);
+
 		if (test_bit(In_sync, &rdev->flags) ||
 		    atomic_read(&rdev->nr_pending)) {
 			err = -EBUSY;
@@ -4405,7 +4753,8 @@
 		 * isn't possible.
 		 */
 		if (!test_bit(Faulty, &rdev->flags) &&
-		    mddev->degraded <= conf->max_degraded) {
+		    mddev->degraded <= conf->max_degraded &&
+		    number < conf->raid_disks) {
 			err = -EBUSY;
 			goto abort;
 		}
@@ -4472,36 +4821,48 @@
 	 * any io in the removed space completes, but it hardly seems
 	 * worth it.
 	 */
-	raid5_conf_t *conf = mddev_to_conf(mddev);
-
 	sectors &= ~((sector_t)mddev->chunk_size/512 - 1);
-	mddev->array_sectors = sectors * (mddev->raid_disks
-					  - conf->max_degraded);
+	md_set_array_sectors(mddev, raid5_size(mddev, sectors,
+					       mddev->raid_disks));
+	if (mddev->array_sectors >
+	    raid5_size(mddev, sectors, mddev->raid_disks))
+		return -EINVAL;
 	set_capacity(mddev->gendisk, mddev->array_sectors);
 	mddev->changed = 1;
-	if (sectors/2  > mddev->size && mddev->recovery_cp == MaxSector) {
-		mddev->recovery_cp = mddev->size << 1;
+	if (sectors > mddev->dev_sectors && mddev->recovery_cp == MaxSector) {
+		mddev->recovery_cp = mddev->dev_sectors;
 		set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
 	}
-	mddev->size = sectors /2;
+	mddev->dev_sectors = sectors;
 	mddev->resync_max_sectors = sectors;
 	return 0;
 }
 
-#ifdef CONFIG_MD_RAID5_RESHAPE
 static int raid5_check_reshape(mddev_t *mddev)
 {
 	raid5_conf_t *conf = mddev_to_conf(mddev);
-	int err;
 
-	if (mddev->delta_disks < 0 ||
-	    mddev->new_level != mddev->level)
-		return -EINVAL; /* Cannot shrink array or change level yet */
-	if (mddev->delta_disks == 0)
-		return 0; /* nothing to do */
+	if (mddev->delta_disks == 0 &&
+	    mddev->new_layout == mddev->layout &&
+	    mddev->new_chunk == mddev->chunk_size)
+		return -EINVAL; /* nothing to do */
 	if (mddev->bitmap)
 		/* Cannot grow a bitmap yet */
 		return -EBUSY;
+	if (mddev->degraded > conf->max_degraded)
+		return -EINVAL;
+	if (mddev->delta_disks < 0) {
+		/* We might be able to shrink, but the devices must
+		 * be made bigger first.
+		 * For raid6, 4 is the minimum size.
+		 * Otherwise 2 is the minimum
+		 */
+		int min = 2;
+		if (mddev->level == 6)
+			min = 4;
+		if (mddev->raid_disks + mddev->delta_disks < min)
+			return -EINVAL;
+	}
 
 	/* Can only proceed if there are plenty of stripe_heads.
 	 * We need a minimum of one full stripe,, and for sensible progress
@@ -4514,18 +4875,12 @@
 	if ((mddev->chunk_size / STRIPE_SIZE) * 4 > conf->max_nr_stripes ||
 	    (mddev->new_chunk / STRIPE_SIZE) * 4 > conf->max_nr_stripes) {
 		printk(KERN_WARNING "raid5: reshape: not enough stripes.  Needed %lu\n",
-		       (mddev->chunk_size / STRIPE_SIZE)*4);
+		       (max(mddev->chunk_size, mddev->new_chunk)
+			/ STRIPE_SIZE)*4);
 		return -ENOSPC;
 	}
 
-	err = resize_stripes(conf, conf->raid_disks + mddev->delta_disks);
-	if (err)
-		return err;
-
-	if (mddev->degraded > conf->max_degraded)
-		return -EINVAL;
-	/* looks like we might be able to manage this */
-	return 0;
+	return resize_stripes(conf, conf->raid_disks + mddev->delta_disks);
 }
 
 static int raid5_start_reshape(mddev_t *mddev)
@@ -4550,12 +4905,31 @@
 		 */
 		return -EINVAL;
 
+	/* Refuse to reduce size of the array.  Any reductions in
+	 * array size must be through explicit setting of array_size
+	 * attribute.
+	 */
+	if (raid5_size(mddev, 0, conf->raid_disks + mddev->delta_disks)
+	    < mddev->array_sectors) {
+		printk(KERN_ERR "md: %s: array size must be reduced "
+		       "before number of disks\n", mdname(mddev));
+		return -EINVAL;
+	}
+
 	atomic_set(&conf->reshape_stripes, 0);
 	spin_lock_irq(&conf->device_lock);
 	conf->previous_raid_disks = conf->raid_disks;
 	conf->raid_disks += mddev->delta_disks;
-	conf->expand_progress = 0;
-	conf->expand_lo = 0;
+	conf->prev_chunk = conf->chunk_size;
+	conf->chunk_size = mddev->new_chunk;
+	conf->prev_algo = conf->algorithm;
+	conf->algorithm = mddev->new_layout;
+	if (mddev->delta_disks < 0)
+		conf->reshape_progress = raid5_size(mddev, 0, 0);
+	else
+		conf->reshape_progress = 0;
+	conf->reshape_safe = conf->reshape_progress;
+	conf->generation++;
 	spin_unlock_irq(&conf->device_lock);
 
 	/* Add some new drives, as many as will fit.
@@ -4580,9 +4954,12 @@
 				break;
 		}
 
-	spin_lock_irqsave(&conf->device_lock, flags);
-	mddev->degraded = (conf->raid_disks - conf->previous_raid_disks) - added_devices;
-	spin_unlock_irqrestore(&conf->device_lock, flags);
+	if (mddev->delta_disks > 0) {
+		spin_lock_irqsave(&conf->device_lock, flags);
+		mddev->degraded = (conf->raid_disks - conf->previous_raid_disks)
+			- added_devices;
+		spin_unlock_irqrestore(&conf->device_lock, flags);
+	}
 	mddev->raid_disks = conf->raid_disks;
 	mddev->reshape_position = 0;
 	set_bit(MD_CHANGE_DEVS, &mddev->flags);
@@ -4597,52 +4974,86 @@
 		mddev->recovery = 0;
 		spin_lock_irq(&conf->device_lock);
 		mddev->raid_disks = conf->raid_disks = conf->previous_raid_disks;
-		conf->expand_progress = MaxSector;
+		conf->reshape_progress = MaxSector;
 		spin_unlock_irq(&conf->device_lock);
 		return -EAGAIN;
 	}
+	conf->reshape_checkpoint = jiffies;
 	md_wakeup_thread(mddev->sync_thread);
 	md_new_event(mddev);
 	return 0;
 }
-#endif
 
+/* This is called from the reshape thread and should make any
+ * changes needed in 'conf'
+ */
 static void end_reshape(raid5_conf_t *conf)
 {
-	struct block_device *bdev;
 
 	if (!test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) {
-		conf->mddev->array_sectors = 2 * conf->mddev->size *
-			(conf->raid_disks - conf->max_degraded);
-		set_capacity(conf->mddev->gendisk, conf->mddev->array_sectors);
-		conf->mddev->changed = 1;
 
-		bdev = bdget_disk(conf->mddev->gendisk, 0);
-		if (bdev) {
-			mutex_lock(&bdev->bd_inode->i_mutex);
-			i_size_write(bdev->bd_inode,
-				     (loff_t)conf->mddev->array_sectors << 9);
-			mutex_unlock(&bdev->bd_inode->i_mutex);
-			bdput(bdev);
-		}
 		spin_lock_irq(&conf->device_lock);
-		conf->expand_progress = MaxSector;
+		conf->previous_raid_disks = conf->raid_disks;
+		conf->reshape_progress = MaxSector;
 		spin_unlock_irq(&conf->device_lock);
-		conf->mddev->reshape_position = MaxSector;
+		wake_up(&conf->wait_for_overlap);
 
 		/* read-ahead size must cover two whole stripes, which is
 		 * 2 * (datadisks) * chunksize where 'n' is the number of raid devices
 		 */
 		{
-			int data_disks = conf->previous_raid_disks - conf->max_degraded;
-			int stripe = data_disks *
-				(conf->mddev->chunk_size / PAGE_SIZE);
+			int data_disks = conf->raid_disks - conf->max_degraded;
+			int stripe = data_disks * (conf->chunk_size
+						   / PAGE_SIZE);
 			if (conf->mddev->queue->backing_dev_info.ra_pages < 2 * stripe)
 				conf->mddev->queue->backing_dev_info.ra_pages = 2 * stripe;
 		}
 	}
 }
 
+/* This is called from the raid5d thread with mddev_lock held.
+ * It makes config changes to the device.
+ */
+static void raid5_finish_reshape(mddev_t *mddev)
+{
+	struct block_device *bdev;
+	raid5_conf_t *conf = mddev_to_conf(mddev);
+
+	if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) {
+
+		if (mddev->delta_disks > 0) {
+			md_set_array_sectors(mddev, raid5_size(mddev, 0, 0));
+			set_capacity(mddev->gendisk, mddev->array_sectors);
+			mddev->changed = 1;
+
+			bdev = bdget_disk(mddev->gendisk, 0);
+			if (bdev) {
+				mutex_lock(&bdev->bd_inode->i_mutex);
+				i_size_write(bdev->bd_inode,
+					     (loff_t)mddev->array_sectors << 9);
+				mutex_unlock(&bdev->bd_inode->i_mutex);
+				bdput(bdev);
+			}
+		} else {
+			int d;
+			mddev->degraded = conf->raid_disks;
+			for (d = 0; d < conf->raid_disks ; d++)
+				if (conf->disks[d].rdev &&
+				    test_bit(In_sync,
+					     &conf->disks[d].rdev->flags))
+					mddev->degraded--;
+			for (d = conf->raid_disks ;
+			     d < conf->raid_disks - mddev->delta_disks;
+			     d++)
+				raid5_remove_disk(mddev, d);
+		}
+		mddev->layout = conf->algorithm;
+		mddev->chunk_size = conf->chunk_size;
+		mddev->reshape_position = MaxSector;
+		mddev->delta_disks = 0;
+	}
+}
+
 static void raid5_quiesce(mddev_t *mddev, int state)
 {
 	raid5_conf_t *conf = mddev_to_conf(mddev);
@@ -4672,6 +5083,212 @@
 	}
 }
 
+
+static void *raid5_takeover_raid1(mddev_t *mddev)
+{
+	int chunksect;
+
+	if (mddev->raid_disks != 2 ||
+	    mddev->degraded > 1)
+		return ERR_PTR(-EINVAL);
+
+	/* Should check if there are write-behind devices? */
+
+	chunksect = 64*2; /* 64K by default */
+
+	/* The array must be an exact multiple of chunksize */
+	while (chunksect && (mddev->array_sectors & (chunksect-1)))
+		chunksect >>= 1;
+
+	if ((chunksect<<9) < STRIPE_SIZE)
+		/* array size does not allow a suitable chunk size */
+		return ERR_PTR(-EINVAL);
+
+	mddev->new_level = 5;
+	mddev->new_layout = ALGORITHM_LEFT_SYMMETRIC;
+	mddev->new_chunk = chunksect << 9;
+
+	return setup_conf(mddev);
+}
+
+static void *raid5_takeover_raid6(mddev_t *mddev)
+{
+	int new_layout;
+
+	switch (mddev->layout) {
+	case ALGORITHM_LEFT_ASYMMETRIC_6:
+		new_layout = ALGORITHM_LEFT_ASYMMETRIC;
+		break;
+	case ALGORITHM_RIGHT_ASYMMETRIC_6:
+		new_layout = ALGORITHM_RIGHT_ASYMMETRIC;
+		break;
+	case ALGORITHM_LEFT_SYMMETRIC_6:
+		new_layout = ALGORITHM_LEFT_SYMMETRIC;
+		break;
+	case ALGORITHM_RIGHT_SYMMETRIC_6:
+		new_layout = ALGORITHM_RIGHT_SYMMETRIC;
+		break;
+	case ALGORITHM_PARITY_0_6:
+		new_layout = ALGORITHM_PARITY_0;
+		break;
+	case ALGORITHM_PARITY_N:
+		new_layout = ALGORITHM_PARITY_N;
+		break;
+	default:
+		return ERR_PTR(-EINVAL);
+	}
+	mddev->new_level = 5;
+	mddev->new_layout = new_layout;
+	mddev->delta_disks = -1;
+	mddev->raid_disks -= 1;
+	return setup_conf(mddev);
+}
+
+
+static int raid5_reconfig(mddev_t *mddev, int new_layout, int new_chunk)
+{
+	/* For a 2-drive array, the layout and chunk size can be changed
+	 * immediately as not restriping is needed.
+	 * For larger arrays we record the new value - after validation
+	 * to be used by a reshape pass.
+	 */
+	raid5_conf_t *conf = mddev_to_conf(mddev);
+
+	if (new_layout >= 0 && !algorithm_valid_raid5(new_layout))
+		return -EINVAL;
+	if (new_chunk > 0) {
+		if (new_chunk & (new_chunk-1))
+			/* not a power of 2 */
+			return -EINVAL;
+		if (new_chunk < PAGE_SIZE)
+			return -EINVAL;
+		if (mddev->array_sectors & ((new_chunk>>9)-1))
+			/* not factor of array size */
+			return -EINVAL;
+	}
+
+	/* They look valid */
+
+	if (mddev->raid_disks == 2) {
+
+		if (new_layout >= 0) {
+			conf->algorithm = new_layout;
+			mddev->layout = mddev->new_layout = new_layout;
+		}
+		if (new_chunk > 0) {
+			conf->chunk_size = new_chunk;
+			mddev->chunk_size = mddev->new_chunk = new_chunk;
+		}
+		set_bit(MD_CHANGE_DEVS, &mddev->flags);
+		md_wakeup_thread(mddev->thread);
+	} else {
+		if (new_layout >= 0)
+			mddev->new_layout = new_layout;
+		if (new_chunk > 0)
+			mddev->new_chunk = new_chunk;
+	}
+	return 0;
+}
+
+static int raid6_reconfig(mddev_t *mddev, int new_layout, int new_chunk)
+{
+	if (new_layout >= 0 && !algorithm_valid_raid6(new_layout))
+		return -EINVAL;
+	if (new_chunk > 0) {
+		if (new_chunk & (new_chunk-1))
+			/* not a power of 2 */
+			return -EINVAL;
+		if (new_chunk < PAGE_SIZE)
+			return -EINVAL;
+		if (mddev->array_sectors & ((new_chunk>>9)-1))
+			/* not factor of array size */
+			return -EINVAL;
+	}
+
+	/* They look valid */
+
+	if (new_layout >= 0)
+		mddev->new_layout = new_layout;
+	if (new_chunk > 0)
+		mddev->new_chunk = new_chunk;
+
+	return 0;
+}
+
+static void *raid5_takeover(mddev_t *mddev)
+{
+	/* raid5 can take over:
+	 *  raid0 - if all devices are the same - make it a raid4 layout
+	 *  raid1 - if there are two drives.  We need to know the chunk size
+	 *  raid4 - trivial - just use a raid4 layout.
+	 *  raid6 - Providing it is a *_6 layout
+	 *
+	 * For now, just do raid1
+	 */
+
+	if (mddev->level == 1)
+		return raid5_takeover_raid1(mddev);
+	if (mddev->level == 4) {
+		mddev->new_layout = ALGORITHM_PARITY_N;
+		mddev->new_level = 5;
+		return setup_conf(mddev);
+	}
+	if (mddev->level == 6)
+		return raid5_takeover_raid6(mddev);
+
+	return ERR_PTR(-EINVAL);
+}
+
+
+static struct mdk_personality raid5_personality;
+
+static void *raid6_takeover(mddev_t *mddev)
+{
+	/* Currently can only take over a raid5.  We map the
+	 * personality to an equivalent raid6 personality
+	 * with the Q block at the end.
+	 */
+	int new_layout;
+
+	if (mddev->pers != &raid5_personality)
+		return ERR_PTR(-EINVAL);
+	if (mddev->degraded > 1)
+		return ERR_PTR(-EINVAL);
+	if (mddev->raid_disks > 253)
+		return ERR_PTR(-EINVAL);
+	if (mddev->raid_disks < 3)
+		return ERR_PTR(-EINVAL);
+
+	switch (mddev->layout) {
+	case ALGORITHM_LEFT_ASYMMETRIC:
+		new_layout = ALGORITHM_LEFT_ASYMMETRIC_6;
+		break;
+	case ALGORITHM_RIGHT_ASYMMETRIC:
+		new_layout = ALGORITHM_RIGHT_ASYMMETRIC_6;
+		break;
+	case ALGORITHM_LEFT_SYMMETRIC:
+		new_layout = ALGORITHM_LEFT_SYMMETRIC_6;
+		break;
+	case ALGORITHM_RIGHT_SYMMETRIC:
+		new_layout = ALGORITHM_RIGHT_SYMMETRIC_6;
+		break;
+	case ALGORITHM_PARITY_0:
+		new_layout = ALGORITHM_PARITY_0_6;
+		break;
+	case ALGORITHM_PARITY_N:
+		new_layout = ALGORITHM_PARITY_N;
+		break;
+	default:
+		return ERR_PTR(-EINVAL);
+	}
+	mddev->new_level = 6;
+	mddev->new_layout = new_layout;
+	mddev->delta_disks = 1;
+	mddev->raid_disks += 1;
+	return setup_conf(mddev);
+}
+
+
 static struct mdk_personality raid6_personality =
 {
 	.name		= "raid6",
@@ -4687,11 +5304,13 @@
 	.spare_active	= raid5_spare_active,
 	.sync_request	= sync_request,
 	.resize		= raid5_resize,
-#ifdef CONFIG_MD_RAID5_RESHAPE
+	.size		= raid5_size,
 	.check_reshape	= raid5_check_reshape,
 	.start_reshape  = raid5_start_reshape,
-#endif
+	.finish_reshape = raid5_finish_reshape,
 	.quiesce	= raid5_quiesce,
+	.takeover	= raid6_takeover,
+	.reconfig	= raid6_reconfig,
 };
 static struct mdk_personality raid5_personality =
 {
@@ -4708,11 +5327,13 @@
 	.spare_active	= raid5_spare_active,
 	.sync_request	= sync_request,
 	.resize		= raid5_resize,
-#ifdef CONFIG_MD_RAID5_RESHAPE
+	.size		= raid5_size,
 	.check_reshape	= raid5_check_reshape,
 	.start_reshape  = raid5_start_reshape,
-#endif
+	.finish_reshape = raid5_finish_reshape,
 	.quiesce	= raid5_quiesce,
+	.takeover	= raid5_takeover,
+	.reconfig	= raid5_reconfig,
 };
 
 static struct mdk_personality raid4_personality =
@@ -4730,20 +5351,15 @@
 	.spare_active	= raid5_spare_active,
 	.sync_request	= sync_request,
 	.resize		= raid5_resize,
-#ifdef CONFIG_MD_RAID5_RESHAPE
+	.size		= raid5_size,
 	.check_reshape	= raid5_check_reshape,
 	.start_reshape  = raid5_start_reshape,
-#endif
+	.finish_reshape = raid5_finish_reshape,
 	.quiesce	= raid5_quiesce,
 };
 
 static int __init raid5_init(void)
 {
-	int e;
-
-	e = raid6_select_algo();
-	if ( e )
-		return e;
 	register_md_personality(&raid6_personality);
 	register_md_personality(&raid5_personality);
 	register_md_personality(&raid4_personality);
diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h
new file mode 100644
index 0000000..52ba999
--- /dev/null
+++ b/drivers/md/raid5.h
@@ -0,0 +1,474 @@
+#ifndef _RAID5_H
+#define _RAID5_H
+
+#include <linux/raid/xor.h>
+
+/*
+ *
+ * Each stripe contains one buffer per disc.  Each buffer can be in
+ * one of a number of states stored in "flags".  Changes between
+ * these states happen *almost* exclusively under a per-stripe
+ * spinlock.  Some very specific changes can happen in bi_end_io, and
+ * these are not protected by the spin lock.
+ *
+ * The flag bits that are used to represent these states are:
+ *   R5_UPTODATE and R5_LOCKED
+ *
+ * State Empty == !UPTODATE, !LOCK
+ *        We have no data, and there is no active request
+ * State Want == !UPTODATE, LOCK
+ *        A read request is being submitted for this block
+ * State Dirty == UPTODATE, LOCK
+ *        Some new data is in this buffer, and it is being written out
+ * State Clean == UPTODATE, !LOCK
+ *        We have valid data which is the same as on disc
+ *
+ * The possible state transitions are:
+ *
+ *  Empty -> Want   - on read or write to get old data for  parity calc
+ *  Empty -> Dirty  - on compute_parity to satisfy write/sync request.(RECONSTRUCT_WRITE)
+ *  Empty -> Clean  - on compute_block when computing a block for failed drive
+ *  Want  -> Empty  - on failed read
+ *  Want  -> Clean  - on successful completion of read request
+ *  Dirty -> Clean  - on successful completion of write request
+ *  Dirty -> Clean  - on failed write
+ *  Clean -> Dirty  - on compute_parity to satisfy write/sync (RECONSTRUCT or RMW)
+ *
+ * The Want->Empty, Want->Clean, Dirty->Clean, transitions
+ * all happen in b_end_io at interrupt time.
+ * Each sets the Uptodate bit before releasing the Lock bit.
+ * This leaves one multi-stage transition:
+ *    Want->Dirty->Clean
+ * This is safe because thinking that a Clean buffer is actually dirty
+ * will at worst delay some action, and the stripe will be scheduled
+ * for attention after the transition is complete.
+ *
+ * There is one possibility that is not covered by these states.  That
+ * is if one drive has failed and there is a spare being rebuilt.  We
+ * can't distinguish between a clean block that has been generated
+ * from parity calculations, and a clean block that has been
+ * successfully written to the spare ( or to parity when resyncing).
+ * To distingush these states we have a stripe bit STRIPE_INSYNC that
+ * is set whenever a write is scheduled to the spare, or to the parity
+ * disc if there is no spare.  A sync request clears this bit, and
+ * when we find it set with no buffers locked, we know the sync is
+ * complete.
+ *
+ * Buffers for the md device that arrive via make_request are attached
+ * to the appropriate stripe in one of two lists linked on b_reqnext.
+ * One list (bh_read) for read requests, one (bh_write) for write.
+ * There should never be more than one buffer on the two lists
+ * together, but we are not guaranteed of that so we allow for more.
+ *
+ * If a buffer is on the read list when the associated cache buffer is
+ * Uptodate, the data is copied into the read buffer and it's b_end_io
+ * routine is called.  This may happen in the end_request routine only
+ * if the buffer has just successfully been read.  end_request should
+ * remove the buffers from the list and then set the Uptodate bit on
+ * the buffer.  Other threads may do this only if they first check
+ * that the Uptodate bit is set.  Once they have checked that they may
+ * take buffers off the read queue.
+ *
+ * When a buffer on the write list is committed for write it is copied
+ * into the cache buffer, which is then marked dirty, and moved onto a
+ * third list, the written list (bh_written).  Once both the parity
+ * block and the cached buffer are successfully written, any buffer on
+ * a written list can be returned with b_end_io.
+ *
+ * The write list and read list both act as fifos.  The read list is
+ * protected by the device_lock.  The write and written lists are
+ * protected by the stripe lock.  The device_lock, which can be
+ * claimed while the stipe lock is held, is only for list
+ * manipulations and will only be held for a very short time.  It can
+ * be claimed from interrupts.
+ *
+ *
+ * Stripes in the stripe cache can be on one of two lists (or on
+ * neither).  The "inactive_list" contains stripes which are not
+ * currently being used for any request.  They can freely be reused
+ * for another stripe.  The "handle_list" contains stripes that need
+ * to be handled in some way.  Both of these are fifo queues.  Each
+ * stripe is also (potentially) linked to a hash bucket in the hash
+ * table so that it can be found by sector number.  Stripes that are
+ * not hashed must be on the inactive_list, and will normally be at
+ * the front.  All stripes start life this way.
+ *
+ * The inactive_list, handle_list and hash bucket lists are all protected by the
+ * device_lock.
+ *  - stripes on the inactive_list never have their stripe_lock held.
+ *  - stripes have a reference counter. If count==0, they are on a list.
+ *  - If a stripe might need handling, STRIPE_HANDLE is set.
+ *  - When refcount reaches zero, then if STRIPE_HANDLE it is put on
+ *    handle_list else inactive_list
+ *
+ * This, combined with the fact that STRIPE_HANDLE is only ever
+ * cleared while a stripe has a non-zero count means that if the
+ * refcount is 0 and STRIPE_HANDLE is set, then it is on the
+ * handle_list and if recount is 0 and STRIPE_HANDLE is not set, then
+ * the stripe is on inactive_list.
+ *
+ * The possible transitions are:
+ *  activate an unhashed/inactive stripe (get_active_stripe())
+ *     lockdev check-hash unlink-stripe cnt++ clean-stripe hash-stripe unlockdev
+ *  activate a hashed, possibly active stripe (get_active_stripe())
+ *     lockdev check-hash if(!cnt++)unlink-stripe unlockdev
+ *  attach a request to an active stripe (add_stripe_bh())
+ *     lockdev attach-buffer unlockdev
+ *  handle a stripe (handle_stripe())
+ *     lockstripe clrSTRIPE_HANDLE ...
+ *		(lockdev check-buffers unlockdev) ..
+ *		change-state ..
+ *		record io/ops needed unlockstripe schedule io/ops
+ *  release an active stripe (release_stripe())
+ *     lockdev if (!--cnt) { if  STRIPE_HANDLE, add to handle_list else add to inactive-list } unlockdev
+ *
+ * The refcount counts each thread that have activated the stripe,
+ * plus raid5d if it is handling it, plus one for each active request
+ * on a cached buffer, and plus one if the stripe is undergoing stripe
+ * operations.
+ *
+ * Stripe operations are performed outside the stripe lock,
+ * the stripe operations are:
+ * -copying data between the stripe cache and user application buffers
+ * -computing blocks to save a disk access, or to recover a missing block
+ * -updating the parity on a write operation (reconstruct write and
+ *  read-modify-write)
+ * -checking parity correctness
+ * -running i/o to disk
+ * These operations are carried out by raid5_run_ops which uses the async_tx
+ * api to (optionally) offload operations to dedicated hardware engines.
+ * When requesting an operation handle_stripe sets the pending bit for the
+ * operation and increments the count.  raid5_run_ops is then run whenever
+ * the count is non-zero.
+ * There are some critical dependencies between the operations that prevent some
+ * from being requested while another is in flight.
+ * 1/ Parity check operations destroy the in cache version of the parity block,
+ *    so we prevent parity dependent operations like writes and compute_blocks
+ *    from starting while a check is in progress.  Some dma engines can perform
+ *    the check without damaging the parity block, in these cases the parity
+ *    block is re-marked up to date (assuming the check was successful) and is
+ *    not re-read from disk.
+ * 2/ When a write operation is requested we immediately lock the affected
+ *    blocks, and mark them as not up to date.  This causes new read requests
+ *    to be held off, as well as parity checks and compute block operations.
+ * 3/ Once a compute block operation has been requested handle_stripe treats
+ *    that block as if it is up to date.  raid5_run_ops guaruntees that any
+ *    operation that is dependent on the compute block result is initiated after
+ *    the compute block completes.
+ */
+
+/*
+ * Operations state - intermediate states that are visible outside of sh->lock
+ * In general _idle indicates nothing is running, _run indicates a data
+ * processing operation is active, and _result means the data processing result
+ * is stable and can be acted upon.  For simple operations like biofill and
+ * compute that only have an _idle and _run state they are indicated with
+ * sh->state flags (STRIPE_BIOFILL_RUN and STRIPE_COMPUTE_RUN)
+ */
+/**
+ * enum check_states - handles syncing / repairing a stripe
+ * @check_state_idle - check operations are quiesced
+ * @check_state_run - check operation is running
+ * @check_state_result - set outside lock when check result is valid
+ * @check_state_compute_run - check failed and we are repairing
+ * @check_state_compute_result - set outside lock when compute result is valid
+ */
+enum check_states {
+	check_state_idle = 0,
+	check_state_run, /* parity check */
+	check_state_check_result,
+	check_state_compute_run, /* parity repair */
+	check_state_compute_result,
+};
+
+/**
+ * enum reconstruct_states - handles writing or expanding a stripe
+ */
+enum reconstruct_states {
+	reconstruct_state_idle = 0,
+	reconstruct_state_prexor_drain_run,	/* prexor-write */
+	reconstruct_state_drain_run,		/* write */
+	reconstruct_state_run,			/* expand */
+	reconstruct_state_prexor_drain_result,
+	reconstruct_state_drain_result,
+	reconstruct_state_result,
+};
+
+struct stripe_head {
+	struct hlist_node	hash;
+	struct list_head	lru;	      /* inactive_list or handle_list */
+	struct raid5_private_data *raid_conf;
+	short			generation;	/* increments with every
+						 * reshape */
+	sector_t		sector;		/* sector of this row */
+	short			pd_idx;		/* parity disk index */
+	short			qd_idx;		/* 'Q' disk index for raid6 */
+	short			ddf_layout;/* use DDF ordering to calculate Q */
+	unsigned long		state;		/* state flags */
+	atomic_t		count;	      /* nr of active thread/requests */
+	spinlock_t		lock;
+	int			bm_seq;	/* sequence number for bitmap flushes */
+	int			disks;		/* disks in stripe */
+	enum check_states	check_state;
+	enum reconstruct_states reconstruct_state;
+	/* stripe_operations
+	 * @target - STRIPE_OP_COMPUTE_BLK target
+	 */
+	struct stripe_operations {
+		int		   target;
+		u32		   zero_sum_result;
+	} ops;
+	struct r5dev {
+		struct bio	req;
+		struct bio_vec	vec;
+		struct page	*page;
+		struct bio	*toread, *read, *towrite, *written;
+		sector_t	sector;			/* sector of this page */
+		unsigned long	flags;
+	} dev[1]; /* allocated with extra space depending of RAID geometry */
+};
+
+/* stripe_head_state - collects and tracks the dynamic state of a stripe_head
+ *     for handle_stripe.  It is only valid under spin_lock(sh->lock);
+ */
+struct stripe_head_state {
+	int syncing, expanding, expanded;
+	int locked, uptodate, to_read, to_write, failed, written;
+	int to_fill, compute, req_compute, non_overwrite;
+	int failed_num;
+	unsigned long ops_request;
+};
+
+/* r6_state - extra state data only relevant to r6 */
+struct r6_state {
+	int p_failed, q_failed, failed_num[2];
+};
+
+/* Flags */
+#define	R5_UPTODATE	0	/* page contains current data */
+#define	R5_LOCKED	1	/* IO has been submitted on "req" */
+#define	R5_OVERWRITE	2	/* towrite covers whole page */
+/* and some that are internal to handle_stripe */
+#define	R5_Insync	3	/* rdev && rdev->in_sync at start */
+#define	R5_Wantread	4	/* want to schedule a read */
+#define	R5_Wantwrite	5
+#define	R5_Overlap	7	/* There is a pending overlapping request on this block */
+#define	R5_ReadError	8	/* seen a read error here recently */
+#define	R5_ReWrite	9	/* have tried to over-write the readerror */
+
+#define	R5_Expanded	10	/* This block now has post-expand data */
+#define	R5_Wantcompute	11 /* compute_block in progress treat as
+				    * uptodate
+				    */
+#define	R5_Wantfill	12 /* dev->toread contains a bio that needs
+				    * filling
+				    */
+#define R5_Wantdrain	13 /* dev->towrite needs to be drained */
+/*
+ * Write method
+ */
+#define RECONSTRUCT_WRITE	1
+#define READ_MODIFY_WRITE	2
+/* not a write method, but a compute_parity mode */
+#define	CHECK_PARITY		3
+/* Additional compute_parity mode -- updates the parity w/o LOCKING */
+#define UPDATE_PARITY		4
+
+/*
+ * Stripe state
+ */
+#define STRIPE_HANDLE		2
+#define	STRIPE_SYNCING		3
+#define	STRIPE_INSYNC		4
+#define	STRIPE_PREREAD_ACTIVE	5
+#define	STRIPE_DELAYED		6
+#define	STRIPE_DEGRADED		7
+#define	STRIPE_BIT_DELAY	8
+#define	STRIPE_EXPANDING	9
+#define	STRIPE_EXPAND_SOURCE	10
+#define	STRIPE_EXPAND_READY	11
+#define	STRIPE_IO_STARTED	12 /* do not count towards 'bypass_count' */
+#define	STRIPE_FULL_WRITE	13 /* all blocks are set to be overwritten */
+#define	STRIPE_BIOFILL_RUN	14
+#define	STRIPE_COMPUTE_RUN	15
+/*
+ * Operation request flags
+ */
+#define STRIPE_OP_BIOFILL	0
+#define STRIPE_OP_COMPUTE_BLK	1
+#define STRIPE_OP_PREXOR	2
+#define STRIPE_OP_BIODRAIN	3
+#define STRIPE_OP_POSTXOR	4
+#define STRIPE_OP_CHECK	5
+
+/*
+ * Plugging:
+ *
+ * To improve write throughput, we need to delay the handling of some
+ * stripes until there has been a chance that several write requests
+ * for the one stripe have all been collected.
+ * In particular, any write request that would require pre-reading
+ * is put on a "delayed" queue until there are no stripes currently
+ * in a pre-read phase.  Further, if the "delayed" queue is empty when
+ * a stripe is put on it then we "plug" the queue and do not process it
+ * until an unplug call is made. (the unplug_io_fn() is called).
+ *
+ * When preread is initiated on a stripe, we set PREREAD_ACTIVE and add
+ * it to the count of prereading stripes.
+ * When write is initiated, or the stripe refcnt == 0 (just in case) we
+ * clear the PREREAD_ACTIVE flag and decrement the count
+ * Whenever the 'handle' queue is empty and the device is not plugged, we
+ * move any strips from delayed to handle and clear the DELAYED flag and set
+ * PREREAD_ACTIVE.
+ * In stripe_handle, if we find pre-reading is necessary, we do it if
+ * PREREAD_ACTIVE is set, else we set DELAYED which will send it to the delayed queue.
+ * HANDLE gets cleared if stripe_handle leave nothing locked.
+ */
+
+
+struct disk_info {
+	mdk_rdev_t	*rdev;
+};
+
+struct raid5_private_data {
+	struct hlist_head	*stripe_hashtbl;
+	mddev_t			*mddev;
+	struct disk_info	*spare;
+	int			chunk_size, level, algorithm;
+	int			max_degraded;
+	int			raid_disks;
+	int			max_nr_stripes;
+
+	/* reshape_progress is the leading edge of a 'reshape'
+	 * It has value MaxSector when no reshape is happening
+	 * If delta_disks < 0, it is the last sector we started work on,
+	 * else is it the next sector to work on.
+	 */
+	sector_t		reshape_progress;
+	/* reshape_safe is the trailing edge of a reshape.  We know that
+	 * before (or after) this address, all reshape has completed.
+	 */
+	sector_t		reshape_safe;
+	int			previous_raid_disks;
+	int			prev_chunk, prev_algo;
+	short			generation; /* increments with every reshape */
+	unsigned long		reshape_checkpoint; /* Time we last updated
+						     * metadata */
+
+	struct list_head	handle_list; /* stripes needing handling */
+	struct list_head	hold_list; /* preread ready stripes */
+	struct list_head	delayed_list; /* stripes that have plugged requests */
+	struct list_head	bitmap_list; /* stripes delaying awaiting bitmap update */
+	struct bio		*retry_read_aligned; /* currently retrying aligned bios   */
+	struct bio		*retry_read_aligned_list; /* aligned bios retry list  */
+	atomic_t		preread_active_stripes; /* stripes with scheduled io */
+	atomic_t		active_aligned_reads;
+	atomic_t		pending_full_writes; /* full write backlog */
+	int			bypass_count; /* bypassed prereads */
+	int			bypass_threshold; /* preread nice */
+	struct list_head	*last_hold; /* detect hold_list promotions */
+
+	atomic_t		reshape_stripes; /* stripes with pending writes for reshape */
+	/* unfortunately we need two cache names as we temporarily have
+	 * two caches.
+	 */
+	int			active_name;
+	char			cache_name[2][20];
+	struct kmem_cache		*slab_cache; /* for allocating stripes */
+
+	int			seq_flush, seq_write;
+	int			quiesce;
+
+	int			fullsync;  /* set to 1 if a full sync is needed,
+					    * (fresh device added).
+					    * Cleared when a sync completes.
+					    */
+
+	struct page 		*spare_page; /* Used when checking P/Q in raid6 */
+
+	/*
+	 * Free stripes pool
+	 */
+	atomic_t		active_stripes;
+	struct list_head	inactive_list;
+	wait_queue_head_t	wait_for_stripe;
+	wait_queue_head_t	wait_for_overlap;
+	int			inactive_blocked;	/* release of inactive stripes blocked,
+							 * waiting for 25% to be free
+							 */
+	int			pool_size; /* number of disks in stripeheads in pool */
+	spinlock_t		device_lock;
+	struct disk_info	*disks;
+
+	/* When taking over an array from a different personality, we store
+	 * the new thread here until we fully activate the array.
+	 */
+	struct mdk_thread_s	*thread;
+};
+
+typedef struct raid5_private_data raid5_conf_t;
+
+#define mddev_to_conf(mddev) ((raid5_conf_t *) mddev->private)
+
+/*
+ * Our supported algorithms
+ */
+#define ALGORITHM_LEFT_ASYMMETRIC	0 /* Rotating Parity N with Data Restart */
+#define ALGORITHM_RIGHT_ASYMMETRIC	1 /* Rotating Parity 0 with Data Restart */
+#define ALGORITHM_LEFT_SYMMETRIC	2 /* Rotating Parity N with Data Continuation */
+#define ALGORITHM_RIGHT_SYMMETRIC	3 /* Rotating Parity 0 with Data Continuation */
+
+/* Define non-rotating (raid4) algorithms.  These allow
+ * conversion of raid4 to raid5.
+ */
+#define ALGORITHM_PARITY_0		4 /* P or P,Q are initial devices */
+#define ALGORITHM_PARITY_N		5 /* P or P,Q are final devices. */
+
+/* DDF RAID6 layouts differ from md/raid6 layouts in two ways.
+ * Firstly, the exact positioning of the parity block is slightly
+ * different between the 'LEFT_*' modes of md and the "_N_*" modes
+ * of DDF.
+ * Secondly, or order of datablocks over which the Q syndrome is computed
+ * is different.
+ * Consequently we have different layouts for DDF/raid6 than md/raid6.
+ * These layouts are from the DDFv1.2 spec.
+ * Interestingly DDFv1.2-Errata-A does not specify N_CONTINUE but
+ * leaves RLQ=3 as 'Vendor Specific'
+ */
+
+#define ALGORITHM_ROTATING_ZERO_RESTART	8 /* DDF PRL=6 RLQ=1 */
+#define ALGORITHM_ROTATING_N_RESTART	9 /* DDF PRL=6 RLQ=2 */
+#define ALGORITHM_ROTATING_N_CONTINUE	10 /*DDF PRL=6 RLQ=3 */
+
+
+/* For every RAID5 algorithm we define a RAID6 algorithm
+ * with exactly the same layout for data and parity, and
+ * with the Q block always on the last device (N-1).
+ * This allows trivial conversion from RAID5 to RAID6
+ */
+#define ALGORITHM_LEFT_ASYMMETRIC_6	16
+#define ALGORITHM_RIGHT_ASYMMETRIC_6	17
+#define ALGORITHM_LEFT_SYMMETRIC_6	18
+#define ALGORITHM_RIGHT_SYMMETRIC_6	19
+#define ALGORITHM_PARITY_0_6		20
+#define ALGORITHM_PARITY_N_6		ALGORITHM_PARITY_N
+
+static inline int algorithm_valid_raid5(int layout)
+{
+	return (layout >= 0) &&
+		(layout <= 5);
+}
+static inline int algorithm_valid_raid6(int layout)
+{
+	return (layout >= 0 && layout <= 5)
+		||
+		(layout == 8 || layout == 10)
+		||
+		(layout >= 16 && layout <= 20);
+}
+
+static inline int algorithm_is_DDF(int layout)
+{
+	return layout >= 8 && layout <= 10;
+}
+#endif
diff --git a/drivers/md/raid6.h b/drivers/md/raid6.h
deleted file mode 100644
index 98dcde8..0000000
--- a/drivers/md/raid6.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/* -*- linux-c -*- ------------------------------------------------------- *
- *
- *   Copyright 2003 H. Peter Anvin - 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, Inc., 53 Temple Place Ste 330,
- *   Bostom MA 02111-1307, USA; either version 2 of the License, or
- *   (at your option) any later version; incorporated herein by reference.
- *
- * ----------------------------------------------------------------------- */
-
-#ifndef LINUX_RAID_RAID6_H
-#define LINUX_RAID_RAID6_H
-
-#ifdef __KERNEL__
-
-/* Set to 1 to use kernel-wide empty_zero_page */
-#define RAID6_USE_EMPTY_ZERO_PAGE 0
-
-#include <linux/raid/md.h>
-#include <linux/raid/raid5.h>
-
-typedef raid5_conf_t raid6_conf_t; /* Same configuration */
-
-/* Additional compute_parity mode -- updates the parity w/o LOCKING */
-#define UPDATE_PARITY	4
-
-/* We need a pre-zeroed page... if we don't want to use the kernel-provided
-   one define it here */
-#if RAID6_USE_EMPTY_ZERO_PAGE
-# define raid6_empty_zero_page empty_zero_page
-#else
-extern const char raid6_empty_zero_page[PAGE_SIZE];
-#endif
-
-#else /* ! __KERNEL__ */
-/* Used for testing in user space */
-
-#include <errno.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <stddef.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-
-/* Not standard, but glibc defines it */
-#define BITS_PER_LONG __WORDSIZE
-
-typedef uint8_t  u8;
-typedef uint16_t u16;
-typedef uint32_t u32;
-typedef uint64_t u64;
-
-#ifndef PAGE_SIZE
-# define PAGE_SIZE 4096
-#endif
-extern const char raid6_empty_zero_page[PAGE_SIZE];
-
-#define __init
-#define __exit
-#define __attribute_const__ __attribute__((const))
-#define noinline __attribute__((noinline))
-
-#define preempt_enable()
-#define preempt_disable()
-#define cpu_has_feature(x) 1
-#define enable_kernel_altivec()
-#define disable_kernel_altivec()
-
-#endif /* __KERNEL__ */
-
-/* Routine choices */
-struct raid6_calls {
-	void (*gen_syndrome)(int, size_t, void **);
-	int  (*valid)(void);	/* Returns 1 if this routine set is usable */
-	const char *name;	/* Name of this routine set */
-	int prefer;		/* Has special performance attribute */
-};
-
-/* Selected algorithm */
-extern struct raid6_calls raid6_call;
-
-/* Algorithm list */
-extern const struct raid6_calls * const raid6_algos[];
-int raid6_select_algo(void);
-
-/* Return values from chk_syndrome */
-#define RAID6_OK	0
-#define RAID6_P_BAD	1
-#define RAID6_Q_BAD	2
-#define RAID6_PQ_BAD	3
-
-/* Galois field tables */
-extern const u8 raid6_gfmul[256][256] __attribute__((aligned(256)));
-extern const u8 raid6_gfexp[256]      __attribute__((aligned(256)));
-extern const u8 raid6_gfinv[256]      __attribute__((aligned(256)));
-extern const u8 raid6_gfexi[256]      __attribute__((aligned(256)));
-
-/* Recovery routines */
-void raid6_2data_recov(int disks, size_t bytes, int faila, int failb, void **ptrs);
-void raid6_datap_recov(int disks, size_t bytes, int faila, void **ptrs);
-void raid6_dual_recov(int disks, size_t bytes, int faila, int failb, void **ptrs);
-
-/* Some definitions to allow code to be compiled for testing in userspace */
-#ifndef __KERNEL__
-
-# define jiffies	raid6_jiffies()
-# define printk 	printf
-# define GFP_KERNEL	0
-# define __get_free_pages(x,y)	((unsigned long)mmap(NULL, PAGE_SIZE << (y), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0))
-# define free_pages(x,y)	munmap((void *)(x), (y)*PAGE_SIZE)
-
-static inline void cpu_relax(void)
-{
-	/* Nothing */
-}
-
-#undef  HZ
-#define HZ 1000
-static inline uint32_t raid6_jiffies(void)
-{
-	struct timeval tv;
-	gettimeofday(&tv, NULL);
-	return tv.tv_sec*1000 + tv.tv_usec/1000;
-}
-
-#endif /* ! __KERNEL__ */
-
-#endif /* LINUX_RAID_RAID6_H */
diff --git a/drivers/md/raid6algos.c b/drivers/md/raid6algos.c
index 21987e3..866215a 100644
--- a/drivers/md/raid6algos.c
+++ b/drivers/md/raid6algos.c
@@ -5,7 +5,7 @@
  *   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, Inc., 53 Temple Place Ste 330,
- *   Bostom MA 02111-1307, USA; either version 2 of the License, or
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
  *   (at your option) any later version; incorporated herein by reference.
  *
  * ----------------------------------------------------------------------- */
@@ -16,13 +16,20 @@
  * Algorithm list and algorithm selection for RAID-6
  */
 
-#include "raid6.h"
+#include <linux/raid/pq.h>
 #ifndef __KERNEL__
 #include <sys/mman.h>
 #include <stdio.h>
+#else
+#if !RAID6_USE_EMPTY_ZERO_PAGE
+/* In .bss so it's zeroed */
+const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(256)));
+EXPORT_SYMBOL(raid6_empty_zero_page);
+#endif
 #endif
 
 struct raid6_calls raid6_call;
+EXPORT_SYMBOL_GPL(raid6_call);
 
 /* Various routine sets */
 extern const struct raid6_calls raid6_intx1;
@@ -79,6 +86,7 @@
 #else
 /* Need more time to be stable in userspace */
 #define RAID6_TIME_JIFFIES_LG2	9
+#define time_before(x, y) ((x) < (y))
 #endif
 
 /* Try to pick the best algorithm */
@@ -152,3 +160,12 @@
 
 	return best ? 0 : -EINVAL;
 }
+
+static void raid6_exit(void)
+{
+	do { } while (0);
+}
+
+subsys_initcall(raid6_select_algo);
+module_exit(raid6_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/md/raid6altivec.uc b/drivers/md/raid6altivec.uc
index b9afd35..699dfee 100644
--- a/drivers/md/raid6altivec.uc
+++ b/drivers/md/raid6altivec.uc
@@ -5,7 +5,7 @@
  *   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, Inc., 53 Temple Place Ste 330,
- *   Bostom MA 02111-1307, USA; either version 2 of the License, or
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
  *   (at your option) any later version; incorporated herein by reference.
  *
  * ----------------------------------------------------------------------- */
@@ -22,7 +22,7 @@
  * bracked this with preempt_disable/enable or in a lock)
  */
 
-#include "raid6.h"
+#include <linux/raid/pq.h>
 
 #ifdef CONFIG_ALTIVEC
 
diff --git a/drivers/md/raid6int.uc b/drivers/md/raid6int.uc
index ad004ce..f9bf9cb 100644
--- a/drivers/md/raid6int.uc
+++ b/drivers/md/raid6int.uc
@@ -5,7 +5,7 @@
  *   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, Inc., 53 Temple Place Ste 330,
- *   Bostom MA 02111-1307, USA; either version 2 of the License, or
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
  *   (at your option) any later version; incorporated herein by reference.
  *
  * ----------------------------------------------------------------------- */
@@ -18,7 +18,7 @@
  * This file is postprocessed using unroll.pl
  */
 
-#include "raid6.h"
+#include <linux/raid/pq.h>
 
 /*
  * This is the C data type to use
diff --git a/drivers/md/raid6mmx.c b/drivers/md/raid6mmx.c
index d4e4a1b..e7f6c13 100644
--- a/drivers/md/raid6mmx.c
+++ b/drivers/md/raid6mmx.c
@@ -5,7 +5,7 @@
  *   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, Inc., 53 Temple Place Ste 330,
- *   Bostom MA 02111-1307, USA; either version 2 of the License, or
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
  *   (at your option) any later version; incorporated herein by reference.
  *
  * ----------------------------------------------------------------------- */
@@ -18,7 +18,7 @@
 
 #if defined(__i386__) && !defined(__arch_um__)
 
-#include "raid6.h"
+#include <linux/raid/pq.h>
 #include "raid6x86.h"
 
 /* Shared with raid6sse1.c */
diff --git a/drivers/md/raid6recov.c b/drivers/md/raid6recov.c
index a8c4d94..2609f00 100644
--- a/drivers/md/raid6recov.c
+++ b/drivers/md/raid6recov.c
@@ -5,7 +5,7 @@
  *   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, Inc., 53 Temple Place Ste 330,
- *   Bostom MA 02111-1307, USA; either version 2 of the License, or
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
  *   (at your option) any later version; incorporated herein by reference.
  *
  * ----------------------------------------------------------------------- */
@@ -18,7 +18,7 @@
  * the syndrome.)
  */
 
-#include "raid6.h"
+#include <linux/raid/pq.h>
 
 /* Recover two failed data blocks. */
 void raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
@@ -63,9 +63,7 @@
 		p++; q++;
 	}
 }
-
-
-
+EXPORT_SYMBOL_GPL(raid6_2data_recov);
 
 /* Recover failure of one data block plus the P block */
 void raid6_datap_recov(int disks, size_t bytes, int faila, void **ptrs)
@@ -97,9 +95,10 @@
 		q++; dq++;
 	}
 }
+EXPORT_SYMBOL_GPL(raid6_datap_recov);
 
-
-#ifndef __KERNEL__		/* Testing only */
+#ifndef __KERNEL__
+/* Testing only */
 
 /* Recover two failed blocks. */
 void raid6_dual_recov(int disks, size_t bytes, int faila, int failb, void **ptrs)
diff --git a/drivers/md/raid6sse1.c b/drivers/md/raid6sse1.c
index 0666237..b274dd5 100644
--- a/drivers/md/raid6sse1.c
+++ b/drivers/md/raid6sse1.c
@@ -5,7 +5,7 @@
  *   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, Inc., 53 Temple Place Ste 330,
- *   Bostom MA 02111-1307, USA; either version 2 of the License, or
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
  *   (at your option) any later version; incorporated herein by reference.
  *
  * ----------------------------------------------------------------------- */
@@ -23,7 +23,7 @@
 
 #if defined(__i386__) && !defined(__arch_um__)
 
-#include "raid6.h"
+#include <linux/raid/pq.h>
 #include "raid6x86.h"
 
 /* Defined in raid6mmx.c */
diff --git a/drivers/md/raid6sse2.c b/drivers/md/raid6sse2.c
index b034ad8..6ed6c6c 100644
--- a/drivers/md/raid6sse2.c
+++ b/drivers/md/raid6sse2.c
@@ -5,7 +5,7 @@
  *   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, Inc., 53 Temple Place Ste 330,
- *   Bostom MA 02111-1307, USA; either version 2 of the License, or
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
  *   (at your option) any later version; incorporated herein by reference.
  *
  * ----------------------------------------------------------------------- */
@@ -19,7 +19,7 @@
 
 #if (defined(__i386__) || defined(__x86_64__)) && !defined(__arch_um__)
 
-#include "raid6.h"
+#include <linux/raid/pq.h>
 #include "raid6x86.h"
 
 static const struct raid6_sse_constants {
diff --git a/drivers/md/raid6test/Makefile b/drivers/md/raid6test/Makefile
index 78e0396..58ffdf4 100644
--- a/drivers/md/raid6test/Makefile
+++ b/drivers/md/raid6test/Makefile
@@ -5,7 +5,7 @@
 
 CC	 = gcc
 OPTFLAGS = -O2			# Adjust as desired
-CFLAGS	 = -I.. -g $(OPTFLAGS)
+CFLAGS	 = -I.. -I ../../../include -g $(OPTFLAGS)
 LD	 = ld
 PERL	 = perl
 AR	 = ar
diff --git a/drivers/md/raid6test/test.c b/drivers/md/raid6test/test.c
index 559cc41..7a93031 100644
--- a/drivers/md/raid6test/test.c
+++ b/drivers/md/raid6test/test.c
@@ -17,7 +17,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
-#include "raid6.h"
+#include <linux/raid/pq.h>
 
 #define NDISKS		16	/* Including P and Q */
 
diff --git a/drivers/md/raid6x86.h b/drivers/md/raid6x86.h
index 99fea7a..4c22c15 100644
--- a/drivers/md/raid6x86.h
+++ b/drivers/md/raid6x86.h
@@ -5,7 +5,7 @@
  *   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, Inc., 53 Temple Place Ste 330,
- *   Bostom MA 02111-1307, USA; either version 2 of the License, or
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
  *   (at your option) any later version; incorporated herein by reference.
  *
  * ----------------------------------------------------------------------- */
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig
index 52c3f65..607d319 100644
--- a/drivers/media/common/tuners/Kconfig
+++ b/drivers/media/common/tuners/Kconfig
@@ -148,7 +148,7 @@
 	default m if MEDIA_TUNER_CUSTOMISE
 	help
 	  A driver for the silicon tuner XC5000 from Xceive.
-	  This device is only used inside a SiP called togther with a
+	  This device is only used inside a SiP called together with a
 	  demodulator for now.
 
 config MEDIA_TUNER_MXL5005S
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index a206cee..a486a7f 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -479,7 +479,7 @@
 	default m if DVB_FE_CUSTOMISE
 	help
 	  A driver for the silicon baseband tuner DiB0070 from DiBcom.
-	  This device is only used inside a SiP called togther with a
+	  This device is only used inside a SiP called together with a
 	  demodulator for now.
 
 comment "SEC control devices for DVB-S"
diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c
index 1e81e71..172f1f9 100644
--- a/drivers/media/dvb/frontends/drx397xD.c
+++ b/drivers/media/dvb/frontends/drx397xD.c
@@ -74,7 +74,7 @@
 } fw[] = {
 #define _FW_ENTRY(a, b, c)	{					\
 			.name	= a,					\
-			.file	= 0,					\
+			.file	= NULL,					\
 			.lock	= __RW_LOCK_UNLOCKED(fw[c].lock),	\
 			.refcnt = 0,					\
 			.data	= { }		}
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 06a2b0f..ee3927a 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -52,6 +52,7 @@
 
 config HTC_PASIC3
 	tristate "HTC PASIC3 LED/DS1WM chip support"
+	select MFD_CORE
 	help
 	  This core driver provides register access for the LED/DS1WM
 	  chips labeled "AIC2" and "AIC3", found on HTC Blueangel and
@@ -88,7 +89,7 @@
 	help
 	  If you say yes here you get support for the Texas Instruments
 	  TWL92330/Menelaus Power Management chip. This include voltage
-	  regulators, Dual slot memory card tranceivers, real-time clock
+	  regulators, Dual slot memory card transceivers, real-time clock
 	  and other features that are often used in portable devices like
 	  cell phones and PDAs.
 
diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c
index 99f8dcf..7283d88 100644
--- a/drivers/mfd/da903x.c
+++ b/drivers/mfd/da903x.c
@@ -413,7 +413,7 @@
 	enable_irq(chip->client->irq);
 }
 
-static int da903x_irq_handler(int irq, void *data)
+static irqreturn_t da903x_irq_handler(int irq, void *data)
 {
 	struct da903x_chip *chip = data;
 
diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c
index 91b294d..386da15 100644
--- a/drivers/mfd/htc-pasic3.c
+++ b/drivers/mfd/htc-pasic3.c
@@ -12,18 +12,17 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 
-#include <linux/ds1wm.h>
 #include <linux/gpio.h>
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/ds1wm.h>
 #include <linux/mfd/htc-pasic3.h>
 
 struct pasic3_data {
 	void __iomem *mapping;
 	unsigned int bus_shift;
-	struct platform_device *ds1wm_pdev;
-	struct platform_device *led_pdev;
 };
 
 #define REG_ADDR  5
@@ -65,46 +64,15 @@
  * LEDs
  */
 
-static int led_device_add(struct device *pasic3_dev,
-				const struct pasic3_leds_machinfo *pdata)
-{
-	struct pasic3_data *asic = pasic3_dev->driver_data;
-	struct platform_device *pdev;
-	int ret;
-
-	pdev = platform_device_alloc("pasic3-led", -1);
-	if (!pdev) {
-		dev_dbg(pasic3_dev, "failed to allocate LED platform device\n");
-		return -ENOMEM;
-	}
-
-	ret = platform_device_add_data(pdev, pdata,
-					sizeof(struct pasic3_leds_machinfo));
-	if (ret < 0) {
-		dev_dbg(pasic3_dev, "failed to add LED platform data\n");
-		goto exit_pdev_put;
-	}
-
-	pdev->dev.parent = pasic3_dev;
-	ret = platform_device_add(pdev);
-	if (ret < 0) {
-		dev_dbg(pasic3_dev, "failed to add LED platform device\n");
-		goto exit_pdev_put;
-	}
-
-	asic->led_pdev = pdev;
-	return 0;
-
-exit_pdev_put:
-	platform_device_put(pdev);
-	return ret;
-}
+static struct mfd_cell led_cell __initdata = {
+	.name = "leds-pasic3",
+};
 
 /*
  * DS1WM
  */
 
-static void ds1wm_enable(struct platform_device *pdev)
+static int ds1wm_enable(struct platform_device *pdev)
 {
 	struct device *dev = pdev->dev.parent;
 	int c;
@@ -113,9 +81,10 @@
 	pasic3_write_register(dev, 0x28, c & 0x7f);
 
 	dev_dbg(dev, "DS1WM OWM_EN low (active) %02x\n", c & 0x7f);
+	return 0;
 }
 
-static void ds1wm_disable(struct platform_device *pdev)
+static int ds1wm_disable(struct platform_device *pdev)
 {
 	struct device *dev = pdev->dev.parent;
 	int c;
@@ -124,56 +93,33 @@
 	pasic3_write_register(dev, 0x28, c | 0x80);
 
 	dev_dbg(dev, "DS1WM OWM_EN high (inactive) %02x\n", c | 0x80);
+	return 0;
 }
 
-static struct ds1wm_platform_data ds1wm_pdata = {
-	.bus_shift = 2,
-	.enable    = ds1wm_enable,
-	.disable   = ds1wm_disable,
+static struct ds1wm_driver_data ds1wm_pdata = {
+	.active_high = 0,
 };
 
-static int ds1wm_device_add(struct platform_device *pasic3_pdev, int bus_shift)
-{
-	struct device *pasic3_dev = &pasic3_pdev->dev;
-	struct pasic3_data *asic = pasic3_dev->driver_data;
-	struct platform_device *pdev;
-	int ret;
+static struct resource ds1wm_resources[] __initdata = {
+	[0] = {
+		.start  = 0,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 0,
+		.end    = 0,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
 
-	pdev = platform_device_alloc("ds1wm", -1);
-	if (!pdev) {
-		dev_dbg(pasic3_dev, "failed to allocate DS1WM platform device\n");
-		return -ENOMEM;
-	}
-
-	ret = platform_device_add_resources(pdev, pasic3_pdev->resource,
-						pasic3_pdev->num_resources);
-	if (ret < 0) {
-		dev_dbg(pasic3_dev, "failed to add DS1WM resources\n");
-		goto exit_pdev_put;
-	}
-
-	ds1wm_pdata.bus_shift = asic->bus_shift;
-	ret = platform_device_add_data(pdev, &ds1wm_pdata,
-					sizeof(struct ds1wm_platform_data));
-	if (ret < 0) {
-		dev_dbg(pasic3_dev, "failed to add DS1WM platform data\n");
-		goto exit_pdev_put;
-	}
-
-	pdev->dev.parent = pasic3_dev;
-	ret = platform_device_add(pdev);
-	if (ret < 0) {
-		dev_dbg(pasic3_dev, "failed to add DS1WM platform device\n");
-		goto exit_pdev_put;
-	}
-
-	asic->ds1wm_pdev = pdev;
-	return 0;
-
-exit_pdev_put:
-	platform_device_put(pdev);
-	return ret;
-}
+static struct mfd_cell ds1wm_cell __initdata = {
+	.name          = "ds1wm",
+	.enable        = ds1wm_enable,
+	.disable       = ds1wm_disable,
+	.driver_data   = &ds1wm_pdata,
+	.num_resources = 2,
+	.resources     = ds1wm_resources,
+};
 
 static int __init pasic3_probe(struct platform_device *pdev)
 {
@@ -182,12 +128,27 @@
 	struct pasic3_data *asic;
 	struct resource *r;
 	int ret;
+	int irq = 0;
+
+	r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (r) {
+		ds1wm_resources[1].flags = IORESOURCE_IRQ | (r->flags &
+			(IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE));
+		irq = r->start;
+	}
+
+	r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (r) {
+		ds1wm_resources[1].flags = IORESOURCE_IRQ | (r->flags &
+			(IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE));
+		irq = r->start;
+	}
 
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!r)
 		return -ENXIO;
 
-	if (!request_mem_region(r->start, r->end - r->start + 1, "pasic3"))
+	if (!request_mem_region(r->start, resource_size(r), "pasic3"))
 		return -EBUSY;
 
 	asic = kzalloc(sizeof(struct pasic3_data), GFP_KERNEL);
@@ -196,24 +157,33 @@
 
 	platform_set_drvdata(pdev, asic);
 
-	if (pdata && pdata->bus_shift)
-		asic->bus_shift = pdata->bus_shift;
-	else
-		asic->bus_shift = 2;
-
-	asic->mapping = ioremap(r->start, r->end - r->start + 1);
+	asic->mapping = ioremap(r->start, resource_size(r));
 	if (!asic->mapping) {
 		dev_err(dev, "couldn't ioremap PASIC3\n");
 		kfree(asic);
 		return -ENOMEM;
 	}
 
-	ret = ds1wm_device_add(pdev, asic->bus_shift);
-	if (ret < 0)
-		dev_warn(dev, "failed to register DS1WM\n");
+	/* calculate bus shift from mem resource */
+	asic->bus_shift = (resource_size(r) - 5) >> 3;
 
-	if (pdata->led_pdata) {
-		ret = led_device_add(dev, pdata->led_pdata);
+	if (pdata && pdata->clock_rate) {
+		ds1wm_pdata.clock_rate = pdata->clock_rate;
+		/* the first 5 PASIC3 registers control the DS1WM */
+		ds1wm_resources[0].end = (5 << asic->bus_shift) - 1;
+		ds1wm_cell.platform_data = &ds1wm_cell;
+		ds1wm_cell.data_size = sizeof(ds1wm_cell);
+		ret = mfd_add_devices(&pdev->dev, pdev->id,
+				&ds1wm_cell, 1, r, irq);
+		if (ret < 0)
+			dev_warn(dev, "failed to register DS1WM\n");
+	}
+
+	if (pdata && pdata->led_pdata) {
+		led_cell.driver_data = pdata->led_pdata;
+		led_cell.platform_data = &led_cell;
+		led_cell.data_size = sizeof(ds1wm_cell);
+		ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r, 0);
 		if (ret < 0)
 			dev_warn(dev, "failed to register LED device\n");
 	}
@@ -226,14 +196,11 @@
 	struct pasic3_data *asic = platform_get_drvdata(pdev);
 	struct resource *r;
 
-	if (asic->led_pdev)
-		platform_device_unregister(asic->led_pdev);
-	if (asic->ds1wm_pdev)
-		platform_device_unregister(asic->ds1wm_pdev);
+	mfd_remove_devices(&pdev->dev);
 
 	iounmap(asic->mapping);
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	release_mem_region(r->start, r->end - r->start + 1);
+	release_mem_region(r->start, resource_size(r));
 	kfree(asic);
 	return 0;
 }
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
index 2e3605765..7793932 100644
--- a/drivers/mfd/pcf50633-core.c
+++ b/drivers/mfd/pcf50633-core.c
@@ -15,7 +15,6 @@
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <linux/sysfs.h>
-#include <linux/device.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c
index 9f7024c0..e9f4323 100644
--- a/drivers/mfd/t7l66xb.c
+++ b/drivers/mfd/t7l66xb.c
@@ -108,7 +108,7 @@
 
 /*--------------------------------------------------------------------------*/
 
-const static struct resource t7l66xb_mmc_resources[] = {
+static const struct resource t7l66xb_mmc_resources[] = {
 	{
 		.start = 0x800,
 		.end	= 0x9ff,
@@ -126,7 +126,7 @@
 	},
 };
 
-const static struct resource t7l66xb_nand_resources[] = {
+static const struct resource t7l66xb_nand_resources[] = {
 	{
 		.start	= 0xc00,
 		.end	= 0xc07,
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
index f856e94..77a12fc 100644
--- a/drivers/mfd/tc6393xb.c
+++ b/drivers/mfd/tc6393xb.c
@@ -172,7 +172,7 @@
 	},
 };
 
-const static struct resource tc6393xb_ohci_resources[] = {
+static const struct resource tc6393xb_ohci_resources[] = {
 	{
 		.start	= 0x3000,
 		.end	= 0x31ff,
diff --git a/drivers/mfd/twl4030-core.c b/drivers/mfd/twl4030-core.c
index 68826f1..ec90e95 100644
--- a/drivers/mfd/twl4030-core.c
+++ b/drivers/mfd/twl4030-core.c
@@ -592,11 +592,9 @@
 
 	/* maybe add LDOs that are omitted on cost-reduced parts */
 	if (twl_has_regulator() && !(features & TPS_SUBSET)) {
-		/*
 		child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
-		*/
 
 		child = add_regulator(TWL4030_REG_VMMC2, pdata->vmmc2);
 		if (IS_ERR(child))
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
index b108760..aca2670 100644
--- a/drivers/mfd/twl4030-irq.c
+++ b/drivers/mfd/twl4030-irq.c
@@ -182,7 +182,7 @@
 	long irq = (long)data;
 	struct irq_desc *desc = irq_to_desc(irq);
 	static unsigned i2c_errors;
-	const static unsigned max_i2c_errors = 100;
+	static const unsigned max_i2c_errors = 100;
 
 	if (!desc) {
 		pr_err("twl4030: Invalid IRQ: %ld\n", irq);
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c
index b457a05..c2be308 100644
--- a/drivers/mfd/wm8350-core.c
+++ b/drivers/mfd/wm8350-core.c
@@ -1111,7 +1111,7 @@
 	do {
 		schedule_timeout_interruptible(1);
 		reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1);
-	} while (--tries && (reg & WM8350_AUXADC_POLL));
+	} while ((reg & WM8350_AUXADC_POLL) && --tries);
 
 	if (!tries)
 		dev_err(wm8350->dev, "adc chn %d read timeout\n", channel);
@@ -1238,7 +1238,7 @@
 	}
 
 	wm8350->reg_cache =
-	    kzalloc(sizeof(u16) * (WM8350_MAX_REGISTER + 1), GFP_KERNEL);
+		kmalloc(sizeof(u16) * (WM8350_MAX_REGISTER + 1), GFP_KERNEL);
 	if (wm8350->reg_cache == NULL)
 		return -ENOMEM;
 
@@ -1246,17 +1246,20 @@
 	 * a PMIC so the device many not be in a virgin state and we
 	 * can't rely on the silicon values.
 	 */
+	ret = wm8350->read_dev(wm8350, 0,
+			       sizeof(u16) * (WM8350_MAX_REGISTER + 1),
+			       wm8350->reg_cache);
+	if (ret < 0) {
+		dev_err(wm8350->dev,
+			"failed to read initial cache values\n");
+		goto out;
+	}
+
+	/* Mask out uncacheable/unreadable bits and the audio. */
 	for (i = 0; i < WM8350_MAX_REGISTER; i++) {
-		/* audio register range */
 		if (wm8350_reg_io_map[i].readable &&
 		    (i < WM8350_CLOCK_CONTROL_1 || i > WM8350_AIF_TEST)) {
-			ret = wm8350->read_dev(wm8350, i, 2, (char *)&value);
-			if (ret < 0) {
-				dev_err(wm8350->dev,
-				       "failed to read initial cache value\n");
-				goto out;
-			}
-			value = be16_to_cpu(value);
+			value = be16_to_cpu(wm8350->reg_cache[i]);
 			value &= wm8350_reg_io_map[i].readable;
 			value &= ~wm8350_reg_io_map[i].vol;
 			wm8350->reg_cache[i] = value;
@@ -1435,7 +1438,21 @@
 	mutex_init(&wm8350->irq_mutex);
 	INIT_WORK(&wm8350->irq_work, wm8350_irq_worker);
 	if (irq) {
-		ret = request_irq(irq, wm8350_irq, 0,
+		int flags = 0;
+
+		if (pdata && pdata->irq_high) {
+			flags |= IRQF_TRIGGER_HIGH;
+
+			wm8350_set_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
+					WM8350_IRQ_POL);
+		} else {
+			flags |= IRQF_TRIGGER_LOW;
+
+			wm8350_clear_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
+					  WM8350_IRQ_POL);
+		}
+
+		ret = request_irq(irq, wm8350_irq, flags,
 				  "wm8350", wm8350);
 		if (ret != 0) {
 			dev_err(wm8350->dev, "Failed to request IRQ: %d\n",
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 0b92b2f..6d1ac18 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -18,8 +18,8 @@
 	depends on AVR32 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9
 	help
 	  This option enables device driver support for the PWM channels
-	  on certain Atmel prcoessors.  Pulse Width Modulation is used for
-	  purposes including software controlled power-efficent backlights
+	  on certain Atmel processors.  Pulse Width Modulation is used for
+	  purposes including software controlled power-efficient backlights
 	  on LCD displays, motor control, and waveform generation.
 
 config ATMEL_TCLIB
@@ -142,7 +142,7 @@
 	tristate "Device driver for Atmel SSC peripheral"
 	depends on AVR32 || ARCH_AT91
 	---help---
-	  This option enables device driver support for Atmel Syncronized
+	  This option enables device driver support for Atmel Synchronized
 	  Serial Communication peripheral (SSC).
 
 	  The SSC peripheral supports a wide variety of serial frame based
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 513eb09..fe8041e 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -41,6 +41,8 @@
 
 #include "queue.h"
 
+MODULE_ALIAS("mmc:block");
+
 /*
  * max 8 partitions per card
  */
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index f210a8e..bdb165f 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -84,6 +84,14 @@
 	}
 
 	retval = add_uevent_var(env, "MMC_NAME=%s", mmc_card_name(card));
+	if (retval)
+		return retval;
+
+	/*
+	 * Request the mmc_block device.  Note: that this is a direct request
+	 * for the module it carries no information as to what is inserted.
+	 */
+	retval = add_uevent_var(env, "MODALIAS=mmc:block");
 
 	return retval;
 }
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index df6ce4a..fa073ab 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -21,6 +21,7 @@
 #include <linux/leds.h>
 #include <linux/scatterlist.h>
 #include <linux/log2.h>
+#include <linux/regulator/consumer.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
@@ -297,6 +298,21 @@
 			data->timeout_clks = 0;
 		}
 	}
+	/*
+	 * Some cards need very high timeouts if driven in SPI mode.
+	 * The worst observed timeout was 900ms after writing a
+	 * continuous stream of data until the internal logic
+	 * overflowed.
+	 */
+	if (mmc_host_is_spi(card->host)) {
+		if (data->flags & MMC_DATA_WRITE) {
+			if (data->timeout_ns < 1000000000)
+				data->timeout_ns = 1000000000;	/* 1s */
+		} else {
+			if (data->timeout_ns < 100000000)
+				data->timeout_ns =  100000000;	/* 100ms */
+		}
+	}
 }
 EXPORT_SYMBOL(mmc_set_data_timeout);
 
@@ -523,6 +539,105 @@
 }
 EXPORT_SYMBOL(mmc_vddrange_to_ocrmask);
 
+#ifdef CONFIG_REGULATOR
+
+/**
+ * mmc_regulator_get_ocrmask - return mask of supported voltages
+ * @supply: regulator to use
+ *
+ * This returns either a negative errno, or a mask of voltages that
+ * can be provided to MMC/SD/SDIO devices using the specified voltage
+ * regulator.  This would normally be called before registering the
+ * MMC host adapter.
+ */
+int mmc_regulator_get_ocrmask(struct regulator *supply)
+{
+	int			result = 0;
+	int			count;
+	int			i;
+
+	count = regulator_count_voltages(supply);
+	if (count < 0)
+		return count;
+
+	for (i = 0; i < count; i++) {
+		int		vdd_uV;
+		int		vdd_mV;
+
+		vdd_uV = regulator_list_voltage(supply, i);
+		if (vdd_uV <= 0)
+			continue;
+
+		vdd_mV = vdd_uV / 1000;
+		result |= mmc_vddrange_to_ocrmask(vdd_mV, vdd_mV);
+	}
+
+	return result;
+}
+EXPORT_SYMBOL(mmc_regulator_get_ocrmask);
+
+/**
+ * mmc_regulator_set_ocr - set regulator to match host->ios voltage
+ * @vdd_bit: zero for power off, else a bit number (host->ios.vdd)
+ * @supply: regulator to use
+ *
+ * Returns zero on success, else negative errno.
+ *
+ * MMC host drivers may use this to enable or disable a regulator using
+ * a particular supply voltage.  This would normally be called from the
+ * set_ios() method.
+ */
+int mmc_regulator_set_ocr(struct regulator *supply, unsigned short vdd_bit)
+{
+	int			result = 0;
+	int			min_uV, max_uV;
+	int			enabled;
+
+	enabled = regulator_is_enabled(supply);
+	if (enabled < 0)
+		return enabled;
+
+	if (vdd_bit) {
+		int		tmp;
+		int		voltage;
+
+		/* REVISIT mmc_vddrange_to_ocrmask() may have set some
+		 * bits this regulator doesn't quite support ... don't
+		 * be too picky, most cards and regulators are OK with
+		 * a 0.1V range goof (it's a small error percentage).
+		 */
+		tmp = vdd_bit - ilog2(MMC_VDD_165_195);
+		if (tmp == 0) {
+			min_uV = 1650 * 1000;
+			max_uV = 1950 * 1000;
+		} else {
+			min_uV = 1900 * 1000 + tmp * 100 * 1000;
+			max_uV = min_uV + 100 * 1000;
+		}
+
+		/* avoid needless changes to this voltage; the regulator
+		 * might not allow this operation
+		 */
+		voltage = regulator_get_voltage(supply);
+		if (voltage < 0)
+			result = voltage;
+		else if (voltage < min_uV || voltage > max_uV)
+			result = regulator_set_voltage(supply, min_uV, max_uV);
+		else
+			result = 0;
+
+		if (result == 0 && !enabled)
+			result = regulator_enable(supply);
+	} else if (enabled) {
+		result = regulator_disable(supply);
+	}
+
+	return result;
+}
+EXPORT_SYMBOL(mmc_regulator_set_ocr);
+
+#endif
+
 /*
  * Mask off any voltages we don't support and select
  * the lowest voltage
@@ -815,6 +930,7 @@
 	spin_unlock_irqrestore(&host->lock, flags);
 #endif
 
+	cancel_delayed_work(&host->detect);
 	mmc_flush_scheduled_work();
 
 	mmc_bus_get(host);
@@ -842,6 +958,7 @@
  */
 int mmc_suspend_host(struct mmc_host *host, pm_message_t state)
 {
+	cancel_delayed_work(&host->detect);
 	mmc_flush_scheduled_work();
 
 	mmc_bus_get(host);
@@ -875,6 +992,7 @@
 	mmc_bus_get(host);
 	if (host->bus_ops && !host->bus_dead) {
 		mmc_power_up(host);
+		mmc_select_voltage(host, host->ocr);
 		BUG_ON(!host->bus_ops->resume);
 		host->bus_ops->resume(host);
 	}
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
index 1237bb4..610dbd1 100644
--- a/drivers/mmc/core/debugfs.c
+++ b/drivers/mmc/core/debugfs.c
@@ -184,6 +184,68 @@
 DEFINE_SIMPLE_ATTRIBUTE(mmc_dbg_card_status_fops, mmc_dbg_card_status_get,
 		NULL, "%08llx\n");
 
+#define EXT_CSD_STR_LEN 1025
+
+static int mmc_ext_csd_open(struct inode *inode, struct file *filp)
+{
+	struct mmc_card *card = inode->i_private;
+	char *buf;
+	ssize_t n = 0;
+	u8 *ext_csd;
+	int err, i;
+
+	buf = kmalloc(EXT_CSD_STR_LEN + 1, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	ext_csd = kmalloc(512, GFP_KERNEL);
+	if (!ext_csd) {
+		err = -ENOMEM;
+		goto out_free;
+	}
+
+	mmc_claim_host(card->host);
+	err = mmc_send_ext_csd(card, ext_csd);
+	mmc_release_host(card->host);
+	if (err)
+		goto out_free;
+
+	for (i = 511; i >= 0; i--)
+		n += sprintf(buf + n, "%02x", ext_csd[i]);
+	n += sprintf(buf + n, "\n");
+	BUG_ON(n != EXT_CSD_STR_LEN);
+
+	filp->private_data = buf;
+	kfree(ext_csd);
+	return 0;
+
+out_free:
+	kfree(buf);
+	kfree(ext_csd);
+	return err;
+}
+
+static ssize_t mmc_ext_csd_read(struct file *filp, char __user *ubuf,
+				size_t cnt, loff_t *ppos)
+{
+	char *buf = filp->private_data;
+
+	return simple_read_from_buffer(ubuf, cnt, ppos,
+				       buf, EXT_CSD_STR_LEN);
+}
+
+static int mmc_ext_csd_release(struct inode *inode, struct file *file)
+{
+	kfree(file->private_data);
+	return 0;
+}
+
+static struct file_operations mmc_dbg_ext_csd_fops = {
+	.open		= mmc_ext_csd_open,
+	.read		= mmc_ext_csd_read,
+	.release	= mmc_ext_csd_release,
+};
+
 void mmc_add_card_debugfs(struct mmc_card *card)
 {
 	struct mmc_host	*host = card->host;
@@ -211,6 +273,11 @@
 					&mmc_dbg_card_status_fops))
 			goto err;
 
+	if (mmc_card_mmc(card))
+		if (!debugfs_create_file("ext_csd", S_IRUSR, root, card,
+					&mmc_dbg_ext_csd_fops))
+			goto err;
+
 	return;
 
 err:
diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c
index 956bd76..963f293 100644
--- a/drivers/mmc/core/sdio_cis.c
+++ b/drivers/mmc/core/sdio_cis.c
@@ -223,10 +223,18 @@
 		if (tpl_code == 0xff)
 			break;
 
+		/* null entries have no link field or data */
+		if (tpl_code == 0x00)
+			continue;
+
 		ret = mmc_io_rw_direct(card, 0, 0, ptr++, 0, &tpl_link);
 		if (ret)
 			break;
 
+		/* a size of 0xff also means we're done */
+		if (tpl_link == 0xff)
+			break;
+
 		this = kmalloc(sizeof(*this) + tpl_link, GFP_KERNEL);
 		if (!this)
 			return -ENOMEM;
diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c
index c8fa095..4eb7825f 100644
--- a/drivers/mmc/core/sdio_ops.c
+++ b/drivers/mmc/core/sdio_ops.c
@@ -76,6 +76,10 @@
 	BUG_ON(!card);
 	BUG_ON(fn > 7);
 
+	/* sanity check */
+	if (addr & ~0x1FFFF)
+		return -EINVAL;
+
 	memset(&cmd, 0, sizeof(struct mmc_command));
 
 	cmd.opcode = SD_IO_RW_DIRECT;
@@ -125,6 +129,10 @@
 	WARN_ON(blocks == 0);
 	WARN_ON(blksz == 0);
 
+	/* sanity check */
+	if (addr & ~0x1FFFF)
+		return -EINVAL;
+
 	memset(&mrq, 0, sizeof(struct mmc_request));
 	memset(&cmd, 0, sizeof(struct mmc_command));
 	memset(&data, 0, sizeof(struct mmc_data));
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 99d4b28..b4cf691 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -37,6 +37,13 @@
 
 	  If unsure, say N.
 
+config MMC_SDHCI_IO_ACCESSORS
+	bool
+	depends on MMC_SDHCI
+	help
+	  This is silent Kconfig symbol that is selected by the drivers that
+	  need to overwrite SDHCI IO memory accessors.
+
 config MMC_SDHCI_PCI
 	tristate "SDHCI support on PCI bus"
 	depends on MMC_SDHCI && PCI
@@ -65,6 +72,17 @@
 
 	  If unsure, say Y.
 
+config MMC_SDHCI_OF
+	tristate "SDHCI support on OpenFirmware platforms"
+	depends on MMC_SDHCI && PPC_OF
+	select MMC_SDHCI_IO_ACCESSORS
+	help
+	  This selects the OF support for Secure Digital Host Controller
+	  Interfaces. So far, only the Freescale eSDHC controller is known
+	  to exist on OF platforms.
+
+	  If unsure, say N.
+
 config MMC_OMAP
 	tristate "TI OMAP Multimedia Card Interface support"
 	depends on ARCH_OMAP
@@ -171,13 +189,24 @@
           To compile this driver as a module, choose M here: the
 	  module will be called tifm_sd.
 
+config MMC_MVSDIO
+	tristate "Marvell MMC/SD/SDIO host driver"
+	depends on PLAT_ORION
+	---help---
+	  This selects the Marvell SDIO host driver.
+	  SDIO may currently be found on the Kirkwood 88F6281 and 88F6192
+	  SoC controllers.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called mvsdio.
+
 config MMC_SPI
 	tristate "MMC/SD/SDIO over SPI"
 	depends on SPI_MASTER && !HIGHMEM && HAS_DMA
 	select CRC7
 	select CRC_ITU_T
 	help
-	  Some systems accss MMC/SD/SDIO cards using a SPI controller
+	  Some systems access MMC/SD/SDIO cards using a SPI controller
 	  instead of using a "native" MMC/SD/SDIO controller.  This has a
 	  disadvantage of being relatively high overhead, but a compensating
 	  advantage of working on many systems without dedicated MMC/SD/SDIO
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index dedec55..970a997 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -13,6 +13,7 @@
 obj-$(CONFIG_MMC_SDHCI)		+= sdhci.o
 obj-$(CONFIG_MMC_SDHCI_PCI)	+= sdhci-pci.o
 obj-$(CONFIG_MMC_RICOH_MMC)	+= ricoh_mmc.o
+obj-$(CONFIG_MMC_SDHCI_OF)	+= sdhci-of.o
 obj-$(CONFIG_MMC_WBSD)		+= wbsd.o
 obj-$(CONFIG_MMC_AU1X)		+= au1xmmc.o
 obj-$(CONFIG_MMC_OMAP)		+= omap.o
@@ -20,6 +21,7 @@
 obj-$(CONFIG_MMC_AT91)		+= at91_mci.o
 obj-$(CONFIG_MMC_ATMELMCI)	+= atmel-mci.o
 obj-$(CONFIG_MMC_TIFM_SD)	+= tifm_sd.o
+obj-$(CONFIG_MMC_MVSDIO)	+= mvsdio.o
 obj-$(CONFIG_MMC_SPI)		+= mmc_spi.o
 ifeq ($(CONFIG_OF),y)
 obj-$(CONFIG_MMC_SPI)		+= of_mmc_spi.o
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index e94e920..cf6a100 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -812,7 +812,7 @@
 		slot->sdc_reg |= MCI_SDCBUS_1BIT;
 		break;
 	case MMC_BUS_WIDTH_4:
-		slot->sdc_reg = MCI_SDCBUS_4BIT;
+		slot->sdc_reg |= MCI_SDCBUS_4BIT;
 		break;
 	}
 
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 87e211d..72f8bde 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -279,8 +279,11 @@
 		 * so it can always DMA directly into the target buffer.
 		 * It'd probably be better to memcpy() the first chunk and
 		 * avoid extra i/o calls...
+		 *
+		 * Note we check for more than 8 bytes, because in practice,
+		 * some SD cards are slow...
 		 */
-		for (i = 2; i < 9; i++) {
+		for (i = 2; i < 16; i++) {
 			value = mmc_spi_readbytes(host, 1);
 			if (value < 0)
 				goto done;
@@ -609,6 +612,7 @@
 	struct spi_device	*spi = host->spi;
 	int			status, i;
 	struct scratch		*scratch = host->data;
+	u32			pattern;
 
 	if (host->mmc->use_spi_crc)
 		scratch->crc_val = cpu_to_be16(
@@ -636,8 +640,27 @@
 	 * doesn't necessarily tell whether the write operation succeeded;
 	 * it just says if the transmission was ok and whether *earlier*
 	 * writes succeeded; see the standard.
+	 *
+	 * In practice, there are (even modern SDHC-)cards which are late
+	 * in sending the response, and miss the time frame by a few bits,
+	 * so we have to cope with this situation and check the response
+	 * bit-by-bit. Arggh!!!
 	 */
-	switch (SPI_MMC_RESPONSE_CODE(scratch->status[0])) {
+	pattern  = scratch->status[0] << 24;
+	pattern |= scratch->status[1] << 16;
+	pattern |= scratch->status[2] << 8;
+	pattern |= scratch->status[3];
+
+	/* First 3 bit of pattern are undefined */
+	pattern |= 0xE0000000;
+
+	/* left-adjust to leading 0 bit */
+	while (pattern & 0x80000000)
+		pattern <<= 1;
+	/* right-adjust for pattern matching. Code is in bit 4..0 now. */
+	pattern >>= 27;
+
+	switch (pattern) {
 	case SPI_RESPONSE_ACCEPTED:
 		status = 0;
 		break;
@@ -668,8 +691,9 @@
 	/* Return when not busy.  If we didn't collect that status yet,
 	 * we'll need some more I/O.
 	 */
-	for (i = 1; i < sizeof(scratch->status); i++) {
-		if (scratch->status[i] != 0)
+	for (i = 4; i < sizeof(scratch->status); i++) {
+		/* card is non-busy if the most recent bit is 1 */
+		if (scratch->status[i] & 0x01)
 			return 0;
 	}
 	return mmc_spi_wait_unbusy(host, timeout);
@@ -1204,10 +1228,12 @@
 
 	/* MMC and SD specs only seem to care that sampling is on the
 	 * rising edge ... meaning SPI modes 0 or 3.  So either SPI mode
-	 * should be legit.  We'll use mode 0 since it seems to be a
-	 * bit less troublesome on some hardware ... unclear why.
+	 * should be legit.  We'll use mode 0 since the steady state is 0,
+	 * which is appropriate for hotplugging, unless the platform data
+	 * specify mode 3 (if hardware is not compatible to mode 0).
 	 */
-	spi->mode = SPI_MODE_0;
+	if (spi->mode != SPI_MODE_3)
+		spi->mode = SPI_MODE_0;
 	spi->bits_per_word = 8;
 
 	status = spi_setup(spi);
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c
new file mode 100644
index 0000000..b5c375d
--- /dev/null
+++ b/drivers/mmc/host/mvsdio.c
@@ -0,0 +1,885 @@
+/*
+ * Marvell MMC/SD/SDIO driver
+ *
+ * Authors: Maen Suleiman, Nicolas Pitre
+ * Copyright (C) 2008-2009 Marvell Ltd.
+ *
+ * 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/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/mbus.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/scatterlist.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/mmc/host.h>
+
+#include <asm/sizes.h>
+#include <asm/unaligned.h>
+#include <plat/mvsdio.h>
+
+#include "mvsdio.h"
+
+#define DRIVER_NAME	"mvsdio"
+
+static int maxfreq = MVSD_CLOCKRATE_MAX;
+static int nodma;
+
+struct mvsd_host {
+	void __iomem *base;
+	struct mmc_request *mrq;
+	spinlock_t lock;
+	unsigned int xfer_mode;
+	unsigned int intr_en;
+	unsigned int ctrl;
+	unsigned int pio_size;
+	void *pio_ptr;
+	unsigned int sg_frags;
+	unsigned int ns_per_clk;
+	unsigned int clock;
+	unsigned int base_clock;
+	struct timer_list timer;
+	struct mmc_host *mmc;
+	struct device *dev;
+	struct resource *res;
+	int irq;
+	int gpio_card_detect;
+	int gpio_write_protect;
+};
+
+#define mvsd_write(offs, val)	writel(val, iobase + (offs))
+#define mvsd_read(offs)		readl(iobase + (offs))
+
+static int mvsd_setup_data(struct mvsd_host *host, struct mmc_data *data)
+{
+	void __iomem *iobase = host->base;
+	unsigned int tmout;
+	int tmout_index;
+
+	/* If timeout=0 then maximum timeout index is used. */
+	tmout = DIV_ROUND_UP(data->timeout_ns, host->ns_per_clk);
+	tmout += data->timeout_clks;
+	tmout_index = fls(tmout - 1) - 12;
+	if (tmout_index < 0)
+		tmout_index = 0;
+	if (tmout_index > MVSD_HOST_CTRL_TMOUT_MAX)
+		tmout_index = MVSD_HOST_CTRL_TMOUT_MAX;
+
+	dev_dbg(host->dev, "data %s at 0x%08x: blocks=%d blksz=%d tmout=%u (%d)\n",
+		(data->flags & MMC_DATA_READ) ? "read" : "write",
+		(u32)sg_virt(data->sg), data->blocks, data->blksz,
+		tmout, tmout_index);
+
+	host->ctrl &= ~MVSD_HOST_CTRL_TMOUT_MASK;
+	host->ctrl |= MVSD_HOST_CTRL_TMOUT(tmout_index);
+	mvsd_write(MVSD_HOST_CTRL, host->ctrl);
+	mvsd_write(MVSD_BLK_COUNT, data->blocks);
+	mvsd_write(MVSD_BLK_SIZE, data->blksz);
+
+	if (nodma || (data->blksz | data->sg->offset) & 3) {
+		/*
+		 * We cannot do DMA on a buffer which offset or size
+		 * is not aligned on a 4-byte boundary.
+		 */
+		host->pio_size = data->blocks * data->blksz;
+		host->pio_ptr = sg_virt(data->sg);
+		if (!nodma)
+			printk(KERN_DEBUG "%s: fallback to PIO for data "
+					  "at 0x%p size %d\n",
+					  mmc_hostname(host->mmc),
+					  host->pio_ptr, host->pio_size);
+		return 1;
+	} else {
+		dma_addr_t phys_addr;
+		int dma_dir = (data->flags & MMC_DATA_READ) ?
+			DMA_FROM_DEVICE : DMA_TO_DEVICE;
+		host->sg_frags = dma_map_sg(mmc_dev(host->mmc), data->sg,
+					    data->sg_len, dma_dir);
+		phys_addr = sg_dma_address(data->sg);
+		mvsd_write(MVSD_SYS_ADDR_LOW, (u32)phys_addr & 0xffff);
+		mvsd_write(MVSD_SYS_ADDR_HI,  (u32)phys_addr >> 16);
+		return 0;
+	}
+}
+
+static void mvsd_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+	struct mvsd_host *host = mmc_priv(mmc);
+	void __iomem *iobase = host->base;
+	struct mmc_command *cmd = mrq->cmd;
+	u32 cmdreg = 0, xfer = 0, intr = 0;
+	unsigned long flags;
+
+	BUG_ON(host->mrq != NULL);
+	host->mrq = mrq;
+
+	dev_dbg(host->dev, "cmd %d (hw state 0x%04x)\n",
+		cmd->opcode, mvsd_read(MVSD_HW_STATE));
+
+	cmdreg = MVSD_CMD_INDEX(cmd->opcode);
+
+	if (cmd->flags & MMC_RSP_BUSY)
+		cmdreg |= MVSD_CMD_RSP_48BUSY;
+	else if (cmd->flags & MMC_RSP_136)
+		cmdreg |= MVSD_CMD_RSP_136;
+	else if (cmd->flags & MMC_RSP_PRESENT)
+		cmdreg |= MVSD_CMD_RSP_48;
+	else
+		cmdreg |= MVSD_CMD_RSP_NONE;
+
+	if (cmd->flags & MMC_RSP_CRC)
+		cmdreg |= MVSD_CMD_CHECK_CMDCRC;
+
+	if (cmd->flags & MMC_RSP_OPCODE)
+		cmdreg |= MVSD_CMD_INDX_CHECK;
+
+	if (cmd->flags & MMC_RSP_PRESENT) {
+		cmdreg |= MVSD_UNEXPECTED_RESP;
+		intr |= MVSD_NOR_UNEXP_RSP;
+	}
+
+	if (mrq->data) {
+		struct mmc_data *data = mrq->data;
+		int pio;
+
+		cmdreg |= MVSD_CMD_DATA_PRESENT | MVSD_CMD_CHECK_DATACRC16;
+		xfer |= MVSD_XFER_MODE_HW_WR_DATA_EN;
+		if (data->flags & MMC_DATA_READ)
+			xfer |= MVSD_XFER_MODE_TO_HOST;
+
+		pio = mvsd_setup_data(host, data);
+		if (pio) {
+			xfer |= MVSD_XFER_MODE_PIO;
+			/* PIO section of mvsd_irq has comments on those bits */
+			if (data->flags & MMC_DATA_WRITE)
+				intr |= MVSD_NOR_TX_AVAIL;
+			else if (host->pio_size > 32)
+				intr |= MVSD_NOR_RX_FIFO_8W;
+			else
+				intr |= MVSD_NOR_RX_READY;
+		}
+
+		if (data->stop) {
+			struct mmc_command *stop = data->stop;
+			u32 cmd12reg = 0;
+
+			mvsd_write(MVSD_AUTOCMD12_ARG_LOW, stop->arg & 0xffff);
+			mvsd_write(MVSD_AUTOCMD12_ARG_HI,  stop->arg >> 16);
+
+			if (stop->flags & MMC_RSP_BUSY)
+				cmd12reg |= MVSD_AUTOCMD12_BUSY;
+			if (stop->flags & MMC_RSP_OPCODE)
+				cmd12reg |= MVSD_AUTOCMD12_INDX_CHECK;
+			cmd12reg |= MVSD_AUTOCMD12_INDEX(stop->opcode);
+			mvsd_write(MVSD_AUTOCMD12_CMD, cmd12reg);
+
+			xfer |= MVSD_XFER_MODE_AUTO_CMD12;
+			intr |= MVSD_NOR_AUTOCMD12_DONE;
+		} else {
+			intr |= MVSD_NOR_XFER_DONE;
+		}
+	} else {
+		intr |= MVSD_NOR_CMD_DONE;
+	}
+
+	mvsd_write(MVSD_ARG_LOW, cmd->arg & 0xffff);
+	mvsd_write(MVSD_ARG_HI,  cmd->arg >> 16);
+
+	spin_lock_irqsave(&host->lock, flags);
+
+	host->xfer_mode &= MVSD_XFER_MODE_INT_CHK_EN;
+	host->xfer_mode |= xfer;
+	mvsd_write(MVSD_XFER_MODE, host->xfer_mode);
+
+	mvsd_write(MVSD_NOR_INTR_STATUS, ~MVSD_NOR_CARD_INT);
+	mvsd_write(MVSD_ERR_INTR_STATUS, 0xffff);
+	mvsd_write(MVSD_CMD, cmdreg);
+
+	host->intr_en &= MVSD_NOR_CARD_INT;
+	host->intr_en |= intr | MVSD_NOR_ERROR;
+	mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+	mvsd_write(MVSD_ERR_INTR_EN, 0xffff);
+
+	mod_timer(&host->timer, jiffies + 5 * HZ);
+
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static u32 mvsd_finish_cmd(struct mvsd_host *host, struct mmc_command *cmd,
+			   u32 err_status)
+{
+	void __iomem *iobase = host->base;
+
+	if (cmd->flags & MMC_RSP_136) {
+		unsigned int response[8], i;
+		for (i = 0; i < 8; i++)
+			response[i] = mvsd_read(MVSD_RSP(i));
+		cmd->resp[0] =		((response[0] & 0x03ff) << 22) |
+					((response[1] & 0xffff) << 6) |
+					((response[2] & 0xfc00) >> 10);
+		cmd->resp[1] =		((response[2] & 0x03ff) << 22) |
+					((response[3] & 0xffff) << 6) |
+					((response[4] & 0xfc00) >> 10);
+		cmd->resp[2] =		((response[4] & 0x03ff) << 22) |
+					((response[5] & 0xffff) << 6) |
+					((response[6] & 0xfc00) >> 10);
+		cmd->resp[3] =		((response[6] & 0x03ff) << 22) |
+					((response[7] & 0x3fff) << 8);
+	} else if (cmd->flags & MMC_RSP_PRESENT) {
+		unsigned int response[3], i;
+		for (i = 0; i < 3; i++)
+			response[i] = mvsd_read(MVSD_RSP(i));
+		cmd->resp[0] =		((response[2] & 0x003f) << (8 - 8)) |
+					((response[1] & 0xffff) << (14 - 8)) |
+					((response[0] & 0x03ff) << (30 - 8));
+		cmd->resp[1] =		((response[0] & 0xfc00) >> 10);
+		cmd->resp[2] = 0;
+		cmd->resp[3] = 0;
+	}
+
+	if (err_status & MVSD_ERR_CMD_TIMEOUT) {
+		cmd->error = -ETIMEDOUT;
+	} else if (err_status & (MVSD_ERR_CMD_CRC | MVSD_ERR_CMD_ENDBIT |
+				 MVSD_ERR_CMD_INDEX | MVSD_ERR_CMD_STARTBIT)) {
+		cmd->error = -EILSEQ;
+	}
+	err_status &= ~(MVSD_ERR_CMD_TIMEOUT | MVSD_ERR_CMD_CRC |
+			MVSD_ERR_CMD_ENDBIT | MVSD_ERR_CMD_INDEX |
+			MVSD_ERR_CMD_STARTBIT);
+
+	return err_status;
+}
+
+static u32 mvsd_finish_data(struct mvsd_host *host, struct mmc_data *data,
+			    u32 err_status)
+{
+	void __iomem *iobase = host->base;
+
+	if (host->pio_ptr) {
+		host->pio_ptr = NULL;
+		host->pio_size = 0;
+	} else {
+		dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_frags,
+			     (data->flags & MMC_DATA_READ) ?
+				DMA_FROM_DEVICE : DMA_TO_DEVICE);
+	}
+
+	if (err_status & MVSD_ERR_DATA_TIMEOUT)
+		data->error = -ETIMEDOUT;
+	else if (err_status & (MVSD_ERR_DATA_CRC | MVSD_ERR_DATA_ENDBIT))
+		data->error = -EILSEQ;
+	else if (err_status & MVSD_ERR_XFER_SIZE)
+		data->error = -EBADE;
+	err_status &= ~(MVSD_ERR_DATA_TIMEOUT | MVSD_ERR_DATA_CRC |
+			MVSD_ERR_DATA_ENDBIT | MVSD_ERR_XFER_SIZE);
+
+	dev_dbg(host->dev, "data done: blocks_left=%d, bytes_left=%d\n",
+		mvsd_read(MVSD_CURR_BLK_LEFT), mvsd_read(MVSD_CURR_BYTE_LEFT));
+	data->bytes_xfered =
+		(data->blocks - mvsd_read(MVSD_CURR_BLK_LEFT)) * data->blksz;
+	/* We can't be sure about the last block when errors are detected */
+	if (data->bytes_xfered && data->error)
+		data->bytes_xfered -= data->blksz;
+
+	/* Handle Auto cmd 12 response */
+	if (data->stop) {
+		unsigned int response[3], i;
+		for (i = 0; i < 3; i++)
+			response[i] = mvsd_read(MVSD_AUTO_RSP(i));
+		data->stop->resp[0] =	((response[2] & 0x003f) << (8 - 8)) |
+					((response[1] & 0xffff) << (14 - 8)) |
+					((response[0] & 0x03ff) << (30 - 8));
+		data->stop->resp[1] =	((response[0] & 0xfc00) >> 10);
+		data->stop->resp[2] = 0;
+		data->stop->resp[3] = 0;
+
+		if (err_status & MVSD_ERR_AUTOCMD12) {
+			u32 err_cmd12 = mvsd_read(MVSD_AUTOCMD12_ERR_STATUS);
+			dev_dbg(host->dev, "c12err 0x%04x\n", err_cmd12);
+			if (err_cmd12 & MVSD_AUTOCMD12_ERR_NOTEXE)
+				data->stop->error = -ENOEXEC;
+			else if (err_cmd12 & MVSD_AUTOCMD12_ERR_TIMEOUT)
+				data->stop->error = -ETIMEDOUT;
+			else if (err_cmd12)
+				data->stop->error = -EILSEQ;
+			err_status &= ~MVSD_ERR_AUTOCMD12;
+		}
+	}
+
+	return err_status;
+}
+
+static irqreturn_t mvsd_irq(int irq, void *dev)
+{
+	struct mvsd_host *host = dev;
+	void __iomem *iobase = host->base;
+	u32 intr_status, intr_done_mask;
+	int irq_handled = 0;
+
+	intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+	dev_dbg(host->dev, "intr 0x%04x intr_en 0x%04x hw_state 0x%04x\n",
+		intr_status, mvsd_read(MVSD_NOR_INTR_EN),
+		mvsd_read(MVSD_HW_STATE));
+
+	spin_lock(&host->lock);
+
+	/* PIO handling, if needed. Messy business... */
+	if (host->pio_size &&
+	    (intr_status & host->intr_en &
+	     (MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W))) {
+		u16 *p = host->pio_ptr;
+		int s = host->pio_size;
+		while (s >= 32 && (intr_status & MVSD_NOR_RX_FIFO_8W)) {
+			readsw(iobase + MVSD_FIFO, p, 16);
+			p += 16;
+			s -= 32;
+			intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+		}
+		/*
+		 * Normally we'd use < 32 here, but the RX_FIFO_8W bit
+		 * doesn't appear to assert when there is exactly 32 bytes
+		 * (8 words) left to fetch in a transfer.
+		 */
+		if (s <= 32) {
+			while (s >= 4 && (intr_status & MVSD_NOR_RX_READY)) {
+				put_unaligned(mvsd_read(MVSD_FIFO), p++);
+				put_unaligned(mvsd_read(MVSD_FIFO), p++);
+				s -= 4;
+				intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+			}
+			if (s && s < 4 && (intr_status & MVSD_NOR_RX_READY)) {
+				u16 val[2] = {0, 0};
+				val[0] = mvsd_read(MVSD_FIFO);
+				val[1] = mvsd_read(MVSD_FIFO);
+				memcpy(p, &val, s);
+				s = 0;
+				intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+			}
+			if (s == 0) {
+				host->intr_en &=
+				     ~(MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W);
+				mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+			} else if (host->intr_en & MVSD_NOR_RX_FIFO_8W) {
+				host->intr_en &= ~MVSD_NOR_RX_FIFO_8W;
+				host->intr_en |= MVSD_NOR_RX_READY;
+				mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+			}
+		}
+		dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n",
+			s, intr_status, mvsd_read(MVSD_HW_STATE));
+		host->pio_ptr = p;
+		host->pio_size = s;
+		irq_handled = 1;
+	} else if (host->pio_size &&
+		   (intr_status & host->intr_en &
+		    (MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W))) {
+		u16 *p = host->pio_ptr;
+		int s = host->pio_size;
+		/*
+		 * The TX_FIFO_8W bit is unreliable. When set, bursting
+		 * 16 halfwords all at once in the FIFO drops data. Actually
+		 * TX_AVAIL does go off after only one word is pushed even if
+		 * TX_FIFO_8W remains set.
+		 */
+		while (s >= 4 && (intr_status & MVSD_NOR_TX_AVAIL)) {
+			mvsd_write(MVSD_FIFO, get_unaligned(p++));
+			mvsd_write(MVSD_FIFO, get_unaligned(p++));
+			s -= 4;
+			intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+		}
+		if (s < 4) {
+			if (s && (intr_status & MVSD_NOR_TX_AVAIL)) {
+				u16 val[2] = {0, 0};
+				memcpy(&val, p, s);
+				mvsd_write(MVSD_FIFO, val[0]);
+				mvsd_write(MVSD_FIFO, val[1]);
+				s = 0;
+				intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+			}
+			if (s == 0) {
+				host->intr_en &=
+				     ~(MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W);
+				mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+			}
+		}
+		dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n",
+			s, intr_status, mvsd_read(MVSD_HW_STATE));
+		host->pio_ptr = p;
+		host->pio_size = s;
+		irq_handled = 1;
+	}
+
+	mvsd_write(MVSD_NOR_INTR_STATUS, intr_status);
+
+	intr_done_mask = MVSD_NOR_CARD_INT | MVSD_NOR_RX_READY |
+			 MVSD_NOR_RX_FIFO_8W | MVSD_NOR_TX_FIFO_8W;
+	if (intr_status & host->intr_en & ~intr_done_mask) {
+		struct mmc_request *mrq = host->mrq;
+		struct mmc_command *cmd = mrq->cmd;
+		u32 err_status = 0;
+
+		del_timer(&host->timer);
+		host->mrq = NULL;
+
+		host->intr_en &= MVSD_NOR_CARD_INT;
+		mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+		mvsd_write(MVSD_ERR_INTR_EN, 0);
+
+		spin_unlock(&host->lock);
+
+		if (intr_status & MVSD_NOR_UNEXP_RSP) {
+			cmd->error = -EPROTO;
+		} else if (intr_status & MVSD_NOR_ERROR) {
+			err_status = mvsd_read(MVSD_ERR_INTR_STATUS);
+			dev_dbg(host->dev, "err 0x%04x\n", err_status);
+		}
+
+		err_status = mvsd_finish_cmd(host, cmd, err_status);
+		if (mrq->data)
+			err_status = mvsd_finish_data(host, mrq->data, err_status);
+		if (err_status) {
+			printk(KERN_ERR "%s: unhandled error status %#04x\n",
+					mmc_hostname(host->mmc), err_status);
+			cmd->error = -ENOMSG;
+		}
+
+		mmc_request_done(host->mmc, mrq);
+		irq_handled = 1;
+	} else
+		spin_unlock(&host->lock);
+
+	if (intr_status & MVSD_NOR_CARD_INT) {
+		mmc_signal_sdio_irq(host->mmc);
+		irq_handled = 1;
+	}
+
+	if (irq_handled)
+		return IRQ_HANDLED;
+
+	printk(KERN_ERR "%s: unhandled interrupt status=0x%04x en=0x%04x "
+			"pio=%d\n", mmc_hostname(host->mmc), intr_status,
+			host->intr_en, host->pio_size);
+	return IRQ_NONE;
+}
+
+static void mvsd_timeout_timer(unsigned long data)
+{
+	struct mvsd_host *host = (struct mvsd_host *)data;
+	void __iomem *iobase = host->base;
+	struct mmc_request *mrq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&host->lock, flags);
+	mrq = host->mrq;
+	if (mrq) {
+		printk(KERN_ERR "%s: Timeout waiting for hardware interrupt.\n",
+				mmc_hostname(host->mmc));
+		printk(KERN_ERR "%s: hw_state=0x%04x, intr_status=0x%04x "
+				"intr_en=0x%04x\n", mmc_hostname(host->mmc),
+				mvsd_read(MVSD_HW_STATE),
+				mvsd_read(MVSD_NOR_INTR_STATUS),
+				mvsd_read(MVSD_NOR_INTR_EN));
+
+		host->mrq = NULL;
+
+		mvsd_write(MVSD_SW_RESET, MVSD_SW_RESET_NOW);
+
+		host->xfer_mode &= MVSD_XFER_MODE_INT_CHK_EN;
+		mvsd_write(MVSD_XFER_MODE, host->xfer_mode);
+
+		host->intr_en &= MVSD_NOR_CARD_INT;
+		mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+		mvsd_write(MVSD_ERR_INTR_EN, 0);
+		mvsd_write(MVSD_ERR_INTR_STATUS, 0xffff);
+
+		mrq->cmd->error = -ETIMEDOUT;
+		mvsd_finish_cmd(host, mrq->cmd, 0);
+		if (mrq->data) {
+			mrq->data->error = -ETIMEDOUT;
+			mvsd_finish_data(host, mrq->data, 0);
+		}
+	}
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	if (mrq)
+		mmc_request_done(host->mmc, mrq);
+}
+
+static irqreturn_t mvsd_card_detect_irq(int irq, void *dev)
+{
+	struct mvsd_host *host = dev;
+	mmc_detect_change(host->mmc, msecs_to_jiffies(100));
+	return IRQ_HANDLED;
+}
+
+static void mvsd_enable_sdio_irq(struct mmc_host *mmc, int enable)
+{
+	struct mvsd_host *host = mmc_priv(mmc);
+	void __iomem *iobase = host->base;
+	unsigned long flags;
+
+	spin_lock_irqsave(&host->lock, flags);
+	if (enable) {
+		host->xfer_mode |= MVSD_XFER_MODE_INT_CHK_EN;
+		host->intr_en |= MVSD_NOR_CARD_INT;
+	} else {
+		host->xfer_mode &= ~MVSD_XFER_MODE_INT_CHK_EN;
+		host->intr_en &= ~MVSD_NOR_CARD_INT;
+	}
+	mvsd_write(MVSD_XFER_MODE, host->xfer_mode);
+	mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static int mvsd_get_ro(struct mmc_host *mmc)
+{
+	struct mvsd_host *host = mmc_priv(mmc);
+
+	if (host->gpio_write_protect)
+		return gpio_get_value(host->gpio_write_protect);
+
+	/*
+	 * Board doesn't support read only detection; let the mmc core
+	 * decide what to do.
+	 */
+	return -ENOSYS;
+}
+
+static void mvsd_power_up(struct mvsd_host *host)
+{
+	void __iomem *iobase = host->base;
+	dev_dbg(host->dev, "power up\n");
+	mvsd_write(MVSD_NOR_INTR_EN, 0);
+	mvsd_write(MVSD_ERR_INTR_EN, 0);
+	mvsd_write(MVSD_SW_RESET, MVSD_SW_RESET_NOW);
+	mvsd_write(MVSD_XFER_MODE, 0);
+	mvsd_write(MVSD_NOR_STATUS_EN, 0xffff);
+	mvsd_write(MVSD_ERR_STATUS_EN, 0xffff);
+	mvsd_write(MVSD_NOR_INTR_STATUS, 0xffff);
+	mvsd_write(MVSD_ERR_INTR_STATUS, 0xffff);
+}
+
+static void mvsd_power_down(struct mvsd_host *host)
+{
+	void __iomem *iobase = host->base;
+	dev_dbg(host->dev, "power down\n");
+	mvsd_write(MVSD_NOR_INTR_EN, 0);
+	mvsd_write(MVSD_ERR_INTR_EN, 0);
+	mvsd_write(MVSD_SW_RESET, MVSD_SW_RESET_NOW);
+	mvsd_write(MVSD_XFER_MODE, MVSD_XFER_MODE_STOP_CLK);
+	mvsd_write(MVSD_NOR_STATUS_EN, 0);
+	mvsd_write(MVSD_ERR_STATUS_EN, 0);
+	mvsd_write(MVSD_NOR_INTR_STATUS, 0xffff);
+	mvsd_write(MVSD_ERR_INTR_STATUS, 0xffff);
+}
+
+static void mvsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct mvsd_host *host = mmc_priv(mmc);
+	void __iomem *iobase = host->base;
+	u32 ctrl_reg = 0;
+
+	if (ios->power_mode == MMC_POWER_UP)
+		mvsd_power_up(host);
+
+	if (ios->clock == 0) {
+		mvsd_write(MVSD_XFER_MODE, MVSD_XFER_MODE_STOP_CLK);
+		mvsd_write(MVSD_CLK_DIV, MVSD_BASE_DIV_MAX);
+		host->clock = 0;
+		dev_dbg(host->dev, "clock off\n");
+	} else if (ios->clock != host->clock) {
+		u32 m = DIV_ROUND_UP(host->base_clock, ios->clock) - 1;
+		if (m > MVSD_BASE_DIV_MAX)
+			m = MVSD_BASE_DIV_MAX;
+		mvsd_write(MVSD_CLK_DIV, m);
+		host->clock = ios->clock;
+		host->ns_per_clk = 1000000000 / (host->base_clock / (m+1));
+		dev_dbg(host->dev, "clock=%d (%d), div=0x%04x\n",
+			ios->clock, host->base_clock / (m+1), m);
+	}
+
+	/* default transfer mode */
+	ctrl_reg |= MVSD_HOST_CTRL_BIG_ENDIAN;
+	ctrl_reg &= ~MVSD_HOST_CTRL_LSB_FIRST;
+
+	/* default to maximum timeout */
+	ctrl_reg |= MVSD_HOST_CTRL_TMOUT_MASK;
+	ctrl_reg |= MVSD_HOST_CTRL_TMOUT_EN;
+
+	if (ios->bus_mode == MMC_BUSMODE_PUSHPULL)
+		ctrl_reg |= MVSD_HOST_CTRL_PUSH_PULL_EN;
+
+	if (ios->bus_width == MMC_BUS_WIDTH_4)
+		ctrl_reg |= MVSD_HOST_CTRL_DATA_WIDTH_4_BITS;
+
+	if (ios->timing == MMC_TIMING_MMC_HS ||
+	    ios->timing == MMC_TIMING_SD_HS)
+		ctrl_reg |= MVSD_HOST_CTRL_HI_SPEED_EN;
+
+	host->ctrl = ctrl_reg;
+	mvsd_write(MVSD_HOST_CTRL, ctrl_reg);
+	dev_dbg(host->dev, "ctrl 0x%04x: %s %s %s\n", ctrl_reg,
+		(ctrl_reg & MVSD_HOST_CTRL_PUSH_PULL_EN) ?
+			"push-pull" : "open-drain",
+		(ctrl_reg & MVSD_HOST_CTRL_DATA_WIDTH_4_BITS) ?
+			"4bit-width" : "1bit-width",
+		(ctrl_reg & MVSD_HOST_CTRL_HI_SPEED_EN) ?
+			"high-speed" : "");
+
+	if (ios->power_mode == MMC_POWER_OFF)
+		mvsd_power_down(host);
+}
+
+static const struct mmc_host_ops mvsd_ops = {
+	.request		= mvsd_request,
+	.get_ro			= mvsd_get_ro,
+	.set_ios		= mvsd_set_ios,
+	.enable_sdio_irq	= mvsd_enable_sdio_irq,
+};
+
+static void __init mv_conf_mbus_windows(struct mvsd_host *host,
+					struct mbus_dram_target_info *dram)
+{
+	void __iomem *iobase = host->base;
+	int i;
+
+	for (i = 0; i < 4; i++) {
+		writel(0, iobase + MVSD_WINDOW_CTRL(i));
+		writel(0, iobase + MVSD_WINDOW_BASE(i));
+	}
+
+	for (i = 0; i < dram->num_cs; i++) {
+		struct mbus_dram_window *cs = dram->cs + i;
+		writel(((cs->size - 1) & 0xffff0000) |
+		       (cs->mbus_attr << 8) |
+		       (dram->mbus_dram_target_id << 4) | 1,
+		       iobase + MVSD_WINDOW_CTRL(i));
+		writel(cs->base, iobase + MVSD_WINDOW_BASE(i));
+	}
+}
+
+static int __init mvsd_probe(struct platform_device *pdev)
+{
+	struct mmc_host *mmc = NULL;
+	struct mvsd_host *host = NULL;
+	const struct mvsdio_platform_data *mvsd_data;
+	struct resource *r;
+	int ret, irq;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	irq = platform_get_irq(pdev, 0);
+	mvsd_data = pdev->dev.platform_data;
+	if (!r || irq < 0 || !mvsd_data)
+		return -ENXIO;
+
+	r = request_mem_region(r->start, SZ_1K, DRIVER_NAME);
+	if (!r)
+		return -EBUSY;
+
+	mmc = mmc_alloc_host(sizeof(struct mvsd_host), &pdev->dev);
+	if (!mmc) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	host = mmc_priv(mmc);
+	host->mmc = mmc;
+	host->dev = &pdev->dev;
+	host->res = r;
+	host->base_clock = mvsd_data->clock / 2;
+
+	mmc->ops = &mvsd_ops;
+
+	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+	mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ |
+		    MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
+
+	mmc->f_min = DIV_ROUND_UP(host->base_clock, MVSD_BASE_DIV_MAX);
+	mmc->f_max = maxfreq;
+
+	mmc->max_blk_size = 2048;
+	mmc->max_blk_count = 65535;
+
+	mmc->max_hw_segs = 1;
+	mmc->max_phys_segs = 1;
+	mmc->max_seg_size = mmc->max_blk_size * mmc->max_blk_count;
+	mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
+
+	spin_lock_init(&host->lock);
+
+	host->base = ioremap(r->start, SZ_4K);
+	if (!host->base) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* (Re-)program MBUS remapping windows if we are asked to. */
+	if (mvsd_data->dram != NULL)
+		mv_conf_mbus_windows(host, mvsd_data->dram);
+
+	mvsd_power_down(host);
+
+	ret = request_irq(irq, mvsd_irq, 0, DRIVER_NAME, host);
+	if (ret) {
+		printk(KERN_ERR "%s: cannot assign irq %d\n", DRIVER_NAME, irq);
+		goto out;
+	} else
+		host->irq = irq;
+
+	if (mvsd_data->gpio_card_detect) {
+		ret = gpio_request(mvsd_data->gpio_card_detect,
+				   DRIVER_NAME " cd");
+		if (ret == 0) {
+			gpio_direction_input(mvsd_data->gpio_card_detect);
+			irq = gpio_to_irq(mvsd_data->gpio_card_detect);
+			ret = request_irq(irq, mvsd_card_detect_irq,
+					  IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING,
+					  DRIVER_NAME " cd", host);
+			if (ret == 0)
+				host->gpio_card_detect =
+					mvsd_data->gpio_card_detect;
+			else
+				gpio_free(mvsd_data->gpio_card_detect);
+		}
+	}
+	if (!host->gpio_card_detect)
+		mmc->caps |= MMC_CAP_NEEDS_POLL;
+
+	if (mvsd_data->gpio_write_protect) {
+		ret = gpio_request(mvsd_data->gpio_write_protect,
+				   DRIVER_NAME " wp");
+		if (ret == 0) {
+			gpio_direction_input(mvsd_data->gpio_write_protect);
+			host->gpio_write_protect =
+				mvsd_data->gpio_write_protect;
+		}
+	}
+
+	setup_timer(&host->timer, mvsd_timeout_timer, (unsigned long)host);
+	platform_set_drvdata(pdev, mmc);
+	ret = mmc_add_host(mmc);
+	if (ret)
+		goto out;
+
+	printk(KERN_NOTICE "%s: %s driver initialized, ",
+			   mmc_hostname(mmc), DRIVER_NAME);
+	if (host->gpio_card_detect)
+		printk("using GPIO %d for card detection\n",
+		       host->gpio_card_detect);
+	else
+		printk("lacking card detect (fall back to polling)\n");
+	return 0;
+
+out:
+	if (host) {
+		if (host->irq)
+			free_irq(host->irq, host);
+		if (host->gpio_card_detect) {
+			free_irq(gpio_to_irq(host->gpio_card_detect), host);
+			gpio_free(host->gpio_card_detect);
+		}
+		if (host->gpio_write_protect)
+			gpio_free(host->gpio_write_protect);
+		if (host->base)
+			iounmap(host->base);
+	}
+	if (r)
+		release_resource(r);
+	if (mmc)
+		mmc_free_host(mmc);
+
+	return ret;
+}
+
+static int __exit mvsd_remove(struct platform_device *pdev)
+{
+	struct mmc_host *mmc = platform_get_drvdata(pdev);
+
+	if (mmc) {
+		struct mvsd_host *host = mmc_priv(mmc);
+
+		if (host->gpio_card_detect) {
+			free_irq(gpio_to_irq(host->gpio_card_detect), host);
+			gpio_free(host->gpio_card_detect);
+		}
+		mmc_remove_host(mmc);
+		free_irq(host->irq, host);
+		if (host->gpio_write_protect)
+			gpio_free(host->gpio_write_protect);
+		del_timer_sync(&host->timer);
+		mvsd_power_down(host);
+		iounmap(host->base);
+		release_resource(host->res);
+		mmc_free_host(mmc);
+	}
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int mvsd_suspend(struct platform_device *dev, pm_message_t state,
+			   u32 level)
+{
+	struct mmc_host *mmc = platform_get_drvdata(dev);
+	int ret = 0;
+
+	if (mmc && level == SUSPEND_DISABLE)
+		ret = mmc_suspend_host(mmc, state);
+
+	return ret;
+}
+
+static int mvsd_resume(struct platform_device *dev, u32 level)
+{
+	struct mmc_host *mmc = platform_dev_get_drvdata(dev);
+	int ret = 0;
+
+	if (mmc && level == RESUME_ENABLE)
+		ret = mmc_resume_host(mmc);
+
+	return ret;
+}
+#else
+#define mvsd_suspend	NULL
+#define mvsd_resume	NULL
+#endif
+
+static struct platform_driver mvsd_driver = {
+	.remove		= __exit_p(mvsd_remove),
+	.suspend	= mvsd_suspend,
+	.resume		= mvsd_resume,
+	.driver		= {
+		.name	= DRIVER_NAME,
+	},
+};
+
+static int __init mvsd_init(void)
+{
+	return platform_driver_probe(&mvsd_driver, mvsd_probe);
+}
+
+static void __exit mvsd_exit(void)
+{
+	platform_driver_unregister(&mvsd_driver);
+}
+
+module_init(mvsd_init);
+module_exit(mvsd_exit);
+
+/* maximum card clock frequency (default 50MHz) */
+module_param(maxfreq, int, 0);
+
+/* force PIO transfers all the time */
+module_param(nodma, int, 0);
+
+MODULE_AUTHOR("Maen Suleiman, Nicolas Pitre");
+MODULE_DESCRIPTION("Marvell MMC,SD,SDIO Host Controller driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/host/mvsdio.h b/drivers/mmc/host/mvsdio.h
new file mode 100644
index 0000000..7d9727b
--- /dev/null
+++ b/drivers/mmc/host/mvsdio.h
@@ -0,0 +1,190 @@
+/*
+ *  Copyright (C) 2008 Marvell Semiconductors, 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.
+ */
+
+#ifndef __MVSDIO_H
+#define __MVSDIO_H
+
+/*
+ * Clock rates
+ */
+
+#define MVSD_CLOCKRATE_MAX			50000000
+#define MVSD_BASE_DIV_MAX			0x7ff
+
+
+/*
+ * Register offsets
+ */
+
+#define MVSD_SYS_ADDR_LOW			0x000
+#define MVSD_SYS_ADDR_HI			0x004
+#define MVSD_BLK_SIZE				0x008
+#define MVSD_BLK_COUNT				0x00c
+#define MVSD_ARG_LOW				0x010
+#define MVSD_ARG_HI				0x014
+#define MVSD_XFER_MODE				0x018
+#define MVSD_CMD				0x01c
+#define MVSD_RSP(i)				(0x020 + ((i)<<2))
+#define MVSD_RSP0				0x020
+#define MVSD_RSP1				0x024
+#define MVSD_RSP2				0x028
+#define MVSD_RSP3				0x02c
+#define MVSD_RSP4				0x030
+#define MVSD_RSP5				0x034
+#define MVSD_RSP6				0x038
+#define MVSD_RSP7				0x03c
+#define MVSD_FIFO				0x040
+#define MVSD_RSP_CRC7				0x044
+#define MVSD_HW_STATE				0x048
+#define MVSD_HOST_CTRL				0x050
+#define MVSD_BLK_GAP_CTRL			0x054
+#define MVSD_CLK_CTRL				0x058
+#define MVSD_SW_RESET				0x05c
+#define MVSD_NOR_INTR_STATUS			0x060
+#define MVSD_ERR_INTR_STATUS			0x064
+#define MVSD_NOR_STATUS_EN			0x068
+#define MVSD_ERR_STATUS_EN			0x06c
+#define MVSD_NOR_INTR_EN			0x070
+#define MVSD_ERR_INTR_EN			0x074
+#define MVSD_AUTOCMD12_ERR_STATUS		0x078
+#define MVSD_CURR_BYTE_LEFT			0x07c
+#define MVSD_CURR_BLK_LEFT			0x080
+#define MVSD_AUTOCMD12_ARG_LOW			0x084
+#define MVSD_AUTOCMD12_ARG_HI			0x088
+#define MVSD_AUTOCMD12_CMD			0x08c
+#define MVSD_AUTO_RSP(i)			(0x090 + ((i)<<2))
+#define MVSD_AUTO_RSP0				0x090
+#define MVSD_AUTO_RSP1				0x094
+#define MVSD_AUTO_RSP2				0x098
+#define MVSD_CLK_DIV				0x128
+
+#define MVSD_WINDOW_CTRL(i)			(0x108 + ((i) << 3))
+#define MVSD_WINDOW_BASE(i)			(0x10c + ((i) << 3))
+
+
+/*
+ * MVSD_CMD
+ */
+
+#define MVSD_CMD_RSP_NONE			(0 << 0)
+#define MVSD_CMD_RSP_136			(1 << 0)
+#define MVSD_CMD_RSP_48				(2 << 0)
+#define MVSD_CMD_RSP_48BUSY			(3 << 0)
+
+#define MVSD_CMD_CHECK_DATACRC16		(1 << 2)
+#define MVSD_CMD_CHECK_CMDCRC			(1 << 3)
+#define MVSD_CMD_INDX_CHECK			(1 << 4)
+#define MVSD_CMD_DATA_PRESENT			(1 << 5)
+#define MVSD_UNEXPECTED_RESP			(1 << 7)
+#define MVSD_CMD_INDEX(x)			((x) << 8)
+
+
+/*
+ * MVSD_AUTOCMD12_CMD
+ */
+
+#define MVSD_AUTOCMD12_BUSY			(1 << 0)
+#define MVSD_AUTOCMD12_INDX_CHECK		(1 << 1)
+#define MVSD_AUTOCMD12_INDEX(x)			((x) << 8)
+
+/*
+ * MVSD_XFER_MODE
+ */
+
+#define MVSD_XFER_MODE_WR_DATA_START		(1 << 0)
+#define MVSD_XFER_MODE_HW_WR_DATA_EN		(1 << 1)
+#define MVSD_XFER_MODE_AUTO_CMD12		(1 << 2)
+#define MVSD_XFER_MODE_INT_CHK_EN		(1 << 3)
+#define MVSD_XFER_MODE_TO_HOST			(1 << 4)
+#define MVSD_XFER_MODE_STOP_CLK			(1 << 5)
+#define MVSD_XFER_MODE_PIO			(1 << 6)
+
+
+/*
+ * MVSD_HOST_CTRL
+ */
+
+#define MVSD_HOST_CTRL_PUSH_PULL_EN 		(1 << 0)
+
+#define MVSD_HOST_CTRL_CARD_TYPE_MEM_ONLY 	(0 << 1)
+#define MVSD_HOST_CTRL_CARD_TYPE_IO_ONLY 	(1 << 1)
+#define MVSD_HOST_CTRL_CARD_TYPE_IO_MEM_COMBO 	(2 << 1)
+#define MVSD_HOST_CTRL_CARD_TYPE_IO_MMC 	(3 << 1)
+#define MVSD_HOST_CTRL_CARD_TYPE_MASK	 	(3 << 1)
+
+#define MVSD_HOST_CTRL_BIG_ENDIAN 		(1 << 3)
+#define MVSD_HOST_CTRL_LSB_FIRST 		(1 << 4)
+#define MVSD_HOST_CTRL_DATA_WIDTH_4_BITS 	(1 << 9)
+#define MVSD_HOST_CTRL_HI_SPEED_EN 		(1 << 10)
+
+#define MVSD_HOST_CTRL_TMOUT_MAX 		0xf
+#define MVSD_HOST_CTRL_TMOUT_MASK 		(0xf << 11)
+#define MVSD_HOST_CTRL_TMOUT(x) 		((x) << 11)
+#define MVSD_HOST_CTRL_TMOUT_EN 		(1 << 15)
+
+
+/*
+ * MVSD_SW_RESET
+ */
+
+#define MVSD_SW_RESET_NOW			(1 << 8)
+
+
+/*
+ * Normal interrupt status bits
+ */
+
+#define MVSD_NOR_CMD_DONE			(1 << 0)
+#define MVSD_NOR_XFER_DONE			(1 << 1)
+#define MVSD_NOR_BLK_GAP_EVT			(1 << 2)
+#define MVSD_NOR_DMA_DONE			(1 << 3)
+#define MVSD_NOR_TX_AVAIL			(1 << 4)
+#define MVSD_NOR_RX_READY			(1 << 5)
+#define MVSD_NOR_CARD_INT			(1 << 8)
+#define MVSD_NOR_READ_WAIT_ON			(1 << 9)
+#define MVSD_NOR_RX_FIFO_8W			(1 << 10)
+#define MVSD_NOR_TX_FIFO_8W			(1 << 11)
+#define MVSD_NOR_SUSPEND_ON			(1 << 12)
+#define MVSD_NOR_AUTOCMD12_DONE			(1 << 13)
+#define MVSD_NOR_UNEXP_RSP			(1 << 14)
+#define MVSD_NOR_ERROR				(1 << 15)
+
+
+/*
+ * Error status bits
+ */
+
+#define MVSD_ERR_CMD_TIMEOUT			(1 << 0)
+#define MVSD_ERR_CMD_CRC			(1 << 1)
+#define MVSD_ERR_CMD_ENDBIT			(1 << 2)
+#define MVSD_ERR_CMD_INDEX			(1 << 3)
+#define MVSD_ERR_DATA_TIMEOUT			(1 << 4)
+#define MVSD_ERR_DATA_CRC			(1 << 5)
+#define MVSD_ERR_DATA_ENDBIT			(1 << 6)
+#define MVSD_ERR_AUTOCMD12			(1 << 8)
+#define MVSD_ERR_CMD_STARTBIT			(1 << 9)
+#define MVSD_ERR_XFER_SIZE			(1 << 10)
+#define MVSD_ERR_RESP_T_BIT			(1 << 11)
+#define MVSD_ERR_CRC_ENDBIT			(1 << 12)
+#define MVSD_ERR_CRC_STARTBIT			(1 << 13)
+#define MVSD_ERR_CRC_STATUS			(1 << 14)
+
+
+/*
+ * CMD12 error status bits
+ */
+
+#define MVSD_AUTOCMD12_ERR_NOTEXE		(1 << 0)
+#define MVSD_AUTOCMD12_ERR_TIMEOUT		(1 << 1)
+#define MVSD_AUTOCMD12_ERR_CRC			(1 << 2)
+#define MVSD_AUTOCMD12_ERR_ENDBIT		(1 << 3)
+#define MVSD_AUTOCMD12_ERR_INDEX		(1 << 4)
+#define MVSD_AUTOCMD12_ERR_RESP_T_BIT		(1 << 5)
+#define MVSD_AUTOCMD12_ERR_RESP_STARTBIT	(1 << 6)
+
+#endif
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 3916a56..d183be6 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -56,6 +56,7 @@
 #define SDVS18			(0x5 << 9)
 #define SDVS30			(0x6 << 9)
 #define SDVS33			(0x7 << 9)
+#define SDVS_MASK		0x00000E00
 #define SDVSCLR			0xFFFFF1FF
 #define SDVSDET			0x00000400
 #define AUTOIDLE		0x1
@@ -76,6 +77,7 @@
 #define MSBS			(1 << 5)
 #define BCE			(1 << 1)
 #define FOUR_BIT		(1 << 1)
+#define DW8			(1 << 5)
 #define CC			0x1
 #define TC			0x02
 #define OD			0x1
@@ -98,10 +100,8 @@
  */
 #define OMAP_MMC1_DEVID		0
 #define OMAP_MMC2_DEVID		1
+#define OMAP_MMC3_DEVID		2
 
-#define OMAP_MMC_DATADIR_NONE	0
-#define OMAP_MMC_DATADIR_READ	1
-#define OMAP_MMC_DATADIR_WRITE	2
 #define MMC_TIMEOUT_MS		20
 #define OMAP_MMC_MASTER_CLOCK	96000000
 #define DRIVER_NAME		"mmci-omap-hs"
@@ -137,18 +137,18 @@
 	resource_size_t		mapbase;
 	unsigned int		id;
 	unsigned int		dma_len;
-	unsigned int		dma_dir;
+	unsigned int		dma_sg_idx;
 	unsigned char		bus_mode;
-	unsigned char		datadir;
 	u32			*buffer;
 	u32			bytesleft;
 	int			suspended;
 	int			irq;
 	int			carddetect;
 	int			use_dma, dma_ch;
-	int			initstr;
+	int			dma_line_tx, dma_line_rx;
 	int			slot_id;
 	int			dbclk_enabled;
+	int			response_busy;
 	struct	omap_mmc_platform_data	*pdata;
 };
 
@@ -218,7 +218,7 @@
 	struct mmc_omap_host *host = mmc_priv(mmc);
 	struct omap_mmc_slot_data slot = host->pdata->slots[host->slot_id];
 
-	return sprintf(buf, "slot:%s\n", slot.name);
+	return sprintf(buf, "%s\n", slot.name);
 }
 
 static DEVICE_ATTR(slot_name, S_IRUGO, mmc_omap_show_slot_name, NULL);
@@ -243,10 +243,14 @@
 	OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK);
 	OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK);
 
+	host->response_busy = 0;
 	if (cmd->flags & MMC_RSP_PRESENT) {
 		if (cmd->flags & MMC_RSP_136)
 			resptype = 1;
-		else
+		else if (cmd->flags & MMC_RSP_BUSY) {
+			resptype = 3;
+			host->response_busy = 1;
+		} else
 			resptype = 2;
 	}
 
@@ -275,19 +279,35 @@
 	OMAP_HSMMC_WRITE(host->base, CMD, cmdreg);
 }
 
+static int
+mmc_omap_get_dma_dir(struct mmc_omap_host *host, struct mmc_data *data)
+{
+	if (data->flags & MMC_DATA_WRITE)
+		return DMA_TO_DEVICE;
+	else
+		return DMA_FROM_DEVICE;
+}
+
 /*
  * Notify the transfer complete to MMC core
  */
 static void
 mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data)
 {
+	if (!data) {
+		struct mmc_request *mrq = host->mrq;
+
+		host->mrq = NULL;
+		mmc_omap_fclk_lazy_disable(host);
+		mmc_request_done(host->mmc, mrq);
+		return;
+	}
+
 	host->data = NULL;
 
 	if (host->use_dma && host->dma_ch != -1)
 		dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len,
-			host->dma_dir);
-
-	host->datadir = OMAP_MMC_DATADIR_NONE;
+			mmc_omap_get_dma_dir(host, data));
 
 	if (!data->error)
 		data->bytes_xfered += data->blocks * (data->blksz);
@@ -322,7 +342,7 @@
 			cmd->resp[0] = OMAP_HSMMC_READ(host->base, RSP10);
 		}
 	}
-	if (host->data == NULL || cmd->error) {
+	if ((host->data == NULL && !host->response_busy) || cmd->error) {
 		host->mrq = NULL;
 		mmc_request_done(host->mmc, cmd->mrq);
 	}
@@ -331,19 +351,18 @@
 /*
  * DMA clean up for command errors
  */
-static void mmc_dma_cleanup(struct mmc_omap_host *host)
+static void mmc_dma_cleanup(struct mmc_omap_host *host, int errno)
 {
-	host->data->error = -ETIMEDOUT;
+	host->data->error = errno;
 
 	if (host->use_dma && host->dma_ch != -1) {
 		dma_unmap_sg(mmc_dev(host->mmc), host->data->sg, host->dma_len,
-			host->dma_dir);
+			mmc_omap_get_dma_dir(host, host->data));
 		omap_free_dma(host->dma_ch);
 		host->dma_ch = -1;
 		up(&host->sem);
 	}
 	host->data = NULL;
-	host->datadir = OMAP_MMC_DATADIR_NONE;
 }
 
 /*
@@ -412,7 +431,7 @@
 	struct mmc_data *data;
 	int end_cmd = 0, end_trans = 0, status;
 
-	if (host->cmd == NULL && host->data == NULL) {
+	if (host->mrq == NULL) {
 		OMAP_HSMMC_WRITE(host->base, STAT,
 			OMAP_HSMMC_READ(host->base, STAT));
 		return IRQ_HANDLED;
@@ -437,18 +456,24 @@
 				}
 				end_cmd = 1;
 			}
-			if (host->data) {
-				mmc_dma_cleanup(host);
+			if (host->data || host->response_busy) {
+				if (host->data)
+					mmc_dma_cleanup(host, -ETIMEDOUT);
+				host->response_busy = 0;
 				mmc_omap_reset_controller_fsm(host, SRD);
 			}
 		}
 		if ((status & DATA_TIMEOUT) ||
 			(status & DATA_CRC)) {
-			if (host->data) {
-				if (status & DATA_TIMEOUT)
-					mmc_dma_cleanup(host);
+			if (host->data || host->response_busy) {
+				int err = (status & DATA_TIMEOUT) ?
+						-ETIMEDOUT : -EILSEQ;
+
+				if (host->data)
+					mmc_dma_cleanup(host, err);
 				else
-					host->data->error = -EILSEQ;
+					host->mrq->cmd->error = err;
+				host->response_busy = 0;
 				mmc_omap_reset_controller_fsm(host, SRD);
 				end_trans = 1;
 			}
@@ -473,6 +498,19 @@
 	return IRQ_HANDLED;
 }
 
+static void set_sd_bus_power(struct mmc_omap_host *host)
+{
+	unsigned long i;
+
+	OMAP_HSMMC_WRITE(host->base, HCTL,
+			 OMAP_HSMMC_READ(host->base, HCTL) | SDBP);
+	for (i = 0; i < loops_per_jiffy; i++) {
+		if (OMAP_HSMMC_READ(host->base, HCTL) & SDBP)
+			break;
+		cpu_relax();
+	}
+}
+
 /*
  * Switch MMC interface voltage ... only relevant for MMC1.
  *
@@ -485,9 +523,6 @@
 	u32 reg_val = 0;
 	int ret;
 
-	if (host->id != OMAP_MMC1_DEVID)
-		return 0;
-
 	/* Disable the clocks */
 	clk_disable(host->fclk);
 	clk_disable(host->iclk);
@@ -532,9 +567,7 @@
 		reg_val |= SDVS30;
 
 	OMAP_HSMMC_WRITE(host->base, HCTL, reg_val);
-
-	OMAP_HSMMC_WRITE(host->base, HCTL,
-		OMAP_HSMMC_READ(host->base, HCTL) | SDBP);
+	set_sd_bus_power(host);
 
 	return 0;
 err:
@@ -551,7 +584,10 @@
 						mmc_carddetect_work);
 	struct omap_mmc_slot_data *slot = &mmc_slot(host);
 
-	host->carddetect = slot->card_detect(slot->card_detect_irq);
+	if (mmc_slot(host).card_detect)
+		host->carddetect = slot->card_detect(slot->card_detect_irq);
+	else
+		host->carddetect = -ENOSYS;
 
 	sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch");
 	if (host->carddetect) {
@@ -574,6 +610,48 @@
 	return IRQ_HANDLED;
 }
 
+static int mmc_omap_get_dma_sync_dev(struct mmc_omap_host *host,
+				     struct mmc_data *data)
+{
+	int sync_dev;
+
+	if (data->flags & MMC_DATA_WRITE)
+		sync_dev = host->dma_line_tx;
+	else
+		sync_dev = host->dma_line_rx;
+	return sync_dev;
+}
+
+static void mmc_omap_config_dma_params(struct mmc_omap_host *host,
+				       struct mmc_data *data,
+				       struct scatterlist *sgl)
+{
+	int blksz, nblk, dma_ch;
+
+	dma_ch = host->dma_ch;
+	if (data->flags & MMC_DATA_WRITE) {
+		omap_set_dma_dest_params(dma_ch, 0, OMAP_DMA_AMODE_CONSTANT,
+			(host->mapbase + OMAP_HSMMC_DATA), 0, 0);
+		omap_set_dma_src_params(dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
+			sg_dma_address(sgl), 0, 0);
+	} else {
+		omap_set_dma_src_params(dma_ch, 0, OMAP_DMA_AMODE_CONSTANT,
+					(host->mapbase + OMAP_HSMMC_DATA), 0, 0);
+		omap_set_dma_dest_params(dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
+			sg_dma_address(sgl), 0, 0);
+	}
+
+	blksz = host->data->blksz;
+	nblk = sg_dma_len(sgl) / blksz;
+
+	omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S32,
+			blksz / 4, nblk, OMAP_DMA_SYNC_FRAME,
+			mmc_omap_get_dma_sync_dev(host, data),
+			!(data->flags & MMC_DATA_WRITE));
+
+	omap_start_dma(dma_ch);
+}
+
 /*
  * DMA call back function
  */
@@ -587,6 +665,14 @@
 	if (host->dma_ch < 0)
 		return;
 
+	host->dma_sg_idx++;
+	if (host->dma_sg_idx < host->dma_len) {
+		/* Fire up the next transfer. */
+		mmc_omap_config_dma_params(host, host->data,
+					   host->data->sg + host->dma_sg_idx);
+		return;
+	}
+
 	omap_free_dma(host->dma_ch);
 	host->dma_ch = -1;
 	/*
@@ -597,38 +683,28 @@
 }
 
 /*
- * Configure dma src and destination parameters
- */
-static int mmc_omap_config_dma_param(int sync_dir, struct mmc_omap_host *host,
-				struct mmc_data *data)
-{
-	if (sync_dir == 0) {
-		omap_set_dma_dest_params(host->dma_ch, 0,
-			OMAP_DMA_AMODE_CONSTANT,
-			(host->mapbase + OMAP_HSMMC_DATA), 0, 0);
-		omap_set_dma_src_params(host->dma_ch, 0,
-			OMAP_DMA_AMODE_POST_INC,
-			sg_dma_address(&data->sg[0]), 0, 0);
-	} else {
-		omap_set_dma_src_params(host->dma_ch, 0,
-			OMAP_DMA_AMODE_CONSTANT,
-			(host->mapbase + OMAP_HSMMC_DATA), 0, 0);
-		omap_set_dma_dest_params(host->dma_ch, 0,
-			OMAP_DMA_AMODE_POST_INC,
-			sg_dma_address(&data->sg[0]), 0, 0);
-	}
-	return 0;
-}
-/*
  * Routine to configure and start DMA for the MMC card
  */
 static int
 mmc_omap_start_dma_transfer(struct mmc_omap_host *host, struct mmc_request *req)
 {
-	int sync_dev, sync_dir = 0;
-	int dma_ch = 0, ret = 0, err = 1;
+	int dma_ch = 0, ret = 0, err = 1, i;
 	struct mmc_data *data = req->data;
 
+	/* Sanity check: all the SG entries must be aligned by block size. */
+	for (i = 0; i < host->dma_len; i++) {
+		struct scatterlist *sgl;
+
+		sgl = data->sg + i;
+		if (sgl->length % data->blksz)
+			return -EINVAL;
+	}
+	if ((data->blksz % 4) != 0)
+		/* REVISIT: The MMC buffer increments only when MSB is written.
+		 * Return error for blksz which is non multiple of four.
+		 */
+		return -EINVAL;
+
 	/*
 	 * If for some reason the DMA transfer is still active,
 	 * we wait for timeout period and free the dma
@@ -647,49 +723,22 @@
 			return err;
 	}
 
-	if (!(data->flags & MMC_DATA_WRITE)) {
-		host->dma_dir = DMA_FROM_DEVICE;
-		if (host->id == OMAP_MMC1_DEVID)
-			sync_dev = OMAP24XX_DMA_MMC1_RX;
-		else
-			sync_dev = OMAP24XX_DMA_MMC2_RX;
-	} else {
-		host->dma_dir = DMA_TO_DEVICE;
-		if (host->id == OMAP_MMC1_DEVID)
-			sync_dev = OMAP24XX_DMA_MMC1_TX;
-		else
-			sync_dev = OMAP24XX_DMA_MMC2_TX;
-	}
-
-	ret = omap_request_dma(sync_dev, "MMC/SD", mmc_omap_dma_cb,
-			host, &dma_ch);
+	ret = omap_request_dma(mmc_omap_get_dma_sync_dev(host, data), "MMC/SD",
+			       mmc_omap_dma_cb,host, &dma_ch);
 	if (ret != 0) {
-		dev_dbg(mmc_dev(host->mmc),
+		dev_err(mmc_dev(host->mmc),
 			"%s: omap_request_dma() failed with %d\n",
 			mmc_hostname(host->mmc), ret);
 		return ret;
 	}
 
 	host->dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg,
-			data->sg_len, host->dma_dir);
+			data->sg_len, mmc_omap_get_dma_dir(host, data));
 	host->dma_ch = dma_ch;
+	host->dma_sg_idx = 0;
 
-	if (!(data->flags & MMC_DATA_WRITE))
-		mmc_omap_config_dma_param(1, host, data);
-	else
-		mmc_omap_config_dma_param(0, host, data);
+	mmc_omap_config_dma_params(host, data, data->sg);
 
-	if ((data->blksz % 4) == 0)
-		omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S32,
-			(data->blksz / 4), data->blocks, OMAP_DMA_SYNC_FRAME,
-			sync_dev, sync_dir);
-	else
-		/* REVISIT: The MMC buffer increments only when MSB is written.
-		 * Return error for blksz which is non multiple of four.
-		 */
-		return -EINVAL;
-
-	omap_start_dma(dma_ch);
 	return 0;
 }
 
@@ -739,7 +788,6 @@
 	host->data = req->data;
 
 	if (req->data == NULL) {
-		host->datadir = OMAP_MMC_DATADIR_NONE;
 		OMAP_HSMMC_WRITE(host->base, BLK, 0);
 		return 0;
 	}
@@ -748,9 +796,6 @@
 					| (req->data->blocks << 16));
 	set_data_timeout(host, req);
 
-	host->datadir = (req->data->flags & MMC_DATA_WRITE) ?
-			OMAP_MMC_DATADIR_WRITE : OMAP_MMC_DATADIR_READ;
-
 	if (host->use_dma) {
 		ret = mmc_omap_start_dma_transfer(host, req);
 		if (ret != 0) {
@@ -782,36 +827,29 @@
 	u16 dsor = 0;
 	unsigned long regval;
 	unsigned long timeout;
+	u32 con;
 
 	switch (ios->power_mode) {
 	case MMC_POWER_OFF:
 		mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0);
-		/*
-		 * Reset interface voltage to 3V if it's 1.8V now;
-		 * only relevant on MMC-1, the others always use 1.8V.
-		 *
-		 * REVISIT: If we are able to detect cards after unplugging
-		 * a 1.8V card, this code should not be needed.
-		 */
-		if (host->id != OMAP_MMC1_DEVID)
-			break;
-		if (!(OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET)) {
-			int vdd = fls(host->mmc->ocr_avail) - 1;
-			if (omap_mmc_switch_opcond(host, vdd) != 0)
-				host->mmc->ios.vdd = vdd;
-		}
 		break;
 	case MMC_POWER_UP:
 		mmc_slot(host).set_power(host->dev, host->slot_id, 1, ios->vdd);
 		break;
 	}
 
+	con = OMAP_HSMMC_READ(host->base, CON);
 	switch (mmc->ios.bus_width) {
+	case MMC_BUS_WIDTH_8:
+		OMAP_HSMMC_WRITE(host->base, CON, con | DW8);
+		break;
 	case MMC_BUS_WIDTH_4:
+		OMAP_HSMMC_WRITE(host->base, CON, con & ~DW8);
 		OMAP_HSMMC_WRITE(host->base, HCTL,
 			OMAP_HSMMC_READ(host->base, HCTL) | FOUR_BIT);
 		break;
 	case MMC_BUS_WIDTH_1:
+		OMAP_HSMMC_WRITE(host->base, CON, con & ~DW8);
 		OMAP_HSMMC_WRITE(host->base, HCTL,
 			OMAP_HSMMC_READ(host->base, HCTL) & ~FOUR_BIT);
 		break;
@@ -891,6 +929,33 @@
 	return pdata->slots[0].get_ro(host->dev, 0);
 }
 
+static void omap_hsmmc_init(struct mmc_omap_host *host)
+{
+	u32 hctl, capa, value;
+
+	/* Only MMC1 supports 3.0V */
+	if (host->id == OMAP_MMC1_DEVID) {
+		hctl = SDVS30;
+		capa = VS30 | VS18;
+	} else {
+		hctl = SDVS18;
+		capa = VS18;
+	}
+
+	value = OMAP_HSMMC_READ(host->base, HCTL) & ~SDVS_MASK;
+	OMAP_HSMMC_WRITE(host->base, HCTL, value | hctl);
+
+	value = OMAP_HSMMC_READ(host->base, CAPA);
+	OMAP_HSMMC_WRITE(host->base, CAPA, value | capa);
+
+	/* Set the controller to AUTO IDLE mode */
+	value = OMAP_HSMMC_READ(host->base, SYSCONFIG);
+	OMAP_HSMMC_WRITE(host->base, SYSCONFIG, value | AUTOIDLE);
+
+	/* Set SD bus power bit */
+	set_sd_bus_power(host);
+}
+
 static struct mmc_host_ops mmc_omap_ops = {
 	.request = omap_mmc_request,
 	.set_ios = omap_mmc_set_ios,
@@ -906,7 +971,6 @@
 	struct mmc_omap_host *host = NULL;
 	struct resource *res;
 	int ret = 0, irq;
-	u32 hctl, capa;
 
 	if (pdata == NULL) {
 		dev_err(&pdev->dev, "Platform Data is missing\n");
@@ -996,10 +1060,11 @@
 		else
 			host->dbclk_enabled = 1;
 
-#ifdef CONFIG_MMC_BLOCK_BOUNCE
-	mmc->max_phys_segs = 1;
-	mmc->max_hw_segs = 1;
-#endif
+	/* Since we do only SG emulation, we can have as many segs
+	 * as we want. */
+	mmc->max_phys_segs = 1024;
+	mmc->max_hw_segs = 1024;
+
 	mmc->max_blk_size = 512;       /* Block Length at max can be 1024 */
 	mmc->max_blk_count = 0xFFFF;    /* No. of Blocks is 16 bits */
 	mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
@@ -1008,32 +1073,32 @@
 	mmc->ocr_avail = mmc_slot(host).ocr_mask;
 	mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED;
 
-	if (pdata->slots[host->slot_id].wires >= 4)
+	if (pdata->slots[host->slot_id].wires >= 8)
+		mmc->caps |= MMC_CAP_8_BIT_DATA;
+	else if (pdata->slots[host->slot_id].wires >= 4)
 		mmc->caps |= MMC_CAP_4_BIT_DATA;
 
-	/* Only MMC1 supports 3.0V */
-	if (host->id == OMAP_MMC1_DEVID) {
-		hctl = SDVS30;
-		capa = VS30 | VS18;
-	} else {
-		hctl = SDVS18;
-		capa = VS18;
+	omap_hsmmc_init(host);
+
+	/* Select DMA lines */
+	switch (host->id) {
+	case OMAP_MMC1_DEVID:
+		host->dma_line_tx = OMAP24XX_DMA_MMC1_TX;
+		host->dma_line_rx = OMAP24XX_DMA_MMC1_RX;
+		break;
+	case OMAP_MMC2_DEVID:
+		host->dma_line_tx = OMAP24XX_DMA_MMC2_TX;
+		host->dma_line_rx = OMAP24XX_DMA_MMC2_RX;
+		break;
+	case OMAP_MMC3_DEVID:
+		host->dma_line_tx = OMAP34XX_DMA_MMC3_TX;
+		host->dma_line_rx = OMAP34XX_DMA_MMC3_RX;
+		break;
+	default:
+		dev_err(mmc_dev(host->mmc), "Invalid MMC id\n");
+		goto err_irq;
 	}
 
-	OMAP_HSMMC_WRITE(host->base, HCTL,
-			OMAP_HSMMC_READ(host->base, HCTL) | hctl);
-
-	OMAP_HSMMC_WRITE(host->base, CAPA,
-			OMAP_HSMMC_READ(host->base, CAPA) | capa);
-
-	/* Set the controller to AUTO IDLE mode */
-	OMAP_HSMMC_WRITE(host->base, SYSCONFIG,
-			OMAP_HSMMC_READ(host->base, SYSCONFIG) | AUTOIDLE);
-
-	/* Set SD bus power bit */
-	OMAP_HSMMC_WRITE(host->base, HCTL,
-			OMAP_HSMMC_READ(host->base, HCTL) | SDBP);
-
 	/* Request IRQ for MMC operations */
 	ret = request_irq(host->irq, mmc_omap_irq, IRQF_DISABLED,
 			mmc_hostname(mmc), host);
@@ -1051,7 +1116,7 @@
 	}
 
 	/* Request IRQ for card detect */
-	if ((mmc_slot(host).card_detect_irq) && (mmc_slot(host).card_detect)) {
+	if ((mmc_slot(host).card_detect_irq)) {
 		ret = request_irq(mmc_slot(host).card_detect_irq,
 				  omap_mmc_cd_handler,
 				  IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
@@ -1074,8 +1139,8 @@
 		if (ret < 0)
 			goto err_slot_name;
 	}
-	if (mmc_slot(host).card_detect_irq && mmc_slot(host).card_detect &&
-			host->pdata->slots[host->slot_id].get_cover_state) {
+	if (mmc_slot(host).card_detect_irq &&
+	    host->pdata->slots[host->slot_id].get_cover_state) {
 		ret = device_create_file(&mmc->class_dev,
 					&dev_attr_cover_switch);
 		if (ret < 0)
@@ -1173,20 +1238,8 @@
 						" level suspend\n");
 			}
 
-			if (host->id == OMAP_MMC1_DEVID
-					&& !(OMAP_HSMMC_READ(host->base, HCTL)
-							& SDVSDET)) {
-				OMAP_HSMMC_WRITE(host->base, HCTL,
-					OMAP_HSMMC_READ(host->base, HCTL)
-					& SDVSCLR);
-				OMAP_HSMMC_WRITE(host->base, HCTL,
-					OMAP_HSMMC_READ(host->base, HCTL)
-					| SDVS30);
-				OMAP_HSMMC_WRITE(host->base, HCTL,
-					OMAP_HSMMC_READ(host->base, HCTL)
-					| SDBP);
-			}
-
+			OMAP_HSMMC_WRITE(host->base, HCTL,
+					 OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP);
 			clk_disable(host->fclk);
 			clk_disable(host->iclk);
 			clk_disable(host->dbclk);
@@ -1222,6 +1275,8 @@
 			dev_dbg(mmc_dev(host->mmc),
 					"Enabling debounce clk failed\n");
 
+		omap_hsmmc_init(host);
+
 		if (host->pdata->resume) {
 			ret = host->pdata->resume(&pdev->dev, host->slot_id);
 			if (ret)
diff --git a/drivers/mmc/host/sdhci-of.c b/drivers/mmc/host/sdhci-of.c
new file mode 100644
index 0000000..3ff4ac3
--- /dev/null
+++ b/drivers/mmc/host/sdhci-of.c
@@ -0,0 +1,309 @@
+/*
+ * OpenFirmware bindings for Secure Digital Host Controller Interface.
+ *
+ * Copyright (c) 2007 Freescale Semiconductor, Inc.
+ * Copyright (c) 2009 MontaVista Software, Inc.
+ *
+ * Authors: Xiaobo Xie <X.Xie@freescale.com>
+ *	    Anton Vorontsov <avorontsov@ru.mvista.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/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/mmc/host.h>
+#include "sdhci.h"
+
+struct sdhci_of_data {
+	unsigned int quirks;
+	struct sdhci_ops ops;
+};
+
+struct sdhci_of_host {
+	unsigned int clock;
+	u16 xfer_mode_shadow;
+};
+
+/*
+ * Ops and quirks for the Freescale eSDHC controller.
+ */
+
+#define ESDHC_DMA_SYSCTL	0x40c
+#define ESDHC_DMA_SNOOP		0x00000040
+
+#define ESDHC_SYSTEM_CONTROL	0x2c
+#define ESDHC_CLOCK_MASK	0x0000fff0
+#define ESDHC_PREDIV_SHIFT	8
+#define ESDHC_DIVIDER_SHIFT	4
+#define ESDHC_CLOCK_PEREN	0x00000004
+#define ESDHC_CLOCK_HCKEN	0x00000002
+#define ESDHC_CLOCK_IPGEN	0x00000001
+
+static u32 esdhc_readl(struct sdhci_host *host, int reg)
+{
+	return in_be32(host->ioaddr + reg);
+}
+
+static u16 esdhc_readw(struct sdhci_host *host, int reg)
+{
+	return in_be16(host->ioaddr + (reg ^ 0x2));
+}
+
+static u8 esdhc_readb(struct sdhci_host *host, int reg)
+{
+	return in_8(host->ioaddr + (reg ^ 0x3));
+}
+
+static void esdhc_writel(struct sdhci_host *host, u32 val, int reg)
+{
+	out_be32(host->ioaddr + reg, val);
+}
+
+static void esdhc_writew(struct sdhci_host *host, u16 val, int reg)
+{
+	struct sdhci_of_host *of_host = sdhci_priv(host);
+	int base = reg & ~0x3;
+	int shift = (reg & 0x2) * 8;
+
+	switch (reg) {
+	case SDHCI_TRANSFER_MODE:
+		/*
+		 * Postpone this write, we must do it together with a
+		 * command write that is down below.
+		 */
+		of_host->xfer_mode_shadow = val;
+		return;
+	case SDHCI_COMMAND:
+		esdhc_writel(host, val << 16 | of_host->xfer_mode_shadow,
+			     SDHCI_TRANSFER_MODE);
+		return;
+	case SDHCI_BLOCK_SIZE:
+		/*
+		 * Two last DMA bits are reserved, and first one is used for
+		 * non-standard blksz of 4096 bytes that we don't support
+		 * yet. So clear the DMA boundary bits.
+		 */
+		val &= ~SDHCI_MAKE_BLKSZ(0x7, 0);
+		/* fall through */
+	}
+	clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift);
+}
+
+static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg)
+{
+	int base = reg & ~0x3;
+	int shift = (reg & 0x3) * 8;
+
+	clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift);
+}
+
+static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
+{
+	int div;
+	int pre_div = 2;
+
+	clrbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN |
+		  ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK);
+
+	if (clock == 0)
+		goto out;
+
+	if (host->max_clk / 16 > clock) {
+		for (; pre_div < 256; pre_div *= 2) {
+			if (host->max_clk / pre_div < clock * 16)
+				break;
+		}
+	}
+
+	for (div = 1; div <= 16; div++) {
+		if (host->max_clk / (div * pre_div) <= clock)
+			break;
+	}
+
+	pre_div >>= 1;
+
+	setbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN |
+		  ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN |
+		  div << ESDHC_DIVIDER_SHIFT | pre_div << ESDHC_PREDIV_SHIFT);
+	mdelay(100);
+out:
+	host->clock = clock;
+}
+
+static int esdhc_enable_dma(struct sdhci_host *host)
+{
+	setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP);
+	return 0;
+}
+
+static unsigned int esdhc_get_max_clock(struct sdhci_host *host)
+{
+	struct sdhci_of_host *of_host = sdhci_priv(host);
+
+	return of_host->clock;
+}
+
+static unsigned int esdhc_get_timeout_clock(struct sdhci_host *host)
+{
+	struct sdhci_of_host *of_host = sdhci_priv(host);
+
+	return of_host->clock / 1000;
+}
+
+static struct sdhci_of_data sdhci_esdhc = {
+	.quirks = SDHCI_QUIRK_FORCE_BLK_SZ_2048 |
+		  SDHCI_QUIRK_BROKEN_CARD_DETECTION |
+		  SDHCI_QUIRK_INVERTED_WRITE_PROTECT |
+		  SDHCI_QUIRK_NO_BUSY_IRQ |
+		  SDHCI_QUIRK_NONSTANDARD_CLOCK |
+		  SDHCI_QUIRK_PIO_NEEDS_DELAY |
+		  SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET |
+		  SDHCI_QUIRK_NO_CARD_NO_RESET,
+	.ops = {
+		.readl = esdhc_readl,
+		.readw = esdhc_readw,
+		.readb = esdhc_readb,
+		.writel = esdhc_writel,
+		.writew = esdhc_writew,
+		.writeb = esdhc_writeb,
+		.set_clock = esdhc_set_clock,
+		.enable_dma = esdhc_enable_dma,
+		.get_max_clock = esdhc_get_max_clock,
+		.get_timeout_clock = esdhc_get_timeout_clock,
+	},
+};
+
+#ifdef CONFIG_PM
+
+static int sdhci_of_suspend(struct of_device *ofdev, pm_message_t state)
+{
+	struct sdhci_host *host = dev_get_drvdata(&ofdev->dev);
+
+	return mmc_suspend_host(host->mmc, state);
+}
+
+static int sdhci_of_resume(struct of_device *ofdev)
+{
+	struct sdhci_host *host = dev_get_drvdata(&ofdev->dev);
+
+	return mmc_resume_host(host->mmc);
+}
+
+#else
+
+#define sdhci_of_suspend NULL
+#define sdhci_of_resume NULL
+
+#endif
+
+static int __devinit sdhci_of_probe(struct of_device *ofdev,
+				 const struct of_device_id *match)
+{
+	struct device_node *np = ofdev->node;
+	struct sdhci_of_data *sdhci_of_data = match->data;
+	struct sdhci_host *host;
+	struct sdhci_of_host *of_host;
+	const u32 *clk;
+	int size;
+	int ret;
+
+	if (!of_device_is_available(np))
+		return -ENODEV;
+
+	host = sdhci_alloc_host(&ofdev->dev, sizeof(*of_host));
+	if (!host)
+		return -ENOMEM;
+
+	of_host = sdhci_priv(host);
+	dev_set_drvdata(&ofdev->dev, host);
+
+	host->ioaddr = of_iomap(np, 0);
+	if (!host->ioaddr) {
+		ret = -ENOMEM;
+		goto err_addr_map;
+	}
+
+	host->irq = irq_of_parse_and_map(np, 0);
+	if (!host->irq) {
+		ret = -EINVAL;
+		goto err_no_irq;
+	}
+
+	host->hw_name = dev_name(&ofdev->dev);
+	if (sdhci_of_data) {
+		host->quirks = sdhci_of_data->quirks;
+		host->ops = &sdhci_of_data->ops;
+	}
+
+	clk = of_get_property(np, "clock-frequency", &size);
+	if (clk && size == sizeof(*clk) && *clk)
+		of_host->clock = *clk;
+
+	ret = sdhci_add_host(host);
+	if (ret)
+		goto err_add_host;
+
+	return 0;
+
+err_add_host:
+	irq_dispose_mapping(host->irq);
+err_no_irq:
+	iounmap(host->ioaddr);
+err_addr_map:
+	sdhci_free_host(host);
+	return ret;
+}
+
+static int __devexit sdhci_of_remove(struct of_device *ofdev)
+{
+	struct sdhci_host *host = dev_get_drvdata(&ofdev->dev);
+
+	sdhci_remove_host(host, 0);
+	sdhci_free_host(host);
+	irq_dispose_mapping(host->irq);
+	iounmap(host->ioaddr);
+	return 0;
+}
+
+static const struct of_device_id sdhci_of_match[] = {
+	{ .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc, },
+	{ .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc, },
+	{ .compatible = "generic-sdhci", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, sdhci_of_match);
+
+static struct of_platform_driver sdhci_of_driver = {
+	.driver.name = "sdhci-of",
+	.match_table = sdhci_of_match,
+	.probe = sdhci_of_probe,
+	.remove = __devexit_p(sdhci_of_remove),
+	.suspend = sdhci_of_suspend,
+	.resume	= sdhci_of_resume,
+};
+
+static int __init sdhci_of_init(void)
+{
+	return of_register_platform_driver(&sdhci_of_driver);
+}
+module_init(sdhci_of_init);
+
+static void __exit sdhci_of_exit(void)
+{
+	of_unregister_platform_driver(&sdhci_of_driver);
+}
+module_exit(sdhci_of_exit);
+
+MODULE_DESCRIPTION("Secure Digital Host Controller Interface OF driver");
+MODULE_AUTHOR("Xiaobo Xie <X.Xie@freescale.com>, "
+	      "Anton Vorontsov <avorontsov@ru.mvista.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index accb592..30d8e3d 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -48,35 +48,35 @@
 	printk(KERN_DEBUG DRIVER_NAME ": ============== REGISTER DUMP ==============\n");
 
 	printk(KERN_DEBUG DRIVER_NAME ": Sys addr: 0x%08x | Version:  0x%08x\n",
-		readl(host->ioaddr + SDHCI_DMA_ADDRESS),
-		readw(host->ioaddr + SDHCI_HOST_VERSION));
+		sdhci_readl(host, SDHCI_DMA_ADDRESS),
+		sdhci_readw(host, SDHCI_HOST_VERSION));
 	printk(KERN_DEBUG DRIVER_NAME ": Blk size: 0x%08x | Blk cnt:  0x%08x\n",
-		readw(host->ioaddr + SDHCI_BLOCK_SIZE),
-		readw(host->ioaddr + SDHCI_BLOCK_COUNT));
+		sdhci_readw(host, SDHCI_BLOCK_SIZE),
+		sdhci_readw(host, SDHCI_BLOCK_COUNT));
 	printk(KERN_DEBUG DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n",
-		readl(host->ioaddr + SDHCI_ARGUMENT),
-		readw(host->ioaddr + SDHCI_TRANSFER_MODE));
+		sdhci_readl(host, SDHCI_ARGUMENT),
+		sdhci_readw(host, SDHCI_TRANSFER_MODE));
 	printk(KERN_DEBUG DRIVER_NAME ": Present:  0x%08x | Host ctl: 0x%08x\n",
-		readl(host->ioaddr + SDHCI_PRESENT_STATE),
-		readb(host->ioaddr + SDHCI_HOST_CONTROL));
+		sdhci_readl(host, SDHCI_PRESENT_STATE),
+		sdhci_readb(host, SDHCI_HOST_CONTROL));
 	printk(KERN_DEBUG DRIVER_NAME ": Power:    0x%08x | Blk gap:  0x%08x\n",
-		readb(host->ioaddr + SDHCI_POWER_CONTROL),
-		readb(host->ioaddr + SDHCI_BLOCK_GAP_CONTROL));
+		sdhci_readb(host, SDHCI_POWER_CONTROL),
+		sdhci_readb(host, SDHCI_BLOCK_GAP_CONTROL));
 	printk(KERN_DEBUG DRIVER_NAME ": Wake-up:  0x%08x | Clock:    0x%08x\n",
-		readb(host->ioaddr + SDHCI_WAKE_UP_CONTROL),
-		readw(host->ioaddr + SDHCI_CLOCK_CONTROL));
+		sdhci_readb(host, SDHCI_WAKE_UP_CONTROL),
+		sdhci_readw(host, SDHCI_CLOCK_CONTROL));
 	printk(KERN_DEBUG DRIVER_NAME ": Timeout:  0x%08x | Int stat: 0x%08x\n",
-		readb(host->ioaddr + SDHCI_TIMEOUT_CONTROL),
-		readl(host->ioaddr + SDHCI_INT_STATUS));
+		sdhci_readb(host, SDHCI_TIMEOUT_CONTROL),
+		sdhci_readl(host, SDHCI_INT_STATUS));
 	printk(KERN_DEBUG DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n",
-		readl(host->ioaddr + SDHCI_INT_ENABLE),
-		readl(host->ioaddr + SDHCI_SIGNAL_ENABLE));
+		sdhci_readl(host, SDHCI_INT_ENABLE),
+		sdhci_readl(host, SDHCI_SIGNAL_ENABLE));
 	printk(KERN_DEBUG DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n",
-		readw(host->ioaddr + SDHCI_ACMD12_ERR),
-		readw(host->ioaddr + SDHCI_SLOT_INT_STATUS));
+		sdhci_readw(host, SDHCI_ACMD12_ERR),
+		sdhci_readw(host, SDHCI_SLOT_INT_STATUS));
 	printk(KERN_DEBUG DRIVER_NAME ": Caps:     0x%08x | Max curr: 0x%08x\n",
-		readl(host->ioaddr + SDHCI_CAPABILITIES),
-		readl(host->ioaddr + SDHCI_MAX_CURRENT));
+		sdhci_readl(host, SDHCI_CAPABILITIES),
+		sdhci_readl(host, SDHCI_MAX_CURRENT));
 
 	printk(KERN_DEBUG DRIVER_NAME ": ===========================================\n");
 }
@@ -87,17 +87,65 @@
  *                                                                           *
 \*****************************************************************************/
 
+static void sdhci_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set)
+{
+	u32 ier;
+
+	ier = sdhci_readl(host, SDHCI_INT_ENABLE);
+	ier &= ~clear;
+	ier |= set;
+	sdhci_writel(host, ier, SDHCI_INT_ENABLE);
+	sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE);
+}
+
+static void sdhci_unmask_irqs(struct sdhci_host *host, u32 irqs)
+{
+	sdhci_clear_set_irqs(host, 0, irqs);
+}
+
+static void sdhci_mask_irqs(struct sdhci_host *host, u32 irqs)
+{
+	sdhci_clear_set_irqs(host, irqs, 0);
+}
+
+static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
+{
+	u32 irqs = SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT;
+
+	if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
+		return;
+
+	if (enable)
+		sdhci_unmask_irqs(host, irqs);
+	else
+		sdhci_mask_irqs(host, irqs);
+}
+
+static void sdhci_enable_card_detection(struct sdhci_host *host)
+{
+	sdhci_set_card_detection(host, true);
+}
+
+static void sdhci_disable_card_detection(struct sdhci_host *host)
+{
+	sdhci_set_card_detection(host, false);
+}
+
 static void sdhci_reset(struct sdhci_host *host, u8 mask)
 {
 	unsigned long timeout;
+	u32 uninitialized_var(ier);
 
 	if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
-		if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) &
+		if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) &
 			SDHCI_CARD_PRESENT))
 			return;
 	}
 
-	writeb(mask, host->ioaddr + SDHCI_SOFTWARE_RESET);
+	if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
+		ier = sdhci_readl(host, SDHCI_INT_ENABLE);
+
+	sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
 
 	if (mask & SDHCI_RESET_ALL)
 		host->clock = 0;
@@ -106,7 +154,7 @@
 	timeout = 100;
 
 	/* hw clears the bit when it's done */
-	while (readb(host->ioaddr + SDHCI_SOFTWARE_RESET) & mask) {
+	while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) {
 		if (timeout == 0) {
 			printk(KERN_ERR "%s: Reset 0x%x never completed.\n",
 				mmc_hostname(host->mmc), (int)mask);
@@ -116,42 +164,44 @@
 		timeout--;
 		mdelay(1);
 	}
+
+	if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
+		sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier);
 }
 
 static void sdhci_init(struct sdhci_host *host)
 {
-	u32 intmask;
-
 	sdhci_reset(host, SDHCI_RESET_ALL);
 
-	intmask = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
+	sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK,
+		SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
 		SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX |
 		SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT |
-		SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT |
-		SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL |
-		SDHCI_INT_DMA_END | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE |
-		SDHCI_INT_ADMA_ERROR;
+		SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE);
+}
 
-	writel(intmask, host->ioaddr + SDHCI_INT_ENABLE);
-	writel(intmask, host->ioaddr + SDHCI_SIGNAL_ENABLE);
+static void sdhci_reinit(struct sdhci_host *host)
+{
+	sdhci_init(host);
+	sdhci_enable_card_detection(host);
 }
 
 static void sdhci_activate_led(struct sdhci_host *host)
 {
 	u8 ctrl;
 
-	ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
 	ctrl |= SDHCI_CTRL_LED;
-	writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 }
 
 static void sdhci_deactivate_led(struct sdhci_host *host)
 {
 	u8 ctrl;
 
-	ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
 	ctrl &= ~SDHCI_CTRL_LED;
-	writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 }
 
 #ifdef SDHCI_USE_LEDS_CLASS
@@ -205,7 +255,7 @@
 
 		while (len) {
 			if (chunk == 0) {
-				scratch = readl(host->ioaddr + SDHCI_BUFFER);
+				scratch = sdhci_readl(host, SDHCI_BUFFER);
 				chunk = 4;
 			}
 
@@ -257,7 +307,7 @@
 			len--;
 
 			if ((chunk == 4) || ((len == 0) && (blksize == 0))) {
-				writel(scratch, host->ioaddr + SDHCI_BUFFER);
+				sdhci_writel(host, scratch, SDHCI_BUFFER);
 				chunk = 0;
 				scratch = 0;
 			}
@@ -292,7 +342,10 @@
 		(host->data->blocks == 1))
 		mask = ~0;
 
-	while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) {
+	while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
+		if (host->quirks & SDHCI_QUIRK_PIO_NEEDS_DELAY)
+			udelay(100);
+
 		if (host->data->flags & MMC_DATA_READ)
 			sdhci_read_block_pio(host);
 		else
@@ -561,6 +614,17 @@
 	return count;
 }
 
+static void sdhci_set_transfer_irqs(struct sdhci_host *host)
+{
+	u32 pio_irqs = SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL;
+	u32 dma_irqs = SDHCI_INT_DMA_END | SDHCI_INT_ADMA_ERROR;
+
+	if (host->flags & SDHCI_REQ_USE_DMA)
+		sdhci_clear_set_irqs(host, pio_irqs, dma_irqs);
+	else
+		sdhci_clear_set_irqs(host, dma_irqs, pio_irqs);
+}
+
 static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
 {
 	u8 count;
@@ -581,7 +645,7 @@
 	host->data_early = 0;
 
 	count = sdhci_calc_timeout(host, data);
-	writeb(count, host->ioaddr + SDHCI_TIMEOUT_CONTROL);
+	sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
 
 	if (host->flags & SDHCI_USE_DMA)
 		host->flags |= SDHCI_REQ_USE_DMA;
@@ -661,8 +725,8 @@
 				WARN_ON(1);
 				host->flags &= ~SDHCI_REQ_USE_DMA;
 			} else {
-				writel(host->adma_addr,
-					host->ioaddr + SDHCI_ADMA_ADDRESS);
+				sdhci_writel(host, host->adma_addr,
+					SDHCI_ADMA_ADDRESS);
 			}
 		} else {
 			int sg_cnt;
@@ -681,8 +745,8 @@
 				host->flags &= ~SDHCI_REQ_USE_DMA;
 			} else {
 				WARN_ON(sg_cnt != 1);
-				writel(sg_dma_address(data->sg),
-					host->ioaddr + SDHCI_DMA_ADDRESS);
+				sdhci_writel(host, sg_dma_address(data->sg),
+					SDHCI_DMA_ADDRESS);
 			}
 		}
 	}
@@ -693,14 +757,14 @@
 	 * is ADMA.
 	 */
 	if (host->version >= SDHCI_SPEC_200) {
-		ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+		ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
 		ctrl &= ~SDHCI_CTRL_DMA_MASK;
 		if ((host->flags & SDHCI_REQ_USE_DMA) &&
 			(host->flags & SDHCI_USE_ADMA))
 			ctrl |= SDHCI_CTRL_ADMA32;
 		else
 			ctrl |= SDHCI_CTRL_SDMA;
-		writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 	}
 
 	if (!(host->flags & SDHCI_REQ_USE_DMA)) {
@@ -709,10 +773,11 @@
 		host->blocks = data->blocks;
 	}
 
+	sdhci_set_transfer_irqs(host);
+
 	/* We do not handle DMA boundaries, so set it to max (512 KiB) */
-	writew(SDHCI_MAKE_BLKSZ(7, data->blksz),
-		host->ioaddr + SDHCI_BLOCK_SIZE);
-	writew(data->blocks, host->ioaddr + SDHCI_BLOCK_COUNT);
+	sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, data->blksz), SDHCI_BLOCK_SIZE);
+	sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
 }
 
 static void sdhci_set_transfer_mode(struct sdhci_host *host,
@@ -733,7 +798,7 @@
 	if (host->flags & SDHCI_REQ_USE_DMA)
 		mode |= SDHCI_TRNS_DMA;
 
-	writew(mode, host->ioaddr + SDHCI_TRANSFER_MODE);
+	sdhci_writew(host, mode, SDHCI_TRANSFER_MODE);
 }
 
 static void sdhci_finish_data(struct sdhci_host *host)
@@ -802,7 +867,7 @@
 	if (host->mrq->data && (cmd == host->mrq->data->stop))
 		mask &= ~SDHCI_DATA_INHIBIT;
 
-	while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) {
+	while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
 		if (timeout == 0) {
 			printk(KERN_ERR "%s: Controller never released "
 				"inhibit bit(s).\n", mmc_hostname(host->mmc));
@@ -821,7 +886,7 @@
 
 	sdhci_prepare_data(host, cmd->data);
 
-	writel(cmd->arg, host->ioaddr + SDHCI_ARGUMENT);
+	sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT);
 
 	sdhci_set_transfer_mode(host, cmd->data);
 
@@ -849,8 +914,7 @@
 	if (cmd->data)
 		flags |= SDHCI_CMD_DATA;
 
-	writew(SDHCI_MAKE_CMD(cmd->opcode, flags),
-		host->ioaddr + SDHCI_COMMAND);
+	sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND);
 }
 
 static void sdhci_finish_command(struct sdhci_host *host)
@@ -863,15 +927,15 @@
 		if (host->cmd->flags & MMC_RSP_136) {
 			/* CRC is stripped so we need to do some shifting. */
 			for (i = 0;i < 4;i++) {
-				host->cmd->resp[i] = readl(host->ioaddr +
+				host->cmd->resp[i] = sdhci_readl(host,
 					SDHCI_RESPONSE + (3-i)*4) << 8;
 				if (i != 3)
 					host->cmd->resp[i] |=
-						readb(host->ioaddr +
+						sdhci_readb(host,
 						SDHCI_RESPONSE + (3-i)*4-1);
 			}
 		} else {
-			host->cmd->resp[0] = readl(host->ioaddr + SDHCI_RESPONSE);
+			host->cmd->resp[0] = sdhci_readl(host, SDHCI_RESPONSE);
 		}
 	}
 
@@ -895,7 +959,13 @@
 	if (clock == host->clock)
 		return;
 
-	writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);
+	if (host->ops->set_clock) {
+		host->ops->set_clock(host, clock);
+		if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK)
+			return;
+	}
+
+	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
 
 	if (clock == 0)
 		goto out;
@@ -908,11 +978,11 @@
 
 	clk = div << SDHCI_DIVIDER_SHIFT;
 	clk |= SDHCI_CLOCK_INT_EN;
-	writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL);
+	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
 
 	/* Wait max 10 ms */
 	timeout = 10;
-	while (!((clk = readw(host->ioaddr + SDHCI_CLOCK_CONTROL))
+	while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
 		& SDHCI_CLOCK_INT_STABLE)) {
 		if (timeout == 0) {
 			printk(KERN_ERR "%s: Internal clock never "
@@ -925,7 +995,7 @@
 	}
 
 	clk |= SDHCI_CLOCK_CARD_EN;
-	writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL);
+	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
 
 out:
 	host->clock = clock;
@@ -939,7 +1009,7 @@
 		return;
 
 	if (power == (unsigned short)-1) {
-		writeb(0, host->ioaddr + SDHCI_POWER_CONTROL);
+		sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
 		goto out;
 	}
 
@@ -948,7 +1018,7 @@
 	 * a new value. Some controllers don't seem to like this though.
 	 */
 	if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
-		writeb(0, host->ioaddr + SDHCI_POWER_CONTROL);
+		sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
 
 	pwr = SDHCI_POWER_ON;
 
@@ -973,10 +1043,9 @@
 	 * and set turn on power at the same time, so set the voltage first.
 	 */
 	if ((host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER))
-		writeb(pwr & ~SDHCI_POWER_ON,
-				host->ioaddr + SDHCI_POWER_CONTROL);
+		sdhci_writeb(host, pwr & ~SDHCI_POWER_ON, SDHCI_POWER_CONTROL);
 
-	writeb(pwr, host->ioaddr + SDHCI_POWER_CONTROL);
+	sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
 
 out:
 	host->power = power;
@@ -991,6 +1060,7 @@
 static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 {
 	struct sdhci_host *host;
+	bool present;
 	unsigned long flags;
 
 	host = mmc_priv(mmc);
@@ -1005,8 +1075,14 @@
 
 	host->mrq = mrq;
 
-	if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)
-		|| (host->flags & SDHCI_DEVICE_DEAD)) {
+	/* If polling, assume that the card is always present. */
+	if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
+		present = true;
+	else
+		present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
+				SDHCI_CARD_PRESENT;
+
+	if (!present || host->flags & SDHCI_DEVICE_DEAD) {
 		host->mrq->cmd->error = -ENOMEDIUM;
 		tasklet_schedule(&host->finish_tasklet);
 	} else
@@ -1034,8 +1110,8 @@
 	 * Should clear out any weird states.
 	 */
 	if (ios->power_mode == MMC_POWER_OFF) {
-		writel(0, host->ioaddr + SDHCI_SIGNAL_ENABLE);
-		sdhci_init(host);
+		sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
+		sdhci_reinit(host);
 	}
 
 	sdhci_set_clock(host, ios->clock);
@@ -1045,7 +1121,7 @@
 	else
 		sdhci_set_power(host, ios->vdd);
 
-	ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
 
 	if (ios->bus_width == MMC_BUS_WIDTH_4)
 		ctrl |= SDHCI_CTRL_4BITBUS;
@@ -1057,7 +1133,7 @@
 	else
 		ctrl &= ~SDHCI_CTRL_HISPD;
 
-	writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 
 	/*
 	 * Some (ENE) controllers go apeshit on some ios operation,
@@ -1085,10 +1161,12 @@
 	if (host->flags & SDHCI_DEVICE_DEAD)
 		present = 0;
 	else
-		present = readl(host->ioaddr + SDHCI_PRESENT_STATE);
+		present = sdhci_readl(host, SDHCI_PRESENT_STATE);
 
 	spin_unlock_irqrestore(&host->lock, flags);
 
+	if (host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT)
+		return !!(present & SDHCI_WRITE_PROTECT);
 	return !(present & SDHCI_WRITE_PROTECT);
 }
 
@@ -1096,7 +1174,6 @@
 {
 	struct sdhci_host *host;
 	unsigned long flags;
-	u32 ier;
 
 	host = mmc_priv(mmc);
 
@@ -1105,15 +1182,10 @@
 	if (host->flags & SDHCI_DEVICE_DEAD)
 		goto out;
 
-	ier = readl(host->ioaddr + SDHCI_INT_ENABLE);
-
-	ier &= ~SDHCI_INT_CARD_INT;
 	if (enable)
-		ier |= SDHCI_INT_CARD_INT;
-
-	writel(ier, host->ioaddr + SDHCI_INT_ENABLE);
-	writel(ier, host->ioaddr + SDHCI_SIGNAL_ENABLE);
-
+		sdhci_unmask_irqs(host, SDHCI_INT_CARD_INT);
+	else
+		sdhci_mask_irqs(host, SDHCI_INT_CARD_INT);
 out:
 	mmiowb();
 
@@ -1142,7 +1214,7 @@
 
 	spin_lock_irqsave(&host->lock, flags);
 
-	if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
+	if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
 		if (host->mrq) {
 			printk(KERN_ERR "%s: Card removed during transfer!\n",
 				mmc_hostname(host->mmc));
@@ -1346,8 +1418,8 @@
 		 * we need to at least restart the transfer.
 		 */
 		if (intmask & SDHCI_INT_DMA_END)
-			writel(readl(host->ioaddr + SDHCI_DMA_ADDRESS),
-				host->ioaddr + SDHCI_DMA_ADDRESS);
+			sdhci_writel(host, sdhci_readl(host, SDHCI_DMA_ADDRESS),
+				SDHCI_DMA_ADDRESS);
 
 		if (intmask & SDHCI_INT_DATA_END) {
 			if (host->cmd) {
@@ -1373,7 +1445,7 @@
 
 	spin_lock(&host->lock);
 
-	intmask = readl(host->ioaddr + SDHCI_INT_STATUS);
+	intmask = sdhci_readl(host, SDHCI_INT_STATUS);
 
 	if (!intmask || intmask == 0xffffffff) {
 		result = IRQ_NONE;
@@ -1384,22 +1456,22 @@
 		mmc_hostname(host->mmc), intmask);
 
 	if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
-		writel(intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE),
-			host->ioaddr + SDHCI_INT_STATUS);
+		sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
+			SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
 		tasklet_schedule(&host->card_tasklet);
 	}
 
 	intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
 
 	if (intmask & SDHCI_INT_CMD_MASK) {
-		writel(intmask & SDHCI_INT_CMD_MASK,
-			host->ioaddr + SDHCI_INT_STATUS);
+		sdhci_writel(host, intmask & SDHCI_INT_CMD_MASK,
+			SDHCI_INT_STATUS);
 		sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
 	}
 
 	if (intmask & SDHCI_INT_DATA_MASK) {
-		writel(intmask & SDHCI_INT_DATA_MASK,
-			host->ioaddr + SDHCI_INT_STATUS);
+		sdhci_writel(host, intmask & SDHCI_INT_DATA_MASK,
+			SDHCI_INT_STATUS);
 		sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
 	}
 
@@ -1410,7 +1482,7 @@
 	if (intmask & SDHCI_INT_BUS_POWER) {
 		printk(KERN_ERR "%s: Card is consuming too much power!\n",
 			mmc_hostname(host->mmc));
-		writel(SDHCI_INT_BUS_POWER, host->ioaddr + SDHCI_INT_STATUS);
+		sdhci_writel(host, SDHCI_INT_BUS_POWER, SDHCI_INT_STATUS);
 	}
 
 	intmask &= ~SDHCI_INT_BUS_POWER;
@@ -1425,7 +1497,7 @@
 			mmc_hostname(host->mmc), intmask);
 		sdhci_dumpregs(host);
 
-		writel(intmask, host->ioaddr + SDHCI_INT_STATUS);
+		sdhci_writel(host, intmask, SDHCI_INT_STATUS);
 	}
 
 	result = IRQ_HANDLED;
@@ -1455,6 +1527,8 @@
 {
 	int ret;
 
+	sdhci_disable_card_detection(host);
+
 	ret = mmc_suspend_host(host->mmc, state);
 	if (ret)
 		return ret;
@@ -1487,6 +1561,8 @@
 	if (ret)
 		return ret;
 
+	sdhci_enable_card_detection(host);
+
 	return 0;
 }
 
@@ -1537,7 +1613,7 @@
 
 	sdhci_reset(host, SDHCI_RESET_ALL);
 
-	host->version = readw(host->ioaddr + SDHCI_HOST_VERSION);
+	host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
 	host->version = (host->version & SDHCI_SPEC_VER_MASK)
 				>> SDHCI_SPEC_VER_SHIFT;
 	if (host->version > SDHCI_SPEC_200) {
@@ -1546,7 +1622,7 @@
 			host->version);
 	}
 
-	caps = readl(host->ioaddr + SDHCI_CAPABILITIES);
+	caps = sdhci_readl(host, SDHCI_CAPABILITIES);
 
 	if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
 		host->flags |= SDHCI_USE_DMA;
@@ -1614,19 +1690,27 @@
 
 	host->max_clk =
 		(caps & SDHCI_CLOCK_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT;
-	if (host->max_clk == 0) {
-		printk(KERN_ERR "%s: Hardware doesn't specify base clock "
-			"frequency.\n", mmc_hostname(mmc));
-		return -ENODEV;
-	}
 	host->max_clk *= 1000000;
+	if (host->max_clk == 0) {
+		if (!host->ops->get_max_clock) {
+			printk(KERN_ERR
+			       "%s: Hardware doesn't specify base clock "
+			       "frequency.\n", mmc_hostname(mmc));
+			return -ENODEV;
+		}
+		host->max_clk = host->ops->get_max_clock(host);
+	}
 
 	host->timeout_clk =
 		(caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
 	if (host->timeout_clk == 0) {
-		printk(KERN_ERR "%s: Hardware doesn't specify timeout clock "
-			"frequency.\n", mmc_hostname(mmc));
-		return -ENODEV;
+		if (!host->ops->get_timeout_clock) {
+			printk(KERN_ERR
+			       "%s: Hardware doesn't specify timeout clock "
+			       "frequency.\n", mmc_hostname(mmc));
+			return -ENODEV;
+		}
+		host->timeout_clk = host->ops->get_timeout_clock(host);
 	}
 	if (caps & SDHCI_TIMEOUT_CLK_UNIT)
 		host->timeout_clk *= 1000;
@@ -1642,6 +1726,9 @@
 	if (caps & SDHCI_CAN_DO_HISPD)
 		mmc->caps |= MMC_CAP_SD_HIGHSPEED;
 
+	if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
+		mmc->caps |= MMC_CAP_NEEDS_POLL;
+
 	mmc->ocr_avail = 0;
 	if (caps & SDHCI_CAN_VDD_330)
 		mmc->ocr_avail |= MMC_VDD_32_33|MMC_VDD_33_34;
@@ -1690,13 +1777,19 @@
 	 * Maximum block size. This varies from controller to controller and
 	 * is specified in the capabilities register.
 	 */
-	mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT;
-	if (mmc->max_blk_size >= 3) {
-		printk(KERN_WARNING "%s: Invalid maximum block size, "
-			"assuming 512 bytes\n", mmc_hostname(mmc));
-		mmc->max_blk_size = 512;
-	} else
-		mmc->max_blk_size = 512 << mmc->max_blk_size;
+	if (host->quirks & SDHCI_QUIRK_FORCE_BLK_SZ_2048) {
+		mmc->max_blk_size = 2;
+	} else {
+		mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >>
+				SDHCI_MAX_BLOCK_SHIFT;
+		if (mmc->max_blk_size >= 3) {
+			printk(KERN_WARNING "%s: Invalid maximum block size, "
+				"assuming 512 bytes\n", mmc_hostname(mmc));
+			mmc->max_blk_size = 0;
+		}
+	}
+
+	mmc->max_blk_size = 512 << mmc->max_blk_size;
 
 	/*
 	 * Maximum block count.
@@ -1746,6 +1839,8 @@
 		(host->flags & SDHCI_USE_ADMA)?"A":"",
 		(host->flags & SDHCI_USE_DMA)?"DMA":"PIO");
 
+	sdhci_enable_card_detection(host);
+
 	return 0;
 
 #ifdef SDHCI_USE_LEDS_CLASS
@@ -1782,6 +1877,8 @@
 		spin_unlock_irqrestore(&host->lock, flags);
 	}
 
+	sdhci_disable_card_detection(host);
+
 	mmc_remove_host(host->mmc);
 
 #ifdef SDHCI_USE_LEDS_CLASS
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 43c37c6..f20a834 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -10,6 +10,9 @@
  */
 
 #include <linux/scatterlist.h>
+#include <linux/compiler.h>
+#include <linux/types.h>
+#include <linux/io.h>
 
 /*
  * Controller registers
@@ -123,6 +126,7 @@
 		SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \
 		SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \
 		SDHCI_INT_DATA_END_BIT)
+#define SDHCI_INT_ALL_MASK	((unsigned int)-1)
 
 #define SDHCI_ACMD12_ERR	0x3C
 
@@ -210,6 +214,18 @@
 #define SDHCI_QUIRK_BROKEN_SMALL_PIO			(1<<13)
 /* Controller does not provide transfer-complete interrupt when not busy */
 #define SDHCI_QUIRK_NO_BUSY_IRQ				(1<<14)
+/* Controller has unreliable card detection */
+#define SDHCI_QUIRK_BROKEN_CARD_DETECTION		(1<<15)
+/* Controller reports inverted write-protect state */
+#define SDHCI_QUIRK_INVERTED_WRITE_PROTECT		(1<<16)
+/* Controller has nonstandard clock management */
+#define SDHCI_QUIRK_NONSTANDARD_CLOCK			(1<<17)
+/* Controller does not like fast PIO transfers */
+#define SDHCI_QUIRK_PIO_NEEDS_DELAY			(1<<18)
+/* Controller losing signal/interrupt enable states after reset */
+#define SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET		(1<<19)
+/* Controller has to be forced to use block size of 2048 bytes */
+#define SDHCI_QUIRK_FORCE_BLK_SZ_2048			(1<<20)
 
 	int			irq;		/* Device IRQ */
 	void __iomem *		ioaddr;		/* Mapped address */
@@ -267,9 +283,105 @@
 
 
 struct sdhci_ops {
+#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
+	u32		(*readl)(struct sdhci_host *host, int reg);
+	u16		(*readw)(struct sdhci_host *host, int reg);
+	u8		(*readb)(struct sdhci_host *host, int reg);
+	void		(*writel)(struct sdhci_host *host, u32 val, int reg);
+	void		(*writew)(struct sdhci_host *host, u16 val, int reg);
+	void		(*writeb)(struct sdhci_host *host, u8 val, int reg);
+#endif
+
+	void	(*set_clock)(struct sdhci_host *host, unsigned int clock);
+
 	int		(*enable_dma)(struct sdhci_host *host);
+	unsigned int	(*get_max_clock)(struct sdhci_host *host);
+	unsigned int	(*get_timeout_clock)(struct sdhci_host *host);
 };
 
+#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
+
+static inline void sdhci_writel(struct sdhci_host *host, u32 val, int reg)
+{
+	if (unlikely(host->ops->writel))
+		host->ops->writel(host, val, reg);
+	else
+		writel(val, host->ioaddr + reg);
+}
+
+static inline void sdhci_writew(struct sdhci_host *host, u16 val, int reg)
+{
+	if (unlikely(host->ops->writew))
+		host->ops->writew(host, val, reg);
+	else
+		writew(val, host->ioaddr + reg);
+}
+
+static inline void sdhci_writeb(struct sdhci_host *host, u8 val, int reg)
+{
+	if (unlikely(host->ops->writeb))
+		host->ops->writeb(host, val, reg);
+	else
+		writeb(val, host->ioaddr + reg);
+}
+
+static inline u32 sdhci_readl(struct sdhci_host *host, int reg)
+{
+	if (unlikely(host->ops->readl))
+		return host->ops->readl(host, reg);
+	else
+		return readl(host->ioaddr + reg);
+}
+
+static inline u16 sdhci_readw(struct sdhci_host *host, int reg)
+{
+	if (unlikely(host->ops->readw))
+		return host->ops->readw(host, reg);
+	else
+		return readw(host->ioaddr + reg);
+}
+
+static inline u8 sdhci_readb(struct sdhci_host *host, int reg)
+{
+	if (unlikely(host->ops->readb))
+		return host->ops->readb(host, reg);
+	else
+		return readb(host->ioaddr + reg);
+}
+
+#else
+
+static inline void sdhci_writel(struct sdhci_host *host, u32 val, int reg)
+{
+	writel(val, host->ioaddr + reg);
+}
+
+static inline void sdhci_writew(struct sdhci_host *host, u16 val, int reg)
+{
+	writew(val, host->ioaddr + reg);
+}
+
+static inline void sdhci_writeb(struct sdhci_host *host, u8 val, int reg)
+{
+	writeb(val, host->ioaddr + reg);
+}
+
+static inline u32 sdhci_readl(struct sdhci_host *host, int reg)
+{
+	return readl(host->ioaddr + reg);
+}
+
+static inline u16 sdhci_readw(struct sdhci_host *host, int reg)
+{
+	return readw(host->ioaddr + reg);
+}
+
+static inline u8 sdhci_readb(struct sdhci_host *host, int reg)
+{
+	return readb(host->ioaddr + reg);
+}
+
+#endif /* CONFIG_MMC_SDHCI_IO_ACCESSORS */
 
 extern struct sdhci_host *sdhci_alloc_host(struct device *dev,
 	size_t priv_size);
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c
index 6a7a619..63fbd5b 100644
--- a/drivers/mmc/host/tmio_mmc.c
+++ b/drivers/mmc/host/tmio_mmc.c
@@ -568,11 +568,11 @@
 	host->mmc = mmc;
 	platform_set_drvdata(dev, mmc);
 
-	host->ctl = ioremap(res_ctl->start, res_ctl->end - res_ctl->start);
+	host->ctl = ioremap(res_ctl->start, resource_size(res_ctl));
 	if (!host->ctl)
 		goto host_free;
 
-	host->cnf = ioremap(res_cnf->start, res_cnf->end - res_cnf->start);
+	host->cnf = ioremap(res_cnf->start, resource_size(res_cnf));
 	if (!host->cnf)
 		goto unmap_ctl;
 
@@ -650,10 +650,10 @@
 	if (mmc) {
 		struct tmio_mmc_host *host = mmc_priv(mmc);
 		mmc_remove_host(mmc);
-		mmc_free_host(mmc);
 		free_irq(host->irq, host);
 		iounmap(host->ctl);
 		iounmap(host->cnf);
+		mmc_free_host(mmc);
 	}
 
 	return 0;
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index ba2b424..9c831ab 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -8,6 +8,9 @@
  * published by the Free Software Foundation.
  *
  */
+
+#include <linux/highmem.h>
+
 #define CNF_CMD     0x04
 #define CNF_CTL_BASE   0x10
 #define CNF_INT_PIN  0x3d
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c
index e9026cb..572d32f 100644
--- a/drivers/mtd/maps/pxa2xx-flash.c
+++ b/drivers/mtd/maps/pxa2xx-flash.c
@@ -117,7 +117,7 @@
 	return 0;
 }
 
-static int __exit pxa2xx_flash_remove(struct platform_device *dev)
+static int __devexit pxa2xx_flash_remove(struct platform_device *dev)
 {
 	struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
 
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index e4226e0..e51c1ed7 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -1773,4 +1773,4 @@
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-MODULE_DESCRIPTION("M-Systems DiskOnChip 2000, Millennium and Millennium Plus device driver\n");
+MODULE_DESCRIPTION("M-Systems DiskOnChip 2000, Millennium and Millennium Plus device driver");
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 0c3afcc..5f71371 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2720,14 +2720,14 @@
 	return chip->scan_bbt(mtd);
 }
 
-/* module_text_address() isn't exported, and it's mostly a pointless
+/* is_module_text_address() isn't exported, and it's mostly a pointless
    test if this is a module _anyway_ -- they'd have to try _really_ hard
    to call us from in-kernel code if the core NAND support is modular. */
 #ifdef MODULE
 #define caller_is_module() (1)
 #else
 #define caller_is_module() \
-	module_text_address((unsigned long)__builtin_return_address(0))
+	is_module_text_address((unsigned long)__builtin_return_address(0))
 #endif
 
 /**
diff --git a/drivers/mtd/tests/mtd_oobtest.c b/drivers/mtd/tests/mtd_oobtest.c
index afbc3f8..a18e8d2 100644
--- a/drivers/mtd/tests/mtd_oobtest.c
+++ b/drivers/mtd/tests/mtd_oobtest.c
@@ -136,7 +136,7 @@
 		ops.ooblen    = use_len;
 		ops.oobretlen = 0;
 		ops.ooboffs   = use_offset;
-		ops.datbuf    = 0;
+		ops.datbuf    = NULL;
 		ops.oobbuf    = writebuf;
 		err = mtd->write_oob(mtd, addr, &ops);
 		if (err || ops.oobretlen != use_len) {
@@ -189,7 +189,7 @@
 		ops.ooblen    = use_len;
 		ops.oobretlen = 0;
 		ops.ooboffs   = use_offset;
-		ops.datbuf    = 0;
+		ops.datbuf    = NULL;
 		ops.oobbuf    = readbuf;
 		err = mtd->read_oob(mtd, addr, &ops);
 		if (err || ops.oobretlen != use_len) {
@@ -216,7 +216,7 @@
 			ops.ooblen    = mtd->ecclayout->oobavail;
 			ops.oobretlen = 0;
 			ops.ooboffs   = 0;
-			ops.datbuf    = 0;
+			ops.datbuf    = NULL;
 			ops.oobbuf    = readbuf;
 			err = mtd->read_oob(mtd, addr, &ops);
 			if (err || ops.oobretlen != mtd->ecclayout->oobavail) {
@@ -281,7 +281,7 @@
 	ops.ooblen    = len;
 	ops.oobretlen = 0;
 	ops.ooboffs   = 0;
-	ops.datbuf    = 0;
+	ops.datbuf    = NULL;
 	ops.oobbuf    = readbuf;
 	err = mtd->read_oob(mtd, addr, &ops);
 	if (err || ops.oobretlen != len) {
@@ -522,7 +522,7 @@
 	ops.ooblen    = 1;
 	ops.oobretlen = 0;
 	ops.ooboffs   = mtd->ecclayout->oobavail;
-	ops.datbuf    = 0;
+	ops.datbuf    = NULL;
 	ops.oobbuf    = writebuf;
 	printk(PRINT_PREF "attempting to start write past end of OOB\n");
 	printk(PRINT_PREF "an error is expected...\n");
@@ -542,7 +542,7 @@
 	ops.ooblen    = 1;
 	ops.oobretlen = 0;
 	ops.ooboffs   = mtd->ecclayout->oobavail;
-	ops.datbuf    = 0;
+	ops.datbuf    = NULL;
 	ops.oobbuf    = readbuf;
 	printk(PRINT_PREF "attempting to start read past end of OOB\n");
 	printk(PRINT_PREF "an error is expected...\n");
@@ -566,7 +566,7 @@
 		ops.ooblen    = mtd->ecclayout->oobavail + 1;
 		ops.oobretlen = 0;
 		ops.ooboffs   = 0;
-		ops.datbuf    = 0;
+		ops.datbuf    = NULL;
 		ops.oobbuf    = writebuf;
 		printk(PRINT_PREF "attempting to write past end of device\n");
 		printk(PRINT_PREF "an error is expected...\n");
@@ -586,7 +586,7 @@
 		ops.ooblen    = mtd->ecclayout->oobavail + 1;
 		ops.oobretlen = 0;
 		ops.ooboffs   = 0;
-		ops.datbuf    = 0;
+		ops.datbuf    = NULL;
 		ops.oobbuf    = readbuf;
 		printk(PRINT_PREF "attempting to read past end of device\n");
 		printk(PRINT_PREF "an error is expected...\n");
@@ -610,7 +610,7 @@
 		ops.ooblen    = mtd->ecclayout->oobavail;
 		ops.oobretlen = 0;
 		ops.ooboffs   = 1;
-		ops.datbuf    = 0;
+		ops.datbuf    = NULL;
 		ops.oobbuf    = writebuf;
 		printk(PRINT_PREF "attempting to write past end of device\n");
 		printk(PRINT_PREF "an error is expected...\n");
@@ -630,7 +630,7 @@
 		ops.ooblen    = mtd->ecclayout->oobavail;
 		ops.oobretlen = 0;
 		ops.ooboffs   = 1;
-		ops.datbuf    = 0;
+		ops.datbuf    = NULL;
 		ops.oobbuf    = readbuf;
 		printk(PRINT_PREF "attempting to read past end of device\n");
 		printk(PRINT_PREF "an error is expected...\n");
@@ -670,7 +670,7 @@
 			ops.ooblen    = sz;
 			ops.oobretlen = 0;
 			ops.ooboffs   = 0;
-			ops.datbuf    = 0;
+			ops.datbuf    = NULL;
 			ops.oobbuf    = writebuf;
 			err = mtd->write_oob(mtd, addr, &ops);
 			if (err)
@@ -698,7 +698,7 @@
 		ops.ooblen    = mtd->ecclayout->oobavail * 2;
 		ops.oobretlen = 0;
 		ops.ooboffs   = 0;
-		ops.datbuf    = 0;
+		ops.datbuf    = NULL;
 		ops.oobbuf    = readbuf;
 		err = mtd->read_oob(mtd, addr, &ops);
 		if (err)
diff --git a/drivers/mtd/tests/mtd_readtest.c b/drivers/mtd/tests/mtd_readtest.c
index 645e77f..79fc453 100644
--- a/drivers/mtd/tests/mtd_readtest.c
+++ b/drivers/mtd/tests/mtd_readtest.c
@@ -71,7 +71,7 @@
 			ops.ooblen    = mtd->oobsize;
 			ops.oobretlen = 0;
 			ops.ooboffs   = 0;
-			ops.datbuf    = 0;
+			ops.datbuf    = NULL;
 			ops.oobbuf    = oobbuf;
 			ret = mtd->read_oob(mtd, addr, &ops);
 			if (ret || ops.oobretlen != mtd->oobsize) {
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index 88dd2e0..ce7551e 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -2299,7 +2299,7 @@
 	eaddr = sc->sbm_hwaddr;
 
 	/*
-	 * Read the ethernet address.  The firwmare left this programmed
+	 * Read the ethernet address.  The firmware left this programmed
 	 * for us in the ethernet address register for each mac.
 	 */
 
diff --git a/drivers/net/skfp/h/hwmtm.h b/drivers/net/skfp/h/hwmtm.h
index 1a606d4..e1a7e5f 100644
--- a/drivers/net/skfp/h/hwmtm.h
+++ b/drivers/net/skfp/h/hwmtm.h
@@ -145,7 +145,7 @@
 	int	leave_isr ;		/* leave fddi_isr immedeately if set */
 	int	isr_flag ;		/* set, when HWM is entered from isr */
 	/*
-	 * varaibles for the current transmit frame
+	 * variables for the current transmit frame
 	 */
 	struct s_smt_tx_queue *tx_p ;	/* pointer to the transmit queue */
 	u_long	tx_descr ;		/* tx descriptor for FORMAC+ */
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 1205c2a..437683a 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -11225,7 +11225,7 @@
 		return tg3_phy_init(tp);
 
 	/* Reading the PHY ID register can conflict with ASF
-	 * firwmare access to the PHY hardware.
+	 * firmware access to the PHY hardware.
 	 */
 	err = 0;
 	if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index 00945f7..25c9ef6 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -69,7 +69,7 @@
 #endif
 
 /*
- * Modules parameters and associated varaibles
+ * Modules parameters and associated variables
  */
 static int fst_txq_low = FST_LOW_WATER_MARK;
 static int fst_txq_high = FST_HIGH_WATER_MARK;
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 115b704..f4e963b 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -2362,7 +2362,7 @@
 		       i * sizeof(struct ipw2100_status));
 
 #ifdef IPW2100_DEBUG_C3
-	/* Halt the fimrware so we can get a good image */
+	/* Halt the firmware so we can get a good image */
 	write_register(priv->net_dev, IPW_REG_RESET_REG,
 		       IPW_AUX_HOST_RESET_REG_STOP_MASTER);
 	j = 5;
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 4a92af1..e17a459 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -8844,7 +8844,7 @@
 #endif				/* CONFIG_IPW2200_MONITOR */
 
 	/* Free the existing firmware and reset the fw_loaded
-	 * flag so ipw_load() will bring in the new firmawre */
+	 * flag so ipw_load() will bring in the new firmware */
 	free_firmware();
 
 	priv->ieee->iw_mode = wrqu->mode;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 663dc83..3889158 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1337,7 +1337,7 @@
 
 	/* api_ver should match the api version forming part of the
 	 * firmware filename ... but we don't check for that and only rely
-	 * on the API version read from firware header from here on forward */
+	 * on the API version read from firmware header from here on forward */
 
 	if (api_ver < api_min || api_ver > api_max) {
 		IWL_ERR(priv, "Driver unable to support your firmware API. "
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index a71b08c..9d5f97d 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -2562,7 +2562,7 @@
 
 	/* api_ver should match the api version forming part of the
 	 * firmware filename ... but we don't check for that and only rely
-	 * on the API version read from firware header from here on forward */
+	 * on the API version read from firmware header from here on forward */
 
 	if (api_ver < api_min || api_ver > api_max) {
 		IWL_ERR(priv, "Driver unable to support your firmware API. "
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 639dd02..8c3605c 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -1649,7 +1649,7 @@
 
 /**
  *  @brief This function executes next command in command
- *  pending queue. It will put fimware back to PS mode
+ *  pending queue. It will put firmware back to PS mode
  *  if applicable.
  *
  *  @param priv     A pointer to struct lbs_private structure
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
index 2c9aa49..8574622 100644
--- a/drivers/oprofile/buffer_sync.c
+++ b/drivers/oprofile/buffer_sync.c
@@ -154,6 +154,10 @@
 {
 	int err;
 
+	if (!alloc_cpumask_var(&marked_cpus, GFP_KERNEL))
+		return -ENOMEM;
+	cpumask_clear(marked_cpus);
+
 	start_cpu_work();
 
 	err = task_handoff_register(&task_free_nb);
@@ -179,6 +183,7 @@
 	task_handoff_unregister(&task_free_nb);
 out1:
 	end_sync();
+	free_cpumask_var(marked_cpus);
 	goto out;
 }
 
@@ -190,6 +195,7 @@
 	profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb);
 	task_handoff_unregister(&task_free_nb);
 	end_sync();
+	free_cpumask_var(marked_cpus);
 }
 
 
@@ -565,20 +571,6 @@
 	mutex_unlock(&buffer_mutex);
 }
 
-int __init buffer_sync_init(void)
-{
-	if (!alloc_cpumask_var(&marked_cpus, GFP_KERNEL))
-		return -ENOMEM;
-
-	cpumask_clear(marked_cpus);
-		return 0;
-}
-
-void buffer_sync_cleanup(void)
-{
-	free_cpumask_var(marked_cpus);
-}
-
 /* The function can be used to add a buffer worth of data directly to
  * the kernel buffer. The buffer is assumed to be a circular buffer.
  * Take the entries from index start and end at index end, wrapping
diff --git a/drivers/oprofile/buffer_sync.h b/drivers/oprofile/buffer_sync.h
index 0ebf5db..3110732 100644
--- a/drivers/oprofile/buffer_sync.h
+++ b/drivers/oprofile/buffer_sync.h
@@ -19,8 +19,4 @@
 /* sync the given CPU's buffer */
 void sync_buffer(int cpu);
 
-/* initialize/destroy the buffer system. */
-int buffer_sync_init(void);
-void buffer_sync_cleanup(void);
-
 #endif /* OPROFILE_BUFFER_SYNC_H */
diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
index e76d715..f0e99d4 100644
--- a/drivers/oprofile/cpu_buffer.c
+++ b/drivers/oprofile/cpu_buffer.c
@@ -161,7 +161,7 @@
 {
 	entry->event = ring_buffer_lock_reserve
 		(op_ring_buffer_write, sizeof(struct op_sample) +
-		 size * sizeof(entry->sample->data[0]), &entry->irq_flags);
+		 size * sizeof(entry->sample->data[0]));
 	if (entry->event)
 		entry->sample = ring_buffer_event_data(entry->event);
 	else
@@ -178,8 +178,7 @@
 
 int op_cpu_buffer_write_commit(struct op_entry *entry)
 {
-	return ring_buffer_unlock_commit(op_ring_buffer_write, entry->event,
-					 entry->irq_flags);
+	return ring_buffer_unlock_commit(op_ring_buffer_write, entry->event);
 }
 
 struct op_sample *op_cpu_buffer_read_entry(struct op_entry *entry, int cpu)
diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c
index ced39f6..3cffce9 100644
--- a/drivers/oprofile/oprof.c
+++ b/drivers/oprofile/oprof.c
@@ -183,10 +183,6 @@
 {
 	int err;
 
-	err = buffer_sync_init();
-	if (err)
-		return err;
-
 	err = oprofile_arch_init(&oprofile_ops);
 
 	if (err < 0 || timer) {
@@ -195,10 +191,8 @@
 	}
 
 	err = oprofilefs_register();
-	if (err) {
+	if (err)
 		oprofile_arch_exit();
-		buffer_sync_cleanup();
-	}
 
 	return err;
 }
@@ -208,7 +202,6 @@
 {
 	oprofilefs_unregister();
 	oprofile_arch_exit();
-	buffer_sync_cleanup();
 }
 
 
diff --git a/drivers/parisc/asp.c b/drivers/parisc/asp.c
index 79311335..9ca2109 100644
--- a/drivers/parisc/asp.c
+++ b/drivers/parisc/asp.c
@@ -81,7 +81,7 @@
 	asp.hpa = ASP_INTERRUPT_ADDR;
 
 	printk(KERN_INFO "%s version %d at 0x%lx found.\n", 
-		asp.name, asp.version, dev->hpa.start);
+		asp.name, asp.version, (unsigned long)dev->hpa.start);
 
 	/* the IRQ ASP should use */
 	ret = -EBUSY;
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index cd4dd7e..5d610cb 100644
--- a/drivers/parisc/ccio-dma.c
+++ b/drivers/parisc/ccio-dma.c
@@ -406,8 +406,6 @@
 	}
 	ioc->avg_search[ioc->avg_idx++] = cr_start;
 	ioc->avg_idx &= CCIO_SEARCH_SAMPLE - 1;
-#endif
-#ifdef CCIO_COLLECT_STATS
 	ioc->used_pages += pages_needed;
 #endif
 	/* 
@@ -453,10 +451,10 @@
 		unsigned long mask = ~(~0UL >> pages_mapped);
 		CCIO_FREE_MAPPINGS(ioc, res_idx, mask, 8);
 #else
-		CCIO_FREE_MAPPINGS(ioc, res_idx, 0xff, 8);
+		CCIO_FREE_MAPPINGS(ioc, res_idx, 0xffUL, 8);
 #endif
 	} else if(pages_mapped <= 16) {
-		CCIO_FREE_MAPPINGS(ioc, res_idx, 0xffff, 16);
+		CCIO_FREE_MAPPINGS(ioc, res_idx, 0xffffUL, 16);
 	} else if(pages_mapped <= 32) {
 		CCIO_FREE_MAPPINGS(ioc, res_idx, ~(unsigned int)0, 32);
 #ifdef __LP64__
@@ -1028,8 +1026,10 @@
 
 	while (ioc != NULL) {
 		unsigned int total_pages = ioc->res_size << 3;
+#ifdef CCIO_COLLECT_STATS
 		unsigned long avg = 0, min, max;
 		int j;
+#endif
 
 		len += seq_printf(m, "%s\n", ioc->name);
 		
@@ -1060,8 +1060,7 @@
 		avg /= CCIO_SEARCH_SAMPLE;
 		len += seq_printf(m, "  Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n",
 				  min, avg, max);
-#endif
-#ifdef CCIO_COLLECT_STATS
+
 		len += seq_printf(m, "pci_map_single(): %8ld calls  %8ld pages (avg %d/1000)\n",
 				  ioc->msingle_calls, ioc->msingle_pages,
 				  (int)((ioc->msingle_pages * 1000)/ioc->msingle_calls));
@@ -1400,7 +1399,7 @@
 	result = insert_resource(&iomem_resource, res);
 	if (result < 0) {
 		printk(KERN_ERR "%s() failed to claim CCIO bus address space (%08lx,%08lx)\n", 
-			__func__, res->start, res->end);
+			__func__, (unsigned long)res->start, (unsigned long)res->end);
 	}
 }
 
@@ -1551,7 +1550,8 @@
 
 	ioc->name = dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn";
 
-	printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name, dev->hpa.start);
+	printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name,
+		(unsigned long)dev->hpa.start);
 
 	for (i = 0; i < ioc_count; i++) {
 		ioc_p = &(*ioc_p)->next;
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index bb5a1c9..52ae0b1 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -819,7 +819,9 @@
 
 		result = ccio_request_resource(dino_dev->hba.dev, &res[i]);
 		if (result < 0) {
-			printk(KERN_ERR "%s: failed to claim PCI Bus address space %d (0x%lx-0x%lx)!\n", name, i, res[i].start, res[i].end);
+			printk(KERN_ERR "%s: failed to claim PCI Bus address "
+			       "space %d (0x%lx-0x%lx)!\n", name, i,
+			       (unsigned long)res[i].start, (unsigned long)res[i].end);
 			return result;
 		}
 	}
@@ -899,7 +901,8 @@
 	if (request_resource(&ioport_resource, res) < 0) {
 		printk(KERN_ERR "%s: request I/O Port region failed "
 		       "0x%lx/%lx (hpa 0x%p)\n",
-		       name, res->start, res->end, dino_dev->hba.base_addr);
+		       name, (unsigned long)res->start, (unsigned long)res->end,
+		       dino_dev->hba.base_addr);
 		return 1;
 	}
 
diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c
index 7891db5..f415fdd 100644
--- a/drivers/parisc/eisa.c
+++ b/drivers/parisc/eisa.c
@@ -314,7 +314,7 @@
 	char *name = is_mongoose(dev) ? "Mongoose" : "Wax";
 
 	printk(KERN_INFO "%s EISA Adapter found at 0x%08lx\n", 
-		name, dev->hpa.start);
+		name, (unsigned long)dev->hpa.start);
 
 	eisa_dev.hba.dev = dev;
 	eisa_dev.hba.iommu = ccio_get_iommu(dev);
diff --git a/drivers/parisc/eisa_enumerator.c b/drivers/parisc/eisa_enumerator.c
index 6d8aae0..c709ecc 100644
--- a/drivers/parisc/eisa_enumerator.c
+++ b/drivers/parisc/eisa_enumerator.c
@@ -98,7 +98,7 @@
 			res->start = mem_parent->start + get_24(buf+len+2);
 			res->end = res->start + get_16(buf+len+5)*1024;
 			res->flags = IORESOURCE_MEM;
-			printk("memory %lx-%lx ", res->start, res->end);
+			printk("memory %lx-%lx ", (unsigned long)res->start, (unsigned long)res->end);
 			result = request_resource(mem_parent, res);
 			if (result < 0) {
 				printk("\n" KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n");
@@ -188,7 +188,7 @@
 			res->start = get_16(buf+len+1);
 			res->end = get_16(buf+len+1)+(c&HPEE_PORT_SIZE_MASK)+1;
 			res->flags = IORESOURCE_IO;
-			printk("ioports %lx-%lx ", res->start, res->end);
+			printk("ioports %lx-%lx ", (unsigned long)res->start, (unsigned long)res->end);
 			result = request_resource(io_parent, res);
 			if (result < 0) {
 				printk("\n" KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n");
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
index 501aaf1..73348c4 100644
--- a/drivers/parisc/iosapic.c
+++ b/drivers/parisc/iosapic.c
@@ -714,7 +714,7 @@
 	if (dest_cpu < 0)
 		return;
 
-	irq_desc[irq].affinity = cpumask_of_cpu(dest_cpu);
+	cpumask_copy(irq_desc[irq].affinity, cpumask_of(dest_cpu));
 	vi->txn_addr = txn_affinity_addr(irq, dest_cpu);
 
 	spin_lock_irqsave(&iosapic_lock, flags);
diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c
index 454b653..9581d36 100644
--- a/drivers/parisc/led.c
+++ b/drivers/parisc/led.c
@@ -3,7 +3,7 @@
  *
  *      (c) Copyright 2000 Red Hat Software
  *      (c) Copyright 2000 Helge Deller <hdeller@redhat.com>
- *      (c) Copyright 2001-2005 Helge Deller <deller@gmx.de>
+ *      (c) Copyright 2001-2009 Helge Deller <deller@gmx.de>
  *      (c) Copyright 2001 Randolph Chung <tausq@debian.org>
  *
  *      This program is free software; you can redistribute it and/or modify
@@ -243,13 +243,11 @@
 
 	proc_pdc_root = proc_mkdir("pdc", 0);
 	if (!proc_pdc_root) return -1;
-	proc_pdc_root->owner = THIS_MODULE;
 	ent = create_proc_entry("led", S_IFREG|S_IRUGO|S_IWUSR, proc_pdc_root);
 	if (!ent) return -1;
 	ent->data = (void *)LED_NOLCD; /* LED */
 	ent->read_proc = led_proc_read;
 	ent->write_proc = led_proc_write;
-	ent->owner = THIS_MODULE;
 
 	if (led_type == LED_HASLCD)
 	{
@@ -258,7 +256,6 @@
 		ent->data = (void *)LED_HASLCD; /* LCD */
 		ent->read_proc = led_proc_read;
 		ent->write_proc = led_proc_write;
-		ent->owner = THIS_MODULE;
 	}
 
 	return 0;
@@ -463,9 +460,20 @@
 	if (likely(led_lanrxtx))  currentleds |= led_get_net_activity();
 	if (likely(led_diskio))   currentleds |= led_get_diskio_activity();
 
-	/* blink all LEDs twice a second if we got an Oops (HPMC) */
-	if (unlikely(oops_in_progress)) 
-		currentleds = (count_HZ<=(HZ/2)) ? 0 : 0xff;
+	/* blink LEDs if we got an Oops (HPMC) */
+	if (unlikely(oops_in_progress)) {
+		if (boot_cpu_data.cpu_type >= pcxl2) {
+			/* newer machines don't have loadavg. LEDs, so we
+			 * let all LEDs blink twice per second instead */
+			currentleds = (count_HZ <= (HZ/2)) ? 0 : 0xff;
+		} else {
+			/* old machines: blink loadavg. LEDs twice per second */
+			if (count_HZ <= (HZ/2))
+				currentleds &= ~(LED4|LED5|LED6|LED7);
+			else
+				currentleds |= (LED4|LED5|LED6|LED7);
+		}
+	}
 
 	if (currentleds != lastleds)
 	{
@@ -511,7 +519,7 @@
 	
 	/* Cancel the work item and delete the queue */
 	if (led_wq) {
-		cancel_rearming_delayed_workqueue(led_wq, &led_task);
+		cancel_delayed_work_sync(&led_task);
 		destroy_workqueue(led_wq);
 		led_wq = NULL;
 	}
@@ -630,7 +638,7 @@
 	
 	/* temporarily disable the led work task */
 	if (led_wq)
-		cancel_rearming_delayed_workqueue(led_wq, &led_task);
+		cancel_delayed_work_sync(&led_task);
 
 	/* copy display string to buffer for procfs */
 	strlcpy(lcd_text, str, sizeof(lcd_text));
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index 9dbd506..23e56a5 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -164,7 +164,8 @@
  * 1: writable
  * 2-6: reserved
  * 7: super page
- * 8-11: available
+ * 8-10: available
+ * 11: snoop behavior
  * 12-63: Host physcial address
  */
 struct dma_pte {
@@ -186,6 +187,11 @@
 	pte->val |= DMA_PTE_WRITE;
 }
 
+static inline void dma_set_pte_snp(struct dma_pte *pte)
+{
+	pte->val |= DMA_PTE_SNP;
+}
+
 static inline void dma_set_pte_prot(struct dma_pte *pte, unsigned long prot)
 {
 	pte->val = (pte->val & ~3) | (prot & 3);
@@ -231,6 +237,7 @@
 	int		flags;		/* flags to find out type of domain */
 
 	int		iommu_coherency;/* indicate coherency of iommu access */
+	int		iommu_snooping; /* indicate snooping control feature*/
 	int		iommu_count;	/* reference count of iommu */
 	spinlock_t	iommu_lock;	/* protect iommu set in domain */
 	u64		max_addr;	/* maximum mapped address */
@@ -421,7 +428,6 @@
 	return g_iommus[iommu_id];
 }
 
-/* "Coherency" capability may be different across iommus */
 static void domain_update_iommu_coherency(struct dmar_domain *domain)
 {
 	int i;
@@ -438,6 +444,29 @@
 	}
 }
 
+static void domain_update_iommu_snooping(struct dmar_domain *domain)
+{
+	int i;
+
+	domain->iommu_snooping = 1;
+
+	i = find_first_bit(&domain->iommu_bmp, g_num_of_iommus);
+	for (; i < g_num_of_iommus; ) {
+		if (!ecap_sc_support(g_iommus[i]->ecap)) {
+			domain->iommu_snooping = 0;
+			break;
+		}
+		i = find_next_bit(&domain->iommu_bmp, g_num_of_iommus, i+1);
+	}
+}
+
+/* Some capabilities may be different across iommus */
+static void domain_update_iommu_cap(struct dmar_domain *domain)
+{
+	domain_update_iommu_coherency(domain);
+	domain_update_iommu_snooping(domain);
+}
+
 static struct intel_iommu *device_to_iommu(u8 bus, u8 devfn)
 {
 	struct dmar_drhd_unit *drhd = NULL;
@@ -689,15 +718,17 @@
 static void dma_pte_clear_range(struct dmar_domain *domain, u64 start, u64 end)
 {
 	int addr_width = agaw_to_width(domain->agaw);
+	int npages;
 
 	start &= (((u64)1) << addr_width) - 1;
 	end &= (((u64)1) << addr_width) - 1;
 	/* in case it's partial page */
 	start = PAGE_ALIGN(start);
 	end &= PAGE_MASK;
+	npages = (end - start) / VTD_PAGE_SIZE;
 
 	/* we don't need lock here, nobody else touches the iova range */
-	while (start < end) {
+	while (npages--) {
 		dma_pte_clear_one(domain, start);
 		start += VTD_PAGE_SIZE;
 	}
@@ -1241,6 +1272,11 @@
 	else
 		domain->iommu_coherency = 0;
 
+	if (ecap_sc_support(iommu->ecap))
+		domain->iommu_snooping = 1;
+	else
+		domain->iommu_snooping = 0;
+
 	domain->iommu_count = 1;
 
 	/* always allocate the top pgd */
@@ -1369,7 +1405,7 @@
 	spin_lock_irqsave(&domain->iommu_lock, flags);
 	if (!test_and_set_bit(iommu->seq_id, &domain->iommu_bmp)) {
 		domain->iommu_count++;
-		domain_update_iommu_coherency(domain);
+		domain_update_iommu_cap(domain);
 	}
 	spin_unlock_irqrestore(&domain->iommu_lock, flags);
 	return 0;
@@ -1469,6 +1505,8 @@
 		BUG_ON(dma_pte_addr(pte));
 		dma_set_pte_addr(pte, start_pfn << VTD_PAGE_SHIFT);
 		dma_set_pte_prot(pte, prot);
+		if (prot & DMA_PTE_SNP)
+			dma_set_pte_snp(pte);
 		domain_flush_cache(domain, pte, sizeof(*pte));
 		start_pfn++;
 		index++;
@@ -2119,7 +2157,7 @@
 error:
 	if (iova)
 		__free_iova(&domain->iovad, iova);
-	printk(KERN_ERR"Device %s request: %lx@%llx dir %d --- failed\n",
+	printk(KERN_ERR"Device %s request: %zx@%llx dir %d --- failed\n",
 		pci_name(pdev), size, (unsigned long long)paddr, dir);
 	return 0;
 }
@@ -2218,7 +2256,7 @@
 	start_addr = iova->pfn_lo << PAGE_SHIFT;
 	size = aligned_size((u64)dev_addr, size);
 
-	pr_debug("Device %s unmapping: %lx@%llx\n",
+	pr_debug("Device %s unmapping: %zx@%llx\n",
 		pci_name(pdev), size, (unsigned long long)start_addr);
 
 	/*  clear the whole page */
@@ -2282,8 +2320,6 @@
 	free_pages((unsigned long)vaddr, order);
 }
 
-#define SG_ENT_VIRT_ADDRESS(sg)	(sg_virt((sg)))
-
 static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
 			   int nelems, enum dma_data_direction dir,
 			   struct dma_attrs *attrs)
@@ -2294,7 +2330,7 @@
 	unsigned long start_addr;
 	struct iova *iova;
 	size_t size = 0;
-	void *addr;
+	phys_addr_t addr;
 	struct scatterlist *sg;
 	struct intel_iommu *iommu;
 
@@ -2310,7 +2346,7 @@
 	if (!iova)
 		return;
 	for_each_sg(sglist, sg, nelems, i) {
-		addr = SG_ENT_VIRT_ADDRESS(sg);
+		addr = page_to_phys(sg_page(sg)) + sg->offset;
 		size += aligned_size((u64)addr, sg->length);
 	}
 
@@ -2337,7 +2373,7 @@
 
 	for_each_sg(sglist, sg, nelems, i) {
 		BUG_ON(!sg_page(sg));
-		sg->dma_address = virt_to_bus(SG_ENT_VIRT_ADDRESS(sg));
+		sg->dma_address = page_to_phys(sg_page(sg)) + sg->offset;
 		sg->dma_length = sg->length;
 	}
 	return nelems;
@@ -2346,7 +2382,7 @@
 static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems,
 			enum dma_data_direction dir, struct dma_attrs *attrs)
 {
-	void *addr;
+	phys_addr_t addr;
 	int i;
 	struct pci_dev *pdev = to_pci_dev(hwdev);
 	struct dmar_domain *domain;
@@ -2370,8 +2406,7 @@
 	iommu = domain_get_iommu(domain);
 
 	for_each_sg(sglist, sg, nelems, i) {
-		addr = SG_ENT_VIRT_ADDRESS(sg);
-		addr = (void *)virt_to_phys(addr);
+		addr = page_to_phys(sg_page(sg)) + sg->offset;
 		size += aligned_size((u64)addr, sg->length);
 	}
 
@@ -2394,8 +2429,7 @@
 	start_addr = iova->pfn_lo << PAGE_SHIFT;
 	offset = 0;
 	for_each_sg(sglist, sg, nelems, i) {
-		addr = SG_ENT_VIRT_ADDRESS(sg);
-		addr = (void *)virt_to_phys(addr);
+		addr = page_to_phys(sg_page(sg)) + sg->offset;
 		size = aligned_size((u64)addr, sg->length);
 		ret = domain_page_mapping(domain, start_addr + offset,
 			((u64)addr) & PAGE_MASK,
@@ -2628,6 +2662,33 @@
 	return 0;
 }
 
+static void iommu_detach_dependent_devices(struct intel_iommu *iommu,
+					   struct pci_dev *pdev)
+{
+	struct pci_dev *tmp, *parent;
+
+	if (!iommu || !pdev)
+		return;
+
+	/* dependent device detach */
+	tmp = pci_find_upstream_pcie_bridge(pdev);
+	/* Secondary interface's bus number and devfn 0 */
+	if (tmp) {
+		parent = pdev->bus->self;
+		while (parent != tmp) {
+			iommu_detach_dev(iommu, parent->bus->number,
+				parent->devfn);
+			parent = parent->bus->self;
+		}
+		if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */
+			iommu_detach_dev(iommu,
+				tmp->subordinate->number, 0);
+		else /* this is a legacy PCI bridge */
+			iommu_detach_dev(iommu,
+				tmp->bus->number, tmp->devfn);
+	}
+}
+
 static void vm_domain_remove_one_dev_info(struct dmar_domain *domain,
 					  struct pci_dev *pdev)
 {
@@ -2653,6 +2714,7 @@
 			spin_unlock_irqrestore(&device_domain_lock, flags);
 
 			iommu_detach_dev(iommu, info->bus, info->devfn);
+			iommu_detach_dependent_devices(iommu, pdev);
 			free_devinfo_mem(info);
 
 			spin_lock_irqsave(&device_domain_lock, flags);
@@ -2676,7 +2738,7 @@
 		spin_lock_irqsave(&domain->iommu_lock, tmp_flags);
 		clear_bit(iommu->seq_id, &domain->iommu_bmp);
 		domain->iommu_count--;
-		domain_update_iommu_coherency(domain);
+		domain_update_iommu_cap(domain);
 		spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags);
 	}
 
@@ -2702,15 +2764,16 @@
 
 		iommu = device_to_iommu(info->bus, info->devfn);
 		iommu_detach_dev(iommu, info->bus, info->devfn);
+		iommu_detach_dependent_devices(iommu, info->dev);
 
 		/* clear this iommu in iommu_bmp, update iommu count
-		 * and coherency
+		 * and capabilities
 		 */
 		spin_lock_irqsave(&domain->iommu_lock, flags2);
 		if (test_and_clear_bit(iommu->seq_id,
 				       &domain->iommu_bmp)) {
 			domain->iommu_count--;
-			domain_update_iommu_coherency(domain);
+			domain_update_iommu_cap(domain);
 		}
 		spin_unlock_irqrestore(&domain->iommu_lock, flags2);
 
@@ -2933,6 +2996,8 @@
 		prot |= DMA_PTE_READ;
 	if (iommu_prot & IOMMU_WRITE)
 		prot |= DMA_PTE_WRITE;
+	if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping)
+		prot |= DMA_PTE_SNP;
 
 	max_addr = (iova & VTD_PAGE_MASK) + VTD_PAGE_ALIGN(size);
 	if (dmar_domain->max_addr < max_addr) {
@@ -2986,6 +3051,17 @@
 	return phys;
 }
 
+static int intel_iommu_domain_has_cap(struct iommu_domain *domain,
+				      unsigned long cap)
+{
+	struct dmar_domain *dmar_domain = domain->priv;
+
+	if (cap == IOMMU_CAP_CACHE_COHERENCY)
+		return dmar_domain->iommu_snooping;
+
+	return 0;
+}
+
 static struct iommu_ops intel_iommu_ops = {
 	.domain_init	= intel_iommu_domain_init,
 	.domain_destroy = intel_iommu_domain_destroy,
@@ -2994,6 +3070,7 @@
 	.map		= intel_iommu_map_range,
 	.unmap		= intel_iommu_unmap_range,
 	.iova_to_phys	= intel_iommu_iova_to_phys,
+	.domain_has_cap = intel_iommu_domain_has_cap,
 };
 
 static void __devinit quirk_iommu_rwbf(struct pci_dev *dev)
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index fac5edd..ea15b05 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -171,12 +171,12 @@
 {
 	int ret;
 
-	if (acpi_gbl_FADT.boot_flags & BAF_MSI_NOT_SUPPORTED) {
+	if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_MSI) {
 		printk(KERN_INFO"ACPI FADT declares the system doesn't support MSI, so disable it\n");
 		pci_no_msi();
 	}
 
-	if (acpi_gbl_FADT.boot_flags & BAF_PCIE_ASPM_CONTROL) {
+	if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) {
 		printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n");
 		pcie_no_aspm();
 	}
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index c0cbbb5..d76c4c8 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -277,10 +277,9 @@
 	node = dev_to_node(&dev->dev);
 	if (node >= 0) {
 		int cpu;
-		node_to_cpumask_ptr(nodecpumask, node);
 
 		get_online_cpus();
-		cpu = cpumask_any_and(nodecpumask, cpu_online_mask);
+		cpu = cpumask_any_and(cpumask_of_node(node), cpu_online_mask);
 		if (cpu < nr_cpu_ids)
 			error = work_on_cpu(cpu, local_pci_probe, &ddi);
 		else
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index fe7ac2c..445fb6f 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -593,7 +593,7 @@
  * @dev: PCI device to handle.
  * @state: PCI power state (D0, D1, D2, D3hot) to put the device into.
  *
- * Transition a device to a new power state, using the platform formware and/or
+ * Transition a device to a new power state, using the platform firmware and/or
  * the device's PCI PM registers.
  *
  * RETURN VALUE:
diff --git a/drivers/pcmcia/pxa2xx_cm_x255.c b/drivers/pcmcia/pxa2xx_cm_x255.c
index 4ed64d8..5143a76 100644
--- a/drivers/pcmcia/pxa2xx_cm_x255.c
+++ b/drivers/pcmcia/pxa2xx_cm_x255.c
@@ -63,7 +63,7 @@
 				       struct pcmcia_state *state)
 {
 	int cd = skt->nr ? GPIO_PCMCIA_S1_CD_VALID : GPIO_PCMCIA_S0_CD_VALID;
-	int rdy = skt->nr ? GPIO_PCMCIA_S0_RDYINT : GPIO_PCMCIA_S1_RDYINT;
+	int rdy = skt->nr ? GPIO_PCMCIA_S1_RDYINT : GPIO_PCMCIA_S0_RDYINT;
 
 	state->detect = !gpio_get_value(cd);
 	state->ready  = !!gpio_get_value(rdy);
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 3608081..284ebac 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -67,6 +67,16 @@
 	This driver adds support for rfkill and backlight control to Dell
 	laptops.
 
+config DELL_WMI
+	tristate "Dell WMI extras"
+	depends on ACPI_WMI
+	depends on INPUT
+	---help---
+	  Say Y here if you want to support WMI-based hotkeys on Dell laptops.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called dell-wmi.
+
 config FUJITSU_LAPTOP
 	tristate "Fujitsu Laptop Extras"
 	depends on ACPI
@@ -165,6 +175,7 @@
 	depends on ACPI
 	select BACKLIGHT_CLASS_DEVICE
 	depends on INPUT
+	depends on RFKILL
 	  ---help---
 	  This mini-driver drives the SNC and SPIC devices present in the ACPI
 	  BIOS of the Sony Vaio laptops.
@@ -226,6 +237,30 @@
 
 	  If you are not sure, say N here.
 
+config THINKPAD_ACPI_UNSAFE_LEDS
+	bool "Allow control of important LEDs (unsafe)"
+	depends on THINKPAD_ACPI
+	default n
+	---help---
+	  Overriding LED state on ThinkPads can mask important
+	  firmware alerts (like critical battery condition), or misled
+	  the user into damaging the hardware (undocking or ejecting
+	  the bay while buses are still active), etc.
+
+	  LED control on the ThinkPad is write-only (with very few
+	  exceptions on very ancient models), which makes it
+	  impossible to know beforehand if important information will
+	  be lost when one changes LED state.
+
+	  Users that know what they are doing can enable this option
+	  and the driver will allow control of every LED, including
+	  the ones on the dock stations.
+
+	  Never enable this option on a distribution kernel.
+
+	  Say N here, unless you are building a kernel for your own
+	  use, and need to control the important firmware LEDs.
+
 config THINKPAD_ACPI_DOCK
 	bool "Legacy Docking Station Support"
 	depends on THINKPAD_ACPI
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index e290651..e40c7bd 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -7,6 +7,7 @@
 obj-$(CONFIG_MSI_LAPTOP)	+= msi-laptop.o
 obj-$(CONFIG_COMPAL_LAPTOP)	+= compal-laptop.o
 obj-$(CONFIG_DELL_LAPTOP)	+= dell-laptop.o
+obj-$(CONFIG_DELL_WMI)		+= dell-wmi.o
 obj-$(CONFIG_ACER_WMI)		+= acer-wmi.o
 obj-$(CONFIG_HP_WMI)		+= hp-wmi.o
 obj-$(CONFIG_TC1100_WMI)	+= tc1100-wmi.o
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index a6a42e8..0f6e43b 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -1,7 +1,7 @@
 /*
  *  Acer WMI Laptop Extras
  *
- *  Copyright (C) 2007-2008	Carlos Corbacho <carlos@strangeworlds.co.uk>
+ *  Copyright (C) 2007-2009	Carlos Corbacho <carlos@strangeworlds.co.uk>
  *
  *  Based on acer_acpi:
  *    Copyright (C) 2005-2007	E.M. Smith
@@ -225,6 +225,25 @@
 	.wireless = 2,
 };
 
+/* The Aspire One has a dummy ACPI-WMI interface - disable it */
+static struct dmi_system_id __devinitdata acer_blacklist[] = {
+	{
+		.ident = "Acer Aspire One (SSD)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"),
+		},
+	},
+	{
+		.ident = "Acer Aspire One (HDD)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"),
+		},
+	},
+	{}
+};
+
 static struct dmi_system_id acer_quirks[] = {
 	{
 		.callback = dmi_matched,
@@ -1117,11 +1136,17 @@
 	}
 
 	err = acer_rfkill_init(&device->dev);
+	if (err)
+		goto error_rfkill;
 
 	return err;
 
+error_rfkill:
+	if (has_cap(ACER_CAP_BRIGHTNESS))
+		acer_backlight_exit();
 error_brightness:
-	acer_led_exit();
+	if (has_cap(ACER_CAP_MAILLED))
+		acer_led_exit();
 error_mailled:
 	return err;
 }
@@ -1254,6 +1279,12 @@
 
 	printk(ACER_INFO "Acer Laptop ACPI-WMI Extras\n");
 
+	if (dmi_check_system(acer_blacklist)) {
+		printk(ACER_INFO "Blacklisted hardware detected - "
+				"not loading\n");
+		return -ENODEV;
+	}
+
 	find_quirks();
 
 	/*
diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c
new file mode 100644
index 0000000..2fab941
--- /dev/null
+++ b/drivers/platform/x86/dell-wmi.c
@@ -0,0 +1,210 @@
+/*
+ * Dell WMI hotkeys
+ *
+ * Copyright (C) 2008 Red Hat <mjg@redhat.com>
+ *
+ * Portions based on wistron_btns.c:
+ * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
+ * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
+ * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
+ *
+ *  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
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/input.h>
+#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
+#include <linux/string.h>
+
+MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>");
+MODULE_DESCRIPTION("Dell laptop WMI hotkeys driver");
+MODULE_LICENSE("GPL");
+
+#define DELL_EVENT_GUID "9DBB5994-A997-11DA-B012-B622A1EF5492"
+
+MODULE_ALIAS("wmi:"DELL_EVENT_GUID);
+
+struct key_entry {
+	char type;		/* See KE_* below */
+	u16 code;
+	u16 keycode;
+};
+
+enum { KE_KEY, KE_SW, KE_END };
+
+static struct key_entry dell_wmi_keymap[] = {
+	{KE_KEY, 0xe045, KEY_PROG1},
+	{KE_END, 0}
+};
+
+static struct input_dev *dell_wmi_input_dev;
+
+static struct key_entry *dell_wmi_get_entry_by_scancode(int code)
+{
+	struct key_entry *key;
+
+	for (key = dell_wmi_keymap; key->type != KE_END; key++)
+		if (code == key->code)
+			return key;
+
+	return NULL;
+}
+
+static struct key_entry *dell_wmi_get_entry_by_keycode(int keycode)
+{
+	struct key_entry *key;
+
+	for (key = dell_wmi_keymap; key->type != KE_END; key++)
+		if (key->type == KE_KEY && keycode == key->keycode)
+			return key;
+
+	return NULL;
+}
+
+static int dell_wmi_getkeycode(struct input_dev *dev, int scancode,
+			       int *keycode)
+{
+	struct key_entry *key = dell_wmi_get_entry_by_scancode(scancode);
+
+	if (key && key->type == KE_KEY) {
+		*keycode = key->keycode;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int dell_wmi_setkeycode(struct input_dev *dev, int scancode, int keycode)
+{
+	struct key_entry *key;
+	int old_keycode;
+
+	if (keycode < 0 || keycode > KEY_MAX)
+		return -EINVAL;
+
+	key = dell_wmi_get_entry_by_scancode(scancode);
+	if (key && key->type == KE_KEY) {
+		old_keycode = key->keycode;
+		key->keycode = keycode;
+		set_bit(keycode, dev->keybit);
+		if (!dell_wmi_get_entry_by_keycode(old_keycode))
+			clear_bit(old_keycode, dev->keybit);
+		return 0;
+	}
+	return -EINVAL;
+}
+
+static void dell_wmi_notify(u32 value, void *context)
+{
+	struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
+	static struct key_entry *key;
+	union acpi_object *obj;
+
+	wmi_get_event_data(value, &response);
+
+	obj = (union acpi_object *)response.pointer;
+
+	if (obj && obj->type == ACPI_TYPE_BUFFER) {
+		int *buffer = (int *)obj->buffer.pointer;
+		key = dell_wmi_get_entry_by_scancode(buffer[1]);
+		if (key) {
+			input_report_key(dell_wmi_input_dev, key->keycode, 1);
+			input_sync(dell_wmi_input_dev);
+			input_report_key(dell_wmi_input_dev, key->keycode, 0);
+			input_sync(dell_wmi_input_dev);
+		} else
+			printk(KERN_INFO "dell-wmi: Unknown key %x pressed\n",
+			       buffer[1]);
+	}
+}
+
+static int __init dell_wmi_input_setup(void)
+{
+	struct key_entry *key;
+	int err;
+
+	dell_wmi_input_dev = input_allocate_device();
+
+	if (!dell_wmi_input_dev)
+		return -ENOMEM;
+
+	dell_wmi_input_dev->name = "Dell WMI hotkeys";
+	dell_wmi_input_dev->phys = "wmi/input0";
+	dell_wmi_input_dev->id.bustype = BUS_HOST;
+	dell_wmi_input_dev->getkeycode = dell_wmi_getkeycode;
+	dell_wmi_input_dev->setkeycode = dell_wmi_setkeycode;
+
+	for (key = dell_wmi_keymap; key->type != KE_END; key++) {
+		switch (key->type) {
+		case KE_KEY:
+			set_bit(EV_KEY, dell_wmi_input_dev->evbit);
+			set_bit(key->keycode, dell_wmi_input_dev->keybit);
+			break;
+		case KE_SW:
+			set_bit(EV_SW, dell_wmi_input_dev->evbit);
+			set_bit(key->keycode, dell_wmi_input_dev->swbit);
+			break;
+		}
+	}
+
+	err = input_register_device(dell_wmi_input_dev);
+
+	if (err) {
+		input_free_device(dell_wmi_input_dev);
+		return err;
+	}
+
+	return 0;
+}
+
+static int __init dell_wmi_init(void)
+{
+	int err;
+
+	if (wmi_has_guid(DELL_EVENT_GUID)) {
+		err = dell_wmi_input_setup();
+
+		if (err)
+			return err;
+
+		err = wmi_install_notify_handler(DELL_EVENT_GUID,
+						 dell_wmi_notify, NULL);
+		if (err) {
+			input_unregister_device(dell_wmi_input_dev);
+			printk(KERN_ERR "dell-wmi: Unable to register"
+			       " notify handler - %d\n", err);
+			return err;
+		}
+
+	} else
+		printk(KERN_WARNING "dell-wmi: No known WMI GUID found\n");
+
+	return 0;
+}
+
+static void __exit dell_wmi_exit(void)
+{
+	if (wmi_has_guid(DELL_EVENT_GUID)) {
+		wmi_remove_notify_handler(DELL_EVENT_GUID);
+		input_unregister_device(dell_wmi_input_dev);
+	}
+}
+
+module_init(dell_wmi_init);
+module_exit(dell_wmi_exit);
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
index f41135f..50d9019 100644
--- a/drivers/platform/x86/hp-wmi.c
+++ b/drivers/platform/x86/hp-wmi.c
@@ -53,6 +53,7 @@
 
 static int __init hp_wmi_bios_setup(struct platform_device *device);
 static int __exit hp_wmi_bios_remove(struct platform_device *device);
+static int hp_wmi_resume_handler(struct platform_device *device);
 
 struct bios_args {
 	u32 signature;
@@ -101,6 +102,7 @@
 	},
 	.probe = hp_wmi_bios_setup,
 	.remove = hp_wmi_bios_remove,
+	.resume = hp_wmi_resume_handler,
 };
 
 static int hp_wmi_perform_query(int query, int write, int value)
@@ -487,6 +489,29 @@
 	return 0;
 }
 
+static int hp_wmi_resume_handler(struct platform_device *device)
+{
+	struct key_entry *key;
+
+	/*
+	 * Docking state may have changed while suspended, so trigger
+	 * an input event for the current state. As this is a switch,
+	 * the input layer will only actually pass it on if the state
+	 * changed.
+	 */
+	for (key = hp_wmi_keymap; key->type != KE_END; key++) {
+		switch (key->type) {
+		case KE_SW:
+			input_report_switch(hp_wmi_input_dev, key->keycode,
+					    hp_wmi_dock_state());
+			input_sync(hp_wmi_input_dev);
+			break;
+		}
+	}
+
+	return 0;
+}
+
 static int __init hp_wmi_init(void)
 {
 	int err;
diff --git a/drivers/platform/x86/intel_menlow.c b/drivers/platform/x86/intel_menlow.c
index 27b7662..29432a50 100644
--- a/drivers/platform/x86/intel_menlow.c
+++ b/drivers/platform/x86/intel_menlow.c
@@ -57,8 +57,8 @@
  * In that case max_cstate would be n-1
  * GTHS returning '0' would mean that no bandwidth control states are supported
  */
-static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev,
-					unsigned long *max_state)
+static int memory_get_max_bandwidth(struct thermal_cooling_device *cdev,
+				    unsigned long *max_state)
 {
 	struct acpi_device *device = cdev->devdata;
 	acpi_handle handle = device->handle;
@@ -83,22 +83,12 @@
 	return 0;
 }
 
-static int memory_get_max_bandwidth(struct thermal_cooling_device *cdev,
-				    char *buf)
-{
-	unsigned long value;
-	if (memory_get_int_max_bandwidth(cdev, &value))
-		return -EINVAL;
-
-	return sprintf(buf, "%ld\n", value);
-}
-
 static int memory_get_cur_bandwidth(struct thermal_cooling_device *cdev,
-				    char *buf)
+				    unsigned long *value)
 {
 	struct acpi_device *device = cdev->devdata;
 	acpi_handle handle = device->handle;
-	unsigned long long value;
+	unsigned long long result;
 	struct acpi_object_list arg_list;
 	union acpi_object arg;
 	acpi_status status = AE_OK;
@@ -108,15 +98,16 @@
 	arg.type = ACPI_TYPE_INTEGER;
 	arg.integer.value = MEMORY_ARG_CUR_BANDWIDTH;
 	status = acpi_evaluate_integer(handle, MEMORY_GET_BANDWIDTH,
-				       &arg_list, &value);
+				       &arg_list, &result);
 	if (ACPI_FAILURE(status))
 		return -EFAULT;
 
-	return sprintf(buf, "%llu\n", value);
+	*value = result;
+	return 0;
 }
 
 static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,
-				    unsigned int state)
+				    unsigned long state)
 {
 	struct acpi_device *device = cdev->devdata;
 	acpi_handle handle = device->handle;
@@ -126,7 +117,7 @@
 	unsigned long long temp;
 	unsigned long max_state;
 
-	if (memory_get_int_max_bandwidth(cdev, &max_state))
+	if (memory_get_max_bandwidth(cdev, &max_state))
 		return -EFAULT;
 
 	if (state > max_state)
@@ -142,7 +133,7 @@
 				  &temp);
 
 	printk(KERN_INFO
-	       "Bandwidth value was %d: status is %d\n", state, status);
+	       "Bandwidth value was %ld: status is %d\n", state, status);
 	if (ACPI_FAILURE(status))
 		return -EFAULT;
 
diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c
index c47a44d..a5ce4bc 100644
--- a/drivers/platform/x86/panasonic-laptop.c
+++ b/drivers/platform/x86/panasonic-laptop.c
@@ -184,6 +184,7 @@
 	{ "MAT0019", 0},
 	{ "", 0},
 };
+MODULE_DEVICE_TABLE(acpi, pcc_device_ids);
 
 static struct acpi_driver acpi_pcc_driver = {
 	.name =		ACPI_PCC_DRIVER_NAME,
@@ -366,7 +367,7 @@
 	if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
 		return -EIO;
 
-	return sprintf(buf, "%u\n", pcc->sinf[SINF_NUM_BATTERIES]);
+	return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_NUM_BATTERIES]);
 }
 
 static ssize_t show_lcdtype(struct device *dev, struct device_attribute *attr,
@@ -378,7 +379,7 @@
 	if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
 		return -EIO;
 
-	return sprintf(buf, "%u\n", pcc->sinf[SINF_LCD_TYPE]);
+	return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_LCD_TYPE]);
 }
 
 static ssize_t show_mute(struct device *dev, struct device_attribute *attr,
@@ -390,7 +391,7 @@
 	if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
 		return -EIO;
 
-	return sprintf(buf, "%u\n", pcc->sinf[SINF_MUTE]);
+	return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_MUTE]);
 }
 
 static ssize_t show_sticky(struct device *dev, struct device_attribute *attr,
@@ -402,7 +403,7 @@
 	if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
 		return -EIO;
 
-	return sprintf(buf, "%u\n", pcc->sinf[SINF_STICKY_KEY]);
+	return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_STICKY_KEY]);
 }
 
 static ssize_t set_sticky(struct device *dev, struct device_attribute *attr,
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index bc8996c..a90ec5c 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -2,7 +2,7 @@
  * ACPI Sony Notebook Control Driver (SNC and SPIC)
  *
  * Copyright (C) 2004-2005 Stelian Pop <stelian@popies.net>
- * Copyright (C) 2007 Mattia Dongili <malattia@linux.it>
+ * Copyright (C) 2007-2009 Mattia Dongili <malattia@linux.it>
  *
  * Parts of this driver inspired from asus_acpi.c and ibm_acpi.c
  * which are copyrighted by their respective authors.
@@ -46,7 +46,6 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <linux/types.h>
 #include <linux/backlight.h>
 #include <linux/platform_device.h>
@@ -64,6 +63,7 @@
 #include <asm/uaccess.h>
 #include <linux/sonypi.h>
 #include <linux/sony-laptop.h>
+#include <linux/rfkill.h>
 #ifdef CONFIG_SONYPI_COMPAT
 #include <linux/poll.h>
 #include <linux/miscdevice.h>
@@ -123,6 +123,18 @@
 		 "default is -1 (automatic)");
 #endif
 
+enum sony_nc_rfkill {
+	SONY_WIFI,
+	SONY_BLUETOOTH,
+	SONY_WWAN,
+	SONY_WIMAX,
+	SONY_RFKILL_MAX,
+};
+
+static struct rfkill *sony_rfkill_devices[SONY_RFKILL_MAX];
+static int sony_rfkill_address[SONY_RFKILL_MAX] = {0x300, 0x500, 0x700, 0x900};
+static void sony_nc_rfkill_update(void);
+
 /*********** Input Devices ***********/
 
 #define SONY_LAPTOP_BUF_SIZE	128
@@ -134,6 +146,7 @@
 	spinlock_t		fifo_lock;
 	struct workqueue_struct	*wq;
 };
+
 static struct sony_laptop_input_s sony_laptop_input = {
 	.users = ATOMIC_INIT(0),
 };
@@ -211,6 +224,14 @@
 	48,	/* 61 SONYPI_EVENT_WIRELESS_OFF */
 	49,	/* 62 SONYPI_EVENT_ZOOM_IN_PRESSED */
 	50,	/* 63 SONYPI_EVENT_ZOOM_OUT_PRESSED */
+	51,	/* 64 SONYPI_EVENT_CD_EJECT_PRESSED */
+	52,	/* 65 SONYPI_EVENT_MODEKEY_PRESSED */
+	53,	/* 66 SONYPI_EVENT_PKEY_P4 */
+	54,	/* 67 SONYPI_EVENT_PKEY_P5 */
+	55,	/* 68 SONYPI_EVENT_SETTINGKEY_PRESSED */
+	56,	/* 69 SONYPI_EVENT_VOLUME_INC_PRESSED */
+	57,	/* 70 SONYPI_EVENT_VOLUME_DEC_PRESSED */
+	-1,	/* 71 SONYPI_EVENT_BRIGHTNESS_PRESSED */
 };
 
 static int sony_laptop_input_keycode_map[] = {
@@ -264,7 +285,14 @@
 	KEY_WLAN,	/* 47 SONYPI_EVENT_WIRELESS_ON */
 	KEY_WLAN,	/* 48 SONYPI_EVENT_WIRELESS_OFF */
 	KEY_ZOOMIN,	/* 49 SONYPI_EVENT_ZOOM_IN_PRESSED */
-	KEY_ZOOMOUT	/* 50 SONYPI_EVENT_ZOOM_OUT_PRESSED */
+	KEY_ZOOMOUT,	/* 50 SONYPI_EVENT_ZOOM_OUT_PRESSED */
+	KEY_EJECTCD,	/* 51 SONYPI_EVENT_CD_EJECT_PRESSED */
+	KEY_F13,	/* 52 SONYPI_EVENT_MODEKEY_PRESSED */
+	KEY_PROG4,	/* 53 SONYPI_EVENT_PKEY_P4 */
+	KEY_F14,	/* 54 SONYPI_EVENT_PKEY_P5 */
+	KEY_F15,	/* 55 SONYPI_EVENT_SETTINGKEY_PRESSED */
+	KEY_VOLUMEUP,	/* 56 SONYPI_EVENT_VOLUME_INC_PRESSED */
+	KEY_VOLUMEDOWN,	/* 57 SONYPI_EVENT_VOLUME_DEC_PRESSED */
 };
 
 /* release buttons after a short delay if pressed */
@@ -369,7 +397,7 @@
 	sony_laptop_input.wq = create_singlethread_workqueue("sony-laptop");
 	if (!sony_laptop_input.wq) {
 		printk(KERN_ERR DRV_PFX
-				"Unabe to create workqueue.\n");
+				"Unable to create workqueue.\n");
 		error = -ENXIO;
 		goto err_free_kfifo;
 	}
@@ -689,6 +717,31 @@
 	return -1;
 }
 
+static int sony_find_snc_handle(int handle)
+{
+	int i;
+	int result;
+
+	for (i = 0x20; i < 0x30; i++) {
+		acpi_callsetfunc(sony_nc_acpi_handle, "SN00", i, &result);
+		if (result == handle)
+			return i-0x20;
+	}
+
+	return -1;
+}
+
+static int sony_call_snc_handle(int handle, int argument, int *result)
+{
+	int offset = sony_find_snc_handle(handle);
+
+	if (offset < 0)
+		return -1;
+
+	return acpi_callsetfunc(sony_nc_acpi_handle, "SN07", offset | argument,
+				result);
+}
+
 /*
  * sony_nc_values input/output validate functions
  */
@@ -809,87 +862,53 @@
 	u8	event;
 };
 
-static struct sony_nc_event *sony_nc_events;
-
-/* Vaio C* --maybe also FE*, N* and AR* ?-- special init sequence
- * for Fn keys
- */
-static int sony_nc_C_enable(const struct dmi_system_id *id)
-{
-	int result = 0;
-
-	printk(KERN_NOTICE DRV_PFX "detected %s\n", id->ident);
-
-	sony_nc_events = id->driver_data;
-
-	if (acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x4, &result) < 0
-			|| acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x2, &result) < 0
-			|| acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x10, &result) < 0
-			|| acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x0, &result) < 0
-			|| acpi_callsetfunc(sony_nc_acpi_handle, "SN03", 0x2, &result) < 0
-			|| acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x101, &result) < 0) {
-		printk(KERN_WARNING DRV_PFX "failed to initialize SNC, some "
-				"functionalities may be missing\n");
-		return 1;
-	}
-	return 0;
-}
-
-static struct sony_nc_event sony_C_events[] = {
+static struct sony_nc_event sony_100_events[] = {
+	{ 0x90, SONYPI_EVENT_PKEY_P1 },
+	{ 0x10, SONYPI_EVENT_ANYBUTTON_RELEASED },
+	{ 0x91, SONYPI_EVENT_PKEY_P2 },
+	{ 0x11, SONYPI_EVENT_ANYBUTTON_RELEASED },
 	{ 0x81, SONYPI_EVENT_FNKEY_F1 },
 	{ 0x01, SONYPI_EVENT_FNKEY_RELEASED },
+	{ 0x82, SONYPI_EVENT_FNKEY_F2 },
+	{ 0x02, SONYPI_EVENT_FNKEY_RELEASED },
+	{ 0x83, SONYPI_EVENT_FNKEY_F3 },
+	{ 0x03, SONYPI_EVENT_FNKEY_RELEASED },
+	{ 0x84, SONYPI_EVENT_FNKEY_F4 },
+	{ 0x04, SONYPI_EVENT_FNKEY_RELEASED },
 	{ 0x85, SONYPI_EVENT_FNKEY_F5 },
 	{ 0x05, SONYPI_EVENT_FNKEY_RELEASED },
 	{ 0x86, SONYPI_EVENT_FNKEY_F6 },
 	{ 0x06, SONYPI_EVENT_FNKEY_RELEASED },
 	{ 0x87, SONYPI_EVENT_FNKEY_F7 },
 	{ 0x07, SONYPI_EVENT_FNKEY_RELEASED },
+	{ 0x89, SONYPI_EVENT_FNKEY_F9 },
+	{ 0x09, SONYPI_EVENT_FNKEY_RELEASED },
 	{ 0x8A, SONYPI_EVENT_FNKEY_F10 },
 	{ 0x0A, SONYPI_EVENT_FNKEY_RELEASED },
 	{ 0x8C, SONYPI_EVENT_FNKEY_F12 },
 	{ 0x0C, SONYPI_EVENT_FNKEY_RELEASED },
+	{ 0x9f, SONYPI_EVENT_CD_EJECT_PRESSED },
+	{ 0x1f, SONYPI_EVENT_ANYBUTTON_RELEASED },
 	{ 0, 0 },
 };
 
-/* SNC-only model map */
-static const struct dmi_system_id sony_nc_ids[] = {
-		{
-			.ident = "Sony Vaio FE Series",
-			.callback = sony_nc_C_enable,
-			.driver_data = sony_C_events,
-			.matches = {
-				DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
-				DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FE"),
-			},
-		},
-		{
-			.ident = "Sony Vaio FZ Series",
-			.callback = sony_nc_C_enable,
-			.driver_data = sony_C_events,
-			.matches = {
-				DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
-				DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ"),
-			},
-		},
-		{
-			.ident = "Sony Vaio C Series",
-			.callback = sony_nc_C_enable,
-			.driver_data = sony_C_events,
-			.matches = {
-				DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
-				DMI_MATCH(DMI_PRODUCT_NAME, "VGN-C"),
-			},
-		},
-		{
-			.ident = "Sony Vaio N Series",
-			.callback = sony_nc_C_enable,
-			.driver_data = sony_C_events,
-			.matches = {
-				DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
-				DMI_MATCH(DMI_PRODUCT_NAME, "VGN-N"),
-			},
-		},
-		{ }
+static struct sony_nc_event sony_127_events[] = {
+	{ 0x81, SONYPI_EVENT_MODEKEY_PRESSED },
+	{ 0x01, SONYPI_EVENT_ANYBUTTON_RELEASED },
+	{ 0x82, SONYPI_EVENT_PKEY_P1 },
+	{ 0x02, SONYPI_EVENT_ANYBUTTON_RELEASED },
+	{ 0x83, SONYPI_EVENT_PKEY_P2 },
+	{ 0x03, SONYPI_EVENT_ANYBUTTON_RELEASED },
+	{ 0x84, SONYPI_EVENT_PKEY_P3 },
+	{ 0x04, SONYPI_EVENT_ANYBUTTON_RELEASED },
+	{ 0x85, SONYPI_EVENT_PKEY_P4 },
+	{ 0x05, SONYPI_EVENT_ANYBUTTON_RELEASED },
+	{ 0x86, SONYPI_EVENT_PKEY_P5 },
+	{ 0x06, SONYPI_EVENT_ANYBUTTON_RELEASED },
+	{ 0x06, SONYPI_EVENT_ANYBUTTON_RELEASED },
+	{ 0x87, SONYPI_EVENT_SETTINGKEY_PRESSED },
+	{ 0x07, SONYPI_EVENT_ANYBUTTON_RELEASED },
+	{ 0, 0 },
 };
 
 /*
@@ -897,38 +916,59 @@
  */
 static void sony_acpi_notify(acpi_handle handle, u32 event, void *data)
 {
-	struct sony_nc_event *evmap;
 	u32 ev = event;
-	int result;
 
-	if (ev == 0x92) {
-		/* read the key pressed from EC.GECR
-		 * A call to SN07 with 0x0202 will do it as well respecting
-		 * the current protocol on different OSes
-		 *
-		 * Note: the path for GECR may be
-		 *   \_SB.PCI0.LPCB.EC (C, FE, AR, N and friends)
-		 *   \_SB.PCI0.PIB.EC0 (VGN-FR notifications are sent directly, no GECR)
-		 *
-		 * TODO: we may want to do the same for the older GHKE -need
-		 *       dmi list- so this snippet may become one more callback.
-		 */
-		if (acpi_callsetfunc(handle, "SN07", 0x0202, &result) < 0)
-			dprintk("sony_acpi_notify, unable to decode event 0x%.2x\n", ev);
-		else
-			ev = result & 0xFF;
-	}
+	if (ev >= 0x90) {
+		/* New-style event */
+		int result;
+		int key_handle = 0;
+		ev -= 0x90;
 
-	if (sony_nc_events)
-		for (evmap = sony_nc_events; evmap->event; evmap++) {
-			if (evmap->data == ev) {
-				ev = evmap->event;
-				break;
+		if (sony_find_snc_handle(0x100) == ev)
+			key_handle = 0x100;
+		if (sony_find_snc_handle(0x127) == ev)
+			key_handle = 0x127;
+
+		if (key_handle) {
+			struct sony_nc_event *key_event;
+
+			if (sony_call_snc_handle(key_handle, 0x200, &result)) {
+				dprintk("sony_acpi_notify, unable to decode"
+					" event 0x%.2x 0x%.2x\n", key_handle,
+					ev);
+				/* restore the original event */
+				ev = event;
+			} else {
+				ev = result & 0xFF;
+
+				if (key_handle == 0x100)
+					key_event = sony_100_events;
+				else
+					key_event = sony_127_events;
+
+				for (; key_event->data; key_event++) {
+					if (key_event->data == ev) {
+						ev = key_event->event;
+						break;
+					}
+				}
+
+				if (!key_event->data)
+					printk(KERN_INFO DRV_PFX
+							"Unknown event: 0x%x 0x%x\n",
+							key_handle,
+							ev);
+				else
+					sony_laptop_report_input_event(ev);
 			}
+		} else if (sony_find_snc_handle(0x124) == ev) {
+			sony_nc_rfkill_update();
+			return;
 		}
+	} else
+		sony_laptop_report_input_event(ev);
 
 	dprintk("sony_acpi_notify, event: 0x%.2x\n", ev);
-	sony_laptop_report_input_event(ev);
 	acpi_bus_generate_proc_event(sony_nc_acpi_device, 1, ev);
 }
 
@@ -953,9 +993,25 @@
 /*
  * ACPI device
  */
+static int sony_nc_function_setup(struct acpi_device *device)
+{
+	int result;
+
+	/* Enable all events */
+	acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0xffff, &result);
+
+	/* Setup hotkeys */
+	sony_call_snc_handle(0x0100, 0, &result);
+	sony_call_snc_handle(0x0101, 0, &result);
+	sony_call_snc_handle(0x0102, 0x100, &result);
+
+	return 0;
+}
+
 static int sony_nc_resume(struct acpi_device *device)
 {
 	struct sony_nc_value *item;
+	acpi_handle handle;
 
 	for (item = sony_nc_values; item->name; item++) {
 		int ret;
@@ -970,13 +1026,188 @@
 		}
 	}
 
+	if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON",
+					 &handle))) {
+		if (acpi_callsetfunc(sony_nc_acpi_handle, "ECON", 1, NULL))
+			dprintk("ECON Method failed\n");
+	}
+
+	if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "SN00",
+					 &handle))) {
+		dprintk("Doing SNC setup\n");
+		sony_nc_function_setup(device);
+	}
+
 	/* set the last requested brightness level */
 	if (sony_backlight_device &&
 			!sony_backlight_update_status(sony_backlight_device))
 		printk(KERN_WARNING DRV_PFX "unable to restore brightness level\n");
 
-	/* re-initialize models with specific requirements */
-	dmi_check_system(sony_nc_ids);
+	return 0;
+}
+
+static void sony_nc_rfkill_cleanup(void)
+{
+	int i;
+
+	for (i = 0; i < SONY_RFKILL_MAX; i++) {
+		if (sony_rfkill_devices[i])
+			rfkill_unregister(sony_rfkill_devices[i]);
+	}
+}
+
+static int sony_nc_rfkill_get(void *data, enum rfkill_state *state)
+{
+	int result;
+	int argument = sony_rfkill_address[(long) data];
+
+	sony_call_snc_handle(0x124, 0x200, &result);
+	if (result & 0x1) {
+		sony_call_snc_handle(0x124, argument, &result);
+		if (result & 0xf)
+			*state = RFKILL_STATE_UNBLOCKED;
+		else
+			*state = RFKILL_STATE_SOFT_BLOCKED;
+	} else {
+		*state = RFKILL_STATE_HARD_BLOCKED;
+	}
+
+	return 0;
+}
+
+static int sony_nc_rfkill_set(void *data, enum rfkill_state state)
+{
+	int result;
+	int argument = sony_rfkill_address[(long) data] + 0x100;
+
+	if (state == RFKILL_STATE_UNBLOCKED)
+		argument |= 0xff0000;
+
+	return sony_call_snc_handle(0x124, argument, &result);
+}
+
+static int sony_nc_setup_wifi_rfkill(struct acpi_device *device)
+{
+	int err = 0;
+	struct rfkill *sony_wifi_rfkill;
+
+	sony_wifi_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WLAN);
+	if (!sony_wifi_rfkill)
+		return -1;
+	sony_wifi_rfkill->name = "sony-wifi";
+	sony_wifi_rfkill->toggle_radio = sony_nc_rfkill_set;
+	sony_wifi_rfkill->get_state = sony_nc_rfkill_get;
+	sony_wifi_rfkill->user_claim_unsupported = 1;
+	sony_wifi_rfkill->data = (void *)SONY_WIFI;
+	err = rfkill_register(sony_wifi_rfkill);
+	if (err)
+		rfkill_free(sony_wifi_rfkill);
+	else
+		sony_rfkill_devices[SONY_WIFI] = sony_wifi_rfkill;
+	return err;
+}
+
+static int sony_nc_setup_bluetooth_rfkill(struct acpi_device *device)
+{
+	int err = 0;
+	struct rfkill *sony_bluetooth_rfkill;
+
+	sony_bluetooth_rfkill = rfkill_allocate(&device->dev,
+						RFKILL_TYPE_BLUETOOTH);
+	if (!sony_bluetooth_rfkill)
+		return -1;
+	sony_bluetooth_rfkill->name = "sony-bluetooth";
+	sony_bluetooth_rfkill->toggle_radio = sony_nc_rfkill_set;
+	sony_bluetooth_rfkill->get_state = sony_nc_rfkill_get;
+	sony_bluetooth_rfkill->user_claim_unsupported = 1;
+	sony_bluetooth_rfkill->data = (void *)SONY_BLUETOOTH;
+	err = rfkill_register(sony_bluetooth_rfkill);
+	if (err)
+		rfkill_free(sony_bluetooth_rfkill);
+	else
+		sony_rfkill_devices[SONY_BLUETOOTH] = sony_bluetooth_rfkill;
+	return err;
+}
+
+static int sony_nc_setup_wwan_rfkill(struct acpi_device *device)
+{
+	int err = 0;
+	struct rfkill *sony_wwan_rfkill;
+
+	sony_wwan_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WWAN);
+	if (!sony_wwan_rfkill)
+		return -1;
+	sony_wwan_rfkill->name = "sony-wwan";
+	sony_wwan_rfkill->toggle_radio = sony_nc_rfkill_set;
+	sony_wwan_rfkill->get_state = sony_nc_rfkill_get;
+	sony_wwan_rfkill->user_claim_unsupported = 1;
+	sony_wwan_rfkill->data = (void *)SONY_WWAN;
+	err = rfkill_register(sony_wwan_rfkill);
+	if (err)
+		rfkill_free(sony_wwan_rfkill);
+	else
+		sony_rfkill_devices[SONY_WWAN] = sony_wwan_rfkill;
+	return err;
+}
+
+static int sony_nc_setup_wimax_rfkill(struct acpi_device *device)
+{
+	int err = 0;
+	struct rfkill *sony_wimax_rfkill;
+
+	sony_wimax_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WIMAX);
+	if (!sony_wimax_rfkill)
+		return -1;
+	sony_wimax_rfkill->name = "sony-wimax";
+	sony_wimax_rfkill->toggle_radio = sony_nc_rfkill_set;
+	sony_wimax_rfkill->get_state = sony_nc_rfkill_get;
+	sony_wimax_rfkill->user_claim_unsupported = 1;
+	sony_wimax_rfkill->data = (void *)SONY_WIMAX;
+	err = rfkill_register(sony_wimax_rfkill);
+	if (err)
+		rfkill_free(sony_wimax_rfkill);
+	else
+		sony_rfkill_devices[SONY_WIMAX] = sony_wimax_rfkill;
+	return err;
+}
+
+static void sony_nc_rfkill_update()
+{
+	int i;
+	enum rfkill_state state;
+
+	for (i = 0; i < SONY_RFKILL_MAX; i++) {
+		if (sony_rfkill_devices[i]) {
+			sony_rfkill_devices[i]->
+				get_state(sony_rfkill_devices[i]->data,
+					  &state);
+			rfkill_force_state(sony_rfkill_devices[i], state);
+		}
+	}
+}
+
+static int sony_nc_rfkill_setup(struct acpi_device *device)
+{
+	int result, ret;
+
+	if (sony_find_snc_handle(0x124) == -1)
+		return -1;
+
+	ret = sony_call_snc_handle(0x124, 0xb00, &result);
+	if (ret) {
+		printk(KERN_INFO DRV_PFX
+		       "Unable to enumerate rfkill devices: %x\n", ret);
+		return ret;
+	}
+
+	if (result & 0x1)
+		sony_nc_setup_wifi_rfkill(device);
+	if (result & 0x2)
+		sony_nc_setup_bluetooth_rfkill(device);
+	if (result & 0x1c)
+		sony_nc_setup_wwan_rfkill(device);
+	if (result & 0x20)
+		sony_nc_setup_wimax_rfkill(device);
 
 	return 0;
 }
@@ -1024,11 +1255,24 @@
 			dprintk("_INI Method failed\n");
 	}
 
+	if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON",
+					 &handle))) {
+		if (acpi_callsetfunc(sony_nc_acpi_handle, "ECON", 1, NULL))
+			dprintk("ECON Method failed\n");
+	}
+
+	if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "SN00",
+					 &handle))) {
+		dprintk("Doing SNC setup\n");
+		sony_nc_function_setup(device);
+		sony_nc_rfkill_setup(device);
+	}
+
 	/* setup input devices and helper fifo */
 	result = sony_laptop_setup_input(device);
 	if (result) {
 		printk(KERN_ERR DRV_PFX
-				"Unabe to create input devices.\n");
+				"Unable to create input devices.\n");
 		goto outwalk;
 	}
 
@@ -1063,9 +1307,6 @@
 
 	}
 
-	/* initialize models with specific requirements */
-	dmi_check_system(sony_nc_ids);
-
 	result = sony_pf_add();
 	if (result)
 		goto outbacklight;
@@ -1131,6 +1372,7 @@
 	sony_laptop_remove_input();
 
       outwalk:
+	sony_nc_rfkill_cleanup();
 	return result;
 }
 
@@ -1156,6 +1398,7 @@
 
 	sony_pf_remove();
 	sony_laptop_remove_input();
+	sony_nc_rfkill_cleanup();
 	dprintk(SONY_NC_DRIVER_NAME " removed.\n");
 
 	return 0;
@@ -1195,7 +1438,6 @@
 #define SONYPI_TYPE1_OFFSET	0x04
 #define SONYPI_TYPE2_OFFSET	0x12
 #define SONYPI_TYPE3_OFFSET	0x12
-#define SONYPI_TYPE4_OFFSET	0x12
 
 struct sony_pic_ioport {
 	struct acpi_resource_io	io1;
@@ -1328,6 +1570,7 @@
 	{ 0x01, SONYPI_EVENT_PKEY_P1 },
 	{ 0x02, SONYPI_EVENT_PKEY_P2 },
 	{ 0x04, SONYPI_EVENT_PKEY_P3 },
+	{ 0x20, SONYPI_EVENT_PKEY_P1 },
 	{ 0, 0 }
 };
 
@@ -1371,6 +1614,7 @@
 	{ 0x39, SONYPI_EVENT_ZOOM_PRESSED },
 	{ 0x10, SONYPI_EVENT_ZOOM_IN_PRESSED },
 	{ 0x20, SONYPI_EVENT_ZOOM_OUT_PRESSED },
+	{ 0x04, SONYPI_EVENT_ZOOM_PRESSED },
 	{ 0, 0 }
 };
 
@@ -1401,6 +1645,19 @@
 	{ 0, 0 }
 };
 
+/* The set of possible volume events */
+static struct sonypi_event sonypi_volumeev[] = {
+	{ 0x01, SONYPI_EVENT_VOLUME_INC_PRESSED },
+	{ 0x02, SONYPI_EVENT_VOLUME_DEC_PRESSED },
+	{ 0, 0 }
+};
+
+/* The set of possible brightness events */
+static struct sonypi_event sonypi_brightnessev[] = {
+	{ 0x80, SONYPI_EVENT_BRIGHTNESS_PRESSED },
+	{ 0, 0 }
+};
+
 static struct sonypi_eventtypes type1_events[] = {
 	{ 0, 0xffffffff, sonypi_releaseev },
 	{ 0x70, SONYPI_MEYE_MASK, sonypi_meyeev },
@@ -1438,17 +1695,11 @@
 	{ 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
 	{ 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
 	{ 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
-	{ 0 },
-};
-static struct sonypi_eventtypes type4_events[] = {
-	{ 0, 0xffffffff, sonypi_releaseev },
-	{ 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
-	{ 0x31, SONYPI_WIRELESS_MASK, sonypi_wlessev },
-	{ 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
-	{ 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
 	{ 0x05, SONYPI_PKEY_MASK, sonypi_pkeyev },
 	{ 0x05, SONYPI_ZOOM_MASK, sonypi_zoomev },
 	{ 0x05, SONYPI_CAPTURE_MASK, sonypi_captureev },
+	{ 0x05, SONYPI_PKEY_MASK, sonypi_volumeev },
+	{ 0x05, SONYPI_PKEY_MASK, sonypi_brightnessev },
 	{ 0 },
 };
 
@@ -1511,11 +1762,11 @@
 /*
  * minidrivers for SPIC models
  */
-static int type4_handle_irq(const u8 data_mask, const u8 ev)
+static int type3_handle_irq(const u8 data_mask, const u8 ev)
 {
 	/*
 	 * 0x31 could mean we have to take some extra action and wait for
-	 * the next irq for some Type4 models, it will generate a new
+	 * the next irq for some Type3 models, it will generate a new
 	 * irq and we can read new data from the device:
 	 *  - 0x5c and 0x5f requires 0xA0
 	 *  - 0x61 requires 0xB3
@@ -1545,16 +1796,10 @@
 	},
 	{
 		.model = SONYPI_DEVICE_TYPE3,
-		.handle_irq = NULL,
+		.handle_irq = type3_handle_irq,
 		.evport_offset = SONYPI_TYPE3_OFFSET,
 		.event_types = type3_events,
 	},
-	{
-		.model = SONYPI_DEVICE_TYPE4,
-		.handle_irq = type4_handle_irq,
-		.evport_offset = SONYPI_TYPE4_OFFSET,
-		.event_types = type4_events,
-	},
 };
 
 static void sony_pic_detect_device_type(struct sony_pic_dev *dev)
@@ -1578,14 +1823,21 @@
 	pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
 			PCI_DEVICE_ID_INTEL_ICH7_1, NULL);
 	if (pcidev) {
-		dev->control = &spic_types[3];
+		dev->control = &spic_types[2];
 		goto out;
 	}
 
 	pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
 			PCI_DEVICE_ID_INTEL_ICH8_4, NULL);
 	if (pcidev) {
-		dev->control = &spic_types[3];
+		dev->control = &spic_types[2];
+		goto out;
+	}
+
+	pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
+			PCI_DEVICE_ID_INTEL_ICH9_1, NULL);
+	if (pcidev) {
+		dev->control = &spic_types[2];
 		goto out;
 	}
 
@@ -1598,8 +1850,7 @@
 
 	printk(KERN_INFO DRV_PFX "detected Type%d model\n",
 			dev->control->model == SONYPI_DEVICE_TYPE1 ? 1 :
-			dev->control->model == SONYPI_DEVICE_TYPE2 ? 2 :
-			dev->control->model == SONYPI_DEVICE_TYPE3 ? 3 : 4);
+			dev->control->model == SONYPI_DEVICE_TYPE2 ? 2 : 3);
 }
 
 /* camera tests and poweron/poweroff */
@@ -1754,17 +2005,14 @@
 EXPORT_SYMBOL(sony_pic_camera_command);
 
 /* gprs/edge modem (SZ460N and SZ210P), thanks to Joshua Wise */
-static void sony_pic_set_wwanpower(u8 state)
+static void __sony_pic_set_wwanpower(u8 state)
 {
 	state = !!state;
-	mutex_lock(&spic_dev.lock);
-	if (spic_dev.wwan_power == state) {
-		mutex_unlock(&spic_dev.lock);
+	if (spic_dev.wwan_power == state)
 		return;
-	}
 	sony_pic_call2(0xB0, state);
+	sony_pic_call1(0x82);
 	spic_dev.wwan_power = state;
-	mutex_unlock(&spic_dev.lock);
 }
 
 static ssize_t sony_pic_wwanpower_store(struct device *dev,
@@ -1776,7 +2024,9 @@
 		return -EINVAL;
 
 	value = simple_strtoul(buffer, NULL, 10);
-	sony_pic_set_wwanpower(value);
+	mutex_lock(&spic_dev.lock);
+	__sony_pic_set_wwanpower(value);
+	mutex_unlock(&spic_dev.lock);
 
 	return count;
 }
@@ -1929,10 +2179,15 @@
 static int sonypi_misc_open(struct inode *inode, struct file *file)
 {
 	/* Flush input queue on first open */
-	lock_kernel();
+	unsigned long flags;
+
+	spin_lock_irqsave(sonypi_compat.fifo->lock, flags);
+
 	if (atomic_inc_return(&sonypi_compat.open_count) == 1)
-		kfifo_reset(sonypi_compat.fifo);
-	unlock_kernel();
+		__kfifo_reset(sonypi_compat.fifo);
+
+	spin_unlock_irqrestore(sonypi_compat.fifo->lock, flags);
+
 	return 0;
 }
 
@@ -1985,8 +2240,8 @@
 	return 0;
 }
 
-static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
-			     unsigned int cmd, unsigned long arg)
+static long sonypi_misc_ioctl(struct file *fp, unsigned int cmd,
+							unsigned long arg)
 {
 	int ret = 0;
 	void __user *argp = (void __user *)arg;
@@ -2120,7 +2375,7 @@
 	.open		= sonypi_misc_open,
 	.release	= sonypi_misc_release,
 	.fasync		= sonypi_misc_fasync,
-	.ioctl		= sonypi_misc_ioctl,
+	.unlocked_ioctl	= sonypi_misc_ioctl,
 };
 
 static struct miscdevice sonypi_misc_device = {
@@ -2561,7 +2816,7 @@
 	result = sony_pic_possible_resources(device);
 	if (result) {
 		printk(KERN_ERR DRV_PFX
-				"Unabe to read possible resources.\n");
+				"Unable to read possible resources.\n");
 		goto err_free_resources;
 	}
 
@@ -2569,7 +2824,7 @@
 	result = sony_laptop_setup_input(device);
 	if (result) {
 		printk(KERN_ERR DRV_PFX
-				"Unabe to create input devices.\n");
+				"Unable to create input devices.\n");
 		goto err_free_resources;
 	}
 
diff --git a/drivers/platform/x86/tc1100-wmi.c b/drivers/platform/x86/tc1100-wmi.c
index b4a4aa9..4416600 100644
--- a/drivers/platform/x86/tc1100-wmi.c
+++ b/drivers/platform/x86/tc1100-wmi.c
@@ -94,9 +94,8 @@
 		return -ENODEV;
 
 	obj = (union acpi_object *) result.pointer;
-	if (obj && obj->type == ACPI_TYPE_BUFFER &&
-		obj->buffer.length == sizeof(u32)) {
-		tmp = *((u32 *) obj->buffer.pointer);
+	if (obj && obj->type == ACPI_TYPE_INTEGER) {
+		tmp = obj->integer.value;
 	} else {
 		tmp = 0;
 	}
@@ -109,7 +108,7 @@
 		*out = (tmp == 3) ? 1 : 0;
 		return 0;
 	case TC1100_INSTANCE_JOGDIAL:
-		*out = (tmp == 1) ? 1 : 0;
+		*out = (tmp == 1) ? 0 : 1;
 		return 0;
 	default:
 		return -ENODEV;
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index 3dad27a3..a40b075 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -3,7 +3,7 @@
  *
  *
  *  Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net>
- *  Copyright (C) 2006-2008 Henrique de Moraes Holschuh <hmh@hmh.eng.br>
+ *  Copyright (C) 2006-2009 Henrique de Moraes Holschuh <hmh@hmh.eng.br>
  *
  *  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
@@ -22,7 +22,7 @@
  */
 
 #define TPACPI_VERSION "0.22"
-#define TPACPI_SYSFS_VERSION 0x020200
+#define TPACPI_SYSFS_VERSION 0x020300
 
 /*
  *  Changelog:
@@ -54,6 +54,7 @@
 #include <linux/string.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
+#include <linux/sched.h>
 #include <linux/kthread.h>
 #include <linux/freezer.h>
 #include <linux/delay.h>
@@ -172,29 +173,26 @@
 	TPACPI_RFK_UWB_SW_ID,
 };
 
-/* Debugging */
+/* printk headers */
 #define TPACPI_LOG TPACPI_FILE ": "
-#define TPACPI_ALERT	KERN_ALERT  TPACPI_LOG
-#define TPACPI_CRIT	KERN_CRIT   TPACPI_LOG
-#define TPACPI_ERR	KERN_ERR    TPACPI_LOG
-#define TPACPI_NOTICE	KERN_NOTICE TPACPI_LOG
-#define TPACPI_INFO	KERN_INFO   TPACPI_LOG
-#define TPACPI_DEBUG	KERN_DEBUG  TPACPI_LOG
+#define TPACPI_EMERG	KERN_EMERG	TPACPI_LOG
+#define TPACPI_ALERT	KERN_ALERT	TPACPI_LOG
+#define TPACPI_CRIT	KERN_CRIT	TPACPI_LOG
+#define TPACPI_ERR	KERN_ERR	TPACPI_LOG
+#define TPACPI_WARN	KERN_WARNING	TPACPI_LOG
+#define TPACPI_NOTICE	KERN_NOTICE	TPACPI_LOG
+#define TPACPI_INFO	KERN_INFO	TPACPI_LOG
+#define TPACPI_DEBUG	KERN_DEBUG	TPACPI_LOG
 
+/* Debugging printk groups */
 #define TPACPI_DBG_ALL		0xffff
+#define TPACPI_DBG_DISCLOSETASK	0x8000
 #define TPACPI_DBG_INIT		0x0001
 #define TPACPI_DBG_EXIT		0x0002
-#define dbg_printk(a_dbg_level, format, arg...) \
-	do { if (dbg_level & a_dbg_level) \
-		printk(TPACPI_DEBUG "%s: " format, __func__ , ## arg); \
-	} while (0)
-#ifdef CONFIG_THINKPAD_ACPI_DEBUG
-#define vdbg_printk(a_dbg_level, format, arg...) \
-	dbg_printk(a_dbg_level, format, ## arg)
-static const char *str_supported(int is_supported);
-#else
-#define vdbg_printk(a_dbg_level, format, arg...)
-#endif
+#define TPACPI_DBG_RFKILL	0x0004
+#define TPACPI_DBG_HKEY		0x0008
+#define TPACPI_DBG_FAN		0x0010
+#define TPACPI_DBG_BRGHT	0x0020
 
 #define onoff(status, bit) ((status) & (1 << (bit)) ? "on" : "off")
 #define enabled(status, bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
@@ -277,7 +275,6 @@
 
 static struct {
 	u16 hotkey_mask_ff:1;
-	u16 bright_cmos_ec_unsync:1;
 } tp_warned;
 
 struct thinkpad_id_data {
@@ -326,6 +323,39 @@
 #endif
 
 
+/*************************************************************************
+ *  Debugging helpers
+ */
+
+#define dbg_printk(a_dbg_level, format, arg...) \
+	do { if (dbg_level & (a_dbg_level)) \
+		printk(TPACPI_DEBUG "%s: " format, __func__ , ## arg); \
+	} while (0)
+
+#ifdef CONFIG_THINKPAD_ACPI_DEBUG
+#define vdbg_printk dbg_printk
+static const char *str_supported(int is_supported);
+#else
+#define vdbg_printk(a_dbg_level, format, arg...) \
+	do { } while (0)
+#endif
+
+static void tpacpi_log_usertask(const char * const what)
+{
+	printk(TPACPI_DEBUG "%s: access by process with PID %d\n",
+		what, task_tgid_vnr(current));
+}
+
+#define tpacpi_disclose_usertask(what, format, arg...) \
+	do { \
+		if (unlikely( \
+		    (dbg_level & TPACPI_DBG_DISCLOSETASK) && \
+		    (tpacpi_lifecycle == TPACPI_LIFE_RUNNING))) { \
+			printk(TPACPI_DEBUG "%s: PID %d: " format, \
+				what, task_tgid_vnr(current), ## arg); \
+		} \
+	} while (0)
+
 /****************************************************************************
  ****************************************************************************
  *
@@ -989,10 +1019,13 @@
 		/* try to set the initial state as the default for the rfkill
 		 * type, since we ask the firmware to preserve it across S5 in
 		 * NVRAM */
-		rfkill_set_default(rfktype,
+		if (rfkill_set_default(rfktype,
 				(initial_state == RFKILL_STATE_UNBLOCKED) ?
 					RFKILL_STATE_UNBLOCKED :
-					RFKILL_STATE_SOFT_BLOCKED);
+					RFKILL_STATE_SOFT_BLOCKED) == -EPERM)
+			vdbg_printk(TPACPI_DBG_RFKILL,
+				    "Default state for %s cannot be changed\n",
+				    name);
 	}
 
 	*rfk = rfkill_allocate(&tpacpi_pdev->dev, rfktype);
@@ -1020,6 +1053,21 @@
 	return 0;
 }
 
+static void printk_deprecated_attribute(const char * const what,
+					const char * const details)
+{
+	tpacpi_log_usertask("deprecated sysfs attribute");
+	printk(TPACPI_WARN "WARNING: sysfs attribute %s is deprecated and "
+		"will be removed. %s\n",
+		what, details);
+}
+
+static void printk_deprecated_rfkill_attribute(const char * const what)
+{
+	printk_deprecated_attribute(what,
+			"Please switch to generic rfkill before year 2010");
+}
+
 /*************************************************************************
  * thinkpad-acpi driver attributes
  */
@@ -1382,7 +1430,6 @@
 
 static int hotkey_autosleep_ack;
 
-static int hotkey_orig_status;
 static u32 hotkey_orig_mask;
 static u32 hotkey_all_mask;
 static u32 hotkey_reserved_mask;
@@ -1529,9 +1576,9 @@
 	return 0;
 }
 
-static int hotkey_status_set(int status)
+static int hotkey_status_set(bool enable)
 {
-	if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", status))
+	if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", enable ? 1 : 0))
 		return -EIO;
 
 	return 0;
@@ -1847,6 +1894,9 @@
 {
 	int res, status;
 
+	printk_deprecated_attribute("hotkey_enable",
+			"Hotkey reporting is always enabled");
+
 	res = hotkey_status_get(&status);
 	if (res)
 		return res;
@@ -1859,14 +1909,17 @@
 			    const char *buf, size_t count)
 {
 	unsigned long t;
-	int res;
+
+	printk_deprecated_attribute("hotkey_enable",
+			"Hotkeys can be disabled through hotkey_mask");
 
 	if (parse_strtoul(buf, 1, &t))
 		return -EINVAL;
 
-	res = hotkey_status_set(t);
+	if (t == 0)
+		return -EPERM;
 
-	return (res) ? res : count;
+	return count;
 }
 
 static struct device_attribute dev_attr_hotkey_enable =
@@ -1910,6 +1963,8 @@
 
 	mutex_unlock(&hotkey_mutex);
 
+	tpacpi_disclose_usertask("hotkey_mask", "set to 0x%08lx\n", t);
+
 	return (res) ? res : count;
 }
 
@@ -1922,7 +1977,7 @@
 			   struct device_attribute *attr,
 			   char *buf)
 {
-	return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_orig_status);
+	return sprintf(buf, "0\n");
 }
 
 static struct device_attribute dev_attr_hotkey_bios_enabled =
@@ -1996,6 +2051,8 @@
 
 	mutex_unlock(&hotkey_mutex);
 
+	tpacpi_disclose_usertask("hotkey_source_mask", "set to 0x%08lx\n", t);
+
 	return count;
 }
 
@@ -2028,6 +2085,8 @@
 	hotkey_poll_setup(1);
 	mutex_unlock(&hotkey_mutex);
 
+	tpacpi_disclose_usertask("hotkey_poll_freq", "set to %lu\n", t);
+
 	return count;
 }
 
@@ -2197,11 +2256,11 @@
 	kfree(hotkey_keycode_map);
 
 	if (tp_features.hotkey) {
-		dbg_printk(TPACPI_DBG_EXIT,
+		dbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_HKEY,
 			   "restoring original hot key mask\n");
 		/* no short-circuit boolean operator below! */
 		if ((hotkey_mask_set(hotkey_orig_mask) |
-		     hotkey_status_set(hotkey_orig_status)) != 0)
+		     hotkey_status_set(false)) != 0)
 			printk(TPACPI_ERR
 			       "failed to restore hot key mask "
 			       "to BIOS defaults\n");
@@ -2327,7 +2386,8 @@
 	int status;
 	int hkeyv;
 
-	vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n");
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+			"initializing hotkey subdriver\n");
 
 	BUG_ON(!tpacpi_inputdev);
 	BUG_ON(tpacpi_inputdev->open != NULL ||
@@ -2344,7 +2404,8 @@
 	/* hotkey not supported on 570 */
 	tp_features.hotkey = hkey_handle != NULL;
 
-	vdbg_printk(TPACPI_DBG_INIT, "hotkeys are %s\n",
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+		"hotkeys are %s\n",
 		str_supported(tp_features.hotkey));
 
 	if (!tp_features.hotkey)
@@ -2376,10 +2437,14 @@
 			 * T4x, X31, and later
 			 */
 			tp_features.hotkey_mask = 1;
+			vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+				"firmware HKEY interface version: 0x%x\n",
+				hkeyv);
 		}
 	}
 
-	vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n",
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+		"hotkey masks are %s\n",
 		str_supported(tp_features.hotkey_mask));
 
 	if (tp_features.hotkey_mask) {
@@ -2396,10 +2461,6 @@
 
 	/* hotkey_source_mask *must* be zero for
 	 * the first hotkey_mask_get */
-	res = hotkey_status_get(&hotkey_orig_status);
-	if (res)
-		goto err_exit;
-
 	if (tp_features.hotkey_mask) {
 		res = hotkey_mask_get();
 		if (res)
@@ -2422,7 +2483,7 @@
 		hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK;
 	}
 
-	vdbg_printk(TPACPI_DBG_INIT,
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
 		    "hotkey source mask 0x%08x, polling freq %d\n",
 		    hotkey_source_mask, hotkey_poll_freq);
 #endif
@@ -2476,12 +2537,12 @@
 	}
 
 	if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) {
-		dbg_printk(TPACPI_DBG_INIT,
+		dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
 			   "using Lenovo default hot key map\n");
 		memcpy(hotkey_keycode_map, &lenovo_keycode_map,
 			TPACPI_HOTKEY_MAP_SIZE);
 	} else {
-		dbg_printk(TPACPI_DBG_INIT,
+		dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
 			   "using IBM default hot key map\n");
 		memcpy(hotkey_keycode_map, &ibm_keycode_map,
 			TPACPI_HOTKEY_MAP_SIZE);
@@ -2538,8 +2599,9 @@
 			| (1 << TP_ACPI_HOTKEYSCAN_FNEND);
 	}
 
-	dbg_printk(TPACPI_DBG_INIT, "enabling hot key handling\n");
-	res = hotkey_status_set(1);
+	dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+			"enabling firmware HKEY event interface...\n");
+	res = hotkey_status_set(true);
 	if (res) {
 		hotkey_exit();
 		return res;
@@ -2552,8 +2614,8 @@
 		return res;
 	}
 
-	dbg_printk(TPACPI_DBG_INIT,
-			"legacy hot key reporting over procfs %s\n",
+	dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+			"legacy ibm/hotkey event reporting over procfs %s\n",
 			(hotkey_report_mode < 2) ?
 				"enabled" : "disabled");
 
@@ -2884,9 +2946,17 @@
 	return len;
 }
 
+static void hotkey_enabledisable_warn(void)
+{
+	tpacpi_log_usertask("procfs hotkey enable/disable");
+	WARN(1, TPACPI_WARN
+	     "hotkey enable/disable functionality has been "
+	     "removed from the driver. Hotkeys are always enabled.\n");
+}
+
 static int hotkey_write(char *buf)
 {
-	int res, status;
+	int res;
 	u32 mask;
 	char *cmd;
 
@@ -2896,17 +2966,16 @@
 	if (mutex_lock_killable(&hotkey_mutex))
 		return -ERESTARTSYS;
 
-	status = -1;
 	mask = hotkey_mask;
 
 	res = 0;
 	while ((cmd = next_cmd(&buf))) {
 		if (strlencmp(cmd, "enable") == 0) {
-			status = 1;
+			hotkey_enabledisable_warn();
 		} else if (strlencmp(cmd, "disable") == 0) {
-			status = 0;
+			hotkey_enabledisable_warn();
+			res = -EPERM;
 		} else if (strlencmp(cmd, "reset") == 0) {
-			status = hotkey_orig_status;
 			mask = hotkey_orig_mask;
 		} else if (sscanf(cmd, "0x%x", &mask) == 1) {
 			/* mask set */
@@ -2917,8 +2986,10 @@
 			goto errexit;
 		}
 	}
-	if (status != -1)
-		res = hotkey_status_set(status);
+
+	if (!res)
+		tpacpi_disclose_usertask("procfs hotkey",
+			"set mask to 0x%08x\n", mask);
 
 	if (!res && mask != hotkey_mask)
 		res = hotkey_mask_set(mask);
@@ -2971,13 +3042,17 @@
 	TP_ACPI_BLTH_SAVE_STATE		= 0x05, /* Save state for S4/S5 */
 };
 
+#define TPACPI_RFK_BLUETOOTH_SW_NAME	"tpacpi_bluetooth_sw"
+
 static struct rfkill *tpacpi_bluetooth_rfkill;
 
 static void bluetooth_suspend(pm_message_t state)
 {
 	/* Try to make sure radio will resume powered off */
-	acpi_evalf(NULL, NULL, "\\BLTH", "vd",
-		   TP_ACPI_BLTH_PWR_OFF_ON_RESUME);
+	if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd",
+		   TP_ACPI_BLTH_PWR_OFF_ON_RESUME))
+		vdbg_printk(TPACPI_DBG_RFKILL,
+			"bluetooth power down on resume request failed\n");
 }
 
 static int bluetooth_get_radiosw(void)
@@ -3015,6 +3090,10 @@
 	if (status < 0)
 		return;
 	rfkill_force_state(tpacpi_bluetooth_rfkill, status);
+
+	vdbg_printk(TPACPI_DBG_RFKILL,
+		"forced rfkill state to %d\n",
+		status);
 }
 
 static int bluetooth_set_radiosw(int radio_on, int update_rfk)
@@ -3030,6 +3109,9 @@
 	    && radio_on)
 		return -EPERM;
 
+	vdbg_printk(TPACPI_DBG_RFKILL,
+		"will %s bluetooth\n", radio_on ? "enable" : "disable");
+
 #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
 	if (dbg_bluetoothemul) {
 		tpacpi_bluetooth_emulstate = !!radio_on;
@@ -3060,6 +3142,8 @@
 {
 	int status;
 
+	printk_deprecated_rfkill_attribute("bluetooth_enable");
+
 	status = bluetooth_get_radiosw();
 	if (status < 0)
 		return status;
@@ -3075,9 +3159,13 @@
 	unsigned long t;
 	int res;
 
+	printk_deprecated_rfkill_attribute("bluetooth_enable");
+
 	if (parse_strtoul(buf, 1, &t))
 		return -EINVAL;
 
+	tpacpi_disclose_usertask("bluetooth_enable", "set to %ld\n", t);
+
 	res = bluetooth_set_radiosw(t, 1);
 
 	return (res) ? res : count;
@@ -3111,6 +3199,8 @@
 
 static int tpacpi_bluetooth_rfk_set(void *data, enum rfkill_state state)
 {
+	dbg_printk(TPACPI_DBG_RFKILL,
+		   "request to change radio state to %d\n", state);
 	return bluetooth_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
 }
 
@@ -3121,6 +3211,9 @@
 			TP_ACPI_BLTH_SAVE_STATE))
 		printk(TPACPI_NOTICE
 			"failed to save bluetooth state to NVRAM\n");
+	else
+		vdbg_printk(TPACPI_DBG_RFKILL,
+			"bluestooth state saved to NVRAM\n");
 }
 
 static void bluetooth_exit(void)
@@ -3139,7 +3232,8 @@
 	int res;
 	int status = 0;
 
-	vdbg_printk(TPACPI_DBG_INIT, "initializing bluetooth subdriver\n");
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+			"initializing bluetooth subdriver\n");
 
 	TPACPI_ACPIHANDLE_INIT(hkey);
 
@@ -3148,7 +3242,8 @@
 	tp_features.bluetooth = hkey_handle &&
 	    acpi_evalf(hkey_handle, &status, "GBDC", "qd");
 
-	vdbg_printk(TPACPI_DBG_INIT, "bluetooth is %s, status 0x%02x\n",
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+		"bluetooth is %s, status 0x%02x\n",
 		str_supported(tp_features.bluetooth),
 		status);
 
@@ -3163,7 +3258,7 @@
 	    !(status & TP_ACPI_BLUETOOTH_HWPRESENT)) {
 		/* no bluetooth hardware present in system */
 		tp_features.bluetooth = 0;
-		dbg_printk(TPACPI_DBG_INIT,
+		dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
 			   "bluetooth hardware not installed\n");
 	}
 
@@ -3178,7 +3273,7 @@
 	res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID,
 				&tpacpi_bluetooth_rfkill,
 				RFKILL_TYPE_BLUETOOTH,
-				"tpacpi_bluetooth_sw",
+				TPACPI_RFK_BLUETOOTH_SW_NAME,
 				true,
 				tpacpi_bluetooth_rfk_set,
 				tpacpi_bluetooth_rfk_get);
@@ -3211,19 +3306,27 @@
 static int bluetooth_write(char *buf)
 {
 	char *cmd;
+	int state = -1;
 
 	if (!tp_features.bluetooth)
 		return -ENODEV;
 
 	while ((cmd = next_cmd(&buf))) {
 		if (strlencmp(cmd, "enable") == 0) {
-			bluetooth_set_radiosw(1, 1);
+			state = 1;
 		} else if (strlencmp(cmd, "disable") == 0) {
-			bluetooth_set_radiosw(0, 1);
+			state = 0;
 		} else
 			return -EINVAL;
 	}
 
+	if (state != -1) {
+		tpacpi_disclose_usertask("procfs bluetooth",
+			"attempt to %s\n",
+			state ? "enable" : "disable");
+		bluetooth_set_radiosw(state, 1);
+	}
+
 	return 0;
 }
 
@@ -3248,13 +3351,17 @@
 						   off / last state */
 };
 
+#define TPACPI_RFK_WWAN_SW_NAME		"tpacpi_wwan_sw"
+
 static struct rfkill *tpacpi_wan_rfkill;
 
 static void wan_suspend(pm_message_t state)
 {
 	/* Try to make sure radio will resume powered off */
-	acpi_evalf(NULL, NULL, "\\WGSV", "qvd",
-		   TP_ACPI_WGSV_PWR_OFF_ON_RESUME);
+	if (!acpi_evalf(NULL, NULL, "\\WGSV", "qvd",
+		   TP_ACPI_WGSV_PWR_OFF_ON_RESUME))
+		vdbg_printk(TPACPI_DBG_RFKILL,
+			"WWAN power down on resume request failed\n");
 }
 
 static int wan_get_radiosw(void)
@@ -3292,6 +3399,10 @@
 	if (status < 0)
 		return;
 	rfkill_force_state(tpacpi_wan_rfkill, status);
+
+	vdbg_printk(TPACPI_DBG_RFKILL,
+		"forced rfkill state to %d\n",
+		status);
 }
 
 static int wan_set_radiosw(int radio_on, int update_rfk)
@@ -3307,6 +3418,9 @@
 	    && radio_on)
 		return -EPERM;
 
+	vdbg_printk(TPACPI_DBG_RFKILL,
+		"will %s WWAN\n", radio_on ? "enable" : "disable");
+
 #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
 	if (dbg_wwanemul) {
 		tpacpi_wwan_emulstate = !!radio_on;
@@ -3337,6 +3451,8 @@
 {
 	int status;
 
+	printk_deprecated_rfkill_attribute("wwan_enable");
+
 	status = wan_get_radiosw();
 	if (status < 0)
 		return status;
@@ -3352,9 +3468,13 @@
 	unsigned long t;
 	int res;
 
+	printk_deprecated_rfkill_attribute("wwan_enable");
+
 	if (parse_strtoul(buf, 1, &t))
 		return -EINVAL;
 
+	tpacpi_disclose_usertask("wwan_enable", "set to %ld\n", t);
+
 	res = wan_set_radiosw(t, 1);
 
 	return (res) ? res : count;
@@ -3388,6 +3508,8 @@
 
 static int tpacpi_wan_rfk_set(void *data, enum rfkill_state state)
 {
+	dbg_printk(TPACPI_DBG_RFKILL,
+		   "request to change radio state to %d\n", state);
 	return wan_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
 }
 
@@ -3398,6 +3520,9 @@
 			TP_ACPI_WGSV_SAVE_STATE))
 		printk(TPACPI_NOTICE
 			"failed to save WWAN state to NVRAM\n");
+	else
+		vdbg_printk(TPACPI_DBG_RFKILL,
+			"WWAN state saved to NVRAM\n");
 }
 
 static void wan_exit(void)
@@ -3416,14 +3541,16 @@
 	int res;
 	int status = 0;
 
-	vdbg_printk(TPACPI_DBG_INIT, "initializing wan subdriver\n");
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+			"initializing wan subdriver\n");
 
 	TPACPI_ACPIHANDLE_INIT(hkey);
 
 	tp_features.wan = hkey_handle &&
 	    acpi_evalf(hkey_handle, &status, "GWAN", "qd");
 
-	vdbg_printk(TPACPI_DBG_INIT, "wan is %s, status 0x%02x\n",
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+		"wan is %s, status 0x%02x\n",
 		str_supported(tp_features.wan),
 		status);
 
@@ -3438,7 +3565,7 @@
 	    !(status & TP_ACPI_WANCARD_HWPRESENT)) {
 		/* no wan hardware present in system */
 		tp_features.wan = 0;
-		dbg_printk(TPACPI_DBG_INIT,
+		dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
 			   "wan hardware not installed\n");
 	}
 
@@ -3453,7 +3580,7 @@
 	res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID,
 				&tpacpi_wan_rfkill,
 				RFKILL_TYPE_WWAN,
-				"tpacpi_wwan_sw",
+				TPACPI_RFK_WWAN_SW_NAME,
 				true,
 				tpacpi_wan_rfk_set,
 				tpacpi_wan_rfk_get);
@@ -3471,6 +3598,8 @@
 	int len = 0;
 	int status = wan_get_radiosw();
 
+	tpacpi_disclose_usertask("procfs wan", "read");
+
 	if (!tp_features.wan)
 		len += sprintf(p + len, "status:\t\tnot supported\n");
 	else {
@@ -3486,19 +3615,27 @@
 static int wan_write(char *buf)
 {
 	char *cmd;
+	int state = -1;
 
 	if (!tp_features.wan)
 		return -ENODEV;
 
 	while ((cmd = next_cmd(&buf))) {
 		if (strlencmp(cmd, "enable") == 0) {
-			wan_set_radiosw(1, 1);
+			state = 1;
 		} else if (strlencmp(cmd, "disable") == 0) {
-			wan_set_radiosw(0, 1);
+			state = 0;
 		} else
 			return -EINVAL;
 	}
 
+	if (state != -1) {
+		tpacpi_disclose_usertask("procfs wan",
+			"attempt to %s\n",
+			state ? "enable" : "disable");
+		wan_set_radiosw(state, 1);
+	}
+
 	return 0;
 }
 
@@ -3521,6 +3658,8 @@
 	TP_ACPI_UWB_RADIOSSW	= 0x02,	/* UWB radio enabled */
 };
 
+#define TPACPI_RFK_UWB_SW_NAME	"tpacpi_uwb_sw"
+
 static struct rfkill *tpacpi_uwb_rfkill;
 
 static int uwb_get_radiosw(void)
@@ -3558,6 +3697,10 @@
 	if (status < 0)
 		return;
 	rfkill_force_state(tpacpi_uwb_rfkill, status);
+
+	vdbg_printk(TPACPI_DBG_RFKILL,
+		"forced rfkill state to %d\n",
+		status);
 }
 
 static int uwb_set_radiosw(int radio_on, int update_rfk)
@@ -3573,6 +3716,9 @@
 	    && radio_on)
 		return -EPERM;
 
+	vdbg_printk(TPACPI_DBG_RFKILL,
+			"will %s UWB\n", radio_on ? "enable" : "disable");
+
 #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
 	if (dbg_uwbemul) {
 		tpacpi_uwb_emulstate = !!radio_on;
@@ -3607,6 +3753,8 @@
 
 static int tpacpi_uwb_rfk_set(void *data, enum rfkill_state state)
 {
+	dbg_printk(TPACPI_DBG_RFKILL,
+		   "request to change radio state to %d\n", state);
 	return uwb_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
 }
 
@@ -3621,14 +3769,16 @@
 	int res;
 	int status = 0;
 
-	vdbg_printk(TPACPI_DBG_INIT, "initializing uwb subdriver\n");
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+			"initializing uwb subdriver\n");
 
 	TPACPI_ACPIHANDLE_INIT(hkey);
 
 	tp_features.uwb = hkey_handle &&
 	    acpi_evalf(hkey_handle, &status, "GUWB", "qd");
 
-	vdbg_printk(TPACPI_DBG_INIT, "uwb is %s, status 0x%02x\n",
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+		"uwb is %s, status 0x%02x\n",
 		str_supported(tp_features.uwb),
 		status);
 
@@ -3653,7 +3803,7 @@
 	res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID,
 				&tpacpi_uwb_rfkill,
 				RFKILL_TYPE_UWB,
-				"tpacpi_uwb_sw",
+				TPACPI_RFK_UWB_SW_NAME,
 				false,
 				tpacpi_uwb_rfk_set,
 				tpacpi_uwb_rfk_get);
@@ -4602,6 +4752,16 @@
 	"tpacpi::unknown_led",
 	"tpacpi::standby",
 };
+#define TPACPI_SAFE_LEDS	0x0081U
+
+static inline bool tpacpi_is_led_restricted(const unsigned int led)
+{
+#ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS
+	return false;
+#else
+	return (TPACPI_SAFE_LEDS & (1 << led)) == 0;
+#endif
+}
 
 static int led_get_status(const unsigned int led)
 {
@@ -4639,16 +4799,20 @@
 	switch (led_supported) {
 	case TPACPI_LED_570:
 		/* 570 */
-		if (led > 7)
+		if (unlikely(led > 7))
 			return -EINVAL;
+		if (unlikely(tpacpi_is_led_restricted(led)))
+			return -EPERM;
 		if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
 				(1 << led), led_sled_arg1[ledstatus]))
 			rc = -EIO;
 		break;
 	case TPACPI_LED_OLD:
 		/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */
-		if (led > 7)
+		if (unlikely(led > 7))
 			return -EINVAL;
+		if (unlikely(tpacpi_is_led_restricted(led)))
+			return -EPERM;
 		rc = ec_write(TPACPI_LED_EC_HLMS, (1 << led));
 		if (rc >= 0)
 			rc = ec_write(TPACPI_LED_EC_HLBL,
@@ -4659,6 +4823,10 @@
 		break;
 	case TPACPI_LED_NEW:
 		/* all others */
+		if (unlikely(led >= TPACPI_LED_NUMLEDS))
+			return -EINVAL;
+		if (unlikely(tpacpi_is_led_restricted(led)))
+			return -EPERM;
 		if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
 				led, led_led_arg1[ledstatus]))
 			rc = -EIO;
@@ -4751,6 +4919,30 @@
 	kfree(tpacpi_leds);
 }
 
+static int __init tpacpi_init_led(unsigned int led)
+{
+	int rc;
+
+	tpacpi_leds[led].led = led;
+
+	tpacpi_leds[led].led_classdev.brightness_set = &led_sysfs_set;
+	tpacpi_leds[led].led_classdev.blink_set = &led_sysfs_blink_set;
+	if (led_supported == TPACPI_LED_570)
+		tpacpi_leds[led].led_classdev.brightness_get =
+						&led_sysfs_get;
+
+	tpacpi_leds[led].led_classdev.name = tpacpi_led_names[led];
+
+	INIT_WORK(&tpacpi_leds[led].work, led_set_status_worker);
+
+	rc = led_classdev_register(&tpacpi_pdev->dev,
+				&tpacpi_leds[led].led_classdev);
+	if (rc < 0)
+		tpacpi_leds[led].led_classdev.name = NULL;
+
+	return rc;
+}
+
 static int __init led_init(struct ibm_init_struct *iibm)
 {
 	unsigned int i;
@@ -4784,27 +4976,21 @@
 	}
 
 	for (i = 0; i < TPACPI_LED_NUMLEDS; i++) {
-		tpacpi_leds[i].led = i;
-
-		tpacpi_leds[i].led_classdev.brightness_set = &led_sysfs_set;
-		tpacpi_leds[i].led_classdev.blink_set = &led_sysfs_blink_set;
-		if (led_supported == TPACPI_LED_570)
-			tpacpi_leds[i].led_classdev.brightness_get =
-							&led_sysfs_get;
-
-		tpacpi_leds[i].led_classdev.name = tpacpi_led_names[i];
-
-		INIT_WORK(&tpacpi_leds[i].work, led_set_status_worker);
-
-		rc = led_classdev_register(&tpacpi_pdev->dev,
-					   &tpacpi_leds[i].led_classdev);
-		if (rc < 0) {
-			tpacpi_leds[i].led_classdev.name = NULL;
-			led_exit();
-			return rc;
+		if (!tpacpi_is_led_restricted(i)) {
+			rc = tpacpi_init_led(i);
+			if (rc < 0) {
+				led_exit();
+				return rc;
+			}
 		}
 	}
 
+#ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS
+	if (led_supported != TPACPI_LED_NONE)
+		printk(TPACPI_NOTICE
+			"warning: userspace override of important "
+			"firmware LEDs is enabled\n");
+#endif
 	return (led_supported != TPACPI_LED_NONE)? 0 : 1;
 }
 
@@ -5340,6 +5526,20 @@
 
 #define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen"
 
+/*
+ * ThinkPads can read brightness from two places: EC HBRV (0x31), or
+ * CMOS NVRAM byte 0x5E, bits 0-3.
+ *
+ * EC HBRV (0x31) has the following layout
+ *   Bit 7: unknown function
+ *   Bit 6: unknown function
+ *   Bit 5: Z: honour scale changes, NZ: ignore scale changes
+ *   Bit 4: must be set to zero to avoid problems
+ *   Bit 3-0: backlight brightness level
+ *
+ * brightness_get_raw returns status data in the HBRV layout
+ */
+
 enum {
 	TP_EC_BACKLIGHT = 0x31,
 
@@ -5349,108 +5549,164 @@
 	TP_EC_BACKLIGHT_MAPSW = 0x20,
 };
 
+enum tpacpi_brightness_access_mode {
+	TPACPI_BRGHT_MODE_AUTO = 0,	/* Not implemented yet */
+	TPACPI_BRGHT_MODE_EC,		/* EC control */
+	TPACPI_BRGHT_MODE_UCMS_STEP,	/* UCMS step-based control */
+	TPACPI_BRGHT_MODE_ECNVRAM,	/* EC control w/ NVRAM store */
+	TPACPI_BRGHT_MODE_MAX
+};
+
 static struct backlight_device *ibm_backlight_device;
-static int brightness_mode;
+
+static enum tpacpi_brightness_access_mode brightness_mode =
+		TPACPI_BRGHT_MODE_MAX;
+
 static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */
 
 static struct mutex brightness_mutex;
 
-/*
- * ThinkPads can read brightness from two places: EC 0x31, or
- * CMOS NVRAM byte 0x5E, bits 0-3.
- *
- * EC 0x31 has the following layout
- *   Bit 7: unknown function
- *   Bit 6: unknown function
- *   Bit 5: Z: honour scale changes, NZ: ignore scale changes
- *   Bit 4: must be set to zero to avoid problems
- *   Bit 3-0: backlight brightness level
- *
- * brightness_get_raw returns status data in the EC 0x31 layout
- */
-static int brightness_get_raw(int *status)
+/* NVRAM brightness access,
+ * call with brightness_mutex held! */
+static unsigned int tpacpi_brightness_nvram_get(void)
 {
-	u8 lec = 0, lcmos = 0, level = 0;
+	u8 lnvram;
 
-	if (brightness_mode & 1) {
-		if (!acpi_ec_read(TP_EC_BACKLIGHT, &lec))
-			return -EIO;
-		level = lec & TP_EC_BACKLIGHT_LVLMSK;
-	};
-	if (brightness_mode & 2) {
-		lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
-			 & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
-			>> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
-		lcmos &= (tp_features.bright_16levels)? 0x0f : 0x07;
-		level = lcmos;
-	}
+	lnvram = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
+		  & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
+		  >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
+	lnvram &= (tp_features.bright_16levels) ? 0x0f : 0x07;
 
-	if (brightness_mode == 3) {
-		*status = lec;	/* Prefer EC, CMOS is just a backing store */
-		lec &= TP_EC_BACKLIGHT_LVLMSK;
-		if (lec == lcmos)
-			tp_warned.bright_cmos_ec_unsync = 0;
-		else {
-			if (!tp_warned.bright_cmos_ec_unsync) {
-				printk(TPACPI_ERR
-					"CMOS NVRAM (%u) and EC (%u) do not "
-					"agree on display brightness level\n",
-					(unsigned int) lcmos,
-					(unsigned int) lec);
-				tp_warned.bright_cmos_ec_unsync = 1;
-			}
+	return lnvram;
+}
+
+static void tpacpi_brightness_checkpoint_nvram(void)
+{
+	u8 lec = 0;
+	u8 b_nvram;
+
+	if (brightness_mode != TPACPI_BRGHT_MODE_ECNVRAM)
+		return;
+
+	vdbg_printk(TPACPI_DBG_BRGHT,
+		"trying to checkpoint backlight level to NVRAM...\n");
+
+	if (mutex_lock_killable(&brightness_mutex) < 0)
+		return;
+
+	if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
+		goto unlock;
+	lec &= TP_EC_BACKLIGHT_LVLMSK;
+	b_nvram = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
+
+	if (lec != ((b_nvram & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
+			     >> TP_NVRAM_POS_LEVEL_BRIGHTNESS)) {
+		/* NVRAM needs update */
+		b_nvram &= ~(TP_NVRAM_MASK_LEVEL_BRIGHTNESS <<
+				TP_NVRAM_POS_LEVEL_BRIGHTNESS);
+		b_nvram |= lec;
+		nvram_write_byte(b_nvram, TP_NVRAM_ADDR_BRIGHTNESS);
+		dbg_printk(TPACPI_DBG_BRGHT,
+			   "updated NVRAM backlight level to %u (0x%02x)\n",
+			   (unsigned int) lec, (unsigned int) b_nvram);
+	} else
+		vdbg_printk(TPACPI_DBG_BRGHT,
+			   "NVRAM backlight level already is %u (0x%02x)\n",
+			   (unsigned int) lec, (unsigned int) b_nvram);
+
+unlock:
+	mutex_unlock(&brightness_mutex);
+}
+
+
+/* call with brightness_mutex held! */
+static int tpacpi_brightness_get_raw(int *status)
+{
+	u8 lec = 0;
+
+	switch (brightness_mode) {
+	case TPACPI_BRGHT_MODE_UCMS_STEP:
+		*status = tpacpi_brightness_nvram_get();
+		return 0;
+	case TPACPI_BRGHT_MODE_EC:
+	case TPACPI_BRGHT_MODE_ECNVRAM:
+		if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
 			return -EIO;
-		}
-	} else {
-		*status = level;
+		*status = lec;
+		return 0;
+	default:
+		return -ENXIO;
 	}
+}
+
+/* call with brightness_mutex held! */
+/* do NOT call with illegal backlight level value */
+static int tpacpi_brightness_set_ec(unsigned int value)
+{
+	u8 lec = 0;
+
+	if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
+		return -EIO;
+
+	if (unlikely(!acpi_ec_write(TP_EC_BACKLIGHT,
+				(lec & TP_EC_BACKLIGHT_CMDMSK) |
+				(value & TP_EC_BACKLIGHT_LVLMSK))))
+		return -EIO;
+
+	return 0;
+}
+
+/* call with brightness_mutex held! */
+static int tpacpi_brightness_set_ucmsstep(unsigned int value)
+{
+	int cmos_cmd, inc;
+	unsigned int current_value, i;
+
+	current_value = tpacpi_brightness_nvram_get();
+
+	if (value == current_value)
+		return 0;
+
+	cmos_cmd = (value > current_value) ?
+			TP_CMOS_BRIGHTNESS_UP :
+			TP_CMOS_BRIGHTNESS_DOWN;
+	inc = (value > current_value) ? 1 : -1;
+
+	for (i = current_value; i != value; i += inc)
+		if (issue_thinkpad_cmos_command(cmos_cmd))
+			return -EIO;
 
 	return 0;
 }
 
 /* May return EINTR which can always be mapped to ERESTARTSYS */
-static int brightness_set(int value)
+static int brightness_set(unsigned int value)
 {
-	int cmos_cmd, inc, i, res;
-	int current_value;
-	int command_bits;
+	int res;
 
 	if (value > ((tp_features.bright_16levels)? 15 : 7) ||
 	    value < 0)
 		return -EINVAL;
 
+	vdbg_printk(TPACPI_DBG_BRGHT,
+			"set backlight level to %d\n", value);
+
 	res = mutex_lock_killable(&brightness_mutex);
 	if (res < 0)
 		return res;
 
-	res = brightness_get_raw(&current_value);
-	if (res < 0)
-		goto errout;
-
-	command_bits = current_value & TP_EC_BACKLIGHT_CMDMSK;
-	current_value &= TP_EC_BACKLIGHT_LVLMSK;
-
-	cmos_cmd = value > current_value ?
-			TP_CMOS_BRIGHTNESS_UP :
-			TP_CMOS_BRIGHTNESS_DOWN;
-	inc = (value > current_value)? 1 : -1;
-
-	res = 0;
-	for (i = current_value; i != value; i += inc) {
-		if ((brightness_mode & 2) &&
-		    issue_thinkpad_cmos_command(cmos_cmd)) {
-			res = -EIO;
-			goto errout;
-		}
-		if ((brightness_mode & 1) &&
-		    !acpi_ec_write(TP_EC_BACKLIGHT,
-				   (i + inc) | command_bits)) {
-			res = -EIO;
-			goto errout;;
-		}
+	switch (brightness_mode) {
+	case TPACPI_BRGHT_MODE_EC:
+	case TPACPI_BRGHT_MODE_ECNVRAM:
+		res = tpacpi_brightness_set_ec(value);
+		break;
+	case TPACPI_BRGHT_MODE_UCMS_STEP:
+		res = tpacpi_brightness_set_ucmsstep(value);
+		break;
+	default:
+		res = -ENXIO;
 	}
 
-errout:
 	mutex_unlock(&brightness_mutex);
 	return res;
 }
@@ -5459,21 +5715,34 @@
 
 static int brightness_update_status(struct backlight_device *bd)
 {
-	/* it is the backlight class's job (caller) to handle
-	 * EINTR and other errors properly */
-	return brightness_set(
+	unsigned int level =
 		(bd->props.fb_blank == FB_BLANK_UNBLANK &&
 		 bd->props.power == FB_BLANK_UNBLANK) ?
-				bd->props.brightness : 0);
+				bd->props.brightness : 0;
+
+	dbg_printk(TPACPI_DBG_BRGHT,
+			"backlight: attempt to set level to %d\n",
+			level);
+
+	/* it is the backlight class's job (caller) to handle
+	 * EINTR and other errors properly */
+	return brightness_set(level);
 }
 
 static int brightness_get(struct backlight_device *bd)
 {
 	int status, res;
 
-	res = brightness_get_raw(&status);
+	res = mutex_lock_killable(&brightness_mutex);
 	if (res < 0)
-		return 0; /* FIXME: teach backlight about error handling */
+		return 0;
+
+	res = tpacpi_brightness_get_raw(&status);
+
+	mutex_unlock(&brightness_mutex);
+
+	if (res < 0)
+		return 0;
 
 	return status & TP_EC_BACKLIGHT_LVLMSK;
 }
@@ -5523,7 +5792,7 @@
 	}
 
 	if (!brightness_enable) {
-		dbg_printk(TPACPI_DBG_INIT,
+		dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
 			   "brightness support disabled by "
 			   "module parameter\n");
 		return 1;
@@ -5538,20 +5807,38 @@
 	if (b == 16)
 		tp_features.bright_16levels = 1;
 
-	if (!brightness_mode) {
-		if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO)
-			brightness_mode = 2;
-		else
-			brightness_mode = 3;
-
-		dbg_printk(TPACPI_DBG_INIT, "selected brightness_mode=%d\n",
-			brightness_mode);
-	}
-
-	if (brightness_mode > 3)
+	/*
+	 * Check for module parameter bogosity, note that we
+	 * init brightness_mode to TPACPI_BRGHT_MODE_MAX in order to be
+	 * able to detect "unspecified"
+	 */
+	if (brightness_mode > TPACPI_BRGHT_MODE_MAX)
 		return -EINVAL;
 
-	if (brightness_get_raw(&b) < 0)
+	/* TPACPI_BRGHT_MODE_AUTO not implemented yet, just use default */
+	if (brightness_mode == TPACPI_BRGHT_MODE_AUTO ||
+	    brightness_mode == TPACPI_BRGHT_MODE_MAX) {
+		if (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) {
+			/*
+			 * IBM models that define HBRV probably have
+			 * EC-based backlight level control
+			 */
+			if (acpi_evalf(ec_handle, NULL, "HBRV", "qd"))
+				/* T40-T43, R50-R52, R50e, R51e, X31-X41 */
+				brightness_mode = TPACPI_BRGHT_MODE_ECNVRAM;
+			else
+				/* all other IBM ThinkPads */
+				brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP;
+		} else
+			/* All Lenovo ThinkPads */
+			brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP;
+
+		dbg_printk(TPACPI_DBG_BRGHT,
+			   "selected brightness_mode=%d\n",
+			   brightness_mode);
+	}
+
+	if (tpacpi_brightness_get_raw(&b) < 0)
 		return 1;
 
 	if (tp_features.bright_16levels)
@@ -5565,7 +5852,8 @@
 		printk(TPACPI_ERR "Could not register backlight device\n");
 		return PTR_ERR(ibm_backlight_device);
 	}
-	vdbg_printk(TPACPI_DBG_INIT, "brightness is supported\n");
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
+			"brightness is supported\n");
 
 	ibm_backlight_device->props.max_brightness =
 				(tp_features.bright_16levels)? 15 : 7;
@@ -5575,13 +5863,25 @@
 	return 0;
 }
 
+static void brightness_suspend(pm_message_t state)
+{
+	tpacpi_brightness_checkpoint_nvram();
+}
+
+static void brightness_shutdown(void)
+{
+	tpacpi_brightness_checkpoint_nvram();
+}
+
 static void brightness_exit(void)
 {
 	if (ibm_backlight_device) {
-		vdbg_printk(TPACPI_DBG_EXIT,
+		vdbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_BRGHT,
 			    "calling backlight_device_unregister()\n");
 		backlight_device_unregister(ibm_backlight_device);
 	}
+
+	tpacpi_brightness_checkpoint_nvram();
 }
 
 static int brightness_read(char *p)
@@ -5628,6 +5928,9 @@
 			return -EINVAL;
 	}
 
+	tpacpi_disclose_usertask("procfs brightness",
+			"set level to %d\n", level);
+
 	/*
 	 * Now we know what the final level should be, so we try to set it.
 	 * Doing it this way makes the syscall restartable in case of EINTR
@@ -5641,6 +5944,8 @@
 	.read = brightness_read,
 	.write = brightness_write,
 	.exit = brightness_exit,
+	.suspend = brightness_suspend,
+	.shutdown = brightness_shutdown,
 };
 
 /*************************************************************************
@@ -5811,7 +6116,7 @@
  *	ThinkPads from this same time period (and earlier) probably lack the
  *	tachometer as well.
  *
- *	Unfortunately a lot of ThinkPads with new-style ECs but whose firwmare
+ *	Unfortunately a lot of ThinkPads with new-style ECs but whose firmware
  *	was never fixed by IBM to report the EC firmware version string
  *	probably support the tachometer (like the early X models), so
  *	detecting it is quite hard.  We need more data to know for sure.
@@ -6086,6 +6391,9 @@
 	default:
 		return -ENXIO;
 	}
+
+	vdbg_printk(TPACPI_DBG_FAN,
+		"fan control: set fan control register to 0x%02x\n", level);
 	return 0;
 }
 
@@ -6163,6 +6471,11 @@
 	}
 
 	mutex_unlock(&fan_mutex);
+
+	if (!rc)
+		vdbg_printk(TPACPI_DBG_FAN,
+			"fan control: set fan control register to 0x%02x\n",
+			s);
 	return rc;
 }
 
@@ -6199,6 +6512,9 @@
 		rc = -ENXIO;
 	}
 
+	if (!rc)
+		vdbg_printk(TPACPI_DBG_FAN,
+			"fan control: set fan control register to 0\n");
 
 	mutex_unlock(&fan_mutex);
 	return rc;
@@ -6327,6 +6643,9 @@
 	if (parse_strtoul(buf, 2, &t))
 		return -EINVAL;
 
+	tpacpi_disclose_usertask("hwmon pwm1_enable",
+			"set fan mode to %lu\n", t);
+
 	switch (t) {
 	case 0:
 		level = TP_EC_FAN_FULLSPEED;
@@ -6392,6 +6711,9 @@
 	if (parse_strtoul(buf, 255, &s))
 		return -EINVAL;
 
+	tpacpi_disclose_usertask("hwmon pwm1",
+			"set fan speed to %lu\n", s);
+
 	/* scale down from 0-255 to 0-7 */
 	newlevel = (s >> 5) & 0x07;
 
@@ -6458,6 +6780,8 @@
 	fan_watchdog_maxinterval = t;
 	fan_watchdog_reset();
 
+	tpacpi_disclose_usertask("fan_watchdog", "set to %lu\n", t);
+
 	return count;
 }
 
@@ -6479,7 +6803,8 @@
 {
 	int rc;
 
-	vdbg_printk(TPACPI_DBG_INIT, "initializing fan subdriver\n");
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
+			"initializing fan subdriver\n");
 
 	mutex_init(&fan_mutex);
 	fan_status_access_mode = TPACPI_FAN_NONE;
@@ -6538,7 +6863,8 @@
 		}
 	}
 
-	vdbg_printk(TPACPI_DBG_INIT, "fan is %s, modes %d, %d\n",
+	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
+		"fan is %s, modes %d, %d\n",
 		str_supported(fan_status_access_mode != TPACPI_FAN_NONE ||
 		  fan_control_access_mode != TPACPI_FAN_WR_NONE),
 		fan_status_access_mode, fan_control_access_mode);
@@ -6547,7 +6873,7 @@
 	if (!fan_control_allowed) {
 		fan_control_access_mode = TPACPI_FAN_WR_NONE;
 		fan_control_commands = 0;
-		dbg_printk(TPACPI_DBG_INIT,
+		dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
 			   "fan control features disabled by parameter\n");
 	}
 
@@ -6576,7 +6902,7 @@
 
 static void fan_exit(void)
 {
-	vdbg_printk(TPACPI_DBG_EXIT,
+	vdbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_FAN,
 		    "cancelling any pending fan watchdog tasks\n");
 
 	/* FIXME: can we really do this unconditionally? */
@@ -6757,6 +7083,9 @@
 	if (*rc == -ENXIO)
 		printk(TPACPI_ERR "level command accepted for unsupported "
 		       "access mode %d", fan_control_access_mode);
+	else if (!*rc)
+		tpacpi_disclose_usertask("procfs fan",
+			"set level to %d\n", level);
 
 	return 1;
 }
@@ -6770,6 +7099,8 @@
 	if (*rc == -ENXIO)
 		printk(TPACPI_ERR "enable command accepted for unsupported "
 		       "access mode %d", fan_control_access_mode);
+	else if (!*rc)
+		tpacpi_disclose_usertask("procfs fan", "enable\n");
 
 	return 1;
 }
@@ -6783,6 +7114,8 @@
 	if (*rc == -ENXIO)
 		printk(TPACPI_ERR "disable command accepted for unsupported "
 		       "access mode %d", fan_control_access_mode);
+	else if (!*rc)
+		tpacpi_disclose_usertask("procfs fan", "disable\n");
 
 	return 1;
 }
@@ -6801,6 +7134,9 @@
 	if (*rc == -ENXIO)
 		printk(TPACPI_ERR "speed command accepted for unsupported "
 		       "access mode %d", fan_control_access_mode);
+	else if (!*rc)
+		tpacpi_disclose_usertask("procfs fan",
+			"set speed to %d\n", speed);
 
 	return 1;
 }
@@ -6814,8 +7150,12 @@
 
 	if (interval < 0 || interval > 120)
 		*rc = -EINVAL;
-	else
+	else {
 		fan_watchdog_maxinterval = interval;
+		tpacpi_disclose_usertask("procfs fan",
+			"set watchdog timer to %d\n",
+			interval);
+	}
 
 	return 1;
 }
@@ -7243,10 +7583,10 @@
 MODULE_PARM_DESC(fan_control,
 		 "Enables setting fan parameters features when true");
 
-module_param_named(brightness_mode, brightness_mode, int, 0);
+module_param_named(brightness_mode, brightness_mode, uint, 0);
 MODULE_PARM_DESC(brightness_mode,
 		 "Selects brightness control strategy: "
-		 "0=auto, 1=EC, 2=CMOS, 3=both");
+		 "0=auto, 1=EC, 2=UCMS, 3=EC+NVRAM");
 
 module_param(brightness_enable, uint, 0);
 MODULE_PARM_DESC(brightness_enable,
@@ -7515,9 +7855,6 @@
 	return 0;
 }
 
-/* Please remove this in year 2009 */
-MODULE_ALIAS("ibm_acpi");
-
 MODULE_ALIAS(TPACPI_DRVR_SHORTNAME);
 
 /*
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 2834846..9a3a682 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -83,7 +83,6 @@
 	acpi_handle handle = dev->data;
 	struct acpi_buffer buffer;
 	int ret;
-	acpi_status status;
 
 	pnp_dbg(&dev->dev, "set resources\n");
 	ret = pnpacpi_build_resource_template(dev, &buffer);
@@ -94,21 +93,31 @@
 		kfree(buffer.pointer);
 		return ret;
 	}
-	status = acpi_set_current_resources(handle, &buffer);
-	if (ACPI_FAILURE(status))
+	if (ACPI_FAILURE(acpi_set_current_resources(handle, &buffer)))
 		ret = -EINVAL;
+	else if (acpi_bus_power_manageable(handle))
+		ret = acpi_bus_set_power(handle, ACPI_STATE_D0);
 	kfree(buffer.pointer);
 	return ret;
 }
 
 static int pnpacpi_disable_resources(struct pnp_dev *dev)
 {
-	acpi_status status;
+	acpi_handle handle = dev->data;
+	int ret;
+
+	dev_dbg(&dev->dev, "disable resources\n");
 
 	/* acpi_unregister_gsi(pnp_irq(dev, 0)); */
-	status = acpi_evaluate_object((acpi_handle) dev->data,
-				      "_DIS", NULL, NULL);
-	return ACPI_FAILURE(status) ? -ENODEV : 0;
+	ret = 0;
+	if (acpi_bus_power_manageable(handle)) {
+		ret = acpi_bus_set_power(handle, ACPI_STATE_D3);
+		if (ret)
+			return ret;
+	}
+	if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DIS", NULL, NULL)))
+		ret = -ENODEV;
+	return ret;
 }
 
 #ifdef CONFIG_ACPI_SLEEP
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c
index 0c056fcc..62bb981 100644
--- a/drivers/power/bq27x00_battery.c
+++ b/drivers/power/bq27x00_battery.c
@@ -83,7 +83,7 @@
 }
 
 /*
- * Return the battery temperature in Celcius degrees
+ * Return the battery temperature in Celsius degrees
  * Or < 0 if something fails.
  */
 static int bq27x00_battery_temperature(struct bq27x00_device_info *di)
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
index ac01e06..da73591 100644
--- a/drivers/power/power_supply_sysfs.c
+++ b/drivers/power/power_supply_sysfs.c
@@ -93,6 +93,8 @@
 	POWER_SUPPLY_ATTR(voltage_avg),
 	POWER_SUPPLY_ATTR(current_now),
 	POWER_SUPPLY_ATTR(current_avg),
+	POWER_SUPPLY_ATTR(power_now),
+	POWER_SUPPLY_ATTR(power_avg),
 	POWER_SUPPLY_ATTR(charge_full_design),
 	POWER_SUPPLY_ATTR(charge_empty_design),
 	POWER_SUPPLY_ATTR(charge_full),
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index e7e0cf1..e58c0ce 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -29,8 +29,12 @@
 	  Say yes here to enable debugging support.
 
 config REGULATOR_FIXED_VOLTAGE
-	tristate
+	tristate "Fixed voltage regulator support"
 	default n
+	help
+	  This driver provides support for fixed voltage regulators,
+	  useful for systems which use a combination of software
+	  managed regulators and simple non-configurable regulators.
 
 config REGULATOR_VIRTUAL_CONSUMER
 	tristate "Virtual regulator consumer support"
@@ -52,6 +56,13 @@
 	  charging select between 100 mA and 500 mA charging current
 	  limit.
 
+config REGULATOR_TWL4030
+	bool "TI TWL4030/TWL5030/TPS695x0 PMIC"
+	depends on TWL4030_CORE
+	help
+	  This driver supports the voltage regulators provided by
+	  this family of companion chips.
+
 config REGULATOR_WM8350
 	tristate "Wolfson Microelectroncis WM8350 AudioPlus PMIC"
 	depends on MFD_WM8350
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 61b30c6..bac133a 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -8,6 +8,7 @@
 obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
 
 obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
+obj-$(CONFIG_REGULATOR_TWL4030) += twl4030-regulator.o
 obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
 obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
 obj-$(CONFIG_REGULATOR_DA903X)	+= da903x.o
diff --git a/drivers/regulator/bq24022.c b/drivers/regulator/bq24022.c
index c175e38..7ecb820 100644
--- a/drivers/regulator/bq24022.c
+++ b/drivers/regulator/bq24022.c
@@ -105,7 +105,8 @@
 	ret = gpio_direction_output(pdata->gpio_iset2, 0);
 	ret = gpio_direction_output(pdata->gpio_nce, 1);
 
-	bq24022 = regulator_register(&bq24022_desc, &pdev->dev, pdata);
+	bq24022 = regulator_register(&bq24022_desc, &pdev->dev,
+				     pdata->init_data, pdata);
 	if (IS_ERR(bq24022)) {
 		dev_dbg(&pdev->dev, "couldn't register regulator\n");
 		ret = PTR_ERR(bq24022);
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index f511a40..01f7702 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -28,33 +28,7 @@
 static DEFINE_MUTEX(regulator_list_mutex);
 static LIST_HEAD(regulator_list);
 static LIST_HEAD(regulator_map_list);
-
-/*
- * struct regulator_dev
- *
- * Voltage / Current regulator class device. One for each regulator.
- */
-struct regulator_dev {
-	struct regulator_desc *desc;
-	int use_count;
-
-	/* lists we belong to */
-	struct list_head list; /* list of all regulators */
-	struct list_head slist; /* list of supplied regulators */
-
-	/* lists we own */
-	struct list_head consumer_list; /* consumers we supply */
-	struct list_head supply_list; /* regulators we supply */
-
-	struct blocking_notifier_head notifier;
-	struct mutex mutex; /* consumer lock */
-	struct module *owner;
-	struct device dev;
-	struct regulation_constraints *constraints;
-	struct regulator_dev *supply;	/* for tree */
-
-	void *reg_data;		/* regulator_dev data */
-};
+static int has_full_constraints;
 
 /*
  * struct regulator_map
@@ -79,7 +53,6 @@
 	int uA_load;
 	int min_uV;
 	int max_uV;
-	int enabled; /* count of client enables */
 	char *supply_name;
 	struct device_attribute dev_attr;
 	struct regulator_dev *rdev;
@@ -312,6 +285,47 @@
 }
 static DEVICE_ATTR(state, 0444, regulator_state_show, NULL);
 
+static ssize_t regulator_status_show(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	struct regulator_dev *rdev = dev_get_drvdata(dev);
+	int status;
+	char *label;
+
+	status = rdev->desc->ops->get_status(rdev);
+	if (status < 0)
+		return status;
+
+	switch (status) {
+	case REGULATOR_STATUS_OFF:
+		label = "off";
+		break;
+	case REGULATOR_STATUS_ON:
+		label = "on";
+		break;
+	case REGULATOR_STATUS_ERROR:
+		label = "error";
+		break;
+	case REGULATOR_STATUS_FAST:
+		label = "fast";
+		break;
+	case REGULATOR_STATUS_NORMAL:
+		label = "normal";
+		break;
+	case REGULATOR_STATUS_IDLE:
+		label = "idle";
+		break;
+	case REGULATOR_STATUS_STANDBY:
+		label = "standby";
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	return sprintf(buf, "%s\n", label);
+}
+static DEVICE_ATTR(status, 0444, regulator_status_show, NULL);
+
 static ssize_t regulator_min_uA_show(struct device *dev,
 				    struct device_attribute *attr, char *buf)
 {
@@ -678,6 +692,73 @@
 	else
 		name = "regulator";
 
+	/* constrain machine-level voltage specs to fit
+	 * the actual range supported by this regulator.
+	 */
+	if (ops->list_voltage && rdev->desc->n_voltages) {
+		int	count = rdev->desc->n_voltages;
+		int	i;
+		int	min_uV = INT_MAX;
+		int	max_uV = INT_MIN;
+		int	cmin = constraints->min_uV;
+		int	cmax = constraints->max_uV;
+
+		/* it's safe to autoconfigure fixed-voltage supplies */
+		if (count == 1 && !cmin) {
+			cmin = INT_MIN;
+			cmax = INT_MAX;
+		}
+
+		/* voltage constraints are optional */
+		if ((cmin == 0) && (cmax == 0))
+			goto out;
+
+		/* else require explicit machine-level constraints */
+		if (cmin <= 0 || cmax <= 0 || cmax < cmin) {
+			pr_err("%s: %s '%s' voltage constraints\n",
+				       __func__, "invalid", name);
+			ret = -EINVAL;
+			goto out;
+		}
+
+		/* initial: [cmin..cmax] valid, [min_uV..max_uV] not */
+		for (i = 0; i < count; i++) {
+			int	value;
+
+			value = ops->list_voltage(rdev, i);
+			if (value <= 0)
+				continue;
+
+			/* maybe adjust [min_uV..max_uV] */
+			if (value >= cmin && value < min_uV)
+				min_uV = value;
+			if (value <= cmax && value > max_uV)
+				max_uV = value;
+		}
+
+		/* final: [min_uV..max_uV] valid iff constraints valid */
+		if (max_uV < min_uV) {
+			pr_err("%s: %s '%s' voltage constraints\n",
+				       __func__, "unsupportable", name);
+			ret = -EINVAL;
+			goto out;
+		}
+
+		/* use regulator's subset of machine constraints */
+		if (constraints->min_uV < min_uV) {
+			pr_debug("%s: override '%s' %s, %d -> %d\n",
+				       __func__, name, "min_uV",
+					constraints->min_uV, min_uV);
+			constraints->min_uV = min_uV;
+		}
+		if (constraints->max_uV > max_uV) {
+			pr_debug("%s: override '%s' %s, %d -> %d\n",
+				       __func__, name, "max_uV",
+					constraints->max_uV, max_uV);
+			constraints->max_uV = max_uV;
+		}
+	}
+
 	rdev->constraints = constraints;
 
 	/* do we need to apply the constraint voltage */
@@ -695,10 +776,6 @@
 			}
 	}
 
-	/* are we enabled at boot time by firmware / bootloader */
-	if (rdev->constraints->boot_on)
-		rdev->use_count = 1;
-
 	/* do we need to setup our suspend state */
 	if (constraints->initial_state) {
 		ret = suspend_prepare(rdev, constraints->initial_state);
@@ -710,11 +787,27 @@
 		}
 	}
 
-	/* if always_on is set then turn the regulator on if it's not
-	 * already on. */
-	if (constraints->always_on && ops->enable &&
-	    ((ops->is_enabled && !ops->is_enabled(rdev)) ||
-	     (!ops->is_enabled && !constraints->boot_on))) {
+	if (constraints->initial_mode) {
+		if (!ops->set_mode) {
+			printk(KERN_ERR "%s: no set_mode operation for %s\n",
+			       __func__, name);
+			ret = -EINVAL;
+			goto out;
+		}
+
+		ret = ops->set_mode(rdev, constraints->initial_mode);
+		if (ret < 0) {
+			printk(KERN_ERR
+			       "%s: failed to set initial mode for %s: %d\n",
+			       __func__, name, ret);
+			goto out;
+		}
+	}
+
+	/* If the constraints say the regulator should be on at this point
+	 * and we have control then make sure it is enabled.
+	 */
+	if ((constraints->always_on || constraints->boot_on) && ops->enable) {
 		ret = ops->enable(rdev);
 		if (ret < 0) {
 			printk(KERN_ERR "%s: failed to enable %s\n",
@@ -817,6 +910,19 @@
 	}
 }
 
+static void unset_regulator_supplies(struct regulator_dev *rdev)
+{
+	struct regulator_map *node, *n;
+
+	list_for_each_entry_safe(node, n, &regulator_map_list, list) {
+		if (rdev == node->regulator) {
+			list_del(&node->list);
+			kfree(node);
+			return;
+		}
+	}
+}
+
 #define REG_STR_SIZE	32
 
 static struct regulator *create_regulator(struct regulator_dev *rdev,
@@ -898,9 +1004,12 @@
  * @id: Supply name or regulator ID.
  *
  * Returns a struct regulator corresponding to the regulator producer,
- * or IS_ERR() condition containing errno.  Use of supply names
- * configured via regulator_set_device_supply() is strongly
- * encouraged.
+ * or IS_ERR() condition containing errno.
+ *
+ * Use of supply names configured via regulator_set_device_supply() is
+ * strongly encouraged.  It is recommended that the supply name used
+ * should match the name used for the supply and/or the relevant
+ * device pins in the datasheet.
  */
 struct regulator *regulator_get(struct device *dev, const char *id)
 {
@@ -922,8 +1031,6 @@
 			goto found;
 		}
 	}
-	printk(KERN_ERR "regulator: Unable to get requested regulator: %s\n",
-	       id);
 	mutex_unlock(&regulator_list_mutex);
 	return regulator;
 
@@ -961,10 +1068,6 @@
 	mutex_lock(&regulator_list_mutex);
 	rdev = regulator->rdev;
 
-	if (WARN(regulator->enabled, "Releasing supply %s while enabled\n",
-			       regulator->supply_name))
-		_regulator_disable(rdev);
-
 	/* remove any sysfs entries */
 	if (regulator->dev) {
 		sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name);
@@ -1039,12 +1142,7 @@
 	int ret = 0;
 
 	mutex_lock(&rdev->mutex);
-	if (regulator->enabled == 0)
-		ret = _regulator_enable(rdev);
-	else if (regulator->enabled < 0)
-		ret = -EIO;
-	if (ret == 0)
-		regulator->enabled++;
+	ret = _regulator_enable(rdev);
 	mutex_unlock(&rdev->mutex);
 	return ret;
 }
@@ -1055,6 +1153,11 @@
 {
 	int ret = 0;
 
+	if (WARN(rdev->use_count <= 0,
+			"unbalanced disables for %s\n",
+			rdev->desc->name))
+		return -EIO;
+
 	/* are we the last user and permitted to disable ? */
 	if (rdev->use_count == 1 && !rdev->constraints->always_on) {
 
@@ -1103,16 +1206,7 @@
 	int ret = 0;
 
 	mutex_lock(&rdev->mutex);
-	if (regulator->enabled == 1) {
-		ret = _regulator_disable(rdev);
-		if (ret == 0)
-			regulator->uA_load = 0;
-	} else if (WARN(regulator->enabled <= 0,
-			"unbalanced disables for supply %s\n",
-			regulator->supply_name))
-		ret = -EIO;
-	if (ret == 0)
-		regulator->enabled--;
+	ret = _regulator_disable(rdev);
 	mutex_unlock(&rdev->mutex);
 	return ret;
 }
@@ -1159,7 +1253,6 @@
 	int ret;
 
 	mutex_lock(&regulator->rdev->mutex);
-	regulator->enabled = 0;
 	regulator->uA_load = 0;
 	ret = _regulator_force_disable(regulator->rdev);
 	mutex_unlock(&regulator->rdev->mutex);
@@ -1204,6 +1297,56 @@
 EXPORT_SYMBOL_GPL(regulator_is_enabled);
 
 /**
+ * regulator_count_voltages - count regulator_list_voltage() selectors
+ * @regulator: regulator source
+ *
+ * Returns number of selectors, or negative errno.  Selectors are
+ * numbered starting at zero, and typically correspond to bitfields
+ * in hardware registers.
+ */
+int regulator_count_voltages(struct regulator *regulator)
+{
+	struct regulator_dev	*rdev = regulator->rdev;
+
+	return rdev->desc->n_voltages ? : -EINVAL;
+}
+EXPORT_SYMBOL_GPL(regulator_count_voltages);
+
+/**
+ * regulator_list_voltage - enumerate supported voltages
+ * @regulator: regulator source
+ * @selector: identify voltage to list
+ * Context: can sleep
+ *
+ * Returns a voltage that can be passed to @regulator_set_voltage(),
+ * zero if this selector code can't be used on this sytem, or a
+ * negative errno.
+ */
+int regulator_list_voltage(struct regulator *regulator, unsigned selector)
+{
+	struct regulator_dev	*rdev = regulator->rdev;
+	struct regulator_ops	*ops = rdev->desc->ops;
+	int			ret;
+
+	if (!ops->list_voltage || selector >= rdev->desc->n_voltages)
+		return -EINVAL;
+
+	mutex_lock(&rdev->mutex);
+	ret = ops->list_voltage(rdev, selector);
+	mutex_unlock(&rdev->mutex);
+
+	if (ret > 0) {
+		if (ret < rdev->constraints->min_uV)
+			ret = 0;
+		else if (ret > rdev->constraints->max_uV)
+			ret = 0;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(regulator_list_voltage);
+
+/**
  * regulator_set_voltage - set regulator output voltage
  * @regulator: regulator source
  * @min_uV: Minimum required voltage in uV
@@ -1243,6 +1386,7 @@
 	ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV);
 
 out:
+	_notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE, NULL);
 	mutex_unlock(&rdev->mutex);
 	return ret;
 }
@@ -1543,20 +1687,23 @@
 }
 EXPORT_SYMBOL_GPL(regulator_unregister_notifier);
 
-/* notify regulator consumers and downstream regulator consumers */
+/* notify regulator consumers and downstream regulator consumers.
+ * Note mutex must be held by caller.
+ */
 static void _notifier_call_chain(struct regulator_dev *rdev,
 				  unsigned long event, void *data)
 {
 	struct regulator_dev *_rdev;
 
 	/* call rdev chain first */
-	mutex_lock(&rdev->mutex);
 	blocking_notifier_call_chain(&rdev->notifier, event, NULL);
-	mutex_unlock(&rdev->mutex);
 
 	/* now notify regulator we supply */
-	list_for_each_entry(_rdev, &rdev->supply_list, slist)
-		_notifier_call_chain(_rdev, event, data);
+	list_for_each_entry(_rdev, &rdev->supply_list, slist) {
+	  mutex_lock(&_rdev->mutex);
+	  _notifier_call_chain(_rdev, event, data);
+	  mutex_unlock(&_rdev->mutex);
+	}
 }
 
 /**
@@ -1703,6 +1850,7 @@
  *
  * Called by regulator drivers to notify clients a regulator event has
  * occurred. We also notify regulator clients downstream.
+ * Note lock must be held by caller.
  */
 int regulator_notifier_call_chain(struct regulator_dev *rdev,
 				  unsigned long event, void *data)
@@ -1744,6 +1892,11 @@
 		if (status < 0)
 			return status;
 	}
+	if (ops->get_status) {
+		status = device_create_file(dev, &dev_attr_status);
+		if (status < 0)
+			return status;
+	}
 
 	/* some attributes are type-specific */
 	if (rdev->desc->type == REGULATOR_CURRENT) {
@@ -1828,17 +1981,18 @@
  * regulator_register - register regulator
  * @regulator_desc: regulator to register
  * @dev: struct device for the regulator
+ * @init_data: platform provided init data, passed through by driver
  * @driver_data: private regulator data
  *
  * Called by regulator drivers to register a regulator.
  * Returns 0 on success.
  */
 struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
-	struct device *dev, void *driver_data)
+	struct device *dev, struct regulator_init_data *init_data,
+	void *driver_data)
 {
 	static atomic_t regulator_no = ATOMIC_INIT(0);
 	struct regulator_dev *rdev;
-	struct regulator_init_data *init_data = dev->platform_data;
 	int ret, i;
 
 	if (regulator_desc == NULL)
@@ -1945,6 +2099,7 @@
 		return;
 
 	mutex_lock(&regulator_list_mutex);
+	unset_regulator_supplies(rdev);
 	list_del(&rdev->list);
 	if (rdev->supply)
 		sysfs_remove_link(&rdev->dev.kobj, "supply");
@@ -1989,6 +2144,23 @@
 EXPORT_SYMBOL_GPL(regulator_suspend_prepare);
 
 /**
+ * regulator_has_full_constraints - the system has fully specified constraints
+ *
+ * Calling this function will cause the regulator API to disable all
+ * regulators which have a zero use count and don't have an always_on
+ * constraint in a late_initcall.
+ *
+ * The intention is that this will become the default behaviour in a
+ * future kernel release so users are encouraged to use this facility
+ * now.
+ */
+void regulator_has_full_constraints(void)
+{
+	has_full_constraints = 1;
+}
+EXPORT_SYMBOL_GPL(regulator_has_full_constraints);
+
+/**
  * rdev_get_drvdata - get rdev regulator driver data
  * @rdev: regulator
  *
@@ -2055,3 +2227,77 @@
 
 /* init early to allow our consumers to complete system booting */
 core_initcall(regulator_init);
+
+static int __init regulator_init_complete(void)
+{
+	struct regulator_dev *rdev;
+	struct regulator_ops *ops;
+	struct regulation_constraints *c;
+	int enabled, ret;
+	const char *name;
+
+	mutex_lock(&regulator_list_mutex);
+
+	/* If we have a full configuration then disable any regulators
+	 * which are not in use or always_on.  This will become the
+	 * default behaviour in the future.
+	 */
+	list_for_each_entry(rdev, &regulator_list, list) {
+		ops = rdev->desc->ops;
+		c = rdev->constraints;
+
+		if (c->name)
+			name = c->name;
+		else if (rdev->desc->name)
+			name = rdev->desc->name;
+		else
+			name = "regulator";
+
+		if (!ops->disable || c->always_on)
+			continue;
+
+		mutex_lock(&rdev->mutex);
+
+		if (rdev->use_count)
+			goto unlock;
+
+		/* If we can't read the status assume it's on. */
+		if (ops->is_enabled)
+			enabled = ops->is_enabled(rdev);
+		else
+			enabled = 1;
+
+		if (!enabled)
+			goto unlock;
+
+		if (has_full_constraints) {
+			/* We log since this may kill the system if it
+			 * goes wrong. */
+			printk(KERN_INFO "%s: disabling %s\n",
+			       __func__, name);
+			ret = ops->disable(rdev);
+			if (ret != 0) {
+				printk(KERN_ERR
+				       "%s: couldn't disable %s: %d\n",
+				       __func__, name, ret);
+			}
+		} else {
+			/* The intention is that in future we will
+			 * assume that full constraints are provided
+			 * so warn even if we aren't going to do
+			 * anything here.
+			 */
+			printk(KERN_WARNING
+			       "%s: incomplete constraints, leaving %s on\n",
+			       __func__, name);
+		}
+
+unlock:
+		mutex_unlock(&rdev->mutex);
+	}
+
+	mutex_unlock(&regulator_list_mutex);
+
+	return 0;
+}
+late_initcall(regulator_init_complete);
diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c
index fe77730..72b1549 100644
--- a/drivers/regulator/da903x.c
+++ b/drivers/regulator/da903x.c
@@ -471,7 +471,8 @@
 	if (ri->desc.id == DA9030_ID_LDO1 || ri->desc.id == DA9030_ID_LDO15)
 		ri->desc.ops = &da9030_regulator_ldo1_15_ops;
 
-	rdev = regulator_register(&ri->desc, &pdev->dev, ri);
+	rdev = regulator_register(&ri->desc, &pdev->dev,
+				  pdev->dev.platform_data, ri);
 	if (IS_ERR(rdev)) {
 		dev_err(&pdev->dev, "failed to register regulator %s\n",
 				ri->desc.name);
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c
index d31db3e..23d5546 100644
--- a/drivers/regulator/fixed.c
+++ b/drivers/regulator/fixed.c
@@ -73,7 +73,8 @@
 
 	drvdata->microvolts = config->microvolts;
 
-	drvdata->dev = regulator_register(&drvdata->desc, drvdata);
+	drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev,
+					  config->init_data, drvdata);
 	if (IS_ERR(drvdata->dev)) {
 		ret = PTR_ERR(drvdata->dev);
 		goto err_name;
diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c
index 4cc85ec..cd761d8 100644
--- a/drivers/regulator/pcf50633-regulator.c
+++ b/drivers/regulator/pcf50633-regulator.c
@@ -284,7 +284,8 @@
 	/* Already set by core driver */
 	pcf = platform_get_drvdata(pdev);
 
-	rdev = regulator_register(&regulators[pdev->id], &pdev->dev, pcf);
+	rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
+				  pdev->dev.platform_data, pcf);
 	if (IS_ERR(rdev))
 		return PTR_ERR(rdev);
 
diff --git a/drivers/regulator/twl4030-regulator.c b/drivers/regulator/twl4030-regulator.c
new file mode 100644
index 0000000..e2032fb6
--- /dev/null
+++ b/drivers/regulator/twl4030-regulator.c
@@ -0,0 +1,500 @@
+/*
+ * twl4030-regulator.c -- support regulators in twl4030 family chips
+ *
+ * Copyright (C) 2008 David Brownell
+ *
+ * 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/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/i2c/twl4030.h>
+
+
+/*
+ * The TWL4030/TW5030/TPS659x0 family chips include power management, a
+ * USB OTG transceiver, an RTC, ADC, PWM, and lots more.  Some versions
+ * include an audio codec, battery charger, and more voltage regulators.
+ * These chips are often used in OMAP-based systems.
+ *
+ * This driver implements software-based resource control for various
+ * voltage regulators.  This is usually augmented with state machine
+ * based control.
+ */
+
+struct twlreg_info {
+	/* start of regulator's PM_RECEIVER control register bank */
+	u8			base;
+
+	/* twl4030 resource ID, for resource control state machine */
+	u8			id;
+
+	/* voltage in mV = table[VSEL]; table_len must be a power-of-two */
+	u8			table_len;
+	const u16		*table;
+
+	/* chip constraints on regulator behavior */
+	u16			min_mV;
+
+	/* used by regulator core */
+	struct regulator_desc	desc;
+};
+
+
+/* LDO control registers ... offset is from the base of its register bank.
+ * The first three registers of all power resource banks help hardware to
+ * manage the various resource groups.
+ */
+#define VREG_GRP		0
+#define VREG_TYPE		1
+#define VREG_REMAP		2
+#define VREG_DEDICATED		3	/* LDO control */
+
+
+static inline int
+twl4030reg_read(struct twlreg_info *info, unsigned offset)
+{
+	u8 value;
+	int status;
+
+	status = twl4030_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER,
+			&value, info->base + offset);
+	return (status < 0) ? status : value;
+}
+
+static inline int
+twl4030reg_write(struct twlreg_info *info, unsigned offset, u8 value)
+{
+	return twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+			value, info->base + offset);
+}
+
+/*----------------------------------------------------------------------*/
+
+/* generic power resource operations, which work on all regulators */
+
+static int twl4030reg_grp(struct regulator_dev *rdev)
+{
+	return twl4030reg_read(rdev_get_drvdata(rdev), VREG_GRP);
+}
+
+/*
+ * Enable/disable regulators by joining/leaving the P1 (processor) group.
+ * We assume nobody else is updating the DEV_GRP registers.
+ */
+
+#define P3_GRP		BIT(7)		/* "peripherals" */
+#define P2_GRP		BIT(6)		/* secondary processor, modem, etc */
+#define P1_GRP		BIT(5)		/* CPU/Linux */
+
+static int twl4030reg_is_enabled(struct regulator_dev *rdev)
+{
+	int	state = twl4030reg_grp(rdev);
+
+	if (state < 0)
+		return state;
+
+	return (state & P1_GRP) != 0;
+}
+
+static int twl4030reg_enable(struct regulator_dev *rdev)
+{
+	struct twlreg_info	*info = rdev_get_drvdata(rdev);
+	int			grp;
+
+	grp = twl4030reg_read(info, VREG_GRP);
+	if (grp < 0)
+		return grp;
+
+	grp |= P1_GRP;
+	return twl4030reg_write(info, VREG_GRP, grp);
+}
+
+static int twl4030reg_disable(struct regulator_dev *rdev)
+{
+	struct twlreg_info	*info = rdev_get_drvdata(rdev);
+	int			grp;
+
+	grp = twl4030reg_read(info, VREG_GRP);
+	if (grp < 0)
+		return grp;
+
+	grp &= ~P1_GRP;
+	return twl4030reg_write(info, VREG_GRP, grp);
+}
+
+static int twl4030reg_get_status(struct regulator_dev *rdev)
+{
+	int	state = twl4030reg_grp(rdev);
+
+	if (state < 0)
+		return state;
+	state &= 0x0f;
+
+	/* assume state != WARM_RESET; we'd not be running...  */
+	if (!state)
+		return REGULATOR_STATUS_OFF;
+	return (state & BIT(3))
+		? REGULATOR_STATUS_NORMAL
+		: REGULATOR_STATUS_STANDBY;
+}
+
+static int twl4030reg_set_mode(struct regulator_dev *rdev, unsigned mode)
+{
+	struct twlreg_info	*info = rdev_get_drvdata(rdev);
+	unsigned		message;
+	int			status;
+
+	/* We can only set the mode through state machine commands... */
+	switch (mode) {
+	case REGULATOR_MODE_NORMAL:
+		message = MSG_SINGULAR(DEV_GRP_P1, info->id, RES_STATE_ACTIVE);
+		break;
+	case REGULATOR_MODE_STANDBY:
+		message = MSG_SINGULAR(DEV_GRP_P1, info->id, RES_STATE_SLEEP);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* Ensure the resource is associated with some group */
+	status = twl4030reg_grp(rdev);
+	if (status < 0)
+		return status;
+	if (!(status & (P3_GRP | P2_GRP | P1_GRP)))
+		return -EACCES;
+
+	status = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
+			message >> 8, 0x15 /* PB_WORD_MSB */ );
+	if (status >= 0)
+		return status;
+
+	return twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
+			message, 0x16 /* PB_WORD_LSB */ );
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Support for adjustable-voltage LDOs uses a four bit (or less) voltage
+ * select field in its control register.   We use tables indexed by VSEL
+ * to record voltages in milliVolts.  (Accuracy is about three percent.)
+ *
+ * Note that VSEL values for VAUX2 changed in twl5030 and newer silicon;
+ * currently handled by listing two slightly different VAUX2 regulators,
+ * only one of which will be configured.
+ *
+ * VSEL values documented as "TI cannot support these values" are flagged
+ * in these tables as UNSUP() values; we normally won't assign them.
+ *
+ * VAUX3 at 3V is incorrectly listed in some TI manuals as unsupported.
+ * TI are revising the twl5030/tps659x0 specs to support that 3.0V setting.
+ */
+#ifdef CONFIG_TWL4030_ALLOW_UNSUPPORTED
+#define UNSUP_MASK	0x0000
+#else
+#define UNSUP_MASK	0x8000
+#endif
+
+#define UNSUP(x)	(UNSUP_MASK | (x))
+#define IS_UNSUP(x)	(UNSUP_MASK & (x))
+#define LDO_MV(x)	(~UNSUP_MASK & (x))
+
+
+static const u16 VAUX1_VSEL_table[] = {
+	UNSUP(1500), UNSUP(1800), 2500, 2800,
+	3000, 3000, 3000, 3000,
+};
+static const u16 VAUX2_4030_VSEL_table[] = {
+	UNSUP(1000), UNSUP(1000), UNSUP(1200), 1300,
+	1500, 1800, UNSUP(1850), 2500,
+	UNSUP(2600), 2800, UNSUP(2850), UNSUP(3000),
+	UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150),
+};
+static const u16 VAUX2_VSEL_table[] = {
+	1700, 1700, 1900, 1300,
+	1500, 1800, 2000, 2500,
+	2100, 2800, 2200, 2300,
+	2400, 2400, 2400, 2400,
+};
+static const u16 VAUX3_VSEL_table[] = {
+	1500, 1800, 2500, 2800,
+	3000, 3000, 3000, 3000,
+};
+static const u16 VAUX4_VSEL_table[] = {
+	700, 1000, 1200, UNSUP(1300),
+	1500, 1800, UNSUP(1850), 2500,
+	UNSUP(2600), 2800, UNSUP(2850), UNSUP(3000),
+	UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150),
+};
+static const u16 VMMC1_VSEL_table[] = {
+	1850, 2850, 3000, 3150,
+};
+static const u16 VMMC2_VSEL_table[] = {
+	UNSUP(1000), UNSUP(1000), UNSUP(1200), UNSUP(1300),
+	UNSUP(1500), UNSUP(1800), 1850, UNSUP(2500),
+	2600, 2800, 2850, 3000,
+	3150, 3150, 3150, 3150,
+};
+static const u16 VPLL1_VSEL_table[] = {
+	1000, 1200, 1300, 1800,
+	UNSUP(2800), UNSUP(3000), UNSUP(3000), UNSUP(3000),
+};
+static const u16 VPLL2_VSEL_table[] = {
+	700, 1000, 1200, 1300,
+	UNSUP(1500), 1800, UNSUP(1850), UNSUP(2500),
+	UNSUP(2600), UNSUP(2800), UNSUP(2850), UNSUP(3000),
+	UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150),
+};
+static const u16 VSIM_VSEL_table[] = {
+	UNSUP(1000), UNSUP(1200), UNSUP(1300), 1800,
+	2800, 3000, 3000, 3000,
+};
+static const u16 VDAC_VSEL_table[] = {
+	1200, 1300, 1800, 1800,
+};
+
+
+static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index)
+{
+	struct twlreg_info	*info = rdev_get_drvdata(rdev);
+	int			mV = info->table[index];
+
+	return IS_UNSUP(mV) ? 0 : (LDO_MV(mV) * 1000);
+}
+
+static int
+twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
+{
+	struct twlreg_info	*info = rdev_get_drvdata(rdev);
+	int			vsel;
+
+	for (vsel = 0; vsel < info->table_len; vsel++) {
+		int mV = info->table[vsel];
+		int uV;
+
+		if (IS_UNSUP(mV))
+			continue;
+		uV = LDO_MV(mV) * 1000;
+
+		/* REVISIT for VAUX2, first match may not be best/lowest */
+
+		/* use the first in-range value */
+		if (min_uV <= uV && uV <= max_uV)
+			return twl4030reg_write(info, VREG_DEDICATED, vsel);
+	}
+
+	return -EDOM;
+}
+
+static int twl4030ldo_get_voltage(struct regulator_dev *rdev)
+{
+	struct twlreg_info	*info = rdev_get_drvdata(rdev);
+	int			vsel = twl4030reg_read(info, VREG_DEDICATED);
+
+	if (vsel < 0)
+		return vsel;
+
+	vsel &= info->table_len - 1;
+	return LDO_MV(info->table[vsel]) * 1000;
+}
+
+static struct regulator_ops twl4030ldo_ops = {
+	.list_voltage	= twl4030ldo_list_voltage,
+
+	.set_voltage	= twl4030ldo_set_voltage,
+	.get_voltage	= twl4030ldo_get_voltage,
+
+	.enable		= twl4030reg_enable,
+	.disable	= twl4030reg_disable,
+	.is_enabled	= twl4030reg_is_enabled,
+
+	.set_mode	= twl4030reg_set_mode,
+
+	.get_status	= twl4030reg_get_status,
+};
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Fixed voltage LDOs don't have a VSEL field to update.
+ */
+static int twl4030fixed_list_voltage(struct regulator_dev *rdev, unsigned index)
+{
+	struct twlreg_info	*info = rdev_get_drvdata(rdev);
+
+	return info->min_mV * 1000;
+}
+
+static int twl4030fixed_get_voltage(struct regulator_dev *rdev)
+{
+	struct twlreg_info	*info = rdev_get_drvdata(rdev);
+
+	return info->min_mV * 1000;
+}
+
+static struct regulator_ops twl4030fixed_ops = {
+	.list_voltage	= twl4030fixed_list_voltage,
+
+	.get_voltage	= twl4030fixed_get_voltage,
+
+	.enable		= twl4030reg_enable,
+	.disable	= twl4030reg_disable,
+	.is_enabled	= twl4030reg_is_enabled,
+
+	.set_mode	= twl4030reg_set_mode,
+
+	.get_status	= twl4030reg_get_status,
+};
+
+/*----------------------------------------------------------------------*/
+
+#define TWL_ADJUSTABLE_LDO(label, offset, num) { \
+	.base = offset, \
+	.id = num, \
+	.table_len = ARRAY_SIZE(label##_VSEL_table), \
+	.table = label##_VSEL_table, \
+	.desc = { \
+		.name = #label, \
+		.id = TWL4030_REG_##label, \
+		.n_voltages = ARRAY_SIZE(label##_VSEL_table), \
+		.ops = &twl4030ldo_ops, \
+		.type = REGULATOR_VOLTAGE, \
+		.owner = THIS_MODULE, \
+		}, \
+	}
+
+#define TWL_FIXED_LDO(label, offset, mVolts, num) { \
+	.base = offset, \
+	.id = num, \
+	.min_mV = mVolts, \
+	.desc = { \
+		.name = #label, \
+		.id = TWL4030_REG_##label, \
+		.n_voltages = 1, \
+		.ops = &twl4030fixed_ops, \
+		.type = REGULATOR_VOLTAGE, \
+		.owner = THIS_MODULE, \
+		}, \
+	}
+
+/*
+ * We list regulators here if systems need some level of
+ * software control over them after boot.
+ */
+static struct twlreg_info twl4030_regs[] = {
+	TWL_ADJUSTABLE_LDO(VAUX1, 0x17, 1),
+	TWL_ADJUSTABLE_LDO(VAUX2_4030, 0x1b, 2),
+	TWL_ADJUSTABLE_LDO(VAUX2, 0x1b, 2),
+	TWL_ADJUSTABLE_LDO(VAUX3, 0x1f, 3),
+	TWL_ADJUSTABLE_LDO(VAUX4, 0x23, 4),
+	TWL_ADJUSTABLE_LDO(VMMC1, 0x27, 5),
+	TWL_ADJUSTABLE_LDO(VMMC2, 0x2b, 6),
+	/*
+	TWL_ADJUSTABLE_LDO(VPLL1, 0x2f, 7),
+	*/
+	TWL_ADJUSTABLE_LDO(VPLL2, 0x33, 8),
+	TWL_ADJUSTABLE_LDO(VSIM, 0x37, 9),
+	TWL_ADJUSTABLE_LDO(VDAC, 0x3b, 10),
+	/*
+	TWL_ADJUSTABLE_LDO(VINTANA1, 0x3f, 11),
+	TWL_ADJUSTABLE_LDO(VINTANA2, 0x43, 12),
+	TWL_ADJUSTABLE_LDO(VINTDIG, 0x47, 13),
+	TWL_SMPS(VIO, 0x4b, 14),
+	TWL_SMPS(VDD1, 0x55, 15),
+	TWL_SMPS(VDD2, 0x63, 16),
+	 */
+	TWL_FIXED_LDO(VUSB1V5, 0x71, 1500, 17),
+	TWL_FIXED_LDO(VUSB1V8, 0x74, 1800, 18),
+	TWL_FIXED_LDO(VUSB3V1, 0x77, 3100, 19),
+	/* VUSBCP is managed *only* by the USB subchip */
+};
+
+static int twl4030reg_probe(struct platform_device *pdev)
+{
+	int				i;
+	struct twlreg_info		*info;
+	struct regulator_init_data	*initdata;
+	struct regulation_constraints	*c;
+	struct regulator_dev		*rdev;
+
+	for (i = 0, info = NULL; i < ARRAY_SIZE(twl4030_regs); i++) {
+		if (twl4030_regs[i].desc.id != pdev->id)
+			continue;
+		info = twl4030_regs + i;
+		break;
+	}
+	if (!info)
+		return -ENODEV;
+
+	initdata = pdev->dev.platform_data;
+	if (!initdata)
+		return -EINVAL;
+
+	/* Constrain board-specific capabilities according to what
+	 * this driver and the chip itself can actually do.
+	 */
+	c = &initdata->constraints;
+	c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY;
+	c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE
+				| REGULATOR_CHANGE_MODE
+				| REGULATOR_CHANGE_STATUS;
+
+	rdev = regulator_register(&info->desc, &pdev->dev, initdata, info);
+	if (IS_ERR(rdev)) {
+		dev_err(&pdev->dev, "can't register %s, %ld\n",
+				info->desc.name, PTR_ERR(rdev));
+		return PTR_ERR(rdev);
+	}
+	platform_set_drvdata(pdev, rdev);
+
+	/* NOTE:  many regulators support short-circuit IRQs (presentable
+	 * as REGULATOR_OVER_CURRENT notifications?) configured via:
+	 *  - SC_CONFIG
+	 *  - SC_DETECT1 (vintana2, vmmc1/2, vaux1/2/3/4)
+	 *  - SC_DETECT2 (vusb, vdac, vio, vdd1/2, vpll2)
+	 *  - IT_CONFIG
+	 */
+
+	return 0;
+}
+
+static int __devexit twl4030reg_remove(struct platform_device *pdev)
+{
+	regulator_unregister(platform_get_drvdata(pdev));
+	return 0;
+}
+
+MODULE_ALIAS("platform:twl4030_reg");
+
+static struct platform_driver twl4030reg_driver = {
+	.probe		= twl4030reg_probe,
+	.remove		= __devexit_p(twl4030reg_remove),
+	/* NOTE: short name, to work around driver model truncation of
+	 * "twl4030_regulator.12" (and friends) to "twl4030_regulator.1".
+	 */
+	.driver.name	= "twl4030_reg",
+	.driver.owner	= THIS_MODULE,
+};
+
+static int __init twl4030reg_init(void)
+{
+	return platform_driver_register(&twl4030reg_driver);
+}
+subsys_initcall(twl4030reg_init);
+
+static void __exit twl4030reg_exit(void)
+{
+	platform_driver_unregister(&twl4030reg_driver);
+}
+module_exit(twl4030reg_exit)
+
+MODULE_DESCRIPTION("TWL4030 regulator driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/virtual.c b/drivers/regulator/virtual.c
index 5ddb464..3d08348 100644
--- a/drivers/regulator/virtual.c
+++ b/drivers/regulator/virtual.c
@@ -226,13 +226,17 @@
 	unsigned int mode;
 	int ret;
 
-	if (strncmp(buf, "fast", strlen("fast")) == 0)
+	/*
+	 * sysfs_streq() doesn't need the \n's, but we add them so the strings
+	 * will be shared with show_mode(), above.
+	 */
+	if (sysfs_streq(buf, "fast\n") == 0)
 		mode = REGULATOR_MODE_FAST;
-	else if (strncmp(buf, "normal", strlen("normal")) == 0)
+	else if (sysfs_streq(buf, "normal\n") == 0)
 		mode = REGULATOR_MODE_NORMAL;
-	else if (strncmp(buf, "idle", strlen("idle")) == 0)
+	else if (sysfs_streq(buf, "idle\n") == 0)
 		mode = REGULATOR_MODE_IDLE;
-	else if (strncmp(buf, "standby", strlen("standby")) == 0)
+	else if (sysfs_streq(buf, "standby\n") == 0)
 		mode = REGULATOR_MODE_STANDBY;
 	else {
 		dev_err(dev, "Configuring invalid mode\n");
@@ -256,7 +260,7 @@
 static DEVICE_ATTR(max_microamps, 0666, show_max_uA, set_max_uA);
 static DEVICE_ATTR(mode, 0666, show_mode, set_mode);
 
-struct device_attribute *attributes[] = {
+static struct device_attribute *attributes[] = {
 	&dev_attr_min_microvolts,
 	&dev_attr_max_microvolts,
 	&dev_attr_min_microamps,
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c
index 5056e23..771eca1 100644
--- a/drivers/regulator/wm8350-regulator.c
+++ b/drivers/regulator/wm8350-regulator.c
@@ -24,6 +24,9 @@
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 
+/* Maximum value possible for VSEL */
+#define WM8350_DCDC_MAX_VSEL 0x66
+
 /* Microamps */
 static const int isink_cur[] = {
 	4,
@@ -385,6 +388,14 @@
 	return wm8350_dcdc_val_to_mvolts(val) * 1000;
 }
 
+static int wm8350_dcdc_list_voltage(struct regulator_dev *rdev,
+				    unsigned selector)
+{
+	if (selector > WM8350_DCDC_MAX_VSEL)
+		return -EINVAL;
+	return wm8350_dcdc_val_to_mvolts(selector) * 1000;
+}
+
 static int wm8350_dcdc_set_suspend_voltage(struct regulator_dev *rdev, int uV)
 {
 	struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
@@ -775,6 +786,14 @@
 	return wm8350_ldo_val_to_mvolts(val) * 1000;
 }
 
+static int wm8350_ldo_list_voltage(struct regulator_dev *rdev,
+				    unsigned selector)
+{
+	if (selector > WM8350_LDO1_VSEL_MASK)
+		return -EINVAL;
+	return wm8350_ldo_val_to_mvolts(selector) * 1000;
+}
+
 int wm8350_dcdc_set_slot(struct wm8350 *wm8350, int dcdc, u16 start,
 			 u16 stop, u16 fault)
 {
@@ -1031,18 +1050,30 @@
 	int dcdc = rdev_get_id(rdev);
 	u16 mask, sleep, active, force;
 	int mode = REGULATOR_MODE_NORMAL;
+	int reg;
 
-	if (dcdc < WM8350_DCDC_1 || dcdc > WM8350_DCDC_6)
+	switch (dcdc) {
+	case WM8350_DCDC_1:
+		reg = WM8350_DCDC1_FORCE_PWM;
+		break;
+	case WM8350_DCDC_3:
+		reg = WM8350_DCDC3_FORCE_PWM;
+		break;
+	case WM8350_DCDC_4:
+		reg = WM8350_DCDC4_FORCE_PWM;
+		break;
+	case WM8350_DCDC_6:
+		reg = WM8350_DCDC6_FORCE_PWM;
+		break;
+	default:
 		return -EINVAL;
-
-	if (dcdc == WM8350_DCDC_2 || dcdc == WM8350_DCDC_5)
-		return -EINVAL;
+	}
 
 	mask = 1 << (dcdc - WM8350_DCDC_1);
 	active = wm8350_reg_read(wm8350, WM8350_DCDC_ACTIVE_OPTIONS) & mask;
+	force = wm8350_reg_read(wm8350, reg) & WM8350_DCDC1_FORCE_PWM_ENA;
 	sleep = wm8350_reg_read(wm8350, WM8350_DCDC_SLEEP_OPTIONS) & mask;
-	force = wm8350_reg_read(wm8350, WM8350_DCDC1_FORCE_PWM)
-	    & WM8350_DCDC1_FORCE_PWM_ENA;
+
 	dev_dbg(wm8350->dev, "mask %x active %x sleep %x force %x",
 		mask, active, sleep, force);
 
@@ -1150,6 +1181,7 @@
 static struct regulator_ops wm8350_dcdc_ops = {
 	.set_voltage = wm8350_dcdc_set_voltage,
 	.get_voltage = wm8350_dcdc_get_voltage,
+	.list_voltage = wm8350_dcdc_list_voltage,
 	.enable = wm8350_dcdc_enable,
 	.disable = wm8350_dcdc_disable,
 	.get_mode = wm8350_dcdc_get_mode,
@@ -1173,6 +1205,7 @@
 static struct regulator_ops wm8350_ldo_ops = {
 	.set_voltage = wm8350_ldo_set_voltage,
 	.get_voltage = wm8350_ldo_get_voltage,
+	.list_voltage = wm8350_ldo_list_voltage,
 	.enable = wm8350_ldo_enable,
 	.disable = wm8350_ldo_disable,
 	.is_enabled = wm8350_ldo_is_enabled,
@@ -1197,6 +1230,7 @@
 		.ops = &wm8350_dcdc_ops,
 		.irq = WM8350_IRQ_UV_DC1,
 		.type = REGULATOR_VOLTAGE,
+		.n_voltages = WM8350_DCDC_MAX_VSEL + 1,
 		.owner = THIS_MODULE,
 	},
 	{
@@ -1213,6 +1247,7 @@
 		.ops = &wm8350_dcdc_ops,
 		.irq = WM8350_IRQ_UV_DC3,
 		.type = REGULATOR_VOLTAGE,
+		.n_voltages = WM8350_DCDC_MAX_VSEL + 1,
 		.owner = THIS_MODULE,
 	},
 	{
@@ -1221,6 +1256,7 @@
 		.ops = &wm8350_dcdc_ops,
 		.irq = WM8350_IRQ_UV_DC4,
 		.type = REGULATOR_VOLTAGE,
+		.n_voltages = WM8350_DCDC_MAX_VSEL + 1,
 		.owner = THIS_MODULE,
 	},
 	{
@@ -1237,6 +1273,7 @@
 		.ops = &wm8350_dcdc_ops,
 		.irq = WM8350_IRQ_UV_DC6,
 		.type = REGULATOR_VOLTAGE,
+		.n_voltages = WM8350_DCDC_MAX_VSEL + 1,
 		.owner = THIS_MODULE,
 	},
 	{
@@ -1245,6 +1282,7 @@
 		.ops = &wm8350_ldo_ops,
 		.irq = WM8350_IRQ_UV_LDO1,
 		.type = REGULATOR_VOLTAGE,
+		.n_voltages = WM8350_LDO1_VSEL_MASK + 1,
 		.owner = THIS_MODULE,
 	},
 	{
@@ -1253,6 +1291,7 @@
 		.ops = &wm8350_ldo_ops,
 		.irq = WM8350_IRQ_UV_LDO2,
 		.type = REGULATOR_VOLTAGE,
+		.n_voltages = WM8350_LDO2_VSEL_MASK + 1,
 		.owner = THIS_MODULE,
 	},
 	{
@@ -1261,6 +1300,7 @@
 		.ops = &wm8350_ldo_ops,
 		.irq = WM8350_IRQ_UV_LDO3,
 		.type = REGULATOR_VOLTAGE,
+		.n_voltages = WM8350_LDO3_VSEL_MASK + 1,
 		.owner = THIS_MODULE,
 	},
 	{
@@ -1269,6 +1309,7 @@
 		.ops = &wm8350_ldo_ops,
 		.irq = WM8350_IRQ_UV_LDO4,
 		.type = REGULATOR_VOLTAGE,
+		.n_voltages = WM8350_LDO4_VSEL_MASK + 1,
 		.owner = THIS_MODULE,
 	},
 	{
@@ -1293,6 +1334,7 @@
 {
 	struct regulator_dev *rdev = (struct regulator_dev *)data;
 
+	mutex_lock(&rdev->mutex);
 	if (irq == WM8350_IRQ_CS1 || irq == WM8350_IRQ_CS2)
 		regulator_notifier_call_chain(rdev,
 					      REGULATOR_EVENT_REGULATION_OUT,
@@ -1301,6 +1343,7 @@
 		regulator_notifier_call_chain(rdev,
 					      REGULATOR_EVENT_UNDER_VOLTAGE,
 					      wm8350);
+	mutex_unlock(&rdev->mutex);
 }
 
 static int wm8350_regulator_probe(struct platform_device *pdev)
@@ -1333,9 +1376,9 @@
 		break;
 	}
 
-
 	/* register regulator */
 	rdev = regulator_register(&wm8350_reg[pdev->id], &pdev->dev,
+				  pdev->dev.platform_data,
 				  dev_get_drvdata(&pdev->dev));
 	if (IS_ERR(rdev)) {
 		dev_err(&pdev->dev, "failed to register %s\n",
diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c
index 56e23d4..1574260 100644
--- a/drivers/regulator/wm8400-regulator.c
+++ b/drivers/regulator/wm8400-regulator.c
@@ -43,6 +43,18 @@
 			       WM8400_LDO1_ENA, 0);
 }
 
+static int wm8400_ldo_list_voltage(struct regulator_dev *dev,
+				   unsigned selector)
+{
+	if (selector > WM8400_LDO1_VSEL_MASK)
+		return -EINVAL;
+
+	if (selector < 15)
+		return 900000 + (selector * 50000);
+	else
+		return 1600000 + ((selector - 14) * 100000);
+}
+
 static int wm8400_ldo_get_voltage(struct regulator_dev *dev)
 {
 	struct wm8400 *wm8400 = rdev_get_drvdata(dev);
@@ -51,10 +63,7 @@
 	val = wm8400_reg_read(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev));
 	val &= WM8400_LDO1_VSEL_MASK;
 
-	if (val < 15)
-		return 900000 + (val * 50000);
-	else
-		return 1600000 + ((val - 14) * 100000);
+	return wm8400_ldo_list_voltage(dev, val);
 }
 
 static int wm8400_ldo_set_voltage(struct regulator_dev *dev,
@@ -92,6 +101,7 @@
 	.is_enabled = wm8400_ldo_is_enabled,
 	.enable = wm8400_ldo_enable,
 	.disable = wm8400_ldo_disable,
+	.list_voltage = wm8400_ldo_list_voltage,
 	.get_voltage = wm8400_ldo_get_voltage,
 	.set_voltage = wm8400_ldo_set_voltage,
 };
@@ -124,6 +134,15 @@
 			       WM8400_DC1_ENA, 0);
 }
 
+static int wm8400_dcdc_list_voltage(struct regulator_dev *dev,
+				    unsigned selector)
+{
+	if (selector > WM8400_DC1_VSEL_MASK)
+		return -EINVAL;
+
+	return 850000 + (selector * 25000);
+}
+
 static int wm8400_dcdc_get_voltage(struct regulator_dev *dev)
 {
 	struct wm8400 *wm8400 = rdev_get_drvdata(dev);
@@ -237,6 +256,7 @@
 	.is_enabled = wm8400_dcdc_is_enabled,
 	.enable = wm8400_dcdc_enable,
 	.disable = wm8400_dcdc_disable,
+	.list_voltage = wm8400_dcdc_list_voltage,
 	.get_voltage = wm8400_dcdc_get_voltage,
 	.set_voltage = wm8400_dcdc_set_voltage,
 	.get_mode = wm8400_dcdc_get_mode,
@@ -249,6 +269,7 @@
 		.name = "LDO1",
 		.id = WM8400_LDO1,
 		.ops = &wm8400_ldo_ops,
+		.n_voltages = WM8400_LDO1_VSEL_MASK + 1,
 		.type = REGULATOR_VOLTAGE,
 		.owner = THIS_MODULE,
 	},
@@ -256,6 +277,7 @@
 		.name = "LDO2",
 		.id = WM8400_LDO2,
 		.ops = &wm8400_ldo_ops,
+		.n_voltages = WM8400_LDO2_VSEL_MASK + 1,
 		.type = REGULATOR_VOLTAGE,
 		.owner = THIS_MODULE,
 	},
@@ -263,6 +285,7 @@
 		.name = "LDO3",
 		.id = WM8400_LDO3,
 		.ops = &wm8400_ldo_ops,
+		.n_voltages = WM8400_LDO3_VSEL_MASK + 1,
 		.type = REGULATOR_VOLTAGE,
 		.owner = THIS_MODULE,
 	},
@@ -270,6 +293,7 @@
 		.name = "LDO4",
 		.id = WM8400_LDO4,
 		.ops = &wm8400_ldo_ops,
+		.n_voltages = WM8400_LDO4_VSEL_MASK + 1,
 		.type = REGULATOR_VOLTAGE,
 		.owner = THIS_MODULE,
 	},
@@ -277,6 +301,7 @@
 		.name = "DCDC1",
 		.id = WM8400_DCDC1,
 		.ops = &wm8400_dcdc_ops,
+		.n_voltages = WM8400_DC1_VSEL_MASK + 1,
 		.type = REGULATOR_VOLTAGE,
 		.owner = THIS_MODULE,
 	},
@@ -284,6 +309,7 @@
 		.name = "DCDC2",
 		.id = WM8400_DCDC2,
 		.ops = &wm8400_dcdc_ops,
+		.n_voltages = WM8400_DC2_VSEL_MASK + 1,
 		.type = REGULATOR_VOLTAGE,
 		.owner = THIS_MODULE,
 	},
@@ -294,7 +320,7 @@
 	struct regulator_dev *rdev;
 
 	rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
-		pdev->dev.driver_data);
+		pdev->dev.platform_data, pdev->dev.driver_data);
 
 	if (IS_ERR(rdev))
 		return PTR_ERR(rdev);
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 56002f7..ffe34a1 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -688,22 +688,16 @@
 	help
 	  If you say yes here you get support for the Ricoh RS5C313 RTC chips.
 
-config RTC_DRV_PARISC
-	tristate "PA-RISC firmware RTC support"
-	depends on PARISC
+config RTC_DRV_GENERIC
+	tristate "Generic RTC support"
+	# Please consider writing a new RTC driver instead of using the generic
+	# RTC abstraction
+	depends on PARISC || M68K || PPC
 	help
-	  Say Y or M here to enable RTC support on PA-RISC systems using
-	  firmware calls. If you do not know what you are doing, you should
+	  Say Y or M here to enable RTC support on systems using the generic
+	  RTC abstraction. If you do not know what you are doing, you should
 	  just say Y.
 
-config RTC_DRV_PPC
-       tristate "PowerPC machine dependent RTC support"
-       depends on PPC
-       help
-	 The PowerPC kernel has machine-specific functions for accessing
-	 the RTC. This exposes that functionality through the generic RTC
-	 class.
-
 config RTC_DRV_PXA
        tristate "PXA27x/PXA3xx"
        depends on ARCH_PXA
@@ -747,4 +741,13 @@
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-mv.
 
+config RTC_DRV_PS3
+	tristate "PS3 RTC"
+	depends on PPC_PS3
+	help
+	  If you say yes here you will get support for the RTC on PS3.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-ps3.
+
 endif # RTC_CLASS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index e7b0998..6c0639a 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -56,8 +56,7 @@
 obj-$(CONFIG_RTC_DRV_PCF8583)	+= rtc-pcf8583.o
 obj-$(CONFIG_RTC_DRV_PL030)	+= rtc-pl030.o
 obj-$(CONFIG_RTC_DRV_PL031)	+= rtc-pl031.o
-obj-$(CONFIG_RTC_DRV_PARISC)	+= rtc-parisc.o
-obj-$(CONFIG_RTC_DRV_PPC)	+= rtc-ppc.o
+obj-$(CONFIG_RTC_DRV_GENERIC)	+= rtc-generic.o
 obj-$(CONFIG_RTC_DRV_PXA)	+= rtc-pxa.o
 obj-$(CONFIG_RTC_DRV_R9701)	+= rtc-r9701.o
 obj-$(CONFIG_RTC_DRV_RS5C313)	+= rtc-rs5c313.o
@@ -77,3 +76,4 @@
 obj-$(CONFIG_RTC_DRV_WM8350)	+= rtc-wm8350.o
 obj-$(CONFIG_RTC_DRV_X1205)	+= rtc-x1205.o
 obj-$(CONFIG_RTC_DRV_PCF50633)	+= rtc-pcf50633.o
+obj-$(CONFIG_RTC_DRV_PS3)	+= rtc-ps3.o
diff --git a/drivers/rtc/rtc-generic.c b/drivers/rtc/rtc-generic.c
new file mode 100644
index 0000000..98322004
--- /dev/null
+++ b/drivers/rtc/rtc-generic.c
@@ -0,0 +1,84 @@
+/* rtc-generic: RTC driver using the generic RTC abstraction
+ *
+ * Copyright (C) 2008 Kyle McMartin <kyle@mcmartin.ca>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/time.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+#include <asm/rtc.h>
+
+static int generic_get_time(struct device *dev, struct rtc_time *tm)
+{
+	unsigned int ret = get_rtc_time(tm);
+
+	if (ret & RTC_BATT_BAD)
+		return -EOPNOTSUPP;
+
+	return rtc_valid_tm(tm);
+}
+
+static int generic_set_time(struct device *dev, struct rtc_time *tm)
+{
+	if (set_rtc_time(tm) < 0)
+		return -EOPNOTSUPP;
+
+	return 0;
+}
+
+static const struct rtc_class_ops generic_rtc_ops = {
+	.read_time = generic_get_time,
+	.set_time = generic_set_time,
+};
+
+static int __init generic_rtc_probe(struct platform_device *dev)
+{
+	struct rtc_device *rtc;
+
+	rtc = rtc_device_register("rtc-generic", &dev->dev, &generic_rtc_ops,
+				  THIS_MODULE);
+	if (IS_ERR(rtc))
+		return PTR_ERR(rtc);
+
+	platform_set_drvdata(dev, rtc);
+
+	return 0;
+}
+
+static int __exit generic_rtc_remove(struct platform_device *dev)
+{
+	struct rtc_device *rtc = platform_get_drvdata(dev);
+
+	rtc_device_unregister(rtc);
+
+	return 0;
+}
+
+static struct platform_driver generic_rtc_driver = {
+	.driver = {
+		.name = "rtc-generic",
+		.owner = THIS_MODULE,
+	},
+	.remove = __exit_p(generic_rtc_remove),
+};
+
+static int __init generic_rtc_init(void)
+{
+	return platform_driver_probe(&generic_rtc_driver, generic_rtc_probe);
+}
+
+static void __exit generic_rtc_fini(void)
+{
+	platform_driver_unregister(&generic_rtc_driver);
+}
+
+module_init(generic_rtc_init);
+module_exit(generic_rtc_fini);
+
+MODULE_AUTHOR("Kyle McMartin <kyle@mcmartin.ca>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic RTC driver");
+MODULE_ALIAS("platform:rtc-generic");
diff --git a/drivers/rtc/rtc-parisc.c b/drivers/rtc/rtc-parisc.c
deleted file mode 100644
index b966f56..0000000
--- a/drivers/rtc/rtc-parisc.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/* rtc-parisc: RTC for HP PA-RISC firmware
- *
- * Copyright (C) 2008 Kyle McMartin <kyle@mcmartin.ca>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/time.h>
-#include <linux/platform_device.h>
-#include <linux/rtc.h>
-
-#include <asm/rtc.h>
-
-static int parisc_get_time(struct device *dev, struct rtc_time *tm)
-{
-	unsigned long ret;
-
-	ret = get_rtc_time(tm);
-
-	if (ret & RTC_BATT_BAD)
-		return -EOPNOTSUPP;
-
-	return rtc_valid_tm(tm);
-}
-
-static int parisc_set_time(struct device *dev, struct rtc_time *tm)
-{
-	if (set_rtc_time(tm) < 0)
-		return -EOPNOTSUPP;
-
-	return 0;
-}
-
-static const struct rtc_class_ops parisc_rtc_ops = {
-	.read_time = parisc_get_time,
-	.set_time = parisc_set_time,
-};
-
-static int __init parisc_rtc_probe(struct platform_device *dev)
-{
-	struct rtc_device *rtc;
-
-	rtc = rtc_device_register("rtc-parisc", &dev->dev, &parisc_rtc_ops,
-				  THIS_MODULE);
-	if (IS_ERR(rtc))
-		return PTR_ERR(rtc);
-
-	platform_set_drvdata(dev, rtc);
-
-	return 0;
-}
-
-static int __exit parisc_rtc_remove(struct platform_device *dev)
-{
-	struct rtc_device *rtc = platform_get_drvdata(dev);
-
-	rtc_device_unregister(rtc);
-
-	return 0;
-}
-
-static struct platform_driver parisc_rtc_driver = {
-	.driver = {
-		.name = "rtc-parisc",
-		.owner = THIS_MODULE,
-	},
-	.probe = parisc_rtc_probe,
-	.remove = __devexit_p(parisc_rtc_remove),
-};
-
-static int __init parisc_rtc_init(void)
-{
-	return platform_driver_probe(&parisc_rtc_driver, parisc_rtc_probe);
-}
-
-static void __exit parisc_rtc_fini(void)
-{
-	platform_driver_unregister(&parisc_rtc_driver);
-}
-
-module_init(parisc_rtc_init);
-module_exit(parisc_rtc_fini);
-
-MODULE_AUTHOR("Kyle McMartin <kyle@mcmartin.ca>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("HP PA-RISC RTC driver");
diff --git a/drivers/rtc/rtc-ppc.c b/drivers/rtc/rtc-ppc.c
deleted file mode 100644
index c8e97e2..0000000
--- a/drivers/rtc/rtc-ppc.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * RTC driver for ppc_md RTC functions
- *
- * © 2007 Red Hat, Inc.
- *
- * Author: David Woodhouse <dwmw2@infradead.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/module.h>
-#include <linux/err.h>
-#include <linux/rtc.h>
-#include <linux/platform_device.h>
-#include <asm/machdep.h>
-
-static int ppc_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
-	ppc_md.get_rtc_time(tm);
-	return 0;
-}
-
-static int ppc_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
-	return ppc_md.set_rtc_time(tm);
-}
-
-static const struct rtc_class_ops ppc_rtc_ops = {
-	.set_time = ppc_rtc_set_time,
-	.read_time = ppc_rtc_read_time,
-};
-
-static struct rtc_device *rtc;
-static struct platform_device *ppc_rtc_pdev;
-
-static int __init ppc_rtc_init(void)
-{
-	if (!ppc_md.get_rtc_time || !ppc_md.set_rtc_time)
-		return -ENODEV;
-
-	ppc_rtc_pdev = platform_device_register_simple("ppc-rtc", 0, NULL, 0);
-	if (IS_ERR(ppc_rtc_pdev))
-		return PTR_ERR(ppc_rtc_pdev);
-
-	rtc = rtc_device_register("ppc_md", &ppc_rtc_pdev->dev,
-				  &ppc_rtc_ops, THIS_MODULE);
-	if (IS_ERR(rtc)) {
-		platform_device_unregister(ppc_rtc_pdev);
-		return PTR_ERR(rtc);
-	}
-
-	return 0;
-}
-
-static void __exit ppc_rtc_exit(void)
-{
-	rtc_device_unregister(rtc);
-	platform_device_unregister(ppc_rtc_pdev);
-}
-
-module_init(ppc_rtc_init);
-module_exit(ppc_rtc_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-MODULE_DESCRIPTION("Generic RTC class driver for PowerPC");
diff --git a/drivers/rtc/rtc-ps3.c b/drivers/rtc/rtc-ps3.c
new file mode 100644
index 0000000..968133c
--- /dev/null
+++ b/drivers/rtc/rtc-ps3.c
@@ -0,0 +1,104 @@
+/*
+ * PS3 RTC Driver
+ *
+ * Copyright 2009 Sony 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; version 2 of the License.
+ *
+ * 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/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+#include <asm/lv1call.h>
+#include <asm/ps3.h>
+
+
+static u64 read_rtc(void)
+{
+	int result;
+	u64 rtc_val;
+	u64 tb_val;
+
+	result = lv1_get_rtc(&rtc_val, &tb_val);
+	BUG_ON(result);
+
+	return rtc_val;
+}
+
+static int ps3_get_time(struct device *dev, struct rtc_time *tm)
+{
+	rtc_time_to_tm(read_rtc() + ps3_os_area_get_rtc_diff(), tm);
+	return rtc_valid_tm(tm);
+}
+
+static int ps3_set_time(struct device *dev, struct rtc_time *tm)
+{
+	unsigned long now;
+
+	rtc_tm_to_time(tm, &now);
+	ps3_os_area_set_rtc_diff(now - read_rtc());
+	return 0;
+}
+
+static const struct rtc_class_ops ps3_rtc_ops = {
+	.read_time = ps3_get_time,
+	.set_time = ps3_set_time,
+};
+
+static int __init ps3_rtc_probe(struct platform_device *dev)
+{
+	struct rtc_device *rtc;
+
+	rtc = rtc_device_register("rtc-ps3", &dev->dev, &ps3_rtc_ops,
+				  THIS_MODULE);
+	if (IS_ERR(rtc))
+		return PTR_ERR(rtc);
+
+	platform_set_drvdata(dev, rtc);
+	return 0;
+}
+
+static int __exit ps3_rtc_remove(struct platform_device *dev)
+{
+	rtc_device_unregister(platform_get_drvdata(dev));
+	return 0;
+}
+
+static struct platform_driver ps3_rtc_driver = {
+	.driver = {
+		.name = "rtc-ps3",
+		.owner = THIS_MODULE,
+	},
+	.remove = __exit_p(ps3_rtc_remove),
+};
+
+static int __init ps3_rtc_init(void)
+{
+	return platform_driver_probe(&ps3_rtc_driver, ps3_rtc_probe);
+}
+
+static void __exit ps3_rtc_fini(void)
+{
+	platform_driver_unregister(&ps3_rtc_driver);
+}
+
+module_init(ps3_rtc_init);
+module_exit(ps3_rtc_fini);
+
+MODULE_AUTHOR("Sony Corporation");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ps3 RTC driver");
+MODULE_ALIAS("platform:rtc-ps3");
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index 4898f7f..9b1ff12 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -795,10 +795,46 @@
 
 	return 0;
 }
+
+static void sh_rtc_set_irq_wake(struct device *dev, int enabled)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct sh_rtc *rtc = platform_get_drvdata(pdev);
+
+	set_irq_wake(rtc->periodic_irq, enabled);
+	if (rtc->carry_irq > 0) {
+		set_irq_wake(rtc->carry_irq, enabled);
+		set_irq_wake(rtc->alarm_irq, enabled);
+	}
+
+}
+
+static int sh_rtc_suspend(struct device *dev)
+{
+	if (device_may_wakeup(dev))
+		sh_rtc_set_irq_wake(dev, 1);
+
+	return 0;
+}
+
+static int sh_rtc_resume(struct device *dev)
+{
+	if (device_may_wakeup(dev))
+		sh_rtc_set_irq_wake(dev, 0);
+
+	return 0;
+}
+
+static struct dev_pm_ops sh_rtc_dev_pm_ops = {
+	.suspend = sh_rtc_suspend,
+	.resume = sh_rtc_resume,
+};
+
 static struct platform_driver sh_rtc_platform_driver = {
 	.driver		= {
 		.name	= DRV_NAME,
 		.owner	= THIS_MODULE,
+		.pm	= &sh_rtc_dev_pm_ops,
 	},
 	.probe		= sh_rtc_probe,
 	.remove		= __devexit_p(sh_rtc_remove),
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 876cd20..8ed2990 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -1387,7 +1387,7 @@
 	bool "Emulex LightPulse Fibre Channel debugfs Support"
 	depends on SCSI_LPFC && DEBUG_FS
 	help
-	  This makes debugging infomation from the lpfc driver
+	  This makes debugging information from the lpfc driver
 	  available via the debugfs filesystem.
 
 config SCSI_SIM710
@@ -1395,7 +1395,7 @@
 	depends on (EISA || MCA) && SCSI
 	select SCSI_SPI_ATTRS
 	---help---
-	  This driver for NCR53c710 based SCSI host adapters.
+	  This driver is for NCR53c710 based SCSI host adapters.
 
 	  It currently supports Compaq EISA cards and NCR MCA cards
 
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 9be11b0..aa9d3a4 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -1374,7 +1374,7 @@
 	depends on BLACKFIN && EXPERIMENTAL
 	select SERIAL_CORE
 	help
-	  Enble support SPORT emulate UART on Blackfin series.
+	  Enable SPORT emulate UART on Blackfin series.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called bfin_sport_uart.
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c
index 8f58f7f..b3497d7 100644
--- a/drivers/serial/atmel_serial.c
+++ b/drivers/serial/atmel_serial.c
@@ -1020,7 +1020,8 @@
 
 	/* Get current mode register */
 	mode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL
-					| ATMEL_US_NBSTOP | ATMEL_US_PAR);
+					| ATMEL_US_NBSTOP | ATMEL_US_PAR
+					| ATMEL_US_USMODE);
 
 	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
 	quot = uart_get_divisor(port, baud);
@@ -1065,6 +1066,12 @@
 	} else
 		mode |= ATMEL_US_PAR_NONE;
 
+	/* hardware handshake (RTS/CTS) */
+	if (termios->c_cflag & CRTSCTS)
+		mode |= ATMEL_US_USMODE_HWHS;
+	else
+		mode |= ATMEL_US_USMODE_NORMAL;
+
 	spin_lock_irqsave(&port->lock, flags);
 
 	port->read_status_mask = ATMEL_US_OVRE;
diff --git a/drivers/serial/mcf.c b/drivers/serial/mcf.c
index 56841fe..0eefb07 100644
--- a/drivers/serial/mcf.c
+++ b/drivers/serial/mcf.c
@@ -513,7 +513,7 @@
 	int parity = 'n';
 	int flow = 'n';
 
-	if ((co->index >= 0) && (co->index <= MCF_MAXPORTS))
+	if ((co->index < 0) || (co->index >= MCF_MAXPORTS))
 		co->index = 0;
 	port = &mcf_ports[co->index].port;
 	if (port->membase == 0)
diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c
index 2269fbc..7fb9b5c 100644
--- a/drivers/sh/intc.c
+++ b/drivers/sh/intc.c
@@ -22,6 +22,8 @@
 #include <linux/interrupt.h>
 #include <linux/bootmem.h>
 #include <linux/sh_intc.h>
+#include <linux/sysdev.h>
+#include <linux/list.h>
 
 #define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \
 	((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \
@@ -40,6 +42,8 @@
 };
 
 struct intc_desc_int {
+	struct list_head list;
+	struct sys_device sysdev;
 	unsigned long *reg;
 #ifdef CONFIG_SMP
 	unsigned long *smp;
@@ -52,6 +56,8 @@
 	struct irq_chip chip;
 };
 
+static LIST_HEAD(intc_list);
+
 #ifdef CONFIG_SMP
 #define IS_SMP(x) x.smp
 #define INTC_REG(d, x, c) (d->reg[(x)] + ((d->smp[(x)] & 0xff) * c))
@@ -232,6 +238,11 @@
 	}
 }
 
+static int intc_set_wake(unsigned int irq, unsigned int on)
+{
+	return 0; /* allow wakeup, but setup hardware in intc_suspend() */
+}
+
 #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
 static void intc_mask_ack(unsigned int irq)
 {
@@ -664,6 +675,9 @@
 
 	d = alloc_bootmem(sizeof(*d));
 
+	INIT_LIST_HEAD(&d->list);
+	list_add(&d->list, &intc_list);
+
 	d->nr_reg = desc->mask_regs ? desc->nr_mask_regs * 2 : 0;
 	d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0;
 	d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0;
@@ -707,7 +721,11 @@
 	d->chip.mask = intc_disable;
 	d->chip.unmask = intc_enable;
 	d->chip.mask_ack = intc_disable;
+	d->chip.enable = intc_enable;
+	d->chip.disable = intc_disable;
+	d->chip.shutdown = intc_disable;
 	d->chip.set_type = intc_set_sense;
+	d->chip.set_wake = intc_set_wake;
 
 #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
 	if (desc->ack_regs) {
@@ -758,3 +776,53 @@
 		intc_register_irq(desc, d, vect->enum_id, evt2irq(vect->vect));
 	}
 }
+
+static int intc_suspend(struct sys_device *dev, pm_message_t state)
+{
+	struct intc_desc_int *d;
+	struct irq_desc *desc;
+	int irq;
+
+	/* get intc controller associated with this sysdev */
+	d = container_of(dev, struct intc_desc_int, sysdev);
+
+	/* enable wakeup irqs belonging to this intc controller */
+	for_each_irq_desc(irq, desc) {
+		if ((desc->status & IRQ_WAKEUP) && (desc->chip == &d->chip))
+			intc_enable(irq);
+	}
+
+	return 0;
+}
+
+static struct sysdev_class intc_sysdev_class = {
+	.name = "intc",
+	.suspend = intc_suspend,
+};
+
+/* register this intc as sysdev to allow suspend/resume */
+static int __init register_intc_sysdevs(void)
+{
+	struct intc_desc_int *d;
+	int error;
+	int id = 0;
+
+	error = sysdev_class_register(&intc_sysdev_class);
+	if (!error) {
+		list_for_each_entry(d, &intc_list, list) {
+			d->sysdev.id = id;
+			d->sysdev.cls = &intc_sysdev_class;
+			error = sysdev_register(&d->sysdev);
+			if (error)
+				break;
+			id++;
+		}
+	}
+
+	if (error)
+		pr_warning("intc: sysdev registration error\n");
+
+	return error;
+}
+
+device_initcall(register_intc_sysdevs);
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 211af86..0dcf9ca 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -4,7 +4,7 @@
 	---help---
 	  This option allows you to select a number of drivers that are
 	  not of the "normal" Linux kernel quality level.  These drivers
-	  are placed here in order to get a wider audience for use of
+	  are placed here in order to get a wider audience to make use of
 	  them.  Please note that these drivers are under heavy
 	  development, may or may not work, and may contain userspace
 	  interfaces that most likely will be changed in the near
@@ -12,7 +12,7 @@
 
 	  Using any of these drivers will taint your kernel which might
 	  affect support options from both the community, and various
-	  commercial support orginizations.
+	  commercial support organizations.
 
 	  If you wish to work on these drivers, to help improve them, or
 	  to report problems you have with them, please see the
@@ -73,6 +73,8 @@
 
 source "drivers/staging/rt2870/Kconfig"
 
+source "drivers/staging/rt3070/Kconfig"
+
 source "drivers/staging/comedi/Kconfig"
 
 source "drivers/staging/asus_oled/Kconfig"
@@ -93,5 +95,25 @@
 
 source "drivers/staging/android/Kconfig"
 
+source "drivers/staging/dst/Kconfig"
+
+source "drivers/staging/pohmelfs/Kconfig"
+
+source "drivers/staging/stlc45xx/Kconfig"
+
+source "drivers/staging/uc2322/Kconfig"
+
+source "drivers/staging/b3dfg/Kconfig"
+
+source "drivers/staging/phison/Kconfig"
+
+source "drivers/staging/p9auth/Kconfig"
+
+source "drivers/staging/heci/Kconfig"
+
+source "drivers/staging/line6/Kconfig"
+
+source "drivers/staging/serqt_usb/Kconfig"
+
 endif # !STAGING_EXCLUDE_BUILD
 endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 47a56f5..47dfd5b4 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -19,6 +19,7 @@
 obj-$(CONFIG_OTUS)		+= otus/
 obj-$(CONFIG_RT2860)		+= rt2860/
 obj-$(CONFIG_RT2870)		+= rt2870/
+obj-$(CONFIG_RT3070)		+= rt3070/
 obj-$(CONFIG_COMEDI)		+= comedi/
 obj-$(CONFIG_ASUS_OLED)		+= asus_oled/
 obj-$(CONFIG_PANEL)		+= panel/
@@ -29,3 +30,13 @@
 obj-$(CONFIG_TRANZPORT)		+= frontier/
 obj-$(CONFIG_EPL)		+= epl/
 obj-$(CONFIG_ANDROID)		+= android/
+obj-$(CONFIG_DST)		+= dst/
+obj-$(CONFIG_POHMELFS)		+= pohmelfs/
+obj-$(CONFIG_STLC45XX)		+= stlc45xx/
+obj-$(CONFIG_USB_SERIAL_ATEN2011)	+= uc2322/
+obj-$(CONFIG_B3DFG)		+= b3dfg/
+obj-$(CONFIG_IDE_PHISON)	+= phison/
+obj-$(CONFIG_PLAN9AUTH)		+= p9auth/
+obj-$(CONFIG_HECI)		+= heci/
+obj-$(CONFIG_LINE6_USB)		+= line6/
+obj-$(CONFIG_USB_SERIAL_QUATECH_ESU100)	+= serqt_usb/
diff --git a/drivers/staging/agnx/agnx.h b/drivers/staging/agnx/agnx.h
index 20f36da..3963d25 100644
--- a/drivers/staging/agnx/agnx.h
+++ b/drivers/staging/agnx/agnx.h
@@ -41,16 +41,16 @@
 /* 	{ .bitrate = 20, .hw_value = 2, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, */
 /* 	{ .bitrate = 55, .hw_value = 3, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, */
 /* 	{ .bitrate = 110, .hw_value = 4, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, */
- 	{ .bitrate = 10, .hw_value = 1, },
- 	{ .bitrate = 20, .hw_value = 2, },
- 	{ .bitrate = 55, .hw_value = 3, },
- 	{ .bitrate = 110, .hw_value = 4,},
+	{ .bitrate = 10, .hw_value = 1, },
+	{ .bitrate = 20, .hw_value = 2, },
+	{ .bitrate = 55, .hw_value = 3, },
+	{ .bitrate = 110, .hw_value = 4,},
 
 	{ .bitrate = 60, .hw_value = 0xB, },
 	{ .bitrate = 90, .hw_value = 0xF, },
 	{ .bitrate = 120, .hw_value = 0xA },
 	{ .bitrate = 180, .hw_value = 0xE, },
-//	{ .bitrate = 240, .hw_value = 0xd, },
+/*	{ .bitrate = 240, .hw_value = 0xd, }, */
 	{ .bitrate = 360, .hw_value = 0xD, },
 	{ .bitrate = 480, .hw_value = 0x8, },
 	{ .bitrate = 540, .hw_value = 0xC, },
@@ -110,10 +110,10 @@
 	/* Need volatile? */
 	u32 irq_status;
 
-        struct delayed_work periodic_work; /* Periodic tasks like recalibrate*/
+	struct delayed_work periodic_work; /* Periodic tasks like recalibrate */
 	struct ieee80211_low_level_stats stats;
 
-//        unsigned int phymode;
+	/* unsigned int phymode; */
 	int mode;
 	int channel;
 	u8 bssid[ETH_ALEN];
diff --git a/drivers/staging/agnx/debug.h b/drivers/staging/agnx/debug.h
index e3e25dd..761d99c 100644
--- a/drivers/staging/agnx/debug.h
+++ b/drivers/staging/agnx/debug.h
@@ -23,7 +23,7 @@
 
 static inline void agnx_print_desc(struct agnx_desc *desc)
 {
-        u32 reg = be32_to_cpu(desc->frag);
+	u32 reg = be32_to_cpu(desc->frag);
 
 	PRINTK_BITS(DESC, PACKET_LEN);
 
@@ -291,7 +291,7 @@
 	PRINTK_LE32(STA, sta->phy_stats_high);
 	PRINTK_LE32(STA, sta->phy_stats_low);
 
-//	for (i = 0; i < 8; i++)
+	/* for (i = 0; i < 8; i++) */
 	agnx_print_sta_traffic(sta->traffic + 0);
 
 	PRINTK_LE16(STA, sta->traffic_class0_frag_success);
@@ -311,10 +311,10 @@
 static inline void dump_ieee80211_hdr(struct ieee80211_hdr *hdr, char *tag)
 {
 	u16 fctl;
-        int hdrlen;
+	int hdrlen;
 	DECLARE_MAC_BUF(mac);
 
-        fctl = le16_to_cpu(hdr->frame_control);
+	fctl = le16_to_cpu(hdr->frame_control);
 	switch (fctl & IEEE80211_FCTL_FTYPE) {
 	case IEEE80211_FTYPE_DATA:
 		printk(PFX "%s DATA ", tag);
@@ -324,7 +324,7 @@
 		break;
 	case IEEE80211_FTYPE_MGMT:
 		printk(PFX "%s MGMT ", tag);
-		switch(fctl & IEEE80211_FCTL_STYPE) {
+		switch (fctl & IEEE80211_FCTL_STYPE) {
 		case IEEE80211_STYPE_ASSOC_REQ:
 			printk("SubType: ASSOC_REQ ");
 			break;
@@ -369,7 +369,7 @@
 		printk(PFX "%s Packet type: Unknow\n", tag);
 	}
 
-        hdrlen = ieee80211_hdrlen(fctl);
+	hdrlen = ieee80211_hdrlen(fctl);
 
 	if (hdrlen >= 4)
 		printk("FC=0x%04x DUR=0x%04x",
@@ -389,29 +389,28 @@
 {
 	void __iomem *ctl = priv->ctl;
 	int i;
-	for (i = 0; i <=0x1e8; i += 4) {
+	for (i = 0; i <= 0x1e8; i += 4)
 		printk(KERN_DEBUG PFX "TXM: %x---> 0x%.8x\n", i, ioread32(ctl + i));
-	}
 }
 static inline void dump_rxm_registers(struct agnx_priv *priv)
 {
 	void __iomem *ctl = priv->ctl;
 	int i;
-	for (i = 0; i <=0x108; i += 4)
+	for (i = 0; i <= 0x108; i += 4)
 		printk(KERN_DEBUG PFX "RXM: %x---> 0x%.8x\n", i, ioread32(ctl + 0x2000 + i));
 }
 static inline void dump_bm_registers(struct agnx_priv *priv)
 {
 	void __iomem *ctl = priv->ctl;
 	int i;
-	for (i = 0; i <=0x90; i += 4)
+	for (i = 0; i <= 0x90; i += 4)
 		printk(KERN_DEBUG PFX "BM: %x---> 0x%.8x\n", i, ioread32(ctl + 0x2c00 + i));
 }
 static inline void dump_cir_registers(struct agnx_priv *priv)
 {
 	void __iomem *ctl = priv->ctl;
 	int i;
-	for (i = 0; i <=0xb8; i += 4)
+	for (i = 0; i <= 0xb8; i += 4)
 		printk(KERN_DEBUG PFX "CIR: %x---> 0x%.8x\n", i, ioread32(ctl + 0x3000 + i));
 }
 
diff --git a/drivers/staging/agnx/pci.c b/drivers/staging/agnx/pci.c
index 854630c..4ff4c16 100644
--- a/drivers/staging/agnx/pci.c
+++ b/drivers/staging/agnx/pci.c
@@ -39,34 +39,34 @@
 	void __iomem *ctl = priv->ctl;
 	u32 reg;
 
-	if ( *reason & AGNX_STAT_RX ) {
+	if (*reason & AGNX_STAT_RX) {
 		/* Mark complete RX */
 		reg = ioread32(ctl + AGNX_CIR_RXCTL);
 		reg |= 0x4;
 		iowrite32(reg, ctl + AGNX_CIR_RXCTL);
 		/* disable Rx interrupt */
 	}
-	if ( *reason & AGNX_STAT_TX ) {
+	if (*reason & AGNX_STAT_TX) {
 		reg = ioread32(ctl + AGNX_CIR_TXDCTL);
 		if (reg & 0x4) {
 			iowrite32(reg, ctl + AGNX_CIR_TXDCTL);
 			*reason |= AGNX_STAT_TXD;
 		}
- 		reg = ioread32(ctl + AGNX_CIR_TXMCTL);
+		reg = ioread32(ctl + AGNX_CIR_TXMCTL);
 		if (reg & 0x4) {
 			iowrite32(reg, ctl + AGNX_CIR_TXMCTL);
 			*reason |= AGNX_STAT_TXM;
 		}
 	}
-	if ( *reason & AGNX_STAT_X ) {
-/* 		reg = ioread32(ctl + AGNX_INT_STAT); */
-/* 		iowrite32(reg, ctl + AGNX_INT_STAT); */
-/* 		/\* FIXME reinit interrupt mask *\/ */
-/* 		reg = 0xc390bf9 & ~IRQ_TX_BEACON; */
-/* 		reg &= ~IRQ_TX_DISABLE; */
-/* 		iowrite32(reg, ctl + AGNX_INT_MASK); */
-/* 		iowrite32(0x800, ctl + AGNX_CIR_BLKCTL); */
-	}
+/*	if (*reason & AGNX_STAT_X) {
+		reg = ioread32(ctl + AGNX_INT_STAT);
+		iowrite32(reg, ctl + AGNX_INT_STAT);
+		/* FIXME reinit interrupt mask *\/
+		reg = 0xc390bf9 & ~IRQ_TX_BEACON;
+		reg &= ~IRQ_TX_DISABLE;
+		iowrite32(reg, ctl + AGNX_INT_MASK);
+		iowrite32(0x800, ctl + AGNX_CIR_BLKCTL);
+	} */
 } /* agnx_interrupt_ack */
 
 static irqreturn_t agnx_interrupt_handler(int irq, void *dev_id)
@@ -79,7 +79,7 @@
 
 	spin_lock(&priv->lock);
 
-//	printk(KERN_ERR PFX "Get a interrupt %s\n", __func__);
+/*	printk(KERN_ERR PFX "Get a interrupt %s\n", __func__); */
 
 	if (priv->init_status != AGNX_START)
 		goto out;
@@ -92,7 +92,7 @@
 	ret = IRQ_HANDLED;
 	priv->irq_status = ioread32(ctl + AGNX_INT_STAT);
 
-//	printk(PFX "Interrupt reason is 0x%x\n", irq_reason);
+/*	printk(PFX "Interrupt reason is 0x%x\n", irq_reason); */
 	/* Make sure the txm and txd flags don't conflict with other unknown
 	   interrupt flag, maybe is not necessary */
 	irq_reason &= 0xF;
@@ -101,13 +101,13 @@
 	/* TODO Make sure the card finished initialized */
 	agnx_interrupt_ack(priv, &irq_reason);
 
-	if ( irq_reason & AGNX_STAT_RX )
+	if (irq_reason & AGNX_STAT_RX)
 		handle_rx_irq(priv);
-	if ( irq_reason & AGNX_STAT_TXD )
+	if (irq_reason & AGNX_STAT_TXD)
 		handle_txd_irq(priv);
-	if ( irq_reason & AGNX_STAT_TXM )
+	if (irq_reason & AGNX_STAT_TXM)
 		handle_txm_irq(priv);
-	if ( irq_reason & AGNX_STAT_X )
+	if (irq_reason & AGNX_STAT_X)
 		handle_other_irq(priv);
 
 	enable_rx_interrupt(priv);
@@ -171,7 +171,7 @@
 
 	len = priv->rx.size + priv->txm.size + priv->txd.size;
 
-//	priv->rx.info = kzalloc(sizeof(struct agnx_info) * len, GFP_KERNEL);
+/*	priv->rx.info = kzalloc(sizeof(struct agnx_info) * len, GFP_KERNEL); */
 	priv->rx.info = kzalloc(sizeof(struct agnx_info) * len, GFP_ATOMIC);
 	if (!priv->rx.info)
 		return -ENOMEM;
@@ -210,28 +210,27 @@
 #if 0
 static void agnx_periodic_work_handler(struct work_struct *work)
 {
-	struct agnx_priv *priv = container_of(work, struct agnx_priv,
-                                             periodic_work.work);
-//	unsigned long flags;
+	struct agnx_priv *priv = container_of(work, struct agnx_priv, periodic_work.work);
+/*	unsigned long flags; */
 	unsigned long delay;
 
 	/* fixme: using mutex?? */
-//	spin_lock_irqsave(&priv->lock, flags);
+/*	spin_lock_irqsave(&priv->lock, flags); */
 
 	/* TODO Recalibrate*/
-//	calibrate_oscillator(priv);
-//	antenna_calibrate(priv);
-//	agnx_send_packet(priv, 997);
+/*	calibrate_oscillator(priv); */
+/*	antenna_calibrate(priv); */
+/*	agnx_send_packet(priv, 997); /
 	/* FIXME */
 /* 	if (debug == 3) */
 /*                 delay = msecs_to_jiffies(AGNX_PERIODIC_DELAY); */
 /* 	else */
 	delay = msecs_to_jiffies(AGNX_PERIODIC_DELAY);
-//		delay = round_jiffies(HZ * 15);
+/*	delay = round_jiffies(HZ * 15); */
 
 	queue_delayed_work(priv->hw->workqueue, &priv->periodic_work, delay);
 
-//	spin_unlock_irqrestore(&priv->lock, flags);
+/*	spin_unlock_irqrestore(&priv->lock, flags); */
 }
 #endif
 
@@ -255,12 +254,12 @@
 		goto out;
 	}
 
-//	mdelay(500);
+/*	mdelay(500); */
 
 	might_sleep();
 	agnx_hw_init(priv);
 
-//	mdelay(500);
+/*	mdelay(500); */
 	might_sleep();
 
 	priv->init_status = AGNX_START;
@@ -280,16 +279,16 @@
 	/* make sure hardware will not generate irq */
 	agnx_hw_reset(priv);
 	free_irq(priv->pdev->irq, dev);
-        flush_workqueue(priv->hw->workqueue);
-//	cancel_delayed_work_sync(&priv->periodic_work);
+	flush_workqueue(priv->hw->workqueue);
+/*	cancel_delayed_work_sync(&priv->periodic_work); */
 	unfill_rings(priv);
 	rings_free(priv);
 }
 
-static int agnx_config(struct ieee80211_hw *dev,
-		       struct ieee80211_conf *conf)
+static int agnx_config(struct ieee80211_hw *dev, u32 changed)
 {
 	struct agnx_priv *priv = dev->priv;
+	struct ieee80211_conf *conf = &dev->conf;
 	int channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
 	AGNX_TRACE;
 
@@ -315,7 +314,6 @@
 	spin_lock(&priv->lock);
 
 	if (memcmp(conf->bssid, priv->bssid, ETH_ALEN)) {
-//		u32 reghi, reglo;
 		agnx_set_bssid(priv, conf->bssid);
 		memcpy(priv->bssid, conf->bssid, ETH_ALEN);
 		hash_write(priv, conf->bssid, BSSID_STAID);
@@ -425,7 +423,7 @@
 	.remove_interface	= agnx_remove_interface,
 	.config			= agnx_config,
 	.config_interface	= agnx_config_interface,
- 	.configure_filter	= agnx_configure_filter,
+	.configure_filter	= agnx_configure_filter,
 	.get_stats		= agnx_get_stats,
 	.get_tx_stats		= agnx_get_tx_stats,
 	.get_tsf		= agnx_get_tsft
@@ -434,11 +432,12 @@
 static void __devexit agnx_pci_remove(struct pci_dev *pdev)
 {
 	struct ieee80211_hw *dev = pci_get_drvdata(pdev);
-	struct agnx_priv *priv = dev->priv;
+	struct agnx_priv *priv;
 	AGNX_TRACE;
 
 	if (!dev)
 		return;
+	priv = dev->priv;
 	ieee80211_unregister_hw(dev);
 	pci_iounmap(pdev, priv->ctl);
 	pci_iounmap(pdev, priv->data);
@@ -504,7 +503,7 @@
 
 	/* Map mem #1 and #2 */
 	priv->ctl = pci_iomap(pdev, 0, mem_len0);
-//	printk(KERN_DEBUG PFX"MEM1 mapped address is 0x%p\n", priv->ctl);
+/*	printk(KERN_DEBUG PFX"MEM1 mapped address is 0x%p\n", priv->ctl); */
 	if (!priv->ctl) {
 		printk(KERN_ERR PFX "Can't map device memory\n");
 		goto err_free_dev;
diff --git a/drivers/staging/agnx/phy.c b/drivers/staging/agnx/phy.c
index da8f10c..2be6331 100644
--- a/drivers/staging/agnx/phy.c
+++ b/drivers/staging/agnx/phy.c
@@ -114,7 +114,7 @@
 	/* FIXME */
 	reg = (mac_addr[0] << 24) | (mac_addr[1] << 16) | mac_addr[2] << 8 | mac_addr[3];
 	iowrite32(reg, ctl + AGNX_RXM_MACHI);
- 	reg = (mac_addr[4] << 8) | mac_addr[5];
+	reg = (mac_addr[4] << 8) | mac_addr[5];
 	iowrite32(reg, ctl + AGNX_RXM_MACLO);
 }
 
@@ -127,7 +127,7 @@
 	/* FIXME */
 	reg = bssid[0] << 24 | (bssid[1] << 16) | (bssid[2] << 8) | bssid[3];
 	iowrite32(reg, ctl + AGNX_RXM_BSSIDHI);
- 	reg = (bssid[4] << 8) | bssid[5];
+	reg = (bssid[4] << 8) | bssid[5];
 	iowrite32(reg, ctl + AGNX_RXM_BSSIDLO);
 
 	/* Enable the receiver */
@@ -401,9 +401,9 @@
 		agnx_write32(ctl, 0x2074, 0x1f171710);
 		agnx_write32(ctl, 0x2078, 0x10100d0d);
 		agnx_write32(ctl, 0x207c, 0x11111010);
-	}
-	else
+	} else {
 		agnx_write32(ctl, AGNX_RXM_DELAY11, 0x0);
+	}
 	agnx_write32(ctl, AGNX_RXM_REQRATE, 0x8195e00);
 }
 
@@ -476,7 +476,7 @@
 	/* It seemed if we set other bit to 1 the bit 0 will
 	   be auto change to 0 */
 	agnx_write32(ctl, AGNX_BM_TXTOPEER, 0x2 | 0x1);
-//	agnx_write32(ctl, AGNX_BM_TXTOPEER, 0x1);
+/*	agnx_write32(ctl, AGNX_BM_TXTOPEER, 0x1); */
 } /* gain_ctlcnt_init */
 
 
@@ -490,7 +490,7 @@
 	/* Load InitialGainTable */
 	gain_table_init(priv);
 
-  	agnx_write32(ctl, AGNX_CIR_ADDRWIN, 0x2000000);
+	agnx_write32(ctl, AGNX_CIR_ADDRWIN, 0x2000000);
 
 	/* Clear the following offsets in Memory Range #2: */
 	memset_io(data + 0x5040, 0, 0xa * 4);
@@ -586,7 +586,7 @@
 		agnx_write32(ctl, AGNX_GCR_SIFST11B, 0x28);
 		agnx_write32(ctl, AGNX_GCR_CWDETEC, 0x0);
 		agnx_write32(ctl, AGNX_GCR_0X38, 0x1e);
-//		agnx_write32(ctl, AGNX_GCR_BOACT, 0x26);
+/*		agnx_write32(ctl, AGNX_GCR_BOACT, 0x26);*/
 		agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x3);
 
 		agnx_write32(ctl, AGNX_GCR_THCAP11A, 0x32);
@@ -810,10 +810,10 @@
 		}
 		print_hex_dump_bytes(PFX "EEPROM: ", DUMP_PREFIX_NONE, eeprom,
 				     ARRAY_SIZE(eeprom));
-	} while(0);
+	} while (0);
 
 	spi_rc_write(ctl, RF_CHIP0, 0x26);
-        reg = agnx_read32(ctl, AGNX_SPI_RLSW);
+	reg = agnx_read32(ctl, AGNX_SPI_RLSW);
 
 	/* Initialize the system interface */
 	system_itf_init(priv);
@@ -874,19 +874,19 @@
 	/* FIXME Enable the request */
 	/* Check packet length */
 	/* Set maximum packet length */
-/* 	agnx_write32(ctl, AGNX_RXM_REQRATE, 0x88195e00); */
-/* 	enable_receiver(priv); */
+/*	agnx_write32(ctl, AGNX_RXM_REQRATE, 0x88195e00); */
+/*	enable_receiver(priv); */
 
 	/* Set the Receiver BSSID */
 	receiver_bssid_set(priv, bssid);
 
 	/* FIXME Set to managed mode */
 	set_managed_mode(priv);
-//	set_promiscuous_mode(priv);
-/* 	set_scan_mode(priv); */
-/* 	set_learn_mode(priv); */
-// 	set_promis_and_managed(priv);
-// 	set_adhoc_mode(priv);
+/*	set_promiscuous_mode(priv); */
+/*	set_scan_mode(priv); */
+/*	set_learn_mode(priv); */
+/*	set_promis_and_managed(priv); */
+/*	set_adhoc_mode(priv); */
 
 	/* Set the recieve request rate */
 	/* Check packet length */
diff --git a/drivers/staging/agnx/rf.c b/drivers/staging/agnx/rf.c
index 8294b6e..42e457a 100644
--- a/drivers/staging/agnx/rf.c
+++ b/drivers/staging/agnx/rf.c
@@ -109,12 +109,12 @@
 	}
 
 	/* Set SPI clock speed to 200NS */
-        reg = agnx_read32(ctl, AGNX_SPI_CFG);
-        reg &= ~0xF;
-        reg |= 0x3;
-        agnx_write32(ctl, AGNX_SPI_CFG, reg);
+	reg = agnx_read32(ctl, AGNX_SPI_CFG);
+	reg &= ~0xF;
+	reg |= 0x3;
+	agnx_write32(ctl, AGNX_SPI_CFG, reg);
 
-        /* Set SPI clock speed to 50NS */
+	/* Set SPI clock speed to 50NS */
 	reg = agnx_read32(ctl, AGNX_SPI_CFG);
 	reg &= ~0xF;
 	reg |= 0x1;
@@ -256,7 +256,7 @@
 		agnx_write32(ctl, AGNX_GCR_THD0BTFEST, 70);
 		agnx_write32(ctl, AGNX_GCR_SIGHTH, 100);
 		agnx_write32(ctl, AGNX_GCR_SIGLTH, 48);
-//		agnx_write32(ctl, AGNX_GCR_SIGLTH, 16);
+/*		agnx_write32(ctl, AGNX_GCR_SIGLTH, 16); */
 		break;
 	default:
 		printk(KERN_WARNING PFX "Unknow antenna number\n");
@@ -275,8 +275,8 @@
 	if (reg == 0x4)
 		spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, reg|0x1000);
 	else if (reg != 0x0)
-     		spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, reg|0x1000);
-        else {
+		spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, reg|0x1000);
+	else {
 		if (chain == 3 || chain == 6) {
 			spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, reg|0x1000);
 			agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x0);
@@ -634,8 +634,7 @@
 	}
 } /* chain_calibrate */
 
-
-static void inline get_calibrete_value(struct agnx_priv *priv, struct chains *chains,
+static inline void get_calibrete_value(struct agnx_priv *priv, struct chains *chains,
 				       unsigned int num)
 {
 	void __iomem *ctl = priv->ctl;
@@ -652,7 +651,7 @@
 	}
 
 	if (num == 0 || num == 1 || num == 2) {
-		if ( 0 == chains[num].cali)
+		if (0 == chains[num].cali)
 			chains[num].cali = 0xff;
 		else
 			chains[num].cali--;
@@ -669,7 +668,7 @@
 	unsigned int i = 100;
 
 	wmb();
-	while (i--) {
+	while (--i) {
 		reg = (ioread32(ctl + AGNX_ACI_STATUS));
 		if (reg == 0x4000)
 			break;
diff --git a/drivers/staging/agnx/sta.c b/drivers/staging/agnx/sta.c
index d3ac675..5b2d54a 100644
--- a/drivers/staging/agnx/sta.c
+++ b/drivers/staging/agnx/sta.c
@@ -18,7 +18,7 @@
 	iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
 
 	reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_HIGH);
-        reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
+	reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
 	printk(PFX "RX hash cmd are : %.8x%.8x\n", reghi, reglo);
 }
 
@@ -40,7 +40,7 @@
 	iowrite32(reghi, ctl + AGNX_RXM_HASH_CMD_HIGH);
 	iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
 
-        reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
+	reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
 	if (!(reglo & 0x80000000))
 		printk(KERN_WARNING PFX "Update hash table failed\n");
 }
@@ -59,7 +59,7 @@
 	iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
 	reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_HIGH);
 
-        reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
+	reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
 	printk(PFX "RX hash cmd are : %.8x%.8x\n", reghi, reglo);
 
 }
@@ -69,15 +69,14 @@
 	void __iomem *ctl = priv->ctl;
 	u32 reghi, reglo;
 
-	reglo = 0x0;		/* dump command */
-	reglo|= 0x40000000;  	/* status bit */
+	reglo = 0x40000000;  	/* status bit */
 	iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
 	iowrite32(sta_id << 16, ctl + AGNX_RXM_HASH_DUMP_DATA);
 
 	udelay(80);
 
 	reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_HIGH);
-        reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
+	reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
 	printk(PFX "hash cmd are : %.8x%.8x\n", reghi, reglo);
 	reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_FLAG);
 	printk(PFX "hash flag is : %.8x\n", reghi);
@@ -91,7 +90,7 @@
 void get_sta_power(struct agnx_priv *priv, struct agnx_sta_power *power, unsigned int sta_idx)
 {
 	void __iomem *ctl = priv->ctl;
-        memcpy_fromio(power, ctl + AGNX_TXM_STAPOWTEMP + sizeof(*power) * sta_idx,
+	memcpy_fromio(power, ctl + AGNX_TXM_STAPOWTEMP + sizeof(*power) * sta_idx,
 		      sizeof(*power));
 }
 
@@ -100,7 +99,7 @@
 {
 	void __iomem *ctl = priv->ctl;
 	/* FIXME   2. Write Template to offset + station number  */
-        memcpy_toio(ctl + AGNX_TXM_STAPOWTEMP + sizeof(*power) * sta_idx,
+	memcpy_toio(ctl + AGNX_TXM_STAPOWTEMP + sizeof(*power) * sta_idx,
 		    power, sizeof(*power));
 }
 
@@ -135,7 +134,7 @@
 {
 	void __iomem *data = priv->data;
 
-        memcpy_toio(data + AGNX_PDUPOOL + sizeof(*sta) * sta_idx,
+	memcpy_toio(data + AGNX_PDUPOOL + sizeof(*sta) * sta_idx,
 		    sta, sizeof(*sta));
 }
 
@@ -165,7 +164,7 @@
 
 	reg = agnx_set_bits(WORK_QUEUE_VALID, WORK_QUEUE_VALID_SHIFT, 1);
 	reg |= agnx_set_bits(WORK_QUEUE_ACK_TYPE, WORK_QUEUE_ACK_TYPE_SHIFT, 1);
-//	reg |= agnx_set_bits(WORK_QUEUE_ACK_TYPE, WORK_QUEUE_ACK_TYPE_SHIFT, 0);
+/*	reg |= agnx_set_bits(WORK_QUEUE_ACK_TYPE, WORK_QUEUE_ACK_TYPE_SHIFT, 0); */
 	tx_wq.reg2 |= cpu_to_le32(reg);
 
 	/* Suppose all 8 traffic class are used */
@@ -181,7 +180,7 @@
 
 	reg = agnx_set_bits(NEW_PACKET, NEW_PACKET_SHIFT, 1);
 	reg |= agnx_set_bits(TRAFFIC_VALID, TRAFFIC_VALID_SHIFT, 1);
-//	reg |= agnx_set_bits(TRAFFIC_ACK_TYPE, TRAFFIC_ACK_TYPE_SHIFT, 1);
+/*	reg |= agnx_set_bits(TRAFFIC_ACK_TYPE, TRAFFIC_ACK_TYPE_SHIFT, 1); */
 	traffic->reg0 = cpu_to_le32(reg);
 
 	/* 	3. setting RX Sequence Number to 4095 */
diff --git a/drivers/staging/agnx/sta.h b/drivers/staging/agnx/sta.h
index 58d0b12..94e2cf1 100644
--- a/drivers/staging/agnx/sta.h
+++ b/drivers/staging/agnx/sta.h
@@ -16,7 +16,7 @@
 #define PASS		0x00000001
 #define PASS_SHIFT	1
 	__be32 cmdlo;
-}__attribute__((__packed__));
+} __attribute__((__packed__));
 
 
 /*
diff --git a/drivers/staging/agnx/table.c b/drivers/staging/agnx/table.c
index c600484..b52fef9 100644
--- a/drivers/staging/agnx/table.c
+++ b/drivers/staging/agnx/table.c
@@ -80,7 +80,7 @@
 
 	disable_receiver(priv);
 
-	for ( type = 0; type < 0x3; type++ ) {
+	for (type = 0; type < 0x3; type++) {
 		for (subtype = 0; subtype < 0x10; subtype++) {
 			/* 1. Set Routing table to R/W and to Return status on Read */
 			reg = (type << ROUTAB_TYPE_SHIFT) |
@@ -89,7 +89,7 @@
 			if (type == ROUTAB_TYPE_DATA) {
 				/* NULL goes to RFP */
 				if (subtype == ROUTAB_SUBTYPE_NULL)
-//					reg |= ROUTAB_ROUTE_RFP;
+/*					reg |= ROUTAB_ROUTE_RFP; */
 					reg |= ROUTAB_ROUTE_CPU;
 				/* QOS NULL goes to CPU */
 				else if (subtype == ROUTAB_SUBTYPE_QOSNULL)
@@ -104,7 +104,7 @@
 					 (subtype == ROUTAB_SUBTYPE_QOSDATAPOLL) ||
 					 (subtype == ROUTAB_SUBTYPE_QOSDATAACKPOLL))
 					reg |= ROUTAB_ROUTE_ENCRY;
-//					reg |= ROUTAB_ROUTE_CPU;
+/*					reg |= ROUTAB_ROUTE_CPU; */
 				/*Drop NULL and QOS NULL ack, poll and poll ack*/
 				else if ((subtype == ROUTAB_SUBTYPE_NULLACK) ||
 					 (subtype == ROUTAB_SUBTYPE_QOSNULLACK) ||
@@ -112,11 +112,11 @@
 					 (subtype == ROUTAB_SUBTYPE_QOSNULLPOLL) ||
 					 (subtype == ROUTAB_SUBTYPE_NULLPOLLACK) ||
 					 (subtype == ROUTAB_SUBTYPE_QOSNULLPOLLACK))
-//					reg |= ROUTAB_ROUTE_DROP;
+/*					reg |= ROUTAB_ROUTE_DROP; */
 					reg |= ROUTAB_ROUTE_CPU;
-			}
-			else
+			} else {
 				reg |= (ROUTAB_ROUTE_CPU);
+			}
 			iowrite32(reg, ctl + AGNX_RXM_ROUTAB);
 			/* Check to verify that the status bit cleared */
 			routing_table_delay();
diff --git a/drivers/staging/agnx/xmit.c b/drivers/staging/agnx/xmit.c
index 7f01528..0e03408 100644
--- a/drivers/staging/agnx/xmit.c
+++ b/drivers/staging/agnx/xmit.c
@@ -17,8 +17,8 @@
 #include "debug.h"
 #include "phy.h"
 
-unsigned int rx_frame_cnt = 0;
-//unsigned int local_tx_sent_cnt = 0;
+unsigned int rx_frame_cnt;
+/* unsigned int local_tx_sent_cnt = 0; */
 
 static inline void disable_rx_engine(struct agnx_priv *priv)
 {
@@ -242,15 +242,15 @@
 	memset(stat, 0, sizeof(*stat));
 	/* RSSI */
 	rssi = (u8 *)&hdr->phy_stats_lo;
-//	stat->ssi = (rssi[0] + rssi[1] + rssi[2]) / 3;
+/*	stat->ssi = (rssi[0] + rssi[1] + rssi[2]) / 3; */
 	/* Noise */
 	noise = ioread32(ctl + AGNX_GCR_NOISE0);
 	noise += ioread32(ctl + AGNX_GCR_NOISE1);
 	noise += ioread32(ctl + AGNX_GCR_NOISE2);
 	stat->noise = noise / 3;
 	/* Signal quality */
-	//snr = stat->ssi - stat->noise;
-	if (snr >=0 && snr < 40)
+/*	snr = stat->ssi - stat->noise; */
+	if (snr >= 0 && snr < 40)
 		stat->signal = 5 * snr / 2;
 	else if (snr >= 40)
 		stat->signal = 100;
@@ -269,10 +269,9 @@
 
 	stat->band = IEEE80211_BAND_2GHZ;
 	stat->freq = agnx_channels[priv->channel - 1].center_freq;
-//	stat->antenna = 3;
-//	stat->mactime = be32_to_cpu(hdr->time_stamp);
-//	stat->channel = priv->channel;
-
+/*	stat->antenna = 3;
+	stat->mactime = be32_to_cpu(hdr->time_stamp);
+	stat->channel = priv->channel; */
 }
 
 static inline void combine_hdr_frag(struct ieee80211_hdr *ieeehdr,
@@ -296,7 +295,7 @@
 static inline int agnx_packet_check(struct agnx_priv *priv, struct agnx_hdr *agnxhdr,
 				    unsigned packet_len)
 {
-	if (agnx_get_bits(CRC_FAIL, CRC_FAIL_SHIFT, be32_to_cpu(agnxhdr->reg1)) == 1){
+	if (agnx_get_bits(CRC_FAIL, CRC_FAIL_SHIFT, be32_to_cpu(agnxhdr->reg1)) == 1) {
 		printk(PFX "RX: CRC check fail\n");
 		goto drop;
 	}
@@ -320,7 +319,7 @@
 {
 	struct ieee80211_rx_status status;
 	unsigned int len;
-//	AGNX_TRACE;
+/*	AGNX_TRACE; */
 
 	do {
 		struct agnx_desc *desc;
@@ -341,54 +340,54 @@
 
 		len = (frag & PACKET_LEN) >> PACKET_LEN_SHIFT;
 		if (agnx_packet_check(priv, hdr, len) == -1) {
- 			rx_desc_reusing(priv, i);
+			rx_desc_reusing(priv, i);
 			continue;
 		}
 		skb_put(skb, len);
 
 		do {
-			u16 fctl;
+				u16 fctl;
 			fctl = le16_to_cpu(((struct ieee80211_hdr *)hdr->mac_hdr)->frame_control);
-			if ((fctl & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_BEACON)// && !(fctl & IEEE80211_STYPE_BEACON))
+			if ((fctl & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_BEACON)/* && !(fctl & IEEE80211_STYPE_BEACON)) */
 				dump_ieee80211_hdr((struct ieee80211_hdr *)hdr->mac_hdr, "RX");
 		} while (0);
 
 		if (hdr->_11b0 && !hdr->_11g0) {
-/* 			int j; */
-/* 			u16 fctl = le16_to_cpu(((struct ieee80211_hdr *)hdr->mac_hdr) */
-/* 					       ->frame_control); */
-/* 			if ( (fctl & IEEE80211_FCTL_FTYPE) ==  IEEE80211_FTYPE_DATA) { */
-/* 				agnx_print_rx_hdr(hdr); */
-// 				agnx_print_sta(priv, BSSID_STAID);
-/* 				for (j = 0; j < 8; j++) */
-/* 					agnx_print_sta_tx_wq(priv, BSSID_STAID, j);		 */
-/* 			} */
+/*			int j;
+			u16 fctl = le16_to_cpu(((struct ieee80211_hdr *)hdr->mac_hdr)
+					       ->frame_control);
+			if ( (fctl & IEEE80211_FCTL_FTYPE) ==  IEEE80211_FTYPE_DATA) {
+				agnx_print_rx_hdr(hdr);
+				agnx_print_sta(priv, BSSID_STAID);
+				for (j = 0; j < 8; j++)
+					agnx_print_sta_tx_wq(priv, BSSID_STAID, j);
+			} */
 
 			get_rx_stats(priv, hdr, &status);
 			skb_pull(skb, sizeof(*hdr));
 			combine_hdr_frag((struct ieee80211_hdr *)hdr->mac_hdr, skb);
 		} else if (!hdr->_11b0 && hdr->_11g0) {
-//			int j;
+/*			int j; */
 			agnx_print_rx_hdr(hdr);
 			agnx_print_sta(priv, BSSID_STAID);
-//			for (j = 0; j < 8; j++)
+/*			for (j = 0; j < 8; j++) */
 			agnx_print_sta_tx_wq(priv, BSSID_STAID, 0);
 
 			print_hex_dump_bytes("agnx: RX_PACKET: ", DUMP_PREFIX_NONE,
 					     skb->data, skb->len + 8);
 
-//			if (agnx_plcp_get_bitrate_ofdm(&hdr->_11g0) == 0)
+/*			if (agnx_plcp_get_bitrate_ofdm(&hdr->_11g0) == 0) */
 			get_rx_stats(priv, hdr, &status);
 			skb_pull(skb, sizeof(*hdr));
 			combine_hdr_frag((struct ieee80211_hdr *)
 					 ((void *)&hdr->mac_hdr), skb);
-//			dump_ieee80211_hdr((struct ieee80211_hdr *)skb->data, "RX G");
+/*			dump_ieee80211_hdr((struct ieee80211_hdr *)skb->data, "RX G"); */
 		} else
 			agnx_bug("Unknown packets type");
 		ieee80211_rx_irqsafe(priv->hw, skb, &status);
 		rx_desc_reinit(priv, i);
 
-	} while ( priv->rx.idx++ );
+	} while (priv->rx.idx++);
 } /* handle_rx_irq */
 
 static inline void handle_tx_irq(struct agnx_priv *priv, struct agnx_ring *ring)
@@ -415,40 +414,40 @@
 		pci_unmap_single(priv->pdev, info->mapping, info->dma_len, PCI_DMA_TODEVICE);
 
 		do {
-//			int j;
+/*			int j; */
 			size_t len;
 			len = info->skb->len - sizeof(struct agnx_hdr) + info->hdr_len;
-			//	if (len == 614) {
-//				agnx_print_desc(desc);
+/*			if (len == 614) { */
+/*				agnx_print_desc(desc); */
 				if (info->type == PACKET) {
-//					agnx_print_tx_hdr((struct agnx_hdr *)info->skb->data);
-/* 					agnx_print_sta_power(priv, LOCAL_STAID); */
-/* 					agnx_print_sta(priv, LOCAL_STAID); */
-/* //					for (j = 0; j < 8; j++) */
-/* 					agnx_print_sta_tx_wq(priv, LOCAL_STAID, 0); */
-//					agnx_print_sta_power(priv, BSSID_STAID);
-//					agnx_print_sta(priv, BSSID_STAID);
-//					for (j = 0; j < 8; j++)
-//					agnx_print_sta_tx_wq(priv, BSSID_STAID, 0);
+/*					agnx_print_tx_hdr((struct agnx_hdr *)info->skb->data); */
+/*					agnx_print_sta_power(priv, LOCAL_STAID); */
+/*					agnx_print_sta(priv, LOCAL_STAID); */
+/*					for (j = 0; j < 8; j++) */
+/*					agnx_print_sta_tx_wq(priv, LOCAL_STAID, 0); */
+/*					agnx_print_sta_power(priv, BSSID_STAID); */
+/*					agnx_print_sta(priv, BSSID_STAID); */
+/*					for (j = 0; j < 8; j++) */
+/*					agnx_print_sta_tx_wq(priv, BSSID_STAID, 0); */
 				}
-//			}
+/*			} */
 		} while (0);
 
 		if (info->type == PACKET) {
-//			dump_txm_registers(priv);
-//			dump_rxm_registers(priv);
-//			dump_bm_registers(priv);
-//			dump_cir_registers(priv);
+/*			dump_txm_registers(priv);
+			dump_rxm_registers(priv);
+			dump_bm_registers(priv);
+			dump_cir_registers(priv); */
 		}
 
 		if (info->type == PACKET) {
-//			struct ieee80211_hdr *hdr;
+/*			struct ieee80211_hdr *hdr; */
 			struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(info->skb);
 
 			skb_pull(info->skb, sizeof(struct agnx_hdr));
 			memcpy(skb_push(info->skb, info->hdr_len), &info->hdr, info->hdr_len);
 
-//			dump_ieee80211_hdr((struct ieee80211_hdr *)info->skb->data, "TX_HANDLE");
+/*			dump_ieee80211_hdr((struct ieee80211_hdr *)info->skb->data, "TX_HANDLE"); */
 /* 			print_hex_dump_bytes("agnx: TX_HANDLE: ", DUMP_PREFIX_NONE, */
 /* 					     info->skb->data, info->skb->len); */
 
@@ -462,7 +461,7 @@
 /* 				ieee80211_tx_status_irqsafe(priv->hw, info->skb, &(info->tx_status)); */
 /* 			} else */
 /* 				dev_kfree_skb_irq(info->skb); */
- 		}
+		}
 		memset(desc, 0, sizeof(*desc));
 		memset(info, 0, sizeof(*info));
 	}
@@ -485,7 +484,7 @@
 
 void handle_other_irq(struct agnx_priv *priv)
 {
-//	void __iomem *ctl = priv->ctl;
+/*	void __iomem *ctl = priv->ctl; */
 	u32 status = priv->irq_status;
 	void __iomem *ctl = priv->ctl;
 	u32 reg;
@@ -526,11 +525,11 @@
 		iowrite32(reg, ctl + AGNX_INT_MASK);
 		iowrite32(IRQ_RX_FRAME, ctl + AGNX_INT_STAT);
 		printk(PFX "IRQ: RX Frame\n");
- 		rx_frame_cnt++;
+		rx_frame_cnt++;
 	}
 	if (status & IRQ_ERR_INT) {
 		iowrite32(IRQ_ERR_INT, ctl + AGNX_INT_STAT);
-//		agnx_hw_reset(priv);
+/*		agnx_hw_reset(priv); */
 		printk(PFX "IRQ: Error Interrupt\n");
 	}
 	if (status & IRQ_TX_QUE_FULL)
@@ -558,14 +557,14 @@
 
 static inline void route_flag_set(struct agnx_hdr *txhdr)
 {
-//	u32 reg = 0;
+/*	u32 reg = 0; */
 
 	/* FIXME */
-/*  	reg = (0x7 << ROUTE_COMPRESSION_SHIFT) & ROUTE_COMPRESSION; */
-/* 	txhdr->reg5 = cpu_to_be32(reg); */
- 	txhdr->reg5 = (0xa << 0x0) | (0x7 << 0x18);
-// 	txhdr->reg5 = cpu_to_be32((0xa << 0x0) | (0x7 << 0x18));
-// 	txhdr->reg5 = cpu_to_be32(0x7 << 0x0);
+/*	reg = (0x7 << ROUTE_COMPRESSION_SHIFT) & ROUTE_COMPRESSION; */
+/*	txhdr->reg5 = cpu_to_be32(reg); */
+	txhdr->reg5 = (0xa << 0x0) | (0x7 << 0x18);
+/*	txhdr->reg5 = cpu_to_be32((0xa << 0x0) | (0x7 << 0x18)); */
+/*	txhdr->reg5 = cpu_to_be32(0x7 << 0x0); */
 }
 
 /* Return 0 if no match */
@@ -579,12 +578,29 @@
 	case 55:
 	case 60:
 	case 90:
-	case 120: power_level = 22; break;
-	case 180: power_level = 19; break;
-	case 240: power_level = 18; break;
-	case 360: power_level = 16; break;
-	case 480: power_level = 15; break;
-	case 540: power_level = 14; break;
+	case 120:
+		power_level = 22;
+		break;
+
+	case 180:
+		power_level = 19;
+		break;
+
+	case 240:
+		power_level = 18;
+		break;
+
+	case 360:
+		power_level = 16;
+		break;
+
+	case 480:
+		power_level = 15;
+		break;
+
+	case 540:
+		power_level = 14;
+		break;
 	default:
 		agnx_bug("Error rate setting\n");
 	}
@@ -604,30 +620,30 @@
 
 	memset(txhdr, 0, sizeof(*txhdr));
 
-//	reg = agnx_set_bits(STATION_ID, STATION_ID_SHIFT, LOCAL_STAID);
+/*	reg = agnx_set_bits(STATION_ID, STATION_ID_SHIFT, LOCAL_STAID); */
 	reg = agnx_set_bits(STATION_ID, STATION_ID_SHIFT, BSSID_STAID);
 	reg |= agnx_set_bits(WORKQUEUE_ID, WORKQUEUE_ID_SHIFT, 0);
 	txhdr->reg4 = cpu_to_be32(reg);
 
 	/* Set the Hardware Sequence Number to 1? */
 	reg = agnx_set_bits(SEQUENCE_NUMBER, SEQUENCE_NUMBER_SHIFT, 0);
-//	reg = agnx_set_bits(SEQUENCE_NUMBER, SEQUENCE_NUMBER_SHIFT, 1);
+/*	reg = agnx_set_bits(SEQUENCE_NUMBER, SEQUENCE_NUMBER_SHIFT, 1); */
 	reg |= agnx_set_bits(MAC_HDR_LEN, MAC_HDR_LEN_SHIFT, tx_info->hdr_len);
 	txhdr->reg1 = cpu_to_be32(reg);
 	/* Set the agnx_hdr's MAC header */
 	memcpy(txhdr->mac_hdr, &tx_info->hdr, tx_info->hdr_len);
 
 	reg = agnx_set_bits(ACK, ACK_SHIFT, 1);
-//	reg = agnx_set_bits(ACK, ACK_SHIFT, 0);
+/*	reg = agnx_set_bits(ACK, ACK_SHIFT, 0); */
 	reg |= agnx_set_bits(MULTICAST, MULTICAST_SHIFT, 0);
-//	reg |= agnx_set_bits(MULTICAST, MULTICAST_SHIFT, 1);
+/*	reg |= agnx_set_bits(MULTICAST, MULTICAST_SHIFT, 1); */
 	reg |= agnx_set_bits(RELAY, RELAY_SHIFT, 0);
 	reg |= agnx_set_bits(TM, TM_SHIFT, 0);
 	txhdr->reg0 = cpu_to_be32(reg);
 
 	/* Set the long and short retry limits */
- 	txhdr->tx.short_retry_limit = tx_info->txi->control.rates[0].count;
- 	txhdr->tx.long_retry_limit = tx_info->txi->control.rates[0].count;
+	txhdr->tx.short_retry_limit = tx_info->txi->control.rates[0].count;
+	txhdr->tx.long_retry_limit = tx_info->txi->control.rates[0].count;
 
 	/* FIXME */
 	len = tx_info->skb->len - sizeof(*txhdr) + tx_info->hdr_len + FCS_LEN;
@@ -652,23 +668,23 @@
 	if (txi->control.rates[0].idx < 0) {
 		/* For B mode Short Preamble */
 		reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211B_SHORT);
-//		control->tx_rate = -control->tx_rate;
+/*		control->tx_rate = -control->tx_rate; */
 	} else
 		reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211G);
-//		reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211B_LONG);
+/*		reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211B_LONG); */
 	reg |= agnx_set_bits(SIGNAL, SIGNAL_SHIFT, 0xB);
 	reg |= agnx_set_bits(RATE, RATE_SHIFT, 0xB);
-//	reg |= agnx_set_bits(POWER_LEVEL, POWER_LEVEL_SHIFT, 15);
+/*	reg |= agnx_set_bits(POWER_LEVEL, POWER_LEVEL_SHIFT, 15); */
 	reg |= agnx_set_bits(POWER_LEVEL, POWER_LEVEL_SHIFT, 20);
 	/* if rate < 11M set it to 0 */
 	reg |= agnx_set_bits(NUM_TRANSMITTERS, NUM_TRANSMITTERS_SHIFT, 1);
-//	reg |= agnx_set_bits(EDCF, EDCF_SHIFT, 1);
-//	reg |= agnx_set_bits(TIFS, TIFS_SHIFT, 1);
+/*	reg |= agnx_set_bits(EDCF, EDCF_SHIFT, 1); */
+/*	reg |= agnx_set_bits(TIFS, TIFS_SHIFT, 1); */
 
 	power.reg = reg;
-//	power.reg = cpu_to_le32(reg);
+/*	power.reg = cpu_to_le32(reg); */
 
-//	set_sta_power(priv, &power, LOCAL_STAID);
+/*	set_sta_power(priv, &power, LOCAL_STAID); */
 	set_sta_power(priv, &power, BSSID_STAID);
 }
 
@@ -759,24 +775,24 @@
 
 	txm_power_set(priv, txi);
 
-/* 	do { */
-/* 		int j; */
-/* 		size_t len; */
-/* 		len = skb->len - hdr_info->dma_len + hdr_info->hdr_len;  */
-/* //		if (len == 614) { */
-/* 			agnx_print_desc(hdr_desc); */
-/* 			agnx_print_desc(frag_desc); */
-/* 			agnx_print_tx_hdr((struct agnx_hdr *)skb->data); */
-/* 			agnx_print_sta_power(priv, LOCAL_STAID); */
-/* 			agnx_print_sta(priv, LOCAL_STAID); */
-/* 			for (j = 0; j < 8; j++) */
-/* 				agnx_print_sta_tx_wq(priv, LOCAL_STAID, j); */
-/* 			agnx_print_sta_power(priv, BSSID_STAID); */
-/* 			agnx_print_sta(priv, BSSID_STAID); */
-/* 			for (j = 0; j < 8; j++) */
-/* 				agnx_print_sta_tx_wq(priv, BSSID_STAID, j); */
-/* 			//	} */
-/* 	} while (0); */
+/*	do { */
+/*		int j; */
+/*		size_t len; */
+/*		len = skb->len - hdr_info->dma_len + hdr_info->hdr_len;  */
+/*		if (len == 614) { */
+/*			agnx_print_desc(hdr_desc); */
+/*			agnx_print_desc(frag_desc); */
+/*			agnx_print_tx_hdr((struct agnx_hdr *)skb->data); */
+/*			agnx_print_sta_power(priv, LOCAL_STAID); */
+/*			agnx_print_sta(priv, LOCAL_STAID); */
+/*			for (j = 0; j < 8; j++) */
+/*				agnx_print_sta_tx_wq(priv, LOCAL_STAID, j); */
+/*			agnx_print_sta_power(priv, BSSID_STAID); */
+/*			agnx_print_sta(priv, BSSID_STAID); */
+/*			for (j = 0; j < 8; j++) */
+/*				agnx_print_sta_tx_wq(priv, BSSID_STAID, j); */
+/*			} */
+/*	} while (0); */
 
 	spin_unlock_irqrestore(&priv->lock, flags);
 
@@ -787,7 +803,7 @@
 		reg = (ioread32(priv->ctl + AGNX_CIR_TXMCTL));
 		reg |= 0x8;
 		iowrite32((reg), priv->ctl + AGNX_CIR_TXMCTL);
-	}while (0);
+	} while (0);
 
 	/* Trigger TXD */
 	do {
@@ -795,7 +811,7 @@
 		reg = (ioread32(priv->ctl + AGNX_CIR_TXDCTL));
 		reg |= 0x8;
 		iowrite32((reg), priv->ctl + AGNX_CIR_TXDCTL);
-	}while (0);
+	} while (0);
 
 	return 0;
 }
@@ -807,12 +823,12 @@
 	if (tx_packet_check(skb))
 		return 0;
 
-/* 	print_hex_dump_bytes("agnx: TX_PACKET: ", DUMP_PREFIX_NONE, */
-/* 			     skb->data, skb->len); */
+/*	print_hex_dump_bytes("agnx: TX_PACKET: ", DUMP_PREFIX_NONE, */
+/*			     skb->data, skb->len); */
 
-        fctl = le16_to_cpu(*((__le16 *)skb->data));
+	fctl = le16_to_cpu(*((__le16 *)skb->data));
 
-	if ( (fctl & IEEE80211_FCTL_FTYPE)  == IEEE80211_FTYPE_DATA )
+	if ((fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)
 		return __agnx_tx(priv, skb, &priv->txd);
 	else
 		return __agnx_tx(priv, skb, &priv->txm);
diff --git a/drivers/staging/altpciechdma/altpciechdma.c b/drivers/staging/altpciechdma/altpciechdma.c
index f516140..3e41e08 100644
--- a/drivers/staging/altpciechdma/altpciechdma.c
+++ b/drivers/staging/altpciechdma/altpciechdma.c
@@ -46,7 +46,6 @@
 #include <linux/cdev.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
-#include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -313,15 +312,16 @@
 			continue;
 		/* do not map BARs with address 0 */
 		if (!bar_start || !bar_end) {
-            printk(KERN_DEBUG "BAR #%d is not present?!\n", i);
+			printk(KERN_DEBUG "BAR #%d is not present?!\n", i);
 			rc = -1;
 			goto fail;
 		}
 		bar_length = bar_end - bar_start + 1;
 		/* BAR length is less than driver requires? */
 		if (bar_length < bar_min_len[i]) {
-            printk(KERN_DEBUG "BAR #%d length = %lu bytes but driver "
-            "requires at least %lu bytes\n", i, bar_length, bar_min_len[i]);
+			printk(KERN_DEBUG "BAR #%d length = %lu bytes but driver "
+			"requires at least %lu bytes\n",
+			i, bar_length, bar_min_len[i]);
 			rc = -1;
 			goto fail;
 		}
@@ -333,8 +333,8 @@
 			rc = -1;
 			goto fail;
 		}
-        printk(KERN_DEBUG "BAR[%d] mapped at 0x%p with length %lu(/%lu).\n", i,
-			ape->bar[i], bar_min_len[i], bar_length);
+		printk(KERN_DEBUG "BAR[%d] mapped at 0x%p with length %lu(/%lu).\n", i,
+		ape->bar[i], bar_min_len[i], bar_length);
 	}
 	/* succesfully mapped all required BAR regions */
 	rc = 0;
@@ -427,11 +427,13 @@
 		dma_addr_t next = sg_dma_address(&sgl[i + 1]);
 		/* length of this entry i */
 		len = sg_dma_len(&sgl[i]);
-		printk(KERN_DEBUG "%04d: addr=0x%08x length=0x%08x\n", i, addr, len);
+		printk(KERN_DEBUG "%04d: addr=0x%Lx length=0x%08x\n", i,
+			(unsigned long long)addr, len);
 		/* entry i + 1 is non-contiguous with entry i? */
 		if (next != addr + len) {
 			/* TODO create entry here (we could overwrite i) */
-			printk(KERN_DEBUG "%4d: cont_addr=0x%08x cont_len=0x%08x\n", j, cont_addr, cont_len);
+			printk(KERN_DEBUG "%4d: cont_addr=0x%Lx cont_len=0x%08x\n", j,
+				(unsigned long long)cont_addr, cont_len);
 			/* set descriptor for contiguous transfer */
 			ape_chdma_desc_set(&desc[j], cont_addr, ep_addr, cont_len);
 			/* next end point memory address */
@@ -447,8 +449,10 @@
 		addr = next;
 	}
 	/* TODO create entry here  (we could overwrite i) */
-	printk(KERN_DEBUG "%04d: addr=0x%08x length=0x%08x\n", i, addr, len);
-	printk(KERN_DEBUG "%4d: cont_addr=0x%08x length=0x%08x\n", j, cont_addr, cont_len);
+	printk(KERN_DEBUG "%04d: addr=0x%Lx length=0x%08x\n", i,
+		(unsigned long long)addr, len);
+	printk(KERN_DEBUG "%4d: cont_addr=0x%Lx length=0x%08x\n", j,
+		(unsigned long long)cont_addr, cont_len);
 	j++;
 	return j;
 }
@@ -467,15 +471,14 @@
 		} else {
 			fail++;
 			/* show the first few miscompares */
-			if (fail < 10) {
-                printk(KERN_DEBUG "[%p] = 0x%08x != [%p] = 0x%08x ?!\n", p, *p, q, *q);
-            /* but stop after a while */
-            } else if (fail == 10) {
-                printk(KERN_DEBUG "---more errors follow! not printed---\n");
-		  	} else {
+			if (fail < 10)
+				printk(KERN_DEBUG "[%p] = 0x%08x != [%p] = 0x%08x ?!\n", p, *p, q, *q);
+				/* but stop after a while */
+			else if (fail == 10)
+				printk(KERN_DEBUG "---more errors follow! not printed---\n");
+			else
 				/* stop compare after this many errors */
-                break;
-            }
+			break;
 		}
 		p++;
 		q++;
@@ -528,7 +531,7 @@
 	printk(KERN_DEBUG "ape->table_virt = 0x%p.\n", ape->table_virt);
 
 	if (!write_header || !read_header || !ape->table_virt)
-        goto fail;
+		goto fail;
 
 	/* allocate and map coherently-cached memory for a DMA-able buffer */
 	/* @see Documentation/PCI/PCI-DMA-mapping.txt, near line 318 */
@@ -565,9 +568,8 @@
 	/* read 8192 bytes from RC buffer to EP address 4096 */
 	ape_chdma_desc_set(&ape->table_virt->desc[n], buffer_bus, 4096, 2 * PAGE_SIZE);
 #if 1
-	for (i = 0; i < 255; i++) {
+	for (i = 0; i < 255; i++)
 		ape_chdma_desc_set(&ape->table_virt->desc[i], buffer_bus, 4096, 2 * PAGE_SIZE);
-	}
 	/* index of last descriptor */
 	n = i - 1;
 #endif
@@ -647,7 +649,7 @@
 		printk(KERN_DEBUG "EPLAST = %u, n = %d\n", eplast, n);
 		if (eplast == n) {
 			printk(KERN_DEBUG "DONE\n");
-            /* print IRQ count before the transfer */
+			/* print IRQ count before the transfer */
 			printk(KERN_DEBUG "#IRQs during transfer: %d\n", ape->irq_count - irq_count);
 			break;
 		}
@@ -661,9 +663,9 @@
 	n = 0;
 	ape_chdma_desc_set(&ape->table_virt->desc[n], buffer_bus + 8192, 4096, 2 * PAGE_SIZE);
 #if 1
-	for (i = 0; i < 255; i++) {
+	for (i = 0; i < 255; i++)
 		ape_chdma_desc_set(&ape->table_virt->desc[i], buffer_bus + 8192, 4096, 2 * PAGE_SIZE);
-	}
+
 	/* index of last descriptor */
 	n = i - 1;
 #endif
@@ -691,7 +693,7 @@
 	w = (u32)(n + 1);
 	/* enable updates of eplast for each descriptor completion */
 	w |= (u32)(1UL << 18)/*global EPLAST_EN*/;
-#if 0 // test variable, make a module option later
+#if 0   /* test variable, make a module option later */
 	/* enable MSI for each descriptor completion */
 	if (ape->msi_enabled)
 		w |= (1UL << 17)/*global MSI*/;
@@ -715,7 +717,7 @@
 	/** memory write barrier */
 	wmb();
 	/** dummy read to flush posted writes */
-	//(void)ioread32();
+	/* (void) ioread32(); */
 
 	printk(KERN_DEBUG "POLL FOR WRITE:\n");
 	/* poll for completion, 1000 times 1 millisecond */
@@ -844,7 +846,7 @@
 	}
 	ape->got_regions = 1;
 
-#if 1 // @todo For now, disable 64-bit, because I do not understand the implications (DAC!)
+#if 1   /* @todo For now, disable 64-bit, because I do not understand the implications (DAC!) */
 	/* query for DMA transfer */
 	/* @see Documentation/PCI/PCI-DMA-mapping.txt */
 	if (!pci_set_dma_mask(dev, DMA_64BIT_MASK)) {
@@ -947,7 +949,8 @@
 	struct ape_dev *ape;
 	printk(KERN_DEBUG "remove(0x%p)\n", dev);
 	if ((dev == 0) || (dev->dev.driver_data == 0)) {
-		printk(KERN_DEBUG "remove(dev = 0x%p) dev->dev.driver_data = 0x%p\n", dev, dev->dev.driver_data);
+		printk(KERN_DEBUG "remove(dev = 0x%p) dev->dev.driver_data = 0x%p\n",
+			dev, (dev? dev->dev.driver_data: NULL));
 		return;
 	}
 	ape = (struct ape_dev *)dev->dev.driver_data;
@@ -1048,10 +1051,9 @@
 	printk(KERN_DEBUG DRV_NAME "_write(buf=0x%p, count=%lld, pos=%llu)\n",
 		buf, (s64)count, (u64)*pos);
 	/* TODO transfer boundaries at PAGE_SIZE granularity */
-	while (remaining > 0)
-	{
+	while (remaining > 0) {
 		/* limit DMA transfer size */
-		transfer_len = (remaining < APE_CHDMA_MAX_TRANSFER_LEN)? remaining:
+		transfer_len = (remaining < APE_CHDMA_MAX_TRANSFER_LEN) ? remaining :
 			APE_CHDMA_MAX_TRANSFER_LEN;
 		/* get all user space buffer pages and create a scattergather list */
 		sgm_map_user_pages(ape->sgm, transfer_addr, transfer_len, 0/*read from userspace*/);
@@ -1085,12 +1087,12 @@
 /*
  * character device file operations
  */
-static struct file_operations sg_fops = {
-  .owner = THIS_MODULE,
-  .open = sg_open,
-  .release = sg_close,
-  .read = sg_read,
-  .write = sg_write,
+static const struct file_operations sg_fops = {
+	.owner = THIS_MODULE,
+	.open = sg_open,
+	.release = sg_close,
+	.read = sg_read,
+	.write = sg_write,
 };
 
 /* sg_init() - Initialize character device
@@ -1158,12 +1160,12 @@
  */
 static int __init alterapciechdma_init(void)
 {
-  int rc = 0;
+	int rc = 0;
 	printk(KERN_DEBUG DRV_NAME " init(), built at " __DATE__ " " __TIME__ "\n");
 	/* register this driver with the PCI bus driver */
 	rc = pci_register_driver(&pci_driver);
 	if (rc < 0)
-	  return rc;
+		return rc;
 	return 0;
 }
 
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index 758131c..79e90fe 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -2649,14 +2649,22 @@
 {
 	struct binder_proc *proc = vma->vm_private_data;
 	if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE)
-		printk(KERN_INFO "binder: %d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, pgprot_val(vma->vm_page_prot));
+		printk(KERN_INFO
+			"binder: %d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n",
+			proc->pid, vma->vm_start, vma->vm_end,
+			(vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
+			(unsigned long)pgprot_val(vma->vm_page_prot));
 	dump_stack();
 }
 static void binder_vma_close(struct vm_area_struct *vma)
 {
 	struct binder_proc *proc = vma->vm_private_data;
 	if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE)
-		printk(KERN_INFO "binder: %d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, pgprot_val(vma->vm_page_prot));
+		printk(KERN_INFO
+			"binder: %d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n",
+			proc->pid, vma->vm_start, vma->vm_end,
+			(vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
+			(unsigned long)pgprot_val(vma->vm_page_prot));
 	proc->vma = NULL;
 }
 
@@ -2677,7 +2685,11 @@
 		vma->vm_end = vma->vm_start + SZ_4M;
 
 	if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE)
-		printk(KERN_INFO "binder_mmap: %d %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, pgprot_val(vma->vm_page_prot));
+		printk(KERN_INFO
+			"binder_mmap: %d %lx-%lx (%ld K) vma %lx pagep %lx\n",
+			proc->pid, vma->vm_start, vma->vm_end,
+			(vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
+			(unsigned long)pgprot_val(vma->vm_page_prot));
 
 	if (vma->vm_flags & FORBIDDEN_MMAP_FLAGS) {
 		ret = -EPERM;
diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c
index 643ac5c..3375c1c 100644
--- a/drivers/staging/android/ram_console.c
+++ b/drivers/staging/android/ram_console.c
@@ -225,7 +225,7 @@
 		buffer_size - sizeof(struct ram_console_buffer);
 
 	if (ram_console_buffer_size > buffer_size) {
-		pr_err("ram_console: buffer %p, invalid size %d, datasize %d\n",
+		pr_err("ram_console: buffer %p, invalid size %zu, datasize %zu\n",
 		       buffer, buffer_size, ram_console_buffer_size);
 		return 0;
 	}
@@ -235,8 +235,8 @@
 						ECC_BLOCK_SIZE) + 1) * ECC_SIZE;
 
 	if (ram_console_buffer_size > buffer_size) {
-		pr_err("ram_console: buffer %p, invalid size %d, "
-		       "non-ecc datasize %d\n",
+		pr_err("ram_console: buffer %p, invalid size %zu, "
+		       "non-ecc datasize %zu\n",
 		       buffer, buffer_size, ram_console_buffer_size);
 		return 0;
 	}
@@ -322,7 +322,7 @@
 	}
 	buffer_size = res->end - res->start + 1;
 	start = res->start;
-	printk(KERN_INFO "ram_console: got buffer at %x, size %x\n",
+	printk(KERN_INFO "ram_console: got buffer at %zx, size %zx\n",
 	       start, buffer_size);
 	buffer = ioremap(res->start, buffer_size);
 	if (buffer == NULL) {
diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c
index 666a186..04dde4b 100644
--- a/drivers/staging/asus_oled/asus_oled.c
+++ b/drivers/staging/asus_oled/asus_oled.c
@@ -56,10 +56,10 @@
 MODULE_DESCRIPTION("Asus OLED Driver v" ASUS_OLED_VERSION);
 MODULE_LICENSE("GPL");
 
-static struct class *oled_class = 0;
-static int oled_num = 0;
+static struct class *oled_class;
+static int oled_num;
 
-static uint start_off = 0;
+static uint start_off;
 
 module_param(start_off, uint, 0644);
 
@@ -80,20 +80,20 @@
 };
 
 /* table of devices that work with this driver */
-static struct usb_device_id id_table [] = {
+static struct usb_device_id id_table[] = {
 	{ USB_DEVICE(0x0b05, 0x1726) }, // Asus G1/G2 (and variants)
 	{ USB_DEVICE(0x0b05, 0x175b) }, // Asus G50V (and possibly others - G70? G71?)
 	{ },
 };
 
 /* parameters of specific devices */
-static struct oled_dev_desc_str oled_dev_desc_table [] = {
+static struct oled_dev_desc_str oled_dev_desc_table[] = {
 	{ 0x0b05, 0x1726, 128, PACK_MODE_G1, "G1/G2" },
 	{ 0x0b05, 0x175b, 256, PACK_MODE_G50, "G50" },
 	{ },
 };
 
-MODULE_DEVICE_TABLE (usb, id_table);
+MODULE_DEVICE_TABLE(usb, id_table);
 
 #define SETUP_PACKET_HEADER(packet, val1, val2, val3, val4, val5, val6, val7) \
 	do {					\
@@ -107,7 +107,7 @@
 		packet->header.value6 = val5;		\
 		packet->header.value7 = val6;		\
 		packet->header.value8 = val7;		\
-	} while(0);
+	} while (0);
 
 struct asus_oled_header {
 	uint8_t		magic1;
@@ -160,10 +160,12 @@
 
 	SETUP_PACKET_HEADER(packet, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00);
 
-	if (enabl) packet->bitmap[0] = 0xaf;
-	else packet->bitmap[0] = 0xae;
+	if (enabl)
+		packet->bitmap[0] = 0xaf;
+	else
+		packet->bitmap[0] = 0xae;
 
-	for (a=0; a<1; a++) {
+	for (a = 0; a < 1; a++) {
 		retval = usb_bulk_msg(odev->udev,
 			usb_sndbulkpipe(odev->udev, 2),
 			packet,
@@ -252,7 +254,7 @@
 	}
 }
 
-static void send_packet(struct usb_device *udev, struct asus_oled_packet *packet, size_t offset, size_t len, char *buf, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5, uint8_t b6){
+static void send_packet(struct usb_device *udev, struct asus_oled_packet *packet, size_t offset, size_t len, char *buf, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5, uint8_t b6) {
 	int retval;
 	int act_len;
 
@@ -294,7 +296,7 @@
 		return;
 	}
 
-	if (odev->pack_mode==PACK_MODE_G1){
+	if (odev->pack_mode == PACK_MODE_G1) {
 		// When sending roll-mode data the display updated only first packet.
 		// I have no idea why, but when static picture is send just before
 		// rolling picture - everything works fine.
@@ -308,7 +310,7 @@
 		send_packets(odev->udev, packet, odev->buf, odev->pic_mode, packet_num);
 	}
 	else
-	if (odev->pack_mode==PACK_MODE_G50){
+	if (odev->pack_mode == PACK_MODE_G50) {
 		send_packets_g50(odev->udev, packet, odev->buf);
 	}
 
@@ -326,7 +328,7 @@
 			x += odev->x_shift;
 			y += odev->y_shift;
 
-			switch(odev->pack_mode)
+			switch (odev->pack_mode)
 			{
 				case PACK_MODE_G1:
 					// i = (x/128)*640 + 127 - x + (y/8)*128;
@@ -377,30 +379,32 @@
 {
 	size_t offs = 0, max_offs;
 
-	if (count < 1) return 0;
+	if (count < 1)
+		return 0;
 
-	if (tolower(buf[0]) == 'b'){
+	if (tolower(buf[0]) == 'b') {
 	    // binary mode, set the entire memory
 
 	    size_t i;
 
 	    odev->buf_size = (odev->dev_width * ASUS_OLED_DISP_HEIGHT) / 8;
 
-	    if (odev->buf) kfree(odev->buf);
+	    if (odev->buf)
+		    kfree(odev->buf);
 	    odev->buf = kmalloc(odev->buf_size, GFP_KERNEL);
 
 	    memset(odev->buf, 0xff, odev->buf_size);
 
-	    for (i=1; i < count && i<=32*32; i++){
+	    for (i = 1; i < count && i <= 32 * 32; i++) {
 		odev->buf[i-1] = buf[i];
 		odev->buf_offs = i-1;
 	    }
 
-	    odev->width=odev->dev_width / 8;
-	    odev->height=ASUS_OLED_DISP_HEIGHT;
-	    odev->x_shift=0;
-	    odev->y_shift=0;
-	    odev->last_val=0;
+	    odev->width = odev->dev_width / 8;
+	    odev->height = ASUS_OLED_DISP_HEIGHT;
+	    odev->x_shift = 0;
+	    odev->y_shift = 0;
+	    odev->last_val =  0;
 
 	    send_data(odev);
 
@@ -416,7 +420,7 @@
 			goto error_header;
 		}
 
-		switch(tolower(buf[1])) {
+		switch (tolower(buf[1])) {
 			case ASUS_OLED_STATIC:
 			case ASUS_OLED_ROLL:
 			case ASUS_OLED_FLASH:
@@ -432,27 +436,36 @@
 			if (buf[i] >= '0' && buf[i] <= '9') {
 				w = 10*w + (buf[i] - '0');
 
-				if (w > ASUS_OLED_MAX_WIDTH) goto error_width;
+				if (w > ASUS_OLED_MAX_WIDTH)
+					goto error_width;
 			}
-			else if (tolower(buf[i]) == 'x') break;
-			else goto error_width;
+			else if (tolower(buf[i]) == 'x')
+				break;
+			else
+				goto error_width;
 		}
 
 		for (++i; i < count; ++i) {
 			if (buf[i] >= '0' && buf[i] <= '9') {
 				h = 10*h + (buf[i] - '0');
 
-				if (h > ASUS_OLED_DISP_HEIGHT) goto error_height;
+				if (h > ASUS_OLED_DISP_HEIGHT)
+					goto error_height;
 			}
-			else if (tolower(buf[i]) == '>') break;
-			else goto error_height;
+			else if (tolower(buf[i]) == '>')
+				break;
+			else
+				goto error_height;
 		}
 
-		if (w < 1 || w > ASUS_OLED_MAX_WIDTH) goto error_width;
+		if (w < 1 || w > ASUS_OLED_MAX_WIDTH)
+			goto error_width;
 
-		if (h < 1 || h > ASUS_OLED_DISP_HEIGHT) goto error_height;
+		if (h < 1 || h > ASUS_OLED_DISP_HEIGHT)
+			goto error_height;
 
-		if (i >= count || buf[i] != '>') goto error_header;
+		if (i >= count || buf[i] != '>')
+			goto error_header;
 
 		offs = i+1;
 
@@ -468,7 +481,8 @@
 
 		odev->buf_size = w_mem * h_mem / 8;
 
-		if (odev->buf) kfree(odev->buf);
+		if (odev->buf)
+			kfree(odev->buf);
 		odev->buf = kmalloc(odev->buf_size, GFP_KERNEL);
 
 		if (odev->buf == NULL) {
@@ -505,23 +519,30 @@
 		int ret;
 
 		if (buf[offs] == '1' || buf[offs] == '#') {
-			if ( (ret = append_values(odev, 1, 1)) < 0) return ret;
+			ret = append_values(odev, 1, 1);
+			if (ret < 0)
+				return ret;
 		}
 		else if (buf[offs] == '0' || buf[offs] == ' ') {
-			if ( (ret = append_values(odev, 0, 1)) < 0) return ret;
+			ret = append_values(odev, 0, 1);
+			if (ret < 0)
+				return ret;
 		}
 		else if (buf[offs] == '\n') {
 			// New line detected. Lets assume, that all characters till the end of the
 			// line were equal to the last character in this line.
 			if (odev->buf_offs % odev->width != 0)
-				if ( (ret = append_values(odev, odev->last_val,
-				      odev->width - (odev->buf_offs % odev->width))) < 0) return ret;
+				ret = append_values(odev, odev->last_val,
+				      odev->width - (odev->buf_offs % odev->width));
+				if (ret < 0)
+					return ret;
 		}
 
 		offs++;
 	}
 
-	if (odev->buf_offs >= max_offs) send_data(odev);
+	if (odev->buf_offs >= max_offs)
+		send_data(odev);
 
 	return count;
 
@@ -566,9 +587,9 @@
 	uint16_t dev_width = 0;
 	oled_pack_mode_t pack_mode = PACK_MODE_LAST;
 	const struct oled_dev_desc_str * dev_desc = oled_dev_desc_table;
-	const char *desc = 0;
+	const char *desc = NULL;
 
-	if (id == 0) {
+	if (!id) {
 		// Even possible? Just to make sure...
 		dev_err(&interface->dev, "No usb_device_id provided!\n");
 		return -ENODEV;
@@ -586,7 +607,7 @@
 		}
 	}
 
-	if ( !desc || dev_width < 1 || pack_mode == PACK_MODE_LAST) {
+	if (!desc || dev_width < 1 || pack_mode == PACK_MODE_LAST) {
 		dev_err(&interface->dev, "Missing or incomplete device description!\n");
 		return -ENODEV;
 	}
@@ -611,20 +632,20 @@
 	odev->last_val = 0;
 	odev->buf = NULL;
 	odev->enabled = 1;
-	odev->dev = 0;
+	odev->dev = NULL;
 
-	usb_set_intfdata (interface, odev);
+	usb_set_intfdata(interface, odev);
 
-	if ((retval = device_create_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(enabled)))) {
+	retval = device_create_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(enabled));
+	if (retval)
 		goto err_files;
-	}
 
-	if ((retval = device_create_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(picture)))) {
+	retval = device_create_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(picture));
+	if (retval)
 		goto err_files;
-	}
 
-	odev->dev = device_create(oled_class, &interface->dev, MKDEV(0,0),
-				NULL,"oled_%d", ++oled_num);
+	odev->dev = device_create(oled_class, &interface->dev, MKDEV(0, 0),
+				NULL, "oled_%d", ++oled_num);
 
 	if (IS_ERR(odev->dev)) {
 		retval = PTR_ERR(odev->dev);
@@ -633,13 +654,13 @@
 
 	dev_set_drvdata(odev->dev, odev);
 
-	if ( (retval = device_create_file(odev->dev, &dev_attr_enabled))) {
+	retval = device_create_file(odev->dev, &dev_attr_enabled);
+	if (retval)
 		goto err_class_enabled;
-	}
 
-	if ( (retval = device_create_file(odev->dev, &dev_attr_picture))) {
+	retval = device_create_file(odev->dev, &dev_attr_picture);
+	if (retval)
 		goto err_class_picture;
-	}
 
 	dev_info(&interface->dev, "Attached Asus OLED device: %s [width %u, pack_mode %d]\n", desc, odev->dev_width, odev->pack_mode);
 
@@ -659,7 +680,7 @@
 	device_remove_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(enabled));
 	device_remove_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(picture));
 
-	usb_set_intfdata (interface, NULL);
+	usb_set_intfdata(interface, NULL);
 	usb_put_dev(odev->udev);
 	kfree(odev);
 
@@ -670,19 +691,20 @@
 {
 	struct asus_oled_dev *odev;
 
-	odev = usb_get_intfdata (interface);
-	usb_set_intfdata (interface, NULL);
+	odev = usb_get_intfdata(interface);
+	usb_set_intfdata(interface, NULL);
 
 	device_remove_file(odev->dev, &dev_attr_picture);
 	device_remove_file(odev->dev, &dev_attr_enabled);
 	device_unregister(odev->dev);
 
-	device_remove_file(&interface->dev, & ASUS_OLED_DEVICE_ATTR(picture));
-	device_remove_file(&interface->dev, & ASUS_OLED_DEVICE_ATTR(enabled));
+	device_remove_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(picture));
+	device_remove_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(enabled));
 
 	usb_put_dev(odev->udev);
 
-	if (odev->buf) kfree(odev->buf);
+	if (odev->buf)
+		kfree(odev->buf);
 
 	kfree(odev);
 
@@ -713,7 +735,8 @@
 		return PTR_ERR(oled_class);
 	}
 
-	if ((retval = class_create_file(oled_class, &class_attr_version))) {
+	retval = class_create_file(oled_class, &class_attr_version);
+	if (retval) {
 		err("Error creating class version file");
 		goto error;
 	}
@@ -740,6 +763,6 @@
 	usb_deregister(&oled_driver);
 }
 
-module_init (asus_oled_init);
-module_exit (asus_oled_exit);
+module_init(asus_oled_init);
+module_exit(asus_oled_exit);
 
diff --git a/drivers/staging/at76_usb/TODO b/drivers/staging/at76_usb/TODO
index 6911ca7..0c7ed21 100644
--- a/drivers/staging/at76_usb/TODO
+++ b/drivers/staging/at76_usb/TODO
@@ -1,2 +1,7 @@
-rewrite the driver to use the proper in-kernel wireless stack
-instead of using its own.
+Fix the mac80211 port of at76_usb (the proper in-kernel wireless
+stack) and get it included to the mainline. Patches available here:
+
+http://git.kernel.org/?p=linux/kernel/git/linville/wireless-legacy.git;a=shortlog;h=at76
+
+Contact Kalle Valo <kalle.valo@iki.fi> and linux-wireless list
+<linux-wireless@vger.kernel.org> for more information.
diff --git a/drivers/staging/at76_usb/at76_usb.c b/drivers/staging/at76_usb/at76_usb.c
index c8e4d31..6f6e36a 100644
--- a/drivers/staging/at76_usb/at76_usb.c
+++ b/drivers/staging/at76_usb/at76_usb.c
@@ -36,7 +36,7 @@
 #include <net/ieee80211_radiotap.h>
 #include <linux/firmware.h>
 #include <linux/leds.h>
-#include <net/ieee80211.h>
+#include <linux/ieee80211.h>
 
 #include "at76_usb.h"
 
@@ -1727,12 +1727,12 @@
 
 	/* write TLV data elements */
 
-	ie->id = MFIE_TYPE_SSID;
+	ie->id = WLAN_EID_SSID;
 	ie->len = bss->ssid_len;
 	memcpy(ie->data, bss->ssid, bss->ssid_len);
 	next_ie(&ie);
 
-	ie->id = MFIE_TYPE_RATES;
+	ie->id = WLAN_EID_SUPP_RATES;
 	ie->len = sizeof(hw_rates);
 	memcpy(ie->data, hw_rates, sizeof(hw_rates));
 	next_ie(&ie);		/* ie points behind the supp_rates field */
@@ -4397,7 +4397,7 @@
 
 		switch (ie->id) {
 
-		case MFIE_TYPE_SSID:
+		case WLAN_EID_SSID:
 			if (have_ssid)
 				break;
 
@@ -4420,7 +4420,7 @@
 			have_ssid = 1;
 			break;
 
-		case MFIE_TYPE_RATES:
+		case WLAN_EID_SUPP_RATES:
 			if (have_rates)
 				break;
 
@@ -4433,7 +4433,7 @@
 				 hex2str(ie->data, ie->len));
 			break;
 
-		case MFIE_TYPE_DS_SET:
+		case WLAN_EID_DS_PARAMS:
 			if (have_channel)
 				break;
 
@@ -4443,9 +4443,9 @@
 				 priv->netdev->name, match->channel);
 			break;
 
-		case MFIE_TYPE_CF_SET:
-		case MFIE_TYPE_TIM:
-		case MFIE_TYPE_IBSS_SET:
+		case WLAN_EID_CF_PARAMS:
+		case WLAN_EID_TIM:
+		case WLAN_EID_IBSS_PARAMS:
 		default:
 			at76_dbg(DBG_RX_BEACON, "%s: beacon IE id %d len %d %s",
 				 priv->netdev->name, ie->id, ie->len,
@@ -5370,8 +5370,7 @@
 
 	at76_dbg(DBG_PROC_ENTRY, "%s: unlinked urbs", __func__);
 
-	if (priv->rx_skb)
-		kfree_skb(priv->rx_skb);
+	kfree_skb(priv->rx_skb);
 
 	at76_free_bss_list(priv);
 	del_timer_sync(&priv->bss_list_timer);
diff --git a/drivers/staging/at76_usb/at76_usb.h b/drivers/staging/at76_usb/at76_usb.h
index b20be9d..6d60c6e 100644
--- a/drivers/staging/at76_usb/at76_usb.h
+++ b/drivers/staging/at76_usb/at76_usb.h
@@ -22,6 +22,93 @@
 #ifndef _AT76_USB_H
 #define _AT76_USB_H
 
+/*
+ * ieee80211 definitions copied from net/ieee80211.h
+ */
+
+#define WEP_KEY_LEN		13
+#define WEP_KEYS		4
+
+#define IEEE80211_DATA_LEN		2304
+/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
+   6.2.1.1.2.
+
+   The figure in section 7.1.2 suggests a body size of up to 2312
+   bytes is allowed, which is a bit confusing, I suspect this
+   represents the 2304 bytes of real data, plus a possible 8 bytes of
+   WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
+
+#define IEEE80211_1ADDR_LEN 10
+#define IEEE80211_2ADDR_LEN 16
+#define IEEE80211_3ADDR_LEN 24
+#define IEEE80211_4ADDR_LEN 30
+#define IEEE80211_FCS_LEN    4
+#define IEEE80211_HLEN			(IEEE80211_4ADDR_LEN)
+#define IEEE80211_FRAME_LEN		(IEEE80211_DATA_LEN + IEEE80211_HLEN)
+
+#define MIN_FRAG_THRESHOLD     256U
+#define	MAX_FRAG_THRESHOLD     2346U
+
+struct ieee80211_info_element {
+	u8 id;
+	u8 len;
+	u8 data[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addr {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+	u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_auth {
+	struct ieee80211_hdr_3addr header;
+	__le16 algorithm;
+	__le16 transaction;
+	__le16 status;
+	/* challenge */
+	struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_assoc_request {
+	struct ieee80211_hdr_3addr header;
+	__le16 capability;
+	__le16 listen_interval;
+	/* SSID, supported rates, RSN */
+	struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_probe_response {
+	struct ieee80211_hdr_3addr header;
+	__le32 time_stamp[2];
+	__le16 beacon_interval;
+	__le16 capability;
+	/* SSID, supported rates, FH params, DS params,
+	 * CF params, IBSS params, TIM (if beacon), RSN */
+	struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+/* Alias beacon for probe_response */
+#define ieee80211_beacon ieee80211_probe_response
+
+struct ieee80211_assoc_response {
+	struct ieee80211_hdr_3addr header;
+	__le16 capability;
+	__le16 status;
+	__le16 aid;
+	/* supported rates */
+	struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_disassoc {
+	struct ieee80211_hdr_3addr header;
+	__le16 reason;
+} __attribute__ ((packed));
+
 /* Board types */
 enum board_type {
 	BOARD_503_ISL3861 = 1,
diff --git a/drivers/staging/b3dfg/Kconfig b/drivers/staging/b3dfg/Kconfig
new file mode 100644
index 0000000..5242310
--- /dev/null
+++ b/drivers/staging/b3dfg/Kconfig
@@ -0,0 +1,9 @@
+config B3DFG
+       tristate "Brontes 3d Frame Framegrabber"
+       default n
+       ---help---
+         This driver provides support for the Brontes 3d Framegrabber
+         PCI card.
+
+         To compile this driver as a module, choose M here. The module
+         will be called b3dfg.
diff --git a/drivers/staging/b3dfg/Makefile b/drivers/staging/b3dfg/Makefile
new file mode 100644
index 0000000..91f439f
--- /dev/null
+++ b/drivers/staging/b3dfg/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_B3DFG) += b3dfg.o
diff --git a/drivers/staging/b3dfg/TODO b/drivers/staging/b3dfg/TODO
new file mode 100644
index 0000000..f5a9298
--- /dev/null
+++ b/drivers/staging/b3dfg/TODO
@@ -0,0 +1,4 @@
+
+ - queue/wait buffer presents filltime results for each frame?
+ - counting of dropped frames
+ - review endianness
diff --git a/drivers/staging/b3dfg/b3dfg.c b/drivers/staging/b3dfg/b3dfg.c
new file mode 100644
index 0000000..0348072
--- /dev/null
+++ b/drivers/staging/b3dfg/b3dfg.c
@@ -0,0 +1,1119 @@
+ /*
+ * Brontes PCI frame grabber driver
+ *
+ * Copyright (C) 2008 3M Company
+ * Contact: Justin Bronder <jsbronder@brontes3d.com>
+ * Original Authors: Daniel Drake <ddrake@brontes3d.com>
+ *                   Duane Griffin <duaneg@dghda.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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/ioctl.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <linux/cdev.h>
+#include <linux/list.h>
+#include <linux/poll.h>
+#include <linux/wait.h>
+#include <linux/mm.h>
+#include <linux/version.h>
+#include <linux/uaccess.h>
+
+static unsigned int b3dfg_nbuf = 2;
+
+module_param_named(buffer_count, b3dfg_nbuf, uint, 0444);
+
+MODULE_PARM_DESC(buffer_count, "Number of buffers (min 2, default 2)\n");
+
+MODULE_AUTHOR("Daniel Drake <ddrake@brontes3d.com>");
+MODULE_DESCRIPTION("Brontes frame grabber driver");
+MODULE_LICENSE("GPL");
+
+#define DRIVER_NAME "b3dfg"
+#define B3DFG_MAX_DEVS 4
+#define B3DFG_FRAMES_PER_BUFFER 3
+
+#define B3DFG_BAR_REGS	0
+#define B3DFG_REGS_LENGTH 0x10000
+
+#define B3DFG_IOC_MAGIC		0xb3 /* dfg :-) */
+#define B3DFG_IOCGFRMSZ		_IOR(B3DFG_IOC_MAGIC, 1, int)
+#define B3DFG_IOCTNUMBUFS	_IO(B3DFG_IOC_MAGIC, 2)
+#define B3DFG_IOCTTRANS		_IO(B3DFG_IOC_MAGIC, 3)
+#define B3DFG_IOCTQUEUEBUF	_IO(B3DFG_IOC_MAGIC, 4)
+#define B3DFG_IOCTPOLLBUF	_IOWR(B3DFG_IOC_MAGIC, 5, struct b3dfg_poll)
+#define B3DFG_IOCTWAITBUF	_IOWR(B3DFG_IOC_MAGIC, 6, struct b3dfg_wait)
+#define B3DFG_IOCGWANDSTAT	_IOR(B3DFG_IOC_MAGIC, 7, int)
+
+enum {
+	/* number of 4kb pages per frame */
+	B3D_REG_FRM_SIZE = 0x0,
+
+	/* bit 0: set to enable interrupts
+	 * bit 1: set to enable cable status change interrupts */
+	B3D_REG_HW_CTRL = 0x4,
+
+	/* bit 0-1 - 1-based ID of next pending frame transfer (0 = none)
+	 * bit 2 indicates the previous DMA transfer has completed
+	 * bit 3 indicates wand cable status change
+	 * bit 8:15 - counter of number of discarded triplets */
+	B3D_REG_DMA_STS = 0x8,
+
+	/* bit 0: wand status (1 = present, 0 = disconnected) */
+	B3D_REG_WAND_STS = 0xc,
+
+	/* bus address for DMA transfers. lower 2 bits must be zero because DMA
+	 * works with 32 bit word size. */
+	B3D_REG_EC220_DMA_ADDR = 0x8000,
+
+	/* bit 20:0 - number of 32 bit words to be transferred
+	 * bit 21:31 - reserved */
+	B3D_REG_EC220_TRF_SIZE = 0x8004,
+
+	/* bit 0 - error bit
+	 * bit 1 - interrupt bit (set to generate interrupt at end of transfer)
+	 * bit 2 - start bit (set to start transfer)
+	 * bit 3 - direction (0 = DMA_TO_DEVICE, 1 = DMA_FROM_DEVICE
+	 * bit 4:31 - reserved */
+	B3D_REG_EC220_DMA_STS = 0x8008,
+};
+
+enum b3dfg_buffer_state {
+	B3DFG_BUFFER_POLLED = 0,
+	B3DFG_BUFFER_PENDING,
+	B3DFG_BUFFER_POPULATED,
+};
+
+struct b3dfg_buffer {
+	unsigned char *frame[B3DFG_FRAMES_PER_BUFFER];
+	struct list_head list;
+	u8 state;
+};
+
+struct b3dfg_dev {
+
+	/* no protection needed: all finalized at initialization time */
+	struct pci_dev *pdev;
+	struct cdev chardev;
+	struct device *dev;
+	void __iomem *regs;
+	unsigned int frame_size;
+
+	/*
+	 * Protects buffer state, including buffer_queue, triplet_ready,
+	 * cur_dma_frame_idx & cur_dma_frame_addr.
+	 */
+	spinlock_t buffer_lock;
+	struct b3dfg_buffer *buffers;
+	struct list_head buffer_queue;
+
+	/* Last frame in triplet transferred (-1 if none). */
+	int cur_dma_frame_idx;
+
+	/* Current frame's address for DMA. */
+	dma_addr_t cur_dma_frame_addr;
+
+	/*
+	 * Protects cstate_tstamp.
+	 * Nests inside buffer_lock.
+	 */
+	spinlock_t cstate_lock;
+	unsigned long cstate_tstamp;
+
+	/*
+	 * Protects triplets_dropped.
+	 * Nests inside buffers_lock.
+	 */
+	spinlock_t triplets_dropped_lock;
+	unsigned int triplets_dropped;
+
+	wait_queue_head_t buffer_waitqueue;
+
+	unsigned int transmission_enabled:1;
+	unsigned int triplet_ready:1;
+};
+
+static u8 b3dfg_devices[B3DFG_MAX_DEVS];
+
+static struct class *b3dfg_class;
+static dev_t b3dfg_devt;
+
+static const struct pci_device_id b3dfg_ids[] __devinitdata = {
+	{ PCI_DEVICE(0x0b3d, 0x0001) },
+	{ },
+};
+
+MODULE_DEVICE_TABLE(pci, b3dfg_ids);
+
+/***** user-visible types *****/
+
+struct b3dfg_poll {
+	int buffer_idx;
+	unsigned int triplets_dropped;
+};
+
+struct b3dfg_wait {
+	int buffer_idx;
+	unsigned int timeout;
+	unsigned int triplets_dropped;
+};
+
+/**** register I/O ****/
+
+static u32 b3dfg_read32(struct b3dfg_dev *fgdev, u16 reg)
+{
+	return ioread32(fgdev->regs + reg);
+}
+
+static void b3dfg_write32(struct b3dfg_dev *fgdev, u16 reg, u32 value)
+{
+	iowrite32(value, fgdev->regs + reg);
+}
+
+/**** buffer management ****/
+
+/*
+ * Program EC220 for transfer of a specific frame.
+ * Called with buffer_lock held.
+ */
+static int setup_frame_transfer(struct b3dfg_dev *fgdev,
+	struct b3dfg_buffer *buf, int frame)
+{
+	unsigned char *frm_addr;
+	dma_addr_t frm_addr_dma;
+	unsigned int frm_size = fgdev->frame_size;
+
+	frm_addr = buf->frame[frame];
+	frm_addr_dma = pci_map_single(fgdev->pdev, frm_addr,
+					  frm_size, PCI_DMA_FROMDEVICE);
+	if (pci_dma_mapping_error(fgdev->pdev, frm_addr_dma))
+		return -ENOMEM;
+
+	fgdev->cur_dma_frame_addr = frm_addr_dma;
+	fgdev->cur_dma_frame_idx = frame;
+
+	b3dfg_write32(fgdev, B3D_REG_EC220_DMA_ADDR,
+					cpu_to_le32(frm_addr_dma));
+	b3dfg_write32(fgdev, B3D_REG_EC220_TRF_SIZE,
+					cpu_to_le32(frm_size >> 2));
+	b3dfg_write32(fgdev, B3D_REG_EC220_DMA_STS, 0xf);
+
+	return 0;
+}
+
+/* Caller should hold buffer lock */
+static void dequeue_all_buffers(struct b3dfg_dev *fgdev)
+{
+	int i;
+	for (i = 0; i < b3dfg_nbuf; i++) {
+		struct b3dfg_buffer *buf = &fgdev->buffers[i];
+		buf->state = B3DFG_BUFFER_POLLED;
+		list_del_init(&buf->list);
+	}
+}
+
+/* queue a buffer to receive data */
+static int queue_buffer(struct b3dfg_dev *fgdev, int bufidx)
+{
+	struct device *dev = &fgdev->pdev->dev;
+	struct b3dfg_buffer *buf;
+	unsigned long flags;
+	int r = 0;
+
+	spin_lock_irqsave(&fgdev->buffer_lock, flags);
+	if (bufidx < 0 || bufidx >= b3dfg_nbuf) {
+		dev_dbg(dev, "Invalid buffer index, %d\n", bufidx);
+		r = -ENOENT;
+		goto out;
+	}
+	buf = &fgdev->buffers[bufidx];
+
+	if (unlikely(buf->state == B3DFG_BUFFER_PENDING)) {
+		dev_dbg(dev, "buffer %d is already queued\n", bufidx);
+		r = -EINVAL;
+		goto out;
+	}
+
+	buf->state = B3DFG_BUFFER_PENDING;
+	list_add_tail(&buf->list, &fgdev->buffer_queue);
+
+	if (fgdev->transmission_enabled && fgdev->triplet_ready) {
+		dev_dbg(dev, "triplet is ready, pushing immediately\n");
+		fgdev->triplet_ready = 0;
+		r = setup_frame_transfer(fgdev, buf, 0);
+		if (r)
+			dev_err(dev, "unable to map DMA buffer\n");
+	}
+
+out:
+	spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+	return r;
+}
+
+/* non-blocking buffer poll. returns 1 if data is present in the buffer,
+ * 0 otherwise */
+static int poll_buffer(struct b3dfg_dev *fgdev, void __user *arg)
+{
+	struct device *dev = &fgdev->pdev->dev;
+	struct b3dfg_poll p;
+	struct b3dfg_buffer *buf;
+	unsigned long flags;
+	int r = 1;
+	int arg_out = 0;
+
+	if (copy_from_user(&p, arg, sizeof(p)))
+		return -EFAULT;
+
+	if (unlikely(!fgdev->transmission_enabled)) {
+		dev_dbg(dev, "cannot poll, transmission disabled\n");
+		return -EINVAL;
+	}
+
+	if (p.buffer_idx < 0 || p.buffer_idx >= b3dfg_nbuf)
+		return -ENOENT;
+
+	buf = &fgdev->buffers[p.buffer_idx];
+
+	spin_lock_irqsave(&fgdev->buffer_lock, flags);
+
+	if (likely(buf->state == B3DFG_BUFFER_POPULATED)) {
+		arg_out = 1;
+		buf->state = B3DFG_BUFFER_POLLED;
+
+		/* IRQs already disabled by spin_lock_irqsave above. */
+		spin_lock(&fgdev->triplets_dropped_lock);
+		p.triplets_dropped = fgdev->triplets_dropped;
+		fgdev->triplets_dropped = 0;
+		spin_unlock(&fgdev->triplets_dropped_lock);
+	} else {
+		r = 0;
+	}
+
+	spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+
+	if (arg_out && copy_to_user(arg, &p, sizeof(p)))
+		r = -EFAULT;
+
+	return r;
+}
+
+static unsigned long get_cstate_change(struct b3dfg_dev *fgdev)
+{
+	unsigned long flags, when;
+
+	spin_lock_irqsave(&fgdev->cstate_lock, flags);
+	when = fgdev->cstate_tstamp;
+	spin_unlock_irqrestore(&fgdev->cstate_lock, flags);
+	return when;
+}
+
+static int is_event_ready(struct b3dfg_dev *fgdev, struct b3dfg_buffer *buf,
+			  unsigned long when)
+{
+	int result;
+	unsigned long flags;
+
+	spin_lock_irqsave(&fgdev->buffer_lock, flags);
+	spin_lock(&fgdev->cstate_lock);
+	result = (!fgdev->transmission_enabled ||
+		  buf->state == B3DFG_BUFFER_POPULATED ||
+		  when != fgdev->cstate_tstamp);
+	spin_unlock(&fgdev->cstate_lock);
+	spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+
+	return result;
+}
+
+/* sleep until a specific buffer becomes populated */
+static int wait_buffer(struct b3dfg_dev *fgdev, void __user *arg)
+{
+	struct device *dev = &fgdev->pdev->dev;
+	struct b3dfg_wait w;
+	struct b3dfg_buffer *buf;
+	unsigned long flags, when;
+	int r;
+
+	if (copy_from_user(&w, arg, sizeof(w)))
+		return -EFAULT;
+
+	if (!fgdev->transmission_enabled) {
+		dev_dbg(dev, "cannot wait, transmission disabled\n");
+		return -EINVAL;
+	}
+
+	if (w.buffer_idx < 0 || w.buffer_idx >= b3dfg_nbuf)
+		return -ENOENT;
+
+	buf = &fgdev->buffers[w.buffer_idx];
+
+	spin_lock_irqsave(&fgdev->buffer_lock, flags);
+
+	if (buf->state == B3DFG_BUFFER_POPULATED) {
+		r = w.timeout;
+		goto out_triplets_dropped;
+	}
+
+	spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+
+	when = get_cstate_change(fgdev);
+	if (w.timeout > 0) {
+		r = wait_event_interruptible_timeout(fgdev->buffer_waitqueue,
+			is_event_ready(fgdev, buf, when),
+			(w.timeout * HZ) / 1000);
+
+		if (unlikely(r < 0))
+			goto out;
+
+		w.timeout = r * 1000 / HZ;
+	} else {
+		r = wait_event_interruptible(fgdev->buffer_waitqueue,
+			is_event_ready(fgdev, buf, when));
+
+		if (unlikely(r)) {
+			r = -ERESTARTSYS;
+			goto out;
+		}
+	}
+
+	/* TODO: Inform the user via field(s) in w? */
+	if (!fgdev->transmission_enabled || when != get_cstate_change(fgdev)) {
+		r = -EINVAL;
+		goto out;
+	}
+
+	spin_lock_irqsave(&fgdev->buffer_lock, flags);
+
+	if (buf->state != B3DFG_BUFFER_POPULATED) {
+		r = -ETIMEDOUT;
+		goto out_unlock;
+	}
+
+	buf->state = B3DFG_BUFFER_POLLED;
+
+out_triplets_dropped:
+
+	/* IRQs already disabled by spin_lock_irqsave above. */
+	spin_lock(&fgdev->triplets_dropped_lock);
+	w.triplets_dropped = fgdev->triplets_dropped;
+	fgdev->triplets_dropped = 0;
+	spin_unlock(&fgdev->triplets_dropped_lock);
+
+out_unlock:
+	spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+	if (copy_to_user(arg, &w, sizeof(w)))
+		r = -EFAULT;
+out:
+	return r;
+}
+
+/* mmap page fault handler */
+static int b3dfg_vma_fault(struct vm_area_struct *vma,
+	struct vm_fault *vmf)
+{
+	struct b3dfg_dev *fgdev = vma->vm_file->private_data;
+	unsigned long off = vmf->pgoff << PAGE_SHIFT;
+	unsigned int frame_size = fgdev->frame_size;
+	unsigned int buf_size = frame_size * B3DFG_FRAMES_PER_BUFFER;
+	unsigned char *addr;
+
+	/* determine which buffer the offset lies within */
+	unsigned int buf_idx = off / buf_size;
+	/* and the offset into the buffer */
+	unsigned int buf_off = off % buf_size;
+
+	/* determine which frame inside the buffer the offset lies in */
+	unsigned int frm_idx = buf_off / frame_size;
+	/* and the offset into the frame */
+	unsigned int frm_off = buf_off % frame_size;
+
+	if (unlikely(buf_idx >= b3dfg_nbuf))
+		return VM_FAULT_SIGBUS;
+
+	addr = fgdev->buffers[buf_idx].frame[frm_idx] + frm_off;
+	vm_insert_pfn(vma, (unsigned long)vmf->virtual_address,
+			  virt_to_phys(addr) >> PAGE_SHIFT);
+
+	return VM_FAULT_NOPAGE;
+}
+
+static struct vm_operations_struct b3dfg_vm_ops = {
+	.fault = b3dfg_vma_fault,
+};
+
+static int get_wand_status(struct b3dfg_dev *fgdev, int __user *arg)
+{
+	u32 wndstat = b3dfg_read32(fgdev, B3D_REG_WAND_STS);
+	dev_dbg(&fgdev->pdev->dev, "wand status %x\n", wndstat);
+	return __put_user(wndstat & 0x1, arg);
+}
+
+static int enable_transmission(struct b3dfg_dev *fgdev)
+{
+	u16 command;
+	unsigned long flags;
+	struct device *dev = &fgdev->pdev->dev;
+
+	dev_dbg(dev, "enable transmission\n");
+
+	/* check the cable is plugged in. */
+	if (!b3dfg_read32(fgdev, B3D_REG_WAND_STS)) {
+		dev_dbg(dev, "cannot start transmission without wand\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * Check we're a bus master.
+	 * TODO: I think we can remove this having added the pci_set_master call
+	 */
+	pci_read_config_word(fgdev->pdev, PCI_COMMAND, &command);
+	if (!(command & PCI_COMMAND_MASTER)) {
+		dev_err(dev, "not a bus master, force-enabling\n");
+		pci_write_config_word(fgdev->pdev, PCI_COMMAND,
+			command | PCI_COMMAND_MASTER);
+	}
+
+	spin_lock_irqsave(&fgdev->buffer_lock, flags);
+
+	/* Handle racing enable_transmission calls. */
+	if (fgdev->transmission_enabled) {
+		spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+		goto out;
+	}
+
+	spin_lock(&fgdev->triplets_dropped_lock);
+	fgdev->triplets_dropped = 0;
+	spin_unlock(&fgdev->triplets_dropped_lock);
+
+	fgdev->triplet_ready = 0;
+	fgdev->cur_dma_frame_idx = -1;
+	fgdev->transmission_enabled = 1;
+
+	spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+
+	/* Enable DMA and cable status interrupts. */
+	b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0x03);
+
+out:
+	return 0;
+}
+
+static void disable_transmission(struct b3dfg_dev *fgdev)
+{
+	struct device *dev = &fgdev->pdev->dev;
+	unsigned long flags;
+	u32 tmp;
+
+	dev_dbg(dev, "disable transmission\n");
+
+	/* guarantee that no more interrupts will be serviced */
+	spin_lock_irqsave(&fgdev->buffer_lock, flags);
+	fgdev->transmission_enabled = 0;
+
+	b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0);
+
+	/* FIXME: temporary debugging only. if the board stops transmitting,
+	 * hitting ctrl+c and seeing this message is useful for determining
+	 * the state of the board. */
+	tmp = b3dfg_read32(fgdev, B3D_REG_DMA_STS);
+	dev_dbg(dev, "DMA_STS reads %x after TX stopped\n", tmp);
+
+	dequeue_all_buffers(fgdev);
+	spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+
+	wake_up_interruptible(&fgdev->buffer_waitqueue);
+}
+
+static int set_transmission(struct b3dfg_dev *fgdev, int enabled)
+{
+	int res = 0;
+
+	if (enabled && !fgdev->transmission_enabled)
+		res = enable_transmission(fgdev);
+	else if (!enabled && fgdev->transmission_enabled)
+		disable_transmission(fgdev);
+
+	return res;
+}
+
+/* Called in interrupt context. */
+static void handle_cstate_unplug(struct b3dfg_dev *fgdev)
+{
+	/* Disable all interrupts. */
+	b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0);
+
+	/* Stop transmission. */
+	spin_lock(&fgdev->buffer_lock);
+	fgdev->transmission_enabled = 0;
+
+	fgdev->cur_dma_frame_idx = -1;
+	fgdev->triplet_ready = 0;
+	if (fgdev->cur_dma_frame_addr) {
+		pci_unmap_single(fgdev->pdev, fgdev->cur_dma_frame_addr,
+				 fgdev->frame_size, PCI_DMA_FROMDEVICE);
+		fgdev->cur_dma_frame_addr = 0;
+	}
+	dequeue_all_buffers(fgdev);
+	spin_unlock(&fgdev->buffer_lock);
+}
+
+/* Called in interrupt context. */
+static void handle_cstate_change(struct b3dfg_dev *fgdev)
+{
+	u32 cstate = b3dfg_read32(fgdev, B3D_REG_WAND_STS);
+	unsigned long when;
+	struct device *dev = &fgdev->pdev->dev;
+
+	dev_dbg(dev, "cable state change: %u\n", cstate);
+
+	/*
+	 * When the wand is unplugged we reset our state. The hardware will
+	 * have done the same internally.
+	 *
+	 * Note we should never see a cable *plugged* event, as interrupts
+	 * should only be enabled when transmitting, which requires the cable
+	 * to be plugged. If we do see one it probably means the cable has been
+	 * unplugged and re-plugged very rapidly. Possibly because it has a
+	 * broken wire and is momentarily losing contact.
+	 *
+	 * TODO: At the moment if you plug in the cable then enable transmission
+	 * the hardware will raise a couple of spurious interrupts, so
+	 * just ignore them for now.
+	 *
+	 * Once the hardware is fixed we should complain and treat it as an
+	 * unplug. Or at least track how frequently it is happening and do
+	 * so if too many come in.
+	 */
+	if (cstate) {
+		dev_warn(dev, "ignoring unexpected plug event\n");
+		return;
+	}
+	handle_cstate_unplug(fgdev);
+
+	/*
+	 * Record cable state change timestamp & wake anyone waiting
+	 * on a cable state change. Be paranoid about ensuring events
+	 * are not missed if we somehow get two interrupts in a jiffy.
+	 */
+	spin_lock(&fgdev->cstate_lock);
+	when = jiffies_64;
+	if (when <= fgdev->cstate_tstamp)
+		when = fgdev->cstate_tstamp + 1;
+	fgdev->cstate_tstamp = when;
+	wake_up_interruptible(&fgdev->buffer_waitqueue);
+	spin_unlock(&fgdev->cstate_lock);
+}
+
+/* Called with buffer_lock held. */
+static void transfer_complete(struct b3dfg_dev *fgdev)
+{
+	struct b3dfg_buffer *buf;
+	struct device *dev = &fgdev->pdev->dev;
+
+	pci_unmap_single(fgdev->pdev, fgdev->cur_dma_frame_addr,
+			 fgdev->frame_size, PCI_DMA_FROMDEVICE);
+	fgdev->cur_dma_frame_addr = 0;
+
+	buf = list_entry(fgdev->buffer_queue.next, struct b3dfg_buffer, list);
+	if (buf) {
+		dev_dbg(dev, "handle frame completion\n");
+		if (fgdev->cur_dma_frame_idx == B3DFG_FRAMES_PER_BUFFER - 1) {
+
+			/* last frame of that triplet completed */
+			dev_dbg(dev, "triplet completed\n");
+			buf->state = B3DFG_BUFFER_POPULATED;
+			list_del_init(&buf->list);
+			wake_up_interruptible(&fgdev->buffer_waitqueue);
+		}
+	} else {
+		dev_err(dev, "got frame but no buffer!\n");
+	}
+}
+
+/*
+ * Called with buffer_lock held.
+ *
+ * Note that idx is the (1-based) *next* frame to be transferred, while
+ * cur_dma_frame_idx is the (0-based) *last* frame to have been transferred (or
+ * -1 if none). Thus there should be a difference of 2 between them.
+ */
+static bool setup_next_frame_transfer(struct b3dfg_dev *fgdev, int idx)
+{
+	struct b3dfg_buffer *buf;
+	struct device *dev = &fgdev->pdev->dev;
+	bool need_ack = 1;
+
+	dev_dbg(dev, "program DMA transfer for next frame: %d\n", idx);
+
+	buf = list_entry(fgdev->buffer_queue.next, struct b3dfg_buffer, list);
+	if (buf) {
+		if (idx == fgdev->cur_dma_frame_idx + 2) {
+			if (setup_frame_transfer(fgdev, buf, idx - 1))
+				dev_err(dev, "unable to map DMA buffer\n");
+			need_ack = 0;
+		} else {
+			dev_err(dev, "frame mismatch, got %d, expected %d\n",
+				idx, fgdev->cur_dma_frame_idx + 2);
+
+			/* FIXME: handle dropped triplets here */
+		}
+	} else {
+		dev_err(dev, "cannot setup DMA, no buffer\n");
+	}
+
+	return need_ack;
+}
+
+static irqreturn_t b3dfg_intr(int irq, void *dev_id)
+{
+	struct b3dfg_dev *fgdev = dev_id;
+	struct device *dev = &fgdev->pdev->dev;
+	u32 sts;
+	u8 dropped;
+	bool need_ack = 1;
+	irqreturn_t res = IRQ_HANDLED;
+
+	sts = b3dfg_read32(fgdev, B3D_REG_DMA_STS);
+	if (unlikely(sts == 0)) {
+		dev_warn(dev, "ignore interrupt, DMA status is 0\n");
+		res = IRQ_NONE;
+		goto out;
+	}
+
+	if (unlikely(!fgdev->transmission_enabled)) {
+		dev_warn(dev, "ignore interrupt, TX disabled\n");
+		res = IRQ_HANDLED;
+		goto out;
+	}
+
+	/* Handle dropped frames, as reported by the hardware. */
+	dropped = (sts >> 8) & 0xff;
+	dev_dbg(dev, "intr: DMA_STS=%08x (drop=%d comp=%d next=%d)\n",
+		sts, dropped, !!(sts & 0x4), sts & 0x3);
+	if (unlikely(dropped > 0)) {
+		spin_lock(&fgdev->triplets_dropped_lock);
+		fgdev->triplets_dropped += dropped;
+		spin_unlock(&fgdev->triplets_dropped_lock);
+	}
+
+	/* Handle a cable state change (i.e. the wand being unplugged). */
+	if (sts & 0x08) {
+		handle_cstate_change(fgdev);
+		goto out;
+	}
+
+	spin_lock(&fgdev->buffer_lock);
+	if (unlikely(list_empty(&fgdev->buffer_queue))) {
+
+		/* FIXME need more sanity checking here */
+		dev_info(dev, "buffer not ready for next transfer\n");
+		fgdev->triplet_ready = 1;
+		goto out_unlock;
+	}
+
+	/* Has a frame transfer been completed? */
+	if (sts & 0x4) {
+		u32 dma_status = b3dfg_read32(fgdev, B3D_REG_EC220_DMA_STS);
+
+		/* Check for DMA errors reported by the hardware. */
+		if (unlikely(dma_status & 0x1)) {
+			dev_err(dev, "EC220 error: %08x\n", dma_status);
+
+			/* FIXME flesh out error handling */
+			goto out_unlock;
+		}
+
+		/* Sanity check, we should have a frame index at this point. */
+		if (unlikely(fgdev->cur_dma_frame_idx == -1)) {
+			dev_err(dev, "completed but no last idx?\n");
+
+			/* FIXME flesh out error handling */
+			goto out_unlock;
+		}
+
+		transfer_complete(fgdev);
+	}
+
+	/* Is there another frame transfer pending? */
+	if (sts & 0x3)
+		need_ack = setup_next_frame_transfer(fgdev, sts & 0x3);
+	else
+		fgdev->cur_dma_frame_idx = -1;
+
+out_unlock:
+	spin_unlock(&fgdev->buffer_lock);
+out:
+	if (need_ack) {
+		dev_dbg(dev, "acknowledging interrupt\n");
+		b3dfg_write32(fgdev, B3D_REG_EC220_DMA_STS, 0x0b);
+	}
+	return res;
+}
+
+static int b3dfg_open(struct inode *inode, struct file *filp)
+{
+	struct b3dfg_dev *fgdev =
+		container_of(inode->i_cdev, struct b3dfg_dev, chardev);
+
+	dev_dbg(&fgdev->pdev->dev, "open\n");
+	filp->private_data = fgdev;
+	return 0;
+}
+
+static int b3dfg_release(struct inode *inode, struct file *filp)
+{
+	struct b3dfg_dev *fgdev = filp->private_data;
+	dev_dbg(&fgdev->pdev->dev, "release\n");
+	disable_transmission(fgdev);
+	return 0;
+}
+
+static long b3dfg_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	struct b3dfg_dev *fgdev = filp->private_data;
+
+	switch (cmd) {
+	case B3DFG_IOCGFRMSZ:
+		return __put_user(fgdev->frame_size, (int __user *) arg);
+	case B3DFG_IOCGWANDSTAT:
+		return get_wand_status(fgdev, (int __user *) arg);
+	case B3DFG_IOCTTRANS:
+		return set_transmission(fgdev, (int) arg);
+	case B3DFG_IOCTQUEUEBUF:
+		return queue_buffer(fgdev, (int) arg);
+	case B3DFG_IOCTPOLLBUF:
+		return poll_buffer(fgdev, (void __user *) arg);
+	case B3DFG_IOCTWAITBUF:
+		return wait_buffer(fgdev, (void __user *) arg);
+	default:
+		dev_dbg(&fgdev->pdev->dev, "unrecognised ioctl %x\n", cmd);
+		return -EINVAL;
+	}
+}
+
+static unsigned int b3dfg_poll(struct file *filp, poll_table *poll_table)
+{
+	struct b3dfg_dev *fgdev = filp->private_data;
+	unsigned long flags, when;
+	int i;
+	int r = 0;
+
+	when = get_cstate_change(fgdev);
+	poll_wait(filp, &fgdev->buffer_waitqueue, poll_table);
+
+	spin_lock_irqsave(&fgdev->buffer_lock, flags);
+	for (i = 0; i < b3dfg_nbuf; i++) {
+		if (fgdev->buffers[i].state == B3DFG_BUFFER_POPULATED) {
+			r = POLLIN | POLLRDNORM;
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+
+	/* TODO: Confirm this is how we want to communicate the change. */
+	if (!fgdev->transmission_enabled || when != get_cstate_change(fgdev))
+		r = POLLERR;
+
+	return r;
+}
+
+static int b3dfg_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	struct b3dfg_dev *fgdev = filp->private_data;
+	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+	unsigned long vsize = vma->vm_end - vma->vm_start;
+	unsigned long bufdatalen = b3dfg_nbuf * fgdev->frame_size * 3;
+	unsigned long psize = bufdatalen - offset;
+	int r = 0;
+
+	if (vsize <= psize) {
+		vma->vm_flags |= VM_IO | VM_RESERVED | VM_CAN_NONLINEAR |
+				 VM_PFNMAP;
+		vma->vm_ops = &b3dfg_vm_ops;
+	} else {
+		r = -EINVAL;
+	}
+
+	return r;
+}
+
+static struct file_operations b3dfg_fops = {
+	.owner = THIS_MODULE,
+	.open = b3dfg_open,
+	.release = b3dfg_release,
+	.unlocked_ioctl = b3dfg_ioctl,
+	.poll = b3dfg_poll,
+	.mmap = b3dfg_mmap,
+};
+
+static void free_all_frame_buffers(struct b3dfg_dev *fgdev)
+{
+	int i, j;
+	for (i = 0; i < b3dfg_nbuf; i++)
+		for (j = 0; j < B3DFG_FRAMES_PER_BUFFER; j++)
+			kfree(fgdev->buffers[i].frame[j]);
+	kfree(fgdev->buffers);
+}
+
+/* initialize device and any data structures. called before any interrupts
+ * are enabled. */
+static int b3dfg_init_dev(struct b3dfg_dev *fgdev)
+{
+	int i, j;
+	u32 frm_size = b3dfg_read32(fgdev, B3D_REG_FRM_SIZE);
+
+	/* Disable interrupts. In abnormal circumstances (e.g. after a crash)
+	 * the board may still be transmitting from the previous session. If we
+	 * ensure that interrupts are disabled before we later enable them, we
+	 * are sure to capture a triplet from the start, rather than starting
+	 * from frame 2 or 3. Disabling interrupts causes the FG to throw away
+	 * all buffered data and stop buffering more until interrupts are
+	 * enabled again.
+	 */
+	b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0);
+
+	fgdev->frame_size = frm_size * 4096;
+	fgdev->buffers = kzalloc(sizeof(struct b3dfg_buffer) * b3dfg_nbuf,
+				 GFP_KERNEL);
+	if (!fgdev->buffers)
+		goto err_no_buf;
+	for (i = 0; i < b3dfg_nbuf; i++) {
+		struct b3dfg_buffer *buf = &fgdev->buffers[i];
+		for (j = 0; j < B3DFG_FRAMES_PER_BUFFER; j++) {
+			buf->frame[j] = kmalloc(fgdev->frame_size, GFP_KERNEL);
+			if (!buf->frame[j])
+				goto err_no_mem;
+		}
+		INIT_LIST_HEAD(&buf->list);
+	}
+
+	INIT_LIST_HEAD(&fgdev->buffer_queue);
+	init_waitqueue_head(&fgdev->buffer_waitqueue);
+	spin_lock_init(&fgdev->buffer_lock);
+	spin_lock_init(&fgdev->cstate_lock);
+	spin_lock_init(&fgdev->triplets_dropped_lock);
+	return 0;
+
+err_no_mem:
+	free_all_frame_buffers(fgdev);
+err_no_buf:
+	return -ENOMEM;
+}
+
+/* find next free minor number, returns -1 if none are availabile */
+static int get_free_minor(void)
+{
+	int i;
+	for (i = 0; i < B3DFG_MAX_DEVS; i++) {
+		if (b3dfg_devices[i] == 0)
+			return i;
+	}
+	return -1;
+}
+
+static int __devinit b3dfg_probe(struct pci_dev *pdev,
+	const struct pci_device_id *id)
+{
+	struct b3dfg_dev *fgdev = kzalloc(sizeof(*fgdev), GFP_KERNEL);
+	int r = 0;
+	int minor = get_free_minor();
+	dev_t devno = MKDEV(MAJOR(b3dfg_devt), minor);
+	unsigned long res_len;
+	resource_size_t res_base;
+
+	if (fgdev == NULL)
+		return -ENOMEM;
+
+	if (minor < 0) {
+		dev_err(&pdev->dev, "too many devices found!\n");
+		r = -EIO;
+		goto err_free;
+	}
+
+	b3dfg_devices[minor] = 1;
+	dev_info(&pdev->dev, "probe device with IRQ %d\n", pdev->irq);
+
+	cdev_init(&fgdev->chardev, &b3dfg_fops);
+	fgdev->chardev.owner = THIS_MODULE;
+
+	r = cdev_add(&fgdev->chardev, devno, 1);
+	if (r) {
+		dev_err(&pdev->dev, "cannot add char device\n");
+		goto err_release_minor;
+	}
+
+	fgdev->dev = device_create(
+		b3dfg_class,
+		&pdev->dev,
+		devno,
+		dev_get_drvdata(&pdev->dev),
+		DRIVER_NAME "%d", minor);
+
+	if (IS_ERR(fgdev->dev)) {
+		dev_err(&pdev->dev, "cannot create device\n");
+		r = PTR_ERR(fgdev->dev);
+		goto err_del_cdev;
+	}
+
+	r = pci_enable_device(pdev);
+	if (r) {
+		dev_err(&pdev->dev, "cannot enable PCI device\n");
+		goto err_dev_unreg;
+	}
+
+	res_len = pci_resource_len(pdev, B3DFG_BAR_REGS);
+	if (res_len != B3DFG_REGS_LENGTH) {
+		dev_err(&pdev->dev, "invalid register resource size\n");
+		r = -EIO;
+		goto err_disable;
+	}
+
+	if (pci_resource_flags(pdev, B3DFG_BAR_REGS)
+				!= (IORESOURCE_MEM | IORESOURCE_SIZEALIGN)) {
+		dev_err(&pdev->dev, "invalid resource flags\n");
+		r = -EIO;
+		goto err_disable;
+	}
+	r = pci_request_regions(pdev, DRIVER_NAME);
+	if (r) {
+		dev_err(&pdev->dev, "cannot obtain PCI resources\n");
+		goto err_disable;
+	}
+
+	pci_set_master(pdev);
+
+	r = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	if (r) {
+		dev_err(&pdev->dev, "no usable DMA configuration\n");
+		goto err_free_res;
+	}
+
+	res_base = pci_resource_start(pdev, B3DFG_BAR_REGS);
+	fgdev->regs = ioremap_nocache(res_base, res_len);
+	if (!fgdev->regs) {
+		dev_err(&pdev->dev, "regs ioremap failed\n");
+		r = -EIO;
+		goto err_free_res;
+	}
+
+	fgdev->pdev = pdev;
+	pci_set_drvdata(pdev, fgdev);
+	r = b3dfg_init_dev(fgdev);
+	if (r < 0) {
+		dev_err(&pdev->dev, "failed to initalize device\n");
+		goto err_unmap;
+	}
+
+	r = request_irq(pdev->irq, b3dfg_intr, IRQF_SHARED, DRIVER_NAME, fgdev);
+	if (r) {
+		dev_err(&pdev->dev, "couldn't request irq %d\n", pdev->irq);
+		goto err_free_bufs;
+	}
+
+	return 0;
+
+err_free_bufs:
+	free_all_frame_buffers(fgdev);
+err_unmap:
+	iounmap(fgdev->regs);
+err_free_res:
+	pci_release_regions(pdev);
+err_disable:
+	pci_disable_device(pdev);
+err_dev_unreg:
+	device_destroy(b3dfg_class, devno);
+err_del_cdev:
+	cdev_del(&fgdev->chardev);
+err_release_minor:
+	b3dfg_devices[minor] = 0;
+err_free:
+	kfree(fgdev);
+	return r;
+}
+
+static void __devexit b3dfg_remove(struct pci_dev *pdev)
+{
+	struct b3dfg_dev *fgdev = pci_get_drvdata(pdev);
+	unsigned int minor = MINOR(fgdev->chardev.dev);
+
+	dev_dbg(&pdev->dev, "remove\n");
+
+	free_irq(pdev->irq, fgdev);
+	iounmap(fgdev->regs);
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+	device_destroy(b3dfg_class, MKDEV(MAJOR(b3dfg_devt), minor));
+	cdev_del(&fgdev->chardev);
+	free_all_frame_buffers(fgdev);
+	kfree(fgdev);
+	b3dfg_devices[minor] = 0;
+}
+
+static struct pci_driver b3dfg_driver = {
+	.name = DRIVER_NAME,
+	.id_table = b3dfg_ids,
+	.probe = b3dfg_probe,
+	.remove = __devexit_p(b3dfg_remove),
+};
+
+static int __init b3dfg_module_init(void)
+{
+	int r;
+
+	if (b3dfg_nbuf < 2) {
+		printk(KERN_ERR DRIVER_NAME
+			   ": buffer_count is out of range (must be >= 2)");
+		return -EINVAL;
+	}
+
+	printk(KERN_INFO DRIVER_NAME ": loaded\n");
+
+	b3dfg_class = class_create(THIS_MODULE, DRIVER_NAME);
+	if (IS_ERR(b3dfg_class))
+		return PTR_ERR(b3dfg_class);
+
+	r = alloc_chrdev_region(&b3dfg_devt, 0, B3DFG_MAX_DEVS, DRIVER_NAME);
+	if (r)
+		goto err1;
+
+	r = pci_register_driver(&b3dfg_driver);
+	if (r)
+		goto err2;
+
+	return r;
+
+err2:
+	unregister_chrdev_region(b3dfg_devt, B3DFG_MAX_DEVS);
+err1:
+	class_destroy(b3dfg_class);
+	return r;
+}
+
+static void __exit b3dfg_module_exit(void)
+{
+	printk(KERN_INFO DRIVER_NAME ": unloaded\n");
+	pci_unregister_driver(&b3dfg_driver);
+	unregister_chrdev_region(b3dfg_devt, B3DFG_MAX_DEVS);
+	class_destroy(b3dfg_class);
+}
+
+module_init(b3dfg_module_init);
+module_exit(b3dfg_module_exit);
diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig
index b47ca1e..2d819d27 100644
--- a/drivers/staging/comedi/Kconfig
+++ b/drivers/staging/comedi/Kconfig
@@ -1,11 +1,18 @@
 config COMEDI
-	tristate "Data Acquision support (comedi)"
+	tristate "Data acquisition support (comedi)"
 	default N
 	depends on m
 	---help---
-	  Enable support a wide range of data acquision devices
+	  Enable support a wide range of data acquisition devices
 	  for Linux.
 
+config COMEDI_DEBUG
+	bool "Comedi debugging"
+	depends on COMEDI != n
+	help
+	  This is an option for use by developers; most people should
+	  say N here. This enables comedi core and driver debugging.
+
 config COMEDI_RT
 	tristate "Comedi Real-time support"
 	depends on COMEDI && RT
@@ -20,6 +27,13 @@
 	---help---
 	  Enable lots of comedi PCI drivers to be built
 
+config COMEDI_PCMCIA_DRIVERS
+	tristate "Comedi PCMCIA drivers"
+	depends on COMEDI && PCMCIAI
+	default N
+	---help---
+	  Enable lots of comedi PCMCIA drivers to be built
+
 config COMEDI_USB_DRIVERS
 	tristate "Comedi USB drivers"
 	depends on COMEDI && USB
diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h
index 36d2e1b..e6b5f16 100644
--- a/drivers/staging/comedi/comedi.h
+++ b/drivers/staging/comedi/comedi.h
@@ -57,9 +57,6 @@
 /* max length of device and driver names */
 #define COMEDI_NAMELEN 20
 
-	typedef unsigned int lsampl_t;
-	typedef unsigned short sampl_t;
-
 /* packs and unpacks a channel/range number */
 
 #define CR_PACK(chan, rng, aref)		((((aref)&0x3)<<24) | (((rng)&0xff)<<16) | (chan))
@@ -261,10 +258,11 @@
 	INSN_CONFIG_GET_CLOCK_SRC = 2004,	/* Get master clock source */
 	INSN_CONFIG_SET_OTHER_SRC = 2005,	/* Set other source */
 /*	INSN_CONFIG_GET_OTHER_SRC = 2006,*/	/* Get other source */
-	INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE,	/* Get size in bytes of
-						  subdevice's on-board fifos
-						  used during streaming
-						  input/output */
+	INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE = 2006,	/* Get size in bytes of
+							   subdevice's on-board
+							   fifos used during
+							   streaming
+							   input/output */
 	INSN_CONFIG_SET_COUNTER_MODE = 4097,
 	INSN_CONFIG_8254_SET_MODE = INSN_CONFIG_SET_COUNTER_MODE,	/* deprecated */
 	INSN_CONFIG_8254_READ_STATUS = 4098,
@@ -293,45 +291,32 @@
 /* ioctls */
 
 #define CIO 'd'
-#define COMEDI_DEVCONFIG _IOW(CIO, 0, comedi_devconfig)
-#define COMEDI_DEVINFO _IOR(CIO, 1, comedi_devinfo)
-#define COMEDI_SUBDINFO _IOR(CIO, 2, comedi_subdinfo)
-#define COMEDI_CHANINFO _IOR(CIO, 3, comedi_chaninfo)
+#define COMEDI_DEVCONFIG _IOW(CIO, 0, struct comedi_devconfig)
+#define COMEDI_DEVINFO _IOR(CIO, 1, struct comedi_devinfo)
+#define COMEDI_SUBDINFO _IOR(CIO, 2, struct comedi_subdinfo)
+#define COMEDI_CHANINFO _IOR(CIO, 3, struct comedi_chaninfo)
 #define COMEDI_TRIG _IOWR(CIO, 4, comedi_trig)
 #define COMEDI_LOCK _IO(CIO, 5)
 #define COMEDI_UNLOCK _IO(CIO, 6)
 #define COMEDI_CANCEL _IO(CIO, 7)
-#define COMEDI_RANGEINFO _IOR(CIO, 8, comedi_rangeinfo)
-#define COMEDI_CMD _IOR(CIO, 9, comedi_cmd)
-#define COMEDI_CMDTEST _IOR(CIO, 10, comedi_cmd)
-#define COMEDI_INSNLIST _IOR(CIO, 11, comedi_insnlist)
-#define COMEDI_INSN _IOR(CIO, 12, comedi_insn)
-#define COMEDI_BUFCONFIG _IOR(CIO, 13, comedi_bufconfig)
-#define COMEDI_BUFINFO _IOWR(CIO, 14, comedi_bufinfo)
+#define COMEDI_RANGEINFO _IOR(CIO, 8, struct comedi_rangeinfo)
+#define COMEDI_CMD _IOR(CIO, 9, struct comedi_cmd)
+#define COMEDI_CMDTEST _IOR(CIO, 10, struct comedi_cmd)
+#define COMEDI_INSNLIST _IOR(CIO, 11, struct comedi_insnlist)
+#define COMEDI_INSN _IOR(CIO, 12, struct comedi_insn)
+#define COMEDI_BUFCONFIG _IOR(CIO, 13, struct comedi_bufconfig)
+#define COMEDI_BUFINFO _IOWR(CIO, 14, struct comedi_bufinfo)
 #define COMEDI_POLL _IO(CIO, 15)
 
 /* structures */
 
-typedef struct comedi_trig_struct comedi_trig;
-typedef struct comedi_cmd_struct comedi_cmd;
-typedef struct comedi_insn_struct comedi_insn;
-typedef struct comedi_insnlist_struct comedi_insnlist;
-typedef struct comedi_chaninfo_struct comedi_chaninfo;
-typedef struct comedi_subdinfo_struct comedi_subdinfo;
-typedef struct comedi_devinfo_struct comedi_devinfo;
-typedef struct comedi_devconfig_struct comedi_devconfig;
-typedef struct comedi_rangeinfo_struct comedi_rangeinfo;
-typedef struct comedi_krange_struct comedi_krange;
-typedef struct comedi_bufconfig_struct comedi_bufconfig;
-typedef struct comedi_bufinfo_struct comedi_bufinfo;
-
-struct comedi_trig_struct {
+struct comedi_trig {
 	unsigned int subdev;	/* subdevice */
 	unsigned int mode;	/* mode */
 	unsigned int flags;
 	unsigned int n_chan;	/* number of channels */
 	unsigned int *chanlist;	/* channel/range list */
-	sampl_t *data;	/* data list, size depends on subd flags */
+	short *data;	/* data list, size depends on subd flags */
 	unsigned int n;	/* number of scans */
 	unsigned int trigsrc;
 	unsigned int trigvar;
@@ -340,21 +325,21 @@
 	unsigned int unused[3];
 };
 
-struct comedi_insn_struct {
+struct comedi_insn {
 	unsigned int insn;
 	unsigned int n;
-	lsampl_t *data;
+	unsigned int *data;
 	unsigned int subdev;
 	unsigned int chanspec;
 	unsigned int unused[3];
 };
 
-struct comedi_insnlist_struct {
+struct comedi_insnlist {
 	unsigned int n_insns;
-	comedi_insn *insns;
+	struct comedi_insn *insns;
 };
 
-struct comedi_cmd_struct {
+struct comedi_cmd {
 	unsigned int subdev;
 	unsigned int flags;
 
@@ -376,37 +361,37 @@
 	unsigned int *chanlist;	/* channel/range list */
 	unsigned int chanlist_len;
 
-	sampl_t *data;	/* data list, size depends on subd flags */
+	short *data;	/* data list, size depends on subd flags */
 	unsigned int data_len;
 };
 
-struct comedi_chaninfo_struct {
+struct comedi_chaninfo {
 	unsigned int subdev;
-	lsampl_t *maxdata_list;
+	unsigned int *maxdata_list;
 	unsigned int *flaglist;
 	unsigned int *rangelist;
 	unsigned int unused[4];
 };
 
-struct comedi_rangeinfo_struct {
+struct comedi_rangeinfo {
 	unsigned int range_type;
 	void *range_ptr;
 };
 
-struct comedi_krange_struct {
+struct comedi_krange {
 	int min;	/* fixed point, multiply by 1e-6 */
 	int max;	/* fixed point, multiply by 1e-6 */
 	unsigned int flags;
 };
 
 
-struct comedi_subdinfo_struct {
+struct comedi_subdinfo {
 	unsigned int type;
 	unsigned int n_chan;
 	unsigned int subd_flags;
 	unsigned int timer_type;
 	unsigned int len_chanlist;
-	lsampl_t maxdata;
+	unsigned int maxdata;
 	unsigned int flags;	/* channel flags */
 	unsigned int range_type;	/* lookup in kernel */
 	unsigned int settling_time_0;
@@ -414,7 +399,7 @@
 	unsigned int unused[8];
 };
 
-struct comedi_devinfo_struct {
+struct comedi_devinfo {
 	unsigned int version_code;
 	unsigned int n_subdevs;
 	char driver_name[COMEDI_NAMELEN];
@@ -424,12 +409,12 @@
 	int unused[30];
 };
 
-struct comedi_devconfig_struct {
+struct comedi_devconfig {
 	char board_name[COMEDI_NAMELEN];
 	int options[COMEDI_NDEVCONFOPTS];
 };
 
-struct comedi_bufconfig_struct {
+struct comedi_bufconfig {
 	unsigned int subdevice;
 	unsigned int flags;
 
@@ -439,7 +424,7 @@
 	unsigned int unused[4];
 };
 
-struct comedi_bufinfo_struct {
+struct comedi_bufinfo {
 	unsigned int subdevice;
 	unsigned int bytes_read;
 
diff --git a/drivers/staging/comedi/comedi_compat32.c b/drivers/staging/comedi/comedi_compat32.c
index 7d0116b..1b9c2a7 100644
--- a/drivers/staging/comedi/comedi_compat32.c
+++ b/drivers/staging/comedi/comedi_compat32.c
@@ -37,31 +37,31 @@
 #include <linux/ioctl32.h>	/* for (un)register_ioctl32_conversion */
 #endif
 
-#define COMEDI32_CHANINFO _IOR(CIO,3,comedi32_chaninfo)
-#define COMEDI32_RANGEINFO _IOR(CIO,8,comedi32_rangeinfo)
+#define COMEDI32_CHANINFO _IOR(CIO, 3, struct comedi32_chaninfo_struct)
+#define COMEDI32_RANGEINFO _IOR(CIO, 8, struct comedi32_rangeinfo_struct)
 /* N.B. COMEDI32_CMD and COMEDI_CMD ought to use _IOWR, not _IOR.
  * It's too late to change it now, but it only affects the command number. */
-#define COMEDI32_CMD _IOR(CIO,9,comedi32_cmd)
+#define COMEDI32_CMD _IOR(CIO, 9, struct comedi32_cmd_struct)
 /* N.B. COMEDI32_CMDTEST and COMEDI_CMDTEST ought to use _IOWR, not _IOR.
  * It's too late to change it now, but it only affects the command number. */
-#define COMEDI32_CMDTEST _IOR(CIO,10,comedi32_cmd)
-#define COMEDI32_INSNLIST _IOR(CIO,11,comedi32_insnlist)
-#define COMEDI32_INSN _IOR(CIO,12,comedi32_insn)
+#define COMEDI32_CMDTEST _IOR(CIO, 10, struct comedi32_cmd_struct)
+#define COMEDI32_INSNLIST _IOR(CIO, 11, struct comedi32_insnlist_struct)
+#define COMEDI32_INSN _IOR(CIO, 12, struct comedi32_insn_struct)
 
-typedef struct comedi32_chaninfo_struct {
+struct comedi32_chaninfo_struct {
 	unsigned int subdev;
-	compat_uptr_t maxdata_list;	/* 32-bit 'lsampl_t *' */
+	compat_uptr_t maxdata_list;	/* 32-bit 'unsigned int *' */
 	compat_uptr_t flaglist;		/* 32-bit 'unsigned int *' */
 	compat_uptr_t rangelist;	/* 32-bit 'unsigned int *' */
 	unsigned int unused[4];
-} comedi32_chaninfo;
+};
 
-typedef struct comedi32_rangeinfo_struct {
+struct comedi32_rangeinfo_struct {
 	unsigned int range_type;
 	compat_uptr_t range_ptr;	/* 32-bit 'void *' */
-} comedi32_rangeinfo;
+};
 
-typedef struct comedi32_cmd_struct {
+struct comedi32_cmd_struct {
 	unsigned int subdev;
 	unsigned int flags;
 	unsigned int start_src;
@@ -76,37 +76,36 @@
 	unsigned int stop_arg;
 	compat_uptr_t chanlist;		/* 32-bit 'unsigned int *' */
 	unsigned int chanlist_len;
-	compat_uptr_t data;		/* 32-bit 'sampl_t *' */
+	compat_uptr_t data;		/* 32-bit 'short *' */
 	unsigned int data_len;
-} comedi32_cmd;
+};
 
-typedef struct comedi32_insn_struct {
+struct comedi32_insn_struct {
 	unsigned int insn;
 	unsigned int n;
-	compat_uptr_t data;		/* 32-bit 'lsampl_t *' */
+	compat_uptr_t data;		/* 32-bit 'unsigned int *' */
 	unsigned int subdev;
 	unsigned int chanspec;
 	unsigned int unused[3];
-} comedi32_insn;
+};
 
-typedef struct comedi32_insnlist_struct {
+struct comedi32_insnlist_struct {
 	unsigned int n_insns;
-	compat_uptr_t insns;		/* 32-bit 'comedi_insn *' */
-} comedi32_insnlist;
+	compat_uptr_t insns;		/* 32-bit 'struct comedi_insn *' */
+};
 
 /* Handle translated ioctl. */
 static int translated_ioctl(struct file *file, unsigned int cmd,
 		unsigned long arg)
 {
-	if (!file->f_op) {
+	if (!file->f_op)
 		return -ENOTTY;
-	}
+
 #ifdef HAVE_UNLOCKED_IOCTL
 	if (file->f_op->unlocked_ioctl) {
 		int rc = (int)(*file->f_op->unlocked_ioctl)(file, cmd, arg);
-		if (rc == -ENOIOCTLCMD) {
+		if (rc == -ENOIOCTLCMD)
 			rc = -ENOTTY;
-		}
 		return rc;
 	}
 #endif
@@ -124,8 +123,8 @@
 /* Handle 32-bit COMEDI_CHANINFO ioctl. */
 static int compat_chaninfo(struct file *file, unsigned long arg)
 {
-	comedi_chaninfo __user *chaninfo;
-	comedi32_chaninfo __user *chaninfo32;
+	struct comedi_chaninfo __user *chaninfo;
+	struct comedi32_chaninfo_struct __user *chaninfo32;
 	int err;
 	union {
 		unsigned int uint;
@@ -150,9 +149,8 @@
 	err |= __put_user(compat_ptr(temp.uptr), &chaninfo->flaglist);
 	err |= __get_user(temp.uptr, &chaninfo32->rangelist);
 	err |= __put_user(compat_ptr(temp.uptr), &chaninfo->rangelist);
-	if (err) {
+	if (err)
 		return -EFAULT;
-	}
 
 	return translated_ioctl(file, COMEDI_CHANINFO, (unsigned long)chaninfo);
 }
@@ -160,8 +158,8 @@
 /* Handle 32-bit COMEDI_RANGEINFO ioctl. */
 static int compat_rangeinfo(struct file *file, unsigned long arg)
 {
-	comedi_rangeinfo __user *rangeinfo;
-	comedi32_rangeinfo __user *rangeinfo32;
+	struct comedi_rangeinfo __user *rangeinfo;
+	struct comedi32_rangeinfo_struct __user *rangeinfo32;
 	int err;
 	union {
 		unsigned int uint;
@@ -182,17 +180,16 @@
 	err |= __put_user(temp.uint, &rangeinfo->range_type);
 	err |= __get_user(temp.uptr, &rangeinfo32->range_ptr);
 	err |= __put_user(compat_ptr(temp.uptr), &rangeinfo->range_ptr);
-	if (err) {
+	if (err)
 		return -EFAULT;
-	}
 
 	return translated_ioctl(file, COMEDI_RANGEINFO,
 			(unsigned long)rangeinfo);
 }
 
 /* Copy 32-bit cmd structure to native cmd structure. */
-static int get_compat_cmd(comedi_cmd __user *cmd,
-		comedi32_cmd __user *cmd32)
+static int get_compat_cmd(struct comedi_cmd __user *cmd,
+		struct comedi32_cmd_struct __user *cmd32)
 {
 	int err;
 	union {
@@ -242,7 +239,7 @@
 }
 
 /* Copy native cmd structure to 32-bit cmd structure. */
-static int put_compat_cmd(comedi32_cmd __user *cmd32, comedi_cmd __user *cmd)
+static int put_compat_cmd(struct comedi32_cmd_struct __user *cmd32, struct comedi_cmd __user *cmd)
 {
 	int err;
 	unsigned int temp;
@@ -292,17 +289,16 @@
 /* Handle 32-bit COMEDI_CMD ioctl. */
 static int compat_cmd(struct file *file, unsigned long arg)
 {
-	comedi_cmd __user *cmd;
-	comedi32_cmd __user *cmd32;
+	struct comedi_cmd __user *cmd;
+	struct comedi32_cmd_struct __user *cmd32;
 	int rc;
 
 	cmd32 = compat_ptr(arg);
 	cmd = compat_alloc_user_space(sizeof(*cmd));
 
 	rc = get_compat_cmd(cmd, cmd32);
-	if (rc) {
+	if (rc)
 		return rc;
-	}
 
 	return translated_ioctl(file, COMEDI_CMD, (unsigned long)cmd);
 }
@@ -310,33 +306,31 @@
 /* Handle 32-bit COMEDI_CMDTEST ioctl. */
 static int compat_cmdtest(struct file *file, unsigned long arg)
 {
-	comedi_cmd __user *cmd;
-	comedi32_cmd __user *cmd32;
+	struct comedi_cmd __user *cmd;
+	struct comedi32_cmd_struct __user *cmd32;
 	int rc, err;
 
 	cmd32 = compat_ptr(arg);
 	cmd = compat_alloc_user_space(sizeof(*cmd));
 
 	rc = get_compat_cmd(cmd, cmd32);
-	if (rc) {
+	if (rc)
 		return rc;
-	}
 
 	rc = translated_ioctl(file, COMEDI_CMDTEST, (unsigned long)cmd);
-	if (rc < 0) {
+	if (rc < 0)
 		return rc;
-	}
 
 	err = put_compat_cmd(cmd32, cmd);
-	if (err) {
+	if (err)
 		rc = err;
-	}
+
 	return rc;
 }
 
 /* Copy 32-bit insn structure to native insn structure. */
-static int get_compat_insn(comedi_insn __user *insn,
-		comedi32_insn __user *insn32)
+static int get_compat_insn(struct comedi_insn __user *insn,
+		struct comedi32_insn_struct __user *insn32)
 {
 	int err;
 	union {
@@ -347,9 +341,9 @@
 	/* Copy insn structure.  Ignore the unused members. */
 	err = 0;
 	if (!access_ok(VERIFY_READ, insn32, sizeof(*insn32))
-			|| !access_ok(VERIFY_WRITE, insn, sizeof(*insn))) {
+			|| !access_ok(VERIFY_WRITE, insn, sizeof(*insn)))
 		return -EFAULT;
-	}
+
 	err |= __get_user(temp.uint, &insn32->insn);
 	err |= __put_user(temp.uint, &insn->insn);
 	err |= __get_user(temp.uint, &insn32->n);
@@ -367,11 +361,11 @@
 static int compat_insnlist(struct file *file, unsigned long arg)
 {
 	struct combined_insnlist {
-		comedi_insnlist insnlist;
-		comedi_insn insn[1];
+		struct comedi_insnlist insnlist;
+		struct comedi_insn insn[1];
 	} __user *s;
-	comedi32_insnlist __user *insnlist32;
-	comedi32_insn __user *insn32;
+	struct comedi32_insnlist_struct __user *insnlist32;
+	struct comedi32_insn_struct __user *insn32;
 	compat_uptr_t uptr;
 	unsigned int n_insns, n;
 	int err, rc;
@@ -386,9 +380,8 @@
 	err |= __get_user(n_insns, &insnlist32->n_insns);
 	err |= __get_user(uptr, &insnlist32->insns);
 	insn32 = compat_ptr(uptr);
-	if (err) {
+	if (err)
 		return -EFAULT;
-	}
 
 	/* Allocate user memory to copy insnlist and insns into. */
 	s = compat_alloc_user_space(offsetof(struct combined_insnlist,
@@ -400,16 +393,14 @@
 	}
 	err |= __put_user(n_insns, &s->insnlist.n_insns);
 	err |= __put_user(&s->insn[0], &s->insnlist.insns);
-	if (err) {
+	if (err)
 		return -EFAULT;
-	}
 
 	/* Copy insn structures. */
 	for (n = 0; n < n_insns; n++) {
 		rc = get_compat_insn(&s->insn[n], &insn32[n]);
-		if (rc) {
+		if (rc)
 			return rc;
-		}
 	}
 
 	return translated_ioctl(file, COMEDI_INSNLIST,
@@ -419,17 +410,16 @@
 /* Handle 32-bit COMEDI_INSN ioctl. */
 static int compat_insn(struct file *file, unsigned long arg)
 {
-	comedi_insn __user *insn;
-	comedi32_insn __user *insn32;
+	struct comedi_insn __user *insn;
+	struct comedi32_insn_struct __user *insn32;
 	int rc;
 
 	insn32 = compat_ptr(arg);
 	insn = compat_alloc_user_space(sizeof(*insn));
 
 	rc = get_compat_insn(insn, insn32);
-	if (rc) {
+	if (rc)
 		return rc;
-	}
 
 	return translated_ioctl(file, COMEDI_INSN, (unsigned long)insn);
 }
@@ -512,14 +502,14 @@
 	int rc;
 
 	/* Make sure we are dealing with a Comedi device. */
-	if (imajor(file->f_dentry->d_inode) != COMEDI_MAJOR) {
+	if (imajor(file->f_dentry->d_inode) != COMEDI_MAJOR)
 		return -ENOTTY;
-	}
+
 	rc = raw_ioctl(file, cmd, arg);
 	/* Do not return -ENOIOCTLCMD. */
-	if (rc == -ENOIOCTLCMD) {
+	if (rc == -ENOIOCTLCMD)
 		rc = -ENOTTY;
-	}
+
 	return rc;
 }
 
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index 018c964..19dce2e 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -59,33 +59,39 @@
 module_param(comedi_debug, int, 0644);
 #endif
 
+int comedi_autoconfig = 1;
+module_param(comedi_autoconfig, bool, 0444);
+
+int comedi_num_legacy_minors = 0;
+module_param(comedi_num_legacy_minors, int, 0444);
+
 static DEFINE_SPINLOCK(comedi_file_info_table_lock);
 static struct comedi_device_file_info
     *comedi_file_info_table[COMEDI_NUM_MINORS];
 
-static int do_devconfig_ioctl(comedi_device *dev, comedi_devconfig *arg);
-static int do_bufconfig_ioctl(comedi_device *dev, void *arg);
-static int do_devinfo_ioctl(comedi_device *dev, comedi_devinfo *arg,
+static int do_devconfig_ioctl(struct comedi_device *dev, struct comedi_devconfig *arg);
+static int do_bufconfig_ioctl(struct comedi_device *dev, void *arg);
+static int do_devinfo_ioctl(struct comedi_device *dev, struct comedi_devinfo *arg,
 			    struct file *file);
-static int do_subdinfo_ioctl(comedi_device *dev, comedi_subdinfo *arg,
+static int do_subdinfo_ioctl(struct comedi_device *dev, struct comedi_subdinfo *arg,
 			     void *file);
-static int do_chaninfo_ioctl(comedi_device *dev, comedi_chaninfo *arg);
-static int do_bufinfo_ioctl(comedi_device *dev, void *arg);
-static int do_cmd_ioctl(comedi_device *dev, void *arg, void *file);
-static int do_lock_ioctl(comedi_device *dev, unsigned int arg, void *file);
-static int do_unlock_ioctl(comedi_device *dev, unsigned int arg, void *file);
-static int do_cancel_ioctl(comedi_device *dev, unsigned int arg, void *file);
-static int do_cmdtest_ioctl(comedi_device *dev, void *arg, void *file);
-static int do_insnlist_ioctl(comedi_device *dev, void *arg, void *file);
-static int do_insn_ioctl(comedi_device *dev, void *arg, void *file);
-static int do_poll_ioctl(comedi_device *dev, unsigned int subd, void *file);
+static int do_chaninfo_ioctl(struct comedi_device *dev, struct comedi_chaninfo *arg);
+static int do_bufinfo_ioctl(struct comedi_device *dev, void *arg);
+static int do_cmd_ioctl(struct comedi_device *dev, void *arg, void *file);
+static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg, void *file);
+static int do_unlock_ioctl(struct comedi_device *dev, unsigned int arg, void *file);
+static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, void *file);
+static int do_cmdtest_ioctl(struct comedi_device *dev, void *arg, void *file);
+static int do_insnlist_ioctl(struct comedi_device *dev, void *arg, void *file);
+static int do_insn_ioctl(struct comedi_device *dev, void *arg, void *file);
+static int do_poll_ioctl(struct comedi_device *dev, unsigned int subd, void *file);
 
-extern void do_become_nonbusy(comedi_device *dev, comedi_subdevice *s);
-static int do_cancel(comedi_device *dev, comedi_subdevice *s);
+extern void do_become_nonbusy(struct comedi_device *dev, struct comedi_subdevice *s);
+static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
 
 static int comedi_fasync(int fd, struct file *file, int on);
 
-static int is_device_busy(comedi_device *dev);
+static int is_device_busy(struct comedi_device *dev);
 
 #ifdef HAVE_UNLOCKED_IOCTL
 static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
@@ -98,9 +104,13 @@
 	const unsigned minor = iminor(file->f_dentry->d_inode);
 	struct comedi_device_file_info *dev_file_info =
 	    comedi_get_device_file_info(minor);
-	comedi_device *dev = dev_file_info->device;
+	struct comedi_device *dev;
 	int rc;
 
+	if (dev_file_info == NULL || dev_file_info->device == NULL)
+		return -ENODEV;
+	dev = dev_file_info->device;
+
 	mutex_lock(&dev->mutex);
 
 	/* Device config is special, because it must work on
@@ -182,9 +192,9 @@
 	writes:
 		none
 */
-static int do_devconfig_ioctl(comedi_device *dev, comedi_devconfig *arg)
+static int do_devconfig_ioctl(struct comedi_device *dev, struct comedi_devconfig *arg)
 {
-	comedi_devconfig it;
+	struct comedi_devconfig it;
 	int ret;
 	unsigned char *aux_data = NULL;
 	int aux_len;
@@ -203,7 +213,7 @@
 		return 0;
 	}
 
-	if (copy_from_user(&it, arg, sizeof(comedi_devconfig)))
+	if (copy_from_user(&it, arg, sizeof(struct comedi_devconfig)))
 		return -EFAULT;
 
 	it.board_name[COMEDI_NAMELEN - 1] = 0;
@@ -262,14 +272,14 @@
 		modified bufconfig at arg
 
 */
-static int do_bufconfig_ioctl(comedi_device *dev, void *arg)
+static int do_bufconfig_ioctl(struct comedi_device *dev, void *arg)
 {
-	comedi_bufconfig bc;
-	comedi_async *async;
-	comedi_subdevice *s;
+	struct comedi_bufconfig bc;
+	struct comedi_async *async;
+	struct comedi_subdevice *s;
 	int ret = 0;
 
-	if (copy_from_user(&bc, arg, sizeof(comedi_bufconfig)))
+	if (copy_from_user(&bc, arg, sizeof(struct comedi_bufconfig)))
 		return -EFAULT;
 
 	if (bc.subdevice >= dev->n_subdevices || bc.subdevice < 0)
@@ -330,7 +340,7 @@
 	bc.maximum_size = async->max_bufsize;
 
 copyback:
-	if (copy_to_user(arg, &bc, sizeof(comedi_bufconfig)))
+	if (copy_to_user(arg, &bc, sizeof(struct comedi_bufconfig)))
 		return -EFAULT;
 
 	return 0;
@@ -350,16 +360,16 @@
 		devinfo structure
 
 */
-static int do_devinfo_ioctl(comedi_device *dev, comedi_devinfo *arg,
+static int do_devinfo_ioctl(struct comedi_device *dev, struct comedi_devinfo *arg,
 			    struct file *file)
 {
-	comedi_devinfo devinfo;
+	struct comedi_devinfo devinfo;
 	const unsigned minor = iminor(file->f_dentry->d_inode);
 	struct comedi_device_file_info *dev_file_info =
 	    comedi_get_device_file_info(minor);
-	comedi_subdevice *read_subdev =
+	struct comedi_subdevice *read_subdev =
 	    comedi_get_read_subdevice(dev_file_info);
-	comedi_subdevice *write_subdev =
+	struct comedi_subdevice *write_subdev =
 	    comedi_get_write_subdevice(dev_file_info);
 
 	memset(&devinfo, 0, sizeof(devinfo));
@@ -380,7 +390,7 @@
 	else
 		devinfo.write_subdevice = -1;
 
-	if (copy_to_user(arg, &devinfo, sizeof(comedi_devinfo)))
+	if (copy_to_user(arg, &devinfo, sizeof(struct comedi_devinfo)))
 		return -EFAULT;
 
 	return 0;
@@ -400,14 +410,14 @@
 		array of subdevice info structures at arg
 
 */
-static int do_subdinfo_ioctl(comedi_device *dev, comedi_subdinfo *arg,
+static int do_subdinfo_ioctl(struct comedi_device *dev, struct comedi_subdinfo *arg,
 			     void *file)
 {
 	int ret, i;
-	comedi_subdinfo *tmp, *us;
-	comedi_subdevice *s;
+	struct comedi_subdinfo *tmp, *us;
+	struct comedi_subdevice *s;
 
-	tmp = kcalloc(dev->n_subdevices, sizeof(comedi_subdinfo), GFP_KERNEL);
+	tmp = kcalloc(dev->n_subdevices, sizeof(struct comedi_subdinfo), GFP_KERNEL);
 	if (!tmp)
 		return -ENOMEM;
 
@@ -459,7 +469,7 @@
 	}
 
 	ret = copy_to_user(arg, tmp,
-			   dev->n_subdevices * sizeof(comedi_subdinfo));
+			   dev->n_subdevices * sizeof(struct comedi_subdinfo));
 
 	kfree(tmp);
 
@@ -480,12 +490,12 @@
 		arrays at elements of chaninfo structure
 
 */
-static int do_chaninfo_ioctl(comedi_device *dev, comedi_chaninfo *arg)
+static int do_chaninfo_ioctl(struct comedi_device *dev, struct comedi_chaninfo *arg)
 {
-	comedi_subdevice *s;
-	comedi_chaninfo it;
+	struct comedi_subdevice *s;
+	struct comedi_chaninfo it;
 
-	if (copy_from_user(&it, arg, sizeof(comedi_chaninfo)))
+	if (copy_from_user(&it, arg, sizeof(struct comedi_chaninfo)))
 		return -EFAULT;
 
 	if (it.subdev >= dev->n_subdevices)
@@ -496,7 +506,7 @@
 		if (s->maxdata || !s->maxdata_list)
 			return -EINVAL;
 		if (copy_to_user(it.maxdata_list, s->maxdata_list,
-				 s->n_chan * sizeof(lsampl_t)))
+				 s->n_chan * sizeof(unsigned int)))
 			return -EFAULT;
 	}
 
@@ -544,13 +554,13 @@
     modified bufinfo at arg
 
   */
-static int do_bufinfo_ioctl(comedi_device *dev, void *arg)
+static int do_bufinfo_ioctl(struct comedi_device *dev, void *arg)
 {
-	comedi_bufinfo bi;
-	comedi_subdevice *s;
-	comedi_async *async;
+	struct comedi_bufinfo bi;
+	struct comedi_subdevice *s;
+	struct comedi_async *async;
 
-	if (copy_from_user(&bi, arg, sizeof(comedi_bufinfo)))
+	if (copy_from_user(&bi, arg, sizeof(struct comedi_bufinfo)))
 		return -EFAULT;
 
 	if (bi.subdevice >= dev->n_subdevices || bi.subdevice < 0)
@@ -591,13 +601,13 @@
 	bi.buf_read_ptr = async->buf_read_ptr;
 
 copyback:
-	if (copy_to_user(arg, &bi, sizeof(comedi_bufinfo)))
+	if (copy_to_user(arg, &bi, sizeof(struct comedi_bufinfo)))
 		return -EFAULT;
 
 	return 0;
 }
 
-static int parse_insn(comedi_device *dev, comedi_insn *insn, lsampl_t *data,
+static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data,
 		      void *file);
 /*
  * 	COMEDI_INSNLIST
@@ -616,25 +626,25 @@
  */
 /* arbitrary limits */
 #define MAX_SAMPLES 256
-static int do_insnlist_ioctl(comedi_device *dev, void *arg, void *file)
+static int do_insnlist_ioctl(struct comedi_device *dev, void *arg, void *file)
 {
-	comedi_insnlist insnlist;
-	comedi_insn *insns = NULL;
-	lsampl_t *data = NULL;
+	struct comedi_insnlist insnlist;
+	struct comedi_insn *insns = NULL;
+	unsigned int *data = NULL;
 	int i = 0;
 	int ret = 0;
 
-	if (copy_from_user(&insnlist, arg, sizeof(comedi_insnlist)))
+	if (copy_from_user(&insnlist, arg, sizeof(struct comedi_insnlist)))
 		return -EFAULT;
 
-	data = kmalloc(sizeof(lsampl_t) * MAX_SAMPLES, GFP_KERNEL);
+	data = kmalloc(sizeof(unsigned int) * MAX_SAMPLES, GFP_KERNEL);
 	if (!data) {
 		DPRINTK("kmalloc failed\n");
 		ret = -ENOMEM;
 		goto error;
 	}
 
-	insns = kmalloc(sizeof(comedi_insn) * insnlist.n_insns, GFP_KERNEL);
+	insns = kmalloc(sizeof(struct comedi_insn) * insnlist.n_insns, GFP_KERNEL);
 	if (!insns) {
 		DPRINTK("kmalloc failed\n");
 		ret = -ENOMEM;
@@ -642,7 +652,7 @@
 	}
 
 	if (copy_from_user(insns, insnlist.insns,
-			   sizeof(comedi_insn) * insnlist.n_insns)) {
+			   sizeof(struct comedi_insn) * insnlist.n_insns)) {
 		DPRINTK("copy_from_user failed\n");
 		ret = -EFAULT;
 		goto error;
@@ -656,7 +666,7 @@
 		}
 		if (insns[i].insn & INSN_MASK_WRITE) {
 			if (copy_from_user(data, insns[i].data,
-					   insns[i].n * sizeof(lsampl_t))) {
+					   insns[i].n * sizeof(unsigned int))) {
 				DPRINTK("copy_from_user failed\n");
 				ret = -EFAULT;
 				goto error;
@@ -667,7 +677,7 @@
 			goto error;
 		if (insns[i].insn & INSN_MASK_READ) {
 			if (copy_to_user(insns[i].data, data,
-					 insns[i].n * sizeof(lsampl_t))) {
+					 insns[i].n * sizeof(unsigned int))) {
 				DPRINTK("copy_to_user failed\n");
 				ret = -EFAULT;
 				goto error;
@@ -686,7 +696,7 @@
 	return i;
 }
 
-static int check_insn_config_length(comedi_insn *insn, lsampl_t *data)
+static int check_insn_config_length(struct comedi_insn *insn, unsigned int *data)
 {
 	if (insn->n < 1)
 		return -EINVAL;
@@ -747,10 +757,10 @@
 	return -EINVAL;
 }
 
-static int parse_insn(comedi_device *dev, comedi_insn *insn, lsampl_t *data,
+static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data,
 		      void *file)
 {
-	comedi_subdevice *s;
+	struct comedi_subdevice *s;
 	int ret = 0;
 	int i;
 
@@ -815,7 +825,7 @@
 		}
 	} else {
 		/* a subdevice instruction */
-		lsampl_t maxdata;
+		unsigned int maxdata;
 
 		if (insn->subdev >= dev->n_subdevices) {
 			DPRINTK("subdevice %d out of range\n", insn->subdev);
@@ -901,25 +911,25 @@
  * 		pointer to insn
  *
  * 	reads:
- * 		comedi_insn struct at arg
+ * 		struct comedi_insn struct at arg
  * 		data (for writes)
  *
  * 	writes:
  * 		data (for reads)
  */
-static int do_insn_ioctl(comedi_device *dev, void *arg, void *file)
+static int do_insn_ioctl(struct comedi_device *dev, void *arg, void *file)
 {
-	comedi_insn insn;
-	lsampl_t *data = NULL;
+	struct comedi_insn insn;
+	unsigned int *data = NULL;
 	int ret = 0;
 
-	data = kmalloc(sizeof(lsampl_t) * MAX_SAMPLES, GFP_KERNEL);
+	data = kmalloc(sizeof(unsigned int) * MAX_SAMPLES, GFP_KERNEL);
 	if (!data) {
 		ret = -ENOMEM;
 		goto error;
 	}
 
-	if (copy_from_user(&insn, arg, sizeof(comedi_insn))) {
+	if (copy_from_user(&insn, arg, sizeof(struct comedi_insn))) {
 		ret = -EFAULT;
 		goto error;
 	}
@@ -928,7 +938,7 @@
 	if (insn.n > MAX_SAMPLES)
 		insn.n = MAX_SAMPLES;
 	if (insn.insn & INSN_MASK_WRITE) {
-		if (copy_from_user(data, insn.data, insn.n * sizeof(lsampl_t))) {
+		if (copy_from_user(data, insn.data, insn.n * sizeof(unsigned int))) {
 			ret = -EFAULT;
 			goto error;
 		}
@@ -937,7 +947,7 @@
 	if (ret < 0)
 		goto error;
 	if (insn.insn & INSN_MASK_READ) {
-		if (copy_to_user(insn.data, data, insn.n * sizeof(lsampl_t))) {
+		if (copy_to_user(insn.data, data, insn.n * sizeof(unsigned int))) {
 			ret = -EFAULT;
 			goto error;
 		}
@@ -965,15 +975,15 @@
 		modified cmd structure at arg
 
 */
-static int do_cmd_ioctl(comedi_device *dev, void *arg, void *file)
+static int do_cmd_ioctl(struct comedi_device *dev, void *arg, void *file)
 {
-	comedi_cmd user_cmd;
-	comedi_subdevice *s;
-	comedi_async *async;
+	struct comedi_cmd user_cmd;
+	struct comedi_subdevice *s;
+	struct comedi_async *async;
 	int ret = 0;
 	unsigned int *chanlist_saver = NULL;
 
-	if (copy_from_user(&user_cmd, arg, sizeof(comedi_cmd))) {
+	if (copy_from_user(&user_cmd, arg, sizeof(struct comedi_cmd))) {
 		DPRINTK("bad cmd address\n");
 		return -EFAULT;
 	}
@@ -1062,7 +1072,7 @@
 		/* restore chanlist pointer before copying back */
 		user_cmd.chanlist = chanlist_saver;
 		user_cmd.data = NULL;
-		if (copy_to_user(arg, &user_cmd, sizeof(comedi_cmd))) {
+		if (copy_to_user(arg, &user_cmd, sizeof(struct comedi_cmd))) {
 			DPRINTK("fault writing cmd\n");
 			ret = -EFAULT;
 			goto cleanup;
@@ -1119,15 +1129,15 @@
 		modified cmd structure at arg
 
 */
-static int do_cmdtest_ioctl(comedi_device *dev, void *arg, void *file)
+static int do_cmdtest_ioctl(struct comedi_device *dev, void *arg, void *file)
 {
-	comedi_cmd user_cmd;
-	comedi_subdevice *s;
+	struct comedi_cmd user_cmd;
+	struct comedi_subdevice *s;
 	int ret = 0;
 	unsigned int *chanlist = NULL;
 	unsigned int *chanlist_saver = NULL;
 
-	if (copy_from_user(&user_cmd, arg, sizeof(comedi_cmd))) {
+	if (copy_from_user(&user_cmd, arg, sizeof(struct comedi_cmd))) {
 		DPRINTK("bad cmd address\n");
 		return -EFAULT;
 	}
@@ -1191,7 +1201,7 @@
 	/* restore chanlist pointer before copying back */
 	user_cmd.chanlist = chanlist_saver;
 
-	if (copy_to_user(arg, &user_cmd, sizeof(comedi_cmd))) {
+	if (copy_to_user(arg, &user_cmd, sizeof(struct comedi_cmd))) {
 		DPRINTK("bad cmd address\n");
 		ret = -EFAULT;
 		goto cleanup;
@@ -1217,11 +1227,11 @@
 
 */
 
-static int do_lock_ioctl(comedi_device *dev, unsigned int arg, void *file)
+static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg, void *file)
 {
 	int ret = 0;
 	unsigned long flags;
-	comedi_subdevice *s;
+	struct comedi_subdevice *s;
 
 	if (arg >= dev->n_subdevices)
 		return -EINVAL;
@@ -1261,9 +1271,9 @@
 	This function isn't protected by the semaphore, since
 	we already own the lock.
 */
-static int do_unlock_ioctl(comedi_device *dev, unsigned int arg, void *file)
+static int do_unlock_ioctl(struct comedi_device *dev, unsigned int arg, void *file)
 {
-	comedi_subdevice *s;
+	struct comedi_subdevice *s;
 
 	if (arg >= dev->n_subdevices)
 		return -EINVAL;
@@ -1301,9 +1311,9 @@
 		nothing
 
 */
-static int do_cancel_ioctl(comedi_device *dev, unsigned int arg, void *file)
+static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, void *file)
 {
-	comedi_subdevice *s;
+	struct comedi_subdevice *s;
 
 	if (arg >= dev->n_subdevices)
 		return -EINVAL;
@@ -1337,9 +1347,9 @@
 		nothing
 
 */
-static int do_poll_ioctl(comedi_device *dev, unsigned int arg, void *file)
+static int do_poll_ioctl(struct comedi_device *dev, unsigned int arg, void *file)
 {
-	comedi_subdevice *s;
+	struct comedi_subdevice *s;
 
 	if (arg >= dev->n_subdevices)
 		return -EINVAL;
@@ -1360,7 +1370,7 @@
 	return -EINVAL;
 }
 
-static int do_cancel(comedi_device *dev, comedi_subdevice *s)
+static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	int ret = 0;
 
@@ -1374,8 +1384,8 @@
 
 void comedi_unmap(struct vm_area_struct *area)
 {
-	comedi_async *async;
-	comedi_device *dev;
+	struct comedi_async *async;
+	struct comedi_device *dev;
 
 	async = area->vm_private_data;
 	dev = async->subdevice->device;
@@ -1394,14 +1404,14 @@
 	const unsigned minor = iminor(file->f_dentry->d_inode);
 	struct comedi_device_file_info *dev_file_info =
 	    comedi_get_device_file_info(minor);
-	comedi_device *dev = dev_file_info->device;
-	comedi_async *async = NULL;
+	struct comedi_device *dev = dev_file_info->device;
+	struct comedi_async *async = NULL;
 	unsigned long start = vma->vm_start;
 	unsigned long size;
 	int n_pages;
 	int i;
 	int retval;
-	comedi_subdevice *s;
+	struct comedi_subdevice *s;
 
 	mutex_lock(&dev->mutex);
 	if (!dev->attached) {
@@ -1470,9 +1480,9 @@
 	const unsigned minor = iminor(file->f_dentry->d_inode);
 	struct comedi_device_file_info *dev_file_info =
 	    comedi_get_device_file_info(minor);
-	comedi_device *dev = dev_file_info->device;
-	comedi_subdevice *read_subdev;
-	comedi_subdevice *write_subdev;
+	struct comedi_device *dev = dev_file_info->device;
+	struct comedi_subdevice *read_subdev;
+	struct comedi_subdevice *write_subdev;
 
 	mutex_lock(&dev->mutex);
 	if (!dev->attached) {
@@ -1513,14 +1523,14 @@
 static ssize_t comedi_write(struct file *file, const char *buf, size_t nbytes,
 			    loff_t *offset)
 {
-	comedi_subdevice *s;
-	comedi_async *async;
+	struct comedi_subdevice *s;
+	struct comedi_async *async;
 	int n, m, count = 0, retval = 0;
 	DECLARE_WAITQUEUE(wait, current);
 	const unsigned minor = iminor(file->f_dentry->d_inode);
 	struct comedi_device_file_info *dev_file_info =
 	    comedi_get_device_file_info(minor);
-	comedi_device *dev = dev_file_info->device;
+	struct comedi_device *dev = dev_file_info->device;
 
 	if (!dev->attached) {
 		DPRINTK("no driver configured on comedi%i\n", dev->minor);
@@ -1615,14 +1625,14 @@
 static ssize_t comedi_read(struct file *file, char *buf, size_t nbytes,
 			   loff_t *offset)
 {
-	comedi_subdevice *s;
-	comedi_async *async;
+	struct comedi_subdevice *s;
+	struct comedi_async *async;
 	int n, m, count = 0, retval = 0;
 	DECLARE_WAITQUEUE(wait, current);
 	const unsigned minor = iminor(file->f_dentry->d_inode);
 	struct comedi_device_file_info *dev_file_info =
 	    comedi_get_device_file_info(minor);
-	comedi_device *dev = dev_file_info->device;
+	struct comedi_device *dev = dev_file_info->device;
 
 	if (!dev->attached) {
 		DPRINTK("no driver configured on comedi%i\n", dev->minor);
@@ -1723,9 +1733,9 @@
 /*
    This function restores a subdevice to an idle state.
  */
-void do_become_nonbusy(comedi_device *dev, comedi_subdevice *s)
+void do_become_nonbusy(struct comedi_device *dev, struct comedi_subdevice *s)
 {
-	comedi_async *async = s->async;
+	struct comedi_async *async = s->async;
 
 	comedi_set_subdevice_runflags(s, SRF_RUNNING, 0);
 #ifdef CONFIG_COMEDI_RT
@@ -1747,11 +1757,11 @@
 
 static int comedi_open(struct inode *inode, struct file *file)
 {
-	char mod[32];
 	const unsigned minor = iminor(inode);
 	struct comedi_device_file_info *dev_file_info =
 	    comedi_get_device_file_info(minor);
-	comedi_device *dev = dev_file_info->device;
+	struct comedi_device *dev = dev_file_info ? dev_file_info->device : NULL;
+
 	if (dev == NULL) {
 		DPRINTK("invalid minor number\n");
 		return -ENODEV;
@@ -1783,10 +1793,9 @@
 
 	dev->in_request_module = 1;
 
-	sprintf(mod, "char-major-%i-%i", COMEDI_MAJOR, dev->minor);
 #ifdef CONFIG_KMOD
 	mutex_unlock(&dev->mutex);
-	request_module(mod);
+	request_module("char-major-%i-%i", COMEDI_MAJOR, dev->minor);
 	mutex_lock(&dev->mutex);
 #endif
 
@@ -1823,8 +1832,8 @@
 	const unsigned minor = iminor(inode);
 	struct comedi_device_file_info *dev_file_info =
 	    comedi_get_device_file_info(minor);
-	comedi_device *dev = dev_file_info->device;
-	comedi_subdevice *s = NULL;
+	struct comedi_device *dev = dev_file_info->device;
+	struct comedi_subdevice *s = NULL;
 	int i;
 
 	mutex_lock(&dev->mutex);
@@ -1862,7 +1871,7 @@
 	struct comedi_device_file_info *dev_file_info =
 	    comedi_get_device_file_info(minor);
 
-	comedi_device *dev = dev_file_info->device;
+	struct comedi_device *dev = dev_file_info->device;
 
 	return fasync_helper(fd, file, on, &dev->async_queue);
 }
@@ -1893,7 +1902,7 @@
 {
 	unsigned i;
 
-	for (i = 0; i < COMEDI_NUM_LEGACY_MINORS; i++)
+	for (i = 0; i < comedi_num_legacy_minors; i++)
 		comedi_free_board_minor(i);
 }
 
@@ -1905,6 +1914,22 @@
 	printk(KERN_INFO "comedi: version " COMEDI_RELEASE
 	       " - http://www.comedi.org\n");
 
+	if (comedi_num_legacy_minors < 0 ||
+	    comedi_num_legacy_minors > COMEDI_NUM_BOARD_MINORS) {
+		printk(KERN_ERR "comedi: error: invalid value for module "
+		       "parameter \"comedi_num_legacy_minors\".  Valid values "
+		       "are 0 through %i.\n", COMEDI_NUM_BOARD_MINORS);
+		return -EINVAL;
+	}
+
+	/*
+	 * comedi is unusable if both comedi_autoconfig and
+	 * comedi_num_legacy_minors are zero, so we might as well adjust the
+	 * defaults in that case
+	 */
+	if (comedi_autoconfig == 0 && comedi_num_legacy_minors == 0)
+		comedi_num_legacy_minors = 16;
+
 	memset(comedi_file_info_table, 0,
 	       sizeof(struct comedi_device_file_info *) * COMEDI_NUM_MINORS);
 
@@ -1933,7 +1958,7 @@
 	comedi_proc_init();
 
 	/* create devices files for legacy/manual use */
-	for (i = 0; i < COMEDI_NUM_LEGACY_MINORS; i++) {
+	for (i = 0; i < comedi_num_legacy_minors; i++) {
 		int minor;
 		minor = comedi_alloc_board_minor(NULL);
 		if (minor < 0) {
@@ -1975,15 +2000,15 @@
 module_init(comedi_init);
 module_exit(comedi_cleanup);
 
-void comedi_error(const comedi_device *dev, const char *s)
+void comedi_error(const struct comedi_device *dev, const char *s)
 {
 	rt_printk("comedi%d: %s: %s\n", dev->minor, dev->driver->driver_name,
 		  s);
 }
 
-void comedi_event(comedi_device *dev, comedi_subdevice *s)
+void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
 {
-	comedi_async *async = s->async;
+	struct comedi_async *async = s->async;
 	unsigned runflags = 0;
 	unsigned runflags_mask = 0;
 
@@ -2042,7 +2067,7 @@
 	s->async->events = 0;
 }
 
-void comedi_set_subdevice_runflags(comedi_subdevice *s, unsigned mask,
+void comedi_set_subdevice_runflags(struct comedi_subdevice *s, unsigned mask,
 				   unsigned bits)
 {
 	unsigned long flags;
@@ -2053,7 +2078,7 @@
 	comedi_spin_unlock_irqrestore(&s->spin_lock, flags);
 }
 
-unsigned comedi_get_subdevice_runflags(comedi_subdevice *s)
+unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s)
 {
 	unsigned long flags;
 	unsigned runflags;
@@ -2064,9 +2089,9 @@
 	return runflags;
 }
 
-static int is_device_busy(comedi_device *dev)
+static int is_device_busy(struct comedi_device *dev)
 {
-	comedi_subdevice *s;
+	struct comedi_subdevice *s;
 	int i;
 
 	if (!dev->attached)
@@ -2083,15 +2108,15 @@
 	return 0;
 }
 
-void comedi_device_init(comedi_device *dev)
+void comedi_device_init(struct comedi_device *dev)
 {
-	memset(dev, 0, sizeof(comedi_device));
+	memset(dev, 0, sizeof(struct comedi_device));
 	spin_lock_init(&dev->spinlock);
 	mutex_init(&dev->mutex);
 	dev->minor = -1;
 }
 
-void comedi_device_cleanup(comedi_device *dev)
+void comedi_device_cleanup(struct comedi_device *dev)
 {
 	if (dev == NULL)
 		return;
@@ -2105,13 +2130,13 @@
 {
 	unsigned long flags;
 	struct comedi_device_file_info *info;
-	device_create_result_type *csdev;
+	struct device *csdev;
 	unsigned i;
 
 	info = kzalloc(sizeof(struct comedi_device_file_info), GFP_KERNEL);
 	if (info == NULL)
 		return -ENOMEM;
-	info->device = kzalloc(sizeof(comedi_device), GFP_KERNEL);
+	info->device = kzalloc(sizeof(struct comedi_device), GFP_KERNEL);
 	if (info->device == NULL) {
 		kfree(info);
 		return -ENOMEM;
@@ -2155,7 +2180,7 @@
 	comedi_spin_unlock_irqrestore(&comedi_file_info_table_lock, flags);
 
 	if (info) {
-		comedi_device *dev = info->device;
+		struct comedi_device *dev = info->device;
 		if (dev) {
 			if (dev->class_dev) {
 				device_destroy(comedi_class,
@@ -2168,11 +2193,11 @@
 	}
 }
 
-int comedi_alloc_subdevice_minor(comedi_device *dev, comedi_subdevice *s)
+int comedi_alloc_subdevice_minor(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	unsigned long flags;
 	struct comedi_device_file_info *info;
-	device_create_result_type *csdev;
+	struct device *csdev;
 	unsigned i;
 
 	info = kmalloc(sizeof(struct comedi_device_file_info), GFP_KERNEL);
@@ -2182,7 +2207,7 @@
 	info->read_subdevice = s;
 	info->write_subdevice = s;
 	comedi_spin_lock_irqsave(&comedi_file_info_table_lock, flags);
-	for (i = COMEDI_FIRST_SUBDEVICE_MINOR; i < COMEDI_NUM_BOARD_MINORS; ++i) {
+	for (i = COMEDI_FIRST_SUBDEVICE_MINOR; i < COMEDI_NUM_MINORS; ++i) {
 		if (comedi_file_info_table[i] == NULL) {
 			comedi_file_info_table[i] = info;
 			break;
@@ -2206,7 +2231,7 @@
 	return i;
 }
 
-void comedi_free_subdevice_minor(comedi_subdevice *s)
+void comedi_free_subdevice_minor(struct comedi_subdevice *s)
 {
 	unsigned long flags;
 	struct comedi_device_file_info *info;
diff --git a/drivers/staging/comedi/comedi_fops.h b/drivers/staging/comedi/comedi_fops.h
index 63f8df5..cb503c8 100644
--- a/drivers/staging/comedi/comedi_fops.h
+++ b/drivers/staging/comedi/comedi_fops.h
@@ -4,5 +4,6 @@
 
 extern struct class *comedi_class;
 extern const struct file_operations comedi_fops;
+extern int comedi_autoconfig;
 
 #endif /* _COMEDI_FOPS_H */
diff --git a/drivers/staging/comedi/comedi_ksyms.c b/drivers/staging/comedi/comedi_ksyms.c
index 90d5728..6e6fb97 100644
--- a/drivers/staging/comedi/comedi_ksyms.c
+++ b/drivers/staging/comedi/comedi_ksyms.c
@@ -31,12 +31,12 @@
 /* for drivers */
 EXPORT_SYMBOL(comedi_driver_register);
 EXPORT_SYMBOL(comedi_driver_unregister);
-//EXPORT_SYMBOL(comedi_bufcheck);
-//EXPORT_SYMBOL(comedi_done);
-//EXPORT_SYMBOL(comedi_error_done);
+/* EXPORT_SYMBOL(comedi_bufcheck); */
+/* EXPORT_SYMBOL(comedi_done); */
+/* EXPORT_SYMBOL(comedi_error_done); */
 EXPORT_SYMBOL(comedi_error);
-//EXPORT_SYMBOL(comedi_eobuf);
-//EXPORT_SYMBOL(comedi_eos);
+/* EXPORT_SYMBOL(comedi_eobuf); */
+/* EXPORT_SYMBOL(comedi_eos); */
 EXPORT_SYMBOL(comedi_event);
 EXPORT_SYMBOL(comedi_get_subdevice_runflags);
 EXPORT_SYMBOL(comedi_set_subdevice_runflags);
@@ -60,6 +60,8 @@
 EXPORT_SYMBOL_GPL(comedi_free_board_minor);
 EXPORT_SYMBOL_GPL(comedi_pci_auto_config);
 EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig);
+EXPORT_SYMBOL_GPL(comedi_usb_auto_config);
+EXPORT_SYMBOL_GPL(comedi_usb_auto_unconfig);
 
 /* for kcomedilib */
 EXPORT_SYMBOL(check_chanlist);
diff --git a/drivers/staging/comedi/comedi_rt.h b/drivers/staging/comedi/comedi_rt.h
index 61852bf..169ca96 100644
--- a/drivers/staging/comedi/comedi_rt.h
+++ b/drivers/staging/comedi/comedi_rt.h
@@ -28,7 +28,6 @@
 #error comedi_rt.h should only be included by comedidev.h
 #endif
 
-#include <linux/version.h>
 #include <linux/kdev_t.h>
 #include <linux/slab.h>
 #include <linux/errno.h>
@@ -59,12 +58,12 @@
 
 int comedi_request_irq(unsigned int irq, irqreturn_t(*handler) (int,
 		void *PT_REGS_ARG), unsigned long flags, const char *device,
-		comedi_device *dev_id);
-void comedi_free_irq(unsigned int irq, comedi_device *dev_id);
+		struct comedi_device *dev_id);
+void comedi_free_irq(unsigned int irq, struct comedi_device *dev_id);
 void comedi_rt_init(void);
 void comedi_rt_cleanup(void);
-int comedi_switch_to_rt(comedi_device *dev);
-void comedi_switch_to_non_rt(comedi_device *dev);
+int comedi_switch_to_rt(struct comedi_device *dev);
+void comedi_switch_to_non_rt(struct comedi_device *dev);
 void comedi_rt_pend_wakeup(wait_queue_head_t *q);
 extern int rt_pend_call(void (*func) (int arg1, void *arg2), int arg1,
 	void *arg2);
diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h
index 3735355..ea31936 100644
--- a/drivers/staging/comedi/comedidev.h
+++ b/drivers/staging/comedi/comedidev.h
@@ -26,7 +26,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/kdev_t.h>
 #include <linux/slab.h>
 #include <linux/errno.h>
@@ -36,7 +35,6 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/vmalloc.h>
-#include <linux/mm.h>
 #include "interrupt.h"
 #include <linux/dma-mapping.h>
 #include <linux/uaccess.h>
@@ -55,9 +53,9 @@
 
 #define COMEDI_INITCLEANUP_NOMODULE(x)					\
 	static int __init x ## _init_module(void)			\
-		{return comedi_driver_register(&(x));}			\
+		{return comedi_driver_register(&(x)); }			\
 	static void __exit x ## _cleanup_module(void)			\
-		{comedi_driver_unregister(&(x));} 			\
+		{comedi_driver_unregister(&(x)); } 			\
 	module_init(x ## _init_module);					\
 	module_exit(x ## _cleanup_module);					\
 
@@ -120,23 +118,14 @@
 #define PCI_VENDOR_ID_MEILHAUS		0x1402
 
 #define COMEDI_NUM_MINORS 0x100
-#define COMEDI_NUM_LEGACY_MINORS 0x10
 #define COMEDI_NUM_BOARD_MINORS 0x30
 #define COMEDI_FIRST_SUBDEVICE_MINOR COMEDI_NUM_BOARD_MINORS
 
-typedef struct comedi_device_struct comedi_device;
-typedef struct comedi_subdevice_struct comedi_subdevice;
-typedef struct comedi_async_struct comedi_async;
-typedef struct comedi_driver_struct comedi_driver;
-typedef struct comedi_lrange_struct comedi_lrange;
-
-typedef struct device device_create_result_type;
-
 #define COMEDI_DEVICE_CREATE(cs, parent, devt, drvdata, device, fmt...) \
 	device_create(cs, ((parent) ? (parent) : (device)), devt, drvdata, fmt)
 
-struct comedi_subdevice_struct {
-	comedi_device *device;
+struct comedi_subdevice {
+	struct comedi_device *device;
 	int type;
 	int n_chan;
 	volatile int subdev_flags;
@@ -144,7 +133,7 @@
 
 	void *private;
 
-	comedi_async *async;
+	struct comedi_async *async;
 
 	void *lock;
 	void *busy;
@@ -153,46 +142,46 @@
 
 	int io_bits;
 
-	lsampl_t maxdata;	/* if maxdata==0, use list */
-	const lsampl_t *maxdata_list;	/* list is channel specific */
+	unsigned int maxdata;	/* if maxdata==0, use list */
+	const unsigned int *maxdata_list;	/* list is channel specific */
 
 	unsigned int flags;
 	const unsigned int *flaglist;
 
 	unsigned int settling_time_0;
 
-	const comedi_lrange *range_table;
-	const comedi_lrange *const *range_table_list;
+	const struct comedi_lrange *range_table;
+	const struct comedi_lrange *const *range_table_list;
 
 	unsigned int *chanlist;	/* driver-owned chanlist (not used) */
 
-	int (*insn_read) (comedi_device *, comedi_subdevice *, comedi_insn *,
-		lsampl_t *);
-	int (*insn_write) (comedi_device *, comedi_subdevice *, comedi_insn *,
-		lsampl_t *);
-	int (*insn_bits) (comedi_device *, comedi_subdevice *, comedi_insn *,
-		lsampl_t *);
-	int (*insn_config) (comedi_device *, comedi_subdevice *, comedi_insn *,
-		lsampl_t *);
+	int (*insn_read) (struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+		unsigned int *);
+	int (*insn_write) (struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+		unsigned int *);
+	int (*insn_bits) (struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+		unsigned int *);
+	int (*insn_config) (struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+		unsigned int *);
 
-	int (*do_cmd) (comedi_device *, comedi_subdevice *);
-	int (*do_cmdtest) (comedi_device *, comedi_subdevice *, comedi_cmd *);
-	int (*poll) (comedi_device *, comedi_subdevice *);
-	int (*cancel) (comedi_device *, comedi_subdevice *);
-	/* int (*do_lock)(comedi_device *,comedi_subdevice *); */
-	/* int (*do_unlock)(comedi_device *,comedi_subdevice *); */
+	int (*do_cmd) (struct comedi_device *, struct comedi_subdevice *);
+	int (*do_cmdtest) (struct comedi_device *, struct comedi_subdevice *, struct comedi_cmd *);
+	int (*poll) (struct comedi_device *, struct comedi_subdevice *);
+	int (*cancel) (struct comedi_device *, struct comedi_subdevice *);
+	/* int (*do_lock)(struct comedi_device *,struct comedi_subdevice *); */
+	/* int (*do_unlock)(struct comedi_device *,struct comedi_subdevice *); */
 
 	/* called when the buffer changes */
-	int (*buf_change) (comedi_device *dev, comedi_subdevice *s,
+	int (*buf_change) (struct comedi_device *dev, struct comedi_subdevice *s,
 		unsigned long new_size);
 
-	void (*munge) (comedi_device *dev, comedi_subdevice *s, void *data,
+	void (*munge) (struct comedi_device *dev, struct comedi_subdevice *s, void *data,
 		unsigned int num_bytes, unsigned int start_chan_index);
 	enum dma_data_direction async_dma_dir;
 
 	unsigned int state;
 
-	device_create_result_type *class_dev;
+	struct device *class_dev;
 	int minor;
 };
 
@@ -201,8 +190,8 @@
 	dma_addr_t dma_addr;
 };
 
-struct comedi_async_struct {
-	comedi_subdevice *subdevice;
+struct comedi_async {
+	struct comedi_subdevice *subdevice;
 
 	void *prealloc_buf;	/* pre-allocated buffer */
 	unsigned int prealloc_bufsz;	/* buffer size, in bytes */
@@ -232,7 +221,7 @@
 
 	unsigned int events;	/* events that have occurred */
 
-	comedi_cmd cmd;
+	struct comedi_cmd cmd;
 
 	wait_queue_head_t wait_head;
 
@@ -241,17 +230,17 @@
 	int (*cb_func) (unsigned int flags, void *);
 	void *cb_arg;
 
-	int (*inttrig) (comedi_device *dev, comedi_subdevice *s,
+	int (*inttrig) (struct comedi_device *dev, struct comedi_subdevice *s,
 			unsigned int x);
 };
 
-struct comedi_driver_struct {
-	struct comedi_driver_struct *next;
+struct comedi_driver {
+	struct comedi_driver *next;
 
 	const char *driver_name;
 	struct module *module;
-	int (*attach) (comedi_device *, comedi_devconfig *);
-	int (*detach) (comedi_device *);
+	int (*attach) (struct comedi_device *, struct comedi_devconfig *);
+	int (*detach) (struct comedi_device *);
 
 	/* number of elements in board_name and board_id arrays */
 	unsigned int num_names;
@@ -260,12 +249,12 @@
 	int offset;
 };
 
-struct comedi_device_struct {
+struct comedi_device {
 	int use_count;
-	comedi_driver *driver;
+	struct comedi_driver *driver;
 	void *private;
 
-	device_create_result_type *class_dev;
+	struct device *class_dev;
 	int minor;
 	/* hw_dev is passed to dma_alloc_coherent when allocating async buffers
 	 * for subdevices that have async_dma_dir set to something other than
@@ -281,25 +270,25 @@
 	int in_request_module;
 
 	int n_subdevices;
-	comedi_subdevice *subdevices;
+	struct comedi_subdevice *subdevices;
 
 	/* dumb */
 	unsigned long iobase;
 	unsigned int irq;
 
-	comedi_subdevice *read_subdev;
-	comedi_subdevice *write_subdev;
+	struct comedi_subdevice *read_subdev;
+	struct comedi_subdevice *write_subdev;
 
 	struct fasync_struct *async_queue;
 
-	void (*open) (comedi_device *dev);
-	void (*close) (comedi_device *dev);
+	void (*open) (struct comedi_device *dev);
+	void (*close) (struct comedi_device *dev);
 };
 
 struct comedi_device_file_info {
-	comedi_device *device;
-	comedi_subdevice *read_subdevice;
-	comedi_subdevice *write_subdevice;
+	struct comedi_device *device;
+	struct comedi_subdevice *read_subdevice;
+	struct comedi_subdevice *write_subdevice;
 };
 
 #ifdef CONFIG_COMEDI_DEBUG
@@ -312,8 +301,8 @@
  * function prototypes
  */
 
-void comedi_event(comedi_device *dev, comedi_subdevice *s);
-void comedi_error(const comedi_device *dev, const char *s);
+void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s);
+void comedi_error(const struct comedi_device *dev, const char *s);
 
 /* we can expand the number of bits used to encode devices/subdevices into
  the minor number soon, after more distros support > 8 bit minor numbers
@@ -327,7 +316,7 @@
 
 struct comedi_device_file_info *comedi_get_device_file_info(unsigned minor);
 
-static inline comedi_subdevice *comedi_get_read_subdevice(
+static inline struct comedi_subdevice *comedi_get_read_subdevice(
 				const struct comedi_device_file_info *info)
 {
 	if (info->read_subdevice)
@@ -337,7 +326,7 @@
 	return info->device->read_subdev;
 }
 
-static inline comedi_subdevice *comedi_get_write_subdevice(
+static inline struct comedi_subdevice *comedi_get_write_subdevice(
 				const struct comedi_device_file_info *info)
 {
 	if (info->write_subdevice)
@@ -347,17 +336,17 @@
 	return info->device->write_subdev;
 }
 
-void comedi_device_detach(comedi_device *dev);
-int comedi_device_attach(comedi_device *dev, comedi_devconfig *it);
-int comedi_driver_register(comedi_driver *);
-int comedi_driver_unregister(comedi_driver *);
+void comedi_device_detach(struct comedi_device *dev);
+int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+int comedi_driver_register(struct comedi_driver *);
+int comedi_driver_unregister(struct comedi_driver *);
 
 void init_polling(void);
 void cleanup_polling(void);
-void start_polling(comedi_device *);
-void stop_polling(comedi_device *);
+void start_polling(struct comedi_device *);
+void stop_polling(struct comedi_device *);
 
-int comedi_buf_alloc(comedi_device *dev, comedi_subdevice *s, unsigned long
+int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long
 	new_size);
 
 #ifdef CONFIG_PROC_FS
@@ -386,13 +375,13 @@
    various internal comedi functions
  */
 
-int do_rangeinfo_ioctl(comedi_device *dev, comedi_rangeinfo *arg);
-int check_chanlist(comedi_subdevice *s, int n, unsigned int *chanlist);
-void comedi_set_subdevice_runflags(comedi_subdevice *s, unsigned mask,
+int do_rangeinfo_ioctl(struct comedi_device *dev, struct comedi_rangeinfo *arg);
+int check_chanlist(struct comedi_subdevice *s, int n, unsigned int *chanlist);
+void comedi_set_subdevice_runflags(struct comedi_subdevice *s, unsigned mask,
 	unsigned bits);
-unsigned comedi_get_subdevice_runflags(comedi_subdevice *s);
-int insn_inval(comedi_device *dev, comedi_subdevice *s,
-	comedi_insn *insn, lsampl_t *data);
+unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s);
+int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data);
 
 /* range stuff */
 
@@ -403,12 +392,12 @@
 #define BIP_RANGE(a)		{-(a)*1e6, (a)*1e6, 0}
 #define UNI_RANGE(a)		{0, (a)*1e6, 0}
 
-extern const comedi_lrange range_bipolar10;
-extern const comedi_lrange range_bipolar5;
-extern const comedi_lrange range_bipolar2_5;
-extern const comedi_lrange range_unipolar10;
-extern const comedi_lrange range_unipolar5;
-extern const comedi_lrange range_unknown;
+extern const struct comedi_lrange range_bipolar10;
+extern const struct comedi_lrange range_bipolar5;
+extern const struct comedi_lrange range_bipolar2_5;
+extern const struct comedi_lrange range_unipolar10;
+extern const struct comedi_lrange range_unipolar5;
+extern const struct comedi_lrange range_unknown;
 
 #define range_digital		range_unipolar5
 
@@ -418,21 +407,21 @@
 #define GCC_ZERO_LENGTH_ARRAY 0
 #endif
 
-struct comedi_lrange_struct {
+struct comedi_lrange {
 	int length;
-	comedi_krange range[GCC_ZERO_LENGTH_ARRAY];
+	struct comedi_krange range[GCC_ZERO_LENGTH_ARRAY];
 };
 
 /* some silly little inline functions */
 
-static inline int alloc_subdevices(comedi_device *dev,
+static inline int alloc_subdevices(struct comedi_device *dev,
 				   unsigned int num_subdevices)
 {
 	unsigned i;
 
 	dev->n_subdevices = num_subdevices;
 	dev->subdevices =
-		kcalloc(num_subdevices, sizeof(comedi_subdevice), GFP_KERNEL);
+		kcalloc(num_subdevices, sizeof(struct comedi_subdevice), GFP_KERNEL);
 	if (!dev->subdevices)
 		return -ENOMEM;
 	for (i = 0; i < num_subdevices; ++i) {
@@ -444,7 +433,7 @@
 	return 0;
 }
 
-static inline int alloc_private(comedi_device *dev, int size)
+static inline int alloc_private(struct comedi_device *dev, int size)
 {
 	dev->private = kzalloc(size, GFP_KERNEL);
 	if (!dev->private)
@@ -452,17 +441,17 @@
 	return 0;
 }
 
-static inline unsigned int bytes_per_sample(const comedi_subdevice *subd)
+static inline unsigned int bytes_per_sample(const struct comedi_subdevice *subd)
 {
 	if (subd->subdev_flags & SDF_LSAMPL)
-		return sizeof(lsampl_t);
+		return sizeof(unsigned int);
 	else
-		return sizeof(sampl_t);
+		return sizeof(short);
 }
 
 /* must be used in attach to set dev->hw_dev if you wish to dma directly
 into comedi's buffer */
-static inline void comedi_set_hw_dev(comedi_device *dev, struct device *hw_dev)
+static inline void comedi_set_hw_dev(struct comedi_device *dev, struct device *hw_dev)
 {
 	if (dev->hw_dev)
 		put_device(dev->hw_dev);
@@ -474,31 +463,31 @@
 	}
 }
 
-int comedi_buf_put(comedi_async *async, sampl_t x);
-int comedi_buf_get(comedi_async *async, sampl_t *x);
+int comedi_buf_put(struct comedi_async *async, short x);
+int comedi_buf_get(struct comedi_async *async, short *x);
 
-unsigned int comedi_buf_write_n_available(comedi_async *async);
-unsigned int comedi_buf_write_alloc(comedi_async *async, unsigned int nbytes);
-unsigned int comedi_buf_write_alloc_strict(comedi_async *async,
+unsigned int comedi_buf_write_n_available(struct comedi_async *async);
+unsigned int comedi_buf_write_alloc(struct comedi_async *async, unsigned int nbytes);
+unsigned int comedi_buf_write_alloc_strict(struct comedi_async *async,
 	unsigned int nbytes);
-unsigned comedi_buf_write_free(comedi_async *async, unsigned int nbytes);
-unsigned comedi_buf_read_alloc(comedi_async *async, unsigned nbytes);
-unsigned comedi_buf_read_free(comedi_async *async, unsigned int nbytes);
-unsigned int comedi_buf_read_n_available(comedi_async *async);
-void comedi_buf_memcpy_to(comedi_async *async, unsigned int offset,
+unsigned comedi_buf_write_free(struct comedi_async *async, unsigned int nbytes);
+unsigned comedi_buf_read_alloc(struct comedi_async *async, unsigned nbytes);
+unsigned comedi_buf_read_free(struct comedi_async *async, unsigned int nbytes);
+unsigned int comedi_buf_read_n_available(struct comedi_async *async);
+void comedi_buf_memcpy_to(struct comedi_async *async, unsigned int offset,
 	const void *source, unsigned int num_bytes);
-void comedi_buf_memcpy_from(comedi_async *async, unsigned int offset,
+void comedi_buf_memcpy_from(struct comedi_async *async, unsigned int offset,
 	void *destination, unsigned int num_bytes);
-static inline unsigned comedi_buf_write_n_allocated(comedi_async *async)
+static inline unsigned comedi_buf_write_n_allocated(struct comedi_async *async)
 {
 	return async->buf_write_alloc_count - async->buf_write_count;
 }
-static inline unsigned comedi_buf_read_n_allocated(comedi_async *async)
+static inline unsigned comedi_buf_read_n_allocated(struct comedi_async *async)
 {
 	return async->buf_read_alloc_count - async->buf_read_count;
 }
 
-void comedi_reset_async_buf(comedi_async *async);
+void comedi_reset_async_buf(struct comedi_async *async);
 
 static inline void *comedi_aux_data(int options[], int n)
 {
@@ -527,10 +516,13 @@
 
 int comedi_alloc_board_minor(struct device *hardware_device);
 void comedi_free_board_minor(unsigned minor);
-int comedi_alloc_subdevice_minor(comedi_device *dev, comedi_subdevice *s);
-void comedi_free_subdevice_minor(comedi_subdevice *s);
+int comedi_alloc_subdevice_minor(struct comedi_device *dev, struct comedi_subdevice *s);
+void comedi_free_subdevice_minor(struct comedi_subdevice *s);
 int comedi_pci_auto_config(struct pci_dev *pcidev, const char *board_name);
 void comedi_pci_auto_unconfig(struct pci_dev *pcidev);
+struct usb_device;	/* forward declaration */
+int comedi_usb_auto_config(struct usb_device *usbdev, const char *board_name);
+void comedi_usb_auto_unconfig(struct usb_device *usbdev);
 
 #include "comedi_rt.h"
 
diff --git a/drivers/staging/comedi/comedilib.h b/drivers/staging/comedi/comedilib.h
index fc5fc01..c272931 100644
--- a/drivers/staging/comedi/comedilib.h
+++ b/drivers/staging/comedi/comedilib.h
@@ -36,18 +36,16 @@
 
 #ifndef KCOMEDILIB_DEPRECATED
 
-typedef void comedi_t;
-
 /* these functions may not be called at real-time priority */
 
-comedi_t *comedi_open(const char *path);
-int comedi_close(comedi_t *dev);
+void *comedi_open(const char *path);
+int comedi_close(void *dev);
 
 /* these functions may be called at any priority, but may fail at
    real-time priority */
 
-int comedi_lock(comedi_t *dev, unsigned int subdev);
-int comedi_unlock(comedi_t *dev, unsigned int subdev);
+int comedi_lock(void *dev, unsigned int subdev);
+int comedi_unlock(void *dev, unsigned int subdev);
 
 /* these functions may be called at any priority, but you must hold
    the lock for the subdevice */
@@ -56,68 +54,68 @@
 void comedi_perror(const char *s);
 char *comedi_strerror(int errnum);
 int comedi_errno(void);
-int comedi_fileno(comedi_t *dev);
+int comedi_fileno(void *dev);
 
-int comedi_cancel(comedi_t *dev, unsigned int subdev);
-int comedi_register_callback(comedi_t *dev, unsigned int subdev,
+int comedi_cancel(void *dev, unsigned int subdev);
+int comedi_register_callback(void *dev, unsigned int subdev,
 	unsigned int mask, int (*cb) (unsigned int, void *), void *arg);
 
-int comedi_command(comedi_t *dev, comedi_cmd *cmd);
-int comedi_command_test(comedi_t *dev, comedi_cmd *cmd);
-int comedi_trigger(comedi_t *dev, unsigned int subdev, comedi_trig *it);
-int __comedi_trigger(comedi_t *dev, unsigned int subdev, comedi_trig *it);
-int comedi_data_write(comedi_t *dev, unsigned int subdev, unsigned int chan,
-	unsigned int range, unsigned int aref, lsampl_t data);
-int comedi_data_read(comedi_t *dev, unsigned int subdev, unsigned int chan,
-	unsigned int range, unsigned int aref, lsampl_t *data);
-int comedi_data_read_hint(comedi_t *dev, unsigned int subdev,
+int comedi_command(void *dev, struct comedi_cmd *cmd);
+int comedi_command_test(void *dev, struct comedi_cmd *cmd);
+int comedi_trigger(void *dev, unsigned int subdev, struct comedi_trig *it);
+int __comedi_trigger(void *dev, unsigned int subdev, struct comedi_trig *it);
+int comedi_data_write(void *dev, unsigned int subdev, unsigned int chan,
+	unsigned int range, unsigned int aref, unsigned int data);
+int comedi_data_read(void *dev, unsigned int subdev, unsigned int chan,
+	unsigned int range, unsigned int aref, unsigned int *data);
+int comedi_data_read_hint(void *dev, unsigned int subdev,
 	unsigned int chan, unsigned int range, unsigned int aref);
-int comedi_data_read_delayed(comedi_t *dev, unsigned int subdev,
+int comedi_data_read_delayed(void *dev, unsigned int subdev,
 	unsigned int chan, unsigned int range, unsigned int aref,
-	lsampl_t *data, unsigned int nano_sec);
-int comedi_dio_config(comedi_t *dev, unsigned int subdev, unsigned int chan,
+	unsigned int *data, unsigned int nano_sec);
+int comedi_dio_config(void *dev, unsigned int subdev, unsigned int chan,
 	unsigned int io);
-int comedi_dio_read(comedi_t *dev, unsigned int subdev, unsigned int chan,
+int comedi_dio_read(void *dev, unsigned int subdev, unsigned int chan,
 	unsigned int *val);
-int comedi_dio_write(comedi_t *dev, unsigned int subdev, unsigned int chan,
+int comedi_dio_write(void *dev, unsigned int subdev, unsigned int chan,
 	unsigned int val);
-int comedi_dio_bitfield(comedi_t *dev, unsigned int subdev, unsigned int mask,
+int comedi_dio_bitfield(void *dev, unsigned int subdev, unsigned int mask,
 	unsigned int *bits);
-int comedi_get_n_subdevices(comedi_t *dev);
-int comedi_get_version_code(comedi_t *dev);
-const char *comedi_get_driver_name(comedi_t *dev);
-const char *comedi_get_board_name(comedi_t *dev);
-int comedi_get_subdevice_type(comedi_t *dev, unsigned int subdevice);
-int comedi_find_subdevice_by_type(comedi_t *dev, int type, unsigned int subd);
-int comedi_get_n_channels(comedi_t *dev, unsigned int subdevice);
-lsampl_t comedi_get_maxdata(comedi_t *dev, unsigned int subdevice, unsigned
+int comedi_get_n_subdevices(void *dev);
+int comedi_get_version_code(void *dev);
+const char *comedi_get_driver_name(void *dev);
+const char *comedi_get_board_name(void *dev);
+int comedi_get_subdevice_type(void *dev, unsigned int subdevice);
+int comedi_find_subdevice_by_type(void *dev, int type, unsigned int subd);
+int comedi_get_n_channels(void *dev, unsigned int subdevice);
+unsigned int comedi_get_maxdata(void *dev, unsigned int subdevice, unsigned
 	int chan);
-int comedi_get_n_ranges(comedi_t *dev, unsigned int subdevice, unsigned int
+int comedi_get_n_ranges(void *dev, unsigned int subdevice, unsigned int
 	chan);
-int comedi_do_insn(comedi_t *dev, comedi_insn *insn);
-int comedi_poll(comedi_t *dev, unsigned int subdev);
+int comedi_do_insn(void *dev, struct comedi_insn *insn);
+int comedi_poll(void *dev, unsigned int subdev);
 
 /* DEPRECATED functions */
-int comedi_get_rangetype(comedi_t *dev, unsigned int subdevice,
+int comedi_get_rangetype(void *dev, unsigned int subdevice,
 	unsigned int chan);
 
 /* ALPHA functions */
-unsigned int comedi_get_subdevice_flags(comedi_t *dev, unsigned int subdevice);
-int comedi_get_len_chanlist(comedi_t *dev, unsigned int subdevice);
-int comedi_get_krange(comedi_t *dev, unsigned int subdevice, unsigned int
-	chan, unsigned int range, comedi_krange *krange);
-unsigned int comedi_get_buf_head_pos(comedi_t *dev, unsigned int subdevice);
-int comedi_set_user_int_count(comedi_t *dev, unsigned int subdevice,
+unsigned int comedi_get_subdevice_flags(void *dev, unsigned int subdevice);
+int comedi_get_len_chanlist(void *dev, unsigned int subdevice);
+int comedi_get_krange(void *dev, unsigned int subdevice, unsigned int
+	chan, unsigned int range, struct comedi_krange *krange);
+unsigned int comedi_get_buf_head_pos(void *dev, unsigned int subdevice);
+int comedi_set_user_int_count(void *dev, unsigned int subdevice,
 	unsigned int buf_user_count);
-int comedi_map(comedi_t *dev, unsigned int subdev, void *ptr);
-int comedi_unmap(comedi_t *dev, unsigned int subdev);
-int comedi_get_buffer_size(comedi_t *dev, unsigned int subdev);
-int comedi_mark_buffer_read(comedi_t *dev, unsigned int subdevice,
+int comedi_map(void *dev, unsigned int subdev, void *ptr);
+int comedi_unmap(void *dev, unsigned int subdev);
+int comedi_get_buffer_size(void *dev, unsigned int subdev);
+int comedi_mark_buffer_read(void *dev, unsigned int subdevice,
 	unsigned int num_bytes);
-int comedi_mark_buffer_written(comedi_t *d, unsigned int subdevice,
+int comedi_mark_buffer_written(void *d, unsigned int subdevice,
 	unsigned int num_bytes);
-int comedi_get_buffer_contents(comedi_t *dev, unsigned int subdevice);
-int comedi_get_buffer_offset(comedi_t *dev, unsigned int subdevice);
+int comedi_get_buffer_contents(void *dev, unsigned int subdevice);
+int comedi_get_buffer_offset(void *dev, unsigned int subdevice);
 
 #else
 
@@ -139,14 +137,14 @@
 int comedi_register_callback(unsigned int minor, unsigned int subdev,
 	unsigned int mask, int (*cb) (unsigned int, void *), void *arg);
 
-int comedi_command(unsigned int minor, comedi_cmd *cmd);
-int comedi_command_test(unsigned int minor, comedi_cmd *cmd);
-int comedi_trigger(unsigned int minor, unsigned int subdev, comedi_trig *it);
-int __comedi_trigger(unsigned int minor, unsigned int subdev, comedi_trig *it);
+int comedi_command(unsigned int minor, struct comedi_cmd *cmd);
+int comedi_command_test(unsigned int minor, struct comedi_cmd *cmd);
+int comedi_trigger(unsigned int minor, unsigned int subdev, struct comedi_trig *it);
+int __comedi_trigger(unsigned int minor, unsigned int subdev, struct comedi_trig *it);
 int comedi_data_write(unsigned int dev, unsigned int subdev, unsigned int chan,
-	unsigned int range, unsigned int aref, lsampl_t data);
+	unsigned int range, unsigned int aref, unsigned int data);
 int comedi_data_read(unsigned int dev, unsigned int subdev, unsigned int chan,
-	unsigned int range, unsigned int aref, lsampl_t *data);
+	unsigned int range, unsigned int aref, unsigned int *data);
 int comedi_dio_config(unsigned int dev, unsigned int subdev, unsigned int chan,
 	unsigned int io);
 int comedi_dio_read(unsigned int dev, unsigned int subdev, unsigned int chan,
@@ -163,11 +161,11 @@
 int comedi_find_subdevice_by_type(unsigned int minor, int type,
 	unsigned int subd);
 int comedi_get_n_channels(unsigned int minor, unsigned int subdevice);
-lsampl_t comedi_get_maxdata(unsigned int minor, unsigned int subdevice, unsigned
+unsigned int comedi_get_maxdata(unsigned int minor, unsigned int subdevice, unsigned
 	int chan);
 int comedi_get_n_ranges(unsigned int minor, unsigned int subdevice, unsigned int
 	chan);
-int comedi_do_insn(unsigned int minor, comedi_insn *insn);
+int comedi_do_insn(unsigned int minor, struct comedi_insn *insn);
 int comedi_poll(unsigned int minor, unsigned int subdev);
 
 /* DEPRECATED functions */
@@ -179,7 +177,7 @@
 	subdevice);
 int comedi_get_len_chanlist(unsigned int minor, unsigned int subdevice);
 int comedi_get_krange(unsigned int minor, unsigned int subdevice, unsigned int
-	chan, unsigned int range, comedi_krange *krange);
+	chan, unsigned int range, struct comedi_krange *krange);
 unsigned int comedi_get_buf_head_pos(unsigned int minor, unsigned int
 	subdevice);
 int comedi_set_user_int_count(unsigned int minor, unsigned int subdevice,
diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c
index 36a93b9..6e13e45 100644
--- a/drivers/staging/comedi/drivers.c
+++ b/drivers/staging/comedi/drivers.c
@@ -28,6 +28,7 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/usb.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -46,26 +47,26 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-static int postconfig(comedi_device * dev);
-static int insn_rw_emulate_bits(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data);
-static void *comedi_recognize(comedi_driver * driv, const char *name);
-static void comedi_report_boards(comedi_driver * driv);
-static int poll_invalid(comedi_device * dev, comedi_subdevice * s);
-int comedi_buf_alloc(comedi_device * dev, comedi_subdevice * s,
+static int postconfig(struct comedi_device *dev);
+static int insn_rw_emulate_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data);
+static void *comedi_recognize(struct comedi_driver * driv, const char *name);
+static void comedi_report_boards(struct comedi_driver *driv);
+static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s);
+int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
 	unsigned long new_size);
 
-comedi_driver *comedi_drivers;
+struct comedi_driver *comedi_drivers;
 
 int comedi_modprobe(int minor)
 {
 	return -EINVAL;
 }
 
-static void cleanup_device(comedi_device * dev)
+static void cleanup_device(struct comedi_device *dev)
 {
 	int i;
-	comedi_subdevice *s;
+	struct comedi_subdevice *s;
 
 	if (dev->subdevices) {
 		for (i = 0; i < dev->n_subdevices; i++) {
@@ -80,10 +81,8 @@
 		dev->subdevices = NULL;
 		dev->n_subdevices = 0;
 	}
-	if (dev->private) {
-		kfree(dev->private);
-		dev->private = NULL;
-	}
+	kfree(dev->private);
+	dev->private = NULL;
 	dev->driver = 0;
 	dev->board_name = NULL;
 	dev->board_ptr = NULL;
@@ -96,7 +95,7 @@
 	comedi_set_hw_dev(dev, NULL);
 }
 
-static void __comedi_device_detach(comedi_device * dev)
+static void __comedi_device_detach(struct comedi_device *dev)
 {
 	dev->attached = 0;
 	if (dev->driver) {
@@ -107,16 +106,16 @@
 	cleanup_device(dev);
 }
 
-void comedi_device_detach(comedi_device * dev)
+void comedi_device_detach(struct comedi_device *dev)
 {
 	if (!dev->attached)
 		return;
 	__comedi_device_detach(dev);
 }
 
-int comedi_device_attach(comedi_device * dev, comedi_devconfig * it)
+int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
-	comedi_driver *driv;
+	struct comedi_driver *driv;
 	int ret;
 
 	if (dev->attached)
@@ -139,7 +138,7 @@
 				continue;
 			}
 		}
-		//initialize dev->driver here so comedi_error() can be called from attach
+		/* initialize dev->driver here so comedi_error() can be called from attach */
 		dev->driver = driv;
 		ret = driv->attach(dev, it);
 		if (ret < 0) {
@@ -150,8 +149,8 @@
 		goto attached;
 	}
 
-	// recognize has failed if we get here
-	// report valid board names before returning error
+	/*  recognize has failed if we get here */
+	/*  report valid board names before returning error */
 	for (driv = comedi_drivers; driv; driv = driv->next) {
 		if (!try_module_get(driv->module)) {
 			printk("comedi: failed to increment module count\n");
@@ -181,7 +180,7 @@
 	return 0;
 }
 
-int comedi_driver_register(comedi_driver * driver)
+int comedi_driver_register(struct comedi_driver *driver)
 {
 	driver->next = comedi_drivers;
 	comedi_drivers = driver;
@@ -189,15 +188,15 @@
 	return 0;
 }
 
-int comedi_driver_unregister(comedi_driver * driver)
+int comedi_driver_unregister(struct comedi_driver *driver)
 {
-	comedi_driver *prev;
+	struct comedi_driver *prev;
 	int i;
 
 	/* check for devices using this driver */
 	for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) {
 		struct comedi_device_file_info *dev_file_info = comedi_get_device_file_info(i);
-		comedi_device *dev;
+		struct comedi_device *dev;
 
 		if(dev_file_info == NULL) continue;
 		dev = dev_file_info->device;
@@ -225,11 +224,11 @@
 	return -EINVAL;
 }
 
-static int postconfig(comedi_device * dev)
+static int postconfig(struct comedi_device *dev)
 {
 	int i;
-	comedi_subdevice *s;
-	comedi_async *async = NULL;
+	struct comedi_subdevice *s;
+	struct comedi_async *async = NULL;
 	int ret;
 
 	for (i = 0; i < dev->n_subdevices; i++) {
@@ -246,7 +245,7 @@
 				SDF_CMD_WRITE)) == 0);
 			BUG_ON(!s->do_cmdtest);
 
-			async = kzalloc(sizeof(comedi_async), GFP_KERNEL);
+			async = kzalloc(sizeof(struct comedi_async), GFP_KERNEL);
 			if (async == NULL) {
 				printk("failed to allocate async struct\n");
 				return -ENOMEM;
@@ -298,8 +297,8 @@
 	return 0;
 }
 
-// generic recognize function for drivers that register their supported board names
-void *comedi_recognize(comedi_driver * driv, const char *name)
+/*  generic recognize function for drivers that register their supported board names */
+void *comedi_recognize(struct comedi_driver * driv, const char *name)
 {
 	unsigned i;
 	const char *const *name_ptr = driv->board_name;
@@ -314,7 +313,7 @@
 	return NULL;
 }
 
-void comedi_report_boards(comedi_driver * driv)
+void comedi_report_boards(struct comedi_driver *driv)
 {
 	unsigned int i;
 	const char *const *name_ptr;
@@ -332,28 +331,28 @@
 		printk(" %s\n", driv->driver_name);
 }
 
-static int poll_invalid(comedi_device * dev, comedi_subdevice * s)
+static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	return -EINVAL;
 }
 
-int insn_inval(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data)
+int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data)
 {
 	return -EINVAL;
 }
 
-static int insn_rw_emulate_bits(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data)
+static int insn_rw_emulate_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data)
 {
-	comedi_insn new_insn;
+	struct comedi_insn new_insn;
 	int ret;
 	static const unsigned channels_per_bitfield = 32;
 
 	unsigned chan = CR_CHAN(insn->chanspec);
 	const unsigned base_bitfield_channel =
 		(chan < channels_per_bitfield) ? 0 : chan;
-	lsampl_t new_data[2];
+	unsigned int new_data[2];
 	memset(new_data, 0, sizeof(new_data));
 	memset(&new_insn, 0, sizeof(new_insn));
 	new_insn.insn = INSN_BITS;
@@ -380,7 +379,7 @@
 	return 1;
 }
 
-static inline unsigned long uvirt_to_kva(pgd_t * pgd, unsigned long adr)
+static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
 {
 	unsigned long ret = 0UL;
 	pmd_t *pmd;
@@ -413,10 +412,10 @@
 	return kva;
 }
 
-int comedi_buf_alloc(comedi_device * dev, comedi_subdevice * s,
+int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
 	unsigned long new_size)
 {
-	comedi_async *async = s->async;
+	struct comedi_async *async = s->async;
 
 	/* Round up new_size to multiple of PAGE_SIZE */
 	new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK;
@@ -425,7 +424,7 @@
 	if (async->prealloc_buf && async->prealloc_bufsz == new_size) {
 		return 0;
 	}
-	// deallocate old buffer
+	/*  deallocate old buffer */
 	if (async->prealloc_buf) {
 		vunmap(async->prealloc_buf);
 		async->prealloc_buf = NULL;
@@ -454,7 +453,7 @@
 		async->buf_page_list = NULL;
 		async->n_buf_pages = 0;
 	}
-	// allocate new buffer
+	/*  allocate new buffer */
 	if (new_size) {
 		unsigned i = 0;
 		unsigned n_pages = new_size >> PAGE_SHIFT;
@@ -537,16 +536,15 @@
 
 /* munging is applied to data by core as it passes between user
  * and kernel space */
-unsigned int comedi_buf_munge(comedi_async * async, unsigned int num_bytes)
+unsigned int comedi_buf_munge(struct comedi_async *async, unsigned int num_bytes)
 {
-	comedi_subdevice *s = async->subdevice;
+	struct comedi_subdevice *s = async->subdevice;
 	unsigned int count = 0;
 	const unsigned num_sample_bytes = bytes_per_sample(s);
 
 	if (s->munge == NULL || (async->cmd.flags & CMDF_RAWDATA)) {
 		async->munge_count += num_bytes;
-		if ((int)(async->munge_count - async->buf_write_count) > 0)
-			BUG();
+		BUG_ON((int)(async->munge_count - async->buf_write_count) > 0);
 		return num_bytes;
 	}
 	/* don't munge partial samples */
@@ -567,7 +565,7 @@
 		s->munge(s->device, s, async->prealloc_buf + async->munge_ptr,
 			block_size, async->munge_chan);
 
-		smp_wmb();	//barrier insures data is munged in buffer before munge_count is incremented
+		smp_wmb();	/* barrier insures data is munged in buffer before munge_count is incremented */
 
 		async->munge_chan += block_size / num_sample_bytes;
 		async->munge_chan %= async->cmd.chanlist_len;
@@ -576,12 +574,11 @@
 		async->munge_ptr %= async->prealloc_bufsz;
 		count += block_size;
 	}
-	if ((int)(async->munge_count - async->buf_write_count) > 0)
-		BUG();
+	BUG_ON((int)(async->munge_count - async->buf_write_count) > 0);
 	return count;
 }
 
-unsigned int comedi_buf_write_n_available(comedi_async * async)
+unsigned int comedi_buf_write_n_available(struct comedi_async *async)
 {
 	unsigned int free_end;
 	unsigned int nbytes;
@@ -601,7 +598,7 @@
 }
 
 /* allocates chunk for the writer from free buffer space */
-unsigned int comedi_buf_write_alloc(comedi_async * async, unsigned int nbytes)
+unsigned int comedi_buf_write_alloc(struct comedi_async *async, unsigned int nbytes)
 {
 	unsigned int free_end = async->buf_read_count + async->prealloc_bufsz;
 
@@ -616,7 +613,7 @@
 }
 
 /* allocates nothing unless it can completely fulfill the request */
-unsigned int comedi_buf_write_alloc_strict(comedi_async * async,
+unsigned int comedi_buf_write_alloc_strict(struct comedi_async *async,
 	unsigned int nbytes)
 {
 	unsigned int free_end = async->buf_read_count + async->prealloc_bufsz;
@@ -632,7 +629,7 @@
 }
 
 /* transfers a chunk from writer to filled buffer space */
-unsigned comedi_buf_write_free(comedi_async * async, unsigned int nbytes)
+unsigned comedi_buf_write_free(struct comedi_async *async, unsigned int nbytes)
 {
 	if ((int)(async->buf_write_count + nbytes -
 			async->buf_write_alloc_count) > 0) {
@@ -650,7 +647,7 @@
 }
 
 /* allocates a chunk for the reader from filled (and munged) buffer space */
-unsigned comedi_buf_read_alloc(comedi_async * async, unsigned nbytes)
+unsigned comedi_buf_read_alloc(struct comedi_async *async, unsigned nbytes)
 {
 	if ((int)(async->buf_read_alloc_count + nbytes - async->munge_count) >
 		0) {
@@ -664,9 +661,9 @@
 }
 
 /* transfers control of a chunk from reader to free buffer space */
-unsigned comedi_buf_read_free(comedi_async * async, unsigned int nbytes)
+unsigned comedi_buf_read_free(struct comedi_async *async, unsigned int nbytes)
 {
-	// barrier insures data has been read out of buffer before read count is incremented
+	/*  barrier insures data has been read out of buffer before read count is incremented */
 	smp_mb();
 	if ((int)(async->buf_read_count + nbytes -
 			async->buf_read_alloc_count) > 0) {
@@ -680,7 +677,7 @@
 	return nbytes;
 }
 
-void comedi_buf_memcpy_to(comedi_async * async, unsigned int offset,
+void comedi_buf_memcpy_to(struct comedi_async *async, unsigned int offset,
 	const void *data, unsigned int num_bytes)
 {
 	unsigned int write_ptr = async->buf_write_ptr + offset;
@@ -705,7 +702,7 @@
 	}
 }
 
-void comedi_buf_memcpy_from(comedi_async * async, unsigned int offset,
+void comedi_buf_memcpy_from(struct comedi_async *async, unsigned int offset,
 	void *dest, unsigned int nbytes)
 {
 	void *src;
@@ -731,7 +728,7 @@
 	}
 }
 
-unsigned int comedi_buf_read_n_available(comedi_async * async)
+unsigned int comedi_buf_read_n_available(struct comedi_async *async)
 {
 	unsigned num_bytes;
 
@@ -746,32 +743,32 @@
 	return num_bytes;
 }
 
-int comedi_buf_get(comedi_async * async, sampl_t * x)
+int comedi_buf_get(struct comedi_async *async, short *x)
 {
 	unsigned int n = comedi_buf_read_n_available(async);
 
-	if (n < sizeof(sampl_t))
+	if (n < sizeof(short))
 		return 0;
-	comedi_buf_read_alloc(async, sizeof(sampl_t));
-	*x = *(sampl_t *) (async->prealloc_buf + async->buf_read_ptr);
-	comedi_buf_read_free(async, sizeof(sampl_t));
+	comedi_buf_read_alloc(async, sizeof(short));
+	*x = *(short *) (async->prealloc_buf + async->buf_read_ptr);
+	comedi_buf_read_free(async, sizeof(short));
 	return 1;
 }
 
-int comedi_buf_put(comedi_async * async, sampl_t x)
+int comedi_buf_put(struct comedi_async *async, short x)
 {
-	unsigned int n = comedi_buf_write_alloc_strict(async, sizeof(sampl_t));
+	unsigned int n = comedi_buf_write_alloc_strict(async, sizeof(short));
 
-	if (n < sizeof(sampl_t)) {
+	if (n < sizeof(short)) {
 		async->events |= COMEDI_CB_ERROR;
 		return 0;
 	}
-	*(sampl_t *) (async->prealloc_buf + async->buf_write_ptr) = x;
-	comedi_buf_write_free(async, sizeof(sampl_t));
+	*(short *) (async->prealloc_buf + async->buf_write_ptr) = x;
+	comedi_buf_write_free(async, sizeof(short));
 	return 1;
 }
 
-void comedi_reset_async_buf(comedi_async * async)
+void comedi_reset_async_buf(struct comedi_async *async)
 {
 	async->buf_write_alloc_count = 0;
 	async->buf_write_count = 0;
@@ -792,14 +789,27 @@
 
 int comedi_auto_config(struct device *hardware_device, const char *board_name, const int *options, unsigned num_options)
 {
-	comedi_devconfig it;
+	struct comedi_devconfig it;
 	int minor;
 	struct comedi_device_file_info *dev_file_info;
 	int retval;
+	unsigned *private_data = NULL;
+
+	if (!comedi_autoconfig) {
+		dev_set_drvdata(hardware_device, NULL);
+		return 0;
+	}
 
 	minor = comedi_alloc_board_minor(hardware_device);
 	if(minor < 0) return minor;
-	dev_set_drvdata(hardware_device, (void*)(unsigned long)minor);
+
+	private_data = kmalloc(sizeof(unsigned), GFP_KERNEL);
+	if (private_data == NULL) {
+		retval = -ENOMEM;
+		goto cleanup;
+	}
+	*private_data = minor;
+	dev_set_drvdata(hardware_device, private_data);
 
 	dev_file_info = comedi_get_device_file_info(minor);
 
@@ -812,8 +822,11 @@
 	mutex_lock(&dev_file_info->device->mutex);
 	retval = comedi_device_attach(dev_file_info->device, &it);
 	mutex_unlock(&dev_file_info->device->mutex);
+
+cleanup:
 	if(retval < 0)
 	{
+		kfree(private_data);
 		comedi_free_board_minor(minor);
 	}
 	return retval;
@@ -821,20 +834,23 @@
 
 void comedi_auto_unconfig(struct device *hardware_device)
 {
-	unsigned long minor = (unsigned long)dev_get_drvdata(hardware_device);
+	unsigned *minor = (unsigned *)dev_get_drvdata(hardware_device);
+	if(minor == NULL) return;
 
-	BUG_ON(minor >= COMEDI_NUM_BOARD_MINORS);
+	BUG_ON(*minor >= COMEDI_NUM_BOARD_MINORS);
 
-	comedi_free_board_minor(minor);
+	comedi_free_board_minor(*minor);
+	dev_set_drvdata(hardware_device, NULL);
+	kfree(minor);
 }
 
 int comedi_pci_auto_config(struct pci_dev *pcidev, const char *board_name)
 {
 	int options[2];
 
-	// pci bus
+	/*  pci bus */
 	options[0] = pcidev->bus->number;
-	// pci slot
+	/*  pci slot */
 	options[1] = PCI_SLOT(pcidev->devfn);
 
 	return comedi_auto_config(&pcidev->dev, board_name, options, sizeof(options) / sizeof(options[0]));
@@ -844,3 +860,16 @@
 {
 	comedi_auto_unconfig(&pcidev->dev);
 }
+
+int comedi_usb_auto_config(struct usb_device *usbdev,
+	const char *board_name)
+{
+	BUG_ON(usbdev == NULL);
+	return comedi_auto_config(&usbdev->dev, board_name, NULL, 0);
+}
+
+void comedi_usb_auto_unconfig(struct usb_device *usbdev)
+{
+	BUG_ON(usbdev == NULL);
+	comedi_auto_unconfig(&usbdev->dev);
+}
diff --git a/drivers/staging/comedi/drivers/8253.h b/drivers/staging/comedi/drivers/8253.h
new file mode 100644
index 0000000..08a11a5
--- /dev/null
+++ b/drivers/staging/comedi/drivers/8253.h
@@ -0,0 +1,420 @@
+/*
+    comedi/drivers/8253.h
+    Header file for 8253
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000 David A. Schleef <ds@schleef.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.
+
+    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 _8253_H
+#define _8253_H
+
+#ifndef CMDTEST
+#include "../comedi.h"
+#else
+#include "../comedi.h"
+#endif
+
+#define i8253_cascade_ns_to_timer i8253_cascade_ns_to_timer_2div
+
+static inline void i8253_cascade_ns_to_timer_2div_old(int i8253_osc_base,
+	unsigned int *d1, unsigned int *d2, unsigned int *nanosec,
+	int round_mode)
+{
+	int divider;
+	int div1, div2;
+	int div1_glb, div2_glb, ns_glb;
+	int div1_lub, div2_lub, ns_lub;
+	int ns;
+
+	divider = (*nanosec + i8253_osc_base / 2) / i8253_osc_base;
+
+	/* find 2 integers 1<={x,y}<=65536 such that x*y is
+	   close to divider */
+
+	div1_lub = div2_lub = 0;
+	div1_glb = div2_glb = 0;
+
+	ns_glb = 0;
+	ns_lub = 0xffffffff;
+
+	div2 = 0x10000;
+	for (div1 = divider / 65536 + 1; div1 < div2; div1++) {
+		div2 = divider / div1;
+
+		ns = i8253_osc_base * div1 * div2;
+		if (ns <= *nanosec && ns > ns_glb) {
+			ns_glb = ns;
+			div1_glb = div1;
+			div2_glb = div2;
+		}
+
+		div2++;
+		if (div2 <= 65536) {
+			ns = i8253_osc_base * div1 * div2;
+			if (ns > *nanosec && ns < ns_lub) {
+				ns_lub = ns;
+				div1_lub = div1;
+				div2_lub = div2;
+			}
+		}
+	}
+
+	*nanosec = div1_lub * div2_lub * i8253_osc_base;
+	*d1 = div1_lub & 0xffff;
+	*d2 = div2_lub & 0xffff;
+	return;
+}
+
+static inline void i8253_cascade_ns_to_timer_power(int i8253_osc_base,
+	unsigned int *d1, unsigned int *d2, unsigned int *nanosec,
+	int round_mode)
+{
+	int div1, div2;
+	int base;
+
+	for (div1 = 2; div1 <= (1 << 16); div1 <<= 1) {
+		base = i8253_osc_base * div1;
+		round_mode &= TRIG_ROUND_MASK;
+		switch (round_mode) {
+		case TRIG_ROUND_NEAREST:
+		default:
+			div2 = (*nanosec + base / 2) / base;
+			break;
+		case TRIG_ROUND_DOWN:
+			div2 = (*nanosec) / base;
+			break;
+		case TRIG_ROUND_UP:
+			div2 = (*nanosec + base - 1) / base;
+			break;
+		}
+		if (div2 < 2)
+			div2 = 2;
+		if (div2 <= 65536) {
+			*nanosec = div2 * base;
+			*d1 = div1 & 0xffff;
+			*d2 = div2 & 0xffff;
+			return;
+		}
+	}
+
+	/* shouldn't get here */
+	div1 = 0x10000;
+	div2 = 0x10000;
+	*nanosec = div1 * div2 * i8253_osc_base;
+	*d1 = div1 & 0xffff;
+	*d2 = div2 & 0xffff;
+}
+
+static inline void i8253_cascade_ns_to_timer_2div(int i8253_osc_base,
+	unsigned int *d1, unsigned int *d2, unsigned int *nanosec,
+	int round_mode)
+{
+	unsigned int divider;
+	unsigned int div1, div2;
+	unsigned int div1_glb, div2_glb, ns_glb;
+	unsigned int div1_lub, div2_lub, ns_lub;
+	unsigned int ns;
+	unsigned int start;
+	unsigned int ns_low, ns_high;
+	static const unsigned int max_count = 0x10000;
+	/* exit early if everything is already correct (this can save time
+	 * since this function may be called repeatedly during command tests
+	 * and execution) */
+	div1 = *d1 ? *d1 : max_count;
+	div2 = *d2 ? *d2 : max_count;
+	divider = div1 * div2;
+	if (div1 * div2 * i8253_osc_base == *nanosec &&
+		div1 > 1 && div1 <= max_count &&
+		div2 > 1 && div2 <= max_count &&
+		/* check for overflow */
+		divider > div1 && divider > div2 &&
+		divider * i8253_osc_base > divider &&
+		divider * i8253_osc_base > i8253_osc_base) {
+		return;
+	}
+
+	divider = *nanosec / i8253_osc_base;
+
+	div1_lub = div2_lub = 0;
+	div1_glb = div2_glb = 0;
+
+	ns_glb = 0;
+	ns_lub = 0xffffffff;
+
+	div2 = max_count;
+	start = divider / div2;
+	if (start < 2)
+		start = 2;
+	for (div1 = start; div1 <= divider / div1 + 1 && div1 <= max_count;
+		div1++) {
+		for (div2 = divider / div1;
+			div1 * div2 <= divider + div1 + 1 && div2 <= max_count;
+			div2++) {
+			ns = i8253_osc_base * div1 * div2;
+			if (ns <= *nanosec && ns > ns_glb) {
+				ns_glb = ns;
+				div1_glb = div1;
+				div2_glb = div2;
+			}
+			if (ns >= *nanosec && ns < ns_lub) {
+				ns_lub = ns;
+				div1_lub = div1;
+				div2_lub = div2;
+			}
+		}
+	}
+
+	round_mode &= TRIG_ROUND_MASK;
+	switch (round_mode) {
+	case TRIG_ROUND_NEAREST:
+	default:
+		ns_high = div1_lub * div2_lub * i8253_osc_base;
+		ns_low = div1_glb * div2_glb * i8253_osc_base;
+		if (ns_high - *nanosec < *nanosec - ns_low) {
+			div1 = div1_lub;
+			div2 = div2_lub;
+		} else {
+			div1 = div1_glb;
+			div2 = div2_glb;
+		}
+		break;
+	case TRIG_ROUND_UP:
+		div1 = div1_lub;
+		div2 = div2_lub;
+		break;
+	case TRIG_ROUND_DOWN:
+		div1 = div1_glb;
+		div2 = div2_glb;
+		break;
+	}
+
+	*nanosec = div1 * div2 * i8253_osc_base;
+	*d1 = div1 & 0xffff;	// masking is done since counter maps zero to 0x10000
+	*d2 = div2 & 0xffff;
+	return;
+}
+
+#ifndef CMDTEST
+/* i8254_load programs 8254 counter chip.  It should also work for the 8253.
+ * base_address is the lowest io address for the chip (the address of counter 0).
+ * counter_number is the counter you want to load (0,1 or 2)
+ * count is the number to load into the counter.
+ *
+ * You probably want to use mode 2.
+ *
+ * Use i8254_mm_load() if you board uses memory-mapped io, it is
+ * the same as i8254_load() except it uses writeb() instead of outb().
+ *
+ * Neither i8254_load() or i8254_read() do their loading/reading
+ * atomically.  The 16 bit read/writes are performed with two successive
+ * 8 bit read/writes.  So if two parts of your driver do a load/read on
+ * the same counter, it may be necessary to protect these functions
+ * with a spinlock.
+ *
+ * FMH
+ */
+
+#define i8254_control_reg	3
+
+static inline int i8254_load(unsigned long base_address, unsigned int regshift,
+	unsigned int counter_number, unsigned int count, unsigned int mode)
+{
+	unsigned int byte;
+
+	if (counter_number > 2)
+		return -1;
+	if (count > 0xffff)
+		return -1;
+	if (mode > 5)
+		return -1;
+	if ((mode == 2 || mode == 3) && count == 1)
+		return -1;
+
+	byte = counter_number << 6;
+	byte |= 0x30;		// load low then high byte
+	byte |= (mode << 1);	// set counter mode
+	outb(byte, base_address + (i8254_control_reg << regshift));
+	byte = count & 0xff;	// lsb of counter value
+	outb(byte, base_address + (counter_number << regshift));
+	byte = (count >> 8) & 0xff;	// msb of counter value
+	outb(byte, base_address + (counter_number << regshift));
+
+	return 0;
+}
+
+static inline int i8254_mm_load(void *base_address, unsigned int regshift,
+	unsigned int counter_number, unsigned int count, unsigned int mode)
+{
+	unsigned int byte;
+
+	if (counter_number > 2)
+		return -1;
+	if (count > 0xffff)
+		return -1;
+	if (mode > 5)
+		return -1;
+	if ((mode == 2 || mode == 3) && count == 1)
+		return -1;
+
+	byte = counter_number << 6;
+	byte |= 0x30;		// load low then high byte
+	byte |= (mode << 1);	// set counter mode
+	writeb(byte, base_address + (i8254_control_reg << regshift));
+	byte = count & 0xff;	// lsb of counter value
+	writeb(byte, base_address + (counter_number << regshift));
+	byte = (count >> 8) & 0xff;	// msb of counter value
+	writeb(byte, base_address + (counter_number << regshift));
+
+	return 0;
+}
+
+/* Returns 16 bit counter value, should work for 8253 also.*/
+static inline int i8254_read(unsigned long base_address, unsigned int regshift,
+	unsigned int counter_number)
+{
+	unsigned int byte;
+	int ret;
+
+	if (counter_number > 2)
+		return -1;
+
+	// latch counter
+	byte = counter_number << 6;
+	outb(byte, base_address + (i8254_control_reg << regshift));
+
+	// read lsb
+	ret = inb(base_address + (counter_number << regshift));
+	// read msb
+	ret += inb(base_address + (counter_number << regshift)) << 8;
+
+	return ret;
+}
+
+static inline int i8254_mm_read(void *base_address, unsigned int regshift,
+	unsigned int counter_number)
+{
+	unsigned int byte;
+	int ret;
+
+	if (counter_number > 2)
+		return -1;
+
+	// latch counter
+	byte = counter_number << 6;
+	writeb(byte, base_address + (i8254_control_reg << regshift));
+
+	// read lsb
+	ret = readb(base_address + (counter_number << regshift));
+	// read msb
+	ret += readb(base_address + (counter_number << regshift)) << 8;
+
+	return ret;
+}
+
+/* Loads 16 bit initial counter value, should work for 8253 also. */
+static inline void i8254_write(unsigned long base_address,
+	unsigned int regshift, unsigned int counter_number, unsigned int count)
+{
+	unsigned int byte;
+
+	if (counter_number > 2)
+		return;
+
+	byte = count & 0xff;	// lsb of counter value
+	outb(byte, base_address + (counter_number << regshift));
+	byte = (count >> 8) & 0xff;	// msb of counter value
+	outb(byte, base_address + (counter_number << regshift));
+}
+
+static inline void i8254_mm_write(void *base_address,
+	unsigned int regshift, unsigned int counter_number, unsigned int count)
+{
+	unsigned int byte;
+
+	if (counter_number > 2)
+		return;
+
+	byte = count & 0xff;	// lsb of counter value
+	writeb(byte, base_address + (counter_number << regshift));
+	byte = (count >> 8) & 0xff;	// msb of counter value
+	writeb(byte, base_address + (counter_number << regshift));
+}
+
+/* Set counter mode, should work for 8253 also.
+ * Note: the 'mode' value is different to that for i8254_load() and comes
+ * from the INSN_CONFIG_8254_SET_MODE command:
+ *   I8254_MODE0, I8254_MODE1, ..., I8254_MODE5
+ * OR'ed with:
+ *   I8254_BCD, I8254_BINARY
+ */
+static inline int i8254_set_mode(unsigned long base_address,
+	unsigned int regshift, unsigned int counter_number, unsigned int mode)
+{
+	unsigned int byte;
+
+	if (counter_number > 2)
+		return -1;
+	if (mode > (I8254_MODE5 | I8254_BINARY))
+		return -1;
+
+	byte = counter_number << 6;
+	byte |= 0x30;		// load low then high byte
+	byte |= mode;		// set counter mode and BCD|binary
+	outb(byte, base_address + (i8254_control_reg << regshift));
+
+	return 0;
+}
+
+static inline int i8254_mm_set_mode(void *base_address,
+	unsigned int regshift, unsigned int counter_number, unsigned int mode)
+{
+	unsigned int byte;
+
+	if (counter_number > 2)
+		return -1;
+	if (mode > (I8254_MODE5 | I8254_BINARY))
+		return -1;
+
+	byte = counter_number << 6;
+	byte |= 0x30;		// load low then high byte
+	byte |= mode;		// set counter mode and BCD|binary
+	writeb(byte, base_address + (i8254_control_reg << regshift));
+
+	return 0;
+}
+
+static inline int i8254_status(unsigned long base_address,
+	unsigned int regshift, unsigned int counter_number)
+{
+	outb(0xE0 | (2 << counter_number),
+		base_address + (i8254_control_reg << regshift));
+	return inb(base_address + (counter_number << regshift));
+}
+
+static inline int i8254_mm_status(void *base_address,
+	unsigned int regshift, unsigned int counter_number)
+{
+	writeb(0xE0 | (2 << counter_number),
+		base_address + (i8254_control_reg << regshift));
+	return readb(base_address + (counter_number << regshift));
+}
+
+#endif
+
+#endif
diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c
new file mode 100644
index 0000000..0369c7c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/8255.c
@@ -0,0 +1,442 @@
+/*
+    comedi/drivers/8255.c
+    Driver for 8255
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 1998 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: 8255
+Description: generic 8255 support
+Devices: [standard] 8255 (8255)
+Author: ds
+Status: works
+Updated: Fri,  7 Jun 2002 12:56:45 -0700
+
+The classic in digital I/O.  The 8255 appears in Comedi as a single
+digital I/O subdevice with 24 channels.  The channel 0 corresponds
+to the 8255's port A, bit 0; channel 23 corresponds to port C, bit
+7.  Direction configuration is done in blocks, with channels 0-7,
+8-15, 16-19, and 20-23 making up the 4 blocks.  The only 8255 mode
+supported is mode 0.
+
+You should enable compilation this driver if you plan to use a board
+that has an 8255 chip.  For multifunction boards, the main driver will
+configure the 8255 subdevice automatically.
+
+This driver also works independently with ISA and PCI cards that
+directly map the 8255 registers to I/O ports, including cards with
+multiple 8255 chips.  To configure the driver for such a card, the
+option list should be a list of the I/O port bases for each of the
+8255 chips.  For example,
+
+  comedi_config /dev/comedi0 8255 0x200,0x204,0x208,0x20c
+
+Note that most PCI 8255 boards do NOT work with this driver, and
+need a separate driver as a wrapper.  For those that do work, the
+I/O port base address can be found in the output of 'lspci -v'.
+
+*/
+
+/*
+   This file contains an exported subdevice for driving an 8255.
+
+   To use this subdevice as part of another driver, you need to
+   set up the subdevice in the attach function of the driver by
+   calling:
+
+     subdev_8255_init(device, subdevice, callback_function, arg)
+
+   device and subdevice are pointers to the device and subdevice
+   structures.  callback_function will be called to provide the
+   low-level input/output to the device, i.e., actual register
+   access.  callback_function will be called with the value of arg
+   as the last parameter.  If the 8255 device is mapped as 4
+   consecutive I/O ports, you can use NULL for callback_function
+   and the I/O port base for arg, and an internal function will
+   handle the register access.
+
+   In addition, if the main driver handles interrupts, you can
+   enable commands on the subdevice by calling subdev_8255_init_irq()
+   instead.  Then, when you get an interrupt that is likely to be
+   from the 8255, you should call subdev_8255_interrupt(), which
+   will copy the latched value to a Comedi buffer.
+ */
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define _8255_SIZE 4
+
+#define _8255_DATA 0
+#define _8255_CR 3
+
+#define CR_C_LO_IO	0x01
+#define CR_B_IO		0x02
+#define CR_B_MODE	0x04
+#define CR_C_HI_IO	0x08
+#define CR_A_IO		0x10
+#define CR_A_MODE(a)	((a)<<5)
+#define CR_CW		0x80
+
+struct subdev_8255_struct {
+	unsigned long cb_arg;
+	int (*cb_func) (int, int, int, unsigned long);
+	int have_irq;
+};
+
+#define CALLBACK_ARG	(((struct subdev_8255_struct *)s->private)->cb_arg)
+#define CALLBACK_FUNC	(((struct subdev_8255_struct *)s->private)->cb_func)
+#define subdevpriv	((struct subdev_8255_struct *)s->private)
+
+static int dev_8255_attach(struct comedi_device *dev, struct comedi_devconfig * it);
+static int dev_8255_detach(struct comedi_device *dev);
+static struct comedi_driver driver_8255 = {
+      driver_name:"8255",
+      module:THIS_MODULE,
+      attach:dev_8255_attach,
+      detach:dev_8255_detach,
+};
+
+COMEDI_INITCLEANUP(driver_8255);
+
+static void do_config(struct comedi_device *dev, struct comedi_subdevice * s);
+
+void subdev_8255_interrupt(struct comedi_device *dev, struct comedi_subdevice * s)
+{
+	short d;
+
+	d = CALLBACK_FUNC(0, _8255_DATA, 0, CALLBACK_ARG);
+	d |= (CALLBACK_FUNC(0, _8255_DATA + 1, 0, CALLBACK_ARG) << 8);
+
+	comedi_buf_put(s->async, d);
+	s->async->events |= COMEDI_CB_EOS;
+
+	comedi_event(dev, s);
+}
+
+static int subdev_8255_cb(int dir, int port, int data, unsigned long arg)
+{
+	unsigned long iobase = arg;
+
+	if (dir) {
+		outb(data, iobase + port);
+		return 0;
+	} else {
+		return inb(iobase + port);
+	}
+}
+
+static int subdev_8255_insn(struct comedi_device *dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= (data[0] & data[1]);
+
+		if (data[0] & 0xff)
+			CALLBACK_FUNC(1, _8255_DATA, s->state & 0xff,
+				CALLBACK_ARG);
+		if (data[0] & 0xff00)
+			CALLBACK_FUNC(1, _8255_DATA + 1, (s->state >> 8) & 0xff,
+				CALLBACK_ARG);
+		if (data[0] & 0xff0000)
+			CALLBACK_FUNC(1, _8255_DATA + 2,
+				(s->state >> 16) & 0xff, CALLBACK_ARG);
+	}
+
+	data[1] = CALLBACK_FUNC(0, _8255_DATA, 0, CALLBACK_ARG);
+	data[1] |= (CALLBACK_FUNC(0, _8255_DATA + 1, 0, CALLBACK_ARG) << 8);
+	data[1] |= (CALLBACK_FUNC(0, _8255_DATA + 2, 0, CALLBACK_ARG) << 16);
+
+	return 2;
+}
+
+static int subdev_8255_insn_config(struct comedi_device *dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int mask;
+	unsigned int bits;
+
+	mask = 1 << CR_CHAN(insn->chanspec);
+	if (mask & 0x0000ff) {
+		bits = 0x0000ff;
+	} else if (mask & 0x00ff00) {
+		bits = 0x00ff00;
+	} else if (mask & 0x0f0000) {
+		bits = 0x0f0000;
+	} else {
+		bits = 0xf00000;
+	}
+
+	switch (data[0]) {
+	case INSN_CONFIG_DIO_INPUT:
+		s->io_bits &= ~bits;
+		break;
+	case INSN_CONFIG_DIO_OUTPUT:
+		s->io_bits |= bits;
+		break;
+	case INSN_CONFIG_DIO_QUERY:
+		data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
+		return insn->n;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	do_config(dev, s);
+
+	return 1;
+}
+
+static void do_config(struct comedi_device *dev, struct comedi_subdevice * s)
+{
+	int config;
+
+	config = CR_CW;
+	/* 1 in io_bits indicates output, 1 in config indicates input */
+	if (!(s->io_bits & 0x0000ff))
+		config |= CR_A_IO;
+	if (!(s->io_bits & 0x00ff00))
+		config |= CR_B_IO;
+	if (!(s->io_bits & 0x0f0000))
+		config |= CR_C_LO_IO;
+	if (!(s->io_bits & 0xf00000))
+		config |= CR_C_HI_IO;
+	CALLBACK_FUNC(1, _8255_CR, config, CALLBACK_ARG);
+}
+
+static int subdev_8255_cmdtest(struct comedi_device *dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	unsigned int tmp;
+
+	/* step 1 */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_EXT;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_FOLLOW;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2 */
+
+	if (err)
+		return 2;
+
+	/* step 3 */
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+	if (cmd->scan_begin_arg != 0) {
+		cmd->scan_begin_arg = 0;
+		err++;
+	}
+	if (cmd->convert_arg != 0) {
+		cmd->convert_arg = 0;
+		err++;
+	}
+	if (cmd->scan_end_arg != 1) {
+		cmd->scan_end_arg = 1;
+		err++;
+	}
+	if (cmd->stop_arg != 0) {
+		cmd->stop_arg = 0;
+		err++;
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4 */
+
+	if (err)
+		return 4;
+
+	return 0;
+}
+
+static int subdev_8255_cmd(struct comedi_device *dev, struct comedi_subdevice * s)
+{
+	/* FIXME */
+
+	return 0;
+}
+
+static int subdev_8255_cancel(struct comedi_device *dev, struct comedi_subdevice * s)
+{
+	/* FIXME */
+
+	return 0;
+}
+
+int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice * s, int (*cb) (int,
+		int, int, unsigned long), unsigned long arg)
+{
+	s->type = COMEDI_SUBD_DIO;
+	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+	s->n_chan = 24;
+	s->range_table = &range_digital;
+	s->maxdata = 1;
+
+	s->private = kmalloc(sizeof(struct subdev_8255_struct), GFP_KERNEL);
+	if (!s->private)
+		return -ENOMEM;
+
+	CALLBACK_ARG = arg;
+	if (cb == NULL) {
+		CALLBACK_FUNC = subdev_8255_cb;
+	} else {
+		CALLBACK_FUNC = cb;
+	}
+	s->insn_bits = subdev_8255_insn;
+	s->insn_config = subdev_8255_insn_config;
+
+	s->state = 0;
+	s->io_bits = 0;
+	do_config(dev, s);
+
+	return 0;
+}
+
+int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice * s,
+	int (*cb) (int, int, int, unsigned long), unsigned long arg)
+{
+	int ret;
+
+	ret = subdev_8255_init(dev, s, cb, arg);
+	if (ret < 0)
+		return ret;
+
+	s->do_cmdtest = subdev_8255_cmdtest;
+	s->do_cmd = subdev_8255_cmd;
+	s->cancel = subdev_8255_cancel;
+
+	subdevpriv->have_irq = 1;
+
+	return 0;
+}
+
+void subdev_8255_cleanup(struct comedi_device *dev, struct comedi_subdevice * s)
+{
+	if (s->private) {
+		if (subdevpriv->have_irq) {
+		}
+
+		kfree(s->private);
+	}
+}
+
+/*
+
+   Start of the 8255 standalone device
+
+ */
+
+static int dev_8255_attach(struct comedi_device *dev, struct comedi_devconfig * it)
+{
+	int ret;
+	unsigned long iobase;
+	int i;
+
+	printk("comedi%d: 8255:", dev->minor);
+
+	dev->board_name = "8255";
+
+	for (i = 0; i < COMEDI_NDEVCONFOPTS; i++) {
+		iobase = it->options[i];
+		if (!iobase)
+			break;
+	}
+	if (i == 0) {
+		printk(" no devices specified\n");
+		return -EINVAL;
+	}
+
+	if ((ret = alloc_subdevices(dev, i)) < 0)
+		return ret;
+
+	for (i = 0; i < dev->n_subdevices; i++) {
+		iobase = it->options[i];
+
+		printk(" 0x%04lx", iobase);
+		if (!request_region(iobase, _8255_SIZE, "8255")) {
+			printk(" (I/O port conflict)");
+
+			dev->subdevices[i].type = COMEDI_SUBD_UNUSED;
+		} else {
+			subdev_8255_init(dev, dev->subdevices + i, NULL,
+				iobase);
+		}
+	}
+
+	printk("\n");
+
+	return 0;
+}
+
+static int dev_8255_detach(struct comedi_device *dev)
+{
+	int i;
+	unsigned long iobase;
+	struct comedi_subdevice *s;
+
+	printk("comedi%d: 8255: remove\n", dev->minor);
+
+	for (i = 0; i < dev->n_subdevices; i++) {
+		s = dev->subdevices + i;
+		if (s->type != COMEDI_SUBD_UNUSED) {
+			iobase = CALLBACK_ARG;
+			release_region(iobase, _8255_SIZE);
+		}
+		subdev_8255_cleanup(dev, s);
+	}
+
+	return 0;
+}
+
+EXPORT_SYMBOL(subdev_8255_init);
+EXPORT_SYMBOL(subdev_8255_init_irq);
+EXPORT_SYMBOL(subdev_8255_cleanup);
+EXPORT_SYMBOL(subdev_8255_interrupt);
diff --git a/drivers/staging/comedi/drivers/8255.h b/drivers/staging/comedi/drivers/8255.h
new file mode 100644
index 0000000..979311b
--- /dev/null
+++ b/drivers/staging/comedi/drivers/8255.h
@@ -0,0 +1,57 @@
+/*
+    module/8255.h
+    Header file for 8255
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 1998 David A. Schleef <ds@schleef.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.
+
+    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 _8255_H
+#define _8255_H
+
+#include "../comedidev.h"
+
+#if defined(CONFIG_COMEDI_8255) || defined(CONFIG_COMEDI_8255_MODULE)
+
+int subdev_8255_init(struct comedi_device * dev, struct comedi_subdevice * s,
+	int (*cb) (int, int, int, unsigned long), unsigned long arg);
+int subdev_8255_init_irq(struct comedi_device * dev, struct comedi_subdevice * s,
+	int (*cb) (int, int, int, unsigned long), unsigned long arg);
+void subdev_8255_cleanup(struct comedi_device * dev, struct comedi_subdevice * s);
+void subdev_8255_interrupt(struct comedi_device * dev, struct comedi_subdevice * s);
+
+#else
+
+static inline int subdev_8255_init(struct comedi_device * dev, struct comedi_subdevice * s,
+	void *x, unsigned long y)
+{
+	printk("8255 support not configured -- disabling subdevice\n");
+
+	s->type = COMEDI_SUBD_UNUSED;
+
+	return 0;
+}
+
+static inline void subdev_8255_cleanup(struct comedi_device * dev,
+	struct comedi_subdevice * s)
+{
+}
+
+#endif
+
+#endif
diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile
index eb7a615..12d6e43 100644
--- a/drivers/staging/comedi/drivers/Makefile
+++ b/drivers/staging/comedi/drivers/Makefile
@@ -8,12 +8,121 @@
 obj-$(CONFIG_COMEDI)			+= comedi_parport.o
 
 # Comedi PCI drivers
-obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= mite.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= 8255.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= acl7225b.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= addi_apci_035.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= addi_apci_1032.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= addi_apci_1500.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= addi_apci_1516.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= addi_apci_1564.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= addi_apci_16xx.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= addi_apci_2016.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= addi_apci_2032.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= addi_apci_2200.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= addi_apci_3001.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= addi_apci_3120.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= addi_apci_3501.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= addi_apci_3xxx.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= adl_pci6208.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= adl_pci7296.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= adl_pci7432.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= adl_pci8164.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= adl_pci9111.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= adl_pci9118.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= adq12b.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= adv_pci1710.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= adv_pci1723.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= adv_pci_dio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= aio_aio12_8.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= aio_iiro_16.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= amplc_dio200.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= amplc_pc236.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= amplc_pc263.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= amplc_pci224.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= amplc_pci230.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= c6xdigio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= cb_pcidas64.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= cb_pcidas.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= cb_pcidda.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= cb_pcidio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= cb_pcimdas.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= cb_pcimdda.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= comedi_bond.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= comedi_parport.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= comedi_test.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= contec_pci_dio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= daqboard2000.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= das08.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= das16m1.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= das16.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= das1800.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= das6402.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= das800.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= dmm32at.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= dt2801.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= dt2811.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= dt2814.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= dt2815.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= dt2817.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= dt282x.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= dt3000.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= fl512.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= gsc_hpdi.o
 obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= icp_multi.o
-obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= me_daq.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= ii_pci20kc.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= jr3_pci.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= ke_counter.o
 obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= me4000.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= me_daq.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= mite.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= mpc624.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= multiq3.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= ni_6527.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= ni_65xx.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= ni_660x.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= ni_670x.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= ni_at_a2150.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= ni_at_ao.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= ni_atmio16d.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= ni_atmio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= ni_labpc.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= ni_pcidio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= ni_pcimio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= ni_tiocmd.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= ni_tio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= pcl711.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= pcl724.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= pcl725.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= pcl726.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= pcl730.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= pcl812.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= pcl816.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= pcl818.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= pcm3724.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= pcm3730.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= pcmad.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= pcmda12.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= pcmmio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= pcmuio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= poc.o
 obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= rtd520.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= rti800.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= rti802.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= s526.o
 obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= s626.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= serial2002.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= skel.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= ssv_dnp.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS)	+= unioxx5.o
+
+# Comedi PCMCIA drivers
+obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS)	+= cb_das16_cs.o
+obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS)	+= das08_cs.o
+obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS)	+= ni_daq_700.o
+obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS)	+= ni_daq_dio24.o
+obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS)	+= ni_labpc_cs.o
+obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS)	+= ni_mio_cs.o
+obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS)	+= quatech_daqp_cs.o
 
 # Comedi USB drivers
 obj-$(CONFIG_COMEDI_USB_DRIVERS)	+= usbdux.o
diff --git a/drivers/staging/comedi/drivers/acl7225b.c b/drivers/staging/comedi/drivers/acl7225b.c
new file mode 100644
index 0000000..b21320f
--- /dev/null
+++ b/drivers/staging/comedi/drivers/acl7225b.c
@@ -0,0 +1,149 @@
+/*
+ * comedi/drivers/acl7225b.c
+ * Driver for Adlink NuDAQ ACL-7225b and clones
+ * José Luis Sánchez
+ */
+/*
+Driver: acl7225b
+Description: Adlink NuDAQ ACL-7225b & compatibles
+Author: José Luis Sánchez (jsanchezv@teleline.es)
+Status: testing
+Devices: [Adlink] ACL-7225b (acl7225b), [ICP] P16R16DIO (p16r16dio)
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define ACL7225_SIZE   8	/* Requires 8 ioports, but only 4 are used */
+#define P16R16DIO_SIZE 4
+#define ACL7225_RIO_LO 0	/* Relays input/output low byte (R0-R7) */
+#define ACL7225_RIO_HI 1	/* Relays input/output high byte (R8-R15) */
+#define ACL7225_DI_LO  2	/* Digital input low byte (DI0-DI7) */
+#define ACL7225_DI_HI  3	/* Digital input high byte (DI8-DI15) */
+
+static int acl7225b_attach(struct comedi_device *dev, struct comedi_devconfig * it);
+static int acl7225b_detach(struct comedi_device *dev);
+
+struct boardtype {
+	const char *name;	// driver name
+	int io_range;		// len of I/O space
+};
+
+static const struct boardtype boardtypes[] = {
+	{"acl7225b", ACL7225_SIZE,},
+	{"p16r16dio", P16R16DIO_SIZE,},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype))
+#define this_board ((const struct boardtype *)dev->board_ptr)
+
+static struct comedi_driver driver_acl7225b = {
+      driver_name:"acl7225b",
+      module:THIS_MODULE,
+      attach:acl7225b_attach,
+      detach:acl7225b_detach,
+      board_name:&boardtypes[0].name,
+      num_names:n_boardtypes,
+      offset:sizeof(struct boardtype),
+};
+
+COMEDI_INITCLEANUP(driver_acl7225b);
+
+static int acl7225b_do_insn(struct comedi_device *dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= (data[0] & data[1]);
+	}
+	if (data[0] & 0x00ff)
+		outb(s->state & 0xff, dev->iobase + (unsigned long)s->private);
+	if (data[0] & 0xff00)
+		outb((s->state >> 8),
+			dev->iobase + (unsigned long)s->private + 1);
+
+	data[1] = s->state;
+
+	return 2;
+}
+
+static int acl7225b_di_insn(struct comedi_device *dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	data[1] = inb(dev->iobase + (unsigned long)s->private) |
+		(inb(dev->iobase + (unsigned long)s->private + 1) << 8);
+
+	return 2;
+}
+
+static int acl7225b_attach(struct comedi_device *dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	int iobase, iorange;
+
+	iobase = it->options[0];
+	iorange = this_board->io_range;
+	printk("comedi%d: acl7225b: board=%s 0x%04x ", dev->minor,
+		this_board->name, iobase);
+	if (!request_region(iobase, iorange, "acl7225b")) {
+		printk("I/O port conflict\n");
+		return -EIO;
+	}
+	dev->board_name = this_board->name;
+	dev->iobase = iobase;
+	dev->irq = 0;
+
+	if (alloc_subdevices(dev, 3) < 0)
+		return -ENOMEM;
+
+	s = dev->subdevices + 0;
+	/* Relays outputs */
+	s->type = COMEDI_SUBD_DO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->maxdata = 1;
+	s->n_chan = 16;
+	s->insn_bits = acl7225b_do_insn;
+	s->range_table = &range_digital;
+	s->private = (void *)ACL7225_RIO_LO;
+
+	s = dev->subdevices + 1;
+	/* Relays status */
+	s->type = COMEDI_SUBD_DI;
+	s->subdev_flags = SDF_READABLE;
+	s->maxdata = 1;
+	s->n_chan = 16;
+	s->insn_bits = acl7225b_di_insn;
+	s->range_table = &range_digital;
+	s->private = (void *)ACL7225_RIO_LO;
+
+	s = dev->subdevices + 2;
+	/* Isolated digital inputs */
+	s->type = COMEDI_SUBD_DI;
+	s->subdev_flags = SDF_READABLE;
+	s->maxdata = 1;
+	s->n_chan = 16;
+	s->insn_bits = acl7225b_di_insn;
+	s->range_table = &range_digital;
+	s->private = (void *)ACL7225_DI_LO;
+
+	printk("\n");
+
+	return 0;
+}
+
+static int acl7225b_detach(struct comedi_device *dev)
+{
+	printk("comedi%d: acl7225b: remove\n", dev->minor);
+
+	if (dev->iobase)
+		release_region(dev->iobase, this_board->io_range);
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c
new file mode 100644
index 0000000..c96aee0
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c
@@ -0,0 +1,1047 @@
+/*
+ *  Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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.
+ */
+/*
+  | Description :   APCI-1710 82X54 timer module                          |
+*/
+
+#include "APCI1710_82x54.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_     i_APCI1710_InitTimer                         |
+|                               (BYTE_   b_BoardHandle,                      |
+|                                BYTE_   b_ModulNbr,                         |
+|                                BYTE_   b_TimerNbr,                         |
+|                                BYTE_   b_TimerMode,                        |
+|                                ULONG_ ul_ReloadValue,                      |
+|                                BYTE_   b_InputClockSelection,              |
+|                                BYTE_   b_InputClockLevel,                  |
+|                                BYTE_   b_OutputLevel,                      |
+|                                BYTE_   b_HardwareGateLevel)
+INT i_InsnConfig_InitTimer(struct comedi_device *dev,struct comedi_subdevice *s,
+	struct comedi_insn *insn,unsigned int *data)
+|
++----------------------------------------------------------------------------+
+| Task              : Configure the Timer (b_TimerNbr) operating mode        |
+|                     (b_TimerMode) from selected module (b_ModulNbr).       |
+|                     You must calling this function be for you call any     |
+|                     other function witch access of the timer.              |
+|                                                                            |
+|                                                                            |
+|                       Timer mode description table                         |
+|                                                                            |
+|+--------+-----------------------------+--------------+--------------------+|
+||Selected+      Mode description       +u_ReloadValue | Hardware gate input||
+||  mode  |                             |  description |      action        ||
+|+--------+-----------------------------+--------------+--------------------+|
+||        |Mode 0 is typically used     |              |                    ||
+||        |for event counting. After    |              |                    ||
+||        |the initialisation, OUT      |              |                    ||
+||        |is initially low, and        |              |                    ||
+||   0    |will remain low until the    |Start counting|   Hardware gate    ||
+||        |counter reaches zero.        |   value      |                    ||
+||        |OUT then goes high and       |              |                    ||
+||        |remains high until a new     |              |                    ||
+||        |count is written. See        |              |                    ||
+||        |"i_APCI1710_WriteTimerValue" |              |                    ||
+||        |function.                    |              |                    ||
+|+--------+-----------------------------+--------------+--------------------+|
+||        |Mode 1 is similar to mode 0  |              |                    ||
+||        |except for the gate input    |              |                    ||
+||   1    |action. The gate input is not|Start counting|  Hardware trigger  ||
+||        |used for enabled or disabled |   value      |                    ||
+||        |the timer.                   |              |                    ||
+||        |The gate input is used for   |              |                    ||
+||        |triggered the timer.         |              |                    ||
+|+--------+-----------------------------+--------------+--------------------+|
+||        |This mode functions like a   |              |                    ||
+||        |divide-by-ul_ReloadValue     |              |                    ||
+||        |counter. It is typically used|              |                    ||
+||        |to generate a real time clock|              |                    ||
+||        |interrupt. OUT will initially|              |                    ||
+||   2    |be high after the            |   Division   |  Hardware gate     ||
+||        |initialisation. When the     |    factor    |                    ||
+||        |initial count has decremented|              |                    ||
+||        |to 1, OUT goes low for one   |              |                    ||
+||        |CLK pule. OUT then goes high |              |                    ||
+||        |again, the counter reloads   |              |                    ||
+||        |the initial count            |              |                    ||
+||        |(ul_ReloadValue) and the     |              |                    ||
+||        |process is repeated.         |              |                    ||
+||        |This action can generated a  |              |                    ||
+||        |interrupt. See function      |              |                    ||
+||        |"i_APCI1710_SetBoardInt-     |              |                    ||
+||        |RoutineX"                    |              |                    ||
+||        |and "i_APCI1710_EnableTimer" |              |                    ||
+|+--------+-----------------------------+--------------+--------------------+|
+||        |Mode 3 is typically used for |              |                    ||
+||        |baud rate generation. This   |              |                    ||
+||        |mode is similar to mode 2    |              |                    ||
+||        |except for the duty cycle of |              |                    ||
+||   3    |OUT. OUT will initially be   |  Division    |   Hardware gate    ||
+||        |high after the initialisation|   factor     |                    ||
+||        |When half the initial count  |              |                    ||
+||        |(ul_ReloadValue) has expired,|              |                    ||
+||        |OUT goes low for the         |              |                    ||
+||        |remainder of the count. The  |              |                    ||
+||        |mode is periodic; the        |              |                    ||
+||        |sequence above is repeated   |              |                    ||
+||        |indefinitely.                |              |                    ||
+|+--------+-----------------------------+--------------+--------------------+|
+||        |OUT will be initially high   |              |                    ||
+||        |after the initialisation.    |              |                    ||
+||        |When the initial count       |              |                    ||
+||   4    |expires OUT will go low for  |Start counting|  Hardware gate     ||
+||        |one CLK pulse and then go    |    value     |                    ||
+||        |high again.                  |              |                    ||
+||        |The counting sequences is    |              |                    ||
+||        |triggered by writing a new   |              |                    ||
+||        |value. See                   |              |                    ||
+||        |"i_APCI1710_WriteTimerValue" |              |                    ||
+||        |function. If a new count is  |              |                    ||
+||        |written during counting,     |              |                    ||
+||        |it will be loaded on the     |              |                    ||
+||        |next CLK pulse               |              |                    ||
+|+--------+-----------------------------+--------------+--------------------+|
+||        |Mode 5 is similar to mode 4  |              |                    ||
+||        |except for the gate input    |              |                    ||
+||        |action. The gate input is not|              |                    ||
+||   5    |used for enabled or disabled |Start counting|  Hardware trigger  ||
+||        |the timer. The gate input is |    value     |                    ||
+||        |used for triggered the timer.|              |                    ||
+|+--------+-----------------------------+--------------+--------------------+|
+|                                                                            |
+|                                                                            |
+|                                                                            |
+|                      Input clock selection table                           |
+|                                                                            |
+|  +--------------------------------+------------------------------------+   |
+|  |       b_InputClockSelection    |           Description              |   |
+|  |           parameter            |                                    |   |
+|  +--------------------------------+------------------------------------+   |
+|  |    APCI1710_PCI_BUS_CLOCK      | For the timer input clock, the PCI |   |
+|  |                                | bus clock / 4 is used. This PCI bus|   |
+|  |                                | clock can be 30MHz or 33MHz. For   |   |
+|  |                                | Timer 0 only this selection are    |   |
+|  |                                | available.                         |   |
+|  +--------------------------------+------------------------------------+   |
+|  | APCI1710_ FRONT_CONNECTOR_INPUT| Of the front connector you have the|   |
+|  |                                | possibility to inject a input clock|   |
+|  |                                | for Timer 1 or Timer 2. The source |   |
+|  |                                | from this clock can eat the output |   |
+|  |                                | clock from Timer 0 or any other    |   |
+|  |                                | clock source.                      |   |
+|  +--------------------------------+------------------------------------+   |
+|                                                                            |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_   b_BoardHandle        : Handle of board         |
+|                                                    APCI-1710               |
+|                     BYTE_   b_ModulNbr           : Module number to        |
+|                                                    configure (0 to 3)      |
+|                     BYTE_   b_TimerNbr           : Timer number to         |
+|                                                    configure (0 to 2)      |
+|                     BYTE_   b_TimerMode          : Timer mode selection    |
+|                                                    (0 to 5)                |
+|                                                    0: Interrupt on terminal|
+|                                                       count                |
+|                                                    1: Hardware             |
+|                                                       retriggerable one-   |
+|                                                       shot                 |
+|                                                    2: Rate generator       |
+|                                                    3: Square wave mode     |
+|                                                    4: Software triggered   |
+|                                                       strobe               |
+|                                                    5: Hardware triggered   |
+|                                                       strobe               |
+|                                                       See timer mode       |
+|                                                       description table.   |
+|                     ULONG_ ul_ReloadValue         : Start counting value   |
+|                                                     or division factor     |
+|                                                     See timer mode         |
+|                                                     description table.     |
+|                     BYTE_   b_InputClockSelection : Selection from input   |
+|                                                     timer clock.           |
+|                                                     See input clock        |
+|                                                     selection table.       |
+|                     BYTE_   b_InputClockLevel     : Selection from input   |
+|                                                     clock level.           |
+|                                                     0 : Low active         |
+|                                                         (Input inverted)   |
+|                                                     1 : High active        |
+|                     BYTE_   b_OutputLevel,        : Selection from output  |
+|                                                     clock level.           |
+|                                                     0 : Low active         |
+|                                                     1 : High active        |
+|                                                         (Output inverted)  |
+|                     BYTE_   b_HardwareGateLevel   : Selection from         |
+|                                                     hardware gate level.   |
+|                                                     0 : Low active         |
+|                                                         (Input inverted)   |
+|                                                     1 : High active        |
+|                                                     If you will not used   |
+|                                                     the hardware gate set  |
+|                                                     this value to 0.
+|b_ModulNbr        = (BYTE) CR_AREF(insn->chanspec);
+	b_TimerNbr		  = (BYTE) CR_CHAN(insn->chanspec);
+	b_TimerMode		  = (BYTE) data[0];
+	ul_ReloadValue	  = (ULONG) data[1];
+	b_InputClockSelection	=(BYTE) data[2];
+	b_InputClockLevel		=(BYTE) data[3];
+	b_OutputLevel			=(BYTE) data[4];
+	b_HardwareGateLevel		=(BYTE) data[5];
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : 0: No error                                            |
+|                    -1: The handle parameter of the board is wrong          |
+|                    -2: Module selection wrong                              |
+|                    -3: Timer selection wrong                               |
+|                    -4: The module is not a TIMER module                    |
+|                    -5: Timer mode selection is wrong                       |
+|                    -6: Input timer clock selection is wrong                |
+|                    -7: Selection from input clock level is wrong           |
+|                    -8: Selection from output clock level is wrong          |
+|                    -9: Selection from hardware gate level is wrong         |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigInitTimer(struct comedi_device * dev, struct comedi_subdevice * s,
+				   struct comedi_insn * insn, unsigned int * data)
+{
+
+	INT i_ReturnValue = 0;
+	BYTE b_ModulNbr;
+	BYTE b_TimerNbr;
+	BYTE b_TimerMode;
+	ULONG ul_ReloadValue;
+	BYTE b_InputClockSelection;
+	BYTE b_InputClockLevel;
+	BYTE b_OutputLevel;
+	BYTE b_HardwareGateLevel;
+
+	//BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz
+	DWORD dw_Test = 0;
+	//END JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz
+
+	i_ReturnValue = insn->n;
+	b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+	b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec);
+	b_TimerMode = (BYTE) data[0];
+	ul_ReloadValue = (ULONG) data[1];
+	b_InputClockSelection = (BYTE) data[2];
+	b_InputClockLevel = (BYTE) data[3];
+	b_OutputLevel = (BYTE) data[4];
+	b_HardwareGateLevel = (BYTE) data[5];
+
+	/* Test the module number */
+	if (b_ModulNbr < 4) {
+		/* Test if 82X54 timer */
+		if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
+			/* Test the timer number */
+
+			if (b_TimerNbr <= 2) {
+				/* Test the timer mode */
+				if (b_TimerMode <= 5) {
+					//BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz
+					/* Test te imput clock selection */
+					/*
+					   if (((b_TimerNbr == 0) && (b_InputClockSelection == 0)) ||
+					   ((b_TimerNbr != 0) && ((b_InputClockSelection == 0) || (b_InputClockSelection == 1))))
+					 */
+
+					if (((b_TimerNbr == 0) &&
+					     (b_InputClockSelection == APCI1710_PCI_BUS_CLOCK)) ||
+					    ((b_TimerNbr == 0) &&
+					     (b_InputClockSelection == APCI1710_10MHZ)) ||
+					    ((b_TimerNbr != 0) &&
+					     ((b_InputClockSelection == APCI1710_PCI_BUS_CLOCK) ||
+					      (b_InputClockSelection == APCI1710_FRONT_CONNECTOR_INPUT) ||
+					      (b_InputClockSelection == APCI1710_10MHZ)))) {
+						//BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz
+						if (((b_InputClockSelection == APCI1710_10MHZ) &&
+						     ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0x0000FFFFUL) >= 0x3131)) ||
+						     (b_InputClockSelection != APCI1710_10MHZ)) {
+							//END JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz
+							/* Test the input clock level selection */
+
+							if ((b_InputClockLevel == 0) ||
+							    (b_InputClockLevel == 1)) {
+								/* Test the output clock level selection */
+								if ((b_OutputLevel == 0) || (b_OutputLevel == 1)) {
+									/* Test the hardware gate level selection */
+									if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1)) {
+										//BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
+										/* Test if version > 1.1 and clock selection = 10MHz */
+										if ((b_InputClockSelection == APCI1710_10MHZ) && ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0x0000FFFFUL) > 0x3131)) {
+											/* Test if 40MHz quartz on board */
+											dw_Test = inl(devpriv->s_BoardInfos.ui_Address + (16 + (b_TimerNbr * 4) + (64 * b_ModulNbr)));
+
+											dw_Test = (dw_Test >> 16) & 1;
+										} else {
+											dw_Test = 1;
+										}
+
+										/* Test if detection OK */
+										if (dw_Test == 1) {
+											//END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
+											/* Initialisation OK */
+											devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init = 1;
+
+											/* Save the input clock selection */
+											devpriv-> s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_InputClockSelection = b_InputClockSelection;
+
+											/* Save the input clock level */
+											devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_InputClockLevel = ~b_InputClockLevel & 1;
+
+											/* Save the output level */
+											devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_OutputLevel = ~b_OutputLevel & 1;
+
+											/* Save the gate level */
+											devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_HardwareGateLevel = b_HardwareGateLevel;
+
+											/* Set the configuration word and disable the timer */
+											//BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
+											/*
+											   devpriv->s_ModuleInfo [b_ModulNbr].
+											   s_82X54ModuleInfo.
+											   s_82X54TimerInfo  [b_TimerNbr].
+											   dw_ConfigurationWord = (DWORD) (((b_HardwareGateLevel         << 0) & 0x1) |
+											   ((b_InputClockLevel           << 1) & 0x2) |
+											   (((~b_OutputLevel       & 1)  << 2) & 0x4) |
+											   ((b_InputClockSelection       << 4) & 0x10));
+											 */
+											/* Test if 10MHz selected */
+											if (b_InputClockSelection == APCI1710_10MHZ) {
+												b_InputClockSelection = 2;
+											}
+
+											devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord = (DWORD)(((b_HardwareGateLevel << 0) & 0x1) | ((b_InputClockLevel << 1) & 0x2) | (((~b_OutputLevel & 1) << 2) & 0x4) | ((b_InputClockSelection << 4) & 0x30));
+											//END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
+											outl(devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord, devpriv->s_BoardInfos.ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+
+											/* Initialise the 82X54 Timer */
+											outl((DWORD) b_TimerMode, devpriv->s_BoardInfos.ui_Address + 16 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+
+											/* Write the reload value */
+											outl(ul_ReloadValue, devpriv->s_BoardInfos.ui_Address + 0 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+											//BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
+										}	// if (dw_Test == 1)
+										else {
+											/* Input timer clock selection is wrong */
+											i_ReturnValue = -6;
+										}	// if (dw_Test == 1)
+										//END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
+									}	// if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1))
+									else {
+										/* Selection from hardware gate level is wrong */
+										DPRINTK("Selection from hardware gate level is wrong\n");
+										i_ReturnValue = -9;
+									}	// if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1))
+								}	// if ((b_OutputLevel == 0) || (b_OutputLevel == 1))
+								else {
+									/* Selection from output clock level is wrong */
+									DPRINTK("Selection from output clock level is wrong\n");
+									i_ReturnValue = -8;
+								}	// if ((b_OutputLevel == 0) || (b_OutputLevel == 1))
+							}	// if ((b_InputClockLevel == 0) || (b_InputClockLevel == 1))
+							else {
+								/* Selection from input clock level is wrong */
+								DPRINTK("Selection from input clock level is wrong\n");
+								i_ReturnValue = -7;
+							}	// if ((b_InputClockLevel == 0) || (b_InputClockLevel == 1))
+						} else {
+							/* Input timer clock selection is wrong */
+							DPRINTK("Input timer clock selection is wrong\n");
+							i_ReturnValue = -6;
+						}
+					} else {
+						/* Input timer clock selection is wrong */
+						DPRINTK("Input timer clock selection is wrong\n");
+						i_ReturnValue = -6;
+					}
+				}	// if ((b_TimerMode >= 0) && (b_TimerMode <= 5))
+				else {
+					/* Timer mode selection is wrong */
+					DPRINTK("Timer mode selection is wrong\n");
+					i_ReturnValue = -5;
+				}	// if ((b_TimerMode >= 0) && (b_TimerMode <= 5))
+			}	// if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+			else {
+				/* Timer selection wrong */
+				DPRINTK("Timer selection wrong\n");
+				i_ReturnValue = -3;
+			}	// if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+		} else {
+			/* The module is not a TIMER module */
+			DPRINTK("The module is not a TIMER module\n");
+			i_ReturnValue = -4;
+		}
+	} else {
+		/* Module number error */
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_     i_APCI1710_EnableTimer                       |
+|                               (BYTE_ b_BoardHandle,                        |
+|                                BYTE_ b_ModulNbr,                           |
+|                                BYTE_ b_TimerNbr,                           |
+|                                BYTE_ b_InterruptEnable)
+INT i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device *dev,struct comedi_subdevice *s,
+	struct comedi_insn *insn,unsigned int *data)                |
++----------------------------------------------------------------------------+
+| Task              : Enable OR Disable the Timer (b_TimerNbr) from selected module     |
+|                     (b_ModulNbr). You must calling the                     |
+|                     "i_APCI1710_InitTimer" function be for you call this   |
+|                     function. If you enable the timer interrupt, the timer |
+|                     generate a interrupt after the timer value reach       |
+|                     the zero. See function "i_APCI1710_SetBoardIntRoutineX"|
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_   b_BoardHandle     : Handle of board            |
+|                                                 APCI-1710                  |
+|                     BYTE_   b_ModulNbr        : Selected module number     |
+|                                                 (0 to 3)                   |
+|                     BYTE_   b_TimerNbr        : Timer number to enable     |
+|                                                 (0 to 2)                   |
+|                     BYTE_   b_InterruptEnable : Enable or disable the      |
+|                                                 timer interrupt.           |
+|                                                 APCI1710_ENABLE :          |
+|                                                 Enable the timer interrupt |
+|                                                 APCI1710_DISABLE :         |
+|                                                 Disable the timer interrupt|
+i_ReturnValue=insn->n;
+	b_ModulNbr        = (BYTE) CR_AREF(insn->chanspec);
+	b_TimerNbr		  = (BYTE) CR_CHAN(insn->chanspec);
+	b_ActionType      = (BYTE) data[0]; // enable disable
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : 0: No error                                            |
+|                    -1: The handle parameter of the board is wrong          |
+|                    -2: Module selection wrong                              |
+|                    -3: Timer selection wrong                               |
+|                    -4: The module is not a TIMER module                    |
+|                    -5: Timer not initialised see function                  |
+|                        "i_APCI1710_InitTimer"                              |
+|                    -6: Interrupt parameter is wrong                        |
+|                    -7: Interrupt function not initialised.                 |
+|                        See function "i_APCI1710_SetBoardIntRoutineX"       |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device * dev,
+					   struct comedi_subdevice * s,
+					   struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_DummyRead;
+	BYTE b_ModulNbr;
+	BYTE b_TimerNbr;
+	BYTE b_ActionType;
+	BYTE b_InterruptEnable;
+
+	i_ReturnValue = insn->n;
+	b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+	b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec);
+	b_ActionType = (BYTE) data[0];	// enable disable
+
+	/* Test the module number */
+	if (b_ModulNbr < 4) {
+		/* Test if 82X54 timer */
+		if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
+			/* Test the timer number */
+			if (b_TimerNbr <= 2) {
+				/* Test if timer initialised */
+				if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) {
+
+					switch (b_ActionType) {
+					case APCI1710_ENABLE:
+						b_InterruptEnable = (BYTE) data[1];
+						/* Test the interrupt selection */
+						if ((b_InterruptEnable == APCI1710_ENABLE) ||
+						    (b_InterruptEnable == APCI1710_DISABLE)) {
+							if (b_InterruptEnable == APCI1710_ENABLE) {
+
+								dw_DummyRead = inl(devpriv->s_BoardInfos.ui_Address + 12 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+
+								/* Enable the interrupt */
+								devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord | 0x8;
+
+								outl(devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord, devpriv->s_BoardInfos.ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+								devpriv->tsk_Current = current;	// Save the current process task structure
+
+							}	// if (b_InterruptEnable == APCI1710_ENABLE)
+							else {
+								/* Disable the interrupt */
+								devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord & 0xF7;
+
+								outl(devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord, devpriv->s_BoardInfos.ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+
+								/* Save the interrupt flag */
+								devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask & (0xFF - (1 << b_TimerNbr));
+							}	// if (b_InterruptEnable == APCI1710_ENABLE)
+
+							/* Test if error occur */
+							if (i_ReturnValue >= 0) {
+								/* Save the interrupt flag */
+								devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask | ((1 & b_InterruptEnable) << b_TimerNbr);
+
+								/* Enable the timer */
+								outl(1, devpriv->s_BoardInfos.ui_Address + 44 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+							}
+						} else {
+							/* Interrupt parameter is wrong */
+							DPRINTK("\n");
+							i_ReturnValue = -6;
+						}
+						break;
+					case APCI1710_DISABLE:
+						/* Test the interrupt flag */
+						if (((devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask >> b_TimerNbr) & 1) == 1) {
+							/* Disable the interrupt */
+
+							devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr]. dw_ConfigurationWord = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord & 0xF7;
+
+							outl(devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord, devpriv->s_BoardInfos.ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+
+							/* Save the interrupt flag */
+							devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask & (0xFF - (1 << b_TimerNbr));
+						}
+
+						/* Disable the timer */
+						outl(0, devpriv->s_BoardInfos.ui_Address + 44 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+						break;
+					}	// Switch end
+				} else {
+					/* Timer not initialised see function */
+					DPRINTK ("Timer not initialised see function\n");
+					i_ReturnValue = -5;
+				}
+			} else {
+				/* Timer selection wrong */
+				DPRINTK("Timer selection wrong\n");
+				i_ReturnValue = -3;
+			}	// if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+		} else {
+			/* The module is not a TIMER module */
+			DPRINTK("The module is not a TIMER module\n");
+			i_ReturnValue = -4;
+		}
+	} else {
+		/* Module number error */
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_     i_APCI1710_ReadAllTimerValue                 |
+|                                       (BYTE_     b_BoardHandle,            |
+|                                        BYTE_     b_ModulNbr,               |
+|                                        PULONG_ pul_TimerValueArray)
+INT i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev,struct comedi_subdevice *s,
+	struct comedi_insn *insn,unsigned int *data)        |
++----------------------------------------------------------------------------+
+| Task              : Return the all timer values from selected timer        |
+|                     module (b_ModulNbr).                                   |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_   b_BoardHandle     : Handle of board            |
+|                                                 APCI-1710                  |
+|                     BYTE_   b_ModulNbr        : Selected module number     |
+|                                                 (0 to 3)                   |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_TimerValueArray : Timer value array.       |
+|                           Element 0 contain the timer 0 value.             |
+|                           Element 1 contain the timer 1 value.             |
+|                           Element 2 contain the timer 2 value.             |
++----------------------------------------------------------------------------+
+| Return Value      : 0: No error                                            |
+|                    -1: The handle parameter of the board is wrong          |
+|                    -2: Module selection wrong                              |
+|                    -3: The module is not a TIMER module                    |
+|                    -4: Timer 0 not initialised see function                |
+|                        "i_APCI1710_InitTimer"                              |
+|                    -5: Timer 1 not initialised see function                |
+|                        "i_APCI1710_InitTimer"                              |
+|                    -6: Timer 2 not initialised see function                |
+|                        "i_APCI1710_InitTimer"                              |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev, struct comedi_subdevice *s,
+				     struct comedi_insn *insn, unsigned int *data)
+{
+	INT i_ReturnValue = 0;
+	BYTE b_ModulNbr, b_ReadType;
+	PULONG pul_TimerValueArray;
+
+	b_ModulNbr = CR_AREF(insn->chanspec);
+	b_ReadType = CR_CHAN(insn->chanspec);
+	pul_TimerValueArray = (PULONG) data;
+	i_ReturnValue = insn->n;
+
+	switch (b_ReadType) {
+	case APCI1710_TIMER_READINTERRUPT:
+
+		data[0] = devpriv->s_InterruptParameters.s_FIFOInterruptParameters[devpriv->s_InterruptParameters.ui_Read].b_OldModuleMask;
+		data[1] = devpriv->s_InterruptParameters.s_FIFOInterruptParameters[devpriv->s_InterruptParameters.ui_Read].ul_OldInterruptMask;
+		data[2] = devpriv->s_InterruptParameters.s_FIFOInterruptParameters[devpriv->s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
+
+		/* Increment the read FIFO */
+		devpriv->s_InterruptParameters.ui_Read = (devpriv->s_InterruptParameters.ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+
+		break;
+
+	case APCI1710_TIMER_READALLTIMER:
+		/* Test the module number */
+		if (b_ModulNbr < 4) {
+			/* Test if 82X54 timer */
+			if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
+				/* Test if timer 0 iniutialised */
+				if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[0].b_82X54Init == 1) {
+					/* Test if timer 1 iniutialised */
+					if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[1].b_82X54Init == 1) {
+						/* Test if timer 2 iniutialised */
+						if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[2].b_82X54Init == 1) {
+							/* Latch all counter */
+							outl(0x17, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));
+
+							/* Read the timer 0 value */
+							pul_TimerValueArray[0] = inl(devpriv->s_BoardInfos.ui_Address + 0 + (64 * b_ModulNbr));
+
+							/* Read the timer 1 value */
+							pul_TimerValueArray[1] = inl(devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr));
+
+							/* Read the timer 2 value */
+							pul_TimerValueArray[2] = inl(devpriv->s_BoardInfos.ui_Address + 8 + (64 * b_ModulNbr));
+						} else {
+							/* Timer 2 not initialised see function */
+							DPRINTK("Timer 2 not initialised see function\n");
+							i_ReturnValue = -6;
+						}
+					} else {
+						/* Timer 1 not initialised see function */
+						DPRINTK("Timer 1 not initialised see function\n");
+						i_ReturnValue = -5;
+					}
+				} else {
+					/* Timer 0 not initialised see function */
+					DPRINTK("Timer 0 not initialised see function\n");
+					i_ReturnValue = -4;
+				}
+			} else {
+				/* The module is not a TIMER module */
+				DPRINTK("The module is not a TIMER module\n");
+				i_ReturnValue = -3;
+			}
+		} else {
+			/* Module number error */
+			DPRINTK("Module number error\n");
+			i_ReturnValue = -2;
+		}
+
+	}			// End of Switch
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     :INT i_APCI1710_InsnBitsTimer(struct comedi_device *dev,
+struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)                   |
++----------------------------------------------------------------------------+
+| Task              : Read write functions for Timer                                          |
++----------------------------------------------------------------------------+
+| Input Parameters  :
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnBitsTimer(struct comedi_device * dev, struct comedi_subdevice * s,
+			     struct comedi_insn * insn, unsigned int * data)
+{
+	BYTE b_BitsType;
+	INT i_ReturnValue = 0;
+	b_BitsType = data[0];
+
+	printk("\n82X54");
+
+	switch (b_BitsType) {
+	case APCI1710_TIMER_READVALUE:
+		i_ReturnValue = i_APCI1710_ReadTimerValue(dev,
+							  (BYTE)CR_AREF(insn->chanspec),
+							  (BYTE)CR_CHAN(insn->chanspec),
+							  (PULONG) & data[0]);
+		break;
+
+	case APCI1710_TIMER_GETOUTPUTLEVEL:
+		i_ReturnValue = i_APCI1710_GetTimerOutputLevel(dev,
+							       (BYTE)CR_AREF(insn->chanspec),
+							       (BYTE)CR_CHAN(insn->chanspec),
+							       (PBYTE) &data[0]);
+		break;
+
+	case APCI1710_TIMER_GETPROGRESSSTATUS:
+		i_ReturnValue = i_APCI1710_GetTimerProgressStatus(dev,
+								  (BYTE)CR_AREF(insn->chanspec),
+								  (BYTE)CR_CHAN(insn->chanspec),
+								  (PBYTE)&data[0]);
+		break;
+
+	case APCI1710_TIMER_WRITEVALUE:
+		i_ReturnValue = i_APCI1710_WriteTimerValue(dev,
+							   (BYTE)CR_AREF(insn->chanspec),
+							   (BYTE)CR_CHAN(insn->chanspec),
+							   (ULONG)data[1]);
+
+		break;
+
+	default:
+		printk("Bits Config Parameter Wrong\n");
+		i_ReturnValue = -1;
+	}
+
+	if (i_ReturnValue >= 0)
+		i_ReturnValue = insn->n;
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_     i_APCI1710_ReadTimerValue                    |
+|                                       (BYTE_     b_BoardHandle,            |
+|                                        BYTE_     b_ModulNbr,               |
+|                                        BYTE_     b_TimerNbr,               |
+|                                        PULONG_ pul_TimerValue)             |
++----------------------------------------------------------------------------+
+| Task              : Return the timer value from selected digital timer     |
+|                     (b_TimerNbr) from selected timer  module (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_   b_BoardHandle     : Handle of board            |
+|                                                 APCI-1710                  |
+|                     BYTE_   b_ModulNbr        : Selected module number     |
+|                                                 (0 to 3)                   |
+|                     BYTE_   b_TimerNbr        : Timer number to read       |
+|                                                 (0 to 2)                   |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_TimerValue    : Timer value                |
++----------------------------------------------------------------------------+
+| Return Value      : 0: No error                                            |
+|                    -1: The handle parameter of the board is wrong          |
+|                    -2: Module selection wrong                              |
+|                    -3: Timer selection wrong                               |
+|                    -4: The module is not a TIMER module                    |
+|                    -5: Timer not initialised see function                  |
+|                        "i_APCI1710_InitTimer"                              |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_ReadTimerValue(struct comedi_device * dev,
+			      BYTE b_ModulNbr, BYTE b_TimerNbr,
+			      PULONG pul_TimerValue)
+{
+	INT i_ReturnValue = 0;
+
+	/* Test the module number */
+	if (b_ModulNbr < 4) {
+		/* Test if 82X54 timer */
+		if ((devpriv->s_BoardInfos.
+		     dw_MolduleConfiguration[b_ModulNbr] &
+		     0xFFFF0000UL) == APCI1710_82X54_TIMER) {
+			/* Test the timer number */
+			if (b_TimerNbr <= 2) {
+				/* Test if timer initialised */
+				if (devpriv->
+				    s_ModuleInfo[b_ModulNbr].
+				    s_82X54ModuleInfo.
+				    s_82X54TimerInfo[b_TimerNbr].
+				    b_82X54Init == 1) {
+					/* Latch the timer value */
+					outl((2 << b_TimerNbr) | 0xD0,
+					     devpriv->s_BoardInfos.
+					     ui_Address + 12 +
+					     (64 * b_ModulNbr));
+
+					/* Read the counter value */
+					*pul_TimerValue =
+					    inl(devpriv->s_BoardInfos.
+						ui_Address + (b_TimerNbr * 4) +
+						(64 * b_ModulNbr));
+				} else {
+					/* Timer not initialised see function */
+					DPRINTK("Timer not initialised see function\n");
+					i_ReturnValue = -5;
+				}
+			} else {
+				/* Timer selection wrong */
+				DPRINTK("Timer selection wrong\n");
+				i_ReturnValue = -3;
+			}	// if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+		} else {
+			/* The module is not a TIMER module */
+			DPRINTK("The module is not a TIMER module\n");
+			i_ReturnValue = -4;
+		}
+	} else {
+		/* Module number error */
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+	/*
+	   +----------------------------------------------------------------------------+
+	   | Function Name     : _INT_     i_APCI1710_GetTimerOutputLevel               |
+	   |                                       (BYTE_     b_BoardHandle,            |
+	   |                                        BYTE_     b_ModulNbr,               |
+	   |                                        BYTE_     b_TimerNbr,               |
+	   |                                        PBYTE_   pb_OutputLevel)            |
+	   +----------------------------------------------------------------------------+
+	   | Task              : Return the output signal level (pb_OutputLevel) from   |
+	   |                     selected digital timer (b_TimerNbr) from selected timer|
+	   |                     module (b_ModulNbr).                                   |
+	   +----------------------------------------------------------------------------+
+	   | Input Parameters  : BYTE_   b_BoardHandle     : Handle of board            |
+	   |                                                 APCI-1710                  |
+	   |                     BYTE_   b_ModulNbr        : Selected module number     |
+	   |                                                 (0 to 3)                   |
+	   |                     BYTE_   b_TimerNbr        : Timer number to test       |
+	   |                                                 (0 to 2)                   |
+	   +----------------------------------------------------------------------------+
+	   | Output Parameters : PBYTE_ pb_OutputLevel     : Output signal level        |
+	   |                                                 0 : The output is low      |
+	   |                                                 1 : The output is high     |
+	   +----------------------------------------------------------------------------+
+	   | Return Value      : 0: No error                                            |
+	   |                    -1: The handle parameter of the board is wrong          |
+	   |                    -2: Module selection wrong                              |
+	   |                    -3: Timer selection wrong                               |
+	   |                    -4: The module is not a TIMER module                    |
+	   |                    -5: Timer not initialised see function                  |
+	   |                        "i_APCI1710_InitTimer"                              |
+	   +----------------------------------------------------------------------------+
+	 */
+
+INT i_APCI1710_GetTimerOutputLevel(struct comedi_device * dev,
+				   BYTE b_ModulNbr, BYTE b_TimerNbr,
+				   PBYTE pb_OutputLevel)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_TimerStatus;
+
+	/* Test the module number */
+	if (b_ModulNbr < 4) {
+		/* Test if 82X54 timer */
+		if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
+			/* Test the timer number */
+			if (b_TimerNbr <= 2) {
+				/* Test if timer initialised */
+				if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) {
+					/* Latch the timer value */
+					outl((2 << b_TimerNbr) | 0xE0, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));
+
+					/* Read the timer status */
+					dw_TimerStatus = inl(devpriv->s_BoardInfos.ui_Address + 16 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+
+					*pb_OutputLevel = (BYTE) (((dw_TimerStatus >> 7) & 1) ^ devpriv-> s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_OutputLevel);
+				} else {
+					/* Timer not initialised see function */
+					DPRINTK("Timer not initialised see function\n");
+					i_ReturnValue = -5;
+				}
+			} else {
+				/* Timer selection wrong */
+				DPRINTK("Timer selection wrong\n");
+				i_ReturnValue = -3;
+			}	// if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+		} else {
+			/* The module is not a TIMER module */
+			DPRINTK("The module is not a TIMER module\n");
+			i_ReturnValue = -4;
+		}
+	} else {
+		/* Module number error */
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_     i_APCI1710_GetTimerProgressStatus            |
+|                                       (BYTE_     b_BoardHandle,            |
+|                                        BYTE_     b_ModulNbr,               |
+|                                        BYTE_     b_TimerNbr,               |
+|                                        PBYTE_   pb_TimerStatus)            |
++----------------------------------------------------------------------------+
+| Task              : Return the progress status (pb_TimerStatus) from       |
+|                     selected digital timer (b_TimerNbr) from selected timer|
+|                     module (b_ModulNbr).                                   |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_   b_BoardHandle     : Handle of board            |
+|                                                 APCI-1710                  |
+|                     BYTE_   b_ModulNbr        : Selected module number     |
+|                                                 (0 to 3)                   |
+|                     BYTE_   b_TimerNbr        : Timer number to test       |
+|                                                 (0 to 2)                   |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_TimerStatus     : Output signal level        |
+|                                                 0 : Timer not in progress  |
+|                                                 1 : Timer in progress      |
++----------------------------------------------------------------------------+
+| Return Value      : 0: No error                                            |
+|                    -1: The handle parameter of the board is wrong          |
+|                    -2: Module selection wrong                              |
+|                    -3: Timer selection wrong                               |
+|                    -4: The module is not a TIMER module                    |
+|                    -5: Timer not initialised see function                  |
+|                        "i_APCI1710_InitTimer"                              |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetTimerProgressStatus(struct comedi_device *dev,
+				      BYTE b_ModulNbr, BYTE b_TimerNbr,
+				      PBYTE pb_TimerStatus)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_TimerStatus;
+
+	/* Test the module number */
+	if (b_ModulNbr < 4) {
+		/* Test if 82X54 timer */
+
+		if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
+			/* Test the timer number */
+			if (b_TimerNbr <= 2) {
+				/* Test if timer initialised */
+				if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) {
+					/* Latch the timer value */
+					outl((2 << b_TimerNbr) | 0xE0, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));
+
+					/* Read the timer status */
+					dw_TimerStatus = inl(devpriv->s_BoardInfos.ui_Address + 16 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+
+					*pb_TimerStatus = (BYTE) ((dw_TimerStatus) >> 8) & 1;
+					printk("ProgressStatus : %d", *pb_TimerStatus);
+				} else {
+					/* Timer not initialised see function */
+					i_ReturnValue = -5;
+				}
+			} else {
+				/* Timer selection wrong */
+				i_ReturnValue = -3;
+			}	// if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+		} else {
+			/* The module is not a TIMER module */
+
+			i_ReturnValue = -4;
+		}
+	} else {
+		/* Module number error */
+
+		i_ReturnValue = -2;
+	}
+
+	return i_ReturnValue;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_     i_APCI1710_WriteTimerValue                   |
+|                                       (BYTE_   b_BoardHandle,              |
+|                                        BYTE_   b_ModulNbr,                 |
+|                                        BYTE_   b_TimerNbr,                 |
+|                                        ULONG_ ul_WriteValue)               |
++----------------------------------------------------------------------------+
+| Task              : Write the value (ul_WriteValue) into the selected timer|
+|                     (b_TimerNbr) from selected timer module (b_ModulNbr).  |
+|                     The action in depend of the time mode selection.       |
+|                     See timer mode description table.                      |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_   b_BoardHandle     : Handle of board            |
+|                                                 APCI-1710                  |
+|                     BYTE_   b_ModulNbr        : Selected module number     |
+|                                                 (0 to 3)                   |
+|                     BYTE_   b_TimerNbr        : Timer number to write      |
+|                                                 (0 to 2)                   |
+|                     ULONG_ ul_WriteValue      : Value to write             |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : 0: No error                                            |
+|                    -1: The handle parameter of the board is wrong          |
+|                    -2: Module selection wrong                              |
+|                    -3: Timer selection wrong                               |
+|                    -4: The module is not a TIMER module                    |
+|                    -5: Timer not initialised see function                  |
+|                        "i_APCI1710_InitTimer"                              |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_WriteTimerValue(struct comedi_device * dev,
+			       BYTE b_ModulNbr, BYTE b_TimerNbr,
+			       ULONG ul_WriteValue)
+{
+	INT i_ReturnValue = 0;
+
+	/* Test the module number */
+	if (b_ModulNbr < 4) {
+		/* Test if 82X54 timer */
+		if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
+			/* Test the timer number */
+			if (b_TimerNbr <= 2) {
+				/* Test if timer initialised */
+				if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) {
+					/* Write the value */
+					outl(ul_WriteValue, devpriv->s_BoardInfos.ui_Address + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+				} else {
+					/* Timer not initialised see function */
+					DPRINTK("Timer not initialised see function\n");
+					i_ReturnValue = -5;
+				}
+			} else {
+				/* Timer selection wrong */
+				DPRINTK("Timer selection wrong\n");
+				i_ReturnValue = -3;
+			}	// if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+		} else {
+			/* The module is not a TIMER module */
+			DPRINTK("The module is not a TIMER module\n");
+			i_ReturnValue = -4;
+		}
+	} else {
+		/* Module number error */
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+
+	return i_ReturnValue;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h
new file mode 100644
index 0000000..4797c0b
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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.
+ */
+
+#define APCI1710_PCI_BUS_CLOCK 			0
+#define APCI1710_FRONT_CONNECTOR_INPUT 		1
+#define APCI1710_TIMER_READVALUE		0
+#define APCI1710_TIMER_GETOUTPUTLEVEL		1
+#define APCI1710_TIMER_GETPROGRESSSTATUS	2
+#define APCI1710_TIMER_WRITEVALUE		3
+
+#define APCI1710_TIMER_READINTERRUPT		1
+#define APCI1710_TIMER_READALLTIMER		2
+
+/* BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */
+#ifndef APCI1710_10MHZ
+#define APCI1710_10MHZ	10
+#endif
+/* END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */
+
+/*
+ * 82X54 TIMER INISIALISATION FUNCTION
+ */
+INT i_APCI1710_InsnConfigInitTimer(struct comedi_device *dev, struct comedi_subdevice *s,
+				   struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device *dev,
+					   struct comedi_subdevice *s,
+					   struct comedi_insn *insn, unsigned int *data);
+
+/*
+ * 82X54 READ FUNCTION
+ */
+INT i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev, struct comedi_subdevice *s,
+				     struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnBitsTimer(struct comedi_device *dev, struct comedi_subdevice *s,
+			     struct comedi_insn *insn, unsigned int *data);
+
+/*
+ * 82X54 READ & WRITE FUNCTION
+ */
+INT i_APCI1710_ReadTimerValue(struct comedi_device *dev,
+			      BYTE b_ModulNbr, BYTE b_TimerNbr,
+			      PULONG pul_TimerValue);
+
+INT i_APCI1710_GetTimerOutputLevel(struct comedi_device *dev,
+				   BYTE b_ModulNbr, BYTE b_TimerNbr,
+				   PBYTE pb_OutputLevel);
+
+INT i_APCI1710_GetTimerProgressStatus(struct comedi_device *dev,
+				      BYTE b_ModulNbr, BYTE b_TimerNbr,
+				      PBYTE pb_TimerStatus);
+
+/*
+ * 82X54 WRITE FUNCTION
+ */
+INT i_APCI1710_WriteTimerValue(struct comedi_device *dev,
+			       BYTE b_ModulNbr, BYTE b_TimerNbr,
+			       ULONG ul_WriteValue);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c
new file mode 100644
index 0000000..1a54d3b
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c
@@ -0,0 +1,2032 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+
+        ADDI-DATA GmbH
+        Dieselstrasse 3
+        D-77833 Ottersweier
+        Tel: +19(0)7223/9493-0
+        Fax: +49(0)7223/9493-92
+        http://www.addi-data-com
+        info@addi-data.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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+  +-----------------------------------------------------------------------+
+  | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
+  +-----------------------------------------------------------------------+
+  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
+  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
+  +-----------------------------------------------------------------------+
+  | Project     : API APCI1710    | Compiler : gcc                        |
+  | Module name : CHRONO.C        | Version  : 2.96                       |
+  +-------------------------------+---------------------------------------+
+  | Project manager: Eric Stolz   | Date     :  02/12/2002                |
+  +-----------------------------------------------------------------------+
+  | Description :   APCI-1710 chronometer module                          |
+  |                                                                       |
+  |                                                                       |
+  +-----------------------------------------------------------------------+
+  |                             UPDATES                                   |
+  +-----------------------------------------------------------------------+
+  |   Date   |   Author  |          Description of updates                |
+  +----------+-----------+------------------------------------------------+
+  | 29/06/98 | S. Weber  | Digital input / output implementation          |
+  |----------|-----------|------------------------------------------------|
+  | 08/05/00 | Guinot C  | - 0400/0228 All Function in RING 0             |
+  |          |           |   available                                    |
+  +-----------------------------------------------------------------------+
+  |          |           |                                                |
+  |          |           |                                                |
+  +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+|                               Included files                               |
++----------------------------------------------------------------------------+
+*/
+#include "APCI1710_Chrono.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_     i_APCI1710_InitChrono                        |
+|                                       (BYTE_     b_BoardHandle,            |
+|                                        BYTE_     b_ModulNbr,               |
+|                                        BYTE_     b_ChronoMode,             |
+|                                        BYTE_     b_PCIInputClock,          |
+|                                        BYTE_     b_TimingUnit,             |
+|                                        ULONG_   ul_TimingInterval,         |
+|                                        PULONG_ pul_RealTimingInterval)
+
++----------------------------------------------------------------------------+
+| Task              : Configure the chronometer operating mode (b_ChronoMode)|
+|                     from selected module (b_ModulNbr).                     |
+|                     The ul_TimingInterval and ul_TimingUnit determine the  |
+|                     timing base for the measurement.                       |
+|                     The pul_RealTimingInterval return the real timing      |
+|                     value. You must calling this function be for you call  |
+|                     any other function witch access of the chronometer.    |
+|                                                                            |
+|                     Witch this functionality from the APCI-1710 you have   |
+|                     the possibility to measure the timing witch two event. |
+|                                                                            |
+|                     The mode 0 and 1 is appropriate for period measurement.|
+|                     The mode 2 and 3 is appropriate for frequent           |
+|                     measurement.                                           |
+|                     The mode 4 to 7 is appropriate for measuring the timing|
+|                     between  two event.                                    |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_   b_BoardHandle    : Handle of board APCI-1710   |
+| BYTE_   b_ModulNbr  CR_AREF(insn->chanspec)  : Module number to configure  |
+|                                                (0 to 3)                    |
+| BYTE_   b_ChronoMode				data[0]    : Chronometer action mode     |
+|                                                (0 to 7).                   |
+| BYTE_   b_PCIInputClock			data[1] : Selection from PCI bus clock|
+|                                                - APCI1710_30MHZ :          |
+|                                                  The PC have a PCI bus     |
+|                                                  clock from 30 MHz         |
+|                                                - APCI1710_33MHZ :          |
+|                                                  The PC have a PCI bus     |
+|                                                  clock from 33 MHz         |
+|                                                - APCI1710_40MHZ            |
+|                                                  The APCI-1710 have a      |
+|                                                  integrated 40Mhz          |
+|                                                  quartz.                   |
+|               BYTE_   b_TimingUnit	data[2]    : Base timing unity (0 to 4) |
+|                                                 0 : ns                     |
+|                                                 1 : µs                     |
+|                                                 2 : ms                     |
+|                                                 3 : s                      |
+|                                                 4 : mn                     |
+|         ULONG_ ul_TimingInterval : data[3]	 Base timing value.          |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_  pul_RealTimingInterval : Real  base timing    |
+|                                                       value.
+|                     data[0]
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: Module selection wrong                             |
+|                     -3: The module is not a Chronometer module             |
+|                     -4: Chronometer mode selection is wrong                |
+|                     -5: The selected PCI input clock is wrong              |
+|                     -6: Timing unity selection is wrong                    |
+|                     -7: Base timing selection is wrong                     |
+|                     -8: You can not used the 40MHz clock selection wich    |
+|                         this board                                         |
+|                     -9: You can not used the 40MHz clock selection wich    |
+|                         this CHRONOS version                               |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigInitChrono(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = 0;
+	ULONG ul_TimerValue = 0;
+	ULONG ul_TimingInterval = 0;
+	ULONG ul_RealTimingInterval = 0;
+	double d_RealTimingInterval = 0;
+	DWORD dw_ModeArray[8] =
+		{ 0x01, 0x05, 0x00, 0x04, 0x02, 0x0E, 0x0A, 0x06 };
+	BYTE b_ModulNbr, b_ChronoMode, b_PCIInputClock, b_TimingUnit;
+
+	b_ModulNbr = CR_AREF(insn->chanspec);
+	b_ChronoMode = (BYTE) data[0];
+	b_PCIInputClock = (BYTE) data[1];
+	b_TimingUnit = (BYTE) data[2];
+	ul_TimingInterval = (ULONG) data[3];
+	i_ReturnValue = insn->n;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /***********************/
+		/* Test if chronometer */
+	   /***********************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_CHRONOMETER) {
+	      /*****************************/
+			/* Test the chronometer mode */
+	      /*****************************/
+
+			if (b_ChronoMode <= 7) {
+		 /**************************/
+				/* Test the PCI bus clock */
+		 /**************************/
+
+				if ((b_PCIInputClock == APCI1710_30MHZ) ||
+					(b_PCIInputClock == APCI1710_33MHZ) ||
+					(b_PCIInputClock == APCI1710_40MHZ)) {
+		    /*************************/
+					/* Test the timing unity */
+		    /*************************/
+
+					if (b_TimingUnit <= 4) {
+		       /**********************************/
+						/* Test the base timing selection */
+		       /**********************************/
+
+						if (((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 66) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 143165576UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 143165UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 143UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 2UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 60) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 130150240UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 130150UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 130UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 2UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 50) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 107374182UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 107374UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 107UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 1UL))) {
+			  /**************************/
+							/* Test the board version */
+			  /**************************/
+
+							if (((b_PCIInputClock == APCI1710_40MHZ) && (devpriv->s_BoardInfos.b_BoardVersion > 0)) || (b_PCIInputClock != APCI1710_40MHZ)) {
+			     /************************/
+								/* Test the TOR version */
+			     /************************/
+
+								if (((b_PCIInputClock == APCI1710_40MHZ) && ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3131)) || (b_PCIInputClock != APCI1710_40MHZ)) {
+									fpu_begin
+										();
+
+				/****************************************/
+									/* Calculate the timer 0 division fator */
+				/****************************************/
+
+									switch (b_TimingUnit) {
+				   /******/
+										/* ns */
+				   /******/
+
+									case 0:
+
+					   /******************/
+										/* Timer 0 factor */
+					   /******************/
+
+										ul_TimerValue
+											=
+											(ULONG)
+											(ul_TimingInterval
+											*
+											(0.001 * b_PCIInputClock));
+
+					   /*******************/
+										/* Round the value */
+					   /*******************/
+
+										if ((double)((double)ul_TimingInterval * (0.001 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+											ul_TimerValue
+												=
+												ul_TimerValue
+												+
+												1;
+										}
+
+					   /*****************************/
+										/* Calculate the real timing */
+					   /*****************************/
+
+										ul_RealTimingInterval
+											=
+											(ULONG)
+											(ul_TimerValue
+											/
+											(0.001 * (double)b_PCIInputClock));
+										d_RealTimingInterval
+											=
+											(double)
+											ul_TimerValue
+											/
+											(0.001
+											*
+											(double)
+											b_PCIInputClock);
+
+										if ((double)((double)ul_TimerValue / (0.001 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+											ul_RealTimingInterval
+												=
+												ul_RealTimingInterval
+												+
+												1;
+										}
+
+										ul_TimingInterval
+											=
+											ul_TimingInterval
+											-
+											1;
+										ul_TimerValue
+											=
+											ul_TimerValue
+											-
+											2;
+										if (b_PCIInputClock != APCI1710_40MHZ) {
+											ul_TimerValue
+												=
+												(ULONG)
+												(
+												(double)
+												(ul_TimerValue)
+												*
+												0.99392);
+										}
+
+										break;
+
+				   /******/
+										/* æs */
+				   /******/
+
+									case 1:
+
+					   /******************/
+										/* Timer 0 factor */
+					   /******************/
+
+										ul_TimerValue
+											=
+											(ULONG)
+											(ul_TimingInterval
+											*
+											(1.0 * b_PCIInputClock));
+
+					   /*******************/
+										/* Round the value */
+					   /*******************/
+
+										if ((double)((double)ul_TimingInterval * (1.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+											ul_TimerValue
+												=
+												ul_TimerValue
+												+
+												1;
+										}
+
+					   /*****************************/
+										/* Calculate the real timing */
+					   /*****************************/
+
+										ul_RealTimingInterval
+											=
+											(ULONG)
+											(ul_TimerValue
+											/
+											(1.0 * (double)b_PCIInputClock));
+										d_RealTimingInterval
+											=
+											(double)
+											ul_TimerValue
+											/
+											(
+											(double)
+											1.0
+											*
+											(double)
+											b_PCIInputClock);
+
+										if ((double)((double)ul_TimerValue / (1.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+											ul_RealTimingInterval
+												=
+												ul_RealTimingInterval
+												+
+												1;
+										}
+
+										ul_TimingInterval
+											=
+											ul_TimingInterval
+											-
+											1;
+										ul_TimerValue
+											=
+											ul_TimerValue
+											-
+											2;
+										if (b_PCIInputClock != APCI1710_40MHZ) {
+											ul_TimerValue
+												=
+												(ULONG)
+												(
+												(double)
+												(ul_TimerValue)
+												*
+												0.99392);
+										}
+
+										break;
+
+				   /******/
+										/* ms */
+				   /******/
+
+									case 2:
+
+					   /******************/
+										/* Timer 0 factor */
+					   /******************/
+
+										ul_TimerValue
+											=
+											ul_TimingInterval
+											*
+											(1000
+											*
+											b_PCIInputClock);
+
+					   /*******************/
+										/* Round the value */
+					   /*******************/
+
+										if ((double)((double)ul_TimingInterval * (1000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+											ul_TimerValue
+												=
+												ul_TimerValue
+												+
+												1;
+										}
+
+					   /*****************************/
+										/* Calculate the real timing */
+					   /*****************************/
+
+										ul_RealTimingInterval
+											=
+											(ULONG)
+											(ul_TimerValue
+											/
+											(1000.0 * (double)b_PCIInputClock));
+										d_RealTimingInterval
+											=
+											(double)
+											ul_TimerValue
+											/
+											(1000.0
+											*
+											(double)
+											b_PCIInputClock);
+
+										if ((double)((double)ul_TimerValue / (1000.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+											ul_RealTimingInterval
+												=
+												ul_RealTimingInterval
+												+
+												1;
+										}
+
+										ul_TimingInterval
+											=
+											ul_TimingInterval
+											-
+											1;
+										ul_TimerValue
+											=
+											ul_TimerValue
+											-
+											2;
+										if (b_PCIInputClock != APCI1710_40MHZ) {
+											ul_TimerValue
+												=
+												(ULONG)
+												(
+												(double)
+												(ul_TimerValue)
+												*
+												0.99392);
+										}
+
+										break;
+
+				   /*****/
+										/* s */
+				   /*****/
+
+									case 3:
+
+					   /******************/
+										/* Timer 0 factor */
+					   /******************/
+
+										ul_TimerValue
+											=
+											(ULONG)
+											(ul_TimingInterval
+											*
+											(1000000.0
+												*
+												b_PCIInputClock));
+
+					   /*******************/
+										/* Round the value */
+					   /*******************/
+
+										if ((double)((double)ul_TimingInterval * (1000000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+											ul_TimerValue
+												=
+												ul_TimerValue
+												+
+												1;
+										}
+
+					   /*****************************/
+										/* Calculate the real timing */
+					   /*****************************/
+
+										ul_RealTimingInterval
+											=
+											(ULONG)
+											(ul_TimerValue
+											/
+											(1000000.0
+												*
+												(double)
+												b_PCIInputClock));
+										d_RealTimingInterval
+											=
+											(double)
+											ul_TimerValue
+											/
+											(1000000.0
+											*
+											(double)
+											b_PCIInputClock);
+
+										if ((double)((double)ul_TimerValue / (1000000.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+											ul_RealTimingInterval
+												=
+												ul_RealTimingInterval
+												+
+												1;
+										}
+
+										ul_TimingInterval
+											=
+											ul_TimingInterval
+											-
+											1;
+										ul_TimerValue
+											=
+											ul_TimerValue
+											-
+											2;
+										if (b_PCIInputClock != APCI1710_40MHZ) {
+											ul_TimerValue
+												=
+												(ULONG)
+												(
+												(double)
+												(ul_TimerValue)
+												*
+												0.99392);
+										}
+
+										break;
+
+				   /******/
+										/* mn */
+				   /******/
+
+									case 4:
+
+					   /******************/
+										/* Timer 0 factor */
+					   /******************/
+
+										ul_TimerValue
+											=
+											(ULONG)
+											(
+											(ul_TimingInterval
+												*
+												60)
+											*
+											(1000000.0
+												*
+												b_PCIInputClock));
+
+					   /*******************/
+										/* Round the value */
+					   /*******************/
+
+										if ((double)((double)(ul_TimingInterval * 60.0) * (1000000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+											ul_TimerValue
+												=
+												ul_TimerValue
+												+
+												1;
+										}
+
+					   /*****************************/
+										/* Calculate the real timing */
+					   /*****************************/
+
+										ul_RealTimingInterval
+											=
+											(ULONG)
+											(ul_TimerValue
+											/
+											(1000000.0
+												*
+												(double)
+												b_PCIInputClock))
+											/
+											60;
+										d_RealTimingInterval
+											=
+											(
+											(double)
+											ul_TimerValue
+											/
+											(0.001 * (double)b_PCIInputClock)) / 60.0;
+
+										if ((double)(((double)ul_TimerValue / (1000000.0 * (double)b_PCIInputClock)) / 60.0) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+											ul_RealTimingInterval
+												=
+												ul_RealTimingInterval
+												+
+												1;
+										}
+
+										ul_TimingInterval
+											=
+											ul_TimingInterval
+											-
+											1;
+										ul_TimerValue
+											=
+											ul_TimerValue
+											-
+											2;
+										if (b_PCIInputClock != APCI1710_40MHZ) {
+											ul_TimerValue
+												=
+												(ULONG)
+												(
+												(double)
+												(ul_TimerValue)
+												*
+												0.99392);
+										}
+
+										break;
+									}
+
+									fpu_end();
+
+				/****************************/
+									/* Save the PCI input clock */
+				/****************************/
+
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_ChronoModuleInfo.
+										b_PCIInputClock
+										=
+										b_PCIInputClock;
+
+				/*************************/
+									/* Save the timing unity */
+				/*************************/
+
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_ChronoModuleInfo.
+										b_TimingUnit
+										=
+										b_TimingUnit;
+
+				/************************/
+									/* Save the base timing */
+				/************************/
+
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_ChronoModuleInfo.
+										d_TimingInterval
+										=
+										d_RealTimingInterval;
+
+				/****************************/
+									/* Set the chronometer mode */
+				/****************************/
+
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_ChronoModuleInfo.
+										dw_ConfigReg
+										=
+										dw_ModeArray
+										[b_ChronoMode];
+
+				/***********************/
+									/* Test if 40 MHz used */
+				/***********************/
+
+									if (b_PCIInputClock == APCI1710_40MHZ) {
+										devpriv->
+											s_ModuleInfo
+											[b_ModulNbr].
+											s_ChronoModuleInfo.
+											dw_ConfigReg
+											=
+											devpriv->
+											s_ModuleInfo
+											[b_ModulNbr].
+											s_ChronoModuleInfo.
+											dw_ConfigReg
+											|
+											0x80;
+									}
+
+									outl(devpriv->s_ModuleInfo[b_ModulNbr].s_ChronoModuleInfo.dw_ConfigReg, devpriv->s_BoardInfos.ui_Address + 16 + (64 * b_ModulNbr));
+
+				/***********************/
+									/* Write timer 0 value */
+				/***********************/
+
+									outl(ul_TimerValue, devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr));
+
+				/*********************/
+									/* Chronometer init. */
+				/*********************/
+
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_ChronoModuleInfo.
+										b_ChronoInit
+										=
+										1;
+								} else {
+				/***********************************************/
+									/* TOR version error for 40MHz clock selection */
+				/***********************************************/
+
+									DPRINTK("TOR version error for 40MHz clock selection\n");
+									i_ReturnValue
+										=
+										-9;
+								}
+							} else {
+			     /**************************************************************/
+								/* You can not used the 40MHz clock selection wich this board */
+			     /**************************************************************/
+
+								DPRINTK("You can not used the 40MHz clock selection wich this board\n");
+								i_ReturnValue =
+									-8;
+							}
+						} else {
+			  /**********************************/
+							/* Base timing selection is wrong */
+			  /**********************************/
+
+							DPRINTK("Base timing selection is wrong\n");
+							i_ReturnValue = -7;
+						}
+					}	// if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+					else {
+		       /***********************************/
+						/* Timing unity selection is wrong */
+		       /***********************************/
+
+						DPRINTK("Timing unity selection is wrong\n");
+						i_ReturnValue = -6;
+					}	// if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+				}	// if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ))
+				else {
+		    /*****************************************/
+					/* The selected PCI input clock is wrong */
+		    /*****************************************/
+
+					DPRINTK("The selected PCI input clock is wrong\n");
+					i_ReturnValue = -5;
+				}	// if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ))
+			}	// if (b_ChronoMode >= 0 && b_ChronoMode <= 7)
+			else {
+		 /***************************************/
+				/* Chronometer mode selection is wrong */
+		 /***************************************/
+
+				DPRINTK("Chronometer mode selection is wrong\n");
+				i_ReturnValue = -4;
+			}	// if (b_ChronoMode >= 0 && b_ChronoMode <= 7)
+		} else {
+	      /******************************************/
+			/* The module is not a Chronometer module */
+	      /******************************************/
+
+			DPRINTK("The module is not a Chronometer module\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /***********************/
+		/* Module number error */
+	   /***********************/
+
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+	data[0] = ul_RealTimingInterval;
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_EnableChrono                          |
+|                                               (BYTE_ b_BoardHandle,        |
+|                                                BYTE_ b_ModulNbr,           |
+|                                                BYTE_ b_CycleMode,          |
+|                                                BYTE_ b_InterruptEnable)
+INT i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev,
+struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)						 |
++----------------------------------------------------------------------------+
+| Task              : Enable the chronometer from selected module            |
+|                     (b_ModulNbr). You must calling the                     |
+|                     "i_APCI1710_InitChrono" function be for you call this  |
+|                     function.                                              |
+|                     If you enable the chronometer interrupt, the           |
+|                     chronometer generate a interrupt after the stop signal.|
+|                     See function "i_APCI1710_SetBoardIntRoutineX" and the  |
+|                     Interrupt mask description chapter from this manual.   |
+|                     The b_CycleMode parameter determine if you will        |
+|                     measured a single or more cycle.
+
+|					  Disable the chronometer from selected module           |
+|                     (b_ModulNbr). If you disable the chronometer after a   |
+|                     start signal occur and you restart the chronometer     |
+|                     witch the " i_APCI1710_EnableChrono" function, if no   |
+|                     stop signal occur this start signal is ignored.
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle  : Handle of board APCI-1710       |
+|                     BYTE_ b_ModulNbr   CR_AREF(chanspec)  : Selected module number (0 to 3) |
+                                  data[0]  ENABle/Disable chrono
+|                     BYTE_ b_CycleMode    : Selected the chronometer        |
+|                                  data[1]           acquisition mode                |
+|                     BYTE_ b_InterruptEnable : Enable or disable the        |
+|                                   data[2]            chronometer interrupt.       |
+|                                               APCI1710_ENABLE:             |
+|                                               Enable the chronometer       |
+|                                               interrupt                    |
+|                                               APCI1710_DISABLE:            |
+|                                               Disable the chronometer      |
+|                                               interrupt                    |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: Module selection wrong                             |
+|                     -3: The module is not a Chronometer module             |
+|                     -4: Chronometer not initialised see function           |
+|                         "i_APCI1710_InitChrono"                            |
+|                     -5: Chronometer acquisition mode cycle is wrong        |
+|                     -6: Interrupt parameter is wrong                       |
+|                     -7: Interrupt function not initialised.                |
+|                         See function "i_APCI1710_SetBoardIntRoutineX"
+                      -8: data[0] wrong input    |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = 0;
+	BYTE b_ModulNbr, b_CycleMode, b_InterruptEnable, b_Action;
+	b_ModulNbr = CR_AREF(insn->chanspec);
+	b_Action = (BYTE) data[0];
+	b_CycleMode = (BYTE) data[1];
+	b_InterruptEnable = (BYTE) data[2];
+	i_ReturnValue = insn->n;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /***********************/
+		/* Test if chronometer */
+	   /***********************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_CHRONOMETER) {
+	      /***********************************/
+			/* Test if chronometer initialised */
+	      /***********************************/
+
+			if (devpriv->s_ModuleInfo[b_ModulNbr].
+				s_ChronoModuleInfo.b_ChronoInit == 1) {
+
+				switch (b_Action) {
+
+				case APCI1710_ENABLE:
+
+		 /*********************************/
+					/* Test the cycle mode parameter */
+		 /*********************************/
+
+					if ((b_CycleMode == APCI1710_SINGLE)
+						|| (b_CycleMode ==
+							APCI1710_CONTINUOUS)) {
+		    /***************************/
+						/* Test the interrupt flag */
+		    /***************************/
+
+						if ((b_InterruptEnable ==
+								APCI1710_ENABLE)
+							|| (b_InterruptEnable ==
+								APCI1710_DISABLE))
+						{
+
+			  /***************************/
+							/* Save the interrupt flag */
+			  /***************************/
+
+							devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_ChronoModuleInfo.
+								b_InterruptMask
+								=
+								b_InterruptEnable;
+
+			  /***********************/
+							/* Save the cycle mode */
+			  /***********************/
+
+							devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_ChronoModuleInfo.
+								b_CycleMode =
+								b_CycleMode;
+
+							devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_ChronoModuleInfo.
+								dw_ConfigReg =
+								(devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_ChronoModuleInfo.
+								dw_ConfigReg &
+								0x8F) | ((1 &
+									b_InterruptEnable)
+								<< 5) | ((1 &
+									b_CycleMode)
+								<< 6) | 0x10;
+
+			  /*****************************/
+							/* Test if interrupt enabled */
+			  /*****************************/
+
+							if (b_InterruptEnable ==
+								APCI1710_ENABLE)
+							{
+			     /****************************/
+								/* Clear the interrupt flag */
+			     /****************************/
+
+								outl(devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_ChronoModuleInfo.
+									dw_ConfigReg,
+									devpriv->
+									s_BoardInfos.
+									ui_Address
+									+ 32 +
+									(64 * b_ModulNbr));
+								devpriv->tsk_Current = current;	// Save the current process task structure
+							}
+
+			  /***********************************/
+							/* Enable or disable the interrupt */
+							/* Enable the chronometer          */
+			  /***********************************/
+
+							outl(devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_ChronoModuleInfo.
+								dw_ConfigReg,
+								devpriv->
+								s_BoardInfos.
+								ui_Address +
+								16 +
+								(64 * b_ModulNbr));
+
+			  /*************************/
+							/* Clear status register */
+			  /*************************/
+
+							outl(0, devpriv->
+								s_BoardInfos.
+								ui_Address +
+								36 +
+								(64 * b_ModulNbr));
+
+						}	// if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE))
+						else {
+		       /********************************/
+							/* Interrupt parameter is wrong */
+		       /********************************/
+
+							DPRINTK("Interrupt parameter is wrong\n");
+							i_ReturnValue = -6;
+						}	// if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE))
+					}	// if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS))
+					else {
+		    /***********************************************/
+						/* Chronometer acquisition mode cycle is wrong */
+		    /***********************************************/
+
+						DPRINTK("Chronometer acquisition mode cycle is wrong\n");
+						i_ReturnValue = -5;
+					}	// if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS))
+					break;
+
+				case APCI1710_DISABLE:
+
+					devpriv->s_ModuleInfo[b_ModulNbr].
+						s_ChronoModuleInfo.
+						b_InterruptMask = 0;
+
+					devpriv->s_ModuleInfo[b_ModulNbr].
+						s_ChronoModuleInfo.
+						dw_ConfigReg =
+						devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_ChronoModuleInfo.
+						dw_ConfigReg & 0x2F;
+
+		 /***************************/
+					/* Disable the interrupt   */
+					/* Disable the chronometer */
+		 /***************************/
+
+					outl(devpriv->s_ModuleInfo[b_ModulNbr].
+						s_ChronoModuleInfo.dw_ConfigReg,
+						devpriv->s_BoardInfos.
+						ui_Address + 16 +
+						(64 * b_ModulNbr));
+
+		 /***************************/
+					/* Test if continuous mode */
+		 /***************************/
+
+					if (devpriv->s_ModuleInfo[b_ModulNbr].
+						s_ChronoModuleInfo.
+						b_CycleMode ==
+						APCI1710_CONTINUOUS) {
+		    /*************************/
+						/* Clear status register */
+		    /*************************/
+
+						outl(0, devpriv->s_BoardInfos.
+							ui_Address + 36 +
+							(64 * b_ModulNbr));
+					}
+					break;
+
+				default:
+					DPRINTK("Inputs wrong! Enable or Disable chrono\n");
+					i_ReturnValue = -8;
+				}	// switch ENABLE/DISABLE
+			} else {
+		 /*******************************/
+				/* Chronometer not initialised */
+		 /*******************************/
+
+				DPRINTK("Chronometer not initialised\n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /******************************************/
+			/* The module is not a Chronometer module */
+	      /******************************************/
+
+			DPRINTK("The module is not a Chronometer module\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /***********************/
+		/* Module number error */
+	   /***********************/
+
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     :INT	i_APCI1710_InsnReadChrono(struct comedi_device *dev,struct comedi_subdevice *s,
+struct comedi_insn *insn,unsigned int *data)                   |
++----------------------------------------------------------------------------+
+| Task              : Read  functions for Timer                                     |
++----------------------------------------------------------------------------+
+| Input Parameters  :
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnReadChrono(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	BYTE b_ReadType;
+	INT i_ReturnValue = insn->n;
+
+	b_ReadType = CR_CHAN(insn->chanspec);
+
+	switch (b_ReadType) {
+	case APCI1710_CHRONO_PROGRESS_STATUS:
+		i_ReturnValue = i_APCI1710_GetChronoProgressStatus(dev,
+			(BYTE) CR_AREF(insn->chanspec), (PBYTE) & data[0]);
+		break;
+
+	case APCI1710_CHRONO_READVALUE:
+		i_ReturnValue = i_APCI1710_ReadChronoValue(dev,
+			(BYTE) CR_AREF(insn->chanspec),
+			(UINT) insn->unused[0],
+			(PBYTE) & data[0], (PULONG) & data[1]);
+		break;
+
+	case APCI1710_CHRONO_CONVERTVALUE:
+		i_ReturnValue = i_APCI1710_ConvertChronoValue(dev,
+			(BYTE) CR_AREF(insn->chanspec),
+			(ULONG) insn->unused[0],
+			(PULONG) & data[0],
+			(PBYTE) & data[1],
+			(PBYTE) & data[2],
+			(PUINT) & data[3],
+			(PUINT) & data[4], (PUINT) & data[5]);
+		break;
+
+	case APCI1710_CHRONO_READINTERRUPT:
+		printk("In Chrono Read Interrupt\n");
+
+		data[0] = devpriv->s_InterruptParameters.
+			s_FIFOInterruptParameters[devpriv->
+			s_InterruptParameters.ui_Read].b_OldModuleMask;
+		data[1] = devpriv->s_InterruptParameters.
+			s_FIFOInterruptParameters[devpriv->
+			s_InterruptParameters.ui_Read].ul_OldInterruptMask;
+		data[2] = devpriv->s_InterruptParameters.
+			s_FIFOInterruptParameters[devpriv->
+			s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
+
+			     /**************************/
+		/* Increment the read FIFO */
+			     /***************************/
+
+		devpriv->
+			s_InterruptParameters.
+			ui_Read = (devpriv->
+			s_InterruptParameters.
+			ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+		break;
+
+	default:
+		printk("ReadType Parameter wrong\n");
+	}
+
+	if (i_ReturnValue >= 0)
+		i_ReturnValue = insn->n;
+	return (i_ReturnValue);
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_GetChronoProgressStatus               |
+|                               (BYTE_    b_BoardHandle,                     |
+|                                BYTE_    b_ModulNbr,                        |
+|                                PBYTE_  pb_ChronoStatus)                    |
++----------------------------------------------------------------------------+
+| Task              : Return the chronometer status (pb_ChronoStatus) from   |
+|                     selected chronometer module (b_ModulNbr).              |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle  : Handle of board APCI-1710       |
+|                     BYTE_ b_ModulNbr     : Selected module number (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_  pb_ChronoStatus : Return the chronometer      |
+|                                                status.                     |
+|                                                0 : Measurement not started.|
+|                                                    No start signal occur.  |
+|                                                1 : Measurement started.    |
+|                                                    A start signal occur.   |
+|                                                2 : Measurement stopped.    |
+|                                                    A stop signal occur.    |
+|                                                    The measurement is      |
+|                                                    terminate.              |
+|                                                3: A overflow occur. You    |
+|                                                   must change the base     |
+|                                                   timing witch the         |
+|                                                   function                 |
+|                                                   "i_APCI1710_InitChrono"  |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: Module selection wrong                             |
+|                     -3: The module is not a Chronometer module             |
+|                     -4: Chronometer not initialised see function           |
+|                         "i_APCI1710_InitChrono"                            |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetChronoProgressStatus(struct comedi_device * dev,
+	BYTE b_ModulNbr, PBYTE pb_ChronoStatus)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_Status;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /***********************/
+		/* Test if chronometer */
+	   /***********************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_CHRONOMETER) {
+	      /***********************************/
+			/* Test if chronometer initialised */
+	      /***********************************/
+
+			if (devpriv->
+				s_ModuleInfo[b_ModulNbr].
+				s_ChronoModuleInfo.b_ChronoInit == 1) {
+
+				dw_Status = inl(devpriv->s_BoardInfos.
+					ui_Address + 8 + (64 * b_ModulNbr));
+
+		 /********************/
+				/* Test if overflow */
+		 /********************/
+
+				if ((dw_Status & 8) == 8) {
+		    /******************/
+					/* Overflow occur */
+		    /******************/
+
+					*pb_ChronoStatus = 3;
+				}	// if ((dw_Status & 8) == 8)
+				else {
+		    /*******************************/
+					/* Test if measurement stopped */
+		    /*******************************/
+
+					if ((dw_Status & 2) == 2) {
+		       /***********************/
+						/* A stop signal occur */
+		       /***********************/
+
+						*pb_ChronoStatus = 2;
+					}	// if ((dw_Status & 2) == 2)
+					else {
+		       /*******************************/
+						/* Test if measurement started */
+		       /*******************************/
+
+						if ((dw_Status & 1) == 1) {
+			  /************************/
+							/* A start signal occur */
+			  /************************/
+
+							*pb_ChronoStatus = 1;
+						}	// if ((dw_Status & 1) == 1)
+						else {
+			  /***************************/
+							/* Measurement not started */
+			  /***************************/
+
+							*pb_ChronoStatus = 0;
+						}	// if ((dw_Status & 1) == 1)
+					}	// if ((dw_Status & 2) == 2)
+				}	// if ((dw_Status & 8) == 8)
+			} else {
+		 /*******************************/
+				/* Chronometer not initialised */
+		 /*******************************/
+				DPRINTK("Chronometer not initialised\n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /******************************************/
+			/* The module is not a Chronometer module */
+	      /******************************************/
+			DPRINTK("The module is not a Chronometer module\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /***********************/
+		/* Module number error */
+	   /***********************/
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_ReadChronoValue                       |
+|                               (BYTE_     b_BoardHandle,                    |
+|                                BYTE_     b_ModulNbr,                       |
+|                                UINT_    ui_TimeOut,                        |
+|                                PBYTE_   pb_ChronoStatus,                   |
+|                                PULONG_ pul_ChronoValue)                    |
++----------------------------------------------------------------------------+
+| Task              : Return the chronometer status (pb_ChronoStatus) and the|
+|                     timing value (pul_ChronoValue) after a stop signal     |
+|                     occur from selected chronometer module (b_ModulNbr).   |
+|                     This function are only avaible if you have disabled    |
+|                     the interrupt functionality. See function              |
+|                     "i_APCI1710_EnableChrono" and the Interrupt mask       |
+|                     description chapter.                                   |
+|                     You can test the chronometer status witch the          |
+|                     "i_APCI1710_GetChronoProgressStatus" function.         |
+|                                                                            |
+|                     The returned value from pul_ChronoValue parameter is   |
+|                     not real measured timing.                              |
+|                     You must used the "i_APCI1710_ConvertChronoValue"      |
+|                     function or make this operation for calculate the      |
+|                     timing:                                                |
+|                                                                            |
+|                     Timing = pul_ChronoValue * pul_RealTimingInterval.     |
+|                                                                            |
+|                     pul_RealTimingInterval is the returned parameter from  |
+|                     "i_APCI1710_InitChrono" function and the time unity is |
+|                     the b_TimingUnit from "i_APCI1710_InitChrono" function|
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle  : Handle of board APCI-1710       |
+|                     BYTE_ b_ModulNbr     : Selected module number (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_  pb_ChronoStatus : Return the chronometer      |
+|                                                status.                     |
+|                                                0 : Measurement not started.|
+|                                                    No start signal occur.  |
+|                                                1 : Measurement started.    |
+|                                                    A start signal occur.   |
+|                                                2 : Measurement stopped.    |
+|                                                    A stop signal occur.    |
+|                                                    The measurement is      |
+|                                                    terminate.              |
+|                                                3: A overflow occur. You    |
+|                                                   must change the base     |
+|                                                   timing witch the         |
+|                                                   function                 |
+|                                                   "i_APCI1710_InitChrono"  |
+|                     PULONG  pul_ChronoValue  : Chronometer timing value.   |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: Module selection wrong                             |
+|                     -3: The module is not a Chronometer module             |
+|                     -4: Chronometer not initialised see function           |
+|                         "i_APCI1710_InitChrono"                            |
+|                     -5: Timeout parameter is wrong (0 to 65535)            |
+|                     -6: Interrupt routine installed. You can not read      |
+|                         directly the chronometer measured timing.          |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_ReadChronoValue(struct comedi_device * dev,
+	BYTE b_ModulNbr,
+	UINT ui_TimeOut, PBYTE pb_ChronoStatus, PULONG pul_ChronoValue)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_Status;
+	DWORD dw_TimeOut = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /***********************/
+		/* Test if chronometer */
+	   /***********************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_CHRONOMETER) {
+	      /***********************************/
+			/* Test if chronometer initialised */
+	      /***********************************/
+
+			if (devpriv->
+				s_ModuleInfo[b_ModulNbr].
+				s_ChronoModuleInfo.b_ChronoInit == 1) {
+		 /*****************************/
+				/* Test the timout parameter */
+		 /*****************************/
+
+				if ((ui_TimeOut >= 0)
+					&& (ui_TimeOut <= 65535UL)) {
+
+					for (;;) {
+			  /*******************/
+						/* Read the status */
+			  /*******************/
+
+						dw_Status =
+							inl(devpriv->
+							s_BoardInfos.
+							ui_Address + 8 +
+							(64 * b_ModulNbr));
+
+			  /********************/
+						/* Test if overflow */
+			  /********************/
+
+						if ((dw_Status & 8) == 8) {
+			     /******************/
+							/* Overflow occur */
+			     /******************/
+
+							*pb_ChronoStatus = 3;
+
+			     /***************************/
+							/* Test if continuous mode */
+			     /***************************/
+
+							if (devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_ChronoModuleInfo.
+								b_CycleMode ==
+								APCI1710_CONTINUOUS)
+							{
+				/*************************/
+								/* Clear status register */
+				/*************************/
+
+								outl(0, devpriv->s_BoardInfos.ui_Address + 36 + (64 * b_ModulNbr));
+							}
+
+							break;
+						}	// if ((dw_Status & 8) == 8)
+						else {
+			     /*******************************/
+							/* Test if measurement stopped */
+			     /*******************************/
+
+							if ((dw_Status & 2) ==
+								2) {
+				/***********************/
+								/* A stop signal occur */
+				/***********************/
+
+								*pb_ChronoStatus
+									= 2;
+
+				/***************************/
+								/* Test if continnous mode */
+				/***************************/
+
+								if (devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_ChronoModuleInfo.
+									b_CycleMode
+									==
+									APCI1710_CONTINUOUS)
+								{
+				   /*************************/
+									/* Clear status register */
+				   /*************************/
+
+									outl(0, devpriv->s_BoardInfos.ui_Address + 36 + (64 * b_ModulNbr));
+								}
+								break;
+							}	// if ((dw_Status & 2) == 2)
+							else {
+				/*******************************/
+								/* Test if measurement started */
+				/*******************************/
+
+								if ((dw_Status & 1) == 1) {
+				   /************************/
+									/* A start signal occur */
+				   /************************/
+
+									*pb_ChronoStatus
+										=
+										1;
+								}	// if ((dw_Status & 1) == 1)
+								else {
+				   /***************************/
+									/* Measurement not started */
+				   /***************************/
+
+									*pb_ChronoStatus
+										=
+										0;
+								}	// if ((dw_Status & 1) == 1)
+							}	// if ((dw_Status & 2) == 2)
+						}	// if ((dw_Status & 8) == 8)
+
+						if (dw_TimeOut == ui_TimeOut) {
+			     /*****************/
+							/* Timeout occur */
+			     /*****************/
+
+							break;
+						} else {
+			     /*************************/
+							/* Increment the timeout */
+			     /*************************/
+
+							dw_TimeOut =
+								dw_TimeOut + 1;
+							mdelay(1000);
+
+						}
+					}	// for (;;)
+
+		       /*****************************/
+					/* Test if stop signal occur */
+		       /*****************************/
+
+					if (*pb_ChronoStatus == 2) {
+			  /**********************************/
+						/* Read the measured timing value */
+			  /**********************************/
+
+						*pul_ChronoValue =
+							inl(devpriv->
+							s_BoardInfos.
+							ui_Address + 4 +
+							(64 * b_ModulNbr));
+
+						if (*pul_ChronoValue != 0) {
+							*pul_ChronoValue =
+								*pul_ChronoValue
+								- 1;
+						}
+					} else {
+			  /*************************/
+						/* Test if timeout occur */
+			  /*************************/
+
+						if ((*pb_ChronoStatus != 3)
+							&& (dw_TimeOut ==
+								ui_TimeOut)
+							&& (ui_TimeOut != 0)) {
+			     /*****************/
+							/* Timeout occur */
+			     /*****************/
+
+							*pb_ChronoStatus = 4;
+						}
+					}
+
+				} else {
+		    /******************************/
+					/* Timeout parameter is wrong */
+		    /******************************/
+					DPRINTK("Timeout parameter is wrong\n");
+					i_ReturnValue = -5;
+				}
+			} else {
+		 /*******************************/
+				/* Chronometer not initialised */
+		 /*******************************/
+				DPRINTK("Chronometer not initialised\n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /******************************************/
+			/* The module is not a Chronometer module */
+	      /******************************************/
+			DPRINTK("The module is not a Chronometer module\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /***********************/
+		/* Module number error */
+	   /***********************/
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_ConvertChronoValue                    |
+|                               (BYTE_     b_BoardHandle,                    |
+|                                BYTE_     b_ModulNbr,                       |
+|                                ULONG_   ul_ChronoValue,                    |
+|                                PULONG_ pul_Hour,                           |
+|                                PBYTE_   pb_Minute,                         |
+|                                PBYTE_   pb_Second,                         |
+|                                PUINT_  pui_MilliSecond,                    |
+|                                PUINT_  pui_MicroSecond,                    |
+|                                PUINT_  pui_NanoSecond)                     |
++----------------------------------------------------------------------------+
+| Task              : Convert the chronometer measured timing                |
+|                     (ul_ChronoValue) in to h, mn, s, ms, µs, ns.           |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_   b_BoardHandle : Handle of board APCI-1710      |
+|                     BYTE_   b_ModulNbr    : Selected module number (0 to 3)|
+|                     ULONG_ ul_ChronoValue : Measured chronometer timing    |
+|                                             value.                         |
+|                                             See"i_APCI1710_ReadChronoValue"|
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_   pul_Hour        : Chronometer timing hour    |
+|                     PBYTE_     pb_Minute      : Chronometer timing minute  |
+|                     PBYTE_     pb_Second      : Chronometer timing second  |
+|                     PUINT_    pui_MilliSecond  : Chronometer timing mini   |
+|                                                 second                     |
+|                     PUINT_    pui_MicroSecond : Chronometer timing micro   |
+|                                                 second                     |
+|                     PUINT_    pui_NanoSecond  : Chronometer timing nano    |
+|                                                 second                     |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: Module selection wrong                             |
+|                     -3: The module is not a Chronometer module             |
+|                     -4: Chronometer not initialised see function           |
+|                         "i_APCI1710_InitChrono"                            |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_ConvertChronoValue(struct comedi_device * dev,
+	BYTE b_ModulNbr,
+	ULONG ul_ChronoValue,
+	PULONG pul_Hour,
+	PBYTE pb_Minute,
+	PBYTE pb_Second,
+	PUINT pui_MilliSecond, PUINT pui_MicroSecond, PUINT pui_NanoSecond)
+{
+	INT i_ReturnValue = 0;
+	double d_Hour;
+	double d_Minute;
+	double d_Second;
+	double d_MilliSecond;
+	double d_MicroSecond;
+	double d_NanoSecond;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /***********************/
+		/* Test if chronometer */
+	   /***********************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_CHRONOMETER) {
+	      /***********************************/
+			/* Test if chronometer initialised */
+	      /***********************************/
+
+			if (devpriv->
+				s_ModuleInfo[b_ModulNbr].
+				s_ChronoModuleInfo.b_ChronoInit == 1) {
+				fpu_begin();
+
+				d_Hour = (double)ul_ChronoValue *(double)
+					devpriv->s_ModuleInfo[b_ModulNbr].
+					s_ChronoModuleInfo.d_TimingInterval;
+
+				switch (devpriv->
+					s_ModuleInfo[b_ModulNbr].
+					s_ChronoModuleInfo.b_TimingUnit) {
+				case 0:
+					d_Hour = d_Hour / (double)1000.0;
+
+				case 1:
+					d_Hour = d_Hour / (double)1000.0;
+
+				case 2:
+					d_Hour = d_Hour / (double)1000.0;
+
+				case 3:
+					d_Hour = d_Hour / (double)60.0;
+
+				case 4:
+			    /**********************/
+					/* Calculate the hour */
+			    /**********************/
+
+					d_Hour = d_Hour / (double)60.0;
+					*pul_Hour = (ULONG) d_Hour;
+
+			    /************************/
+					/* Calculate the minute */
+			    /************************/
+
+					d_Minute = d_Hour - *pul_Hour;
+					d_Minute = d_Minute * 60;
+					*pb_Minute = (BYTE) d_Minute;
+
+			    /************************/
+					/* Calculate the second */
+			    /************************/
+
+					d_Second = d_Minute - *pb_Minute;
+					d_Second = d_Second * 60;
+					*pb_Second = (BYTE) d_Second;
+
+			    /*****************************/
+					/* Calculate the mini second */
+			    /*****************************/
+
+					d_MilliSecond = d_Second - *pb_Second;
+					d_MilliSecond = d_MilliSecond * 1000;
+					*pui_MilliSecond = (UINT) d_MilliSecond;
+
+			    /******************************/
+					/* Calculate the micro second */
+			    /******************************/
+
+					d_MicroSecond =
+						d_MilliSecond -
+						*pui_MilliSecond;
+					d_MicroSecond = d_MicroSecond * 1000;
+					*pui_MicroSecond = (UINT) d_MicroSecond;
+
+			    /******************************/
+					/* Calculate the micro second */
+			    /******************************/
+
+					d_NanoSecond =
+						d_MicroSecond -
+						*pui_MicroSecond;
+					d_NanoSecond = d_NanoSecond * 1000;
+					*pui_NanoSecond = (UINT) d_NanoSecond;
+					break;
+				}
+
+				fpu_end();
+			} else {
+		 /*******************************/
+				/* Chronometer not initialised */
+		 /*******************************/
+				DPRINTK("Chronometer not initialised\n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /******************************************/
+			/* The module is not a Chronometer module */
+	      /******************************************/
+			DPRINTK("The module is not a Chronometer module\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /***********************/
+		/* Module number error */
+	   /***********************/
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : INT i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev,struct comedi_subdevice *s,
+	struct comedi_insn *insn,unsigned int *data)                    |
++----------------------------------------------------------------------------+
+| Task              : Sets the output witch has been passed with the         |
+|                     parameter b_Channel. Setting an output means setting an|
+|                     output high.                                           |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle   : Handle of board APCI-1710      |
+|                     BYTE_ b_ModulNbr      : Selected module number (0 to 3)|
+|                     BYTE_ b_OutputChannel : Selection from digital output  |
+|                           CR_CHAN()                  channel (0 to 2)               |
+|                                              0 : Channel H                 |
+|                                              1 : Channel A                 |
+|                                              2 : Channel B                 |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: Module selection wrong                             |
+|                     -3: The module is not a Chronometer module             |
+|                     -4: The selected digital output is wrong               |
+|                     -5: Chronometer not initialised see function           |
+|                         "i_APCI1710_InitChrono"                            |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_SetChronoChlOff                       |
+|                               (BYTE_  b_BoardHandle,                       |
+|                                BYTE_  b_ModulNbr,                          |
+|                                BYTE_  b_OutputChannel)                     |
++----------------------------------------------------------------------------+
+| Task              : Resets the output witch has been passed with the       |
+|                     parameter b_Channel. Resetting an output means setting |
+|                     an output low.                                         |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle   : Handle of board APCI-1710
+                        data[0] : Chl ON, Chl OFF , Chl Read , Port Read
+
+|                     BYTE_ b_ModulNbr  CR_AREF    : Selected module number (0 to 3)|
+|                     BYTE_ b_OutputChannel CR_CHAN : Selection from digital output  |
+|                                             channel (0 to 2)               |
+|                                              0 : Channel H                 |
+|                                              1 : Channel A                 |
+|                                              2 : Channel B                 |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: Module selection wrong                             |
+|                     -3: The module is not a Chronometer module             |
+|                     -4: The selected digital output is wrong               |
+|                     -5: Chronometer not initialised see function           |
+|                         "i_APCI1710_InitChrono"                            |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_ReadChronoChlValue                    |
+|                               (BYTE_   b_BoardHandle,                      |
+|                                BYTE_   b_ModulNbr,                         |
+|                                BYTE_   b_InputChannel,                     |
+|                                PBYTE_ pb_ChannelStatus)                    |
++----------------------------------------------------------------------------+
+| Task              : Return the status from selected digital input          |
+|                     (b_InputChannel) from selected chronometer             |
+|                     module (b_ModulNbr).                                   |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle   : Handle of board APCI-1710      |
+|                     BYTE_ b_ModulNbr      : Selected module number (0 to 3)|
+|                     BYTE_ b_InputChannel  : Selection from digital input   |
+|                                             channel (0 to 2)               |
+|                                   CR_CHAN()             0 : Channel E               |
+|                                                1 : Channel F               |
+|                                                2 : Channel G               |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_ChannelStatus : Digital input channel status.|
+|                                data[0]                0 : Channel is not active   |
+|                                                1 : Channel is active       |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: Module selection wrong                             |
+|                     -3: The module is not a Chronometer module             |
+|                     -4: The selected digital input is wrong                |
+|                     -5: Chronometer not initialised see function           |
+|                         "i_APCI1710_InitChrono"                            |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_ReadChronoPortValue                   |
+|                               (BYTE_   b_BoardHandle,                      |
+|                                BYTE_   b_ModulNbr,                         |
+|                                PBYTE_ pb_PortValue)                        |
++----------------------------------------------------------------------------+
+| Task              : Return the status from digital inputs port from        |
+|                     selected  (b_ModulNbr) chronometer module.             |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle   : Handle of board APCI-1710      |
+|                     BYTE_ b_ModulNbr      : Selected module number (0 to 3)|
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_PortValue   : Digital inputs port status.
+|                     data[0]
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: Module selection wrong                             |
+|                     -3: The module is not a Chronometer module             |
+|                     -4: Chronometer not initialised see function           |
+|                         "i_APCI1710_InitChrono"                            |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = 0;
+	BYTE b_ModulNbr, b_OutputChannel, b_InputChannel, b_IOType;
+	DWORD dw_Status;
+	PBYTE pb_ChannelStatus;
+	PBYTE pb_PortValue;
+
+	b_ModulNbr = CR_AREF(insn->chanspec);
+	i_ReturnValue = insn->n;
+	b_IOType = (BYTE) data[0];
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /***********************/
+		/* Test if chronometer */
+	   /***********************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_CHRONOMETER) {
+	      /***********************************/
+			/* Test if chronometer initialised */
+	      /***********************************/
+
+			if (devpriv->s_ModuleInfo[b_ModulNbr].
+				s_ChronoModuleInfo.b_ChronoInit == 1) {
+		 /***********************************/
+				/* Test the digital output channel */
+		 /***********************************/
+				switch (b_IOType) {
+
+				case APCI1710_CHRONO_SET_CHANNELOFF:
+
+					b_OutputChannel =
+						(BYTE) CR_CHAN(insn->chanspec);
+					if (b_OutputChannel <= 2) {
+
+						outl(0, devpriv->s_BoardInfos.
+							ui_Address + 20 +
+							(b_OutputChannel * 4) +
+							(64 * b_ModulNbr));
+					}	// if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2))
+					else {
+		    /****************************************/
+						/* The selected digital output is wrong */
+		    /****************************************/
+
+						DPRINTK("The selected digital output is wrong\n");
+						i_ReturnValue = -4;
+
+					}	// if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2))
+
+					break;
+
+				case APCI1710_CHRONO_SET_CHANNELON:
+
+					b_OutputChannel =
+						(BYTE) CR_CHAN(insn->chanspec);
+					if (b_OutputChannel <= 2) {
+
+						outl(1, devpriv->s_BoardInfos.
+							ui_Address + 20 +
+							(b_OutputChannel * 4) +
+							(64 * b_ModulNbr));
+					}	// if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2))
+					else {
+		    /****************************************/
+						/* The selected digital output is wrong */
+		    /****************************************/
+
+						DPRINTK("The selected digital output is wrong\n");
+						i_ReturnValue = -4;
+
+					}	// if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2))
+
+					break;
+
+				case APCI1710_CHRONO_READ_CHANNEL:
+		 /**********************************/
+					/* Test the digital input channel */
+		 /**********************************/
+					pb_ChannelStatus = (PBYTE) & data[0];
+					b_InputChannel =
+						(BYTE) CR_CHAN(insn->chanspec);
+
+					if (b_InputChannel <= 2) {
+
+						dw_Status =
+							inl(devpriv->
+							s_BoardInfos.
+							ui_Address + 12 +
+							(64 * b_ModulNbr));
+
+						*pb_ChannelStatus =
+							(BYTE) (((dw_Status >>
+									b_InputChannel)
+								& 1) ^ 1);
+					}	// if ((b_InputChannel >= 0) && (b_InputChannel <= 2))
+					else {
+		    /***************************************/
+						/* The selected digital input is wrong */
+		    /***************************************/
+
+						DPRINTK("The selected digital input is wrong\n");
+						i_ReturnValue = -4;
+					}	// if ((b_InputChannel >= 0) && (b_InputChannel <= 2))
+
+					break;
+
+				case APCI1710_CHRONO_READ_PORT:
+
+					pb_PortValue = (PBYTE) & data[0];
+
+					dw_Status =
+						inl(devpriv->s_BoardInfos.
+						ui_Address + 12 +
+						(64 * b_ModulNbr));
+
+					*pb_PortValue =
+						(BYTE) ((dw_Status & 0x7) ^ 7);
+					break;
+				}
+			} else {
+		 /*******************************/
+				/* Chronometer not initialised */
+		 /*******************************/
+
+				DPRINTK("Chronometer not initialised\n");
+				i_ReturnValue = -5;
+			}
+		} else {
+	      /******************************************/
+			/* The module is not a Chronometer module */
+	      /******************************************/
+
+			DPRINTK("The module is not a Chronometer module\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /***********************/
+		/* Module number error */
+	   /***********************/
+
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h
new file mode 100644
index 0000000..26b50ce
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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.
+ */
+
+#define APCI1710_30MHZ			30
+#define APCI1710_33MHZ			33
+#define APCI1710_40MHZ			40
+
+#define APCI1710_SINGLE			0
+#define APCI1710_CONTINUOUS		1
+
+#define APCI1710_CHRONO_PROGRESS_STATUS	0
+#define APCI1710_CHRONO_READVALUE	1
+#define APCI1710_CHRONO_CONVERTVALUE	2
+#define APCI1710_CHRONO_READINTERRUPT	3
+
+#define APCI1710_CHRONO_SET_CHANNELON	0
+#define APCI1710_CHRONO_SET_CHANNELOFF	1
+#define APCI1710_CHRONO_READ_CHANNEL	2
+#define APCI1710_CHRONO_READ_PORT	3
+
+/*
+ * CHRONOMETER INISIALISATION FUNCTION
+ */
+INT i_APCI1710_InsnConfigInitChrono(struct comedi_device *dev, struct comedi_subdevice *s,
+				    struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev,
+					    struct comedi_subdevice *s,
+					    struct comedi_insn *insn,
+					    unsigned int *data);
+
+/*
+ * CHRONOMETER READ FUNCTION
+ */
+INT i_APCI1710_InsnReadChrono(struct comedi_device *dev, struct comedi_subdevice *s,
+			      struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_GetChronoProgressStatus(struct comedi_device *dev,
+				       BYTE b_ModulNbr, PBYTE pb_ChronoStatus);
+
+INT i_APCI1710_ReadChronoValue(struct comedi_device *dev,
+			       BYTE b_ModulNbr,
+			       UINT ui_TimeOut, PBYTE pb_ChronoStatus,
+			       PULONG pul_ChronoValue);
+
+INT i_APCI1710_ConvertChronoValue(struct comedi_device *dev,
+				  BYTE b_ModulNbr,
+				  ULONG ul_ChronoValue,
+				  PULONG pul_Hour,
+				  PBYTE pb_Minute,
+				  PBYTE pb_Second,
+				  PUINT pui_MilliSecond, PUINT pui_MicroSecond,
+				  PUINT pui_NanoSecond);
+
+/*
+ * CHRONOMETER DIGITAL INPUT OUTPUT FUNCTION
+ */
+INT i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev,
+				       struct comedi_subdevice *s, struct comedi_insn *insn,
+				       unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c
new file mode 100644
index 0000000..8be27ae
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c
@@ -0,0 +1,1020 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+
+        ADDI-DATA GmbH
+        Dieselstrasse 3
+        D-77833 Ottersweier
+        Tel: +19(0)7223/9493-0
+        Fax: +49(0)7223/9493-92
+        http://www.addi-data-com
+        info@addi-data.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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+  +-----------------------------------------------------------------------+
+  | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
+  +-----------------------------------------------------------------------+
+  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
+  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
+  +-----------------------------------------------------------------------+
+  | Project     : API APCI1710    | Compiler : gcc                        |
+  | Module name : DIG_IO.C        | Version  : 2.96                       |
+  +-------------------------------+---------------------------------------+
+  | Project manager: Eric Stolz   | Date     :  02/12/2002                |
+  +-----------------------------------------------------------------------+
+  | Description :   APCI-1710 digital I/O module                          |
+  |                                                                       |
+  |                                                                       |
+  +-----------------------------------------------------------------------+
+  |                             UPDATES                                   |
+  +-----------------------------------------------------------------------+
+  |   Date   |   Author  |          Description of updates                |
+  +----------+-----------+------------------------------------------------+
+  | 16/06/98 | S. Weber  | Digital input / output implementation          |
+  |----------|-----------|------------------------------------------------|
+  | 08/05/00 | Guinot C  | - 0400/0228 All Function in RING 0             |
+  |          |           |   available                                    |
+  +-----------------------------------------------------------------------+
+  |          |           |                                                |
+  |          |           |                                                |
+  +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+|                               Included files                               |
++----------------------------------------------------------------------------+
+*/
+#include "APCI1710_Dig_io.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : INT i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, |
+|						struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)|
++----------------------------------------------------------------------------+
+| Task              : Configure the digital I/O operating mode from selected |
+|                     module  (b_ModulNbr). You must calling this function be|
+|                     for you call any other function witch access of digital|
+|                     I/O.                                                   |
++----------------------------------------------------------------------------+
+| Input Parameters  :													     |
+|                  BYTE_ b_ModulNbr      data[0]: Module number to               |
+|                                             configure (0 to 3)             |
+|                     BYTE_ b_ChannelAMode data[1]  : Channel A mode selection       |
+|                                             0 : Channel used for digital   |
+|                                                 input                      |
+|                                             1 : Channel used for digital   |
+|                                                 output                     |
+|                     BYTE_ b_ChannelBMode data[2] : Channel B mode selection       |
+|                                             0 : Channel used for digital   |
+|                                                 input                      |
+|                                             1 : Channel used for digital   |
+|                                                 output					 |
+						data[0]	  memory on/off
+Activates and deactivates the digital output memory.
+						After having      |
+|                 called up this function with memory on,the output you have previously|
+|                     activated with the function are not reset
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : 0: No error                                            |
+|                    -1: The handle parameter of the board is wrong          |
+|                    -2: The module parameter is wrong                       |
+|                    -3: The module is not a digital I/O module              |
+|                    -4: Bi-directional channel A configuration error        |
+|                    -5: Bi-directional channel B configuration error        |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigDigitalIO(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	BYTE b_ModulNbr, b_ChannelAMode, b_ChannelBMode;
+	BYTE b_MemoryOnOff, b_ConfigType;
+	INT i_ReturnValue = 0;
+	DWORD dw_WriteConfig = 0;
+
+	b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+	b_ConfigType = (BYTE) data[0];	// Memory or  Init
+	b_ChannelAMode = (BYTE) data[1];
+	b_ChannelBMode = (BYTE) data[2];
+	b_MemoryOnOff = (BYTE) data[1];	// if memory operation
+	i_ReturnValue = insn->n;
+
+		/**************************/
+	/* Test the module number */
+		/**************************/
+
+	if (b_ModulNbr >= 4) {
+		DPRINTK("Module Number invalid\n");
+		i_ReturnValue = -2;
+		return i_ReturnValue;
+	}
+	switch (b_ConfigType) {
+	case APCI1710_DIGIO_MEMORYONOFF:
+
+		if (b_MemoryOnOff)	// If Memory ON
+		{
+		 /****************************/
+			/* Set the output memory on */
+		 /****************************/
+
+			devpriv->s_ModuleInfo[b_ModulNbr].
+				s_DigitalIOInfo.b_OutputMemoryEnabled = 1;
+
+		 /***************************/
+			/* Clear the output memory */
+		 /***************************/
+			devpriv->s_ModuleInfo[b_ModulNbr].
+				s_DigitalIOInfo.dw_OutputMemory = 0;
+		} else		// If memory off
+		{
+		 /*****************************/
+			/* Set the output memory off */
+		 /*****************************/
+
+			devpriv->s_ModuleInfo[b_ModulNbr].
+				s_DigitalIOInfo.b_OutputMemoryEnabled = 0;
+		}
+		break;
+
+	case APCI1710_DIGIO_INIT:
+
+	/*******************************/
+		/* Test if digital I/O counter */
+	/*******************************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
+
+	/***************************************************/
+			/* Test the bi-directional channel A configuration */
+	/***************************************************/
+
+			if ((b_ChannelAMode == 0) || (b_ChannelAMode == 1)) {
+	/***************************************************/
+				/* Test the bi-directional channel B configuration */
+	/***************************************************/
+
+				if ((b_ChannelBMode == 0)
+					|| (b_ChannelBMode == 1)) {
+					devpriv->s_ModuleInfo[b_ModulNbr].
+						s_DigitalIOInfo.b_DigitalInit =
+						1;
+
+	/********************************/
+					/* Save channel A configuration */
+	/********************************/
+
+					devpriv->s_ModuleInfo[b_ModulNbr].
+						s_DigitalIOInfo.
+						b_ChannelAMode = b_ChannelAMode;
+
+	/********************************/
+					/* Save channel B configuration */
+	/********************************/
+
+					devpriv->s_ModuleInfo[b_ModulNbr].
+						s_DigitalIOInfo.
+						b_ChannelBMode = b_ChannelBMode;
+
+	/*****************************************/
+					/* Set the channel A and B configuration */
+	/*****************************************/
+
+					dw_WriteConfig =
+						(DWORD) (b_ChannelAMode |
+						(b_ChannelBMode * 2));
+
+	/***************************/
+					/* Write the configuration */
+	/***************************/
+
+					outl(dw_WriteConfig,
+						devpriv->s_BoardInfos.
+						ui_Address + 4 +
+						(64 * b_ModulNbr));
+
+				} else {
+	/************************************************/
+					/* Bi-directional channel B configuration error */
+	/************************************************/
+					DPRINTK("Bi-directional channel B configuration error\n");
+					i_ReturnValue = -5;
+				}
+
+			} else {
+	/************************************************/
+				/* Bi-directional channel A configuration error */
+	/************************************************/
+				DPRINTK("Bi-directional channel A configuration error\n");
+				i_ReturnValue = -4;
+
+			}
+
+		} else {
+	/******************************************/
+			/* The module is not a digital I/O module */
+	/******************************************/
+			DPRINTK("The module is not a digital I/O module\n");
+			i_ReturnValue = -3;
+		}
+	}			// end of Switch
+	printk("Return Value %d\n", i_ReturnValue);
+	return i_ReturnValue;
+}
+
+/*
++----------------------------------------------------------------------------+
+|                            INPUT FUNCTIONS                                 |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+
+|INT i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev,comedi_subdevice
+*s,	struct comedi_insn *insn,unsigned int *data)
+
++----------------------------------------------------------------------------+
+| Task              : Read the status from selected digital I/O digital input|
+|                     (b_InputChannel)                                       |
++----------------------------------------------------------------------------|
+
+
+|
+|  BYTE_ b_ModulNbr  CR_AREF(chanspec)          : Selected module number   |
+|                                                   (0 to 3)                 |
+|  BYTE_ b_InputChannel CR_CHAN(chanspec)        : Selection from digital   |
+|                                                   input ( 0 to 6)          |
+|                                                      0 : Channel C         |
+|                                                      1 : Channel D         |
+|                                                      2 : Channel E         |
+|                                                      3 : Channel F         |
+|                                                      4 : Channel G         |
+|                                                      5 : Channel A         |
+|                                                      6 : Channel B
+
+
+	|
++----------------------------------------------------------------------------+
+| Output Parameters :					 data[0]   : Digital input channel    |
+|                                                   status                   |
+|                                                   0 : Channle is not active|
+|                                                   1 : Channle is active    |
++----------------------------------------------------------------------------+
+| Return Value      : 0: No error                                            |
+|                    -1: The handle parameter of the board is wrong          |
+|                    -2: The module parameter is wrong                       |
+|                    -3: The module is not a digital I/O module              |
+|                    -4: The selected digital I/O digital input is wrong     |
+|                    -5: Digital I/O not initialised                         |
+|                    -6: The digital channel A is used for output            |
+|                    -7: The digital channel B is used for output            |
++----------------------------------------------------------------------------+
+*/
+
+//_INT_   i_APCI1710_ReadDigitalIOChlValue      (BYTE_    b_BoardHandle,
+//                                             BYTE_    b_ModulNbr,
+//                                             BYTE_    b_InputChannel,
+//
+//                                             PBYTE_  pb_ChannelStatus)
+INT i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_StatusReg;
+	BYTE b_ModulNbr, b_InputChannel;
+	PBYTE pb_ChannelStatus;
+	b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+	b_InputChannel = (BYTE) CR_CHAN(insn->chanspec);
+	data[0] = 0;
+	pb_ChannelStatus = (PBYTE) & data[0];
+	i_ReturnValue = insn->n;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if digital I/O counter */
+	   /*******************************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
+	      /******************************************/
+			/* Test the digital imnput channel number */
+	      /******************************************/
+
+			if (b_InputChannel <= 6) {
+		 /**********************************************/
+				/* Test if the digital I/O module initialised */
+		 /**********************************************/
+
+				if (devpriv->s_ModuleInfo[b_ModulNbr].
+					s_DigitalIOInfo.b_DigitalInit == 1) {
+		    /**********************************/
+					/* Test if channel A or channel B */
+		    /**********************************/
+
+					if (b_InputChannel > 4) {
+		       /*********************/
+						/* Test if channel A */
+		       /*********************/
+
+						if (b_InputChannel == 5) {
+			  /***************************/
+							/* Test the channel A mode */
+			  /***************************/
+
+							if (devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_DigitalIOInfo.
+								b_ChannelAMode
+								!= 0) {
+			     /********************************************/
+								/* The digital channel A is used for output */
+			     /********************************************/
+
+								i_ReturnValue =
+									-6;
+							}
+						}	// if (b_InputChannel == 5)
+						else {
+			  /***************************/
+							/* Test the channel B mode */
+			  /***************************/
+
+							if (devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_DigitalIOInfo.
+								b_ChannelBMode
+								!= 0) {
+			     /********************************************/
+								/* The digital channel B is used for output */
+			     /********************************************/
+
+								i_ReturnValue =
+									-7;
+							}
+						}	// if (b_InputChannel == 5)
+					}	// if (b_InputChannel > 4)
+
+		    /***********************/
+					/* Test if error occur */
+		    /***********************/
+
+					if (i_ReturnValue >= 0) {
+		       /**************************/
+						/* Read all digital input */
+		       /**************************/
+
+						//INPDW (ps_APCI1710Variable->
+						//   s_Board [b_BoardHandle].
+						//   s_BoardInfos.
+						//  ui_Address + (64 * b_ModulNbr),
+						// &dw_StatusReg);
+
+						dw_StatusReg =
+							inl(devpriv->
+							s_BoardInfos.
+							ui_Address +
+							(64 * b_ModulNbr));
+
+						*pb_ChannelStatus =
+							(BYTE) ((dw_StatusReg ^
+								0x1C) >>
+							b_InputChannel) & 1;
+
+					}	// if (i_ReturnValue == 0)
+				} else {
+		    /*******************************/
+					/* Digital I/O not initialised */
+		    /*******************************/
+					DPRINTK("Digital I/O not initialised\n");
+					i_ReturnValue = -5;
+				}
+			} else {
+		 /********************************/
+				/* Selected digital input error */
+		 /********************************/
+				DPRINTK("Selected digital input error\n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /******************************************/
+			/* The module is not a digital I/O module */
+	      /******************************************/
+			DPRINTK("The module is not a digital I/O module\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /***********************/
+		/* Module number error */
+	   /***********************/
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+|                            OUTPUT FUNCTIONS                                |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : INT i_APCI1710_InsnWriteDigitalIOChlOnOff(comedi_device
+|*dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)
+
++----------------------------------------------------------------------------+
+| Task              : Sets or resets the output witch has been passed with the         |
+|                     parameter b_Channel. Setting an output means setting   |
+|                     an ouput high.                                         |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle   : Handle of board APCI-1710      |
+|                     BYTE_ b_ModulNbr (aref )    : Selected module number (0 to 3)|
+|                     BYTE_ b_OutputChannel (CR_CHAN) : Selection from digital output  |
+|                                             channel (0 to 2)               |
+|                                                0 : Channel H               |
+|                                                1 : Channel A               |
+|                                                2 : Channel B               |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : 0: No error                                            |
+|                    -1: The handle parameter of the board is wrong          |
+|                    -2: The module parameter is wrong                       |
+|                    -3: The module is not a digital I/O module              |
+|                    -4: The selected digital output is wrong                |
+|                    -5: digital I/O not initialised see function            |
+|                        " i_APCI1710_InitDigitalIO"                         |
+|                    -6: The digital channel A is used for input             |
+|                    -7: The digital channel B is used for input
+					 -8: Digital Output Memory OFF.                          |
+|                        Use previously the function                         |
+|                        "i_APCI1710_SetDigitalIOMemoryOn".            |
++----------------------------------------------------------------------------+
+*/
+
+//_INT_   i_APCI1710_SetDigitalIOChlOn    (BYTE_ b_BoardHandle,
+//                                       BYTE_ b_ModulNbr,
+//                                       BYTE_ b_OutputChannel)
+INT i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_WriteValue = 0;
+	BYTE b_ModulNbr, b_OutputChannel;
+	i_ReturnValue = insn->n;
+	b_ModulNbr = CR_AREF(insn->chanspec);
+	b_OutputChannel = CR_CHAN(insn->chanspec);
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if digital I/O counter */
+	   /*******************************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
+	      /**********************************************/
+			/* Test if the digital I/O module initialised */
+	      /**********************************************/
+
+			if (devpriv->s_ModuleInfo[b_ModulNbr].
+				s_DigitalIOInfo.b_DigitalInit == 1) {
+		 /******************************************/
+				/* Test the digital output channel number */
+		 /******************************************/
+
+				switch (b_OutputChannel) {
+		    /*************/
+					/* Channel H */
+		    /*************/
+
+				case 0:
+					break;
+
+		    /*************/
+					/* Channel A */
+		    /*************/
+
+				case 1:
+					if (devpriv->s_ModuleInfo[b_ModulNbr].
+						s_DigitalIOInfo.
+						b_ChannelAMode != 1) {
+			    /*******************************************/
+						/* The digital channel A is used for input */
+			    /*******************************************/
+
+						i_ReturnValue = -6;
+					}
+					break;
+
+		    /*************/
+					/* Channel B */
+		    /*************/
+
+				case 2:
+					if (devpriv->s_ModuleInfo[b_ModulNbr].
+						s_DigitalIOInfo.
+						b_ChannelBMode != 1) {
+			    /*******************************************/
+						/* The digital channel B is used for input */
+			    /*******************************************/
+
+						i_ReturnValue = -7;
+					}
+					break;
+
+				default:
+			 /****************************************/
+					/* The selected digital output is wrong */
+			 /****************************************/
+
+					i_ReturnValue = -4;
+					break;
+				}
+
+		 /***********************/
+				/* Test if error occur */
+		 /***********************/
+
+				if (i_ReturnValue >= 0) {
+
+			/*********************************/
+					/* Test if set channel ON        */
+		    /*********************************/
+					if (data[0]) {
+		    /*********************************/
+						/* Test if output memory enabled */
+		    /*********************************/
+
+						if (devpriv->
+							s_ModuleInfo
+							[b_ModulNbr].
+							s_DigitalIOInfo.
+							b_OutputMemoryEnabled ==
+							1) {
+							dw_WriteValue =
+								devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_DigitalIOInfo.
+								dw_OutputMemory
+								| (1 <<
+								b_OutputChannel);
+
+							devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_DigitalIOInfo.
+								dw_OutputMemory
+								= dw_WriteValue;
+						} else {
+							dw_WriteValue =
+								1 <<
+								b_OutputChannel;
+						}
+					}	// set channel off
+					else {
+						if (devpriv->
+							s_ModuleInfo
+							[b_ModulNbr].
+							s_DigitalIOInfo.
+							b_OutputMemoryEnabled ==
+							1) {
+							dw_WriteValue =
+								devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_DigitalIOInfo.
+								dw_OutputMemory
+								& (0xFFFFFFFFUL
+								-
+								(1 << b_OutputChannel));
+
+							devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_DigitalIOInfo.
+								dw_OutputMemory
+								= dw_WriteValue;
+						} else {
+		       /*****************************/
+							/* Digital Output Memory OFF */
+		       /*****************************/
+							// +Use previously the function "i_APCI1710_SetDigitalIOMemoryOn"
+							i_ReturnValue = -8;
+						}
+
+					}
+		    /*******************/
+					/* Write the value */
+		    /*******************/
+
+					//OUTPDW (ps_APCI1710Variable->
+					//    s_Board [b_BoardHandle].
+					//   s_BoardInfos.
+					//   ui_Address + (64 * b_ModulNbr),
+					//   dw_WriteValue);
+					outl(dw_WriteValue,
+						devpriv->s_BoardInfos.
+						ui_Address + (64 * b_ModulNbr));
+				}
+			} else {
+		 /*******************************/
+				/* Digital I/O not initialised */
+		 /*******************************/
+
+				i_ReturnValue = -5;
+			}
+		} else {
+	      /******************************************/
+			/* The module is not a digital I/O module */
+	      /******************************************/
+
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /***********************/
+		/* Module number error */
+	   /***********************/
+
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+
+|INT i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev,comedi_subdevice
+	*s,	struct comedi_insn *insn,unsigned int *data)
++----------------------------------------------------------------------------+
+| Task              : write:
+					  Sets or resets one or several outputs from port.                 |
+|                     Setting an output means setting an output high.        |
+|                     If you have switched OFF the digital output memory     |
+|                     (OFF), all the other output are set to "0".
+
+|                      read:
+					  Read the status from digital input port                |
+|                     from selected digital I/O module (b_ModulNbr)
++----------------------------------------------------------------------------+
+| Input Parameters  :
+	BYTE_ b_BoardHandle   : Handle of board APCI-1710      |
+|   BYTE_ b_ModulNbr  CR_AREF(aref)    : Selected module number (0 to 3)|
+|   BYTE_ b_PortValue CR_CHAN(chanspec) : Output Value ( 0 To 7 )
+|                       data[0]           read or write port
+                        data[1]            if write then indicate ON or OFF
+
+                        if read : data[1] will return port status.
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :
+
+                INPUT :
+
+					  0: No error                                            |
+|                    -1: The handle parameter of the board is wrong          |
+|                    -2: The module parameter is wrong                       |
+|                    -3: The module is not a digital I/O module              |
+|                    -4: Digital I/O not initialised
+
+				OUTPUT:	  0: No error                                            |
+|                    -1: The handle parameter of the board is wrong          |
+|                    -2: The module parameter is wrong                       |
+|                    -3: The module is not a digital I/O module              |
+|                    -4: Output value wrong                                  |
+|                    -5: digital I/O not initialised see function            |
+|                        " i_APCI1710_InitDigitalIO"                         |
+|                    -6: The digital channel A is used for input             |
+|                    -7: The digital channel B is used for input
+					-8: Digital Output Memory OFF.                          |
+|                        Use previously the function                         |
+|                        "i_APCI1710_SetDigitalIOMemoryOn".               |
++----------------------------------------------------------------------------+
+*/
+
+//_INT_   i_APCI1710_SetDigitalIOPortOn   (BYTE_ b_BoardHandle,
+//                                       BYTE_ b_ModulNbr,
+//                                       BYTE_ b_PortValue)
+INT i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_WriteValue = 0;
+	DWORD dw_StatusReg;
+	BYTE b_ModulNbr, b_PortValue;
+	BYTE b_PortOperation, b_PortOnOFF;
+
+	PBYTE pb_PortValue;
+
+	b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+	b_PortOperation = (BYTE) data[0];	// Input or output
+	b_PortOnOFF = (BYTE) data[1];	// if output then On or Off
+	b_PortValue = (BYTE) data[2];	// if out put then Value
+	i_ReturnValue = insn->n;
+	pb_PortValue = (PBYTE) & data[0];
+// if input then read value
+
+	switch (b_PortOperation) {
+	case APCI1710_INPUT:
+	/**************************/
+		/* Test the module number */
+	/**************************/
+
+		if (b_ModulNbr < 4) {
+	   /*******************************/
+			/* Test if digital I/O counter */
+	   /*******************************/
+
+			if ((devpriv->s_BoardInfos.
+					dw_MolduleConfiguration[b_ModulNbr] &
+					0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
+	      /**********************************************/
+				/* Test if the digital I/O module initialised */
+	      /**********************************************/
+
+				if (devpriv->s_ModuleInfo[b_ModulNbr].
+					s_DigitalIOInfo.b_DigitalInit == 1) {
+		 /**************************/
+					/* Read all digital input */
+		 /**************************/
+
+					//INPDW (ps_APCI1710Variable->
+					//      s_Board [b_BoardHandle].
+					//      s_BoardInfos.
+					//      ui_Address + (64 * b_ModulNbr),
+					//      &dw_StatusReg);
+
+					dw_StatusReg =
+						inl(devpriv->s_BoardInfos.
+						ui_Address + (64 * b_ModulNbr));
+					*pb_PortValue =
+						(BYTE) (dw_StatusReg ^ 0x1C);
+
+				} else {
+		 /*******************************/
+					/* Digital I/O not initialised */
+		 /*******************************/
+
+					i_ReturnValue = -4;
+				}
+			} else {
+	      /******************************************/
+				/* The module is not a digital I/O module */
+	      /******************************************/
+
+				i_ReturnValue = -3;
+			}
+		} else {
+	   /***********************/
+			/* Module number error */
+	   /***********************/
+
+			i_ReturnValue = -2;
+		}
+
+		break;
+
+	case APCI1710_OUTPUT:
+	/**************************/
+		/* Test the module number */
+	/**************************/
+
+		if (b_ModulNbr < 4) {
+	   /*******************************/
+			/* Test if digital I/O counter */
+	   /*******************************/
+
+			if ((devpriv->s_BoardInfos.
+					dw_MolduleConfiguration[b_ModulNbr] &
+					0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
+	      /**********************************************/
+				/* Test if the digital I/O module initialised */
+	      /**********************************************/
+
+				if (devpriv->s_ModuleInfo[b_ModulNbr].
+					s_DigitalIOInfo.b_DigitalInit == 1) {
+		 /***********************/
+					/* Test the port value */
+		 /***********************/
+
+					if (b_PortValue <= 7) {
+		    /***********************************/
+						/* Test the digital output channel */
+		    /***********************************/
+
+		    /**************************/
+						/* Test if channel A used */
+		    /**************************/
+
+						if ((b_PortValue & 2) == 2) {
+							if (devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_DigitalIOInfo.
+								b_ChannelAMode
+								!= 1) {
+			  /*******************************************/
+								/* The digital channel A is used for input */
+			  /*******************************************/
+
+								i_ReturnValue =
+									-6;
+							}
+						}	// if ((b_PortValue & 2) == 2)
+
+		    /**************************/
+						/* Test if channel B used */
+		    /**************************/
+
+						if ((b_PortValue & 4) == 4) {
+							if (devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_DigitalIOInfo.
+								b_ChannelBMode
+								!= 1) {
+			  /*******************************************/
+								/* The digital channel B is used for input */
+			  /*******************************************/
+
+								i_ReturnValue =
+									-7;
+							}
+						}	// if ((b_PortValue & 4) == 4)
+
+		    /***********************/
+						/* Test if error occur */
+		    /***********************/
+
+						if (i_ReturnValue >= 0) {
+
+							//if(data[1])
+							//{
+							switch (b_PortOnOFF) {
+			   /*********************************/
+								/* Test if set Port ON                   */
+		       /*********************************/
+
+							case APCI1710_ON:
+
+		       /*********************************/
+								/* Test if output memory enabled */
+		       /*********************************/
+
+								if (devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_DigitalIOInfo.
+									b_OutputMemoryEnabled
+									== 1) {
+									dw_WriteValue
+										=
+										devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_DigitalIOInfo.
+										dw_OutputMemory
+										|
+										b_PortValue;
+
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_DigitalIOInfo.
+										dw_OutputMemory
+										=
+										dw_WriteValue;
+								} else {
+									dw_WriteValue
+										=
+										b_PortValue;
+								}
+								break;
+
+								// If Set PORT  OFF
+							case APCI1710_OFF:
+
+			   /*********************************/
+								/* Test if output memory enabled */
+		       /*********************************/
+
+								if (devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_DigitalIOInfo.
+									b_OutputMemoryEnabled
+									== 1) {
+									dw_WriteValue
+										=
+										devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_DigitalIOInfo.
+										dw_OutputMemory
+										&
+										(0xFFFFFFFFUL
+										-
+										b_PortValue);
+
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_DigitalIOInfo.
+										dw_OutputMemory
+										=
+										dw_WriteValue;
+								} else {
+			  /*****************************/
+									/* Digital Output Memory OFF */
+			  /*****************************/
+
+									i_ReturnValue
+										=
+										-8;
+								}
+							}	// switch
+
+		       /*******************/
+							/* Write the value */
+		       /*******************/
+
+							//  OUTPDW (ps_APCI1710Variable->
+							//      s_Board [b_BoardHandle].
+							//      s_BoardInfos.
+							//      ui_Address + (64 * b_ModulNbr),
+							//      dw_WriteValue);
+							outl(dw_WriteValue,
+								devpriv->
+								s_BoardInfos.
+								ui_Address +
+								(64 * b_ModulNbr));
+						}
+					} else {
+		    /**********************/
+						/* Output value wrong */
+		    /**********************/
+
+						i_ReturnValue = -4;
+					}
+				} else {
+		 /*******************************/
+					/* Digital I/O not initialised */
+		 /*******************************/
+
+					i_ReturnValue = -5;
+				}
+			} else {
+	      /******************************************/
+				/* The module is not a digital I/O module */
+	      /******************************************/
+
+				i_ReturnValue = -3;
+			}
+		} else {
+	   /***********************/
+			/* Module number error */
+	   /***********************/
+
+			i_ReturnValue = -2;
+		}
+		break;
+
+	default:
+		i_ReturnValue = -9;
+		DPRINTK("NO INPUT/OUTPUT specified\n");
+	}			//switch INPUT / OUTPUT
+	return (i_ReturnValue);
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h
new file mode 100644
index 0000000..5ef157a
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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.
+ */
+
+#define APCI1710_ON			1	/* Digital  Output ON or OFF */
+#define APCI1710_OFF			0
+
+#define APCI1710_INPUT			0	/* Digital I/O */
+#define APCI1710_OUTPUT			1
+
+#define APCI1710_DIGIO_MEMORYONOFF	0x10
+#define APCI1710_DIGIO_INIT		0x11
+
+/*
+ * DIGITAL I/O INISIALISATION FUNCTION
+ */
+INT i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s,
+				   struct comedi_insn *insn, unsigned int *data);
+
+/*
+ * INPUT OUTPUT  FUNCTIONS
+ */
+INT i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev,
+					 struct comedi_subdevice *s,
+					 struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device *dev,
+					  struct comedi_subdevice *s,
+					  struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev,
+					  struct comedi_subdevice *s,
+					  struct comedi_insn *insn, unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c
new file mode 100644
index 0000000..1062f2f
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c
@@ -0,0 +1,5363 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+
+        ADDI-DATA GmbH
+        Dieselstrasse 3
+        D-77833 Ottersweier
+        Tel: +19(0)7223/9493-0
+        Fax: +49(0)7223/9493-92
+        http://www.addi-data-com
+        info@addi-data.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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+  +-----------------------------------------------------------------------+
+  | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
+  +-----------------------------------------------------------------------+
+  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
+  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
+  +-----------------------------------------------------------------------+
+  | Project     : API APCI1710    | Compiler : gcc                        |
+  | Module name : INC_CPT.C       | Version  : 2.96                       |
+  +-------------------------------+---------------------------------------+
+  | Project manager: Eric Stolz   | Date     :  02/12/2002                |
+  +-----------------------------------------------------------------------+
+  | Description :   APCI-1710 incremental counter module                  |
+  |                                                                       |
+  |                                                                       |
+  +-----------------------------------------------------------------------+
+  |                             UPDATES                                   |
+  +-----------------------------------------------------------------------+
+  |   Date   |   Author  |          Description of updates                |
+  +----------+-----------+------------------------------------------------+
+  |          |           |                                                |
+  |----------|-----------|------------------------------------------------|
+  | 08/05/00 | Guinot C  | - 0400/0228 All Function in RING 0             |
+  |          |           |   available                                    |
+  +-----------------------------------------------------------------------+
+  | 29/06/01 | Guinot C. | - 1100/0231 -> 0701/0232                       |
+  |          |           | See i_APCI1710_DisableFrequencyMeasurement     |
+  +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+|                               Included files                               |
++----------------------------------------------------------------------------+
+*/
+
+#include "APCI1710_INCCPT.h"
+
+/*
++----------------------------------------------------------------------------+
+| INT	i_APCI1710_InsnConfigINCCPT(struct comedi_device *dev,struct comedi_subdevice *s,
+struct comedi_insn *insn,unsigned int *data)
+
++----------------------------------------------------------------------------+
+| Task              : Configuration function for INC_CPT                             |
++----------------------------------------------------------------------------+
+| Input Parameters  :														 |
++----------------------------------------------------------------------------+
+| Output Parameters : *data
++----------------------------------------------------------------------------+
+| Return Value      :                 |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigINCCPT(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_ConfigType;
+	INT i_ReturnValue = 0;
+	ui_ConfigType = CR_CHAN(insn->chanspec);
+
+	printk("\nINC_CPT");
+
+	devpriv->tsk_Current = current;	// Save the current process task structure
+	switch (ui_ConfigType) {
+	case APCI1710_INCCPT_INITCOUNTER:
+		i_ReturnValue = i_APCI1710_InitCounter(dev,
+			CR_AREF(insn->chanspec),
+			(BYTE) data[0],
+			(BYTE) data[1],
+			(BYTE) data[2], (BYTE) data[3], (BYTE) data[4]);
+		break;
+
+	case APCI1710_INCCPT_COUNTERAUTOTEST:
+		i_ReturnValue = i_APCI1710_CounterAutoTest(dev,
+			(PBYTE) & data[0]);
+		break;
+
+	case APCI1710_INCCPT_INITINDEX:
+		i_ReturnValue = i_APCI1710_InitIndex(dev,
+			CR_AREF(insn->chanspec),
+			(BYTE) data[0],
+			(BYTE) data[1], (BYTE) data[2], (BYTE) data[3]);
+		break;
+
+	case APCI1710_INCCPT_INITREFERENCE:
+		i_ReturnValue = i_APCI1710_InitReference(dev,
+			CR_AREF(insn->chanspec), (BYTE) data[0]);
+		break;
+
+	case APCI1710_INCCPT_INITEXTERNALSTROBE:
+		i_ReturnValue = i_APCI1710_InitExternalStrobe(dev,
+			CR_AREF(insn->chanspec),
+			(BYTE) data[0], (BYTE) data[1]);
+		break;
+
+	case APCI1710_INCCPT_INITCOMPARELOGIC:
+		i_ReturnValue = i_APCI1710_InitCompareLogic(dev,
+			CR_AREF(insn->chanspec), (UINT) data[0]);
+		break;
+
+	case APCI1710_INCCPT_INITFREQUENCYMEASUREMENT:
+		i_ReturnValue = i_APCI1710_InitFrequencyMeasurement(dev,
+			CR_AREF(insn->chanspec),
+			(BYTE) data[0],
+			(BYTE) data[1], (ULONG) data[2], (PULONG) & data[0]);
+		break;
+
+	default:
+		printk("Insn Config : Config Parameter Wrong\n");
+
+	}
+
+	if (i_ReturnValue >= 0)
+		i_ReturnValue = insn->n;
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_InitCounter                           |
+|                               (BYTE_          b_BoardHandle,               |
+|                                BYTE_          b_ModulNbr,                  |
+|                                BYTE_          b_CounterRange,              |
+|                                BYTE_          b_FirstCounterModus,         |
+|                                BYTE_          b_FirstCounterOption,        |
+|                                BYTE_          b_SecondCounterModus,        |
+|                                BYTE_          b_SecondCounterOption)       |
++----------------------------------------------------------------------------+
+| Task              : Configure the counter operating mode from selected     |
+|                     module (b_ModulNbr). You must calling this function be |
+|                     for you call any other function witch access of        |
+|                     counters.                                              |
+|                                                                            |
+|                          Counter range                                     |
+|                          -------------                                     |
+| +------------------------------------+-----------------------------------+ |
+| | Parameter       Passed value       |        Description                | |
+| |------------------------------------+-----------------------------------| |
+| |b_ModulNbr   APCI1710_16BIT_COUNTER |  The module is configured for     | |
+| |                                    |  two 16-bit counter.              | |
+| |                                    |  - b_FirstCounterModus and        | |
+| |                                    |    b_FirstCounterOption           | |
+| |                                    |    configure the first 16 bit     | |
+| |                                    |    counter.                       | |
+| |                                    |  - b_SecondCounterModus and       | |
+| |                                    |    b_SecondCounterOption          | |
+| |                                    |    configure the second 16 bit    | |
+| |                                    |    counter.                       | |
+| |------------------------------------+-----------------------------------| |
+| |b_ModulNbr   APCI1710_32BIT_COUNTER |  The module is configured for one | |
+| |                                    |  32-bit counter.                  | |
+| |                                    |  - b_FirstCounterModus and        | |
+| |                                    |    b_FirstCounterOption           | |
+| |                                    |    configure the 32 bit counter.  | |
+| |                                    |  - b_SecondCounterModus and       | |
+| |                                    |    b_SecondCounterOption          | |
+| |                                    |    are not used and have no       | |
+| |                                    |    importance.                    | |
+| +------------------------------------+-----------------------------------+ |
+|                                                                            |
+|                      Counter operating mode                                |
+|                      ----------------------                                |
+|                                                                            |
+| +--------------------+-------------------------+-------------------------+ |
+| |    Parameter       |     Passed value        |    Description          | |
+| |--------------------+-------------------------+-------------------------| |
+| |b_FirstCounterModus | APCI1710_QUADRUPLE_MODE | In the quadruple mode,  | |
+| |       or           |                         | the edge analysis       | |
+| |b_SecondCounterModus|                         | circuit generates a     | |
+| |                    |                         | counting pulse from     | |
+| |                    |                         | each edge of 2 signals  | |
+| |                    |                         | which are phase shifted | |
+| |                    |                         | in relation to each     | |
+| |                    |                         | other.                  | |
+| |--------------------+-------------------------+-------------------------| |
+| |b_FirstCounterModus |   APCI1710_DOUBLE_MODE  | Functions in the same   | |
+| |       or           |                         | way as the quadruple    | |
+| |b_SecondCounterModus|                         | mode, except that only  | |
+| |                    |                         | two of the four edges   | |
+| |                    |                         | are analysed per        | |
+| |                    |                         | period                  | |
+| |--------------------+-------------------------+-------------------------| |
+| |b_FirstCounterModus |   APCI1710_SIMPLE_MODE  | Functions in the same   | |
+| |       or           |                         | way as the quadruple    | |
+| |b_SecondCounterModus|                         | mode, except that only  | |
+| |                    |                         | one of the four edges   | |
+| |                    |                         | is analysed per         | |
+| |                    |                         | period.                 | |
+| |--------------------+-------------------------+-------------------------| |
+| |b_FirstCounterModus |   APCI1710_DIRECT_MODE  | In the direct mode the  | |
+| |       or           |                         | both edge analysis      | |
+| |b_SecondCounterModus|                         | circuits are inactive.  | |
+| |                    |                         | The inputs A, B in the  | |
+| |                    |                         | 32-bit mode or A, B and | |
+| |                    |                         | C, D in the 16-bit mode | |
+| |                    |                         | represent, each, one    | |
+| |                    |                         | clock pulse gate circuit| |
+| |                    |                         | There by frequency and  | |
+| |                    |                         | pulse duration          | |
+| |                    |                         | measurements can be     | |
+| |                    |                         | performed.              | |
+| +--------------------+-------------------------+-------------------------+ |
+|                                                                            |
+|                                                                            |
+|       IMPORTANT!                                                           |
+|       If you have configured the module for two 16-bit counter, a mixed    |
+|       mode with a counter in quadruple/double/single mode                  |
+|       and the other counter in direct mode is not possible!                |
+|                                                                            |
+|                                                                            |
+|         Counter operating option for quadruple/double/simple mode          |
+|         ---------------------------------------------------------          |
+|                                                                            |
+| +----------------------+-------------------------+------------------------+|
+| |       Parameter      |     Passed value        |  Description           ||
+| |----------------------+-------------------------+------------------------||
+| |b_FirstCounterOption  | APCI1710_HYSTERESIS_ON  | In both edge analysis  ||
+| |        or            |                         | circuits is available  ||
+| |b_SecondCounterOption |                         | one hysteresis circuit.||
+| |                      |                         | It suppresses each     ||
+| |                      |                         | time the first counting||
+| |                      |                         | pulse after a change   ||
+| |                      |                         | of rotation.           ||
+| |----------------------+-------------------------+------------------------||
+| |b_FirstCounterOption  | APCI1710_HYSTERESIS_OFF | The first counting     ||
+| |       or             |                         | pulse is not suppress  ||
+| |b_SecondCounterOption |                         | after a change of      ||
+| |                      |                         | rotation.              ||
+| +----------------------+-------------------------+------------------------+|
+|                                                                            |
+|                                                                            |
+|       IMPORTANT!                                                           |
+|       This option are only avaible if you have selected the direct mode.   |
+|                                                                            |
+|                                                                            |
+|               Counter operating option for direct mode                     |
+|               ----------------------------------------                     |
+|                                                                            |
+| +----------------------+--------------------+----------------------------+ |
+| |      Parameter       |     Passed value   |       Description          | |
+| |----------------------+--------------------+----------------------------| |
+| |b_FirstCounterOption  | APCI1710_INCREMENT | The counter increment for  | |
+| |       or             |                    | each counting pulse        | |
+| |b_SecondCounterOption |                    |                            | |
+| |----------------------+--------------------+----------------------------| |
+| |b_FirstCounterOption  | APCI1710_DECREMENT | The counter decrement for  | |
+| |       or             |                    | each counting pulse        | |
+| |b_SecondCounterOption |                    |                            | |
+| +----------------------+--------------------+----------------------------+ |
+|                                                                            |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle         : Handle of board APCI-1710|
+|                     BYTE_ b_ModulNbr            : Module number to         |
+|                                                   configure (0 to 3)       |
+|                     BYTE_ b_CounterRange        : Selection form counter   |
+|                                                   range.                   |
+|                     BYTE_ b_FirstCounterModus   : First counter operating  |
+|                                                   mode.                    |
+|                     BYTE_ b_FirstCounterOption  : First counter  option.   |
+|                     BYTE_ b_SecondCounterModus  : Second counter operating |
+|                                                   mode.                    |
+|                     BYTE_ b_SecondCounterOption : Second counter  option.  |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : 0: No error                                            |
+|                    -1: The handle parameter of the board is wrong          |
+|                    -2: The module is not a counter module                  |
+|                    -3: The selected counter range is wrong.                |
+|                    -4: The selected first counter operating mode is wrong. |
+|                    -5: The selected first counter operating option is wrong|
+|                    -6: The selected second counter operating mode is wrong.|
+|                    -7: The selected second counter operating option is     |
+|                        wrong.                                              |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InitCounter(struct comedi_device * dev,
+	BYTE b_ModulNbr,
+	BYTE b_CounterRange,
+	BYTE b_FirstCounterModus,
+	BYTE b_FirstCounterOption,
+	BYTE b_SecondCounterModus, BYTE b_SecondCounterOption)
+{
+	INT i_ReturnValue = 0;
+
+	/*******************************/
+	/* Test if incremental counter */
+	/*******************************/
+
+	if ((devpriv->s_BoardInfos.
+			dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) ==
+		APCI1710_INCREMENTAL_COUNTER) {
+	   /**************************/
+		/* Test the counter range */
+	   /**************************/
+
+		if (b_CounterRange == APCI1710_16BIT_COUNTER
+			|| b_CounterRange == APCI1710_32BIT_COUNTER) {
+	      /********************************/
+			/* Test the first counter modus */
+	      /********************************/
+
+			if (b_FirstCounterModus == APCI1710_QUADRUPLE_MODE ||
+				b_FirstCounterModus == APCI1710_DOUBLE_MODE ||
+				b_FirstCounterModus == APCI1710_SIMPLE_MODE ||
+				b_FirstCounterModus == APCI1710_DIRECT_MODE) {
+		 /*********************************/
+				/* Test the first counter option */
+		 /*********************************/
+
+				if ((b_FirstCounterModus == APCI1710_DIRECT_MODE
+						&& (b_FirstCounterOption ==
+							APCI1710_INCREMENT
+							|| b_FirstCounterOption
+							== APCI1710_DECREMENT))
+					|| (b_FirstCounterModus !=
+						APCI1710_DIRECT_MODE
+						&& (b_FirstCounterOption ==
+							APCI1710_HYSTERESIS_ON
+							|| b_FirstCounterOption
+							==
+							APCI1710_HYSTERESIS_OFF)))
+				{
+		    /**************************/
+					/* Test if 16-bit counter */
+		    /**************************/
+
+					if (b_CounterRange ==
+						APCI1710_16BIT_COUNTER) {
+		       /*********************************/
+						/* Test the second counter modus */
+		       /*********************************/
+
+						if ((b_FirstCounterModus !=
+								APCI1710_DIRECT_MODE
+								&&
+								(b_SecondCounterModus
+									==
+									APCI1710_QUADRUPLE_MODE
+									||
+									b_SecondCounterModus
+									==
+									APCI1710_DOUBLE_MODE
+									||
+									b_SecondCounterModus
+									==
+									APCI1710_SIMPLE_MODE))
+							|| (b_FirstCounterModus
+								==
+								APCI1710_DIRECT_MODE
+								&&
+								b_SecondCounterModus
+								==
+								APCI1710_DIRECT_MODE))
+						{
+			  /**********************************/
+							/* Test the second counter option */
+			  /**********************************/
+
+							if ((b_SecondCounterModus == APCI1710_DIRECT_MODE && (b_SecondCounterOption == APCI1710_INCREMENT || b_SecondCounterOption == APCI1710_DECREMENT)) || (b_SecondCounterModus != APCI1710_DIRECT_MODE && (b_SecondCounterOption == APCI1710_HYSTERESIS_ON || b_SecondCounterOption == APCI1710_HYSTERESIS_OFF))) {
+								i_ReturnValue =
+									0;
+							} else {
+			     /*********************************************************/
+								/* The selected second counter operating option is wrong */
+			     /*********************************************************/
+
+								DPRINTK("The selected second counter operating option is wrong\n");
+								i_ReturnValue =
+									-7;
+							}
+						} else {
+			  /*******************************************************/
+							/* The selected second counter operating mode is wrong */
+			  /*******************************************************/
+
+							DPRINTK("The selected second counter operating mode is wrong\n");
+							i_ReturnValue = -6;
+						}
+					}
+				} else {
+		    /********************************************************/
+					/* The selected first counter operating option is wrong */
+		    /********************************************************/
+
+					DPRINTK("The selected first counter operating option is wrong\n");
+					i_ReturnValue = -5;
+				}
+			} else {
+		 /******************************************************/
+				/* The selected first counter operating mode is wrong */
+		 /******************************************************/
+				DPRINTK("The selected first counter operating mode is wrong\n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /***************************************/
+			/* The selected counter range is wrong */
+	      /***************************************/
+
+			DPRINTK("The selected counter range is wrong\n");
+			i_ReturnValue = -3;
+		}
+
+	   /*************************/
+		/* Test if a error occur */
+	   /*************************/
+
+		if (i_ReturnValue == 0) {
+	      /**************************/
+			/* Test if 16-Bit counter */
+	      /**************************/
+
+			if (b_CounterRange == APCI1710_32BIT_COUNTER) {
+				devpriv->
+					s_ModuleInfo[b_ModulNbr].
+					s_SiemensCounterInfo.
+					s_ModeRegister.
+					s_ByteModeRegister.
+					b_ModeRegister1 = b_CounterRange |
+					b_FirstCounterModus |
+					b_FirstCounterOption;
+			} else {
+				devpriv->
+					s_ModuleInfo[b_ModulNbr].
+					s_SiemensCounterInfo.
+					s_ModeRegister.
+					s_ByteModeRegister.
+					b_ModeRegister1 = b_CounterRange |
+					(b_FirstCounterModus & 0x5) |
+					(b_FirstCounterOption & 0x20) |
+					(b_SecondCounterModus & 0xA) |
+					(b_SecondCounterOption & 0x40);
+
+		 /***********************/
+				/* Test if direct mode */
+		 /***********************/
+
+				if (b_FirstCounterModus == APCI1710_DIRECT_MODE) {
+					devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_SiemensCounterInfo.
+						s_ModeRegister.
+						s_ByteModeRegister.
+						b_ModeRegister1 = devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_SiemensCounterInfo.
+						s_ModeRegister.
+						s_ByteModeRegister.
+						b_ModeRegister1 |
+						APCI1710_DIRECT_MODE;
+				}
+			}
+
+	      /***************************/
+			/* Write the configuration */
+	      /***************************/
+
+			outl(devpriv->s_ModuleInfo[b_ModulNbr].
+				s_SiemensCounterInfo.
+				s_ModeRegister.
+				dw_ModeRegister1_2_3_4,
+				devpriv->s_BoardInfos.
+				ui_Address + 20 + (64 * b_ModulNbr));
+
+			devpriv->
+				s_ModuleInfo[b_ModulNbr].
+				s_SiemensCounterInfo.
+				s_InitFlag.b_CounterInit = 1;
+		}
+	} else {
+	   /**************************************/
+		/* The module is not a counter module */
+	   /**************************************/
+
+		DPRINTK("The module is not a counter module\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_CounterAutoTest                       |
+|                                               (BYTE_     b_BoardHandle,    |
+|                                                PBYTE_   pb_TestStatus)     |
++----------------------------------------------------------------------------+
+| Task              : A test mode is intended for testing the component and  |
+|                     the connected periphery. All the 8-bit counter chains  |
+|                     are operated internally as down counters.              |
+|                     Independently from the external signals,               |
+|                     all the four 8-bit counter chains are decremented in   |
+|                     parallel by each negative clock pulse edge of CLKX.    |
+|                                                                            |
+|                       Counter auto test conclusion                         |
+|                       ----------------------------                         |
+|              +-----------------+-----------------------------+             |
+|              | pb_TestStatus   |    Error description        |             |
+|              |     mask        |                             |             |
+|              |-----------------+-----------------------------|             |
+|              |    0000         |     No error detected       |             |
+|              |-----------------|-----------------------------|             |
+|              |    0001         | Error detected of counter 0 |             |
+|              |-----------------|-----------------------------|             |
+|              |    0010         | Error detected of counter 1 |             |
+|              |-----------------|-----------------------------|             |
+|              |    0100         | Error detected of counter 2 |             |
+|              |-----------------|-----------------------------|             |
+|              |    1000         | Error detected of counter 3 |             |
+|              +-----------------+-----------------------------+             |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_   b_BoardHandle : Handle of board APCI-1710      |  |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_TestStatus  : Auto test conclusion. See table|
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: No counter module found                            |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_CounterAutoTest(struct comedi_device * dev, PBYTE pb_TestStatus)
+{
+	BYTE b_ModulCpt = 0;
+	INT i_ReturnValue = 0;
+	DWORD dw_LathchValue;
+
+	*pb_TestStatus = 0;
+
+	/********************************/
+	/* Test if counter module found */
+	/********************************/
+
+	if ((devpriv->s_BoardInfos.
+			dw_MolduleConfiguration[0] & 0xFFFF0000UL) ==
+		APCI1710_INCREMENTAL_COUNTER
+		|| (devpriv->s_BoardInfos.
+			dw_MolduleConfiguration[1] & 0xFFFF0000UL) ==
+		APCI1710_INCREMENTAL_COUNTER
+		|| (devpriv->s_BoardInfos.
+			dw_MolduleConfiguration[2] & 0xFFFF0000UL) ==
+		APCI1710_INCREMENTAL_COUNTER
+		|| (devpriv->s_BoardInfos.
+			dw_MolduleConfiguration[3] & 0xFFFF0000UL) ==
+		APCI1710_INCREMENTAL_COUNTER) {
+		for (b_ModulCpt = 0; b_ModulCpt < 4; b_ModulCpt++) {
+	      /*******************************/
+			/* Test if incremental counter */
+	      /*******************************/
+
+			if ((devpriv->s_BoardInfos.
+					dw_MolduleConfiguration[b_ModulCpt] &
+					0xFFFF0000UL) ==
+				APCI1710_INCREMENTAL_COUNTER) {
+		 /******************/
+				/* Start the test */
+		 /******************/
+
+				outl(3, devpriv->s_BoardInfos.
+					ui_Address + 16 + (64 * b_ModulCpt));
+
+		 /*********************/
+				/* Tatch the counter */
+		 /*********************/
+
+				outl(1, devpriv->s_BoardInfos.
+					ui_Address + (64 * b_ModulCpt));
+
+		 /************************/
+				/* Read the latch value */
+		 /************************/
+
+				dw_LathchValue = inl(devpriv->s_BoardInfos.
+					ui_Address + 4 + (64 * b_ModulCpt));
+
+				if ((dw_LathchValue & 0xFF) !=
+					((dw_LathchValue >> 8) & 0xFF)
+					&& (dw_LathchValue & 0xFF) !=
+					((dw_LathchValue >> 16) & 0xFF)
+					&& (dw_LathchValue & 0xFF) !=
+					((dw_LathchValue >> 24) & 0xFF)) {
+					*pb_TestStatus =
+						*pb_TestStatus | (1 <<
+						b_ModulCpt);
+				}
+
+		 /*****************/
+				/* Stop the test */
+		 /*****************/
+
+				outl(0, devpriv->s_BoardInfos.
+					ui_Address + 16 + (64 * b_ModulCpt));
+			}
+		}
+	} else {
+	   /***************************/
+		/* No counter module found */
+	   /***************************/
+
+		DPRINTK("No counter module found\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_InitIndex (BYTE_ b_BoardHandle,       |
+|                                                 BYTE_ b_ModulNbr,          |
+|                                                 BYTE_ b_ReferenceAction,   |
+|                                                 BYTE_ b_IndexOperation,    |
+|                                                 BYTE_ b_AutoMode,          |
+|                                                 BYTE_ b_InterruptEnable)   |
++----------------------------------------------------------------------------+
+| Task              : Initialise the index corresponding to the selected     |
+|                     module (b_ModulNbr). If a INDEX flag occur, you have   |
+|                     the possibility to clear the 32-Bit counter or to latch|
+|                     the current 32-Bit value in to the first latch         |
+|                     register. The b_IndexOperation parameter give the      |
+|                     possibility to choice the INDEX action.                |
+|                     If you have enabled the automatic mode, each INDEX     |
+|                     action is cleared automatically, else you must read    |
+|                     the index status ("i_APCI1710_ReadIndexStatus")        |
+|                     after each INDEX action.                               |
+|                                                                            |
+|                                                                            |
+|                               Index action                                 |
+|                               ------------                                 |
+|                                                                            |
+|           +------------------------+------------------------------------+  |
+|           |   b_IndexOperation     |         Operation                  |  |
+|           |------------------------+------------------------------------|  |
+|           |APCI1710_LATCH_COUNTER  | After a index signal, the counter  |  |
+|           |                        | value (32-Bit) is latched in to    |  |
+|           |                        | the first latch register           |  |
+|           |------------------------|------------------------------------|  |
+|           |APCI1710_CLEAR_COUNTER  | After a index signal, the counter  |  |
+|           |                        | value is cleared (32-Bit)          |  |
+|           +------------------------+------------------------------------+  |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle     : Handle of board APCI-1710    |
+|                     BYTE_ b_ModulNbr        : Module number to configure   |
+|                                               (0 to 3)                     |
+|                     BYTE_ b_ReferenceAction : Determine if the reference   |
+|                                               must set or no for the       |
+|                                               acceptance from index        |
+|                                               APCI1710_ENABLE :            |
+|                                                  Reference must be set for |
+|                                                  accepted the index        |
+|                                               APCI1710_DISABLE :           |
+|                                                  Reference have not        |
+|                                                  importance                |
+|                     BYTE_ b_IndexOperation  : Index operating mode.        |
+|                                               See table.                   |
+|                     BYTE_ b_AutoMode        : Enable or disable the        |
+|                                               automatic index reset.       |
+|                                               APCI1710_ENABLE :            |
+|                                                 Enable the automatic mode  |
+|                                               APCI1710_DISABLE :           |
+|                                                 Disable the automatic mode |
+|                     BYTE_ b_InterruptEnable : Enable or disable the        |
+|                                               interrupt.                   |
+|                                               APCI1710_ENABLE :            |
+|                                               Enable the interrupt         |
+|                                               APCI1710_DISABLE :           |
+|                                               Disable the interrupt        |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: No counter module found                            |
+|                     -3: Counter not initialised see function               |
+|                         "i_APCI1710_InitCounter"                           |
+|                     -4  The reference action parameter is wrong            |
+|                     -5: The index operating mode parameter is wrong        |
+|                     -6: The auto mode parameter is wrong                   |
+|                     -7: Interrupt parameter is wrong                       |
+|                     -8: Interrupt function not initialised.                |
+|                         See function "i_APCI1710_SetBoardIntRoutineX"      |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InitIndex(struct comedi_device * dev,
+	BYTE b_ModulNbr,
+	BYTE b_ReferenceAction,
+	BYTE b_IndexOperation, BYTE b_AutoMode, BYTE b_InterruptEnable)
+{
+	INT i_ReturnValue = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+	      /********************************/
+			/* Test the reference parameter */
+	      /********************************/
+
+			if (b_ReferenceAction == APCI1710_ENABLE ||
+				b_ReferenceAction == APCI1710_DISABLE) {
+		 /****************************/
+				/* Test the index parameter */
+		 /****************************/
+
+				if (b_IndexOperation ==
+					APCI1710_HIGH_EDGE_LATCH_COUNTER
+					|| b_IndexOperation ==
+					APCI1710_LOW_EDGE_LATCH_COUNTER
+					|| b_IndexOperation ==
+					APCI1710_HIGH_EDGE_CLEAR_COUNTER
+					|| b_IndexOperation ==
+					APCI1710_LOW_EDGE_CLEAR_COUNTER
+					|| b_IndexOperation ==
+					APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER
+					|| b_IndexOperation ==
+					APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER)
+				{
+		    /********************************/
+					/* Test the auto mode parameter */
+		    /********************************/
+
+					if (b_AutoMode == APCI1710_ENABLE ||
+						b_AutoMode == APCI1710_DISABLE)
+					{
+		       /***************************/
+						/* Test the interrupt mode */
+		       /***************************/
+
+						if (b_InterruptEnable ==
+							APCI1710_ENABLE
+							|| b_InterruptEnable ==
+							APCI1710_DISABLE) {
+
+			     /************************************/
+							/* Makte the configuration commando */
+			     /************************************/
+
+							if (b_ReferenceAction ==
+								APCI1710_ENABLE)
+							{
+								devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_SiemensCounterInfo.
+									s_ModeRegister.
+									s_ByteModeRegister.
+									b_ModeRegister2
+									=
+									devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_SiemensCounterInfo.
+									s_ModeRegister.
+									s_ByteModeRegister.
+									b_ModeRegister2
+									|
+									APCI1710_ENABLE_INDEX_ACTION;
+							} else {
+								devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_SiemensCounterInfo.
+									s_ModeRegister.
+									s_ByteModeRegister.
+									b_ModeRegister2
+									=
+									devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_SiemensCounterInfo.
+									s_ModeRegister.
+									s_ByteModeRegister.
+									b_ModeRegister2
+									&
+									APCI1710_DISABLE_INDEX_ACTION;
+							}
+
+			     /****************************************/
+							/* Test if low level latch or/and clear */
+			     /****************************************/
+
+							if (b_IndexOperation ==
+								APCI1710_LOW_EDGE_LATCH_COUNTER
+								||
+								b_IndexOperation
+								==
+								APCI1710_LOW_EDGE_CLEAR_COUNTER
+								||
+								b_IndexOperation
+								==
+								APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER)
+							{
+				/*************************************/
+								/* Set the index level to low (DQ26) */
+				/*************************************/
+
+								devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_SiemensCounterInfo.
+									s_ModeRegister.
+									s_ByteModeRegister.
+									b_ModeRegister4
+									=
+									devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_SiemensCounterInfo.
+									s_ModeRegister.
+									s_ByteModeRegister.
+									b_ModeRegister4
+									|
+									APCI1710_SET_LOW_INDEX_LEVEL;
+							} else {
+				/**************************************/
+								/* Set the index level to high (DQ26) */
+				/**************************************/
+
+								devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_SiemensCounterInfo.
+									s_ModeRegister.
+									s_ByteModeRegister.
+									b_ModeRegister4
+									=
+									devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_SiemensCounterInfo.
+									s_ModeRegister.
+									s_ByteModeRegister.
+									b_ModeRegister4
+									&
+									APCI1710_SET_HIGH_INDEX_LEVEL;
+							}
+
+			     /***********************************/
+							/* Test if latch and clear counter */
+			     /***********************************/
+
+							if (b_IndexOperation ==
+								APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER
+								||
+								b_IndexOperation
+								==
+								APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER)
+							{
+				/***************************************/
+								/* Set the latch and clear flag (DQ27) */
+				/***************************************/
+
+								devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_SiemensCounterInfo.
+									s_ModeRegister.
+									s_ByteModeRegister.
+									b_ModeRegister4
+									=
+									devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_SiemensCounterInfo.
+									s_ModeRegister.
+									s_ByteModeRegister.
+									b_ModeRegister4
+									|
+									APCI1710_ENABLE_LATCH_AND_CLEAR;
+							}	// if (b_IndexOperation == APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER || b_IndexOperation == APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER)
+							else {
+				/*****************************************/
+								/* Clear the latch and clear flag (DQ27) */
+				/*****************************************/
+
+								devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_SiemensCounterInfo.
+									s_ModeRegister.
+									s_ByteModeRegister.
+									b_ModeRegister4
+									=
+									devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_SiemensCounterInfo.
+									s_ModeRegister.
+									s_ByteModeRegister.
+									b_ModeRegister4
+									&
+									APCI1710_DISABLE_LATCH_AND_CLEAR;
+
+				/*************************/
+								/* Test if latch counter */
+				/*************************/
+
+								if (b_IndexOperation == APCI1710_HIGH_EDGE_LATCH_COUNTER || b_IndexOperation == APCI1710_LOW_EDGE_LATCH_COUNTER) {
+				   /*********************************/
+									/* Enable the latch from counter */
+				   /*********************************/
+
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_SiemensCounterInfo.
+										s_ModeRegister.
+										s_ByteModeRegister.
+										b_ModeRegister2
+										=
+										devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_SiemensCounterInfo.
+										s_ModeRegister.
+										s_ByteModeRegister.
+										b_ModeRegister2
+										|
+										APCI1710_INDEX_LATCH_COUNTER;
+								} else {
+				   /*********************************/
+									/* Enable the clear from counter */
+				   /*********************************/
+
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_SiemensCounterInfo.
+										s_ModeRegister.
+										s_ByteModeRegister.
+										b_ModeRegister2
+										=
+										devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_SiemensCounterInfo.
+										s_ModeRegister.
+										s_ByteModeRegister.
+										b_ModeRegister2
+										&
+										(~APCI1710_INDEX_LATCH_COUNTER);
+								}
+							}	// // if (b_IndexOperation == APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER || b_IndexOperation == APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER)
+
+							if (b_AutoMode ==
+								APCI1710_DISABLE)
+							{
+								devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_SiemensCounterInfo.
+									s_ModeRegister.
+									s_ByteModeRegister.
+									b_ModeRegister2
+									=
+									devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_SiemensCounterInfo.
+									s_ModeRegister.
+									s_ByteModeRegister.
+									b_ModeRegister2
+									|
+									APCI1710_INDEX_AUTO_MODE;
+							} else {
+								devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_SiemensCounterInfo.
+									s_ModeRegister.
+									s_ByteModeRegister.
+									b_ModeRegister2
+									=
+									devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_SiemensCounterInfo.
+									s_ModeRegister.
+									s_ByteModeRegister.
+									b_ModeRegister2
+									&
+									(~APCI1710_INDEX_AUTO_MODE);
+							}
+
+							if (b_InterruptEnable ==
+								APCI1710_ENABLE)
+							{
+								devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_SiemensCounterInfo.
+									s_ModeRegister.
+									s_ByteModeRegister.
+									b_ModeRegister3
+									=
+									devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_SiemensCounterInfo.
+									s_ModeRegister.
+									s_ByteModeRegister.
+									b_ModeRegister3
+									|
+									APCI1710_ENABLE_INDEX_INT;
+							} else {
+								devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_SiemensCounterInfo.
+									s_ModeRegister.
+									s_ByteModeRegister.
+									b_ModeRegister3
+									=
+									devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_SiemensCounterInfo.
+									s_ModeRegister.
+									s_ByteModeRegister.
+									b_ModeRegister3
+									&
+									APCI1710_DISABLE_INDEX_INT;
+							}
+
+							devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_SiemensCounterInfo.
+								s_InitFlag.
+								b_IndexInit = 1;
+
+						} else {
+			  /********************************/
+							/* Interrupt parameter is wrong */
+			  /********************************/
+							DPRINTK("Interrupt parameter is wrong\n");
+							i_ReturnValue = -7;
+						}
+					} else {
+		       /************************************/
+						/* The auto mode parameter is wrong */
+		       /************************************/
+
+						DPRINTK("The auto mode parameter is wrong\n");
+						i_ReturnValue = -6;
+					}
+				} else {
+		    /***********************************************/
+					/* The index operating mode parameter is wrong */
+		    /***********************************************/
+
+					DPRINTK("The index operating mode parameter is wrong\n");
+					i_ReturnValue = -5;
+				}
+			} else {
+		 /*******************************************/
+				/* The reference action parameter is wrong */
+		 /*******************************************/
+
+				DPRINTK("The reference action parameter is wrong\n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_InitReference                         |
+|                                                (BYTE_ b_BoardHandle,       |
+|                                                 BYTE_ b_ModulNbr,          |
+|                                                 BYTE_ b_ReferenceLevel)    |
++----------------------------------------------------------------------------+
+| Task              : Initialise the reference corresponding to the selected |
+|                     module (b_ModulNbr).                                   |
+|                                                                            |
+|                               Reference level                              |
+|                               ---------------                              |
+|             +--------------------+-------------------------+               |
+|             | b_ReferenceLevel   |         Operation       |               |
+|             +--------------------+-------------------------+               |
+|             |   APCI1710_LOW     |  Reference occur if "0" |               |
+|             |--------------------|-------------------------|               |
+|             |   APCI1710_HIGH    |  Reference occur if "1" |               |
+|             +--------------------+-------------------------+               |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle     : Handle of board APCI-1710    |
+|                     BYTE_ b_ModulNbr        : Module number to configure   |
+|                                               (0 to 3)                     |
+|                     BYTE_ b_ReferenceLevel  : Reference level.             |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: The selected module number parameter is wrong      |
+|                     -3: Counter not initialised see function               |
+|                         "i_APCI1710_InitCounter"                           |
+|                     -4: Reference level parameter is wrong                 |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InitReference(struct comedi_device * dev,
+	BYTE b_ModulNbr, BYTE b_ReferenceLevel)
+{
+	INT i_ReturnValue = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+	      /**************************************/
+			/* Test the reference level parameter */
+	      /**************************************/
+
+			if (b_ReferenceLevel == 0 || b_ReferenceLevel == 1) {
+				if (b_ReferenceLevel == 1) {
+					devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_SiemensCounterInfo.
+						s_ModeRegister.
+						s_ByteModeRegister.
+						b_ModeRegister2 = devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_SiemensCounterInfo.
+						s_ModeRegister.
+						s_ByteModeRegister.
+						b_ModeRegister2 |
+						APCI1710_REFERENCE_HIGH;
+				} else {
+					devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_SiemensCounterInfo.
+						s_ModeRegister.
+						s_ByteModeRegister.
+						b_ModeRegister2 = devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_SiemensCounterInfo.
+						s_ModeRegister.
+						s_ByteModeRegister.
+						b_ModeRegister2 &
+						APCI1710_REFERENCE_LOW;
+				}
+
+				outl(devpriv->s_ModuleInfo[b_ModulNbr].
+					s_SiemensCounterInfo.
+					s_ModeRegister.
+					dw_ModeRegister1_2_3_4,
+					devpriv->s_BoardInfos.ui_Address + 20 +
+					(64 * b_ModulNbr));
+
+				devpriv->
+					s_ModuleInfo[b_ModulNbr].
+					s_SiemensCounterInfo.
+					s_InitFlag.b_ReferenceInit = 1;
+			} else {
+		 /**************************************/
+				/* Reference level parameter is wrong */
+		 /**************************************/
+
+				DPRINTK("Reference level parameter is wrong\n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_	i_APCI1710_InitExternalStrobe                |
+|					(BYTE_ b_BoardHandle,                |
+|					 BYTE_ b_ModulNbr,                   |
+|					 BYTE_ b_ExternalStrobe,             |
+|					 BYTE_ b_ExternalStrobeLevel)        |
++----------------------------------------------------------------------------+
+| Task              : Initialises the external strobe level corresponding to |
+|		      the selected module (b_ModulNbr).                      |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle     : Handle of board APCI-1710    |
+|                     BYTE_ b_ModulNbr        : Module number to configure   |
+|                                               (0 to 3)                     |
+|		      BYTE_ b_ExternalStrobe  : External strobe selection    |
+|						0 : External strobe A        |
+|						1 : External strobe B        |
+|		      BYTE_ b_ExternalStrobeLevel : External strobe level    |
+|						APCI1710_LOW :               |
+|						External latch occurs if "0" |
+|						APCI1710_HIGH :              |
+|						External latch occurs if "1" |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: The selected module number is wrong                |
+|                     -3: Counter not initialised.                           |
+|			  See function "i_APCI1710_InitCounter"              |
+|                     -4: External strobe selection is wrong                 |
+|                     -5: External strobe level parameter is wrong           |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InitExternalStrobe(struct comedi_device * dev,
+	BYTE b_ModulNbr, BYTE b_ExternalStrobe, BYTE b_ExternalStrobeLevel)
+{
+	INT i_ReturnValue = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+	      /**************************************/
+			/* Test the external strobe selection */
+	      /**************************************/
+
+			if (b_ExternalStrobe == 0 || b_ExternalStrobe == 1) {
+		 /******************/
+				/* Test the level */
+		 /******************/
+
+				if ((b_ExternalStrobeLevel == APCI1710_HIGH) ||
+					((b_ExternalStrobeLevel == APCI1710_LOW
+							&& (devpriv->
+								s_BoardInfos.
+								dw_MolduleConfiguration
+								[b_ModulNbr] &
+								0xFFFF) >=
+							0x3135))) {
+		    /*****************/
+					/* Set the level */
+		    /*****************/
+
+					devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_SiemensCounterInfo.
+						s_ModeRegister.
+						s_ByteModeRegister.
+						b_ModeRegister4 = (devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_SiemensCounterInfo.
+						s_ModeRegister.
+						s_ByteModeRegister.
+						b_ModeRegister4 & (0xFF -
+							(0x10 << b_ExternalStrobe))) | ((b_ExternalStrobeLevel ^ 1) << (4 + b_ExternalStrobe));
+				} else {
+		    /********************************************/
+					/* External strobe level parameter is wrong */
+		    /********************************************/
+
+					DPRINTK("External strobe level parameter is wrong\n");
+					i_ReturnValue = -5;
+				}
+			}	// if (b_ExternalStrobe == 0 || b_ExternalStrobe == 1)
+			else {
+		 /**************************************/
+				/* External strobe selection is wrong */
+		 /**************************************/
+
+				DPRINTK("External strobe selection is wrong\n");
+				i_ReturnValue = -4;
+			}	// if (b_ExternalStrobe == 0 || b_ExternalStrobe == 1)
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+	/*
+	   +----------------------------------------------------------------------------+
+	   | Function Name     : _INT_ i_APCI1710_InitCompareLogic                      |
+	   |                               (BYTE_   b_BoardHandle,                      |
+	   |                                BYTE_   b_ModulNbr,                         |
+	   |                                UINT_  ui_CompareValue)                     |
+	   +----------------------------------------------------------------------------+
+	   | Task              : Set the 32-Bit compare value. At that moment that the  |
+	   |                     incremental counter arrive to the compare value        |
+	   |                     (ui_CompareValue) a interrupt is generated.            |
+	   +----------------------------------------------------------------------------+
+	   | Input Parameters  : BYTE_  b_BoardHandle    : Handle of board APCI-1710    |
+	   |                     BYTE_  b_ModulNbr       : Module number to configure   |
+	   |                                               (0 to 3)                     |
+	   |                     UINT_ ui_CompareValue   : 32-Bit compare value         |
+	   +----------------------------------------------------------------------------+
+	   | Output Parameters : -
+	   +----------------------------------------------------------------------------+
+	   | Return Value      :  0: No error                                           |
+	   |                     -1: The handle parameter of the board is wrong         |
+	   |                     -2: No counter module found                            |
+	   |                     -3: Counter not initialised see function               |
+	   |                         "i_APCI1710_InitCounter"                           |
+	   +----------------------------------------------------------------------------+
+	 */
+
+INT i_APCI1710_InitCompareLogic(struct comedi_device * dev,
+	BYTE b_ModulNbr, UINT ui_CompareValue)
+{
+	INT i_ReturnValue = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+
+			outl(ui_CompareValue, devpriv->s_BoardInfos.
+				ui_Address + 28 + (64 * b_ModulNbr));
+
+			devpriv->
+				s_ModuleInfo[b_ModulNbr].
+				s_SiemensCounterInfo.
+				s_InitFlag.b_CompareLogicInit = 1;
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_InitFrequencyMeasurement              |
+|				(BYTE_		 b_BoardHandle,              |
+|				 BYTE_		 b_ModulNbr,                 |
+|				 BYTE_		 b_PCIInputClock,            |
+|				 BYTE_		 b_TimingUnity,              |
+|				 ULONG_ 	ul_TimingInterval,           |
+|				 PULONG_       pul_RealTimingInterval)       |
++----------------------------------------------------------------------------+
+| Task              : Sets the time for the frequency measurement.           |
+|		      Configures the selected TOR incremental counter of the |
+|		      selected module (b_ModulNbr). The ul_TimingInterval and|
+|		      ul_TimingUnity determine the time base for the         |
+|		      measurement. The pul_RealTimingInterval returns the    |
+|		      real time value. You must call up this function before |
+|		      you call up any other function which gives access to   |
+|		      the frequency measurement.                             |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_  b_BoardHandle    : Handle of board APCI-1710    |
+|		      BYTE_  b_ModulNbr	      :	Number of the module to be   |
+|						configured (0 to 3)          |
+|		      BYTE_  b_PCIInputClock  :	Selection of the PCI bus     |
+|						clock                        |
+|						- APCI1710_30MHZ :           |
+|						  The PC has a PCI bus clock |
+|						  of 30 MHz                  |
+|						- APCI1710_33MHZ :           |
+|						  The PC has a PCI bus clock |
+|						  of 33 MHz                  |
+|		      BYTE_  b_TimingUnity    : Base time unit (0 to 2)      |
+|						  0 : ns                     |
+|						  1 : æs                     |
+|						  2 : ms                     |
+|		      ULONG_ ul_TimingInterval: Base time value.             |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_RealTimingInterval : Real base time value. |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: The selected module number is wrong                |
+|                     -3: Counter not initialised see function               |
+|			  "i_APCI1710_InitCounter"                           |
+|                     -4: The selected PCI input clock is wrong              |
+|                     -5: Timing unity selection is wrong                    |
+|                     -6: Base timing selection is wrong                     |
+|		      -7: 40MHz quartz not on board                          |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InitFrequencyMeasurement(struct comedi_device * dev,
+	BYTE b_ModulNbr,
+	BYTE b_PCIInputClock,
+	BYTE b_TimingUnity,
+	ULONG ul_TimingInterval, PULONG pul_RealTimingInterval)
+{
+	INT i_ReturnValue = 0;
+	ULONG ul_TimerValue = 0;
+	double d_RealTimingInterval;
+	DWORD dw_Status = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+	      /**************************/
+			/* Test the PCI bus clock */
+	      /**************************/
+
+			if ((b_PCIInputClock == APCI1710_30MHZ) ||
+				(b_PCIInputClock == APCI1710_33MHZ) ||
+				(b_PCIInputClock == APCI1710_40MHZ)) {
+		 /************************/
+				/* Test the timing unit */
+		 /************************/
+
+				if (b_TimingUnity <= 2) {
+		    /**********************************/
+					/* Test the base timing selection */
+		    /**********************************/
+
+					if (((b_PCIInputClock == APCI1710_30MHZ)
+							&& (b_TimingUnity == 0)
+							&& (ul_TimingInterval >=
+								266)
+							&& (ul_TimingInterval <=
+								8738133UL))
+						|| ((b_PCIInputClock ==
+								APCI1710_30MHZ)
+							&& (b_TimingUnity == 1)
+							&& (ul_TimingInterval >=
+								1)
+							&& (ul_TimingInterval <=
+								8738UL))
+						|| ((b_PCIInputClock ==
+								APCI1710_30MHZ)
+							&& (b_TimingUnity == 2)
+							&& (ul_TimingInterval >=
+								1)
+							&& (ul_TimingInterval <=
+								8UL))
+						|| ((b_PCIInputClock ==
+								APCI1710_33MHZ)
+							&& (b_TimingUnity == 0)
+							&& (ul_TimingInterval >=
+								242)
+							&& (ul_TimingInterval <=
+								7943757UL))
+						|| ((b_PCIInputClock ==
+								APCI1710_33MHZ)
+							&& (b_TimingUnity == 1)
+							&& (ul_TimingInterval >=
+								1)
+							&& (ul_TimingInterval <=
+								7943UL))
+						|| ((b_PCIInputClock ==
+								APCI1710_33MHZ)
+							&& (b_TimingUnity == 2)
+							&& (ul_TimingInterval >=
+								1)
+							&& (ul_TimingInterval <=
+								7UL))
+						|| ((b_PCIInputClock ==
+								APCI1710_40MHZ)
+							&& (b_TimingUnity == 0)
+							&& (ul_TimingInterval >=
+								200)
+							&& (ul_TimingInterval <=
+								6553500UL))
+						|| ((b_PCIInputClock ==
+								APCI1710_40MHZ)
+							&& (b_TimingUnity == 1)
+							&& (ul_TimingInterval >=
+								1)
+							&& (ul_TimingInterval <=
+								6553UL))
+						|| ((b_PCIInputClock ==
+								APCI1710_40MHZ)
+							&& (b_TimingUnity == 2)
+							&& (ul_TimingInterval >=
+								1)
+							&& (ul_TimingInterval <=
+								6UL))) {
+		       /**********************/
+						/* Test if 40MHz used */
+		       /**********************/
+
+						if (b_PCIInputClock ==
+							APCI1710_40MHZ) {
+			  /******************************/
+							/* Test if firmware >= Rev1.5 */
+			  /******************************/
+
+							if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3135) {
+			     /*********************************/
+								/* Test if 40MHz quartz on board */
+			     /*********************************/
+
+								/*INPDW (ps_APCI1710Variable->
+								   s_Board [b_BoardHandle].
+								   s_BoardInfos.
+								   ui_Address + 36 + (64 * b_ModulNbr), &dw_Status); */
+								dw_Status =
+									inl
+									(devpriv->
+									s_BoardInfos.
+									ui_Address
+									+ 36 +
+									(64 * b_ModulNbr));
+
+			     /******************************/
+								/* Test the quartz flag (DQ0) */
+			     /******************************/
+
+								if ((dw_Status & 1) != 1) {
+				/*****************************/
+									/* 40MHz quartz not on board */
+				/*****************************/
+
+									DPRINTK("40MHz quartz not on board\n");
+									i_ReturnValue
+										=
+										-7;
+								}
+							} else {
+			     /*****************************/
+								/* 40MHz quartz not on board */
+			     /*****************************/
+								DPRINTK("40MHz quartz not on board\n");
+								i_ReturnValue =
+									-7;
+							}
+						}	// if (b_PCIInputClock == APCI1710_40MHZ)
+
+		       /***************************/
+						/* Test if not error occur */
+		       /***************************/
+
+						if (i_ReturnValue == 0) {
+			  /****************************/
+							/* Test the INC_CPT version */
+			  /****************************/
+
+							if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3131) {
+
+				/**********************/
+								/* Test if 40MHz used */
+				/**********************/
+
+								if (b_PCIInputClock == APCI1710_40MHZ) {
+				   /*********************************/
+									/* Enable the 40MHz quarz (DQ30) */
+				   /*********************************/
+
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_SiemensCounterInfo.
+										s_ModeRegister.
+										s_ByteModeRegister.
+										b_ModeRegister4
+										=
+										devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_SiemensCounterInfo.
+										s_ModeRegister.
+										s_ByteModeRegister.
+										b_ModeRegister4
+										|
+										APCI1710_ENABLE_40MHZ_FREQUENCY;
+								}	// if (b_PCIInputClock == APCI1710_40MHZ)
+								else {
+				   /**********************************/
+									/* Disable the 40MHz quarz (DQ30) */
+				   /**********************************/
+
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_SiemensCounterInfo.
+										s_ModeRegister.
+										s_ByteModeRegister.
+										b_ModeRegister4
+										=
+										devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_SiemensCounterInfo.
+										s_ModeRegister.
+										s_ByteModeRegister.
+										b_ModeRegister4
+										&
+										APCI1710_DISABLE_40MHZ_FREQUENCY;
+
+								}	// if (b_PCIInputClock == APCI1710_40MHZ)
+
+			     /********************************/
+								/* Calculate the division fator */
+			     /********************************/
+
+								fpu_begin();
+								switch (b_TimingUnity) {
+				/******/
+									/* ns */
+				/******/
+
+								case 0:
+
+					/******************/
+									/* Timer 0 factor */
+					/******************/
+
+									ul_TimerValue
+										=
+										(ULONG)
+										(ul_TimingInterval
+										*
+										(0.00025 * b_PCIInputClock));
+
+					/*******************/
+									/* Round the value */
+					/*******************/
+
+									if ((double)((double)ul_TimingInterval * (0.00025 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+										ul_TimerValue
+											=
+											ul_TimerValue
+											+
+											1;
+									}
+
+					/*****************************/
+									/* Calculate the real timing */
+					/*****************************/
+
+									*pul_RealTimingInterval
+										=
+										(ULONG)
+										(ul_TimerValue
+										/
+										(0.00025 * (double)b_PCIInputClock));
+									d_RealTimingInterval
+										=
+										(double)
+										ul_TimerValue
+										/
+										(0.00025
+										*
+										(double)
+										b_PCIInputClock);
+
+									if ((double)((double)ul_TimerValue / (0.00025 * (double)b_PCIInputClock)) >= (double)((double)*pul_RealTimingInterval + 0.5)) {
+										*pul_RealTimingInterval
+											=
+											*pul_RealTimingInterval
+											+
+											1;
+									}
+
+									ul_TimingInterval
+										=
+										ul_TimingInterval
+										-
+										1;
+									ul_TimerValue
+										=
+										ul_TimerValue
+										-
+										2;
+
+									break;
+
+				/******/
+									/* æs */
+				/******/
+
+								case 1:
+
+					/******************/
+									/* Timer 0 factor */
+					/******************/
+
+									ul_TimerValue
+										=
+										(ULONG)
+										(ul_TimingInterval
+										*
+										(0.25 * b_PCIInputClock));
+
+					/*******************/
+									/* Round the value */
+					/*******************/
+
+									if ((double)((double)ul_TimingInterval * (0.25 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+										ul_TimerValue
+											=
+											ul_TimerValue
+											+
+											1;
+									}
+
+					/*****************************/
+									/* Calculate the real timing */
+					/*****************************/
+
+									*pul_RealTimingInterval
+										=
+										(ULONG)
+										(ul_TimerValue
+										/
+										(0.25 * (double)b_PCIInputClock));
+									d_RealTimingInterval
+										=
+										(double)
+										ul_TimerValue
+										/
+										(
+										(double)
+										0.25
+										*
+										(double)
+										b_PCIInputClock);
+
+									if ((double)((double)ul_TimerValue / (0.25 * (double)b_PCIInputClock)) >= (double)((double)*pul_RealTimingInterval + 0.5)) {
+										*pul_RealTimingInterval
+											=
+											*pul_RealTimingInterval
+											+
+											1;
+									}
+
+									ul_TimingInterval
+										=
+										ul_TimingInterval
+										-
+										1;
+									ul_TimerValue
+										=
+										ul_TimerValue
+										-
+										2;
+
+									break;
+
+				/******/
+									/* ms */
+				/******/
+
+								case 2:
+
+					/******************/
+									/* Timer 0 factor */
+					/******************/
+
+									ul_TimerValue
+										=
+										ul_TimingInterval
+										*
+										(250.0
+										*
+										b_PCIInputClock);
+
+					/*******************/
+									/* Round the value */
+					/*******************/
+
+									if ((double)((double)ul_TimingInterval * (250.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+										ul_TimerValue
+											=
+											ul_TimerValue
+											+
+											1;
+									}
+
+					/*****************************/
+									/* Calculate the real timing */
+					/*****************************/
+
+									*pul_RealTimingInterval
+										=
+										(ULONG)
+										(ul_TimerValue
+										/
+										(250.0 * (double)b_PCIInputClock));
+									d_RealTimingInterval
+										=
+										(double)
+										ul_TimerValue
+										/
+										(250.0
+										*
+										(double)
+										b_PCIInputClock);
+
+									if ((double)((double)ul_TimerValue / (250.0 * (double)b_PCIInputClock)) >= (double)((double)*pul_RealTimingInterval + 0.5)) {
+										*pul_RealTimingInterval
+											=
+											*pul_RealTimingInterval
+											+
+											1;
+									}
+
+									ul_TimingInterval
+										=
+										ul_TimingInterval
+										-
+										1;
+									ul_TimerValue
+										=
+										ul_TimerValue
+										-
+										2;
+
+									break;
+								}
+
+								fpu_end();
+			     /*************************/
+								/* Write the timer value */
+			     /*************************/
+
+								outl(ul_TimerValue, devpriv->s_BoardInfos.ui_Address + 32 + (64 * b_ModulNbr));
+
+			     /*******************************/
+								/* Set the initialisation flag */
+			     /*******************************/
+
+								devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_SiemensCounterInfo.
+									s_InitFlag.
+									b_FrequencyMeasurementInit
+									= 1;
+							} else {
+			     /***************************/
+								/* Counter not initialised */
+			     /***************************/
+
+								DPRINTK("Counter not initialised\n");
+								i_ReturnValue =
+									-3;
+							}
+						}	// if (i_ReturnValue == 0)
+					} else {
+		       /**********************************/
+						/* Base timing selection is wrong */
+		       /**********************************/
+
+						DPRINTK("Base timing selection is wrong\n");
+						i_ReturnValue = -6;
+					}
+				} else {
+		    /***********************************/
+					/* Timing unity selection is wrong */
+		    /***********************************/
+
+					DPRINTK("Timing unity selection is wrong\n");
+					i_ReturnValue = -5;
+				}
+			} else {
+		 /*****************************************/
+				/* The selected PCI input clock is wrong */
+		 /*****************************************/
+
+				DPRINTK("The selected PCI input clock is wrong\n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*########################################################################### */
+
+							//INSN BITS
+/*########################################################################### */
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     :INT	i_APCI1710_InsnBitsINCCPT(struct comedi_device *dev,struct comedi_subdevice *s,
+struct comedi_insn *insn,unsigned int *data)                   |
++----------------------------------------------------------------------------+
+| Task              : Set & Clear Functions for INC_CPT                                          |
++----------------------------------------------------------------------------+
+| Input Parameters  :
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnBitsINCCPT(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_BitsType;
+	INT i_ReturnValue = 0;
+	ui_BitsType = CR_CHAN(insn->chanspec);
+	devpriv->tsk_Current = current;	// Save the current process task structure
+
+	switch (ui_BitsType) {
+	case APCI1710_INCCPT_CLEARCOUNTERVALUE:
+		i_ReturnValue = i_APCI1710_ClearCounterValue(dev,
+			(BYTE) CR_AREF(insn->chanspec));
+		break;
+
+	case APCI1710_INCCPT_CLEARALLCOUNTERVALUE:
+		i_ReturnValue = i_APCI1710_ClearAllCounterValue(dev);
+		break;
+
+	case APCI1710_INCCPT_SETINPUTFILTER:
+		i_ReturnValue = i_APCI1710_SetInputFilter(dev,
+			(BYTE) CR_AREF(insn->chanspec),
+			(BYTE) data[0], (BYTE) data[1]);
+		break;
+
+	case APCI1710_INCCPT_LATCHCOUNTER:
+		i_ReturnValue = i_APCI1710_LatchCounter(dev,
+			(BYTE) CR_AREF(insn->chanspec), (BYTE) data[0]);
+		break;
+
+	case APCI1710_INCCPT_SETINDEXANDREFERENCESOURCE:
+		i_ReturnValue = i_APCI1710_SetIndexAndReferenceSource(dev,
+			(BYTE) CR_AREF(insn->chanspec), (BYTE) data[0]);
+		break;
+
+	case APCI1710_INCCPT_SETDIGITALCHLON:
+		i_ReturnValue = i_APCI1710_SetDigitalChlOn(dev,
+			(BYTE) CR_AREF(insn->chanspec));
+		break;
+
+	case APCI1710_INCCPT_SETDIGITALCHLOFF:
+		i_ReturnValue = i_APCI1710_SetDigitalChlOff(dev,
+			(BYTE) CR_AREF(insn->chanspec));
+		break;
+
+	default:
+		printk("Bits Config Parameter Wrong\n");
+	}
+
+	if (i_ReturnValue >= 0)
+		i_ReturnValue = insn->n;
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_ClearCounterValue                     |
+|                               (BYTE_      b_BoardHandle,                   |
+|                                BYTE_       b_ModulNbr)                     |
++----------------------------------------------------------------------------+
+| Task              : Clear the counter value from selected module           |
+|                     (b_ModulNbr).                                          |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle : Handle of board APCI-1710        |
+|                     BYTE_ b_ModulNbr    : Module number to configure       |
+|                                           (0 to 3)                         |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: The selected module number parameter is wrong      |
+|                     -3: Counter not initialised see function               |
+|                         "i_APCI1710_InitCounter"                           |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_ClearCounterValue(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+	INT i_ReturnValue = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+	      /*********************/
+			/* Clear the counter */
+	      /*********************/
+
+			outl(1, devpriv->s_BoardInfos.
+				ui_Address + 16 + (64 * b_ModulNbr));
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_ClearAllCounterValue                  |
+|                               (BYTE_      b_BoardHandle)                   |
++----------------------------------------------------------------------------+
+| Task              : Clear all counter value.                               |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle : Handle of board APCI-1710        |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: No counter module found                            |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_ClearAllCounterValue(struct comedi_device * dev)
+{
+	BYTE b_ModulCpt = 0;
+	INT i_ReturnValue = 0;
+
+	/********************************/
+	/* Test if counter module found */
+	/********************************/
+
+	if ((devpriv->s_BoardInfos.
+			dw_MolduleConfiguration[0] & 0xFFFF0000UL) ==
+		APCI1710_INCREMENTAL_COUNTER
+		|| (devpriv->s_BoardInfos.
+			dw_MolduleConfiguration[1] & 0xFFFF0000UL) ==
+		APCI1710_INCREMENTAL_COUNTER
+		|| (devpriv->s_BoardInfos.
+			dw_MolduleConfiguration[2] & 0xFFFF0000UL) ==
+		APCI1710_INCREMENTAL_COUNTER
+		|| (devpriv->s_BoardInfos.
+			dw_MolduleConfiguration[3] & 0xFFFF0000UL) ==
+		APCI1710_INCREMENTAL_COUNTER) {
+		for (b_ModulCpt = 0; b_ModulCpt < 4; b_ModulCpt++) {
+	      /*******************************/
+			/* Test if incremental counter */
+	      /*******************************/
+
+			if ((devpriv->s_BoardInfos.
+					dw_MolduleConfiguration[b_ModulCpt] &
+					0xFFFF0000UL) ==
+				APCI1710_INCREMENTAL_COUNTER) {
+		 /*********************/
+				/* Clear the counter */
+		 /*********************/
+
+				outl(1, devpriv->s_BoardInfos.
+					ui_Address + 16 + (64 * b_ModulCpt));
+			}
+		}
+	} else {
+	   /***************************/
+		/* No counter module found */
+	   /***************************/
+
+		DPRINTK("No counter module found\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_SetInputFilter                        |
+|					(BYTE_ b_BoardHandle,                |
+|					 BYTE_ b_Module,                     |
+|					 BYTE_ b_PCIInputClock,              |
+|					 BYTE_ b_Filter)     		     |
++----------------------------------------------------------------------------+
+| Task              : Disable or enable the software filter from selected    |
+|		      module (b_ModulNbr). b_Filter determine the filter time|
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_  b_BoardHandle    : Handle of board APCI-1710    |
+|		      BYTE_  b_ModulNbr	      :	Number of the module to be   |
+|						configured (0 to 3)          |
+|		      BYTE_  b_PCIInputClock  :	Selection of the PCI bus     |
+|						clock                        |
+|						- APCI1710_30MHZ :           |
+|						  The PC has a PCI bus clock |
+|						  of 30 MHz                  |
+|						- APCI1710_33MHZ :           |
+|						  The PC has a PCI bus clock |
+|						  of 33 MHz                  |
+|						- APCI1710_40MHZ :           |
+|						  The APCI1710 has a 40MHz    |
+|						  quartz		     |
+|		      BYTE_  b_Filter	      : Filter selection             |
+|                                                                            |
+|				30 MHz                                       |
+|				------                                       |
+|					0:  Software filter not used         |
+|					1:  Filter from 266ns  (3.750000MHz) |
+|					2:  Filter from 400ns  (2.500000MHz) |
+|					3:  Filter from 533ns  (1.876170MHz) |
+|					4:  Filter from 666ns  (1.501501MHz) |
+|					5:  Filter from 800ns  (1.250000MHz) |
+|					6:  Filter from 933ns  (1.071800MHz) |
+|					7:  Filter from 1066ns (0.938080MHz) |
+|					8:  Filter from 1200ns (0.833333MHz) |
+|					9:  Filter from 1333ns (0.750000MHz) |
+|					10: Filter from 1466ns (0.682100MHz) |
+|					11: Filter from 1600ns (0.625000MHz) |
+|					12: Filter from 1733ns (0.577777MHz) |
+|					13: Filter from 1866ns (0.535900MHz) |
+|					14: Filter from 2000ns (0.500000MHz) |
+|					15: Filter from 2133ns (0.468800MHz) |
+|									     |
+|				33 MHz                                       |
+|				------                                       |
+|					0:  Software filter not used         |
+|					1:  Filter from 242ns  (4.125000MHz) |
+|					2:  Filter from 363ns  (2.754820MHz) |
+|					3:  Filter from 484ns  (2.066115MHz) |
+|					4:  Filter from 605ns  (1.652892MHz) |
+|					5:  Filter from 726ns  (1.357741MHz) |
+|					6:  Filter from 847ns  (1.180637MHz) |
+|					7:  Filter from 968ns  (1.033055MHz) |
+|					8:  Filter from 1089ns (0.918273MHz) |
+|					9:  Filter from 1210ns (0.826446MHz) |
+|					10: Filter from 1331ns (0.751314MHz) |
+|					11: Filter from 1452ns (0.688705MHz) |
+|					12: Filter from 1573ns (0.635727MHz) |
+|					13: Filter from 1694ns (0.590318MHz) |
+|					14: Filter from 1815ns (0.550964MHz) |
+|					15: Filter from 1936ns (0.516528MHz) |
+|									     |
+|				40 MHz                                       |
+|				------                                       |
+|					0:  Software filter not used         |
+|					1:  Filter from 200ns  (5.000000MHz) |
+|					2:  Filter from 300ns  (3.333333MHz) |
+|					3:  Filter from 400ns  (2.500000MHz) |
+|					4:  Filter from 500ns  (2.000000MHz) |
+|					5:  Filter from 600ns  (1.666666MHz) |
+|					6:  Filter from 700ns  (1.428500MHz) |
+|					7:  Filter from 800ns  (1.250000MHz) |
+|					8:  Filter from 900ns  (1.111111MHz) |
+|					9:  Filter from 1000ns (1.000000MHz) |
+|					10: Filter from 1100ns (0.909090MHz) |
+|					11: Filter from 1200ns (0.833333MHz) |
+|					12: Filter from 1300ns (0.769200MHz) |
+|					13: Filter from 1400ns (0.714200MHz) |
+|					14: Filter from 1500ns (0.666666MHz) |
+|					15: Filter from 1600ns (0.625000MHz) |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: The selected module number is wrong                |
+|                     -3: The module is not a counter module                 |
+|					  -4: The selected PCI input clock is wrong              |
+|					  -5: The selected filter value is wrong                 |
+|					  -6: 40MHz quartz not on board                          |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_SetInputFilter(struct comedi_device * dev,
+	BYTE b_ModulNbr, BYTE b_PCIInputClock, BYTE b_Filter)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_Status = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if incremental counter */
+	   /*******************************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_INCREMENTAL_COUNTER) {
+	      /******************************/
+			/* Test if firmware >= Rev1.5 */
+	      /******************************/
+
+			if ((devpriv->s_BoardInfos.
+					dw_MolduleConfiguration[b_ModulNbr] &
+					0xFFFF) >= 0x3135) {
+		 /**************************/
+				/* Test the PCI bus clock */
+		 /**************************/
+
+				if ((b_PCIInputClock == APCI1710_30MHZ) ||
+					(b_PCIInputClock == APCI1710_33MHZ) ||
+					(b_PCIInputClock == APCI1710_40MHZ)) {
+		    /*************************/
+					/* Test the filter value */
+		    /*************************/
+
+					if (b_Filter < 16) {
+		       /**********************/
+						/* Test if 40MHz used */
+		       /**********************/
+
+						if (b_PCIInputClock ==
+							APCI1710_40MHZ) {
+			  /*********************************/
+							/* Test if 40MHz quartz on board */
+			  /*********************************/
+
+							dw_Status =
+								inl(devpriv->
+								s_BoardInfos.
+								ui_Address +
+								36 +
+								(64 * b_ModulNbr));
+
+			  /******************************/
+							/* Test the quartz flag (DQ0) */
+			  /******************************/
+
+							if ((dw_Status & 1) !=
+								1) {
+			     /*****************************/
+								/* 40MHz quartz not on board */
+			     /*****************************/
+
+								DPRINTK("40MHz quartz not on board\n");
+								i_ReturnValue =
+									-6;
+							}
+						}	// if (b_PCIInputClock == APCI1710_40MHZ)
+
+		       /***************************/
+						/* Test if error not occur */
+		       /***************************/
+
+						if (i_ReturnValue == 0) {
+			  /**********************/
+							/* Test if 40MHz used */
+			  /**********************/
+
+							if (b_PCIInputClock ==
+								APCI1710_40MHZ)
+							{
+			     /*********************************/
+								/* Enable the 40MHz quarz (DQ31) */
+			     /*********************************/
+
+								devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_SiemensCounterInfo.
+									s_ModeRegister.
+									s_ByteModeRegister.
+									b_ModeRegister4
+									=
+									devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_SiemensCounterInfo.
+									s_ModeRegister.
+									s_ByteModeRegister.
+									b_ModeRegister4
+									|
+									APCI1710_ENABLE_40MHZ_FILTER;
+
+							}	// if (b_PCIInputClock == APCI1710_40MHZ)
+							else {
+			     /**********************************/
+								/* Disable the 40MHz quarz (DQ31) */
+			     /**********************************/
+
+								devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_SiemensCounterInfo.
+									s_ModeRegister.
+									s_ByteModeRegister.
+									b_ModeRegister4
+									=
+									devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_SiemensCounterInfo.
+									s_ModeRegister.
+									s_ByteModeRegister.
+									b_ModeRegister4
+									&
+									APCI1710_DISABLE_40MHZ_FILTER;
+
+							}	// if (b_PCIInputClock == APCI1710_40MHZ)
+
+			  /************************/
+							/* Set the filter value */
+			  /************************/
+
+							devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_SiemensCounterInfo.
+								s_ModeRegister.
+								s_ByteModeRegister.
+								b_ModeRegister3
+								=
+								(devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_SiemensCounterInfo.
+								s_ModeRegister.
+								s_ByteModeRegister.
+								b_ModeRegister3
+								& 0x1F) |
+								((b_Filter &
+									0x7) <<
+								5);
+
+							devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_SiemensCounterInfo.
+								s_ModeRegister.
+								s_ByteModeRegister.
+								b_ModeRegister4
+								=
+								(devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_SiemensCounterInfo.
+								s_ModeRegister.
+								s_ByteModeRegister.
+								b_ModeRegister4
+								& 0xFE) |
+								((b_Filter &
+									0x8) >>
+								3);
+
+			  /***************************/
+							/* Write the configuration */
+			  /***************************/
+
+							outl(devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_SiemensCounterInfo.
+								s_ModeRegister.
+								dw_ModeRegister1_2_3_4,
+								devpriv->
+								s_BoardInfos.
+								ui_Address +
+								20 +
+								(64 * b_ModulNbr));
+						}	// if (i_ReturnValue == 0)
+					}	// if (b_Filter < 16)
+					else {
+		       /**************************************/
+						/* The selected filter value is wrong */
+		       /**************************************/
+
+						DPRINTK("The selected filter value is wrong\n");
+						i_ReturnValue = -5;
+					}	// if (b_Filter < 16)
+				}	// if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ) || (b_PCIInputClock == APCI1710_40MHZ))
+				else {
+		    /*****************************************/
+					/* The selected PCI input clock is wrong */
+		    /*****************************************/
+
+					DPRINTK("The selected PCI input clock is wrong\n");
+					i_ReturnValue = 4;
+				}	// if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ) || (b_PCIInputClock == APCI1710_40MHZ))
+			} else {
+		 /**************************************/
+				/* The module is not a counter module */
+		 /**************************************/
+
+				DPRINTK("The module is not a counter module\n");
+				i_ReturnValue = -3;
+			}
+		} else {
+	      /**************************************/
+			/* The module is not a counter module */
+	      /**************************************/
+
+			DPRINTK("The module is not a counter module\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_LatchCounter (BYTE_ b_BoardHandle,    |
+|                                                    BYTE_ b_ModulNbr,       |
+|                                                    BYTE_ b_LatchReg)       |
++----------------------------------------------------------------------------+
+| Task              : Latch the courant value from selected module           |
+|                     (b_ModulNbr) in to the selected latch register         |
+|                     (b_LatchReg).                                          |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle : Handle of board APCI-1710        |
+|                     BYTE_ b_ModulNbr    : Module number to configure       |
+|                                           (0 to 3)                         |
+|                     BYTE_ b_LatchReg    : Selected latch register          |
+|                               0 : for the first latch register             |
+|                               1 : for the second latch register            |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: No counter module found                            |
+|                     -3: Counter not initialised see function               |
+|                         "i_APCI1710_InitCounter"                           |
+|                     -4: The selected latch register parameter is wrong     |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_LatchCounter(struct comedi_device * dev,
+	BYTE b_ModulNbr, BYTE b_LatchReg)
+{
+	INT i_ReturnValue = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+	      /*************************************/
+			/* Test the latch register parameter */
+	      /*************************************/
+
+			if (b_LatchReg < 2) {
+		 /*********************/
+				/* Tatch the counter */
+		 /*********************/
+
+				outl(1 << (b_LatchReg * 4),
+					devpriv->s_BoardInfos.ui_Address +
+					(64 * b_ModulNbr));
+			} else {
+		 /**************************************************/
+				/* The selected latch register parameter is wrong */
+		 /**************************************************/
+
+				DPRINTK("The selected latch register parameter is wrong\n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_	i_APCI1710_SetIndexAndReferenceSource        |
+|					(BYTE_ b_BoardHandle,                |
+|					 BYTE_ b_ModulNbr,                   |
+|					 BYTE_ b_SourceSelection)            |
++----------------------------------------------------------------------------+
+| Task              : Determine the hardware source for the index and the    |
+|		      reference logic. Per default the index logic is        |
+|		      connected to the difference input C and the reference  |
+|		      logic is connected to the 24V input E                  |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle     : Handle of board APCI-1710    |
+|                     BYTE_ b_ModulNbr        : Module number to configure   |
+|                                               (0 to 3)                     |
+|		      BYTE_ b_SourceSelection : APCI1710_SOURCE_0 :          |
+|						The index logic is connected |
+|						to the difference input C and|
+|						the reference logic is       |
+|						connected to the 24V input E.|
+|						This is the default          |
+|						configuration.               |
+|						APCI1710_SOURCE_1 :          |
+|						The reference logic is       |
+|						connected to the difference  |
+|						input C and the index logic  |
+|						is connected to the 24V      |
+|						input E                      |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|		      -2: The selected module number is wrong                |
+|		      -3: The module is not a counter module.                |
+|		      -4: The source selection is wrong                      |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_SetIndexAndReferenceSource(struct comedi_device * dev,
+	BYTE b_ModulNbr, BYTE b_SourceSelection)
+{
+	INT i_ReturnValue = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if incremental counter */
+	   /*******************************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_INCREMENTAL_COUNTER) {
+	      /******************************/
+			/* Test if firmware >= Rev1.5 */
+	      /******************************/
+
+			if ((devpriv->s_BoardInfos.
+					dw_MolduleConfiguration[b_ModulNbr] &
+					0xFFFF) >= 0x3135) {
+		 /*****************************/
+				/* Test the source selection */
+		 /*****************************/
+
+				if (b_SourceSelection == APCI1710_SOURCE_0 ||
+					b_SourceSelection == APCI1710_SOURCE_1)
+				{
+		    /******************************************/
+					/* Test if invert the index and reference */
+		    /******************************************/
+
+					if (b_SourceSelection ==
+						APCI1710_SOURCE_1) {
+		       /********************************************/
+						/* Invert index and reference source (DQ25) */
+		       /********************************************/
+
+						devpriv->
+							s_ModuleInfo
+							[b_ModulNbr].
+							s_SiemensCounterInfo.
+							s_ModeRegister.
+							s_ByteModeRegister.
+							b_ModeRegister4 =
+							devpriv->
+							s_ModuleInfo
+							[b_ModulNbr].
+							s_SiemensCounterInfo.
+							s_ModeRegister.
+							s_ByteModeRegister.
+							b_ModeRegister4 |
+							APCI1710_INVERT_INDEX_RFERENCE;
+					} else {
+		       /****************************************/
+						/* Set the default configuration (DQ25) */
+		       /****************************************/
+
+						devpriv->
+							s_ModuleInfo
+							[b_ModulNbr].
+							s_SiemensCounterInfo.
+							s_ModeRegister.
+							s_ByteModeRegister.
+							b_ModeRegister4 =
+							devpriv->
+							s_ModuleInfo
+							[b_ModulNbr].
+							s_SiemensCounterInfo.
+							s_ModeRegister.
+							s_ByteModeRegister.
+							b_ModeRegister4 &
+							APCI1710_DEFAULT_INDEX_RFERENCE;
+					}
+				}	// if (b_SourceSelection == APCI1710_SOURCE_0 ||b_SourceSelection == APCI1710_SOURCE_1)
+				else {
+		    /*********************************/
+					/* The source selection is wrong */
+		    /*********************************/
+
+					DPRINTK("The source selection is wrong\n");
+					i_ReturnValue = -4;
+				}	// if (b_SourceSelection == APCI1710_SOURCE_0 ||b_SourceSelection == APCI1710_SOURCE_1)
+			} else {
+		 /**************************************/
+				/* The module is not a counter module */
+		 /**************************************/
+
+				DPRINTK("The module is not a counter module\n");
+				i_ReturnValue = -3;
+			}
+		} else {
+	      /**************************************/
+			/* The module is not a counter module */
+	      /**************************************/
+
+			DPRINTK("The module is not a counter module\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /***************************************/
+		/* The selected module number is wrong */
+	   /***************************************/
+
+		DPRINTK("The selected module number is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_	i_APCI1710_SetDigitalChlOn                   |
+|				   (BYTE_  b_BoardHandle,                    |
+|				    BYTE_  b_ModulNbr)                       |
++----------------------------------------------------------------------------+
+| Task              : Sets the digital output H Setting an output means      |
+|		      setting an ouput high.                                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_  b_BoardHandle    : Handle of board APCI-1710    |
+|		      BYTE_  b_ModulNbr	      :	Number of the module to be   |
+|						configured (0 to 3)          |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: The selected module number is wrong                |
+|                     -3: Counter not initialised see function               |
+|			  "i_APCI1710_InitCounter"                           |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_SetDigitalChlOn(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+	INT i_ReturnValue = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+			devpriv->
+				s_ModuleInfo[b_ModulNbr].
+				s_SiemensCounterInfo.
+				s_ModeRegister.
+				s_ByteModeRegister.
+				b_ModeRegister3 = devpriv->
+				s_ModuleInfo[b_ModulNbr].
+				s_SiemensCounterInfo.
+				s_ModeRegister.
+				s_ByteModeRegister.b_ModeRegister3 | 0x10;
+
+	      /*********************/
+			/* Set the output On */
+	      /*********************/
+
+			outl(devpriv->s_ModuleInfo[b_ModulNbr].
+				s_SiemensCounterInfo.
+				s_ModeRegister.
+				dw_ModeRegister1_2_3_4, devpriv->s_BoardInfos.
+				ui_Address + 20 + (64 * b_ModulNbr));
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_	i_APCI1710_SetDigitalChlOff                  |
+|				   (BYTE_  b_BoardHandle,                    |
+|				    BYTE_  b_ModulNbr)                       |
++----------------------------------------------------------------------------+
+| Task              : Resets the digital output H. Resetting an output means |
+|		      setting an ouput low.                                  |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_  b_BoardHandle    : Handle of board APCI-1710    |
+|		      BYTE_  b_ModulNbr	      :	Number of the module to be   |
+|						configured (0 to 3)          |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: The selected module number is wrong                |
+|                     -3: Counter not initialised see function               |
+|			  "i_APCI1710_InitCounter"                           |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_SetDigitalChlOff(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+	INT i_ReturnValue = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+			devpriv->
+				s_ModuleInfo[b_ModulNbr].
+				s_SiemensCounterInfo.
+				s_ModeRegister.
+				s_ByteModeRegister.
+				b_ModeRegister3 = devpriv->
+				s_ModuleInfo[b_ModulNbr].
+				s_SiemensCounterInfo.
+				s_ModeRegister.
+				s_ByteModeRegister.b_ModeRegister3 & 0xEF;
+
+	      /**********************/
+			/* Set the output Off */
+	      /**********************/
+
+			outl(devpriv->s_ModuleInfo[b_ModulNbr].
+				s_SiemensCounterInfo.
+				s_ModeRegister.
+				dw_ModeRegister1_2_3_4, devpriv->s_BoardInfos.
+				ui_Address + 20 + (64 * b_ModulNbr));
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*########################################################################### */
+
+							// INSN WRITE
+/*########################################################################### */
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     :INT	i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev,struct comedi_subdevice *s,
+struct comedi_insn *insn,unsigned int *data)                   |
++----------------------------------------------------------------------------+
+| Task              : Enable Disable functions for INC_CPT                                       |
++----------------------------------------------------------------------------+
+| Input Parameters  :
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1710_InsnWriteINCCPT(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_WriteType;
+	INT i_ReturnValue = 0;
+
+	ui_WriteType = CR_CHAN(insn->chanspec);
+	devpriv->tsk_Current = current;	// Save the current process task structure
+
+	switch (ui_WriteType) {
+	case APCI1710_INCCPT_ENABLELATCHINTERRUPT:
+		i_ReturnValue = i_APCI1710_EnableLatchInterrupt(dev,
+			(BYTE) CR_AREF(insn->chanspec));
+		break;
+
+	case APCI1710_INCCPT_DISABLELATCHINTERRUPT:
+		i_ReturnValue = i_APCI1710_DisableLatchInterrupt(dev,
+			(BYTE) CR_AREF(insn->chanspec));
+		break;
+
+	case APCI1710_INCCPT_WRITE16BITCOUNTERVALUE:
+		i_ReturnValue = i_APCI1710_Write16BitCounterValue(dev,
+			(BYTE) CR_AREF(insn->chanspec),
+			(BYTE) data[0], (UINT) data[1]);
+		break;
+
+	case APCI1710_INCCPT_WRITE32BITCOUNTERVALUE:
+		i_ReturnValue = i_APCI1710_Write32BitCounterValue(dev,
+			(BYTE) CR_AREF(insn->chanspec), (ULONG) data[0]);
+
+		break;
+
+	case APCI1710_INCCPT_ENABLEINDEX:
+		i_APCI1710_EnableIndex(dev, (BYTE) CR_AREF(insn->chanspec));
+		break;
+
+	case APCI1710_INCCPT_DISABLEINDEX:
+		i_ReturnValue = i_APCI1710_DisableIndex(dev,
+			(BYTE) CR_AREF(insn->chanspec));
+		break;
+
+	case APCI1710_INCCPT_ENABLECOMPARELOGIC:
+		i_ReturnValue = i_APCI1710_EnableCompareLogic(dev,
+			(BYTE) CR_AREF(insn->chanspec));
+		break;
+
+	case APCI1710_INCCPT_DISABLECOMPARELOGIC:
+		i_ReturnValue = i_APCI1710_DisableCompareLogic(dev,
+			(BYTE) CR_AREF(insn->chanspec));
+		break;
+
+	case APCI1710_INCCPT_ENABLEFREQUENCYMEASUREMENT:
+		i_ReturnValue = i_APCI1710_EnableFrequencyMeasurement(dev,
+			(BYTE) CR_AREF(insn->chanspec), (BYTE) data[0]);
+		break;
+
+	case APCI1710_INCCPT_DISABLEFREQUENCYMEASUREMENT:
+		i_ReturnValue = i_APCI1710_DisableFrequencyMeasurement(dev,
+			(BYTE) CR_AREF(insn->chanspec));
+		break;
+
+	default:
+		printk("Write Config Parameter Wrong\n");
+	}
+
+	if (i_ReturnValue >= 0)
+		i_ReturnValue = insn->n;
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_EnableLatchInterrupt                  |
+|                               (BYTE_ b_BoardHandle,                        |
+|                                BYTE_ b_ModulNbr)                           |
++----------------------------------------------------------------------------+
+| Task              : Enable the latch interrupt from selected module        |
+|                     (b_ModulNbr). Each software or hardware latch occur a  |
+|                     interrupt.                                             |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle : Handle of board APCI-1710        |
+|                     BYTE_ b_ModulNbr    : Module number to configure       |
+|                                           (0 to 3)                         |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: No counter module found                            |
+|                     -3: Counter not initialised see function               |
+|                         "i_APCI1710_InitCounter"                           |
+|                     -4: Interrupt routine not installed see function       |
+|                         "i_APCI1710_SetBoardIntRoutine"                    |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_EnableLatchInterrupt(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+	INT i_ReturnValue = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+
+		 /********************/
+			/* Enable interrupt */
+		 /********************/
+
+			devpriv->s_ModuleInfo[b_ModulNbr].
+				s_SiemensCounterInfo.
+				s_ModeRegister.
+				s_ByteModeRegister.
+				b_ModeRegister2 = devpriv->
+				s_ModuleInfo[b_ModulNbr].
+				s_SiemensCounterInfo.
+				s_ModeRegister.
+				s_ByteModeRegister.
+				b_ModeRegister2 | APCI1710_ENABLE_LATCH_INT;
+
+		 /***************************/
+			/* Write the configuration */
+		 /***************************/
+
+			outl(devpriv->s_ModuleInfo[b_ModulNbr].
+				s_SiemensCounterInfo.
+				s_ModeRegister.
+				dw_ModeRegister1_2_3_4, devpriv->s_BoardInfos.
+				ui_Address + 20 + (64 * b_ModulNbr));
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_DisableLatchInterrupt                 |
+|                               (BYTE_ b_BoardHandle,                        |
+|                                BYTE_ b_ModulNbr)                           |
++----------------------------------------------------------------------------+
+| Task              : Disable the latch interrupt from selected module       |
+|                     (b_ModulNbr).                                          |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle : Handle of board APCI-1710        |
+|                     BYTE_ b_ModulNbr    : Module number to configure       |
+|                                           (0 to 3)                         |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: No counter module found                            |
+|                     -3: Counter not initialised see function               |
+|                         "i_APCI1710_InitCounter"                           |
+|                     -4: Interrupt routine not installed see function       |
+|                         "i_APCI1710_SetBoardIntRoutine"                    |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_DisableLatchInterrupt(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+	INT i_ReturnValue = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+
+		 /***************************/
+			/* Write the configuration */
+		 /***************************/
+
+			outl(devpriv->s_ModuleInfo[b_ModulNbr].
+				s_SiemensCounterInfo.
+				s_ModeRegister.
+				dw_ModeRegister1_2_3_4 &
+				((APCI1710_DISABLE_LATCH_INT << 8) | 0xFF),
+				devpriv->s_BoardInfos.ui_Address + 20 +
+				(64 * b_ModulNbr));
+
+			mdelay(1000);
+
+		 /*********************/
+			/* Disable interrupt */
+		 /*********************/
+
+			devpriv->
+				s_ModuleInfo[b_ModulNbr].
+				s_SiemensCounterInfo.
+				s_ModeRegister.
+				s_ByteModeRegister.
+				b_ModeRegister2 = devpriv->
+				s_ModuleInfo[b_ModulNbr].
+				s_SiemensCounterInfo.
+				s_ModeRegister.
+				s_ByteModeRegister.
+				b_ModeRegister2 & APCI1710_DISABLE_LATCH_INT;
+
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_Write16BitCounterValue                |
+|                                               (BYTE_  b_BoardHandle        |
+|                                                BYTE_  b_ModulNbr,          |
+|                                                BYTE_  b_SelectedCounter,   |
+|                                                UINT_ ui_WriteValue)        |
++----------------------------------------------------------------------------+
+| Task              : Write a 16-Bit value (ui_WriteValue) in to the selected|
+|                     16-Bit counter (b_SelectedCounter) from selected module|
+|                     (b_ModulNbr).                                          |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle     : Handle of board APCI-1710    |
+|                     BYTE_ b_ModulNbr        : Module number to configure   |
+|                                              (0 to 3)                      |
+|                     BYTE_ b_SelectedCounter : Selected 16-Bit counter      |
+|                                               (0 or 1)                     |
+|                     UINT_ ui_WriteValue     : 16-Bit write value           |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: No counter module found                            |
+|                     -3: Counter not initialised see function               |
+|                         "i_APCI1710_InitCounter"                           |
+|                     -4: The selected 16-Bit counter parameter is wrong     |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_Write16BitCounterValue(struct comedi_device * dev,
+	BYTE b_ModulNbr, BYTE b_SelectedCounter, UINT ui_WriteValue)
+{
+	INT i_ReturnValue = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+	      /******************************/
+			/* Test the counter selection */
+	      /******************************/
+
+			if (b_SelectedCounter < 2) {
+		 /*******************/
+				/* Write the value */
+		 /*******************/
+
+				outl((ULONG) ((ULONG) (ui_WriteValue) << (16 *
+							b_SelectedCounter)),
+					devpriv->s_BoardInfos.ui_Address + 8 +
+					(b_SelectedCounter * 4) +
+					(64 * b_ModulNbr));
+			} else {
+		 /**************************************************/
+				/* The selected 16-Bit counter parameter is wrong */
+		 /**************************************************/
+
+				DPRINTK("The selected 16-Bit counter parameter is wrong\n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_Write32BitCounterValue                |
+|                                               (BYTE_   b_BoardHandle       |
+|                                                BYTE_   b_ModulNbr,         |
+|                                                ULONG_ ul_WriteValue)       |
++----------------------------------------------------------------------------+
+| Task              : Write a 32-Bit value (ui_WriteValue) in to the selected|
+|                     module (b_ModulNbr).                                   |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle     : Handle of board APCI-1710    |
+|                     BYTE_ b_ModulNbr        : Module number to configure   |
+|                                              (0 to 3)                      |
+|                     ULONG_ ul_WriteValue    : 32-Bit write value           |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: No counter module found                            |
+|                     -3: Counter not initialised see function               |
+|                         "i_APCI1710_InitCounter"                           |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_Write32BitCounterValue(struct comedi_device * dev,
+	BYTE b_ModulNbr, ULONG ul_WriteValue)
+{
+	INT i_ReturnValue = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+	      /*******************/
+			/* Write the value */
+	      /*******************/
+
+			outl(ul_WriteValue, devpriv->s_BoardInfos.
+				ui_Address + 4 + (64 * b_ModulNbr));
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_EnableIndex (BYTE_  b_BoardHandle,    |
+|                                                   BYTE_  b_ModulNbr)       |
++----------------------------------------------------------------------------+
+| Task              : Enable the INDEX actions                               |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle     : Handle of board APCI-1710    |
+|                     BYTE_ b_ModulNbr        : Module number to configure   |
+|                                               (0 to 3)                     |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: No counter module found                            |
+|                     -3: Counter not initialised see function               |
+|                         "i_APCI1710_InitCounter"                           |
+|                     -4: Index not initialised see function                 |
+|                         "i_APCI1710_InitIndex"                             |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_EnableIndex(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+	INT i_ReturnValue = 0;
+	ULONG ul_InterruptLatchReg;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+	      /*****************************/
+			/* Test if index initialised */
+	      /*****************************/
+
+			if (devpriv->
+				s_ModuleInfo[b_ModulNbr].
+				s_SiemensCounterInfo.s_InitFlag.b_IndexInit) {
+				devpriv->
+					s_ModuleInfo[b_ModulNbr].
+					s_SiemensCounterInfo.
+					s_ModeRegister.
+					s_ByteModeRegister.
+					b_ModeRegister2 = devpriv->
+					s_ModuleInfo[b_ModulNbr].
+					s_SiemensCounterInfo.
+					s_ModeRegister.
+					s_ByteModeRegister.
+					b_ModeRegister2 | APCI1710_ENABLE_INDEX;
+
+				ul_InterruptLatchReg =
+					inl(devpriv->s_BoardInfos.ui_Address +
+					24 + (64 * b_ModulNbr));
+
+				outl(devpriv->s_ModuleInfo[b_ModulNbr].
+					s_SiemensCounterInfo.
+					s_ModeRegister.
+					dw_ModeRegister1_2_3_4,
+					devpriv->s_BoardInfos.ui_Address + 20 +
+					(64 * b_ModulNbr));
+			} else {
+		 /*************************************************************/
+				/* Index not initialised see function "i_APCI1710_InitIndex" */
+		 /*************************************************************/
+
+				DPRINTK("Index not initialised \n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_DisableIndex (BYTE_  b_BoardHandle,   |
+|                                                    BYTE_  b_ModulNbr)      |
++----------------------------------------------------------------------------+
+| Task              : Disable the INDEX actions                              |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle     : Handle of board APCI-1710    |
+|                     BYTE_ b_ModulNbr        : Module number to configure   |
+|                                               (0 to 3)                     |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: No counter module found                            |
+|                     -3: Counter not initialised see function               |
+|                         "i_APCI1710_InitCounter"                           |
+|                     -4: Index not initialised see function                 |
+|                         "i_APCI1710_InitIndex"                             |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_DisableIndex(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+	INT i_ReturnValue = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+	      /*****************************/
+			/* Test if index initialised */
+	      /*****************************/
+
+			if (devpriv->
+				s_ModuleInfo[b_ModulNbr].
+				s_SiemensCounterInfo.s_InitFlag.b_IndexInit) {
+				devpriv->
+					s_ModuleInfo[b_ModulNbr].
+					s_SiemensCounterInfo.
+					s_ModeRegister.
+					s_ByteModeRegister.
+					b_ModeRegister2 = devpriv->
+					s_ModuleInfo[b_ModulNbr].
+					s_SiemensCounterInfo.
+					s_ModeRegister.
+					s_ByteModeRegister.
+					b_ModeRegister2 &
+					APCI1710_DISABLE_INDEX;
+
+				outl(devpriv->s_ModuleInfo[b_ModulNbr].
+					s_SiemensCounterInfo.
+					s_ModeRegister.
+					dw_ModeRegister1_2_3_4,
+					devpriv->s_BoardInfos.ui_Address + 20 +
+					(64 * b_ModulNbr));
+			} else {
+		 /*************************************************************/
+				/* Index not initialised see function "i_APCI1710_InitIndex" */
+		 /*************************************************************/
+
+				DPRINTK("Index not initialised  \n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_EnableCompareLogic                    |
+|                               (BYTE_   b_BoardHandle,                      |
+|                                BYTE_   b_ModulNbr)                         |
++----------------------------------------------------------------------------+
+| Task              : Enable the 32-Bit compare logic. At that moment that   |
+|                     the incremental counter arrive to the compare value a  |
+|                     interrupt is generated.                                |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_  b_BoardHandle    : Handle of board APCI-1710    |
+|                     BYTE_  b_ModulNbr       : Module number to configure   |
+|                                               (0 to 3)                     |
++----------------------------------------------------------------------------+
+| Output Parameters : -
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: No counter module found                            |
+|                     -3: Counter not initialised see function               |
+|                         "i_APCI1710_InitCounter"                           |
+|                     -4: Compare logic not initialised.                     |
+|                         See function "i_APCI1710_InitCompareLogic"         |
+|                     -5: Interrupt function not initialised.                |
+|                         See function "i_APCI1710_SetBoardIntRoutineX"      |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_EnableCompareLogic(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+	INT i_ReturnValue = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+	      /*************************************/
+			/* Test if compare logic initialised */
+	      /*************************************/
+
+			if (devpriv->
+				s_ModuleInfo[b_ModulNbr].
+				s_SiemensCounterInfo.
+				s_InitFlag.b_CompareLogicInit == 1) {
+				devpriv->
+					s_ModuleInfo[b_ModulNbr].
+					s_SiemensCounterInfo.
+					s_ModeRegister.
+					s_ByteModeRegister.
+					b_ModeRegister3 = devpriv->
+					s_ModuleInfo[b_ModulNbr].
+					s_SiemensCounterInfo.
+					s_ModeRegister.
+					s_ByteModeRegister.
+					b_ModeRegister3 |
+					APCI1710_ENABLE_COMPARE_INT;
+
+		    /***************************/
+				/* Write the configuration */
+		    /***************************/
+
+				outl(devpriv->s_ModuleInfo[b_ModulNbr].
+					s_SiemensCounterInfo.
+					s_ModeRegister.
+					dw_ModeRegister1_2_3_4,
+					devpriv->s_BoardInfos.ui_Address + 20 +
+					(64 * b_ModulNbr));
+			} else {
+		 /*********************************/
+				/* Compare logic not initialised */
+		 /*********************************/
+
+				DPRINTK("Compare logic not initialised\n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_DisableCompareLogic                   |
+|                               (BYTE_   b_BoardHandle,                      |
+|                                BYTE_   b_ModulNbr)                         |
++----------------------------------------------------------------------------+
+| Task              : Disable the 32-Bit compare logic.
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_  b_BoardHandle    : Handle of board APCI-1710    |
+|                     BYTE_  b_ModulNbr       : Module number to configure   |
+|                                               (0 to 3)                     |
++----------------------------------------------------------------------------+
+| Output Parameters : -
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: No counter module found                            |
+|                     -3: Counter not initialised see function               |
+|                         "i_APCI1710_InitCounter"                           |
+|                     -4: Compare logic not initialised.                     |
+|                         See function "i_APCI1710_InitCompareLogic"         |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_DisableCompareLogic(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+	INT i_ReturnValue = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+	      /*************************************/
+			/* Test if compare logic initialised */
+	      /*************************************/
+
+			if (devpriv->
+				s_ModuleInfo[b_ModulNbr].
+				s_SiemensCounterInfo.
+				s_InitFlag.b_CompareLogicInit == 1) {
+				devpriv->
+					s_ModuleInfo[b_ModulNbr].
+					s_SiemensCounterInfo.
+					s_ModeRegister.
+					s_ByteModeRegister.
+					b_ModeRegister3 = devpriv->
+					s_ModuleInfo[b_ModulNbr].
+					s_SiemensCounterInfo.
+					s_ModeRegister.
+					s_ByteModeRegister.
+					b_ModeRegister3 &
+					APCI1710_DISABLE_COMPARE_INT;
+
+		 /***************************/
+				/* Write the configuration */
+		 /***************************/
+
+				outl(devpriv->s_ModuleInfo[b_ModulNbr].
+					s_SiemensCounterInfo.
+					s_ModeRegister.
+					dw_ModeRegister1_2_3_4,
+					devpriv->s_BoardInfos.ui_Address + 20 +
+					(64 * b_ModulNbr));
+			} else {
+		 /*********************************/
+				/* Compare logic not initialised */
+		 /*********************************/
+
+				DPRINTK("Compare logic not initialised\n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+	/*
+	   +----------------------------------------------------------------------------+
+	   | Function Name     : _INT_ i_APCI1710_EnableFrequencyMeasurement            |
+	   |                            (BYTE_   b_BoardHandle,                      |
+	   |                             BYTE_   b_ModulNbr,                         |
+	   |                             BYTE_   b_InterruptEnable)                  |
+	   +----------------------------------------------------------------------------+
+	   | Task              : Enables the frequency measurement function             |
+	   +----------------------------------------------------------------------------+
+	   | Input Parameters  : BYTE_  b_BoardHandle    : Handle of board APCI-1710    |
+	   |                  BYTE_  b_ModulNbr       : Number of the module to be   |
+	   |                                            configured (0 to 3)          |
+	   |                  BYTE_  b_InterruptEnable: Enable or disable the        |
+	   |                                            interrupt.                   |
+	   |                                            APCI1710_ENABLE:             |
+	   |                                            Enable the interrupt         |
+	   |                                            APCI1710_DISABLE:            |
+	   |                                            Disable the interrupt        |
+	   +----------------------------------------------------------------------------+
+	   | Output Parameters : -                                                      |
+	   +----------------------------------------------------------------------------+
+	   | Return Value      :  0: No error                                           |
+	   |                     -1: The handle parameter of the board is wrong         |
+	   |                     -2: The selected module number is wrong                |
+	   |                     -3: Counter not initialised see function               |
+	   |                      "i_APCI1710_InitCounter"                           |
+	   |                     -4: Frequency measurement logic not initialised.       |
+	   |                      See function "i_APCI1710_InitFrequencyMeasurement" |
+	   |                     -5: Interrupt parameter is wrong                       |
+	   |                     -6: Interrupt function not initialised.                |
+	   +----------------------------------------------------------------------------+
+	 */
+
+INT i_APCI1710_EnableFrequencyMeasurement(struct comedi_device * dev,
+	BYTE b_ModulNbr, BYTE b_InterruptEnable)
+{
+	INT i_ReturnValue = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+	      /********************************************/
+			/* Test if frequency mesurement initialised */
+	      /********************************************/
+
+			if (devpriv->
+				s_ModuleInfo[b_ModulNbr].
+				s_SiemensCounterInfo.
+				s_InitFlag.b_FrequencyMeasurementInit == 1) {
+		 /***************************/
+				/* Test the interrupt mode */
+		 /***************************/
+
+				if ((b_InterruptEnable == APCI1710_DISABLE) ||
+					(b_InterruptEnable == APCI1710_ENABLE))
+				{
+
+		       /************************************/
+					/* Enable the frequency measurement */
+		       /************************************/
+
+					devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_SiemensCounterInfo.
+						s_ModeRegister.
+						s_ByteModeRegister.
+						b_ModeRegister3 = devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_SiemensCounterInfo.
+						s_ModeRegister.
+						s_ByteModeRegister.
+						b_ModeRegister3 |
+						APCI1710_ENABLE_FREQUENCY;
+
+		       /*********************************************/
+					/* Disable or enable the frequency interrupt */
+		       /*********************************************/
+
+					devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_SiemensCounterInfo.
+						s_ModeRegister.
+						s_ByteModeRegister.
+						b_ModeRegister3 = (devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_SiemensCounterInfo.
+						s_ModeRegister.
+						s_ByteModeRegister.
+						b_ModeRegister3 &
+						APCI1710_DISABLE_FREQUENCY_INT)
+						| (b_InterruptEnable << 3);
+
+		       /***************************/
+					/* Write the configuration */
+		       /***************************/
+
+					outl(devpriv->s_ModuleInfo[b_ModulNbr].
+						s_SiemensCounterInfo.
+						s_ModeRegister.
+						dw_ModeRegister1_2_3_4,
+						devpriv->s_BoardInfos.
+						ui_Address + 20 +
+						(64 * b_ModulNbr));
+
+					devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_SiemensCounterInfo.
+						s_InitFlag.
+						b_FrequencyMeasurementEnable =
+						1;
+				} else {
+		    /********************************/
+					/* Interrupt parameter is wrong */
+		    /********************************/
+
+					DPRINTK("Interrupt parameter is wrong\n");
+					i_ReturnValue = -5;
+				}
+			} else {
+		 /***********************************************/
+				/* Frequency measurement logic not initialised */
+		 /***********************************************/
+
+				DPRINTK("Frequency measurement logic not initialised\n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+	/*
+	   +----------------------------------------------------------------------------+
+	   | Function Name     : _INT_ i_APCI1710_DisableFrequencyMeasurement           |
+	   |                            (BYTE_   b_BoardHandle,                      |
+	   |                             BYTE_   b_ModulNbr)                         |
+	   +----------------------------------------------------------------------------+
+	   | Task              : Disables the frequency measurement function             |
+	   +----------------------------------------------------------------------------+
+	   | Input Parameters  : BYTE_  b_BoardHandle    : Handle of board APCI-1710    |
+	   |                  BYTE_  b_ModulNbr       : Number of the module to be   |
+	   |                                            configured (0 to 3)          |
+	   +----------------------------------------------------------------------------+
+	   | Output Parameters : -                                                      |
+	   +----------------------------------------------------------------------------+
+	   | Return Value      :  0: No error                                           |
+	   |                     -1: The handle parameter of the board is wrong         |
+	   |                     -2: The selected module number is wrong                |
+	   |                     -3: Counter not initialised see function               |
+	   |                      "i_APCI1710_InitCounter"                           |
+	   |                     -4: Frequency measurement logic not initialised.       |
+	   |                      See function "i_APCI1710_InitFrequencyMeasurement" |
+	   +----------------------------------------------------------------------------+
+	 */
+
+INT i_APCI1710_DisableFrequencyMeasurement(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+	INT i_ReturnValue = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+	      /********************************************/
+			/* Test if frequency mesurement initialised */
+	      /********************************************/
+
+			if (devpriv->
+				s_ModuleInfo[b_ModulNbr].
+				s_SiemensCounterInfo.
+				s_InitFlag.b_FrequencyMeasurementInit == 1) {
+		 /*************************************/
+				/* Disable the frequency measurement */
+		 /*************************************/
+
+				devpriv->
+					s_ModuleInfo[b_ModulNbr].
+					s_SiemensCounterInfo.
+					s_ModeRegister.
+					s_ByteModeRegister.
+					b_ModeRegister3 = devpriv->
+					s_ModuleInfo[b_ModulNbr].
+					s_SiemensCounterInfo.
+					s_ModeRegister.
+					s_ByteModeRegister.
+					b_ModeRegister3 &
+					APCI1710_DISABLE_FREQUENCY
+					// Begin CG 29/06/01 CG 1100/0231 -> 0701/0232 Frequence measure IRQ must be cleared
+					& APCI1710_DISABLE_FREQUENCY_INT;
+				// End CG 29/06/01 CG 1100/0231 -> 0701/0232 Frequence measure IRQ must be cleared
+
+		 /***************************/
+				/* Write the configuration */
+		 /***************************/
+
+				outl(devpriv->s_ModuleInfo[b_ModulNbr].
+					s_SiemensCounterInfo.
+					s_ModeRegister.
+					dw_ModeRegister1_2_3_4,
+					devpriv->s_BoardInfos.ui_Address + 20 +
+					(64 * b_ModulNbr));
+
+		 /*************************************/
+				/* Disable the frequency measurement */
+		 /*************************************/
+
+				devpriv->
+					s_ModuleInfo[b_ModulNbr].
+					s_SiemensCounterInfo.
+					s_InitFlag.
+					b_FrequencyMeasurementEnable = 0;
+			} else {
+		 /***********************************************/
+				/* Frequency measurement logic not initialised */
+		 /***********************************************/
+
+				DPRINTK("Frequency measurement logic not initialised\n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*########################################################################### */
+
+							// INSN READ
+
+/*########################################################################### */
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     :INT	i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev,struct comedi_subdevice *s,
+struct comedi_insn *insn,unsigned int *data)                   |
++----------------------------------------------------------------------------+
+| Task              : Read and Get functions for INC_CPT                                       |
++----------------------------------------------------------------------------+
+| Input Parameters  :
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1710_InsnReadINCCPT(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_ReadType;
+	INT i_ReturnValue = 0;
+
+	ui_ReadType = CR_CHAN(insn->chanspec);
+
+	devpriv->tsk_Current = current;	// Save the current process task structure
+	switch (ui_ReadType) {
+	case APCI1710_INCCPT_READLATCHREGISTERSTATUS:
+		i_ReturnValue = i_APCI1710_ReadLatchRegisterStatus(dev,
+			(BYTE) CR_AREF(insn->chanspec),
+			(BYTE) CR_RANGE(insn->chanspec), (PBYTE) & data[0]);
+		break;
+
+	case APCI1710_INCCPT_READLATCHREGISTERVALUE:
+		i_ReturnValue = i_APCI1710_ReadLatchRegisterValue(dev,
+			(BYTE) CR_AREF(insn->chanspec),
+			(BYTE) CR_RANGE(insn->chanspec), (PULONG) & data[0]);
+		printk("Latch Register Value %d\n", data[0]);
+		break;
+
+	case APCI1710_INCCPT_READ16BITCOUNTERVALUE:
+		i_ReturnValue = i_APCI1710_Read16BitCounterValue(dev,
+			(BYTE) CR_AREF(insn->chanspec),
+			(BYTE) CR_RANGE(insn->chanspec), (PUINT) & data[0]);
+		break;
+
+	case APCI1710_INCCPT_READ32BITCOUNTERVALUE:
+		i_ReturnValue = i_APCI1710_Read32BitCounterValue(dev,
+			(BYTE) CR_AREF(insn->chanspec), (PULONG) & data[0]);
+		break;
+
+	case APCI1710_INCCPT_GETINDEXSTATUS:
+		i_ReturnValue = i_APCI1710_GetIndexStatus(dev,
+			(BYTE) CR_AREF(insn->chanspec), (PBYTE) & data[0]);
+		break;
+
+	case APCI1710_INCCPT_GETREFERENCESTATUS:
+		i_ReturnValue = i_APCI1710_GetReferenceStatus(dev,
+			(BYTE) CR_AREF(insn->chanspec), (PBYTE) & data[0]);
+		break;
+
+	case APCI1710_INCCPT_GETUASSTATUS:
+		i_ReturnValue = i_APCI1710_GetUASStatus(dev,
+			(BYTE) CR_AREF(insn->chanspec), (PBYTE) & data[0]);
+		break;
+
+	case APCI1710_INCCPT_GETCBSTATUS:
+		i_ReturnValue = i_APCI1710_GetCBStatus(dev,
+			(BYTE) CR_AREF(insn->chanspec), (PBYTE) & data[0]);
+		break;
+
+	case APCI1710_INCCPT_GET16BITCBSTATUS:
+		i_ReturnValue = i_APCI1710_Get16BitCBStatus(dev,
+			(BYTE) CR_AREF(insn->chanspec),
+			(PBYTE) & data[0], (PBYTE) & data[1]);
+		break;
+
+	case APCI1710_INCCPT_GETUDSTATUS:
+		i_ReturnValue = i_APCI1710_GetUDStatus(dev,
+			(BYTE) CR_AREF(insn->chanspec), (PBYTE) & data[0]);
+
+		break;
+
+	case APCI1710_INCCPT_GETINTERRUPTUDLATCHEDSTATUS:
+		i_ReturnValue = i_APCI1710_GetInterruptUDLatchedStatus(dev,
+			(BYTE) CR_AREF(insn->chanspec), (PBYTE) & data[0]);
+		break;
+
+	case APCI1710_INCCPT_READFREQUENCYMEASUREMENT:
+		i_ReturnValue = i_APCI1710_ReadFrequencyMeasurement(dev,
+			(BYTE) CR_AREF(insn->chanspec),
+			(PBYTE) & data[0],
+			(PBYTE) & data[1], (PULONG) & data[2]);
+		break;
+
+	case APCI1710_INCCPT_READINTERRUPT:
+		data[0] = devpriv->s_InterruptParameters.
+			s_FIFOInterruptParameters[devpriv->
+			s_InterruptParameters.ui_Read].b_OldModuleMask;
+		data[1] = devpriv->s_InterruptParameters.
+			s_FIFOInterruptParameters[devpriv->
+			s_InterruptParameters.ui_Read].ul_OldInterruptMask;
+		data[2] = devpriv->s_InterruptParameters.
+			s_FIFOInterruptParameters[devpriv->
+			s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
+
+		/**************************/
+		/* Increment the read FIFO */
+		/***************************/
+
+		devpriv->
+			s_InterruptParameters.
+			ui_Read = (devpriv->s_InterruptParameters.
+			ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+
+		break;
+
+	default:
+		printk("ReadType Parameter wrong\n");
+	}
+
+	if (i_ReturnValue >= 0)
+		i_ReturnValue = insn->n;
+	return (i_ReturnValue);
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_ReadLatchRegisterStatus               |
+|                                                   (BYTE_   b_BoardHandle,  |
+|                                                    BYTE_   b_ModulNbr,     |
+|                                                    BYTE_   b_LatchReg,     |
+|                                                    PBYTE_ pb_LatchStatus)  |
++----------------------------------------------------------------------------+
+| Task              : Read the latch register status from selected module    |
+|                     (b_ModulNbr) and selected latch register (b_LatchReg). |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle : Handle of board APCI-1710        |
+|                     BYTE_ b_ModulNbr    : Module number to configure       |
+|                                           (0 to 3)                         |
+|                     BYTE_ b_LatchReg    : Selected latch register          |
+|                               0 : for the first latch register             |
+|                               1 : for the second latch register            |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_LatchStatus :   Latch register status.       |
+|                                               0 : No latch occur           |
+|                                               1 : A software latch occur   |
+|                                               2 : A hardware latch occur   |
+|                                               3 : A software and hardware  |
+|                                                   latch occur              |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: No counter module found                            |
+|                     -3: Counter not initialised see function               |
+|                         "i_APCI1710_InitCounter"                           |
+|                     -4: The selected latch register parameter is wrong     |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_ReadLatchRegisterStatus(struct comedi_device * dev,
+	BYTE b_ModulNbr, BYTE b_LatchReg, PBYTE pb_LatchStatus)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_LatchReg;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+	      /*************************************/
+			/* Test the latch register parameter */
+	      /*************************************/
+
+			if (b_LatchReg < 2) {
+				dw_LatchReg = inl(devpriv->s_BoardInfos.
+					ui_Address + (64 * b_ModulNbr));
+
+				*pb_LatchStatus =
+					(BYTE) ((dw_LatchReg >> (b_LatchReg *
+							4)) & 0x3);
+			} else {
+		 /**************************************************/
+				/* The selected latch register parameter is wrong */
+		 /**************************************************/
+
+				DPRINTK("The selected latch register parameter is wrong\n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_ReadLatchRegisterValue                |
+|                                                   (BYTE_     b_BoardHandle,|
+|                                                    BYTE_     b_ModulNbr,   |
+|                                                    BYTE_     b_LatchReg,   |
+|                                                    PULONG_ pul_LatchValue) |
++----------------------------------------------------------------------------+
+| Task              : Read the latch register value from selected module     |
+|                     (b_ModulNbr) and selected latch register (b_LatchReg). |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle : Handle of board APCI-1710        |
+|                     BYTE_ b_ModulNbr    : Module number to configure       |
+|                                           (0 to 3)                         |
+|                     BYTE_ b_LatchReg    : Selected latch register          |
+|                               0 : for the first latch register             |
+|                               1 : for the second latch register            |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_LatchValue : Latch register value          |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: No counter module found                            |
+|                     -3: Counter not initialised see function               |
+|                         "i_APCI1710_InitCounter"                           |
+|                     -4: The selected latch register parameter is wrong     |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_ReadLatchRegisterValue(struct comedi_device * dev,
+	BYTE b_ModulNbr, BYTE b_LatchReg, PULONG pul_LatchValue)
+{
+	INT i_ReturnValue = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+	      /*************************************/
+			/* Test the latch register parameter */
+	      /*************************************/
+
+			if (b_LatchReg < 2) {
+				*pul_LatchValue = inl(devpriv->s_BoardInfos.
+					ui_Address + ((b_LatchReg + 1) * 4) +
+					(64 * b_ModulNbr));
+
+			} else {
+		 /**************************************************/
+				/* The selected latch register parameter is wrong */
+		 /**************************************************/
+
+				DPRINTK("The selected latch register parameter is wrong\n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_Read16BitCounterValue                 |
+|                                       (BYTE_     b_BoardHandle,            |
+|                                        BYTE_     b_ModulNbr,               |
+|                                        BYTE_     b_SelectedCounter,        |
+|                                        PUINT_   pui_CounterValue)          |
++----------------------------------------------------------------------------+
+| Task              : Latch the selected 16-Bit counter (b_SelectedCounter)  |
+|                     from selected module (b_ModulNbr) in to the first      |
+|                     latch register and return the latched value.           |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle     : Handle of board APCI-1710    |
+|                     BYTE_ b_ModulNbr        : Module number to configure   |
+|                                              (0 to 3)                      |
+|                     BYTE_ b_SelectedCounter : Selected 16-Bit counter      |
+|                                               (0 or 1)                     |
++----------------------------------------------------------------------------+
+| Output Parameters : PUINT_ pui_CounterValue : 16-Bit counter value         |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: No counter module found                            |
+|                     -3: Counter not initialised see function               |
+|                         "i_APCI1710_InitCounter"                           |
+|                     -4: The selected 16-Bit counter parameter is wrong     |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_Read16BitCounterValue(struct comedi_device * dev,
+	BYTE b_ModulNbr, BYTE b_SelectedCounter, PUINT pui_CounterValue)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_LathchValue = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+	      /******************************/
+			/* Test the counter selection */
+	      /******************************/
+
+			if (b_SelectedCounter < 2) {
+		 /*********************/
+				/* Latch the counter */
+		 /*********************/
+
+				outl(1, devpriv->s_BoardInfos.
+					ui_Address + (64 * b_ModulNbr));
+
+		 /************************/
+				/* Read the latch value */
+		 /************************/
+
+				dw_LathchValue = inl(devpriv->s_BoardInfos.
+					ui_Address + 4 + (64 * b_ModulNbr));
+
+				*pui_CounterValue =
+					(UINT) ((dw_LathchValue >> (16 *
+							b_SelectedCounter)) &
+					0xFFFFU);
+			} else {
+		 /**************************************************/
+				/* The selected 16-Bit counter parameter is wrong */
+		 /**************************************************/
+
+				DPRINTK("The selected 16-Bit counter parameter is wrong\n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_Read32BitCounterValue                 |
+|                                       (BYTE_     b_BoardHandle,            |
+|                                        BYTE_     b_ModulNbr,               |
+|                                        PULONG_ pul_CounterValue)           |
++----------------------------------------------------------------------------+
+| Task              : Latch the 32-Bit counter from selected module          |
+|                     (b_ModulNbr) in to the first latch register and return |
+|                     the latched value.                                     |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle     : Handle of board APCI-1710    |
+|                     BYTE_ b_ModulNbr        : Module number to configure   |
+|                                              (0 to 3)                      |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_  pul_CounterValue : 32-Bit counter value       |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: No counter module found                            |
+|                     -3: Counter not initialised see function               |
+|                         "i_APCI1710_InitCounter"                           |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_Read32BitCounterValue(struct comedi_device * dev,
+	BYTE b_ModulNbr, PULONG pul_CounterValue)
+{
+	INT i_ReturnValue = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+	      /*********************/
+			/* Tatch the counter */
+	      /*********************/
+
+			outl(1, devpriv->s_BoardInfos.
+				ui_Address + (64 * b_ModulNbr));
+
+	      /************************/
+			/* Read the latch value */
+	      /************************/
+
+			*pul_CounterValue = inl(devpriv->s_BoardInfos.
+				ui_Address + 4 + (64 * b_ModulNbr));
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_GetIndexStatus (BYTE_   b_BoardHandle,|
+|                                                      BYTE_   b_ModulNbr,   |
+|                                                      PBYTE_ pb_IndexStatus)|
++----------------------------------------------------------------------------+
+| Task              : Return the index status                                |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle     : Handle of board APCI-1710    |
+|                     BYTE_ b_ModulNbr        : Module number to configure   |
+|                                               (0 to 3)                     |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_IndexStatus   : 0 : No INDEX occur           |
+|                                               1 : A INDEX occur            |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: No counter module found                            |
+|                     -3: Counter not initialised see function               |
+|                         "i_APCI1710_InitCounter"                           |
+|                     -4: Index not initialised see function                 |
+|                         "i_APCI1710_InitIndex"                             |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetIndexStatus(struct comedi_device * dev,
+	BYTE b_ModulNbr, PBYTE pb_IndexStatus)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_StatusReg = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+	      /*****************************/
+			/* Test if index initialised */
+	      /*****************************/
+
+			if (devpriv->
+				s_ModuleInfo[b_ModulNbr].
+				s_SiemensCounterInfo.s_InitFlag.b_IndexInit) {
+				dw_StatusReg = inl(devpriv->s_BoardInfos.
+					ui_Address + 12 + (64 * b_ModulNbr));
+
+				*pb_IndexStatus = (BYTE) (dw_StatusReg & 1);
+			} else {
+		 /*************************************************************/
+				/* Index not initialised see function "i_APCI1710_InitIndex" */
+		 /*************************************************************/
+
+				DPRINTK("Index not initialised\n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_GetReferenceStatus                    |
+|                                                (BYTE_   b_BoardHandle,     |
+|                                                 BYTE_   b_ModulNbr,        |
+|                                                 PBYTE_ pb_ReferenceStatus) |
++----------------------------------------------------------------------------+
+| Task              : Return the reference status                            |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle     : Handle of board APCI-1710    |
+|                     BYTE_ b_ModulNbr        : Module number to configure   |
+|                                               (0 to 3)                     |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_ReferenceStatus   : 0 : No REFERENCE occur   |
+|                                                   1 : A REFERENCE occur    |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: No counter module found                            |
+|                     -3: Counter not initialised see function               |
+|                         "i_APCI1710_InitCounter"                           |
+|                     -4: Reference not initialised see function             |
+|                         "i_APCI1710_InitReference"                         |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetReferenceStatus(struct comedi_device * dev,
+	BYTE b_ModulNbr, PBYTE pb_ReferenceStatus)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_StatusReg = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+	      /*********************************/
+			/* Test if reference initialised */
+	      /*********************************/
+
+			if (devpriv->
+				s_ModuleInfo[b_ModulNbr].
+				s_SiemensCounterInfo.
+				s_InitFlag.b_ReferenceInit) {
+				dw_StatusReg = inl(devpriv->s_BoardInfos.
+					ui_Address + 24 + (64 * b_ModulNbr));
+
+				*pb_ReferenceStatus =
+					(BYTE) (~dw_StatusReg & 1);
+			} else {
+		 /*********************************************************************/
+				/* Reference not initialised see function "i_APCI1710_InitReference" */
+		 /*********************************************************************/
+
+				DPRINTK("Reference not initialised\n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_GetUASStatus                          |
+|                               (BYTE_   b_BoardHandle,                      |
+|                                BYTE_   b_ModulNbr,                         |
+|                                PBYTE_ pb_UASStatus)                        |
++----------------------------------------------------------------------------+
+| Task              : Return the error signal (UAS) status                   |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle     : Handle of board APCI-1710    |
+|                     BYTE_ b_ModulNbr        : Module number to configure   |
+|                                               (0 to 3)                     |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_UASStatus      : 0 : UAS is low "0"          |
+|                                                1 : UAS is high "1"         |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: No counter module found                            |
+|                     -3: Counter not initialised see function               |
+|                         "i_APCI1710_InitCounter"                           |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetUASStatus(struct comedi_device * dev,
+	BYTE b_ModulNbr, PBYTE pb_UASStatus)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_StatusReg = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+			dw_StatusReg = inl(devpriv->s_BoardInfos.
+				ui_Address + 24 + (64 * b_ModulNbr));
+
+			*pb_UASStatus = (BYTE) ((dw_StatusReg >> 1) & 1);
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_GetCBStatus                           |
+|                               (BYTE_   b_BoardHandle,                      |
+|                                BYTE_   b_ModulNbr,                         |
+|                                PBYTE_ pb_CBStatus)                         |
++----------------------------------------------------------------------------+
+| Task              : Return the counter overflow status                     |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle     : Handle of board APCI-1710    |
+|                     BYTE_ b_ModulNbr        : Module number to configure   |
+|                                               (0 to 3)                     |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_CBStatus      : 0 : Counter no overflow      |
+|                                               1 : Counter overflow         |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: No counter module found                            |
+|                     -3: Counter not initialised see function               |
+|                         "i_APCI1710_InitCounter"                           |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetCBStatus(struct comedi_device * dev,
+	BYTE b_ModulNbr, PBYTE pb_CBStatus)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_StatusReg = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+			dw_StatusReg = inl(devpriv->s_BoardInfos.
+				ui_Address + 16 + (64 * b_ModulNbr));
+
+			*pb_CBStatus = (BYTE) (dw_StatusReg & 1);
+
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_Get16BitCBStatus                      |
+|					(BYTE_     b_BoardHandle,            |
+|					 BYTE_     b_ModulNbr,               |
+|					 PBYTE_ pb_CBStatusCounter0,         |
+|					 PBYTE_ pb_CBStatusCounter1)         |
++----------------------------------------------------------------------------+
+| Task              : Returns the counter overflow (counter initialised to   |
+|		      2*16-bit) status from selected incremental counter     |
+|		      module                                                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle     : Handle of board APCI-1710    |
+|                     BYTE_ b_ModulNbr        : Module number to configure   |
+|                                               (0 to 3)                     |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_CBStatusCounter0 : 0 : No overflow occur for |
+|						       the first 16-bit      |
+|						       counter               |
+|						   1 : Overflow occur for the|
+|						       first 16-bit counter  |
+|		      PBYTE_ pb_CBStatusCounter1 : 0 : No overflow occur for |
+|						       the second 16-bit     |
+|						       counter               |
+|						   1 : Overflow occur for the|
+|						       second 16-bit counter |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: No counter module found                            |
+|                     -3: Counter not initialised see function               |
+|                         "i_APCI1710_InitCounter"                           |
+|                     -4: Counter not initialised to 2*16-bit mode.          |
+|			  See function "i_APCI1710_InitCounter"              |
+|                     -5: Firmware revision error                            |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_Get16BitCBStatus(struct comedi_device * dev,
+	BYTE b_ModulNbr, PBYTE pb_CBStatusCounter0, PBYTE pb_CBStatusCounter1)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_StatusReg = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+	      /*************************/
+			/* Test if 2*16-Bit mode */
+	      /*************************/
+
+			if ((devpriv->s_ModuleInfo[b_ModulNbr].
+					s_SiemensCounterInfo.
+					s_ModeRegister.
+					s_ByteModeRegister.
+					b_ModeRegister1 & 0x10) == 0x10) {
+		 /*****************************/
+				/* Test the Firmware version */
+		 /*****************************/
+
+				if ((devpriv->s_BoardInfos.
+						dw_MolduleConfiguration
+						[b_ModulNbr] & 0xFFFF) >=
+					0x3136) {
+					dw_StatusReg =
+						inl(devpriv->s_BoardInfos.
+						ui_Address + 16 +
+						(64 * b_ModulNbr));
+
+					*pb_CBStatusCounter1 =
+						(BYTE) ((dw_StatusReg >> 0) &
+						1);
+					*pb_CBStatusCounter0 =
+						(BYTE) ((dw_StatusReg >> 1) &
+						1);
+				}	// if ((ps_APCI1710Variable->s_Board [b_BoardHandle].s_BoardInfos.dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) >= 0x3136)
+				else {
+		    /****************************/
+					/* Firmware revision error  */
+		    /****************************/
+
+					i_ReturnValue = -5;
+				}	// if ((ps_APCI1710Variable->s_Board [b_BoardHandle].s_BoardInfos.dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) >= 0x3136)
+			}	// if ((ps_APCI1710Variable->s_Board [b_BoardHandle].s_ModuleInfo [b_ModulNbr].s_SiemensCounterInfo.s_ModeRegister.s_ByteModeRegister.b_ModeRegister1 & 0x10) == 0x10)
+			else {
+		 /********************************************/
+				/* Counter not initialised to 2*16-bit mode */
+				/* "i_APCI1710_InitCounter"                 */
+		 /********************************************/
+
+				DPRINTK("Counter not initialised\n");
+				i_ReturnValue = -4;
+			}	// if ((ps_APCI1710Variable->s_Board [b_BoardHandle].s_ModuleInfo [b_ModulNbr].s_SiemensCounterInfo.s_ModeRegister.s_ByteModeRegister.b_ModeRegister1 & 0x10) == 0x10)
+		}		// if (ps_APCI1710Variable->s_Board [b_BoardHandle].s_ModuleInfo [b_ModulNbr].s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1)
+		else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}		// if (ps_APCI1710Variable->s_Board [b_BoardHandle].s_ModuleInfo [b_ModulNbr].s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1)
+	}			// if (b_ModulNbr < 4)
+	else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}			// if (b_ModulNbr < 4)
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_GetUDStatus                           |
+|                               (BYTE_   b_BoardHandle,                      |
+|                                BYTE_   b_ModulNbr,                         |
+|                                PBYTE_ pb_UDStatus)                         |
++----------------------------------------------------------------------------+
+| Task              : Return the counter progress status                     |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle     : Handle of board APCI-1710    |
+|                     BYTE_ b_ModulNbr        : Module number to configure   |
+|                                               (0 to 3)                     |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_UDStatus      : 0 : Counter progress in the  |
+|                                                   selected mode down       |
+|                                               1 : Counter progress in the  |
+|                                                   selected mode up         |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: No counter module found                            |
+|                     -3: Counter not initialised see function               |
+|                         "i_APCI1710_InitCounter"                           |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetUDStatus(struct comedi_device * dev,
+	BYTE b_ModulNbr, PBYTE pb_UDStatus)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_StatusReg = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+			dw_StatusReg = inl(devpriv->s_BoardInfos.
+				ui_Address + 24 + (64 * b_ModulNbr));
+
+			*pb_UDStatus = (BYTE) ((dw_StatusReg >> 2) & 1);
+
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_GetInterruptUDLatchedStatus           |
+|                               (BYTE_   b_BoardHandle,                      |
+|                                BYTE_   b_ModulNbr,                         |
+|                                PBYTE_ pb_UDStatus)                         |
++----------------------------------------------------------------------------+
+| Task              : Return the counter progress latched status after a     |
+|                     index interrupt occur.                                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle     : Handle of board APCI-1710    |
+|                     BYTE_ b_ModulNbr        : Module number to configure   |
+|                                               (0 to 3)                     |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_UDStatus      : 0 : Counter progress in the  |
+|                                                   selected mode down       |
+|                                               1 : Counter progress in the  |
+|                                                   selected mode up         |
+|                                               2 : No index interrupt occur |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: No counter module found                            |
+|                     -3: Counter not initialised see function               |
+|                         "i_APCI1710_InitCounter"                           |
+|                     -4: Interrupt function not initialised.                |
+|                         See function "i_APCI1710_SetBoardIntRoutineX"      |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetInterruptUDLatchedStatus(struct comedi_device * dev,
+	BYTE b_ModulNbr, PBYTE pb_UDStatus)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_StatusReg = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+		 /*********************************/
+			/* Test if index interrupt occur */
+		 /*********************************/
+
+			if (devpriv->
+				s_ModuleInfo[b_ModulNbr].
+				s_SiemensCounterInfo.
+				s_InitFlag.b_IndexInterruptOccur == 1) {
+				devpriv->
+					s_ModuleInfo[b_ModulNbr].
+					s_SiemensCounterInfo.
+					s_InitFlag.b_IndexInterruptOccur = 0;
+
+				dw_StatusReg = inl(devpriv->s_BoardInfos.
+					ui_Address + 12 + (64 * b_ModulNbr));
+
+				*pb_UDStatus = (BYTE) ((dw_StatusReg >> 1) & 1);
+			} else {
+		    /****************************/
+				/* No index interrupt occur */
+		    /****************************/
+
+				*pb_UDStatus = 2;
+			}
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+	/*
+	   +----------------------------------------------------------------------------+
+	   | Function Name     : _INT_ i_APCI1710_ReadFrequencyMeasurement              |
+	   |                            (BYTE_            b_BoardHandle,             |
+	   |                             BYTE_            b_ModulNbr,                |
+	   |                             PBYTE_          pb_Status,                  |
+	   |                             PULONG_        pul_ReadValue)               |
+	   +----------------------------------------------------------------------------+
+	   | Task              : Returns the status (pb_Status) and the number of       |
+	   |                  increments in the set time.                            |
+	   |                  See function " i_APCI1710_InitFrequencyMeasurement "   |
+	   +----------------------------------------------------------------------------+
+	   | Input Parameters  : BYTE_  b_BoardHandle    : Handle of board APCI-1710    |
+	   |                  BYTE_  b_ModulNbr       : Number of the module to be   |
+	   |                                            configured (0 to 3)          |
+	   +----------------------------------------------------------------------------+
+	   | Output Parameters : PBYTE_ pb_Status     : Returns the frequency        |
+	   |                                            measurement status           |
+	   |                                            0 : Counting cycle not       |
+	   |                                                started.                 |
+	   |                                            1 : Counting cycle started.  |
+	   |                                            2 : Counting cycle stopped.  |
+	   |                                                The measurement cycle is |
+	   |                                                completed.               |
+	   |                  PBYTE_ pb_UDStatus      : 0 : Counter progress in the  |
+	   |                                                   selected mode down       |
+	   |                                               1 : Counter progress in the  |
+	   |                                                   selected mode up         |
+	   |                  PULONG_ pul_ReadValue   : Return the number of         |
+	   |                                            increments in the defined    |
+	   |                                            time base.                   |
+	   +----------------------------------------------------------------------------+
+	   | Return Value      :  0: No error                                           |
+	   |                     -1: The handle parameter of the board is wrong         |
+	   |                     -2: The selected module number is wrong                |
+	   |                     -3: Counter not initialised see function               |
+	   |                      "i_APCI1710_InitCounter"                           |
+	   |                     -4: Frequency measurement logic not initialised.       |
+	   |                      See function "i_APCI1710_InitFrequencyMeasurement" |
+	   +----------------------------------------------------------------------------+
+	 */
+
+INT i_APCI1710_ReadFrequencyMeasurement(struct comedi_device * dev,
+	BYTE b_ModulNbr,
+	PBYTE pb_Status, PBYTE pb_UDStatus, PULONG pul_ReadValue)
+{
+	INT i_ReturnValue = 0;
+	UINT ui_16BitValue;
+	DWORD dw_StatusReg;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /*******************************/
+		/* Test if counter initialised */
+	   /*******************************/
+
+		if (devpriv->
+			s_ModuleInfo[b_ModulNbr].
+			s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+	      /********************************************/
+			/* Test if frequency mesurement initialised */
+	      /********************************************/
+
+			if (devpriv->
+				s_ModuleInfo[b_ModulNbr].
+				s_SiemensCounterInfo.
+				s_InitFlag.b_FrequencyMeasurementInit == 1) {
+		 /******************/
+				/* Test if enable */
+		 /******************/
+
+				if (devpriv->
+					s_ModuleInfo[b_ModulNbr].
+					s_SiemensCounterInfo.
+					s_InitFlag.
+					b_FrequencyMeasurementEnable == 1) {
+		    /*******************/
+					/* Read the status */
+		    /*******************/
+
+					dw_StatusReg =
+						inl(devpriv->s_BoardInfos.
+						ui_Address + 32 +
+						(64 * b_ModulNbr));
+
+		    /**************************/
+					/* Test if frequency stop */
+		    /**************************/
+
+					if (dw_StatusReg & 1) {
+						*pb_Status = 2;
+						*pb_UDStatus =
+							(BYTE) ((dw_StatusReg >>
+								1) & 3);
+
+		       /******************/
+						/* Read the value */
+		       /******************/
+
+						*pul_ReadValue =
+							inl(devpriv->
+							s_BoardInfos.
+							ui_Address + 28 +
+							(64 * b_ModulNbr));
+
+						if (*pb_UDStatus == 0) {
+			  /*************************/
+							/* Test the counter mode */
+			  /*************************/
+
+							if ((devpriv->s_ModuleInfo[b_ModulNbr].s_SiemensCounterInfo.s_ModeRegister.s_ByteModeRegister.b_ModeRegister1 & APCI1710_16BIT_COUNTER) == APCI1710_16BIT_COUNTER) {
+			     /****************************************/
+								/* Test if 16-bit counter 1 pulse occur */
+			     /****************************************/
+
+								if ((*pul_ReadValue & 0xFFFFU) != 0) {
+									ui_16BitValue
+										=
+										(UINT)
+										*
+										pul_ReadValue
+										&
+										0xFFFFU;
+									*pul_ReadValue
+										=
+										(*pul_ReadValue
+										&
+										0xFFFF0000UL)
+										|
+										(0xFFFFU
+										-
+										ui_16BitValue);
+								}
+
+			     /****************************************/
+								/* Test if 16-bit counter 2 pulse occur */
+			     /****************************************/
+
+								if ((*pul_ReadValue & 0xFFFF0000UL) != 0) {
+									ui_16BitValue
+										=
+										(UINT)
+										(
+										(*pul_ReadValue
+											>>
+											16)
+										&
+										0xFFFFU);
+									*pul_ReadValue
+										=
+										(*pul_ReadValue
+										&
+										0xFFFFUL)
+										|
+										(
+										(0xFFFFU - ui_16BitValue) << 16);
+								}
+							} else {
+								if (*pul_ReadValue != 0) {
+									*pul_ReadValue
+										=
+										0xFFFFFFFFUL
+										-
+										*pul_ReadValue;
+								}
+							}
+						} else {
+							if (*pb_UDStatus == 1) {
+			     /****************************************/
+								/* Test if 16-bit counter 2 pulse occur */
+			     /****************************************/
+
+								if ((*pul_ReadValue & 0xFFFF0000UL) != 0) {
+									ui_16BitValue
+										=
+										(UINT)
+										(
+										(*pul_ReadValue
+											>>
+											16)
+										&
+										0xFFFFU);
+									*pul_ReadValue
+										=
+										(*pul_ReadValue
+										&
+										0xFFFFUL)
+										|
+										(
+										(0xFFFFU - ui_16BitValue) << 16);
+								}
+							} else {
+								if (*pb_UDStatus
+									== 2) {
+				/****************************************/
+									/* Test if 16-bit counter 1 pulse occur */
+				/****************************************/
+
+									if ((*pul_ReadValue & 0xFFFFU) != 0) {
+										ui_16BitValue
+											=
+											(UINT)
+											*
+											pul_ReadValue
+											&
+											0xFFFFU;
+										*pul_ReadValue
+											=
+											(*pul_ReadValue
+											&
+											0xFFFF0000UL)
+											|
+											(0xFFFFU
+											-
+											ui_16BitValue);
+									}
+								}
+							}
+						}
+					} else {
+						*pb_Status = 1;
+						*pb_UDStatus = 0;
+					}
+				} else {
+					*pb_Status = 0;
+					*pb_UDStatus = 0;
+				}
+			} else {
+		 /***********************************************/
+				/* Frequency measurement logic not initialised */
+		 /***********************************************/
+
+				DPRINTK("Frequency measurement logic not initialised\n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /****************************************/
+			/* Counter not initialised see function */
+			/* "i_APCI1710_InitCounter"             */
+	      /****************************************/
+
+			DPRINTK("Counter not initialised\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*************************************************/
+		/* The selected module number parameter is wrong */
+	   /*************************************************/
+
+		DPRINTK("The selected module number parameter is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h
new file mode 100644
index 0000000..5153cf6
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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.
+ */
+
+#define APCI1710_16BIT_COUNTER			0x10
+#define APCI1710_32BIT_COUNTER			0x0
+#define APCI1710_QUADRUPLE_MODE			0x0
+#define APCI1710_DOUBLE_MODE			0x3
+#define APCI1710_SIMPLE_MODE			0xF
+#define APCI1710_DIRECT_MODE			0x80
+#define APCI1710_HYSTERESIS_ON			0x60
+#define APCI1710_HYSTERESIS_OFF			0x0
+#define APCI1710_INCREMENT			0x60
+#define APCI1710_DECREMENT			0x0
+#define APCI1710_LATCH_COUNTER			0x1
+#define APCI1710_CLEAR_COUNTER			0x0
+#define APCI1710_LOW				0x0
+#define APCI1710_HIGH				0x1
+
+/*********************/
+/* Version 0600-0229 */
+/*********************/
+#define APCI1710_HIGH_EDGE_CLEAR_COUNTER		0x0
+#define APCI1710_HIGH_EDGE_LATCH_COUNTER		0x1
+#define APCI1710_LOW_EDGE_CLEAR_COUNTER			0x2
+#define APCI1710_LOW_EDGE_LATCH_COUNTER			0x3
+#define APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER	0x4
+#define APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER	0x5
+#define APCI1710_SOURCE_0				0x0
+#define APCI1710_SOURCE_1				0x1
+
+#define APCI1710_30MHZ				30
+#define APCI1710_33MHZ				33
+#define APCI1710_40MHZ				40
+
+#define APCI1710_ENABLE_LATCH_INT    		0x80
+#define APCI1710_DISABLE_LATCH_INT   		(~APCI1710_ENABLE_LATCH_INT)
+
+#define APCI1710_INDEX_LATCH_COUNTER		0x10
+#define APCI1710_INDEX_AUTO_MODE		0x8
+#define APCI1710_ENABLE_INDEX			0x4
+#define APCI1710_DISABLE_INDEX			(~APCI1710_ENABLE_INDEX)
+#define APCI1710_ENABLE_LATCH_AND_CLEAR		0x8
+#define APCI1710_DISABLE_LATCH_AND_CLEAR	(~APCI1710_ENABLE_LATCH_AND_CLEAR)
+#define APCI1710_SET_LOW_INDEX_LEVEL		0x4
+#define APCI1710_SET_HIGH_INDEX_LEVEL		(~APCI1710_SET_LOW_INDEX_LEVEL)
+#define APCI1710_INVERT_INDEX_RFERENCE		0x2
+#define APCI1710_DEFAULT_INDEX_RFERENCE         (~APCI1710_INVERT_INDEX_RFERENCE)
+
+#define APCI1710_ENABLE_INDEX_INT		0x1
+#define APCI1710_DISABLE_INDEX_INT		(~APCI1710_ENABLE_INDEX_INT)
+
+#define APCI1710_ENABLE_FREQUENCY		0x4
+#define APCI1710_DISABLE_FREQUENCY		(~APCI1710_ENABLE_FREQUENCY)
+
+#define APCI1710_ENABLE_FREQUENCY_INT		0x8
+#define APCI1710_DISABLE_FREQUENCY_INT		(~APCI1710_ENABLE_FREQUENCY_INT)
+
+#define APCI1710_ENABLE_40MHZ_FREQUENCY		0x40
+#define APCI1710_DISABLE_40MHZ_FREQUENCY	(~APCI1710_ENABLE_40MHZ_FREQUENCY)
+
+#define APCI1710_ENABLE_40MHZ_FILTER		0x80
+#define APCI1710_DISABLE_40MHZ_FILTER		(~APCI1710_ENABLE_40MHZ_FILTER)
+
+#define APCI1710_ENABLE_COMPARE_INT		0x2
+#define APCI1710_DISABLE_COMPARE_INT		(~APCI1710_ENABLE_COMPARE_INT)
+
+#define APCI1710_ENABLE_INDEX_ACTION		0x20
+#define APCI1710_DISABLE_INDEX_ACTION		(~APCI1710_ENABLE_INDEX_ACTION)
+#define APCI1710_REFERENCE_HIGH			0x40
+#define APCI1710_REFERENCE_LOW			(~APCI1710_REFERENCE_HIGH)
+
+#define APCI1710_TOR_GATE_LOW			0x40
+#define APCI1710_TOR_GATE_HIGH			(~APCI1710_TOR_GATE_LOW)
+
+/* INSN CONFIG */
+#define	APCI1710_INCCPT_INITCOUNTER				100
+#define APCI1710_INCCPT_COUNTERAUTOTEST				101
+#define APCI1710_INCCPT_INITINDEX				102
+#define APCI1710_INCCPT_INITREFERENCE				103
+#define APCI1710_INCCPT_INITEXTERNALSTROBE			104
+#define APCI1710_INCCPT_INITCOMPARELOGIC			105
+#define APCI1710_INCCPT_INITFREQUENCYMEASUREMENT		106
+
+/* INSN READ */
+#define APCI1710_INCCPT_READLATCHREGISTERSTATUS			200
+#define APCI1710_INCCPT_READLATCHREGISTERVALUE			201
+#define APCI1710_INCCPT_READ16BITCOUNTERVALUE			202
+#define APCI1710_INCCPT_READ32BITCOUNTERVALUE			203
+#define APCI1710_INCCPT_GETINDEXSTATUS				204
+#define APCI1710_INCCPT_GETREFERENCESTATUS			205
+#define APCI1710_INCCPT_GETUASSTATUS				206
+#define APCI1710_INCCPT_GETCBSTATUS				207
+#define APCI1710_INCCPT_GET16BITCBSTATUS			208
+#define APCI1710_INCCPT_GETUDSTATUS				209
+#define APCI1710_INCCPT_GETINTERRUPTUDLATCHEDSTATUS		210
+#define APCI1710_INCCPT_READFREQUENCYMEASUREMENT		211
+#define APCI1710_INCCPT_READINTERRUPT				212
+
+/* INSN BITS */
+#define APCI1710_INCCPT_CLEARCOUNTERVALUE			300
+#define APCI1710_INCCPT_CLEARALLCOUNTERVALUE			301
+#define APCI1710_INCCPT_SETINPUTFILTER				302
+#define APCI1710_INCCPT_LATCHCOUNTER				303
+#define APCI1710_INCCPT_SETINDEXANDREFERENCESOURCE		304
+#define APCI1710_INCCPT_SETDIGITALCHLON				305
+#define APCI1710_INCCPT_SETDIGITALCHLOFF			306
+
+/* INSN WRITE */
+#define APCI1710_INCCPT_ENABLELATCHINTERRUPT			400
+#define APCI1710_INCCPT_DISABLELATCHINTERRUPT			401
+#define APCI1710_INCCPT_WRITE16BITCOUNTERVALUE			402
+#define APCI1710_INCCPT_WRITE32BITCOUNTERVALUE			403
+#define APCI1710_INCCPT_ENABLEINDEX				404
+#define APCI1710_INCCPT_DISABLEINDEX				405
+#define APCI1710_INCCPT_ENABLECOMPARELOGIC			406
+#define APCI1710_INCCPT_DISABLECOMPARELOGIC			407
+#define APCI1710_INCCPT_ENABLEFREQUENCYMEASUREMENT		408
+#define APCI1710_INCCPT_DISABLEFREQUENCYMEASUREMENT		409
+
+/************ Main Functions *************/
+INT i_APCI1710_InsnConfigINCCPT(struct comedi_device *dev, struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int * data);
+
+INT i_APCI1710_InsnBitsINCCPT(struct comedi_device *dev, struct comedi_subdevice * s,
+			      struct comedi_insn *insn, unsigned int * data);
+
+INT i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev, struct comedi_subdevice * s,
+			       struct comedi_insn *insn, unsigned int * data);
+
+INT i_APCI1710_InsnReadINCCPT(struct comedi_device *dev, struct comedi_subdevice * s,
+			      struct comedi_insn *insn, unsigned int * data);
+
+/*********** Supplementary Functions********/
+
+/* INSN CONFIG */
+INT i_APCI1710_InitCounter(struct comedi_device *dev,
+			   BYTE b_ModulNbr,
+			   BYTE b_CounterRange,
+			   BYTE b_FirstCounterModus,
+			   BYTE b_FirstCounterOption,
+			   BYTE b_SecondCounterModus,
+			   BYTE b_SecondCounterOption);
+
+INT i_APCI1710_CounterAutoTest(struct comedi_device *dev, PBYTE pb_TestStatus);
+
+INT i_APCI1710_InitIndex(struct comedi_device *dev,
+			 BYTE b_ModulNbr,
+			 BYTE b_ReferenceAction,
+			 BYTE b_IndexOperation, BYTE b_AutoMode,
+			 BYTE b_InterruptEnable);
+
+INT i_APCI1710_InitReference(struct comedi_device *dev,
+			     BYTE b_ModulNbr, BYTE b_ReferenceLevel);
+
+INT i_APCI1710_InitExternalStrobe(struct comedi_device *dev,
+				  BYTE b_ModulNbr, BYTE b_ExternalStrobe,
+				  BYTE b_ExternalStrobeLevel);
+
+INT i_APCI1710_InitCompareLogic(struct comedi_device *dev,
+				BYTE b_ModulNbr, UINT ui_CompareValue);
+
+INT i_APCI1710_InitFrequencyMeasurement(struct comedi_device *dev,
+					BYTE b_ModulNbr,
+					BYTE b_PCIInputClock,
+					BYTE b_TimingUnity,
+					ULONG ul_TimingInterval,
+					PULONG pul_RealTimingInterval);
+
+/* INSN BITS */
+INT i_APCI1710_ClearCounterValue(struct comedi_device *dev, BYTE b_ModulNbr);
+
+INT i_APCI1710_ClearAllCounterValue(struct comedi_device *dev);
+
+INT i_APCI1710_SetInputFilter(struct comedi_device *dev,
+			      BYTE b_ModulNbr, BYTE b_PCIInputClock,
+			      BYTE b_Filter);
+
+INT i_APCI1710_LatchCounter(struct comedi_device *dev,
+			    BYTE b_ModulNbr, BYTE b_LatchReg);
+
+INT i_APCI1710_SetIndexAndReferenceSource(struct comedi_device *dev,
+					  BYTE b_ModulNbr,
+					  BYTE b_SourceSelection);
+
+INT i_APCI1710_SetDigitalChlOn(struct comedi_device *dev, BYTE b_ModulNbr);
+
+INT i_APCI1710_SetDigitalChlOff(struct comedi_device *dev, BYTE b_ModulNbr);
+
+/* INSN WRITE */
+INT i_APCI1710_EnableLatchInterrupt(struct comedi_device *dev, BYTE b_ModulNbr);
+
+INT i_APCI1710_DisableLatchInterrupt(struct comedi_device *dev, BYTE b_ModulNbr);
+
+INT i_APCI1710_Write16BitCounterValue(struct comedi_device *dev,
+				      BYTE b_ModulNbr, BYTE b_SelectedCounter,
+				      UINT ui_WriteValue);
+
+INT i_APCI1710_Write32BitCounterValue(struct comedi_device *dev,
+				      BYTE b_ModulNbr, ULONG ul_WriteValue);
+
+INT i_APCI1710_EnableIndex(struct comedi_device *dev, BYTE b_ModulNbr);
+
+INT i_APCI1710_DisableIndex(struct comedi_device *dev, BYTE b_ModulNbr);
+
+INT i_APCI1710_EnableCompareLogic(struct comedi_device *dev, BYTE b_ModulNbr);
+
+INT i_APCI1710_DisableCompareLogic(struct comedi_device *dev, BYTE b_ModulNbr);
+
+INT i_APCI1710_EnableFrequencyMeasurement(struct comedi_device *dev,
+					  BYTE b_ModulNbr,
+					  BYTE b_InterruptEnable);
+
+INT i_APCI1710_DisableFrequencyMeasurement(struct comedi_device *dev,
+					   BYTE b_ModulNbr);
+
+/* INSN READ */
+INT i_APCI1710_ReadLatchRegisterStatus(struct comedi_device *dev,
+				       BYTE b_ModulNbr, BYTE b_LatchReg,
+				       PBYTE pb_LatchStatus);
+
+INT i_APCI1710_ReadLatchRegisterValue(struct comedi_device *dev,
+				      BYTE b_ModulNbr, BYTE b_LatchReg,
+				      PULONG pul_LatchValue);
+
+INT i_APCI1710_Read16BitCounterValue(struct comedi_device *dev,
+				     BYTE b_ModulNbr, BYTE b_SelectedCounter,
+				     PUINT pui_CounterValue);
+
+INT i_APCI1710_Read32BitCounterValue(struct comedi_device *dev,
+				     BYTE b_ModulNbr, PULONG pul_CounterValue);
+
+INT i_APCI1710_GetIndexStatus(struct comedi_device *dev,
+			      BYTE b_ModulNbr, PBYTE pb_IndexStatus);
+
+INT i_APCI1710_GetReferenceStatus(struct comedi_device *dev,
+				  BYTE b_ModulNbr, PBYTE pb_ReferenceStatus);
+
+INT i_APCI1710_GetUASStatus(struct comedi_device *dev,
+			    BYTE b_ModulNbr, PBYTE pb_UASStatus);
+
+INT i_APCI1710_GetCBStatus(struct comedi_device *dev,
+			   BYTE b_ModulNbr, PBYTE pb_CBStatus);
+
+INT i_APCI1710_Get16BitCBStatus(struct comedi_device *dev,
+				BYTE b_ModulNbr, PBYTE pb_CBStatusCounter0,
+				PBYTE pb_CBStatusCounter1);
+
+INT i_APCI1710_GetUDStatus(struct comedi_device *dev,
+			   BYTE b_ModulNbr, PBYTE pb_UDStatus);
+
+INT i_APCI1710_GetInterruptUDLatchedStatus(struct comedi_device *dev,
+					   BYTE b_ModulNbr, PBYTE pb_UDStatus);
+
+INT i_APCI1710_ReadFrequencyMeasurement(struct comedi_device *dev,
+					BYTE b_ModulNbr,
+					PBYTE pb_Status, PBYTE pb_UDStatus,
+					PULONG pul_ReadValue);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c
new file mode 100644
index 0000000..3ac6a26
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c
@@ -0,0 +1,861 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+
+        ADDI-DATA GmbH
+        Dieselstrasse 3
+        D-77833 Ottersweier
+        Tel: +19(0)7223/9493-0
+        Fax: +49(0)7223/9493-92
+        http://www.addi-data-com
+        info@addi-data.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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+  +-----------------------------------------------------------------------+
+  | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
+  +-----------------------------------------------------------------------+
+  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
+  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
+  +-----------------------------------------------------------------------+
+  | Project     : API APCI1710    | Compiler : gcc                        |
+  | Module name : Inp_CPT.C       | Version  : 2.96                       |
+  +-------------------------------+---------------------------------------+
+  | Project manager: Eric Stolz   | Date     :  02/12/2002                |
+  +-----------------------------------------------------------------------+
+  | Description :   APCI-1710 pulse encoder module                        |
+  |                                                                       |
+  |                                                                       |
+  +-----------------------------------------------------------------------+
+  |                             UPDATES                                   |
+  +-----------------------------------------------------------------------+
+  |   Date   |   Author  |          Description of updates                |
+  +----------+-----------+------------------------------------------------+
+  |          |           |                                                |
+  |----------|-----------|------------------------------------------------|
+  | 08/05/00 | Guinot C  | - 0400/0228 All Function in RING 0             |
+  |          |           |   available                                    |
+  +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+|                               Included files                               |
++----------------------------------------------------------------------------+
+*/
+
+#include "APCI1710_Inp_cpt.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_InitPulseEncoder                      |
+|                               (BYTE_          b_BoardHandle,               |
+|                                BYTE_          b_ModulNbr,                  |
+|                                BYTE_          b_PulseEncoderNbr,           |
+|                                BYTE_          b_InputLevelSelection,       |
+|                                BYTE_          b_TriggerOutputAction,       |
+|                                ULONG_        ul_StartValue)                |
++----------------------------------------------------------------------------+
+| Task              : Configure the pulse encoder operating mode selected via|
+|                     b_ModulNbr and b_PulseEncoderNbr. The pulse encoder    |
+|                     after each pulse decrement the counter value from 1.   |
+|                                                                            |
+|                     You must calling this function be for you call any     |
+|                     other function witch access of pulse encoders.         |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle         : Handle of board APCI-1710|
+|                     BYTE_ b_ModulNbr            : Module number to         |
+|                                                   configure (0 to 3)       |
+|                     BYTE_ b_PulseEncoderNbr     : Pulse encoder selection  |
+|                                                   (0 to 3)                 |
+|                     BYTE_ b_InputLevelSelection : Input level selection    |
+|                                                   (0 or 1)                 |
+|                                                       0 : Set pulse encoder|
+|                                                           count the the low|
+|                                                           level pulse.     |
+|                                                       1 : Set pulse encoder|
+|                                                           count the the    |
+|                                                           high level pulse.|
+|                     BYTE_ b_TriggerOutputAction : Digital TRIGGER output   |
+|                                                   action                   |
+|                                                       0 : No action        |
+|                                                       1 : Set the trigger  |
+|                                                           output to "1"    |
+|                                                           (high) after the |
+|                                                           passage from 1 to|
+|                                                           0 from pulse     |
+|                                                           encoder.         |
+|                                                       2 : Set the trigger  |
+|                                                           output to "0"    |
+|                                                           (low) after the  |
+|                                                           passage from 1 to|
+|                                                           0 from pulse     |
+|                                                           encoder          |
+|                     ULONG_ ul_StartValue        : Pulse encoder start value|
+|                                                   (1 to 4294967295)
+	b_ModulNbr				=(BYTE) CR_AREF(insn->chanspec);
+	b_PulseEncoderNbr		=(BYTE) data[0];
+	b_InputLevelSelection	=(BYTE) data[1];
+	b_TriggerOutputAction	=(BYTE) data[2];
+	ul_StartValue			=(ULONG) data[3];
+       |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : 0: No error                                            |
+|                    -1: The handle parameter of the board is wrong          |
+|                    -2: The module is not a pulse encoder module            |
+|                    -3: Pulse encoder selection is wrong                    |
+|                    -4: Input level selection is wrong                      |
+|                    -5: Digital TRIGGER output action selection is wrong    |
+|                    -6: Pulse encoder start value is wrong                  |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_IntRegister;
+
+	BYTE b_ModulNbr;
+	BYTE b_PulseEncoderNbr;
+	BYTE b_InputLevelSelection;
+	BYTE b_TriggerOutputAction;
+	ULONG ul_StartValue;
+
+	b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+	b_PulseEncoderNbr = (BYTE) data[0];
+	b_InputLevelSelection = (BYTE) data[1];
+	b_TriggerOutputAction = (BYTE) data[2];
+	ul_StartValue = (ULONG) data[3];
+
+	i_ReturnValue = insn->n;
+
+	/***********************************/
+	/* Test the selected module number */
+	/***********************************/
+
+	if (b_ModulNbr <= 3) {
+	   /*************************/
+		/* Test if pulse encoder */
+	   /*************************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				APCI1710_PULSE_ENCODER) ==
+			APCI1710_PULSE_ENCODER) {
+	      /******************************************/
+			/* Test the selected pulse encoder number */
+	      /******************************************/
+
+			if (b_PulseEncoderNbr <= 3) {
+		 /************************/
+				/* Test the input level */
+		 /************************/
+
+				if ((b_InputLevelSelection == 0)
+					|| (b_InputLevelSelection == 1)) {
+		    /*******************************************/
+					/* Test the ouput TRIGGER action selection */
+		    /*******************************************/
+
+					if ((b_TriggerOutputAction <= 2)
+						|| (b_PulseEncoderNbr > 0)) {
+						if (ul_StartValue > 1) {
+
+							dw_IntRegister =
+								inl(devpriv->
+								s_BoardInfos.
+								ui_Address +
+								20 +
+								(64 * b_ModulNbr));
+
+			  /***********************/
+							/* Set the start value */
+			  /***********************/
+
+							outl(ul_StartValue,
+								devpriv->
+								s_BoardInfos.
+								ui_Address +
+								(b_PulseEncoderNbr
+									* 4) +
+								(64 * b_ModulNbr));
+
+			  /***********************/
+							/* Set the input level */
+			  /***********************/
+							devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_PulseEncoderModuleInfo.
+								dw_SetRegister =
+								(devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_PulseEncoderModuleInfo.
+								dw_SetRegister &
+								(0xFFFFFFFFUL -
+									(1UL << (8 + b_PulseEncoderNbr)))) | ((1UL & (~b_InputLevelSelection)) << (8 + b_PulseEncoderNbr));
+
+			  /*******************************/
+							/* Test if output trigger used */
+			  /*******************************/
+
+							if ((b_TriggerOutputAction > 0) && (b_PulseEncoderNbr > 1)) {
+			     /****************************/
+								/* Enable the output action */
+			     /****************************/
+
+								devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_PulseEncoderModuleInfo.
+									dw_SetRegister
+									=
+									devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_PulseEncoderModuleInfo.
+									dw_SetRegister
+									| (1UL
+									<< (4 + b_PulseEncoderNbr));
+
+			     /*********************************/
+								/* Set the output TRIGGER action */
+			     /*********************************/
+
+								devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_PulseEncoderModuleInfo.
+									dw_SetRegister
+									=
+									(devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_PulseEncoderModuleInfo.
+									dw_SetRegister
+									&
+									(0xFFFFFFFFUL
+										-
+										(1UL << (12 + b_PulseEncoderNbr)))) | ((1UL & (b_TriggerOutputAction - 1)) << (12 + b_PulseEncoderNbr));
+							} else {
+			     /*****************************/
+								/* Disable the output action */
+			     /*****************************/
+
+								devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_PulseEncoderModuleInfo.
+									dw_SetRegister
+									=
+									devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_PulseEncoderModuleInfo.
+									dw_SetRegister
+									&
+									(0xFFFFFFFFUL
+									-
+									(1UL << (4 + b_PulseEncoderNbr)));
+							}
+
+			  /*************************/
+							/* Set the configuration */
+			  /*************************/
+
+							outl(devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_PulseEncoderModuleInfo.
+								dw_SetRegister,
+								devpriv->
+								s_BoardInfos.
+								ui_Address +
+								20 +
+								(64 * b_ModulNbr));
+
+							devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_PulseEncoderModuleInfo.
+								s_PulseEncoderInfo
+								[b_PulseEncoderNbr].
+								b_PulseEncoderInit
+								= 1;
+						} else {
+			  /**************************************/
+							/* Pulse encoder start value is wrong */
+			  /**************************************/
+
+							DPRINTK("Pulse encoder start value is wrong\n");
+							i_ReturnValue = -6;
+						}
+					} else {
+		       /****************************************************/
+						/* Digital TRIGGER output action selection is wrong */
+		       /****************************************************/
+
+						DPRINTK("Digital TRIGGER output action selection is wrong\n");
+						i_ReturnValue = -5;
+					}
+				} else {
+		    /**********************************/
+					/* Input level selection is wrong */
+		    /**********************************/
+
+					DPRINTK("Input level selection is wrong\n");
+					i_ReturnValue = -4;
+				}
+			} else {
+		 /************************************/
+				/* Pulse encoder selection is wrong */
+		 /************************************/
+
+				DPRINTK("Pulse encoder selection is wrong\n");
+				i_ReturnValue = -3;
+			}
+		} else {
+	      /********************************************/
+			/* The module is not a pulse encoder module */
+	      /********************************************/
+
+			DPRINTK("The module is not a pulse encoder module\n");
+			i_ReturnValue = -2;
+		}
+	} else {
+	   /********************************************/
+		/* The module is not a pulse encoder module */
+	   /********************************************/
+
+		DPRINTK("The module is not a pulse encoder module\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_EnablePulseEncoder                    |
+|                                       (BYTE_  b_BoardHandle,               |
+|                                        BYTE_  b_ModulNbr,                  |
+|                                        BYTE_  b_PulseEncoderNbr,           |
+|                                        BYTE_  b_CycleSelection,            |
+|                                        BYTE_  b_InterruptHandling)         |
++----------------------------------------------------------------------------+
+| Task              : Enableor disable  the selected pulse encoder (b_PulseEncoderNbr)  |
+|                     from selected module (b_ModulNbr). Each input pulse    |
+|                     decrement the pulse encoder counter value from 1.      |
+|                     If you enabled the interrupt (b_InterruptHandling), a  |
+|                     interrupt is generated when the pulse encoder has run  |
+|                     down.                                                  |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_   b_BoardHandle       : Handle of board APCI-1710|
+|                     BYTE_   b_ModulNbr          : Module number to         |
+|                                                   configure (0 to 3)       |
+|                     BYTE_   b_PulseEncoderNbr   : Pulse encoder selection  |
+|                                                   (0 to 3)                 |
+|                     BYTE_   b_CycleSelection    : APCI1710_CONTINUOUS:     |
+|                                                       Each time the        |
+|                                                       counting value is set|
+|                                                       on "0", the pulse    |
+|                                                       encoder load the     |
+|                                                       start value after    |
+|                                                       the next pulse.      |
+|                                                   APCI1710_SINGLE:         |
+|                                                       If the counter is set|
+|                                                       on "0", the pulse    |
+|                                                       encoder is stopped.  |
+|                     BYTE_   b_InterruptHandling : Interrupts can be        |
+|                                                   generated, when the pulse|
+|                                                   encoder has run down.    |
+|                                                   With this parameter the  |
+|                                                   user decides if          |
+|                                                   interrupts are used or   |
+|                                                   not.                     |
+|                                                     APCI1710_ENABLE:       |
+|                                                     Interrupts are enabled |
+|                                                     APCI1710_DISABLE:      |
+|                                                     Interrupts are disabled
+
+  	b_ModulNbr			=(BYTE) CR_AREF(insn->chanspec);
+	b_Action			=(BYTE) data[0];
+	b_PulseEncoderNbr	=(BYTE) data[1];
+	b_CycleSelection	=(BYTE) data[2];
+	b_InterruptHandling	=(BYTE) data[3];|
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: Module selection is wrong                          |
+|                     -3: Pulse encoder selection is wrong                   |
+|                     -4: Pulse encoder not initialised.                     |
+|                         See function "i_APCI1710_InitPulseEncoder"         |
+|                     -5: Cycle selection mode is wrong                      |
+|                     -6: Interrupt handling mode is wrong                   |
+|                     -7: Interrupt routine not installed.                   |
+|                         See function "i_APCI1710_SetBoardIntRoutineX"      |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = 0;
+	BYTE b_ModulNbr;
+	BYTE b_PulseEncoderNbr;
+	BYTE b_CycleSelection;
+	BYTE b_InterruptHandling;
+	BYTE b_Action;
+
+	i_ReturnValue = insn->n;
+	b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+	b_Action = (BYTE) data[0];
+	b_PulseEncoderNbr = (BYTE) data[1];
+	b_CycleSelection = (BYTE) data[2];
+	b_InterruptHandling = (BYTE) data[3];
+
+	/***********************************/
+	/* Test the selected module number */
+	/***********************************/
+
+	if (b_ModulNbr <= 3) {
+	   /******************************************/
+		/* Test the selected pulse encoder number */
+	   /******************************************/
+
+		if (b_PulseEncoderNbr <= 3) {
+	      /*************************************/
+			/* Test if pulse encoder initialised */
+	      /*************************************/
+
+			if (devpriv->s_ModuleInfo[b_ModulNbr].
+				s_PulseEncoderModuleInfo.
+				s_PulseEncoderInfo[b_PulseEncoderNbr].
+				b_PulseEncoderInit == 1) {
+				switch (b_Action) {
+
+				case APCI1710_ENABLE:
+		 /****************************/
+					/* Test the cycle selection */
+		 /****************************/
+
+					if (b_CycleSelection ==
+						APCI1710_CONTINUOUS
+						|| b_CycleSelection ==
+						APCI1710_SINGLE) {
+		    /*******************************/
+						/* Test the interrupt handling */
+		    /*******************************/
+
+						if (b_InterruptHandling ==
+							APCI1710_ENABLE
+							|| b_InterruptHandling
+							== APCI1710_DISABLE) {
+		       /******************************/
+							/* Test if interrupt not used */
+		       /******************************/
+
+							if (b_InterruptHandling
+								==
+								APCI1710_DISABLE)
+							{
+			  /*************************/
+								/* Disable the interrupt */
+			  /*************************/
+
+								devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_PulseEncoderModuleInfo.
+									dw_SetRegister
+									=
+									devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_PulseEncoderModuleInfo.
+									dw_SetRegister
+									&
+									(0xFFFFFFFFUL
+									-
+									(1UL << b_PulseEncoderNbr));
+							} else {
+
+			     /************************/
+								/* Enable the interrupt */
+			     /************************/
+
+								devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_PulseEncoderModuleInfo.
+									dw_SetRegister
+									=
+									devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_PulseEncoderModuleInfo.
+									dw_SetRegister
+									| (1UL
+									<<
+									b_PulseEncoderNbr);
+								devpriv->tsk_Current = current;	// Save the current process task structure
+
+							}
+
+							if (i_ReturnValue >= 0) {
+			  /***********************************/
+								/* Enable or disable the interrupt */
+			  /***********************************/
+
+								outl(devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_PulseEncoderModuleInfo.
+									dw_SetRegister,
+									devpriv->
+									s_BoardInfos.
+									ui_Address
+									+ 20 +
+									(64 * b_ModulNbr));
+
+			  /****************************/
+								/* Enable the pulse encoder */
+			  /****************************/
+								devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_PulseEncoderModuleInfo.
+									dw_ControlRegister
+									=
+									devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_PulseEncoderModuleInfo.
+									dw_ControlRegister
+									| (1UL
+									<<
+									b_PulseEncoderNbr);
+
+			  /**********************/
+								/* Set the cycle mode */
+			  /**********************/
+
+								devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_PulseEncoderModuleInfo.
+									dw_ControlRegister
+									=
+									(devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_PulseEncoderModuleInfo.
+									dw_ControlRegister
+									&
+									(0xFFFFFFFFUL
+										-
+										(1 << (b_PulseEncoderNbr + 4)))) | ((b_CycleSelection & 1UL) << (4 + b_PulseEncoderNbr));
+
+			  /****************************/
+								/* Enable the pulse encoder */
+			  /****************************/
+
+								outl(devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_PulseEncoderModuleInfo.
+									dw_ControlRegister,
+									devpriv->
+									s_BoardInfos.
+									ui_Address
+									+ 16 +
+									(64 * b_ModulNbr));
+							}
+						} else {
+		       /************************************/
+							/* Interrupt handling mode is wrong */
+		       /************************************/
+
+							DPRINTK("Interrupt handling mode is wrong\n");
+							i_ReturnValue = -6;
+						}
+					} else {
+		    /*********************************/
+						/* Cycle selection mode is wrong */
+		    /*********************************/
+
+						DPRINTK("Cycle selection mode is wrong\n");
+						i_ReturnValue = -5;
+					}
+					break;
+
+				case APCI1710_DISABLE:
+					devpriv->s_ModuleInfo[b_ModulNbr].
+						s_PulseEncoderModuleInfo.
+						dw_ControlRegister =
+						devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_PulseEncoderModuleInfo.
+						dw_ControlRegister &
+						(0xFFFFFFFFUL -
+						(1UL << b_PulseEncoderNbr));
+
+		 /*****************************/
+					/* Disable the pulse encoder */
+		 /*****************************/
+
+					outl(devpriv->s_ModuleInfo[b_ModulNbr].
+						s_PulseEncoderModuleInfo.
+						dw_ControlRegister,
+						devpriv->s_BoardInfos.
+						ui_Address + 16 +
+						(64 * b_ModulNbr));
+
+					break;
+				}	// switch End
+
+			} else {
+		 /*********************************/
+				/* Pulse encoder not initialised */
+		 /*********************************/
+
+				DPRINTK("Pulse encoder not initialised\n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /************************************/
+			/* Pulse encoder selection is wrong */
+	      /************************************/
+
+			DPRINTK("Pulse encoder selection is wrong\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*****************************/
+		/* Module selection is wrong */
+	   /*****************************/
+
+		DPRINTK("Module selection is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_ReadPulseEncoderStatus                |
+|                                       (BYTE_  b_BoardHandle,               |
+|                                        BYTE_  b_ModulNbr,                  |
+|                                        BYTE_  b_PulseEncoderNbr,           |
+|                                        PBYTE_ pb_Status)                   |
++----------------------------------------------------------------------------+
+| Task    APCI1710_PULSEENCODER_READ          : Reads the pulse encoder status
+											and valuefrom selected pulse     |
+|                     encoder (b_PulseEncoderNbr) from selected module       |
+|                     (b_ModulNbr).                                          |
++----------------------------------------------------------------------------+
+	BYTE   b_Type; data[0]
+   APCI1710_PULSEENCODER_WRITE
+ Writes a 32-bit value (ul_WriteValue) into the selected|
+|                     pulse encoder (b_PulseEncoderNbr) from selected module |
+|                     (b_ModulNbr). This operation set the new start pulse   |
+|                     encoder value.
+ APCI1710_PULSEENCODER_READ
+| Input Parameters  : BYTE_   b_BoardHandle       : Handle of board APCI-1710|
+|            CRAREF()         BYTE_   b_ModulNbr          : Module number to         |
+|                                                   configure (0 to 3)       |
+|              data[1]       BYTE_   b_PulseEncoderNbr   : Pulse encoder selection  |
+|                                                   (0 to 3)
+   APCI1710_PULSEENCODER_WRITE
+				data[2]		ULONG_ ul_WriteValue        : 32-bit value to be       |
+|                                                   written             |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_Status            : Pulse encoder status.    |
+|                                                       0 : No overflow occur|
+|                                                       1 : Overflow occur
+						PULONG_ pul_ReadValue       : Pulse encoder value      |  |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: Module selection is wrong                          |
+|                     -3: Pulse encoder selection is wrong                   |
+|                     -4: Pulse encoder not initialised.                     |
+|                         See function "i_APCI1710_InitPulseEncoder"         |
++----------------------------------------------------------------------------+
+*/
+
+/*_INT_   i_APCI1710_ReadPulseEncoderStatus       (BYTE_   b_BoardHandle,
+						 BYTE_   b_ModulNbr,
+						 BYTE_   b_PulseEncoderNbr,
+
+   						 PBYTE_ pb_Status)
+						 */
+INT i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_StatusRegister;
+	BYTE b_ModulNbr;
+	BYTE b_PulseEncoderNbr;
+	PBYTE pb_Status;
+	BYTE b_Type;
+	PULONG pul_ReadValue;
+	ULONG ul_WriteValue;
+
+	i_ReturnValue = insn->n;
+	b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+	b_Type = (BYTE) data[0];
+	b_PulseEncoderNbr = (BYTE) data[1];
+	pb_Status = (PBYTE) & data[0];
+	pul_ReadValue = (PULONG) & data[1];
+
+	/***********************************/
+	/* Test the selected module number */
+	/***********************************/
+
+	if (b_ModulNbr <= 3) {
+	   /******************************************/
+		/* Test the selected pulse encoder number */
+	   /******************************************/
+
+		if (b_PulseEncoderNbr <= 3) {
+	      /*************************************/
+			/* Test if pulse encoder initialised */
+	      /*************************************/
+
+			if (devpriv->s_ModuleInfo[b_ModulNbr].
+				s_PulseEncoderModuleInfo.
+				s_PulseEncoderInfo[b_PulseEncoderNbr].
+				b_PulseEncoderInit == 1) {
+
+				switch (b_Type) {
+				case APCI1710_PULSEENCODER_READ:
+		 /****************************/
+					/* Read the status register */
+		 /****************************/
+
+					dw_StatusRegister =
+						inl(devpriv->s_BoardInfos.
+						ui_Address + 16 +
+						(64 * b_ModulNbr));
+
+					devpriv->s_ModuleInfo[b_ModulNbr].
+						s_PulseEncoderModuleInfo.
+						dw_StatusRegister = devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_PulseEncoderModuleInfo.
+						dw_StatusRegister |
+						dw_StatusRegister;
+
+					*pb_Status =
+						(BYTE) (devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_PulseEncoderModuleInfo.
+						dw_StatusRegister >> (1 +
+							b_PulseEncoderNbr)) & 1;
+
+					devpriv->s_ModuleInfo[b_ModulNbr].
+						s_PulseEncoderModuleInfo.
+						dw_StatusRegister =
+						devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_PulseEncoderModuleInfo.
+						dw_StatusRegister &
+						(0xFFFFFFFFUL - (1 << (1 +
+								b_PulseEncoderNbr)));
+
+		 /******************/
+					/* Read the value */
+		 /******************/
+
+					*pul_ReadValue =
+						inl(devpriv->s_BoardInfos.
+						ui_Address +
+						(4 * b_PulseEncoderNbr) +
+						(64 * b_ModulNbr));
+					break;
+
+				case APCI1710_PULSEENCODER_WRITE:
+					ul_WriteValue = (ULONG) data[2];
+			/*******************/
+					/* Write the value */
+			/*******************/
+
+					outl(ul_WriteValue,
+						devpriv->s_BoardInfos.
+						ui_Address +
+						(4 * b_PulseEncoderNbr) +
+						(64 * b_ModulNbr));
+
+				}	//end of switch
+			} else {
+		 /*********************************/
+				/* Pulse encoder not initialised */
+		 /*********************************/
+
+				DPRINTK("Pulse encoder not initialised\n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /************************************/
+			/* Pulse encoder selection is wrong */
+	      /************************************/
+
+			DPRINTK("Pulse encoder selection is wrong\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*****************************/
+		/* Module selection is wrong */
+	   /*****************************/
+
+		DPRINTK("Module selection is wrong\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+INT i_APCI1710_InsnReadInterruptPulseEncoder(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+
+	data[0] = devpriv->s_InterruptParameters.
+		s_FIFOInterruptParameters[devpriv->
+		s_InterruptParameters.ui_Read].b_OldModuleMask;
+	data[1] = devpriv->s_InterruptParameters.
+		s_FIFOInterruptParameters[devpriv->
+		s_InterruptParameters.ui_Read].ul_OldInterruptMask;
+	data[2] = devpriv->s_InterruptParameters.
+		s_FIFOInterruptParameters[devpriv->
+		s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
+
+	/***************************/
+	/* Increment the read FIFO */
+	/***************************/
+
+	devpriv->s_InterruptParameters.
+		ui_Read = (devpriv->
+		s_InterruptParameters.ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+
+	return insn->n;
+
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h
new file mode 100644
index 0000000..2825287
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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.
+ */
+
+#define APCI1710_SINGLE			0
+#define APCI1710_CONTINUOUS		1
+
+#define APCI1710_PULSEENCODER_READ	0
+#define APCI1710_PULSEENCODER_WRITE	1
+
+INT i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device *dev,
+					  struct comedi_subdevice *s,
+					  struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device *dev,
+						  struct comedi_subdevice *s,
+						  struct comedi_insn *insn,
+						  unsigned int *data);
+
+/*
+ * READ PULSE ENCODER FUNCTIONS
+ */
+INT i_APCI1710_InsnReadInterruptPulseEncoder(struct comedi_device *dev,
+					     struct comedi_subdevice *s,
+					     struct comedi_insn *insn,
+					     unsigned int *data);
+
+/*
+ * WRITE PULSE ENCODER FUNCTIONS
+ */
+INT i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device *dev,
+					     struct comedi_subdevice *s,
+					     struct comedi_insn *insn,
+					     unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c
new file mode 100644
index 0000000..5ddd092
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c
@@ -0,0 +1,3588 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+
+        ADDI-DATA GmbH
+        Dieselstrasse 3
+        D-77833 Ottersweier
+        Tel: +19(0)7223/9493-0
+        Fax: +49(0)7223/9493-92
+        http://www.addi-data-com
+        info@addi-data.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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+  +-----------------------------------------------------------------------+
+  | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
+  +-----------------------------------------------------------------------+
+  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
+  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
+  +-----------------------------------------------------------------------+
+  | Project     : API APCI1710    | Compiler : gcc                        |
+  | Module name : PWM.C           | Version  : 2.96                       |
+  +-------------------------------+---------------------------------------+
+  | Project manager: Eric Stolz   | Date     :  02/12/2002                |
+  +-----------------------------------------------------------------------+
+  | Description :   APCI-1710 Wulse wide modulation module                |
+  |                                                                       |
+  |                                                                       |
+  +-----------------------------------------------------------------------+
+  |                             UPDATES                                   |
+  +-----------------------------------------------------------------------+
+  |   Date   |   Author  |          Description of updates                |
+  +-----------------------------------------------------------------------+
+  | 08/05/00 | Guinot C  | - 0400/0228 All Function in RING 0             |
+  |          |           |   available                                    |
+  +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+|                               Included files                               |
++----------------------------------------------------------------------------+
+*/
+
+#include "APCI1710_Pwm.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     :INT i_APCI1710_InsnConfigPWM(struct comedi_device *dev,
+struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)                        |
++----------------------------------------------------------------------------+
+| Task              : Pwm Init and Get Pwm Initialisation                    |
++----------------------------------------------------------------------------+
+| Input Parameters  :
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigPWM(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	BYTE b_ConfigType;
+	INT i_ReturnValue = 0;
+	b_ConfigType = CR_CHAN(insn->chanspec);
+
+	switch (b_ConfigType) {
+	case APCI1710_PWM_INIT:
+		i_ReturnValue = i_APCI1710_InitPWM(dev, (BYTE) CR_AREF(insn->chanspec),	//  b_ModulNbr
+			(BYTE) data[0],	//b_PWM
+			(BYTE) data[1],	// b_ClockSelection
+			(BYTE) data[2],	// b_TimingUnit
+			(ULONG) data[3],	//ul_LowTiming
+			(ULONG) data[4],	//ul_HighTiming
+			(PULONG) & data[0],	//pul_RealLowTiming
+			(PULONG) & data[1]	//pul_RealHighTiming
+			);
+		break;
+
+	case APCI1710_PWM_GETINITDATA:
+		i_ReturnValue = i_APCI1710_GetPWMInitialisation(dev, (BYTE) CR_AREF(insn->chanspec),	// b_ModulNbr
+			(BYTE) data[0],	//b_PWM
+			(PBYTE) & data[0],	//pb_TimingUnit
+			(PULONG) & data[1],	//pul_LowTiming
+			(PULONG) & data[2],	//pul_HighTiming
+			(PBYTE) & data[3],	// pb_StartLevel
+			(PBYTE) & data[4],	// pb_StopMode
+			(PBYTE) & data[5],	// pb_StopLevel
+			(PBYTE) & data[6],	// pb_ExternGate
+			(PBYTE) & data[7],	// pb_InterruptEnable
+			(PBYTE) & data[8]	// pb_Enable
+			);
+		break;
+
+	default:
+		printk(" Config Parameter Wrong\n");
+	}
+
+	if (i_ReturnValue >= 0)
+		i_ReturnValue = insn->n;
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_InitPWM                               |
+|                                       (BYTE_     b_BoardHandle,            |
+|                                        BYTE_     b_ModulNbr,               |
+|                                        BYTE_     b_PWM,                    |
+|                                        BYTE_     b_ClockSelection,         |
+|                                        BYTE_     b_TimingUnit,             |
+|                                        ULONG_   ul_LowTiming,              |
+|                                        ULONG_   ul_HighTiming,             |
+|                                        PULONG_ pul_RealLowTiming,          |
+|                                        PULONG_ pul_RealHighTiming)         |
++----------------------------------------------------------------------------+
+| Task              : Configure the selected PWM (b_PWM) from selected module|
+|                     (b_ModulNbr). The ul_LowTiming, ul_HighTiming and      |
+|                     ul_TimingUnit determine the low/high timing base for   |
+|                     the period. pul_RealLowTiming, pul_RealHighTiming      |
+|                     return the real timing value.                          |
+|                     You must calling this function be for you call any     |
+|                     other function witch access of the PWM.                |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_     b_BoardHandle    : Handle of board APCI-1710 |
+|                     BYTE_     b_ModulNbr       : Module number to configure|
+|                                                  (0 to 3)                  |
+|                     BYTE_     b_PWM            : Selected PWM (0 or 1).    |
+|                     BYTE_     b_ClockSelection : Selection from PCI bus    |
+|                                                  clock                     |
+|                                                   - APCI1710_30MHZ :       |
+|                                                     The PC have a 30 MHz   |
+|                                                     PCI bus clock          |
+|                                                   - APCI1710_33MHZ :       |
+|                                                     The PC have a 33 MHz   |
+|                                                     PCI bus clock          |
+|                                                   - APCI1710_40MHZ         |
+|                                                     The APCI-1710 have a   |
+|                                                     integrated 40Mhz       |
+|                                                     quartz.                |
+|                     BYTE_     b_TimingUnit     : Base timing Unit (0 to 4) |
+|                                                       0 : ns               |
+|                                                       1 : æs               |
+|                                                       2 : ms               |
+|                                                       3 : s                |
+|                                                       4 : mn               |
+|                     ULONG_    ul_LowTiming     : Low base timing value.    |
+|                     ULONG_    ul_HighTiming    : High base timing value.   |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_  pul_RealLowTiming  : Real low base timing     |
+|                                                   value.                   |
+|                     PULONG_  pul_RealHighTiming : Real high base timing    |
+|                                                   value.                   |
++----------------------------------------------------------------------------+
+| Return Value      : 0: No error                                            |
+|                    -1: The handle parameter of the board is wrong          |
+|                    -2: Module selection wrong                              |
+|                    -3: The module is not a PWM module                      |
+|                    -4: PWM selection is wrong                              |
+|                    -5: The selected input clock is wrong                   |
+|                    -6: Timing Unit selection is wrong                      |
+|                    -7: Low base timing selection is wrong                  |
+|                    -8: High base timing selection is wrong                 |
+|                    -9: You can not used the 40MHz clock selection with     |
+|                        this board                                          |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InitPWM(struct comedi_device * dev,
+	BYTE b_ModulNbr,
+	BYTE b_PWM,
+	BYTE b_ClockSelection,
+	BYTE b_TimingUnit,
+	ULONG ul_LowTiming,
+	ULONG ul_HighTiming,
+	PULONG pul_RealLowTiming, PULONG pul_RealHighTiming)
+{
+	INT i_ReturnValue = 0;
+	ULONG ul_LowTimerValue = 0;
+	ULONG ul_HighTimerValue = 0;
+	DWORD dw_Command;
+	double d_RealLowTiming = 0;
+	double d_RealHighTiming = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /***************/
+		/* Test if PWM */
+	   /***************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_PWM) {
+	      /**************************/
+			/* Test the PWM selection */
+	      /**************************/
+
+			if (b_PWM <= 1) {
+		 /******************/
+				/* Test the clock */
+		 /******************/
+
+				if ((b_ClockSelection == APCI1710_30MHZ) ||
+					(b_ClockSelection == APCI1710_33MHZ) ||
+					(b_ClockSelection == APCI1710_40MHZ)) {
+		    /************************/
+					/* Test the timing unit */
+		    /************************/
+
+					if (b_TimingUnit <= 4) {
+		       /*********************************/
+						/* Test the low timing selection */
+		       /*********************************/
+
+						if (((b_ClockSelection ==
+									APCI1710_30MHZ)
+								&& (b_TimingUnit
+									== 0)
+								&& (ul_LowTiming
+									>= 266)
+								&& (ul_LowTiming
+									<=
+									0xFFFFFFFFUL))
+							|| ((b_ClockSelection ==
+									APCI1710_30MHZ)
+								&& (b_TimingUnit
+									== 1)
+								&& (ul_LowTiming
+									>= 1)
+								&& (ul_LowTiming
+									<=
+									571230650UL))
+							|| ((b_ClockSelection ==
+									APCI1710_30MHZ)
+								&& (b_TimingUnit
+									== 2)
+								&& (ul_LowTiming
+									>= 1)
+								&& (ul_LowTiming
+									<=
+									571230UL))
+							|| ((b_ClockSelection ==
+									APCI1710_30MHZ)
+								&& (b_TimingUnit
+									== 3)
+								&& (ul_LowTiming
+									>= 1)
+								&& (ul_LowTiming
+									<=
+									571UL))
+							|| ((b_ClockSelection ==
+									APCI1710_30MHZ)
+								&& (b_TimingUnit
+									== 4)
+								&& (ul_LowTiming
+									>= 1)
+								&& (ul_LowTiming
+									<= 9UL))
+							|| ((b_ClockSelection ==
+									APCI1710_33MHZ)
+								&& (b_TimingUnit
+									== 0)
+								&& (ul_LowTiming
+									>= 242)
+								&& (ul_LowTiming
+									<=
+									0xFFFFFFFFUL))
+							|| ((b_ClockSelection ==
+									APCI1710_33MHZ)
+								&& (b_TimingUnit
+									== 1)
+								&& (ul_LowTiming
+									>= 1)
+								&& (ul_LowTiming
+									<=
+									519691043UL))
+							|| ((b_ClockSelection ==
+									APCI1710_33MHZ)
+								&& (b_TimingUnit
+									== 2)
+								&& (ul_LowTiming
+									>= 1)
+								&& (ul_LowTiming
+									<=
+									519691UL))
+							|| ((b_ClockSelection ==
+									APCI1710_33MHZ)
+								&& (b_TimingUnit
+									== 3)
+								&& (ul_LowTiming
+									>= 1)
+								&& (ul_LowTiming
+									<=
+									520UL))
+							|| ((b_ClockSelection ==
+									APCI1710_33MHZ)
+								&& (b_TimingUnit
+									== 4)
+								&& (ul_LowTiming
+									>= 1)
+								&& (ul_LowTiming
+									<= 8UL))
+							|| ((b_ClockSelection ==
+									APCI1710_40MHZ)
+								&& (b_TimingUnit
+									== 0)
+								&& (ul_LowTiming
+									>= 200)
+								&& (ul_LowTiming
+									<=
+									0xFFFFFFFFUL))
+							|| ((b_ClockSelection ==
+									APCI1710_40MHZ)
+								&& (b_TimingUnit
+									== 1)
+								&& (ul_LowTiming
+									>= 1)
+								&& (ul_LowTiming
+									<=
+									429496729UL))
+							|| ((b_ClockSelection ==
+									APCI1710_40MHZ)
+								&& (b_TimingUnit
+									== 2)
+								&& (ul_LowTiming
+									>= 1)
+								&& (ul_LowTiming
+									<=
+									429496UL))
+							|| ((b_ClockSelection ==
+									APCI1710_40MHZ)
+								&& (b_TimingUnit
+									== 3)
+								&& (ul_LowTiming
+									>= 1)
+								&& (ul_LowTiming
+									<=
+									429UL))
+							|| ((b_ClockSelection ==
+									APCI1710_40MHZ)
+								&& (b_TimingUnit
+									== 4)
+								&& (ul_LowTiming
+									>= 1)
+								&& (ul_LowTiming
+									<=
+									7UL))) {
+			  /**********************************/
+							/* Test the High timing selection */
+			  /**********************************/
+
+							if (((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 266) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571230650UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571230UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 9UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 242) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 519691043UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 519691UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 520UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 8UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 200) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429496729UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429496UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 7UL))) {
+			     /**************************/
+								/* Test the board version */
+			     /**************************/
+
+								if (((b_ClockSelection == APCI1710_40MHZ) && (devpriv->s_BoardInfos.b_BoardVersion > 0)) || (b_ClockSelection != APCI1710_40MHZ)) {
+
+				/************************************/
+									/* Calculate the low division fator */
+				/************************************/
+
+									fpu_begin
+										();
+
+									switch (b_TimingUnit) {
+				   /******/
+										/* ns */
+				   /******/
+
+									case 0:
+
+					   /******************/
+										/* Timer 0 factor */
+					   /******************/
+
+										ul_LowTimerValue
+											=
+											(ULONG)
+											(ul_LowTiming
+											*
+											(0.00025 * b_ClockSelection));
+
+					   /*******************/
+										/* Round the value */
+					   /*******************/
+
+										if ((double)((double)ul_LowTiming * (0.00025 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+											ul_LowTimerValue
+												=
+												ul_LowTimerValue
+												+
+												1;
+										}
+
+					   /*****************************/
+										/* Calculate the real timing */
+					   /*****************************/
+
+										*pul_RealLowTiming
+											=
+											(ULONG)
+											(ul_LowTimerValue
+											/
+											(0.00025 * (double)b_ClockSelection));
+										d_RealLowTiming
+											=
+											(double)
+											ul_LowTimerValue
+											/
+											(0.00025
+											*
+											(double)
+											b_ClockSelection);
+
+										if ((double)((double)ul_LowTimerValue / (0.00025 * (double)b_ClockSelection)) >= (double)((double)*pul_RealLowTiming + 0.5)) {
+											*pul_RealLowTiming
+												=
+												*pul_RealLowTiming
+												+
+												1;
+										}
+
+										ul_LowTiming
+											=
+											ul_LowTiming
+											-
+											1;
+										ul_LowTimerValue
+											=
+											ul_LowTimerValue
+											-
+											2;
+
+										if (b_ClockSelection != APCI1710_40MHZ) {
+											ul_LowTimerValue
+												=
+												(ULONG)
+												(
+												(double)
+												(ul_LowTimerValue)
+												*
+												1.007752288);
+										}
+
+										break;
+
+				   /******/
+										/* æs */
+				   /******/
+
+									case 1:
+
+					   /******************/
+										/* Timer 0 factor */
+					   /******************/
+
+										ul_LowTimerValue
+											=
+											(ULONG)
+											(ul_LowTiming
+											*
+											(0.25 * b_ClockSelection));
+
+					   /*******************/
+										/* Round the value */
+					   /*******************/
+
+										if ((double)((double)ul_LowTiming * (0.25 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+											ul_LowTimerValue
+												=
+												ul_LowTimerValue
+												+
+												1;
+										}
+
+					   /*****************************/
+										/* Calculate the real timing */
+					   /*****************************/
+
+										*pul_RealLowTiming
+											=
+											(ULONG)
+											(ul_LowTimerValue
+											/
+											(0.25 * (double)b_ClockSelection));
+										d_RealLowTiming
+											=
+											(double)
+											ul_LowTimerValue
+											/
+											(
+											(double)
+											0.25
+											*
+											(double)
+											b_ClockSelection);
+
+										if ((double)((double)ul_LowTimerValue / (0.25 * (double)b_ClockSelection)) >= (double)((double)*pul_RealLowTiming + 0.5)) {
+											*pul_RealLowTiming
+												=
+												*pul_RealLowTiming
+												+
+												1;
+										}
+
+										ul_LowTiming
+											=
+											ul_LowTiming
+											-
+											1;
+										ul_LowTimerValue
+											=
+											ul_LowTimerValue
+											-
+											2;
+
+										if (b_ClockSelection != APCI1710_40MHZ) {
+											ul_LowTimerValue
+												=
+												(ULONG)
+												(
+												(double)
+												(ul_LowTimerValue)
+												*
+												1.007752288);
+										}
+
+										break;
+
+				   /******/
+										/* ms */
+				   /******/
+
+									case 2:
+
+					   /******************/
+										/* Timer 0 factor */
+					   /******************/
+
+										ul_LowTimerValue
+											=
+											ul_LowTiming
+											*
+											(250.0
+											*
+											b_ClockSelection);
+
+					   /*******************/
+										/* Round the value */
+					   /*******************/
+
+										if ((double)((double)ul_LowTiming * (250.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+											ul_LowTimerValue
+												=
+												ul_LowTimerValue
+												+
+												1;
+										}
+
+					   /*****************************/
+										/* Calculate the real timing */
+					   /*****************************/
+
+										*pul_RealLowTiming
+											=
+											(ULONG)
+											(ul_LowTimerValue
+											/
+											(250.0 * (double)b_ClockSelection));
+										d_RealLowTiming
+											=
+											(double)
+											ul_LowTimerValue
+											/
+											(250.0
+											*
+											(double)
+											b_ClockSelection);
+
+										if ((double)((double)ul_LowTimerValue / (250.0 * (double)b_ClockSelection)) >= (double)((double)*pul_RealLowTiming + 0.5)) {
+											*pul_RealLowTiming
+												=
+												*pul_RealLowTiming
+												+
+												1;
+										}
+
+										ul_LowTiming
+											=
+											ul_LowTiming
+											-
+											1;
+										ul_LowTimerValue
+											=
+											ul_LowTimerValue
+											-
+											2;
+
+										if (b_ClockSelection != APCI1710_40MHZ) {
+											ul_LowTimerValue
+												=
+												(ULONG)
+												(
+												(double)
+												(ul_LowTimerValue)
+												*
+												1.007752288);
+										}
+
+										break;
+
+				   /*****/
+										/* s */
+				   /*****/
+
+									case 3:
+					   /******************/
+										/* Timer 0 factor */
+					   /******************/
+
+										ul_LowTimerValue
+											=
+											(ULONG)
+											(ul_LowTiming
+											*
+											(250000.0
+												*
+												b_ClockSelection));
+
+					   /*******************/
+										/* Round the value */
+					   /*******************/
+
+										if ((double)((double)ul_LowTiming * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+											ul_LowTimerValue
+												=
+												ul_LowTimerValue
+												+
+												1;
+										}
+
+					   /*****************************/
+										/* Calculate the real timing */
+					   /*****************************/
+
+										*pul_RealLowTiming
+											=
+											(ULONG)
+											(ul_LowTimerValue
+											/
+											(250000.0
+												*
+												(double)
+												b_ClockSelection));
+										d_RealLowTiming
+											=
+											(double)
+											ul_LowTimerValue
+											/
+											(250000.0
+											*
+											(double)
+											b_ClockSelection);
+
+										if ((double)((double)ul_LowTimerValue / (250000.0 * (double)b_ClockSelection)) >= (double)((double)*pul_RealLowTiming + 0.5)) {
+											*pul_RealLowTiming
+												=
+												*pul_RealLowTiming
+												+
+												1;
+										}
+
+										ul_LowTiming
+											=
+											ul_LowTiming
+											-
+											1;
+										ul_LowTimerValue
+											=
+											ul_LowTimerValue
+											-
+											2;
+
+										if (b_ClockSelection != APCI1710_40MHZ) {
+											ul_LowTimerValue
+												=
+												(ULONG)
+												(
+												(double)
+												(ul_LowTimerValue)
+												*
+												1.007752288);
+										}
+
+										break;
+
+				   /******/
+										/* mn */
+				   /******/
+
+									case 4:
+
+					   /******************/
+										/* Timer 0 factor */
+					   /******************/
+
+										ul_LowTimerValue
+											=
+											(ULONG)
+											(
+											(ul_LowTiming
+												*
+												60)
+											*
+											(250000.0
+												*
+												b_ClockSelection));
+
+					   /*******************/
+										/* Round the value */
+					   /*******************/
+
+										if ((double)((double)(ul_LowTiming * 60.0) * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+											ul_LowTimerValue
+												=
+												ul_LowTimerValue
+												+
+												1;
+										}
+
+					   /*****************************/
+										/* Calculate the real timing */
+					   /*****************************/
+
+										*pul_RealLowTiming
+											=
+											(ULONG)
+											(ul_LowTimerValue
+											/
+											(250000.0
+												*
+												(double)
+												b_ClockSelection))
+											/
+											60;
+										d_RealLowTiming
+											=
+											(
+											(double)
+											ul_LowTimerValue
+											/
+											(250000.0
+												*
+												(double)
+												b_ClockSelection))
+											/
+											60.0;
+
+										if ((double)(((double)ul_LowTimerValue / (250000.0 * (double)b_ClockSelection)) / 60.0) >= (double)((double)*pul_RealLowTiming + 0.5)) {
+											*pul_RealLowTiming
+												=
+												*pul_RealLowTiming
+												+
+												1;
+										}
+
+										ul_LowTiming
+											=
+											ul_LowTiming
+											-
+											1;
+										ul_LowTimerValue
+											=
+											ul_LowTimerValue
+											-
+											2;
+
+										if (b_ClockSelection != APCI1710_40MHZ) {
+											ul_LowTimerValue
+												=
+												(ULONG)
+												(
+												(double)
+												(ul_LowTimerValue)
+												*
+												1.007752288);
+										}
+
+										break;
+									}
+
+				/*************************************/
+									/* Calculate the high division fator */
+				/*************************************/
+
+									switch (b_TimingUnit) {
+				   /******/
+										/* ns */
+				   /******/
+
+									case 0:
+
+					   /******************/
+										/* Timer 0 factor */
+					   /******************/
+
+										ul_HighTimerValue
+											=
+											(ULONG)
+											(ul_HighTiming
+											*
+											(0.00025 * b_ClockSelection));
+
+					   /*******************/
+										/* Round the value */
+					   /*******************/
+
+										if ((double)((double)ul_HighTiming * (0.00025 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+											ul_HighTimerValue
+												=
+												ul_HighTimerValue
+												+
+												1;
+										}
+
+					   /*****************************/
+										/* Calculate the real timing */
+					   /*****************************/
+
+										*pul_RealHighTiming
+											=
+											(ULONG)
+											(ul_HighTimerValue
+											/
+											(0.00025 * (double)b_ClockSelection));
+										d_RealHighTiming
+											=
+											(double)
+											ul_HighTimerValue
+											/
+											(0.00025
+											*
+											(double)
+											b_ClockSelection);
+
+										if ((double)((double)ul_HighTimerValue / (0.00025 * (double)b_ClockSelection)) >= (double)((double)*pul_RealHighTiming + 0.5)) {
+											*pul_RealHighTiming
+												=
+												*pul_RealHighTiming
+												+
+												1;
+										}
+
+										ul_HighTiming
+											=
+											ul_HighTiming
+											-
+											1;
+										ul_HighTimerValue
+											=
+											ul_HighTimerValue
+											-
+											2;
+
+										if (b_ClockSelection != APCI1710_40MHZ) {
+											ul_HighTimerValue
+												=
+												(ULONG)
+												(
+												(double)
+												(ul_HighTimerValue)
+												*
+												1.007752288);
+										}
+
+										break;
+
+				   /******/
+										/* æs */
+				   /******/
+
+									case 1:
+
+					   /******************/
+										/* Timer 0 factor */
+					   /******************/
+
+										ul_HighTimerValue
+											=
+											(ULONG)
+											(ul_HighTiming
+											*
+											(0.25 * b_ClockSelection));
+
+					   /*******************/
+										/* Round the value */
+					   /*******************/
+
+										if ((double)((double)ul_HighTiming * (0.25 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+											ul_HighTimerValue
+												=
+												ul_HighTimerValue
+												+
+												1;
+										}
+
+					   /*****************************/
+										/* Calculate the real timing */
+					   /*****************************/
+
+										*pul_RealHighTiming
+											=
+											(ULONG)
+											(ul_HighTimerValue
+											/
+											(0.25 * (double)b_ClockSelection));
+										d_RealHighTiming
+											=
+											(double)
+											ul_HighTimerValue
+											/
+											(
+											(double)
+											0.25
+											*
+											(double)
+											b_ClockSelection);
+
+										if ((double)((double)ul_HighTimerValue / (0.25 * (double)b_ClockSelection)) >= (double)((double)*pul_RealHighTiming + 0.5)) {
+											*pul_RealHighTiming
+												=
+												*pul_RealHighTiming
+												+
+												1;
+										}
+
+										ul_HighTiming
+											=
+											ul_HighTiming
+											-
+											1;
+										ul_HighTimerValue
+											=
+											ul_HighTimerValue
+											-
+											2;
+
+										if (b_ClockSelection != APCI1710_40MHZ) {
+											ul_HighTimerValue
+												=
+												(ULONG)
+												(
+												(double)
+												(ul_HighTimerValue)
+												*
+												1.007752288);
+										}
+
+										break;
+
+				   /******/
+										/* ms */
+				   /******/
+
+									case 2:
+
+					   /******************/
+										/* Timer 0 factor */
+					   /******************/
+
+										ul_HighTimerValue
+											=
+											ul_HighTiming
+											*
+											(250.0
+											*
+											b_ClockSelection);
+
+					   /*******************/
+										/* Round the value */
+					   /*******************/
+
+										if ((double)((double)ul_HighTiming * (250.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+											ul_HighTimerValue
+												=
+												ul_HighTimerValue
+												+
+												1;
+										}
+
+					   /*****************************/
+										/* Calculate the real timing */
+					   /*****************************/
+
+										*pul_RealHighTiming
+											=
+											(ULONG)
+											(ul_HighTimerValue
+											/
+											(250.0 * (double)b_ClockSelection));
+										d_RealHighTiming
+											=
+											(double)
+											ul_HighTimerValue
+											/
+											(250.0
+											*
+											(double)
+											b_ClockSelection);
+
+										if ((double)((double)ul_HighTimerValue / (250.0 * (double)b_ClockSelection)) >= (double)((double)*pul_RealHighTiming + 0.5)) {
+											*pul_RealHighTiming
+												=
+												*pul_RealHighTiming
+												+
+												1;
+										}
+
+										ul_HighTiming
+											=
+											ul_HighTiming
+											-
+											1;
+										ul_HighTimerValue
+											=
+											ul_HighTimerValue
+											-
+											2;
+
+										if (b_ClockSelection != APCI1710_40MHZ) {
+											ul_HighTimerValue
+												=
+												(ULONG)
+												(
+												(double)
+												(ul_HighTimerValue)
+												*
+												1.007752288);
+										}
+
+										break;
+
+				   /*****/
+										/* s */
+				   /*****/
+
+									case 3:
+
+					   /******************/
+										/* Timer 0 factor */
+					   /******************/
+
+										ul_HighTimerValue
+											=
+											(ULONG)
+											(ul_HighTiming
+											*
+											(250000.0
+												*
+												b_ClockSelection));
+
+					   /*******************/
+										/* Round the value */
+					   /*******************/
+
+										if ((double)((double)ul_HighTiming * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+											ul_HighTimerValue
+												=
+												ul_HighTimerValue
+												+
+												1;
+										}
+
+					   /*****************************/
+										/* Calculate the real timing */
+					   /*****************************/
+
+										*pul_RealHighTiming
+											=
+											(ULONG)
+											(ul_HighTimerValue
+											/
+											(250000.0
+												*
+												(double)
+												b_ClockSelection));
+										d_RealHighTiming
+											=
+											(double)
+											ul_HighTimerValue
+											/
+											(250000.0
+											*
+											(double)
+											b_ClockSelection);
+
+										if ((double)((double)ul_HighTimerValue / (250000.0 * (double)b_ClockSelection)) >= (double)((double)*pul_RealHighTiming + 0.5)) {
+											*pul_RealHighTiming
+												=
+												*pul_RealHighTiming
+												+
+												1;
+										}
+
+										ul_HighTiming
+											=
+											ul_HighTiming
+											-
+											1;
+										ul_HighTimerValue
+											=
+											ul_HighTimerValue
+											-
+											2;
+
+										if (b_ClockSelection != APCI1710_40MHZ) {
+											ul_HighTimerValue
+												=
+												(ULONG)
+												(
+												(double)
+												(ul_HighTimerValue)
+												*
+												1.007752288);
+										}
+
+										break;
+
+				   /******/
+										/* mn */
+				   /******/
+
+									case 4:
+
+					   /******************/
+										/* Timer 0 factor */
+					   /******************/
+
+										ul_HighTimerValue
+											=
+											(ULONG)
+											(
+											(ul_HighTiming
+												*
+												60)
+											*
+											(250000.0
+												*
+												b_ClockSelection));
+
+					   /*******************/
+										/* Round the value */
+					   /*******************/
+
+										if ((double)((double)(ul_HighTiming * 60.0) * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+											ul_HighTimerValue
+												=
+												ul_HighTimerValue
+												+
+												1;
+										}
+
+					   /*****************************/
+										/* Calculate the real timing */
+					   /*****************************/
+
+										*pul_RealHighTiming
+											=
+											(ULONG)
+											(ul_HighTimerValue
+											/
+											(250000.0
+												*
+												(double)
+												b_ClockSelection))
+											/
+											60;
+										d_RealHighTiming
+											=
+											(
+											(double)
+											ul_HighTimerValue
+											/
+											(250000.0
+												*
+												(double)
+												b_ClockSelection))
+											/
+											60.0;
+
+										if ((double)(((double)ul_HighTimerValue / (250000.0 * (double)b_ClockSelection)) / 60.0) >= (double)((double)*pul_RealHighTiming + 0.5)) {
+											*pul_RealHighTiming
+												=
+												*pul_RealHighTiming
+												+
+												1;
+										}
+
+										ul_HighTiming
+											=
+											ul_HighTiming
+											-
+											1;
+										ul_HighTimerValue
+											=
+											ul_HighTimerValue
+											-
+											2;
+
+										if (b_ClockSelection != APCI1710_40MHZ) {
+											ul_HighTimerValue
+												=
+												(ULONG)
+												(
+												(double)
+												(ul_HighTimerValue)
+												*
+												1.007752288);
+										}
+
+										break;
+									}
+
+									fpu_end();
+				/****************************/
+									/* Save the clock selection */
+				/****************************/
+
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_PWMModuleInfo.
+										b_ClockSelection
+										=
+										b_ClockSelection;
+
+				/************************/
+									/* Save the timing unit */
+				/************************/
+
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_PWMModuleInfo.
+										s_PWMInfo
+										[b_PWM].
+										b_TimingUnit
+										=
+										b_TimingUnit;
+
+				/****************************/
+									/* Save the low base timing */
+				/****************************/
+
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_PWMModuleInfo.
+										s_PWMInfo
+										[b_PWM].
+										d_LowTiming
+										=
+										d_RealLowTiming;
+
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_PWMModuleInfo.
+										s_PWMInfo
+										[b_PWM].
+										ul_RealLowTiming
+										=
+										*pul_RealLowTiming;
+
+				/****************************/
+									/* Save the high base timing */
+				/****************************/
+
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_PWMModuleInfo.
+										s_PWMInfo
+										[b_PWM].
+										d_HighTiming
+										=
+										d_RealHighTiming;
+
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_PWMModuleInfo.
+										s_PWMInfo
+										[b_PWM].
+										ul_RealHighTiming
+										=
+										*pul_RealHighTiming;
+
+				/************************/
+									/* Write the low timing */
+				/************************/
+
+									outl(ul_LowTimerValue, devpriv->s_BoardInfos.ui_Address + 0 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+				/*************************/
+									/* Write the high timing */
+				/*************************/
+
+									outl(ul_HighTimerValue, devpriv->s_BoardInfos.ui_Address + 4 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+				/***************************/
+									/* Set the clock selection */
+				/***************************/
+
+									dw_Command
+										=
+										inl
+										(devpriv->
+										s_BoardInfos.
+										ui_Address
+										+
+										8
+										+
+										(20 * b_PWM) + (64 * b_ModulNbr));
+
+									dw_Command
+										=
+										dw_Command
+										&
+										0x7F;
+
+									if (b_ClockSelection == APCI1710_40MHZ) {
+										dw_Command
+											=
+											dw_Command
+											|
+											0x80;
+									}
+
+				/***************************/
+									/* Set the clock selection */
+				/***************************/
+
+									outl(dw_Command, devpriv->s_BoardInfos.ui_Address + 8 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+				/*************/
+									/* PWM init. */
+				/*************/
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_PWMModuleInfo.
+										s_PWMInfo
+										[b_PWM].
+										b_PWMInit
+										=
+										1;
+								} else {
+				/***************************************************/
+									/* You can not used the 40MHz clock selection with */
+									/* this board                                      */
+				/***************************************************/
+									DPRINTK("You can not used the 40MHz clock selection with this board\n");
+									i_ReturnValue
+										=
+										-9;
+								}
+							} else {
+			     /***************************************/
+								/* High base timing selection is wrong */
+			     /***************************************/
+								DPRINTK("High base timing selection is wrong\n");
+								i_ReturnValue =
+									-8;
+							}
+						} else {
+			  /**************************************/
+							/* Low base timing selection is wrong */
+			  /**************************************/
+							DPRINTK("Low base timing selection is wrong\n");
+							i_ReturnValue = -7;
+						}
+					}	// if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+					else {
+		       /**********************************/
+						/* Timing unit selection is wrong */
+		       /**********************************/
+						DPRINTK("Timing unit selection is wrong\n");
+						i_ReturnValue = -6;
+					}	// if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+				}	// if ((b_ClockSelection == APCI1710_30MHZ) || (b_ClockSelection == APCI1710_33MHZ) || (b_ClockSelection == APCI1710_40MHZ))
+				else {
+		    /*******************************/
+					/* The selected clock is wrong */
+		    /*******************************/
+					DPRINTK("The selected clock is wrong\n");
+					i_ReturnValue = -5;
+				}	// if ((b_ClockSelection == APCI1710_30MHZ) || (b_ClockSelection == APCI1710_33MHZ) || (b_ClockSelection == APCI1710_40MHZ))
+			}	// if (b_PWM >= 0 && b_PWM <= 1)
+			else {
+		 /******************************/
+				/* Tor PWM selection is wrong */
+		 /******************************/
+				DPRINTK("Tor PWM selection is wrong\n");
+				i_ReturnValue = -4;
+			}	// if (b_PWM >= 0 && b_PWM <= 1)
+		} else {
+	      /**********************************/
+			/* The module is not a PWM module */
+	      /**********************************/
+			DPRINTK("The module is not a PWM module\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /***********************/
+		/* Module number error */
+	   /***********************/
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_GetPWMInitialisation                  |
+|                                       (BYTE_     b_BoardHandle,            |
+|                                        BYTE_     b_ModulNbr,               |
+|                                        BYTE_     b_PWM,                    |
+|                                        PBYTE_   pb_TimingUnit,             |
+|                                        PULONG_ pul_LowTiming,              |
+|                                        PULONG_ pul_HighTiming,             |
+|                                        PBYTE_   pb_StartLevel,             |
+|                                        PBYTE_   pb_StopMode,               |
+|                                        PBYTE_   pb_StopLevel,              |
+|                                        PBYTE_   pb_ExternGate,             |
+|                                        PBYTE_   pb_InterruptEnable,        |
+|                                        PBYTE_   pb_Enable)                 |
++----------------------------------------------------------------------------+
+| Task              : Return the PWM (b_PWM) initialisation from selected    |
+|                     module (b_ModulNbr). You must calling the              |
+|                     "i_APCI1710_InitPWM" function be for you call this     |
+|                     function.                                              |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle : Handle of board APCI-1710        |
+|                     BYTE_ b_ModulNbr    : Selected module number (0 to 3)  |
+|                     BYTE_ b_PWM         : Selected PWM (0 or 1)            |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_  pb_TimingUnit      : Base timing Unit (0 to 4) |
+|                                                       0 : ns               |
+|                                                       1 : æs               |
+|                                                       2 : ms               |
+|                                                       3 : s                |
+|                                                       4 : mn               |
+|                     PULONG_ pul_LowTiming      : Low base timing value.    |
+|                     PULONG_ pul_HighTiming     : High base timing value.   |
+|                     PBYTE_  pb_StartLevel      : Start period level        |
+|                                                  selection                 |
+|                                                       0 : The period start |
+|                                                           with a low level |
+|                                                       1 : The period start |
+|                                                           with a high level|
+|                     PBYTE_  pb_StopMode        : Stop mode selection       |
+|                                                  0 : The PWM is stopped    |
+|                                                      directly after the    |
+|                                                     "i_APCI1710_DisablePWM"|
+|                                                      function and break the|
+|                                                      last period           |
+|                                                  1 : After the             |
+|                                                     "i_APCI1710_DisablePWM"|
+|                                                      function the PWM is   |
+|                                                      stopped at the end    |
+|                                                      from last period cycle|
+|                     PBYTE_  pb_StopLevel        : Stop PWM level selection |
+|                                                    0 : The output signal   |
+|                                                        keep the level after|
+|                                                        the                 |
+|                                                     "i_APCI1710_DisablePWM"|
+|                                                        function            |
+|                                                    1 : The output signal is|
+|                                                        set to low after the|
+|                                                     "i_APCI1710_DisablePWM"|
+|                                                        function            |
+|                                                    2 : The output signal is|
+|                                                        set to high after   |
+|                                                        the                 |
+|                                                     "i_APCI1710_DisablePWM"|
+|                                                        function            |
+|                     PBYTE_  pb_ExternGate      : Extern gate action        |
+|                                                  selection                 |
+|                                                   0 : Extern gate signal   |
+|                                                       not used.            |
+|                                                   1 : Extern gate signal   |
+|                                                       used.                |
+|                     PBYTE_  pb_InterruptEnable : Enable or disable the PWM |
+|                                                  interrupt.                |
+|                                                  - APCI1710_ENABLE :       |
+|                                                    Enable the PWM interrupt|
+|                                                    A interrupt occur after |
+|                                                    each period             |
+|                                                  - APCI1710_DISABLE :      |
+|                                                    Disable the PWM         |
+|                                                    interrupt               |
+|                     PBYTE_  pb_Enable          : Indicate if the PWM is    |
+|                                                  enabled or no             |
+|                                                       0 : PWM not enabled  |
+|                                                       1 : PWM enabled      |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: Module selection wrong                             |
+|                     -3: The module is not a PWM module                     |
+|                     -4: PWM selection is wrong                             |
+|                     -5: PWM not initialised see function                   |
+|                         "i_APCI1710_InitPWM"                               |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetPWMInitialisation(struct comedi_device * dev,
+	BYTE b_ModulNbr,
+	BYTE b_PWM,
+	PBYTE pb_TimingUnit,
+	PULONG pul_LowTiming,
+	PULONG pul_HighTiming,
+	PBYTE pb_StartLevel,
+	PBYTE pb_StopMode,
+	PBYTE pb_StopLevel,
+	PBYTE pb_ExternGate, PBYTE pb_InterruptEnable, PBYTE pb_Enable)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_Status;
+	DWORD dw_Command;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /***************/
+		/* Test if PWM */
+	   /***************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_PWM) {
+	      /**************************/
+			/* Test the PWM selection */
+	      /**************************/
+
+			if (b_PWM <= 1) {
+		 /***************************/
+				/* Test if PWM initialised */
+		 /***************************/
+
+				dw_Status = inl(devpriv->s_BoardInfos.
+					ui_Address + 12 + (20 * b_PWM) +
+					(64 * b_ModulNbr));
+
+				if (dw_Status & 0x10) {
+		    /***********************/
+					/* Read the low timing */
+		    /***********************/
+
+					*pul_LowTiming =
+						inl(devpriv->s_BoardInfos.
+						ui_Address + 0 + (20 * b_PWM) +
+						(64 * b_ModulNbr));
+
+		    /************************/
+					/* Read the high timing */
+		    /************************/
+
+					*pul_HighTiming =
+						inl(devpriv->s_BoardInfos.
+						ui_Address + 4 + (20 * b_PWM) +
+						(64 * b_ModulNbr));
+
+		    /********************/
+					/* Read the command */
+		    /********************/
+
+					dw_Command = inl(devpriv->s_BoardInfos.
+						ui_Address + 8 + (20 * b_PWM) +
+						(64 * b_ModulNbr));
+
+					*pb_StartLevel =
+						(BYTE) ((dw_Command >> 5) & 1);
+					*pb_StopMode =
+						(BYTE) ((dw_Command >> 0) & 1);
+					*pb_StopLevel =
+						(BYTE) ((dw_Command >> 1) & 1);
+					*pb_ExternGate =
+						(BYTE) ((dw_Command >> 4) & 1);
+					*pb_InterruptEnable =
+						(BYTE) ((dw_Command >> 3) & 1);
+
+					if (*pb_StopLevel) {
+						*pb_StopLevel =
+							*pb_StopLevel +
+							(BYTE) ((dw_Command >>
+								2) & 1);
+					}
+
+		    /********************/
+					/* Read the command */
+		    /********************/
+
+					dw_Command = inl(devpriv->s_BoardInfos.
+						ui_Address + 8 + (20 * b_PWM) +
+						(64 * b_ModulNbr));
+
+					*pb_Enable =
+						(BYTE) ((dw_Command >> 0) & 1);
+
+					*pb_TimingUnit = devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_PWMModuleInfo.
+						s_PWMInfo[b_PWM].b_TimingUnit;
+				}	// if (dw_Status & 0x10)
+				else {
+		    /***********************/
+					/* PWM not initialised */
+		    /***********************/
+					DPRINTK("PWM not initialised\n");
+					i_ReturnValue = -5;
+				}	// if (dw_Status & 0x10)
+			}	// if (b_PWM >= 0 && b_PWM <= 1)
+			else {
+		 /******************************/
+				/* Tor PWM selection is wrong */
+		 /******************************/
+				DPRINTK("Tor PWM selection is wrong\n");
+				i_ReturnValue = -4;
+			}	// if (b_PWM >= 0 && b_PWM <= 1)
+		} else {
+	      /**********************************/
+			/* The module is not a PWM module */
+	      /**********************************/
+			DPRINTK("The module is not a PWM module\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /***********************/
+		/* Module number error */
+	   /***********************/
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     :INT i_APCI1710_InsnWritePWM(struct comedi_device *dev,
+struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)                        |
++----------------------------------------------------------------------------+
+| Task              : Pwm Enable Disable and Set New Timing                  |
++----------------------------------------------------------------------------+
+| Input Parameters  :
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnWritePWM(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	BYTE b_WriteType;
+	INT i_ReturnValue = 0;
+	b_WriteType = CR_CHAN(insn->chanspec);
+
+	switch (b_WriteType) {
+	case APCI1710_PWM_ENABLE:
+		i_ReturnValue = i_APCI1710_EnablePWM(dev,
+			(BYTE) CR_AREF(insn->chanspec),
+			(BYTE) data[0],
+			(BYTE) data[1],
+			(BYTE) data[2],
+			(BYTE) data[3], (BYTE) data[4], (BYTE) data[5]);
+		break;
+
+	case APCI1710_PWM_DISABLE:
+		i_ReturnValue = i_APCI1710_DisablePWM(dev,
+			(BYTE) CR_AREF(insn->chanspec), (BYTE) data[0]);
+		break;
+
+	case APCI1710_PWM_NEWTIMING:
+		i_ReturnValue = i_APCI1710_SetNewPWMTiming(dev,
+			(BYTE) CR_AREF(insn->chanspec),
+			(BYTE) data[0],
+			(BYTE) data[1], (ULONG) data[2], (ULONG) data[3]);
+		break;
+
+	default:
+		printk("Write Config Parameter Wrong\n");
+	}
+
+	if (i_ReturnValue >= 0)
+		i_ReturnValue = insn->n;
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_     i_APCI1710_EnablePWM                         |
+|                                       (BYTE_  b_BoardHandle,               |
+|                                        BYTE_  b_ModulNbr,                  |
+|                                        BYTE_  b_PWM,                       |
+|                                        BYTE_  b_StartLevel,                |
+|                                        BYTE_  b_StopMode,                  |
+|                                        BYTE_  b_StopLevel,                 |
+|                                        BYTE_  b_ExternGate,                |
+|                                        BYTE_  b_InterruptEnable)           |
++----------------------------------------------------------------------------+
+| Task              : Enable the selected PWM (b_PWM) from selected module   |
+|                     (b_ModulNbr). You must calling the "i_APCI1710_InitPWM"|
+|                     function be for you call this function.                |
+|                     If you enable the PWM interrupt, the PWM generate a    |
+|                     interrupt after each period.                           |
+|                     See function "i_APCI1710_SetBoardIntRoutineX" and the  |
+|                     Interrupt mask description chapter.                    |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle     : Handle of board APCI-1710    |
+|                     BYTE_ b_ModulNbr        : Selected module number       |
+|                                               (0 to 3)                     |
+|                     BYTE_ b_PWM             : Selected PWM (0 or 1)        |
+|                     BYTE_ b_StartLevel      : Start period level selection |
+|                                                0 : The period start with a |
+|                                                    low level               |
+|                                                1 : The period start with a |
+|                                                    high level              |
+|                     BYTE_ b_StopMode        : Stop mode selection          |
+|                                                0 : The PWM is stopped      |
+|                                                    directly after the      |
+|                                                    "i_APCI1710_DisablePWM" |
+|                                                    function and break the  |
+|                                                    last period             |
+|                                                1 : After the               |
+|                                                    "i_APCI1710_DisablePWM" |
+|                                                     function the PWM is    |
+|                                                     stopped at the end from|
+|                                                     last period cycle.     |
+|                     BYTE_ b_StopLevel       : Stop PWM level selection     |
+|                                                0 : The output signal keep  |
+|                                                    the level after the     |
+|                                                    "i_APCI1710_DisablePWM" |
+|                                                    function                |
+|                                                1 : The output signal is set|
+|                                                    to low after the        |
+|                                                    "i_APCI1710_DisablePWM" |
+|                                                    function                |
+|                                                2 : The output signal is set|
+|                                                    to high after the       |
+|                                                    "i_APCI1710_DisablePWM" |
+|                                                    function                |
+|                     BYTE_ b_ExternGate      : Extern gate action selection |
+|                                                0 : Extern gate signal not  |
+|                                                    used.                   |
+|                                                1 : Extern gate signal used.|
+|                     BYTE_ b_InterruptEnable : Enable or disable the PWM    |
+|                                               interrupt.                   |
+|                                               - APCI1710_ENABLE :          |
+|                                                 Enable the PWM interrupt   |
+|                                                 A interrupt occur after    |
+|                                                 each period                |
+|                                               - APCI1710_DISABLE :         |
+|                                                 Disable the PWM interrupt  |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : 0:  No error                                           |
+|                    -1:  The handle parameter of the board is wrong         |
+|                    -2:  Module selection wrong                             |
+|                    -3:  The module is not a PWM module                     |
+|                    -4:  PWM selection is wrong                             |
+|                    -5:  PWM not initialised see function                   |
+|                         "i_APCI1710_InitPWM"                               |
+|                    -6:  PWM start level selection is wrong                 |
+|                    -7:  PWM stop mode selection is wrong                   |
+|                    -8:  PWM stop level selection is wrong                  |
+|                    -9:  Extern gate signal selection is wrong              |
+|                    -10: Interrupt parameter is wrong                       |
+|                    -11: Interrupt function not initialised.                |
+|                         See function "i_APCI1710_SetBoardIntRoutineX"      |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_EnablePWM(struct comedi_device * dev,
+	BYTE b_ModulNbr,
+	BYTE b_PWM,
+	BYTE b_StartLevel,
+	BYTE b_StopMode,
+	BYTE b_StopLevel, BYTE b_ExternGate, BYTE b_InterruptEnable)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_Status;
+	DWORD dw_Command;
+
+	devpriv->tsk_Current = current;	// Save the current process task structure
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /***************/
+		/* Test if PWM */
+	   /***************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_PWM) {
+	      /**************************/
+			/* Test the PWM selection */
+	      /**************************/
+
+			if (b_PWM <= 1) {
+		 /***************************/
+				/* Test if PWM initialised */
+		 /***************************/
+
+				dw_Status = inl(devpriv->s_BoardInfos.
+					ui_Address + 12 + (20 * b_PWM) +
+					(64 * b_ModulNbr));
+
+				if (dw_Status & 0x10) {
+		    /**********************************/
+					/* Test the start level selection */
+		    /**********************************/
+
+					if (b_StartLevel <= 1) {
+		       /**********************/
+						/* Test the stop mode */
+		       /**********************/
+
+						if (b_StopMode <= 1) {
+			  /***********************/
+							/* Test the stop level */
+			  /***********************/
+
+							if (b_StopLevel <= 2) {
+			     /*****************************/
+								/* Test the extern gate mode */
+			     /*****************************/
+
+								if (b_ExternGate
+									<= 1) {
+				/*****************************/
+									/* Test the interrupt action */
+				/*****************************/
+
+									if (b_InterruptEnable == APCI1710_ENABLE || b_InterruptEnable == APCI1710_DISABLE) {
+				   /******************************************/
+										/* Test if interrupt function initialised */
+				   /******************************************/
+
+				      /********************/
+										/* Read the command */
+				      /********************/
+
+										dw_Command
+											=
+											inl
+											(devpriv->
+											s_BoardInfos.
+											ui_Address
+											+
+											8
+											+
+											(20 * b_PWM) + (64 * b_ModulNbr));
+
+										dw_Command
+											=
+											dw_Command
+											&
+											0x80;
+
+				      /********************/
+										/* Make the command */
+				      /********************/
+
+										dw_Command
+											=
+											dw_Command
+											|
+											b_StopMode
+											|
+											(b_InterruptEnable
+											<<
+											3)
+											|
+											(b_ExternGate
+											<<
+											4)
+											|
+											(b_StartLevel
+											<<
+											5);
+
+										if (b_StopLevel & 3) {
+											dw_Command
+												=
+												dw_Command
+												|
+												2;
+
+											if (b_StopLevel & 2) {
+												dw_Command
+													=
+													dw_Command
+													|
+													4;
+											}
+										}
+
+										devpriv->
+											s_ModuleInfo
+											[b_ModulNbr].
+											s_PWMModuleInfo.
+											s_PWMInfo
+											[b_PWM].
+											b_InterruptEnable
+											=
+											b_InterruptEnable;
+
+				      /*******************/
+										/* Set the command */
+				      /*******************/
+
+										outl(dw_Command, devpriv->s_BoardInfos.ui_Address + 8 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+				      /******************/
+										/* Enable the PWM */
+				      /******************/
+										outl(1, devpriv->s_BoardInfos.ui_Address + 12 + (20 * b_PWM) + (64 * b_ModulNbr));
+									}	// if (b_InterruptEnable == APCI1710_ENABLE || b_InterruptEnable == APCI1710_DISABLE)
+									else {
+				   /********************************/
+										/* Interrupt parameter is wrong */
+				   /********************************/
+										DPRINTK("Interrupt parameter is wrong\n");
+										i_ReturnValue
+											=
+											-10;
+									}	// if (b_InterruptEnable == APCI1710_ENABLE || b_InterruptEnable == APCI1710_DISABLE)
+								}	// if (b_ExternGate >= 0 && b_ExternGate <= 1)
+								else {
+				/*****************************************/
+									/* Extern gate signal selection is wrong */
+				/*****************************************/
+									DPRINTK("Extern gate signal selection is wrong\n");
+									i_ReturnValue
+										=
+										-9;
+								}	// if (b_ExternGate >= 0 && b_ExternGate <= 1)
+							}	// if (b_StopLevel >= 0 && b_StopLevel <= 2)
+							else {
+			     /*************************************/
+								/* PWM stop level selection is wrong */
+			     /*************************************/
+								DPRINTK("PWM stop level selection is wrong\n");
+								i_ReturnValue =
+									-8;
+							}	// if (b_StopLevel >= 0 && b_StopLevel <= 2)
+						}	// if (b_StopMode >= 0 && b_StopMode <= 1)
+						else {
+			  /************************************/
+							/* PWM stop mode selection is wrong */
+			  /************************************/
+							DPRINTK("PWM stop mode selection is wrong\n");
+							i_ReturnValue = -7;
+						}	// if (b_StopMode >= 0 && b_StopMode <= 1)
+					}	// if (b_StartLevel >= 0 && b_StartLevel <= 1)
+					else {
+		       /**************************************/
+						/* PWM start level selection is wrong */
+		       /**************************************/
+						DPRINTK("PWM start level selection is wrong\n");
+						i_ReturnValue = -6;
+					}	// if (b_StartLevel >= 0 && b_StartLevel <= 1)
+				}	// if (dw_Status & 0x10)
+				else {
+		    /***********************/
+					/* PWM not initialised */
+		    /***********************/
+					DPRINTK("PWM not initialised\n");
+					i_ReturnValue = -5;
+				}	// if (dw_Status & 0x10)
+			}	// if (b_PWM >= 0 && b_PWM <= 1)
+			else {
+		 /******************************/
+				/* Tor PWM selection is wrong */
+		 /******************************/
+				DPRINTK("Tor PWM selection is wrong\n");
+				i_ReturnValue = -4;
+			}	// if (b_PWM >= 0 && b_PWM <= 1)
+		} else {
+	      /**********************************/
+			/* The module is not a PWM module */
+	      /**********************************/
+			DPRINTK("The module is not a PWM module\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /***********************/
+		/* Module number error */
+	   /***********************/
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_DisablePWM (BYTE_  b_BoardHandle,     |
+|                                                  BYTE_  b_ModulNbr,        |
+|                                                  BYTE_  b_PWM)             |
++----------------------------------------------------------------------------+
+| Task              : Disable the selected PWM (b_PWM) from selected module  |
+|                     (b_ModulNbr). The output signal level depend of the    |
+|                     initialisation by the "i_APCI1710_EnablePWM".          |
+|                     See the b_StartLevel, b_StopMode and b_StopLevel       |
+|                     parameters from this function.                         |
++----------------------------------------------------------------------------+
+| Input Parameters  :BYTE_ b_BoardHandle : Handle of board APCI-1710         |
+|                    BYTE_ b_ModulNbr    : Selected module number (0 to 3)   |
+|                    BYTE_ b_PWM         : Selected PWM (0 or 1)             |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: Module selection wrong                             |
+|                     -3: The module is not a PWM module                     |
+|                     -4: PWM selection is wrong                             |
+|                     -5: PWM not initialised see function                   |
+|                         "i_APCI1710_InitPWM"                               |
+|                     -6: PWM not enabled see function                       |
+|                         "i_APCI1710_EnablePWM"                             |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_DisablePWM(struct comedi_device * dev, BYTE b_ModulNbr, BYTE b_PWM)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_Status;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /***************/
+		/* Test if PWM */
+	   /***************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_PWM) {
+	      /**************************/
+			/* Test the PWM selection */
+	      /**************************/
+
+			if (b_PWM <= 1) {
+		 /***************************/
+				/* Test if PWM initialised */
+		 /***************************/
+
+				dw_Status = inl(devpriv->s_BoardInfos.
+					ui_Address + 12 + (20 * b_PWM) +
+					(64 * b_ModulNbr));
+
+				if (dw_Status & 0x10) {
+		    /***********************/
+					/* Test if PWM enabled */
+		    /***********************/
+
+					if (dw_Status & 0x1) {
+		       /*******************/
+						/* Disable the PWM */
+		       /*******************/
+						outl(0, devpriv->s_BoardInfos.
+							ui_Address + 12 +
+							(20 * b_PWM) +
+							(64 * b_ModulNbr));
+					}	// if (dw_Status & 0x1)
+					else {
+		       /*******************/
+						/* PWM not enabled */
+		       /*******************/
+						DPRINTK("PWM not enabled\n");
+						i_ReturnValue = -6;
+					}	// if (dw_Status & 0x1)
+				}	// if (dw_Status & 0x10)
+				else {
+		    /***********************/
+					/* PWM not initialised */
+		    /***********************/
+					DPRINTK(" PWM not initialised\n");
+					i_ReturnValue = -5;
+				}	// if (dw_Status & 0x10)
+			}	// if (b_PWM >= 0 && b_PWM <= 1)
+			else {
+		 /******************************/
+				/* Tor PWM selection is wrong */
+		 /******************************/
+				DPRINTK("Tor PWM selection is wrong\n");
+				i_ReturnValue = -4;
+			}	// if (b_PWM >= 0 && b_PWM <= 1)
+		} else {
+	      /**********************************/
+			/* The module is not a PWM module */
+	      /**********************************/
+			DPRINTK("The module is not a PWM module\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /***********************/
+		/* Module number error */
+	   /***********************/
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_SetNewPWMTiming                       |
+|                                       (BYTE_     b_BoardHandle,            |
+|                                        BYTE_     b_ModulNbr,               |
+|                                        BYTE_     b_PWM,                    |
+|                                        BYTE_     b_ClockSelection,         |
+|                                        BYTE_     b_TimingUnit,             |
+|                                        ULONG_   ul_LowTiming,              |
+|                                        ULONG_   ul_HighTiming)             |
++----------------------------------------------------------------------------+
+| Task              : Set a new timing. The ul_LowTiming, ul_HighTiming and  |
+|                     ul_TimingUnit determine the low/high timing base for   |
+|                     the period.                                            |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_     b_BoardHandle    : Handle of board APCI-1710 |
+|                     BYTE_     b_ModulNbr       : Module number to configure|
+|                                                  (0 to 3)                  |
+|                     BYTE_     b_PWM            : Selected PWM (0 or 1).    |
+|                     BYTE_     b_TimingUnit     : Base timing Unit (0 to 4) |
+|                                                       0 : ns               |
+|                                                       1 : æs               |
+|                                                       2 : ms               |
+|                                                       3 : s                |
+|                                                       4 : mn               |
+|                     ULONG_    ul_LowTiming     : Low base timing value.    |
+|                     ULONG_    ul_HighTiming    : High base timing value.   |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : 0: No error                                            |
+|                    -1: The handle parameter of the board is wrong          |
+|                    -2: Module selection wrong                              |
+|                    -3: The module is not a PWM module                      |
+|                    -4: PWM selection is wrong                              |
+|                    -5: PWM not initialised                                 |
+|                    -6: Timing Unit selection is wrong                      |
+|                    -7: Low base timing selection is wrong                  |
+|                    -8: High base timing selection is wrong                 |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_SetNewPWMTiming(struct comedi_device * dev,
+	BYTE b_ModulNbr,
+	BYTE b_PWM, BYTE b_TimingUnit, ULONG ul_LowTiming, ULONG ul_HighTiming)
+{
+	BYTE b_ClockSelection;
+	INT i_ReturnValue = 0;
+	ULONG ul_LowTimerValue = 0;
+	ULONG ul_HighTimerValue = 0;
+	ULONG ul_RealLowTiming = 0;
+	ULONG ul_RealHighTiming = 0;
+	DWORD dw_Status;
+	DWORD dw_Command;
+	double d_RealLowTiming = 0;
+	double d_RealHighTiming = 0;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /***************/
+		/* Test if PWM */
+	   /***************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_PWM) {
+	      /**************************/
+			/* Test the PWM selection */
+	      /**************************/
+
+			if (b_PWM <= 1) {
+		 /***************************/
+				/* Test if PWM initialised */
+		 /***************************/
+
+				dw_Status = inl(devpriv->s_BoardInfos.
+					ui_Address + 12 + (20 * b_PWM) +
+					(64 * b_ModulNbr));
+
+				if (dw_Status & 0x10) {
+					b_ClockSelection = devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_PWMModuleInfo.
+						b_ClockSelection;
+
+		    /************************/
+					/* Test the timing unit */
+		    /************************/
+
+					if (b_TimingUnit <= 4) {
+		       /*********************************/
+						/* Test the low timing selection */
+		       /*********************************/
+
+						if (((b_ClockSelection ==
+									APCI1710_30MHZ)
+								&& (b_TimingUnit
+									== 0)
+								&& (ul_LowTiming
+									>= 266)
+								&& (ul_LowTiming
+									<=
+									0xFFFFFFFFUL))
+							|| ((b_ClockSelection ==
+									APCI1710_30MHZ)
+								&& (b_TimingUnit
+									== 1)
+								&& (ul_LowTiming
+									>= 1)
+								&& (ul_LowTiming
+									<=
+									571230650UL))
+							|| ((b_ClockSelection ==
+									APCI1710_30MHZ)
+								&& (b_TimingUnit
+									== 2)
+								&& (ul_LowTiming
+									>= 1)
+								&& (ul_LowTiming
+									<=
+									571230UL))
+							|| ((b_ClockSelection ==
+									APCI1710_30MHZ)
+								&& (b_TimingUnit
+									== 3)
+								&& (ul_LowTiming
+									>= 1)
+								&& (ul_LowTiming
+									<=
+									571UL))
+							|| ((b_ClockSelection ==
+									APCI1710_30MHZ)
+								&& (b_TimingUnit
+									== 4)
+								&& (ul_LowTiming
+									>= 1)
+								&& (ul_LowTiming
+									<= 9UL))
+							|| ((b_ClockSelection ==
+									APCI1710_33MHZ)
+								&& (b_TimingUnit
+									== 0)
+								&& (ul_LowTiming
+									>= 242)
+								&& (ul_LowTiming
+									<=
+									0xFFFFFFFFUL))
+							|| ((b_ClockSelection ==
+									APCI1710_33MHZ)
+								&& (b_TimingUnit
+									== 1)
+								&& (ul_LowTiming
+									>= 1)
+								&& (ul_LowTiming
+									<=
+									519691043UL))
+							|| ((b_ClockSelection ==
+									APCI1710_33MHZ)
+								&& (b_TimingUnit
+									== 2)
+								&& (ul_LowTiming
+									>= 1)
+								&& (ul_LowTiming
+									<=
+									519691UL))
+							|| ((b_ClockSelection ==
+									APCI1710_33MHZ)
+								&& (b_TimingUnit
+									== 3)
+								&& (ul_LowTiming
+									>= 1)
+								&& (ul_LowTiming
+									<=
+									520UL))
+							|| ((b_ClockSelection ==
+									APCI1710_33MHZ)
+								&& (b_TimingUnit
+									== 4)
+								&& (ul_LowTiming
+									>= 1)
+								&& (ul_LowTiming
+									<= 8UL))
+							|| ((b_ClockSelection ==
+									APCI1710_40MHZ)
+								&& (b_TimingUnit
+									== 0)
+								&& (ul_LowTiming
+									>= 200)
+								&& (ul_LowTiming
+									<=
+									0xFFFFFFFFUL))
+							|| ((b_ClockSelection ==
+									APCI1710_40MHZ)
+								&& (b_TimingUnit
+									== 1)
+								&& (ul_LowTiming
+									>= 1)
+								&& (ul_LowTiming
+									<=
+									429496729UL))
+							|| ((b_ClockSelection ==
+									APCI1710_40MHZ)
+								&& (b_TimingUnit
+									== 2)
+								&& (ul_LowTiming
+									>= 1)
+								&& (ul_LowTiming
+									<=
+									429496UL))
+							|| ((b_ClockSelection ==
+									APCI1710_40MHZ)
+								&& (b_TimingUnit
+									== 3)
+								&& (ul_LowTiming
+									>= 1)
+								&& (ul_LowTiming
+									<=
+									429UL))
+							|| ((b_ClockSelection ==
+									APCI1710_40MHZ)
+								&& (b_TimingUnit
+									== 4)
+								&& (ul_LowTiming
+									>= 1)
+								&& (ul_LowTiming
+									<=
+									7UL))) {
+			  /**********************************/
+							/* Test the High timing selection */
+			  /**********************************/
+
+							if (((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 266) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571230650UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571230UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 9UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 242) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 519691043UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 519691UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 520UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 8UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 200) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429496729UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429496UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 7UL))) {
+			     /************************************/
+								/* Calculate the low division fator */
+			     /************************************/
+
+								fpu_begin();
+								switch (b_TimingUnit) {
+				/******/
+									/* ns */
+				/******/
+
+								case 0:
+
+					/******************/
+									/* Timer 0 factor */
+					/******************/
+
+									ul_LowTimerValue
+										=
+										(ULONG)
+										(ul_LowTiming
+										*
+										(0.00025 * b_ClockSelection));
+
+					/*******************/
+									/* Round the value */
+					/*******************/
+
+									if ((double)((double)ul_LowTiming * (0.00025 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+										ul_LowTimerValue
+											=
+											ul_LowTimerValue
+											+
+											1;
+									}
+
+					/*****************************/
+									/* Calculate the real timing */
+					/*****************************/
+
+									ul_RealLowTiming
+										=
+										(ULONG)
+										(ul_LowTimerValue
+										/
+										(0.00025 * (double)b_ClockSelection));
+									d_RealLowTiming
+										=
+										(double)
+										ul_LowTimerValue
+										/
+										(0.00025
+										*
+										(double)
+										b_ClockSelection);
+
+									if ((double)((double)ul_LowTimerValue / (0.00025 * (double)b_ClockSelection)) >= (double)((double)ul_RealLowTiming + 0.5)) {
+										ul_RealLowTiming
+											=
+											ul_RealLowTiming
+											+
+											1;
+									}
+
+									ul_LowTiming
+										=
+										ul_LowTiming
+										-
+										1;
+									ul_LowTimerValue
+										=
+										ul_LowTimerValue
+										-
+										2;
+
+									if (b_ClockSelection != APCI1710_40MHZ) {
+										ul_LowTimerValue
+											=
+											(ULONG)
+											(
+											(double)
+											(ul_LowTimerValue)
+											*
+											1.007752288);
+									}
+
+									break;
+
+				/******/
+									/* æs */
+				/******/
+
+								case 1:
+
+					/******************/
+									/* Timer 0 factor */
+					/******************/
+
+									ul_LowTimerValue
+										=
+										(ULONG)
+										(ul_LowTiming
+										*
+										(0.25 * b_ClockSelection));
+
+					/*******************/
+									/* Round the value */
+					/*******************/
+
+									if ((double)((double)ul_LowTiming * (0.25 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+										ul_LowTimerValue
+											=
+											ul_LowTimerValue
+											+
+											1;
+									}
+
+					/*****************************/
+									/* Calculate the real timing */
+					/*****************************/
+
+									ul_RealLowTiming
+										=
+										(ULONG)
+										(ul_LowTimerValue
+										/
+										(0.25 * (double)b_ClockSelection));
+									d_RealLowTiming
+										=
+										(double)
+										ul_LowTimerValue
+										/
+										(
+										(double)
+										0.25
+										*
+										(double)
+										b_ClockSelection);
+
+									if ((double)((double)ul_LowTimerValue / (0.25 * (double)b_ClockSelection)) >= (double)((double)ul_RealLowTiming + 0.5)) {
+										ul_RealLowTiming
+											=
+											ul_RealLowTiming
+											+
+											1;
+									}
+
+									ul_LowTiming
+										=
+										ul_LowTiming
+										-
+										1;
+									ul_LowTimerValue
+										=
+										ul_LowTimerValue
+										-
+										2;
+
+									if (b_ClockSelection != APCI1710_40MHZ) {
+										ul_LowTimerValue
+											=
+											(ULONG)
+											(
+											(double)
+											(ul_LowTimerValue)
+											*
+											1.007752288);
+									}
+
+									break;
+
+				/******/
+									/* ms */
+				/******/
+
+								case 2:
+
+					/******************/
+									/* Timer 0 factor */
+					/******************/
+
+									ul_LowTimerValue
+										=
+										ul_LowTiming
+										*
+										(250.0
+										*
+										b_ClockSelection);
+
+					/*******************/
+									/* Round the value */
+					/*******************/
+
+									if ((double)((double)ul_LowTiming * (250.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+										ul_LowTimerValue
+											=
+											ul_LowTimerValue
+											+
+											1;
+									}
+
+					/*****************************/
+									/* Calculate the real timing */
+					/*****************************/
+
+									ul_RealLowTiming
+										=
+										(ULONG)
+										(ul_LowTimerValue
+										/
+										(250.0 * (double)b_ClockSelection));
+									d_RealLowTiming
+										=
+										(double)
+										ul_LowTimerValue
+										/
+										(250.0
+										*
+										(double)
+										b_ClockSelection);
+
+									if ((double)((double)ul_LowTimerValue / (250.0 * (double)b_ClockSelection)) >= (double)((double)ul_RealLowTiming + 0.5)) {
+										ul_RealLowTiming
+											=
+											ul_RealLowTiming
+											+
+											1;
+									}
+
+									ul_LowTiming
+										=
+										ul_LowTiming
+										-
+										1;
+									ul_LowTimerValue
+										=
+										ul_LowTimerValue
+										-
+										2;
+
+									if (b_ClockSelection != APCI1710_40MHZ) {
+										ul_LowTimerValue
+											=
+											(ULONG)
+											(
+											(double)
+											(ul_LowTimerValue)
+											*
+											1.007752288);
+									}
+
+									break;
+
+				/*****/
+									/* s */
+				/*****/
+
+								case 3:
+
+					/******************/
+									/* Timer 0 factor */
+					/******************/
+
+									ul_LowTimerValue
+										=
+										(ULONG)
+										(ul_LowTiming
+										*
+										(250000.0
+											*
+											b_ClockSelection));
+
+					/*******************/
+									/* Round the value */
+					/*******************/
+
+									if ((double)((double)ul_LowTiming * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+										ul_LowTimerValue
+											=
+											ul_LowTimerValue
+											+
+											1;
+									}
+
+					/*****************************/
+									/* Calculate the real timing */
+					/*****************************/
+
+									ul_RealLowTiming
+										=
+										(ULONG)
+										(ul_LowTimerValue
+										/
+										(250000.0
+											*
+											(double)
+											b_ClockSelection));
+									d_RealLowTiming
+										=
+										(double)
+										ul_LowTimerValue
+										/
+										(250000.0
+										*
+										(double)
+										b_ClockSelection);
+
+									if ((double)((double)ul_LowTimerValue / (250000.0 * (double)b_ClockSelection)) >= (double)((double)ul_RealLowTiming + 0.5)) {
+										ul_RealLowTiming
+											=
+											ul_RealLowTiming
+											+
+											1;
+									}
+
+									ul_LowTiming
+										=
+										ul_LowTiming
+										-
+										1;
+									ul_LowTimerValue
+										=
+										ul_LowTimerValue
+										-
+										2;
+
+									if (b_ClockSelection != APCI1710_40MHZ) {
+										ul_LowTimerValue
+											=
+											(ULONG)
+											(
+											(double)
+											(ul_LowTimerValue)
+											*
+											1.007752288);
+									}
+
+									break;
+
+				/******/
+									/* mn */
+				/******/
+
+								case 4:
+
+					/******************/
+									/* Timer 0 factor */
+					/******************/
+
+									ul_LowTimerValue
+										=
+										(ULONG)
+										(
+										(ul_LowTiming
+											*
+											60)
+										*
+										(250000.0
+											*
+											b_ClockSelection));
+
+					/*******************/
+									/* Round the value */
+					/*******************/
+
+									if ((double)((double)(ul_LowTiming * 60.0) * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+										ul_LowTimerValue
+											=
+											ul_LowTimerValue
+											+
+											1;
+									}
+
+					/*****************************/
+									/* Calculate the real timing */
+					/*****************************/
+
+									ul_RealLowTiming
+										=
+										(ULONG)
+										(ul_LowTimerValue
+										/
+										(250000.0
+											*
+											(double)
+											b_ClockSelection))
+										/
+										60;
+									d_RealLowTiming
+										=
+										(
+										(double)
+										ul_LowTimerValue
+										/
+										(250000.0
+											*
+											(double)
+											b_ClockSelection))
+										/
+										60.0;
+
+									if ((double)(((double)ul_LowTimerValue / (250000.0 * (double)b_ClockSelection)) / 60.0) >= (double)((double)ul_RealLowTiming + 0.5)) {
+										ul_RealLowTiming
+											=
+											ul_RealLowTiming
+											+
+											1;
+									}
+
+									ul_LowTiming
+										=
+										ul_LowTiming
+										-
+										1;
+									ul_LowTimerValue
+										=
+										ul_LowTimerValue
+										-
+										2;
+
+									if (b_ClockSelection != APCI1710_40MHZ) {
+										ul_LowTimerValue
+											=
+											(ULONG)
+											(
+											(double)
+											(ul_LowTimerValue)
+											*
+											1.007752288);
+									}
+
+									break;
+								}
+
+			     /*************************************/
+								/* Calculate the high division fator */
+			     /*************************************/
+
+								switch (b_TimingUnit) {
+				/******/
+									/* ns */
+				/******/
+
+								case 0:
+
+					/******************/
+									/* Timer 0 factor */
+					/******************/
+
+									ul_HighTimerValue
+										=
+										(ULONG)
+										(ul_HighTiming
+										*
+										(0.00025 * b_ClockSelection));
+
+					/*******************/
+									/* Round the value */
+					/*******************/
+
+									if ((double)((double)ul_HighTiming * (0.00025 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+										ul_HighTimerValue
+											=
+											ul_HighTimerValue
+											+
+											1;
+									}
+
+					/*****************************/
+									/* Calculate the real timing */
+					/*****************************/
+
+									ul_RealHighTiming
+										=
+										(ULONG)
+										(ul_HighTimerValue
+										/
+										(0.00025 * (double)b_ClockSelection));
+									d_RealHighTiming
+										=
+										(double)
+										ul_HighTimerValue
+										/
+										(0.00025
+										*
+										(double)
+										b_ClockSelection);
+
+									if ((double)((double)ul_HighTimerValue / (0.00025 * (double)b_ClockSelection)) >= (double)((double)ul_RealHighTiming + 0.5)) {
+										ul_RealHighTiming
+											=
+											ul_RealHighTiming
+											+
+											1;
+									}
+
+									ul_HighTiming
+										=
+										ul_HighTiming
+										-
+										1;
+									ul_HighTimerValue
+										=
+										ul_HighTimerValue
+										-
+										2;
+
+									if (b_ClockSelection != APCI1710_40MHZ) {
+										ul_HighTimerValue
+											=
+											(ULONG)
+											(
+											(double)
+											(ul_HighTimerValue)
+											*
+											1.007752288);
+									}
+
+									break;
+
+				/******/
+									/* æs */
+				/******/
+
+								case 1:
+
+					/******************/
+									/* Timer 0 factor */
+					/******************/
+
+									ul_HighTimerValue
+										=
+										(ULONG)
+										(ul_HighTiming
+										*
+										(0.25 * b_ClockSelection));
+
+					/*******************/
+									/* Round the value */
+					/*******************/
+
+									if ((double)((double)ul_HighTiming * (0.25 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+										ul_HighTimerValue
+											=
+											ul_HighTimerValue
+											+
+											1;
+									}
+
+					/*****************************/
+									/* Calculate the real timing */
+					/*****************************/
+
+									ul_RealHighTiming
+										=
+										(ULONG)
+										(ul_HighTimerValue
+										/
+										(0.25 * (double)b_ClockSelection));
+									d_RealHighTiming
+										=
+										(double)
+										ul_HighTimerValue
+										/
+										(
+										(double)
+										0.25
+										*
+										(double)
+										b_ClockSelection);
+
+									if ((double)((double)ul_HighTimerValue / (0.25 * (double)b_ClockSelection)) >= (double)((double)ul_RealHighTiming + 0.5)) {
+										ul_RealHighTiming
+											=
+											ul_RealHighTiming
+											+
+											1;
+									}
+
+									ul_HighTiming
+										=
+										ul_HighTiming
+										-
+										1;
+									ul_HighTimerValue
+										=
+										ul_HighTimerValue
+										-
+										2;
+
+									if (b_ClockSelection != APCI1710_40MHZ) {
+										ul_HighTimerValue
+											=
+											(ULONG)
+											(
+											(double)
+											(ul_HighTimerValue)
+											*
+											1.007752288);
+									}
+
+									break;
+
+				/******/
+									/* ms */
+				/******/
+
+								case 2:
+
+					/******************/
+									/* Timer 0 factor */
+					/******************/
+
+									ul_HighTimerValue
+										=
+										ul_HighTiming
+										*
+										(250.0
+										*
+										b_ClockSelection);
+
+					/*******************/
+									/* Round the value */
+					/*******************/
+
+									if ((double)((double)ul_HighTiming * (250.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+										ul_HighTimerValue
+											=
+											ul_HighTimerValue
+											+
+											1;
+									}
+
+					/*****************************/
+									/* Calculate the real timing */
+					/*****************************/
+
+									ul_RealHighTiming
+										=
+										(ULONG)
+										(ul_HighTimerValue
+										/
+										(250.0 * (double)b_ClockSelection));
+									d_RealHighTiming
+										=
+										(double)
+										ul_HighTimerValue
+										/
+										(250.0
+										*
+										(double)
+										b_ClockSelection);
+
+									if ((double)((double)ul_HighTimerValue / (250.0 * (double)b_ClockSelection)) >= (double)((double)ul_RealHighTiming + 0.5)) {
+										ul_RealHighTiming
+											=
+											ul_RealHighTiming
+											+
+											1;
+									}
+
+									ul_HighTiming
+										=
+										ul_HighTiming
+										-
+										1;
+									ul_HighTimerValue
+										=
+										ul_HighTimerValue
+										-
+										2;
+
+									if (b_ClockSelection != APCI1710_40MHZ) {
+										ul_HighTimerValue
+											=
+											(ULONG)
+											(
+											(double)
+											(ul_HighTimerValue)
+											*
+											1.007752288);
+									}
+
+									break;
+
+				/*****/
+									/* s */
+				/*****/
+
+								case 3:
+
+					/******************/
+									/* Timer 0 factor */
+					/******************/
+
+									ul_HighTimerValue
+										=
+										(ULONG)
+										(ul_HighTiming
+										*
+										(250000.0
+											*
+											b_ClockSelection));
+
+					/*******************/
+									/* Round the value */
+					/*******************/
+
+									if ((double)((double)ul_HighTiming * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+										ul_HighTimerValue
+											=
+											ul_HighTimerValue
+											+
+											1;
+									}
+
+					/*****************************/
+									/* Calculate the real timing */
+					/*****************************/
+
+									ul_RealHighTiming
+										=
+										(ULONG)
+										(ul_HighTimerValue
+										/
+										(250000.0
+											*
+											(double)
+											b_ClockSelection));
+									d_RealHighTiming
+										=
+										(double)
+										ul_HighTimerValue
+										/
+										(250000.0
+										*
+										(double)
+										b_ClockSelection);
+
+									if ((double)((double)ul_HighTimerValue / (250000.0 * (double)b_ClockSelection)) >= (double)((double)ul_RealHighTiming + 0.5)) {
+										ul_RealHighTiming
+											=
+											ul_RealHighTiming
+											+
+											1;
+									}
+
+									ul_HighTiming
+										=
+										ul_HighTiming
+										-
+										1;
+									ul_HighTimerValue
+										=
+										ul_HighTimerValue
+										-
+										2;
+
+									if (b_ClockSelection != APCI1710_40MHZ) {
+										ul_HighTimerValue
+											=
+											(ULONG)
+											(
+											(double)
+											(ul_HighTimerValue)
+											*
+											1.007752288);
+									}
+
+									break;
+
+				/******/
+									/* mn */
+				/******/
+
+								case 4:
+
+					/******************/
+									/* Timer 0 factor */
+					/******************/
+
+									ul_HighTimerValue
+										=
+										(ULONG)
+										(
+										(ul_HighTiming
+											*
+											60)
+										*
+										(250000.0
+											*
+											b_ClockSelection));
+
+					/*******************/
+									/* Round the value */
+					/*******************/
+
+									if ((double)((double)(ul_HighTiming * 60.0) * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+										ul_HighTimerValue
+											=
+											ul_HighTimerValue
+											+
+											1;
+									}
+
+					/*****************************/
+									/* Calculate the real timing */
+					/*****************************/
+
+									ul_RealHighTiming
+										=
+										(ULONG)
+										(ul_HighTimerValue
+										/
+										(250000.0
+											*
+											(double)
+											b_ClockSelection))
+										/
+										60;
+									d_RealHighTiming
+										=
+										(
+										(double)
+										ul_HighTimerValue
+										/
+										(250000.0
+											*
+											(double)
+											b_ClockSelection))
+										/
+										60.0;
+
+									if ((double)(((double)ul_HighTimerValue / (250000.0 * (double)b_ClockSelection)) / 60.0) >= (double)((double)ul_RealHighTiming + 0.5)) {
+										ul_RealHighTiming
+											=
+											ul_RealHighTiming
+											+
+											1;
+									}
+
+									ul_HighTiming
+										=
+										ul_HighTiming
+										-
+										1;
+									ul_HighTimerValue
+										=
+										ul_HighTimerValue
+										-
+										2;
+
+									if (b_ClockSelection != APCI1710_40MHZ) {
+										ul_HighTimerValue
+											=
+											(ULONG)
+											(
+											(double)
+											(ul_HighTimerValue)
+											*
+											1.007752288);
+									}
+
+									break;
+								}
+
+								fpu_end();
+
+			     /************************/
+								/* Save the timing unit */
+			     /************************/
+
+								devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_PWMModuleInfo.
+									s_PWMInfo
+									[b_PWM].
+									b_TimingUnit
+									=
+									b_TimingUnit;
+
+			     /****************************/
+								/* Save the low base timing */
+			     /****************************/
+
+								devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_PWMModuleInfo.
+									s_PWMInfo
+									[b_PWM].
+									d_LowTiming
+									=
+									d_RealLowTiming;
+
+								devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_PWMModuleInfo.
+									s_PWMInfo
+									[b_PWM].
+									ul_RealLowTiming
+									=
+									ul_RealLowTiming;
+
+			     /****************************/
+								/* Save the high base timing */
+			     /****************************/
+
+								devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_PWMModuleInfo.
+									s_PWMInfo
+									[b_PWM].
+									d_HighTiming
+									=
+									d_RealHighTiming;
+
+								devpriv->
+									s_ModuleInfo
+									[b_ModulNbr].
+									s_PWMModuleInfo.
+									s_PWMInfo
+									[b_PWM].
+									ul_RealHighTiming
+									=
+									ul_RealHighTiming;
+
+			     /************************/
+								/* Write the low timing */
+			     /************************/
+
+								outl(ul_LowTimerValue, devpriv->s_BoardInfos.ui_Address + 0 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+			     /*************************/
+								/* Write the high timing */
+			     /*************************/
+
+								outl(ul_HighTimerValue, devpriv->s_BoardInfos.ui_Address + 4 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+			     /***************************/
+								/* Set the clock selection */
+			     /***************************/
+
+								dw_Command =
+									inl
+									(devpriv->
+									s_BoardInfos.
+									ui_Address
+									+ 8 +
+									(20 * b_PWM) + (64 * b_ModulNbr));
+
+								dw_Command =
+									dw_Command
+									& 0x7F;
+
+								if (b_ClockSelection == APCI1710_40MHZ) {
+									dw_Command
+										=
+										dw_Command
+										|
+										0x80;
+								}
+
+			     /***************************/
+								/* Set the clock selection */
+			     /***************************/
+
+								outl(dw_Command,
+									devpriv->
+									s_BoardInfos.
+									ui_Address
+									+ 8 +
+									(20 * b_PWM) + (64 * b_ModulNbr));
+							} else {
+			     /***************************************/
+								/* High base timing selection is wrong */
+			     /***************************************/
+								DPRINTK("High base timing selection is wrong\n");
+								i_ReturnValue =
+									-8;
+							}
+						} else {
+			  /**************************************/
+							/* Low base timing selection is wrong */
+			  /**************************************/
+							DPRINTK("Low base timing selection is wrong\n");
+							i_ReturnValue = -7;
+						}
+					}	// if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+					else {
+		       /**********************************/
+						/* Timing unit selection is wrong */
+		       /**********************************/
+						DPRINTK("Timing unit selection is wrong\n");
+						i_ReturnValue = -6;
+					}	// if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+				}	// if (dw_Status & 0x10)
+				else {
+		    /***********************/
+					/* PWM not initialised */
+		    /***********************/
+					DPRINTK("PWM not initialised\n");
+					i_ReturnValue = -5;
+				}	// if (dw_Status & 0x10)
+			}	// if (b_PWM >= 0 && b_PWM <= 1)
+			else {
+		 /******************************/
+				/* Tor PWM selection is wrong */
+		 /******************************/
+				DPRINTK("Tor PWM selection is wrong\n");
+				i_ReturnValue = -4;
+			}	// if (b_PWM >= 0 && b_PWM <= 1)
+		} else {
+	      /**********************************/
+			/* The module is not a PWM module */
+	      /**********************************/
+			DPRINTK("The module is not a PWM module\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /***********************/
+		/* Module number error */
+	   /***********************/
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_GetPWMStatus                          |
+|                               (BYTE_    b_BoardHandle,                     |
+|                                BYTE_    b_ModulNbr,                        |
+|                                BYTE_    b_PWM,                             |
+|                                PBYTE_  pb_PWMOutputStatus,                 |
+|                                PBYTE_  pb_ExternGateStatus)                |
++----------------------------------------------------------------------------+
+| Task              : Return the status from selected PWM (b_PWM) from       |
+|                     selected module (b_ModulNbr).                          |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_  b_BoardHandle : Handle of board APCI-1710       |
+|                     BYTE_  b_PWM         : Selected PWM (0 or 1)           |
+|                     BYTE_  b_ModulNbr    : Selected module number (0 to 3)
+	b_ModulNbr			=(BYTE)  CR_AREF(insn->chanspec);
+	b_PWM				=(BYTE)  data[0];
+
+ |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_  pb_PWMOutputStatus  : Return the PWM output    |
+|                                                   level status.            |
+|                                                    0 : The PWM output level|
+|                                                        is low.             |
+|                                                    1 : The PWM output level|
+|                                                        is high.            |
+|                     PBYTE_  pb_ExternGateStatus : Return the extern gate   |
+|                                                   level status.            |
+|                                                    0 : The extern gate is  |
+|                                                        low.                |
+|                                                    1 : The extern gate is  |
+|                                                        high.
+    pb_PWMOutputStatus	=(PBYTE) data[0];
+	pb_ExternGateStatus =(PBYTE) data[1];             |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: Module selection wrong                             |
+|                     -3: The module is not a PWM module                     |
+|                     -4: PWM selection is wrong                             |
+|                     -5: PWM not initialised see function                   |
+|                         "i_APCI1710_InitPWM"                               |
+|                     -6: PWM not enabled see function "i_APCI1710_EnablePWM"|
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnReadGetPWMStatus(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_Status;
+
+	BYTE b_ModulNbr;
+	BYTE b_PWM;
+	PBYTE pb_PWMOutputStatus;
+	PBYTE pb_ExternGateStatus;
+
+	i_ReturnValue = insn->n;
+	b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+	b_PWM = (BYTE) CR_CHAN(insn->chanspec);
+	pb_PWMOutputStatus = (PBYTE) & data[0];
+	pb_ExternGateStatus = (PBYTE) & data[1];
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /***************/
+		/* Test if PWM */
+	   /***************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_PWM) {
+	      /**************************/
+			/* Test the PWM selection */
+	      /**************************/
+
+			if (b_PWM <= 1) {
+		 /***************************/
+				/* Test if PWM initialised */
+		 /***************************/
+
+				dw_Status = inl(devpriv->s_BoardInfos.
+					ui_Address + 12 + (20 * b_PWM) +
+					(64 * b_ModulNbr));
+
+				if (dw_Status & 0x10) {
+		    /***********************/
+					/* Test if PWM enabled */
+		    /***********************/
+
+					if (dw_Status & 0x1) {
+						*pb_PWMOutputStatus =
+							(BYTE) ((dw_Status >> 7)
+							& 1);
+						*pb_ExternGateStatus =
+							(BYTE) ((dw_Status >> 6)
+							& 1);
+					}	// if (dw_Status & 0x1)
+					else {
+		       /*******************/
+						/* PWM not enabled */
+		       /*******************/
+
+						DPRINTK("PWM not enabled \n");
+						i_ReturnValue = -6;
+					}	// if (dw_Status & 0x1)
+				}	// if (dw_Status & 0x10)
+				else {
+		    /***********************/
+					/* PWM not initialised */
+		    /***********************/
+
+					DPRINTK("PWM not initialised\n");
+					i_ReturnValue = -5;
+				}	// if (dw_Status & 0x10)
+			}	// if (b_PWM >= 0 && b_PWM <= 1)
+			else {
+		 /******************************/
+				/* Tor PWM selection is wrong */
+		 /******************************/
+
+				DPRINTK("Tor PWM selection is wrong\n");
+				i_ReturnValue = -4;
+			}	// if (b_PWM >= 0 && b_PWM <= 1)
+		} else {
+	      /**********************************/
+			/* The module is not a PWM module */
+	      /**********************************/
+
+			DPRINTK("The module is not a PWM module\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /***********************/
+		/* Module number error */
+	   /***********************/
+
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+INT i_APCI1710_InsnBitsReadPWMInterrupt(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	data[0] = devpriv->s_InterruptParameters.
+		s_FIFOInterruptParameters[devpriv->
+		s_InterruptParameters.ui_Read].b_OldModuleMask;
+	data[1] = devpriv->s_InterruptParameters.
+		s_FIFOInterruptParameters[devpriv->
+		s_InterruptParameters.ui_Read].ul_OldInterruptMask;
+	data[2] = devpriv->s_InterruptParameters.
+		s_FIFOInterruptParameters[devpriv->
+		s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
+
+			     /**************************/
+	/* Increment the read FIFO */
+			     /***************************/
+
+	devpriv->
+		s_InterruptParameters.
+		ui_Read = (devpriv->
+		s_InterruptParameters.ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+
+	return insn->n;
+
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h
new file mode 100644
index 0000000..c1b7f4ca
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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.
+ */
+
+#define APCI1710_30MHZ		30
+#define APCI1710_33MHZ		33
+#define APCI1710_40MHZ		40
+
+#define APCI1710_PWM_INIT		0
+#define APCI1710_PWM_GETINITDATA	1
+
+#define APCI1710_PWM_DISABLE		0
+#define APCI1710_PWM_ENABLE		1
+#define APCI1710_PWM_NEWTIMING		2
+
+INT i_APCI1710_InsnConfigPWM(struct comedi_device *dev, struct comedi_subdevice *s,
+			     struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InitPWM(struct comedi_device *dev,
+		       BYTE b_ModulNbr,
+		       BYTE b_PWM,
+		       BYTE b_ClockSelection,
+		       BYTE b_TimingUnit,
+		       ULONG ul_LowTiming,
+		       ULONG ul_HighTiming,
+		       PULONG pul_RealLowTiming, PULONG pul_RealHighTiming);
+
+INT i_APCI1710_GetPWMInitialisation(struct comedi_device *dev,
+				    BYTE b_ModulNbr,
+				    BYTE b_PWM,
+				    PBYTE pb_TimingUnit,
+				    PULONG pul_LowTiming,
+				    PULONG pul_HighTiming,
+				    PBYTE pb_StartLevel,
+				    PBYTE pb_StopMode,
+				    PBYTE pb_StopLevel,
+				    PBYTE pb_ExternGate,
+				    PBYTE pb_InterruptEnable, PBYTE pb_Enable);
+
+INT i_APCI1710_InsnWritePWM(struct comedi_device *dev, struct comedi_subdevice *s,
+			    struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_EnablePWM(struct comedi_device *dev,
+			 BYTE b_ModulNbr,
+			 BYTE b_PWM,
+			 BYTE b_StartLevel,
+			 BYTE b_StopMode,
+			 BYTE b_StopLevel, BYTE b_ExternGate,
+			 BYTE b_InterruptEnable);
+
+INT i_APCI1710_SetNewPWMTiming(struct comedi_device *dev,
+			       BYTE b_ModulNbr,
+			       BYTE b_PWM, BYTE b_TimingUnit,
+			       ULONG ul_LowTiming, ULONG ul_HighTiming);
+
+INT i_APCI1710_DisablePWM(struct comedi_device *dev, BYTE b_ModulNbr, BYTE b_PWM);
+
+INT i_APCI1710_InsnReadGetPWMStatus(struct comedi_device *dev, struct comedi_subdevice *s,
+				    struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnBitsReadPWMInterrupt(struct comedi_device *dev,
+					struct comedi_subdevice *s,
+					struct comedi_insn *insn, unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c
new file mode 100644
index 0000000..bb6e162
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c
@@ -0,0 +1,848 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+
+        ADDI-DATA GmbH
+        Dieselstrasse 3
+        D-77833 Ottersweier
+        Tel: +19(0)7223/9493-0
+        Fax: +49(0)7223/9493-92
+        http://www.addi-data-com
+        info@addi-data.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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+  +-----------------------------------------------------------------------+
+  | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
+  +-----------------------------------------------------------------------+
+  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
+  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
+  +-----------------------------------------------------------------------+
+  | Project     : API APCI1710    | Compiler : gcc                        |
+  | Module name : SSI.C           | Version  : 2.96                       |
+  +-------------------------------+---------------------------------------+
+  | Project manager: Eric Stolz   | Date     :  02/12/2002                |
+  +-----------------------------------------------------------------------+
+  | Description :   APCI-1710 SSI counter module                          |
+  |                                                                       |
+  |                                                                       |
+  +-----------------------------------------------------------------------+
+  |                             UPDATES                                   |
+  +-----------------------------------------------------------------------+
+  |   Date   |   Author  |          Description of updates                |
+  +----------+-----------+------------------------------------------------+
+  | 13/05/98 | S. Weber  | SSI digital input / output implementation      |
+  |----------|-----------|------------------------------------------------|
+  | 22/03/00 | C.Guinot  | 0100/0226 -> 0200/0227                         |
+  |          |           | Änderung in InitSSI Funktion                   |
+  |          |           | b_SSIProfile >= 2 anstatt b_SSIProfile > 2     |
+  |          |           |                                                |
+  +-----------------------------------------------------------------------+
+  | 08/05/00 | Guinot C  | - 0400/0228 All Function in RING 0             |
+  |          |           |   available                                    |
+  +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+|                               Included files                               |
++----------------------------------------------------------------------------+
+*/
+
+#include "APCI1710_Ssi.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_InitSSI                               |
+|                               (BYTE_    b_BoardHandle,                     |
+|                                BYTE_    b_ModulNbr,                        |
+|                                BYTE_    b_SSIProfile,                      |
+|                                BYTE_    b_PositionTurnLength,              |
+|                                BYTE_    b_TurnCptLength,                   |
+|                                BYTE_    b_PCIInputClock,                   |
+|                                ULONG_  ul_SSIOutputClock,                  |
+|                                BYTE_    b_SSICountingMode)                 |
++----------------------------------------------------------------------------+
+| Task              : Configure the SSI operating mode from selected module  |
+|                     (b_ModulNbr). You must calling this function be for you|
+|                     call any other function witch access of SSI.           |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle         : Handle of board APCI-1710|
+|                     BYTE_ b_ModulNbr            : Module number to         |
+|                                                   configure (0 to 3)       |
+|                     BYTE_  b_SSIProfile         : Selection from SSI       |
+|                                                   profile length (2 to 32).|
+|                     BYTE_  b_PositionTurnLength : Selection from SSI       |
+|                                                   position data length     |
+|                                                   (1 to 31).               |
+|                     BYTE_  b_TurnCptLength      : Selection from SSI turn  |
+|                                                   counter data length      |
+|                                                   (1 to 31).               |
+|                     BYTE   b_PCIInputClock      : Selection from PCI bus   |
+|                                                   clock                    |
+|                                                 - APCI1710_30MHZ :         |
+|                                                   The PC have a PCI bus    |
+|                                                   clock from 30 MHz        |
+|                                                 - APCI1710_33MHZ :         |
+|                                                   The PC have a PCI bus    |
+|                                                   clock from 33 MHz        |
+|                     ULONG_ ul_SSIOutputClock    : Selection from SSI output|
+|                                                   clock.                   |
+|                                                   From  229 to 5 000 000 Hz|
+|                                                   for 30 MHz selection.    |
+|                                                   From  252 to 5 000 000 Hz|
+|                                                   for 33 MHz selection.    |
+|                     BYTE   b_SSICountingMode    : SSI counting mode        |
+|                                                   selection                |
+|                                                 - APCI1710_BINARY_MODE :   |
+|                                                    Binary counting mode.   |
+|                                                 - APCI1710_GRAY_MODE :     |
+|                                                    Gray counting mode.
+
+	b_ModulNbr			= CR_AREF(insn->chanspec);
+	b_SSIProfile		= (BYTE) data[0];
+	b_PositionTurnLength= (BYTE) data[1];
+	b_TurnCptLength		= (BYTE) data[2];
+	b_PCIInputClock		= (BYTE) data[3];
+	ul_SSIOutputClock	= (ULONG) data[4];
+	b_SSICountingMode	= (BYTE)  data[5];     |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : 0: No error                                            |
+|                    -1: The handle parameter of the board is wrong          |
+|                    -2: The module parameter is wrong                       |
+|                    -3: The module is not a SSI module                      |
+|                    -4: The selected SSI profile length is wrong            |
+|                    -5: The selected SSI position data length is wrong      |
+|                    -6: The selected SSI turn counter data length is wrong  |
+|                    -7: The selected PCI input clock is wrong               |
+|                    -8: The selected SSI output clock is wrong              |
+|                    -9: The selected SSI counting mode parameter is wrong   |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigInitSSI(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = 0;
+	UINT ui_TimerValue;
+	BYTE b_ModulNbr, b_SSIProfile, b_PositionTurnLength, b_TurnCptLength,
+		b_PCIInputClock, b_SSICountingMode;
+	ULONG ul_SSIOutputClock;
+
+	b_ModulNbr = CR_AREF(insn->chanspec);
+	b_SSIProfile = (BYTE) data[0];
+	b_PositionTurnLength = (BYTE) data[1];
+	b_TurnCptLength = (BYTE) data[2];
+	b_PCIInputClock = (BYTE) data[3];
+	ul_SSIOutputClock = (ULONG) data[4];
+	b_SSICountingMode = (BYTE) data[5];
+
+	i_ReturnValue = insn->n;
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /***********************/
+		/* Test if SSI counter */
+	   /***********************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_SSI_COUNTER) {
+	      /*******************************/
+			/* Test the SSI profile length */
+	      /*******************************/
+
+			// CG 22/03/00 b_SSIProfile >= 2 anstatt b_SSIProfile > 2
+			if (b_SSIProfile >= 2 && b_SSIProfile < 33) {
+		 /*************************************/
+				/* Test the SSI position data length */
+		 /*************************************/
+
+				if (b_PositionTurnLength > 0
+					&& b_PositionTurnLength < 32) {
+		    /*****************************************/
+					/* Test the SSI turn counter data length */
+		    /*****************************************/
+
+					if (b_TurnCptLength > 0
+						&& b_TurnCptLength < 32) {
+		       /***************************/
+						/* Test the profile length */
+		       /***************************/
+
+						if ((b_TurnCptLength +
+								b_PositionTurnLength)
+							<= b_SSIProfile) {
+			  /****************************/
+							/* Test the PCI input clock */
+			  /****************************/
+
+							if (b_PCIInputClock ==
+								APCI1710_30MHZ
+								||
+								b_PCIInputClock
+								==
+								APCI1710_33MHZ)
+							{
+			     /*************************/
+								/* Test the output clock */
+			     /*************************/
+
+								if ((b_PCIInputClock == APCI1710_30MHZ && (ul_SSIOutputClock > 228 && ul_SSIOutputClock <= 5000000UL)) || (b_PCIInputClock == APCI1710_33MHZ && (ul_SSIOutputClock > 251 && ul_SSIOutputClock <= 5000000UL))) {
+									if (b_SSICountingMode == APCI1710_BINARY_MODE || b_SSICountingMode == APCI1710_GRAY_MODE) {
+				   /**********************/
+										/* Save configuration */
+				   /**********************/
+										devpriv->
+											s_ModuleInfo
+											[b_ModulNbr].
+											s_SSICounterInfo.
+											b_SSIProfile
+											=
+											b_SSIProfile;
+
+										devpriv->
+											s_ModuleInfo
+											[b_ModulNbr].
+											s_SSICounterInfo.
+											b_PositionTurnLength
+											=
+											b_PositionTurnLength;
+
+										devpriv->
+											s_ModuleInfo
+											[b_ModulNbr].
+											s_SSICounterInfo.
+											b_TurnCptLength
+											=
+											b_TurnCptLength;
+
+				   /*********************************/
+										/* Initialise the profile length */
+				   /*********************************/
+
+										if (b_SSICountingMode == APCI1710_BINARY_MODE) {
+
+											outl(b_SSIProfile + 1, devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr));
+										} else {
+
+											outl(b_SSIProfile, devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr));
+										}
+
+				   /******************************/
+										/* Calculate the output clock */
+				   /******************************/
+
+										ui_TimerValue
+											=
+											(UINT)
+											(
+											((ULONG) (b_PCIInputClock) * 500000UL) / ul_SSIOutputClock);
+
+				   /************************/
+										/* Initialise the timer */
+				   /************************/
+
+										outl(ui_TimerValue, devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr));
+
+				   /********************************/
+										/* Initialise the counting mode */
+				   /********************************/
+
+										outl(7 * b_SSICountingMode, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));
+
+										devpriv->
+											s_ModuleInfo
+											[b_ModulNbr].
+											s_SSICounterInfo.
+											b_SSIInit
+											=
+											1;
+									} else {
+				   /*****************************************************/
+										/* The selected SSI counting mode parameter is wrong */
+				   /*****************************************************/
+
+										DPRINTK("The selected SSI counting mode parameter is wrong\n");
+										i_ReturnValue
+											=
+											-9;
+									}
+								} else {
+				/******************************************/
+									/* The selected SSI output clock is wrong */
+				/******************************************/
+
+									DPRINTK("The selected SSI output clock is wrong\n");
+									i_ReturnValue
+										=
+										-8;
+								}
+							} else {
+			     /*****************************************/
+								/* The selected PCI input clock is wrong */
+			     /*****************************************/
+
+								DPRINTK("The selected PCI input clock is wrong\n");
+								i_ReturnValue =
+									-7;
+							}
+						} else {
+			  /********************************************/
+							/* The selected SSI profile length is wrong */
+			  /********************************************/
+
+							DPRINTK("The selected SSI profile length is wrong\n");
+							i_ReturnValue = -4;
+						}
+					} else {
+		       /******************************************************/
+						/* The selected SSI turn counter data length is wrong */
+		       /******************************************************/
+
+						DPRINTK("The selected SSI turn counter data length is wrong\n");
+						i_ReturnValue = -6;
+					}
+				} else {
+		    /**************************************************/
+					/* The selected SSI position data length is wrong */
+		    /**************************************************/
+
+					DPRINTK("The selected SSI position data length is wrong\n");
+					i_ReturnValue = -5;
+				}
+			} else {
+		 /********************************************/
+				/* The selected SSI profile length is wrong */
+		 /********************************************/
+
+				DPRINTK("The selected SSI profile length is wrong\n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /**********************************/
+			/* The module is not a SSI module */
+	      /**********************************/
+
+			DPRINTK("The module is not a SSI module\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /***********************/
+		/* Module number error */
+	   /***********************/
+
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_  i_APCI1710_Read1SSIValue                        |
+|                               (BYTE_     b_BoardHandle,                    |
+|                                BYTE_     b_ModulNbr,                       |
+|                                BYTE_     b_SelectedSSI,                    |
+|                                PULONG_ pul_Position,                       |
+|                                PULONG_ pul_TurnCpt)
+ INT i_APCI1710_ReadSSIValue(struct comedi_device *dev,struct comedi_subdevice *s,
+	struct comedi_insn *insn,unsigned int *data)                       |
++----------------------------------------------------------------------------+
+| Task              :
+
+
+						Read the selected SSI counter (b_SelectedSSI) from     |
+|                     selected module (b_ModulNbr).
+						or Read all SSI counter (b_SelectedSSI) from              |
+|                     selected module (b_ModulNbr).                            |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle         : Handle of board APCI-1710|
+|                     BYTE_ b_ModulNbr            : Module number to         |
+|                                                   configure (0 to 3)       |
+|                     BYTE_ b_SelectedSSI         : Selection from SSI       |
+|                                                   counter (0 to 2)
+
+    b_ModulNbr		=   (BYTE) CR_AREF(insn->chanspec);
+	b_SelectedSSI	=	(BYTE) CR_CHAN(insn->chanspec); (in case of single ssi)
+	b_ReadType		=	(BYTE) CR_RANGE(insn->chanspec);
+|
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_  pul_Position       : SSI position in the turn |
+|                     PULONG_  pul_TurnCpt        : Number of turns
+
+pul_Position	=	(PULONG) &data[0];
+	pul_TurnCpt		=	(PULONG) &data[1];         |
++----------------------------------------------------------------------------+
+| Return Value      : 0: No error                                            |
+|                    -1: The handle parameter of the board is wrong          |
+|                    -2: The module parameter is wrong                       |
+|                    -3: The module is not a SSI module                      |
+|                    -4: SSI not initialised see function                    |
+|                        "i_APCI1710_InitSSI"                                |
+|                    -5: The selected SSI is wrong                           |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnReadSSIValue(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = 0;
+	BYTE b_Cpt;
+	BYTE b_Length;
+	BYTE b_Schift;
+	BYTE b_SSICpt;
+	DWORD dw_And;
+	DWORD dw_And1;
+	DWORD dw_And2;
+	DWORD dw_StatusReg;
+	DWORD dw_CounterValue;
+	BYTE b_ModulNbr;
+	BYTE b_SelectedSSI;
+	BYTE b_ReadType;
+	PULONG pul_Position;
+	PULONG pul_TurnCpt;
+	PULONG pul_Position1;
+	PULONG pul_TurnCpt1;
+
+	i_ReturnValue = insn->n;
+	pul_Position1 = (PULONG) & data[0];
+// For Read1
+	pul_TurnCpt1 = (PULONG) & data[1];
+// For Read all
+	pul_Position = (PULONG) & data[0];	//0-2
+	pul_TurnCpt = (PULONG) & data[3];	//3-5
+	b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+	b_SelectedSSI = (BYTE) CR_CHAN(insn->chanspec);
+	b_ReadType = (BYTE) CR_RANGE(insn->chanspec);
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /***********************/
+		/* Test if SSI counter */
+	   /***********************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_SSI_COUNTER) {
+	      /***************************/
+			/* Test if SSI initialised */
+	      /***************************/
+
+			if (devpriv->s_ModuleInfo[b_ModulNbr].
+				s_SSICounterInfo.b_SSIInit == 1) {
+
+				switch (b_ReadType) {
+
+				case APCI1710_SSI_READ1VALUE:
+		 /****************************************/
+					/* Test the selected SSI counter number */
+		 /****************************************/
+
+					if (b_SelectedSSI < 3) {
+		    /************************/
+						/* Start the conversion */
+		    /************************/
+
+						outl(0, devpriv->s_BoardInfos.
+							ui_Address + 8 +
+							(64 * b_ModulNbr));
+
+						do {
+		       /*******************/
+							/* Read the status */
+		       /*******************/
+
+							dw_StatusReg =
+								inl(devpriv->
+								s_BoardInfos.
+								ui_Address +
+								(64 * b_ModulNbr));
+						}
+						while ((dw_StatusReg & 0x1) !=
+							0);
+
+		    /******************************/
+						/* Read the SSI counter value */
+		    /******************************/
+
+						dw_CounterValue =
+							inl(devpriv->
+							s_BoardInfos.
+							ui_Address + 4 +
+							(b_SelectedSSI * 4) +
+							(64 * b_ModulNbr));
+
+						b_Length =
+							devpriv->
+							s_ModuleInfo
+							[b_ModulNbr].
+							s_SSICounterInfo.
+							b_SSIProfile / 2;
+
+						if ((b_Length * 2) !=
+							devpriv->
+							s_ModuleInfo
+							[b_ModulNbr].
+							s_SSICounterInfo.
+							b_SSIProfile) {
+							b_Length++;
+						}
+
+						b_Schift =
+							b_Length -
+							devpriv->
+							s_ModuleInfo
+							[b_ModulNbr].
+							s_SSICounterInfo.
+							b_PositionTurnLength;
+
+						*pul_Position1 =
+							dw_CounterValue >>
+							b_Schift;
+
+						dw_And = 1;
+
+						for (b_Cpt = 0;
+							b_Cpt <
+							devpriv->
+							s_ModuleInfo
+							[b_ModulNbr].
+							s_SSICounterInfo.
+							b_PositionTurnLength;
+							b_Cpt++) {
+							dw_And = dw_And * 2;
+						}
+
+						*pul_Position1 =
+							*pul_Position1 &
+							((dw_And) - 1);
+
+						*pul_TurnCpt1 =
+							dw_CounterValue >>
+							b_Length;
+
+						dw_And = 1;
+
+						for (b_Cpt = 0;
+							b_Cpt <
+							devpriv->
+							s_ModuleInfo
+							[b_ModulNbr].
+							s_SSICounterInfo.
+							b_TurnCptLength;
+							b_Cpt++) {
+							dw_And = dw_And * 2;
+						}
+
+						*pul_TurnCpt1 =
+							*pul_TurnCpt1 &
+							((dw_And) - 1);
+					} else {
+		    /*****************************/
+						/* The selected SSI is wrong */
+		    /*****************************/
+
+						DPRINTK("The selected SSI is wrong\n");
+						i_ReturnValue = -5;
+					}
+					break;
+
+				case APCI1710_SSI_READALLVALUE:
+					dw_And1 = 1;
+
+					for (b_Cpt = 0;
+						b_Cpt <
+						devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_SSICounterInfo.
+						b_PositionTurnLength; b_Cpt++) {
+						dw_And1 = dw_And1 * 2;
+					}
+
+					dw_And2 = 1;
+
+					for (b_Cpt = 0;
+						b_Cpt <
+						devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_SSICounterInfo.
+						b_TurnCptLength; b_Cpt++) {
+						dw_And2 = dw_And2 * 2;
+					}
+
+		 /************************/
+					/* Start the conversion */
+		 /************************/
+
+					outl(0, devpriv->s_BoardInfos.
+						ui_Address + 8 +
+						(64 * b_ModulNbr));
+
+					do {
+		    /*******************/
+						/* Read the status */
+		    /*******************/
+
+						dw_StatusReg =
+							inl(devpriv->
+							s_BoardInfos.
+							ui_Address +
+							(64 * b_ModulNbr));
+					}
+					while ((dw_StatusReg & 0x1) != 0);
+
+					for (b_SSICpt = 0; b_SSICpt < 3;
+						b_SSICpt++) {
+		    /******************************/
+						/* Read the SSI counter value */
+		    /******************************/
+
+						dw_CounterValue =
+							inl(devpriv->
+							s_BoardInfos.
+							ui_Address + 4 +
+							(b_SSICpt * 4) +
+							(64 * b_ModulNbr));
+
+						b_Length =
+							devpriv->
+							s_ModuleInfo
+							[b_ModulNbr].
+							s_SSICounterInfo.
+							b_SSIProfile / 2;
+
+						if ((b_Length * 2) !=
+							devpriv->
+							s_ModuleInfo
+							[b_ModulNbr].
+							s_SSICounterInfo.
+							b_SSIProfile) {
+							b_Length++;
+						}
+
+						b_Schift =
+							b_Length -
+							devpriv->
+							s_ModuleInfo
+							[b_ModulNbr].
+							s_SSICounterInfo.
+							b_PositionTurnLength;
+
+						pul_Position[b_SSICpt] =
+							dw_CounterValue >>
+							b_Schift;
+						pul_Position[b_SSICpt] =
+							pul_Position[b_SSICpt] &
+							((dw_And1) - 1);
+
+						pul_TurnCpt[b_SSICpt] =
+							dw_CounterValue >>
+							b_Length;
+						pul_TurnCpt[b_SSICpt] =
+							pul_TurnCpt[b_SSICpt] &
+							((dw_And2) - 1);
+					}
+					break;
+
+				default:
+					printk("Read Type Inputs Wrong\n");
+
+				}	// switch  ending
+
+			} else {
+		 /***********************/
+				/* SSI not initialised */
+		 /***********************/
+
+				DPRINTK("SSI not initialised\n");
+				i_ReturnValue = -4;
+			}
+		} else {
+	      /**********************************/
+			/* The module is not a SSI module */
+	      /**********************************/
+
+			DPRINTK("The module is not a SSI module\n");
+			i_ReturnValue = -3;
+
+		}
+	} else {
+	   /***********************/
+		/* Module number error */
+	   /***********************/
+
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_   i_APCI1710_ReadSSI1DigitalInput                |
+|                                       (BYTE_     b_BoardHandle,            |
+|                                        BYTE_     b_ModulNbr,               |
+|                                        BYTE_     b_InputChannel,           |
+|                                        PBYTE_   pb_ChannelStatus)          |
++----------------------------------------------------------------------------+
+| Task              :
+					(0) Set the digital output from selected SSI moule         |
+|                     (b_ModuleNbr) ON
+                    (1) Set the digital output from selected SSI moule         |
+|                     (b_ModuleNbr) OFF
+					(2)Read the status from selected SSI digital input        |
+|                     (b_InputChannel)
+                    (3)Read the status from all SSI digital inputs from       |
+|                     selected SSI module (b_ModulNbr)                   |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle         : Handle of board APCI-1710|
+|                     BYTE_ b_ModulNbr    CR_AREF        : Module number to         |
+|                                                   configure (0 to 3)       |
+|                     BYTE_ b_InputChannel CR_CHAN       : Selection from digital   |
+|                        data[0] which IOTYPE                           input ( 0 to 2)          |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_  pb_ChannelStatus    : Digital input channel    |
+|                                 data[0]                  status                   |
+|                                                   0 : Channle is not active|
+|                                                   1 : Channle is active    |
++----------------------------------------------------------------------------+
+| Return Value      : 0: No error                                            |
+|                    -1: The handle parameter of the board is wrong          |
+|                    -2: The module parameter is wrong                       |
+|                    -3: The module is not a SSI module                      |
+|                    -4: The selected SSI digital input is wrong             |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_StatusReg;
+	BYTE b_ModulNbr;
+	BYTE b_InputChannel;
+	PBYTE pb_ChannelStatus;
+	PBYTE pb_InputStatus;
+	BYTE b_IOType;
+	i_ReturnValue = insn->n;
+	b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+	b_IOType = (BYTE) data[0];
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /***********************/
+		/* Test if SSI counter */
+	   /***********************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_SSI_COUNTER) {
+			switch (b_IOType) {
+			case APCI1710_SSI_SET_CHANNELON:
+					/*****************************/
+				/* Set the digital output ON */
+					/*****************************/
+
+				outl(1, devpriv->s_BoardInfos.ui_Address + 16 +
+					(64 * b_ModulNbr));
+				break;
+
+			case APCI1710_SSI_SET_CHANNELOFF:
+					/******************************/
+				/* Set the digital output OFF */
+					/******************************/
+
+				outl(0, devpriv->s_BoardInfos.ui_Address + 16 +
+					(64 * b_ModulNbr));
+				break;
+
+			case APCI1710_SSI_READ_1CHANNEL:
+				   /******************************************/
+				/* Test the digital imnput channel number */
+				   /******************************************/
+
+				b_InputChannel = (BYTE) CR_CHAN(insn->chanspec);
+				pb_ChannelStatus = (PBYTE) & data[0];
+
+				if (b_InputChannel <= 2) {
+					/**************************/
+					/* Read all digital input */
+					/**************************/
+
+					dw_StatusReg =
+						inl(devpriv->s_BoardInfos.
+						ui_Address + (64 * b_ModulNbr));
+					*pb_ChannelStatus =
+						(BYTE) (((~dw_StatusReg) >> (4 +
+								b_InputChannel))
+						& 1);
+				} else {
+					/********************************/
+					/* Selected digital input error */
+					/********************************/
+
+					DPRINTK("Selected digital input error\n");
+					i_ReturnValue = -4;
+				}
+				break;
+
+			case APCI1710_SSI_READ_ALLCHANNEL:
+					/**************************/
+				/* Read all digital input */
+					/**************************/
+				pb_InputStatus = (PBYTE) & data[0];
+
+				dw_StatusReg =
+					inl(devpriv->s_BoardInfos.ui_Address +
+					(64 * b_ModulNbr));
+				*pb_InputStatus =
+					(BYTE) (((~dw_StatusReg) >> 4) & 7);
+				break;
+
+			default:
+				printk("IO type wrong\n");
+
+			}	//switch end
+		} else {
+	      /**********************************/
+			/* The module is not a SSI module */
+	      /**********************************/
+
+			DPRINTK("The module is not a SSI module\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /***********************/
+		/* Module number error */
+	   /***********************/
+
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h
new file mode 100644
index 0000000..88daad1
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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.
+ */
+
+#define APCI1710_30MHZ		30
+#define APCI1710_33MHZ		33
+#define APCI1710_40MHZ		40
+
+#define APCI1710_BINARY_MODE	0x1
+#define APCI1710_GRAY_MODE	0x0
+
+#define APCI1710_SSI_READ1VALUE		1
+#define APCI1710_SSI_READALLVALUE	2
+
+#define APCI1710_SSI_SET_CHANNELON	0
+#define APCI1710_SSI_SET_CHANNELOFF	1
+#define APCI1710_SSI_READ_1CHANNEL	2
+#define APCI1710_SSI_READ_ALLCHANNEL	3
+
+/*
+ * SSI INISIALISATION FUNCTION
+ */
+INT i_APCI1710_InsnConfigInitSSI(struct comedi_device *dev, struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnReadSSIValue(struct comedi_device *dev, struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s,
+				    struct comedi_insn *insn, unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c
new file mode 100644
index 0000000..90316e1
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c
@@ -0,0 +1,2049 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+
+        ADDI-DATA GmbH
+        Dieselstrasse 3
+        D-77833 Ottersweier
+        Tel: +19(0)7223/9493-0
+        Fax: +49(0)7223/9493-92
+        http://www.addi-data-com
+        info@addi-data.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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+  +-----------------------------------------------------------------------+
+  | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
+  +-----------------------------------------------------------------------+
+  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
+  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
+  +-----------------------------------------------------------------------+
+  | Project     : API APCI1710    | Compiler : gcc                        |
+  | Module name : TOR.C           | Version  : 2.96                       |
+  +-------------------------------+---------------------------------------+
+  | Project manager: Eric Stolz   | Date     :  02/12/2002                |
+  +-----------------------------------------------------------------------+
+  | Description :   APCI-1710 tor counter module                          |
+  |                                                                       |
+  |                                                                       |
+  +-----------------------------------------------------------------------+
+  |                             UPDATES                                   |
+  +-----------------------------------------------------------------------+
+  |   Date   |   Author  |          Description of updates                |
+  +----------+-----------+------------------------------------------------+
+  | 27/01/99 | S. Weber  | 40 MHz implementation                          |
+  +-----------------------------------------------------------------------+
+  | 28/04/00 | S. Weber  | Simple,double and quadruple mode implementation|
+  |          |           | Extern clock implementation                    |
+  +-----------------------------------------------------------------------+
+  | 08/05/00 | Guinot C  | - 0400/0228 All Function in RING 0             |
+  |          |           |   available                                    |
+  +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+|                               Included files                               |
++----------------------------------------------------------------------------+
+*/
+
+#include "APCI1710_Tor.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_     i_APCI1710_InitTorCounter                    |
+|                                       (BYTE_     b_BoardHandle,            |
+|                                        BYTE_     b_ModulNbr,               |
+|                                        BYTE_     b_TorCounter,             |
+|                                        BYTE_     b_PCIInputClock,          |
+|                                        BYTE_     b_TimingUnit,             |
+|                                        ULONG_   ul_TimingInterval,         |
+|                                        PULONG_ pul_RealTimingInterval)     |
++----------------------------------------------------------------------------+
+| Task              : Configure the selected tor counter (b_TorCounter)      |
+|                     from selected module (b_ModulNbr).                     |
+|                     The ul_TimingInterval and ul_TimingUnit determine the  |
+|                     timing base for the measurement.                       |
+|                     The pul_RealTimingInterval return the real timing      |
+|                     value. You must calling this function be for you call  |
+|                     any other function witch access of the tor counter.    |
+|                                                                            |
++----------------------------------------------------------------------------+
+| Input Parameters  :    |
+|
+		CR_AREF	BYTE_   b_ModulNbr       : Module number to configure  |
+|                                                (0 to 3)                    |
+|           data[0] BYTE_   b_TorCounter     : Tor counter selection       |
+|                                                (0 or 1).                   |
+|           data[1] BYTE_   b_PCIInputClock  : Selection from PCI bus clock|
+|                                                - APCI1710_30MHZ :          |
+|                                                  The PC have a PCI bus     |
+|                                                  clock from 30 MHz         |
+|                                                - APCI1710_33MHZ :          |
+|                                                  The PC have a PCI bus     |
+|                                                  clock from 33 MHz         |
+|                                                - APCI1710_40MHZ            |
+|                                                  The APCI-1710 have a      |
+|                                                  integrated 40Mhz          |
+|                                                  quartz.                   |
+|                                                - APCI1710_GATE_INPUT       |
+|                                                  Used the gate input for   |
+|						   the base clock. If you    |
+|						   have selected this option,|
+|						   than it is not possibl to |
+|						   used the gate input for   |
+|						   enabled the acquisition   |
+|           data[2] BYTE_   b_TimingUnit    : Base timing unit (0 to 4)    |
+|                                                 0 : ns                     |
+|                                                 1 : µs                     |
+|                                                 2 : ms                     |
+|                                                 3 : s                      |
+|                                                 4 : mn                     |
+|           data[3]          ULONG_ ul_TimingInterval : Base timing value.          |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_  pul_RealTimingInterval : Real  base timing    |
+|                     data[0]                                  value.               |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: Module selection wrong                             |
+|                     -3: The module is not a tor counter module             |
+|                     -4: Tor counter selection is wrong                     |
+|                     -5: The selected PCI input clock is wrong              |
+|                     -6: Timing unit selection is wrong                     |
+|                     -7: Base timing selection is wrong                     |
+|                     -8: You can not used the 40MHz clock selection wich    |
+|                         this board                                         |
+|                     -9: You can not used the 40MHz clock selection wich    |
+|                         this TOR version                                   |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigInitTorCounter(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = 0;
+	ULONG ul_TimerValue = 0;
+	DWORD dw_Command;
+	double d_RealTimingInterval = 0;
+	BYTE b_ModulNbr;
+	BYTE b_TorCounter;
+	BYTE b_PCIInputClock;
+	BYTE b_TimingUnit;
+	ULONG ul_TimingInterval;
+	ULONG ul_RealTimingInterval = 0;
+
+	i_ReturnValue = insn->n;
+	b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+
+	b_TorCounter = (BYTE) data[0];
+	b_PCIInputClock = (BYTE) data[1];
+	b_TimingUnit = (BYTE) data[2];
+	ul_TimingInterval = (ULONG) data[3];
+	printk("INPUT clock %d\n", b_PCIInputClock);
+
+		/**************************/
+	/* Test the module number */
+		/**************************/
+
+	if (b_ModulNbr < 4) {
+		/***********************/
+		/* Test if tor counter */
+		/***********************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_TOR_COUNTER) {
+	      /**********************************/
+			/* Test the tor counter selection */
+	      /**********************************/
+
+			if (b_TorCounter <= 1) {
+		 /**************************/
+				/* Test the PCI bus clock */
+		 /**************************/
+
+				if ((b_PCIInputClock == APCI1710_30MHZ) ||
+					(b_PCIInputClock == APCI1710_33MHZ) ||
+					(b_PCIInputClock == APCI1710_40MHZ) ||
+					(b_PCIInputClock ==
+						APCI1710_GATE_INPUT)) {
+		    /************************/
+					/* Test the timing unit */
+		    /************************/
+
+					if ((b_TimingUnit <= 4)
+						|| (b_PCIInputClock ==
+							APCI1710_GATE_INPUT)) {
+		       /**********************************/
+						/* Test the base timing selection */
+		       /**********************************/
+
+						if (((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 133) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 571230650UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 571230UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 571UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 9UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 121) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 519691043UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 519691UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 520UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 8UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 100) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 429496729UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 429496UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 429UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 7UL)) || ((b_PCIInputClock == APCI1710_GATE_INPUT) && (ul_TimingInterval >= 2))) {
+				/**************************/
+							/* Test the board version */
+				/**************************/
+
+							if (((b_PCIInputClock == APCI1710_40MHZ) && (devpriv->s_BoardInfos.b_BoardVersion > 0)) || (b_PCIInputClock != APCI1710_40MHZ)) {
+			     /************************/
+								/* Test the TOR version */
+			     /************************/
+
+								if (((b_PCIInputClock == APCI1710_40MHZ) && ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3131)) || ((b_PCIInputClock == APCI1710_GATE_INPUT) && ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3132)) || (b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ)) {
+				/*********************************/
+									/* Test if not extern clock used */
+				/*********************************/
+
+									if (b_PCIInputClock != APCI1710_GATE_INPUT) {
+										fpu_begin
+											();
+				   /****************************************/
+										/* Calculate the timer 0 division fator */
+				   /****************************************/
+
+										switch (b_TimingUnit) {
+				      /******/
+											/* ns */
+				      /******/
+
+										case 0:
+
+					      /******************/
+											/* Timer 0 factor */
+					      /******************/
+
+											ul_TimerValue
+												=
+												(ULONG)
+												(ul_TimingInterval
+												*
+												(0.00025 * b_PCIInputClock));
+
+					      /*******************/
+											/* Round the value */
+					      /*******************/
+
+											if ((double)((double)ul_TimingInterval * (0.00025 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+												ul_TimerValue
+													=
+													ul_TimerValue
+													+
+													1;
+											}
+
+					      /*****************************/
+											/* Calculate the real timing */
+					      /*****************************/
+
+											ul_RealTimingInterval
+												=
+												(ULONG)
+												(ul_TimerValue
+												/
+												(0.00025 * (double)b_PCIInputClock));
+											d_RealTimingInterval
+												=
+												(double)
+												ul_TimerValue
+												/
+												(0.00025
+												*
+												(double)
+												b_PCIInputClock);
+
+											if ((double)((double)ul_TimerValue / (0.00025 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+												ul_RealTimingInterval
+													=
+													ul_RealTimingInterval
+													+
+													1;
+											}
+
+											ul_TimingInterval
+												=
+												ul_TimingInterval
+												-
+												1;
+											ul_TimerValue
+												=
+												ul_TimerValue
+												-
+												2;
+
+											if (b_PCIInputClock != APCI1710_40MHZ) {
+												ul_TimerValue
+													=
+													(ULONG)
+													(
+													(double)
+													(ul_TimerValue)
+													*
+													1.007752288);
+											}
+
+											break;
+
+				      /******/
+											/* æs */
+				      /******/
+
+										case 1:
+
+					      /******************/
+											/* Timer 0 factor */
+					      /******************/
+
+											ul_TimerValue
+												=
+												(ULONG)
+												(ul_TimingInterval
+												*
+												(0.25 * b_PCIInputClock));
+
+					      /*******************/
+											/* Round the value */
+					      /*******************/
+
+											if ((double)((double)ul_TimingInterval * (0.25 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+												ul_TimerValue
+													=
+													ul_TimerValue
+													+
+													1;
+											}
+
+					      /*****************************/
+											/* Calculate the real timing */
+					      /*****************************/
+
+											ul_RealTimingInterval
+												=
+												(ULONG)
+												(ul_TimerValue
+												/
+												(0.25 * (double)b_PCIInputClock));
+											d_RealTimingInterval
+												=
+												(double)
+												ul_TimerValue
+												/
+												(
+												(double)
+												0.25
+												*
+												(double)
+												b_PCIInputClock);
+
+											if ((double)((double)ul_TimerValue / (0.25 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+												ul_RealTimingInterval
+													=
+													ul_RealTimingInterval
+													+
+													1;
+											}
+
+											ul_TimingInterval
+												=
+												ul_TimingInterval
+												-
+												1;
+											ul_TimerValue
+												=
+												ul_TimerValue
+												-
+												2;
+
+											if (b_PCIInputClock != APCI1710_40MHZ) {
+												ul_TimerValue
+													=
+													(ULONG)
+													(
+													(double)
+													(ul_TimerValue)
+													*
+													1.007752288);
+											}
+
+											break;
+
+				      /******/
+											/* ms */
+				      /******/
+
+										case 2:
+
+					      /******************/
+											/* Timer 0 factor */
+					      /******************/
+
+											ul_TimerValue
+												=
+												ul_TimingInterval
+												*
+												(250.0
+												*
+												b_PCIInputClock);
+
+					      /*******************/
+											/* Round the value */
+					      /*******************/
+
+											if ((double)((double)ul_TimingInterval * (250.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+												ul_TimerValue
+													=
+													ul_TimerValue
+													+
+													1;
+											}
+
+					      /*****************************/
+											/* Calculate the real timing */
+					      /*****************************/
+
+											ul_RealTimingInterval
+												=
+												(ULONG)
+												(ul_TimerValue
+												/
+												(250.0 * (double)b_PCIInputClock));
+											d_RealTimingInterval
+												=
+												(double)
+												ul_TimerValue
+												/
+												(250.0
+												*
+												(double)
+												b_PCIInputClock);
+
+											if ((double)((double)ul_TimerValue / (250.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+												ul_RealTimingInterval
+													=
+													ul_RealTimingInterval
+													+
+													1;
+											}
+
+											ul_TimingInterval
+												=
+												ul_TimingInterval
+												-
+												1;
+											ul_TimerValue
+												=
+												ul_TimerValue
+												-
+												2;
+
+											if (b_PCIInputClock != APCI1710_40MHZ) {
+												ul_TimerValue
+													=
+													(ULONG)
+													(
+													(double)
+													(ul_TimerValue)
+													*
+													1.007752288);
+											}
+
+											break;
+
+				      /*****/
+											/* s */
+				      /*****/
+
+										case 3:
+
+					      /******************/
+											/* Timer 0 factor */
+					      /******************/
+
+											ul_TimerValue
+												=
+												(ULONG)
+												(ul_TimingInterval
+												*
+												(250000.0
+													*
+													b_PCIInputClock));
+
+					      /*******************/
+											/* Round the value */
+					      /*******************/
+
+											if ((double)((double)ul_TimingInterval * (250000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+												ul_TimerValue
+													=
+													ul_TimerValue
+													+
+													1;
+											}
+
+					      /*****************************/
+											/* Calculate the real timing */
+					      /*****************************/
+
+											ul_RealTimingInterval
+												=
+												(ULONG)
+												(ul_TimerValue
+												/
+												(250000.0
+													*
+													(double)
+													b_PCIInputClock));
+											d_RealTimingInterval
+												=
+												(double)
+												ul_TimerValue
+												/
+												(250000.0
+												*
+												(double)
+												b_PCIInputClock);
+
+											if ((double)((double)ul_TimerValue / (250000.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+												ul_RealTimingInterval
+													=
+													ul_RealTimingInterval
+													+
+													1;
+											}
+
+											ul_TimingInterval
+												=
+												ul_TimingInterval
+												-
+												1;
+											ul_TimerValue
+												=
+												ul_TimerValue
+												-
+												2;
+
+											if (b_PCIInputClock != APCI1710_40MHZ) {
+												ul_TimerValue
+													=
+													(ULONG)
+													(
+													(double)
+													(ul_TimerValue)
+													*
+													1.007752288);
+											}
+
+											break;
+
+				      /******/
+											/* mn */
+				      /******/
+
+										case 4:
+
+					      /******************/
+											/* Timer 0 factor */
+					      /******************/
+
+											ul_TimerValue
+												=
+												(ULONG)
+												(
+												(ul_TimingInterval
+													*
+													60)
+												*
+												(250000.0
+													*
+													b_PCIInputClock));
+
+					      /*******************/
+											/* Round the value */
+					      /*******************/
+
+											if ((double)((double)(ul_TimingInterval * 60.0) * (250000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+												ul_TimerValue
+													=
+													ul_TimerValue
+													+
+													1;
+											}
+
+					      /*****************************/
+											/* Calculate the real timing */
+					      /*****************************/
+
+											ul_RealTimingInterval
+												=
+												(ULONG)
+												(ul_TimerValue
+												/
+												(250000.0
+													*
+													(double)
+													b_PCIInputClock))
+												/
+												60;
+											d_RealTimingInterval
+												=
+												(
+												(double)
+												ul_TimerValue
+												/
+												(250000.0
+													*
+													(double)
+													b_PCIInputClock))
+												/
+												60.0;
+
+											if ((double)(((double)ul_TimerValue / (250000.0 * (double)b_PCIInputClock)) / 60.0) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+												ul_RealTimingInterval
+													=
+													ul_RealTimingInterval
+													+
+													1;
+											}
+
+											ul_TimingInterval
+												=
+												ul_TimingInterval
+												-
+												1;
+											ul_TimerValue
+												=
+												ul_TimerValue
+												-
+												2;
+
+											if (b_PCIInputClock != APCI1710_40MHZ) {
+												ul_TimerValue
+													=
+													(ULONG)
+													(
+													(double)
+													(ul_TimerValue)
+													*
+													1.007752288);
+											}
+
+											break;
+										}
+
+										fpu_end();
+									}	// if (b_PCIInputClock != APCI1710_GATE_INPUT)
+									else {
+				   /*************************************************************/
+										/* 2 Clock used for the overflow and the reload from counter */
+				   /*************************************************************/
+
+										ul_TimerValue
+											=
+											ul_TimingInterval
+											-
+											2;
+									}	// if (b_PCIInputClock != APCI1710_GATE_INPUT)
+
+				/****************************/
+									/* Save the PCI input clock */
+				/****************************/
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_TorCounterModuleInfo.
+										b_PCIInputClock
+										=
+										b_PCIInputClock;
+
+				/************************/
+									/* Save the timing unit */
+				/************************/
+
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_TorCounterModuleInfo.
+										s_TorCounterInfo
+										[b_TorCounter].
+										b_TimingUnit
+										=
+										b_TimingUnit;
+
+				/************************/
+									/* Save the base timing */
+				/************************/
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_TorCounterModuleInfo.
+										s_TorCounterInfo
+										[b_TorCounter].
+										d_TimingInterval
+										=
+										d_RealTimingInterval;
+
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_TorCounterModuleInfo.
+										s_TorCounterInfo
+										[b_TorCounter].
+										ul_RealTimingInterval
+										=
+										ul_RealTimingInterval;
+
+				/*******************/
+									/* Get the command */
+				/*******************/
+
+									dw_Command
+										=
+										inl
+										(devpriv->
+										s_BoardInfos.
+										ui_Address
+										+
+										4
+										+
+										(16 * b_TorCounter) + (64 * b_ModulNbr));
+
+									dw_Command
+										=
+										(dw_Command
+										>>
+										4)
+										&
+										0xF;
+
+				/******************/
+									/* Test if 40 MHz */
+				/******************/
+
+									if (b_PCIInputClock == APCI1710_40MHZ) {
+				   /****************************/
+										/* Set the 40 MHz selection */
+				   /****************************/
+
+										dw_Command
+											=
+											dw_Command
+											|
+											0x10;
+									}
+
+				/*****************************/
+									/* Test if extern clock used */
+				/*****************************/
+
+									if (b_PCIInputClock == APCI1710_GATE_INPUT) {
+				   /****************************/
+										/* Set the 40 MHz selection */
+				   /****************************/
+
+										dw_Command
+											=
+											dw_Command
+											|
+											0x20;
+									}
+
+				/*************************/
+									/* Write the new command */
+				/*************************/
+
+									outl(dw_Command, devpriv->s_BoardInfos.ui_Address + 4 + (16 * b_TorCounter) + (64 * b_ModulNbr));
+
+				/*******************/
+									/* Disable the tor */
+				/*******************/
+
+									outl(0, devpriv->s_BoardInfos.ui_Address + 8 + (16 * b_TorCounter) + (64 * b_ModulNbr));
+				/*************************/
+									/* Set the timer 1 value */
+				/*************************/
+
+									outl(ul_TimerValue, devpriv->s_BoardInfos.ui_Address + 0 + (16 * b_TorCounter) + (64 * b_ModulNbr));
+
+				/*********************/
+									/* Tor counter init. */
+				/*********************/
+
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_TorCounterModuleInfo.
+										s_TorCounterInfo
+										[b_TorCounter].
+										b_TorCounterInit
+										=
+										1;
+								} else {
+				/***********************************************/
+									/* TOR version error for 40MHz clock selection */
+				/***********************************************/
+
+									DPRINTK("TOR version error for 40MHz clock selection\n");
+									i_ReturnValue
+										=
+										-9;
+								}
+							} else {
+			     /**************************************************************/
+								/* You can not used the 40MHz clock selection wich this board */
+			     /**************************************************************/
+
+								DPRINTK("You can not used the 40MHz clock selection wich this board\n");
+								i_ReturnValue =
+									-8;
+							}
+						} else {
+			  /**********************************/
+							/* Base timing selection is wrong */
+			  /**********************************/
+
+							DPRINTK("Base timing selection is wrong\n");
+							i_ReturnValue = -7;
+						}
+					}	// if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+					else {
+		       /**********************************/
+						/* Timing unit selection is wrong */
+		       /**********************************/
+
+						DPRINTK("Timing unit selection is wrong\n");
+						i_ReturnValue = -6;
+					}	// if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+				}	// if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ))
+				else {
+		    /*****************************************/
+					/* The selected PCI input clock is wrong */
+		    /*****************************************/
+
+					DPRINTK("The selected PCI input clock is wrong\n");
+					i_ReturnValue = -5;
+				}	// if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ))
+			}	// if (b_TorCounterMode >= 0 && b_TorCounterMode <= 7)
+			else {
+		 /**********************************/
+				/* Tor Counter selection is wrong */
+		 /**********************************/
+
+				DPRINTK("Tor Counter selection is wrong\n");
+				i_ReturnValue = -4;
+			}	// if (b_TorCounterMode >= 0 && b_TorCounterMode <= 7)
+		} else {
+	      /******************************************/
+			/* The module is not a tor counter module */
+	      /******************************************/
+
+			DPRINTK("The module is not a tor counter module\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /***********************/
+		/* Module number error */
+	   /***********************/
+
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+	data[0] = (UINT) ul_RealTimingInterval;
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_EnableTorCounter                      |
+|                                               (BYTE_ b_BoardHandle,        |
+|                                                BYTE_ b_ModulNbr,           |
+|						 BYTE_ b_TorCounter,         |
+|						 BYTE_ b_InputMode,          |
+|						 BYTE_ b_ExternGate,         |
+|                                                BYTE_ b_CycleMode,          |
+|                                                BYTE_ b_InterruptEnable)    |
++----------------------------------------------------------------------------+
+| Task              : Enable the tor counter (b_TorCounter) from selected    |
+|		      module (b_ModulNbr). You must calling the              |
+|                     "i_APCI1710_InitTorCounter" function be for you call   |
+|		      this function.                                         |
+|                     If you enable the tor counter interrupt, the           |
+|                     tor counter generate a interrupt after the timing cycle|
+|                     See function "i_APCI1710_SetBoardIntRoutineX" and the  |
+|                     Interrupt mask description chapter from this manual.   |
+|                     The b_CycleMode parameter determine if you will        |
+|                     measured a single or more cycle.                       |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle  : Handle of board APCI-1710       |
+|                     BYTE_ b_ModulNbr     : Selected module number (0 to 3) |
+|                     BYTE_ b_TorCounter   : Tor counter selection (0 or 1). |
+|		      BYTE_ b_InputMode    : Input signal level selection    |
+|						0 : Tor count each low level |
+|						1 : Tor count each high level|
+|		      BYTE_ b_ExternGate   : Extern gate action selection    |
+|						0 : Extern gate signal not   |
+|						    used                     |
+|						1 : Extern gate signal used. |
+|						    If you selected the      |
+|						    single mode, each high   |
+|						    level signal start the   |
+|						    counter.                 |
+|						    If you selected the      |
+|						    continuous mode, the     |
+|						    first high level signal  |
+|						    start the tor counter    |
+|									     |
+|					      APCI1710_TOR_QUADRUPLE _MODE : |
+|					      In the quadruple mode, the edge|
+|					      analysis circuit generates a   |
+|					      counting pulse from each edge  |
+|					      of 2 signals which are phase   |
+|					      shifted in relation to each    |
+|					      other.                         |
+|					      The gate input is used for the |
+|					      signal B                       |
+|									     |
+|					      APCI1710_TOR_DOUBLE_MODE:      |
+|					      Functions in the same way as   |
+|					      the quadruple mode, except that|
+|					      only two of the four edges are |
+|					      analysed per period.           |
+|					      The gate input is used for the |
+|					      signal B                       |
+|									     |
+|					      APCI1710_TOR_SIMPLE_MODE:      |
+|					      Functions in the same way as   |
+|					      the quadruple mode, except that|
+|					      only one of the four edges is  |
+|					      analysed per period.           |
+|					      The gate input is used for the |
+|					      signal B                       |
+|									     |
+|                     BYTE_ b_CycleMode    : Selected the tor counter        |
+|                                            acquisition mode                |
+|                     BYTE_ b_InterruptEnable : Enable or disable the        |
+|                                               tor counter interrupt.       |
+|                                               APCI1710_ENABLE:             |
+|                                               Enable the tor counter       |
+|                                               interrupt                    |
+|                                               APCI1710_DISABLE:            |
+|                                               Disable the tor counter      |
+|                                               interrupt                    |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: Module selection wrong                             |
+|                     -3: The module is not a tor counter module             |
+|                     -4: Tor counter selection is wrong                     |
+|                     -5: Tor counter not initialised see function           |
+|                         "i_APCI1710_InitTorCounter"                        |
+|                     -6: Tor input signal selection is wrong                |
+|                     -7: Extern gate signal mode is wrong                   |
+|                     -8: Tor counter acquisition mode cycle is wrong        |
+|                     -9: Interrupt parameter is wrong                       |
+|                     -10:Interrupt function not initialised.                |
+|                         See function "i_APCI1710_SetBoardIntRoutineX"      |
++----------------------------------------------------------------------------+
+*/
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_DisableTorCounter                     |
+|                                               (BYTE_  b_BoardHandle,       |
+|                                                BYTE_  b_ModulNbr,          |
+|						 BYTE_  b_TorCounter)        |
++----------------------------------------------------------------------------+
+| Task              : Disable the tor counter (b_TorCounter) from selected   |
+|		      module (b_ModulNbr). If you disable the tor counter    |
+|		      after a start cycle occur and you restart the tor      |
+|		      counter witch the " i_APCI1710_EnableTorCounter"       |
+|		      function, the status register is cleared               |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle  : Handle of board APCI-1710       |
+|                     BYTE_ b_ModulNbr     : Selected module number (0 to 3) |
+|                     BYTE_ b_TorCounter   : Tor counter selection (0 or 1). |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: Module selection wrong                             |
+|                     -3: The module is not a tor counter module             |
+|                     -4: Tor counter selection is wrong                     |
+|                     -5: Tor counter not initialised see function           |
+|                         "i_APCI1710_InitTorCounter"                        |
+|                     -6: Tor counter not enabled see function               |
+|                         "i_APCI1710_EnableTorCounter"                      |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnWriteEnableDisableTorCounter(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_Status;
+	DWORD dw_DummyRead;
+	DWORD dw_ConfigReg;
+	BYTE b_ModulNbr, b_Action;
+	BYTE b_TorCounter;
+	BYTE b_InputMode;
+	BYTE b_ExternGate;
+	BYTE b_CycleMode;
+	BYTE b_InterruptEnable;
+
+	b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+	b_Action = (BYTE) data[0];	// enable or disable
+	b_TorCounter = (BYTE) data[1];
+	b_InputMode = (BYTE) data[2];
+	b_ExternGate = (BYTE) data[3];
+	b_CycleMode = (BYTE) data[4];
+	b_InterruptEnable = (BYTE) data[5];
+	i_ReturnValue = insn->n;;
+	devpriv->tsk_Current = current;	// Save the current process task structure
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /***********************/
+		/* Test if tor counter */
+	   /***********************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_TOR_COUNTER) {
+	      /**********************************/
+			/* Test the tor counter selection */
+	      /**********************************/
+
+			if (b_TorCounter <= 1) {
+				switch (b_Action)	// Enable or Disable
+				{
+				case APCI1710_ENABLE:
+		 /***********************************/
+					/* Test if tor counter initialised */
+		 /***********************************/
+
+					dw_Status =
+						inl(devpriv->s_BoardInfos.
+						ui_Address + 8 +
+						(16 * b_TorCounter) +
+						(64 * b_ModulNbr));
+
+					if (dw_Status & 0x10) {
+		    /******************************/
+						/* Test the input signal mode */
+		    /******************************/
+
+						if (b_InputMode == 0 ||
+							b_InputMode == 1 ||
+							b_InputMode ==
+							APCI1710_TOR_SIMPLE_MODE
+							|| b_InputMode ==
+							APCI1710_TOR_DOUBLE_MODE
+							|| b_InputMode ==
+							APCI1710_TOR_QUADRUPLE_MODE)
+						{
+		       /************************************/
+							/* Test the extern gate signal mode */
+		       /************************************/
+
+							if (b_ExternGate == 0
+								|| b_ExternGate
+								== 1
+								|| b_InputMode >
+								1) {
+			  /*********************************/
+								/* Test the cycle mode parameter */
+			  /*********************************/
+
+								if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS)) {
+			     /***************************/
+									/* Test the interrupt flag */
+			     /***************************/
+
+									if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE)) {
+
+				   /***************************/
+										/* Save the interrupt mode */
+				   /***************************/
+
+										devpriv->
+											s_ModuleInfo
+											[b_ModulNbr].
+											s_TorCounterModuleInfo.
+											s_TorCounterInfo
+											[b_TorCounter].
+											b_InterruptEnable
+											=
+											b_InterruptEnable;
+
+				   /*******************/
+										/* Get the command */
+				   /*******************/
+
+										dw_ConfigReg
+											=
+											inl
+											(devpriv->
+											s_BoardInfos.
+											ui_Address
+											+
+											4
+											+
+											(16 * b_TorCounter) + (64 * b_ModulNbr));
+
+										dw_ConfigReg
+											=
+											(dw_ConfigReg
+											>>
+											4)
+											&
+											0x30;
+
+				   /********************************/
+										/* Test if not direct mode used */
+				   /********************************/
+
+										if (b_InputMode > 1) {
+				      /*******************************/
+											/* Extern gate can not be used */
+				      /*******************************/
+
+											b_ExternGate
+												=
+												0;
+
+				      /*******************************************/
+											/* Enable the extern gate for the Signal B */
+				      /*******************************************/
+
+											dw_ConfigReg
+												=
+												dw_ConfigReg
+												|
+												0x40;
+
+				      /***********************/
+											/* Test if simple mode */
+				      /***********************/
+
+											if (b_InputMode == APCI1710_TOR_SIMPLE_MODE) {
+					 /**************************/
+												/* Enable the sinple mode */
+					 /**************************/
+
+												dw_ConfigReg
+													=
+													dw_ConfigReg
+													|
+													0x780;
+
+											}	// if (b_InputMode == APCI1710_TOR_SIMPLE_MODE)
+
+				      /***********************/
+											/* Test if double mode */
+				      /***********************/
+
+											if (b_InputMode == APCI1710_TOR_DOUBLE_MODE) {
+					 /**************************/
+												/* Enable the double mode */
+					 /**************************/
+
+												dw_ConfigReg
+													=
+													dw_ConfigReg
+													|
+													0x180;
+
+											}	// if (b_InputMode == APCI1710_TOR_DOUBLE_MODE)
+
+											b_InputMode
+												=
+												0;
+										}	// if (b_InputMode > 1)
+
+				   /*******************/
+										/* Set the command */
+				   /*******************/
+
+										dw_ConfigReg
+											=
+											dw_ConfigReg
+											|
+											b_CycleMode
+											|
+											(b_InterruptEnable
+											*
+											2)
+											|
+											(b_InputMode
+											*
+											4)
+											|
+											(b_ExternGate
+											*
+											8);
+
+				   /*****************************/
+										/* Clear the status register */
+				   /*****************************/
+
+										dw_DummyRead
+											=
+											inl
+											(devpriv->
+											s_BoardInfos.
+											ui_Address
+											+
+											0
+											+
+											(16 * b_TorCounter) + (64 * b_ModulNbr));
+
+				   /***************************************/
+										/* Clear the interrupt status register */
+				   /***************************************/
+
+										dw_DummyRead
+											=
+											inl
+											(devpriv->
+											s_BoardInfos.
+											ui_Address
+											+
+											12
+											+
+											(16 * b_TorCounter) + (64 * b_ModulNbr));
+
+				   /********************/
+										/* Set the commando */
+				   /********************/
+
+										outl(dw_ConfigReg, devpriv->s_BoardInfos.ui_Address + 4 + (16 * b_TorCounter) + (64 * b_ModulNbr));
+
+				   /****************/
+										/* Set the gate */
+				   /****************/
+
+										outl(1, devpriv->s_BoardInfos.ui_Address + 8 + (16 * b_TorCounter) + (64 * b_ModulNbr));
+
+									}	// if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE))
+									else {
+				/********************************/
+										/* Interrupt parameter is wrong */
+				/********************************/
+
+										DPRINTK("Interrupt parameter is wrong\n");
+										i_ReturnValue
+											=
+											-9;
+									}	// if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE))
+								}	// if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS))
+								else {
+			     /***********************************************/
+									/* Tor counter acquisition mode cycle is wrong */
+			     /***********************************************/
+
+									DPRINTK("Tor counter acquisition mode cycle is wrong\n");
+									i_ReturnValue
+										=
+										-8;
+								}	// if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS))
+							}	// if (b_ExternGate >= 0 && b_ExternGate <= 1)
+							else {
+			  /***********************************/
+								/* Extern gate input mode is wrong */
+			  /***********************************/
+
+								DPRINTK("Extern gate input mode is wrong\n");
+								i_ReturnValue =
+									-7;
+							}	// if (b_ExternGate >= 0 && b_ExternGate <= 1)
+						}	// if (b_InputMode >= 0 && b_InputMode <= 1)
+						else {
+		       /***************************************/
+							/* Tor input signal selection is wrong */
+		       /***************************************/
+
+							DPRINTK("Tor input signal selection is wrong\n");
+							i_ReturnValue = -6;
+						}
+					} else {
+		    /*******************************/
+						/* Tor counter not initialised */
+		    /*******************************/
+
+						DPRINTK("Tor counter not initialised\n");
+						i_ReturnValue = -5;
+					}
+					break;
+
+				case APCI1710_DISABLE:
+			 /***********************************/
+					/* Test if tor counter initialised */
+		 /***********************************/
+
+					dw_Status = inl(devpriv->s_BoardInfos.
+						ui_Address + 8 +
+						(16 * b_TorCounter) +
+						(64 * b_ModulNbr));
+
+		 /*******************************/
+					/* Test if counter initialised */
+		 /*******************************/
+
+					if (dw_Status & 0x10) {
+		    /***************************/
+						/* Test if counter enabled */
+		    /***************************/
+
+						if (dw_Status & 0x1) {
+		       /****************************/
+							/* Clear the interrupt mode */
+		       /****************************/
+							devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_TorCounterModuleInfo.
+								s_TorCounterInfo
+								[b_TorCounter].
+								b_InterruptEnable
+								=
+								APCI1710_DISABLE;
+
+		       /******************/
+							/* Clear the gate */
+		       /******************/
+
+							outl(0, devpriv->
+								s_BoardInfos.
+								ui_Address + 8 +
+								(16 * b_TorCounter) + (64 * b_ModulNbr));
+						}	// if (dw_Status & 0x1)
+						else {
+		       /***************************/
+							/* Tor counter not enabled */
+		       /***************************/
+
+							DPRINTK("Tor counter not enabled \n");
+							i_ReturnValue = -6;
+						}	// if (dw_Status & 0x1)
+					}	// if (dw_Status & 0x10)
+					else {
+		    /*******************************/
+						/* Tor counter not initialised */
+		    /*******************************/
+
+						DPRINTK("Tor counter not initialised\n");
+						i_ReturnValue = -5;
+					}	// // if (dw_Status & 0x10)
+
+				}	// switch
+			}	// if (b_TorCounter <= 1)
+			else {
+		 /**********************************/
+				/* Tor counter selection is wrong */
+		 /**********************************/
+
+				DPRINTK("Tor counter selection is wrong\n");
+				i_ReturnValue = -4;
+			}	// if (b_TorCounter <= 1)
+		} else {
+	      /******************************************/
+			/* The module is not a tor counter module */
+	      /******************************************/
+
+			DPRINTK("The module is not a tor counter module \n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /***********************/
+		/* Module number error */
+	   /***********************/
+
+		DPRINTK("Module number error \n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_GetTorCounterInitialisation           |
+|                                               (BYTE_     b_BoardHandle,    |
+|                                                BYTE_     b_ModulNbr,       |
+|						 BYTE_     b_TorCounter,     |
+|                                        	 PBYTE_   pb_TimingUnit,     |
+|                                        	 PULONG_ pul_TimingInterval, |
+|						 PBYTE_   pb_InputMode,      |
+|						 PBYTE_   pb_ExternGate,     |
+|                                                PBYTE_   pb_CycleMode,      |
+|						 PBYTE_   pb_Enable,         |
+|                                                PBYTE_   pb_InterruptEnable)|
++----------------------------------------------------------------------------+
+| Task              : Enable the tor counter (b_TorCounter) from selected    |
+|		      module (b_ModulNbr). You must calling the              |
+|                     "i_APCI1710_InitTorCounter" function be for you call   |
+|		      this function.                                         |
+|                     If you enable the tor counter interrupt, the           |
+|                     tor counter generate a interrupt after the timing cycle|
+|                     See function "i_APCI1710_SetBoardIntRoutineX" and the  |
+|                     Interrupt mask description chapter from this manual.   |
+|                     The b_CycleMode parameter determine if you will        |
+|                     measured a single or more cycle.                       |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle  : Handle of board APCI-1710       |
+|                     BYTE_ b_ModulNbr     : Selected module number (0 to 3) |
+|                     BYTE_ b_TorCounter   : Tor counter selection (0 or 1)
+
+	b_ModulNbr			=	CR_AREF(insn->chanspec);
+	b_TorCounter		=	CR_CHAN(insn->chanspec);
+. |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_  pb_TimingUnit    : Base timing unit (0 to 4)   |
+|                                                 0 : ns                     |
+|                                                 1 : µs                     |
+|                                                 2 : ms                     |
+|                                                 3 : s                      |
+|                                                 4 : mn                     |
+|                     PULONG_ pul_TimingInterval : Base timing value.        |
+|		      PBYTE_ pb_InputMode        : Input signal level        |
+|						   selection  		     |
+|						0 : Tor count each low level |
+|						1 : Tor count each high level|
+|		      PBYTE_ pb_ExternGate	: Extern gate action         |
+|						  selection                  |
+|						  0 : Extern gate signal not |
+|						      used                   |
+|						  1 : Extern gate signal used|
+|                     PBYTE_ pb_CycleMode       : Tor counter acquisition    |
+|						  mode           	     |
+|		      PBYTE_ pb_Enable		: Indicate if the tor counter|
+|						  is enabled or no           |
+|						  0 : Tor counter disabled   |
+|						  1 : Tor counter enabled    |
+|                     PBYTE_ pb_InterruptEnable : Enable or disable the      |
+|                                                 tor counter interrupt.     |
+|                                                 APCI1710_ENABLE:           |
+|                                                 Enable the tor counter     |
+|                                                 interrupt                  |
+|                                                 APCI1710_DISABLE:          |
+|                                                 Disable the tor counter    |
+|                                                 interrupt
+	pb_TimingUnit		=	(PBYTE) &data[0];
+	pul_TimingInterval	=  (PULONG) &data[1];
+	pb_InputMode		=	(PBYTE) &data[2];
+	pb_ExternGate		=	(PBYTE) &data[3];
+	pb_CycleMode		=	(PBYTE) &data[4];
+	pb_Enable			=	(PBYTE) &data[5];
+	pb_InterruptEnable	=	(PBYTE) &data[6];
+                 |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: Module selection wrong                             |
+|                     -3: The module is not a tor counter module             |
+|                     -4: Tor counter selection is wrong                     |
+|                     -5: Tor counter not initialised see function           |
+|                         "i_APCI1710_InitTorCounter"                        |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnReadGetTorCounterInitialisation(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_Status;
+	BYTE b_ModulNbr;
+	BYTE b_TorCounter;
+	PBYTE pb_TimingUnit;
+	PULONG pul_TimingInterval;
+	PBYTE pb_InputMode;
+	PBYTE pb_ExternGate;
+	PBYTE pb_CycleMode;
+	PBYTE pb_Enable;
+	PBYTE pb_InterruptEnable;
+
+	i_ReturnValue = insn->n;
+	b_ModulNbr = CR_AREF(insn->chanspec);
+	b_TorCounter = CR_CHAN(insn->chanspec);
+
+	pb_TimingUnit = (PBYTE) & data[0];
+	pul_TimingInterval = (PULONG) & data[1];
+	pb_InputMode = (PBYTE) & data[2];
+	pb_ExternGate = (PBYTE) & data[3];
+	pb_CycleMode = (PBYTE) & data[4];
+	pb_Enable = (PBYTE) & data[5];
+	pb_InterruptEnable = (PBYTE) & data[6];
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /***********************/
+		/* Test if tor counter */
+	   /***********************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_TOR_COUNTER) {
+	      /**********************************/
+			/* Test the tor counter selection */
+	      /**********************************/
+
+			if (b_TorCounter <= 1) {
+
+		 /***********************************/
+				/* Test if tor counter initialised */
+		 /***********************************/
+
+				dw_Status = inl(devpriv->s_BoardInfos.
+					ui_Address + 8 + (16 * b_TorCounter) +
+					(64 * b_ModulNbr));
+
+				if (dw_Status & 0x10) {
+					*pb_Enable = dw_Status & 1;
+
+		    /********************/
+					/* Get the commando */
+		    /********************/
+
+					dw_Status = inl(devpriv->s_BoardInfos.
+						ui_Address + 4 +
+						(16 * b_TorCounter) +
+						(64 * b_ModulNbr));
+
+					*pb_CycleMode =
+						(BYTE) ((dw_Status >> 4) & 1);
+					*pb_InterruptEnable =
+						(BYTE) ((dw_Status >> 5) & 1);
+
+		    /******************************************************/
+					/* Test if extern gate used for clock or for signal B */
+		    /******************************************************/
+
+					if (dw_Status & 0x600) {
+		       /*****************************************/
+						/* Test if extern gate used for signal B */
+		       /*****************************************/
+
+						if (dw_Status & 0x400) {
+			  /***********************/
+							/* Test if simple mode */
+			  /***********************/
+
+							if ((dw_Status & 0x7800)
+								== 0x7800) {
+								*pb_InputMode =
+									APCI1710_TOR_SIMPLE_MODE;
+							}
+
+			  /***********************/
+							/* Test if double mode */
+			  /***********************/
+
+							if ((dw_Status & 0x7800)
+								== 0x1800) {
+								*pb_InputMode =
+									APCI1710_TOR_DOUBLE_MODE;
+							}
+
+			  /**************************/
+							/* Test if quadruple mode */
+			  /**************************/
+
+							if ((dw_Status & 0x7800)
+								== 0x0000) {
+								*pb_InputMode =
+									APCI1710_TOR_QUADRUPLE_MODE;
+							}
+						}	// if (dw_Status & 0x400)
+						else {
+							*pb_InputMode = 1;
+						}	// // if (dw_Status & 0x400)
+
+		       /************************/
+						/* Extern gate not used */
+		       /************************/
+
+						*pb_ExternGate = 0;
+					}	// if (dw_Status & 0x600)
+					else {
+						*pb_InputMode =
+							(BYTE) ((dw_Status >> 6)
+							& 1);
+						*pb_ExternGate =
+							(BYTE) ((dw_Status >> 7)
+							& 1);
+					}	// if (dw_Status & 0x600)
+
+					*pb_TimingUnit =
+						devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_TorCounterModuleInfo.
+						s_TorCounterInfo[b_TorCounter].
+						b_TimingUnit;
+
+					*pul_TimingInterval =
+						devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_TorCounterModuleInfo.
+						s_TorCounterInfo[b_TorCounter].
+						ul_RealTimingInterval;
+				} else {
+		    /*******************************/
+					/* Tor counter not initialised */
+		    /*******************************/
+
+					DPRINTK("Tor counter not initialised\n");
+					i_ReturnValue = -5;
+				}
+
+			}	// if (b_TorCounter <= 1)
+			else {
+		 /**********************************/
+				/* Tor counter selection is wrong */
+		 /**********************************/
+
+				DPRINTK("Tor counter selection is wrong \n");
+				i_ReturnValue = -4;
+			}	// if (b_TorCounter <= 1)
+		} else {
+	      /******************************************/
+			/* The module is not a tor counter module */
+	      /******************************************/
+
+			DPRINTK("The module is not a tor counter module\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /***********************/
+		/* Module number error */
+	   /***********************/
+
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_ReadTorCounterValue                   |
+|                               (BYTE_     b_BoardHandle,                    |
+|                                BYTE_     b_ModulNbr,                       |
+|				 BYTE_     b_TorCounter,                     |
+|                                UINT_    ui_TimeOut,                        |
+|                                PBYTE_   pb_TorCounterStatus,               |
+|                                PULONG_ pul_TorCounterValue)                |
++----------------------------------------------------------------------------+
+| Task        	case APCI1710_TOR_GETPROGRESSSTATUS: Return the tor counter
+(b_TorCounter) status (pb_TorCounterStatus) from selected tor counter        |
+|		      module (b_ModulNbr).
+
+				 case APCI1710_TOR_GETCOUNTERVALUE :
+  Return the tor counter (b_TorCounter) status           |
+|		      (pb_TorCounterStatus) and the timing value             |
+|		      (pul_TorCounterValue) after a conting cycle stop       |
+|                     from selected tor counter module (b_ModulNbr).         |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle  : Handle of board APCI-1710       |
+|                     BYTE_ b_ModulNbr     : Selected module number (0 to 3) |
+|                     BYTE_ b_TorCounter   : Tor counter selection (0 or 1).
+	b_ModulNbr    = CR_AREF(insn->chanspec);
+	b_ReadType    = (BYTE) data[0];
+	b_TorCounter  =	(BYTE) data[1];
+	ui_TimeOut	  = (UINT) data[2]; |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_  pb_TorCounterStatus : Return the tor counter   |
+|                                                    status.                 |
+|                                               0 : Conting cycle not started|
+|                                                   Software gate not set.   |
+|                                               1 : Conting cycle started.   |
+|                                                   Software gate set.       |
+|                                               2 : Conting cycle stopped.   |
+|                                                   The conting cycle is     |
+|                                                   terminate.               |
+|                                               3 : A overflow occur. You    |
+|                                                   must change the base     |
+|                                                   timing witch the         |
+|                                                   function                 |
+|                                                 "i_APCI1710_InitTorCounter"|
+|						4 : Timeeout occur           |
+|                     PULONG  pul_TorCounterValue  : Tor counter value.
+	pb_TorCounterStatus=(PBYTE) &data[0];
+	pul_TorCounterValue=(PULONG) &data[1];    |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: Module selection wrong                             |
+|                     -3: The module is not a tor counter module             |
+|                     -4: Tor counter selection is wrong                     |
+|                     -5: Tor counter not initialised see function           |
+|                         "i_APCI1710_InitTorCounter"                        |
+|                     -6: Tor counter not enabled see function               |
+|                         "i_APCI1710_EnableTorCounter"                      |
+|                     -7: Timeout parameter is wrong (0 to 65535)            |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_Status;
+	DWORD dw_TimeOut = 0;
+
+	BYTE b_ModulNbr;
+	BYTE b_TorCounter;
+	BYTE b_ReadType;
+	UINT ui_TimeOut;
+	PBYTE pb_TorCounterStatus;
+	PULONG pul_TorCounterValue;
+
+	i_ReturnValue = insn->n;
+	b_ModulNbr = CR_AREF(insn->chanspec);
+	b_ReadType = (BYTE) data[0];
+	b_TorCounter = (BYTE) data[1];
+	ui_TimeOut = (UINT) data[2];
+	pb_TorCounterStatus = (PBYTE) & data[0];
+	pul_TorCounterValue = (PULONG) & data[1];
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ReadType == APCI1710_TOR_READINTERRUPT) {
+
+		data[0] = devpriv->s_InterruptParameters.
+			s_FIFOInterruptParameters[devpriv->
+			s_InterruptParameters.ui_Read].b_OldModuleMask;
+		data[1] = devpriv->s_InterruptParameters.
+			s_FIFOInterruptParameters[devpriv->
+			s_InterruptParameters.ui_Read].ul_OldInterruptMask;
+		data[2] = devpriv->s_InterruptParameters.
+			s_FIFOInterruptParameters[devpriv->
+			s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
+
+			   /**************************/
+		/* Increment the read FIFO */
+			   /***************************/
+
+		devpriv->
+			s_InterruptParameters.
+			ui_Read = (devpriv->
+			s_InterruptParameters.
+			ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+
+		return insn->n;
+	}
+
+	if (b_ModulNbr < 4) {
+	   /***********************/
+		/* Test if tor counter */
+	   /***********************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_TOR_COUNTER) {
+	      /**********************************/
+			/* Test the tor counter selection */
+	      /**********************************/
+
+			if (b_TorCounter <= 1) {
+		 /***********************************/
+				/* Test if tor counter initialised */
+		 /***********************************/
+
+				dw_Status = inl(devpriv->s_BoardInfos.
+					ui_Address + 8 + (16 * b_TorCounter) +
+					(64 * b_ModulNbr));
+
+		 /*******************************/
+				/* Test if counter initialised */
+		 /*******************************/
+
+				if (dw_Status & 0x10) {
+		    /***************************/
+					/* Test if counter enabled */
+		    /***************************/
+
+					if (dw_Status & 0x1) {
+
+						switch (b_ReadType) {
+
+						case APCI1710_TOR_GETPROGRESSSTATUS:
+		       /*******************/
+							/* Read the status */
+		       /*******************/
+
+							dw_Status =
+								inl(devpriv->
+								s_BoardInfos.
+								ui_Address + 4 +
+								(16 * b_TorCounter) + (64 * b_ModulNbr));
+
+							dw_Status =
+								dw_Status & 0xF;
+
+		       /*****************/
+							/* Test if start */
+		       /*****************/
+
+							if (dw_Status & 1) {
+								if (dw_Status &
+									2) {
+									if (dw_Status & 4) {
+				/************************/
+										/* Tor counter owerflow */
+				/************************/
+
+										*pb_TorCounterStatus
+											=
+											3;
+									} else {
+				/***********************/
+										/* Tor counter started */
+				/***********************/
+
+										*pb_TorCounterStatus
+											=
+											2;
+									}
+								} else {
+			     /***********************/
+									/* Tor counter started */
+			     /***********************/
+
+									*pb_TorCounterStatus
+										=
+										1;
+								}
+							} else {
+			  /***************************/
+								/* Tor counter not started */
+			  /***************************/
+
+								*pb_TorCounterStatus
+									= 0;
+							}
+							break;
+
+						case APCI1710_TOR_GETCOUNTERVALUE:
+
+		       /*****************************/
+							/* Test the timout parameter */
+		       /*****************************/
+
+							if ((ui_TimeOut >= 0)
+								&& (ui_TimeOut
+									<=
+									65535UL))
+							{
+								for (;;) {
+			     /*******************/
+									/* Read the status */
+			     /*******************/
+
+									dw_Status
+										=
+										inl
+										(devpriv->
+										s_BoardInfos.
+										ui_Address
+										+
+										4
+										+
+										(16 * b_TorCounter) + (64 * b_ModulNbr));
+			     /********************/
+									/* Test if overflow */
+			     /********************/
+
+									if ((dw_Status & 4) == 4) {
+				/******************/
+										/* Overflow occur */
+				/******************/
+
+										*pb_TorCounterStatus
+											=
+											3;
+
+				/******************/
+										/* Read the value */
+				/******************/
+
+										*pul_TorCounterValue
+											=
+											inl
+											(devpriv->
+											s_BoardInfos.
+											ui_Address
+											+
+											0
+											+
+											(16 * b_TorCounter) + (64 * b_ModulNbr));
+										break;
+									}	// if ((dw_Status & 4) == 4)
+									else {
+				/*******************************/
+										/* Test if measurement stopped */
+				/*******************************/
+
+										if ((dw_Status & 2) == 2) {
+				   /***********************/
+											/* A stop signal occur */
+				   /***********************/
+
+											*pb_TorCounterStatus
+												=
+												2;
+
+				   /******************/
+											/* Read the value */
+				   /******************/
+
+											*pul_TorCounterValue
+												=
+												inl
+												(devpriv->
+												s_BoardInfos.
+												ui_Address
+												+
+												0
+												+
+												(16 * b_TorCounter) + (64 * b_ModulNbr));
+
+											break;
+										}	// if ((dw_Status & 2) == 2)
+										else {
+				   /*******************************/
+											/* Test if measurement started */
+				   /*******************************/
+
+											if ((dw_Status & 1) == 1) {
+				      /************************/
+												/* A start signal occur */
+				      /************************/
+
+												*pb_TorCounterStatus
+													=
+													1;
+											}	// if ((dw_Status & 1) == 1)
+											else {
+				      /***************************/
+												/* Measurement not started */
+				      /***************************/
+
+												*pb_TorCounterStatus
+													=
+													0;
+											}	// if ((dw_Status & 1) == 1)
+										}	// if ((dw_Status & 2) == 2)
+									}	// if ((dw_Status & 8) == 8)
+
+									if (dw_TimeOut == ui_TimeOut) {
+				/*****************/
+										/* Timeout occur */
+				/*****************/
+
+										break;
+									} else {
+				/*************************/
+										/* Increment the timeout */
+				/*************************/
+
+										dw_TimeOut
+											=
+											dw_TimeOut
+											+
+											1;
+
+										mdelay(1000);
+									}
+								}	// for (;;)
+
+			  /*************************/
+								/* Test if timeout occur */
+			  /*************************/
+
+								if ((*pb_TorCounterStatus != 3) && (dw_TimeOut == ui_TimeOut) && (ui_TimeOut != 0)) {
+			     /*****************/
+									/* Timeout occur */
+			     /*****************/
+
+									*pb_TorCounterStatus
+										=
+										4;
+								}
+							} else {
+			  /******************************/
+								/* Timeout parameter is wrong */
+			  /******************************/
+
+								DPRINTK("Timeout parameter is wrong\n");
+								i_ReturnValue =
+									-7;
+							}
+							break;
+
+						default:
+							printk("Inputs wrong\n");
+						}	// switch end
+					}	// if (dw_Status & 0x1)
+					else {
+		       /***************************/
+						/* Tor counter not enabled */
+		       /***************************/
+
+						DPRINTK("Tor counter not enabled\n");
+						i_ReturnValue = -6;
+					}	// if (dw_Status & 0x1)
+				} else {
+		    /*******************************/
+					/* Tor counter not initialised */
+		    /*******************************/
+
+					DPRINTK("Tor counter not initialised\n");
+					i_ReturnValue = -5;
+				}
+			}	// if (b_TorCounter <= 1)
+			else {
+		 /**********************************/
+				/* Tor counter selection is wrong */
+		 /**********************************/
+
+				DPRINTK("Tor counter selection is wrong\n");
+				i_ReturnValue = -4;
+			}	// if (b_TorCounter <= 1)
+		} else {
+	      /******************************************/
+			/* The module is not a tor counter module */
+	      /******************************************/
+
+			DPRINTK("The module is not a tor counter module\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /***********************/
+		/* Module number error */
+	   /***********************/
+
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h
new file mode 100644
index 0000000..c245d16
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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.
+ */
+
+#define APCI1710_30MHZ		30
+#define APCI1710_33MHZ		33
+#define APCI1710_40MHZ		40
+
+#define APCI1710_GATE_INPUT	10
+
+#define APCI1710_TOR_SIMPLE_MODE	2
+#define APCI1710_TOR_DOUBLE_MODE	3
+#define APCI1710_TOR_QUADRUPLE_MODE	4
+
+#define APCI1710_SINGLE			0
+#define APCI1710_CONTINUOUS		1
+
+#define APCI1710_TOR_GETPROGRESSSTATUS	0
+#define APCI1710_TOR_GETCOUNTERVALUE	1
+#define APCI1710_TOR_READINTERRUPT	2
+
+/*
+ * TOR_COUNTER INISIALISATION FUNCTION
+ */
+INT i_APCI1710_InsnConfigInitTorCounter(struct comedi_device *dev,
+					struct comedi_subdevice *s,
+					struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnWriteEnableDisableTorCounter(struct comedi_device *dev,
+						struct comedi_subdevice *s,
+						struct comedi_insn *insn,
+						unsigned int *data);
+
+INT i_APCI1710_InsnReadGetTorCounterInitialisation(struct comedi_device *dev,
+						   struct comedi_subdevice *s,
+						   struct comedi_insn *insn,
+						   unsigned int *data);
+/*
+ * TOR_COUNTER READ FUNCTION
+ */
+INT i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue(struct comedi_device *dev,
+							   struct comedi_subdevice *s,
+							   struct comedi_insn *insn,
+							   unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c
new file mode 100644
index 0000000..68b1d26
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c
@@ -0,0 +1,1038 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+
+        ADDI-DATA GmbH
+        Dieselstrasse 3
+        D-77833 Ottersweier
+        Tel: +19(0)7223/9493-0
+        Fax: +49(0)7223/9493-92
+        http://www.addi-data-com
+        info@addi-data.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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+  +-----------------------------------------------------------------------+
+  | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
+  +-----------------------------------------------------------------------+
+  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
+  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
+  +-----------------------------------------------------------------------+
+  | Project     : API APCI1710    | Compiler : gcc                        |
+  | Module name : TTL.C           | Version  : 2.96                       |
+  +-------------------------------+---------------------------------------+
+  | Project manager: Eric Stolz   | Date     :  02/12/2002                |
+  +-----------------------------------------------------------------------+
+  | Description :   APCI-1710 TTL I/O module                              |
+  |                                                                       |
+  |                                                                       |
+  +-----------------------------------------------------------------------+
+  |                             UPDATES                                   |
+  +-----------------------------------------------------------------------+
+  |   Date   |   Author  |          Description of updates                |
+  +----------+-----------+------------------------------------------------+
+  | 13/05/98 | S. Weber  | TTL digital input / output implementation      |
+  |----------|-----------|------------------------------------------------|
+  | 08/05/00 | Guinot C  | - 0400/0228 All Function in RING 0             |
+  |          |           |   available                                    |
+  +-----------------------------------------------------------------------+
+  |          |           |                                                |
+  |          |           |                                                |
+  +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+|                               Included files                               |
++----------------------------------------------------------------------------+
+*/
+
+#include "APCI1710_Ttl.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_InitTTLIODirection                    |
+|                               (BYTE_    b_BoardHandle,                     |
+|				 BYTE_    b_ModulNbr,                        |
+|				 BYTE_    b_PortAMode,                       |
+|				 BYTE_    b_PortBMode,                       |
+|				 BYTE_    b_PortCMode,                       |
+|				 BYTE_    b_PortDMode)                       |
++----------------------------------------------------------------------------+
+| Task           APCI1710_TTL_INIT (using defaults)   : Configure the TTL I/O operating mode from selected     |
+|                     module  (b_ModulNbr). You must calling this function be|
+|                     for you call any other function witch access of TTL.   |
+				 APCI1710_TTL_INITDIRECTION(user inputs for direction)
+
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle         : Handle of board APCI-1710|
+|                     BYTE_ b_ModulNbr            : Module number to         |
+|                                                   configure (0 to 3)
+		b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+		b_InitType = (BYTE) data[0];
+		b_PortAMode	= (BYTE) data[1];
+		b_PortBMode = (BYTE) data[2];
+		b_PortCMode = (BYTE) data[3];
+		b_PortDMode	= (BYTE) data[4];|
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : 0: No error                                            |
+|                    -1: The handle parameter of the board is wrong          |
+|                    -2: The module parameter is wrong                       |
+|                    -3: The module is not a TTL module                      |
+|		     -4: Function not available for this version             |
+|		     -5: Port A mode selection is wrong                      |
+|		     -6: Port B mode selection is wrong                      |
+|		     -7: Port C mode selection is wrong                      |
+|		     -8: Port D mode selection is wrong                      |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigInitTTLIO(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = 0;
+	BYTE b_ModulNbr;
+	BYTE b_InitType;
+	BYTE b_PortAMode;
+	BYTE b_PortBMode;
+	BYTE b_PortCMode;
+	BYTE b_PortDMode;
+
+	b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+	b_InitType = (BYTE) data[0];
+	i_ReturnValue = insn->n;
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /**************************/
+		/* Test if TTL I/O module */
+	   /**************************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_TTL_IO) {
+			switch (b_InitType) {
+			case APCI1710_TTL_INIT:
+
+				devpriv->s_ModuleInfo[b_ModulNbr].
+					s_TTLIOInfo.b_TTLInit = 1;
+
+	      /***************************/
+				/* Set TTL port A to input */
+	      /***************************/
+
+				devpriv->s_ModuleInfo[b_ModulNbr].
+					s_TTLIOInfo.b_PortConfiguration[0] = 0;
+
+	      /***************************/
+				/* Set TTL port B to input */
+	      /***************************/
+
+				devpriv->s_ModuleInfo[b_ModulNbr].
+					s_TTLIOInfo.b_PortConfiguration[1] = 0;
+
+	      /***************************/
+				/* Set TTL port C to input */
+	      /***************************/
+
+				devpriv->s_ModuleInfo[b_ModulNbr].
+					s_TTLIOInfo.b_PortConfiguration[2] = 0;
+
+	      /****************************/
+				/* Set TTL port D to output */
+	      /****************************/
+
+				devpriv->s_ModuleInfo[b_ModulNbr].
+					s_TTLIOInfo.b_PortConfiguration[3] = 1;
+
+	      /*************************/
+				/* Set the configuration */
+	      /*************************/
+
+				outl(0x8,
+					devpriv->s_BoardInfos.ui_Address + 20 +
+					(64 * b_ModulNbr));
+				break;
+
+			case APCI1710_TTL_INITDIRECTION:
+
+				b_PortAMode = (BYTE) data[1];
+				b_PortBMode = (BYTE) data[2];
+				b_PortCMode = (BYTE) data[3];
+				b_PortDMode = (BYTE) data[4];
+
+	      /********************/
+				/* Test the version */
+	      /********************/
+
+				if ((devpriv->s_BoardInfos.
+						dw_MolduleConfiguration
+						[b_ModulNbr] & 0xFFFF) >=
+					0x3230) {
+		 /************************/
+					/* Test the port A mode */
+		 /************************/
+
+					if ((b_PortAMode == 0)
+						|| (b_PortAMode == 1)) {
+		    /************************/
+						/* Test the port B mode */
+		    /************************/
+
+						if ((b_PortBMode == 0)
+							|| (b_PortBMode == 1)) {
+		       /************************/
+							/* Test the port C mode */
+		       /************************/
+
+							if ((b_PortCMode == 0)
+								|| (b_PortCMode
+									== 1)) {
+			  /************************/
+								/* Test the port D mode */
+			  /************************/
+
+								if ((b_PortDMode == 0) || (b_PortDMode == 1)) {
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_TTLIOInfo.
+										b_TTLInit
+										=
+										1;
+
+			     /***********************/
+									/* Set TTL port A mode */
+			     /***********************/
+
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_TTLIOInfo.
+										b_PortConfiguration
+										[0]
+										=
+										b_PortAMode;
+
+			     /***********************/
+									/* Set TTL port B mode */
+			     /***********************/
+
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_TTLIOInfo.
+										b_PortConfiguration
+										[1]
+										=
+										b_PortBMode;
+
+			     /***********************/
+									/* Set TTL port C mode */
+			     /***********************/
+
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_TTLIOInfo.
+										b_PortConfiguration
+										[2]
+										=
+										b_PortCMode;
+
+			     /***********************/
+									/* Set TTL port D mode */
+			     /***********************/
+
+									devpriv->
+										s_ModuleInfo
+										[b_ModulNbr].
+										s_TTLIOInfo.
+										b_PortConfiguration
+										[3]
+										=
+										b_PortDMode;
+
+			     /*************************/
+									/* Set the configuration */
+			     /*************************/
+
+									outl((b_PortAMode << 0) | (b_PortBMode << 1) | (b_PortCMode << 2) | (b_PortDMode << 3), devpriv->s_BoardInfos.ui_Address + 20 + (64 * b_ModulNbr));
+								} else {
+			     /**********************************/
+									/* Port D mode selection is wrong */
+			     /**********************************/
+
+									DPRINTK("Port D mode selection is wrong\n");
+									i_ReturnValue
+										=
+										-8;
+								}
+							} else {
+			  /**********************************/
+								/* Port C mode selection is wrong */
+			  /**********************************/
+
+								DPRINTK("Port C mode selection is wrong\n");
+								i_ReturnValue =
+									-7;
+							}
+						} else {
+		       /**********************************/
+							/* Port B mode selection is wrong */
+		       /**********************************/
+
+							DPRINTK("Port B mode selection is wrong\n");
+							i_ReturnValue = -6;
+						}
+					} else {
+		    /**********************************/
+						/* Port A mode selection is wrong */
+		    /**********************************/
+
+						DPRINTK("Port A mode selection is wrong\n");
+						i_ReturnValue = -5;
+					}
+				} else {
+		 /*******************************************/
+					/* Function not available for this version */
+		 /*******************************************/
+
+					DPRINTK("Function not available for this version\n");
+					i_ReturnValue = -4;
+				}
+				break;
+
+				DPRINTK("\n");
+			default:
+				printk("Bad Config Type\n");
+			}	// switch end
+		} else {
+	      /**********************************/
+			/* The module is not a TTL module */
+	      /**********************************/
+
+			DPRINTK("The module is not a TTL module\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /***********************/
+		/* Module number error */
+	   /***********************/
+
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+|                            INPUT FUNCTIONS                                 |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_   i_APCI1710_ReadTTLIOChannelValue               |
+|                                       (BYTE_     b_BoardHandle,            |
+|                                        BYTE_     b_ModulNbr,               |
+|                                        BYTE_     b_SelectedPort,           |
+|                                        BYTE_     b_InputChannel,           |
+|                                        PBYTE_   pb_ChannelStatus)          |
++----------------------------------------------------------------------------+
+| Task              : Read the status from selected TTL digital input        |
+|                     (b_InputChannel)
++----------------------------------------------------------------------------+
+| Task              : Read the status from digital input port                |
+|                     (b_SelectedPort) from selected TTL module (b_ModulNbr) |
++----------------------------------------------------------------------------+
+
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle         : Handle of board APCI-1710|
+|                     BYTE_ b_ModulNbr            : Module number to         |
+|                                                   configure (0 to 7)       |
+|                     BYTE_ b_SelectedPort,       : Selection from TTL I/O   |
+|                                                   port (0 to 2)            |
+|                                                      0 : Port A selection  |
+|                                                      1 : Port B selection  |
+|                                                      2 : Port C selection  |
+|                                                      3 : Port D selection  |
+|                     BYTE_ b_InputChannel        : Selection from digital   |
+|                                                   input ( 0 to 2)
+APCI1710_TTL_READCHANNEL
+	b_ModulNbr	  = CR_AREF(insn->chanspec);
+	b_SelectedPort= CR_RANGE(insn->chanspec);
+	b_InputChannel= CR_CHAN(insn->chanspec);
+	b_ReadType	  = (BYTE) data[0];
+
+ APCI1710_TTL_READPORT|
+	b_ModulNbr	  = CR_AREF(insn->chanspec);
+	b_SelectedPort= CR_RANGE(insn->chanspec);
+	b_ReadType	  = (BYTE) data[0];
+
++----------------------------------------------------------------------------+
+| Output Parameters : data[0]
+
+	PBYTE_  pb_ChannelStatus    : Digital input channel    |
+|                                                   status                   |
+|                                                   0 : Channle is not active|
+|                                                   1 : Channle is active    |
++----------------------------------------------------------------------------+
+| Return Value      : 0: No error                                            |
+|                    -1: The handle parameter of the board is wrong          |
+|                    -2: The module parameter is wrong                       |
+|                    -3: The module is not a TTL module                      |
+|                    -4: The selected TTL input port is wrong                |
+|                    -5: The selected TTL digital input is wrong             |
+|                    -6: TTL I/O not initialised                             |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnBitsReadTTLIO(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_StatusReg;
+	BYTE b_ModulNbr;
+	BYTE b_SelectedPort;
+	BYTE b_InputChannel;
+	BYTE b_ReadType;
+	PBYTE pb_ChannelStatus;
+	PBYTE pb_PortValue;
+
+	i_ReturnValue = insn->n;
+	b_ReadType = (BYTE) data[0];
+	b_ModulNbr = CR_AREF(insn->chanspec);
+	b_SelectedPort = CR_RANGE(insn->chanspec);
+	b_InputChannel = CR_CHAN(insn->chanspec);
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /**************************/
+		/* Test if TTL I/O module */
+	   /**************************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_TTL_IO) {
+			switch (b_ReadType) {
+
+			case APCI1710_TTL_READCHANNEL:
+				pb_ChannelStatus = (PBYTE) & data[0];
+	      /********************************/
+				/* Test the TTL I/O port number */
+	      /********************************/
+
+				if (((b_SelectedPort <= 2)
+						&& ((devpriv->s_BoardInfos.
+								dw_MolduleConfiguration
+								[b_ModulNbr] &
+								0xFFFF) ==
+							0x3130))
+					|| ((b_SelectedPort <= 3)
+						&& ((devpriv->s_BoardInfos.
+								dw_MolduleConfiguration
+								[b_ModulNbr] &
+								0xFFFF) >=
+							0x3230))) {
+		 /******************************************/
+					/* Test the digital imnput channel number */
+		 /******************************************/
+
+					if (((b_InputChannel <= 7)
+							&& (b_SelectedPort < 3))
+						|| ((b_InputChannel <= 1)
+							&& (b_SelectedPort ==
+								3))) {
+		    /******************************************/
+						/* Test if the TTL I/O module initialised */
+		    /******************************************/
+
+						if (devpriv->
+							s_ModuleInfo
+							[b_ModulNbr].
+							s_TTLIOInfo.b_TTLInit ==
+							1) {
+		       /***********************************/
+							/* Test if TTL port used for input */
+		       /***********************************/
+
+							if (((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) == 0x3130) || (((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3230) && (devpriv->s_ModuleInfo[b_ModulNbr].s_TTLIOInfo.b_PortConfiguration[b_SelectedPort] == 0))) {
+			  /**************************/
+								/* Read all digital input */
+			  /**************************/
+
+								dw_StatusReg =
+									inl
+									(devpriv->
+									s_BoardInfos.
+									ui_Address
+									+
+									(64 * b_ModulNbr));
+
+								*pb_ChannelStatus
+									=
+									(BYTE) (
+									(dw_StatusReg
+										>>
+										(8 * b_SelectedPort)) >> b_InputChannel) & 1;
+							} else {
+			  /*******************************/
+								/* Selected TTL I/O port error */
+			  /*******************************/
+
+								DPRINTK("Selected TTL I/O port error\n");
+								i_ReturnValue =
+									-4;
+							}
+						} else {
+		       /***************************/
+							/* TTL I/O not initialised */
+		       /***************************/
+
+							DPRINTK("TTL I/O not initialised\n");
+							i_ReturnValue = -6;
+						}
+					} else {
+		    /********************************/
+						/* Selected digital input error */
+		    /********************************/
+
+						DPRINTK("Selected digital input error\n");
+						i_ReturnValue = -5;
+					}
+				} else {
+		 /*******************************/
+					/* Selected TTL I/O port error */
+		 /*******************************/
+
+					DPRINTK("Selected TTL I/O port error\n");
+					i_ReturnValue = -4;
+				}
+				break;
+
+			case APCI1710_TTL_READPORT:
+				pb_PortValue = (PBYTE) & data[0];
+			  /********************************/
+				/* Test the TTL I/O port number */
+			  /********************************/
+
+				if (((b_SelectedPort <= 2)
+						&& ((devpriv->s_BoardInfos.
+								dw_MolduleConfiguration
+								[b_ModulNbr] &
+								0xFFFF) ==
+							0x3130))
+					|| ((b_SelectedPort <= 3)
+						&& ((devpriv->s_BoardInfos.
+								dw_MolduleConfiguration
+								[b_ModulNbr] &
+								0xFFFF) >=
+							0x3230))) {
+		 /******************************************/
+					/* Test if the TTL I/O module initialised */
+		 /******************************************/
+
+					if (devpriv->s_ModuleInfo[b_ModulNbr].
+						s_TTLIOInfo.b_TTLInit == 1) {
+		    /***********************************/
+						/* Test if TTL port used for input */
+		    /***********************************/
+
+						if (((devpriv->s_BoardInfos.
+									dw_MolduleConfiguration
+									[b_ModulNbr]
+									&
+									0xFFFF)
+								== 0x3130)
+							|| (((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3230) && (devpriv->s_ModuleInfo[b_ModulNbr].s_TTLIOInfo.b_PortConfiguration[b_SelectedPort] == 0))) {
+		       /**************************/
+							/* Read all digital input */
+		       /**************************/
+
+							dw_StatusReg =
+								inl(devpriv->
+								s_BoardInfos.
+								ui_Address +
+								(64 * b_ModulNbr));
+
+							*pb_PortValue =
+								(BYTE) (
+								(dw_StatusReg >>
+									(8 * b_SelectedPort)) & 0xFF);
+						} else {
+		       /*******************************/
+							/* Selected TTL I/O port error */
+		       /*******************************/
+
+							DPRINTK("Selected TTL I/O port error\n");
+							i_ReturnValue = -4;
+						}
+					} else {
+		    /***************************/
+						/* TTL I/O not initialised */
+		    /***************************/
+
+						DPRINTK("TTL I/O not initialised\n");
+						i_ReturnValue = -5;
+					}
+				} else {
+		 /*******************************/
+					/* Selected TTL I/O port error */
+		 /*******************************/
+
+					DPRINTK("Selected TTL I/O port error\n");
+					i_ReturnValue = -4;
+				}
+				break;
+
+			default:
+				printk("Bad ReadType\n");
+
+			}	//End Switch
+		} else {
+	      /**********************************/
+			/* The module is not a TTL module */
+	      /**********************************/
+
+			DPRINTK("The module is not a TTL module\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /***********************/
+		/* Module number error */
+	   /***********************/
+
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : INT i_APCI1710_InsnReadTTLIOAllPortValue(comedi_device
+*dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)              |
++----------------------------------------------------------------------------+
+| Task              : Read the status from all digital input ports           |
+|                     (port A, port B and port C) from selected TTL          |
+|		      module (b_ModulNbr) 				     |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle         : Handle of board APCI-1710|
+|                     BYTE_ b_ModulNbr            : Module number to         |
+|                                                   configure (0 to 3)       |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_  pul_PortValue      : Digital TTL inputs port  |
+|                                                   status                   |
++----------------------------------------------------------------------------+
+| Return Value      : 0: No error                                            |
+|                    -1: The handle parameter of the board is wrong          |
+|                    -2: The module parameter is wrong                       |
+|                    -3: The module is not a TTL module                      |
+|                    -4: TTL I/O not initialised                             |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnReadTTLIOAllPortValue(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_StatusReg;
+	BYTE b_ModulNbr;
+	PULONG pul_PortValue;
+
+	b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+	i_ReturnValue = insn->n;
+	pul_PortValue = (PULONG) & data[0];
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /**************************/
+		/* Test if TTL I/O module */
+	   /**************************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_TTL_IO) {
+	      /******************************************/
+			/* Test if the TTL I/O module initialised */
+	      /******************************************/
+
+			if (devpriv->
+				s_ModuleInfo[b_ModulNbr].
+				s_TTLIOInfo.b_TTLInit == 1) {
+		 /**************************/
+				/* Read all digital input */
+		 /**************************/
+
+				dw_StatusReg = inl(devpriv->s_BoardInfos.
+					ui_Address + (64 * b_ModulNbr));
+
+		 /**********************/
+				/* Test if TTL Rev1.0 */
+		 /**********************/
+
+				if ((devpriv->s_BoardInfos.
+						dw_MolduleConfiguration
+						[b_ModulNbr] & 0xFFFF) ==
+					0x3130) {
+					*pul_PortValue =
+						dw_StatusReg & 0xFFFFFFUL;
+				} else {
+		    /**************************************/
+					/* Test if port A not used for output */
+		    /**************************************/
+
+					if (devpriv->s_ModuleInfo[b_ModulNbr].
+						s_TTLIOInfo.
+						b_PortConfiguration[0] == 1) {
+						*pul_PortValue =
+							dw_StatusReg &
+							0x3FFFF00UL;
+					}
+
+		    /**************************************/
+					/* Test if port B not used for output */
+		    /**************************************/
+
+					if (devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_TTLIOInfo.
+						b_PortConfiguration[1] == 1) {
+						*pul_PortValue =
+							dw_StatusReg &
+							0x3FF00FFUL;
+					}
+
+		    /**************************************/
+					/* Test if port C not used for output */
+		    /**************************************/
+
+					if (devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_TTLIOInfo.
+						b_PortConfiguration[2] == 1) {
+						*pul_PortValue =
+							dw_StatusReg &
+							0x300FFFFUL;
+					}
+
+		    /**************************************/
+					/* Test if port D not used for output */
+		    /**************************************/
+
+					if (devpriv->
+						s_ModuleInfo[b_ModulNbr].
+						s_TTLIOInfo.
+						b_PortConfiguration[3] == 1) {
+						*pul_PortValue =
+							dw_StatusReg &
+							0xFFFFFFUL;
+					}
+				}
+			} else {
+		 /***************************/
+				/* TTL I/O not initialised */
+		 /***************************/
+				DPRINTK("TTL I/O not initialised\n");
+				i_ReturnValue = -5;
+			}
+		} else {
+	      /**********************************/
+			/* The module is not a TTL module */
+	      /**********************************/
+			DPRINTK("The module is not a TTL module\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /***********************/
+		/* Module number error */
+	   /***********************/
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+|                            OUTPUT FUNCTIONS                                |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_SetTTLIOChlOn                         |
+|                               (BYTE_           b_BoardHandle,              |
+|                                BYTE_           b_ModulNbr,                 |
+|                                BYTE_           b_OutputChannel)
+INT i_APCI1710_InsnWriteSetTTLIOChlOnOff(struct comedi_device *dev,struct comedi_subdevice *s,
+	struct comedi_insn *insn,unsigned int *data)           |
++----------------------------------------------------------------------------+
+| Task              : Sets or resets  the output witch has been passed with the         |
+|                     parameter b_Channel. Setting an output means setting   |
+|                     an ouput high.                                         |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle   : Handle of board APCI-1710      |
+|                     BYTE_ b_ModulNbr      : Selected module number (0 to 3)|
+|                     BYTE_ b_OutputChannel : Selection from digital output  |
+|                                             channel (0 or 1)               |
+|                                                0      : PD0                |
+|                                                1      : PD1                |
+|						 2 to 9 : PA                 |
+|						10 to 17: PB                 |
+|						18 to 25: PC                 |
+
+  b_ModulNbr	   = CR_AREF(insn->chanspec);
+	b_OutputChannel= CR_CHAN(insn->chanspec);
+	ui_State	   = data[0]; // ON or OFF
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : 0: No error                                            |
+|                    -1: The handle parameter of the board is wrong          |
+|                    -2: The module parameter is wrong                       |
+|                    -3: The module is not a TTL I/O module                  |
+|                    -4: The selected digital output is wrong                |
+|                    -5: TTL I/O not initialised see function                |
+|                        " i_APCI1710_InitTTLIO"
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnWriteSetTTLIOChlOnOff(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = 0;
+	DWORD dw_StatusReg = 0;
+	BYTE b_ModulNbr;
+	BYTE b_OutputChannel;
+	UINT ui_State;
+
+	i_ReturnValue = insn->n;
+	b_ModulNbr = CR_AREF(insn->chanspec);
+	b_OutputChannel = CR_CHAN(insn->chanspec);
+	ui_State = data[0];	// ON or OFF
+
+	/**************************/
+	/* Test the module number */
+	/**************************/
+
+	if (b_ModulNbr < 4) {
+	   /**************************/
+		/* Test if TTL I/O module */
+	   /**************************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModulNbr] &
+				0xFFFF0000UL) == APCI1710_TTL_IO) {
+	      /******************************************/
+			/* Test if the TTL I/O module initialised */
+	      /******************************************/
+
+			if (devpriv->s_ModuleInfo[b_ModulNbr].
+				s_TTLIOInfo.b_TTLInit == 1) {
+		 /***********************************/
+				/* Test the TTL I/O channel number */
+		 /***********************************/
+
+				if (((b_OutputChannel <= 1)
+						&& ((devpriv->s_BoardInfos.
+								dw_MolduleConfiguration
+								[b_ModulNbr] &
+								0xFFFF) ==
+							0x3130))
+					|| ((b_OutputChannel <= 25)
+						&& ((devpriv->s_BoardInfos.
+								dw_MolduleConfiguration
+								[b_ModulNbr] &
+								0xFFFF) >=
+							0x3230))) {
+		    /****************************************************/
+					/* Test if the selected channel is a output channel */
+		    /****************************************************/
+
+					if (((b_OutputChannel <= 1)
+							&& (devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_TTLIOInfo.
+								b_PortConfiguration
+								[3] == 1))
+						|| ((b_OutputChannel >= 2)
+							&& (b_OutputChannel <=
+								9)
+							&& (devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_TTLIOInfo.
+								b_PortConfiguration
+								[0] == 1))
+						|| ((b_OutputChannel >= 10)
+							&& (b_OutputChannel <=
+								17)
+							&& (devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_TTLIOInfo.
+								b_PortConfiguration
+								[1] == 1))
+						|| ((b_OutputChannel >= 18)
+							&& (b_OutputChannel <=
+								25)
+							&& (devpriv->
+								s_ModuleInfo
+								[b_ModulNbr].
+								s_TTLIOInfo.
+								b_PortConfiguration
+								[2] == 1))) {
+		       /************************/
+						/* Test if PD0 selected */
+		       /************************/
+
+						if (b_OutputChannel == 0) {
+
+							outl(ui_State,
+								devpriv->
+								s_BoardInfos.
+								ui_Address +
+								(64 * b_ModulNbr));
+						} else {
+			  /************************/
+							/* Test if PD1 selected */
+			  /************************/
+
+							if (b_OutputChannel ==
+								1) {
+
+								outl(ui_State,
+									devpriv->
+									s_BoardInfos.
+									ui_Address
+									+ 4 +
+									(64 * b_ModulNbr));
+							} else {
+								b_OutputChannel
+									=
+									b_OutputChannel
+									- 2;
+
+			     /********************/
+								/* Read all channel */
+			     /********************/
+
+								dw_StatusReg =
+									inl
+									(devpriv->
+									s_BoardInfos.
+									ui_Address
+									+
+									(64 * b_ModulNbr));
+								if (ui_State)	// ON
+								{
+									dw_StatusReg
+										=
+										(dw_StatusReg
+										>>
+										((b_OutputChannel / 8) * 8)) & 0xFF;
+									dw_StatusReg
+										=
+										dw_StatusReg
+										|
+										(1
+										<<
+										(b_OutputChannel
+											%
+											8));
+								} else	// Off
+								{
+									dw_StatusReg
+										=
+										(dw_StatusReg
+										>>
+										((b_OutputChannel / 8) * 8)) & 0xFF;
+									dw_StatusReg
+										=
+										dw_StatusReg
+										&
+										(0xFF
+										-
+										(1 << (b_OutputChannel % 8)));
+
+								}
+
+			     /****************************/
+								/* Set the new output value */
+			     /****************************/
+
+								outl(dw_StatusReg, devpriv->s_BoardInfos.ui_Address + 8 + ((b_OutputChannel / 8) * 4) + (64 * b_ModulNbr));
+							}
+						}
+					} else {
+		       /************************************/
+						/* The selected TTL output is wrong */
+		       /************************************/
+
+						DPRINTK(" The selected TTL output is wrong\n");
+						i_ReturnValue = -4;
+					}
+				} else {
+		    /************************************/
+					/* The selected TTL output is wrong */
+		    /************************************/
+
+					DPRINTK("The selected TTL output is wrong\n");
+					i_ReturnValue = -4;
+				}
+			} else {
+		 /***************************/
+				/* TTL I/O not initialised */
+		 /***************************/
+
+				DPRINTK("TTL I/O not initialised\n");
+				i_ReturnValue = -5;
+			}
+		} else {
+	      /**************************************/
+			/* The module is not a TTL I/O module */
+	      /**************************************/
+
+			DPRINTK("The module is not a TTL I/O module\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /***********************/
+		/* Module number error */
+	   /***********************/
+
+		DPRINTK("Module number error\n");
+		i_ReturnValue = -2;
+	}
+
+	return (i_ReturnValue);
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h
new file mode 100644
index 0000000..00915dd
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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.
+ */
+
+#define APCI1710_TTL_INIT		0
+#define APCI1710_TTL_INITDIRECTION	1
+
+#define APCI1710_TTL_READCHANNEL	0
+#define APCI1710_TTL_READPORT		1
+
+/*
+ * TTL INISIALISATION FUNCTION
+ */
+INT i_APCI1710_InsnConfigInitTTLIO(struct comedi_device *dev, struct comedi_subdevice *s,
+				   struct comedi_insn *insn, unsigned int *data);
+
+/*
+ * TTL INPUT FUNCTION
+ */
+INT i_APCI1710_InsnBitsReadTTLIO(struct comedi_device *dev, struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data);
+INT i_APCI1710_InsnReadTTLIOAllPortValue(struct comedi_device *dev,
+					 struct comedi_subdevice *s,
+					 struct comedi_insn *insn, unsigned int *data);
+
+/*
+ * TTL OUTPUT FUNCTIONS
+ */
+INT i_APCI1710_InsnWriteSetTTLIOChlOnOff(struct comedi_device *dev,
+					 struct comedi_subdevice *s,
+					 struct comedi_insn *insn, unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c b/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c
new file mode 100644
index 0000000..b0907ec
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c
@@ -0,0 +1,203 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+
+        ADDI-DATA GmbH
+        Dieselstrasse 3
+        D-77833 Ottersweier
+        Tel: +19(0)7223/9493-0
+        Fax: +49(0)7223/9493-92
+        http://www.addi-data-com
+        info@addi-data.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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+  +-----------------------------------------------------------------------+
+  | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
+  +-----------------------------------------------------------------------+
+  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
+  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
+  +-------------------------------+---------------------------------------+
+  | Project : ADDI HEADER READ WRITER |     Compiler   : Visual C++       |
+  | Module name : S5920.cpp           |     Version    : 6.0              |
+  +-------------------------------+---------------------------------------+
+  | Author : E. LIBS                      Date : 02/05/2002               |
+  +-----------------------------------------------------------------------+
+  | Description   : DLL with the S5920 PCI Controller functions           |
+  +-----------------------------------------------------------------------+
+  |                             UPDATE'S                                  |
+  +-----------------------------------------------------------------------+
+  |   Date   |   Author  |          Description of updates                |
+  +----------+-----------+------------------------------------------------+
+  | 28/08/02 | LIBS Eric | Add return codes each time a function of the   |
+  |          |           | Addi Library is called                         |
+  +-----------------------------------------------------------------------+
+  | 31/07/03 | KRAUTH J. | Changes for the MSX-Box                        |
+  +-----------------------------------------------------------------------+
+*/
+
+#include "addi_amcc_S5920.h"
+
+/*+----------------------------------------------------------------------------+*/
+/*| Function   Name   : INT i_AddiHeaderRW_ReadEeprom                          |*/
+/*|                               (INT    i_NbOfWordsToRead,                   |*/
+/*|                                DWORD dw_PCIBoardEepromAddress,             |*/
+/*|                                WORD   w_EepromStartAddress,                |*/
+/*|                                PWORD pw_DataRead)                          |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Task              : Read word from the 5920 eeprom.                        |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Input Parameters  : INT    i_NbOfWordsToRead : Nbr. of word to read        |*/
+/*|                     DWORD dw_PCIBoardEepromAddress : Address of the eeprom |*/
+/*|                     WORD   w_EepromStartAddress : Eeprom strat address     |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Output Parameters : PWORD pw_DataRead : Read data                          |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Return Value      : -                                                      |*/
+/*+----------------------------------------------------------------------------+*/
+
+INT i_AddiHeaderRW_ReadEeprom(INT i_NbOfWordsToRead,
+	DWORD dw_PCIBoardEepromAddress,
+	WORD w_EepromStartAddress, PWORD pw_DataRead)
+{
+	DWORD dw_eeprom_busy = 0;
+	INT i_Counter = 0;
+	INT i_WordCounter;
+	INT i;
+	BYTE pb_ReadByte[1];
+	BYTE b_ReadLowByte = 0;
+	BYTE b_ReadHighByte = 0;
+	BYTE b_SelectedAddressLow = 0;
+	BYTE b_SelectedAddressHigh = 0;
+	WORD w_ReadWord = 0;
+
+	for (i_WordCounter = 0; i_WordCounter < i_NbOfWordsToRead;
+		i_WordCounter++) {
+		do {
+			dw_eeprom_busy =
+				inl(dw_PCIBoardEepromAddress +
+				AMCC_OP_REG_MCSR);
+			dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+		}
+		while (dw_eeprom_busy == EEPROM_BUSY);
+
+		for (i_Counter = 0; i_Counter < 2; i_Counter++) {
+			b_SelectedAddressLow = (w_EepromStartAddress + i_Counter) % 256;	//Read the low 8 bit part
+			b_SelectedAddressHigh = (w_EepromStartAddress + i_Counter) / 256;	//Read the high 8 bit part
+
+			//Select the load low address mode
+			outb(NVCMD_LOAD_LOW,
+				dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+				3);
+
+			//Wait on busy
+			do {
+				dw_eeprom_busy =
+					inl(dw_PCIBoardEepromAddress +
+					AMCC_OP_REG_MCSR);
+				dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+			}
+			while (dw_eeprom_busy == EEPROM_BUSY);
+
+			//Load the low address
+			outb(b_SelectedAddressLow,
+				dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+				2);
+
+			//Wait on busy
+			do {
+				dw_eeprom_busy =
+					inl(dw_PCIBoardEepromAddress +
+					AMCC_OP_REG_MCSR);
+				dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+			}
+			while (dw_eeprom_busy == EEPROM_BUSY);
+
+			//Select the load high address mode
+			outb(NVCMD_LOAD_HIGH,
+				dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+				3);
+
+			//Wait on busy
+			do {
+				dw_eeprom_busy =
+					inl(dw_PCIBoardEepromAddress +
+					AMCC_OP_REG_MCSR);
+				dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+			}
+			while (dw_eeprom_busy == EEPROM_BUSY);
+
+			//Load the high address
+			outb(b_SelectedAddressHigh,
+				dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+				2);
+
+			//Wait on busy
+			do {
+				dw_eeprom_busy =
+					inl(dw_PCIBoardEepromAddress +
+					AMCC_OP_REG_MCSR);
+				dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+			}
+			while (dw_eeprom_busy == EEPROM_BUSY);
+
+			//Select the READ mode
+			outb(NVCMD_BEGIN_READ,
+				dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+				3);
+
+			//Wait on busy
+			do {
+				dw_eeprom_busy =
+					inl(dw_PCIBoardEepromAddress +
+					AMCC_OP_REG_MCSR);
+				dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+			}
+			while (dw_eeprom_busy == EEPROM_BUSY);
+
+			//Read data into the EEPROM
+			*pb_ReadByte =
+				inb(dw_PCIBoardEepromAddress +
+				AMCC_OP_REG_MCSR + 2);
+
+			//Wait on busy
+			do {
+				dw_eeprom_busy =
+					inl(dw_PCIBoardEepromAddress +
+					AMCC_OP_REG_MCSR);
+				dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+			}
+			while (dw_eeprom_busy == EEPROM_BUSY);
+
+			//Select the upper address part
+			if (i_Counter == 0) {
+				b_ReadLowByte = pb_ReadByte[0];
+			} else {
+				b_ReadHighByte = pb_ReadByte[0];
+			}
+
+			//Sleep
+			for (i = 0; i < 10000; i++) ;
+
+		}
+		w_ReadWord =
+			(b_ReadLowByte | (((unsigned short)b_ReadHighByte) *
+				256));
+
+		pw_DataRead[i_WordCounter] = w_ReadWord;
+
+		w_EepromStartAddress += 2;	// to read the next word
+
+	}			// for (...) i_NbOfWordsToRead
+	return (0);
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.h b/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.h
new file mode 100644
index 0000000..9ae56bc
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.h
@@ -0,0 +1,27 @@
+/*
+ *  Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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.
+ */
+
+#define AMCC_OP_REG_MCSR	0x3c
+#define EEPROM_BUSY		0x80000000
+#define NVCMD_LOAD_LOW		(0x4 << 5)	/* nvRam load low command */
+#define NVCMD_LOAD_HIGH		(0x5 << 5)	/* nvRam load high command */
+#define NVCMD_BEGIN_READ	(0x7 << 5)	/* nvRam begin read command */
+#define NVCMD_BEGIN_WRITE	(0x6 << 5)	/* EEPROM begin write command */
+
+INT i_AddiHeaderRW_ReadEeprom(INT i_NbOfWordsToRead,
+			      DWORD dw_PCIBoardEepromAddress,
+			      WORD w_EepromStartAddress, PWORD pw_DataRead);
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h
new file mode 100644
index 0000000..b50774c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h
@@ -0,0 +1,476 @@
+/*
+ *  Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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.
+ */
+
+/* Header file for AMCC  s 5933 */
+
+#ifndef _AMCC_S5933_H_
+#define _AMCC_S5933_H_
+
+#include "../../comedidev.h"
+
+#include "../comedi_pci.h"
+
+#ifdef PCI_SUPPORT_VER1
+#error     No support for 2.1.55 and older
+#endif
+
+/* written on base0 */
+#define FIFO_ADVANCE_ON_BYTE_2	0x20000000
+
+/* added for step 6 dma written on base2 */
+#define AMWEN_ENABLE		0x02
+
+#define A2P_FIFO_WRITE_ENABLE	0x01
+
+/* for transfer count enable bit */
+#define AGCSTS_TC_ENABLE	0x10000000
+
+/*
+ * ADDON RELATED ADDITIONS
+ */
+/* Constant */
+#define APCI3120_ENABLE_TRANSFER_ADD_ON_LOW		0x00
+#define APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH		0x1200
+#define APCI3120_A2P_FIFO_MANAGEMENT			0x04000400L
+#define APCI3120_AMWEN_ENABLE				0x02
+#define APCI3120_A2P_FIFO_WRITE_ENABLE			0x01
+#define APCI3120_FIFO_ADVANCE_ON_BYTE_2			0x20000000L
+#define APCI3120_ENABLE_WRITE_TC_INT			0x00004000L
+#define APCI3120_CLEAR_WRITE_TC_INT			0x00040000L
+#define APCI3120_DISABLE_AMWEN_AND_A2P_FIFO_WRITE	0x0
+#define APCI3120_DISABLE_BUS_MASTER_ADD_ON		0x0
+#define APCI3120_DISABLE_BUS_MASTER_PCI			0x0
+
+/* ADD_ON ::: this needed since apci supports 16 bit interface to add on */
+#define APCI3120_ADD_ON_AGCSTS_LOW	0x3C
+#define APCI3120_ADD_ON_AGCSTS_HIGH	(APCI3120_ADD_ON_AGCSTS_LOW + 2)
+#define APCI3120_ADD_ON_MWAR_LOW	0x24
+#define APCI3120_ADD_ON_MWAR_HIGH	(APCI3120_ADD_ON_MWAR_LOW + 2)
+#define APCI3120_ADD_ON_MWTC_LOW	0x058
+#define APCI3120_ADD_ON_MWTC_HIGH	(APCI3120_ADD_ON_MWTC_LOW + 2)
+
+/* AMCC */
+#define APCI3120_AMCC_OP_MCSR		0x3C
+#define APCI3120_AMCC_OP_REG_INTCSR	0x38
+
+/*
+ * AMCC Operation Register Offsets - PCI
+ */
+#define AMCC_OP_REG_OMB1		0x00
+#define AMCC_OP_REG_OMB2		0x04
+#define AMCC_OP_REG_OMB3		0x08
+#define AMCC_OP_REG_OMB4		0x0c
+#define AMCC_OP_REG_IMB1		0x10
+#define AMCC_OP_REG_IMB2		0x14
+#define AMCC_OP_REG_IMB3		0x18
+#define AMCC_OP_REG_IMB4		0x1c
+#define AMCC_OP_REG_FIFO		0x20
+#define AMCC_OP_REG_MWAR		0x24
+#define AMCC_OP_REG_MWTC		0x28
+#define AMCC_OP_REG_MRAR		0x2c
+#define AMCC_OP_REG_MRTC		0x30
+#define AMCC_OP_REG_MBEF		0x34
+#define AMCC_OP_REG_INTCSR		0x38
+/* INT source */
+#define  AMCC_OP_REG_INTCSR_SRC		(AMCC_OP_REG_INTCSR + 2)
+/* FIFO ctrl */
+#define  AMCC_OP_REG_INTCSR_FEC		(AMCC_OP_REG_INTCSR + 3)
+#define AMCC_OP_REG_MCSR		0x3c
+/* Data in byte 2 */
+#define  AMCC_OP_REG_MCSR_NVDATA	(AMCC_OP_REG_MCSR + 2)
+/* Command in byte 3 */
+#define  AMCC_OP_REG_MCSR_NVCMD		(AMCC_OP_REG_MCSR + 3)
+
+#define AMCC_FIFO_DEPTH_DWORD	8
+#define AMCC_FIFO_DEPTH_BYTES	(8 * sizeof(u32))
+
+/*
+ * AMCC Operation Registers Size - PCI
+ */
+#define AMCC_OP_REG_SIZE	 64	/* in bytes */
+
+/*
+ * AMCC Operation Register Offsets - Add-on
+ */
+#define AMCC_OP_REG_AIMB1	0x00
+#define AMCC_OP_REG_AIMB2	0x04
+#define AMCC_OP_REG_AIMB3	0x08
+#define AMCC_OP_REG_AIMB4	0x0c
+#define AMCC_OP_REG_AOMB1	0x10
+#define AMCC_OP_REG_AOMB2	0x14
+#define AMCC_OP_REG_AOMB3	0x18
+#define AMCC_OP_REG_AOMB4	0x1c
+#define AMCC_OP_REG_AFIFO	0x20
+#define AMCC_OP_REG_AMWAR	0x24
+#define AMCC_OP_REG_APTA	0x28
+#define AMCC_OP_REG_APTD	0x2c
+#define AMCC_OP_REG_AMRAR	0x30
+#define AMCC_OP_REG_AMBEF	0x34
+#define AMCC_OP_REG_AINT	0x38
+#define AMCC_OP_REG_AGCSTS	0x3c
+#define AMCC_OP_REG_AMWTC	0x58
+#define AMCC_OP_REG_AMRTC	0x5c
+
+/*
+ * AMCC - Add-on General Control/Status Register
+ */
+#define AGCSTS_CONTROL_MASK	0xfffff000
+#define  AGCSTS_NV_ACC_MASK	0xe0000000
+#define  AGCSTS_RESET_MASK	0x0e000000
+#define  AGCSTS_NV_DA_MASK	0x00ff0000
+#define  AGCSTS_BIST_MASK	0x0000f000
+#define AGCSTS_STATUS_MASK	0x000000ff
+#define  AGCSTS_TCZERO_MASK	0x000000c0
+#define  AGCSTS_FIFO_ST_MASK	0x0000003f
+
+#define AGCSTS_RESET_MBFLAGS	0x08000000
+#define AGCSTS_RESET_P2A_FIFO	0x04000000
+#define AGCSTS_RESET_A2P_FIFO	0x02000000
+#define AGCSTS_RESET_FIFOS	(AGCSTS_RESET_A2P_FIFO | AGCSTS_RESET_P2A_FIFO)
+
+#define AGCSTS_A2P_TCOUNT	0x00000080
+#define AGCSTS_P2A_TCOUNT	0x00000040
+
+#define AGCSTS_FS_P2A_EMPTY	0x00000020
+#define AGCSTS_FS_P2A_HALF	0x00000010
+#define AGCSTS_FS_P2A_FULL	0x00000008
+
+#define AGCSTS_FS_A2P_EMPTY	0x00000004
+#define AGCSTS_FS_A2P_HALF	0x00000002
+#define AGCSTS_FS_A2P_FULL	0x00000001
+
+/*
+ * AMCC - Add-on Interrupt Control/Status Register
+ */
+#define AINT_INT_MASK		0x00ff0000
+#define AINT_SEL_MASK		0x0000ffff
+#define  AINT_IS_ENSEL_MASK	0x00001f1f
+
+#define AINT_INT_ASSERTED	0x00800000
+#define AINT_BM_ERROR		0x00200000
+#define AINT_BIST_INT		0x00100000
+
+#define AINT_RT_COMPLETE	0x00080000
+#define AINT_WT_COMPLETE	0x00040000
+
+#define AINT_OUT_MB_INT		0x00020000
+#define AINT_IN_MB_INT		0x00010000
+
+#define AINT_READ_COMPL		0x00008000
+#define AINT_WRITE_COMPL	0x00004000
+
+#define AINT_OMB_ENABLE 	0x00001000
+#define AINT_OMB_SELECT 	0x00000c00
+#define AINT_OMB_BYTE		0x00000300
+
+#define AINT_IMB_ENABLE 	0x00000010
+#define AINT_IMB_SELECT 	0x0000000c
+#define AINT_IMB_BYTE		0x00000003
+
+/* Enable Bus Mastering */
+#define EN_A2P_TRANSFERS	0x00000400
+/* FIFO Flag Reset */
+#define RESET_A2P_FLAGS		0x04000000L
+/* FIFO Relative Priority */
+#define A2P_HI_PRIORITY		0x00000100L
+/* Identify Interrupt Sources */
+#define ANY_S593X_INT		0x00800000L
+#define READ_TC_INT		0x00080000L
+#define WRITE_TC_INT		0x00040000L
+#define IN_MB_INT		0x00020000L
+#define MASTER_ABORT_INT	0x00100000L
+#define TARGET_ABORT_INT	0x00200000L
+#define BUS_MASTER_INT		0x00200000L
+
+/****************************************************************************/
+
+struct pcilst_struct {
+	struct pcilst_struct *next;
+	int used;
+	struct pci_dev *pcidev;
+	unsigned short vendor;
+	unsigned short device;
+	unsigned char pci_bus;
+	unsigned char pci_slot;
+	unsigned char pci_func;
+	resource_size_t io_addr[5];
+	unsigned int irq;
+};
+
+/* ptr to root list of all amcc devices */
+struct pcilst_struct *amcc_devices;
+
+static const int i_ADDIDATADeviceID[] = { 0x15B8, 0x10E8 };
+
+/****************************************************************************/
+
+void v_pci_card_list_init(unsigned short pci_vendor, char display);
+void v_pci_card_list_cleanup(unsigned short pci_vendor);
+struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
+						       unsigned short
+						       device_id);
+int i_find_free_pci_card_by_position(unsigned short vendor_id,
+				     unsigned short device_id,
+				     unsigned short pci_bus,
+				     unsigned short pci_slot,
+				     struct pcilst_struct **card);
+struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
+						    unsigned short device_id,
+						    unsigned short pci_bus,
+						    unsigned short pci_slot,
+						    int i_Master);
+
+int pci_card_alloc(struct pcilst_struct *amcc, int master);
+int i_pci_card_free(struct pcilst_struct *amcc);
+void v_pci_card_list_display(void);
+int i_pci_card_data(struct pcilst_struct *amcc,
+		    unsigned char *pci_bus, unsigned char *pci_slot,
+		    unsigned char *pci_func, resource_size_t * io_addr,
+		    unsigned int *irq);
+
+/****************************************************************************/
+
+/* build list of amcc cards in this system */
+void v_pci_card_list_init(unsigned short pci_vendor, char display)
+{
+	struct pci_dev *pcidev;
+	struct pcilst_struct *amcc, *last;
+	int i;
+	int i_Count = 0;
+	amcc_devices = NULL;
+	last = NULL;
+
+	for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+	     pcidev != NULL;
+	     pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+		for (i_Count = 0; i_Count < 2; i_Count++) {
+			pci_vendor = i_ADDIDATADeviceID[i_Count];
+			if (pcidev->vendor == pci_vendor) {
+				amcc = kmalloc(sizeof(*amcc), GFP_KERNEL);
+				memset(amcc, 0, sizeof(*amcc));
+
+				amcc->pcidev = pcidev;
+				if (last)
+					last->next = amcc;
+				else
+					amcc_devices = amcc;
+				last = amcc;
+
+				amcc->vendor = pcidev->vendor;
+				amcc->device = pcidev->device;
+				amcc->pci_bus = pcidev->bus->number;
+				amcc->pci_slot = PCI_SLOT(pcidev->devfn);
+				amcc->pci_func = PCI_FUNC(pcidev->devfn);
+				/* Note: resources may be invalid if PCI device
+				 * not enabled, but they are corrected in
+				 * pci_card_alloc. */
+				for (i = 0; i < 5; i++)
+					amcc->io_addr[i] =
+					    pci_resource_start(pcidev, i);
+				amcc->irq = pcidev->irq;
+
+			}
+		}
+	}
+
+	if (display)
+		v_pci_card_list_display();
+}
+
+/****************************************************************************/
+/* free up list of amcc cards in this system */
+void v_pci_card_list_cleanup(unsigned short pci_vendor)
+{
+	struct pcilst_struct *amcc, *next;
+
+	for (amcc = amcc_devices; amcc; amcc = next) {
+		next = amcc->next;
+		kfree(amcc);
+	}
+
+	amcc_devices = NULL;
+}
+
+/****************************************************************************/
+/* find first unused card with this device_id */
+struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
+						       unsigned short device_id)
+{
+	struct pcilst_struct *amcc, *next;
+
+	for (amcc = amcc_devices; amcc; amcc = next) {
+		next = amcc->next;
+		if ((!amcc->used) && (amcc->device == device_id)
+		    && (amcc->vendor == vendor_id))
+			return amcc;
+
+	}
+
+	return NULL;
+}
+
+/****************************************************************************/
+/* find card on requested position */
+int i_find_free_pci_card_by_position(unsigned short vendor_id,
+				     unsigned short device_id,
+				     unsigned short pci_bus,
+				     unsigned short pci_slot,
+				     struct pcilst_struct **card)
+{
+	struct pcilst_struct *amcc, *next;
+
+	*card = NULL;
+	for (amcc = amcc_devices; amcc; amcc = next) {
+		next = amcc->next;
+		if ((amcc->vendor == vendor_id) && (amcc->device == device_id)
+		    && (amcc->pci_bus == pci_bus)
+		    && (amcc->pci_slot == pci_slot)) {
+			if (!(amcc->used)) {
+				*card = amcc;
+				return 0;	/* ok, card is found */
+			} else {
+				rt_printk(" - \nCard on requested position is used b:s %d:%d!\n",
+					  pci_bus, pci_slot);
+				return 2;	/* card exist but is used */
+			}
+		}
+	}
+
+	/* no card found */
+	return 1;
+}
+
+/****************************************************************************/
+/* mark card as used */
+int pci_card_alloc(struct pcilst_struct *amcc, int master)
+{
+	int i;
+
+	if (!amcc)
+		return -1;
+
+	if (amcc->used)
+		return 1;
+	if (comedi_pci_enable(amcc->pcidev, "addi_amcc_s5933"))
+		return -1;
+	/* Resources will be accurate now. */
+	for (i = 0; i < 5; i++)
+		amcc->io_addr[i] = pci_resource_start(amcc->pcidev, i);
+	if (master)
+		pci_set_master(amcc->pcidev);
+	amcc->used = 1;
+
+	return 0;
+}
+
+/****************************************************************************/
+/* mark card as free */
+int i_pci_card_free(struct pcilst_struct *amcc)
+{
+	if (!amcc)
+		return -1;
+
+	if (!amcc->used)
+		return 1;
+	amcc->used = 0;
+	comedi_pci_disable(amcc->pcidev);
+	return 0;
+}
+
+/****************************************************************************/
+/* display list of found cards */
+void v_pci_card_list_display(void)
+{
+	struct pcilst_struct *amcc, *next;
+
+	printk(KERN_DEBUG "List of pci cards\n");
+	printk(KERN_DEBUG "bus:slot:func vendor device io_amcc io_daq irq used\n");
+
+	for (amcc = amcc_devices; amcc; amcc = next) {
+		next = amcc->next;
+		printk
+		    ("%2d   %2d   %2d  0x%4x 0x%4x   0x%8llx 0x%8llx  %2u  %2d\n",
+		     amcc->pci_bus, amcc->pci_slot, amcc->pci_func,
+		     amcc->vendor, amcc->device,
+		     (unsigned long long)amcc->io_addr[0],
+		     (unsigned long long)amcc->io_addr[2], amcc->irq,
+		     amcc->used);
+
+	}
+}
+
+/****************************************************************************/
+/* return all card information for driver */
+int i_pci_card_data(struct pcilst_struct *amcc,
+		    unsigned char *pci_bus, unsigned char *pci_slot,
+		    unsigned char *pci_func, resource_size_t * io_addr,
+		    unsigned int *irq)
+{
+	int i;
+
+	if (!amcc)
+		return -1;
+	*pci_bus = amcc->pci_bus;
+	*pci_slot = amcc->pci_slot;
+	*pci_func = amcc->pci_func;
+	for (i = 0; i < 5; i++)
+		io_addr[i] = amcc->io_addr[i];
+	*irq = amcc->irq;
+	return 0;
+}
+
+/****************************************************************************/
+/* select and alloc card */
+struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
+						    unsigned short device_id,
+						    unsigned short pci_bus,
+						    unsigned short pci_slot,
+						    int i_Master)
+{
+	struct pcilst_struct *card;
+
+	if ((pci_bus < 1) & (pci_slot < 1)) {
+		/* use autodetection */
+		card = ptr_find_free_pci_card_by_device(vendor_id, device_id);
+		if (card == NULL) {
+			rt_printk(" - Unused card not found in system!\n");
+			return NULL;
+		}
+	} else {
+		switch (i_find_free_pci_card_by_position(vendor_id, device_id,
+							 pci_bus, pci_slot,
+							 &card)) {
+		case 1:
+			rt_printk(" - Card not found on requested position b:s %d:%d!\n",
+				  pci_bus, pci_slot);
+			return NULL;
+		case 2:
+			rt_printk(" - Card on requested position is used b:s %d:%d!\n",
+				  pci_bus, pci_slot);
+			return NULL;
+		}
+	}
+
+	if (pci_card_alloc(card, i_Master) != 0) {
+		rt_printk(" - Can't allocate card!\n");
+		return NULL;
+
+	}
+
+	return card;
+}
+#endif
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c
new file mode 100644
index 0000000..618c69b
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c
@@ -0,0 +1,3062 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+
+        ADDI-DATA GmbH
+        Dieselstrasse 3
+        D-77833 Ottersweier
+        Tel: +19(0)7223/9493-0
+        Fax: +49(0)7223/9493-92
+        http://www.addi-data-com
+        info@addi-data.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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+  +-----------------------------------------------------------------------+
+  | (C) ADDI-DATA GmbH          Dieselstrasse 3      D-77833 Ottersweier  |
+  +-----------------------------------------------------------------------+
+  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
+  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
+  +-----------------------------------------------------------------------+
+  | Project   : ADDI DATA         | Compiler : GCC 		          |
+  | Modulname : addi_common.c     | Version  : 2.96                       |
+  +-------------------------------+---------------------------------------+
+  | Author    :           | Date     :                    		  |
+  +-----------------------------------------------------------------------+
+  | Description : ADDI COMMON Main Module                                 |
+  +-----------------------------------------------------------------------+
+  | CONFIG OPTIONS                                                        |
+  |	option[0] - PCI bus number - if bus number and slot number are 0, |
+  |			         then driver search for first unused card |
+  |	option[1] - PCI slot number                                       |
+  |							                  |
+  |	option[2] = 0  - DMA ENABLE                                       |
+  |               = 1  - DMA DISABLE                                      |
+  +----------+-----------+------------------------------------------------+
+*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/timer.h>
+#include <linux/pci.h>
+#include "../../comedidev.h"
+#include <asm/io.h>
+#if defined(CONFIG_APCI_1710) || defined(CONFIG_APCI_3200) || defined(CONFIG_APCI_3300)
+#include <asm/i387.h>
+#endif
+#include "../comedi_fc.h"
+
+#include "addi_common.h"
+#include "addi_amcc_s5933.h"
+
+//Update-0.7.57->0.7.68MODULE_AUTHOR("ADDI-DATA GmbH <info@addi-data.com>");
+//Update-0.7.57->0.7.68MODULE_DESCRIPTION("Comedi ADDI-DATA module");
+//Update-0.7.57->0.7.68MODULE_LICENSE("GPL");
+
+#define devpriv ((addi_private *)dev->private)
+#define this_board ((boardtype *)dev->board_ptr)
+
+#if defined(CONFIG_APCI_1710) || defined(CONFIG_APCI_3200) || defined(CONFIG_APCI_3300)
+//BYTE b_SaveFPUReg [94];
+
+void fpu_begin(void)
+{
+	//asm ("fstenv b_SaveFPUReg");
+	kernel_fpu_begin();
+}
+
+void fpu_end(void)
+{
+	// asm ("frstor b_SaveFPUReg");
+	kernel_fpu_end();
+}
+#endif
+
+#include "addi_eeprom.c"
+#if (defined (CONFIG_APCI_3120) || defined (CONFIG_APCI_3001))
+#include "hwdrv_apci3120.c"
+#endif
+#ifdef CONFIG_APCI_1032
+#include "hwdrv_apci1032.c"
+#endif
+#ifdef CONFIG_APCI_1516
+#include "hwdrv_apci1516.c"
+#endif
+#ifdef CONFIG_APCI_2016
+#include "hwdrv_apci2016.c"
+#endif
+#ifdef CONFIG_APCI_2032
+#include "hwdrv_apci2032.c"
+#endif
+#ifdef CONFIG_APCI_2200
+#include "hwdrv_apci2200.c"
+#endif
+#ifdef CONFIG_APCI_1564
+#include "hwdrv_apci1564.c"
+#endif
+#ifdef CONFIG_APCI_1500
+#include "hwdrv_apci1500.c"
+#endif
+#ifdef CONFIG_APCI_3501
+#include "hwdrv_apci3501.c"
+#endif
+#ifdef CONFIG_APCI_035
+#include "hwdrv_apci035.c"
+#endif
+#if (defined (CONFIG_APCI_3200) || defined (CONFIG_APCI_3300))
+#include "hwdrv_apci3200.c"
+#endif
+#ifdef CONFIG_APCI_1710
+#include "hwdrv_APCI1710.c"
+#endif
+#ifdef CONFIG_APCI_16XX
+#include "hwdrv_apci16xx.c"
+#endif
+#ifdef CONFIG_APCI_3XXX
+#include "hwdrv_apci3xxx.c"
+#endif
+
+#ifndef COMEDI_SUBD_TTLIO
+#define COMEDI_SUBD_TTLIO   11	/* Digital Input Output But TTL */
+#endif
+
+static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = {
+#ifdef CONFIG_APCI_3120
+	{APCI3120_BOARD_VENDOR_ID, 0x818D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_1032
+	{APCI1032_BOARD_VENDOR_ID, 0x1003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_1516
+	{APCI1516_BOARD_VENDOR_ID, 0x1001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_2016
+	{APCI2016_BOARD_VENDOR_ID, 0x1002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_2032
+	{APCI2032_BOARD_VENDOR_ID, 0x1004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_2200
+	{APCI2200_BOARD_VENDOR_ID, 0x1005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_1564
+	{APCI1564_BOARD_VENDOR_ID, 0x1006, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_1500
+	{APCI1500_BOARD_VENDOR_ID, 0x80fc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_3001
+	{APCI3120_BOARD_VENDOR_ID, 0x828D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_3501
+	{APCI3501_BOARD_VENDOR_ID, 0x3001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_035
+	{APCI035_BOARD_VENDOR_ID, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_3200
+	{APCI3200_BOARD_VENDOR_ID, 0x3000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_3300
+	{APCI3200_BOARD_VENDOR_ID, 0x3007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_1710
+	{APCI1710_BOARD_VENDOR_ID, APCI1710_BOARD_DEVICE_ID,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_16XX
+	{0x15B8, 0x1009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x15B8, 0x100A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_3XXX
+	{0x15B8, 0x3010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x15B8, 0x300F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x15B8, 0x300E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x15B8, 0x3013, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x15B8, 0x3014, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x15B8, 0x3015, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x15B8, 0x3016, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x15B8, 0x3017, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x15B8, 0x3018, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x15B8, 0x3019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x15B8, 0x301A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x15B8, 0x301B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x15B8, 0x301C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x15B8, 0x301D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x15B8, 0x301E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x15B8, 0x301F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x15B8, 0x3020, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x15B8, 0x3021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x15B8, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x15B8, 0x3023, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x15B8, 0x300B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x15B8, 0x3002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x15B8, 0x3003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x15B8, 0x3004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x15B8, 0x3024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, addi_apci_tbl);
+
+static const boardtype boardtypes[] = {
+#ifdef CONFIG_APCI_3120
+	{"apci3120",
+			APCI3120_BOARD_VENDOR_ID,
+			0x818D,
+			AMCC_OP_REG_SIZE,
+			APCI3120_ADDRESS_RANGE,
+			8,
+			0,
+			ADDIDATA_NO_EEPROM,
+			NULL,
+			16,
+			8,
+			16,
+			8,
+			0xffff,
+			0x3fff,
+			&range_apci3120_ai,
+			&range_apci3120_ao,
+			4,
+			4,
+			0x0f,
+			0,
+			NULL,
+			1,
+			1,
+			1,
+			10000,
+			100000,
+			v_APCI3120_Interrupt,
+			i_APCI3120_Reset,
+			i_APCI3120_InsnConfigAnalogInput,
+			i_APCI3120_InsnReadAnalogInput,
+			NULL,
+			NULL,
+			i_APCI3120_CommandTestAnalogInput,
+			i_APCI3120_CommandAnalogInput,
+			i_APCI3120_StopCyclicAcquisition,
+			NULL,
+			i_APCI3120_InsnWriteAnalogOutput,
+			NULL,
+			NULL,
+			i_APCI3120_InsnReadDigitalInput,
+			NULL,
+			i_APCI3120_InsnBitsDigitalInput,
+			i_APCI3120_InsnConfigDigitalOutput,
+			i_APCI3120_InsnWriteDigitalOutput,
+			i_APCI3120_InsnBitsDigitalOutput,
+			NULL,
+			i_APCI3120_InsnConfigTimer,
+			i_APCI3120_InsnWriteTimer,
+			i_APCI3120_InsnReadTimer,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+		NULL},
+#endif
+#ifdef CONFIG_APCI_1032
+	{"apci1032",
+			APCI1032_BOARD_VENDOR_ID,
+			0x1003,
+			4,
+			APCI1032_ADDRESS_RANGE,
+			0,
+			0,
+			ADDIDATA_EEPROM,
+			ADDIDATA_93C76,
+			0,
+			0,
+			0,
+			0,
+			0,
+			0,
+			0,
+			0,
+			32,
+			0,
+			0,
+			0,
+			NULL,
+			0,
+			0,
+			0,
+			0,
+			0,
+			v_APCI1032_Interrupt,
+			i_APCI1032_Reset,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI1032_ConfigDigitalInput,
+			i_APCI1032_Read1DigitalInput,
+			NULL,
+			i_APCI1032_ReadMoreDigitalInput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+		NULL},
+#endif
+#ifdef CONFIG_APCI_1516
+	{"apci1516",
+			APCI1516_BOARD_VENDOR_ID,
+			0x1001,
+			128,
+			APCI1516_ADDRESS_RANGE,
+			32,
+			0,
+			ADDIDATA_EEPROM,
+			ADDIDATA_S5920,
+			0,
+			0,
+			0,
+			0,
+			0,
+			0,
+			NULL,
+			NULL,
+			8,
+			8,
+			0,
+			0,
+			NULL,
+			0,
+			1,
+			0,
+			0,
+			0,
+			NULL,
+			i_APCI1516_Reset,
+			NULL, NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI1516_Read1DigitalInput,
+			NULL,
+			i_APCI1516_ReadMoreDigitalInput,
+			i_APCI1516_ConfigDigitalOutput,
+			i_APCI1516_WriteDigitalOutput,
+			i_APCI1516_ReadDigitalOutput,
+			NULL,
+			i_APCI1516_ConfigWatchdog,
+			i_APCI1516_StartStopWriteWatchdog,
+			i_APCI1516_ReadWatchdog,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+		NULL},
+#endif
+#ifdef CONFIG_APCI_2016
+	{"apci2016",
+			APCI2016_BOARD_VENDOR_ID,
+			0x1002,
+			128,
+			APCI2016_ADDRESS_RANGE,
+			32,
+			0,
+			ADDIDATA_EEPROM,
+			ADDIDATA_S5920,
+			0,
+			0,
+			0,
+			0,
+			0,
+			0,
+			NULL,
+			NULL,
+			0,
+			16,
+			0,
+			0,
+			NULL,
+			0,
+			1,
+			0,
+			0,
+			0,
+			NULL,
+			i_APCI2016_Reset,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI2016_ConfigDigitalOutput,
+			i_APCI2016_WriteDigitalOutput,
+			i_APCI2016_BitsDigitalOutput,
+			NULL,
+			i_APCI2016_ConfigWatchdog,
+			i_APCI2016_StartStopWriteWatchdog,
+			i_APCI2016_ReadWatchdog,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+		NULL},
+#endif
+#ifdef CONFIG_APCI_2032
+	{"apci2032",
+			APCI2032_BOARD_VENDOR_ID,
+			0x1004,
+			4,
+			APCI2032_ADDRESS_RANGE,
+			0,
+			0,
+			ADDIDATA_EEPROM,
+			ADDIDATA_93C76,
+			0,
+			0,
+			0,
+			0,
+			0,
+			0,
+			NULL,
+			NULL,
+			0,
+			32,
+			0xffffffff,
+			0,
+			NULL,
+			0,
+			1,
+			0,
+			0,
+			0,
+			v_APCI2032_Interrupt,
+			i_APCI2032_Reset,
+			NULL, NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI2032_ConfigDigitalOutput,
+			i_APCI2032_WriteDigitalOutput,
+			i_APCI2032_ReadDigitalOutput,
+			i_APCI2032_ReadInterruptStatus,
+			i_APCI2032_ConfigWatchdog,
+			i_APCI2032_StartStopWriteWatchdog,
+			i_APCI2032_ReadWatchdog,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+		NULL},
+#endif
+#ifdef CONFIG_APCI_2200
+	{"apci2200",
+			APCI2200_BOARD_VENDOR_ID,
+			0x1005,
+			4,
+			APCI2200_ADDRESS_RANGE,
+			0,
+			0,
+			ADDIDATA_EEPROM,
+			ADDIDATA_93C76,
+			0,
+			0,
+			0,
+			0,
+			0,
+			0,
+			NULL,
+			NULL,
+			8,
+			16,
+			0,
+			0,
+			NULL,
+			0,
+			1,
+			0,
+			0,
+			0,
+			NULL,
+			i_APCI2200_Reset,
+			NULL, NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI2200_Read1DigitalInput,
+			NULL,
+			i_APCI2200_ReadMoreDigitalInput,
+			i_APCI2200_ConfigDigitalOutput,
+			i_APCI2200_WriteDigitalOutput,
+			i_APCI2200_ReadDigitalOutput,
+			NULL,
+			i_APCI2200_ConfigWatchdog,
+			i_APCI2200_StartStopWriteWatchdog,
+			i_APCI2200_ReadWatchdog,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+		NULL},
+#endif
+#ifdef CONFIG_APCI_1564
+	{"apci1564",
+			APCI1564_BOARD_VENDOR_ID,
+			0x1006,
+			128,
+			APCI1564_ADDRESS_RANGE,
+			0,
+			0,
+			ADDIDATA_EEPROM,
+			ADDIDATA_93C76,
+			0,
+			0,
+			0,
+			0,
+			0,
+			0,
+			NULL,
+			NULL,
+			32,
+			32,
+			0xffffffff,
+			0,
+			NULL,
+			0,
+			1,
+			0,
+			0,
+			0,
+			v_APCI1564_Interrupt,
+			i_APCI1564_Reset,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI1564_ConfigDigitalInput,
+			i_APCI1564_Read1DigitalInput,
+			NULL,
+			i_APCI1564_ReadMoreDigitalInput,
+			i_APCI1564_ConfigDigitalOutput,
+			i_APCI1564_WriteDigitalOutput,
+			i_APCI1564_ReadDigitalOutput,
+			i_APCI1564_ReadInterruptStatus,
+			i_APCI1564_ConfigTimerCounterWatchdog,
+			i_APCI1564_StartStopWriteTimerCounterWatchdog,
+			i_APCI1564_ReadTimerCounterWatchdog,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+		NULL},
+#endif
+#ifdef CONFIG_APCI_1500
+	{"apci1500",
+			APCI1500_BOARD_VENDOR_ID,
+			0x80fc,
+			128,
+			APCI1500_ADDRESS_RANGE,
+			4,
+			0,
+			ADDIDATA_NO_EEPROM,
+			NULL,
+			0,
+			0,
+			0,
+			0,
+			0,
+			0,
+			NULL,
+			NULL,
+			16,
+			16,
+			0xffff,
+			0,
+			NULL,
+			0,
+			1,
+			0,
+			0,
+			0,
+			v_APCI1500_Interrupt,
+			i_APCI1500_Reset,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI1500_ConfigDigitalInputEvent,
+			i_APCI1500_Initialisation,
+			i_APCI1500_StartStopInputEvent,
+			i_APCI1500_ReadMoreDigitalInput,
+			i_APCI1500_ConfigDigitalOutputErrorInterrupt,
+			i_APCI1500_WriteDigitalOutput,
+			i_APCI1500_ConfigureInterrupt,
+			NULL,
+			i_APCI1500_ConfigCounterTimerWatchdog,
+			i_APCI1500_StartStopTriggerTimerCounterWatchdog,
+			i_APCI1500_ReadInterruptMask,
+			i_APCI1500_ReadCounterTimerWatchdog,
+			NULL,
+			NULL,
+			NULL,
+		NULL},
+#endif
+#ifdef CONFIG_APCI_3001
+	{"apci3001",
+			APCI3120_BOARD_VENDOR_ID,
+			0x828D,
+			AMCC_OP_REG_SIZE,
+			APCI3120_ADDRESS_RANGE,
+			8,
+			0,
+			ADDIDATA_NO_EEPROM,
+			NULL,
+			16,
+			8,
+			16,
+			0,
+			0xfff,
+			0,
+			&range_apci3120_ai,
+			NULL,
+			4,
+			4,
+			0x0f,
+			0,
+			NULL,
+			1,
+			1,
+			1,
+			10000,
+			100000,
+			v_APCI3120_Interrupt,
+			i_APCI3120_Reset,
+			i_APCI3120_InsnConfigAnalogInput,
+			i_APCI3120_InsnReadAnalogInput,
+			NULL,
+			NULL,
+			i_APCI3120_CommandTestAnalogInput,
+			i_APCI3120_CommandAnalogInput,
+			i_APCI3120_StopCyclicAcquisition,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3120_InsnReadDigitalInput,
+			NULL,
+			i_APCI3120_InsnBitsDigitalInput,
+			i_APCI3120_InsnConfigDigitalOutput,
+			i_APCI3120_InsnWriteDigitalOutput,
+			i_APCI3120_InsnBitsDigitalOutput,
+			NULL,
+			i_APCI3120_InsnConfigTimer,
+			i_APCI3120_InsnWriteTimer,
+			i_APCI3120_InsnReadTimer,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+		NULL},
+#endif
+#ifdef CONFIG_APCI_3501
+	{"apci3501",
+			APCI3501_BOARD_VENDOR_ID,
+			0x3001,
+			64,
+			APCI3501_ADDRESS_RANGE,
+			0,
+			0,
+			ADDIDATA_EEPROM,
+			ADDIDATA_S5933,
+			0,
+			0,
+			0,
+			8,
+			0,
+			16383,
+			NULL,
+			&range_apci3501_ao,
+			2,
+			2,
+			0x3,
+			0,
+			NULL,
+			0,
+			1,
+			0,
+			0,
+			0,
+			v_APCI3501_Interrupt,
+			i_APCI3501_Reset,
+			NULL, NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3501_ConfigAnalogOutput,
+			i_APCI3501_WriteAnalogOutput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3501_ReadDigitalInput,
+			i_APCI3501_ConfigDigitalOutput,
+			i_APCI3501_WriteDigitalOutput,
+			i_APCI3501_ReadDigitalOutput,
+			NULL,
+			i_APCI3501_ConfigTimerCounterWatchdog,
+			i_APCI3501_StartStopWriteTimerCounterWatchdog,
+			i_APCI3501_ReadTimerCounterWatchdog,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+		NULL},
+#endif
+#ifdef CONFIG_APCI_035
+	{"apci035",
+			APCI035_BOARD_VENDOR_ID,
+			0x0300,
+			127,
+			APCI035_ADDRESS_RANGE,
+			0,
+			0,
+			1,
+			ADDIDATA_S5920,
+			16,
+			8,
+			16,
+			0,
+			0xff,
+			0,
+			&range_apci035_ai,
+			NULL,
+			0,
+			0,
+			0,
+			0,
+			NULL,
+			0,
+			1,
+			0,
+			10000,
+			100000,
+			v_APCI035_Interrupt,
+			i_APCI035_Reset,
+			i_APCI035_ConfigAnalogInput,
+			i_APCI035_ReadAnalogInput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI035_ConfigTimerWatchdog,
+			i_APCI035_StartStopWriteTimerWatchdog,
+			i_APCI035_ReadTimerWatchdog,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+		NULL},
+#endif
+#ifdef CONFIG_APCI_3200
+	{"apci3200",
+			APCI3200_BOARD_VENDOR_ID,
+			0x3000,
+			128,
+			256,
+			4,
+			4,
+			ADDIDATA_EEPROM,
+			ADDIDATA_S5920,
+			16,
+			8,
+			16,
+			0,
+			0x3ffff,
+			0,
+			&range_apci3200_ai,
+			NULL,
+			4,
+			4,
+			0,
+			0,
+			NULL,
+			0,
+			0,
+			0,
+			10000,
+			100000,
+			v_APCI3200_Interrupt,
+			i_APCI3200_Reset,
+			i_APCI3200_ConfigAnalogInput,
+			i_APCI3200_ReadAnalogInput,
+			i_APCI3200_InsnWriteReleaseAnalogInput,
+			i_APCI3200_InsnBits_AnalogInput_Test,
+			i_APCI3200_CommandTestAnalogInput,
+			i_APCI3200_CommandAnalogInput,
+			i_APCI3200_StopCyclicAcquisition,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3200_ReadDigitalInput,
+			i_APCI3200_ConfigDigitalOutput,
+			i_APCI3200_WriteDigitalOutput,
+			i_APCI3200_ReadDigitalOutput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+		NULL},
+#endif
+#ifdef CONFIG_APCI_3300
+	//Begin JK 20.10.2004: APCI-3300 integration
+	{"apci3300",
+			APCI3200_BOARD_VENDOR_ID,
+			0x3007,
+			128,
+			256,
+			4,
+			4,
+			ADDIDATA_EEPROM,
+			ADDIDATA_S5920,
+			0,
+			8,
+			8,
+			0,
+			0x3ffff,
+			0,
+			&range_apci3300_ai,
+			NULL,
+			4,
+			4,
+			0,
+			0,
+			NULL,
+			0,
+			0,
+			0,
+			10000,
+			100000,
+			v_APCI3200_Interrupt,
+			i_APCI3200_Reset,
+			i_APCI3200_ConfigAnalogInput,
+			i_APCI3200_ReadAnalogInput,
+			i_APCI3200_InsnWriteReleaseAnalogInput,
+			i_APCI3200_InsnBits_AnalogInput_Test,
+			i_APCI3200_CommandTestAnalogInput,
+			i_APCI3200_CommandAnalogInput,
+			i_APCI3200_StopCyclicAcquisition,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3200_ReadDigitalInput,
+			i_APCI3200_ConfigDigitalOutput,
+			i_APCI3200_WriteDigitalOutput,
+			i_APCI3200_ReadDigitalOutput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+		NULL},
+#endif
+#ifdef CONFIG_APCI_1710
+	{"apci1710", APCI1710_BOARD_VENDOR_ID, APCI1710_BOARD_DEVICE_ID,
+			128,
+			8,
+			256,
+			0,
+			ADDIDATA_NO_EEPROM,
+			NULL,
+			0,
+			0,
+			0,
+			0,
+			0,
+			0,
+			NULL,
+			NULL,
+			0,
+			0,
+			0,
+			0,
+			NULL,
+			0,
+			0,
+			0,
+			0,
+			0,
+			v_APCI1710_Interrupt,
+			i_APCI1710_Reset,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+		NULL},
+#endif
+#ifdef CONFIG_APCI_16XX
+	{"apci1648",
+			0x15B8,
+			0x1009,
+			128,
+			0,
+			0,
+			0,
+			ADDIDATA_NO_EEPROM,
+			NULL,
+			0,
+			0,
+			0,
+			0,
+			0,
+			0,
+			NULL,
+			NULL,
+			0,
+			0,
+			0,
+			48,
+			&range_apci16xx_ttl,
+			0,
+			0,
+			0,
+			0,
+			0,
+			NULL,
+			i_APCI16XX_Reset,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI16XX_InsnConfigInitTTLIO,
+			i_APCI16XX_InsnBitsReadTTLIO,
+			i_APCI16XX_InsnReadTTLIOAllPortValue,
+		i_APCI16XX_InsnBitsWriteTTLIO},
+
+	{"apci1696",
+			0x15B8,
+			0x100A,
+			128,
+			0,
+			0,
+			0,
+			ADDIDATA_NO_EEPROM,
+			NULL,
+			0,
+			0,
+			0,
+			0,
+			0,
+			0,
+			NULL,
+			NULL,
+			0,
+			0,
+			0,
+			96,
+			&range_apci16xx_ttl,
+			0,
+			0,
+			0,
+			0,
+			0,
+			NULL,
+			i_APCI16XX_Reset,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI16XX_InsnConfigInitTTLIO,
+			i_APCI16XX_InsnBitsReadTTLIO,
+			i_APCI16XX_InsnReadTTLIOAllPortValue,
+		i_APCI16XX_InsnBitsWriteTTLIO},
+#endif
+#ifdef CONFIG_APCI_3XXX
+	{"apci3000-16",
+			0x15B8,
+			0x3010,
+			256,
+			256,
+			256,
+			256,
+			ADDIDATA_NO_EEPROM,
+			ADDIDATA_9054,
+			16,
+			8,
+			16,
+			0,
+			4095,
+			0,
+			&range_apci3XXX_ai,
+			NULL,
+			0,
+			0,
+			0,
+			24,
+			&range_apci3XXX_ttl,
+			0,
+			0,
+			6,
+			10000,
+			0,
+			v_APCI3XXX_Interrupt,
+			i_APCI3XXX_Reset,
+			i_APCI3XXX_InsnConfigAnalogInput,
+			i_APCI3XXX_InsnReadAnalogInput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnConfigInitTTLIO,
+			i_APCI3XXX_InsnBitsTTLIO,
+			i_APCI3XXX_InsnReadTTLIO,
+		i_APCI3XXX_InsnWriteTTLIO},
+
+	{"apci3000-8",
+			0x15B8,
+			0x300F,
+			256,
+			256,
+			256,
+			256,
+			ADDIDATA_NO_EEPROM,
+			ADDIDATA_9054,
+			8,
+			4,
+			8,
+			0,
+			4095,
+			0,
+			&range_apci3XXX_ai,
+			NULL,
+			0,
+			0,
+			0,
+			24,
+			&range_apci3XXX_ttl,
+			0,
+			0,
+			6,
+			10000,
+			0,
+			v_APCI3XXX_Interrupt,
+			i_APCI3XXX_Reset,
+			i_APCI3XXX_InsnConfigAnalogInput,
+			i_APCI3XXX_InsnReadAnalogInput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnConfigInitTTLIO,
+			i_APCI3XXX_InsnBitsTTLIO,
+			i_APCI3XXX_InsnReadTTLIO,
+		i_APCI3XXX_InsnWriteTTLIO},
+
+	{"apci3000-4",
+			0x15B8,
+			0x300E,
+			256,
+			256,
+			256,
+			256,
+			ADDIDATA_NO_EEPROM,
+			ADDIDATA_9054,
+			4,
+			2,
+			4,
+			0,
+			4095,
+			0,
+			&range_apci3XXX_ai,
+			NULL,
+			0,
+			0,
+			0,
+			24,
+			&range_apci3XXX_ttl,
+			0,
+			0,
+			6,
+			10000,
+			0,
+			v_APCI3XXX_Interrupt,
+			i_APCI3XXX_Reset,
+			i_APCI3XXX_InsnConfigAnalogInput,
+			i_APCI3XXX_InsnReadAnalogInput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnConfigInitTTLIO,
+			i_APCI3XXX_InsnBitsTTLIO,
+			i_APCI3XXX_InsnReadTTLIO,
+		i_APCI3XXX_InsnWriteTTLIO},
+
+	{"apci3006-16",
+			0x15B8,
+			0x3013,
+			256,
+			256,
+			256,
+			256,
+			ADDIDATA_NO_EEPROM,
+			ADDIDATA_9054,
+			16,
+			8,
+			16,
+			0,
+			65535,
+			0,
+			&range_apci3XXX_ai,
+			NULL,
+			0,
+			0,
+			0,
+			24,
+			&range_apci3XXX_ttl,
+			0,
+			0,
+			6,
+			10000,
+			0,
+			v_APCI3XXX_Interrupt,
+			i_APCI3XXX_Reset,
+			i_APCI3XXX_InsnConfigAnalogInput,
+			i_APCI3XXX_InsnReadAnalogInput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnConfigInitTTLIO,
+			i_APCI3XXX_InsnBitsTTLIO,
+			i_APCI3XXX_InsnReadTTLIO,
+		i_APCI3XXX_InsnWriteTTLIO},
+
+	{"apci3006-8",
+			0x15B8,
+			0x3014,
+			256,
+			256,
+			256,
+			256,
+			ADDIDATA_NO_EEPROM,
+			ADDIDATA_9054,
+			8,
+			4,
+			8,
+			0,
+			65535,
+			0,
+			&range_apci3XXX_ai,
+			NULL,
+			0,
+			0,
+			0,
+			24,
+			&range_apci3XXX_ttl,
+			0,
+			0,
+			6,
+			10000,
+			0,
+			v_APCI3XXX_Interrupt,
+			i_APCI3XXX_Reset,
+			i_APCI3XXX_InsnConfigAnalogInput,
+			i_APCI3XXX_InsnReadAnalogInput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnConfigInitTTLIO,
+			i_APCI3XXX_InsnBitsTTLIO,
+			i_APCI3XXX_InsnReadTTLIO,
+		i_APCI3XXX_InsnWriteTTLIO},
+
+	{"apci3006-4",
+			0x15B8,
+			0x3015,
+			256,
+			256,
+			256,
+			256,
+			ADDIDATA_NO_EEPROM,
+			ADDIDATA_9054,
+			4,
+			2,
+			4,
+			0,
+			65535,
+			0,
+			&range_apci3XXX_ai,
+			NULL,
+			0,
+			0,
+			0,
+			24,
+			&range_apci3XXX_ttl,
+			0,
+			0,
+			6,
+			10000,
+			0,
+			v_APCI3XXX_Interrupt,
+			i_APCI3XXX_Reset,
+			i_APCI3XXX_InsnConfigAnalogInput,
+			i_APCI3XXX_InsnReadAnalogInput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnConfigInitTTLIO,
+			i_APCI3XXX_InsnBitsTTLIO,
+			i_APCI3XXX_InsnReadTTLIO,
+		i_APCI3XXX_InsnWriteTTLIO},
+
+	{"apci3010-16",
+			0x15B8,
+			0x3016,
+			256,
+			256,
+			256,
+			256,
+			ADDIDATA_NO_EEPROM,
+			ADDIDATA_9054,
+			16,
+			8,
+			16,
+			0,
+			4095,
+			0,
+			&range_apci3XXX_ai,
+			NULL,
+			4,
+			4,
+			1,
+			24,
+			&range_apci3XXX_ttl,
+			0,
+			0,
+			6,
+			5000,
+			0,
+			v_APCI3XXX_Interrupt,
+			i_APCI3XXX_Reset,
+			i_APCI3XXX_InsnConfigAnalogInput,
+			i_APCI3XXX_InsnReadAnalogInput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnReadDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnBitsDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnWriteDigitalOutput,
+			i_APCI3XXX_InsnBitsDigitalOutput,
+			i_APCI3XXX_InsnReadDigitalOutput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnConfigInitTTLIO,
+			i_APCI3XXX_InsnBitsTTLIO,
+			i_APCI3XXX_InsnReadTTLIO,
+		i_APCI3XXX_InsnWriteTTLIO},
+
+	{"apci3010-8",
+			0x15B8,
+			0x3017,
+			256,
+			256,
+			256,
+			256,
+			ADDIDATA_NO_EEPROM,
+			ADDIDATA_9054,
+			8,
+			4,
+			8,
+			0,
+			4095,
+			0,
+			&range_apci3XXX_ai,
+			NULL,
+			4,
+			4,
+			1,
+			24,
+			&range_apci3XXX_ttl,
+			0,
+			0,
+			6,
+			5000,
+			0,
+			v_APCI3XXX_Interrupt,
+			i_APCI3XXX_Reset,
+			i_APCI3XXX_InsnConfigAnalogInput,
+			i_APCI3XXX_InsnReadAnalogInput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnReadDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnBitsDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnWriteDigitalOutput,
+			i_APCI3XXX_InsnBitsDigitalOutput,
+			i_APCI3XXX_InsnReadDigitalOutput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnConfigInitTTLIO,
+			i_APCI3XXX_InsnBitsTTLIO,
+			i_APCI3XXX_InsnReadTTLIO,
+		i_APCI3XXX_InsnWriteTTLIO},
+
+	{"apci3010-4",
+			0x15B8,
+			0x3018,
+			256,
+			256,
+			256,
+			256,
+			ADDIDATA_NO_EEPROM,
+			ADDIDATA_9054,
+			4,
+			2,
+			4,
+			0,
+			4095,
+			0,
+			&range_apci3XXX_ai,
+			NULL,
+			4,
+			4,
+			1,
+			24,
+			&range_apci3XXX_ttl,
+			0,
+			0,
+			6,
+			5000,
+			0,
+			v_APCI3XXX_Interrupt,
+			i_APCI3XXX_Reset,
+			i_APCI3XXX_InsnConfigAnalogInput,
+			i_APCI3XXX_InsnReadAnalogInput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnReadDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnBitsDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnWriteDigitalOutput,
+			i_APCI3XXX_InsnBitsDigitalOutput,
+			i_APCI3XXX_InsnReadDigitalOutput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnConfigInitTTLIO,
+			i_APCI3XXX_InsnBitsTTLIO,
+			i_APCI3XXX_InsnReadTTLIO,
+		i_APCI3XXX_InsnWriteTTLIO},
+
+	{"apci3016-16",
+			0x15B8,
+			0x3019,
+			256,
+			256,
+			256,
+			256,
+			ADDIDATA_NO_EEPROM,
+			ADDIDATA_9054,
+			16,
+			8,
+			16,
+			0,
+			65535,
+			0,
+			&range_apci3XXX_ai,
+			NULL,
+			4,
+			4,
+			1,
+			24,
+			&range_apci3XXX_ttl,
+			0,
+			0,
+			6,
+			5000,
+			0,
+			v_APCI3XXX_Interrupt,
+			i_APCI3XXX_Reset,
+			i_APCI3XXX_InsnConfigAnalogInput,
+			i_APCI3XXX_InsnReadAnalogInput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnReadDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnBitsDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnWriteDigitalOutput,
+			i_APCI3XXX_InsnBitsDigitalOutput,
+			i_APCI3XXX_InsnReadDigitalOutput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnConfigInitTTLIO,
+			i_APCI3XXX_InsnBitsTTLIO,
+			i_APCI3XXX_InsnReadTTLIO,
+		i_APCI3XXX_InsnWriteTTLIO},
+
+	{"apci3016-8",
+			0x15B8,
+			0x301A,
+			256,
+			256,
+			256,
+			256,
+			ADDIDATA_NO_EEPROM,
+			ADDIDATA_9054,
+			8,
+			4,
+			8,
+			0,
+			65535,
+			0,
+			&range_apci3XXX_ai,
+			NULL,
+			4,
+			4,
+			1,
+			24,
+			&range_apci3XXX_ttl,
+			0,
+			0,
+			6,
+			5000,
+			0,
+			v_APCI3XXX_Interrupt,
+			i_APCI3XXX_Reset,
+			i_APCI3XXX_InsnConfigAnalogInput,
+			i_APCI3XXX_InsnReadAnalogInput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnReadDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnBitsDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnWriteDigitalOutput,
+			i_APCI3XXX_InsnBitsDigitalOutput,
+			i_APCI3XXX_InsnReadDigitalOutput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnConfigInitTTLIO,
+			i_APCI3XXX_InsnBitsTTLIO,
+			i_APCI3XXX_InsnReadTTLIO,
+		i_APCI3XXX_InsnWriteTTLIO},
+
+	{"apci3016-4",
+			0x15B8,
+			0x301B,
+			256,
+			256,
+			256,
+			256,
+			ADDIDATA_NO_EEPROM,
+			ADDIDATA_9054,
+			4,
+			2,
+			4,
+			0,
+			65535,
+			0,
+			&range_apci3XXX_ai,
+			NULL,
+			4,
+			4,
+			1,
+			24,
+			&range_apci3XXX_ttl,
+			0,
+			0,
+			6,
+			5000,
+			0,
+			v_APCI3XXX_Interrupt,
+			i_APCI3XXX_Reset,
+			i_APCI3XXX_InsnConfigAnalogInput,
+			i_APCI3XXX_InsnReadAnalogInput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnReadDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnBitsDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnWriteDigitalOutput,
+			i_APCI3XXX_InsnBitsDigitalOutput,
+			i_APCI3XXX_InsnReadDigitalOutput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnConfigInitTTLIO,
+			i_APCI3XXX_InsnBitsTTLIO,
+			i_APCI3XXX_InsnReadTTLIO,
+		i_APCI3XXX_InsnWriteTTLIO},
+
+	{"apci3100-16-4",
+			0x15B8,
+			0x301C,
+			256,
+			256,
+			256,
+			256,
+			ADDIDATA_NO_EEPROM,
+			ADDIDATA_9054,
+			16,
+			8,
+			16,
+			4,
+			4095,
+			4095,
+			&range_apci3XXX_ai,
+			&range_apci3XXX_ao,
+			0,
+			0,
+			0,
+			24,
+			&range_apci3XXX_ttl,
+			0,
+			0,
+			6,
+			10000,
+			0,
+			v_APCI3XXX_Interrupt,
+			i_APCI3XXX_Reset,
+			i_APCI3XXX_InsnConfigAnalogInput,
+			i_APCI3XXX_InsnReadAnalogInput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnWriteAnalogOutput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnConfigInitTTLIO,
+			i_APCI3XXX_InsnBitsTTLIO,
+			i_APCI3XXX_InsnReadTTLIO,
+		i_APCI3XXX_InsnWriteTTLIO},
+
+	{"apci3100-8-4",
+			0x15B8,
+			0x301D,
+			256,
+			256,
+			256,
+			256,
+			ADDIDATA_NO_EEPROM,
+			ADDIDATA_9054,
+			8,
+			4,
+			8,
+			4,
+			4095,
+			4095,
+			&range_apci3XXX_ai,
+			&range_apci3XXX_ao,
+			0,
+			0,
+			0,
+			24,
+			&range_apci3XXX_ttl,
+			0,
+			0,
+			6,
+			10000,
+			0,
+			v_APCI3XXX_Interrupt,
+			i_APCI3XXX_Reset,
+			i_APCI3XXX_InsnConfigAnalogInput,
+			i_APCI3XXX_InsnReadAnalogInput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnWriteAnalogOutput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnConfigInitTTLIO,
+			i_APCI3XXX_InsnBitsTTLIO,
+			i_APCI3XXX_InsnReadTTLIO,
+		i_APCI3XXX_InsnWriteTTLIO},
+
+	{"apci3106-16-4",
+			0x15B8,
+			0x301E,
+			256,
+			256,
+			256,
+			256,
+			ADDIDATA_NO_EEPROM,
+			ADDIDATA_9054,
+			16,
+			8,
+			16,
+			4,
+			65535,
+			4095,
+			&range_apci3XXX_ai,
+			&range_apci3XXX_ao,
+			0,
+			0,
+			0,
+			24,
+			&range_apci3XXX_ttl,
+			0,
+			0,
+			6,
+			10000,
+			0,
+			v_APCI3XXX_Interrupt,
+			i_APCI3XXX_Reset,
+			i_APCI3XXX_InsnConfigAnalogInput,
+			i_APCI3XXX_InsnReadAnalogInput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnWriteAnalogOutput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnConfigInitTTLIO,
+			i_APCI3XXX_InsnBitsTTLIO,
+			i_APCI3XXX_InsnReadTTLIO,
+		i_APCI3XXX_InsnWriteTTLIO},
+
+	{"apci3106-8-4",
+			0x15B8,
+			0x301F,
+			256,
+			256,
+			256,
+			256,
+			ADDIDATA_NO_EEPROM,
+			ADDIDATA_9054,
+			8,
+			4,
+			8,
+			4,
+			65535,
+			4095,
+			&range_apci3XXX_ai,
+			&range_apci3XXX_ao,
+			0,
+			0,
+			0,
+			24,
+			&range_apci3XXX_ttl,
+			0,
+			0,
+			6,
+			10000,
+			0,
+			v_APCI3XXX_Interrupt,
+			i_APCI3XXX_Reset,
+			i_APCI3XXX_InsnConfigAnalogInput,
+			i_APCI3XXX_InsnReadAnalogInput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnWriteAnalogOutput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnConfigInitTTLIO,
+			i_APCI3XXX_InsnBitsTTLIO,
+			i_APCI3XXX_InsnReadTTLIO,
+		i_APCI3XXX_InsnWriteTTLIO},
+
+	{"apci3110-16-4",
+			0x15B8,
+			0x3020,
+			256,
+			256,
+			256,
+			256,
+			ADDIDATA_NO_EEPROM,
+			ADDIDATA_9054,
+			16,
+			8,
+			16,
+			4,
+			4095,
+			4095,
+			&range_apci3XXX_ai,
+			&range_apci3XXX_ao,
+			4,
+			4,
+			1,
+			24,
+			&range_apci3XXX_ttl,
+			0,
+			0,
+			6,
+			5000,
+			0,
+			v_APCI3XXX_Interrupt,
+			i_APCI3XXX_Reset,
+			i_APCI3XXX_InsnConfigAnalogInput,
+			i_APCI3XXX_InsnReadAnalogInput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnWriteAnalogOutput,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnReadDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnBitsDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnWriteDigitalOutput,
+			i_APCI3XXX_InsnBitsDigitalOutput,
+			i_APCI3XXX_InsnReadDigitalOutput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnConfigInitTTLIO,
+			i_APCI3XXX_InsnBitsTTLIO,
+			i_APCI3XXX_InsnReadTTLIO,
+		i_APCI3XXX_InsnWriteTTLIO},
+
+	{"apci3110-8-4",
+			0x15B8,
+			0x3021,
+			256,
+			256,
+			256,
+			256,
+			ADDIDATA_NO_EEPROM,
+			ADDIDATA_9054,
+			8,
+			4,
+			8,
+			4,
+			4095,
+			4095,
+			&range_apci3XXX_ai,
+			&range_apci3XXX_ao,
+			4,
+			4,
+			1,
+			24,
+			&range_apci3XXX_ttl,
+			0,
+			0,
+			6,
+			5000,
+			0,
+			v_APCI3XXX_Interrupt,
+			i_APCI3XXX_Reset,
+			i_APCI3XXX_InsnConfigAnalogInput,
+			i_APCI3XXX_InsnReadAnalogInput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnWriteAnalogOutput,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnReadDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnBitsDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnWriteDigitalOutput,
+			i_APCI3XXX_InsnBitsDigitalOutput,
+			i_APCI3XXX_InsnReadDigitalOutput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnConfigInitTTLIO,
+			i_APCI3XXX_InsnBitsTTLIO,
+			i_APCI3XXX_InsnReadTTLIO,
+		i_APCI3XXX_InsnWriteTTLIO},
+
+	{"apci3116-16-4",
+			0x15B8,
+			0x3022,
+			256,
+			256,
+			256,
+			256,
+			ADDIDATA_NO_EEPROM,
+			ADDIDATA_9054,
+			16,
+			8,
+			16,
+			4,
+			65535,
+			4095,
+			&range_apci3XXX_ai,
+			&range_apci3XXX_ao,
+			4,
+			4,
+			1,
+			24,
+			&range_apci3XXX_ttl,
+			0,
+			0,
+			6,
+			5000,
+			0,
+			v_APCI3XXX_Interrupt,
+			i_APCI3XXX_Reset,
+			i_APCI3XXX_InsnConfigAnalogInput,
+			i_APCI3XXX_InsnReadAnalogInput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnWriteAnalogOutput,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnReadDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnBitsDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnWriteDigitalOutput,
+			i_APCI3XXX_InsnBitsDigitalOutput,
+			i_APCI3XXX_InsnReadDigitalOutput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnConfigInitTTLIO,
+			i_APCI3XXX_InsnBitsTTLIO,
+			i_APCI3XXX_InsnReadTTLIO,
+		i_APCI3XXX_InsnWriteTTLIO},
+
+	{"apci3116-8-4",
+			0x15B8,
+			0x3023,
+			256,
+			256,
+			256,
+			256,
+			ADDIDATA_NO_EEPROM,
+			ADDIDATA_9054,
+			8,
+			4,
+			8,
+			4,
+			65535,
+			4095,
+			&range_apci3XXX_ai,
+			&range_apci3XXX_ao,
+			4,
+			4,
+			1,
+			24,
+			&range_apci3XXX_ttl,
+			0,
+			0,
+			6,
+			5000,
+			0,
+			v_APCI3XXX_Interrupt,
+			i_APCI3XXX_Reset,
+			i_APCI3XXX_InsnConfigAnalogInput,
+			i_APCI3XXX_InsnReadAnalogInput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnWriteAnalogOutput,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnReadDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnBitsDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnWriteDigitalOutput,
+			i_APCI3XXX_InsnBitsDigitalOutput,
+			i_APCI3XXX_InsnReadDigitalOutput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnConfigInitTTLIO,
+			i_APCI3XXX_InsnBitsTTLIO,
+			i_APCI3XXX_InsnReadTTLIO,
+		i_APCI3XXX_InsnWriteTTLIO},
+
+	{"apci3003",
+			0x15B8,
+			0x300B,
+			256,
+			256,
+			256,
+			256,
+			ADDIDATA_NO_EEPROM,
+			ADDIDATA_9054,
+			0,
+			4,
+			4,
+			0,
+			65535,
+			0,
+			&range_apci3XXX_ai,
+			NULL,
+			4,
+			4,
+			1,
+			0,
+			NULL,
+			0,
+			0,
+			7,
+			2500,
+			0,
+			v_APCI3XXX_Interrupt,
+			i_APCI3XXX_Reset,
+			i_APCI3XXX_InsnConfigAnalogInput,
+			i_APCI3XXX_InsnReadAnalogInput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnReadDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnBitsDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnWriteDigitalOutput,
+			i_APCI3XXX_InsnBitsDigitalOutput,
+			i_APCI3XXX_InsnReadDigitalOutput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+		NULL},
+
+	{"apci3002-16",
+			0x15B8,
+			0x3002,
+			256,
+			256,
+			256,
+			256,
+			ADDIDATA_NO_EEPROM,
+			ADDIDATA_9054,
+			0,
+			16,
+			16,
+			0,
+			65535,
+			0,
+			&range_apci3XXX_ai,
+			NULL,
+			4,
+			4,
+			1,
+			0,
+			NULL,
+			0,
+			0,
+			6,
+			5000,
+			0,
+			v_APCI3XXX_Interrupt,
+			i_APCI3XXX_Reset,
+			i_APCI3XXX_InsnConfigAnalogInput,
+			i_APCI3XXX_InsnReadAnalogInput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnReadDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnBitsDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnWriteDigitalOutput,
+			i_APCI3XXX_InsnBitsDigitalOutput,
+			i_APCI3XXX_InsnReadDigitalOutput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+		NULL},
+
+	{"apci3002-8",
+			0x15B8,
+			0x3003,
+			256,
+			256,
+			256,
+			256,
+			ADDIDATA_NO_EEPROM,
+			ADDIDATA_9054,
+			0,
+			8,
+			8,
+			0,
+			65535,
+			0,
+			&range_apci3XXX_ai,
+			NULL,
+			4,
+			4,
+			1,
+			0,
+			NULL,
+			0,
+			0,
+			6,
+			5000,
+			0,
+			v_APCI3XXX_Interrupt,
+			i_APCI3XXX_Reset,
+			i_APCI3XXX_InsnConfigAnalogInput,
+			i_APCI3XXX_InsnReadAnalogInput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnReadDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnBitsDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnWriteDigitalOutput,
+			i_APCI3XXX_InsnBitsDigitalOutput,
+			i_APCI3XXX_InsnReadDigitalOutput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+		NULL},
+
+	{"apci3002-4",
+			0x15B8,
+			0x3004,
+			256,
+			256,
+			256,
+			256,
+			ADDIDATA_NO_EEPROM,
+			ADDIDATA_9054,
+			0,
+			4,
+			4,
+			0,
+			65535,
+			0,
+			&range_apci3XXX_ai,
+			NULL,
+			4,
+			4,
+			1,
+			0,
+			NULL,
+			0,
+			0,
+			6,
+			5000,
+			0,
+			v_APCI3XXX_Interrupt,
+			i_APCI3XXX_Reset,
+			i_APCI3XXX_InsnConfigAnalogInput,
+			i_APCI3XXX_InsnReadAnalogInput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnReadDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnBitsDigitalInput,
+			NULL,
+			i_APCI3XXX_InsnWriteDigitalOutput,
+			i_APCI3XXX_InsnBitsDigitalOutput,
+			i_APCI3XXX_InsnReadDigitalOutput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+		NULL},
+
+	{"apci3500",
+			0x15B8,
+			0x3024,
+			256,
+			256,
+			256,
+			256,
+			ADDIDATA_NO_EEPROM,
+			ADDIDATA_9054,
+			0,
+			0,
+			0,
+			4,
+			0,
+			4095,
+			NULL,
+			&range_apci3XXX_ao,
+			0,
+			0,
+			0,
+			24,
+			&range_apci3XXX_ttl,
+			0,
+			0,
+			0,
+			0,
+			0,
+			v_APCI3XXX_Interrupt,
+			i_APCI3XXX_Reset,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnWriteAnalogOutput,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			NULL,
+			i_APCI3XXX_InsnConfigInitTTLIO,
+			i_APCI3XXX_InsnBitsTTLIO,
+			i_APCI3XXX_InsnReadTTLIO,
+		i_APCI3XXX_InsnWriteTTLIO},
+#endif
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(boardtype))
+
+struct comedi_driver driver_addi = {
+      driver_name:"addi_common",
+      module:THIS_MODULE,
+      attach:i_ADDI_Attach,
+      detach:i_ADDI_Detach,
+      num_names:n_boardtypes,
+      board_name:&boardtypes[0].pc_DriverName,
+      offset:sizeof(boardtype),
+};
+
+COMEDI_PCI_INITCLEANUP(driver_addi, addi_apci_tbl);
+
+/*
++----------------------------------------------------------------------------+
+| Function name     :static int i_ADDI_Attach(struct comedi_device *dev,            |
+|										struct comedi_devconfig *it)        |
+|                                        									 |
++----------------------------------------------------------------------------+
+| Task              :Detects the card.                                       |
+|  			 Configure the driver for a particular board.            |
+|  			 This function does all the initializations and memory   |
+|			 allocation of data structures for the driver.	         |
++----------------------------------------------------------------------------+
+| Input Parameters  :struct comedi_device *dev										 |
+|                    struct comedi_devconfig *it									 |
+|                                                 					         |
++----------------------------------------------------------------------------+
+| Return Value      :  0            					                     |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+
+static int i_ADDI_Attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	int ret, pages, i, n_subdevices;
+	DWORD dw_Dummy;
+	resource_size_t io_addr[5];
+	unsigned int irq;
+	resource_size_t iobase_a, iobase_main, iobase_addon, iobase_reserved;
+	struct pcilst_struct *card = NULL;
+	unsigned char pci_bus, pci_slot, pci_func;
+	int i_Dma = 0;
+	static char c_Identifier[150];
+
+	sprintf(c_Identifier, "Addi-Data GmbH Comedi %s",
+		this_board->pc_DriverName);
+
+	if ((ret = alloc_private(dev, sizeof(addi_private))) < 0) {
+	  	return -ENOMEM;
+	}
+
+	if (!pci_list_builded) {
+		v_pci_card_list_init(this_board->i_VendorId, 1);	//1 for displaying the list..
+		pci_list_builded = 1;
+	}
+	//rt_printk("comedi%d: addi_common: board=%s",dev->minor,this_board->pc_DriverName);
+
+	if ((this_board->i_Dma) && (it->options[2] == 0)) {
+		i_Dma = 1;
+	}
+
+	if ((card = ptr_select_and_alloc_pci_card(this_board->i_VendorId,
+				this_board->i_DeviceId,
+				it->options[0],
+				it->options[1], i_Dma)) == NULL) {
+		return -EIO;
+	}
+	devpriv->allocated = 1;
+
+	if ((i_pci_card_data(card, &pci_bus, &pci_slot, &pci_func, &io_addr[0],
+				&irq)) < 0) {
+		i_pci_card_free(card);
+		printk(" - Can't get AMCC data!\n");
+		return -EIO;
+	}
+
+	iobase_a = io_addr[0];
+	iobase_main = io_addr[1];
+	iobase_addon = io_addr[2];
+	iobase_reserved = io_addr[3];
+	printk("\nBus %d: Slot %d: Funct%d\nBase0: 0x%8llx\nBase1: 0x%8llx\nBase2: 0x%8llx\nBase3: 0x%8llx\n", pci_bus, pci_slot, pci_func, (unsigned long long)io_addr[0], (unsigned long long)io_addr[1], (unsigned long long)io_addr[2], (unsigned long long)io_addr[3]);
+
+	if ((this_board->pc_EepromChip == NULL)
+		|| (strcmp(this_board->pc_EepromChip, ADDIDATA_9054) != 0)) {
+	   /************************************/
+		/* Test if more that 1 address used */
+	   /************************************/
+
+		if (this_board->i_IorangeBase1 != 0) {
+			dev->iobase = (unsigned long)iobase_main;	// DAQ base address...
+		} else {
+			dev->iobase = (unsigned long)iobase_a;	// DAQ base address...
+		}
+
+		dev->board_name = this_board->pc_DriverName;
+		devpriv->amcc = card;
+		devpriv->iobase = (INT) dev->iobase;
+		devpriv->i_IobaseAmcc = (INT) iobase_a;	//AMCC base address...
+		devpriv->i_IobaseAddon = (INT) iobase_addon;	//ADD ON base address....
+		devpriv->i_IobaseReserved = (INT) iobase_reserved;
+		devpriv->ps_BoardInfo = this_board;
+	} else {
+		dev->board_name = this_board->pc_DriverName;
+		dev->iobase = (unsigned long)io_addr[2];
+		devpriv->amcc = card;
+		devpriv->iobase = (INT) io_addr[2];
+		devpriv->ps_BoardInfo = this_board;
+		devpriv->i_IobaseReserved = (INT) io_addr[3];
+		printk("\nioremap begin");
+		devpriv->dw_AiBase =
+			(ULONG_PTR) ioremap(io_addr[3],
+			this_board->i_IorangeBase3);
+		printk("\nioremap end");
+	}
+
+	//##
+
+	if (irq > 0) {
+		if (comedi_request_irq(irq, v_ADDI_Interrupt, IRQF_SHARED,
+				c_Identifier, dev) < 0) {
+			printk(", unable to allocate IRQ %u, DISABLING IT",
+				irq);
+			irq = 0;	/* Can't use IRQ */
+		} else {
+			rt_printk("\nirq=%u", irq);
+		}
+	} else {
+		rt_printk(", IRQ disabled");
+	}
+
+	printk("\nOption %d %d %d\n", it->options[0], it->options[1],
+		it->options[2]);
+	dev->irq = irq;
+
+	// Read eepeom and fill boardtype Structure
+
+	if (this_board->i_PCIEeprom) {
+		printk("\nPCI Eeprom used");
+		if (!(strcmp(this_board->pc_EepromChip, "S5920"))) {
+			// Set 3 wait stait
+			if (!(strcmp(this_board->pc_DriverName, "apci035"))) {
+				outl(0x80808082, devpriv->i_IobaseAmcc + 0x60);
+			} else {
+				outl(0x83838383, devpriv->i_IobaseAmcc + 0x60);
+			}
+			// Enable the interrupt for the controler
+			dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38);
+			outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38);
+			printk("\nEnable the interrupt for the controler");
+		}
+		printk("\nRead Eeprom");
+		i_EepromReadMainHeader(io_addr[0], this_board->pc_EepromChip,
+			dev);
+	} else {
+		printk("\nPCI Eeprom unused");
+	}
+
+	if (it->options[2] > 0) {
+		devpriv->us_UseDma = ADDI_DISABLE;
+	} else {
+		devpriv->us_UseDma = ADDI_ENABLE;
+	}
+
+	if (this_board->i_Dma) {
+		printk("\nDMA used");
+		if (devpriv->us_UseDma == ADDI_ENABLE) {
+			// alloc DMA buffers
+			devpriv->b_DmaDoubleBuffer = 0;
+			for (i = 0; i < 2; i++) {
+				for (pages = 4; pages >= 0; pages--) {
+					if ((devpriv->ul_DmaBufferVirtual[i] =
+							(void *)
+							__get_free_pages
+							(GFP_KERNEL, pages))) {
+						break;
+					}
+				}
+				if (devpriv->ul_DmaBufferVirtual[i]) {
+					devpriv->ui_DmaBufferPages[i] = pages;
+					devpriv->ui_DmaBufferSize[i] =
+						PAGE_SIZE * pages;
+					devpriv->ui_DmaBufferSamples[i] =
+						devpriv->
+						ui_DmaBufferSize[i] >> 1;
+					devpriv->ul_DmaBufferHw[i] =
+						virt_to_bus((void *)devpriv->
+						ul_DmaBufferVirtual[i]);
+				}
+			}
+			if (!devpriv->ul_DmaBufferVirtual[0]) {
+				rt_printk
+					(", Can't allocate DMA buffer, DMA disabled!");
+				devpriv->us_UseDma = ADDI_DISABLE;
+			}
+
+			if (devpriv->ul_DmaBufferVirtual[1]) {
+				devpriv->b_DmaDoubleBuffer = 1;
+			}
+		}
+
+		if ((devpriv->us_UseDma == ADDI_ENABLE)) {
+			rt_printk("\nDMA ENABLED\n");
+		} else {
+			printk("\nDMA DISABLED\n");
+		}
+	}
+
+	if (!strcmp(this_board->pc_DriverName, "apci1710")) {
+#ifdef CONFIG_APCI_1710
+		i_ADDI_AttachPCI1710(dev);
+
+		// save base address
+		devpriv->s_BoardInfos.ui_Address = io_addr[2];
+#endif
+	} else {
+		//Update-0.7.57->0.7.68dev->n_subdevices = 7;
+		n_subdevices = 7;
+		if ((ret = alloc_subdevices(dev, n_subdevices)) < 0)
+			return ret;
+
+		// Allocate and Initialise AI Subdevice Structures
+		s = dev->subdevices + 0;
+		if ((this_board->i_NbrAiChannel)
+			|| (this_board->i_NbrAiChannelDiff)) {
+			dev->read_subdev = s;
+			s->type = COMEDI_SUBD_AI;
+			s->subdev_flags =
+				SDF_READABLE | SDF_RT | SDF_COMMON | SDF_GROUND
+				| SDF_DIFF;
+			if (this_board->i_NbrAiChannel) {
+				s->n_chan = this_board->i_NbrAiChannel;
+				devpriv->b_SingelDiff = 0;
+			} else {
+				s->n_chan = this_board->i_NbrAiChannelDiff;
+				devpriv->b_SingelDiff = 1;
+			}
+			s->maxdata = this_board->i_AiMaxdata;
+			s->len_chanlist = this_board->i_AiChannelList;
+			s->range_table = this_board->pr_AiRangelist;
+
+			/* Set the initialisation flag */
+			devpriv->b_AiInitialisation = 1;
+
+			s->insn_config =
+				this_board->i_hwdrv_InsnConfigAnalogInput;
+			s->insn_read = this_board->i_hwdrv_InsnReadAnalogInput;
+			s->insn_write =
+				this_board->i_hwdrv_InsnWriteAnalogInput;
+			s->insn_bits = this_board->i_hwdrv_InsnBitsAnalogInput;
+			s->do_cmdtest =
+				this_board->i_hwdrv_CommandTestAnalogInput;
+			s->do_cmd = this_board->i_hwdrv_CommandAnalogInput;
+			s->cancel = this_board->i_hwdrv_CancelAnalogInput;
+
+		} else {
+			s->type = COMEDI_SUBD_UNUSED;
+		}
+
+		// Allocate and Initialise AO Subdevice Structures
+		s = dev->subdevices + 1;
+		if (this_board->i_NbrAoChannel) {
+			s->type = COMEDI_SUBD_AO;
+			s->subdev_flags =
+				SDF_WRITEABLE | SDF_GROUND | SDF_COMMON |
+				SDF_RT;
+			s->n_chan = this_board->i_NbrAoChannel;
+			s->maxdata = this_board->i_AoMaxdata;
+			s->len_chanlist = this_board->i_NbrAoChannel;
+			s->range_table = this_board->pr_AoRangelist;
+			s->insn_config =
+				this_board->i_hwdrv_InsnConfigAnalogOutput;
+			s->insn_write =
+				this_board->i_hwdrv_InsnWriteAnalogOutput;
+		} else {
+			s->type = COMEDI_SUBD_UNUSED;
+		}
+		// Allocate and Initialise DI Subdevice Structures
+		s = dev->subdevices + 2;
+		if (this_board->i_NbrDiChannel) {
+			s->type = COMEDI_SUBD_DI;
+			s->subdev_flags =
+				SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+			s->n_chan = this_board->i_NbrDiChannel;
+			s->maxdata = 1;
+			s->len_chanlist = this_board->i_NbrDiChannel;
+			s->range_table = &range_digital;
+			s->io_bits = 0;	/* all bits input */
+			s->insn_config =
+				this_board->i_hwdrv_InsnConfigDigitalInput;
+			s->insn_read = this_board->i_hwdrv_InsnReadDigitalInput;
+			s->insn_write =
+				this_board->i_hwdrv_InsnWriteDigitalInput;
+			s->insn_bits = this_board->i_hwdrv_InsnBitsDigitalInput;
+		} else {
+			s->type = COMEDI_SUBD_UNUSED;
+		}
+		// Allocate and Initialise DO Subdevice Structures
+		s = dev->subdevices + 3;
+		if (this_board->i_NbrDoChannel) {
+			s->type = COMEDI_SUBD_DO;
+			s->subdev_flags =
+				SDF_READABLE | SDF_WRITEABLE | SDF_RT |
+				SDF_GROUND | SDF_COMMON;
+			s->n_chan = this_board->i_NbrDoChannel;
+			s->maxdata = this_board->i_DoMaxdata;
+			s->len_chanlist = this_board->i_NbrDoChannel;
+			s->range_table = &range_digital;
+			s->io_bits = 0xf;	/* all bits output */
+
+			s->insn_config = this_board->i_hwdrv_InsnConfigDigitalOutput;	//for digital output memory..
+			s->insn_write =
+				this_board->i_hwdrv_InsnWriteDigitalOutput;
+			s->insn_bits =
+				this_board->i_hwdrv_InsnBitsDigitalOutput;
+			s->insn_read =
+				this_board->i_hwdrv_InsnReadDigitalOutput;
+		} else {
+			s->type = COMEDI_SUBD_UNUSED;
+		}
+
+		// Allocate and Initialise Timer Subdevice Structures
+		s = dev->subdevices + 4;
+		if (this_board->i_Timer) {
+			s->type = COMEDI_SUBD_TIMER;
+			s->subdev_flags =
+				SDF_WRITEABLE | SDF_RT | SDF_GROUND |
+				SDF_COMMON;
+			s->n_chan = 1;
+			s->maxdata = 0;
+			s->len_chanlist = 1;
+			s->range_table = &range_digital;
+
+			s->insn_write = this_board->i_hwdrv_InsnWriteTimer;
+			s->insn_read = this_board->i_hwdrv_InsnReadTimer;
+			s->insn_config = this_board->i_hwdrv_InsnConfigTimer;
+			s->insn_bits = this_board->i_hwdrv_InsnBitsTimer;
+		} else {
+			s->type = COMEDI_SUBD_UNUSED;
+		}
+
+		// Allocate and Initialise TTL
+		s = dev->subdevices + 5;
+		if (this_board->i_NbrTTLChannel) {
+			s->type = COMEDI_SUBD_TTLIO;
+			s->subdev_flags =
+				SDF_WRITEABLE | SDF_READABLE | SDF_RT |
+				SDF_GROUND | SDF_COMMON;
+			s->n_chan = this_board->i_NbrTTLChannel;
+			s->maxdata = 1;
+			s->io_bits = 0;	/* all bits input */
+			s->len_chanlist = this_board->i_NbrTTLChannel;
+			s->range_table = &range_digital;
+			s->insn_config = this_board->i_hwdr_ConfigInitTTLIO;
+			s->insn_bits = this_board->i_hwdr_ReadTTLIOBits;
+			s->insn_read = this_board->i_hwdr_ReadTTLIOAllPortValue;
+			s->insn_write = this_board->i_hwdr_WriteTTLIOChlOnOff;
+		} else {
+			s->type = COMEDI_SUBD_UNUSED;
+		}
+
+		/* EEPROM */
+		s = dev->subdevices + 6;
+		if (this_board->i_PCIEeprom) {
+			s->type = COMEDI_SUBD_MEMORY;
+			s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
+			s->n_chan = 256;
+			s->maxdata = 0xffff;
+			s->insn_read = i_ADDIDATA_InsnReadEeprom;
+		} else {
+			s->type = COMEDI_SUBD_UNUSED;
+		}
+	}
+
+	printk("\ni_ADDI_Attach end\n");
+	i_ADDI_Reset(dev);
+	devpriv->b_ValidDriver = 1;
+	return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name     : static int i_ADDI_Detach(struct comedi_device *dev)           |
+|                                        									 |
+|                                            						         |
++----------------------------------------------------------------------------+
+| Task              : Deallocates resources of the addi_common driver        |
+|			  Free the DMA buffers, unregister irq.				     |
+|                     										                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev									 |
+|                     														 |
+|                                                 					         |
++----------------------------------------------------------------------------+
+| Return Value      : 0             					                     |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+
+static int i_ADDI_Detach(struct comedi_device * dev)
+{
+
+	if (dev->private) {
+		if (devpriv->b_ValidDriver) {
+			i_ADDI_Reset(dev);
+		}
+
+		if (dev->irq) {
+			comedi_free_irq(dev->irq, dev);
+		}
+
+		if ((devpriv->ps_BoardInfo->pc_EepromChip == NULL)
+			|| (strcmp(devpriv->ps_BoardInfo->pc_EepromChip,
+					ADDIDATA_9054) != 0)) {
+			if (devpriv->allocated) {
+				i_pci_card_free(devpriv->amcc);
+			}
+
+			if (devpriv->ul_DmaBufferVirtual[0]) {
+				free_pages((unsigned long)devpriv->
+					ul_DmaBufferVirtual[0],
+					devpriv->ui_DmaBufferPages[0]);
+			}
+
+			if (devpriv->ul_DmaBufferVirtual[1]) {
+				free_pages((unsigned long)devpriv->
+					ul_DmaBufferVirtual[1],
+					devpriv->ui_DmaBufferPages[1]);
+			}
+		} else {
+			iounmap((void *)devpriv->dw_AiBase);
+
+			if (devpriv->allocated) {
+				i_pci_card_free(devpriv->amcc);
+			}
+		}
+
+		if (pci_list_builded) {
+			//v_pci_card_list_cleanup(PCI_VENDOR_ID_AMCC);
+			v_pci_card_list_cleanup(this_board->i_VendorId);
+			pci_list_builded = 0;
+		}
+	}
+
+	return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name     : static int i_ADDI_Reset(struct comedi_device *dev)			 |
+|                                        									 |
++----------------------------------------------------------------------------+
+| Task              : Disables all interrupts, Resets digital output to low, |
+|				Set all analog output to low						 |
+|                     										                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev									 |
+|                     														 |
+|                                                 					         |
++----------------------------------------------------------------------------+
+| Return Value      : 0           					                         |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+
+static int i_ADDI_Reset(struct comedi_device * dev)
+{
+
+	this_board->i_hwdrv_Reset(dev);
+	return 0;
+}
+
+// Interrupt function
+/*
++----------------------------------------------------------------------------+
+| Function name     :                                                        |
+|static void v_ADDI_Interrupt(int irq, void *d  PT_REGS_ARG)                 |
+|                                        									 |
++----------------------------------------------------------------------------+
+| Task              : Registerd interrupt routine						     |
+|                     										                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : 	int irq												 |
+|                     														 |
+|                                                 					         |
++----------------------------------------------------------------------------+
+| Return Value      :              					                         |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+
+static irqreturn_t v_ADDI_Interrupt(int irq, void *d PT_REGS_ARG)
+{
+	struct comedi_device *dev = d;
+	this_board->v_hwdrv_Interrupt(irq, d);
+	return IRQ_RETVAL(1);
+}
+
+// EEPROM Read Function
+/*
++----------------------------------------------------------------------------+
+| Function name     :                                                        |
+|INT i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev,struct comedi_subdevice *s,
+							struct comedi_insn *insn,unsigned int *data)
+|                                        									 |
++----------------------------------------------------------------------------+
+| Task              : Read 256 words from EEPROM          				     |
+|                     										                 |
++----------------------------------------------------------------------------+
+| Input Parameters  :(struct comedi_device *dev,struct comedi_subdevice *s,
+			struct comedi_insn *insn,unsigned int *data) 						 |
+|                     														 |
+|                                                 					         |
++----------------------------------------------------------------------------+
+| Return Value      :              					                         |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+
+static int i_ADDIDATA_InsnReadEeprom(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	WORD w_Data;
+	WORD w_Address;
+	w_Address = CR_CHAN(insn->chanspec);	// address to be read as 0,1,2,3...255
+
+	w_Data = w_EepromReadWord(devpriv->i_IobaseAmcc,
+		this_board->pc_EepromChip, 0x100 + (2 * w_Address));
+	data[0] = w_Data;
+	//multiplied by 2 bcozinput will be like 0,1,2...255
+	return insn->n;
+
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h
new file mode 100644
index 0000000..19df5c1
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h
@@ -0,0 +1,462 @@
+/*
+ *  Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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/module.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/timer.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include <linux/kmod.h>
+#include <linux/uaccess.h>
+#include "../../comedidev.h"
+#include "addi_amcc_s5933.h"
+
+#define ERROR	-1
+#define SUCCESS	1
+
+/* variable type definition */
+typedef unsigned char BYTE, *PBYTE;
+typedef short SHORT, *PSHORT;
+typedef unsigned short USHORT, *PUSHORT;
+typedef unsigned short WORD, *PWORD;
+typedef int INT, *PINT;;
+typedef unsigned int UINT, *PUINT;
+typedef int LONG, *PLONG;		/* 32-bit */
+typedef unsigned int ULONG, *PULONG;	/* 32-bit */
+typedef unsigned int DWORD, *PDWORD;	/* 32-bit */
+typedef unsigned long ULONG_PTR;
+
+typedef const struct comedi_lrange *PCRANGE;
+
+#define LOBYTE(W)	(BYTE)((W) & 0xFF)
+#define HIBYTE(W)	(BYTE)(((W) >> 8) & 0xFF)
+#define MAKEWORD(H, L)	(USHORT)((L) | ((H) << 8))
+#define LOWORD(W)	(USHORT)((W) & 0xFFFF)
+#define HIWORD(W)	(USHORT)(((W) >> 16) & 0xFFFF)
+#define MAKEDWORD(H, L)	(UINT)((L) | ((H) << 16))
+
+#define ADDI_ENABLE		1
+#define ADDI_DISABLE		0
+#define APCI1710_SAVE_INTERRUPT	1
+
+#define ADDIDATA_EEPROM		1
+#define ADDIDATA_NO_EEPROM	0
+#define ADDIDATA_93C76		"93C76"
+#define ADDIDATA_S5920		"S5920"
+#define ADDIDATA_S5933		"S5933"
+#define ADDIDATA_9054		"9054"
+
+/* ADDIDATA Enable Disable */
+#define ADDIDATA_ENABLE		1
+#define ADDIDATA_DISABLE	0
+
+/* Structures */
+
+/* structure for the boardtype */
+typedef struct {
+	const char *pc_DriverName;	// driver name
+	INT i_VendorId;		//PCI vendor a device ID of card
+	INT i_DeviceId;
+	INT i_IorangeBase0;
+	INT i_IorangeBase1;
+	INT i_IorangeBase2;	//  base 2 range
+	INT i_IorangeBase3;	//  base 3 range
+	INT i_PCIEeprom;	// eeprom present or not
+	char *pc_EepromChip;	// type of chip
+	INT i_NbrAiChannel;	// num of A/D chans
+	INT i_NbrAiChannelDiff;	// num of A/D chans in diff mode
+	INT i_AiChannelList;	// len of chanlist
+	INT i_NbrAoChannel;	// num of D/A chans
+	INT i_AiMaxdata;	// resolution of A/D
+	INT i_AoMaxdata;	// resolution of D/A
+	PCRANGE pr_AiRangelist;	// rangelist for A/D
+	PCRANGE pr_AoRangelist;	// rangelist for D/A
+
+	INT i_NbrDiChannel;	// Number of DI channels
+	INT i_NbrDoChannel;	// Number of DO channels
+	INT i_DoMaxdata;	// data to set all chanels high
+
+	INT i_NbrTTLChannel;	// Number of TTL channels
+	PCRANGE pr_TTLRangelist;	// rangelist for TTL
+
+	INT i_Dma;		// dma present or not
+	INT i_Timer;		//   timer subdevice present or not
+	BYTE b_AvailableConvertUnit;
+	UINT ui_MinAcquisitiontimeNs;	// Minimum Acquisition in Nano secs
+	UINT ui_MinDelaytimeNs;	// Minimum Delay in Nano secs
+
+	/* interrupt and reset */
+	void (*v_hwdrv_Interrupt)(int irq, void *d);
+	int (*i_hwdrv_Reset)(struct comedi_device *dev);
+
+	/* Subdevice functions */
+
+	/* ANALOG INPUT */
+	int (*i_hwdrv_InsnConfigAnalogInput)(struct comedi_device *dev,
+					     struct comedi_subdevice *s,
+					     struct comedi_insn *insn,
+					     unsigned int *data);
+	int (*i_hwdrv_InsnReadAnalogInput)(struct comedi_device *dev,
+					    struct comedi_subdevice *s,
+					    struct comedi_insn *insn,
+					    unsigned int *data);
+	int (*i_hwdrv_InsnWriteAnalogInput)(struct comedi_device *dev,
+					    struct comedi_subdevice *s,
+					    struct comedi_insn *insn,
+					    unsigned int *data);
+	int (*i_hwdrv_InsnBitsAnalogInput)(struct comedi_device *dev,
+					   struct comedi_subdevice *s,
+					   struct comedi_insn *insn,
+					   unsigned int *data);
+	int (*i_hwdrv_CommandTestAnalogInput)(struct comedi_device *dev,
+					      struct comedi_subdevice *s,
+					      struct comedi_cmd *cmd);
+	int (*i_hwdrv_CommandAnalogInput)(struct comedi_device *dev,
+					  struct comedi_subdevice *s);
+	int (*i_hwdrv_CancelAnalogInput)(struct comedi_device *dev,
+					 struct comedi_subdevice *s);
+
+	/* Analog Output */
+	int (*i_hwdrv_InsnConfigAnalogOutput)(struct comedi_device *dev,
+					      struct comedi_subdevice *s,
+					      struct comedi_insn *insn,
+					      unsigned int *data);
+	int (*i_hwdrv_InsnWriteAnalogOutput)(struct comedi_device *dev,
+					     struct comedi_subdevice *s,
+					     struct comedi_insn *insn,
+					     unsigned int *data);
+	int (*i_hwdrv_InsnBitsAnalogOutput)(struct comedi_device *dev,
+					    struct comedi_subdevice *s,
+					    struct comedi_insn *insn,
+					    unsigned int *data);
+
+	/* Digital Input */
+	int (*i_hwdrv_InsnConfigDigitalInput) (struct comedi_device *dev,
+					       struct comedi_subdevice *s,
+					       struct comedi_insn *insn,
+					       unsigned int *data);
+	int (*i_hwdrv_InsnReadDigitalInput) (struct comedi_device *dev,
+					     struct comedi_subdevice *s,
+					     struct comedi_insn *insn,
+					     unsigned int *data);
+	int (*i_hwdrv_InsnWriteDigitalInput) (struct comedi_device *dev,
+					      struct comedi_subdevice *s,
+					      struct comedi_insn *insn,
+					      unsigned int *data);
+	int (*i_hwdrv_InsnBitsDigitalInput) (struct comedi_device *dev,
+					     struct comedi_subdevice *s,
+					     struct comedi_insn *insn,
+					     unsigned int *data);
+
+	/* Digital Output */
+	int (*i_hwdrv_InsnConfigDigitalOutput)(struct comedi_device *dev,
+					       struct comedi_subdevice *s,
+					       struct comedi_insn *insn,
+					       unsigned int *data);
+	int (*i_hwdrv_InsnWriteDigitalOutput)(struct comedi_device *dev,
+					      struct comedi_subdevice *s,
+					      struct comedi_insn *insn,
+					      unsigned int *data);
+	int (*i_hwdrv_InsnBitsDigitalOutput)(struct comedi_device *dev,
+					     struct comedi_subdevice *s,
+					     struct comedi_insn *insn,
+					     unsigned int *data);
+	int (*i_hwdrv_InsnReadDigitalOutput)(struct comedi_device *dev,
+					     struct comedi_subdevice *s,
+					     struct comedi_insn *insn,
+					     unsigned int *data);
+
+	/* TIMER */
+	int (*i_hwdrv_InsnConfigTimer)(struct comedi_device *dev,
+				       struct comedi_subdevice *s,
+				       struct comedi_insn *insn, unsigned int *data);
+	int (*i_hwdrv_InsnWriteTimer)(struct comedi_device *dev,
+				      struct comedi_subdevice *s, struct comedi_insn *insn,
+				      unsigned int *data);
+	int (*i_hwdrv_InsnReadTimer)(struct comedi_device *dev, struct comedi_subdevice *s,
+				     struct comedi_insn *insn, unsigned int *data);
+	int (*i_hwdrv_InsnBitsTimer)(struct comedi_device *dev, struct comedi_subdevice *s,
+				     struct comedi_insn *insn, unsigned int *data);
+
+	/* TTL IO */
+	int (*i_hwdr_ConfigInitTTLIO)(struct comedi_device *dev,
+				      struct comedi_subdevice *s, struct comedi_insn *insn,
+				      unsigned int *data);
+	int (*i_hwdr_ReadTTLIOBits)(struct comedi_device *dev, struct comedi_subdevice *s,
+				    struct comedi_insn *insn, unsigned int *data);
+	int (*i_hwdr_ReadTTLIOAllPortValue)(struct comedi_device *dev,
+					    struct comedi_subdevice *s,
+					    struct comedi_insn *insn,
+					    unsigned int *data);
+	int (*i_hwdr_WriteTTLIOChlOnOff)(struct comedi_device *dev,
+					 struct comedi_subdevice *s,
+					 struct comedi_insn *insn, unsigned int *data);
+} boardtype;
+
+//MODULE INFO STRUCTURE
+
+typedef union {
+	/* Incremental counter infos */
+	struct {
+		union {
+			struct {
+				BYTE b_ModeRegister1;
+				BYTE b_ModeRegister2;
+				BYTE b_ModeRegister3;
+				BYTE b_ModeRegister4;
+			} s_ByteModeRegister;
+			DWORD dw_ModeRegister1_2_3_4;
+		} s_ModeRegister;
+
+		struct {
+			unsigned int b_IndexInit:1;
+			unsigned int b_CounterInit:1;
+			unsigned int b_ReferenceInit:1;
+			unsigned int b_IndexInterruptOccur:1;
+			unsigned int b_CompareLogicInit:1;
+			unsigned int b_FrequencyMeasurementInit:1;
+			unsigned int b_FrequencyMeasurementEnable:1;
+		} s_InitFlag;
+
+	} s_SiemensCounterInfo;
+
+	/* SSI infos */
+	struct {
+		BYTE b_SSIProfile;
+		BYTE b_PositionTurnLength;
+		BYTE b_TurnCptLength;
+		BYTE b_SSIInit;
+	} s_SSICounterInfo;
+
+	/* TTL I/O infos */
+	struct {
+		BYTE b_TTLInit;
+		BYTE b_PortConfiguration[4];
+	} s_TTLIOInfo;
+
+	/* Digital I/O infos */
+	struct {
+		BYTE b_DigitalInit;
+		BYTE b_ChannelAMode;
+		BYTE b_ChannelBMode;
+		BYTE b_OutputMemoryEnabled;
+		DWORD dw_OutputMemory;
+	} s_DigitalIOInfo;
+
+      /*********************/
+	/* 82X54 timer infos */
+      /*********************/
+
+	struct {
+		struct {
+			BYTE b_82X54Init;
+			BYTE b_InputClockSelection;
+			BYTE b_InputClockLevel;
+			BYTE b_OutputLevel;
+			BYTE b_HardwareGateLevel;
+			DWORD dw_ConfigurationWord;
+		} s_82X54TimerInfo[3];
+		BYTE b_InterruptMask;
+	} s_82X54ModuleInfo;
+
+      /*********************/
+	/* Chronometer infos */
+      /*********************/
+
+	struct {
+		BYTE b_ChronoInit;
+		BYTE b_InterruptMask;
+		BYTE b_PCIInputClock;
+		BYTE b_TimingUnit;
+		BYTE b_CycleMode;
+		double d_TimingInterval;
+		DWORD dw_ConfigReg;
+	} s_ChronoModuleInfo;
+
+      /***********************/
+	/* Pulse encoder infos */
+      /***********************/
+
+	struct {
+		struct {
+			BYTE b_PulseEncoderInit;
+		} s_PulseEncoderInfo[4];
+		DWORD dw_SetRegister;
+		DWORD dw_ControlRegister;
+		DWORD dw_StatusRegister;
+	} s_PulseEncoderModuleInfo;
+
+	/* Tor conter infos */
+	struct {
+		struct {
+			BYTE b_TorCounterInit;
+			BYTE b_TimingUnit;
+			BYTE b_InterruptEnable;
+			double d_TimingInterval;
+			ULONG ul_RealTimingInterval;
+		} s_TorCounterInfo[2];
+		BYTE b_PCIInputClock;
+	} s_TorCounterModuleInfo;
+
+	/* PWM infos */
+	struct {
+		struct {
+			BYTE b_PWMInit;
+			BYTE b_TimingUnit;
+			BYTE b_InterruptEnable;
+			double d_LowTiming;
+			double d_HighTiming;
+			ULONG ul_RealLowTiming;
+			ULONG ul_RealHighTiming;
+		} s_PWMInfo[2];
+		BYTE b_ClockSelection;
+	} s_PWMModuleInfo;
+
+	/* ETM infos */
+	struct {
+		struct {
+			BYTE b_ETMEnable;
+			BYTE b_ETMInterrupt;
+		} s_ETMInfo[2];
+		BYTE b_ETMInit;
+		BYTE b_TimingUnit;
+		BYTE b_ClockSelection;
+		double d_TimingInterval;
+		ULONG ul_Timing;
+	} s_ETMModuleInfo;
+
+	/* CDA infos */
+	struct {
+		BYTE b_CDAEnable;
+		BYTE b_CDAInterrupt;
+		BYTE b_CDAInit;
+		BYTE b_FctSelection;
+		BYTE b_CDAReadFIFOOverflow;
+	} s_CDAModuleInfo;
+
+} str_ModuleInfo;
+
+/* Private structure for the addi_apci3120 driver */
+typedef struct {
+
+	INT iobase;
+	INT i_IobaseAmcc;	// base+size for AMCC chip
+	INT i_IobaseAddon;	//addon base address
+	INT i_IobaseReserved;
+	ULONG_PTR dw_AiBase;
+	struct pcilst_struct *amcc;	// ptr too AMCC data
+	BYTE allocated;		// we have blocked card
+	BYTE b_ValidDriver;	// driver is ok
+	BYTE b_AiContinuous;	// we do unlimited AI
+	BYTE b_AiInitialisation;
+	UINT ui_AiActualScan;	//how many scans we finished
+	UINT ui_AiBufferPtr;	// data buffer ptr in samples
+	UINT ui_AiNbrofChannels;	// how many channels is measured
+	UINT ui_AiScanLength;	// Length of actual scanlist
+	UINT ui_AiActualScanPosition;	// position in actual scan
+	PUINT pui_AiChannelList;	// actual chanlist
+	UINT ui_AiChannelList[32];	// actual chanlist
+	BYTE b_AiChannelConfiguration[32];	// actual chanlist
+	UINT ui_AiReadData[32];
+	DWORD dw_AiInitialised;
+	UINT ui_AiTimer0;	//Timer Constant for Timer0
+	UINT ui_AiTimer1;	//Timer constant for Timer1
+	UINT ui_AiFlags;
+	UINT ui_AiDataLength;
+	short *AiData;	// Pointer to sample data
+	UINT ui_AiNbrofScans;	// number of scans to do
+	USHORT us_UseDma;	// To use Dma or not
+	BYTE b_DmaDoubleBuffer;	// we can use double buffering
+	UINT ui_DmaActualBuffer;	// which buffer is used now
+	//*UPDATE-0.7.57->0.7.68
+	//ULONG               ul_DmaBufferVirtual[2];// pointers to begin of DMA buffer
+	short *ul_DmaBufferVirtual[2];	// pointers to begin of DMA buffer
+	ULONG ul_DmaBufferHw[2];	// hw address of DMA buff
+	UINT ui_DmaBufferSize[2];	// size of dma buffer in bytes
+	UINT ui_DmaBufferUsesize[2];	// which size we may now used for transfer
+	UINT ui_DmaBufferSamples[2];	// size in samples
+	UINT ui_DmaBufferPages[2];	// number of pages in buffer
+	BYTE b_DigitalOutputRegister;	// Digital Output Register
+	BYTE b_OutputMemoryStatus;
+	BYTE b_AnalogInputChannelNbr;	// Analog input channel Nbr
+	BYTE b_AnalogOutputChannelNbr;	// Analog input Output  Nbr
+	BYTE b_TimerSelectMode;	// Contain data written at iobase + 0C
+	BYTE b_ModeSelectRegister;	// Contain data written at iobase + 0E
+	USHORT us_OutputRegister;	// Contain data written at iobase + 0
+	BYTE b_InterruptState;
+	BYTE b_TimerInit;	// Specify if InitTimerWatchdog was load
+	BYTE b_TimerStarted;	// Specify if timer 2 is running or not
+	BYTE b_Timer2Mode;	// Specify the timer 2 mode
+	BYTE b_Timer2Interrupt;	//Timer2  interrupt enable or disable
+	BYTE b_AiCyclicAcquisition;	// indicate cyclic acquisition
+	BYTE b_InterruptMode;	// eoc eos or dma
+	BYTE b_EocEosInterrupt;	// Enable disable eoc eos interrupt
+	UINT ui_EocEosConversionTime;
+	BYTE b_EocEosConversionTimeBase;
+	BYTE b_SingelDiff;
+	BYTE b_ExttrigEnable;	/* To enable or disable external trigger */
+
+	/* Pointer to the current process */
+	struct task_struct *tsk_Current;
+	boardtype *ps_BoardInfo;
+
+	/* Hardware board infos for 1710 */
+	struct {
+		UINT ui_Address;	/* Board address */
+		UINT ui_FlashAddress;
+		BYTE b_InterruptNbr;	/* Board interrupt number */
+		BYTE b_SlotNumber;	/* PCI slot number */
+		BYTE b_BoardVersion;
+		DWORD dw_MolduleConfiguration[4];	/* Module config */
+	} s_BoardInfos;
+
+	/* Interrupt infos */
+	struct {
+		ULONG ul_InterruptOccur;	/* 0   : No interrupt occur */
+						/* > 0 : Interrupt occur */
+		UINT ui_Read;	/* Read FIFO */
+		UINT ui_Write;	/* Write FIFO */
+		struct {
+			BYTE b_OldModuleMask;
+			ULONG ul_OldInterruptMask;	/* Interrupt mask */
+			ULONG ul_OldCounterLatchValue;	/* Interrupt counter value */
+		} s_FIFOInterruptParameters[APCI1710_SAVE_INTERRUPT];
+	} s_InterruptParameters;
+
+	str_ModuleInfo s_ModuleInfo[4];
+	ULONG ul_TTLPortConfiguration[10];
+
+} addi_private;
+
+static unsigned short pci_list_builded;	/* set to 1 when list of card is known */
+
+/* Function declarations */
+static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int i_ADDI_Detach(struct comedi_device *dev);
+static int i_ADDI_Reset(struct comedi_device *dev);
+
+static irqreturn_t v_ADDI_Interrupt(int irq, void *d PT_REGS_ARG);
+static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, struct comedi_subdevice *s,
+				     struct comedi_insn *insn, unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c
new file mode 100644
index 0000000..a8a1bb2
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c
@@ -0,0 +1,1158 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+
+        ADDI-DATA GmbH
+        Dieselstrasse 3
+        D-77833 Ottersweier
+        Tel: +19(0)7223/9493-0
+        Fax: +49(0)7223/9493-92
+        http://www.addi-data-com
+        info@addi-data.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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+  +-----------------------------------------------------------------------+
+  | (C) ADDI-DATA GmbH          Dieselstrasse 3      D-77833 Ottersweier  |
+  +-----------------------------------------------------------------------+
+  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
+  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
+  +-----------------------------------------------------------------------+
+  | Project   : ADDI DATA         | Compiler : GCC 			              |
+  | Modulname : addi_eeprom.c     | Version  : 2.96                       |
+  +-------------------------------+---------------------------------------+
+  | Project manager: Eric Stolz   | Date     :  02/12/2002                |
+  +-----------------------------------------------------------------------+
+  | Description : ADDI EEPROM  Module                                     |
+  +-----------------------------------------------------------------------+
+  |                             UPDATE'S                                  |
+  +-----------------------------------------------------------------------+
+  |   Date   |   Author  |          Description of updates                |
+  +----------+-----------+------------------------------------------------+
+  |          | 		 | 						  |
+  |          |           | 						  |
+  +----------+-----------+------------------------------------------------+
+*/
+
+#define NVCMD_BEGIN_READ 	(0x7 << 5 )	// nvRam begin read command
+#define NVCMD_LOAD_LOW   	(0x4 << 5 )	// nvRam load low command
+#define NVCMD_LOAD_HIGH  	(0x5 << 5 )	// nvRam load high command
+#define EE76_CMD_LEN    	13	// bits in instructions
+#define EE_READ         	0x0180	// 01 1000 0000 read instruction
+
+#define	WORD				unsigned short
+#define PWORD				unsigned short *
+#define PDWORD				unsigned int  *
+
+#ifndef DWORD
+#define	DWORD				unsigned int
+#endif
+
+#define EEPROM_DIGITALINPUT 			0
+#define EEPROM_DIGITALOUTPUT			1
+#define EEPROM_ANALOGINPUT				2
+#define EEPROM_ANALOGOUTPUT				3
+#define EEPROM_TIMER					4
+#define EEPROM_WATCHDOG					5
+#define EEPROM_TIMER_WATCHDOG_COUNTER	10
+
+struct str_Functionality {
+	BYTE b_Type;
+	WORD w_Address;
+};
+
+typedef struct {
+	WORD w_HeaderSize;
+	BYTE b_Nfunctions;
+	struct str_Functionality s_Functions[7];
+} str_MainHeader;
+
+typedef struct {
+	WORD w_Nchannel;
+	BYTE b_Interruptible;
+	WORD w_NinterruptLogic;
+} str_DigitalInputHeader;
+
+typedef struct {
+	WORD w_Nchannel;
+} str_DigitalOutputHeader;
+
+// used for timer as well as watchdog
+
+typedef struct {
+	WORD w_HeaderSize;
+	BYTE b_Resolution;
+	BYTE b_Mode;		// in case of Watchdog it is functionality
+	WORD w_MinTiming;
+	BYTE b_TimeBase;
+} str_TimerDetails;
+typedef struct {
+
+	WORD w_Ntimer;
+	str_TimerDetails s_TimerDetails[4];	//  supports 4 timers
+} str_TimerMainHeader;
+
+typedef struct {
+	WORD w_Nchannel;
+	BYTE b_Resolution;
+} str_AnalogOutputHeader;
+
+typedef struct {
+	WORD w_Nchannel;
+	WORD w_MinConvertTiming;
+	WORD w_MinDelayTiming;
+	BYTE b_HasDma;
+	BYTE b_Resolution;
+} str_AnalogInputHeader;
+
+		/*****************************************/
+		/*            Read Header Functions              */
+		/*****************************************/
+
+INT i_EepromReadMainHeader(WORD w_PCIBoardEepromAddress,
+	char *pc_PCIChipInformation, struct comedi_device *dev);
+
+INT i_EepromReadDigitalInputHeader(WORD w_PCIBoardEepromAddress,
+	char *pc_PCIChipInformation, WORD w_Address,
+	str_DigitalInputHeader * s_Header);
+
+INT i_EepromReadDigitalOutputHeader(WORD w_PCIBoardEepromAddress,
+	char *pc_PCIChipInformation, WORD w_Address,
+	str_DigitalOutputHeader * s_Header);
+
+INT i_EepromReadTimerHeader(WORD w_PCIBoardEepromAddress,
+	char *pc_PCIChipInformation, WORD w_Address,
+	str_TimerMainHeader * s_Header);
+
+INT i_EepromReadAnlogOutputHeader(WORD w_PCIBoardEepromAddress,
+	char *pc_PCIChipInformation, WORD w_Address,
+	str_AnalogOutputHeader * s_Header);
+
+INT i_EepromReadAnlogInputHeader(WORD w_PCIBoardEepromAddress,
+	char *pc_PCIChipInformation, WORD w_Address,
+	str_AnalogInputHeader * s_Header);
+
+		/******************************************/
+		/*      Eeprom Specific Functions                         */
+		/******************************************/
+WORD w_EepromReadWord(WORD w_PCIBoardEepromAddress, char *pc_PCIChipInformation,
+	WORD w_EepromStartAddress);
+void v_EepromWaitBusy(WORD w_PCIBoardEepromAddress);
+void v_EepromClock76(DWORD dw_Address, DWORD dw_RegisterValue);
+void v_EepromWaitBusy(WORD w_PCIBoardEepromAddress);
+void v_EepromSendCommand76(DWORD dw_Address, DWORD dw_EepromCommand,
+	BYTE b_DataLengthInBits);
+void v_EepromCs76Read(DWORD dw_Address, WORD w_offset, PWORD pw_Value);
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : WORD w_EepromReadWord                                  |
+|				(WORD	w_PCIBoardEepromAddress,             		 |
+|				 char *	pc_PCIChipInformation,               		 |
+|				 WORD   w_EepromStartAddress)                		 |
++----------------------------------------------------------------------------+
+| Task              : Read from eepromn a word                               |
++----------------------------------------------------------------------------+
+| Input Parameters  : WORD w_PCIBoardEepromAddress : PCI eeprom address      |
+|																	 |
+|		      char *pc_PCIChipInformation  : PCI Chip Type.          |
+|																	 |
+|		      WORD w_EepromStartAddress    : Selected eeprom address |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : Read word value from eeprom                            |
++----------------------------------------------------------------------------+
+*/
+
+WORD w_EepromReadWord(WORD w_PCIBoardEepromAddress, char *pc_PCIChipInformation,
+	WORD w_EepromStartAddress)
+{
+
+	BYTE b_Counter = 0;
+
+	BYTE b_ReadByte = 0;
+
+	BYTE b_ReadLowByte = 0;
+
+	BYTE b_ReadHighByte = 0;
+
+	BYTE b_SelectedAddressLow = 0;
+
+	BYTE b_SelectedAddressHigh = 0;
+
+	WORD w_ReadWord = 0;
+
+	/**************************/
+
+	/* Test the PCI chip type */
+
+	/**************************/
+
+	if ((!strcmp(pc_PCIChipInformation, "S5920")) ||
+		(!strcmp(pc_PCIChipInformation, "S5933")))
+	{
+
+		for (b_Counter = 0; b_Counter < 2; b_Counter++)
+		{
+
+			b_SelectedAddressLow = (w_EepromStartAddress + b_Counter) % 256;	//Read the low 8 bit part
+
+			b_SelectedAddressHigh = (w_EepromStartAddress + b_Counter) / 256;	//Read the high 8 bit part
+
+	      /************************************/
+
+			/* Select the load low address mode */
+
+	      /************************************/
+
+			outb(NVCMD_LOAD_LOW, w_PCIBoardEepromAddress + 0x3F);
+
+	      /****************/
+
+			/* Wait on busy */
+
+	      /****************/
+
+			v_EepromWaitBusy(w_PCIBoardEepromAddress);
+
+	      /************************/
+
+			/* Load the low address */
+
+	      /************************/
+
+			outb(b_SelectedAddressLow,
+				w_PCIBoardEepromAddress + 0x3E);
+
+	      /****************/
+
+			/* Wait on busy */
+
+	      /****************/
+
+			v_EepromWaitBusy(w_PCIBoardEepromAddress);
+
+	      /*************************************/
+
+			/* Select the load high address mode */
+
+	      /*************************************/
+
+			outb(NVCMD_LOAD_HIGH, w_PCIBoardEepromAddress + 0x3F);
+
+	      /****************/
+
+			/* Wait on busy */
+
+	      /****************/
+
+			v_EepromWaitBusy(w_PCIBoardEepromAddress);
+
+	      /*************************/
+
+			/* Load the high address */
+
+	      /*************************/
+
+			outb(b_SelectedAddressHigh,
+				w_PCIBoardEepromAddress + 0x3E);
+
+	      /****************/
+
+			/* Wait on busy */
+
+	      /****************/
+
+			v_EepromWaitBusy(w_PCIBoardEepromAddress);
+
+	      /************************/
+
+			/* Select the READ mode */
+
+	      /************************/
+
+			outb(NVCMD_BEGIN_READ, w_PCIBoardEepromAddress + 0x3F);
+
+	      /****************/
+
+			/* Wait on busy */
+
+	      /****************/
+
+			v_EepromWaitBusy(w_PCIBoardEepromAddress);
+
+	      /*****************************/
+
+			/* Read data into the EEPROM */
+
+	      /*****************************/
+
+			b_ReadByte = inb(w_PCIBoardEepromAddress + 0x3E);
+
+	      /****************/
+
+			/* Wait on busy */
+
+	      /****************/
+
+			v_EepromWaitBusy(w_PCIBoardEepromAddress);
+
+	      /*********************************/
+
+			/* Select the upper address part */
+
+	      /*********************************/
+
+			if (b_Counter == 0)
+			{
+
+				b_ReadLowByte = b_ReadByte;
+
+			}	// if(b_Counter==0)
+
+			else
+			{
+
+				b_ReadHighByte = b_ReadByte;
+
+			}	// if(b_Counter==0)
+
+		}		// for (b_Counter=0; b_Counter<2; b_Counter++)
+
+		w_ReadWord = (b_ReadLowByte | (((WORD) b_ReadHighByte) * 256));
+
+	}			// end of if ((!strcmp(pc_PCIChipInformation, "S5920")) || (!strcmp(pc_PCIChipInformation, "S5933")))
+
+	if (!strcmp(pc_PCIChipInformation, "93C76"))
+	{
+
+	   /*************************************/
+
+		/* Read 16 bit from the EEPROM 93C76 */
+
+	   /*************************************/
+
+		v_EepromCs76Read(w_PCIBoardEepromAddress, w_EepromStartAddress,
+			&w_ReadWord);
+
+	}
+
+	return (w_ReadWord);
+
+}
+
+/*
+
++----------------------------------------------------------------------------+
+
+| Function   Name   : void v_EepromWaitBusy                                  |
+
+|			(WORD	w_PCIBoardEepromAddress)                    	 |
+
++----------------------------------------------------------------------------+
+
+| Task              : Wait the busy flag from PCI controller                 |
+
++----------------------------------------------------------------------------+
+
+| Input Parameters  : WORD w_PCIBoardEepromAddress : PCI eeprom base address |
+
++----------------------------------------------------------------------------+
+
+| Output Parameters : -                                                      |
+
++----------------------------------------------------------------------------+
+
+| Return Value      : -                                                      |
+
++----------------------------------------------------------------------------+
+
+*/
+
+void v_EepromWaitBusy(WORD w_PCIBoardEepromAddress)
+{
+
+	BYTE b_EepromBusy = 0;
+
+	do
+	{
+
+	   /*************/
+
+		/* IMPORTANT */
+
+	   /*************/
+
+	   /************************************************************************/
+
+		/* An error has been written in the AMCC 5933 book at the page B-13 */
+
+		/* Ex: if you read a byte and look for the busy statusEEPROM=0x80 and   */
+
+		/*      the operator register is AMCC_OP_REG_MCSR+3 */
+
+		/*      WORD read  EEPROM=0x8000 andAMCC_OP_REG_MCSR+2                  */
+
+		/*      DWORD read  EEPROM=0x80000000 and AMCC_OP_REG_MCSR */
+
+	   /************************************************************************/
+
+		b_EepromBusy = inb(w_PCIBoardEepromAddress + 0x3F);
+		b_EepromBusy = b_EepromBusy & 0x80;
+
+	}
+	while (b_EepromBusy == 0x80);
+
+}
+
+/*
+
++---------------------------------------------------------------------------------+
+
+| Function   Name   : void v_EepromClock76(DWORD dw_Address,                      |
+
+|					   DWORD dw_RegisterValue)                 			  |
+
++---------------------------------------------------------------------------------+
+
+| Task              : This function sends the clocking sequence to the EEPROM.    |
+
++---------------------------------------------------------------------------------+
+
+| Input Parameters  : DWORD dw_Address : PCI eeprom base address                  |
+
+|		      DWORD dw_RegisterValue : PCI eeprom register value to write.|
+
++---------------------------------------------------------------------------------+
+
+| Output Parameters : -                                                           |
+
++---------------------------------------------------------------------------------+
+
+| Return Value      : -                                                           |
+
++---------------------------------------------------------------------------------+
+
+*/
+
+void v_EepromClock76(DWORD dw_Address, DWORD dw_RegisterValue)
+{
+
+   /************************/
+
+	/* Set EEPROM clock Low */
+
+   /************************/
+
+	outl(dw_RegisterValue & 0x6, dw_Address);
+
+   /***************/
+
+	/* Wait 0.1 ms */
+
+   /***************/
+
+	udelay(100);
+
+   /*************************/
+
+	/* Set EEPROM clock High */
+
+   /*************************/
+
+	outl(dw_RegisterValue | 0x1, dw_Address);
+
+   /***************/
+
+	/* Wait 0.1 ms */
+
+   /***************/
+
+	udelay(100);
+
+}
+
+/*
+
++---------------------------------------------------------------------------------+
+
+| Function   Name   : void v_EepromSendCommand76(DWORD dw_Address,                |
+
+|					   DWORD   dw_EepromCommand,                		  |
+
+|					   BYTE    b_DataLengthInBits)                        |
+
++---------------------------------------------------------------------------------+
+
+| Task              : This function sends a Command to the EEPROM 93C76.          |
+
++---------------------------------------------------------------------------------+
+
+| Input Parameters  : DWORD dw_Address : PCI eeprom base address                  |
+
+|		      DWORD dw_EepromCommand : PCI eeprom command to write.       |
+
+|		      BYTE  b_DataLengthInBits : PCI eeprom command data length.  |
+
++---------------------------------------------------------------------------------+
+
+| Output Parameters : -                                                           |
+
++---------------------------------------------------------------------------------+
+
+| Return Value      : -                                                           |
+
++---------------------------------------------------------------------------------+
+
+*/
+
+void v_EepromSendCommand76(DWORD dw_Address, DWORD dw_EepromCommand,
+	BYTE b_DataLengthInBits)
+{
+
+	char c_BitPos = 0;
+
+	DWORD dw_RegisterValue = 0;
+
+   /*****************************/
+
+	/* Enable EEPROM Chip Select */
+
+   /*****************************/
+
+	dw_RegisterValue = 0x2;
+
+   /********************************************************************/
+
+	/* Toggle EEPROM's Chip select to get it out of Shift Register Mode */
+
+   /********************************************************************/
+
+	outl(dw_RegisterValue, dw_Address);
+
+   /***************/
+
+	/* Wait 0.1 ms */
+
+   /***************/
+
+	udelay(100);
+
+   /*******************************************/
+
+	/* Send EEPROM command - one bit at a time */
+
+   /*******************************************/
+
+	for (c_BitPos = (b_DataLengthInBits - 1); c_BitPos >= 0; c_BitPos--)
+	{
+
+      /**********************************/
+
+		/* Check if current bit is 0 or 1 */
+
+      /**********************************/
+
+		if (dw_EepromCommand & (1 << c_BitPos))
+		{
+
+	 /***********/
+
+			/* Write 1 */
+
+	 /***********/
+
+			dw_RegisterValue = dw_RegisterValue | 0x4;
+
+		}
+
+		else
+		{
+
+	 /***********/
+
+			/* Write 0 */
+
+	 /***********/
+
+			dw_RegisterValue = dw_RegisterValue & 0x3;
+
+		}
+
+      /*********************/
+
+		/* Write the command */
+
+      /*********************/
+
+		outl(dw_RegisterValue, dw_Address);
+
+      /***************/
+
+		/* Wait 0.1 ms */
+
+      /***************/
+
+		udelay(100);
+
+      /****************************/
+
+		/* Trigger the EEPROM clock */
+
+      /****************************/
+
+		v_EepromClock76(dw_Address, dw_RegisterValue);
+
+	}
+
+}
+
+/*
+
++---------------------------------------------------------------------------------+
+
+| Function   Name   : void v_EepromCs76Read(DWORD dw_Address,                     |
+
+|					   WORD    w_offset,                      			  |
+
+|					   PWORD   pw_Value)                      			  |
+
++---------------------------------------------------------------------------------+
+
+| Task              : This function read a value from the EEPROM 93C76.           |
+
++---------------------------------------------------------------------------------+
+
+| Input Parameters  : DWORD dw_Address : PCI eeprom base address                  |
+
+|		      WORD    w_offset : Offset of the adress to read             |
+
+|		      PWORD   pw_Value : PCI eeprom 16 bit read value.            |
+
++---------------------------------------------------------------------------------+
+
+| Output Parameters : -                                                           |
+
++---------------------------------------------------------------------------------+
+
+| Return Value      : -                                                           |
+
++---------------------------------------------------------------------------------+
+
+*/
+
+void v_EepromCs76Read(DWORD dw_Address, WORD w_offset, PWORD pw_Value)
+{
+
+        char c_BitPos = 0;
+
+	DWORD dw_RegisterValue = 0;
+
+	DWORD dw_RegisterValueRead = 0;
+
+   /*************************************************/
+
+	/* Send EEPROM read command and offset to EEPROM */
+
+   /*************************************************/
+
+	v_EepromSendCommand76(dw_Address, (EE_READ << 4) | (w_offset / 2),
+		EE76_CMD_LEN);
+
+   /*******************************/
+
+	/* Get the last register value */
+
+   /*******************************/
+
+	dw_RegisterValue = (((w_offset / 2) & 0x1) << 2) | 0x2;
+
+   /*****************************/
+
+	/* Set the 16-bit value of 0 */
+
+   /*****************************/
+
+	*pw_Value = 0;
+
+   /************************/
+
+	/* Get the 16-bit value */
+
+   /************************/
+
+	for (c_BitPos = 0; c_BitPos < 16; c_BitPos++)
+	{
+
+      /****************************/
+
+		/* Trigger the EEPROM clock */
+
+      /****************************/
+
+		v_EepromClock76(dw_Address, dw_RegisterValue);
+
+      /**********************/
+
+		/* Get the result bit */
+
+      /**********************/
+
+		dw_RegisterValueRead = inl(dw_Address);
+
+      /***************/
+
+		/* Wait 0.1 ms */
+
+      /***************/
+
+		udelay(100);
+
+      /***************************************/
+
+		/* Get bit value and shift into result */
+
+      /***************************************/
+
+		if (dw_RegisterValueRead & 0x8)
+		{
+
+	 /**********/
+
+			/* Read 1 */
+
+	 /**********/
+
+			*pw_Value = (*pw_Value << 1) | 0x1;
+
+		}
+
+		else
+		{
+
+	 /**********/
+
+			/* Read 0 */
+
+	 /**********/
+
+			*pw_Value = (*pw_Value << 1);
+
+		}
+
+	}
+
+   /*************************/
+
+	/* Clear all EEPROM bits */
+
+   /*************************/
+
+	dw_RegisterValue = 0x0;
+
+   /********************************************************************/
+
+	/* Toggle EEPROM's Chip select to get it out of Shift Register Mode */
+
+   /********************************************************************/
+
+	outl(dw_RegisterValue, dw_Address);
+
+   /***************/
+
+	/* Wait 0.1 ms */
+
+   /***************/
+
+	udelay(100);
+
+}
+
+	/******************************************/
+	/*      EEPROM HEADER READ FUNCTIONS      */
+	/******************************************/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name  : INT i_EepromReadMainHeader(WORD w_PCIBoardEepromAddress,  |
+|				char *	pc_PCIChipInformation,struct comedi_device *dev)    |
++----------------------------------------------------------------------------+
+| Task              : Read from eeprom Main Header                           |
++----------------------------------------------------------------------------+
+| Input Parameters  : WORD w_PCIBoardEepromAddress : PCI eeprom address      |
+|																	 |
+|		      char *pc_PCIChipInformation  : PCI Chip Type.          |
+|																	 |
+|			  struct comedi_device *dev		   : comedi device structure |
+|											 pointer				 |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : 0							                             |
++----------------------------------------------------------------------------+
+*/
+
+INT i_EepromReadMainHeader(WORD w_PCIBoardEepromAddress,
+	char *pc_PCIChipInformation, struct comedi_device *dev)
+{
+	WORD w_Temp, i, w_Count = 0;
+	UINT ui_Temp;
+	str_MainHeader s_MainHeader;
+	str_DigitalInputHeader s_DigitalInputHeader;
+	str_DigitalOutputHeader s_DigitalOutputHeader;
+	//str_TimerMainHeader     s_TimerMainHeader,s_WatchdogMainHeader;
+	str_AnalogOutputHeader s_AnalogOutputHeader;
+	str_AnalogInputHeader s_AnalogInputHeader;
+
+	// Read size
+	s_MainHeader.w_HeaderSize =
+		w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
+		0x100 + 8);
+
+	// Read nbr of functionality
+	w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+		pc_PCIChipInformation, 0x100 + 10);
+	s_MainHeader.b_Nfunctions = (BYTE) w_Temp & 0x00FF;
+
+	// Read functionality details
+	for (i = 0; i < s_MainHeader.b_Nfunctions; i++) {
+		// Read Type
+		w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+			pc_PCIChipInformation, 0x100 + 12 + w_Count);
+		s_MainHeader.s_Functions[i].b_Type = (BYTE) w_Temp & 0x3F;
+		w_Count = w_Count + 2;
+		//Read Address
+		s_MainHeader.s_Functions[i].w_Address =
+			w_EepromReadWord(w_PCIBoardEepromAddress,
+			pc_PCIChipInformation, 0x100 + 12 + w_Count);
+		w_Count = w_Count + 2;
+	}
+
+	// Display main header info
+	for (i = 0; i < s_MainHeader.b_Nfunctions; i++) {
+
+		switch (s_MainHeader.s_Functions[i].b_Type) {
+		case EEPROM_DIGITALINPUT:
+			i_EepromReadDigitalInputHeader(w_PCIBoardEepromAddress,
+				pc_PCIChipInformation,
+				s_MainHeader.s_Functions[i].w_Address,
+				&s_DigitalInputHeader);
+			this_board->i_NbrDiChannel =
+				s_DigitalInputHeader.w_Nchannel;
+			break;
+
+		case EEPROM_DIGITALOUTPUT:
+			i_EepromReadDigitalOutputHeader(w_PCIBoardEepromAddress,
+				pc_PCIChipInformation,
+				s_MainHeader.s_Functions[i].w_Address,
+				&s_DigitalOutputHeader);
+			this_board->i_NbrDoChannel =
+				s_DigitalOutputHeader.w_Nchannel;
+			ui_Temp = 0xffffffff;
+			this_board->i_DoMaxdata =
+				ui_Temp >> (32 - this_board->i_NbrDoChannel);
+			break;
+
+		case EEPROM_ANALOGINPUT:
+			i_EepromReadAnlogInputHeader(w_PCIBoardEepromAddress,
+				pc_PCIChipInformation,
+				s_MainHeader.s_Functions[i].w_Address,
+				&s_AnalogInputHeader);
+			if (!(strcmp(this_board->pc_DriverName, "apci3200")))
+				this_board->i_NbrAiChannel =
+					s_AnalogInputHeader.w_Nchannel * 4;
+			else
+				this_board->i_NbrAiChannel =
+					s_AnalogInputHeader.w_Nchannel;
+			this_board->i_Dma = s_AnalogInputHeader.b_HasDma;
+			this_board->ui_MinAcquisitiontimeNs =
+				(UINT) s_AnalogInputHeader.w_MinConvertTiming *
+				1000;
+			this_board->ui_MinDelaytimeNs =
+				(UINT) s_AnalogInputHeader.w_MinDelayTiming *
+				1000;
+			ui_Temp = 0xffff;
+			this_board->i_AiMaxdata =
+				ui_Temp >> (16 -
+				s_AnalogInputHeader.b_Resolution);
+			break;
+
+		case EEPROM_ANALOGOUTPUT:
+			i_EepromReadAnlogOutputHeader(w_PCIBoardEepromAddress,
+				pc_PCIChipInformation,
+				s_MainHeader.s_Functions[i].w_Address,
+				&s_AnalogOutputHeader);
+			this_board->i_NbrAoChannel =
+				s_AnalogOutputHeader.w_Nchannel;
+			ui_Temp = 0xffff;
+			this_board->i_AoMaxdata =
+				ui_Temp >> (16 -
+				s_AnalogOutputHeader.b_Resolution);
+			break;
+
+		case EEPROM_TIMER:
+			this_board->i_Timer = 1;	//Timer subdevice present
+			break;
+
+		case EEPROM_WATCHDOG:
+			this_board->i_Timer = 1;	//Timer subdevice present
+			break;
+
+		case EEPROM_TIMER_WATCHDOG_COUNTER:
+			this_board->i_Timer = 1;	//Timer subdevice present
+		}
+	}
+
+	return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name  : INT i_EepromReadDigitalInputHeader(WORD 					 |
+|			w_PCIBoardEepromAddress,char *pc_PCIChipInformation,	 |
+|			WORD w_Address,str_DigitalInputHeader *s_Header)		 |
+|																	 |
++----------------------------------------------------------------------------+
+| Task              : Read Digital Input Header                              |
++----------------------------------------------------------------------------+
+| Input Parameters  : WORD w_PCIBoardEepromAddress : PCI eeprom address      |
+|																	 |
+|		      char *pc_PCIChipInformation  : PCI Chip Type.          |
+|																	 |
+|			 str_DigitalInputHeader *s_Header: Digita Input Header   |
+|												   Pointer			 |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : 0							                             |
++----------------------------------------------------------------------------+
+*/
+INT i_EepromReadDigitalInputHeader(WORD w_PCIBoardEepromAddress,
+	char *pc_PCIChipInformation, WORD w_Address,
+	str_DigitalInputHeader * s_Header)
+{
+	WORD w_Temp;
+
+	// read nbr of channels
+	s_Header->w_Nchannel =
+		w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
+		0x100 + w_Address + 6);
+
+	// interruptible or not
+	w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+		pc_PCIChipInformation, 0x100 + w_Address + 8);
+	s_Header->b_Interruptible = (BYTE) (w_Temp >> 7) & 0x01;
+
+// How many interruptible logic
+	s_Header->w_NinterruptLogic =
+		w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
+		0x100 + w_Address + 10);
+
+	return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name  : INT i_EepromReadDigitalOutputHeader(WORD 				 |
+|			w_PCIBoardEepromAddress,char *pc_PCIChipInformation,	 |
+|			WORD w_Address,str_DigitalOutputHeader *s_Header)	     |
+|																	 |
++----------------------------------------------------------------------------+
+| Task              : Read Digital Output Header                             |
++----------------------------------------------------------------------------+
+| Input Parameters  : WORD w_PCIBoardEepromAddress : PCI eeprom address      |
+|																	 |
+|		      char *pc_PCIChipInformation  : PCI Chip Type.          |
+|																	 |
+|			 str_DigitalOutputHeader *s_Header: Digital Output Header|
+|											   Pointer				 |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : 0							                             |
++----------------------------------------------------------------------------+
+*/
+INT i_EepromReadDigitalOutputHeader(WORD w_PCIBoardEepromAddress,
+	char *pc_PCIChipInformation, WORD w_Address,
+	str_DigitalOutputHeader * s_Header)
+{
+// Read Nbr channels
+	s_Header->w_Nchannel =
+		w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
+		0x100 + w_Address + 6);
+	return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name  : INT i_EepromReadTimerHeader(WORD w_PCIBoardEepromAddress, |
+|			char *pc_PCIChipInformation,WORD w_Address,				 |
+|			str_TimerMainHeader *s_Header)							 |
++----------------------------------------------------------------------------+
+| Task              : Read Timer or Watchdog Header                          |
++----------------------------------------------------------------------------+
+| Input Parameters  : WORD w_PCIBoardEepromAddress : PCI eeprom address      |
+|																	 |
+|		      char *pc_PCIChipInformation  : PCI Chip Type.          |
+|																	 |
+|			 str_TimerMainHeader *s_Header: Timer Header			 |
+|											   Pointer				 |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : 0							                             |
++----------------------------------------------------------------------------+
+*/
+INT i_EepromReadTimerHeader(WORD w_PCIBoardEepromAddress,
+	char *pc_PCIChipInformation, WORD w_Address,
+	str_TimerMainHeader * s_Header)
+{
+
+	WORD i, w_Size = 0, w_Temp;
+
+//Read No of Timer
+	s_Header->w_Ntimer =
+		w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
+		0x100 + w_Address + 6);
+//Read header size
+
+	for (i = 0; i < s_Header->w_Ntimer; i++) {
+		s_Header->s_TimerDetails[i].w_HeaderSize =
+			w_EepromReadWord(w_PCIBoardEepromAddress,
+			pc_PCIChipInformation,
+			0x100 + w_Address + 8 + w_Size + 0);
+		w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+			pc_PCIChipInformation,
+			0x100 + w_Address + 8 + w_Size + 2);
+
+		//Read Resolution
+		s_Header->s_TimerDetails[i].b_Resolution =
+			(BYTE) (w_Temp >> 10) & 0x3F;
+
+		//Read Mode
+		s_Header->s_TimerDetails[i].b_Mode =
+			(BYTE) (w_Temp >> 4) & 0x3F;
+
+		w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+			pc_PCIChipInformation,
+			0x100 + w_Address + 8 + w_Size + 4);
+
+		//Read MinTiming
+		s_Header->s_TimerDetails[i].w_MinTiming = (w_Temp >> 6) & 0x3FF;
+
+		//Read Timebase
+		s_Header->s_TimerDetails[i].b_TimeBase = (BYTE) (w_Temp) & 0x3F;
+		w_Size += s_Header->s_TimerDetails[i].w_HeaderSize;
+	}
+
+	return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name  : INT i_EepromReadAnlogOutputHeader(WORD 					 |
+|			w_PCIBoardEepromAddress,char *pc_PCIChipInformation,	 |
+|			WORD w_Address,str_AnalogOutputHeader *s_Header)         |
++----------------------------------------------------------------------------+
+| Task              : Read Nalog Output  Header                              |
++----------------------------------------------------------------------------+
+| Input Parameters  : WORD w_PCIBoardEepromAddress : PCI eeprom address      |
+|																	 |
+|		      char *pc_PCIChipInformation  : PCI Chip Type.          |
+|																	 |
+|			 str_AnalogOutputHeader *s_Header:Anlog Output Header    |
+|											   Pointer				 |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : 0							                             |
++----------------------------------------------------------------------------+
+*/
+
+INT i_EepromReadAnlogOutputHeader(WORD w_PCIBoardEepromAddress,
+	char *pc_PCIChipInformation, WORD w_Address,
+	str_AnalogOutputHeader * s_Header)
+{
+	WORD w_Temp;
+	// No of channels for 1st hard component
+	w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+		pc_PCIChipInformation, 0x100 + w_Address + 10);
+	s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF;
+	// Resolution for 1st hard component
+	w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+		pc_PCIChipInformation, 0x100 + w_Address + 16);
+	s_Header->b_Resolution = (BYTE) (w_Temp >> 8) & 0xFF;
+	return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name  : INT i_EepromReadAnlogInputHeader(WORD 					 |
+|			w_PCIBoardEepromAddress,char *pc_PCIChipInformation,     |
+|			WORD w_Address,str_AnalogInputHeader *s_Header)          |
++----------------------------------------------------------------------------+
+| Task              : Read Nalog Output  Header                              |
++----------------------------------------------------------------------------+
+| Input Parameters  : WORD w_PCIBoardEepromAddress : PCI eeprom address      |
+|																	 |
+|		      char *pc_PCIChipInformation  : PCI Chip Type.          |
+|																	 |
+|			 str_AnalogInputHeader *s_Header:Anlog Input Header      |
+|											   Pointer				 |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : 0							                             |
++----------------------------------------------------------------------------+
+*/
+
+// Reads only for ONE  hardware component
+INT i_EepromReadAnlogInputHeader(WORD w_PCIBoardEepromAddress,
+	char *pc_PCIChipInformation, WORD w_Address,
+	str_AnalogInputHeader * s_Header)
+{
+	WORD w_Temp, w_Offset;
+	w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+		pc_PCIChipInformation, 0x100 + w_Address + 10);
+	s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF;
+	s_Header->w_MinConvertTiming =
+		w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
+		0x100 + w_Address + 16);
+	s_Header->w_MinDelayTiming =
+		w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
+		0x100 + w_Address + 30);
+	w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+		pc_PCIChipInformation, 0x100 + w_Address + 20);
+	s_Header->b_HasDma = (w_Temp >> 13) & 0x01;	// whether dma present or not
+
+	w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 72);	// reading Y
+	w_Temp = w_Temp & 0x00FF;
+	if (w_Temp)		//Y>0
+	{
+		w_Offset = 74 + (2 * w_Temp) + (10 * (1 + (w_Temp / 16)));	// offset of first analog input single header
+		w_Offset = w_Offset + 2;	// resolution
+	} else			//Y=0
+	{
+		w_Offset = 74;
+		w_Offset = w_Offset + 2;	// resolution
+	}
+
+// read Resolution
+	w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+		pc_PCIChipInformation, 0x100 + w_Address + w_Offset);
+	s_Header->b_Resolution = w_Temp & 0x001F;	// last 5 bits
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h b/drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h
new file mode 100644
index 0000000..617dc08
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h
@@ -0,0 +1,457 @@
+/*
+	Modified by umesh on 16th may 2001
+	Modified by sarath on 22nd may 2001
+*/
+
+/*
+    comedi/drivers/amcc_s5933_v_58.h
+
+    Stuff for AMCC S5933 PCI Controller
+
+    Author: Michal Dobes <majkl@tesnet.cz>
+
+    Inspirated from general-purpose AMCC S5933 PCI Matchmaker driver
+    made by Andrea Cisternino  <acister@pcape1.pi.infn.it>
+    and as result of espionage from MITE code made by David A. Schleef.
+    Thanks to AMCC for their on-line documentation and bus master DMA
+    example.
+*/
+
+#ifndef _AMCC_S5933_H_
+#define _AMCC_S5933_H_
+
+#include <linux/pci.h>
+#include "../../comedidev.h"
+
+#ifdef PCI_SUPPORT_VER1
+#error    Sorry, no support for 2.1.55 and older! :-((((
+#endif
+
+/***********Added by sarath for compatibility with APCI3120
+
+*************************/
+
+#define FIFO_ADVANCE_ON_BYTE_2     0x20000000	// written on base0
+
+#define AMWEN_ENABLE                     0x02	// added for step 6 dma written on base2
+#define A2P_FIFO_WRITE_ENABLE            0x01
+
+#define AGCSTS_TC_ENABLE		   0x10000000	// Added for transfer count enable bit
+
+//  ADDON RELATED ADDITIONS
+// Constant
+#define     APCI3120_ENABLE_TRANSFER_ADD_ON_LOW       0x00
+#define     APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH      0x1200
+#define     APCI3120_A2P_FIFO_MANAGEMENT              0x04000400L
+#define     APCI3120_AMWEN_ENABLE                     0x02
+#define     APCI3120_A2P_FIFO_WRITE_ENABLE            0x01
+#define     APCI3120_FIFO_ADVANCE_ON_BYTE_2           0x20000000L
+#define     APCI3120_ENABLE_WRITE_TC_INT              0x00004000L
+#define     APCI3120_CLEAR_WRITE_TC_INT               0x00040000L
+#define     APCI3120_DISABLE_AMWEN_AND_A2P_FIFO_WRITE 0x0
+#define     APCI3120_DISABLE_BUS_MASTER_ADD_ON        0x0
+#define     APCI3120_DISABLE_BUS_MASTER_PCI           0x0
+
+ // ADD_ON ::: this needed since apci supports 16 bit interface to add on
+#define     APCI3120_ADD_ON_AGCSTS_LOW       0x3C
+#define     APCI3120_ADD_ON_AGCSTS_HIGH      APCI3120_ADD_ON_AGCSTS_LOW + 2
+#define     APCI3120_ADD_ON_MWAR_LOW         0x24
+#define     APCI3120_ADD_ON_MWAR_HIGH        APCI3120_ADD_ON_MWAR_LOW + 2
+#define     APCI3120_ADD_ON_MWTC_LOW         0x058
+#define     APCI3120_ADD_ON_MWTC_HIGH        APCI3120_ADD_ON_MWTC_LOW + 2
+
+// AMCC
+#define     APCI3120_AMCC_OP_MCSR            0x3C
+#define     APCI3120_AMCC_OP_REG_INTCSR      0x38
+
+/*******from here all upward definitions are added by sarath */
+
+/****************************************************************************/
+/* AMCC Operation Register Offsets - PCI                                    */
+/****************************************************************************/
+
+#define AMCC_OP_REG_OMB1         0x00
+#define AMCC_OP_REG_OMB2         0x04
+#define AMCC_OP_REG_OMB3         0x08
+#define AMCC_OP_REG_OMB4         0x0c
+#define AMCC_OP_REG_IMB1         0x10
+#define AMCC_OP_REG_IMB2         0x14
+#define AMCC_OP_REG_IMB3         0x18
+#define AMCC_OP_REG_IMB4         0x1c
+#define AMCC_OP_REG_FIFO         0x20
+#define AMCC_OP_REG_MWAR         0x24
+#define AMCC_OP_REG_MWTC         0x28
+#define AMCC_OP_REG_MRAR         0x2c
+#define AMCC_OP_REG_MRTC         0x30
+#define AMCC_OP_REG_MBEF         0x34
+#define AMCC_OP_REG_INTCSR       0x38
+#define  AMCC_OP_REG_INTCSR_SRC  (AMCC_OP_REG_INTCSR + 2)	/* INT source */
+#define  AMCC_OP_REG_INTCSR_FEC  (AMCC_OP_REG_INTCSR + 3)	/* FIFO ctrl */
+#define AMCC_OP_REG_MCSR         0x3c
+#define  AMCC_OP_REG_MCSR_NVDATA (AMCC_OP_REG_MCSR + 2)	/* Data in byte 2 */
+#define  AMCC_OP_REG_MCSR_NVCMD  (AMCC_OP_REG_MCSR + 3)	/* Command in byte 3 */
+
+#define AMCC_FIFO_DEPTH_DWORD	8
+#define AMCC_FIFO_DEPTH_BYTES	(8 * sizeof (u32))
+
+/****************************************************************************/
+/* AMCC Operation Registers Size - PCI                                      */
+/****************************************************************************/
+
+#define AMCC_OP_REG_SIZE	 64	/* in bytes */
+
+/****************************************************************************/
+/* AMCC Operation Register Offsets - Add-on                                 */
+/****************************************************************************/
+
+#define AMCC_OP_REG_AIMB1         0x00
+#define AMCC_OP_REG_AIMB2         0x04
+#define AMCC_OP_REG_AIMB3         0x08
+#define AMCC_OP_REG_AIMB4         0x0c
+#define AMCC_OP_REG_AOMB1         0x10
+#define AMCC_OP_REG_AOMB2         0x14
+#define AMCC_OP_REG_AOMB3         0x18
+#define AMCC_OP_REG_AOMB4         0x1c
+#define AMCC_OP_REG_AFIFO         0x20
+#define AMCC_OP_REG_AMWAR         0x24
+#define AMCC_OP_REG_APTA          0x28
+#define AMCC_OP_REG_APTD          0x2c
+#define AMCC_OP_REG_AMRAR         0x30
+#define AMCC_OP_REG_AMBEF         0x34
+#define AMCC_OP_REG_AINT          0x38
+#define AMCC_OP_REG_AGCSTS        0x3c
+#define AMCC_OP_REG_AMWTC         0x58
+#define AMCC_OP_REG_AMRTC         0x5c
+
+/****************************************************************************/
+/* AMCC - Add-on General Control/Status Register                            */
+/****************************************************************************/
+
+#define AGCSTS_CONTROL_MASK	0xfffff000
+#define  AGCSTS_NV_ACC_MASK	0xe0000000
+#define  AGCSTS_RESET_MASK	0x0e000000
+#define  AGCSTS_NV_DA_MASK	0x00ff0000
+#define  AGCSTS_BIST_MASK	0x0000f000
+#define AGCSTS_STATUS_MASK	0x000000ff
+#define  AGCSTS_TCZERO_MASK	0x000000c0
+#define  AGCSTS_FIFO_ST_MASK	0x0000003f
+
+#define AGCSTS_RESET_MBFLAGS	0x08000000
+#define AGCSTS_RESET_P2A_FIFO	0x04000000
+#define AGCSTS_RESET_A2P_FIFO	0x02000000
+#define AGCSTS_RESET_FIFOS	(AGCSTS_RESET_A2P_FIFO | AGCSTS_RESET_P2A_FIFO)
+
+#define AGCSTS_A2P_TCOUNT	0x00000080
+#define AGCSTS_P2A_TCOUNT	0x00000040
+
+#define AGCSTS_FS_P2A_EMPTY	0x00000020
+#define AGCSTS_FS_P2A_HALF	0x00000010
+#define AGCSTS_FS_P2A_FULL	0x00000008
+
+#define AGCSTS_FS_A2P_EMPTY	0x00000004
+#define AGCSTS_FS_A2P_HALF	0x00000002
+#define AGCSTS_FS_A2P_FULL	0x00000001
+
+/****************************************************************************/
+/* AMCC - Add-on Interrupt Control/Status Register                            */
+/****************************************************************************/
+
+#define AINT_INT_MASK		0x00ff0000
+#define AINT_SEL_MASK		0x0000ffff
+#define  AINT_IS_ENSEL_MASK	0x00001f1f
+
+#define AINT_INT_ASSERTED	0x00800000
+#define AINT_BM_ERROR		0x00200000
+#define AINT_BIST_INT		0x00100000
+
+#define AINT_RT_COMPLETE	0x00080000
+#define AINT_WT_COMPLETE	0x00040000
+
+#define AINT_OUT_MB_INT		0x00020000
+#define AINT_IN_MB_INT		0x00010000
+
+#define AINT_READ_COMPL		0x00008000
+#define AINT_WRITE_COMPL	0x00004000
+
+#define AINT_OMB_ENABLE 	0x00001000
+#define AINT_OMB_SELECT 	0x00000c00
+#define AINT_OMB_BYTE		0x00000300
+
+#define AINT_IMB_ENABLE 	0x00000010
+#define AINT_IMB_SELECT 	0x0000000c
+#define AINT_IMB_BYTE		0x00000003
+
+/* Enable Bus Mastering */
+#define EN_A2P_TRANSFERS	0x00000400
+/* FIFO Flag Reset */
+#define RESET_A2P_FLAGS		0x04000000L
+/* FIFO Relative Priority */
+#define A2P_HI_PRIORITY		0x00000100L
+/* Identify Interrupt Sources */
+#define ANY_S593X_INT		0x00800000L
+#define READ_TC_INT		0x00080000L
+#define WRITE_TC_INT		0x00040000L
+#define IN_MB_INT		0x00020000L
+#define MASTER_ABORT_INT	0x00100000L
+#define TARGET_ABORT_INT	0x00200000L
+#define BUS_MASTER_INT		0x00200000L
+
+/****************************************************************************/
+
+struct pcilst_struct {
+	struct pcilst_struct *next;
+	int used;
+	struct pci_dev *pcidev;
+	unsigned short vendor;
+	unsigned short device;
+	unsigned int master;
+	unsigned char pci_bus;
+	unsigned char pci_slot;
+	unsigned char pci_func;
+	unsigned int io_addr[5];
+	unsigned int irq;
+};
+
+struct pcilst_struct *amcc_devices;	// ptr to root list of all amcc devices
+
+/****************************************************************************/
+
+void v_pci_card_list_init(unsigned short pci_vendor, char display);
+void v_pci_card_list_cleanup(unsigned short pci_vendor);
+struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
+						       unsigned short
+						       device_id);
+int i_find_free_pci_card_by_position(unsigned short vendor_id,
+				     unsigned short device_id,
+				     unsigned short pci_bus,
+				     unsigned short pci_slot,
+				     struct pcilst_struct **card);
+struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
+						    unsigned short device_id,
+						    unsigned short pci_bus,
+						    unsigned short pci_slot);
+
+int i_pci_card_alloc(struct pcilst_struct *amcc);
+int i_pci_card_free(struct pcilst_struct *amcc);
+void v_pci_card_list_display(void);
+int i_pci_card_data(struct pcilst_struct *amcc,
+		    unsigned char *pci_bus, unsigned char *pci_slot,
+		    unsigned char *pci_func, unsigned short *io_addr,
+		    unsigned short *irq, unsigned short *master);
+
+/****************************************************************************/
+
+/* build list of amcc cards in this system */
+void v_pci_card_list_init(unsigned short pci_vendor, char display)
+{
+	struct pci_dev *pcidev;
+	struct pcilst_struct *amcc, *last;
+	int i;
+
+	amcc_devices = NULL;
+	last = NULL;
+
+	pci_for_each_dev(pcidev) {
+		if (pcidev->vendor == pci_vendor) {
+			amcc = kmalloc(sizeof(*amcc), GFP_KERNEL);
+			memset(amcc, 0, sizeof(*amcc));
+
+			amcc->pcidev = pcidev;
+			if (last) {
+				last->next = amcc;
+			} else {
+				amcc_devices = amcc;
+			}
+			last = amcc;
+
+			amcc->vendor = pcidev->vendor;
+			amcc->device = pcidev->device;
+#if 0
+			amcc->master = pcidev->master;	// how get this information under 2.4 kernels?
+#endif
+			amcc->pci_bus = pcidev->bus->number;
+			amcc->pci_slot = PCI_SLOT(pcidev->devfn);
+			amcc->pci_func = PCI_FUNC(pcidev->devfn);
+			for (i = 0; i < 5; i++)
+				amcc->io_addr[i] =
+				    pcidev->resource[i].start & ~3UL;
+			amcc->irq = pcidev->irq;
+		}
+	}
+
+	if (display)
+		v_pci_card_list_display();
+}
+
+/****************************************************************************/
+/* free up list of amcc cards in this system */
+void v_pci_card_list_cleanup(unsigned short pci_vendor)
+{
+	struct pcilst_struct *amcc, *next;
+
+	for (amcc = amcc_devices; amcc; amcc = next) {
+		next = amcc->next;
+		kfree(amcc);
+	}
+
+	amcc_devices = NULL;
+}
+
+/****************************************************************************/
+/* find first unused card with this device_id */
+struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
+						       unsigned short device_id)
+{
+	struct pcilst_struct *amcc, *next;
+
+	for (amcc = amcc_devices; amcc; amcc = next) {
+		next = amcc->next;
+		if ((!amcc->used) && (amcc->device == device_id)
+		    && (amcc->vendor == vendor_id))
+			return amcc;
+
+	}
+
+	return NULL;
+}
+
+/****************************************************************************/
+/* find card on requested position */
+int i_find_free_pci_card_by_position(unsigned short vendor_id,
+				     unsigned short device_id,
+				     unsigned short pci_bus,
+				     unsigned short pci_slot,
+				     struct pcilst_struct **card)
+{
+	struct pcilst_struct *amcc, *next;
+
+	*card = NULL;
+	for (amcc = amcc_devices; amcc; amcc = next) {
+		next = amcc->next;
+		if ((amcc->vendor == vendor_id) && (amcc->device == device_id)
+		    && (amcc->pci_bus == pci_bus)
+		    && (amcc->pci_slot == pci_slot)) {
+			if (!(amcc->used)) {
+				*card = amcc;
+				return 0;	// ok, card is found
+			} else {
+				rt_printk
+				    (" - \nCard on requested position is used b:s %d:%d!\n",
+				     pci_bus, pci_slot);
+				return 2;	// card exist but is used
+			}
+		}
+	}
+
+	return 1;		// no card found
+}
+
+/****************************************************************************/
+/* mark card as used */
+int i_pci_card_alloc(struct pcilst_struct *amcc)
+{
+	if (!amcc)
+		return -1;
+
+	if (amcc->used)
+		return 1;
+	amcc->used = 1;
+	return 0;
+}
+
+/****************************************************************************/
+/* mark card as free */
+int i_pci_card_free(struct pcilst_struct *amcc)
+{
+	if (!amcc)
+		return -1;
+
+	if (!amcc->used)
+		return 1;
+	amcc->used = 0;
+	return 0;
+}
+
+/****************************************************************************/
+/* display list of found cards */
+void v_pci_card_list_display(void)
+{
+	struct pcilst_struct *amcc, *next;
+
+	printk("List of pci cards\n");
+	printk("bus:slot:func vendor device master io_amcc io_daq irq used\n");
+
+	for (amcc = amcc_devices; amcc; amcc = next) {
+		next = amcc->next;
+		printk
+		    ("%2d   %2d   %2d  0x%4x 0x%4x   %3s   0x%4x 0x%4x  %2d  %2d\n",
+		     amcc->pci_bus, amcc->pci_slot, amcc->pci_func,
+		     amcc->vendor, amcc->device, amcc->master ? "yes" : "no",
+		     amcc->io_addr[0], amcc->io_addr[2], amcc->irq, amcc->used);
+
+	}
+}
+
+/****************************************************************************/
+/* return all card information for driver */
+int i_pci_card_data(struct pcilst_struct *amcc,
+		    unsigned char *pci_bus, unsigned char *pci_slot,
+		    unsigned char *pci_func, unsigned short *io_addr,
+		    unsigned short *irq, unsigned short *master)
+{
+	int i;
+
+	if (!amcc)
+		return -1;
+	*pci_bus = amcc->pci_bus;
+	*pci_slot = amcc->pci_slot;
+	*pci_func = amcc->pci_func;
+	for (i = 0; i < 5; i++)
+		io_addr[i] = amcc->io_addr[i];
+	*irq = amcc->irq;
+	*master = amcc->master;
+	return 0;
+}
+
+/****************************************************************************/
+/* select and alloc card */
+struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
+						    unsigned short device_id,
+						    unsigned short pci_bus,
+						    unsigned short pci_slot)
+{
+	struct pcilst_struct *card;
+
+	if ((pci_bus < 1) & (pci_slot < 1)) {	// use autodetection
+		if ((card = ptr_find_free_pci_card_by_device(vendor_id,
+							     device_id)) ==
+		    NULL) {
+			rt_printk(" - Unused card not found in system!\n");
+			return NULL;
+		}
+	} else {
+		switch (i_find_free_pci_card_by_position(vendor_id, device_id,
+							 pci_bus, pci_slot,
+							 &card)) {
+		case 1:
+			rt_printk
+			    (" - Card not found on requested position b:s %d:%d!\n",
+			     pci_bus, pci_slot);
+			return NULL;
+		case 2:
+			rt_printk
+			    (" - Card on requested position is used b:s %d:%d!\n",
+			     pci_bus, pci_slot);
+			return NULL;
+		}
+	}
+
+	if (i_pci_card_alloc(card) != 0) {
+		rt_printk(" - Can't allocate card!\n");
+		return NULL;
+	}
+
+	return card;
+}
+
+#endif
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c
new file mode 100644
index 0000000..3f8929c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c
@@ -0,0 +1,1265 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+
+        ADDI-DATA GmbH
+        Dieselstrasse 3
+        D-77833 Ottersweier
+        Tel: +19(0)7223/9493-0
+        Fax: +49(0)7223/9493-92
+        http://www.addi-data-com
+        info@addi-data.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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+  +-----------------------------------------------------------------------+
+  | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
+  +-----------------------------------------------------------------------+
+  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
+  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
+  +-------------------------------+---------------------------------------+
+  | Project     : APCI-1710       | Compiler   : GCC                      |
+  | Module name : hwdrv_apci1710.c| Version    : 2.96                     |
+  +-------------------------------+---------------------------------------+
+  | Project manager: Eric Stolz   | Date       :  02/12/2002              |
+  +-------------------------------+---------------------------------------+
+  | Description :   Hardware Layer Acces For APCI-1710                    |
+  +-----------------------------------------------------------------------+
+  |                             UPDATES                                   |
+  +----------+-----------+------------------------------------------------+
+  |   Date   |   Author  |          Description of updates                |
+  +----------+-----------+------------------------------------------------+
+  |          |           |                                                |
+  |          |           |                                                |
+  |          |           |                                                |
+  +----------+-----------+------------------------------------------------+
+*/
+#include "hwdrv_APCI1710.h"
+#include "APCI1710_Inp_cpt.c"
+
+#include "APCI1710_Ssi.c"
+#include "APCI1710_Tor.c"
+#include "APCI1710_Ttl.c"
+#include "APCI1710_Dig_io.c"
+#include "APCI1710_82x54.c"
+#include "APCI1710_Chrono.c"
+#include "APCI1710_Pwm.c"
+#include "APCI1710_INCCPT.c"
+
+void i_ADDI_AttachPCI1710(struct comedi_device * dev)
+{
+	struct comedi_subdevice *s;
+	int ret = 0;
+	int n_subdevices = 9;
+
+	//Update-0.7.57->0.7.68dev->n_subdevices = 9;
+	if ((ret = alloc_subdevices(dev, n_subdevices)) < 0)
+		return;
+
+	// Allocate and Initialise Timer Subdevice Structures
+	s = dev->subdevices + 0;
+
+	s->type = COMEDI_SUBD_TIMER;
+	s->subdev_flags = SDF_WRITEABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+	s->n_chan = 3;
+	s->maxdata = 0;
+	s->len_chanlist = 3;
+	s->range_table = &range_digital;
+	s->insn_write = i_APCI1710_InsnWriteEnableDisableTimer;
+	s->insn_read = i_APCI1710_InsnReadAllTimerValue;
+	s->insn_config = i_APCI1710_InsnConfigInitTimer;
+	s->insn_bits = i_APCI1710_InsnBitsTimer;
+
+	// Allocate and Initialise DIO Subdevice Structures
+	s = dev->subdevices + 1;
+
+	s->type = COMEDI_SUBD_DIO;
+	s->subdev_flags =
+		SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+	s->n_chan = 7;
+	s->maxdata = 1;
+	s->len_chanlist = 7;
+	s->range_table = &range_digital;
+	s->insn_config = i_APCI1710_InsnConfigDigitalIO;
+	s->insn_read = i_APCI1710_InsnReadDigitalIOChlValue;
+	s->insn_bits = i_APCI1710_InsnBitsDigitalIOPortOnOff;
+	s->insn_write = i_APCI1710_InsnWriteDigitalIOChlOnOff;
+
+	// Allocate and Initialise Chrono Subdevice Structures
+	s = dev->subdevices + 2;
+
+	s->type = COMEDI_SUBD_CHRONO;
+	s->subdev_flags = SDF_WRITEABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+	s->n_chan = 4;
+	s->maxdata = 0;
+	s->len_chanlist = 4;
+	s->range_table = &range_digital;
+	s->insn_write = i_APCI1710_InsnWriteEnableDisableChrono;
+	s->insn_read = i_APCI1710_InsnReadChrono;
+	s->insn_config = i_APCI1710_InsnConfigInitChrono;
+	s->insn_bits = i_APCI1710_InsnBitsChronoDigitalIO;
+
+	// Allocate and Initialise PWM Subdevice Structures
+	s = dev->subdevices + 3;
+	s->type = COMEDI_SUBD_PWM;
+	s->subdev_flags =
+		SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+	s->n_chan = 3;
+	s->maxdata = 1;
+	s->len_chanlist = 3;
+	s->range_table = &range_digital;
+	s->io_bits = 0;		//all bits input
+	s->insn_config = i_APCI1710_InsnConfigPWM;
+	s->insn_read = i_APCI1710_InsnReadGetPWMStatus;
+	s->insn_write = i_APCI1710_InsnWritePWM;
+	s->insn_bits = i_APCI1710_InsnBitsReadPWMInterrupt;
+
+	// Allocate and Initialise TTLIO Subdevice Structures
+	s = dev->subdevices + 4;
+	s->type = COMEDI_SUBD_TTLIO;
+	s->subdev_flags =
+		SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+	s->n_chan = 8;
+	s->maxdata = 1;
+	s->len_chanlist = 8;
+	s->range_table = &range_apci1710_ttl;	// to pass arguments in range
+	s->insn_config = i_APCI1710_InsnConfigInitTTLIO;
+	s->insn_bits = i_APCI1710_InsnBitsReadTTLIO;
+	s->insn_write = i_APCI1710_InsnWriteSetTTLIOChlOnOff;
+	s->insn_read = i_APCI1710_InsnReadTTLIOAllPortValue;
+
+	// Allocate and Initialise TOR Subdevice Structures
+	s = dev->subdevices + 5;
+	s->type = COMEDI_SUBD_TOR;
+	s->subdev_flags =
+		SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+	s->n_chan = 8;
+	s->maxdata = 1;
+	s->len_chanlist = 8;
+	s->range_table = &range_digital;
+	s->io_bits = 0;		//all bits input
+	s->insn_config = i_APCI1710_InsnConfigInitTorCounter;
+	s->insn_read = i_APCI1710_InsnReadGetTorCounterInitialisation;
+	s->insn_write = i_APCI1710_InsnWriteEnableDisableTorCounter;
+	s->insn_bits = i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue;
+
+	// Allocate and Initialise SSI Subdevice Structures
+	s = dev->subdevices + 6;
+	s->type = COMEDI_SUBD_SSI;
+	s->subdev_flags =
+		SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+	s->n_chan = 4;
+	s->maxdata = 1;
+	s->len_chanlist = 4;
+	s->range_table = &range_apci1710_ssi;
+	s->insn_config = i_APCI1710_InsnConfigInitSSI;
+	s->insn_read = i_APCI1710_InsnReadSSIValue;
+	s->insn_bits = i_APCI1710_InsnBitsSSIDigitalIO;
+
+	// Allocate and Initialise PULSEENCODER Subdevice Structures
+	s = dev->subdevices + 7;
+	s->type = COMEDI_SUBD_PULSEENCODER;
+	s->subdev_flags =
+		SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+	s->n_chan = 4;
+	s->maxdata = 1;
+	s->len_chanlist = 4;
+	s->range_table = &range_digital;
+	s->insn_config = i_APCI1710_InsnConfigInitPulseEncoder;
+	s->insn_write = i_APCI1710_InsnWriteEnableDisablePulseEncoder;
+	s->insn_bits = i_APCI1710_InsnBitsReadWritePulseEncoder;
+	s->insn_read = i_APCI1710_InsnReadInterruptPulseEncoder;
+
+	// Allocate and Initialise INCREMENTALCOUNTER Subdevice Structures
+	s = dev->subdevices + 8;
+	s->type = COMEDI_SUBD_INCREMENTALCOUNTER;
+	s->subdev_flags =
+		SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+	s->n_chan = 500;
+	s->maxdata = 1;
+	s->len_chanlist = 500;
+	s->range_table = &range_apci1710_inccpt;
+	s->insn_config = i_APCI1710_InsnConfigINCCPT;
+	s->insn_write = i_APCI1710_InsnWriteINCCPT;
+	s->insn_read = i_APCI1710_InsnReadINCCPT;
+	s->insn_bits = i_APCI1710_InsnBitsINCCPT;
+}
+
+int i_APCI1710_Reset(struct comedi_device * dev);
+void v_APCI1710_Interrupt(int irq, void *d);
+//for 1710
+
+int i_APCI1710_Reset(struct comedi_device * dev)
+{
+	int ret;
+	DWORD dw_Dummy;
+
+	/*********************************/
+	/* Read all module configuration */
+	/*********************************/
+	ret = inl(devpriv->s_BoardInfos.ui_Address + 60);
+	devpriv->s_BoardInfos.dw_MolduleConfiguration[0] = ret;
+
+	ret = inl(devpriv->s_BoardInfos.ui_Address + 124);
+	devpriv->s_BoardInfos.dw_MolduleConfiguration[1] = ret;
+
+	ret = inl(devpriv->s_BoardInfos.ui_Address + 188);
+	devpriv->s_BoardInfos.dw_MolduleConfiguration[2] = ret;
+
+	ret = inl(devpriv->s_BoardInfos.ui_Address + 252);
+	devpriv->s_BoardInfos.dw_MolduleConfiguration[3] = ret;
+
+	// outl(0x80808082,devpriv->s_BoardInfos.ui_Address+0x60);
+	outl(0x83838383, devpriv->s_BoardInfos.ui_Address + 0x60);
+
+	devpriv->s_BoardInfos.b_BoardVersion = 1;
+
+	// Enable the interrupt for the controler
+	dw_Dummy = inl(devpriv->s_BoardInfos.ui_Address + 0x38);
+	outl(dw_Dummy | 0x2000, devpriv->s_BoardInfos.ui_Address + 0x38);
+
+	return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function's Name   : __void__ v_APCI1710_InterruptFunction                  |
+|				(BYTE b_Interrupt, __CPPARGS)                |
++----------------------------------------------------------------------------+
+| Task              : APCI-1710 interrupt function                           |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE b_Interrupt : Interrupt number                    |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : 0 : OK                                                 |
+|                    -1 : Error                                              |
++----------------------------------------------------------------------------+
+*/
+
+void v_APCI1710_Interrupt(int irq, void *d)
+{
+	struct comedi_device *dev = d;
+	BYTE b_ModuleCpt = 0;
+	BYTE b_InterruptFlag = 0;
+	BYTE b_PWMCpt = 0;
+	BYTE b_TorCounterCpt = 0;
+	BYTE b_PulseIncoderCpt = 0;
+	UINT ui_16BitValue;
+	ULONG ul_InterruptLatchReg = 0;
+	ULONG ul_LatchRegisterValue = 0;
+	ULONG ul_82X54InterruptStatus;
+	ULONG ul_StatusRegister;
+
+	str_ModuleInfo *ps_ModuleInfo;
+
+	printk("APCI1710 Interrupt\n");
+	for (b_ModuleCpt = 0; b_ModuleCpt < 4; b_ModuleCpt++, ps_ModuleInfo++) {
+
+		 /**************************/
+		/* 1199/0225 to 0100/0226 */
+		 /**************************/
+		ps_ModuleInfo = &devpriv->s_ModuleInfo[b_ModuleCpt];
+
+		 /***********************/
+		/* Test if 82X54 timer */
+		 /***********************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModuleCpt] &
+				0xFFFF0000UL) == APCI1710_82X54_TIMER) {
+
+			//printk("TIMER Interrupt Occurred\n");
+			ul_82X54InterruptStatus = inl(devpriv->s_BoardInfos.
+				ui_Address + 12 + (64 * b_ModuleCpt));
+
+		    /***************************/
+			/* Test if interrupt occur */
+		    /***************************/
+
+			if ((ul_82X54InterruptStatus & ps_ModuleInfo->
+					s_82X54ModuleInfo.
+					b_InterruptMask) != 0) {
+				devpriv->
+					s_InterruptParameters.
+					s_FIFOInterruptParameters[devpriv->
+					s_InterruptParameters.
+					ui_Write].
+					ul_OldInterruptMask =
+					(ul_82X54InterruptStatus &
+					ps_ModuleInfo->s_82X54ModuleInfo.
+					b_InterruptMask) << 4;
+
+				devpriv->
+					s_InterruptParameters.
+					s_FIFOInterruptParameters[devpriv->
+					s_InterruptParameters.
+					ui_Write].
+					b_OldModuleMask = 1 << b_ModuleCpt;
+
+				devpriv->
+					s_InterruptParameters.
+					s_FIFOInterruptParameters[devpriv->
+					s_InterruptParameters.
+					ui_Write].ul_OldCounterLatchValue = 0;
+
+				devpriv->
+					s_InterruptParameters.
+					ul_InterruptOccur++;
+
+		       /****************************/
+				/* Increment the write FIFO */
+		       /****************************/
+
+				devpriv->
+					s_InterruptParameters.
+					ui_Write = (devpriv->
+					s_InterruptParameters.
+					ui_Write + 1) % APCI1710_SAVE_INTERRUPT;
+
+				b_InterruptFlag = 1;
+
+			     /**********************/
+				/* Call user function */
+			     /**********************/
+				//Send a signal to from kernel to user space
+				send_sig(SIGIO, devpriv->tsk_Current, 0);
+
+			}	// if ((ul_82X54InterruptStatus & 0x7) != 0)
+		}		// 82X54 timer
+
+		 /***************************/
+		/* Test if increm. counter */
+		 /***************************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModuleCpt] &
+				0xFFFF0000UL) == APCI1710_INCREMENTAL_COUNTER) {
+
+			ul_InterruptLatchReg = inl(devpriv->s_BoardInfos.
+				ui_Address + (64 * b_ModuleCpt));
+
+		    /*********************/
+			/* Test if interrupt */
+		    /*********************/
+
+			if ((ul_InterruptLatchReg & 0x22) && (ps_ModuleInfo->
+					s_SiemensCounterInfo.
+					s_ModeRegister.
+					s_ByteModeRegister.
+					b_ModeRegister2 & 0x80)) {
+		       /************************************/
+				/* Test if strobe latch I interrupt */
+		       /************************************/
+
+				if (ul_InterruptLatchReg & 2) {
+					ul_LatchRegisterValue =
+						inl(devpriv->s_BoardInfos.
+						ui_Address + 4 +
+						(64 * b_ModuleCpt));
+
+					devpriv->
+						s_InterruptParameters.
+						s_FIFOInterruptParameters
+						[devpriv->s_InterruptParameters.
+						ui_Write].ul_OldInterruptMask =
+						1UL;
+
+					devpriv->
+						s_InterruptParameters.
+						s_FIFOInterruptParameters
+						[devpriv->s_InterruptParameters.
+						ui_Write].b_OldModuleMask =
+						1 << b_ModuleCpt;
+
+					devpriv->
+						s_InterruptParameters.
+						s_FIFOInterruptParameters
+						[devpriv->s_InterruptParameters.
+						ui_Write].
+						ul_OldCounterLatchValue =
+						ul_LatchRegisterValue;
+
+					devpriv->
+						s_InterruptParameters.
+						ul_InterruptOccur++;
+
+			  /****************************/
+					/* 0899/0224 to 1199/0225   */
+			  /****************************/
+					/* Increment the write FIFO */
+		      /****************************/
+
+					devpriv->
+						s_InterruptParameters.
+						ui_Write = (devpriv->
+						s_InterruptParameters.
+						ui_Write +
+						1) % APCI1710_SAVE_INTERRUPT;
+
+					b_InterruptFlag = 1;
+
+				/**********************/
+					/* Call user function */
+				/**********************/
+					//Send a signal to from kernel to user space
+					send_sig(SIGIO, devpriv->tsk_Current,
+						0);
+
+				}
+
+		       /*************************************/
+				/* Test if strobe latch II interrupt */
+		       /*************************************/
+
+				if (ul_InterruptLatchReg & 0x20) {
+
+					ul_LatchRegisterValue =
+						inl(devpriv->s_BoardInfos.
+						ui_Address + 8 +
+						(64 * b_ModuleCpt));
+
+					devpriv->
+						s_InterruptParameters.
+						s_FIFOInterruptParameters
+						[devpriv->s_InterruptParameters.
+						ui_Write].ul_OldInterruptMask =
+						2UL;
+
+					devpriv->
+						s_InterruptParameters.
+						s_FIFOInterruptParameters
+						[devpriv->s_InterruptParameters.
+						ui_Write].b_OldModuleMask =
+						1 << b_ModuleCpt;
+
+					devpriv->
+						s_InterruptParameters.
+						s_FIFOInterruptParameters
+						[devpriv->s_InterruptParameters.
+						ui_Write].
+						ul_OldCounterLatchValue =
+						ul_LatchRegisterValue;
+
+					devpriv->
+						s_InterruptParameters.
+						ul_InterruptOccur++;
+
+			  /****************************/
+					/* 0899/0224 to 1199/0225   */
+			  /****************************/
+					/* Increment the write FIFO */
+			  /****************************/
+
+					devpriv->
+						s_InterruptParameters.
+						ui_Write = (devpriv->
+						s_InterruptParameters.
+						ui_Write +
+						1) % APCI1710_SAVE_INTERRUPT;
+
+					b_InterruptFlag = 1;
+
+			    /**********************/
+					/* Call user function */
+				/**********************/
+					//Send a signal to from kernel to user space
+					send_sig(SIGIO, devpriv->tsk_Current,
+						0);
+
+				}
+			}
+
+			ul_InterruptLatchReg = inl(devpriv->s_BoardInfos.
+				ui_Address + 24 + (64 * b_ModuleCpt));
+
+		    /***************************/
+			/* Test if index interrupt */
+		    /***************************/
+
+			if (ul_InterruptLatchReg & 0x8) {
+				ps_ModuleInfo->
+					s_SiemensCounterInfo.
+					s_InitFlag.b_IndexInterruptOccur = 1;
+
+				if (ps_ModuleInfo->
+					s_SiemensCounterInfo.
+					s_ModeRegister.
+					s_ByteModeRegister.
+					b_ModeRegister2 &
+					APCI1710_INDEX_AUTO_MODE) {
+
+					outl(ps_ModuleInfo->
+						s_SiemensCounterInfo.
+						s_ModeRegister.
+						dw_ModeRegister1_2_3_4,
+						devpriv->s_BoardInfos.
+						ui_Address + 20 +
+						(64 * b_ModuleCpt));
+				}
+
+		       /*****************************/
+				/* Test if interrupt enabled */
+		       /*****************************/
+
+				if ((ps_ModuleInfo->
+						s_SiemensCounterInfo.
+						s_ModeRegister.
+						s_ByteModeRegister.
+						b_ModeRegister3 &
+						APCI1710_ENABLE_INDEX_INT) ==
+					APCI1710_ENABLE_INDEX_INT) {
+					devpriv->s_InterruptParameters.
+						s_FIFOInterruptParameters
+						[devpriv->s_InterruptParameters.
+						ui_Write].ul_OldInterruptMask =
+						4UL;
+
+					devpriv->
+						s_InterruptParameters.
+						s_FIFOInterruptParameters
+						[devpriv->s_InterruptParameters.
+						ui_Write].b_OldModuleMask =
+						1 << b_ModuleCpt;
+
+					devpriv->
+						s_InterruptParameters.
+						s_FIFOInterruptParameters
+						[devpriv->s_InterruptParameters.
+						ui_Write].
+						ul_OldCounterLatchValue =
+						ul_LatchRegisterValue;
+
+					devpriv->
+						s_InterruptParameters.
+						ul_InterruptOccur++;
+
+			  /****************************/
+					/* 0899/0224 to 1199/0225   */
+			  /****************************/
+					/* Increment the write FIFO */
+			  /****************************/
+
+					devpriv->
+						s_InterruptParameters.
+						ui_Write = (devpriv->
+						s_InterruptParameters.
+						ui_Write +
+						1) % APCI1710_SAVE_INTERRUPT;
+
+					b_InterruptFlag = 1;
+
+				/**********************/
+					/* Call user function */
+				/**********************/
+					//Send a signal to from kernel to user space
+					send_sig(SIGIO, devpriv->tsk_Current,
+						0);
+
+				}
+			}
+
+		    /*****************************/
+			/* Test if compare interrupt */
+		    /*****************************/
+
+			if (ul_InterruptLatchReg & 0x10) {
+		       /*****************************/
+				/* Test if interrupt enabled */
+		       /*****************************/
+
+				if ((ps_ModuleInfo->
+						s_SiemensCounterInfo.
+						s_ModeRegister.
+						s_ByteModeRegister.
+						b_ModeRegister3 &
+						APCI1710_ENABLE_COMPARE_INT) ==
+					APCI1710_ENABLE_COMPARE_INT) {
+					devpriv->s_InterruptParameters.
+						s_FIFOInterruptParameters
+						[devpriv->s_InterruptParameters.
+						ui_Write].ul_OldInterruptMask =
+						8UL;
+
+					devpriv->
+						s_InterruptParameters.
+						s_FIFOInterruptParameters
+						[devpriv->s_InterruptParameters.
+						ui_Write].b_OldModuleMask =
+						1 << b_ModuleCpt;
+
+					devpriv->
+						s_InterruptParameters.
+						s_FIFOInterruptParameters
+						[devpriv->s_InterruptParameters.
+						ui_Write].
+						ul_OldCounterLatchValue =
+						ul_LatchRegisterValue;
+
+					devpriv->
+						s_InterruptParameters.
+						ul_InterruptOccur++;
+
+			  /****************************/
+					/* 0899/0224 to 1199/0225   */
+			  /****************************/
+					/* Increment the write FIFO */
+		      /****************************/
+
+					devpriv->
+						s_InterruptParameters.
+						ui_Write = (devpriv->
+						s_InterruptParameters.
+						ui_Write +
+						1) % APCI1710_SAVE_INTERRUPT;
+
+					b_InterruptFlag = 1;
+
+				/**********************/
+					/* Call user function */
+				/**********************/
+					//Send a signal to from kernel to user space
+					send_sig(SIGIO, devpriv->tsk_Current,
+						0);
+
+				}
+			}
+
+		    /*******************************************/
+			/* Test if frequency measurement interrupt */
+		    /*******************************************/
+
+			if (ul_InterruptLatchReg & 0x20) {
+		       /*******************/
+				/* Read the status */
+		       /*******************/
+
+				ul_StatusRegister = inl(devpriv->s_BoardInfos.
+					ui_Address + 32 + (64 * b_ModuleCpt));
+
+		       /******************/
+				/* Read the value */
+		       /******************/
+
+				ul_LatchRegisterValue =
+					inl(devpriv->s_BoardInfos.ui_Address +
+					28 + (64 * b_ModuleCpt));
+
+				switch ((ul_StatusRegister >> 1) & 3) {
+				case 0:
+			       /*************************/
+					/* Test the counter mode */
+			       /*************************/
+
+					if ((devpriv->s_ModuleInfo[b_ModuleCpt].
+							s_SiemensCounterInfo.
+							s_ModeRegister.
+							s_ByteModeRegister.
+							b_ModeRegister1 &
+							APCI1710_16BIT_COUNTER)
+						== APCI1710_16BIT_COUNTER) {
+				  /****************************************/
+						/* Test if 16-bit counter 1 pulse occur */
+				  /****************************************/
+
+						if ((ul_LatchRegisterValue &
+								0xFFFFU) != 0) {
+							ui_16BitValue =
+								(UINT)
+								ul_LatchRegisterValue
+								& 0xFFFFU;
+							ul_LatchRegisterValue =
+								(ul_LatchRegisterValue
+								& 0xFFFF0000UL)
+								| (0xFFFFU -
+								ui_16BitValue);
+						}
+
+				  /****************************************/
+						/* Test if 16-bit counter 2 pulse occur */
+				  /****************************************/
+
+						if ((ul_LatchRegisterValue &
+								0xFFFF0000UL) !=
+							0) {
+							ui_16BitValue =
+								(UINT) (
+								(ul_LatchRegisterValue
+									>> 16) &
+								0xFFFFU);
+							ul_LatchRegisterValue =
+								(ul_LatchRegisterValue
+								& 0xFFFFUL) |
+								((0xFFFFU -
+									ui_16BitValue)
+								<< 16);
+						}
+					} else {
+						if (ul_LatchRegisterValue != 0) {
+							ul_LatchRegisterValue =
+								0xFFFFFFFFUL -
+								ul_LatchRegisterValue;
+						}
+					}
+					break;
+
+				case 1:
+			       /****************************************/
+					/* Test if 16-bit counter 2 pulse occur */
+			       /****************************************/
+
+					if ((ul_LatchRegisterValue &
+							0xFFFF0000UL) != 0) {
+						ui_16BitValue =
+							(UINT) (
+							(ul_LatchRegisterValue
+								>> 16) &
+							0xFFFFU);
+						ul_LatchRegisterValue =
+							(ul_LatchRegisterValue &
+							0xFFFFUL) | ((0xFFFFU -
+								ui_16BitValue)
+							<< 16);
+					}
+					break;
+
+				case 2:
+			       /****************************************/
+					/* Test if 16-bit counter 1 pulse occur */
+			       /****************************************/
+
+					if ((ul_LatchRegisterValue & 0xFFFFU) !=
+						0) {
+						ui_16BitValue =
+							(UINT)
+							ul_LatchRegisterValue &
+							0xFFFFU;
+						ul_LatchRegisterValue =
+							(ul_LatchRegisterValue &
+							0xFFFF0000UL) | (0xFFFFU
+							- ui_16BitValue);
+					}
+					break;
+				}
+
+				devpriv->
+					s_InterruptParameters.
+					s_FIFOInterruptParameters[devpriv->
+					s_InterruptParameters.
+					ui_Write].
+					ul_OldInterruptMask = 0x10000UL;
+
+				devpriv->
+					s_InterruptParameters.
+					s_FIFOInterruptParameters[devpriv->
+					s_InterruptParameters.
+					ui_Write].
+					b_OldModuleMask = 1 << b_ModuleCpt;
+
+				devpriv->
+					s_InterruptParameters.
+					s_FIFOInterruptParameters[devpriv->
+					s_InterruptParameters.
+					ui_Write].
+					ul_OldCounterLatchValue =
+					ul_LatchRegisterValue;
+
+				devpriv->
+					s_InterruptParameters.
+					ul_InterruptOccur++;
+
+		       /****************************/
+				/* 0899/0224 to 1199/0225   */
+		       /****************************/
+				/* Increment the write FIFO */
+		       /****************************/
+
+				devpriv->
+					s_InterruptParameters.
+					ui_Write = (devpriv->
+					s_InterruptParameters.
+					ui_Write + 1) % APCI1710_SAVE_INTERRUPT;
+
+				b_InterruptFlag = 1;
+
+			     /**********************/
+				/* Call user function */
+			     /**********************/
+				//Send a signal to from kernel to user space
+				send_sig(SIGIO, devpriv->tsk_Current, 0);
+
+			}
+		}		// Incremental counter
+
+		 /***************/
+		/* Test if CDA */
+		 /***************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModuleCpt] &
+				0xFFFF0000UL) == APCI1710_CDA) {
+		    /******************************************/
+			/* Test if CDA enable and functionality 0 */
+		    /******************************************/
+
+			if ((devpriv->s_ModuleInfo[b_ModuleCpt].
+					s_CDAModuleInfo.
+					b_CDAEnable == APCI1710_ENABLE)
+				&& (devpriv->s_ModuleInfo[b_ModuleCpt].
+					s_CDAModuleInfo.b_FctSelection == 0)) {
+		       /****************************/
+				/* Get the interrupt status */
+		       /****************************/
+
+				ul_StatusRegister = inl(devpriv->s_BoardInfos.
+					ui_Address + 16 + (64 * b_ModuleCpt));
+		       /***************************/
+				/* Test if interrupt occur */
+		       /***************************/
+
+				if (ul_StatusRegister & 1) {
+					devpriv->
+						s_InterruptParameters.
+						s_FIFOInterruptParameters
+						[devpriv->s_InterruptParameters.
+						ui_Write].ul_OldInterruptMask =
+						0x80000UL;
+
+					devpriv->
+						s_InterruptParameters.
+						s_FIFOInterruptParameters
+						[devpriv->s_InterruptParameters.
+						ui_Write].b_OldModuleMask =
+						1 << b_ModuleCpt;
+
+					devpriv->
+						s_InterruptParameters.
+						s_FIFOInterruptParameters
+						[devpriv->s_InterruptParameters.
+						ui_Write].
+						ul_OldCounterLatchValue = 0;
+
+					devpriv->
+						s_InterruptParameters.
+						ul_InterruptOccur++;
+
+			  /****************************/
+					/* Increment the write FIFO */
+			  /****************************/
+
+					devpriv->
+						s_InterruptParameters.
+						ui_Write = (devpriv->
+						s_InterruptParameters.
+						ui_Write +
+						1) % APCI1710_SAVE_INTERRUPT;
+
+					b_InterruptFlag = 1;
+
+				/**********************/
+					/* Call user function */
+				/**********************/
+
+					//Send a signal to from kernel to user space
+					send_sig(SIGIO, devpriv->tsk_Current,
+						0);
+
+				}	// if (ul_StatusRegister & 1)
+
+			}
+		}		// CDA
+
+		 /***********************/
+		/* Test if PWM counter */
+		 /***********************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModuleCpt] &
+				0xFFFF0000UL) == APCI1710_PWM) {
+			for (b_PWMCpt = 0; b_PWMCpt < 2; b_PWMCpt++) {
+		       /*************************************/
+				/* Test if PWM interrupt initialised */
+		       /*************************************/
+
+				if (devpriv->
+					s_ModuleInfo[b_ModuleCpt].
+					s_PWMModuleInfo.
+					s_PWMInfo[b_PWMCpt].
+					b_InterruptEnable == APCI1710_ENABLE) {
+			  /*****************************/
+					/* Read the interrupt status */
+			  /*****************************/
+
+					ul_StatusRegister =
+						inl(devpriv->s_BoardInfos.
+						ui_Address + 16 +
+						(20 * b_PWMCpt) +
+						(64 * b_ModuleCpt));
+
+			  /***************************/
+					/* Test if interrupt occur */
+			  /***************************/
+
+					if (ul_StatusRegister & 0x1) {
+						devpriv->
+							s_InterruptParameters.
+							s_FIFOInterruptParameters
+							[devpriv->
+							s_InterruptParameters.
+							ui_Write].
+							ul_OldInterruptMask =
+							0x4000UL << b_PWMCpt;
+
+						devpriv->
+							s_InterruptParameters.
+							s_FIFOInterruptParameters
+							[devpriv->
+							s_InterruptParameters.
+							ui_Write].
+							b_OldModuleMask =
+							1 << b_ModuleCpt;
+
+						devpriv->
+							s_InterruptParameters.
+							ul_InterruptOccur++;
+
+			     /****************************/
+						/* Increment the write FIFO */
+			     /****************************/
+
+						devpriv->
+							s_InterruptParameters.
+							ui_Write = (devpriv->
+							s_InterruptParameters.
+							ui_Write +
+							1) %
+							APCI1710_SAVE_INTERRUPT;
+
+						b_InterruptFlag = 1;
+
+				   /**********************/
+						/* Call user function */
+				   /**********************/
+						//Send a signal to from kernel to user space
+						send_sig(SIGIO,
+							devpriv->tsk_Current,
+							0);
+
+					}	// if (ul_StatusRegister & 0x1)
+				}	// if (APCI1710_ENABLE)
+			}	// for (b_PWMCpt == 0; b_PWMCpt < 0; b_PWMCpt ++)
+		}		// PWM counter
+
+		 /***********************/
+		/* Test if tor counter */
+		 /***********************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModuleCpt] &
+				0xFFFF0000UL) == APCI1710_TOR_COUNTER) {
+			for (b_TorCounterCpt = 0; b_TorCounterCpt < 2;
+				b_TorCounterCpt++) {
+		       /*************************************/
+				/* Test if tor interrupt initialised */
+		       /*************************************/
+
+				if (devpriv->
+					s_ModuleInfo[b_ModuleCpt].
+					s_TorCounterModuleInfo.
+					s_TorCounterInfo[b_TorCounterCpt].
+					b_InterruptEnable == APCI1710_ENABLE) {
+			  /*****************************/
+					/* Read the interrupt status */
+			  /*****************************/
+
+					ul_StatusRegister =
+						inl(devpriv->s_BoardInfos.
+						ui_Address + 12 +
+						(16 * b_TorCounterCpt) +
+						(64 * b_ModuleCpt));
+
+			  /***************************/
+					/* Test if interrupt occur */
+			  /***************************/
+
+					if (ul_StatusRegister & 0x1) {
+			     /******************************/
+						/* Read the tor counter value */
+			     /******************************/
+
+						ul_LatchRegisterValue =
+							inl(devpriv->
+							s_BoardInfos.
+							ui_Address + 0 +
+							(16 * b_TorCounterCpt) +
+							(64 * b_ModuleCpt));
+
+						devpriv->
+							s_InterruptParameters.
+							s_FIFOInterruptParameters
+							[devpriv->
+							s_InterruptParameters.
+							ui_Write].
+							ul_OldInterruptMask =
+							0x1000UL <<
+							b_TorCounterCpt;
+
+						devpriv->
+							s_InterruptParameters.
+							s_FIFOInterruptParameters
+							[devpriv->
+							s_InterruptParameters.
+							ui_Write].
+							b_OldModuleMask =
+							1 << b_ModuleCpt;
+
+						devpriv->
+							s_InterruptParameters.
+							s_FIFOInterruptParameters
+							[devpriv->
+							s_InterruptParameters.
+							ui_Write].
+							ul_OldCounterLatchValue
+							= ul_LatchRegisterValue;
+
+						devpriv->
+							s_InterruptParameters.
+							ul_InterruptOccur++;
+
+			     /****************************/
+						/* Increment the write FIFO */
+			     /****************************/
+
+						devpriv->
+							s_InterruptParameters.
+							ui_Write = (devpriv->
+							s_InterruptParameters.
+							ui_Write +
+							1) %
+							APCI1710_SAVE_INTERRUPT;
+
+						b_InterruptFlag = 1;
+
+				   /**********************/
+						/* Call user function */
+				   /**********************/
+
+						//Send a signal to from kernel to user space
+						send_sig(SIGIO,
+							devpriv->tsk_Current,
+							0);
+					}	// if (ul_StatusRegister & 0x1)
+				}	// if (APCI1710_ENABLE)
+			}	// for (b_TorCounterCpt == 0; b_TorCounterCpt < 0; b_TorCounterCpt ++)
+		}		// Tor counter
+
+		 /***********************/
+		/* Test if chronometer */
+		 /***********************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModuleCpt] &
+				0xFFFF0000UL) == APCI1710_CHRONOMETER) {
+
+			//printk("APCI1710 Chrono Interrupt\n");
+		    /*****************************/
+			/* Read the interrupt status */
+		    /*****************************/
+
+			ul_InterruptLatchReg = inl(devpriv->s_BoardInfos.
+				ui_Address + 12 + (64 * b_ModuleCpt));
+
+		    /***************************/
+			/* Test if interrupt occur */
+		    /***************************/
+
+			if ((ul_InterruptLatchReg & 0x8) == 0x8) {
+		       /****************************/
+				/* Clear the interrupt flag */
+		       /****************************/
+
+				outl(0, devpriv->s_BoardInfos.
+					ui_Address + 32 + (64 * b_ModuleCpt));
+
+		       /***************************/
+				/* Test if continuous mode */
+		       /***************************/
+
+				if (ps_ModuleInfo->
+					s_ChronoModuleInfo.
+					b_CycleMode == APCI1710_ENABLE) {
+			  /********************/
+					/* Clear the status */
+			  /********************/
+
+					outl(0, devpriv->s_BoardInfos.
+						ui_Address + 36 +
+						(64 * b_ModuleCpt));
+				}
+
+		       /*************************/
+				/* Read the timing value */
+		       /*************************/
+
+				ul_LatchRegisterValue =
+					inl(devpriv->s_BoardInfos.ui_Address +
+					4 + (64 * b_ModuleCpt));
+
+		       /*****************************/
+				/* Test if interrupt enabled */
+		       /*****************************/
+
+				if (ps_ModuleInfo->
+					s_ChronoModuleInfo.b_InterruptMask) {
+					devpriv->
+						s_InterruptParameters.
+						s_FIFOInterruptParameters
+						[devpriv->s_InterruptParameters.
+						ui_Write].ul_OldInterruptMask =
+						0x80;
+
+					devpriv->
+						s_InterruptParameters.
+						s_FIFOInterruptParameters
+						[devpriv->s_InterruptParameters.
+						ui_Write].b_OldModuleMask =
+						1 << b_ModuleCpt;
+
+					devpriv->
+						s_InterruptParameters.
+						s_FIFOInterruptParameters
+						[devpriv->s_InterruptParameters.
+						ui_Write].
+						ul_OldCounterLatchValue =
+						ul_LatchRegisterValue;
+
+					devpriv->
+						s_InterruptParameters.
+						ul_InterruptOccur++;
+
+			  /****************************/
+					/* Increment the write FIFO */
+		      /****************************/
+
+					devpriv->
+						s_InterruptParameters.
+						ui_Write = (devpriv->
+						s_InterruptParameters.
+						ui_Write +
+						1) % APCI1710_SAVE_INTERRUPT;
+
+					b_InterruptFlag = 1;
+
+				/**********************/
+					/* Call user function */
+				/**********************/
+					//Send a signal to from kernel to user space
+					send_sig(SIGIO, devpriv->tsk_Current,
+						0);
+
+				}
+			}
+		}		// Chronometer
+
+		 /*************************/
+		/* Test if pulse encoder */
+		 /*************************/
+
+		if ((devpriv->s_BoardInfos.
+				dw_MolduleConfiguration[b_ModuleCpt] &
+				0xFFFF0000UL) == APCI1710_PULSE_ENCODER) {
+		    /****************************/
+			/* Read the status register */
+		    /****************************/
+
+			ul_StatusRegister = inl(devpriv->s_BoardInfos.
+				ui_Address + 20 + (64 * b_ModuleCpt));
+
+			if (ul_StatusRegister & 0xF) {
+				for (b_PulseIncoderCpt = 0;
+					b_PulseIncoderCpt < 4;
+					b_PulseIncoderCpt++) {
+			  /*************************************/
+					/* Test if pulse encoder initialised */
+			  /*************************************/
+
+					if ((ps_ModuleInfo->
+							s_PulseEncoderModuleInfo.
+							s_PulseEncoderInfo
+							[b_PulseIncoderCpt].
+							b_PulseEncoderInit == 1)
+						&& (((ps_ModuleInfo->s_PulseEncoderModuleInfo.dw_SetRegister >> b_PulseIncoderCpt) & 1) == 1) && (((ul_StatusRegister >> (b_PulseIncoderCpt)) & 1) == 1)) {
+						devpriv->s_InterruptParameters.
+							s_FIFOInterruptParameters
+							[devpriv->
+							s_InterruptParameters.
+							ui_Write].
+							ul_OldInterruptMask =
+							0x100UL <<
+							b_PulseIncoderCpt;
+
+						devpriv->
+							s_InterruptParameters.
+							s_FIFOInterruptParameters
+							[devpriv->
+							s_InterruptParameters.
+							ui_Write].
+							b_OldModuleMask =
+							1 << b_ModuleCpt;
+
+						devpriv->
+							s_InterruptParameters.
+							s_FIFOInterruptParameters
+							[devpriv->
+							s_InterruptParameters.
+							ui_Write].
+							ul_OldCounterLatchValue
+							= ul_LatchRegisterValue;
+
+						devpriv->
+							s_InterruptParameters.
+							ul_InterruptOccur++;
+
+			     /****************************/
+						/* 0899/0224 to 1199/0225   */
+			     /****************************/
+						/* Increment the write FIFO */
+			     /****************************/
+
+						devpriv->
+							s_InterruptParameters.
+							ui_Write = (devpriv->
+							s_InterruptParameters.
+							ui_Write +
+							1) %
+							APCI1710_SAVE_INTERRUPT;
+
+						b_InterruptFlag = 1;
+
+				   /**********************/
+						/* Call user function */
+				   /**********************/
+						//Send a signal to from kernel to user space
+						send_sig(SIGIO,
+							devpriv->tsk_Current,
+							0);
+
+					}
+				}
+			}
+		}		//pulse encoder
+
+	}
+	return;
+
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h
new file mode 100644
index 0000000..998cbba
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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.
+ */
+
+#define COMEDI_SUBD_TTLIO		11	/* Digital Input Output But TTL */
+#define COMEDI_SUBD_PWM			12	/* Pulse width Measurement */
+#define COMEDI_SUBD_SSI			13	/* Synchronous serial interface */
+#define COMEDI_SUBD_TOR			14	/* Tor counter */
+#define COMEDI_SUBD_CHRONO		15	/* Chrono meter */
+#define COMEDI_SUBD_PULSEENCODER	16	/* Pulse Encoder INP CPT */
+#define COMEDI_SUBD_INCREMENTALCOUNTER	17	/* Incremental Counter */
+
+#define APCI1710_BOARD_NAME		"apci1710"
+#define APCI1710_BOARD_VENDOR_ID	0x10E8
+#define APCI1710_BOARD_DEVICE_ID	0x818F
+#define APCI1710_ADDRESS_RANGE		256
+#define APCI1710_CONFIG_ADDRESS_RANGE	8
+#define APCI1710_INCREMENTAL_COUNTER	0x53430000UL
+#define APCI1710_SSI_COUNTER		0x53490000UL
+#define APCI1710_TTL_IO			0x544C0000UL
+#define APCI1710_DIGITAL_IO		0x44490000UL
+#define APCI1710_82X54_TIMER		0x49430000UL
+#define APCI1710_CHRONOMETER		0x43480000UL
+#define APCI1710_PULSE_ENCODER		0x495A0000UL
+#define APCI1710_TOR_COUNTER		0x544F0000UL
+#define APCI1710_PWM			0x50570000UL
+#define APCI1710_ETM			0x45540000UL
+#define APCI1710_CDA			0x43440000UL
+#define APCI1710_DISABLE		0
+#define APCI1710_ENABLE			1
+#define APCI1710_SYNCHRONOUS_MODE	1
+#define APCI1710_ASYNCHRONOUS_MODE	0
+
+//MODULE INFO STRUCTURE
+
+static const struct comedi_lrange range_apci1710_ttl = { 4, {
+						      BIP_RANGE(10),
+						      BIP_RANGE(5),
+						      BIP_RANGE(2),
+						      BIP_RANGE(1)
+						      }
+};
+
+static const struct comedi_lrange range_apci1710_ssi = { 4, {
+						      BIP_RANGE(10),
+						      BIP_RANGE(5),
+						      BIP_RANGE(2),
+						      BIP_RANGE(1)
+						      }
+};
+
+static const struct comedi_lrange range_apci1710_inccpt = { 4, {
+							 BIP_RANGE(10),
+							 BIP_RANGE(5),
+							 BIP_RANGE(2),
+							 BIP_RANGE(1)
+							 }
+};
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c
new file mode 100644
index 0000000..e452792
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c
@@ -0,0 +1,600 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+
+        ADDI-DATA GmbH
+        Dieselstrasse 3
+        D-77833 Ottersweier
+        Tel: +19(0)7223/9493-0
+        Fax: +49(0)7223/9493-92
+        http://www.addi-data-com
+        info@addi-data.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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+  +-----------------------------------------------------------------------+
+  | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
+  +-----------------------------------------------------------------------+
+  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
+  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
+  +-------------------------------+---------------------------------------+
+  | Project     : APCI-035        | Compiler   : GCC                      |
+  | Module name : hwdrv_apci035.c | Version    : 2.96                     |
+  +-------------------------------+---------------------------------------+
+  | Project manager: Eric Stolz   | Date       :  02/12/2002              |
+  +-------------------------------+---------------------------------------+
+  | Description :   Hardware Layer Acces For APCI-035                     |
+  +-----------------------------------------------------------------------+
+  |                             UPDATES                                   |
+  +----------+-----------+------------------------------------------------+
+  |   Date   |   Author  |          Description of updates                |
+  +----------+-----------+------------------------------------------------+
+  |          |           |                                                |
+  |          |           |                                                |
+  |          |           |                                                |
+  +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+|                               Included files                               |
++----------------------------------------------------------------------------+
+*/
+#include "hwdrv_apci035.h"
+INT i_WatchdogNbr = 0;
+INT i_Temp = 0;
+INT i_Flag = 1;
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI035_ConfigTimerWatchdog                      |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Configures The Timer , Counter or Watchdog             |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev : Driver handle                     |
+|                     UINT *data         : Data Pointer contains             |
+|                                          configuration parameters as below |
+|                                                                            |
+|					  data[0]            : 0 Configure As Timer      |
+|										   1 Configure As Watchdog   |
+                              data[1]            : Watchdog number
+|					  data[2]            : Time base Unit            |
+|					  data[3]			 : Reload Value			     |
+                              data[4]            : External Trigger          |
+                                                   1:Enable
+                                                   0:Disable
+                              data[5]            :External Trigger Level
+                                                  00 Trigger Disabled
+                                                  01 Trigger Enabled (Low level)
+                                                  10 Trigger Enabled (High Level)
+                                                  11 Trigger Enabled (High/Low level)
+                              data[6]            : External Gate            |
+                                                   1:Enable
+                                                   0:Disable
+                              data[7]            : External Gate level
+                                                  00 Gate Disabled
+                                                  01 Gate Enabled (Low level)
+                                                  10 Gate Enabled (High Level)
+                              data[8]            :Warning Relay
+                                                  1: ENABLE
+                                                  0: DISABLE
+                              data[9]            :Warning Delay available
+                              data[10]           :Warning Relay Time unit
+                              data[11]           :Warning Relay Time Reload value
+                              data[12]           :Reset Relay
+                                                  1 : ENABLE
+                                                  0 : DISABLE
+                              data[13]           :Interrupt
+                                                  1 : ENABLE
+                                                  0 : DISABLE
+
+|
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI035_ConfigTimerWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_Status = 0;
+	UINT ui_Command = 0;
+	UINT ui_Mode = 0;
+	i_Temp = 0;
+	devpriv->tsk_Current = current;
+	devpriv->b_TimerSelectMode = data[0];
+	i_WatchdogNbr = data[1];
+	if (data[0] == 0) {
+		ui_Mode = 2;
+	} else {
+		ui_Mode = 0;
+	}
+//ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
+	ui_Command = 0;
+//ui_Command = ui_Command & 0xFFFFF9FEUL;
+	outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+	ui_Command = 0;
+	ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+/************************/
+/* Set the reload value */
+/************************/
+	outl(data[3], devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 4);
+/*********************/
+/* Set the time unit */
+/*********************/
+	outl(data[2], devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 8);
+	if (data[0] == ADDIDATA_TIMER) {
+
+		 /******************************/
+		/* Set the mode :             */
+		/* - Disable the hardware     */
+		/* - Disable the counter mode */
+		/* - Disable the warning      */
+		/* - Disable the reset        */
+		/* - Enable the timer mode    */
+		/* - Set the timer mode       */
+		 /******************************/
+
+		ui_Command =
+			(ui_Command & 0xFFF719E2UL) | ui_Mode << 13UL | 0x10UL;
+
+	}			//if (data[0] == ADDIDATA_TIMER)
+	else {
+		if (data[0] == ADDIDATA_WATCHDOG) {
+
+		 /******************************/
+			/* Set the mode :             */
+			/* - Disable the hardware     */
+			/* - Disable the counter mode */
+			/* - Disable the warning      */
+			/* - Disable the reset        */
+			/* - Disable the timer mode   */
+		 /******************************/
+
+			ui_Command = ui_Command & 0xFFF819E2UL;
+
+		} else {
+			printk("\n The parameter for Timer/watchdog selection is in error\n");
+			return -EINVAL;
+		}
+	}
+	outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+	ui_Command = 0;
+	ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+/********************************/
+/* Disable the hardware trigger */
+/********************************/
+	ui_Command = ui_Command & 0xFFFFF89FUL;
+	if (data[4] == ADDIDATA_ENABLE) {
+    /**********************************/
+		/* Set the hardware trigger level */
+    /**********************************/
+		ui_Command = ui_Command | (data[5] << 5);
+	}
+	outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+	ui_Command = 0;
+	ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+/*****************************/
+/* Disable the hardware gate */
+/*****************************/
+	ui_Command = ui_Command & 0xFFFFF87FUL;
+	if (data[6] == ADDIDATA_ENABLE) {
+/*******************************/
+/* Set the hardware gate level */
+/*******************************/
+		ui_Command = ui_Command | (data[7] << 7);
+	}
+	outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+	ui_Command = 0;
+	ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+/*******************************/
+/* Disable the hardware output */
+/*******************************/
+	ui_Command = ui_Command & 0xFFFFF9FBUL;
+/*********************************/
+/* Set the hardware output level */
+/*********************************/
+	ui_Command = ui_Command | (data[8] << 2);
+	outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+	if (data[9] == ADDIDATA_ENABLE) {
+   /************************/
+		/* Set the reload value */
+   /************************/
+		outl(data[11],
+			devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 24);
+   /**********************/
+		/* Set the time unite */
+   /**********************/
+		outl(data[10],
+			devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 28);
+	}
+
+	ui_Command = 0;
+	ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+ /*******************************/
+	/* Disable the hardware output */
+ /*******************************/
+	ui_Command = ui_Command & 0xFFFFF9F7UL;
+   /*********************************/
+	/* Set the hardware output level */
+   /*********************************/
+	ui_Command = ui_Command | (data[12] << 3);
+	outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+ /*************************************/
+ /**  Enable the watchdog interrupt  **/
+ /*************************************/
+	ui_Command = 0;
+	ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+/*******************************/
+/* Set the interrupt selection */
+/*******************************/
+	ui_Status = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 16);
+
+	ui_Command = (ui_Command & 0xFFFFF9FDUL) | (data[13] << 1);
+	outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI035_StartStopWriteTimerWatchdog              |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Start / Stop The Selected Timer , or Watchdog  |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev : Driver handle                     |
+|                     UINT *data         : Data Pointer contains             |
+|                                          configuration parameters as below |
+|					                                                 |
+|					  data[0] : 0 - Stop Selected Timer/Watchdog     |
+|					            1 - Start Selected Timer/Watchdog    |
+|					            2 - Trigger Selected Timer/Watchdog  |
+|					            3 - Stop All Timer/Watchdog          |
+|					            4 - Start All Timer/Watchdog         |
+|					            5 - Trigger All Timer/Watchdog       |
+|					                                                 |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error			 |
+|					                                                 |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI035_StartStopWriteTimerWatchdog(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_Command = 0;
+	INT i_Count = 0;
+	if (data[0] == 1) {
+		ui_Command =
+			inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+	 /**********************/
+		/* Start the hardware */
+	 /**********************/
+		ui_Command = (ui_Command & 0xFFFFF9FFUL) | 0x1UL;
+		outl(ui_Command,
+			devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+	}			// if  (data[0]==1)
+	if (data[0] == 2) {
+		ui_Command =
+			inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+	 /***************************/
+		/* Set the trigger command */
+	 /***************************/
+		ui_Command = (ui_Command & 0xFFFFF9FFUL) | 0x200UL;
+		outl(ui_Command,
+			devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+	}
+
+	if (data[0] == 0)	//Stop The Watchdog
+	{
+		//Stop The Watchdog
+		ui_Command = 0;
+		//ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
+		//ui_Command = ui_Command & 0xFFFFF9FEUL;
+		outl(ui_Command,
+			devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+	}			//  if (data[1]==0)
+	if (data[0] == 3)	//stop all Watchdogs
+	{
+		ui_Command = 0;
+		for (i_Count = 1; i_Count <= 4; i_Count++) {
+			if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
+				ui_Command = 0x2UL;
+			} else {
+				ui_Command = 0x10UL;
+			}
+			i_WatchdogNbr = i_Count;
+			outl(ui_Command,
+				devpriv->iobase + ((i_WatchdogNbr - 1) * 32) +
+				0);
+		}
+
+	}
+	if (data[0] == 4)	//start all Watchdogs
+	{
+		ui_Command = 0;
+		for (i_Count = 1; i_Count <= 4; i_Count++) {
+			if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
+				ui_Command = 0x1UL;
+			} else {
+				ui_Command = 0x8UL;
+			}
+			i_WatchdogNbr = i_Count;
+			outl(ui_Command,
+				devpriv->iobase + ((i_WatchdogNbr - 1) * 32) +
+				0);
+		}
+	}
+	if (data[0] == 5)	//trigger all Watchdogs
+	{
+		ui_Command = 0;
+		for (i_Count = 1; i_Count <= 4; i_Count++) {
+			if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
+				ui_Command = 0x4UL;
+			} else {
+				ui_Command = 0x20UL;
+			}
+
+			i_WatchdogNbr = i_Count;
+			outl(ui_Command,
+				devpriv->iobase + ((i_WatchdogNbr - 1) * 32) +
+				0);
+		}
+		i_Temp = 1;
+	}
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI035_ReadTimerWatchdog                        |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Read The Selected Timer , Counter or Watchdog          |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev : Driver handle                     |
+|                     UINT *data         : Data Pointer contains             |
+|                                          configuration parameters as below |
+|                                                                            |
+|     																	 |
++----------------------------------------------------------------------------+
+| Output Parameters :	data[0]            : software trigger status
+              data[1]            : hardware trigger status
+|     				data[2]            : Software clear status
+                        data[3]            : Overflow status
+                     data[4]            : Timer actual value
+
+
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI035_ReadTimerWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_Status = 0;	// Status register
+	i_WatchdogNbr = insn->unused[0];
+	      /******************/
+	/* Get the status */
+	      /******************/
+	ui_Status = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 16);
+      /***********************************/
+	/* Get the software trigger status */
+      /***********************************/
+	data[0] = ((ui_Status >> 1) & 1);
+      /***********************************/
+	/* Get the hardware trigger status */
+      /***********************************/
+	data[1] = ((ui_Status >> 2) & 1);
+      /*********************************/
+	/* Get the software clear status */
+      /*********************************/
+	data[2] = ((ui_Status >> 3) & 1);
+      /***************************/
+	/* Get the overflow status */
+      /***************************/
+	data[3] = ((ui_Status >> 0) & 1);
+	if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
+		data[4] = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 0);
+
+	}			//  if  (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
+
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : INT i_APCI035_ConfigAnalogInput                        |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Configures The Analog Input Subdevice                  |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                     struct comedi_subdevice *s     : Subdevice Pointer            |
+|                     struct comedi_insn *insn       : Insn Structure Pointer       |
+|                     unsigned int *data          : Data Pointer contains        |
+|                                          configuration parameters as below |
+|                     data[0]                  : Warning delay value
+|                                                                            |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI035_ConfigAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	devpriv->tsk_Current = current;
+	outl(0x200 | 0, devpriv->iobase + 128 + 0x4);
+	outl(0, devpriv->iobase + 128 + 0);
+/********************************/
+/* Initialise the warning value */
+/********************************/
+	outl(0x300 | 0, devpriv->iobase + 128 + 0x4);
+	outl((data[0] << 8), devpriv->iobase + 128 + 0);
+	outl(0x200000UL, devpriv->iobase + 128 + 12);
+
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI035_ReadAnalogInput                          |
+|			          (struct comedi_device *dev,struct comedi_subdevice *s,       |
+|                     struct comedi_insn *insn,unsigned int *data)                      |
++----------------------------------------------------------------------------+
+| Task              : Read  value  of the selected channel			         |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                     UINT ui_NoOfChannels    : No Of Channels To read       |
+|                     UINT *data              : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
+|			          data[0]  : Digital Value Of Input              |
+|			                                                         |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI035_ReadAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_CommandRegister = 0;
+/******************/
+/*  Set the start */
+/******************/
+	ui_CommandRegister = 0x80000;
+ /******************************/
+	/* Write the command register */
+ /******************************/
+	outl(ui_CommandRegister, devpriv->iobase + 128 + 8);
+
+/***************************************/
+/* Read the digital value of the input */
+/***************************************/
+	data[0] = inl(devpriv->iobase + 128 + 28);
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   :  int i_APCI035_Reset(struct comedi_device *dev)			     |
+|					                                                         |
++----------------------------------------------------------------------------+
+| Task              :Resets the registers of the card                        |
++----------------------------------------------------------------------------+
+| Input Parameters  :                                                        |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      :                                                        |
+|			                                                                 |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI035_Reset(struct comedi_device * dev)
+{
+	INT i_Count = 0;
+	for (i_Count = 1; i_Count <= 4; i_Count++) {
+		i_WatchdogNbr = i_Count;
+		outl(0x0, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 0);	//stop all timers
+	}
+	outl(0x0, devpriv->iobase + 128 + 12);	//Disable the warning delay
+
+	return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : static void v_APCI035_Interrupt					     |
+|					  (int irq , void *d)      |
++----------------------------------------------------------------------------+
+| Task              : Interrupt processing Routine                           |
++----------------------------------------------------------------------------+
+| Input Parameters  : int irq                 : irq number                   |
+|                     void *d                 : void pointer                 |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+static void v_APCI035_Interrupt(int irq, void *d)
+{
+	struct comedi_device *dev = d;
+	UINT ui_StatusRegister1 = 0;
+	UINT ui_StatusRegister2 = 0;
+	UINT ui_ReadCommand = 0;
+	UINT ui_ChannelNumber = 0;
+	UINT ui_DigitalTemperature = 0;
+	if (i_Temp == 1) {
+		i_WatchdogNbr = i_Flag;
+		i_Flag = i_Flag + 1;
+	}
+  /**************************************/
+	/* Read the interrupt status register of temperature Warning */
+  /**************************************/
+	ui_StatusRegister1 = inl(devpriv->iobase + 128 + 16);
+  /**************************************/
+	/* Read the interrupt status register for Watchdog/timer */
+   /**************************************/
+
+	ui_StatusRegister2 =
+		inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 20);
+
+	if ((((ui_StatusRegister1) & 0x8) == 0x8))	//Test if warning relay interrupt
+	{
+	/**********************************/
+		/* Disable the temperature warning */
+	/**********************************/
+		ui_ReadCommand = inl(devpriv->iobase + 128 + 12);
+		ui_ReadCommand = ui_ReadCommand & 0xFFDF0000UL;
+		outl(ui_ReadCommand, devpriv->iobase + 128 + 12);
+      /***************************/
+		/* Read the channel number */
+      /***************************/
+		ui_ChannelNumber = inl(devpriv->iobase + 128 + 60);
+	/**************************************/
+		/* Read the digital temperature value */
+	/**************************************/
+		ui_DigitalTemperature = inl(devpriv->iobase + 128 + 60);
+		send_sig(SIGIO, devpriv->tsk_Current, 0);	// send signal to the sample
+	}			//if (((ui_StatusRegister1 & 0x8) == 0x8))
+
+	else {
+		if ((ui_StatusRegister2 & 0x1) == 0x1) {
+			send_sig(SIGIO, devpriv->tsk_Current, 0);	// send signal to the sample
+		}
+	}			//else if (((ui_StatusRegister1 & 0x8) == 0x8))
+
+	return;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h
new file mode 100644
index 0000000..80d7c0d
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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.
+ */
+
+/* Card Specific information */
+#define APCI035_BOARD_VENDOR_ID		0x15B8
+#define APCI035_ADDRESS_RANGE		255
+
+INT i_TW_Number;
+struct {
+	INT i_Gain;
+	INT i_Polarity;
+	INT i_OffsetRange;
+	INT i_Coupling;
+	INT i_SingleDiff;
+	INT i_AutoCalibration;
+	UINT ui_ReloadValue;
+	UINT ui_TimeUnitReloadVal;
+	INT i_Interrupt;
+	INT i_ModuleSelection;
+} Config_Parameters_Main;
+
+/* ANALOG INPUT RANGE */
+struct comedi_lrange range_apci035_ai = { 8, {
+				       BIP_RANGE(10),
+				       BIP_RANGE(5),
+				       BIP_RANGE(2),
+				       BIP_RANGE(1),
+				       UNI_RANGE(10),
+				       UNI_RANGE(5),
+				       UNI_RANGE(2),
+				       UNI_RANGE(1)
+				       }
+};
+
+/* Timer / Watchdog Related Defines */
+#define APCI035_TCW_SYNC_ENABLEDISABLE	0
+#define APCI035_TCW_RELOAD_VALUE	4
+#define APCI035_TCW_TIMEBASE		8
+#define APCI035_TCW_PROG		12
+#define APCI035_TCW_TRIG_STATUS		16
+#define APCI035_TCW_IRQ			20
+#define APCI035_TCW_WARN_TIMEVAL	24
+#define APCI035_TCW_WARN_TIMEBASE	28
+
+#define ADDIDATA_TIMER			0
+/* #define ADDIDATA_WATCHDOG		1 */
+
+#define APCI035_TW1                               0
+#define APCI035_TW2                               32
+#define APCI035_TW3                               64
+#define APCI035_TW4                               96
+
+#define APCI035_AI_OFFSET                        0
+#define APCI035_TEMP                             128
+#define APCI035_ALR_SEQ                          4
+#define APCI035_START_STOP_INDEX                 8
+#define APCI035_ALR_START_STOP                   12
+#define APCI035_ALR_IRQ                          16
+#define APCI035_EOS                              20
+#define APCI035_CHAN_NO                          24
+#define APCI035_CHAN_VAL                         28
+#define APCI035_CONV_TIME_TIME_BASE	36
+#define APCI035_RELOAD_CONV_TIME_VAL	32
+#define APCI035_DELAY_TIME_TIME_BASE	44
+#define APCI035_RELOAD_DELAY_TIME_VAL	40
+#define ENABLE_EXT_TRIG			1
+#define ENABLE_EXT_GATE			2
+#define ENABLE_EXT_TRIG_GATE		3
+
+#define ANALOG_INPUT			0
+#define TEMPERATURE			1
+#define RESISTANCE			2
+
+#define ADDIDATA_GREATER_THAN_TEST	0
+#define ADDIDATA_LESS_THAN_TEST		1
+
+#define APCI035_MAXVOLT                         2.5
+
+#define ADDIDATA_UNIPOLAR                        1
+#define ADDIDATA_BIPOLAR                         2
+
+/* ADDIDATA Enable Disable */
+#define ADDIDATA_ENABLE				1
+#define ADDIDATA_DISABLE			0
+
+/* Hardware Layer functions for Apci035 */
+
+/* TIMER */
+/* timer value is passed as u seconds */
+INT i_APCI035_ConfigTimerWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+				  struct comedi_insn *insn, unsigned int *data);
+INT i_APCI035_StartStopWriteTimerWatchdog(struct comedi_device *dev,
+					  struct comedi_subdevice *s,
+					  struct comedi_insn *insn, unsigned int *data);
+INT i_APCI035_ReadTimerWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data);
+
+/* Temperature Related Defines (Analog Input Subdevice) */
+
+INT i_APCI035_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data);
+INT i_APCI035_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
+			      struct comedi_insn *insn, unsigned int *data);
+
+/* Interrupt */
+static void v_APCI035_Interrupt(int irq, void *d);
+
+/* Reset functions */
+INT i_APCI035_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c
new file mode 100644
index 0000000..32796ce
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c
@@ -0,0 +1,285 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+
+        ADDI-DATA GmbH
+        Dieselstrasse 3
+        D-77833 Ottersweier
+        Tel: +19(0)7223/9493-0
+        Fax: +49(0)7223/9493-92
+        http://www.addi-data-com
+        info@addi-data.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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+  +-----------------------------------------------------------------------+
+  | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
+  +-----------------------------------------------------------------------+
+  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
+  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
+  +-------------------------------+---------------------------------------+
+  | Project     : APCI-1032       | Compiler   : GCC                      |
+  | Module name : hwdrv_apci1032.c| Version    : 2.96                     |
+  +-------------------------------+---------------------------------------+
+  | Project manager: Eric Stolz   | Date       :  02/12/2002              |
+  +-------------------------------+---------------------------------------+
+  | Description :   Hardware Layer Acces For APCI-1032                    |
+  +-----------------------------------------------------------------------+
+  |                             UPDATES                                   |
+  +----------+-----------+------------------------------------------------+
+  |   Date   |   Author  |          Description of updates                |
+  +----------+-----------+------------------------------------------------+
+  |          |           |                                                |
+  |          |           |                                                |
+  |          |           |                                                |
+  +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+|                               Included files                               |
++----------------------------------------------------------------------------+
+*/
+#include "hwdrv_apci1032.h"
+#include <linux/delay.h>
+//Global variables
+UINT ui_InterruptStatus = 0;
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1032_ConfigDigitalInput                      |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Configures the digital input Subdevice                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev : Driver handle                     |
+|                     unsigned int *data         : Data Pointer contains         |
+|                                          configuration parameters as below |
+|                                                                            |
+|			  data[0]            : 1 Enable  Digital Input Interrupt |
+|								   0 Disable Digital Input Interrupt |
+|			  data[1]            : 0 ADDIDATA Interrupt OR LOGIC	 |
+|								 : 1 ADDIDATA Interrupt AND LOGIC    |
+|			  data[2]			 : Interrupt mask for the mode 1	 |
+|			  data[3]			 : Interrupt mask for the mode 2	 |
+|																	 |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1032_ConfigDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_TmpValue;
+
+	ULONG ul_Command1 = 0;
+	ULONG ul_Command2 = 0;
+	devpriv->tsk_Current = current;
+
+  /*******************************/
+	/* Set the digital input logic */
+  /*******************************/
+	if (data[0] == ADDIDATA_ENABLE) {
+		ul_Command1 = ul_Command1 | data[2];
+		ul_Command2 = ul_Command2 | data[3];
+		outl(ul_Command1,
+			devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1);
+		outl(ul_Command2,
+			devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2);
+		if (data[1] == ADDIDATA_OR) {
+			outl(0x4, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
+			ui_TmpValue =
+				inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
+		}		//if (data[1] == ADDIDATA_OR)
+		else {
+			outl(0x6, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
+		}		//else if(data[1] == ADDIDATA_OR)
+	}			// if( data[0] == ADDIDATA_ENABLE)
+	else {
+		ul_Command1 = ul_Command1 & 0xFFFF0000;
+		ul_Command2 = ul_Command2 & 0xFFFF0000;
+		outl(ul_Command1,
+			devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1);
+		outl(ul_Command2,
+			devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2);
+		outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
+	}			//else if  ( data[0] == ADDIDATA_ENABLE)
+
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1032_Read1DigitalInput                       |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Return the status of the digital input                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|		              UINT ui_Channel : Channel number to read       |
+|                     unsigned int *data          : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1032_Read1DigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_TmpValue = 0;
+	UINT ui_Channel;
+	ui_Channel = CR_CHAN(insn->chanspec);
+	if (ui_Channel >= 0 && ui_Channel <= 31) {
+		ui_TmpValue = (UINT) inl(devpriv->iobase + APCI1032_DIGITAL_IP);
+		//  since only 1 channel reqd  to bring it to last bit it is rotated
+		//  8 +(chan - 1) times then ANDed with 1 for last bit.
+		*data = (ui_TmpValue >> ui_Channel) & 0x1;
+	}			//if(ui_Channel >= 0 && ui_Channel <=31)
+	else {
+		//comedi_error(dev," \n chan spec wrong\n");
+		return -EINVAL;	// "sorry channel spec wrong "
+	}			//else if(ui_Channel >= 0 && ui_Channel <=31)
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1032_ReadMoreDigitalInput                    |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                     struct comedi_insn *insn,unsigned int *data)                      |
++----------------------------------------------------------------------------+
+| Task              : Return the status of the Requested digital inputs      |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                     UINT ui_NoOfChannels    : No Of Channels To be Read    |
+|                      UINT *data             : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1032_ReadMoreDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_PortValue = data[0];
+	UINT ui_Mask = 0;
+	UINT ui_NoOfChannels;
+
+	ui_NoOfChannels = CR_CHAN(insn->chanspec);
+	if (data[1] == 0) {
+		*data = (UINT) inl(devpriv->iobase + APCI1032_DIGITAL_IP);
+		switch (ui_NoOfChannels) {
+		case 2:
+			ui_Mask = 3;
+			*data = (*data >> (2 * ui_PortValue)) & ui_Mask;
+			break;
+		case 4:
+			ui_Mask = 15;
+			*data = (*data >> (4 * ui_PortValue)) & ui_Mask;
+			break;
+		case 8:
+			ui_Mask = 255;
+			*data = (*data >> (8 * ui_PortValue)) & ui_Mask;
+			break;
+		case 16:
+			ui_Mask = 65535;
+			*data = (*data >> (16 * ui_PortValue)) & ui_Mask;
+			break;
+		case 31:
+			break;
+		default:
+			//comedi_error(dev," \nchan spec wrong\n");
+			return -EINVAL;	// "sorry channel spec wrong "
+			break;
+		}		//switch(ui_NoOfChannels)
+	}			//if(data[1]==0)
+	else {
+		if (data[1] == 1) {
+			*data = ui_InterruptStatus;
+		}		//if(data[1]==1)
+	}			//else if(data[1]==0)
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : static void v_APCI1032_Interrupt					     |
+|					  (int irq , void *d)      |
++----------------------------------------------------------------------------+
+| Task              : Interrupt handler for the interruptible digital inputs |
++----------------------------------------------------------------------------+
+| Input Parameters  : int irq                 : irq number                   |
+|                     void *d                 : void pointer                 |
++----------------------------------------------------------------------------+
+| Output Parameters :	--						     |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                     |
++----------------------------------------------------------------------------+
+*/
+static void v_APCI1032_Interrupt(int irq, void *d)
+{
+	struct comedi_device *dev = d;
+
+	UINT ui_Temp;
+	//disable the interrupt
+	ui_Temp = inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
+	outl(ui_Temp & APCI1032_DIGITAL_IP_INTERRUPT_DISABLE,
+		devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
+	ui_InterruptStatus =
+		inl(devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_STATUS);
+	ui_InterruptStatus = ui_InterruptStatus & 0X0000FFFF;
+	send_sig(SIGIO, devpriv->tsk_Current, 0);	// send signal to the sample
+	outl(ui_Temp, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);	//enable the interrupt
+	return;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1032_Reset(struct comedi_device *dev)               |                                                       |
++----------------------------------------------------------------------------+
+| Task              :resets all the registers                                |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      :                                                        |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1032_Reset(struct comedi_device * dev)
+{
+	outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);	//disable the interrupts
+	inl(devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_STATUS);	//Reset the interrupt status register
+	outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1);	//Disable the and/or interrupt
+	outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2);
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h
new file mode 100644
index 0000000..659ef85
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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.
+ */
+
+/*********      Definitions for APCI-1032 card  *****/
+
+#define APCI1032_BOARD_VENDOR_ID 0x15B8
+#define APCI1032_ADDRESS_RANGE  20
+//DIGITAL INPUT DEFINE
+
+#define APCI1032_DIGITAL_IP                     0
+#define APCI1032_DIGITAL_IP_INTERRUPT_MODE1     4
+#define APCI1032_DIGITAL_IP_INTERRUPT_MODE2     8
+#define APCI1032_DIGITAL_IP_IRQ                 16
+
+//Digital Input IRQ Function Selection
+#define ADDIDATA_OR                  0
+#define ADDIDATA_AND                 1
+
+//Digital Input Interrupt Status
+#define APCI1032_DIGITAL_IP_INTERRUPT_STATUS    12
+
+//Digital Input Interrupt Enable Disable.
+#define APCI1032_DIGITAL_IP_INTERRUPT_ENABLE    0x4
+#define APCI1032_DIGITAL_IP_INTERRUPT_DISABLE   0xFFFFFFFB
+
+//ADDIDATA Enable Disable
+
+#define ADDIDATA_ENABLE                            1
+#define ADDIDATA_DISABLE                           0
+
+// Hardware Layer  functions for Apci1032
+
+//DI
+// for di read
+
+INT i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+				  struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1032_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1032_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+				    struct comedi_insn *insn, unsigned int *data);
+
+// Interrupt functions.....
+
+static void v_APCI1032_Interrupt(int irq, void *d);
+//Reset
+INT i_APCI1032_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
new file mode 100644
index 0000000..2d6adcf
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
@@ -0,0 +1,3045 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+
+        ADDI-DATA GmbH
+        Dieselstrasse 3
+        D-77833 Ottersweier
+        Tel: +19(0)7223/9493-0
+        Fax: +49(0)7223/9493-92
+        http://www.addi-data-com
+        info@addi-data.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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+  +-----------------------------------------------------------------------+
+  | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
+  +-----------------------------------------------------------------------+
+  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
+  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
+  +-------------------------------+---------------------------------------+
+  | Project     : APCI-1500       | Compiler   : GCC                      |
+  | Module name : hwdrv_apci1500.c| Version    : 2.96                     |
+  +-------------------------------+---------------------------------------+
+  | Project manager: Eric Stolz   | Date       :  02/12/2002              |
+  +-------------------------------+---------------------------------------+
+  | Description :   Hardware Layer Acces For APCI-1500                    |
+  +-----------------------------------------------------------------------+
+  |                             UPDATES                                   |
+  +----------+-----------+------------------------------------------------+
+  |   Date   |   Author  |          Description of updates                |
+  +----------+-----------+------------------------------------------------+
+  |          |           |                                                |
+  |          |           |                                                |
+  |          |           |                                                |
+  +----------+-----------+------------------------------------------------+
+*/
+#include "hwdrv_apci1500.h"
+
+int i_TimerCounter1Init = 0;
+int i_TimerCounter2Init = 0;
+int i_WatchdogCounter3Init = 0;
+int i_Event1Status = 0, i_Event2Status = 0;
+int i_TimerCounterWatchdogInterrupt = 0;
+int i_Logic = 0, i_CounterLogic = 0;
+int i_InterruptMask = 0;
+int i_InputChannel = 0;
+int i_TimerCounter1Enabled = 0, i_TimerCounter2Enabled =
+	0, i_WatchdogCounter3Enabled = 0;
+
+/*
+  +----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1500_ConfigDigitalInputEvent                 |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : An event can be generated for each port.               |
+|                     The first event is related to the first 8 channels     |
+|                     (port 1) and the second to the following 6 channels    |
+|                     (port 2). An interrupt is generated when one or both   |
+|                     events have occurred                                   |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev : Driver handle                     |
+|                     unsigned int *data     : Data Pointer contains             |
+|                                          configuration parameters as below |
+|                                                                            |
+|			  data[0]            :Number of the input port on        |
+|                                         which the event will take place    |
+|                                         (1 or 2)
+                      data[1]            : The event logic for port 1 has    |
+|                                            three possibilities             |
+|                                        :0  APCI1500_AND       :This logic  |
+|                                                                links       |
+|                                                                the inputs  |
+|                                                                with an AND |
+|                                                                logic.      |
+|                                          1 APCI1500_OR        :This logic  |
+|                                                                links       |
+|                                                                the inputs  |
+|                                                                with a      |
+|                                                                OR logic.   |
+|                                          2    APCI1500_OR_PRIORITY        |
+|								:This logic                          |
+|                                                                links       |
+|                                                                the inputs  |
+|                                                                with a      |
+|                                                                priority    |
+|                                                                OR logic.   |
+|                                                                Input 1     |
+|                                                                has the     |
+|                                                                highest     |
+|                                                                priority    |
+|                                                                level and   |
+|                                                                input   8   |
+|                                                                the smallest|
+|                                            For the second port the user has|
+|                                            1 possibility:                  |
+|                                            APCI1500_OR        :This logic  |
+|                                                                links       |
+|                                                                the inputs  |
+|                                                                with a      |
+|                                                                polarity    |
+|                                                                OR logic    |
+|                     data[2]              : These 8-character word for port1|
+|                                            and 6-character word for port 2 |
+|                                            give the mask of the event.     |
+|                                            Each place gives the state      |
+|                                            of the input channels and can   |
+|                                            have one of these six characters|
+|                                                     |
+|                                       0  : This input must be on 0         |
+|                                       1  : This input must be on 1         |
+|                                       2  : This input reacts to            |
+|                                            a falling edge                  |
+|                                       3  : This input reacts to a          |
+|                                            rising edge                     |
+|                                       4  : This input reacts to both edges |
+|
+|								5  : This input is not               |
+|                                            used for event   				 |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1500_ConfigDigitalInputEvent(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	int i_PatternPolarity = 0, i_PatternTransition = 0, i_PatternMask = 0;
+	int i_MaxChannel = 0, i_Count = 0, i_EventMask = 0;
+	int i_PatternTransitionCount = 0, i_RegValue;
+	int i;
+
+      /*************************************************/
+	/* Selects the master interrupt control register */
+      /*************************************************/
+	outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+      /**********************************************/
+	/* Disables  the main interrupt on the board */
+      /**********************************************/
+	outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+	if (data[0] == 1) {
+		i_MaxChannel = 8;
+	}			// if (data[0] == 1)
+	else {
+		if (data[0] == 2) {
+			i_MaxChannel = 6;
+		}		// if(data[0]==2)
+		else {
+			printk("\nThe specified port event  does not exist\n");
+			return -EINVAL;
+		}		//else if(data[0]==2)
+	}			//else  if (data[0] == 1)
+	switch (data[1]) {
+	case 0:
+		data[1] = APCI1500_AND;
+		break;
+	case 1:
+		data[1] = APCI1500_OR;
+		break;
+	case 2:
+		data[1] = APCI1500_OR_PRIORITY;
+		break;
+	default:
+		printk("\nThe specified interrupt logic does not exist\n");
+		return -EINVAL;
+	}			//switch(data[1]);
+
+	i_Logic = data[1];
+	for (i_Count = i_MaxChannel, i = 0; i_Count > 0; i_Count--, i++) {
+		i_EventMask = data[2 + i];
+		switch (i_EventMask) {
+		case 0:
+			i_PatternMask =
+				i_PatternMask | (1 << (i_MaxChannel - i_Count));
+			break;
+		case 1:
+			i_PatternMask =
+				i_PatternMask | (1 << (i_MaxChannel - i_Count));
+			i_PatternPolarity =
+				i_PatternPolarity | (1 << (i_MaxChannel -
+					i_Count));
+			break;
+		case 2:
+			i_PatternMask =
+				i_PatternMask | (1 << (i_MaxChannel - i_Count));
+			i_PatternTransition =
+				i_PatternTransition | (1 << (i_MaxChannel -
+					i_Count));
+			break;
+		case 3:
+			i_PatternMask =
+				i_PatternMask | (1 << (i_MaxChannel - i_Count));
+			i_PatternPolarity =
+				i_PatternPolarity | (1 << (i_MaxChannel -
+					i_Count));
+			i_PatternTransition =
+				i_PatternTransition | (1 << (i_MaxChannel -
+					i_Count));
+			break;
+		case 4:
+			i_PatternTransition =
+				i_PatternTransition | (1 << (i_MaxChannel -
+					i_Count));
+			break;
+		case 5:
+			break;
+		default:
+			printk("\nThe option indicated in the event mask does not exist\n");
+			return -EINVAL;
+		}		// switch(i_EventMask)
+	}			//for (i_Count = i_MaxChannel; i_Count >0;i_Count --)
+
+	if (data[0] == 1) {
+		    /****************************/
+		/* Test the interrupt logic */
+		    /****************************/
+
+		if (data[1] == APCI1500_AND ||
+			data[1] == APCI1500_OR ||
+			data[1] == APCI1500_OR_PRIORITY) {
+		       /**************************************/
+			/* Tests if a transition was declared */
+			/* for a OR PRIORITY logic            */
+		       /**************************************/
+
+			if (data[1] == APCI1500_OR_PRIORITY
+				&& i_PatternTransition != 0) {
+			      /********************************************/
+				/* Transition error on an OR PRIORITY logic */
+			      /********************************************/
+				printk("\nTransition error on an OR PRIORITY logic\n");
+				return -EINVAL;
+			}	// if (data[1]== APCI1500_OR_PRIORITY && i_PatternTransition != 0)
+
+		       /*************************************/
+			/* Tests if more than one transition */
+			/* was declared for an AND logic     */
+		       /*************************************/
+
+			if (data[1] == APCI1500_AND) {
+				for (i_Count = 0; i_Count < 8; i_Count++) {
+					i_PatternTransitionCount =
+						i_PatternTransitionCount +
+						((i_PatternTransition >>
+							i_Count) & 0x1);
+
+				}	//for (i_Count = 0; i_Count < 8; i_Count++)
+
+				if (i_PatternTransitionCount > 1) {
+				  /****************************************/
+					/* Transition error on an AND logic     */
+				  /****************************************/
+					printk("\n Transition error on an AND logic\n");
+					return -EINVAL;
+				}	// if (i_PatternTransitionCount > 1)
+			}	// if (data[1]== APCI1500_AND)
+
+			    /*****************************************************************/
+			/* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+			    /*****************************************************************/
+			outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			/******************/
+			/* Disable Port A */
+			    /******************/
+			outb(0xF0,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			/**********************************************/
+			/* Selects the polarity register of port 1    */
+			    /**********************************************/
+			outb(APCI1500_RW_PORT_A_PATTERN_POLARITY,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			outb(i_PatternPolarity,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+
+			/*********************************************/
+			/* Selects the pattern mask register of      */
+			/* port 1                                    */
+			    /*********************************************/
+			outb(APCI1500_RW_PORT_A_PATTERN_MASK,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			outb(i_PatternMask,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			/********************************************/
+			/* Selects the pattern transition register  */
+			/* of port 1                                */
+			    /********************************************/
+			outb(APCI1500_RW_PORT_A_PATTERN_TRANSITION,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			outb(i_PatternTransition,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+
+		      /******************************************/
+			/* Selects the mode specification mask    */
+			/* register of port 1                     */
+			  /******************************************/
+			outb(APCI1500_RW_PORT_A_SPECIFICATION,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			i_RegValue =
+				inb(devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+
+		      /******************************************/
+			/* Selects the mode specification mask    */
+			/* register of port 1                     */
+			  /******************************************/
+			outb(APCI1500_RW_PORT_A_SPECIFICATION,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+
+		      /**********************/
+			/* Port A new mode    */
+			  /**********************/
+
+			i_RegValue = (i_RegValue & 0xF9) | data[1] | 0x9;
+			outb(i_RegValue,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+
+			i_Event1Status = 1;
+
+		      /*****************************************************************/
+			/* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+			  /*****************************************************************/
+
+			outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+		      /*****************/
+			/* Enable Port A */
+			  /*****************/
+			outb(0xF4,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+
+		}		// if(data[1]==APCI1500_AND||data[1]==APCI1500_OR||data[1]==APCI1500_OR_PRIORITY)
+		else {
+			printk("\nThe choice for interrupt logic does not exist\n");
+			return -EINVAL;
+		}		// else }// if(data[1]==APCI1500_AND||data[1]==APCI1500_OR||data[1]==APCI1500_OR_PRIORITY)
+	}			//   if (data[0]== 1)
+
+		 /************************************/
+	/* Test if event setting for port 2 */
+		 /************************************/
+
+	if (data[0] == 2) {
+		    /************************/
+		/* Test the event logic */
+		    /************************/
+
+		if (data[1] == APCI1500_OR) {
+		       /*****************************************************************/
+			/* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+		       /*****************************************************************/
+			outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+		       /******************/
+			/* Disable Port B */
+		       /******************/
+			outb(0x74,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+		       /****************************************/
+			/* Selects the mode specification mask  */
+			/* register of port B                   */
+		       /****************************************/
+			outb(APCI1500_RW_PORT_B_SPECIFICATION,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			i_RegValue =
+				inb(devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+
+		       /******************************************/
+			/* Selects the mode specification mask    */
+			/* register of port B                     */
+		       /******************************************/
+			outb(APCI1500_RW_PORT_B_SPECIFICATION,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			i_RegValue = i_RegValue & 0xF9;
+			outb(i_RegValue,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+
+		       /**********************************/
+			/* Selects error channels 1 and 2 */
+		       /**********************************/
+
+			i_PatternMask = (i_PatternMask | 0xC0);
+			i_PatternPolarity = (i_PatternPolarity | 0xC0);
+			i_PatternTransition = (i_PatternTransition | 0xC0);
+
+		       /**********************************************/
+			/* Selects the polarity register of port 2    */
+		       /**********************************************/
+			outb(APCI1500_RW_PORT_B_PATTERN_POLARITY,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			outb(i_PatternPolarity,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+		       /**********************************************/
+			/* Selects the pattern transition register    */
+			/* of port 2                                  */
+		       /**********************************************/
+			outb(APCI1500_RW_PORT_B_PATTERN_TRANSITION,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			outb(i_PatternTransition,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+		       /**********************************************/
+			/* Selects the pattern Mask register    */
+			/* of port 2                                  */
+		       /**********************************************/
+
+			outb(APCI1500_RW_PORT_B_PATTERN_MASK,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			outb(i_PatternMask,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+
+		       /******************************************/
+			/* Selects the mode specification mask    */
+			/* register of port 2                     */
+		       /******************************************/
+			outb(APCI1500_RW_PORT_B_SPECIFICATION,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			i_RegValue =
+				inb(devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+		       /******************************************/
+			/* Selects the mode specification mask    */
+			/* register of port 2                     */
+		       /******************************************/
+			outb(APCI1500_RW_PORT_B_SPECIFICATION,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			i_RegValue = (i_RegValue & 0xF9) | 4;
+			outb(i_RegValue,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+
+			i_Event2Status = 1;
+		       /*****************************************************************/
+			/* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+		       /*****************************************************************/
+
+			outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+		       /*****************/
+			/* Enable Port B */
+		       /*****************/
+
+			outb(0xF4,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+		}		//  if (data[1] == APCI1500_OR)
+		else {
+			printk("\nThe choice for interrupt logic does not exist\n");
+			return -EINVAL;
+		}		//elseif (data[1] == APCI1500_OR)
+	}			//if(data[0]==2)
+
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1500_StartStopInputEvent                     |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              :  Allows or disallows a port event                      |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|		              UINT ui_Channel : Channel number to read       |
+|                     unsigned int *data          : Data Pointer to read status  |
+                      data[0]                 :0 Start input event
+                                               1 Stop input event
+                      data[1]                 :No of port (1 or 2)
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+int i_APCI1500_StartStopInputEvent(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i_Event1InterruptStatus = 0, i_Event2InterruptStatus =
+		0, i_RegValue;
+	switch (data[0]) {
+	case START:
+	      /*************************/
+		/* Tests the port number */
+	      /*************************/
+
+		if (data[1] == 1 || data[1] == 2) {
+		  /***************************/
+			/* Test if port 1 selected */
+		  /***************************/
+
+			if (data[1] == 1) {
+		    /*****************************/
+				/* Test if event initialised */
+		    /*****************************/
+				if (i_Event1Status == 1) {
+		       /*****************************************************************/
+					/* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+		       /*****************************************************************/
+					outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+		       /******************/
+					/* Disable Port A */
+		       /******************/
+					outb(0xF0,
+						devpriv->iobase +
+						APCI1500_Z8536_CONTROL_REGISTER);
+		       /***************************************************/
+					/* Selects the command and status register of      */
+					/* port 1                                          */
+		       /***************************************************/
+					outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+		       /*************************************/
+					/* Allows the pattern interrupt      */
+		       /*************************************/
+					outb(0xC0,
+						devpriv->iobase +
+						APCI1500_Z8536_CONTROL_REGISTER);
+		       /*****************************************************************/
+					/* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+		       /*****************************************************************/
+					outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+		       /*****************/
+					/* Enable Port A */
+		       /*****************/
+					outb(0xF4,
+						devpriv->iobase +
+						APCI1500_Z8536_CONTROL_REGISTER);
+					i_Event1InterruptStatus = 1;
+					outb(APCI1500_RW_PORT_A_SPECIFICATION,
+						devpriv->iobase +
+						APCI1500_Z8536_CONTROL_REGISTER);
+					i_RegValue =
+						inb(devpriv->iobase +
+						APCI1500_Z8536_CONTROL_REGISTER);
+
+					/* Selects the master interrupt control register */
+		       /*************************************************/
+					outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+		       /**********************************************/
+					/* Authorizes the main interrupt on the board */
+		       /**********************************************/
+					outb(0xD0,
+						devpriv->iobase +
+						APCI1500_Z8536_CONTROL_REGISTER);
+
+				}	// if(i_Event1Status==1)
+				else {
+					printk("\nEvent 1 not initialised\n");
+					return -EINVAL;
+				}	//else if(i_Event1Status==1)
+			}	//if (data[1]==1)
+			if (data[1] == 2) {
+
+				if (i_Event2Status == 1) {
+			    /*****************************************************************/
+					/* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+			    /*****************************************************************/
+					outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+		       /******************/
+					/* Disable Port B */
+		       /******************/
+					outb(0x74,
+						devpriv->iobase +
+						APCI1500_Z8536_CONTROL_REGISTER);
+		       /***************************************************/
+					/* Selects the command and status register of      */
+					/* port 2                                          */
+		       /***************************************************/
+					outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+		       /*************************************/
+					/* Allows the pattern interrupt      */
+		       /*************************************/
+					outb(0xC0,
+						devpriv->iobase +
+						APCI1500_Z8536_CONTROL_REGISTER);
+		       /*****************************************************************/
+					/* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+		       /*****************************************************************/
+					outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+		       /*****************/
+					/* Enable Port B */
+		       /*****************/
+					outb(0xF4,
+						devpriv->iobase +
+						APCI1500_Z8536_CONTROL_REGISTER);
+
+					/* Selects the master interrupt control register */
+		       /*************************************************/
+					outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+		       /**********************************************/
+					/* Authorizes the main interrupt on the board */
+		       /**********************************************/
+					outb(0xD0,
+						devpriv->iobase +
+						APCI1500_Z8536_CONTROL_REGISTER);
+					i_Event2InterruptStatus = 1;
+				}	// if(i_Event2Status==1)
+				else {
+					printk("\nEvent 2 not initialised\n");
+					return -EINVAL;
+				}	//else if(i_Event2Status==1)
+			}	// if(data[1]==2)
+		}		// if (data[1] == 1 || data[0] == 2)
+		else {
+			printk("\nThe port parameter is in error\n");
+			return -EINVAL;
+		}		//else if (data[1] == 1 || data[0] == 2)
+
+		break;
+
+	case STOP:
+		  /*************************/
+		/* Tests the port number */
+		  /*************************/
+
+		if (data[1] == 1 || data[1] == 2) {
+		  /***************************/
+			/* Test if port 1 selected */
+		  /***************************/
+
+			if (data[1] == 1) {
+		    /*****************************/
+				/* Test if event initialised */
+		    /*****************************/
+				if (i_Event1Status == 1) {
+		       /*****************************************************************/
+					/* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+		       /*****************************************************************/
+					outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+		       /******************/
+					/* Disable Port A */
+		       /******************/
+					outb(0xF0,
+						devpriv->iobase +
+						APCI1500_Z8536_CONTROL_REGISTER);
+		       /***************************************************/
+					/* Selects the command and status register of      */
+					/* port 1                                          */
+		       /***************************************************/
+					outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+		       /*************************************/
+					/* Inhibits the pattern interrupt      */
+		       /*************************************/
+					outb(0xE0,
+						devpriv->iobase +
+						APCI1500_Z8536_CONTROL_REGISTER);
+		       /*****************************************************************/
+					/* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+		       /*****************************************************************/
+					outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+		       /*****************/
+					/* Enable Port A */
+		       /*****************/
+					outb(0xF4,
+						devpriv->iobase +
+						APCI1500_Z8536_CONTROL_REGISTER);
+					i_Event1InterruptStatus = 0;
+				}	// if(i_Event1Status==1)
+				else {
+					printk("\nEvent 1 not initialised\n");
+					return -EINVAL;
+				}	//else if(i_Event1Status==1)
+			}	//if (data[1]==1)
+			if (data[1] == 2) {
+			 /*****************************/
+				/* Test if event initialised */
+			 /*****************************/
+				if (i_Event2Status == 1) {
+			  /*****************************************************************/
+					/* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+			  /*****************************************************************/
+					outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+			  /******************/
+					/* Disable Port B */
+			  /******************/
+					outb(0x74,
+						devpriv->iobase +
+						APCI1500_Z8536_CONTROL_REGISTER);
+			  /***************************************************/
+					/* Selects the command and status register of      */
+					/* port 2                                         */
+			  /***************************************************/
+					outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+		       /*************************************/
+					/* Inhibits the pattern interrupt      */
+		       /*************************************/
+					outb(0xE0,
+						devpriv->iobase +
+						APCI1500_Z8536_CONTROL_REGISTER);
+		       /*****************************************************************/
+					/* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+		       /*****************************************************************/
+					outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+		       /*****************/
+					/* Enable Port B */
+		       /*****************/
+					outb(0xF4,
+						devpriv->iobase +
+						APCI1500_Z8536_CONTROL_REGISTER);
+					i_Event2InterruptStatus = 0;
+				}	// if(i_Event2Status==1)
+				else {
+					printk("\nEvent 2 not initialised\n");
+					return -EINVAL;
+				}	//else if(i_Event2Status==1)
+			}	//if(data[1]==2)
+
+		}		// if (data[1] == 1 || data[1] == 2)
+		else {
+			printk("\nThe port parameter is in error\n");
+			return -EINVAL;
+		}		//else if (data[1] == 1 || data[1] == 2)
+		break;
+	default:
+		printk("\nThe option of START/STOP logic does not exist\n");
+		return -EINVAL;
+	}			//switch(data[0])
+
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1500_Initialisation                          |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Return the status of the digital input                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|		              UINT ui_Channel : Channel number to read       |
+|                     unsigned int *data          : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1500_Initialisation(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i_DummyRead = 0;
+    /******************/
+	/* Software reset */
+    /******************/
+	i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	outb(1, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+	/* Selects the master configuration control register */
+ /*****************************************************/
+	outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	outb(0xF4, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+	/*****************************************************/
+	/* Selects the mode specification register of port A */
+	/*****************************************************/
+	outb(APCI1500_RW_PORT_A_SPECIFICATION,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+	/* Selects the data path polarity register of port A */
+	outb(APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* High level of port A means 1 */
+	outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+	/* Selects the data direction register of port A */
+	outb(APCI1500_RW_PORT_A_DATA_DIRECTION,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* All bits used as inputs */
+	outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Selects the command and status register of port A */
+	outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deletes IP and IUS */
+	outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/*  Selects the command and status register of port A */
+	outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deactivates the interrupt management of port A:  */
+	outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Selects the handshake specification register of port A */
+	outb(APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deletes the register */
+	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+	 /*****************************************************/
+	/* Selects the mode specification register of port B */
+	 /*****************************************************/
+	outb(APCI1500_RW_PORT_B_SPECIFICATION,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Selects the data path polarity register of port B */
+	outb(APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* A high level of port B means 1 */
+	outb(0x7F, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Selects the data direction register of port B */
+	outb(APCI1500_RW_PORT_B_DATA_DIRECTION,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* All bits used as inputs */
+	outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Selects the command and status register of port B */
+	outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deletes IP and IUS */
+	outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Selects the command and status register of port B */
+	outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deactivates the interrupt management of port B:         */
+	outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Selects the handshake specification register of port B */
+	outb(APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deletes the register */
+	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+	   /*****************************************************/
+	/* Selects the data path polarity register of port C */
+	   /*****************************************************/
+	outb(APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* High level of port C means 1 */
+	outb(0x9, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Selects the data direction register of port C */
+	outb(APCI1500_RW_PORT_C_DATA_DIRECTION,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* All bits used as inputs except channel 1 */
+	outb(0x0E, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Selects the special IO register of port C */
+	outb(APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deletes it */
+	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	   /******************************************************/
+	/* Selects the command and status register of timer 1 */
+	   /******************************************************/
+	outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deletes IP and IUS */
+	outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Selects the command and status register of timer 1 */
+	outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deactivates the interrupt management of timer 1         */
+	outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	   /******************************************************/
+	/* Selects the command and status register of timer 2 */
+	   /******************************************************/
+	outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deletes IP and IUS */
+	outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Selects the command and status register of timer 2 */
+	outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deactivates Timer 2 interrupt management:               */
+	outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	  /******************************************************/
+	/* Selects the command and status register of timer 3 */
+	  /******************************************************/
+	outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deletes IP and IUS */
+	outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Selects the command and status register of Timer 3 */
+	outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deactivates interrupt management of timer 3:            */
+	outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	 /*************************************************/
+	/* Selects the master interrupt control register */
+	 /*************************************************/
+	outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deletes all interrupts */
+	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1500_ReadMoreDigitalInput                    |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                     struct comedi_insn *insn,unsigned int *data)                      |
++----------------------------------------------------------------------------+
+| Task              : Return the status of the Requested digital inputs      |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                     UINT ui_NoOfChannels    : No Of Channels To be Read    |
+|                      UINT *data             : Data Pointer
+                      data[0]                 : 0 Read a single channel
+                                                1 read a port value
+                      data[1]                 : port value
++----------------------------------------------------------------------------+
+| Output Parameters :	--	data[0]    :The read status value
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1500_ReadMoreDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_PortValue = data[1];
+	UINT ui_Mask = 0;
+	UINT ui_Channel;
+	UINT ui_TmpValue = 0;
+	ui_Channel = CR_CHAN(insn->chanspec);
+
+	switch (data[0]) {
+	case 0:
+		if (ui_Channel >= 0 && ui_Channel <= 15) {
+			ui_TmpValue =
+				(UINT) inw(devpriv->i_IobaseAddon +
+				APCI1500_DIGITAL_IP);
+			*data = (ui_TmpValue >> ui_Channel) & 0x1;
+		}		//if(ui_Channel >= 0 && ui_Channel <=15)
+		else {
+			printk("\nThe channel specification are in error\n");
+			return -EINVAL;	// "sorry channel spec wrong "
+		}		//else if(ui_Channel >= 0 && ui_Channel <=15)
+		break;
+	case 1:
+
+		*data = (UINT) inw(devpriv->i_IobaseAddon +
+			APCI1500_DIGITAL_IP);
+		switch (ui_Channel) {
+		case 2:
+			ui_Mask = 3;
+			*data = (*data >> (2 * ui_PortValue)) & ui_Mask;
+			break;
+		case 4:
+			ui_Mask = 15;
+			*data = (*data >> (4 * ui_PortValue)) & ui_Mask;
+			break;
+		case 8:
+			ui_Mask = 255;
+			*data = (*data >> (8 * ui_PortValue)) & ui_Mask;
+			break;
+		case 15:
+			break;
+
+		default:
+			printk("\nSpecified channel cannot be read \n");
+			return -EINVAL;	// "sorry channel spec wrong "
+			break;
+		}		//switch(ui_Channel)
+		break;
+	default:
+		printk("\nThe specified functionality does not exist\n");
+		return -EINVAL;
+	}			//switch(data[0])
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1500_ConfigDigitalOutputErrorInterrupt
+                      (struct comedi_device *dev,struct comedi_subdevice *s struct comedi_insn
+                      *insn,unsigned int *data)                                  |
+|				                                                     |
++----------------------------------------------------------------------------+
+| Task              : Configures the digital output memory and the digital
+                      output error interrupt                                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev : Driver handle                     |
+|                     unsigned int *data         : Data Pointer contains         |
+|                                          configuration parameters as below |
+|                      struct comedi_subdevice *s,   :pointer to subdevice structure
+                       struct comedi_insn *insn      :pointer to insn structure                                                                                                                |
+|					  data[0]  :1:Memory on                          |
+|					            0:Memory off                         |
+                              data[1]  :1 Enable the voltage error interrupt
+|							   :0 Disable the voltage error interrupt 		                                                                                                    |
+|																	 |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+int i_APCI1500_ConfigDigitalOutputErrorInterrupt(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	devpriv->b_OutputMemoryStatus = data[0];
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1500_WriteDigitalOutput                      |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Writes port value  To the selected port                |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                     UINT ui_NoOfChannels    : No Of Channels To Write      |
+|                     UINT *data              : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1500_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	static UINT ui_Temp = 0;
+	UINT ui_Temp1;
+
+	UINT ui_NoOfChannel = CR_CHAN(insn->chanspec);	// get the channel
+
+	if (!devpriv->b_OutputMemoryStatus) {
+		ui_Temp = 0;
+
+	}			//if(!devpriv->b_OutputMemoryStatus )
+	if (data[3] == 0) {
+		if (data[1] == 0) {
+			data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
+			outw(data[0],
+				devpriv->i_IobaseAddon + APCI1500_DIGITAL_OP);
+		}		//if(data[1]==0)
+		else {
+			if (data[1] == 1) {
+				switch (ui_NoOfChannel) {
+
+				case 2:
+					data[0] =
+						(data[0] << (2 *
+							data[2])) | ui_Temp;
+					break;
+
+				case 4:
+					data[0] =
+						(data[0] << (4 *
+							data[2])) | ui_Temp;
+					break;
+
+				case 8:
+					data[0] =
+						(data[0] << (8 *
+							data[2])) | ui_Temp;
+					break;
+
+				case 15:
+					data[0] = data[0] | ui_Temp;
+					break;
+
+				default:
+					comedi_error(dev, " chan spec wrong");
+					return -EINVAL;	// "sorry channel spec wrong "
+
+				}	//switch(ui_NoOfChannels)
+
+				outw(data[0],
+					devpriv->i_IobaseAddon +
+					APCI1500_DIGITAL_OP);
+			}	// if(data[1]==1)
+			else {
+				printk("\nSpecified channel not supported\n");
+			}	//else if(data[1]==1)
+		}		//elseif(data[1]==0)
+	}			//if(data[3]==0)
+	else {
+		if (data[3] == 1) {
+			if (data[1] == 0) {
+				data[0] = ~data[0] & 0x1;
+				ui_Temp1 = 1;
+				ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+				ui_Temp = ui_Temp | ui_Temp1;
+				data[0] =
+					(data[0] << ui_NoOfChannel) ^
+					0xffffffff;
+				data[0] = data[0] & ui_Temp;
+				outw(data[0],
+					devpriv->i_IobaseAddon +
+					APCI1500_DIGITAL_OP);
+			}	//if(data[1]==0)
+			else {
+				if (data[1] == 1) {
+					switch (ui_NoOfChannel) {
+
+					case 2:
+						data[0] = ~data[0] & 0x3;
+						ui_Temp1 = 3;
+						ui_Temp1 =
+							ui_Temp1 << 2 * data[2];
+						ui_Temp = ui_Temp | ui_Temp1;
+						data[0] =
+							((data[0] << (2 *
+									data
+									[2])) ^
+							0xffffffff) & ui_Temp;
+						break;
+
+					case 4:
+						data[0] = ~data[0] & 0xf;
+						ui_Temp1 = 15;
+						ui_Temp1 =
+							ui_Temp1 << 4 * data[2];
+						ui_Temp = ui_Temp | ui_Temp1;
+						data[0] =
+							((data[0] << (4 *
+									data
+									[2])) ^
+							0xffffffff) & ui_Temp;
+						break;
+
+					case 8:
+						data[0] = ~data[0] & 0xff;
+						ui_Temp1 = 255;
+						ui_Temp1 =
+							ui_Temp1 << 8 * data[2];
+						ui_Temp = ui_Temp | ui_Temp1;
+						data[0] =
+							((data[0] << (8 *
+									data
+									[2])) ^
+							0xffffffff) & ui_Temp;
+						break;
+
+					case 15:
+						break;
+
+					default:
+						comedi_error(dev,
+							" chan spec wrong");
+						return -EINVAL;	// "sorry channel spec wrong "
+
+					}	//switch(ui_NoOfChannels)
+
+					outw(data[0],
+						devpriv->i_IobaseAddon +
+						APCI1500_DIGITAL_OP);
+				}	// if(data[1]==1)
+				else {
+					printk("\nSpecified channel not supported\n");
+				}	//else if(data[1]==1)
+			}	//elseif(data[1]==0)
+		}		//if(data[3]==1);
+		else {
+			printk("\nSpecified functionality does not exist\n");
+			return -EINVAL;
+		}		//if else data[3]==1)
+	}			//if else data[3]==0)
+	ui_Temp = data[0];
+	return (insn->n);;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1500_ConfigCounterTimerWatchdog(comedi_device
+                   *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)|
+|				                                                     |
++----------------------------------------------------------------------------+
+| Task              : Configures The Watchdog                                |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                     struct comedi_subdevice *s,   :pointer to subdevice structure
+                      struct comedi_insn *insn      :pointer to insn structure      |
+|                     unsigned int *data         : Data Pointer to read status                                                       data[0]                : 2     APCI1500_1_8_KHZ
+|                                              1     APCI1500_3_6_KHZ        |
+|                                              0     APCI1500_115_KHZ
+                      data[1]                : 0     Counter1/Timer1
+                                               1     Counter2/Timer2
+                                               2     Counter3/Watchdog
+                      data[2]                : 0     Counter
+                                               1     Timer/Watchdog
+                      data[3]                :         This parameter has    |
+|                                                      two meanings.         |
+|                                                    - If the counter/timer  |
+|                                                      is used as a counter  |
+|                                                      the limit value of    |
+|                                                      the counter is given  |
+|                                                                            |
+|                                                    - If the counter/timer  |
+|                                                      is used as a timer,   |
+|                                                      the divider factor    |
+|                                                      for the output is     |
+|                                                      given.
+                       data[4]                 : 0    APCI1500_CONTINUOUS
+                                                 1    APCI1500_SINGLE
+                       data[5]                 : 0    Software Trigger
+                                                 1    Hardware Trigger
+
+                       data[6]                  :0    Software gate
+                                                 1    Hardware gate
+                       data[7]                  :0    Interrupt Disable
+                                                 1    Interrupt Enable
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI1500_ConfigCounterTimerWatchdog(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	int i_TimerCounterMode, i_MasterConfiguration;
+
+	devpriv->tsk_Current = current;
+
+//Selection of the input clock
+	if (data[0] == 0 || data[0] == 1 || data[0] == 2) {
+		outw(data[0], devpriv->i_IobaseAddon + APCI1500_CLK_SELECT);
+	}			// if(data[0]==0||data[0]==1||data[0]==2)
+	else {
+		if (data[0] != 3) {
+			printk("\nThe option for input clock selection does not exist\n");
+			return -EINVAL;
+		}		// if(data[0]!=3)
+	}			//elseif(data[0]==0||data[0]==1||data[0]==2)
+	//Select the counter/timer
+	switch (data[1]) {
+	case COUNTER1:
+		//selecting counter or timer
+		switch (data[2]) {
+		case 0:
+			data[2] = APCI1500_COUNTER;
+			break;
+		case 1:
+			data[2] = APCI1500_TIMER;
+			break;
+		default:
+			printk("\nThis choice is not a timer nor a counter\n");
+			return -EINVAL;
+		}		// switch(data[2])
+
+		//Selecting  single or continuous mode
+		switch (data[4]) {
+		case 0:
+			data[4] = APCI1500_CONTINUOUS;
+			break;
+		case 1:
+			data[4] = APCI1500_SINGLE;
+			break;
+		default:
+			printk("\nThis option for single/continuous mode does not exist\n");
+			return -EINVAL;
+		}		// switch(data[4])
+
+		i_TimerCounterMode = data[2] | data[4] | 7;
+			 /*************************/
+		/* Test the reload value */
+			 /*************************/
+
+		if ((data[3] >= 0) && (data[3] <= 65535)) {
+			if (data[7] == APCI1500_ENABLE
+				|| data[7] == APCI1500_DISABLE) {
+
+				/************************************************/
+				/* Selects the mode register of timer/counter 1 */
+				/************************************************/
+				outb(APCI1500_RW_CPT_TMR1_MODE_SPECIFICATION,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+				/***********************/
+				/* Writes the new mode */
+				/***********************/
+				outb(i_TimerCounterMode,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				/****************************************************/
+				/* Selects the constant register of timer/counter 1 */
+				/****************************************************/
+
+				outb(APCI1500_RW_CPT_TMR1_TIME_CST_LOW,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				  /*************************/
+				/* Writes the low value  */
+				  /*************************/
+
+				outb(data[3],
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				   /****************************************************/
+				/* Selects the constant register of timer/counter 1 */
+				   /****************************************************/
+
+				outb(APCI1500_RW_CPT_TMR1_TIME_CST_HIGH,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				  /**************************/
+				/* Writes the high value  */
+				  /**************************/
+
+				data[3] = data[3] >> 8;
+				outb(data[3],
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				     /*********************************************/
+				/* Selects the master configuration register */
+				     /*********************************************/
+
+				outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				     /**********************/
+				/* Reads the register */
+				     /**********************/
+
+				i_MasterConfiguration =
+					inb(devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				       /********************************************************/
+				/* Enables timer/counter 1 and triggers timer/counter 1 */
+				       /********************************************************/
+
+				i_MasterConfiguration =
+					i_MasterConfiguration | 0x40;
+
+				    /*********************************************/
+				/* Selects the master configuration register */
+				    /*********************************************/
+				outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				      /********************************/
+				/* Writes the new configuration */
+				      /********************************/
+				outb(i_MasterConfiguration,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+					 /****************************************/
+				/* Selects the commands register of     */
+				/* timer/counter 1                      */
+					 /****************************************/
+
+				outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				       /***************************/
+				/* Disable timer/counter 1 */
+				       /***************************/
+
+				outb(0x0,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+					  /****************************************/
+				/* Selects the commands register of     */
+				/* timer/counter 1                      */
+					  /****************************************/
+				outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				      /***************************/
+				/* Trigger timer/counter 1 */
+				      /***************************/
+				outb(0x2,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+			}	//if(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+			else {
+				printk("\nError in selection of interrupt enable or disable\n");
+				return -EINVAL;
+			}	//elseif(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+		}		// if ((data[3]>= 0) && (data[3] <= 65535))
+		else {
+			printk("\nError in selection of reload value\n");
+			return -EINVAL;
+		}		//else if ((data[3]>= 0) && (data[3] <= 65535))
+		i_TimerCounterWatchdogInterrupt = data[7];
+		i_TimerCounter1Init = 1;
+		break;
+
+	case COUNTER2:		//selecting counter or timer
+		switch (data[2]) {
+		case 0:
+			data[2] = APCI1500_COUNTER;
+			break;
+		case 1:
+			data[2] = APCI1500_TIMER;
+			break;
+		default:
+			printk("\nThis choice is not a timer nor a counter\n");
+			return -EINVAL;
+		}		// switch(data[2])
+
+		//Selecting  single or continuous mode
+		switch (data[4]) {
+		case 0:
+			data[4] = APCI1500_CONTINUOUS;
+			break;
+		case 1:
+			data[4] = APCI1500_SINGLE;
+			break;
+		default:
+			printk("\nThis option for single/continuous mode does not exist\n");
+			return -EINVAL;
+		}		// switch(data[4])
+
+		//Selecting  software or hardware trigger
+		switch (data[5]) {
+		case 0:
+			data[5] = APCI1500_SOFTWARE_TRIGGER;
+			break;
+		case 1:
+			data[5] = APCI1500_HARDWARE_TRIGGER;
+			break;
+		default:
+			printk("\nThis choice for software or hardware trigger does not exist\n");
+			return -EINVAL;
+		}		// switch(data[5])
+
+		//Selecting  software or hardware gate
+		switch (data[6]) {
+		case 0:
+			data[6] = APCI1500_SOFTWARE_GATE;
+			break;
+		case 1:
+			data[6] = APCI1500_HARDWARE_GATE;
+			break;
+		default:
+			printk("\nThis choice for software or hardware gate does not exist\n");
+			return -EINVAL;
+		}		// switch(data[6])
+
+		i_TimerCounterMode = data[2] | data[4] | data[5] | data[6] | 7;
+
+			     /*************************/
+		/* Test the reload value */
+			     /*************************/
+
+		if ((data[3] >= 0) && (data[3] <= 65535)) {
+			if (data[7] == APCI1500_ENABLE
+				|| data[7] == APCI1500_DISABLE) {
+
+				/************************************************/
+				/* Selects the mode register of timer/counter 2 */
+				/************************************************/
+				outb(APCI1500_RW_CPT_TMR2_MODE_SPECIFICATION,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+				/***********************/
+				/* Writes the new mode */
+				/***********************/
+				outb(i_TimerCounterMode,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				/****************************************************/
+				/* Selects the constant register of timer/counter 2 */
+				/****************************************************/
+
+				outb(APCI1500_RW_CPT_TMR2_TIME_CST_LOW,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				  /*************************/
+				/* Writes the low value  */
+				  /*************************/
+
+				outb(data[3],
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				   /****************************************************/
+				/* Selects the constant register of timer/counter 2 */
+				   /****************************************************/
+
+				outb(APCI1500_RW_CPT_TMR2_TIME_CST_HIGH,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				  /**************************/
+				/* Writes the high value  */
+				  /**************************/
+
+				data[3] = data[3] >> 8;
+				outb(data[3],
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				     /*********************************************/
+				/* Selects the master configuration register */
+				     /*********************************************/
+
+				outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				     /**********************/
+				/* Reads the register */
+				     /**********************/
+
+				i_MasterConfiguration =
+					inb(devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				       /********************************************************/
+				/* Enables timer/counter 2 and triggers timer/counter 2 */
+				       /********************************************************/
+
+				i_MasterConfiguration =
+					i_MasterConfiguration | 0x20;
+
+				    /*********************************************/
+				/* Selects the master configuration register */
+				    /*********************************************/
+				outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				      /********************************/
+				/* Writes the new configuration */
+				      /********************************/
+				outb(i_MasterConfiguration,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+					 /****************************************/
+				/* Selects the commands register of     */
+				/* timer/counter 2                      */
+					 /****************************************/
+
+				outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				       /***************************/
+				/* Disable timer/counter 2 */
+				       /***************************/
+
+				outb(0x0,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+					  /****************************************/
+				/* Selects the commands register of     */
+				/* timer/counter 2                      */
+					  /****************************************/
+				outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				      /***************************/
+				/* Trigger timer/counter 1 */
+				      /***************************/
+				outb(0x2,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+			}	//if(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+			else {
+				printk("\nError in selection of interrupt enable or disable\n");
+				return -EINVAL;
+			}	//elseif(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+		}		// if ((data[3]>= 0) && (data[3] <= 65535))
+		else {
+			printk("\nError in selection of reload value\n");
+			return -EINVAL;
+		}		//else if ((data[3]>= 0) && (data[3] <= 65535))
+		i_TimerCounterWatchdogInterrupt = data[7];
+		i_TimerCounter2Init = 1;
+		break;
+
+	case COUNTER3:		//selecting counter or watchdog
+		switch (data[2]) {
+		case 0:
+			data[2] = APCI1500_COUNTER;
+			break;
+		case 1:
+			data[2] = APCI1500_WATCHDOG;
+			break;
+		default:
+			printk("\nThis choice is not a watchdog nor a counter\n");
+			return -EINVAL;
+		}		// switch(data[2])
+
+		//Selecting  single or continuous mode
+		switch (data[4]) {
+		case 0:
+			data[4] = APCI1500_CONTINUOUS;
+			break;
+		case 1:
+			data[4] = APCI1500_SINGLE;
+			break;
+		default:
+			printk("\nThis option for single/continuous mode does not exist\n");
+			return -EINVAL;
+		}		// switch(data[4])
+
+		//Selecting  software or hardware gate
+		switch (data[6]) {
+		case 0:
+			data[6] = APCI1500_SOFTWARE_GATE;
+			break;
+		case 1:
+			data[6] = APCI1500_HARDWARE_GATE;
+			break;
+		default:
+			printk("\nThis choice for software or hardware gate does not exist\n");
+			return -EINVAL;
+		}		// switch(data[6])
+
+		      /*****************************/
+		/* Test if used for watchdog */
+			  /*****************************/
+
+		if (data[2] == APCI1500_WATCHDOG) {
+			     /*****************************/
+			/* - Enables the output line */
+			/* - Enables retrigger       */
+			/* - Pulses output           */
+			     /*****************************/
+			i_TimerCounterMode = data[2] | data[4] | 0x54;
+		}		//if (data[2] == APCI1500_WATCHDOG)
+		else {
+			i_TimerCounterMode = data[2] | data[4] | data[6] | 7;
+		}		//elseif (data[2] == APCI1500_WATCHDOG)
+				 /*************************/
+		/* Test the reload value */
+			     /*************************/
+
+		if ((data[3] >= 0) && (data[3] <= 65535)) {
+			if (data[7] == APCI1500_ENABLE
+				|| data[7] == APCI1500_DISABLE) {
+
+				/************************************************/
+				/* Selects the mode register of watchdog/counter 3 */
+				/************************************************/
+				outb(APCI1500_RW_CPT_TMR3_MODE_SPECIFICATION,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+				/***********************/
+				/* Writes the new mode */
+				/***********************/
+				outb(i_TimerCounterMode,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				/****************************************************/
+				/* Selects the constant register of watchdog/counter 3 */
+				/****************************************************/
+
+				outb(APCI1500_RW_CPT_TMR3_TIME_CST_LOW,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				  /*************************/
+				/* Writes the low value  */
+				  /*************************/
+
+				outb(data[3],
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				   /****************************************************/
+				/* Selects the constant register of watchdog/counter 3 */
+				   /****************************************************/
+
+				outb(APCI1500_RW_CPT_TMR3_TIME_CST_HIGH,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				  /**************************/
+				/* Writes the high value  */
+				  /**************************/
+
+				data[3] = data[3] >> 8;
+				outb(data[3],
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				     /*********************************************/
+				/* Selects the master configuration register */
+				     /*********************************************/
+
+				outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				     /**********************/
+				/* Reads the register */
+				     /**********************/
+
+				i_MasterConfiguration =
+					inb(devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				       /********************************************************/
+				/* Enables watchdog/counter 3 and triggers watchdog/counter 3 */
+				       /********************************************************/
+
+				i_MasterConfiguration =
+					i_MasterConfiguration | 0x10;
+
+				    /*********************************************/
+				/* Selects the master configuration register */
+				    /*********************************************/
+				outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				      /********************************/
+				/* Writes the new configuration */
+				      /********************************/
+				outb(i_MasterConfiguration,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				      /********************/
+				/* Test if COUNTER */
+					  /********************/
+				if (data[2] == APCI1500_COUNTER) {
+
+					    /*************************************/
+					/* Selects the command register of   */
+					/* watchdog/counter 3                */
+						 /*************************************/
+					outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+						devpriv->iobase +
+						APCI1500_Z8536_CONTROL_REGISTER);
+					      /*************************************************/
+					/* Disable the  watchdog/counter 3 and starts it */
+						  /*************************************************/
+					outb(0x0,
+						devpriv->iobase +
+						APCI1500_Z8536_CONTROL_REGISTER);
+
+					      /*************************************/
+					/* Selects the command register of   */
+					/* watchdog/counter 3                */
+						  /*************************************/
+
+					outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+						devpriv->iobase +
+						APCI1500_Z8536_CONTROL_REGISTER);
+					     /*************************************************/
+					/* Trigger the  watchdog/counter 3 and starts it */
+						 /*************************************************/
+					outb(0x2,
+						devpriv->iobase +
+						APCI1500_Z8536_CONTROL_REGISTER);
+
+				}	//elseif(data[2]==APCI1500_COUNTER)
+
+			}	//if(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+			else {
+				printk("\nError in selection of interrupt enable or disable\n");
+				return -EINVAL;
+			}	//elseif(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+		}		// if ((data[3]>= 0) && (data[3] <= 65535))
+		else {
+			printk("\nError in selection of reload value\n");
+			return -EINVAL;
+		}		//else if ((data[3]>= 0) && (data[3] <= 65535))
+		i_TimerCounterWatchdogInterrupt = data[7];
+		i_WatchdogCounter3Init = 1;
+		break;
+
+	default:
+		printk("\nThe specified counter\timer option does not exist\n");
+	}			//switch(data[1])
+	i_CounterLogic = data[2];
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1500_StartStopTriggerTimerCounterWatchdog      |
+|				(struct comedi_device *dev,struct comedi_subdevice *s,
+                         struct comedi_insn *insn,unsigned int *data);                  |
++----------------------------------------------------------------------------+
+| Task              : Start / Stop or trigger the timer counter or Watchdog  |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev     : Driver handle                 |
+|                     struct comedi_subdevice *s,   :pointer to subdevice structure
+                      struct comedi_insn *insn      :pointer to insn structure      |
+|                     unsigned int *data         : Data Pointer to read status   |
+                      data[0]                : 0     Counter1/Timer1
+                                               1     Counter2/Timer2
+                                               2     Counter3/Watchdog
+                      data[1]                : 0     start
+                                               1     stop
+                                               2     Trigger
+                      data[2]                : 0     Counter
+                                               1     Timer/Watchdog
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+int i_APCI1500_StartStopTriggerTimerCounterWatchdog(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	int i_CommandAndStatusValue;
+
+	switch (data[0]) {
+	case COUNTER1:
+		switch (data[1]) {
+		case START:
+			if (i_TimerCounter1Init == 1) {
+				if (i_TimerCounterWatchdogInterrupt == 1) {
+					i_CommandAndStatusValue = 0xC4;	//Enable the interrupt
+				}	// if(i_TimerCounterWatchdogInterrupt==1)
+				else {
+					i_CommandAndStatusValue = 0xE4;	//disable the interrupt
+				}	//elseif(i_TimerCounterWatchdogInterrupt==1)
+					      /**************************/
+				/* Starts timer/counter 1 */
+					      /**************************/
+				i_TimerCounter1Enabled = 1;
+						/********************************************/
+				/* Selects the commands and status register */
+						/********************************************/
+				outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+				outb(i_CommandAndStatusValue,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+			}	//if( i_TimerCounter1Init==1)
+			else {
+				printk("\nCounter/Timer1 not configured\n");
+				return -EINVAL;
+			}
+			break;
+
+		case STOP:
+
+					      /**************************/
+			/* Stop timer/counter 1 */
+					      /**************************/
+
+						/********************************************/
+			/* Selects the commands and status register */
+						/********************************************/
+			outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			outb(0x00,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			i_TimerCounter1Enabled = 0;
+			break;
+
+		case TRIGGER:
+			if (i_TimerCounter1Init == 1) {
+				if (i_TimerCounter1Enabled == 1) {
+						 /************************/
+					/* Set Trigger and gate */
+						 /************************/
+
+					i_CommandAndStatusValue = 0x6;
+				}	//if( i_TimerCounter1Enabled==1)
+				else {
+						   /***************/
+					/* Set Trigger */
+						   /***************/
+
+					i_CommandAndStatusValue = 0x2;
+				}	//elseif(i_TimerCounter1Enabled==1)
+
+						/********************************************/
+				/* Selects the commands and status register */
+						/********************************************/
+				outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+				outb(i_CommandAndStatusValue,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+			}	//if( i_TimerCounter1Init==1)
+			else {
+				printk("\nCounter/Timer1 not configured\n");
+				return -EINVAL;
+			}
+			break;
+
+		default:
+			printk("\nThe specified option for start/stop/trigger does not exist\n");
+			return -EINVAL;
+		}		//switch(data[1])
+		break;
+
+	case COUNTER2:
+		switch (data[1]) {
+		case START:
+			if (i_TimerCounter2Init == 1) {
+				if (i_TimerCounterWatchdogInterrupt == 1) {
+					i_CommandAndStatusValue = 0xC4;	//Enable the interrupt
+				}	// if(i_TimerCounterWatchdogInterrupt==1)
+				else {
+					i_CommandAndStatusValue = 0xE4;	//disable the interrupt
+				}	//elseif(i_TimerCounterWatchdogInterrupt==1)
+					      /**************************/
+				/* Starts timer/counter 2 */
+					      /**************************/
+				i_TimerCounter2Enabled = 1;
+						/********************************************/
+				/* Selects the commands and status register */
+						/********************************************/
+				outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+				outb(i_CommandAndStatusValue,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+			}	//if( i_TimerCounter2Init==1)
+			else {
+				printk("\nCounter/Timer2 not configured\n");
+				return -EINVAL;
+			}
+			break;
+
+		case STOP:
+
+					      /**************************/
+			/* Stop timer/counter 2 */
+					      /**************************/
+
+						/********************************************/
+			/* Selects the commands and status register */
+						/********************************************/
+			outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			outb(0x00,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			i_TimerCounter2Enabled = 0;
+			break;
+		case TRIGGER:
+			if (i_TimerCounter2Init == 1) {
+				if (i_TimerCounter2Enabled == 1) {
+						 /************************/
+					/* Set Trigger and gate */
+						 /************************/
+
+					i_CommandAndStatusValue = 0x6;
+				}	//if( i_TimerCounter2Enabled==1)
+				else {
+						   /***************/
+					/* Set Trigger */
+						   /***************/
+
+					i_CommandAndStatusValue = 0x2;
+				}	//elseif(i_TimerCounter2Enabled==1)
+
+						/********************************************/
+				/* Selects the commands and status register */
+						/********************************************/
+				outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+				outb(i_CommandAndStatusValue,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+			}	//if( i_TimerCounter2Init==1)
+			else {
+				printk("\nCounter/Timer2 not configured\n");
+				return -EINVAL;
+			}
+			break;
+		default:
+			printk("\nThe specified option for start/stop/trigger does not exist\n");
+			return -EINVAL;
+		}		//switch(data[1])
+		break;
+	case COUNTER3:
+		switch (data[1]) {
+		case START:
+			if (i_WatchdogCounter3Init == 1) {
+
+				if (i_TimerCounterWatchdogInterrupt == 1) {
+					i_CommandAndStatusValue = 0xC4;	//Enable the interrupt
+				}	// if(i_TimerCounterWatchdogInterrupt==1)
+				else {
+					i_CommandAndStatusValue = 0xE4;	//disable the interrupt
+				}	//elseif(i_TimerCounterWatchdogInterrupt==1)
+					      /**************************/
+				/* Starts Watchdog/counter 3 */
+					      /**************************/
+				i_WatchdogCounter3Enabled = 1;
+						/********************************************/
+				/* Selects the commands and status register */
+						/********************************************/
+				outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+				outb(i_CommandAndStatusValue,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+			}	// if( i_WatchdogCounter3init==1)
+			else {
+				printk("\nWatchdog/Counter3 not configured\n");
+				return -EINVAL;
+			}
+			break;
+
+		case STOP:
+
+					      /**************************/
+			/* Stop Watchdog/counter 3 */
+					      /**************************/
+
+						/********************************************/
+			/* Selects the commands and status register */
+						/********************************************/
+			outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			outb(0x00,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			i_WatchdogCounter3Enabled = 0;
+			break;
+
+		case TRIGGER:
+			switch (data[2]) {
+			case 0:	//triggering counter 3
+				if (i_WatchdogCounter3Init == 1) {
+					if (i_WatchdogCounter3Enabled == 1) {
+							       /************************/
+						/* Set Trigger and gate */
+							       /************************/
+
+						i_CommandAndStatusValue = 0x6;
+					}	//if( i_WatchdogCounter3Enabled==1)
+					else {
+							   /***************/
+						/* Set Trigger */
+							   /***************/
+
+						i_CommandAndStatusValue = 0x2;
+					}	//elseif(i_WatchdogCounter3Enabled==1)
+
+						/********************************************/
+					/* Selects the commands and status register */
+						/********************************************/
+					outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+						devpriv->iobase +
+						APCI1500_Z8536_CONTROL_REGISTER);
+					outb(i_CommandAndStatusValue,
+						devpriv->iobase +
+						APCI1500_Z8536_CONTROL_REGISTER);
+				}	//if( i_WatchdogCounter3Init==1)
+				else {
+					printk("\nCounter3 not configured\n");
+					return -EINVAL;
+				}
+				break;
+			case 1:
+				//triggering Watchdog 3
+				if (i_WatchdogCounter3Init == 1) {
+
+						/********************************************/
+					/* Selects the commands and status register */
+						/********************************************/
+					outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+						devpriv->iobase +
+						APCI1500_Z8536_CONTROL_REGISTER);
+					outb(0x6,
+						devpriv->iobase +
+						APCI1500_Z8536_CONTROL_REGISTER);
+				}	//if( i_WatchdogCounter3Init==1)
+				else {
+					printk("\nWatchdog 3 not configured\n");
+					return -EINVAL;
+				}
+				break;
+			default:
+				printk("\nWrong choice of watchdog/counter3\n");
+				return -EINVAL;
+			}	//switch(data[2])
+			break;
+		default:
+			printk("\nThe specified option for start/stop/trigger does not exist\n");
+			return -EINVAL;
+		}		//switch(data[1])
+		break;
+	default:
+		printk("\nThe specified choice for counter/watchdog/timer does not exist\n");
+		return -EINVAL;
+	}			//switch(data[0])
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1500_ReadCounterTimerWatchdog                |
+|			(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+                    unsigned int *data); 	                                     |
++----------------------------------------------------------------------------+
+| Task              : Read The Watchdog                                      |
++----------------------------------------------------------------------------+
+| Input Parameters  :   struct comedi_device *dev      : Driver handle              |
+|                     struct comedi_subdevice *s,   :pointer to subdevice structure
+                      struct comedi_insn *insn      :pointer to insn structure      |
+|                     unsigned int *data          : Data Pointer to read status  |
+                      data[0]                : 0     Counter1/Timer1
+                                               1     Counter2/Timer2
+                                               2     Counter3/Watchdog
+
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI1500_ReadCounterTimerWatchdog(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	int i_CommandAndStatusValue;
+	switch (data[0]) {
+	case COUNTER1:
+		//Read counter/timer1
+		if (i_TimerCounter1Init == 1) {
+			if (i_TimerCounter1Enabled == 1) {
+		  /************************/
+				/* Set RCC and gate */
+		  /************************/
+
+				i_CommandAndStatusValue = 0xC;
+			}	//if( i_TimerCounter1Init==1)
+			else {
+		    /***************/
+				/* Set RCC */
+		    /***************/
+
+				i_CommandAndStatusValue = 0x8;
+			}	//elseif(i_TimerCounter1Init==1)
+
+		/********************************************/
+			/* Selects the commands and status register */
+		/********************************************/
+			outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			outb(i_CommandAndStatusValue,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+
+		 /***************************************/
+			/* Selects the counter register (high) */
+		 /***************************************/
+			outb(APCI1500_R_CPT_TMR1_VALUE_HIGH,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			data[0] =
+				inb(devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			data[0] = data[0] << 8;
+			data[0] = data[0] & 0xff00;
+			outb(APCI1500_R_CPT_TMR1_VALUE_LOW,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			data[0] =
+				data[0] | inb(devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+		}		//if( i_TimerCounter1Init==1)
+		else {
+			printk("\nTimer/Counter1 not configured\n");
+			return -EINVAL;
+		}		//elseif( i_TimerCounter1Init==1)
+		break;
+	case COUNTER2:
+		//Read counter/timer2
+		if (i_TimerCounter2Init == 1) {
+			if (i_TimerCounter2Enabled == 1) {
+		  /************************/
+				/* Set RCC and gate */
+		  /************************/
+
+				i_CommandAndStatusValue = 0xC;
+			}	//if( i_TimerCounter2Init==1)
+			else {
+		    /***************/
+				/* Set RCC */
+		    /***************/
+
+				i_CommandAndStatusValue = 0x8;
+			}	//elseif(i_TimerCounter2Init==1)
+
+		/********************************************/
+			/* Selects the commands and status register */
+		/********************************************/
+			outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			outb(i_CommandAndStatusValue,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+
+		 /***************************************/
+			/* Selects the counter register (high) */
+		 /***************************************/
+			outb(APCI1500_R_CPT_TMR2_VALUE_HIGH,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			data[0] =
+				inb(devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			data[0] = data[0] << 8;
+			data[0] = data[0] & 0xff00;
+			outb(APCI1500_R_CPT_TMR2_VALUE_LOW,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			data[0] =
+				data[0] | inb(devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+		}		//if( i_TimerCounter2Init==1)
+		else {
+			printk("\nTimer/Counter2 not configured\n");
+			return -EINVAL;
+		}		//elseif( i_TimerCounter2Init==1)
+		break;
+	case COUNTER3:
+		//Read counter/watchdog2
+		if (i_WatchdogCounter3Init == 1) {
+			if (i_WatchdogCounter3Enabled == 1) {
+		  /************************/
+				/* Set RCC and gate */
+		  /************************/
+
+				i_CommandAndStatusValue = 0xC;
+			}	//if( i_TimerCounter2Init==1)
+			else {
+		    /***************/
+				/* Set RCC */
+		    /***************/
+
+				i_CommandAndStatusValue = 0x8;
+			}	//elseif(i_WatchdogCounter3Init==1)
+
+		/********************************************/
+			/* Selects the commands and status register */
+		/********************************************/
+			outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			outb(i_CommandAndStatusValue,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+
+		 /***************************************/
+			/* Selects the counter register (high) */
+		 /***************************************/
+			outb(APCI1500_R_CPT_TMR3_VALUE_HIGH,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			data[0] =
+				inb(devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			data[0] = data[0] << 8;
+			data[0] = data[0] & 0xff00;
+			outb(APCI1500_R_CPT_TMR3_VALUE_LOW,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			data[0] =
+				data[0] | inb(devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+		}		//if( i_WatchdogCounter3Init==1)
+		else {
+			printk("\nWatchdogCounter3 not configured\n");
+			return -EINVAL;
+		}		//elseif( i_WatchdogCounter3Init==1)
+		break;
+	default:
+		printk("\nThe choice of timer/counter/watchdog does not exist\n");
+		return -EINVAL;
+	}			//switch(data[0])
+
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int  i_APCI1500_ReadInterruptMask                      |
+|			(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+                    unsigned int *data); 	                                     |
++----------------------------------------------------------------------------+
+| Task              : Read the interrupt mask                                |
++----------------------------------------------------------------------------+
+| Input Parameters  :   struct comedi_device *dev      : Driver handle              |
+|                     struct comedi_subdevice *s,   :pointer to subdevice structure
+                      struct comedi_insn *insn      :pointer to insn structure      |
+|                     unsigned int *data          : Data Pointer to read status  |
+
+
++----------------------------------------------------------------------------+
+| Output Parameters :	--	data[0]:The interrupt mask value												                           data[1]:Channel no
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+int i_APCI1500_ReadInterruptMask(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	data[0] = i_InterruptMask;
+	data[1] = i_InputChannel;
+	i_InterruptMask = 0;
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int  i_APCI1500_ConfigureInterrupt                     |
+|			(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+                    unsigned int *data); 	                                     |
++----------------------------------------------------------------------------+
+| Task              : Configures the interrupt registers                     |
++----------------------------------------------------------------------------+
+| Input Parameters  :   struct comedi_device *dev      : Driver handle              |
+|                     struct comedi_subdevice *s,   :pointer to subdevice structure
+                      struct comedi_insn *insn      :pointer to insn structure      |
+|                     unsigned int *data          : Data Pointer                 |
+
+
++----------------------------------------------------------------------------+
+| Output Parameters :	--
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+int i_APCI1500_ConfigureInterrupt(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_Status;
+	int i_RegValue;
+	int i_Constant;
+	devpriv->tsk_Current = current;
+	outl(0x0, devpriv->i_IobaseAmcc + 0x38);
+	if (data[0] == 1) {
+		i_Constant = 0xC0;
+	}			//if(data[0]==1)
+	else {
+		if (data[0] == 0) {
+			i_Constant = 0x00;
+		}		//if{data[0]==0)
+		else {
+			printk("\nThe parameter passed to driver is in error for enabling the voltage interrupt\n");
+			return -EINVAL;
+		}		//else if(data[0]==0)
+	}			//elseif(data[0]==1)
+
+	 /*****************************************************/
+	/* Selects the mode specification register of port B */
+	 /*****************************************************/
+	outb(APCI1500_RW_PORT_B_SPECIFICATION,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	outb(APCI1500_RW_PORT_B_SPECIFICATION,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+      /*********************************************/
+	/* Writes the new configuration (APCI1500_OR) */
+      /*********************************************/
+	i_RegValue = (i_RegValue & 0xF9) | APCI1500_OR;
+
+	outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+       /*****************************************************/
+	/* Selects the command and status register of port B */
+       /*****************************************************/
+	outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/*****************************************/
+	/* Authorises the interrupt on the board */
+	/*****************************************/
+	outb(0xC0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/***************************************************/
+	/* Selects the pattern polarity register of port B */
+	/***************************************************/
+	outb(APCI1500_RW_PORT_B_PATTERN_POLARITY,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	outb(i_Constant, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/*****************************************************/
+	/* Selects the pattern transition register of port B */
+	/*****************************************************/
+	outb(APCI1500_RW_PORT_B_PATTERN_TRANSITION,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	outb(i_Constant, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/***********************************************/
+	/* Selects the pattern mask register of port B */
+	/***********************************************/
+	outb(APCI1500_RW_PORT_B_PATTERN_MASK,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	outb(i_Constant, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+	/*****************************************************/
+	/* Selects the command and status register of port A */
+	/*****************************************************/
+	outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	 /***********************************/
+	/* Deletes the interrupt of port A */
+	 /***********************************/
+
+	i_RegValue = (i_RegValue & 0x0F) | 0x20;
+	outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/*****************************************************/
+	/* Selects the command and status register of port  B */
+	/*****************************************************/
+	outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	 /***********************************/
+	/* Deletes the interrupt of port B */
+	 /***********************************/
+
+	i_RegValue = (i_RegValue & 0x0F) | 0x20;
+	outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+	/*****************************************************/
+	/* Selects the command and status register of timer 1 */
+	/*****************************************************/
+	outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	 /***********************************/
+	/* Deletes the interrupt of timer 1 */
+	 /***********************************/
+
+	i_RegValue = (i_RegValue & 0x0F) | 0x20;
+	outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+	 /*****************************************************/
+	/* Selects the command and status register of timer 2 */
+	/*****************************************************/
+	outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	 /***********************************/
+	/* Deletes the interrupt of timer 2 */
+	 /***********************************/
+
+	i_RegValue = (i_RegValue & 0x0F) | 0x20;
+	outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+	/*****************************************************/
+	/* Selects the command and status register of timer 3 */
+	/*****************************************************/
+	outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	 /***********************************/
+	/* Deletes the interrupt of timer 3 */
+	 /***********************************/
+
+	i_RegValue = (i_RegValue & 0x0F) | 0x20;
+	outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+	 /*************************************************/
+	/* Selects the master interrupt control register */
+	 /*************************************************/
+	outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/**********************************************/
+	/* Authorizes the main interrupt on the board */
+	/**********************************************/
+	outb(0xD0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+      /***************************/
+	/* Enables the PCI interrupt */
+      /*****************************/
+	outl(0x3000, devpriv->i_IobaseAmcc + 0x38);
+	ui_Status = inl(devpriv->i_IobaseAmcc + 0x10);
+	ui_Status = inl(devpriv->i_IobaseAmcc + 0x38);
+	outl(0x23000, devpriv->i_IobaseAmcc + 0x38);
+
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : static void v_APCI1500_Interrupt					     |
+|					  (int irq , void *d)      |
++----------------------------------------------------------------------------+
+| Task              : Interrupt handler                                      |
++----------------------------------------------------------------------------+
+| Input Parameters  : int irq                 : irq number                   |
+|                     void *d                 : void pointer                 |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+static void v_APCI1500_Interrupt(int irq, void *d)
+{
+
+	struct comedi_device *dev = d;
+	UINT ui_InterruptStatus = 0;
+	int i_RegValue = 0;
+	i_InterruptMask = 0;
+
+ /***********************************/
+	/* Read the board interrupt status */
+ /***********************************/
+	ui_InterruptStatus = inl(devpriv->i_IobaseAmcc + 0x38);
+
+  /***************************************/
+	/* Test if board generated a interrupt */
+  /***************************************/
+	if ((ui_InterruptStatus & 0x800000) == 0x800000) {
+      /************************/
+		/* Disable all Interrupt */
+      /************************/
+      /*************************************************/
+		/* Selects the master interrupt control register */
+      /*************************************************/
+		//outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+	/**********************************************/
+		/* Disables  the main interrupt on the board */
+	/**********************************************/
+		//outb(0x00,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+   /*****************************************************/
+		/* Selects the command and status register of port A */
+   /*****************************************************/
+		outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+			devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+		i_RegValue =
+			inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+		if ((i_RegValue & 0x60) == 0x60) {
+	   /*****************************************************/
+			/* Selects the command and status register of port A */
+	   /*****************************************************/
+			outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+	    /***********************************/
+			/* Deletes the interrupt of port A */
+	    /***********************************/
+			i_RegValue = (i_RegValue & 0x0F) | 0x20;
+			outb(i_RegValue,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			i_InterruptMask = i_InterruptMask | 1;
+			if (i_Logic == APCI1500_OR_PRIORITY) {
+				outb(APCI1500_RW_PORT_A_SPECIFICATION,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+				i_RegValue =
+					inb(devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+	      /***************************************************/
+				/* Selects the interrupt vector register of port A */
+	      /***************************************************/
+				outb(APCI1500_RW_PORT_A_INTERRUPT_CONTROL,
+					devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+				i_RegValue =
+					inb(devpriv->iobase +
+					APCI1500_Z8536_CONTROL_REGISTER);
+
+				i_InputChannel = 1 + (i_RegValue >> 1);
+
+			}	// if(i_Logic==APCI1500_OR_PRIORITY)
+			else {
+				i_InputChannel = 0;
+			}	//elseif(i_Logic==APCI1500_OR_PRIORITY)
+		}		// if ((i_RegValue & 0x60) == 0x60)
+
+	   /*****************************************************/
+		/* Selects the command and status register of port B */
+	   /*****************************************************/
+		outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+			devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+		i_RegValue =
+			inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+		if ((i_RegValue & 0x60) == 0x60) {
+	     /*****************************************************/
+			/* Selects the command and status register of port B */
+	     /*****************************************************/
+			outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+	     /***********************************/
+			/* Deletes the interrupt of port B */
+	     /***********************************/
+			i_RegValue = (i_RegValue & 0x0F) | 0x20;
+			outb(i_RegValue,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			printk("\n\n\n");
+	     /****************/
+			/* Reads port B */
+	     /****************/
+			i_RegValue =
+				inb((UINT) devpriv->iobase +
+				APCI1500_Z8536_PORT_B);
+
+			i_RegValue = i_RegValue & 0xC0;
+	      /**************************************/
+			/* Tests if this is an external error */
+	      /**************************************/
+
+			if (i_RegValue) {
+				//Disable the interrupt
+		     /*****************************************************/
+				/* Selects the command and status register of port B */
+		     /*****************************************************/
+				outl(0x0, devpriv->i_IobaseAmcc + 0x38);
+
+				if (i_RegValue & 0x80) {
+					i_InterruptMask =
+						i_InterruptMask | 0x40;
+				}	//if (i_RegValue & 0x80)
+
+				if (i_RegValue & 0x40) {
+					i_InterruptMask =
+						i_InterruptMask | 0x80;
+				}	//if (i_RegValue & 0x40)
+			}	// if (i_RegValue)
+			else {
+				i_InterruptMask = i_InterruptMask | 2;
+			}	// if (i_RegValue)
+		}		//if ((i_RegValue & 0x60) == 0x60)
+
+		/*****************************************************/
+		/* Selects the command and status register of timer 1 */
+		/*****************************************************/
+		outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+			devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+		i_RegValue =
+			inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+		if ((i_RegValue & 0x60) == 0x60) {
+		   /*****************************************************/
+			/* Selects the command and status register of timer 1 */
+		   /*****************************************************/
+			outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+		   /***********************************/
+			/* Deletes the interrupt of timer 1 */
+		   /***********************************/
+			i_RegValue = (i_RegValue & 0x0F) | 0x20;
+			outb(i_RegValue,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			i_InterruptMask = i_InterruptMask | 4;
+		}		// if ((i_RegValue & 0x60) == 0x60)
+		/*****************************************************/
+		/* Selects the command and status register of timer 2 */
+		/*****************************************************/
+		outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+			devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+		i_RegValue =
+			inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+		if ((i_RegValue & 0x60) == 0x60) {
+		   /*****************************************************/
+			/* Selects the command and status register of timer 2 */
+		   /*****************************************************/
+			outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+		   /***********************************/
+			/* Deletes the interrupt of timer 2 */
+		   /***********************************/
+			i_RegValue = (i_RegValue & 0x0F) | 0x20;
+			outb(i_RegValue,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			i_InterruptMask = i_InterruptMask | 8;
+		}		// if ((i_RegValue & 0x60) == 0x60)
+
+		/*****************************************************/
+		/* Selects the command and status register of timer 3 */
+		/*****************************************************/
+		outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+			devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+		i_RegValue =
+			inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+		if ((i_RegValue & 0x60) == 0x60) {
+		   /*****************************************************/
+			/* Selects the command and status register of timer 3 */
+		   /*****************************************************/
+			outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+		   /***********************************/
+			/* Deletes the interrupt of timer 3 */
+		   /***********************************/
+			i_RegValue = (i_RegValue & 0x0F) | 0x20;
+			outb(i_RegValue,
+				devpriv->iobase +
+				APCI1500_Z8536_CONTROL_REGISTER);
+			if (i_CounterLogic == APCI1500_COUNTER) {
+				i_InterruptMask = i_InterruptMask | 0x10;
+			}	//if(i_CounterLogic==APCI1500_COUNTER)
+			else {
+				i_InterruptMask = i_InterruptMask | 0x20;
+			}
+		}		// if ((i_RegValue & 0x60) == 0x60)
+
+		send_sig(SIGIO, devpriv->tsk_Current, 0);	// send signal to the sample
+	       /***********************/
+		/* Enable all Interrupts */
+	       /***********************/
+
+	       /*************************************************/
+		/* Selects the master interrupt control register */
+	       /*************************************************/
+		outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
+			devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	       /**********************************************/
+		/* Authorizes the main interrupt on the board */
+	       /**********************************************/
+		outb(0xD0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	}			//  if ((ui_InterruptStatus & 0x800000) == 0x800000)
+	else {
+		printk("\nInterrupt from unknown source\n");
+
+	}			//else if ((ui_InterruptStatus & 0x800000) == 0x800000)
+	return;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1500_Reset(struct comedi_device *dev)               |                                                       |
++----------------------------------------------------------------------------+
+| Task              :resets all the registers                                |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      :                                                        |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1500_Reset(struct comedi_device * dev)
+{
+	int i_DummyRead = 0;
+	i_TimerCounter1Init = 0;
+	i_TimerCounter2Init = 0;
+	i_WatchdogCounter3Init = 0;
+	i_Event1Status = 0;
+	i_Event2Status = 0;
+	i_TimerCounterWatchdogInterrupt = 0;
+	i_Logic = 0;
+	i_CounterLogic = 0;
+	i_InterruptMask = 0;
+	i_InputChannel = 0;;
+	i_TimerCounter1Enabled = 0;
+	i_TimerCounter2Enabled = 0;
+	i_WatchdogCounter3Enabled = 0;
+
+    /******************/
+	/* Software reset */
+    /******************/
+	i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	outb(1, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+	/* Selects the master configuration control register */
+ /*****************************************************/
+	outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	outb(0xF4, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+	/*****************************************************/
+	/* Selects the mode specification register of port A */
+	/*****************************************************/
+	outb(APCI1500_RW_PORT_A_SPECIFICATION,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+	/* Selects the data path polarity register of port A */
+	outb(APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* High level of port A means 1 */
+	outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+	/* Selects the data direction register of port A */
+	outb(APCI1500_RW_PORT_A_DATA_DIRECTION,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* All bits used as inputs */
+	outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Selects the command and status register of port A */
+	outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deletes IP and IUS */
+	outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/*  Selects the command and status register of port A */
+	outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deactivates the interrupt management of port A:  */
+	outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Selects the handshake specification register of port A */
+	outb(APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deletes the register */
+	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+	 /*****************************************************/
+	/* Selects the mode specification register of port B */
+	 /*****************************************************/
+	outb(APCI1500_RW_PORT_B_SPECIFICATION,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Selects the data path polarity register of port B */
+	outb(APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* A high level of port B means 1 */
+	outb(0x7F, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Selects the data direction register of port B */
+	outb(APCI1500_RW_PORT_B_DATA_DIRECTION,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* All bits used as inputs */
+	outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Selects the command and status register of port B */
+	outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deletes IP and IUS */
+	outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Selects the command and status register of port B */
+	outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deactivates the interrupt management of port B:         */
+	outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Selects the handshake specification register of port B */
+	outb(APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deletes the register */
+	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+	   /*****************************************************/
+	/* Selects the data path polarity register of port C */
+	   /*****************************************************/
+	outb(APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* High level of port C means 1 */
+	outb(0x9, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Selects the data direction register of port C */
+	outb(APCI1500_RW_PORT_C_DATA_DIRECTION,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* All bits used as inputs except channel 1 */
+	outb(0x0E, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Selects the special IO register of port C */
+	outb(APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deletes it */
+	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	   /******************************************************/
+	/* Selects the command and status register of timer 1 */
+	   /******************************************************/
+	outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deletes IP and IUS */
+	outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Selects the command and status register of timer 1 */
+	outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deactivates the interrupt management of timer 1         */
+	outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	   /******************************************************/
+	/* Selects the command and status register of timer 2 */
+	   /******************************************************/
+	outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deletes IP and IUS */
+	outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Selects the command and status register of timer 2 */
+	outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deactivates Timer 2 interrupt management:               */
+	outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	  /******************************************************/
+	/* Selects the command and status register of timer 3 */
+	  /******************************************************/
+	outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deletes IP and IUS */
+	outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Selects the command and status register of Timer 3 */
+	outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deactivates interrupt management of timer 3:            */
+	outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	 /*************************************************/
+	/* Selects the master interrupt control register */
+	 /*************************************************/
+	outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	/* Deletes all interrupts */
+	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	//reset all the digital outputs
+	outw(0x0, devpriv->i_IobaseAddon + APCI1500_DIGITAL_OP);
+/*******************************/
+/* Disable the board interrupt */
+/*******************************/
+ /*************************************************/
+	/* Selects the master interrupt control register */
+ /*************************************************/
+	outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/****************************/
+/* Deactivates all interrupts */
+/******************************/
+	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************************/
+	/* Selects the command and status register of port A */
+ /*****************************************************/
+	outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/****************************/
+/* Deactivates all interrupts */
+/******************************/
+	outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/*****************************************************/
+	/* Selects the command and status register of port B */
+ /*****************************************************/
+	outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/****************************/
+/* Deactivates all interrupts */
+/******************************/
+	outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/*****************************************************/
+	/* Selects the command and status register of timer 1 */
+ /*****************************************************/
+	outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/****************************/
+/* Deactivates all interrupts */
+/******************************/
+	outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/*****************************************************/
+	/* Selects the command and status register of timer 2 */
+ /*****************************************************/
+	outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/****************************/
+/* Deactivates all interrupts */
+/******************************/
+	outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/*****************************************************/
+/* Selects the command and status register of timer 3*/
+/*****************************************************/
+	outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/****************************/
+/* Deactivates all interrupts */
+/******************************/
+	outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h
new file mode 100644
index 0000000..5d960b4
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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.
+ */
+
+/*********      Definitions for APCI-1500 card  *****/
+
+// Card Specific information
+#define APCI1500_BOARD_VENDOR_ID           0x10e8
+#define APCI1500_ADDRESS_RANGE              4
+
+//DIGITAL INPUT-OUTPUT DEFINE
+
+#define  APCI1500_DIGITAL_OP                 	2
+#define  APCI1500_DIGITAL_IP                    0
+#define  APCI1500_AND               		    2
+#define  APCI1500_OR                		    4
+#define  APCI1500_OR_PRIORITY       		    6
+#define  APCI1500_CLK_SELECT                    0
+#define  COUNTER1                               0
+#define  COUNTER2                               1
+#define  COUNTER3                               2
+#define  APCI1500_COUNTER                		0x20
+#define  APCI1500_TIMER                  		0
+#define  APCI1500_WATCHDOG          		    0
+#define  APCI1500_SINGLE            		    0
+#define  APCI1500_CONTINUOUS        		    0x80
+#define  APCI1500_DISABLE                		0
+#define  APCI1500_ENABLE                		1
+#define  APCI1500_SOFTWARE_TRIGGER  		    0x4
+#define  APCI1500_HARDWARE_TRIGGER  		    0x10
+#define  APCI1500_SOFTWARE_GATE     		    0
+#define  APCI1500_HARDWARE_GATE     		    0x8
+#define  START                       		    0
+#define  STOP                       		    1
+#define  TRIGGER                       		    2
+
+/*
+ * Zillog I/O enumeration
+ */
+enum {
+	APCI1500_Z8536_PORT_C,
+	APCI1500_Z8536_PORT_B,
+	APCI1500_Z8536_PORT_A,
+	APCI1500_Z8536_CONTROL_REGISTER
+};
+
+/*
+ * Z8536 CIO Internal Address
+ */
+enum {
+	APCI1500_RW_MASTER_INTERRUPT_CONTROL,
+	APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+	APCI1500_RW_PORT_A_INTERRUPT_CONTROL,
+	APCI1500_RW_PORT_B_INTERRUPT_CONTROL,
+	APCI1500_RW_TIMER_COUNTER_INTERRUPT_VECTOR,
+	APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,
+	APCI1500_RW_PORT_C_DATA_DIRECTION,
+	APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,
+
+	APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+	APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+	APCI1500_RW_CPT_TMR1_CMD_STATUS,
+	APCI1500_RW_CPT_TMR2_CMD_STATUS,
+	APCI1500_RW_CPT_TMR3_CMD_STATUS,
+	APCI1500_RW_PORT_A_DATA,
+	APCI1500_RW_PORT_B_DATA,
+	APCI1500_RW_PORT_C_DATA,
+
+	APCI1500_R_CPT_TMR1_VALUE_HIGH,
+	APCI1500_R_CPT_TMR1_VALUE_LOW,
+	APCI1500_R_CPT_TMR2_VALUE_HIGH,
+	APCI1500_R_CPT_TMR2_VALUE_LOW,
+	APCI1500_R_CPT_TMR3_VALUE_HIGH,
+	APCI1500_R_CPT_TMR3_VALUE_LOW,
+	APCI1500_RW_CPT_TMR1_TIME_CST_HIGH,
+	APCI1500_RW_CPT_TMR1_TIME_CST_LOW,
+	APCI1500_RW_CPT_TMR2_TIME_CST_HIGH,
+	APCI1500_RW_CPT_TMR2_TIME_CST_LOW,
+	APCI1500_RW_CPT_TMR3_TIME_CST_HIGH,
+	APCI1500_RW_CPT_TMR3_TIME_CST_LOW,
+	APCI1500_RW_CPT_TMR1_MODE_SPECIFICATION,
+	APCI1500_RW_CPT_TMR2_MODE_SPECIFICATION,
+	APCI1500_RW_CPT_TMR3_MODE_SPECIFICATION,
+	APCI1500_R_CURRENT_VECTOR,
+
+	APCI1500_RW_PORT_A_SPECIFICATION,
+	APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,
+	APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,
+	APCI1500_RW_PORT_A_DATA_DIRECTION,
+	APCI1500_RW_PORT_A_SPECIAL_IO_CONTROL,
+	APCI1500_RW_PORT_A_PATTERN_POLARITY,
+	APCI1500_RW_PORT_A_PATTERN_TRANSITION,
+	APCI1500_RW_PORT_A_PATTERN_MASK,
+
+	APCI1500_RW_PORT_B_SPECIFICATION,
+	APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,
+	APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,
+	APCI1500_RW_PORT_B_DATA_DIRECTION,
+	APCI1500_RW_PORT_B_SPECIAL_IO_CONTROL,
+	APCI1500_RW_PORT_B_PATTERN_POLARITY,
+	APCI1500_RW_PORT_B_PATTERN_TRANSITION,
+	APCI1500_RW_PORT_B_PATTERN_MASK
+};
+
+ /*----------DIGITAL INPUT----------------*/
+static int i_APCI1500_Initialisation(struct comedi_device *dev, struct comedi_subdevice *s,
+				     struct comedi_insn *insn, unsigned int *data);
+static int i_APCI1500_ConfigDigitalInputEvent(struct comedi_device *dev,
+					      struct comedi_subdevice *s,
+					      struct comedi_insn *insn,
+					      unsigned int *data);
+
+static int i_APCI1500_StartStopInputEvent(struct comedi_device *dev,
+					  struct comedi_subdevice *s,
+					  struct comedi_insn *insn, unsigned int *data);
+static int i_APCI1500_ReadMoreDigitalInput(struct comedi_device *dev,
+					   struct comedi_subdevice *s,
+					   struct comedi_insn *insn, unsigned int *data);
+
+/*----------	DIGITAL OUTPUT------------*/
+static int i_APCI1500_ConfigDigitalOutputErrorInterrupt(struct comedi_device *dev,
+							struct comedi_subdevice *s,
+							struct comedi_insn *insn,
+							unsigned int *data);
+static int i_APCI1500_WriteDigitalOutput(struct comedi_device *dev,
+					 struct comedi_subdevice *s,
+					 struct comedi_insn *insn, unsigned int *data);
+
+/*----------TIMER----------------*/
+static int i_APCI1500_ConfigCounterTimerWatchdog(struct comedi_device *dev,
+						 struct comedi_subdevice *s,
+						 struct comedi_insn *insn,
+						 unsigned int *data);
+static int i_APCI1500_StartStopTriggerTimerCounterWatchdog(struct comedi_device *dev,
+							   struct comedi_subdevice *s,
+							   struct comedi_insn *insn,
+							   unsigned int *data);
+static int i_APCI1500_ReadCounterTimerWatchdog(struct comedi_device *dev,
+					       struct comedi_subdevice *s,
+					       struct comedi_insn *insn,
+					       unsigned int *data);
+static int i_APCI1500_ReadInterruptMask(struct comedi_device *dev,
+					struct comedi_subdevice *s,
+					struct comedi_insn *insn, unsigned int *data);
+
+/*----------INTERRUPT HANDLER------*/
+static void v_APCI1500_Interrupt(int irq, void *d);
+static int i_APCI1500_ConfigureInterrupt(struct comedi_device *dev,
+					 struct comedi_subdevice *s,
+					 struct comedi_insn *insn, unsigned int *data);
+/*----------RESET---------------*/
+static int i_APCI1500_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c
new file mode 100644
index 0000000..5ae9a93
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c
@@ -0,0 +1,542 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+
+        ADDI-DATA GmbH
+        Dieselstrasse 3
+        D-77833 Ottersweier
+        Tel: +19(0)7223/9493-0
+        Fax: +49(0)7223/9493-92
+        http://www.addi-data-com
+        info@addi-data.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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+  +-----------------------------------------------------------------------+
+  | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
+  +-----------------------------------------------------------------------+
+  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
+  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
+  +-------------------------------+---------------------------------------+
+  | Project     : APCI-1516       | Compiler   : GCC                      |
+  | Module name : hwdrv_apci1516.c| Version    : 2.96                     |
+  +-------------------------------+---------------------------------------+
+  | Project manager: Eric Stolz   | Date       :  02/12/2002              |
+  +-------------------------------+---------------------------------------+
+  | Description :   Hardware Layer Acces For APCI-1516                    |
+  +-----------------------------------------------------------------------+
+  |                             UPDATES                                   |
+  +----------+-----------+------------------------------------------------+
+  |   Date   |   Author  |          Description of updates                |
+  +----------+-----------+------------------------------------------------+
+  |          |           |                                                |
+  |          |           |                                                |
+  |          |           |                                                |
+  +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+|                               Included files                               |
++----------------------------------------------------------------------------+
+*/
+#include "hwdrv_apci1516.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1516_Read1DigitalInput                       |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Return the status of the digital input                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|		       struct comedi_subdevice *s,   :pointer to subdevice structure
+                       struct comedi_insn *insn      :pointer to insn structure     |
+|                     unsigned int *data          : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1516_Read1DigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_TmpValue = 0;
+	UINT ui_Channel;
+	ui_Channel = CR_CHAN(insn->chanspec);
+	if (ui_Channel >= 0 && ui_Channel <= 7) {
+		ui_TmpValue = (UINT) inw(devpriv->iobase + APCI1516_DIGITAL_IP);
+		//  since only 1 channel reqd  to bring it to last bit it is rotated
+		//  8 +(chan - 1) times then ANDed with 1 for last bit.
+		*data = (ui_TmpValue >> ui_Channel) & 0x1;
+	}			//if(ui_Channel >= 0 && ui_Channel <=7)
+	else {
+		//comedi_error(dev," \n chan spec wrong\n");
+		return -EINVAL;	// "sorry channel spec wrong "
+	}			//else if(ui_Channel >= 0 && ui_Channel <=7)
+
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1516_ReadMoreDigitalInput                    |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                     struct comedi_insn *insn,unsigned int *data)                      |
++----------------------------------------------------------------------------+
+| Task              : Return the status of the Requested digital inputs      |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                      struct comedi_subdevice *s,   :pointer to subdevice structure
+                       struct comedi_insn *insn      :pointer to insn structure     |
+|                      unsigned int *data         : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1516_ReadMoreDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+
+	UINT ui_PortValue = data[0];
+	UINT ui_Mask = 0;
+	UINT ui_NoOfChannels;
+
+	ui_NoOfChannels = CR_CHAN(insn->chanspec);
+
+	*data = (UINT) inw(devpriv->iobase + APCI1516_DIGITAL_IP);
+	switch (ui_NoOfChannels) {
+	case 2:
+		ui_Mask = 3;
+		*data = (*data >> (2 * ui_PortValue)) & ui_Mask;
+		break;
+	case 4:
+		ui_Mask = 15;
+		*data = (*data >> (4 * ui_PortValue)) & ui_Mask;
+		break;
+	case 7:
+		break;
+
+	default:
+		printk("\nWrong parameters\n");
+		return -EINVAL;	// "sorry channel spec wrong "
+		break;
+	}			//switch(ui_NoOfChannels)
+
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1516_ConfigDigitalOutput (struct comedi_device *dev,
+                    struct comedi_subdevice *s struct comedi_insn *insn,unsigned int *data)    |
+|				                                                     |
++----------------------------------------------------------------------------+
+| Task              : Configures The Digital Output Subdevice.               |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev : Driver handle                     |
+|                     unsigned int *data         : Data Pointer contains         |
+|                                          configuration parameters as below |
+|                      struct comedi_subdevice *s,   :pointer to subdevice structure
+                       struct comedi_insn *insn      :pointer to insn structure                                                           |
+|					  data[0]  :1:Memory on                          |
+|					            0:Memory off                         |
+|										                             |
+|																	 |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+int i_APCI1516_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	devpriv->b_OutputMemoryStatus = data[0];
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1516_WriteDigitalOutput                      |
+|			(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+                     unsigned int *data)                                         |
++----------------------------------------------------------------------------+
+| Task              : Writes port value  To the selected port                |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                     struct comedi_subdevice *s,   :pointer to subdevice structure
+                      struct comedi_insn *insn      :pointer to insn structure      |
+|                    unsigned int *data           : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1516_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_Temp, ui_Temp1;
+	UINT ui_NoOfChannel = CR_CHAN(insn->chanspec);	// get the channel
+
+	printk("EL311003 : @=%x\n", devpriv->iobase + APCI1516_DIGITAL_OP);
+
+	if (devpriv->b_OutputMemoryStatus) {
+		ui_Temp = inw(devpriv->iobase + APCI1516_DIGITAL_OP);
+
+	}			//if(devpriv->b_OutputMemoryStatus )
+	else {
+		ui_Temp = 0;
+	}			//if(devpriv->b_OutputMemoryStatus )
+	if (data[3] == 0) {
+		if (data[1] == 0) {
+			data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
+			outw(data[0], devpriv->iobase + APCI1516_DIGITAL_OP);
+
+			printk("EL311003 : d=%d @=%x\n", data[0],
+				devpriv->iobase + APCI1516_DIGITAL_OP);
+
+		}		//if(data[1]==0)
+		else {
+			if (data[1] == 1) {
+				switch (ui_NoOfChannel) {
+
+				case 2:
+					data[0] =
+						(data[0] << (2 *
+							data[2])) | ui_Temp;
+					break;
+
+				case 4:
+					data[0] =
+						(data[0] << (4 *
+							data[2])) | ui_Temp;
+					break;
+
+				case 7:
+					data[0] = data[0] | ui_Temp;
+					break;
+
+				default:
+					comedi_error(dev, " chan spec wrong");
+					return -EINVAL;	// "sorry channel spec wrong "
+
+				}	//switch(ui_NoOfChannels)
+
+				outw(data[0],
+					devpriv->iobase + APCI1516_DIGITAL_OP);
+
+				printk("EL311003 : d=%d @=%x\n", data[0],
+					devpriv->iobase + APCI1516_DIGITAL_OP);
+			}	// if(data[1]==1)
+			else {
+				printk("\nSpecified channel not supported\n");
+			}	//else if(data[1]==1)
+		}		//elseif(data[1]==0)
+	}			//if(data[3]==0)
+	else {
+		if (data[3] == 1) {
+			if (data[1] == 0) {
+				data[0] = ~data[0] & 0x1;
+				ui_Temp1 = 1;
+				ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+				ui_Temp = ui_Temp | ui_Temp1;
+				data[0] = (data[0] << ui_NoOfChannel) ^ 0xff;
+				data[0] = data[0] & ui_Temp;
+				outw(data[0],
+					devpriv->iobase + APCI1516_DIGITAL_OP);
+
+				printk("EL311003 : d=%d @=%x\n", data[0],
+					devpriv->iobase + APCI1516_DIGITAL_OP);
+
+			}	//if(data[1]==0)
+			else {
+				if (data[1] == 1) {
+					switch (ui_NoOfChannel) {
+
+					case 2:
+						data[0] = ~data[0] & 0x3;
+						ui_Temp1 = 3;
+						ui_Temp1 =
+							ui_Temp1 << 2 * data[2];
+						ui_Temp = ui_Temp | ui_Temp1;
+						data[0] =
+							((data[0] << (2 *
+									data
+									[2])) ^
+							0xff) & ui_Temp;
+						break;
+
+					case 4:
+						data[0] = ~data[0] & 0xf;
+						ui_Temp1 = 15;
+						ui_Temp1 =
+							ui_Temp1 << 4 * data[2];
+						ui_Temp = ui_Temp | ui_Temp1;
+						data[0] =
+							((data[0] << (4 *
+									data
+									[2])) ^
+							0xff) & ui_Temp;
+						break;
+
+					case 7:
+						break;
+
+					default:
+						comedi_error(dev,
+							" chan spec wrong");
+						return -EINVAL;	// "sorry channel spec wrong "
+
+					}	//switch(ui_NoOfChannels)
+
+					outw(data[0],
+						devpriv->iobase +
+						APCI1516_DIGITAL_OP);
+
+					printk("EL311003 : d=%d @=%x\n",
+						data[0],
+						devpriv->iobase +
+						APCI1516_DIGITAL_OP);
+				}	// if(data[1]==1)
+				else {
+					printk("\nSpecified channel not supported\n");
+				}	//else if(data[1]==1)
+			}	//elseif(data[1]==0)
+		}		//if(data[3]==1);
+		else {
+			printk("\nSpecified functionality does not exist\n");
+			return -EINVAL;
+		}		//if else data[3]==1)
+	}			//if else data[3]==0)
+	return (insn->n);;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1516_ReadDigitalOutput                       |
+|			(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+                    unsigned int *data) 	                                     |
++----------------------------------------------------------------------------+
+| Task              : Read  value  of the selected channel or port           |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                     struct comedi_subdevice *s,   :pointer to subdevice structure
+                      struct comedi_insn *insn      :pointer to insn structure      |
+|                     unsigned int *data          : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1516_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+
+	UINT ui_Temp;
+	UINT ui_NoOfChannel = CR_CHAN(insn->chanspec);	// get the channel
+	ui_Temp = data[0];
+	*data = inw(devpriv->iobase + APCI1516_DIGITAL_OP_RW);
+	if (ui_Temp == 0) {
+		*data = (*data >> ui_NoOfChannel) & 0x1;
+	}			//if(ui_Temp==0)
+	else {
+		if (ui_Temp == 1) {
+			switch (ui_NoOfChannel) {
+
+			case 2:
+				*data = (*data >> (2 * data[1])) & 3;
+				break;
+
+			case 4:
+				*data = (*data >> (4 * data[1])) & 15;
+				break;
+
+			case 7:
+				break;
+
+			default:
+				comedi_error(dev, " chan spec wrong");
+				return -EINVAL;	// "sorry channel spec wrong "
+
+			}	//switch(ui_NoOfChannels)
+		}		//if(ui_Temp==1)
+		else {
+			printk("\nSpecified channel not supported \n");
+		}		//elseif(ui_Temp==1)
+	}			//elseif(ui_Temp==0)
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1516_ConfigWatchdog(struct comedi_device *dev,
+                      struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)  |
+|				                                                     |
++----------------------------------------------------------------------------+
+| Task              : Configures The Watchdog                                |
++----------------------------------------------------------------------------+
+| Input Parameters  :   struct comedi_device *dev      : Driver handle              |
+|                     struct comedi_subdevice *s,   :pointer to subdevice structure
+                      struct comedi_insn *insn      :pointer to insn structure      |
+|                     unsigned int *data          : Data Pointer to read status                                                     |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI1516_ConfigWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (data[0] == 0) {
+		//Disable the watchdog
+		outw(0x0,
+			devpriv->i_IobaseAddon +
+			APCI1516_WATCHDOG_ENABLEDISABLE);
+		//Loading the Reload value
+		outw(data[1],
+			devpriv->i_IobaseAddon +
+			APCI1516_WATCHDOG_RELOAD_VALUE);
+		data[1] = data[1] >> 16;
+		outw(data[1],
+			devpriv->i_IobaseAddon +
+			APCI1516_WATCHDOG_RELOAD_VALUE + 2);
+	}			//if(data[0]==0)
+	else {
+		printk("\nThe input parameters are wrong\n");
+		return -EINVAL;
+	}			//elseif(data[0]==0)
+
+	return insn->n;
+}
+
+ /*
+    +----------------------------------------------------------------------------+
+    | Function   Name   : int i_APCI1516_StartStopWriteWatchdog                  |
+    |                           (struct comedi_device *dev,struct comedi_subdevice *s,
+    struct comedi_insn *insn,unsigned int *data);                      |
+    +----------------------------------------------------------------------------+
+    | Task              : Start / Stop The Watchdog                              |
+    +----------------------------------------------------------------------------+
+    | Input Parameters  : struct comedi_device *dev      : Driver handle                |
+    |                     struct comedi_subdevice *s,   :pointer to subdevice structure
+    struct comedi_insn *insn      :pointer to insn structure      |
+    |                     unsigned int *data          : Data Pointer to read status  |
+    +----------------------------------------------------------------------------+
+    | Output Parameters :       --                                                                                                       |
+    +----------------------------------------------------------------------------+
+    | Return Value      : TRUE  : No error occur                                 |
+    |                       : FALSE : Error occur. Return the error          |
+    |                                                                            |
+    +----------------------------------------------------------------------------+
+  */
+
+int i_APCI1516_StartStopWriteWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	switch (data[0]) {
+	case 0:		//stop the watchdog
+		outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_ENABLEDISABLE);	//disable the watchdog
+		break;
+	case 1:		//start the watchdog
+		outw(0x0001,
+			devpriv->i_IobaseAddon +
+			APCI1516_WATCHDOG_ENABLEDISABLE);
+		break;
+	case 2:		//Software trigger
+		outw(0x0201,
+			devpriv->i_IobaseAddon +
+			APCI1516_WATCHDOG_ENABLEDISABLE);
+		break;
+	default:
+		printk("\nSpecified functionality does not exist\n");
+		return -EINVAL;
+	}			// switch(data[0])
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1516_ReadWatchdog                            |
+|			(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+                    unsigned int *data); 	                                     |
++----------------------------------------------------------------------------+
+| Task              : Read The Watchdog                                      |
++----------------------------------------------------------------------------+
+| Input Parameters  :   struct comedi_device *dev      : Driver handle              |
+|                     struct comedi_subdevice *s,   :pointer to subdevice structure
+                      struct comedi_insn *insn      :pointer to insn structure      |
+|                     unsigned int *data          : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI1516_ReadWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	data[0] = inw(devpriv->i_IobaseAddon + APCI1516_WATCHDOG_STATUS) & 0x1;
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1516_Reset(struct comedi_device *dev)               |                                                                                                          |
++----------------------------------------------------------------------------+
+| Task              :resets all the registers                                |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      :                                                        |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1516_Reset(struct comedi_device * dev)
+{
+	outw(0x0, devpriv->iobase + APCI1516_DIGITAL_OP);	//RESETS THE DIGITAL OUTPUTS
+	outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_ENABLEDISABLE);
+	outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_RELOAD_VALUE);
+	outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_RELOAD_VALUE + 2);
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h
new file mode 100644
index 0000000..398baa0
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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.
+ */
+
+/*********      Definitions for APCI-1516 card  *****/
+
+// Card Specific information
+#define APCI1516_BOARD_VENDOR_ID                 0x15B8
+#define APCI1516_ADDRESS_RANGE                   8
+
+//DIGITAL INPUT-OUTPUT DEFINE
+
+#define APCI1516_DIGITAL_OP                 	4
+#define APCI1516_DIGITAL_OP_RW                 	4
+#define APCI1516_DIGITAL_IP                     0
+
+// TIMER COUNTER WATCHDOG DEFINES
+
+#define ADDIDATA_WATCHDOG                          2
+#define APCI1516_DIGITAL_OP_WATCHDOG               0
+#define APCI1516_WATCHDOG_ENABLEDISABLE            12
+#define APCI1516_WATCHDOG_RELOAD_VALUE             4
+#define APCI1516_WATCHDOG_STATUS                   16
+
+// Hardware Layer  functions for Apci1516
+
+//Digital Input
+INT i_APCI1516_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+				    struct comedi_insn *insn, unsigned int *data);
+INT i_APCI1516_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data);
+
+//Digital Output
+int i_APCI1516_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+				   struct comedi_insn *insn, unsigned int *data);
+INT i_APCI1516_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+				  struct comedi_insn *insn, unsigned int *data);
+INT i_APCI1516_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data);
+
+// TIMER
+// timer value is passed as u seconds
+int i_APCI1516_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+			      struct comedi_insn *insn, unsigned int *data);
+int i_APCI1516_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+				      struct comedi_insn *insn, unsigned int *data);
+int i_APCI1516_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+			    struct comedi_insn *insn, unsigned int *data);
+
+//reset
+INT i_APCI1516_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
new file mode 100644
index 0000000..a6b504c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
@@ -0,0 +1,1105 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+
+        ADDI-DATA GmbH
+        Dieselstrasse 3
+        D-77833 Ottersweier
+        Tel: +19(0)7223/9493-0
+        Fax: +49(0)7223/9493-92
+        http://www.addi-data-com
+        info@addi-data.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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+  +-----------------------------------------------------------------------+
+  | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
+  +-----------------------------------------------------------------------+
+  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
+  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
+  +-------------------------------+---------------------------------------+
+  | Project     : APCI-1564       | Compiler   : GCC                      |
+  | Module name : hwdrv_apci1564.c| Version    : 2.96                     |
+  +-------------------------------+---------------------------------------+
+  | Project manager: Eric Stolz   | Date       :  02/12/2002              |
+  +-------------------------------+---------------------------------------+
+  | Description :   Hardware Layer Acces For APCI-1564                    |
+  +-----------------------------------------------------------------------+
+  |                             UPDATES                                   |
+  +----------+-----------+------------------------------------------------+
+  |   Date   |   Author  |          Description of updates                |
+  +----------+-----------+------------------------------------------------+
+  |          |           |                                                |
+  |          |           |                                                |
+  |          |           |                                                |
+  +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+|                               Included files                               |
++----------------------------------------------------------------------------+
+*/
+
+#include <linux/delay.h>
+#include "hwdrv_apci1564.h"
+
+//Global variables
+UINT ui_InterruptStatus_1564 = 0;
+UINT ui_InterruptData, ui_Type;
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1564_ConfigDigitalInput                      |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Configures the digital input Subdevice                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev : Driver handle                     |
+|                     unsigned int *data         : Data Pointer contains         |
+|                                          configuration parameters as below |
+|                                                                            |
+|			  data[0]            : 1 Enable  Digital Input Interrupt |
+|								   0 Disable Digital Input Interrupt |
+|			  data[1]            : 0 ADDIDATA Interrupt OR LOGIC	 |
+|								 : 1 ADDIDATA Interrupt AND LOGIC    |
+|			  data[2]			 : Interrupt mask for the mode 1	 |
+|			  data[3]			 : Interrupt mask for the mode 2	 |
+|																	 |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_ConfigDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	devpriv->tsk_Current = current;
+   /*******************************/
+	/* Set the digital input logic */
+   /*******************************/
+	if (data[0] == ADDIDATA_ENABLE) {
+		data[2] = data[2] << 4;
+		data[3] = data[3] << 4;
+		outl(data[2],
+			devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+			APCI1564_DIGITAL_IP_INTERRUPT_MODE1);
+		outl(data[3],
+			devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+			APCI1564_DIGITAL_IP_INTERRUPT_MODE2);
+		if (data[1] == ADDIDATA_OR) {
+			outl(0x4,
+				devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+				APCI1564_DIGITAL_IP_IRQ);
+		}		// if  (data[1] == ADDIDATA_OR)
+		else {
+			outl(0x6,
+				devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+				APCI1564_DIGITAL_IP_IRQ);
+		}		// else if  (data[1] == ADDIDATA_OR)
+	}			// if  (data[0] == ADDIDATA_ENABLE)
+	else {
+		outl(0x0,
+			devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+			APCI1564_DIGITAL_IP_INTERRUPT_MODE1);
+		outl(0x0,
+			devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+			APCI1564_DIGITAL_IP_INTERRUPT_MODE2);
+		outl(0x0,
+			devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+			APCI1564_DIGITAL_IP_IRQ);
+	}			// else if  (data[0] == ADDIDATA_ENABLE)
+
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1564_Read1DigitalInput                       |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Return the status of the digital input                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|		              UINT ui_Channel : Channel number to read       |
+|                     unsigned int *data          : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_Read1DigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_TmpValue = 0;
+	UINT ui_Channel;
+
+	ui_Channel = CR_CHAN(insn->chanspec);
+	if (ui_Channel >= 0 && ui_Channel <= 31) {
+		ui_TmpValue =
+			(UINT) inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP);
+		//  since only 1 channel reqd  to bring it to last bit it is rotated
+		//  8 +(chan - 1) times then ANDed with 1 for last bit.
+		*data = (ui_TmpValue >> ui_Channel) & 0x1;
+	}			// if  (ui_Channel >= 0 && ui_Channel <=31)
+	else {
+		comedi_error(dev, "Not a valid channel number !!! \n");
+		return -EINVAL;	// "sorry channel spec wrong "
+	}			//else if  (ui_Channel >= 0 && ui_Channel <=31)
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1564_ReadMoreDigitalInput                    |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                     struct comedi_insn *insn,unsigned int *data)                      |
++----------------------------------------------------------------------------+
+| Task              : Return the status of the Requested digital inputs      |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                     UINT ui_NoOfChannels    : No Of Channels To be Read    |
+|                      UINT *data             : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_ReadMoreDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_PortValue = data[0];
+	UINT ui_Mask = 0;
+	UINT ui_NoOfChannels;
+
+	ui_NoOfChannels = CR_CHAN(insn->chanspec);
+	if (data[1] == 0) {
+		*data = (UINT) inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP);
+		switch (ui_NoOfChannels) {
+		case 2:
+			ui_Mask = 3;
+			*data = (*data >> (2 * ui_PortValue)) & ui_Mask;
+			break;
+		case 4:
+			ui_Mask = 15;
+			*data = (*data >> (4 * ui_PortValue)) & ui_Mask;
+			break;
+		case 8:
+			ui_Mask = 255;
+			*data = (*data >> (8 * ui_PortValue)) & ui_Mask;
+			break;
+		case 16:
+			ui_Mask = 65535;
+			*data = (*data >> (16 * ui_PortValue)) & ui_Mask;
+			break;
+		case 31:
+			break;
+		default:
+			comedi_error(dev, "Not a valid Channel number !!!\n");
+			return -EINVAL;	// "sorry channel spec wrong "
+			break;
+		}		// switch  (ui_NoOfChannels)
+	}			// if  (data[1]==0)
+	else {
+		if (data[1] == 1) {
+			*data = ui_InterruptStatus_1564;
+		}		// if  (data[1]==1)
+	}			// else if  (data[1]==0)
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1564_ConfigDigitalOutput                     |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Configures The Digital Output Subdevice.               |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev : Driver handle                     |
+|                     UINT *data         : Data Pointer contains             |
+|                                          configuration parameters as below |
+|                                                                            |
+|					  data[1]            : 1 Enable  VCC  Interrupt  |
+|										   0 Disable VCC  Interrupt  |
+|					  data[2]            : 1 Enable  CC  Interrupt   |
+|										   0 Disable CC  Interrupt   |
+|																	 |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	ULONG ul_Command = 0;
+
+	if ((data[0] != 0) && (data[0] != 1)) {
+		comedi_error(dev,
+			"Not a valid Data !!! ,Data should be 1 or 0\n");
+		return -EINVAL;
+	}			// if  ((data[0]!=0) && (data[0]!=1))
+	if (data[0]) {
+		devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
+	}			// if  (data[0])
+	else {
+		devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
+	}			// else if  (data[0])
+	if (data[1] == ADDIDATA_ENABLE) {
+		ul_Command = ul_Command | 0x1;
+	}			// if  (data[1] == ADDIDATA_ENABLE)
+	else {
+		ul_Command = ul_Command & 0xFFFFFFFE;
+	}			// else if  (data[1] == ADDIDATA_ENABLE)
+	if (data[2] == ADDIDATA_ENABLE) {
+		ul_Command = ul_Command | 0x2;
+	}			// if  (data[2] == ADDIDATA_ENABLE)
+	else {
+		ul_Command = ul_Command & 0xFFFFFFFD;
+	}			// else if  (data[2] == ADDIDATA_ENABLE)
+	outl(ul_Command,
+		devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+		APCI1564_DIGITAL_OP_INTERRUPT);
+	ui_InterruptData =
+		inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+		APCI1564_DIGITAL_OP_INTERRUPT);
+	devpriv->tsk_Current = current;
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1564_WriteDigitalOutput                      |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Writes port value  To the selected port                |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                     UINT ui_NoOfChannels    : No Of Channels To Write      |
+|                     UINT *data              : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_Temp, ui_Temp1;
+	UINT ui_NoOfChannel;
+
+	ui_NoOfChannel = CR_CHAN(insn->chanspec);
+	if (devpriv->b_OutputMemoryStatus) {
+		ui_Temp =
+			inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+			APCI1564_DIGITAL_OP_RW);
+	}			// if  (devpriv->b_OutputMemoryStatus )
+	else {
+		ui_Temp = 0;
+	}			// else if  (devpriv->b_OutputMemoryStatus )
+	if (data[3] == 0) {
+		if (data[1] == 0) {
+			data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
+			outl(data[0],
+				devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+				APCI1564_DIGITAL_OP_RW);
+		}		// if  (data[1]==0)
+		else {
+			if (data[1] == 1) {
+				switch (ui_NoOfChannel) {
+				case 2:
+					data[0] =
+						(data[0] << (2 *
+							data[2])) | ui_Temp;
+					break;
+				case 4:
+					data[0] =
+						(data[0] << (4 *
+							data[2])) | ui_Temp;
+					break;
+				case 8:
+					data[0] =
+						(data[0] << (8 *
+							data[2])) | ui_Temp;
+					break;
+				case 16:
+					data[0] =
+						(data[0] << (16 *
+							data[2])) | ui_Temp;
+					break;
+				case 31:
+					data[0] = data[0] | ui_Temp;
+					break;
+				default:
+					comedi_error(dev, " chan spec wrong");
+					return -EINVAL;	// "sorry channel spec wrong "
+				}	// switch (ui_NoOfChannels)
+				outl(data[0],
+					devpriv->i_IobaseAmcc +
+					APCI1564_DIGITAL_OP +
+					APCI1564_DIGITAL_OP_RW);
+			}	// if  (data[1]==1)
+			else {
+				printk("\nSpecified channel not supported\n");
+			}	// else if  (data[1]==1)
+		}		// else if (data[1]==0)
+	}			//if(data[3]==0)
+	else {
+		if (data[3] == 1) {
+			if (data[1] == 0) {
+				data[0] = ~data[0] & 0x1;
+				ui_Temp1 = 1;
+				ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+				ui_Temp = ui_Temp | ui_Temp1;
+				data[0] =
+					(data[0] << ui_NoOfChannel) ^
+					0xffffffff;
+				data[0] = data[0] & ui_Temp;
+				outl(data[0],
+					devpriv->i_IobaseAmcc +
+					APCI1564_DIGITAL_OP +
+					APCI1564_DIGITAL_OP_RW);
+			}	// if  (data[1]==0)
+			else {
+				if (data[1] == 1) {
+					switch (ui_NoOfChannel) {
+					case 2:
+						data[0] = ~data[0] & 0x3;
+						ui_Temp1 = 3;
+						ui_Temp1 =
+							ui_Temp1 << 2 * data[2];
+						ui_Temp = ui_Temp | ui_Temp1;
+						data[0] =
+							((data[0] << (2 *
+									data
+									[2])) ^
+							0xffffffff) & ui_Temp;
+						break;
+					case 4:
+						data[0] = ~data[0] & 0xf;
+						ui_Temp1 = 15;
+						ui_Temp1 =
+							ui_Temp1 << 4 * data[2];
+						ui_Temp = ui_Temp | ui_Temp1;
+						data[0] =
+							((data[0] << (4 *
+									data
+									[2])) ^
+							0xffffffff) & ui_Temp;
+						break;
+					case 8:
+						data[0] = ~data[0] & 0xff;
+						ui_Temp1 = 255;
+						ui_Temp1 =
+							ui_Temp1 << 8 * data[2];
+						ui_Temp = ui_Temp | ui_Temp1;
+						data[0] =
+							((data[0] << (8 *
+									data
+									[2])) ^
+							0xffffffff) & ui_Temp;
+						break;
+					case 16:
+						data[0] = ~data[0] & 0xffff;
+						ui_Temp1 = 65535;
+						ui_Temp1 =
+							ui_Temp1 << 16 *
+							data[2];
+						ui_Temp = ui_Temp | ui_Temp1;
+						data[0] =
+							((data[0] << (16 *
+									data
+									[2])) ^
+							0xffffffff) & ui_Temp;
+						break;
+					case 31:
+						break;
+					default:
+						comedi_error(dev,
+							" chan spec wrong");
+						return -EINVAL;	// "sorry channel spec wrong "
+					}	//switch(ui_NoOfChannels)
+					outl(data[0],
+						devpriv->i_IobaseAmcc +
+						APCI1564_DIGITAL_OP +
+						APCI1564_DIGITAL_OP_RW);
+				}	// if  (data[1]==1)
+				else {
+					printk("\nSpecified channel not supported\n");
+				}	// else if  (data[1]==1)
+			}	// else if  (data[1]==0)
+		}		// if  (data[3]==1);
+		else {
+			printk("\nSpecified functionality does not exist\n");
+			return -EINVAL;
+		}		// else if (data[3]==1)
+	}			// else if (data[3]==0)
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1564_ReadDigitalOutput                       |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Read  value  of the selected channel or port           |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                     UINT ui_NoOfChannels    : No Of Channels To read       |
+|                     UINT *data              : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_Temp;
+	UINT ui_NoOfChannel;
+
+	ui_NoOfChannel = CR_CHAN(insn->chanspec);
+	ui_Temp = data[0];
+	*data = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+		APCI1564_DIGITAL_OP_RW);
+	if (ui_Temp == 0) {
+		*data = (*data >> ui_NoOfChannel) & 0x1;
+	}			// if  (ui_Temp==0)
+	else {
+		if (ui_Temp == 1) {
+			switch (ui_NoOfChannel) {
+			case 2:
+				*data = (*data >> (2 * data[1])) & 3;
+				break;
+
+			case 4:
+				*data = (*data >> (4 * data[1])) & 15;
+				break;
+
+			case 8:
+				*data = (*data >> (8 * data[1])) & 255;
+				break;
+
+			case 16:
+				*data = (*data >> (16 * data[1])) & 65535;
+				break;
+
+			case 31:
+				break;
+
+			default:
+				comedi_error(dev, " chan spec wrong");
+				return -EINVAL;	// "sorry channel spec wrong "
+				break;
+			}	// switch(ui_NoOfChannels)
+		}		// if  (ui_Temp==1)
+		else {
+			printk("\nSpecified channel not supported \n");
+		}		// else if (ui_Temp==1)
+	}			// else if  (ui_Temp==0)
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1564_ConfigTimerCounterWatchdog              |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Configures The Timer , Counter or Watchdog             |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev : Driver handle                     |
+|                     UINT *data         : Data Pointer contains             |
+|                                          configuration parameters as below |
+|                                                                            |
+|					  data[0]            : 0 Configure As Timer      |
+|										   1 Configure As Counter    |
+|										   2 Configure As Watchdog   |
+|					  data[1]            : 1 Enable  Interrupt       |
+|										   0 Disable Interrupt 	     |
+|					  data[2]            : Time Unit                 |
+|					  data[3]			 : Reload Value			     |
+|					  data[4]            : Timer Mode             	 |
+|					  data[5]			 : Timer Counter Watchdog Number|
+                              data[6]            :  Counter Direction
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	ULONG ul_Command1 = 0;
+	devpriv->tsk_Current = current;
+	if (data[0] == ADDIDATA_WATCHDOG) {
+		devpriv->b_TimerSelectMode = ADDIDATA_WATCHDOG;
+
+		//Disable the watchdog
+		outl(0x0,
+			devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG +
+			APCI1564_TCW_PROG);
+		//Loading the Reload value
+		outl(data[3],
+			devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG +
+			APCI1564_TCW_RELOAD_VALUE);
+	}			// if  (data[0]==ADDIDATA_WATCHDOG)
+	else if (data[0] == ADDIDATA_TIMER) {
+		//First Stop The Timer
+		ul_Command1 =
+			inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
+			APCI1564_TCW_PROG);
+		ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
+		outl(ul_Command1, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG);	//Stop The Timer
+
+		devpriv->b_TimerSelectMode = ADDIDATA_TIMER;
+		if (data[1] == 1) {
+			outl(0x02, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG);	//Enable TIMER int & DISABLE ALL THE OTHER int SOURCES
+			outl(0x0,
+				devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+				APCI1564_DIGITAL_IP_IRQ);
+			outl(0x0,
+				devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+				APCI1564_DIGITAL_OP_IRQ);
+			outl(0x0,
+				devpriv->i_IobaseAmcc +
+				APCI1564_DIGITAL_OP_WATCHDOG +
+				APCI1564_TCW_IRQ);
+			outl(0x0,
+				devpriv->iobase + APCI1564_COUNTER1 +
+				APCI1564_TCW_IRQ);
+			outl(0x0,
+				devpriv->iobase + APCI1564_COUNTER2 +
+				APCI1564_TCW_IRQ);
+			outl(0x0,
+				devpriv->iobase + APCI1564_COUNTER3 +
+				APCI1564_TCW_IRQ);
+			outl(0x0,
+				devpriv->iobase + APCI1564_COUNTER4 +
+				APCI1564_TCW_IRQ);
+		}		// if  (data[1]==1)
+		else {
+			outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG);	//disable Timer interrupt
+		}		// else if  (data[1]==1)
+
+		// Loading Timebase
+
+		outl(data[2],
+			devpriv->i_IobaseAmcc + APCI1564_TIMER +
+			APCI1564_TCW_TIMEBASE);
+
+		//Loading the Reload value
+		outl(data[3],
+			devpriv->i_IobaseAmcc + APCI1564_TIMER +
+			APCI1564_TCW_RELOAD_VALUE);
+
+		ul_Command1 =
+			inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
+			APCI1564_TCW_PROG);
+		ul_Command1 =
+			(ul_Command1 & 0xFFF719E2UL) | 2UL << 13UL | 0x10UL;
+		outl(ul_Command1, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG);	//mode 2
+	}			// else if  (data[0]==ADDIDATA_TIMER)
+	else if (data[0] == ADDIDATA_COUNTER) {
+		devpriv->b_TimerSelectMode = ADDIDATA_COUNTER;
+		devpriv->b_ModeSelectRegister = data[5];
+
+		//First Stop The Counter
+		ul_Command1 =
+			inl(devpriv->iobase + ((data[5] - 1) * 0x20) +
+			APCI1564_TCW_PROG);
+		ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
+		outl(ul_Command1, devpriv->iobase + ((data[5] - 1) * 0x20) + APCI1564_TCW_PROG);	//Stop The Timer
+
+      /************************/
+		/* Set the reload value */
+      /************************/
+		outl(data[3],
+			devpriv->iobase + ((data[5] - 1) * 0x20) +
+			APCI1564_TCW_RELOAD_VALUE);
+
+      /******************************/
+		/* Set the mode :             */
+		/* - Disable the hardware     */
+		/* - Disable the counter mode */
+		/* - Disable the warning      */
+		/* - Disable the reset        */
+		/* - Disable the timer mode   */
+		/* - Enable the counter mode  */
+      /******************************/
+		ul_Command1 =
+			(ul_Command1 & 0xFFFC19E2UL) | 0x80000UL |
+			(ULONG) ((ULONG) data[4] << 16UL);
+		outl(ul_Command1,
+			devpriv->iobase + ((data[5] - 1) * 0x20) +
+			APCI1564_TCW_PROG);
+
+		// Enable or Disable Interrupt
+		ul_Command1 = (ul_Command1 & 0xFFFFF9FD) | (data[1] << 1);
+		outl(ul_Command1,
+			devpriv->iobase + ((data[5] - 1) * 0x20) +
+			APCI1564_TCW_PROG);
+
+      /*****************************/
+		/* Set the Up/Down selection */
+      /*****************************/
+		ul_Command1 = (ul_Command1 & 0xFFFBF9FFUL) | (data[6] << 18);
+		outl(ul_Command1,
+			devpriv->iobase + ((data[5] - 1) * 0x20) +
+			APCI1564_TCW_PROG);
+	}			// else if  (data[0]==ADDIDATA_COUNTER)
+	else {
+		printk(" Invalid subdevice.");
+	}			// else if  (data[0]==ADDIDATA_WATCHDOG)
+
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1564_StartStopWriteTimerCounterWatchdog      |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Start / Stop The Selected Timer , Counter or Watchdog  |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev : Driver handle                     |
+|                     UINT *data         : Data Pointer contains             |
+|                                          configuration parameters as below |
+|                                                                            |
+|					  data[0]            : 0 Timer                   |
+|										   1 Counter                 |
+|										   2 Watchdog        		 |                             |					         data[1]            : 1 Start                   |
+|										   0 Stop                    |
+|                                                  2 Trigger             	 |
+|                                                    Clear (Only Counter)    |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	ULONG ul_Command1 = 0;
+	if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
+		switch (data[1]) {
+		case 0:	//stop the watchdog
+			outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG + APCI1564_TCW_PROG);	//disable the watchdog
+			break;
+		case 1:	//start the watchdog
+			outl(0x0001,
+				devpriv->i_IobaseAmcc +
+				APCI1564_DIGITAL_OP_WATCHDOG +
+				APCI1564_TCW_PROG);
+			break;
+		case 2:	//Software trigger
+			outl(0x0201,
+				devpriv->i_IobaseAmcc +
+				APCI1564_DIGITAL_OP_WATCHDOG +
+				APCI1564_TCW_PROG);
+			break;
+		default:
+			printk("\nSpecified functionality does not exist\n");
+			return -EINVAL;
+		}		// switch (data[1])
+	}			// if  (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
+	if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
+		if (data[1] == 1) {
+			ul_Command1 =
+				inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
+				APCI1564_TCW_PROG);
+			ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
+
+			//Enable the Timer
+			outl(ul_Command1,
+				devpriv->i_IobaseAmcc + APCI1564_TIMER +
+				APCI1564_TCW_PROG);
+		}		// if  (data[1]==1)
+		else if (data[1] == 0) {
+			//Stop The Timer
+
+			ul_Command1 =
+				inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
+				APCI1564_TCW_PROG);
+			ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
+			outl(ul_Command1,
+				devpriv->i_IobaseAmcc + APCI1564_TIMER +
+				APCI1564_TCW_PROG);
+		}		// else if(data[1]==0)
+	}			// if  (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
+	if (devpriv->b_TimerSelectMode == ADDIDATA_COUNTER) {
+		ul_Command1 =
+			inl(devpriv->iobase + ((devpriv->b_ModeSelectRegister -
+					1) * 0x20) + APCI1564_TCW_PROG);
+		if (data[1] == 1) {
+			//Start the Counter subdevice
+			ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
+		}		// if  (data[1] == 1)
+		else if (data[1] == 0) {
+			// Stops the Counter subdevice
+			ul_Command1 = 0;
+
+		}		// else if  (data[1] == 0)
+		else if (data[1] == 2) {
+			// Clears the Counter subdevice
+			ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x400;
+		}		// else if  (data[1] == 3)
+		outl(ul_Command1,
+			devpriv->iobase + ((devpriv->b_ModeSelectRegister -
+					1) * 0x20) + APCI1564_TCW_PROG);
+	}			// if (devpriv->b_TimerSelectMode==ADDIDATA_COUNTER)
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1564_ReadTimerCounterWatchdog                |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Read The Selected Timer , Counter or Watchdog          |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev : Driver handle                     |
+|                     UINT *data         : Data Pointer contains             |
+|                                          configuration parameters as below |
+|                                                                            |
+
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_ReadTimerCounterWatchdog(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	ULONG ul_Command1 = 0;
+
+	if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
+		// Stores the status of the Watchdog
+		data[0] =
+			inl(devpriv->i_IobaseAmcc +
+			APCI1564_DIGITAL_OP_WATCHDOG +
+			APCI1564_TCW_TRIG_STATUS) & 0x1;
+		data[1] =
+			inl(devpriv->i_IobaseAmcc +
+			APCI1564_DIGITAL_OP_WATCHDOG);
+	}			// if  (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
+	else if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
+		// Stores the status of the Timer
+		data[0] =
+			inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
+			APCI1564_TCW_TRIG_STATUS) & 0x1;
+
+		// Stores the Actual value of the Timer
+		data[1] = inl(devpriv->i_IobaseAmcc + APCI1564_TIMER);
+	}			// else if  (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
+	else if (devpriv->b_TimerSelectMode == ADDIDATA_COUNTER) {
+		// Read the Counter Actual Value.
+		data[0] =
+			inl(devpriv->iobase + ((devpriv->b_ModeSelectRegister -
+					1) * 0x20) +
+			APCI1564_TCW_SYNC_ENABLEDISABLE);
+		ul_Command1 =
+			inl(devpriv->iobase + ((devpriv->b_ModeSelectRegister -
+					1) * 0x20) + APCI1564_TCW_TRIG_STATUS);
+
+      /***********************************/
+		/* Get the software trigger status */
+      /***********************************/
+		data[1] = (BYTE) ((ul_Command1 >> 1) & 1);
+
+      /***********************************/
+		/* Get the hardware trigger status */
+      /***********************************/
+		data[2] = (BYTE) ((ul_Command1 >> 2) & 1);
+
+      /*********************************/
+		/* Get the software clear status */
+      /*********************************/
+		data[3] = (BYTE) ((ul_Command1 >> 3) & 1);
+
+      /***************************/
+		/* Get the overflow status */
+      /***************************/
+		data[4] = (BYTE) ((ul_Command1 >> 0) & 1);
+	}			// else  if  (devpriv->b_TimerSelectMode==ADDIDATA_COUNTER)
+	else if ((devpriv->b_TimerSelectMode != ADDIDATA_TIMER)
+		&& (devpriv->b_TimerSelectMode != ADDIDATA_WATCHDOG)
+		&& (devpriv->b_TimerSelectMode != ADDIDATA_COUNTER)) {
+		printk("\n Invalid Subdevice !!!\n");
+	}			// else if ((devpriv->b_TimerSelectMode!=ADDIDATA_TIMER) && (devpriv->b_TimerSelectMode!=ADDIDATA_WATCHDOG)&& (devpriv->b_TimerSelectMode!=ADDIDATA_COUNTER))
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   :  int i_APCI1564_ReadInterruptStatus                    |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              :Reads the interrupt status register                     |
++----------------------------------------------------------------------------+
+| Input Parameters  :                                                        |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      :                                                        |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI1564_ReadInterruptStatus(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	*data = ui_Type;
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : static void v_APCI1564_Interrupt					     |
+|					  (int irq , void *d)      |
++----------------------------------------------------------------------------+
+| Task              : Interrupt handler for the interruptible digital inputs |
++----------------------------------------------------------------------------+
+| Input Parameters  : int irq                 : irq number                   |
+|                     void *d                 : void pointer                 |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+static void v_APCI1564_Interrupt(int irq, void *d)
+{
+	struct comedi_device *dev = d;
+	UINT ui_DO, ui_DI;
+	UINT ui_Timer;
+	UINT ui_C1, ui_C2, ui_C3, ui_C4;
+	ULONG ul_Command2 = 0;
+	ui_DI = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+		APCI1564_DIGITAL_IP_IRQ) & 0x01;
+	ui_DO = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+		APCI1564_DIGITAL_OP_IRQ) & 0x01;
+	ui_Timer =
+		inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
+		APCI1564_TCW_IRQ) & 0x01;
+	ui_C1 = inl(devpriv->iobase + APCI1564_COUNTER1 +
+		APCI1564_TCW_IRQ) & 0x1;
+	ui_C2 = inl(devpriv->iobase + APCI1564_COUNTER2 +
+		APCI1564_TCW_IRQ) & 0x1;
+	ui_C3 = inl(devpriv->iobase + APCI1564_COUNTER3 +
+		APCI1564_TCW_IRQ) & 0x1;
+	ui_C4 = inl(devpriv->iobase + APCI1564_COUNTER4 +
+		APCI1564_TCW_IRQ) & 0x1;
+	if (ui_DI == 0 && ui_DO == 0 && ui_Timer == 0 && ui_C1 == 0
+		&& ui_C2 == 0 && ui_C3 == 0 && ui_C4 == 0) {
+		printk("\nInterrupt from unknown source\n");
+	}			// if(ui_DI==0 && ui_DO==0 && ui_Timer==0 && ui_C1==0 && ui_C2==0 && ui_C3==0 && ui_C4==0)
+
+	if (ui_DI == 1) {
+		ui_DI = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+			APCI1564_DIGITAL_IP_IRQ);
+		outl(0x0,
+			devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+			APCI1564_DIGITAL_IP_IRQ);
+		ui_InterruptStatus_1564 =
+			inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+			APCI1564_DIGITAL_IP_INTERRUPT_STATUS);
+		ui_InterruptStatus_1564 = ui_InterruptStatus_1564 & 0X000FFFF0;
+		send_sig(SIGIO, devpriv->tsk_Current, 0);	// send signal to the sample
+		outl(ui_DI, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + APCI1564_DIGITAL_IP_IRQ);	//enable the interrupt
+		return;
+	}
+
+	if (ui_DO == 1) {
+		// Check for Digital Output interrupt Type - 1: Vcc interrupt 2: CC interrupt.
+		ui_Type =
+			inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+			APCI1564_DIGITAL_OP_INTERRUPT_STATUS) & 0x3;
+		//Disable the  Interrupt
+		outl(0x0,
+			devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+			APCI1564_DIGITAL_OP_INTERRUPT);
+
+		//Sends signal to user space
+		send_sig(SIGIO, devpriv->tsk_Current, 0);
+
+	}			// if  (ui_DO)
+
+	if ((ui_Timer == 1) && (devpriv->b_TimerSelectMode = ADDIDATA_TIMER)) {
+		// Disable Timer Interrupt
+		ul_Command2 =
+			inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
+			APCI1564_TCW_PROG);
+		outl(0x0,
+			devpriv->i_IobaseAmcc + APCI1564_TIMER +
+			APCI1564_TCW_PROG);
+
+		//Send a signal to from kernel to user space
+		send_sig(SIGIO, devpriv->tsk_Current, 0);
+
+		// Enable Timer Interrupt
+
+		outl(ul_Command2,
+			devpriv->i_IobaseAmcc + APCI1564_TIMER +
+			APCI1564_TCW_PROG);
+	}			// if  ((ui_Timer == 1) && (devpriv->b_TimerSelectMode =ADDIDATA_TIMER))
+
+	if ((ui_C1 == 1) && (devpriv->b_TimerSelectMode = ADDIDATA_COUNTER)) {
+		// Disable Counter Interrupt
+		ul_Command2 =
+			inl(devpriv->iobase + APCI1564_COUNTER1 +
+			APCI1564_TCW_PROG);
+		outl(0x0,
+			devpriv->iobase + APCI1564_COUNTER1 +
+			APCI1564_TCW_PROG);
+
+		//Send a signal to from kernel to user space
+		send_sig(SIGIO, devpriv->tsk_Current, 0);
+
+		// Enable Counter Interrupt
+		outl(ul_Command2,
+			devpriv->iobase + APCI1564_COUNTER1 +
+			APCI1564_TCW_PROG);
+	}			// if  ((ui_C1 == 1) && (devpriv->b_TimerSelectMode = ADDIDATA_COUNTER))
+
+	if ((ui_C2 == 1) && (devpriv->b_TimerSelectMode = ADDIDATA_COUNTER)) {
+		// Disable Counter Interrupt
+		ul_Command2 =
+			inl(devpriv->iobase + APCI1564_COUNTER2 +
+			APCI1564_TCW_PROG);
+		outl(0x0,
+			devpriv->iobase + APCI1564_COUNTER2 +
+			APCI1564_TCW_PROG);
+
+		//Send a signal to from kernel to user space
+		send_sig(SIGIO, devpriv->tsk_Current, 0);
+
+		// Enable Counter Interrupt
+		outl(ul_Command2,
+			devpriv->iobase + APCI1564_COUNTER2 +
+			APCI1564_TCW_PROG);
+	}			// if  ((ui_C2 == 1) && (devpriv->b_TimerSelectMode =ADDIDATA_COUNTER))
+
+	if ((ui_C3 == 1) && (devpriv->b_TimerSelectMode = ADDIDATA_COUNTER)) {
+		// Disable Counter Interrupt
+		ul_Command2 =
+			inl(devpriv->iobase + APCI1564_COUNTER3 +
+			APCI1564_TCW_PROG);
+		outl(0x0,
+			devpriv->iobase + APCI1564_COUNTER3 +
+			APCI1564_TCW_PROG);
+
+		//Send a signal to from kernel to user space
+		send_sig(SIGIO, devpriv->tsk_Current, 0);
+
+		// Enable Counter Interrupt
+		outl(ul_Command2,
+			devpriv->iobase + APCI1564_COUNTER3 +
+			APCI1564_TCW_PROG);
+	}			// if ((ui_C3 == 1) && (devpriv->b_TimerSelectMode =ADDIDATA_COUNTER))
+
+	if ((ui_C4 == 1) && (devpriv->b_TimerSelectMode = ADDIDATA_COUNTER)) {
+		// Disable Counter Interrupt
+		ul_Command2 =
+			inl(devpriv->iobase + APCI1564_COUNTER4 +
+			APCI1564_TCW_PROG);
+		outl(0x0,
+			devpriv->iobase + APCI1564_COUNTER4 +
+			APCI1564_TCW_PROG);
+
+		//Send a signal to from kernel to user space
+		send_sig(SIGIO, devpriv->tsk_Current, 0);
+
+		// Enable Counter Interrupt
+		outl(ul_Command2,
+			devpriv->iobase + APCI1564_COUNTER4 +
+			APCI1564_TCW_PROG);
+	}			// if ((ui_C4 == 1) && (devpriv->b_TimerSelectMode =ADDIDATA_COUNTER))
+	return;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI1564_Reset(struct comedi_device *dev)               |                                                       |
++----------------------------------------------------------------------------+
+| Task              :resets all the registers                                |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      :                                                        |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1564_Reset(struct comedi_device * dev)
+{
+	outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_IRQ);	//disable the interrupts
+	inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_STATUS);	//Reset the interrupt status register
+	outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_MODE1);	//Disable the and/or interrupt
+	outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_MODE2);
+	devpriv->b_DigitalOutputRegister = 0;
+	ui_Type = 0;
+	outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP);	//Resets the output channels
+	outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_INTERRUPT);	//Disables the interrupt.
+	outl(0x0,
+		devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG +
+		APCI1564_TCW_RELOAD_VALUE);
+	outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER);
+	outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG);
+
+	outl(0x0, devpriv->iobase + APCI1564_COUNTER1 + APCI1564_TCW_PROG);
+	outl(0x0, devpriv->iobase + APCI1564_COUNTER2 + APCI1564_TCW_PROG);
+	outl(0x0, devpriv->iobase + APCI1564_COUNTER3 + APCI1564_TCW_PROG);
+	outl(0x0, devpriv->iobase + APCI1564_COUNTER4 + APCI1564_TCW_PROG);
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h
new file mode 100644
index 0000000..f0c461c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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.
+ */
+
+/*********      Definitions for APCI-1564 card  *****/
+
+#define APCI1564_BOARD_VENDOR_ID                0x15B8
+#define APCI1564_ADDRESS_RANGE                  128
+
+//DIGITAL INPUT-OUTPUT DEFINE
+// Input defines
+#define APCI1564_DIGITAL_IP                     0x04
+#define APCI1564_DIGITAL_IP_INTERRUPT_MODE1     4
+#define APCI1564_DIGITAL_IP_INTERRUPT_MODE2     8
+#define APCI1564_DIGITAL_IP_IRQ                 16
+
+// Output defines
+#define APCI1564_DIGITAL_OP                 	0x18
+#define APCI1564_DIGITAL_OP_RW               	0
+#define APCI1564_DIGITAL_OP_INTERRUPT           4
+#define APCI1564_DIGITAL_OP_IRQ                 12
+
+//Digital Input IRQ Function Selection
+#define ADDIDATA_OR                             0
+#define ADDIDATA_AND                            1
+
+//Digital Input Interrupt Status
+#define APCI1564_DIGITAL_IP_INTERRUPT_STATUS    12
+
+//Digital Output Interrupt Status
+#define APCI1564_DIGITAL_OP_INTERRUPT_STATUS    8
+
+//Digital Input Interrupt Enable Disable.
+#define APCI1564_DIGITAL_IP_INTERRUPT_ENABLE    0x4
+#define APCI1564_DIGITAL_IP_INTERRUPT_DISABLE   0xFFFFFFFB
+
+//Digital Output Interrupt Enable Disable.
+#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_ENABLE   0x1
+#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_DISABLE  0xFFFFFFFE
+#define APCI1564_DIGITAL_OP_CC_INTERRUPT_ENABLE    0x2
+#define APCI1564_DIGITAL_OP_CC_INTERRUPT_DISABLE   0xFFFFFFFD
+
+//ADDIDATA Enable Disable
+
+#define ADDIDATA_ENABLE                            1
+#define ADDIDATA_DISABLE                           0
+
+// TIMER COUNTER WATCHDOG DEFINES
+
+#define ADDIDATA_TIMER                             0
+#define ADDIDATA_COUNTER                           1
+#define ADDIDATA_WATCHDOG                          2
+#define APCI1564_DIGITAL_OP_WATCHDOG               0x28
+#define APCI1564_TIMER                             0x48
+#define APCI1564_COUNTER1                          0x0
+#define APCI1564_COUNTER2                          0x20
+#define APCI1564_COUNTER3                          0x40
+#define APCI1564_COUNTER4                          0x60
+#define APCI1564_TCW_SYNC_ENABLEDISABLE            0
+#define APCI1564_TCW_RELOAD_VALUE                  4
+#define APCI1564_TCW_TIMEBASE                      8
+#define APCI1564_TCW_PROG                          12
+#define APCI1564_TCW_TRIG_STATUS                   16
+#define APCI1564_TCW_IRQ                           20
+#define APCI1564_TCW_WARN_TIMEVAL                  24
+#define APCI1564_TCW_WARN_TIMEBASE                 28
+
+// Hardware Layer  functions for Apci1564
+
+//DI
+// for di read
+INT i_APCI1564_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+				  struct comedi_insn *insn, unsigned int *data);
+INT i_APCI1564_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data);
+INT i_APCI1564_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+				    struct comedi_insn *insn, unsigned int *data);
+
+//DO
+int i_APCI1564_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+				   struct comedi_insn *insn, unsigned int *data);
+INT i_APCI1564_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+				  struct comedi_insn *insn, unsigned int *data);
+INT i_APCI1564_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data);
+int i_APCI1564_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subdevice *s,
+				   struct comedi_insn *insn, unsigned int *data);
+
+// TIMER
+// timer value is passed as u seconds
+INT i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev,
+					  struct comedi_subdevice *s,
+					  struct comedi_insn *insn, unsigned int *data);
+int i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev,
+						  struct comedi_subdevice *s,
+						  struct comedi_insn *insn,
+						  unsigned int *data);
+int i_APCI1564_ReadTimerCounterWatchdog(struct comedi_device *dev,
+					struct comedi_subdevice *s,
+					struct comedi_insn *insn, unsigned int *data);
+
+// INTERRUPT
+static void v_APCI1564_Interrupt(int irq, void *d);
+
+// RESET
+INT i_APCI1564_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c
new file mode 100644
index 0000000..906d635
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c
@@ -0,0 +1,780 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+
+        ADDI-DATA GmbH
+        Dieselstrasse 3
+        D-77833 Ottersweier
+        Tel: +19(0)7223/9493-0
+        Fax: +49(0)7223/9493-92
+        http://www.addi-data-com
+        info@addi-data.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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+  +-----------------------------------------------------------------------+
+  | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
+  +-----------------------------------------------------------------------+
+  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
+  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
+  +-----------------------------------------------------------------------+
+  | Project     : API APCI1648    | Compiler : gcc                        |
+  | Module name : TTL.C           | Version  : 2.96                       |
+  +-------------------------------+---------------------------------------+
+  | Project manager: S. Weber     | Date     :  25/05/2005                |
+  +-----------------------------------------------------------------------+
+  | Description :   APCI-16XX TTL I/O module                              |
+  |                                                                       |
+  |                                                                       |
+  +-----------------------------------------------------------------------+
+  |                             UPDATES                                   |
+  +-----------------------------------------------------------------------+
+  |   Date   |   Author  |          Description of updates                |
+  +----------+-----------+------------------------------------------------+
+  |25.05.2005| S.Weber   | Creation                                       |
+  |          |           |                                                |
+  +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+|                               Included files                               |
++----------------------------------------------------------------------------+
+*/
+
+#include "hwdrv_apci16xx.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : INT   i_APCI16XX_InsnConfigInitTTLIO                   |
+|                          (struct comedi_device    *dev,                           |
+|                           struct comedi_subdevice *s,                             |
+|                           struct comedi_insn      *insn,                          |
+|                           unsigned int         *data)                          |
++----------------------------------------------------------------------------+
+| Task           APCI16XX_TTL_INIT (using defaults)   :                      |
+|                Configure the TTL I/O operating mode from all ports         |
+|                You must calling this function be                           |
+|                for you call any other function witch access of TTL.        |
+|                APCI16XX_TTL_INITDIRECTION(user inputs for direction)       |
++----------------------------------------------------------------------------+
+| Input Parameters  : b_InitType    = (BYTE) data[0];                        |
+|                     b_Port0Mode   = (BYTE) data[1];                        |
+|                     b_Port1Mode   = (BYTE) data[2];                        |
+|                     b_Port2Mode   = (BYTE) data[3];                        |
+|                     b_Port3Mode   = (BYTE) data[4];                        |
+|                     ........                                               |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :>0: No error                                            |
+|                    -1: Port 0 mode selection is wrong                      |
+|                    -2: Port 1 mode selection is wrong                      |
+|                    -3: Port 2 mode selection is wrong                      |
+|                    -4: Port 3 mode selection is wrong                      |
+|                    -X: Port X-1 mode selection is wrong                    |
+|                    ....                                                    |
+|                    -100 : Config command error                             |
+|                    -101 : Data size error                                  |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI16XX_InsnConfigInitTTLIO(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = insn->n;
+	BYTE b_Command = 0;
+	BYTE b_Cpt = 0;
+	BYTE b_NumberOfPort =
+		(BYTE) (devpriv->ps_BoardInfo->i_NbrTTLChannel / 8);
+
+	/************************/
+	/* Test the buffer size */
+	/************************/
+
+	if (insn->n >= 1) {
+	   /*******************/
+		/* Get the command */
+		/* **************** */
+
+		b_Command = (BYTE) data[0];
+
+	   /********************/
+		/* Test the command */
+	   /********************/
+
+		if ((b_Command == APCI16XX_TTL_INIT) ||
+			(b_Command == APCI16XX_TTL_INITDIRECTION) ||
+			(b_Command == APCI16XX_TTL_OUTPUTMEMORY)) {
+	      /***************************************/
+			/* Test the initialisation buffer size */
+	      /***************************************/
+
+			if ((b_Command == APCI16XX_TTL_INITDIRECTION)
+				&& ((BYTE) (insn->n - 1) != b_NumberOfPort)) {
+		 /*******************/
+				/* Data size error */
+		 /*******************/
+
+				printk("\nBuffer size error");
+				i_ReturnValue = -101;
+			}
+
+			if ((b_Command == APCI16XX_TTL_OUTPUTMEMORY)
+				&& ((BYTE) (insn->n) != 2)) {
+		 /*******************/
+				/* Data size error */
+		 /*******************/
+
+				printk("\nBuffer size error");
+				i_ReturnValue = -101;
+			}
+		} else {
+	      /************************/
+			/* Config command error */
+	      /************************/
+
+			printk("\nCommand selection error");
+			i_ReturnValue = -100;
+		}
+	} else {
+	   /*******************/
+		/* Data size error */
+	   /*******************/
+
+		printk("\nBuffer size error");
+		i_ReturnValue = -101;
+	}
+
+	/**************************************************************************/
+	/* Test if no error occur and APCI16XX_TTL_INITDIRECTION command selected */
+	/**************************************************************************/
+
+	if ((i_ReturnValue >= 0) && (b_Command == APCI16XX_TTL_INITDIRECTION)) {
+		memset(devpriv->ul_TTLPortConfiguration, 0,
+			sizeof(devpriv->ul_TTLPortConfiguration));
+
+	   /*************************************/
+		/* Test the port direction selection */
+	   /*************************************/
+
+		for (b_Cpt = 1;
+			(b_Cpt <= b_NumberOfPort) && (i_ReturnValue >= 0);
+			b_Cpt++) {
+	      /**********************/
+			/* Test the direction */
+	      /**********************/
+
+			if ((data[b_Cpt] != 0) && (data[b_Cpt] != 0xFF)) {
+		 /************************/
+				/* Port direction error */
+		 /************************/
+
+				printk("\nPort %d direction selection error",
+					(INT) b_Cpt);
+				i_ReturnValue = -(INT) b_Cpt;
+			}
+
+	      /**************************/
+			/* Save the configuration */
+	      /**************************/
+
+			devpriv->ul_TTLPortConfiguration[(b_Cpt - 1) / 4] =
+				devpriv->ul_TTLPortConfiguration[(b_Cpt -
+					1) / 4] | (data[b_Cpt] << (8 * ((b_Cpt -
+							1) % 4)));
+		}
+	}
+
+	/**************************/
+	/* Test if no error occur */
+	/**************************/
+
+	if (i_ReturnValue >= 0) {
+	   /***********************************/
+		/* Test if TTL port initilaisation */
+	   /***********************************/
+
+		if ((b_Command == APCI16XX_TTL_INIT)
+			|| (b_Command == APCI16XX_TTL_INITDIRECTION)) {
+	      /******************************/
+			/* Set all port configuration */
+	      /******************************/
+
+			for (b_Cpt = 0; b_Cpt <= b_NumberOfPort; b_Cpt++) {
+				if ((b_Cpt % 4) == 0) {
+		    /*************************/
+					/* Set the configuration */
+		    /*************************/
+
+					outl(devpriv->
+						ul_TTLPortConfiguration[b_Cpt /
+							4],
+						devpriv->iobase + 32 + b_Cpt);
+				}
+			}
+		}
+	}
+
+	/************************************************/
+	/* Test if output memory initialisation command */
+	/************************************************/
+
+	if (b_Command == APCI16XX_TTL_OUTPUTMEMORY) {
+		if (data[1]) {
+			devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
+		} else {
+			devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
+		}
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+|                            INPUT FUNCTIONS                                 |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : INT     i_APCI16XX_InsnBitsReadTTLIO                   |
+|                          (struct comedi_device    *dev,                           |
+|                           struct comedi_subdevice *s,                             |
+|                           struct comedi_insn      *insn,                          |
+|                           unsigned int         *data)                          |
++----------------------------------------------------------------------------+
+| Task              : Read the status from selected TTL digital input        |
+|                     (b_InputChannel)                                       |
++----------------------------------------------------------------------------+
+| Task              : Read the status from digital input port                |
+|                     (b_SelectedPort)                                       |
++----------------------------------------------------------------------------+
+| Input Parameters  :                                                        |
+|              APCI16XX_TTL_READCHANNEL                                      |
+|                    b_SelectedPort= CR_RANGE(insn->chanspec);               |
+|                    b_InputChannel= CR_CHAN(insn->chanspec);                |
+|                    b_ReadType	  = (BYTE) data[0];                          |
+|                                                                            |
+|              APCI16XX_TTL_READPORT                                         |
+|                    b_SelectedPort= CR_RANGE(insn->chanspec);               |
+|                    b_ReadType	  = (BYTE) data[0];                          |
++----------------------------------------------------------------------------+
+| Output Parameters : data[0]    0 : Channle is not active                   |
+|                                1 : Channle is active                       |
++----------------------------------------------------------------------------+
+| Return Value      : >0  : No error                                         |
+|                    -100 : Config command error                             |
+|                    -101 : Data size error                                  |
+|                    -102 : The selected TTL input port is wrong             |
+|                    -103 : The selected TTL digital input is wrong          |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI16XX_InsnBitsReadTTLIO(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = insn->n;
+	BYTE b_Command = 0;
+	BYTE b_NumberOfPort =
+		(BYTE) (devpriv->ps_BoardInfo->i_NbrTTLChannel / 8);
+	BYTE b_SelectedPort = CR_RANGE(insn->chanspec);
+	BYTE b_InputChannel = CR_CHAN(insn->chanspec);
+	BYTE *pb_Status;
+	DWORD dw_Status;
+
+	/************************/
+	/* Test the buffer size */
+	/************************/
+
+	if (insn->n >= 1) {
+	   /*******************/
+		/* Get the command */
+		/* **************** */
+
+		b_Command = (BYTE) data[0];
+
+	   /********************/
+		/* Test the command */
+	   /********************/
+
+		if ((b_Command == APCI16XX_TTL_READCHANNEL)
+			|| (b_Command == APCI16XX_TTL_READPORT)) {
+	      /**************************/
+			/* Test the selected port */
+	      /**************************/
+
+			if (b_SelectedPort < b_NumberOfPort) {
+		 /**********************/
+				/* Test if input port */
+		 /**********************/
+
+				if (((devpriv->ul_TTLPortConfiguration
+							[b_SelectedPort /
+								4] >> (8 *
+								(b_SelectedPort
+									%
+									4))) &
+						0xFF) == 0) {
+		    /***************************/
+					/* Test the channel number */
+		    /***************************/
+
+					if ((b_Command ==
+							APCI16XX_TTL_READCHANNEL)
+						&& (b_InputChannel > 7)) {
+		       /*******************************************/
+						/* The selected TTL digital input is wrong */
+		       /*******************************************/
+
+						printk("\nChannel selection error");
+						i_ReturnValue = -103;
+					}
+				} else {
+		    /****************************************/
+					/* The selected TTL input port is wrong */
+		    /****************************************/
+
+					printk("\nPort selection error");
+					i_ReturnValue = -102;
+				}
+			} else {
+		 /****************************************/
+				/* The selected TTL input port is wrong */
+		 /****************************************/
+
+				printk("\nPort selection error");
+				i_ReturnValue = -102;
+			}
+		} else {
+	      /************************/
+			/* Config command error */
+	      /************************/
+
+			printk("\nCommand selection error");
+			i_ReturnValue = -100;
+		}
+	} else {
+	   /*******************/
+		/* Data size error */
+	   /*******************/
+
+		printk("\nBuffer size error");
+		i_ReturnValue = -101;
+	}
+
+	/**************************/
+	/* Test if no error occur */
+	/**************************/
+
+	if (i_ReturnValue >= 0) {
+		pb_Status = (PBYTE) & data[0];
+
+	   /*******************************/
+		/* Get the digital inpu status */
+	   /*******************************/
+
+		dw_Status =
+			inl(devpriv->iobase + 8 + ((b_SelectedPort / 4) * 4));
+		dw_Status = (dw_Status >> (8 * (b_SelectedPort % 4))) & 0xFF;
+
+	   /***********************/
+		/* Save the port value */
+	   /***********************/
+
+		*pb_Status = (BYTE) dw_Status;
+
+	   /***************************************/
+		/* Test if read channel status command */
+	   /***************************************/
+
+		if (b_Command == APCI16XX_TTL_READCHANNEL) {
+			*pb_Status = (*pb_Status >> b_InputChannel) & 1;
+		}
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : INT i_APCI16XX_InsnReadTTLIOAllPortValue               |
+|                          (struct comedi_device    *dev,                           |
+|                           struct comedi_subdevice *s,                             |
+|                           struct comedi_insn      *insn,                          |
+|                           unsigned int         *data)                          |
++----------------------------------------------------------------------------+
+| Task              : Read the status from all digital input ports           |
++----------------------------------------------------------------------------+
+| Input Parameters  : -                                                      |
++----------------------------------------------------------------------------+
+| Output Parameters : data[0] : Port 0 to 3 data                             |
+|                     data[1] : Port 4 to 7 data                             |
+|                     ....                                                   |
++----------------------------------------------------------------------------+
+| Return Value      : 0: No error                                            |
+|                    -100 : Read command error                               |
+|                    -101 : Data size error                                  |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI16XX_InsnReadTTLIOAllPortValue(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	BYTE b_Command = (BYTE) CR_AREF(insn->chanspec);
+	INT i_ReturnValue = insn->n;
+	BYTE b_Cpt = 0;
+	BYTE b_NumberOfPort = 0;
+	unsigned int *pls_ReadData = data;
+
+	/********************/
+	/* Test the command */
+	/********************/
+
+	if ((b_Command == APCI16XX_TTL_READ_ALL_INPUTS)
+		|| (b_Command == APCI16XX_TTL_READ_ALL_OUTPUTS)) {
+	   /**********************************/
+		/* Get the number of 32-Bit ports */
+	   /**********************************/
+
+		b_NumberOfPort =
+			(BYTE) (devpriv->ps_BoardInfo->i_NbrTTLChannel / 32);
+		if ((b_NumberOfPort * 32) <
+			devpriv->ps_BoardInfo->i_NbrTTLChannel) {
+			b_NumberOfPort = b_NumberOfPort + 1;
+		}
+
+	   /************************/
+		/* Test the buffer size */
+	   /************************/
+
+		if (insn->n >= b_NumberOfPort) {
+			if (b_Command == APCI16XX_TTL_READ_ALL_INPUTS) {
+		 /**************************/
+				/* Read all digital input */
+		 /**************************/
+
+				for (b_Cpt = 0; b_Cpt < b_NumberOfPort; b_Cpt++) {
+		    /************************/
+					/* Read the 32-Bit port */
+		    /************************/
+
+					pls_ReadData[b_Cpt] =
+						inl(devpriv->iobase + 8 +
+						(b_Cpt * 4));
+
+		    /**************************************/
+					/* Mask all channels used als outputs */
+		    /**************************************/
+
+					pls_ReadData[b_Cpt] =
+						pls_ReadData[b_Cpt] &
+						(~devpriv->
+						ul_TTLPortConfiguration[b_Cpt]);
+				}
+			} else {
+		 /****************************/
+				/* Read all digital outputs */
+		 /****************************/
+
+				for (b_Cpt = 0; b_Cpt < b_NumberOfPort; b_Cpt++) {
+		    /************************/
+					/* Read the 32-Bit port */
+		    /************************/
+
+					pls_ReadData[b_Cpt] =
+						inl(devpriv->iobase + 20 +
+						(b_Cpt * 4));
+
+		    /**************************************/
+					/* Mask all channels used als outputs */
+		    /**************************************/
+
+					pls_ReadData[b_Cpt] =
+						pls_ReadData[b_Cpt] & devpriv->
+						ul_TTLPortConfiguration[b_Cpt];
+				}
+			}
+		} else {
+	      /*******************/
+			/* Data size error */
+	      /*******************/
+
+			printk("\nBuffer size error");
+			i_ReturnValue = -101;
+		}
+	} else {
+	   /*****************/
+		/* Command error */
+	   /*****************/
+
+		printk("\nCommand selection error");
+		i_ReturnValue = -100;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+|                            OUTPUT FUNCTIONS                                |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : INT     i_APCI16XX_InsnBitsWriteTTLIO                  |
+|                          (struct comedi_device    *dev,                           |
+|                           struct comedi_subdevice *s,                             |
+|                           struct comedi_insn      *insn,                          |
+|                           unsigned int         *data)                          |
++----------------------------------------------------------------------------+
+| Task              : Set the state from selected TTL digital output         |
+|                     (b_OutputChannel)                                      |
++----------------------------------------------------------------------------+
+| Task              : Set the state from digital output port                 |
+|                     (b_SelectedPort)                                       |
++----------------------------------------------------------------------------+
+| Input Parameters  :                                                        |
+|              APCI16XX_TTL_WRITECHANNEL_ON | APCI16XX_TTL_WRITECHANNEL_OFF  |
+|                    b_SelectedPort = CR_RANGE(insn->chanspec);              |
+|                    b_OutputChannel= CR_CHAN(insn->chanspec);               |
+|                    b_Command      = (BYTE) data[0];                        |
+|                                                                            |
+|              APCI16XX_TTL_WRITEPORT_ON | APCI16XX_TTL_WRITEPORT_OFF        |
+|                    b_SelectedPort = CR_RANGE(insn->chanspec);              |
+|                    b_Command      = (BYTE) data[0];                        |
++----------------------------------------------------------------------------+
+| Output Parameters : data[0] : TTL output port 0 to 3 data                  |
+|                     data[1] : TTL output port 4 to 7 data                  |
+|                     ....                                                   |
++----------------------------------------------------------------------------+
+| Return Value      : >0  : No error                                         |
+|                    -100 : Command error                                    |
+|                    -101 : Data size error                                  |
+|                    -102 : The selected TTL output port is wrong            |
+|                    -103 : The selected TTL digital output is wrong         |
+|                    -104 : Output memory disabled                           |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI16XX_InsnBitsWriteTTLIO(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = insn->n;
+	BYTE b_Command = 0;
+	BYTE b_NumberOfPort =
+		(BYTE) (devpriv->ps_BoardInfo->i_NbrTTLChannel / 8);
+	BYTE b_SelectedPort = CR_RANGE(insn->chanspec);
+	BYTE b_OutputChannel = CR_CHAN(insn->chanspec);
+	DWORD dw_Status = 0;
+
+	/************************/
+	/* Test the buffer size */
+	/************************/
+
+	if (insn->n >= 1) {
+	   /*******************/
+		/* Get the command */
+		/* **************** */
+
+		b_Command = (BYTE) data[0];
+
+	   /********************/
+		/* Test the command */
+	   /********************/
+
+		if ((b_Command == APCI16XX_TTL_WRITECHANNEL_ON) ||
+			(b_Command == APCI16XX_TTL_WRITEPORT_ON) ||
+			(b_Command == APCI16XX_TTL_WRITECHANNEL_OFF) ||
+			(b_Command == APCI16XX_TTL_WRITEPORT_OFF)) {
+	      /**************************/
+			/* Test the selected port */
+	      /**************************/
+
+			if (b_SelectedPort < b_NumberOfPort) {
+		 /***********************/
+				/* Test if output port */
+		 /***********************/
+
+				if (((devpriv->ul_TTLPortConfiguration
+							[b_SelectedPort /
+								4] >> (8 *
+								(b_SelectedPort
+									%
+									4))) &
+						0xFF) == 0xFF) {
+		    /***************************/
+					/* Test the channel number */
+		    /***************************/
+
+					if (((b_Command == APCI16XX_TTL_WRITECHANNEL_ON) || (b_Command == APCI16XX_TTL_WRITECHANNEL_OFF)) && (b_OutputChannel > 7)) {
+		       /********************************************/
+						/* The selected TTL digital output is wrong */
+		       /********************************************/
+
+						printk("\nChannel selection error");
+						i_ReturnValue = -103;
+					}
+
+					if (((b_Command == APCI16XX_TTL_WRITECHANNEL_OFF) || (b_Command == APCI16XX_TTL_WRITEPORT_OFF)) && (devpriv->b_OutputMemoryStatus == ADDIDATA_DISABLE)) {
+		       /********************************************/
+						/* The selected TTL digital output is wrong */
+		       /********************************************/
+
+						printk("\nOutput memory disabled");
+						i_ReturnValue = -104;
+					}
+
+		    /************************/
+					/* Test the buffer size */
+		    /************************/
+
+					if (((b_Command == APCI16XX_TTL_WRITEPORT_ON) || (b_Command == APCI16XX_TTL_WRITEPORT_OFF)) && (insn->n < 2)) {
+		       /*******************/
+						/* Data size error */
+		       /*******************/
+
+						printk("\nBuffer size error");
+						i_ReturnValue = -101;
+					}
+				} else {
+		    /*****************************************/
+					/* The selected TTL output port is wrong */
+		    /*****************************************/
+
+					printk("\nPort selection error %lX",
+						(unsigned long)devpriv->
+						ul_TTLPortConfiguration[0]);
+					i_ReturnValue = -102;
+				}
+			} else {
+		 /****************************************/
+				/* The selected TTL output port is wrong */
+		 /****************************************/
+
+				printk("\nPort selection error %d %d",
+					b_SelectedPort, b_NumberOfPort);
+				i_ReturnValue = -102;
+			}
+		} else {
+	      /************************/
+			/* Config command error */
+	      /************************/
+
+			printk("\nCommand selection error");
+			i_ReturnValue = -100;
+		}
+	} else {
+	   /*******************/
+		/* Data size error */
+	   /*******************/
+
+		printk("\nBuffer size error");
+		i_ReturnValue = -101;
+	}
+
+	/**************************/
+	/* Test if no error occur */
+	/**************************/
+
+	if (i_ReturnValue >= 0) {
+	   /********************************/
+		/* Get the digital output state */
+	   /********************************/
+
+		dw_Status =
+			inl(devpriv->iobase + 20 + ((b_SelectedPort / 4) * 4));
+
+	   /**********************************/
+		/* Test if output memory not used */
+	   /**********************************/
+
+		if (devpriv->b_OutputMemoryStatus == ADDIDATA_DISABLE) {
+	      /*********************************/
+			/* Clear the selected port value */
+	      /*********************************/
+
+			dw_Status =
+				dw_Status & (0xFFFFFFFFUL -
+				(0xFFUL << (8 * (b_SelectedPort % 4))));
+		}
+
+	   /******************************/
+		/* Test if setting channel ON */
+	   /******************************/
+
+		if (b_Command == APCI16XX_TTL_WRITECHANNEL_ON) {
+			dw_Status =
+				dw_Status | (1UL << ((8 * (b_SelectedPort %
+							4)) + b_OutputChannel));
+		}
+
+	   /***************************/
+		/* Test if setting port ON */
+	   /***************************/
+
+		if (b_Command == APCI16XX_TTL_WRITEPORT_ON) {
+			dw_Status =
+				dw_Status | ((data[1] & 0xFF) << (8 *
+					(b_SelectedPort % 4)));
+		}
+
+	   /*******************************/
+		/* Test if setting channel OFF */
+	   /*******************************/
+
+		if (b_Command == APCI16XX_TTL_WRITECHANNEL_OFF) {
+			dw_Status =
+				dw_Status & (0xFFFFFFFFUL -
+				(1UL << ((8 * (b_SelectedPort % 4)) +
+						b_OutputChannel)));
+		}
+
+	   /****************************/
+		/* Test if setting port OFF */
+	   /****************************/
+
+		if (b_Command == APCI16XX_TTL_WRITEPORT_OFF) {
+			dw_Status =
+				dw_Status & (0xFFFFFFFFUL -
+				((data[1] & 0xFF) << (8 * (b_SelectedPort %
+							4))));
+		}
+
+		outl(dw_Status,
+			devpriv->iobase + 20 + ((b_SelectedPort / 4) * 4));
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI2200_Reset(struct comedi_device *dev)               |                                                         +----------------------------------------------------------------------------+
+| Task              :resets all the registers                                |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev                                     |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : -                                                      |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI16XX_Reset(struct comedi_device * dev)
+{
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h
new file mode 100644
index 0000000..5bf91e1
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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.
+ */
+
+#ifndef COMEDI_SUBD_TTLIO
+#define COMEDI_SUBD_TTLIO   11	/* Digital Input Output But TTL */
+#endif
+
+#ifndef ADDIDATA_ENABLE
+#define ADDIDATA_ENABLE  1
+#define ADDIDATA_DISABLE 0
+#endif
+
+#define APCI16XX_TTL_INIT           0
+#define APCI16XX_TTL_INITDIRECTION  1
+#define APCI16XX_TTL_OUTPUTMEMORY   2
+
+#define APCI16XX_TTL_READCHANNEL            0
+#define APCI16XX_TTL_READPORT               1
+
+#define APCI16XX_TTL_WRITECHANNEL_ON        0
+#define APCI16XX_TTL_WRITECHANNEL_OFF       1
+#define APCI16XX_TTL_WRITEPORT_ON           2
+#define APCI16XX_TTL_WRITEPORT_OFF          3
+
+#define APCI16XX_TTL_READ_ALL_INPUTS        0
+#define APCI16XX_TTL_READ_ALL_OUTPUTS       1
+
+#ifdef __KERNEL__
+
+static const struct comedi_lrange range_apci16xx_ttl = { 12,
+	{BIP_RANGE(1),
+	 BIP_RANGE(1),
+	 BIP_RANGE(1),
+	 BIP_RANGE(1),
+	 BIP_RANGE(1),
+	 BIP_RANGE(1),
+	 BIP_RANGE(1),
+	 BIP_RANGE(1),
+	 BIP_RANGE(1),
+	 BIP_RANGE(1),
+	 BIP_RANGE(1),
+	 BIP_RANGE(1)}
+};
+
+/*
++----------------------------------------------------------------------------+
+|                       TTL INISIALISATION FUNCTION                          |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI16XX_InsnConfigInitTTLIO(struct comedi_device *dev,
+				   struct comedi_subdevice *s, struct comedi_insn *insn,
+				   unsigned int *data);
+
+/*
++----------------------------------------------------------------------------+
+|                       TTL INPUT FUNCTION                                   |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI16XX_InsnBitsReadTTLIO(struct comedi_device *dev,
+				 struct comedi_subdevice *s, struct comedi_insn *insn,
+				 unsigned int *data);
+
+int i_APCI16XX_InsnReadTTLIOAllPortValue(struct comedi_device *dev,
+					 struct comedi_subdevice *s,
+					 struct comedi_insn *insn, unsigned int *data);
+
+/*
++----------------------------------------------------------------------------+
+|                            TTL OUTPUT FUNCTIONS                            |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI16XX_InsnBitsWriteTTLIO(struct comedi_device *dev,
+				  struct comedi_subdevice *s, struct comedi_insn *insn,
+				  unsigned int *data);
+
+int i_APCI16XX_Reset(struct comedi_device *dev);
+#endif
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c
new file mode 100644
index 0000000..31f55da
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c
@@ -0,0 +1,460 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+
+        ADDI-DATA GmbH
+        Dieselstrasse 3
+        D-77833 Ottersweier
+        Tel: +19(0)7223/9493-0
+        Fax: +49(0)7223/9493-92
+        http://www.addi-data-com
+        info@addi-data.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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+  +-----------------------------------------------------------------------+
+  | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
+  +-----------------------------------------------------------------------+
+  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
+  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
+  +-------------------------------+---------------------------------------+
+  | Project     : APCI-2016       | Compiler   : GCC                      |
+  | Module name : hwdrv_apci2016.c| Version    : 2.96                     |
+  +-------------------------------+---------------------------------------+
+  | Project manager: Eric Stolz   | Date       :  02/12/2002              |
+  +-------------------------------+---------------------------------------+
+  | Description :   Hardware Layer Acces For APCI-2016                    |
+  +-----------------------------------------------------------------------+
+  |                             UPDATES                                   |
+  +----------+-----------+------------------------------------------------+
+  |   Date   |   Author  |          Description of updates                |
+  +----------+-----------+------------------------------------------------+
+  |          |           |                                                |
+  |          |           |                                                |
+  |          |           |                                                |
+  +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+|                               Included files                               |
++----------------------------------------------------------------------------+
+*/
+#include "hwdrv_apci2016.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI2016_ConfigDigitalOutput                     |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Configures The Digital Output Subdevice.               |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev : Driver handle                     |
+|                     UINT *data         : Data Pointer contains             |
+|                                          configuration parameters as below |
+|                                                                            |
+|			  data[0]            : 1 Digital Memory On               |
+|				     			   0 Digital Memory Off              |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+int i_APCI2016_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if ((data[0] != 0) && (data[0] != 1)) {
+		comedi_error(dev,
+			"Not a valid Data !!! ,Data should be 1 or 0\n");
+		return -EINVAL;
+	}			// if  ((data[0]!=0) && (data[0]!=1))
+	if (data[0]) {
+		devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
+	}			// if  (data[0]
+	else {
+		devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
+	}			// else if  (data[0]
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI2016_WriteDigitalOutput                      |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Writes port value  To the selected port                |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                     UINT ui_NoOfChannels    : No Of Channels To Write      |
+|                     UINT *data              : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+int i_APCI2016_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_NoOfChannel;
+	UINT ui_Temp, ui_Temp1;
+	ui_NoOfChannel = CR_CHAN(insn->chanspec);
+	if ((ui_NoOfChannel < 0) || (ui_NoOfChannel > 15)) {
+		comedi_error(dev,
+			"Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n");
+		return -EINVAL;
+	}			// if  ((ui_NoOfChannel<0) || (ui_NoOfChannel>15))
+	if (devpriv->b_OutputMemoryStatus) {
+		ui_Temp = inw(devpriv->iobase + APCI2016_DIGITAL_OP);
+	}			// if  (devpriv->b_OutputMemoryStatus )
+	else {
+		ui_Temp = 0;
+	}			// else if  (devpriv->b_OutputMemoryStatus )
+	if ((data[1] != 0) && (data[1] != 1)) {
+		comedi_error(dev,
+			"Invalid Data[1] value !!!, Data[1] should be 0 or 1\n");
+		return -EINVAL;
+	}			// if  ((data[1]!=0) && (data[1]!=1))
+
+	if (data[3] == 0) {
+		if (data[1] == 0) {
+			data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
+			outw(data[0], devpriv->iobase + APCI2016_DIGITAL_OP);
+		}		// if (data[1]==0)
+		else {
+			if (data[1] == 1) {
+				switch (ui_NoOfChannel) {
+				case 2:
+					data[0] =
+						(data[0] << (2 *
+							data[2])) | ui_Temp;
+					break;
+				case 4:
+					data[0] =
+						(data[0] << (4 *
+							data[2])) | ui_Temp;
+					break;
+				case 8:
+					data[0] =
+						(data[0] << (8 *
+							data[2])) | ui_Temp;
+					break;
+				case 15:
+					data[0] = data[0] | ui_Temp;
+					break;
+				default:
+					comedi_error(dev, " chan spec wrong");
+					return -EINVAL;	// "sorry channel spec wrong "
+				}	//switch(ui_NoOfChannels)
+				outw(data[0],
+					devpriv->iobase + APCI2016_DIGITAL_OP);
+			}	// if  (data[1]==1)
+			else {
+				printk("\nSpecified channel not supported\n");
+			}	// else if  (data[1]==1)
+		}		// else if (data[1]==0)
+	}			// if (data[3]==0)
+	else {
+		if (data[3] == 1) {
+			if (data[1] == 0) {
+				data[0] = ~data[0] & 0x1;
+				ui_Temp1 = 1;
+				ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+				ui_Temp = ui_Temp | ui_Temp1;
+				data[0] = (data[0] << ui_NoOfChannel) ^ 0xffff;
+				data[0] = data[0] & ui_Temp;
+				outw(data[0],
+					devpriv->iobase + APCI2016_DIGITAL_OP);
+			}	// if  (data[1]==0)
+			else {
+				if (data[1] == 1) {
+					switch (ui_NoOfChannel) {
+					case 2:
+						data[0] = ~data[0] & 0x3;
+						ui_Temp1 = 3;
+						ui_Temp1 =
+							ui_Temp1 << 2 * data[2];
+						ui_Temp = ui_Temp | ui_Temp1;
+						data[0] =
+							((data[0] << (2 *
+									data
+									[2])) ^
+							0xffff) & ui_Temp;
+						break;
+					case 4:
+						data[0] = ~data[0] & 0xf;
+						ui_Temp1 = 15;
+						ui_Temp1 =
+							ui_Temp1 << 4 * data[2];
+						ui_Temp = ui_Temp | ui_Temp1;
+						data[0] =
+							((data[0] << (4 *
+									data
+									[2])) ^
+							0xffff) & ui_Temp;
+						break;
+					case 8:
+						data[0] = ~data[0] & 0xff;
+						ui_Temp1 = 255;
+						ui_Temp1 =
+							ui_Temp1 << 8 * data[2];
+						ui_Temp = ui_Temp | ui_Temp1;
+						data[0] =
+							((data[0] << (8 *
+									data
+									[2])) ^
+							0xffff) & ui_Temp;
+						break;
+					case 15:
+						break;
+					default:
+						comedi_error(dev,
+							" chan spec wrong");
+						return -EINVAL;	// "sorry channel spec wrong "
+					}	//switch(ui_NoOfChannels)
+					outw(data[0],
+						devpriv->iobase +
+						APCI2016_DIGITAL_OP);
+				}	// if(data[1]==1)
+				else {
+					printk("\nSpecified channel not supported\n");
+				}	//else if(data[1]==1)
+			}	//elseif(data[1]==0)
+		}		//if(data[3]==1);
+		else {
+			printk("\nSpecified functionality does not exist\n");
+			return -EINVAL;
+		}		//if else data[3]==1)
+	}			//if else data[3]==0)
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI2016_BitsDigitalOutput                       |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Read  value  of the selected channel or port           |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                     UINT ui_NoOfChannels    : No Of Channels To read       |
+|                     UINT *data              : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+int i_APCI2016_BitsDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_Temp;
+	UINT ui_NoOfChannel;
+	ui_NoOfChannel = CR_CHAN(insn->chanspec);
+	if ((ui_NoOfChannel < 0) || (ui_NoOfChannel > 15)) {
+		comedi_error(dev,
+			"Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n");
+		return -EINVAL;
+	}			// if  ((ui_NoOfChannel<0) || (ui_NoOfChannel>15))
+	if ((data[0] != 0) && (data[0] != 1)) {
+		comedi_error(dev,
+			"Invalid Data[0] value !!!, Data[0] should be 0 or 1\n");
+		return -EINVAL;
+	}			// if  ((data[0]!=0) && (data[0]!=1))
+	ui_Temp = data[0];
+	*data = inw(devpriv->iobase + APCI2016_DIGITAL_OP_RW);
+	if (ui_Temp == 0) {
+		*data = (*data >> ui_NoOfChannel) & 0x1;
+	}			// if  (ui_Temp==0)
+	else {
+		if (ui_Temp == 1) {
+			switch (ui_NoOfChannel) {
+			case 2:
+				*data = (*data >> (2 * data[1])) & 3;
+				break;
+
+			case 4:
+				*data = (*data >> (4 * data[1])) & 15;
+				break;
+
+			case 8:
+				*data = (*data >> (8 * data[1])) & 255;
+				break;
+
+			case 15:
+				break;
+
+			default:
+				comedi_error(dev, " chan spec wrong");
+				return -EINVAL;	// "sorry channel spec wrong "
+			}	//switch(ui_NoOfChannel)
+		}		// if  (ui_Temp==1)
+		else {
+			printk("\nSpecified channel not supported \n");
+		}		// else if  (ui_Temp==1)
+	}			// if  (ui_Temp==0)
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI2016_ConfigWatchdog                          |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Configures The Watchdog                                |
++----------------------------------------------------------------------------+
+| Input Parameters  :   struct comedi_device *dev      : Driver handle              |
+|                     struct comedi_subdevice *s,   :pointer to subdevice structure |
+|                     struct comedi_insn *insn      :pointer to insn structure      |
+|                     unsigned int *data          : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+int i_APCI2016_ConfigWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+
+	if (data[0] == 0) {
+		//Disable the watchdog
+		outw(0x0,
+			devpriv->i_IobaseAddon +
+			APCI2016_WATCHDOG_ENABLEDISABLE);
+		//Loading the Reload value
+		outw(data[1],
+			devpriv->i_IobaseAddon +
+			APCI2016_WATCHDOG_RELOAD_VALUE);
+		data[1] = data[1] >> 16;
+		outw(data[1],
+			devpriv->i_IobaseAddon +
+			APCI2016_WATCHDOG_RELOAD_VALUE + 2);
+	} else {
+		printk("\nThe input parameters are wrong\n");
+	}
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI2016_StartStopWriteWatchdog                  |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Start / Stop The Watchdog                              |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                     struct comedi_subdevice *s,   :pointer to subdevice structure |
+|                     struct comedi_insn *insn      :pointer to insn structure      |
+|                     unsigned int *data          : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+int i_APCI2016_StartStopWriteWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+
+	switch (data[0]) {
+	case 0:		//stop the watchdog
+		outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_ENABLEDISABLE);	//disable the watchdog
+		break;
+	case 1:		//start the watchdog
+		outw(0x0001,
+			devpriv->i_IobaseAddon +
+			APCI2016_WATCHDOG_ENABLEDISABLE);
+		break;
+	case 2:		//Software trigger
+		outw(0x0201,
+			devpriv->i_IobaseAddon +
+			APCI2016_WATCHDOG_ENABLEDISABLE);
+		break;
+	default:
+		printk("\nSpecified functionality does not exist\n");
+		return -EINVAL;
+	}			// switch(data[0])
+
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI2016_ReadWatchdog                            |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Read The Watchdog                                      |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                     struct comedi_subdevice *s,   :pointer to subdevice structure |
+|                     struct comedi_insn *insn      :pointer to insn structure      |
+|                     unsigned int *data          : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI2016_ReadWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	udelay(5);
+	data[0] = inw(devpriv->i_IobaseAddon + APCI2016_WATCHDOG_STATUS) & 0x1;
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI2016_Reset(struct comedi_device *dev)               |                                                       |
++----------------------------------------------------------------------------+
+| Task              :resets all the registers                                |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      :                                                        |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2016_Reset(struct comedi_device * dev)
+{
+	outw(0x0, devpriv->iobase + APCI2016_DIGITAL_OP);	// Resets the digital output channels
+	outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_ENABLEDISABLE);
+	outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_RELOAD_VALUE);
+	outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_RELOAD_VALUE + 2);
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h
new file mode 100644
index 0000000..9261aac
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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.
+ */
+/*********      Definitions for APCI-2016 card  *****/
+
+#define APCI2016_BOARD_VENDOR_ID 0x15B8
+#define APCI2016_ADDRESS_RANGE   8
+
+//DIGITAL INPUT-OUTPUT DEFINE
+
+#define APCI2016_DIGITAL_OP                 	0x04
+#define APCI2016_DIGITAL_OP_RW                 	4
+
+//ADDIDATA Enable Disable
+
+#define ADDIDATA_ENABLE                            1
+#define ADDIDATA_DISABLE                           0
+
+// TIMER COUNTER WATCHDOG DEFINES
+
+#define ADDIDATA_WATCHDOG                          2
+#define APCI2016_DIGITAL_OP_WATCHDOG               0
+#define APCI2016_WATCHDOG_ENABLEDISABLE            12
+#define APCI2016_WATCHDOG_RELOAD_VALUE             4
+#define APCI2016_WATCHDOG_STATUS                   16
+
+// Hardware Layer  functions for Apci2016
+
+//DO
+int i_APCI2016_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+				   struct comedi_insn *insn, unsigned int *data);
+
+int i_APCI2016_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+				  struct comedi_insn *insn, unsigned int *data);
+
+int i_APCI2016_BitsDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data);
+
+// TIMER
+// timer value is passed as u seconds
+
+int i_APCI2016_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+			      struct comedi_insn *insn, unsigned int *data);
+
+int i_APCI2016_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+				      struct comedi_insn *insn, unsigned int *data);
+
+int i_APCI2016_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+			    struct comedi_insn *insn, unsigned int *data);
+
+// Interrupt functions.....
+
+// void v_APCI2016_Interrupt(int irq, void *d) ;
+
+ //void v_APCI2016_Interrupt(int irq, void *d);
+// RESET
+INT i_APCI2016_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c
new file mode 100644
index 0000000..1347bc3
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c
@@ -0,0 +1,579 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+
+        ADDI-DATA GmbH
+        Dieselstrasse 3
+        D-77833 Ottersweier
+        Tel: +19(0)7223/9493-0
+        Fax: +49(0)7223/9493-92
+        http://www.addi-data-com
+        info@addi-data.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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+  +-----------------------------------------------------------------------+
+  | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
+  +-----------------------------------------------------------------------+
+  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
+  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
+  +-------------------------------+---------------------------------------+
+  | Project     : APCI-2032       | Compiler   : GCC                      |
+  | Module name : hwdrv_apci2032.c| Version    : 2.96                     |
+  +-------------------------------+---------------------------------------+
+  | Project manager: Eric Stolz   | Date       :  02/12/2002              |
+  +-------------------------------+---------------------------------------+
+  | Description :   Hardware Layer Acces For APCI-2032                    |
+  +-----------------------------------------------------------------------+
+  |                             UPDATES                                   |
+  +----------+-----------+------------------------------------------------+
+  |   Date   |   Author  |          Description of updates                |
+  +----------+-----------+------------------------------------------------+
+  |          |           |                                                |
+  |          |           |                                                |
+  |          |           |                                                |
+  +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+|                               Included files                               |
++----------------------------------------------------------------------------+
+*/
+
+#include "hwdrv_apci2032.h"
+UINT ui_InterruptData, ui_Type;
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI2032_ConfigDigitalOutput                     |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Configures The Digital Output Subdevice.               |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev : Driver handle                     |
+|                     UINT *data         : Data Pointer contains             |
+|                                          configuration parameters as below |
+|                                                                            |
+|					  data[1]            : 1 Enable  VCC  Interrupt  |
+|										   0 Disable VCC  Interrupt  |
+|					  data[2]            : 1 Enable  CC  Interrupt   |
+|										   0 Disable CC  Interrupt   |
+|																	 |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+int i_APCI2032_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	ULONG ul_Command = 0;
+	devpriv->tsk_Current = current;
+
+	if ((data[0] != 0) && (data[0] != 1)) {
+		comedi_error(dev,
+			"Not a valid Data !!! ,Data should be 1 or 0\n");
+		return -EINVAL;
+	}			//if  ( (data[0]!=0) && (data[0]!=1) )
+	if (data[0]) {
+		devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
+	}			// if  (data[0])
+	else {
+		devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
+	}			//else if  (data[0])
+
+	if (data[1] == ADDIDATA_ENABLE) {
+		ul_Command = ul_Command | 0x1;
+	}			//if  (data[1] == ADDIDATA_ENABLE)
+	else {
+		ul_Command = ul_Command & 0xFFFFFFFE;
+	}			//elseif  (data[1] == ADDIDATA_ENABLE)
+	if (data[2] == ADDIDATA_ENABLE) {
+		ul_Command = ul_Command | 0x2;
+	}			//if  (data[2] == ADDIDATA_ENABLE)
+	else {
+		ul_Command = ul_Command & 0xFFFFFFFD;
+	}			//elseif  (data[2] == ADDIDATA_ENABLE)
+	outl(ul_Command, devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT);
+	ui_InterruptData = inl(devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT);
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI2032_WriteDigitalOutput                      |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Writes port value  To the selected port                |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                     UINT ui_NoOfChannels    : No Of Channels To Write      |
+|                     UINT *data              : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2032_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_Temp, ui_Temp1;
+	UINT ui_NoOfChannel = CR_CHAN(insn->chanspec);	// get the channel
+	if (devpriv->b_OutputMemoryStatus) {
+		ui_Temp = inl(devpriv->iobase + APCI2032_DIGITAL_OP);
+
+	}			//if(devpriv->b_OutputMemoryStatus )
+	else {
+		ui_Temp = 0;
+	}			//if(devpriv->b_OutputMemoryStatus )
+	if (data[3] == 0) {
+		if (data[1] == 0) {
+			data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
+			outl(data[0], devpriv->iobase + APCI2032_DIGITAL_OP);
+		}		//if(data[1]==0)
+		else {
+			if (data[1] == 1) {
+				switch (ui_NoOfChannel) {
+
+				case 2:
+					data[0] =
+						(data[0] << (2 *
+							data[2])) | ui_Temp;
+					break;
+
+				case 4:
+					data[0] =
+						(data[0] << (4 *
+							data[2])) | ui_Temp;
+					break;
+
+				case 8:
+					data[0] =
+						(data[0] << (8 *
+							data[2])) | ui_Temp;
+					break;
+
+				case 16:
+					data[0] =
+						(data[0] << (16 *
+							data[2])) | ui_Temp;
+					break;
+				case 31:
+					data[0] = data[0] | ui_Temp;
+					break;
+
+				default:
+					comedi_error(dev, " chan spec wrong");
+					return -EINVAL;	// "sorry channel spec wrong "
+
+				}	//switch(ui_NoOfChannels)
+
+				outl(data[0],
+					devpriv->iobase + APCI2032_DIGITAL_OP);
+			}	// if(data[1]==1)
+			else {
+				printk("\nSpecified channel not supported\n");
+			}	//else if(data[1]==1)
+		}		//elseif(data[1]==0)
+	}			//if(data[3]==0)
+	else {
+		if (data[3] == 1) {
+			if (data[1] == 0) {
+				data[0] = ~data[0] & 0x1;
+				ui_Temp1 = 1;
+				ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+				ui_Temp = ui_Temp | ui_Temp1;
+				data[0] =
+					(data[0] << ui_NoOfChannel) ^
+					0xffffffff;
+				data[0] = data[0] & ui_Temp;
+				outl(data[0],
+					devpriv->iobase + APCI2032_DIGITAL_OP);
+			}	//if(data[1]==0)
+			else {
+				if (data[1] == 1) {
+					switch (ui_NoOfChannel) {
+
+					case 2:
+						data[0] = ~data[0] & 0x3;
+						ui_Temp1 = 3;
+						ui_Temp1 =
+							ui_Temp1 << 2 * data[2];
+						ui_Temp = ui_Temp | ui_Temp1;
+						data[0] =
+							((data[0] << (2 *
+									data
+									[2])) ^
+							0xffffffff) & ui_Temp;
+						break;
+
+					case 4:
+						data[0] = ~data[0] & 0xf;
+						ui_Temp1 = 15;
+						ui_Temp1 =
+							ui_Temp1 << 4 * data[2];
+						ui_Temp = ui_Temp | ui_Temp1;
+						data[0] =
+							((data[0] << (4 *
+									data
+									[2])) ^
+							0xffffffff) & ui_Temp;
+						break;
+
+					case 8:
+						data[0] = ~data[0] & 0xff;
+						ui_Temp1 = 255;
+						ui_Temp1 =
+							ui_Temp1 << 8 * data[2];
+						ui_Temp = ui_Temp | ui_Temp1;
+						data[0] =
+							((data[0] << (8 *
+									data
+									[2])) ^
+							0xffffffff) & ui_Temp;
+						break;
+
+					case 16:
+						data[0] = ~data[0] & 0xffff;
+						ui_Temp1 = 65535;
+						ui_Temp1 =
+							ui_Temp1 << 16 *
+							data[2];
+						ui_Temp = ui_Temp | ui_Temp1;
+						data[0] =
+							((data[0] << (16 *
+									data
+									[2])) ^
+							0xffffffff) & ui_Temp;
+						break;
+
+					case 31:
+						break;
+					default:
+						comedi_error(dev,
+							" chan spec wrong");
+						return -EINVAL;	// "sorry channel spec wrong "
+
+					}	//switch(ui_NoOfChannels)
+
+					outl(data[0],
+						devpriv->iobase +
+						APCI2032_DIGITAL_OP);
+				}	// if(data[1]==1)
+				else {
+					printk("\nSpecified channel not supported\n");
+				}	//else if(data[1]==1)
+			}	//elseif(data[1]==0)
+		}		//if(data[3]==1);
+		else {
+			printk("\nSpecified functionality does not exist\n");
+			return -EINVAL;
+		}		//if else data[3]==1)
+	}			//if else data[3]==0)
+	return (insn->n);;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI2032_ReadDigitalOutput                       |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Read  value  of the selected channel or port           |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                     UINT ui_NoOfChannels    : No Of Channels To read       |
+|                     UINT *data              : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2032_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_Temp;
+	UINT ui_NoOfChannel;
+	ui_NoOfChannel = CR_CHAN(insn->chanspec);
+	ui_Temp = data[0];
+	*data = inl(devpriv->iobase + APCI2032_DIGITAL_OP_RW);
+	if (ui_Temp == 0) {
+		*data = (*data >> ui_NoOfChannel) & 0x1;
+	}			//if  (ui_Temp==0)
+	else {
+		if (ui_Temp == 1) {
+			switch (ui_NoOfChannel) {
+
+			case 2:
+				*data = (*data >> (2 * data[1])) & 3;
+				break;
+
+			case 4:
+				*data = (*data >> (4 * data[1])) & 15;
+				break;
+
+			case 8:
+				*data = (*data >> (8 * data[1])) & 255;
+				break;
+
+			case 16:
+				*data = (*data >> (16 * data[1])) & 65535;
+				break;
+
+			case 31:
+				break;
+
+			default:
+				comedi_error(dev, " chan spec wrong");
+				return -EINVAL;	// "sorry channel spec wrong "
+
+			}	//switch(ui_NoOfChannels)
+		}		//if  (ui_Temp==1)
+		else {
+			printk("\nSpecified channel not supported \n");
+		}		//elseif  (ui_Temp==1)
+	}
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : INT i_APCI2032_ConfigWatchdog(comedi_device
+                   *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)|
+|				                                                     |
++----------------------------------------------------------------------------+
+| Task              : Configures The Watchdog                                |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                     struct comedi_subdevice *s,   :pointer to subdevice structure
+                      struct comedi_insn *insn      :pointer to insn structure      |
+|                     unsigned int *data          : Data Pointer to read status                                                                                                             |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI2032_ConfigWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (data[0] == 0) {
+		//Disable the watchdog
+		outl(0x0,
+			devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
+			APCI2032_TCW_PROG);
+		//Loading the Reload value
+		outl(data[1],
+			devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
+			APCI2032_TCW_RELOAD_VALUE);
+	} else {
+		printk("\nThe input parameters are wrong\n");
+		return -EINVAL;
+	}
+
+	return insn->n;
+}
+
+ /*
+    +----------------------------------------------------------------------------+
+    | Function   Name   : int i_APCI2032_StartStopWriteWatchdog                  |
+    |                           (struct comedi_device *dev,struct comedi_subdevice *s,
+    struct comedi_insn *insn,unsigned int *data);                      |
+    +----------------------------------------------------------------------------+
+    | Task              : Start / Stop The Watchdog                              |
+    +----------------------------------------------------------------------------+
+    | Input Parameters  : struct comedi_device *dev      : Driver handle                |
+    |                     struct comedi_subdevice *s,   :pointer to subdevice structure
+    struct comedi_insn *insn      :pointer to insn structure      |
+    |                     unsigned int *data          : Data Pointer to read status  |
+    +----------------------------------------------------------------------------+
+    | Output Parameters :       --                                                                                                       |
+    +----------------------------------------------------------------------------+
+    | Return Value      : TRUE  : No error occur                                 |
+    |                       : FALSE : Error occur. Return the error          |
+    |                                                                            |
+    +----------------------------------------------------------------------------+
+  */
+
+int i_APCI2032_StartStopWriteWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	switch (data[0]) {
+	case 0:		//stop the watchdog
+		outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_PROG);	//disable the watchdog
+		break;
+	case 1:		//start the watchdog
+		outl(0x0001,
+			devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
+			APCI2032_TCW_PROG);
+		break;
+	case 2:		//Software trigger
+		outl(0x0201,
+			devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
+			APCI2032_TCW_PROG);
+		break;
+	default:
+		printk("\nSpecified functionality does not exist\n");
+		return -EINVAL;
+	}
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI2032_ReadWatchdog                            |
+|			(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+                    unsigned int *data); 	                                     |
++----------------------------------------------------------------------------+
+| Task              : Read The Watchdog                                      |
++----------------------------------------------------------------------------+
+| Input Parameters  :   struct comedi_device *dev      : Driver handle              |
+|                     struct comedi_subdevice *s,   :pointer to subdevice structure
+                      struct comedi_insn *insn      :pointer to insn structure      |
+|                     unsigned int *data          : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI2032_ReadWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+
+	data[0] =
+		inl(devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
+		APCI2032_TCW_TRIG_STATUS) & 0x1;
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   :  void v_APCI2032_Interrupt					         |
+|					  (int irq , void *d)      |
++----------------------------------------------------------------------------+
+| Task              : Writes port value  To the selected port                |
++----------------------------------------------------------------------------+
+| Input Parameters  : int irq                 : irq number                   |
+|                     void *d                 : void pointer                 |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+void v_APCI2032_Interrupt(int irq, void *d)
+{
+	struct comedi_device *dev = d;
+	unsigned int ui_DO;
+
+	ui_DO = inl(devpriv->iobase + APCI2032_DIGITAL_OP_IRQ) & 0x1;	//Check if VCC OR CC interrupt has occured.
+
+	if (ui_DO == 0) {
+		printk("\nInterrupt from unKnown source\n");
+	}			// if(ui_DO==0)
+	if (ui_DO) {
+		// Check for Digital Output interrupt Type - 1: Vcc interrupt 2: CC interrupt.
+		ui_Type =
+			inl(devpriv->iobase +
+			APCI2032_DIGITAL_OP_INTERRUPT_STATUS) & 0x3;
+		outl(0x0,
+			devpriv->iobase + APCI2032_DIGITAL_OP +
+			APCI2032_DIGITAL_OP_INTERRUPT);
+		if (ui_Type == 1) {
+			//Sends signal to user space
+			send_sig(SIGIO, devpriv->tsk_Current, 0);
+		}		// if (ui_Type==1)
+		else {
+			if (ui_Type == 2) {
+				// Sends signal to user space
+				send_sig(SIGIO, devpriv->tsk_Current, 0);
+			}	//if (ui_Type==2)
+		}		//else if (ui_Type==1)
+	}			//if(ui_DO)
+
+	return;
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   :  int i_APCI2032_ReadInterruptStatus                    |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              :Reads the interrupt status register                     |
++----------------------------------------------------------------------------+
+| Input Parameters  :                                                        |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      :                                                        |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI2032_ReadInterruptStatus(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	*data = ui_Type;
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   :  int i_APCI2032_Reset(struct comedi_device *dev)			     |
+|					                                                 |
++----------------------------------------------------------------------------+
+| Task              :Resets the registers of the card                        |
++----------------------------------------------------------------------------+
+| Input Parameters  :                                                        |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      :                                                        |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI2032_Reset(struct comedi_device * dev)
+{
+	devpriv->b_DigitalOutputRegister = 0;
+	ui_Type = 0;
+	outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP);	//Resets the output channels
+	outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT);	//Disables the interrupt.
+	outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_PROG);	//disable the watchdog
+	outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_RELOAD_VALUE);	//reload=0
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h
new file mode 100644
index 0000000..55002e0
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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.
+ */
+
+/*********      Definitions for APCI-2032 card  *****/
+
+// Card Specific information
+#define APCI2032_BOARD_VENDOR_ID                 0x15B8
+#define APCI2032_ADDRESS_RANGE                   63
+
+//DIGITAL INPUT-OUTPUT DEFINE
+
+#define APCI2032_DIGITAL_OP                 	0
+#define APCI2032_DIGITAL_OP_RW                 	0
+#define APCI2032_DIGITAL_OP_INTERRUPT           4
+#define APCI2032_DIGITAL_OP_IRQ                 12
+
+//Digital Output Interrupt Status
+#define APCI2032_DIGITAL_OP_INTERRUPT_STATUS    8
+
+//Digital Output Interrupt Enable Disable.
+#define APCI2032_DIGITAL_OP_VCC_INTERRUPT_ENABLE   0x1
+#define APCI2032_DIGITAL_OP_VCC_INTERRUPT_DISABLE  0xFFFFFFFE
+#define APCI2032_DIGITAL_OP_CC_INTERRUPT_ENABLE    0x2
+#define APCI2032_DIGITAL_OP_CC_INTERRUPT_DISABLE   0xFFFFFFFD
+
+//ADDIDATA Enable Disable
+
+#define ADDIDATA_ENABLE                            1
+#define ADDIDATA_DISABLE                           0
+
+// TIMER COUNTER WATCHDOG DEFINES
+
+#define ADDIDATA_WATCHDOG                          2
+#define APCI2032_DIGITAL_OP_WATCHDOG               16
+#define APCI2032_TCW_RELOAD_VALUE                  4
+#define APCI2032_TCW_TIMEBASE                      8
+#define APCI2032_TCW_PROG                          12
+#define APCI2032_TCW_TRIG_STATUS                   16
+#define APCI2032_TCW_IRQ                           20
+
+// Hardware Layer  functions for Apci2032
+
+//DO
+int i_APCI2032_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+				   struct comedi_insn *insn, unsigned int *data);
+INT i_APCI2032_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+				  struct comedi_insn *insn, unsigned int *data);
+INT i_APCI2032_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data);
+int i_APCI2032_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subdevice *s,
+				   struct comedi_insn *insn, unsigned int *data);
+
+// TIMER
+// timer value is passed as u seconds
+INT i_APCI2032_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+			      struct comedi_insn *insn, unsigned int *data);
+int i_APCI2032_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+				      struct comedi_insn *insn, unsigned int *data);
+int i_APCI2032_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+			    struct comedi_insn *insn, unsigned int *data);
+
+// Interrupt functions.....
+
+void v_APCI2032_Interrupt(int irq, void *d);
+
+//Reset functions
+int i_APCI2032_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c
new file mode 100644
index 0000000..947e18e
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c
@@ -0,0 +1,549 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+
+        ADDI-DATA GmbH
+        Dieselstrasse 3
+        D-77833 Ottersweier
+        Tel: +19(0)7223/9493-0
+        Fax: +49(0)7223/9493-92
+        http://www.addi-data-com
+        info@addi-data.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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+  +-----------------------------------------------------------------------+
+  | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
+  +-----------------------------------------------------------------------+
+  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
+  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
+  +-------------------------------+---------------------------------------+
+  | Project     : APCI-2200       | Compiler   : GCC                      |
+  | Module name : hwdrv_apci2200.c| Version    : 2.96                     |
+  +-------------------------------+---------------------------------------+
+  | Project manager: Eric Stolz   | Date       :  02/12/2002              |
+  +-------------------------------+---------------------------------------+
+  | Description :   Hardware Layer Acces For APCI-2200                    |
+  +-----------------------------------------------------------------------+
+  |                             UPDATES                                   |
+  +----------+-----------+------------------------------------------------+
+  |   Date   |   Author  |          Description of updates                |
+  +----------+-----------+------------------------------------------------+
+  |          |           |                                                |
+  |          |           |                                                |
+  |          |           |                                                |
+  +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+|                               Included files                               |
++----------------------------------------------------------------------------+
+*/
+#include "hwdrv_apci2200.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI2200_Read1DigitalInput                       |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Return the status of the digital input                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|		       struct comedi_subdevice *s,   :pointer to subdevice structure
+                       struct comedi_insn *insn      :pointer to insn structure     |
+|                     unsigned int *data          : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI2200_Read1DigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_TmpValue = 0;
+	UINT ui_Channel;
+	ui_Channel = CR_CHAN(insn->chanspec);
+	if (ui_Channel >= 0 && ui_Channel <= 7) {
+		ui_TmpValue = (UINT) inw(devpriv->iobase + APCI2200_DIGITAL_IP);
+		*data = (ui_TmpValue >> ui_Channel) & 0x1;
+	}			//if(ui_Channel >= 0 && ui_Channel <=7)
+	else {
+		printk("\nThe specified channel does not exist\n");
+		return -EINVAL;	// "sorry channel spec wrong "
+	}			//else if(ui_Channel >= 0 && ui_Channel <=7)
+
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI2200_ReadMoreDigitalInput                    |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                     struct comedi_insn *insn,unsigned int *data)                      |
++----------------------------------------------------------------------------+
+| Task              : Return the status of the Requested digital inputs      |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                      struct comedi_subdevice *s,   :pointer to subdevice structure
+                       struct comedi_insn *insn      :pointer to insn structure     |
+|                      unsigned int *data         : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2200_ReadMoreDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+
+	UINT ui_PortValue = data[0];
+	UINT ui_Mask = 0;
+	UINT ui_NoOfChannels;
+
+	ui_NoOfChannels = CR_CHAN(insn->chanspec);
+
+	*data = (UINT) inw(devpriv->iobase + APCI2200_DIGITAL_IP);
+	switch (ui_NoOfChannels) {
+	case 2:
+		ui_Mask = 3;
+		*data = (*data >> (2 * ui_PortValue)) & ui_Mask;
+		break;
+	case 4:
+		ui_Mask = 15;
+		*data = (*data >> (4 * ui_PortValue)) & ui_Mask;
+		break;
+	case 7:
+		break;
+
+	default:
+		printk("\nWrong parameters\n");
+		return -EINVAL;	// "sorry channel spec wrong "
+		break;
+	}			//switch(ui_NoOfChannels)
+
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI2200_ConfigDigitalOutput (struct comedi_device *dev,
+                    struct comedi_subdevice *s struct comedi_insn *insn,unsigned int *data)    |
+|				                                                     |
++----------------------------------------------------------------------------+
+| Task              : Configures The Digital Output Subdevice.               |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev : Driver handle                     |
+|                     unsigned int *data         : Data Pointer contains         |
+|                                          configuration parameters as below |
+|                      struct comedi_subdevice *s,   :pointer to subdevice structure
+                       struct comedi_insn *insn      :pointer to insn structure                                                           |
+|					  data[0]  :1:Memory on                          |
+|					            0:Memory off                         |
+|										                             |
+|																	 |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+int i_APCI2200_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	devpriv->b_OutputMemoryStatus = data[0];
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI2200_WriteDigitalOutput                      |
+|			(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+                     unsigned int *data)                                         |
++----------------------------------------------------------------------------+
+| Task              : Writes port value  To the selected port                |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                     struct comedi_subdevice *s,   :pointer to subdevice structure
+                      struct comedi_insn *insn      :pointer to insn structure      |
+|                    unsigned int *data           : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2200_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_Temp, ui_Temp1;
+	UINT ui_NoOfChannel = CR_CHAN(insn->chanspec);	// get the channel
+	if (devpriv->b_OutputMemoryStatus) {
+		ui_Temp = inw(devpriv->iobase + APCI2200_DIGITAL_OP);
+
+	}			//if(devpriv->b_OutputMemoryStatus )
+	else {
+		ui_Temp = 0;
+	}			//if(devpriv->b_OutputMemoryStatus )
+	if (data[3] == 0) {
+		if (data[1] == 0) {
+			data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
+			outw(data[0], devpriv->iobase + APCI2200_DIGITAL_OP);
+		}		//if(data[1]==0)
+		else {
+			if (data[1] == 1) {
+				switch (ui_NoOfChannel) {
+
+				case 2:
+					data[0] =
+						(data[0] << (2 *
+							data[2])) | ui_Temp;
+					break;
+
+				case 4:
+					data[0] =
+						(data[0] << (4 *
+							data[2])) | ui_Temp;
+					break;
+
+				case 8:
+					data[0] =
+						(data[0] << (8 *
+							data[2])) | ui_Temp;
+					break;
+				case 15:
+					data[0] = data[0] | ui_Temp;
+					break;
+				default:
+					comedi_error(dev, " chan spec wrong");
+					return -EINVAL;	// "sorry channel spec wrong "
+
+				}	//switch(ui_NoOfChannels)
+
+				outw(data[0],
+					devpriv->iobase + APCI2200_DIGITAL_OP);
+			}	// if(data[1]==1)
+			else {
+				printk("\nSpecified channel not supported\n");
+			}	//else if(data[1]==1)
+		}		//elseif(data[1]==0)
+	}			//if(data[3]==0)
+	else {
+		if (data[3] == 1) {
+			if (data[1] == 0) {
+				data[0] = ~data[0] & 0x1;
+				ui_Temp1 = 1;
+				ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+				ui_Temp = ui_Temp | ui_Temp1;
+				data[0] = (data[0] << ui_NoOfChannel) ^ 0xffff;
+				data[0] = data[0] & ui_Temp;
+				outw(data[0],
+					devpriv->iobase + APCI2200_DIGITAL_OP);
+			}	//if(data[1]==0)
+			else {
+				if (data[1] == 1) {
+					switch (ui_NoOfChannel) {
+
+					case 2:
+						data[0] = ~data[0] & 0x3;
+						ui_Temp1 = 3;
+						ui_Temp1 =
+							ui_Temp1 << 2 * data[2];
+						ui_Temp = ui_Temp | ui_Temp1;
+						data[0] =
+							((data[0] << (2 *
+									data
+									[2])) ^
+							0xffff) & ui_Temp;
+						break;
+
+					case 4:
+						data[0] = ~data[0] & 0xf;
+						ui_Temp1 = 15;
+						ui_Temp1 =
+							ui_Temp1 << 4 * data[2];
+						ui_Temp = ui_Temp | ui_Temp1;
+						data[0] =
+							((data[0] << (4 *
+									data
+									[2])) ^
+							0xffff) & ui_Temp;
+						break;
+
+					case 8:
+						data[0] = ~data[0] & 0xff;
+						ui_Temp1 = 255;
+						ui_Temp1 =
+							ui_Temp1 << 8 * data[2];
+						ui_Temp = ui_Temp | ui_Temp1;
+						data[0] =
+							((data[0] << (8 *
+									data
+									[2])) ^
+							0xffff) & ui_Temp;
+						break;
+					case 15:
+						break;
+
+					default:
+						comedi_error(dev,
+							" chan spec wrong");
+						return -EINVAL;	// "sorry channel spec wrong "
+
+					}	//switch(ui_NoOfChannels)
+
+					outw(data[0],
+						devpriv->iobase +
+						APCI2200_DIGITAL_OP);
+				}	// if(data[1]==1)
+				else {
+					printk("\nSpecified channel not supported\n");
+				}	//else if(data[1]==1)
+			}	//elseif(data[1]==0)
+		}		//if(data[3]==1);
+		else {
+			printk("\nSpecified functionality does not exist\n");
+			return -EINVAL;
+		}		//if else data[3]==1)
+	}			//if else data[3]==0)
+	return (insn->n);;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI2200_ReadDigitalOutput                       |
+|			(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+                    unsigned int *data) 	                                     |
++----------------------------------------------------------------------------+
+| Task              : Read  value  of the selected channel or port           |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                     struct comedi_subdevice *s,   :pointer to subdevice structure
+                      struct comedi_insn *insn      :pointer to insn structure      |
+|                     unsigned int *data          : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2200_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+
+	UINT ui_Temp;
+	UINT ui_NoOfChannel = CR_CHAN(insn->chanspec);	// get the channel
+	ui_Temp = data[0];
+	*data = inw(devpriv->iobase + APCI2200_DIGITAL_OP);
+	if (ui_Temp == 0) {
+		*data = (*data >> ui_NoOfChannel) & 0x1;
+	}			//if(ui_Temp==0)
+	else {
+		if (ui_Temp == 1) {
+			switch (ui_NoOfChannel) {
+
+			case 2:
+				*data = (*data >> (2 * data[1])) & 3;
+				break;
+
+			case 4:
+				*data = (*data >> (4 * data[1])) & 15;
+				break;
+
+			case 8:
+				*data = (*data >> (8 * data[1])) & 255;
+				break;
+
+			case 15:
+				break;
+
+			default:
+				comedi_error(dev, " chan spec wrong");
+				return -EINVAL;	// "sorry channel spec wrong "
+
+			}	//switch(ui_NoOfChannels)
+		}		//if(ui_Temp==1)
+		else {
+			printk("\nSpecified channel not supported \n");
+		}		//elseif(ui_Temp==1)
+	}			//elseif(ui_Temp==0)
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI2200_ConfigWatchdog(struct comedi_device *dev,
+                      struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)  |
+|				                                                     |
++----------------------------------------------------------------------------+
+| Task              : Configures The Watchdog                                |
++----------------------------------------------------------------------------+
+| Input Parameters  :   struct comedi_device *dev      : Driver handle              |
+|                     struct comedi_subdevice *s,   :pointer to subdevice structure
+                      struct comedi_insn *insn      :pointer to insn structure      |
+|                     unsigned int *data          : Data Pointer to read status                                                                                                             |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI2200_ConfigWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (data[0] == 0) {
+		//Disable the watchdog
+		outw(0x0,
+			devpriv->iobase + APCI2200_WATCHDOG +
+			APCI2200_WATCHDOG_ENABLEDISABLE);
+		//Loading the Reload value
+		outw(data[1],
+			devpriv->iobase + APCI2200_WATCHDOG +
+			APCI2200_WATCHDOG_RELOAD_VALUE);
+		data[1] = data[1] >> 16;
+		outw(data[1],
+			devpriv->iobase + APCI2200_WATCHDOG +
+			APCI2200_WATCHDOG_RELOAD_VALUE + 2);
+	}			//if(data[0]==0)
+	else {
+		printk("\nThe input parameters are wrong\n");
+		return -EINVAL;
+	}			//elseif(data[0]==0)
+
+	return insn->n;
+}
+
+ /*
+    +----------------------------------------------------------------------------+
+    | Function   Name   : int i_APCI2200_StartStopWriteWatchdog                  |
+    |                           (struct comedi_device *dev,struct comedi_subdevice *s,
+    struct comedi_insn *insn,unsigned int *data);                      |
+    +----------------------------------------------------------------------------+
+    | Task              : Start / Stop The Watchdog                              |
+    +----------------------------------------------------------------------------+
+    | Input Parameters  : struct comedi_device *dev      : Driver handle                |
+    |                     struct comedi_subdevice *s,   :pointer to subdevice structure
+    struct comedi_insn *insn      :pointer to insn structure      |
+    |                     unsigned int *data          : Data Pointer to read status  |
+    +----------------------------------------------------------------------------+
+    | Output Parameters :       --                                                                                                       |
+    +----------------------------------------------------------------------------+
+    | Return Value      : TRUE  : No error occur                                 |
+    |                       : FALSE : Error occur. Return the error          |
+    |                                                                            |
+    +----------------------------------------------------------------------------+
+  */
+
+int i_APCI2200_StartStopWriteWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	switch (data[0]) {
+	case 0:		//stop the watchdog
+		outw(0x0, devpriv->iobase + APCI2200_WATCHDOG + APCI2200_WATCHDOG_ENABLEDISABLE);	//disable the watchdog
+		break;
+	case 1:		//start the watchdog
+		outw(0x0001,
+			devpriv->iobase + APCI2200_WATCHDOG +
+			APCI2200_WATCHDOG_ENABLEDISABLE);
+		break;
+	case 2:		//Software trigger
+		outw(0x0201,
+			devpriv->iobase + APCI2200_WATCHDOG +
+			APCI2200_WATCHDOG_ENABLEDISABLE);
+		break;
+	default:
+		printk("\nSpecified functionality does not exist\n");
+		return -EINVAL;
+	}			// switch(data[0])
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI2200_ReadWatchdog                            |
+|			(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+                    unsigned int *data); 	                                     |
++----------------------------------------------------------------------------+
+| Task              : Read The Watchdog                                      |
++----------------------------------------------------------------------------+
+| Input Parameters  :   struct comedi_device *dev      : Driver handle              |
+|                     struct comedi_subdevice *s,   :pointer to subdevice structure
+                      struct comedi_insn *insn      :pointer to insn structure      |
+|                     unsigned int *data          : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI2200_ReadWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	data[0] =
+		inw(devpriv->iobase + APCI2200_WATCHDOG +
+		APCI2200_WATCHDOG_STATUS) & 0x1;
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI2200_Reset(struct comedi_device *dev)               |                                                                                                          |
++----------------------------------------------------------------------------+
+| Task              :resets all the registers                                |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      :                                                        |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2200_Reset(struct comedi_device * dev)
+{
+	outw(0x0, devpriv->iobase + APCI2200_DIGITAL_OP);	//RESETS THE DIGITAL OUTPUTS
+	outw(0x0,
+		devpriv->iobase + APCI2200_WATCHDOG +
+		APCI2200_WATCHDOG_ENABLEDISABLE);
+	outw(0x0,
+		devpriv->iobase + APCI2200_WATCHDOG +
+		APCI2200_WATCHDOG_RELOAD_VALUE);
+	outw(0x0,
+		devpriv->iobase + APCI2200_WATCHDOG +
+		APCI2200_WATCHDOG_RELOAD_VALUE + 2);
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h
new file mode 100644
index 0000000..0a115b4
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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.
+ */
+
+/*********      Definitions for APCI-2200 card  *****/
+
+// Card Specific information
+#define APCI2200_BOARD_VENDOR_ID                 0x15b8
+#define APCI2200_ADDRESS_RANGE                   64
+
+//DIGITAL INPUT-OUTPUT DEFINE
+
+#define APCI2200_DIGITAL_OP                 	4
+#define APCI2200_DIGITAL_IP                     0
+
+// TIMER COUNTER WATCHDOG DEFINES
+
+#define APCI2200_WATCHDOG                          0x08
+#define APCI2200_WATCHDOG_ENABLEDISABLE            12
+#define APCI2200_WATCHDOG_RELOAD_VALUE             4
+#define APCI2200_WATCHDOG_STATUS                   16
+
+// Hardware Layer  functions for Apci2200
+
+//Digital Input
+INT i_APCI2200_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+				    struct comedi_insn *insn, unsigned int *data);
+INT i_APCI2200_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data);
+
+//Digital Output
+int i_APCI2200_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+				   struct comedi_insn *insn, unsigned int *data);
+INT i_APCI2200_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+				  struct comedi_insn *insn, unsigned int *data);
+INT i_APCI2200_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data);
+
+// TIMER
+int i_APCI2200_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+			      struct comedi_insn *insn, unsigned int *data);
+int i_APCI2200_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+				      struct comedi_insn *insn, unsigned int *data);
+int i_APCI2200_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+			    struct comedi_insn *insn, unsigned int *data);
+
+//reset
+INT i_APCI2200_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
new file mode 100644
index 0000000..68eb8df
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
@@ -0,0 +1,2697 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+
+        ADDI-DATA GmbH
+        Dieselstrasse 3
+        D-77833 Ottersweier
+        Tel: +19(0)7223/9493-0
+        Fax: +49(0)7223/9493-92
+        http://www.addi-data-com
+        info@addi-data.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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+  +-----------------------------------------------------------------------+
+  | (C) ADDI-DATA GmbH          Dieselstrasse 3      D-77833 Ottersweier  |
+  +-----------------------------------------------------------------------+
+  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
+  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
+  +-----------------------------------------------------------------------+
+  | Project     : APCI-3120       | Compiler   : GCC                      |
+  | Module name : hwdrv_apci3120.c| Version    : 2.96                     |
+  +-------------------------------+---------------------------------------+
+  | Project manager: Eric Stolz   | Date       :  02/12/2002              |
+  +-----------------------------------------------------------------------+
+  | Description :APCI3120 Module.  Hardware abstraction Layer for APCI3120|
+  +-----------------------------------------------------------------------+
+  |                             UPDATE'S                                  |
+  +-----------------------------------------------------------------------+
+  |   Date   |   Author  |          Description of updates                |
+  +----------+-----------+------------------------------------------------+
+  |          | 		 | 						  |
+  |          |           |						  |
+  +----------+-----------+------------------------------------------------+
+*/
+
+#include "hwdrv_apci3120.h"
+static UINT ui_Temp = 0;
+
+// FUNCTION DEFINITIONS
+
+/*
++----------------------------------------------------------------------------+
+|                           ANALOG INPUT SUBDEVICE   		                 |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function name     :int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev,|
+|  struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)					 |
+|                                            						         |
++----------------------------------------------------------------------------+
+| Task              : Calls card specific function  					     |
+|                     										                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev									 |
+|                     struct comedi_subdevice *s									 |
+|                     struct comedi_insn *insn                                      |
+|                     unsigned int *data      					         		 |
++----------------------------------------------------------------------------+
+| Return Value      :              					                         |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnConfigAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT i;
+
+	if ((data[0] != APCI3120_EOC_MODE) && (data[0] != APCI3120_EOS_MODE))
+		return -1;
+
+	// Check for Conversion time to be added ??
+	devpriv->ui_EocEosConversionTime = data[2];
+
+	if (data[0] == APCI3120_EOS_MODE) {
+
+		//Test the number of the channel
+		for (i = 0; i < data[3]; i++) {
+
+			if (CR_CHAN(data[4 + i]) >= this_board->i_NbrAiChannel) {
+				printk("bad channel list\n");
+				return -2;
+			}
+		}
+
+		devpriv->b_InterruptMode = APCI3120_EOS_MODE;
+
+		if (data[1]) {
+			devpriv->b_EocEosInterrupt = APCI3120_ENABLE;
+		} else
+			devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
+		// Copy channel list and Range List to devpriv
+
+		devpriv->ui_AiNbrofChannels = data[3];
+		for (i = 0; i < devpriv->ui_AiNbrofChannels; i++) {
+			devpriv->ui_AiChannelList[i] = data[4 + i];
+		}
+
+	} else			// EOC
+	{
+		devpriv->b_InterruptMode = APCI3120_EOC_MODE;
+		if (data[1]) {
+			devpriv->b_EocEosInterrupt = APCI3120_ENABLE;
+		} else {
+			devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
+		}
+	}
+
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name     :int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev,  |
+|			struct comedi_subdevice *s,struct comedi_insn *insn, unsigned int *data)	 |
+|                                            						         |
++----------------------------------------------------------------------------+
+| Task              :  card specific function								 |
+|				Reads analog input in synchronous mode               |
+|			  EOC and EOS is selected as per configured              |
+|                     if no conversion time is set uses default conversion   |
+|			  time 10 microsec.					      				 |
+|                     										                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev									 |
+|                     struct comedi_subdevice *s									 |
+|                     struct comedi_insn *insn                                      |
+|                     unsigned int *data     									 |
++----------------------------------------------------------------------------+
+| Return Value      :              					                         |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnReadAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	USHORT us_ConvertTiming, us_TmpValue, i;
+	BYTE b_Tmp;
+
+	// fix convertion time to 10 us
+	if (!devpriv->ui_EocEosConversionTime) {
+		printk("No timer0 Value using 10 us\n");
+		us_ConvertTiming = 10;
+	} else
+		us_ConvertTiming = (USHORT) (devpriv->ui_EocEosConversionTime / 1000);	// nano to useconds
+
+	// this_board->i_hwdrv_InsnReadAnalogInput(dev,us_ConvertTiming,insn->n,&insn->chanspec,data,insn->unused[0]);
+
+	// Clear software registers
+	devpriv->b_TimerSelectMode = 0;
+	devpriv->b_ModeSelectRegister = 0;
+	devpriv->us_OutputRegister = 0;
+//        devpriv->b_DigitalOutputRegister=0;
+
+	if (insn->unused[0] == 222)	// second insn read
+	{
+
+		for (i = 0; i < insn->n; i++) {
+			data[i] = devpriv->ui_AiReadData[i];
+		}
+
+	} else {
+		devpriv->tsk_Current = current;	// Save the current process task structure
+		//Testing if board have the new Quartz and calculate the time value
+		//to set in the timer
+
+		us_TmpValue =
+			(USHORT) inw(devpriv->iobase + APCI3120_RD_STATUS);
+
+		//EL250804: Testing if board APCI3120 have the new Quartz or if it is an APCI3001
+		if ((us_TmpValue & 0x00B0) == 0x00B0
+			|| !strcmp(this_board->pc_DriverName, "apci3001")) {
+			us_ConvertTiming = (us_ConvertTiming * 2) - 2;
+		} else {
+			us_ConvertTiming =
+				((us_ConvertTiming * 12926) / 10000) - 1;
+		}
+
+		us_TmpValue = (USHORT) devpriv->b_InterruptMode;
+
+		switch (us_TmpValue) {
+
+		case APCI3120_EOC_MODE:
+
+			// Testing the interrupt flag and set the EOC bit
+			// Clears the FIFO
+			inw(devpriv->iobase + APCI3120_RESET_FIFO);
+
+			// Initialize the sequence array
+
+			//if (!i_APCI3120_SetupChannelList(dev,s,1,chanlist,0))  return -EINVAL;
+
+			if (!i_APCI3120_SetupChannelList(dev, s, 1,
+					&insn->chanspec, 0))
+				return -EINVAL;
+
+			//Initialize Timer 0 mode 4
+			devpriv->b_TimerSelectMode =
+				(devpriv->
+				b_TimerSelectMode & 0xFC) |
+				APCI3120_TIMER_0_MODE_4;
+			outb(devpriv->b_TimerSelectMode,
+				devpriv->iobase + APCI3120_TIMER_CRT1);
+
+			// Reset the scan bit and Disables the  EOS, DMA, EOC interrupt
+			devpriv->b_ModeSelectRegister =
+				devpriv->
+				b_ModeSelectRegister & APCI3120_DISABLE_SCAN;
+
+			if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) {
+
+				//Disables the EOS,DMA and enables the EOC interrupt
+				devpriv->b_ModeSelectRegister =
+					(devpriv->
+					b_ModeSelectRegister &
+					APCI3120_DISABLE_EOS_INT) |
+					APCI3120_ENABLE_EOC_INT;
+				inw(devpriv->iobase);
+
+			} else {
+				devpriv->b_ModeSelectRegister =
+					devpriv->
+					b_ModeSelectRegister &
+					APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER;
+			}
+
+			outb(devpriv->b_ModeSelectRegister,
+				devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
+
+			// Sets gate 0
+			devpriv->us_OutputRegister =
+				(devpriv->
+				us_OutputRegister & APCI3120_CLEAR_PA_PR) |
+				APCI3120_ENABLE_TIMER0;
+			outw(devpriv->us_OutputRegister,
+				devpriv->iobase + APCI3120_WR_ADDRESS);
+
+			// Select Timer 0
+			b_Tmp = ((devpriv->
+					b_DigitalOutputRegister) & 0xF0) |
+				APCI3120_SELECT_TIMER_0_WORD;
+			outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+
+			//Set the convertion time
+			outw(us_ConvertTiming,
+				devpriv->iobase + APCI3120_TIMER_VALUE);
+
+			us_TmpValue =
+				(USHORT) inw(dev->iobase + APCI3120_RD_STATUS);
+
+			if (devpriv->b_EocEosInterrupt == APCI3120_DISABLE) {
+
+				do {
+					// Waiting for the end of conversion
+					us_TmpValue =
+						inw(devpriv->iobase +
+						APCI3120_RD_STATUS);
+				} while ((us_TmpValue & APCI3120_EOC) ==
+					APCI3120_EOC);
+
+				//Read the result in FIFO  and put it in insn data pointer
+				us_TmpValue = inw(devpriv->iobase + 0);
+				*data = us_TmpValue;
+
+				inw(devpriv->iobase + APCI3120_RESET_FIFO);
+			}
+
+			break;
+
+		case APCI3120_EOS_MODE:
+
+			inw(devpriv->iobase);
+			// Clears the FIFO
+			inw(devpriv->iobase + APCI3120_RESET_FIFO);
+			// clear PA PR  and disable timer 0
+
+			devpriv->us_OutputRegister =
+				(devpriv->
+				us_OutputRegister & APCI3120_CLEAR_PA_PR) |
+				APCI3120_DISABLE_TIMER0;
+
+			outw(devpriv->us_OutputRegister,
+				devpriv->iobase + APCI3120_WR_ADDRESS);
+
+			if (!i_APCI3120_SetupChannelList(dev, s,
+					devpriv->ui_AiNbrofChannels,
+					devpriv->ui_AiChannelList, 0))
+				return -EINVAL;
+
+			//Initialize Timer 0 mode 2
+			devpriv->b_TimerSelectMode =
+				(devpriv->
+				b_TimerSelectMode & 0xFC) |
+				APCI3120_TIMER_0_MODE_2;
+			outb(devpriv->b_TimerSelectMode,
+				devpriv->iobase + APCI3120_TIMER_CRT1);
+
+			//Select Timer 0
+			b_Tmp = ((devpriv->
+					b_DigitalOutputRegister) & 0xF0) |
+				APCI3120_SELECT_TIMER_0_WORD;
+			outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+
+			//Set the convertion time
+			outw(us_ConvertTiming,
+				devpriv->iobase + APCI3120_TIMER_VALUE);
+
+			//Set the scan bit
+			devpriv->b_ModeSelectRegister =
+				devpriv->
+				b_ModeSelectRegister | APCI3120_ENABLE_SCAN;
+			outb(devpriv->b_ModeSelectRegister,
+				devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
+
+			//If Interrupt function is loaded
+			if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) {
+				//Disables the EOC,DMA and enables the EOS interrupt
+				devpriv->b_ModeSelectRegister =
+					(devpriv->
+					b_ModeSelectRegister &
+					APCI3120_DISABLE_EOC_INT) |
+					APCI3120_ENABLE_EOS_INT;
+				inw(devpriv->iobase);
+
+			} else
+				devpriv->b_ModeSelectRegister =
+					devpriv->
+					b_ModeSelectRegister &
+					APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER;
+
+			outb(devpriv->b_ModeSelectRegister,
+				devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
+
+			inw(devpriv->iobase + APCI3120_RD_STATUS);
+
+			//Sets gate 0
+
+			devpriv->us_OutputRegister =
+				devpriv->
+				us_OutputRegister | APCI3120_ENABLE_TIMER0;
+			outw(devpriv->us_OutputRegister,
+				devpriv->iobase + APCI3120_WR_ADDRESS);
+
+			//Start conversion
+			outw(0, devpriv->iobase + APCI3120_START_CONVERSION);
+
+			//Waiting of end of convertion if interrupt is not installed
+			if (devpriv->b_EocEosInterrupt == APCI3120_DISABLE) {
+				//Waiting the end of convertion
+				do {
+					us_TmpValue =
+						inw(devpriv->iobase +
+						APCI3120_RD_STATUS);
+				}
+				while ((us_TmpValue & APCI3120_EOS) !=
+					APCI3120_EOS);
+
+				for (i = 0; i < devpriv->ui_AiNbrofChannels;
+					i++) {
+					//Read the result in FIFO and write them in shared memory
+					us_TmpValue = inw(devpriv->iobase);
+					data[i] = (UINT) us_TmpValue;
+				}
+
+				devpriv->b_InterruptMode = APCI3120_EOC_MODE;	// Restore defaults.
+			}
+			break;
+
+		default:
+			printk("inputs wrong\n");
+
+		}
+		devpriv->ui_EocEosConversionTime = 0;	// re initializing the variable;
+	}
+
+	return insn->n;
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name     :int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev,|
+| 											     struct comedi_subdevice *s)|
+|                                        									 |
++----------------------------------------------------------------------------+
+| Task              : Stops Cyclic acquisition  						     |
+|                     										                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev									 |
+|                     struct comedi_subdevice *s									 |
+|                                                 					         |
++----------------------------------------------------------------------------+
+| Return Value      :0              					                     |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_StopCyclicAcquisition(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	// Disable A2P Fifo write and AMWEN signal
+	outw(0, devpriv->i_IobaseAddon + 4);
+
+	//Disable Bus Master ADD ON
+	outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0);
+	outw(0, devpriv->i_IobaseAddon + 2);
+	outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0);
+	outw(0, devpriv->i_IobaseAddon + 2);
+
+	//Disable BUS Master PCI
+	outl(0, devpriv->i_IobaseAmcc + AMCC_OP_REG_MCSR);
+
+	//outl(inl(devpriv->i_IobaseAmcc+AMCC_OP_REG_INTCSR)&(~AINT_WRITE_COMPL), devpriv->i_IobaseAmcc+AMCC_OP_REG_INTCSR);    // stop amcc irqs
+	//outl(inl(devpriv->i_IobaseAmcc+AMCC_OP_REG_MCSR)&(~EN_A2P_TRANSFERS), devpriv->i_IobaseAmcc+AMCC_OP_REG_MCSR); // stop DMA
+
+	//Disable ext trigger
+	i_APCI3120_ExttrigDisable(dev);
+
+	devpriv->us_OutputRegister = 0;
+	//stop  counters
+	outw(devpriv->
+		us_OutputRegister & APCI3120_DISABLE_TIMER0 &
+		APCI3120_DISABLE_TIMER1, dev->iobase + APCI3120_WR_ADDRESS);
+
+	outw(APCI3120_DISABLE_ALL_TIMER, dev->iobase + APCI3120_WR_ADDRESS);
+
+	//DISABLE_ALL_INTERRUPT
+	outb(APCI3120_DISABLE_ALL_INTERRUPT,
+		dev->iobase + APCI3120_WRITE_MODE_SELECT);
+	//Flush FIFO
+	inb(dev->iobase + APCI3120_RESET_FIFO);
+	inw(dev->iobase + APCI3120_RD_STATUS);
+	devpriv->ui_AiActualScan = 0;
+	devpriv->ui_AiActualScanPosition = 0;
+	s->async->cur_chan = 0;
+	devpriv->ui_AiBufferPtr = 0;
+	devpriv->b_AiContinuous = 0;
+	devpriv->ui_DmaActualBuffer = 0;
+
+	devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
+	devpriv->b_InterruptMode = APCI3120_EOC_MODE;
+	devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
+	i_APCI3120_Reset(dev);
+	return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name     :int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev|
+|			,struct comedi_subdevice *s,struct comedi_cmd *cmd)					 |
+|                                        									 |
++----------------------------------------------------------------------------+
+| Task              : Test validity for a command for cyclic anlog input     |
+|                       acquisition  						     			 |
+|                     										                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev									 |
+|                     struct comedi_subdevice *s									 |
+|                     struct comedi_cmd *cmd              					         |
++----------------------------------------------------------------------------+
+| Return Value      :0              					                     |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_CommandTestAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp;		// divisor1,divisor2;
+
+	// step 1: make sure trigger sources are trivially valid
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW | TRIG_EXT;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_TIMER | TRIG_FOLLOW;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_TIMER;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	//step 2: make sure trigger sources are unique and mutually compatible
+
+	if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) {
+		err++;
+	}
+
+	if (cmd->scan_begin_src != TRIG_TIMER &&
+		cmd->scan_begin_src != TRIG_FOLLOW)
+		err++;
+
+	if (cmd->convert_src != TRIG_TIMER)
+		err++;
+
+	if (cmd->scan_end_src != TRIG_COUNT) {
+		cmd->scan_end_src = TRIG_COUNT;
+		err++;
+	}
+
+	if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
+		err++;
+
+	if (err)
+		return 2;
+
+	// step 3: make sure arguments are trivially compatible
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+
+	if (cmd->scan_begin_src == TRIG_TIMER)	// Test Delay timing
+	{
+		if (cmd->scan_begin_arg < this_board->ui_MinDelaytimeNs) {
+			cmd->scan_begin_arg = this_board->ui_MinDelaytimeNs;
+			err++;
+		}
+	}
+
+	if (cmd->convert_src == TRIG_TIMER)	// Test Acquisition timing
+	{
+		if (cmd->scan_begin_src == TRIG_TIMER) {
+			if ((cmd->convert_arg)
+				&& (cmd->convert_arg <
+					this_board->ui_MinAcquisitiontimeNs)) {
+				cmd->convert_arg =
+					this_board->ui_MinAcquisitiontimeNs;
+				err++;
+			}
+		} else {
+			if (cmd->convert_arg <
+				this_board->ui_MinAcquisitiontimeNs) {
+				cmd->convert_arg =
+					this_board->ui_MinAcquisitiontimeNs;
+				err++;
+
+			}
+		}
+	}
+
+	if (!cmd->chanlist_len) {
+		cmd->chanlist_len = 1;
+		err++;
+	}
+	if (cmd->chanlist_len > this_board->i_AiChannelList) {
+		cmd->chanlist_len = this_board->i_AiChannelList;
+		err++;
+	}
+	if (cmd->stop_src == TRIG_COUNT) {
+		if (!cmd->stop_arg) {
+			cmd->stop_arg = 1;
+			err++;
+		}
+	} else {		// TRIG_NONE
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (err)
+		return 3;
+
+	// step 4: fix up any arguments
+
+	if (cmd->convert_src == TRIG_TIMER) {
+
+		if (cmd->scan_begin_src == TRIG_TIMER &&
+			cmd->scan_begin_arg <
+			cmd->convert_arg * cmd->scan_end_arg) {
+			cmd->scan_begin_arg =
+				cmd->convert_arg * cmd->scan_end_arg;
+			err++;
+		}
+	}
+
+	if (err)
+		return 4;
+
+	return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name     : int i_APCI3120_CommandAnalogInput(struct comedi_device *dev,  |
+|												struct comedi_subdevice *s) |
+|                                        									 |
++----------------------------------------------------------------------------+
+| Task              : Does asynchronous acquisition                          |
+|                     Determines the mode 1 or 2.						     |
+|                     										                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev									 |
+|                     struct comedi_subdevice *s									 |
+|                     														 |
++----------------------------------------------------------------------------+
+| Return Value      :              					                         |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_CommandAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_cmd *cmd = &s->async->cmd;
+
+	//loading private structure with cmd structure inputs
+	devpriv->ui_AiFlags = cmd->flags;
+	devpriv->ui_AiNbrofChannels = cmd->chanlist_len;
+	devpriv->ui_AiScanLength = cmd->scan_end_arg;
+	devpriv->pui_AiChannelList = cmd->chanlist;
+
+	//UPDATE-0.7.57->0.7.68devpriv->AiData=s->async->data;
+	devpriv->AiData = s->async->prealloc_buf;
+	//UPDATE-0.7.57->0.7.68devpriv->ui_AiDataLength=s->async->data_len;
+	devpriv->ui_AiDataLength = s->async->prealloc_bufsz;
+
+	if (cmd->stop_src == TRIG_COUNT) {
+		devpriv->ui_AiNbrofScans = cmd->stop_arg;
+	} else {
+		devpriv->ui_AiNbrofScans = 0;
+	}
+
+	devpriv->ui_AiTimer0 = 0;	// variables changed to timer0,timer1
+	devpriv->ui_AiTimer1 = 0;
+	if ((devpriv->ui_AiNbrofScans == 0) || (devpriv->ui_AiNbrofScans == -1))
+		devpriv->b_AiContinuous = 1;	// user want neverending analog acquisition
+	// stopped using cancel
+
+	if (cmd->start_src == TRIG_EXT)
+		devpriv->b_ExttrigEnable = APCI3120_ENABLE;
+	else
+		devpriv->b_ExttrigEnable = APCI3120_DISABLE;
+
+	if (cmd->scan_begin_src == TRIG_FOLLOW) {
+		// mode 1 or 3
+		if (cmd->convert_src == TRIG_TIMER) {
+			// mode 1
+
+			devpriv->ui_AiTimer0 = cmd->convert_arg;	// timer constant in nano seconds
+			//return this_board->i_hwdrv_CommandAnalogInput(1,dev,s);
+			return i_APCI3120_CyclicAnalogInput(1, dev, s);
+		}
+
+	}
+	if ((cmd->scan_begin_src == TRIG_TIMER)
+		&& (cmd->convert_src == TRIG_TIMER)) {
+		// mode 2
+		devpriv->ui_AiTimer1 = cmd->scan_begin_arg;
+		devpriv->ui_AiTimer0 = cmd->convert_arg;	// variable changed timer2 to timer0
+		//return this_board->i_hwdrv_CommandAnalogInput(2,dev,s);
+		return i_APCI3120_CyclicAnalogInput(2, dev, s);
+	}
+	return -1;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name     :  int i_APCI3120_CyclicAnalogInput(int mode,            |
+|		 	   struct comedi_device * dev,struct comedi_subdevice * s)			 |
++----------------------------------------------------------------------------+
+| Task              : This is used for analog input cyclic acquisition       |
+|			  Performs the command operations.                       |
+|			  If DMA is configured does DMA initialization           |
+|			  otherwise does the acquisition with EOS interrupt.     |
+|                     										                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : 														 |
+|                     														 |
+|                                                 					         |
++----------------------------------------------------------------------------+
+| Return Value      :              					                         |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device * dev,
+	struct comedi_subdevice * s)
+{
+	BYTE b_Tmp;
+	UINT ui_Tmp, ui_DelayTiming = 0, ui_TimerValue1 = 0, dmalen0 =
+		0, dmalen1 = 0, ui_TimerValue2 =
+		0, ui_TimerValue0, ui_ConvertTiming;
+	USHORT us_TmpValue;
+
+	//BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+	//devpriv->b_AiCyclicAcquisition=APCI3120_ENABLE;
+	//END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+	/*******************/
+	/* Resets the FIFO */
+	/*******************/
+	inb(dev->iobase + APCI3120_RESET_FIFO);
+
+	//BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+	//inw(dev->iobase+APCI3120_RD_STATUS);
+	//END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+	/***************************/
+	/* Acquisition initialized */
+	/***************************/
+	//BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+	devpriv->b_AiCyclicAcquisition = APCI3120_ENABLE;
+	//END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+	// clear software  registers
+	devpriv->b_TimerSelectMode = 0;
+	devpriv->us_OutputRegister = 0;
+	devpriv->b_ModeSelectRegister = 0;
+	//devpriv->b_DigitalOutputRegister=0;
+
+	//COMMENT JK 07.05.04: Followings calls are in i_APCI3120_StartAnalogInputAcquisition
+
+   /****************************/
+	/* Clear Timer Write TC INT */
+   /****************************/
+	outl(APCI3120_CLEAR_WRITE_TC_INT,
+		devpriv->i_IobaseAmcc + APCI3120_AMCC_OP_REG_INTCSR);
+
+   /************************************/
+	/* Clears the timer status register */
+   /************************************/
+	//BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+	//inw(dev->iobase+APCI3120_TIMER_STATUS_REGISTER);
+	inb(dev->iobase + APCI3120_TIMER_STATUS_REGISTER);
+	//END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+   /**************************/
+	/* Disables All Timer     */
+	/* Sets PR and PA to 0    */
+   /**************************/
+	devpriv->us_OutputRegister = devpriv->us_OutputRegister &
+		APCI3120_DISABLE_TIMER0 &
+		APCI3120_DISABLE_TIMER1 & APCI3120_CLEAR_PA_PR;
+
+	outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS);
+
+   /*******************/
+	/* Resets the FIFO */
+   /*******************/
+	//BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+	inb(devpriv->iobase + APCI3120_RESET_FIFO);
+	//END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+	devpriv->ui_AiActualScan = 0;
+	devpriv->ui_AiActualScanPosition = 0;
+	s->async->cur_chan = 0;
+	devpriv->ui_AiBufferPtr = 0;
+	devpriv->ui_DmaActualBuffer = 0;
+
+	// value for timer2  minus -2 has to be done .....dunno y??
+	ui_TimerValue2 = devpriv->ui_AiNbrofScans - 2;
+	ui_ConvertTiming = devpriv->ui_AiTimer0;
+
+	if (mode == 2)
+		ui_DelayTiming = devpriv->ui_AiTimer1;
+
+   /**********************************/
+	/* Initializes the sequence array */
+   /**********************************/
+	if (!i_APCI3120_SetupChannelList(dev, s, devpriv->ui_AiNbrofChannels,
+			devpriv->pui_AiChannelList, 0))
+		return -EINVAL;
+
+	us_TmpValue = (USHORT) inw(dev->iobase + APCI3120_RD_STATUS);
+/*** EL241003 : add this section in comment because floats must not be used
+	 if((us_TmpValue & 0x00B0)==0x00B0)
+	 {
+           f_ConvertValue=(((float)ui_ConvertTiming * 0.002) - 2);
+		ui_TimerValue0=(UINT)f_ConvertValue;
+		if (mode==2)
+		{
+			f_DelayValue     = (((float)ui_DelayTiming * 0.00002) - 2);
+			ui_TimerValue1  =   (UINT) f_DelayValue;
+		}
+	 }
+   	 else
+	 {
+		f_ConvertValue=(((float)ui_ConvertTiming * 0.0012926) - 1);
+		ui_TimerValue0=(UINT)f_ConvertValue;
+		if (mode == 2)
+		{
+		     f_DelayValue     = (((float)ui_DelayTiming * 0.000012926) - 1);
+		     ui_TimerValue1  =   (UINT) f_DelayValue;
+		}
+	}
+***********************************************************************************************/
+/*** EL241003 Begin : add this section to replace floats calculation by integer calculations **/
+	//EL250804: Testing if board APCI3120 have the new Quartz or if it is an APCI3001
+	if ((us_TmpValue & 0x00B0) == 0x00B0
+		|| !strcmp(this_board->pc_DriverName, "apci3001")) {
+		ui_TimerValue0 = ui_ConvertTiming * 2 - 2000;
+		ui_TimerValue0 = ui_TimerValue0 / 1000;
+
+		if (mode == 2) {
+			ui_DelayTiming = ui_DelayTiming / 1000;
+			ui_TimerValue1 = ui_DelayTiming * 2 - 200;
+			ui_TimerValue1 = ui_TimerValue1 / 100;
+		}
+	} else {
+		ui_ConvertTiming = ui_ConvertTiming / 1000;
+		ui_TimerValue0 = ui_ConvertTiming * 12926 - 10000;
+		ui_TimerValue0 = ui_TimerValue0 / 10000;
+
+		if (mode == 2) {
+			ui_DelayTiming = ui_DelayTiming / 1000;
+			ui_TimerValue1 = ui_DelayTiming * 12926 - 1;
+			ui_TimerValue1 = ui_TimerValue1 / 1000000;
+		}
+	}
+/*** EL241003 End ******************************************************************************/
+
+	if (devpriv->b_ExttrigEnable == APCI3120_ENABLE) {
+		i_APCI3120_ExttrigEnable(dev);	// activate EXT trigger
+	}
+	switch (mode) {
+	case 1:
+		// init timer0 in mode 2
+		devpriv->b_TimerSelectMode =
+			(devpriv->
+			b_TimerSelectMode & 0xFC) | APCI3120_TIMER_0_MODE_2;
+		outb(devpriv->b_TimerSelectMode,
+			dev->iobase + APCI3120_TIMER_CRT1);
+
+		//Select Timer 0
+		b_Tmp = ((devpriv->
+				b_DigitalOutputRegister) & 0xF0) |
+			APCI3120_SELECT_TIMER_0_WORD;
+		outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0);
+		//Set the convertion time
+		outw(((USHORT) ui_TimerValue0),
+			dev->iobase + APCI3120_TIMER_VALUE);
+		break;
+
+	case 2:
+		// init timer1 in mode 2
+		devpriv->b_TimerSelectMode =
+			(devpriv->
+			b_TimerSelectMode & 0xF3) | APCI3120_TIMER_1_MODE_2;
+		outb(devpriv->b_TimerSelectMode,
+			dev->iobase + APCI3120_TIMER_CRT1);
+
+		//Select Timer 1
+		b_Tmp = ((devpriv->
+				b_DigitalOutputRegister) & 0xF0) |
+			APCI3120_SELECT_TIMER_1_WORD;
+		outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0);
+		//Set the convertion time
+		outw(((USHORT) ui_TimerValue1),
+			dev->iobase + APCI3120_TIMER_VALUE);
+
+		// init timer0 in mode 2
+		devpriv->b_TimerSelectMode =
+			(devpriv->
+			b_TimerSelectMode & 0xFC) | APCI3120_TIMER_0_MODE_2;
+		outb(devpriv->b_TimerSelectMode,
+			dev->iobase + APCI3120_TIMER_CRT1);
+
+		//Select Timer 0
+		b_Tmp = ((devpriv->
+				b_DigitalOutputRegister) & 0xF0) |
+			APCI3120_SELECT_TIMER_0_WORD;
+		outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0);
+
+		//Set the convertion time
+		outw(((USHORT) ui_TimerValue0),
+			dev->iobase + APCI3120_TIMER_VALUE);
+		break;
+
+	}
+	//   ##########common for all modes#################
+
+	/***********************/
+	/* Clears the SCAN bit */
+	/***********************/
+	//BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+	//devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister | APCI3120_DISABLE_SCAN;
+	devpriv->b_ModeSelectRegister = devpriv->b_ModeSelectRegister &
+		APCI3120_DISABLE_SCAN;
+	//END JK 07.05.04: Comparison between WIN32 and Linux driver
+	outb(devpriv->b_ModeSelectRegister,
+		dev->iobase + APCI3120_WRITE_MODE_SELECT);
+
+	// If DMA is disabled
+	if (devpriv->us_UseDma == APCI3120_DISABLE) {
+		// disable EOC and enable EOS
+		devpriv->b_InterruptMode = APCI3120_EOS_MODE;
+		devpriv->b_EocEosInterrupt = APCI3120_ENABLE;
+
+		devpriv->b_ModeSelectRegister =
+			(devpriv->
+			b_ModeSelectRegister & APCI3120_DISABLE_EOC_INT) |
+			APCI3120_ENABLE_EOS_INT;
+		outb(devpriv->b_ModeSelectRegister,
+			dev->iobase + APCI3120_WRITE_MODE_SELECT);
+
+		if (!devpriv->b_AiContinuous) {
+			// configure Timer2 For counting  EOS
+			//Reset gate 2 of Timer 2 to disable it (Set Bit D14 to 0)
+			devpriv->us_OutputRegister =
+				devpriv->
+				us_OutputRegister & APCI3120_DISABLE_TIMER2;
+			outw(devpriv->us_OutputRegister,
+				dev->iobase + APCI3120_WR_ADDRESS);
+
+			// DISABLE TIMER INTERRUPT
+			devpriv->b_ModeSelectRegister =
+				devpriv->
+				b_ModeSelectRegister &
+				APCI3120_DISABLE_TIMER_INT & 0xEF;
+			outb(devpriv->b_ModeSelectRegister,
+				dev->iobase + APCI3120_WRITE_MODE_SELECT);
+
+			//(1) Init timer 2 in mode 0 and write timer value
+			devpriv->b_TimerSelectMode =
+				(devpriv->
+				b_TimerSelectMode & 0x0F) |
+				APCI3120_TIMER_2_MODE_0;
+			outb(devpriv->b_TimerSelectMode,
+				dev->iobase + APCI3120_TIMER_CRT1);
+
+			//Writing LOW WORD
+			b_Tmp = ((devpriv->
+					b_DigitalOutputRegister) & 0xF0) |
+				APCI3120_SELECT_TIMER_2_LOW_WORD;
+			outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0);
+			outw(LOWORD(ui_TimerValue2),
+				dev->iobase + APCI3120_TIMER_VALUE);
+
+			//Writing HIGH WORD
+			b_Tmp = ((devpriv->
+					b_DigitalOutputRegister) & 0xF0) |
+				APCI3120_SELECT_TIMER_2_HIGH_WORD;
+			outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0);
+			outw(HIWORD(ui_TimerValue2),
+				dev->iobase + APCI3120_TIMER_VALUE);
+
+			//(2) Reset FC_TIMER BIT  Clearing timer status register
+			inb(dev->iobase + APCI3120_TIMER_STATUS_REGISTER);
+			// enable timer counter and disable watch dog
+			devpriv->b_ModeSelectRegister =
+				(devpriv->
+				b_ModeSelectRegister |
+				APCI3120_ENABLE_TIMER_COUNTER) &
+				APCI3120_DISABLE_WATCHDOG;
+			// select EOS clock input for timer 2
+			devpriv->b_ModeSelectRegister =
+				devpriv->
+				b_ModeSelectRegister |
+				APCI3120_TIMER2_SELECT_EOS;
+			// Enable timer2  interrupt
+			devpriv->b_ModeSelectRegister =
+				devpriv->
+				b_ModeSelectRegister |
+				APCI3120_ENABLE_TIMER_INT;
+			outb(devpriv->b_ModeSelectRegister,
+				dev->iobase + APCI3120_WRITE_MODE_SELECT);
+			devpriv->b_Timer2Mode = APCI3120_COUNTER;
+			devpriv->b_Timer2Interrupt = APCI3120_ENABLE;
+		}
+	} else {
+		// If DMA Enabled
+		//BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+		//inw(dev->iobase+0);// reset EOC bit
+		//END JK 07.05.04: Comparison between WIN32 and Linux driver
+		devpriv->b_InterruptMode = APCI3120_DMA_MODE;
+
+      /************************************/
+		/* Disables the EOC, EOS interrupt  */
+	  /************************************/
+		devpriv->b_ModeSelectRegister = devpriv->b_ModeSelectRegister &
+			APCI3120_DISABLE_EOC_INT & APCI3120_DISABLE_EOS_INT;
+
+		outb(devpriv->b_ModeSelectRegister,
+			dev->iobase + APCI3120_WRITE_MODE_SELECT);
+
+		dmalen0 = devpriv->ui_DmaBufferSize[0];
+		dmalen1 = devpriv->ui_DmaBufferSize[1];
+
+		if (!devpriv->b_AiContinuous) {
+
+			if (dmalen0 > (devpriv->ui_AiNbrofScans * devpriv->ui_AiScanLength * 2)) {	// must we fill full first buffer?
+				dmalen0 =
+					devpriv->ui_AiNbrofScans *
+					devpriv->ui_AiScanLength * 2;
+			} else if (dmalen1 > (devpriv->ui_AiNbrofScans * devpriv->ui_AiScanLength * 2 - dmalen0))	// and must we fill full second buffer when first is once filled?
+				dmalen1 =
+					devpriv->ui_AiNbrofScans *
+					devpriv->ui_AiScanLength * 2 - dmalen0;
+		}
+
+		if (devpriv->ui_AiFlags & TRIG_WAKE_EOS) {
+			// don't we want wake up every scan?
+			if (dmalen0 > (devpriv->ui_AiScanLength * 2)) {
+				dmalen0 = devpriv->ui_AiScanLength * 2;
+				if (devpriv->ui_AiScanLength & 1)
+					dmalen0 += 2;
+			}
+			if (dmalen1 > (devpriv->ui_AiScanLength * 2)) {
+				dmalen1 = devpriv->ui_AiScanLength * 2;
+				if (devpriv->ui_AiScanLength & 1)
+					dmalen1 -= 2;
+				if (dmalen1 < 4)
+					dmalen1 = 4;
+			}
+		} else {	// isn't output buff smaller that our DMA buff?
+			if (dmalen0 > (devpriv->ui_AiDataLength)) {
+				dmalen0 = devpriv->ui_AiDataLength;
+			}
+			if (dmalen1 > (devpriv->ui_AiDataLength)) {
+				dmalen1 = devpriv->ui_AiDataLength;
+			}
+		}
+		devpriv->ui_DmaBufferUsesize[0] = dmalen0;
+		devpriv->ui_DmaBufferUsesize[1] = dmalen1;
+
+		//Initialize DMA
+
+		// Set Transfer count enable bit and A2P_fifo reset bit in AGCSTS register
+		//1
+		ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO;
+		outl(ui_Tmp, devpriv->i_IobaseAmcc + AMCC_OP_REG_AGCSTS);
+
+		// changed  since 16 bit interface for add on
+		/*********************/
+		/* ENABLE BUS MASTER */
+		/*********************/
+		outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0);
+		outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW,
+			devpriv->i_IobaseAddon + 2);
+
+		outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0);
+		outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH,
+			devpriv->i_IobaseAddon + 2);
+
+		// TO VERIFIED
+		//BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+		outw(0x1000, devpriv->i_IobaseAddon + 2);
+		//END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+		//2  No change
+		// A2P FIFO MANAGEMENT
+		// A2P fifo reset  & transfer control enable
+		 /***********************/
+		/* A2P FIFO MANAGEMENT */
+		 /***********************/
+		outl(APCI3120_A2P_FIFO_MANAGEMENT, devpriv->i_IobaseAmcc +
+			APCI3120_AMCC_OP_MCSR);
+
+		//3
+		//beginning address of dma buf
+		//The 32 bit address of dma buffer is converted into two 16 bit addresses
+		// Can done by using _attach and put into into an array
+		// array used may be for differnet pages
+
+		// DMA Start Adress Low
+		outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0);
+		outw((devpriv->ul_DmaBufferHw[0] & 0xFFFF),
+			devpriv->i_IobaseAddon + 2);
+
+		 /*************************/
+		/* DMA Start Adress High */
+		 /*************************/
+		outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0);
+		outw((devpriv->ul_DmaBufferHw[0] / 65536),
+			devpriv->i_IobaseAddon + 2);
+
+		//4
+		// amount of bytes to be transfered  set transfer count
+		// used ADDON MWTC register
+		//commented testing             outl(devpriv->ui_DmaBufferUsesize[0], devpriv->i_IobaseAddon+AMCC_OP_REG_AMWTC);
+
+		 /**************************/
+		/* Nbr of acquisition LOW */
+		 /**************************/
+		outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0);
+		outw((devpriv->ui_DmaBufferUsesize[0] & 0xFFFF),
+			devpriv->i_IobaseAddon + 2);
+
+		 /***************************/
+		/* Nbr of acquisition HIGH */
+		 /***************************/
+		outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0);
+		outw((devpriv->ui_DmaBufferUsesize[0] / 65536),
+			devpriv->i_IobaseAddon + 2);
+
+		//5
+		// To configure A2P FIFO
+		// testing outl( FIFO_ADVANCE_ON_BYTE_2,devpriv->i_IobaseAmcc+AMCC_OP_REG_INTCSR);
+
+		/******************/
+		/* A2P FIFO RESET */
+		/******************/
+		// TO VERIFY
+		//BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+		outl(0x04000000UL, devpriv->i_IobaseAmcc + AMCC_OP_REG_MCSR);
+		//END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+		//6
+		//ENABLE A2P FIFO WRITE AND ENABLE AMWEN
+		// AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03
+		//BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+		//outw(3,devpriv->i_IobaseAddon + 4);
+		//END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+		//7
+		//initialise end of dma interrupt  AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI)
+		/***************************************************/
+		/* A2P FIFO CONFIGURATE, END OF DMA INTERRUPT INIT */
+		/***************************************************/
+		outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 |
+				APCI3120_ENABLE_WRITE_TC_INT),
+			devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR);
+
+		//BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+		/******************************************/
+		/* ENABLE A2P FIFO WRITE AND ENABLE AMWEN */
+		/******************************************/
+		outw(3, devpriv->i_IobaseAddon + 4);
+		//END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+		/******************/
+		/* A2P FIFO RESET */
+		/******************/
+		//BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+		outl(0x04000000UL,
+			devpriv->i_IobaseAmcc + APCI3120_AMCC_OP_MCSR);
+		//END JK 07.05.04: Comparison between WIN32 and Linux driver
+	}
+
+	if ((devpriv->us_UseDma == APCI3120_DISABLE)
+		&& !devpriv->b_AiContinuous) {
+		// set gate 2   to start conversion
+		devpriv->us_OutputRegister =
+			devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER2;
+		outw(devpriv->us_OutputRegister,
+			dev->iobase + APCI3120_WR_ADDRESS);
+	}
+
+	switch (mode) {
+	case 1:
+		// set gate 0   to start conversion
+		devpriv->us_OutputRegister =
+			devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER0;
+		outw(devpriv->us_OutputRegister,
+			dev->iobase + APCI3120_WR_ADDRESS);
+		break;
+	case 2:
+		// set  gate 0 and gate 1
+		devpriv->us_OutputRegister =
+			devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER1;
+		devpriv->us_OutputRegister =
+			devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER0;
+		outw(devpriv->us_OutputRegister,
+			dev->iobase + APCI3120_WR_ADDRESS);
+		break;
+
+	}
+
+	return 0;
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| 			INTERNAL FUNCTIONS						                 |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function name     : int i_APCI3120_Reset(struct comedi_device *dev)               |
+|                                        									 |
+|                                            						         |
++----------------------------------------------------------------------------+
+| Task              : Hardware reset function   						     |
+|                     										                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : 	struct comedi_device *dev									 |
+|                     														 |
+|                                                 					         |
++----------------------------------------------------------------------------+
+| Return Value      :              					                         |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_Reset(struct comedi_device * dev)
+{
+	unsigned int i;
+	unsigned short us_TmpValue;
+
+	devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
+	devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
+	devpriv->b_InterruptMode = APCI3120_EOC_MODE;
+	devpriv->ui_EocEosConversionTime = 0;	// set eoc eos conv time to 0
+	devpriv->b_OutputMemoryStatus = 0;
+
+	// variables used in timer subdevice
+	devpriv->b_Timer2Mode = 0;
+	devpriv->b_Timer2Interrupt = 0;
+	devpriv->b_ExttrigEnable = 0;	// Disable ext trigger
+
+	/* Disable all interrupts, watchdog for the anolog output */
+	devpriv->b_ModeSelectRegister = 0;
+	outb(devpriv->b_ModeSelectRegister,
+		dev->iobase + APCI3120_WRITE_MODE_SELECT);
+
+	// Disables all counters, ext trigger and clears PA, PR
+	devpriv->us_OutputRegister = 0;
+	outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS);
+
+	//Code to set the all anolog o/p channel to 0v
+	//8191 is decimal value for zero(0 v)volt in bipolar mode(default)
+	outw(8191 | APCI3120_ANALOG_OP_CHANNEL_1, dev->iobase + APCI3120_ANALOG_OUTPUT_1);	//channel 1
+	outw(8191 | APCI3120_ANALOG_OP_CHANNEL_2, dev->iobase + APCI3120_ANALOG_OUTPUT_1);	//channel 2
+	outw(8191 | APCI3120_ANALOG_OP_CHANNEL_3, dev->iobase + APCI3120_ANALOG_OUTPUT_1);	//channel 3
+	outw(8191 | APCI3120_ANALOG_OP_CHANNEL_4, dev->iobase + APCI3120_ANALOG_OUTPUT_1);	//channel 4
+
+	outw(8191 | APCI3120_ANALOG_OP_CHANNEL_5, dev->iobase + APCI3120_ANALOG_OUTPUT_2);	//channel 5
+	outw(8191 | APCI3120_ANALOG_OP_CHANNEL_6, dev->iobase + APCI3120_ANALOG_OUTPUT_2);	//channel 6
+	outw(8191 | APCI3120_ANALOG_OP_CHANNEL_7, dev->iobase + APCI3120_ANALOG_OUTPUT_2);	//channel 7
+	outw(8191 | APCI3120_ANALOG_OP_CHANNEL_8, dev->iobase + APCI3120_ANALOG_OUTPUT_2);	//channel 8
+
+	//  Reset digital output to L0W
+
+//ES05  outb(0x0,dev->iobase+APCI3120_DIGITAL_OUTPUT);
+	udelay(10);
+
+	inw(dev->iobase + 0);	//make a dummy read
+	inb(dev->iobase + APCI3120_RESET_FIFO);	// flush FIFO
+	inw(dev->iobase + APCI3120_RD_STATUS);	// flush A/D status register
+
+	//code to reset the RAM sequence
+	for (i = 0; i < 16; i++) {
+		us_TmpValue = i << 8;	//select the location
+		outw(us_TmpValue, dev->iobase + APCI3120_SEQ_RAM_ADDRESS);
+	}
+	return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name     : int i_APCI3120_SetupChannelList(struct comedi_device * dev,   |
+|                     struct comedi_subdevice * s, int n_chan,unsigned int *chanlist|
+|			  ,char check)											 |
+|                                            						         |
++----------------------------------------------------------------------------+
+| Task              :This function will first check channel list is ok or not|
+|and then initialize the sequence RAM with the polarity, Gain,Channel number |
+|If the last argument of function "check"is 1 then it only checks the channel|
+|list is ok or not.												     		 |
+|                     										                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device * dev									 |
+|                     struct comedi_subdevice * s									 |
+|                     int n_chan                   					         |
+			  unsigned int *chanlist
+			  char check
++----------------------------------------------------------------------------+
+| Return Value      :              					                         |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_SetupChannelList(struct comedi_device * dev, struct comedi_subdevice * s,
+	int n_chan, unsigned int *chanlist, char check)
+{
+	unsigned int i;		//, differencial=0, bipolar=0;
+	unsigned int gain;
+	unsigned short us_TmpValue;
+
+	/* correct channel and range number check itself comedi/range.c */
+	if (n_chan < 1) {
+		if (!check)
+			comedi_error(dev, "range/channel list is empty!");
+		return 0;
+	}
+	// All is ok, so we can setup channel/range list
+	if (check)
+		return 1;
+
+	//Code  to set the PA and PR...Here it set PA to 0..
+	devpriv->us_OutputRegister =
+		devpriv->us_OutputRegister & APCI3120_CLEAR_PA_PR;
+	devpriv->us_OutputRegister = ((n_chan - 1) & 0xf) << 8;
+	outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS);
+
+	for (i = 0; i < n_chan; i++) {
+		// store range list to card
+		us_TmpValue = CR_CHAN(chanlist[i]);	// get channel number;
+
+		if (CR_RANGE(chanlist[i]) < APCI3120_BIPOLAR_RANGES) {
+			us_TmpValue &= ((~APCI3120_UNIPOLAR) & 0xff);	// set bipolar
+		} else {
+			us_TmpValue |= APCI3120_UNIPOLAR;	// enable unipolar......
+		}
+
+		gain = CR_RANGE(chanlist[i]);	// get gain number
+		us_TmpValue |= ((gain & 0x03) << 4);	//<<4 for G0 and G1 bit in RAM
+		us_TmpValue |= i << 8;	//To select the RAM LOCATION....
+		outw(us_TmpValue, dev->iobase + APCI3120_SEQ_RAM_ADDRESS);
+
+		printk("\n Gain = %i",
+			(((unsigned char)CR_RANGE(chanlist[i]) & 0x03) << 2));
+		printk("\n Channel = %i", CR_CHAN(chanlist[i]));
+		printk("\n Polarity = %i", us_TmpValue & APCI3120_UNIPOLAR);
+	}
+	return 1;		// we can serve this with scan logic
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name     :	int i_APCI3120_ExttrigEnable(struct comedi_device * dev)    |
+|                                        									 |
+|                                            						         |
++----------------------------------------------------------------------------+
+| Task              : 	Enable the external trigger						     |
+|                     										                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : 	struct comedi_device * dev									 |
+|                     														 |
+|                                                 					         |
++----------------------------------------------------------------------------+
+| Return Value      :      0        					                         |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_ExttrigEnable(struct comedi_device * dev)
+{
+
+	devpriv->us_OutputRegister |= APCI3120_ENABLE_EXT_TRIGGER;
+	outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS);
+	return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name     : 	int i_APCI3120_ExttrigDisable(struct comedi_device * dev)   |
+|                                        									 |
++----------------------------------------------------------------------------+
+| Task              : 	Disables the external trigger					     |
+|                     										                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : 	struct comedi_device * dev									 |
+|                     														 |
+|                                                 					         |
++----------------------------------------------------------------------------+
+| Return Value      :    0          					                         |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_ExttrigDisable(struct comedi_device * dev)
+{
+	devpriv->us_OutputRegister &= ~APCI3120_ENABLE_EXT_TRIGGER;
+	outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS);
+	return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+|                    INTERRUPT FUNCTIONS		    		                 |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function name     : void v_APCI3120_Interrupt(int irq, void *d) 								 |
+|                                        									 |
+|                                            						         |
++----------------------------------------------------------------------------+
+| Task              :Interrupt handler for APCI3120                        	 |
+|			 When interrupt occurs this gets called.                 |
+|			 First it finds which interrupt has been generated and   |
+|			 handles  corresponding interrupt                        |
+|                     										                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : 	int irq 											 |
+|                        void *d											 |
+|                                                 					         |
++----------------------------------------------------------------------------+
+| Return Value      : void         					                         |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+
+void v_APCI3120_Interrupt(int irq, void *d)
+{
+	struct comedi_device *dev = d;
+	USHORT int_daq;
+
+	unsigned int int_amcc, ui_Check, i;
+	USHORT us_TmpValue;
+	BYTE b_DummyRead;
+
+	struct comedi_subdevice *s = dev->subdevices + 0;
+	ui_Check = 1;
+
+	int_daq = inw(dev->iobase + APCI3120_RD_STATUS) & 0xf000;	// get IRQ reasons
+	int_amcc = inl(devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR);	// get AMCC INT register
+
+	if ((!int_daq) && (!(int_amcc & ANY_S593X_INT))) {
+		comedi_error(dev, "IRQ from unknow source");
+		return;
+	}
+
+	outl(int_amcc | 0x00ff0000, devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR);	// shutdown IRQ reasons in AMCC
+
+	int_daq = (int_daq >> 12) & 0xF;
+
+	if (devpriv->b_ExttrigEnable == APCI3120_ENABLE) {
+		//Disable ext trigger
+		i_APCI3120_ExttrigDisable(dev);
+		devpriv->b_ExttrigEnable = APCI3120_DISABLE;
+	}
+	//clear the timer 2 interrupt
+	inb(devpriv->i_IobaseAmcc + APCI3120_TIMER_STATUS_REGISTER);
+
+	if (int_amcc & MASTER_ABORT_INT)
+		comedi_error(dev, "AMCC IRQ - MASTER DMA ABORT!");
+	if (int_amcc & TARGET_ABORT_INT)
+		comedi_error(dev, "AMCC IRQ - TARGET DMA ABORT!");
+
+	// Ckeck if EOC interrupt
+	if (((int_daq & 0x8) == 0)
+		&& (devpriv->b_InterruptMode == APCI3120_EOC_MODE)) {
+		if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) {
+
+			// Read the AI Value
+
+			devpriv->ui_AiReadData[0] =
+				(UINT) inw(devpriv->iobase + 0);
+			devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
+			send_sig(SIGIO, devpriv->tsk_Current, 0);	// send signal to the sample
+		} else {
+			//Disable EOC Interrupt
+			devpriv->b_ModeSelectRegister =
+				devpriv->
+				b_ModeSelectRegister & APCI3120_DISABLE_EOC_INT;
+			outb(devpriv->b_ModeSelectRegister,
+				devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
+
+		}
+	}
+
+	// Check If EOS interrupt
+	if ((int_daq & 0x2) && (devpriv->b_InterruptMode == APCI3120_EOS_MODE)) {
+
+		if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE)	// enable this in without DMA ???
+		{
+
+			if (devpriv->b_AiCyclicAcquisition == APCI3120_ENABLE) {
+				ui_Check = 0;
+				i_APCI3120_InterruptHandleEos(dev);
+				devpriv->ui_AiActualScan++;
+				devpriv->b_ModeSelectRegister =
+					devpriv->
+					b_ModeSelectRegister |
+					APCI3120_ENABLE_EOS_INT;
+				outb(devpriv->b_ModeSelectRegister,
+					dev->iobase +
+					APCI3120_WRITE_MODE_SELECT);
+			} else {
+				ui_Check = 0;
+				for (i = 0; i < devpriv->ui_AiNbrofChannels;
+					i++) {
+					us_TmpValue = inw(devpriv->iobase + 0);
+					devpriv->ui_AiReadData[i] =
+						(UINT) us_TmpValue;
+				}
+				devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
+				devpriv->b_InterruptMode = APCI3120_EOC_MODE;
+
+				send_sig(SIGIO, devpriv->tsk_Current, 0);	// send signal to the sample
+
+			}
+
+		} else {
+			devpriv->b_ModeSelectRegister =
+				devpriv->
+				b_ModeSelectRegister & APCI3120_DISABLE_EOS_INT;
+			outb(devpriv->b_ModeSelectRegister,
+				dev->iobase + APCI3120_WRITE_MODE_SELECT);
+			devpriv->b_EocEosInterrupt = APCI3120_DISABLE;	//Default settings
+			devpriv->b_InterruptMode = APCI3120_EOC_MODE;
+		}
+
+	}
+	//Timer2 interrupt
+	if (int_daq & 0x1) {
+
+		switch (devpriv->b_Timer2Mode) {
+		case APCI3120_COUNTER:
+
+			devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
+			devpriv->b_ModeSelectRegister =
+				devpriv->
+				b_ModeSelectRegister & APCI3120_DISABLE_EOS_INT;
+			outb(devpriv->b_ModeSelectRegister,
+				dev->iobase + APCI3120_WRITE_MODE_SELECT);
+
+			// stop timer 2
+			devpriv->us_OutputRegister =
+				devpriv->
+				us_OutputRegister & APCI3120_DISABLE_ALL_TIMER;
+			outw(devpriv->us_OutputRegister,
+				dev->iobase + APCI3120_WR_ADDRESS);
+
+			//stop timer 0 and timer 1
+			i_APCI3120_StopCyclicAcquisition(dev, s);
+			devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
+
+			//UPDATE-0.7.57->0.7.68comedi_done(dev,s);
+			s->async->events |= COMEDI_CB_EOA;
+			comedi_event(dev, s);
+
+			break;
+
+		case APCI3120_TIMER:
+
+			//Send a signal to from kernel to user space
+			send_sig(SIGIO, devpriv->tsk_Current, 0);
+			break;
+
+		case APCI3120_WATCHDOG:
+
+			//Send a signal to from kernel to user space
+			send_sig(SIGIO, devpriv->tsk_Current, 0);
+			break;
+
+		default:
+
+			// disable Timer Interrupt
+
+			devpriv->b_ModeSelectRegister =
+				devpriv->
+				b_ModeSelectRegister &
+				APCI3120_DISABLE_TIMER_INT;
+
+			outb(devpriv->b_ModeSelectRegister,
+				dev->iobase + APCI3120_WRITE_MODE_SELECT);
+
+		}
+
+		b_DummyRead = inb(dev->iobase + APCI3120_TIMER_STATUS_REGISTER);
+
+	}
+
+	if ((int_daq & 0x4) && (devpriv->b_InterruptMode == APCI3120_DMA_MODE)) {
+		if (devpriv->b_AiCyclicAcquisition == APCI3120_ENABLE) {
+
+			/****************************/
+			/* Clear Timer Write TC INT */
+			/****************************/
+
+			outl(APCI3120_CLEAR_WRITE_TC_INT,
+				devpriv->i_IobaseAmcc +
+				APCI3120_AMCC_OP_REG_INTCSR);
+
+			/************************************/
+			/* Clears the timer status register */
+			/************************************/
+			inw(dev->iobase + APCI3120_TIMER_STATUS_REGISTER);
+			v_APCI3120_InterruptDma(irq, d);	// do some data transfer
+		} else {
+			/* Stops the Timer */
+			outw(devpriv->
+				us_OutputRegister & APCI3120_DISABLE_TIMER0 &
+				APCI3120_DISABLE_TIMER1,
+				dev->iobase + APCI3120_WR_ADDRESS);
+		}
+
+	}
+
+	return;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name     :int i_APCI3120_InterruptHandleEos(struct comedi_device *dev)   |
+|                                        									 |
+|                                            						         |
++----------------------------------------------------------------------------+
+| Task              : This function handles EOS interrupt.                   |
+|                     This function copies the acquired data(from FIFO)      |
+|				to Comedi buffer.		 							 |
+|                     										                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev									 |
+|                     														 |
+|                                                 					         |
++----------------------------------------------------------------------------+
+| Return Value      : 0            					                         |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+
+/*
+ * int i_APCI3120_InterruptHandleEos(struct comedi_device *dev)
+{
+       int n_chan,i;
+       short *data;
+       struct comedi_subdevice *s=dev->subdevices+0;
+       struct comedi_async *async = s->async;
+       data=async->data+async->buf_int_ptr;
+        n_chan=devpriv->ui_AiNbrofChannels;
+
+       for(i=0;i<n_chan;i++)
+         {
+           data[i]=inw(dev->iobase+0);
+         }
+       async->buf_int_count+=n_chan*sizeof(short);
+       async->buf_int_ptr+=n_chan*sizeof(short);
+       comedi_eos(dev,s);
+       if (s->async->buf_int_ptr>=s->async->data_len) //  for buffer rool over
+		         {
+*//* buffer rollover */
+/*	        s->async->buf_int_ptr=0;
+		comedi_eobuf(dev,s);
+         }
+ 	return 0;
+}*/
+int i_APCI3120_InterruptHandleEos(struct comedi_device * dev)
+{
+	int n_chan, i;
+	struct comedi_subdevice *s = dev->subdevices + 0;
+	int err = 1;
+
+	n_chan = devpriv->ui_AiNbrofChannels;
+
+	s->async->events = 0;
+
+	for (i = 0; i < n_chan; i++)
+		err &= comedi_buf_put(s->async, inw(dev->iobase + 0));
+
+	s->async->events |= COMEDI_CB_EOS;
+
+	if (err == 0)
+		s->async->events |= COMEDI_CB_OVERFLOW;
+
+	comedi_event(dev, s);
+
+	return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name     : void v_APCI3120_InterruptDma(int irq, void *d) 									 |
+|                                        									 |
++----------------------------------------------------------------------------+
+| Task              : This is a handler for the DMA interrupt                |
+|			  This function copies the data to Comedi Buffer.        |
+|			  For continuous DMA it reinitializes the DMA operation. |
+|			  For single mode DMA it stop the acquisition.           |
+|													     			 |
++----------------------------------------------------------------------------+
+| Input Parameters  : int irq, void *d				 |
+|                     														 |
++----------------------------------------------------------------------------+
+| Return Value      :  void        					                         |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+
+void v_APCI3120_InterruptDma(int irq, void *d)
+{
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s = dev->subdevices + 0;
+	unsigned int next_dma_buf, samplesinbuf;
+	unsigned long low_word, high_word, var;
+
+	UINT ui_Tmp;
+	samplesinbuf =
+		devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer] -
+		inl(devpriv->i_IobaseAmcc + AMCC_OP_REG_MWTC);
+
+	if (samplesinbuf <
+		devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer]) {
+		comedi_error(dev, "Interrupted DMA transfer!");
+	}
+	if (samplesinbuf & 1) {
+		comedi_error(dev, "Odd count of bytes in DMA ring!");
+		i_APCI3120_StopCyclicAcquisition(dev, s);
+		devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
+
+		return;
+	}
+	samplesinbuf = samplesinbuf >> 1;	// number of received samples
+	if (devpriv->b_DmaDoubleBuffer) {
+		// switch DMA buffers if is used double buffering
+		next_dma_buf = 1 - devpriv->ui_DmaActualBuffer;
+
+		ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO;
+		outl(ui_Tmp, devpriv->i_IobaseAddon + AMCC_OP_REG_AGCSTS);
+
+		// changed  since 16 bit interface for add on
+		outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0);
+		outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW,
+			devpriv->i_IobaseAddon + 2);
+		outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0);
+		outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->i_IobaseAddon + 2);	// 0x1000 is out putted in windows driver
+
+		var = devpriv->ul_DmaBufferHw[next_dma_buf];
+		low_word = var & 0xffff;
+		var = devpriv->ul_DmaBufferHw[next_dma_buf];
+		high_word = var / 65536;
+
+		/* DMA Start Adress Low */
+		outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0);
+		outw(low_word, devpriv->i_IobaseAddon + 2);
+
+		/* DMA Start Adress High */
+		outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0);
+		outw(high_word, devpriv->i_IobaseAddon + 2);
+
+		var = devpriv->ui_DmaBufferUsesize[next_dma_buf];
+		low_word = var & 0xffff;
+		var = devpriv->ui_DmaBufferUsesize[next_dma_buf];
+		high_word = var / 65536;
+
+		/* Nbr of acquisition LOW */
+		outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0);
+		outw(low_word, devpriv->i_IobaseAddon + 2);
+
+		/* Nbr of acquisition HIGH */
+		outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0);
+		outw(high_word, devpriv->i_IobaseAddon + 2);
+
+		// To configure A2P FIFO
+		// ENABLE A2P FIFO WRITE AND ENABLE AMWEN
+		// AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03
+		outw(3, devpriv->i_IobaseAddon + 4);
+		//initialise end of dma interrupt  AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI)
+		outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 |
+				APCI3120_ENABLE_WRITE_TC_INT),
+			devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR);
+
+	}
+/*UPDATE-0.7.57->0.7.68
+	ptr=(short *)devpriv->ul_DmaBufferVirtual[devpriv->ui_DmaActualBuffer];
+
+
+	// if there is not enough space left in the buffer to copy all data contained in the DMABufferVirtual
+	if(s->async->buf_int_ptr+samplesinbuf*sizeof(short)>=devpriv->ui_AiDataLength)
+	{
+		m=(devpriv->ui_AiDataLength-s->async->buf_int_ptr)/sizeof(short);
+		v_APCI3120_InterruptDmaMoveBlock16bit(dev,s,(void *)ptr,((void *)(devpriv->AiData))+s->async->buf_int_ptr,m);
+		s->async->buf_int_count+=m*sizeof(short);
+		ptr+=m*sizeof(short);
+                samplesinbuf-=m;
+		s->async->buf_int_ptr=0;
+		comedi_eobuf(dev,s);
+	}
+
+	if (samplesinbuf)
+	{
+	        v_APCI3120_InterruptDmaMoveBlock16bit(dev,s,(void *)ptr,((void *)(devpriv->AiData))+s->async->buf_int_ptr,samplesinbuf);
+
+		s->async->buf_int_count+=samplesinbuf*sizeof(short);
+		s->async->buf_int_ptr+=samplesinbuf*sizeof(short);
+		if (!(devpriv->ui_AiFlags & TRIG_WAKE_EOS))
+		{
+			comedi_bufcheck(dev,s);
+                }
+	}
+	if (!devpriv->b_AiContinuous)
+	if ( devpriv->ui_AiActualScan>=devpriv->ui_AiNbrofScans )
+	{
+	    // all data sampled
+	    i_APCI3120_StopCyclicAcquisition(dev,s);
+            devpriv->b_AiCyclicAcquisition=APCI3120_DISABLE;
+	    //DPRINTK("\n Single DMA completed..\n");
+		comedi_done(dev,s);
+            	return;
+	}
+*/
+	if (samplesinbuf) {
+		v_APCI3120_InterruptDmaMoveBlock16bit(dev, s,
+			devpriv->ul_DmaBufferVirtual[devpriv->
+				ui_DmaActualBuffer], samplesinbuf);
+
+		if (!(devpriv->ui_AiFlags & TRIG_WAKE_EOS)) {
+			s->async->events |= COMEDI_CB_EOS;
+			comedi_event(dev, s);
+		}
+	}
+	if (!devpriv->b_AiContinuous)
+		if (devpriv->ui_AiActualScan >= devpriv->ui_AiNbrofScans) {
+			// all data sampled
+			i_APCI3120_StopCyclicAcquisition(dev, s);
+			devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
+			s->async->events |= COMEDI_CB_EOA;
+			comedi_event(dev, s);
+			return;
+		}
+
+	if (devpriv->b_DmaDoubleBuffer) {	// switch dma buffers
+		devpriv->ui_DmaActualBuffer = 1 - devpriv->ui_DmaActualBuffer;
+	} else {
+		// restart DMA if is not used double buffering
+		//ADDED REINITIALISE THE DMA
+		ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO;
+		outl(ui_Tmp, devpriv->i_IobaseAddon + AMCC_OP_REG_AGCSTS);
+
+		// changed  since 16 bit interface for add on
+		outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0);
+		outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW,
+			devpriv->i_IobaseAddon + 2);
+		outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0);
+		outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->i_IobaseAddon + 2);	//
+		// A2P FIFO MANAGEMENT
+		// A2P fifo reset  & transfer control enable
+		outl(APCI3120_A2P_FIFO_MANAGEMENT,
+			devpriv->i_IobaseAmcc + AMCC_OP_REG_MCSR);
+
+		var = devpriv->ul_DmaBufferHw[0];
+		low_word = var & 0xffff;
+		var = devpriv->ul_DmaBufferHw[0];
+		high_word = var / 65536;
+		outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0);
+		outw(low_word, devpriv->i_IobaseAddon + 2);
+		outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0);
+		outw(high_word, devpriv->i_IobaseAddon + 2);
+
+		var = devpriv->ui_DmaBufferUsesize[0];
+		low_word = var & 0xffff;	//changed
+		var = devpriv->ui_DmaBufferUsesize[0];
+		high_word = var / 65536;
+		outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0);
+		outw(low_word, devpriv->i_IobaseAddon + 2);
+		outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0);
+		outw(high_word, devpriv->i_IobaseAddon + 2);
+
+		// To configure A2P FIFO
+		//ENABLE A2P FIFO WRITE AND ENABLE AMWEN
+		// AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03
+		outw(3, devpriv->i_IobaseAddon + 4);
+		//initialise end of dma interrupt  AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI)
+		outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 |
+				APCI3120_ENABLE_WRITE_TC_INT),
+			devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR);
+	}
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name     :void v_APCI3120_InterruptDmaMoveBlock16bit(comedi_device|
+|*dev,struct comedi_subdevice *s,short *dma,short *data,int n)				     |
+|                                        									 |
++----------------------------------------------------------------------------+
+| Task              : This function copies the data from DMA buffer to the   |
+|				 Comedi buffer  									 |
+|                     										                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev									 |
+|                     struct comedi_subdevice *s									 |
+|                     short *dma											 |
+|                     short *data,int n          					         |
++----------------------------------------------------------------------------+
+| Return Value      : void         					                         |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+
+/*void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev,struct comedi_subdevice *s,short *dma,short *data,int n)
+{
+	int i,j,m;
+
+	j=s->async->cur_chan;
+	m=devpriv->ui_AiActualScanPosition;
+        for(i=0;i<n;i++)
+	{
+		*data=*dma;
+   		data++; dma++;
+		j++;
+		if(j>=devpriv->ui_AiNbrofChannels)
+		{
+			m+=j;
+			j=0;
+			if(m>=devpriv->ui_AiScanLength)
+			{
+				m=0;
+			        devpriv->ui_AiActualScan++;
+				if (devpriv->ui_AiFlags & TRIG_WAKE_EOS)
+;//UPDATE-0.7.57->0.7.68					comedi_eos(dev,s);
+			}
+		}
+	}
+        devpriv->ui_AiActualScanPosition=m;
+	s->async->cur_chan=j;
+
+}
+*/
+void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device * dev,
+	struct comedi_subdevice * s, short * dma_buffer, unsigned int num_samples)
+{
+	devpriv->ui_AiActualScan +=
+		(s->async->cur_chan + num_samples) / devpriv->ui_AiScanLength;
+	s->async->cur_chan += num_samples;
+	s->async->cur_chan %= devpriv->ui_AiScanLength;
+
+	cfc_write_array_to_buffer(s, dma_buffer, num_samples * sizeof(short));
+}
+
+/*
++----------------------------------------------------------------------------+
+|                           TIMER SUBDEVICE   		                         |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function name     :int i_APCI3120_InsnConfigTimer(struct comedi_device *dev,          |
+|	struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) 			     |
+|                                        									 |
++----------------------------------------------------------------------------+
+| Task              :Configure Timer 2  								     |
+|                     										                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev									 |
+|                     struct comedi_subdevice *s									 |
+|                     struct comedi_insn *insn                                      |
+|                     unsigned int *data 										 |
+|                     														 |
+|                      data[0]= TIMER  configure as timer                    |
+|              				 = WATCHDOG configure as watchdog				 |
+|       			  data[1] = Timer constant							 |
+|       			  data[2] = Timer2 interrupt (1)enable or(0) disable |
+|                                                 					         |
++----------------------------------------------------------------------------+
+| Return Value      :              					                         |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnConfigTimer(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+
+	UINT ui_Timervalue2;
+	USHORT us_TmpValue;
+	BYTE b_Tmp;
+
+	if (!data[1])
+		comedi_error(dev, "config:No timer constant !");
+
+	devpriv->b_Timer2Interrupt = (BYTE) data[2];	// save info whether to enable or disable interrupt
+
+	ui_Timervalue2 = data[1] / 1000;	// convert nano seconds  to u seconds
+
+	//this_board->i_hwdrv_InsnConfigTimer(dev, ui_Timervalue2,(BYTE)data[0]);
+	us_TmpValue = (USHORT) inw(devpriv->iobase + APCI3120_RD_STATUS);
+
+	//EL250804: Testing if board APCI3120 have the new Quartz or if it is an APCI3001
+	// and calculate the time value to set in the timer
+	if ((us_TmpValue & 0x00B0) == 0x00B0
+		|| !strcmp(this_board->pc_DriverName, "apci3001")) {
+		//Calculate the time value to set in the timer
+		ui_Timervalue2 = ui_Timervalue2 / 50;
+	} else {
+		//Calculate the time value to set in the timer
+		ui_Timervalue2 = ui_Timervalue2 / 70;
+	}
+
+	//Reset gate 2 of Timer 2 to disable it (Set Bit D14 to 0)
+	devpriv->us_OutputRegister =
+		devpriv->us_OutputRegister & APCI3120_DISABLE_TIMER2;
+	outw(devpriv->us_OutputRegister, devpriv->iobase + APCI3120_WR_ADDRESS);
+
+	// Disable TIMER Interrupt
+	devpriv->b_ModeSelectRegister =
+		devpriv->
+		b_ModeSelectRegister & APCI3120_DISABLE_TIMER_INT & 0xEF;
+
+	// Disable Eoc and Eos Interrupts
+	devpriv->b_ModeSelectRegister =
+		devpriv->
+		b_ModeSelectRegister & APCI3120_DISABLE_EOC_INT &
+		APCI3120_DISABLE_EOS_INT;
+	outb(devpriv->b_ModeSelectRegister,
+		devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
+	if (data[0] == APCI3120_TIMER)	//initialize timer
+	{
+
+		//devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister| APCI3120_ENABLE_TIMER_INT ;
+		//outb(devpriv->b_ModeSelectRegister,devpriv->iobase+APCI3120_WRITE_MODE_SELECT);
+
+		//Set the Timer 2 in mode 2(Timer)
+		devpriv->b_TimerSelectMode =
+			(devpriv->
+			b_TimerSelectMode & 0x0F) | APCI3120_TIMER_2_MODE_2;
+		outb(devpriv->b_TimerSelectMode,
+			devpriv->iobase + APCI3120_TIMER_CRT1);
+
+		//Configure the timer 2 for writing the LOW WORD of timer is Delay value
+		//You must make a b_tmp variable with DigitalOutPutRegister because at Address_1+APCI3120_TIMER_CRT0
+		//you can set the digital output and configure the timer 2,and if you don't make this, digital output
+		//are erase (Set to 0)
+
+		//Writing LOW WORD
+		b_Tmp = ((devpriv->
+				b_DigitalOutputRegister) & 0xF0) |
+			APCI3120_SELECT_TIMER_2_LOW_WORD;
+		outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+		outw(LOWORD(ui_Timervalue2),
+			devpriv->iobase + APCI3120_TIMER_VALUE);
+
+		//Writing HIGH WORD
+		b_Tmp = ((devpriv->
+				b_DigitalOutputRegister) & 0xF0) |
+			APCI3120_SELECT_TIMER_2_HIGH_WORD;
+		outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+		outw(HIWORD(ui_Timervalue2),
+			devpriv->iobase + APCI3120_TIMER_VALUE);
+		// timer2 in Timer mode enabled
+		devpriv->b_Timer2Mode = APCI3120_TIMER;
+
+	} else			// Initialize Watch dog
+	{
+
+		//Set the Timer 2 in mode 5(Watchdog)
+
+		devpriv->b_TimerSelectMode =
+			(devpriv->
+			b_TimerSelectMode & 0x0F) | APCI3120_TIMER_2_MODE_5;
+		outb(devpriv->b_TimerSelectMode,
+			devpriv->iobase + APCI3120_TIMER_CRT1);
+
+		//Configure the timer 2 for writing the LOW WORD of timer is Delay value
+		//You must make a b_tmp variable with DigitalOutPutRegister because at Address_1+APCI3120_TIMER_CRT0
+		//you can set the digital output and configure the timer 2,and if you don't make this, digital output
+		//are erase (Set to 0)
+
+		//Writing LOW WORD
+		b_Tmp = ((devpriv->
+				b_DigitalOutputRegister) & 0xF0) |
+			APCI3120_SELECT_TIMER_2_LOW_WORD;
+		outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+		outw(LOWORD(ui_Timervalue2),
+			devpriv->iobase + APCI3120_TIMER_VALUE);
+
+		//Writing HIGH WORD
+		b_Tmp = ((devpriv->
+				b_DigitalOutputRegister) & 0xF0) |
+			APCI3120_SELECT_TIMER_2_HIGH_WORD;
+		outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+
+		outw(HIWORD(ui_Timervalue2),
+			devpriv->iobase + APCI3120_TIMER_VALUE);
+		//watchdog enabled
+		devpriv->b_Timer2Mode = APCI3120_WATCHDOG;
+
+	}
+
+	return insn->n;
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name     :int i_APCI3120_InsnWriteTimer(struct comedi_device *dev,           |
+|                    struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data)  |
+|                                            						         |
++----------------------------------------------------------------------------+
+| Task              :    To start and stop the timer		                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev									 |
+|                     struct comedi_subdevice *s									 |
+|                     struct comedi_insn *insn                                      |
+|                     unsigned int *data                                         |
+|                                                                            |
+|				data[0] = 1 (start)                                  |
+|				data[0] = 0 (stop )                                  |
+|	 			data[0] = 2  (write new value)                       |
+|	   			data[1]= new value                                   |
+|                                                                            |
+|    				devpriv->b_Timer2Mode =  0 DISABLE                   |
+|	                     					 1 Timer                     |
+|					 					 2 Watch dog			     |
+|                                                 					         |
++----------------------------------------------------------------------------+
+| Return Value      :              					                         |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnWriteTimer(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+
+	UINT ui_Timervalue2 = 0;
+	USHORT us_TmpValue;
+	BYTE b_Tmp;
+
+	if ((devpriv->b_Timer2Mode != APCI3120_WATCHDOG)
+		&& (devpriv->b_Timer2Mode != APCI3120_TIMER)) {
+		comedi_error(dev, "\nwrite:timer2  not configured ");
+		return -EINVAL;
+	}
+
+	if (data[0] == 2)	// write new value
+	{
+		if (devpriv->b_Timer2Mode != APCI3120_TIMER) {
+			comedi_error(dev,
+				"write :timer2  not configured  in TIMER MODE");
+			return -EINVAL;
+		}
+
+		if (data[1])
+			ui_Timervalue2 = data[1];
+		else
+			ui_Timervalue2 = 0;
+	}
+
+	//this_board->i_hwdrv_InsnWriteTimer(dev,data[0],ui_Timervalue2);
+
+	switch (data[0]) {
+	case APCI3120_START:
+
+		// Reset FC_TIMER BIT
+		inb(devpriv->iobase + APCI3120_TIMER_STATUS_REGISTER);
+		if (devpriv->b_Timer2Mode == APCI3120_TIMER)	//start timer
+		{
+			//Enable Timer
+			devpriv->b_ModeSelectRegister =
+				devpriv->b_ModeSelectRegister & 0x0B;
+		} else		//start watch dog
+		{
+			//Enable WatchDog
+			devpriv->b_ModeSelectRegister =
+				(devpriv->
+				b_ModeSelectRegister & 0x0B) |
+				APCI3120_ENABLE_WATCHDOG;
+		}
+
+		//enable disable interrupt
+		if ((devpriv->b_Timer2Interrupt) == APCI3120_ENABLE) {
+
+			devpriv->b_ModeSelectRegister =
+				devpriv->
+				b_ModeSelectRegister |
+				APCI3120_ENABLE_TIMER_INT;
+			// save the task structure to pass info to user
+			devpriv->tsk_Current = current;
+		} else {
+
+			devpriv->b_ModeSelectRegister =
+				devpriv->
+				b_ModeSelectRegister &
+				APCI3120_DISABLE_TIMER_INT;
+		}
+		outb(devpriv->b_ModeSelectRegister,
+			devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
+
+		if (devpriv->b_Timer2Mode == APCI3120_TIMER)	//start timer
+		{
+			//For Timer mode is  Gate2 must be activated   **timer started
+			devpriv->us_OutputRegister =
+				devpriv->
+				us_OutputRegister | APCI3120_ENABLE_TIMER2;
+			outw(devpriv->us_OutputRegister,
+				devpriv->iobase + APCI3120_WR_ADDRESS);
+		}
+
+		break;
+
+	case APCI3120_STOP:
+		if (devpriv->b_Timer2Mode == APCI3120_TIMER) {
+			//Disable timer
+			devpriv->b_ModeSelectRegister =
+				devpriv->
+				b_ModeSelectRegister &
+				APCI3120_DISABLE_TIMER_COUNTER;
+		} else {
+			//Disable WatchDog
+			devpriv->b_ModeSelectRegister =
+				devpriv->
+				b_ModeSelectRegister &
+				APCI3120_DISABLE_WATCHDOG;
+		}
+		// Disable timer interrupt
+		devpriv->b_ModeSelectRegister =
+			devpriv->
+			b_ModeSelectRegister & APCI3120_DISABLE_TIMER_INT;
+
+		// Write above states  to register
+		outb(devpriv->b_ModeSelectRegister,
+			devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
+
+		// Reset Gate 2
+		devpriv->us_OutputRegister =
+			devpriv->us_OutputRegister & APCI3120_DISABLE_TIMER_INT;
+		outw(devpriv->us_OutputRegister,
+			devpriv->iobase + APCI3120_WR_ADDRESS);
+
+		// Reset FC_TIMER BIT
+		inb(devpriv->iobase + APCI3120_TIMER_STATUS_REGISTER);
+
+		// Disable timer
+		//devpriv->b_Timer2Mode=APCI3120_DISABLE;
+
+		break;
+
+	case 2:		//write new value to Timer
+		if (devpriv->b_Timer2Mode != APCI3120_TIMER) {
+			comedi_error(dev,
+				"write :timer2  not configured  in TIMER MODE");
+			return -EINVAL;
+		}
+		// ui_Timervalue2=data[1]; // passed as argument
+		us_TmpValue =
+			(USHORT) inw(devpriv->iobase + APCI3120_RD_STATUS);
+
+		//EL250804: Testing if board APCI3120 have the new Quartz or if it is an APCI3001
+		// and calculate the time value to set in the timer
+		if ((us_TmpValue & 0x00B0) == 0x00B0
+			|| !strcmp(this_board->pc_DriverName, "apci3001")) {
+			//Calculate the time value to set in the timer
+			ui_Timervalue2 = ui_Timervalue2 / 50;
+		} else {
+			//Calculate the time value to set in the timer
+			ui_Timervalue2 = ui_Timervalue2 / 70;
+		}
+		//Writing LOW WORD
+		b_Tmp = ((devpriv->
+				b_DigitalOutputRegister) & 0xF0) |
+			APCI3120_SELECT_TIMER_2_LOW_WORD;
+		outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+
+		outw(LOWORD(ui_Timervalue2),
+			devpriv->iobase + APCI3120_TIMER_VALUE);
+
+		//Writing HIGH WORD
+		b_Tmp = ((devpriv->
+				b_DigitalOutputRegister) & 0xF0) |
+			APCI3120_SELECT_TIMER_2_HIGH_WORD;
+		outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+
+		outw(HIWORD(ui_Timervalue2),
+			devpriv->iobase + APCI3120_TIMER_VALUE);
+
+		break;
+	default:
+		return -EINVAL;	// Not a valid input
+	}
+
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name     : int i_APCI3120_InsnReadTimer(struct comedi_device *dev,           |
+|		struct comedi_subdevice *s,struct comedi_insn *insn, unsigned int *data) 		 |
+|                                        									 |
+|                                            						         |
++----------------------------------------------------------------------------+
+| Task              : read the Timer value 				                 	 |
++----------------------------------------------------------------------------+
+| Input Parameters  : 	struct comedi_device *dev									 |
+|                     struct comedi_subdevice *s									 |
+|                     struct comedi_insn *insn                                      |
+|                     unsigned int *data 										 |
+|                     														 |
++----------------------------------------------------------------------------+
+| Return Value      :   													 |
+|			for Timer:	data[0]= Timer constant						 |
+|																	 |
+|         		for watchdog: data[0]=0 (still running)                  |
+|	               			  data[0]=1  (run down)            			 |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+int i_APCI3120_InsnReadTimer(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	BYTE b_Tmp;
+	USHORT us_TmpValue, us_TmpValue_2, us_StatusValue;
+
+	if ((devpriv->b_Timer2Mode != APCI3120_WATCHDOG)
+		&& (devpriv->b_Timer2Mode != APCI3120_TIMER)) {
+		comedi_error(dev, "\nread:timer2  not configured ");
+	}
+
+	//this_board->i_hwdrv_InsnReadTimer(dev,data);
+	if (devpriv->b_Timer2Mode == APCI3120_TIMER) {
+
+		//Read the LOW WORD of Timer 2 register
+		b_Tmp = ((devpriv->
+				b_DigitalOutputRegister) & 0xF0) |
+			APCI3120_SELECT_TIMER_2_LOW_WORD;
+		outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+
+		us_TmpValue = inw(devpriv->iobase + APCI3120_TIMER_VALUE);
+
+		//Read the HIGH WORD of Timer 2 register
+		b_Tmp = ((devpriv->
+				b_DigitalOutputRegister) & 0xF0) |
+			APCI3120_SELECT_TIMER_2_HIGH_WORD;
+		outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+
+		us_TmpValue_2 = inw(devpriv->iobase + APCI3120_TIMER_VALUE);
+
+		// combining both words
+		data[0] = (UINT) ((us_TmpValue) | ((us_TmpValue_2) << 16));
+
+	} else			// Read watch dog status
+	{
+
+		us_StatusValue = inw(devpriv->iobase + APCI3120_RD_STATUS);
+		us_StatusValue =
+			((us_StatusValue & APCI3120_FC_TIMER) >> 12) & 1;
+		if (us_StatusValue == 1) {
+			// RESET FC_TIMER BIT
+			inb(devpriv->iobase + APCI3120_TIMER_STATUS_REGISTER);
+		}
+		data[0] = us_StatusValue;	// when data[0] = 1 then the watch dog has rundown
+	}
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+|                           DIGITAL INPUT SUBDEVICE   		                 |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function name     :int i_APCI3120_InsnReadDigitalInput(struct comedi_device *dev,     |
+|			struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data)   |
+|                                        									 |
+|                                            						         |
++----------------------------------------------------------------------------+
+| Task              : Reads the value of the specified  Digital input channel|
+|                     										                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev									 |
+|                     struct comedi_subdevice *s									 |
+|                     struct comedi_insn *insn                                      |
+|                     unsigned int *data 										 |
++----------------------------------------------------------------------------+
+| Return Value      :              					                         |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnReadDigitalInput(struct comedi_device *dev,
+				    struct comedi_subdevice *s,
+				    struct comedi_insn *insn,
+				    unsigned int *data)
+{
+	UINT ui_Chan, ui_TmpValue;
+
+	ui_Chan = CR_CHAN(insn->chanspec);	// channel specified
+
+	//this_board->i_hwdrv_InsnReadDigitalInput(dev,ui_Chan,data);
+	if (ui_Chan >= 0 && ui_Chan <= 3) {
+		ui_TmpValue = (UINT) inw(devpriv->iobase + APCI3120_RD_STATUS);
+
+		//      since only 1 channel reqd  to bring it to last bit it is rotated
+		//  8 +(chan - 1) times then ANDed with 1 for last bit.
+		*data = (ui_TmpValue >> (ui_Chan + 8)) & 1;
+		//return 0;
+	} else {
+		//      comedi_error(dev," chan spec wrong");
+		return -EINVAL;	// "sorry channel spec wrong "
+	}
+	return insn->n;
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name     :int i_APCI3120_InsnBitsDigitalInput(struct comedi_device *dev, |
+|struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data)                      |
+|                                        									 |
++----------------------------------------------------------------------------+
+| Task              : Reads the value of the Digital input Port i.e.4channels|
+|   value is returned in data[0]											 |
+|                     										                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev									 |
+|                     struct comedi_subdevice *s									 |
+|                     struct comedi_insn *insn                                      |
+|                     unsigned int *data 										 |
++----------------------------------------------------------------------------+
+| Return Value      :              					                         |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+int i_APCI3120_InsnBitsDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_TmpValue;
+	ui_TmpValue = (UINT) inw(devpriv->iobase + APCI3120_RD_STATUS);
+	/*****	state of 4 channels  in the 11, 10, 9, 8   bits of status reg
+			rotated right 8 times to bring them to last four bits
+			ANDed with oxf for  value.
+	*****/
+
+	*data = (ui_TmpValue >> 8) & 0xf;
+	//this_board->i_hwdrv_InsnBitsDigitalInput(dev,data);
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+|                           DIGITAL OUTPUT SUBDEVICE   		                 |
++----------------------------------------------------------------------------+
+*/
+/*
++----------------------------------------------------------------------------+
+| Function name     :int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device    |
+| *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)				 |
+|                                            						         |
++----------------------------------------------------------------------------+
+| Task              :Configure the output memory ON or OFF				     |
+|                     										                 |
++----------------------------------------------------------------------------+
+| Input Parameters  :struct comedi_device *dev									 	 |
+|                     struct comedi_subdevice *s									 |
+|                     struct comedi_insn *insn                                      |
+|                     unsigned int *data 										 |
++----------------------------------------------------------------------------+
+| Return Value      :              					                         |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+
+	if ((data[0] != 0) && (data[0] != 1)) {
+		comedi_error(dev,
+			"Not a valid Data !!! ,Data should be 1 or 0\n");
+		return -EINVAL;
+	}
+	if (data[0]) {
+		devpriv->b_OutputMemoryStatus = APCI3120_ENABLE;
+
+	} else {
+		devpriv->b_OutputMemoryStatus = APCI3120_DISABLE;
+		devpriv->b_DigitalOutputRegister = 0;
+	}
+	if (!devpriv->b_OutputMemoryStatus) {
+		ui_Temp = 0;
+
+	}			//if(!devpriv->b_OutputMemoryStatus )
+
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name     :int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device *dev,    |
+|		struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) 		 |
+|                                        									 |
++----------------------------------------------------------------------------+
+| Task              : write diatal output port							     |
+|                     										                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev									 |
+|                     struct comedi_subdevice *s									 |
+|                     struct comedi_insn *insn                                      |
+|                     unsigned int *data 										 |
+                      data[0]     Value to be written
+                      data[1]    :1 Set digital o/p ON
+                      data[1]     2 Set digital o/p OFF with memory ON
++----------------------------------------------------------------------------+
+| Return Value      :              					                         |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device * dev,
+				     struct comedi_subdevice *s,
+				     struct comedi_insn *insn,
+				     unsigned int *data)
+{
+	if ((data[0] > this_board->i_DoMaxdata) || (data[0] < 0)) {
+
+		comedi_error(dev, "Data is not valid !!! \n");
+		return -EINVAL;
+	}
+
+	switch (data[1]) {
+	case 1:
+		data[0] = (data[0] << 4) | devpriv->b_DigitalOutputRegister;
+		break;
+
+	case 2:
+		data[0] = data[0];
+		break;
+	default:
+		printk("\nThe parameter passed is in error \n");
+		return -EINVAL;
+	}			// switch(data[1])
+	outb(data[0], devpriv->iobase + APCI3120_DIGITAL_OUTPUT);
+
+	devpriv->b_DigitalOutputRegister = data[0] & 0xF0;
+
+	return insn->n;
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name     :int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev,|
+|struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) 			             |
+|                                            						         |
++----------------------------------------------------------------------------+
+| Task              : Write digiatl output								     |
+|                     										                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev								 	 |
+|                     struct comedi_subdevice *s									 |
+|                     struct comedi_insn *insn                                      |
+|                     unsigned int *data 										 |
+                      data[0]     Value to be written
+                      data[1]    :1 Set digital o/p ON
+                      data[1]     2 Set digital o/p OFF with memory ON
++----------------------------------------------------------------------------+
+| Return Value      :              					                         |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev,
+				      struct comedi_subdevice *s,
+				      struct comedi_insn *insn,
+				      unsigned int *data)
+{
+
+	UINT ui_Temp1;
+
+	UINT ui_NoOfChannel = CR_CHAN(insn->chanspec);	// get the channel
+
+	if ((data[0] != 0) && (data[0] != 1)) {
+		comedi_error(dev,
+			"Not a valid Data !!! ,Data should be 1 or 0\n");
+		return -EINVAL;
+	}
+	if ((ui_NoOfChannel > (this_board->i_NbrDoChannel - 1))
+		|| (ui_NoOfChannel < 0)) {
+		comedi_error(dev,
+			"This board doesn't have specified channel !!! \n");
+		return -EINVAL;
+	}
+
+	switch (data[1]) {
+	case 1:
+		data[0] = (data[0] << ui_NoOfChannel);
+//ES05                   data[0]=(data[0]<<4)|ui_Temp;
+		data[0] = (data[0] << 4) | devpriv->b_DigitalOutputRegister;
+		break;
+
+	case 2:
+		data[0] = ~data[0] & 0x1;
+		ui_Temp1 = 1;
+		ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+		ui_Temp1 = ui_Temp1 << 4;
+//ES05                   ui_Temp=ui_Temp|ui_Temp1;
+		devpriv->b_DigitalOutputRegister =
+			devpriv->b_DigitalOutputRegister | ui_Temp1;
+
+		data[0] = (data[0] << ui_NoOfChannel) ^ 0xf;
+		data[0] = data[0] << 4;
+//ES05                   data[0]=data[0]& ui_Temp;
+		data[0] = data[0] & devpriv->b_DigitalOutputRegister;
+		break;
+	default:
+		printk("\nThe parameter passed is in error \n");
+		return -EINVAL;
+	}			// switch(data[1])
+	outb(data[0], devpriv->iobase + APCI3120_DIGITAL_OUTPUT);
+
+//ES05        ui_Temp=data[0] & 0xf0;
+	devpriv->b_DigitalOutputRegister = data[0] & 0xf0;
+	return (insn->n);
+
+}
+
+/*
++----------------------------------------------------------------------------+
+|                            ANALOG OUTPUT SUBDEVICE                         |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function name     :int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev,|
+|struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data)			             |
+|                                        									 |
++----------------------------------------------------------------------------+
+| Task              : Write  analog output   							     |
+|                     										                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev									 |
+|                     struct comedi_subdevice *s									 |
+|                     struct comedi_insn *insn                                      |
+|                     unsigned int *data  										 |
++----------------------------------------------------------------------------+
+| Return Value      :              					                         |
+|                    													     |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev,
+				     struct comedi_subdevice *s,
+				     struct comedi_insn *insn,
+				     unsigned int *data)
+{
+	UINT ui_Range, ui_Channel;
+	USHORT us_TmpValue;
+
+	ui_Range = CR_RANGE(insn->chanspec);
+	ui_Channel = CR_CHAN(insn->chanspec);
+
+	//this_board->i_hwdrv_InsnWriteAnalogOutput(dev, ui_Range, ui_Channel,data[0]);
+	if (ui_Range)		// if 1 then unipolar
+	{
+
+		if (data[0] != 0)
+			data[0] =
+				((((ui_Channel & 0x03) << 14) & 0xC000) | (1 <<
+					13) | (data[0] + 8191));
+		else
+			data[0] =
+				((((ui_Channel & 0x03) << 14) & 0xC000) | (1 <<
+					13) | 8192);
+
+	} else			// if 0 then   bipolar
+	{
+		data[0] =
+			((((ui_Channel & 0x03) << 14) & 0xC000) | (0 << 13) |
+			data[0]);
+
+	}
+
+	//out put n values at the given channel.
+	// rt_printk("\nwaiting for DA_READY BIT");
+	do			//Waiting of DA_READY BIT
+	{
+		us_TmpValue =
+			((USHORT) inw(devpriv->iobase +
+				APCI3120_RD_STATUS)) & 0x0001;
+	} while (us_TmpValue != 0x0001);
+
+	if (ui_Channel <= 3)
+		// for channel 0-3 out at  the register 1 (wrDac1-8)
+		// data[i] typecasted to ushort since  word write is to be done
+		outw((USHORT) data[0],
+			devpriv->iobase + APCI3120_ANALOG_OUTPUT_1);
+	else
+		// for channel 4-7 out at the register 2 (wrDac5-8)
+		//data[i] typecasted to ushort since  word write is to be done
+		outw((USHORT) data[0],
+			devpriv->iobase + APCI3120_ANALOG_OUTPUT_2);
+
+	return insn->n;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h
new file mode 100644
index 0000000..59d5d87
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h
@@ -0,0 +1,241 @@
+
+// hwdrv_apci3120.h
+
+/*
+ * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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.
+ */
+
+// comedi related defines
+
+//ANALOG INPUT RANGE
+static const struct comedi_lrange range_apci3120_ai = { 8, {
+						     BIP_RANGE(10),
+						     BIP_RANGE(5),
+						     BIP_RANGE(2),
+						     BIP_RANGE(1),
+						     UNI_RANGE(10),
+						     UNI_RANGE(5),
+						     UNI_RANGE(2),
+						     UNI_RANGE(1)
+						     }
+};
+
+// ANALOG OUTPUT RANGE
+static const struct comedi_lrange range_apci3120_ao = { 2, {
+						     BIP_RANGE(10),
+						     UNI_RANGE(10)
+						     }
+};
+
+#define APCI3120_BIPOLAR_RANGES	4	// used for test on mixture of BIP/UNI ranges
+
+#define APCI3120_BOARD_VENDOR_ID                 0x10E8
+#define APCI3120_ADDRESS_RANGE            			16
+
+#define APCI3120_DISABLE                         0
+#define APCI3120_ENABLE                          1
+
+#define APCI3120_START                           1
+#define APCI3120_STOP                            0
+
+#define     APCI3120_EOC_MODE         1
+#define     APCI3120_EOS_MODE         2
+#define     APCI3120_DMA_MODE         3
+
+//DIGITAL INPUT-OUTPUT DEFINE
+
+#define APCI3120_DIGITAL_OUTPUT                  	0x0D
+#define APCI3120_RD_STATUS                       	0x02
+#define APCI3120_RD_FIFO                     		0x00
+
+// digital output insn_write ON /OFF selection
+#define	APCI3120_SET4DIGITALOUTPUTON				1
+#define APCI3120_SET4DIGITALOUTPUTOFF				0
+
+// analog output SELECT BIT
+#define APCI3120_ANALOG_OP_CHANNEL_1   0x0000
+#define APCI3120_ANALOG_OP_CHANNEL_2   0x4000
+#define APCI3120_ANALOG_OP_CHANNEL_3   0x8000
+#define APCI3120_ANALOG_OP_CHANNEL_4   0xC000
+#define APCI3120_ANALOG_OP_CHANNEL_5   0x0000
+#define APCI3120_ANALOG_OP_CHANNEL_6   0x4000
+#define APCI3120_ANALOG_OP_CHANNEL_7   0x8000
+#define APCI3120_ANALOG_OP_CHANNEL_8   0xC000
+
+// Enable external trigger bit in nWrAddress
+#define APCI3120_ENABLE_EXT_TRIGGER    0x8000
+
+//ANALOG OUTPUT AND INPUT DEFINE
+#define APCI3120_UNIPOLAR 0x80	//$$ RAM sequence polarity BIT
+#define APCI3120_BIPOLAR  0x00	//$$ RAM sequence polarity BIT
+#define APCI3120_ANALOG_OUTPUT_1 0x08	// (ADDRESS )
+#define APCI3120_ANALOG_OUTPUT_2 0x0A	// (ADDRESS )
+#define APCI3120_1_GAIN              0x00	//$$ RAM sequence Gain Bits for gain 1
+#define APCI3120_2_GAIN              0x10	//$$ RAM sequence Gain Bits for gain 2
+#define APCI3120_5_GAIN              0x20	//$$ RAM sequence Gain Bits for gain 5
+#define APCI3120_10_GAIN             0x30	//$$ RAM sequence Gain Bits for gain 10
+#define APCI3120_SEQ_RAM_ADDRESS        0x06	//$$ EARLIER NAMED APCI3120_FIFO_ADDRESS
+#define APCI3120_RESET_FIFO          0x0C	//(ADDRESS)
+#define APCI3120_TIMER_0_MODE_2      0x01	//$$ Bits for timer mode
+#define APCI3120_TIMER_0_MODE_4       0x2
+#define APCI3120_SELECT_TIMER_0_WORD 0x00
+#define APCI3120_ENABLE_TIMER0     0x1000	//$$Gatebit 0 in nWrAddress
+#define APCI3120_CLEAR_PR          0xF0FF
+#define APCI3120_CLEAR_PA          0xFFF0
+#define APCI3120_CLEAR_PA_PR       (APCI3120_CLEAR_PR & APCI3120_CLEAR_PA)
+
+// nWrMode_Select
+#define APCI3120_ENABLE_SCAN          0x8	//$$ bit in nWrMode_Select
+#define APCI3120_DISABLE_SCAN      (~APCI3120_ENABLE_SCAN)
+#define APCI3120_ENABLE_EOS_INT       0x2	//$$ bit in nWrMode_Select
+
+#define APCI3120_DISABLE_EOS_INT   (~APCI3120_ENABLE_EOS_INT)
+#define APCI3120_ENABLE_EOC_INT       0x1
+#define APCI3120_DISABLE_EOC_INT   (~APCI3120_ENABLE_EOC_INT)
+#define APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER   (APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT)
+#define APCI3120_DISABLE_ALL_INTERRUPT   (APCI3120_DISABLE_TIMER_INT & APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT)
+
+//status register bits
+#define APCI3120_EOC                     0x8000
+#define APCI3120_EOS                     0x2000
+
+// software trigger dummy register
+#define APCI3120_START_CONVERSION        0x02	//(ADDRESS)
+
+//TIMER DEFINE
+#define APCI3120_QUARTZ_A				  70
+#define APCI3120_QUARTZ_B				  50
+#define APCI3120_TIMER                            1
+#define APCI3120_WATCHDOG                         2
+#define APCI3120_TIMER_DISABLE                    0
+#define APCI3120_TIMER_ENABLE                     1
+#define APCI3120_ENABLE_TIMER2                    0x4000	//$$ gatebit 2 in nWrAddress
+#define APCI3120_DISABLE_TIMER2                   (~APCI3120_ENABLE_TIMER2)
+#define APCI3120_ENABLE_TIMER_INT                 0x04	//$$ ENAIRQ_FC_Bit in nWrModeSelect
+#define APCI3120_DISABLE_TIMER_INT                (~APCI3120_ENABLE_TIMER_INT)
+#define APCI3120_WRITE_MODE_SELECT                0x0E	// (ADDRESS)
+#define APCI3120_SELECT_TIMER_0_WORD  0x00
+#define APCI3120_SELECT_TIMER_1_WORD  0x01
+#define APCI3120_TIMER_1_MODE_2       0x4
+
+//$$ BIT FOR MODE IN nCsTimerCtr1
+#define APCI3120_TIMER_2_MODE_0                   0x0
+#define APCI3120_TIMER_2_MODE_2                   0x10
+#define APCI3120_TIMER_2_MODE_5                   0x30
+
+//$$ BIT FOR MODE IN nCsTimerCtr0
+#define APCI3120_SELECT_TIMER_2_LOW_WORD          0x02
+#define APCI3120_SELECT_TIMER_2_HIGH_WORD         0x03
+
+#define APCI3120_TIMER_CRT0                       0x0D	//(ADDRESS for cCsTimerCtr0)
+#define APCI3120_TIMER_CRT1                       0x0C	//(ADDRESS for cCsTimerCtr1)
+
+#define APCI3120_TIMER_VALUE                      0x04	//ADDRESS for nCsTimerWert
+#define APCI3120_TIMER_STATUS_REGISTER            0x0D	//ADDRESS for delete timer 2 interrupt
+#define APCI3120_RD_STATUS                        0x02	//ADDRESS
+#define APCI3120_WR_ADDRESS                       0x00	//ADDRESS
+#define APCI3120_ENABLE_WATCHDOG                  0x20	//$$BIT in nWrMode_Select
+#define APCI3120_DISABLE_WATCHDOG                 (~APCI3120_ENABLE_WATCHDOG)
+#define APCI3120_ENABLE_TIMER_COUNTER    		  0x10	//$$BIT in nWrMode_Select
+#define APCI3120_DISABLE_TIMER_COUNTER            (~APCI3120_ENABLE_TIMER_COUNTER)
+#define APCI3120_FC_TIMER                         0x1000	//bit in  status register
+#define APCI3120_ENABLE_TIMER0                    0x1000
+#define APCI3120_ENABLE_TIMER1                    0x2000
+#define APCI3120_ENABLE_TIMER2                    0x4000
+#define APCI3120_DISABLE_TIMER0			          (~APCI3120_ENABLE_TIMER0)
+#define APCI3120_DISABLE_TIMER1		              (~APCI3120_ENABLE_TIMER1)
+#define APCI3120_DISABLE_TIMER2	                  (~APCI3120_ENABLE_TIMER2)
+
+#define APCI3120_TIMER2_SELECT_EOS                0xC0	// ADDED on 20-6
+#define APCI3120_COUNTER                          3	// on 20-6
+#define APCI3120_DISABLE_ALL_TIMER                ( APCI3120_DISABLE_TIMER0 & APCI3120_DISABLE_TIMER1 & APCI3120_DISABLE_TIMER2 )	// on 20-6
+
+#define MAX_ANALOGINPUT_CHANNELS    32
+
+typedef struct {
+	BYTE b_Type;		/* EOC or EOS */
+	BYTE b_InterruptFlag;	/* Interrupt use or not                    */
+	UINT ui_ConvertTiming;	/* Selection of the convertion time        */
+	BYTE b_NbrOfChannel;	/* Number of channel to read               */
+	UINT ui_ChannelList[MAX_ANALOGINPUT_CHANNELS];	/* Number of the channel to be read        */
+	UINT ui_RangeList[MAX_ANALOGINPUT_CHANNELS];	/* Gain of each channel                    */
+
+} str_AnalogReadInformation;
+
+// Function Declaration For APCI-3120
+
+// Internal functions
+int i_APCI3120_SetupChannelList(struct comedi_device *dev, struct comedi_subdevice *s,
+				int n_chan, unsigned int *chanlist, char check);
+int i_APCI3120_ExttrigEnable(struct comedi_device *dev);
+int i_APCI3120_ExttrigDisable(struct comedi_device *dev);
+int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s);
+int i_APCI3120_Reset(struct comedi_device *dev);
+int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev,
+				 struct comedi_subdevice *s);
+// Interrupt functions
+void v_APCI3120_Interrupt(int irq, void *d);
+//UPDATE-0.7.57->0.7.68 void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev,struct comedi_subdevice *s,short *dma,short *data,int n);
+void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev,
+					   struct comedi_subdevice *s,
+					   short *dma_buffer,
+					   unsigned int num_samples);
+int i_APCI3120_InterruptHandleEos(struct comedi_device *dev);
+void v_APCI3120_InterruptDma(int irq, void *d);
+
+// TIMER
+
+int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevice *s,
+			       struct comedi_insn *insn, unsigned int *data);
+int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice *s,
+			      struct comedi_insn *insn, unsigned int *data);
+int i_APCI3120_InsnReadTimer(struct comedi_device *dev, struct comedi_subdevice *s,
+			     struct comedi_insn *insn, unsigned int *data);
+
+//DI
+// for di read
+
+int i_APCI3120_InsnBitsDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+				    struct comedi_insn *insn, unsigned int *data);
+int i_APCI3120_InsnReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+				    struct comedi_insn *insn, unsigned int *data);
+
+//DO
+//int i_APCI3120_WriteDigitalOutput(struct comedi_device *dev, BYTE data);
+int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device *dev,
+				       struct comedi_subdevice *s, struct comedi_insn *insn,
+				       unsigned int *data);
+int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+				     struct comedi_insn *insn, unsigned int *data);
+int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+				      struct comedi_insn *insn, unsigned int *data);
+
+//AO
+//int i_APCI3120_Write1AnalogValue(struct comedi_device *dev,UINT ui_Range,UINT ui_Channel,UINT data );
+int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+				     struct comedi_insn *insn, unsigned int *data);
+
+//AI HArdware layer
+
+int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
+				     struct comedi_insn *insn, unsigned int *data);
+int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
+				   struct comedi_insn *insn, unsigned int *data);
+int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
+				      struct comedi_cmd *cmd);
+int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s);
+//int i_APCI3120_CancelAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s);
+int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
new file mode 100644
index 0000000..1ff66be
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
@@ -0,0 +1,3642 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+
+        ADDI-DATA GmbH
+        Dieselstrasse 3
+        D-77833 Ottersweier
+        Tel: +19(0)7223/9493-0
+        Fax: +49(0)7223/9493-92
+        http://www.addi-data-com
+        info@addi-data.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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+  +-----------------------------------------------------------------------+
+  | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
+  +-----------------------------------------------------------------------+
+  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
+  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
+  +-------------------------------+---------------------------------------+
+  | Project     : APCI-3200       | Compiler   : GCC                      |
+  | Module name : hwdrv_apci3200.c| Version    : 2.96                     |
+  +-------------------------------+---------------------------------------+
+  | Project manager: Eric Stolz   | Date       :  02/12/2002              |
+  +-------------------------------+---------------------------------------+
+  | Description :   Hardware Layer Acces For APCI-3200                    |
+  +-----------------------------------------------------------------------+
+  |                             UPDATES                                   |
+  +----------+-----------+------------------------------------------------+
+  |   Date   |   Author  |          Description of updates                |
+  +----------+-----------+------------------------------------------------+
+  | 02.07.04 | J. Krauth | Modification from the driver in order to       |
+  |          |           | correct some errors when using several boards. |
+  |          |           |                                                |
+  |          |           |                                                |
+  +----------+-----------+------------------------------------------------+
+  | 26.10.04 | J. Krauth | - Update for COMEDI 0.7.68                     |
+  |          |           | - Read eeprom value                            |
+  |          |           | - Append APCI-3300                             |
+  +----------+-----------+------------------------------------------------+
+*/
+
+/*
+  +----------------------------------------------------------------------------+
+  |                               Included files                               |
+  +----------------------------------------------------------------------------+
+*/
+#include "hwdrv_apci3200.h"
+//Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+#include "addi_amcc_S5920.h"
+//#define PRINT_INFO
+
+//End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+//BEGIN JK 06.07.04: Management of sevrals boards
+/*
+  INT i_CJCAvailable=1;
+  INT i_CJCPolarity=0;
+  INT i_CJCGain=2;//changed from 0 to 2
+  INT i_InterruptFlag=0;
+  INT i_ADDIDATAPolarity;
+  INT i_ADDIDATAGain;
+  INT i_AutoCalibration=0;   //: auto calibration
+  INT i_ADDIDATAConversionTime;
+  INT i_ADDIDATAConversionTimeUnit;
+  INT i_ADDIDATAType;
+  INT i_ChannelNo;
+  INT i_ChannelCount=0;
+  INT i_ScanType;
+  INT i_FirstChannel;
+  INT i_LastChannel;
+  INT i_Sum=0;
+  INT i_Offset;
+  UINT ui_Channel_num=0;
+  static int i_Count=0;
+  INT i_Initialised=0;
+  UINT ui_InterruptChannelValue[96]; //Buffer
+*/
+str_BoardInfos s_BoardInfos[100];	// 100 will be the max number of boards to be used
+//END JK 06.07.04: Management of sevrals boards
+
+//Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+/*+----------------------------------------------------------------------------+*/
+/*| Function   Name   : INT i_AddiHeaderRW_ReadEeprom                          |*/
+/*|                               (INT    i_NbOfWordsToRead,                   |*/
+/*|                                DWORD dw_PCIBoardEepromAddress,             |*/
+/*|                                WORD   w_EepromStartAddress,                |*/
+/*|                                PWORD pw_DataRead)                          |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Task              : Read word from the 5920 eeprom.                        |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Input Parameters  : INT    i_NbOfWordsToRead : Nbr. of word to read        |*/
+/*|                     DWORD dw_PCIBoardEepromAddress : Address of the eeprom |*/
+/*|                     WORD   w_EepromStartAddress : Eeprom strat address     |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Output Parameters : PWORD pw_DataRead : Read data                          |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Return Value      : -                                                      |*/
+/*+----------------------------------------------------------------------------+*/
+
+INT i_AddiHeaderRW_ReadEeprom(INT i_NbOfWordsToRead,
+	DWORD dw_PCIBoardEepromAddress,
+	WORD w_EepromStartAddress, PWORD pw_DataRead)
+{
+	DWORD dw_eeprom_busy = 0;
+	INT i_Counter = 0;
+	INT i_WordCounter;
+	INT i;
+	BYTE pb_ReadByte[1];
+	BYTE b_ReadLowByte = 0;
+	BYTE b_ReadHighByte = 0;
+	BYTE b_SelectedAddressLow = 0;
+	BYTE b_SelectedAddressHigh = 0;
+	WORD w_ReadWord = 0;
+
+	for (i_WordCounter = 0; i_WordCounter < i_NbOfWordsToRead;
+		i_WordCounter++) {
+		do {
+			dw_eeprom_busy =
+				inl(dw_PCIBoardEepromAddress +
+				AMCC_OP_REG_MCSR);
+			dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+		}
+		while (dw_eeprom_busy == EEPROM_BUSY);
+
+		for (i_Counter = 0; i_Counter < 2; i_Counter++) {
+			b_SelectedAddressLow = (w_EepromStartAddress + i_Counter) % 256;	//Read the low 8 bit part
+			b_SelectedAddressHigh = (w_EepromStartAddress + i_Counter) / 256;	//Read the high 8 bit part
+
+			//Select the load low address mode
+			outb(NVCMD_LOAD_LOW,
+				dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+				3);
+
+			//Wait on busy
+			do {
+				dw_eeprom_busy =
+					inl(dw_PCIBoardEepromAddress +
+					AMCC_OP_REG_MCSR);
+				dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+			}
+			while (dw_eeprom_busy == EEPROM_BUSY);
+
+			//Load the low address
+			outb(b_SelectedAddressLow,
+				dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+				2);
+
+			//Wait on busy
+			do {
+				dw_eeprom_busy =
+					inl(dw_PCIBoardEepromAddress +
+					AMCC_OP_REG_MCSR);
+				dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+			}
+			while (dw_eeprom_busy == EEPROM_BUSY);
+
+			//Select the load high address mode
+			outb(NVCMD_LOAD_HIGH,
+				dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+				3);
+
+			//Wait on busy
+			do {
+				dw_eeprom_busy =
+					inl(dw_PCIBoardEepromAddress +
+					AMCC_OP_REG_MCSR);
+				dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+			}
+			while (dw_eeprom_busy == EEPROM_BUSY);
+
+			//Load the high address
+			outb(b_SelectedAddressHigh,
+				dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+				2);
+
+			//Wait on busy
+			do {
+				dw_eeprom_busy =
+					inl(dw_PCIBoardEepromAddress +
+					AMCC_OP_REG_MCSR);
+				dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+			}
+			while (dw_eeprom_busy == EEPROM_BUSY);
+
+			//Select the READ mode
+			outb(NVCMD_BEGIN_READ,
+				dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+				3);
+
+			//Wait on busy
+			do {
+				dw_eeprom_busy =
+					inl(dw_PCIBoardEepromAddress +
+					AMCC_OP_REG_MCSR);
+				dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+			}
+			while (dw_eeprom_busy == EEPROM_BUSY);
+
+			//Read data into the EEPROM
+			*pb_ReadByte =
+				inb(dw_PCIBoardEepromAddress +
+				AMCC_OP_REG_MCSR + 2);
+
+			//Wait on busy
+			do {
+				dw_eeprom_busy =
+					inl(dw_PCIBoardEepromAddress +
+					AMCC_OP_REG_MCSR);
+				dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+			}
+			while (dw_eeprom_busy == EEPROM_BUSY);
+
+			//Select the upper address part
+			if (i_Counter == 0) {
+				b_ReadLowByte = pb_ReadByte[0];
+			} else {
+				b_ReadHighByte = pb_ReadByte[0];
+			}
+
+			//Sleep
+			for (i = 0; i < 10000; i++) ;
+
+		}
+		w_ReadWord =
+			(b_ReadLowByte | (((unsigned short)b_ReadHighByte) *
+				256));
+
+		pw_DataRead[i_WordCounter] = w_ReadWord;
+
+		w_EepromStartAddress += 2;	// to read the next word
+
+	}			// for (...) i_NbOfWordsToRead
+	return (0);
+}
+
+/*+----------------------------------------------------------------------------+*/
+/*| Function   Name   : void v_GetAPCI3200EepromCalibrationValue (void)        |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Task              : Read calibration value from the APCI-3200 eeprom.      |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Input Parameters  : -                                                      |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Output Parameters : -                                                      |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Return Value      : -                                                      |*/
+/*+----------------------------------------------------------------------------+*/
+
+void v_GetAPCI3200EepromCalibrationValue(DWORD dw_PCIBoardEepromAddress,
+	str_BoardInfos * BoardInformations)
+{
+	WORD w_AnalogInputMainHeaderAddress;
+	WORD w_AnalogInputComponentAddress;
+	WORD w_NumberOfModuls = 0;
+	WORD w_CurrentSources[2];
+	WORD w_ModulCounter = 0;
+	WORD w_FirstHeaderSize = 0;
+	WORD w_NumberOfInputs = 0;
+	WORD w_CJCFlag = 0;
+	WORD w_NumberOfGainValue = 0;
+	WORD w_SingleHeaderAddress = 0;
+	WORD w_SingleHeaderSize = 0;
+	WORD w_Input = 0;
+	WORD w_GainFactorAddress = 0;
+	WORD w_GainFactorValue[2];
+	WORD w_GainIndex = 0;
+	WORD w_GainValue = 0;
+
+  /*****************************************/
+  /** Get the Analog input header address **/
+  /*****************************************/
+	i_AddiHeaderRW_ReadEeprom(1,	//i_NbOfWordsToRead
+		dw_PCIBoardEepromAddress, 0x116,	//w_EepromStartAddress: Analog input header address
+		&w_AnalogInputMainHeaderAddress);
+
+  /*******************************************/
+  /** Compute the real analog input address **/
+  /*******************************************/
+	w_AnalogInputMainHeaderAddress = w_AnalogInputMainHeaderAddress + 0x100;
+
+  /******************************/
+  /** Get the number of moduls **/
+  /******************************/
+	i_AddiHeaderRW_ReadEeprom(1,	//i_NbOfWordsToRead
+		dw_PCIBoardEepromAddress, w_AnalogInputMainHeaderAddress + 0x02,	//w_EepromStartAddress: Number of conponment
+		&w_NumberOfModuls);
+
+	for (w_ModulCounter = 0; w_ModulCounter < w_NumberOfModuls;
+		w_ModulCounter++) {
+      /***********************************/
+      /** Compute the component address **/
+      /***********************************/
+		w_AnalogInputComponentAddress =
+			w_AnalogInputMainHeaderAddress +
+			(w_FirstHeaderSize * w_ModulCounter) + 0x04;
+
+      /****************************/
+      /** Read first header size **/
+      /****************************/
+		i_AddiHeaderRW_ReadEeprom(1,	//i_NbOfWordsToRead
+			dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress,	// Address of the first header
+			&w_FirstHeaderSize);
+
+		w_FirstHeaderSize = w_FirstHeaderSize >> 4;
+
+      /***************************/
+      /** Read number of inputs **/
+      /***************************/
+		i_AddiHeaderRW_ReadEeprom(1,	//i_NbOfWordsToRead
+			dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 0x06,	// Number of inputs for the first modul
+			&w_NumberOfInputs);
+
+		w_NumberOfInputs = w_NumberOfInputs >> 4;
+
+      /***********************/
+      /** Read the CJC flag **/
+      /***********************/
+		i_AddiHeaderRW_ReadEeprom(1,	//i_NbOfWordsToRead
+			dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 0x08,	// CJC flag
+			&w_CJCFlag);
+
+		w_CJCFlag = (w_CJCFlag >> 3) & 0x1;	// Get only the CJC flag
+
+      /*******************************/
+      /** Read number of gain value **/
+      /*******************************/
+		i_AddiHeaderRW_ReadEeprom(1,	//i_NbOfWordsToRead
+			dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 0x44,	// Number of gain value
+			&w_NumberOfGainValue);
+
+		w_NumberOfGainValue = w_NumberOfGainValue & 0xFF;
+
+      /***********************************/
+      /** Compute single header address **/
+      /***********************************/
+		w_SingleHeaderAddress =
+			w_AnalogInputComponentAddress + 0x46 +
+			(((w_NumberOfGainValue / 16) + 1) * 2) +
+			(6 * w_NumberOfGainValue) +
+			(4 * (((w_NumberOfGainValue / 16) + 1) * 2));
+
+      /********************************************/
+      /** Read current sources value for input 1 **/
+      /********************************************/
+		i_AddiHeaderRW_ReadEeprom(1,	//i_NbOfWordsToRead
+			dw_PCIBoardEepromAddress, w_SingleHeaderAddress,	//w_EepromStartAddress: Single header address
+			&w_SingleHeaderSize);
+
+		w_SingleHeaderSize = w_SingleHeaderSize >> 4;
+
+      /*************************************/
+      /** Read gain factor for the module **/
+      /*************************************/
+		w_GainFactorAddress = w_AnalogInputComponentAddress;
+
+		for (w_GainIndex = 0; w_GainIndex < w_NumberOfGainValue;
+			w_GainIndex++) {
+	  /************************************/
+	  /** Read gain value for the module **/
+	  /************************************/
+			i_AddiHeaderRW_ReadEeprom(1,	//i_NbOfWordsToRead
+				dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 70 + (2 * (1 + (w_NumberOfGainValue / 16))) + (0x02 * w_GainIndex),	// Gain value
+				&w_GainValue);
+
+			BoardInformations->s_Module[w_ModulCounter].
+				w_GainValue[w_GainIndex] = w_GainValue;
+
+#             ifdef PRINT_INFO
+			printk("\n Gain value = %d",
+				BoardInformations->s_Module[w_ModulCounter].
+				w_GainValue[w_GainIndex]);
+#             endif
+
+	  /*************************************/
+	  /** Read gain factor for the module **/
+	  /*************************************/
+			i_AddiHeaderRW_ReadEeprom(2,	//i_NbOfWordsToRead
+				dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 70 + ((2 * w_NumberOfGainValue) + (2 * (1 + (w_NumberOfGainValue / 16)))) + (0x04 * w_GainIndex),	// Gain factor
+				w_GainFactorValue);
+
+			BoardInformations->s_Module[w_ModulCounter].
+				ul_GainFactor[w_GainIndex] =
+				(w_GainFactorValue[1] << 16) +
+				w_GainFactorValue[0];
+
+#             ifdef PRINT_INFO
+			printk("\n w_GainFactorValue [%d] = %lu", w_GainIndex,
+				BoardInformations->s_Module[w_ModulCounter].
+				ul_GainFactor[w_GainIndex]);
+#             endif
+		}
+
+      /***************************************************************/
+      /** Read current source value for each channels of the module **/
+      /***************************************************************/
+		for (w_Input = 0; w_Input < w_NumberOfInputs; w_Input++) {
+	  /********************************************/
+	  /** Read current sources value for input 1 **/
+	  /********************************************/
+			i_AddiHeaderRW_ReadEeprom(2,	//i_NbOfWordsToRead
+				dw_PCIBoardEepromAddress,
+				(w_Input * w_SingleHeaderSize) +
+				w_SingleHeaderAddress + 0x0C, w_CurrentSources);
+
+	  /************************************/
+	  /** Save the current sources value **/
+	  /************************************/
+			BoardInformations->s_Module[w_ModulCounter].
+				ul_CurrentSource[w_Input] =
+				(w_CurrentSources[0] +
+				((w_CurrentSources[1] & 0xFFF) << 16));
+
+#             ifdef PRINT_INFO
+			printk("\n Current sources [%d] = %lu", w_Input,
+				BoardInformations->s_Module[w_ModulCounter].
+				ul_CurrentSource[w_Input]);
+#             endif
+		}
+
+      /***************************************/
+      /** Read the CJC current source value **/
+      /***************************************/
+		i_AddiHeaderRW_ReadEeprom(2,	//i_NbOfWordsToRead
+			dw_PCIBoardEepromAddress,
+			(w_Input * w_SingleHeaderSize) + w_SingleHeaderAddress +
+			0x0C, w_CurrentSources);
+
+      /************************************/
+      /** Save the current sources value **/
+      /************************************/
+		BoardInformations->s_Module[w_ModulCounter].
+			ul_CurrentSourceCJC =
+			(w_CurrentSources[0] +
+			((w_CurrentSources[1] & 0xFFF) << 16));
+
+#          ifdef PRINT_INFO
+		printk("\n Current sources CJC = %lu",
+			BoardInformations->s_Module[w_ModulCounter].
+			ul_CurrentSourceCJC);
+#          endif
+	}
+}
+
+INT i_APCI3200_GetChannelCalibrationValue(struct comedi_device * dev,
+	unsigned int ui_Channel_num, unsigned int * CJCCurrentSource,
+	unsigned int * ChannelCurrentSource, unsigned int * ChannelGainFactor)
+{
+	int i_DiffChannel = 0;
+	int i_Module = 0;
+
+#ifdef PRINT_INFO
+	printk("\n Channel = %u", ui_Channel_num);
+#endif
+
+	//Test if single or differential mode
+	if (s_BoardInfos[dev->minor].i_ConnectionType == 1) {
+		//if diff
+
+		if ((ui_Channel_num >= 0) && (ui_Channel_num <= 1))
+			i_DiffChannel = ui_Channel_num, i_Module = 0;
+		else if ((ui_Channel_num >= 2) && (ui_Channel_num <= 3))
+			i_DiffChannel = ui_Channel_num - 2, i_Module = 1;
+		else if ((ui_Channel_num >= 4) && (ui_Channel_num <= 5))
+			i_DiffChannel = ui_Channel_num - 4, i_Module = 2;
+		else if ((ui_Channel_num >= 6) && (ui_Channel_num <= 7))
+			i_DiffChannel = ui_Channel_num - 6, i_Module = 3;
+
+	} else {
+		// if single
+		if ((ui_Channel_num == 0) || (ui_Channel_num == 1))
+			i_DiffChannel = 0, i_Module = 0;
+		else if ((ui_Channel_num == 2) || (ui_Channel_num == 3))
+			i_DiffChannel = 1, i_Module = 0;
+		else if ((ui_Channel_num == 4) || (ui_Channel_num == 5))
+			i_DiffChannel = 0, i_Module = 1;
+		else if ((ui_Channel_num == 6) || (ui_Channel_num == 7))
+			i_DiffChannel = 1, i_Module = 1;
+		else if ((ui_Channel_num == 8) || (ui_Channel_num == 9))
+			i_DiffChannel = 0, i_Module = 2;
+		else if ((ui_Channel_num == 10) || (ui_Channel_num == 11))
+			i_DiffChannel = 1, i_Module = 2;
+		else if ((ui_Channel_num == 12) || (ui_Channel_num == 13))
+			i_DiffChannel = 0, i_Module = 3;
+		else if ((ui_Channel_num == 14) || (ui_Channel_num == 15))
+			i_DiffChannel = 1, i_Module = 3;
+	}
+
+	//Test if thermocouple or RTD mode
+	*CJCCurrentSource =
+		s_BoardInfos[dev->minor].s_Module[i_Module].ul_CurrentSourceCJC;
+#ifdef PRINT_INFO
+	printk("\n CJCCurrentSource = %lu", *CJCCurrentSource);
+#endif
+
+	*ChannelCurrentSource =
+		s_BoardInfos[dev->minor].s_Module[i_Module].
+		ul_CurrentSource[i_DiffChannel];
+#ifdef PRINT_INFO
+	printk("\n ChannelCurrentSource = %lu", *ChannelCurrentSource);
+#endif
+	//      }
+	//   }
+
+	//Channle gain factor
+	*ChannelGainFactor =
+		s_BoardInfos[dev->minor].s_Module[i_Module].
+		ul_GainFactor[s_BoardInfos[dev->minor].i_ADDIDATAGain];
+#ifdef PRINT_INFO
+	printk("\n ChannelGainFactor = %lu", *ChannelGainFactor);
+#endif
+	//End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+	return (0);
+}
+
+//End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+/*
+  +----------------------------------------------------------------------------+
+  | Function   Name   : int i_APCI3200_ReadDigitalInput                       |
+  |			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+  |                      struct comedi_insn *insn,unsigned int *data)                     |
+  +----------------------------------------------------------------------------+
+  | Task              : Read  value  of the selected channel or port           |
+  +----------------------------------------------------------------------------+
+  | Input Parameters  : struct comedi_device *dev      : Driver handle                |
+  |                     UINT ui_NoOfChannels    : No Of Channels To read  for Port
+  Channel Numberfor single channel
+  |                     UINT data[0]            : 0: Read single channel
+  1: Read port value
+  data[1]              Port number
+  +----------------------------------------------------------------------------+
+  | Output Parameters :	--	data[0] :Read status value
+  +----------------------------------------------------------------------------+
+  | Return Value      : TRUE  : No error occur                                 |
+  |		            : FALSE : Error occur. Return the error          |
+  |			                                                         |
+  +----------------------------------------------------------------------------+
+*/
+
+INT i_APCI3200_ReadDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_Temp = 0;
+	UINT ui_NoOfChannel = 0;
+	ui_NoOfChannel = CR_CHAN(insn->chanspec);
+	ui_Temp = data[0];
+	*data = inl(devpriv->i_IobaseReserved);
+
+	if (ui_Temp == 0) {
+		*data = (*data >> ui_NoOfChannel) & 0x1;
+	}			//if  (ui_Temp==0)
+	else {
+		if (ui_Temp == 1) {
+			if (data[1] < 0 || data[1] > 1) {
+				printk("\nThe port number is in error\n");
+				return -EINVAL;
+			}	//if(data[1] < 0 || data[1] >1)
+			switch (ui_NoOfChannel) {
+
+			case 2:
+				*data = (*data >> (2 * data[1])) & 0x3;
+				break;
+			case 3:
+				*data = (*data & 15);
+				break;
+			default:
+				comedi_error(dev, " chan spec wrong");
+				return -EINVAL;	// "sorry channel spec wrong "
+
+			}	//switch(ui_NoOfChannels)
+		}		//if  (ui_Temp==1)
+		else {
+			printk("\nSpecified channel not supported \n");
+		}		//elseif  (ui_Temp==1)
+	}
+	return insn->n;
+}
+
+/*
+  +----------------------------------------------------------------------------+
+  | Function   Name   : int i_APCI3200_ConfigDigitalOutput                     |
+  |			  (struct comedi_device *dev,struct comedi_subdevice *s,				 |
+  |                      struct comedi_insn *insn,unsigned int *data)                     |
+  +----------------------------------------------------------------------------+
+  | Task              : Configures The Digital Output Subdevice.               |
+  +----------------------------------------------------------------------------+
+  | Input Parameters  : struct comedi_device *dev : Driver handle                     |
+  |			  data[0]  :1  Memory enable
+  0  Memory Disable
+  +----------------------------------------------------------------------------+
+  | Output Parameters :	--													 |
+  +----------------------------------------------------------------------------+
+  | Return Value      : TRUE  : No error occur                                 |
+  |		            : FALSE : Error occur. Return the error			 |
+  |																	 |
+  +----------------------------------------------------------------------------+
+*/
+int i_APCI3200_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+
+	if ((data[0] != 0) && (data[0] != 1)) {
+		comedi_error(dev,
+			"Not a valid Data !!! ,Data should be 1 or 0\n");
+		return -EINVAL;
+	}			//if  ( (data[0]!=0) && (data[0]!=1) )
+	if (data[0]) {
+		devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
+	}			// if  (data[0])
+	else {
+		devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
+	}			//else if  (data[0])
+	return insn->n;
+}
+
+/*
+  +----------------------------------------------------------------------------+
+  | Function   Name   : int i_APCI3200_WriteDigitalOutput                      |
+  |			  (struct comedi_device *dev,struct comedi_subdevice *s,				 |
+  |                      struct comedi_insn *insn,unsigned int *data)                     |
+  +----------------------------------------------------------------------------+
+  | Task              : writes To the digital Output Subdevice                 |
+  +----------------------------------------------------------------------------+
+  | Input Parameters  : struct comedi_device *dev      : Driver handle                |
+  |                     struct comedi_subdevice *s     : Subdevice Pointer            |
+  |                     struct comedi_insn *insn       : Insn Structure Pointer       |
+  |                     unsigned int *data          : Data Pointer contains        |
+  |                                          configuration parameters as below |
+  |                     data[0]             :Value to output
+  data[1]             : 0 o/p single channel
+  1 o/p port
+  data[2]             : port no
+  data[3]             :0 set the digital o/p on
+  1 set the digital o/p off
+  +----------------------------------------------------------------------------+
+  | Output Parameters :	--													 |
+  +----------------------------------------------------------------------------+
+  | Return Value      : TRUE  : No error occur                                 |
+  |		            : FALSE : Error occur. Return the error	     	 |
+  |			                                                         |
+  +----------------------------------------------------------------------------+
+*/
+INT i_APCI3200_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_Temp = 0, ui_Temp1 = 0;
+	UINT ui_NoOfChannel = CR_CHAN(insn->chanspec);	// get the channel
+	if (devpriv->b_OutputMemoryStatus) {
+		ui_Temp = inl(devpriv->i_IobaseAddon);
+
+	}			//if(devpriv->b_OutputMemoryStatus )
+	else {
+		ui_Temp = 0;
+	}			//if(devpriv->b_OutputMemoryStatus )
+	if (data[3] == 0) {
+		if (data[1] == 0) {
+			data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
+			outl(data[0], devpriv->i_IobaseAddon);
+		}		//if(data[1]==0)
+		else {
+			if (data[1] == 1) {
+				switch (ui_NoOfChannel) {
+
+				case 2:
+					data[0] =
+						(data[0] << (2 *
+							data[2])) | ui_Temp;
+					break;
+				case 3:
+					data[0] = (data[0] | ui_Temp);
+					break;
+				}	//switch(ui_NoOfChannels)
+
+				outl(data[0], devpriv->i_IobaseAddon);
+			}	// if(data[1]==1)
+			else {
+				printk("\nSpecified channel not supported\n");
+			}	//else if(data[1]==1)
+		}		//elseif(data[1]==0)
+	}			//if(data[3]==0)
+	else {
+		if (data[3] == 1) {
+			if (data[1] == 0) {
+				data[0] = ~data[0] & 0x1;
+				ui_Temp1 = 1;
+				ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+				ui_Temp = ui_Temp | ui_Temp1;
+				data[0] = (data[0] << ui_NoOfChannel) ^ 0xf;
+				data[0] = data[0] & ui_Temp;
+				outl(data[0], devpriv->i_IobaseAddon);
+			}	//if(data[1]==0)
+			else {
+				if (data[1] == 1) {
+					switch (ui_NoOfChannel) {
+
+					case 2:
+						data[0] = ~data[0] & 0x3;
+						ui_Temp1 = 3;
+						ui_Temp1 =
+							ui_Temp1 << 2 * data[2];
+						ui_Temp = ui_Temp | ui_Temp1;
+						data[0] =
+							((data[0] << (2 *
+									data
+									[2])) ^
+							0xf) & ui_Temp;
+
+						break;
+					case 3:
+						break;
+
+					default:
+						comedi_error(dev,
+							" chan spec wrong");
+						return -EINVAL;	// "sorry channel spec wrong "
+					}	//switch(ui_NoOfChannels)
+
+					outl(data[0], devpriv->i_IobaseAddon);
+				}	// if(data[1]==1)
+				else {
+					printk("\nSpecified channel not supported\n");
+				}	//else if(data[1]==1)
+			}	//elseif(data[1]==0)
+		}		//if(data[3]==1);
+		else {
+			printk("\nSpecified functionality does not exist\n");
+			return -EINVAL;
+		}		//if else data[3]==1)
+	}			//if else data[3]==0)
+	return insn->n;
+}
+
+/*
+  +----------------------------------------------------------------------------+
+  | Function   Name   : int i_APCI3200_ReadDigitalOutput                       |
+  |			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+  |                      struct comedi_insn *insn,unsigned int *data)                     |
+  +----------------------------------------------------------------------------+
+  | Task              : Read  value  of the selected channel or port           |
+  +----------------------------------------------------------------------------+
+  | Input Parameters  : struct comedi_device *dev      : Driver handle                |
+  |                     UINT ui_NoOfChannels    : No Of Channels To read       |
+  |                     UINT *data              : Data Pointer to read status  |
+  data[0]                 :0 read single channel
+  1 read port value
+  data[1]                  port no
+
+  +----------------------------------------------------------------------------+
+  | Output Parameters :	--													 |
+  +----------------------------------------------------------------------------+
+  | Return Value      : TRUE  : No error occur                                 |
+  |		            : FALSE : Error occur. Return the error          |
+  |			                                                         |
+  +----------------------------------------------------------------------------+
+*/
+INT i_APCI3200_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_Temp;
+	UINT ui_NoOfChannel;
+	ui_NoOfChannel = CR_CHAN(insn->chanspec);
+	ui_Temp = data[0];
+	*data = inl(devpriv->i_IobaseAddon);
+	if (ui_Temp == 0) {
+		*data = (*data >> ui_NoOfChannel) & 0x1;
+	}			// if  (ui_Temp==0)
+	else {
+		if (ui_Temp == 1) {
+			if (data[1] < 0 || data[1] > 1) {
+				printk("\nThe port selection is in error\n");
+				return -EINVAL;
+			}	//if(data[1] <0 ||data[1] >1)
+			switch (ui_NoOfChannel) {
+			case 2:
+				*data = (*data >> (2 * data[1])) & 3;
+				break;
+
+			case 3:
+				break;
+
+			default:
+				comedi_error(dev, " chan spec wrong");
+				return -EINVAL;	// "sorry channel spec wrong "
+				break;
+			}	// switch(ui_NoOfChannels)
+		}		// if  (ui_Temp==1)
+		else {
+			printk("\nSpecified channel not supported \n");
+		}		// else if (ui_Temp==1)
+	}			// else if  (ui_Temp==0)
+	return insn->n;
+}
+
+/*
+  +----------------------------------------------------------------------------+
+  | Function   Name   : INT i_APCI3200_ConfigAnalogInput                       |
+  |			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+  |                      struct comedi_insn *insn,unsigned int *data)                     |
+  +----------------------------------------------------------------------------+
+  | Task              : Configures The Analog Input Subdevice                  |
+  +----------------------------------------------------------------------------+
+  | Input Parameters  : struct comedi_device *dev      : Driver handle                |
+  |                     struct comedi_subdevice *s     : Subdevice Pointer            |
+  |                     struct comedi_insn *insn       : Insn Structure Pointer       |
+  |                     unsigned int *data          : Data Pointer contains        |
+  |                                          configuration parameters as below |
+  |                                                                            |
+  |					data[0]
+  |                                               0:Normal AI                  |
+  |                                               1:RTD                        |
+  |                                               2:THERMOCOUPLE               |
+  |				    data[1]            : Gain To Use                 |
+  |                                                                            |
+  |                           data[2]            : Polarity
+  |                                                0:Bipolar                   |
+  |                                                1:Unipolar                  |
+  |															    	 |
+  |                           data[3]            : Offset Range
+  |                                                                            |
+  |                           data[4]            : Coupling
+  |                                                0:DC Coupling               |
+  |                                                1:AC Coupling               |
+  |                                                                            |
+  |                           data[5]            :Differential/Single
+  |                                                0:Single                    |
+  |                                                1:Differential              |
+  |                                                                            |
+  |                           data[6]            :TimerReloadValue
+  |                                                                            |
+  |                           data[7]            :ConvertingTimeUnit
+  |                                                                            |
+  |                           data[8]             :0 Analog voltage measurement
+  1 Resistance measurement
+  2 Temperature measurement
+  |                           data[9]            :Interrupt
+  |                                              0:Disable
+  |                                              1:Enable
+  data[10]           :Type of Thermocouple
+  |                          data[11]           : 0: single channel
+  Module Number
+  |
+  |                          data[12]
+  |                                             0:Single Read
+  |                                             1:Read more channel
+  2:Single scan
+  |                                             3:Continous Scan
+  data[13]          :Number of channels to read
+  |                          data[14]          :RTD connection type
+  :0:RTD not used
+  1:RTD 2 wire connection
+  2:RTD 3 wire connection
+  3:RTD 4 wire connection
+  |                                                                            |
+  |                                                                            |
+  |                                                                            |
+  +----------------------------------------------------------------------------+
+  | Output Parameters :	--													 |
+  +----------------------------------------------------------------------------+
+  | Return Value      : TRUE  : No error occur                                 |
+  |		            : FALSE : Error occur. Return the error          |
+  |			                                                         |
+  +----------------------------------------------------------------------------+
+*/
+INT i_APCI3200_ConfigAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+
+	UINT ul_Config = 0, ul_Temp = 0;
+	UINT ui_ChannelNo = 0;
+	UINT ui_Dummy = 0;
+	INT i_err = 0;
+
+	//Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+#ifdef PRINT_INFO
+	INT i = 0, i2 = 0;
+#endif
+	//End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+	//BEGIN JK 06.07.04: Management of sevrals boards
+	// Initialize the structure
+	if (s_BoardInfos[dev->minor].b_StructInitialized != 1) {
+		s_BoardInfos[dev->minor].i_CJCAvailable = 1;
+		s_BoardInfos[dev->minor].i_CJCPolarity = 0;
+		s_BoardInfos[dev->minor].i_CJCGain = 2;	//changed from 0 to 2
+		s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+		s_BoardInfos[dev->minor].i_AutoCalibration = 0;	//: auto calibration
+		s_BoardInfos[dev->minor].i_ChannelCount = 0;
+		s_BoardInfos[dev->minor].i_Sum = 0;
+		s_BoardInfos[dev->minor].ui_Channel_num = 0;
+		s_BoardInfos[dev->minor].i_Count = 0;
+		s_BoardInfos[dev->minor].i_Initialised = 0;
+		s_BoardInfos[dev->minor].b_StructInitialized = 1;
+
+		//Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+		s_BoardInfos[dev->minor].i_ConnectionType = 0;
+		//End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+		//Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+		memset(s_BoardInfos[dev->minor].s_Module, 0,
+			sizeof(s_BoardInfos[dev->minor].s_Module[MAX_MODULE]));
+
+		v_GetAPCI3200EepromCalibrationValue(devpriv->i_IobaseAmcc,
+			&s_BoardInfos[dev->minor]);
+
+#ifdef PRINT_INFO
+		for (i = 0; i < MAX_MODULE; i++) {
+			printk("\n s_Module[%i].ul_CurrentSourceCJC = %lu", i,
+				s_BoardInfos[dev->minor].s_Module[i].
+				ul_CurrentSourceCJC);
+
+			for (i2 = 0; i2 < 5; i2++) {
+				printk("\n s_Module[%i].ul_CurrentSource [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_CurrentSource[i2]);
+			}
+
+			for (i2 = 0; i2 < 8; i2++) {
+				printk("\n s_Module[%i].ul_GainFactor [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_GainFactor[i2]);
+			}
+
+			for (i2 = 0; i2 < 8; i2++) {
+				printk("\n s_Module[%i].w_GainValue [%i] = %u",
+					i, i2,
+					s_BoardInfos[dev->minor].s_Module[i].
+					w_GainValue[i2]);
+			}
+		}
+#endif
+		//End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+	}
+
+	if (data[0] != 0 && data[0] != 1 && data[0] != 2) {
+		printk("\nThe selection of acquisition type is in error\n");
+		i_err++;
+	}			//if(data[0]!=0 && data[0]!=1 && data[0]!=2)
+	if (data[0] == 1) {
+		if (data[14] != 0 && data[14] != 1 && data[14] != 2
+			&& data[14] != 4) {
+			printk("\n Error in selection of RTD connection type\n");
+			i_err++;
+		}		//if(data[14]!=0 && data[14]!=1 && data[14]!=2 && data[14]!=4)
+	}			//if(data[0]==1 )
+	if (data[1] < 0 || data[1] > 7) {
+		printk("\nThe selection of gain is in error\n");
+		i_err++;
+	}			// if(data[1]<0 || data[1]>7)
+	if (data[2] != 0 && data[2] != 1) {
+		printk("\nThe selection of polarity is in error\n");
+		i_err++;
+	}			//if(data[2]!=0 &&  data[2]!=1)
+	if (data[3] != 0) {
+		printk("\nThe selection of offset range  is in error\n");
+		i_err++;
+	}			// if(data[3]!=0)
+	if (data[4] != 0 && data[4] != 1) {
+		printk("\nThe selection of coupling is in error\n");
+		i_err++;
+	}			//if(data[4]!=0 &&  data[4]!=1)
+	if (data[5] != 0 && data[5] != 1) {
+		printk("\nThe selection of single/differential mode is in error\n");
+		i_err++;
+	}			//if(data[5]!=0 &&  data[5]!=1)
+	if (data[8] != 0 && data[8] != 1 && data[2] != 2) {
+		printk("\nError in selection of functionality\n");
+	}			//if(data[8]!=0 && data[8]!=1 && data[2]!=2)
+	if (data[12] == 0 || data[12] == 1) {
+		if (data[6] != 20 && data[6] != 40 && data[6] != 80
+			&& data[6] != 160) {
+			printk("\nThe selection of conversion time reload value is in error\n");
+			i_err++;
+		}		// if (data[6]!=20 && data[6]!=40 && data[6]!=80 && data[6]!=160 )
+		if (data[7] != 2) {
+			printk("\nThe selection of conversion time unit  is in error\n");
+			i_err++;
+		}		// if(data[7]!=2)
+	}
+	if (data[9] != 0 && data[9] != 1) {
+		printk("\nThe selection of interrupt enable is in error\n");
+		i_err++;
+	}			//if(data[9]!=0 &&  data[9]!=1)
+	if (data[11] < 0 || data[11] > 4) {
+		printk("\nThe selection of module is in error\n");
+		i_err++;
+	}			//if(data[11] <0 ||  data[11]>1)
+	if (data[12] < 0 || data[12] > 3) {
+		printk("\nThe selection of singlechannel/scan selection is in error\n");
+		i_err++;
+	}			//if(data[12] < 0 ||  data[12]> 3)
+	if (data[13] < 0 || data[13] > 16) {
+		printk("\nThe selection of number of channels is in error\n");
+		i_err++;
+	}			// if(data[13] <0 ||data[13] >15)
+
+	//BEGIN JK 06.07.04: Management of sevrals boards
+	/*
+	   i_ChannelCount=data[13];
+	   i_ScanType=data[12];
+	   i_ADDIDATAPolarity = data[2];
+	   i_ADDIDATAGain=data[1];
+	   i_ADDIDATAConversionTime=data[6];
+	   i_ADDIDATAConversionTimeUnit=data[7];
+	   i_ADDIDATAType=data[0];
+	 */
+
+	// Save acquisition configuration for the actual board
+	s_BoardInfos[dev->minor].i_ChannelCount = data[13];
+	s_BoardInfos[dev->minor].i_ScanType = data[12];
+	s_BoardInfos[dev->minor].i_ADDIDATAPolarity = data[2];
+	s_BoardInfos[dev->minor].i_ADDIDATAGain = data[1];
+	s_BoardInfos[dev->minor].i_ADDIDATAConversionTime = data[6];
+	s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit = data[7];
+	s_BoardInfos[dev->minor].i_ADDIDATAType = data[0];
+	//Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+	s_BoardInfos[dev->minor].i_ConnectionType = data[5];
+	//End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+	//END JK 06.07.04: Management of sevrals boards
+
+	//Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+	memset(s_BoardInfos[dev->minor].ui_ScanValueArray, 0, (7 + 12) * sizeof(unsigned int));	// 7 is the maximal number of channels
+	//End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+
+	//BEGIN JK 02.07.04 : This while can't be do, it block the process when using severals boards
+	//while(i_InterruptFlag==1)
+	while (s_BoardInfos[dev->minor].i_InterruptFlag == 1) {
+#ifndef MSXBOX
+		udelay(1);
+#else
+		// In the case where the driver is compiled for the MSX-Box
+		// we used a printk to have a little delay because udelay
+		// seems to be broken under the MSX-Box.
+		// This solution hat to be studied.
+		printk("");
+#endif
+	}
+	//END JK 02.07.04 : This while can't be do, it block the process when using severals boards
+
+	ui_ChannelNo = CR_CHAN(insn->chanspec);	// get the channel
+	//BEGIN JK 06.07.04: Management of sevrals boards
+	//i_ChannelNo=ui_ChannelNo;
+	//ui_Channel_num =ui_ChannelNo;
+
+	s_BoardInfos[dev->minor].i_ChannelNo = ui_ChannelNo;
+	s_BoardInfos[dev->minor].ui_Channel_num = ui_ChannelNo;
+
+	//END JK 06.07.04: Management of sevrals boards
+
+	if (data[5] == 0) {
+		if (ui_ChannelNo < 0 || ui_ChannelNo > 15) {
+			printk("\nThe Selection of the channel is in error\n");
+			i_err++;
+		}		// if(ui_ChannelNo<0 || ui_ChannelNo>15)
+	}			//if(data[5]==0)
+	else {
+		if (data[14] == 2) {
+			if (ui_ChannelNo < 0 || ui_ChannelNo > 3) {
+				printk("\nThe Selection of the channel is in error\n");
+				i_err++;
+			}	// if(ui_ChannelNo<0 || ui_ChannelNo>3)
+		}		//if(data[14]==2)
+		else {
+			if (ui_ChannelNo < 0 || ui_ChannelNo > 7) {
+				printk("\nThe Selection of the channel is in error\n");
+				i_err++;
+			}	// if(ui_ChannelNo<0 || ui_ChannelNo>7)
+		}		//elseif(data[14]==2)
+	}			//elseif(data[5]==0)
+	if (data[12] == 0 || data[12] == 1) {
+		switch (data[5]) {
+		case 0:
+			if (ui_ChannelNo >= 0 && ui_ChannelNo <= 3) {
+				//BEGIN JK 06.07.04: Management of sevrals boards
+				//i_Offset=0;
+				s_BoardInfos[dev->minor].i_Offset = 0;
+				//END JK 06.07.04: Management of sevrals boards
+			}	//if(ui_ChannelNo >=0 && ui_ChannelNo <=3)
+			if (ui_ChannelNo >= 4 && ui_ChannelNo <= 7) {
+				//BEGIN JK 06.07.04: Management of sevrals boards
+				//i_Offset=64;
+				s_BoardInfos[dev->minor].i_Offset = 64;
+				//END JK 06.07.04: Management of sevrals boards
+			}	//if(ui_ChannelNo >=4 && ui_ChannelNo <=7)
+			if (ui_ChannelNo >= 8 && ui_ChannelNo <= 11) {
+				//BEGIN JK 06.07.04: Management of sevrals boards
+				//i_Offset=128;
+				s_BoardInfos[dev->minor].i_Offset = 128;
+				//END JK 06.07.04: Management of sevrals boards
+			}	//if(ui_ChannelNo >=8 && ui_ChannelNo <=11)
+			if (ui_ChannelNo >= 12 && ui_ChannelNo <= 15) {
+				//BEGIN JK 06.07.04: Management of sevrals boards
+				//i_Offset=192;
+				s_BoardInfos[dev->minor].i_Offset = 192;
+				//END JK 06.07.04: Management of sevrals boards
+			}	//if(ui_ChannelNo >=12 && ui_ChannelNo <=15)
+			break;
+		case 1:
+			if (data[14] == 2) {
+				if (ui_ChannelNo == 0) {
+					//BEGIN JK 06.07.04: Management of sevrals boards
+					//i_Offset=0;
+					s_BoardInfos[dev->minor].i_Offset = 0;
+					//END JK 06.07.04: Management of sevrals boards
+				}	//if(ui_ChannelNo ==0 )
+				if (ui_ChannelNo == 1) {
+					//BEGIN JK 06.07.04: Management of sevrals boards
+					//i_Offset=0;
+					s_BoardInfos[dev->minor].i_Offset = 64;
+					//END JK 06.07.04: Management of sevrals boards
+				}	// if(ui_ChannelNo ==1)
+				if (ui_ChannelNo == 2) {
+					//BEGIN JK 06.07.04: Management of sevrals boards
+					//i_Offset=128;
+					s_BoardInfos[dev->minor].i_Offset = 128;
+					//END JK 06.07.04: Management of sevrals boards
+				}	//if(ui_ChannelNo ==2 )
+				if (ui_ChannelNo == 3) {
+					//BEGIN JK 06.07.04: Management of sevrals boards
+					//i_Offset=192;
+					s_BoardInfos[dev->minor].i_Offset = 192;
+					//END JK 06.07.04: Management of sevrals boards
+				}	//if(ui_ChannelNo ==3)
+
+				//BEGIN JK 06.07.04: Management of sevrals boards
+				//i_ChannelNo=0;
+				s_BoardInfos[dev->minor].i_ChannelNo = 0;
+				//END JK 06.07.04: Management of sevrals boards
+				ui_ChannelNo = 0;
+				break;
+			}	//if(data[14]==2)
+			if (ui_ChannelNo >= 0 && ui_ChannelNo <= 1) {
+				//BEGIN JK 06.07.04: Management of sevrals boards
+				//i_Offset=0;
+				s_BoardInfos[dev->minor].i_Offset = 0;
+				//END JK 06.07.04: Management of sevrals boards
+			}	//if(ui_ChannelNo >=0 && ui_ChannelNo <=1)
+			if (ui_ChannelNo >= 2 && ui_ChannelNo <= 3) {
+				//BEGIN JK 06.07.04: Management of sevrals boards
+				//i_ChannelNo=i_ChannelNo-2;
+				//i_Offset=64;
+				s_BoardInfos[dev->minor].i_ChannelNo =
+					s_BoardInfos[dev->minor].i_ChannelNo -
+					2;
+				s_BoardInfos[dev->minor].i_Offset = 64;
+				//END JK 06.07.04: Management of sevrals boards
+				ui_ChannelNo = ui_ChannelNo - 2;
+			}	//if(ui_ChannelNo >=2 && ui_ChannelNo <=3)
+			if (ui_ChannelNo >= 4 && ui_ChannelNo <= 5) {
+				//BEGIN JK 06.07.04: Management of sevrals boards
+				//i_ChannelNo=i_ChannelNo-4;
+				//i_Offset=128;
+				s_BoardInfos[dev->minor].i_ChannelNo =
+					s_BoardInfos[dev->minor].i_ChannelNo -
+					4;
+				s_BoardInfos[dev->minor].i_Offset = 128;
+				//END JK 06.07.04: Management of sevrals boards
+				ui_ChannelNo = ui_ChannelNo - 4;
+			}	//if(ui_ChannelNo >=4 && ui_ChannelNo <=5)
+			if (ui_ChannelNo >= 6 && ui_ChannelNo <= 7) {
+				//BEGIN JK 06.07.04: Management of sevrals boards
+				//i_ChannelNo=i_ChannelNo-6;
+				//i_Offset=192;
+				s_BoardInfos[dev->minor].i_ChannelNo =
+					s_BoardInfos[dev->minor].i_ChannelNo -
+					6;
+				s_BoardInfos[dev->minor].i_Offset = 192;
+				//END JK 06.07.04: Management of sevrals boards
+				ui_ChannelNo = ui_ChannelNo - 6;
+			}	//if(ui_ChannelNo >=6 && ui_ChannelNo <=7)
+			break;
+
+		default:
+			printk("\n This selection of polarity does not exist\n");
+			i_err++;
+		}		//switch(data[2])
+	}			//if(data[12]==0 || data[12]==1)
+	else {
+		switch (data[11]) {
+		case 1:
+			//BEGIN JK 06.07.04: Management of sevrals boards
+			//i_Offset=0;
+			s_BoardInfos[dev->minor].i_Offset = 0;
+			//END JK 06.07.04: Management of sevrals boards
+			break;
+		case 2:
+			//BEGIN JK 06.07.04: Management of sevrals boards
+			//i_Offset=64;
+			s_BoardInfos[dev->minor].i_Offset = 64;
+			//END JK 06.07.04: Management of sevrals boards
+			break;
+		case 3:
+			//BEGIN JK 06.07.04: Management of sevrals boards
+			//i_Offset=128;
+			s_BoardInfos[dev->minor].i_Offset = 128;
+			//END JK 06.07.04: Management of sevrals boards
+			break;
+		case 4:
+			//BEGIN JK 06.07.04: Management of sevrals boards
+			//i_Offset=192;
+			s_BoardInfos[dev->minor].i_Offset = 192;
+			//END JK 06.07.04: Management of sevrals boards
+			break;
+		default:
+			printk("\nError in module selection\n");
+			i_err++;
+		}		// switch(data[11])
+	}			// elseif(data[12]==0 || data[12]==1)
+	if (i_err) {
+		i_APCI3200_Reset(dev);
+		return -EINVAL;
+	}
+	//if(i_ScanType!=1)
+	if (s_BoardInfos[dev->minor].i_ScanType != 1) {
+		//BEGIN JK 06.07.04: Management of sevrals boards
+		//i_Count=0;
+		//i_Sum=0;
+		s_BoardInfos[dev->minor].i_Count = 0;
+		s_BoardInfos[dev->minor].i_Sum = 0;
+		//END JK 06.07.04: Management of sevrals boards
+	}			//if(i_ScanType!=1)
+
+	ul_Config =
+		data[1] | (data[2] << 6) | (data[5] << 7) | (data[3] << 8) |
+		(data[4] << 9);
+	//BEGIN JK 06.07.04: Management of sevrals boards
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//END JK 06.07.04: Management of sevrals boards
+  /*********************************/
+	/* Write the channel to configure */
+  /*********************************/
+	//BEGIN JK 06.07.04: Management of sevrals boards
+	//outl(0 | ui_ChannelNo , devpriv->iobase+i_Offset + 0x4);
+	outl(0 | ui_ChannelNo,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x4);
+	//END JK 06.07.04: Management of sevrals boards
+
+	//BEGIN JK 06.07.04: Management of sevrals boards
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//END JK 06.07.04: Management of sevrals boards
+  /**************************/
+	/* Reset the configuration */
+  /**************************/
+	//BEGIN JK 06.07.04: Management of sevrals boards
+	//outl(0 , devpriv->iobase+i_Offset + 0x0);
+	outl(0, devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0);
+	//END JK 06.07.04: Management of sevrals boards
+
+	//BEGIN JK 06.07.04: Management of sevrals boards
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//END JK 06.07.04: Management of sevrals boards
+
+  /***************************/
+	/* Write the configuration */
+  /***************************/
+	//BEGIN JK 06.07.04: Management of sevrals boards
+	//outl(ul_Config , devpriv->iobase+i_Offset + 0x0);
+	outl(ul_Config,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0);
+	//END JK 06.07.04: Management of sevrals boards
+
+  /***************************/
+	/*Reset the calibration bit */
+  /***************************/
+	//BEGIN JK 06.07.04: Management of sevrals boards
+	//ul_Temp = inl(devpriv->iobase+i_Offset + 12);
+	ul_Temp = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+	//END JK 06.07.04: Management of sevrals boards
+
+	//BEGIN JK 06.07.04: Management of sevrals boards
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//END JK 06.07.04: Management of sevrals boards
+
+	//BEGIN JK 06.07.04: Management of sevrals boards
+	//outl((ul_Temp & 0xFFF9FFFF) , devpriv->iobase+.i_Offset + 12);
+	outl((ul_Temp & 0xFFF9FFFF),
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+	//END JK 06.07.04: Management of sevrals boards
+
+	if (data[9] == 1) {
+		devpriv->tsk_Current = current;
+		//BEGIN JK 06.07.04: Management of sevrals boards
+		//i_InterruptFlag=1;
+		s_BoardInfos[dev->minor].i_InterruptFlag = 1;
+		//END JK 06.07.04: Management of sevrals boards
+	}			// if(data[9]==1)
+	else {
+		//BEGIN JK 06.07.04: Management of sevrals boards
+		//i_InterruptFlag=0;
+		s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+		//END JK 06.07.04: Management of sevrals boards
+	}			//else  if(data[9]==1)
+
+	//BEGIN JK 06.07.04: Management of sevrals boards
+	//i_Initialised=1;
+	s_BoardInfos[dev->minor].i_Initialised = 1;
+	//END JK 06.07.04: Management of sevrals boards
+
+	//BEGIN JK 06.07.04: Management of sevrals boards
+	//if(i_ScanType==1)
+	if (s_BoardInfos[dev->minor].i_ScanType == 1)
+		//END JK 06.07.04: Management of sevrals boards
+	{
+		//BEGIN JK 06.07.04: Management of sevrals boards
+		//i_Sum=i_Sum+1;
+		s_BoardInfos[dev->minor].i_Sum =
+			s_BoardInfos[dev->minor].i_Sum + 1;
+		//END JK 06.07.04: Management of sevrals boards
+
+		insn->unused[0] = 0;
+		i_APCI3200_ReadAnalogInput(dev, s, insn, &ui_Dummy);
+	}
+
+	return insn->n;
+}
+
+/*
+  +----------------------------------------------------------------------------+
+  | Function   Name   : int i_APCI3200_ReadAnalogInput                         |
+  |			          (struct comedi_device *dev,struct comedi_subdevice *s,       |
+  |                     struct comedi_insn *insn,unsigned int *data)                      |
+  +----------------------------------------------------------------------------+
+  | Task              : Read  value  of the selected channel			         |
+  +----------------------------------------------------------------------------+
+  | Input Parameters  : struct comedi_device *dev      : Driver handle                |
+  |                     UINT ui_NoOfChannels    : No Of Channels To read       |
+  |                     UINT *data              : Data Pointer to read status  |
+  +----------------------------------------------------------------------------+
+  | Output Parameters :	--													 |
+  |				data[0]  : Digital Value Of Input             |
+  |				data[1]  : Calibration Offset Value           |
+  |				data[2]  : Calibration Gain Value
+  |				data[3]  : CJC value
+  |				data[4]  : CJC offset value
+  |				data[5]  : CJC gain value
+  | Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+  |				data[6] : CJC current source from eeprom
+  |				data[7] : Channel current source from eeprom
+  |				data[8] : Channle gain factor from eeprom
+  | End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+  +----------------------------------------------------------------------------+
+  | Return Value      : TRUE  : No error occur                                 |
+  |		            : FALSE : Error occur. Return the error          |
+  |			                                                         |
+  +----------------------------------------------------------------------------+
+*/
+INT i_APCI3200_ReadAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_DummyValue = 0;
+	int i_ConvertCJCCalibration;
+	int i = 0;
+
+	//BEGIN JK 06.07.04: Management of sevrals boards
+	//if(i_Initialised==0)
+	if (s_BoardInfos[dev->minor].i_Initialised == 0)
+		//END JK 06.07.04: Management of sevrals boards
+	{
+		i_APCI3200_Reset(dev);
+		return -EINVAL;
+	}			//if(i_Initialised==0);
+
+#ifdef PRINT_INFO
+	printk("\n insn->unused[0] = %i", insn->unused[0]);
+#endif
+
+	switch (insn->unused[0]) {
+	case 0:
+
+		i_APCI3200_Read1AnalogInputChannel(dev, s, insn,
+			&ui_DummyValue);
+		//BEGIN JK 06.07.04: Management of sevrals boards
+		//ui_InterruptChannelValue[i_Count+0]=ui_DummyValue;
+		s_BoardInfos[dev->minor].
+			ui_InterruptChannelValue[s_BoardInfos[dev->minor].
+			i_Count + 0] = ui_DummyValue;
+		//END JK 06.07.04: Management of sevrals boards
+
+		//Begin JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+		i_APCI3200_GetChannelCalibrationValue(dev,
+			s_BoardInfos[dev->minor].ui_Channel_num,
+			&s_BoardInfos[dev->minor].
+			ui_InterruptChannelValue[s_BoardInfos[dev->minor].
+				i_Count + 6],
+			&s_BoardInfos[dev->minor].
+			ui_InterruptChannelValue[s_BoardInfos[dev->minor].
+				i_Count + 7],
+			&s_BoardInfos[dev->minor].
+			ui_InterruptChannelValue[s_BoardInfos[dev->minor].
+				i_Count + 8]);
+
+#ifdef PRINT_INFO
+		printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+6] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 6]);
+
+		printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+7] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 7]);
+
+		printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+8] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 8]);
+#endif
+
+		//End JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+		//BEGIN JK 06.07.04: Management of sevrals boards
+		//if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1))
+		if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2)
+			&& (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE)
+			&& (s_BoardInfos[dev->minor].i_CJCAvailable == 1))
+			//END JK 06.07.04: Management of sevrals boards
+		{
+			i_APCI3200_ReadCJCValue(dev, &ui_DummyValue);
+			//BEGIN JK 06.07.04: Management of sevrals boards
+			//ui_InterruptChannelValue[i_Count + 3]=ui_DummyValue;
+			s_BoardInfos[dev->minor].
+				ui_InterruptChannelValue[s_BoardInfos[dev->
+					minor].i_Count + 3] = ui_DummyValue;
+			//END JK 06.07.04: Management of sevrals boards
+		}		//if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE))
+		else {
+			//BEGIN JK 06.07.04: Management of sevrals boards
+			//ui_InterruptChannelValue[i_Count + 3]=0;
+			s_BoardInfos[dev->minor].
+				ui_InterruptChannelValue[s_BoardInfos[dev->
+					minor].i_Count + 3] = 0;
+			//END JK 06.07.04: Management of sevrals boards
+		}		//elseif((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1))
+
+		//BEGIN JK 06.07.04: Management of sevrals boards
+		//if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE))
+		if ((s_BoardInfos[dev->minor].i_AutoCalibration == FALSE)
+			&& (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE))
+			//END JK 06.07.04: Management of sevrals boards
+		{
+			i_APCI3200_ReadCalibrationOffsetValue(dev,
+				&ui_DummyValue);
+			//BEGIN JK 06.07.04: Management of sevrals boards
+			//ui_InterruptChannelValue[i_Count + 1]=ui_DummyValue;
+			s_BoardInfos[dev->minor].
+				ui_InterruptChannelValue[s_BoardInfos[dev->
+					minor].i_Count + 1] = ui_DummyValue;
+			//END JK 06.07.04: Management of sevrals boards
+			i_APCI3200_ReadCalibrationGainValue(dev,
+				&ui_DummyValue);
+			//BEGIN JK 06.07.04: Management of sevrals boards
+			//ui_InterruptChannelValue[i_Count + 2]=ui_DummyValue;
+			s_BoardInfos[dev->minor].
+				ui_InterruptChannelValue[s_BoardInfos[dev->
+					minor].i_Count + 2] = ui_DummyValue;
+			//END JK 06.07.04: Management of sevrals boards
+		}		//if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE))
+
+		//BEGIN JK 06.07.04: Management of sevrals boards
+		//if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)&& (i_CJCAvailable==1))
+		if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2)
+			&& (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE)
+			&& (s_BoardInfos[dev->minor].i_CJCAvailable == 1))
+			//END JK 06.07.04: Management of sevrals boards
+		{
+	  /**********************************************************/
+			/*Test if the Calibration channel must be read for the CJC */
+	  /**********************************************************/
+	  /**********************************/
+			/*Test if the polarity is the same */
+	  /**********************************/
+			//BEGIN JK 06.07.04: Management of sevrals boards
+			//if(i_CJCPolarity!=i_ADDIDATAPolarity)
+			if (s_BoardInfos[dev->minor].i_CJCPolarity !=
+				s_BoardInfos[dev->minor].i_ADDIDATAPolarity)
+				//END JK 06.07.04: Management of sevrals boards
+			{
+				i_ConvertCJCCalibration = 1;
+			}	//if(i_CJCPolarity!=i_ADDIDATAPolarity)
+			else {
+				//BEGIN JK 06.07.04: Management of sevrals boards
+				//if(i_CJCGain==i_ADDIDATAGain)
+				if (s_BoardInfos[dev->minor].i_CJCGain ==
+					s_BoardInfos[dev->minor].i_ADDIDATAGain)
+					//END JK 06.07.04: Management of sevrals boards
+				{
+					i_ConvertCJCCalibration = 0;
+				}	//if(i_CJCGain==i_ADDIDATAGain)
+				else {
+					i_ConvertCJCCalibration = 1;
+				}	//elseif(i_CJCGain==i_ADDIDATAGain)
+			}	//elseif(i_CJCPolarity!=i_ADDIDATAPolarity)
+			if (i_ConvertCJCCalibration == 1) {
+				i_APCI3200_ReadCJCCalOffset(dev,
+					&ui_DummyValue);
+				//BEGIN JK 06.07.04: Management of sevrals boards
+				//ui_InterruptChannelValue[i_Count+4]=ui_DummyValue;
+				s_BoardInfos[dev->minor].
+					ui_InterruptChannelValue[s_BoardInfos
+					[dev->minor].i_Count + 4] =
+					ui_DummyValue;
+				//END JK 06.07.04: Management of sevrals boards
+
+				i_APCI3200_ReadCJCCalGain(dev, &ui_DummyValue);
+
+				//BEGIN JK 06.07.04: Management of sevrals boards
+				//ui_InterruptChannelValue[i_Count+5]=ui_DummyValue;
+				s_BoardInfos[dev->minor].
+					ui_InterruptChannelValue[s_BoardInfos
+					[dev->minor].i_Count + 5] =
+					ui_DummyValue;
+				//END JK 06.07.04: Management of sevrals boards
+			}	//if(i_ConvertCJCCalibration==1)
+			else {
+				//BEGIN JK 06.07.04: Management of sevrals boards
+				//ui_InterruptChannelValue[i_Count+4]=0;
+				//ui_InterruptChannelValue[i_Count+5]=0;
+
+				s_BoardInfos[dev->minor].
+					ui_InterruptChannelValue[s_BoardInfos
+					[dev->minor].i_Count + 4] = 0;
+				s_BoardInfos[dev->minor].
+					ui_InterruptChannelValue[s_BoardInfos
+					[dev->minor].i_Count + 5] = 0;
+				//END JK 06.07.04: Management of sevrals boards
+			}	//elseif(i_ConvertCJCCalibration==1)
+		}		//if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE))
+
+		//BEGIN JK 06.07.04: Management of sevrals boards
+		//if(i_ScanType!=1)
+		if (s_BoardInfos[dev->minor].i_ScanType != 1) {
+			//i_Count=0;
+			s_BoardInfos[dev->minor].i_Count = 0;
+		}		//if(i_ScanType!=1)
+		else {
+			//i_Count=i_Count +6;
+			//Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+			//s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count +6;
+			s_BoardInfos[dev->minor].i_Count =
+				s_BoardInfos[dev->minor].i_Count + 9;
+			//End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+		}		//else if(i_ScanType!=1)
+
+		//if((i_ScanType==1) &&(i_InterruptFlag==1))
+		if ((s_BoardInfos[dev->minor].i_ScanType == 1)
+			&& (s_BoardInfos[dev->minor].i_InterruptFlag == 1)) {
+			//i_Count=i_Count-6;
+			//Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+			//s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count-6;
+			s_BoardInfos[dev->minor].i_Count =
+				s_BoardInfos[dev->minor].i_Count - 9;
+			//End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+		}
+		//if(i_ScanType==0)
+		if (s_BoardInfos[dev->minor].i_ScanType == 0) {
+			/*
+			   data[0]= ui_InterruptChannelValue[0];
+			   data[1]= ui_InterruptChannelValue[1];
+			   data[2]= ui_InterruptChannelValue[2];
+			   data[3]= ui_InterruptChannelValue[3];
+			   data[4]= ui_InterruptChannelValue[4];
+			   data[5]= ui_InterruptChannelValue[5];
+			 */
+#ifdef PRINT_INFO
+			printk("\n data[0]= s_BoardInfos [dev->minor].ui_InterruptChannelValue[0];");
+#endif
+			data[0] =
+				s_BoardInfos[dev->minor].
+				ui_InterruptChannelValue[0];
+			data[1] =
+				s_BoardInfos[dev->minor].
+				ui_InterruptChannelValue[1];
+			data[2] =
+				s_BoardInfos[dev->minor].
+				ui_InterruptChannelValue[2];
+			data[3] =
+				s_BoardInfos[dev->minor].
+				ui_InterruptChannelValue[3];
+			data[4] =
+				s_BoardInfos[dev->minor].
+				ui_InterruptChannelValue[4];
+			data[5] =
+				s_BoardInfos[dev->minor].
+				ui_InterruptChannelValue[5];
+
+			//Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+			//printk("\n 0 - i_APCI3200_GetChannelCalibrationValue data [6] = %lu, data [7] = %lu, data [8] = %lu", data [6], data [7], data [8]);
+			i_APCI3200_GetChannelCalibrationValue(dev,
+				s_BoardInfos[dev->minor].ui_Channel_num,
+				&data[6], &data[7], &data[8]);
+			//End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+		}
+		break;
+	case 1:
+
+		for (i = 0; i < insn->n; i++) {
+			//data[i]=ui_InterruptChannelValue[i];
+			data[i] =
+				s_BoardInfos[dev->minor].
+				ui_InterruptChannelValue[i];
+		}
+
+		//i_Count=0;
+		//i_Sum=0;
+		//if(i_ScanType==1)
+		s_BoardInfos[dev->minor].i_Count = 0;
+		s_BoardInfos[dev->minor].i_Sum = 0;
+		if (s_BoardInfos[dev->minor].i_ScanType == 1) {
+			//i_Initialised=0;
+			//i_InterruptFlag=0;
+			s_BoardInfos[dev->minor].i_Initialised = 0;
+			s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+			//END JK 06.07.04: Management of sevrals boards
+		}
+		break;
+	default:
+		printk("\nThe parameters passed are in error\n");
+		i_APCI3200_Reset(dev);
+		return -EINVAL;
+	}			//switch(insn->unused[0])
+
+	return insn->n;
+}
+
+/*
+  +----------------------------------------------------------------------------+
+  | Function   Name   : int i_APCI3200_Read1AnalogInputChannel                 |
+  |			          (struct comedi_device *dev,struct comedi_subdevice *s,       |
+  |                     struct comedi_insn *insn,unsigned int *data)                      |
+  +----------------------------------------------------------------------------+
+  | Task              : Read  value  of the selected channel			         |
+  +----------------------------------------------------------------------------+
+  | Input Parameters  : struct comedi_device *dev      : Driver handle                |
+  |                     UINT ui_NoOfChannel    : Channel No to read            |
+  |                     UINT *data              : Data Pointer to read status  |
+  +----------------------------------------------------------------------------+
+  | Output Parameters :	--													 |
+  |			          data[0]  : Digital Value read                   |
+  |
+  +----------------------------------------------------------------------------+
+  | Return Value      : TRUE  : No error occur                                 |
+  |		            : FALSE : Error occur. Return the error          |
+  |			                                                         |
+  +----------------------------------------------------------------------------+
+*/
+INT i_APCI3200_Read1AnalogInputChannel(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_EOC = 0;
+	UINT ui_ChannelNo = 0;
+	UINT ui_CommandRegister = 0;
+
+	//BEGIN JK 06.07.04: Management of sevrals boards
+	//ui_ChannelNo=i_ChannelNo;
+	ui_ChannelNo = s_BoardInfos[dev->minor].i_ChannelNo;
+
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+  /*********************************/
+	/* Write the channel to configure */
+  /*********************************/
+	//Begin JK 20.10.2004: Bad channel value is used when using differential mode
+	//outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4);
+	//outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4);
+	outl(0 | s_BoardInfos[dev->minor].i_ChannelNo,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x4);
+	//End JK 20.10.2004: Bad channel value is used when using differential mode
+
+  /*******************************/
+	/* Set the convert timing unit */
+  /*******************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+
+	//outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+	outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+
+  /**************************/
+	/* Set the convert timing */
+  /**************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+
+	//outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+	outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+
+  /**************************************************************************/
+	/* Set the start end stop index to the selected channel and set the start */
+  /**************************************************************************/
+
+	ui_CommandRegister = ui_ChannelNo | (ui_ChannelNo << 8) | 0x80000;
+
+  /*********************************/
+	/*Test if the interrupt is enable */
+  /*********************************/
+
+	//if (i_InterruptFlag == ADDIDATA_ENABLE)
+	if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
+      /************************/
+		/* Enable the interrupt */
+      /************************/
+		ui_CommandRegister = ui_CommandRegister | 0x00100000;
+	}			//if (i_InterruptFlag == ADDIDATA_ENABLE)
+
+  /******************************/
+	/* Write the command register */
+  /******************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+
+	//outl(ui_CommandRegister, devpriv->iobase+i_Offset + 8);
+	outl(ui_CommandRegister,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+
+  /*****************************/
+	/*Test if interrupt is enable */
+  /*****************************/
+	//if (i_InterruptFlag == ADDIDATA_DISABLE)
+	if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+		do {
+	  /*************************/
+			/*Read the EOC Status bit */
+	  /*************************/
+
+			//ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1;
+			ui_EOC = inl(devpriv->iobase +
+				s_BoardInfos[dev->minor].i_Offset + 20) & 1;
+
+		} while (ui_EOC != 1);
+
+      /***************************************/
+		/* Read the digital value of the input */
+      /***************************************/
+
+		//data[0] = inl (devpriv->iobase+i_Offset + 28);
+		data[0] =
+			inl(devpriv->iobase +
+			s_BoardInfos[dev->minor].i_Offset + 28);
+		//END JK 06.07.04: Management of sevrals boards
+
+	}			// if (i_InterruptFlag == ADDIDATA_DISABLE)
+	return 0;
+}
+
+/*
+  +----------------------------------------------------------------------------+
+  | Function   Name   : int i_APCI3200_ReadCalibrationOffsetValue              |
+  |			          (struct comedi_device *dev,struct comedi_subdevice *s,       |
+  |                     struct comedi_insn *insn,unsigned int *data)                      |
+  +----------------------------------------------------------------------------+
+  | Task              : Read calibration offset  value  of the selected channel|
+  +----------------------------------------------------------------------------+
+  | Input Parameters  : struct comedi_device *dev      : Driver handle                |
+  |                     UINT *data              : Data Pointer to read status  |
+  +----------------------------------------------------------------------------+
+  | Output Parameters :	--													 |
+  |			          data[0]  : Calibration offset Value   |
+  |
+  +----------------------------------------------------------------------------+
+  | Return Value      : TRUE  : No error occur                                 |
+  |		            : FALSE : Error occur. Return the error          |
+  |			                                                         |
+  +----------------------------------------------------------------------------+
+*/
+int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device * dev, UINT * data)
+{
+	UINT ui_Temp = 0, ui_EOC = 0;
+	UINT ui_CommandRegister = 0;
+
+	//BEGIN JK 06.07.04: Management of sevrals boards
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+  /*********************************/
+	/* Write the channel to configure */
+  /*********************************/
+	//Begin JK 20.10.2004: This seems not necessary !
+	//outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4);
+	//outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4);
+	//End JK 20.10.2004: This seems not necessary !
+
+  /*******************************/
+	/* Set the convert timing unit */
+  /*******************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+	outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+  /**************************/
+	/* Set the convert timing */
+  /**************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+	outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+  /*****************************/
+	/*Read the calibration offset */
+  /*****************************/
+	//ui_Temp = inl(devpriv->iobase+i_Offset + 12);
+	ui_Temp = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+
+  /*********************************/
+	/*Configure the Offset Conversion */
+  /*********************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl((ui_Temp | 0x00020000), devpriv->iobase+i_Offset + 12);
+	outl((ui_Temp | 0x00020000),
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+  /*******************************/
+	/*Initialise ui_CommandRegister */
+  /*******************************/
+
+	ui_CommandRegister = 0;
+
+  /*********************************/
+	/*Test if the interrupt is enable */
+  /*********************************/
+
+	//if (i_InterruptFlag == ADDIDATA_ENABLE)
+	if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
+
+      /**********************/
+		/*Enable the interrupt */
+      /**********************/
+
+		ui_CommandRegister = ui_CommandRegister | 0x00100000;
+
+	}			//if (i_InterruptFlag == ADDIDATA_ENABLE)
+
+  /**********************/
+	/*Start the conversion */
+  /**********************/
+	ui_CommandRegister = ui_CommandRegister | 0x00080000;
+
+  /***************************/
+	/*Write the command regiter */
+  /***************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl(ui_CommandRegister, devpriv->iobase+i_Offset + 8);
+	outl(ui_CommandRegister,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+
+  /*****************************/
+	/*Test if interrupt is enable */
+  /*****************************/
+
+	//if (i_InterruptFlag == ADDIDATA_DISABLE)
+	if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+
+		do {
+	  /*******************/
+			/*Read the EOC flag */
+	  /*******************/
+
+			//ui_EOC = inl (devpriv->iobase+i_Offset + 20) & 1;
+			ui_EOC = inl(devpriv->iobase +
+				s_BoardInfos[dev->minor].i_Offset + 20) & 1;
+
+		} while (ui_EOC != 1);
+
+      /**************************************************/
+		/*Read the digital value of the calibration Offset */
+      /**************************************************/
+
+		//data[0] = inl(devpriv->iobase+i_Offset+ 28);
+		data[0] =
+			inl(devpriv->iobase +
+			s_BoardInfos[dev->minor].i_Offset + 28);
+	}			//if (i_InterruptFlag == ADDIDATA_DISABLE)
+	return 0;
+}
+
+/*
+  +----------------------------------------------------------------------------+
+  | Function   Name   : int i_APCI3200_ReadCalibrationGainValue                |
+  |			          (struct comedi_device *dev,struct comedi_subdevice *s,       |
+  |                     struct comedi_insn *insn,unsigned int *data)                      |
+  +----------------------------------------------------------------------------+
+  | Task              : Read calibration gain  value  of the selected channel  |
+  +----------------------------------------------------------------------------+
+  | Input Parameters  : struct comedi_device *dev      : Driver handle                |
+  |                     UINT *data              : Data Pointer to read status  |
+  +----------------------------------------------------------------------------+
+  | Output Parameters :	--													 |
+  |			          data[0]  : Calibration gain Value Of Input     |
+  |
+  +----------------------------------------------------------------------------+
+  | Return Value      : TRUE  : No error occur                                 |
+  |		            : FALSE : Error occur. Return the error          |
+  |			                                                         |
+  +----------------------------------------------------------------------------+
+*/
+int i_APCI3200_ReadCalibrationGainValue(struct comedi_device * dev, UINT * data)
+{
+	UINT ui_EOC = 0;
+	INT ui_CommandRegister = 0;
+
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+  /*********************************/
+	/* Write the channel to configure */
+  /*********************************/
+	//Begin JK 20.10.2004: This seems not necessary !
+	//outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4);
+	//outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4);
+	//End JK 20.10.2004: This seems not necessary !
+
+  /***************************/
+	/*Read the calibration gain */
+  /***************************/
+  /*******************************/
+	/* Set the convert timing unit */
+  /*******************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+	outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+  /**************************/
+	/* Set the convert timing */
+  /**************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+	outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+  /*******************************/
+	/*Configure the Gain Conversion */
+  /*******************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl(0x00040000 , devpriv->iobase+i_Offset + 12);
+	outl(0x00040000,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+
+  /*******************************/
+	/*Initialise ui_CommandRegister */
+  /*******************************/
+
+	ui_CommandRegister = 0;
+
+  /*********************************/
+	/*Test if the interrupt is enable */
+  /*********************************/
+
+	//if (i_InterruptFlag == ADDIDATA_ENABLE)
+	if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
+
+      /**********************/
+		/*Enable the interrupt */
+      /**********************/
+
+		ui_CommandRegister = ui_CommandRegister | 0x00100000;
+
+	}			//if (i_InterruptFlag == ADDIDATA_ENABLE)
+
+  /**********************/
+	/*Start the conversion */
+  /**********************/
+
+	ui_CommandRegister = ui_CommandRegister | 0x00080000;
+  /***************************/
+	/*Write the command regiter */
+  /***************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl(ui_CommandRegister , devpriv->iobase+i_Offset + 8);
+	outl(ui_CommandRegister,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+
+  /*****************************/
+	/*Test if interrupt is enable */
+  /*****************************/
+
+	//if (i_InterruptFlag == ADDIDATA_DISABLE)
+	if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+
+		do {
+
+	  /*******************/
+			/*Read the EOC flag */
+	  /*******************/
+
+			//ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1;
+			ui_EOC = inl(devpriv->iobase +
+				s_BoardInfos[dev->minor].i_Offset + 20) & 1;
+
+		} while (ui_EOC != 1);
+
+      /************************************************/
+		/*Read the digital value of the calibration Gain */
+      /************************************************/
+
+		//data[0] = inl(devpriv->iobase+i_Offset + 28);
+		data[0] =
+			inl(devpriv->iobase +
+			s_BoardInfos[dev->minor].i_Offset + 28);
+
+	}			//if (i_InterruptFlag == ADDIDATA_DISABLE)
+	return 0;
+}
+
+/*
+  +----------------------------------------------------------------------------+
+  | Function   Name   : int i_APCI3200_ReadCJCValue                            |
+  |			          (struct comedi_device *dev,struct comedi_subdevice *s,       |
+  |                     struct comedi_insn *insn,unsigned int *data)                      |
+  +----------------------------------------------------------------------------+
+  | Task              : Read CJC  value  of the selected channel               |
+  +----------------------------------------------------------------------------+
+  | Input Parameters  : struct comedi_device *dev      : Driver handle                |
+  |                     UINT *data              : Data Pointer to read status  |
+  +----------------------------------------------------------------------------+
+  | Output Parameters :	--													 |
+  |			          data[0]  : CJC Value                           |
+  |
+  +----------------------------------------------------------------------------+
+  | Return Value      : TRUE  : No error occur                                 |
+  |		            : FALSE : Error occur. Return the error          |
+  |			                                                         |
+  +----------------------------------------------------------------------------+
+*/
+
+int i_APCI3200_ReadCJCValue(struct comedi_device * dev, unsigned int * data)
+{
+	UINT ui_EOC = 0;
+	INT ui_CommandRegister = 0;
+
+  /******************************/
+	/*Set the converting time unit */
+  /******************************/
+
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+
+	//outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+	outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+  /**************************/
+	/* Set the convert timing */
+  /**************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+
+	//outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+	outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+
+  /******************************/
+	/*Configure the CJC Conversion */
+  /******************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+
+	//outl( 0x00000400 , devpriv->iobase+i_Offset + 4);
+	outl(0x00000400,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
+  /*******************************/
+	/*Initialise dw_CommandRegister */
+  /*******************************/
+	ui_CommandRegister = 0;
+  /*********************************/
+	/*Test if the interrupt is enable */
+  /*********************************/
+	//if (i_InterruptFlag == ADDIDATA_ENABLE)
+	if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
+      /**********************/
+		/*Enable the interrupt */
+      /**********************/
+		ui_CommandRegister = ui_CommandRegister | 0x00100000;
+	}
+
+  /**********************/
+	/*Start the conversion */
+  /**********************/
+
+	ui_CommandRegister = ui_CommandRegister | 0x00080000;
+
+  /***************************/
+	/*Write the command regiter */
+  /***************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl(ui_CommandRegister , devpriv->iobase+i_Offset + 8);
+	outl(ui_CommandRegister,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+
+  /*****************************/
+	/*Test if interrupt is enable */
+  /*****************************/
+
+	//if (i_InterruptFlag == ADDIDATA_DISABLE)
+	if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+		do {
+
+	  /*******************/
+			/*Read the EOC flag */
+	  /*******************/
+
+			//ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1;
+			ui_EOC = inl(devpriv->iobase +
+				s_BoardInfos[dev->minor].i_Offset + 20) & 1;
+
+		} while (ui_EOC != 1);
+
+      /***********************************/
+		/*Read the digital value of the CJC */
+      /***********************************/
+
+		//data[0] = inl(devpriv->iobase+i_Offset + 28);
+		data[0] =
+			inl(devpriv->iobase +
+			s_BoardInfos[dev->minor].i_Offset + 28);
+
+	}			//if (i_InterruptFlag == ADDIDATA_DISABLE)
+	return 0;
+}
+
+/*
+  +----------------------------------------------------------------------------+
+  | Function   Name   : int i_APCI3200_ReadCJCCalOffset                        |
+  |			          (struct comedi_device *dev,struct comedi_subdevice *s,       |
+  |                     struct comedi_insn *insn,unsigned int *data)                      |
+  +----------------------------------------------------------------------------+
+  | Task              : Read CJC calibration offset  value  of the selected channel
+  +----------------------------------------------------------------------------+
+  | Input Parameters  : struct comedi_device *dev      : Driver handle                |
+  |                     UINT *data              : Data Pointer to read status  |
+  +----------------------------------------------------------------------------+
+  | Output Parameters :	--													 |
+  |			          data[0]  : CJC calibration offset Value
+  |
+  +----------------------------------------------------------------------------+
+  | Return Value      : TRUE  : No error occur                                 |
+  |		            : FALSE : Error occur. Return the error          |
+  |			                                                         |
+  +----------------------------------------------------------------------------+
+*/
+int i_APCI3200_ReadCJCCalOffset(struct comedi_device * dev, unsigned int * data)
+{
+	UINT ui_EOC = 0;
+	INT ui_CommandRegister = 0;
+  /*******************************************/
+	/*Read calibration offset value for the CJC */
+  /*******************************************/
+  /*******************************/
+	/* Set the convert timing unit */
+  /*******************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+	outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+  /**************************/
+	/* Set the convert timing */
+  /**************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+	outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+  /******************************/
+	/*Configure the CJC Conversion */
+  /******************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl(0x00000400 , devpriv->iobase+i_Offset + 4);
+	outl(0x00000400,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
+  /*********************************/
+	/*Configure the Offset Conversion */
+  /*********************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl(0x00020000, devpriv->iobase+i_Offset + 12);
+	outl(0x00020000,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+  /*******************************/
+	/*Initialise ui_CommandRegister */
+  /*******************************/
+	ui_CommandRegister = 0;
+  /*********************************/
+	/*Test if the interrupt is enable */
+  /*********************************/
+
+	//if (i_InterruptFlag == ADDIDATA_ENABLE)
+	if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
+      /**********************/
+		/*Enable the interrupt */
+      /**********************/
+		ui_CommandRegister = ui_CommandRegister | 0x00100000;
+
+	}
+
+  /**********************/
+	/*Start the conversion */
+  /**********************/
+	ui_CommandRegister = ui_CommandRegister | 0x00080000;
+  /***************************/
+	/*Write the command regiter */
+  /***************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl(ui_CommandRegister,devpriv->iobase+i_Offset + 8);
+	outl(ui_CommandRegister,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+	//if (i_InterruptFlag == ADDIDATA_DISABLE)
+	if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+		do {
+	  /*******************/
+			/*Read the EOC flag */
+	  /*******************/
+			//ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1;
+			ui_EOC = inl(devpriv->iobase +
+				s_BoardInfos[dev->minor].i_Offset + 20) & 1;
+		} while (ui_EOC != 1);
+
+      /**************************************************/
+		/*Read the digital value of the calibration Offset */
+      /**************************************************/
+		//data[0] = inl(devpriv->iobase+i_Offset + 28);
+		data[0] =
+			inl(devpriv->iobase +
+			s_BoardInfos[dev->minor].i_Offset + 28);
+	}			//if (i_InterruptFlag == ADDIDATA_DISABLE)
+	return 0;
+}
+
+/*
+  +----------------------------------------------------------------------------+
+  | Function   Name   : int i_APCI3200_ReadCJCGainValue                        |
+  |			          (struct comedi_device *dev,struct comedi_subdevice *s,       |
+  |                     struct comedi_insn *insn,unsigned int *data)                      |
+  +----------------------------------------------------------------------------+
+  | Task              : Read CJC calibration gain value
+  +----------------------------------------------------------------------------+
+  | Input Parameters  : struct comedi_device *dev      : Driver handle                |
+  |                     UINT ui_NoOfChannels    : No Of Channels To read       |
+  |                     UINT *data              : Data Pointer to read status  |
+  +----------------------------------------------------------------------------+
+  | Output Parameters :	--													 |
+  |			          data[0]  : CJC calibration gain value
+  |
+  +----------------------------------------------------------------------------+
+  | Return Value      : TRUE  : No error occur                                 |
+  |		            : FALSE : Error occur. Return the error          |
+  |			                                                         |
+  +----------------------------------------------------------------------------+
+*/
+int i_APCI3200_ReadCJCCalGain(struct comedi_device * dev, unsigned int * data)
+{
+	UINT ui_EOC = 0;
+	INT ui_CommandRegister = 0;
+  /*******************************/
+	/* Set the convert timing unit */
+  /*******************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+	outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+  /**************************/
+	/* Set the convert timing */
+  /**************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+	outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+  /******************************/
+	/*Configure the CJC Conversion */
+  /******************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl(0x00000400,devpriv->iobase+i_Offset + 4);
+	outl(0x00000400,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
+  /*******************************/
+	/*Configure the Gain Conversion */
+  /*******************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl(0x00040000,devpriv->iobase+i_Offset + 12);
+	outl(0x00040000,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+
+  /*******************************/
+	/*Initialise dw_CommandRegister */
+  /*******************************/
+	ui_CommandRegister = 0;
+  /*********************************/
+	/*Test if the interrupt is enable */
+  /*********************************/
+	//if (i_InterruptFlag == ADDIDATA_ENABLE)
+	if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
+      /**********************/
+		/*Enable the interrupt */
+      /**********************/
+		ui_CommandRegister = ui_CommandRegister | 0x00100000;
+	}
+  /**********************/
+	/*Start the conversion */
+  /**********************/
+	ui_CommandRegister = ui_CommandRegister | 0x00080000;
+  /***************************/
+	/*Write the command regiter */
+  /***************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl(ui_CommandRegister ,devpriv->iobase+i_Offset + 8);
+	outl(ui_CommandRegister,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+	//if (i_InterruptFlag == ADDIDATA_DISABLE)
+	if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+		do {
+	  /*******************/
+			/*Read the EOC flag */
+	  /*******************/
+			//ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1;
+			ui_EOC = inl(devpriv->iobase +
+				s_BoardInfos[dev->minor].i_Offset + 20) & 1;
+		} while (ui_EOC != 1);
+      /************************************************/
+		/*Read the digital value of the calibration Gain */
+      /************************************************/
+		//data[0] = inl (devpriv->iobase+i_Offset + 28);
+		data[0] =
+			inl(devpriv->iobase +
+			s_BoardInfos[dev->minor].i_Offset + 28);
+	}			//if (i_InterruptFlag == ADDIDATA_DISABLE)
+	return 0;
+}
+
+/*
+  +----------------------------------------------------------------------------+
+  | Function   Name   : int i_APCI3200_InsnBits_AnalogInput_Test               |
+  |			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+  |                      struct comedi_insn *insn,unsigned int *data)                     |
+  +----------------------------------------------------------------------------+
+  | Task              : Tests the Selected Anlog Input Channel                 |
+  +----------------------------------------------------------------------------+
+  | Input Parameters  : struct comedi_device *dev      : Driver handle                |
+  |                     struct comedi_subdevice *s     : Subdevice Pointer            |
+  |                     struct comedi_insn *insn       : Insn Structure Pointer       |
+  |                     unsigned int *data          : Data Pointer contains        |
+  |                                          configuration parameters as below |
+  |
+  |
+  |                           data[0]            : 0 TestAnalogInputShortCircuit
+  |									     1 TestAnalogInputConnection							 														                        |
+
+  +----------------------------------------------------------------------------+
+  | Output Parameters :	--													 |
+  |			        data[0]            : Digital value obtained      |
+  |                           data[1]            : calibration offset          |
+  |                           data[2]            : calibration gain            |
+  |			                                                         |
+  |			                                                         |
+  +----------------------------------------------------------------------------+
+  | Return Value      : TRUE  : No error occur                                 |
+  |		            : FALSE : Error occur. Return the error          |
+  |			                                                         |
+  +----------------------------------------------------------------------------+
+*/
+
+INT i_APCI3200_InsnBits_AnalogInput_Test(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_Configuration = 0;
+	INT i_Temp;		//,i_TimeUnit;
+	//if(i_Initialised==0)
+
+	if (s_BoardInfos[dev->minor].i_Initialised == 0) {
+		i_APCI3200_Reset(dev);
+		return -EINVAL;
+	}			//if(i_Initialised==0);
+	if (data[0] != 0 && data[0] != 1) {
+		printk("\nError in selection of functionality\n");
+		i_APCI3200_Reset(dev);
+		return -EINVAL;
+	}			//if(data[0]!=0 && data[0]!=1)
+
+	if (data[0] == 1)	//Perform Short Circuit TEST
+	{
+      /**************************/
+		/*Set the short-cicuit bit */
+      /**************************/
+		//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+		while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].
+						i_Offset + 12) >> 19) & 1) !=
+			1) ;
+		//outl((0x00001000 |i_ChannelNo) , devpriv->iobase+i_Offset + 4);
+		outl((0x00001000 | s_BoardInfos[dev->minor].i_ChannelNo),
+			devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+			4);
+      /*************************/
+		/*Set the time unit to ns */
+      /*************************/
+		/* i_TimeUnit= i_ADDIDATAConversionTimeUnit;
+		   i_ADDIDATAConversionTimeUnit= 1; */
+		//i_Temp= i_InterruptFlag ;
+		i_Temp = s_BoardInfos[dev->minor].i_InterruptFlag;
+		//i_InterruptFlag = ADDIDATA_DISABLE;
+		s_BoardInfos[dev->minor].i_InterruptFlag = ADDIDATA_DISABLE;
+		i_APCI3200_Read1AnalogInputChannel(dev, s, insn, data);
+		//if(i_AutoCalibration == FALSE)
+		if (s_BoardInfos[dev->minor].i_AutoCalibration == FALSE) {
+			//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+			while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].
+							i_Offset +
+							12) >> 19) & 1) != 1) ;
+
+			//outl((0x00001000 |i_ChannelNo) , devpriv->iobase+i_Offset + 4);
+			outl((0x00001000 | s_BoardInfos[dev->minor].
+					i_ChannelNo),
+				devpriv->iobase +
+				s_BoardInfos[dev->minor].i_Offset + 4);
+			data++;
+			i_APCI3200_ReadCalibrationOffsetValue(dev, data);
+			data++;
+			i_APCI3200_ReadCalibrationGainValue(dev, data);
+		}
+	} else {
+		//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+		while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].
+						i_Offset + 12) >> 19) & 1) !=
+			1) ;
+		//outl((0x00000800|i_ChannelNo) , devpriv->iobase+i_Offset + 4);
+		outl((0x00000800 | s_BoardInfos[dev->minor].i_ChannelNo),
+			devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+			4);
+		//ui_Configuration = inl(devpriv->iobase+i_Offset + 0);
+		ui_Configuration =
+			inl(devpriv->iobase +
+			s_BoardInfos[dev->minor].i_Offset + 0);
+      /*************************/
+		/*Set the time unit to ns */
+      /*************************/
+		/* i_TimeUnit= i_ADDIDATAConversionTimeUnit;
+		   i_ADDIDATAConversionTimeUnit= 1; */
+		//i_Temp= i_InterruptFlag ;
+		i_Temp = s_BoardInfos[dev->minor].i_InterruptFlag;
+		//i_InterruptFlag = ADDIDATA_DISABLE;
+		s_BoardInfos[dev->minor].i_InterruptFlag = ADDIDATA_DISABLE;
+		i_APCI3200_Read1AnalogInputChannel(dev, s, insn, data);
+		//if(i_AutoCalibration == FALSE)
+		if (s_BoardInfos[dev->minor].i_AutoCalibration == FALSE) {
+			//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+			while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].
+							i_Offset +
+							12) >> 19) & 1) != 1) ;
+			//outl((0x00000800|i_ChannelNo) , devpriv->iobase+i_Offset + 4);
+			outl((0x00000800 | s_BoardInfos[dev->minor].
+					i_ChannelNo),
+				devpriv->iobase +
+				s_BoardInfos[dev->minor].i_Offset + 4);
+			data++;
+			i_APCI3200_ReadCalibrationOffsetValue(dev, data);
+			data++;
+			i_APCI3200_ReadCalibrationGainValue(dev, data);
+		}
+	}
+	//i_InterruptFlag=i_Temp ;
+	s_BoardInfos[dev->minor].i_InterruptFlag = i_Temp;
+	//printk("\ni_InterruptFlag=%d\n",i_InterruptFlag);
+	return insn->n;
+}
+
+/*
+  +----------------------------------------------------------------------------+
+  | Function   Name   : int i_APCI3200_InsnWriteReleaseAnalogInput             |
+  |			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+  |                      struct comedi_insn *insn,unsigned int *data)                     |
+  +----------------------------------------------------------------------------+
+  | Task              :  Resets the channels                                                      |
+  +----------------------------------------------------------------------------+
+  | Input Parameters  : struct comedi_device *dev      : Driver handle                |
+  |                     struct comedi_subdevice *s     : Subdevice Pointer            |
+  |                     struct comedi_insn *insn       : Insn Structure Pointer       |
+  |                     unsigned int *data          : Data Pointer
+  +----------------------------------------------------------------------------+
+  | Output Parameters :	--													 |
+
+  +----------------------------------------------------------------------------+
+  | Return Value      : TRUE  : No error occur                                 |
+  |		            : FALSE : Error occur. Return the error          |
+  |			                                                         |
+  +----------------------------------------------------------------------------+
+*/
+
+INT i_APCI3200_InsnWriteReleaseAnalogInput(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	i_APCI3200_Reset(dev);
+	return insn->n;
+}
+
+/*
+  +----------------------------------------------------------------------------+
+  | Function name     :int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev|
+  |			,struct comedi_subdevice *s,struct comedi_cmd *cmd)			         |
+  |                                        									 |
+  +----------------------------------------------------------------------------+
+  | Task              : Test validity for a command for cyclic anlog input     |
+  |                       acquisition  						     			 |
+  |                     										                 |
+  +----------------------------------------------------------------------------+
+  | Input Parameters  : struct comedi_device *dev									 |
+  |                     struct comedi_subdevice *s									 |
+  |                     struct comedi_cmd *cmd              					         |
+  |                     										                 |
+  |
+  |                     										                 |
+  |                     										                 |
+  |                     										                 |
+  +----------------------------------------------------------------------------+
+  | Return Value      :0              					                     |
+  |                    													     |
+  +----------------------------------------------------------------------------+
+*/
+
+int i_APCI3200_CommandTestAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+
+	int err = 0;
+	int tmp;		// divisor1,divisor2;
+	UINT ui_ConvertTime = 0;
+	UINT ui_ConvertTimeBase = 0;
+	UINT ui_DelayTime = 0;
+	UINT ui_DelayTimeBase = 0;
+	INT i_Triggermode = 0;
+	INT i_TriggerEdge = 0;
+	INT i_NbrOfChannel = 0;
+	INT i_Cpt = 0;
+	double d_ConversionTimeForAllChannels = 0.0;
+	double d_SCANTimeNewUnit = 0.0;
+	// step 1: make sure trigger sources are trivially valid
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW | TRIG_EXT;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_TIMER | TRIG_FOLLOW;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_TIMER;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+	//if(i_InterruptFlag==0)
+	if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) {
+		err++;
+		//          printk("\nThe interrupt should be enabled\n");
+	}
+	if (err) {
+		i_APCI3200_Reset(dev);
+		return 1;
+	}
+
+	if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) {
+		err++;
+	}
+	if (cmd->start_src == TRIG_EXT) {
+		i_TriggerEdge = cmd->start_arg & 0xFFFF;
+		i_Triggermode = cmd->start_arg >> 16;
+		if (i_TriggerEdge < 1 || i_TriggerEdge > 3) {
+			err++;
+			printk("\nThe trigger edge selection is in error\n");
+		}
+		if (i_Triggermode != 2) {
+			err++;
+			printk("\nThe trigger mode selection is in error\n");
+		}
+	}
+
+	if (cmd->scan_begin_src != TRIG_TIMER &&
+		cmd->scan_begin_src != TRIG_FOLLOW)
+		err++;
+
+	if (cmd->convert_src != TRIG_TIMER)
+		err++;
+
+	if (cmd->scan_end_src != TRIG_COUNT) {
+		cmd->scan_end_src = TRIG_COUNT;
+		err++;
+	}
+
+	if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
+		err++;
+
+	if (err) {
+		i_APCI3200_Reset(dev);
+		return 2;
+	}
+	//i_FirstChannel=cmd->chanlist[0];
+	s_BoardInfos[dev->minor].i_FirstChannel = cmd->chanlist[0];
+	//i_LastChannel=cmd->chanlist[1];
+	s_BoardInfos[dev->minor].i_LastChannel = cmd->chanlist[1];
+
+	if (cmd->convert_src == TRIG_TIMER) {
+		ui_ConvertTime = cmd->convert_arg & 0xFFFF;
+		ui_ConvertTimeBase = cmd->convert_arg >> 16;
+		if (ui_ConvertTime != 20 && ui_ConvertTime != 40
+			&& ui_ConvertTime != 80 && ui_ConvertTime != 160)
+		{
+			printk("\nThe selection of conversion time reload value is in error\n");
+			err++;
+		}		// if (ui_ConvertTime!=20 && ui_ConvertTime!=40 && ui_ConvertTime!=80 && ui_ConvertTime!=160 )
+		if (ui_ConvertTimeBase != 2) {
+			printk("\nThe selection of conversion time unit  is in error\n");
+			err++;
+		}		//if(ui_ConvertTimeBase!=2)
+	} else {
+		ui_ConvertTime = 0;
+		ui_ConvertTimeBase = 0;
+	}
+	if (cmd->scan_begin_src == TRIG_FOLLOW) {
+		ui_DelayTime = 0;
+		ui_DelayTimeBase = 0;
+	}			//if(cmd->scan_begin_src==TRIG_FOLLOW)
+	else {
+		ui_DelayTime = cmd->scan_begin_arg & 0xFFFF;
+		ui_DelayTimeBase = cmd->scan_begin_arg >> 16;
+		if (ui_DelayTimeBase != 2 && ui_DelayTimeBase != 3) {
+			err++;
+			printk("\nThe Delay time base selection is in error\n");
+		}
+		if (ui_DelayTime < 1 && ui_DelayTime > 1023) {
+			err++;
+			printk("\nThe Delay time value is in error\n");
+		}
+		if (err) {
+			i_APCI3200_Reset(dev);
+			return 3;
+		}
+		fpu_begin();
+		d_SCANTimeNewUnit = (double)ui_DelayTime;
+		//i_NbrOfChannel= i_LastChannel-i_FirstChannel + 4;
+		i_NbrOfChannel =
+			s_BoardInfos[dev->minor].i_LastChannel -
+			s_BoardInfos[dev->minor].i_FirstChannel + 4;
+      /**********************************************************/
+		/*calculate the total conversion time for all the channels */
+      /**********************************************************/
+		d_ConversionTimeForAllChannels =
+			(double)((double)ui_ConvertTime /
+			(double)i_NbrOfChannel);
+
+      /*******************************/
+		/*Convert the frequence in time */
+      /*******************************/
+		d_ConversionTimeForAllChannels =
+			(double)1.0 / d_ConversionTimeForAllChannels;
+		ui_ConvertTimeBase = 3;
+      /***********************************/
+		/*Test if the time unit is the same */
+      /***********************************/
+
+		if (ui_DelayTimeBase <= ui_ConvertTimeBase) {
+
+			for (i_Cpt = 0;
+				i_Cpt < (ui_ConvertTimeBase - ui_DelayTimeBase);
+				i_Cpt++) {
+
+				d_ConversionTimeForAllChannels =
+					d_ConversionTimeForAllChannels * 1000;
+				d_ConversionTimeForAllChannels =
+					d_ConversionTimeForAllChannels + 1;
+			}
+		} else {
+			for (i_Cpt = 0;
+				i_Cpt < (ui_DelayTimeBase - ui_ConvertTimeBase);
+				i_Cpt++) {
+				d_SCANTimeNewUnit = d_SCANTimeNewUnit * 1000;
+
+			}
+		}
+
+		if (d_ConversionTimeForAllChannels >= d_SCANTimeNewUnit) {
+
+			printk("\nSCAN Delay value cannot be used\n");
+	  /*********************************/
+			/*SCAN Delay value cannot be used */
+	  /*********************************/
+			err++;
+		}
+		fpu_end();
+	}			//else if(cmd->scan_begin_src==TRIG_FOLLOW)
+
+	if (err) {
+		i_APCI3200_Reset(dev);
+		return 4;
+	}
+
+	return 0;
+}
+
+/*
+  +----------------------------------------------------------------------------+
+  | Function name     :int i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev,|
+  | 											     struct comedi_subdevice *s)|
+  |                                        									 |
+  +----------------------------------------------------------------------------+
+  | Task              : Stop the  acquisition  						     |
+  |                     										                 |
+  +----------------------------------------------------------------------------+
+  | Input Parameters  : struct comedi_device *dev									 |
+  |                     struct comedi_subdevice *s									 |
+  |                                                 					         |
+  +----------------------------------------------------------------------------+
+  | Return Value      :0              					                     |
+  |                    													     |
+  +----------------------------------------------------------------------------+
+*/
+
+int i_APCI3200_StopCyclicAcquisition(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	UINT ui_Configuration = 0;
+	//i_InterruptFlag=0;
+	//i_Initialised=0;
+	//i_Count=0;
+	//i_Sum=0;
+	s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+	s_BoardInfos[dev->minor].i_Initialised = 0;
+	s_BoardInfos[dev->minor].i_Count = 0;
+	s_BoardInfos[dev->minor].i_Sum = 0;
+
+  /*******************/
+	/*Read the register */
+  /*******************/
+	//ui_Configuration = inl(devpriv->iobase+i_Offset + 8);
+	ui_Configuration =
+		inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+  /*****************************/
+	/*Reset the START and IRQ bit */
+  /*****************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl((ui_Configuration & 0xFFE7FFFF),devpriv->iobase+i_Offset + 8);
+	outl((ui_Configuration & 0xFFE7FFFF),
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+	return 0;
+}
+
+/*
+  +----------------------------------------------------------------------------+
+  | Function name     : int i_APCI3200_CommandAnalogInput(struct comedi_device *dev,  |
+  |												struct comedi_subdevice *s) |
+  |                                        									 |
+  +----------------------------------------------------------------------------+
+  | Task              : Does asynchronous acquisition                          |
+  |                     Determines the mode 1 or 2.						     |
+  |                     										                 |
+  +----------------------------------------------------------------------------+
+  | Input Parameters  : struct comedi_device *dev									 |
+  |                     struct comedi_subdevice *s									 |
+  |                     														 |
+  |                     														 |
+  +----------------------------------------------------------------------------+
+  | Return Value      :              					                         |
+  |                    													     |
+  +----------------------------------------------------------------------------+
+*/
+
+int i_APCI3200_CommandAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_cmd *cmd = &s->async->cmd;
+	UINT ui_Configuration = 0;
+	//INT  i_CurrentSource = 0;
+	UINT ui_Trigger = 0;
+	UINT ui_TriggerEdge = 0;
+	UINT ui_Triggermode = 0;
+	UINT ui_ScanMode = 0;
+	UINT ui_ConvertTime = 0;
+	UINT ui_ConvertTimeBase = 0;
+	UINT ui_DelayTime = 0;
+	UINT ui_DelayTimeBase = 0;
+	UINT ui_DelayMode = 0;
+	//i_FirstChannel=cmd->chanlist[0];
+	//i_LastChannel=cmd->chanlist[1];
+	s_BoardInfos[dev->minor].i_FirstChannel = cmd->chanlist[0];
+	s_BoardInfos[dev->minor].i_LastChannel = cmd->chanlist[1];
+	if (cmd->start_src == TRIG_EXT) {
+		ui_Trigger = 1;
+		ui_TriggerEdge = cmd->start_arg & 0xFFFF;
+		ui_Triggermode = cmd->start_arg >> 16;
+	}			//if(cmd->start_src==TRIG_EXT)
+	else {
+		ui_Trigger = 0;
+	}			//elseif(cmd->start_src==TRIG_EXT)
+
+	if (cmd->stop_src == TRIG_COUNT) {
+		ui_ScanMode = 0;
+	}			// if (cmd->stop_src==TRIG_COUNT)
+	else {
+		ui_ScanMode = 2;
+	}			//else if (cmd->stop_src==TRIG_COUNT)
+
+	if (cmd->scan_begin_src == TRIG_FOLLOW) {
+		ui_DelayTime = 0;
+		ui_DelayTimeBase = 0;
+		ui_DelayMode = 0;
+	}			//if(cmd->scan_begin_src==TRIG_FOLLOW)
+	else {
+		ui_DelayTime = cmd->scan_begin_arg & 0xFFFF;
+		ui_DelayTimeBase = cmd->scan_begin_arg >> 16;
+		ui_DelayMode = 1;
+	}			//else if(cmd->scan_begin_src==TRIG_FOLLOW)
+	//        printk("\nui_DelayTime=%u\n",ui_DelayTime);
+	//        printk("\nui_DelayTimeBase=%u\n",ui_DelayTimeBase);
+	if (cmd->convert_src == TRIG_TIMER) {
+		ui_ConvertTime = cmd->convert_arg & 0xFFFF;
+		ui_ConvertTimeBase = cmd->convert_arg >> 16;
+	} else {
+		ui_ConvertTime = 0;
+		ui_ConvertTimeBase = 0;
+	}
+
+	// if(i_ADDIDATAType ==1 || ((i_ADDIDATAType==2)))
+	//   {
+  /**************************************************/
+	/*Read the old configuration of the current source */
+  /**************************************************/
+	//ui_Configuration = inl(devpriv->iobase+i_Offset + 12);
+	ui_Configuration =
+		inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+  /***********************************************/
+	/*Write the configuration of the current source */
+  /***********************************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl((ui_Configuration & 0xFFC00000 ), devpriv->iobase+i_Offset +12);
+	outl((ui_Configuration & 0xFFC00000),
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+	// }
+	ui_Configuration = 0;
+	//     printk("\nfirstchannel=%u\n",i_FirstChannel);
+	//     printk("\nlastchannel=%u\n",i_LastChannel);
+	//     printk("\nui_Trigger=%u\n",ui_Trigger);
+	//     printk("\nui_TriggerEdge=%u\n",ui_TriggerEdge);
+	//     printk("\nui_Triggermode=%u\n",ui_Triggermode);
+	//      printk("\nui_DelayMode=%u\n",ui_DelayMode);
+	//     printk("\nui_ScanMode=%u\n",ui_ScanMode);
+
+	//ui_Configuration = i_FirstChannel |(i_LastChannel << 8)| 0x00100000 |
+	ui_Configuration =
+		s_BoardInfos[dev->minor].i_FirstChannel | (s_BoardInfos[dev->
+			minor].
+		i_LastChannel << 8) | 0x00100000 | (ui_Trigger << 24) |
+		(ui_TriggerEdge << 25) | (ui_Triggermode << 27) | (ui_DelayMode
+		<< 18) | (ui_ScanMode << 16);
+
+  /*************************/
+	/*Write the Configuration */
+  /*************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl( ui_Configuration, devpriv->iobase+i_Offset + 0x8);
+	outl(ui_Configuration,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x8);
+  /***********************/
+	/*Write the Delay Value */
+  /***********************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl(ui_DelayTime,devpriv->iobase+i_Offset + 40);
+	outl(ui_DelayTime,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 40);
+  /***************************/
+	/*Write the Delay time base */
+  /***************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl(ui_DelayTimeBase,devpriv->iobase+i_Offset + 44);
+	outl(ui_DelayTimeBase,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 44);
+  /*********************************/
+	/*Write the conversion time value */
+  /*********************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl(ui_ConvertTime,devpriv->iobase+i_Offset + 32);
+	outl(ui_ConvertTime,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+
+  /********************************/
+	/*Write the conversion time base */
+  /********************************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl(ui_ConvertTimeBase,devpriv->iobase+i_Offset + 36);
+	outl(ui_ConvertTimeBase,
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+  /*******************/
+	/*Read the register */
+  /*******************/
+	//ui_Configuration = inl(devpriv->iobase+i_Offset + 4);
+	ui_Configuration =
+		inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
+  /******************/
+	/*Set the SCAN bit */
+  /******************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+
+	//outl(((ui_Configuration & 0x1E0FF) | 0x00002000),devpriv->iobase+i_Offset + 4);
+	outl(((ui_Configuration & 0x1E0FF) | 0x00002000),
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
+  /*******************/
+	/*Read the register */
+  /*******************/
+	ui_Configuration = 0;
+	//ui_Configuration = inl(devpriv->iobase+i_Offset + 8);
+	ui_Configuration =
+		inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+
+  /*******************/
+	/*Set the START bit */
+  /*******************/
+	//while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+	while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+					12) >> 19) & 1) != 1) ;
+	//outl((ui_Configuration | 0x00080000),devpriv->iobase+i_Offset + 8);
+	outl((ui_Configuration | 0x00080000),
+		devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+	return 0;
+}
+
+/*
+  +----------------------------------------------------------------------------+
+  | Function   Name   :  int i_APCI3200_Reset(struct comedi_device *dev)			     |
+  |							                                         |
+  +----------------------------------------------------------------------------+
+  | Task              :Resets the registers of the card                        |
+  +----------------------------------------------------------------------------+
+  | Input Parameters  :                                                        |
+  +----------------------------------------------------------------------------+
+  | Output Parameters :	--													 |
+  +----------------------------------------------------------------------------+
+  | Return Value      :                                                        |
+  |					                                                 |
+  +----------------------------------------------------------------------------+
+*/
+
+int i_APCI3200_Reset(struct comedi_device * dev)
+{
+	INT i_Temp;
+	DWORD dw_Dummy;
+	//i_InterruptFlag=0;
+	//i_Initialised==0;
+	//i_Count=0;
+	//i_Sum=0;
+
+	s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+	s_BoardInfos[dev->minor].i_Initialised = 0;
+	s_BoardInfos[dev->minor].i_Count = 0;
+	s_BoardInfos[dev->minor].i_Sum = 0;
+	s_BoardInfos[dev->minor].b_StructInitialized = 0;
+
+	outl(0x83838383, devpriv->i_IobaseAmcc + 0x60);
+
+	// Enable the interrupt for the controler
+	dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38);
+	outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38);
+	outl(0, devpriv->i_IobaseAddon);	//Resets the output
+  /***************/
+	/*Empty the buffer */
+  /**************/
+	for (i_Temp = 0; i_Temp <= 95; i_Temp++) {
+		//ui_InterruptChannelValue[i_Temp]=0;
+		s_BoardInfos[dev->minor].ui_InterruptChannelValue[i_Temp] = 0;
+	}			//for(i_Temp=0;i_Temp<=95;i_Temp++)
+  /*****************************/
+	/*Reset the START and IRQ bit */
+  /*****************************/
+	for (i_Temp = 0; i_Temp <= 192;) {
+		while (((inl(devpriv->iobase + i_Temp + 12) >> 19) & 1) != 1) ;
+		outl(0, devpriv->iobase + i_Temp + 8);
+		i_Temp = i_Temp + 64;
+	}			//for(i_Temp=0;i_Temp<=192;i_Temp+64)
+	return 0;
+}
+
+/*
+  +----------------------------------------------------------------------------+
+  | Function   Name   : static void v_APCI3200_Interrupt					     |
+  |					  (int irq , void *d)				 |
+  +----------------------------------------------------------------------------+
+  | Task              : Interrupt processing Routine                           |
+  +----------------------------------------------------------------------------+
+  | Input Parameters  : int irq                 : irq number                   |
+  |                     void *d                 : void pointer                 |
+  +----------------------------------------------------------------------------+
+  | Output Parameters :	--													 |
+  +----------------------------------------------------------------------------+
+  | Return Value      : TRUE  : No error occur                                 |
+  |		            : FALSE : Error occur. Return the error					 |
+  |					                                                         |
+  +----------------------------------------------------------------------------+
+*/
+void v_APCI3200_Interrupt(int irq, void *d)
+{
+	struct comedi_device *dev = d;
+	UINT ui_StatusRegister = 0;
+	UINT ui_ChannelNumber = 0;
+	INT i_CalibrationFlag = 0;
+	INT i_CJCFlag = 0;
+	UINT ui_DummyValue = 0;
+	UINT ui_DigitalTemperature = 0;
+	UINT ui_DigitalInput = 0;
+	int i_ConvertCJCCalibration;
+
+	//BEGIN JK TEST
+	int i_ReturnValue = 0;
+	//END JK TEST
+
+	//printk ("\n i_ScanType = %i i_ADDIDATAType = %i", s_BoardInfos [dev->minor].i_ScanType, s_BoardInfos [dev->minor].i_ADDIDATAType);
+
+	//switch(i_ScanType)
+	switch (s_BoardInfos[dev->minor].i_ScanType) {
+	case 0:
+	case 1:
+		//switch(i_ADDIDATAType)
+		switch (s_BoardInfos[dev->minor].i_ADDIDATAType) {
+		case 0:
+		case 1:
+
+	  /************************************/
+			/*Read the interrupt status register */
+	  /************************************/
+			//ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16);
+			ui_StatusRegister =
+				inl(devpriv->iobase +
+				s_BoardInfos[dev->minor].i_Offset + 16);
+			if ((ui_StatusRegister & 0x2) == 0x2) {
+				//i_CalibrationFlag = ((inl(devpriv->iobase+i_Offset + 12) & 0x00060000) >> 17);
+				i_CalibrationFlag =
+					((inl(devpriv->iobase +
+							s_BoardInfos[dev->
+								minor].
+							i_Offset +
+							12) & 0x00060000) >>
+					17);
+	      /*************************/
+				/*Read the channel number */
+	      /*************************/
+				//ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24);
+
+	      /*************************************/
+				/*Read the digital analog input value */
+	      /*************************************/
+				//ui_DigitalInput = inl(devpriv->iobase+i_Offset + 28);
+				ui_DigitalInput =
+					inl(devpriv->iobase +
+					s_BoardInfos[dev->minor].i_Offset + 28);
+
+	      /***********************************************/
+				/* Test if the value read is the channel value */
+	      /***********************************************/
+				if (i_CalibrationFlag == 0) {
+					//ui_InterruptChannelValue[i_Count + 0] = ui_DigitalInput;
+					s_BoardInfos[dev->minor].
+						ui_InterruptChannelValue
+						[s_BoardInfos[dev->minor].
+						i_Count + 0] = ui_DigitalInput;
+
+					//Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+					/*
+					   printk("\n 1 - i_APCI3200_GetChannelCalibrationValue (dev, s_BoardInfos %i", ui_ChannelNumber);
+					   i_APCI3200_GetChannelCalibrationValue (dev, s_BoardInfos [dev->minor].ui_Channel_num,
+					   &s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 6],
+					   &s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 7],
+					   &s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 8]);
+					 */
+					//End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+		  /******************************************************/
+					/*Start the conversion of the calibration offset value */
+		  /******************************************************/
+					i_APCI3200_ReadCalibrationOffsetValue
+						(dev, &ui_DummyValue);
+				}	//if (i_CalibrationFlag == 0)
+	      /**********************************************************/
+				/* Test if the value read is the calibration offset value */
+	      /**********************************************************/
+
+				if (i_CalibrationFlag == 1) {
+
+		  /******************/
+					/* Save the value */
+		  /******************/
+
+					//ui_InterruptChannelValue[i_Count + 1] = ui_DigitalInput;
+					s_BoardInfos[dev->minor].
+						ui_InterruptChannelValue
+						[s_BoardInfos[dev->minor].
+						i_Count + 1] = ui_DigitalInput;
+
+		  /******************************************************/
+					/* Start the conversion of the calibration gain value */
+		  /******************************************************/
+					i_APCI3200_ReadCalibrationGainValue(dev,
+						&ui_DummyValue);
+				}	//if (i_CalibrationFlag == 1)
+	      /******************************************************/
+				/*Test if the value read is the calibration gain value */
+	      /******************************************************/
+
+				if (i_CalibrationFlag == 2) {
+
+		  /****************/
+					/*Save the value */
+		  /****************/
+					//ui_InterruptChannelValue[i_Count + 2] = ui_DigitalInput;
+					s_BoardInfos[dev->minor].
+						ui_InterruptChannelValue
+						[s_BoardInfos[dev->minor].
+						i_Count + 2] = ui_DigitalInput;
+					//if(i_ScanType==1)
+					if (s_BoardInfos[dev->minor].
+						i_ScanType == 1) {
+
+						//i_InterruptFlag=0;
+						s_BoardInfos[dev->minor].
+							i_InterruptFlag = 0;
+						//i_Count=i_Count + 6;
+						//Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+						//s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count + 6;
+						s_BoardInfos[dev->minor].
+							i_Count =
+							s_BoardInfos[dev->
+							minor].i_Count + 9;
+						//End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+					}	//if(i_ScanType==1)
+					else {
+						//i_Count=0;
+						s_BoardInfos[dev->minor].
+							i_Count = 0;
+					}	//elseif(i_ScanType==1)
+					//if(i_ScanType!=1)
+					if (s_BoardInfos[dev->minor].
+						i_ScanType != 1) {
+						i_ReturnValue = send_sig(SIGIO, devpriv->tsk_Current, 0);	// send signal to the sample
+					}	//if(i_ScanType!=1)
+					else {
+						//if(i_ChannelCount==i_Sum)
+						if (s_BoardInfos[dev->minor].
+							i_ChannelCount ==
+							s_BoardInfos[dev->
+								minor].i_Sum) {
+							send_sig(SIGIO, devpriv->tsk_Current, 0);	// send signal to the sample
+						}
+					}	//if(i_ScanType!=1)
+				}	//if (i_CalibrationFlag == 2)
+			}	// if ((ui_StatusRegister & 0x2) == 0x2)
+
+			break;
+
+		case 2:
+	  /************************************/
+			/*Read the interrupt status register */
+	  /************************************/
+
+			//ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16);
+			ui_StatusRegister =
+				inl(devpriv->iobase +
+				s_BoardInfos[dev->minor].i_Offset + 16);
+	  /*************************/
+			/*Test if interrupt occur */
+	  /*************************/
+
+			if ((ui_StatusRegister & 0x2) == 0x2) {
+
+				//i_CJCFlag = ((inl(devpriv->iobase+i_Offset + 4) & 0x00000400) >> 10);
+				i_CJCFlag =
+					((inl(devpriv->iobase +
+							s_BoardInfos[dev->
+								minor].
+							i_Offset +
+							4) & 0x00000400) >> 10);
+
+				//i_CalibrationFlag = ((inl(devpriv->iobase+i_Offset + 12) & 0x00060000) >> 17);
+				i_CalibrationFlag =
+					((inl(devpriv->iobase +
+							s_BoardInfos[dev->
+								minor].
+							i_Offset +
+							12) & 0x00060000) >>
+					17);
+
+	      /*************************/
+				/*Read the channel number */
+	      /*************************/
+
+				//ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24);
+				ui_ChannelNumber =
+					inl(devpriv->iobase +
+					s_BoardInfos[dev->minor].i_Offset + 24);
+				//Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+				s_BoardInfos[dev->minor].ui_Channel_num =
+					ui_ChannelNumber;
+				//End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+	      /************************************/
+				/*Read the digital temperature value */
+	      /************************************/
+				//ui_DigitalTemperature = inl(devpriv->iobase+i_Offset + 28);
+				ui_DigitalTemperature =
+					inl(devpriv->iobase +
+					s_BoardInfos[dev->minor].i_Offset + 28);
+
+	      /*********************************************/
+				/*Test if the value read is the channel value */
+	      /*********************************************/
+
+				if ((i_CalibrationFlag == 0)
+					&& (i_CJCFlag == 0)) {
+					//ui_InterruptChannelValue[i_Count + 0]=ui_DigitalTemperature;
+					s_BoardInfos[dev->minor].
+						ui_InterruptChannelValue
+						[s_BoardInfos[dev->minor].
+						i_Count + 0] =
+						ui_DigitalTemperature;
+
+		  /*********************************/
+					/*Start the conversion of the CJC */
+		  /*********************************/
+					i_APCI3200_ReadCJCValue(dev,
+						&ui_DummyValue);
+
+				}	//if ((i_CalibrationFlag == 0) && (i_CJCFlag == 0))
+
+		 /*****************************************/
+				/*Test if the value read is the CJC value */
+		 /*****************************************/
+
+				if ((i_CJCFlag == 1)
+					&& (i_CalibrationFlag == 0)) {
+					//ui_InterruptChannelValue[i_Count + 3]=ui_DigitalTemperature;
+					s_BoardInfos[dev->minor].
+						ui_InterruptChannelValue
+						[s_BoardInfos[dev->minor].
+						i_Count + 3] =
+						ui_DigitalTemperature;
+
+		  /******************************************************/
+					/*Start the conversion of the calibration offset value */
+		  /******************************************************/
+					i_APCI3200_ReadCalibrationOffsetValue
+						(dev, &ui_DummyValue);
+				}	// if ((i_CJCFlag == 1) && (i_CalibrationFlag == 0))
+
+		 /********************************************************/
+				/*Test if the value read is the calibration offset value */
+		 /********************************************************/
+
+				if ((i_CalibrationFlag == 1)
+					&& (i_CJCFlag == 0)) {
+					//ui_InterruptChannelValue[i_Count + 1]=ui_DigitalTemperature;
+					s_BoardInfos[dev->minor].
+						ui_InterruptChannelValue
+						[s_BoardInfos[dev->minor].
+						i_Count + 1] =
+						ui_DigitalTemperature;
+
+		  /****************************************************/
+					/*Start the conversion of the calibration gain value */
+		  /****************************************************/
+					i_APCI3200_ReadCalibrationGainValue(dev,
+						&ui_DummyValue);
+
+				}	//if ((i_CalibrationFlag == 1) && (i_CJCFlag == 0))
+
+	      /******************************************************/
+				/*Test if the value read is the calibration gain value */
+	      /******************************************************/
+
+				if ((i_CalibrationFlag == 2)
+					&& (i_CJCFlag == 0)) {
+					//ui_InterruptChannelValue[i_Count + 2]=ui_DigitalTemperature;
+					s_BoardInfos[dev->minor].
+						ui_InterruptChannelValue
+						[s_BoardInfos[dev->minor].
+						i_Count + 2] =
+						ui_DigitalTemperature;
+
+		  /**********************************************************/
+					/*Test if the Calibration channel must be read for the CJC */
+		  /**********************************************************/
+
+					/*Test if the polarity is the same */
+		  /**********************************/
+					//if(i_CJCPolarity!=i_ADDIDATAPolarity)
+					if (s_BoardInfos[dev->minor].
+						i_CJCPolarity !=
+						s_BoardInfos[dev->minor].
+						i_ADDIDATAPolarity) {
+						i_ConvertCJCCalibration = 1;
+					}	//if(i_CJCPolarity!=i_ADDIDATAPolarity)
+					else {
+						//if(i_CJCGain==i_ADDIDATAGain)
+						if (s_BoardInfos[dev->minor].
+							i_CJCGain ==
+							s_BoardInfos[dev->
+								minor].
+							i_ADDIDATAGain) {
+							i_ConvertCJCCalibration
+								= 0;
+						}	//if(i_CJCGain==i_ADDIDATAGain)
+						else {
+							i_ConvertCJCCalibration
+								= 1;
+						}	//elseif(i_CJCGain==i_ADDIDATAGain)
+					}	//elseif(i_CJCPolarity!=i_ADDIDATAPolarity)
+					if (i_ConvertCJCCalibration == 1) {
+		      /****************************************************************/
+						/*Start the conversion of the calibration gain value for the CJC */
+		      /****************************************************************/
+						i_APCI3200_ReadCJCCalOffset(dev,
+							&ui_DummyValue);
+
+					}	//if(i_ConvertCJCCalibration==1)
+					else {
+						//ui_InterruptChannelValue[i_Count + 4]=0;
+						//ui_InterruptChannelValue[i_Count + 5]=0;
+						s_BoardInfos[dev->minor].
+							ui_InterruptChannelValue
+							[s_BoardInfos[dev->
+								minor].i_Count +
+							4] = 0;
+						s_BoardInfos[dev->minor].
+							ui_InterruptChannelValue
+							[s_BoardInfos[dev->
+								minor].i_Count +
+							5] = 0;
+					}	//elseif(i_ConvertCJCCalibration==1)
+				}	//else if ((i_CalibrationFlag == 2) && (i_CJCFlag == 0))
+
+		 /********************************************************************/
+				/*Test if the value read is the calibration offset value for the CJC */
+		 /********************************************************************/
+
+				if ((i_CalibrationFlag == 1)
+					&& (i_CJCFlag == 1)) {
+					//ui_InterruptChannelValue[i_Count + 4]=ui_DigitalTemperature;
+					s_BoardInfos[dev->minor].
+						ui_InterruptChannelValue
+						[s_BoardInfos[dev->minor].
+						i_Count + 4] =
+						ui_DigitalTemperature;
+
+		  /****************************************************************/
+					/*Start the conversion of the calibration gain value for the CJC */
+		  /****************************************************************/
+					i_APCI3200_ReadCJCCalGain(dev,
+						&ui_DummyValue);
+
+				}	//if ((i_CalibrationFlag == 1) && (i_CJCFlag == 1))
+
+	      /******************************************************************/
+				/*Test if the value read is the calibration gain value for the CJC */
+	      /******************************************************************/
+
+				if ((i_CalibrationFlag == 2)
+					&& (i_CJCFlag == 1)) {
+					//ui_InterruptChannelValue[i_Count + 5]=ui_DigitalTemperature;
+					s_BoardInfos[dev->minor].
+						ui_InterruptChannelValue
+						[s_BoardInfos[dev->minor].
+						i_Count + 5] =
+						ui_DigitalTemperature;
+
+					//if(i_ScanType==1)
+					if (s_BoardInfos[dev->minor].
+						i_ScanType == 1) {
+
+						//i_InterruptFlag=0;
+						s_BoardInfos[dev->minor].
+							i_InterruptFlag = 0;
+						//i_Count=i_Count + 6;
+						//Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+						//s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count + 6;
+						s_BoardInfos[dev->minor].
+							i_Count =
+							s_BoardInfos[dev->
+							minor].i_Count + 9;
+						//End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+					}	//if(i_ScanType==1)
+					else {
+						//i_Count=0;
+						s_BoardInfos[dev->minor].
+							i_Count = 0;
+					}	//elseif(i_ScanType==1)
+
+					//if(i_ScanType!=1)
+					if (s_BoardInfos[dev->minor].
+						i_ScanType != 1) {
+						send_sig(SIGIO, devpriv->tsk_Current, 0);	// send signal to the sample
+					}	//if(i_ScanType!=1)
+					else {
+						//if(i_ChannelCount==i_Sum)
+						if (s_BoardInfos[dev->minor].
+							i_ChannelCount ==
+							s_BoardInfos[dev->
+								minor].i_Sum) {
+							send_sig(SIGIO, devpriv->tsk_Current, 0);	// send signal to the sample
+
+						}	//if(i_ChannelCount==i_Sum)
+					}	//else if(i_ScanType!=1)
+				}	//if ((i_CalibrationFlag == 2) && (i_CJCFlag == 1))
+
+			}	//else if ((ui_StatusRegister & 0x2) == 0x2)
+			break;
+		}		//switch(i_ADDIDATAType)
+		break;
+	case 2:
+	case 3:
+		i_APCI3200_InterruptHandleEos(dev);
+		break;
+	}			//switch(i_ScanType)
+	return;
+}
+
+/*
+  +----------------------------------------------------------------------------+
+  | Function name     :int i_APCI3200_InterruptHandleEos(struct comedi_device *dev)   |
+  |                                        									 |
+  |                                            						         |
+  +----------------------------------------------------------------------------+
+  | Task              : .                   |
+  |                     This function copies the acquired data(from FIFO)      |
+  |				to Comedi buffer.		 							 |
+  |                     										                 |
+  +----------------------------------------------------------------------------+
+  | Input Parameters  : struct comedi_device *dev									 |
+  |                     														 |
+  |                                                 					         |
+  +----------------------------------------------------------------------------+
+  | Return Value      : 0            					                         |
+  |                    													     |
+  +----------------------------------------------------------------------------+
+*/
+int i_APCI3200_InterruptHandleEos(struct comedi_device * dev)
+{
+	UINT ui_StatusRegister = 0;
+	struct comedi_subdevice *s = dev->subdevices + 0;
+
+	//BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+	//comedi_async *async = s->async;
+	//UINT *data;
+	//data=async->data+async->buf_int_ptr;//new samples added from here onwards
+	int n = 0, i = 0;
+	//END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+
+  /************************************/
+	/*Read the interrupt status register */
+  /************************************/
+	//ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16);
+	ui_StatusRegister =
+		inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 16);
+
+  /*************************/
+	/*Test if interrupt occur */
+  /*************************/
+
+	if ((ui_StatusRegister & 0x2) == 0x2) {
+      /*************************/
+		/*Read the channel number */
+      /*************************/
+		//ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24);
+		//BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+		//This value is not used
+		//ui_ChannelNumber = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 24);
+		s->async->events = 0;
+		//END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+
+      /*************************************/
+		/*Read the digital Analog Input value */
+      /*************************************/
+
+		//data[i_Count] = inl(devpriv->iobase+i_Offset + 28);
+		//Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+		//data[s_BoardInfos [dev->minor].i_Count] = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 28);
+		s_BoardInfos[dev->minor].ui_ScanValueArray[s_BoardInfos[dev->
+				minor].i_Count] =
+			inl(devpriv->iobase +
+			s_BoardInfos[dev->minor].i_Offset + 28);
+		//End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+
+		//if((i_Count == (i_LastChannel-i_FirstChannel+3)))
+		if ((s_BoardInfos[dev->minor].i_Count ==
+				(s_BoardInfos[dev->minor].i_LastChannel -
+					s_BoardInfos[dev->minor].
+					i_FirstChannel + 3))) {
+
+			//Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+			s_BoardInfos[dev->minor].i_Count++;
+
+			for (i = s_BoardInfos[dev->minor].i_FirstChannel;
+				i <= s_BoardInfos[dev->minor].i_LastChannel;
+				i++) {
+				i_APCI3200_GetChannelCalibrationValue(dev, i,
+					&s_BoardInfos[dev->minor].
+					ui_ScanValueArray[s_BoardInfos[dev->
+							minor].i_Count + ((i -
+								s_BoardInfos
+								[dev->minor].
+								i_FirstChannel)
+							* 3)],
+					&s_BoardInfos[dev->minor].
+					ui_ScanValueArray[s_BoardInfos[dev->
+							minor].i_Count + ((i -
+								s_BoardInfos
+								[dev->minor].
+								i_FirstChannel)
+							* 3) + 1],
+					&s_BoardInfos[dev->minor].
+					ui_ScanValueArray[s_BoardInfos[dev->
+							minor].i_Count + ((i -
+								s_BoardInfos
+								[dev->minor].
+								i_FirstChannel)
+							* 3) + 2]);
+			}
+
+			//End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+			//i_Count=-1;
+
+			s_BoardInfos[dev->minor].i_Count = -1;
+
+			//async->buf_int_count+=(i_LastChannel-i_FirstChannel+4)*sizeof(UINT);
+			//Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+			//async->buf_int_count+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(UINT);
+			//End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+			//async->buf_int_ptr+=(i_LastChannel-i_FirstChannel+4)*sizeof(UINT);
+			//Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+			//async->buf_int_ptr+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(UINT);
+			//comedi_eos(dev,s);
+
+			// Set the event type (Comedi Buffer End Of Scan)
+			s->async->events |= COMEDI_CB_EOS;
+
+			// Test if enougth memory is available and allocate it for 7 values
+			//n = comedi_buf_write_alloc(s->async, 7*sizeof(unsigned int));
+			n = comedi_buf_write_alloc(s->async,
+				(7 + 12) * sizeof(unsigned int));
+
+			// If not enougth memory available, event is set to Comedi Buffer Errror
+			if (n > ((7 + 12) * sizeof(unsigned int))) {
+				printk("\ncomedi_buf_write_alloc n = %i", n);
+				s->async->events |= COMEDI_CB_ERROR;
+			}
+			// Write all 7 scan values in the comedi buffer
+			comedi_buf_memcpy_to(s->async, 0,
+				(unsigned int *) s_BoardInfos[dev->minor].
+				ui_ScanValueArray, (7 + 12) * sizeof(unsigned int));
+
+			// Update comedi buffer pinters indexes
+			comedi_buf_write_free(s->async,
+				(7 + 12) * sizeof(unsigned int));
+
+			// Send events
+			comedi_event(dev, s);
+			//End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+
+			//BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+			//
+			//if (s->async->buf_int_ptr>=s->async->data_len) //  for buffer rool over
+			//  {
+			//    /* buffer rollover */
+			//    s->async->buf_int_ptr=0;
+			//    comedi_eobuf(dev,s);
+			//  }
+			//End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+		}
+		//i_Count++;
+		s_BoardInfos[dev->minor].i_Count++;
+	}
+	//i_InterruptFlag=0;
+	s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h
new file mode 100644
index 0000000..a6f57f5
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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.
+ */
+
+// Card Specific information
+#define APCI3200_BOARD_VENDOR_ID                 0x15B8
+//#define APCI3200_ADDRESS_RANGE                   264
+
+int MODULE_NO;
+struct {
+	INT i_Gain;
+	INT i_Polarity;
+	INT i_OffsetRange;
+	INT i_Coupling;
+	INT i_SingleDiff;
+	INT i_AutoCalibration;
+	UINT ui_ReloadValue;
+	UINT ui_TimeUnitReloadVal;
+	INT i_Interrupt;
+	INT i_ModuleSelection;
+} Config_Parameters_Module1, Config_Parameters_Module2,
+    Config_Parameters_Module3, Config_Parameters_Module4;
+
+//ANALOG INPUT RANGE
+static const struct comedi_lrange range_apci3200_ai = { 8, {
+						     BIP_RANGE(10),
+						     BIP_RANGE(5),
+						     BIP_RANGE(2),
+						     BIP_RANGE(1),
+						     UNI_RANGE(10),
+						     UNI_RANGE(5),
+						     UNI_RANGE(2),
+						     UNI_RANGE(1)
+						     }
+};
+
+static const struct comedi_lrange range_apci3300_ai = { 4, {
+						     UNI_RANGE(10),
+						     UNI_RANGE(5),
+						     UNI_RANGE(2),
+						     UNI_RANGE(1)
+						     }
+};
+
+//Analog Input related Defines
+#define APCI3200_AI_OFFSET_GAIN                  0
+#define APCI3200_AI_SC_TEST                      4
+#define APCI3200_AI_IRQ                          8
+#define APCI3200_AI_AUTOCAL                      12
+#define APCI3200_RELOAD_CONV_TIME_VAL            32
+#define APCI3200_CONV_TIME_TIME_BASE             36
+#define APCI3200_RELOAD_DELAY_TIME_VAL           40
+#define APCI3200_DELAY_TIME_TIME_BASE            44
+#define APCI3200_AI_MODULE1                      0
+#define APCI3200_AI_MODULE2                      64
+#define APCI3200_AI_MODULE3                      128
+#define APCI3200_AI_MODULE4                      192
+#define TRUE                                     1
+#define FALSE                                    0
+#define APCI3200_AI_EOSIRQ                       16
+#define APCI3200_AI_EOS                          20
+#define APCI3200_AI_CHAN_ID                      24
+#define APCI3200_AI_CHAN_VAL                     28
+#define ANALOG_INPUT                             0
+#define TEMPERATURE                              1
+#define RESISTANCE                               2
+
+#define ENABLE_EXT_TRIG                          1
+#define ENABLE_EXT_GATE                          2
+#define ENABLE_EXT_TRIG_GATE                     3
+
+#define APCI3200_MAXVOLT                         2.5
+#define ADDIDATA_GREATER_THAN_TEST               0
+#define ADDIDATA_LESS_THAN_TEST                  1
+
+#define ADDIDATA_UNIPOLAR                        1
+#define ADDIDATA_BIPOLAR                         2
+
+//BEGIN JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+#define MAX_MODULE				4
+//END JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+typedef struct {
+	ULONG ul_NumberOfValue;
+	ULONG *pul_ResistanceValue;
+	ULONG *pul_TemperatureValue;
+} str_ADDIDATA_RTDStruct, *pstr_ADDIDATA_RTDStruct;
+
+//BEGIN JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+typedef struct {
+	// Begin JK 05/08/2003 change for Linux
+	unsigned long ul_CurrentSourceCJC;
+	unsigned long ul_CurrentSource[5];
+	// End JK 05/08/2003 change for Linux
+
+	// Begin CG 15/02/02 Rev 1.0 -> Rev 1.1 : Add Header Type 1
+	unsigned long ul_GainFactor[8];	// Gain Factor
+	unsigned int w_GainValue[10];
+	// End CG 15/02/02 Rev 1.0 -> Rev 1.1 : Add Header Type 1
+} str_Module;
+//END JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+//BEGIN JK 06.07.04: Management of sevrals boards
+typedef struct {
+	INT i_CJCAvailable;
+	INT i_CJCPolarity;
+	INT i_CJCGain;
+	INT i_InterruptFlag;
+	INT i_ADDIDATAPolarity;
+	INT i_ADDIDATAGain;
+	INT i_AutoCalibration;
+	INT i_ADDIDATAConversionTime;
+	INT i_ADDIDATAConversionTimeUnit;
+	INT i_ADDIDATAType;
+	INT i_ChannelNo;
+	INT i_ChannelCount;
+	INT i_ScanType;
+	INT i_FirstChannel;
+	INT i_LastChannel;
+	INT i_Sum;
+	INT i_Offset;
+	UINT ui_Channel_num;
+	INT i_Count;
+	INT i_Initialised;
+	//UINT ui_InterruptChannelValue[96]; //Buffer
+	UINT ui_InterruptChannelValue[144];	//Buffer
+	BYTE b_StructInitialized;
+	//Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+	unsigned int ui_ScanValueArray[7 + 12];	// 7 is the maximal number of channels
+	//End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+
+	//Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+	INT i_ConnectionType;
+	INT i_NbrOfModule;
+	str_Module s_Module[MAX_MODULE];
+	//End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+} str_BoardInfos;
+//END JK 06.07.04: Management of sevrals boards
+
+// Hardware Layer  functions for Apci3200
+
+//AI
+
+INT i_APCI3200_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data);
+INT i_APCI3200_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
+			       struct comedi_insn *insn, unsigned int *data);
+INT i_APCI3200_InsnWriteReleaseAnalogInput(struct comedi_device *dev,
+					   struct comedi_subdevice *s,
+					   struct comedi_insn *insn, unsigned int *data);
+INT i_APCI3200_InsnBits_AnalogInput_Test(struct comedi_device *dev,
+					 struct comedi_subdevice *s,
+					 struct comedi_insn *insn, unsigned int *data);
+INT i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s);
+INT i_APCI3200_InterruptHandleEos(struct comedi_device *dev);
+INT i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
+				      struct comedi_cmd *cmd);
+INT i_APCI3200_CommandAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s);
+INT i_APCI3200_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data);
+//Interrupt
+void v_APCI3200_Interrupt(int irq, void *d);
+int i_APCI3200_InterruptHandleEos(struct comedi_device *dev);
+//Reset functions
+INT i_APCI3200_Reset(struct comedi_device *dev);
+
+int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev, unsigned int *data);
+int i_APCI3200_ReadCJCValue(struct comedi_device *dev, unsigned int *data);
+int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev, UINT *data);
+int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev, UINT *data);
+int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev,
+				       struct comedi_subdevice *s, struct comedi_insn *insn,
+				       unsigned int *data);
+int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev, unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
new file mode 100644
index 0000000..20391a9
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
@@ -0,0 +1,742 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+
+        ADDI-DATA GmbH
+        Dieselstrasse 3
+        D-77833 Ottersweier
+        Tel: +19(0)7223/9493-0
+        Fax: +49(0)7223/9493-92
+        http://www.addi-data-com
+        info@addi-data.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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*.
+
+  +-----------------------------------------------------------------------+
+  | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
+  +-----------------------------------------------------------------------+
+  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
+  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
+  +-------------------------------+---------------------------------------+
+  | Project     : APCI-3501       | Compiler   : GCC                      |
+  | Module name : hwdrv_apci3501.c| Version    : 2.96                     |
+  +-------------------------------+---------------------------------------+
+  | Project manager: Eric Stolz   | Date       :  02/12/2002              |
+  +-------------------------------+---------------------------------------+
+  | Description :   Hardware Layer Acces For APCI-3501                    |
+  +-----------------------------------------------------------------------+
+  |                             UPDATES                                   |
+  +----------+-----------+------------------------------------------------+
+  |   Date   |   Author  |          Description of updates                |
+  +----------+-----------+------------------------------------------------+
+  |          |           |                                                |
+  |          |           |                                                |
+  |          |           |                                                |
+  +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+|                               Included files                               |
++----------------------------------------------------------------------------+
+*/
+#include "hwdrv_apci3501.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI3501_ReadDigitalInput                    |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Read  value  of the selected channel or port           |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                     UINT ui_NoOfChannels    : No Of Channels To read       |
+|                     UINT *data              : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI3501_ReadDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_Temp;
+	UINT ui_NoOfChannel;
+	ui_NoOfChannel = CR_CHAN(insn->chanspec);
+	ui_Temp = data[0];
+	*data = inl(devpriv->iobase + APCI3501_DIGITAL_IP);
+	if (ui_Temp == 0) {
+		*data = (*data >> ui_NoOfChannel) & 0x1;
+	}			//if  (ui_Temp==0)
+	else {
+		if (ui_Temp == 1) {
+
+			*data = *data & 0x3;
+		}		//if  (ui_Temp==1)
+		else {
+			printk("\nSpecified channel not supported \n");
+		}		//elseif  (ui_Temp==1)
+	}			//elseif  (ui_Temp==0)
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI3501_ConfigDigitalOutput                     |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Configures The Digital Output Subdevice.               |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev : Driver handle                     |
+|                     UINT *data         : Data Pointer contains             |
+|                                          configuration parameters as below |
+|                                                                            |
+|					  data[1]            : 1 Enable  VCC  Interrupt  |
+|										   0 Disable VCC  Interrupt  |
+|					  data[2]            : 1 Enable  CC  Interrupt   |
+|										   0 Disable CC  Interrupt   |
+|																	 |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+int i_APCI3501_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+
+	if ((data[0] != 0) && (data[0] != 1)) {
+		comedi_error(dev,
+			"Not a valid Data !!! ,Data should be 1 or 0\n");
+		return -EINVAL;
+	}			//if  ( (data[0]!=0) && (data[0]!=1) )
+	if (data[0]) {
+		devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
+	}			// if  (data[0])
+	else {
+		devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
+	}			//else if  (data[0])
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI3501_WriteDigitalOutput                      |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : writes To the digital Output Subdevice                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                     struct comedi_subdevice *s     : Subdevice Pointer            |
+|                     struct comedi_insn *insn       : Insn Structure Pointer       |
+|                     unsigned int *data          : Data Pointer contains        |
+|                                          configuration parameters as below |
+|                                                                            |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI3501_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_Temp, ui_Temp1;
+	UINT ui_NoOfChannel = CR_CHAN(insn->chanspec);	// get the channel
+	if (devpriv->b_OutputMemoryStatus) {
+		ui_Temp = inl(devpriv->iobase + APCI3501_DIGITAL_OP);
+	}			//if(devpriv->b_OutputMemoryStatus )
+	else {
+		ui_Temp = 0;
+	}			//if(devpriv->b_OutputMemoryStatus )
+	if (data[3] == 0) {
+		if (data[1] == 0) {
+			data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
+			outl(data[0], devpriv->iobase + APCI3501_DIGITAL_OP);
+		}		//if(data[1]==0)
+		else {
+			if (data[1] == 1) {
+				data[0] = (data[0] << (2 * data[2])) | ui_Temp;
+				outl(data[0],
+					devpriv->iobase + APCI3501_DIGITAL_OP);
+			}	// if(data[1]==1)
+			else {
+				printk("\nSpecified channel not supported\n");
+			}	//else if(data[1]==1)
+		}		//elseif(data[1]==0)
+	}			//if(data[3]==0)
+	else {
+		if (data[3] == 1) {
+			if (data[1] == 0) {
+				data[0] = ~data[0] & 0x1;
+				ui_Temp1 = 1;
+				ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+				ui_Temp = ui_Temp | ui_Temp1;
+				data[0] =
+					(data[0] << ui_NoOfChannel) ^
+					0xffffffff;
+				data[0] = data[0] & ui_Temp;
+				outl(data[0],
+					devpriv->iobase + APCI3501_DIGITAL_OP);
+			}	//if(data[1]==0)
+			else {
+				if (data[1] == 1) {
+					data[0] = ~data[0] & 0x3;
+					ui_Temp1 = 3;
+					ui_Temp1 = ui_Temp1 << 2 * data[2];
+					ui_Temp = ui_Temp | ui_Temp1;
+					data[0] =
+						((data[0] << (2 *
+								data[2])) ^
+						0xffffffff) & ui_Temp;
+					outl(data[0],
+						devpriv->iobase +
+						APCI3501_DIGITAL_OP);
+				}	// if(data[1]==1)
+				else {
+					printk("\nSpecified channel not supported\n");
+				}	//else if(data[1]==1)
+			}	//elseif(data[1]==0)
+		}		//if(data[3]==1);
+		else {
+			printk("\nSpecified functionality does not exist\n");
+			return -EINVAL;
+		}		//if else data[3]==1)
+	}			//if else data[3]==0)
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI3501_ReadDigitalOutput                       |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Read  value  of the selected channel or port           |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                     UINT ui_NoOfChannels    : No Of Channels To read       |
+|                     UINT *data              : Data Pointer to read status  |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI3501_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	UINT ui_Temp;
+	UINT ui_NoOfChannel;
+
+	ui_NoOfChannel = CR_CHAN(insn->chanspec);
+	ui_Temp = data[0];
+	*data = inl(devpriv->iobase + APCI3501_DIGITAL_OP);
+	if (ui_Temp == 0) {
+		*data = (*data >> ui_NoOfChannel) & 0x1;
+	}			// if  (ui_Temp==0)
+	else {
+		if (ui_Temp == 1) {
+			*data = *data & 0x3;
+
+		}		// if  (ui_Temp==1)
+		else {
+			printk("\nSpecified channel not supported \n");
+		}		// else if (ui_Temp==1)
+	}			// else if  (ui_Temp==0)
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI3501_ConfigAnalogOutput                      |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Configures The Analog Output Subdevice                 |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                     struct comedi_subdevice *s     : Subdevice Pointer            |
+|                     struct comedi_insn *insn       : Insn Structure Pointer       |
+|                     unsigned int *data          : Data Pointer contains        |
+|                                          configuration parameters as below |
+|                                                                            |
+|					data[0]            : Voltage Mode                |
+|                                                0:Mode 0                    |
+|                                                1:Mode 1                    |
+|                                                                            |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI3501_ConfigAnalogOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	outl(data[0],
+		devpriv->iobase + APCI3501_ANALOG_OUTPUT +
+		APCI3501_AO_VOLT_MODE);
+
+	if (data[0]) {
+		devpriv->b_InterruptMode = MODE1;
+	} else {
+		devpriv->b_InterruptMode = MODE0;
+	}
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI3501_WriteAnalogOutput                       |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Writes To the Selected Anlog Output Channel            |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev      : Driver handle                |
+|                     struct comedi_subdevice *s     : Subdevice Pointer            |
+|                     struct comedi_insn *insn       : Insn Structure Pointer       |
+|                     unsigned int *data          : Data Pointer contains        |
+|                                          configuration parameters as below |
+|                                                                            |
+|                                                                            |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI3501_WriteAnalogOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	ULONG ul_Command1 = 0, ul_Channel_no, ul_Polarity, ul_DAC_Ready = 0;;
+
+	ul_Channel_no = CR_CHAN(insn->chanspec);
+
+	if (devpriv->b_InterruptMode == MODE1) {
+		ul_Polarity = 0x80000000;
+		if ((*data < 0) || (*data > 16384)) {
+			printk("\nIn WriteAnalogOutput :: Not Valid Data\n");
+		}
+
+	}			// end if(devpriv->b_InterruptMode==MODE1)
+	else {
+		ul_Polarity = 0;
+		if ((*data < 0) || (*data > 8192)) {
+			printk("\nIn WriteAnalogOutput :: Not Valid Data\n");
+		}
+
+	}			// end else
+
+	if ((ul_Channel_no < 0) || (ul_Channel_no > 7)) {
+		printk("\nIn WriteAnalogOutput :: Not Valid Channel\n");
+	}			// end if((ul_Channel_no<0)||(ul_Channel_no>7))
+
+	ul_DAC_Ready = inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT);
+
+	while (ul_DAC_Ready == 0) {
+		ul_DAC_Ready = inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT);
+		ul_DAC_Ready = (ul_DAC_Ready >> 8) & 1;
+	}
+
+	if (ul_DAC_Ready) {
+// Output the Value on the output channels.
+		ul_Command1 =
+			(ULONG) ((ULONG) (ul_Channel_no & 0xFF) |
+			(ULONG) ((*data << 0x8) & 0x7FFFFF00L) |
+			(ULONG) (ul_Polarity));
+		outl(ul_Command1,
+			devpriv->iobase + APCI3501_ANALOG_OUTPUT +
+			APCI3501_AO_PROG);
+	}
+
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI3501_ConfigTimerCounterWatchdog              |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Configures The Timer , Counter or Watchdog             |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev : Driver handle                     |
+|                     UINT *data         : Data Pointer contains             |
+|                                          configuration parameters as below |
+|                                                                            |
+|					  data[0]            : 0 Configure As Timer      |
+|										   1 Configure As Counter    |
+|										   2 Configure As Watchdog   |
+|					  data[1]            : 1 Enable  Interrupt       |
+|										   0 Disable Interrupt 	     |
+|					  data[2]            : Time Unit                 |
+|					  data[3]			 : Reload Value			     |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI3501_ConfigTimerCounterWatchdog(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	ULONG ul_Command1 = 0;
+	devpriv->tsk_Current = current;
+	if (data[0] == ADDIDATA_WATCHDOG) {
+
+		devpriv->b_TimerSelectMode = ADDIDATA_WATCHDOG;
+		//Disable the watchdog
+		outl(0x0, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);	//disable Wa
+
+		if (data[1] == 1) {
+			//Enable TIMER int & DISABLE ALL THE OTHER int SOURCES
+			outl(0x02,
+				devpriv->iobase + APCI3501_WATCHDOG +
+				APCI3501_TCW_PROG);
+		} else {
+			outl(0x0, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);	//disable Timer interrupt
+		}
+
+		//Loading the Timebase value
+		outl(data[2],
+			devpriv->iobase + APCI3501_WATCHDOG +
+			APCI3501_TCW_TIMEBASE);
+
+		//Loading the Reload value
+		outl(data[3],
+			devpriv->iobase + APCI3501_WATCHDOG +
+			APCI3501_TCW_RELOAD_VALUE);
+		//Set the mode
+		ul_Command1 = inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG) | 0xFFF819E0UL;	//e2->e0
+		outl(ul_Command1,
+			devpriv->iobase + APCI3501_WATCHDOG +
+			APCI3501_TCW_PROG);
+	}			//end if(data[0]==ADDIDATA_WATCHDOG)
+
+	else if (data[0] == ADDIDATA_TIMER) {
+		//First Stop The Timer
+		ul_Command1 =
+			inl(devpriv->iobase + APCI3501_WATCHDOG +
+			APCI3501_TCW_PROG);
+		ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
+		outl(ul_Command1, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);	//Stop The Timer
+		devpriv->b_TimerSelectMode = ADDIDATA_TIMER;
+		if (data[1] == 1) {
+			//Enable TIMER int & DISABLE ALL THE OTHER int SOURCES
+			outl(0x02,
+				devpriv->iobase + APCI3501_WATCHDOG +
+				APCI3501_TCW_PROG);
+		} else {
+			outl(0x0, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);	//disable Timer interrupt
+		}
+
+		// Loading Timebase
+		outl(data[2],
+			devpriv->iobase + APCI3501_WATCHDOG +
+			APCI3501_TCW_TIMEBASE);
+
+		//Loading the Reload value
+		outl(data[3],
+			devpriv->iobase + APCI3501_WATCHDOG +
+			APCI3501_TCW_RELOAD_VALUE);
+
+		// printk ("\nTimer Address :: %x\n", (devpriv->iobase+APCI3501_WATCHDOG));
+		ul_Command1 =
+			inl(devpriv->iobase + APCI3501_WATCHDOG +
+			APCI3501_TCW_PROG);
+		ul_Command1 =
+			(ul_Command1 & 0xFFF719E2UL) | 2UL << 13UL | 0x10UL;
+		outl(ul_Command1, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);	//mode 2
+
+	}			//end if(data[0]==ADDIDATA_TIMER)
+
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI3501_StartStopWriteTimerCounterWatchdog      |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Start / Stop The Selected Timer , Counter or Watchdog  |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev : Driver handle                     |
+|                     UINT *data         : Data Pointer contains             |
+|                                          configuration parameters as below |
+|                                                                            |
+|					  data[0]            : 0 Timer                   |
+|										   1 Counter                 |
+|										   2 Watchdog          		 |                             |            				 data[1]            : 1 Start                   |
+|										   0 Stop      				 |									                                              2 Trigger                 |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3501_StartStopWriteTimerCounterWatchdog(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	ULONG ul_Command1 = 0;
+	int i_Temp;
+	if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
+
+		if (data[1] == 1) {
+			ul_Command1 =
+				inl(devpriv->iobase + APCI3501_WATCHDOG +
+				APCI3501_TCW_PROG);
+			ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
+			//Enable the Watchdog
+			outl(ul_Command1,
+				devpriv->iobase + APCI3501_WATCHDOG +
+				APCI3501_TCW_PROG);
+		}
+
+		else if (data[1] == 0)	//Stop The Watchdog
+		{
+			//Stop The Watchdog
+			ul_Command1 =
+				inl(devpriv->iobase + APCI3501_WATCHDOG +
+				APCI3501_TCW_PROG);
+			ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
+			outl(0x0,
+				devpriv->iobase + APCI3501_WATCHDOG +
+				APCI3501_TCW_PROG);
+		} else if (data[1] == 2) {
+			ul_Command1 =
+				inl(devpriv->iobase + APCI3501_WATCHDOG +
+				APCI3501_TCW_PROG);
+			ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x200UL;
+			outl(ul_Command1,
+				devpriv->iobase + APCI3501_WATCHDOG +
+				APCI3501_TCW_PROG);
+		}		//if(data[1]==2)
+	}			// end if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
+
+	if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
+		if (data[1] == 1) {
+
+			ul_Command1 =
+				inl(devpriv->iobase + APCI3501_WATCHDOG +
+				APCI3501_TCW_PROG);
+			ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
+			//Enable the Timer
+			outl(ul_Command1,
+				devpriv->iobase + APCI3501_WATCHDOG +
+				APCI3501_TCW_PROG);
+		} else if (data[1] == 0) {
+			//Stop The Timer
+			ul_Command1 =
+				inl(devpriv->iobase + APCI3501_WATCHDOG +
+				APCI3501_TCW_PROG);
+			ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
+			outl(ul_Command1,
+				devpriv->iobase + APCI3501_WATCHDOG +
+				APCI3501_TCW_PROG);
+		}
+
+		else if (data[1] == 2) {
+			//Trigger the Timer
+			ul_Command1 =
+				inl(devpriv->iobase + APCI3501_WATCHDOG +
+				APCI3501_TCW_PROG);
+			ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x200UL;
+			outl(ul_Command1,
+				devpriv->iobase + APCI3501_WATCHDOG +
+				APCI3501_TCW_PROG);
+		}
+
+	}			// end if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
+	i_Temp = inl(devpriv->iobase + APCI3501_WATCHDOG +
+		APCI3501_TCW_TRIG_STATUS) & 0x1;
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI3501_ReadTimerCounterWatchdog                |
+|			  (struct comedi_device *dev,struct comedi_subdevice *s,               |
+|                      struct comedi_insn *insn,unsigned int *data)                     |
++----------------------------------------------------------------------------+
+| Task              : Read The Selected Timer , Counter or Watchdog          |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev : Driver handle                     |
+|                     UINT *data         : Data Pointer contains             |
+|                                          configuration parameters as below |
+|                                                                            |
+|					  data[0]            : 0 Timer                   |
+|										   1 Counter                 |
+|										   2 Watchdog                |                             |					  data[1]             : Timer Counter Watchdog Number   |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3501_ReadTimerCounterWatchdog(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+
+	if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
+		data[0] =
+			inl(devpriv->iobase + APCI3501_WATCHDOG +
+			APCI3501_TCW_TRIG_STATUS) & 0x1;
+		data[1] = inl(devpriv->iobase + APCI3501_WATCHDOG);
+	}			// end if  (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
+
+	else if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
+		data[0] =
+			inl(devpriv->iobase + APCI3501_WATCHDOG +
+			APCI3501_TCW_TRIG_STATUS) & 0x1;
+		data[1] = inl(devpriv->iobase + APCI3501_WATCHDOG);
+	}			// end if  (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
+
+	else if ((devpriv->b_TimerSelectMode != ADDIDATA_TIMER)
+		&& (devpriv->b_TimerSelectMode != ADDIDATA_WATCHDOG)) {
+		printk("\nIn ReadTimerCounterWatchdog :: Invalid Subdevice \n");
+	}
+	return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   :  int i_APCI3501_Reset(struct comedi_device *dev)			     |
+|					                                                 |
++----------------------------------------------------------------------------+
+| Task              :Resets the registers of the card                        |
++----------------------------------------------------------------------------+
+| Input Parameters  :                                                        |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      :                                                        |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3501_Reset(struct comedi_device * dev)
+{
+	int i_Count = 0, i_temp = 0;
+	ULONG ul_Command1 = 0, ul_Polarity, ul_DAC_Ready = 0;
+	outl(0x0, devpriv->iobase + APCI3501_DIGITAL_OP);
+	outl(1, devpriv->iobase + APCI3501_ANALOG_OUTPUT +
+		APCI3501_AO_VOLT_MODE);
+
+	ul_Polarity = 0x80000000;
+
+	for (i_Count = 0; i_Count <= 7; i_Count++) {
+		ul_DAC_Ready = inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT);
+
+		while (ul_DAC_Ready == 0) {
+			ul_DAC_Ready =
+				inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT);
+			ul_DAC_Ready = (ul_DAC_Ready >> 8) & 1;
+		}
+
+		if (ul_DAC_Ready) {
+			// Output the Value on the output channels.
+			ul_Command1 =
+				(ULONG) ((ULONG) (i_Count & 0xFF) |
+				(ULONG) ((i_temp << 0x8) & 0x7FFFFF00L) |
+				(ULONG) (ul_Polarity));
+			outl(ul_Command1,
+				devpriv->iobase + APCI3501_ANALOG_OUTPUT +
+				APCI3501_AO_PROG);
+		}
+	}
+
+	return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : static void v_APCI3501_Interrupt					     |
+|					  (int irq , void *d)      |
++----------------------------------------------------------------------------+
+| Task              : Interrupt processing Routine                           |
++----------------------------------------------------------------------------+
+| Input Parameters  : int irq                 : irq number                   |
+|                     void *d                 : void pointer                 |
++----------------------------------------------------------------------------+
+| Output Parameters :	--													 |
++----------------------------------------------------------------------------+
+| Return Value      : TRUE  : No error occur                                 |
+|		            : FALSE : Error occur. Return the error          |
+|			                                                         |
++----------------------------------------------------------------------------+
+*/
+void v_APCI3501_Interrupt(int irq, void *d)
+{
+	int i_temp;
+	struct comedi_device *dev = d;
+	unsigned int ui_Timer_AOWatchdog;
+	unsigned long ul_Command1;
+	// Disable Interrupt
+	ul_Command1 =
+		inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);
+
+	ul_Command1 = (ul_Command1 & 0xFFFFF9FDul);
+	outl(ul_Command1,
+		devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);
+
+	ui_Timer_AOWatchdog =
+		inl(devpriv->iobase + APCI3501_WATCHDOG +
+		APCI3501_TCW_IRQ) & 0x1;
+
+	if ((!ui_Timer_AOWatchdog)) {
+		comedi_error(dev, "IRQ from unknow source");
+		return;
+	}
+
+	// Enable Interrupt
+	//Send a signal to from kernel to user space
+	send_sig(SIGIO, devpriv->tsk_Current, 0);
+	ul_Command1 =
+		inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);
+	ul_Command1 = ((ul_Command1 & 0xFFFFF9FDul) | 1 << 1);
+	outl(ul_Command1,
+		devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);
+	i_temp = inl(devpriv->iobase + APCI3501_WATCHDOG +
+		APCI3501_TCW_TRIG_STATUS) & 0x1;
+	return;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h
new file mode 100644
index 0000000..51e7b66
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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.
+ */
+
+// Card Specific information
+#define APCI3501_BOARD_VENDOR_ID                 0x15B8
+#define APCI3501_ADDRESS_RANGE                   255
+
+#define APCI3501_DIGITAL_IP                       0x50
+#define APCI3501_DIGITAL_OP                       0x40
+#define APCI3501_ANALOG_OUTPUT                    0x00
+
+//Analog Output related Defines
+#define APCI3501_AO_VOLT_MODE                     0
+#define APCI3501_AO_PROG                          4
+#define APCI3501_AO_TRIG_SCS                      8
+#define UNIPOLAR                                  0
+#define BIPOLAR                                   1
+#define MODE0                                     0
+#define MODE1                                     1
+// ANALOG OUTPUT RANGE
+struct comedi_lrange range_apci3501_ao = { 2, {
+					BIP_RANGE(10),
+					UNI_RANGE(10)
+					}
+};
+
+//Watchdog Related Defines
+
+#define APCI3501_WATCHDOG                         0x20
+#define APCI3501_TCW_SYNC_ENABLEDISABLE           0
+#define APCI3501_TCW_RELOAD_VALUE                 4
+#define APCI3501_TCW_TIMEBASE                     8
+#define APCI3501_TCW_PROG                         12
+#define APCI3501_TCW_TRIG_STATUS                  16
+#define APCI3501_TCW_IRQ                          20
+#define APCI3501_TCW_WARN_TIMEVAL                 24
+#define APCI3501_TCW_WARN_TIMEBASE                28
+#define ADDIDATA_TIMER                            0
+#define ADDIDATA_WATCHDOG                         2
+
+// Hardware Layer  functions for Apci3501
+
+//AO
+INT i_APCI3501_ConfigAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+				  struct comedi_insn *insn, unsigned int *data);
+INT i_APCI3501_WriteAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data);
+
+//DI
+// for di read
+//INT i_APCI3501_ReadDigitalInput(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data);
+
+INT i_APCI3501_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data);
+
+//DO
+int i_APCI3501_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+				   struct comedi_insn *insn, unsigned int *data);
+INT i_APCI3501_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+				  struct comedi_insn *insn, unsigned int *data);
+INT i_APCI3501_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data);
+
+// TIMER
+// timer value is passed as u seconds
+INT i_APCI3501_ConfigTimerCounterWatchdog(struct comedi_device *dev,
+					  struct comedi_subdevice *s,
+					  struct comedi_insn *insn, unsigned int *data);
+int i_APCI3501_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev,
+						  struct comedi_subdevice *s,
+						  struct comedi_insn *insn,
+						  unsigned int *data);
+int i_APCI3501_ReadTimerCounterWatchdog(struct comedi_device *dev,
+					struct comedi_subdevice *s,
+					struct comedi_insn *insn, unsigned int *data);
+//Interrupt
+void v_APCI3501_Interrupt(int irq, void *d);
+
+//Reset functions
+int i_APCI3501_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c
new file mode 100644
index 0000000..b7268e4
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c
@@ -0,0 +1,1691 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+
+        ADDI-DATA GmbH
+        Dieselstrasse 3
+        D-77833 Ottersweier
+        Tel: +19(0)7223/9493-0
+        Fax: +49(0)7223/9493-92
+        http://www.addi-data-com
+        info@addi-data.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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+  +-----------------------------------------------------------------------+
+  | (C) ADDI-DATA GmbH          Dieselstrasse 3      D-77833 Ottersweier  |
+  +-----------------------------------------------------------------------+
+  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
+  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
+  +-----------------------------------------------------------------------+
+  | Project     : APCI-3XXX       | Compiler   : GCC                      |
+  | Module name : hwdrv_apci3xxx.c| Version    : 2.96                     |
+  +-------------------------------+---------------------------------------+
+  | Project manager: S. Weber     | Date       :  15/09/2005              |
+  +-----------------------------------------------------------------------+
+  | Description :APCI3XXX Module.  Hardware abstraction Layer for APCI3XXX|
+  +-----------------------------------------------------------------------+
+  |                             UPDATE'S                                  |
+  +-----------------------------------------------------------------------+
+  |   Date   |   Author  |          Description of updates                |
+  +----------+-----------+------------------------------------------------+
+  |          | 		 | 						  |
+  |          |           |						  |
+  +----------+-----------+------------------------------------------------+
+*/
+
+#include "hwdrv_apci3xxx.h"
+
+/*
++----------------------------------------------------------------------------+
+|                         ANALOG INPUT FUNCTIONS                             |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : INT   i_APCI3XXX_TestConversionStarted                 |
+|                          (struct comedi_device    *dev)                           |
++----------------------------------------------------------------------------+
+| Task                Test if any conversion started                         |
++----------------------------------------------------------------------------+
+| Input Parameters  : -                                                      |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : 0 : Conversion not started                             |
+|                     1 : Conversion started                                 |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_TestConversionStarted(struct comedi_device * dev)
+{
+	if ((readl((void *)(devpriv->dw_AiBase + 8)) & 0x80000UL) == 0x80000UL) {
+		return (1);
+	} else {
+		return (0);
+	}
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : INT   i_APCI3XXX_AnalogInputConfigOperatingMode        |
+|                          (struct comedi_device    *dev,                           |
+|                           struct comedi_subdevice *s,                             |
+|                           struct comedi_insn      *insn,                          |
+|                           unsigned int         *data)                          |
++----------------------------------------------------------------------------+
+| Task           Converting mode and convert time selection                  |
++----------------------------------------------------------------------------+
+| Input Parameters  : b_SingleDiff  = (BYTE)  data[1];                       |
+|                     b_TimeBase    = (BYTE)  data[2]; (0: ns, 1:micros 2:ms)|
+|                    dw_ReloadValue = (DWORD) data[3];                       |
+|                     ........                                               |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :>0 : No error                                           |
+|                    -1 : Single/Diff selection error                        |
+|                    -2 : Convert time base unity selection error            |
+|                    -3 : Convert time value selection error                 |
+|                    -10: Any conversion started                             |
+|                    ....                                                    |
+|                    -100 : Config command error                             |
+|                    -101 : Data size error                                  |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_AnalogInputConfigOperatingMode(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = insn->n;
+	BYTE b_TimeBase = 0;
+	BYTE b_SingleDiff = 0;
+	DWORD dw_ReloadValue = 0;
+	DWORD dw_TestReloadValue = 0;
+
+	/************************/
+	/* Test the buffer size */
+	/************************/
+
+	if (insn->n == 4) {
+	   /****************************/
+		/* Get the Singel/Diff flag */
+	   /****************************/
+
+		b_SingleDiff = (BYTE) data[1];
+
+	   /****************************/
+		/* Get the time base unitiy */
+	   /****************************/
+
+		b_TimeBase = (BYTE) data[2];
+
+	   /*************************************/
+		/* Get the convert time reload value */
+	   /*************************************/
+
+		dw_ReloadValue = (DWORD) data[3];
+
+	   /**********************/
+		/* Test the time base */
+	   /**********************/
+
+		if ((devpriv->ps_BoardInfo->
+				b_AvailableConvertUnit & (1 << b_TimeBase)) !=
+			0) {
+	      /*******************************/
+			/* Test the convert time value */
+	      /*******************************/
+
+			if ((dw_ReloadValue >= 0) && (dw_ReloadValue <= 65535)) {
+				dw_TestReloadValue = dw_ReloadValue;
+
+				if (b_TimeBase == 1) {
+					dw_TestReloadValue =
+						dw_TestReloadValue * 1000UL;
+				}
+				if (b_TimeBase == 2) {
+					dw_TestReloadValue =
+						dw_TestReloadValue * 1000000UL;
+				}
+
+		 /*******************************/
+				/* Test the convert time value */
+		 /*******************************/
+
+				if (dw_TestReloadValue >=
+					devpriv->ps_BoardInfo->
+					ui_MinAcquisitiontimeNs) {
+					if ((b_SingleDiff == APCI3XXX_SINGLE)
+						|| (b_SingleDiff ==
+							APCI3XXX_DIFF)) {
+						if (((b_SingleDiff == APCI3XXX_SINGLE) && (devpriv->ps_BoardInfo->i_NbrAiChannel == 0)) || ((b_SingleDiff == APCI3XXX_DIFF) && (devpriv->ps_BoardInfo->i_NbrAiChannelDiff == 0))) {
+			   /*******************************/
+							/* Single/Diff selection error */
+			   /*******************************/
+
+							printk("Single/Diff selection error\n");
+							i_ReturnValue = -1;
+						} else {
+			   /**********************************/
+							/* Test if conversion not started */
+			   /**********************************/
+
+							if (i_APCI3XXX_TestConversionStarted(dev) == 0) {
+								devpriv->
+									ui_EocEosConversionTime
+									=
+									(UINT)
+									dw_ReloadValue;
+								devpriv->
+									b_EocEosConversionTimeBase
+									=
+									b_TimeBase;
+								devpriv->
+									b_SingelDiff
+									=
+									b_SingleDiff;
+								devpriv->
+									b_AiInitialisation
+									= 1;
+
+			      /*******************************/
+								/* Set the convert timing unit */
+			      /*******************************/
+
+								writel((DWORD)
+									b_TimeBase,
+									(void *)
+									(devpriv->
+										dw_AiBase
+										+
+										36));
+
+			      /**************************/
+								/* Set the convert timing */
+			      /*************************/
+
+								writel(dw_ReloadValue, (void *)(devpriv->dw_AiBase + 32));
+							} else {
+			      /**************************/
+								/* Any conversion started */
+			      /**************************/
+
+								printk("Any conversion started\n");
+								i_ReturnValue =
+									-10;
+							}
+						}
+					} else {
+		       /*******************************/
+						/* Single/Diff selection error */
+		       /*******************************/
+
+						printk("Single/Diff selection error\n");
+						i_ReturnValue = -1;
+					}
+				} else {
+		    /************************/
+					/* Time selection error */
+		    /************************/
+
+					printk("Convert time value selection error\n");
+					i_ReturnValue = -3;
+				}
+			} else {
+		 /************************/
+				/* Time selection error */
+		 /************************/
+
+				printk("Convert time value selection error\n");
+				i_ReturnValue = -3;
+			}
+		} else {
+	      /*****************************/
+			/* Time base selection error */
+	      /*****************************/
+
+			printk("Convert time base unity selection error\n");
+			i_ReturnValue = -2;
+		}
+	} else {
+	   /*******************/
+		/* Data size error */
+	   /*******************/
+
+		printk("Buffer size error\n");
+		i_ReturnValue = -101;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : INT   i_APCI3XXX_InsnConfigAnalogInput                 |
+|                          (struct comedi_device    *dev,                           |
+|                           struct comedi_subdevice *s,                             |
+|                           struct comedi_insn      *insn,                          |
+|                           unsigned int         *data)                          |
++----------------------------------------------------------------------------+
+| Task           Converting mode and convert time selection                  |
++----------------------------------------------------------------------------+
+| Input Parameters  : b_ConvertMode = (BYTE)  data[0];                       |
+|                     b_TimeBase    = (BYTE)  data[1]; (0: ns, 1:micros 2:ms)|
+|                    dw_ReloadValue = (DWORD) data[2];                       |
+|                     ........                                               |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :>0: No error                                            |
+|                    ....                                                    |
+|                    -100 : Config command error                             |
+|                    -101 : Data size error                                  |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnConfigAnalogInput(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = insn->n;
+
+	/************************/
+	/* Test the buffer size */
+	/************************/
+
+	if (insn->n >= 1) {
+		switch ((BYTE) data[0]) {
+		case APCI3XXX_CONFIGURATION:
+			i_ReturnValue =
+				i_APCI3XXX_AnalogInputConfigOperatingMode(dev,
+				s, insn, data);
+			break;
+
+		default:
+			i_ReturnValue = -100;
+			printk("Config command error %d\n", data[0]);
+			break;
+		}
+	} else {
+	   /*******************/
+		/* Data size error */
+	   /*******************/
+
+		printk("Buffer size error\n");
+		i_ReturnValue = -101;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : INT   i_APCI3XXX_InsnReadAnalogInput                   |
+|                          (struct comedi_device    *dev,                           |
+|                           struct comedi_subdevice *s,                             |
+|                           struct comedi_insn      *insn,                          |
+|                           unsigned int         *data)                          |
++----------------------------------------------------------------------------+
+| Task                Read 1 analog input                                    |
++----------------------------------------------------------------------------+
+| Input Parameters  : b_Range             = CR_RANGE(insn->chanspec);        |
+|                     b_Channel           = CR_CHAN(insn->chanspec);         |
+|                     dw_NbrOfAcquisition = insn->n;                         |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :>0: No error                                            |
+|                    -3 : Channel selection error                            |
+|                    -4 : Configuration selelection error                    |
+|                    -10: Any conversion started                             |
+|                    ....                                                    |
+|                    -100 : Config command error                             |
+|                    -101 : Data size error                                  |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnReadAnalogInput(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = insn->n;
+	BYTE b_Configuration = (BYTE) CR_RANGE(insn->chanspec);
+	BYTE b_Channel = (BYTE) CR_CHAN(insn->chanspec);
+	DWORD dw_Temp = 0;
+	DWORD dw_Configuration = 0;
+	DWORD dw_AcquisitionCpt = 0;
+	BYTE b_Interrupt = 0;
+
+	/*************************************/
+	/* Test if operating mode configured */
+	/*************************************/
+
+	if (devpriv->b_AiInitialisation) {
+	   /***************************/
+		/* Test the channel number */
+	   /***************************/
+
+		if (((b_Channel < devpriv->ps_BoardInfo->i_NbrAiChannel)
+				&& (devpriv->b_SingelDiff == APCI3XXX_SINGLE))
+			|| ((b_Channel < devpriv->ps_BoardInfo->
+					i_NbrAiChannelDiff)
+				&& (devpriv->b_SingelDiff == APCI3XXX_DIFF))) {
+	      /**********************************/
+			/* Test the channel configuration */
+	      /**********************************/
+
+			if (b_Configuration > 7) {
+		 /***************************/
+				/* Channel not initialised */
+		 /***************************/
+
+				i_ReturnValue = -4;
+				printk("Channel %d range %d selection error\n",
+					b_Channel, b_Configuration);
+			}
+		} else {
+	      /***************************/
+			/* Channel selection error */
+	      /***************************/
+
+			i_ReturnValue = -3;
+			printk("Channel %d selection error\n", b_Channel);
+		}
+
+	   /**************************/
+		/* Test if no error occur */
+	   /**************************/
+
+		if (i_ReturnValue >= 0) {
+	      /************************/
+			/* Test the buffer size */
+	      /************************/
+
+			if ((b_Interrupt != 0) || ((b_Interrupt == 0)
+					&& (insn->n >= 1))) {
+		 /**********************************/
+				/* Test if conversion not started */
+		 /**********************************/
+
+				if (i_APCI3XXX_TestConversionStarted(dev) == 0) {
+		    /******************/
+					/* Clear the FIFO */
+		    /******************/
+
+					writel(0x10000UL,
+						(void *)(devpriv->dw_AiBase +
+							12));
+
+		    /*******************************/
+					/* Get and save the delay mode */
+		    /*******************************/
+
+					dw_Temp =
+						readl((void *)(devpriv->
+							dw_AiBase + 4));
+					dw_Temp = dw_Temp & 0xFFFFFEF0UL;
+
+		    /***********************************/
+					/* Channel configuration selection */
+		    /***********************************/
+
+					writel(dw_Temp,
+						(void *)(devpriv->dw_AiBase +
+							4));
+
+		    /**************************/
+					/* Make the configuration */
+		    /**************************/
+
+					dw_Configuration =
+						(b_Configuration & 3) |
+						((DWORD) (b_Configuration >> 2)
+						<< 6) | ((DWORD) devpriv->
+						b_SingelDiff << 7);
+
+		    /***************************/
+					/* Write the configuration */
+		    /***************************/
+
+					writel(dw_Configuration,
+						(void *)(devpriv->dw_AiBase +
+							0));
+
+		    /*********************/
+					/* Channel selection */
+		    /*********************/
+
+					writel(dw_Temp | 0x100UL,
+						(void *)(devpriv->dw_AiBase +
+							4));
+					writel((DWORD) b_Channel,
+						(void *)(devpriv->dw_AiBase +
+							0));
+
+		    /***********************/
+					/* Restaure delay mode */
+		    /***********************/
+
+					writel(dw_Temp,
+						(void *)(devpriv->dw_AiBase +
+							4));
+
+		    /***********************************/
+					/* Set the number of sequence to 1 */
+		    /***********************************/
+
+					writel(1,
+						(void *)(devpriv->dw_AiBase +
+							48));
+
+		    /***************************/
+					/* Save the interrupt flag */
+		    /***************************/
+
+					devpriv->b_EocEosInterrupt =
+						b_Interrupt;
+
+		    /*******************************/
+					/* Save the number of channels */
+		    /*******************************/
+
+					devpriv->ui_AiNbrofChannels = 1;
+
+		    /******************************/
+					/* Test if interrupt not used */
+		    /******************************/
+
+					if (b_Interrupt == 0) {
+						for (dw_AcquisitionCpt = 0;
+							dw_AcquisitionCpt <
+							insn->n;
+							dw_AcquisitionCpt++) {
+			  /************************/
+							/* Start the conversion */
+			  /************************/
+
+							writel(0x80000UL,
+								(void *)
+								(devpriv->
+									dw_AiBase
+									+ 8));
+
+			  /****************/
+							/* Wait the EOS */
+			  /****************/
+
+							do {
+								dw_Temp =
+									readl(
+									(void *)
+									(devpriv->
+										dw_AiBase
+										+
+										20));
+								dw_Temp =
+									dw_Temp
+									& 1;
+							}
+							while (dw_Temp != 1);
+
+			  /*************************/
+							/* Read the analog value */
+			  /*************************/
+
+							data[dw_AcquisitionCpt]
+								=
+								(unsigned int)
+								readl((void
+									*)
+								(devpriv->
+									dw_AiBase
+									+ 28));
+						}
+					} else {
+		       /************************/
+						/* Start the conversion */
+		       /************************/
+
+						writel(0x180000UL,
+							(void *)(devpriv->
+								dw_AiBase + 8));
+					}
+				} else {
+		    /**************************/
+					/* Any conversion started */
+		    /**************************/
+
+					printk("Any conversion started\n");
+					i_ReturnValue = -10;
+				}
+			} else {
+		 /*******************/
+				/* Data size error */
+		 /*******************/
+
+				printk("Buffer size error\n");
+				i_ReturnValue = -101;
+			}
+		}
+	} else {
+	   /***************************/
+		/* Channel selection error */
+	   /***************************/
+
+		printk("Operating mode not configured\n");
+		i_ReturnValue = -1;
+	}
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name     : void v_APCI3XXX_Interrupt (int            irq,         |
+|                                                void           *d)       |
++----------------------------------------------------------------------------+
+| Task              :Interrupt handler for APCI3XXX                          |
+|                    When interrupt occurs this gets called.                 |
+|                    First it finds which interrupt has been generated and   |
+|                    handles  corresponding interrupt                        |
++----------------------------------------------------------------------------+
+| Input Parameters  : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : -                                                      |
++----------------------------------------------------------------------------+
+*/
+
+void v_APCI3XXX_Interrupt(int irq, void *d)
+{
+	struct comedi_device *dev = d;
+	BYTE b_CopyCpt = 0;
+	DWORD dw_Status = 0;
+
+	/***************************/
+	/* Test if interrupt occur */
+	/***************************/
+
+	if (((dw_Status = readl((void *)(devpriv->dw_AiBase + 16))) & 0x2UL) ==
+		0x2UL) {
+	   /***********************/
+		/* Reset the interrupt */
+	   /***********************/
+
+		writel(dw_Status, (void *)(devpriv->dw_AiBase + 16));
+
+	   /*****************************/
+		/* Test if interrupt enabled */
+	   /*****************************/
+
+		if (devpriv->b_EocEosInterrupt == 1) {
+	      /********************************/
+			/* Read all analog inputs value */
+	      /********************************/
+
+			for (b_CopyCpt = 0;
+				b_CopyCpt < devpriv->ui_AiNbrofChannels;
+				b_CopyCpt++) {
+				devpriv->ui_AiReadData[b_CopyCpt] =
+					(UINT) readl((void *)(devpriv->
+						dw_AiBase + 28));
+			}
+
+	      /**************************/
+			/* Set the interrupt flag */
+	      /**************************/
+
+			devpriv->b_EocEosInterrupt = 2;
+
+	      /**********************************************/
+			/* Send a signal to from kernel to user space */
+	      /**********************************************/
+
+			send_sig(SIGIO, devpriv->tsk_Current, 0);
+		}
+	}
+}
+
+/*
++----------------------------------------------------------------------------+
+|                            ANALOG OUTPUT SUBDEVICE                         |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : INT   i_APCI3XXX_InsnWriteAnalogOutput                 |
+|                          (struct comedi_device    *dev,                           |
+|                           struct comedi_subdevice *s,                             |
+|                           struct comedi_insn      *insn,                          |
+|                           unsigned int         *data)                          |
++----------------------------------------------------------------------------+
+| Task                Read 1 analog input                                    |
++----------------------------------------------------------------------------+
+| Input Parameters  : b_Range    = CR_RANGE(insn->chanspec);                 |
+|                     b_Channel  = CR_CHAN(insn->chanspec);                  |
+|                     data[0]    = analog value;                             |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :>0: No error                                            |
+|                    -3 : Channel selection error                            |
+|                    -4 : Configuration selelection error                    |
+|                    ....                                                    |
+|                    -101 : Data size error                                  |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnWriteAnalogOutput(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	BYTE b_Range = (BYTE) CR_RANGE(insn->chanspec);
+	BYTE b_Channel = (BYTE) CR_CHAN(insn->chanspec);
+	DWORD dw_Status = 0;
+	INT i_ReturnValue = insn->n;
+
+	/************************/
+	/* Test the buffer size */
+	/************************/
+
+	if (insn->n >= 1) {
+	   /***************************/
+		/* Test the channel number */
+	   /***************************/
+
+		if (b_Channel < devpriv->ps_BoardInfo->i_NbrAoChannel) {
+	      /**********************************/
+			/* Test the channel configuration */
+	      /**********************************/
+
+			if (b_Range < 2) {
+		 /***************************/
+				/* Set the range selection */
+		 /***************************/
+
+				writel(b_Range,
+					(void *)(devpriv->dw_AiBase + 96));
+
+		 /**************************************************/
+				/* Write the analog value to the selected channel */
+		 /**************************************************/
+
+				writel((data[0] << 8) | b_Channel,
+					(void *)(devpriv->dw_AiBase + 100));
+
+		 /****************************/
+				/* Wait the end of transfer */
+		 /****************************/
+
+				do {
+					dw_Status =
+						readl((void *)(devpriv->
+							dw_AiBase + 96));
+				}
+				while ((dw_Status & 0x100) != 0x100);
+			} else {
+		 /***************************/
+				/* Channel not initialised */
+		 /***************************/
+
+				i_ReturnValue = -4;
+				printk("Channel %d range %d selection error\n",
+					b_Channel, b_Range);
+			}
+		} else {
+	      /***************************/
+			/* Channel selection error */
+	      /***************************/
+
+			i_ReturnValue = -3;
+			printk("Channel %d selection error\n", b_Channel);
+		}
+	} else {
+	   /*******************/
+		/* Data size error */
+	   /*******************/
+
+		printk("Buffer size error\n");
+		i_ReturnValue = -101;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+|                              TTL FUNCTIONS                                 |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : INT   i_APCI3XXX_InsnConfigInitTTLIO                   |
+|                          (struct comedi_device    *dev,                           |
+|                           struct comedi_subdevice *s,                             |
+|                           struct comedi_insn      *insn,                          |
+|                           unsigned int         *data)                          |
++----------------------------------------------------------------------------+
+| Task           You must calling this function be                           |
+|                for you call any other function witch access of TTL.        |
+|                APCI3XXX_TTL_INIT_DIRECTION_PORT2(user inputs for direction)|
++----------------------------------------------------------------------------+
+| Input Parameters  : b_InitType    = (BYTE) data[0];                        |
+|                     b_Port2Mode   = (BYTE) data[1];                        |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :>0: No error                                            |
+|                    -1: Port 2 mode selection is wrong                      |
+|                    ....                                                    |
+|                    -100 : Config command error                             |
+|                    -101 : Data size error                                  |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnConfigInitTTLIO(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = insn->n;
+	BYTE b_Command = 0;
+
+	/************************/
+	/* Test the buffer size */
+	/************************/
+
+	if (insn->n >= 1) {
+	   /*******************/
+		/* Get the command */
+		/* **************** */
+
+		b_Command = (BYTE) data[0];
+
+	   /********************/
+		/* Test the command */
+	   /********************/
+
+		if (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) {
+	      /***************************************/
+			/* Test the initialisation buffer size */
+	      /***************************************/
+
+			if ((b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2)
+				&& (insn->n != 2)) {
+		 /*******************/
+				/* Data size error */
+		 /*******************/
+
+				printk("Buffer size error\n");
+				i_ReturnValue = -101;
+			}
+		} else {
+	      /************************/
+			/* Config command error */
+	      /************************/
+
+			printk("Command selection error\n");
+			i_ReturnValue = -100;
+		}
+	} else {
+	   /*******************/
+		/* Data size error */
+	   /*******************/
+
+		printk("Buffer size error\n");
+		i_ReturnValue = -101;
+	}
+
+	/*********************************************************************************/
+	/* Test if no error occur and APCI3XXX_TTL_INIT_DIRECTION_PORT2 command selected */
+	/*********************************************************************************/
+
+	if ((i_ReturnValue >= 0)
+		&& (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2)) {
+	   /**********************/
+		/* Test the direction */
+	   /**********************/
+
+		if ((data[1] == 0) || (data[1] == 0xFF)) {
+	      /**************************/
+			/* Save the configuration */
+	      /**************************/
+
+			devpriv->ul_TTLPortConfiguration[0] =
+				devpriv->ul_TTLPortConfiguration[0] | data[1];
+		} else {
+	      /************************/
+			/* Port direction error */
+	      /************************/
+
+			printk("Port 2 direction selection error\n");
+			i_ReturnValue = -1;
+		}
+	}
+
+	/**************************/
+	/* Test if no error occur */
+	/**************************/
+
+	if (i_ReturnValue >= 0) {
+	   /***********************************/
+		/* Test if TTL port initilaisation */
+	   /***********************************/
+
+		if (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) {
+	      /*************************/
+			/* Set the configuration */
+	      /*************************/
+
+			outl(data[1], devpriv->iobase + 224);
+		}
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+|                        TTL INPUT FUNCTIONS                                 |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : INT     i_APCI3XXX_InsnBitsTTLIO                       |
+|                          (struct comedi_device    *dev,                           |
+|                           struct comedi_subdevice *s,                             |
+|                           struct comedi_insn      *insn,                          |
+|                           unsigned int         *data)                          |
++----------------------------------------------------------------------------+
+| Task              : Write the selected output mask and read the status from|
+|                     all TTL channles                                       |
++----------------------------------------------------------------------------+
+| Input Parameters  : dw_ChannelMask = data [0];                             |
+|                     dw_BitMask     = data [1];                             |
++----------------------------------------------------------------------------+
+| Output Parameters : data[1] : All TTL channles states                      |
++----------------------------------------------------------------------------+
+| Return Value      : >0  : No error                                         |
+|                    -4   : Channel mask error                               |
+|                    -101 : Data size error                                  |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnBitsTTLIO(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = insn->n;
+	BYTE b_ChannelCpt = 0;
+	DWORD dw_ChannelMask = 0;
+	DWORD dw_BitMask = 0;
+	DWORD dw_Status = 0;
+
+	/************************/
+	/* Test the buffer size */
+	/************************/
+
+	if (insn->n >= 2) {
+	   /*******************************/
+		/* Get the channe and bit mask */
+	   /*******************************/
+
+		dw_ChannelMask = data[0];
+		dw_BitMask = data[1];
+
+	   /*************************/
+		/* Test the channel mask */
+	   /*************************/
+
+		if (((dw_ChannelMask & 0XFF00FF00) == 0) &&
+			(((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0xFF)
+				|| (((devpriv->ul_TTLPortConfiguration[0] &
+							0xFF) == 0)
+					&& ((dw_ChannelMask & 0XFF0000) ==
+						0)))) {
+	      /*********************************/
+			/* Test if set/reset any channel */
+	      /*********************************/
+
+			if (dw_ChannelMask) {
+		 /****************************************/
+				/* Test if set/rest any port 0 channels */
+		 /****************************************/
+
+				if (dw_ChannelMask & 0xFF) {
+		    /*******************************************/
+					/* Read port 0 (first digital output port) */
+		    /*******************************************/
+
+					dw_Status = inl(devpriv->iobase + 80);
+
+					for (b_ChannelCpt = 0; b_ChannelCpt < 8;
+						b_ChannelCpt++) {
+						if ((dw_ChannelMask >>
+								b_ChannelCpt) &
+							1) {
+							dw_Status =
+								(dw_Status &
+								(0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
+						}
+					}
+
+					outl(dw_Status, devpriv->iobase + 80);
+				}
+
+		 /****************************************/
+				/* Test if set/rest any port 2 channels */
+		 /****************************************/
+
+				if (dw_ChannelMask & 0xFF0000) {
+					dw_BitMask = dw_BitMask >> 16;
+					dw_ChannelMask = dw_ChannelMask >> 16;
+
+		    /********************************************/
+					/* Read port 2 (second digital output port) */
+		    /********************************************/
+
+					dw_Status = inl(devpriv->iobase + 112);
+
+					for (b_ChannelCpt = 0; b_ChannelCpt < 8;
+						b_ChannelCpt++) {
+						if ((dw_ChannelMask >>
+								b_ChannelCpt) &
+							1) {
+							dw_Status =
+								(dw_Status &
+								(0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
+						}
+					}
+
+					outl(dw_Status, devpriv->iobase + 112);
+				}
+			}
+
+	      /*******************************************/
+			/* Read port 0 (first digital output port) */
+	      /*******************************************/
+
+			data[1] = inl(devpriv->iobase + 80);
+
+	      /******************************************/
+			/* Read port 1 (first digital input port) */
+	      /******************************************/
+
+			data[1] = data[1] | (inl(devpriv->iobase + 64) << 8);
+
+	      /************************/
+			/* Test if port 2 input */
+	      /************************/
+
+			if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0) {
+				data[1] =
+					data[1] | (inl(devpriv->iobase +
+						96) << 16);
+			} else {
+				data[1] =
+					data[1] | (inl(devpriv->iobase +
+						112) << 16);
+			}
+		} else {
+	      /************************/
+			/* Config command error */
+	      /************************/
+
+			printk("Channel mask error\n");
+			i_ReturnValue = -4;
+		}
+	} else {
+	   /*******************/
+		/* Data size error */
+	   /*******************/
+
+		printk("Buffer size error\n");
+		i_ReturnValue = -101;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : INT i_APCI3XXX_InsnReadTTLIO                           |
+|                          (struct comedi_device    *dev,                           |
+|                           struct comedi_subdevice *s,                             |
+|                           struct comedi_insn      *insn,                          |
+|                           unsigned int         *data)                          |
++----------------------------------------------------------------------------+
+| Task              : Read the status from selected channel                  |
++----------------------------------------------------------------------------+
+| Input Parameters  : b_Channel = CR_CHAN(insn->chanspec)                    |
++----------------------------------------------------------------------------+
+| Output Parameters : data[0] : Selected TTL channel state                   |
++----------------------------------------------------------------------------+
+| Return Value      : 0   : No error                                         |
+|                    -3   : Channel selection error                          |
+|                    -101 : Data size error                                  |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnReadTTLIO(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	BYTE b_Channel = (BYTE) CR_CHAN(insn->chanspec);
+	INT i_ReturnValue = insn->n;
+	unsigned int *pls_ReadData = data;
+
+	/************************/
+	/* Test the buffer size */
+	/************************/
+
+	if (insn->n >= 1) {
+	   /***********************/
+		/* Test if read port 0 */
+	   /***********************/
+
+		if (b_Channel < 8) {
+	      /*******************************************/
+			/* Read port 0 (first digital output port) */
+	      /*******************************************/
+
+			pls_ReadData[0] = inl(devpriv->iobase + 80);
+			pls_ReadData[0] = (pls_ReadData[0] >> b_Channel) & 1;
+		} else {
+	      /***********************/
+			/* Test if read port 1 */
+	      /***********************/
+
+			if ((b_Channel > 7) && (b_Channel < 16)) {
+		 /******************************************/
+				/* Read port 1 (first digital input port) */
+		 /******************************************/
+
+				pls_ReadData[0] = inl(devpriv->iobase + 64);
+				pls_ReadData[0] =
+					(pls_ReadData[0] >> (b_Channel -
+						8)) & 1;
+			} else {
+		 /***********************/
+				/* Test if read port 2 */
+		 /***********************/
+
+				if ((b_Channel > 15) && (b_Channel < 24)) {
+		    /************************/
+					/* Test if port 2 input */
+		    /************************/
+
+					if ((devpriv->ul_TTLPortConfiguration[0]
+							& 0xFF) == 0) {
+						pls_ReadData[0] =
+							inl(devpriv->iobase +
+							96);
+						pls_ReadData[0] =
+							(pls_ReadData[0] >>
+							(b_Channel - 16)) & 1;
+					} else {
+						pls_ReadData[0] =
+							inl(devpriv->iobase +
+							112);
+						pls_ReadData[0] =
+							(pls_ReadData[0] >>
+							(b_Channel - 16)) & 1;
+					}
+				} else {
+		    /***************************/
+					/* Channel selection error */
+		    /***************************/
+
+					i_ReturnValue = -3;
+					printk("Channel %d selection error\n",
+						b_Channel);
+				}
+			}
+		}
+	} else {
+	   /*******************/
+		/* Data size error */
+	   /*******************/
+
+		printk("Buffer size error\n");
+		i_ReturnValue = -101;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+|                        TTL OUTPUT FUNCTIONS                                |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : INT     i_APCI3XXX_InsnWriteTTLIO                      |
+|                          (struct comedi_device    *dev,                           |
+|                           struct comedi_subdevice *s,                             |
+|                           struct comedi_insn      *insn,                          |
+|                           unsigned int         *data)                          |
++----------------------------------------------------------------------------+
+| Task              : Set the state from TTL output channel                  |
++----------------------------------------------------------------------------+
+| Input Parameters  : b_Channel = CR_CHAN(insn->chanspec)                    |
+|                     b_State   = data [0]                                   |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : 0   : No error                                         |
+|                    -3   : Channel selection error                          |
+|                    -101 : Data size error                                  |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = insn->n;
+	BYTE b_Channel = (BYTE) CR_CHAN(insn->chanspec);
+	BYTE b_State = 0;
+	DWORD dw_Status = 0;
+
+	/************************/
+	/* Test the buffer size */
+	/************************/
+
+	if (insn->n >= 1) {
+		b_State = (BYTE) data[0];
+
+	   /***********************/
+		/* Test if read port 0 */
+	   /***********************/
+
+		if (b_Channel < 8) {
+	      /*****************************************************************************/
+			/* Read port 0 (first digital output port) and set/reset the selcted channel */
+	      /*****************************************************************************/
+
+			dw_Status = inl(devpriv->iobase + 80);
+			dw_Status =
+				(dw_Status & (0xFF -
+					(1 << b_Channel))) | ((b_State & 1) <<
+				b_Channel);
+			outl(dw_Status, devpriv->iobase + 80);
+		} else {
+	      /***********************/
+			/* Test if read port 2 */
+	      /***********************/
+
+			if ((b_Channel > 15) && (b_Channel < 24)) {
+		 /*************************/
+				/* Test if port 2 output */
+		 /*************************/
+
+				if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF)
+					== 0xFF) {
+		    /*****************************************************************************/
+					/* Read port 2 (first digital output port) and set/reset the selcted channel */
+		    /*****************************************************************************/
+
+					dw_Status = inl(devpriv->iobase + 112);
+					dw_Status =
+						(dw_Status & (0xFF -
+							(1 << (b_Channel -
+									16)))) |
+						((b_State & 1) << (b_Channel -
+							16));
+					outl(dw_Status, devpriv->iobase + 112);
+				} else {
+		    /***************************/
+					/* Channel selection error */
+		    /***************************/
+
+					i_ReturnValue = -3;
+					printk("Channel %d selection error\n",
+						b_Channel);
+				}
+			} else {
+		 /***************************/
+				/* Channel selection error */
+		 /***************************/
+
+				i_ReturnValue = -3;
+				printk("Channel %d selection error\n",
+					b_Channel);
+			}
+		}
+	} else {
+	   /*******************/
+		/* Data size error */
+	   /*******************/
+
+		printk("Buffer size error\n");
+		i_ReturnValue = -101;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+|                           DIGITAL INPUT SUBDEVICE                          |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function name     :int i_APCI3XXX_InsnReadDigitalInput                     |
+|                                          (struct comedi_device *dev,              |
+|                                           struct comedi_subdevice *s,             |
+|                                           struct comedi_insn *insn,               |
+|                                           unsigned int *data)                  |
++----------------------------------------------------------------------------+
+| Task              : Reads the value of the specified Digital input channel |
++----------------------------------------------------------------------------+
+| Input Parameters  : b_Channel = CR_CHAN(insn->chanspec) (0 to 3)           |
++----------------------------------------------------------------------------+
+| Output Parameters : data[0] : Channel value                                |
++----------------------------------------------------------------------------+
+| Return Value      : 0   : No error                                         |
+|                    -3   : Channel selection error                          |
+|                    -101 : Data size error                                  |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnReadDigitalInput(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = insn->n;
+	BYTE b_Channel = (BYTE) CR_CHAN(insn->chanspec);
+	DWORD dw_Temp = 0;
+
+	/***************************/
+	/* Test the channel number */
+	/***************************/
+
+	if (b_Channel <= devpriv->ps_BoardInfo->i_NbrDiChannel) {
+	   /************************/
+		/* Test the buffer size */
+	   /************************/
+
+		if (insn->n >= 1) {
+			dw_Temp = inl(devpriv->iobase + 32);
+			*data = (dw_Temp >> b_Channel) & 1;
+		} else {
+	      /*******************/
+			/* Data size error */
+	      /*******************/
+
+			printk("Buffer size error\n");
+			i_ReturnValue = -101;
+		}
+	} else {
+	   /***************************/
+		/* Channel selection error */
+	   /***************************/
+
+		printk("Channel selection error\n");
+		i_ReturnValue = -3;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name     :int i_APCI3XXX_InsnBitsDigitalInput                     |
+|                                          (struct comedi_device *dev,              |
+|                                           struct comedi_subdevice *s,             |
+|                                           struct comedi_insn *insn,               |
+|                                           unsigned int *data)                  |
++----------------------------------------------------------------------------+
+| Task              : Reads the value of the Digital input Port i.e.4channels|
++----------------------------------------------------------------------------+
+| Input Parameters  : -                                                      |
++----------------------------------------------------------------------------+
+| Output Parameters : data[0] : Port value                                   |
++----------------------------------------------------------------------------+
+| Return Value      :>0: No error                                            |
+|                    ....                                                    |
+|                    -101 : Data size error                                  |
++----------------------------------------------------------------------------+
+*/
+int i_APCI3XXX_InsnBitsDigitalInput(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = insn->n;
+	DWORD dw_Temp = 0;
+
+	/************************/
+	/* Test the buffer size */
+	/************************/
+
+	if (insn->n >= 1) {
+		dw_Temp = inl(devpriv->iobase + 32);
+		*data = dw_Temp & 0xf;
+	} else {
+	   /*******************/
+		/* Data size error */
+	   /*******************/
+
+		printk("Buffer size error\n");
+		i_ReturnValue = -101;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+|                           DIGITAL OUTPUT SUBDEVICE                         |
++----------------------------------------------------------------------------+
+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function name     :int i_APCI3XXX_InsnBitsDigitalOutput                    |
+|                                          (struct comedi_device *dev,              |
+|                                           struct comedi_subdevice *s,             |
+|                                           struct comedi_insn *insn,               |
+|                                           unsigned int *data)                  |
++----------------------------------------------------------------------------+
+| Task              : Write the selected output mask and read the status from|
+|                     all digital output channles                            |
++----------------------------------------------------------------------------+
+| Input Parameters  : dw_ChannelMask = data [0];                             |
+|                     dw_BitMask     = data [1];                             |
++----------------------------------------------------------------------------+
+| Output Parameters : data[1] : All digital output channles states           |
++----------------------------------------------------------------------------+
+| Return Value      : >0  : No error                                         |
+|                    -4   : Channel mask error                               |
+|                    -101 : Data size error                                  |
++----------------------------------------------------------------------------+
+*/
+int i_APCI3XXX_InsnBitsDigitalOutput(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = insn->n;
+	BYTE b_ChannelCpt = 0;
+	DWORD dw_ChannelMask = 0;
+	DWORD dw_BitMask = 0;
+	DWORD dw_Status = 0;
+
+	/************************/
+	/* Test the buffer size */
+	/************************/
+
+	if (insn->n >= 2) {
+	   /*******************************/
+		/* Get the channe and bit mask */
+	   /*******************************/
+
+		dw_ChannelMask = data[0];
+		dw_BitMask = data[1];
+
+	   /*************************/
+		/* Test the channel mask */
+	   /*************************/
+
+		if ((dw_ChannelMask & 0XFFFFFFF0) == 0) {
+	      /*********************************/
+			/* Test if set/reset any channel */
+	      /*********************************/
+
+			if (dw_ChannelMask & 0xF) {
+		 /********************************/
+				/* Read the digital output port */
+		 /********************************/
+
+				dw_Status = inl(devpriv->iobase + 48);
+
+				for (b_ChannelCpt = 0; b_ChannelCpt < 4;
+					b_ChannelCpt++) {
+					if ((dw_ChannelMask >> b_ChannelCpt) &
+						1) {
+						dw_Status =
+							(dw_Status & (0xF -
+								(1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
+					}
+				}
+
+				outl(dw_Status, devpriv->iobase + 48);
+			}
+
+	      /********************************/
+			/* Read the digital output port */
+	      /********************************/
+
+			data[1] = inl(devpriv->iobase + 48);
+		} else {
+	      /************************/
+			/* Config command error */
+	      /************************/
+
+			printk("Channel mask error\n");
+			i_ReturnValue = -4;
+		}
+	} else {
+	   /*******************/
+		/* Data size error */
+	   /*******************/
+
+		printk("Buffer size error\n");
+		i_ReturnValue = -101;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name     :int i_APCI3XXX_InsnWriteDigitalOutput                   |
+|                                          (struct comedi_device *dev,              |
+|                                           struct comedi_subdevice *s,             |
+|                                           struct comedi_insn *insn,               |
+|                                           unsigned int *data)                  |
++----------------------------------------------------------------------------+
+| Task              : Set the state from digital output channel              |
++----------------------------------------------------------------------------+
+| Input Parameters  : b_Channel = CR_CHAN(insn->chanspec)                    |
+|                     b_State   = data [0]                                   |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : >0  : No error                                         |
+|                    -3   : Channel selection error                          |
+|                    -101 : Data size error                                  |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnWriteDigitalOutput(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = insn->n;
+	BYTE b_Channel = CR_CHAN(insn->chanspec);
+	BYTE b_State = 0;
+	DWORD dw_Status = 0;
+
+	/************************/
+	/* Test the buffer size */
+	/************************/
+
+	if (insn->n >= 1) {
+	   /***************************/
+		/* Test the channel number */
+	   /***************************/
+
+		if (b_Channel < devpriv->ps_BoardInfo->i_NbrDoChannel) {
+	      /*******************/
+			/* Get the command */
+	      /*******************/
+
+			b_State = (BYTE) data[0];
+
+	      /********************************/
+			/* Read the digital output port */
+	      /********************************/
+
+			dw_Status = inl(devpriv->iobase + 48);
+
+			dw_Status =
+				(dw_Status & (0xF -
+					(1 << b_Channel))) | ((b_State & 1) <<
+				b_Channel);
+			outl(dw_Status, devpriv->iobase + 48);
+		} else {
+	      /***************************/
+			/* Channel selection error */
+	      /***************************/
+
+			printk("Channel selection error\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*******************/
+		/* Data size error */
+	   /*******************/
+
+		printk("Buffer size error\n");
+		i_ReturnValue = -101;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name     :int i_APCI3XXX_InsnReadDigitalOutput                    |
+|                                          (struct comedi_device *dev,              |
+|                                           struct comedi_subdevice *s,             |
+|                                           struct comedi_insn *insn,               |
+|                                           unsigned int *data)                  |
++----------------------------------------------------------------------------+
+| Task              : Read the state from digital output channel             |
++----------------------------------------------------------------------------+
+| Input Parameters  : b_Channel = CR_CHAN(insn->chanspec)                    |
++----------------------------------------------------------------------------+
+| Output Parameters : b_State   = data [0]                                   |
++----------------------------------------------------------------------------+
+| Return Value      : >0  : No error                                         |
+|                    -3   : Channel selection error                          |
+|                    -101 : Data size error                                  |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnReadDigitalOutput(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	INT i_ReturnValue = insn->n;
+	BYTE b_Channel = CR_CHAN(insn->chanspec);
+	DWORD dw_Status = 0;
+
+	/************************/
+	/* Test the buffer size */
+	/************************/
+
+	if (insn->n >= 1) {
+	   /***************************/
+		/* Test the channel number */
+	   /***************************/
+
+		if (b_Channel < devpriv->ps_BoardInfo->i_NbrDoChannel) {
+	      /********************************/
+			/* Read the digital output port */
+	      /********************************/
+
+			dw_Status = inl(devpriv->iobase + 48);
+
+			dw_Status = (dw_Status >> b_Channel) & 1;
+			*data = dw_Status;
+		} else {
+	      /***************************/
+			/* Channel selection error */
+	      /***************************/
+
+			printk("Channel selection error\n");
+			i_ReturnValue = -3;
+		}
+	} else {
+	   /*******************/
+		/* Data size error */
+	   /*******************/
+
+		printk("Buffer size error\n");
+		i_ReturnValue = -101;
+	}
+
+	return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function   Name   : int i_APCI3XXX_Reset(struct comedi_device *dev)               |                                                         +----------------------------------------------------------------------------+
+| Task              :resets all the registers                                |
++----------------------------------------------------------------------------+
+| Input Parameters  : struct comedi_device *dev                                     |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : -                                                      |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_Reset(struct comedi_device * dev)
+{
+	unsigned char b_Cpt = 0;
+
+	/*************************/
+	/* Disable the interrupt */
+	/*************************/
+
+	disable_irq(dev->irq);
+
+	/****************************/
+	/* Reset the interrupt flag */
+	/****************************/
+
+	devpriv->b_EocEosInterrupt = 0;
+
+	/***************************/
+	/* Clear the start command */
+	/***************************/
+
+	writel(0, (void *)(devpriv->dw_AiBase + 8));
+
+	/*****************************/
+	/* Reset the interrupt flags */
+	/*****************************/
+
+	writel(readl((void *)(devpriv->dw_AiBase + 16)),
+		(void *)(devpriv->dw_AiBase + 16));
+
+	/*****************/
+	/* clear the EOS */
+	/*****************/
+
+	readl((void *)(devpriv->dw_AiBase + 20));
+
+	/******************/
+	/* Clear the FIFO */
+	/******************/
+
+	for (b_Cpt = 0; b_Cpt < 16; b_Cpt++) {
+		readl((void *)(devpriv->dw_AiBase + 28));
+	}
+
+	/************************/
+	/* Enable the interrupt */
+	/************************/
+
+	enable_irq(dev->irq);
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.h
new file mode 100644
index 0000000..788d7c1
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data-com
+ *	info@addi-data.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.
+ */
+
+#ifndef COMEDI_SUBD_TTLIO
+#define COMEDI_SUBD_TTLIO   11	/* Digital Input Output But TTL */
+#endif
+
+#ifndef ADDIDATA_ENABLE
+#define ADDIDATA_ENABLE  1
+#define ADDIDATA_DISABLE 0
+#endif
+
+#define APCI3XXX_SINGLE                              0
+#define APCI3XXX_DIFF                                1
+#define APCI3XXX_CONFIGURATION                       0
+
+#define APCI3XXX_TTL_INIT_DIRECTION_PORT2   0
+
+#ifdef __KERNEL__
+
+static const struct comedi_lrange range_apci3XXX_ai = { 8, {BIP_RANGE(10),
+						     BIP_RANGE(5),
+						     BIP_RANGE(2),
+						     BIP_RANGE(1),
+						     UNI_RANGE(10),
+						     UNI_RANGE(5),
+						     UNI_RANGE(2),
+						     UNI_RANGE(1)}
+};
+
+static const struct comedi_lrange range_apci3XXX_ttl = { 12, {BIP_RANGE(1),
+						       BIP_RANGE(1),
+						       BIP_RANGE(1),
+						       BIP_RANGE(1),
+						       BIP_RANGE(1),
+						       BIP_RANGE(1),
+						       BIP_RANGE(1),
+						       BIP_RANGE(1),
+						       BIP_RANGE(1),
+						       BIP_RANGE(1),
+						       BIP_RANGE(1),
+						       BIP_RANGE(1)}
+};
+
+static const struct comedi_lrange range_apci3XXX_ao = { 2, {BIP_RANGE(10),
+						     UNI_RANGE(10)}
+};
+#endif
diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c
new file mode 100644
index 0000000..bac0182
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_035.c
@@ -0,0 +1,5 @@
+#define CONFIG_APCI_035 1
+
+#define ADDIDATA_WATCHDOG 2	// Or shold it be something else
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c
new file mode 100644
index 0000000..fa2056e
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_1032.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_1032 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c
new file mode 100644
index 0000000..7a5cae5
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_1500.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_1500 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c
new file mode 100644
index 0000000..8d414844
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_1516.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_1516 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c
new file mode 100644
index 0000000..0351cdd
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_1564.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_1564 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c
new file mode 100644
index 0000000..5067990
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_16XX 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c
new file mode 100644
index 0000000..c433445
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_1710.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_1710 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_2016.c b/drivers/staging/comedi/drivers/addi_apci_2016.c
new file mode 100644
index 0000000..271c47c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_2016.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_2016 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c
new file mode 100644
index 0000000..5108ea2
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_2032.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_2032 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c
new file mode 100644
index 0000000..e439f83
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_2200.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_2200 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_3001.c b/drivers/staging/comedi/drivers/addi_apci_3001.c
new file mode 100644
index 0000000..df97c30
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_3001.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_3001 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c
new file mode 100644
index 0000000..9183125
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_3120.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_3120 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c
new file mode 100644
index 0000000..f25a70b32
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_3200.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_3200 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_3300.c b/drivers/staging/comedi/drivers/addi_apci_3300.c
new file mode 100644
index 0000000..1ee4778
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_3300.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_3300 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c
new file mode 100644
index 0000000..1049e20
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_3501.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_3501 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c
new file mode 100644
index 0000000..fb9deb70
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_3XXX 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_all.c b/drivers/staging/comedi/drivers/addi_apci_all.c
new file mode 100644
index 0000000..aeb1b26
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_all.c
@@ -0,0 +1,18 @@
+#define CONFIG_APCI_035  1
+#define CONFIG_APCI_1032 1
+#define CONFIG_APCI_1500 1
+#define CONFIG_APCI_1516 1
+#define CONFIG_APCI_1564 1
+#define CONFIG_APCI_16XX 1
+#define CONFIG_APCI_1710 1
+#define CONFIG_APCI_2016 1
+#define CONFIG_APCI_2032 1
+#define CONFIG_APCI_2200 1
+#define CONFIG_APCI_3001 1
+#define CONFIG_APCI_3120 1
+#define CONFIG_APCI_3200 1
+#define CONFIG_APCI_3300 1
+#define CONFIG_APCI_3501 1
+#define CONFIG_APCI_3XXX 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c
new file mode 100644
index 0000000..f710f551
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adl_pci6208.c
@@ -0,0 +1,391 @@
+/*
+    comedi/drivers/adl_pci6208.c
+
+    Hardware driver for ADLink 6208 series cards:
+	card	     | voltage output    | current output
+	-------------+-------------------+---------------
+	PCI-6208V    |  8 channels       | -
+	PCI-6216V    | 16 channels       | -
+	PCI-6208A    |  8 channels       | 8 channels
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000 David A. Schleef <ds@schleef.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.
+
+    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.
+*/
+/*
+Driver: adl_pci6208
+Description: ADLink PCI-6208A
+Devices: [ADLink] PCI-6208A (adl_pci6208)
+Author: nsyeow <nsyeow@pd.jaring.my>
+Updated: Fri, 30 Jan 2004 14:44:27 +0800
+Status: untested
+
+Configuration Options:
+  none
+
+References:
+	- ni_660x.c
+	- adl_pci9111.c		copied the entire pci setup section
+	- adl_pci9118.c
+*/
+/*
+ * These headers should be followed by a blank line, and any comments
+ * you wish to say about the driver.  The comment area is the place
+ * to put any known bugs, limitations, unsupported features, supported
+ * command triggers, whether or not commands are supported on particular
+ * subdevices, etc.
+ *
+ * Somewhere in the comment should be information about configuration
+ * options that are used with comedi_config.
+ */
+#include "../comedidev.h"
+#include "comedi_pci.h"
+
+#define PCI6208_DRIVER_NAME 	"adl_pci6208"
+
+/* Board descriptions */
+struct pci6208_board {
+	const char *name;
+	unsigned short dev_id;	/* `lspci` will show you this */
+	int ao_chans;
+	//int ao_bits;
+};
+
+static const struct pci6208_board pci6208_boards[] = {
+	/*{
+	   name :  "pci6208v",
+	   dev_id       :  0x6208,      //not sure
+	   ao_chans:  8
+	   //,  ao_bits :  16
+	   },
+	   {
+	   name :  "pci6216v",
+	   dev_id       :  0x6208,      //not sure
+	   ao_chans:  16
+	   //,  ao_bits :  16
+	   }, */
+	{
+	      name:	"pci6208a",
+	      dev_id:	0x6208,
+	      ao_chans:8
+			//,     ao_bits :  16
+		}
+};
+
+/* This is used by modprobe to translate PCI IDs to drivers.  Should
+ * only be used for PCI and ISA-PnP devices */
+static DEFINE_PCI_DEVICE_TABLE(pci6208_pci_table) = {
+	//{ PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	//{ PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	{PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci6208_pci_table);
+
+/* Will be initialized in pci6208_find device(). */
+#define thisboard ((const struct pci6208_board *)dev->board_ptr)
+
+struct pci6208_private {
+	int data;
+	struct pci_dev *pci_dev;	/* for a PCI device */
+	unsigned int ao_readback[2];	/* Used for AO readback */
+};
+
+#define devpriv ((struct pci6208_private *)dev->private)
+
+static int pci6208_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci6208_detach(struct comedi_device * dev);
+
+#define pci6208_board_nbr \
+	(sizeof(pci6208_boards) / sizeof(struct pci6208_board))
+
+static struct comedi_driver driver_pci6208 = {
+      driver_name:PCI6208_DRIVER_NAME,
+      module:THIS_MODULE,
+      attach:pci6208_attach,
+      detach:pci6208_detach,
+};
+
+COMEDI_PCI_INITCLEANUP(driver_pci6208, pci6208_pci_table);
+
+static int pci6208_find_device(struct comedi_device * dev, int bus, int slot);
+static int
+pci6208_pci_setup(struct pci_dev *pci_dev, unsigned long *io_base_ptr,
+	int dev_minor);
+
+/*read/write functions*/
+static int pci6208_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int pci6208_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+//static int pci6208_dio_insn_bits(struct comedi_device *dev,struct comedi_subdevice *s,
+//      struct comedi_insn *insn,unsigned int *data);
+//static int pci6208_dio_insn_config(struct comedi_device *dev,struct comedi_subdevice *s,
+//      struct comedi_insn *insn,unsigned int *data);
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board.  If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pci6208_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	int retval;
+	unsigned long io_base;
+
+	printk("comedi%d: pci6208: ", dev->minor);
+
+	retval = alloc_private(dev, sizeof(struct pci6208_private));
+	if (retval < 0)
+		return retval;
+
+	retval = pci6208_find_device(dev, it->options[0], it->options[1]);
+	if (retval < 0)
+		return retval;
+
+	retval = pci6208_pci_setup(devpriv->pci_dev, &io_base, dev->minor);
+	if (retval < 0)
+		return retval;
+
+	dev->iobase = io_base;
+	dev->board_name = thisboard->name;
+
+/*
+ * Allocate the subdevice structures.  alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+	if (alloc_subdevices(dev, 2) < 0)
+		return -ENOMEM;
+
+	s = dev->subdevices + 0;
+	/* analog output subdevice */
+	s->type = COMEDI_SUBD_AO;
+	s->subdev_flags = SDF_WRITABLE;	//anything else to add here??
+	s->n_chan = thisboard->ao_chans;
+	s->maxdata = 0xffff;	//16-bit DAC
+	s->range_table = &range_bipolar10;	//this needs to be checked.
+	s->insn_write = pci6208_ao_winsn;
+	s->insn_read = pci6208_ao_rinsn;
+
+	//s=dev->subdevices+1;
+	/* digital i/o subdevice */
+	//s->type=COMEDI_SUBD_DIO;
+	//s->subdev_flags=SDF_READABLE|SDF_WRITABLE;
+	//s->n_chan=16;
+	//s->maxdata=1;
+	//s->range_table=&range_digital;
+	//s->insn_bits = pci6208_dio_insn_bits;
+	//s->insn_config = pci6208_dio_insn_config;
+
+	printk("attached\n");
+
+	return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device.  It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach().  dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pci6208_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: pci6208: remove\n", dev->minor);
+
+	if (devpriv && devpriv->pci_dev) {
+		if (dev->iobase) {
+			comedi_pci_disable(devpriv->pci_dev);
+		}
+		pci_dev_put(devpriv->pci_dev);
+	}
+
+	return 0;
+}
+
+static int pci6208_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i = 0, Data_Read;
+	unsigned short chan = CR_CHAN(insn->chanspec);
+	unsigned long invert = 1 << (16 - 1);
+	unsigned long out_value;
+	/* Writing a list of values to an AO channel is probably not
+	 * very useful, but that's how the interface is defined. */
+	for (i = 0; i < insn->n; i++) {
+		out_value = data[i] ^ invert;
+		/* a typical programming sequence */
+		do {
+			Data_Read = (inw(dev->iobase) & 1);
+		} while (Data_Read);
+		outw(out_value, dev->iobase + (0x02 * chan));
+		devpriv->ao_readback[chan] = out_value;
+	}
+
+	/* return the number of samples read/written */
+	return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+ * Usually this means copying a value stored in devpriv. */
+static int pci6208_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+
+	for (i = 0; i < insn->n; i++)
+		data[i] = devpriv->ao_readback[chan];
+
+	return i;
+}
+
+/* DIO devices are slightly special.  Although it is possible to
+ * implement the insn_read/insn_write interface, it is much more
+ * useful to applications if you implement the insn_bits interface.
+ * This allows packed reading/writing of the DIO channels.  The
+ * comedi core can convert between insn_bits and insn_read/write */
+//static int pci6208_dio_insn_bits(struct comedi_device *dev,struct comedi_subdevice *s,
+//      struct comedi_insn *insn,unsigned int *data)
+//{
+//      if(insn->n!=2)return -EINVAL;
+
+	/* The insn data is a mask in data[0] and the new data
+	 * in data[1], each channel cooresponding to a bit. */
+//      if(data[0]){
+//              s->state &= ~data[0];
+//              s->state |= data[0]&data[1];
+		/* Write out the new digital output lines */
+		//outw(s->state,dev->iobase + SKEL_DIO);
+//      }
+
+	/* on return, data[1] contains the value of the digital
+	 * input and output lines. */
+	//data[1]=inw(dev->iobase + SKEL_DIO);
+	/* or we could just return the software copy of the output values if
+	 * it was a purely digital output subdevice */
+	//data[1]=s->state;
+
+//      return 2;
+//}
+
+//static int pci6208_dio_insn_config(struct comedi_device *dev,struct comedi_subdevice *s,
+//      struct comedi_insn *insn,unsigned int *data)
+//{
+//      int chan=CR_CHAN(insn->chanspec);
+
+	/* The input or output configuration of each digital line is
+	 * configured by a special insn_config instruction.  chanspec
+	 * contains the channel to be changed, and data[0] contains the
+	 * value COMEDI_INPUT or COMEDI_OUTPUT. */
+
+//      if(data[0]==COMEDI_OUTPUT){
+//              s->io_bits |= 1<<chan;
+//      }else{
+//              s->io_bits &= ~(1<<chan);
+//      }
+	//outw(s->io_bits,dev->iobase + SKEL_DIO_CONFIG);
+
+//      return 1;
+//}
+
+static int pci6208_find_device(struct comedi_device * dev, int bus, int slot)
+{
+	struct pci_dev *pci_dev;
+	int i;
+
+	for (pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+		pci_dev != NULL;
+		pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) {
+		if (pci_dev->vendor == PCI_VENDOR_ID_ADLINK) {
+			for (i = 0; i < pci6208_board_nbr; i++) {
+				if (pci6208_boards[i].dev_id == pci_dev->device) {
+					// was a particular bus/slot requested?
+					if ((bus != 0) || (slot != 0)) {
+						// are we on the wrong bus/slot?
+						if (pci_dev->bus->number
+							!= bus ||
+							PCI_SLOT(pci_dev->devfn)
+							!= slot) {
+							continue;
+						}
+					}
+					dev->board_ptr = pci6208_boards + i;
+					goto found;
+				}
+			}
+		}
+	}
+
+	printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
+		dev->minor, bus, slot);
+	return -EIO;
+
+      found:
+	printk("comedi%d: found %s (b:s:f=%d:%d:%d) , irq=%d\n",
+		dev->minor,
+		pci6208_boards[i].name,
+		pci_dev->bus->number,
+		PCI_SLOT(pci_dev->devfn),
+		PCI_FUNC(pci_dev->devfn), pci_dev->irq);
+
+	// TODO: Warn about non-tested boards.
+	//switch(board->device_id)
+	//{
+	//};
+
+	devpriv->pci_dev = pci_dev;
+
+	return 0;
+}
+
+static int
+pci6208_pci_setup(struct pci_dev *pci_dev, unsigned long *io_base_ptr,
+	int dev_minor)
+{
+	unsigned long io_base, io_range, lcr_io_base, lcr_io_range;
+
+	// Enable PCI device and request regions
+	if (comedi_pci_enable(pci_dev, PCI6208_DRIVER_NAME) < 0) {
+		printk("comedi%d: Failed to enable PCI device and request regions\n", dev_minor);
+		return -EIO;
+	}
+	// Read local configuration register base address [PCI_BASE_ADDRESS #1].
+	lcr_io_base = pci_resource_start(pci_dev, 1);
+	lcr_io_range = pci_resource_len(pci_dev, 1);
+
+	printk("comedi%d: local config registers at address 0x%4lx [0x%4lx]\n",
+		dev_minor, lcr_io_base, lcr_io_range);
+
+	// Read PCI6208 register base address [PCI_BASE_ADDRESS #2].
+	io_base = pci_resource_start(pci_dev, 2);
+	io_range = pci_resource_end(pci_dev, 2) - io_base + 1;
+
+	printk("comedi%d: 6208 registers at address 0x%4lx [0x%4lx]\n",
+		dev_minor, io_base, io_range);
+
+	*io_base_ptr = io_base;
+	//devpriv->io_range = io_range;
+	//devpriv->is_valid=0;
+	//devpriv->lcr_io_base=lcr_io_base;
+	//devpriv->lcr_io_range=lcr_io_range;
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/adl_pci7296.c b/drivers/staging/comedi/drivers/adl_pci7296.c
new file mode 100644
index 0000000..bd0f9ab
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adl_pci7296.c
@@ -0,0 +1,174 @@
+/*
+    comedi/drivers/adl_pci7296.c
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: adl_pci7296
+Description: Driver for the Adlink PCI-7296 96 ch. digital io board
+Devices: [ADLink] PCI-7296 (adl_pci7296)
+Author: Jon Grierson <jd@renko.co.uk>
+Updated: Mon, 14 Apr 2008 15:05:56 +0100
+Status: testing
+
+Configuration Options:
+  [0] - PCI bus of device (optional)
+  [1] - PCI slot of device (optional)
+  If bus/slot is not specified, the first supported
+  PCI device found will be used.
+*/
+
+#include "../comedidev.h"
+#include <linux/kernel.h>
+
+#include "comedi_pci.h"
+#include "8255.h"
+// #include "8253.h"
+
+#define PORT1A 0
+#define PORT2A 4
+#define PORT3A 8
+#define PORT4A 12
+
+#define PCI_DEVICE_ID_PCI7296 0x7296
+
+static DEFINE_PCI_DEVICE_TABLE(adl_pci7296_pci_table) = {
+	{PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7296, PCI_ANY_ID, PCI_ANY_ID, 0,
+		0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, adl_pci7296_pci_table);
+
+struct adl_pci7296_private {
+	int data;
+	struct pci_dev *pci_dev;
+};
+
+
+#define devpriv ((struct adl_pci7296_private *)dev->private)
+
+static int adl_pci7296_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int adl_pci7296_detach(struct comedi_device * dev);
+static struct comedi_driver driver_adl_pci7296 = {
+      driver_name:"adl_pci7296",
+      module:THIS_MODULE,
+      attach:adl_pci7296_attach,
+      detach:adl_pci7296_detach,
+};
+
+static int adl_pci7296_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct pci_dev *pcidev;
+	struct comedi_subdevice *s;
+	int bus, slot;
+	int ret;
+
+	printk("comedi: attempt to attach...\n");
+	printk("comedi%d: adl_pci7432\n", dev->minor);
+
+	dev->board_name = "pci7432";
+	bus = it->options[0];
+	slot = it->options[1];
+
+	if (alloc_private(dev, sizeof(struct adl_pci7296_private)) < 0)
+		return -ENOMEM;
+
+	if (alloc_subdevices(dev, 4) < 0)
+		return -ENOMEM;
+
+	for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+		pcidev != NULL;
+		pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+
+		if (pcidev->vendor == PCI_VENDOR_ID_ADLINK &&
+			pcidev->device == PCI_DEVICE_ID_PCI7296) {
+			if (bus || slot) {
+				/* requested particular bus/slot */
+				if (pcidev->bus->number != bus
+					|| PCI_SLOT(pcidev->devfn) != slot) {
+					continue;
+				}
+			}
+			devpriv->pci_dev = pcidev;
+			if (comedi_pci_enable(pcidev, "adl_pci7296") < 0) {
+				printk("comedi%d: Failed to enable PCI device and request regions\n", dev->minor);
+				return -EIO;
+			}
+
+			dev->iobase = pci_resource_start(pcidev, 2);
+			printk("comedi: base addr %4lx\n", dev->iobase);
+
+			// four 8255 digital io subdevices
+			s = dev->subdevices + 0;
+			subdev_8255_init(dev, s, NULL,
+				(unsigned long)(dev->iobase));
+
+			s = dev->subdevices + 1;
+			ret = subdev_8255_init(dev, s, NULL,
+				(unsigned long)(dev->iobase + PORT2A));
+			if (ret < 0)
+				return ret;
+
+			s = dev->subdevices + 2;
+			ret = subdev_8255_init(dev, s, NULL,
+				(unsigned long)(dev->iobase + PORT3A));
+			if (ret < 0)
+				return ret;
+
+			s = dev->subdevices + 3;
+			ret = subdev_8255_init(dev, s, NULL,
+				(unsigned long)(dev->iobase + PORT4A));
+			if (ret < 0)
+				return ret;
+
+			printk("attached\n");
+
+			return 1;
+		}
+	}
+
+	printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
+		dev->minor, bus, slot);
+	return -EIO;
+}
+
+static int adl_pci7296_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: pci7432: remove\n", dev->minor);
+
+	if (devpriv && devpriv->pci_dev) {
+		if (dev->iobase) {
+			comedi_pci_disable(devpriv->pci_dev);
+		}
+		pci_dev_put(devpriv->pci_dev);
+	}
+	// detach four 8255 digital io subdevices
+	if (dev->subdevices) {
+		subdev_8255_cleanup(dev, dev->subdevices + 0);
+		subdev_8255_cleanup(dev, dev->subdevices + 1);
+		subdev_8255_cleanup(dev, dev->subdevices + 2);
+		subdev_8255_cleanup(dev, dev->subdevices + 3);
+
+	}
+
+	return 0;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_adl_pci7296, adl_pci7296_pci_table);
diff --git a/drivers/staging/comedi/drivers/adl_pci7432.c b/drivers/staging/comedi/drivers/adl_pci7432.c
new file mode 100644
index 0000000..a8f1715
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adl_pci7432.c
@@ -0,0 +1,202 @@
+/*
+    comedi/drivers/adl_pci7432.c
+
+    Hardware comedi driver fot PCI7432 Adlink card
+    Copyright (C) 2004 Michel Lachine <mike@mikelachaine.ca>
+
+    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.
+
+*/
+/*
+Driver: adl_pci7432
+Description: Driver for the Adlink PCI-7432 64 ch. isolated digital io board
+Devices: [ADLink] PCI-7432 (adl_pci7432)
+Author: Michel Lachaine <mike@mikelachaine.ca>
+Status: experimental
+Updated: Mon, 14 Apr 2008 15:08:14 +0100
+
+Configuration Options:
+  [0] - PCI bus of device (optional)
+  [1] - PCI slot of device (optional)
+  If bus/slot is not specified, the first supported
+  PCI device found will be used.
+*/
+
+#include "../comedidev.h"
+#include <linux/kernel.h>
+#include "comedi_pci.h"
+
+#define PCI7432_DI      0x00
+#define PCI7432_DO	    0x00
+
+#define PCI_DEVICE_ID_PCI7432 0x7432
+
+static DEFINE_PCI_DEVICE_TABLE(adl_pci7432_pci_table) = {
+	{PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7432, PCI_ANY_ID, PCI_ANY_ID, 0,
+		0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, adl_pci7432_pci_table);
+
+struct adl_pci7432_private {
+	int data;
+	struct pci_dev *pci_dev;
+};
+
+#define devpriv ((struct adl_pci7432_private *)dev->private)
+
+static int adl_pci7432_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int adl_pci7432_detach(struct comedi_device * dev);
+static struct comedi_driver driver_adl_pci7432 = {
+      driver_name:"adl_pci7432",
+      module:THIS_MODULE,
+      attach:adl_pci7432_attach,
+      detach:adl_pci7432_detach,
+};
+
+/* Digital IO */
+
+static int adl_pci7432_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci7432_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+/*            */
+
+static int adl_pci7432_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct pci_dev *pcidev;
+	struct comedi_subdevice *s;
+	int bus, slot;
+
+	printk("comedi: attempt to attach...\n");
+	printk("comedi%d: adl_pci7432\n", dev->minor);
+
+	dev->board_name = "pci7432";
+	bus = it->options[0];
+	slot = it->options[1];
+
+	if (alloc_private(dev, sizeof(struct adl_pci7432_private)) < 0)
+		return -ENOMEM;
+
+	if (alloc_subdevices(dev, 2) < 0)
+		return -ENOMEM;
+
+	for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+		pcidev != NULL;
+		pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+
+		if (pcidev->vendor == PCI_VENDOR_ID_ADLINK &&
+			pcidev->device == PCI_DEVICE_ID_PCI7432) {
+			if (bus || slot) {
+				/* requested particular bus/slot */
+				if (pcidev->bus->number != bus
+					|| PCI_SLOT(pcidev->devfn) != slot) {
+					continue;
+				}
+			}
+			devpriv->pci_dev = pcidev;
+			if (comedi_pci_enable(pcidev, "adl_pci7432") < 0) {
+				printk("comedi%d: Failed to enable PCI device and request regions\n", dev->minor);
+				return -EIO;
+			}
+			dev->iobase = pci_resource_start(pcidev, 2);
+			printk("comedi: base addr %4lx\n", dev->iobase);
+
+			s = dev->subdevices + 0;
+			s->type = COMEDI_SUBD_DI;
+			s->subdev_flags =
+				SDF_READABLE | SDF_GROUND | SDF_COMMON;
+			s->n_chan = 32;
+			s->maxdata = 1;
+			s->len_chanlist = 32;
+			s->io_bits = 0x00000000;
+			s->range_table = &range_digital;
+			s->insn_bits = adl_pci7432_di_insn_bits;
+
+			s = dev->subdevices + 1;
+			s->type = COMEDI_SUBD_DO;
+			s->subdev_flags =
+				SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+			s->n_chan = 32;
+			s->maxdata = 1;
+			s->len_chanlist = 32;
+			s->io_bits = 0xffffffff;
+			s->range_table = &range_digital;
+			s->insn_bits = adl_pci7432_do_insn_bits;
+
+			printk("comedi: attached\n");
+
+			return 1;
+		}
+	}
+
+	printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
+		dev->minor, bus, slot);
+	return -EIO;
+}
+
+static int adl_pci7432_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: pci7432: remove\n", dev->minor);
+
+	if (devpriv && devpriv->pci_dev) {
+		if (dev->iobase) {
+			comedi_pci_disable(devpriv->pci_dev);
+		}
+		pci_dev_put(devpriv->pci_dev);
+	}
+
+	return 0;
+}
+
+static int adl_pci7432_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	printk("comedi: pci7432_do_insn_bits called\n");
+	printk("comedi: data0: %8x data1: %8x\n", data[0], data[1]);
+
+	if (insn->n != 2)
+		return -EINVAL;
+
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= (data[0] & data[1]);
+
+		printk("comedi: out: %8x on iobase %4lx\n", s->state,
+			dev->iobase + PCI7432_DO);
+		outl(s->state & 0xffffffff, dev->iobase + PCI7432_DO);
+	}
+	return 2;
+}
+
+static int adl_pci7432_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	printk("comedi: pci7432_di_insn_bits called\n");
+	printk("comedi: data0: %8x data1: %8x\n", data[0], data[1]);
+
+	if (insn->n != 2)
+		return -EINVAL;
+
+	data[1] = inl(dev->iobase + PCI7432_DI) & 0xffffffff;
+	printk("comedi: data1 %8x\n", data[1]);
+
+	return 2;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_adl_pci7432, adl_pci7432_pci_table);
diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c
new file mode 100644
index 0000000..adf90be
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adl_pci8164.c
@@ -0,0 +1,512 @@
+/*
+    comedi/drivers/adl_pci8164.c
+
+    Hardware comedi driver fot PCI-8164 Adlink card
+    Copyright (C) 2004 Michel Lachine <mike@mikelachaine.ca>
+
+    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.
+
+*/
+/*
+Driver: adl_pci8164
+Description: Driver for the Adlink PCI-8164 4 Axes Motion Control board
+Devices: [ADLink] PCI-8164 (adl_pci8164)
+Author: Michel Lachaine <mike@mikelachaine.ca>
+Status: experimental
+Updated: Mon, 14 Apr 2008 15:10:32 +0100
+
+Configuration Options:
+  [0] - PCI bus of device (optional)
+  [1] - PCI slot of device (optional)
+  If bus/slot is not specified, the first supported
+  PCI device found will be used.
+*/
+
+#include "../comedidev.h"
+#include <linux/delay.h>
+#include "comedi_fc.h"
+#include "comedi_pci.h"
+#include "8253.h"
+
+#define PCI8164_AXIS_X  0x00
+#define PCI8164_AXIS_Y  0x08
+#define PCI8164_AXIS_Z  0x10
+#define PCI8164_AXIS_U  0x18
+
+#define PCI8164_MSTS	0x00
+#define PCI8164_SSTS    0x02
+#define PCI8164_BUF0    0x04
+#define PCI8164_BUF1    0x06
+
+#define PCI8164_CMD     0x00
+#define PCI8164_OTP     0x02
+
+#define PCI_DEVICE_ID_PCI8164 0x8164
+
+static DEFINE_PCI_DEVICE_TABLE(adl_pci8164_pci_table) = {
+	{PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI8164, PCI_ANY_ID, PCI_ANY_ID, 0,
+		0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, adl_pci8164_pci_table);
+
+struct adl_pci8164_private {
+	int data;
+	struct pci_dev *pci_dev;
+};
+
+#define devpriv ((struct adl_pci8164_private *)dev->private)
+
+static int adl_pci8164_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int adl_pci8164_detach(struct comedi_device * dev);
+static struct comedi_driver driver_adl_pci8164 = {
+      driver_name:"adl_pci8164",
+      module:THIS_MODULE,
+      attach:adl_pci8164_attach,
+      detach:adl_pci8164_detach,
+};
+
+static int adl_pci8164_insn_read_msts(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci8164_insn_read_ssts(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci8164_insn_read_buf0(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci8164_insn_read_buf1(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci8164_insn_write_cmd(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci8164_insn_write_otp(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci8164_insn_write_buf0(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci8164_insn_write_buf1(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci8164_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct pci_dev *pcidev;
+	struct comedi_subdevice *s;
+	int bus, slot;
+
+	printk("comedi: attempt to attach...\n");
+	printk("comedi%d: adl_pci8164\n", dev->minor);
+
+	dev->board_name = "pci8164";
+	bus = it->options[0];
+	slot = it->options[1];
+
+	if (alloc_private(dev, sizeof(struct adl_pci8164_private)) < 0)
+		return -ENOMEM;
+
+	if (alloc_subdevices(dev, 4) < 0)
+		return -ENOMEM;
+
+	for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+		pcidev != NULL;
+		pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+
+		if (pcidev->vendor == PCI_VENDOR_ID_ADLINK &&
+			pcidev->device == PCI_DEVICE_ID_PCI8164) {
+			if (bus || slot) {
+				/* requested particular bus/slot */
+				if (pcidev->bus->number != bus
+					|| PCI_SLOT(pcidev->devfn) != slot) {
+					continue;
+				}
+			}
+			devpriv->pci_dev = pcidev;
+			if (comedi_pci_enable(pcidev, "adl_pci8164") < 0) {
+				printk("comedi%d: Failed to enable PCI device and request regions\n", dev->minor);
+				return -EIO;
+			}
+			dev->iobase = pci_resource_start(pcidev, 2);
+			printk("comedi: base addr %4lx\n", dev->iobase);
+
+			s = dev->subdevices + 0;
+			s->type = COMEDI_SUBD_PROC;
+			s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+			s->n_chan = 4;
+			s->maxdata = 0xffff;
+			s->len_chanlist = 4;
+			//s->range_table = &range_axis;
+			s->insn_read = adl_pci8164_insn_read_msts;
+			s->insn_write = adl_pci8164_insn_write_cmd;
+
+			s = dev->subdevices + 1;
+			s->type = COMEDI_SUBD_PROC;
+			s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+			s->n_chan = 4;
+			s->maxdata = 0xffff;
+			s->len_chanlist = 4;
+			//s->range_table = &range_axis;
+			s->insn_read = adl_pci8164_insn_read_ssts;
+			s->insn_write = adl_pci8164_insn_write_otp;
+
+			s = dev->subdevices + 2;
+			s->type = COMEDI_SUBD_PROC;
+			s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+			s->n_chan = 4;
+			s->maxdata = 0xffff;
+			s->len_chanlist = 4;
+			//s->range_table = &range_axis;
+			s->insn_read = adl_pci8164_insn_read_buf0;
+			s->insn_write = adl_pci8164_insn_write_buf0;
+
+			s = dev->subdevices + 3;
+			s->type = COMEDI_SUBD_PROC;
+			s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+			s->n_chan = 4;
+			s->maxdata = 0xffff;
+			s->len_chanlist = 4;
+			//s->range_table = &range_axis;
+			s->insn_read = adl_pci8164_insn_read_buf1;
+			s->insn_write = adl_pci8164_insn_write_buf1;
+
+			printk("comedi: attached\n");
+
+			return 1;
+		}
+	}
+
+	printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
+		dev->minor, bus, slot);
+	return -EIO;
+}
+
+static int adl_pci8164_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: pci8164: remove\n", dev->minor);
+
+	if (devpriv && devpriv->pci_dev) {
+		if (dev->iobase) {
+			comedi_pci_disable(devpriv->pci_dev);
+		}
+		pci_dev_put(devpriv->pci_dev);
+	}
+
+	return 0;
+}
+
+static int adl_pci8164_insn_read_msts(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int axis, axis_reg;
+	char *axisname;
+
+	axis = CR_CHAN(insn->chanspec);
+
+	switch (axis) {
+	case 0:
+		axis_reg = PCI8164_AXIS_X;
+		axisname = "X";
+		break;
+	case 1:
+		axis_reg = PCI8164_AXIS_Y;
+		axisname = "Y";
+		break;
+	case 2:
+		axis_reg = PCI8164_AXIS_Z;
+		axisname = "Z";
+		break;
+	case 3:
+		axis_reg = PCI8164_AXIS_U;
+		axisname = "U";
+		break;
+	default:
+		axis_reg = PCI8164_AXIS_X;
+		axisname = "X";
+	}
+
+	data[0] = inw(dev->iobase + axis_reg + PCI8164_MSTS);
+	printk("comedi: pci8164 MSTS read -> %04X:%04X on axis %s\n", data[0],
+		data[1], axisname);
+
+	return 2;
+}
+
+static int adl_pci8164_insn_read_ssts(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int axis, axis_reg;
+	char *axisname;
+
+	axis = CR_CHAN(insn->chanspec);
+
+	switch (axis) {
+	case 0:
+		axis_reg = PCI8164_AXIS_X;
+		axisname = "X";
+		break;
+	case 1:
+		axis_reg = PCI8164_AXIS_Y;
+		axisname = "Y";
+		break;
+	case 2:
+		axis_reg = PCI8164_AXIS_Z;
+		axisname = "Z";
+		break;
+	case 3:
+		axis_reg = PCI8164_AXIS_U;
+		axisname = "U";
+		break;
+	default:
+		axis_reg = PCI8164_AXIS_X;
+		axisname = "X";
+	}
+
+	data[0] = inw(dev->iobase + axis_reg + PCI8164_SSTS);
+	printk("comedi: pci8164 SSTS read -> %04X:%04X on axis %s\n", data[0],
+		data[1], axisname);
+
+	return 2;
+}
+
+static int adl_pci8164_insn_read_buf0(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int axis, axis_reg;
+	char *axisname;
+
+	axis = CR_CHAN(insn->chanspec);
+
+	switch (axis) {
+	case 0:
+		axis_reg = PCI8164_AXIS_X;
+		axisname = "X";
+		break;
+	case 1:
+		axis_reg = PCI8164_AXIS_Y;
+		axisname = "Y";
+		break;
+	case 2:
+		axis_reg = PCI8164_AXIS_Z;
+		axisname = "Z";
+		break;
+	case 3:
+		axis_reg = PCI8164_AXIS_U;
+		axisname = "U";
+		break;
+	default:
+		axis_reg = PCI8164_AXIS_X;
+		axisname = "X";
+	}
+
+	data[0] = inw(dev->iobase + axis_reg + PCI8164_BUF0);
+	printk("comedi: pci8164 BUF0 read -> %04X:%04X on axis %s\n", data[0],
+		data[1], axisname);
+
+	return 2;
+}
+
+static int adl_pci8164_insn_read_buf1(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int axis, axis_reg;
+
+	char *axisname;
+
+	axis = CR_CHAN(insn->chanspec);
+
+	switch (axis) {
+	case 0:
+		axis_reg = PCI8164_AXIS_X;
+		axisname = "X";
+		break;
+	case 1:
+		axis_reg = PCI8164_AXIS_Y;
+		axisname = "Y";
+		break;
+	case 2:
+		axis_reg = PCI8164_AXIS_Z;
+		axisname = "Z";
+		break;
+	case 3:
+		axis_reg = PCI8164_AXIS_U;
+		axisname = "U";
+		break;
+	default:
+		axis_reg = PCI8164_AXIS_X;
+		axisname = "X";
+	}
+
+	data[0] = inw(dev->iobase + axis_reg + PCI8164_BUF1);
+	printk("comedi: pci8164 BUF1 read -> %04X:%04X on axis %s\n", data[0],
+		data[1], axisname);
+
+	return 2;
+}
+
+static int adl_pci8164_insn_write_cmd(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int axis, axis_reg;
+
+	char *axisname;
+
+	axis = CR_CHAN(insn->chanspec);
+
+	switch (axis) {
+	case 0:
+		axis_reg = PCI8164_AXIS_X;
+		axisname = "X";
+		break;
+	case 1:
+		axis_reg = PCI8164_AXIS_Y;
+		axisname = "Y";
+		break;
+	case 2:
+		axis_reg = PCI8164_AXIS_Z;
+		axisname = "Z";
+		break;
+	case 3:
+		axis_reg = PCI8164_AXIS_U;
+		axisname = "U";
+		break;
+	default:
+		axis_reg = PCI8164_AXIS_X;
+		axisname = "X";
+	}
+
+	outw(data[0], dev->iobase + axis_reg + PCI8164_CMD);
+	printk("comedi: pci8164 CMD write -> %04X:%04X on axis %s\n", data[0],
+		data[1], axisname);
+
+	return 2;
+}
+
+static int adl_pci8164_insn_write_otp(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int axis, axis_reg;
+
+	char *axisname;
+
+	axis = CR_CHAN(insn->chanspec);
+
+	switch (axis) {
+	case 0:
+		axis_reg = PCI8164_AXIS_X;
+		axisname = "X";
+		break;
+	case 1:
+		axis_reg = PCI8164_AXIS_Y;
+		axisname = "Y";
+		break;
+	case 2:
+		axis_reg = PCI8164_AXIS_Z;
+		axisname = "Z";
+		break;
+	case 3:
+		axis_reg = PCI8164_AXIS_U;
+		axisname = "U";
+		break;
+	default:
+		axis_reg = PCI8164_AXIS_X;
+		axisname = "X";
+	}
+
+	outw(data[0], dev->iobase + axis_reg + PCI8164_OTP);
+	printk("comedi: pci8164 OTP write -> %04X:%04X on axis %s\n", data[0],
+		data[1], axisname);
+
+	return 2;
+}
+
+static int adl_pci8164_insn_write_buf0(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	int axis, axis_reg;
+
+	char *axisname;
+
+	axis = CR_CHAN(insn->chanspec);
+
+	switch (axis) {
+	case 0:
+		axis_reg = PCI8164_AXIS_X;
+		axisname = "X";
+		break;
+	case 1:
+		axis_reg = PCI8164_AXIS_Y;
+		axisname = "Y";
+		break;
+	case 2:
+		axis_reg = PCI8164_AXIS_Z;
+		axisname = "Z";
+		break;
+	case 3:
+		axis_reg = PCI8164_AXIS_U;
+		axisname = "U";
+		break;
+	default:
+		axis_reg = PCI8164_AXIS_X;
+		axisname = "X";
+	}
+
+	outw(data[0], dev->iobase + axis_reg + PCI8164_BUF0);
+	printk("comedi: pci8164 BUF0 write -> %04X:%04X on axis %s\n", data[0],
+		data[1], axisname);
+
+	return 2;
+}
+
+static int adl_pci8164_insn_write_buf1(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	int axis, axis_reg;
+
+	char *axisname;
+
+	axis = CR_CHAN(insn->chanspec);
+
+	switch (axis) {
+	case 0:
+		axis_reg = PCI8164_AXIS_X;
+		axisname = "X";
+		break;
+	case 1:
+		axis_reg = PCI8164_AXIS_Y;
+		axisname = "Y";
+		break;
+	case 2:
+		axis_reg = PCI8164_AXIS_Z;
+		axisname = "Z";
+		break;
+	case 3:
+		axis_reg = PCI8164_AXIS_U;
+		axisname = "U";
+		break;
+	default:
+		axis_reg = PCI8164_AXIS_X;
+		axisname = "X";
+	}
+
+	outw(data[0], dev->iobase + axis_reg + PCI8164_BUF1);
+	printk("comedi: pci8164 BUF1 write -> %04X:%04X on axis %s\n", data[0],
+		data[1], axisname);
+
+	return 2;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_adl_pci8164, adl_pci8164_pci_table);
diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c
new file mode 100644
index 0000000..b4a61c5
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adl_pci9111.c
@@ -0,0 +1,1391 @@
+/*
+
+   comedi/drivers/adl_pci9111.c
+
+   Hardware driver for PCI9111 ADLink cards:
+
+     PCI-9111HR
+
+   Copyright (C) 2002-2005 Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+Driver: adl_pci9111
+Description: Adlink PCI-9111HR
+Author: Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.fr>
+Devices: [ADLink] PCI-9111HR (adl_pci9111)
+Status: experimental
+
+Supports:
+
+  - ai_insn read
+  - ao_insn read/write
+  - di_insn read
+  - do_insn read/write
+  - ai_do_cmd mode with the following sources:
+
+    - start_src 		TRIG_NOW
+    - scan_begin_src 		TRIG_FOLLOW	TRIG_TIMER	TRIG_EXT
+    - convert_src				TRIG_TIMER	TRIG_EXT
+    - scan_end_src		TRIG_COUNT
+    - stop_src			TRIG_COUNT	TRIG_NONE
+
+    The scanned channels must be consecutive and start from 0. They must
+    all have the same range and aref.
+
+Configuration options:
+
+    [0] - PCI bus number (optional)
+    [1] - PCI slot number (optional)
+
+    If bus/slot is not specified, the first available PCI
+    device will be used.
+
+*/
+
+/*
+CHANGELOG:
+
+  2005/02/17 Extend AI streaming capabilities. Now, scan_begin_arg can be
+  a multiple of chanlist_len*convert_arg.
+  2002/02/19 Fixed the two's complement conversion in pci9111_(hr_)ai_get_data.
+  2002/02/18 Added external trigger support for analog input.
+
+TODO:
+
+  - Really test implemented functionality.
+  - Add support for the PCI-9111DG with a probe routine to identify the card type
+    (perhaps with the help of the channel number readback of the A/D Data register).
+  - Add external multiplexer support.
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+
+#include "8253.h"
+#include "comedi_pci.h"
+#include "comedi_fc.h"
+
+#define PCI9111_DRIVER_NAME 	"adl_pci9111"
+#define PCI9111_HR_DEVICE_ID 	0x9111
+
+/*  TODO: Add other pci9111 board id */
+
+#define PCI9111_IO_RANGE 	0x0100
+
+#define PCI9111_FIFO_HALF_SIZE	512
+
+#define PCI9111_AI_CHANNEL_NBR			16
+
+#define PCI9111_AI_RESOLUTION			12
+#define PCI9111_AI_RESOLUTION_MASK		0x0FFF
+#define PCI9111_AI_RESOLUTION_2_CMP_BIT		0x0800
+
+#define PCI9111_HR_AI_RESOLUTION		16
+#define PCI9111_HR_AI_RESOLUTION_MASK		0xFFFF
+#define PCI9111_HR_AI_RESOLUTION_2_CMP_BIT	0x8000
+
+#define PCI9111_AI_ACQUISITION_PERIOD_MIN_NS	10000
+#define PCI9111_AO_CHANNEL_NBR			1
+#define	PCI9111_AO_RESOLUTION			12
+#define PCI9111_AO_RESOLUTION_MASK		0x0FFF
+#define PCI9111_DI_CHANNEL_NBR			16
+#define	PCI9111_DO_CHANNEL_NBR			16
+#define PCI9111_DO_MASK				0xFFFF
+
+#define PCI9111_RANGE_SETTING_DELAY		10
+#define PCI9111_AI_INSTANT_READ_UDELAY_US	2
+#define PCI9111_AI_INSTANT_READ_TIMEOUT		100
+
+#define PCI9111_8254_CLOCK_PERIOD_NS		500
+
+#define PCI9111_8254_COUNTER_0			0x00
+#define PCI9111_8254_COUNTER_1			0x40
+#define PCI9111_8254_COUNTER_2			0x80
+#define PCI9111_8254_COUNTER_LATCH		0x00
+#define PCI9111_8254_READ_LOAD_LSB_ONLY		0x10
+#define PCI9111_8254_READ_LOAD_MSB_ONLY		0x20
+#define PCI9111_8254_READ_LOAD_LSB_MSB		0x30
+#define PCI9111_8254_MODE_0			0x00
+#define PCI9111_8254_MODE_1			0x02
+#define PCI9111_8254_MODE_2			0x04
+#define PCI9111_8254_MODE_3			0x06
+#define PCI9111_8254_MODE_4			0x08
+#define PCI9111_8254_MODE_5			0x0A
+#define PCI9111_8254_BINARY_COUNTER		0x00
+#define PCI9111_8254_BCD_COUNTER		0x01
+
+/* IO address map */
+
+#define PCI9111_REGISTER_AD_FIFO_VALUE 			0x00	/*  AD Data stored in FIFO */
+#define PCI9111_REGISTER_DA_OUTPUT 			0x00
+#define PCI9111_REGISTER_DIGITAL_IO 			0x02
+#define PCI9111_REGISTER_EXTENDED_IO_PORTS 		0x04
+#define PCI9111_REGISTER_AD_CHANNEL_CONTROL 		0x06	/*  Channel selection */
+#define PCI9111_REGISTER_AD_CHANNEL_READBACK 		0x06
+#define PCI9111_REGISTER_INPUT_SIGNAL_RANGE 		0x08
+#define PCI9111_REGISTER_RANGE_STATUS_READBACK 		0x08
+#define PCI9111_REGISTER_TRIGGER_MODE_CONTROL 		0x0A
+#define PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK 	0x0A
+#define PCI9111_REGISTER_SOFTWARE_TRIGGER 		0x0E
+#define PCI9111_REGISTER_INTERRUPT_CONTROL 		0x0C
+#define PCI9111_REGISTER_8254_COUNTER_0			0x40
+#define PCI9111_REGISTER_8254_COUNTER_1			0x42
+#define PCI9111_REGISTER_8254_COUNTER_2 		0X44
+#define PCI9111_REGISTER_8254_CONTROL			0x46
+#define PCI9111_REGISTER_INTERRUPT_CLEAR 		0x48
+
+#define PCI9111_TRIGGER_MASK 				0x0F
+#define PCI9111_PTRG_OFF 				(0 << 3)
+#define PCI9111_PTRG_ON 				(1 << 3)
+#define PCI9111_EITS_EXTERNAL				(1 << 2)
+#define PCI9111_EITS_INTERNAL				(0 << 2)
+#define PCI9111_TPST_SOFTWARE_TRIGGER			(0 << 1)
+#define PCI9111_TPST_TIMER_PACER			(1 << 1)
+#define PCI9111_ASCAN_ON				(1 << 0)
+#define PCI9111_ASCAN_OFF				(0 << 0)
+
+#define PCI9111_ISC0_SET_IRQ_ON_ENDING_OF_AD_CONVERSION (0 << 0)
+#define PCI9111_ISC0_SET_IRQ_ON_FIFO_HALF_FULL		(1 << 0)
+#define PCI9111_ISC1_SET_IRQ_ON_TIMER_TICK  		(0 << 1)
+#define PCI9111_ISC1_SET_IRQ_ON_EXT_TRG 		(1 << 1)
+#define PCI9111_FFEN_SET_FIFO_ENABLE 			(0 << 2)
+#define PCI9111_FFEN_SET_FIFO_DISABLE			(1 << 2)
+
+#define PCI9111_CHANNEL_MASK				0x0F
+
+#define PCI9111_RANGE_MASK				0x07
+#define PCI9111_FIFO_EMPTY_MASK				0x10
+#define PCI9111_FIFO_HALF_FULL_MASK			0x20
+#define PCI9111_FIFO_FULL_MASK				0x40
+#define PCI9111_AD_BUSY_MASK				0x80
+
+#define PCI9111_IO_BASE dev->iobase
+
+/*
+ * Define inlined function
+ */
+
+#define pci9111_trigger_and_autoscan_get() \
+  (inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK)&0x0F)
+
+#define pci9111_trigger_and_autoscan_set(flags) \
+  outb(flags,PCI9111_IO_BASE+PCI9111_REGISTER_TRIGGER_MODE_CONTROL)
+
+#define pci9111_interrupt_and_fifo_get() \
+  ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK) >> 4) &0x03)
+
+#define pci9111_interrupt_and_fifo_set(flags) \
+  outb(flags,PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL)
+
+#define pci9111_interrupt_clear() \
+  outb(0,PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CLEAR)
+
+#define pci9111_software_trigger() \
+  outb(0,PCI9111_IO_BASE+PCI9111_REGISTER_SOFTWARE_TRIGGER)
+
+#define pci9111_fifo_reset() \
+  outb(PCI9111_FFEN_SET_FIFO_ENABLE,PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \
+  outb(PCI9111_FFEN_SET_FIFO_DISABLE,PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \
+  outb(PCI9111_FFEN_SET_FIFO_ENABLE,PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL)
+
+#define pci9111_is_fifo_full() \
+  ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
+    PCI9111_FIFO_FULL_MASK)==0)
+
+#define pci9111_is_fifo_half_full() \
+  ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
+    PCI9111_FIFO_HALF_FULL_MASK)==0)
+
+#define pci9111_is_fifo_empty() \
+  ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
+    PCI9111_FIFO_EMPTY_MASK)==0)
+
+#define pci9111_ai_channel_set(channel) \
+  outb((channel)&PCI9111_CHANNEL_MASK,PCI9111_IO_BASE+PCI9111_REGISTER_AD_CHANNEL_CONTROL)
+
+#define pci9111_ai_channel_get() \
+  inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_CHANNEL_READBACK)&PCI9111_CHANNEL_MASK
+
+#define pci9111_ai_range_set(range) \
+  outb((range)&PCI9111_RANGE_MASK,PCI9111_IO_BASE+PCI9111_REGISTER_INPUT_SIGNAL_RANGE)
+
+#define pci9111_ai_range_get() \
+  inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)&PCI9111_RANGE_MASK
+
+#define pci9111_ai_get_data() \
+  ((inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE)>>4)&PCI9111_AI_RESOLUTION_MASK) \
+  ^ PCI9111_AI_RESOLUTION_2_CMP_BIT
+
+#define pci9111_hr_ai_get_data() \
+  (inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE) & PCI9111_HR_AI_RESOLUTION_MASK) \
+  ^ PCI9111_HR_AI_RESOLUTION_2_CMP_BIT
+
+#define pci9111_ao_set_data(data) \
+  outw(data&PCI9111_AO_RESOLUTION_MASK,PCI9111_IO_BASE+PCI9111_REGISTER_DA_OUTPUT)
+
+#define pci9111_di_get_bits() \
+  inw(PCI9111_IO_BASE+PCI9111_REGISTER_DIGITAL_IO)
+
+#define pci9111_do_set_bits(bits) \
+  outw(bits,PCI9111_IO_BASE+PCI9111_REGISTER_DIGITAL_IO)
+
+#define pci9111_8254_control_set(flags) \
+  outb(flags,PCI9111_IO_BASE+PCI9111_REGISTER_8254_CONTROL)
+
+#define pci9111_8254_counter_0_set(data) \
+  outb(data & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_0); \
+  outb( (data >> 8) & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_0)
+
+#define pci9111_8254_counter_1_set(data) \
+  outb(data & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_1); \
+  outb( (data >> 8) & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_1)
+
+#define pci9111_8254_counter_2_set(data) \
+  outb(data & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_2); \
+  outb( (data >> 8) & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_2)
+
+/*  Function prototypes */
+
+static int pci9111_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci9111_detach(struct comedi_device * dev);
+static void pci9111_ai_munge(struct comedi_device * dev, struct comedi_subdevice * s,
+	void *data, unsigned int num_bytes, unsigned int start_chan_index);
+
+static const struct comedi_lrange pci9111_hr_ai_range = {
+	5,
+	{
+			BIP_RANGE(10),
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+			BIP_RANGE(0.625)
+		}
+};
+
+static DEFINE_PCI_DEVICE_TABLE(pci9111_pci_table) = {
+	{PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0,
+		0, 0},
+	/* { PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, */
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci9111_pci_table);
+
+/*  */
+/*  Board specification structure */
+/*  */
+
+struct pci9111_board {
+	const char *name;	/*  driver name */
+	int device_id;
+	int ai_channel_nbr;	/*  num of A/D chans */
+	int ao_channel_nbr;	/*  num of D/A chans */
+	int ai_resolution;	/*  resolution of A/D */
+	int ai_resolution_mask;
+	int ao_resolution;	/*  resolution of D/A */
+	int ao_resolution_mask;
+	const struct comedi_lrange *ai_range_list;	/*  rangelist for A/D */
+	const struct comedi_lrange *ao_range_list;	/*  rangelist for D/A */
+	unsigned int ai_acquisition_period_min_ns;
+};
+
+static const struct pci9111_board pci9111_boards[] = {
+	{
+	      name:	"pci9111_hr",
+	      device_id:PCI9111_HR_DEVICE_ID,
+	      ai_channel_nbr:PCI9111_AI_CHANNEL_NBR,
+	      ao_channel_nbr:PCI9111_AO_CHANNEL_NBR,
+	      ai_resolution:PCI9111_HR_AI_RESOLUTION,
+	      ai_resolution_mask:PCI9111_HR_AI_RESOLUTION_MASK,
+	      ao_resolution:PCI9111_AO_RESOLUTION,
+	      ao_resolution_mask:PCI9111_AO_RESOLUTION_MASK,
+	      ai_range_list:&pci9111_hr_ai_range,
+	      ao_range_list:&range_bipolar10,
+      ai_acquisition_period_min_ns:PCI9111_AI_ACQUISITION_PERIOD_MIN_NS}
+};
+
+#define pci9111_board_nbr \
+  (sizeof(pci9111_boards)/sizeof(struct pci9111_board))
+
+static struct comedi_driver pci9111_driver = {
+      driver_name:PCI9111_DRIVER_NAME,
+      module:THIS_MODULE,
+      attach:pci9111_attach,
+      detach:pci9111_detach,
+};
+
+COMEDI_PCI_INITCLEANUP(pci9111_driver, pci9111_pci_table);
+
+/*  Private data structure */
+
+struct pci9111_private_data {
+	struct pci_dev *pci_device;
+	unsigned long io_range;	/*  PCI6503 io range */
+
+	unsigned long lcr_io_base;	/*  Local configuration register base address */
+	unsigned long lcr_io_range;
+
+	int stop_counter;
+	int stop_is_none;
+
+	unsigned int scan_delay;
+	unsigned int chanlist_len;
+	unsigned int chunk_counter;
+	unsigned int chunk_num_samples;
+
+	int ao_readback;	/*  Last written analog output data */
+
+	int timer_divisor_1;	/*  Divisor values for the 8254 timer pacer */
+	int timer_divisor_2;
+
+	int is_valid;		/*  Is device valid */
+
+	short ai_bounce_buffer[2 * PCI9111_FIFO_HALF_SIZE];
+};
+
+#define dev_private 	((struct pci9111_private_data *)dev->private)
+
+/*  ------------------------------------------------------------------ */
+/*  PLX9050 SECTION */
+/*  ------------------------------------------------------------------ */
+
+#define PLX9050_REGISTER_INTERRUPT_CONTROL 0x4c
+
+#define PLX9050_LINTI1_ENABLE		(1 << 0)
+#define PLX9050_LINTI1_ACTIVE_HIGH	(1 << 1)
+#define PLX9050_LINTI1_STATUS		(1 << 2)
+#define PLX9050_LINTI2_ENABLE		(1 << 3)
+#define PLX9050_LINTI2_ACTIVE_HIGH	(1 << 4)
+#define PLX9050_LINTI2_STATUS		(1 << 5)
+#define PLX9050_PCI_INTERRUPT_ENABLE	(1 << 6)
+#define PLX9050_SOFTWARE_INTERRUPT	(1 << 7)
+
+static void plx9050_interrupt_control(unsigned long io_base,
+	bool LINTi1_enable,
+	bool LINTi1_active_high,
+	bool LINTi2_enable, bool LINTi2_active_high, bool interrupt_enable)
+{
+	int flags = 0;
+
+	if (LINTi1_enable)
+		flags |= PLX9050_LINTI1_ENABLE;
+	if (LINTi1_active_high)
+		flags |= PLX9050_LINTI1_ACTIVE_HIGH;
+	if (LINTi2_enable)
+		flags |= PLX9050_LINTI2_ENABLE;
+	if (LINTi2_active_high)
+		flags |= PLX9050_LINTI2_ACTIVE_HIGH;
+
+	if (interrupt_enable)
+		flags |= PLX9050_PCI_INTERRUPT_ENABLE;
+
+	outb(flags, io_base + PLX9050_REGISTER_INTERRUPT_CONTROL);
+}
+
+/*  ------------------------------------------------------------------ */
+/*  MISCELLANEOUS SECTION */
+/*  ------------------------------------------------------------------ */
+
+/*  8254 timer */
+
+static void pci9111_timer_set(struct comedi_device * dev)
+{
+	pci9111_8254_control_set(PCI9111_8254_COUNTER_0 |
+		PCI9111_8254_READ_LOAD_LSB_MSB |
+		PCI9111_8254_MODE_0 | PCI9111_8254_BINARY_COUNTER);
+
+	pci9111_8254_control_set(PCI9111_8254_COUNTER_1 |
+		PCI9111_8254_READ_LOAD_LSB_MSB |
+		PCI9111_8254_MODE_2 | PCI9111_8254_BINARY_COUNTER);
+
+	pci9111_8254_control_set(PCI9111_8254_COUNTER_2 |
+		PCI9111_8254_READ_LOAD_LSB_MSB |
+		PCI9111_8254_MODE_2 | PCI9111_8254_BINARY_COUNTER);
+
+	comedi_udelay(1);
+
+	pci9111_8254_counter_2_set(dev_private->timer_divisor_2);
+	pci9111_8254_counter_1_set(dev_private->timer_divisor_1);
+}
+
+enum pci9111_trigger_sources {
+	software,
+	timer_pacer,
+	external
+};
+
+static void pci9111_trigger_source_set(struct comedi_device * dev,
+	enum pci9111_trigger_sources source)
+{
+	int flags;
+
+	flags = pci9111_trigger_and_autoscan_get() & 0x09;
+
+	switch (source) {
+	case software:
+		flags |= PCI9111_EITS_INTERNAL | PCI9111_TPST_SOFTWARE_TRIGGER;
+		break;
+
+	case timer_pacer:
+		flags |= PCI9111_EITS_INTERNAL | PCI9111_TPST_TIMER_PACER;
+		break;
+
+	case external:
+		flags |= PCI9111_EITS_EXTERNAL;
+		break;
+	}
+
+	pci9111_trigger_and_autoscan_set(flags);
+}
+
+static void pci9111_pretrigger_set(struct comedi_device * dev, bool pretrigger)
+{
+	int flags;
+
+	flags = pci9111_trigger_and_autoscan_get() & 0x07;
+
+	if (pretrigger)
+		flags |= PCI9111_PTRG_ON;
+
+	pci9111_trigger_and_autoscan_set(flags);
+}
+
+static void pci9111_autoscan_set(struct comedi_device * dev, bool autoscan)
+{
+	int flags;
+
+	flags = pci9111_trigger_and_autoscan_get() & 0x0e;
+
+	if (autoscan)
+		flags |= PCI9111_ASCAN_ON;
+
+	pci9111_trigger_and_autoscan_set(flags);
+}
+
+enum pci9111_ISC0_sources {
+	irq_on_eoc,
+	irq_on_fifo_half_full
+};
+
+enum pci9111_ISC1_sources {
+	irq_on_timer_tick,
+	irq_on_external_trigger
+};
+
+static void pci9111_interrupt_source_set(struct comedi_device * dev,
+	enum pci9111_ISC0_sources irq_0_source, enum pci9111_ISC1_sources irq_1_source)
+{
+	int flags;
+
+	flags = pci9111_interrupt_and_fifo_get() & 0x04;
+
+	if (irq_0_source == irq_on_fifo_half_full)
+		flags |= PCI9111_ISC0_SET_IRQ_ON_FIFO_HALF_FULL;
+
+	if (irq_1_source == irq_on_external_trigger)
+		flags |= PCI9111_ISC1_SET_IRQ_ON_EXT_TRG;
+
+	pci9111_interrupt_and_fifo_set(flags);
+}
+
+/*  ------------------------------------------------------------------ */
+/*  HARDWARE TRIGGERED ANALOG INPUT SECTION */
+/*  ------------------------------------------------------------------ */
+
+/*  Cancel analog input autoscan */
+
+#undef AI_DO_CMD_DEBUG
+
+static int pci9111_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	/*  Disable interrupts */
+
+	plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true,
+		true, false);
+
+	pci9111_trigger_source_set(dev, software);
+
+	pci9111_autoscan_set(dev, false);
+
+	pci9111_fifo_reset();
+
+#ifdef AI_DO_CMD_DEBUG
+	printk(PCI9111_DRIVER_NAME ": ai_cancel\n");
+#endif
+
+	return 0;
+}
+
+/*  Test analog input command */
+
+#define pci9111_check_trigger_src(src,flags) \
+  tmp = src; \
+  src &= flags; \
+  if (!src || tmp != src) error++
+
+static int
+pci9111_ai_do_cmd_test(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_cmd * cmd)
+{
+	int tmp;
+	int error = 0;
+	int range, reference;
+	int i;
+	struct pci9111_board *board = (struct pci9111_board *) dev->board_ptr;
+
+	/*  Step 1 : check if trigger are trivialy valid */
+
+	pci9111_check_trigger_src(cmd->start_src, TRIG_NOW);
+	pci9111_check_trigger_src(cmd->scan_begin_src,
+		TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT);
+	pci9111_check_trigger_src(cmd->convert_src, TRIG_TIMER | TRIG_EXT);
+	pci9111_check_trigger_src(cmd->scan_end_src, TRIG_COUNT);
+	pci9111_check_trigger_src(cmd->stop_src, TRIG_COUNT | TRIG_NONE);
+
+	if (error)
+		return 1;
+
+	/*  step 2 : make sure trigger sources are unique and mutually compatible */
+
+	if (cmd->start_src != TRIG_NOW)
+		error++;
+
+	if ((cmd->scan_begin_src != TRIG_TIMER) &&
+		(cmd->scan_begin_src != TRIG_FOLLOW) &&
+		(cmd->scan_begin_src != TRIG_EXT))
+		error++;
+
+	if ((cmd->convert_src != TRIG_TIMER) && (cmd->convert_src != TRIG_EXT)) {
+		error++;
+	}
+	if ((cmd->convert_src == TRIG_TIMER) &&
+		!((cmd->scan_begin_src == TRIG_TIMER) ||
+			(cmd->scan_begin_src == TRIG_FOLLOW))) {
+		error++;
+	}
+	if ((cmd->convert_src == TRIG_EXT) &&
+		!((cmd->scan_begin_src == TRIG_EXT) ||
+			(cmd->scan_begin_src == TRIG_FOLLOW))) {
+		error++;
+	}
+
+	if (cmd->scan_end_src != TRIG_COUNT)
+		error++;
+	if ((cmd->stop_src != TRIG_COUNT) && (cmd->stop_src != TRIG_NONE))
+		error++;
+
+	if (error)
+		return 2;
+
+	/*  Step 3 : make sure arguments are trivialy compatible */
+
+	if (cmd->chanlist_len < 1) {
+		cmd->chanlist_len = 1;
+		error++;
+	}
+
+	if (cmd->chanlist_len > board->ai_channel_nbr) {
+		cmd->chanlist_len = board->ai_channel_nbr;
+		error++;
+	}
+
+	if ((cmd->start_src == TRIG_NOW) && (cmd->start_arg != 0)) {
+		cmd->start_arg = 0;
+		error++;
+	}
+
+	if ((cmd->convert_src == TRIG_TIMER) &&
+		(cmd->convert_arg < board->ai_acquisition_period_min_ns)) {
+		cmd->convert_arg = board->ai_acquisition_period_min_ns;
+		error++;
+	}
+	if ((cmd->convert_src == TRIG_EXT) && (cmd->convert_arg != 0)) {
+		cmd->convert_arg = 0;
+		error++;
+	}
+
+	if ((cmd->scan_begin_src == TRIG_TIMER) &&
+		(cmd->scan_begin_arg < board->ai_acquisition_period_min_ns)) {
+		cmd->scan_begin_arg = board->ai_acquisition_period_min_ns;
+		error++;
+	}
+	if ((cmd->scan_begin_src == TRIG_FOLLOW) && (cmd->scan_begin_arg != 0)) {
+		cmd->scan_begin_arg = 0;
+		error++;
+	}
+	if ((cmd->scan_begin_src == TRIG_EXT) && (cmd->scan_begin_arg != 0)) {
+		cmd->scan_begin_arg = 0;
+		error++;
+	}
+
+	if ((cmd->scan_end_src == TRIG_COUNT) &&
+		(cmd->scan_end_arg != cmd->chanlist_len)) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		error++;
+	}
+
+	if ((cmd->stop_src == TRIG_COUNT) && (cmd->stop_arg < 1)) {
+		cmd->stop_arg = 1;
+		error++;
+	}
+	if ((cmd->stop_src == TRIG_NONE) && (cmd->stop_arg != 0)) {
+		cmd->stop_arg = 0;
+		error++;
+	}
+
+	if (error)
+		return 3;
+
+	/*  Step 4 : fix up any arguments */
+
+	if (cmd->convert_src == TRIG_TIMER) {
+		tmp = cmd->convert_arg;
+		i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS,
+			&(dev_private->timer_divisor_1),
+			&(dev_private->timer_divisor_2),
+			&(cmd->convert_arg), cmd->flags & TRIG_ROUND_MASK);
+		if (tmp != cmd->convert_arg)
+			error++;
+	}
+	/*  There's only one timer on this card, so the scan_begin timer must */
+	/*  be a multiple of chanlist_len*convert_arg */
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+
+		unsigned int scan_begin_min;
+		unsigned int scan_begin_arg;
+		unsigned int scan_factor;
+
+		scan_begin_min = cmd->chanlist_len * cmd->convert_arg;
+
+		if (cmd->scan_begin_arg != scan_begin_min) {
+			if (scan_begin_min < cmd->scan_begin_arg) {
+				scan_factor =
+					cmd->scan_begin_arg / scan_begin_min;
+				scan_begin_arg = scan_factor * scan_begin_min;
+				if (cmd->scan_begin_arg != scan_begin_arg) {
+					cmd->scan_begin_arg = scan_begin_arg;
+					error++;
+				}
+			} else {
+				cmd->scan_begin_arg = scan_begin_min;
+				error++;
+			}
+		}
+	}
+
+	if (error)
+		return 4;
+
+	/*  Step 5 : check channel list */
+
+	if (cmd->chanlist) {
+
+		range = CR_RANGE(cmd->chanlist[0]);
+		reference = CR_AREF(cmd->chanlist[0]);
+
+		if (cmd->chanlist_len > 1) {
+			for (i = 0; i < cmd->chanlist_len; i++) {
+				if (CR_CHAN(cmd->chanlist[i]) != i) {
+					comedi_error(dev,
+						"entries in chanlist must be consecutive "
+						"channels,counting upwards from 0\n");
+					error++;
+				}
+				if (CR_RANGE(cmd->chanlist[i]) != range) {
+					comedi_error(dev,
+						"entries in chanlist must all have the same gain\n");
+					error++;
+				}
+				if (CR_AREF(cmd->chanlist[i]) != reference) {
+					comedi_error(dev,
+						"entries in chanlist must all have the same reference\n");
+					error++;
+				}
+			}
+		} else {
+			if ((CR_CHAN(cmd->chanlist[0]) >
+					(board->ai_channel_nbr - 1))
+				|| (CR_CHAN(cmd->chanlist[0]) < 0)) {
+				comedi_error(dev,
+					"channel number is out of limits\n");
+				error++;
+			}
+		}
+	}
+
+	if (error)
+		return 5;
+
+	return 0;
+
+}
+
+/*  Analog input command */
+
+static int pci9111_ai_do_cmd(struct comedi_device * dev, struct comedi_subdevice * subdevice)
+{
+	struct comedi_cmd *async_cmd = &subdevice->async->cmd;
+
+	if (!dev->irq) {
+		comedi_error(dev,
+			"no irq assigned for PCI9111, cannot do hardware conversion");
+		return -1;
+	}
+	/*  Set channel scan limit */
+	/*  PCI9111 allows only scanning from channel 0 to channel n */
+	/*  TODO: handle the case of an external multiplexer */
+
+	if (async_cmd->chanlist_len > 1) {
+		pci9111_ai_channel_set((async_cmd->chanlist_len) - 1);
+		pci9111_autoscan_set(dev, true);
+	} else {
+		pci9111_ai_channel_set(CR_CHAN(async_cmd->chanlist[0]));
+		pci9111_autoscan_set(dev, false);
+	}
+
+	/*  Set gain */
+	/*  This is the same gain on every channel */
+
+	pci9111_ai_range_set(CR_RANGE(async_cmd->chanlist[0]));
+
+	/* Set counter */
+
+	switch (async_cmd->stop_src) {
+	case TRIG_COUNT:
+		dev_private->stop_counter =
+			async_cmd->stop_arg * async_cmd->chanlist_len;
+		dev_private->stop_is_none = 0;
+		break;
+
+	case TRIG_NONE:
+		dev_private->stop_counter = 0;
+		dev_private->stop_is_none = 1;
+		break;
+
+	default:
+		comedi_error(dev, "Invalid stop trigger");
+		return -1;
+	}
+
+	/*  Set timer pacer */
+
+	dev_private->scan_delay = 0;
+	switch (async_cmd->convert_src) {
+	case TRIG_TIMER:
+		i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS,
+			&(dev_private->timer_divisor_1),
+			&(dev_private->timer_divisor_2),
+			&(async_cmd->convert_arg),
+			async_cmd->flags & TRIG_ROUND_MASK);
+#ifdef AI_DO_CMD_DEBUG
+		printk(PCI9111_DRIVER_NAME ": divisors = %d, %d\n",
+			dev_private->timer_divisor_1,
+			dev_private->timer_divisor_2);
+#endif
+
+		pci9111_trigger_source_set(dev, software);
+		pci9111_timer_set(dev);
+		pci9111_fifo_reset();
+		pci9111_interrupt_source_set(dev, irq_on_fifo_half_full,
+			irq_on_timer_tick);
+		pci9111_trigger_source_set(dev, timer_pacer);
+		plx9050_interrupt_control(dev_private->lcr_io_base, true, true,
+			false, true, true);
+
+		dev_private->scan_delay =
+			(async_cmd->scan_begin_arg / (async_cmd->convert_arg *
+				async_cmd->chanlist_len)) - 1;
+
+		break;
+
+	case TRIG_EXT:
+
+		pci9111_trigger_source_set(dev, external);
+		pci9111_fifo_reset();
+		pci9111_interrupt_source_set(dev, irq_on_fifo_half_full,
+			irq_on_timer_tick);
+		plx9050_interrupt_control(dev_private->lcr_io_base, true, true,
+			false, true, true);
+
+		break;
+
+	default:
+		comedi_error(dev, "Invalid convert trigger");
+		return -1;
+	}
+
+	dev_private->stop_counter *= (1 + dev_private->scan_delay);
+	dev_private->chanlist_len = async_cmd->chanlist_len;
+	dev_private->chunk_counter = 0;
+	dev_private->chunk_num_samples =
+		dev_private->chanlist_len * (1 + dev_private->scan_delay);
+
+#ifdef AI_DO_CMD_DEBUG
+	printk(PCI9111_DRIVER_NAME ": start interruptions!\n");
+	printk(PCI9111_DRIVER_NAME ": trigger source = %2x\n",
+		pci9111_trigger_and_autoscan_get());
+	printk(PCI9111_DRIVER_NAME ": irq source     = %2x\n",
+		pci9111_interrupt_and_fifo_get());
+	printk(PCI9111_DRIVER_NAME ": ai_do_cmd\n");
+	printk(PCI9111_DRIVER_NAME ": stop counter   = %d\n",
+		dev_private->stop_counter);
+	printk(PCI9111_DRIVER_NAME ": scan delay     = %d\n",
+		dev_private->scan_delay);
+	printk(PCI9111_DRIVER_NAME ": chanlist_len   = %d\n",
+		dev_private->chanlist_len);
+	printk(PCI9111_DRIVER_NAME ": chunk num samples = %d\n",
+		dev_private->chunk_num_samples);
+#endif
+
+	return 0;
+}
+
+static void pci9111_ai_munge(struct comedi_device * dev, struct comedi_subdevice * s,
+	void *data, unsigned int num_bytes, unsigned int start_chan_index)
+{
+	unsigned int i, num_samples = num_bytes / sizeof(short);
+	short *array = data;
+	int resolution =
+		((struct pci9111_board *) dev->board_ptr)->ai_resolution;
+
+	for (i = 0; i < num_samples; i++) {
+		if (resolution == PCI9111_HR_AI_RESOLUTION)
+			array[i] =
+				(array[i] & PCI9111_HR_AI_RESOLUTION_MASK) ^
+				PCI9111_HR_AI_RESOLUTION_2_CMP_BIT;
+		else
+			array[i] =
+				((array[i] >> 4) & PCI9111_AI_RESOLUTION_MASK) ^
+				PCI9111_AI_RESOLUTION_2_CMP_BIT;
+	}
+}
+
+/*  ------------------------------------------------------------------ */
+/*  INTERRUPT SECTION */
+/*  ------------------------------------------------------------------ */
+
+#undef INTERRUPT_DEBUG
+
+static irqreturn_t pci9111_interrupt(int irq, void *p_device PT_REGS_ARG)
+{
+	struct comedi_device *dev = p_device;
+	struct comedi_subdevice *subdevice = dev->read_subdev;
+	struct comedi_async *async;
+	unsigned long irq_flags;
+	unsigned char intcsr;
+
+	if (!dev->attached) {
+		/*  Ignore interrupt before device fully attached. */
+		/*  Might not even have allocated subdevices yet! */
+		return IRQ_NONE;
+	}
+
+	async = subdevice->async;
+
+	comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+
+	/*  Check if we are source of interrupt */
+	intcsr = inb(dev_private->lcr_io_base +
+		PLX9050_REGISTER_INTERRUPT_CONTROL);
+	if (!(((intcsr & PLX9050_PCI_INTERRUPT_ENABLE) != 0)
+			&& (((intcsr & (PLX9050_LINTI1_ENABLE |
+							PLX9050_LINTI1_STATUS))
+					==
+					(PLX9050_LINTI1_ENABLE |
+						PLX9050_LINTI1_STATUS))
+				|| ((intcsr & (PLX9050_LINTI2_ENABLE |
+							PLX9050_LINTI2_STATUS))
+					==
+					(PLX9050_LINTI2_ENABLE |
+						PLX9050_LINTI2_STATUS))))) {
+		/*  Not the source of the interrupt. */
+		/*  (N.B. not using PLX9050_SOFTWARE_INTERRUPT) */
+		comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+		return IRQ_NONE;
+	}
+
+	if ((intcsr & (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) ==
+		(PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) {
+		/*  Interrupt comes from fifo_half-full signal */
+
+		if (pci9111_is_fifo_full()) {
+			comedi_spin_unlock_irqrestore(&dev->spinlock,
+				irq_flags);
+			comedi_error(dev, PCI9111_DRIVER_NAME " fifo overflow");
+			pci9111_interrupt_clear();
+			pci9111_ai_cancel(dev, subdevice);
+			async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+			comedi_event(dev, subdevice);
+
+			return IRQ_HANDLED;
+		}
+
+		if (pci9111_is_fifo_half_full()) {
+			unsigned int num_samples;
+			unsigned int bytes_written = 0;
+
+#ifdef INTERRUPT_DEBUG
+			printk(PCI9111_DRIVER_NAME ": fifo is half full\n");
+#endif
+
+			num_samples =
+				PCI9111_FIFO_HALF_SIZE >
+				dev_private->stop_counter
+				&& !dev_private->stop_is_none ? dev_private->
+				stop_counter : PCI9111_FIFO_HALF_SIZE;
+			insw(PCI9111_IO_BASE + PCI9111_REGISTER_AD_FIFO_VALUE,
+				dev_private->ai_bounce_buffer, num_samples);
+
+			if (dev_private->scan_delay < 1) {
+				bytes_written =
+					cfc_write_array_to_buffer(subdevice,
+					dev_private->ai_bounce_buffer,
+					num_samples * sizeof(short));
+			} else {
+				int position = 0;
+				int to_read;
+
+				while (position < num_samples) {
+					if (dev_private->chunk_counter <
+						dev_private->chanlist_len) {
+						to_read =
+							dev_private->
+							chanlist_len -
+							dev_private->
+							chunk_counter;
+
+						if (to_read >
+							num_samples - position)
+							to_read =
+								num_samples -
+								position;
+
+						bytes_written +=
+							cfc_write_array_to_buffer
+							(subdevice,
+							dev_private->
+							ai_bounce_buffer +
+							position,
+							to_read *
+							sizeof(short));
+					} else {
+						to_read =
+							dev_private->
+							chunk_num_samples -
+							dev_private->
+							chunk_counter;
+						if (to_read >
+							num_samples - position)
+							to_read =
+								num_samples -
+								position;
+
+						bytes_written +=
+							sizeof(short) *
+							to_read;
+					}
+
+					position += to_read;
+					dev_private->chunk_counter += to_read;
+
+					if (dev_private->chunk_counter >=
+						dev_private->chunk_num_samples)
+						dev_private->chunk_counter = 0;
+				}
+			}
+
+			dev_private->stop_counter -=
+				bytes_written / sizeof(short);
+		}
+	}
+
+	if ((dev_private->stop_counter == 0) && (!dev_private->stop_is_none)) {
+		async->events |= COMEDI_CB_EOA;
+		pci9111_ai_cancel(dev, subdevice);
+	}
+
+	/* Very important, otherwise another interrupt request will be inserted
+	 * and will cause driver hangs on processing interrupt event. */
+
+	pci9111_interrupt_clear();
+
+	comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+	comedi_event(dev, subdevice);
+
+	return IRQ_HANDLED;
+}
+
+/*  ------------------------------------------------------------------ */
+/*  INSTANT ANALOG INPUT OUTPUT SECTION */
+/*  ------------------------------------------------------------------ */
+
+/*  analog instant input */
+
+#undef AI_INSN_DEBUG
+
+static int pci9111_ai_insn_read(struct comedi_device * dev,
+	struct comedi_subdevice * subdevice, struct comedi_insn * insn, unsigned int * data)
+{
+	int resolution =
+		((struct pci9111_board *) dev->board_ptr)->ai_resolution;
+
+	int timeout, i;
+
+#ifdef AI_INSN_DEBUG
+	printk(PCI9111_DRIVER_NAME ": ai_insn set c/r/n = %2x/%2x/%2x\n",
+		CR_CHAN((&insn->chanspec)[0]),
+		CR_RANGE((&insn->chanspec)[0]), insn->n);
+#endif
+
+	pci9111_ai_channel_set(CR_CHAN((&insn->chanspec)[0]));
+
+	if ((pci9111_ai_range_get()) != CR_RANGE((&insn->chanspec)[0])) {
+		pci9111_ai_range_set(CR_RANGE((&insn->chanspec)[0]));
+	}
+
+	pci9111_fifo_reset();
+
+	for (i = 0; i < insn->n; i++) {
+		pci9111_software_trigger();
+
+		timeout = PCI9111_AI_INSTANT_READ_TIMEOUT;
+
+		while (timeout--) {
+			if (!pci9111_is_fifo_empty())
+				goto conversion_done;
+		}
+
+		comedi_error(dev, "A/D read timeout");
+		data[i] = 0;
+		pci9111_fifo_reset();
+		return -ETIME;
+
+	      conversion_done:
+
+		if (resolution == PCI9111_HR_AI_RESOLUTION) {
+			data[i] = pci9111_hr_ai_get_data();
+		} else {
+			data[i] = pci9111_ai_get_data();
+		}
+	}
+
+#ifdef AI_INSN_DEBUG
+	printk(PCI9111_DRIVER_NAME ": ai_insn get c/r/t = %2x/%2x/%2x\n",
+		pci9111_ai_channel_get(),
+		pci9111_ai_range_get(), pci9111_trigger_and_autoscan_get());
+#endif
+
+	return i;
+}
+
+/*  Analog instant output */
+
+static int
+pci9111_ao_insn_write(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+
+	for (i = 0; i < insn->n; i++) {
+		pci9111_ao_set_data(data[i]);
+		dev_private->ao_readback = data[i];
+	}
+
+	return i;
+}
+
+/*  Analog output readback */
+
+static int pci9111_ao_insn_read(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+
+	for (i = 0; i < insn->n; i++) {
+		data[i] = dev_private->ao_readback & PCI9111_AO_RESOLUTION_MASK;
+	}
+
+	return i;
+}
+
+/*  ------------------------------------------------------------------ */
+/*  DIGITAL INPUT OUTPUT SECTION */
+/*  ------------------------------------------------------------------ */
+
+/*  Digital inputs */
+
+static int pci9111_di_insn_bits(struct comedi_device * dev,
+	struct comedi_subdevice * subdevice, struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int bits;
+
+	bits = pci9111_di_get_bits();
+	data[1] = bits;
+
+	return 2;
+}
+
+/*  Digital outputs */
+
+static int pci9111_do_insn_bits(struct comedi_device * dev,
+	struct comedi_subdevice * subdevice, struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int bits;
+
+	/*  Only set bits that have been masked */
+	/*  data[0] = mask */
+	/*  data[1] = bit state */
+
+	data[0] &= PCI9111_DO_MASK;
+
+	bits = subdevice->state;
+	bits &= ~data[0];
+	bits |= data[0] & data[1];
+	subdevice->state = bits;
+
+	pci9111_do_set_bits(bits);
+
+	data[1] = bits;
+
+	return 2;
+}
+
+/*  ------------------------------------------------------------------ */
+/*  INITIALISATION SECTION */
+/*  ------------------------------------------------------------------ */
+
+/*  Reset device */
+
+static int pci9111_reset(struct comedi_device * dev)
+{
+	/*  Set trigger source to software */
+
+	plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true,
+		true, false);
+
+	pci9111_trigger_source_set(dev, software);
+	pci9111_pretrigger_set(dev, false);
+	pci9111_autoscan_set(dev, false);
+
+	/*  Reset 8254 chip */
+
+	dev_private->timer_divisor_1 = 0;
+	dev_private->timer_divisor_2 = 0;
+
+	pci9111_timer_set(dev);
+
+	return 0;
+}
+
+/*  Attach */
+/*       - Register PCI device */
+/*       - Declare device driver capability */
+
+static int pci9111_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *subdevice;
+	unsigned long io_base, io_range, lcr_io_base, lcr_io_range;
+	struct pci_dev *pci_device;
+	int error, i;
+	const struct pci9111_board *board;
+
+	if (alloc_private(dev, sizeof(struct pci9111_private_data)) < 0) {
+		return -ENOMEM;
+	}
+	/*  Probe the device to determine what device in the series it is. */
+
+	printk("comedi%d: " PCI9111_DRIVER_NAME " driver\n", dev->minor);
+
+	for (pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+		pci_device != NULL;
+		pci_device =
+		pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
+		if (pci_device->vendor == PCI_VENDOR_ID_ADLINK) {
+			for (i = 0; i < pci9111_board_nbr; i++) {
+				if (pci9111_boards[i].device_id ==
+					pci_device->device) {
+					/*  was a particular bus/slot requested? */
+					if ((it->options[0] != 0)
+						|| (it->options[1] != 0)) {
+						/*  are we on the wrong bus/slot? */
+						if (pci_device->bus->number !=
+							it->options[0]
+							|| PCI_SLOT(pci_device->
+								devfn) !=
+							it->options[1]) {
+							continue;
+						}
+					}
+
+					dev->board_ptr = pci9111_boards + i;
+					board = (struct pci9111_board *) dev->
+						board_ptr;
+					dev_private->pci_device = pci_device;
+					goto found;
+				}
+			}
+		}
+	}
+
+	printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
+		dev->minor, it->options[0], it->options[1]);
+	return -EIO;
+
+      found:
+
+	printk("comedi%d: found %s (b:s:f=%d:%d:%d) , irq=%d\n",
+		dev->minor,
+		pci9111_boards[i].name,
+		pci_device->bus->number,
+		PCI_SLOT(pci_device->devfn),
+		PCI_FUNC(pci_device->devfn), pci_device->irq);
+
+	/*  TODO: Warn about non-tested boards. */
+
+	switch (board->device_id) {
+	};
+
+	/*  Read local configuration register base address [PCI_BASE_ADDRESS #1]. */
+
+	lcr_io_base = pci_resource_start(pci_device, 1);
+	lcr_io_range = pci_resource_len(pci_device, 1);
+
+	printk("comedi%d: local configuration registers at address 0x%4lx [0x%4lx]\n", dev->minor, lcr_io_base, lcr_io_range);
+
+	/*  Enable PCI device and request regions */
+	if (comedi_pci_enable(pci_device, PCI9111_DRIVER_NAME) < 0) {
+		printk("comedi%d: Failed to enable PCI device and request regions\n", dev->minor);
+		return -EIO;
+	}
+	/*  Read PCI6308 register base address [PCI_BASE_ADDRESS #2]. */
+
+	io_base = pci_resource_start(pci_device, 2);
+	io_range = pci_resource_len(pci_device, 2);
+
+	printk("comedi%d: 6503 registers at address 0x%4lx [0x%4lx]\n",
+		dev->minor, io_base, io_range);
+
+	dev->iobase = io_base;
+	dev->board_name = board->name;
+	dev_private->io_range = io_range;
+	dev_private->is_valid = 0;
+	dev_private->lcr_io_base = lcr_io_base;
+	dev_private->lcr_io_range = lcr_io_range;
+
+	pci9111_reset(dev);
+
+	/*  Irq setup */
+
+	dev->irq = 0;
+	if (pci_device->irq > 0) {
+		if (comedi_request_irq(pci_device->irq,
+				pci9111_interrupt,
+				IRQF_SHARED, PCI9111_DRIVER_NAME, dev) != 0) {
+			printk("comedi%d: unable to allocate irq  %u\n",
+				dev->minor, pci_device->irq);
+			return -EINVAL;
+		}
+	}
+	dev->irq = pci_device->irq;
+
+	/*  TODO: Add external multiplexer setup (according to option[2]). */
+
+	if ((error = alloc_subdevices(dev, 4)) < 0)
+		return error;
+
+	subdevice = dev->subdevices + 0;
+	dev->read_subdev = subdevice;
+
+	subdevice->type = COMEDI_SUBD_AI;
+	subdevice->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ;
+
+	/*  TODO: Add external multiplexer data */
+	/*     if (devpriv->usemux) { subdevice->n_chan = devpriv->usemux; } */
+	/*     else { subdevice->n_chan = this_board->n_aichan; } */
+
+	subdevice->n_chan = board->ai_channel_nbr;
+	subdevice->maxdata = board->ai_resolution_mask;
+	subdevice->len_chanlist = board->ai_channel_nbr;
+	subdevice->range_table = board->ai_range_list;
+	subdevice->cancel = pci9111_ai_cancel;
+	subdevice->insn_read = pci9111_ai_insn_read;
+	subdevice->do_cmdtest = pci9111_ai_do_cmd_test;
+	subdevice->do_cmd = pci9111_ai_do_cmd;
+	subdevice->munge = pci9111_ai_munge;
+
+	subdevice = dev->subdevices + 1;
+	subdevice->type = COMEDI_SUBD_AO;
+	subdevice->subdev_flags = SDF_WRITABLE | SDF_COMMON;
+	subdevice->n_chan = board->ao_channel_nbr;
+	subdevice->maxdata = board->ao_resolution_mask;
+	subdevice->len_chanlist = board->ao_channel_nbr;
+	subdevice->range_table = board->ao_range_list;
+	subdevice->insn_write = pci9111_ao_insn_write;
+	subdevice->insn_read = pci9111_ao_insn_read;
+
+	subdevice = dev->subdevices + 2;
+	subdevice->type = COMEDI_SUBD_DI;
+	subdevice->subdev_flags = SDF_READABLE;
+	subdevice->n_chan = PCI9111_DI_CHANNEL_NBR;
+	subdevice->maxdata = 1;
+	subdevice->range_table = &range_digital;
+	subdevice->insn_bits = pci9111_di_insn_bits;
+
+	subdevice = dev->subdevices + 3;
+	subdevice->type = COMEDI_SUBD_DO;
+	subdevice->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+	subdevice->n_chan = PCI9111_DO_CHANNEL_NBR;
+	subdevice->maxdata = 1;
+	subdevice->range_table = &range_digital;
+	subdevice->insn_bits = pci9111_do_insn_bits;
+
+	dev_private->is_valid = 1;
+
+	return 0;
+}
+
+/*  Detach */
+
+static int pci9111_detach(struct comedi_device * dev)
+{
+	/*  Reset device */
+
+	if (dev->private != 0) {
+		if (dev_private->is_valid)
+			pci9111_reset(dev);
+
+	}
+	/*  Release previously allocated irq */
+
+	if (dev->irq != 0) {
+		comedi_free_irq(dev->irq, dev);
+	}
+
+	if (dev_private != 0 && dev_private->pci_device != 0) {
+		if (dev->iobase) {
+			comedi_pci_disable(dev_private->pci_device);
+		}
+		pci_dev_put(dev_private->pci_device);
+	}
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c
new file mode 100644
index 0000000..278cf30
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adl_pci9118.c
@@ -0,0 +1,2100 @@
+/*
+ *  comedi/drivers/adl_pci9118.c
+ *
+ *  hardware driver for ADLink cards:
+ *   card:   PCI-9118DG, PCI-9118HG, PCI-9118HR
+ *   driver: pci9118dg,  pci9118hg,  pci9118hr
+ *
+ * Author: Michal Dobes <dobes@tesnet.cz>
+ *
+*/
+/*
+Driver: adl_pci9118
+Description: Adlink PCI-9118DG, PCI-9118HG, PCI-9118HR
+Author: Michal Dobes <dobes@tesnet.cz>
+Devices: [ADLink] PCI-9118DG (pci9118dg), PCI-9118HG (pci9118hg),
+  PCI-9118HR (pci9118hr)
+Status: works
+
+This driver supports AI, AO, DI and DO subdevices.
+AI subdevice supports cmd and insn interface,
+other subdevices support only insn interface.
+For AI:
+- If cmd->scan_begin_src=TRIG_EXT then trigger input is TGIN (pin 46).
+- If cmd->convert_src=TRIG_EXT then trigger input is EXTTRG (pin 44).
+- If cmd->start_src/stop_src=TRIG_EXT then trigger input is TGIN (pin 46).
+- It is not neccessary to have cmd.scan_end_arg=cmd.chanlist_len but
+  cmd.scan_end_arg modulo cmd.chanlist_len must by 0.
+- If return value of cmdtest is 5 then you've bad channel list
+  (it isn't possible mixture S.E. and DIFF inputs or bipolar and unipolar
+  ranges).
+
+There are some hardware limitations:
+a) You cann't use mixture of unipolar/bipoar ranges or differencial/single
+   ended inputs.
+b) DMA transfers must have the length aligned to two samples (32 bit),
+   so there is some problems if cmd->chanlist_len is odd. This driver tries
+   bypass this with adding one sample to the end of the every scan and discard
+   it on output but this cann't be used if cmd->scan_begin_src=TRIG_FOLLOW
+   and is used flag TRIG_WAKE_EOS, then driver switch to interrupt driven mode
+   with interrupt after every sample.
+c) If isn't used DMA then you can use only mode where
+   cmd->scan_begin_src=TRIG_FOLLOW.
+
+Configuration options:
+  [0] - PCI bus of device (optional)
+  [1] - PCI slot of device (optional)
+          If bus/slot is not specified, then first available PCI
+          card will be used.
+  [2] - 0= standard 8 DIFF/16 SE channels configuration
+        n= external multiplexer connected, 1<=n<=256
+  [3] - 0=autoselect DMA or EOC interrupts operation
+        1=disable DMA mode
+        3=disable DMA and INT, only insn interface will work
+  [4] - sample&hold signal - card can generate signal for external S&H board
+        0=use SSHO (pin 45) signal is generated in onboard hardware S&H logic
+        0!=use ADCHN7 (pin 23) signal is generated from driver, number
+           say how long delay is requested in ns and sign polarity of the hold
+           (in this case external multiplexor can serve only 128 channels)
+  [5] - 0=stop measure on all hardware errors
+        2|=ignore ADOR - A/D Overrun status
+	8|=ignore Bover - A/D Burst Mode Overrun status
+	256|=ignore nFull - A/D FIFO Full status
+
+*/
+#include "../comedidev.h"
+#include "../pci_ids.h"
+
+#include <linux/delay.h>
+
+#include "amcc_s5933.h"
+#include "8253.h"
+#include "comedi_pci.h"
+#include "comedi_fc.h"
+
+/* paranoid checks are broken */
+#undef PCI9118_PARANOIDCHECK	/* if defined, then is used code which control correct channel number on every 12 bit sample */
+
+#undef PCI9118_EXTDEBUG		/* if defined then driver prints a lot of messages */
+
+#undef DPRINTK
+#ifdef PCI9118_EXTDEBUG
+#define DPRINTK(fmt, args...) rt_printk(fmt, ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+#define IORANGE_9118 	64	/* I hope */
+#define PCI9118_CHANLEN	255	/* len of chanlist, some source say 256, but reality looks like 255 :-( */
+
+#define PCI9118_CNT0	0x00	/* R/W: 8254 couter 0 */
+#define PCI9118_CNT1	0x04	/* R/W: 8254 couter 0 */
+#define PCI9118_CNT2	0x08	/* R/W: 8254 couter 0 */
+#define PCI9118_CNTCTRL	0x0c	/* W:   8254 counter control */
+#define PCI9118_AD_DATA	0x10	/* R:   A/D data */
+#define PCI9118_DA1	0x10	/* W:   D/A registers */
+#define PCI9118_DA2	0x14
+#define PCI9118_ADSTAT	0x18	/* R:   A/D status register */
+#define PCI9118_ADCNTRL	0x18	/* W:   A/D control register */
+#define PCI9118_DI	0x1c	/* R:   digi input register */
+#define PCI9118_DO	0x1c	/* W:   digi output register */
+#define PCI9118_SOFTTRG	0x20	/* W:   soft trigger for A/D */
+#define PCI9118_GAIN	0x24	/* W:   A/D gain/channel register */
+#define PCI9118_BURST	0x28	/* W:   A/D burst number register */
+#define PCI9118_SCANMOD	0x2c	/* W:   A/D auto scan mode */
+#define PCI9118_ADFUNC	0x30	/* W:   A/D function register */
+#define PCI9118_DELFIFO	0x34	/* W:   A/D data FIFO reset */
+#define PCI9118_INTSRC	0x38	/* R:   interrupt reason register */
+#define PCI9118_INTCTRL	0x38	/* W:   interrupt control register */
+
+// bits from A/D control register (PCI9118_ADCNTRL)
+#define AdControl_UniP	0x80	/* 1=bipolar, 0=unipolar */
+#define AdControl_Diff	0x40	/* 1=differential, 0= single end inputs */
+#define AdControl_SoftG	0x20	/* 1=8254 counter works, 0=counter stops */
+#define	AdControl_ExtG	0x10	/* 1=8254 countrol controlled by TGIN(pin 46), 0=controled by SoftG */
+#define AdControl_ExtM	0x08	/* 1=external hardware trigger (pin 44), 0=internal trigger */
+#define AdControl_TmrTr	0x04	/* 1=8254 is iternal trigger source, 0=software trigger is source (register PCI9118_SOFTTRG) */
+#define AdControl_Int	0x02	/* 1=enable INT, 0=disable */
+#define AdControl_Dma	0x01	/* 1=enable DMA, 0=disable */
+
+// bits from A/D function register (PCI9118_ADFUNC)
+#define AdFunction_PDTrg	0x80	/* 1=positive, 0=negative digital trigger (only positive is correct) */
+#define AdFunction_PETrg	0x40	/* 1=positive, 0=negative external trigger (only positive is correct) */
+#define AdFunction_BSSH		0x20	/* 1=with sample&hold, 0=without */
+#define AdFunction_BM		0x10	/* 1=burst mode, 0=normal mode */
+#define AdFunction_BS		0x08	/* 1=burst mode start, 0=burst mode stop */
+#define AdFunction_PM		0x04	/* 1=post trigger mode, 0=not post trigger */
+#define AdFunction_AM		0x02	/* 1=about trigger mode, 0=not about trigger */
+#define AdFunction_Start	0x01	/* 1=trigger start, 0=trigger stop */
+
+// bits from A/D status register (PCI9118_ADSTAT)
+#define AdStatus_nFull	0x100	/* 0=FIFO full (fatal), 1=not full */
+#define AdStatus_nHfull	0x080	/* 0=FIFO half full, 1=FIFO not half full */
+#define AdStatus_nEpty	0x040	/* 0=FIFO empty, 1=FIFO not empty */
+#define AdStatus_Acmp	0x020	/*  */
+#define AdStatus_DTH	0x010	/* 1=external digital trigger */
+#define AdStatus_Bover	0x008	/* 1=burst mode overrun (fatal) */
+#define AdStatus_ADOS	0x004	/* 1=A/D over speed (warning) */
+#define AdStatus_ADOR	0x002	/* 1=A/D overrun (fatal) */
+#define AdStatus_ADrdy	0x001	/* 1=A/D already ready, 0=not ready */
+
+// bits for interrupt reason and control (PCI9118_INTSRC, PCI9118_INTCTRL)
+// 1=interrupt occur, enable source,  0=interrupt not occur, disable source
+#define Int_Timer	0x08	/* timer interrupt */
+#define Int_About	0x04	/* about trigger complete */
+#define Int_Hfull	0x02	/* A/D FIFO hlaf full */
+#define Int_DTrg	0x01	/* external digital trigger */
+
+#define START_AI_EXT	0x01	/* start measure on external trigger */
+#define STOP_AI_EXT	0x02	/* stop measure on external trigger */
+#define START_AI_INT	0x04	/* start measure on internal trigger */
+#define STOP_AI_INT	0x08	/* stop measure on internal trigger */
+
+#define EXTTRG_AI	0	/* ext trg is used by AI */
+
+static const struct comedi_lrange range_pci9118dg_hr = { 8, {
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+			BIP_RANGE(0.625),
+			UNI_RANGE(10),
+			UNI_RANGE(5),
+			UNI_RANGE(2.5),
+			UNI_RANGE(1.25)
+	}
+};
+
+static const struct comedi_lrange range_pci9118hg = { 8, {
+			BIP_RANGE(5),
+			BIP_RANGE(0.5),
+			BIP_RANGE(0.05),
+			BIP_RANGE(0.005),
+			UNI_RANGE(10),
+			UNI_RANGE(1),
+			UNI_RANGE(0.1),
+			UNI_RANGE(0.01)
+	}
+};
+
+#define PCI9118_BIPOLAR_RANGES	4	/* used for test on mixture of BIP/UNI ranges */
+
+static int pci9118_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci9118_detach(struct comedi_device * dev);
+
+struct boardtype {
+	const char *name;	// board name
+	int vendor_id;		// PCI vendor a device ID of card
+	int device_id;
+	int iorange_amcc;	// iorange for own S5933 region
+	int iorange_9118;	// pass thru card region size
+	int n_aichan;		// num of A/D chans
+	int n_aichand;		// num of A/D chans in diff mode
+	int mux_aichan;		// num of A/D chans with external multiplexor
+	int n_aichanlist;	// len of chanlist
+	int n_aochan;		// num of D/A chans
+	int ai_maxdata;		// resolution of A/D
+	int ao_maxdata;		// resolution of D/A
+	const struct comedi_lrange *rangelist_ai;	// rangelist for A/D
+	const struct comedi_lrange *rangelist_ao;	// rangelist for D/A
+	unsigned int ai_ns_min;	// max sample speed of card v ns
+	unsigned int ai_pacer_min;	// minimal pacer value (c1*c2 or c1 in burst)
+	int half_fifo_size;	// size of FIFO/2
+
+};
+
+static DEFINE_PCI_DEVICE_TABLE(pci9118_pci_table) = {
+	{PCI_VENDOR_ID_AMCC, 0x80d9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci9118_pci_table);
+
+static const struct boardtype boardtypes[] = {
+	{"pci9118dg", PCI_VENDOR_ID_AMCC, 0x80d9,
+			AMCC_OP_REG_SIZE, IORANGE_9118,
+			16, 8, 256, PCI9118_CHANLEN, 2, 0x0fff, 0x0fff,
+			&range_pci9118dg_hr, &range_bipolar10,
+		3000, 12, 512},
+	{"pci9118hg", PCI_VENDOR_ID_AMCC, 0x80d9,
+			AMCC_OP_REG_SIZE, IORANGE_9118,
+			16, 8, 256, PCI9118_CHANLEN, 2, 0x0fff, 0x0fff,
+			&range_pci9118hg, &range_bipolar10,
+		3000, 12, 512},
+	{"pci9118hr", PCI_VENDOR_ID_AMCC, 0x80d9,
+			AMCC_OP_REG_SIZE, IORANGE_9118,
+			16, 8, 256, PCI9118_CHANLEN, 2, 0xffff, 0x0fff,
+			&range_pci9118dg_hr, &range_bipolar10,
+		10000, 40, 512},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype))
+
+static struct comedi_driver driver_pci9118 = {
+      driver_name:"adl_pci9118",
+      module:THIS_MODULE,
+      attach:pci9118_attach,
+      detach:pci9118_detach,
+      num_names:n_boardtypes,
+      board_name:&boardtypes[0].name,
+      offset:sizeof(struct boardtype),
+};
+
+COMEDI_PCI_INITCLEANUP(driver_pci9118, pci9118_pci_table);
+
+struct pci9118_private {
+	unsigned long iobase_a;	// base+size for AMCC chip
+	unsigned int master;	// master capable
+	struct pci_dev *pcidev;	// ptr to actual pcidev
+	unsigned int usemux;	// we want to use external multiplexor!
+#ifdef PCI9118_PARANOIDCHECK
+	unsigned short chanlist[PCI9118_CHANLEN + 1];	// list of scaned channel
+	unsigned char chanlistlen;	// number of scanlist
+#endif
+	unsigned char AdControlReg;	// A/D control register
+	unsigned char IntControlReg;	// Interrupt control register
+	unsigned char AdFunctionReg;	// A/D function register
+	char valid;		// driver is ok
+	char ai_neverending;	// we do unlimited AI
+	unsigned int i8254_osc_base;	// frequence of onboard oscilator
+	unsigned int ai_do;	// what do AI? 0=nothing, 1 to 4 mode
+	unsigned int ai_act_scan;	// how many scans we finished
+	unsigned int ai_buf_ptr;	// data buffer ptr in samples
+	unsigned int ai_n_chan;	// how many channels is measured
+	unsigned int ai_n_scanlen;	// len of actual scanlist
+	unsigned int ai_n_realscanlen;	// what we must transfer for one outgoing scan include front/back adds
+	unsigned int ai_act_dmapos;	// position in actual real stream
+	unsigned int ai_add_front;	// how many channels we must add before scan to satisfy S&H?
+	unsigned int ai_add_back;	// how many channels we must add before scan to satisfy DMA?
+	unsigned int *ai_chanlist;	// actaul chanlist
+	unsigned int ai_timer1;
+	unsigned int ai_timer2;
+	unsigned int ai_flags;
+	char ai12_startstop;	// measure can start/stop on external trigger
+	unsigned int ai_divisor1, ai_divisor2;	// divisors for start of measure on external start
+	unsigned int ai_data_len;
+	short *ai_data;
+	short ao_data[2];	// data output buffer
+	unsigned int ai_scans;	// number of scans to do
+	char dma_doublebuf;	// we can use double buffring
+	unsigned int dma_actbuf;	// which buffer is used now
+	short *dmabuf_virt[2];	// pointers to begin of DMA buffer
+	unsigned long dmabuf_hw[2];	// hw address of DMA buff
+	unsigned int dmabuf_size[2];	// size of dma buffer in bytes
+	unsigned int dmabuf_use_size[2];	// which size we may now used for transfer
+	unsigned int dmabuf_used_size[2];	// which size was trully used
+	unsigned int dmabuf_panic_size[2];
+	unsigned int dmabuf_samples[2];	// size in samples
+	int dmabuf_pages[2];	// number of pages in buffer
+	unsigned char cnt0_users;	// bit field of 8254 CNT0 users (0-unused, 1-AO, 2-DI, 3-DO)
+	unsigned char exttrg_users;	// bit field of external trigger users (0-AI, 1-AO, 2-DI, 3-DO)
+	unsigned int cnt0_divisor;	// actual CNT0 divisor
+	void (*int_ai_func) (struct comedi_device *, struct comedi_subdevice *, unsigned short, unsigned int, unsigned short);	// ptr to actual interrupt AI function
+	unsigned char ai16bits;	// =1 16 bit card
+	unsigned char usedma;	// =1 use DMA transfer and not INT
+	unsigned char useeoshandle;	// =1 change WAKE_EOS DMA transfer to fit on every second
+	unsigned char usessh;	// =1 turn on S&H support
+	int softsshdelay;	// >0 use software S&H, numer is requested delay in ns
+	unsigned char softsshsample;	// polarity of S&H signal in sample state
+	unsigned char softsshhold;	// polarity of S&H signal in hold state
+	unsigned int ai_maskerr;	// which warning was printed
+	unsigned int ai_maskharderr;	// on which error bits stops
+	unsigned int ai_inttrig_start;	// TRIG_INT for start
+};
+
+#define devpriv ((struct pci9118_private *)dev->private)
+#define this_board ((struct boardtype *)dev->board_ptr)
+
+/*
+==============================================================================
+*/
+
+static int check_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+	int n_chan, unsigned int *chanlist, int frontadd, int backadd);
+static int setup_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+	int n_chan, unsigned int *chanlist, int rot, int frontadd, int backadd,
+	int usedma, char eoshandle);
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+	unsigned int divisor2);
+static int pci9118_reset(struct comedi_device * dev);
+static int pci9118_exttrg_add(struct comedi_device * dev, unsigned char source);
+static int pci9118_exttrg_del(struct comedi_device * dev, unsigned char source);
+static int pci9118_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void pci9118_calc_divisors(char mode, struct comedi_device * dev,
+	struct comedi_subdevice * s, unsigned int *tim1, unsigned int *tim2,
+	unsigned int flags, int chans, unsigned int *div1, unsigned int *div2,
+	char usessh, unsigned int chnsshfront);
+
+/*
+==============================================================================
+*/
+static int pci9118_insn_read_ai(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+
+	int n, timeout;
+
+	devpriv->AdControlReg = AdControl_Int & 0xff;
+	devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
+	outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);	// positive triggers, no S&H, no burst, burst stop, no post trigger, no about trigger, trigger stop
+
+	if (!setup_channel_list(dev, s, 1, &insn->chanspec, 0, 0, 0, 0, 0))
+		return -EINVAL;
+
+	outl(0, dev->iobase + PCI9118_DELFIFO);	// flush FIFO
+
+	for (n = 0; n < insn->n; n++) {
+		outw(0, dev->iobase + PCI9118_SOFTTRG);	/* start conversion */
+		comedi_udelay(2);
+		timeout = 100;
+		while (timeout--) {
+			if (inl(dev->iobase + PCI9118_ADSTAT) & AdStatus_ADrdy)
+				goto conv_finish;
+			comedi_udelay(1);
+		}
+
+		comedi_error(dev, "A/D insn timeout");
+		data[n] = 0;
+		outl(0, dev->iobase + PCI9118_DELFIFO);	// flush FIFO
+		return -ETIME;
+
+	      conv_finish:
+		if (devpriv->ai16bits) {
+			data[n] =
+				(inl(dev->iobase +
+					PCI9118_AD_DATA) & 0xffff) ^ 0x8000;
+		} else {
+			data[n] =
+				(inw(dev->iobase +
+					PCI9118_AD_DATA) >> 4) & 0xfff;
+		}
+	}
+
+	outl(0, dev->iobase + PCI9118_DELFIFO);	// flush FIFO
+	return n;
+
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_insn_write_ao(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n, chanreg, ch;
+
+	ch = CR_CHAN(insn->chanspec);
+	if (ch) {
+		chanreg = PCI9118_DA2;
+	} else {
+		chanreg = PCI9118_DA1;
+	}
+
+	for (n = 0; n < insn->n; n++) {
+		outl(data[n], dev->iobase + chanreg);
+		devpriv->ao_data[ch] = data[n];
+	}
+
+	return n;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_insn_read_ao(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n, chan;
+
+	chan = CR_CHAN(insn->chanspec);
+	for (n = 0; n < insn->n; n++)
+		data[n] = devpriv->ao_data[chan];
+
+	return n;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_insn_bits_di(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	data[1] = inl(dev->iobase + PCI9118_DI) & 0xf;
+
+	return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_insn_bits_do(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= (data[0] & data[1]);
+		outl(s->state & 0x0f, dev->iobase + PCI9118_DO);
+	}
+	data[1] = s->state;
+
+	return 2;
+}
+
+/*
+==============================================================================
+*/
+static void interrupt_pci9118_ai_mode4_switch(struct comedi_device * dev)
+{
+	devpriv->AdFunctionReg =
+		AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM;
+	outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
+	outl(0x30, dev->iobase + PCI9118_CNTCTRL);
+	outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 1) & 0xff,
+		dev->iobase + PCI9118_CNT0);
+	outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 9) & 0xff,
+		dev->iobase + PCI9118_CNT0);
+	devpriv->AdFunctionReg |= AdFunction_Start;
+	outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
+}
+
+static unsigned int defragment_dma_buffer(struct comedi_device * dev,
+	struct comedi_subdevice * s, short * dma_buffer, unsigned int num_samples)
+{
+	unsigned int i = 0, j = 0;
+	unsigned int start_pos = devpriv->ai_add_front,
+		stop_pos = devpriv->ai_add_front + devpriv->ai_n_chan;
+	unsigned int raw_scanlen = devpriv->ai_add_front + devpriv->ai_n_chan +
+		devpriv->ai_add_back;
+
+	for (i = 0; i < num_samples; i++) {
+		if (devpriv->ai_act_dmapos >= start_pos &&
+			devpriv->ai_act_dmapos < stop_pos) {
+			dma_buffer[j++] = dma_buffer[i];
+		}
+		devpriv->ai_act_dmapos++;
+		devpriv->ai_act_dmapos %= raw_scanlen;
+	}
+
+	return j;
+}
+
+/*
+==============================================================================
+*/
+static unsigned int move_block_from_dma(struct comedi_device * dev,
+	struct comedi_subdevice * s, short * dma_buffer, unsigned int num_samples)
+{
+	unsigned int num_bytes;
+
+	num_samples = defragment_dma_buffer(dev, s, dma_buffer, num_samples);
+	devpriv->ai_act_scan +=
+		(s->async->cur_chan + num_samples) / devpriv->ai_n_scanlen;
+	s->async->cur_chan += num_samples;
+	s->async->cur_chan %= devpriv->ai_n_scanlen;
+	num_bytes =
+		cfc_write_array_to_buffer(s, dma_buffer,
+		num_samples * sizeof(short));
+	if (num_bytes < num_samples * sizeof(short))
+		return -1;
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+static char pci9118_decode_error_status(struct comedi_device * dev,
+	struct comedi_subdevice * s, unsigned char m)
+{
+	if (m & 0x100) {
+		comedi_error(dev, "A/D FIFO Full status (Fatal Error!)");
+		devpriv->ai_maskerr &= ~0x100L;
+	}
+	if (m & 0x008) {
+		comedi_error(dev,
+			"A/D Burst Mode Overrun Status (Fatal Error!)");
+		devpriv->ai_maskerr &= ~0x008L;
+	}
+	if (m & 0x004) {
+		comedi_error(dev, "A/D Over Speed Status (Warning!)");
+		devpriv->ai_maskerr &= ~0x004L;
+	}
+	if (m & 0x002) {
+		comedi_error(dev, "A/D Overrun Status (Fatal Error!)");
+		devpriv->ai_maskerr &= ~0x002L;
+	}
+	if (m & devpriv->ai_maskharderr) {
+		s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+		pci9118_ai_cancel(dev, s);
+		comedi_event(dev, s);
+		return 1;
+	}
+
+	return 0;
+}
+
+static void pci9118_ai_munge(struct comedi_device * dev, struct comedi_subdevice * s,
+	void *data, unsigned int num_bytes, unsigned int start_chan_index)
+{
+	unsigned int i, num_samples = num_bytes / sizeof(short);
+	short *array = data;
+
+	for (i = 0; i < num_samples; i++) {
+		if (devpriv->usedma)
+			array[i] = be16_to_cpu(array[i]);
+		if (devpriv->ai16bits) {
+			array[i] ^= 0x8000;
+		} else {
+			array[i] = (array[i] >> 4) & 0x0fff;
+		}
+	}
+}
+
+/*
+==============================================================================
+*/
+static void interrupt_pci9118_ai_onesample(struct comedi_device * dev,
+	struct comedi_subdevice * s, unsigned short int_adstat, unsigned int int_amcc,
+	unsigned short int_daq)
+{
+	register short sampl;
+
+	s->async->events = 0;
+
+	if (int_adstat & devpriv->ai_maskerr)
+		if (pci9118_decode_error_status(dev, s, int_adstat))
+			return;
+
+	sampl = inw(dev->iobase + PCI9118_AD_DATA);
+
+#ifdef PCI9118_PARANOIDCHECK
+	if (devpriv->ai16bits == 0) {
+		if ((sampl & 0x000f) != devpriv->chanlist[s->async->cur_chan]) {	// data dropout!
+			rt_printk
+				("comedi: A/D  SAMPL - data dropout: received channel %d, expected %d!\n",
+				sampl & 0x000f,
+				devpriv->chanlist[s->async->cur_chan]);
+			s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+			pci9118_ai_cancel(dev, s);
+			comedi_event(dev, s);
+			return;
+		}
+	}
+#endif
+	cfc_write_to_buffer(s, sampl);
+	s->async->cur_chan++;
+	if (s->async->cur_chan >= devpriv->ai_n_scanlen) {	/* one scan done */
+		s->async->cur_chan %= devpriv->ai_n_scanlen;
+		devpriv->ai_act_scan++;
+		if (!(devpriv->ai_neverending))
+			if (devpriv->ai_act_scan >= devpriv->ai_scans) {	/* all data sampled */
+				pci9118_ai_cancel(dev, s);
+				s->async->events |= COMEDI_CB_EOA;
+			}
+	}
+
+	if (s->async->events)
+		comedi_event(dev, s);
+}
+
+/*
+==============================================================================
+*/
+static void interrupt_pci9118_ai_dma(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned short int_adstat, unsigned int int_amcc,
+	unsigned short int_daq)
+{
+	unsigned int next_dma_buf, samplesinbuf, sampls, m;
+
+	if (int_amcc & MASTER_ABORT_INT) {
+		comedi_error(dev, "AMCC IRQ - MASTER DMA ABORT!");
+		s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+		pci9118_ai_cancel(dev, s);
+		comedi_event(dev, s);
+		return;
+	}
+
+	if (int_amcc & TARGET_ABORT_INT) {
+		comedi_error(dev, "AMCC IRQ - TARGET DMA ABORT!");
+		s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+		pci9118_ai_cancel(dev, s);
+		comedi_event(dev, s);
+		return;
+	}
+
+	if (int_adstat & devpriv->ai_maskerr)
+//      if (int_adstat & 0x106)
+		if (pci9118_decode_error_status(dev, s, int_adstat))
+			return;
+
+	samplesinbuf = devpriv->dmabuf_use_size[devpriv->dma_actbuf] >> 1;	// number of received real samples
+//      DPRINTK("dma_actbuf=%d\n",devpriv->dma_actbuf);
+
+	if (devpriv->dma_doublebuf) {	// switch DMA buffers if is used double buffering
+		next_dma_buf = 1 - devpriv->dma_actbuf;
+		outl(devpriv->dmabuf_hw[next_dma_buf],
+			devpriv->iobase_a + AMCC_OP_REG_MWAR);
+		outl(devpriv->dmabuf_use_size[next_dma_buf],
+			devpriv->iobase_a + AMCC_OP_REG_MWTC);
+		devpriv->dmabuf_used_size[next_dma_buf] =
+			devpriv->dmabuf_use_size[next_dma_buf];
+		if (devpriv->ai_do == 4)
+			interrupt_pci9118_ai_mode4_switch(dev);
+	}
+
+	if (samplesinbuf) {
+		m = devpriv->ai_data_len >> 1;	// how many samples is to end of buffer
+//              DPRINTK("samps=%d m=%d %d %d\n",samplesinbuf,m,s->async->buf_int_count,s->async->buf_int_ptr);
+		sampls = m;
+		move_block_from_dma(dev, s,
+			devpriv->dmabuf_virt[devpriv->dma_actbuf],
+			samplesinbuf);
+		m = m - sampls;	// m= how many samples was transfered
+	}
+//      DPRINTK("YYY\n");
+
+	if (!devpriv->ai_neverending)
+		if (devpriv->ai_act_scan >= devpriv->ai_scans) {	/* all data sampled */
+			pci9118_ai_cancel(dev, s);
+			s->async->events |= COMEDI_CB_EOA;
+		}
+
+	if (devpriv->dma_doublebuf) {	// switch dma buffers
+		devpriv->dma_actbuf = 1 - devpriv->dma_actbuf;
+	} else {		// restart DMA if is not used double buffering
+		outl(devpriv->dmabuf_hw[0],
+			devpriv->iobase_a + AMCC_OP_REG_MWAR);
+		outl(devpriv->dmabuf_use_size[0],
+			devpriv->iobase_a + AMCC_OP_REG_MWTC);
+		if (devpriv->ai_do == 4)
+			interrupt_pci9118_ai_mode4_switch(dev);
+	}
+
+	comedi_event(dev, s);
+}
+
+/*
+==============================================================================
+*/
+static irqreturn_t interrupt_pci9118(int irq, void *d PT_REGS_ARG)
+{
+	struct comedi_device *dev = d;
+	unsigned int int_daq = 0, int_amcc, int_adstat;
+
+	if (!dev->attached)
+		return IRQ_NONE;	// not fully initialized
+
+	int_daq = inl(dev->iobase + PCI9118_INTSRC) & 0xf;	// get IRQ reasons from card
+	int_amcc = inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR);	// get INT register from AMCC chip
+
+//      DPRINTK("INT daq=0x%01x amcc=0x%08x MWAR=0x%08x MWTC=0x%08x ADSTAT=0x%02x ai_do=%d\n", int_daq, int_amcc, inl(devpriv->iobase_a+AMCC_OP_REG_MWAR), inl(devpriv->iobase_a+AMCC_OP_REG_MWTC), inw(dev->iobase+PCI9118_ADSTAT)&0x1ff,devpriv->ai_do);
+
+	if ((!int_daq) && (!(int_amcc & ANY_S593X_INT)))
+		return IRQ_NONE;	// interrupt from other source
+
+	outl(int_amcc | 0x00ff0000, devpriv->iobase_a + AMCC_OP_REG_INTCSR);	// shutdown IRQ reasons in AMCC
+
+	int_adstat = inw(dev->iobase + PCI9118_ADSTAT) & 0x1ff;	// get STATUS register
+
+	if (devpriv->ai_do) {
+		if (devpriv->ai12_startstop)
+			if ((int_adstat & AdStatus_DTH) && (int_daq & Int_DTrg)) {	// start stop of measure
+				if (devpriv->ai12_startstop & START_AI_EXT) {
+					devpriv->ai12_startstop &=
+						~START_AI_EXT;
+					if (!(devpriv->ai12_startstop &
+							STOP_AI_EXT))
+						pci9118_exttrg_del(dev, EXTTRG_AI);	// deactivate EXT trigger
+					start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1, devpriv->ai_divisor2);	// start pacer
+					outl(devpriv->AdControlReg,
+						dev->iobase + PCI9118_ADCNTRL);
+				} else {
+					if (devpriv->
+						ai12_startstop & STOP_AI_EXT) {
+						devpriv->ai12_startstop &=
+							~STOP_AI_EXT;
+						pci9118_exttrg_del(dev, EXTTRG_AI);	// deactivate EXT trigger
+						devpriv->ai_neverending = 0;	//well, on next interrupt from DMA/EOC measure will stop
+					}
+				}
+			}
+
+		(devpriv->int_ai_func) (dev, dev->subdevices + 0, int_adstat,
+			int_amcc, int_daq);
+
+	}
+	return IRQ_HANDLED;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_ai_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int trignum)
+{
+	if (trignum != devpriv->ai_inttrig_start)
+		return -EINVAL;
+
+	devpriv->ai12_startstop &= ~START_AI_INT;
+	s->async->inttrig = NULL;
+
+	outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
+	outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
+	if (devpriv->ai_do != 3) {
+		start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
+			devpriv->ai_divisor2);
+		devpriv->AdControlReg |= AdControl_SoftG;
+	}
+	outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
+
+	return 1;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp, divisor1, divisor2;
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW | TRIG_EXT | TRIG_INT;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	if (devpriv->master) {
+		cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT | TRIG_FOLLOW;
+	} else {
+		cmd->scan_begin_src &= TRIG_FOLLOW;
+	}
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	if (devpriv->master) {
+		cmd->convert_src &= TRIG_TIMER | TRIG_EXT | TRIG_NOW;
+	} else {
+		cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+	}
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE | TRIG_EXT;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	if (cmd->start_src != TRIG_NOW &&
+		cmd->start_src != TRIG_INT && cmd->start_src != TRIG_EXT) {
+		cmd->start_src = TRIG_NOW;
+		err++;
+	}
+
+	if (cmd->scan_begin_src != TRIG_TIMER &&
+		cmd->scan_begin_src != TRIG_EXT &&
+		cmd->scan_begin_src != TRIG_INT &&
+		cmd->scan_begin_src != TRIG_FOLLOW) {
+		cmd->scan_begin_src = TRIG_FOLLOW;
+		err++;
+	}
+
+	if (cmd->convert_src != TRIG_TIMER &&
+		cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) {
+		cmd->convert_src = TRIG_TIMER;
+		err++;
+	}
+
+	if (cmd->scan_end_src != TRIG_COUNT) {
+		cmd->scan_end_src = TRIG_COUNT;
+		err++;
+	}
+
+	if (cmd->stop_src != TRIG_NONE &&
+		cmd->stop_src != TRIG_COUNT &&
+		cmd->stop_src != TRIG_INT && cmd->stop_src != TRIG_EXT) {
+		cmd->stop_src = TRIG_COUNT;
+		err++;
+	}
+
+	if (cmd->start_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT) {
+		cmd->start_src = TRIG_NOW;
+		err++;
+	}
+
+	if (cmd->start_src == TRIG_INT && cmd->scan_begin_src == TRIG_INT) {
+		cmd->start_src = TRIG_NOW;
+		err++;
+	}
+
+	if ((cmd->scan_begin_src & (TRIG_TIMER | TRIG_EXT)) &&
+		(!(cmd->convert_src & (TRIG_TIMER | TRIG_NOW)))) {
+		cmd->convert_src = TRIG_TIMER;
+		err++;
+	}
+
+	if ((cmd->scan_begin_src == TRIG_FOLLOW) &&
+		(!(cmd->convert_src & (TRIG_TIMER | TRIG_EXT)))) {
+		cmd->convert_src = TRIG_TIMER;
+		err++;
+	}
+
+	if (cmd->stop_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT) {
+		cmd->stop_src = TRIG_COUNT;
+		err++;
+	}
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->start_src & (TRIG_NOW | TRIG_EXT))
+		if (cmd->start_arg != 0) {
+			cmd->start_arg = 0;
+			err++;
+		}
+
+	if (cmd->scan_begin_src & (TRIG_FOLLOW | TRIG_EXT))
+		if (cmd->scan_begin_arg != 0) {
+			cmd->scan_begin_arg = 0;
+			err++;
+		}
+
+	if ((cmd->scan_begin_src == TRIG_TIMER) &&
+		(cmd->convert_src == TRIG_TIMER) && (cmd->scan_end_arg == 1)) {
+		cmd->scan_begin_src = TRIG_FOLLOW;
+		cmd->convert_arg = cmd->scan_begin_arg;
+		cmd->scan_begin_arg = 0;
+	}
+
+	if (cmd->scan_begin_src == TRIG_TIMER)
+		if (cmd->scan_begin_arg < this_board->ai_ns_min) {
+			cmd->scan_begin_arg = this_board->ai_ns_min;
+			err++;
+		}
+
+	if (cmd->scan_begin_src == TRIG_EXT)
+		if (cmd->scan_begin_arg) {
+			cmd->scan_begin_arg = 0;
+			err++;
+			if (cmd->scan_end_arg > 65535) {
+				cmd->scan_end_arg = 65535;
+				err++;
+			}
+		}
+
+	if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW))
+		if (cmd->convert_arg < this_board->ai_ns_min) {
+			cmd->convert_arg = this_board->ai_ns_min;
+			err++;
+		}
+
+	if (cmd->convert_src == TRIG_EXT)
+		if (cmd->convert_arg) {
+			cmd->convert_arg = 0;
+			err++;
+		}
+
+	if (cmd->stop_src == TRIG_COUNT) {
+		if (!cmd->stop_arg) {
+			cmd->stop_arg = 1;
+			err++;
+		}
+	} else {		/* TRIG_NONE */
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (!cmd->chanlist_len) {
+		cmd->chanlist_len = 1;
+		err++;
+	}
+
+	if (cmd->chanlist_len > this_board->n_aichanlist) {
+		cmd->chanlist_len = this_board->n_aichanlist;
+		err++;
+	}
+
+	if (cmd->scan_end_arg < cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+
+	if ((cmd->scan_end_arg % cmd->chanlist_len)) {
+		cmd->scan_end_arg =
+			cmd->chanlist_len * (cmd->scan_end_arg /
+			cmd->chanlist_len);
+		err++;
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		tmp = cmd->scan_begin_arg;
+//              rt_printk("S1 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg);
+		i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
+			&divisor2, &cmd->scan_begin_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+//              rt_printk("S2 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg);
+		if (cmd->scan_begin_arg < this_board->ai_ns_min)
+			cmd->scan_begin_arg = this_board->ai_ns_min;
+		if (tmp != cmd->scan_begin_arg)
+			err++;
+	}
+
+	if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) {
+		tmp = cmd->convert_arg;
+		i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
+			&divisor2, &cmd->convert_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+//              rt_printk("s1 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg);
+		if (cmd->convert_arg < this_board->ai_ns_min)
+			cmd->convert_arg = this_board->ai_ns_min;
+		if (tmp != cmd->convert_arg)
+			err++;
+		if (cmd->scan_begin_src == TRIG_TIMER
+			&& cmd->convert_src == TRIG_NOW) {
+			if (cmd->convert_arg == 0) {
+				if (cmd->scan_begin_arg <
+					this_board->ai_ns_min *
+					(cmd->scan_end_arg + 2)) {
+					cmd->scan_begin_arg =
+						this_board->ai_ns_min *
+						(cmd->scan_end_arg + 2);
+//              rt_printk("s2 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg);
+					err++;
+				}
+			} else {
+				if (cmd->scan_begin_arg <
+					cmd->convert_arg * cmd->chanlist_len) {
+					cmd->scan_begin_arg =
+						cmd->convert_arg *
+						cmd->chanlist_len;
+//              rt_printk("s3 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg);
+					err++;
+				}
+			}
+		}
+	}
+
+	if (err)
+		return 4;
+
+	if (cmd->chanlist)
+		if (!check_channel_list(dev, s, cmd->chanlist_len,
+				cmd->chanlist, 0, 0))
+			return 5;	// incorrect channels list
+
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+static int Compute_and_setup_dma(struct comedi_device * dev)
+{
+	unsigned int dmalen0, dmalen1, i;
+
+	DPRINTK("adl_pci9118 EDBG: BGN: Compute_and_setup_dma()\n");
+	dmalen0 = devpriv->dmabuf_size[0];
+	dmalen1 = devpriv->dmabuf_size[1];
+	DPRINTK("1 dmalen0=%d dmalen1=%d ai_data_len=%d\n", dmalen0, dmalen1,
+		devpriv->ai_data_len);
+	// isn't output buff smaller that our DMA buff?
+	if (dmalen0 > (devpriv->ai_data_len)) {
+		dmalen0 = devpriv->ai_data_len & ~3L;	// allign to 32bit down
+	}
+	if (dmalen1 > (devpriv->ai_data_len)) {
+		dmalen1 = devpriv->ai_data_len & ~3L;	// allign to 32bit down
+	}
+	DPRINTK("2 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
+
+	// we want wake up every scan?
+	if (devpriv->ai_flags & TRIG_WAKE_EOS) {
+		if (dmalen0 < (devpriv->ai_n_realscanlen << 1)) {
+			// uff, too short DMA buffer, disable EOS support!
+			devpriv->ai_flags &= (~TRIG_WAKE_EOS);
+			rt_printk
+				("comedi%d: WAR: DMA0 buf too short, cann't support TRIG_WAKE_EOS (%d<%d)\n",
+				dev->minor, dmalen0,
+				devpriv->ai_n_realscanlen << 1);
+		} else {
+			// short first DMA buffer to one scan
+			dmalen0 = devpriv->ai_n_realscanlen << 1;
+			DPRINTK("21 dmalen0=%d ai_n_realscanlen=%d useeoshandle=%d\n", dmalen0, devpriv->ai_n_realscanlen, devpriv->useeoshandle);
+			if (devpriv->useeoshandle)
+				dmalen0 += 2;
+			if (dmalen0 < 4) {
+				rt_printk
+					("comedi%d: ERR: DMA0 buf len bug? (%d<4)\n",
+					dev->minor, dmalen0);
+				dmalen0 = 4;
+			}
+		}
+	}
+	if (devpriv->ai_flags & TRIG_WAKE_EOS) {
+		if (dmalen1 < (devpriv->ai_n_realscanlen << 1)) {
+			// uff, too short DMA buffer, disable EOS support!
+			devpriv->ai_flags &= (~TRIG_WAKE_EOS);
+			rt_printk
+				("comedi%d: WAR: DMA1 buf too short, cann't support TRIG_WAKE_EOS (%d<%d)\n",
+				dev->minor, dmalen1,
+				devpriv->ai_n_realscanlen << 1);
+		} else {
+			// short second DMA buffer to one scan
+			dmalen1 = devpriv->ai_n_realscanlen << 1;
+			DPRINTK("22 dmalen1=%d ai_n_realscanlen=%d useeoshandle=%d\n", dmalen1, devpriv->ai_n_realscanlen, devpriv->useeoshandle);
+			if (devpriv->useeoshandle)
+				dmalen1 -= 2;
+			if (dmalen1 < 4) {
+				rt_printk
+					("comedi%d: ERR: DMA1 buf len bug? (%d<4)\n",
+					dev->minor, dmalen1);
+				dmalen1 = 4;
+			}
+		}
+	}
+
+	DPRINTK("3 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
+	// transfer without TRIG_WAKE_EOS
+	if (!(devpriv->ai_flags & TRIG_WAKE_EOS)) {
+		// if it's possible then allign DMA buffers to length of scan
+		i = dmalen0;
+		dmalen0 =
+			(dmalen0 / (devpriv->ai_n_realscanlen << 1)) *
+			(devpriv->ai_n_realscanlen << 1);
+		dmalen0 &= ~3L;
+		if (!dmalen0)
+			dmalen0 = i;	// uff. very long scan?
+		i = dmalen1;
+		dmalen1 =
+			(dmalen1 / (devpriv->ai_n_realscanlen << 1)) *
+			(devpriv->ai_n_realscanlen << 1);
+		dmalen1 &= ~3L;
+		if (!dmalen1)
+			dmalen1 = i;	// uff. very long scan?
+		// if measure isn't neverending then test, if it whole fits into one or two DMA buffers
+		if (!devpriv->ai_neverending) {
+			// fits whole measure into one DMA buffer?
+			if (dmalen0 >
+				((devpriv->ai_n_realscanlen << 1) *
+					devpriv->ai_scans)) {
+				DPRINTK("3.0 ai_n_realscanlen=%d ai_scans=%d \n", devpriv->ai_n_realscanlen, devpriv->ai_scans);
+				dmalen0 =
+					(devpriv->ai_n_realscanlen << 1) *
+					devpriv->ai_scans;
+				DPRINTK("3.1 dmalen0=%d dmalen1=%d \n", dmalen0,
+					dmalen1);
+				dmalen0 &= ~3L;
+			} else {	// fits whole measure into two DMA buffer?
+				if (dmalen1 >
+					((devpriv->ai_n_realscanlen << 1) *
+						devpriv->ai_scans - dmalen0))
+					dmalen1 =
+						(devpriv->
+						ai_n_realscanlen << 1) *
+						devpriv->ai_scans - dmalen0;
+				DPRINTK("3.2 dmalen0=%d dmalen1=%d \n", dmalen0,
+					dmalen1);
+				dmalen1 &= ~3L;
+			}
+		}
+	}
+
+	DPRINTK("4 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
+
+	// these DMA buffer size we'll be used
+	devpriv->dma_actbuf = 0;
+	devpriv->dmabuf_use_size[0] = dmalen0;
+	devpriv->dmabuf_use_size[1] = dmalen1;
+
+	DPRINTK("5 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
+#if 0
+	if (devpriv->ai_n_scanlen < this_board->half_fifo_size) {
+		devpriv->dmabuf_panic_size[0] =
+			(this_board->half_fifo_size / devpriv->ai_n_scanlen +
+			1) * devpriv->ai_n_scanlen * sizeof(short);
+		devpriv->dmabuf_panic_size[1] =
+			(this_board->half_fifo_size / devpriv->ai_n_scanlen +
+			1) * devpriv->ai_n_scanlen * sizeof(short);
+	} else {
+		devpriv->dmabuf_panic_size[0] =
+			(devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[0];
+		devpriv->dmabuf_panic_size[1] =
+			(devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[1];
+	}
+#endif
+
+	outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & (~EN_A2P_TRANSFERS), devpriv->iobase_a + AMCC_OP_REG_MCSR);	// stop DMA
+	outl(devpriv->dmabuf_hw[0], devpriv->iobase_a + AMCC_OP_REG_MWAR);
+	outl(devpriv->dmabuf_use_size[0], devpriv->iobase_a + AMCC_OP_REG_MWTC);
+	// init DMA transfer
+	outl(0x00000000 | AINT_WRITE_COMPL,
+		devpriv->iobase_a + AMCC_OP_REG_INTCSR);
+//      outl(0x02000000|AINT_WRITE_COMPL, devpriv->iobase_a+AMCC_OP_REG_INTCSR);
+
+	outl(inl(devpriv->iobase_a +
+			AMCC_OP_REG_MCSR) | RESET_A2P_FLAGS | A2P_HI_PRIORITY |
+		EN_A2P_TRANSFERS, devpriv->iobase_a + AMCC_OP_REG_MCSR);
+	outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | EN_A2P_TRANSFERS, devpriv->iobase_a + AMCC_OP_REG_INTCSR);	// allow bus mastering
+
+	DPRINTK("adl_pci9118 EDBG: END: Compute_and_setup_dma()\n");
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_ai_docmd_sampl(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_sampl(%d,) [%d]\n",
+		dev->minor, devpriv->ai_do);
+	switch (devpriv->ai_do) {
+	case 1:
+		devpriv->AdControlReg |= AdControl_TmrTr;
+		break;
+	case 2:
+		comedi_error(dev, "pci9118_ai_docmd_sampl() mode 2 bug!\n");
+		return -EIO;
+	case 3:
+		devpriv->AdControlReg |= AdControl_ExtM;
+		break;
+	case 4:
+		comedi_error(dev, "pci9118_ai_docmd_sampl() mode 4 bug!\n");
+		return -EIO;
+	default:
+		comedi_error(dev,
+			"pci9118_ai_docmd_sampl() mode number bug!\n");
+		return -EIO;
+	};
+
+	devpriv->int_ai_func = interrupt_pci9118_ai_onesample;	//transfer function
+
+	if (devpriv->ai12_startstop)
+		pci9118_exttrg_add(dev, EXTTRG_AI);	// activate EXT trigger
+
+	if ((devpriv->ai_do == 1) || (devpriv->ai_do == 2))
+		devpriv->IntControlReg |= Int_Timer;
+
+	devpriv->AdControlReg |= AdControl_Int;
+
+	outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, devpriv->iobase_a + AMCC_OP_REG_INTCSR);	// allow INT in AMCC
+
+	if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) {
+		outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
+		outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
+		if (devpriv->ai_do != 3) {
+			start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
+				devpriv->ai_divisor2);
+			devpriv->AdControlReg |= AdControl_SoftG;
+		}
+		outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
+	}
+
+	DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_docmd_sampl()\n");
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_ai_docmd_dma(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma(%d,) [%d,%d]\n",
+		dev->minor, devpriv->ai_do, devpriv->usedma);
+	Compute_and_setup_dma(dev);
+
+	switch (devpriv->ai_do) {
+	case 1:
+		devpriv->AdControlReg |=
+			((AdControl_TmrTr | AdControl_Dma) & 0xff);
+		break;
+	case 2:
+		devpriv->AdControlReg |=
+			((AdControl_TmrTr | AdControl_Dma) & 0xff);
+		devpriv->AdFunctionReg =
+			AdFunction_PDTrg | AdFunction_PETrg | AdFunction_BM |
+			AdFunction_BS;
+		if (devpriv->usessh && (!devpriv->softsshdelay))
+			devpriv->AdFunctionReg |= AdFunction_BSSH;
+		outl(devpriv->ai_n_realscanlen, dev->iobase + PCI9118_BURST);
+		break;
+	case 3:
+		devpriv->AdControlReg |=
+			((AdControl_ExtM | AdControl_Dma) & 0xff);
+		devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
+		break;
+	case 4:
+		devpriv->AdControlReg |=
+			((AdControl_TmrTr | AdControl_Dma) & 0xff);
+		devpriv->AdFunctionReg =
+			AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM;
+		outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
+		outl(0x30, dev->iobase + PCI9118_CNTCTRL);
+		outl((devpriv->dmabuf_hw[0] >> 1) & 0xff,
+			dev->iobase + PCI9118_CNT0);
+		outl((devpriv->dmabuf_hw[0] >> 9) & 0xff,
+			dev->iobase + PCI9118_CNT0);
+		devpriv->AdFunctionReg |= AdFunction_Start;
+		break;
+	default:
+		comedi_error(dev, "pci9118_ai_docmd_dma() mode number bug!\n");
+		return -EIO;
+	};
+
+	if (devpriv->ai12_startstop) {
+		pci9118_exttrg_add(dev, EXTTRG_AI);	// activate EXT trigger
+	}
+
+	devpriv->int_ai_func = interrupt_pci9118_ai_dma;	//transfer function
+
+	outl(0x02000000 | AINT_WRITE_COMPL,
+		devpriv->iobase_a + AMCC_OP_REG_INTCSR);
+
+	if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) {
+		outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
+		outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
+		if (devpriv->ai_do != 3) {
+			start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
+				devpriv->ai_divisor2);
+			devpriv->AdControlReg |= AdControl_SoftG;
+		}
+		outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
+	}
+
+	DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma()\n");
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int addchans = 0;
+	int ret = 0;
+
+	DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_cmd(%d,)\n", dev->minor);
+	devpriv->ai12_startstop = 0;
+	devpriv->ai_flags = cmd->flags;
+	devpriv->ai_n_chan = cmd->chanlist_len;
+	devpriv->ai_n_scanlen = cmd->scan_end_arg;
+	devpriv->ai_chanlist = cmd->chanlist;
+	devpriv->ai_data = s->async->prealloc_buf;
+	devpriv->ai_data_len = s->async->prealloc_bufsz;
+	devpriv->ai_timer1 = 0;
+	devpriv->ai_timer2 = 0;
+	devpriv->ai_add_front = 0;
+	devpriv->ai_add_back = 0;
+	devpriv->ai_maskerr = 0x10e;
+
+	// prepare for start/stop conditions
+	if (cmd->start_src == TRIG_EXT)
+		devpriv->ai12_startstop |= START_AI_EXT;
+	if (cmd->stop_src == TRIG_EXT) {
+		devpriv->ai_neverending = 1;
+		devpriv->ai12_startstop |= STOP_AI_EXT;
+	}
+	if (cmd->start_src == TRIG_INT) {
+		devpriv->ai12_startstop |= START_AI_INT;
+		devpriv->ai_inttrig_start = cmd->start_arg;
+		s->async->inttrig = pci9118_ai_inttrig;
+	}
+#if 0
+	if (cmd->stop_src == TRIG_INT) {
+		devpriv->ai_neverending = 1;
+		devpriv->ai12_startstop |= STOP_AI_INT;
+	}
+#endif
+	if (cmd->stop_src == TRIG_NONE)
+		devpriv->ai_neverending = 1;
+	if (cmd->stop_src == TRIG_COUNT) {
+		devpriv->ai_scans = cmd->stop_arg;
+		devpriv->ai_neverending = 0;
+	} else {
+		devpriv->ai_scans = 0;
+	}
+
+	// use sample&hold signal?
+	if (cmd->convert_src == TRIG_NOW) {
+		devpriv->usessh = 1;
+	}			// yes
+	else {
+		devpriv->usessh = 0;
+	}			// no
+
+	DPRINTK("1 neverending=%d scans=%u usessh=%d ai_startstop=0x%2x\n",
+		devpriv->ai_neverending, devpriv->ai_scans, devpriv->usessh,
+		devpriv->ai12_startstop);
+
+	// use additional sample at end of every scan to satisty DMA 32 bit transfer?
+	devpriv->ai_add_front = 0;
+	devpriv->ai_add_back = 0;
+	devpriv->useeoshandle = 0;
+	if (devpriv->master) {
+		devpriv->usedma = 1;
+		if ((cmd->flags & TRIG_WAKE_EOS) &&
+			(devpriv->ai_n_scanlen == 1)) {
+			if (cmd->convert_src == TRIG_NOW) {
+				devpriv->ai_add_back = 1;
+			}
+			if (cmd->convert_src == TRIG_TIMER) {
+				devpriv->usedma = 0;	// use INT transfer if scanlist have only one channel
+			}
+		}
+		if ((cmd->flags & TRIG_WAKE_EOS) &&
+			(devpriv->ai_n_scanlen & 1) &&
+			(devpriv->ai_n_scanlen > 1)) {
+			if (cmd->scan_begin_src == TRIG_FOLLOW) {
+				//vpriv->useeoshandle=1; // change DMA transfer block to fit EOS on every second call
+				devpriv->usedma = 0;	// XXX maybe can be corrected to use 16 bit DMA
+			} else {	// well, we must insert one sample to end of EOS to meet 32 bit transfer
+				devpriv->ai_add_back = 1;
+			}
+		}
+	} else {		// interrupt transfer don't need any correction
+		devpriv->usedma = 0;
+	}
+
+	// we need software S&H signal? It add  two samples before every scan as minimum
+	if (devpriv->usessh && devpriv->softsshdelay) {
+		devpriv->ai_add_front = 2;
+		if ((devpriv->usedma == 1) && (devpriv->ai_add_back == 1)) {	// move it to front
+			devpriv->ai_add_front++;
+			devpriv->ai_add_back = 0;
+		}
+		if (cmd->convert_arg < this_board->ai_ns_min)
+			cmd->convert_arg = this_board->ai_ns_min;
+		addchans = devpriv->softsshdelay / cmd->convert_arg;
+		if (devpriv->softsshdelay % cmd->convert_arg)
+			addchans++;
+		if (addchans > (devpriv->ai_add_front - 1)) {	// uff, still short :-(
+			devpriv->ai_add_front = addchans + 1;
+			if (devpriv->usedma == 1)
+				if ((devpriv->ai_add_front +
+						devpriv->ai_n_chan +
+						devpriv->ai_add_back) & 1)
+					devpriv->ai_add_front++;	// round up to 32 bit
+		}
+	}			// well, we now know what must be all added
+
+	devpriv->ai_n_realscanlen =	// what we must take from card in real to have ai_n_scanlen on output?
+		(devpriv->ai_add_front + devpriv->ai_n_chan +
+		devpriv->ai_add_back) * (devpriv->ai_n_scanlen /
+		devpriv->ai_n_chan);
+
+	DPRINTK("2 usedma=%d realscan=%d af=%u n_chan=%d ab=%d n_scanlen=%d\n",
+		devpriv->usedma,
+		devpriv->ai_n_realscanlen, devpriv->ai_add_front,
+		devpriv->ai_n_chan, devpriv->ai_add_back,
+		devpriv->ai_n_scanlen);
+
+	// check and setup channel list
+	if (!check_channel_list(dev, s, devpriv->ai_n_chan,
+			devpriv->ai_chanlist, devpriv->ai_add_front,
+			devpriv->ai_add_back))
+		return -EINVAL;
+	if (!setup_channel_list(dev, s, devpriv->ai_n_chan,
+			devpriv->ai_chanlist, 0, devpriv->ai_add_front,
+			devpriv->ai_add_back, devpriv->usedma,
+			devpriv->useeoshandle))
+		return -EINVAL;
+
+	// compute timers settings
+	// simplest way, fr=4Mhz/(tim1*tim2), channel manipulation without timers effect
+	if (((cmd->scan_begin_src == TRIG_FOLLOW) || (cmd->scan_begin_src == TRIG_EXT) || (cmd->scan_begin_src == TRIG_INT)) && (cmd->convert_src == TRIG_TIMER)) {	// both timer is used for one time
+		if (cmd->scan_begin_src == TRIG_EXT) {
+			devpriv->ai_do = 4;
+		} else {
+			devpriv->ai_do = 1;
+		}
+		pci9118_calc_divisors(devpriv->ai_do, dev, s,
+			&cmd->scan_begin_arg, &cmd->convert_arg,
+			devpriv->ai_flags, devpriv->ai_n_realscanlen,
+			&devpriv->ai_divisor1, &devpriv->ai_divisor2,
+			devpriv->usessh, devpriv->ai_add_front);
+		devpriv->ai_timer2 = cmd->convert_arg;
+	}
+
+	if ((cmd->scan_begin_src == TRIG_TIMER) && ((cmd->convert_src == TRIG_TIMER) || (cmd->convert_src == TRIG_NOW))) {	// double timed action
+		if (!devpriv->usedma) {
+			comedi_error(dev,
+				"cmd->scan_begin_src=TRIG_TIMER works only with bus mastering!");
+			return -EIO;
+		}
+
+		devpriv->ai_do = 2;
+		pci9118_calc_divisors(devpriv->ai_do, dev, s,
+			&cmd->scan_begin_arg, &cmd->convert_arg,
+			devpriv->ai_flags, devpriv->ai_n_realscanlen,
+			&devpriv->ai_divisor1, &devpriv->ai_divisor2,
+			devpriv->usessh, devpriv->ai_add_front);
+		devpriv->ai_timer1 = cmd->scan_begin_arg;
+		devpriv->ai_timer2 = cmd->convert_arg;
+	}
+
+	if ((cmd->scan_begin_src == TRIG_FOLLOW)
+		&& (cmd->convert_src == TRIG_EXT)) {
+		devpriv->ai_do = 3;
+	}
+
+	start_pacer(dev, -1, 0, 0);	// stop pacer
+
+	devpriv->AdControlReg = 0;	// bipolar, S.E., use 8254, stop 8354, internal trigger, soft trigger, disable DMA
+	outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
+	devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;	// positive triggers, no S&H, no burst, burst stop, no post trigger, no about trigger, trigger stop
+	outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
+	comedi_udelay(1);
+	outl(0, dev->iobase + PCI9118_DELFIFO);	// flush FIFO
+	inl(dev->iobase + PCI9118_ADSTAT);	// flush A/D and INT status register
+	inl(dev->iobase + PCI9118_INTSRC);
+
+	devpriv->ai_act_scan = 0;
+	devpriv->ai_act_dmapos = 0;
+	s->async->cur_chan = 0;
+	devpriv->ai_buf_ptr = 0;
+
+	if (devpriv->usedma) {
+		ret = pci9118_ai_docmd_dma(dev, s);
+	} else {
+		ret = pci9118_ai_docmd_sampl(dev, s);
+	}
+
+	DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_cmd()\n");
+	return ret;
+}
+
+/*
+==============================================================================
+*/
+static int check_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+	int n_chan, unsigned int *chanlist, int frontadd, int backadd)
+{
+	unsigned int i, differencial = 0, bipolar = 0;
+
+	/* correct channel and range number check itself comedi/range.c */
+	if (n_chan < 1) {
+		comedi_error(dev, "range/channel list is empty!");
+		return 0;
+	}
+	if ((frontadd + n_chan + backadd) > s->len_chanlist) {
+		rt_printk
+			("comedi%d: range/channel list is too long for actual configuration (%d>%d)!",
+			dev->minor, n_chan,
+			s->len_chanlist - frontadd - backadd);
+		return 0;
+	}
+
+	if (CR_AREF(chanlist[0]) == AREF_DIFF)
+		differencial = 1;	// all input must be diff
+	if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
+		bipolar = 1;	// all input must be bipolar
+	if (n_chan > 1)
+		for (i = 1; i < n_chan; i++) {	// check S.E/diff
+			if ((CR_AREF(chanlist[i]) == AREF_DIFF) !=
+				(differencial)) {
+				comedi_error(dev,
+					"Differencial and single ended inputs cann't be mixtured!");
+				return 0;
+			}
+			if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) !=
+				(bipolar)) {
+				comedi_error(dev,
+					"Bipolar and unipolar ranges cann't be mixtured!");
+				return 0;
+			}
+			if ((!devpriv->usemux) & (differencial) &
+				(CR_CHAN(chanlist[i]) >=
+					this_board->n_aichand)) {
+				comedi_error(dev,
+					"If AREF_DIFF is used then is available only first 8 channels!");
+				return 0;
+			}
+		}
+
+	return 1;
+}
+
+/*
+==============================================================================
+*/
+static int setup_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+	int n_chan, unsigned int *chanlist, int rot, int frontadd, int backadd,
+	int usedma, char useeos)
+{
+	unsigned int i, differencial = 0, bipolar = 0;
+	unsigned int scanquad, gain, ssh = 0x00;
+
+	DPRINTK("adl_pci9118 EDBG: BGN: setup_channel_list(%d,.,%d,.,%d,%d,%d,%d)\n", dev->minor, n_chan, rot, frontadd, backadd, usedma);
+
+	if (usedma == 1) {
+		rot = 8;
+		usedma = 0;
+	}
+
+	if (CR_AREF(chanlist[0]) == AREF_DIFF)
+		differencial = 1;	// all input must be diff
+	if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
+		bipolar = 1;	// all input must be bipolar
+
+	// All is ok, so we can setup channel/range list
+
+	if (!bipolar) {
+		devpriv->AdControlReg |= AdControl_UniP;	// set unibipolar
+	} else {
+		devpriv->AdControlReg &= ((~AdControl_UniP) & 0xff);	// enable bipolar
+	}
+
+	if (differencial) {
+		devpriv->AdControlReg |= AdControl_Diff;	// enable diff inputs
+	} else {
+		devpriv->AdControlReg &= ((~AdControl_Diff) & 0xff);	// set single ended inputs
+	}
+
+	outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);	// setup mode
+
+	outl(2, dev->iobase + PCI9118_SCANMOD);	// gods know why this sequence!
+	outl(0, dev->iobase + PCI9118_SCANMOD);
+	outl(1, dev->iobase + PCI9118_SCANMOD);
+
+#ifdef PCI9118_PARANOIDCHECK
+	devpriv->chanlistlen = n_chan;
+	for (i = 0; i < (PCI9118_CHANLEN + 1); i++)
+		devpriv->chanlist[i] = 0x55aa;
+#endif
+
+	if (frontadd) {		// insert channels for S&H
+		ssh = devpriv->softsshsample;
+		DPRINTK("FA: %04x: ", ssh);
+		for (i = 0; i < frontadd; i++) {	// store range list to card
+			scanquad = CR_CHAN(chanlist[0]);	// get channel number;
+			gain = CR_RANGE(chanlist[0]);	// get gain number
+			scanquad |= ((gain & 0x03) << 8);
+			outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
+			DPRINTK("%02x ", scanquad | ssh);
+			ssh = devpriv->softsshhold;
+		}
+		DPRINTK("\n ");
+	}
+
+	DPRINTK("SL: ", ssh);
+	for (i = 0; i < n_chan; i++) {	// store range list to card
+		scanquad = CR_CHAN(chanlist[i]);	// get channel number;
+#ifdef PCI9118_PARANOIDCHECK
+		devpriv->chanlist[i ^ usedma] = (scanquad & 0xf) << rot;
+#endif
+		gain = CR_RANGE(chanlist[i]);	// get gain number
+		scanquad |= ((gain & 0x03) << 8);
+		outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
+		DPRINTK("%02x ", scanquad | ssh);
+	}
+	DPRINTK("\n ");
+
+	if (backadd) {		// insert channels for fit onto 32bit DMA
+		DPRINTK("BA: %04x: ", ssh);
+		for (i = 0; i < backadd; i++) {	// store range list to card
+			scanquad = CR_CHAN(chanlist[0]);	// get channel number;
+			gain = CR_RANGE(chanlist[0]);	// get gain number
+			scanquad |= ((gain & 0x03) << 8);
+			outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
+			DPRINTK("%02x ", scanquad | ssh);
+		}
+		DPRINTK("\n ");
+	}
+#ifdef PCI9118_PARANOIDCHECK
+	devpriv->chanlist[n_chan ^ usedma] = devpriv->chanlist[0 ^ usedma];	// for 32bit oerations
+	if (useeos) {
+		for (i = 1; i < n_chan; i++) {	// store range list to card
+			devpriv->chanlist[(n_chan + i) ^ usedma] =
+				(CR_CHAN(chanlist[i]) & 0xf) << rot;
+		}
+		devpriv->chanlist[(2 * n_chan) ^ usedma] = devpriv->chanlist[0 ^ usedma];	// for 32bit oerations
+		useeos = 2;
+	} else {
+		useeos = 1;
+	}
+#ifdef PCI9118_EXTDEBUG
+	DPRINTK("CHL: ");
+	for (i = 0; i <= (useeos * n_chan); i++) {
+		DPRINTK("%04x ", devpriv->chanlist[i]);
+	}
+	DPRINTK("\n ");
+#endif
+#endif
+	outl(0, dev->iobase + PCI9118_SCANMOD);	// close scan queue
+//      comedi_udelay(100);                             // important delay, or first sample will be cripled
+
+	DPRINTK("adl_pci9118 EDBG: END: setup_channel_list()\n");
+	return 1;		// we can serve this with scan logic
+}
+
+/*
+==============================================================================
+  calculate 8254 divisors if they are used for dual timing
+*/
+static void pci9118_calc_divisors(char mode, struct comedi_device * dev,
+	struct comedi_subdevice * s, unsigned int *tim1, unsigned int *tim2,
+	unsigned int flags, int chans, unsigned int *div1, unsigned int *div2,
+	char usessh, unsigned int chnsshfront)
+{
+	DPRINTK("adl_pci9118 EDBG: BGN: pci9118_calc_divisors(%d,%d,.,%u,%u,%u,%d,.,.,,%u,%u)\n", mode, dev->minor, *tim1, *tim2, flags, chans, usessh, chnsshfront);
+	switch (mode) {
+	case 1:
+	case 4:
+		if (*tim2 < this_board->ai_ns_min)
+			*tim2 = this_board->ai_ns_min;
+		i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, div1, div2,
+			tim2, flags & TRIG_ROUND_NEAREST);
+		DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u\n",
+			devpriv->i8254_osc_base, *div1, *div2, *tim1);
+		break;
+	case 2:
+		if (*tim2 < this_board->ai_ns_min)
+			*tim2 = this_board->ai_ns_min;
+		DPRINTK("1 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
+			*tim1, *tim2);
+		*div1 = *tim2 / devpriv->i8254_osc_base;	// convert timer (burst)
+		DPRINTK("2 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
+			*tim1, *tim2);
+		if (*div1 < this_board->ai_pacer_min)
+			*div1 = this_board->ai_pacer_min;
+		DPRINTK("3 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
+			*tim1, *tim2);
+		*div2 = *tim1 / devpriv->i8254_osc_base;	// scan timer
+		DPRINTK("4 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
+			*tim1, *tim2);
+		*div2 = *div2 / *div1;	// major timer is c1*c2
+		DPRINTK("5 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
+			*tim1, *tim2);
+		if (*div2 < chans)
+			*div2 = chans;
+		DPRINTK("6 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
+			*tim1, *tim2);
+
+		*tim2 = *div1 * devpriv->i8254_osc_base;	// real convert timer
+
+		if (usessh & (chnsshfront == 0))	// use BSSH signal
+			if (*div2 < (chans + 2))
+				*div2 = chans + 2;
+
+		DPRINTK("7 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
+			*tim1, *tim2);
+		*tim1 = *div1 * *div2 * devpriv->i8254_osc_base;
+		DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u timer2=%u\n",
+			devpriv->i8254_osc_base, *div1, *div2, *tim1, *tim2);
+		break;
+	}
+	DPRINTK("adl_pci9118 EDBG: END: pci9118_calc_divisors(%u,%u)\n",
+		*div1, *div2);
+}
+
+/*
+==============================================================================
+*/
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+	unsigned int divisor2)
+{
+	outl(0x74, dev->iobase + PCI9118_CNTCTRL);
+	outl(0xb4, dev->iobase + PCI9118_CNTCTRL);
+//      outl(0x30, dev->iobase + PCI9118_CNTCTRL);
+	comedi_udelay(1);
+
+	if ((mode == 1) || (mode == 2) || (mode == 4)) {
+		outl(divisor2 & 0xff, dev->iobase + PCI9118_CNT2);
+		outl((divisor2 >> 8) & 0xff, dev->iobase + PCI9118_CNT2);
+		outl(divisor1 & 0xff, dev->iobase + PCI9118_CNT1);
+		outl((divisor1 >> 8) & 0xff, dev->iobase + PCI9118_CNT1);
+	}
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_exttrg_add(struct comedi_device * dev, unsigned char source)
+{
+	if (source > 3)
+		return -1;	// incorrect source
+	devpriv->exttrg_users |= (1 << source);
+	devpriv->IntControlReg |= Int_DTrg;
+	outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
+	outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, devpriv->iobase_a + AMCC_OP_REG_INTCSR);	// allow INT in AMCC
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_exttrg_del(struct comedi_device * dev, unsigned char source)
+{
+	if (source > 3)
+		return -1;	// incorrect source
+	devpriv->exttrg_users &= ~(1 << source);
+	if (!devpriv->exttrg_users) {	// shutdown ext trg intterrupts
+		devpriv->IntControlReg &= ~Int_DTrg;
+		if (!devpriv->IntControlReg)	// all IRQ disabled
+			outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) & (~0x00001f00), devpriv->iobase_a + AMCC_OP_REG_INTCSR);	// disable int in AMCC
+		outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
+	}
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	if (devpriv->usedma)
+		outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & (~EN_A2P_TRANSFERS), devpriv->iobase_a + AMCC_OP_REG_MCSR);	// stop DMA
+	pci9118_exttrg_del(dev, EXTTRG_AI);
+	start_pacer(dev, 0, 0, 0);	// stop 8254 counters
+	devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
+	outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);	// positive triggers, no S&H, no burst, burst stop, no post trigger, no about trigger, trigger stop
+	devpriv->AdControlReg = 0x00;
+	outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);	// bipolar, S.E., use 8254, stop 8354, internal trigger, soft trigger, disable INT and DMA
+	outl(0, dev->iobase + PCI9118_BURST);
+	outl(1, dev->iobase + PCI9118_SCANMOD);
+	outl(2, dev->iobase + PCI9118_SCANMOD);	// reset scan queue
+	outl(0, dev->iobase + PCI9118_DELFIFO);	// flush FIFO
+
+	devpriv->ai_do = 0;
+	devpriv->usedma = 0;
+
+	devpriv->ai_act_scan = 0;
+	devpriv->ai_act_dmapos = 0;
+	s->async->cur_chan = 0;
+	s->async->inttrig = NULL;
+	devpriv->ai_buf_ptr = 0;
+	devpriv->ai_neverending = 0;
+	devpriv->dma_actbuf = 0;
+
+	if (!devpriv->IntControlReg)
+		outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, devpriv->iobase_a + AMCC_OP_REG_INTCSR);	// allow INT in AMCC
+
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_reset(struct comedi_device * dev)
+{
+	devpriv->IntControlReg = 0;
+	devpriv->exttrg_users = 0;
+	inl(dev->iobase + PCI9118_INTCTRL);
+	outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);	// disable interrupts source
+	outl(0x30, dev->iobase + PCI9118_CNTCTRL);
+//        outl(0xb4, dev->iobase + PCI9118_CNTCTRL);
+	start_pacer(dev, 0, 0, 0);	// stop 8254 counters
+	devpriv->AdControlReg = 0;
+	outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);	// bipolar, S.E., use 8254, stop 8354, internal trigger, soft trigger, disable INT and DMA
+	outl(0, dev->iobase + PCI9118_BURST);
+	outl(1, dev->iobase + PCI9118_SCANMOD);
+	outl(2, dev->iobase + PCI9118_SCANMOD);	// reset scan queue
+	devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
+	outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);	// positive triggers, no S&H, no burst, burst stop, no post trigger, no about trigger, trigger stop
+
+	devpriv->ao_data[0] = 2047;
+	devpriv->ao_data[1] = 2047;
+	outl(devpriv->ao_data[0], dev->iobase + PCI9118_DA1);	// reset A/D outs to 0V
+	outl(devpriv->ao_data[1], dev->iobase + PCI9118_DA2);
+	outl(0, dev->iobase + PCI9118_DO);	// reset digi outs to L
+	comedi_udelay(10);
+	inl(dev->iobase + PCI9118_AD_DATA);
+	outl(0, dev->iobase + PCI9118_DELFIFO);	// flush FIFO
+	outl(0, dev->iobase + PCI9118_INTSRC);	// remove INT requests
+	inl(dev->iobase + PCI9118_ADSTAT);	// flush A/D status register
+	inl(dev->iobase + PCI9118_INTSRC);	// flush INT requests
+	devpriv->AdControlReg = 0;
+	outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);	// bipolar, S.E., use 8254, stop 8354, internal trigger, soft trigger, disable INT and DMA
+
+	devpriv->cnt0_users = 0;
+	devpriv->exttrg_users = 0;
+
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	int ret, pages, i;
+	unsigned short master;
+	unsigned int irq;
+	unsigned long iobase_a, iobase_9;
+	struct pci_dev *pcidev;
+	int opt_bus, opt_slot;
+	const char *errstr;
+	unsigned char pci_bus, pci_slot, pci_func;
+	u16 u16w;
+
+	rt_printk("comedi%d: adl_pci9118: board=%s", dev->minor,
+		this_board->name);
+
+	opt_bus = it->options[0];
+	opt_slot = it->options[1];
+	if (it->options[3] & 1) {
+		master = 0;	// user don't want use bus master
+	} else {
+		master = 1;
+	}
+
+	if ((ret = alloc_private(dev, sizeof(struct pci9118_private))) < 0) {
+		rt_printk(" - Allocation failed!\n");
+		return -ENOMEM;
+	}
+
+	/* Look for matching PCI device */
+	errstr = "not found!";
+	pcidev = NULL;
+	while (NULL != (pcidev = pci_get_device(PCI_VENDOR_ID_AMCC,
+				this_board->device_id, pcidev))) {
+		/* Found matching vendor/device. */
+		if (opt_bus || opt_slot) {
+			/* Check bus/slot. */
+			if (opt_bus != pcidev->bus->number
+				|| opt_slot != PCI_SLOT(pcidev->devfn))
+				continue;	/* no match */
+		}
+		/*
+		 * Look for device that isn't in use.
+		 * Enable PCI device and request regions.
+		 */
+		if (comedi_pci_enable(pcidev, "adl_pci9118")) {
+			errstr = "failed to enable PCI device and request regions!";
+			continue;
+		}
+		break;
+	}
+
+	if (!pcidev) {
+		if (opt_bus || opt_slot) {
+			rt_printk(" - Card at b:s %d:%d %s\n",
+				opt_bus, opt_slot, errstr);
+		} else {
+			rt_printk(" - Card %s\n", errstr);
+		}
+		return -EIO;
+	}
+
+	if (master) {
+		pci_set_master(pcidev);
+	}
+
+	pci_bus = pcidev->bus->number;
+	pci_slot = PCI_SLOT(pcidev->devfn);
+	pci_func = PCI_FUNC(pcidev->devfn);
+	irq = pcidev->irq;
+	iobase_a = pci_resource_start(pcidev, 0);
+	iobase_9 = pci_resource_start(pcidev, 2);
+
+	rt_printk(", b:s:f=%d:%d:%d, io=0x%4lx, 0x%4lx", pci_bus, pci_slot,
+		pci_func, iobase_9, iobase_a);
+
+	dev->iobase = iobase_9;
+	dev->board_name = this_board->name;
+
+	devpriv->pcidev = pcidev;
+	devpriv->iobase_a = iobase_a;
+
+	pci9118_reset(dev);
+
+	if (it->options[3] & 2)
+		irq = 0;	// user don't want use IRQ
+	if (irq > 0) {
+		if (comedi_request_irq(irq, interrupt_pci9118, IRQF_SHARED,
+				"ADLink PCI-9118", dev)) {
+			rt_printk(", unable to allocate IRQ %d, DISABLING IT",
+				irq);
+			irq = 0;	/* Can't use IRQ */
+		} else {
+			rt_printk(", irq=%u", irq);
+		}
+	} else {
+		rt_printk(", IRQ disabled");
+	}
+
+	dev->irq = irq;
+
+	if (master) {		// alloc DMA buffers
+		devpriv->dma_doublebuf = 0;
+		for (i = 0; i < 2; i++) {
+			for (pages = 4; pages >= 0; pages--)
+				if ((devpriv->dmabuf_virt[i] = (short *)
+						__get_free_pages(GFP_KERNEL,
+							pages)))
+					break;
+			if (devpriv->dmabuf_virt[i]) {
+				devpriv->dmabuf_pages[i] = pages;
+				devpriv->dmabuf_size[i] = PAGE_SIZE * pages;
+				devpriv->dmabuf_samples[i] =
+					devpriv->dmabuf_size[i] >> 1;
+				devpriv->dmabuf_hw[i] =
+					virt_to_bus((void *)devpriv->
+					dmabuf_virt[i]);
+			}
+		}
+		if (!devpriv->dmabuf_virt[0]) {
+			rt_printk(", Can't allocate DMA buffer, DMA disabled!");
+			master = 0;
+		}
+
+		if (devpriv->dmabuf_virt[1])
+			devpriv->dma_doublebuf = 1;
+
+	}
+
+	if ((devpriv->master = master)) {
+		rt_printk(", bus master");
+	} else {
+		rt_printk(", no bus master");
+	}
+
+	devpriv->usemux = 0;
+	if (it->options[2] > 0) {
+		devpriv->usemux = it->options[2];
+		if (devpriv->usemux > 256)
+			devpriv->usemux = 256;	// max 256 channels!
+		if (it->options[4] > 0)
+			if (devpriv->usemux > 128) {
+				devpriv->usemux = 128;	// max 128 channels with softare S&H!
+			}
+		rt_printk(", ext. mux %d channels", devpriv->usemux);
+	}
+
+	devpriv->softsshdelay = it->options[4];
+	if (devpriv->softsshdelay < 0) {	// select sample&hold signal polarity
+		devpriv->softsshdelay = -devpriv->softsshdelay;
+		devpriv->softsshsample = 0x80;
+		devpriv->softsshhold = 0x00;
+	} else {
+		devpriv->softsshsample = 0x00;
+		devpriv->softsshhold = 0x80;
+	}
+
+	rt_printk(".\n");
+
+	pci_read_config_word(devpriv->pcidev, PCI_COMMAND, &u16w);
+	pci_write_config_word(devpriv->pcidev, PCI_COMMAND, u16w | 64);	// Enable parity check for parity error
+
+	if ((ret = alloc_subdevices(dev, 4)) < 0)
+		return ret;
+
+	s = dev->subdevices + 0;
+	dev->read_subdev = s;
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
+	if (devpriv->usemux) {
+		s->n_chan = devpriv->usemux;
+	} else {
+		s->n_chan = this_board->n_aichan;
+	}
+	s->maxdata = this_board->ai_maxdata;
+	s->len_chanlist = this_board->n_aichanlist;
+	s->range_table = this_board->rangelist_ai;
+	s->cancel = pci9118_ai_cancel;
+	s->insn_read = pci9118_insn_read_ai;
+	if (dev->irq) {
+		s->subdev_flags |= SDF_CMD_READ;
+		s->do_cmdtest = pci9118_ai_cmdtest;
+		s->do_cmd = pci9118_ai_cmd;
+		s->munge = pci9118_ai_munge;
+	}
+
+	s = dev->subdevices + 1;
+	s->type = COMEDI_SUBD_AO;
+	s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+	s->n_chan = this_board->n_aochan;
+	s->maxdata = this_board->ao_maxdata;
+	s->len_chanlist = this_board->n_aochan;
+	s->range_table = this_board->rangelist_ao;
+	s->insn_write = pci9118_insn_write_ao;
+	s->insn_read = pci9118_insn_read_ao;
+
+	s = dev->subdevices + 2;
+	s->type = COMEDI_SUBD_DI;
+	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
+	s->n_chan = 4;
+	s->maxdata = 1;
+	s->len_chanlist = 4;
+	s->range_table = &range_digital;
+	s->io_bits = 0;		/* all bits input */
+	s->insn_bits = pci9118_insn_bits_di;
+
+	s = dev->subdevices + 3;
+	s->type = COMEDI_SUBD_DO;
+	s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+	s->n_chan = 4;
+	s->maxdata = 1;
+	s->len_chanlist = 4;
+	s->range_table = &range_digital;
+	s->io_bits = 0xf;	/* all bits output */
+	s->insn_bits = pci9118_insn_bits_do;
+
+	devpriv->valid = 1;
+	devpriv->i8254_osc_base = 250;	// 250ns=4MHz
+	devpriv->ai_maskharderr = 0x10a;	// default measure crash condition
+	if (it->options[5])	// disable some requested
+		devpriv->ai_maskharderr &= ~it->options[5];
+
+	switch (this_board->ai_maxdata) {
+	case 0xffff:
+		devpriv->ai16bits = 1;
+		break;
+	default:
+		devpriv->ai16bits = 0;
+		break;
+	}
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_detach(struct comedi_device * dev)
+{
+	if (dev->private) {
+		if (devpriv->valid)
+			pci9118_reset(dev);
+		if (dev->irq)
+			comedi_free_irq(dev->irq, dev);
+		if (devpriv->pcidev) {
+			if (dev->iobase) {
+				comedi_pci_disable(devpriv->pcidev);
+			}
+			pci_dev_put(devpriv->pcidev);
+		}
+		if (devpriv->dmabuf_virt[0])
+			free_pages((unsigned long)devpriv->dmabuf_virt[0],
+				devpriv->dmabuf_pages[0]);
+		if (devpriv->dmabuf_virt[1])
+			free_pages((unsigned long)devpriv->dmabuf_virt[1],
+				devpriv->dmabuf_pages[1]);
+	}
+
+	return 0;
+}
+
+/*
+==============================================================================
+*/
diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c
new file mode 100644
index 0000000..92f6285
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adq12b.c
@@ -0,0 +1,394 @@
+/*
+    comedi/drivers/adq12b.c
+    driver for MicroAxial ADQ12-B data acquisition and control card
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: adq12b
+Description: driver for MicroAxial ADQ12-B data acquisition and control card
+Devices: [MicroAxial] ADQ12-B (adq12b)
+Author: jeremy theler <thelerg@ib.cnea.gov.ar>
+Updated: Thu, 21 Feb 2008 02:56:27 -0300
+Status: works
+
+Driver for the acquisition card ADQ12-B (without any add-on).
+
+ - Analog input is subdevice 0 (16 channels single-ended or 8 differential)
+ - Digital input is subdevice 1 (5 channels)
+ - Digital output is subdevice 1 (8 channels)
+ - The PACER is not supported in this version
+
+If you do not specify any options, they will default to
+
+  # comedi_config /dev/comedi0 adq12b 0x300,0,0
+
+  option 1: I/O base address. The following table is provided as a help
+   of the hardware jumpers.
+
+         address            jumper JADR
+          0x300                 1 (factory default)
+          0x320                 2
+          0x340                 3
+          0x360                 4
+          0x380                 5
+          0x3A0                 6
+
+  option 2: unipolar/bipolar ADC selection: 0 -> bipolar, 1 -> unipolar
+
+        selection         comedi_config option            JUB
+         bipolar                0                         2-3 (factory default)
+         unipolar               1                         1-2
+
+  option 3: single-ended/differential AI selection: 0 -> SE, 1 -> differential
+
+        selection         comedi_config option     JCHA    JCHB
+       single-ended             0                  1-2     1-2 (factory default)
+       differential             1                  2-3     2-3
+
+
+   written by jeremy theler <thelerg@ib.cnea.gov.ar>
+
+   instituto balseiro
+   comision nacional de energia atomica
+   universidad nacional de cuyo
+   argentina
+
+   21-feb-2008
+     + changed supported devices string (missused the [] and ())
+
+   13-oct-2007
+     + first try
+
+
+*/
+
+#include "../comedidev.h"
+
+// address scheme (page 2.17 of the manual)
+#define ADQ12B_SIZE     16
+
+#define ADQ12B_CTREG    0x00
+#define ADQ12B_STINR    0x00
+#define ADQ12B_OUTBR    0x04
+#define ADQ12B_ADLOW    0x08
+#define ADQ12B_ADHIG    0x09
+#define ADQ12B_CONT0    0x0c
+#define ADQ12B_CONT1    0x0d
+#define ADQ12B_CONT2    0x0e
+#define ADQ12B_COWORD   0x0f
+
+// mask of the bit at STINR to check end of conversion
+#define ADQ12B_EOC     0x20
+
+#define TIMEOUT        20
+
+// available ranges through the PGA gains
+static const struct comedi_lrange range_adq12b_ai_bipolar = { 4, {
+        BIP_RANGE( 5 ),
+        BIP_RANGE( 2 ),
+        BIP_RANGE( 1 ),
+        BIP_RANGE( 0.5 )
+}};
+
+static const struct comedi_lrange range_adq12b_ai_unipolar = { 4, {
+        UNI_RANGE( 5 ),
+        UNI_RANGE( 2 ),
+        UNI_RANGE( 1 ),
+        UNI_RANGE( 0.5 )
+}};
+
+
+
+struct adq12b_board {
+        const char *name;
+        int ai_se_chans;
+        int ai_diff_chans;
+        int ai_bits;
+        int di_chans;
+        int do_chans;
+};
+
+static const struct adq12b_board adq12b_boards[] = {
+        {
+        name:           "adq12b",
+        ai_se_chans:    16,
+        ai_diff_chans:  8,
+        ai_bits:        12,
+        di_chans:       5,
+        do_chans:       8
+        }
+// potentially, more adq-based deviced will be added
+/*,
+        name:           "adq12b",
+        ai_chans:       16,  // this is just for reference, hardcoded again later
+        ai_bits:        12,
+        di_chans:       8,
+        do_chans:       5
+        }*/
+};
+
+#define thisboard ((const struct adq12b_board *)dev->board_ptr)
+
+struct adq12b_private {
+        int unipolar;          /* option 2 of comedi_config (1 is iobase) */
+        int differential;      /* option 3 of comedi_config */
+        int last_channel;
+        int last_range;
+        unsigned int digital_state;
+};
+
+#define devpriv ((struct adq12b_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int adq12b_attach(struct comedi_device *dev,struct comedi_devconfig *it);
+static int adq12b_detach(struct comedi_device *dev);
+static struct comedi_driver driver_adq12b={
+        driver_name:    "adq12b",
+        module:         THIS_MODULE,
+        attach:         adq12b_attach,
+        detach:         adq12b_detach,
+        board_name:     &adq12b_boards[0].name,
+        offset:         sizeof(struct adq12b_board),
+        num_names:      sizeof(adq12b_boards) / sizeof(struct adq12b_board),
+};
+
+static int adq12b_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data);
+static int adq12b_di_insn_bits(struct comedi_device *dev,struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data);
+static int adq12b_do_insn_bits(struct comedi_device *dev,struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data);
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board.  If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int adq12b_attach(struct comedi_device *dev,struct comedi_devconfig *it)
+{
+        struct comedi_subdevice *s;
+        unsigned long iobase;
+        int unipolar, differential;
+
+        iobase = it->options[0];
+        unipolar = it->options[1];
+        differential = it->options[2];
+
+        printk("comedi%d: adq12b called with options base=0x%03lx, %s and %s\n",dev->minor, iobase, (unipolar==1)?"unipolar":"bipolar", (differential==1)?"differential":"single-ended");
+
+        /* if no address was specified, try the default 0x300 */
+        if (iobase == 0) {
+          printk("comedi%d: adq12b warning: I/O base address not specified. Trying the default 0x300.\n", dev->minor);
+          iobase = 0x300;
+        }
+
+        printk("comedi%d: adq12b: 0x%04lx ", dev->minor, iobase);
+        if (!request_region(iobase, ADQ12B_SIZE, "adq12b")) {
+          printk("I/O port conflict\n");
+          return -EIO;
+        }
+        dev->iobase = iobase;
+
+/*
+ * Initialize dev->board_name.  Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+        dev->board_name = thisboard->name;
+
+/*
+ * Allocate the private structure area.  alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+        if(alloc_private(dev, sizeof(struct adq12b_private)) < 0)
+          return -ENOMEM;
+
+/* fill in devpriv structure */
+        devpriv->unipolar = unipolar;
+        devpriv->differential = differential;
+	devpriv->digital_state = 0;
+/* initialize channel and range to -1 so we make sure we always write
+   at least once to the CTREG in the instruction */
+        devpriv->last_channel = -1;
+        devpriv->last_range = -1;
+
+
+/*
+ * Allocate the subdevice structures.  alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+        if(alloc_subdevices(dev, 3)<0)
+           return -ENOMEM;
+
+        s = dev->subdevices+0;
+        /* analog input subdevice */
+        s->type = COMEDI_SUBD_AI;
+        if (differential) {
+          s->subdev_flags = SDF_READABLE|SDF_GROUND|SDF_DIFF;
+          s->n_chan = thisboard->ai_diff_chans;
+        } else {
+          s->subdev_flags = SDF_READABLE|SDF_GROUND;
+          s->n_chan = thisboard->ai_se_chans;
+        }
+
+        if (unipolar) {
+          s->range_table = &range_adq12b_ai_unipolar;
+        } else {
+          s->range_table = &range_adq12b_ai_bipolar;
+        }
+
+        s->maxdata = (1 << thisboard->ai_bits)-1;
+
+
+        s->len_chanlist = 4;  /* This is the maximum chanlist length that
+                                 the board can handle */
+        s->insn_read = adq12b_ai_rinsn;
+
+
+        s = dev->subdevices+1;
+        /* digital input subdevice */
+        s->type = COMEDI_SUBD_DI;
+        s->subdev_flags = SDF_READABLE;
+        s->n_chan=thisboard->di_chans;
+        s->maxdata = 1;
+        s->range_table = &range_digital;
+        s->insn_bits = adq12b_di_insn_bits;
+
+        s = dev->subdevices+2;
+        /* digital output subdevice */
+        s->type = COMEDI_SUBD_DO;
+        s->subdev_flags = SDF_WRITABLE;
+        s->n_chan = thisboard->do_chans;
+        s->maxdata = 1;
+        s->range_table = &range_digital;
+        s->insn_bits = adq12b_do_insn_bits;
+
+
+        printk("attached\n");
+
+        return 0;
+}
+
+
+/*
+ * _detach is called to deconfigure a device.  It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach().  dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int adq12b_detach(struct comedi_device *dev)
+{
+        if (dev->iobase)
+          release_region(dev->iobase, ADQ12B_SIZE);
+
+        kfree(devpriv);
+
+        printk("comedi%d: adq12b: removed\n",dev->minor);
+
+        return 0;
+}
+
+/*
+ * "instructions" read/write data in "one-shot" or "software-triggered"
+ * mode.
+ */
+
+static int adq12b_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)
+{
+        int n, i;
+        int range, channel;
+        unsigned char hi, lo, status;
+
+        /* change channel and range only if it is different from the previous */
+        range = CR_RANGE(insn->chanspec);
+        channel = CR_CHAN(insn->chanspec);
+        if (channel != devpriv->last_channel || range != devpriv->last_range) {
+          outb((range << 4) | channel, dev->iobase + ADQ12B_CTREG);
+          comedi_udelay(50);   /* wait for the mux to settle */
+        }
+
+        /* trigger conversion */
+        status = inb(dev->iobase + ADQ12B_ADLOW);
+
+        /* convert n samples */
+        for(n=0; n < insn->n; n++){
+
+          /* wait for end of convertion */
+	  i = 0;
+          do {
+//            comedi_udelay(1);
+	    status = inb(dev->iobase + ADQ12B_STINR);
+            status = status & ADQ12B_EOC;
+          } while (status == 0 && ++i < TIMEOUT);
+//          } while (++i < 10);
+
+          /* read data */
+          hi = inb(dev->iobase + ADQ12B_ADHIG);
+          lo = inb(dev->iobase + ADQ12B_ADLOW);
+
+          //rt_printk("debug: chan=%d range=%d status=%d hi=%d lo=%d\n", channel, range, status,  hi, lo);
+          data[n] = (hi << 8) | lo;
+
+        }
+
+        /* return the number of samples read/written */
+        return n;
+}
+
+
+static int adq12b_di_insn_bits(struct comedi_device *dev,struct comedi_subdevice *s, 	struct comedi_insn *insn,unsigned int *data)
+{
+
+        /* only bits 0-4 have information about digital inputs */
+        data[1] = (inb(dev->iobase+ADQ12B_STINR) & (0x1f));
+
+        return 2;
+}
+
+
+static int adq12b_do_insn_bits(struct comedi_device *dev,struct comedi_subdevice *s, 	struct comedi_insn *insn,unsigned int *data)
+{
+        int channel;
+
+	for (channel = 0; channel < 8; channel++)
+	  if (((data[0]>>channel) & 0x01) != 0)
+            outb((((data[1]>>channel)&0x01)<<3) | channel, dev->iobase + ADQ12B_OUTBR);
+
+        /* store information to retrieve when asked for reading */
+        if (data[0]) {
+          devpriv->digital_state &= ~data[0];
+          devpriv->digital_state |= (data[0]&data[1]);
+        }
+
+        data[1] = devpriv->digital_state;
+
+        return 2;
+}
+
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver_adq12b);
diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c
new file mode 100644
index 0000000..29eac74
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adv_pci1710.c
@@ -0,0 +1,1568 @@
+/*
+ * comedi/drivers/adv_pci1710.c
+ *
+ * Author: Michal Dobes <dobes@tesnet.cz>
+ *
+ * Thanks to ZhenGang Shang <ZhenGang.Shang@Advantech.com.cn>
+ * for testing and informations.
+ *
+ *  hardware driver for Advantech cards:
+ *   card:   PCI-1710, PCI-1710HG, PCI-1711, PCI-1713, PCI-1720, PCI-1731
+ *   driver: pci1710,  pci1710hg,  pci1711,  pci1713,  pci1720,  pci1731
+ *
+ * Options:
+ *  [0] - PCI bus number - if bus number and slot number are 0,
+ *                         then driver search for first unused card
+ *  [1] - PCI slot number
+ *
+*/
+/*
+Driver: adv_pci1710
+Description: Advantech PCI-1710, PCI-1710HG, PCI-1711, PCI-1713,
+             Advantech PCI-1720, PCI-1731
+Author: Michal Dobes <dobes@tesnet.cz>
+Devices: [Advantech] PCI-1710 (adv_pci1710), PCI-1710HG (pci1710hg),
+  PCI-1711 (adv_pci1710), PCI-1713, PCI-1720,
+  PCI-1731
+Status: works
+
+This driver supports AI, AO, DI and DO subdevices.
+AI subdevice supports cmd and insn interface,
+other subdevices support only insn interface.
+
+The PCI-1710 and PCI-1710HG have the same PCI device ID, so the
+driver cannot distinguish between them, as would be normal for a
+PCI driver.
+
+Configuration options:
+  [0] - PCI bus of device (optional)
+  [1] - PCI slot of device (optional)
+          If bus/slot is not specified, the first available PCI
+          device will be used.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+#include "8253.h"
+#include "amcc_s5933.h"
+
+#define PCI171x_PARANOIDCHECK	/* if defined, then is used code which control correct channel number on every 12 bit sample */
+
+#undef PCI171X_EXTDEBUG
+
+#define DRV_NAME "adv_pci1710"
+
+#undef DPRINTK
+#ifdef PCI171X_EXTDEBUG
+#define DPRINTK(fmt, args...) rt_printk(fmt, ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+// hardware types of the cards
+#define TYPE_PCI171X	0
+#define TYPE_PCI1713	2
+#define TYPE_PCI1720	3
+
+#define IORANGE_171x 	32
+#define IORANGE_1720 	16
+
+#define PCI171x_AD_DATA	 0	/* R:   A/D data */
+#define PCI171x_SOFTTRG	 0	/* W:   soft trigger for A/D */
+#define PCI171x_RANGE	 2	/* W:   A/D gain/range register */
+#define PCI171x_MUX	 4	/* W:   A/D multiplexor control */
+#define PCI171x_STATUS	 6	/* R:   status register */
+#define PCI171x_CONTROL	 6	/* W:   control register */
+#define PCI171x_CLRINT	 8	/* W:   clear interrupts request */
+#define PCI171x_CLRFIFO	 9	/* W:   clear FIFO */
+#define PCI171x_DA1	10	/* W:   D/A register */
+#define PCI171x_DA2	12	/* W:   D/A register */
+#define PCI171x_DAREF	14	/* W:   D/A reference control */
+#define PCI171x_DI	16	/* R:   digi inputs */
+#define PCI171x_DO	16	/* R:   digi inputs */
+#define PCI171x_CNT0	24	/* R/W: 8254 couter 0 */
+#define PCI171x_CNT1	26	/* R/W: 8254 couter 1 */
+#define PCI171x_CNT2	28	/* R/W: 8254 couter 2 */
+#define PCI171x_CNTCTRL	30	/* W:   8254 counter control */
+
+// upper bits from status register (PCI171x_STATUS) (lower is same woth control reg)
+#define	Status_FE	0x0100	/* 1=FIFO is empty */
+#define Status_FH	0x0200	/* 1=FIFO is half full */
+#define Status_FF	0x0400	/* 1=FIFO is full, fatal error */
+#define Status_IRQ	0x0800	/* 1=IRQ occured */
+// bits from control register (PCI171x_CONTROL)
+#define Control_CNT0	0x0040	/* 1=CNT0 have external source, 0=have internal 100kHz source */
+#define Control_ONEFH	0x0020	/* 1=IRQ on FIFO is half full, 0=every sample */
+#define Control_IRQEN	0x0010	/* 1=enable IRQ */
+#define Control_GATE	0x0008	/* 1=enable external trigger GATE (8254?) */
+#define Control_EXT	0x0004	/* 1=external trigger source */
+#define Control_PACER	0x0002	/* 1=enable internal 8254 trigger source */
+#define Control_SW	0x0001	/* 1=enable software trigger source */
+// bits from counter control register (PCI171x_CNTCTRL)
+#define Counter_BCD     0x0001	/* 0 = binary counter, 1 = BCD counter */
+#define Counter_M0      0x0002	/* M0-M2 select modes 0-5 */
+#define Counter_M1      0x0004	/* 000 = mode 0, 010 = mode 2 ... */
+#define Counter_M2      0x0008
+#define Counter_RW0     0x0010	/* RW0/RW1 select read/write mode */
+#define Counter_RW1     0x0020
+#define Counter_SC0     0x0040	/* Select Counter. Only 00 or 11 may */
+#define Counter_SC1     0x0080	/* be used, 00 for CNT0, 11 for read-back command */
+
+#define PCI1720_DA0	 0	/* W:   D/A register 0 */
+#define PCI1720_DA1	 2	/* W:   D/A register 1 */
+#define PCI1720_DA2	 4	/* W:   D/A register 2 */
+#define PCI1720_DA3	 6	/* W:   D/A register 3 */
+#define PCI1720_RANGE	 8	/* R/W: D/A range register */
+#define PCI1720_SYNCOUT	 9	/* W:   D/A synchronized output register */
+#define PCI1720_SYNCONT	15	/* R/W: D/A synchronized control */
+
+// D/A synchronized control (PCI1720_SYNCONT)
+#define Syncont_SC0	 1	/* set synchronous output mode */
+
+static const struct comedi_lrange range_pci1710_3 = { 9, {
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+			BIP_RANGE(0.625),
+			BIP_RANGE(10),
+			UNI_RANGE(10),
+			UNI_RANGE(5),
+			UNI_RANGE(2.5),
+			UNI_RANGE(1.25)
+	}
+};
+
+static const char range_codes_pci1710_3[] =
+	{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x10, 0x11, 0x12, 0x13 };
+
+static const struct comedi_lrange range_pci1710hg = { 12, {
+			BIP_RANGE(5),
+			BIP_RANGE(0.5),
+			BIP_RANGE(0.05),
+			BIP_RANGE(0.005),
+			BIP_RANGE(10),
+			BIP_RANGE(1),
+			BIP_RANGE(0.1),
+			BIP_RANGE(0.01),
+			UNI_RANGE(10),
+			UNI_RANGE(1),
+			UNI_RANGE(0.1),
+			UNI_RANGE(0.01)
+	}
+};
+
+static const char range_codes_pci1710hg[] =
+	{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12,
+		0x13 };
+
+static const struct comedi_lrange range_pci17x1 = { 5, {
+			BIP_RANGE(10),
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+			BIP_RANGE(0.625)
+	}
+};
+
+static const char range_codes_pci17x1[] = { 0x00, 0x01, 0x02, 0x03, 0x04 };
+
+static const struct comedi_lrange range_pci1720 = { 4, {
+			UNI_RANGE(5),
+			UNI_RANGE(10),
+			BIP_RANGE(5),
+			BIP_RANGE(10)
+	}
+};
+
+static const struct comedi_lrange range_pci171x_da = { 2, {
+			UNI_RANGE(5),
+			UNI_RANGE(10),
+	}
+};
+
+static int pci1710_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci1710_detach(struct comedi_device * dev);
+
+struct boardtype {
+	const char *name;	// board name
+	int device_id;
+	int iorange;		// I/O range len
+	char have_irq;		// 1=card support IRQ
+	char cardtype;		// 0=1710& co. 2=1713, ...
+	int n_aichan;		// num of A/D chans
+	int n_aichand;		// num of A/D chans in diff mode
+	int n_aochan;		// num of D/A chans
+	int n_dichan;		// num of DI chans
+	int n_dochan;		// num of DO chans
+	int n_counter;		// num of counters
+	int ai_maxdata;		// resolution of A/D
+	int ao_maxdata;		// resolution of D/A
+	const struct comedi_lrange *rangelist_ai;	// rangelist for A/D
+	const char *rangecode_ai;	// range codes for programming
+	const struct comedi_lrange *rangelist_ao;	// rangelist for D/A
+	unsigned int ai_ns_min;	// max sample speed of card v ns
+	unsigned int fifo_half_size;	// size of FIFO/2
+};
+
+static DEFINE_PCI_DEVICE_TABLE(pci1710_pci_table) = {
+	{PCI_VENDOR_ID_ADVANTECH, 0x1710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_ADVANTECH, 0x1711, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_ADVANTECH, 0x1713, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_ADVANTECH, 0x1720, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_ADVANTECH, 0x1731, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci1710_pci_table);
+
+static const struct boardtype boardtypes[] = {
+	{"pci1710", 0x1710,
+		IORANGE_171x, 1, TYPE_PCI171X,
+		16, 8, 2, 16, 16, 1, 0x0fff, 0x0fff,
+		&range_pci1710_3, range_codes_pci1710_3,
+		&range_pci171x_da,
+		10000, 2048},
+	{"pci1710hg", 0x1710,
+		IORANGE_171x, 1, TYPE_PCI171X,
+		16, 8, 2, 16, 16, 1, 0x0fff, 0x0fff,
+		&range_pci1710hg, range_codes_pci1710hg,
+		&range_pci171x_da,
+		10000, 2048},
+	{"pci1711", 0x1711,
+		IORANGE_171x, 1, TYPE_PCI171X,
+		16, 0, 2, 16, 16, 1, 0x0fff, 0x0fff,
+		&range_pci17x1, range_codes_pci17x1, &range_pci171x_da,
+		10000, 512},
+	{"pci1713", 0x1713,
+		IORANGE_171x, 1, TYPE_PCI1713,
+		32, 16, 0, 0, 0, 0, 0x0fff, 0x0000,
+		&range_pci1710_3, range_codes_pci1710_3, NULL,
+		10000, 2048},
+	{"pci1720", 0x1720,
+		IORANGE_1720, 0, TYPE_PCI1720,
+		0, 0, 4, 0, 0, 0, 0x0000, 0x0fff,
+		NULL, NULL, &range_pci1720,
+		0, 0},
+	{"pci1731", 0x1731,
+		IORANGE_171x, 1, TYPE_PCI171X,
+		16, 0, 0, 16, 16, 0, 0x0fff, 0x0000,
+		&range_pci17x1, range_codes_pci17x1, NULL,
+		10000, 512},
+	// dummy entry corresponding to driver name
+	{.name = DRV_NAME},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype))
+
+static struct comedi_driver driver_pci1710 = {
+	.driver_name = DRV_NAME,
+	.module = THIS_MODULE,
+	.attach = pci1710_attach,
+	.detach = pci1710_detach,
+	.num_names = n_boardtypes,
+	.board_name = &boardtypes[0].name,
+	.offset = sizeof(struct boardtype),
+};
+
+struct pci1710_private {
+	struct pci_dev *pcidev;	// ptr to PCI device
+	char valid;		// card is usable
+	char neverending_ai;	// we do unlimited AI
+	unsigned int CntrlReg;	// Control register
+	unsigned int i8254_osc_base;	// frequence of onboard oscilator
+	unsigned int ai_do;	// what do AI? 0=nothing, 1 to 4 mode
+	unsigned int ai_act_scan;	// how many scans we finished
+	unsigned int ai_act_chan;	// actual position in actual scan
+	unsigned int ai_buf_ptr;	// data buffer ptr in samples
+	unsigned char ai_eos;	// 1=EOS wake up
+	unsigned char ai_et;
+	unsigned int ai_et_CntrlReg;
+	unsigned int ai_et_MuxVal;
+	unsigned int ai_et_div1, ai_et_div2;
+	unsigned int act_chanlist[32];	// list of scaned channel
+	unsigned char act_chanlist_len;	// len of scanlist
+	unsigned char act_chanlist_pos;	// actual position in MUX list
+	unsigned char da_ranges;	// copy of D/A outpit range register
+	unsigned int ai_scans;	// len of scanlist
+	unsigned int ai_n_chan;	// how many channels is measured
+	unsigned int *ai_chanlist;	// actaul chanlist
+	unsigned int ai_flags;	// flaglist
+	unsigned int ai_data_len;	// len of data buffer
+	short *ai_data;	// data buffer
+	unsigned int ai_timer1;	// timers
+	unsigned int ai_timer2;
+	short ao_data[4];	// data output buffer
+	unsigned int cnt0_write_wait;	// after a write, wait for update of the internal state
+};
+
+#define devpriv ((struct pci1710_private *)dev->private)
+#define this_board ((const struct boardtype *)dev->board_ptr)
+
+/*
+==============================================================================
+*/
+
+static int check_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int *chanlist, unsigned int n_chan);
+static void setup_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int *chanlist, unsigned int n_chan, unsigned int seglen);
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+	unsigned int divisor2);
+static int pci1710_reset(struct comedi_device * dev);
+static int pci171x_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static const unsigned int muxonechan[] = { 0x0000, 0x0101, 0x0202, 0x0303, 0x0404, 0x0505, 0x0606, 0x0707,	// used for gain list programming
+	0x0808, 0x0909, 0x0a0a, 0x0b0b, 0x0c0c, 0x0d0d, 0x0e0e, 0x0f0f,
+	0x1010, 0x1111, 0x1212, 0x1313, 0x1414, 0x1515, 0x1616, 0x1717,
+	0x1818, 0x1919, 0x1a1a, 0x1b1b, 0x1c1c, 0x1d1d, 0x1e1e, 0x1f1f
+};
+
+/*
+==============================================================================
+*/
+static int pci171x_insn_read_ai(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n, timeout;
+#ifdef PCI171x_PARANOIDCHECK
+	unsigned int idata;
+#endif
+
+	DPRINTK("adv_pci1710 EDBG: BGN: pci171x_insn_read_ai(...)\n");
+	devpriv->CntrlReg &= Control_CNT0;
+	devpriv->CntrlReg |= Control_SW;	// set software trigger
+	outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
+	outb(0, dev->iobase + PCI171x_CLRFIFO);
+	outb(0, dev->iobase + PCI171x_CLRINT);
+
+	setup_channel_list(dev, s, &insn->chanspec, 1, 1);
+
+	DPRINTK("adv_pci1710 A ST=%4x IO=%x\n",
+		inw(dev->iobase + PCI171x_STATUS),
+		dev->iobase + PCI171x_STATUS);
+	for (n = 0; n < insn->n; n++) {
+		outw(0, dev->iobase + PCI171x_SOFTTRG);	/* start conversion */
+		DPRINTK("adv_pci1710 B n=%d ST=%4x\n", n,
+			inw(dev->iobase + PCI171x_STATUS));
+		//comedi_udelay(1);
+		DPRINTK("adv_pci1710 C n=%d ST=%4x\n", n,
+			inw(dev->iobase + PCI171x_STATUS));
+		timeout = 100;
+		while (timeout--) {
+			if (!(inw(dev->iobase + PCI171x_STATUS) & Status_FE))
+				goto conv_finish;
+			if (!(timeout % 10))
+				DPRINTK("adv_pci1710 D n=%d tm=%d ST=%4x\n", n,
+					timeout,
+					inw(dev->iobase + PCI171x_STATUS));
+		}
+		comedi_error(dev, "A/D insn timeout");
+		outb(0, dev->iobase + PCI171x_CLRFIFO);
+		outb(0, dev->iobase + PCI171x_CLRINT);
+		data[n] = 0;
+		DPRINTK("adv_pci1710 EDBG: END: pci171x_insn_read_ai(...) n=%d\n", n);
+		return -ETIME;
+
+	      conv_finish:
+#ifdef PCI171x_PARANOIDCHECK
+		idata = inw(dev->iobase + PCI171x_AD_DATA);
+		if (this_board->cardtype != TYPE_PCI1713)
+			if ((idata & 0xf000) != devpriv->act_chanlist[0]) {
+				comedi_error(dev, "A/D insn data droput!");
+				return -ETIME;
+			}
+		data[n] = idata & 0x0fff;
+#else
+		data[n] = inw(dev->iobase + PCI171x_AD_DATA) & 0x0fff;
+#endif
+
+	}
+
+	outb(0, dev->iobase + PCI171x_CLRFIFO);
+	outb(0, dev->iobase + PCI171x_CLRINT);
+
+	DPRINTK("adv_pci1710 EDBG: END: pci171x_insn_read_ai(...) n=%d\n", n);
+	return n;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_insn_write_ao(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n, chan, range, ofs;
+
+	chan = CR_CHAN(insn->chanspec);
+	range = CR_RANGE(insn->chanspec);
+	if (chan) {
+		devpriv->da_ranges &= 0xfb;
+		devpriv->da_ranges |= (range << 2);
+		outw(devpriv->da_ranges, dev->iobase + PCI171x_DAREF);
+		ofs = PCI171x_DA2;
+	} else {
+		devpriv->da_ranges &= 0xfe;
+		devpriv->da_ranges |= range;
+		outw(devpriv->da_ranges, dev->iobase + PCI171x_DAREF);
+		ofs = PCI171x_DA1;
+	}
+
+	for (n = 0; n < insn->n; n++)
+		outw(data[n], dev->iobase + ofs);
+
+	devpriv->ao_data[chan] = data[n];
+
+	return n;
+
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_insn_read_ao(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n, chan;
+
+	chan = CR_CHAN(insn->chanspec);
+	for (n = 0; n < insn->n; n++)
+		data[n] = devpriv->ao_data[chan];
+
+	return n;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_insn_bits_di(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	data[1] = inw(dev->iobase + PCI171x_DI);
+
+	return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_insn_bits_do(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= (data[0] & data[1]);
+		outw(s->state, dev->iobase + PCI171x_DO);
+	}
+	data[1] = s->state;
+
+	return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_insn_counter_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int msb, lsb, ccntrl;
+	int i;
+
+	ccntrl = 0xD2;		/* count only */
+	for (i = 0; i < insn->n; i++) {
+		outw(ccntrl, dev->iobase + PCI171x_CNTCTRL);
+
+		lsb = inw(dev->iobase + PCI171x_CNT0) & 0xFF;
+		msb = inw(dev->iobase + PCI171x_CNT0) & 0xFF;
+
+		data[0] = lsb | (msb << 8);
+	}
+
+	return insn->n;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_insn_counter_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	uint msb, lsb, ccntrl, status;
+
+	lsb = data[0] & 0x00FF;
+	msb = (data[0] & 0xFF00) >> 8;
+
+	/* write lsb, then msb */
+	outw(lsb, dev->iobase + PCI171x_CNT0);
+	outw(msb, dev->iobase + PCI171x_CNT0);
+
+	if (devpriv->cnt0_write_wait) {
+		/* wait for the new count to be loaded */
+		ccntrl = 0xE2;
+		do {
+			outw(ccntrl, dev->iobase + PCI171x_CNTCTRL);
+			status = inw(dev->iobase + PCI171x_CNT0) & 0xFF;
+		} while (status & 0x40);
+	}
+
+	return insn->n;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_insn_counter_config(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+#ifdef unused
+	/* This doesn't work like a normal Comedi counter config */
+	uint ccntrl = 0;
+
+	devpriv->cnt0_write_wait = data[0] & 0x20;
+
+	/* internal or external clock? */
+	if (!(data[0] & 0x10)) {	/* internal */
+		devpriv->CntrlReg &= ~Control_CNT0;
+	} else {
+		devpriv->CntrlReg |= Control_CNT0;
+	}
+	outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
+
+	if (data[0] & 0x01)
+		ccntrl |= Counter_M0;
+	if (data[0] & 0x02)
+		ccntrl |= Counter_M1;
+	if (data[0] & 0x04)
+		ccntrl |= Counter_M2;
+	if (data[0] & 0x08)
+		ccntrl |= Counter_BCD;
+	ccntrl |= Counter_RW0;	/* set read/write mode */
+	ccntrl |= Counter_RW1;
+	outw(ccntrl, dev->iobase + PCI171x_CNTCTRL);
+#endif
+
+	return 1;
+}
+
+/*
+==============================================================================
+*/
+static int pci1720_insn_write_ao(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n, rangereg, chan;
+
+	chan = CR_CHAN(insn->chanspec);
+	rangereg = devpriv->da_ranges & (~(0x03 << (chan << 1)));
+	rangereg |= (CR_RANGE(insn->chanspec) << (chan << 1));
+	if (rangereg != devpriv->da_ranges) {
+		outb(rangereg, dev->iobase + PCI1720_RANGE);
+		devpriv->da_ranges = rangereg;
+	}
+
+	for (n = 0; n < insn->n; n++) {
+		outw(data[n], dev->iobase + PCI1720_DA0 + (chan << 1));
+		outb(0, dev->iobase + PCI1720_SYNCOUT);	// update outputs
+	}
+
+	devpriv->ao_data[chan] = data[n];
+
+	return n;
+}
+
+/*
+==============================================================================
+*/
+static void interrupt_pci1710_every_sample(void *d)
+{
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s = dev->subdevices + 0;
+	int m;
+#ifdef PCI171x_PARANOIDCHECK
+	short sampl;
+#endif
+
+	DPRINTK("adv_pci1710 EDBG: BGN: interrupt_pci1710_every_sample(...)\n");
+	m = inw(dev->iobase + PCI171x_STATUS);
+	if (m & Status_FE) {
+		rt_printk("comedi%d: A/D FIFO empty (%4x)\n", dev->minor, m);
+		pci171x_ai_cancel(dev, s);
+		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+		comedi_event(dev, s);
+		return;
+	}
+	if (m & Status_FF) {
+		rt_printk
+			("comedi%d: A/D FIFO Full status (Fatal Error!) (%4x)\n",
+			dev->minor, m);
+		pci171x_ai_cancel(dev, s);
+		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+		comedi_event(dev, s);
+		return;
+	}
+
+	outb(0, dev->iobase + PCI171x_CLRINT);	// clear our INT request
+
+	DPRINTK("FOR ");
+	for (; !(inw(dev->iobase + PCI171x_STATUS) & Status_FE);) {
+#ifdef PCI171x_PARANOIDCHECK
+		sampl = inw(dev->iobase + PCI171x_AD_DATA);
+		DPRINTK("%04x:", sampl);
+		if (this_board->cardtype != TYPE_PCI1713)
+			if ((sampl & 0xf000) !=
+				devpriv->act_chanlist[s->async->cur_chan]) {
+				rt_printk
+					("comedi: A/D data dropout: received data from channel %d, expected %d!\n",
+					(sampl & 0xf000) >> 12,
+					(devpriv->act_chanlist[s->async->
+							cur_chan] & 0xf000) >>
+					12);
+				pci171x_ai_cancel(dev, s);
+				s->async->events |=
+					COMEDI_CB_EOA | COMEDI_CB_ERROR;
+				comedi_event(dev, s);
+				return;
+			}
+		DPRINTK("%8d %2d %8d~", s->async->buf_int_ptr,
+			s->async->cur_chan, s->async->buf_int_count);
+		comedi_buf_put(s->async, sampl & 0x0fff);
+#else
+		comedi_buf_put(s->async,
+			inw(dev->iobase + PCI171x_AD_DATA) & 0x0fff);
+#endif
+		++s->async->cur_chan;
+
+		if (s->async->cur_chan >= devpriv->ai_n_chan) {
+			s->async->cur_chan = 0;
+		}
+
+		if (s->async->cur_chan == 0) {	// one scan done
+			devpriv->ai_act_scan++;
+			DPRINTK("adv_pci1710 EDBG: EOS1 bic %d bip %d buc %d bup %d\n", s->async->buf_int_count, s->async->buf_int_ptr, s->async->buf_user_count, s->async->buf_user_ptr);
+			DPRINTK("adv_pci1710 EDBG: EOS2\n");
+			if ((!devpriv->neverending_ai) && (devpriv->ai_act_scan >= devpriv->ai_scans)) {	// all data sampled
+				pci171x_ai_cancel(dev, s);
+				s->async->events |= COMEDI_CB_EOA;
+				comedi_event(dev, s);
+				return;
+			}
+		}
+	}
+
+	outb(0, dev->iobase + PCI171x_CLRINT);	// clear our INT request
+	DPRINTK("adv_pci1710 EDBG: END: interrupt_pci1710_every_sample(...)\n");
+
+	comedi_event(dev, s);
+}
+
+/*
+==============================================================================
+*/
+static int move_block_from_fifo(struct comedi_device * dev, struct comedi_subdevice * s,
+	int n, int turn)
+{
+	int i, j;
+#ifdef PCI171x_PARANOIDCHECK
+	int sampl;
+#endif
+	DPRINTK("adv_pci1710 EDBG: BGN: move_block_from_fifo(...,%d,%d)\n", n,
+		turn);
+	j = s->async->cur_chan;
+	for (i = 0; i < n; i++) {
+#ifdef PCI171x_PARANOIDCHECK
+		sampl = inw(dev->iobase + PCI171x_AD_DATA);
+		if (this_board->cardtype != TYPE_PCI1713)
+			if ((sampl & 0xf000) != devpriv->act_chanlist[j]) {
+				rt_printk
+					("comedi%d: A/D  FIFO data dropout: received data from channel %d, expected %d! (%d/%d/%d/%d/%d/%4x)\n",
+					dev->minor, (sampl & 0xf000) >> 12,
+					(devpriv->
+						act_chanlist[j] & 0xf000) >> 12,
+					i, j, devpriv->ai_act_scan, n, turn,
+					sampl);
+				pci171x_ai_cancel(dev, s);
+				s->async->events |=
+					COMEDI_CB_EOA | COMEDI_CB_ERROR;
+				comedi_event(dev, s);
+				return 1;
+			}
+		comedi_buf_put(s->async, sampl & 0x0fff);
+#else
+		comedi_buf_put(s->async,
+			inw(dev->iobase + PCI171x_AD_DATA) & 0x0fff);
+#endif
+		j++;
+		if (j >= devpriv->ai_n_chan) {
+			j = 0;
+			devpriv->ai_act_scan++;
+		}
+	}
+	DPRINTK("adv_pci1710 EDBG: END: move_block_from_fifo(...)\n");
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+static void interrupt_pci1710_half_fifo(void *d)
+{
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s = dev->subdevices + 0;
+	int m, samplesinbuf;
+
+	DPRINTK("adv_pci1710 EDBG: BGN: interrupt_pci1710_half_fifo(...)\n");
+	m = inw(dev->iobase + PCI171x_STATUS);
+	if (!(m & Status_FH)) {
+		rt_printk("comedi%d: A/D FIFO not half full! (%4x)\n",
+			dev->minor, m);
+		pci171x_ai_cancel(dev, s);
+		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+		comedi_event(dev, s);
+		return;
+	}
+	if (m & Status_FF) {
+		rt_printk
+			("comedi%d: A/D FIFO Full status (Fatal Error!) (%4x)\n",
+			dev->minor, m);
+		pci171x_ai_cancel(dev, s);
+		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+		comedi_event(dev, s);
+		return;
+	}
+
+	samplesinbuf = this_board->fifo_half_size;
+	if (samplesinbuf * sizeof(short) >= devpriv->ai_data_len) {
+		m = devpriv->ai_data_len / sizeof(short);
+		if (move_block_from_fifo(dev, s, m, 0))
+			return;
+		samplesinbuf -= m;
+	}
+
+	if (samplesinbuf) {
+		if (move_block_from_fifo(dev, s, samplesinbuf, 1))
+			return;
+	}
+
+	if (!devpriv->neverending_ai)
+		if (devpriv->ai_act_scan >= devpriv->ai_scans) {	/* all data sampled */
+			pci171x_ai_cancel(dev, s);
+			s->async->events |= COMEDI_CB_EOA;
+			comedi_event(dev, s);
+			return;
+		}
+	outb(0, dev->iobase + PCI171x_CLRINT);	// clear our INT request
+	DPRINTK("adv_pci1710 EDBG: END: interrupt_pci1710_half_fifo(...)\n");
+
+	comedi_event(dev, s);
+}
+
+/*
+==============================================================================
+*/
+static irqreturn_t interrupt_service_pci1710(int irq, void *d PT_REGS_ARG)
+{
+	struct comedi_device *dev = d;
+
+	DPRINTK("adv_pci1710 EDBG: BGN: interrupt_service_pci1710(%d,...)\n",
+		irq);
+	if (!dev->attached)	// is device attached?
+		return IRQ_NONE;	// no, exit
+
+	if (!(inw(dev->iobase + PCI171x_STATUS) & Status_IRQ))	// is this interrupt from our board?
+		return IRQ_NONE;	// no, exit
+
+	DPRINTK("adv_pci1710 EDBG: interrupt_service_pci1710() ST: %4x\n",
+		inw(dev->iobase + PCI171x_STATUS));
+
+	if (devpriv->ai_et) {	// Switch from initial TRIG_EXT to TRIG_xxx.
+		devpriv->ai_et = 0;
+		devpriv->CntrlReg &= Control_CNT0;
+		devpriv->CntrlReg |= Control_SW;	// set software trigger
+		outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
+		devpriv->CntrlReg = devpriv->ai_et_CntrlReg;
+		outb(0, dev->iobase + PCI171x_CLRFIFO);
+		outb(0, dev->iobase + PCI171x_CLRINT);
+		outw(devpriv->ai_et_MuxVal, dev->iobase + PCI171x_MUX);
+		outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
+		// start pacer
+		start_pacer(dev, 1, devpriv->ai_et_div1, devpriv->ai_et_div2);
+		return IRQ_HANDLED;
+	}
+	if (devpriv->ai_eos) {	// We use FIFO half full INT or not?
+		interrupt_pci1710_every_sample(d);
+	} else {
+		interrupt_pci1710_half_fifo(d);
+	}
+	DPRINTK("adv_pci1710 EDBG: END: interrupt_service_pci1710(...)\n");
+	return IRQ_HANDLED;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device * dev,
+	struct comedi_subdevice * s)
+{
+	unsigned int divisor1, divisor2;
+	unsigned int seglen;
+
+	DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_docmd_and_mode(%d,...)\n",
+		mode);
+	start_pacer(dev, -1, 0, 0);	// stop pacer
+
+	seglen = check_channel_list(dev, s, devpriv->ai_chanlist,
+		devpriv->ai_n_chan);
+	if (seglen < 1)
+		return -EINVAL;
+	setup_channel_list(dev, s, devpriv->ai_chanlist,
+		devpriv->ai_n_chan, seglen);
+
+	outb(0, dev->iobase + PCI171x_CLRFIFO);
+	outb(0, dev->iobase + PCI171x_CLRINT);
+
+	devpriv->ai_do = mode;
+
+	devpriv->ai_act_scan = 0;
+	s->async->cur_chan = 0;
+	devpriv->ai_buf_ptr = 0;
+	devpriv->neverending_ai = 0;
+
+	devpriv->CntrlReg &= Control_CNT0;
+	if ((devpriv->ai_flags & TRIG_WAKE_EOS)) {	// don't we want wake up every scan?            devpriv->ai_eos=1;
+		devpriv->ai_eos = 1;
+	} else {
+		devpriv->CntrlReg |= Control_ONEFH;
+		devpriv->ai_eos = 0;
+	}
+
+	if ((devpriv->ai_scans == 0) || (devpriv->ai_scans == -1)) {
+		devpriv->neverending_ai = 1;
+	}			//well, user want neverending
+	else {
+		devpriv->neverending_ai = 0;
+	}
+	switch (mode) {
+	case 1:
+	case 2:
+		if (devpriv->ai_timer1 < this_board->ai_ns_min)
+			devpriv->ai_timer1 = this_board->ai_ns_min;
+		devpriv->CntrlReg |= Control_PACER | Control_IRQEN;
+		if (mode == 2) {
+			devpriv->ai_et_CntrlReg = devpriv->CntrlReg;
+			devpriv->CntrlReg &=
+				~(Control_PACER | Control_ONEFH | Control_GATE);
+			devpriv->CntrlReg |= Control_EXT;
+			devpriv->ai_et = 1;
+		} else {
+			devpriv->ai_et = 0;
+		}
+		i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
+			&divisor2, &devpriv->ai_timer1,
+			devpriv->ai_flags & TRIG_ROUND_MASK);
+		DPRINTK("adv_pci1710 EDBG: OSC base=%u div1=%u div2=%u timer=%u\n", devpriv->i8254_osc_base, divisor1, divisor2, devpriv->ai_timer1);
+		outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
+		if (mode != 2) {
+			// start pacer
+			start_pacer(dev, mode, divisor1, divisor2);
+		} else {
+			devpriv->ai_et_div1 = divisor1;
+			devpriv->ai_et_div2 = divisor2;
+		}
+		break;
+	case 3:
+		devpriv->CntrlReg |= Control_EXT | Control_IRQEN;
+		outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
+		break;
+	}
+
+	DPRINTK("adv_pci1710 EDBG: END: pci171x_ai_docmd_and_mode(...)\n");
+	return 0;
+}
+
+#ifdef PCI171X_EXTDEBUG
+/*
+==============================================================================
+*/
+static void pci171x_cmdtest_out(int e, struct comedi_cmd * cmd)
+{
+	rt_printk("adv_pci1710 e=%d startsrc=%x scansrc=%x convsrc=%x\n", e,
+		cmd->start_src, cmd->scan_begin_src, cmd->convert_src);
+	rt_printk("adv_pci1710 e=%d startarg=%d scanarg=%d convarg=%d\n", e,
+		cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg);
+	rt_printk("adv_pci1710 e=%d stopsrc=%x scanend=%x\n", e, cmd->stop_src,
+		cmd->scan_end_src);
+	rt_printk("adv_pci1710 e=%d stoparg=%d scanendarg=%d chanlistlen=%d\n",
+		e, cmd->stop_arg, cmd->scan_end_arg, cmd->chanlist_len);
+}
+#endif
+
+/*
+==============================================================================
+*/
+static int pci171x_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp, divisor1, divisor2;
+
+	DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...)\n");
+#ifdef PCI171X_EXTDEBUG
+	pci171x_cmdtest_out(-1, cmd);
+#endif
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW | TRIG_EXT;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_FOLLOW;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err) {
+#ifdef PCI171X_EXTDEBUG
+		pci171x_cmdtest_out(1, cmd);
+#endif
+		DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=1\n", err);
+		return 1;
+	}
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) {
+		cmd->start_src = TRIG_NOW;
+		err++;
+	}
+
+	if (cmd->scan_begin_src != TRIG_FOLLOW) {
+		cmd->scan_begin_src = TRIG_FOLLOW;
+		err++;
+	}
+
+	if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+		err++;
+
+	if (cmd->scan_end_src != TRIG_COUNT) {
+		cmd->scan_end_src = TRIG_COUNT;
+		err++;
+	}
+
+	if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
+		err++;
+
+	if (err) {
+#ifdef PCI171X_EXTDEBUG
+		pci171x_cmdtest_out(2, cmd);
+#endif
+		DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=2\n", err);
+		return 2;
+	}
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+
+	if (cmd->scan_begin_arg != 0) {
+		cmd->scan_begin_arg = 0;
+		err++;
+	}
+
+	if (cmd->convert_src == TRIG_TIMER) {
+		if (cmd->convert_arg < this_board->ai_ns_min) {
+			cmd->convert_arg = this_board->ai_ns_min;
+			err++;
+		}
+	} else {		/* TRIG_FOLLOW */
+		if (cmd->convert_arg != 0) {
+			cmd->convert_arg = 0;
+			err++;
+		}
+	}
+
+	if (!cmd->chanlist_len) {
+		cmd->chanlist_len = 1;
+		err++;
+	}
+	if (cmd->chanlist_len > this_board->n_aichan) {
+		cmd->chanlist_len = this_board->n_aichan;
+		err++;
+	}
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+	if (cmd->stop_src == TRIG_COUNT) {
+		if (!cmd->stop_arg) {
+			cmd->stop_arg = 1;
+			err++;
+		}
+	} else {		/* TRIG_NONE */
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (err) {
+#ifdef PCI171X_EXTDEBUG
+		pci171x_cmdtest_out(3, cmd);
+#endif
+		DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=3\n", err);
+		return 3;
+	}
+
+	/* step 4: fix up any arguments */
+
+	if (cmd->convert_src == TRIG_TIMER) {
+		tmp = cmd->convert_arg;
+		i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
+			&divisor2, &cmd->convert_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+		if (cmd->convert_arg < this_board->ai_ns_min)
+			cmd->convert_arg = this_board->ai_ns_min;
+		if (tmp != cmd->convert_arg)
+			err++;
+	}
+
+	if (err) {
+		DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=4\n", err);
+		return 4;
+	}
+
+	/* step 5: complain about special chanlist considerations */
+
+	if (cmd->chanlist) {
+		if (!check_channel_list(dev, s, cmd->chanlist,
+				cmd->chanlist_len))
+			return 5;	// incorrect channels list
+	}
+
+	DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) ret=0\n");
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_cmd *cmd = &s->async->cmd;
+
+	DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmd(...)\n");
+	devpriv->ai_n_chan = cmd->chanlist_len;
+	devpriv->ai_chanlist = cmd->chanlist;
+	devpriv->ai_flags = cmd->flags;
+	devpriv->ai_data_len = s->async->prealloc_bufsz;
+	devpriv->ai_data = s->async->prealloc_buf;
+	devpriv->ai_timer1 = 0;
+	devpriv->ai_timer2 = 0;
+
+	if (cmd->stop_src == TRIG_COUNT) {
+		devpriv->ai_scans = cmd->stop_arg;
+	} else {
+		devpriv->ai_scans = 0;
+	}
+
+	if (cmd->scan_begin_src == TRIG_FOLLOW) {	// mode 1, 2, 3
+		if (cmd->convert_src == TRIG_TIMER) {	// mode 1 and 2
+			devpriv->ai_timer1 = cmd->convert_arg;
+			return pci171x_ai_docmd_and_mode(cmd->start_src ==
+				TRIG_EXT ? 2 : 1, dev, s);
+		}
+		if (cmd->convert_src == TRIG_EXT) {	// mode 3
+			return pci171x_ai_docmd_and_mode(3, dev, s);
+		}
+	}
+
+	return -1;
+}
+
+/*
+==============================================================================
+ Check if channel list from user is builded correctly
+ If it's ok, then program scan/gain logic.
+ This works for all cards.
+*/
+static int check_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int *chanlist, unsigned int n_chan)
+{
+	unsigned int chansegment[32];
+	unsigned int i, nowmustbechan, seglen, segpos;
+
+	DPRINTK("adv_pci1710 EDBG:  check_channel_list(...,%d)\n", n_chan);
+	/* correct channel and range number check itself comedi/range.c */
+	if (n_chan < 1) {
+		comedi_error(dev, "range/channel list is empty!");
+		return 0;
+	}
+
+	if (n_chan > 1) {
+		chansegment[0] = chanlist[0];	// first channel is everytime ok
+		for (i = 1, seglen = 1; i < n_chan; i++, seglen++) {	// build part of chanlist
+			// rt_printk("%d. %d %d\n",i,CR_CHAN(chanlist[i]),CR_RANGE(chanlist[i]));
+			if (chanlist[0] == chanlist[i])
+				break;	// we detect loop, this must by finish
+			if (CR_CHAN(chanlist[i]) & 1)	// odd channel cann't by differencial
+				if (CR_AREF(chanlist[i]) == AREF_DIFF) {
+					comedi_error(dev,
+						"Odd channel can't be differential input!\n");
+					return 0;
+				}
+			nowmustbechan =
+				(CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan;
+			if (CR_AREF(chansegment[i - 1]) == AREF_DIFF)
+				nowmustbechan = (nowmustbechan + 1) % s->n_chan;
+			if (nowmustbechan != CR_CHAN(chanlist[i])) {	// channel list isn't continous :-(
+				rt_printk
+					("channel list must be continous! chanlist[%i]=%d but must be %d or %d!\n",
+					i, CR_CHAN(chanlist[i]), nowmustbechan,
+					CR_CHAN(chanlist[0]));
+				return 0;
+			}
+			chansegment[i] = chanlist[i];	// well, this is next correct channel in list
+		}
+
+		for (i = 0, segpos = 0; i < n_chan; i++) {	// check whole chanlist
+			//rt_printk("%d %d=%d %d\n",CR_CHAN(chansegment[i%seglen]),CR_RANGE(chansegment[i%seglen]),CR_CHAN(chanlist[i]),CR_RANGE(chanlist[i]));
+			if (chanlist[i] != chansegment[i % seglen]) {
+				rt_printk
+					("bad channel, reference or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
+					i, CR_CHAN(chansegment[i]),
+					CR_RANGE(chansegment[i]),
+					CR_AREF(chansegment[i]),
+					CR_CHAN(chanlist[i % seglen]),
+					CR_RANGE(chanlist[i % seglen]),
+					CR_AREF(chansegment[i % seglen]));
+				return 0;	// chan/gain list is strange
+			}
+		}
+	} else {
+		seglen = 1;
+	}
+	return seglen;
+}
+
+static void setup_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int *chanlist, unsigned int n_chan, unsigned int seglen)
+{
+	unsigned int i, range, chanprog;
+
+	DPRINTK("adv_pci1710 EDBG:  setup_channel_list(...,%d,%d)\n", n_chan,
+		seglen);
+	devpriv->act_chanlist_len = seglen;
+	devpriv->act_chanlist_pos = 0;
+
+	DPRINTK("SegLen: %d\n", seglen);
+	for (i = 0; i < seglen; i++) {	// store range list to card
+		chanprog = muxonechan[CR_CHAN(chanlist[i])];
+		outw(chanprog, dev->iobase + PCI171x_MUX);	/* select channel */
+		range = this_board->rangecode_ai[CR_RANGE(chanlist[i])];
+		if (CR_AREF(chanlist[i]) == AREF_DIFF)
+			range |= 0x0020;
+		outw(range, dev->iobase + PCI171x_RANGE);	/* select gain */
+#ifdef PCI171x_PARANOIDCHECK
+		devpriv->act_chanlist[i] =
+			(CR_CHAN(chanlist[i]) << 12) & 0xf000;
+#endif
+		DPRINTK("GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range,
+			devpriv->act_chanlist[i]);
+	}
+
+	devpriv->ai_et_MuxVal =
+		CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8);
+	outw(devpriv->ai_et_MuxVal, dev->iobase + PCI171x_MUX);	/* select channel interval to scan */
+	DPRINTK("MUX: %4x L%4x.H%4x\n",
+		CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8),
+		CR_CHAN(chanlist[0]), CR_CHAN(chanlist[seglen - 1]));
+}
+
+/*
+==============================================================================
+*/
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+	unsigned int divisor2)
+{
+	DPRINTK("adv_pci1710 EDBG: BGN: start_pacer(%d,%u,%u)\n", mode,
+		divisor1, divisor2);
+	outw(0xb4, dev->iobase + PCI171x_CNTCTRL);
+	outw(0x74, dev->iobase + PCI171x_CNTCTRL);
+
+	if (mode == 1) {
+		outw(divisor2 & 0xff, dev->iobase + PCI171x_CNT2);
+		outw((divisor2 >> 8) & 0xff, dev->iobase + PCI171x_CNT2);
+		outw(divisor1 & 0xff, dev->iobase + PCI171x_CNT1);
+		outw((divisor1 >> 8) & 0xff, dev->iobase + PCI171x_CNT1);
+	}
+	DPRINTK("adv_pci1710 EDBG: END: start_pacer(...)\n");
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cancel(...)\n");
+
+	switch (this_board->cardtype) {
+	default:
+		devpriv->CntrlReg &= Control_CNT0;
+		devpriv->CntrlReg |= Control_SW;
+
+		outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);	// reset any operations
+		start_pacer(dev, -1, 0, 0);
+		outb(0, dev->iobase + PCI171x_CLRFIFO);
+		outb(0, dev->iobase + PCI171x_CLRINT);
+		break;
+	}
+
+	devpriv->ai_do = 0;
+	devpriv->ai_act_scan = 0;
+	s->async->cur_chan = 0;
+	devpriv->ai_buf_ptr = 0;
+	devpriv->neverending_ai = 0;
+
+	DPRINTK("adv_pci1710 EDBG: END: pci171x_ai_cancel(...)\n");
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_reset(struct comedi_device * dev)
+{
+	DPRINTK("adv_pci1710 EDBG: BGN: pci171x_reset(...)\n");
+	outw(0x30, dev->iobase + PCI171x_CNTCTRL);
+	devpriv->CntrlReg = Control_SW | Control_CNT0;	// Software trigger, CNT0=external
+	outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);	// reset any operations
+	outb(0, dev->iobase + PCI171x_CLRFIFO);	// clear FIFO
+	outb(0, dev->iobase + PCI171x_CLRINT);	// clear INT request
+	start_pacer(dev, -1, 0, 0);	// stop 8254
+	devpriv->da_ranges = 0;
+	if (this_board->n_aochan) {
+		outb(devpriv->da_ranges, dev->iobase + PCI171x_DAREF);	// set DACs to 0..5V
+		outw(0, dev->iobase + PCI171x_DA1);	// set DA outputs to 0V
+		devpriv->ao_data[0] = 0x0000;
+		if (this_board->n_aochan > 1) {
+			outw(0, dev->iobase + PCI171x_DA2);
+			devpriv->ao_data[1] = 0x0000;
+		}
+	}
+	outw(0, dev->iobase + PCI171x_DO);	// digital outputs to 0
+	outb(0, dev->iobase + PCI171x_CLRFIFO);	// clear FIFO
+	outb(0, dev->iobase + PCI171x_CLRINT);	// clear INT request
+
+	DPRINTK("adv_pci1710 EDBG: END: pci171x_reset(...)\n");
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci1720_reset(struct comedi_device * dev)
+{
+	DPRINTK("adv_pci1710 EDBG: BGN: pci1720_reset(...)\n");
+	outb(Syncont_SC0, dev->iobase + PCI1720_SYNCONT);	// set synchronous output mode
+	devpriv->da_ranges = 0xAA;
+	outb(devpriv->da_ranges, dev->iobase + PCI1720_RANGE);	// set all ranges to +/-5V
+	outw(0x0800, dev->iobase + PCI1720_DA0);	// set outputs to 0V
+	outw(0x0800, dev->iobase + PCI1720_DA1);
+	outw(0x0800, dev->iobase + PCI1720_DA2);
+	outw(0x0800, dev->iobase + PCI1720_DA3);
+	outb(0, dev->iobase + PCI1720_SYNCOUT);	// update outputs
+	devpriv->ao_data[0] = 0x0800;
+	devpriv->ao_data[1] = 0x0800;
+	devpriv->ao_data[2] = 0x0800;
+	devpriv->ao_data[3] = 0x0800;
+	DPRINTK("adv_pci1710 EDBG: END: pci1720_reset(...)\n");
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci1710_reset(struct comedi_device * dev)
+{
+	DPRINTK("adv_pci1710 EDBG: BGN: pci1710_reset(...)\n");
+	switch (this_board->cardtype) {
+	case TYPE_PCI1720:
+		return pci1720_reset(dev);
+	default:
+		return pci171x_reset(dev);
+	}
+	DPRINTK("adv_pci1710 EDBG: END: pci1710_reset(...)\n");
+}
+
+/*
+==============================================================================
+*/
+static int pci1710_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	int ret, subdev, n_subdevices;
+	unsigned int irq;
+	unsigned long iobase;
+	struct pci_dev *pcidev;
+	int opt_bus, opt_slot;
+	const char *errstr;
+	unsigned char pci_bus, pci_slot, pci_func;
+	int i;
+	int board_index;
+
+	rt_printk("comedi%d: adv_pci1710: ", dev->minor);
+
+	opt_bus = it->options[0];
+	opt_slot = it->options[1];
+
+	if ((ret = alloc_private(dev, sizeof(struct pci1710_private))) < 0) {
+		rt_printk(" - Allocation failed!\n");
+		return -ENOMEM;
+	}
+
+	/* Look for matching PCI device */
+	errstr = "not found!";
+	pcidev = NULL;
+	board_index = this_board - boardtypes;
+	while (NULL != (pcidev = pci_get_device(PCI_VENDOR_ID_ADVANTECH,
+		PCI_ANY_ID, pcidev))) {
+		if(strcmp(this_board->name, DRV_NAME) == 0)
+		{
+			for(i = 0; i < n_boardtypes; ++i)
+			{
+				if(pcidev->device == boardtypes[i].device_id)
+				{
+					board_index = i;
+					break;
+				}
+			}
+			if(i == n_boardtypes) continue;
+		}else
+		{
+			if(pcidev->device != boardtypes[board_index].device_id) continue;
+		}
+
+		/* Found matching vendor/device. */
+		if (opt_bus || opt_slot) {
+			/* Check bus/slot. */
+			if (opt_bus != pcidev->bus->number
+				|| opt_slot != PCI_SLOT(pcidev->devfn))
+				continue;	/* no match */
+		}
+		/*
+		* Look for device that isn't in use.
+		* Enable PCI device and request regions.
+		*/
+		if (comedi_pci_enable(pcidev, DRV_NAME)) {
+			errstr = "failed to enable PCI device and request regions!";
+			continue;
+		}
+		// fixup board_ptr in case we were using the dummy entry with the driver name
+		dev->board_ptr = &boardtypes[board_index];
+		break;
+	}
+
+	if (!pcidev) {
+		if (opt_bus || opt_slot) {
+			rt_printk(" - Card at b:s %d:%d %s\n",
+				opt_bus, opt_slot, errstr);
+		} else {
+			rt_printk(" - Card %s\n", errstr);
+		}
+		return -EIO;
+	}
+
+	pci_bus = pcidev->bus->number;
+	pci_slot = PCI_SLOT(pcidev->devfn);
+	pci_func = PCI_FUNC(pcidev->devfn);
+	irq = pcidev->irq;
+	iobase = pci_resource_start(pcidev, 2);
+
+	rt_printk(", b:s:f=%d:%d:%d, io=0x%4lx", pci_bus, pci_slot, pci_func,
+		iobase);
+
+	dev->iobase = iobase;
+
+	dev->board_name = this_board->name;
+	devpriv->pcidev = pcidev;
+
+	n_subdevices = 0;
+	if (this_board->n_aichan)
+		n_subdevices++;
+	if (this_board->n_aochan)
+		n_subdevices++;
+	if (this_board->n_dichan)
+		n_subdevices++;
+	if (this_board->n_dochan)
+		n_subdevices++;
+	if (this_board->n_counter)
+		n_subdevices++;
+
+	if ((ret = alloc_subdevices(dev, n_subdevices)) < 0) {
+		rt_printk(" - Allocation failed!\n");
+		return ret;
+	}
+
+	pci1710_reset(dev);
+
+	if (this_board->have_irq) {
+		if (irq) {
+			if (comedi_request_irq(irq, interrupt_service_pci1710,
+					IRQF_SHARED, "Advantech PCI-1710",
+					dev)) {
+				rt_printk
+					(", unable to allocate IRQ %d, DISABLING IT",
+					irq);
+				irq = 0;	/* Can't use IRQ */
+			} else {
+				rt_printk(", irq=%u", irq);
+			}
+		} else {
+			rt_printk(", IRQ disabled");
+		}
+	} else {
+		irq = 0;
+	}
+
+	dev->irq = irq;
+
+	printk(".\n");
+
+	subdev = 0;
+
+	if (this_board->n_aichan) {
+		s = dev->subdevices + subdev;
+		dev->read_subdev = s;
+		s->type = COMEDI_SUBD_AI;
+		s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND;
+		if (this_board->n_aichand)
+			s->subdev_flags |= SDF_DIFF;
+		s->n_chan = this_board->n_aichan;
+		s->maxdata = this_board->ai_maxdata;
+		s->len_chanlist = this_board->n_aichan;
+		s->range_table = this_board->rangelist_ai;
+		s->cancel = pci171x_ai_cancel;
+		s->insn_read = pci171x_insn_read_ai;
+		if (irq) {
+			s->subdev_flags |= SDF_CMD_READ;
+			s->do_cmdtest = pci171x_ai_cmdtest;
+			s->do_cmd = pci171x_ai_cmd;
+		}
+		devpriv->i8254_osc_base = 100;	// 100ns=10MHz
+		subdev++;
+	}
+
+	if (this_board->n_aochan) {
+		s = dev->subdevices + subdev;
+		s->type = COMEDI_SUBD_AO;
+		s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+		s->n_chan = this_board->n_aochan;
+		s->maxdata = this_board->ao_maxdata;
+		s->len_chanlist = this_board->n_aochan;
+		s->range_table = this_board->rangelist_ao;
+		switch (this_board->cardtype) {
+		case TYPE_PCI1720:
+			s->insn_write = pci1720_insn_write_ao;
+			break;
+		default:
+			s->insn_write = pci171x_insn_write_ao;
+			break;
+		}
+		s->insn_read = pci171x_insn_read_ao;
+		subdev++;
+	}
+
+	if (this_board->n_dichan) {
+		s = dev->subdevices + subdev;
+		s->type = COMEDI_SUBD_DI;
+		s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
+		s->n_chan = this_board->n_dichan;
+		s->maxdata = 1;
+		s->len_chanlist = this_board->n_dichan;
+		s->range_table = &range_digital;
+		s->io_bits = 0;	/* all bits input */
+		s->insn_bits = pci171x_insn_bits_di;
+		subdev++;
+	}
+
+	if (this_board->n_dochan) {
+		s = dev->subdevices + subdev;
+		s->type = COMEDI_SUBD_DO;
+		s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+		s->n_chan = this_board->n_dochan;
+		s->maxdata = 1;
+		s->len_chanlist = this_board->n_dochan;
+		s->range_table = &range_digital;
+		s->io_bits = (1 << this_board->n_dochan) - 1;	/* all bits output */
+		s->state = 0;
+		s->insn_bits = pci171x_insn_bits_do;
+		subdev++;
+	}
+
+	if (this_board->n_counter) {
+		s = dev->subdevices + subdev;
+		s->type = COMEDI_SUBD_COUNTER;
+		s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+		s->n_chan = this_board->n_counter;
+		s->len_chanlist = this_board->n_counter;
+		s->maxdata = 0xffff;
+		s->range_table = &range_unknown;
+		s->insn_read = pci171x_insn_counter_read;
+		s->insn_write = pci171x_insn_counter_write;
+		s->insn_config = pci171x_insn_counter_config;
+		subdev++;
+	}
+
+	devpriv->valid = 1;
+
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci1710_detach(struct comedi_device * dev)
+{
+
+	if (dev->private) {
+		if (devpriv->valid)
+			pci1710_reset(dev);
+		if (dev->irq)
+			comedi_free_irq(dev->irq, dev);
+		if (devpriv->pcidev) {
+			if (dev->iobase) {
+				comedi_pci_disable(devpriv->pcidev);
+			}
+			pci_dev_put(devpriv->pcidev);
+		}
+	}
+
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+COMEDI_PCI_INITCLEANUP(driver_pci1710, pci1710_pci_table);
+/*
+==============================================================================
+*/
diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c
new file mode 100644
index 0000000..81f7ee1
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adv_pci1723.c
@@ -0,0 +1,465 @@
+/*******************************************************************************
+   comedi/drivers/pci1723.c
+
+   COMEDI - Linux Control and Measurement Device Interface
+   Copyright (C) 2000 David A. Schleef <ds@schleef.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.
+
+   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.
+
+*******************************************************************************/
+/*
+Driver: adv_pci1723
+Description: Advantech PCI-1723
+Author: yonggang <rsmgnu@gmail.com>, Ian Abbott <abbotti@mev.co.uk>
+Devices: [Advantech] PCI-1723 (adv_pci1723)
+Updated: Mon, 14 Apr 2008 15:12:56 +0100
+Status: works
+
+Configuration Options:
+  [0] - PCI bus of device (optional)
+  [1] - PCI slot of device (optional)
+
+  If bus/slot is not specified, the first supported
+  PCI device found will be used.
+
+Subdevice 0 is 8-channel AO, 16-bit, range +/- 10 V.
+
+Subdevice 1 is 16-channel DIO.  The channels are configurable as input or
+output in 2 groups (0 to 7, 8 to 15).  Configuring any channel implicitly
+configures all channels in the same group.
+
+TODO:
+
+1. Add the two milliamp ranges to the AO subdevice (0 to 20 mA, 4 to 20 mA).
+2. Read the initial ranges and values of the AO subdevice at start-up instead
+   of reinitializing them.
+3. Implement calibration.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+#define ADVANTECH_VENDOR        0x13fe	/* Advantech PCI vendor ID */
+
+// hardware types of the cards
+#define TYPE_PCI1723 0
+
+#define IORANGE_1723  0x2A
+
+/* all the registers for the pci1723 board */
+#define PCI1723_DA(N)   ((N)<<1)	/* W:   D/A register N (0 to 7) */
+
+#define PCI1723_SYN_SET  0x12	/*synchronized set register       */
+#define PCI1723_ALL_CHNNELE_SYN_STROBE  0x12	/*synchronized status register    */
+
+#define PCI1723_RANGE_CALIBRATION_MODE 0x14	/* range and calibration mode   */
+#define PCI1723_RANGE_CALIBRATION_STATUS 0x14	/* range and calibration status */
+
+#define PCI1723_CONTROL_CMD_CALIBRATION_FUN 0x16	/* SADC control command for calibration function */
+#define PCI1723_STATUS_CMD_CALIBRATION_FUN 0x16	/* SADC control status for calibration function */
+
+#define PCI1723_CALIBRATION_PARA_STROBE 0x18	/* Calibration parameter strobe */
+
+#define PCI1723_DIGITAL_IO_PORT_SET 0x1A	/* Digital I/O port setting */
+#define PCI1723_DIGITAL_IO_PORT_MODE 0x1A	/* Digital I/O port mode */
+
+#define PCI1723_WRITE_DIGITAL_OUTPUT_CMD 0x1C	/* Write digital output command */
+#define PCI1723_READ_DIGITAL_INPUT_DATA 0x1C	/* Read digital input data */
+
+#define PCI1723_WRITE_CAL_CMD 0x1E	/* Write calibration command */
+#define PCI1723_READ_CAL_STATUS 0x1E	/* Read calibration status */
+
+#define PCI1723_SYN_STROBE 0x20	/* Synchronized strobe */
+
+#define PCI1723_RESET_ALL_CHN_STROBE 0x22	/* Reset all D/A channels strobe */
+
+#define PCI1723_RESET_CAL_CONTROL_STROBE 0x24	/* Reset the calibration controller strobe */
+
+#define PCI1723_CHANGE_CHA_OUTPUT_TYPE_STROBE 0x26	/* Change D/A channels output type strobe */
+
+#define PCI1723_SELECT_CALIBRATION 0x28	/* Select the calibration Ref_V */
+
+//static unsigned short pci_list_builded=0;     /*=1 list of card is know */
+
+static const struct comedi_lrange range_pci1723 = { 1, {
+			BIP_RANGE(10)
+	}
+};
+
+/*
+ * Board descriptions for pci1723 boards.
+ */
+struct pci1723_board {
+	const char *name;
+	int vendor_id;		// PCI vendor a device ID of card
+	int device_id;
+	int iorange;
+	char cardtype;
+	int n_aochan;		// num of D/A chans
+	int n_diochan;		// num of DIO chans
+	int ao_maxdata;		// resolution of D/A
+	const struct comedi_lrange *rangelist_ao;	// rangelist for D/A
+};
+
+static const struct pci1723_board boardtypes[] = {
+	{
+	      name:	"pci1723",
+	      vendor_id:ADVANTECH_VENDOR,
+	      device_id:0x1723,
+	      iorange:	IORANGE_1723,
+	      cardtype:TYPE_PCI1723,
+	      n_aochan:8,
+	      n_diochan:16,
+	      ao_maxdata:0xffff,
+	      rangelist_ao:&range_pci1723,
+		},
+};
+
+/* This is used by modprobe to translate PCI IDs to drivers.  Should
+ * only be used for PCI and ISA-PnP devices */
+static DEFINE_PCI_DEVICE_TABLE(pci1723_pci_table) = {
+	{PCI_VENDOR_ID_ADVANTECH, 0x1723, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci1723_pci_table);
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pci1723_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci1723_detach(struct comedi_device * dev);
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pci1723_board))
+
+static struct comedi_driver driver_pci1723 = {
+      driver_name:"adv_pci1723",
+      module:THIS_MODULE,
+      attach:pci1723_attach,
+      detach:pci1723_detach,
+};
+
+/* this structure is for data unique to this hardware driver. */
+struct pci1723_private {
+	int valid;		//card is usable;
+
+	struct pci_dev *pcidev;
+	unsigned char da_range[8];	// D/A output range for each channel
+
+	short ao_data[8];	// data output buffer
+};
+
+/*the following macro to make it easy to
+* access the private structure.
+*/
+#define devpriv ((struct pci1723_private *)dev->private)
+
+#define this_board boardtypes
+
+/*
+ *   the pci1723 card reset;
+ */
+static int pci1723_reset(struct comedi_device * dev)
+{
+	int i;
+	DPRINTK("adv_pci1723 EDBG: BGN: pci1723_reset(...)\n");
+
+	outw(0x01, dev->iobase + PCI1723_SYN_SET);	// set synchronous output mode
+
+	for (i = 0; i < 8; i++) {
+		// set all outputs to 0V
+		devpriv->ao_data[i] = 0x8000;
+		outw(devpriv->ao_data[i], dev->iobase + PCI1723_DA(i));
+		// set all ranges to +/- 10V
+		devpriv->da_range[i] = 0;
+		outw(((devpriv->da_range[i] << 4) | i),
+			PCI1723_RANGE_CALIBRATION_MODE);
+	}
+
+	outw(0, dev->iobase + PCI1723_CHANGE_CHA_OUTPUT_TYPE_STROBE);	// update ranges
+	outw(0, dev->iobase + PCI1723_SYN_STROBE);	// update outputs
+
+	// set asynchronous output mode
+	outw(0, dev->iobase + PCI1723_SYN_SET);
+
+	DPRINTK("adv_pci1723 EDBG: END: pci1723_reset(...)\n");
+	return 0;
+}
+
+static int pci1723_insn_read_ao(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n, chan;
+
+	chan = CR_CHAN(insn->chanspec);
+	DPRINTK(" adv_PCI1723 DEBUG: pci1723_insn_read_ao() ----- \n");
+	for (n = 0; n < insn->n; n++)
+		data[n] = devpriv->ao_data[chan];
+
+	return n;
+}
+
+/*
+  analog data output;
+*/
+static int pci1723_ao_write_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n, chan;
+	chan = CR_CHAN(insn->chanspec);
+
+	DPRINTK("PCI1723: the pci1723_ao_write_winsn() ------\n");
+
+	for (n = 0; n < insn->n; n++) {
+
+		devpriv->ao_data[chan] = data[n];
+		outw(data[n], dev->iobase + PCI1723_DA(chan));
+	}
+
+	return n;
+}
+
+/*
+  digital i/o config/query
+*/
+static int pci1723_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int mask;
+	unsigned int bits;
+	unsigned short dio_mode;
+
+	mask = 1 << CR_CHAN(insn->chanspec);
+	if (mask & 0x00FF) {
+		bits = 0x00FF;
+	} else {
+		bits = 0xFF00;
+	}
+	switch (data[0]) {
+	case INSN_CONFIG_DIO_INPUT:
+		s->io_bits &= ~bits;
+		break;
+	case INSN_CONFIG_DIO_OUTPUT:
+		s->io_bits |= bits;
+		break;
+	case INSN_CONFIG_DIO_QUERY:
+		data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
+		return insn->n;
+	default:
+		return -EINVAL;
+	}
+
+	// update hardware DIO mode
+	dio_mode = 0x0000;	// low byte output, high byte output
+	if ((s->io_bits & 0x00FF) == 0)
+		dio_mode |= 0x0001;	// low byte input
+	if ((s->io_bits & 0xFF00) == 0)
+		dio_mode |= 0x0002;	// high byte input
+	outw(dio_mode, dev->iobase + PCI1723_DIGITAL_IO_PORT_SET);
+	return 1;
+}
+
+/*
+  digital i/o bits read/write
+*/
+static int pci1723_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= (data[0] & data[1]);
+		outw(s->state, dev->iobase + PCI1723_WRITE_DIGITAL_OUTPUT_CMD);
+	}
+	data[1] = inw(dev->iobase + PCI1723_READ_DIGITAL_INPUT_DATA);
+	return 2;
+}
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a pci1723 board.
+ */
+static int pci1723_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	int ret, subdev, n_subdevices;
+	struct pci_dev *pcidev;
+	unsigned int iobase;
+	unsigned char pci_bus, pci_slot, pci_func;
+	int opt_bus, opt_slot;
+	const char *errstr;
+
+	rt_printk("comedi%d: adv_pci1723: board=%s", dev->minor,
+		this_board->name);
+
+	opt_bus = it->options[0];
+	opt_slot = it->options[1];
+
+	if ((ret = alloc_private(dev, sizeof(struct pci1723_private))) < 0) {
+		rt_printk(" - Allocation failed!\n");
+		return -ENOMEM;
+	}
+
+	/* Look for matching PCI device */
+	errstr = "not found!";
+	pcidev = NULL;
+	while (NULL != (pcidev =
+			pci_get_device(PCI_VENDOR_ID_ADVANTECH,
+				this_board->device_id, pcidev))) {
+		/* Found matching vendor/device. */
+		if (opt_bus || opt_slot) {
+			/* Check bus/slot. */
+			if (opt_bus != pcidev->bus->number
+				|| opt_slot != PCI_SLOT(pcidev->devfn))
+				continue;	/* no match */
+		}
+		/*
+		 * Look for device that isn't in use.
+		 * Enable PCI device and request regions.
+		 */
+		if (comedi_pci_enable(pcidev, "adv_pci1723")) {
+			errstr = "failed to enable PCI device and request regions!";
+			continue;
+		}
+		break;
+	}
+
+	if (!pcidev) {
+		if (opt_bus || opt_slot) {
+			rt_printk(" - Card at b:s %d:%d %s\n",
+				opt_bus, opt_slot, errstr);
+		} else {
+			rt_printk(" - Card %s\n", errstr);
+		}
+		return -EIO;
+	}
+
+	pci_bus = pcidev->bus->number;
+	pci_slot = PCI_SLOT(pcidev->devfn);
+	pci_func = PCI_FUNC(pcidev->devfn);
+	iobase = pci_resource_start(pcidev, 2);
+
+	rt_printk(", b:s:f=%d:%d:%d, io=0x%4x", pci_bus, pci_slot, pci_func,
+		iobase);
+
+	dev->iobase = iobase;
+
+	dev->board_name = this_board->name;
+	devpriv->pcidev = pcidev;
+
+	n_subdevices = 0;
+
+	if (this_board->n_aochan)
+		n_subdevices++;
+	if (this_board->n_diochan)
+		n_subdevices++;
+
+	if ((ret = alloc_subdevices(dev, n_subdevices)) < 0) {
+		rt_printk(" - Allocation failed!\n");
+		return ret;
+	}
+
+	pci1723_reset(dev);
+	subdev = 0;
+	if (this_board->n_aochan) {
+		s = dev->subdevices + subdev;
+		dev->write_subdev = s;
+		s->type = COMEDI_SUBD_AO;
+		s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
+		s->n_chan = this_board->n_aochan;
+		s->maxdata = this_board->ao_maxdata;
+		s->len_chanlist = this_board->n_aochan;
+		s->range_table = this_board->rangelist_ao;
+
+		s->insn_write = pci1723_ao_write_winsn;
+		s->insn_read = pci1723_insn_read_ao;
+
+		// read DIO config
+		switch (inw(dev->iobase + PCI1723_DIGITAL_IO_PORT_MODE) & 0x03) {
+		case 0x00:	// low byte output, high byte output
+			s->io_bits = 0xFFFF;
+			break;
+		case 0x01:	// low byte input, high byte output
+			s->io_bits = 0xFF00;
+			break;
+		case 0x02:	// low byte output, high byte input
+			s->io_bits = 0x00FF;
+			break;
+		case 0x03:	// low byte input, high byte input
+			s->io_bits = 0x0000;
+			break;
+		}
+		// read DIO port state
+		s->state = inw(dev->iobase + PCI1723_READ_DIGITAL_INPUT_DATA);
+
+		subdev++;
+	}
+
+	if (this_board->n_diochan) {
+		s = dev->subdevices + subdev;
+		s->type = COMEDI_SUBD_DIO;
+		s->subdev_flags =
+			SDF_READABLE | SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+		s->n_chan = this_board->n_diochan;
+		s->maxdata = 1;
+		s->len_chanlist = this_board->n_diochan;
+		s->range_table = &range_digital;
+		s->insn_config = pci1723_dio_insn_config;
+		s->insn_bits = pci1723_dio_insn_bits;
+		subdev++;
+	}
+
+	devpriv->valid = 1;
+
+	pci1723_reset(dev);
+
+	return 0;
+}
+
+/*
+ * _detach is called to deconfigure a device.  It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach().  dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pci1723_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: pci1723: remove\n", dev->minor);
+
+	if (dev->private) {
+		if (devpriv->valid)
+			pci1723_reset(dev);
+
+		if (devpriv->pcidev) {
+			if (dev->iobase) {
+				comedi_pci_disable(devpriv->pcidev);
+			}
+			pci_dev_put(devpriv->pcidev);
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_PCI_INITCLEANUP(driver_pci1723, pci1723_pci_table);
diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c
new file mode 100644
index 0000000..2604425
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adv_pci_dio.c
@@ -0,0 +1,1077 @@
+/*
+ * comedi/drivers/adv_pci_dio.c
+ *
+ * Author: Michal Dobes <dobes@tesnet.cz>
+ *
+ *  Hardware driver for Advantech PCI DIO cards.
+*/
+/*
+Driver: adv_pci_dio
+Description: Advantech PCI-1730, PCI-1733, PCI-1734, PCI-1736UP,
+             PCI-1750, PCI-1751, PCI-1752, PCI-1753/E, PCI-1754,
+             PCI-1756, PCI-1762
+Author: Michal Dobes <dobes@tesnet.cz>
+Devices: [Advantech] PCI-1730 (adv_pci_dio), PCI-1733,
+  PCI-1734, PCI-1736UP, PCI-1750,
+  PCI-1751, PCI-1752, PCI-1753,
+  PCI-1753+PCI-1753E, PCI-1754, PCI-1756,
+  PCI-1760, PCI-1762
+Status: untested
+Updated: Mon, 14 Apr 2008 10:43:08 +0100
+
+This driver supports now only insn interface for DI/DO/DIO.
+
+Configuration options:
+  [0] - PCI bus of device (optional)
+  [1] - PCI slot of device (optional)
+          If bus/slot is not specified, the first available PCI
+          device will be used.
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+
+#include "comedi_pci.h"
+#include "8255.h"
+
+#undef PCI_DIO_EXTDEBUG		/* if defined, enable extensive debug logging */
+
+#undef DPRINTK
+#ifdef PCI_DIO_EXTDEBUG
+#define DPRINTK(fmt, args...) rt_printk(fmt, ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+/* hardware types of the cards */
+enum hw_cards_id {
+	TYPE_PCI1730, TYPE_PCI1733, TYPE_PCI1734, TYPE_PCI1736,
+	TYPE_PCI1750,
+	TYPE_PCI1751,
+	TYPE_PCI1752,
+	TYPE_PCI1753, TYPE_PCI1753E,
+	TYPE_PCI1754, TYPE_PCI1756,
+	TYPE_PCI1760,
+	TYPE_PCI1762
+};
+
+/* which I/O instructions to use */
+enum hw_io_access {
+	IO_8b, IO_16b
+};
+
+#define MAX_DI_SUBDEVS	2	/* max number of DI subdevices per card */
+#define MAX_DO_SUBDEVS	2	/* max number of DO subdevices per card */
+#define MAX_DIO_SUBDEVG	2	/* max number of DIO subdevices group per card */
+
+#define SIZE_8255	   4	/* 8255 IO space length */
+
+#define PCIDIO_MAINREG	   2	/* main I/O region for all Advantech cards? */
+
+/* Register offset definitions */
+/*  Advantech PCI-1730/3/4 */
+#define PCI1730_IDI	   0	/* R:   Isolated digital input  0-15 */
+#define PCI1730_IDO	   0	/* W:   Isolated digital output 0-15 */
+#define PCI1730_DI	   2	/* R:   Digital input  0-15 */
+#define PCI1730_DO	   2	/* W:   Digital output 0-15 */
+#define PCI1733_IDI	   0	/* R:   Isolated digital input  0-31 */
+#define	PCI1730_3_INT_EN	0x08	/* R/W: enable/disable interrupts */
+#define	PCI1730_3_INT_RF	0x0c	/* R/W: set falling/raising edge for interrupts */
+#define	PCI1730_3_INT_CLR	0x10	/* R/W: clear interrupts */
+#define PCI1734_IDO	   0	/* W:   Isolated digital output 0-31 */
+#define PCI173x_BOARDID	   4	/* R:   Board I/D switch for 1730/3/4 */
+
+/*  Advantech PCI-1736UP */
+#define PCI1736_IDI        0    /* R:   Isolated digital input  0-15 */
+#define PCI1736_IDO        0    /* W:   Isolated digital output 0-15 */
+#define PCI1736_3_INT_EN        0x08    /* R/W: enable/disable interrupts */
+#define PCI1736_3_INT_RF        0x0c    /* R/W: set falling/raising edge for interrupts */
+#define PCI1736_3_INT_CLR       0x10    /* R/W: clear interrupts */
+#define PCI1736_BOARDID    4            /* R:   Board I/D switch for 1736UP */
+#define PCI1736_MAINREG    0            /* Normal register (2) doesn't work */
+
+/*  Advantech PCI-1750 */
+#define PCI1750_IDI	   0	/* R:   Isolated digital input  0-15 */
+#define PCI1750_IDO	   0	/* W:   Isolated digital output 0-15 */
+#define PCI1750_ICR	  32	/* W:   Interrupt control register */
+#define PCI1750_ISR	  32	/* R:   Interrupt status register */
+
+/*  Advantech PCI-1751/3/3E */
+#define PCI1751_DIO	   0	/* R/W: begin of 8255 registers block */
+#define PCI1751_ICR	  32	/* W:   Interrupt control register */
+#define PCI1751_ISR	  32	/* R:   Interrupt status register */
+#define PCI1753_DIO	   0	/* R/W: begin of 8255 registers block */
+#define PCI1753_ICR0	  16	/* R/W: Interrupt control register group 0 */
+#define PCI1753_ICR1	  17	/* R/W: Interrupt control register group 1 */
+#define PCI1753_ICR2	  18	/* R/W: Interrupt control register group 2 */
+#define PCI1753_ICR3	  19	/* R/W: Interrupt control register group 3 */
+#define PCI1753E_DIO	  32	/* R/W: begin of 8255 registers block */
+#define PCI1753E_ICR0	  48	/* R/W: Interrupt control register group 0 */
+#define PCI1753E_ICR1	  49	/* R/W: Interrupt control register group 1 */
+#define PCI1753E_ICR2	  50	/* R/W: Interrupt control register group 2 */
+#define PCI1753E_ICR3	  51	/* R/W: Interrupt control register group 3 */
+
+/*  Advantech PCI-1752/4/6 */
+#define PCI1752_IDO	   0	/* R/W: Digital output  0-31 */
+#define PCI1752_IDO2	   4	/* R/W: Digital output 32-63 */
+#define PCI1754_IDI	   0	/* R:   Digital input   0-31 */
+#define PCI1754_IDI2	   4	/* R:   Digital input  32-64 */
+#define PCI1756_IDI	   0	/* R:   Digital input   0-31 */
+#define PCI1756_IDO	   4	/* R/W: Digital output  0-31 */
+#define PCI1754_6_ICR0	0x08	/* R/W: Interrupt control register group 0 */
+#define PCI1754_6_ICR1	0x0a	/* R/W: Interrupt control register group 1 */
+#define PCI1754_ICR2	0x0c	/* R/W: Interrupt control register group 2 */
+#define PCI1754_ICR3	0x0e	/* R/W: Interrupt control register group 3 */
+#define PCI1752_6_CFC	0x12	/* R/W: set/read channel freeze function */
+#define PCI175x_BOARDID	0x10	/* R:   Board I/D switch for 1752/4/6 */
+
+/*  Advantech PCI-1762 registers */
+#define PCI1762_RO	   0	/* R/W: Relays status/output */
+#define PCI1762_IDI	   2	/* R:   Isolated input status */
+#define PCI1762_BOARDID	   4	/* R:   Board I/D switch */
+#define PCI1762_ICR	   6	/* W:   Interrupt control register */
+#define PCI1762_ISR	   6	/* R:   Interrupt status register */
+
+/*  Advantech PCI-1760 registers */
+#define OMB0		0x0c	/* W:   Mailbox outgoing registers */
+#define OMB1		0x0d
+#define OMB2		0x0e
+#define OMB3		0x0f
+#define IMB0		0x1c	/* R:   Mailbox incoming registers */
+#define IMB1		0x1d
+#define IMB2		0x1e
+#define IMB3		0x1f
+#define INTCSR0		0x38	/* R/W: Interrupt control registers */
+#define INTCSR1		0x39
+#define INTCSR2		0x3a
+#define INTCSR3		0x3b
+
+/*  PCI-1760 mailbox commands */
+#define CMD_ClearIMB2		0x00	/* Clear IMB2 status and return actaul DI status in IMB3 */
+#define CMD_SetRelaysOutput	0x01	/* Set relay output from OMB0 */
+#define CMD_GetRelaysStatus	0x02	/* Get relay status to IMB0 */
+#define CMD_ReadCurrentStatus	0x07	/* Read the current status of the register in OMB0, result in IMB0 */
+#define CMD_ReadFirmwareVersion	0x0e	/* Read the firmware ver., result in IMB1.IMB0 */
+#define CMD_ReadHardwareVersion	0x0f	/* Read the hardware ver., result in IMB1.IMB0 */
+#define CMD_EnableIDIFilters	0x20	/* Enable IDI filters based on bits in OMB0 */
+#define CMD_EnableIDIPatternMatch 0x21	/* Enable IDI pattern match based on bits in OMB0 */
+#define CMD_SetIDIPatternMatch	0x22	/* Enable IDI pattern match based on bits in OMB0 */
+#define CMD_EnableIDICounters	0x28	/* Enable IDI counters based on bits in OMB0 */
+#define CMD_ResetIDICounters	0x29	/* Reset IDI counters based on bits in OMB0 to its reset values */
+#define CMD_OverflowIDICounters	0x2a	/* Enable IDI counters overflow interrupts  based on bits in OMB0 */
+#define CMD_MatchIntIDICounters	0x2b	/* Enable IDI counters match value interrupts  based on bits in OMB0 */
+#define CMD_EdgeIDICounters	0x2c	/* Set IDI up counters count edge (bit=0 - rising, =1 - falling) */
+#define CMD_GetIDICntCurValue	0x2f	/* Read IDI{OMB0} up counter current value */
+#define CMD_SetIDI0CntResetValue 0x40	/* Set IDI0 Counter Reset Value 256*OMB1+OMB0 */
+#define CMD_SetIDI1CntResetValue 0x41	/* Set IDI1 Counter Reset Value 256*OMB1+OMB0 */
+#define CMD_SetIDI2CntResetValue 0x42	/* Set IDI2 Counter Reset Value 256*OMB1+OMB0 */
+#define CMD_SetIDI3CntResetValue 0x43	/* Set IDI3 Counter Reset Value 256*OMB1+OMB0 */
+#define CMD_SetIDI4CntResetValue 0x44	/* Set IDI4 Counter Reset Value 256*OMB1+OMB0 */
+#define CMD_SetIDI5CntResetValue 0x45	/* Set IDI5 Counter Reset Value 256*OMB1+OMB0 */
+#define CMD_SetIDI6CntResetValue 0x46	/* Set IDI6 Counter Reset Value 256*OMB1+OMB0 */
+#define CMD_SetIDI7CntResetValue 0x47	/* Set IDI7 Counter Reset Value 256*OMB1+OMB0 */
+#define CMD_SetIDI0CntMatchValue 0x48	/* Set IDI0 Counter Match Value 256*OMB1+OMB0 */
+#define CMD_SetIDI1CntMatchValue 0x49	/* Set IDI1 Counter Match Value 256*OMB1+OMB0 */
+#define CMD_SetIDI2CntMatchValue 0x4a	/* Set IDI2 Counter Match Value 256*OMB1+OMB0 */
+#define CMD_SetIDI3CntMatchValue 0x4b	/* Set IDI3 Counter Match Value 256*OMB1+OMB0 */
+#define CMD_SetIDI4CntMatchValue 0x4c	/* Set IDI4 Counter Match Value 256*OMB1+OMB0 */
+#define CMD_SetIDI5CntMatchValue 0x4d	/* Set IDI5 Counter Match Value 256*OMB1+OMB0 */
+#define CMD_SetIDI6CntMatchValue 0x4e	/* Set IDI6 Counter Match Value 256*OMB1+OMB0 */
+#define CMD_SetIDI7CntMatchValue 0x4f	/* Set IDI7 Counter Match Value 256*OMB1+OMB0 */
+
+#define OMBCMD_RETRY	0x03	/* 3 times try request before error */
+
+static int pci_dio_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci_dio_detach(struct comedi_device * dev);
+
+struct diosubd_data {
+	int chans;		/*  num of chans */
+	int addr;		/*  PCI address ofset */
+	int regs;		/*  number of registers to read or 8255 subdevices */
+	unsigned int specflags;	/*  addon subdevice flags */
+};
+
+struct dio_boardtype {
+	const char *name;	/*  board name */
+	int vendor_id;		/*  vendor/device PCI ID */
+	int device_id;
+	int main_pci_region;	/*  main I/O PCI region */
+	enum hw_cards_id cardtype;
+	struct diosubd_data sdi[MAX_DI_SUBDEVS];	/*  DI chans */
+	struct diosubd_data sdo[MAX_DO_SUBDEVS];	/*  DO chans */
+	struct diosubd_data sdio[MAX_DIO_SUBDEVG];	/*  DIO 8255 chans */
+	struct diosubd_data boardid;	/*  card supports board ID switch */
+	enum hw_io_access io_access;
+};
+
+static DEFINE_PCI_DEVICE_TABLE(pci_dio_pci_table) = {
+	{PCI_VENDOR_ID_ADVANTECH, 0x1730, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_ADVANTECH, 0x1733, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_ADVANTECH, 0x1734, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_ADVANTECH, 0x1736, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_ADVANTECH, 0x1750, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_ADVANTECH, 0x1751, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_ADVANTECH, 0x1752, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_ADVANTECH, 0x1753, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_ADVANTECH, 0x1754, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_ADVANTECH, 0x1756, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_ADVANTECH, 0x1760, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_ADVANTECH, 0x1762, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci_dio_pci_table);
+
+static const struct dio_boardtype boardtypes[] = {
+	{"pci1730", PCI_VENDOR_ID_ADVANTECH, 0x1730, PCIDIO_MAINREG,
+			TYPE_PCI1730,
+			{{16, PCI1730_DI, 2, 0}, {16, PCI1730_IDI, 2, 0}},
+			{{16, PCI1730_DO, 2, 0}, {16, PCI1730_IDO, 2, 0}},
+			{{0, 0, 0, 0}, {0, 0, 0, 0}},
+			{4, PCI173x_BOARDID, 1, SDF_INTERNAL},
+			IO_8b,
+		},
+	{"pci1733", PCI_VENDOR_ID_ADVANTECH, 0x1733, PCIDIO_MAINREG,
+			TYPE_PCI1733,
+			{{0, 0, 0, 0}, {32, PCI1733_IDI, 4, 0}},
+			{{0, 0, 0, 0}, {0, 0, 0, 0}},
+			{{0, 0, 0, 0}, {0, 0, 0, 0}},
+			{4, PCI173x_BOARDID, 1, SDF_INTERNAL},
+		IO_8b},
+	{"pci1734", PCI_VENDOR_ID_ADVANTECH, 0x1734, PCIDIO_MAINREG,
+			TYPE_PCI1734,
+			{{0, 0, 0, 0}, {0, 0, 0, 0}},
+			{{0, 0, 0, 0}, {32, PCI1734_IDO, 4, 0}},
+			{{0, 0, 0, 0}, {0, 0, 0, 0}},
+			{4, PCI173x_BOARDID, 1, SDF_INTERNAL},
+		IO_8b},
+	{"pci1736", PCI_VENDOR_ID_ADVANTECH, 0x1736, PCI1736_MAINREG,
+			TYPE_PCI1736,
+			{{0, 0, 0, 0}, {16, PCI1736_IDI, 2, 0}},
+			{{0, 0, 0, 0}, {16, PCI1736_IDO, 2, 0}},
+			{{ 0, 0, 0, 0}, { 0, 0, 0, 0}},
+			{ 4, PCI1736_BOARDID, 1, SDF_INTERNAL},
+			IO_8b,
+        },
+	{"pci1750", PCI_VENDOR_ID_ADVANTECH, 0x1750, PCIDIO_MAINREG,
+			TYPE_PCI1750,
+			{{0, 0, 0, 0}, {16, PCI1750_IDI, 2, 0}},
+			{{0, 0, 0, 0}, {16, PCI1750_IDO, 2, 0}},
+			{{0, 0, 0, 0}, {0, 0, 0, 0}},
+			{0, 0, 0, 0},
+		IO_8b},
+	{"pci1751", PCI_VENDOR_ID_ADVANTECH, 0x1751, PCIDIO_MAINREG,
+			TYPE_PCI1751,
+			{{0, 0, 0, 0}, {0, 0, 0, 0}},
+			{{0, 0, 0, 0}, {0, 0, 0, 0}},
+			{{48, PCI1751_DIO, 2, 0}, {0, 0, 0, 0}},
+			{0, 0, 0, 0},
+		IO_8b},
+	{"pci1752", PCI_VENDOR_ID_ADVANTECH, 0x1752, PCIDIO_MAINREG,
+			TYPE_PCI1752,
+			{{0, 0, 0, 0}, {0, 0, 0, 0}},
+			{{32, PCI1752_IDO, 2, 0}, {32, PCI1752_IDO2, 2, 0}},
+			{{0, 0, 0, 0}, {0, 0, 0, 0}},
+			{4, PCI175x_BOARDID, 1, SDF_INTERNAL},
+		IO_16b},
+	{"pci1753", PCI_VENDOR_ID_ADVANTECH, 0x1753, PCIDIO_MAINREG,
+			TYPE_PCI1753,
+			{{0, 0, 0, 0}, {0, 0, 0, 0}},
+			{{0, 0, 0, 0}, {0, 0, 0, 0}},
+			{{96, PCI1753_DIO, 4, 0}, {0, 0, 0, 0}},
+			{0, 0, 0, 0},
+		IO_8b},
+	{"pci1753e", PCI_VENDOR_ID_ADVANTECH, 0x1753, PCIDIO_MAINREG,
+			TYPE_PCI1753E,
+			{{0, 0, 0, 0}, {0, 0, 0, 0}},
+			{{0, 0, 0, 0}, {0, 0, 0, 0}},
+			{{96, PCI1753_DIO, 4, 0}, {96, PCI1753E_DIO, 4, 0}},
+			{0, 0, 0, 0},
+		IO_8b},
+	{"pci1754", PCI_VENDOR_ID_ADVANTECH, 0x1754, PCIDIO_MAINREG,
+			TYPE_PCI1754,
+			{{32, PCI1754_IDI, 2, 0}, {32, PCI1754_IDI2, 2, 0}},
+			{{0, 0, 0, 0}, {0, 0, 0, 0}},
+			{{0, 0, 0, 0}, {0, 0, 0, 0}},
+			{4, PCI175x_BOARDID, 1, SDF_INTERNAL},
+		IO_16b},
+	{"pci1756", PCI_VENDOR_ID_ADVANTECH, 0x1756, PCIDIO_MAINREG,
+			TYPE_PCI1756,
+			{{0, 0, 0, 0}, {32, PCI1756_IDI, 2, 0}},
+			{{0, 0, 0, 0}, {32, PCI1756_IDO, 2, 0}},
+			{{0, 0, 0, 0}, {0, 0, 0, 0}},
+			{4, PCI175x_BOARDID, 1, SDF_INTERNAL},
+		IO_16b},
+	{"pci1760", PCI_VENDOR_ID_ADVANTECH, 0x1760, 0,
+			TYPE_PCI1760,
+			{{0, 0, 0, 0}, {0, 0, 0, 0}},	/*  This card have own setup work */
+			{{0, 0, 0, 0}, {0, 0, 0, 0}},
+			{{0, 0, 0, 0}, {0, 0, 0, 0}},
+			{0, 0, 0, 0},
+		IO_8b},
+	{"pci1762", PCI_VENDOR_ID_ADVANTECH, 0x1762, PCIDIO_MAINREG,
+			TYPE_PCI1762,
+			{{0, 0, 0, 0}, {16, PCI1762_IDI, 1, 0}},
+			{{0, 0, 0, 0}, {16, PCI1762_RO, 1, 0}},
+			{{0, 0, 0, 0}, {0, 0, 0, 0}},
+			{4, PCI1762_BOARDID, 1, SDF_INTERNAL},
+		IO_16b}
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct dio_boardtype))
+
+static struct comedi_driver driver_pci_dio = {
+      driver_name:"adv_pci_dio",
+      module:THIS_MODULE,
+      attach:pci_dio_attach,
+      detach:pci_dio_detach
+};
+
+struct pci_dio_private {
+	struct pci_dio_private *prev;	/*  previous private struct */
+	struct pci_dio_private *next;	/*  next private struct */
+	struct pci_dev *pcidev;	/*  pointer to board's pci_dev */
+	char valid;		/*  card is usable */
+	char GlobalIrqEnabled;	/*  1= any IRQ source is enabled */
+	/*  PCI-1760 specific data */
+	unsigned char IDICntEnable;	/*  counter's counting enable status */
+	unsigned char IDICntOverEnable;	/*  counter's overflow interrupts enable status */
+	unsigned char IDICntMatchEnable;	/*  counter's match interrupts enable status */
+	unsigned char IDICntEdge;	/*  counter's count edge value (bit=0 - rising, =1 - falling) */
+	unsigned short CntResValue[8];	/*  counters' reset value */
+	unsigned short CntMatchValue[8];	/*  counters' match interrupt value */
+	unsigned char IDIFiltersEn;	/*  IDI's digital filters enable status */
+	unsigned char IDIPatMatchEn;	/*  IDI's pattern match enable status */
+	unsigned char IDIPatMatchValue;	/*  IDI's pattern match value */
+	unsigned short IDIFiltrLow[8];	/*  IDI's filter value low signal */
+	unsigned short IDIFiltrHigh[8];	/*  IDI's filter value high signal */
+};
+
+static struct pci_dio_private *pci_priv = NULL;	/* list of allocated cards */
+
+#define devpriv ((struct pci_dio_private *)dev->private)
+#define this_board ((const struct dio_boardtype *)dev->board_ptr)
+
+/*
+==============================================================================
+*/
+static int pci_dio_insn_bits_di_b(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	const struct diosubd_data *d = (const struct diosubd_data *)s->private;
+	int i;
+
+	data[1] = 0;
+	for (i = 0; i < d->regs; i++) {
+		data[1] |= inb(dev->iobase + d->addr + i) << (8 * i);
+	}
+
+	return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci_dio_insn_bits_di_w(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	const struct diosubd_data *d = (const struct diosubd_data *)s->private;
+	int i;
+
+	data[1] = 0;
+	for (i = 0; i < d->regs; i++)
+		data[1] |= inw(dev->iobase + d->addr + 2 * i) << (16 * i);
+
+	return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci_dio_insn_bits_do_b(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	const struct diosubd_data *d = (const struct diosubd_data *)s->private;
+	int i;
+
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= (data[0] & data[1]);
+		for (i = 0; i < d->regs; i++)
+			outb((s->state >> (8 * i)) & 0xff,
+				dev->iobase + d->addr + i);
+	}
+	data[1] = s->state;
+
+	return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci_dio_insn_bits_do_w(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	const struct diosubd_data *d = (const struct diosubd_data *)s->private;
+	int i;
+
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= (data[0] & data[1]);
+		for (i = 0; i < d->regs; i++)
+			outw((s->state >> (16 * i)) & 0xffff,
+				dev->iobase + d->addr + 2 * i);
+	}
+	data[1] = s->state;
+
+	return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci1760_unchecked_mbxrequest(struct comedi_device * dev,
+	unsigned char *omb, unsigned char *imb, int repeats)
+{
+	int cnt, tout, ok = 0;
+
+	for (cnt = 0; cnt < repeats; cnt++) {
+		outb(omb[0], dev->iobase + OMB0);
+		outb(omb[1], dev->iobase + OMB1);
+		outb(omb[2], dev->iobase + OMB2);
+		outb(omb[3], dev->iobase + OMB3);
+		for (tout = 0; tout < 251; tout++) {
+			if ((imb[2] = inb(dev->iobase + IMB2)) == omb[2]) {
+				imb[0] = inb(dev->iobase + IMB0);
+				imb[1] = inb(dev->iobase + IMB1);
+				imb[3] = inb(dev->iobase + IMB3);
+				ok = 1;
+				break;
+			}
+			comedi_udelay(1);
+		}
+		if (ok)
+			return 0;
+	}
+
+	comedi_error(dev, "PCI-1760 mailbox request timeout!");
+	return -ETIME;
+}
+
+static int pci1760_clear_imb2(struct comedi_device * dev)
+{
+	unsigned char omb[4] = { 0x0, 0x0, CMD_ClearIMB2, 0x0 };
+	unsigned char imb[4];
+	/* check if imb2 is already clear */
+	if (inb(dev->iobase + IMB2) == CMD_ClearIMB2)
+		return 0;
+	return pci1760_unchecked_mbxrequest(dev, omb, imb, OMBCMD_RETRY);
+}
+
+static int pci1760_mbxrequest(struct comedi_device * dev,
+	unsigned char *omb, unsigned char *imb)
+{
+	if (omb[2] == CMD_ClearIMB2) {
+		comedi_error(dev,
+			"bug! this function should not be used for CMD_ClearIMB2 command");
+		return -EINVAL;
+	}
+	if (inb(dev->iobase + IMB2) == omb[2]) {
+		int retval;
+		retval = pci1760_clear_imb2(dev);
+		if (retval < 0)
+			return retval;
+	}
+	return pci1760_unchecked_mbxrequest(dev, omb, imb, OMBCMD_RETRY);
+}
+
+/*
+==============================================================================
+*/
+static int pci1760_insn_bits_di(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	data[1] = inb(dev->iobase + IMB3);
+
+	return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci1760_insn_bits_do(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int ret;
+	unsigned char omb[4] = {
+		0x00,
+		0x00,
+		CMD_SetRelaysOutput,
+		0x00
+	};
+	unsigned char imb[4];
+
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= (data[0] & data[1]);
+		omb[0] = s->state;
+		if (!(ret = pci1760_mbxrequest(dev, omb, imb)))
+			return ret;
+	}
+	data[1] = s->state;
+
+	return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci1760_insn_cnt_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int ret, n;
+	unsigned char omb[4] = {
+		CR_CHAN(insn->chanspec) & 0x07,
+		0x00,
+		CMD_GetIDICntCurValue,
+		0x00
+	};
+	unsigned char imb[4];
+
+	for (n = 0; n < insn->n; n++) {
+		if (!(ret = pci1760_mbxrequest(dev, omb, imb)))
+			return ret;
+		data[n] = (imb[1] << 8) + imb[0];
+	}
+
+	return n;
+}
+
+/*
+==============================================================================
+*/
+static int pci1760_insn_cnt_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int ret;
+	unsigned char chan = CR_CHAN(insn->chanspec) & 0x07;
+	unsigned char bitmask = 1 << chan;
+	unsigned char omb[4] = {
+		data[0] & 0xff,
+		(data[0] >> 8) & 0xff,
+		CMD_SetIDI0CntResetValue + chan,
+		0x00
+	};
+	unsigned char imb[4];
+
+	if (devpriv->CntResValue[chan] != (data[0] & 0xffff)) {	/*  Set reset value if different */
+		if (!(ret = pci1760_mbxrequest(dev, omb, imb)))
+			return ret;
+		devpriv->CntResValue[chan] = data[0] & 0xffff;
+	}
+
+	omb[0] = bitmask;	/*  reset counter to it reset value */
+	omb[2] = CMD_ResetIDICounters;
+	if (!(ret = pci1760_mbxrequest(dev, omb, imb)))
+		return ret;
+
+	if (!(bitmask & devpriv->IDICntEnable)) {	/*  start counter if it don't run */
+		omb[0] = bitmask;
+		omb[2] = CMD_EnableIDICounters;
+		if (!(ret = pci1760_mbxrequest(dev, omb, imb)))
+			return ret;
+		devpriv->IDICntEnable |= bitmask;
+	}
+	return 1;
+}
+
+/*
+==============================================================================
+*/
+static int pci1760_reset(struct comedi_device * dev)
+{
+	int i;
+	unsigned char omb[4] = { 0x00, 0x00, 0x00, 0x00 };
+	unsigned char imb[4];
+
+	outb(0, dev->iobase + INTCSR0);	/*  disable IRQ */
+	outb(0, dev->iobase + INTCSR1);
+	outb(0, dev->iobase + INTCSR2);
+	outb(0, dev->iobase + INTCSR3);
+	devpriv->GlobalIrqEnabled = 0;
+
+	omb[0] = 0x00;
+	omb[2] = CMD_SetRelaysOutput;	/*  reset relay outputs */
+	pci1760_mbxrequest(dev, omb, imb);
+
+	omb[0] = 0x00;
+	omb[2] = CMD_EnableIDICounters;	/*  disable IDI up counters */
+	pci1760_mbxrequest(dev, omb, imb);
+	devpriv->IDICntEnable = 0;
+
+	omb[0] = 0x00;
+	omb[2] = CMD_OverflowIDICounters;	/*  disable counters overflow interrupts */
+	pci1760_mbxrequest(dev, omb, imb);
+	devpriv->IDICntOverEnable = 0;
+
+	omb[0] = 0x00;
+	omb[2] = CMD_MatchIntIDICounters;	/*  disable counters match value interrupts */
+	pci1760_mbxrequest(dev, omb, imb);
+	devpriv->IDICntMatchEnable = 0;
+
+	omb[0] = 0x00;
+	omb[1] = 0x80;
+	for (i = 0; i < 8; i++) {	/*  set IDI up counters match value */
+		omb[2] = CMD_SetIDI0CntMatchValue + i;
+		pci1760_mbxrequest(dev, omb, imb);
+		devpriv->CntMatchValue[i] = 0x8000;
+	}
+
+	omb[0] = 0x00;
+	omb[1] = 0x00;
+	for (i = 0; i < 8; i++) {	/*  set IDI up counters reset value */
+		omb[2] = CMD_SetIDI0CntResetValue + i;
+		pci1760_mbxrequest(dev, omb, imb);
+		devpriv->CntResValue[i] = 0x0000;
+	}
+
+	omb[0] = 0xff;
+	omb[2] = CMD_ResetIDICounters;	/*  reset IDI up counters to reset values */
+	pci1760_mbxrequest(dev, omb, imb);
+
+	omb[0] = 0x00;
+	omb[2] = CMD_EdgeIDICounters;	/*  set IDI up counters count edge */
+	pci1760_mbxrequest(dev, omb, imb);
+	devpriv->IDICntEdge = 0x00;
+
+	omb[0] = 0x00;
+	omb[2] = CMD_EnableIDIFilters;	/*  disable all digital in filters */
+	pci1760_mbxrequest(dev, omb, imb);
+	devpriv->IDIFiltersEn = 0x00;
+
+	omb[0] = 0x00;
+	omb[2] = CMD_EnableIDIPatternMatch;	/*  disable pattern matching */
+	pci1760_mbxrequest(dev, omb, imb);
+	devpriv->IDIPatMatchEn = 0x00;
+
+	omb[0] = 0x00;
+	omb[2] = CMD_SetIDIPatternMatch;	/*  set pattern match value */
+	pci1760_mbxrequest(dev, omb, imb);
+	devpriv->IDIPatMatchValue = 0x00;
+
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci_dio_reset(struct comedi_device * dev)
+{
+	DPRINTK("adv_pci_dio EDBG: BGN: pci171x_reset(...)\n");
+
+	switch (this_board->cardtype) {
+	case TYPE_PCI1730:
+		outb(0, dev->iobase + PCI1730_DO);	/*  clear outputs */
+		outb(0, dev->iobase + PCI1730_DO + 1);
+		outb(0, dev->iobase + PCI1730_IDO);
+		outb(0, dev->iobase + PCI1730_IDO + 1);
+		/* NO break there! */
+	case TYPE_PCI1733:
+		outb(0, dev->iobase + PCI1730_3_INT_EN);	/*  disable interrupts */
+		outb(0x0f, dev->iobase + PCI1730_3_INT_CLR);	/*  clear interrupts */
+		outb(0, dev->iobase + PCI1730_3_INT_RF);	/*  set rising edge trigger */
+		break;
+	case TYPE_PCI1734:
+		outb(0, dev->iobase + PCI1734_IDO);	/*  clear outputs */
+		outb(0, dev->iobase + PCI1734_IDO + 1);
+		outb(0, dev->iobase + PCI1734_IDO + 2);
+		outb(0, dev->iobase + PCI1734_IDO + 3);
+		break;
+
+	case TYPE_PCI1736:
+		outb(0, dev->iobase+PCI1736_IDO);
+		outb(0, dev->iobase+PCI1736_IDO+1);
+		outb(0, dev->iobase+PCI1736_3_INT_EN);  /*  disable interrupts */
+		outb(0x0f, dev->iobase+PCI1736_3_INT_CLR);/*  clear interrupts */
+		outb(0, dev->iobase+PCI1736_3_INT_RF);  /*  set rising edge trigger */
+		break;
+
+	case TYPE_PCI1750:
+	case TYPE_PCI1751:
+		outb(0x88, dev->iobase + PCI1750_ICR);	/*  disable & clear interrupts */
+		break;
+	case TYPE_PCI1752:
+		outw(0, dev->iobase + PCI1752_6_CFC);	/*  disable channel freeze function */
+		outw(0, dev->iobase + PCI1752_IDO);	/*  clear outputs */
+		outw(0, dev->iobase + PCI1752_IDO + 2);
+		outw(0, dev->iobase + PCI1752_IDO2);
+		outw(0, dev->iobase + PCI1752_IDO2 + 2);
+		break;
+	case TYPE_PCI1753E:
+		outb(0x88, dev->iobase + PCI1753E_ICR0);	/*  disable & clear interrupts */
+		outb(0x80, dev->iobase + PCI1753E_ICR1);
+		outb(0x80, dev->iobase + PCI1753E_ICR2);
+		outb(0x80, dev->iobase + PCI1753E_ICR3);
+		/* NO break there! */
+	case TYPE_PCI1753:
+		outb(0x88, dev->iobase + PCI1753_ICR0);	/*  disable & clear interrupts */
+		outb(0x80, dev->iobase + PCI1753_ICR1);
+		outb(0x80, dev->iobase + PCI1753_ICR2);
+		outb(0x80, dev->iobase + PCI1753_ICR3);
+		break;
+	case TYPE_PCI1754:
+		outw(0x08, dev->iobase + PCI1754_6_ICR0);	/*  disable and clear interrupts */
+		outw(0x08, dev->iobase + PCI1754_6_ICR1);
+		outw(0x08, dev->iobase + PCI1754_ICR2);
+		outw(0x08, dev->iobase + PCI1754_ICR3);
+		break;
+	case TYPE_PCI1756:
+		outw(0, dev->iobase + PCI1752_6_CFC);	/*  disable channel freeze function */
+		outw(0x08, dev->iobase + PCI1754_6_ICR0);	/*  disable and clear interrupts */
+		outw(0x08, dev->iobase + PCI1754_6_ICR1);
+		outw(0, dev->iobase + PCI1756_IDO);	/*  clear outputs */
+		outw(0, dev->iobase + PCI1756_IDO + 2);
+		break;
+	case TYPE_PCI1760:
+		pci1760_reset(dev);
+		break;
+	case TYPE_PCI1762:
+		outw(0x0101, dev->iobase + PCI1762_ICR);	/*  disable & clear interrupts */
+		break;
+	}
+
+	DPRINTK("adv_pci_dio EDBG: END: pci171x_reset(...)\n");
+
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci1760_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	int subdev = 0;
+
+	s = dev->subdevices + subdev;
+	s->type = COMEDI_SUBD_DI;
+	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
+	s->n_chan = 8;
+	s->maxdata = 1;
+	s->len_chanlist = 8;
+	s->range_table = &range_digital;
+	s->insn_bits = pci1760_insn_bits_di;
+	subdev++;
+
+	s = dev->subdevices + subdev;
+	s->type = COMEDI_SUBD_DO;
+	s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+	s->n_chan = 8;
+	s->maxdata = 1;
+	s->len_chanlist = 8;
+	s->range_table = &range_digital;
+	s->state = 0;
+	s->insn_bits = pci1760_insn_bits_do;
+	subdev++;
+
+	s = dev->subdevices + subdev;
+	s->type = COMEDI_SUBD_TIMER;
+	s->subdev_flags = SDF_WRITABLE | SDF_LSAMPL;
+	s->n_chan = 2;
+	s->maxdata = 0xffffffff;
+	s->len_chanlist = 2;
+/*       s->insn_config=pci1760_insn_pwm_cfg; */
+	subdev++;
+
+	s = dev->subdevices + subdev;
+	s->type = COMEDI_SUBD_COUNTER;
+	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+	s->n_chan = 8;
+	s->maxdata = 0xffff;
+	s->len_chanlist = 8;
+	s->insn_read = pci1760_insn_cnt_read;
+	s->insn_write = pci1760_insn_cnt_write;
+/*       s->insn_config=pci1760_insn_cnt_cfg; */
+	subdev++;
+
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci_dio_add_di(struct comedi_device * dev, struct comedi_subdevice * s,
+	const struct diosubd_data * d, int subdev)
+{
+	s->type = COMEDI_SUBD_DI;
+	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | d->specflags;
+	if (d->chans > 16)
+		s->subdev_flags |= SDF_LSAMPL;
+	s->n_chan = d->chans;
+	s->maxdata = 1;
+	s->len_chanlist = d->chans;
+	s->range_table = &range_digital;
+	switch (this_board->io_access) {
+	case IO_8b:
+		s->insn_bits = pci_dio_insn_bits_di_b;
+		break;
+	case IO_16b:
+		s->insn_bits = pci_dio_insn_bits_di_w;
+		break;
+	}
+	s->private = (void *)d;
+
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci_dio_add_do(struct comedi_device * dev, struct comedi_subdevice * s,
+	const struct diosubd_data * d, int subdev)
+{
+	s->type = COMEDI_SUBD_DO;
+	s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+	if (d->chans > 16)
+		s->subdev_flags |= SDF_LSAMPL;
+	s->n_chan = d->chans;
+	s->maxdata = 1;
+	s->len_chanlist = d->chans;
+	s->range_table = &range_digital;
+	s->state = 0;
+	switch (this_board->io_access) {
+	case IO_8b:
+		s->insn_bits = pci_dio_insn_bits_do_b;
+		break;
+	case IO_16b:
+		s->insn_bits = pci_dio_insn_bits_do_w;
+		break;
+	}
+	s->private = (void *)d;
+
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+static int CheckAndAllocCard(struct comedi_device * dev, struct comedi_devconfig * it,
+	struct pci_dev *pcidev)
+{
+	struct pci_dio_private *pr, *prev;
+
+	for (pr = pci_priv, prev = NULL; pr != NULL; prev = pr, pr = pr->next) {
+		if (pr->pcidev == pcidev) {
+			return 0;	/*  this card is used, look for another */
+		}
+	}
+
+	if (prev) {
+		devpriv->prev = prev;
+		prev->next = devpriv;
+	} else {
+		pci_priv = devpriv;
+	}
+
+	devpriv->pcidev = pcidev;
+
+	return 1;
+}
+
+/*
+==============================================================================
+*/
+static int pci_dio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	int ret, subdev, n_subdevices, i, j;
+	unsigned long iobase;
+	struct pci_dev *pcidev;
+
+	rt_printk("comedi%d: adv_pci_dio: ", dev->minor);
+
+	if ((ret = alloc_private(dev, sizeof(struct pci_dio_private))) < 0) {
+		rt_printk(", Error: Cann't allocate private memory!\n");
+		return -ENOMEM;
+	}
+
+	for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+		pcidev != NULL;
+		pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+		/*  loop through cards supported by this driver */
+		for (i = 0; i < n_boardtypes; ++i) {
+			if (boardtypes[i].vendor_id != pcidev->vendor)
+				continue;
+			if (boardtypes[i].device_id != pcidev->device)
+				continue;
+			/*  was a particular bus/slot requested? */
+			if (it->options[0] || it->options[1]) {
+				/*  are we on the wrong bus/slot? */
+				if (pcidev->bus->number != it->options[0] ||
+					PCI_SLOT(pcidev->devfn) !=
+					it->options[1]) {
+					continue;
+				}
+			}
+			ret = CheckAndAllocCard(dev, it, pcidev);
+			if (ret != 1) continue;
+			dev->board_ptr = boardtypes + i;
+			break;
+		}
+		if (dev->board_ptr)
+			break;
+	}
+
+	if (!dev->board_ptr) {
+		rt_printk
+			(", Error: Requested type of the card was not found!\n");
+		return -EIO;
+	}
+
+	if (comedi_pci_enable(pcidev, driver_pci_dio.driver_name)) {
+		rt_printk
+			(", Error: Can't enable PCI device and request regions!\n");
+		return -EIO;
+	}
+	iobase = pci_resource_start(pcidev, this_board->main_pci_region);
+	rt_printk(", b:s:f=%d:%d:%d, io=0x%4lx",
+		pcidev->bus->number, PCI_SLOT(pcidev->devfn),
+		PCI_FUNC(pcidev->devfn), iobase);
+
+	dev->iobase = iobase;
+	dev->board_name = this_board->name;
+
+	if (this_board->cardtype == TYPE_PCI1760) {
+		n_subdevices = 4;	/*  8 IDI, 8 IDO, 2 PWM, 8 CNT */
+	} else {
+		n_subdevices = 0;
+		for (i = 0; i < MAX_DI_SUBDEVS; i++)
+			if (this_board->sdi[i].chans)
+				n_subdevices++;
+		for (i = 0; i < MAX_DO_SUBDEVS; i++)
+			if (this_board->sdo[i].chans)
+				n_subdevices++;
+		for (i = 0; i < MAX_DIO_SUBDEVG; i++)
+			n_subdevices += this_board->sdio[i].regs;
+		if (this_board->boardid.chans)
+			n_subdevices++;
+	}
+
+	if ((ret = alloc_subdevices(dev, n_subdevices)) < 0) {
+		rt_printk(", Error: Cann't allocate subdevice memory!\n");
+		return ret;
+	}
+
+	rt_printk(".\n");
+
+	subdev = 0;
+
+	for (i = 0; i < MAX_DI_SUBDEVS; i++)
+		if (this_board->sdi[i].chans) {
+			s = dev->subdevices + subdev;
+			pci_dio_add_di(dev, s, &this_board->sdi[i], subdev);
+			subdev++;
+		}
+
+	for (i = 0; i < MAX_DO_SUBDEVS; i++)
+		if (this_board->sdo[i].chans) {
+			s = dev->subdevices + subdev;
+			pci_dio_add_do(dev, s, &this_board->sdo[i], subdev);
+			subdev++;
+		}
+
+	for (i = 0; i < MAX_DIO_SUBDEVG; i++)
+		for (j = 0; j < this_board->sdio[i].regs; j++) {
+			s = dev->subdevices + subdev;
+			subdev_8255_init(dev, s, NULL,
+				dev->iobase + this_board->sdio[i].addr +
+				SIZE_8255 * j);
+			subdev++;
+		}
+
+	if (this_board->boardid.chans) {
+		s = dev->subdevices + subdev;
+		s->type = COMEDI_SUBD_DI;
+		pci_dio_add_di(dev, s, &this_board->boardid, subdev);
+		subdev++;
+	}
+
+	if (this_board->cardtype == TYPE_PCI1760)
+		pci1760_attach(dev, it);
+
+	devpriv->valid = 1;
+
+	pci_dio_reset(dev);
+
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci_dio_detach(struct comedi_device * dev)
+{
+	int i, j;
+	struct comedi_subdevice *s;
+	int subdev;
+
+	if (dev->private) {
+		if (devpriv->valid) {
+			pci_dio_reset(dev);
+		}
+
+		/* This shows the silliness of using this kind of
+		 * scheme for numbering subdevices.  Don't do it.  --ds */
+		subdev = 0;
+		for (i = 0; i < MAX_DI_SUBDEVS; i++) {
+			if (this_board->sdi[i].chans) {
+				subdev++;
+			}
+		}
+		for (i = 0; i < MAX_DO_SUBDEVS; i++) {
+			if (this_board->sdo[i].chans) {
+				subdev++;
+			}
+		}
+		for (i = 0; i < MAX_DIO_SUBDEVG; i++) {
+			for (j = 0; j < this_board->sdio[i].regs; j++) {
+				s = dev->subdevices + subdev;
+				subdev_8255_cleanup(dev, s);
+				subdev++;
+			}
+		}
+
+		for (i = 0; i < dev->n_subdevices; i++) {
+			s = dev->subdevices + i;
+			s->private = NULL;
+		}
+
+		if (devpriv->pcidev) {
+			if (dev->iobase) {
+				comedi_pci_disable(devpriv->pcidev);
+			}
+			pci_dev_put(devpriv->pcidev);
+		}
+
+		if (devpriv->prev) {
+			devpriv->prev->next = devpriv->next;
+		} else {
+			pci_priv = devpriv->next;
+		}
+		if (devpriv->next) {
+			devpriv->next->prev = devpriv->prev;
+		}
+	}
+
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+COMEDI_PCI_INITCLEANUP(driver_pci_dio, pci_dio_pci_table);
+/*
+==============================================================================
+*/
diff --git a/drivers/staging/comedi/drivers/aio_aio12_8.c b/drivers/staging/comedi/drivers/aio_aio12_8.c
new file mode 100644
index 0000000..b97b4d8
--- /dev/null
+++ b/drivers/staging/comedi/drivers/aio_aio12_8.c
@@ -0,0 +1,226 @@
+/*
+
+    comedi/drivers/aio_aio12_8.c
+
+    Driver for Acces I/O Products PC-104 AIO12-8 Analog I/O Board
+    Copyright (C) 2006 C&C Technologies, 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 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.
+*/
+
+/*
+
+Driver: aio_aio12_8
+Description: Acces I/O Products PC-104 AIO12-8 Analog I/O Board
+Author: Pablo Mejia <pablo.mejia@cctechnol.com>
+Devices:
+ [Acces I/O] PC-104 AIO12-8
+Status: experimental
+
+Configuration Options:
+  [0] - I/O port base address
+
+Notes:
+
+  Only synchronous operations are supported.
+
+*/
+
+#include "../comedidev.h"
+#include <linux/ioport.h>
+#include "8255.h"
+
+#define AIO12_8_STATUS			0x00
+#define AIO12_8_INTERRUPT		0x01
+#define AIO12_8_ADC			0x02
+#define AIO12_8_DAC_0			0x04
+#define AIO12_8_DAC_1			0x06
+#define AIO12_8_DAC_2			0x08
+#define AIO12_8_DAC_3			0x0A
+#define AIO12_8_COUNTER_0		0x0C
+#define AIO12_8_COUNTER_1		0x0D
+#define AIO12_8_COUNTER_2		0x0E
+#define AIO12_8_COUNTER_CONTROL		0x0F
+#define AIO12_8_DIO_0			0x10
+#define AIO12_8_DIO_1			0x11
+#define AIO12_8_DIO_2			0x12
+#define AIO12_8_DIO_STATUS		0x13
+#define AIO12_8_DIO_CONTROL		0x14
+#define AIO12_8_ADC_TRIGGER_CONTROL	0x15
+#define AIO12_8_TRIGGER			0x16
+#define AIO12_8_POWER			0x17
+
+#define STATUS_ADC_EOC			0x80
+
+#define ADC_MODE_NORMAL			0x00
+#define ADC_MODE_INTERNAL_CLOCK		0x40
+#define ADC_MODE_STANDBY		0x80
+#define ADC_MODE_POWERDOWN		0xC0
+
+#define DAC_ENABLE			0x18
+
+struct aio12_8_boardtype {
+	const char *name;
+};
+
+static const struct aio12_8_boardtype board_types[] = {
+	{
+      name:	"aio_aio12_8"},
+};
+
+#define	thisboard	((const struct aio12_8_boardtype  *) dev->board_ptr)
+
+struct aio12_8_private {
+	unsigned int ao_readback[4];
+};
+
+#define devpriv	((struct aio12_8_private *) dev->private)
+
+static int aio_aio12_8_ai_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n;
+	unsigned char control =
+		ADC_MODE_NORMAL |
+		(CR_RANGE(insn->chanspec) << 3) | CR_CHAN(insn->chanspec);
+
+	//read status to clear EOC latch
+	inb(dev->iobase + AIO12_8_STATUS);
+
+	for (n = 0; n < insn->n; n++) {
+		int timeout = 5;
+
+		// Setup and start conversion
+		outb(control, dev->iobase + AIO12_8_ADC);
+
+		// Wait for conversion to complete
+		while (timeout &&
+			!(inb(dev->iobase + AIO12_8_STATUS) & STATUS_ADC_EOC)) {
+			timeout--;
+			printk("timeout %d\n", timeout);
+			comedi_udelay(1);
+		}
+		if (timeout == 0) {
+			comedi_error(dev, "ADC timeout");
+			return -EIO;
+		}
+
+		data[n] = inw(dev->iobase + AIO12_8_ADC) & 0x0FFF;
+	}
+	return n;
+}
+
+static int aio_aio12_8_ao_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int val = devpriv->ao_readback[CR_CHAN(insn->chanspec)];
+
+	for (i = 0; i < insn->n; i++)
+		data[i] = val;
+	return insn->n;
+}
+
+static int aio_aio12_8_ao_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+	unsigned long port = dev->iobase + AIO12_8_DAC_0 + (2 * chan);
+
+	//enable DACs
+	outb(0x01, dev->iobase + DAC_ENABLE);
+
+	for (i = 0; i < insn->n; i++) {
+		outb(data[i] & 0xFF, port);	// LSB
+		outb((data[i] >> 8) & 0x0F, port + 1);	// MSB
+		devpriv->ao_readback[chan] = data[i];
+	}
+	return insn->n;
+}
+
+static const struct comedi_lrange range_aio_aio12_8 = {
+	4,
+	{
+			UNI_RANGE(5),
+			BIP_RANGE(5),
+			UNI_RANGE(10),
+			BIP_RANGE(10),
+		}
+};
+
+static int aio_aio12_8_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	int iobase;
+	struct comedi_subdevice *s;
+
+	iobase = it->options[0];
+	if (!request_region(iobase, 24, "aio_aio12_8")) {
+		printk("I/O port conflict");
+		return -EIO;
+	}
+
+	dev->board_name = thisboard->name;
+
+	dev->iobase = iobase;
+
+	if (alloc_private(dev, sizeof(struct aio12_8_private)) < 0)
+		return -ENOMEM;
+
+	if (alloc_subdevices(dev, 3) < 0)
+		return -ENOMEM;
+
+	s = &dev->subdevices[0];
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
+	s->n_chan = 8;
+	s->maxdata = (1 << 12) - 1;
+	s->range_table = &range_aio_aio12_8;
+	s->insn_read = aio_aio12_8_ai_read;
+
+	s = &dev->subdevices[1];
+	s->type = COMEDI_SUBD_AO;
+	s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_DIFF;
+	s->n_chan = 4;
+	s->maxdata = (1 << 12) - 1;
+	s->range_table = &range_aio_aio12_8;
+	s->insn_read = aio_aio12_8_ao_read;
+	s->insn_write = aio_aio12_8_ao_write;
+
+	s = &dev->subdevices[2];
+	subdev_8255_init(dev, s, NULL, dev->iobase + AIO12_8_DIO_0);
+
+	return 0;
+}
+
+static int aio_aio12_8_detach(struct comedi_device * dev)
+{
+	subdev_8255_cleanup(dev, &dev->subdevices[2]);
+	if (dev->iobase)
+		release_region(dev->iobase, 24);
+	return 0;
+}
+
+static struct comedi_driver driver_aio_aio12_8 = {
+      driver_name:"aio_aio12_8",
+      module:THIS_MODULE,
+      attach:aio_aio12_8_attach,
+      detach:aio_aio12_8_detach,
+      board_name:&board_types[0].name,
+      num_names:1,
+      offset:sizeof(struct aio12_8_boardtype),
+};
+
+COMEDI_INITCLEANUP(driver_aio_aio12_8);
diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c
new file mode 100644
index 0000000..9160fdf
--- /dev/null
+++ b/drivers/staging/comedi/drivers/aio_iiro_16.c
@@ -0,0 +1,177 @@
+/*
+
+    comedi/drivers/aio_iiro_16.c
+
+    Driver for Acces I/O Products PC-104 AIO-IIRO-16 Digital I/O board
+    Copyright (C) 2006 C&C Technologies, 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 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.
+*/
+
+/*
+
+Driver: aio_iiro_16
+Description: Acces I/O Products PC-104 IIRO16 Relay And Isolated Input Board
+Author: Zachary Ware <zach.ware@cctechnol.com>
+Devices:
+ [Acces I/O] PC-104 AIO12-8
+Status: experimental
+
+Configuration Options:
+  [0] - I/O port base address
+
+*/
+
+#include "../comedidev.h"
+#include <linux/ioport.h>
+
+#define AIO_IIRO_16_SIZE	0x08
+#define AIO_IIRO_16_RELAY_0_7	0x00
+#define AIO_IIRO_16_INPUT_0_7	0x01
+#define AIO_IIRO_16_IRQ		0x02
+#define AIO_IIRO_16_RELAY_8_15	0x04
+#define AIO_IIRO_16_INPUT_8_15	0x05
+
+struct aio_iiro_16_board {
+	const char *name;
+	int do_;
+	int di;
+};
+
+static const struct aio_iiro_16_board aio_iiro_16_boards[] = {
+	{
+	      name:	"aio_iiro_16",
+	      di:	16,
+      do_:	16},
+};
+
+#define	thisboard	((const struct aio_iiro_16_board *) dev->board_ptr)
+
+struct aio_iiro_16_private {
+	int data;
+	struct pci_dev *pci_dev;
+	unsigned int ao_readback[2];
+};
+
+#define	devpriv	((struct aio_iiro_16_private *) dev->private)
+
+static int aio_iiro_16_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+
+static int aio_iiro_16_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver_aio_iiro_16 = {
+      driver_name:"aio_iiro_16",
+      module:THIS_MODULE,
+      attach:aio_iiro_16_attach,
+      detach:aio_iiro_16_detach,
+      board_name:&aio_iiro_16_boards[0].name,
+      offset:sizeof(struct aio_iiro_16_board),
+      num_names:sizeof(aio_iiro_16_boards) / sizeof(struct aio_iiro_16_board),
+};
+
+static int aio_iiro_16_dio_insn_bits_read(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+static int aio_iiro_16_dio_insn_bits_write(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+static int aio_iiro_16_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	int iobase;
+	struct comedi_subdevice *s;
+
+	printk("comedi%d: aio_iiro_16: ", dev->minor);
+
+	dev->board_name = thisboard->name;
+
+	iobase = it->options[0];
+
+	if (!request_region(iobase, AIO_IIRO_16_SIZE, dev->board_name)) {
+		printk("I/O port conflict");
+		return -EIO;
+	}
+
+	dev->iobase = iobase;
+
+	if (alloc_private(dev, sizeof(struct aio_iiro_16_private)) < 0)
+		return -ENOMEM;
+
+	if (alloc_subdevices(dev, 2) < 0)
+		return -ENOMEM;
+
+	s = dev->subdevices + 0;
+	s->type = COMEDI_SUBD_DIO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->n_chan = 16;
+	s->maxdata = 1;
+	s->range_table = &range_digital;
+	s->insn_bits = aio_iiro_16_dio_insn_bits_write;
+
+	s = dev->subdevices + 1;
+	s->type = COMEDI_SUBD_DIO;
+	s->subdev_flags = SDF_READABLE;
+	s->n_chan = 16;
+	s->maxdata = 1;
+	s->range_table = &range_digital;
+	s->insn_bits = aio_iiro_16_dio_insn_bits_read;
+
+	printk("attached\n");
+
+	return 1;
+}
+
+static int aio_iiro_16_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: aio_iiro_16: remove\n", dev->minor);
+
+	if (dev->iobase)
+		release_region(dev->iobase, AIO_IIRO_16_SIZE);
+
+	return 0;
+}
+
+static int aio_iiro_16_dio_insn_bits_write(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= data[0] & data[1];
+		outb(s->state & 0xff, dev->iobase + AIO_IIRO_16_RELAY_0_7);
+		outb((s->state >> 8) & 0xff,
+			dev->iobase + AIO_IIRO_16_RELAY_8_15);
+	}
+
+	data[1] = s->state;
+
+	return 2;
+}
+
+static int aio_iiro_16_dio_insn_bits_read(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	data[1] = 0;
+	data[1] |= inb(dev->iobase + AIO_IIRO_16_INPUT_0_7);
+	data[1] |= inb(dev->iobase + AIO_IIRO_16_INPUT_8_15) << 8;
+
+	return 2;
+}
+
+COMEDI_INITCLEANUP(driver_aio_iiro_16);
diff --git a/drivers/staging/comedi/drivers/am9513.h b/drivers/staging/comedi/drivers/am9513.h
new file mode 100644
index 0000000..f533cf1
--- /dev/null
+++ b/drivers/staging/comedi/drivers/am9513.h
@@ -0,0 +1,79 @@
+/*
+    module/am9513.h
+    value added preprocessor definitions for Am9513 timer chip
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 1998 David A. Schleef <ds@schleef.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.
+
+    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 _AM9513_H_
+#define _AM9513_H_
+
+#if 0
+
+/*
+ *	Before including this file, the following need to be defined:
+ */
+#define Am9513_8BITBUS xxx
+/* or */
+#define Am9513_16BITBUS xxx
+
+#define Am9513_output_control(a)	xxx
+#define Am9513_input_status()		xxx
+#define Am9513_output_data(a)		xxx
+#define Am9513_input_data()		xxx
+
+#endif
+
+/*
+ *
+ */
+
+#ifdef Am9513_8BITBUS
+
+#define Am9513_write_register(reg,val)				\
+	do{							\
+		Am9513_output_control(reg);			\
+		Am9513_output_data(val>>8);			\
+		Am9513_output_data(val&0xff);			\
+	}while(0)
+
+#define Am9513_read_register(reg,val)				\
+	do{							\
+		Am9513_output_control(reg);			\
+		val=Am9513_input_data()<<8;			\
+		val|=Am9513_input_data();			\
+	}while(0)
+
+#else /* Am9513_16BITBUS */
+
+#define Am9513_write_register(reg,val)				\
+	do{							\
+		Am9513_output_control(reg);			\
+		Am9513_output_data(val);			\
+	}while(0)
+
+#define Am9513_read_register(reg,val)				\
+	do{							\
+		Am9513_output_control(reg);			\
+		val=Am9513_input_data();			\
+	}while(0)
+
+#endif
+
+#endif
diff --git a/drivers/staging/comedi/drivers/amcc_s5933.h b/drivers/staging/comedi/drivers/amcc_s5933.h
new file mode 100644
index 0000000..aceffce
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amcc_s5933.h
@@ -0,0 +1,172 @@
+/*
+    comedi/drivers/amcc_s5933.h
+
+    Stuff for AMCC S5933 PCI Controller
+
+    Author: Michal Dobes <dobes@tesnet.cz>
+
+    Inspirated from general-purpose AMCC S5933 PCI Matchmaker driver
+    made by Andrea Cisternino  <acister@pcape1.pi.infn.it>
+    and as result of espionage from MITE code made by David A. Schleef.
+    Thanks to AMCC for their on-line documentation and bus master DMA
+    example.
+*/
+
+#ifndef _AMCC_S5933_H_
+#define _AMCC_S5933_H_
+
+/****************************************************************************/
+/* AMCC Operation Register Offsets - PCI                                    */
+/****************************************************************************/
+
+#define AMCC_OP_REG_OMB1         0x00
+#define AMCC_OP_REG_OMB2         0x04
+#define AMCC_OP_REG_OMB3         0x08
+#define AMCC_OP_REG_OMB4         0x0c
+#define AMCC_OP_REG_IMB1         0x10
+#define AMCC_OP_REG_IMB2         0x14
+#define AMCC_OP_REG_IMB3         0x18
+#define AMCC_OP_REG_IMB4         0x1c
+#define AMCC_OP_REG_FIFO         0x20
+#define AMCC_OP_REG_MWAR         0x24
+#define AMCC_OP_REG_MWTC         0x28
+#define AMCC_OP_REG_MRAR         0x2c
+#define AMCC_OP_REG_MRTC         0x30
+#define AMCC_OP_REG_MBEF         0x34
+#define AMCC_OP_REG_INTCSR       0x38
+#define  AMCC_OP_REG_INTCSR_SRC  (AMCC_OP_REG_INTCSR + 2)	/* INT source */
+#define  AMCC_OP_REG_INTCSR_FEC  (AMCC_OP_REG_INTCSR + 3)	/* FIFO ctrl */
+#define AMCC_OP_REG_MCSR         0x3c
+#define  AMCC_OP_REG_MCSR_NVDATA (AMCC_OP_REG_MCSR + 2)	/* Data in byte 2 */
+#define  AMCC_OP_REG_MCSR_NVCMD  (AMCC_OP_REG_MCSR + 3)	/* Command in byte 3 */
+
+#define AMCC_FIFO_DEPTH_DWORD	8
+#define AMCC_FIFO_DEPTH_BYTES	(8 * sizeof (u32))
+
+/****************************************************************************/
+/* AMCC - PCI Interrupt Control/Status Register                            */
+/****************************************************************************/
+#define INTCSR_OUTBOX_BYTE(x)	((x) & 0x3)
+#define INTCSR_OUTBOX_SELECT(x)	(((x) & 0x3) << 2)
+#define INTCSR_OUTBOX_EMPTY_INT	0x10	// enable outbox empty interrupt
+#define INTCSR_INBOX_BYTE(x)	(((x) & 0x3) << 8)
+#define INTCSR_INBOX_SELECT(x)	(((x) & 0x3) << 10)
+#define INTCSR_INBOX_FULL_INT	0x1000	// enable inbox full interrupt
+#define INTCSR_INBOX_INTR_STATUS	0x20000	// read, or write clear inbox full interrupt
+#define INTCSR_INTR_ASSERTED	0x800000	// read only, interrupt asserted
+
+/****************************************************************************/
+/* AMCC - PCI non-volatile ram command register (byte 3 of master control/status register) */
+/****************************************************************************/
+#define MCSR_NV_LOAD_LOW_ADDR	0x0
+#define MCSR_NV_LOAD_HIGH_ADDR	0x20
+#define MCSR_NV_WRITE	0x40
+#define MCSR_NV_READ	0x60
+#define MCSR_NV_MASK	0x60
+#define MCSR_NV_ENABLE	0x80
+#define MCSR_NV_BUSY	MCSR_NV_ENABLE
+
+/****************************************************************************/
+/* AMCC Operation Registers Size - PCI                                      */
+/****************************************************************************/
+
+#define AMCC_OP_REG_SIZE	 64	/* in bytes */
+
+/****************************************************************************/
+/* AMCC Operation Register Offsets - Add-on                                 */
+/****************************************************************************/
+
+#define AMCC_OP_REG_AIMB1         0x00
+#define AMCC_OP_REG_AIMB2         0x04
+#define AMCC_OP_REG_AIMB3         0x08
+#define AMCC_OP_REG_AIMB4         0x0c
+#define AMCC_OP_REG_AOMB1         0x10
+#define AMCC_OP_REG_AOMB2         0x14
+#define AMCC_OP_REG_AOMB3         0x18
+#define AMCC_OP_REG_AOMB4         0x1c
+#define AMCC_OP_REG_AFIFO         0x20
+#define AMCC_OP_REG_AMWAR         0x24
+#define AMCC_OP_REG_APTA          0x28
+#define AMCC_OP_REG_APTD          0x2c
+#define AMCC_OP_REG_AMRAR         0x30
+#define AMCC_OP_REG_AMBEF         0x34
+#define AMCC_OP_REG_AINT          0x38
+#define AMCC_OP_REG_AGCSTS        0x3c
+#define AMCC_OP_REG_AMWTC         0x58
+#define AMCC_OP_REG_AMRTC         0x5c
+
+/****************************************************************************/
+/* AMCC - Add-on General Control/Status Register                            */
+/****************************************************************************/
+
+#define AGCSTS_CONTROL_MASK	0xfffff000
+#define  AGCSTS_NV_ACC_MASK	0xe0000000
+#define  AGCSTS_RESET_MASK	0x0e000000
+#define  AGCSTS_NV_DA_MASK	0x00ff0000
+#define  AGCSTS_BIST_MASK	0x0000f000
+#define AGCSTS_STATUS_MASK	0x000000ff
+#define  AGCSTS_TCZERO_MASK	0x000000c0
+#define  AGCSTS_FIFO_ST_MASK	0x0000003f
+
+#define AGCSTS_RESET_MBFLAGS	0x08000000
+#define AGCSTS_RESET_P2A_FIFO	0x04000000
+#define AGCSTS_RESET_A2P_FIFO	0x02000000
+#define AGCSTS_RESET_FIFOS	(AGCSTS_RESET_A2P_FIFO | AGCSTS_RESET_P2A_FIFO)
+
+#define AGCSTS_A2P_TCOUNT	0x00000080
+#define AGCSTS_P2A_TCOUNT	0x00000040
+
+#define AGCSTS_FS_P2A_EMPTY	0x00000020
+#define AGCSTS_FS_P2A_HALF	0x00000010
+#define AGCSTS_FS_P2A_FULL	0x00000008
+
+#define AGCSTS_FS_A2P_EMPTY	0x00000004
+#define AGCSTS_FS_A2P_HALF	0x00000002
+#define AGCSTS_FS_A2P_FULL	0x00000001
+
+/****************************************************************************/
+/* AMCC - Add-on Interrupt Control/Status Register                            */
+/****************************************************************************/
+
+#define AINT_INT_MASK		0x00ff0000
+#define AINT_SEL_MASK		0x0000ffff
+#define  AINT_IS_ENSEL_MASK	0x00001f1f
+
+#define AINT_INT_ASSERTED	0x00800000
+#define AINT_BM_ERROR		0x00200000
+#define AINT_BIST_INT		0x00100000
+
+#define AINT_RT_COMPLETE	0x00080000
+#define AINT_WT_COMPLETE	0x00040000
+
+#define AINT_OUT_MB_INT		0x00020000
+#define AINT_IN_MB_INT		0x00010000
+
+#define AINT_READ_COMPL		0x00008000
+#define AINT_WRITE_COMPL	0x00004000
+
+#define AINT_OMB_ENABLE 	0x00001000
+#define AINT_OMB_SELECT 	0x00000c00
+#define AINT_OMB_BYTE		0x00000300
+
+#define AINT_IMB_ENABLE 	0x00000010
+#define AINT_IMB_SELECT 	0x0000000c
+#define AINT_IMB_BYTE		0x00000003
+
+// these are bits from various different registers, needs cleanup XXX
+/* Enable Bus Mastering */
+#define EN_A2P_TRANSFERS	0x00000400
+/* FIFO Flag Reset */
+#define RESET_A2P_FLAGS		0x04000000L
+/* FIFO Relative Priority */
+#define A2P_HI_PRIORITY		0x00000100L
+/* Identify Interrupt Sources */
+#define ANY_S593X_INT		0x00800000L
+#define READ_TC_INT		0x00080000L
+#define WRITE_TC_INT		0x00040000L
+#define IN_MB_INT		0x00020000L
+#define MASTER_ABORT_INT	0x00100000L
+#define TARGET_ABORT_INT	0x00200000L
+#define BUS_MASTER_INT		0x00200000L
+
+#endif
diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c
new file mode 100644
index 0000000..8555e27
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amplc_dio200.c
@@ -0,0 +1,1483 @@
+/*
+    comedi/drivers/amplc_dio200.c
+    Driver for Amplicon PC272E and PCI272 DIO boards.
+    (Support for other boards in Amplicon 200 series may be added at
+    a later date, e.g. PCI215.)
+
+    Copyright (C) 2005 MEV Ltd. <http://www.mev.co.uk/>
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 1998,2000 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: amplc_dio200
+Description: Amplicon 200 Series Digital I/O
+Author: Ian Abbott <abbotti@mev.co.uk>
+Devices: [Amplicon] PC212E (pc212e), PC214E (pc214e), PC215E (pc215e),
+  PCI215 (pci215 or amplc_dio200), PC218E (pc218e), PC272E (pc272e),
+  PCI272 (pci272 or amplc_dio200)
+Updated: Wed, 22 Oct 2008 13:36:02 +0100
+Status: works
+
+Configuration options - PC212E, PC214E, PC215E, PC218E, PC272E:
+  [0] - I/O port base address
+  [1] - IRQ (optional, but commands won't work without it)
+
+Configuration options - PCI215, PCI272:
+  [0] - PCI bus of device (optional)
+  [1] - PCI slot of device (optional)
+  If bus/slot is not specified, the first available PCI device will
+  be used.
+
+Passing a zero for an option is the same as leaving it unspecified.
+
+SUBDEVICES
+
+                    PC218E         PC212E      PC215E/PCI215
+                 -------------  -------------  -------------
+  Subdevices           7              6              5
+   0                 CTR-X1         PPI-X          PPI-X
+   1                 CTR-X2         CTR-Y1         PPI-Y
+   2                 CTR-Y1         CTR-Y2         CTR-Z1
+   3                 CTR-Y2         CTR-Z1         CTR-Z2
+   4                 CTR-Z1         CTR-Z2       INTERRUPT
+   5                 CTR-Z2       INTERRUPT
+   6               INTERRUPT
+
+                    PC214E      PC272E/PCI272
+                 -------------  -------------
+  Subdevices           4              4
+   0                 PPI-X          PPI-X
+   1                 PPI-Y          PPI-Y
+   2                 CTR-Z1*        PPI-Z
+   3               INTERRUPT*     INTERRUPT
+
+Each PPI is a 8255 chip providing 24 DIO channels.  The DIO channels
+are configurable as inputs or outputs in four groups:
+
+  Port A  - channels  0 to  7
+  Port B  - channels  8 to 15
+  Port CL - channels 16 to 19
+  Port CH - channels 20 to 23
+
+Only mode 0 of the 8255 chips is supported.
+
+Each CTR is a 8254 chip providing 3 16-bit counter channels.  Each
+channel is configured individually with INSN_CONFIG instructions.  The
+specific type of configuration instruction is specified in data[0].
+Some configuration instructions expect an additional parameter in
+data[1]; others return a value in data[1].  The following configuration
+instructions are supported:
+
+  INSN_CONFIG_SET_COUNTER_MODE.  Sets the counter channel's mode and
+    BCD/binary setting specified in data[1].
+
+  INSN_CONFIG_8254_READ_STATUS.  Reads the status register value for the
+    counter channel into data[1].
+
+  INSN_CONFIG_SET_CLOCK_SRC.  Sets the counter channel's clock source as
+    specified in data[1] (this is a hardware-specific value).  Not
+    supported on PC214E.  For the other boards, valid clock sources are
+    0 to 7 as follows:
+
+      0.  CLK n, the counter channel's dedicated CLK input from the SK1
+        connector.  (N.B. for other values, the counter channel's CLKn
+        pin on the SK1 connector is an output!)
+      1.  Internal 10 MHz clock.
+      2.  Internal 1 MHz clock.
+      3.  Internal 100 kHz clock.
+      4.  Internal 10 kHz clock.
+      5.  Internal 1 kHz clock.
+      6.  OUT n-1, the output of counter channel n-1 (see note 1 below).
+      7.  Ext Clock, the counter chip's dedicated Ext Clock input from
+        the SK1 connector.  This pin is shared by all three counter
+        channels on the chip.
+
+  INSN_CONFIG_GET_CLOCK_SRC.  Returns the counter channel's current
+    clock source in data[1].  For internal clock sources, data[2] is set
+    to the period in ns.
+
+  INSN_CONFIG_SET_GATE_SRC.  Sets the counter channel's gate source as
+    specified in data[2] (this is a hardware-specific value).  Not
+    supported on PC214E.  For the other boards, valid gate sources are 0
+    to 7 as follows:
+
+      0.  VCC (internal +5V d.c.), i.e. gate permanently enabled.
+      1.  GND (internal 0V d.c.), i.e. gate permanently disabled.
+      2.  GAT n, the counter channel's dedicated GAT input from the SK1
+        connector.  (N.B. for other values, the counter channel's GATn
+        pin on the SK1 connector is an output!)
+      3.  /OUT n-2, the inverted output of counter channel n-2 (see note
+        2 below).
+      4.  Reserved.
+      5.  Reserved.
+      6.  Reserved.
+      7.  Reserved.
+
+  INSN_CONFIG_GET_GATE_SRC.  Returns the counter channel's current gate
+    source in data[2].
+
+Clock and gate interconnection notes:
+
+  1.  Clock source OUT n-1 is the output of the preceding channel on the
+  same counter subdevice if n > 0, or the output of channel 2 on the
+  preceding counter subdevice (see note 3) if n = 0.
+
+  2.  Gate source /OUT n-2 is the inverted output of channel 0 on the
+  same counter subdevice if n = 2, or the inverted output of channel n+1
+  on the preceding counter subdevice (see note 3) if n < 2.
+
+  3.  The counter subdevices are connected in a ring, so the highest
+  counter subdevice precedes the lowest.
+
+The 'INTERRUPT' subdevice pretends to be a digital input subdevice.  The
+digital inputs come from the interrupt status register.  The number of
+channels matches the number of interrupt sources.  The PC214E does not
+have an interrupt status register; see notes on 'INTERRUPT SOURCES'
+below.
+
+INTERRUPT SOURCES
+
+                    PC218E         PC212E      PC215E/PCI215
+                 -------------  -------------  -------------
+  Sources              6              6              6
+   0              CTR-X1-OUT      PPI-X-C0       PPI-X-C0
+   1              CTR-X2-OUT      PPI-X-C3       PPI-X-C3
+   2              CTR-Y1-OUT     CTR-Y1-OUT      PPI-Y-C0
+   3              CTR-Y2-OUT     CTR-Y2-OUT      PPI-Y-C3
+   4              CTR-Z1-OUT     CTR-Z1-OUT     CTR-Z1-OUT
+   5              CTR-Z2-OUT     CTR-Z2-OUT     CTR-Z2-OUT
+
+                    PC214E      PC272E/PCI272
+                 -------------  -------------
+  Sources              1              6
+   0               JUMPER-J5      PPI-X-C0
+   1                              PPI-X-C3
+   2                              PPI-Y-C0
+   3                              PPI-Y-C3
+   4                              PPI-Z-C0
+   5                              PPI-Z-C3
+
+When an interrupt source is enabled in the interrupt source enable
+register, a rising edge on the source signal latches the corresponding
+bit to 1 in the interrupt status register.
+
+When the interrupt status register value as a whole (actually, just the
+6 least significant bits) goes from zero to non-zero, the board will
+generate an interrupt.  For level-triggered hardware interrupts (PCI
+card), the interrupt will remain asserted until the interrupt status
+register is cleared to zero.  For edge-triggered hardware interrupts
+(ISA card), no further interrupts will occur until the interrupt status
+register is cleared to zero.  To clear a bit to zero in the interrupt
+status register, the corresponding interrupt source must be disabled
+in the interrupt source enable register (there is no separate interrupt
+clear register).
+
+The PC214E does not have an interrupt source enable register or an
+interrupt status register; its 'INTERRUPT' subdevice has a single
+channel and its interrupt source is selected by the position of jumper
+J5.
+
+COMMANDS
+
+The driver supports a read streaming acquisition command on the
+'INTERRUPT' subdevice.  The channel list selects the interrupt sources
+to be enabled.  All channels will be sampled together (convert_src ==
+TRIG_NOW).  The scan begins a short time after the hardware interrupt
+occurs, subject to interrupt latencies (scan_begin_src == TRIG_EXT,
+scan_begin_arg == 0).  The value read from the interrupt status register
+is packed into a short value, one bit per requested channel, in the
+order they appear in the channel list.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+#include "8255.h"
+#include "8253.h"
+
+#define DIO200_DRIVER_NAME	"amplc_dio200"
+
+/* PCI IDs */
+/* #define PCI_VENDOR_ID_AMPLICON 0x14dc */
+#define PCI_DEVICE_ID_AMPLICON_PCI272 0x000a
+#define PCI_DEVICE_ID_AMPLICON_PCI215 0x000b
+#define PCI_DEVICE_ID_INVALID 0xffff
+
+/* 200 series registers */
+#define DIO200_IO_SIZE		0x20
+#define DIO200_XCLK_SCE		0x18	/* Group X clock selection register */
+#define DIO200_YCLK_SCE		0x19	/* Group Y clock selection register */
+#define DIO200_ZCLK_SCE		0x1a	/* Group Z clock selection register */
+#define DIO200_XGAT_SCE		0x1b	/* Group X gate selection register */
+#define DIO200_YGAT_SCE		0x1c	/* Group Y gate selection register */
+#define DIO200_ZGAT_SCE		0x1d	/* Group Z gate selection register */
+#define DIO200_INT_SCE		0x1e	/* Interrupt enable/status register */
+
+/*
+ * Macros for constructing value for DIO_200_?CLK_SCE and
+ * DIO_200_?GAT_SCE registers:
+ *
+ * 'which' is: 0 for CTR-X1, CTR-Y1, CTR-Z1; 1 for CTR-X2, CTR-Y2 or CTR-Z2.
+ * 'chan' is the channel: 0, 1 or 2.
+ * 'source' is the signal source: 0 to 7.
+ */
+#define CLK_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | (source))
+#define GAT_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | (source))
+
+/*
+ * Periods of the internal clock sources in nanoseconds.
+ */
+static const unsigned clock_period[8] = {
+	0,			/* dedicated clock input/output pin */
+	100,			/* 10 MHz */
+	1000,			/* 1 MHz */
+	10000,			/* 100 kHz */
+	100000,			/* 10 kHz */
+	1000000,		/* 1 kHz */
+	0,			/* OUT N-1 */
+	0			/* group clock input pin */
+};
+
+/*
+ * Board descriptions.
+ */
+
+enum dio200_bustype { isa_bustype, pci_bustype };
+
+enum dio200_model {
+	pc212e_model,
+	pc214e_model,
+	pc215e_model, pci215_model,
+	pc218e_model,
+	pc272e_model, pci272_model,
+	anypci_model
+};
+
+enum dio200_layout {
+	pc212_layout,
+	pc214_layout,
+	pc215_layout,
+	pc218_layout,
+	pc272_layout
+};
+
+struct dio200_board {
+	const char *name;
+	unsigned short devid;
+	enum dio200_bustype bustype;
+	enum dio200_model model;
+	enum dio200_layout layout;
+};
+
+static const struct dio200_board dio200_boards[] = {
+	{
+	      name:	"pc212e",
+	      bustype:	isa_bustype,
+	      model:	pc212e_model,
+	      layout:	pc212_layout,
+		},
+	{
+	      name:	"pc214e",
+	      bustype:	isa_bustype,
+	      model:	pc214e_model,
+	      layout:	pc214_layout,
+		},
+	{
+	      name:	"pc215e",
+	      bustype:	isa_bustype,
+	      model:	pc215e_model,
+	      layout:	pc215_layout,
+		},
+#ifdef CONFIG_COMEDI_PCI
+	{
+	      name:	"pci215",
+	      devid:	PCI_DEVICE_ID_AMPLICON_PCI215,
+	      bustype:	pci_bustype,
+	      model:	pci215_model,
+	      layout:	pc215_layout,
+		},
+#endif
+	{
+	      name:	"pc218e",
+	      bustype:	isa_bustype,
+	      model:	pc218e_model,
+	      layout:	pc218_layout,
+		},
+	{
+	      name:	"pc272e",
+	      bustype:	isa_bustype,
+	      model:	pc272e_model,
+	      layout:	pc272_layout,
+		},
+#ifdef CONFIG_COMEDI_PCI
+	{
+	      name:	"pci272",
+	      devid:	PCI_DEVICE_ID_AMPLICON_PCI272,
+	      bustype:	pci_bustype,
+	      model:	pci272_model,
+	      layout:	pc272_layout,
+		},
+#endif
+#ifdef CONFIG_COMEDI_PCI
+	{
+	      name:	DIO200_DRIVER_NAME,
+	      devid:	PCI_DEVICE_ID_INVALID,
+	      bustype:	pci_bustype,
+	      model:	anypci_model,	/* wildcard */
+		},
+#endif
+};
+
+/*
+ * Layout descriptions - some ISA and PCI board descriptions share the same
+ * layout.
+ */
+
+enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254 };
+
+#define DIO200_MAX_SUBDEVS	7
+#define DIO200_MAX_ISNS		6
+
+struct dio200_layout_struct {
+	unsigned short n_subdevs;	/* number of subdevices */
+	unsigned char sdtype[DIO200_MAX_SUBDEVS];	/* enum dio200_sdtype */
+	unsigned char sdinfo[DIO200_MAX_SUBDEVS];	/* depends on sdtype */
+	char has_int_sce;	/* has interrupt enable/status register */
+	char has_clk_gat_sce;	/* has clock/gate selection registers */
+};
+
+static const struct dio200_layout_struct dio200_layouts[] = {
+	[pc212_layout] = {
+	      n_subdevs:6,
+	      sdtype:	{sd_8255, sd_8254, sd_8254, sd_8254,
+					sd_8254,
+				sd_intr},
+	      sdinfo:	{0x00, 0x08, 0x0C, 0x10, 0x14,
+				0x3F},
+	      has_int_sce:1,
+	      has_clk_gat_sce:1,
+		},
+	[pc214_layout] = {
+	      n_subdevs:4,
+	      sdtype:	{sd_8255, sd_8255, sd_8254,
+				sd_intr},
+	      sdinfo:	{0x00, 0x08, 0x10, 0x01},
+	      has_int_sce:0,
+	      has_clk_gat_sce:0,
+		},
+	[pc215_layout] = {
+	      n_subdevs:5,
+	      sdtype:	{sd_8255, sd_8255, sd_8254,
+					sd_8254,
+				sd_intr},
+	      sdinfo:	{0x00, 0x08, 0x10, 0x14, 0x3F},
+	      has_int_sce:1,
+	      has_clk_gat_sce:1,
+		},
+	[pc218_layout] = {
+	      n_subdevs:7,
+	      sdtype:	{sd_8254, sd_8254, sd_8255, sd_8254,
+					sd_8254,
+				sd_intr},
+	      sdinfo:	{0x00, 0x04, 0x08, 0x0C, 0x10,
+					0x14,
+				0x3F},
+	      has_int_sce:1,
+	      has_clk_gat_sce:1,
+		},
+	[pc272_layout] = {
+	      n_subdevs:4,
+	      sdtype:	{sd_8255, sd_8255, sd_8255,
+				sd_intr},
+	      sdinfo:	{0x00, 0x08, 0x10, 0x3F},
+	      has_int_sce:1,
+	      has_clk_gat_sce:0,
+		},
+};
+
+/*
+ * PCI driver table.
+ */
+
+#ifdef CONFIG_COMEDI_PCI
+static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = {
+	{PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, dio200_pci_table);
+#endif /* CONFIG_COMEDI_PCI */
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct dio200_board *)dev->board_ptr)
+#define thislayout (&dio200_layouts[((struct dio200_board *)dev->board_ptr)->layout])
+
+/* this structure is for data unique to this hardware driver.  If
+   several hardware drivers keep similar information in this structure,
+   feel free to suggest moving the variable to the struct comedi_device struct.  */
+struct dio200_private {
+#ifdef CONFIG_COMEDI_PCI
+	struct pci_dev *pci_dev;	/* PCI device */
+#endif
+	int intr_sd;
+};
+
+#define devpriv ((struct dio200_private *)dev->private)
+
+struct dio200_subdev_8254 {
+	unsigned long iobase;	/* Counter base address */
+	unsigned long clk_sce_iobase;	/* CLK_SCE base address */
+	unsigned long gat_sce_iobase;	/* GAT_SCE base address */
+	int which;		/* Bit 5 of CLK_SCE or GAT_SCE */
+	int has_clk_gat_sce;
+	unsigned clock_src[3];	/* Current clock sources */
+	unsigned gate_src[3];	/* Current gate sources */
+};
+
+struct dio200_subdev_intr {
+	unsigned long iobase;
+	spinlock_t spinlock;
+	int active;
+	int has_int_sce;
+	unsigned int valid_isns;
+	unsigned int enabled_isns;
+	unsigned int stopcount;
+	int continuous;
+};
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int dio200_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dio200_detach(struct comedi_device * dev);
+static struct comedi_driver driver_amplc_dio200 = {
+      driver_name:DIO200_DRIVER_NAME,
+      module:THIS_MODULE,
+      attach:dio200_attach,
+      detach:dio200_detach,
+      board_name:&dio200_boards[0].name,
+      offset:sizeof(struct dio200_board),
+      num_names:sizeof(dio200_boards) / sizeof(struct dio200_board),
+};
+
+#ifdef CONFIG_COMEDI_PCI
+COMEDI_PCI_INITCLEANUP(driver_amplc_dio200, dio200_pci_table);
+#else
+COMEDI_INITCLEANUP(driver_amplc_dio200);
+#endif
+
+/*
+ * This function looks for a PCI device matching the requested board name,
+ * bus and slot.
+ */
+#ifdef CONFIG_COMEDI_PCI
+static int
+dio200_find_pci(struct comedi_device * dev, int bus, int slot,
+	struct pci_dev **pci_dev_p)
+{
+	struct pci_dev *pci_dev = NULL;
+
+	*pci_dev_p = NULL;
+
+	/* Look for matching PCI device. */
+	for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
+		pci_dev != NULL;
+		pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
+			PCI_ANY_ID, pci_dev)) {
+		/* If bus/slot specified, check them. */
+		if (bus || slot) {
+			if (bus != pci_dev->bus->number
+				|| slot != PCI_SLOT(pci_dev->devfn))
+				continue;
+		}
+		if (thisboard->model == anypci_model) {
+			/* Match any supported model. */
+			int i;
+
+			for (i = 0; i < ARRAY_SIZE(dio200_boards); i++) {
+				if (dio200_boards[i].bustype != pci_bustype)
+					continue;
+				if (pci_dev->device == dio200_boards[i].devid) {
+					/* Change board_ptr to matched board. */
+					dev->board_ptr = &dio200_boards[i];
+					break;
+				}
+			}
+			if (i == ARRAY_SIZE(dio200_boards))
+				continue;
+		} else {
+			/* Match specific model name. */
+			if (pci_dev->device != thisboard->devid)
+				continue;
+		}
+
+		/* Found a match. */
+		*pci_dev_p = pci_dev;
+		return 0;
+	}
+	/* No match found. */
+	if (bus || slot) {
+		printk(KERN_ERR
+			"comedi%d: error! no %s found at pci %02x:%02x!\n",
+			dev->minor, thisboard->name, bus, slot);
+	} else {
+		printk(KERN_ERR "comedi%d: error! no %s found!\n",
+			dev->minor, thisboard->name);
+	}
+	return -EIO;
+}
+#endif
+
+/*
+ * This function checks and requests an I/O region, reporting an error
+ * if there is a conflict.
+ */
+static int
+dio200_request_region(unsigned minor, unsigned long from, unsigned long extent)
+{
+	if (!from || !request_region(from, extent, DIO200_DRIVER_NAME)) {
+		printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n",
+			minor, from, extent);
+		return -EIO;
+	}
+	return 0;
+}
+
+/*
+ * 'insn_bits' function for an 'INTERRUPT' subdevice.
+ */
+static int
+dio200_subdev_intr_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	struct dio200_subdev_intr *subpriv = s->private;
+
+	if (subpriv->has_int_sce) {
+		/* Just read the interrupt status register.  */
+		data[1] = inb(subpriv->iobase) & subpriv->valid_isns;
+	} else {
+		/* No interrupt status register. */
+		data[0] = 0;
+	}
+
+	return 2;
+}
+
+/*
+ * Called to stop acquisition for an 'INTERRUPT' subdevice.
+ */
+static void dio200_stop_intr(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct dio200_subdev_intr *subpriv = s->private;
+
+	subpriv->active = 0;
+	subpriv->enabled_isns = 0;
+	if (subpriv->has_int_sce) {
+		outb(0, subpriv->iobase);
+	}
+}
+
+/*
+ * Called to start acquisition for an 'INTERRUPT' subdevice.
+ */
+static int dio200_start_intr(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	unsigned int n;
+	unsigned isn_bits;
+	struct dio200_subdev_intr *subpriv = s->private;
+	struct comedi_cmd *cmd = &s->async->cmd;
+	int retval = 0;
+
+	if (!subpriv->continuous && subpriv->stopcount == 0) {
+		/* An empty acquisition! */
+		s->async->events |= COMEDI_CB_EOA;
+		subpriv->active = 0;
+		retval = 1;
+	} else {
+		/* Determine interrupt sources to enable. */
+		isn_bits = 0;
+		if (cmd->chanlist) {
+			for (n = 0; n < cmd->chanlist_len; n++) {
+				isn_bits |= (1U << CR_CHAN(cmd->chanlist[n]));
+			}
+		}
+		isn_bits &= subpriv->valid_isns;
+		/* Enable interrupt sources. */
+		subpriv->enabled_isns = isn_bits;
+		if (subpriv->has_int_sce) {
+			outb(isn_bits, subpriv->iobase);
+		}
+	}
+
+	return retval;
+}
+
+/*
+ * Internal trigger function to start acquisition for an 'INTERRUPT' subdevice.
+ */
+static int
+dio200_inttrig_start_intr(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int trignum)
+{
+	struct dio200_subdev_intr *subpriv;
+	unsigned long flags;
+	int event = 0;
+
+	if (trignum != 0)
+		return -EINVAL;
+
+	subpriv = s->private;
+
+	comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
+	s->async->inttrig = 0;
+	if (subpriv->active) {
+		event = dio200_start_intr(dev, s);
+	}
+	comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
+
+	if (event) {
+		comedi_event(dev, s);
+	}
+
+	return 1;
+}
+
+/*
+ * This is called from the interrupt service routine to handle a read
+ * scan on an 'INTERRUPT' subdevice.
+ */
+static int dio200_handle_read_intr(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct dio200_subdev_intr *subpriv = s->private;
+	unsigned triggered;
+	unsigned intstat;
+	unsigned cur_enabled;
+	unsigned int oldevents;
+	unsigned long flags;
+
+	triggered = 0;
+
+	comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
+	oldevents = s->async->events;
+	if (subpriv->has_int_sce) {
+		/*
+		 * Collect interrupt sources that have triggered and disable
+		 * them temporarily.  Loop around until no extra interrupt
+		 * sources have triggered, at which point, the valid part of
+		 * the interrupt status register will read zero, clearing the
+		 * cause of the interrupt.
+		 *
+		 * Mask off interrupt sources already seen to avoid infinite
+		 * loop in case of misconfiguration.
+		 */
+		cur_enabled = subpriv->enabled_isns;
+		while ((intstat = (inb(subpriv->iobase) & subpriv->valid_isns
+					& ~triggered)) != 0) {
+			triggered |= intstat;
+			cur_enabled &= ~triggered;
+			outb(cur_enabled, subpriv->iobase);
+		}
+	} else {
+		/*
+		 * No interrupt status register.  Assume the single interrupt
+		 * source has triggered.
+		 */
+		triggered = subpriv->enabled_isns;
+	}
+
+	if (triggered) {
+		/*
+		 * Some interrupt sources have triggered and have been
+		 * temporarily disabled to clear the cause of the interrupt.
+		 *
+		 * Reenable them NOW to minimize the time they are disabled.
+		 */
+		cur_enabled = subpriv->enabled_isns;
+		if (subpriv->has_int_sce) {
+			outb(cur_enabled, subpriv->iobase);
+		}
+
+		if (subpriv->active) {
+			/*
+			 * The command is still active.
+			 *
+			 * Ignore interrupt sources that the command isn't
+			 * interested in (just in case there's a race
+			 * condition).
+			 */
+			if (triggered & subpriv->enabled_isns) {
+				/* Collect scan data. */
+				short val;
+				unsigned int n, ch, len;
+
+				val = 0;
+				len = s->async->cmd.chanlist_len;
+				for (n = 0; n < len; n++) {
+					ch = CR_CHAN(s->async->cmd.chanlist[n]);
+					if (triggered & (1U << ch)) {
+						val |= (1U << n);
+					}
+				}
+				/* Write the scan to the buffer. */
+				if (comedi_buf_put(s->async, val)) {
+					s->async->events |= (COMEDI_CB_BLOCK |
+						COMEDI_CB_EOS);
+				} else {
+					/* Error!  Stop acquisition.  */
+					dio200_stop_intr(dev, s);
+					s->async->events |= COMEDI_CB_ERROR
+						| COMEDI_CB_OVERFLOW;
+					comedi_error(dev, "buffer overflow");
+				}
+
+				/* Check for end of acquisition. */
+				if (!subpriv->continuous) {
+					/* stop_src == TRIG_COUNT */
+					if (subpriv->stopcount > 0) {
+						subpriv->stopcount--;
+						if (subpriv->stopcount == 0) {
+							s->async->events |=
+								COMEDI_CB_EOA;
+							dio200_stop_intr(dev,
+								s);
+						}
+					}
+				}
+			}
+		}
+	}
+	comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
+
+	if (oldevents != s->async->events) {
+		comedi_event(dev, s);
+	}
+
+	return (triggered != 0);
+}
+
+/*
+ * 'cancel' function for an 'INTERRUPT' subdevice.
+ */
+static int dio200_subdev_intr_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct dio200_subdev_intr *subpriv = s->private;
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
+	if (subpriv->active) {
+		dio200_stop_intr(dev, s);
+	}
+	comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
+
+	return 0;
+}
+
+/*
+ * 'do_cmdtest' function for an 'INTERRUPT' subdevice.
+ */
+static int
+dio200_subdev_intr_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	unsigned int tmp;
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= (TRIG_NOW | TRIG_INT);
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_EXT;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_NOW;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= (TRIG_COUNT | TRIG_NONE);
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	/* these tests are true if more than one _src bit is set */
+	if ((cmd->start_src & (cmd->start_src - 1)) != 0)
+		err++;
+	if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
+		err++;
+	if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
+		err++;
+	if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
+		err++;
+	if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	/* cmd->start_src == TRIG_NOW || cmd->start_src == TRIG_INT */
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+
+	/* cmd->scan_begin_src == TRIG_EXT */
+	if (cmd->scan_begin_arg != 0) {
+		cmd->scan_begin_arg = 0;
+		err++;
+	}
+
+	/* cmd->convert_src == TRIG_NOW */
+	if (cmd->convert_arg != 0) {
+		cmd->convert_arg = 0;
+		err++;
+	}
+
+	/* cmd->scan_end_src == TRIG_COUNT */
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+
+	switch (cmd->stop_src) {
+	case TRIG_COUNT:
+		/* any count allowed */
+		break;
+	case TRIG_NONE:
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+		break;
+	default:
+		break;
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	/* if (err) return 4; */
+
+	return 0;
+}
+
+/*
+ * 'do_cmd' function for an 'INTERRUPT' subdevice.
+ */
+static int dio200_subdev_intr_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_cmd *cmd = &s->async->cmd;
+	struct dio200_subdev_intr *subpriv = s->private;
+	unsigned long flags;
+	int event = 0;
+
+	comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
+	subpriv->active = 1;
+
+	/* Set up end of acquisition. */
+	switch (cmd->stop_src) {
+	case TRIG_COUNT:
+		subpriv->continuous = 0;
+		subpriv->stopcount = cmd->stop_arg;
+		break;
+	default:
+		/* TRIG_NONE */
+		subpriv->continuous = 1;
+		subpriv->stopcount = 0;
+		break;
+	}
+
+	/* Set up start of acquisition. */
+	switch (cmd->start_src) {
+	case TRIG_INT:
+		s->async->inttrig = dio200_inttrig_start_intr;
+		break;
+	default:
+		/* TRIG_NOW */
+		event = dio200_start_intr(dev, s);
+		break;
+	}
+	comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
+
+	if (event) {
+		comedi_event(dev, s);
+	}
+
+	return 0;
+}
+
+/*
+ * This function initializes an 'INTERRUPT' subdevice.
+ */
+static int
+dio200_subdev_intr_init(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned long iobase, unsigned valid_isns, int has_int_sce)
+{
+	struct dio200_subdev_intr *subpriv;
+
+	subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
+	if (!subpriv) {
+		printk(KERN_ERR "comedi%d: error! out of memory!\n",
+			dev->minor);
+		return -ENOMEM;
+	}
+	subpriv->iobase = iobase;
+	subpriv->has_int_sce = has_int_sce;
+	subpriv->valid_isns = valid_isns;
+	spin_lock_init(&subpriv->spinlock);
+
+	if (has_int_sce) {
+		outb(0, subpriv->iobase);	/* Disable interrupt sources. */
+	}
+
+	s->private = subpriv;
+	s->type = COMEDI_SUBD_DI;
+	s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+	if (has_int_sce) {
+		s->n_chan = DIO200_MAX_ISNS;
+		s->len_chanlist = DIO200_MAX_ISNS;
+	} else {
+		/* No interrupt source register.  Support single channel. */
+		s->n_chan = 1;
+		s->len_chanlist = 1;
+	}
+	s->range_table = &range_digital;
+	s->maxdata = 1;
+	s->insn_bits = dio200_subdev_intr_insn_bits;
+	s->do_cmdtest = dio200_subdev_intr_cmdtest;
+	s->do_cmd = dio200_subdev_intr_cmd;
+	s->cancel = dio200_subdev_intr_cancel;
+
+	return 0;
+}
+
+/*
+ * This function cleans up an 'INTERRUPT' subdevice.
+ */
+static void
+dio200_subdev_intr_cleanup(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct dio200_subdev_intr *subpriv = s->private;
+
+	if (subpriv) {
+		kfree(subpriv);
+	}
+}
+
+/*
+ * Interrupt service routine.
+ */
+static irqreturn_t dio200_interrupt(int irq, void *d PT_REGS_ARG)
+{
+	struct comedi_device *dev = d;
+	int handled;
+
+	if (!dev->attached) {
+		return IRQ_NONE;
+	}
+
+	if (devpriv->intr_sd >= 0) {
+		handled = dio200_handle_read_intr(dev,
+			dev->subdevices + devpriv->intr_sd);
+	} else {
+		handled = 0;
+	}
+
+	return IRQ_RETVAL(handled);
+}
+
+/*
+ * Handle 'insn_read' for an '8254' counter subdevice.
+ */
+static int
+dio200_subdev_8254_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	struct dio200_subdev_8254 *subpriv = s->private;
+	int chan = CR_CHAN(insn->chanspec);
+
+	data[0] = i8254_read(subpriv->iobase, 0, chan);
+
+	return 1;
+}
+
+/*
+ * Handle 'insn_write' for an '8254' counter subdevice.
+ */
+static int
+dio200_subdev_8254_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	struct dio200_subdev_8254 *subpriv = s->private;
+	int chan = CR_CHAN(insn->chanspec);
+
+	i8254_write(subpriv->iobase, 0, chan, data[0]);
+
+	return 1;
+}
+
+/*
+ * Set gate source for an '8254' counter subdevice channel.
+ */
+static int
+dio200_set_gate_src(struct dio200_subdev_8254 * subpriv, unsigned int counter_number,
+	unsigned int gate_src)
+{
+	unsigned char byte;
+
+	if (!subpriv->has_clk_gat_sce)
+		return -1;
+	if (counter_number > 2)
+		return -1;
+	if (gate_src > 7)
+		return -1;
+
+	subpriv->gate_src[counter_number] = gate_src;
+	byte = GAT_SCE(subpriv->which, counter_number, gate_src);
+	outb(byte, subpriv->gat_sce_iobase);
+
+	return 0;
+}
+
+/*
+ * Get gate source for an '8254' counter subdevice channel.
+ */
+static int
+dio200_get_gate_src(struct dio200_subdev_8254 * subpriv, unsigned int counter_number)
+{
+	if (!subpriv->has_clk_gat_sce)
+		return -1;
+	if (counter_number > 2)
+		return -1;
+
+	return subpriv->gate_src[counter_number];
+}
+
+/*
+ * Set clock source for an '8254' counter subdevice channel.
+ */
+static int
+dio200_set_clock_src(struct dio200_subdev_8254 * subpriv, unsigned int counter_number,
+	unsigned int clock_src)
+{
+	unsigned char byte;
+
+	if (!subpriv->has_clk_gat_sce)
+		return -1;
+	if (counter_number > 2)
+		return -1;
+	if (clock_src > 7)
+		return -1;
+
+	subpriv->clock_src[counter_number] = clock_src;
+	byte = CLK_SCE(subpriv->which, counter_number, clock_src);
+	outb(byte, subpriv->clk_sce_iobase);
+
+	return 0;
+}
+
+/*
+ * Get clock source for an '8254' counter subdevice channel.
+ */
+static int
+dio200_get_clock_src(struct dio200_subdev_8254 * subpriv, unsigned int counter_number,
+	unsigned int * period_ns)
+{
+	unsigned clock_src;
+
+	if (!subpriv->has_clk_gat_sce)
+		return -1;
+	if (counter_number > 2)
+		return -1;
+
+	clock_src = subpriv->clock_src[counter_number];
+	*period_ns = clock_period[clock_src];
+	return clock_src;
+}
+
+/*
+ * Handle 'insn_config' for an '8254' counter subdevice.
+ */
+static int
+dio200_subdev_8254_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	struct dio200_subdev_8254 *subpriv = s->private;
+	int ret;
+	int chan = CR_CHAN(insn->chanspec);
+
+	switch (data[0]) {
+	case INSN_CONFIG_SET_COUNTER_MODE:
+		ret = i8254_set_mode(subpriv->iobase, 0, chan, data[1]);
+		if (ret < 0)
+			return -EINVAL;
+		break;
+	case INSN_CONFIG_8254_READ_STATUS:
+		data[1] = i8254_status(subpriv->iobase, 0, chan);
+		break;
+	case INSN_CONFIG_SET_GATE_SRC:
+		ret = dio200_set_gate_src(subpriv, chan, data[2]);
+		if (ret < 0)
+			return -EINVAL;
+		break;
+	case INSN_CONFIG_GET_GATE_SRC:
+		ret = dio200_get_gate_src(subpriv, chan);
+		if (ret < 0)
+			return -EINVAL;
+		data[2] = ret;
+		break;
+	case INSN_CONFIG_SET_CLOCK_SRC:
+		ret = dio200_set_clock_src(subpriv, chan, data[1]);
+		if (ret < 0)
+			return -EINVAL;
+		break;
+	case INSN_CONFIG_GET_CLOCK_SRC:
+		ret = dio200_get_clock_src(subpriv, chan, &data[2]);
+		if (ret < 0)
+			return -EINVAL;
+		data[1] = ret;
+		break;
+	default:
+		return -EINVAL;
+		break;
+	}
+	return insn->n;
+}
+
+/*
+ * This function initializes an '8254' counter subdevice.
+ *
+ * Note: iobase is the base address of the board, not the subdevice;
+ * offset is the offset to the 8254 chip.
+ */
+static int
+dio200_subdev_8254_init(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned long iobase, unsigned offset, int has_clk_gat_sce)
+{
+	struct dio200_subdev_8254 *subpriv;
+	unsigned int chan;
+
+	subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
+	if (!subpriv) {
+		printk(KERN_ERR "comedi%d: error! out of memory!\n",
+			dev->minor);
+		return -ENOMEM;
+	}
+
+	s->private = subpriv;
+	s->type = COMEDI_SUBD_COUNTER;
+	s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+	s->n_chan = 3;
+	s->maxdata = 0xFFFF;
+	s->insn_read = dio200_subdev_8254_read;
+	s->insn_write = dio200_subdev_8254_write;
+	s->insn_config = dio200_subdev_8254_config;
+
+	subpriv->iobase = offset + iobase;
+	subpriv->has_clk_gat_sce = has_clk_gat_sce;
+	if (has_clk_gat_sce) {
+		/* Derive CLK_SCE and GAT_SCE register offsets from
+		 * 8254 offset. */
+		subpriv->clk_sce_iobase =
+			DIO200_XCLK_SCE + (offset >> 3) + iobase;
+		subpriv->gat_sce_iobase =
+			DIO200_XGAT_SCE + (offset >> 3) + iobase;
+		subpriv->which = (offset >> 2) & 1;
+	}
+
+	/* Initialize channels. */
+	for (chan = 0; chan < 3; chan++) {
+		i8254_set_mode(subpriv->iobase, 0, chan,
+			I8254_MODE0 | I8254_BINARY);
+		if (subpriv->has_clk_gat_sce) {
+			/* Gate source 0 is VCC (logic 1). */
+			dio200_set_gate_src(subpriv, chan, 0);
+			/* Clock source 0 is the dedicated clock input. */
+			dio200_set_clock_src(subpriv, chan, 0);
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * This function cleans up an '8254' counter subdevice.
+ */
+static void
+dio200_subdev_8254_cleanup(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct dio200_subdev_intr *subpriv = s->private;
+
+	if (subpriv) {
+		kfree(subpriv);
+	}
+}
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board.  If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int dio200_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	unsigned long iobase = 0;
+	unsigned int irq = 0;
+#ifdef CONFIG_COMEDI_PCI
+	struct pci_dev *pci_dev = NULL;
+	int bus = 0, slot = 0;
+#endif
+	const struct dio200_layout_struct *layout;
+	int share_irq = 0;
+	int sdx;
+	unsigned n;
+	int ret;
+
+	printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
+		DIO200_DRIVER_NAME);
+
+	if ((ret = alloc_private(dev, sizeof(struct dio200_private))) < 0) {
+		printk(KERN_ERR "comedi%d: error! out of memory!\n",
+			dev->minor);
+		return ret;
+	}
+
+	/* Process options. */
+	switch (thisboard->bustype) {
+	case isa_bustype:
+		iobase = it->options[0];
+		irq = it->options[1];
+		share_irq = 0;
+		break;
+#ifdef CONFIG_COMEDI_PCI
+	case pci_bustype:
+		bus = it->options[0];
+		slot = it->options[1];
+		share_irq = 1;
+
+		if ((ret = dio200_find_pci(dev, bus, slot, &pci_dev)) < 0)
+			return ret;
+		devpriv->pci_dev = pci_dev;
+		break;
+#endif
+	default:
+		printk(KERN_ERR
+			"comedi%d: %s: BUG! cannot determine board type!\n",
+			dev->minor, DIO200_DRIVER_NAME);
+		return -EINVAL;
+		break;
+	}
+
+	devpriv->intr_sd = -1;
+
+	/* Enable device and reserve I/O spaces. */
+#ifdef CONFIG_COMEDI_PCI
+	if (pci_dev) {
+		ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME);
+		if (ret < 0) {
+			printk(KERN_ERR
+				"comedi%d: error! cannot enable PCI device and request regions!\n",
+				dev->minor);
+			return ret;
+		}
+		iobase = pci_resource_start(pci_dev, 2);
+		irq = pci_dev->irq;
+	} else
+#endif
+	{
+		ret = dio200_request_region(dev->minor, iobase, DIO200_IO_SIZE);
+		if (ret < 0) {
+			return ret;
+		}
+	}
+	dev->iobase = iobase;
+
+	layout = thislayout;
+	if ((ret = alloc_subdevices(dev, layout->n_subdevs)) < 0) {
+		printk(KERN_ERR "comedi%d: error! out of memory!\n",
+			dev->minor);
+		return ret;
+	}
+
+	for (n = 0; n < dev->n_subdevices; n++) {
+		s = &dev->subdevices[n];
+		switch (layout->sdtype[n]) {
+		case sd_8254:
+			/* counter subdevice (8254) */
+			ret = dio200_subdev_8254_init(dev, s, iobase,
+				layout->sdinfo[n], layout->has_clk_gat_sce);
+			if (ret < 0) {
+				return ret;
+			}
+			break;
+		case sd_8255:
+			/* digital i/o subdevice (8255) */
+			ret = subdev_8255_init(dev, s, 0,
+				iobase + layout->sdinfo[n]);
+			if (ret < 0) {
+				return ret;
+			}
+			break;
+		case sd_intr:
+			/* 'INTERRUPT' subdevice */
+			if (irq) {
+				ret = dio200_subdev_intr_init(dev, s,
+					iobase + DIO200_INT_SCE,
+					layout->sdinfo[n], layout->has_int_sce);
+				if (ret < 0) {
+					return ret;
+				}
+				devpriv->intr_sd = n;
+			} else {
+				s->type = COMEDI_SUBD_UNUSED;
+			}
+			break;
+		default:
+			s->type = COMEDI_SUBD_UNUSED;
+			break;
+		}
+	}
+
+	sdx = devpriv->intr_sd;
+	if (sdx >= 0 && sdx < dev->n_subdevices) {
+		dev->read_subdev = &dev->subdevices[sdx];
+	}
+
+	dev->board_name = thisboard->name;
+
+	if (irq) {
+		unsigned long flags = share_irq ? IRQF_SHARED : 0;
+
+		if (comedi_request_irq(irq, dio200_interrupt, flags,
+				DIO200_DRIVER_NAME, dev) >= 0) {
+			dev->irq = irq;
+		} else {
+			printk(KERN_WARNING
+				"comedi%d: warning! irq %u unavailable!\n",
+				dev->minor, irq);
+		}
+	}
+
+	printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
+	if (thisboard->bustype == isa_bustype) {
+		printk("(base %#lx) ", iobase);
+	} else {
+#ifdef CONFIG_COMEDI_PCI
+		printk("(pci %s) ", pci_name(pci_dev));
+#endif
+	}
+	if (irq) {
+		printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
+	} else {
+		printk("(no irq) ");
+	}
+
+	printk("attached\n");
+
+	return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device.  It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach().  dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int dio200_detach(struct comedi_device * dev)
+{
+	const struct dio200_layout_struct *layout;
+	unsigned n;
+
+	printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
+		DIO200_DRIVER_NAME);
+
+	if (dev->irq) {
+		comedi_free_irq(dev->irq, dev);
+	}
+	if (dev->subdevices) {
+		layout = thislayout;
+		for (n = 0; n < dev->n_subdevices; n++) {
+			struct comedi_subdevice *s = &dev->subdevices[n];
+			switch (layout->sdtype[n]) {
+			case sd_8254:
+				dio200_subdev_8254_cleanup(dev, s);
+				break;
+			case sd_8255:
+				subdev_8255_cleanup(dev, s);
+				break;
+			case sd_intr:
+				dio200_subdev_intr_cleanup(dev, s);
+				break;
+			default:
+				break;
+			}
+		}
+	}
+	if (devpriv) {
+#ifdef CONFIG_COMEDI_PCI
+		if (devpriv->pci_dev) {
+			if (dev->iobase) {
+				comedi_pci_disable(devpriv->pci_dev);
+			}
+			pci_dev_put(devpriv->pci_dev);
+		} else
+#endif
+		{
+			if (dev->iobase) {
+				release_region(dev->iobase, DIO200_IO_SIZE);
+			}
+		}
+	}
+	if (dev->board_name) {
+		printk(KERN_INFO "comedi%d: %s removed\n",
+			dev->minor, dev->board_name);
+	}
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c
new file mode 100644
index 0000000..2027c75
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amplc_pc236.c
@@ -0,0 +1,654 @@
+/*
+    comedi/drivers/amplc_pc236.c
+    Driver for Amplicon PC36AT and PCI236 DIO boards.
+
+    Copyright (C) 2002 MEV Ltd. <http://www.mev.co.uk/>
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: amplc_pc236
+Description: Amplicon PC36AT, PCI236
+Author: Ian Abbott <abbotti@mev.co.uk>
+Devices: [Amplicon] PC36AT (pc36at), PCI236 (pci236 or amplc_pc236)
+Updated: Wed, 22 Oct 2008 13:40:03 +0100
+Status: works
+
+Configuration options - PC36AT:
+  [0] - I/O port base address
+  [1] - IRQ (optional)
+
+Configuration options - PCI236:
+  [0] - PCI bus of device (optional)
+  [1] - PCI slot of device (optional)
+  If bus/slot is not specified, the first available PCI device will be
+  used.
+
+The PC36AT ISA board and PCI236 PCI board have a single 8255 appearing
+as subdevice 0.
+
+Subdevice 1 pretends to be a digital input device, but it always returns
+0 when read. However, if you run a command with scan_begin_src=TRIG_EXT,
+a rising edge on port C bit 7 acts as an external trigger, which can be
+used to wake up tasks.  This is like the comedi_parport device, but the
+only way to physically disable the interrupt on the PC36AT is to remove
+the IRQ jumper.  If no interrupt is connected, then subdevice 1 is
+unused.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+#include "8255.h"
+#include "plx9052.h"
+
+#define PC236_DRIVER_NAME	"amplc_pc236"
+
+/* PCI236 PCI configuration register information */
+#define PCI_VENDOR_ID_AMPLICON 0x14dc
+#define PCI_DEVICE_ID_AMPLICON_PCI236 0x0009
+#define PCI_DEVICE_ID_INVALID 0xffff
+
+/* PC36AT / PCI236 registers */
+
+#define PC236_IO_SIZE		4
+#define PC236_LCR_IO_SIZE	128
+
+/*
+ * INTCSR values for PCI236.
+ */
+/* Disable interrupt, also clear any interrupt there */
+#define PCI236_INTR_DISABLE ( PLX9052_INTCSR_LI1ENAB_DISABLED \
+        | PLX9052_INTCSR_LI1POL_HIGH \
+        | PLX9052_INTCSR_LI2POL_HIGH \
+        | PLX9052_INTCSR_PCIENAB_DISABLED \
+        | PLX9052_INTCSR_LI1SEL_EDGE \
+        | PLX9052_INTCSR_LI1CLRINT_ASSERTED )
+/* Enable interrupt, also clear any interrupt there. */
+#define PCI236_INTR_ENABLE ( PLX9052_INTCSR_LI1ENAB_ENABLED \
+        | PLX9052_INTCSR_LI1POL_HIGH \
+        | PLX9052_INTCSR_LI2POL_HIGH \
+        | PLX9052_INTCSR_PCIENAB_ENABLED \
+        | PLX9052_INTCSR_LI1SEL_EDGE \
+        | PLX9052_INTCSR_LI1CLRINT_ASSERTED )
+
+/*
+ * Board descriptions for Amplicon PC36AT and PCI236.
+ */
+
+enum pc236_bustype { isa_bustype, pci_bustype };
+enum pc236_model { pc36at_model, pci236_model, anypci_model };
+
+struct pc236_board {
+	const char *name;
+	const char *fancy_name;
+	unsigned short devid;
+	enum pc236_bustype bustype;
+	enum pc236_model model;
+};
+static const struct pc236_board pc236_boards[] = {
+	{
+	      name:	"pc36at",
+	      fancy_name:"PC36AT",
+	      bustype:	isa_bustype,
+	      model:	pc36at_model,
+		},
+#ifdef CONFIG_COMEDI_PCI
+	{
+	      name:	"pci236",
+	      fancy_name:"PCI236",
+	      devid:	PCI_DEVICE_ID_AMPLICON_PCI236,
+	      bustype:	pci_bustype,
+	      model:	pci236_model,
+		},
+#endif
+#ifdef CONFIG_COMEDI_PCI
+	{
+	      name:	PC236_DRIVER_NAME,
+	      fancy_name:PC236_DRIVER_NAME,
+	      devid:	PCI_DEVICE_ID_INVALID,
+	      bustype:	pci_bustype,
+	      model:	anypci_model,	/* wildcard */
+		},
+#endif
+};
+
+#ifdef CONFIG_COMEDI_PCI
+static DEFINE_PCI_DEVICE_TABLE(pc236_pci_table) = {
+	{PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI236, PCI_ANY_ID,
+		PCI_ANY_ID, 0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, pc236_pci_table);
+#endif /* CONFIG_COMEDI_PCI */
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct pc236_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver.  If
+   several hardware drivers keep similar information in this structure,
+   feel free to suggest moving the variable to the struct comedi_device struct.  */
+struct pc236_private {
+#ifdef CONFIG_COMEDI_PCI
+	/* PCI device */
+	struct pci_dev *pci_dev;
+	unsigned long lcr_iobase;	/* PLX PCI9052 config registers in PCIBAR1 */
+#endif
+	int enable_irq;
+};
+
+#define devpriv ((struct pc236_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pc236_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pc236_detach(struct comedi_device * dev);
+static struct comedi_driver driver_amplc_pc236 = {
+      driver_name:PC236_DRIVER_NAME,
+      module:THIS_MODULE,
+      attach:pc236_attach,
+      detach:pc236_detach,
+      board_name:&pc236_boards[0].name,
+      offset:sizeof(struct pc236_board),
+      num_names:sizeof(pc236_boards) / sizeof(struct pc236_board),
+};
+
+#ifdef CONFIG_COMEDI_PCI
+COMEDI_PCI_INITCLEANUP(driver_amplc_pc236, pc236_pci_table);
+#else
+COMEDI_INITCLEANUP(driver_amplc_pc236);
+#endif
+
+static int pc236_request_region(unsigned minor, unsigned long from,
+	unsigned long extent);
+static void pc236_intr_disable(struct comedi_device * dev);
+static void pc236_intr_enable(struct comedi_device * dev);
+static int pc236_intr_check(struct comedi_device * dev);
+static int pc236_intr_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int pc236_intr_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd);
+static int pc236_intr_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pc236_intr_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static irqreturn_t pc236_interrupt(int irq, void *d PT_REGS_ARG);
+
+/*
+ * This function looks for a PCI device matching the requested board name,
+ * bus and slot.
+ */
+#ifdef CONFIG_COMEDI_PCI
+static int
+pc236_find_pci(struct comedi_device * dev, int bus, int slot,
+	struct pci_dev **pci_dev_p)
+{
+	struct pci_dev *pci_dev = NULL;
+
+	*pci_dev_p = NULL;
+
+	/* Look for matching PCI device. */
+	for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
+		pci_dev != NULL;
+		pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
+			PCI_ANY_ID, pci_dev)) {
+		/* If bus/slot specified, check them. */
+		if (bus || slot) {
+			if (bus != pci_dev->bus->number
+				|| slot != PCI_SLOT(pci_dev->devfn))
+				continue;
+		}
+		if (thisboard->model == anypci_model) {
+			/* Match any supported model. */
+			int i;
+
+			for (i = 0; i < ARRAY_SIZE(pc236_boards); i++) {
+				if (pc236_boards[i].bustype != pci_bustype)
+					continue;
+				if (pci_dev->device == pc236_boards[i].devid) {
+					/* Change board_ptr to matched board. */
+					dev->board_ptr = &pc236_boards[i];
+					break;
+				}
+			}
+			if (i == ARRAY_SIZE(pc236_boards))
+				continue;
+		} else {
+			/* Match specific model name. */
+			if (pci_dev->device != thisboard->devid)
+				continue;
+		}
+
+		/* Found a match. */
+		*pci_dev_p = pci_dev;
+		return 0;
+	}
+	/* No match found. */
+	if (bus || slot) {
+		printk(KERN_ERR
+			"comedi%d: error! no %s found at pci %02x:%02x!\n",
+			dev->minor, thisboard->name, bus, slot);
+	} else {
+		printk(KERN_ERR "comedi%d: error! no %s found!\n",
+			dev->minor, thisboard->name);
+	}
+	return -EIO;
+}
+#endif
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board.  If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pc236_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	unsigned long iobase = 0;
+	unsigned int irq = 0;
+#ifdef CONFIG_COMEDI_PCI
+	struct pci_dev *pci_dev = NULL;
+	int bus = 0, slot = 0;
+#endif
+	int share_irq = 0;
+	int ret;
+
+	printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
+		PC236_DRIVER_NAME);
+/*
+ * Allocate the private structure area.  alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+	if ((ret = alloc_private(dev, sizeof(struct pc236_private))) < 0) {
+		printk(KERN_ERR "comedi%d: error! out of memory!\n",
+			dev->minor);
+		return ret;
+	}
+	/* Process options. */
+	switch (thisboard->bustype) {
+	case isa_bustype:
+		iobase = it->options[0];
+		irq = it->options[1];
+		share_irq = 0;
+		break;
+#ifdef CONFIG_COMEDI_PCI
+	case pci_bustype:
+		bus = it->options[0];
+		slot = it->options[1];
+		share_irq = 1;
+
+		if ((ret = pc236_find_pci(dev, bus, slot, &pci_dev)) < 0)
+			return ret;
+		devpriv->pci_dev = pci_dev;
+		break;
+#endif /* CONFIG_COMEDI_PCI */
+	default:
+		printk(KERN_ERR
+			"comedi%d: %s: BUG! cannot determine board type!\n",
+			dev->minor, PC236_DRIVER_NAME);
+		return -EINVAL;
+		break;
+	}
+
+/*
+ * Initialize dev->board_name.
+ */
+	dev->board_name = thisboard->name;
+
+	/* Enable device and reserve I/O spaces. */
+#ifdef CONFIG_COMEDI_PCI
+	if (pci_dev) {
+		if ((ret = comedi_pci_enable(pci_dev, PC236_DRIVER_NAME)) < 0) {
+			printk(KERN_ERR
+				"comedi%d: error! cannot enable PCI device and request regions!\n",
+				dev->minor);
+			return ret;
+		}
+		devpriv->lcr_iobase = pci_resource_start(pci_dev, 1);
+		iobase = pci_resource_start(pci_dev, 2);
+		irq = pci_dev->irq;
+	} else
+#endif
+	{
+		ret = pc236_request_region(dev->minor, iobase, PC236_IO_SIZE);
+		if (ret < 0) {
+			return ret;
+		}
+	}
+	dev->iobase = iobase;
+
+/*
+ * Allocate the subdevice structures.  alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+	if ((ret = alloc_subdevices(dev, 2)) < 0) {
+		printk(KERN_ERR "comedi%d: error! out of memory!\n",
+			dev->minor);
+		return ret;
+	}
+
+	s = dev->subdevices + 0;
+	/* digital i/o subdevice (8255) */
+	if ((ret = subdev_8255_init(dev, s, NULL, iobase)) < 0) {
+		printk(KERN_ERR "comedi%d: error! out of memory!\n",
+			dev->minor);
+		return ret;
+	}
+	s = dev->subdevices + 1;
+	dev->read_subdev = s;
+	s->type = COMEDI_SUBD_UNUSED;
+	pc236_intr_disable(dev);
+	if (irq) {
+		unsigned long flags = share_irq ? IRQF_SHARED : 0;
+
+		if (comedi_request_irq(irq, pc236_interrupt, flags,
+				PC236_DRIVER_NAME, dev) >= 0) {
+			dev->irq = irq;
+			s->type = COMEDI_SUBD_DI;
+			s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+			s->n_chan = 1;
+			s->maxdata = 1;
+			s->range_table = &range_digital;
+			s->insn_bits = pc236_intr_insn;
+			s->do_cmdtest = pc236_intr_cmdtest;
+			s->do_cmd = pc236_intr_cmd;
+			s->cancel = pc236_intr_cancel;
+		}
+	}
+	printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
+	if (thisboard->bustype == isa_bustype) {
+		printk("(base %#lx) ", iobase);
+	} else {
+#ifdef CONFIG_COMEDI_PCI
+		printk("(pci %s) ", pci_name(pci_dev));
+#endif
+	}
+	if (irq) {
+		printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
+	} else {
+		printk("(no irq) ");
+	}
+
+	printk("attached\n");
+
+	return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device.  It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach().  dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pc236_detach(struct comedi_device * dev)
+{
+	printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
+		PC236_DRIVER_NAME);
+	if (devpriv) {
+		pc236_intr_disable(dev);
+	}
+	if (dev->irq)
+		comedi_free_irq(dev->irq, dev);
+	if (dev->subdevices) {
+		subdev_8255_cleanup(dev, dev->subdevices + 0);
+	}
+	if (devpriv) {
+#ifdef CONFIG_COMEDI_PCI
+		if (devpriv->pci_dev) {
+			if (dev->iobase) {
+				comedi_pci_disable(devpriv->pci_dev);
+			}
+			pci_dev_put(devpriv->pci_dev);
+		} else
+#endif
+		{
+			if (dev->iobase) {
+				release_region(dev->iobase, PC236_IO_SIZE);
+			}
+		}
+	}
+	if (dev->board_name) {
+		printk(KERN_INFO "comedi%d: %s removed\n",
+			dev->minor, dev->board_name);
+	}
+	return 0;
+}
+
+/*
+ * This function checks and requests an I/O region, reporting an error
+ * if there is a conflict.
+ */
+static int pc236_request_region(unsigned minor, unsigned long from,
+	unsigned long extent)
+{
+	if (!from || !request_region(from, extent, PC236_DRIVER_NAME)) {
+		printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n",
+			minor, from, extent);
+		return -EIO;
+	}
+	return 0;
+}
+
+/*
+ * This function is called to mark the interrupt as disabled (no command
+ * configured on subdevice 1) and to physically disable the interrupt
+ * (not possible on the PC36AT, except by removing the IRQ jumper!).
+ */
+static void pc236_intr_disable(struct comedi_device * dev)
+{
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	devpriv->enable_irq = 0;
+#ifdef CONFIG_COMEDI_PCI
+	if (devpriv->lcr_iobase)
+		outl(PCI236_INTR_DISABLE, devpriv->lcr_iobase + PLX9052_INTCSR);
+#endif
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+}
+
+/*
+ * This function is called to mark the interrupt as enabled (a command
+ * configured on subdevice 1) and to physically enable the interrupt
+ * (not possible on the PC36AT, except by (re)connecting the IRQ jumper!).
+ */
+static void pc236_intr_enable(struct comedi_device * dev)
+{
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	devpriv->enable_irq = 1;
+#ifdef CONFIG_COMEDI_PCI
+	if (devpriv->lcr_iobase)
+		outl(PCI236_INTR_ENABLE, devpriv->lcr_iobase + PLX9052_INTCSR);
+#endif
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+}
+
+/*
+ * This function is called when an interrupt occurs to check whether
+ * the interrupt has been marked as enabled and was generated by the
+ * board.  If so, the function prepares the hardware for the next
+ * interrupt.
+ * Returns 0 if the interrupt should be ignored.
+ */
+static int pc236_intr_check(struct comedi_device * dev)
+{
+	int retval = 0;
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	if (devpriv->enable_irq) {
+		retval = 1;
+#ifdef CONFIG_COMEDI_PCI
+		if (devpriv->lcr_iobase) {
+			if ((inl(devpriv->lcr_iobase + PLX9052_INTCSR)
+					& PLX9052_INTCSR_LI1STAT_MASK)
+				== PLX9052_INTCSR_LI1STAT_INACTIVE) {
+				retval = 0;
+			} else {
+				/* Clear interrupt and keep it enabled. */
+				outl(PCI236_INTR_ENABLE,
+					devpriv->lcr_iobase + PLX9052_INTCSR);
+			}
+		}
+#endif
+	}
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	return retval;
+}
+
+/*
+ * Input from subdevice 1.
+ * Copied from the comedi_parport driver.
+ */
+static int pc236_intr_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	data[1] = 0;
+	return 2;
+}
+
+/*
+ * Subdevice 1 command test.
+ * Copied from the comedi_parport driver.
+ */
+static int pc236_intr_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp;
+
+	/* step 1 */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_EXT;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_FOLLOW;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: ignored */
+
+	if (err)
+		return 2;
+
+	/* step 3: */
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+	if (cmd->scan_begin_arg != 0) {
+		cmd->scan_begin_arg = 0;
+		err++;
+	}
+	if (cmd->convert_arg != 0) {
+		cmd->convert_arg = 0;
+		err++;
+	}
+	if (cmd->scan_end_arg != 1) {
+		cmd->scan_end_arg = 1;
+		err++;
+	}
+	if (cmd->stop_arg != 0) {
+		cmd->stop_arg = 0;
+		err++;
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: ignored */
+
+	if (err)
+		return 4;
+
+	return 0;
+}
+
+/*
+ * Subdevice 1 command.
+ */
+static int pc236_intr_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	pc236_intr_enable(dev);
+
+	return 0;
+}
+
+/*
+ * Subdevice 1 cancel command.
+ */
+static int pc236_intr_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	pc236_intr_disable(dev);
+
+	return 0;
+}
+
+/*
+ * Interrupt service routine.
+ * Based on the comedi_parport driver.
+ */
+static irqreturn_t pc236_interrupt(int irq, void *d PT_REGS_ARG)
+{
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s = dev->subdevices + 1;
+	int handled;
+
+	handled = pc236_intr_check(dev);
+	if (dev->attached && handled) {
+		comedi_buf_put(s->async, 0);
+		s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
+		comedi_event(dev, s);
+	}
+	return IRQ_RETVAL(handled);
+}
diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c
new file mode 100644
index 0000000..97ac415
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amplc_pc263.c
@@ -0,0 +1,431 @@
+/*
+    comedi/drivers/amplc_pc263.c
+    Driver for Amplicon PC263 and PCI263 relay boards.
+
+    Copyright (C) 2002 MEV Ltd. <http://www.mev.co.uk/>
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: amplc_pc263
+Description: Amplicon PC263, PCI263
+Author: Ian Abbott <abbotti@mev.co.uk>
+Devices: [Amplicon] PC263 (pc263), PCI263 (pci263 or amplc_pc263)
+Updated: Wed, 22 Oct 2008 14:10:53 +0100
+Status: works
+
+Configuration options - PC263:
+  [0] - I/O port base address
+
+Configuration options - PCI263:
+  [0] - PCI bus of device (optional)
+  [1] - PCI slot of device (optional)
+  If bus/slot is not specified, the first available PCI device will be
+  used.
+
+Each board appears as one subdevice, with 16 digital outputs, each
+connected to a reed-relay. Relay contacts are closed when output is 1.
+The state of the outputs can be read.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+#define PC263_DRIVER_NAME	"amplc_pc263"
+
+/* PCI263 PCI configuration register information */
+#define PCI_VENDOR_ID_AMPLICON 0x14dc
+#define PCI_DEVICE_ID_AMPLICON_PCI263 0x000c
+#define PCI_DEVICE_ID_INVALID 0xffff
+
+/* PC263 / PCI263 registers */
+#define PC263_IO_SIZE	2
+
+/*
+ * Board descriptions for Amplicon PC263 / PCI263.
+ */
+
+enum pc263_bustype { isa_bustype, pci_bustype };
+enum pc263_model { pc263_model, pci263_model, anypci_model };
+
+struct pc263_board {
+	const char *name;
+	const char *fancy_name;
+	unsigned short devid;
+	enum pc263_bustype bustype;
+	enum pc263_model model;
+};
+static const struct pc263_board pc263_boards[] = {
+	{
+	      name:	"pc263",
+	      fancy_name:"PC263",
+	      bustype:	isa_bustype,
+	      model:	pc263_model,
+		},
+#ifdef CONFIG_COMEDI_PCI
+	{
+	      name:	"pci263",
+	      fancy_name:"PCI263",
+	      devid:	PCI_DEVICE_ID_AMPLICON_PCI263,
+	      bustype:	pci_bustype,
+	      model:	pci263_model,
+		},
+#endif
+#ifdef CONFIG_COMEDI_PCI
+	{
+	      name:	PC263_DRIVER_NAME,
+	      fancy_name:PC263_DRIVER_NAME,
+	      devid:	PCI_DEVICE_ID_INVALID,
+	      bustype:	pci_bustype,
+	      model:	anypci_model,	/* wildcard */
+		},
+#endif
+};
+
+#ifdef CONFIG_COMEDI_PCI
+static DEFINE_PCI_DEVICE_TABLE(pc263_pci_table) = {
+	{PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI263, PCI_ANY_ID,
+		PCI_ANY_ID, 0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, pc263_pci_table);
+#endif /* CONFIG_COMEDI_PCI */
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct pc263_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver.  If
+   several hardware drivers keep similar information in this structure,
+   feel free to suggest moving the variable to the struct comedi_device struct.  */
+#ifdef CONFIG_COMEDI_PCI
+struct pc263_private {
+	/* PCI device. */
+	struct pci_dev *pci_dev;
+};
+
+#define devpriv ((struct pc263_private *)dev->private)
+#endif /* CONFIG_COMEDI_PCI */
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pc263_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pc263_detach(struct comedi_device * dev);
+static struct comedi_driver driver_amplc_pc263 = {
+      driver_name:PC263_DRIVER_NAME,
+      module:THIS_MODULE,
+      attach:pc263_attach,
+      detach:pc263_detach,
+      board_name:&pc263_boards[0].name,
+      offset:sizeof(struct pc263_board),
+      num_names:sizeof(pc263_boards) / sizeof(struct pc263_board),
+};
+
+static int pc263_request_region(unsigned minor, unsigned long from,
+	unsigned long extent);
+static int pc263_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int pc263_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+/*
+ * This function looks for a PCI device matching the requested board name,
+ * bus and slot.
+ */
+#ifdef CONFIG_COMEDI_PCI
+static int
+pc263_find_pci(struct comedi_device * dev, int bus, int slot,
+	struct pci_dev **pci_dev_p)
+{
+	struct pci_dev *pci_dev = NULL;
+
+	*pci_dev_p = NULL;
+
+	/* Look for matching PCI device. */
+	for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
+		pci_dev != NULL;
+		pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
+			PCI_ANY_ID, pci_dev)) {
+		/* If bus/slot specified, check them. */
+		if (bus || slot) {
+			if (bus != pci_dev->bus->number
+				|| slot != PCI_SLOT(pci_dev->devfn))
+				continue;
+		}
+		if (thisboard->model == anypci_model) {
+			/* Match any supported model. */
+			int i;
+
+			for (i = 0; i < ARRAY_SIZE(pc263_boards); i++) {
+				if (pc263_boards[i].bustype != pci_bustype)
+					continue;
+				if (pci_dev->device == pc263_boards[i].devid) {
+					/* Change board_ptr to matched board. */
+					dev->board_ptr = &pc263_boards[i];
+					break;
+				}
+			}
+			if (i == ARRAY_SIZE(pc263_boards))
+				continue;
+		} else {
+			/* Match specific model name. */
+			if (pci_dev->device != thisboard->devid)
+				continue;
+		}
+
+		/* Found a match. */
+		*pci_dev_p = pci_dev;
+		return 0;
+	}
+	/* No match found. */
+	if (bus || slot) {
+		printk(KERN_ERR
+			"comedi%d: error! no %s found at pci %02x:%02x!\n",
+			dev->minor, thisboard->name, bus, slot);
+	} else {
+		printk(KERN_ERR "comedi%d: error! no %s found!\n",
+			dev->minor, thisboard->name);
+	}
+	return -EIO;
+}
+#endif
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board.  If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pc263_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	unsigned long iobase = 0;
+#ifdef CONFIG_COMEDI_PCI
+	struct pci_dev *pci_dev = NULL;
+	int bus = 0, slot = 0;
+#endif
+	int ret;
+
+	printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
+		PC263_DRIVER_NAME);
+/*
+ * Allocate the private structure area.  alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+#ifdef CONFIG_COMEDI_PCI
+	if ((ret = alloc_private(dev, sizeof(struct pc263_private))) < 0) {
+		printk(KERN_ERR "comedi%d: error! out of memory!\n",
+			dev->minor);
+		return ret;
+	}
+#endif
+	/* Process options. */
+	switch (thisboard->bustype) {
+	case isa_bustype:
+		iobase = it->options[0];
+		break;
+#ifdef CONFIG_COMEDI_PCI
+	case pci_bustype:
+		bus = it->options[0];
+		slot = it->options[1];
+
+		if ((ret = pc263_find_pci(dev, bus, slot, &pci_dev)) < 0)
+			return ret;
+		devpriv->pci_dev = pci_dev;
+		break;
+#endif /* CONFIG_COMEDI_PCI */
+	default:
+		printk(KERN_ERR
+			"comedi%d: %s: BUG! cannot determine board type!\n",
+			dev->minor, PC263_DRIVER_NAME);
+		return -EINVAL;
+		break;
+	}
+
+/*
+ * Initialize dev->board_name.
+ */
+	dev->board_name = thisboard->name;
+
+	/* Enable device and reserve I/O spaces. */
+#ifdef CONFIG_COMEDI_PCI
+	if (pci_dev) {
+		if ((ret = comedi_pci_enable(pci_dev, PC263_DRIVER_NAME)) < 0) {
+			printk(KERN_ERR
+				"comedi%d: error! cannot enable PCI device and request regions!\n",
+				dev->minor);
+			return ret;
+		}
+		iobase = pci_resource_start(pci_dev, 2);
+	} else
+#endif
+	{
+		ret = pc263_request_region(dev->minor, iobase, PC263_IO_SIZE);
+		if (ret < 0) {
+			return ret;
+		}
+	}
+	dev->iobase = iobase;
+
+/*
+ * Allocate the subdevice structures.  alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+	if ((ret = alloc_subdevices(dev, 1)) < 0) {
+		printk(KERN_ERR "comedi%d: error! out of memory!\n",
+			dev->minor);
+		return ret;
+	}
+
+	s = dev->subdevices + 0;
+	/* digital i/o subdevice */
+	s->type = COMEDI_SUBD_DIO;
+	s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_RT;
+	s->n_chan = 16;
+	s->maxdata = 1;
+	s->range_table = &range_digital;
+	s->insn_bits = pc263_dio_insn_bits;
+	s->insn_config = pc263_dio_insn_config;
+	/* all outputs */
+	s->io_bits = 0xffff;
+	/* read initial relay state */
+	s->state = inb(dev->iobase);
+	s->state = s->state | (inb(dev->iobase) << 8);
+
+	printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
+	if (thisboard->bustype == isa_bustype) {
+		printk("(base %#lx) ", iobase);
+	} else {
+#ifdef CONFIG_COMEDI_PCI
+		printk("(pci %s) ", pci_name(pci_dev));
+#endif
+	}
+
+	printk("attached\n");
+
+	return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device.  It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach().  dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pc263_detach(struct comedi_device * dev)
+{
+	printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
+		PC263_DRIVER_NAME);
+
+#ifdef CONFIG_COMEDI_PCI
+	if (devpriv)
+#endif
+	{
+#ifdef CONFIG_COMEDI_PCI
+		if (devpriv->pci_dev) {
+			if (dev->iobase) {
+				comedi_pci_disable(devpriv->pci_dev);
+			}
+			pci_dev_put(devpriv->pci_dev);
+		} else
+#endif
+		{
+			if (dev->iobase) {
+				release_region(dev->iobase, PC263_IO_SIZE);
+			}
+		}
+	}
+	if (dev->board_name) {
+		printk(KERN_INFO "comedi%d: %s removed\n",
+			dev->minor, dev->board_name);
+	}
+	return 0;
+}
+
+/*
+ * This function checks and requests an I/O region, reporting an error
+ * if there is a conflict.
+ */
+static int pc263_request_region(unsigned minor, unsigned long from,
+	unsigned long extent)
+{
+	if (!from || !request_region(from, extent, PC263_DRIVER_NAME)) {
+		printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n",
+			minor, from, extent);
+		return -EIO;
+	}
+	return 0;
+}
+
+/* DIO devices are slightly special.  Although it is possible to
+ * implement the insn_read/insn_write interface, it is much more
+ * useful to applications if you implement the insn_bits interface.
+ * This allows packed reading/writing of the DIO channels.  The
+ * comedi core can convert between insn_bits and insn_read/write */
+static int pc263_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	/* The insn data is a mask in data[0] and the new data
+	 * in data[1], each channel cooresponding to a bit. */
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= data[0] & data[1];
+		/* Write out the new digital output lines */
+		outb(s->state & 0xFF, dev->iobase);
+		outb(s->state >> 8, dev->iobase + 1);
+	}
+
+	/* on return, data[1] contains the value of the digital
+	 * input and output lines. */
+	/* or we could just return the software copy of the output values if
+	 * it was a purely digital output subdevice */
+	data[1] = s->state;
+
+	return 2;
+}
+
+static int pc263_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 1)
+		return -EINVAL;
+	return 1;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+#ifdef CONFIG_COMEDI_PCI
+COMEDI_PCI_INITCLEANUP(driver_amplc_pc263, pc263_pci_table);
+#else
+COMEDI_INITCLEANUP(driver_amplc_pc263);
+#endif
diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c
new file mode 100644
index 0000000..770b966
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amplc_pci224.c
@@ -0,0 +1,1545 @@
+/*
+    comedi/drivers/amplc_pci224.c
+    Driver for Amplicon PCI224 and PCI234 AO boards.
+
+    Copyright (C) 2005 MEV Ltd. <http://www.mev.co.uk/>
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 1998,2000 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: amplc_pci224
+Description: Amplicon PCI224, PCI234
+Author: Ian Abbott <abbotti@mev.co.uk>
+Devices: [Amplicon] PCI224 (amplc_pci224 or pci224),
+  PCI234 (amplc_pci224 or pci234)
+Updated: Wed, 22 Oct 2008 12:25:08 +0100
+Status: works, but see caveats
+
+Supports:
+
+  - ao_insn read/write
+  - ao_do_cmd mode with the following sources:
+
+    - start_src         TRIG_INT        TRIG_EXT
+    - scan_begin_src    TRIG_TIMER      TRIG_EXT
+    - convert_src       TRIG_NOW
+    - scan_end_src      TRIG_COUNT
+    - stop_src          TRIG_COUNT      TRIG_EXT        TRIG_NONE
+
+    The channel list must contain at least one channel with no repeated
+    channels.  The scan end count must equal the number of channels in
+    the channel list.
+
+    There is only one external trigger source so only one of start_src,
+    scan_begin_src or stop_src may use TRIG_EXT.
+
+Configuration options - PCI224:
+  [0] - PCI bus of device (optional).
+  [1] - PCI slot of device (optional).
+          If bus/slot is not specified, the first available PCI device
+          will be used.
+  [2] - Select available ranges according to jumper LK1.  All channels
+        are set to the same range:
+        0=Jumper position 1-2 (factory default), 4 software-selectable
+          internal voltage references, giving 4 bipolar and 4 unipolar
+          ranges:
+            [-10V,+10V], [-5V,+5V], [-2.5V,+2.5V], [-1.25V,+1.25V],
+            [0,+10V], [0,+5V], [0,+2.5V], [0,1.25V].
+        1=Jumper position 2-3, 1 external voltage reference, giving
+          1 bipolar and 1 unipolar range:
+            [-Vext,+Vext], [0,+Vext].
+
+Configuration options - PCI234:
+  [0] - PCI bus of device (optional).
+  [1] - PCI slot of device (optional).
+          If bus/slot is not specified, the first available PCI device
+          will be used.
+  [2] - Select internal or external voltage reference according to
+        jumper LK1.  This affects all channels:
+        0=Jumper position 1-2 (factory default), Vref=5V internal.
+        1=Jumper position 2-3, Vref=Vext external.
+  [3] - Select channel 0 range according to jumper LK2:
+        0=Jumper position 2-3 (factory default), range [-2*Vref,+2*Vref]
+          (10V bipolar when options[2]=0).
+        1=Jumper position 1-2, range [-Vref,+Vref]
+          (5V bipolar when options[2]=0).
+  [4] - Select channel 1 range according to jumper LK3: cf. options[3].
+  [5] - Select channel 2 range according to jumper LK4: cf. options[3].
+  [6] - Select channel 3 range according to jumper LK5: cf. options[3].
+
+Passing a zero for an option is the same as leaving it unspecified.
+
+Caveats:
+
+  1) All channels on the PCI224 share the same range.  Any change to the
+     range as a result of insn_write or a streaming command will affect
+     the output voltages of all channels, including those not specified
+     by the instruction or command.
+
+  2) For the analog output command,  the first scan may be triggered
+     falsely at the start of acquisition.  This occurs when the DAC scan
+     trigger source is switched from 'none' to 'timer' (scan_begin_src =
+     TRIG_TIMER) or 'external' (scan_begin_src == TRIG_EXT) at the start
+     of acquisition and the trigger source is at logic level 1 at the
+     time of the switch.  This is very likely for TRIG_TIMER.  For
+     TRIG_EXT, it depends on the state of the external line and whether
+     the CR_INVERT flag has been set.  The remaining scans are triggered
+     correctly.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+#include "comedi_fc.h"
+#include "8253.h"
+
+#define DRIVER_NAME	"amplc_pci224"
+
+/*
+ * PCI IDs.
+ */
+/* #define PCI_VENDOR_ID_AMPLICON 0x14dc */
+#define PCI_DEVICE_ID_AMPLICON_PCI224 0x0007
+#define PCI_DEVICE_ID_AMPLICON_PCI234 0x0008
+#define PCI_DEVICE_ID_INVALID 0xffff
+
+/*
+ * PCI224/234 i/o space 1 (PCIBAR2) registers.
+ */
+#define PCI224_IO1_SIZE	0x20	/* Size of i/o space 1 (8-bit registers) */
+#define PCI224_Z2_CT0	0x14	/* 82C54 counter/timer 0 */
+#define PCI224_Z2_CT1	0x15	/* 82C54 counter/timer 1 */
+#define PCI224_Z2_CT2	0x16	/* 82C54 counter/timer 2 */
+#define PCI224_Z2_CTC	0x17	/* 82C54 counter/timer control word */
+#define PCI224_ZCLK_SCE	0x1A	/* Group Z Clock Configuration Register */
+#define PCI224_ZGAT_SCE	0x1D	/* Group Z Gate Configuration Register */
+#define PCI224_INT_SCE	0x1E	/* ISR Interrupt source mask register */
+				/* /Interrupt status */
+
+/*
+ * PCI224/234 i/o space 2 (PCIBAR3) 16-bit registers.
+ */
+#define PCI224_IO2_SIZE	0x10	/* Size of i/o space 2 (16-bit registers). */
+#define PCI224_DACDATA	0x00	/* (w-o) DAC FIFO data. */
+#define PCI224_SOFTTRIG	0x00	/* (r-o) DAC software scan trigger. */
+#define PCI224_DACCON	0x02	/* (r/w) DAC status/configuration. */
+#define PCI224_FIFOSIZ	0x04	/* (w-o) FIFO size for wraparound mode. */
+#define PCI224_DACCEN	0x06	/* (w-o) DAC channel enable register. */
+
+/*
+ * DACCON values.
+ */
+/* (r/w) Scan trigger. */
+#define PCI224_DACCON_TRIG_MASK		(7 << 0)
+#define PCI224_DACCON_TRIG_NONE		(0 << 0)	/* none */
+#define PCI224_DACCON_TRIG_SW		(1 << 0)	/* software trig */
+#define PCI224_DACCON_TRIG_EXTP		(2 << 0)	/* ext +ve edge */
+#define PCI224_DACCON_TRIG_EXTN		(3 << 0)	/* ext -ve edge */
+#define PCI224_DACCON_TRIG_Z2CT0	(4 << 0)	/* Z2 CT0 out */
+#define PCI224_DACCON_TRIG_Z2CT1	(5 << 0)	/* Z2 CT1 out */
+#define PCI224_DACCON_TRIG_Z2CT2	(6 << 0)	/* Z2 CT2 out */
+/* (r/w) Polarity (PCI224 only, PCI234 always bipolar!). */
+#define PCI224_DACCON_POLAR_MASK	(1 << 3)
+#define PCI224_DACCON_POLAR_UNI		(0 << 3)	/* range [0,Vref] */
+#define PCI224_DACCON_POLAR_BI		(1 << 3)	/* range [-Vref,Vref] */
+/* (r/w) Internal Vref (PCI224 only, when LK1 in position 1-2). */
+#define PCI224_DACCON_VREF_MASK		(3 << 4)
+#define PCI224_DACCON_VREF_1_25		(0 << 4)	/* Vref = 1.25V */
+#define PCI224_DACCON_VREF_2_5		(1 << 4)	/* Vref = 2.5V */
+#define PCI224_DACCON_VREF_5		(2 << 4)	/* Vref = 5V */
+#define PCI224_DACCON_VREF_10		(3 << 4)	/* Vref = 10V */
+/* (r/w) Wraparound mode enable (to play back stored waveform). */
+#define PCI224_DACCON_FIFOWRAP		(1 << 7)
+/* (r/w) FIFO enable.  It MUST be set! */
+#define PCI224_DACCON_FIFOENAB		(1 << 8)
+/* (r/w) FIFO interrupt trigger level (most values are not very useful). */
+#define PCI224_DACCON_FIFOINTR_MASK	(7 << 9)
+#define PCI224_DACCON_FIFOINTR_EMPTY	(0 << 9)	/* when empty */
+#define PCI224_DACCON_FIFOINTR_NEMPTY	(1 << 9)	/* when not empty */
+#define PCI224_DACCON_FIFOINTR_NHALF	(2 << 9)	/* when not half full */
+#define PCI224_DACCON_FIFOINTR_HALF	(3 << 9)	/* when half full */
+#define PCI224_DACCON_FIFOINTR_NFULL	(4 << 9)	/* when not full */
+#define PCI224_DACCON_FIFOINTR_FULL	(5 << 9)	/* when full */
+/* (r-o) FIFO fill level. */
+#define PCI224_DACCON_FIFOFL_MASK	(7 << 12)
+#define PCI224_DACCON_FIFOFL_EMPTY	(1 << 12)	/* 0 */
+#define PCI224_DACCON_FIFOFL_ONETOHALF	(0 << 12)	/* [1,2048] */
+#define PCI224_DACCON_FIFOFL_HALFTOFULL	(4 << 12)	/* [2049,4095] */
+#define PCI224_DACCON_FIFOFL_FULL	(6 << 12)	/* 4096 */
+/* (r-o) DAC busy flag. */
+#define PCI224_DACCON_BUSY		(1 << 15)
+/* (w-o) FIFO reset. */
+#define PCI224_DACCON_FIFORESET		(1 << 12)
+/* (w-o) Global reset (not sure what it does). */
+#define PCI224_DACCON_GLOBALRESET	(1 << 13)
+
+/*
+ * DAC FIFO size.
+ */
+#define PCI224_FIFO_SIZE	4096
+
+/*
+ * DAC FIFO guaranteed minimum room available, depending on reported fill level.
+ * The maximum room available depends on the reported fill level and how much
+ * has been written!
+ */
+#define PCI224_FIFO_ROOM_EMPTY		PCI224_FIFO_SIZE
+#define PCI224_FIFO_ROOM_ONETOHALF	(PCI224_FIFO_SIZE / 2)
+#define PCI224_FIFO_ROOM_HALFTOFULL	1
+#define PCI224_FIFO_ROOM_FULL		0
+
+/*
+ * Counter/timer clock input configuration sources.
+ */
+#define CLK_CLK		0	/* reserved (channel-specific clock) */
+#define CLK_10MHZ	1	/* internal 10 MHz clock */
+#define CLK_1MHZ	2	/* internal 1 MHz clock */
+#define CLK_100KHZ	3	/* internal 100 kHz clock */
+#define CLK_10KHZ	4	/* internal 10 kHz clock */
+#define CLK_1KHZ	5	/* internal 1 kHz clock */
+#define CLK_OUTNM1	6	/* output of channel-1 modulo total */
+#define CLK_EXT		7	/* external clock */
+/* Macro to construct clock input configuration register value. */
+#define CLK_CONFIG(chan, src)	((((chan) & 3) << 3) | ((src) & 7))
+/* Timebases in ns. */
+#define TIMEBASE_10MHZ		100
+#define TIMEBASE_1MHZ		1000
+#define TIMEBASE_100KHZ		10000
+#define TIMEBASE_10KHZ		100000
+#define TIMEBASE_1KHZ		1000000
+
+/*
+ * Counter/timer gate input configuration sources.
+ */
+#define GAT_VCC		0	/* VCC (i.e. enabled) */
+#define GAT_GND		1	/* GND (i.e. disabled) */
+#define GAT_EXT		2	/* reserved (external gate input) */
+#define GAT_NOUTNM2	3	/* inverted output of channel-2 modulo total */
+/* Macro to construct gate input configuration register value. */
+#define GAT_CONFIG(chan, src)	((((chan) & 3) << 3) | ((src) & 7))
+
+/*
+ * Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI224 and PCI234:
+ *
+ *              Channel's       Channel's
+ *              clock input     gate input
+ * Channel      CLK_OUTNM1      GAT_NOUTNM2
+ * -------      ----------      -----------
+ * Z2-CT0       Z2-CT2-OUT      /Z2-CT1-OUT
+ * Z2-CT1       Z2-CT0-OUT      /Z2-CT2-OUT
+ * Z2-CT2       Z2-CT1-OUT      /Z2-CT0-OUT
+ */
+
+/*
+ * Interrupt enable/status bits
+ */
+#define PCI224_INTR_EXT		0x01	/* rising edge on external input */
+#define PCI224_INTR_DAC		0x04	/* DAC (FIFO) interrupt */
+#define PCI224_INTR_Z2CT1	0x20	/* rising edge on Z2-CT1 output */
+
+#define PCI224_INTR_EDGE_BITS	(PCI224_INTR_EXT | PCI224_INTR_Z2CT1)
+#define PCI224_INTR_LEVEL_BITS	PCI224_INTR_DACFIFO
+
+/*
+ * Handy macros.
+ */
+
+/* Combine old and new bits. */
+#define COMBINE(old, new, mask)	(((old) & ~(mask)) | ((new) & (mask)))
+
+/* A generic null function pointer value.  */
+#define NULLFUNC	0
+
+/* Current CPU.  XXX should this be hard_smp_processor_id()? */
+#define THISCPU		smp_processor_id()
+
+/* State bits for use with atomic bit operations. */
+#define AO_CMD_STARTED	0
+
+/*
+ * Range tables.
+ */
+
+/* The software selectable internal ranges for PCI224 (option[2] == 0). */
+static const struct comedi_lrange range_pci224_internal = {
+	8,
+	{
+			BIP_RANGE(10),
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+			UNI_RANGE(10),
+			UNI_RANGE(5),
+			UNI_RANGE(2.5),
+			UNI_RANGE(1.25),
+		}
+};
+
+static const unsigned short hwrange_pci224_internal[8] = {
+	PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_10,
+	PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_5,
+	PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_2_5,
+	PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_1_25,
+	PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_10,
+	PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_5,
+	PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_2_5,
+	PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_1_25,
+};
+
+/* The software selectable external ranges for PCI224 (option[2] == 1). */
+static const struct comedi_lrange range_pci224_external = {
+	2,
+	{
+			RANGE_ext(-1, 1),	/* bipolar [-Vref,+Vref] */
+			RANGE_ext(0, 1),	/* unipolar [0,+Vref] */
+		}
+};
+
+static const unsigned short hwrange_pci224_external[2] = {
+	PCI224_DACCON_POLAR_BI,
+	PCI224_DACCON_POLAR_UNI,
+};
+
+/* The hardware selectable Vref*2 external range for PCI234
+ * (option[2] == 1, option[3+n] == 0). */
+static const struct comedi_lrange range_pci234_ext2 = {
+	1,
+	{
+			RANGE_ext(-2, 2),
+		}
+};
+
+/* The hardware selectable Vref external range for PCI234
+ * (option[2] == 1, option[3+n] == 1). */
+static const struct comedi_lrange range_pci234_ext = {
+	1,
+	{
+			RANGE_ext(-1, 1),
+		}
+};
+
+/* This serves for all the PCI234 ranges. */
+static const unsigned short hwrange_pci234[1] = {
+	PCI224_DACCON_POLAR_BI,	/* bipolar - hardware ignores it! */
+};
+
+/*
+ * Board descriptions.
+ */
+
+enum pci224_model { any_model, pci224_model, pci234_model };
+
+struct pci224_board {
+	const char *name;
+	unsigned short devid;
+	enum pci224_model model;
+	unsigned int ao_chans;
+	unsigned int ao_bits;
+};
+
+static const struct pci224_board pci224_boards[] = {
+	{
+	      name:	"pci224",
+	      devid: PCI_DEVICE_ID_AMPLICON_PCI224,
+	      model:	pci224_model,
+	      ao_chans:16,
+	      ao_bits:	12,
+		},
+	{
+	      name:	"pci234",
+	      devid: PCI_DEVICE_ID_AMPLICON_PCI234,
+	      model:	pci234_model,
+	      ao_chans:4,
+	      ao_bits:	16,
+		},
+	{
+	      name:	DRIVER_NAME,
+	      devid: PCI_DEVICE_ID_INVALID,
+	      model:	any_model,	/* wildcard */
+		},
+};
+
+/*
+ * PCI driver table.
+ */
+
+static DEFINE_PCI_DEVICE_TABLE(pci224_pci_table) = {
+	{PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI224,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI234,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci224_pci_table);
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((struct pci224_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver.  If
+   several hardware drivers keep similar information in this structure,
+   feel free to suggest moving the variable to the struct comedi_device struct.  */
+struct pci224_private {
+	struct pci_dev *pci_dev;	/* PCI device */
+	const unsigned short *hwrange;
+	unsigned long iobase1;
+	unsigned long state;
+	spinlock_t ao_spinlock;
+	unsigned int *ao_readback;
+	short *ao_scan_vals;
+	unsigned char *ao_scan_order;
+	int intr_cpuid;
+	short intr_running;
+	unsigned short daccon;
+	unsigned int cached_div1;
+	unsigned int cached_div2;
+	unsigned int ao_stop_count;
+	short ao_stop_continuous;
+	unsigned short ao_enab;	/* max 16 channels so 'short' will do */
+	unsigned char intsce;
+};
+
+#define devpriv ((struct pci224_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pci224_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci224_detach(struct comedi_device * dev);
+static struct comedi_driver driver_amplc_pci224 = {
+      driver_name:DRIVER_NAME,
+      module:THIS_MODULE,
+      attach:pci224_attach,
+      detach:pci224_detach,
+      board_name:&pci224_boards[0].name,
+      offset:sizeof(struct pci224_board),
+      num_names:sizeof(pci224_boards) / sizeof(struct pci224_board),
+};
+
+COMEDI_PCI_INITCLEANUP(driver_amplc_pci224, pci224_pci_table);
+
+/*
+ * Called from the 'insn_write' function to perform a single write.
+ */
+static void
+pci224_ao_set_data(struct comedi_device * dev, int chan, int range, unsigned int data)
+{
+	unsigned short mangled;
+
+	/* Store unmangled data for readback. */
+	devpriv->ao_readback[chan] = data;
+	/* Enable the channel. */
+	outw(1 << chan, dev->iobase + PCI224_DACCEN);
+	/* Set range and reset FIFO. */
+	devpriv->daccon = COMBINE(devpriv->daccon, devpriv->hwrange[range],
+		(PCI224_DACCON_POLAR_MASK | PCI224_DACCON_VREF_MASK));
+	outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
+		dev->iobase + PCI224_DACCON);
+	/*
+	 * Mangle the data.  The hardware expects:
+	 * - bipolar: 16-bit 2's complement
+	 * - unipolar: 16-bit unsigned
+	 */
+	mangled = (unsigned short)data << (16 - thisboard->ao_bits);
+	if ((devpriv->daccon & PCI224_DACCON_POLAR_MASK) ==
+		PCI224_DACCON_POLAR_BI) {
+		mangled ^= 0x8000;
+	}
+	/* Write mangled data to the FIFO. */
+	outw(mangled, dev->iobase + PCI224_DACDATA);
+	/* Trigger the conversion. */
+	inw(dev->iobase + PCI224_SOFTTRIG);
+}
+
+/*
+ * 'insn_write' function for AO subdevice.
+ */
+static int
+pci224_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan, range;
+
+	/* Unpack channel and range. */
+	chan = CR_CHAN(insn->chanspec);
+	range = CR_RANGE(insn->chanspec);
+
+	/* Writing a list of values to an AO channel is probably not
+	 * very useful, but that's how the interface is defined. */
+	for (i = 0; i < insn->n; i++) {
+		pci224_ao_set_data(dev, chan, range, data[i]);
+	}
+	return i;
+}
+
+/*
+ * 'insn_read' function for AO subdevice.
+ *
+ * N.B. The value read will not be valid if the DAC channel has
+ * never been written successfully since the device was attached
+ * or since the channel has been used by an AO streaming write
+ * command.
+ */
+static int
+pci224_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan;
+
+	chan = CR_CHAN(insn->chanspec);
+
+	for (i = 0; i < insn->n; i++) {
+		data[i] = devpriv->ao_readback[chan];
+	}
+
+	return i;
+}
+
+/*
+ * Just a wrapper for the inline function 'i8253_cascade_ns_to_timer'.
+ */
+static void
+pci224_cascade_ns_to_timer(int osc_base, unsigned int *d1, unsigned int *d2,
+	unsigned int *nanosec, int round_mode)
+{
+	i8253_cascade_ns_to_timer(osc_base, d1, d2, nanosec, round_mode);
+}
+
+/*
+ * Kills a command running on the AO subdevice.
+ */
+static void pci224_ao_stop(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	unsigned long flags;
+
+	if (!test_and_clear_bit(AO_CMD_STARTED, &devpriv->state)) {
+		return;
+	}
+
+	comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
+	/* Kill the interrupts. */
+	devpriv->intsce = 0;
+	outb(0, devpriv->iobase1 + PCI224_INT_SCE);
+	/*
+	 * Interrupt routine may or may not be running.  We may or may not
+	 * have been called from the interrupt routine (directly or
+	 * indirectly via a comedi_events() callback routine).  It's highly
+	 * unlikely that we've been called from some other interrupt routine
+	 * but who knows what strange things coders get up to!
+	 *
+	 * If the interrupt routine is currently running, wait for it to
+	 * finish, unless we appear to have been called via the interrupt
+	 * routine.
+	 */
+	while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
+		comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
+		comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
+	}
+	comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
+	/* Reconfigure DAC for insn_write usage. */
+	outw(0, dev->iobase + PCI224_DACCEN);	/* Disable channels. */
+	devpriv->daccon = COMBINE(devpriv->daccon,
+		PCI224_DACCON_TRIG_SW | PCI224_DACCON_FIFOINTR_EMPTY,
+		PCI224_DACCON_TRIG_MASK | PCI224_DACCON_FIFOINTR_MASK);
+	outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
+		dev->iobase + PCI224_DACCON);
+}
+
+/*
+ * Handles start of acquisition for the AO subdevice.
+ */
+static void pci224_ao_start(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned long flags;
+
+	set_bit(AO_CMD_STARTED, &devpriv->state);
+	if (!devpriv->ao_stop_continuous && devpriv->ao_stop_count == 0) {
+		/* An empty acquisition! */
+		pci224_ao_stop(dev, s);
+		s->async->events |= COMEDI_CB_EOA;
+		comedi_event(dev, s);
+	} else {
+		/* Enable interrupts. */
+		comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
+		if (cmd->stop_src == TRIG_EXT) {
+			devpriv->intsce = PCI224_INTR_EXT | PCI224_INTR_DAC;
+		} else {
+			devpriv->intsce = PCI224_INTR_DAC;
+		}
+		outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
+		comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
+	}
+}
+
+/*
+ * Handles interrupts from the DAC FIFO.
+ */
+static void pci224_ao_handle_fifo(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int num_scans;
+	unsigned int room;
+	unsigned short dacstat;
+	unsigned int i, n;
+	unsigned int bytes_per_scan;
+
+	if (cmd->chanlist_len) {
+		bytes_per_scan = cmd->chanlist_len * sizeof(short);
+	} else {
+		/* Shouldn't get here! */
+		bytes_per_scan = sizeof(short);
+	}
+	/* Determine number of scans available in buffer. */
+	num_scans = comedi_buf_read_n_available(s->async) / bytes_per_scan;
+	if (!devpriv->ao_stop_continuous) {
+		/* Fixed number of scans. */
+		if (num_scans > devpriv->ao_stop_count) {
+			num_scans = devpriv->ao_stop_count;
+		}
+	}
+
+	/* Determine how much room is in the FIFO (in samples). */
+	dacstat = inw(dev->iobase + PCI224_DACCON);
+	switch (dacstat & PCI224_DACCON_FIFOFL_MASK) {
+	case PCI224_DACCON_FIFOFL_EMPTY:
+		room = PCI224_FIFO_ROOM_EMPTY;
+		if (!devpriv->ao_stop_continuous
+			&& devpriv->ao_stop_count == 0) {
+			/* FIFO empty at end of counted acquisition. */
+			pci224_ao_stop(dev, s);
+			s->async->events |= COMEDI_CB_EOA;
+			comedi_event(dev, s);
+			return;
+		}
+		break;
+	case PCI224_DACCON_FIFOFL_ONETOHALF:
+		room = PCI224_FIFO_ROOM_ONETOHALF;
+		break;
+	case PCI224_DACCON_FIFOFL_HALFTOFULL:
+		room = PCI224_FIFO_ROOM_HALFTOFULL;
+		break;
+	default:
+		room = PCI224_FIFO_ROOM_FULL;
+		break;
+	}
+	if (room >= PCI224_FIFO_ROOM_ONETOHALF) {
+		/* FIFO is less than half-full. */
+		if (num_scans == 0) {
+			/* Nothing left to put in the FIFO. */
+			pci224_ao_stop(dev, s);
+			s->async->events |= COMEDI_CB_OVERFLOW;
+			rt_printk(KERN_ERR "comedi%d: "
+				"AO buffer underrun\n", dev->minor);
+		}
+	}
+	/* Determine how many new scans can be put in the FIFO. */
+	if (cmd->chanlist_len) {
+		room /= cmd->chanlist_len;
+	}
+	/* Determine how many scans to process. */
+	if (num_scans > room) {
+		num_scans = room;
+	}
+	/* Process scans. */
+	for (n = 0; n < num_scans; n++) {
+		cfc_read_array_from_buffer(s, &devpriv->ao_scan_vals[0],
+			bytes_per_scan);
+		for (i = 0; i < cmd->chanlist_len; i++) {
+			outw(devpriv->ao_scan_vals[devpriv->
+					ao_scan_order[i]],
+				dev->iobase + PCI224_DACDATA);
+		}
+	}
+	if (!devpriv->ao_stop_continuous) {
+		devpriv->ao_stop_count -= num_scans;
+		if (devpriv->ao_stop_count == 0) {
+			/*
+			 * Change FIFO interrupt trigger level to wait
+			 * until FIFO is empty.
+			 */
+			devpriv->daccon = COMBINE(devpriv->daccon,
+				PCI224_DACCON_FIFOINTR_EMPTY,
+				PCI224_DACCON_FIFOINTR_MASK);
+			outw(devpriv->daccon,
+				dev->iobase + PCI224_DACCON);
+		}
+	}
+	if ((devpriv->daccon & PCI224_DACCON_TRIG_MASK) ==
+		PCI224_DACCON_TRIG_NONE) {
+		unsigned short trig;
+
+		/*
+		 * This is the initial DAC FIFO interrupt at the
+		 * start of the acquisition.  The DAC's scan trigger
+		 * has been set to 'none' up until now.
+		 *
+		 * Now that data has been written to the FIFO, the
+		 * DAC's scan trigger source can be set to the
+		 * correct value.
+		 *
+		 * BUG: The first scan will be triggered immediately
+		 * if the scan trigger source is at logic level 1.
+		 */
+		if (cmd->scan_begin_src == TRIG_TIMER) {
+			trig = PCI224_DACCON_TRIG_Z2CT0;
+		} else {
+			/* cmd->scan_begin_src == TRIG_EXT */
+			if (cmd->scan_begin_arg & CR_INVERT) {
+				trig = PCI224_DACCON_TRIG_EXTN;
+			} else {
+				trig = PCI224_DACCON_TRIG_EXTP;
+			}
+		}
+		devpriv->daccon = COMBINE(devpriv->daccon, trig,
+			PCI224_DACCON_TRIG_MASK);
+		outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
+	}
+	if (s->async->events) {
+		comedi_event(dev, s);
+	}
+}
+
+/*
+ * Internal trigger function to start acquisition on AO subdevice.
+ */
+static int
+pci224_ao_inttrig_start(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int trignum)
+{
+	if (trignum != 0)
+		return -EINVAL;
+
+	s->async->inttrig = NULLFUNC;
+	pci224_ao_start(dev, s);
+
+	return 1;
+}
+
+#define MAX_SCAN_PERIOD		0xFFFFFFFFU
+#define MIN_SCAN_PERIOD		2500
+#define CONVERT_PERIOD		625
+
+/*
+ * 'do_cmdtest' function for AO subdevice.
+ */
+static int
+pci224_ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s, struct comedi_cmd * cmd)
+{
+	int err = 0;
+	unsigned int tmp;
+
+	/* Step 1: make sure trigger sources are trivially valid. */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_INT | TRIG_EXT;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_EXT | TRIG_TIMER;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_NOW;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* Step 2: make sure trigger sources are unique and mutually
+	 * compatible. */
+
+	/* these tests are true if more than one _src bit is set */
+	if ((cmd->start_src & (cmd->start_src - 1)) != 0)
+		err++;
+	if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
+		err++;
+	if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
+		err++;
+	if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
+		err++;
+	if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
+		err++;
+
+	/* There's only one external trigger signal (which makes these
+	 * tests easier).  Only one thing can use it. */
+	tmp = 0;
+	if (cmd->start_src & TRIG_EXT)
+		tmp++;
+	if (cmd->scan_begin_src & TRIG_EXT)
+		tmp++;
+	if (cmd->stop_src & TRIG_EXT)
+		tmp++;
+	if (tmp > 1)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* Step 3: make sure arguments are trivially compatible. */
+
+	switch (cmd->start_src) {
+	case TRIG_INT:
+		if (cmd->start_arg != 0) {
+			cmd->start_arg = 0;
+			err++;
+		}
+		break;
+	case TRIG_EXT:
+		/* Force to external trigger 0. */
+		if ((cmd->start_arg & ~CR_FLAGS_MASK) != 0) {
+			cmd->start_arg = COMBINE(cmd->start_arg, 0,
+				~CR_FLAGS_MASK);
+			err++;
+		}
+		/* The only flag allowed is CR_EDGE, which is ignored. */
+		if ((cmd->start_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
+			cmd->start_arg = COMBINE(cmd->start_arg, 0,
+				CR_FLAGS_MASK & ~CR_EDGE);
+			err++;
+		}
+		break;
+	}
+
+	switch (cmd->scan_begin_src) {
+	case TRIG_TIMER:
+		if (cmd->scan_begin_arg > MAX_SCAN_PERIOD) {
+			cmd->scan_begin_arg = MAX_SCAN_PERIOD;
+			err++;
+		}
+		tmp = cmd->chanlist_len * CONVERT_PERIOD;
+		if (tmp < MIN_SCAN_PERIOD) {
+			tmp = MIN_SCAN_PERIOD;
+		}
+		if (cmd->scan_begin_arg < tmp) {
+			cmd->scan_begin_arg = tmp;
+			err++;
+		}
+		break;
+	case TRIG_EXT:
+		/* Force to external trigger 0. */
+		if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
+			cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
+				~CR_FLAGS_MASK);
+			err++;
+		}
+		/* Only allow flags CR_EDGE and CR_INVERT.  Ignore CR_EDGE. */
+		if ((cmd->scan_begin_arg & CR_FLAGS_MASK &
+				~(CR_EDGE | CR_INVERT)) != 0) {
+			cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
+				CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT));
+			err++;
+		}
+		break;
+	}
+
+	/* cmd->convert_src == TRIG_NOW */
+	if (cmd->convert_arg != 0) {
+		cmd->convert_arg = 0;
+		err++;
+	}
+
+	/* cmd->scan_end_arg == TRIG_COUNT */
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+
+	switch (cmd->stop_src) {
+	case TRIG_COUNT:
+		/* Any count allowed. */
+		break;
+	case TRIG_EXT:
+		/* Force to external trigger 0. */
+		if ((cmd->stop_arg & ~CR_FLAGS_MASK) != 0) {
+			cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
+				~CR_FLAGS_MASK);
+			err++;
+		}
+		/* The only flag allowed is CR_EDGE, which is ignored. */
+		if ((cmd->stop_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
+			cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
+				CR_FLAGS_MASK & ~CR_EDGE);
+		}
+		break;
+	case TRIG_NONE:
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+		break;
+	}
+
+	if (err)
+		return 3;
+
+	/* Step 4: fix up any arguments. */
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		unsigned int div1, div2, round;
+		int round_mode = cmd->flags & TRIG_ROUND_MASK;
+
+		tmp = cmd->scan_begin_arg;
+		/* Check whether to use a single timer. */
+		switch (round_mode) {
+		case TRIG_ROUND_NEAREST:
+		default:
+			round = TIMEBASE_10MHZ / 2;
+			break;
+		case TRIG_ROUND_DOWN:
+			round = 0;
+			break;
+		case TRIG_ROUND_UP:
+			round = TIMEBASE_10MHZ - 1;
+			break;
+		}
+		/* Be careful to avoid overflow! */
+		div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
+		div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
+			TIMEBASE_10MHZ;
+		if (div2 <= 0x10000) {
+			/* A single timer will suffice. */
+			if (div2 < 2)
+				div2 = 2;
+			cmd->scan_begin_arg = div2 * TIMEBASE_10MHZ;
+			if (cmd->scan_begin_arg < div2 ||
+				cmd->scan_begin_arg < TIMEBASE_10MHZ) {
+				/* Overflow! */
+				cmd->scan_begin_arg = MAX_SCAN_PERIOD;
+			}
+		} else {
+			/* Use two timers. */
+			div1 = devpriv->cached_div1;
+			div2 = devpriv->cached_div2;
+			pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
+				&cmd->scan_begin_arg, round_mode);
+			devpriv->cached_div1 = div1;
+			devpriv->cached_div2 = div2;
+		}
+		if (tmp != cmd->scan_begin_arg) {
+			err++;
+		}
+	}
+
+	if (err)
+		return 4;
+
+	/* Step 5: check channel list. */
+
+	if (cmd->chanlist && (cmd->chanlist_len > 0)) {
+		unsigned int range;
+		enum { range_err = 1, dupchan_err = 2, };
+		unsigned errors;
+		unsigned int n;
+		unsigned int ch;
+
+		/*
+		 * Check all channels have the same range index.  Don't care
+		 * about analogue reference, as we can't configure it.
+		 *
+		 * Check the list has no duplicate channels.
+		 */
+		range = CR_RANGE(cmd->chanlist[0]);
+		errors = 0;
+		tmp = 0;
+		for (n = 0; n < cmd->chanlist_len; n++) {
+			ch = CR_CHAN(cmd->chanlist[n]);
+			if (tmp & (1U << ch)) {
+				errors |= dupchan_err;
+			}
+			tmp |= (1U << ch);
+			if (CR_RANGE(cmd->chanlist[n]) != range) {
+				errors |= range_err;
+			}
+		}
+		if (errors) {
+			if (errors & dupchan_err) {
+				DPRINTK("comedi%d: " DRIVER_NAME
+					": ao_cmdtest: "
+					"entries in chanlist must contain no "
+					"duplicate channels\n", dev->minor);
+			}
+			if (errors & range_err) {
+				DPRINTK("comedi%d: " DRIVER_NAME
+					": ao_cmdtest: "
+					"entries in chanlist must all have "
+					"the same range index\n", dev->minor);
+			}
+			err++;
+		}
+	}
+
+	if (err)
+		return 5;
+
+	return 0;
+}
+
+/*
+ * 'do_cmd' function for AO subdevice.
+ */
+static int pci224_ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_cmd *cmd = &s->async->cmd;
+	int range;
+	unsigned int i, j;
+	unsigned int ch;
+	unsigned int rank;
+	unsigned long flags;
+
+	/* Cannot handle null/empty chanlist. */
+	if (cmd->chanlist == NULL || cmd->chanlist_len == 0) {
+		return -EINVAL;
+	}
+
+	/* Determine which channels are enabled and their load order.  */
+	devpriv->ao_enab = 0;
+
+	for (i = 0; i < cmd->chanlist_len; i++) {
+		ch = CR_CHAN(cmd->chanlist[i]);
+		devpriv->ao_enab |= 1U << ch;
+		rank = 0;
+		for (j = 0; j < cmd->chanlist_len; j++) {
+			if (CR_CHAN(cmd->chanlist[j]) < ch) {
+				rank++;
+			}
+		}
+		devpriv->ao_scan_order[rank] = i;
+	}
+
+	/* Set enabled channels. */
+	outw(devpriv->ao_enab, dev->iobase + PCI224_DACCEN);
+
+	/* Determine range and polarity.  All channels the same.  */
+	range = CR_RANGE(cmd->chanlist[0]);
+
+	/*
+	 * Set DAC range and polarity.
+	 * Set DAC scan trigger source to 'none'.
+	 * Set DAC FIFO interrupt trigger level to 'not half full'.
+	 * Reset DAC FIFO.
+	 *
+	 * N.B. DAC FIFO interrupts are currently disabled.
+	 */
+	devpriv->daccon = COMBINE(devpriv->daccon,
+		(devpriv->hwrange[range] | PCI224_DACCON_TRIG_NONE |
+			PCI224_DACCON_FIFOINTR_NHALF),
+		(PCI224_DACCON_POLAR_MASK | PCI224_DACCON_VREF_MASK |
+			PCI224_DACCON_TRIG_MASK | PCI224_DACCON_FIFOINTR_MASK));
+	outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
+		dev->iobase + PCI224_DACCON);
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		unsigned int div1, div2, round;
+		unsigned int ns = cmd->scan_begin_arg;
+		int round_mode = cmd->flags & TRIG_ROUND_MASK;
+
+		/* Check whether to use a single timer. */
+		switch (round_mode) {
+		case TRIG_ROUND_NEAREST:
+		default:
+			round = TIMEBASE_10MHZ / 2;
+			break;
+		case TRIG_ROUND_DOWN:
+			round = 0;
+			break;
+		case TRIG_ROUND_UP:
+			round = TIMEBASE_10MHZ - 1;
+			break;
+		}
+		/* Be careful to avoid overflow! */
+		div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
+		div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
+			TIMEBASE_10MHZ;
+		if (div2 <= 0x10000) {
+			/* A single timer will suffice. */
+			if (div2 < 2)
+				div2 = 2;
+			div2 &= 0xffff;
+			div1 = 1;	/* Flag that single timer to be used. */
+		} else {
+			/* Use two timers. */
+			div1 = devpriv->cached_div1;
+			div2 = devpriv->cached_div2;
+			pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
+				&ns, round_mode);
+		}
+
+		/*
+		 * The output of timer Z2-0 will be used as the scan trigger
+		 * source.
+		 */
+		/* Make sure Z2-0 is gated on.  */
+		outb(GAT_CONFIG(0, GAT_VCC),
+			devpriv->iobase1 + PCI224_ZGAT_SCE);
+		if (div1 == 1) {
+			/* Not cascading.  Z2-0 needs 10 MHz clock. */
+			outb(CLK_CONFIG(0, CLK_10MHZ),
+				devpriv->iobase1 + PCI224_ZCLK_SCE);
+		} else {
+			/* Cascading with Z2-2. */
+			/* Make sure Z2-2 is gated on.  */
+			outb(GAT_CONFIG(2, GAT_VCC),
+				devpriv->iobase1 + PCI224_ZGAT_SCE);
+			/* Z2-2 needs 10 MHz clock. */
+			outb(CLK_CONFIG(2, CLK_10MHZ),
+				devpriv->iobase1 + PCI224_ZCLK_SCE);
+			/* Load Z2-2 mode (2) and counter (div1). */
+			i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0,
+				2, div1, 2);
+			/* Z2-0 is clocked from Z2-2's output. */
+			outb(CLK_CONFIG(0, CLK_OUTNM1),
+				devpriv->iobase1 + PCI224_ZCLK_SCE);
+		}
+		/* Load Z2-0 mode (2) and counter (div2). */
+		i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0, 0, div2, 2);
+	}
+
+	/*
+	 * Sort out end of acquisition.
+	 */
+	switch (cmd->stop_src) {
+	case TRIG_COUNT:
+		/* Fixed number of scans.  */
+		devpriv->ao_stop_continuous = 0;
+		devpriv->ao_stop_count = cmd->stop_arg;
+		break;
+	default:
+		/* Continuous scans. */
+		devpriv->ao_stop_continuous = 1;
+		devpriv->ao_stop_count = 0;
+		break;
+	}
+
+	/*
+	 * Sort out start of acquisition.
+	 */
+	switch (cmd->start_src) {
+	case TRIG_INT:
+		comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
+		s->async->inttrig = &pci224_ao_inttrig_start;
+		comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
+		break;
+	case TRIG_EXT:
+		/* Enable external interrupt trigger to start acquisition. */
+		comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
+		devpriv->intsce |= PCI224_INTR_EXT;
+		outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
+		comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
+		break;
+	}
+
+	return 0;
+}
+
+/*
+ * 'cancel' function for AO subdevice.
+ */
+static int pci224_ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	pci224_ao_stop(dev, s);
+	return 0;
+}
+
+/*
+ * 'munge' data for AO command.
+ */
+static void
+pci224_ao_munge(struct comedi_device * dev, struct comedi_subdevice * s, void *data,
+	unsigned int num_bytes, unsigned int chan_index)
+{
+	struct comedi_async *async = s->async;
+	short *array = data;
+	unsigned int length = num_bytes / sizeof(*array);
+	unsigned int offset;
+	unsigned int shift;
+	unsigned int i;
+
+	/* The hardware expects 16-bit numbers. */
+	shift = 16 - thisboard->ao_bits;
+	/* Channels will be all bipolar or all unipolar. */
+	if ((devpriv->hwrange[CR_RANGE(async->cmd.chanlist[0])] &
+			PCI224_DACCON_POLAR_MASK) == PCI224_DACCON_POLAR_UNI) {
+		/* Unipolar */
+		offset = 0;
+	} else {
+		/* Bipolar */
+		offset = 32768;
+	}
+	/* Munge the data. */
+	for (i = 0; i < length; i++) {
+		array[i] = (array[i] << shift) - offset;
+	}
+}
+
+/*
+ * Interrupt handler.
+ */
+static irqreturn_t pci224_interrupt(int irq, void *d PT_REGS_ARG)
+{
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s = &dev->subdevices[0];
+	struct comedi_cmd *cmd;
+	unsigned char intstat, valid_intstat;
+	unsigned char curenab;
+	int retval = 0;
+	unsigned long flags;
+
+	intstat = inb(devpriv->iobase1 + PCI224_INT_SCE) & 0x3F;
+	if (intstat) {
+		retval = 1;
+		comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
+		valid_intstat = devpriv->intsce & intstat;
+		/* Temporarily disable interrupt sources. */
+		curenab = devpriv->intsce & ~intstat;
+		outb(curenab, devpriv->iobase1 + PCI224_INT_SCE);
+		devpriv->intr_running = 1;
+		devpriv->intr_cpuid = THISCPU;
+		comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
+		if (valid_intstat != 0) {
+			cmd = &s->async->cmd;
+			if (valid_intstat & PCI224_INTR_EXT) {
+				devpriv->intsce &= ~PCI224_INTR_EXT;
+				if (cmd->start_src == TRIG_EXT) {
+					pci224_ao_start(dev, s);
+				} else if (cmd->stop_src == TRIG_EXT) {
+					pci224_ao_stop(dev, s);
+				}
+			}
+			if (valid_intstat & PCI224_INTR_DAC) {
+				pci224_ao_handle_fifo(dev, s);
+			}
+		}
+		/* Reenable interrupt sources. */
+		comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
+		if (curenab != devpriv->intsce) {
+			outb(devpriv->intsce,
+				devpriv->iobase1 + PCI224_INT_SCE);
+		}
+		devpriv->intr_running = 0;
+		comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
+	}
+	return IRQ_RETVAL(retval);
+}
+
+/*
+ * This function looks for a PCI device matching the requested board name,
+ * bus and slot.
+ */
+static int
+pci224_find_pci(struct comedi_device * dev, int bus, int slot,
+	struct pci_dev **pci_dev_p)
+{
+	struct pci_dev *pci_dev = NULL;
+
+	*pci_dev_p = NULL;
+
+	/* Look for matching PCI device. */
+	for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
+		pci_dev != NULL;
+		pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID,
+			pci_dev)) {
+		/* If bus/slot specified, check them. */
+		if (bus || slot) {
+			if (bus != pci_dev->bus->number
+				|| slot != PCI_SLOT(pci_dev->devfn))
+				continue;
+		}
+		if (thisboard->model == any_model) {
+			/* Match any supported model. */
+			int i;
+
+			for (i = 0; i < ARRAY_SIZE(pci224_boards); i++) {
+				if (pci_dev->device == pci224_boards[i].devid) {
+					/* Change board_ptr to matched board. */
+					dev->board_ptr = &pci224_boards[i];
+					break;
+				}
+			}
+			if (i == ARRAY_SIZE(pci224_boards))
+				continue;
+		} else {
+			/* Match specific model name. */
+			if (thisboard->devid != pci_dev->device)
+				continue;
+		}
+
+		/* Found a match. */
+		*pci_dev_p = pci_dev;
+		return 0;
+	}
+	/* No match found. */
+	if (bus || slot) {
+		printk(KERN_ERR "comedi%d: error! "
+			"no %s found at pci %02x:%02x!\n",
+			dev->minor, thisboard->name, bus, slot);
+	} else {
+		printk(KERN_ERR "comedi%d: error! no %s found!\n",
+			dev->minor, thisboard->name);
+	}
+	return -EIO;
+}
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board.  If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pci224_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	struct pci_dev *pci_dev;
+	unsigned int irq;
+	int bus = 0, slot = 0;
+	unsigned n;
+	int ret;
+
+	printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor, DRIVER_NAME);
+
+	bus = it->options[0];
+	slot = it->options[1];
+	if ((ret = alloc_private(dev, sizeof(struct pci224_private))) < 0) {
+		printk(KERN_ERR "comedi%d: error! out of memory!\n",
+			dev->minor);
+		return ret;
+	}
+	if ((ret = pci224_find_pci(dev, bus, slot, &pci_dev)) < 0)
+		return ret;
+	devpriv->pci_dev = pci_dev;
+
+	if ((ret = comedi_pci_enable(pci_dev, DRIVER_NAME)) < 0) {
+		printk(KERN_ERR
+			"comedi%d: error! cannot enable PCI device "
+			"and request regions!\n", dev->minor);
+		return ret;
+	}
+	spin_lock_init(&devpriv->ao_spinlock);
+
+	devpriv->iobase1 = pci_resource_start(pci_dev, 2);
+	dev->iobase = pci_resource_start(pci_dev, 3);
+	irq = pci_dev->irq;
+
+	/* Allocate readback buffer for AO channels. */
+	devpriv->ao_readback = kmalloc(sizeof(devpriv->ao_readback[0]) *
+		thisboard->ao_chans, GFP_KERNEL);
+	if (!devpriv->ao_readback) {
+		return -ENOMEM;
+	}
+
+	/* Allocate buffer to hold values for AO channel scan. */
+	devpriv->ao_scan_vals = kmalloc(sizeof(devpriv->ao_scan_vals[0]) *
+		thisboard->ao_chans, GFP_KERNEL);
+	if (!devpriv->ao_scan_vals) {
+		return -ENOMEM;
+	}
+
+	/* Allocate buffer to hold AO channel scan order. */
+	devpriv->ao_scan_order = kmalloc(sizeof(devpriv->ao_scan_order[0]) *
+		thisboard->ao_chans, GFP_KERNEL);
+	if (!devpriv->ao_scan_order) {
+		return -ENOMEM;
+	}
+
+	/* Disable interrupt sources. */
+	devpriv->intsce = 0;
+	outb(0, devpriv->iobase1 + PCI224_INT_SCE);
+
+	/* Initialize the DAC hardware. */
+	outw(PCI224_DACCON_GLOBALRESET, dev->iobase + PCI224_DACCON);
+	outw(0, dev->iobase + PCI224_DACCEN);
+	outw(0, dev->iobase + PCI224_FIFOSIZ);
+	devpriv->daccon = (PCI224_DACCON_TRIG_SW | PCI224_DACCON_POLAR_BI |
+		PCI224_DACCON_FIFOENAB | PCI224_DACCON_FIFOINTR_EMPTY);
+	outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
+		dev->iobase + PCI224_DACCON);
+
+	/* Allocate subdevices.  There is only one!  */
+	if ((ret = alloc_subdevices(dev, 1)) < 0) {
+		printk(KERN_ERR "comedi%d: error! out of memory!\n",
+			dev->minor);
+		return ret;
+	}
+
+	s = dev->subdevices + 0;
+	/* Analog output subdevice. */
+	s->type = COMEDI_SUBD_AO;
+	s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
+	s->n_chan = thisboard->ao_chans;
+	s->maxdata = (1 << thisboard->ao_bits) - 1;
+	s->insn_write = &pci224_ao_insn_write;
+	s->insn_read = &pci224_ao_insn_read;
+	s->len_chanlist = s->n_chan;
+
+	dev->write_subdev = s;
+	s->do_cmd = &pci224_ao_cmd;
+	s->do_cmdtest = &pci224_ao_cmdtest;
+	s->cancel = &pci224_ao_cancel;
+	s->munge = &pci224_ao_munge;
+
+	/* Sort out channel range options. */
+	if (thisboard->model == pci234_model) {
+		/* PCI234 range options. */
+		const struct comedi_lrange **range_table_list;
+
+		s->range_table_list = range_table_list =
+			kmalloc(sizeof(struct comedi_lrange *) * s->n_chan,
+			GFP_KERNEL);
+		if (!s->range_table_list) {
+			return -ENOMEM;
+		}
+		for (n = 2; n < 3 + s->n_chan; n++) {
+			if (it->options[n] < 0 || it->options[n] > 1) {
+				printk(KERN_WARNING "comedi%d: %s: warning! "
+					"bad options[%u]=%d\n",
+					dev->minor, DRIVER_NAME, n,
+					it->options[n]);
+			}
+		}
+		for (n = 0; n < s->n_chan; n++) {
+			if (n < COMEDI_NDEVCONFOPTS - 3 &&
+				it->options[3 + n] == 1) {
+				if (it->options[2] == 1) {
+					range_table_list[n] = &range_pci234_ext;
+				} else {
+					range_table_list[n] = &range_bipolar5;
+				}
+			} else {
+				if (it->options[2] == 1) {
+					range_table_list[n] =
+						&range_pci234_ext2;
+				} else {
+					range_table_list[n] = &range_bipolar10;
+				}
+			}
+		}
+		devpriv->hwrange = hwrange_pci234;
+	} else {
+		/* PCI224 range options. */
+		if (it->options[2] == 1) {
+			s->range_table = &range_pci224_external;
+			devpriv->hwrange = hwrange_pci224_external;
+		} else {
+			if (it->options[2] != 0) {
+				printk(KERN_WARNING "comedi%d: %s: warning! "
+					"bad options[2]=%d\n",
+					dev->minor, DRIVER_NAME,
+					it->options[2]);
+			}
+			s->range_table = &range_pci224_internal;
+			devpriv->hwrange = hwrange_pci224_internal;
+		}
+	}
+
+	dev->board_name = thisboard->name;
+
+	if (irq) {
+		ret = comedi_request_irq(irq, pci224_interrupt, IRQF_SHARED,
+			DRIVER_NAME, dev);
+		if (ret < 0) {
+			printk(KERN_ERR "comedi%d: error! "
+				"unable to allocate irq %u\n", dev->minor, irq);
+			return ret;
+		} else {
+			dev->irq = irq;
+		}
+	}
+
+	printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
+	printk("(pci %s) ", pci_name(pci_dev));
+	if (irq) {
+		printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
+	} else {
+		printk("(no irq) ");
+	}
+
+	printk("attached\n");
+
+	return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device.  It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach().  dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pci224_detach(struct comedi_device * dev)
+{
+	printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor, DRIVER_NAME);
+
+	if (dev->irq) {
+		comedi_free_irq(dev->irq, dev);
+	}
+	if (dev->subdevices) {
+		struct comedi_subdevice *s;
+
+		s = dev->subdevices + 0;
+		/* AO subdevice */
+		if (s->range_table_list) {
+			kfree(s->range_table_list);
+		}
+	}
+	if (devpriv) {
+		if (devpriv->ao_readback) {
+			kfree(devpriv->ao_readback);
+		}
+		if (devpriv->ao_scan_vals) {
+			kfree(devpriv->ao_scan_vals);
+		}
+		if (devpriv->ao_scan_order) {
+			kfree(devpriv->ao_scan_order);
+		}
+		if (devpriv->pci_dev) {
+			if (dev->iobase) {
+				comedi_pci_disable(devpriv->pci_dev);
+			}
+			pci_dev_put(devpriv->pci_dev);
+		}
+	}
+	if (dev->board_name) {
+		printk(KERN_INFO "comedi%d: %s removed\n",
+			dev->minor, dev->board_name);
+	}
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c
new file mode 100644
index 0000000..0c9e573
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amplc_pci230.c
@@ -0,0 +1,2977 @@
+ /*
+    comedi/drivers/amplc_pci230.c
+    Driver for Amplicon PCI230 and PCI260 Multifunction I/O boards.
+
+    Copyright (C) 2001 Allan Willcox <allanwillcox@ozemail.com.au>
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000 David A. Schleef <ds@schleef.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.
+
+    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.
+  */
+/*
+Driver: amplc_pci230
+Description: Amplicon PCI230, PCI260 Multifunction I/O boards
+Author: Allan Willcox <allanwillcox@ozemail.com.au>,
+  Steve D Sharples <steve.sharples@nottingham.ac.uk>,
+  Ian Abbott <abbotti@mev.co.uk>
+Updated: Wed, 22 Oct 2008 12:34:49 +0100
+Devices: [Amplicon] PCI230 (pci230 or amplc_pci230),
+  PCI230+ (pci230+ or amplc_pci230),
+  PCI260 (pci260 or amplc_pci230), PCI260+ (pci260+ or amplc_pci230)
+Status: works
+
+Configuration options:
+  [0] - PCI bus of device (optional).
+  [1] - PCI slot of device (optional).
+          If bus/slot is not specified, the first available PCI device
+          will be used.
+
+Configuring a "amplc_pci230" will match any supported card and it will
+choose the best match, picking the "+" models if possible.  Configuring
+a "pci230" will match a PCI230 or PCI230+ card and it will be treated as
+a PCI230.  Configuring a "pci260" will match a PCI260 or PCI260+ card
+and it will be treated as a PCI260.  Configuring a "pci230+" will match
+a PCI230+ card.  Configuring a "pci260+" will match a PCI260+ card.
+
+Subdevices:
+
+                PCI230(+)    PCI260(+)
+                ---------    ---------
+  Subdevices       3            1
+        0          AI           AI
+	1          AO
+	2          DIO
+
+AI Subdevice:
+
+  The AI subdevice has 16 single-ended channels or 8 differential
+  channels.
+
+  The PCI230 and PCI260 cards have 12-bit resolution.  The PCI230+ and
+  PCI260+ cards have 16-bit resolution.
+
+  For differential mode, use inputs 2N and 2N+1 for channel N (e.g. use
+  inputs 14 and 15 for channel 7).  If the card is physically a PCI230
+  or PCI260 then it actually uses a "pseudo-differential" mode where the
+  inputs are sampled a few microseconds apart.  The PCI230+ and PCI260+
+  use true differential sampling.  Another difference is that if the
+  card is physically a PCI230 or PCI260, the inverting input is 2N,
+  whereas for a PCI230+ or PCI260+ the inverting input is 2N+1.  So if a
+  PCI230 is physically replaced by a PCI230+ (or a PCI260 with a
+  PCI260+) and differential mode is used, the differential inputs need
+  to be physically swapped on the connector.
+
+  The following input ranges are supported:
+
+    0 => [-10, +10] V
+    1 => [-5, +5] V
+    2 => [-2.5, +2.5] V
+    3 => [-1.25, +1.25] V
+    4 => [0, 10] V
+    5 => [0, 5] V
+    6 => [0, 2.5] V
+
+AI Commands:
+
+  +=========+==============+===========+============+==========+
+  |start_src|scan_begin_src|convert_src|scan_end_src| stop_src |
+  +=========+==============+===========+============+==========+
+  |TRIG_NOW | TRIG_FOLLOW  |TRIG_TIMER | TRIG_COUNT |TRIG_NONE |
+  |TRIG_INT |              |TRIG_EXT(3)|            |TRIG_COUNT|
+  |         |              |TRIG_INT   |            |          |
+  |         |--------------|-----------|            |          |
+  |         | TRIG_TIMER(1)|TRIG_TIMER |            |          |
+  |         | TRIG_EXT(2)  |           |            |          |
+  |         | TRIG_INT     |           |            |          |
+  +---------+--------------+-----------+------------+----------+
+
+  Note 1: If AI command and AO command are used simultaneously, only
+          one may have scan_begin_src == TRIG_TIMER.
+
+  Note 2: For PCI230 and PCI230+, scan_begin_src == TRIG_EXT uses
+          DIO channel 16 (pin 49) which will need to be configured as
+          a digital input.  For PCI260+, the EXTTRIG/EXTCONVCLK input
+          (pin 17) is used instead.  For PCI230, scan_begin_src ==
+          TRIG_EXT is not supported.  The trigger is a rising edge
+          on the input.
+
+  Note 3: For convert_src == TRIG_EXT, the EXTTRIG/EXTCONVCLK input
+          (pin 25 on PCI230(+), pin 17 on PCI260(+)) is used.  The
+          convert_arg value is interpreted as follows:
+
+            convert_arg == (CR_EDGE | 0) => rising edge
+            convert_arg == (CR_EDGE | CR_INVERT | 0) => falling edge
+            convert_arg == 0 => falling edge (backwards compatibility)
+            convert_arg == 1 => rising edge (backwards compatibility)
+
+  All entries in the channel list must use the same analogue reference.
+  If the analogue reference is not AREF_DIFF (not differential) each
+  pair of channel numbers (0 and 1, 2 and 3, etc.) must use the same
+  input range.  The input ranges used in the sequence must be all
+  bipolar (ranges 0 to 3) or all unipolar (ranges 4 to 6).  The channel
+  sequence must consist of 1 or more identical subsequences.  Within the
+  subsequence, channels must be in ascending order with no repeated
+  channels.  For example, the following sequences are valid: 0 1 2 3
+  (single valid subsequence), 0 2 3 5 0 2 3 5 (repeated valid
+  subsequence), 1 1 1 1 (repeated valid subsequence).  The following
+  sequences are invalid: 0 3 2 1 (invalid subsequence), 0 2 3 5 0 2 3
+  (incompletely repeated subsequence).  Some versions of the PCI230+ and
+  PCI260+ have a bug that requires a subsequence longer than one entry
+  long to include channel 0.
+
+AO Subdevice:
+
+  The AO subdevice has 2 channels with 12-bit resolution.
+
+  The following output ranges are supported:
+
+    0 => [0, 10] V
+    1 => [-10, +10] V
+
+AO Commands:
+
+  +=========+==============+===========+============+==========+
+  |start_src|scan_begin_src|convert_src|scan_end_src| stop_src |
+  +=========+==============+===========+============+==========+
+  |TRIG_INT | TRIG_TIMER(1)| TRIG_NOW  | TRIG_COUNT |TRIG_NONE |
+  |         | TRIG_EXT(2)  |           |            |TRIG_COUNT|
+  |         | TRIG_INT     |           |            |          |
+  +---------+--------------+-----------+------------+----------+
+
+  Note 1: If AI command and AO command are used simultaneously, only
+          one may have scan_begin_src == TRIG_TIMER.
+
+  Note 2: scan_begin_src == TRIG_EXT is only supported if the card is
+          configured as a PCI230+ and is only supported on later
+          versions of the card.  As a card configured as a PCI230+ is
+          not guaranteed to support external triggering, please consider
+          this support to be a bonus.  It uses the EXTTRIG/ EXTCONVCLK
+          input (PCI230+ pin 25).  Triggering will be on the rising edge
+          unless the CR_INVERT flag is set in scan_begin_arg.
+
+  The channels in the channel sequence must be in ascending order with
+  no repeats.  All entries in the channel sequence must use the same
+  output range.
+
+DIO Subdevice:
+
+  The DIO subdevice is a 8255 chip providing 24 DIO channels.  The DIO
+  channels are configurable as inputs or outputs in four groups:
+
+    Port A  - channels  0 to  7
+    Port B  - channels  8 to 15
+    Port CL - channels 16 to 19
+    Port CH - channels 20 to 23
+
+  Only mode 0 of the 8255 chip is supported.
+
+  Bit 0 of port C (DIO channel 16) is also used as an external scan
+  trigger input for AI commands on PCI230 and PCI230+, so would need to
+  be configured as an input to use it for that purpose.
+*/
+/*
+Extra triggered scan functionality, interrupt bug-fix added by Steve Sharples.
+Support for PCI230+/260+, more triggered scan functionality, and workarounds
+for (or detection of) various hardware problems added by Ian Abbott.
+*/
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+
+#include "comedi_pci.h"
+#include "8253.h"
+#include "8255.h"
+
+/* PCI230 PCI configuration register information */
+#define PCI_VENDOR_ID_AMPLICON 0x14dc
+#define PCI_DEVICE_ID_PCI230 0x0000
+#define PCI_DEVICE_ID_PCI260 0x0006
+#define PCI_DEVICE_ID_INVALID 0xffff
+
+#define PCI230_IO1_SIZE 32	/* Size of I/O space 1 */
+#define PCI230_IO2_SIZE 16	/* Size of I/O space 2 */
+
+/* PCI230 i/o space 1 registers. */
+#define PCI230_PPI_X_BASE	0x00	/* User PPI (82C55) base */
+#define PCI230_PPI_X_A		0x00	/* User PPI (82C55) port A */
+#define PCI230_PPI_X_B		0x01	/* User PPI (82C55) port B */
+#define PCI230_PPI_X_C		0x02	/* User PPI (82C55) port C */
+#define PCI230_PPI_X_CMD	0x03	/* User PPI (82C55) control word */
+#define PCI230_Z2_CT_BASE	0x14	/* 82C54 counter/timer base */
+#define PCI230_Z2_CT0		0x14	/* 82C54 counter/timer 0 */
+#define PCI230_Z2_CT1		0x15	/* 82C54 counter/timer 1 */
+#define PCI230_Z2_CT2		0x16	/* 82C54 counter/timer 2 */
+#define PCI230_Z2_CTC		0x17	/* 82C54 counter/timer control word */
+#define PCI230_ZCLK_SCE		0x1A	/* Group Z Clock Configuration */
+#define PCI230_ZGAT_SCE		0x1D	/* Group Z Gate Configuration */
+#define PCI230_INT_SCE		0x1E	/* Interrupt source mask (w) */
+#define PCI230_INT_STAT		0x1E	/* Interrupt status (r) */
+
+/* PCI230 i/o space 2 registers. */
+#define PCI230_DACCON		0x00	/* DAC control */
+#define PCI230_DACOUT1		0x02	/* DAC channel 0 (w) */
+#define PCI230_DACOUT2		0x04	/* DAC channel 1 (w) (not FIFO mode) */
+#define PCI230_ADCDATA		0x08	/* ADC data (r) */
+#define PCI230_ADCSWTRIG	0x08	/* ADC software trigger (w) */
+#define PCI230_ADCCON		0x0A	/* ADC control */
+#define PCI230_ADCEN		0x0C	/* ADC channel enable bits */
+#define PCI230_ADCG		0x0E	/* ADC gain control bits */
+/* PCI230+ i/o space 2 additional registers. */
+#define PCI230P_ADCTRIG		0x10	/* ADC start acquisition trigger */
+#define PCI230P_ADCTH		0x12	/* ADC analog trigger threshold */
+#define PCI230P_ADCFFTH		0x14	/* ADC FIFO interrupt threshold */
+#define PCI230P_ADCFFLEV	0x16	/* ADC FIFO level (r) */
+#define PCI230P_ADCPTSC		0x18	/* ADC pre-trigger sample count (r) */
+#define PCI230P_ADCHYST		0x1A	/* ADC analog trigger hysteresys */
+#define PCI230P_EXTFUNC		0x1C	/* Extended functions */
+#define PCI230P_HWVER		0x1E	/* Hardware version (r) */
+/* PCI230+ hardware version 2 onwards. */
+#define PCI230P2_DACDATA	0x02	/* DAC data (FIFO mode) (w) */
+#define PCI230P2_DACSWTRIG	0x02	/* DAC soft trigger (FIFO mode) (r) */
+#define PCI230P2_DACEN		0x06	/* DAC channel enable (FIFO mode) */
+
+/* Convertor related constants. */
+#define PCI230_DAC_SETTLE 5	/* Analogue output settling time in µs */
+				/* (DAC itself is 1µs nominally). */
+#define PCI230_ADC_SETTLE 1	/* Analogue input settling time in µs */
+				/* (ADC itself is 1.6µs nominally but we poll
+				 * anyway). */
+#define PCI230_MUX_SETTLE 10	/* ADC MUX settling time in µS */
+				/* - 10µs for se, 20µs de. */
+
+/* DACCON read-write values. */
+#define PCI230_DAC_OR_UNI		(0<<0)	/* Output range unipolar */
+#define PCI230_DAC_OR_BIP		(1<<0)	/* Output range bipolar */
+#define PCI230_DAC_OR_MASK		(1<<0)
+/* The following applies only if DAC FIFO support is enabled in the EXTFUNC
+ * register (and only for PCI230+ hardware version 2 onwards). */
+#define PCI230P2_DAC_FIFO_EN		(1<<8)	/* FIFO enable */
+/* The following apply only if the DAC FIFO is enabled (and only for PCI230+
+ * hardware version 2 onwards). */
+#define PCI230P2_DAC_TRIG_NONE		(0<<2)	/* No trigger */
+#define PCI230P2_DAC_TRIG_SW		(1<<2)	/* Software trigger trigger */
+#define PCI230P2_DAC_TRIG_EXTP		(2<<2)	/* EXTTRIG +ve edge trigger */
+#define PCI230P2_DAC_TRIG_EXTN		(3<<2)	/* EXTTRIG -ve edge trigger */
+#define PCI230P2_DAC_TRIG_Z2CT0		(4<<2)	/* CT0-OUT +ve edge trigger */
+#define PCI230P2_DAC_TRIG_Z2CT1		(5<<2)	/* CT1-OUT +ve edge trigger */
+#define PCI230P2_DAC_TRIG_Z2CT2		(6<<2)	/* CT2-OUT +ve edge trigger */
+#define PCI230P2_DAC_TRIG_MASK		(7<<2)
+#define PCI230P2_DAC_FIFO_WRAP		(1<<7)	/* FIFO wraparound mode */
+#define PCI230P2_DAC_INT_FIFO_EMPTY	(0<<9)	/* FIFO interrupt empty */
+#define PCI230P2_DAC_INT_FIFO_NEMPTY	(1<<9)
+#define PCI230P2_DAC_INT_FIFO_NHALF	(2<<9)	/* FIFO intr not half full */
+#define PCI230P2_DAC_INT_FIFO_HALF	(3<<9)
+#define PCI230P2_DAC_INT_FIFO_NFULL	(4<<9)	/* FIFO interrupt not full */
+#define PCI230P2_DAC_INT_FIFO_FULL	(5<<9)
+#define PCI230P2_DAC_INT_FIFO_MASK	(7<<9)
+
+/* DACCON read-only values. */
+#define PCI230_DAC_BUSY			(1<<1)	/* DAC busy. */
+/* The following apply only if the DAC FIFO is enabled (and only for PCI230+
+ * hardware version 2 onwards). */
+#define PCI230P2_DAC_FIFO_UNDERRUN_LATCHED	(1<<5)	/* Underrun error */
+#define PCI230P2_DAC_FIFO_EMPTY		(1<<13)	/* FIFO empty */
+#define PCI230P2_DAC_FIFO_FULL		(1<<14)	/* FIFO full */
+#define PCI230P2_DAC_FIFO_HALF		(1<<15)	/* FIFO half full */
+
+/* DACCON write-only, transient values. */
+/* The following apply only if the DAC FIFO is enabled (and only for PCI230+
+ * hardware version 2 onwards). */
+#define PCI230P2_DAC_FIFO_UNDERRUN_CLEAR	(1<<5)	/* Clear underrun */
+#define PCI230P2_DAC_FIFO_RESET		(1<<12)	/* FIFO reset */
+
+/* PCI230+ hardware version 2 DAC FIFO levels. */
+#define PCI230P2_DAC_FIFOLEVEL_HALF	512
+#define PCI230P2_DAC_FIFOLEVEL_FULL	1024
+/* Free space in DAC FIFO. */
+#define PCI230P2_DAC_FIFOROOM_EMPTY		PCI230P2_DAC_FIFOLEVEL_FULL
+#define PCI230P2_DAC_FIFOROOM_ONETOHALF		\
+	(PCI230P2_DAC_FIFOLEVEL_FULL - PCI230P2_DAC_FIFOLEVEL_HALF)
+#define PCI230P2_DAC_FIFOROOM_HALFTOFULL	1
+#define PCI230P2_DAC_FIFOROOM_FULL		0
+
+/* ADCCON read/write values. */
+#define PCI230_ADC_TRIG_NONE		(0<<0)	/* No trigger */
+#define PCI230_ADC_TRIG_SW		(1<<0)	/* Software trigger trigger */
+#define PCI230_ADC_TRIG_EXTP		(2<<0)	/* EXTTRIG +ve edge trigger */
+#define PCI230_ADC_TRIG_EXTN		(3<<0)	/* EXTTRIG -ve edge trigger */
+#define PCI230_ADC_TRIG_Z2CT0		(4<<0)	/* CT0-OUT +ve edge trigger */
+#define PCI230_ADC_TRIG_Z2CT1		(5<<0)	/* CT1-OUT +ve edge trigger */
+#define PCI230_ADC_TRIG_Z2CT2		(6<<0)	/* CT2-OUT +ve edge trigger */
+#define PCI230_ADC_TRIG_MASK		(7<<0)
+#define PCI230_ADC_IR_UNI		(0<<3)	/* Input range unipolar */
+#define PCI230_ADC_IR_BIP		(1<<3)	/* Input range bipolar */
+#define PCI230_ADC_IR_MASK		(1<<3)
+#define PCI230_ADC_IM_SE		(0<<4)	/* Input mode single ended */
+#define PCI230_ADC_IM_DIF		(1<<4)	/* Input mode differential */
+#define PCI230_ADC_IM_MASK		(1<<4)
+#define PCI230_ADC_FIFO_EN		(1<<8)	/* FIFO enable */
+#define PCI230_ADC_INT_FIFO_EMPTY	(0<<9)
+#define PCI230_ADC_INT_FIFO_NEMPTY	(1<<9)	/* FIFO interrupt not empty */
+#define PCI230_ADC_INT_FIFO_NHALF	(2<<9)
+#define PCI230_ADC_INT_FIFO_HALF	(3<<9)	/* FIFO interrupt half full */
+#define PCI230_ADC_INT_FIFO_NFULL	(4<<9)
+#define PCI230_ADC_INT_FIFO_FULL	(5<<9)	/* FIFO interrupt full */
+#define PCI230P_ADC_INT_FIFO_THRESH	(7<<9)	/* FIFO interrupt threshold */
+#define PCI230_ADC_INT_FIFO_MASK	(7<<9)
+
+/* ADCCON write-only, transient values. */
+#define PCI230_ADC_FIFO_RESET		(1<<12)	/* FIFO reset */
+#define PCI230_ADC_GLOB_RESET		(1<<13)	/* Global reset */
+
+/* ADCCON read-only values. */
+#define PCI230_ADC_BUSY			(1<<15)	/* ADC busy */
+#define PCI230_ADC_FIFO_EMPTY		(1<<12)	/* FIFO empty */
+#define PCI230_ADC_FIFO_FULL		(1<<13)	/* FIFO full */
+#define PCI230_ADC_FIFO_HALF		(1<<14)	/* FIFO half full */
+#define PCI230_ADC_FIFO_FULL_LATCHED	(1<<5)	/* Indicates overrun occurred */
+
+/* PCI230 ADC FIFO levels. */
+#define PCI230_ADC_FIFOLEVEL_HALFFULL	2049	/* Value for FIFO half full */
+#define PCI230_ADC_FIFOLEVEL_FULL	4096	/* FIFO size */
+
+/* Value to write to ADCSWTRIG to trigger ADC conversion in software trigger
+ * mode.  Can be anything.  */
+#define PCI230_ADC_CONV			0xffff
+
+/* PCI230+ EXTFUNC values. */
+#define PCI230P_EXTFUNC_GAT_EXTTRIG	(1<<0)
+			/* Route EXTTRIG pin to external gate inputs. */
+/* PCI230+ hardware version 2 values. */
+#define PCI230P2_EXTFUNC_DACFIFO	(1<<1)
+			/* Allow DAC FIFO to be enabled. */
+
+/*
+ * Counter/timer clock input configuration sources.
+ */
+#define CLK_CLK		0	/* reserved (channel-specific clock) */
+#define CLK_10MHZ	1	/* internal 10 MHz clock */
+#define CLK_1MHZ	2	/* internal 1 MHz clock */
+#define CLK_100KHZ	3	/* internal 100 kHz clock */
+#define CLK_10KHZ	4	/* internal 10 kHz clock */
+#define CLK_1KHZ	5	/* internal 1 kHz clock */
+#define CLK_OUTNM1	6	/* output of channel-1 modulo total */
+#define CLK_EXT		7	/* external clock */
+/* Macro to construct clock input configuration register value. */
+#define CLK_CONFIG(chan, src)	((((chan) & 3) << 3) | ((src) & 7))
+/* Timebases in ns. */
+#define TIMEBASE_10MHZ		100
+#define TIMEBASE_1MHZ		1000
+#define TIMEBASE_100KHZ		10000
+#define TIMEBASE_10KHZ		100000
+#define TIMEBASE_1KHZ		1000000
+
+/*
+ * Counter/timer gate input configuration sources.
+ */
+#define GAT_VCC		0	/* VCC (i.e. enabled) */
+#define GAT_GND		1	/* GND (i.e. disabled) */
+#define GAT_EXT		2	/* external gate input (PPCn on PCI230) */
+#define GAT_NOUTNM2	3	/* inverted output of channel-2 modulo total */
+/* Macro to construct gate input configuration register value. */
+#define GAT_CONFIG(chan, src)	((((chan) & 3) << 3) | ((src) & 7))
+
+/*
+ * Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI230 and PCI260:
+ *
+ *              Channel's       Channel's
+ *              clock input     gate input
+ * Channel      CLK_OUTNM1      GAT_NOUTNM2
+ * -------      ----------      -----------
+ * Z2-CT0       Z2-CT2-OUT      /Z2-CT1-OUT
+ * Z2-CT1       Z2-CT0-OUT      /Z2-CT2-OUT
+ * Z2-CT2       Z2-CT1-OUT      /Z2-CT0-OUT
+ */
+
+/* Interrupt enables/status register values. */
+#define PCI230_INT_DISABLE		0
+#define PCI230_INT_PPI_C0		(1<<0)
+#define PCI230_INT_PPI_C3		(1<<1)
+#define PCI230_INT_ADC			(1<<2)
+#define PCI230_INT_ZCLK_CT1		(1<<5)
+/* For PCI230+ hardware version 2 when DAC FIFO enabled. */
+#define PCI230P2_INT_DAC		(1<<4)
+
+#define PCI230_TEST_BIT(val, n)	((val>>n)&1)
+			/* Assumes bits numbered with zero offset, ie. 0-15 */
+
+/* (Potentially) shared resources and their owners */
+enum {
+	RES_Z2CT0,		/* Z2-CT0 */
+	RES_Z2CT1,		/* Z2-CT1 */
+	RES_Z2CT2,		/* Z2-CT2 */
+	NUM_RESOURCES		/* Number of (potentially) shared resources. */
+};
+
+enum {
+	OWNER_NONE,		/* Not owned */
+	OWNER_AICMD,		/* Owned by AI command */
+	OWNER_AOCMD		/* Owned by AO command */
+};
+
+/*
+ * Handy macros.
+ */
+
+/* Combine old and new bits. */
+#define COMBINE(old, new, mask)	(((old) & ~(mask)) | ((new) & (mask)))
+
+/* A generic null function pointer value.  */
+#define NULLFUNC	0
+
+/* Current CPU.  XXX should this be hard_smp_processor_id()? */
+#define THISCPU		smp_processor_id()
+
+/* State flags for atomic bit operations */
+#define AI_CMD_STARTED	0
+#define AO_CMD_STARTED	1
+
+/*
+ * Board descriptions for the two boards supported.
+ */
+
+struct pci230_board {
+	const char *name;
+	unsigned short id;
+	int ai_chans;
+	int ai_bits;
+	int ao_chans;
+	int ao_bits;
+	int have_dio;
+	unsigned int min_hwver;	/* Minimum hardware version supported. */
+};
+static const struct pci230_board pci230_boards[] = {
+	{
+	      name:	"pci230+",
+	      id:	PCI_DEVICE_ID_PCI230,
+	      ai_chans:16,
+	      ai_bits:	16,
+	      ao_chans:2,
+	      ao_bits:	12,
+	      have_dio:1,
+	      min_hwver:1,
+		},
+	{
+	      name:	"pci260+",
+	      id:	PCI_DEVICE_ID_PCI260,
+	      ai_chans:16,
+	      ai_bits:	16,
+	      ao_chans:0,
+	      ao_bits:	0,
+	      have_dio:0,
+	      min_hwver:1,
+		},
+	{
+	      name:	"pci230",
+	      id:	PCI_DEVICE_ID_PCI230,
+	      ai_chans:16,
+	      ai_bits:	12,
+	      ao_chans:2,
+	      ao_bits:	12,
+	      have_dio:1,
+		},
+	{
+	      name:	"pci260",
+	      id:	PCI_DEVICE_ID_PCI260,
+	      ai_chans:16,
+	      ai_bits:	12,
+	      ao_chans:0,
+	      ao_bits:	0,
+	      have_dio:0,
+		},
+	{
+	      name:	"amplc_pci230",	/* Wildcard matches any above */
+	      id:	PCI_DEVICE_ID_INVALID,
+		},
+};
+
+static DEFINE_PCI_DEVICE_TABLE(pci230_pci_table) = {
+	{PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI230, PCI_ANY_ID, PCI_ANY_ID,
+		0, 0, 0},
+	{PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI260, PCI_ANY_ID, PCI_ANY_ID,
+		0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci230_pci_table);
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define n_pci230_boards (sizeof(pci230_boards)/sizeof(pci230_boards[0]))
+#define thisboard ((const struct pci230_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver.  If
+   several hardware drivers keep similar information in this structure,
+   feel free to suggest moving the variable to the struct comedi_device struct.  */
+struct pci230_private {
+	struct pci_dev *pci_dev;
+	spinlock_t isr_spinlock;	/* Interrupt spin lock */
+	spinlock_t res_spinlock;	/* Shared resources spin lock */
+	spinlock_t ai_stop_spinlock;	/* Spin lock for stopping AI command */
+	spinlock_t ao_stop_spinlock;	/* Spin lock for stopping AO command */
+	unsigned long state;	/* State flags */
+	unsigned long iobase1;	/* PCI230's I/O space 1 */
+	unsigned int ao_readback[2];	/* Used for AO readback */
+	unsigned int ai_scan_count;	/* Number of analogue input scans
+					 * remaining.  */
+	unsigned int ai_scan_pos;	/* Current position within analogue
+					 * input scan */
+	unsigned int ao_scan_count;	/* Number of analogue output scans
+					 * remaining.  */
+	int intr_cpuid;		/* ID of CPU running interrupt routine. */
+	unsigned short hwver;	/* Hardware version (for '+' models). */
+	unsigned short adccon;	/* ADCCON register value. */
+	unsigned short daccon;	/* DACCON register value. */
+	unsigned short adcfifothresh;	/* ADC FIFO programmable interrupt
+					 * level threshold (PCI230+/260+). */
+	unsigned short adcg;	/* ADCG register value. */
+	unsigned char int_en;	/* Interrupt enables bits. */
+	unsigned char ai_continuous;	/* Flag set when cmd->stop_src ==
+					 * TRIG_NONE - user chooses to stop
+					 * continuous conversion by
+					 * cancelation. */
+	unsigned char ao_continuous;	/* Flag set when cmd->stop_src ==
+					 * TRIG_NONE - user chooses to stop
+					 * continuous conversion by
+					 * cancelation. */
+	unsigned char ai_bipolar;	/* Set if bipolar input range so we
+					 * know to mangle it. */
+	unsigned char ao_bipolar;	/* Set if bipolar output range so we
+					 * know to mangle it. */
+	unsigned char ier;	/* Copy of interrupt enables/status register. */
+	unsigned char intr_running;	/* Flag set in interrupt routine. */
+	unsigned char res_owner[NUM_RESOURCES];	/* Shared resource owners. */
+};
+
+#define devpriv ((struct pci230_private *)dev->private)
+
+/* PCI230 clock source periods in ns */
+static const unsigned int pci230_timebase[8] = {
+	[CLK_10MHZ] = TIMEBASE_10MHZ,
+	[CLK_1MHZ] = TIMEBASE_1MHZ,
+	[CLK_100KHZ] = TIMEBASE_100KHZ,
+	[CLK_10KHZ] = TIMEBASE_10KHZ,
+	[CLK_1KHZ] = TIMEBASE_1KHZ,
+};
+
+/* PCI230 analogue input range table */
+static const struct comedi_lrange pci230_ai_range = { 7, {
+			BIP_RANGE(10),
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+			UNI_RANGE(10),
+			UNI_RANGE(5),
+			UNI_RANGE(2.5)
+	}
+};
+
+/* PCI230 analogue gain bits for each input range. */
+static const unsigned char pci230_ai_gain[7] = { 0, 1, 2, 3, 1, 2, 3 };
+
+/* PCI230 adccon bipolar flag for each analogue input range. */
+static const unsigned char pci230_ai_bipolar[7] = { 1, 1, 1, 1, 0, 0, 0 };
+
+/* PCI230 analogue output range table */
+static const struct comedi_lrange pci230_ao_range = { 2, {
+			UNI_RANGE(10),
+			BIP_RANGE(10)
+	}
+};
+
+/* PCI230 daccon bipolar flag for each analogue output range. */
+static const unsigned char pci230_ao_bipolar[2] = { 0, 1 };
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pci230_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci230_detach(struct comedi_device * dev);
+static struct comedi_driver driver_amplc_pci230 = {
+      driver_name:"amplc_pci230",
+      module:THIS_MODULE,
+      attach:pci230_attach,
+      detach:pci230_detach,
+      board_name:&pci230_boards[0].name,
+      offset:sizeof(pci230_boards[0]),
+      num_names:sizeof(pci230_boards) / sizeof(pci230_boards[0]),
+};
+
+COMEDI_PCI_INITCLEANUP(driver_amplc_pci230, pci230_pci_table);
+
+static int pci230_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int pci230_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int pci230_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static void pci230_ct_setup_ns_mode(struct comedi_device * dev, unsigned int ct,
+	unsigned int mode, uint64_t ns, unsigned int round);
+static void pci230_ns_to_single_timer(unsigned int *ns, unsigned int round);
+static void pci230_cancel_ct(struct comedi_device * dev, unsigned int ct);
+static irqreturn_t pci230_interrupt(int irq, void *d PT_REGS_ARG);
+static int pci230_ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd);
+static int pci230_ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pci230_ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void pci230_ao_stop(struct comedi_device * dev, struct comedi_subdevice * s);
+static void pci230_handle_ao_nofifo(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pci230_handle_ao_fifo(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pci230_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd);
+static int pci230_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pci230_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void pci230_ai_stop(struct comedi_device * dev, struct comedi_subdevice * s);
+static void pci230_handle_ai(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static short pci230_ai_read(struct comedi_device * dev)
+{
+	/* Read sample. */
+	short data = (short) inw(dev->iobase + PCI230_ADCDATA);
+
+	/* PCI230 is 12 bit - stored in upper bits of 16 bit register (lower
+	 * four bits reserved for expansion). */
+	/* PCI230+ is 16 bit AI. */
+	data = data >> (16 - thisboard->ai_bits);
+
+	/* If a bipolar range was specified, mangle it (twos
+	 * complement->straight binary). */
+	if (devpriv->ai_bipolar) {
+		data ^= 1 << (thisboard->ai_bits - 1);
+	}
+	return data;
+}
+
+static inline unsigned short pci230_ao_mangle_datum(struct comedi_device * dev,
+	short datum)
+{
+	/* If a bipolar range was specified, mangle it (straight binary->twos
+	 * complement). */
+	if (devpriv->ao_bipolar) {
+		datum ^= 1 << (thisboard->ao_bits - 1);
+	}
+
+	/* PCI230 is 12 bit - stored in upper bits of 16 bit register (lower
+	 * four bits reserved for expansion). */
+	/* PCI230+ is also 12 bit AO. */
+	datum <<= (16 - thisboard->ao_bits);
+	return (unsigned short)datum;
+}
+
+static inline void pci230_ao_write_nofifo(struct comedi_device * dev, short datum,
+	unsigned int chan)
+{
+	/* Store unmangled datum to be read back later. */
+	devpriv->ao_readback[chan] = datum;
+
+	/* Write mangled datum to appropriate DACOUT register. */
+	outw(pci230_ao_mangle_datum(dev, datum), dev->iobase + (((chan) == 0)
+			? PCI230_DACOUT1 : PCI230_DACOUT2));
+}
+
+static inline void pci230_ao_write_fifo(struct comedi_device * dev, short datum,
+	unsigned int chan)
+{
+	/* Store unmangled datum to be read back later. */
+	devpriv->ao_readback[chan] = datum;
+
+	/* Write mangled datum to appropriate DACDATA register. */
+	outw(pci230_ao_mangle_datum(dev, datum),
+		dev->iobase + PCI230P2_DACDATA);
+}
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board.  If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pci230_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	unsigned long iobase1, iobase2;
+	/* PCI230's I/O spaces 1 and 2 respectively. */
+	struct pci_dev *pci_dev;
+	int i = 0, irq_hdl, rc;
+
+	printk("comedi%d: amplc_pci230: attach %s %d,%d\n", dev->minor,
+		thisboard->name, it->options[0], it->options[1]);
+
+	/* Allocate the private structure area using alloc_private().
+	 * Macro defined in comedidev.h - memsets struct fields to 0. */
+	if ((alloc_private(dev, sizeof(struct pci230_private))) < 0) {
+		return -ENOMEM;
+	}
+	spin_lock_init(&devpriv->isr_spinlock);
+	spin_lock_init(&devpriv->res_spinlock);
+	spin_lock_init(&devpriv->ai_stop_spinlock);
+	spin_lock_init(&devpriv->ao_stop_spinlock);
+	/* Find card */
+	for (pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+		pci_dev != NULL;
+		pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) {
+		if (it->options[0] || it->options[1]) {
+			/* Match against bus/slot options. */
+			if (it->options[0] != pci_dev->bus->number ||
+				it->options[1] != PCI_SLOT(pci_dev->devfn))
+				continue;
+		}
+		if (pci_dev->vendor != PCI_VENDOR_ID_AMPLICON)
+			continue;
+		if (thisboard->id == PCI_DEVICE_ID_INVALID) {
+			/* The name was specified as "amplc_pci230" which is
+			 * used to match any supported device.  Replace the
+			 * current dev->board_ptr with one that matches the
+			 * PCI device ID. */
+			for (i = 0; i < n_pci230_boards; i++) {
+				if (pci_dev->device == pci230_boards[i].id) {
+					if (pci230_boards[i].min_hwver > 0) {
+						/* Check for a '+' model.
+						 * First check length of
+						 * registers. */
+						if (pci_resource_len(pci_dev, 3)
+							< 32) {
+							/* Not a '+' model. */
+							continue;
+						}
+						/* TODO: temporarily enable the
+						 * PCI device and read the
+						 * hardware version register.
+						 * For now assume it's okay. */
+					}
+					/* Change board_ptr to matched board */
+					dev->board_ptr = &pci230_boards[i];
+					break;
+				}
+			}
+			if (i < n_pci230_boards)
+				break;
+		} else {
+			/* The name was specified as a specific device name.
+			 * The current dev->board_ptr is correct.  Check
+			 * whether it matches the PCI device ID. */
+			if (thisboard->id == pci_dev->device) {
+				/* Check minimum hardware version. */
+				if (thisboard->min_hwver > 0) {
+					/* Looking for a '+' model.  First
+					 * check length of registers. */
+					if (pci_resource_len(pci_dev, 3) < 32) {
+						/* Not a '+' model. */
+						continue;
+					}
+					/* TODO: temporarily enable the PCI
+					 * device and read the hardware version
+					 * register.  For now, assume it's
+					 * okay. */
+					break;
+				} else {
+					break;
+				}
+			}
+		}
+	}
+	if (!pci_dev) {
+		printk("comedi%d: No %s card found\n", dev->minor,
+			thisboard->name);
+		return -EIO;
+	}
+	devpriv->pci_dev = pci_dev;
+
+	/*
+	 * Initialize dev->board_name.
+	 */
+	dev->board_name = thisboard->name;
+
+	/* Enable PCI device and reserve I/O spaces. */
+	if (comedi_pci_enable(pci_dev, "amplc_pci230") < 0) {
+		printk("comedi%d: failed to enable PCI device "
+			"and request regions\n", dev->minor);
+		return -EIO;
+	}
+
+	/* Read base addresses of the PCI230's two I/O regions from PCI
+	 * configuration register. */
+	iobase1 = pci_resource_start(pci_dev, 2);
+	iobase2 = pci_resource_start(pci_dev, 3);
+
+	printk("comedi%d: %s I/O region 1 0x%04lx I/O region 2 0x%04lx\n",
+		dev->minor, dev->board_name, iobase1, iobase2);
+
+	devpriv->iobase1 = iobase1;
+	dev->iobase = iobase2;
+
+	/* Read bits of DACCON register - only the output range. */
+	devpriv->daccon = inw(dev->iobase + PCI230_DACCON) & PCI230_DAC_OR_MASK;
+
+	/* Read hardware version register and set extended function register
+	 * if they exist. */
+	if (pci_resource_len(pci_dev, 3) >= 32) {
+		unsigned short extfunc = 0;
+
+		devpriv->hwver = inw(dev->iobase + PCI230P_HWVER);
+		if (devpriv->hwver < thisboard->min_hwver) {
+			printk("comedi%d: %s - bad hardware version "
+				"- got %u, need %u\n", dev->minor,
+				dev->board_name, devpriv->hwver,
+				thisboard->min_hwver);
+			return -EIO;
+		}
+		if (devpriv->hwver > 0) {
+			if (!thisboard->have_dio) {
+				/* No DIO ports.  Route counters' external gates
+				 * to the EXTTRIG signal (PCI260+ pin 17).
+				 * (Otherwise, they would be routed to DIO
+				 * inputs PC0, PC1 and PC2 which don't exist
+				 * on PCI260[+].) */
+				extfunc |= PCI230P_EXTFUNC_GAT_EXTTRIG;
+			}
+			if ((thisboard->ao_chans > 0)
+				&& (devpriv->hwver >= 2)) {
+				/* Enable DAC FIFO functionality. */
+				extfunc |= PCI230P2_EXTFUNC_DACFIFO;
+			}
+		}
+		outw(extfunc, dev->iobase + PCI230P_EXTFUNC);
+		if ((extfunc & PCI230P2_EXTFUNC_DACFIFO) != 0) {
+			/* Temporarily enable DAC FIFO, reset it and disable
+			 * FIFO wraparound. */
+			outw(devpriv->daccon | PCI230P2_DAC_FIFO_EN
+				| PCI230P2_DAC_FIFO_RESET,
+				dev->iobase + PCI230_DACCON);
+			/* Clear DAC FIFO channel enable register. */
+			outw(0, dev->iobase + PCI230P2_DACEN);
+			/* Disable DAC FIFO. */
+			outw(devpriv->daccon, dev->iobase + PCI230_DACCON);
+		}
+	}
+
+	/* Disable board's interrupts. */
+	outb(0, devpriv->iobase1 + PCI230_INT_SCE);
+
+	/* Set ADC to a reasonable state. */
+	devpriv->adcg = 0;
+	devpriv->adccon = PCI230_ADC_TRIG_NONE | PCI230_ADC_IM_SE
+		| PCI230_ADC_IR_BIP;
+	outw(1 << 0, dev->iobase + PCI230_ADCEN);
+	outw(devpriv->adcg, dev->iobase + PCI230_ADCG);
+	outw(devpriv->adccon | PCI230_ADC_FIFO_RESET,
+		dev->iobase + PCI230_ADCCON);
+
+	/* Register the interrupt handler. */
+	irq_hdl = comedi_request_irq(devpriv->pci_dev->irq, pci230_interrupt,
+		IRQF_SHARED, "amplc_pci230", dev);
+	if (irq_hdl < 0) {
+		printk("comedi%d: unable to register irq, "
+			"commands will not be available %d\n", dev->minor,
+			devpriv->pci_dev->irq);
+	} else {
+		dev->irq = devpriv->pci_dev->irq;
+		printk("comedi%d: registered irq %u\n", dev->minor,
+			devpriv->pci_dev->irq);
+	}
+
+	/*
+	 * Allocate the subdevice structures.  alloc_subdevice() is a
+	 * convenient macro defined in comedidev.h.
+	 */
+	if (alloc_subdevices(dev, 3) < 0)
+		return -ENOMEM;
+
+	s = dev->subdevices + 0;
+	/* analog input subdevice */
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND;
+	s->n_chan = thisboard->ai_chans;
+	s->maxdata = (1 << thisboard->ai_bits) - 1;
+	s->range_table = &pci230_ai_range;
+	s->insn_read = &pci230_ai_rinsn;
+	s->len_chanlist = 256;	/* but there are restrictions. */
+	/* Only register commands if the interrupt handler is installed. */
+	if (irq_hdl == 0) {
+		dev->read_subdev = s;
+		s->subdev_flags |= SDF_CMD_READ;
+		s->do_cmd = &pci230_ai_cmd;
+		s->do_cmdtest = &pci230_ai_cmdtest;
+		s->cancel = pci230_ai_cancel;
+	}
+
+	s = dev->subdevices + 1;
+	/* analog output subdevice */
+	if (thisboard->ao_chans > 0) {
+		s->type = COMEDI_SUBD_AO;
+		s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
+		s->n_chan = thisboard->ao_chans;;
+		s->maxdata = (1 << thisboard->ao_bits) - 1;
+		s->range_table = &pci230_ao_range;
+		s->insn_write = &pci230_ao_winsn;
+		s->insn_read = &pci230_ao_rinsn;
+		s->len_chanlist = thisboard->ao_chans;
+		/* Only register commands if the interrupt handler is
+		 * installed. */
+		if (irq_hdl == 0) {
+			dev->write_subdev = s;
+			s->subdev_flags |= SDF_CMD_WRITE;
+			s->do_cmd = &pci230_ao_cmd;
+			s->do_cmdtest = &pci230_ao_cmdtest;
+			s->cancel = pci230_ao_cancel;
+		}
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	s = dev->subdevices + 2;
+	/* digital i/o subdevice */
+	if (thisboard->have_dio) {
+		rc = subdev_8255_init(dev, s, NULL,
+			(devpriv->iobase1 + PCI230_PPI_X_BASE));
+		if (rc < 0)
+			return rc;
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	printk("comedi%d: attached\n", dev->minor);
+
+	return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device.  It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach().  dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pci230_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: amplc_pci230: remove\n", dev->minor);
+
+	if (dev->subdevices && thisboard->have_dio)
+		/* Clean up dio subdevice. */
+		subdev_8255_cleanup(dev, dev->subdevices + 2);
+
+	if (dev->irq)
+		comedi_free_irq(dev->irq, dev);
+
+	if (devpriv) {
+		if (devpriv->pci_dev) {
+			if (dev->iobase) {
+				comedi_pci_disable(devpriv->pci_dev);
+			}
+			pci_dev_put(devpriv->pci_dev);
+		}
+	}
+
+	return 0;
+}
+
+static int get_resources(struct comedi_device * dev, unsigned int res_mask,
+	unsigned char owner)
+{
+	int ok;
+	unsigned int i;
+	unsigned int b;
+	unsigned int claimed;
+	unsigned long irqflags;
+
+	ok = 1;
+	claimed = 0;
+	comedi_spin_lock_irqsave(&devpriv->res_spinlock, irqflags);
+	for (b = 1, i = 0; (i < NUM_RESOURCES)
+		&& (res_mask != 0); b <<= 1, i++) {
+		if ((res_mask & b) != 0) {
+			res_mask &= ~b;
+			if (devpriv->res_owner[i] == OWNER_NONE) {
+				devpriv->res_owner[i] = owner;
+				claimed |= b;
+			} else if (devpriv->res_owner[i] != owner) {
+				for (b = 1, i = 0; claimed != 0; b <<= 1, i++) {
+					if ((claimed & b) != 0) {
+						devpriv->res_owner[i]
+							= OWNER_NONE;
+						claimed &= ~b;
+					}
+				}
+				ok = 0;
+				break;
+			}
+		}
+	}
+	comedi_spin_unlock_irqrestore(&devpriv->res_spinlock, irqflags);
+	return ok;
+}
+
+static inline int get_one_resource(struct comedi_device * dev, unsigned int resource,
+	unsigned char owner)
+{
+	return get_resources(dev, (1U << resource), owner);
+}
+
+static void put_resources(struct comedi_device * dev, unsigned int res_mask,
+	unsigned char owner)
+{
+	unsigned int i;
+	unsigned int b;
+	unsigned long irqflags;
+
+	comedi_spin_lock_irqsave(&devpriv->res_spinlock, irqflags);
+	for (b = 1, i = 0; (i < NUM_RESOURCES)
+		&& (res_mask != 0); b <<= 1, i++) {
+		if ((res_mask & b) != 0) {
+			res_mask &= ~b;
+			if (devpriv->res_owner[i] == owner) {
+				devpriv->res_owner[i] = OWNER_NONE;
+			}
+		}
+	}
+	comedi_spin_unlock_irqrestore(&devpriv->res_spinlock, irqflags);
+}
+
+static inline void put_one_resource(struct comedi_device * dev, unsigned int resource,
+	unsigned char owner)
+{
+	put_resources(dev, (1U << resource), owner);
+}
+
+static inline void put_all_resources(struct comedi_device * dev, unsigned char owner)
+{
+	put_resources(dev, (1U << NUM_RESOURCES) - 1, owner);
+}
+
+/*
+ *  COMEDI_SUBD_AI instruction;
+ */
+static int pci230_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int n, i;
+	unsigned int chan, range, aref;
+	unsigned int gainshift;
+	unsigned int status;
+	unsigned short adccon, adcen;
+
+	/* Unpack channel and range. */
+	chan = CR_CHAN(insn->chanspec);
+	range = CR_RANGE(insn->chanspec);
+	aref = CR_AREF(insn->chanspec);
+	if (aref == AREF_DIFF) {
+		/* Differential. */
+		if (chan >= s->n_chan / 2) {
+			DPRINTK("comedi%d: amplc_pci230: ai_rinsn: "
+				"differential channel number out of range "
+				"0 to %u\n", dev->minor, (s->n_chan / 2) - 1);
+			return -EINVAL;
+		}
+	}
+
+	/* Use Z2-CT2 as a conversion trigger instead of the built-in
+	 * software trigger, as otherwise triggering of differential channels
+	 * doesn't work properly for some versions of PCI230/260.  Also set
+	 * FIFO mode because the ADC busy bit only works for software triggers.
+	 */
+	adccon = PCI230_ADC_TRIG_Z2CT2 | PCI230_ADC_FIFO_EN;
+	/* Set Z2-CT2 output low to avoid any false triggers. */
+	i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2, I8254_MODE0);
+	devpriv->ai_bipolar = pci230_ai_bipolar[range];
+	if (aref == AREF_DIFF) {
+		/* Differential. */
+		gainshift = chan * 2;
+		if (devpriv->hwver == 0) {
+			/* Original PCI230/260 expects both inputs of the
+			 * differential channel to be enabled. */
+			adcen = 3 << gainshift;
+		} else {
+			/* PCI230+/260+ expects only one input of the
+			 * differential channel to be enabled. */
+			adcen = 1 << gainshift;
+		}
+		adccon |= PCI230_ADC_IM_DIF;
+	} else {
+		/* Single ended. */
+		adcen = 1 << chan;
+		gainshift = chan & ~1;
+		adccon |= PCI230_ADC_IM_SE;
+	}
+	devpriv->adcg = (devpriv->adcg & ~(3 << gainshift))
+		| (pci230_ai_gain[range] << gainshift);
+	if (devpriv->ai_bipolar) {
+		adccon |= PCI230_ADC_IR_BIP;
+	} else {
+		adccon |= PCI230_ADC_IR_UNI;
+	}
+
+	/* Enable only this channel in the scan list - otherwise by default
+	 * we'll get one sample from each channel. */
+	outw(adcen, dev->iobase + PCI230_ADCEN);
+
+	/* Set gain for channel. */
+	outw(devpriv->adcg, dev->iobase + PCI230_ADCG);
+
+	/* Specify uni/bip, se/diff, conversion source, and reset FIFO. */
+	devpriv->adccon = adccon;
+	outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON);
+
+	/* Convert n samples */
+	for (n = 0; n < insn->n; n++) {
+		/* Trigger conversion by toggling Z2-CT2 output (finish with
+		 * output high). */
+		i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
+			I8254_MODE0);
+		i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
+			I8254_MODE1);
+
+#define TIMEOUT 100
+		/* wait for conversion to end */
+		for (i = 0; i < TIMEOUT; i++) {
+			status = inw(dev->iobase + PCI230_ADCCON);
+			if (!(status & PCI230_ADC_FIFO_EMPTY))
+				break;
+			comedi_udelay(1);
+		}
+		if (i == TIMEOUT) {
+			/* rt_printk() should be used instead of printk()
+			 * whenever the code can be called from real-time. */
+			rt_printk("timeout\n");
+			return -ETIMEDOUT;
+		}
+
+		/* read data */
+		data[n] = pci230_ai_read(dev);
+	}
+
+	/* return the number of samples read/written */
+	return n;
+}
+
+/*
+ *  COMEDI_SUBD_AO instructions;
+ */
+static int pci230_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan, range;
+
+	/* Unpack channel and range. */
+	chan = CR_CHAN(insn->chanspec);
+	range = CR_RANGE(insn->chanspec);
+
+	/* Set range - see analogue output range table; 0 => unipolar 10V,
+	 * 1 => bipolar +/-10V range scale */
+	devpriv->ao_bipolar = pci230_ao_bipolar[range];
+	outw(range, dev->iobase + PCI230_DACCON);
+
+	/* Writing a list of values to an AO channel is probably not
+	 * very useful, but that's how the interface is defined. */
+	for (i = 0; i < insn->n; i++) {
+		/* Write value to DAC and store it. */
+		pci230_ao_write_nofifo(dev, data[i], chan);
+	}
+
+	/* return the number of samples read/written */
+	return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+ * Usually this means copying a value stored in devpriv. */
+static int pci230_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+
+	for (i = 0; i < insn->n; i++)
+		data[i] = devpriv->ao_readback[chan];
+
+	return i;
+}
+
+static int pci230_ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	unsigned int tmp;
+
+	/* cmdtest tests a particular command to see if it is valid.
+	 * Using the cmdtest ioctl, a user can create a valid cmd
+	 * and then have it executes by the cmd ioctl.
+	 *
+	 * cmdtest returns 1,2,3,4 or 0, depending on which tests
+	 * the command passes. */
+
+	/* Step 1: make sure trigger sources are trivially valid.
+	 * "invalid source" returned by comedilib to user mode process
+	 * if this fails. */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_INT;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	if ((thisboard->min_hwver > 0) && (devpriv->hwver >= 2)) {
+		/*
+		 * For PCI230+ hardware version 2 onwards, allow external
+		 * trigger from EXTTRIG/EXTCONVCLK input (PCI230+ pin 25).
+		 *
+		 * FIXME: The permitted scan_begin_src values shouldn't depend
+		 * on devpriv->hwver (the detected card's actual hardware
+		 * version).  They should only depend on thisboard->min_hwver
+		 * (the static capabilities of the configured card).  To fix
+		 * it, a new card model, e.g. "pci230+2" would have to be
+		 * defined with min_hwver set to 2.  It doesn't seem worth it
+		 * for this alone.  At the moment, please consider
+		 * scan_begin_src==TRIG_EXT support to be a bonus rather than a
+		 * guarantee!
+		 */
+		cmd->scan_begin_src &= TRIG_TIMER | TRIG_INT | TRIG_EXT;
+	} else {
+		cmd->scan_begin_src &= TRIG_TIMER | TRIG_INT;
+	}
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_NOW;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* Step 2: make sure trigger sources are unique and mutually compatible
+	 * "source conflict" returned by comedilib to user mode process
+	 * if this fails. */
+
+	/* these tests are true if more than one _src bit is set */
+	if ((cmd->start_src & (cmd->start_src - 1)) != 0)
+		err++;
+	if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
+		err++;
+	if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
+		err++;
+	if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
+		err++;
+	if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* Step 3: make sure arguments are trivially compatible.
+	 * "invalid argument" returned by comedilib to user mode process
+	 * if this fails. */
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+#define MAX_SPEED_AO	8000	/* 8000 ns => 125 kHz */
+#define MIN_SPEED_AO	4294967295u	/* 4294967295ns = 4.29s */
+			/*- Comedi limit due to unsigned int cmd.  Driver limit
+			 * = 2^16 (16bit * counter) * 1000000ns (1kHz onboard
+			 * clock) = 65.536s */
+
+	switch (cmd->scan_begin_src) {
+	case TRIG_TIMER:
+		if (cmd->scan_begin_arg < MAX_SPEED_AO) {
+			cmd->scan_begin_arg = MAX_SPEED_AO;
+			err++;
+		}
+		if (cmd->scan_begin_arg > MIN_SPEED_AO) {
+			cmd->scan_begin_arg = MIN_SPEED_AO;
+			err++;
+		}
+		break;
+	case TRIG_EXT:
+		/* External trigger - for PCI230+ hardware version 2 onwards. */
+		/* Trigger number must be 0. */
+		if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
+			cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
+				~CR_FLAGS_MASK);
+			err++;
+		}
+		/* The only flags allowed are CR_EDGE and CR_INVERT.  The
+		 * CR_EDGE flag is ignored. */
+		if ((cmd->scan_begin_arg
+				& (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) !=
+			0) {
+			cmd->scan_begin_arg =
+				COMBINE(cmd->scan_begin_arg, 0,
+				CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT));
+			err++;
+		}
+		break;
+	default:
+		if (cmd->scan_begin_arg != 0) {
+			cmd->scan_begin_arg = 0;
+			err++;
+		}
+		break;
+	}
+
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+	if (cmd->stop_src == TRIG_NONE) {
+		/* TRIG_NONE */
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (err)
+		return 3;
+
+	/* Step 4: fix up any arguments.
+	 * "argument conflict" returned by comedilib to user mode process
+	 * if this fails. */
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		tmp = cmd->scan_begin_arg;
+		pci230_ns_to_single_timer(&cmd->scan_begin_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+		if (tmp != cmd->scan_begin_arg)
+			err++;
+	}
+
+	if (err)
+		return 4;
+
+	/* Step 5: check channel list if it exists. */
+
+	if (cmd->chanlist && cmd->chanlist_len > 0) {
+		enum {
+			seq_err = (1 << 0),
+			range_err = (1 << 1)
+		};
+		unsigned int errors;
+		unsigned int n;
+		unsigned int chan, prev_chan;
+		unsigned int range, first_range;
+
+		prev_chan = CR_CHAN(cmd->chanlist[0]);
+		first_range = CR_RANGE(cmd->chanlist[0]);
+		errors = 0;
+		for (n = 1; n < cmd->chanlist_len; n++) {
+			chan = CR_CHAN(cmd->chanlist[n]);
+			range = CR_RANGE(cmd->chanlist[n]);
+			/* Channel numbers must strictly increase. */
+			if (chan < prev_chan) {
+				errors |= seq_err;
+			}
+			/* Ranges must be the same. */
+			if (range != first_range) {
+				errors |= range_err;
+			}
+			prev_chan = chan;
+		}
+		if (errors != 0) {
+			err++;
+			if ((errors & seq_err) != 0) {
+				DPRINTK("comedi%d: amplc_pci230: ao_cmdtest: "
+					"channel numbers must increase\n",
+					dev->minor);
+			}
+			if ((errors & range_err) != 0) {
+				DPRINTK("comedi%d: amplc_pci230: ao_cmdtest: "
+					"channels must have the same range\n",
+					dev->minor);
+			}
+		}
+	}
+
+	if (err)
+		return 5;
+
+	return 0;
+}
+
+static int pci230_ao_inttrig_scan_begin(struct comedi_device * dev,
+	struct comedi_subdevice * s, unsigned int trig_num)
+{
+	unsigned long irqflags;
+
+	if (trig_num != 0)
+		return -EINVAL;
+
+	comedi_spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags);
+	if (test_bit(AO_CMD_STARTED, &devpriv->state)) {
+		/* Perform scan. */
+		if (devpriv->hwver < 2) {
+			/* Not using DAC FIFO. */
+			comedi_spin_unlock_irqrestore(&devpriv->
+				ao_stop_spinlock, irqflags);
+			pci230_handle_ao_nofifo(dev, s);
+			comedi_event(dev, s);
+		} else {
+			/* Using DAC FIFO. */
+			/* Read DACSWTRIG register to trigger conversion. */
+			inw(dev->iobase + PCI230P2_DACSWTRIG);
+			comedi_spin_unlock_irqrestore(&devpriv->
+				ao_stop_spinlock, irqflags);
+		}
+		/* Delay.  Should driver be responsible for this? */
+		/* XXX TODO: See if DAC busy bit can be used. */
+		comedi_udelay(8);
+	}
+
+	return 1;
+}
+
+static void pci230_ao_start(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+	unsigned long irqflags;
+
+	set_bit(AO_CMD_STARTED, &devpriv->state);
+	if (!devpriv->ao_continuous && (devpriv->ao_scan_count == 0)) {
+		/* An empty acquisition! */
+		async->events |= COMEDI_CB_EOA;
+		pci230_ao_stop(dev, s);
+		comedi_event(dev, s);
+	} else {
+		if (devpriv->hwver >= 2) {
+			/* Using DAC FIFO. */
+			unsigned short scantrig;
+			int run;
+
+			/* Preload FIFO data. */
+			run = pci230_handle_ao_fifo(dev, s);
+			comedi_event(dev, s);
+			if (!run) {
+				/* Stopped. */
+				return;
+			}
+			/* Set scan trigger source. */
+			switch (cmd->scan_begin_src) {
+			case TRIG_TIMER:
+				scantrig = PCI230P2_DAC_TRIG_Z2CT1;
+				break;
+			case TRIG_EXT:
+				/* Trigger on EXTTRIG/EXTCONVCLK pin. */
+				if ((cmd->scan_begin_arg & CR_INVERT) == 0) {
+					/* +ve edge */
+					scantrig = PCI230P2_DAC_TRIG_EXTP;
+				} else {
+					/* -ve edge */
+					scantrig = PCI230P2_DAC_TRIG_EXTN;
+				}
+				break;
+			case TRIG_INT:
+				scantrig = PCI230P2_DAC_TRIG_SW;
+				break;
+			default:
+				/* Shouldn't get here. */
+				scantrig = PCI230P2_DAC_TRIG_NONE;
+				break;
+			}
+			devpriv->daccon = (devpriv->daccon
+				& ~PCI230P2_DAC_TRIG_MASK) | scantrig;
+			outw(devpriv->daccon, dev->iobase + PCI230_DACCON);
+
+		}
+		switch (cmd->scan_begin_src) {
+		case TRIG_TIMER:
+			if (devpriv->hwver < 2) {
+				/* Not using DAC FIFO. */
+				/* Enable CT1 timer interrupt. */
+				comedi_spin_lock_irqsave(&devpriv->isr_spinlock,
+					irqflags);
+				devpriv->int_en |= PCI230_INT_ZCLK_CT1;
+				devpriv->ier |= PCI230_INT_ZCLK_CT1;
+				outb(devpriv->ier,
+					devpriv->iobase1 + PCI230_INT_SCE);
+				comedi_spin_unlock_irqrestore(&devpriv->
+					isr_spinlock, irqflags);
+			}
+			/* Set CT1 gate high to start counting. */
+			outb(GAT_CONFIG(1, GAT_VCC),
+				devpriv->iobase1 + PCI230_ZGAT_SCE);
+			break;
+		case TRIG_INT:
+			async->inttrig = pci230_ao_inttrig_scan_begin;
+			break;
+		}
+		if (devpriv->hwver >= 2) {
+			/* Using DAC FIFO.  Enable DAC FIFO interrupt. */
+			comedi_spin_lock_irqsave(&devpriv->isr_spinlock,
+				irqflags);
+			devpriv->int_en |= PCI230P2_INT_DAC;
+			devpriv->ier |= PCI230P2_INT_DAC;
+			outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
+			comedi_spin_unlock_irqrestore(&devpriv->isr_spinlock,
+				irqflags);
+		}
+	}
+}
+
+static int pci230_ao_inttrig_start(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int trig_num)
+{
+	if (trig_num != 0)
+		return -EINVAL;
+
+	s->async->inttrig = NULLFUNC;
+	pci230_ao_start(dev, s);
+
+	return 1;
+}
+
+static int pci230_ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	unsigned short daccon;
+	unsigned int range;
+
+	/* Get the command. */
+	struct comedi_cmd *cmd = &s->async->cmd;
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		/* Claim Z2-CT1. */
+		if (!get_one_resource(dev, RES_Z2CT1, OWNER_AOCMD)) {
+			return -EBUSY;
+		}
+	}
+
+	/* Get number of scans required. */
+	if (cmd->stop_src == TRIG_COUNT) {
+		devpriv->ao_scan_count = cmd->stop_arg;
+		devpriv->ao_continuous = 0;
+	} else {
+		/* TRIG_NONE, user calls cancel. */
+		devpriv->ao_scan_count = 0;
+		devpriv->ao_continuous = 1;
+	}
+
+	/* Set range - see analogue output range table; 0 => unipolar 10V,
+	 * 1 => bipolar +/-10V range scale */
+	range = CR_RANGE(cmd->chanlist[0]);
+	devpriv->ao_bipolar = pci230_ao_bipolar[range];
+	daccon = devpriv->ao_bipolar ? PCI230_DAC_OR_BIP : PCI230_DAC_OR_UNI;
+	/* Use DAC FIFO for hardware version 2 onwards. */
+	if (devpriv->hwver >= 2) {
+		unsigned short dacen;
+		unsigned int i;
+
+		dacen = 0;
+		for (i = 0; i < cmd->chanlist_len; i++) {
+			dacen |= 1 << CR_CHAN(cmd->chanlist[i]);
+		}
+		/* Set channel scan list. */
+		outw(dacen, dev->iobase + PCI230P2_DACEN);
+		/*
+		 * Enable DAC FIFO.
+		 * Set DAC scan source to 'none'.
+		 * Set DAC FIFO interrupt trigger level to 'not half full'.
+		 * Reset DAC FIFO and clear underrun.
+		 *
+		 * N.B. DAC FIFO interrupts are currently disabled.
+		 */
+		daccon |= PCI230P2_DAC_FIFO_EN | PCI230P2_DAC_FIFO_RESET
+			| PCI230P2_DAC_FIFO_UNDERRUN_CLEAR
+			| PCI230P2_DAC_TRIG_NONE | PCI230P2_DAC_INT_FIFO_NHALF;
+	}
+
+	/* Set DACCON. */
+	outw(daccon, dev->iobase + PCI230_DACCON);
+	/* Preserve most of DACCON apart from write-only, transient bits. */
+	devpriv->daccon = daccon
+		& ~(PCI230P2_DAC_FIFO_RESET | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR);
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		/* Set the counter timer 1 to the specified scan frequency. */
+		/* cmd->scan_begin_arg is sampling period in ns */
+		/* gate it off for now. */
+		outb(GAT_CONFIG(1, GAT_GND),
+			devpriv->iobase1 + PCI230_ZGAT_SCE);
+		pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3,
+			cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK);
+	}
+
+	/* N.B. cmd->start_src == TRIG_INT */
+	s->async->inttrig = pci230_ao_inttrig_start;
+
+	return 0;
+}
+
+static int pci230_ai_check_scan_period(struct comedi_cmd * cmd)
+{
+	unsigned int min_scan_period, chanlist_len;
+	int err = 0;
+
+	chanlist_len = cmd->chanlist_len;
+	if (cmd->chanlist_len == 0) {
+		chanlist_len = 1;
+	}
+	min_scan_period = chanlist_len * cmd->convert_arg;
+	if ((min_scan_period < chanlist_len)
+		|| (min_scan_period < cmd->convert_arg)) {
+		/* Arithmetic overflow. */
+		min_scan_period = UINT_MAX;
+		err++;
+	}
+	if (cmd->scan_begin_arg < min_scan_period) {
+		cmd->scan_begin_arg = min_scan_period;
+		err++;
+	}
+
+	return !err;
+}
+
+static int pci230_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	unsigned int tmp;
+
+	/* cmdtest tests a particular command to see if it is valid.
+	 * Using the cmdtest ioctl, a user can create a valid cmd
+	 * and then have it executes by the cmd ioctl.
+	 *
+	 * cmdtest returns 1,2,3,4,5 or 0, depending on which tests
+	 * the command passes. */
+
+	/* Step 1: make sure trigger sources are trivially valid.
+	 * "invalid source" returned by comedilib to user mode process
+	 * if this fails. */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW | TRIG_INT;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	/* Unfortunately, we cannot trigger a scan off an external source
+	 * on the PCI260 board, since it uses the PPIC0 (DIO) input, which
+	 * isn't present on the PCI260.  For PCI260+ we can use the
+	 * EXTTRIG/EXTCONVCLK input on pin 17 instead. */
+	if ((thisboard->have_dio) || (thisboard->min_hwver > 0)) {
+		cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_INT
+			| TRIG_EXT;
+	} else {
+		cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_INT;
+	}
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_TIMER | TRIG_INT | TRIG_EXT;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* Step 2: make sure trigger sources are unique and mutually compatible
+	 * "source conflict" returned by comedilib to user mode process
+	 * if this fails. */
+
+	/* these tests are true if more than one _src bit is set */
+	if ((cmd->start_src & (cmd->start_src - 1)) != 0)
+		err++;
+	if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
+		err++;
+	if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
+		err++;
+	if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
+		err++;
+	if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
+		err++;
+
+	/* If scan_begin_src is not TRIG_FOLLOW, then a monostable will be
+	 * set up to generate a fixed number of timed conversion pulses. */
+	if ((cmd->scan_begin_src != TRIG_FOLLOW)
+		&& (cmd->convert_src != TRIG_TIMER))
+		err++;
+
+	if (err)
+		return 2;
+
+	/* Step 3: make sure arguments are trivially compatible.
+	 * "invalid argument" returned by comedilib to user mode process
+	 * if this fails. */
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+#define MAX_SPEED_AI_SE		3200	/* PCI230 SE:   3200 ns => 312.5 kHz */
+#define MAX_SPEED_AI_DIFF	8000	/* PCI230 DIFF: 8000 ns => 125 kHz */
+#define MAX_SPEED_AI_PLUS	4000	/* PCI230+:     4000 ns => 250 kHz */
+#define MIN_SPEED_AI	4294967295u	/* 4294967295ns = 4.29s */
+			/*- Comedi limit due to unsigned int cmd.  Driver limit
+			 * = 2^16 (16bit * counter) * 1000000ns (1kHz onboard
+			 * clock) = 65.536s */
+
+	if (cmd->convert_src == TRIG_TIMER) {
+		unsigned int max_speed_ai;
+
+		if (devpriv->hwver == 0) {
+			/* PCI230 or PCI260.  Max speed depends whether
+			 * single-ended or pseudo-differential. */
+			if (cmd->chanlist && (cmd->chanlist_len > 0)) {
+				/* Peek analogue reference of first channel. */
+				if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF) {
+					max_speed_ai = MAX_SPEED_AI_DIFF;
+				} else {
+					max_speed_ai = MAX_SPEED_AI_SE;
+				}
+			} else {
+				/* No channel list.  Assume single-ended. */
+				max_speed_ai = MAX_SPEED_AI_SE;
+			}
+		} else {
+			/* PCI230+ or PCI260+. */
+			max_speed_ai = MAX_SPEED_AI_PLUS;
+		}
+
+		if (cmd->convert_arg < max_speed_ai) {
+			cmd->convert_arg = max_speed_ai;
+			err++;
+		}
+		if (cmd->convert_arg > MIN_SPEED_AI) {
+			cmd->convert_arg = MIN_SPEED_AI;
+			err++;
+		}
+	} else if (cmd->convert_src == TRIG_EXT) {
+		/*
+		 * external trigger
+		 *
+		 * convert_arg == (CR_EDGE | 0)
+		 *                => trigger on +ve edge.
+		 * convert_arg == (CR_EDGE | CR_INVERT | 0)
+		 *                => trigger on -ve edge.
+		 */
+		if ((cmd->convert_arg & CR_FLAGS_MASK) != 0) {
+			/* Trigger number must be 0. */
+			if ((cmd->convert_arg & ~CR_FLAGS_MASK) != 0) {
+				cmd->convert_arg = COMBINE(cmd->convert_arg, 0,
+					~CR_FLAGS_MASK);
+				err++;
+			}
+			/* The only flags allowed are CR_INVERT and CR_EDGE.
+			 * CR_EDGE is required. */
+			if ((cmd->convert_arg & (CR_FLAGS_MASK & ~CR_INVERT))
+				!= CR_EDGE) {
+				/* Set CR_EDGE, preserve CR_INVERT. */
+				cmd->convert_arg =
+					COMBINE(cmd->start_arg, (CR_EDGE | 0),
+					CR_FLAGS_MASK & ~CR_INVERT);
+				err++;
+			}
+		} else {
+			/* Backwards compatibility with previous versions. */
+			/* convert_arg == 0 => trigger on -ve edge. */
+			/* convert_arg == 1 => trigger on +ve edge. */
+			if (cmd->convert_arg > 1) {
+				/* Default to trigger on +ve edge. */
+				cmd->convert_arg = 1;
+				err++;
+			}
+		}
+	} else {
+		if (cmd->convert_arg != 0) {
+			cmd->convert_arg = 0;
+			err++;
+		}
+	}
+
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+
+	if (cmd->stop_src == TRIG_NONE) {
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (cmd->scan_begin_src == TRIG_EXT) {
+		/* external "trigger" to begin each scan
+		 * scan_begin_arg==0 => use PPC0 input -> gate of CT0 -> gate
+		 * of CT2 (sample convert trigger is CT2) */
+		if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
+			cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
+				~CR_FLAGS_MASK);
+			err++;
+		}
+		/* The only flag allowed is CR_EDGE, which is ignored. */
+		if ((cmd->scan_begin_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
+			cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
+				CR_FLAGS_MASK & ~CR_EDGE);
+			err++;
+		}
+	} else if (cmd->scan_begin_src == TRIG_TIMER) {
+		/* N.B. cmd->convert_arg is also TRIG_TIMER */
+		if (!pci230_ai_check_scan_period(cmd)) {
+			err++;
+		}
+	} else {
+		if (cmd->scan_begin_arg != 0) {
+			cmd->scan_begin_arg = 0;
+			err++;
+		}
+	}
+
+	if (err)
+		return 3;
+
+	/* Step 4: fix up any arguments.
+	 * "argument conflict" returned by comedilib to user mode process
+	 * if this fails. */
+
+	if (cmd->convert_src == TRIG_TIMER) {
+		tmp = cmd->convert_arg;
+		pci230_ns_to_single_timer(&cmd->convert_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+		if (tmp != cmd->convert_arg)
+			err++;
+	}
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		/* N.B. cmd->convert_arg is also TRIG_TIMER */
+		tmp = cmd->scan_begin_arg;
+		pci230_ns_to_single_timer(&cmd->scan_begin_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+		if (!pci230_ai_check_scan_period(cmd)) {
+			/* Was below minimum required.  Round up. */
+			pci230_ns_to_single_timer(&cmd->scan_begin_arg,
+				TRIG_ROUND_UP);
+			pci230_ai_check_scan_period(cmd);
+		}
+		if (tmp != cmd->scan_begin_arg)
+			err++;
+	}
+
+	if (err)
+		return 4;
+
+	/* Step 5: check channel list if it exists. */
+
+	if (cmd->chanlist && cmd->chanlist_len > 0) {
+		enum {
+			seq_err = 1 << 0,
+			rangepair_err = 1 << 1,
+			polarity_err = 1 << 2,
+			aref_err = 1 << 3,
+			diffchan_err = 1 << 4,
+			buggy_chan0_err = 1 << 5
+		};
+		unsigned int errors;
+		unsigned int chan, prev_chan;
+		unsigned int range, prev_range;
+		unsigned int polarity, prev_polarity;
+		unsigned int aref, prev_aref;
+		unsigned int subseq_len;
+		unsigned int n;
+
+		subseq_len = 0;
+		errors = 0;
+		prev_chan = prev_aref = prev_range = prev_polarity = 0;
+		for (n = 0; n < cmd->chanlist_len; n++) {
+			chan = CR_CHAN(cmd->chanlist[n]);
+			range = CR_RANGE(cmd->chanlist[n]);
+			aref = CR_AREF(cmd->chanlist[n]);
+			polarity = pci230_ai_bipolar[range];
+			/* Only the first half of the channels are available if
+			 * differential.  (These are remapped in software.  In
+			 * hardware, only the even channels are available.) */
+			if ((aref == AREF_DIFF)
+				&& (chan >= (s->n_chan / 2))) {
+				errors |= diffchan_err;
+			}
+			if (n > 0) {
+				/* Channel numbers must strictly increase or
+				 * subsequence must repeat exactly. */
+				if ((chan <= prev_chan)
+					&& (subseq_len == 0)) {
+					subseq_len = n;
+				}
+				if ((subseq_len > 0)
+					&& (cmd->chanlist[n] !=
+						cmd->chanlist[n %
+							subseq_len])) {
+					errors |= seq_err;
+				}
+				/* Channels must have same AREF. */
+				if (aref != prev_aref) {
+					errors |= aref_err;
+				}
+				/* Channel ranges must have same polarity. */
+				if (polarity != prev_polarity) {
+					errors |= polarity_err;
+				}
+				/* Single-ended channel pairs must have same
+				 * range.  */
+				if ((aref != AREF_DIFF)
+					&& (((chan ^ prev_chan) & ~1) == 0)
+					&& (range != prev_range)) {
+					errors |= rangepair_err;
+				}
+			}
+			prev_chan = chan;
+			prev_range = range;
+			prev_aref = aref;
+			prev_polarity = polarity;
+		}
+		if (subseq_len == 0) {
+			/* Subsequence is whole sequence. */
+			subseq_len = n;
+		}
+		/* If channel list is a repeating subsequence, need a whole
+		 * number of repeats. */
+		if ((n % subseq_len) != 0) {
+			errors |= seq_err;
+		}
+		if ((devpriv->hwver > 0) && (devpriv->hwver < 4)) {
+			/*
+			 * Buggy PCI230+ or PCI260+ requires channel 0 to be
+			 * (first) in the sequence if the sequence contains
+			 * more than one channel.  Hardware versions 1 and 2
+			 * have the bug.  There is no hardware version 3.
+			 *
+			 * Actually, there are two firmwares that report
+			 * themselves as hardware version 1 (the boards
+			 * have different ADC chips with slightly different
+			 * timing requirements, which was supposed to be
+			 * invisible to software).  The first one doesn't
+			 * seem to have the bug, but the second one
+			 * does, and we can't tell them apart!
+			 */
+			if ((subseq_len > 1)
+				&& (CR_CHAN(cmd->chanlist[0]) != 0)) {
+				errors |= buggy_chan0_err;
+			}
+		}
+		if (errors != 0) {
+			err++;
+			if ((errors & seq_err) != 0) {
+				DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
+					"channel numbers must increase or "
+					"sequence must repeat exactly\n",
+					dev->minor);
+			}
+			if ((errors & rangepair_err) != 0) {
+				DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
+					"single-ended channel pairs must "
+					"have the same range\n", dev->minor);
+			}
+			if ((errors & polarity_err) != 0) {
+				DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
+					"channel sequence ranges must be all "
+					"bipolar or all unipolar\n",
+					dev->minor);
+			}
+			if ((errors & aref_err) != 0) {
+				DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
+					"channel sequence analogue references "
+					"must be all the same (single-ended "
+					"or differential)\n", dev->minor);
+			}
+			if ((errors & diffchan_err) != 0) {
+				DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
+					"differential channel number out of "
+					"range 0 to %u\n", dev->minor,
+					(s->n_chan / 2) - 1);
+			}
+			if ((errors & buggy_chan0_err) != 0) {
+				/* Use printk instead of DPRINTK here. */
+				printk("comedi: comedi%d: amplc_pci230: "
+					"ai_cmdtest: Buggy PCI230+/260+ "
+					"h/w version %u requires first channel "
+					"of multi-channel sequence to be 0 "
+					"(corrected in h/w version 4)\n",
+					dev->minor, devpriv->hwver);
+			}
+		}
+	}
+
+	if (err)
+		return 5;
+
+	return 0;
+}
+
+static void pci230_ai_update_fifo_trigger_level(struct comedi_device * dev,
+	struct comedi_subdevice * s)
+{
+	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int scanlen = cmd->scan_end_arg;
+	unsigned int wake;
+	unsigned short triglev;
+	unsigned short adccon;
+
+	if ((cmd->flags & TRIG_WAKE_EOS) != 0) {
+		/* Wake at end of scan. */
+		wake = scanlen - devpriv->ai_scan_pos;
+	} else {
+		if (devpriv->ai_continuous
+			|| (devpriv->ai_scan_count
+				>= PCI230_ADC_FIFOLEVEL_HALFFULL)
+			|| (scanlen >= PCI230_ADC_FIFOLEVEL_HALFFULL)) {
+			wake = PCI230_ADC_FIFOLEVEL_HALFFULL;
+		} else {
+			wake = (devpriv->ai_scan_count * scanlen)
+				- devpriv->ai_scan_pos;
+		}
+	}
+	if (wake >= PCI230_ADC_FIFOLEVEL_HALFFULL) {
+		triglev = PCI230_ADC_INT_FIFO_HALF;
+	} else {
+		if ((wake > 1) && (devpriv->hwver > 0)) {
+			/* PCI230+/260+ programmable FIFO interrupt level. */
+			if (devpriv->adcfifothresh != wake) {
+				devpriv->adcfifothresh = wake;
+				outw(wake, dev->iobase + PCI230P_ADCFFTH);
+			}
+			triglev = PCI230P_ADC_INT_FIFO_THRESH;
+		} else {
+			triglev = PCI230_ADC_INT_FIFO_NEMPTY;
+		}
+	}
+	adccon = (devpriv->adccon & ~PCI230_ADC_INT_FIFO_MASK) | triglev;
+	if (adccon != devpriv->adccon) {
+		devpriv->adccon = adccon;
+		outw(adccon, dev->iobase + PCI230_ADCCON);
+	}
+}
+
+static int pci230_ai_inttrig_convert(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int trig_num)
+{
+	unsigned long irqflags;
+
+	if (trig_num != 0)
+		return -EINVAL;
+
+	comedi_spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
+	if (test_bit(AI_CMD_STARTED, &devpriv->state)) {
+		unsigned int delayus;
+
+		/* Trigger conversion by toggling Z2-CT2 output.  Finish
+		 * with output high. */
+		i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
+			I8254_MODE0);
+		i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
+			I8254_MODE1);
+		/* Delay.  Should driver be responsible for this?  An
+		 * alternative would be to wait until conversion is complete,
+		 * but we can't tell when it's complete because the ADC busy
+		 * bit has a different meaning when FIFO enabled (and when
+		 * FIFO not enabled, it only works for software triggers). */
+		if (((devpriv->adccon & PCI230_ADC_IM_MASK)
+				== PCI230_ADC_IM_DIF)
+			&& (devpriv->hwver == 0)) {
+			/* PCI230/260 in differential mode */
+			delayus = 8;
+		} else {
+			/* single-ended or PCI230+/260+ */
+			delayus = 4;
+		}
+		comedi_spin_unlock_irqrestore(&devpriv->ai_stop_spinlock,
+			irqflags);
+		comedi_udelay(delayus);
+	} else {
+		comedi_spin_unlock_irqrestore(&devpriv->ai_stop_spinlock,
+			irqflags);
+	}
+
+	return 1;
+}
+
+static int pci230_ai_inttrig_scan_begin(struct comedi_device * dev,
+	struct comedi_subdevice * s, unsigned int trig_num)
+{
+	unsigned long irqflags;
+	unsigned char zgat;
+
+	if (trig_num != 0)
+		return -EINVAL;
+
+	comedi_spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
+	if (test_bit(AI_CMD_STARTED, &devpriv->state)) {
+		/* Trigger scan by waggling CT0 gate source. */
+		zgat = GAT_CONFIG(0, GAT_GND);
+		outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
+		zgat = GAT_CONFIG(0, GAT_VCC);
+		outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
+	}
+	comedi_spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
+
+	return 1;
+}
+
+static void pci230_ai_start(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	unsigned long irqflags;
+	unsigned short conv;
+	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+
+	set_bit(AI_CMD_STARTED, &devpriv->state);
+	if (!devpriv->ai_continuous && (devpriv->ai_scan_count == 0)) {
+		/* An empty acquisition! */
+		async->events |= COMEDI_CB_EOA;
+		pci230_ai_stop(dev, s);
+		comedi_event(dev, s);
+	} else {
+		/* Enable ADC FIFO trigger level interrupt. */
+		comedi_spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
+		devpriv->int_en |= PCI230_INT_ADC;
+		devpriv->ier |= PCI230_INT_ADC;
+		outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
+		comedi_spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
+
+		/* Update conversion trigger source which is currently set
+		 * to CT2 output, which is currently stuck high. */
+		switch (cmd->convert_src) {
+		default:
+			conv = PCI230_ADC_TRIG_NONE;
+			break;
+		case TRIG_TIMER:
+			/* Using CT2 output. */
+			conv = PCI230_ADC_TRIG_Z2CT2;
+			break;
+		case TRIG_EXT:
+			if ((cmd->convert_arg & CR_EDGE) != 0) {
+				if ((cmd->convert_arg & CR_INVERT) == 0) {
+					/* Trigger on +ve edge. */
+					conv = PCI230_ADC_TRIG_EXTP;
+				} else {
+					/* Trigger on -ve edge. */
+					conv = PCI230_ADC_TRIG_EXTN;
+				}
+			} else {
+				/* Backwards compatibility. */
+				if (cmd->convert_arg != 0) {
+					/* Trigger on +ve edge. */
+					conv = PCI230_ADC_TRIG_EXTP;
+				} else {
+					/* Trigger on -ve edge. */
+					conv = PCI230_ADC_TRIG_EXTN;
+				}
+			}
+			break;
+		case TRIG_INT:
+			/* Use CT2 output for software trigger due to problems
+			 * in differential mode on PCI230/260. */
+			conv = PCI230_ADC_TRIG_Z2CT2;
+			break;
+		}
+		devpriv->adccon = (devpriv->adccon & ~PCI230_ADC_TRIG_MASK)
+			| conv;
+		outw(devpriv->adccon, dev->iobase + PCI230_ADCCON);
+		if (cmd->convert_src == TRIG_INT) {
+			async->inttrig = pci230_ai_inttrig_convert;
+		}
+		/* Update FIFO interrupt trigger level, which is currently
+		 * set to "full".  */
+		pci230_ai_update_fifo_trigger_level(dev, s);
+		if (cmd->convert_src == TRIG_TIMER) {
+			/* Update timer gates. */
+			unsigned char zgat;
+
+			if (cmd->scan_begin_src != TRIG_FOLLOW) {
+				/* Conversion timer CT2 needs to be gated by
+				 * inverted output of monostable CT2. */
+				zgat = GAT_CONFIG(2, GAT_NOUTNM2);
+			} else {
+				/* Conversion timer CT2 needs to be gated on
+				 * continuously. */
+				zgat = GAT_CONFIG(2, GAT_VCC);
+			}
+			outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
+			if (cmd->scan_begin_src != TRIG_FOLLOW) {
+				/* Set monostable CT0 trigger source. */
+				switch (cmd->scan_begin_src) {
+				default:
+					zgat = GAT_CONFIG(0, GAT_VCC);
+					break;
+				case TRIG_EXT:
+					/*
+					 * For CT0 on PCI230, the external
+					 * trigger (gate) signal comes from
+					 * PPC0, which is channel 16 of the DIO
+					 * subdevice.  The application needs to
+					 * configure this as an input in order
+					 * to use it as an external scan
+					 * trigger.
+					 */
+					zgat = GAT_CONFIG(0, GAT_EXT);
+					break;
+				case TRIG_TIMER:
+					/*
+					 * Monostable CT0 triggered by rising
+					 * edge on inverted output of CT1
+					 * (falling edge on CT1).
+					 */
+					zgat = GAT_CONFIG(0, GAT_NOUTNM2);
+					break;
+				case TRIG_INT:
+					/*
+					 * Monostable CT0 is triggered by
+					 * inttrig function waggling the CT0
+					 * gate source.
+					 */
+					zgat = GAT_CONFIG(0, GAT_VCC);
+					break;
+				}
+				outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
+				switch (cmd->scan_begin_src) {
+				case TRIG_TIMER:
+					/* Scan period timer CT1 needs to be
+					 * gated on to start counting. */
+					zgat = GAT_CONFIG(1, GAT_VCC);
+					outb(zgat, devpriv->iobase1
+						+ PCI230_ZGAT_SCE);
+					break;
+				case TRIG_INT:
+					async->inttrig =
+						pci230_ai_inttrig_scan_begin;
+					break;
+				}
+			}
+		} else if (cmd->convert_src != TRIG_INT) {
+			/* No longer need Z2-CT2. */
+			put_one_resource(dev, RES_Z2CT2, OWNER_AICMD);
+		}
+	}
+}
+
+static int pci230_ai_inttrig_start(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int trig_num)
+{
+	if (trig_num != 0)
+		return -EINVAL;
+
+	s->async->inttrig = NULLFUNC;
+	pci230_ai_start(dev, s);
+
+	return 1;
+}
+
+static int pci230_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	unsigned int i, chan, range, diff;
+	unsigned int res_mask;
+	unsigned short adccon, adcen;
+	unsigned char zgat;
+
+	/* Get the command. */
+	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+
+	/*
+	 * Determine which shared resources are needed.
+	 */
+	res_mask = 0;
+	/* Need Z2-CT2 to supply a conversion trigger source at a high
+	 * logic level, even if not doing timed conversions. */
+	res_mask |= (1U << RES_Z2CT2);
+	if (cmd->scan_begin_src != TRIG_FOLLOW) {
+		/* Using Z2-CT0 monostable to gate Z2-CT2 conversion timer */
+		res_mask |= (1U << RES_Z2CT0);
+		if (cmd->scan_begin_src == TRIG_TIMER) {
+			/* Using Z2-CT1 for scan frequency */
+			res_mask |= (1U << RES_Z2CT1);
+		}
+	}
+	/* Claim resources. */
+	if (!get_resources(dev, res_mask, OWNER_AICMD)) {
+		return -EBUSY;
+	}
+
+	/* Get number of scans required. */
+	if (cmd->stop_src == TRIG_COUNT) {
+		devpriv->ai_scan_count = cmd->stop_arg;
+		devpriv->ai_continuous = 0;
+	} else {
+		/* TRIG_NONE, user calls cancel. */
+		devpriv->ai_scan_count = 0;
+		devpriv->ai_continuous = 1;
+	}
+	devpriv->ai_scan_pos = 0;	/* Position within scan. */
+
+	/* Steps;
+	 * - Set channel scan list.
+	 * - Set channel gains.
+	 * - Enable and reset FIFO, specify uni/bip, se/diff, and set
+	 *   start conversion source to point to something at a high logic
+	 *   level (we use the output of counter/timer 2 for this purpose.
+	 * - PAUSE to allow things to settle down.
+	 * - Reset the FIFO again because it needs resetting twice and there
+	 *   may have been a false conversion trigger on some versions of
+	 *   PCI230/260 due to the start conversion source being set to a
+	 *   high logic level.
+	 * - Enable ADC FIFO level interrupt.
+	 * - Set actual conversion trigger source and FIFO interrupt trigger
+	 *   level.
+	 * - If convert_src is TRIG_TIMER, set up the timers.
+	 */
+
+	adccon = PCI230_ADC_FIFO_EN;
+	adcen = 0;
+
+	if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF) {
+		/* Differential - all channels must be differential. */
+		diff = 1;
+		adccon |= PCI230_ADC_IM_DIF;
+	} else {
+		/* Single ended - all channels must be single-ended. */
+		diff = 0;
+		adccon |= PCI230_ADC_IM_SE;
+	}
+
+	range = CR_RANGE(cmd->chanlist[0]);
+	devpriv->ai_bipolar = pci230_ai_bipolar[range];
+	if (devpriv->ai_bipolar) {
+		adccon |= PCI230_ADC_IR_BIP;
+	} else {
+		adccon |= PCI230_ADC_IR_UNI;
+	}
+	for (i = 0; i < cmd->chanlist_len; i++) {
+		unsigned int gainshift;
+
+		chan = CR_CHAN(cmd->chanlist[i]);
+		range = CR_RANGE(cmd->chanlist[i]);
+		if (diff) {
+			gainshift = 2 * chan;
+			if (devpriv->hwver == 0) {
+				/* Original PCI230/260 expects both inputs of
+				 * the differential channel to be enabled. */
+				adcen |= 3 << gainshift;
+			} else {
+				/* PCI230+/260+ expects only one input of the
+				 * differential channel to be enabled. */
+				adcen |= 1 << gainshift;
+			}
+		} else {
+			gainshift = (chan & ~1);
+			adcen |= 1 << chan;
+		}
+		devpriv->adcg = (devpriv->adcg & ~(3 << gainshift))
+			| (pci230_ai_gain[range] << gainshift);
+	}
+
+	/* Set channel scan list. */
+	outw(adcen, dev->iobase + PCI230_ADCEN);
+
+	/* Set channel gains. */
+	outw(devpriv->adcg, dev->iobase + PCI230_ADCG);
+
+	/* Set counter/timer 2 output high for use as the initial start
+	 * conversion source. */
+	i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2, I8254_MODE1);
+
+	/* Temporarily use CT2 output as conversion trigger source and
+	 * temporarily set FIFO interrupt trigger level to 'full'. */
+	adccon |= PCI230_ADC_INT_FIFO_FULL | PCI230_ADC_TRIG_Z2CT2;
+
+	/* Enable and reset FIFO, specify FIFO trigger level full, specify
+	 * uni/bip, se/diff, and temporarily set the start conversion source
+	 * to CT2 output.  Note that CT2 output is currently high, and this
+	 * will produce a false conversion trigger on some versions of the
+	 * PCI230/260, but that will be dealt with later. */
+	devpriv->adccon = adccon;
+	outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON);
+
+	/* Delay */
+	/* Failure to include this will result in the first few channels'-worth
+	 * of data being corrupt, normally manifesting itself by large negative
+	 * voltages. It seems the board needs time to settle between the first
+	 * FIFO reset (above) and the second FIFO reset (below). Setting the
+	 * channel gains and scan list _before_ the first FIFO reset also
+	 * helps, though only slightly. */
+	comedi_udelay(25);
+
+	/* Reset FIFO again. */
+	outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON);
+
+	if (cmd->convert_src == TRIG_TIMER) {
+		/* Set up CT2 as conversion timer, but gate it off for now.
+		 * Note, counter/timer output 2 can be monitored on the
+		 * connector: PCI230 pin 21, PCI260 pin 18. */
+		zgat = GAT_CONFIG(2, GAT_GND);
+		outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
+		/* Set counter/timer 2 to the specified conversion period. */
+		pci230_ct_setup_ns_mode(dev, 2, I8254_MODE3, cmd->convert_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+		if (cmd->scan_begin_src != TRIG_FOLLOW) {
+			/*
+			 * Set up monostable on CT0 output for scan timing.  A
+			 * rising edge on the trigger (gate) input of CT0 will
+			 * trigger the monostable, causing its output to go low
+			 * for the configured period.  The period depends on
+			 * the conversion period and the number of conversions
+			 * in the scan.
+			 *
+			 * Set the trigger high before setting up the
+			 * monostable to stop it triggering.  The trigger
+			 * source will be changed later.
+			 */
+			zgat = GAT_CONFIG(0, GAT_VCC);
+			outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
+			pci230_ct_setup_ns_mode(dev, 0, I8254_MODE1,
+				((uint64_t) cmd->convert_arg
+					* cmd->scan_end_arg), TRIG_ROUND_UP);
+			if (cmd->scan_begin_src == TRIG_TIMER) {
+				/*
+				 * Monostable on CT0 will be triggered by
+				 * output of CT1 at configured scan frequency.
+				 *
+				 * Set up CT1 but gate it off for now.
+				 */
+				zgat = GAT_CONFIG(1, GAT_GND);
+				outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
+				pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3,
+					cmd->scan_begin_arg,
+					cmd->flags & TRIG_ROUND_MASK);
+			}
+		}
+	}
+
+	if (cmd->start_src == TRIG_INT) {
+		s->async->inttrig = pci230_ai_inttrig_start;
+	} else {
+		/* TRIG_NOW */
+		pci230_ai_start(dev, s);
+	}
+
+	return 0;
+}
+
+static unsigned int divide_ns(uint64_t ns, unsigned int timebase,
+	unsigned int round_mode)
+{
+	uint64_t div;
+	unsigned int rem;
+
+	div = ns;
+	rem = do_div(div, timebase);
+	round_mode &= TRIG_ROUND_MASK;
+	switch (round_mode) {
+	default:
+	case TRIG_ROUND_NEAREST:
+		div += (rem + (timebase / 2)) / timebase;
+		break;
+	case TRIG_ROUND_DOWN:
+		break;
+	case TRIG_ROUND_UP:
+		div += (rem + timebase - 1) / timebase;
+		break;
+	}
+	return div > UINT_MAX ? UINT_MAX : (unsigned int)div;
+}
+
+/* Given desired period in ns, returns the required internal clock source
+ * and gets the initial count. */
+static unsigned int pci230_choose_clk_count(uint64_t ns, unsigned int *count,
+	unsigned int round_mode)
+{
+	unsigned int clk_src, cnt;
+
+	for (clk_src = CLK_10MHZ;; clk_src++) {
+		cnt = divide_ns(ns, pci230_timebase[clk_src], round_mode);
+		if ((cnt <= 65536) || (clk_src == CLK_1KHZ)) {
+			break;
+		}
+	}
+	*count = cnt;
+	return clk_src;
+}
+
+static void pci230_ns_to_single_timer(unsigned int *ns, unsigned int round)
+{
+	unsigned int count;
+	unsigned int clk_src;
+
+	clk_src = pci230_choose_clk_count(*ns, &count, round);
+	*ns = count * pci230_timebase[clk_src];
+	return;
+}
+
+static void pci230_ct_setup_ns_mode(struct comedi_device * dev, unsigned int ct,
+	unsigned int mode, uint64_t ns, unsigned int round)
+{
+	unsigned int clk_src;
+	unsigned int count;
+
+	/* Set mode. */
+	i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct, mode);
+	/* Determine clock source and count. */
+	clk_src = pci230_choose_clk_count(ns, &count, round);
+	/* Program clock source. */
+	outb(CLK_CONFIG(ct, clk_src), devpriv->iobase1 + PCI230_ZCLK_SCE);
+	/* Set initial count. */
+	if (count >= 65536) {
+		count = 0;
+	}
+	i8254_write(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct, count);
+}
+
+static void pci230_cancel_ct(struct comedi_device * dev, unsigned int ct)
+{
+	i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct,
+		I8254_MODE1);
+	/* Counter ct, 8254 mode 1, initial count not written. */
+}
+
+/* Interrupt handler */
+static irqreturn_t pci230_interrupt(int irq, void *d PT_REGS_ARG)
+{
+	unsigned char status_int, valid_status_int;
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s;
+	unsigned long irqflags;
+
+	/* Read interrupt status/enable register. */
+	status_int = inb(devpriv->iobase1 + PCI230_INT_STAT);
+
+	if (status_int == PCI230_INT_DISABLE) {
+		return IRQ_NONE;
+	}
+
+	comedi_spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
+	valid_status_int = devpriv->int_en & status_int;
+	/* Disable triggered interrupts.
+	 * (Only those interrupts that need re-enabling, are, later in the
+	 * handler).  */
+	devpriv->ier = devpriv->int_en & ~status_int;
+	outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
+	devpriv->intr_running = 1;
+	devpriv->intr_cpuid = THISCPU;
+	comedi_spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
+
+	/*
+	 * Check the source of interrupt and handle it.
+	 * The PCI230 can cope with concurrent ADC, DAC, PPI C0 and C3
+	 * interrupts.  However, at present (Comedi-0.7.60) does not allow
+	 * concurrent execution of commands, instructions or a mixture of the
+	 * two.
+	 */
+
+	if ((valid_status_int & PCI230_INT_ZCLK_CT1) != 0) {
+		s = dev->write_subdev;
+		pci230_handle_ao_nofifo(dev, s);
+		comedi_event(dev, s);
+	}
+
+	if ((valid_status_int & PCI230P2_INT_DAC) != 0) {
+		s = dev->write_subdev;
+		pci230_handle_ao_fifo(dev, s);
+		comedi_event(dev, s);
+	}
+
+	if ((valid_status_int & PCI230_INT_ADC) != 0) {
+		s = dev->read_subdev;
+		pci230_handle_ai(dev, s);
+		comedi_event(dev, s);
+	}
+
+	/* Reenable interrupts. */
+	comedi_spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
+	if (devpriv->ier != devpriv->int_en) {
+		devpriv->ier = devpriv->int_en;
+		outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
+	}
+	devpriv->intr_running = 0;
+	comedi_spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
+
+	return IRQ_HANDLED;
+}
+
+static void pci230_handle_ao_nofifo(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	short data;
+	int i, ret;
+	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+
+	if (!devpriv->ao_continuous && (devpriv->ao_scan_count == 0)) {
+		return;
+	}
+
+	for (i = 0; i < cmd->chanlist_len; i++) {
+		/* Read sample from Comedi's circular buffer. */
+		ret = comedi_buf_get(s->async, &data);
+		if (ret == 0) {
+			s->async->events |= COMEDI_CB_OVERFLOW;
+			pci230_ao_stop(dev, s);
+			comedi_error(dev, "AO buffer underrun");
+			return;
+		}
+		/* Write value to DAC. */
+		pci230_ao_write_nofifo(dev, data, CR_CHAN(cmd->chanlist[i]));
+	}
+
+	async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
+	if (!devpriv->ao_continuous) {
+		devpriv->ao_scan_count--;
+		if (devpriv->ao_scan_count == 0) {
+			/* End of acquisition. */
+			async->events |= COMEDI_CB_EOA;
+			pci230_ao_stop(dev, s);
+		}
+	}
+}
+
+/* Loads DAC FIFO (if using it) from buffer. */
+/* Returns 0 if AO finished due to completion or error, 1 if still going. */
+static int pci230_handle_ao_fifo(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+	unsigned int num_scans;
+	unsigned int room;
+	unsigned short dacstat;
+	unsigned int i, n;
+	unsigned int bytes_per_scan;
+	unsigned int events = 0;
+	int running;
+
+	/* Get DAC FIFO status. */
+	dacstat = inw(dev->iobase + PCI230_DACCON);
+
+	/* Determine number of scans available in buffer. */
+	bytes_per_scan = cmd->chanlist_len * sizeof(short);
+	num_scans = comedi_buf_read_n_available(async) / bytes_per_scan;
+	if (!devpriv->ao_continuous) {
+		/* Fixed number of scans. */
+		if (num_scans > devpriv->ao_scan_count) {
+			num_scans = devpriv->ao_scan_count;
+		}
+		if (devpriv->ao_scan_count == 0) {
+			/* End of acquisition. */
+			events |= COMEDI_CB_EOA;
+		}
+	}
+	if (events == 0) {
+		/* Check for FIFO underrun. */
+		if ((dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) != 0) {
+			comedi_error(dev, "AO FIFO underrun");
+			events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
+		}
+		/* Check for buffer underrun if FIFO less than half full
+		 * (otherwise there will be loads of "DAC FIFO not half full"
+		 * interrupts). */
+		if ((num_scans == 0)
+			&& ((dacstat & PCI230P2_DAC_FIFO_HALF) == 0)) {
+			comedi_error(dev, "AO buffer underrun");
+			events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
+		}
+	}
+	if (events == 0) {
+		/* Determine how much room is in the FIFO (in samples). */
+		if ((dacstat & PCI230P2_DAC_FIFO_FULL) != 0) {
+			room = PCI230P2_DAC_FIFOROOM_FULL;
+		} else if ((dacstat & PCI230P2_DAC_FIFO_HALF) != 0) {
+			room = PCI230P2_DAC_FIFOROOM_HALFTOFULL;
+		} else if ((dacstat & PCI230P2_DAC_FIFO_EMPTY) != 0) {
+			room = PCI230P2_DAC_FIFOROOM_EMPTY;
+		} else {
+			room = PCI230P2_DAC_FIFOROOM_ONETOHALF;
+		}
+		/* Convert room to number of scans that can be added. */
+		room /= cmd->chanlist_len;
+		/* Determine number of scans to process. */
+		if (num_scans > room) {
+			num_scans = room;
+		}
+		/* Process scans. */
+		for (n = 0; n < num_scans; n++) {
+			for (i = 0; i < cmd->chanlist_len; i++) {
+				short datum;
+
+				comedi_buf_get(async, &datum);
+				pci230_ao_write_fifo(dev, datum,
+					CR_CHAN(cmd->chanlist[i]));
+			}
+		}
+		events |= COMEDI_CB_EOS | COMEDI_CB_BLOCK;
+		if (!devpriv->ao_continuous) {
+			devpriv->ao_scan_count -= num_scans;
+			if (devpriv->ao_scan_count == 0) {
+				/* All data for the command has been written
+				 * to FIFO.  Set FIFO interrupt trigger level
+				 * to 'empty'. */
+				devpriv->daccon = (devpriv->daccon
+					& ~PCI230P2_DAC_INT_FIFO_MASK)
+					| PCI230P2_DAC_INT_FIFO_EMPTY;
+				outw(devpriv->daccon,
+					dev->iobase + PCI230_DACCON);
+			}
+		}
+		/* Check if FIFO underrun occurred while writing to FIFO. */
+		dacstat = inw(dev->iobase + PCI230_DACCON);
+		if ((dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) != 0) {
+			comedi_error(dev, "AO FIFO underrun");
+			events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
+		}
+	}
+	if ((events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW))
+		!= 0) {
+		/* Stopping AO due to completion or error. */
+		pci230_ao_stop(dev, s);
+		running = 0;
+	} else {
+		running = 1;
+	}
+	async->events |= events;
+	return running;
+}
+
+static void pci230_handle_ai(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	unsigned int events = 0;
+	unsigned int status_fifo;
+	unsigned int i;
+	unsigned int todo;
+	unsigned int fifoamount;
+	struct comedi_async *async = s->async;
+	unsigned int scanlen = async->cmd.scan_end_arg;
+
+	/* Determine number of samples to read. */
+	if (devpriv->ai_continuous) {
+		todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
+	} else if (devpriv->ai_scan_count == 0) {
+		todo = 0;
+	} else if ((devpriv->ai_scan_count > PCI230_ADC_FIFOLEVEL_HALFFULL)
+		|| (scanlen > PCI230_ADC_FIFOLEVEL_HALFFULL)) {
+		todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
+	} else {
+		todo = (devpriv->ai_scan_count * scanlen)
+			- devpriv->ai_scan_pos;
+		if (todo > PCI230_ADC_FIFOLEVEL_HALFFULL) {
+			todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
+		}
+	}
+
+	if (todo == 0) {
+		return;
+	}
+
+	fifoamount = 0;
+	for (i = 0; i < todo; i++) {
+		if (fifoamount == 0) {
+			/* Read FIFO state. */
+			status_fifo = inw(dev->iobase + PCI230_ADCCON);
+
+			if ((status_fifo & PCI230_ADC_FIFO_FULL_LATCHED) != 0) {
+				/* Report error otherwise FIFO overruns will go
+				 * unnoticed by the caller. */
+				comedi_error(dev, "AI FIFO overrun");
+				events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
+				break;
+			} else if ((status_fifo & PCI230_ADC_FIFO_EMPTY) != 0) {
+				/* FIFO empty. */
+				break;
+			} else if ((status_fifo & PCI230_ADC_FIFO_HALF) != 0) {
+				/* FIFO half full. */
+				fifoamount = PCI230_ADC_FIFOLEVEL_HALFFULL;
+			} else {
+				/* FIFO not empty. */
+				if (devpriv->hwver > 0) {
+					/* Read PCI230+/260+ ADC FIFO level. */
+					fifoamount = inw(dev->iobase
+						+ PCI230P_ADCFFLEV);
+					if (fifoamount == 0) {
+						/* Shouldn't happen. */
+						break;
+					}
+				} else {
+					fifoamount = 1;
+				}
+			}
+		}
+
+		/* Read sample and store in Comedi's circular buffer. */
+		if (comedi_buf_put(async, pci230_ai_read(dev)) == 0) {
+			events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
+			comedi_error(dev, "AI buffer overflow");
+			break;
+		}
+		fifoamount--;
+		devpriv->ai_scan_pos++;
+		if (devpriv->ai_scan_pos == scanlen) {
+			/* End of scan. */
+			devpriv->ai_scan_pos = 0;
+			devpriv->ai_scan_count--;
+			async->events |= COMEDI_CB_EOS;
+		}
+	}
+
+	if (!devpriv->ai_continuous && (devpriv->ai_scan_count == 0)) {
+		/* End of acquisition. */
+		events |= COMEDI_CB_EOA;
+	} else {
+		/* More samples required, tell Comedi to block. */
+		events |= COMEDI_CB_BLOCK;
+	}
+	async->events |= events;
+
+	if ((async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
+				COMEDI_CB_OVERFLOW)) != 0) {
+		/* disable hardware conversions */
+		pci230_ai_stop(dev, s);
+	} else {
+		/* update FIFO interrupt trigger level */
+		pci230_ai_update_fifo_trigger_level(dev, s);
+	}
+}
+
+static void pci230_ao_stop(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	unsigned long irqflags;
+	unsigned char intsrc;
+	int started;
+	struct comedi_cmd *cmd;
+
+	comedi_spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags);
+	started = test_and_clear_bit(AO_CMD_STARTED, &devpriv->state);
+	comedi_spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags);
+	if (!started) {
+		return;
+	}
+
+	cmd = &s->async->cmd;
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		/* Stop scan rate generator. */
+		pci230_cancel_ct(dev, 1);
+	}
+
+	/* Determine interrupt source. */
+	if (devpriv->hwver < 2) {
+		/* Not using DAC FIFO.  Using CT1 interrupt. */
+		intsrc = PCI230_INT_ZCLK_CT1;
+	} else {
+		/* Using DAC FIFO interrupt. */
+		intsrc = PCI230P2_INT_DAC;
+	}
+	/* Disable interrupt and wait for interrupt routine to finish running
+	 * unless we are called from the interrupt routine. */
+	comedi_spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
+	devpriv->int_en &= ~intsrc;
+	while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
+		comedi_spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
+		comedi_spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
+	}
+	if (devpriv->ier != devpriv->int_en) {
+		devpriv->ier = devpriv->int_en;
+		outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
+	}
+	comedi_spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
+
+	if (devpriv->hwver >= 2) {
+		/* Using DAC FIFO.  Reset FIFO, clear underrun error,
+		 * disable FIFO. */
+		devpriv->daccon &= PCI230_DAC_OR_MASK;
+		outw(devpriv->daccon | PCI230P2_DAC_FIFO_RESET
+			| PCI230P2_DAC_FIFO_UNDERRUN_CLEAR,
+			dev->iobase + PCI230_DACCON);
+	}
+
+	/* Release resources. */
+	put_all_resources(dev, OWNER_AOCMD);
+}
+
+static int pci230_ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	pci230_ao_stop(dev, s);
+	return 0;
+}
+
+static void pci230_ai_stop(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	unsigned long irqflags;
+	struct comedi_cmd *cmd;
+	int started;
+
+	comedi_spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
+	started = test_and_clear_bit(AI_CMD_STARTED, &devpriv->state);
+	comedi_spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
+	if (!started) {
+		return;
+	}
+
+	cmd = &s->async->cmd;
+	if (cmd->convert_src == TRIG_TIMER) {
+		/* Stop conversion rate generator. */
+		pci230_cancel_ct(dev, 2);
+	}
+	if (cmd->scan_begin_src != TRIG_FOLLOW) {
+		/* Stop scan period monostable. */
+		pci230_cancel_ct(dev, 0);
+	}
+
+	comedi_spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
+	/* Disable ADC interrupt and wait for interrupt routine to finish
+	 * running unless we are called from the interrupt routine. */
+	devpriv->int_en &= ~PCI230_INT_ADC;
+	while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
+		comedi_spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
+		comedi_spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
+	}
+	if (devpriv->ier != devpriv->int_en) {
+		devpriv->ier = devpriv->int_en;
+		outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
+	}
+	comedi_spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
+
+	/* Reset FIFO, disable FIFO and set start conversion source to none.
+	 * Keep se/diff and bip/uni settings */
+	devpriv->adccon = (devpriv->adccon & (PCI230_ADC_IR_MASK
+			| PCI230_ADC_IM_MASK)) | PCI230_ADC_TRIG_NONE;
+	outw(devpriv->adccon | PCI230_ADC_FIFO_RESET,
+		dev->iobase + PCI230_ADCCON);
+
+	/* Release resources. */
+	put_all_resources(dev, OWNER_AICMD);
+}
+
+static int pci230_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	pci230_ai_stop(dev, s);
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/c6xdigio.c b/drivers/staging/comedi/drivers/c6xdigio.c
new file mode 100644
index 0000000..2efffb1
--- /dev/null
+++ b/drivers/staging/comedi/drivers/c6xdigio.c
@@ -0,0 +1,517 @@
+/*
+   comedi/drivers/c6xdigio.c
+
+   Hardware driver for Mechatronic Systems Inc. C6x_DIGIO DSP daughter card.
+   (http://robot0.ge.uiuc.edu/~spong/mecha/)
+
+   COMEDI - Linux Control and Measurement Device Interface
+   Copyright (C) 1999 Dan Block
+
+   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.
+
+ */
+/*
+Driver: c6xdigio
+Description: Mechatronic Systems Inc. C6x_DIGIO DSP daughter card
+Author: Dan Block
+Status: unknown
+Devices: [Mechatronic Systems Inc.] C6x_DIGIO DSP daughter card (c6xdigio)
+Updated: Sun Nov 20 20:18:34 EST 2005
+
+This driver will not work with a 2.4 kernel.
+http://robot0.ge.uiuc.edu/~spong/mecha/
+
+*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/timer.h>
+#include <asm/io.h>
+#include <linux/pnp.h>
+
+#include "../comedidev.h"
+
+static u8 ReadByteFromHwPort(unsigned long addr)
+{
+	u8 result = inb(addr);
+	return result;
+}
+
+static void WriteByteToHwPort(unsigned long addr, u8 val)
+{
+	outb_p(val, addr);
+}
+
+#define C6XDIGIO_SIZE 3
+
+/*
+ * port offsets
+ */
+#define C6XDIGIO_PARALLEL_DATA 0
+#define C6XDIGIO_PARALLEL_STATUS 1
+#define C6XDIGIO_PARALLEL_CONTROL 2
+struct pwmbitstype {
+	unsigned sb0:2;
+	unsigned sb1:2;
+	unsigned sb2:2;
+	unsigned sb3:2;
+	unsigned sb4:2;
+};
+union pwmcmdtype {
+	unsigned cmd;		// assuming here that int is 32bit
+	struct pwmbitstype bits;
+};
+struct encbitstype {
+	unsigned sb0:3;
+	unsigned sb1:3;
+	unsigned sb2:3;
+	unsigned sb3:3;
+	unsigned sb4:3;
+	unsigned sb5:3;
+	unsigned sb6:3;
+	unsigned sb7:3;
+};
+union encvaluetype {
+	unsigned value;
+	struct encbitstype bits;
+};
+
+#define C6XDIGIO_TIME_OUT 20
+
+static int c6xdigio_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int c6xdigio_detach(struct comedi_device * dev);
+struct comedi_driver driver_c6xdigio = {
+      driver_name:"c6xdigio",
+      module:THIS_MODULE,
+      attach:c6xdigio_attach,
+      detach:c6xdigio_detach,
+};
+
+static void C6X_pwmInit(unsigned long baseAddr)
+{
+	int timeout = 0;
+
+//printk("Inside C6X_pwmInit\n");
+
+	WriteByteToHwPort(baseAddr, 0x70);
+	while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0)
+		&& (timeout < C6XDIGIO_TIME_OUT)) {
+		timeout++;
+	}
+
+	WriteByteToHwPort(baseAddr, 0x74);
+	timeout = 0;
+	while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x80)
+		&& (timeout < C6XDIGIO_TIME_OUT)) {
+		timeout++;
+	}
+
+	WriteByteToHwPort(baseAddr, 0x70);
+	timeout = 0;
+	while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x0)
+		&& (timeout < C6XDIGIO_TIME_OUT)) {
+		timeout++;
+	}
+
+	WriteByteToHwPort(baseAddr, 0x0);
+	timeout = 0;
+	while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x80)
+		&& (timeout < C6XDIGIO_TIME_OUT)) {
+		timeout++;
+	}
+
+}
+
+static void C6X_pwmOutput(unsigned long baseAddr, unsigned channel, int value)
+{
+	unsigned ppcmd;
+	union pwmcmdtype pwm;
+	int timeout = 0;
+	unsigned tmp;
+
+	//printk("Inside C6X_pwmOutput\n");
+
+	pwm.cmd = value;
+	if (pwm.cmd > 498)
+		pwm.cmd = 498;
+	if (pwm.cmd < 2)
+		pwm.cmd = 2;
+
+	if (channel == 0) {
+		ppcmd = 0x28;
+	} else {		// if channel == 1
+		ppcmd = 0x30;
+	}			/* endif */
+
+	WriteByteToHwPort(baseAddr, ppcmd + pwm.bits.sb0);
+	tmp = ReadByteFromHwPort(baseAddr + 1);
+	while (((tmp & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) {
+		tmp = ReadByteFromHwPort(baseAddr + 1);
+		timeout++;
+	}
+
+	WriteByteToHwPort(baseAddr, ppcmd + pwm.bits.sb1 + 0x4);
+	timeout = 0;
+	tmp = ReadByteFromHwPort(baseAddr + 1);
+	while (((tmp & 0x80) == 0x80) && (timeout < C6XDIGIO_TIME_OUT)) {
+		tmp = ReadByteFromHwPort(baseAddr + 1);
+		timeout++;
+	}
+
+	WriteByteToHwPort(baseAddr, ppcmd + pwm.bits.sb2);
+	tmp = ReadByteFromHwPort(baseAddr + 1);
+	while (((tmp & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) {
+		tmp = ReadByteFromHwPort(baseAddr + 1);
+		timeout++;
+	}
+
+	WriteByteToHwPort(baseAddr, ppcmd + pwm.bits.sb3 + 0x4);
+	timeout = 0;
+	tmp = ReadByteFromHwPort(baseAddr + 1);
+	while (((tmp & 0x80) == 0x80) && (timeout < C6XDIGIO_TIME_OUT)) {
+		tmp = ReadByteFromHwPort(baseAddr + 1);
+		timeout++;
+	}
+
+	WriteByteToHwPort(baseAddr, ppcmd + pwm.bits.sb4);
+	tmp = ReadByteFromHwPort(baseAddr + 1);
+	while (((tmp & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) {
+		tmp = ReadByteFromHwPort(baseAddr + 1);
+		timeout++;
+	}
+
+	WriteByteToHwPort(baseAddr, 0x0);
+	timeout = 0;
+	tmp = ReadByteFromHwPort(baseAddr + 1);
+	while (((tmp & 0x80) == 0x80) && (timeout < C6XDIGIO_TIME_OUT)) {
+		tmp = ReadByteFromHwPort(baseAddr + 1);
+		timeout++;
+	}
+
+}
+
+static int C6X_encInput(unsigned long baseAddr, unsigned channel)
+{
+	unsigned ppcmd;
+	union encvaluetype enc;
+	int timeout = 0;
+	int tmp;
+
+	//printk("Inside C6X_encInput\n");
+
+	enc.value = 0;
+	if (channel == 0) {
+		ppcmd = 0x48;
+	} else {
+		ppcmd = 0x50;
+	}
+	WriteByteToHwPort(baseAddr, ppcmd);
+	tmp = ReadByteFromHwPort(baseAddr + 1);
+	while (((tmp & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) {
+		tmp = ReadByteFromHwPort(baseAddr + 1);
+		timeout++;
+	}
+
+	enc.bits.sb0 = ((ReadByteFromHwPort(baseAddr + 1) >> 3) & 0x7);
+	WriteByteToHwPort(baseAddr, ppcmd + 0x4);
+	timeout = 0;
+	tmp = ReadByteFromHwPort(baseAddr + 1);
+	while (((tmp & 0x80) == 0x80) && (timeout < C6XDIGIO_TIME_OUT)) {
+		tmp = ReadByteFromHwPort(baseAddr + 1);
+		timeout++;
+	}
+	enc.bits.sb1 = ((ReadByteFromHwPort(baseAddr + 1) >> 3) & 0x7);
+	WriteByteToHwPort(baseAddr, ppcmd);
+	timeout = 0;
+	tmp = ReadByteFromHwPort(baseAddr + 1);
+	while (((tmp & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) {
+		tmp = ReadByteFromHwPort(baseAddr + 1);
+		timeout++;
+	}
+	enc.bits.sb2 = ((ReadByteFromHwPort(baseAddr + 1) >> 3) & 0x7);
+	WriteByteToHwPort(baseAddr, ppcmd + 0x4);
+	timeout = 0;
+	tmp = ReadByteFromHwPort(baseAddr + 1);
+	while (((tmp & 0x80) == 0x80) && (timeout < C6XDIGIO_TIME_OUT)) {
+		tmp = ReadByteFromHwPort(baseAddr + 1);
+		timeout++;
+	}
+	enc.bits.sb3 = ((ReadByteFromHwPort(baseAddr + 1) >> 3) & 0x7);
+	WriteByteToHwPort(baseAddr, ppcmd);
+	timeout = 0;
+	tmp = ReadByteFromHwPort(baseAddr + 1);
+	while (((tmp & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) {
+		tmp = ReadByteFromHwPort(baseAddr + 1);
+		timeout++;
+	}
+	enc.bits.sb4 = ((ReadByteFromHwPort(baseAddr + 1) >> 3) & 0x7);
+	WriteByteToHwPort(baseAddr, ppcmd + 0x4);
+	timeout = 0;
+	tmp = ReadByteFromHwPort(baseAddr + 1);
+	while (((tmp & 0x80) == 0x80) && (timeout < C6XDIGIO_TIME_OUT)) {
+		tmp = ReadByteFromHwPort(baseAddr + 1);
+		timeout++;
+	}
+	enc.bits.sb5 = ((ReadByteFromHwPort(baseAddr + 1) >> 3) & 0x7);
+	WriteByteToHwPort(baseAddr, ppcmd);
+	timeout = 0;
+	tmp = ReadByteFromHwPort(baseAddr + 1);
+	while (((tmp & 0x80) == 0x0) && (timeout < C6XDIGIO_TIME_OUT)) {
+		tmp = ReadByteFromHwPort(baseAddr + 1);
+		timeout++;
+	}
+	enc.bits.sb6 = ((ReadByteFromHwPort(baseAddr + 1) >> 3) & 0x7);
+	WriteByteToHwPort(baseAddr, ppcmd + 0x4);
+	timeout = 0;
+	tmp = ReadByteFromHwPort(baseAddr + 1);
+	while (((tmp & 0x80) == 0x80) && (timeout < C6XDIGIO_TIME_OUT)) {
+		tmp = ReadByteFromHwPort(baseAddr + 1);
+		timeout++;
+	}
+	enc.bits.sb7 = ((ReadByteFromHwPort(baseAddr + 1) >> 3) & 0x7);
+	WriteByteToHwPort(baseAddr, ppcmd);
+	timeout = 0;
+	tmp = ReadByteFromHwPort(baseAddr + 1);
+	while (((tmp & 0x80) == 0x0) && (timeout < C6XDIGIO_TIME_OUT)) {
+		tmp = ReadByteFromHwPort(baseAddr + 1);
+		timeout++;
+	}
+
+	WriteByteToHwPort(baseAddr, 0x0);
+	timeout = 0;
+	tmp = ReadByteFromHwPort(baseAddr + 1);
+	while (((tmp & 0x80) == 0x80) && (timeout < C6XDIGIO_TIME_OUT)) {
+		tmp = ReadByteFromHwPort(baseAddr + 1);
+		timeout++;
+	}
+
+	return (enc.value ^ 0x800000);
+}
+
+static void C6X_encResetAll(unsigned long baseAddr)
+{
+	unsigned timeout = 0;
+
+//printk("Inside C6X_encResetAll\n");
+
+	WriteByteToHwPort(baseAddr, 0x68);
+	while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0)
+		&& (timeout < C6XDIGIO_TIME_OUT)) {
+		timeout++;
+	}
+	WriteByteToHwPort(baseAddr, 0x6C);
+	timeout = 0;
+	while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x80)
+		&& (timeout < C6XDIGIO_TIME_OUT)) {
+		timeout++;
+	}
+	WriteByteToHwPort(baseAddr, 0x68);
+	timeout = 0;
+	while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x0)
+		&& (timeout < C6XDIGIO_TIME_OUT)) {
+		timeout++;
+	}
+	WriteByteToHwPort(baseAddr, 0x0);
+	timeout = 0;
+	while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x80)
+		&& (timeout < C6XDIGIO_TIME_OUT)) {
+		timeout++;
+	}
+}
+
+static int c6xdigio_pwmo_insn_read(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	printk("c6xdigio_pwmo_insn_read %x\n", insn->n);
+	return insn->n;
+}
+
+static int c6xdigio_pwmo_insn_write(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+
+	//  printk("c6xdigio_pwmo_insn_write %x\n", insn->n);
+	for (i = 0; i < insn->n; i++) {
+		C6X_pwmOutput(dev->iobase, chan, data[i]);
+		/*    devpriv->ao_readback[chan] = data[i]; */
+	}
+	return i;
+}
+
+//static int c6xdigio_ei_init_insn_read(struct comedi_device *dev,
+//                                 struct comedi_subdevice *s,
+//                                 struct comedi_insn *insn,
+//                                 unsigned int *data)
+//{
+//  printk("c6xdigio_ei_init_insn_read %x\n", insn->n);
+//  return insn->n;
+//}
+
+//static int c6xdigio_ei_init_insn_write(struct comedi_device *dev,
+//                                 struct comedi_subdevice *s,
+//                                 struct comedi_insn *insn,
+//                                 unsigned int *data)
+//{
+//  int i;
+//  int chan = CR_CHAN(insn->chanspec);
+//
+//  C6X_encResetAll( dev->iobase );
+//
+//  return insn->n;
+//}
+
+static int c6xdigio_ei_insn_read(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	//  printk("c6xdigio_ei__insn_read %x\n", insn->n);
+	int n;
+	int chan = CR_CHAN(insn->chanspec);
+
+	for (n = 0; n < insn->n; n++) {
+		data[n] = (C6X_encInput(dev->iobase, chan) & 0xffffff);
+	}
+
+	return n;
+}
+
+static void board_init(struct comedi_device * dev)
+{
+
+	//printk("Inside board_init\n");
+
+	C6X_pwmInit(dev->iobase);
+	C6X_encResetAll(dev->iobase);
+
+}
+
+//static void board_halt(struct comedi_device *dev) {
+//  C6X_pwmInit(dev->iobase);
+//}
+
+/*
+   options[0] - I/O port
+   options[1] - irq
+   options[2] - number of encoder chips installed
+ */
+
+static const struct pnp_device_id c6xdigio_pnp_tbl[] = {
+	/* Standard LPT Printer Port */
+	{.id = "PNP0400",.driver_data = 0},
+	/* ECP Printer Port */
+	{.id = "PNP0401",.driver_data = 0},
+	{}
+};
+
+static struct pnp_driver c6xdigio_pnp_driver = {
+	.name = "c6xdigio",
+	.id_table = c6xdigio_pnp_tbl,
+};
+
+static int c6xdigio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	int result = 0;
+	unsigned long iobase;
+	unsigned int irq;
+	struct comedi_subdevice *s;
+
+	iobase = it->options[0];
+	printk("comedi%d: c6xdigio: 0x%04lx\n", dev->minor, iobase);
+	if (!request_region(iobase, C6XDIGIO_SIZE, "c6xdigio")) {
+		printk("comedi%d: I/O port conflict\n", dev->minor);
+		return -EIO;
+	}
+	dev->iobase = iobase;
+	dev->board_name = "c6xdigio";
+
+	result = alloc_subdevices(dev, 2);	// 3 with encoder_init write
+	if (result < 0)
+		return result;
+
+	// Make sure that PnP ports gets activated
+	pnp_register_driver(&c6xdigio_pnp_driver);
+
+	irq = it->options[1];
+	if (irq > 0) {
+		printk("comedi%d: irq = %u ignored\n", dev->minor, irq);
+	} else if (irq == 0) {
+		printk("comedi%d: no irq\n", dev->minor);
+	}
+
+	s = dev->subdevices + 0;
+	/* pwm output subdevice */
+	s->type = COMEDI_SUBD_AO;	// Not sure what to put here
+	s->subdev_flags = SDF_WRITEABLE;
+	s->n_chan = 2;
+	/*      s->trig[0] = c6xdigio_pwmo; */
+	s->insn_read = c6xdigio_pwmo_insn_read;
+	s->insn_write = c6xdigio_pwmo_insn_write;
+	s->maxdata = 500;
+	s->range_table = &range_bipolar10;	// A suitable lie
+
+	s = dev->subdevices + 1;
+	/* encoder (counter) subdevice */
+	s->type = COMEDI_SUBD_COUNTER;
+	s->subdev_flags = SDF_READABLE | SDF_LSAMPL;
+	s->n_chan = 2;
+	/* s->trig[0] = c6xdigio_ei; */
+	s->insn_read = c6xdigio_ei_insn_read;
+	s->maxdata = 0xffffff;
+	s->range_table = &range_unknown;
+
+	//          s = dev->subdevices + 2;
+	//      /* pwm output subdevice */
+	//      s->type = COMEDI_SUBD_COUNTER;  // Not sure what to put here
+	//      s->subdev_flags = SDF_WRITEABLE;
+	//      s->n_chan = 1;
+	//      /* s->trig[0] = c6xdigio_ei_init; */
+	//      s->insn_read = c6xdigio_ei_init_insn_read;
+	//      s->insn_write = c6xdigio_ei_init_insn_write;
+	//      s->maxdata = 0xFFFF;  // Really just a don't care
+	//      s->range_table = &range_unknown; // Not sure what to put here
+
+	// I will call this init anyway but more than likely the DSP board will not be connect
+	// when device driver is loaded.
+	board_init(dev);
+
+	return 0;
+}
+
+static int c6xdigio_detach(struct comedi_device * dev)
+{
+//  board_halt(dev);  // may not need this
+
+	printk("comedi%d: c6xdigio: remove\n", dev->minor);
+
+	if (dev->iobase) {
+		release_region(dev->iobase, C6XDIGIO_SIZE);
+	}
+	if (dev->irq) {
+		free_irq(dev->irq, dev);
+	}			// Not using IRQ so I am not sure if I need this
+	pnp_unregister_driver(&c6xdigio_pnp_driver);
+
+	return 0;
+}
+
+COMEDI_INITCLEANUP(driver_c6xdigio);
diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c
new file mode 100644
index 0000000..0bfe4c9
--- /dev/null
+++ b/drivers/staging/comedi/drivers/cb_das16_cs.c
@@ -0,0 +1,976 @@
+/*
+    comedi/drivers/das16cs.c
+    Driver for Computer Boards PC-CARD DAS16/16.
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000, 2001, 2002 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: cb_das16_cs
+Description: Computer Boards PC-CARD DAS16/16
+Devices: [ComputerBoards] PC-CARD DAS16/16 (cb_das16_cs), PC-CARD DAS16/16-AO
+Author: ds
+Updated: Mon, 04 Nov 2002 20:04:21 -0800
+Status: experimental
+
+
+*/
+
+#include "../comedidev.h"
+#include <linux/delay.h>
+#include <linux/pci.h>
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+
+#include "8253.h"
+
+#define DAS16CS_SIZE			18
+
+#define DAS16CS_ADC_DATA		0
+#define DAS16CS_DIO_MUX			2
+#define DAS16CS_MISC1			4
+#define DAS16CS_MISC2			6
+#define DAS16CS_CTR0			8
+#define DAS16CS_CTR1			10
+#define DAS16CS_CTR2			12
+#define DAS16CS_CTR_CONTROL		14
+#define DAS16CS_DIO			16
+
+struct das16cs_board {
+	const char *name;
+	int device_id;
+	int n_ao_chans;
+};
+static const struct das16cs_board das16cs_boards[] = {
+	{
+	      device_id:0x0000,/* unknown */
+	      name:	"PC-CARD DAS16/16",
+	      n_ao_chans:0,
+		},
+	{
+	      device_id:0x0039,
+	      name:	"PC-CARD DAS16/16-AO",
+	      n_ao_chans:2,
+		},
+	{
+	      device_id:0x4009,
+	      name:	"PCM-DAS16s/16",
+	      n_ao_chans:0,
+		},
+};
+
+#define n_boards (sizeof(das16cs_boards)/sizeof(das16cs_boards[0]))
+#define thisboard ((const struct das16cs_board *)dev->board_ptr)
+
+struct das16cs_private {
+	struct pcmcia_device *link;
+
+	unsigned int ao_readback[2];
+	unsigned short status1;
+	unsigned short status2;
+};
+#define devpriv ((struct das16cs_private *)dev->private)
+
+static int das16cs_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int das16cs_detach(struct comedi_device * dev);
+static struct comedi_driver driver_das16cs = {
+      driver_name:"cb_das16_cs",
+      module:THIS_MODULE,
+      attach:das16cs_attach,
+      detach:das16cs_detach,
+};
+
+static struct pcmcia_device *cur_dev = NULL;
+
+static const struct comedi_lrange das16cs_ai_range = { 4, {
+			RANGE(-10, 10),
+			RANGE(-5, 5),
+			RANGE(-2.5, 2.5),
+			RANGE(-1.25, 1.25),
+	}
+};
+
+static irqreturn_t das16cs_interrupt(int irq, void *d PT_REGS_ARG);
+static int das16cs_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int das16cs_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int das16cs_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd);
+static int das16cs_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int das16cs_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int das16cs_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int das16cs_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int das16cs_timer_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int das16cs_timer_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+static int get_prodid(struct comedi_device * dev, struct pcmcia_device *link)
+{
+	tuple_t tuple;
+	u_short buf[128];
+	int prodid = 0;
+
+	tuple.TupleData = (cisdata_t *) buf;
+	tuple.TupleOffset = 0;
+	tuple.TupleDataMax = 255;
+	tuple.DesiredTuple = CISTPL_MANFID;
+	tuple.Attributes = TUPLE_RETURN_COMMON;
+	if ((pcmcia_get_first_tuple(link, &tuple) == 0) &&
+		(pcmcia_get_tuple_data(link, &tuple) == 0)) {
+		prodid = le16_to_cpu(buf[1]);
+	}
+
+	return prodid;
+}
+
+static const struct das16cs_board *das16cs_probe(struct comedi_device * dev,
+	struct pcmcia_device *link)
+{
+	int id;
+	int i;
+
+	id = get_prodid(dev, link);
+
+	for (i = 0; i < n_boards; i++) {
+		if (das16cs_boards[i].device_id == id) {
+			return das16cs_boards + i;
+		}
+	}
+
+	printk("unknown board!\n");
+
+	return NULL;
+}
+
+static int das16cs_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct pcmcia_device *link;
+	struct comedi_subdevice *s;
+	int ret;
+	int i;
+
+	printk("comedi%d: cb_das16_cs: ", dev->minor);
+
+	link = cur_dev;		/* XXX hack */
+	if (!link)
+		return -EIO;
+
+	dev->iobase = link->io.BasePort1;
+	printk("I/O base=0x%04lx ", dev->iobase);
+
+	printk("fingerprint:\n");
+	for (i = 0; i < 48; i += 2) {
+		printk("%04x ", inw(dev->iobase + i));
+	}
+	printk("\n");
+
+	ret = comedi_request_irq(link->irq.AssignedIRQ, das16cs_interrupt,
+		IRQF_SHARED, "cb_das16_cs", dev);
+	if (ret < 0) {
+		return ret;
+	}
+	dev->irq = link->irq.AssignedIRQ;
+	printk("irq=%u ", dev->irq);
+
+	dev->board_ptr = das16cs_probe(dev, link);
+	if (!dev->board_ptr)
+		return -EIO;
+
+	dev->board_name = thisboard->name;
+
+	if (alloc_private(dev, sizeof(struct das16cs_private)) < 0)
+		return -ENOMEM;
+
+	if (alloc_subdevices(dev, 4) < 0)
+		return -ENOMEM;
+
+	s = dev->subdevices + 0;
+	dev->read_subdev = s;
+	/* analog input subdevice */
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
+	s->n_chan = 16;
+	s->maxdata = 0xffff;
+	s->range_table = &das16cs_ai_range;
+	s->len_chanlist = 16;
+	s->insn_read = das16cs_ai_rinsn;
+	s->do_cmd = das16cs_ai_cmd;
+	s->do_cmdtest = das16cs_ai_cmdtest;
+
+	s = dev->subdevices + 1;
+	/* analog output subdevice */
+	if (thisboard->n_ao_chans) {
+		s->type = COMEDI_SUBD_AO;
+		s->subdev_flags = SDF_WRITABLE;
+		s->n_chan = thisboard->n_ao_chans;
+		s->maxdata = 0xffff;
+		s->range_table = &range_bipolar10;
+		s->insn_write = &das16cs_ao_winsn;
+		s->insn_read = &das16cs_ao_rinsn;
+	}
+
+	s = dev->subdevices + 2;
+	/* digital i/o subdevice */
+	if (1) {
+		s->type = COMEDI_SUBD_DIO;
+		s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+		s->n_chan = 8;
+		s->maxdata = 1;
+		s->range_table = &range_digital;
+		s->insn_bits = das16cs_dio_insn_bits;
+		s->insn_config = das16cs_dio_insn_config;
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	s = dev->subdevices + 3;
+	/* timer subdevice */
+	if (0) {
+		s->type = COMEDI_SUBD_TIMER;
+		s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+		s->n_chan = 1;
+		s->maxdata = 0xff;
+		s->range_table = &range_unknown;
+		s->insn_read = das16cs_timer_insn_read;
+		s->insn_config = das16cs_timer_insn_config;
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	printk("attached\n");
+
+	return 1;
+}
+
+static int das16cs_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: das16cs: remove\n", dev->minor);
+
+	if (dev->irq) {
+		comedi_free_irq(dev->irq, dev);
+	}
+
+	return 0;
+}
+
+static irqreturn_t das16cs_interrupt(int irq, void *d PT_REGS_ARG)
+{
+	//struct comedi_device *dev = d;
+	return IRQ_HANDLED;
+}
+
+/*
+ * "instructions" read/write data in "one-shot" or "software-triggered"
+ * mode.
+ */
+static int das16cs_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int to;
+	int aref;
+	int range;
+	int chan;
+	static int range_bits[] = { 0x800, 0x000, 0x100, 0x200 };
+
+	chan = CR_CHAN(insn->chanspec);
+	aref = CR_AREF(insn->chanspec);
+	range = CR_RANGE(insn->chanspec);
+
+	outw(chan, dev->iobase + 2);
+
+	devpriv->status1 &= ~0xf320;
+	devpriv->status1 |= (aref == AREF_DIFF) ? 0 : 0x0020;
+	outw(devpriv->status1, dev->iobase + 4);
+
+	devpriv->status2 &= ~0xff00;
+	devpriv->status2 |= range_bits[range];
+	outw(devpriv->status2, dev->iobase + 6);
+
+	for (i = 0; i < insn->n; i++) {
+		outw(0, dev->iobase);
+
+#define TIMEOUT 1000
+		for (to = 0; to < TIMEOUT; to++) {
+			if (inw(dev->iobase + 4) & 0x0080)
+				break;
+		}
+		if (to == TIMEOUT) {
+			printk("cb_das16_cs: ai timeout\n");
+			return -ETIME;
+		}
+		data[i] = (unsigned short)inw(dev->iobase + 0);
+	}
+
+	return i;
+}
+
+static int das16cs_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	return -EINVAL;
+}
+
+static int das16cs_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp;
+
+	/* cmdtest tests a particular command to see if it is valid.
+	 * Using the cmdtest ioctl, a user can create a valid cmd
+	 * and then have it executes by the cmd ioctl.
+	 *
+	 * cmdtest returns 1,2,3,4 or 0, depending on which tests
+	 * the command passes. */
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	/* note that mutual compatiblity is not an issue here */
+	if (cmd->scan_begin_src != TRIG_TIMER &&
+		cmd->scan_begin_src != TRIG_EXT)
+		err++;
+	if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+		err++;
+	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+#define MAX_SPEED	10000	/* in nanoseconds */
+#define MIN_SPEED	1000000000	/* in nanoseconds */
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		if (cmd->scan_begin_arg < MAX_SPEED) {
+			cmd->scan_begin_arg = MAX_SPEED;
+			err++;
+		}
+		if (cmd->scan_begin_arg > MIN_SPEED) {
+			cmd->scan_begin_arg = MIN_SPEED;
+			err++;
+		}
+	} else {
+		/* external trigger */
+		/* should be level/edge, hi/lo specification here */
+		/* should specify multiple external triggers */
+		if (cmd->scan_begin_arg > 9) {
+			cmd->scan_begin_arg = 9;
+			err++;
+		}
+	}
+	if (cmd->convert_src == TRIG_TIMER) {
+		if (cmd->convert_arg < MAX_SPEED) {
+			cmd->convert_arg = MAX_SPEED;
+			err++;
+		}
+		if (cmd->convert_arg > MIN_SPEED) {
+			cmd->convert_arg = MIN_SPEED;
+			err++;
+		}
+	} else {
+		/* external trigger */
+		/* see above */
+		if (cmd->convert_arg > 9) {
+			cmd->convert_arg = 9;
+			err++;
+		}
+	}
+
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+	if (cmd->stop_src == TRIG_COUNT) {
+		if (cmd->stop_arg > 0x00ffffff) {
+			cmd->stop_arg = 0x00ffffff;
+			err++;
+		}
+	} else {
+		/* TRIG_NONE */
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		unsigned int div1, div2;
+
+		tmp = cmd->scan_begin_arg;
+		i8253_cascade_ns_to_timer(100, &div1, &div2,
+			&cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK);
+		if (tmp != cmd->scan_begin_arg)
+			err++;
+	}
+	if (cmd->convert_src == TRIG_TIMER) {
+		unsigned int div1, div2;
+
+		tmp = cmd->convert_arg;
+		i8253_cascade_ns_to_timer(100, &div1, &div2,
+			&cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK);
+		if (tmp != cmd->convert_arg)
+			err++;
+		if (cmd->scan_begin_src == TRIG_TIMER &&
+			cmd->scan_begin_arg <
+			cmd->convert_arg * cmd->scan_end_arg) {
+			cmd->scan_begin_arg =
+				cmd->convert_arg * cmd->scan_end_arg;
+			err++;
+		}
+	}
+
+	if (err)
+		return 4;
+
+	return 0;
+}
+
+static int das16cs_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+	unsigned short status1;
+	unsigned short d;
+	int bit;
+
+	for (i = 0; i < insn->n; i++) {
+		devpriv->ao_readback[chan] = data[i];
+		d = data[i];
+
+		outw(devpriv->status1, dev->iobase + 4);
+		comedi_udelay(1);
+
+		status1 = devpriv->status1 & ~0xf;
+		if (chan)
+			status1 |= 0x0001;
+		else
+			status1 |= 0x0008;
+
+/* 		printk("0x%04x\n",status1);*/
+		outw(status1, dev->iobase + 4);
+		comedi_udelay(1);
+
+		for (bit = 15; bit >= 0; bit--) {
+			int b = (d >> bit) & 0x1;
+			b <<= 1;
+/*			printk("0x%04x\n",status1 | b | 0x0000);*/
+			outw(status1 | b | 0x0000, dev->iobase + 4);
+			comedi_udelay(1);
+/*			printk("0x%04x\n",status1 | b | 0x0004);*/
+			outw(status1 | b | 0x0004, dev->iobase + 4);
+			comedi_udelay(1);
+		}
+/*		make high both DAC0CS and DAC1CS to load
+		new data and update analog output*/
+		outw(status1 | 0x9, dev->iobase + 4);
+	}
+
+	return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+ * Usually this means copying a value stored in devpriv. */
+static int das16cs_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+
+	for (i = 0; i < insn->n; i++)
+		data[i] = devpriv->ao_readback[chan];
+
+	return i;
+}
+
+/* DIO devices are slightly special.  Although it is possible to
+ * implement the insn_read/insn_write interface, it is much more
+ * useful to applications if you implement the insn_bits interface.
+ * This allows packed reading/writing of the DIO channels.  The
+ * comedi core can convert between insn_bits and insn_read/write */
+static int das16cs_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= data[0] & data[1];
+
+		outw(s->state, dev->iobase + 16);
+	}
+
+	/* on return, data[1] contains the value of the digital
+	 * input and output lines. */
+	data[1] = inw(dev->iobase + 16);
+
+	return 2;
+}
+
+static int das16cs_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int chan = CR_CHAN(insn->chanspec);
+	int bits;
+
+	if (chan < 4)
+		bits = 0x0f;
+	else
+		bits = 0xf0;
+
+	switch (data[0]) {
+	case INSN_CONFIG_DIO_OUTPUT:
+		s->io_bits |= bits;
+		break;
+	case INSN_CONFIG_DIO_INPUT:
+		s->io_bits &= bits;
+		break;
+	case INSN_CONFIG_DIO_QUERY:
+		data[1] =
+			(s->
+			io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+		return insn->n;
+		break;
+	default:
+		return -EINVAL;
+		break;
+	}
+
+	devpriv->status2 &= ~0x00c0;
+	devpriv->status2 |= (s->io_bits & 0xf0) ? 0x0080 : 0;
+	devpriv->status2 |= (s->io_bits & 0x0f) ? 0x0040 : 0;
+
+	outw(devpriv->status2, dev->iobase + 6);
+
+	return insn->n;
+}
+
+static int das16cs_timer_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	return -EINVAL;
+}
+
+static int das16cs_timer_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	return -EINVAL;
+}
+
+/* PCMCIA stuff */
+
+/*======================================================================
+
+    The following pcmcia code for the pcm-das08 is adapted from the
+    dummy_cs.c driver of the Linux PCMCIA Card Services package.
+
+    The initial developer of the original code is David A. Hinds
+    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
+    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
+
+======================================================================*/
+
+/*
+   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
+   you do not define PCMCIA_DEBUG at all, all the debug code will be
+   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
+   be present but disabled -- but it can then be enabled for specific
+   modules at load time with a 'pc_debug=#' option to insmod.
+*/
+#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
+
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+module_param(pc_debug, int, 0644);
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+static char *version =
+	"cb_das16_cs.c pcmcia code (David Schleef), modified from dummy_cs.c 1.31 2001/08/24 12:13:13 (David Hinds)";
+#else
+#define DEBUG(n, args...)
+#endif
+
+/*====================================================================*/
+
+static void das16cs_pcmcia_config(struct pcmcia_device *link);
+static void das16cs_pcmcia_release(struct pcmcia_device *link);
+static int das16cs_pcmcia_suspend(struct pcmcia_device *p_dev);
+static int das16cs_pcmcia_resume(struct pcmcia_device *p_dev);
+
+/*
+   The attach() and detach() entry points are used to create and destroy
+   "instances" of the driver, where each instance represents everything
+   needed to manage one actual PCMCIA card.
+*/
+
+static int das16cs_pcmcia_attach(struct pcmcia_device *);
+static void das16cs_pcmcia_detach(struct pcmcia_device *);
+
+/*
+   You'll also need to prototype all the functions that will actually
+   be used to talk to your device.  See 'memory_cs' for a good example
+   of a fully self-sufficient driver; the other drivers rely more or
+   less on other parts of the kernel.
+*/
+
+/*
+   The dev_info variable is the "key" that is used to match up this
+   device driver with appropriate cards, through the card configuration
+   database.
+*/
+
+static dev_info_t dev_info = "cb_das16_cs";
+
+struct local_info_t {
+	struct pcmcia_device *link;
+	dev_node_t node;
+	int stop;
+	struct bus_operations *bus;
+};
+
+/*======================================================================
+
+    das16cs_pcmcia_attach() creates an "instance" of the driver, allocating
+    local data structures for one device.  The device is registered
+    with Card Services.
+
+    The dev_link structure is initialized, but we don't actually
+    configure the card at this point -- we wait until we receive a
+    card insertion event.
+
+======================================================================*/
+
+static int das16cs_pcmcia_attach(struct pcmcia_device *link)
+{
+	struct local_info_t *local;
+
+	DEBUG(0, "das16cs_pcmcia_attach()\n");
+
+	/* Allocate space for private device-specific data */
+	local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
+	if (!local)
+		return -ENOMEM;
+	local->link = link;
+	link->priv = local;
+
+	/* Initialize the pcmcia_device structure */
+	/* Interrupt setup */
+	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+	link->irq.Handler = NULL;
+
+	link->conf.Attributes = 0;
+	link->conf.IntType = INT_MEMORY_AND_IO;
+
+	cur_dev = link;
+
+	das16cs_pcmcia_config(link);
+
+	return 0;
+}				/* das16cs_pcmcia_attach */
+
+static void das16cs_pcmcia_detach(struct pcmcia_device *link)
+{
+	DEBUG(0, "das16cs_pcmcia_detach(0x%p)\n", link);
+
+	if (link->dev_node) {
+		((struct local_info_t *) link->priv)->stop = 1;
+		das16cs_pcmcia_release(link);
+	}
+	/* This points to the parent struct local_info_t struct */
+	if (link->priv)
+		kfree(link->priv);
+}				/* das16cs_pcmcia_detach */
+
+static void das16cs_pcmcia_config(struct pcmcia_device *link)
+{
+	struct local_info_t *dev = link->priv;
+	tuple_t tuple;
+	cisparse_t parse;
+	int last_fn, last_ret;
+	u_char buf[64];
+	cistpl_cftable_entry_t dflt = { 0 };
+
+	DEBUG(0, "das16cs_pcmcia_config(0x%p)\n", link);
+
+	/*
+	   This reads the card's CONFIG tuple to find its configuration
+	   registers.
+	 */
+	tuple.DesiredTuple = CISTPL_CONFIG;
+	tuple.Attributes = 0;
+	tuple.TupleData = buf;
+	tuple.TupleDataMax = sizeof(buf);
+	tuple.TupleOffset = 0;
+	last_fn = GetFirstTuple;
+	if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0)
+		goto cs_failed;
+	last_fn = GetTupleData;
+	if ((last_ret = pcmcia_get_tuple_data(link, &tuple)) != 0)
+		goto cs_failed;
+	last_fn = ParseTuple;
+	if ((last_ret = pcmcia_parse_tuple(link, &tuple, &parse)) != 0)
+		goto cs_failed;
+	link->conf.ConfigBase = parse.config.base;
+	link->conf.Present = parse.config.rmask[0];
+
+	/*
+	   In this loop, we scan the CIS for configuration table entries,
+	   each of which describes a valid card configuration, including
+	   voltage, IO window, memory window, and interrupt settings.
+
+	   We make no assumptions about the card to be configured: we use
+	   just the information available in the CIS.  In an ideal world,
+	   this would work for any PCMCIA card, but it requires a complete
+	   and accurate CIS.  In practice, a driver usually "knows" most of
+	   these things without consulting the CIS, and most client drivers
+	   will only use the CIS to fill in implementation-defined details.
+	 */
+	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+	last_fn = GetFirstTuple;
+	if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0)
+		goto cs_failed;
+	while (1) {
+		cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+		if (pcmcia_get_tuple_data(link, &tuple))
+			goto next_entry;
+		if (pcmcia_parse_tuple(link, &tuple, &parse))
+			goto next_entry;
+
+		if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+			dflt = *cfg;
+		if (cfg->index == 0)
+			goto next_entry;
+		link->conf.ConfigIndex = cfg->index;
+
+		/* Does this card need audio output? */
+/*	if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+		link->conf.Attributes |= CONF_ENABLE_SPKR;
+		link->conf.Status = CCSR_AUDIO_ENA;
+	}
+*/
+		/* Do we need to allocate an interrupt? */
+		if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
+			link->conf.Attributes |= CONF_ENABLE_IRQ;
+
+		/* IO window settings */
+		link->io.NumPorts1 = link->io.NumPorts2 = 0;
+		if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+			cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+			link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+			if (!(io->flags & CISTPL_IO_8BIT))
+				link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+			if (!(io->flags & CISTPL_IO_16BIT))
+				link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+			link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+			link->io.BasePort1 = io->win[0].base;
+			link->io.NumPorts1 = io->win[0].len;
+			if (io->nwin > 1) {
+				link->io.Attributes2 = link->io.Attributes1;
+				link->io.BasePort2 = io->win[1].base;
+				link->io.NumPorts2 = io->win[1].len;
+			}
+			/* This reserves IO space but doesn't actually enable it */
+			if (pcmcia_request_io(link, &link->io))
+				goto next_entry;
+		}
+
+		/* If we got this far, we're cool! */
+		break;
+
+	      next_entry:
+		last_fn = GetNextTuple;
+		if ((last_ret = pcmcia_get_next_tuple(link, &tuple)) != 0)
+			goto cs_failed;
+	}
+
+	/*
+	   Allocate an interrupt line.  Note that this does not assign a
+	   handler to the interrupt, unless the 'Handler' member of the
+	   irq structure is initialized.
+	 */
+	if (link->conf.Attributes & CONF_ENABLE_IRQ) {
+		last_fn = RequestIRQ;
+		if ((last_ret = pcmcia_request_irq(link, &link->irq)) != 0)
+			goto cs_failed;
+	}
+	/*
+	   This actually configures the PCMCIA socket -- setting up
+	   the I/O windows and the interrupt mapping, and putting the
+	   card and host interface into "Memory and IO" mode.
+	 */
+	last_fn = RequestConfiguration;
+	if ((last_ret = pcmcia_request_configuration(link, &link->conf)) != 0)
+		goto cs_failed;
+
+	/*
+	   At this point, the dev_node_t structure(s) need to be
+	   initialized and arranged in a linked list at link->dev.
+	 */
+	sprintf(dev->node.dev_name, "cb_das16_cs");
+	dev->node.major = dev->node.minor = 0;
+	link->dev_node = &dev->node;
+
+	/* Finally, report what we've done */
+	printk(KERN_INFO "%s: index 0x%02x",
+		dev->node.dev_name, link->conf.ConfigIndex);
+	if (link->conf.Attributes & CONF_ENABLE_IRQ)
+		printk(", irq %u", link->irq.AssignedIRQ);
+	if (link->io.NumPorts1)
+		printk(", io 0x%04x-0x%04x", link->io.BasePort1,
+			link->io.BasePort1 + link->io.NumPorts1 - 1);
+	if (link->io.NumPorts2)
+		printk(" & 0x%04x-0x%04x", link->io.BasePort2,
+			link->io.BasePort2 + link->io.NumPorts2 - 1);
+	printk("\n");
+
+	return;
+
+      cs_failed:
+	cs_error(link, last_fn, last_ret);
+	das16cs_pcmcia_release(link);
+}				/* das16cs_pcmcia_config */
+
+static void das16cs_pcmcia_release(struct pcmcia_device *link)
+{
+	DEBUG(0, "das16cs_pcmcia_release(0x%p)\n", link);
+	pcmcia_disable_device(link);
+}				/* das16cs_pcmcia_release */
+
+static int das16cs_pcmcia_suspend(struct pcmcia_device *link)
+{
+	struct local_info_t *local = link->priv;
+
+	/* Mark the device as stopped, to block IO until later */
+	local->stop = 1;
+
+	return 0;
+}				/* das16cs_pcmcia_suspend */
+
+static int das16cs_pcmcia_resume(struct pcmcia_device *link)
+{
+	struct local_info_t *local = link->priv;
+
+	local->stop = 0;
+	return 0;
+}				/* das16cs_pcmcia_resume */
+
+/*====================================================================*/
+
+static struct pcmcia_device_id das16cs_id_table[] = {
+	PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x0039),
+	PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x4009),
+	PCMCIA_DEVICE_NULL
+};
+
+MODULE_DEVICE_TABLE(pcmcia, das16cs_id_table);
+
+struct pcmcia_driver das16cs_driver = {
+	.probe = das16cs_pcmcia_attach,
+	.remove = das16cs_pcmcia_detach,
+	.suspend = das16cs_pcmcia_suspend,
+	.resume = das16cs_pcmcia_resume,
+	.id_table = das16cs_id_table,
+	.owner = THIS_MODULE,
+	.drv = {
+			.name = dev_info,
+		},
+};
+
+static int __init init_das16cs_pcmcia_cs(void)
+{
+	DEBUG(0, "%s\n", version);
+	pcmcia_register_driver(&das16cs_driver);
+	return 0;
+}
+
+static void __exit exit_das16cs_pcmcia_cs(void)
+{
+	DEBUG(0, "das16cs_pcmcia_cs: unloading\n");
+	pcmcia_unregister_driver(&das16cs_driver);
+}
+
+int __init init_module(void)
+{
+	int ret;
+
+	ret = init_das16cs_pcmcia_cs();
+	if (ret < 0)
+		return ret;
+
+	return comedi_driver_register(&driver_das16cs);
+}
+
+void __exit cleanup_module(void)
+{
+	exit_das16cs_pcmcia_cs();
+	comedi_driver_unregister(&driver_das16cs);
+}
+
+#else
+COMEDI_INITCLEANUP(driver_das16cs);
+#endif //CONFIG_PCMCIA
diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c
new file mode 100644
index 0000000..fcc5516
--- /dev/null
+++ b/drivers/staging/comedi/drivers/cb_pcidas.c
@@ -0,0 +1,1831 @@
+/*
+    comedi/drivers/cb_pcidas.c
+
+    Developed by Ivan Martinez and Frank Mori Hess, with valuable help from
+    David Schleef and the rest of the Comedi developers comunity.
+
+    Copyright (C) 2001-2003 Ivan Martinez <imr@oersted.dtu.dk>
+    Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 1997-8 David A. Schleef <ds@schleef.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.
+
+    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.
+
+************************************************************************
+*/
+/*
+Driver: cb_pcidas
+Description: MeasurementComputing PCI-DAS series with the AMCC S5933 PCI controller
+Author: Ivan Martinez <imr@oersted.dtu.dk>,
+  Frank Mori Hess <fmhess@users.sourceforge.net>
+Updated: 2003-3-11
+Devices: [Measurement Computing] PCI-DAS1602/16 (cb_pcidas),
+  PCI-DAS1602/16jr, PCI-DAS1602/12, PCI-DAS1200, PCI-DAS1200jr,
+  PCI-DAS1000, PCI-DAS1001, PCI_DAS1002
+
+Status:
+  There are many reports of the driver being used with most of the
+  supported cards. Despite no detailed log is maintained, it can
+  be said that the driver is quite tested and stable.
+
+  The boards may be autocalibrated using the comedi_calibrate
+  utility.
+
+Configuration options:
+  [0] - PCI bus of device (optional)
+  [1] - PCI slot of device (optional)
+  If bus/slot is not specified, the first supported
+  PCI device found will be used.
+
+For commands, the scanned channels must be consecutive
+(i.e. 4-5-6-7, 2-3-4,...), and must all have the same
+range and aref.
+*/
+/*
+
+TODO:
+
+analog triggering on 1602 series
+*/
+
+#include "../comedidev.h"
+#include <linux/delay.h>
+
+#include "8253.h"
+#include "8255.h"
+#include "amcc_s5933.h"
+#include "comedi_pci.h"
+#include "comedi_fc.h"
+
+#undef CB_PCIDAS_DEBUG		// disable debugging code
+//#define CB_PCIDAS_DEBUG       // enable debugging code
+
+// PCI vendor number of ComputerBoards/MeasurementComputing
+#define PCI_VENDOR_ID_CB	0x1307
+#define TIMER_BASE 100		// 10MHz master clock
+#define AI_BUFFER_SIZE 1024	// maximum fifo size of any supported board
+#define AO_BUFFER_SIZE 1024	// maximum fifo size of any supported board
+#define NUM_CHANNELS_8800 8
+#define NUM_CHANNELS_7376 1
+#define NUM_CHANNELS_8402 2
+#define NUM_CHANNELS_DAC08 1
+
+/* PCI-DAS base addresses */
+
+// indices of base address regions
+#define S5933_BADRINDEX 0
+#define CONT_STAT_BADRINDEX 1
+#define ADC_FIFO_BADRINDEX 2
+#define PACER_BADRINDEX 3
+#define AO_BADRINDEX 4
+// sizes of io regions
+#define CONT_STAT_SIZE 10
+#define ADC_FIFO_SIZE 4
+#define PACER_SIZE 12
+#define AO_SIZE 4
+
+/* Control/Status registers */
+#define INT_ADCFIFO	0	// INTERRUPT / ADC FIFO register
+#define   INT_EOS 0x1		// interrupt end of scan
+#define   INT_FHF 0x2		// interrupt fifo half full
+#define   INT_FNE 0x3		// interrupt fifo not empty
+#define   INT_MASK 0x3		// mask of interrupt select bits
+#define   INTE 0x4		// interrupt enable
+#define   DAHFIE 0x8		// dac half full interrupt enable
+#define   EOAIE	0x10		// end of aquisition interrupt enable
+#define   DAHFI	0x20		// dac half full read status / write interrupt clear
+#define   EOAI 0x40		// read end of acq. interrupt status / write clear
+#define   INT 0x80		// read interrupt status / write clear
+#define   EOBI 0x200		// read end of burst interrupt status
+#define   ADHFI 0x400		// read half-full interrupt status
+#define   ADNEI 0x800		// read fifo not empty interrupt latch status
+#define   ADNE 0x1000		// read, fifo not empty (realtime, not latched) status
+#define   DAEMIE	0x1000	// write, dac empty interrupt enable
+#define   LADFUL 0x2000		// read fifo overflow / write clear
+#define   DAEMI 0x4000		// dac fifo empty interrupt status / write clear
+
+#define ADCMUX_CONT	2	// ADC CHANNEL MUX AND CONTROL register
+#define   BEGIN_SCAN(x)	((x) & 0xf)
+#define   END_SCAN(x)	(((x) & 0xf) << 4)
+#define   GAIN_BITS(x)	(((x) & 0x3) << 8)
+#define   UNIP	0x800		// Analog front-end unipolar for range
+#define   SE	0x400		// Inputs in single-ended mode
+#define   PACER_MASK	0x3000	// pacer source bits
+#define   PACER_INT 0x1000	// internal pacer
+#define   PACER_EXT_FALL	0x2000	// external falling edge
+#define   PACER_EXT_RISE	0x3000	// external rising edge
+#define   EOC	0x4000		// adc not busy
+
+#define TRIG_CONTSTAT 4		// TRIGGER CONTROL/STATUS register
+#define   SW_TRIGGER 0x1	// software start trigger
+#define   EXT_TRIGGER 0x2	// external start trigger
+#define   ANALOG_TRIGGER 0x3	// external analog trigger
+#define   TRIGGER_MASK	0x3	// mask of bits that determine start trigger
+#define   TGEN	0x10		// enable external start trigger
+#define   BURSTE 0x20		// burst mode enable
+#define   XTRCL	0x80		// clear external trigger
+
+#define CALIBRATION_REG	6	// CALIBRATION register
+#define   SELECT_8800_BIT	0x100	// select 8800 caldac
+#define   SELECT_TRIMPOT_BIT	0x200	// select ad7376 trim pot
+#define   SELECT_DAC08_BIT	0x400	// select dac08 caldac
+#define   CAL_SRC_BITS(x)	(((x) & 0x7) << 11)
+#define   CAL_EN_BIT	0x4000	// read calibration source instead of analog input channel 0
+#define   SERIAL_DATA_IN_BIT	0x8000	// serial data stream going to 8800 and 7376
+
+#define DAC_CSR	0x8		// dac control and status register
+enum dac_csr_bits {
+	DACEN = 0x2,		// dac enable
+	DAC_MODE_UPDATE_BOTH = 0x80,	// update both dacs when dac0 is written
+};
+static inline unsigned int DAC_RANGE(unsigned int channel, unsigned int range)
+{
+	return (range & 0x3) << (8 + 2 * (channel & 0x1));
+}
+static inline unsigned int DAC_RANGE_MASK(unsigned int channel)
+{
+	return 0x3 << (8 + 2 * (channel & 0x1));
+};
+
+// bits for 1602 series only
+enum dac_csr_bits_1602 {
+	DAC_EMPTY = 0x1,	// dac fifo empty, read, write clear
+	DAC_START = 0x4,	// start/arm dac fifo operations
+	DAC_PACER_MASK = 0x18,	// bits that set dac pacer source
+	DAC_PACER_INT = 0x8,	// dac internal pacing
+	DAC_PACER_EXT_FALL = 0x10,	// dac external pacing, falling edge
+	DAC_PACER_EXT_RISE = 0x18,	// dac external pacing, rising edge
+};
+static inline unsigned int DAC_CHAN_EN(unsigned int channel)
+{
+	return 1 << (5 + (channel & 0x1));	// enable channel 0 or 1
+};
+
+/* analog input fifo */
+#define ADCDATA	0		// ADC DATA register
+#define ADCFIFOCLR	2	// ADC FIFO CLEAR
+
+// pacer, counter, dio registers
+#define ADC8254 0
+#define DIO_8255 4
+#define DAC8254 8
+
+// analog output registers for 100x, 1200 series
+static inline unsigned int DAC_DATA_REG(unsigned int channel)
+{
+	return 2 * (channel & 0x1);
+}
+
+/* analog output registers for 1602 series*/
+#define DACDATA	0		// DAC DATA register
+#define DACFIFOCLR	2	// DAC FIFO CLEAR
+
+// bit in hexadecimal representation of range index that indicates unipolar input range
+#define IS_UNIPOLAR 0x4
+// analog input ranges for most boards
+static const struct comedi_lrange cb_pcidas_ranges = {
+	8,
+	{
+			BIP_RANGE(10),
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+			UNI_RANGE(10),
+			UNI_RANGE(5),
+			UNI_RANGE(2.5),
+			UNI_RANGE(1.25)
+		}
+};
+
+// pci-das1001 input ranges
+static const struct comedi_lrange cb_pcidas_alt_ranges = {
+	8,
+	{
+			BIP_RANGE(10),
+			BIP_RANGE(1),
+			BIP_RANGE(0.1),
+			BIP_RANGE(0.01),
+			UNI_RANGE(10),
+			UNI_RANGE(1),
+			UNI_RANGE(0.1),
+			UNI_RANGE(0.01)
+		}
+};
+
+// analog output ranges
+static const struct comedi_lrange cb_pcidas_ao_ranges = {
+	4,
+	{
+			BIP_RANGE(5),
+			BIP_RANGE(10),
+			UNI_RANGE(5),
+			UNI_RANGE(10),
+		}
+};
+
+enum trimpot_model {
+	AD7376,
+	AD8402,
+};
+
+struct cb_pcidas_board {
+	const char *name;
+	unsigned short device_id;
+	int ai_se_chans;	// Inputs in single-ended mode
+	int ai_diff_chans;	// Inputs in differential mode
+	int ai_bits;		// analog input resolution
+	int ai_speed;		// fastest conversion period in ns
+	int ao_nchan;		// number of analog out channels
+	int has_ao_fifo;	// analog output has fifo
+	int ao_scan_speed;	// analog output speed for 1602 series (for a scan, not conversion)
+	int fifo_size;		// number of samples fifo can hold
+	const struct comedi_lrange *ranges;
+	enum trimpot_model trimpot;
+	unsigned has_dac08:1;
+};
+
+static const struct cb_pcidas_board cb_pcidas_boards[] = {
+	{
+	      name:	"pci-das1602/16",
+	      device_id:0x1,
+	      ai_se_chans:16,
+	      ai_diff_chans:8,
+	      ai_bits:	16,
+	      ai_speed:5000,
+	      ao_nchan:2,
+	      has_ao_fifo:1,
+	      ao_scan_speed:10000,
+	      fifo_size:512,
+	      ranges:	&cb_pcidas_ranges,
+	      trimpot:	AD8402,
+	      has_dac08:1,
+		},
+	{
+	      name:	"pci-das1200",
+	      device_id:0xF,
+	      ai_se_chans:16,
+	      ai_diff_chans:8,
+	      ai_bits:	12,
+	      ai_speed:3200,
+	      ao_nchan:2,
+	      has_ao_fifo:0,
+	      fifo_size:1024,
+	      ranges:	&cb_pcidas_ranges,
+	      trimpot:	AD7376,
+	      has_dac08:0,
+		},
+	{
+	      name:	"pci-das1602/12",
+	      device_id:0x10,
+	      ai_se_chans:16,
+	      ai_diff_chans:8,
+	      ai_bits:	12,
+	      ai_speed:3200,
+	      ao_nchan:2,
+	      has_ao_fifo:1,
+	      ao_scan_speed:4000,
+	      fifo_size:1024,
+	      ranges:	&cb_pcidas_ranges,
+	      trimpot:	AD7376,
+	      has_dac08:0,
+		},
+	{
+	      name:	"pci-das1200/jr",
+	      device_id:0x19,
+	      ai_se_chans:16,
+	      ai_diff_chans:8,
+	      ai_bits:	12,
+	      ai_speed:3200,
+	      ao_nchan:0,
+	      has_ao_fifo:0,
+	      fifo_size:1024,
+	      ranges:	&cb_pcidas_ranges,
+	      trimpot:	AD7376,
+	      has_dac08:0,
+		},
+	{
+	      name:	"pci-das1602/16/jr",
+	      device_id:0x1C,
+	      ai_se_chans:16,
+	      ai_diff_chans:8,
+	      ai_bits:	16,
+	      ai_speed:5000,
+	      ao_nchan:0,
+	      has_ao_fifo:0,
+	      fifo_size:512,
+	      ranges:	&cb_pcidas_ranges,
+	      trimpot:	AD8402,
+	      has_dac08:1,
+		},
+	{
+	      name:	"pci-das1000",
+	      device_id:0x4C,
+	      ai_se_chans:16,
+	      ai_diff_chans:8,
+	      ai_bits:	12,
+	      ai_speed:4000,
+	      ao_nchan:0,
+	      has_ao_fifo:0,
+	      fifo_size:1024,
+	      ranges:	&cb_pcidas_ranges,
+	      trimpot:	AD7376,
+	      has_dac08:0,
+		},
+	{
+	      name:	"pci-das1001",
+	      device_id:0x1a,
+	      ai_se_chans:16,
+	      ai_diff_chans:8,
+	      ai_bits:	12,
+	      ai_speed:6800,
+	      ao_nchan:2,
+	      has_ao_fifo:0,
+	      fifo_size:1024,
+	      ranges:	&cb_pcidas_alt_ranges,
+	      trimpot:	AD7376,
+	      has_dac08:0,
+		},
+	{
+	      name:	"pci-das1002",
+	      device_id:0x1b,
+	      ai_se_chans:16,
+	      ai_diff_chans:8,
+	      ai_bits:	12,
+	      ai_speed:6800,
+	      ao_nchan:2,
+	      has_ao_fifo:0,
+	      fifo_size:1024,
+	      ranges:	&cb_pcidas_ranges,
+	      trimpot:	AD7376,
+	      has_dac08:0,
+		},
+};
+
+// Number of boards in cb_pcidas_boards
+#define N_BOARDS	(sizeof(cb_pcidas_boards) / sizeof(struct cb_pcidas_board))
+
+static DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = {
+	{PCI_VENDOR_ID_CB, 0x0001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_CB, 0x000f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_CB, 0x0010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_CB, 0x0019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_CB, 0x001c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_CB, 0x004c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_CB, 0x001a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_CB, 0x001b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table);
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct cb_pcidas_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver.  If
+   several hardware drivers keep similar information in this structure,
+   feel free to suggest moving the variable to the struct comedi_device struct.  */
+struct cb_pcidas_private {
+	/* would be useful for a PCI device */
+	struct pci_dev *pci_dev;
+	// base addresses
+	unsigned long s5933_config;
+	unsigned long control_status;
+	unsigned long adc_fifo;
+	unsigned long pacer_counter_dio;
+	unsigned long ao_registers;
+	// divisors of master clock for analog input pacing
+	unsigned int divisor1;
+	unsigned int divisor2;
+	volatile unsigned int count;	// number of analog input samples remaining
+	volatile unsigned int adc_fifo_bits;	// bits to write to interupt/adcfifo register
+	volatile unsigned int s5933_intcsr_bits;	// bits to write to amcc s5933 interrupt control/status register
+	volatile unsigned int ao_control_bits;	// bits to write to ao control and status register
+	short ai_buffer[AI_BUFFER_SIZE];
+	short ao_buffer[AO_BUFFER_SIZE];
+	// divisors of master clock for analog output pacing
+	unsigned int ao_divisor1;
+	unsigned int ao_divisor2;
+	volatile unsigned int ao_count;	// number of analog output samples remaining
+	int ao_value[2];	// remember what the analog outputs are set to, to allow readback
+	unsigned int caldac_value[NUM_CHANNELS_8800];	// for readback of caldac
+	unsigned int trimpot_value[NUM_CHANNELS_8402];	// for readback of trimpot
+	unsigned int dac08_value;
+	unsigned int calibration_source;
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct cb_pcidas_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int cb_pcidas_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int cb_pcidas_detach(struct comedi_device * dev);
+static struct comedi_driver driver_cb_pcidas = {
+      driver_name:"cb_pcidas",
+      module:THIS_MODULE,
+      attach:cb_pcidas_attach,
+      detach:cb_pcidas_detach,
+};
+
+static int cb_pcidas_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int ai_config_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int cb_pcidas_ao_nofifo_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int cb_pcidas_ao_fifo_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int cb_pcidas_ao_readback_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int cb_pcidas_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int cb_pcidas_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd);
+static int cb_pcidas_ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
+				struct comedi_subdevice *subdev,
+				unsigned int trig_num);
+static int cb_pcidas_ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd);
+static irqreturn_t cb_pcidas_interrupt(int irq, void *d PT_REGS_ARG);
+static void handle_ao_interrupt(struct comedi_device * dev, unsigned int status);
+static int cb_pcidas_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static int cb_pcidas_ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void cb_pcidas_load_counters(struct comedi_device * dev, unsigned int *ns,
+	int round_flags);
+static int eeprom_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int caldac_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int caldac_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int trimpot_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int cb_pcidas_trimpot_write(struct comedi_device * dev, unsigned int channel,
+	unsigned int value);
+static int trimpot_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int dac08_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int dac08_write(struct comedi_device * dev, unsigned int value);
+static int dac08_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int caldac_8800_write(struct comedi_device * dev, unsigned int address,
+	uint8_t value);
+static int trimpot_7376_write(struct comedi_device * dev, uint8_t value);
+static int trimpot_8402_write(struct comedi_device * dev, unsigned int channel,
+	uint8_t value);
+static int nvram_read(struct comedi_device * dev, unsigned int address,
+	uint8_t * data);
+
+static inline unsigned int cal_enable_bits(struct comedi_device * dev)
+{
+	return CAL_EN_BIT | CAL_SRC_BITS(devpriv->calibration_source);
+}
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board.
+ */
+static int cb_pcidas_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	struct pci_dev *pcidev;
+	int index;
+	int i;
+
+	printk("comedi%d: cb_pcidas: ", dev->minor);
+
+/*
+ * Allocate the private structure area.
+ */
+	if (alloc_private(dev, sizeof(struct cb_pcidas_private)) < 0)
+		return -ENOMEM;
+
+/*
+ * Probe the device to determine what device in the series it is.
+ */
+	printk("\n");
+
+	for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+		pcidev != NULL;
+		pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+		// is it not a computer boards card?
+		if (pcidev->vendor != PCI_VENDOR_ID_CB)
+			continue;
+		// loop through cards supported by this driver
+		for (index = 0; index < N_BOARDS; index++) {
+			if (cb_pcidas_boards[index].device_id != pcidev->device)
+				continue;
+			// was a particular bus/slot requested?
+			if (it->options[0] || it->options[1]) {
+				// are we on the wrong bus/slot?
+				if (pcidev->bus->number != it->options[0] ||
+					PCI_SLOT(pcidev->devfn) !=
+					it->options[1]) {
+					continue;
+				}
+			}
+			devpriv->pci_dev = pcidev;
+			dev->board_ptr = cb_pcidas_boards + index;
+			goto found;
+		}
+	}
+
+	printk("No supported ComputerBoards/MeasurementComputing card found on "
+		"requested position\n");
+	return -EIO;
+
+      found:
+
+	printk("Found %s on bus %i, slot %i\n", cb_pcidas_boards[index].name,
+		pcidev->bus->number, PCI_SLOT(pcidev->devfn));
+
+	/*
+	 * Enable PCI device and reserve I/O ports.
+	 */
+	if (comedi_pci_enable(pcidev, "cb_pcidas")) {
+		printk(" Failed to enable PCI device and request regions\n");
+		return -EIO;
+	}
+	/*
+	 * Initialize devpriv->control_status and devpriv->adc_fifo to point to
+	 * their base address.
+	 */
+	devpriv->s5933_config =
+		pci_resource_start(devpriv->pci_dev, S5933_BADRINDEX);
+	devpriv->control_status =
+		pci_resource_start(devpriv->pci_dev, CONT_STAT_BADRINDEX);
+	devpriv->adc_fifo =
+		pci_resource_start(devpriv->pci_dev, ADC_FIFO_BADRINDEX);
+	devpriv->pacer_counter_dio =
+		pci_resource_start(devpriv->pci_dev, PACER_BADRINDEX);
+	if (thisboard->ao_nchan) {
+		devpriv->ao_registers =
+			pci_resource_start(devpriv->pci_dev, AO_BADRINDEX);
+	}
+	// disable and clear interrupts on amcc s5933
+	outl(INTCSR_INBOX_INTR_STATUS,
+		devpriv->s5933_config + AMCC_OP_REG_INTCSR);
+
+	// get irq
+	if (comedi_request_irq(devpriv->pci_dev->irq, cb_pcidas_interrupt,
+			IRQF_SHARED, "cb_pcidas", dev)) {
+		printk(" unable to allocate irq %d\n", devpriv->pci_dev->irq);
+		return -EINVAL;
+	}
+	dev->irq = devpriv->pci_dev->irq;
+
+	//Initialize dev->board_name
+	dev->board_name = thisboard->name;
+
+/*
+ * Allocate the subdevice structures.
+ */
+	if (alloc_subdevices(dev, 7) < 0)
+		return -ENOMEM;
+
+	s = dev->subdevices + 0;
+	/* analog input subdevice */
+	dev->read_subdev = s;
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
+	/* WARNING: Number of inputs in differential mode is ignored */
+	s->n_chan = thisboard->ai_se_chans;
+	s->len_chanlist = thisboard->ai_se_chans;
+	s->maxdata = (1 << thisboard->ai_bits) - 1;
+	s->range_table = thisboard->ranges;
+	s->insn_read = cb_pcidas_ai_rinsn;
+	s->insn_config = ai_config_insn;
+	s->do_cmd = cb_pcidas_ai_cmd;
+	s->do_cmdtest = cb_pcidas_ai_cmdtest;
+	s->cancel = cb_pcidas_cancel;
+
+	/* analog output subdevice */
+	s = dev->subdevices + 1;
+	if (thisboard->ao_nchan) {
+		s->type = COMEDI_SUBD_AO;
+		s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
+		s->n_chan = thisboard->ao_nchan;
+		// analog out resolution is the same as analog input resolution, so use ai_bits
+		s->maxdata = (1 << thisboard->ai_bits) - 1;
+		s->range_table = &cb_pcidas_ao_ranges;
+		s->insn_read = cb_pcidas_ao_readback_insn;
+		if (thisboard->has_ao_fifo) {
+			dev->write_subdev = s;
+			s->subdev_flags |= SDF_CMD_WRITE;
+			s->insn_write = cb_pcidas_ao_fifo_winsn;
+			s->do_cmdtest = cb_pcidas_ao_cmdtest;
+			s->do_cmd = cb_pcidas_ao_cmd;
+			s->cancel = cb_pcidas_ao_cancel;
+		} else {
+			s->insn_write = cb_pcidas_ao_nofifo_winsn;
+		}
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	/* 8255 */
+	s = dev->subdevices + 2;
+	subdev_8255_init(dev, s, NULL, devpriv->pacer_counter_dio + DIO_8255);
+
+	// serial EEPROM,
+	s = dev->subdevices + 3;
+	s->type = COMEDI_SUBD_MEMORY;
+	s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
+	s->n_chan = 256;
+	s->maxdata = 0xff;
+	s->insn_read = eeprom_read_insn;
+
+	// 8800 caldac
+	s = dev->subdevices + 4;
+	s->type = COMEDI_SUBD_CALIB;
+	s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+	s->n_chan = NUM_CHANNELS_8800;
+	s->maxdata = 0xff;
+	s->insn_read = caldac_read_insn;
+	s->insn_write = caldac_write_insn;
+	for (i = 0; i < s->n_chan; i++)
+		caldac_8800_write(dev, i, s->maxdata / 2);
+
+	// trim potentiometer
+	s = dev->subdevices + 5;
+	s->type = COMEDI_SUBD_CALIB;
+	s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+	if (thisboard->trimpot == AD7376) {
+		s->n_chan = NUM_CHANNELS_7376;
+		s->maxdata = 0x7f;
+	} else {
+		s->n_chan = NUM_CHANNELS_8402;
+		s->maxdata = 0xff;
+	}
+	s->insn_read = trimpot_read_insn;
+	s->insn_write = trimpot_write_insn;
+	for (i = 0; i < s->n_chan; i++)
+		cb_pcidas_trimpot_write(dev, i, s->maxdata / 2);
+
+	// dac08 caldac
+	s = dev->subdevices + 6;
+	if (thisboard->has_dac08) {
+		s->type = COMEDI_SUBD_CALIB;
+		s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+		s->n_chan = NUM_CHANNELS_DAC08;
+		s->insn_read = dac08_read_insn;
+		s->insn_write = dac08_write_insn;
+		s->maxdata = 0xff;
+		dac08_write(dev, s->maxdata / 2);
+	} else
+		s->type = COMEDI_SUBD_UNUSED;
+
+	// make sure mailbox 4 is empty
+	inl(devpriv->s5933_config + AMCC_OP_REG_IMB4);
+	/* Set bits to enable incoming mailbox interrupts on amcc s5933. */
+	devpriv->s5933_intcsr_bits =
+		INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
+		INTCSR_INBOX_FULL_INT;
+	// clear and enable interrupt on amcc s5933
+	outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
+		devpriv->s5933_config + AMCC_OP_REG_INTCSR);
+
+	return 1;
+}
+
+/*
+ * cb_pcidas_detach is called to deconfigure a device.  It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach().  dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int cb_pcidas_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: cb_pcidas: remove\n", dev->minor);
+
+	if (devpriv) {
+		if (devpriv->s5933_config) {
+			// disable and clear interrupts on amcc s5933
+			outl(INTCSR_INBOX_INTR_STATUS,
+				devpriv->s5933_config + AMCC_OP_REG_INTCSR);
+#ifdef CB_PCIDAS_DEBUG
+			rt_printk("detaching, incsr is 0x%x\n",
+				inl(devpriv->s5933_config +
+					AMCC_OP_REG_INTCSR));
+#endif
+		}
+	}
+	if (dev->irq)
+		comedi_free_irq(dev->irq, dev);
+	if (dev->subdevices)
+		subdev_8255_cleanup(dev, dev->subdevices + 2);
+	if (devpriv && devpriv->pci_dev) {
+		if (devpriv->s5933_config) {
+			comedi_pci_disable(devpriv->pci_dev);
+		}
+		pci_dev_put(devpriv->pci_dev);
+	}
+
+	return 0;
+}
+
+/*
+ * "instructions" read/write data in "one-shot" or "software-triggered"
+ * mode.
+ */
+static int cb_pcidas_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n, i;
+	unsigned int bits;
+	static const int timeout = 10000;
+	int channel;
+	// enable calibration input if appropriate
+	if (insn->chanspec & CR_ALT_SOURCE) {
+		outw(cal_enable_bits(dev),
+			devpriv->control_status + CALIBRATION_REG);
+		channel = 0;
+	} else {
+		outw(0, devpriv->control_status + CALIBRATION_REG);
+		channel = CR_CHAN(insn->chanspec);
+	}
+	// set mux limits and gain
+	bits = BEGIN_SCAN(channel) |
+		END_SCAN(channel) | GAIN_BITS(CR_RANGE(insn->chanspec));
+	// set unipolar/bipolar
+	if (CR_RANGE(insn->chanspec) & IS_UNIPOLAR)
+		bits |= UNIP;
+	// set singleended/differential
+	if (CR_AREF(insn->chanspec) != AREF_DIFF)
+		bits |= SE;
+	outw(bits, devpriv->control_status + ADCMUX_CONT);
+
+	/* clear fifo */
+	outw(0, devpriv->adc_fifo + ADCFIFOCLR);
+
+	/* convert n samples */
+	for (n = 0; n < insn->n; n++) {
+		/* trigger conversion */
+		outw(0, devpriv->adc_fifo + ADCDATA);
+
+		/* wait for conversion to end */
+		/* return -ETIMEDOUT if there is a timeout */
+		for (i = 0; i < timeout; i++) {
+			if (inw(devpriv->control_status + ADCMUX_CONT) & EOC)
+				break;
+		}
+		if (i == timeout)
+			return -ETIMEDOUT;
+
+		/* read data */
+		data[n] = inw(devpriv->adc_fifo + ADCDATA);
+	}
+
+	/* return the number of samples read/written */
+	return n;
+}
+
+static int ai_config_calibration_source(struct comedi_device * dev, unsigned int * data)
+{
+	static const int num_calibration_sources = 8;
+	unsigned int source = data[1];
+
+	if (source >= num_calibration_sources) {
+		printk("invalid calibration source: %i\n", source);
+		return -EINVAL;
+	}
+
+	devpriv->calibration_source = source;
+
+	return 2;
+}
+
+static int ai_config_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int id = data[0];
+
+	switch (id) {
+	case INSN_CONFIG_ALT_SOURCE:
+		return ai_config_calibration_source(dev, data);
+		break;
+	default:
+		return -EINVAL;
+		break;
+	}
+	return -EINVAL;
+}
+
+// analog output insn for pcidas-1000 and 1200 series
+static int cb_pcidas_ao_nofifo_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int channel;
+	unsigned long flags;
+
+	// set channel and range
+	channel = CR_CHAN(insn->chanspec);
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	devpriv->ao_control_bits &=
+		~DAC_MODE_UPDATE_BOTH & ~DAC_RANGE_MASK(channel);
+	devpriv->ao_control_bits |=
+		DACEN | DAC_RANGE(channel, CR_RANGE(insn->chanspec));
+	outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	// remember value for readback
+	devpriv->ao_value[channel] = data[0];
+	// send data
+	outw(data[0], devpriv->ao_registers + DAC_DATA_REG(channel));
+
+	return 1;
+}
+
+// analog output insn for pcidas-1602 series
+static int cb_pcidas_ao_fifo_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int channel;
+	unsigned long flags;
+
+	// clear dac fifo
+	outw(0, devpriv->ao_registers + DACFIFOCLR);
+
+	// set channel and range
+	channel = CR_CHAN(insn->chanspec);
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	devpriv->ao_control_bits &=
+		~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) & ~DAC_RANGE_MASK(channel) &
+		~DAC_PACER_MASK;
+	devpriv->ao_control_bits |=
+		DACEN | DAC_RANGE(channel,
+		CR_RANGE(insn->chanspec)) | DAC_CHAN_EN(channel) | DAC_START;
+	outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	// remember value for readback
+	devpriv->ao_value[channel] = data[0];
+	// send data
+	outw(data[0], devpriv->ao_registers + DACDATA);
+
+	return 1;
+}
+
+// analog output readback insn
+// XXX loses track of analog output value back after an analog ouput command is executed
+static int cb_pcidas_ao_readback_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)];
+
+	return 1;
+}
+
+static int eeprom_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	uint8_t nvram_data;
+	int retval;
+
+	retval = nvram_read(dev, CR_CHAN(insn->chanspec), &nvram_data);
+	if (retval < 0)
+		return retval;
+
+	data[0] = nvram_data;
+
+	return 1;
+}
+
+static int caldac_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	const unsigned int channel = CR_CHAN(insn->chanspec);
+
+	return caldac_8800_write(dev, channel, data[0]);
+}
+
+static int caldac_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	data[0] = devpriv->caldac_value[CR_CHAN(insn->chanspec)];
+
+	return 1;
+}
+
+/* 1602/16 pregain offset */
+static int dac08_write(struct comedi_device * dev, unsigned int value)
+{
+	if (devpriv->dac08_value == value)
+		return 1;
+
+	devpriv->dac08_value = value;
+
+	outw(cal_enable_bits(dev) | (value & 0xff),
+		devpriv->control_status + CALIBRATION_REG);
+	comedi_udelay(1);
+	outw(cal_enable_bits(dev) | SELECT_DAC08_BIT | (value & 0xff),
+		devpriv->control_status + CALIBRATION_REG);
+	comedi_udelay(1);
+	outw(cal_enable_bits(dev) | (value & 0xff),
+		devpriv->control_status + CALIBRATION_REG);
+	comedi_udelay(1);
+
+	return 1;
+}
+
+static int dac08_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	return dac08_write(dev, data[0]);
+}
+
+static int dac08_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	data[0] = devpriv->dac08_value;
+
+	return 1;
+}
+
+static int cb_pcidas_trimpot_write(struct comedi_device * dev,
+	unsigned int channel, unsigned int value)
+{
+	if (devpriv->trimpot_value[channel] == value)
+		return 1;
+
+	devpriv->trimpot_value[channel] = value;
+	switch (thisboard->trimpot) {
+	case AD7376:
+		trimpot_7376_write(dev, value);
+		break;
+	case AD8402:
+		trimpot_8402_write(dev, channel, value);
+		break;
+	default:
+		comedi_error(dev, "driver bug?");
+		return -1;
+		break;
+	}
+
+	return 1;
+}
+
+static int trimpot_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int channel = CR_CHAN(insn->chanspec);
+
+	return cb_pcidas_trimpot_write(dev, channel, data[0]);
+}
+
+static int trimpot_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int channel = CR_CHAN(insn->chanspec);
+
+	data[0] = devpriv->trimpot_value[channel];
+
+	return 1;
+}
+
+static int cb_pcidas_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp;
+	int i, gain, start_chan;
+
+	/* cmdtest tests a particular command to see if it is valid.
+	 * Using the cmdtest ioctl, a user can create a valid cmd
+	 * and then have it executes by the cmd ioctl.
+	 *
+	 * cmdtest returns 1,2,3,4 or 0, depending on which tests
+	 * the command passes. */
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW | TRIG_EXT;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_TIMER | TRIG_NOW | TRIG_EXT;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
+		err++;
+	if (cmd->scan_begin_src != TRIG_FOLLOW &&
+		cmd->scan_begin_src != TRIG_TIMER &&
+		cmd->scan_begin_src != TRIG_EXT)
+		err++;
+	if (cmd->convert_src != TRIG_TIMER &&
+		cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
+		err++;
+	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+		err++;
+
+	// make sure trigger sources are compatible with each other
+	if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
+		err++;
+	if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
+		err++;
+	if (cmd->start_src == TRIG_EXT &&
+		(cmd->convert_src == TRIG_EXT
+			|| cmd->scan_begin_src == TRIG_EXT))
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		if (cmd->scan_begin_arg <
+			thisboard->ai_speed * cmd->chanlist_len) {
+			cmd->scan_begin_arg =
+				thisboard->ai_speed * cmd->chanlist_len;
+			err++;
+		}
+	}
+	if (cmd->convert_src == TRIG_TIMER) {
+		if (cmd->convert_arg < thisboard->ai_speed) {
+			cmd->convert_arg = thisboard->ai_speed;
+			err++;
+		}
+	}
+
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+	if (cmd->stop_src == TRIG_NONE) {
+		/* TRIG_NONE */
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		tmp = cmd->scan_begin_arg;
+		i8253_cascade_ns_to_timer_2div(TIMER_BASE,
+			&(devpriv->divisor1), &(devpriv->divisor2),
+			&(cmd->scan_begin_arg), cmd->flags & TRIG_ROUND_MASK);
+		if (tmp != cmd->scan_begin_arg)
+			err++;
+	}
+	if (cmd->convert_src == TRIG_TIMER) {
+		tmp = cmd->convert_arg;
+		i8253_cascade_ns_to_timer_2div(TIMER_BASE,
+			&(devpriv->divisor1), &(devpriv->divisor2),
+			&(cmd->convert_arg), cmd->flags & TRIG_ROUND_MASK);
+		if (tmp != cmd->convert_arg)
+			err++;
+	}
+
+	if (err)
+		return 4;
+
+	// check channel/gain list against card's limitations
+	if (cmd->chanlist) {
+		gain = CR_RANGE(cmd->chanlist[0]);
+		start_chan = CR_CHAN(cmd->chanlist[0]);
+		for (i = 1; i < cmd->chanlist_len; i++) {
+			if (CR_CHAN(cmd->chanlist[i]) !=
+				(start_chan + i) % s->n_chan) {
+				comedi_error(dev,
+					"entries in chanlist must be consecutive channels, counting upwards\n");
+				err++;
+			}
+			if (CR_RANGE(cmd->chanlist[i]) != gain) {
+				comedi_error(dev,
+					"entries in chanlist must all have the same gain\n");
+				err++;
+			}
+		}
+	}
+
+	if (err)
+		return 5;
+
+	return 0;
+}
+
+static int cb_pcidas_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+	unsigned int bits;
+	unsigned long flags;
+
+	// make sure CAL_EN_BIT is disabled
+	outw(0, devpriv->control_status + CALIBRATION_REG);
+	// initialize before settings pacer source and count values
+	outw(0, devpriv->control_status + TRIG_CONTSTAT);
+	// clear fifo
+	outw(0, devpriv->adc_fifo + ADCFIFOCLR);
+
+	// set mux limits, gain and pacer source
+	bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) |
+		END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |
+		GAIN_BITS(CR_RANGE(cmd->chanlist[0]));
+	// set unipolar/bipolar
+	if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR)
+		bits |= UNIP;
+	// set singleended/differential
+	if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF)
+		bits |= SE;
+	// set pacer source
+	if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)
+		bits |= PACER_EXT_RISE;
+	else
+		bits |= PACER_INT;
+	outw(bits, devpriv->control_status + ADCMUX_CONT);
+
+#ifdef CB_PCIDAS_DEBUG
+	rt_printk("comedi: sent 0x%x to adcmux control\n", bits);
+#endif
+
+	// load counters
+	if (cmd->convert_src == TRIG_TIMER)
+		cb_pcidas_load_counters(dev, &cmd->convert_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+	else if (cmd->scan_begin_src == TRIG_TIMER)
+		cb_pcidas_load_counters(dev, &cmd->scan_begin_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+
+	// set number of conversions
+	if (cmd->stop_src == TRIG_COUNT) {
+		devpriv->count = cmd->chanlist_len * cmd->stop_arg;
+	}
+	// enable interrupts
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	devpriv->adc_fifo_bits |= INTE;
+	devpriv->adc_fifo_bits &= ~INT_MASK;
+	if (cmd->flags & TRIG_WAKE_EOS) {
+		if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
+			devpriv->adc_fifo_bits |= INT_EOS;	// interrupt end of burst
+		else
+			devpriv->adc_fifo_bits |= INT_FNE;	// interrupt fifo not empty
+	} else {
+		devpriv->adc_fifo_bits |= INT_FHF;	//interrupt fifo half full
+	}
+#ifdef CB_PCIDAS_DEBUG
+	rt_printk("comedi: adc_fifo_bits are 0x%x\n", devpriv->adc_fifo_bits);
+#endif
+	// enable (and clear) interrupts
+	outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL,
+		devpriv->control_status + INT_ADCFIFO);
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	// set start trigger and burst mode
+	bits = 0;
+	if (cmd->start_src == TRIG_NOW)
+		bits |= SW_TRIGGER;
+	else if (cmd->start_src == TRIG_EXT)
+		bits |= EXT_TRIGGER | TGEN | XTRCL;
+	else {
+		comedi_error(dev, "bug!");
+		return -1;
+	}
+	if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
+		bits |= BURSTE;
+	outw(bits, devpriv->control_status + TRIG_CONTSTAT);
+#ifdef CB_PCIDAS_DEBUG
+	rt_printk("comedi: sent 0x%x to trig control\n", bits);
+#endif
+
+	return 0;
+}
+
+static int cb_pcidas_ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp;
+
+	/* cmdtest tests a particular command to see if it is valid.
+	 * Using the cmdtest ioctl, a user can create a valid cmd
+	 * and then have it executes by the cmd ioctl.
+	 *
+	 * cmdtest returns 1,2,3,4 or 0, depending on which tests
+	 * the command passes. */
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_INT;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_NOW;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	if (cmd->scan_begin_src != TRIG_TIMER &&
+		cmd->scan_begin_src != TRIG_EXT)
+		err++;
+	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		if (cmd->scan_begin_arg < thisboard->ao_scan_speed) {
+			cmd->scan_begin_arg = thisboard->ao_scan_speed;
+			err++;
+		}
+	}
+
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+	if (cmd->stop_src == TRIG_NONE) {
+		/* TRIG_NONE */
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		tmp = cmd->scan_begin_arg;
+		i8253_cascade_ns_to_timer_2div(TIMER_BASE,
+			&(devpriv->ao_divisor1), &(devpriv->ao_divisor2),
+			&(cmd->scan_begin_arg), cmd->flags & TRIG_ROUND_MASK);
+		if (tmp != cmd->scan_begin_arg)
+			err++;
+	}
+
+	if (err)
+		return 4;
+
+	// check channel/gain list against card's limitations
+	if (cmd->chanlist && cmd->chanlist_len > 1) {
+		if (CR_CHAN(cmd->chanlist[0]) != 0 ||
+			CR_CHAN(cmd->chanlist[1]) != 1) {
+			comedi_error(dev,
+				"channels must be ordered channel 0, channel 1 in chanlist\n");
+			err++;
+		}
+	}
+
+	if (err)
+		return 5;
+
+	return 0;
+}
+
+static int cb_pcidas_ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+	unsigned int i;
+	unsigned long flags;
+
+	// set channel limits, gain
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	for (i = 0; i < cmd->chanlist_len; i++) {
+		// enable channel
+		devpriv->ao_control_bits |=
+			DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i]));
+		// set range
+		devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]),
+			CR_RANGE(cmd->chanlist[i]));
+	}
+
+	// disable analog out before settings pacer source and count values
+	outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	// clear fifo
+	outw(0, devpriv->ao_registers + DACFIFOCLR);
+
+	// load counters
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		i8253_cascade_ns_to_timer_2div(TIMER_BASE,
+			&(devpriv->ao_divisor1), &(devpriv->ao_divisor2),
+			&(cmd->scan_begin_arg), cmd->flags);
+
+		/* Write the values of ctr1 and ctr2 into counters 1 and 2 */
+		i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 1,
+			devpriv->ao_divisor1, 2);
+		i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 2,
+			devpriv->ao_divisor2, 2);
+	}
+	// set number of conversions
+	if (cmd->stop_src == TRIG_COUNT) {
+		devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg;
+	}
+	// set pacer source
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	switch (cmd->scan_begin_src) {
+	case TRIG_TIMER:
+		devpriv->ao_control_bits |= DAC_PACER_INT;
+		break;
+	case TRIG_EXT:
+		devpriv->ao_control_bits |= DAC_PACER_EXT_RISE;
+		break;
+	default:
+		comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+		comedi_error(dev, "error setting dac pacer source");
+		return -1;
+		break;
+	}
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	async->inttrig = cb_pcidas_ao_inttrig;
+
+	return 0;
+}
+
+static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
+				struct comedi_subdevice *s,
+				unsigned int trig_num)
+{
+	unsigned int num_bytes, num_points = thisboard->fifo_size;
+	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned long flags;
+
+	if (trig_num != 0)
+		return -EINVAL;
+
+	// load up fifo
+	if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points)
+		num_points = devpriv->ao_count;
+
+	num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer,
+		num_points * sizeof(short));
+	num_points = num_bytes / sizeof(short);
+
+	if (cmd->stop_src == TRIG_COUNT) {
+		devpriv->ao_count -= num_points;
+	}
+	// write data to board's fifo
+	outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes);
+
+	// enable dac half-full and empty interrupts
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	devpriv->adc_fifo_bits |= DAEMIE | DAHFIE;
+#ifdef CB_PCIDAS_DEBUG
+	rt_printk("comedi: adc_fifo_bits are 0x%x\n", devpriv->adc_fifo_bits);
+#endif
+	// enable and clear interrupts
+	outw(devpriv->adc_fifo_bits | DAEMI | DAHFI,
+		devpriv->control_status + INT_ADCFIFO);
+
+	// start dac
+	devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY;
+	outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
+#ifdef CB_PCIDAS_DEBUG
+	rt_printk("comedi: sent 0x%x to dac control\n",
+		devpriv->ao_control_bits);
+#endif
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	async->inttrig = NULL;
+
+	return 0;
+}
+
+static irqreturn_t cb_pcidas_interrupt(int irq, void *d PT_REGS_ARG)
+{
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s = dev->read_subdev;
+	struct comedi_async *async;
+	int status, s5933_status;
+	int half_fifo = thisboard->fifo_size / 2;
+	unsigned int num_samples, i;
+	static const int timeout = 10000;
+	unsigned long flags;
+
+	if (dev->attached == 0) {
+		return IRQ_NONE;
+	}
+
+	async = s->async;
+	async->events = 0;
+
+	s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR);
+#ifdef CB_PCIDAS_DEBUG
+	rt_printk("intcsr 0x%x\n", s5933_status);
+	rt_printk("mbef 0x%x\n", inl(devpriv->s5933_config + AMCC_OP_REG_MBEF));
+#endif
+
+	if ((INTCSR_INTR_ASSERTED & s5933_status) == 0)
+		return IRQ_NONE;
+
+	// make sure mailbox 4 is empty
+	inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4);
+	// clear interrupt on amcc s5933
+	outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
+		devpriv->s5933_config + AMCC_OP_REG_INTCSR);
+
+	status = inw(devpriv->control_status + INT_ADCFIFO);
+#ifdef CB_PCIDAS_DEBUG
+	if ((status & (INT | EOAI | LADFUL | DAHFI | DAEMI)) == 0) {
+		comedi_error(dev, "spurious interrupt");
+	}
+#endif
+
+	// check for analog output interrupt
+	if (status & (DAHFI | DAEMI)) {
+		handle_ao_interrupt(dev, status);
+	}
+	// check for analog input interrupts
+	// if fifo half-full
+	if (status & ADHFI) {
+		// read data
+		num_samples = half_fifo;
+		if (async->cmd.stop_src == TRIG_COUNT &&
+			num_samples > devpriv->count) {
+			num_samples = devpriv->count;
+		}
+		insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer,
+			num_samples);
+		cfc_write_array_to_buffer(s, devpriv->ai_buffer,
+			num_samples * sizeof(short));
+		devpriv->count -= num_samples;
+		if (async->cmd.stop_src == TRIG_COUNT && devpriv->count == 0) {
+			async->events |= COMEDI_CB_EOA;
+			cb_pcidas_cancel(dev, s);
+		}
+		// clear half-full interrupt latch
+		comedi_spin_lock_irqsave(&dev->spinlock, flags);
+		outw(devpriv->adc_fifo_bits | INT,
+			devpriv->control_status + INT_ADCFIFO);
+		comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+		// else if fifo not empty
+	} else if (status & (ADNEI | EOBI)) {
+		for (i = 0; i < timeout; i++) {
+			// break if fifo is empty
+			if ((ADNE & inw(devpriv->control_status +
+						INT_ADCFIFO)) == 0)
+				break;
+			cfc_write_to_buffer(s, inw(devpriv->adc_fifo));
+			if (async->cmd.stop_src == TRIG_COUNT && --devpriv->count == 0) {	/* end of acquisition */
+				cb_pcidas_cancel(dev, s);
+				async->events |= COMEDI_CB_EOA;
+				break;
+			}
+		}
+		// clear not-empty interrupt latch
+		comedi_spin_lock_irqsave(&dev->spinlock, flags);
+		outw(devpriv->adc_fifo_bits | INT,
+			devpriv->control_status + INT_ADCFIFO);
+		comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+	} else if (status & EOAI) {
+		comedi_error(dev,
+			"bug! encountered end of aquisition interrupt?");
+		// clear EOA interrupt latch
+		comedi_spin_lock_irqsave(&dev->spinlock, flags);
+		outw(devpriv->adc_fifo_bits | EOAI,
+			devpriv->control_status + INT_ADCFIFO);
+		comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+	}
+	//check for fifo overflow
+	if (status & LADFUL) {
+		comedi_error(dev, "fifo overflow");
+		// clear overflow interrupt latch
+		comedi_spin_lock_irqsave(&dev->spinlock, flags);
+		outw(devpriv->adc_fifo_bits | LADFUL,
+			devpriv->control_status + INT_ADCFIFO);
+		comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+		cb_pcidas_cancel(dev, s);
+		async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+	}
+
+	comedi_event(dev, s);
+
+	return IRQ_HANDLED;
+}
+
+static void handle_ao_interrupt(struct comedi_device * dev, unsigned int status)
+{
+	struct comedi_subdevice *s = dev->write_subdev;
+	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+	unsigned int half_fifo = thisboard->fifo_size / 2;
+	unsigned int num_points;
+	unsigned int flags;
+
+	async->events = 0;
+
+	if (status & DAEMI) {
+		// clear dac empty interrupt latch
+		comedi_spin_lock_irqsave(&dev->spinlock, flags);
+		outw(devpriv->adc_fifo_bits | DAEMI,
+			devpriv->control_status + INT_ADCFIFO);
+		comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+		if (inw(devpriv->ao_registers + DAC_CSR) & DAC_EMPTY) {
+			if (cmd->stop_src == TRIG_NONE ||
+				(cmd->stop_src == TRIG_COUNT
+					&& devpriv->ao_count)) {
+				comedi_error(dev, "dac fifo underflow");
+				cb_pcidas_ao_cancel(dev, s);
+				async->events |= COMEDI_CB_ERROR;
+			}
+			async->events |= COMEDI_CB_EOA;
+		}
+	} else if (status & DAHFI) {
+		unsigned int num_bytes;
+
+		// figure out how many points we are writing to fifo
+		num_points = half_fifo;
+		if (cmd->stop_src == TRIG_COUNT &&
+			devpriv->ao_count < num_points)
+			num_points = devpriv->ao_count;
+		num_bytes =
+			cfc_read_array_from_buffer(s, devpriv->ao_buffer,
+			num_points * sizeof(short));
+		num_points = num_bytes / sizeof(short);
+
+		if (async->cmd.stop_src == TRIG_COUNT) {
+			devpriv->ao_count -= num_points;
+		}
+		// write data to board's fifo
+		outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
+			num_points);
+		// clear half-full interrupt latch
+		comedi_spin_lock_irqsave(&dev->spinlock, flags);
+		outw(devpriv->adc_fifo_bits | DAHFI,
+			devpriv->control_status + INT_ADCFIFO);
+		comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+	}
+
+	comedi_event(dev, s);
+}
+
+/* cancel analog input command */
+static int cb_pcidas_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	// disable interrupts
+	devpriv->adc_fifo_bits &= ~INTE & ~EOAIE;
+	outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	// disable start trigger source and burst mode
+	outw(0, devpriv->control_status + TRIG_CONTSTAT);
+	// software pacer source
+	outw(0, devpriv->control_status + ADCMUX_CONT);
+
+	return 0;
+}
+
+/* cancel analog output command */
+static int cb_pcidas_ao_cancel(struct comedi_device *dev,
+			       struct comedi_subdevice *s)
+{
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	// disable interrupts
+	devpriv->adc_fifo_bits &= ~DAHFIE & ~DAEMIE;
+	outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
+
+	// disable output
+	devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK;
+	outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	return 0;
+}
+
+static void cb_pcidas_load_counters(struct comedi_device * dev, unsigned int *ns,
+	int rounding_flags)
+{
+	i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
+		&(devpriv->divisor2), ns, rounding_flags & TRIG_ROUND_MASK);
+
+	/* Write the values of ctr1 and ctr2 into counters 1 and 2 */
+	i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 1,
+		devpriv->divisor1, 2);
+	i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 2,
+		devpriv->divisor2, 2);
+}
+
+static void write_calibration_bitstream(struct comedi_device * dev,
+	unsigned int register_bits, unsigned int bitstream,
+	unsigned int bitstream_length)
+{
+	static const int write_delay = 1;
+	unsigned int bit;
+
+	for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
+		if (bitstream & bit)
+			register_bits |= SERIAL_DATA_IN_BIT;
+		else
+			register_bits &= ~SERIAL_DATA_IN_BIT;
+		comedi_udelay(write_delay);
+		outw(register_bits, devpriv->control_status + CALIBRATION_REG);
+	}
+}
+
+static int caldac_8800_write(struct comedi_device * dev, unsigned int address,
+	uint8_t value)
+{
+	static const int num_caldac_channels = 8;
+	static const int bitstream_length = 11;
+	unsigned int bitstream = ((address & 0x7) << 8) | value;
+	static const int caldac_8800_comedi_udelay = 1;
+
+	if (address >= num_caldac_channels) {
+		comedi_error(dev, "illegal caldac channel");
+		return -1;
+	}
+
+	if (value == devpriv->caldac_value[address])
+		return 1;
+
+	devpriv->caldac_value[address] = value;
+
+	write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream,
+		bitstream_length);
+
+	comedi_udelay(caldac_8800_comedi_udelay);
+	outw(cal_enable_bits(dev) | SELECT_8800_BIT,
+		devpriv->control_status + CALIBRATION_REG);
+	comedi_udelay(caldac_8800_comedi_udelay);
+	outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
+
+	return 1;
+}
+
+static int trimpot_7376_write(struct comedi_device * dev, uint8_t value)
+{
+	static const int bitstream_length = 7;
+	unsigned int bitstream = value & 0x7f;
+	unsigned int register_bits;
+	static const int ad7376_comedi_udelay = 1;
+
+	register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
+	comedi_udelay(ad7376_comedi_udelay);
+	outw(register_bits, devpriv->control_status + CALIBRATION_REG);
+
+	write_calibration_bitstream(dev, register_bits, bitstream,
+		bitstream_length);
+
+	comedi_udelay(ad7376_comedi_udelay);
+	outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
+
+	return 0;
+}
+
+/* For 1602/16 only
+ * ch 0 : adc gain
+ * ch 1 : adc postgain offset */
+static int trimpot_8402_write(struct comedi_device * dev, unsigned int channel,
+	uint8_t value)
+{
+	static const int bitstream_length = 10;
+	unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
+	unsigned int register_bits;
+	static const int ad8402_comedi_udelay = 1;
+
+	register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
+	comedi_udelay(ad8402_comedi_udelay);
+	outw(register_bits, devpriv->control_status + CALIBRATION_REG);
+
+	write_calibration_bitstream(dev, register_bits, bitstream,
+		bitstream_length);
+
+	comedi_udelay(ad8402_comedi_udelay);
+	outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
+
+	return 0;
+}
+
+static int wait_for_nvram_ready(unsigned long s5933_base_addr)
+{
+	static const int timeout = 1000;
+	unsigned int i;
+
+	for (i = 0; i < timeout; i++) {
+		if ((inb(s5933_base_addr +
+					AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY)
+			== 0)
+			return 0;
+		comedi_udelay(1);
+	}
+	return -1;
+}
+
+static int nvram_read(struct comedi_device * dev, unsigned int address, uint8_t * data)
+{
+	unsigned long iobase = devpriv->s5933_config;
+
+	if (wait_for_nvram_ready(iobase) < 0)
+		return -ETIMEDOUT;
+
+	outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR,
+		iobase + AMCC_OP_REG_MCSR_NVCMD);
+	outb(address & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
+	outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR,
+		iobase + AMCC_OP_REG_MCSR_NVCMD);
+	outb((address >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
+	outb(MCSR_NV_ENABLE | MCSR_NV_READ, iobase + AMCC_OP_REG_MCSR_NVCMD);
+
+	if (wait_for_nvram_ready(iobase) < 0)
+		return -ETIMEDOUT;
+
+	*data = inb(iobase + AMCC_OP_REG_MCSR_NVDATA);
+
+	return 0;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_PCI_INITCLEANUP(driver_cb_pcidas, cb_pcidas_pci_table);
diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c
new file mode 100644
index 0000000..1a580bd
--- /dev/null
+++ b/drivers/staging/comedi/drivers/cb_pcidas64.c
@@ -0,0 +1,4222 @@
+/*
+    comedi/drivers/cb_pcidas64.c
+    This is a driver for the ComputerBoards/MeasurementComputing PCI-DAS
+    64xx, 60xx, and 4020 cards.
+
+    Author:  Frank Mori Hess <fmhess@users.sourceforge.net>
+    Copyright (C) 2001, 2002 Frank Mori Hess
+
+    Thanks also go to the following people:
+
+    Steve Rosenbluth, for providing the source code for
+    his pci-das6402 driver, and source code for working QNX pci-6402
+    drivers by Greg Laird and Mariusz Bogacz.  None of the code was
+    used directly here, but it was useful as an additional source of
+    documentation on how to program the boards.
+
+    John Sims, for much testing and feedback on pcidas-4020 support.
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 1997-8 David A. Schleef <ds@schleef.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.
+
+    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.
+
+************************************************************************/
+
+/*
+
+Driver: cb_pcidas64
+Description: MeasurementComputing PCI-DAS64xx, 60XX, and 4020 series with the PLX 9080 PCI controller
+Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+Status: works
+Updated: 2002-10-09
+Devices: [Measurement Computing] PCI-DAS6402/16 (cb_pcidas64),
+  PCI-DAS6402/12, PCI-DAS64/M1/16, PCI-DAS64/M2/16,
+  PCI-DAS64/M3/16, PCI-DAS6402/16/JR, PCI-DAS64/M1/16/JR,
+  PCI-DAS64/M2/16/JR, PCI-DAS64/M3/16/JR, PCI-DAS64/M1/14,
+  PCI-DAS64/M2/14, PCI-DAS64/M3/14, PCI-DAS6013, PCI-DAS6014,
+  PCI-DAS6023, PCI-DAS6025, PCI-DAS6030,
+  PCI-DAS6031, PCI-DAS6032, PCI-DAS6033, PCI-DAS6034,
+  PCI-DAS6035, PCI-DAS6036, PCI-DAS6040, PCI-DAS6052,
+  PCI-DAS6070, PCI-DAS6071, PCI-DAS4020/12
+
+Configuration options:
+   [0] - PCI bus of device (optional)
+   [1] - PCI slot of device (optional)
+
+These boards may be autocalibrated with the comedi_calibrate utility.
+
+To select the bnc trigger input on the 4020 (instead of the dio input),
+specify a nonzero channel in the chanspec.  If you wish to use an external
+master clock on the 4020, you may do so by setting the scan_begin_src
+to TRIG_OTHER, and using an INSN_CONFIG_TIMER_1 configuration insn
+to configure the divisor to use for the external clock.
+
+Some devices are not identified because the PCI device IDs are not yet
+known. If you have such a board, please file a bug report at
+https://bugs.comedi.org.
+
+*/
+
+/*
+
+TODO:
+	make it return error if user attempts an ai command that uses the
+		external queue, and an ao command simultaneously
+	user counter subdevice
+	there are a number of boards this driver will support when they are
+		fully released, but does not yet since the pci device id numbers
+		are not yet available.
+	support prescaled 100khz clock for slow pacing (not available on 6000 series?)
+	make ao fifo size adjustable like ai fifo
+*/
+
+#include "../comedidev.h"
+#include <linux/delay.h>
+#include <asm/system.h>
+
+#include "comedi_pci.h"
+#include "8253.h"
+#include "8255.h"
+#include "plx9080.h"
+#include "comedi_fc.h"
+
+#undef PCIDAS64_DEBUG		// disable debugging code
+//#define PCIDAS64_DEBUG        // enable debugging code
+
+#ifdef PCIDAS64_DEBUG
+#define DEBUG_PRINT(format, args...)  rt_printk(format , ## args )
+#else
+#define DEBUG_PRINT(format, args...)
+#endif
+
+#define TIMER_BASE 25		// 40MHz master clock
+#define PRESCALED_TIMER_BASE	10000	// 100kHz 'prescaled' clock for slow aquisition, maybe I'll support this someday
+#define DMA_BUFFER_SIZE 0x1000
+
+/* maximum value that can be loaded into board's 24-bit counters*/
+static const int max_counter_value = 0xffffff;
+
+/* PCI-DAS64xxx base addresses */
+
+// indices of base address regions
+enum base_address_regions {
+	PLX9080_BADDRINDEX = 0,
+	MAIN_BADDRINDEX = 2,
+	DIO_COUNTER_BADDRINDEX = 3,
+};
+
+// priv(dev)->main_iobase registers
+enum write_only_registers {
+	INTR_ENABLE_REG = 0x0,	// interrupt enable register
+	HW_CONFIG_REG = 0x2,	// hardware config register
+	DAQ_SYNC_REG = 0xc,
+	DAQ_ATRIG_LOW_4020_REG = 0xc,
+	ADC_CONTROL0_REG = 0x10,	// adc control register 0
+	ADC_CONTROL1_REG = 0x12,	// adc control register 1
+	CALIBRATION_REG = 0x14,
+	ADC_SAMPLE_INTERVAL_LOWER_REG = 0x16,	// lower 16 bits of adc sample interval counter
+	ADC_SAMPLE_INTERVAL_UPPER_REG = 0x18,	// upper 8 bits of adc sample interval counter
+	ADC_DELAY_INTERVAL_LOWER_REG = 0x1a,	// lower 16 bits of delay interval counter
+	ADC_DELAY_INTERVAL_UPPER_REG = 0x1c,	// upper 8 bits of delay interval counter
+	ADC_COUNT_LOWER_REG = 0x1e,	// lower 16 bits of hardware conversion/scan counter
+	ADC_COUNT_UPPER_REG = 0x20,	// upper 8 bits of hardware conversion/scan counter
+	ADC_START_REG = 0x22,	// software trigger to start aquisition
+	ADC_CONVERT_REG = 0x24,	// initiates single conversion
+	ADC_QUEUE_CLEAR_REG = 0x26,	// clears adc queue
+	ADC_QUEUE_LOAD_REG = 0x28,	// loads adc queue
+	ADC_BUFFER_CLEAR_REG = 0x2a,
+	ADC_QUEUE_HIGH_REG = 0x2c,	// high channel for internal queue, use adc_chan_bits() inline above
+	DAC_CONTROL0_REG = 0x50,	// dac control register 0
+	DAC_CONTROL1_REG = 0x52,	// dac control register 0
+	DAC_SAMPLE_INTERVAL_LOWER_REG = 0x54,	// lower 16 bits of dac sample interval counter
+	DAC_SAMPLE_INTERVAL_UPPER_REG = 0x56,	// upper 8 bits of dac sample interval counter
+	DAC_SELECT_REG = 0x60,
+	DAC_START_REG = 0x64,
+	DAC_BUFFER_CLEAR_REG = 0x66,	// clear dac buffer
+};
+static inline unsigned int dac_convert_reg(unsigned int channel)
+{
+	return 0x70 + (2 * (channel & 0x1));
+}
+static inline unsigned int dac_lsb_4020_reg(unsigned int channel)
+{
+	return 0x70 + (4 * (channel & 0x1));
+}
+static inline unsigned int dac_msb_4020_reg(unsigned int channel)
+{
+	return 0x72 + (4 * (channel & 0x1));
+}
+
+enum read_only_registers {
+	HW_STATUS_REG = 0x0,	// hardware status register, reading this apparently clears pending interrupts as well
+	PIPE1_READ_REG = 0x4,
+	ADC_READ_PNTR_REG = 0x8,
+	LOWER_XFER_REG = 0x10,
+	ADC_WRITE_PNTR_REG = 0xc,
+	PREPOST_REG = 0x14,
+};
+
+enum read_write_registers {
+	I8255_4020_REG = 0x48,	// 8255 offset, for 4020 only
+	ADC_QUEUE_FIFO_REG = 0x100,	// external channel/gain queue, uses same bits as ADC_QUEUE_LOAD_REG
+	ADC_FIFO_REG = 0x200,	/* adc data fifo */
+	DAC_FIFO_REG = 0x300,	/* dac data fifo, has weird interactions with external channel queue */
+};
+
+// priv(dev)->dio_counter_iobase registers
+enum dio_counter_registers {
+	DIO_8255_OFFSET = 0x0,
+	DO_REG = 0x20,
+	DI_REG = 0x28,
+	DIO_DIRECTION_60XX_REG = 0x40,
+	DIO_DATA_60XX_REG = 0x48,
+};
+
+// bit definitions for write-only registers
+
+enum intr_enable_contents {
+	ADC_INTR_SRC_MASK = 0x3,	// bits that set adc interrupt source
+	ADC_INTR_QFULL_BITS = 0x0,	// interrupt fifo quater full
+	ADC_INTR_EOC_BITS = 0x1,	// interrupt end of conversion
+	ADC_INTR_EOSCAN_BITS = 0x2,	// interrupt end of scan
+	ADC_INTR_EOSEQ_BITS = 0x3,	// interrupt end of sequence (probably wont use this it's pretty fancy)
+	EN_ADC_INTR_SRC_BIT = 0x4,	// enable adc interrupt source
+	EN_ADC_DONE_INTR_BIT = 0x8,	// enable adc aquisition done interrupt
+	DAC_INTR_SRC_MASK = 0x30,
+	DAC_INTR_QEMPTY_BITS = 0x0,
+	DAC_INTR_HIGH_CHAN_BITS = 0x10,
+	EN_DAC_INTR_SRC_BIT = 0x40,	// enable dac interrupt source
+	EN_DAC_DONE_INTR_BIT = 0x80,
+	EN_ADC_ACTIVE_INTR_BIT = 0x200,	// enable adc active interrupt
+	EN_ADC_STOP_INTR_BIT = 0x400,	// enable adc stop trigger interrupt
+	EN_DAC_ACTIVE_INTR_BIT = 0x800,	// enable dac active interrupt
+	EN_DAC_UNDERRUN_BIT = 0x4000,	// enable dac underrun status bit
+	EN_ADC_OVERRUN_BIT = 0x8000,	// enable adc overrun status bit
+};
+
+enum hw_config_contents {
+	MASTER_CLOCK_4020_MASK = 0x3,	// bits that specify master clock source for 4020
+	INTERNAL_CLOCK_4020_BITS = 0x1,	// use 40 MHz internal master clock for 4020
+	BNC_CLOCK_4020_BITS = 0x2,	// use BNC input for master clock
+	EXT_CLOCK_4020_BITS = 0x3,	// use dio input for master clock
+	EXT_QUEUE_BIT = 0x200,	// use external channel/gain queue (more versatile than internal queue)
+	SLOW_DAC_BIT = 0x400,	// use 225 nanosec strobe when loading dac instead of 50 nanosec
+	HW_CONFIG_DUMMY_BITS = 0x2000,	// bit with unknown function yet given as default value in pci-das64 manual
+	DMA_CH_SELECT_BIT = 0x8000,	// bit selects channels 1/0 for analog input/output, otherwise 0/1
+	FIFO_SIZE_REG = 0x4,	// allows adjustment of fifo sizes
+	DAC_FIFO_SIZE_MASK = 0xff00,	// bits that set dac fifo size
+	DAC_FIFO_BITS = 0xf800,	/* 8k sample ao fifo */
+};
+#define DAC_FIFO_SIZE 0x2000
+
+enum daq_atrig_low_4020_contents {
+	EXT_AGATE_BNC_BIT = 0x8000,	// use trig/ext clk bnc input for analog gate signal
+	EXT_STOP_TRIG_BNC_BIT = 0x4000,	// use trig/ext clk bnc input for external stop trigger signal
+	EXT_START_TRIG_BNC_BIT = 0x2000,	// use trig/ext clk bnc input for external start trigger signal
+};
+static inline uint16_t analog_trig_low_threshold_bits(uint16_t threshold)
+{
+	return threshold & 0xfff;
+}
+
+enum adc_control0_contents {
+	ADC_GATE_SRC_MASK = 0x3,	// bits that select gate
+	ADC_SOFT_GATE_BITS = 0x1,	// software gate
+	ADC_EXT_GATE_BITS = 0x2,	// external digital gate
+	ADC_ANALOG_GATE_BITS = 0x3,	// analog level gate
+	ADC_GATE_LEVEL_BIT = 0x4,	// level-sensitive gate (for digital)
+	ADC_GATE_POLARITY_BIT = 0x8,	// gate active low
+	ADC_START_TRIG_SOFT_BITS = 0x10,
+	ADC_START_TRIG_EXT_BITS = 0x20,
+	ADC_START_TRIG_ANALOG_BITS = 0x30,
+	ADC_START_TRIG_MASK = 0x30,
+	ADC_START_TRIG_FALLING_BIT = 0x40,	// trig 1 uses falling edge
+	ADC_EXT_CONV_FALLING_BIT = 0x800,	// external pacing uses falling edge
+	ADC_SAMPLE_COUNTER_EN_BIT = 0x1000,	// enable hardware scan counter
+	ADC_DMA_DISABLE_BIT = 0x4000,	// disables dma
+	ADC_ENABLE_BIT = 0x8000,	// master adc enable
+};
+
+enum adc_control1_contents {
+	ADC_QUEUE_CONFIG_BIT = 0x1,	// should be set for boards with > 16 channels
+	CONVERT_POLARITY_BIT = 0x10,
+	EOC_POLARITY_BIT = 0x20,
+	ADC_SW_GATE_BIT = 0x40,	// software gate of adc
+	ADC_DITHER_BIT = 0x200,	// turn on extra noise for dithering
+	RETRIGGER_BIT = 0x800,
+	ADC_LO_CHANNEL_4020_MASK = 0x300,
+	ADC_HI_CHANNEL_4020_MASK = 0xc00,
+	TWO_CHANNEL_4020_BITS = 0x1000,	// two channel mode for 4020
+	FOUR_CHANNEL_4020_BITS = 0x2000,	// four channel mode for 4020
+	CHANNEL_MODE_4020_MASK = 0x3000,
+	ADC_MODE_MASK = 0xf000,
+};
+static inline uint16_t adc_lo_chan_4020_bits(unsigned int channel)
+{
+	return (channel & 0x3) << 8;
+};
+static inline uint16_t adc_hi_chan_4020_bits(unsigned int channel)
+{
+	return (channel & 0x3) << 10;
+};
+static inline uint16_t adc_mode_bits(unsigned int mode)
+{
+	return (mode & 0xf) << 12;
+};
+
+enum calibration_contents {
+	SELECT_8800_BIT = 0x1,
+	SELECT_8402_64XX_BIT = 0x2,
+	SELECT_1590_60XX_BIT = 0x2,
+	CAL_EN_64XX_BIT = 0x40,	// calibration enable for 64xx series
+	SERIAL_DATA_IN_BIT = 0x80,
+	SERIAL_CLOCK_BIT = 0x100,
+	CAL_EN_60XX_BIT = 0x200,	// calibration enable for 60xx series
+	CAL_GAIN_BIT = 0x800,
+};
+/* calibration sources for 6025 are:
+ *  0 : ground
+ *  1 : 10V
+ *  2 : 5V
+ *  3 : 0.5V
+ *  4 : 0.05V
+ *  5 : ground
+ *  6 : dac channel 0
+ *  7 : dac channel 1
+ */
+static inline uint16_t adc_src_bits(unsigned int source)
+{
+	return (source & 0xf) << 3;
+};
+
+static inline uint16_t adc_convert_chan_4020_bits(unsigned int channel)
+{
+	return (channel & 0x3) << 8;
+};
+
+enum adc_queue_load_contents {
+	UNIP_BIT = 0x800,	// unipolar/bipolar bit
+	ADC_SE_DIFF_BIT = 0x1000,	// single-ended/ differential bit
+	ADC_COMMON_BIT = 0x2000,	// non-referenced single-ended (common-mode input)
+	QUEUE_EOSEQ_BIT = 0x4000,	// queue end of sequence
+	QUEUE_EOSCAN_BIT = 0x8000,	// queue end of scan
+};
+static inline uint16_t adc_chan_bits(unsigned int channel)
+{
+	return channel & 0x3f;
+};
+
+enum dac_control0_contents {
+	DAC_ENABLE_BIT = 0x8000,	// dac controller enable bit
+	DAC_CYCLIC_STOP_BIT = 0x4000,
+	DAC_WAVEFORM_MODE_BIT = 0x100,
+	DAC_EXT_UPDATE_FALLING_BIT = 0x80,
+	DAC_EXT_UPDATE_ENABLE_BIT = 0x40,
+	WAVEFORM_TRIG_MASK = 0x30,
+	WAVEFORM_TRIG_DISABLED_BITS = 0x0,
+	WAVEFORM_TRIG_SOFT_BITS = 0x10,
+	WAVEFORM_TRIG_EXT_BITS = 0x20,
+	WAVEFORM_TRIG_ADC1_BITS = 0x30,
+	WAVEFORM_TRIG_FALLING_BIT = 0x8,
+	WAVEFORM_GATE_LEVEL_BIT = 0x4,
+	WAVEFORM_GATE_ENABLE_BIT = 0x2,
+	WAVEFORM_GATE_SELECT_BIT = 0x1,
+};
+
+enum dac_control1_contents {
+	DAC_WRITE_POLARITY_BIT = 0x800,	/* board-dependent setting */
+	DAC1_EXT_REF_BIT = 0x200,
+	DAC0_EXT_REF_BIT = 0x100,
+	DAC_OUTPUT_ENABLE_BIT = 0x80,	// dac output enable bit
+	DAC_UPDATE_POLARITY_BIT = 0x40,	/* board-dependent setting */
+	DAC_SW_GATE_BIT = 0x20,
+	DAC1_UNIPOLAR_BIT = 0x8,
+	DAC0_UNIPOLAR_BIT = 0x2,
+};
+
+// bit definitions for read-only registers
+enum hw_status_contents {
+	DAC_UNDERRUN_BIT = 0x1,
+	ADC_OVERRUN_BIT = 0x2,
+	DAC_ACTIVE_BIT = 0x4,
+	ADC_ACTIVE_BIT = 0x8,
+	DAC_INTR_PENDING_BIT = 0x10,
+	ADC_INTR_PENDING_BIT = 0x20,
+	DAC_DONE_BIT = 0x40,
+	ADC_DONE_BIT = 0x80,
+	EXT_INTR_PENDING_BIT = 0x100,
+	ADC_STOP_BIT = 0x200,
+};
+static inline uint16_t pipe_full_bits(uint16_t hw_status_bits)
+{
+	return (hw_status_bits >> 10) & 0x3;
+};
+
+static inline unsigned int dma_chain_flag_bits(uint16_t prepost_bits)
+{
+	return (prepost_bits >> 6) & 0x3;
+}
+static inline unsigned int adc_upper_read_ptr_code(uint16_t prepost_bits)
+{
+	return (prepost_bits >> 12) & 0x3;
+}
+static inline unsigned int adc_upper_write_ptr_code(uint16_t prepost_bits)
+{
+	return (prepost_bits >> 14) & 0x3;
+}
+
+// I2C addresses for 4020
+enum i2c_addresses {
+	RANGE_CAL_I2C_ADDR = 0x20,
+	CALDAC0_I2C_ADDR = 0xc,
+	CALDAC1_I2C_ADDR = 0xd,
+};
+
+enum range_cal_i2c_contents {
+	ADC_SRC_4020_MASK = 0x70,	// bits that set what source the adc converter measures
+	BNC_TRIG_THRESHOLD_0V_BIT = 0x80,	// make bnc trig/ext clock threshold 0V instead of 2.5V
+};
+static inline uint8_t adc_src_4020_bits(unsigned int source)
+{
+	return (source << 4) & ADC_SRC_4020_MASK;
+};
+static inline uint8_t attenuate_bit(unsigned int channel)
+{
+	// attenuate channel (+-5V input range)
+	return 1 << (channel & 0x3);
+};
+
+// analog input ranges for 64xx boards
+static const struct comedi_lrange ai_ranges_64xx = {
+	8,
+	{
+			BIP_RANGE(10),
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+			UNI_RANGE(10),
+			UNI_RANGE(5),
+			UNI_RANGE(2.5),
+			UNI_RANGE(1.25)
+		}
+};
+
+/* analog input ranges for 60xx boards */
+static const struct comedi_lrange ai_ranges_60xx = {
+	4,
+	{
+			BIP_RANGE(10),
+			BIP_RANGE(5),
+			BIP_RANGE(0.5),
+			BIP_RANGE(0.05),
+		}
+};
+
+/* analog input ranges for 6030, etc boards */
+static const struct comedi_lrange ai_ranges_6030 = {
+	14,
+	{
+			BIP_RANGE(10),
+			BIP_RANGE(5),
+			BIP_RANGE(2),
+			BIP_RANGE(1),
+			BIP_RANGE(0.5),
+			BIP_RANGE(0.2),
+			BIP_RANGE(0.1),
+			UNI_RANGE(10),
+			UNI_RANGE(5),
+			UNI_RANGE(2),
+			UNI_RANGE(1),
+			UNI_RANGE(0.5),
+			UNI_RANGE(0.2),
+			UNI_RANGE(0.1),
+		}
+};
+
+/* analog input ranges for 6052, etc boards */
+static const struct comedi_lrange ai_ranges_6052 = {
+	15,
+	{
+			BIP_RANGE(10),
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1),
+			BIP_RANGE(0.5),
+			BIP_RANGE(0.25),
+			BIP_RANGE(0.1),
+			BIP_RANGE(0.05),
+			UNI_RANGE(10),
+			UNI_RANGE(5),
+			UNI_RANGE(2),
+			UNI_RANGE(1),
+			UNI_RANGE(0.5),
+			UNI_RANGE(0.2),
+			UNI_RANGE(0.1),
+		}
+};
+
+// analog input ranges for 4020 board
+static const struct comedi_lrange ai_ranges_4020 = {
+	2,
+	{
+			BIP_RANGE(5),
+			BIP_RANGE(1),
+		}
+};
+
+// analog output ranges
+static const struct comedi_lrange ao_ranges_64xx = {
+	4,
+	{
+			BIP_RANGE(5),
+			BIP_RANGE(10),
+			UNI_RANGE(5),
+			UNI_RANGE(10),
+		}
+};
+static const int ao_range_code_64xx[] = {
+	0x0,
+	0x1,
+	0x2,
+	0x3,
+};
+
+static const struct comedi_lrange ao_ranges_60xx = {
+	1,
+	{
+			BIP_RANGE(10),
+		}
+};
+static const int ao_range_code_60xx[] = {
+	0x0,
+};
+
+static const struct comedi_lrange ao_ranges_6030 = {
+	2,
+	{
+			BIP_RANGE(10),
+			UNI_RANGE(10),
+		}
+};
+static const int ao_range_code_6030[] = {
+	0x0,
+	0x2,
+};
+
+static const struct comedi_lrange ao_ranges_4020 = {
+	2,
+	{
+			BIP_RANGE(5),
+			BIP_RANGE(10),
+		}
+};
+static const int ao_range_code_4020[] = {
+	0x1,
+	0x0,
+};
+
+enum register_layout {
+	LAYOUT_60XX,
+	LAYOUT_64XX,
+	LAYOUT_4020,
+};
+
+struct hw_fifo_info {
+	unsigned int num_segments;
+	unsigned int max_segment_length;
+	unsigned int sample_packing_ratio;
+	uint16_t fifo_size_reg_mask;
+};
+
+struct pcidas64_board {
+	const char *name;
+	int device_id;		// pci device id
+	int ai_se_chans;	// number of ai inputs in single-ended mode
+	int ai_bits;		// analog input resolution
+	int ai_speed;		// fastest conversion period in ns
+	const struct comedi_lrange *ai_range_table;
+	int ao_nchan;		// number of analog out channels
+	int ao_bits;		// analog output resolution
+	int ao_scan_speed;	// analog output speed (for a scan, not conversion)
+	const struct comedi_lrange *ao_range_table;
+	const int *ao_range_code;
+	const struct hw_fifo_info *const ai_fifo;
+	enum register_layout layout;	// different board families have slightly different registers
+	unsigned has_8255:1;
+};
+
+static const struct hw_fifo_info ai_fifo_4020 = {
+      num_segments:2,
+      max_segment_length:0x8000,
+      sample_packing_ratio:2,
+      fifo_size_reg_mask:0x7f,
+};
+
+static const struct hw_fifo_info ai_fifo_64xx = {
+      num_segments:4,
+      max_segment_length:0x800,
+      sample_packing_ratio:1,
+      fifo_size_reg_mask:0x3f,
+};
+
+static const struct hw_fifo_info ai_fifo_60xx = {
+      num_segments:4,
+      max_segment_length:0x800,
+      sample_packing_ratio:1,
+      fifo_size_reg_mask:0x7f,
+};
+
+/* maximum number of dma transfers we will chain together into a ring
+ * (and the maximum number of dma buffers we maintain) */
+#define MAX_AI_DMA_RING_COUNT (0x80000 / DMA_BUFFER_SIZE)
+#define MIN_AI_DMA_RING_COUNT (0x10000 / DMA_BUFFER_SIZE)
+#define AO_DMA_RING_COUNT (0x10000 / DMA_BUFFER_SIZE)
+static inline unsigned int ai_dma_ring_count(struct pcidas64_board * board)
+{
+	if (board->layout == LAYOUT_4020)
+		return MAX_AI_DMA_RING_COUNT;
+	else
+		return MIN_AI_DMA_RING_COUNT;
+}
+
+static const int bytes_in_sample = 2;
+
+static const struct pcidas64_board pcidas64_boards[] = {
+	{
+	      name:	"pci-das6402/16",
+	      device_id:0x1d,
+	      ai_se_chans:64,
+	      ai_bits:	16,
+	      ai_speed:5000,
+	      ao_nchan:2,
+	      ao_bits:	16,
+	      ao_scan_speed:10000,
+	      layout:	LAYOUT_64XX,
+	      ai_range_table:&ai_ranges_64xx,
+	      ao_range_table:&ao_ranges_64xx,
+	      ao_range_code:ao_range_code_64xx,
+	      ai_fifo:	&ai_fifo_64xx,
+	      has_8255:1,
+		},
+	{
+	      name:	"pci-das6402/12",	// XXX check
+	      device_id:0x1e,
+	      ai_se_chans:64,
+	      ai_bits:	12,
+	      ai_speed:5000,
+	      ao_nchan:2,
+	      ao_bits:	12,
+	      ao_scan_speed:10000,
+	      layout:	LAYOUT_64XX,
+	      ai_range_table:&ai_ranges_64xx,
+	      ao_range_table:&ao_ranges_64xx,
+	      ao_range_code:ao_range_code_64xx,
+	      ai_fifo:	&ai_fifo_64xx,
+	      has_8255:1,
+		},
+	{
+	      name:	"pci-das64/m1/16",
+	      device_id:0x35,
+	      ai_se_chans:64,
+	      ai_bits:	16,
+	      ai_speed:1000,
+	      ao_nchan:2,
+	      ao_bits:	16,
+	      ao_scan_speed:10000,
+	      layout:	LAYOUT_64XX,
+	      ai_range_table:&ai_ranges_64xx,
+	      ao_range_table:&ao_ranges_64xx,
+	      ao_range_code:ao_range_code_64xx,
+	      ai_fifo:	&ai_fifo_64xx,
+	      has_8255:1,
+		},
+	{
+	      name:	"pci-das64/m2/16",
+	      device_id:0x36,
+	      ai_se_chans:64,
+	      ai_bits:	16,
+	      ai_speed:500,
+	      ao_nchan:2,
+	      ao_bits:	16,
+	      ao_scan_speed:10000,
+	      layout:	LAYOUT_64XX,
+	      ai_range_table:&ai_ranges_64xx,
+	      ao_range_table:&ao_ranges_64xx,
+	      ao_range_code:ao_range_code_64xx,
+	      ai_fifo:	&ai_fifo_64xx,
+	      has_8255:1,
+		},
+	{
+	      name:	"pci-das64/m3/16",
+	      device_id:0x37,
+	      ai_se_chans:64,
+	      ai_bits:	16,
+	      ai_speed:333,
+	      ao_nchan:2,
+	      ao_bits:	16,
+	      ao_scan_speed:10000,
+	      layout:	LAYOUT_64XX,
+	      ai_range_table:&ai_ranges_64xx,
+	      ao_range_table:&ao_ranges_64xx,
+	      ao_range_code:ao_range_code_64xx,
+	      ai_fifo:	&ai_fifo_64xx,
+	      has_8255:1,
+		},
+	{
+		.name = "pci-das6013",
+		.device_id = 0x78,
+		.ai_se_chans = 16,
+		.ai_bits = 16,
+		.ai_speed = 5000,
+		.ao_nchan = 0,
+		.ao_bits = 16,
+		.layout = LAYOUT_60XX,
+		.ai_range_table = &ai_ranges_60xx,
+		.ao_range_table = &ao_ranges_60xx,
+		.ao_range_code = ao_range_code_60xx,
+		.ai_fifo = &ai_fifo_60xx,
+		.has_8255 = 0,
+		},
+	{
+	      name:	"pci-das6014",
+	      device_id:0x79,
+	      ai_se_chans:16,
+	      ai_bits:	16,
+	      ai_speed:5000,
+	      ao_nchan:2,
+	      ao_bits:	16,
+	      ao_scan_speed:100000,
+	      layout:	LAYOUT_60XX,
+	      ai_range_table:&ai_ranges_60xx,
+	      ao_range_table:&ao_ranges_60xx,
+	      ao_range_code:ao_range_code_60xx,
+	      ai_fifo:	&ai_fifo_60xx,
+	      has_8255:0,
+		},
+	{
+	      name:	"pci-das6023",
+	      device_id:0x5d,
+	      ai_se_chans:16,
+	      ai_bits:	12,
+	      ai_speed:5000,
+	      ao_nchan:0,
+	      ao_scan_speed:100000,
+	      layout:	LAYOUT_60XX,
+	      ai_range_table:&ai_ranges_60xx,
+	      ao_range_table:&ao_ranges_60xx,
+	      ao_range_code:ao_range_code_60xx,
+	      ai_fifo:	&ai_fifo_60xx,
+	      has_8255:1,
+		},
+	{
+	      name:	"pci-das6025",
+	      device_id:0x5e,
+	      ai_se_chans:16,
+	      ai_bits:	12,
+	      ai_speed:5000,
+	      ao_nchan:2,
+	      ao_bits:	12,
+	      ao_scan_speed:100000,
+	      layout:	LAYOUT_60XX,
+	      ai_range_table:&ai_ranges_60xx,
+	      ao_range_table:&ao_ranges_60xx,
+	      ao_range_code:ao_range_code_60xx,
+	      ai_fifo:	&ai_fifo_60xx,
+	      has_8255:1,
+		},
+	{
+	      name:	"pci-das6030",
+	      device_id:0x5f,
+	      ai_se_chans:16,
+	      ai_bits:	16,
+	      ai_speed:10000,
+	      ao_nchan:2,
+	      ao_bits:	16,
+	      ao_scan_speed:10000,
+	      layout:	LAYOUT_60XX,
+	      ai_range_table:&ai_ranges_6030,
+	      ao_range_table:&ao_ranges_6030,
+	      ao_range_code:ao_range_code_6030,
+	      ai_fifo:	&ai_fifo_60xx,
+	      has_8255:0,
+		},
+	{
+	      name:	"pci-das6031",
+	      device_id:0x60,
+	      ai_se_chans:64,
+	      ai_bits:	16,
+	      ai_speed:10000,
+	      ao_nchan:2,
+	      ao_bits:	16,
+	      ao_scan_speed:10000,
+	      layout:	LAYOUT_60XX,
+	      ai_range_table:&ai_ranges_6030,
+	      ao_range_table:&ao_ranges_6030,
+	      ao_range_code:ao_range_code_6030,
+	      ai_fifo:	&ai_fifo_60xx,
+	      has_8255:0,
+		},
+	{
+	      name:	"pci-das6032",
+	      device_id:0x61,
+	      ai_se_chans:16,
+	      ai_bits:	16,
+	      ai_speed:10000,
+	      ao_nchan:0,
+	      layout:	LAYOUT_60XX,
+	      ai_range_table:&ai_ranges_6030,
+	      ai_fifo:	&ai_fifo_60xx,
+	      has_8255:0,
+		},
+	{
+	      name:	"pci-das6033",
+	      device_id:0x62,
+	      ai_se_chans:64,
+	      ai_bits:	16,
+	      ai_speed:10000,
+	      ao_nchan:0,
+	      layout:	LAYOUT_60XX,
+	      ai_range_table:&ai_ranges_6030,
+	      ai_fifo:	&ai_fifo_60xx,
+	      has_8255:0,
+		},
+	{
+	      name:	"pci-das6034",
+	      device_id:0x63,
+	      ai_se_chans:16,
+	      ai_bits:	16,
+	      ai_speed:5000,
+	      ao_nchan:0,
+	      ao_scan_speed:0,
+	      layout:	LAYOUT_60XX,
+	      ai_range_table:&ai_ranges_60xx,
+	      ai_fifo:	&ai_fifo_60xx,
+	      has_8255:0,
+		},
+	{
+	      name:	"pci-das6035",
+	      device_id:0x64,
+	      ai_se_chans:16,
+	      ai_bits:	16,
+	      ai_speed:5000,
+	      ao_nchan:2,
+	      ao_bits:	12,
+	      ao_scan_speed:100000,
+	      layout:	LAYOUT_60XX,
+	      ai_range_table:&ai_ranges_60xx,
+	      ao_range_table:&ao_ranges_60xx,
+	      ao_range_code:ao_range_code_60xx,
+	      ai_fifo:	&ai_fifo_60xx,
+	      has_8255:0,
+		},
+	{
+	      name:	"pci-das6036",
+	      device_id:0x6f,
+	      ai_se_chans:16,
+	      ai_bits:	16,
+	      ai_speed:5000,
+	      ao_nchan:2,
+	      ao_bits:	16,
+	      ao_scan_speed:100000,
+	      layout:	LAYOUT_60XX,
+	      ai_range_table:&ai_ranges_60xx,
+	      ao_range_table:&ao_ranges_60xx,
+	      ao_range_code:ao_range_code_60xx,
+	      ai_fifo:	&ai_fifo_60xx,
+	      has_8255:0,
+		},
+	{
+	      name:	"pci-das6040",
+	      device_id:0x65,
+	      ai_se_chans:16,
+	      ai_bits:	12,
+	      ai_speed:2000,
+	      ao_nchan:2,
+	      ao_bits:	12,
+	      ao_scan_speed:1000,
+	      layout:	LAYOUT_60XX,
+	      ai_range_table:&ai_ranges_6052,
+	      ao_range_table:&ao_ranges_6030,
+	      ao_range_code:ao_range_code_6030,
+	      ai_fifo:	&ai_fifo_60xx,
+	      has_8255:0,
+		},
+	{
+	      name:	"pci-das6052",
+	      device_id:0x66,
+	      ai_se_chans:16,
+	      ai_bits:	16,
+	      ai_speed:3333,
+	      ao_nchan:2,
+	      ao_bits:	16,
+	      ao_scan_speed:3333,
+	      layout:	LAYOUT_60XX,
+	      ai_range_table:&ai_ranges_6052,
+	      ao_range_table:&ao_ranges_6030,
+	      ao_range_code:ao_range_code_6030,
+	      ai_fifo:	&ai_fifo_60xx,
+	      has_8255:0,
+		},
+	{
+	      name:	"pci-das6070",
+	      device_id:0x67,
+	      ai_se_chans:16,
+	      ai_bits:	12,
+	      ai_speed:800,
+	      ao_nchan:2,
+	      ao_bits:	12,
+	      ao_scan_speed:1000,
+	      layout:	LAYOUT_60XX,
+	      ai_range_table:&ai_ranges_6052,
+	      ao_range_table:&ao_ranges_6030,
+	      ao_range_code:ao_range_code_6030,
+	      ai_fifo:	&ai_fifo_60xx,
+	      has_8255:0,
+		},
+	{
+	      name:	"pci-das6071",
+	      device_id:0x68,
+	      ai_se_chans:64,
+	      ai_bits:	12,
+	      ai_speed:800,
+	      ao_nchan:2,
+	      ao_bits:	12,
+	      ao_scan_speed:1000,
+	      layout:	LAYOUT_60XX,
+	      ai_range_table:&ai_ranges_6052,
+	      ao_range_table:&ao_ranges_6030,
+	      ao_range_code:ao_range_code_6030,
+	      ai_fifo:	&ai_fifo_60xx,
+	      has_8255:0,
+		},
+	{
+	      name:	"pci-das4020/12",
+	      device_id:0x52,
+	      ai_se_chans:4,
+	      ai_bits:	12,
+	      ai_speed:50,
+	      ao_bits:	12,
+	      ao_nchan:2,
+	      ao_scan_speed:0,	// no hardware pacing on ao
+	      layout:	LAYOUT_4020,
+	      ai_range_table:&ai_ranges_4020,
+	      ao_range_table:&ao_ranges_4020,
+	      ao_range_code:ao_range_code_4020,
+	      ai_fifo:	&ai_fifo_4020,
+	      has_8255:1,
+		},
+#if 0
+	{
+	      name:	"pci-das6402/16/jr",
+	      device_id:0	// XXX,
+	      ai_se_chans:64,
+	      ai_bits:	16,
+	      ai_speed:5000,
+	      ao_nchan:0,
+	      ao_scan_speed:10000,
+	      layout:	LAYOUT_64XX,
+	      ai_range_table:&ai_ranges_64xx,
+	      ai_fifo:	ai_fifo_64xx,
+	      has_8255:1,
+		},
+	{
+	      name:	"pci-das64/m1/16/jr",
+	      device_id:0	// XXX,
+	      ai_se_chans:64,
+	      ai_bits:	16,
+	      ai_speed:1000,
+	      ao_nchan:0,
+	      ao_scan_speed:10000,
+	      layout:	LAYOUT_64XX,
+	      ai_range_table:&ai_ranges_64xx,
+	      ai_fifo:	ai_fifo_64xx,
+	      has_8255:1,
+		},
+	{
+	      name:	"pci-das64/m2/16/jr",
+	      device_id:0	// XXX,
+	      ai_se_chans:64,
+	      ai_bits:	16,
+	      ai_speed:500,
+	      ao_nchan:0,
+	      ao_scan_speed:10000,
+	      layout:	LAYOUT_64XX,
+	      ai_range_table:&ai_ranges_64xx,
+	      ai_fifo:	ai_fifo_64xx,
+	      has_8255:1,
+		},
+	{
+	      name:	"pci-das64/m3/16/jr",
+	      device_id:0	// XXX,
+	      ai_se_chans:64,
+	      ai_bits:	16,
+	      ai_speed:333,
+	      ao_nchan:0,
+	      ao_scan_speed:10000,
+	      layout:	LAYOUT_64XX,
+	      ai_range_table:&ai_ranges_64xx,
+	      ai_fifo:	ai_fifo_64xx,
+	      has_8255:1,
+		},
+	{
+	      name:	"pci-das64/m1/14",
+	      device_id:0,	// XXX
+	      ai_se_chans:64,
+	      ai_bits:	14,
+	      ai_speed:1000,
+	      ao_nchan:2,
+	      ao_scan_speed:10000,
+	      layout:	LAYOUT_64XX,
+	      ai_range_table:&ai_ranges_64xx,
+	      ai_fifo:	ai_fifo_64xx,
+	      has_8255:1,
+		},
+	{
+	      name:	"pci-das64/m2/14",
+	      device_id:0,	// XXX
+	      ai_se_chans:64,
+	      ai_bits:	14,
+	      ai_speed:500,
+	      ao_nchan:2,
+	      ao_scan_speed:10000,
+	      layout:	LAYOUT_64XX,
+	      ai_range_table:&ai_ranges_64xx,
+	      ai_fifo:	ai_fifo_64xx,
+	      has_8255:1,
+		},
+	{
+	      name:	"pci-das64/m3/14",
+	      device_id:0,	// XXX
+	      ai_se_chans:64,
+	      ai_bits:	14,
+	      ai_speed:333,
+	      ao_nchan:2,
+	      ao_scan_speed:10000,
+	      layout:	LAYOUT_64XX,
+	      ai_range_table:&ai_ranges_64xx,
+	      ai_fifo:	ai_fifo_64xx,
+	      has_8255:1,
+		},
+#endif
+};
+
+// Number of boards in cb_pcidas_boards
+static inline unsigned int num_boards(void)
+{
+	return sizeof(pcidas64_boards) / sizeof(struct pcidas64_board);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(pcidas64_pci_table) = {
+	{PCI_VENDOR_ID_COMPUTERBOARDS, 0x001d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_COMPUTERBOARDS, 0x001e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_COMPUTERBOARDS, 0x0035, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_COMPUTERBOARDS, 0x0036, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_COMPUTERBOARDS, 0x0037, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_COMPUTERBOARDS, 0x0052, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_COMPUTERBOARDS, 0x005d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_COMPUTERBOARDS, 0x005e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_COMPUTERBOARDS, 0x005f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_COMPUTERBOARDS, 0x0061, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_COMPUTERBOARDS, 0x0062, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_COMPUTERBOARDS, 0x0063, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_COMPUTERBOARDS, 0x0064, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_COMPUTERBOARDS, 0x0066, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_COMPUTERBOARDS, 0x0067, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_COMPUTERBOARDS, 0x0068, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_COMPUTERBOARDS, 0x006f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_COMPUTERBOARDS, 0x0078, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_COMPUTERBOARDS, 0x0079, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, pcidas64_pci_table);
+
+static inline struct pcidas64_board *board(const struct comedi_device * dev)
+{
+	return (struct pcidas64_board *) dev->board_ptr;
+}
+
+static inline unsigned short se_diff_bit_6xxx(struct comedi_device * dev,
+	int use_differential)
+{
+	if ((board(dev)->layout == LAYOUT_64XX && !use_differential) ||
+		(board(dev)->layout == LAYOUT_60XX && use_differential))
+		return ADC_SE_DIFF_BIT;
+	else
+		return 0;
+};
+
+struct ext_clock_info {
+	unsigned int divisor;	// master clock divisor to use for scans with external master clock
+	unsigned int chanspec;	// chanspec for master clock input when used as scan begin src
+};
+
+/* this structure is for data unique to this hardware driver. */
+struct pcidas64_private {
+
+	struct pci_dev *hw_dev;	// pointer to board's pci_dev struct
+	// base addresses (physical)
+	resource_size_t plx9080_phys_iobase;
+	resource_size_t main_phys_iobase;
+	resource_size_t dio_counter_phys_iobase;
+	// base addresses (ioremapped)
+	void *plx9080_iobase;
+	void *main_iobase;
+	void *dio_counter_iobase;
+	// local address (used by dma controller)
+	uint32_t local0_iobase;
+	uint32_t local1_iobase;
+	volatile unsigned int ai_count;	// number of analog input samples remaining
+	uint16_t *ai_buffer[MAX_AI_DMA_RING_COUNT];	// dma buffers for analog input
+	dma_addr_t ai_buffer_bus_addr[MAX_AI_DMA_RING_COUNT];	// physical addresses of ai dma buffers
+	struct plx_dma_desc *ai_dma_desc;	// array of ai dma descriptors read by plx9080, allocated to get proper alignment
+	dma_addr_t ai_dma_desc_bus_addr;	// physical address of ai dma descriptor array
+	volatile unsigned int ai_dma_index;	// index of the ai dma descriptor/buffer that is currently being used
+	uint16_t *ao_buffer[AO_DMA_RING_COUNT];	// dma buffers for analog output
+	dma_addr_t ao_buffer_bus_addr[AO_DMA_RING_COUNT];	// physical addresses of ao dma buffers
+	struct plx_dma_desc *ao_dma_desc;
+	dma_addr_t ao_dma_desc_bus_addr;
+	volatile unsigned int ao_dma_index;	// keeps track of buffer where the next ao sample should go
+	volatile unsigned long ao_count;	// number of analog output samples remaining
+	volatile unsigned int ao_value[2];	// remember what the analog outputs are set to, to allow readback
+	unsigned int hw_revision;	// stc chip hardware revision number
+	volatile unsigned int intr_enable_bits;	// last bits sent to INTR_ENABLE_REG register
+	volatile uint16_t adc_control1_bits;	// last bits sent to ADC_CONTROL1_REG register
+	volatile uint16_t fifo_size_bits;	// last bits sent to FIFO_SIZE_REG register
+	volatile uint16_t hw_config_bits;	// last bits sent to HW_CONFIG_REG register
+	volatile uint16_t dac_control1_bits;
+	volatile uint32_t plx_control_bits;	// last bits written to plx9080 control register
+	volatile uint32_t plx_intcsr_bits;	// last bits written to plx interrupt control and status register
+	volatile int calibration_source;	// index of calibration source readable through ai ch0
+	volatile uint8_t i2c_cal_range_bits;	// bits written to i2c calibration/range register
+	volatile unsigned int ext_trig_falling;	// configure digital triggers to trigger on falling edge
+	// states of various devices stored to enable read-back
+	unsigned int ad8402_state[2];
+	unsigned int caldac_state[8];
+	volatile short ai_cmd_running;
+	unsigned int ai_fifo_segment_length;
+	struct ext_clock_info ext_clock;
+	short ao_bounce_buffer[DAC_FIFO_SIZE];
+};
+
+
+/* inline function that makes it easier to
+ * access the private structure.
+ */
+static inline struct pcidas64_private *priv(struct comedi_device * dev)
+{
+	return dev->private;
+}
+
+/*
+ * The comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int detach(struct comedi_device * dev);
+static struct comedi_driver driver_cb_pcidas = {
+      driver_name:"cb_pcidas64",
+      module:THIS_MODULE,
+      attach:attach,
+      detach:detach,
+};
+
+static int ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int ai_config_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int ao_readback_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd);
+static int ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int ao_inttrig(struct comedi_device * dev, struct comedi_subdevice * subdev,
+	unsigned int trig_num);
+static int ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd);
+static irqreturn_t handle_interrupt(int irq, void *d PT_REGS_ARG);
+static int ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static int ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static int dio_callback(int dir, int port, int data, unsigned long arg);
+static int dio_callback_4020(int dir, int port, int data, unsigned long arg);
+static int di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int dio_60xx_config_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int dio_60xx_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int calib_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int calib_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int ad8402_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static void ad8402_write(struct comedi_device * dev, unsigned int channel,
+	unsigned int value);
+static int ad8402_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int eeprom_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static void check_adc_timing(struct comedi_device * dev, struct comedi_cmd * cmd);
+static unsigned int get_divisor(unsigned int ns, unsigned int flags);
+static void i2c_write(struct comedi_device * dev, unsigned int address,
+	const uint8_t * data, unsigned int length);
+static void caldac_write(struct comedi_device * dev, unsigned int channel,
+	unsigned int value);
+static int caldac_8800_write(struct comedi_device * dev, unsigned int address,
+	uint8_t value);
+//static int dac_1590_write(struct comedi_device *dev, unsigned int dac_a, unsigned int dac_b);
+static int caldac_i2c_write(struct comedi_device * dev, unsigned int caldac_channel,
+	unsigned int value);
+static void abort_dma(struct comedi_device * dev, unsigned int channel);
+static void disable_plx_interrupts(struct comedi_device * dev);
+static int set_ai_fifo_size(struct comedi_device * dev, unsigned int num_samples);
+static unsigned int ai_fifo_size(struct comedi_device * dev);
+static int set_ai_fifo_segment_length(struct comedi_device * dev,
+	unsigned int num_entries);
+static void disable_ai_pacing(struct comedi_device * dev);
+static void disable_ai_interrupts(struct comedi_device * dev);
+static void enable_ai_interrupts(struct comedi_device * dev, const struct comedi_cmd * cmd);
+static unsigned int get_ao_divisor(unsigned int ns, unsigned int flags);
+static void load_ao_dma(struct comedi_device * dev, const struct comedi_cmd * cmd);
+
+COMEDI_PCI_INITCLEANUP(driver_cb_pcidas, pcidas64_pci_table);
+
+static unsigned int ai_range_bits_6xxx(const struct comedi_device * dev,
+	unsigned int range_index)
+{
+	const struct comedi_krange *range =
+		&board(dev)->ai_range_table->range[range_index];
+	unsigned int bits = 0;
+
+	switch (range->max) {
+	case 10000000:
+		bits = 0x000;
+		break;
+	case 5000000:
+		bits = 0x100;
+		break;
+	case 2000000:
+	case 2500000:
+		bits = 0x200;
+		break;
+	case 1000000:
+	case 1250000:
+		bits = 0x300;
+		break;
+	case 500000:
+		bits = 0x400;
+		break;
+	case 200000:
+	case 250000:
+		bits = 0x500;
+		break;
+	case 100000:
+		bits = 0x600;
+		break;
+	case 50000:
+		bits = 0x700;
+		break;
+	default:
+		comedi_error(dev, "bug! in ai_range_bits_6xxx");
+		break;
+	}
+	if (range->min == 0)
+		bits += 0x900;
+	return bits;
+}
+
+static unsigned int hw_revision(const struct comedi_device * dev,
+	uint16_t hw_status_bits)
+{
+	if (board(dev)->layout == LAYOUT_4020)
+		return (hw_status_bits >> 13) & 0x7;
+
+	return (hw_status_bits >> 12) & 0xf;
+}
+
+static void set_dac_range_bits(struct comedi_device * dev, volatile uint16_t * bits,
+	unsigned int channel, unsigned int range)
+{
+	unsigned int code = board(dev)->ao_range_code[range];
+
+	if (channel > 1)
+		comedi_error(dev, "bug! bad channel?");
+	if (code & ~0x3)
+		comedi_error(dev, "bug! bad range code?");
+
+	*bits &= ~(0x3 << (2 * channel));
+	*bits |= code << (2 * channel);
+};
+
+static inline int ao_cmd_is_supported(const struct pcidas64_board * board)
+{
+	return board->ao_nchan && board->layout != LAYOUT_4020;
+}
+
+// initialize plx9080 chip
+static void init_plx9080(struct comedi_device * dev)
+{
+	uint32_t bits;
+	void *plx_iobase = priv(dev)->plx9080_iobase;
+
+	priv(dev)->plx_control_bits =
+		readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG);
+
+	// plx9080 dump
+	DEBUG_PRINT(" plx interrupt status 0x%x\n",
+		readl(plx_iobase + PLX_INTRCS_REG));
+	DEBUG_PRINT(" plx id bits 0x%x\n", readl(plx_iobase + PLX_ID_REG));
+	DEBUG_PRINT(" plx control reg 0x%x\n", priv(dev)->plx_control_bits);
+	DEBUG_PRINT(" plx mode/arbitration reg 0x%x\n",
+		readl(plx_iobase + PLX_MARB_REG));
+	DEBUG_PRINT(" plx region0 reg 0x%x\n",
+		readl(plx_iobase + PLX_REGION0_REG));
+	DEBUG_PRINT(" plx region1 reg 0x%x\n",
+		readl(plx_iobase + PLX_REGION1_REG));
+
+	DEBUG_PRINT(" plx revision 0x%x\n",
+		readl(plx_iobase + PLX_REVISION_REG));
+	DEBUG_PRINT(" plx dma channel 0 mode 0x%x\n",
+		readl(plx_iobase + PLX_DMA0_MODE_REG));
+	DEBUG_PRINT(" plx dma channel 1 mode 0x%x\n",
+		readl(plx_iobase + PLX_DMA1_MODE_REG));
+	DEBUG_PRINT(" plx dma channel 0 pci address 0x%x\n",
+		readl(plx_iobase + PLX_DMA0_PCI_ADDRESS_REG));
+	DEBUG_PRINT(" plx dma channel 0 local address 0x%x\n",
+		readl(plx_iobase + PLX_DMA0_LOCAL_ADDRESS_REG));
+	DEBUG_PRINT(" plx dma channel 0 transfer size 0x%x\n",
+		readl(plx_iobase + PLX_DMA0_TRANSFER_SIZE_REG));
+	DEBUG_PRINT(" plx dma channel 0 descriptor 0x%x\n",
+		readl(plx_iobase + PLX_DMA0_DESCRIPTOR_REG));
+	DEBUG_PRINT(" plx dma channel 0 command status 0x%x\n",
+		readb(plx_iobase + PLX_DMA0_CS_REG));
+	DEBUG_PRINT(" plx dma channel 0 threshold 0x%x\n",
+		readl(plx_iobase + PLX_DMA0_THRESHOLD_REG));
+	DEBUG_PRINT(" plx bigend 0x%x\n", readl(plx_iobase + PLX_BIGEND_REG));
+
+#ifdef __BIG_ENDIAN
+	bits = BIGEND_DMA0 | BIGEND_DMA1;
+#else
+	bits = 0;
+#endif
+	writel(bits, priv(dev)->plx9080_iobase + PLX_BIGEND_REG);
+
+	disable_plx_interrupts(dev);
+
+	abort_dma(dev, 0);
+	abort_dma(dev, 1);
+
+	// configure dma0 mode
+	bits = 0;
+	// enable ready input, not sure if this is necessary
+	bits |= PLX_DMA_EN_READYIN_BIT;
+	// enable bterm, not sure if this is necessary
+	bits |= PLX_EN_BTERM_BIT;
+	// enable dma chaining
+	bits |= PLX_EN_CHAIN_BIT;
+	// enable interrupt on dma done (probably don't need this, since chain never finishes)
+	bits |= PLX_EN_DMA_DONE_INTR_BIT;
+	// don't increment local address during transfers (we are transferring from a fixed fifo register)
+	bits |= PLX_LOCAL_ADDR_CONST_BIT;
+	// route dma interrupt to pci bus
+	bits |= PLX_DMA_INTR_PCI_BIT;
+	// enable demand mode
+	bits |= PLX_DEMAND_MODE_BIT;
+	// enable local burst mode
+	bits |= PLX_DMA_LOCAL_BURST_EN_BIT;
+	// 4020 uses 32 bit dma
+	if (board(dev)->layout == LAYOUT_4020) {
+		bits |= PLX_LOCAL_BUS_32_WIDE_BITS;
+	} else {		// localspace0 bus is 16 bits wide
+		bits |= PLX_LOCAL_BUS_16_WIDE_BITS;
+	}
+	writel(bits, plx_iobase + PLX_DMA1_MODE_REG);
+	if (ao_cmd_is_supported(board(dev)))
+		writel(bits, plx_iobase + PLX_DMA0_MODE_REG);
+
+	// enable interrupts on plx 9080
+	priv(dev)->plx_intcsr_bits |=
+		ICS_AERR | ICS_PERR | ICS_PIE | ICS_PLIE | ICS_PAIE | ICS_LIE |
+		ICS_DMA0_E | ICS_DMA1_E;
+	writel(priv(dev)->plx_intcsr_bits,
+		priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
+}
+
+/* Allocate and initialize the subdevice structures.
+ */
+static int setup_subdevices(struct comedi_device * dev)
+{
+	struct comedi_subdevice *s;
+	void *dio_8255_iobase;
+	int i;
+
+	if (alloc_subdevices(dev, 10) < 0)
+		return -ENOMEM;
+
+	s = dev->subdevices + 0;
+	/* analog input subdevice */
+	dev->read_subdev = s;
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DITHER | SDF_CMD_READ;
+	if (board(dev)->layout == LAYOUT_60XX)
+		s->subdev_flags |= SDF_COMMON | SDF_DIFF;
+	else if (board(dev)->layout == LAYOUT_64XX)
+		s->subdev_flags |= SDF_DIFF;
+	/* XXX Number of inputs in differential mode is ignored */
+	s->n_chan = board(dev)->ai_se_chans;
+	s->len_chanlist = 0x2000;
+	s->maxdata = (1 << board(dev)->ai_bits) - 1;
+	s->range_table = board(dev)->ai_range_table;
+	s->insn_read = ai_rinsn;
+	s->insn_config = ai_config_insn;
+	s->do_cmd = ai_cmd;
+	s->do_cmdtest = ai_cmdtest;
+	s->cancel = ai_cancel;
+	if (board(dev)->layout == LAYOUT_4020) {
+		unsigned int i;
+		uint8_t data;
+		// set adc to read from inputs (not internal calibration sources)
+		priv(dev)->i2c_cal_range_bits = adc_src_4020_bits(4);
+		// set channels to +-5 volt input ranges
+		for (i = 0; i < s->n_chan; i++)
+			priv(dev)->i2c_cal_range_bits |= attenuate_bit(i);
+		data = priv(dev)->i2c_cal_range_bits;
+		i2c_write(dev, RANGE_CAL_I2C_ADDR, &data, sizeof(data));
+	}
+
+	/* analog output subdevice */
+	s = dev->subdevices + 1;
+	if (board(dev)->ao_nchan) {
+		s->type = COMEDI_SUBD_AO;
+		s->subdev_flags =
+			SDF_READABLE | SDF_WRITABLE | SDF_GROUND |
+			SDF_CMD_WRITE;
+		s->n_chan = board(dev)->ao_nchan;
+		s->maxdata = (1 << board(dev)->ao_bits) - 1;
+		s->range_table = board(dev)->ao_range_table;
+		s->insn_read = ao_readback_insn;
+		s->insn_write = ao_winsn;
+		if (ao_cmd_is_supported(board(dev))) {
+			dev->write_subdev = s;
+			s->do_cmdtest = ao_cmdtest;
+			s->do_cmd = ao_cmd;
+			s->len_chanlist = board(dev)->ao_nchan;
+			s->cancel = ao_cancel;
+		}
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	// digital input
+	s = dev->subdevices + 2;
+	if (board(dev)->layout == LAYOUT_64XX) {
+		s->type = COMEDI_SUBD_DI;
+		s->subdev_flags = SDF_READABLE;
+		s->n_chan = 4;
+		s->maxdata = 1;
+		s->range_table = &range_digital;
+		s->insn_bits = di_rbits;
+	} else
+		s->type = COMEDI_SUBD_UNUSED;
+
+	// digital output
+	if (board(dev)->layout == LAYOUT_64XX) {
+		s = dev->subdevices + 3;
+		s->type = COMEDI_SUBD_DO;
+		s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+		s->n_chan = 4;
+		s->maxdata = 1;
+		s->range_table = &range_digital;
+		s->insn_bits = do_wbits;
+	} else
+		s->type = COMEDI_SUBD_UNUSED;
+
+	/* 8255 */
+	s = dev->subdevices + 4;
+	if (board(dev)->has_8255) {
+		if (board(dev)->layout == LAYOUT_4020) {
+			dio_8255_iobase =
+				priv(dev)->main_iobase + I8255_4020_REG;
+			subdev_8255_init(dev, s, dio_callback_4020,
+				(unsigned long)dio_8255_iobase);
+		} else {
+			dio_8255_iobase =
+				priv(dev)->dio_counter_iobase + DIO_8255_OFFSET;
+			subdev_8255_init(dev, s, dio_callback,
+				(unsigned long)dio_8255_iobase);
+		}
+	} else
+		s->type = COMEDI_SUBD_UNUSED;
+
+	// 8 channel dio for 60xx
+	s = dev->subdevices + 5;
+	if (board(dev)->layout == LAYOUT_60XX) {
+		s->type = COMEDI_SUBD_DIO;
+		s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+		s->n_chan = 8;
+		s->maxdata = 1;
+		s->range_table = &range_digital;
+		s->insn_config = dio_60xx_config_insn;
+		s->insn_bits = dio_60xx_wbits;
+	} else
+		s->type = COMEDI_SUBD_UNUSED;
+
+	// caldac
+	s = dev->subdevices + 6;
+	s->type = COMEDI_SUBD_CALIB;
+	s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+	s->n_chan = 8;
+	if (board(dev)->layout == LAYOUT_4020)
+		s->maxdata = 0xfff;
+	else
+		s->maxdata = 0xff;
+	s->insn_read = calib_read_insn;
+	s->insn_write = calib_write_insn;
+	for (i = 0; i < s->n_chan; i++)
+		caldac_write(dev, i, s->maxdata / 2);
+
+	// 2 channel ad8402 potentiometer
+	s = dev->subdevices + 7;
+	if (board(dev)->layout == LAYOUT_64XX) {
+		s->type = COMEDI_SUBD_CALIB;
+		s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+		s->n_chan = 2;
+		s->insn_read = ad8402_read_insn;
+		s->insn_write = ad8402_write_insn;
+		s->maxdata = 0xff;
+		for (i = 0; i < s->n_chan; i++)
+			ad8402_write(dev, i, s->maxdata / 2);
+	} else
+		s->type = COMEDI_SUBD_UNUSED;
+
+	//serial EEPROM, if present
+	s = dev->subdevices + 8;
+	if (readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG) & CTL_EECHK) {
+		s->type = COMEDI_SUBD_MEMORY;
+		s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
+		s->n_chan = 128;
+		s->maxdata = 0xffff;
+		s->insn_read = eeprom_read_insn;
+	} else
+		s->type = COMEDI_SUBD_UNUSED;
+
+	// user counter subd XXX
+	s = dev->subdevices + 9;
+	s->type = COMEDI_SUBD_UNUSED;
+
+	return 0;
+}
+
+static void disable_plx_interrupts(struct comedi_device * dev)
+{
+	priv(dev)->plx_intcsr_bits = 0;
+	writel(priv(dev)->plx_intcsr_bits,
+		priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
+}
+
+static void init_stc_registers(struct comedi_device * dev)
+{
+	uint16_t bits;
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+
+	// bit should be set for 6025, although docs say boards with <= 16 chans should be cleared XXX
+	if (1)
+		priv(dev)->adc_control1_bits |= ADC_QUEUE_CONFIG_BIT;
+	writew(priv(dev)->adc_control1_bits,
+		priv(dev)->main_iobase + ADC_CONTROL1_REG);
+
+	// 6402/16 manual says this register must be initialized to 0xff?
+	writew(0xff, priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
+
+	bits = SLOW_DAC_BIT | DMA_CH_SELECT_BIT;
+	if (board(dev)->layout == LAYOUT_4020)
+		bits |= INTERNAL_CLOCK_4020_BITS;
+	priv(dev)->hw_config_bits |= bits;
+	writew(priv(dev)->hw_config_bits,
+		priv(dev)->main_iobase + HW_CONFIG_REG);
+
+	writew(0, priv(dev)->main_iobase + DAQ_SYNC_REG);
+	writew(0, priv(dev)->main_iobase + CALIBRATION_REG);
+
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	// set fifos to maximum size
+	priv(dev)->fifo_size_bits |= DAC_FIFO_BITS;
+	set_ai_fifo_segment_length(dev,
+		board(dev)->ai_fifo->max_segment_length);
+
+	priv(dev)->dac_control1_bits = DAC_OUTPUT_ENABLE_BIT;
+	priv(dev)->intr_enable_bits =	/* EN_DAC_INTR_SRC_BIT | DAC_INTR_QEMPTY_BITS | */
+		EN_DAC_DONE_INTR_BIT | EN_DAC_UNDERRUN_BIT;
+	writew(priv(dev)->intr_enable_bits,
+		priv(dev)->main_iobase + INTR_ENABLE_REG);
+
+	disable_ai_pacing(dev);
+};
+
+int alloc_and_init_dma_members(struct comedi_device * dev)
+{
+	int i;
+
+	// alocate pci dma buffers
+	for (i = 0; i < ai_dma_ring_count(board(dev)); i++) {
+		priv(dev)->ai_buffer[i] =
+			pci_alloc_consistent(priv(dev)->hw_dev, DMA_BUFFER_SIZE,
+			&priv(dev)->ai_buffer_bus_addr[i]);
+		if (priv(dev)->ai_buffer[i] == NULL) {
+			return -ENOMEM;
+		}
+	}
+	for (i = 0; i < AO_DMA_RING_COUNT; i++) {
+		if (ao_cmd_is_supported(board(dev))) {
+			priv(dev)->ao_buffer[i] =
+				pci_alloc_consistent(priv(dev)->hw_dev,
+				DMA_BUFFER_SIZE,
+				&priv(dev)->ao_buffer_bus_addr[i]);
+			if (priv(dev)->ao_buffer[i] == NULL) {
+				return -ENOMEM;
+			}
+		}
+	}
+	// allocate dma descriptors
+	priv(dev)->ai_dma_desc =
+		pci_alloc_consistent(priv(dev)->hw_dev,
+		sizeof(struct plx_dma_desc) * ai_dma_ring_count(board(dev)),
+		&priv(dev)->ai_dma_desc_bus_addr);
+	if (priv(dev)->ai_dma_desc == NULL) {
+		return -ENOMEM;
+	}
+	DEBUG_PRINT("ai dma descriptors start at bus addr 0x%x\n",
+		priv(dev)->ai_dma_desc_bus_addr);
+	if (ao_cmd_is_supported(board(dev))) {
+		priv(dev)->ao_dma_desc =
+			pci_alloc_consistent(priv(dev)->hw_dev,
+			sizeof(struct plx_dma_desc) * AO_DMA_RING_COUNT,
+			&priv(dev)->ao_dma_desc_bus_addr);
+		if (priv(dev)->ao_dma_desc == NULL) {
+			return -ENOMEM;
+		}
+		DEBUG_PRINT("ao dma descriptors start at bus addr 0x%x\n",
+			priv(dev)->ao_dma_desc_bus_addr);
+	}
+	// initialize dma descriptors
+	for (i = 0; i < ai_dma_ring_count(board(dev)); i++) {
+		priv(dev)->ai_dma_desc[i].pci_start_addr =
+			cpu_to_le32(priv(dev)->ai_buffer_bus_addr[i]);
+		if (board(dev)->layout == LAYOUT_4020)
+			priv(dev)->ai_dma_desc[i].local_start_addr =
+				cpu_to_le32(priv(dev)->local1_iobase +
+				ADC_FIFO_REG);
+		else
+			priv(dev)->ai_dma_desc[i].local_start_addr =
+				cpu_to_le32(priv(dev)->local0_iobase +
+				ADC_FIFO_REG);
+		priv(dev)->ai_dma_desc[i].transfer_size = cpu_to_le32(0);
+		priv(dev)->ai_dma_desc[i].next =
+			cpu_to_le32((priv(dev)->ai_dma_desc_bus_addr + ((i +
+						1) %
+					ai_dma_ring_count(board(dev))) *
+				sizeof(priv(dev)->
+					ai_dma_desc[0])) | PLX_DESC_IN_PCI_BIT |
+			PLX_INTR_TERM_COUNT | PLX_XFER_LOCAL_TO_PCI);
+	}
+	if (ao_cmd_is_supported(board(dev))) {
+		for (i = 0; i < AO_DMA_RING_COUNT; i++) {
+			priv(dev)->ao_dma_desc[i].pci_start_addr =
+				cpu_to_le32(priv(dev)->ao_buffer_bus_addr[i]);
+			priv(dev)->ao_dma_desc[i].local_start_addr =
+				cpu_to_le32(priv(dev)->local0_iobase +
+				DAC_FIFO_REG);
+			priv(dev)->ao_dma_desc[i].transfer_size =
+				cpu_to_le32(0);
+			priv(dev)->ao_dma_desc[i].next =
+				cpu_to_le32((priv(dev)->ao_dma_desc_bus_addr +
+					((i + 1) % (AO_DMA_RING_COUNT)) *
+					sizeof(priv(dev)->
+						ao_dma_desc[0])) |
+				PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT);
+		}
+	}
+	return 0;
+}
+
+static inline void warn_external_queue(struct comedi_device * dev)
+{
+	comedi_error(dev,
+		"AO command and AI external channel queue cannot be used simultaneously.");
+	comedi_error(dev,
+		"Use internal AI channel queue (channels must be consecutive and use same range/aref)");
+}
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board.
+ */
+static int attach(struct comedi_device *dev, struct comedi_devconfig *it)
+{
+	struct pci_dev *pcidev;
+	int index;
+	uint32_t local_range, local_decode;
+	int retval;
+
+	printk("comedi%d: cb_pcidas64\n", dev->minor);
+
+/*
+ * Allocate the private structure area.
+ */
+	if (alloc_private(dev, sizeof(struct pcidas64_private)) < 0)
+		return -ENOMEM;
+
+/*
+ * Probe the device to determine what device in the series it is.
+ */
+
+	for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+		pcidev != NULL;
+		pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+		// is it not a computer boards card?
+		if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS)
+			continue;
+		// loop through cards supported by this driver
+		for (index = 0; index < num_boards(); index++) {
+			if (pcidas64_boards[index].device_id != pcidev->device)
+				continue;
+			// was a particular bus/slot requested?
+			if (it->options[0] || it->options[1]) {
+				// are we on the wrong bus/slot?
+				if (pcidev->bus->number != it->options[0] ||
+					PCI_SLOT(pcidev->devfn) !=
+					it->options[1]) {
+					continue;
+				}
+			}
+			priv(dev)->hw_dev = pcidev;
+			dev->board_ptr = pcidas64_boards + index;
+			break;
+		}
+		if (dev->board_ptr)
+			break;
+	}
+
+	if (dev->board_ptr == NULL) {
+		printk("No supported ComputerBoards/MeasurementComputing card found\n");
+		return -EIO;
+	}
+
+	printk("Found %s on bus %i, slot %i\n", board(dev)->name,
+		pcidev->bus->number, PCI_SLOT(pcidev->devfn));
+
+	if (comedi_pci_enable(pcidev, driver_cb_pcidas.driver_name)) {
+		printk(KERN_WARNING
+			" failed to enable PCI device and request regions\n");
+		return -EIO;
+	}
+	pci_set_master(pcidev);
+
+	//Initialize dev->board_name
+	dev->board_name = board(dev)->name;
+
+	priv(dev)->plx9080_phys_iobase =
+		pci_resource_start(pcidev, PLX9080_BADDRINDEX);
+	priv(dev)->main_phys_iobase =
+		pci_resource_start(pcidev, MAIN_BADDRINDEX);
+	priv(dev)->dio_counter_phys_iobase =
+		pci_resource_start(pcidev, DIO_COUNTER_BADDRINDEX);
+
+	// remap, won't work with 2.0 kernels but who cares
+	priv(dev)->plx9080_iobase = ioremap(priv(dev)->plx9080_phys_iobase,
+		pci_resource_len(pcidev, PLX9080_BADDRINDEX));
+	priv(dev)->main_iobase = ioremap(priv(dev)->main_phys_iobase,
+		pci_resource_len(pcidev, MAIN_BADDRINDEX));
+	priv(dev)->dio_counter_iobase =
+		ioremap(priv(dev)->dio_counter_phys_iobase,
+		pci_resource_len(pcidev, DIO_COUNTER_BADDRINDEX));
+
+	if (!priv(dev)->plx9080_iobase || !priv(dev)->main_iobase
+		|| !priv(dev)->dio_counter_iobase) {
+		printk(" failed to remap io memory\n");
+		return -ENOMEM;
+	}
+
+	DEBUG_PRINT(" plx9080 remapped to 0x%p\n", priv(dev)->plx9080_iobase);
+	DEBUG_PRINT(" main remapped to 0x%p\n", priv(dev)->main_iobase);
+	DEBUG_PRINT(" diocounter remapped to 0x%p\n",
+		priv(dev)->dio_counter_iobase);
+
+	// figure out what local addresses are
+	local_range =
+		readl(priv(dev)->plx9080_iobase +
+		PLX_LAS0RNG_REG) & LRNG_MEM_MASK;
+	local_decode =
+		readl(priv(dev)->plx9080_iobase +
+		PLX_LAS0MAP_REG) & local_range & LMAP_MEM_MASK;
+	priv(dev)->local0_iobase =
+		((uint32_t) priv(dev)->
+		main_phys_iobase & ~local_range) | local_decode;
+	local_range =
+		readl(priv(dev)->plx9080_iobase +
+		PLX_LAS1RNG_REG) & LRNG_MEM_MASK;
+	local_decode =
+		readl(priv(dev)->plx9080_iobase +
+		PLX_LAS1MAP_REG) & local_range & LMAP_MEM_MASK;
+	priv(dev)->local1_iobase =
+		((uint32_t) priv(dev)->
+		dio_counter_phys_iobase & ~local_range) | local_decode;
+
+	DEBUG_PRINT(" local 0 io addr 0x%x\n", priv(dev)->local0_iobase);
+	DEBUG_PRINT(" local 1 io addr 0x%x\n", priv(dev)->local1_iobase);
+
+	retval = alloc_and_init_dma_members(dev);
+	if (retval < 0)
+		return retval;
+
+	priv(dev)->hw_revision =
+		hw_revision(dev, readw(priv(dev)->main_iobase + HW_STATUS_REG));
+	printk(" stc hardware revision %i\n", priv(dev)->hw_revision);
+	init_plx9080(dev);
+	init_stc_registers(dev);
+	// get irq
+	if (comedi_request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED,
+			"cb_pcidas64", dev)) {
+		printk(" unable to allocate irq %u\n", pcidev->irq);
+		return -EINVAL;
+	}
+	dev->irq = pcidev->irq;
+	printk(" irq %u\n", dev->irq);
+
+	retval = setup_subdevices(dev);
+	if (retval < 0) {
+		return retval;
+	}
+
+	return 0;
+}
+
+/*
+ * _detach is called to deconfigure a device.  It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach().  dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int detach(struct comedi_device * dev)
+{
+	unsigned int i;
+
+	printk("comedi%d: cb_pcidas: remove\n", dev->minor);
+
+	if (dev->irq)
+		comedi_free_irq(dev->irq, dev);
+	if (priv(dev)) {
+		if (priv(dev)->hw_dev) {
+			if (priv(dev)->plx9080_iobase) {
+				disable_plx_interrupts(dev);
+				iounmap((void *)priv(dev)->plx9080_iobase);
+			}
+			if (priv(dev)->main_iobase)
+				iounmap((void *)priv(dev)->main_iobase);
+			if (priv(dev)->dio_counter_iobase)
+				iounmap((void *)priv(dev)->dio_counter_iobase);
+			// free pci dma buffers
+			for (i = 0; i < ai_dma_ring_count(board(dev)); i++) {
+				if (priv(dev)->ai_buffer[i])
+					pci_free_consistent(priv(dev)->hw_dev,
+						DMA_BUFFER_SIZE,
+						priv(dev)->ai_buffer[i],
+						priv(dev)->
+						ai_buffer_bus_addr[i]);
+			}
+			for (i = 0; i < AO_DMA_RING_COUNT; i++) {
+				if (priv(dev)->ao_buffer[i])
+					pci_free_consistent(priv(dev)->hw_dev,
+						DMA_BUFFER_SIZE,
+						priv(dev)->ao_buffer[i],
+						priv(dev)->
+						ao_buffer_bus_addr[i]);
+			}
+			// free dma descriptors
+			if (priv(dev)->ai_dma_desc)
+				pci_free_consistent(priv(dev)->hw_dev,
+					sizeof(struct plx_dma_desc) *
+					ai_dma_ring_count(board(dev)),
+					priv(dev)->ai_dma_desc,
+					priv(dev)->ai_dma_desc_bus_addr);
+			if (priv(dev)->ao_dma_desc)
+				pci_free_consistent(priv(dev)->hw_dev,
+					sizeof(struct plx_dma_desc) *
+					AO_DMA_RING_COUNT,
+					priv(dev)->ao_dma_desc,
+					priv(dev)->ao_dma_desc_bus_addr);
+			if (priv(dev)->main_phys_iobase) {
+				comedi_pci_disable(priv(dev)->hw_dev);
+			}
+			pci_dev_put(priv(dev)->hw_dev);
+		}
+	}
+	if (dev->subdevices)
+		subdev_8255_cleanup(dev, dev->subdevices + 4);
+
+	return 0;
+}
+
+static int ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int bits = 0, n, i;
+	unsigned int channel, range, aref;
+	unsigned long flags;
+	static const int timeout = 100;
+
+	DEBUG_PRINT("chanspec 0x%x\n", insn->chanspec);
+	channel = CR_CHAN(insn->chanspec);
+	range = CR_RANGE(insn->chanspec);
+	aref = CR_AREF(insn->chanspec);
+
+	// disable card's analog input interrupt sources and pacing
+	// 4020 generates dac done interrupts even though they are disabled
+	disable_ai_pacing(dev);
+
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	if (insn->chanspec & CR_ALT_FILTER)
+		priv(dev)->adc_control1_bits |= ADC_DITHER_BIT;
+	else
+		priv(dev)->adc_control1_bits &= ~ADC_DITHER_BIT;
+	writew(priv(dev)->adc_control1_bits,
+		priv(dev)->main_iobase + ADC_CONTROL1_REG);
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	if (board(dev)->layout != LAYOUT_4020) {
+		// use internal queue
+		priv(dev)->hw_config_bits &= ~EXT_QUEUE_BIT;
+		writew(priv(dev)->hw_config_bits,
+			priv(dev)->main_iobase + HW_CONFIG_REG);
+
+		// ALT_SOURCE is internal calibration reference
+		if (insn->chanspec & CR_ALT_SOURCE) {
+			unsigned int cal_en_bit;
+
+			DEBUG_PRINT("reading calibration source\n");
+			if (board(dev)->layout == LAYOUT_60XX)
+				cal_en_bit = CAL_EN_60XX_BIT;
+			else
+				cal_en_bit = CAL_EN_64XX_BIT;
+			// select internal reference source to connect to channel 0
+			writew(cal_en_bit | adc_src_bits(priv(dev)->
+					calibration_source),
+				priv(dev)->main_iobase + CALIBRATION_REG);
+		} else {
+			// make sure internal calibration source is turned off
+			writew(0, priv(dev)->main_iobase + CALIBRATION_REG);
+		}
+		// load internal queue
+		bits = 0;
+		// set gain
+		bits |= ai_range_bits_6xxx(dev, CR_RANGE(insn->chanspec));
+		// set single-ended / differential
+		bits |= se_diff_bit_6xxx(dev, aref == AREF_DIFF);
+		if (aref == AREF_COMMON)
+			bits |= ADC_COMMON_BIT;
+		bits |= adc_chan_bits(channel);
+		// set stop channel
+		writew(adc_chan_bits(channel),
+			priv(dev)->main_iobase + ADC_QUEUE_HIGH_REG);
+		// set start channel, and rest of settings
+		writew(bits, priv(dev)->main_iobase + ADC_QUEUE_LOAD_REG);
+	} else {
+		uint8_t old_cal_range_bits = priv(dev)->i2c_cal_range_bits;
+
+		priv(dev)->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK;
+		if (insn->chanspec & CR_ALT_SOURCE) {
+			DEBUG_PRINT("reading calibration source\n");
+			priv(dev)->i2c_cal_range_bits |=
+				adc_src_4020_bits(priv(dev)->
+				calibration_source);
+		} else {	//select BNC inputs
+			priv(dev)->i2c_cal_range_bits |= adc_src_4020_bits(4);
+		}
+		// select range
+		if (range == 0)
+			priv(dev)->i2c_cal_range_bits |= attenuate_bit(channel);
+		else
+			priv(dev)->i2c_cal_range_bits &=
+				~attenuate_bit(channel);
+		// update calibration/range i2c register only if necessary, as it is very slow
+		if (old_cal_range_bits != priv(dev)->i2c_cal_range_bits) {
+			uint8_t i2c_data = priv(dev)->i2c_cal_range_bits;
+			i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data,
+				sizeof(i2c_data));
+		}
+
+		/* 4020 manual asks that sample interval register to be set before writing to convert register.
+		 * Using somewhat arbitrary setting of 4 master clock ticks = 0.1 usec */
+		writew(0,
+			priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
+		writew(2,
+			priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG);
+	}
+
+	for (n = 0; n < insn->n; n++) {
+
+		// clear adc buffer (inside loop for 4020 sake)
+		writew(0, priv(dev)->main_iobase + ADC_BUFFER_CLEAR_REG);
+
+		/* trigger conversion, bits sent only matter for 4020 */
+		writew(adc_convert_chan_4020_bits(CR_CHAN(insn->chanspec)),
+			priv(dev)->main_iobase + ADC_CONVERT_REG);
+
+		// wait for data
+		for (i = 0; i < timeout; i++) {
+			bits = readw(priv(dev)->main_iobase + HW_STATUS_REG);
+			DEBUG_PRINT(" pipe bits 0x%x\n", pipe_full_bits(bits));
+			if (board(dev)->layout == LAYOUT_4020) {
+				if (readw(priv(dev)->main_iobase +
+						ADC_WRITE_PNTR_REG))
+					break;
+			} else {
+				if (pipe_full_bits(bits))
+					break;
+			}
+			comedi_udelay(1);
+		}
+		DEBUG_PRINT(" looped %i times waiting for data\n", i);
+		if (i == timeout) {
+			comedi_error(dev, " analog input read insn timed out");
+			rt_printk(" status 0x%x\n", bits);
+			return -ETIME;
+		}
+		if (board(dev)->layout == LAYOUT_4020)
+			data[n] =
+				readl(priv(dev)->dio_counter_iobase +
+				ADC_FIFO_REG) & 0xffff;
+		else
+			data[n] =
+				readw(priv(dev)->main_iobase + PIPE1_READ_REG);
+	}
+
+	return n;
+}
+
+static int ai_config_calibration_source(struct comedi_device * dev, unsigned int * data)
+{
+	unsigned int source = data[1];
+	int num_calibration_sources;
+
+	if (board(dev)->layout == LAYOUT_60XX)
+		num_calibration_sources = 16;
+	else
+		num_calibration_sources = 8;
+	if (source >= num_calibration_sources) {
+		printk("invalid calibration source: %i\n", source);
+		return -EINVAL;
+	}
+
+	DEBUG_PRINT("setting calibration source to %i\n", source);
+	priv(dev)->calibration_source = source;
+
+	return 2;
+}
+
+static int ai_config_block_size(struct comedi_device * dev, unsigned int * data)
+{
+	int fifo_size;
+	const struct hw_fifo_info *const fifo = board(dev)->ai_fifo;
+	unsigned int block_size, requested_block_size;
+	int retval;
+
+	requested_block_size = data[1];
+
+	if (requested_block_size) {
+		fifo_size =
+			requested_block_size * fifo->num_segments /
+			bytes_in_sample;
+
+		retval = set_ai_fifo_size(dev, fifo_size);
+		if (retval < 0)
+			return retval;
+
+	}
+
+	block_size = ai_fifo_size(dev) / fifo->num_segments * bytes_in_sample;
+
+	data[1] = block_size;
+
+	return 2;
+}
+
+static int ai_config_master_clock_4020(struct comedi_device * dev, unsigned int * data)
+{
+	unsigned int divisor = data[4];
+	int retval = 0;
+
+	if (divisor < 2) {
+		divisor = 2;
+		retval = -EAGAIN;
+	}
+
+	switch (data[1]) {
+	case COMEDI_EV_SCAN_BEGIN:
+		priv(dev)->ext_clock.divisor = divisor;
+		priv(dev)->ext_clock.chanspec = data[2];
+		break;
+	default:
+		return -EINVAL;
+		break;
+	}
+
+	data[4] = divisor;
+
+	return retval ? retval : 5;
+}
+
+// XXX could add support for 60xx series
+static int ai_config_master_clock(struct comedi_device * dev, unsigned int * data)
+{
+
+	switch (board(dev)->layout) {
+	case LAYOUT_4020:
+		return ai_config_master_clock_4020(dev, data);
+		break;
+	default:
+		return -EINVAL;
+		break;
+	}
+
+	return -EINVAL;
+}
+
+static int ai_config_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int id = data[0];
+
+	switch (id) {
+	case INSN_CONFIG_ALT_SOURCE:
+		return ai_config_calibration_source(dev, data);
+		break;
+	case INSN_CONFIG_BLOCK_SIZE:
+		return ai_config_block_size(dev, data);
+		break;
+	case INSN_CONFIG_TIMER_1:
+		return ai_config_master_clock(dev, data);
+		break;
+	default:
+		return -EINVAL;
+		break;
+	}
+	return -EINVAL;
+}
+
+static int ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp;
+	unsigned int tmp_arg, tmp_arg2;
+	int i;
+	int aref;
+	unsigned int triggers;
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW | TRIG_EXT;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	triggers = TRIG_TIMER;
+	if (board(dev)->layout == LAYOUT_4020)
+		triggers |= TRIG_OTHER;
+	else
+		triggers |= TRIG_FOLLOW;
+	cmd->scan_begin_src &= triggers;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	triggers = TRIG_TIMER;
+	if (board(dev)->layout == LAYOUT_4020)
+		triggers |= TRIG_NOW;
+	else
+		triggers |= TRIG_EXT;
+	cmd->convert_src &= triggers;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	// uniqueness check
+	if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
+		err++;
+	if (cmd->scan_begin_src != TRIG_TIMER &&
+		cmd->scan_begin_src != TRIG_OTHER &&
+		cmd->scan_begin_src != TRIG_FOLLOW)
+		err++;
+	if (cmd->convert_src != TRIG_TIMER &&
+		cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
+		err++;
+	if (cmd->stop_src != TRIG_COUNT &&
+		cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT)
+		err++;
+
+	// compatibility check
+	if (cmd->convert_src == TRIG_EXT && cmd->scan_begin_src == TRIG_TIMER)
+		err++;
+	if (cmd->stop_src != TRIG_COUNT &&
+		cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->convert_src == TRIG_TIMER) {
+		if (board(dev)->layout == LAYOUT_4020) {
+			if (cmd->convert_arg) {
+				cmd->convert_arg = 0;
+				err++;
+			}
+		} else {
+			if (cmd->convert_arg < board(dev)->ai_speed) {
+				cmd->convert_arg = board(dev)->ai_speed;
+				err++;
+			}
+			if (cmd->scan_begin_src == TRIG_TIMER) {
+				// if scans are timed faster than conversion rate allows
+				if (cmd->convert_arg * cmd->chanlist_len >
+					cmd->scan_begin_arg) {
+					cmd->scan_begin_arg =
+						cmd->convert_arg *
+						cmd->chanlist_len;
+					err++;
+				}
+			}
+		}
+	}
+
+	if (!cmd->chanlist_len) {
+		cmd->chanlist_len = 1;
+		err++;
+	}
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+
+	switch (cmd->stop_src) {
+	case TRIG_EXT:
+		break;
+	case TRIG_COUNT:
+		if (!cmd->stop_arg) {
+			cmd->stop_arg = 1;
+			err++;
+		}
+		break;
+	case TRIG_NONE:
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+		break;
+	default:
+		break;
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	if (cmd->convert_src == TRIG_TIMER) {
+		tmp_arg = cmd->convert_arg;
+		tmp_arg2 = cmd->scan_begin_arg;
+		check_adc_timing(dev, cmd);
+		if (tmp_arg != cmd->convert_arg)
+			err++;
+		if (tmp_arg2 != cmd->scan_begin_arg)
+			err++;
+	}
+
+	if (err)
+		return 4;
+
+	// make sure user is doesn't change analog reference mid chanlist
+	if (cmd->chanlist) {
+		aref = CR_AREF(cmd->chanlist[0]);
+		for (i = 1; i < cmd->chanlist_len; i++) {
+			if (aref != CR_AREF(cmd->chanlist[i])) {
+				comedi_error(dev,
+					"all elements in chanlist must use the same analog reference");
+				err++;
+				break;
+			}
+		}
+		// check 4020 chanlist
+		if (board(dev)->layout == LAYOUT_4020) {
+			unsigned int first_channel = CR_CHAN(cmd->chanlist[0]);
+			for (i = 1; i < cmd->chanlist_len; i++) {
+				if (CR_CHAN(cmd->chanlist[i]) !=
+					first_channel + i) {
+					comedi_error(dev,
+						"chanlist must use consecutive channels");
+					err++;
+					break;
+				}
+			}
+			if (cmd->chanlist_len == 3) {
+				comedi_error(dev,
+					"chanlist cannot be 3 channels long, use 1, 2, or 4 channels");
+				err++;
+			}
+		}
+	}
+
+	if (err)
+		return 5;
+
+	return 0;
+}
+
+static int use_hw_sample_counter(struct comedi_cmd * cmd)
+{
+// disable for now until I work out a race
+	return 0;
+
+	if (cmd->stop_src == TRIG_COUNT && cmd->stop_arg <= max_counter_value)
+		return 1;
+	else
+		return 0;
+}
+
+static void setup_sample_counters(struct comedi_device * dev, struct comedi_cmd * cmd)
+{
+	if (cmd->stop_src == TRIG_COUNT) {
+		// set software count
+		priv(dev)->ai_count = cmd->stop_arg * cmd->chanlist_len;
+	}
+	// load hardware conversion counter
+	if (use_hw_sample_counter(cmd)) {
+		writew(cmd->stop_arg & 0xffff,
+			priv(dev)->main_iobase + ADC_COUNT_LOWER_REG);
+		writew((cmd->stop_arg >> 16) & 0xff,
+			priv(dev)->main_iobase + ADC_COUNT_UPPER_REG);
+	} else {
+		writew(1, priv(dev)->main_iobase + ADC_COUNT_LOWER_REG);
+	}
+}
+
+static inline unsigned int dma_transfer_size(struct comedi_device * dev)
+{
+	unsigned int num_samples;
+
+	num_samples =
+		priv(dev)->ai_fifo_segment_length *
+		board(dev)->ai_fifo->sample_packing_ratio;
+	if (num_samples > DMA_BUFFER_SIZE / sizeof(uint16_t))
+		num_samples = DMA_BUFFER_SIZE / sizeof(uint16_t);
+
+	return num_samples;
+}
+
+static void disable_ai_pacing(struct comedi_device * dev)
+{
+	unsigned long flags;
+
+	disable_ai_interrupts(dev);
+
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	priv(dev)->adc_control1_bits &= ~ADC_SW_GATE_BIT;
+	writew(priv(dev)->adc_control1_bits,
+		priv(dev)->main_iobase + ADC_CONTROL1_REG);
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	/* disable pacing, triggering, etc */
+	writew(ADC_DMA_DISABLE_BIT | ADC_SOFT_GATE_BITS | ADC_GATE_LEVEL_BIT,
+		priv(dev)->main_iobase + ADC_CONTROL0_REG);
+}
+
+static void disable_ai_interrupts(struct comedi_device * dev)
+{
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	priv(dev)->intr_enable_bits &=
+		~EN_ADC_INTR_SRC_BIT & ~EN_ADC_DONE_INTR_BIT &
+		~EN_ADC_ACTIVE_INTR_BIT & ~EN_ADC_STOP_INTR_BIT &
+		~EN_ADC_OVERRUN_BIT & ~ADC_INTR_SRC_MASK;
+	writew(priv(dev)->intr_enable_bits,
+		priv(dev)->main_iobase + INTR_ENABLE_REG);
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	DEBUG_PRINT("intr enable bits 0x%x\n", priv(dev)->intr_enable_bits);
+}
+
+static void enable_ai_interrupts(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+	uint32_t bits;
+	unsigned long flags;
+
+	bits = EN_ADC_OVERRUN_BIT | EN_ADC_DONE_INTR_BIT |
+		EN_ADC_ACTIVE_INTR_BIT | EN_ADC_STOP_INTR_BIT;
+	// Use pio transfer and interrupt on end of conversion if TRIG_WAKE_EOS flag is set.
+	if (cmd->flags & TRIG_WAKE_EOS) {
+		// 4020 doesn't support pio transfers except for fifo dregs
+		if (board(dev)->layout != LAYOUT_4020)
+			bits |= ADC_INTR_EOSCAN_BITS | EN_ADC_INTR_SRC_BIT;
+	}
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	priv(dev)->intr_enable_bits |= bits;
+	writew(priv(dev)->intr_enable_bits,
+		priv(dev)->main_iobase + INTR_ENABLE_REG);
+	DEBUG_PRINT("intr enable bits 0x%x\n", priv(dev)->intr_enable_bits);
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+}
+
+static uint32_t ai_convert_counter_6xxx(const struct comedi_device * dev,
+	const struct comedi_cmd * cmd)
+{
+	// supposed to load counter with desired divisor minus 3
+	return cmd->convert_arg / TIMER_BASE - 3;
+}
+
+static uint32_t ai_scan_counter_6xxx(struct comedi_device * dev, struct comedi_cmd * cmd)
+{
+	uint32_t count;
+	// figure out how long we need to delay at end of scan
+	switch (cmd->scan_begin_src) {
+	case TRIG_TIMER:
+		count = (cmd->scan_begin_arg -
+			(cmd->convert_arg * (cmd->chanlist_len - 1)))
+			/ TIMER_BASE;
+		break;
+	case TRIG_FOLLOW:
+		count = cmd->convert_arg / TIMER_BASE;
+		break;
+	default:
+		return 0;
+		break;
+	}
+	return count - 3;
+}
+
+static uint32_t ai_convert_counter_4020(struct comedi_device * dev, struct comedi_cmd * cmd)
+{
+	unsigned int divisor;
+
+	switch (cmd->scan_begin_src) {
+	case TRIG_TIMER:
+		divisor = cmd->scan_begin_arg / TIMER_BASE;
+		break;
+	case TRIG_OTHER:
+		divisor = priv(dev)->ext_clock.divisor;
+		break;
+	default:		// should never happen
+		comedi_error(dev, "bug! failed to set ai pacing!");
+		divisor = 1000;
+		break;
+	}
+
+	// supposed to load counter with desired divisor minus 2 for 4020
+	return divisor - 2;
+}
+
+static void select_master_clock_4020(struct comedi_device * dev,
+	const struct comedi_cmd * cmd)
+{
+	// select internal/external master clock
+	priv(dev)->hw_config_bits &= ~MASTER_CLOCK_4020_MASK;
+	if (cmd->scan_begin_src == TRIG_OTHER) {
+		int chanspec = priv(dev)->ext_clock.chanspec;
+
+		if (CR_CHAN(chanspec))
+			priv(dev)->hw_config_bits |= BNC_CLOCK_4020_BITS;
+		else
+			priv(dev)->hw_config_bits |= EXT_CLOCK_4020_BITS;
+	} else {
+		priv(dev)->hw_config_bits |= INTERNAL_CLOCK_4020_BITS;
+	}
+	writew(priv(dev)->hw_config_bits,
+		priv(dev)->main_iobase + HW_CONFIG_REG);
+}
+
+static void select_master_clock(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+	switch (board(dev)->layout) {
+	case LAYOUT_4020:
+		select_master_clock_4020(dev, cmd);
+		break;
+	default:
+		break;
+	}
+}
+
+static inline void dma_start_sync(struct comedi_device * dev, unsigned int channel)
+{
+	unsigned long flags;
+
+	// spinlock for plx dma control/status reg
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	if (channel)
+		writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT |
+			PLX_CLEAR_DMA_INTR_BIT,
+			priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
+	else
+		writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT |
+			PLX_CLEAR_DMA_INTR_BIT,
+			priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+}
+
+static void set_ai_pacing(struct comedi_device * dev, struct comedi_cmd * cmd)
+{
+	uint32_t convert_counter = 0, scan_counter = 0;
+
+	check_adc_timing(dev, cmd);
+
+	select_master_clock(dev, cmd);
+
+	if (board(dev)->layout == LAYOUT_4020) {
+		convert_counter = ai_convert_counter_4020(dev, cmd);
+	} else {
+		convert_counter = ai_convert_counter_6xxx(dev, cmd);
+		scan_counter = ai_scan_counter_6xxx(dev, cmd);
+	}
+
+	// load lower 16 bits of convert interval
+	writew(convert_counter & 0xffff,
+		priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG);
+	DEBUG_PRINT("convert counter 0x%x\n", convert_counter);
+	// load upper 8 bits of convert interval
+	writew((convert_counter >> 16) & 0xff,
+		priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
+	// load lower 16 bits of scan delay
+	writew(scan_counter & 0xffff,
+		priv(dev)->main_iobase + ADC_DELAY_INTERVAL_LOWER_REG);
+	// load upper 8 bits of scan delay
+	writew((scan_counter >> 16) & 0xff,
+		priv(dev)->main_iobase + ADC_DELAY_INTERVAL_UPPER_REG);
+	DEBUG_PRINT("scan counter 0x%x\n", scan_counter);
+}
+
+static int use_internal_queue_6xxx(const struct comedi_cmd * cmd)
+{
+	int i;
+	for (i = 0; i + 1 < cmd->chanlist_len; i++) {
+		if (CR_CHAN(cmd->chanlist[i + 1]) !=
+			CR_CHAN(cmd->chanlist[i]) + 1)
+			return 0;
+		if (CR_RANGE(cmd->chanlist[i + 1]) !=
+			CR_RANGE(cmd->chanlist[i]))
+			return 0;
+		if (CR_AREF(cmd->chanlist[i + 1]) != CR_AREF(cmd->chanlist[i]))
+			return 0;
+	}
+	return 1;
+}
+
+static int setup_channel_queue(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+	unsigned short bits;
+	int i;
+
+	if (board(dev)->layout != LAYOUT_4020) {
+		if (use_internal_queue_6xxx(cmd)) {
+			priv(dev)->hw_config_bits &= ~EXT_QUEUE_BIT;
+			writew(priv(dev)->hw_config_bits,
+				priv(dev)->main_iobase + HW_CONFIG_REG);
+			bits = 0;
+			// set channel
+			bits |= adc_chan_bits(CR_CHAN(cmd->chanlist[0]));
+			// set gain
+			bits |= ai_range_bits_6xxx(dev,
+				CR_RANGE(cmd->chanlist[0]));
+			// set single-ended / differential
+			bits |= se_diff_bit_6xxx(dev,
+				CR_AREF(cmd->chanlist[0]) == AREF_DIFF);
+			if (CR_AREF(cmd->chanlist[0]) == AREF_COMMON)
+				bits |= ADC_COMMON_BIT;
+			// set stop channel
+			writew(adc_chan_bits(CR_CHAN(cmd->chanlist[cmd->
+							chanlist_len - 1])),
+				priv(dev)->main_iobase + ADC_QUEUE_HIGH_REG);
+			// set start channel, and rest of settings
+			writew(bits,
+				priv(dev)->main_iobase + ADC_QUEUE_LOAD_REG);
+		} else {
+			// use external queue
+			if (dev->write_subdev && dev->write_subdev->busy) {
+				warn_external_queue(dev);
+				return -EBUSY;
+			}
+			priv(dev)->hw_config_bits |= EXT_QUEUE_BIT;
+			writew(priv(dev)->hw_config_bits,
+				priv(dev)->main_iobase + HW_CONFIG_REG);
+			// clear DAC buffer to prevent weird interactions
+			writew(0,
+				priv(dev)->main_iobase + DAC_BUFFER_CLEAR_REG);
+			// clear queue pointer
+			writew(0, priv(dev)->main_iobase + ADC_QUEUE_CLEAR_REG);
+			// load external queue
+			for (i = 0; i < cmd->chanlist_len; i++) {
+				bits = 0;
+				// set channel
+				bits |= adc_chan_bits(CR_CHAN(cmd->
+						chanlist[i]));
+				// set gain
+				bits |= ai_range_bits_6xxx(dev,
+					CR_RANGE(cmd->chanlist[i]));
+				// set single-ended / differential
+				bits |= se_diff_bit_6xxx(dev,
+					CR_AREF(cmd->chanlist[i]) == AREF_DIFF);
+				if (CR_AREF(cmd->chanlist[i]) == AREF_COMMON)
+					bits |= ADC_COMMON_BIT;
+				// mark end of queue
+				if (i == cmd->chanlist_len - 1)
+					bits |= QUEUE_EOSCAN_BIT |
+						QUEUE_EOSEQ_BIT;
+				writew(bits,
+					priv(dev)->main_iobase +
+					ADC_QUEUE_FIFO_REG);
+				DEBUG_PRINT
+					("wrote 0x%x to external channel queue\n",
+					bits);
+			}
+			/* doing a queue clear is not specified in board docs,
+			 * but required for reliable operation */
+			writew(0, priv(dev)->main_iobase + ADC_QUEUE_CLEAR_REG);
+			// prime queue holding register
+			writew(0, priv(dev)->main_iobase + ADC_QUEUE_LOAD_REG);
+		}
+	} else {
+		unsigned short old_cal_range_bits =
+			priv(dev)->i2c_cal_range_bits;
+
+		priv(dev)->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK;
+		//select BNC inputs
+		priv(dev)->i2c_cal_range_bits |= adc_src_4020_bits(4);
+		// select ranges
+		for (i = 0; i < cmd->chanlist_len; i++) {
+			unsigned int channel = CR_CHAN(cmd->chanlist[i]);
+			unsigned int range = CR_RANGE(cmd->chanlist[i]);
+
+			if (range == 0)
+				priv(dev)->i2c_cal_range_bits |=
+					attenuate_bit(channel);
+			else
+				priv(dev)->i2c_cal_range_bits &=
+					~attenuate_bit(channel);
+		}
+		// update calibration/range i2c register only if necessary, as it is very slow
+		if (old_cal_range_bits != priv(dev)->i2c_cal_range_bits) {
+			uint8_t i2c_data = priv(dev)->i2c_cal_range_bits;
+			i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data,
+				sizeof(i2c_data));
+		}
+	}
+	return 0;
+}
+
+static inline void load_first_dma_descriptor(struct comedi_device * dev,
+	unsigned int dma_channel, unsigned int descriptor_bits)
+{
+	/* The transfer size, pci address, and local address registers
+	 * are supposedly unused during chained dma,
+	 * but I have found that left over values from last operation
+	 * occasionally cause problems with transfer of first dma
+	 * block.  Initializing them to zero seems to fix the problem. */
+	if (dma_channel) {
+		writel(0,
+			priv(dev)->plx9080_iobase + PLX_DMA1_TRANSFER_SIZE_REG);
+		writel(0, priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG);
+		writel(0,
+			priv(dev)->plx9080_iobase + PLX_DMA1_LOCAL_ADDRESS_REG);
+		writel(descriptor_bits,
+			priv(dev)->plx9080_iobase + PLX_DMA1_DESCRIPTOR_REG);
+	} else {
+		writel(0,
+			priv(dev)->plx9080_iobase + PLX_DMA0_TRANSFER_SIZE_REG);
+		writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG);
+		writel(0,
+			priv(dev)->plx9080_iobase + PLX_DMA0_LOCAL_ADDRESS_REG);
+		writel(descriptor_bits,
+			priv(dev)->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG);
+	}
+}
+
+static int ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+	uint32_t bits;
+	unsigned int i;
+	unsigned long flags;
+	int retval;
+
+	disable_ai_pacing(dev);
+	abort_dma(dev, 1);
+
+	retval = setup_channel_queue(dev, cmd);
+	if (retval < 0)
+		return retval;
+
+	// make sure internal calibration source is turned off
+	writew(0, priv(dev)->main_iobase + CALIBRATION_REG);
+
+	set_ai_pacing(dev, cmd);
+
+	setup_sample_counters(dev, cmd);
+
+	enable_ai_interrupts(dev, cmd);
+
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	/* set mode, allow conversions through software gate */
+	priv(dev)->adc_control1_bits |= ADC_SW_GATE_BIT;
+	priv(dev)->adc_control1_bits &= ~ADC_DITHER_BIT;
+	if (board(dev)->layout != LAYOUT_4020) {
+		priv(dev)->adc_control1_bits &= ~ADC_MODE_MASK;
+		if (cmd->convert_src == TRIG_EXT)
+			priv(dev)->adc_control1_bits |= adc_mode_bits(13);	// good old mode 13
+		else
+			priv(dev)->adc_control1_bits |= adc_mode_bits(8);	// mode 8.  What else could you need?
+	} else {
+		priv(dev)->adc_control1_bits &= ~CHANNEL_MODE_4020_MASK;
+		if (cmd->chanlist_len == 4)
+			priv(dev)->adc_control1_bits |= FOUR_CHANNEL_4020_BITS;
+		else if (cmd->chanlist_len == 2)
+			priv(dev)->adc_control1_bits |= TWO_CHANNEL_4020_BITS;
+		priv(dev)->adc_control1_bits &= ~ADC_LO_CHANNEL_4020_MASK;
+		priv(dev)->adc_control1_bits |=
+			adc_lo_chan_4020_bits(CR_CHAN(cmd->chanlist[0]));
+		priv(dev)->adc_control1_bits &= ~ADC_HI_CHANNEL_4020_MASK;
+		priv(dev)->adc_control1_bits |=
+			adc_hi_chan_4020_bits(CR_CHAN(cmd->chanlist[cmd->
+					chanlist_len - 1]));
+	}
+	writew(priv(dev)->adc_control1_bits,
+		priv(dev)->main_iobase + ADC_CONTROL1_REG);
+	DEBUG_PRINT("control1 bits 0x%x\n", priv(dev)->adc_control1_bits);
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	// clear adc buffer
+	writew(0, priv(dev)->main_iobase + ADC_BUFFER_CLEAR_REG);
+
+	if ((cmd->flags & TRIG_WAKE_EOS) == 0 ||
+		board(dev)->layout == LAYOUT_4020) {
+		priv(dev)->ai_dma_index = 0;
+
+		// set dma transfer size
+		for (i = 0; i < ai_dma_ring_count(board(dev)); i++)
+			priv(dev)->ai_dma_desc[i].transfer_size =
+				cpu_to_le32(dma_transfer_size(dev) *
+				sizeof(uint16_t));
+
+		// give location of first dma descriptor
+		load_first_dma_descriptor(dev, 1,
+			priv(dev)->
+			ai_dma_desc_bus_addr | PLX_DESC_IN_PCI_BIT |
+			PLX_INTR_TERM_COUNT | PLX_XFER_LOCAL_TO_PCI);
+
+		dma_start_sync(dev, 1);
+	}
+
+	if (board(dev)->layout == LAYOUT_4020) {
+		/* set source for external triggers */
+		bits = 0;
+		if (cmd->start_src == TRIG_EXT && CR_CHAN(cmd->start_arg))
+			bits |= EXT_START_TRIG_BNC_BIT;
+		if (cmd->stop_src == TRIG_EXT && CR_CHAN(cmd->stop_arg))
+			bits |= EXT_STOP_TRIG_BNC_BIT;
+		writew(bits, priv(dev)->main_iobase + DAQ_ATRIG_LOW_4020_REG);
+	}
+
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+
+	/* enable pacing, triggering, etc */
+	bits = ADC_ENABLE_BIT | ADC_SOFT_GATE_BITS | ADC_GATE_LEVEL_BIT;
+	if (cmd->flags & TRIG_WAKE_EOS)
+		bits |= ADC_DMA_DISABLE_BIT;
+	// set start trigger
+	if (cmd->start_src == TRIG_EXT) {
+		bits |= ADC_START_TRIG_EXT_BITS;
+		if (cmd->start_arg & CR_INVERT)
+			bits |= ADC_START_TRIG_FALLING_BIT;
+	} else if (cmd->start_src == TRIG_NOW)
+		bits |= ADC_START_TRIG_SOFT_BITS;
+	if (use_hw_sample_counter(cmd))
+		bits |= ADC_SAMPLE_COUNTER_EN_BIT;
+	writew(bits, priv(dev)->main_iobase + ADC_CONTROL0_REG);
+	DEBUG_PRINT("control0 bits 0x%x\n", bits);
+
+	priv(dev)->ai_cmd_running = 1;
+
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	// start aquisition
+	if (cmd->start_src == TRIG_NOW) {
+		writew(0, priv(dev)->main_iobase + ADC_START_REG);
+		DEBUG_PRINT("soft trig\n");
+	}
+
+	return 0;
+}
+
+// read num_samples from 16 bit wide ai fifo
+static void pio_drain_ai_fifo_16(struct comedi_device * dev)
+{
+	struct comedi_subdevice *s = dev->read_subdev;
+	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+	unsigned int i;
+	uint16_t prepost_bits;
+	int read_segment, read_index, write_segment, write_index;
+	int num_samples;
+
+	do {
+		// get least significant 15 bits
+		read_index =
+			readw(priv(dev)->main_iobase +
+			ADC_READ_PNTR_REG) & 0x7fff;
+		write_index =
+			readw(priv(dev)->main_iobase +
+			ADC_WRITE_PNTR_REG) & 0x7fff;
+		/* Get most significant bits (grey code).  Different boards use different code
+		 * so use a scheme that doesn't depend on encoding.  This read must
+		 * occur after reading least significant 15 bits to avoid race
+		 * with fifo switching to next segment. */
+		prepost_bits = readw(priv(dev)->main_iobase + PREPOST_REG);
+
+		/* if read and write pointers are not on the same fifo segment, read to the
+		 * end of the read segment */
+		read_segment = adc_upper_read_ptr_code(prepost_bits);
+		write_segment = adc_upper_write_ptr_code(prepost_bits);
+
+		DEBUG_PRINT(" rd seg %i, wrt seg %i, rd idx %i, wrt idx %i\n",
+			read_segment, write_segment, read_index, write_index);
+
+		if (read_segment != write_segment)
+			num_samples =
+				priv(dev)->ai_fifo_segment_length - read_index;
+		else
+			num_samples = write_index - read_index;
+
+		if (cmd->stop_src == TRIG_COUNT) {
+			if (priv(dev)->ai_count == 0)
+				break;
+			if (num_samples > priv(dev)->ai_count) {
+				num_samples = priv(dev)->ai_count;
+			}
+			priv(dev)->ai_count -= num_samples;
+		}
+
+		if (num_samples < 0) {
+			rt_printk(" cb_pcidas64: bug! num_samples < 0\n");
+			break;
+		}
+
+		DEBUG_PRINT(" read %i samples from fifo\n", num_samples);
+
+		for (i = 0; i < num_samples; i++) {
+			cfc_write_to_buffer(s,
+				readw(priv(dev)->main_iobase + ADC_FIFO_REG));
+		}
+
+	} while (read_segment != write_segment);
+}
+
+/* Read from 32 bit wide ai fifo of 4020 - deal with insane grey coding of pointers.
+ * The pci-4020 hardware only supports
+ * dma transfers (it only supports the use of pio for draining the last remaining
+ * points from the fifo when a data aquisition operation has completed).
+ */
+static void pio_drain_ai_fifo_32(struct comedi_device * dev)
+{
+	struct comedi_subdevice *s = dev->read_subdev;
+	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+	unsigned int i;
+	unsigned int max_transfer = 100000;
+	uint32_t fifo_data;
+	int write_code =
+		readw(priv(dev)->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff;
+	int read_code =
+		readw(priv(dev)->main_iobase + ADC_READ_PNTR_REG) & 0x7fff;
+
+	if (cmd->stop_src == TRIG_COUNT) {
+		if (max_transfer > priv(dev)->ai_count) {
+			max_transfer = priv(dev)->ai_count;
+		}
+	}
+	for (i = 0; read_code != write_code && i < max_transfer;) {
+		fifo_data = readl(priv(dev)->dio_counter_iobase + ADC_FIFO_REG);
+		cfc_write_to_buffer(s, fifo_data & 0xffff);
+		i++;
+		if (i < max_transfer) {
+			cfc_write_to_buffer(s, (fifo_data >> 16) & 0xffff);
+			i++;
+		}
+		read_code =
+			readw(priv(dev)->main_iobase +
+			ADC_READ_PNTR_REG) & 0x7fff;
+	}
+	priv(dev)->ai_count -= i;
+}
+
+// empty fifo
+static void pio_drain_ai_fifo(struct comedi_device * dev)
+{
+	if (board(dev)->layout == LAYOUT_4020) {
+		pio_drain_ai_fifo_32(dev);
+	} else
+		pio_drain_ai_fifo_16(dev);
+}
+
+static void drain_dma_buffers(struct comedi_device * dev, unsigned int channel)
+{
+	struct comedi_async *async = dev->read_subdev->async;
+	uint32_t next_transfer_addr;
+	int j;
+	int num_samples = 0;
+	void *pci_addr_reg;
+
+	if (channel)
+		pci_addr_reg =
+			priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG;
+	else
+		pci_addr_reg =
+			priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG;
+
+	// loop until we have read all the full buffers
+	for (j = 0, next_transfer_addr = readl(pci_addr_reg);
+		(next_transfer_addr <
+			priv(dev)->ai_buffer_bus_addr[priv(dev)->ai_dma_index]
+			|| next_transfer_addr >=
+			priv(dev)->ai_buffer_bus_addr[priv(dev)->ai_dma_index] +
+			DMA_BUFFER_SIZE) && j < ai_dma_ring_count(board(dev));
+		j++) {
+		// transfer data from dma buffer to comedi buffer
+		num_samples = dma_transfer_size(dev);
+		if (async->cmd.stop_src == TRIG_COUNT) {
+			if (num_samples > priv(dev)->ai_count)
+				num_samples = priv(dev)->ai_count;
+			priv(dev)->ai_count -= num_samples;
+		}
+		cfc_write_array_to_buffer(dev->read_subdev,
+			priv(dev)->ai_buffer[priv(dev)->ai_dma_index],
+			num_samples * sizeof(uint16_t));
+		priv(dev)->ai_dma_index =
+			(priv(dev)->ai_dma_index +
+			1) % ai_dma_ring_count(board(dev));
+
+		DEBUG_PRINT("next buffer addr 0x%lx\n",
+			(unsigned long)priv(dev)->ai_buffer_bus_addr[priv(dev)->
+				ai_dma_index]);
+		DEBUG_PRINT("pci addr reg 0x%x\n", next_transfer_addr);
+	}
+	/* XXX check for dma ring buffer overrun (use end-of-chain bit to mark last
+	 * unused buffer) */
+}
+
+void handle_ai_interrupt(struct comedi_device * dev, unsigned short status,
+	unsigned int plx_status)
+{
+	struct comedi_subdevice *s = dev->read_subdev;
+	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+	uint8_t dma1_status;
+	unsigned long flags;
+
+	// check for fifo overrun
+	if (status & ADC_OVERRUN_BIT) {
+		comedi_error(dev, "fifo overrun");
+		async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+	}
+	// spin lock makes sure noone else changes plx dma control reg
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	dma1_status = readb(priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
+	if (plx_status & ICS_DMA1_A) {	// dma chan 1 interrupt
+		writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
+			priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
+		DEBUG_PRINT("dma1 status 0x%x\n", dma1_status);
+
+		if (dma1_status & PLX_DMA_EN_BIT) {
+			drain_dma_buffers(dev, 1);
+		}
+		DEBUG_PRINT(" cleared dma ch1 interrupt\n");
+	}
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	if (status & ADC_DONE_BIT)
+		DEBUG_PRINT("adc done interrupt\n");
+
+	// drain fifo with pio
+	if ((status & ADC_DONE_BIT) ||
+		((cmd->flags & TRIG_WAKE_EOS) &&
+			(status & ADC_INTR_PENDING_BIT) &&
+			(board(dev)->layout != LAYOUT_4020))) {
+		DEBUG_PRINT("pio fifo drain\n");
+		comedi_spin_lock_irqsave(&dev->spinlock, flags);
+		if (priv(dev)->ai_cmd_running) {
+			comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+			pio_drain_ai_fifo(dev);
+		} else
+			comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+	}
+	// if we are have all the data, then quit
+	if ((cmd->stop_src == TRIG_COUNT && priv(dev)->ai_count <= 0) ||
+		(cmd->stop_src == TRIG_EXT && (status & ADC_STOP_BIT))) {
+		async->events |= COMEDI_CB_EOA;
+	}
+
+	cfc_handle_events(dev, s);
+}
+
+static inline unsigned int prev_ao_dma_index(struct comedi_device * dev)
+{
+	unsigned int buffer_index;
+
+	if (priv(dev)->ao_dma_index == 0)
+		buffer_index = AO_DMA_RING_COUNT - 1;
+	else
+		buffer_index = priv(dev)->ao_dma_index - 1;
+	return buffer_index;
+}
+
+static int last_ao_dma_load_completed(struct comedi_device * dev)
+{
+	unsigned int buffer_index;
+	unsigned int transfer_address;
+	unsigned short dma_status;
+
+	buffer_index = prev_ao_dma_index(dev);
+	dma_status = readb(priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+	if ((dma_status & PLX_DMA_DONE_BIT) == 0)
+		return 0;
+
+	transfer_address =
+		readl(priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG);
+	if (transfer_address != priv(dev)->ao_buffer_bus_addr[buffer_index])
+		return 0;
+
+	return 1;
+}
+
+static int ao_stopped_by_error(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+	if (cmd->stop_src == TRIG_NONE)
+		return 1;
+	if (cmd->stop_src == TRIG_COUNT) {
+		if (priv(dev)->ao_count)
+			return 1;
+		if (last_ao_dma_load_completed(dev) == 0)
+			return 1;
+	}
+	return 0;
+}
+
+static inline int ao_dma_needs_restart(struct comedi_device * dev,
+	unsigned short dma_status)
+{
+	if ((dma_status & PLX_DMA_DONE_BIT) == 0 ||
+		(dma_status & PLX_DMA_EN_BIT) == 0)
+		return 0;
+	if (last_ao_dma_load_completed(dev))
+		return 0;
+
+	return 1;
+}
+
+static void restart_ao_dma(struct comedi_device * dev)
+{
+	unsigned int dma_desc_bits;
+
+	dma_desc_bits =
+		readl(priv(dev)->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG);
+	dma_desc_bits &= ~PLX_END_OF_CHAIN_BIT;
+	DEBUG_PRINT("restarting ao dma, descriptor reg 0x%x\n", dma_desc_bits);
+	load_first_dma_descriptor(dev, 0, dma_desc_bits);
+
+	dma_start_sync(dev, 0);
+}
+
+static void handle_ao_interrupt(struct comedi_device * dev, unsigned short status,
+	unsigned int plx_status)
+{
+	struct comedi_subdevice *s = dev->write_subdev;
+	struct comedi_async *async;
+	struct comedi_cmd *cmd;
+	uint8_t dma0_status;
+	unsigned long flags;
+
+	/* board might not support ao, in which case write_subdev is NULL */
+	if (s == NULL)
+		return;
+	async = s->async;
+	cmd = &async->cmd;
+
+	// spin lock makes sure noone else changes plx dma control reg
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	dma0_status = readb(priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+	if (plx_status & ICS_DMA0_A) {	// dma chan 0 interrupt
+		if ((dma0_status & PLX_DMA_EN_BIT)
+			&& !(dma0_status & PLX_DMA_DONE_BIT))
+			writeb(PLX_DMA_EN_BIT | PLX_CLEAR_DMA_INTR_BIT,
+				priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+		else
+			writeb(PLX_CLEAR_DMA_INTR_BIT,
+				priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+		comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+		DEBUG_PRINT("dma0 status 0x%x\n", dma0_status);
+		if (dma0_status & PLX_DMA_EN_BIT) {
+			load_ao_dma(dev, cmd);
+			/* try to recover from dma end-of-chain event */
+			if (ao_dma_needs_restart(dev, dma0_status))
+				restart_ao_dma(dev);
+		}
+		DEBUG_PRINT(" cleared dma ch0 interrupt\n");
+	} else
+		comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	if ((status & DAC_DONE_BIT)) {
+		async->events |= COMEDI_CB_EOA;
+		if (ao_stopped_by_error(dev, cmd))
+			async->events |= COMEDI_CB_ERROR;
+		DEBUG_PRINT("plx dma0 desc reg 0x%x\n",
+			readl(priv(dev)->plx9080_iobase +
+				PLX_DMA0_DESCRIPTOR_REG));
+		DEBUG_PRINT("plx dma0 address reg 0x%x\n",
+			readl(priv(dev)->plx9080_iobase +
+				PLX_DMA0_PCI_ADDRESS_REG));
+	}
+	cfc_handle_events(dev, s);
+}
+
+static irqreturn_t handle_interrupt(int irq, void *d PT_REGS_ARG)
+{
+	struct comedi_device *dev = d;
+	unsigned short status;
+	uint32_t plx_status;
+	uint32_t plx_bits;
+
+	plx_status = readl(priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
+	status = readw(priv(dev)->main_iobase + HW_STATUS_REG);
+
+	DEBUG_PRINT("cb_pcidas64: hw status 0x%x ", status);
+	DEBUG_PRINT("plx status 0x%x\n", plx_status);
+
+	/* an interrupt before all the postconfig stuff gets done could
+	 * cause a NULL dereference if we continue through the
+	 * interrupt handler */
+	if (dev->attached == 0) {
+		DEBUG_PRINT("cb_pcidas64: premature interrupt, ignoring",
+			status);
+		return IRQ_HANDLED;
+	}
+	handle_ai_interrupt(dev, status, plx_status);
+	handle_ao_interrupt(dev, status, plx_status);
+
+	// clear possible plx9080 interrupt sources
+	if (plx_status & ICS_LDIA) {	// clear local doorbell interrupt
+		plx_bits = readl(priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG);
+		writel(plx_bits, priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG);
+		DEBUG_PRINT(" cleared local doorbell bits 0x%x\n", plx_bits);
+	}
+
+	DEBUG_PRINT("exiting handler\n");
+
+	return IRQ_HANDLED;
+}
+
+void abort_dma(struct comedi_device * dev, unsigned int channel)
+{
+	unsigned long flags;
+
+	// spinlock for plx dma control/status reg
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+
+	plx9080_abort_dma(priv(dev)->plx9080_iobase, channel);
+
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+}
+
+static int ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	if (priv(dev)->ai_cmd_running == 0) {
+		comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+		return 0;
+	}
+	priv(dev)->ai_cmd_running = 0;
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	disable_ai_pacing(dev);
+
+	abort_dma(dev, 1);
+
+	DEBUG_PRINT("ai canceled\n");
+	return 0;
+}
+
+static int ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int chan = CR_CHAN(insn->chanspec);
+	int range = CR_RANGE(insn->chanspec);
+
+	// do some initializing
+	writew(0, priv(dev)->main_iobase + DAC_CONTROL0_REG);
+
+	// set range
+	set_dac_range_bits(dev, &priv(dev)->dac_control1_bits, chan, range);
+	writew(priv(dev)->dac_control1_bits,
+		priv(dev)->main_iobase + DAC_CONTROL1_REG);
+
+	// write to channel
+	if (board(dev)->layout == LAYOUT_4020) {
+		writew(data[0] & 0xff,
+			priv(dev)->main_iobase + dac_lsb_4020_reg(chan));
+		writew((data[0] >> 8) & 0xf,
+			priv(dev)->main_iobase + dac_msb_4020_reg(chan));
+	} else {
+		writew(data[0], priv(dev)->main_iobase + dac_convert_reg(chan));
+	}
+
+	// remember output value
+	priv(dev)->ao_value[chan] = data[0];
+
+	return 1;
+}
+
+static int ao_readback_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	data[0] = priv(dev)->ao_value[CR_CHAN(insn->chanspec)];
+
+	return 1;
+}
+
+static void set_dac_control0_reg(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+	unsigned int bits = DAC_ENABLE_BIT | WAVEFORM_GATE_LEVEL_BIT |
+		WAVEFORM_GATE_ENABLE_BIT | WAVEFORM_GATE_SELECT_BIT;
+
+	if (cmd->start_src == TRIG_EXT) {
+		bits |= WAVEFORM_TRIG_EXT_BITS;
+		if (cmd->start_arg & CR_INVERT)
+			bits |= WAVEFORM_TRIG_FALLING_BIT;
+	} else {
+		bits |= WAVEFORM_TRIG_SOFT_BITS;
+	}
+	if (cmd->scan_begin_src == TRIG_EXT) {
+		bits |= DAC_EXT_UPDATE_ENABLE_BIT;
+		if (cmd->scan_begin_arg & CR_INVERT)
+			bits |= DAC_EXT_UPDATE_FALLING_BIT;
+	}
+	writew(bits, priv(dev)->main_iobase + DAC_CONTROL0_REG);
+}
+
+static void set_dac_control1_reg(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+	int i;
+
+	for (i = 0; i < cmd->chanlist_len; i++) {
+		int channel, range;
+
+		channel = CR_CHAN(cmd->chanlist[i]);
+		range = CR_RANGE(cmd->chanlist[i]);
+		set_dac_range_bits(dev, &priv(dev)->dac_control1_bits, channel,
+			range);
+	}
+	priv(dev)->dac_control1_bits |= DAC_SW_GATE_BIT;
+	writew(priv(dev)->dac_control1_bits,
+		priv(dev)->main_iobase + DAC_CONTROL1_REG);
+}
+
+static void set_dac_select_reg(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+	uint16_t bits;
+	unsigned int first_channel, last_channel;
+
+	first_channel = CR_CHAN(cmd->chanlist[0]);
+	last_channel = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]);
+	if (last_channel < first_channel)
+		comedi_error(dev, "bug! last ao channel < first ao channel");
+
+	bits = (first_channel & 0x7) | (last_channel & 0x7) << 3;
+
+	writew(bits, priv(dev)->main_iobase + DAC_SELECT_REG);
+}
+
+static void set_dac_interval_regs(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+	unsigned int divisor;
+
+	if (cmd->scan_begin_src != TRIG_TIMER)
+		return;
+
+	divisor = get_ao_divisor(cmd->scan_begin_arg, cmd->flags);
+	if (divisor > max_counter_value) {
+		comedi_error(dev, "bug! ao divisor too big");
+		divisor = max_counter_value;
+	}
+	writew(divisor & 0xffff,
+		priv(dev)->main_iobase + DAC_SAMPLE_INTERVAL_LOWER_REG);
+	writew((divisor >> 16) & 0xff,
+		priv(dev)->main_iobase + DAC_SAMPLE_INTERVAL_UPPER_REG);
+}
+
+static unsigned int load_ao_dma_buffer(struct comedi_device * dev,
+	const struct comedi_cmd * cmd)
+{
+	unsigned int num_bytes, buffer_index, prev_buffer_index;
+	unsigned int next_bits;
+
+	buffer_index = priv(dev)->ao_dma_index;
+	prev_buffer_index = prev_ao_dma_index(dev);
+
+	DEBUG_PRINT("attempting to load ao buffer %i (0x%x)\n", buffer_index,
+		priv(dev)->ao_buffer_bus_addr[buffer_index]);
+
+	num_bytes = comedi_buf_read_n_available(dev->write_subdev->async);
+	if (num_bytes > DMA_BUFFER_SIZE)
+		num_bytes = DMA_BUFFER_SIZE;
+	if (cmd->stop_src == TRIG_COUNT && num_bytes > priv(dev)->ao_count)
+		num_bytes = priv(dev)->ao_count;
+	num_bytes -= num_bytes % bytes_in_sample;
+
+	if (num_bytes == 0)
+		return 0;
+
+	DEBUG_PRINT("loading %i bytes\n", num_bytes);
+
+	num_bytes = cfc_read_array_from_buffer(dev->write_subdev,
+		priv(dev)->ao_buffer[buffer_index], num_bytes);
+	priv(dev)->ao_dma_desc[buffer_index].transfer_size =
+		cpu_to_le32(num_bytes);
+	/* set end of chain bit so we catch underruns */
+	next_bits = le32_to_cpu(priv(dev)->ao_dma_desc[buffer_index].next);
+	next_bits |= PLX_END_OF_CHAIN_BIT;
+	priv(dev)->ao_dma_desc[buffer_index].next = cpu_to_le32(next_bits);
+	/* clear end of chain bit on previous buffer now that we have set it
+	 * for the last buffer */
+	next_bits = le32_to_cpu(priv(dev)->ao_dma_desc[prev_buffer_index].next);
+	next_bits &= ~PLX_END_OF_CHAIN_BIT;
+	priv(dev)->ao_dma_desc[prev_buffer_index].next = cpu_to_le32(next_bits);
+
+	priv(dev)->ao_dma_index = (buffer_index + 1) % AO_DMA_RING_COUNT;
+	priv(dev)->ao_count -= num_bytes;
+
+	return num_bytes;
+}
+
+static void load_ao_dma(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+	unsigned int num_bytes;
+	unsigned int next_transfer_addr;
+	void *pci_addr_reg =
+		priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG;
+	unsigned int buffer_index;
+
+	do {
+		buffer_index = priv(dev)->ao_dma_index;
+		/* don't overwrite data that hasn't been transferred yet */
+		next_transfer_addr = readl(pci_addr_reg);
+		if (next_transfer_addr >=
+			priv(dev)->ao_buffer_bus_addr[buffer_index]
+			&& next_transfer_addr <
+			priv(dev)->ao_buffer_bus_addr[buffer_index] +
+			DMA_BUFFER_SIZE)
+			return;
+		num_bytes = load_ao_dma_buffer(dev, cmd);
+	} while (num_bytes >= DMA_BUFFER_SIZE);
+}
+
+static int prep_ao_dma(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+	unsigned int num_bytes;
+	int i;
+
+	/* clear queue pointer too, since external queue has
+	 * weird interactions with ao fifo */
+	writew(0, priv(dev)->main_iobase + ADC_QUEUE_CLEAR_REG);
+	writew(0, priv(dev)->main_iobase + DAC_BUFFER_CLEAR_REG);
+
+	num_bytes = (DAC_FIFO_SIZE / 2) * bytes_in_sample;
+	if (cmd->stop_src == TRIG_COUNT &&
+		num_bytes / bytes_in_sample > priv(dev)->ao_count)
+		num_bytes = priv(dev)->ao_count * bytes_in_sample;
+	num_bytes = cfc_read_array_from_buffer(dev->write_subdev,
+		priv(dev)->ao_bounce_buffer, num_bytes);
+	for (i = 0; i < num_bytes / bytes_in_sample; i++) {
+		writew(priv(dev)->ao_bounce_buffer[i],
+			priv(dev)->main_iobase + DAC_FIFO_REG);
+	}
+	priv(dev)->ao_count -= num_bytes / bytes_in_sample;
+	if (cmd->stop_src == TRIG_COUNT && priv(dev)->ao_count == 0)
+		return 0;
+	num_bytes = load_ao_dma_buffer(dev, cmd);
+	if (num_bytes == 0)
+		return -1;
+	if (num_bytes >= DMA_BUFFER_SIZE) ;
+	load_ao_dma(dev, cmd);
+
+	dma_start_sync(dev, 0);
+
+	return 0;
+}
+
+static inline int external_ai_queue_in_use(struct comedi_device * dev)
+{
+	if (dev->read_subdev->busy)
+		return 0;
+	if (board(dev)->layout == LAYOUT_4020)
+		return 0;
+	else if (use_internal_queue_6xxx(&dev->read_subdev->async->cmd))
+		return 0;
+	return 1;
+}
+
+static int ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_cmd *cmd = &s->async->cmd;
+
+	if (external_ai_queue_in_use(dev)) {
+		warn_external_queue(dev);
+		return -EBUSY;
+	}
+	/* disable analog output system during setup */
+	writew(0x0, priv(dev)->main_iobase + DAC_CONTROL0_REG);
+
+	priv(dev)->ao_dma_index = 0;
+	priv(dev)->ao_count = cmd->stop_arg * cmd->chanlist_len;
+
+	set_dac_select_reg(dev, cmd);
+	set_dac_interval_regs(dev, cmd);
+	load_first_dma_descriptor(dev, 0, priv(dev)->ao_dma_desc_bus_addr |
+		PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT);
+
+	set_dac_control1_reg(dev, cmd);
+	s->async->inttrig = ao_inttrig;
+
+	return 0;
+}
+
+static int ao_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int trig_num)
+{
+	struct comedi_cmd *cmd = &s->async->cmd;
+	int retval;
+
+	if (trig_num != 0)
+		return -EINVAL;
+
+	retval = prep_ao_dma(dev, cmd);
+	if (retval < 0)
+		return -EPIPE;
+
+	set_dac_control0_reg(dev, cmd);
+
+	if (cmd->start_src == TRIG_INT)
+		writew(0, priv(dev)->main_iobase + DAC_START_REG);
+
+	s->async->inttrig = NULL;
+
+	return 0;
+}
+
+static int ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp;
+	unsigned int tmp_arg;
+	int i;
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_INT | TRIG_EXT;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_NOW;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	// uniqueness check
+	if (cmd->start_src != TRIG_INT && cmd->start_src != TRIG_EXT)
+		err++;
+	if (cmd->scan_begin_src != TRIG_TIMER &&
+		cmd->scan_begin_src != TRIG_EXT)
+		err++;
+
+	// compatibility check
+	if (cmd->convert_src == TRIG_EXT && cmd->scan_begin_src == TRIG_TIMER)
+		err++;
+	if (cmd->stop_src != TRIG_COUNT &&
+		cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		if (cmd->scan_begin_arg < board(dev)->ao_scan_speed) {
+			cmd->scan_begin_arg = board(dev)->ao_scan_speed;
+			err++;
+		}
+		if (get_ao_divisor(cmd->scan_begin_arg,
+				cmd->flags) > max_counter_value) {
+			cmd->scan_begin_arg =
+				(max_counter_value + 2) * TIMER_BASE;
+			err++;
+		}
+	}
+
+	if (!cmd->chanlist_len) {
+		cmd->chanlist_len = 1;
+		err++;
+	}
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		tmp_arg = cmd->scan_begin_arg;
+		cmd->scan_begin_arg =
+			get_divisor(cmd->scan_begin_arg,
+			cmd->flags) * TIMER_BASE;
+		if (tmp_arg != cmd->scan_begin_arg)
+			err++;
+	}
+
+	if (err)
+		return 4;
+
+	if (cmd->chanlist) {
+		unsigned int first_channel = CR_CHAN(cmd->chanlist[0]);
+		for (i = 1; i < cmd->chanlist_len; i++) {
+			if (CR_CHAN(cmd->chanlist[i]) != first_channel + i) {
+				comedi_error(dev,
+					"chanlist must use consecutive channels");
+				err++;
+				break;
+			}
+		}
+	}
+
+	if (err)
+		return 5;
+
+	return 0;
+}
+
+static int ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	writew(0x0, priv(dev)->main_iobase + DAC_CONTROL0_REG);
+	abort_dma(dev, 0);
+	return 0;
+}
+
+static int dio_callback(int dir, int port, int data, unsigned long iobase)
+{
+	if (dir) {
+		writeb(data, (void *)(iobase + port));
+		DEBUG_PRINT("wrote 0x%x to port %i\n", data, port);
+		return 0;
+	} else {
+		return readb((void *)(iobase + port));
+	}
+}
+
+static int dio_callback_4020(int dir, int port, int data, unsigned long iobase)
+{
+	if (dir) {
+		writew(data, (void *)(iobase + 2 * port));
+		return 0;
+	} else {
+		return readw((void *)(iobase + 2 * port));
+	}
+}
+
+static int di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int bits;
+
+	bits = readb(priv(dev)->dio_counter_iobase + DI_REG);
+	bits &= 0xf;
+	data[1] = bits;
+	data[0] = 0;
+
+	return 2;
+}
+
+static int do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	data[0] &= 0xf;
+	// zero bits we are going to change
+	s->state &= ~data[0];
+	// set new bits
+	s->state |= data[0] & data[1];
+
+	writeb(s->state, priv(dev)->dio_counter_iobase + DO_REG);
+
+	data[1] = s->state;
+
+	return 2;
+}
+
+static int dio_60xx_config_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int mask;
+
+	mask = 1 << CR_CHAN(insn->chanspec);
+
+	switch (data[0]) {
+	case INSN_CONFIG_DIO_INPUT:
+		s->io_bits &= ~mask;
+		break;
+	case INSN_CONFIG_DIO_OUTPUT:
+		s->io_bits |= mask;
+		break;
+	case INSN_CONFIG_DIO_QUERY:
+		data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
+		return 2;
+	default:
+		return -EINVAL;
+	}
+
+	writeb(s->io_bits,
+		priv(dev)->dio_counter_iobase + DIO_DIRECTION_60XX_REG);
+
+	return 1;
+}
+
+static int dio_60xx_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= (data[0] & data[1]);
+		writeb(s->state,
+			priv(dev)->dio_counter_iobase + DIO_DATA_60XX_REG);
+	}
+
+	data[1] = readb(priv(dev)->dio_counter_iobase + DIO_DATA_60XX_REG);
+
+	return 2;
+}
+
+static void caldac_write(struct comedi_device * dev, unsigned int channel,
+	unsigned int value)
+{
+	priv(dev)->caldac_state[channel] = value;
+
+	switch (board(dev)->layout) {
+	case LAYOUT_60XX:
+	case LAYOUT_64XX:
+		caldac_8800_write(dev, channel, value);
+		break;
+	case LAYOUT_4020:
+		caldac_i2c_write(dev, channel, value);
+		break;
+	default:
+		break;
+	}
+}
+
+static int calib_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int channel = CR_CHAN(insn->chanspec);
+
+	/* return immediately if setting hasn't changed, since
+	 * programming these things is slow */
+	if (priv(dev)->caldac_state[channel] == data[0])
+		return 1;
+
+	caldac_write(dev, channel, data[0]);
+
+	return 1;
+}
+
+static int calib_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int channel = CR_CHAN(insn->chanspec);
+
+	data[0] = priv(dev)->caldac_state[channel];
+
+	return 1;
+}
+
+static void ad8402_write(struct comedi_device * dev, unsigned int channel,
+	unsigned int value)
+{
+	static const int bitstream_length = 10;
+	unsigned int bit, register_bits;
+	unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
+	static const int ad8402_comedi_udelay = 1;
+
+	priv(dev)->ad8402_state[channel] = value;
+
+	register_bits = SELECT_8402_64XX_BIT;
+	comedi_udelay(ad8402_comedi_udelay);
+	writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG);
+
+	for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
+		if (bitstream & bit)
+			register_bits |= SERIAL_DATA_IN_BIT;
+		else
+			register_bits &= ~SERIAL_DATA_IN_BIT;
+		comedi_udelay(ad8402_comedi_udelay);
+		writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG);
+		comedi_udelay(ad8402_comedi_udelay);
+		writew(register_bits | SERIAL_CLOCK_BIT,
+			priv(dev)->main_iobase + CALIBRATION_REG);
+	}
+
+	comedi_udelay(ad8402_comedi_udelay);
+	writew(0, priv(dev)->main_iobase + CALIBRATION_REG);
+}
+
+/* for pci-das6402/16, channel 0 is analog input gain and channel 1 is offset */
+static int ad8402_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int channel = CR_CHAN(insn->chanspec);
+
+	/* return immediately if setting hasn't changed, since
+	 * programming these things is slow */
+	if (priv(dev)->ad8402_state[channel] == data[0])
+		return 1;
+
+	priv(dev)->ad8402_state[channel] = data[0];
+
+	ad8402_write(dev, channel, data[0]);
+
+	return 1;
+}
+
+static int ad8402_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int channel = CR_CHAN(insn->chanspec);
+
+	data[0] = priv(dev)->ad8402_state[channel];
+
+	return 1;
+}
+
+static uint16_t read_eeprom(struct comedi_device * dev, uint8_t address)
+{
+	static const int bitstream_length = 11;
+	static const int read_command = 0x6;
+	unsigned int bitstream = (read_command << 8) | address;
+	unsigned int bit;
+	void *const plx_control_addr =
+		priv(dev)->plx9080_iobase + PLX_CONTROL_REG;
+	uint16_t value;
+	static const int value_length = 16;
+	static const int eeprom_comedi_udelay = 1;
+
+	comedi_udelay(eeprom_comedi_udelay);
+	priv(dev)->plx_control_bits &= ~CTL_EE_CLK & ~CTL_EE_CS;
+	// make sure we don't send anything to the i2c bus on 4020
+	priv(dev)->plx_control_bits |= CTL_USERO;
+	writel(priv(dev)->plx_control_bits, plx_control_addr);
+	// activate serial eeprom
+	comedi_udelay(eeprom_comedi_udelay);
+	priv(dev)->plx_control_bits |= CTL_EE_CS;
+	writel(priv(dev)->plx_control_bits, plx_control_addr);
+
+	// write read command and desired memory address
+	for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
+		// set bit to be written
+		comedi_udelay(eeprom_comedi_udelay);
+		if (bitstream & bit)
+			priv(dev)->plx_control_bits |= CTL_EE_W;
+		else
+			priv(dev)->plx_control_bits &= ~CTL_EE_W;
+		writel(priv(dev)->plx_control_bits, plx_control_addr);
+		// clock in bit
+		comedi_udelay(eeprom_comedi_udelay);
+		priv(dev)->plx_control_bits |= CTL_EE_CLK;
+		writel(priv(dev)->plx_control_bits, plx_control_addr);
+		comedi_udelay(eeprom_comedi_udelay);
+		priv(dev)->plx_control_bits &= ~CTL_EE_CLK;
+		writel(priv(dev)->plx_control_bits, plx_control_addr);
+	}
+	// read back value from eeprom memory location
+	value = 0;
+	for (bit = 1 << (value_length - 1); bit; bit >>= 1) {
+		// clock out bit
+		comedi_udelay(eeprom_comedi_udelay);
+		priv(dev)->plx_control_bits |= CTL_EE_CLK;
+		writel(priv(dev)->plx_control_bits, plx_control_addr);
+		comedi_udelay(eeprom_comedi_udelay);
+		priv(dev)->plx_control_bits &= ~CTL_EE_CLK;
+		writel(priv(dev)->plx_control_bits, plx_control_addr);
+		comedi_udelay(eeprom_comedi_udelay);
+		if (readl(plx_control_addr) & CTL_EE_R)
+			value |= bit;
+	}
+
+	// deactivate eeprom serial input
+	comedi_udelay(eeprom_comedi_udelay);
+	priv(dev)->plx_control_bits &= ~CTL_EE_CS;
+	writel(priv(dev)->plx_control_bits, plx_control_addr);
+
+	return value;
+}
+
+static int eeprom_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	data[0] = read_eeprom(dev, CR_CHAN(insn->chanspec));
+
+	return 1;
+}
+
+/* utility function that rounds desired timing to an achievable time, and
+ * sets cmd members appropriately.
+ * adc paces conversions from master clock by dividing by (x + 3) where x is 24 bit number
+ */
+static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
+{
+	unsigned int convert_divisor = 0, scan_divisor;
+	static const int min_convert_divisor = 3;
+	static const int max_convert_divisor =
+		max_counter_value + min_convert_divisor;
+	static const int min_scan_divisor_4020 = 2;
+	unsigned long long max_scan_divisor, min_scan_divisor;
+
+	if (cmd->convert_src == TRIG_TIMER) {
+		if (board(dev)->layout == LAYOUT_4020) {
+			cmd->convert_arg = 0;
+		} else {
+			convert_divisor =
+				get_divisor(cmd->convert_arg, cmd->flags);
+			if (convert_divisor > max_convert_divisor)
+				convert_divisor = max_convert_divisor;
+			if (convert_divisor < min_convert_divisor)
+				convert_divisor = min_convert_divisor;
+			cmd->convert_arg = convert_divisor * TIMER_BASE;
+		}
+	} else if (cmd->convert_src == TRIG_NOW)
+		cmd->convert_arg = 0;
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		scan_divisor = get_divisor(cmd->scan_begin_arg, cmd->flags);
+		if (cmd->convert_src == TRIG_TIMER) {
+			// XXX check for integer overflows
+			min_scan_divisor = convert_divisor * cmd->chanlist_len;
+			max_scan_divisor =
+				(convert_divisor * cmd->chanlist_len - 1) +
+				max_counter_value;
+		} else {
+			min_scan_divisor = min_scan_divisor_4020;
+			max_scan_divisor = max_counter_value + min_scan_divisor;
+		}
+		if (scan_divisor > max_scan_divisor)
+			scan_divisor = max_scan_divisor;
+		if (scan_divisor < min_scan_divisor)
+			scan_divisor = min_scan_divisor;
+		cmd->scan_begin_arg = scan_divisor * TIMER_BASE;
+	}
+
+	return;
+}
+
+/* Gets nearest achievable timing given master clock speed, does not
+ * take into account possible minimum/maximum divisor values.  Used
+ * by other timing checking functions. */
+static unsigned int get_divisor(unsigned int ns, unsigned int flags)
+{
+	unsigned int divisor;
+
+	switch (flags & TRIG_ROUND_MASK) {
+	case TRIG_ROUND_UP:
+		divisor = (ns + TIMER_BASE - 1) / TIMER_BASE;
+		break;
+	case TRIG_ROUND_DOWN:
+		divisor = ns / TIMER_BASE;
+		break;
+	case TRIG_ROUND_NEAREST:
+	default:
+		divisor = (ns + TIMER_BASE / 2) / TIMER_BASE;
+		break;
+	}
+	return divisor;
+}
+
+static unsigned int get_ao_divisor(unsigned int ns, unsigned int flags)
+{
+	return get_divisor(ns, flags) - 2;
+}
+
+// adjusts the size of hardware fifo (which determines block size for dma xfers)
+static int set_ai_fifo_size(struct comedi_device * dev, unsigned int num_samples)
+{
+	unsigned int num_fifo_entries;
+	int retval;
+	const struct hw_fifo_info *const fifo = board(dev)->ai_fifo;
+
+	num_fifo_entries = num_samples / fifo->sample_packing_ratio;
+
+	retval = set_ai_fifo_segment_length(dev,
+		num_fifo_entries / fifo->num_segments);
+	if (retval < 0)
+		return retval;
+
+	num_samples = retval * fifo->num_segments * fifo->sample_packing_ratio;
+
+	DEBUG_PRINT("set hardware fifo size to %i\n", num_samples);
+
+	return num_samples;
+}
+
+// query length of fifo
+static unsigned int ai_fifo_size(struct comedi_device * dev)
+{
+	return priv(dev)->ai_fifo_segment_length *
+		board(dev)->ai_fifo->num_segments *
+		board(dev)->ai_fifo->sample_packing_ratio;
+}
+
+static int set_ai_fifo_segment_length(struct comedi_device * dev,
+	unsigned int num_entries)
+{
+	static const int increment_size = 0x100;
+	const struct hw_fifo_info *const fifo = board(dev)->ai_fifo;
+	unsigned int num_increments;
+	uint16_t bits;
+
+	if (num_entries < increment_size)
+		num_entries = increment_size;
+	if (num_entries > fifo->max_segment_length)
+		num_entries = fifo->max_segment_length;
+
+	// 1 == 256 entries, 2 == 512 entries, etc
+	num_increments = (num_entries + increment_size / 2) / increment_size;
+
+	bits = (~(num_increments - 1)) & fifo->fifo_size_reg_mask;
+	priv(dev)->fifo_size_bits &= ~fifo->fifo_size_reg_mask;
+	priv(dev)->fifo_size_bits |= bits;
+	writew(priv(dev)->fifo_size_bits,
+		priv(dev)->main_iobase + FIFO_SIZE_REG);
+
+	priv(dev)->ai_fifo_segment_length = num_increments * increment_size;
+
+	DEBUG_PRINT("set hardware fifo segment length to %i\n",
+		priv(dev)->ai_fifo_segment_length);
+
+	return priv(dev)->ai_fifo_segment_length;
+}
+
+/* pci-6025 8800 caldac:
+ * address 0 == dac channel 0 offset
+ * address 1 == dac channel 0 gain
+ * address 2 == dac channel 1 offset
+ * address 3 == dac channel 1 gain
+ * address 4 == fine adc offset
+ * address 5 == coarse adc offset
+ * address 6 == coarse adc gain
+ * address 7 == fine adc gain
+ */
+/* pci-6402/16 uses all 8 channels for dac:
+ * address 0 == dac channel 0 fine gain
+ * address 1 == dac channel 0 coarse gain
+ * address 2 == dac channel 0 coarse offset
+ * address 3 == dac channel 1 coarse offset
+ * address 4 == dac channel 1 fine gain
+ * address 5 == dac channel 1 coarse gain
+ * address 6 == dac channel 0 fine offset
+ * address 7 == dac channel 1 fine offset
+*/
+
+static int caldac_8800_write(struct comedi_device * dev, unsigned int address,
+	uint8_t value)
+{
+	static const int num_caldac_channels = 8;
+	static const int bitstream_length = 11;
+	unsigned int bitstream = ((address & 0x7) << 8) | value;
+	unsigned int bit, register_bits;
+	static const int caldac_8800_udelay = 1;
+
+	if (address >= num_caldac_channels) {
+		comedi_error(dev, "illegal caldac channel");
+		return -1;
+	}
+	for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
+		register_bits = 0;
+		if (bitstream & bit)
+			register_bits |= SERIAL_DATA_IN_BIT;
+		comedi_udelay(caldac_8800_udelay);
+		writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG);
+		register_bits |= SERIAL_CLOCK_BIT;
+		comedi_udelay(caldac_8800_udelay);
+		writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG);
+	}
+	comedi_udelay(caldac_8800_udelay);
+	writew(SELECT_8800_BIT, priv(dev)->main_iobase + CALIBRATION_REG);
+	comedi_udelay(caldac_8800_udelay);
+	writew(0, priv(dev)->main_iobase + CALIBRATION_REG);
+	comedi_udelay(caldac_8800_udelay);
+	return 0;
+}
+
+// 4020 caldacs
+static int caldac_i2c_write(struct comedi_device * dev, unsigned int caldac_channel,
+	unsigned int value)
+{
+	uint8_t serial_bytes[3];
+	uint8_t i2c_addr;
+	enum pointer_bits {
+		// manual has gain and offset bits switched
+		OFFSET_0_2 = 0x1,
+		GAIN_0_2 = 0x2,
+		OFFSET_1_3 = 0x4,
+		GAIN_1_3 = 0x8,
+	};
+	enum data_bits {
+		NOT_CLEAR_REGISTERS = 0x20,
+	};
+
+	switch (caldac_channel) {
+	case 0:		// chan 0 offset
+		i2c_addr = CALDAC0_I2C_ADDR;
+		serial_bytes[0] = OFFSET_0_2;
+		break;
+	case 1:		// chan 1 offset
+		i2c_addr = CALDAC0_I2C_ADDR;
+		serial_bytes[0] = OFFSET_1_3;
+		break;
+	case 2:		// chan 2 offset
+		i2c_addr = CALDAC1_I2C_ADDR;
+		serial_bytes[0] = OFFSET_0_2;
+		break;
+	case 3:		// chan 3 offset
+		i2c_addr = CALDAC1_I2C_ADDR;
+		serial_bytes[0] = OFFSET_1_3;
+		break;
+	case 4:		// chan 0 gain
+		i2c_addr = CALDAC0_I2C_ADDR;
+		serial_bytes[0] = GAIN_0_2;
+		break;
+	case 5:		// chan 1 gain
+		i2c_addr = CALDAC0_I2C_ADDR;
+		serial_bytes[0] = GAIN_1_3;
+		break;
+	case 6:		// chan 2 gain
+		i2c_addr = CALDAC1_I2C_ADDR;
+		serial_bytes[0] = GAIN_0_2;
+		break;
+	case 7:		// chan 3 gain
+		i2c_addr = CALDAC1_I2C_ADDR;
+		serial_bytes[0] = GAIN_1_3;
+		break;
+	default:
+		comedi_error(dev, "invalid caldac channel\n");
+		return -1;
+		break;
+	}
+	serial_bytes[1] = NOT_CLEAR_REGISTERS | ((value >> 8) & 0xf);
+	serial_bytes[2] = value & 0xff;
+	i2c_write(dev, i2c_addr, serial_bytes, 3);
+	return 0;
+}
+
+// Their i2c requires a huge delay on setting clock or data high for some reason
+static const int i2c_high_comedi_udelay = 1000;
+static const int i2c_low_comedi_udelay = 10;
+
+// set i2c data line high or low
+static void i2c_set_sda(struct comedi_device * dev, int state)
+{
+	static const int data_bit = CTL_EE_W;
+	void *plx_control_addr = priv(dev)->plx9080_iobase + PLX_CONTROL_REG;
+
+	if (state) {
+		// set data line high
+		priv(dev)->plx_control_bits &= ~data_bit;
+		writel(priv(dev)->plx_control_bits, plx_control_addr);
+		comedi_udelay(i2c_high_comedi_udelay);
+	} else			// set data line low
+	{
+		priv(dev)->plx_control_bits |= data_bit;
+		writel(priv(dev)->plx_control_bits, plx_control_addr);
+		comedi_udelay(i2c_low_comedi_udelay);
+	}
+}
+
+// set i2c clock line high or low
+static void i2c_set_scl(struct comedi_device * dev, int state)
+{
+	static const int clock_bit = CTL_USERO;
+	void *plx_control_addr = priv(dev)->plx9080_iobase + PLX_CONTROL_REG;
+
+	if (state) {
+		// set clock line high
+		priv(dev)->plx_control_bits &= ~clock_bit;
+		writel(priv(dev)->plx_control_bits, plx_control_addr);
+		comedi_udelay(i2c_high_comedi_udelay);
+	} else			// set clock line low
+	{
+		priv(dev)->plx_control_bits |= clock_bit;
+		writel(priv(dev)->plx_control_bits, plx_control_addr);
+		comedi_udelay(i2c_low_comedi_udelay);
+	}
+}
+
+static void i2c_write_byte(struct comedi_device * dev, uint8_t byte)
+{
+	uint8_t bit;
+	unsigned int num_bits = 8;
+
+	DEBUG_PRINT("writing to i2c byte 0x%x\n", byte);
+
+	for (bit = 1 << (num_bits - 1); bit; bit >>= 1) {
+		i2c_set_scl(dev, 0);
+		if ((byte & bit))
+			i2c_set_sda(dev, 1);
+		else
+			i2c_set_sda(dev, 0);
+		i2c_set_scl(dev, 1);
+	}
+}
+
+// we can't really read the lines, so fake it
+static int i2c_read_ack(struct comedi_device * dev)
+{
+	i2c_set_scl(dev, 0);
+	i2c_set_sda(dev, 1);
+	i2c_set_scl(dev, 1);
+
+	return 0;		// return fake acknowledge bit
+}
+
+// send start bit
+static void i2c_start(struct comedi_device * dev)
+{
+	i2c_set_scl(dev, 1);
+	i2c_set_sda(dev, 1);
+	i2c_set_sda(dev, 0);
+}
+
+// send stop bit
+static void i2c_stop(struct comedi_device * dev)
+{
+	i2c_set_scl(dev, 0);
+	i2c_set_sda(dev, 0);
+	i2c_set_scl(dev, 1);
+	i2c_set_sda(dev, 1);
+}
+
+static void i2c_write(struct comedi_device * dev, unsigned int address,
+	const uint8_t * data, unsigned int length)
+{
+	unsigned int i;
+	uint8_t bitstream;
+	static const int read_bit = 0x1;
+
+//XXX need mutex to prevent simultaneous attempts to access eeprom and i2c bus
+
+	// make sure we dont send anything to eeprom
+	priv(dev)->plx_control_bits &= ~CTL_EE_CS;
+
+	i2c_stop(dev);
+	i2c_start(dev);
+
+	// send address and write bit
+	bitstream = (address << 1) & ~read_bit;
+	i2c_write_byte(dev, bitstream);
+
+	// get acknowledge
+	if (i2c_read_ack(dev) != 0) {
+		comedi_error(dev, "i2c write failed: no acknowledge");
+		i2c_stop(dev);
+		return;
+	}
+	// write data bytes
+	for (i = 0; i < length; i++) {
+		i2c_write_byte(dev, data[i]);
+		if (i2c_read_ack(dev) != 0) {
+			comedi_error(dev, "i2c write failed: no acknowledge");
+			i2c_stop(dev);
+			return;
+		}
+	}
+	i2c_stop(dev);
+}
diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c
new file mode 100644
index 0000000..ed0a5eb3
--- /dev/null
+++ b/drivers/staging/comedi/drivers/cb_pcidda.c
@@ -0,0 +1,841 @@
+/*
+    comedi/drivers/cb_pcidda.c
+    This intends to be a driver for the ComputerBoards / MeasurementComputing
+    PCI-DDA series.
+
+	 Copyright (C) 2001 Ivan Martinez <ivanmr@altavista.com>
+    Copyright (C) 2001 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 1997-8 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: cb_pcidda
+Description: MeasurementComputing PCI-DDA series
+Author: Ivan Martinez <ivanmr@altavista.com>, Frank Mori Hess <fmhess@users.sourceforge.net>
+Status: Supports 08/16, 04/16, 02/16, 08/12, 04/12, and 02/12
+Devices: [Measurement Computing] PCI-DDA08/12 (cb_pcidda), PCI-DDA04/12,
+  PCI-DDA02/12, PCI-DDA08/16, PCI-DDA04/16, PCI-DDA02/16
+
+Configuration options:
+  [0] - PCI bus of device (optional)
+  [1] - PCI slot of device (optional)
+  If bus/slot is not specified, the first available PCI
+  device will be used.
+
+Only simple analog output writing is supported.
+
+So far it has only been tested with:
+  - PCI-DDA08/12
+Please report success/failure with other different cards to
+<comedi@comedi.org>.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+#include "8255.h"
+
+#define PCI_VENDOR_ID_CB	0x1307	// PCI vendor number of ComputerBoards
+#define N_BOARDS	10	// Number of boards in cb_pcidda_boards
+#define EEPROM_SIZE	128	// number of entries in eeprom
+#define MAX_AO_CHANNELS 8	// maximum number of ao channels for supported boards
+
+/* PCI-DDA base addresses */
+#define DIGITALIO_BADRINDEX	2
+	// DIGITAL I/O is pci_dev->resource[2]
+#define DIGITALIO_SIZE 8
+	// DIGITAL I/O uses 8 I/O port addresses
+#define DAC_BADRINDEX	3
+	// DAC is pci_dev->resource[3]
+
+/* Digital I/O registers */
+#define PORT1A 0		// PORT 1A DATA
+
+#define PORT1B 1		// PORT 1B DATA
+
+#define PORT1C 2		// PORT 1C DATA
+
+#define CONTROL1 3		// CONTROL REGISTER 1
+
+#define PORT2A 4		// PORT 2A DATA
+
+#define PORT2B 5		// PORT 2B DATA
+
+#define PORT2C 6		// PORT 2C DATA
+
+#define CONTROL2 7		// CONTROL REGISTER 2
+
+/* DAC registers */
+#define DACONTROL	0	// D/A CONTROL REGISTER
+#define	SU	0000001		// Simultaneous update enabled
+#define NOSU	0000000		// Simultaneous update disabled
+#define	ENABLEDAC	0000002	// Enable specified DAC
+#define	DISABLEDAC	0000000	// Disable specified DAC
+#define RANGE2V5	0000000	// 2.5V
+#define RANGE5V	0000200		// 5V
+#define RANGE10V	0000300	// 10V
+#define UNIP	0000400		// Unipolar outputs
+#define BIP	0000000		// Bipolar outputs
+
+#define DACALIBRATION1	4	// D/A CALIBRATION REGISTER 1
+//write bits
+#define	SERIAL_IN_BIT	0x1	// serial data input for eeprom, caldacs, reference dac
+#define	CAL_CHANNEL_MASK	(0x7 << 1)
+#define	CAL_CHANNEL_BITS(channel)	(((channel) << 1) & CAL_CHANNEL_MASK)
+//read bits
+#define	CAL_COUNTER_MASK	0x1f
+#define	CAL_COUNTER_OVERFLOW_BIT	0x20	// calibration counter overflow status bit
+#define	AO_BELOW_REF_BIT	0x40	// analog output is less than reference dac voltage
+#define	SERIAL_OUT_BIT	0x80	// serial data out, for reading from eeprom
+
+#define DACALIBRATION2	6	// D/A CALIBRATION REGISTER 2
+#define	SELECT_EEPROM_BIT	0x1	// send serial data in to eeprom
+#define	DESELECT_REF_DAC_BIT	0x2	// don't send serial data to MAX542 reference dac
+#define	DESELECT_CALDAC_BIT(n)	(0x4 << (n))	// don't send serial data to caldac n
+#define	DUMMY_BIT	0x40	// manual says to set this bit with no explanation
+
+#define DADATA	8		// FIRST D/A DATA REGISTER (0)
+
+static const struct comedi_lrange cb_pcidda_ranges = {
+	6,
+	{
+			BIP_RANGE(10),
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			UNI_RANGE(10),
+			UNI_RANGE(5),
+			UNI_RANGE(2.5),
+		}
+};
+
+/*
+ * Board descriptions for two imaginary boards.  Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct cb_pcidda_board {
+	const char *name;
+	char status;		// Driver status:
+	// 0 - tested
+	// 1 - manual read, not tested
+	// 2 - manual not read
+	unsigned short device_id;
+	int ao_chans;
+	int ao_bits;
+	const struct comedi_lrange *ranges;
+};
+static const struct cb_pcidda_board cb_pcidda_boards[] = {
+	{
+	      name:	"pci-dda02/12",
+	      status:	1,
+	      device_id:0x20,
+	      ao_chans:2,
+	      ao_bits:	12,
+	      ranges:	&cb_pcidda_ranges,
+		},
+	{
+	      name:	"pci-dda04/12",
+	      status:	1,
+	      device_id:0x21,
+	      ao_chans:4,
+	      ao_bits:	12,
+	      ranges:	&cb_pcidda_ranges,
+		},
+	{
+	      name:	"pci-dda08/12",
+	      status:	0,
+	      device_id:0x22,
+	      ao_chans:8,
+	      ao_bits:	12,
+	      ranges:	&cb_pcidda_ranges,
+		},
+	{
+	      name:	"pci-dda02/16",
+	      status:	2,
+	      device_id:0x23,
+	      ao_chans:2,
+	      ao_bits:	16,
+	      ranges:	&cb_pcidda_ranges,
+		},
+	{
+	      name:	"pci-dda04/16",
+	      status:	2,
+	      device_id:0x24,
+	      ao_chans:4,
+	      ao_bits:	16,
+	      ranges:	&cb_pcidda_ranges,
+		},
+	{
+	      name:	"pci-dda08/16",
+	      status:	0,
+	      device_id:0x25,
+	      ao_chans:8,
+	      ao_bits:	16,
+	      ranges:	&cb_pcidda_ranges,
+		},
+};
+
+static DEFINE_PCI_DEVICE_TABLE(cb_pcidda_pci_table) = {
+	{PCI_VENDOR_ID_CB, 0x0020, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_CB, 0x0021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_CB, 0x0022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_CB, 0x0023, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_CB, 0x0024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_CB, 0x0025, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, cb_pcidda_pci_table);
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct cb_pcidda_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver.  If
+   several hardware drivers keep similar information in this structure,
+   feel free to suggest moving the variable to the struct comedi_device struct.  */
+struct cb_pcidda_private {
+	int data;
+
+	/* would be useful for a PCI device */
+	struct pci_dev *pci_dev;
+
+	unsigned long digitalio;
+	unsigned long dac;
+	//unsigned long control_status;
+	//unsigned long adc_fifo;
+	unsigned int dac_cal1_bits;	// bits last written to da calibration register 1
+	unsigned int ao_range[MAX_AO_CHANNELS];	// current range settings for output channels
+	u16 eeprom_data[EEPROM_SIZE];	// software copy of board's eeprom
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct cb_pcidda_private *)dev->private)
+
+static int cb_pcidda_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int cb_pcidda_detach(struct comedi_device * dev);
+//static int cb_pcidda_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data);
+static int cb_pcidda_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+//static int cb_pcidda_ai_cmd(struct comedi_device *dev,struct comedi_subdevice *s);
+//static int cb_pcidda_ai_cmdtest(struct comedi_device *dev,struct comedi_subdevice *s, struct comedi_cmd *cmd);
+//static int cb_pcidda_ns_to_timer(unsigned int *ns,int round);
+static unsigned int cb_pcidda_serial_in(struct comedi_device * dev);
+static void cb_pcidda_serial_out(struct comedi_device * dev, unsigned int value,
+	unsigned int num_bits);
+static unsigned int cb_pcidda_read_eeprom(struct comedi_device * dev,
+	unsigned int address);
+static void cb_pcidda_calibrate(struct comedi_device * dev, unsigned int channel,
+	unsigned int range);
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static struct comedi_driver driver_cb_pcidda = {
+      driver_name:"cb_pcidda",
+      module:THIS_MODULE,
+      attach:cb_pcidda_attach,
+      detach:cb_pcidda_detach,
+};
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board.
+ */
+static int cb_pcidda_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	struct pci_dev *pcidev;
+	int index;
+
+	printk("comedi%d: cb_pcidda: ", dev->minor);
+
+/*
+ * Allocate the private structure area.
+ */
+	if (alloc_private(dev, sizeof(struct cb_pcidda_private)) < 0)
+		return -ENOMEM;
+
+/*
+ * Probe the device to determine what device in the series it is.
+ */
+	printk("\n");
+
+	for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+		pcidev != NULL;
+		pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+		if (pcidev->vendor == PCI_VENDOR_ID_CB) {
+			if (it->options[0] || it->options[1]) {
+				if (pcidev->bus->number != it->options[0] ||
+					PCI_SLOT(pcidev->devfn) !=
+					it->options[1]) {
+					continue;
+				}
+			}
+			for (index = 0; index < N_BOARDS; index++) {
+				if (cb_pcidda_boards[index].device_id ==
+					pcidev->device) {
+					goto found;
+				}
+			}
+		}
+	}
+	if (!pcidev) {
+		printk("Not a ComputerBoards/MeasurementComputing card on requested position\n");
+		return -EIO;
+	}
+      found:
+	devpriv->pci_dev = pcidev;
+	dev->board_ptr = cb_pcidda_boards + index;
+	// "thisboard" macro can be used from here.
+	printk("Found %s at requested position\n", thisboard->name);
+
+	/*
+	 * Enable PCI device and request regions.
+	 */
+	if (comedi_pci_enable(pcidev, thisboard->name)) {
+		printk("cb_pcidda: failed to enable PCI device and request regions\n");
+		return -EIO;
+	}
+
+/*
+ * Allocate the I/O ports.
+ */
+	devpriv->digitalio =
+		pci_resource_start(devpriv->pci_dev, DIGITALIO_BADRINDEX);
+	devpriv->dac = pci_resource_start(devpriv->pci_dev, DAC_BADRINDEX);
+
+/*
+ * Warn about the status of the driver.
+ */
+	if (thisboard->status == 2)
+		printk("WARNING: DRIVER FOR THIS BOARD NOT CHECKED WITH MANUAL. " "WORKS ASSUMING FULL COMPATIBILITY WITH PCI-DDA08/12. " "PLEASE REPORT USAGE TO <ivanmr@altavista.com>.\n");
+
+/*
+ * Initialize dev->board_name.
+ */
+	dev->board_name = thisboard->name;
+
+/*
+ * Allocate the subdevice structures.
+ */
+	if (alloc_subdevices(dev, 3) < 0)
+		return -ENOMEM;
+
+	s = dev->subdevices + 0;
+	/* analog output subdevice */
+	s->type = COMEDI_SUBD_AO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->n_chan = thisboard->ao_chans;
+	s->maxdata = (1 << thisboard->ao_bits) - 1;
+	s->range_table = thisboard->ranges;
+	s->insn_write = cb_pcidda_ao_winsn;
+//      s->subdev_flags |= SDF_CMD_READ;
+//      s->do_cmd = cb_pcidda_ai_cmd;
+//      s->do_cmdtest = cb_pcidda_ai_cmdtest;
+
+	// two 8255 digital io subdevices
+	s = dev->subdevices + 1;
+	subdev_8255_init(dev, s, NULL, devpriv->digitalio);
+	s = dev->subdevices + 2;
+	subdev_8255_init(dev, s, NULL, devpriv->digitalio + PORT2A);
+
+	printk(" eeprom:");
+	for (index = 0; index < EEPROM_SIZE; index++) {
+		devpriv->eeprom_data[index] = cb_pcidda_read_eeprom(dev, index);
+		printk(" %i:0x%x ", index, devpriv->eeprom_data[index]);
+	}
+	printk("\n");
+
+	// set calibrations dacs
+	for (index = 0; index < thisboard->ao_chans; index++)
+		cb_pcidda_calibrate(dev, index, devpriv->ao_range[index]);
+
+	return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device.  It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach().  dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int cb_pcidda_detach(struct comedi_device * dev)
+{
+/*
+ * Deallocate the I/O ports.
+ */
+	if (devpriv) {
+		if (devpriv->pci_dev) {
+			if (devpriv->dac) {
+				comedi_pci_disable(devpriv->pci_dev);
+			}
+			pci_dev_put(devpriv->pci_dev);
+		}
+	}
+	// cleanup 8255
+	if (dev->subdevices) {
+		subdev_8255_cleanup(dev, dev->subdevices + 1);
+		subdev_8255_cleanup(dev, dev->subdevices + 2);
+	}
+
+	printk("comedi%d: cb_pcidda: remove\n", dev->minor);
+
+	return 0;
+}
+
+/*
+ * I will program this later... ;-)
+ */
+#if 0
+static int cb_pcidda_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	printk("cb_pcidda_ai_cmd\n");
+	printk("subdev: %d\n", cmd->subdev);
+	printk("flags: %d\n", cmd->flags);
+	printk("start_src: %d\n", cmd->start_src);
+	printk("start_arg: %d\n", cmd->start_arg);
+	printk("scan_begin_src: %d\n", cmd->scan_begin_src);
+	printk("convert_src: %d\n", cmd->convert_src);
+	printk("convert_arg: %d\n", cmd->convert_arg);
+	printk("scan_end_src: %d\n", cmd->scan_end_src);
+	printk("scan_end_arg: %d\n", cmd->scan_end_arg);
+	printk("stop_src: %d\n", cmd->stop_src);
+	printk("stop_arg: %d\n", cmd->stop_arg);
+	printk("chanlist_len: %d\n", cmd->chanlist_len);
+}
+#endif
+
+#if 0
+static int cb_pcidda_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp;
+
+	/* cmdtest tests a particular command to see if it is valid.
+	 * Using the cmdtest ioctl, a user can create a valid cmd
+	 * and then have it executes by the cmd ioctl.
+	 *
+	 * cmdtest returns 1,2,3,4 or 0, depending on which tests
+	 * the command passes. */
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	/* note that mutual compatiblity is not an issue here */
+	if (cmd->scan_begin_src != TRIG_TIMER
+		&& cmd->scan_begin_src != TRIG_EXT)
+		err++;
+	if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+		err++;
+	if (cmd->stop_src != TRIG_TIMER && cmd->stop_src != TRIG_EXT)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+#define MAX_SPEED	10000	/* in nanoseconds */
+#define MIN_SPEED	1000000000	/* in nanoseconds */
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		if (cmd->scan_begin_arg < MAX_SPEED) {
+			cmd->scan_begin_arg = MAX_SPEED;
+			err++;
+		}
+		if (cmd->scan_begin_arg > MIN_SPEED) {
+			cmd->scan_begin_arg = MIN_SPEED;
+			err++;
+		}
+	} else {
+		/* external trigger */
+		/* should be level/edge, hi/lo specification here */
+		/* should specify multiple external triggers */
+		if (cmd->scan_begin_arg > 9) {
+			cmd->scan_begin_arg = 9;
+			err++;
+		}
+	}
+	if (cmd->convert_src == TRIG_TIMER) {
+		if (cmd->convert_arg < MAX_SPEED) {
+			cmd->convert_arg = MAX_SPEED;
+			err++;
+		}
+		if (cmd->convert_arg > MIN_SPEED) {
+			cmd->convert_arg = MIN_SPEED;
+			err++;
+		}
+	} else {
+		/* external trigger */
+		/* see above */
+		if (cmd->convert_arg > 9) {
+			cmd->convert_arg = 9;
+			err++;
+		}
+	}
+
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+	if (cmd->stop_src == TRIG_COUNT) {
+		if (cmd->stop_arg > 0x00ffffff) {
+			cmd->stop_arg = 0x00ffffff;
+			err++;
+		}
+	} else {
+		/* TRIG_NONE */
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		tmp = cmd->scan_begin_arg;
+		cb_pcidda_ns_to_timer(&cmd->scan_begin_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+		if (tmp != cmd->scan_begin_arg)
+			err++;
+	}
+	if (cmd->convert_src == TRIG_TIMER) {
+		tmp = cmd->convert_arg;
+		cb_pcidda_ns_to_timer(&cmd->convert_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+		if (tmp != cmd->convert_arg)
+			err++;
+		if (cmd->scan_begin_src == TRIG_TIMER &&
+			cmd->scan_begin_arg <
+			cmd->convert_arg * cmd->scan_end_arg) {
+			cmd->scan_begin_arg =
+				cmd->convert_arg * cmd->scan_end_arg;
+			err++;
+		}
+	}
+
+	if (err)
+		return 4;
+
+	return 0;
+}
+#endif
+
+/* This function doesn't require a particular form, this is just
+ * what happens to be used in some of the drivers.  It should
+ * convert ns nanoseconds to a counter value suitable for programming
+ * the device.  Also, it should adjust ns so that it cooresponds to
+ * the actual time that the device will use. */
+#if 0
+static int cb_pcidda_ns_to_timer(unsigned int *ns, int round)
+{
+	/* trivial timer */
+	return *ns;
+}
+#endif
+
+static int cb_pcidda_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int command;
+	unsigned int channel, range;
+
+	channel = CR_CHAN(insn->chanspec);
+	range = CR_RANGE(insn->chanspec);
+
+	// adjust calibration dacs if range has changed
+	if (range != devpriv->ao_range[channel])
+		cb_pcidda_calibrate(dev, channel, range);
+
+	/* output channel configuration */
+	command = NOSU | ENABLEDAC;
+
+	/* output channel range */
+	switch (range) {
+	case 0:
+		command |= BIP | RANGE10V;
+		break;
+	case 1:
+		command |= BIP | RANGE5V;
+		break;
+	case 2:
+		command |= BIP | RANGE2V5;
+		break;
+	case 3:
+		command |= UNIP | RANGE10V;
+		break;
+	case 4:
+		command |= UNIP | RANGE5V;
+		break;
+	case 5:
+		command |= UNIP | RANGE2V5;
+		break;
+	};
+
+	/* output channel specification */
+	command |= channel << 2;
+	outw(command, devpriv->dac + DACONTROL);
+
+	/* write data */
+	outw(data[0], devpriv->dac + DADATA + channel * 2);
+
+	/* return the number of samples read/written */
+	return 1;
+}
+
+// lowlevel read from eeprom
+static unsigned int cb_pcidda_serial_in(struct comedi_device * dev)
+{
+	unsigned int value = 0;
+	int i;
+	const int value_width = 16;	// number of bits wide values are
+
+	for (i = 1; i <= value_width; i++) {
+		// read bits most significant bit first
+		if (inw_p(devpriv->dac + DACALIBRATION1) & SERIAL_OUT_BIT) {
+			value |= 1 << (value_width - i);
+		}
+	}
+
+	return value;
+}
+
+// lowlevel write to eeprom/dac
+static void cb_pcidda_serial_out(struct comedi_device * dev, unsigned int value,
+	unsigned int num_bits)
+{
+	int i;
+
+	for (i = 1; i <= num_bits; i++) {
+		// send bits most significant bit first
+		if (value & (1 << (num_bits - i)))
+			devpriv->dac_cal1_bits |= SERIAL_IN_BIT;
+		else
+			devpriv->dac_cal1_bits &= ~SERIAL_IN_BIT;
+		outw_p(devpriv->dac_cal1_bits, devpriv->dac + DACALIBRATION1);
+	}
+}
+
+// reads a 16 bit value from board's eeprom
+static unsigned int cb_pcidda_read_eeprom(struct comedi_device * dev,
+	unsigned int address)
+{
+	unsigned int i;
+	unsigned int cal2_bits;
+	unsigned int value;
+	const int max_num_caldacs = 4;	// one caldac for every two dac channels
+	const int read_instruction = 0x6;	// bits to send to tell eeprom we want to read
+	const int instruction_length = 3;
+	const int address_length = 8;
+
+	// send serial output stream to eeprom
+	cal2_bits = SELECT_EEPROM_BIT | DESELECT_REF_DAC_BIT | DUMMY_BIT;
+	// deactivate caldacs (one caldac for every two channels)
+	for (i = 0; i < max_num_caldacs; i++) {
+		cal2_bits |= DESELECT_CALDAC_BIT(i);
+	}
+	outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
+
+	// tell eeprom we want to read
+	cb_pcidda_serial_out(dev, read_instruction, instruction_length);
+	// send address we want to read from
+	cb_pcidda_serial_out(dev, address, address_length);
+
+	value = cb_pcidda_serial_in(dev);
+
+	// deactivate eeprom
+	cal2_bits &= ~SELECT_EEPROM_BIT;
+	outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
+
+	return value;
+}
+
+// writes to 8 bit calibration dacs
+static void cb_pcidda_write_caldac(struct comedi_device * dev, unsigned int caldac,
+	unsigned int channel, unsigned int value)
+{
+	unsigned int cal2_bits;
+	unsigned int i;
+	const int num_channel_bits = 3;	// caldacs use 3 bit channel specification
+	const int num_caldac_bits = 8;	// 8 bit calibration dacs
+	const int max_num_caldacs = 4;	// one caldac for every two dac channels
+
+	/* write 3 bit channel */
+	cb_pcidda_serial_out(dev, channel, num_channel_bits);
+	// write 8 bit caldac value
+	cb_pcidda_serial_out(dev, value, num_caldac_bits);
+
+	// latch stream into appropriate caldac
+	// deselect reference dac
+	cal2_bits = DESELECT_REF_DAC_BIT | DUMMY_BIT;
+	// deactivate caldacs (one caldac for every two channels)
+	for (i = 0; i < max_num_caldacs; i++) {
+		cal2_bits |= DESELECT_CALDAC_BIT(i);
+	}
+	// activate the caldac we want
+	cal2_bits &= ~DESELECT_CALDAC_BIT(caldac);
+	outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
+	// deactivate caldac
+	cal2_bits |= DESELECT_CALDAC_BIT(caldac);
+	outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
+}
+
+// returns caldac that calibrates given analog out channel
+static unsigned int caldac_number(unsigned int channel)
+{
+	return channel / 2;
+}
+
+// returns caldac channel that provides fine gain for given ao channel
+static unsigned int fine_gain_channel(unsigned int ao_channel)
+{
+	return 4 * (ao_channel % 2);
+}
+
+// returns caldac channel that provides coarse gain for given ao channel
+static unsigned int coarse_gain_channel(unsigned int ao_channel)
+{
+	return 1 + 4 * (ao_channel % 2);
+}
+
+// returns caldac channel that provides coarse offset for given ao channel
+static unsigned int coarse_offset_channel(unsigned int ao_channel)
+{
+	return 2 + 4 * (ao_channel % 2);
+}
+
+// returns caldac channel that provides fine offset for given ao channel
+static unsigned int fine_offset_channel(unsigned int ao_channel)
+{
+	return 3 + 4 * (ao_channel % 2);
+}
+
+// returns eeprom address that provides offset for given ao channel and range
+static unsigned int offset_eeprom_address(unsigned int ao_channel,
+	unsigned int range)
+{
+	return 0x7 + 2 * range + 12 * ao_channel;
+}
+
+// returns eeprom address that provides gain calibration for given ao channel and range
+static unsigned int gain_eeprom_address(unsigned int ao_channel,
+	unsigned int range)
+{
+	return 0x8 + 2 * range + 12 * ao_channel;
+}
+
+// returns upper byte of eeprom entry, which gives the coarse adjustment values
+static unsigned int eeprom_coarse_byte(unsigned int word)
+{
+	return (word >> 8) & 0xff;
+}
+
+// returns lower byte of eeprom entry, which gives the fine adjustment values
+static unsigned int eeprom_fine_byte(unsigned int word)
+{
+	return word & 0xff;
+}
+
+// set caldacs to eeprom values for given channel and range
+static void cb_pcidda_calibrate(struct comedi_device * dev, unsigned int channel,
+	unsigned int range)
+{
+	unsigned int coarse_offset, fine_offset, coarse_gain, fine_gain;
+
+	// remember range so we can tell when we need to readjust calibration
+	devpriv->ao_range[channel] = range;
+
+	// get values from eeprom data
+	coarse_offset =
+		eeprom_coarse_byte(devpriv->
+		eeprom_data[offset_eeprom_address(channel, range)]);
+	fine_offset =
+		eeprom_fine_byte(devpriv->
+		eeprom_data[offset_eeprom_address(channel, range)]);
+	coarse_gain =
+		eeprom_coarse_byte(devpriv->
+		eeprom_data[gain_eeprom_address(channel, range)]);
+	fine_gain =
+		eeprom_fine_byte(devpriv->
+		eeprom_data[gain_eeprom_address(channel, range)]);
+
+	// set caldacs
+	cb_pcidda_write_caldac(dev, caldac_number(channel),
+		coarse_offset_channel(channel), coarse_offset);
+	cb_pcidda_write_caldac(dev, caldac_number(channel),
+		fine_offset_channel(channel), fine_offset);
+	cb_pcidda_write_caldac(dev, caldac_number(channel),
+		coarse_gain_channel(channel), coarse_gain);
+	cb_pcidda_write_caldac(dev, caldac_number(channel),
+		fine_gain_channel(channel), fine_gain);
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_PCI_INITCLEANUP(driver_cb_pcidda, cb_pcidda_pci_table);
diff --git a/drivers/staging/comedi/drivers/cb_pcidio.c b/drivers/staging/comedi/drivers/cb_pcidio.c
new file mode 100644
index 0000000..71a4b14
--- /dev/null
+++ b/drivers/staging/comedi/drivers/cb_pcidio.c
@@ -0,0 +1,294 @@
+/*
+    comedi/drivers/cb_pcidio.c
+    A Comedi driver for PCI-DIO24H & PCI-DIO48H of ComputerBoards (currently MeasurementComputing)
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: cb_pcidio
+Description: ComputerBoards' DIO boards with PCI interface
+Devices: [Measurement Computing] PCI-DIO24 (cb_pcidio), PCI-DIO24H, PCI-DIO48H
+Author: Yoshiya Matsuzaka
+Updated: Mon, 29 Oct 2007 15:40:47 +0000
+Status: experimental
+
+This driver has been modified from skel.c of comedi-0.7.70.
+
+Configuration Options:
+  [0] - PCI bus of device (optional)
+  [1] - PCI slot of device (optional)
+  If bus/slot is not specified, the first available PCI device will
+  be used.
+
+Passing a zero for an option is the same as leaving it unspecified.
+*/
+
+/*------------------------------ HEADER FILES ---------------------------------*/
+#include "../comedidev.h"
+#include "comedi_pci.h"
+#include "8255.h"
+
+/*-------------------------- MACROS and DATATYPES -----------------------------*/
+#define PCI_VENDOR_ID_CB	0x1307
+
+/*
+ * Board descriptions for two imaginary boards.  Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct pcidio_board {
+	const char *name;	// anme of the board
+	int n_8255;		// number of 8255 chips on board
+
+	// indices of base address regions
+	int pcicontroler_badrindex;
+	int dioregs_badrindex;
+};
+
+static const struct pcidio_board pcidio_boards[] = {
+	{
+	      name:	"pci-dio24",
+	      n_8255:	1,
+	      pcicontroler_badrindex:1,
+	      dioregs_badrindex:2,
+		},
+	{
+	      name:	"pci-dio24h",
+	      n_8255:	1,
+	      pcicontroler_badrindex:1,
+	      dioregs_badrindex:2,
+		},
+	{
+	      name:	"pci-dio48h",
+	      n_8255:	2,
+	      pcicontroler_badrindex:0,
+	      dioregs_badrindex:1,
+		},
+};
+
+/* This is used by modprobe to translate PCI IDs to drivers.  Should
+ * only be used for PCI and ISA-PnP devices */
+/* Please add your PCI vendor ID to comedidev.h, and it will be forwarded
+ * upstream. */
+static DEFINE_PCI_DEVICE_TABLE(pcidio_pci_table) = {
+	{PCI_VENDOR_ID_CB, 0x0028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_CB, 0x0014, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_CB, 0x000b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, pcidio_pci_table);
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct pcidio_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver.  If
+   several hardware drivers keep similar information in this structure,
+   feel free to suggest moving the variable to the struct comedi_device struct.  */
+struct pcidio_private {
+	int data;		// curently unused
+
+	/* would be useful for a PCI device */
+	struct pci_dev *pci_dev;
+
+	/* used for DO readback, curently unused */
+	unsigned int do_readback[4];	/* up to 4 unsigned int suffice to hold 96 bits for PCI-DIO96 */
+
+	unsigned long dio_reg_base;	// address of port A of the first 8255 chip on board
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct pcidio_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pcidio_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcidio_detach(struct comedi_device * dev);
+static struct comedi_driver driver_cb_pcidio = {
+      driver_name:"cb_pcidio",
+      module:THIS_MODULE,
+      attach:pcidio_attach,
+      detach:pcidio_detach,
+/* It is not necessary to implement the following members if you are
+ * writing a driver for a ISA PnP or PCI card */
+	/* Most drivers will support multiple types of boards by
+	 * having an array of board structures.  These were defined
+	 * in pcidio_boards[] above.  Note that the element 'name'
+	 * was first in the structure -- Comedi uses this fact to
+	 * extract the name of the board without knowing any details
+	 * about the structure except for its length.
+	 * When a device is attached (by comedi_config), the name
+	 * of the device is given to Comedi, and Comedi tries to
+	 * match it by going through the list of board names.  If
+	 * there is a match, the address of the pointer is put
+	 * into dev->board_ptr and driver->attach() is called.
+	 *
+	 * Note that these are not necessary if you can determine
+	 * the type of board in software.  ISA PnP, PCI, and PCMCIA
+	 * devices are such boards.
+	 */
+// The following fields should NOT be initialized if you are dealing with PCI devices
+//      board_name:     pcidio_boards,
+//      offset:         sizeof(struct pcidio_board),
+//      num_names:      sizeof(pcidio_boards) / sizeof(struct pcidio_board),
+};
+
+/*------------------------------- FUNCTIONS -----------------------------------*/
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board.  If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pcidio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct pci_dev *pcidev = NULL;
+	int index;
+	int i;
+
+	printk("comedi%d: cb_pcidio: \n", dev->minor);
+
+/*
+ * Allocate the private structure area.  alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+	if (alloc_private(dev, sizeof(struct pcidio_private)) < 0)
+		return -ENOMEM;
+/*
+ * If you can probe the device to determine what device in a series
+ * it is, this is the place to do it.  Otherwise, dev->board_ptr
+ * should already be initialized.
+ */
+/*
+ * Probe the device to determine what device in the series it is.
+ */
+
+	for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+		pcidev != NULL;
+		pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+		// is it not a computer boards card?
+		if (pcidev->vendor != PCI_VENDOR_ID_CB)
+			continue;
+		// loop through cards supported by this driver
+		for (index = 0;
+			index < sizeof pcidio_boards / sizeof(struct pcidio_board);
+			index++) {
+			if (pcidio_pci_table[index].device != pcidev->device)
+				continue;
+
+			// was a particular bus/slot requested?
+			if (it->options[0] || it->options[1]) {
+				// are we on the wrong bus/slot?
+				if (pcidev->bus->number != it->options[0] ||
+					PCI_SLOT(pcidev->devfn) !=
+					it->options[1]) {
+					continue;
+				}
+			}
+			dev->board_ptr = pcidio_boards + index;
+			goto found;
+		}
+	}
+
+	printk("No supported ComputerBoards/MeasurementComputing card found on "
+		"requested position\n");
+	return -EIO;
+
+      found:
+
+/*
+ * Initialize dev->board_name.  Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+	dev->board_name = thisboard->name;
+
+	devpriv->pci_dev = pcidev;
+	printk("Found %s on bus %i, slot %i\n", thisboard->name,
+		devpriv->pci_dev->bus->number,
+		PCI_SLOT(devpriv->pci_dev->devfn));
+	if (comedi_pci_enable(pcidev, thisboard->name)) {
+		printk("cb_pcidio: failed to enable PCI device and request regions\n");
+		return -EIO;
+	}
+	devpriv->dio_reg_base
+		=
+		pci_resource_start(devpriv->pci_dev,
+		pcidio_boards[index].dioregs_badrindex);
+
+/*
+ * Allocate the subdevice structures.  alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+	if (alloc_subdevices(dev, thisboard->n_8255) < 0)
+		return -ENOMEM;
+
+	for (i = 0; i < thisboard->n_8255; i++) {
+		subdev_8255_init(dev, dev->subdevices + i,
+			NULL, devpriv->dio_reg_base + i * 4);
+		printk(" subdev %d: base = 0x%lx\n", i,
+			devpriv->dio_reg_base + i * 4);
+	}
+
+	printk("attached\n");
+	return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device.  It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach().  dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pcidio_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: cb_pcidio: remove\n", dev->minor);
+	if (devpriv) {
+		if (devpriv->pci_dev) {
+			if (devpriv->dio_reg_base) {
+				comedi_pci_disable(devpriv->pci_dev);
+			}
+			pci_dev_put(devpriv->pci_dev);
+		}
+	}
+	if (dev->subdevices) {
+		int i;
+		for (i = 0; i < thisboard->n_8255; i++) {
+			subdev_8255_cleanup(dev, dev->subdevices + i);
+		}
+	}
+	return 0;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_PCI_INITCLEANUP(driver_cb_pcidio, pcidio_pci_table);
diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c
new file mode 100644
index 0000000..af705fa
--- /dev/null
+++ b/drivers/staging/comedi/drivers/cb_pcimdas.c
@@ -0,0 +1,484 @@
+/*
+    comedi/drivers/cb_pcimdas.c
+    Comedi driver for Computer Boards PCIM-DAS1602/16
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: cb_pcimdas
+Description: Measurement Computing PCI Migration series boards
+Devices: [ComputerBoards] PCIM-DAS1602/16 (cb_pcimdas)
+Author: Richard Bytheway
+Updated: Wed, 13 Nov 2002 12:34:56 +0000
+Status: experimental
+
+Written to support the PCIM-DAS1602/16 on a 2.4 series kernel.
+
+Configuration Options:
+    [0] - PCI bus number
+    [1] - PCI slot number
+
+Developed from cb_pcidas and skel by Richard Bytheway (mocelet@sucs.org).
+Only supports DIO, AO and simple AI in it's present form.
+No interrupts, multi channel or FIFO AI, although the card looks like it could support this.
+See http://www.measurementcomputing.com/PDFManuals/pcim-das1602_16.pdf for more details.
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+
+#include "comedi_pci.h"
+#include "plx9052.h"
+#include "8255.h"
+
+//#define CBPCIMDAS_DEBUG
+#undef CBPCIMDAS_DEBUG
+
+/* Registers for the PCIM-DAS1602/16 */
+
+// sizes of io regions (bytes)
+#define BADR0_SIZE 2		//??
+#define BADR1_SIZE 4
+#define BADR2_SIZE 6
+#define BADR3_SIZE 16
+#define BADR4_SIZE 4
+
+//DAC Offsets
+#define ADC_TRIG 0
+#define DAC0_OFFSET 2
+#define DAC1_OFFSET 4
+
+//AI and Counter Constants
+#define MUX_LIMITS 0
+#define MAIN_CONN_DIO 1
+#define ADC_STAT 2
+#define ADC_CONV_STAT 3
+#define ADC_INT 4
+#define ADC_PACER 5
+#define BURST_MODE 6
+#define PROG_GAIN 7
+#define CLK8254_1_DATA 8
+#define CLK8254_2_DATA 9
+#define CLK8254_3_DATA 10
+#define CLK8254_CONTROL 11
+#define USER_COUNTER 12
+#define RESID_COUNT_H 13
+#define RESID_COUNT_L 14
+
+/* Board description */
+struct cb_pcimdas_board {
+	const char *name;
+	unsigned short device_id;
+	int ai_se_chans;	// Inputs in single-ended mode
+	int ai_diff_chans;	// Inputs in differential mode
+	int ai_bits;		// analog input resolution
+	int ai_speed;		// fastest conversion period in ns
+	int ao_nchan;		// number of analog out channels
+	int ao_bits;		// analogue output resolution
+	int has_ao_fifo;	// analog output has fifo
+	int ao_scan_speed;	// analog output speed for 1602 series (for a scan, not conversion)
+	int fifo_size;		// number of samples fifo can hold
+	int dio_bits;		// number of dio bits
+	int has_dio;		// has DIO
+	const struct comedi_lrange *ranges;
+};
+
+static const struct cb_pcimdas_board cb_pcimdas_boards[] = {
+	{
+	      name:	"PCIM-DAS1602/16",
+	      device_id:0x56,
+	      ai_se_chans:16,
+	      ai_diff_chans:8,
+	      ai_bits:	16,
+	      ai_speed:10000,	//??
+	      ao_nchan:2,
+	      ao_bits:	12,
+	      has_ao_fifo:0,	//??
+	      ao_scan_speed:10000,
+			//??
+	      fifo_size:1024,
+	      dio_bits:24,
+	      has_dio:	1,
+//              ranges:         &cb_pcimdas_ranges,
+		},
+};
+
+/* This is used by modprobe to translate PCI IDs to drivers.  Should
+ * only be used for PCI and ISA-PnP devices */
+static DEFINE_PCI_DEVICE_TABLE(cb_pcimdas_pci_table) = {
+	{PCI_VENDOR_ID_COMPUTERBOARDS, 0x0056, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, cb_pcimdas_pci_table);
+
+#define N_BOARDS 1		// Max number of boards supported
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct cb_pcimdas_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver.  If
+   several hardware drivers keep similar information in this structure,
+   feel free to suggest moving the variable to the struct comedi_device struct.  */
+struct cb_pcimdas_private {
+	int data;
+
+	// would be useful for a PCI device
+	struct pci_dev *pci_dev;
+
+	//base addresses
+	unsigned long BADR0;
+	unsigned long BADR1;
+	unsigned long BADR2;
+	unsigned long BADR3;
+	unsigned long BADR4;
+
+	/* Used for AO readback */
+	unsigned int ao_readback[2];
+
+	// Used for DIO
+	unsigned short int port_a;	// copy of BADR4+0
+	unsigned short int port_b;	// copy of BADR4+1
+	unsigned short int port_c;	// copy of BADR4+2
+	unsigned short int dio_mode;	// copy of BADR4+3
+
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct cb_pcimdas_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int cb_pcimdas_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int cb_pcimdas_detach(struct comedi_device * dev);
+static struct comedi_driver driver_cb_pcimdas = {
+      driver_name:"cb_pcimdas",
+      module:THIS_MODULE,
+      attach:cb_pcimdas_attach,
+      detach:cb_pcimdas_detach,
+};
+
+static int cb_pcimdas_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int cb_pcimdas_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int cb_pcimdas_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board.  If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int cb_pcimdas_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	struct pci_dev *pcidev;
+	int index;
+	//int i;
+
+	printk("comedi%d: cb_pcimdas: ", dev->minor);
+
+/*
+ * Allocate the private structure area.
+ */
+	if (alloc_private(dev, sizeof(struct cb_pcimdas_private)) < 0)
+		return -ENOMEM;
+
+/*
+ * Probe the device to determine what device in the series it is.
+ */
+	printk("\n");
+
+	for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+		pcidev != NULL;
+		pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+		// is it not a computer boards card?
+		if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS)
+			continue;
+		// loop through cards supported by this driver
+		for (index = 0; index < N_BOARDS; index++) {
+			if (cb_pcimdas_boards[index].device_id !=
+				pcidev->device)
+				continue;
+			// was a particular bus/slot requested?
+			if (it->options[0] || it->options[1]) {
+				// are we on the wrong bus/slot?
+				if (pcidev->bus->number != it->options[0] ||
+					PCI_SLOT(pcidev->devfn) !=
+					it->options[1]) {
+					continue;
+				}
+			}
+			devpriv->pci_dev = pcidev;
+			dev->board_ptr = cb_pcimdas_boards + index;
+			goto found;
+		}
+	}
+
+	printk("No supported ComputerBoards/MeasurementComputing card found on "
+		"requested position\n");
+	return -EIO;
+
+      found:
+
+	printk("Found %s on bus %i, slot %i\n", cb_pcimdas_boards[index].name,
+		pcidev->bus->number, PCI_SLOT(pcidev->devfn));
+
+	// Warn about non-tested features
+	switch (thisboard->device_id) {
+	case 0x56:
+		break;
+	default:
+		printk("THIS CARD IS UNSUPPORTED.\n"
+			"PLEASE REPORT USAGE TO <mocelet@sucs.org>\n");
+	};
+
+	if (comedi_pci_enable(pcidev, "cb_pcimdas")) {
+		printk(" Failed to enable PCI device and request regions\n");
+		return -EIO;
+	}
+
+	devpriv->BADR0 = pci_resource_start(devpriv->pci_dev, 0);
+	devpriv->BADR1 = pci_resource_start(devpriv->pci_dev, 1);
+	devpriv->BADR2 = pci_resource_start(devpriv->pci_dev, 2);
+	devpriv->BADR3 = pci_resource_start(devpriv->pci_dev, 3);
+	devpriv->BADR4 = pci_resource_start(devpriv->pci_dev, 4);
+
+#ifdef CBPCIMDAS_DEBUG
+	printk("devpriv->BADR0 = 0x%lx\n", devpriv->BADR0);
+	printk("devpriv->BADR1 = 0x%lx\n", devpriv->BADR1);
+	printk("devpriv->BADR2 = 0x%lx\n", devpriv->BADR2);
+	printk("devpriv->BADR3 = 0x%lx\n", devpriv->BADR3);
+	printk("devpriv->BADR4 = 0x%lx\n", devpriv->BADR4);
+#endif
+
+// Dont support IRQ yet
+//      // get irq
+//      if(comedi_request_irq(devpriv->pci_dev->irq, cb_pcimdas_interrupt, IRQF_SHARED, "cb_pcimdas", dev ))
+//      {
+//              printk(" unable to allocate irq %u\n", devpriv->pci_dev->irq);
+//              return -EINVAL;
+//      }
+//      dev->irq = devpriv->pci_dev->irq;
+
+	//Initialize dev->board_name
+	dev->board_name = thisboard->name;
+
+/*
+ * Allocate the subdevice structures.  alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+	if (alloc_subdevices(dev, 3) < 0)
+		return -ENOMEM;
+
+	s = dev->subdevices + 0;
+	//dev->read_subdev=s;
+	// analog input subdevice
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE | SDF_GROUND;
+	s->n_chan = thisboard->ai_se_chans;
+	s->maxdata = (1 << thisboard->ai_bits) - 1;
+	s->range_table = &range_unknown;
+	s->len_chanlist = 1;	// This is the maximum chanlist length that
+	// the board can handle
+	s->insn_read = cb_pcimdas_ai_rinsn;
+
+	s = dev->subdevices + 1;
+	// analog output subdevice
+	s->type = COMEDI_SUBD_AO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->n_chan = thisboard->ao_nchan;
+	s->maxdata = 1 << thisboard->ao_bits;
+	s->range_table = &range_unknown;	//ranges are hardware settable, but not software readable.
+	s->insn_write = &cb_pcimdas_ao_winsn;
+	s->insn_read = &cb_pcimdas_ao_rinsn;
+
+	s = dev->subdevices + 2;
+	/* digital i/o subdevice */
+	if (thisboard->has_dio) {
+		subdev_8255_init(dev, s, NULL, devpriv->BADR4);
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	printk("attached\n");
+
+	return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device.  It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach().  dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int cb_pcimdas_detach(struct comedi_device * dev)
+{
+#ifdef CBPCIMDAS_DEBUG
+	if (devpriv) {
+		printk("devpriv->BADR0 = 0x%lx\n", devpriv->BADR0);
+		printk("devpriv->BADR1 = 0x%lx\n", devpriv->BADR1);
+		printk("devpriv->BADR2 = 0x%lx\n", devpriv->BADR2);
+		printk("devpriv->BADR3 = 0x%lx\n", devpriv->BADR3);
+		printk("devpriv->BADR4 = 0x%lx\n", devpriv->BADR4);
+	}
+#endif
+	printk("comedi%d: cb_pcimdas: remove\n", dev->minor);
+	if (dev->irq)
+		comedi_free_irq(dev->irq, dev);
+	if (devpriv) {
+		if (devpriv->pci_dev) {
+			if (devpriv->BADR0) {
+				comedi_pci_disable(devpriv->pci_dev);
+			}
+			pci_dev_put(devpriv->pci_dev);
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * "instructions" read/write data in "one-shot" or "software-triggered"
+ * mode.
+ */
+static int cb_pcimdas_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n, i;
+	unsigned int d;
+	unsigned int busy;
+	int chan = CR_CHAN(insn->chanspec);
+	unsigned short chanlims;
+	int maxchans;
+
+	// only support sw initiated reads from a single channel
+
+	//check channel number
+	if ((inb(devpriv->BADR3 + 2) & 0x20) == 0)	//differential mode
+		maxchans = thisboard->ai_diff_chans;
+	else
+		maxchans = thisboard->ai_se_chans;
+
+	if (chan > (maxchans - 1))
+		return -ETIMEDOUT;	//*** Wrong error code. Fixme.
+
+	//configure for sw initiated read
+	d = inb(devpriv->BADR3 + 5);
+	if ((d & 0x03) > 0) {	//only reset if needed.
+		d = d & 0xfd;
+		outb(d, devpriv->BADR3 + 5);
+	}
+	outb(0x01, devpriv->BADR3 + 6);	//set bursting off, conversions on
+	outb(0x00, devpriv->BADR3 + 7);	//set range to 10V. UP/BP is controlled by a switch on the board
+
+	// write channel limits to multiplexer, set Low (bits 0-3) and High (bits 4-7) channels to chan.
+	chanlims = chan | (chan << 4);
+	outb(chanlims, devpriv->BADR3 + 0);
+
+	/* convert n samples */
+	for (n = 0; n < insn->n; n++) {
+		/* trigger conversion */
+		outw(0, devpriv->BADR2 + 0);
+
+#define TIMEOUT 1000		//typically takes 5 loops on a lightly loaded Pentium 100MHz,
+		//this is likely to be 100 loops on a 2GHz machine, so set 1000 as the limit.
+
+		/* wait for conversion to end */
+		for (i = 0; i < TIMEOUT; i++) {
+			busy = inb(devpriv->BADR3 + 2) & 0x80;
+			if (!busy)
+				break;
+		}
+		if (i == TIMEOUT) {
+			printk("timeout\n");
+			return -ETIMEDOUT;
+		}
+		/* read data */
+		d = inw(devpriv->BADR2 + 0);
+
+		/* mangle the data as necessary */
+		//d ^= 1<<(thisboard->ai_bits-1); // 16 bit data from ADC, so no mangle needed.
+
+		data[n] = d;
+	}
+
+	/* return the number of samples read/written */
+	return n;
+}
+
+static int cb_pcimdas_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+
+	/* Writing a list of values to an AO channel is probably not
+	 * very useful, but that's how the interface is defined. */
+	for (i = 0; i < insn->n; i++) {
+		switch (chan) {
+		case 0:
+			outw(data[i] & 0x0FFF, devpriv->BADR2 + DAC0_OFFSET);
+			break;
+		case 1:
+			outw(data[i] & 0x0FFF, devpriv->BADR2 + DAC1_OFFSET);
+			break;
+		default:
+			return -1;
+		}
+		devpriv->ao_readback[chan] = data[i];
+	}
+
+	/* return the number of samples read/written */
+	return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+ * Usually this means copying a value stored in devpriv. */
+static int cb_pcimdas_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+
+	for (i = 0; i < insn->n; i++)
+		data[i] = devpriv->ao_readback[chan];
+
+	return i;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_PCI_INITCLEANUP(driver_cb_pcimdas, cb_pcimdas_pci_table);
diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c
new file mode 100644
index 0000000..e4c5b46
--- /dev/null
+++ b/drivers/staging/comedi/drivers/cb_pcimdda.c
@@ -0,0 +1,474 @@
+/*
+    comedi/drivers/cb_pcimdda.c
+    Computer Boards PCIM-DDA06-16 Comedi driver
+    Author: Calin Culianu <calin@ajvar.org>
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: cb_pcimdda
+Description: Measurement Computing PCIM-DDA06-16
+Devices: [Measurement Computing] PCIM-DDA06-16 (cb_pcimdda)
+Author: Calin Culianu <calin@ajvar.org>
+Updated: Mon, 14 Apr 2008 15:15:51 +0100
+Status: works
+
+All features of the PCIM-DDA06-16 board are supported.  This board
+has 6 16-bit AO channels, and the usual 8255 DIO setup.  (24 channels,
+configurable in banks of 8 and 4, etc.).  This board does not support commands.
+
+The board has a peculiar way of specifying AO gain/range settings -- You have
+1 jumper bank on the card, which either makes all 6 AO channels either
+5 Volt unipolar, 5V bipolar, 10 Volt unipolar or 10V bipolar.
+
+Since there is absolutely _no_ way to tell in software how this jumper is set
+(well, at least according  to the rather thin spec. from Measurement Computing
+ that comes with the board), the driver assumes the jumper is at its factory
+default setting of +/-5V.
+
+Also of note is the fact that this board features another jumper, whose
+state is also completely invisible to software.  It toggles two possible AO
+output modes on the board:
+
+  - Update Mode: Writing to an AO channel instantaneously updates the actual
+    signal output by the DAC on the board (this is the factory default).
+  - Simultaneous XFER Mode: Writing to an AO channel has no effect until
+    you read from any one of the AO channels.  This is useful for loading
+    all 6 AO values, and then reading from any one of the AO channels on the
+    device to instantly update all 6 AO values in unison.  Useful for some
+    control apps, I would assume?  If your jumper is in this setting, then you
+    need to issue your comedi_data_write()s to load all the values you want,
+    then issue one comedi_data_read() on any channel on the AO subdevice
+    to initiate the simultaneous XFER.
+
+Configuration Options:
+  [0] PCI bus (optional)
+  [1] PCI slot (optional)
+  [2] analog output range jumper setting
+      0 == +/- 5 V
+      1 == +/- 10 V
+*/
+
+/*
+    This is a driver for the Computer Boards PCIM-DDA06-16 Analog Output
+    card.  This board has a unique register layout and as such probably
+    deserves its own driver file.
+
+    It is theoretically possible to integrate this board into the cb_pcidda
+    file, but since that isn't my code, I didn't want to significantly
+    modify that file to support this board (I thought it impolite to do so).
+
+    At any rate, if you feel ambitious, please feel free to take
+    the code out of this file and combine it with a more unified driver
+    file.
+
+    I would like to thank Timothy Curry <Timothy.Curry@rdec.redstone.army.mil>
+    for lending me a board so that I could write this driver.
+
+    -Calin Culianu <calin@ajvar.org>
+ */
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+#include "8255.h"
+
+/* device ids of the cards we support -- currently only 1 card supported */
+#define PCI_ID_PCIM_DDA06_16 0x0053
+
+/*
+ * This is straight from skel.c -- I did this in case this source file
+ * will someday support more than 1 board...
+ */
+struct board_struct {
+	const char *name;
+	unsigned short device_id;
+	int ao_chans;
+	int ao_bits;
+	int dio_chans;
+	int dio_method;
+	int dio_offset;		/* how many bytes into the BADR are the DIO ports */
+	int regs_badrindex;	/* IO Region for the control, analog output,
+				   and DIO registers */
+	int reg_sz;		/* number of bytes of registers in io region */
+};
+
+enum DIO_METHODS {
+	DIO_NONE = 0,
+	DIO_8255,
+	DIO_INTERNAL		/* unimplemented */
+};
+
+static const struct board_struct boards[] = {
+	{
+	      name:	"cb_pcimdda06-16",
+	      device_id:PCI_ID_PCIM_DDA06_16,
+	      ao_chans:6,
+	      ao_bits:	16,
+	      dio_chans:24,
+	      dio_method:DIO_8255,
+	      dio_offset:12,
+	      regs_badrindex:3,
+	      reg_sz:	16,
+		}
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard    ((const struct board_struct *)dev->board_ptr)
+
+/* Number of boards in boards[] */
+#define N_BOARDS	(sizeof(boards) / sizeof(struct board_struct))
+#define REG_SZ (thisboard->reg_sz)
+#define REGS_BADRINDEX (thisboard->regs_badrindex)
+
+/* This is used by modprobe to translate PCI IDs to drivers.  Should
+ * only be used for PCI and ISA-PnP devices */
+/* Please add your PCI vendor ID to comedidev.h, and it will be forwarded
+ * upstream. */
+static DEFINE_PCI_DEVICE_TABLE(pci_table) = {
+	{PCI_VENDOR_ID_COMPUTERBOARDS, PCI_ID_PCIM_DDA06_16, PCI_ANY_ID,
+		PCI_ANY_ID, 0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci_table);
+
+/* this structure is for data unique to this hardware driver.  If
+   several hardware drivers keep similar information in this structure,
+   feel free to suggest moving the variable to the struct comedi_device struct.  */
+struct board_private_struct {
+	unsigned long registers;	/* set by probe */
+	unsigned long dio_registers;
+	char attached_to_8255;	/* boolean */
+	char attached_successfully;	/* boolean */
+	/* would be useful for a PCI device */
+	struct pci_dev *pci_dev;
+
+#define MAX_AO_READBACK_CHANNELS 6
+	/* Used for AO readback */
+	unsigned int ao_readback[MAX_AO_READBACK_CHANNELS];
+
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct board_private_struct *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int detach(struct comedi_device * dev);
+static struct comedi_driver cb_pcimdda_driver = {
+      driver_name:"cb_pcimdda",
+      module:THIS_MODULE,
+      attach:attach,
+      detach:detach,
+};
+
+MODULE_AUTHOR("Calin A. Culianu <calin@rtlab.org>");
+MODULE_DESCRIPTION("Comedi low-level driver for the Computerboards PCIM-DDA "
+	"series.  Currently only supports PCIM-DDA06-16 (which "
+	"also happens to be the only board in this series. :) ) ");
+MODULE_LICENSE("GPL");
+COMEDI_PCI_INITCLEANUP_NOMODULE(cb_pcimdda_driver, pci_table);
+
+static int ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+/*---------------------------------------------------------------------------
+  HELPER FUNCTION DECLARATIONS
+-----------------------------------------------------------------------------*/
+
+/* returns a maxdata value for a given n_bits */
+static inline unsigned int figure_out_maxdata(int bits)
+{
+	return (((unsigned int) 1 << bits) - 1);
+}
+
+/*
+ *  Probes for a supported device.
+ *
+ *  Prerequisite: private be allocated already inside dev
+ *
+ *  If the device is found, it returns 0 and has the following side effects:
+ *
+ *  o  assigns a struct pci_dev * to dev->private->pci_dev
+ *  o  assigns a struct board * to dev->board_ptr
+ *  o  sets dev->private->registers
+ *  o  sets dev->private->dio_registers
+ *
+ *  Otherwise, returns a -errno on error
+ */
+static int probe(struct comedi_device * dev, const struct comedi_devconfig * it);
+
+/*---------------------------------------------------------------------------
+  FUNCTION DEFINITIONS
+-----------------------------------------------------------------------------*/
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board.  If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	int err;
+
+/*
+ * Allocate the private structure area.  alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ * if this function fails (returns negative) then the private area is
+ * kfree'd by comedi
+ */
+	if (alloc_private(dev, sizeof(struct board_private_struct)) < 0)
+		return -ENOMEM;
+
+/*
+ * If you can probe the device to determine what device in a series
+ * it is, this is the place to do it.  Otherwise, dev->board_ptr
+ * should already be initialized.
+ */
+	if ((err = probe(dev, it)))
+		return err;
+
+/* Output some info */
+	printk("comedi%d: %s: ", dev->minor, thisboard->name);
+
+/*
+ * Initialize dev->board_name.  Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+	dev->board_name = thisboard->name;
+
+/*
+ * Allocate the subdevice structures.  alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+	if (alloc_subdevices(dev, 2) < 0)
+		return -ENOMEM;
+
+	s = dev->subdevices + 0;
+
+	/* analog output subdevice */
+	s->type = COMEDI_SUBD_AO;
+	s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+	s->n_chan = thisboard->ao_chans;
+	s->maxdata = figure_out_maxdata(thisboard->ao_bits);
+	/* this is hard-coded here */
+	if (it->options[2]) {
+		s->range_table = &range_bipolar10;
+	} else {
+		s->range_table = &range_bipolar5;
+	}
+	s->insn_write = &ao_winsn;
+	s->insn_read = &ao_rinsn;
+
+	s = dev->subdevices + 1;
+	/* digital i/o subdevice */
+	if (thisboard->dio_chans) {
+		switch (thisboard->dio_method) {
+		case DIO_8255:
+			/* this is a straight 8255, so register us with the 8255 driver */
+			subdev_8255_init(dev, s, NULL, devpriv->dio_registers);
+			devpriv->attached_to_8255 = 1;
+			break;
+		case DIO_INTERNAL:
+		default:
+			printk("DIO_INTERNAL not implemented yet!\n");
+			return -ENXIO;
+			break;
+		}
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	devpriv->attached_successfully = 1;
+
+	printk("attached\n");
+
+	return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device.  It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach().  dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int detach(struct comedi_device * dev)
+{
+	if (devpriv) {
+
+		if (dev->subdevices && devpriv->attached_to_8255) {
+			/* de-register us from the 8255 driver */
+			subdev_8255_cleanup(dev, dev->subdevices + 2);
+			devpriv->attached_to_8255 = 0;
+		}
+
+		if (devpriv->pci_dev) {
+			if (devpriv->registers) {
+				comedi_pci_disable(devpriv->pci_dev);
+			}
+			pci_dev_put(devpriv->pci_dev);
+		}
+
+		if (devpriv->attached_successfully && thisboard)
+			printk("comedi%d: %s: detached\n", dev->minor,
+				thisboard->name);
+
+	}
+
+	return 0;
+}
+
+static int ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+	unsigned long offset = devpriv->registers + chan * 2;
+
+	/* Writing a list of values to an AO channel is probably not
+	 * very useful, but that's how the interface is defined. */
+	for (i = 0; i < insn->n; i++) {
+		/*  first, load the low byte */
+		outb((char)(data[i] & 0x00ff), offset);
+		/*  next, write the high byte -- only after this is written is
+		   the channel voltage updated in the DAC, unless
+		   we're in simultaneous xfer mode (jumper on card)
+		   then a rinsn is necessary to actually update the DAC --
+		   see ao_rinsn() below... */
+		outb((char)(data[i] >> 8 & 0x00ff), offset + 1);
+
+		/* for testing only.. the actual rinsn SHOULD do an inw!
+		   (see the stuff about simultaneous XFER mode on this board) */
+		devpriv->ao_readback[chan] = data[i];
+	}
+
+	/* return the number of samples read/written */
+	return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+
+   Usually this means copying a value stored in devpriv->ao_readback.
+   However, since this board has this jumper setting called "Simultaneous
+   Xfer mode" (off by default), we will support it.  Simultaneaous xfer
+   mode is accomplished by loading ALL the values you want for AO in all the
+   channels, then READing off one of the AO registers to initiate the
+   instantaneous simultaneous update of all DAC outputs, which makes
+   all AO channels update simultaneously.  This is useful for some control
+   applications, I would imagine.
+*/
+static int ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+
+	for (i = 0; i < insn->n; i++) {
+		inw(devpriv->registers + chan * 2);
+		/* should I set data[i] to the result of the actual read on the register
+		   or the cached unsigned int in devpriv->ao_readback[]? */
+		data[i] = devpriv->ao_readback[chan];
+	}
+
+	return i;
+}
+
+/*---------------------------------------------------------------------------
+  HELPER FUNCTION DEFINITIONS
+-----------------------------------------------------------------------------*/
+
+/*
+ *  Probes for a supported device.
+ *
+ *  Prerequisite: private be allocated already inside dev
+ *
+ *  If the device is found, it returns 0 and has the following side effects:
+ *
+ *  o  assigns a struct pci_dev * to dev->private->pci_dev
+ *  o  assigns a struct board * to dev->board_ptr
+ *  o  sets dev->private->registers
+ *  o  sets dev->private->dio_registers
+ *
+ *  Otherwise, returns a -errno on error
+ */
+static int probe(struct comedi_device * dev, const struct comedi_devconfig * it)
+{
+	struct pci_dev *pcidev;
+	int index;
+	unsigned long registers;
+
+	for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+		pcidev != NULL;
+		pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+		// is it not a computer boards card?
+		if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS)
+			continue;
+		// loop through cards supported by this driver
+		for (index = 0; index < N_BOARDS; index++) {
+			if (boards[index].device_id != pcidev->device)
+				continue;
+			// was a particular bus/slot requested?
+			if (it->options[0] || it->options[1]) {
+				// are we on the wrong bus/slot?
+				if (pcidev->bus->number != it->options[0] ||
+					PCI_SLOT(pcidev->devfn) !=
+					it->options[1]) {
+					continue;
+				}
+			}
+			/* found ! */
+
+			devpriv->pci_dev = pcidev;
+			dev->board_ptr = boards + index;
+			if (comedi_pci_enable(pcidev, thisboard->name)) {
+				printk("cb_pcimdda: Failed to enable PCI device and request regions\n");
+				return -EIO;
+			}
+			registers =
+				pci_resource_start(devpriv->pci_dev,
+				REGS_BADRINDEX);
+			devpriv->registers = registers;
+			devpriv->dio_registers
+				= devpriv->registers + thisboard->dio_offset;
+			return 0;
+		}
+	}
+
+	printk("cb_pcimdda: No supported ComputerBoards/MeasurementComputing "
+		"card found at the requested position\n");
+	return -ENODEV;
+}
diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c
index 9e5496f..1ee4898 100644
--- a/drivers/staging/comedi/drivers/comedi_bond.c
+++ b/drivers/staging/comedi/drivers/comedi_bond.c
@@ -59,7 +59,7 @@
  * Devices: a full list of the boards that attempt to be supported by
  *   the driver.  Format is "(manufacturer) board name [comedi name]",
  *   where comedi_name is the name that is used to configure the board.
- *   See the comment near board_name: in the comedi_driver structure
+ *   See the comment near board_name: in the struct comedi_driver structure
  *   below.  If (manufacturer) or [comedi name] is missing, the previous
  *   value is used.
  * Author: you
@@ -142,7 +142,7 @@
 #define thisboard ((const struct BondingBoard *)dev->board_ptr)
 
 struct BondedDevice {
-	comedi_t *dev;
+	void *dev;
 	unsigned minor;
 	unsigned subdev;
 	unsigned subdev_type;
@@ -154,7 +154,7 @@
 
 /* this structure is for data unique to this hardware driver.  If
    several hardware drivers keep similar information in this structure,
-   feel free to suggest moving the variable to the comedi_device struct.  */
+   feel free to suggest moving the variable to the struct comedi_device struct.  */
 struct Private {
 # define MAX_BOARD_NAME 256
 	char name[MAX_BOARD_NAME];
@@ -171,21 +171,21 @@
 #define devpriv ((struct Private *)dev->private)
 
 /*
- * The comedi_driver structure tells the Comedi core module
+ * The struct comedi_driver structure tells the Comedi core module
  * which functions to call to configure/deconfigure (attach/detach)
  * the board, and also about the kernel module that contains
  * the device code.
  */
-static int bonding_attach(comedi_device *dev, comedi_devconfig *it);
-static int bonding_detach(comedi_device *dev);
+static int bonding_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int bonding_detach(struct comedi_device *dev);
 /** Build Private array of all devices.. */
-static int doDevConfig(comedi_device *dev, comedi_devconfig *it);
-static void doDevUnconfig(comedi_device *dev);
+static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it);
+static void doDevUnconfig(struct comedi_device *dev);
 /* Ugly implementation of realloc that always copies memory around -- I'm lazy,
  * what can I say?  I like to do wasteful memcopies.. :) */
 static void *Realloc(const void *ptr, size_t len, size_t old_len);
 
-static comedi_driver driver_bonding = {
+static struct comedi_driver driver_bonding = {
       .driver_name =	MODULE_NAME,
       .module =		THIS_MODULE,
       .attach =		bonding_attach,
@@ -213,10 +213,10 @@
       .num_names =	sizeof(bondingBoards) / sizeof(struct BondingBoard),
 };
 
-static int bonding_dio_insn_bits(comedi_device *dev, comedi_subdevice *s,
-				 comedi_insn *insn, lsampl_t *data);
-static int bonding_dio_insn_config(comedi_device *dev, comedi_subdevice *s,
-				   comedi_insn *insn, lsampl_t *data);
+static int bonding_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data);
+static int bonding_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+				   struct comedi_insn *insn, unsigned int *data);
 
 /*
  * Attach is called by the Comedi core to configure the driver
@@ -224,9 +224,9 @@
  * in the driver structure, dev->board_ptr contains that
  * address.
  */
-static int bonding_attach(comedi_device *dev, comedi_devconfig *it)
+static int bonding_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
-	comedi_subdevice *s;
+	struct comedi_subdevice *s;
 
 	LOG_MSG("comedi%d\n", dev->minor);
 
@@ -281,7 +281,7 @@
  * allocated by _attach().  dev->private and dev->subdevices are
  * deallocated automatically by the core.
  */
-static int bonding_detach(comedi_device *dev)
+static int bonding_detach(struct comedi_device *dev)
 {
 	LOG_MSG("comedi%d: remove\n", dev->minor);
 	doDevUnconfig(dev);
@@ -293,10 +293,10 @@
  * useful to applications if you implement the insn_bits interface.
  * This allows packed reading/writing of the DIO channels.  The
  * comedi core can convert between insn_bits and insn_read/write */
-static int bonding_dio_insn_bits(comedi_device *dev, comedi_subdevice *s,
-				 comedi_insn *insn, lsampl_t *data)
+static int bonding_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data)
 {
-#define LSAMPL_BITS (sizeof(lsampl_t)*8)
+#define LSAMPL_BITS (sizeof(unsigned int)*8)
 	unsigned nchans = LSAMPL_BITS, num_done = 0, i;
 	if (insn->n != 2)
 		return -EINVAL;
@@ -312,12 +312,12 @@
 		   to this subdevice.. need to shift them to zero position of
 		   course. */
 		/* Bits corresponding to this subdev. */
-		lsampl_t subdevMask = ((1 << bdev->nchans) - 1);
-		lsampl_t writeMask, dataBits;
+		unsigned int subdevMask = ((1 << bdev->nchans) - 1);
+		unsigned int writeMask, dataBits;
 
 		/* Argh, we have >= LSAMPL_BITS chans.. take all bits */
 		if (bdev->nchans >= LSAMPL_BITS)
-			subdevMask = (lsampl_t) (-1);
+			subdevMask = (unsigned int) (-1);
 
 		writeMask = (data[0] >> num_done) & subdevMask;
 		dataBits = (data[1] >> num_done) & subdevMask;
@@ -340,8 +340,8 @@
 	return insn->n;
 }
 
-static int bonding_dio_insn_config(comedi_device *dev, comedi_subdevice *s,
-				   comedi_insn *insn, lsampl_t *data)
+static int bonding_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+				   struct comedi_insn *insn, unsigned int *data)
 {
 	int chan = CR_CHAN(insn->chanspec), ret, io_bits = s->io_bits;
 	unsigned int io;
@@ -394,10 +394,10 @@
 	return newmem;
 }
 
-static int doDevConfig(comedi_device *dev, comedi_devconfig *it)
+static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it)
 {
 	int i;
-	comedi_t *devs_opened[COMEDI_NUM_BOARD_MINORS];
+	void *devs_opened[COMEDI_NUM_BOARD_MINORS];
 
 	memset(devs_opened, 0, sizeof(devs_opened));
 	devpriv->name[0] = 0;;
@@ -406,7 +406,7 @@
 	for (i = 0; i < COMEDI_NDEVCONFOPTS && (!i || it->options[i]); ++i) {
 		char file[] = "/dev/comediXXXXXX";
 		int minor = it->options[i];
-		comedi_t *d;
+		void *d;
 		int sdev = -1, nchans, tmp;
 		struct BondedDevice *bdev = NULL;
 
@@ -497,7 +497,7 @@
 	return 1;
 }
 
-static void doDevUnconfig(comedi_device *dev)
+static void doDevUnconfig(struct comedi_device *dev)
 {
 	unsigned long devs_closed = 0;
 
diff --git a/drivers/staging/comedi/drivers/comedi_fc.c b/drivers/staging/comedi/drivers/comedi_fc.c
index cd74dbe..9fa4cdc 100644
--- a/drivers/staging/comedi/drivers/comedi_fc.c
+++ b/drivers/staging/comedi/drivers/comedi_fc.c
@@ -28,10 +28,10 @@
 
 #include "comedi_fc.h"
 
-static void increment_scan_progress(comedi_subdevice *subd,
+static void increment_scan_progress(struct comedi_subdevice *subd,
 				    unsigned int num_bytes)
 {
-	comedi_async *async = subd->async;
+	struct comedi_async *async = subd->async;
 	unsigned int scan_length = cfc_bytes_per_scan(subd);
 
 	async->scan_progress += num_bytes;
@@ -42,10 +42,10 @@
 }
 
 /* Writes an array of data points to comedi's buffer */
-unsigned int cfc_write_array_to_buffer(comedi_subdevice *subd, void *data,
+unsigned int cfc_write_array_to_buffer(struct comedi_subdevice *subd, void *data,
 				       unsigned int num_bytes)
 {
-	comedi_async *async = subd->async;
+	struct comedi_async *async = subd->async;
 	unsigned int retval;
 
 	if (num_bytes == 0)
@@ -67,10 +67,10 @@
 }
 EXPORT_SYMBOL(cfc_write_array_to_buffer);
 
-unsigned int cfc_read_array_from_buffer(comedi_subdevice *subd, void *data,
+unsigned int cfc_read_array_from_buffer(struct comedi_subdevice *subd, void *data,
 					unsigned int num_bytes)
 {
-	comedi_async *async = subd->async;
+	struct comedi_async *async = subd->async;
 
 	if (num_bytes == 0)
 		return 0;
@@ -85,7 +85,7 @@
 }
 EXPORT_SYMBOL(cfc_read_array_from_buffer);
 
-unsigned int cfc_handle_events(comedi_device *dev, comedi_subdevice *subd)
+unsigned int cfc_handle_events(struct comedi_device *dev, struct comedi_subdevice *subd)
 {
 	unsigned int events = subd->async->events;
 
diff --git a/drivers/staging/comedi/drivers/comedi_fc.h b/drivers/staging/comedi/drivers/comedi_fc.h
index 6952fe2..494ae3f 100644
--- a/drivers/staging/comedi/drivers/comedi_fc.h
+++ b/drivers/staging/comedi/drivers/comedi_fc.h
@@ -30,30 +30,30 @@
 #include "../comedidev.h"
 
 /* Writes an array of data points to comedi's buffer */
-extern unsigned int cfc_write_array_to_buffer(comedi_subdevice *subd,
+extern unsigned int cfc_write_array_to_buffer(struct comedi_subdevice *subd,
 					      void *data,
 					      unsigned int num_bytes);
 
-static inline unsigned int cfc_write_to_buffer(comedi_subdevice *subd,
-					       sampl_t data)
+static inline unsigned int cfc_write_to_buffer(struct comedi_subdevice *subd,
+					       short data)
 {
 	return cfc_write_array_to_buffer(subd, &data, sizeof(data));
 };
 
-static inline unsigned int cfc_write_long_to_buffer(comedi_subdevice *subd,
-						    lsampl_t data)
+static inline unsigned int cfc_write_long_to_buffer(struct comedi_subdevice *subd,
+						    unsigned int data)
 {
 	return cfc_write_array_to_buffer(subd, &data, sizeof(data));
 };
 
-extern unsigned int cfc_read_array_from_buffer(comedi_subdevice *subd,
+extern unsigned int cfc_read_array_from_buffer(struct comedi_subdevice *subd,
 					       void *data,
 					       unsigned int num_bytes);
 
-extern unsigned int cfc_handle_events(comedi_device *dev,
-				      comedi_subdevice *subd);
+extern unsigned int cfc_handle_events(struct comedi_device *dev,
+				      struct comedi_subdevice *subd);
 
-static inline unsigned int cfc_bytes_per_scan(comedi_subdevice *subd)
+static inline unsigned int cfc_bytes_per_scan(struct comedi_subdevice *subd)
 {
 	int num_samples;
 	int bits_per_sample;
diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c
index ba838ff..a233391 100644
--- a/drivers/staging/comedi/drivers/comedi_parport.c
+++ b/drivers/staging/comedi/drivers/comedi_parport.c
@@ -90,9 +90,9 @@
 #define PARPORT_B 1
 #define PARPORT_C 2
 
-static int parport_attach(comedi_device *dev, comedi_devconfig *it);
-static int parport_detach(comedi_device *dev);
-static comedi_driver driver_parport = {
+static int parport_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int parport_detach(struct comedi_device *dev);
+static struct comedi_driver driver_parport = {
       .driver_name =	"comedi_parport",
       .module =		THIS_MODULE,
       .attach =		parport_attach,
@@ -108,8 +108,8 @@
 };
 #define devpriv ((struct parport_private *)(dev->private))
 
-static int parport_insn_a(comedi_device *dev, comedi_subdevice *s,
-			  comedi_insn *insn, lsampl_t *data)
+static int parport_insn_a(struct comedi_device *dev, struct comedi_subdevice *s,
+			  struct comedi_insn *insn, unsigned int *data)
 {
 	if (data[0]) {
 		devpriv->a_data &= ~data[0];
@@ -123,8 +123,8 @@
 	return 2;
 }
 
-static int parport_insn_config_a(comedi_device *dev, comedi_subdevice *s,
-				 comedi_insn *insn, lsampl_t *data)
+static int parport_insn_config_a(struct comedi_device *dev, struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data)
 {
 	if (data[0]) {
 		s->io_bits = 0xff;
@@ -138,8 +138,8 @@
 	return 1;
 }
 
-static int parport_insn_b(comedi_device *dev, comedi_subdevice *s,
-			  comedi_insn *insn, lsampl_t *data)
+static int parport_insn_b(struct comedi_device *dev, struct comedi_subdevice *s,
+			  struct comedi_insn *insn, unsigned int *data)
 {
 	if (data[0]) {
 		/* should writes be ignored? */
@@ -151,8 +151,8 @@
 	return 2;
 }
 
-static int parport_insn_c(comedi_device *dev, comedi_subdevice *s,
-			  comedi_insn *insn, lsampl_t *data)
+static int parport_insn_c(struct comedi_device *dev, struct comedi_subdevice *s,
+			  struct comedi_insn *insn, unsigned int *data)
 {
 	data[0] &= 0x0f;
 	if (data[0]) {
@@ -167,8 +167,8 @@
 	return 2;
 }
 
-static int parport_intr_insn(comedi_device *dev, comedi_subdevice *s,
-			     comedi_insn *insn, lsampl_t *data)
+static int parport_intr_insn(struct comedi_device *dev, struct comedi_subdevice *s,
+			     struct comedi_insn *insn, unsigned int *data)
 {
 	if (insn->n < 1)
 		return -EINVAL;
@@ -177,8 +177,8 @@
 	return 2;
 }
 
-static int parport_intr_cmdtest(comedi_device *dev, comedi_subdevice *s,
-				comedi_cmd *cmd)
+static int parport_intr_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+				struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -252,7 +252,7 @@
 	return 0;
 }
 
-static int parport_intr_cmd(comedi_device *dev, comedi_subdevice *s)
+static int parport_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	devpriv->c_data |= 0x10;
 	outb(devpriv->c_data, dev->iobase + PARPORT_C);
@@ -262,7 +262,7 @@
 	return 0;
 }
 
-static int parport_intr_cancel(comedi_device *dev, comedi_subdevice *s)
+static int parport_intr_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	printk(KERN_DEBUG "parport_intr_cancel()\n");
 
@@ -276,8 +276,8 @@
 
 static irqreturn_t parport_interrupt(int irq, void *d PT_REGS_ARG)
 {
-	comedi_device *dev = d;
-	comedi_subdevice *s = dev->subdevices + 3;
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s = dev->subdevices + 3;
 
 	if (!devpriv->enable_irq) {
 		printk(KERN_ERR "comedi_parport: bogus irq, ignored\n");
@@ -291,12 +291,12 @@
 	return IRQ_HANDLED;
 }
 
-static int parport_attach(comedi_device *dev, comedi_devconfig *it)
+static int parport_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
 	int ret;
 	unsigned int irq;
 	unsigned long iobase;
-	comedi_subdevice *s;
+	struct comedi_subdevice *s;
 
 	iobase = it->options[0];
 	printk(KERN_INFO "comedi%d: parport: 0x%04lx ", dev->minor, iobase);
@@ -376,7 +376,7 @@
 	return 1;
 }
 
-static int parport_detach(comedi_device *dev)
+static int parport_detach(struct comedi_device *dev)
 {
 	printk("comedi%d: parport: remove\n", dev->minor);
 
diff --git a/drivers/staging/comedi/drivers/comedi_rt_timer.c b/drivers/staging/comedi/drivers/comedi_rt_timer.c
new file mode 100644
index 0000000..f40c8cf
--- /dev/null
+++ b/drivers/staging/comedi/drivers/comedi_rt_timer.c
@@ -0,0 +1,728 @@
+/*
+    comedi/drivers/comedi_rt_timer.c
+    virtual driver for using RTL timing sources
+
+    Authors: David A. Schleef, Frank M. Hess
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 1999,2001 David A. Schleef <ds@schleef.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.
+
+    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.
+
+**************************************************************************
+*/
+/*
+Driver: comedi_rt_timer
+Description: Command emulator using real-time tasks
+Author: ds, fmhess
+Devices:
+Status: works
+
+This driver requires RTAI or RTLinux to work correctly.  It doesn't
+actually drive hardware directly, but calls other drivers and uses
+a real-time task to emulate commands for drivers and devices that
+are incapable of native commands.  Thus, you can get accurately
+timed I/O on any device.
+
+Since the timing is all done in software, sampling jitter is much
+higher than with a device that has an on-board timer, and maximum
+sample rate is much lower.
+
+Configuration options:
+  [0] - minor number of device you wish to emulate commands for
+  [1] - subdevice number you wish to emulate commands for
+*/
+/*
+TODO:
+	Support for digital io commands could be added, except I can't see why
+		anyone would want to use them
+	What happens if device we are emulating for is de-configured?
+*/
+
+#include "../comedidev.h"
+#include "../comedilib.h"
+
+#include "comedi_fc.h"
+
+#ifdef CONFIG_COMEDI_RTL_V1
+#include <rtl_sched.h>
+#include <asm/rt_irq.h>
+#endif
+#ifdef CONFIG_COMEDI_RTL
+#include <rtl.h>
+#include <rtl_sched.h>
+#include <rtl_compat.h>
+#include <asm/div64.h>
+
+#ifndef RTLINUX_VERSION_CODE
+#define RTLINUX_VERSION_CODE 0
+#endif
+#ifndef RTLINUX_VERSION
+#define RTLINUX_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+#endif
+
+// begin hack to workaround broken HRT_TO_8254() function on rtlinux
+#if RTLINUX_VERSION_CODE <= RTLINUX_VERSION(3,0,100)
+// this function sole purpose is to divide a long long by 838
+static inline RTIME nano2count(long long ns)
+{
+	do_div(ns, 838);
+	return ns;
+}
+
+#ifdef rt_get_time()
+#undef rt_get_time()
+#endif
+#define rt_get_time() nano2count(gethrtime())
+
+#else
+
+#define nano2count(x) HRT_TO_8254(x)
+#endif
+// end hack
+
+// rtl-rtai compatibility
+#define rt_task_wait_period() rt_task_wait()
+#define rt_pend_linux_srq(irq) rtl_global_pend_irq(irq)
+#define rt_free_srq(irq) rtl_free_soft_irq(irq)
+#define rt_request_srq(x,y,z) rtl_get_soft_irq(y,"timer")
+#define rt_task_init(a,b,c,d,e,f,g) rt_task_init(a,b,c,d,(e)+1)
+#define rt_task_resume(x) rt_task_wakeup(x)
+#define rt_set_oneshot_mode()
+#define start_rt_timer(x)
+#define stop_rt_timer()
+
+#endif
+#ifdef CONFIG_COMEDI_RTAI
+#include <rtai.h>
+#include <rtai_sched.h>
+
+#if RTAI_VERSION_CODE < RTAI_MANGLE_VERSION(3,3,0)
+#define comedi_rt_task_context_t	int
+#else
+#define comedi_rt_task_context_t	long
+#endif
+
+#endif
+
+/* This defines the fastest speed we will emulate.  Note that
+ * without a watchdog (like in RTAI), we could easily overrun our
+ * task period because analog input tends to be slow. */
+#define SPEED_LIMIT 100000	/* in nanoseconds */
+
+static int timer_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int timer_detach(struct comedi_device * dev);
+static int timer_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int trig_num);
+static int timer_start_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static struct comedi_driver driver_timer = {
+      module:THIS_MODULE,
+      driver_name:"comedi_rt_timer",
+      attach:timer_attach,
+      detach:timer_detach,
+//      open:           timer_open,
+};
+
+COMEDI_INITCLEANUP(driver_timer);
+
+struct timer_private {
+	comedi_t *device;	// device we are emulating commands for
+	int subd;		// subdevice we are emulating commands for
+	RT_TASK *rt_task;	// rt task that starts scans
+	RT_TASK *scan_task;	// rt task that controls conversion timing in a scan
+	/* io_function can point to either an input or output function
+	 * depending on what kind of subdevice we are emulating for */
+	int (*io_function) (struct comedi_device * dev, struct comedi_cmd * cmd,
+		unsigned int index);
+	// RTIME has units of 1 = 838 nanoseconds
+	// time at which first scan started, used to check scan timing
+	RTIME start;
+	// time between scans
+	RTIME scan_period;
+	// time between conversions in a scan
+	RTIME convert_period;
+	// flags
+	volatile int stop;	// indicates we should stop
+	volatile int rt_task_active;	// indicates rt_task is servicing a struct comedi_cmd
+	volatile int scan_task_active;	// indicates scan_task is servicing a struct comedi_cmd
+	unsigned timer_running:1;
+};
+#define devpriv ((struct timer_private *)dev->private)
+
+static int timer_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	devpriv->stop = 1;
+
+	return 0;
+}
+
+// checks for scan timing error
+inline static int check_scan_timing(struct comedi_device * dev,
+	unsigned long long scan)
+{
+	RTIME now, timing_error;
+
+	now = rt_get_time();
+	timing_error = now - (devpriv->start + scan * devpriv->scan_period);
+	if (timing_error > devpriv->scan_period) {
+		comedi_error(dev, "timing error");
+		rt_printk("scan started %i ns late\n", timing_error * 838);
+		return -1;
+	}
+
+	return 0;
+}
+
+// checks for conversion timing error
+inline static int check_conversion_timing(struct comedi_device * dev,
+	RTIME scan_start, unsigned int conversion)
+{
+	RTIME now, timing_error;
+
+	now = rt_get_time();
+	timing_error =
+		now - (scan_start + conversion * devpriv->convert_period);
+	if (timing_error > devpriv->convert_period) {
+		comedi_error(dev, "timing error");
+		rt_printk("conversion started %i ns late\n",
+			timing_error * 838);
+		return -1;
+	}
+
+	return 0;
+}
+
+// devpriv->io_function for an input subdevice
+static int timer_data_read(struct comedi_device * dev, struct comedi_cmd * cmd,
+	unsigned int index)
+{
+	struct comedi_subdevice *s = dev->read_subdev;
+	int ret;
+	unsigned int data;
+
+	ret = comedi_data_read(devpriv->device, devpriv->subd,
+		CR_CHAN(cmd->chanlist[index]),
+		CR_RANGE(cmd->chanlist[index]),
+		CR_AREF(cmd->chanlist[index]), &data);
+	if (ret < 0) {
+		comedi_error(dev, "read error");
+		return -EIO;
+	}
+	if (s->flags & SDF_LSAMPL) {
+		cfc_write_long_to_buffer(s, data);
+	} else {
+		comedi_buf_put(s->async, data);
+	}
+
+	return 0;
+}
+
+// devpriv->io_function for an output subdevice
+static int timer_data_write(struct comedi_device * dev, struct comedi_cmd * cmd,
+	unsigned int index)
+{
+	struct comedi_subdevice *s = dev->write_subdev;
+	unsigned int num_bytes;
+	short data;
+	unsigned int long_data;
+	int ret;
+
+	if (s->flags & SDF_LSAMPL) {
+		num_bytes =
+			cfc_read_array_from_buffer(s, &long_data,
+			sizeof(long_data));
+	} else {
+		num_bytes = cfc_read_array_from_buffer(s, &data, sizeof(data));
+		long_data = data;
+	}
+
+	if (num_bytes == 0) {
+		comedi_error(dev, "buffer underrun");
+		return -EAGAIN;
+	}
+	ret = comedi_data_write(devpriv->device, devpriv->subd,
+		CR_CHAN(cmd->chanlist[index]),
+		CR_RANGE(cmd->chanlist[index]),
+		CR_AREF(cmd->chanlist[index]), long_data);
+	if (ret < 0) {
+		comedi_error(dev, "write error");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+// devpriv->io_function for DIO subdevices
+static int timer_dio_read(struct comedi_device * dev, struct comedi_cmd * cmd,
+	unsigned int index)
+{
+	struct comedi_subdevice *s = dev->read_subdev;
+	int ret;
+	unsigned int data;
+
+	ret = comedi_dio_bitfield(devpriv->device, devpriv->subd, 0, &data);
+	if (ret < 0) {
+		comedi_error(dev, "read error");
+		return -EIO;
+	}
+
+	if (s->flags & SDF_LSAMPL)
+		cfc_write_long_to_buffer(s, data);
+	else
+		cfc_write_to_buffer(s, data);
+
+	return 0;
+}
+
+// performs scans
+static void scan_task_func(comedi_rt_task_context_t d)
+{
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s = dev->subdevices + 0;
+	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+	int i, ret;
+	unsigned long long n;
+	RTIME scan_start;
+
+	// every struct comedi_cmd causes one execution of while loop
+	while (1) {
+		devpriv->scan_task_active = 1;
+		// each for loop completes one scan
+		for (n = 0; n < cmd->stop_arg || cmd->stop_src == TRIG_NONE;
+			n++) {
+			if (n) {
+				// suspend task until next scan
+				ret = rt_task_suspend(devpriv->scan_task);
+				if (ret < 0) {
+					comedi_error(dev,
+						"error suspending scan task");
+					async->events |= COMEDI_CB_ERROR;
+					goto cleanup;
+				}
+			}
+			// check if stop flag was set (by timer_cancel())
+			if (devpriv->stop)
+				goto cleanup;
+			ret = check_scan_timing(dev, n);
+			if (ret < 0) {
+				async->events |= COMEDI_CB_ERROR;
+				goto cleanup;
+			}
+			scan_start = rt_get_time();
+			for (i = 0; i < cmd->scan_end_arg; i++) {
+				// conversion timing
+				if (cmd->convert_src == TRIG_TIMER && i) {
+					rt_task_wait_period();
+					ret = check_conversion_timing(dev,
+						scan_start, i);
+					if (ret < 0) {
+						async->events |=
+							COMEDI_CB_ERROR;
+						goto cleanup;
+					}
+				}
+				ret = devpriv->io_function(dev, cmd, i);
+				if (ret < 0) {
+					async->events |= COMEDI_CB_ERROR;
+					goto cleanup;
+				}
+			}
+			s->async->events |= COMEDI_CB_BLOCK;
+			comedi_event(dev, s);
+			s->async->events = 0;
+		}
+
+	      cleanup:
+
+		comedi_unlock(devpriv->device, devpriv->subd);
+		async->events |= COMEDI_CB_EOA;
+		comedi_event(dev, s);
+		async->events = 0;
+		devpriv->scan_task_active = 0;
+		// suspend task until next struct comedi_cmd
+		rt_task_suspend(devpriv->scan_task);
+	}
+}
+
+static void timer_task_func(comedi_rt_task_context_t d)
+{
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s = dev->subdevices + 0;
+	struct comedi_cmd *cmd = &s->async->cmd;
+	int ret;
+	unsigned long long n;
+
+	// every struct comedi_cmd causes one execution of while loop
+	while (1) {
+		devpriv->rt_task_active = 1;
+		devpriv->scan_task_active = 1;
+		devpriv->start = rt_get_time();
+
+		for (n = 0; n < cmd->stop_arg || cmd->stop_src == TRIG_NONE;
+			n++) {
+			// scan timing
+			if (n)
+				rt_task_wait_period();
+			if (devpriv->scan_task_active == 0) {
+				goto cleanup;
+			}
+			ret = rt_task_make_periodic(devpriv->scan_task,
+				devpriv->start + devpriv->scan_period * n,
+				devpriv->convert_period);
+			if (ret < 0) {
+				comedi_error(dev, "bug!");
+			}
+		}
+
+	      cleanup:
+
+		devpriv->rt_task_active = 0;
+		// suspend until next struct comedi_cmd
+		rt_task_suspend(devpriv->rt_task);
+	}
+}
+
+static int timer_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	struct comedi_insn xinsn = *insn;
+
+	xinsn.data = data;
+	xinsn.subdev = devpriv->subd;
+
+	return comedi_do_insn(devpriv->device, &xinsn);
+}
+
+static int cmdtest_helper(struct comedi_cmd * cmd,
+	unsigned int start_src,
+	unsigned int scan_begin_src,
+	unsigned int convert_src,
+	unsigned int scan_end_src, unsigned int stop_src)
+{
+	int err = 0;
+	int tmp;
+
+	tmp = cmd->start_src;
+	cmd->start_src &= start_src;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= scan_begin_src;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= convert_src;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= scan_end_src;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= stop_src;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	return err;
+}
+
+static int timer_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	unsigned int start_src = 0;
+
+	if (s->type == COMEDI_SUBD_AO)
+		start_src = TRIG_INT;
+	else
+		start_src = TRIG_NOW;
+
+	err = cmdtest_helper(cmd, start_src,	/* start_src */
+		TRIG_TIMER | TRIG_FOLLOW,	/* scan_begin_src */
+		TRIG_NOW | TRIG_TIMER,	/* convert_src */
+		TRIG_COUNT,	/* scan_end_src */
+		TRIG_COUNT | TRIG_NONE);	/* stop_src */
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually
+	 * compatible */
+
+	if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_INT)
+		err++;
+	if (cmd->scan_begin_src != TRIG_TIMER &&
+		cmd->scan_begin_src != TRIG_FOLLOW)
+		err++;
+	if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_NOW)
+		err++;
+	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+		err++;
+	if (cmd->scan_begin_src == TRIG_FOLLOW
+		&& cmd->convert_src != TRIG_TIMER)
+		err++;
+	if (cmd->convert_src == TRIG_NOW && cmd->scan_begin_src != TRIG_TIMER)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+	// limit frequency, this is fairly arbitrary
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		if (cmd->scan_begin_arg < SPEED_LIMIT) {
+			cmd->scan_begin_arg = SPEED_LIMIT;
+			err++;
+		}
+	}
+	if (cmd->convert_src == TRIG_TIMER) {
+		if (cmd->convert_arg < SPEED_LIMIT) {
+			cmd->convert_arg = SPEED_LIMIT;
+			err++;
+		}
+	}
+	// make sure conversion and scan frequencies are compatible
+	if (cmd->convert_src == TRIG_TIMER && cmd->scan_begin_src == TRIG_TIMER) {
+		if (cmd->convert_arg * cmd->scan_end_arg > cmd->scan_begin_arg) {
+			cmd->scan_begin_arg =
+				cmd->convert_arg * cmd->scan_end_arg;
+			err++;
+		}
+	}
+	if (err)
+		return 3;
+
+	/* step 4: fix up and arguments */
+	if (err)
+		return 4;
+
+	return 0;
+}
+
+static int timer_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	int ret;
+	struct comedi_cmd *cmd = &s->async->cmd;
+
+	/* hack attack: drivers are not supposed to do this: */
+	dev->rt = 1;
+
+	// make sure tasks have finished cleanup of last struct comedi_cmd
+	if (devpriv->rt_task_active || devpriv->scan_task_active)
+		return -EBUSY;
+
+	ret = comedi_lock(devpriv->device, devpriv->subd);
+	if (ret < 0) {
+		comedi_error(dev, "failed to obtain lock");
+		return ret;
+	}
+	switch (cmd->scan_begin_src) {
+	case TRIG_TIMER:
+		devpriv->scan_period = nano2count(cmd->scan_begin_arg);
+		break;
+	case TRIG_FOLLOW:
+		devpriv->scan_period =
+			nano2count(cmd->convert_arg * cmd->scan_end_arg);
+		break;
+	default:
+		comedi_error(dev, "bug setting scan period!");
+		return -1;
+		break;
+	}
+	switch (cmd->convert_src) {
+	case TRIG_TIMER:
+		devpriv->convert_period = nano2count(cmd->convert_arg);
+		break;
+	case TRIG_NOW:
+		devpriv->convert_period = 1;
+		break;
+	default:
+		comedi_error(dev, "bug setting conversion period!");
+		return -1;
+		break;
+	}
+
+	if (cmd->start_src == TRIG_NOW)
+		return timer_start_cmd(dev, s);
+
+	s->async->inttrig = timer_inttrig;
+
+	return 0;
+}
+
+static int timer_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int trig_num)
+{
+	if (trig_num != 0)
+		return -EINVAL;
+
+	s->async->inttrig = NULL;
+
+	return timer_start_cmd(dev, s);
+}
+
+static int timer_start_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+	RTIME now, delay, period;
+	int ret;
+
+	devpriv->stop = 0;
+	s->async->events = 0;
+
+	if (cmd->start_src == TRIG_NOW)
+		delay = nano2count(cmd->start_arg);
+	else
+		delay = 0;
+
+	now = rt_get_time();
+	/* Using 'period' this way gets around some weird bug in gcc-2.95.2
+	 * that generates the compile error 'internal error--unrecognizable insn'
+	 * when rt_task_make_period() is called (observed with rtlinux-3.1, linux-2.2.19).
+	 *  - fmhess */
+	period = devpriv->scan_period;
+	ret = rt_task_make_periodic(devpriv->rt_task, now + delay, period);
+	if (ret < 0) {
+		comedi_error(dev, "error starting rt_task");
+		return ret;
+	}
+	return 0;
+}
+
+static int timer_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	int ret;
+	struct comedi_subdevice *s, *emul_s;
+	struct comedi_device *emul_dev;
+	/* These should probably be devconfig options[] */
+	const int timer_priority = 4;
+	const int scan_priority = timer_priority + 1;
+	char path[20];
+
+	printk("comedi%d: timer: ", dev->minor);
+
+	dev->board_name = "timer";
+
+	if ((ret = alloc_subdevices(dev, 1)) < 0)
+		return ret;
+	if ((ret = alloc_private(dev, sizeof(struct timer_private))) < 0)
+		return ret;
+
+	sprintf(path, "/dev/comedi%d", it->options[0]);
+	devpriv->device = comedi_open(path);
+	devpriv->subd = it->options[1];
+
+	printk("emulating commands for minor %i, subdevice %d\n",
+		it->options[0], devpriv->subd);
+
+	emul_dev = devpriv->device;
+	emul_s = emul_dev->subdevices + devpriv->subd;
+
+	// input or output subdevice
+	s = dev->subdevices + 0;
+	s->type = emul_s->type;
+	s->subdev_flags = emul_s->subdev_flags;	/* SDF_GROUND (to fool check_driver) */
+	s->n_chan = emul_s->n_chan;
+	s->len_chanlist = 1024;
+	s->do_cmd = timer_cmd;
+	s->do_cmdtest = timer_cmdtest;
+	s->cancel = timer_cancel;
+	s->maxdata = emul_s->maxdata;
+	s->range_table = emul_s->range_table;
+	s->range_table_list = emul_s->range_table_list;
+	switch (emul_s->type) {
+	case COMEDI_SUBD_AI:
+		s->insn_read = timer_insn;
+		dev->read_subdev = s;
+		s->subdev_flags |= SDF_CMD_READ;
+		devpriv->io_function = timer_data_read;
+		break;
+	case COMEDI_SUBD_AO:
+		s->insn_write = timer_insn;
+		s->insn_read = timer_insn;
+		dev->write_subdev = s;
+		s->subdev_flags |= SDF_CMD_WRITE;
+		devpriv->io_function = timer_data_write;
+		break;
+	case COMEDI_SUBD_DIO:
+		s->insn_write = timer_insn;
+		s->insn_read = timer_insn;
+		s->insn_bits = timer_insn;
+		dev->read_subdev = s;
+		s->subdev_flags |= SDF_CMD_READ;
+		devpriv->io_function = timer_dio_read;
+		break;
+	default:
+		comedi_error(dev, "failed to determine subdevice type!");
+		return -EINVAL;
+	}
+
+	rt_set_oneshot_mode();
+	start_rt_timer(1);
+	devpriv->timer_running = 1;
+
+	devpriv->rt_task = kzalloc(sizeof(RT_TASK), GFP_KERNEL);
+
+	// initialize real-time tasks
+	ret = rt_task_init(devpriv->rt_task, timer_task_func,
+		(comedi_rt_task_context_t) dev, 3000, timer_priority, 0, 0);
+	if (ret < 0) {
+		comedi_error(dev, "error initalizing rt_task");
+		kfree(devpriv->rt_task);
+		devpriv->rt_task = 0;
+		return ret;
+	}
+
+	devpriv->scan_task = kzalloc(sizeof(RT_TASK), GFP_KERNEL);
+
+	ret = rt_task_init(devpriv->scan_task, scan_task_func,
+		(comedi_rt_task_context_t) dev, 3000, scan_priority, 0, 0);
+	if (ret < 0) {
+		comedi_error(dev, "error initalizing scan_task");
+		kfree(devpriv->scan_task);
+		devpriv->scan_task = 0;
+		return ret;
+	}
+
+	return 1;
+}
+
+// free allocated resources
+static int timer_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: timer: remove\n", dev->minor);
+
+	if (devpriv) {
+		if (devpriv->rt_task) {
+			rt_task_delete(devpriv->rt_task);
+			kfree(devpriv->rt_task);
+		}
+		if (devpriv->scan_task) {
+			rt_task_delete(devpriv->scan_task);
+			kfree(devpriv->scan_task);
+		}
+		if (devpriv->timer_running)
+			stop_rt_timer();
+		if (devpriv->device)
+			comedi_close(devpriv->device);
+	}
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c
index 4b4c37d..e679328 100644
--- a/drivers/staging/comedi/drivers/comedi_test.c
+++ b/drivers/staging/comedi/drivers/comedi_test.c
@@ -89,13 +89,13 @@
 	unsigned int scan_period;	/* scan period in usec */
 	unsigned int convert_period;	/* conversion period in usec */
 	unsigned timer_running:1;
-	lsampl_t ao_loopbacks[N_CHANS];
+	unsigned int ao_loopbacks[N_CHANS];
 };
 #define devpriv ((struct waveform_private *)dev->private)
 
-static int waveform_attach(comedi_device *dev, comedi_devconfig *it);
-static int waveform_detach(comedi_device *dev);
-static comedi_driver driver_waveform = {
+static int waveform_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int waveform_detach(struct comedi_device *dev);
+static struct comedi_driver driver_waveform = {
       .driver_name =	"comedi_test",
       .module =		THIS_MODULE,
       .attach =		waveform_attach,
@@ -107,28 +107,28 @@
 
 COMEDI_INITCLEANUP(driver_waveform);
 
-static int waveform_ai_cmdtest(comedi_device *dev, comedi_subdevice *s,
-			       comedi_cmd *cmd);
-static int waveform_ai_cmd(comedi_device *dev, comedi_subdevice *s);
-static int waveform_ai_cancel(comedi_device *dev, comedi_subdevice *s);
-static int waveform_ai_insn_read(comedi_device *dev, comedi_subdevice *s,
-				 comedi_insn *insn, lsampl_t *data);
-static int waveform_ao_insn_write(comedi_device *dev, comedi_subdevice *s,
-				  comedi_insn *insn, lsampl_t *data);
-static sampl_t fake_sawtooth(comedi_device *dev, unsigned int range,
+static int waveform_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+			       struct comedi_cmd *cmd);
+static int waveform_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
+static int waveform_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
+static int waveform_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data);
+static int waveform_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
+				  struct comedi_insn *insn, unsigned int *data);
+static short fake_sawtooth(struct comedi_device *dev, unsigned int range,
 			     unsigned long current_time);
-static sampl_t fake_squarewave(comedi_device *dev, unsigned int range,
+static short fake_squarewave(struct comedi_device *dev, unsigned int range,
 			       unsigned long current_time);
-static sampl_t fake_flatline(comedi_device *dev, unsigned int range,
+static short fake_flatline(struct comedi_device *dev, unsigned int range,
 			     unsigned long current_time);
-static sampl_t fake_waveform(comedi_device *dev, unsigned int channel,
+static short fake_waveform(struct comedi_device *dev, unsigned int channel,
 			     unsigned int range, unsigned long current_time);
 
 /* 1000 nanosec in a microsec */
 static const int nano_per_micro = 1000;
 
 /* fake analog input ranges */
-static const comedi_lrange waveform_ai_ranges = {
+static const struct comedi_lrange waveform_ai_ranges = {
 	2,
 	{
 			BIP_RANGE(10),
@@ -143,9 +143,9 @@
 */
 static void waveform_ai_interrupt(unsigned long arg)
 {
-	comedi_device *dev = (comedi_device *) arg;
-	comedi_async *async = dev->read_subdev->async;
-	comedi_cmd *cmd = &async->cmd;
+	struct comedi_device *dev = (struct comedi_device *) arg;
+	struct comedi_async *async = dev->read_subdev->async;
+	struct comedi_cmd *cmd = &async->cmd;
 	unsigned int i, j;
 	/* all times in microsec */
 	unsigned long elapsed_time;
@@ -192,9 +192,9 @@
 	comedi_event(dev, dev->read_subdev);
 }
 
-static int waveform_attach(comedi_device *dev, comedi_devconfig *it)
+static int waveform_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
-	comedi_subdevice *s;
+	struct comedi_subdevice *s;
 	int amplitude = it->options[0];
 	int period = it->options[1];
 	int i;
@@ -259,7 +259,7 @@
 	return 1;
 }
 
-static int waveform_detach(comedi_device *dev)
+static int waveform_detach(struct comedi_device *dev)
 {
 	printk("comedi%d: comedi_test: remove\n", dev->minor);
 
@@ -269,8 +269,8 @@
 	return 0;
 }
 
-static int waveform_ai_cmdtest(comedi_device *dev, comedi_subdevice *s,
-			       comedi_cmd *cmd)
+static int waveform_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+			       struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -397,9 +397,9 @@
 	return 0;
 }
 
-static int waveform_ai_cmd(comedi_device *dev, comedi_subdevice *s)
+static int waveform_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
-	comedi_cmd *cmd = &s->async->cmd;
+	struct comedi_cmd *cmd = &s->async->cmd;
 
 	if (cmd->flags & TRIG_RT) {
 		comedi_error(dev,
@@ -429,20 +429,20 @@
 	return 0;
 }
 
-static int waveform_ai_cancel(comedi_device *dev, comedi_subdevice *s)
+static int waveform_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	devpriv->timer_running = 0;
 	del_timer(&devpriv->timer);
 	return 0;
 }
 
-static sampl_t fake_sawtooth(comedi_device *dev, unsigned int range_index,
+static short fake_sawtooth(struct comedi_device *dev, unsigned int range_index,
 			     unsigned long current_time)
 {
-	comedi_subdevice *s = dev->read_subdev;
+	struct comedi_subdevice *s = dev->read_subdev;
 	unsigned int offset = s->maxdata / 2;
 	u64 value;
-	const comedi_krange *krange = &s->range_table->range[range_index];
+	const struct comedi_krange *krange = &s->range_table->range[range_index];
 	u64 binary_amplitude;
 
 	binary_amplitude = s->maxdata;
@@ -457,13 +457,13 @@
 
 	return offset + value;
 }
-static sampl_t fake_squarewave(comedi_device *dev, unsigned int range_index,
+static short fake_squarewave(struct comedi_device *dev, unsigned int range_index,
 			       unsigned long current_time)
 {
-	comedi_subdevice *s = dev->read_subdev;
+	struct comedi_subdevice *s = dev->read_subdev;
 	unsigned int offset = s->maxdata / 2;
 	u64 value;
-	const comedi_krange *krange = &s->range_table->range[range_index];
+	const struct comedi_krange *krange = &s->range_table->range[range_index];
 	current_time %= devpriv->usec_period;
 
 	value = s->maxdata;
@@ -476,14 +476,14 @@
 	return offset + value;
 }
 
-static sampl_t fake_flatline(comedi_device *dev, unsigned int range_index,
+static short fake_flatline(struct comedi_device *dev, unsigned int range_index,
 			     unsigned long current_time)
 {
 	return dev->read_subdev->maxdata / 2;
 }
 
 /* generates a different waveform depending on what channel is read */
-static sampl_t fake_waveform(comedi_device *dev, unsigned int channel,
+static short fake_waveform(struct comedi_device *dev, unsigned int channel,
 			     unsigned int range, unsigned long current_time)
 {
 	enum {
@@ -504,8 +504,8 @@
 	return fake_flatline(dev, range, current_time);
 }
 
-static int waveform_ai_insn_read(comedi_device *dev, comedi_subdevice *s,
-				 comedi_insn *insn, lsampl_t *data)
+static int waveform_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data)
 {
 	int i, chan = CR_CHAN(insn->chanspec);
 
@@ -515,8 +515,8 @@
 	return insn->n;
 }
 
-static int waveform_ao_insn_write(comedi_device *dev, comedi_subdevice *s,
-				  comedi_insn *insn, lsampl_t *data)
+static int waveform_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
+				  struct comedi_insn *insn, unsigned int *data)
 {
 	int i, chan = CR_CHAN(insn->chanspec);
 
diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c
new file mode 100644
index 0000000..1f194a0
--- /dev/null
+++ b/drivers/staging/comedi/drivers/contec_pci_dio.c
@@ -0,0 +1,230 @@
+/*
+    comedi/drivers/contec_pci_dio.c
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: contec_pci_dio
+Description: Contec PIO1616L digital I/O board
+Devices: [Contec] PIO1616L (contec_pci_dio)
+Author: Stefano Rivoir <s.rivoir@gts.it>
+Updated: Wed, 27 Jun 2007 13:00:06 +0100
+Status: works
+
+Configuration Options:
+  [0] - PCI bus of device (optional)
+  [1] - PCI slot of device (optional)
+  If bus/slot is not specified, the first supported
+  PCI device found will be used.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+enum contec_model {
+	PIO1616L = 0,
+};
+
+struct contec_board {
+	const char *name;
+	int model;
+	int in_ports;
+	int out_ports;
+	int in_offs;
+	int out_offs;
+	int out_boffs;
+};
+static const struct contec_board contec_boards[] = {
+	{"PIO1616L", PIO1616L, 16, 16, 0, 2, 10},
+};
+
+#define PCI_DEVICE_ID_PIO1616L 0x8172
+static DEFINE_PCI_DEVICE_TABLE(contec_pci_table) = {
+	{PCI_VENDOR_ID_CONTEC, PCI_DEVICE_ID_PIO1616L, PCI_ANY_ID, PCI_ANY_ID,
+		0, 0, PIO1616L},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, contec_pci_table);
+
+#define thisboard ((const struct contec_board *)dev->board_ptr)
+
+struct contec_private {
+	int data;
+
+	struct pci_dev *pci_dev;
+
+};
+
+#define devpriv ((struct contec_private *)dev->private)
+
+static int contec_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int contec_detach(struct comedi_device * dev);
+static struct comedi_driver driver_contec = {
+      driver_name:"contec_pci_dio",
+      module:THIS_MODULE,
+      attach:contec_attach,
+      detach:contec_detach,
+};
+
+/* Classic digital IO */
+static int contec_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int contec_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+#if 0
+static int contec_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd);
+
+static int contec_ns_to_timer(unsigned int *ns, int round);
+#endif
+
+static int contec_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct pci_dev *pcidev;
+	struct comedi_subdevice *s;
+
+	printk("comedi%d: contec: ", dev->minor);
+
+	dev->board_name = thisboard->name;
+
+	if (alloc_private(dev, sizeof(struct contec_private)) < 0)
+		return -ENOMEM;
+
+	if (alloc_subdevices(dev, 2) < 0)
+		return -ENOMEM;
+
+	for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+		pcidev != NULL;
+		pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+
+		if (pcidev->vendor == PCI_VENDOR_ID_CONTEC &&
+			pcidev->device == PCI_DEVICE_ID_PIO1616L) {
+			if (it->options[0] || it->options[1]) {
+				/* Check bus and slot. */
+				if (it->options[0] != pcidev->bus->number ||
+					it->options[1] !=
+					PCI_SLOT(pcidev->devfn)) {
+					continue;
+				}
+			}
+			devpriv->pci_dev = pcidev;
+			if (comedi_pci_enable(pcidev, "contec_pci_dio")) {
+				printk("error enabling PCI device and request regions!\n");
+				return -EIO;
+			}
+			dev->iobase = pci_resource_start(pcidev, 0);
+			printk(" base addr %lx ", dev->iobase);
+
+			dev->board_ptr = contec_boards + 0;
+
+			s = dev->subdevices + 0;
+
+			s->type = COMEDI_SUBD_DI;
+			s->subdev_flags = SDF_READABLE;
+			s->n_chan = 16;
+			s->maxdata = 1;
+			s->range_table = &range_digital;
+			s->insn_bits = contec_di_insn_bits;
+
+			s = dev->subdevices + 1;
+			s->type = COMEDI_SUBD_DO;
+			s->subdev_flags = SDF_WRITABLE;
+			s->n_chan = 16;
+			s->maxdata = 1;
+			s->range_table = &range_digital;
+			s->insn_bits = contec_do_insn_bits;
+
+			printk("attached\n");
+
+			return 1;
+		}
+	}
+
+	printk("card not present!\n");
+
+	return -EIO;
+}
+
+static int contec_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: contec: remove\n", dev->minor);
+
+	if (devpriv && devpriv->pci_dev) {
+		if (dev->iobase) {
+			comedi_pci_disable(devpriv->pci_dev);
+		}
+		pci_dev_put(devpriv->pci_dev);
+	}
+
+	return 0;
+}
+
+#if 0
+static int contec_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	printk("contec_cmdtest called\n");
+	return 0;
+}
+
+static int contec_ns_to_timer(unsigned int *ns, int round)
+{
+	return *ns;
+}
+#endif
+
+static int contec_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+
+	printk("contec_do_insn_bits called\n");
+	printk(" data: %d %d\n", data[0], data[1]);
+
+	if (insn->n != 2)
+		return -EINVAL;
+
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= data[0] & data[1];
+		rt_printk("  out: %d on %lx\n", s->state,
+			dev->iobase + thisboard->out_offs);
+		outw(s->state, dev->iobase + thisboard->out_offs);
+	}
+	return 2;
+}
+
+static int contec_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+
+	rt_printk("contec_di_insn_bits called\n");
+	rt_printk(" data: %d %d\n", data[0], data[1]);
+
+	if (insn->n != 2)
+		return -EINVAL;
+
+	data[1] = inw(dev->iobase + thisboard->in_offs);
+
+	return 2;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_contec, contec_pci_table);
diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c
new file mode 100644
index 0000000..3b8444f
--- /dev/null
+++ b/drivers/staging/comedi/drivers/daqboard2000.c
@@ -0,0 +1,877 @@
+/*
+   comedi/drivers/daqboard2000.c
+   hardware driver for IOtech DAQboard/2000
+
+   COMEDI - Linux Control and Measurement Device Interface
+   Copyright (C) 1999 Anders Blomdell <anders.blomdell@control.lth.se>
+
+   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.
+
+ */
+/*
+Driver: daqboard2000
+Description: IOTech DAQBoard/2000
+Author: Anders Blomdell <anders.blomdell@control.lth.se>
+Status: works
+Updated: Mon, 14 Apr 2008 15:28:52 +0100
+Devices: [IOTech] DAQBoard/2000 (daqboard2000)
+
+Much of the functionality of this driver was determined from reading
+the source code for the Windows driver.
+
+The FPGA on the board requires initialization code, which can
+be loaded by comedi_config using the -i
+option.  The initialization code is available from http://www.comedi.org
+in the comedi_nonfree_firmware tarball.
+
+Configuration options:
+  [0] - PCI bus of device (optional)
+  [1] - PCI slot of device (optional)
+  If bus/slot is not specified, the first supported
+  PCI device found will be used.
+*/
+/*
+   This card was obviously never intended to leave the Windows world,
+   since it lacked all kind of hardware documentation (except for cable
+   pinouts, plug and pray has something to catch up with yet).
+
+   With some help from our swedish distributor, we got the Windows sourcecode
+   for the card, and here are the findings so far.
+
+   1. A good document that describes the PCI interface chip is found at:
+      http://plx.plxtech.com/download/9080/databook/9080db-106.pdf
+
+   2. The initialization done so far is:
+        a. program the FPGA (windows code sans a lot of error messages)
+	b.
+
+   3. Analog out seems to work OK with DAC's disabled, if DAC's are enabled,
+      you have to output values to all enabled DAC's until result appears, I
+      guess that it has something to do with pacer clocks, but the source
+      gives me no clues. I'll keep it simple so far.
+
+   4. Analog in.
+        Each channel in the scanlist seems to be controlled by four
+	control words:
+
+        Word0:
+          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+          ! | | | ! | | | ! | | | ! | | | !
+          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+        Word1:
+          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+          ! | | | ! | | | ! | | | ! | | | !
+          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	   |             |       | | | | |
+           +------+------+       | | | | +-- Digital input (??)
+		  |		 | | | +---- 10 us settling time
+		  |		 | | +------ Suspend acquisition (last to scan)
+		  |		 | +-------- Simultaneous sample and hold
+		  |		 +---------- Signed data format
+		  +------------------------- Correction offset low
+
+        Word2:
+          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+          ! | | | ! | | | ! | | | ! | | | !
+          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+           |     | |     | | | | | |     |
+           +-----+ +--+--+ +++ +++ +--+--+
+              |       |     |   |     +----- Expansion channel
+	      |       |     |   +----------- Expansion gain
+              |       |     +--------------- Channel (low)
+	      |       +--------------------- Correction offset high
+	      +----------------------------- Correction gain low
+        Word3:
+          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+          ! | | | ! | | | ! | | | ! | | | !
+          +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+           |             | | | |   | | | |
+           +------+------+ | | +-+-+ | | +-- Low bank enable
+                  |        | |   |   | +---- High bank enable
+                  |        | |   |   +------ Hi/low select
+		  |    	   | |   +---------- Gain (1,?,2,4,8,16,32,64)
+		  |    	   | +-------------- differential/single ended
+		  |    	   +---------------- Unipolar
+		  +------------------------- Correction gain high
+
+
+
+   999. The card seems to have an incredible amount of capabilities, but
+        trying to reverse engineer them from the Windows source is beyond my
+	patience.
+
+
+ */
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+
+#include "comedi_pci.h"
+#include "8255.h"
+
+#define DAQBOARD2000_SUBSYSTEM_IDS2 	0x00021616	/* Daqboard/2000 - 2 Dacs */
+#define DAQBOARD2000_SUBSYSTEM_IDS4 	0x00041616	/* Daqboard/2000 - 4 Dacs */
+
+#define DAQBOARD2000_DAQ_SIZE 		0x1002
+#define DAQBOARD2000_PLX_SIZE 		0x100
+
+// Initialization bits for the Serial EEPROM Control Register
+#define DAQBOARD2000_SECRProgPinHi      0x8001767e
+#define DAQBOARD2000_SECRProgPinLo      0x8000767e
+#define DAQBOARD2000_SECRLocalBusHi     0xc000767e
+#define DAQBOARD2000_SECRLocalBusLo     0x8000767e
+#define DAQBOARD2000_SECRReloadHi       0xa000767e
+#define DAQBOARD2000_SECRReloadLo       0x8000767e
+
+// SECR status bits
+#define DAQBOARD2000_EEPROM_PRESENT     0x10000000
+
+// CPLD status bits
+#define DAQBOARD2000_CPLD_INIT 		0x0002
+#define DAQBOARD2000_CPLD_DONE 		0x0004
+
+// Available ranges
+static const struct comedi_lrange range_daqboard2000_ai = { 13, {
+			RANGE(-10, 10),
+			RANGE(-5, 5),
+			RANGE(-2.5, 2.5),
+			RANGE(-1.25, 1.25),
+			RANGE(-0.625, 0.625),
+			RANGE(-0.3125, 0.3125),
+			RANGE(-0.156, 0.156),
+			RANGE(0, 10),
+			RANGE(0, 5),
+			RANGE(0, 2.5),
+			RANGE(0, 1.25),
+			RANGE(0, 0.625),
+			RANGE(0, 0.3125)
+	}
+};
+
+static const struct comedi_lrange range_daqboard2000_ao = { 1, {
+			RANGE(-10, 10)
+	}
+};
+
+struct daqboard2000_hw {
+	volatile u16 acqControl;	// 0x00
+	volatile u16 acqScanListFIFO;	// 0x02
+	volatile u32 acqPacerClockDivLow;	// 0x04
+
+	volatile u16 acqScanCounter;	// 0x08
+	volatile u16 acqPacerClockDivHigh;	// 0x0a
+	volatile u16 acqTriggerCount;	// 0x0c
+	volatile u16 fill2;	// 0x0e
+	volatile u16 acqResultsFIFO;	// 0x10
+	volatile u16 fill3;	// 0x12
+	volatile u16 acqResultsShadow;	// 0x14
+	volatile u16 fill4;	// 0x16
+	volatile u16 acqAdcResult;	// 0x18
+	volatile u16 fill5;	// 0x1a
+	volatile u16 dacScanCounter;	// 0x1c
+	volatile u16 fill6;	// 0x1e
+
+	volatile u16 dacControl;	// 0x20
+	volatile u16 fill7;	// 0x22
+	volatile s16 dacFIFO;	// 0x24
+	volatile u16 fill8[2];	// 0x26
+	volatile u16 dacPacerClockDiv;	// 0x2a
+	volatile u16 refDacs;	// 0x2c
+	volatile u16 fill9;	// 0x2e
+
+	volatile u16 dioControl;	// 0x30
+	volatile s16 dioP3hsioData;	// 0x32
+	volatile u16 dioP3Control;	// 0x34
+	volatile u16 calEepromControl;	// 0x36
+	volatile s16 dacSetting[4];	// 0x38
+	volatile s16 dioP2ExpansionIO8Bit[32];	// 0x40
+
+	volatile u16 ctrTmrControl;	// 0x80
+	volatile u16 fill10[3];	// 0x82
+	volatile s16 ctrInput[4];	// 0x88
+	volatile u16 fill11[8];	// 0x90
+	volatile u16 timerDivisor[2];	// 0xa0
+	volatile u16 fill12[6];	// 0xa4
+
+	volatile u16 dmaControl;	// 0xb0
+	volatile u16 trigControl;	// 0xb2
+	volatile u16 fill13[2];	// 0xb4
+	volatile u16 calEeprom;	// 0xb8
+	volatile u16 acqDigitalMark;	// 0xba
+	volatile u16 trigDacs;	// 0xbc
+	volatile u16 fill14;	// 0xbe
+	volatile s16 dioP2ExpansionIO16Bit[32];	// 0xc0
+};
+
+/* Scan Sequencer programming */
+#define DAQBOARD2000_SeqStartScanList            0x0011
+#define DAQBOARD2000_SeqStopScanList             0x0010
+
+// Prepare for acquisition
+#define DAQBOARD2000_AcqResetScanListFifo        0x0004
+#define DAQBOARD2000_AcqResetResultsFifo         0x0002
+#define DAQBOARD2000_AcqResetConfigPipe          0x0001
+
+// Acqusition status bits
+#define DAQBOARD2000_AcqResultsFIFOMore1Sample   0x0001
+#define DAQBOARD2000_AcqResultsFIFOHasValidData  0x0002
+#define DAQBOARD2000_AcqResultsFIFOOverrun       0x0004
+#define DAQBOARD2000_AcqLogicScanning            0x0008
+#define DAQBOARD2000_AcqConfigPipeFull           0x0010
+#define DAQBOARD2000_AcqScanListFIFOEmpty        0x0020
+#define DAQBOARD2000_AcqAdcNotReady              0x0040
+#define DAQBOARD2000_ArbitrationFailure          0x0080
+#define DAQBOARD2000_AcqPacerOverrun             0x0100
+#define DAQBOARD2000_DacPacerOverrun             0x0200
+#define DAQBOARD2000_AcqHardwareError            0x01c0
+
+// Scan Sequencer programming
+#define DAQBOARD2000_SeqStartScanList            0x0011
+#define DAQBOARD2000_SeqStopScanList             0x0010
+
+/* Pacer Clock Control */
+#define DAQBOARD2000_AdcPacerInternal            0x0030
+#define DAQBOARD2000_AdcPacerExternal            0x0032
+#define DAQBOARD2000_AdcPacerEnable              0x0031
+#define DAQBOARD2000_AdcPacerEnableDacPacer      0x0034
+#define DAQBOARD2000_AdcPacerDisable             0x0030
+#define DAQBOARD2000_AdcPacerNormalMode          0x0060
+#define DAQBOARD2000_AdcPacerCompatibilityMode   0x0061
+#define DAQBOARD2000_AdcPacerInternalOutEnable   0x0008
+#define DAQBOARD2000_AdcPacerExternalRising      0x0100
+
+// DAC status
+#define DAQBOARD2000_DacFull                     0x0001
+#define DAQBOARD2000_RefBusy                     0x0002
+#define DAQBOARD2000_TrgBusy                     0x0004
+#define DAQBOARD2000_CalBusy                     0x0008
+#define DAQBOARD2000_Dac0Busy                    0x0010
+#define DAQBOARD2000_Dac1Busy                    0x0020
+#define DAQBOARD2000_Dac2Busy                    0x0040
+#define DAQBOARD2000_Dac3Busy                    0x0080
+
+// DAC control
+#define DAQBOARD2000_Dac0Enable                  0x0021
+#define DAQBOARD2000_Dac1Enable                  0x0031
+#define DAQBOARD2000_Dac2Enable                  0x0041
+#define DAQBOARD2000_Dac3Enable                  0x0051
+#define DAQBOARD2000_DacEnableBit                0x0001
+#define DAQBOARD2000_Dac0Disable                 0x0020
+#define DAQBOARD2000_Dac1Disable                 0x0030
+#define DAQBOARD2000_Dac2Disable                 0x0040
+#define DAQBOARD2000_Dac3Disable                 0x0050
+#define DAQBOARD2000_DacResetFifo                0x0004
+#define DAQBOARD2000_DacPatternDisable           0x0060
+#define DAQBOARD2000_DacPatternEnable            0x0061
+#define DAQBOARD2000_DacSelectSignedData         0x0002
+#define DAQBOARD2000_DacSelectUnsignedData       0x0000
+
+/* Trigger Control */
+#define DAQBOARD2000_TrigAnalog                  0x0000
+#define DAQBOARD2000_TrigTTL                     0x0010
+#define DAQBOARD2000_TrigTransHiLo               0x0004
+#define DAQBOARD2000_TrigTransLoHi               0x0000
+#define DAQBOARD2000_TrigAbove                   0x0000
+#define DAQBOARD2000_TrigBelow                   0x0004
+#define DAQBOARD2000_TrigLevelSense              0x0002
+#define DAQBOARD2000_TrigEdgeSense               0x0000
+#define DAQBOARD2000_TrigEnable                  0x0001
+#define DAQBOARD2000_TrigDisable                 0x0000
+
+// Reference Dac Selection
+#define DAQBOARD2000_PosRefDacSelect             0x0100
+#define DAQBOARD2000_NegRefDacSelect             0x0000
+
+static int daqboard2000_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int daqboard2000_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver_daqboard2000 = {
+      driver_name:"daqboard2000",
+      module:THIS_MODULE,
+      attach:daqboard2000_attach,
+      detach:daqboard2000_detach,
+};
+
+struct daq200_boardtype {
+	const char *name;
+	int id;
+};
+static const struct daq200_boardtype boardtypes[] = {
+	{"ids2", DAQBOARD2000_SUBSYSTEM_IDS2},
+	{"ids4", DAQBOARD2000_SUBSYSTEM_IDS4},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct daq200_boardtype))
+#define this_board ((const struct daq200_boardtype *)dev->board_ptr)
+
+static DEFINE_PCI_DEVICE_TABLE(daqboard2000_pci_table) = {
+	{0x1616, 0x0409, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, daqboard2000_pci_table);
+
+struct daqboard2000_private {
+	enum {
+		card_daqboard_2000
+	} card;
+	struct pci_dev *pci_dev;
+	void *daq;
+	void *plx;
+	int got_regions;
+	unsigned int ao_readback[2];
+};
+
+#define devpriv ((struct daqboard2000_private *)dev->private)
+
+static void writeAcqScanListEntry(struct comedi_device * dev, u16 entry)
+{
+	struct daqboard2000_hw *fpga = devpriv->daq;
+
+//  comedi_udelay(4);
+	fpga->acqScanListFIFO = entry & 0x00ff;
+//  comedi_udelay(4);
+	fpga->acqScanListFIFO = (entry >> 8) & 0x00ff;
+}
+
+static void setup_sampling(struct comedi_device * dev, int chan, int gain)
+{
+	u16 word0, word1, word2, word3;
+
+	/* Channel 0-7 diff, channel 8-23 single ended */
+	word0 = 0;
+	word1 = 0x0004;		/* Last scan */
+	word2 = (chan << 6) & 0x00c0;
+	switch (chan / 4) {
+	case 0:
+		word3 = 0x0001;
+		break;
+	case 1:
+		word3 = 0x0002;
+		break;
+	case 2:
+		word3 = 0x0005;
+		break;
+	case 3:
+		word3 = 0x0006;
+		break;
+	case 4:
+		word3 = 0x0041;
+		break;
+	case 5:
+		word3 = 0x0042;
+		break;
+	default:
+		word3 = 0;
+		break;
+	}
+/*
+  dev->eeprom.correctionDACSE[i][j][k].offset = 0x800;
+  dev->eeprom.correctionDACSE[i][j][k].gain = 0xc00;
+*/
+	/* These should be read from EEPROM */
+	word2 |= 0x0800;
+	word3 |= 0xc000;
+/*  printk("%d %4.4x %4.4x %4.4x %4.4x\n", chan, word0, word1, word2, word3);*/
+	writeAcqScanListEntry(dev, word0);
+	writeAcqScanListEntry(dev, word1);
+	writeAcqScanListEntry(dev, word2);
+	writeAcqScanListEntry(dev, word3);
+}
+
+static int daqboard2000_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	struct daqboard2000_hw *fpga = devpriv->daq;
+	int gain, chan, timeout;
+
+	fpga->acqControl =
+		DAQBOARD2000_AcqResetScanListFifo |
+		DAQBOARD2000_AcqResetResultsFifo |
+		DAQBOARD2000_AcqResetConfigPipe;
+
+	/* If pacer clock is not set to some high value (> 10 us), we
+	   risk multiple samples to be put into the result FIFO. */
+	fpga->acqPacerClockDivLow = 1000000;	/* 1 second, should be long enough */
+	fpga->acqPacerClockDivHigh = 0;
+
+	gain = CR_RANGE(insn->chanspec);
+	chan = CR_CHAN(insn->chanspec);
+
+	/* This doesn't look efficient.  I decided to take the conservative
+	 * approach when I did the insn conversion.  Perhaps it would be
+	 * better to have broken it completely, then someone would have been
+	 * forced to fix it.  --ds */
+	for (i = 0; i < insn->n; i++) {
+		setup_sampling(dev, chan, gain);
+		/* Enable reading from the scanlist FIFO */
+		fpga->acqControl = DAQBOARD2000_SeqStartScanList;
+		for (timeout = 0; timeout < 20; timeout++) {
+			if (fpga->acqControl & DAQBOARD2000_AcqConfigPipeFull) {
+				break;
+			}
+			//comedi_udelay(2);
+		}
+		fpga->acqControl = DAQBOARD2000_AdcPacerEnable;
+		for (timeout = 0; timeout < 20; timeout++) {
+			if (fpga->acqControl & DAQBOARD2000_AcqLogicScanning) {
+				break;
+			}
+			//comedi_udelay(2);
+		}
+		for (timeout = 0; timeout < 20; timeout++) {
+			if (fpga->
+				acqControl &
+				DAQBOARD2000_AcqResultsFIFOHasValidData) {
+				break;
+			}
+			//comedi_udelay(2);
+		}
+		data[i] = fpga->acqResultsFIFO;
+		fpga->acqControl = DAQBOARD2000_AdcPacerDisable;
+		fpga->acqControl = DAQBOARD2000_SeqStopScanList;
+	}
+
+	return i;
+}
+
+static int daqboard2000_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+
+	for (i = 0; i < insn->n; i++) {
+		data[i] = devpriv->ao_readback[chan];
+	}
+
+	return i;
+}
+
+static int daqboard2000_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+	struct daqboard2000_hw *fpga = devpriv->daq;
+	int timeout;
+
+	for (i = 0; i < insn->n; i++) {
+		/*
+		 * OK, since it works OK without enabling the DAC's, let's keep
+		 * it as simple as possible...
+		 */
+		//fpga->dacControl = (chan + 2) * 0x0010 | 0x0001; comedi_udelay(1000);
+		fpga->dacSetting[chan] = data[i];
+		for (timeout = 0; timeout < 20; timeout++) {
+			if ((fpga->dacControl & ((chan + 1) * 0x0010)) == 0) {
+				break;
+			}
+			//comedi_udelay(2);
+		}
+		devpriv->ao_readback[chan] = data[i];
+		/*
+		 * Since we never enabled the DAC's, we don't need to disable it...
+		 * fpga->dacControl = (chan + 2) * 0x0010 | 0x0000; comedi_udelay(1000);
+		 */
+	}
+
+	return i;
+}
+
+static void daqboard2000_resetLocalBus(struct comedi_device * dev)
+{
+	printk("daqboard2000_resetLocalBus\n");
+	writel(DAQBOARD2000_SECRLocalBusHi, devpriv->plx + 0x6c);
+	comedi_udelay(10000);
+	writel(DAQBOARD2000_SECRLocalBusLo, devpriv->plx + 0x6c);
+	comedi_udelay(10000);
+}
+
+static void daqboard2000_reloadPLX(struct comedi_device * dev)
+{
+	printk("daqboard2000_reloadPLX\n");
+	writel(DAQBOARD2000_SECRReloadLo, devpriv->plx + 0x6c);
+	comedi_udelay(10000);
+	writel(DAQBOARD2000_SECRReloadHi, devpriv->plx + 0x6c);
+	comedi_udelay(10000);
+	writel(DAQBOARD2000_SECRReloadLo, devpriv->plx + 0x6c);
+	comedi_udelay(10000);
+}
+
+static void daqboard2000_pulseProgPin(struct comedi_device * dev)
+{
+	printk("daqboard2000_pulseProgPin 1\n");
+	writel(DAQBOARD2000_SECRProgPinHi, devpriv->plx + 0x6c);
+	comedi_udelay(10000);
+	writel(DAQBOARD2000_SECRProgPinLo, devpriv->plx + 0x6c);
+	comedi_udelay(10000);	/* Not in the original code, but I like symmetry... */
+}
+
+static int daqboard2000_pollCPLD(struct comedi_device * dev, int mask)
+{
+	int result = 0;
+	int i;
+	int cpld;
+
+	/* timeout after 50 tries -> 5ms */
+	for (i = 0; i < 50; i++) {
+		cpld = readw(devpriv->daq + 0x1000);
+		if ((cpld & mask) == mask) {
+			result = 1;
+			break;
+		}
+		comedi_udelay(100);
+	}
+	comedi_udelay(5);
+	return result;
+}
+
+static int daqboard2000_writeCPLD(struct comedi_device * dev, int data)
+{
+	int result = 0;
+
+	comedi_udelay(10);
+	writew(data, devpriv->daq + 0x1000);
+	if ((readw(devpriv->daq + 0x1000) & DAQBOARD2000_CPLD_INIT) ==
+		DAQBOARD2000_CPLD_INIT) {
+		result = 1;
+	}
+	return result;
+}
+
+static int initialize_daqboard2000(struct comedi_device * dev,
+	unsigned char *cpld_array, int len)
+{
+	int result = -EIO;
+	/* Read the serial EEPROM control register */
+	int secr;
+	int retry;
+	int i;
+
+	/* Check to make sure the serial eeprom is present on the board */
+	secr = readl(devpriv->plx + 0x6c);
+	if (!(secr & DAQBOARD2000_EEPROM_PRESENT)) {
+#ifdef DEBUG_EEPROM
+		printk("no serial eeprom\n");
+#endif
+		return -EIO;
+	}
+
+	for (retry = 0; retry < 3; retry++) {
+#ifdef DEBUG_EEPROM
+		printk("Programming EEPROM try %x\n", retry);
+#endif
+
+		daqboard2000_resetLocalBus(dev);
+		daqboard2000_reloadPLX(dev);
+		daqboard2000_pulseProgPin(dev);
+		if (daqboard2000_pollCPLD(dev, DAQBOARD2000_CPLD_INIT)) {
+			for (i = 0; i < len; i++) {
+				if (cpld_array[i] == 0xff
+					&& cpld_array[i + 1] == 0x20) {
+#ifdef DEBUG_EEPROM
+					printk("Preamble found at %d\n", i);
+#endif
+					break;
+				}
+			}
+			for (; i < len; i += 2) {
+				int data =
+					(cpld_array[i] << 8) + cpld_array[i +
+					1];
+				if (!daqboard2000_writeCPLD(dev, data)) {
+					break;
+				}
+			}
+			if (i >= len) {
+#ifdef DEBUG_EEPROM
+				printk("Programmed\n");
+#endif
+				daqboard2000_resetLocalBus(dev);
+				daqboard2000_reloadPLX(dev);
+				result = 0;
+				break;
+			}
+		}
+	}
+	return result;
+}
+
+static void daqboard2000_adcStopDmaTransfer(struct comedi_device * dev)
+{
+/*  printk("Implement: daqboard2000_adcStopDmaTransfer\n");*/
+}
+
+static void daqboard2000_adcDisarm(struct comedi_device * dev)
+{
+	struct daqboard2000_hw *fpga = devpriv->daq;
+
+	/* Disable hardware triggers */
+	comedi_udelay(2);
+	fpga->trigControl = DAQBOARD2000_TrigAnalog | DAQBOARD2000_TrigDisable;
+	comedi_udelay(2);
+	fpga->trigControl = DAQBOARD2000_TrigTTL | DAQBOARD2000_TrigDisable;
+
+	/* Stop the scan list FIFO from loading the configuration pipe */
+	comedi_udelay(2);
+	fpga->acqControl = DAQBOARD2000_SeqStopScanList;
+
+	/* Stop the pacer clock */
+	comedi_udelay(2);
+	fpga->acqControl = DAQBOARD2000_AdcPacerDisable;
+
+	/* Stop the input dma (abort channel 1) */
+	daqboard2000_adcStopDmaTransfer(dev);
+}
+
+static void daqboard2000_activateReferenceDacs(struct comedi_device * dev)
+{
+	struct daqboard2000_hw *fpga = devpriv->daq;
+	int timeout;
+
+	// Set the + reference dac value in the FPGA
+	fpga->refDacs = 0x80 | DAQBOARD2000_PosRefDacSelect;
+	for (timeout = 0; timeout < 20; timeout++) {
+		if ((fpga->dacControl & DAQBOARD2000_RefBusy) == 0) {
+			break;
+		}
+		comedi_udelay(2);
+	}
+/*  printk("DAQBOARD2000_PosRefDacSelect %d\n", timeout);*/
+
+	// Set the - reference dac value in the FPGA
+	fpga->refDacs = 0x80 | DAQBOARD2000_NegRefDacSelect;
+	for (timeout = 0; timeout < 20; timeout++) {
+		if ((fpga->dacControl & DAQBOARD2000_RefBusy) == 0) {
+			break;
+		}
+		comedi_udelay(2);
+	}
+/*  printk("DAQBOARD2000_NegRefDacSelect %d\n", timeout);*/
+}
+
+static void daqboard2000_initializeCtrs(struct comedi_device * dev)
+{
+/*  printk("Implement: daqboard2000_initializeCtrs\n");*/
+}
+
+static void daqboard2000_initializeTmrs(struct comedi_device * dev)
+{
+/*  printk("Implement: daqboard2000_initializeTmrs\n");*/
+}
+
+static void daqboard2000_dacDisarm(struct comedi_device * dev)
+{
+/*  printk("Implement: daqboard2000_dacDisarm\n");*/
+}
+
+static void daqboard2000_initializeAdc(struct comedi_device * dev)
+{
+	daqboard2000_adcDisarm(dev);
+	daqboard2000_activateReferenceDacs(dev);
+	daqboard2000_initializeCtrs(dev);
+	daqboard2000_initializeTmrs(dev);
+}
+
+static void daqboard2000_initializeDac(struct comedi_device * dev)
+{
+	daqboard2000_dacDisarm(dev);
+}
+
+/*
+The test command, REMOVE!!:
+
+rmmod daqboard2000 ; rmmod comedi; make install ; modprobe daqboard2000; /usr/sbin/comedi_config /dev/comedi0 daqboard/2000 ; tail -40 /var/log/messages
+*/
+
+static int daqboard2000_8255_cb(int dir, int port, int data,
+	unsigned long ioaddr)
+{
+	int result = 0;
+	if (dir) {
+		writew(data, ((void *)ioaddr) + port * 2);
+		result = 0;
+	} else {
+		result = readw(((void *)ioaddr) + port * 2);
+	}
+/*
+  printk("daqboard2000_8255_cb %x %d %d %2.2x -> %2.2x\n",
+        arg, dir, port, data, result);
+*/
+	return result;
+}
+
+static int daqboard2000_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	int result = 0;
+	struct comedi_subdevice *s;
+	struct pci_dev *card = NULL;
+	void *aux_data;
+	unsigned int aux_len;
+	int bus, slot;
+
+	printk("comedi%d: daqboard2000:", dev->minor);
+
+	bus = it->options[0];
+	slot = it->options[1];
+
+	result = alloc_private(dev, sizeof(struct daqboard2000_private));
+	if (result < 0) {
+		return -ENOMEM;
+	}
+	for (card = pci_get_device(0x1616, 0x0409, NULL);
+		card != NULL;
+		card = pci_get_device(0x1616, 0x0409, card)) {
+		if (bus || slot) {
+			/* requested particular bus/slot */
+			if (card->bus->number != bus ||
+				PCI_SLOT(card->devfn) != slot) {
+				continue;
+			}
+		}
+		break;  /* found one */
+	}
+	if (!card) {
+		if (bus || slot)
+			printk(" no daqboard2000 found at bus/slot: %d/%d\n",
+				bus, slot);
+		else
+			printk(" no daqboard2000 found\n");
+		return -EIO;
+	} else {
+		u32 id;
+		int i;
+		devpriv->pci_dev = card;
+		id = ((u32) card->subsystem_device << 16) | card->
+			subsystem_vendor;
+		for (i = 0; i < n_boardtypes; i++) {
+			if (boardtypes[i].id == id) {
+				printk(" %s", boardtypes[i].name);
+				dev->board_ptr = boardtypes + i;
+			}
+		}
+		if (!dev->board_ptr) {
+			printk(" unknown subsystem id %08x (pretend it is an ids2)", id);
+			dev->board_ptr = boardtypes;
+		}
+	}
+
+	if ((result = comedi_pci_enable(card, "daqboard2000")) < 0) {
+		printk(" failed to enable PCI device and request regions\n");
+		return -EIO;
+	}
+	devpriv->got_regions = 1;
+	devpriv->plx =
+		ioremap(pci_resource_start(card, 0), DAQBOARD2000_PLX_SIZE);
+	devpriv->daq =
+		ioremap(pci_resource_start(card, 2), DAQBOARD2000_DAQ_SIZE);
+	if (!devpriv->plx || !devpriv->daq) {
+		return -ENOMEM;
+	}
+
+	result = alloc_subdevices(dev, 3);
+	if (result < 0)
+		goto out;
+
+	readl(devpriv->plx + 0x6c);
+
+	/*
+	   u8 interrupt;
+	   Windows code does restore interrupts, but since we don't use them...
+	   pci_read_config_byte(card, PCI_INTERRUPT_LINE, &interrupt);
+	   printk("Interrupt before is: %x\n", interrupt);
+	 */
+
+	aux_data = comedi_aux_data(it->options, 0);
+	aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH];
+
+	if (aux_data && aux_len) {
+		result = initialize_daqboard2000(dev, aux_data, aux_len);
+	} else {
+		printk("no FPGA initialization code, aborting\n");
+		result = -EIO;
+	}
+	if (result < 0)
+		goto out;
+	daqboard2000_initializeAdc(dev);
+	daqboard2000_initializeDac(dev);
+	/*
+	   Windows code does restore interrupts, but since we don't use them...
+	   pci_read_config_byte(card, PCI_INTERRUPT_LINE, &interrupt);
+	   printk("Interrupt after is: %x\n", interrupt);
+	 */
+
+	dev->iobase = (unsigned long)devpriv->daq;
+
+	dev->board_name = this_board->name;
+
+	s = dev->subdevices + 0;
+	/* ai subdevice */
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE | SDF_GROUND;
+	s->n_chan = 24;
+	s->maxdata = 0xffff;
+	s->insn_read = daqboard2000_ai_insn_read;
+	s->range_table = &range_daqboard2000_ai;
+
+	s = dev->subdevices + 1;
+	/* ao subdevice */
+	s->type = COMEDI_SUBD_AO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->n_chan = 2;
+	s->maxdata = 0xffff;
+	s->insn_read = daqboard2000_ao_insn_read;
+	s->insn_write = daqboard2000_ao_insn_write;
+	s->range_table = &range_daqboard2000_ao;
+
+	s = dev->subdevices + 2;
+	result = subdev_8255_init(dev, s, daqboard2000_8255_cb,
+		(unsigned long)(dev->iobase + 0x40));
+
+	printk("\n");
+      out:
+	return result;
+}
+
+static int daqboard2000_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: daqboard2000: remove\n", dev->minor);
+
+	if (dev->subdevices)
+		subdev_8255_cleanup(dev, dev->subdevices + 2);
+
+	if (dev->irq) {
+		free_irq(dev->irq, dev);
+	}
+	if (devpriv) {
+		if (devpriv->daq)
+			iounmap(devpriv->daq);
+		if (devpriv->plx)
+			iounmap(devpriv->plx);
+		if (devpriv->pci_dev) {
+			if (devpriv->got_regions) {
+				comedi_pci_disable(devpriv->pci_dev);
+			}
+			pci_dev_put(devpriv->pci_dev);
+		}
+	}
+	return 0;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_daqboard2000, daqboard2000_pci_table);
diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c
new file mode 100644
index 0000000..e456333
--- /dev/null
+++ b/drivers/staging/comedi/drivers/das08.c
@@ -0,0 +1,1068 @@
+/*
+    comedi/drivers/das08.c
+    DAS08 driver
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+    Copyright (C) 2001,2002,2003 Frank Mori Hess <fmhess@users.sourceforge.net>
+    Copyright (C) 2004 Salvador E. Tropea <set@users.sf.net> <set@ieee.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.
+
+    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.
+
+*****************************************************************
+
+*/
+/*
+Driver: das08
+Description: DAS-08 compatible boards
+Author: Warren Jasper, ds, Frank Hess
+Devices: [Keithley Metrabyte] DAS08 (isa-das08), [ComputerBoards] DAS08 (isa-das08),
+  DAS08-PGM (das08-pgm),
+  DAS08-PGH (das08-pgh), DAS08-PGL (das08-pgl), DAS08-AOH (das08-aoh),
+  DAS08-AOL (das08-aol), DAS08-AOM (das08-aom), DAS08/JR-AO (das08/jr-ao),
+  DAS08/JR-16-AO (das08jr-16-ao), PCI-DAS08 (das08),
+  PC104-DAS08 (pc104-das08), DAS08/JR/16 (das08jr/16)
+Status: works
+
+This is a rewrite of the das08 and das08jr drivers.
+
+Options (for ISA cards):
+        [0] - base io address
+
+Options (for pci-das08):
+        [0] - bus  (optional)
+        [1] = slot (optional)
+
+The das08 driver doesn't support asynchronous commands, since
+the cheap das08 hardware doesn't really support them.  The
+comedi_rt_timer driver can be used to emulate commands for this
+driver.
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+
+#include "comedi_pci.h"
+#include "8255.h"
+#include "das08.h"
+
+#define DRV_NAME "das08"
+
+#define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307
+#define PCI_DEVICE_ID_PCIDAS08 0x29
+#define PCIDAS08_SIZE 0x54
+
+// pci configuration registers
+#define INTCSR               0x4c
+#define   INTR1_ENABLE         0x1
+#define   INTR1_HIGH_POLARITY  0x2
+#define   PCI_INTR_ENABLE      0x40
+#define   INTR1_EDGE_TRIG      0x100	// requires high polarity
+#define CNTRL                0x50
+#define   CNTRL_DIR            0x2
+#define   CNTRL_INTR           0x4
+
+/*
+    cio-das08.pdf
+
+  "isa-das08"
+
+  0	a/d bits 0-3		start 8 bit
+  1	a/d bits 4-11		start 12 bit
+  2	eoc, ip1-3, irq, mux	op1-4, inte, mux
+  3	unused			unused
+  4567	8254
+  89ab	8255
+
+  requires hard-wiring for async ai
+
+*/
+
+#define DAS08_LSB		0
+#define DAS08_MSB		1
+#define DAS08_TRIG_12BIT	1
+#define DAS08_STATUS		2
+#define   DAS08_EOC			(1<<7)
+#define   DAS08_IRQ			(1<<3)
+#define   DAS08_IP(x)			(((x)>>4)&0x7)
+#define DAS08_CONTROL		2
+#define   DAS08_MUX_MASK	0x7
+#define   DAS08_MUX(x)		((x) & DAS08_MUX_MASK)
+#define   DAS08_INTE			(1<<3)
+#define   DAS08_DO_MASK		0xf0
+#define   DAS08_OP(x)		(((x) << 4) & DAS08_DO_MASK)
+
+/*
+    cio-das08jr.pdf
+
+  "das08/jr-ao"
+
+  0	a/d bits 0-3		unused
+  1	a/d bits 4-11		start 12 bit
+  2	eoc, mux		mux
+  3	di			do
+  4	unused			ao0_lsb
+  5	unused			ao0_msb
+  6	unused			ao1_lsb
+  7	unused			ao1_msb
+
+*/
+
+#define DAS08JR_DIO		3
+#define DAS08JR_AO_LSB(x)	((x)?6:4)
+#define DAS08JR_AO_MSB(x)	((x)?7:5)
+
+/*
+    cio-das08_aox.pdf
+
+  "das08-aoh"
+  "das08-aol"
+  "das08-aom"
+
+  0	a/d bits 0-3		start 8 bit
+  1	a/d bits 4-11		start 12 bit
+  2	eoc, ip1-3, irq, mux	op1-4, inte, mux
+  3	mux, gain status	gain control
+  4567	8254
+  8	unused			ao0_lsb
+  9	unused			ao0_msb
+  a	unused			ao1_lsb
+  b	unused			ao1_msb
+  89ab
+  cdef	8255
+*/
+
+#define DAS08AO_GAIN_CONTROL	3
+#define DAS08AO_GAIN_STATUS	3
+
+#define DAS08AO_AO_LSB(x)	((x)?0xa:8)
+#define DAS08AO_AO_MSB(x)	((x)?0xb:9)
+#define DAS08AO_AO_UPDATE	8
+
+/* gainlist same as _pgx_ below */
+
+static int das08_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int das08_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int das08_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int das08jr_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int das08jr_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int das08jr_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int das08ao_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static void i8254_set_mode_low(unsigned int base, int channel,
+	unsigned int mode);
+
+static const struct comedi_lrange range_das08_pgl = { 9, {
+			BIP_RANGE(10),
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+			BIP_RANGE(0.625),
+			UNI_RANGE(10),
+			UNI_RANGE(5),
+			UNI_RANGE(2.5),
+			UNI_RANGE(1.25)
+	}
+};
+static const struct comedi_lrange range_das08_pgh = { 12, {
+			BIP_RANGE(10),
+			BIP_RANGE(5),
+			BIP_RANGE(1),
+			BIP_RANGE(0.5),
+			BIP_RANGE(0.1),
+			BIP_RANGE(0.05),
+			BIP_RANGE(0.01),
+			BIP_RANGE(0.005),
+			UNI_RANGE(10),
+			UNI_RANGE(1),
+			UNI_RANGE(0.1),
+			UNI_RANGE(0.01),
+	}
+};
+static const struct comedi_lrange range_das08_pgm = { 9, {
+			BIP_RANGE(10),
+			BIP_RANGE(5),
+			BIP_RANGE(0.5),
+			BIP_RANGE(0.05),
+			BIP_RANGE(0.01),
+			UNI_RANGE(10),
+			UNI_RANGE(1),
+			UNI_RANGE(0.1),
+			UNI_RANGE(0.01)
+	}
+};				/*
+				   cio-das08jr.pdf
+
+				   "das08/jr-ao"
+
+				   0 a/d bits 0-3            unused
+				   1 a/d bits 4-11           start 12 bit
+				   2 eoc, mux                mux
+				   3 di                      do
+				   4 unused                  ao0_lsb
+				   5 unused                  ao0_msb
+				   6 unused                  ao1_lsb
+				   7 unused                  ao1_msb
+
+				 */
+
+static const struct comedi_lrange *const das08_ai_lranges[] = {
+	&range_unknown,
+	&range_bipolar5,
+	&range_das08_pgh,
+	&range_das08_pgl,
+	&range_das08_pgm,
+};
+
+static const int das08_pgh_gainlist[] =
+	{ 8, 0, 10, 2, 12, 4, 14, 6, 1, 3, 5, 7 };
+static const int das08_pgl_gainlist[] = { 8, 0, 2, 4, 6, 1, 3, 5, 7 };
+static const int das08_pgm_gainlist[] = { 8, 0, 10, 12, 14, 9, 11, 13, 15 };
+
+static const int *const das08_gainlists[] = {
+	NULL,
+	NULL,
+	das08_pgh_gainlist,
+	das08_pgl_gainlist,
+	das08_pgm_gainlist,
+};
+
+static const struct das08_board_struct das08_boards[] = {
+	{
+	      name:	"isa-das08",	// cio-das08.pdf
+	      bustype:	isa,
+	      ai:	das08_ai_rinsn,
+	      ai_nbits:12,
+	      ai_pg:	das08_pg_none,
+	      ai_encoding:das08_encode12,
+	      ao:	NULL,
+	      ao_nbits:12,
+	      di:	das08_di_rbits,
+	      do_:	das08_do_wbits,
+	      do_nchan:4,
+	      i8255_offset:8,
+	      i8254_offset:4,
+	      iosize:	16,	// unchecked
+		},
+	{
+	      name:	"das08-pgm",	// cio-das08pgx.pdf
+	      bustype:	isa,
+	      ai:	das08_ai_rinsn,
+	      ai_nbits:12,
+	      ai_pg:	das08_pgm,
+	      ai_encoding:das08_encode12,
+	      ao:	NULL,
+	      di:	das08_di_rbits,
+	      do_:	das08_do_wbits,
+	      do_nchan:4,
+	      i8255_offset:0,
+	      i8254_offset:0x04,
+	      iosize:	16,	// unchecked
+		},
+	{
+	      name:	"das08-pgh",	// cio-das08pgx.pdf
+	      bustype:	isa,
+	      ai:	das08_ai_rinsn,
+	      ai_nbits:12,
+	      ai_pg:	das08_pgh,
+	      ai_encoding:das08_encode12,
+	      ao:	NULL,
+	      di:	das08_di_rbits,
+	      do_:	das08_do_wbits,
+	      do_nchan:4,
+	      i8255_offset:0,
+	      i8254_offset:0x04,
+	      iosize:	16,	// unchecked
+		},
+	{
+	      name:	"das08-pgl",	// cio-das08pgx.pdf
+	      bustype:	isa,
+	      ai:	das08_ai_rinsn,
+	      ai_nbits:12,
+	      ai_pg:	das08_pgl,
+	      ai_encoding:das08_encode12,
+	      ao:	NULL,
+	      di:	das08_di_rbits,
+	      do_:	das08_do_wbits,
+	      do_nchan:4,
+	      i8255_offset:0,
+	      i8254_offset:0x04,
+	      iosize:	16,	// unchecked
+		},
+	{
+	      name:	"das08-aoh",	// cio-das08_aox.pdf
+	      bustype:	isa,
+	      ai:	das08_ai_rinsn,
+	      ai_nbits:12,
+	      ai_pg:	das08_pgh,
+	      ai_encoding:das08_encode12,
+	      ao:	das08ao_ao_winsn,	// 8
+	      ao_nbits:12,
+	      di:	das08_di_rbits,
+	      do_:	das08_do_wbits,
+	      do_nchan:4,
+	      i8255_offset:0x0c,
+	      i8254_offset:0x04,
+	      iosize:	16,	// unchecked
+		},
+	{
+	      name:	"das08-aol",	// cio-das08_aox.pdf
+	      bustype:	isa,
+	      ai:	das08_ai_rinsn,
+	      ai_nbits:12,
+	      ai_pg:	das08_pgl,
+	      ai_encoding:das08_encode12,
+	      ao:	das08ao_ao_winsn,	// 8
+	      ao_nbits:12,
+	      di:	das08_di_rbits,
+	      do_:	das08_do_wbits,
+	      do_nchan:4,
+	      i8255_offset:0x0c,
+	      i8254_offset:0x04,
+	      iosize:	16,	// unchecked
+		},
+	{
+	      name:	"das08-aom",	// cio-das08_aox.pdf
+	      bustype:	isa,
+	      ai:	das08_ai_rinsn,
+	      ai_nbits:12,
+	      ai_pg:	das08_pgm,
+	      ai_encoding:das08_encode12,
+	      ao:	das08ao_ao_winsn,	// 8
+	      ao_nbits:12,
+	      di:	das08_di_rbits,
+	      do_:	das08_do_wbits,
+	      do_nchan:4,
+	      i8255_offset:0x0c,
+	      i8254_offset:0x04,
+	      iosize:	16,	// unchecked
+		},
+	{
+	      name:	"das08/jr-ao",	// cio-das08-jr-ao.pdf
+	      bustype:	isa,
+	      ai:	das08_ai_rinsn,
+	      ai_nbits:12,
+	      ai_pg:	das08_pg_none,
+	      ai_encoding:das08_encode12,
+	      ao:	das08jr_ao_winsn,
+	      ao_nbits:12,
+	      di:	das08jr_di_rbits,
+	      do_:	das08jr_do_wbits,
+	      do_nchan:8,
+	      i8255_offset:0,
+	      i8254_offset:0,
+	      iosize:	16,	// unchecked
+		},
+	{
+	      name:	"das08jr-16-ao",	// cio-das08jr-16-ao.pdf
+	      bustype:	isa,
+	      ai:	das08_ai_rinsn,
+	      ai_nbits:16,
+	      ai_pg:	das08_pg_none,
+	      ai_encoding:das08_encode12,
+	      ao:	das08jr_ao_winsn,
+	      ao_nbits:16,
+	      di:	das08jr_di_rbits,
+	      do_:	das08jr_do_wbits,
+	      do_nchan:8,
+	      i8255_offset:0,
+	      i8254_offset:0x04,
+	      iosize:	16,	// unchecked
+		},
+#ifdef CONFIG_COMEDI_PCI
+	{
+	      name:	"das08",	// pci-das08
+	      id:	PCI_DEVICE_ID_PCIDAS08,
+	      bustype:	pci,
+	      ai:	das08_ai_rinsn,
+	      ai_nbits:12,
+	      ai_pg:	das08_bipolar5,
+	      ai_encoding:das08_encode12,
+	      ao:	NULL,
+	      ao_nbits:0,
+	      di:	das08_di_rbits,
+	      do_:	das08_do_wbits,
+	      do_nchan:4,
+	      i8255_offset:0,
+	      i8254_offset:4,
+	      iosize:	8,
+		},
+#endif
+	{
+	      name:	"pc104-das08",
+	      bustype:	pc104,
+	      ai:	das08_ai_rinsn,
+	      ai_nbits:12,
+	      ai_pg:	das08_pg_none,
+	      ai_encoding:das08_encode12,
+	      ao:	NULL,
+	      ao_nbits:0,
+	      di:	das08_di_rbits,
+	      do_:	das08_do_wbits,
+	      do_nchan:4,
+	      i8255_offset:0,
+	      i8254_offset:4,
+	      iosize:	16,	// unchecked
+		},
+#if 0
+	{
+	      name:	"das08/f",
+		},
+	{
+	      name:	"das08jr",
+		},
+#endif
+	{
+	      name:	"das08jr/16",
+	      bustype:	isa,
+	      ai:	das08_ai_rinsn,
+	      ai_nbits:16,
+	      ai_pg:	das08_pg_none,
+	      ai_encoding:das08_encode16,
+	      ao:	NULL,
+	      ao_nbits:0,
+	      di:	das08jr_di_rbits,
+	      do_:	das08jr_do_wbits,
+	      do_nchan:8,
+	      i8255_offset:0,
+	      i8254_offset:0,
+	      iosize:	16,	// unchecked
+		},
+#if 0
+	{
+	      name:	"das48-pga",	// cio-das48-pga.pdf
+		},
+	{
+	      name:	"das08-pga-g2",	// a KM board
+		},
+#endif
+};
+
+#ifdef CONFIG_COMEDI_PCMCIA
+struct das08_board_struct das08_cs_boards[NUM_DAS08_CS_BOARDS] = {
+	{
+	      name:	"pcm-das08",
+	      id:	0x0,	// XXX
+	      bustype:	pcmcia,
+	      ai:	das08_ai_rinsn,
+	      ai_nbits:12,
+	      ai_pg:	das08_bipolar5,
+	      ai_encoding:das08_pcm_encode12,
+	      ao:	NULL,
+	      ao_nbits:0,
+	      di:	das08_di_rbits,
+	      do_:	das08_do_wbits,
+	      do_nchan:3,
+	      i8255_offset:0,
+	      i8254_offset:0,
+	      iosize:	16,
+		},
+	// duplicate so driver name can be used also
+	{
+	      name:	"das08_cs",
+	      id:	0x0,	// XXX
+	      bustype:	pcmcia,
+	      ai:	das08_ai_rinsn,
+	      ai_nbits:12,
+	      ai_pg:	das08_bipolar5,
+	      ai_encoding:das08_pcm_encode12,
+	      ao:	NULL,
+	      ao_nbits:0,
+	      di:	das08_di_rbits,
+	      do_:	das08_do_wbits,
+	      do_nchan:3,
+	      i8255_offset:0,
+	      i8254_offset:0,
+	      iosize:	16,
+		},
+};
+#endif
+
+#ifdef CONFIG_COMEDI_PCI
+static DEFINE_PCI_DEVICE_TABLE(das08_pci_table) = {
+	{PCI_VENDOR_ID_COMPUTERBOARDS, PCI_DEVICE_ID_PCIDAS08, PCI_ANY_ID,
+		PCI_ANY_ID, 0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, das08_pci_table);
+#endif
+
+#define devpriv ((struct das08_private_struct *)dev->private)
+#define thisboard ((const struct das08_board_struct *)dev->board_ptr)
+
+#define TIMEOUT 100000
+
+static int das08_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i, n;
+	int chan;
+	int range;
+	int lsb, msb;
+
+	chan = CR_CHAN(insn->chanspec);
+	range = CR_RANGE(insn->chanspec);
+
+	/* clear crap */
+	inb(dev->iobase + DAS08_LSB);
+	inb(dev->iobase + DAS08_MSB);
+
+	/* set multiplexer */
+	spin_lock(&dev->spinlock);	// lock to prevent race with digital output
+	devpriv->do_mux_bits &= ~DAS08_MUX_MASK;
+	devpriv->do_mux_bits |= DAS08_MUX(chan);
+	outb(devpriv->do_mux_bits, dev->iobase + DAS08_CONTROL);
+	spin_unlock(&dev->spinlock);
+
+	if (s->range_table->length > 1) {
+		/* set gain/range */
+		range = CR_RANGE(insn->chanspec);
+		outb(devpriv->pg_gainlist[range],
+			dev->iobase + DAS08AO_GAIN_CONTROL);
+	}
+
+	for (n = 0; n < insn->n; n++) {
+		/* clear over-range bits for 16-bit boards */
+		if (thisboard->ai_nbits == 16)
+			if (inb(dev->iobase + DAS08_MSB) & 0x80)
+				rt_printk("das08: over-range\n");
+
+		/* trigger conversion */
+		outb_p(0, dev->iobase + DAS08_TRIG_12BIT);
+
+		for (i = 0; i < TIMEOUT; i++) {
+			if (!(inb(dev->iobase + DAS08_STATUS) & DAS08_EOC))
+				break;
+		}
+		if (i == TIMEOUT) {
+			rt_printk("das08: timeout\n");
+			return -ETIME;
+		}
+		msb = inb(dev->iobase + DAS08_MSB);
+		lsb = inb(dev->iobase + DAS08_LSB);
+		if (thisboard->ai_encoding == das08_encode12) {
+			data[n] = (lsb >> 4) | (msb << 4);
+		} else if (thisboard->ai_encoding == das08_pcm_encode12) {
+			data[n] = (msb << 8) + lsb;
+		} else if (thisboard->ai_encoding == das08_encode16) {
+			/* FPOS 16-bit boards are sign-magnitude */
+			if (msb & 0x80)
+				data[n] = (1 << 15) | lsb | ((msb & 0x7f) << 8);
+			else
+				data[n] = (1 << 15) - (lsb | (msb & 0x7f) << 8);
+		} else {
+			comedi_error(dev, "bug! unknown ai encoding");
+			return -1;
+		}
+	}
+
+	return n;
+}
+
+static int das08_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	data[0] = 0;
+	data[1] = DAS08_IP(inb(dev->iobase + DAS08_STATUS));
+
+	return 2;
+}
+
+static int das08_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int wbits;
+
+	// get current settings of digital output lines
+	wbits = (devpriv->do_mux_bits >> 4) & 0xf;
+	// null bits we are going to set
+	wbits &= ~data[0];
+	// set new bit values
+	wbits |= data[0] & data[1];
+	// remember digital output bits
+	spin_lock(&dev->spinlock);	// prevent race with setting of analog input mux
+	devpriv->do_mux_bits &= ~DAS08_DO_MASK;
+	devpriv->do_mux_bits |= DAS08_OP(wbits);
+	outb(devpriv->do_mux_bits, dev->iobase + DAS08_CONTROL);
+	spin_unlock(&dev->spinlock);
+
+	data[1] = wbits;
+
+	return 2;
+}
+
+static int das08jr_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	data[0] = 0;
+	data[1] = inb(dev->iobase + DAS08JR_DIO);
+
+	return 2;
+}
+
+static int das08jr_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	// null bits we are going to set
+	devpriv->do_bits &= ~data[0];
+	// set new bit values
+	devpriv->do_bits |= data[0] & data[1];
+	outb(devpriv->do_bits, dev->iobase + DAS08JR_DIO);
+
+	data[1] = devpriv->do_bits;
+
+	return 2;
+}
+
+static int das08jr_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n;
+	int lsb, msb;
+	int chan;
+
+	lsb = data[0] & 0xff;
+	msb = (data[0] >> 8) & 0xf;
+
+	chan = CR_CHAN(insn->chanspec);
+
+	for (n = 0; n < insn->n; n++) {
+#if 0
+		outb(lsb, dev->iobase + devpriv->ao_offset_lsb[chan]);
+		outb(msb, dev->iobase + devpriv->ao_offset_msb[chan]);
+#else
+		outb(lsb, dev->iobase + DAS08JR_AO_LSB(chan));
+		outb(msb, dev->iobase + DAS08JR_AO_MSB(chan));
+#endif
+
+		/* load DACs */
+		inb(dev->iobase + DAS08JR_DIO);
+	}
+
+	return n;
+}
+
+/*
+ *
+ * The -aox boards have the DACs at a different offset and use
+ * a different method to force an update.
+ *
+ */
+static int das08ao_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n;
+	int lsb, msb;
+	int chan;
+
+	lsb = data[0] & 0xff;
+	msb = (data[0] >> 8) & 0xf;
+
+	chan = CR_CHAN(insn->chanspec);
+
+	for (n = 0; n < insn->n; n++) {
+#if 0
+		outb(lsb, dev->iobase + devpriv->ao_offset_lsb[chan]);
+		outb(msb, dev->iobase + devpriv->ao_offset_msb[chan]);
+#else
+		outb(lsb, dev->iobase + DAS08AO_AO_LSB(chan));
+		outb(msb, dev->iobase + DAS08AO_AO_MSB(chan));
+#endif
+
+		/* load DACs */
+		inb(dev->iobase + DAS08AO_AO_UPDATE);
+	}
+
+	return n;
+}
+
+static unsigned int i8254_read_channel_low(unsigned int base, int chan)
+{
+	unsigned int msb, lsb;
+
+	/* The following instructions must be in order.
+	   We must avoid other process reading the counter's value in the
+	   middle.
+	   The spin_lock isn't needed since ioctl calls grab the big kernel
+	   lock automatically */
+	/*spin_lock(sp); */
+	outb(chan << 6, base + I8254_CTRL);
+	base += chan;
+	lsb = inb(base);
+	msb = inb(base);
+	/*spin_unlock(sp); */
+
+	return lsb | (msb << 8);
+}
+
+static void i8254_write_channel_low(unsigned int base, int chan,
+	unsigned int value)
+{
+	unsigned int msb, lsb;
+
+	lsb = value & 0xFF;
+	msb = value >> 8;
+
+	/* write lsb, then msb */
+	base += chan;
+	/* See comments in i8254_read_channel_low */
+	/*spin_lock(sp); */
+	outb(lsb, base);
+	outb(msb, base);
+	/*spin_unlock(sp); */
+}
+
+static unsigned int i8254_read_channel(struct i8254_struct *st, int channel)
+{
+	int chan = st->logic2phys[channel];
+
+	return i8254_read_channel_low(st->iobase, chan);
+}
+
+static void i8254_write_channel(struct i8254_struct *st, int channel,
+	unsigned int value)
+{
+	int chan = st->logic2phys[channel];
+
+	i8254_write_channel_low(st->iobase, chan, value);
+}
+
+static void i8254_initialize(struct i8254_struct *st)
+{
+	int i;
+	for (i = 0; i < 3; ++i)
+		i8254_set_mode_low(st->iobase, i, st->mode[i]);
+}
+
+static void i8254_set_mode_low(unsigned int base, int channel,
+	unsigned int mode)
+{
+	outb((channel << 6) | 0x30 | (mode & 0x0F), base + I8254_CTRL);
+}
+
+static void i8254_set_mode(struct i8254_struct *st, int channel,
+	unsigned int mode)
+{
+	int chan = st->logic2phys[channel];
+
+	st->mode[chan] = mode;
+	return i8254_set_mode_low(st->iobase, chan, mode);
+}
+
+static unsigned int i8254_read_status_low(unsigned int base, int channel)
+{
+	outb(0xE0 | (2 << channel), base + I8254_CTRL);
+	return inb(base + channel);
+}
+
+static unsigned int i8254_read_status(struct i8254_struct *st, int channel)
+{
+	int chan = st->logic2phys[channel];
+
+	return i8254_read_status_low(st->iobase, chan);
+}
+
+static int das08_counter_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int chan = insn->chanspec;
+
+	//printk("Reading counter channel %d ",chan);
+	data[0] = i8254_read_channel(&devpriv->i8254, chan);
+	//printk("=> 0x%08X\n",data[0]);
+
+	return 1;
+}
+
+static int das08_counter_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int chan = insn->chanspec;
+
+	//printk("Writing counter channel %d with 0x%04X\n",chan,data[0]);
+	i8254_write_channel(&devpriv->i8254, chan, data[0]);
+
+	return 1;
+}
+
+static int das08_counter_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int chan = insn->chanspec;
+
+	if (insn->n != 2)
+		return -EINVAL;
+
+	switch (data[0]) {
+	case INSN_CONFIG_SET_COUNTER_MODE:
+		i8254_set_mode(&devpriv->i8254, chan, data[1]);
+		break;
+	case INSN_CONFIG_8254_READ_STATUS:
+		data[1] = i8254_read_status(&devpriv->i8254, chan);
+		break;
+	default:
+		return -EINVAL;
+		break;
+	}
+	return 2;
+}
+
+static int das08_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+
+static struct comedi_driver driver_das08 = {
+      driver_name: DRV_NAME,
+      module:THIS_MODULE,
+      attach:das08_attach,
+      detach:das08_common_detach,
+      board_name:&das08_boards[0].name,
+      num_names:sizeof(das08_boards) /
+		sizeof(struct das08_board_struct),
+      offset:sizeof(struct das08_board_struct),
+};
+
+int das08_common_attach(struct comedi_device * dev, unsigned long iobase)
+{
+	struct comedi_subdevice *s;
+	int ret;
+
+	// allocate ioports for non-pcmcia, non-pci boards
+	if ((thisboard->bustype != pcmcia) && (thisboard->bustype != pci)) {
+		printk(" iobase 0x%lx\n", iobase);
+		if (!request_region(iobase, thisboard->iosize, DRV_NAME)) {
+			printk(" I/O port conflict\n");
+			return -EIO;
+		}
+	}
+	dev->iobase = iobase;
+
+	dev->board_name = thisboard->name;
+
+	if ((ret = alloc_subdevices(dev, 6)) < 0)
+		return ret;
+
+	s = dev->subdevices + 0;
+	/* ai */
+	if (thisboard->ai) {
+		s->type = COMEDI_SUBD_AI;
+		/* XXX some boards actually have differential inputs instead of single ended.
+		 *  The driver does nothing with arefs though, so it's no big deal. */
+		s->subdev_flags = SDF_READABLE | SDF_GROUND;
+		s->n_chan = 8;
+		s->maxdata = (1 << thisboard->ai_nbits) - 1;
+		s->range_table = das08_ai_lranges[thisboard->ai_pg];
+		s->insn_read = thisboard->ai;
+		devpriv->pg_gainlist = das08_gainlists[thisboard->ai_pg];
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	s = dev->subdevices + 1;
+	/* ao */
+	if (thisboard->ao) {
+		s->type = COMEDI_SUBD_AO;
+// XXX lacks read-back insn
+		s->subdev_flags = SDF_WRITABLE;
+		s->n_chan = 2;
+		s->maxdata = (1 << thisboard->ao_nbits) - 1;
+		s->range_table = &range_bipolar5;
+		s->insn_write = thisboard->ao;
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	s = dev->subdevices + 2;
+	/* di */
+	if (thisboard->di) {
+		s->type = COMEDI_SUBD_DI;
+		s->subdev_flags = SDF_READABLE;
+		s->n_chan = (thisboard->di == das08_di_rbits) ? 3 : 8;
+		s->maxdata = 1;
+		s->range_table = &range_digital;
+		s->insn_bits = thisboard->di;
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	s = dev->subdevices + 3;
+	/* do */
+	if (thisboard->do_) {
+		s->type = COMEDI_SUBD_DO;
+		s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+		s->n_chan = thisboard->do_nchan;
+		s->maxdata = 1;
+		s->range_table = &range_digital;
+		s->insn_bits = thisboard->do_;
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	s = dev->subdevices + 4;
+	/* 8255 */
+	if (thisboard->i8255_offset != 0) {
+		subdev_8255_init(dev, s, NULL, (unsigned long)(dev->iobase +
+				thisboard->i8255_offset));
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	s = dev->subdevices + 5;
+	/* 8254 */
+	if (thisboard->i8254_offset != 0) {
+		s->type = COMEDI_SUBD_COUNTER;
+		s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+		s->n_chan = 3;
+		s->maxdata = 0xFFFF;
+		s->insn_read = das08_counter_read;
+		s->insn_write = das08_counter_write;
+		s->insn_config = das08_counter_config;
+		/* Set-up the 8254 structure */
+		devpriv->i8254.channels = 3;
+		devpriv->i8254.logic2phys[0] = 0;
+		devpriv->i8254.logic2phys[1] = 1;
+		devpriv->i8254.logic2phys[2] = 2;
+		devpriv->i8254.iobase = iobase + thisboard->i8254_offset;
+		devpriv->i8254.mode[0] =
+			devpriv->i8254.mode[1] =
+			devpriv->i8254.mode[2] = I8254_MODE0 | I8254_BINARY;
+		i8254_initialize(&devpriv->i8254);
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	return 0;
+}
+
+static int das08_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	int ret;
+	unsigned long iobase;
+#ifdef CONFIG_COMEDI_PCI
+	unsigned long pci_iobase = 0;
+	struct pci_dev *pdev;
+#endif
+
+	if ((ret = alloc_private(dev, sizeof(struct das08_private_struct))) < 0)
+		return ret;
+
+	printk("comedi%d: das08: ", dev->minor);
+	// deal with a pci board
+	if (thisboard->bustype == pci) {
+#ifdef CONFIG_COMEDI_PCI
+		if (it->options[0] || it->options[1]) {
+			printk("bus %i slot %i ",
+				it->options[0], it->options[1]);
+		}
+		printk("\n");
+		// find card
+		for (pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+			pdev != NULL;
+			pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) {
+			if (pdev->vendor == PCI_VENDOR_ID_COMPUTERBOARDS
+				&& pdev->device == PCI_DEVICE_ID_PCIDAS08) {
+				if (it->options[0] || it->options[1]) {
+					if (pdev->bus->number == it->options[0]
+						&& PCI_SLOT(pdev->devfn) ==
+						it->options[1]) {
+						break;
+					}
+				} else {
+					break;
+				}
+			}
+		}
+		if (!pdev) {
+			printk("No pci das08 cards found\n");
+			return -EIO;
+		}
+		devpriv->pdev = pdev;
+		// enable PCI device and reserve I/O spaces
+		if (comedi_pci_enable(pdev, DRV_NAME)) {
+			printk(" Error enabling PCI device and requesting regions\n");
+			return -EIO;
+		}
+		// read base addresses
+		pci_iobase = pci_resource_start(pdev, 1);
+		iobase = pci_resource_start(pdev, 2);
+		printk("pcibase 0x%lx  iobase 0x%lx\n", pci_iobase, iobase);
+		devpriv->pci_iobase = pci_iobase;
+#if 0
+/* We could enable to pci-das08's interrupt here to make it possible
+ * to do timed input in this driver, but there is little point since
+ * conversions would have to be started by the interrupt handler
+ * so you might as well use comedi_rt_timer to emulate commands
+ */
+		/* set source of interrupt trigger to counter2 output */
+		outb(CNTRL_INTR | CNTRL_DIR, pci_iobase + CNTRL);
+		/* Enable local interrupt 1 and pci interrupt */
+		outw(INTR1_ENABLE | PCI_INTR_ENABLE, pci_iobase + INTCSR);
+#endif
+#else	/* CONFIG_COMEDI_PCI */
+		printk("this driver has not been built with PCI support.\n");
+		return -EINVAL;
+#endif	/* CONFIG_COMEDI_PCI */
+	} else {
+		iobase = it->options[0];
+	}
+	printk("\n");
+
+	return das08_common_attach(dev, iobase);
+}
+
+int das08_common_detach(struct comedi_device * dev)
+{
+	printk(KERN_INFO "comedi%d: das08: remove\n", dev->minor);
+
+	if (dev->subdevices)
+		subdev_8255_cleanup(dev, dev->subdevices + 4);
+
+	// deallocate ioports for non-pcmcia, non-pci boards
+	if ((thisboard->bustype != pcmcia) && (thisboard->bustype != pci)) {
+		if (dev->iobase)
+			release_region(dev->iobase, thisboard->iosize);
+	}
+
+#ifdef CONFIG_COMEDI_PCI
+	if (devpriv) {
+		if (devpriv->pdev) {
+			if (devpriv->pci_iobase) {
+				comedi_pci_disable(devpriv->pdev);
+			}
+			pci_dev_put(devpriv->pdev);
+		}
+	}
+#endif
+
+	return 0;
+}
+
+#ifdef CONFIG_COMEDI_PCI
+COMEDI_PCI_INITCLEANUP(driver_das08, das08_pci_table);
+#else
+COMEDI_INITCLEANUP(driver_das08);
+#endif
+
+EXPORT_SYMBOL_GPL(das08_common_attach);
+EXPORT_SYMBOL_GPL(das08_common_detach);
+#ifdef CONFIG_COMEDI_PCMCIA
+EXPORT_SYMBOL_GPL(das08_cs_boards);
+#endif
diff --git a/drivers/staging/comedi/drivers/das08.h b/drivers/staging/comedi/drivers/das08.h
new file mode 100644
index 0000000..69089ce
--- /dev/null
+++ b/drivers/staging/comedi/drivers/das08.h
@@ -0,0 +1,78 @@
+/*
+    das08.h
+
+    Header for das08.c and das08_cs.c
+
+    Copyright (C) 2003 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+    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.
+
+*/
+
+#ifndef _DAS08_H
+#define _DAS08_H
+
+enum das08_bustype { isa, pci, pcmcia, pc104 };
+// different ways ai data is encoded in first two registers
+enum das08_ai_encoding { das08_encode12, das08_encode16, das08_pcm_encode12 };
+enum das08_lrange { das08_pg_none, das08_bipolar5, das08_pgh, das08_pgl,
+		das08_pgm };
+
+struct das08_board_struct {
+	const char *name;
+	unsigned int id;	// id for pci/pcmcia boards
+	enum das08_bustype bustype;
+	void *ai;
+	unsigned int ai_nbits;
+	enum das08_lrange ai_pg;
+	enum das08_ai_encoding ai_encoding;
+	void *ao;
+	unsigned int ao_nbits;
+	void *di;
+	void *do_;
+	unsigned int do_nchan;
+	unsigned int i8255_offset;
+	unsigned int i8254_offset;
+	unsigned int iosize;	// number of ioports used
+};
+
+struct i8254_struct {
+	int channels;		// available channels. Some could be used internally.
+	int logic2phys[3];	// to know which physical channel is.
+	int mode[3];		// the index is the real counter.
+	unsigned int iobase;
+};
+
+#define I8254_CNT0 0
+#define I8254_CNT1 1
+#define I8254_CNT2 2
+#define I8254_CTRL 3
+
+struct das08_private_struct {
+	unsigned int do_mux_bits;	// bits for do/mux register on boards without seperate do register
+	unsigned int do_bits;	// bits for do register on boards with register dedicated to digital out only
+	const unsigned int *pg_gainlist;
+	struct pci_dev *pdev;	// struct for pci-das08
+	unsigned int pci_iobase;	// additional base address for pci-das08
+	struct i8254_struct i8254;
+};
+
+#define NUM_DAS08_CS_BOARDS 2
+extern struct das08_board_struct das08_cs_boards[NUM_DAS08_CS_BOARDS];
+
+int das08_common_attach(struct comedi_device * dev, unsigned long iobase);
+int das08_common_detach(struct comedi_device * dev);
+
+#endif /* _DAS08_H */
diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c
new file mode 100644
index 0000000..be6c8878
--- /dev/null
+++ b/drivers/staging/comedi/drivers/das08_cs.c
@@ -0,0 +1,488 @@
+/*
+    comedi/drivers/das08_cs.c
+    DAS08 driver
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+    Copyright (C) 2001,2002,2003 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+    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.
+
+*****************************************************************
+
+*/
+/*
+Driver: das08_cs
+Description: DAS-08 PCMCIA boards
+Author: Warren Jasper, ds, Frank Hess
+Devices: [ComputerBoards] PCM-DAS08 (pcm-das08)
+Status: works
+
+This is the PCMCIA-specific support split off from the
+das08 driver.
+
+Options (for pcm-das08):
+        NONE
+
+Command support does not exist, but could be added for this board.
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+#include <linux/pci.h>
+
+#include "das08.h"
+
+// pcmcia includes
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+
+static struct pcmcia_device *cur_dev = NULL;
+
+#define thisboard ((const struct das08_board_struct *)dev->board_ptr)
+
+static int das08_cs_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+
+static struct comedi_driver driver_das08_cs = {
+      driver_name:"das08_cs",
+      module:THIS_MODULE,
+      attach:das08_cs_attach,
+      detach:das08_common_detach,
+      board_name:&das08_cs_boards[0].name,
+      num_names:sizeof(das08_cs_boards) /
+		sizeof(struct das08_board_struct),
+      offset:sizeof(struct das08_board_struct),
+};
+
+static int das08_cs_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	int ret;
+	unsigned long iobase;
+	struct pcmcia_device *link = cur_dev;	// XXX hack
+
+	if ((ret = alloc_private(dev, sizeof(struct das08_private_struct))) < 0)
+		return ret;
+
+	printk("comedi%d: das08_cs: ", dev->minor);
+	// deal with a pci board
+
+	if (thisboard->bustype == pcmcia) {
+		if (link == NULL) {
+			printk(" no pcmcia cards found\n");
+			return -EIO;
+		}
+		iobase = link->io.BasePort1;
+	} else {
+		printk(" bug! board does not have PCMCIA bustype\n");
+		return -EINVAL;
+	}
+
+	printk("\n");
+
+	return das08_common_attach(dev, iobase);
+}
+
+/*======================================================================
+
+    The following pcmcia code for the pcm-das08 is adapted from the
+    dummy_cs.c driver of the Linux PCMCIA Card Services package.
+
+    The initial developer of the original code is David A. Hinds
+    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
+    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
+
+======================================================================*/
+
+/*
+   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
+   you do not define PCMCIA_DEBUG at all, all the debug code will be
+   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
+   be present but disabled -- but it can then be enabled for specific
+   modules at load time with a 'pc_debug=#' option to insmod.
+*/
+
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+module_param(pc_debug, int, 0644);
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+static const char *version =
+	"das08.c pcmcia code (Frank Hess), modified from dummy_cs.c 1.31 2001/08/24 12:13:13 (David Hinds)";
+#else
+#define DEBUG(n, args...)
+#endif
+
+/*====================================================================*/
+static void das08_pcmcia_config(struct pcmcia_device *link);
+static void das08_pcmcia_release(struct pcmcia_device *link);
+static int das08_pcmcia_suspend(struct pcmcia_device *p_dev);
+static int das08_pcmcia_resume(struct pcmcia_device *p_dev);
+
+/*
+   The attach() and detach() entry points are used to create and destroy
+   "instances" of the driver, where each instance represents everything
+   needed to manage one actual PCMCIA card.
+*/
+
+static int das08_pcmcia_attach(struct pcmcia_device *);
+static void das08_pcmcia_detach(struct pcmcia_device *);
+
+/*
+   You'll also need to prototype all the functions that will actually
+   be used to talk to your device.  See 'memory_cs' for a good example
+   of a fully self-sufficient driver; the other drivers rely more or
+   less on other parts of the kernel.
+*/
+
+/*
+   The dev_info variable is the "key" that is used to match up this
+   device driver with appropriate cards, through the card configuration
+   database.
+*/
+
+static const dev_info_t dev_info = "pcm-das08";
+
+struct local_info_t {
+	struct pcmcia_device *link;
+	dev_node_t node;
+	int stop;
+	struct bus_operations *bus;
+};
+
+/*======================================================================
+
+    das08_pcmcia_attach() creates an "instance" of the driver, allocating
+    local data structures for one device.  The device is registered
+    with Card Services.
+
+    The dev_link structure is initialized, but we don't actually
+    configure the card at this point -- we wait until we receive a
+    card insertion event.
+
+======================================================================*/
+
+static int das08_pcmcia_attach(struct pcmcia_device *link)
+{
+	struct local_info_t *local;
+
+	DEBUG(0, "das08_pcmcia_attach()\n");
+
+	/* Allocate space for private device-specific data */
+	local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
+	if (!local)
+		return -ENOMEM;
+	local->link = link;
+	link->priv = local;
+
+	/* Interrupt setup */
+	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+	link->irq.Handler = NULL;
+
+	/*
+	   General socket configuration defaults can go here.  In this
+	   client, we assume very little, and rely on the CIS for almost
+	   everything.  In most clients, many details (i.e., number, sizes,
+	   and attributes of IO windows) are fixed by the nature of the
+	   device, and can be hard-wired here.
+	 */
+	link->conf.Attributes = 0;
+	link->conf.IntType = INT_MEMORY_AND_IO;
+
+	cur_dev = link;
+
+	das08_pcmcia_config(link);
+
+	return 0;
+}				/* das08_pcmcia_attach */
+
+/*======================================================================
+
+    This deletes a driver "instance".  The device is de-registered
+    with Card Services.  If it has been released, all local data
+    structures are freed.  Otherwise, the structures will be freed
+    when the device is released.
+
+======================================================================*/
+
+static void das08_pcmcia_detach(struct pcmcia_device *link)
+{
+
+	DEBUG(0, "das08_pcmcia_detach(0x%p)\n", link);
+
+	if (link->dev_node) {
+		((struct local_info_t *) link->priv)->stop = 1;
+		das08_pcmcia_release(link);
+	}
+
+	/* This points to the parent struct local_info_t struct */
+	if (link->priv)
+		kfree(link->priv);
+
+}				/* das08_pcmcia_detach */
+
+/*======================================================================
+
+    das08_pcmcia_config() is scheduled to run after a CARD_INSERTION event
+    is received, to configure the PCMCIA socket, and to make the
+    device available to the system.
+
+======================================================================*/
+
+static void das08_pcmcia_config(struct pcmcia_device *link)
+{
+	struct local_info_t *dev = link->priv;
+	tuple_t tuple;
+	cisparse_t parse;
+	int last_fn, last_ret;
+	u_char buf[64];
+	cistpl_cftable_entry_t dflt = { 0 };
+
+	DEBUG(0, "das08_pcmcia_config(0x%p)\n", link);
+
+	/*
+	   This reads the card's CONFIG tuple to find its configuration
+	   registers.
+	 */
+	tuple.DesiredTuple = CISTPL_CONFIG;
+	tuple.Attributes = 0;
+	tuple.TupleData = buf;
+	tuple.TupleDataMax = sizeof(buf);
+	tuple.TupleOffset = 0;
+	last_fn = GetFirstTuple;
+	if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0)
+		goto cs_failed;
+	last_fn = GetTupleData;
+	if ((last_ret = pcmcia_get_tuple_data(link, &tuple)) != 0)
+		goto cs_failed;
+	last_fn = ParseTuple;
+	if ((last_ret = pcmcia_parse_tuple(&tuple, &parse)) != 0)
+		goto cs_failed;
+	link->conf.ConfigBase = parse.config.base;
+	link->conf.Present = parse.config.rmask[0];
+
+	/*
+	   In this loop, we scan the CIS for configuration table entries,
+	   each of which describes a valid card configuration, including
+	   voltage, IO window, memory window, and interrupt settings.
+
+	   We make no assumptions about the card to be configured: we use
+	   just the information available in the CIS.  In an ideal world,
+	   this would work for any PCMCIA card, but it requires a complete
+	   and accurate CIS.  In practice, a driver usually "knows" most of
+	   these things without consulting the CIS, and most client drivers
+	   will only use the CIS to fill in implementation-defined details.
+	 */
+	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+	last_fn = GetFirstTuple;
+	if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0)
+		goto cs_failed;
+	while (1) {
+		cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+		if ((last_ret = pcmcia_get_tuple_data(link, &tuple)) != 0)
+			goto next_entry;
+		if ((last_ret = pcmcia_parse_tuple(&tuple, &parse)) != 0)
+			goto next_entry;
+
+		if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+			dflt = *cfg;
+		if (cfg->index == 0)
+			goto next_entry;
+		link->conf.ConfigIndex = cfg->index;
+
+		/* Does this card need audio output? */
+/*	if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+		link->conf.Attributes |= CONF_ENABLE_SPKR;
+		link->conf.Status = CCSR_AUDIO_ENA;
+	}
+*/
+		/* Do we need to allocate an interrupt? */
+		if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
+			link->conf.Attributes |= CONF_ENABLE_IRQ;
+
+		/* IO window settings */
+		link->io.NumPorts1 = link->io.NumPorts2 = 0;
+		if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+			cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+			link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+			if (!(io->flags & CISTPL_IO_8BIT))
+				link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+			if (!(io->flags & CISTPL_IO_16BIT))
+				link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+			link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+			link->io.BasePort1 = io->win[0].base;
+			link->io.NumPorts1 = io->win[0].len;
+			if (io->nwin > 1) {
+				link->io.Attributes2 = link->io.Attributes1;
+				link->io.BasePort2 = io->win[1].base;
+				link->io.NumPorts2 = io->win[1].len;
+			}
+			/* This reserves IO space but doesn't actually enable it */
+			if (pcmcia_request_io(link, &link->io) != 0)
+				goto next_entry;
+		}
+
+		/* If we got this far, we're cool! */
+		break;
+
+	      next_entry:
+		last_fn = GetNextTuple;
+		if ((last_ret = pcmcia_get_next_tuple(link, &tuple)) != 0)
+			goto cs_failed;
+	}
+
+	if (link->conf.Attributes & CONF_ENABLE_IRQ) {
+		last_fn = RequestIRQ;
+		if ((last_ret = pcmcia_request_irq(link, &link->irq)) != 0)
+			goto cs_failed;
+	}
+
+	/*
+	   This actually configures the PCMCIA socket -- setting up
+	   the I/O windows and the interrupt mapping, and putting the
+	   card and host interface into "Memory and IO" mode.
+	 */
+	last_fn = RequestConfiguration;
+	if ((last_ret = pcmcia_request_configuration(link, &link->conf)) != 0)
+		goto cs_failed;
+
+	/*
+	   At this point, the dev_node_t structure(s) need to be
+	   initialized and arranged in a linked list at link->dev.
+	 */
+	sprintf(dev->node.dev_name, "pcm-das08");
+	dev->node.major = dev->node.minor = 0;
+	link->dev_node = &dev->node;
+
+	/* Finally, report what we've done */
+	printk(KERN_INFO "%s: index 0x%02x",
+		dev->node.dev_name, link->conf.ConfigIndex);
+	if (link->conf.Attributes & CONF_ENABLE_IRQ)
+		printk(", irq %u", link->irq.AssignedIRQ);
+	if (link->io.NumPorts1)
+		printk(", io 0x%04x-0x%04x", link->io.BasePort1,
+			link->io.BasePort1 + link->io.NumPorts1 - 1);
+	if (link->io.NumPorts2)
+		printk(" & 0x%04x-0x%04x", link->io.BasePort2,
+			link->io.BasePort2 + link->io.NumPorts2 - 1);
+	printk("\n");
+
+	return;
+
+      cs_failed:
+	cs_error(link, last_fn, last_ret);
+	das08_pcmcia_release(link);
+
+}				/* das08_pcmcia_config */
+
+/*======================================================================
+
+    After a card is removed, das08_pcmcia_release() will unregister the
+    device, and release the PCMCIA configuration.  If the device is
+    still open, this will be postponed until it is closed.
+
+======================================================================*/
+
+static void das08_pcmcia_release(struct pcmcia_device *link)
+{
+	DEBUG(0, "das08_pcmcia_release(0x%p)\n", link);
+	pcmcia_disable_device(link);
+}				/* das08_pcmcia_release */
+
+/*======================================================================
+
+    The card status event handler.  Mostly, this schedules other
+    stuff to run after an event is received.
+
+    When a CARD_REMOVAL event is received, we immediately set a
+    private flag to block future accesses to this device.  All the
+    functions that actually access the device should check this flag
+    to make sure the card is still present.
+
+======================================================================*/
+
+static int das08_pcmcia_suspend(struct pcmcia_device *link)
+{
+	struct local_info_t *local = link->priv;
+	/* Mark the device as stopped, to block IO until later */
+	local->stop = 1;
+
+	return 0;
+}				/* das08_pcmcia_suspend */
+
+static int das08_pcmcia_resume(struct pcmcia_device *link)
+{
+	struct local_info_t *local = link->priv;
+
+	local->stop = 0;
+	return 0;
+}				/* das08_pcmcia_resume */
+
+/*====================================================================*/
+
+static struct pcmcia_device_id das08_cs_id_table[] = {
+	PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x4001),
+	PCMCIA_DEVICE_NULL
+};
+
+MODULE_DEVICE_TABLE(pcmcia, das08_cs_id_table);
+
+struct pcmcia_driver das08_cs_driver = {
+	.probe = das08_pcmcia_attach,
+	.remove = das08_pcmcia_detach,
+	.suspend = das08_pcmcia_suspend,
+	.resume = das08_pcmcia_resume,
+	.id_table = das08_cs_id_table,
+	.owner = THIS_MODULE,
+	.drv = {
+			.name = dev_info,
+		},
+};
+
+static int __init init_das08_pcmcia_cs(void)
+{
+	DEBUG(0, "%s\n", version);
+	pcmcia_register_driver(&das08_cs_driver);
+	return 0;
+}
+
+static void __exit exit_das08_pcmcia_cs(void)
+{
+	DEBUG(0, "das08_pcmcia_cs: unloading\n");
+	pcmcia_unregister_driver(&das08_cs_driver);
+}
+
+static int __init das08_cs_init_module(void)
+{
+	int ret;
+
+	ret = init_das08_pcmcia_cs();
+	if (ret < 0)
+		return ret;
+
+	return comedi_driver_register(&driver_das08_cs);
+}
+
+static void __exit das08_cs_exit_module(void)
+{
+	exit_das08_pcmcia_cs();
+	comedi_driver_unregister(&driver_das08_cs);
+}
+
+MODULE_LICENSE("GPL");
+module_init(das08_cs_init_module);
+module_exit(das08_cs_exit_module);
diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c
new file mode 100644
index 0000000..6b6b042
--- /dev/null
+++ b/drivers/staging/comedi/drivers/das16.c
@@ -0,0 +1,1730 @@
+/*
+    comedi/drivers/das16.c
+    DAS16 driver
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+    Copyright (C) 2000 Chris R. Baugher <baugher@enteract.com>
+    Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+    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.
+
+************************************************************************
+*/
+/*
+Driver: das16
+Description: DAS16 compatible boards
+Author: Sam Moore, Warren Jasper, ds, Chris Baugher, Frank Hess, Roman Fietze
+Devices: [Keithley Metrabyte] DAS-16 (das-16), DAS-16G (das-16g),
+  DAS-16F (das-16f), DAS-1201 (das-1201), DAS-1202 (das-1202),
+  DAS-1401 (das-1401), DAS-1402 (das-1402), DAS-1601 (das-1601),
+  DAS-1602 (das-1602),
+  [ComputerBoards] PC104-DAS16/JR (pc104-das16jr),
+  PC104-DAS16JR/16 (pc104-das16jr/16),
+  CIO-DAS16JR/16 (cio-das16jr/16),
+  CIO-DAS16/JR (cio-das16/jr), CIO-DAS1401/12 (cio-das1401/12),
+  CIO-DAS1402/12 (cio-das1402/12), CIO-DAS1402/16 (cio-das1402/16),
+  CIO-DAS1601/12 (cio-das1601/12), CIO-DAS1602/12 (cio-das1602/12),
+  CIO-DAS1602/16 (cio-das1602/16), CIO-DAS16/330 (cio-das16/330)
+Status: works
+Updated: 2003-10-12
+
+A rewrite of the das16 and das1600 drivers.
+Options:
+	[0] - base io address
+	[1] - irq (does nothing, irq is not used anymore)
+	[2] - dma (optional, required for comedi_command support)
+	[3] - master clock speed in MHz (optional, 1 or 10, ignored if
+		board can probe clock, defaults to 1)
+	[4] - analog input range lowest voltage in microvolts (optional,
+		only useful if your board does not have software
+		programmable gain)
+	[5] - analog input range highest voltage in microvolts (optional,
+		only useful if board does not have software programmable
+		gain)
+	[6] - analog output range lowest voltage in microvolts (optional)
+	[7] - analog output range highest voltage in microvolts (optional)
+	[8] - use timer mode for DMA.  Timer mode is needed e.g. for
+		buggy DMA controllers in NS CS5530A (Geode Companion), and for
+		'jr' cards that lack a hardware fifo.  This option is no
+		longer needed, since timer mode is _always_ used.
+
+Passing a zero for an option is the same as leaving it unspecified.
+
+*/
+/*
+
+Testing and debugging help provided by Daniel Koch.
+
+Keithley Manuals:
+	2309.PDF (das16)
+	4919.PDF (das1400, 1600)
+	4922.PDF (das-1400)
+	4923.PDF (das1200, 1400, 1600)
+
+Computer boards manuals also available from their website www.measurementcomputing.com
+
+*/
+
+#include <linux/pci.h>
+#include <asm/dma.h>
+#include "../comedidev.h"
+
+#include "8253.h"
+#include "8255.h"
+#include "comedi_fc.h"
+
+#undef DEBUG
+//#define DEBUG
+
+#ifdef DEBUG
+#define DEBUG_PRINT(format, args...) rt_printk("das16: " format, ## args)
+#else
+#define DEBUG_PRINT(format, args...)
+#endif
+
+#define DAS16_SIZE 20		// number of ioports
+#define DAS16_DMA_SIZE 0xff00	// size in bytes of allocated dma buffer
+
+/*
+    cio-das16.pdf
+
+    "das16"
+    "das16/f"
+
+  0	a/d bits 0-3		start 12 bit
+  1	a/d bits 4-11		unused
+  2	mux read		mux set
+  3	di 4 bit		do 4 bit
+  4	unused			ao0_lsb
+  5	unused			ao0_msb
+  6	unused			ao1_lsb
+  7	unused			ao1_msb
+  8	status eoc uni/bip	interrupt reset
+  9	dma, int, trig ctrl	set dma, int
+  a	pacer control		unused
+  b	reserved		reserved
+  cdef	8254
+  0123	8255
+
+*/
+
+/*
+    cio-das16jr.pdf
+
+    "das16jr"
+
+  0	a/d bits 0-3		start 12 bit
+  1	a/d bits 4-11		unused
+  2	mux read		mux set
+  3	di 4 bit		do 4 bit
+  4567	unused			unused
+  8	status eoc uni/bip	interrupt reset
+  9	dma, int, trig ctrl	set dma, int
+  a	pacer control		unused
+  b	gain status		gain control
+  cdef	8254
+
+*/
+
+/*
+    cio-das16jr_16.pdf
+
+    "das16jr_16"
+
+  0	a/d bits 0-7		start 16 bit
+  1	a/d bits 8-15		unused
+  2	mux read		mux set
+  3	di 4 bit		do 4 bit
+  4567	unused			unused
+  8	status eoc uni/bip	interrupt reset
+  9	dma, int, trig ctrl	set dma, int
+  a	pacer control		unused
+  b	gain status		gain control
+  cdef	8254
+
+*/
+/*
+    cio-das160x-1x.pdf
+
+    "das1601/12"
+    "das1602/12"
+    "das1602/16"
+
+  0	a/d bits 0-3		start 12 bit
+  1	a/d bits 4-11		unused
+  2	mux read		mux set
+  3	di 4 bit		do 4 bit
+  4	unused			ao0_lsb
+  5	unused			ao0_msb
+  6	unused			ao1_lsb
+  7	unused			ao1_msb
+  8	status eoc uni/bip	interrupt reset
+  9	dma, int, trig ctrl	set dma, int
+  a	pacer control		unused
+  b	gain status		gain control
+  cdef	8254
+  400	8255
+  404	unused			conversion enable
+  405	unused			burst enable
+  406	unused			das1600 enable
+  407	status
+
+*/
+
+static const int sample_size = 2;	// size in bytes of a sample from board
+
+#define DAS16_TRIG		0
+#define DAS16_AI_LSB		0
+#define DAS16_AI_MSB		1
+#define DAS16_MUX		2
+#define DAS16_DIO		3
+#define DAS16_AO_LSB(x)	((x)?6:4)
+#define DAS16_AO_MSB(x)	((x)?7:5)
+#define DAS16_STATUS		8
+#define   BUSY			(1<<7)
+#define   UNIPOLAR			(1<<6)
+#define   DAS16_MUXBIT			(1<<5)
+#define   DAS16_INT			(1<<4)
+#define DAS16_CONTROL		9
+#define   DAS16_INTE			(1<<7)
+#define   DAS16_IRQ(x)			(((x) & 0x7) << 4)
+#define   DMA_ENABLE			(1<<2)
+#define   PACING_MASK	0x3
+#define   INT_PACER		0x03
+#define   EXT_PACER			0x02
+#define   DAS16_SOFT		0x00
+#define DAS16_PACER		0x0A
+#define   DAS16_CTR0			(1<<1)
+#define   DAS16_TRIG0			(1<<0)
+#define   BURST_LEN_BITS(x)			(((x) & 0xf) << 4)
+#define DAS16_GAIN		0x0B
+#define DAS16_CNTR0_DATA		0x0C
+#define DAS16_CNTR1_DATA		0x0D
+#define DAS16_CNTR2_DATA		0x0E
+#define DAS16_CNTR_CONTROL	0x0F
+#define   DAS16_TERM_CNT	0x00
+#define   DAS16_ONE_SHOT	0x02
+#define   DAS16_RATE_GEN	0x04
+#define   DAS16_CNTR_LSB_MSB	0x30
+#define   DAS16_CNTR0		0x00
+#define   DAS16_CNTR1		0x40
+#define   DAS16_CNTR2		0x80
+
+#define DAS1600_CONV		0x404
+#define   DAS1600_CONV_DISABLE		0x40
+#define DAS1600_BURST		0x405
+#define   DAS1600_BURST_VAL		0x40
+#define DAS1600_ENABLE		0x406
+#define   DAS1600_ENABLE_VAL		0x40
+#define DAS1600_STATUS_B	0x407
+#define   DAS1600_BME		0x40
+#define   DAS1600_ME		0x20
+#define   DAS1600_CD			0x10
+#define   DAS1600_WS			0x02
+#define   DAS1600_CLK_10MHZ		0x01
+
+static const struct comedi_lrange range_das1x01_bip = { 4, {
+			BIP_RANGE(10),
+			BIP_RANGE(1),
+			BIP_RANGE(0.1),
+			BIP_RANGE(0.01),
+	}
+};
+static const struct comedi_lrange range_das1x01_unip = { 4, {
+			UNI_RANGE(10),
+			UNI_RANGE(1),
+			UNI_RANGE(0.1),
+			UNI_RANGE(0.01),
+	}
+};
+static const struct comedi_lrange range_das1x02_bip = { 4, {
+			BIP_RANGE(10),
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+	}
+};
+static const struct comedi_lrange range_das1x02_unip = { 4, {
+			UNI_RANGE(10),
+			UNI_RANGE(5),
+			UNI_RANGE(2.5),
+			UNI_RANGE(1.25),
+	}
+};
+static const struct comedi_lrange range_das16jr = { 9, {
+			// also used by 16/330
+			BIP_RANGE(10),
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+			BIP_RANGE(0.625),
+			UNI_RANGE(10),
+			UNI_RANGE(5),
+			UNI_RANGE(2.5),
+			UNI_RANGE(1.25),
+	}
+};
+static const struct comedi_lrange range_das16jr_16 = { 8, {
+			BIP_RANGE(10),
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+			UNI_RANGE(10),
+			UNI_RANGE(5),
+			UNI_RANGE(2.5),
+			UNI_RANGE(1.25),
+	}
+};
+
+static const int das16jr_gainlist[] = { 8, 0, 1, 2, 3, 4, 5, 6, 7 };
+static const int das16jr_16_gainlist[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
+static const int das1600_gainlist[] = { 0, 1, 2, 3 };
+enum {
+	das16_pg_none = 0,
+	das16_pg_16jr,
+	das16_pg_16jr_16,
+	das16_pg_1601,
+	das16_pg_1602,
+};
+static const int *const das16_gainlists[] = {
+	NULL,
+	das16jr_gainlist,
+	das16jr_16_gainlist,
+	das1600_gainlist,
+	das1600_gainlist,
+};
+static const struct comedi_lrange *const das16_ai_uni_lranges[] = {
+	&range_unknown,
+	&range_das16jr,
+	&range_das16jr_16,
+	&range_das1x01_unip,
+	&range_das1x02_unip,
+};
+static const struct comedi_lrange *const das16_ai_bip_lranges[] = {
+	&range_unknown,
+	&range_das16jr,
+	&range_das16jr_16,
+	&range_das1x01_bip,
+	&range_das1x02_bip,
+};
+
+struct munge_info {
+	uint8_t byte;
+	unsigned have_byte:1;
+};
+
+static int das16_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int das16_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int das16_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int das16_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+static int das16_cmd_test(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd);
+static int das16_cmd_exec(struct comedi_device * dev, struct comedi_subdevice * s);
+static int das16_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void das16_ai_munge(struct comedi_device * dev, struct comedi_subdevice * s,
+	void *array, unsigned int num_bytes, unsigned int start_chan_index);
+
+static void das16_reset(struct comedi_device * dev);
+static irqreturn_t das16_dma_interrupt(int irq, void *d PT_REGS_ARG);
+static void das16_timer_interrupt(unsigned long arg);
+static void das16_interrupt(struct comedi_device * dev);
+
+static unsigned int das16_set_pacer(struct comedi_device * dev, unsigned int ns,
+	int flags);
+static int das1600_mode_detect(struct comedi_device * dev);
+static unsigned int das16_suggest_transfer_size(struct comedi_device * dev,
+	struct comedi_cmd cmd);
+
+static void reg_dump(struct comedi_device * dev);
+
+struct das16_board {
+	const char *name;
+	void *ai;
+	unsigned int ai_nbits;
+	unsigned int ai_speed;	// max conversion speed in nanosec
+	unsigned int ai_pg;
+	void *ao;
+	unsigned int ao_nbits;
+	void *di;
+	void *do_;
+
+	unsigned int i8255_offset;
+	unsigned int i8254_offset;
+
+	unsigned int size;
+	unsigned int id;
+};
+
+static const struct das16_board das16_boards[] = {
+	{
+	      name:	"das-16",
+	      ai:	das16_ai_rinsn,
+	      ai_nbits:12,
+	      ai_speed:15000,
+	      ai_pg:	das16_pg_none,
+	      ao:	das16_ao_winsn,
+	      ao_nbits:12,
+	      di:	das16_di_rbits,
+	      do_:	das16_do_wbits,
+	      i8255_offset:0x10,
+	      i8254_offset:0x0c,
+	      size:	0x14,
+	      id:	0x00,
+		},
+	{
+	      name:	"das-16g",
+	      ai:	das16_ai_rinsn,
+	      ai_nbits:12,
+	      ai_speed:15000,
+	      ai_pg:	das16_pg_none,
+	      ao:	das16_ao_winsn,
+	      ao_nbits:12,
+	      di:	das16_di_rbits,
+	      do_:	das16_do_wbits,
+	      i8255_offset:0x10,
+	      i8254_offset:0x0c,
+	      size:	0x14,
+	      id:	0x00,
+		},
+	{
+	      name:	"das-16f",
+	      ai:	das16_ai_rinsn,
+	      ai_nbits:12,
+	      ai_speed:8500,
+	      ai_pg:	das16_pg_none,
+	      ao:	das16_ao_winsn,
+	      ao_nbits:12,
+	      di:	das16_di_rbits,
+	      do_:	das16_do_wbits,
+	      i8255_offset:0x10,
+	      i8254_offset:0x0c,
+	      size:	0x14,
+	      id:	0x00,
+		},
+	{
+	      name:	"cio-das16",	// cio-das16.pdf
+	      ai:	das16_ai_rinsn,
+	      ai_nbits:12,
+	      ai_speed:20000,
+	      ai_pg:	das16_pg_none,
+	      ao:	das16_ao_winsn,
+	      ao_nbits:12,
+	      di:	das16_di_rbits,
+	      do_:	das16_do_wbits,
+	      i8255_offset:0x10,
+	      i8254_offset:0x0c,
+	      size:	0x14,
+	      id:	0x80,
+		},
+	{
+	      name:	"cio-das16/f",	// das16.pdf
+	      ai:	das16_ai_rinsn,
+	      ai_nbits:12,
+	      ai_speed:10000,
+	      ai_pg:	das16_pg_none,
+	      ao:	das16_ao_winsn,
+	      ao_nbits:12,
+	      di:	das16_di_rbits,
+	      do_:	das16_do_wbits,
+	      i8255_offset:0x10,
+	      i8254_offset:0x0c,
+	      size:	0x14,
+	      id:	0x80,
+		},
+	{
+	      name:	"cio-das16/jr",	// cio-das16jr.pdf
+	      ai:	das16_ai_rinsn,
+	      ai_nbits:12,
+	      ai_speed:7692,
+	      ai_pg:	das16_pg_16jr,
+	      ao:	NULL,
+	      di:	das16_di_rbits,
+	      do_:	das16_do_wbits,
+	      i8255_offset:0,
+	      i8254_offset:0x0c,
+	      size:	0x10,
+	      id:	0x00,
+		},
+	{
+	      name:	"pc104-das16jr",	// pc104-das16jr_xx.pdf
+	      ai:	das16_ai_rinsn,
+	      ai_nbits:12,
+	      ai_speed:3300,
+	      ai_pg:	das16_pg_16jr,
+	      ao:	NULL,
+	      di:	das16_di_rbits,
+	      do_:	das16_do_wbits,
+	      i8255_offset:0,
+	      i8254_offset:0x0c,
+	      size:	0x10,
+	      id:	0x00,
+		},
+	{
+	      name:	"cio-das16jr/16",	// cio-das16jr_16.pdf
+	      ai:	das16_ai_rinsn,
+	      ai_nbits:16,
+	      ai_speed:10000,
+	      ai_pg:	das16_pg_16jr_16,
+	      ao:	NULL,
+	      di:	das16_di_rbits,
+	      do_:	das16_do_wbits,
+	      i8255_offset:0,
+	      i8254_offset:0x0c,
+	      size:	0x10,
+	      id:	0x00,
+		},
+	{
+	      name:	"pc104-das16jr/16",	// pc104-das16jr_xx.pdf
+	      ai:	das16_ai_rinsn,
+	      ai_nbits:16,
+	      ai_speed:10000,
+	      ai_pg:	das16_pg_16jr_16,
+	      ao:	NULL,
+	      di:	das16_di_rbits,
+	      do_:	das16_do_wbits,
+	      i8255_offset:0,
+	      i8254_offset:0x0c,
+	      size:	0x10,
+	      id:	0x00,
+		},
+	{
+	      name:	"das-1201",	// 4924.pdf (keithley user's manual)
+	      ai:	das16_ai_rinsn,
+	      ai_nbits:12,
+	      ai_speed:20000,
+	      ai_pg:	das16_pg_none,
+	      ao:	NULL,
+	      di:	das16_di_rbits,
+	      do_:	das16_do_wbits,
+	      i8255_offset:0x400,
+	      i8254_offset:0x0c,
+	      size:	0x408,
+	      id:	0x20,
+		},
+	{
+	      name:	"das-1202",	// 4924.pdf (keithley user's manual)
+	      ai:	das16_ai_rinsn,
+	      ai_nbits:12,
+	      ai_speed:10000,
+	      ai_pg:	das16_pg_none,
+	      ao:	NULL,
+	      di:	das16_di_rbits,
+	      do_:	das16_do_wbits,
+	      i8255_offset:0x400,
+	      i8254_offset:0x0c,
+	      size:	0x408,
+	      id:	0x20,
+		},
+	{
+	      name:	"das-1401",	// 4919.pdf and 4922.pdf (keithley user's manual)
+	      ai:	das16_ai_rinsn,
+	      ai_nbits:12,
+	      ai_speed:10000,
+	      ai_pg:	das16_pg_1601,
+	      ao:	NULL,
+	      di:	das16_di_rbits,
+	      do_:	das16_do_wbits,
+	      i8255_offset:0x0,
+	      i8254_offset:0x0c,
+	      size:	0x408,
+	      id:	0xc0	// 4919.pdf says id bits are 0xe0, 4922.pdf says 0xc0
+		},
+	{
+	      name:	"das-1402",	// 4919.pdf and 4922.pdf (keithley user's manual)
+	      ai:	das16_ai_rinsn,
+	      ai_nbits:12,
+	      ai_speed:10000,
+	      ai_pg:	das16_pg_1602,
+	      ao:	NULL,
+	      di:	das16_di_rbits,
+	      do_:	das16_do_wbits,
+	      i8255_offset:0x0,
+	      i8254_offset:0x0c,
+	      size:	0x408,
+	      id:	0xc0	// 4919.pdf says id bits are 0xe0, 4922.pdf says 0xc0
+		},
+	{
+	      name:	"das-1601",	// 4919.pdf
+	      ai:	das16_ai_rinsn,
+	      ai_nbits:12,
+	      ai_speed:10000,
+	      ai_pg:	das16_pg_1601,
+	      ao:	das16_ao_winsn,
+	      ao_nbits:12,
+	      di:	das16_di_rbits,
+	      do_:	das16_do_wbits,
+	      i8255_offset:0x400,
+	      i8254_offset:0x0c,
+	      size:	0x408,
+      id:	0xc0},
+	{
+	      name:	"das-1602",	// 4919.pdf
+	      ai:	das16_ai_rinsn,
+	      ai_nbits:12,
+	      ai_speed:10000,
+	      ai_pg:	das16_pg_1602,
+	      ao:	das16_ao_winsn,
+	      ao_nbits:12,
+	      di:	das16_di_rbits,
+	      do_:	das16_do_wbits,
+	      i8255_offset:0x400,
+	      i8254_offset:0x0c,
+	      size:	0x408,
+      id:	0xc0},
+	{
+	      name:	"cio-das1401/12",	// cio-das1400_series.pdf
+	      ai:	das16_ai_rinsn,
+	      ai_nbits:12,
+	      ai_speed:6250,
+	      ai_pg:	das16_pg_1601,
+	      ao:	NULL,
+	      di:	das16_di_rbits,
+	      do_:	das16_do_wbits,
+	      i8255_offset:0,
+	      i8254_offset:0x0c,
+	      size:	0x408,
+      id:	0xc0},
+	{
+	      name:	"cio-das1402/12",	// cio-das1400_series.pdf
+	      ai:	das16_ai_rinsn,
+	      ai_nbits:12,
+	      ai_speed:6250,
+	      ai_pg:	das16_pg_1602,
+	      ao:	NULL,
+	      di:	das16_di_rbits,
+	      do_:	das16_do_wbits,
+	      i8255_offset:0,
+	      i8254_offset:0x0c,
+	      size:	0x408,
+      id:	0xc0},
+	{
+	      name:	"cio-das1402/16",	// cio-das1400_series.pdf
+	      ai:	das16_ai_rinsn,
+	      ai_nbits:16,
+	      ai_speed:10000,
+	      ai_pg:	das16_pg_1602,
+	      ao:	NULL,
+	      di:	das16_di_rbits,
+	      do_:	das16_do_wbits,
+	      i8255_offset:0,
+	      i8254_offset:0x0c,
+	      size:	0x408,
+      id:	0xc0},
+	{
+	      name:	"cio-das1601/12",	// cio-das160x-1x.pdf
+	      ai:	das16_ai_rinsn,
+	      ai_nbits:12,
+	      ai_speed:6250,
+	      ai_pg:	das16_pg_1601,
+	      ao:	das16_ao_winsn,
+	      ao_nbits:12,
+	      di:	das16_di_rbits,
+	      do_:	das16_do_wbits,
+	      i8255_offset:0x400,
+	      i8254_offset:0x0c,
+	      size:	0x408,
+      id:	0xc0},
+	{
+	      name:	"cio-das1602/12",	// cio-das160x-1x.pdf
+	      ai:	das16_ai_rinsn,
+	      ai_nbits:12,
+	      ai_speed:10000,
+	      ai_pg:	das16_pg_1602,
+	      ao:	das16_ao_winsn,
+	      ao_nbits:12,
+	      di:	das16_di_rbits,
+	      do_:	das16_do_wbits,
+	      i8255_offset:0x400,
+	      i8254_offset:0x0c,
+	      size:	0x408,
+      id:	0xc0},
+	{
+	      name:	"cio-das1602/16",	// cio-das160x-1x.pdf
+	      ai:	das16_ai_rinsn,
+	      ai_nbits:16,
+	      ai_speed:10000,
+	      ai_pg:	das16_pg_1602,
+	      ao:	das16_ao_winsn,
+	      ao_nbits:12,
+	      di:	das16_di_rbits,
+	      do_:	das16_do_wbits,
+	      i8255_offset:0x400,
+	      i8254_offset:0x0c,
+	      size:	0x408,
+      id:	0xc0},
+	{
+	      name:	"cio-das16/330",	// ?
+	      ai:	das16_ai_rinsn,
+	      ai_nbits:12,
+	      ai_speed:3030,
+	      ai_pg:	das16_pg_16jr,
+	      ao:	NULL,
+	      di:	das16_di_rbits,
+	      do_:	das16_do_wbits,
+	      i8255_offset:0,
+	      i8254_offset:0x0c,
+	      size:	0x14,
+      id:	0xf0},
+#if 0
+	{
+	      name:	"das16/330i",	// ?
+		},
+	{
+	      name:	"das16/jr/ctr5",	// ?
+		},
+	{
+	      name:	"cio-das16/m1/16",	// cio-das16_m1_16.pdf, this board is a bit quirky, no dma
+		},
+#endif
+};
+
+#define n_das16_boards ((sizeof(das16_boards))/(sizeof(struct das16_board)))
+
+static int das16_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int das16_detach(struct comedi_device * dev);
+static struct comedi_driver driver_das16 = {
+      driver_name:"das16",
+      module:THIS_MODULE,
+      attach:das16_attach,
+      detach:das16_detach,
+      board_name:&das16_boards[0].name,
+      num_names:n_das16_boards,
+      offset:sizeof(das16_boards[0]),
+};
+
+#define DAS16_TIMEOUT 1000
+
+/* Period for timer interrupt in jiffies.  It's a function
+ * to deal with possibility of dynamic HZ patches  */
+static inline int timer_period(void)
+{
+	return HZ / 20;
+}
+struct das16_private_struct {
+	unsigned int ai_unipolar;	// unipolar flag
+	unsigned int ai_singleended;	// single ended flag
+	unsigned int clockbase;	// master clock speed in ns
+	volatile unsigned int control_state;	// dma, interrupt and trigger control bits
+	volatile unsigned long adc_byte_count;	// number of bytes remaining
+	unsigned int divisor1;	// divisor dividing master clock to get conversion frequency
+	unsigned int divisor2;	// divisor dividing master clock to get conversion frequency
+	unsigned int dma_chan;	// dma channel
+	uint16_t *dma_buffer[2];
+	dma_addr_t dma_buffer_addr[2];
+	unsigned int current_buffer;
+	volatile unsigned int dma_transfer_size;	// target number of bytes to transfer per dma shot
+	// user-defined analog input and output ranges defined from config options
+	struct comedi_lrange *user_ai_range_table;
+	struct comedi_lrange *user_ao_range_table;
+
+	struct timer_list timer;	// for timed interrupt
+	volatile short timer_running;
+	volatile short timer_mode;	// true if using timer mode
+};
+#define devpriv ((struct das16_private_struct *)(dev->private))
+#define thisboard ((struct das16_board *)(dev->board_ptr))
+
+static int das16_cmd_test(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0, tmp;
+	int gain, start_chan, i;
+	int mask;
+
+	/* make sure triggers are valid */
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	mask = TRIG_FOLLOW;
+	// if board supports burst mode
+	if (thisboard->size > 0x400)
+		mask |= TRIG_TIMER | TRIG_EXT;
+	cmd->scan_begin_src &= mask;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	mask = TRIG_TIMER | TRIG_EXT;
+	// if board supports burst mode
+	if (thisboard->size > 0x400)
+		mask |= TRIG_NOW;
+	cmd->convert_src &= mask;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+	if (cmd->scan_begin_src != TRIG_TIMER &&
+		cmd->scan_begin_src != TRIG_EXT &&
+		cmd->scan_begin_src != TRIG_FOLLOW)
+		err++;
+	if (cmd->convert_src != TRIG_TIMER &&
+		cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
+		err++;
+	if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
+		err++;
+
+	// make sure scan_begin_src and convert_src dont conflict
+	if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
+		err++;
+	if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+
+	if (cmd->scan_begin_src == TRIG_FOLLOW) {
+		/* internal trigger */
+		if (cmd->scan_begin_arg != 0) {
+			cmd->scan_begin_arg = 0;
+			err++;
+		}
+	}
+
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+	// check against maximum frequency
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		if (cmd->scan_begin_arg <
+			thisboard->ai_speed * cmd->chanlist_len) {
+			cmd->scan_begin_arg =
+				thisboard->ai_speed * cmd->chanlist_len;
+			err++;
+		}
+	}
+	if (cmd->convert_src == TRIG_TIMER) {
+		if (cmd->convert_arg < thisboard->ai_speed) {
+			cmd->convert_arg = thisboard->ai_speed;
+			err++;
+		}
+	}
+
+	if (cmd->stop_src == TRIG_NONE) {
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+	if (err)
+		return 3;
+
+	// step 4: fix up arguments
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		unsigned int tmp = cmd->scan_begin_arg;
+		// set divisors, correct timing arguments
+		i8253_cascade_ns_to_timer_2div(devpriv->clockbase,
+			&(devpriv->divisor1), &(devpriv->divisor2),
+			&(cmd->scan_begin_arg), cmd->flags & TRIG_ROUND_MASK);
+		err += (tmp != cmd->scan_begin_arg);
+	}
+	if (cmd->convert_src == TRIG_TIMER) {
+		unsigned int tmp = cmd->convert_arg;
+		// set divisors, correct timing arguments
+		i8253_cascade_ns_to_timer_2div(devpriv->clockbase,
+			&(devpriv->divisor1), &(devpriv->divisor2),
+			&(cmd->convert_arg), cmd->flags & TRIG_ROUND_MASK);
+		err += (tmp != cmd->convert_arg);
+	}
+	if (err)
+		return 4;
+
+	// check channel/gain list against card's limitations
+	if (cmd->chanlist) {
+		gain = CR_RANGE(cmd->chanlist[0]);
+		start_chan = CR_CHAN(cmd->chanlist[0]);
+		for (i = 1; i < cmd->chanlist_len; i++) {
+			if (CR_CHAN(cmd->chanlist[i]) !=
+				(start_chan + i) % s->n_chan) {
+				comedi_error(dev,
+					"entries in chanlist must be consecutive channels, counting upwards\n");
+				err++;
+			}
+			if (CR_RANGE(cmd->chanlist[i]) != gain) {
+				comedi_error(dev,
+					"entries in chanlist must all have the same gain\n");
+				err++;
+			}
+		}
+	}
+	if (err)
+		return 5;
+
+	return 0;
+}
+
+static int das16_cmd_exec(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+	unsigned int byte;
+	unsigned long flags;
+	int range;
+
+	if (devpriv->dma_chan == 0 || (dev->irq == 0
+			&& devpriv->timer_mode == 0)) {
+		comedi_error(dev,
+			"irq (or use of 'timer mode') dma required to execute comedi_cmd");
+		return -1;
+	}
+	if (cmd->flags & TRIG_RT) {
+		comedi_error(dev,
+			"isa dma transfers cannot be performed with TRIG_RT, aborting");
+		return -1;
+	}
+
+	devpriv->adc_byte_count =
+		cmd->stop_arg * cmd->chanlist_len * sizeof(uint16_t);
+
+	// disable conversions for das1600 mode
+	if (thisboard->size > 0x400) {
+		outb(DAS1600_CONV_DISABLE, dev->iobase + DAS1600_CONV);
+	}
+	// set scan limits
+	byte = CR_CHAN(cmd->chanlist[0]);
+	byte |= CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]) << 4;
+	outb(byte, dev->iobase + DAS16_MUX);
+
+	/* set gain (this is also burst rate register but according to
+	 * computer boards manual, burst rate does nothing, even on keithley cards) */
+	if (thisboard->ai_pg != das16_pg_none) {
+		range = CR_RANGE(cmd->chanlist[0]);
+		outb((das16_gainlists[thisboard->ai_pg])[range],
+			dev->iobase + DAS16_GAIN);
+	}
+
+	/* set counter mode and counts */
+	cmd->convert_arg =
+		das16_set_pacer(dev, cmd->convert_arg,
+		cmd->flags & TRIG_ROUND_MASK);
+	DEBUG_PRINT("pacer period: %d ns\n", cmd->convert_arg);
+
+	/* enable counters */
+	byte = 0;
+	/* Enable burst mode if appropriate. */
+	if (thisboard->size > 0x400) {
+		if (cmd->convert_src == TRIG_NOW) {
+			outb(DAS1600_BURST_VAL, dev->iobase + DAS1600_BURST);
+			// set burst length
+			byte |= BURST_LEN_BITS(cmd->chanlist_len - 1);
+		} else {
+			outb(0, dev->iobase + DAS1600_BURST);
+		}
+	}
+	outb(byte, dev->iobase + DAS16_PACER);
+
+	// set up dma transfer
+	flags = claim_dma_lock();
+	disable_dma(devpriv->dma_chan);
+	/* clear flip-flop to make sure 2-byte registers for
+	 * count and address get set correctly */
+	clear_dma_ff(devpriv->dma_chan);
+	devpriv->current_buffer = 0;
+	set_dma_addr(devpriv->dma_chan,
+		devpriv->dma_buffer_addr[devpriv->current_buffer]);
+	// set appropriate size of transfer
+	devpriv->dma_transfer_size = das16_suggest_transfer_size(dev, *cmd);
+	set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
+	enable_dma(devpriv->dma_chan);
+	release_dma_lock(flags);
+
+	// set up interrupt
+	if (devpriv->timer_mode) {
+		devpriv->timer_running = 1;
+		devpriv->timer.expires = jiffies + timer_period();
+		add_timer(&devpriv->timer);
+		devpriv->control_state &= ~DAS16_INTE;
+	} else {
+		/* clear interrupt bit */
+		outb(0x00, dev->iobase + DAS16_STATUS);
+		/* enable interrupts */
+		devpriv->control_state |= DAS16_INTE;
+	}
+	devpriv->control_state |= DMA_ENABLE;
+	devpriv->control_state &= ~PACING_MASK;
+	if (cmd->convert_src == TRIG_EXT)
+		devpriv->control_state |= EXT_PACER;
+	else
+		devpriv->control_state |= INT_PACER;
+	outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
+
+	/* Enable conversions if using das1600 mode */
+	if (thisboard->size > 0x400) {
+		outb(0, dev->iobase + DAS1600_CONV);
+	}
+
+	return 0;
+}
+
+static int das16_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	/* disable interrupts, dma and pacer clocked conversions */
+	devpriv->control_state &= ~DAS16_INTE & ~PACING_MASK & ~DMA_ENABLE;
+	outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
+	if (devpriv->dma_chan)
+		disable_dma(devpriv->dma_chan);
+
+	// disable SW timer
+	if (devpriv->timer_mode && devpriv->timer_running) {
+		devpriv->timer_running = 0;
+		del_timer(&devpriv->timer);
+	}
+
+	/* disable burst mode */
+	if (thisboard->size > 0x400) {
+		outb(0, dev->iobase + DAS1600_BURST);
+	}
+
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	return 0;
+}
+
+static void das16_reset(struct comedi_device * dev)
+{
+	outb(0, dev->iobase + DAS16_STATUS);
+	outb(0, dev->iobase + DAS16_CONTROL);
+	outb(0, dev->iobase + DAS16_PACER);
+	outb(0, dev->iobase + DAS16_CNTR_CONTROL);
+}
+
+static int das16_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i, n;
+	int range;
+	int chan;
+	int msb, lsb;
+
+	// disable interrupts and pacing
+	devpriv->control_state &= ~DAS16_INTE & ~DMA_ENABLE & ~PACING_MASK;
+	outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
+
+	/* set multiplexer */
+	chan = CR_CHAN(insn->chanspec);
+	chan |= CR_CHAN(insn->chanspec) << 4;
+	outb(chan, dev->iobase + DAS16_MUX);
+
+	/* set gain */
+	if (thisboard->ai_pg != das16_pg_none) {
+		range = CR_RANGE(insn->chanspec);
+		outb((das16_gainlists[thisboard->ai_pg])[range],
+			dev->iobase + DAS16_GAIN);
+	}
+
+	for (n = 0; n < insn->n; n++) {
+		/* trigger conversion */
+		outb_p(0, dev->iobase + DAS16_TRIG);
+
+		for (i = 0; i < DAS16_TIMEOUT; i++) {
+			if (!(inb(dev->iobase + DAS16_STATUS) & BUSY))
+				break;
+		}
+		if (i == DAS16_TIMEOUT) {
+			rt_printk("das16: timeout\n");
+			return -ETIME;
+		}
+		msb = inb(dev->iobase + DAS16_AI_MSB);
+		lsb = inb(dev->iobase + DAS16_AI_LSB);
+		if (thisboard->ai_nbits == 12) {
+			data[n] = ((lsb >> 4) & 0xf) | (msb << 4);
+		} else {
+			data[n] = lsb | (msb << 8);
+		}
+	}
+
+	return n;
+}
+
+static int das16_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int bits;
+
+	bits = inb(dev->iobase + DAS16_DIO) & 0xf;
+	data[1] = bits;
+	data[0] = 0;
+
+	return 2;
+}
+
+static int das16_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int wbits;
+
+	// only set bits that have been masked
+	data[0] &= 0xf;
+	wbits = s->state;
+	// zero bits that have been masked
+	wbits &= ~data[0];
+	// set masked bits
+	wbits |= data[0] & data[1];
+	s->state = wbits;
+	data[1] = wbits;
+
+	outb(s->state, dev->iobase + DAS16_DIO);
+
+	return 2;
+}
+
+static int das16_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int lsb, msb;
+	int chan;
+
+	chan = CR_CHAN(insn->chanspec);
+
+	for (i = 0; i < insn->n; i++) {
+		if (thisboard->ao_nbits == 12) {
+			lsb = (data[i] << 4) & 0xff;
+			msb = (data[i] >> 4) & 0xff;
+		} else {
+			lsb = data[i] & 0xff;
+			msb = (data[i] >> 8) & 0xff;
+		}
+		outb(lsb, dev->iobase + DAS16_AO_LSB(chan));
+		outb(msb, dev->iobase + DAS16_AO_MSB(chan));
+	}
+
+	return i;
+}
+
+static irqreturn_t das16_dma_interrupt(int irq, void *d PT_REGS_ARG)
+{
+	int status;
+	struct comedi_device *dev = d;
+
+	status = inb(dev->iobase + DAS16_STATUS);
+
+	if ((status & DAS16_INT) == 0) {
+		DEBUG_PRINT("spurious interrupt\n");
+		return IRQ_NONE;
+	}
+
+	/* clear interrupt */
+	outb(0x00, dev->iobase + DAS16_STATUS);
+	das16_interrupt(dev);
+	return IRQ_HANDLED;
+}
+
+static void das16_timer_interrupt(unsigned long arg)
+{
+	struct comedi_device *dev = (struct comedi_device *) arg;
+
+	das16_interrupt(dev);
+
+	if (devpriv->timer_running)
+		mod_timer(&devpriv->timer, jiffies + timer_period());
+}
+
+/* the pc104-das16jr (at least) has problems if the dma
+	transfer is interrupted in the middle of transferring
+	a 16 bit sample, so this function takes care to get
+	an even transfer count after disabling dma
+	channel.
+*/
+static int disable_dma_on_even(struct comedi_device * dev)
+{
+	int residue;
+	int i;
+	static const int disable_limit = 100;
+	static const int enable_timeout = 100;
+	disable_dma(devpriv->dma_chan);
+	residue = get_dma_residue(devpriv->dma_chan);
+	for (i = 0; i < disable_limit && (residue % 2); ++i) {
+		int j;
+		enable_dma(devpriv->dma_chan);
+		for (j = 0; j < enable_timeout; ++j) {
+			int new_residue;
+			comedi_udelay(2);
+			new_residue = get_dma_residue(devpriv->dma_chan);
+			if (new_residue != residue)
+				break;
+		}
+		disable_dma(devpriv->dma_chan);
+		residue = get_dma_residue(devpriv->dma_chan);
+	}
+	if (i == disable_limit) {
+		comedi_error(dev,
+			"failed to get an even dma transfer, could be trouble.");
+	}
+	return residue;
+}
+
+static void das16_interrupt(struct comedi_device * dev)
+{
+	unsigned long dma_flags, spin_flags;
+	struct comedi_subdevice *s = dev->read_subdev;
+	struct comedi_async *async;
+	struct comedi_cmd *cmd;
+	int num_bytes, residue;
+	int buffer_index;
+
+	if (dev->attached == 0) {
+		comedi_error(dev, "premature interrupt");
+		return;
+	}
+	// initialize async here to make sure it is not NULL
+	async = s->async;
+	cmd = &async->cmd;
+
+	if (devpriv->dma_chan == 0) {
+		comedi_error(dev, "interrupt with no dma channel?");
+		return;
+	}
+
+	comedi_spin_lock_irqsave(&dev->spinlock, spin_flags);
+	if ((devpriv->control_state & DMA_ENABLE) == 0) {
+		comedi_spin_unlock_irqrestore(&dev->spinlock, spin_flags);
+		DEBUG_PRINT("interrupt while dma disabled?\n");
+		return;
+	}
+
+	dma_flags = claim_dma_lock();
+	clear_dma_ff(devpriv->dma_chan);
+	residue = disable_dma_on_even(dev);
+
+	// figure out how many points to read
+	if (residue > devpriv->dma_transfer_size) {
+		comedi_error(dev, "residue > transfer size!\n");
+		async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+		num_bytes = 0;
+	} else
+		num_bytes = devpriv->dma_transfer_size - residue;
+
+	if (cmd->stop_src == TRIG_COUNT && num_bytes >= devpriv->adc_byte_count) {
+		num_bytes = devpriv->adc_byte_count;
+		async->events |= COMEDI_CB_EOA;
+	}
+
+	buffer_index = devpriv->current_buffer;
+	devpriv->current_buffer = (devpriv->current_buffer + 1) % 2;
+	devpriv->adc_byte_count -= num_bytes;
+
+	// figure out how many bytes for next transfer
+	if (cmd->stop_src == TRIG_COUNT && devpriv->timer_mode == 0 &&
+		devpriv->dma_transfer_size > devpriv->adc_byte_count)
+		devpriv->dma_transfer_size = devpriv->adc_byte_count;
+
+	// re-enable  dma
+	if ((async->events & COMEDI_CB_EOA) == 0) {
+		set_dma_addr(devpriv->dma_chan,
+			devpriv->dma_buffer_addr[devpriv->current_buffer]);
+		set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
+		enable_dma(devpriv->dma_chan);
+		/* reenable conversions for das1600 mode, (stupid hardware) */
+		if (thisboard->size > 0x400 && devpriv->timer_mode == 0) {
+			outb(0x00, dev->iobase + DAS1600_CONV);
+		}
+	}
+	release_dma_lock(dma_flags);
+
+	comedi_spin_unlock_irqrestore(&dev->spinlock, spin_flags);
+
+	cfc_write_array_to_buffer(s,
+		devpriv->dma_buffer[buffer_index], num_bytes);
+
+	cfc_handle_events(dev, s);
+}
+
+static unsigned int das16_set_pacer(struct comedi_device * dev, unsigned int ns,
+	int rounding_flags)
+{
+	i8253_cascade_ns_to_timer_2div(devpriv->clockbase, &(devpriv->divisor1),
+		&(devpriv->divisor2), &ns, rounding_flags & TRIG_ROUND_MASK);
+
+	/* Write the values of ctr1 and ctr2 into counters 1 and 2 */
+	i8254_load(dev->iobase + DAS16_CNTR0_DATA, 0, 1, devpriv->divisor1, 2);
+	i8254_load(dev->iobase + DAS16_CNTR0_DATA, 0, 2, devpriv->divisor2, 2);
+
+	return ns;
+}
+
+static void reg_dump(struct comedi_device * dev)
+{
+	DEBUG_PRINT("********DAS1600 REGISTER DUMP********\n");
+	DEBUG_PRINT("DAS16_MUX: %x\n", inb(dev->iobase + DAS16_MUX));
+	DEBUG_PRINT("DAS16_DIO: %x\n", inb(dev->iobase + DAS16_DIO));
+	DEBUG_PRINT("DAS16_STATUS: %x\n", inb(dev->iobase + DAS16_STATUS));
+	DEBUG_PRINT("DAS16_CONTROL: %x\n", inb(dev->iobase + DAS16_CONTROL));
+	DEBUG_PRINT("DAS16_PACER: %x\n", inb(dev->iobase + DAS16_PACER));
+	DEBUG_PRINT("DAS16_GAIN: %x\n", inb(dev->iobase + DAS16_GAIN));
+	DEBUG_PRINT("DAS16_CNTR_CONTROL: %x\n",
+		inb(dev->iobase + DAS16_CNTR_CONTROL));
+	DEBUG_PRINT("DAS1600_CONV: %x\n", inb(dev->iobase + DAS1600_CONV));
+	DEBUG_PRINT("DAS1600_BURST: %x\n", inb(dev->iobase + DAS1600_BURST));
+	DEBUG_PRINT("DAS1600_ENABLE: %x\n", inb(dev->iobase + DAS1600_ENABLE));
+	DEBUG_PRINT("DAS1600_STATUS_B: %x\n",
+		inb(dev->iobase + DAS1600_STATUS_B));
+}
+
+static int das16_probe(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	int status;
+	int diobits;
+
+	/* status is available on all boards */
+
+	status = inb(dev->iobase + DAS16_STATUS);
+
+	if ((status & UNIPOLAR)) {
+		devpriv->ai_unipolar = 1;
+	} else {
+		devpriv->ai_unipolar = 0;
+	}
+
+	if ((status & DAS16_MUXBIT)) {
+		devpriv->ai_singleended = 1;
+	} else {
+		devpriv->ai_singleended = 0;
+	}
+
+	/* diobits indicates boards */
+
+	diobits = inb(dev->iobase + DAS16_DIO) & 0xf0;
+
+	printk(" id bits are 0x%02x\n", diobits);
+	if (thisboard->id != diobits) {
+		printk(" requested board's id bits are 0x%x (ignore)\n",
+			thisboard->id);
+	}
+
+	return 0;
+}
+
+static int das1600_mode_detect(struct comedi_device * dev)
+{
+	int status = 0;
+
+	status = inb(dev->iobase + DAS1600_STATUS_B);
+
+	if (status & DAS1600_CLK_10MHZ) {
+		devpriv->clockbase = 100;
+		printk(" 10MHz pacer clock\n");
+	} else {
+		devpriv->clockbase = 1000;
+		printk(" 1MHz pacer clock\n");
+	}
+
+	reg_dump(dev);
+
+	return 0;
+}
+
+/*
+ *
+ * Options list:
+ *   0  I/O base
+ *   1  IRQ
+ *   2  DMA
+ *   3  Clock speed (in MHz)
+ */
+
+static int das16_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	int ret;
+	unsigned int irq;
+	unsigned long iobase;
+	unsigned int dma_chan;
+	int timer_mode;
+	unsigned long flags;
+	struct comedi_krange *user_ai_range, *user_ao_range;
+
+	iobase = it->options[0];
+#if 0
+	irq = it->options[1];
+	timer_mode = it->options[8];
+#endif
+	/* always use time_mode since using irq can drop samples while
+	 * waiting for dma done interrupt (due to hardware limitations) */
+	irq = 0;
+	timer_mode = 1;
+	if (timer_mode)
+		irq = 0;
+
+	printk("comedi%d: das16:", dev->minor);
+
+	// check that clock setting is valid
+	if (it->options[3]) {
+		if (it->options[3] != 0 &&
+			it->options[3] != 1 && it->options[3] != 10) {
+			printk("\n Invalid option.  Master clock must be set to 1 or 10 (MHz)\n");
+			return -EINVAL;
+		}
+	}
+
+	if ((ret = alloc_private(dev, sizeof(struct das16_private_struct))) < 0)
+		return ret;
+
+	if (thisboard->size < 0x400) {
+		printk(" 0x%04lx-0x%04lx\n", iobase, iobase + thisboard->size);
+		if (!request_region(iobase, thisboard->size, "das16")) {
+			printk(" I/O port conflict\n");
+			return -EIO;
+		}
+	} else {
+		printk(" 0x%04lx-0x%04lx 0x%04lx-0x%04lx\n",
+			iobase, iobase + 0x0f,
+			iobase + 0x400,
+			iobase + 0x400 + (thisboard->size & 0x3ff));
+		if (!request_region(iobase, 0x10, "das16")) {
+			printk(" I/O port conflict:  0x%04lx-0x%04lx\n",
+				iobase, iobase + 0x0f);
+			return -EIO;
+		}
+		if (!request_region(iobase + 0x400, thisboard->size & 0x3ff,
+				"das16")) {
+			release_region(iobase, 0x10);
+			printk(" I/O port conflict:  0x%04lx-0x%04lx\n",
+				iobase + 0x400,
+				iobase + 0x400 + (thisboard->size & 0x3ff));
+			return -EIO;
+		}
+	}
+
+	dev->iobase = iobase;
+
+	// probe id bits to make sure they are consistent
+	if (das16_probe(dev, it)) {
+		printk(" id bits do not match selected board, aborting\n");
+		return -EINVAL;
+	}
+	dev->board_name = thisboard->name;
+
+	// get master clock speed
+	if (thisboard->size < 0x400) {
+		if (it->options[3])
+			devpriv->clockbase = 1000 / it->options[3];
+		else
+			devpriv->clockbase = 1000;	// 1 MHz default
+	} else {
+		das1600_mode_detect(dev);
+	}
+
+	/* now for the irq */
+	if (irq > 1 && irq < 8) {
+		if ((ret = comedi_request_irq(irq, das16_dma_interrupt, 0,
+					"das16", dev)) < 0)
+			return ret;
+		dev->irq = irq;
+		printk(" ( irq = %u )", irq);
+	} else if (irq == 0) {
+		printk(" ( no irq )");
+	} else {
+		printk(" invalid irq\n");
+		return -EINVAL;
+	}
+
+	// initialize dma
+	dma_chan = it->options[2];
+	if (dma_chan == 1 || dma_chan == 3) {
+		// allocate dma buffers
+		int i;
+		for (i = 0; i < 2; i++) {
+			devpriv->dma_buffer[i] = pci_alloc_consistent(NULL,
+				DAS16_DMA_SIZE, &devpriv->dma_buffer_addr[i]);
+			if (devpriv->dma_buffer[i] == NULL)
+				return -ENOMEM;
+		}
+		if (request_dma(dma_chan, "das16")) {
+			printk(" failed to allocate dma channel %i\n",
+				dma_chan);
+			return -EINVAL;
+		}
+		devpriv->dma_chan = dma_chan;
+		flags = claim_dma_lock();
+		disable_dma(devpriv->dma_chan);
+		set_dma_mode(devpriv->dma_chan, DMA_MODE_READ);
+		release_dma_lock(flags);
+		printk(" ( dma = %u)\n", dma_chan);
+	} else if (dma_chan == 0) {
+		printk(" ( no dma )\n");
+	} else {
+		printk(" invalid dma channel\n");
+		return -EINVAL;
+	}
+
+	// get any user-defined input range
+	if (thisboard->ai_pg == das16_pg_none &&
+		(it->options[4] || it->options[5])) {
+		// allocate single-range range table
+		devpriv->user_ai_range_table =
+			kmalloc(sizeof(struct comedi_lrange) + sizeof(struct comedi_krange),
+			GFP_KERNEL);
+		// initialize ai range
+		devpriv->user_ai_range_table->length = 1;
+		user_ai_range = devpriv->user_ai_range_table->range;
+		user_ai_range->min = it->options[4];
+		user_ai_range->max = it->options[5];
+		user_ai_range->flags = UNIT_volt;
+	}
+	// get any user-defined output range
+	if (it->options[6] || it->options[7]) {
+		// allocate single-range range table
+		devpriv->user_ao_range_table =
+			kmalloc(sizeof(struct comedi_lrange) + sizeof(struct comedi_krange),
+			GFP_KERNEL);
+		// initialize ao range
+		devpriv->user_ao_range_table->length = 1;
+		user_ao_range = devpriv->user_ao_range_table->range;
+		user_ao_range->min = it->options[6];
+		user_ao_range->max = it->options[7];
+		user_ao_range->flags = UNIT_volt;
+	}
+
+	if (timer_mode) {
+		init_timer(&(devpriv->timer));
+		devpriv->timer.function = das16_timer_interrupt;
+		devpriv->timer.data = (unsigned long)dev;
+	}
+	devpriv->timer_mode = timer_mode ? 1 : 0;
+
+	if ((ret = alloc_subdevices(dev, 5)) < 0)
+		return ret;
+
+	s = dev->subdevices + 0;
+	dev->read_subdev = s;
+	/* ai */
+	if (thisboard->ai) {
+		s->type = COMEDI_SUBD_AI;
+		s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+		if (devpriv->ai_singleended) {
+			s->n_chan = 16;
+			s->len_chanlist = 16;
+			s->subdev_flags |= SDF_GROUND;
+		} else {
+			s->n_chan = 8;
+			s->len_chanlist = 8;
+			s->subdev_flags |= SDF_DIFF;
+		}
+		s->maxdata = (1 << thisboard->ai_nbits) - 1;
+		if (devpriv->user_ai_range_table) {	// user defined ai range
+			s->range_table = devpriv->user_ai_range_table;
+		} else if (devpriv->ai_unipolar) {
+			s->range_table = das16_ai_uni_lranges[thisboard->ai_pg];
+		} else {
+			s->range_table = das16_ai_bip_lranges[thisboard->ai_pg];
+		}
+		s->insn_read = thisboard->ai;
+		s->do_cmdtest = das16_cmd_test;
+		s->do_cmd = das16_cmd_exec;
+		s->cancel = das16_cancel;
+		s->munge = das16_ai_munge;
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	s = dev->subdevices + 1;
+	/* ao */
+	if (thisboard->ao) {
+		s->type = COMEDI_SUBD_AO;
+		s->subdev_flags = SDF_WRITABLE;
+		s->n_chan = 2;
+		s->maxdata = (1 << thisboard->ao_nbits) - 1;
+		if (devpriv->user_ao_range_table) {	// user defined ao range
+			s->range_table = devpriv->user_ao_range_table;
+		} else {
+			s->range_table = &range_unknown;
+		}
+		s->insn_write = thisboard->ao;
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	s = dev->subdevices + 2;
+	/* di */
+	if (thisboard->di) {
+		s->type = COMEDI_SUBD_DI;
+		s->subdev_flags = SDF_READABLE;
+		s->n_chan = 4;
+		s->maxdata = 1;
+		s->range_table = &range_digital;
+		s->insn_bits = thisboard->di;
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	s = dev->subdevices + 3;
+	/* do */
+	if (thisboard->do_) {
+		s->type = COMEDI_SUBD_DO;
+		s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+		s->n_chan = 4;
+		s->maxdata = 1;
+		s->range_table = &range_digital;
+		s->insn_bits = thisboard->do_;
+		// initialize digital output lines
+		outb(s->state, dev->iobase + DAS16_DIO);
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	s = dev->subdevices + 4;
+	/* 8255 */
+	if (thisboard->i8255_offset != 0) {
+		subdev_8255_init(dev, s, NULL, (dev->iobase +
+				thisboard->i8255_offset));
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	das16_reset(dev);
+	/* set the interrupt level */
+	devpriv->control_state = DAS16_IRQ(dev->irq);
+	outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
+
+	// turn on das1600 mode if available
+	if (thisboard->size > 0x400) {
+		outb(DAS1600_ENABLE_VAL, dev->iobase + DAS1600_ENABLE);
+		outb(0, dev->iobase + DAS1600_CONV);
+		outb(0, dev->iobase + DAS1600_BURST);
+	}
+
+	return 0;
+}
+
+static int das16_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: das16: remove\n", dev->minor);
+
+	das16_reset(dev);
+
+	if (dev->subdevices)
+		subdev_8255_cleanup(dev, dev->subdevices + 4);
+
+	if (devpriv) {
+		int i;
+		for (i = 0; i < 2; i++) {
+			if (devpriv->dma_buffer[i])
+				pci_free_consistent(NULL, DAS16_DMA_SIZE,
+					devpriv->dma_buffer[i],
+					devpriv->dma_buffer_addr[i]);
+		}
+		if (devpriv->dma_chan)
+			free_dma(devpriv->dma_chan);
+		if (devpriv->user_ai_range_table)
+			kfree(devpriv->user_ai_range_table);
+		if (devpriv->user_ao_range_table)
+			kfree(devpriv->user_ao_range_table);
+	}
+
+	if (dev->irq)
+		comedi_free_irq(dev->irq, dev);
+
+	if (dev->iobase) {
+		if (thisboard->size < 0x400) {
+			release_region(dev->iobase, thisboard->size);
+		} else {
+			release_region(dev->iobase, 0x10);
+			release_region(dev->iobase + 0x400,
+				thisboard->size & 0x3ff);
+		}
+	}
+
+	return 0;
+}
+
+COMEDI_INITCLEANUP(driver_das16);
+
+// utility function that suggests a dma transfer size in bytes
+static unsigned int das16_suggest_transfer_size(struct comedi_device * dev,
+	struct comedi_cmd cmd)
+{
+	unsigned int size;
+	unsigned int freq;
+
+	/* if we are using timer interrupt, we don't care how long it
+	 * will take to complete transfer since it will be interrupted
+	 * by timer interrupt */
+	if (devpriv->timer_mode)
+		return DAS16_DMA_SIZE;
+
+	/* otherwise, we are relying on dma terminal count interrupt,
+	 * so pick a reasonable size */
+	if (cmd.convert_src == TRIG_TIMER)
+		freq = 1000000000 / cmd.convert_arg;
+	else if (cmd.scan_begin_src == TRIG_TIMER)
+		freq = (1000000000 / cmd.scan_begin_arg) * cmd.chanlist_len;
+	// return some default value
+	else
+		freq = 0xffffffff;
+
+	if (cmd.flags & TRIG_WAKE_EOS) {
+		size = sample_size * cmd.chanlist_len;
+	} else {
+		// make buffer fill in no more than 1/3 second
+		size = (freq / 3) * sample_size;
+	}
+
+	// set a minimum and maximum size allowed
+	if (size > DAS16_DMA_SIZE)
+		size = DAS16_DMA_SIZE - DAS16_DMA_SIZE % sample_size;
+	else if (size < sample_size)
+		size = sample_size;
+
+	if (cmd.stop_src == TRIG_COUNT && size > devpriv->adc_byte_count)
+		size = devpriv->adc_byte_count;
+
+	return size;
+}
+
+static void das16_ai_munge(struct comedi_device * dev, struct comedi_subdevice * s,
+	void *array, unsigned int num_bytes, unsigned int start_chan_index)
+{
+	unsigned int i, num_samples = num_bytes / sizeof(short);
+	short *data = array;
+
+	for (i = 0; i < num_samples; i++) {
+		data[i] = le16_to_cpu(data[i]);
+		if (thisboard->ai_nbits == 12) {
+			data[i] = (data[i] >> 4) & 0xfff;
+		}
+	}
+}
diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c
new file mode 100644
index 0000000..0e423e1
--- /dev/null
+++ b/drivers/staging/comedi/drivers/das16m1.c
@@ -0,0 +1,765 @@
+/*
+    comedi/drivers/das16m1.c
+    CIO-DAS16/M1 driver
+    Author: Frank Mori Hess, based on code from the das16
+      driver.
+    Copyright (C) 2001 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000 David A. Schleef <ds@schleef.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.
+
+    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.
+
+************************************************************************
+*/
+/*
+Driver: das16m1
+Description: CIO-DAS16/M1
+Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+Devices: [Measurement Computing] CIO-DAS16/M1 (cio-das16/m1)
+Status: works
+
+This driver supports a single board - the CIO-DAS16/M1.
+As far as I know, there are no other boards that have
+the same register layout.  Even the CIO-DAS16/M1/16 is
+significantly different.
+
+I was _barely_ able to reach the full 1 MHz capability
+of this board, using a hard real-time interrupt
+(set the TRIG_RT flag in your struct comedi_cmd and use
+rtlinux or RTAI).  The board can't do dma, so the bottleneck is
+pulling the data across the ISA bus.  I timed the interrupt
+handler, and it took my computer ~470 microseconds to pull 512
+samples from the board.  So at 1 Mhz sampling rate,
+expect your CPU to be spending almost all of its
+time in the interrupt handler.
+
+This board has some unusual restrictions for its channel/gain list.  If the
+list has 2 or more channels in it, then two conditions must be satisfied:
+(1) - even/odd channels must appear at even/odd indices in the list
+(2) - the list must have an even number of entries.
+
+Options:
+        [0] - base io address
+        [1] - irq (optional, but you probably want it)
+
+irq can be omitted, although the cmd interface will not work without it.
+*/
+
+#include <linux/ioport.h>
+#include "../comedidev.h"
+
+#include "8255.h"
+#include "8253.h"
+#include "comedi_fc.h"
+
+#define DAS16M1_SIZE 16
+#define DAS16M1_SIZE2 8
+
+#define DAS16M1_XTAL 100	//10 MHz master clock
+
+#define FIFO_SIZE 1024		// 1024 sample fifo
+
+/*
+    CIO-DAS16_M1.pdf
+
+    "cio-das16/m1"
+
+  0	a/d bits 0-3, mux		start 12 bit
+  1	a/d bits 4-11		unused
+  2	status		control
+  3	di 4 bit		do 4 bit
+  4	unused			clear interrupt
+  5	interrupt, pacer
+  6	channel/gain queue address
+  7	channel/gain queue data
+  89ab	8254
+  cdef	8254
+  400	8255
+  404-407 	8254
+
+*/
+
+#define DAS16M1_AI             0	// 16-bit wide register
+#define   AI_CHAN(x)             ((x) & 0xf)
+#define DAS16M1_CS             2
+#define   EXT_TRIG_BIT           0x1
+#define   OVRUN                  0x20
+#define   IRQDATA                0x80
+#define DAS16M1_DIO            3
+#define DAS16M1_CLEAR_INTR     4
+#define DAS16M1_INTR_CONTROL   5
+#define   EXT_PACER              0x2
+#define   INT_PACER              0x3
+#define   PACER_MASK             0x3
+#define   INTE                   0x80
+#define DAS16M1_QUEUE_ADDR     6
+#define DAS16M1_QUEUE_DATA     7
+#define   Q_CHAN(x)              ((x) & 0x7)
+#define   Q_RANGE(x)             (((x) & 0xf) << 4)
+#define   UNIPOLAR               0x40
+#define DAS16M1_8254_FIRST             0x8
+#define DAS16M1_8254_FIRST_CNTRL       0xb
+#define   TOTAL_CLEAR                    0x30
+#define DAS16M1_8254_SECOND            0xc
+#define DAS16M1_82C55                  0x400
+#define DAS16M1_8254_THIRD             0x404
+
+static const struct comedi_lrange range_das16m1 = { 9,
+	{
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+			BIP_RANGE(0.625),
+			UNI_RANGE(10),
+			UNI_RANGE(5),
+			UNI_RANGE(2.5),
+			UNI_RANGE(1.25),
+			BIP_RANGE(10),
+		}
+};
+
+static int das16m1_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int das16m1_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int das16m1_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+static int das16m1_cmd_test(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd);
+static int das16m1_cmd_exec(struct comedi_device * dev, struct comedi_subdevice * s);
+static int das16m1_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static int das16m1_poll(struct comedi_device * dev, struct comedi_subdevice * s);
+static irqreturn_t das16m1_interrupt(int irq, void *d PT_REGS_ARG);
+static void das16m1_handler(struct comedi_device * dev, unsigned int status);
+
+static unsigned int das16m1_set_pacer(struct comedi_device * dev, unsigned int ns,
+	int round_flag);
+
+static int das16m1_irq_bits(unsigned int irq);
+
+struct das16m1_board {
+	const char *name;
+	unsigned int ai_speed;
+};
+
+static const struct das16m1_board das16m1_boards[] = {
+	{
+	      name:	"cio-das16/m1",	// CIO-DAS16_M1.pdf
+	      ai_speed:1000,	// 1MHz max speed
+		},
+};
+
+#define das16m1_num_boards ((sizeof(das16m1_boards)) / (sizeof(das16m1_boards[0])))
+
+static int das16m1_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int das16m1_detach(struct comedi_device * dev);
+static struct comedi_driver driver_das16m1 = {
+      driver_name:"das16m1",
+      module:THIS_MODULE,
+      attach:das16m1_attach,
+      detach:das16m1_detach,
+      board_name:&das16m1_boards[0].name,
+      num_names:das16m1_num_boards,
+      offset:sizeof(das16m1_boards[0]),
+};
+
+struct das16m1_private_struct {
+	unsigned int control_state;
+	volatile unsigned int adc_count;	// number of samples completed
+	/* initial value in lower half of hardware conversion counter,
+	 * needed to keep track of whether new count has been loaded into
+	 * counter yet (loaded by first sample conversion) */
+	u16 initial_hw_count;
+	short ai_buffer[FIFO_SIZE];
+	unsigned int do_bits;	// saves status of digital output bits
+	unsigned int divisor1;	// divides master clock to obtain conversion speed
+	unsigned int divisor2;	// divides master clock to obtain conversion speed
+};
+#define devpriv ((struct das16m1_private_struct *)(dev->private))
+#define thisboard ((const struct das16m1_board *)(dev->board_ptr))
+
+COMEDI_INITCLEANUP(driver_das16m1);
+
+static inline short munge_sample(short data)
+{
+	return (data >> 4) & 0xfff;
+}
+
+static int das16m1_cmd_test(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	unsigned int err = 0, tmp, i;
+
+	/* make sure triggers are valid */
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW | TRIG_EXT;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_FOLLOW;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+		err++;
+	if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
+		err++;
+	if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+
+	if (cmd->scan_begin_src == TRIG_FOLLOW) {
+		/* internal trigger */
+		if (cmd->scan_begin_arg != 0) {
+			cmd->scan_begin_arg = 0;
+			err++;
+		}
+	}
+
+	if (cmd->convert_src == TRIG_TIMER) {
+		if (cmd->convert_arg < thisboard->ai_speed) {
+			cmd->convert_arg = thisboard->ai_speed;
+			err++;
+		}
+	}
+
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+
+	if (cmd->stop_src == TRIG_COUNT) {
+		/* any count is allowed */
+	} else {
+		/* TRIG_NONE */
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up arguments */
+
+	if (cmd->convert_src == TRIG_TIMER) {
+		tmp = cmd->convert_arg;
+		/* calculate counter values that give desired timing */
+		i8253_cascade_ns_to_timer_2div(DAS16M1_XTAL,
+			&(devpriv->divisor1), &(devpriv->divisor2),
+			&(cmd->convert_arg), cmd->flags & TRIG_ROUND_MASK);
+		if (tmp != cmd->convert_arg)
+			err++;
+	}
+
+	if (err)
+		return 4;
+
+	// check chanlist against board's peculiarities
+	if (cmd->chanlist && cmd->chanlist_len > 1) {
+		for (i = 0; i < cmd->chanlist_len; i++) {
+			// even/odd channels must go into even/odd queue addresses
+			if ((i % 2) != (CR_CHAN(cmd->chanlist[i]) % 2)) {
+				comedi_error(dev, "bad chanlist:\n"
+					" even/odd channels must go have even/odd chanlist indices");
+				err++;
+			}
+		}
+		if ((cmd->chanlist_len % 2) != 0) {
+			comedi_error(dev,
+				"chanlist must be of even length or length 1");
+			err++;
+		}
+	}
+
+	if (err)
+		return 5;
+
+	return 0;
+}
+
+static int das16m1_cmd_exec(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+	unsigned int byte, i;
+
+	if (dev->irq == 0) {
+		comedi_error(dev, "irq required to execute comedi_cmd");
+		return -1;
+	}
+
+	/* disable interrupts and internal pacer */
+	devpriv->control_state &= ~INTE & ~PACER_MASK;
+	outb(devpriv->control_state, dev->iobase + DAS16M1_INTR_CONTROL);
+
+	// set software count
+	devpriv->adc_count = 0;
+	/* Initialize lower half of hardware counter, used to determine how
+	 * many samples are in fifo.  Value doesn't actually load into counter
+	 * until counter's next clock (the next a/d conversion) */
+	i8254_load(dev->iobase + DAS16M1_8254_FIRST, 0, 1, 0, 2);
+	/* remember current reading of counter so we know when counter has
+	 * actually been loaded */
+	devpriv->initial_hw_count =
+		i8254_read(dev->iobase + DAS16M1_8254_FIRST, 0, 1);
+	/* setup channel/gain queue */
+	for (i = 0; i < cmd->chanlist_len; i++) {
+		outb(i, dev->iobase + DAS16M1_QUEUE_ADDR);
+		byte = Q_CHAN(CR_CHAN(cmd->
+				chanlist[i])) | Q_RANGE(CR_RANGE(cmd->
+				chanlist[i]));
+		outb(byte, dev->iobase + DAS16M1_QUEUE_DATA);
+	}
+
+	/* set counter mode and counts */
+	cmd->convert_arg =
+		das16m1_set_pacer(dev, cmd->convert_arg,
+		cmd->flags & TRIG_ROUND_MASK);
+
+	// set control & status register
+	byte = 0;
+	/* if we are using external start trigger (also board dislikes having
+	 * both start and conversion triggers external simultaneously) */
+	if (cmd->start_src == TRIG_EXT && cmd->convert_src != TRIG_EXT) {
+		byte |= EXT_TRIG_BIT;
+	}
+	outb(byte, dev->iobase + DAS16M1_CS);
+	/* clear interrupt bit */
+	outb(0, dev->iobase + DAS16M1_CLEAR_INTR);
+
+	/* enable interrupts and internal pacer */
+	devpriv->control_state &= ~PACER_MASK;
+	if (cmd->convert_src == TRIG_TIMER) {
+		devpriv->control_state |= INT_PACER;
+	} else {
+		devpriv->control_state |= EXT_PACER;
+	}
+	devpriv->control_state |= INTE;
+	outb(devpriv->control_state, dev->iobase + DAS16M1_INTR_CONTROL);
+
+	return 0;
+}
+
+static int das16m1_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	devpriv->control_state &= ~INTE & ~PACER_MASK;
+	outb(devpriv->control_state, dev->iobase + DAS16M1_INTR_CONTROL);
+
+	return 0;
+}
+
+static int das16m1_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i, n;
+	int byte;
+	const int timeout = 1000;
+
+	/* disable interrupts and internal pacer */
+	devpriv->control_state &= ~INTE & ~PACER_MASK;
+	outb(devpriv->control_state, dev->iobase + DAS16M1_INTR_CONTROL);
+
+	/* setup channel/gain queue */
+	outb(0, dev->iobase + DAS16M1_QUEUE_ADDR);
+	byte = Q_CHAN(CR_CHAN(insn->chanspec)) | Q_RANGE(CR_RANGE(insn->
+			chanspec));
+	outb(byte, dev->iobase + DAS16M1_QUEUE_DATA);
+
+	for (n = 0; n < insn->n; n++) {
+		/* clear IRQDATA bit */
+		outb(0, dev->iobase + DAS16M1_CLEAR_INTR);
+		/* trigger conversion */
+		outb(0, dev->iobase);
+
+		for (i = 0; i < timeout; i++) {
+			if (inb(dev->iobase + DAS16M1_CS) & IRQDATA)
+				break;
+		}
+		if (i == timeout) {
+			comedi_error(dev, "timeout");
+			return -ETIME;
+		}
+		data[n] = munge_sample(inw(dev->iobase));
+	}
+
+	return n;
+}
+
+static int das16m1_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int bits;
+
+	bits = inb(dev->iobase + DAS16M1_DIO) & 0xf;
+	data[1] = bits;
+	data[0] = 0;
+
+	return 2;
+}
+
+static int das16m1_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int wbits;
+
+	// only set bits that have been masked
+	data[0] &= 0xf;
+	wbits = devpriv->do_bits;
+	// zero bits that have been masked
+	wbits &= ~data[0];
+	// set masked bits
+	wbits |= data[0] & data[1];
+	devpriv->do_bits = wbits;
+	data[1] = wbits;
+
+	outb(devpriv->do_bits, dev->iobase + DAS16M1_DIO);
+
+	return 2;
+}
+
+static int das16m1_poll(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	unsigned long flags;
+	unsigned int status;
+
+	// prevent race with interrupt handler
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	status = inb(dev->iobase + DAS16M1_CS);
+	das16m1_handler(dev, status);
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	return s->async->buf_write_count - s->async->buf_read_count;
+}
+
+static irqreturn_t das16m1_interrupt(int irq, void *d PT_REGS_ARG)
+{
+	int status;
+	struct comedi_device *dev = d;
+
+	if (dev->attached == 0) {
+		comedi_error(dev, "premature interrupt");
+		return IRQ_HANDLED;
+	}
+	// prevent race with comedi_poll()
+	spin_lock(&dev->spinlock);
+
+	status = inb(dev->iobase + DAS16M1_CS);
+
+	if ((status & (IRQDATA | OVRUN)) == 0) {
+		comedi_error(dev, "spurious interrupt");
+		spin_unlock(&dev->spinlock);
+		return IRQ_NONE;
+	}
+
+	das16m1_handler(dev, status);
+
+	/* clear interrupt */
+	outb(0, dev->iobase + DAS16M1_CLEAR_INTR);
+
+	spin_unlock(&dev->spinlock);
+	return IRQ_HANDLED;
+}
+
+static void munge_sample_array(short * array, unsigned int num_elements)
+{
+	unsigned int i;
+
+	for (i = 0; i < num_elements; i++) {
+		array[i] = munge_sample(array[i]);
+	}
+}
+
+static void das16m1_handler(struct comedi_device * dev, unsigned int status)
+{
+	struct comedi_subdevice *s;
+	struct comedi_async *async;
+	struct comedi_cmd *cmd;
+	u16 num_samples;
+	u16 hw_counter;
+
+	s = dev->read_subdev;
+	async = s->async;
+	async->events = 0;
+	cmd = &async->cmd;
+
+	// figure out how many samples are in fifo
+	hw_counter = i8254_read(dev->iobase + DAS16M1_8254_FIRST, 0, 1);
+	/* make sure hardware counter reading is not bogus due to initial value
+	 * not having been loaded yet */
+	if (devpriv->adc_count == 0 && hw_counter == devpriv->initial_hw_count) {
+		num_samples = 0;
+	} else {
+		/* The calculation of num_samples looks odd, but it uses the following facts.
+		 * 16 bit hardware counter is initialized with value of zero (which really
+		 * means 0x1000).  The counter decrements by one on each conversion
+		 * (when the counter decrements from zero it goes to 0xffff).  num_samples
+		 * is a 16 bit variable, so it will roll over in a similar fashion to the
+		 * hardware counter.  Work it out, and this is what you get. */
+		num_samples = -hw_counter - devpriv->adc_count;
+	}
+	// check if we only need some of the points
+	if (cmd->stop_src == TRIG_COUNT) {
+		if (num_samples > cmd->stop_arg * cmd->chanlist_len)
+			num_samples = cmd->stop_arg * cmd->chanlist_len;
+	}
+	// make sure we dont try to get too many points if fifo has overrun
+	if (num_samples > FIFO_SIZE)
+		num_samples = FIFO_SIZE;
+	insw(dev->iobase, devpriv->ai_buffer, num_samples);
+	munge_sample_array(devpriv->ai_buffer, num_samples);
+	cfc_write_array_to_buffer(s, devpriv->ai_buffer,
+		num_samples * sizeof(short));
+	devpriv->adc_count += num_samples;
+
+	if (cmd->stop_src == TRIG_COUNT) {
+		if (devpriv->adc_count >= cmd->stop_arg * cmd->chanlist_len) {	/* end of acquisition */
+			das16m1_cancel(dev, s);
+			async->events |= COMEDI_CB_EOA;
+		}
+	}
+
+	/* this probably won't catch overruns since the card doesn't generate
+	 * overrun interrupts, but we might as well try */
+	if (status & OVRUN) {
+		das16m1_cancel(dev, s);
+		async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+		comedi_error(dev, "fifo overflow");
+	}
+
+	comedi_event(dev, s);
+
+}
+
+/* This function takes a time in nanoseconds and sets the     *
+ * 2 pacer clocks to the closest frequency possible. It also  *
+ * returns the actual sampling period.                        */
+static unsigned int das16m1_set_pacer(struct comedi_device * dev, unsigned int ns,
+	int rounding_flags)
+{
+	i8253_cascade_ns_to_timer_2div(DAS16M1_XTAL, &(devpriv->divisor1),
+		&(devpriv->divisor2), &ns, rounding_flags & TRIG_ROUND_MASK);
+
+	/* Write the values of ctr1 and ctr2 into counters 1 and 2 */
+	i8254_load(dev->iobase + DAS16M1_8254_SECOND, 0, 1, devpriv->divisor1,
+		2);
+	i8254_load(dev->iobase + DAS16M1_8254_SECOND, 0, 2, devpriv->divisor2,
+		2);
+
+	return ns;
+}
+
+static int das16m1_irq_bits(unsigned int irq)
+{
+	int ret;
+
+	switch (irq) {
+	case 10:
+		ret = 0x0;
+		break;
+	case 11:
+		ret = 0x1;
+		break;
+	case 12:
+		ret = 0x2;
+		break;
+	case 15:
+		ret = 0x3;
+		break;
+	case 2:
+		ret = 0x4;
+		break;
+	case 3:
+		ret = 0x5;
+		break;
+	case 5:
+		ret = 0x6;
+		break;
+	case 7:
+		ret = 0x7;
+		break;
+	default:
+		return -1;
+		break;
+	}
+	return (ret << 4);
+}
+
+/*
+ * Options list:
+ *   0  I/O base
+ *   1  IRQ
+ */
+
+static int das16m1_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	int ret;
+	unsigned int irq;
+	unsigned long iobase;
+
+	iobase = it->options[0];
+
+	printk("comedi%d: das16m1:", dev->minor);
+
+	if ((ret = alloc_private(dev,
+				sizeof(struct das16m1_private_struct))) < 0)
+		return ret;
+
+	dev->board_name = thisboard->name;
+
+	printk(" io 0x%lx-0x%lx 0x%lx-0x%lx",
+		iobase, iobase + DAS16M1_SIZE,
+		iobase + DAS16M1_82C55, iobase + DAS16M1_82C55 + DAS16M1_SIZE2);
+	if (!request_region(iobase, DAS16M1_SIZE, driver_das16m1.driver_name)) {
+		printk(" I/O port conflict\n");
+		return -EIO;
+	}
+	if (!request_region(iobase + DAS16M1_82C55, DAS16M1_SIZE2,
+			driver_das16m1.driver_name)) {
+		release_region(iobase, DAS16M1_SIZE);
+		printk(" I/O port conflict\n");
+		return -EIO;
+	}
+	dev->iobase = iobase;
+
+	/* now for the irq */
+	irq = it->options[1];
+	// make sure it is valid
+	if (das16m1_irq_bits(irq) >= 0) {
+		ret = comedi_request_irq(irq, das16m1_interrupt, 0,
+			driver_das16m1.driver_name, dev);
+		if (ret < 0) {
+			printk(", irq unavailable\n");
+			return ret;
+		}
+		dev->irq = irq;
+		printk(", irq %u\n", irq);
+	} else if (irq == 0) {
+		printk(", no irq\n");
+	} else {
+		printk(", invalid irq\n"
+			" valid irqs are 2, 3, 5, 7, 10, 11, 12, or 15\n");
+		return -EINVAL;
+	}
+
+	if ((ret = alloc_subdevices(dev, 4)) < 0)
+		return ret;
+
+	s = dev->subdevices + 0;
+	dev->read_subdev = s;
+	/* ai */
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+	s->n_chan = 8;
+	s->subdev_flags = SDF_DIFF;
+	s->len_chanlist = 256;
+	s->maxdata = (1 << 12) - 1;
+	s->range_table = &range_das16m1;
+	s->insn_read = das16m1_ai_rinsn;
+	s->do_cmdtest = das16m1_cmd_test;
+	s->do_cmd = das16m1_cmd_exec;
+	s->cancel = das16m1_cancel;
+	s->poll = das16m1_poll;
+
+	s = dev->subdevices + 1;
+	/* di */
+	s->type = COMEDI_SUBD_DI;
+	s->subdev_flags = SDF_READABLE;
+	s->n_chan = 4;
+	s->maxdata = 1;
+	s->range_table = &range_digital;
+	s->insn_bits = das16m1_di_rbits;
+
+	s = dev->subdevices + 2;
+	/* do */
+	s->type = COMEDI_SUBD_DO;
+	s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+	s->n_chan = 4;
+	s->maxdata = 1;
+	s->range_table = &range_digital;
+	s->insn_bits = das16m1_do_wbits;
+
+	s = dev->subdevices + 3;
+	/* 8255 */
+	subdev_8255_init(dev, s, NULL, dev->iobase + DAS16M1_82C55);
+
+	// disable upper half of hardware conversion counter so it doesn't mess with us
+	outb(TOTAL_CLEAR, dev->iobase + DAS16M1_8254_FIRST_CNTRL);
+
+	// initialize digital output lines
+	outb(devpriv->do_bits, dev->iobase + DAS16M1_DIO);
+
+	/* set the interrupt level */
+	if (dev->irq)
+		devpriv->control_state = das16m1_irq_bits(dev->irq);
+	else
+		devpriv->control_state = 0;
+	outb(devpriv->control_state, dev->iobase + DAS16M1_INTR_CONTROL);
+
+	return 0;
+}
+
+static int das16m1_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: das16m1: remove\n", dev->minor);
+
+//      das16m1_reset(dev);
+
+	if (dev->subdevices)
+		subdev_8255_cleanup(dev, dev->subdevices + 3);
+
+	if (dev->irq)
+		comedi_free_irq(dev->irq, dev);
+
+	if (dev->iobase) {
+		release_region(dev->iobase, DAS16M1_SIZE);
+		release_region(dev->iobase + DAS16M1_82C55, DAS16M1_SIZE2);
+	}
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c
new file mode 100644
index 0000000..cd4cd4e
--- /dev/null
+++ b/drivers/staging/comedi/drivers/das1800.c
@@ -0,0 +1,1758 @@
+/*
+    comedi/drivers/das1800.c
+    Driver for Keitley das1700/das1800 series boards
+    Copyright (C) 2000 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000 David A. Schleef <ds@schleef.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.
+
+    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.
+
+************************************************************************
+*/
+/*
+Driver: das1800
+Description: Keithley Metrabyte DAS1800 (& compatibles)
+Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+Devices: [Keithley Metrabyte] DAS-1701ST (das-1701st),
+  DAS-1701ST-DA (das-1701st-da), DAS-1701/AO (das-1701ao),
+  DAS-1702ST (das-1702st), DAS-1702ST-DA (das-1702st-da),
+  DAS-1702HR (das-1702hr), DAS-1702HR-DA (das-1702hr-da),
+  DAS-1702/AO (das-1702ao), DAS-1801ST (das-1801st),
+  DAS-1801ST-DA (das-1801st-da), DAS-1801HC (das-1801hc),
+  DAS-1801AO (das-1801ao), DAS-1802ST (das-1802st),
+  DAS-1802ST-DA (das-1802st-da), DAS-1802HR (das-1802hr),
+  DAS-1802HR-DA (das-1802hr-da), DAS-1802HC (das-1802hc),
+  DAS-1802AO (das-1802ao)
+Status: works
+
+The waveform analog output on the 'ao' cards is not supported.
+If you need it, send me (Frank Hess) an email.
+
+Configuration options:
+  [0] - I/O port base address
+  [1] - IRQ (optional, required for timed or externally triggered conversions)
+  [2] - DMA0 (optional, requires irq)
+  [3] - DMA1 (optional, requires irq and dma0)
+*/
+/*
+
+This driver supports the following Keithley boards:
+
+das-1701st
+das-1701st-da
+das-1701ao
+das-1702st
+das-1702st-da
+das-1702hr
+das-1702hr-da
+das-1702ao
+das-1801st
+das-1801st-da
+das-1801hc
+das-1801ao
+das-1802st
+das-1802st-da
+das-1802hr
+das-1802hr-da
+das-1802hc
+das-1802ao
+
+Options:
+	[0] - base io address
+	[1] - irq (optional, required for timed or externally triggered conversions)
+	[2] - dma0 (optional, requires irq)
+	[3] - dma1 (optional, requires irq and dma0)
+
+irq can be omitted, although the cmd interface will not work without it.
+
+analog input cmd triggers supported:
+	start_src:      TRIG_NOW | TRIG_EXT
+	scan_begin_src: TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT
+	scan_end_src:   TRIG_COUNT
+	convert_src:    TRIG_TIMER | TRIG_EXT (TRIG_EXT requires scan_begin_src == TRIG_FOLLOW)
+	stop_src:       TRIG_COUNT | TRIG_EXT | TRIG_NONE
+
+scan_begin_src triggers TRIG_TIMER and TRIG_EXT use the card's
+'burst mode' which limits the valid conversion time to 64 microseconds
+(convert_arg <= 64000).  This limitation does not apply if scan_begin_src
+is TRIG_FOLLOW.
+
+NOTES:
+Only the DAS-1801ST has been tested by me.
+Unipolar and bipolar ranges cannot be mixed in the channel/gain list.
+
+TODO:
+	Make it automatically allocate irq and dma channels if they are not specified
+	Add support for analog out on 'ao' cards
+	read insn for analog out
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <asm/dma.h>
+
+#include "8253.h"
+#include "comedi_fc.h"
+
+// misc. defines
+#define DAS1800_SIZE           16	//uses 16 io addresses
+#define FIFO_SIZE              1024	// 1024 sample fifo
+#define TIMER_BASE             200	// 5 Mhz master clock
+#define UNIPOLAR               0x4	// bit that determines whether input range is uni/bipolar
+#define DMA_BUF_SIZE           0x1ff00	// size in bytes of dma buffers
+
+/* Registers for the das1800 */
+#define DAS1800_FIFO            0x0
+#define DAS1800_QRAM            0x0
+#define DAS1800_DAC             0x0
+#define DAS1800_SELECT          0x2
+#define   ADC                     0x0
+#define   QRAM                    0x1
+#define   DAC(a)                  (0x2 + a)
+#define DAS1800_DIGITAL         0x3
+#define DAS1800_CONTROL_A       0x4
+#define   FFEN                    0x1
+#define   CGEN                    0x4
+#define   CGSL                    0x8
+#define   TGEN                    0x10
+#define   TGSL                    0x20
+#define   ATEN                    0x80
+#define DAS1800_CONTROL_B       0x5
+#define   DMA_CH5                 0x1
+#define   DMA_CH6                 0x2
+#define   DMA_CH7                 0x3
+#define   DMA_CH5_CH6             0x5
+#define   DMA_CH6_CH7             0x6
+#define   DMA_CH7_CH5             0x7
+#define   DMA_ENABLED             0x3	//mask used to determine if dma is enabled
+#define   DMA_DUAL                0x4
+#define   IRQ3                    0x8
+#define   IRQ5                    0x10
+#define   IRQ7                    0x18
+#define   IRQ10                   0x28
+#define   IRQ11                   0x30
+#define   IRQ15                   0x38
+#define   FIMD                    0x40
+#define DAS1800_CONTROL_C       0X6
+#define   IPCLK                   0x1
+#define   XPCLK                   0x3
+#define   BMDE                    0x4
+#define   CMEN                    0x8
+#define   UQEN                    0x10
+#define   SD                      0x40
+#define   UB                      0x80
+#define DAS1800_STATUS          0x7
+// bits that prevent interrupt status bits (and CVEN) from being cleared on write
+#define   CLEAR_INTR_MASK         (CVEN_MASK | 0x1f)
+#define   INT                     0x1
+#define   DMATC                   0x2
+#define   CT0TC                   0x8
+#define   OVF                     0x10
+#define   FHF                     0x20
+#define   FNE                     0x40
+#define   CVEN_MASK               0x40	// masks CVEN on write
+#define   CVEN                    0x80
+#define DAS1800_BURST_LENGTH    0x8
+#define DAS1800_BURST_RATE      0x9
+#define DAS1800_QRAM_ADDRESS    0xa
+#define DAS1800_COUNTER         0xc
+
+#define IOBASE2                   0x400	//offset of additional ioports used on 'ao' cards
+
+enum {
+	das1701st, das1701st_da, das1702st, das1702st_da, das1702hr,
+	das1702hr_da,
+	das1701ao, das1702ao, das1801st, das1801st_da, das1802st, das1802st_da,
+	das1802hr, das1802hr_da, das1801hc, das1802hc, das1801ao, das1802ao
+};
+
+static int das1800_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int das1800_detach(struct comedi_device * dev);
+static int das1800_probe(struct comedi_device * dev);
+static int das1800_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static irqreturn_t das1800_interrupt(int irq, void *d PT_REGS_ARG);
+static int das1800_ai_poll(struct comedi_device * dev, struct comedi_subdevice * s);
+static void das1800_ai_handler(struct comedi_device * dev);
+static void das1800_handle_dma(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int status);
+static void das1800_flush_dma(struct comedi_device * dev, struct comedi_subdevice * s);
+static void das1800_flush_dma_channel(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int channel, uint16_t * buffer);
+static void das1800_handle_fifo_half_full(struct comedi_device * dev,
+	struct comedi_subdevice * s);
+static void das1800_handle_fifo_not_empty(struct comedi_device * dev,
+	struct comedi_subdevice * s);
+static int das1800_ai_do_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd);
+static int das1800_ai_do_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int das1800_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int das1800_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int das1800_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int das1800_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+static int das1800_set_frequency(struct comedi_device * dev);
+static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode);
+static unsigned int suggest_transfer_size(struct comedi_cmd * cmd);
+
+// analog input ranges
+static const struct comedi_lrange range_ai_das1801 = {
+	8,
+	{
+			RANGE(-5, 5),
+			RANGE(-1, 1),
+			RANGE(-0.1, 0.1),
+			RANGE(-0.02, 0.02),
+			RANGE(0, 5),
+			RANGE(0, 1),
+			RANGE(0, 0.1),
+			RANGE(0, 0.02),
+		}
+};
+
+static const struct comedi_lrange range_ai_das1802 = {
+	8,
+	{
+			RANGE(-10, 10),
+			RANGE(-5, 5),
+			RANGE(-2.5, 2.5),
+			RANGE(-1.25, 1.25),
+			RANGE(0, 10),
+			RANGE(0, 5),
+			RANGE(0, 2.5),
+			RANGE(0, 1.25),
+		}
+};
+
+struct das1800_board {
+	const char *name;
+	int ai_speed;		/* max conversion period in nanoseconds */
+	int resolution;		/* bits of ai resolution */
+	int qram_len;		/* length of card's channel / gain queue */
+	int common;		/* supports AREF_COMMON flag */
+	int do_n_chan;		/* number of digital output channels */
+	int ao_ability;		/* 0 == no analog out, 1 == basic analog out, 2 == waveform analog out */
+	int ao_n_chan;		/* number of analog out channels */
+	const struct comedi_lrange *range_ai;	/* available input ranges */
+};
+
+/* Warning: the maximum conversion speeds listed below are
+ * not always achievable depending on board setup (see
+ * user manual.)
+ */
+static const struct das1800_board das1800_boards[] = {
+	{
+	      name:	"das-1701st",
+	      ai_speed:6250,
+	      resolution:12,
+	      qram_len:256,
+	      common:	1,
+	      do_n_chan:4,
+	      ao_ability:0,
+	      ao_n_chan:0,
+	      range_ai:&range_ai_das1801,
+		},
+	{
+	      name:	"das-1701st-da",
+	      ai_speed:6250,
+	      resolution:12,
+	      qram_len:256,
+	      common:	1,
+	      do_n_chan:4,
+	      ao_ability:1,
+	      ao_n_chan:4,
+	      range_ai:&range_ai_das1801,
+		},
+	{
+	      name:	"das-1702st",
+	      ai_speed:6250,
+	      resolution:12,
+	      qram_len:256,
+	      common:	1,
+	      do_n_chan:4,
+	      ao_ability:0,
+	      ao_n_chan:0,
+	      range_ai:&range_ai_das1802,
+		},
+	{
+	      name:	"das-1702st-da",
+	      ai_speed:6250,
+	      resolution:12,
+	      qram_len:256,
+	      common:	1,
+	      do_n_chan:4,
+	      ao_ability:1,
+	      ao_n_chan:4,
+	      range_ai:&range_ai_das1802,
+		},
+	{
+	      name:	"das-1702hr",
+	      ai_speed:20000,
+	      resolution:16,
+	      qram_len:256,
+	      common:	1,
+	      do_n_chan:4,
+	      ao_ability:0,
+	      ao_n_chan:0,
+	      range_ai:&range_ai_das1802,
+		},
+	{
+	      name:	"das-1702hr-da",
+	      ai_speed:20000,
+	      resolution:16,
+	      qram_len:256,
+	      common:	1,
+	      do_n_chan:4,
+	      ao_ability:1,
+	      ao_n_chan:2,
+	      range_ai:&range_ai_das1802,
+		},
+	{
+	      name:	"das-1701ao",
+	      ai_speed:6250,
+	      resolution:12,
+	      qram_len:256,
+	      common:	1,
+	      do_n_chan:4,
+	      ao_ability:2,
+	      ao_n_chan:2,
+	      range_ai:&range_ai_das1801,
+		},
+	{
+	      name:	"das-1702ao",
+	      ai_speed:6250,
+	      resolution:12,
+	      qram_len:256,
+	      common:	1,
+	      do_n_chan:4,
+	      ao_ability:2,
+	      ao_n_chan:2,
+	      range_ai:&range_ai_das1802,
+		},
+	{
+	      name:	"das-1801st",
+	      ai_speed:3000,
+	      resolution:12,
+	      qram_len:256,
+	      common:	1,
+	      do_n_chan:4,
+	      ao_ability:0,
+	      ao_n_chan:0,
+	      range_ai:&range_ai_das1801,
+		},
+	{
+	      name:	"das-1801st-da",
+	      ai_speed:3000,
+	      resolution:12,
+	      qram_len:256,
+	      common:	1,
+	      do_n_chan:4,
+	      ao_ability:0,
+	      ao_n_chan:4,
+	      range_ai:&range_ai_das1801,
+		},
+	{
+	      name:	"das-1802st",
+	      ai_speed:3000,
+	      resolution:12,
+	      qram_len:256,
+	      common:	1,
+	      do_n_chan:4,
+	      ao_ability:0,
+	      ao_n_chan:0,
+	      range_ai:&range_ai_das1802,
+		},
+	{
+	      name:	"das-1802st-da",
+	      ai_speed:3000,
+	      resolution:12,
+	      qram_len:256,
+	      common:	1,
+	      do_n_chan:4,
+	      ao_ability:1,
+	      ao_n_chan:4,
+	      range_ai:&range_ai_das1802,
+		},
+	{
+	      name:	"das-1802hr",
+	      ai_speed:10000,
+	      resolution:16,
+	      qram_len:256,
+	      common:	1,
+	      do_n_chan:4,
+	      ao_ability:0,
+	      ao_n_chan:0,
+	      range_ai:&range_ai_das1802,
+		},
+	{
+	      name:	"das-1802hr-da",
+	      ai_speed:10000,
+	      resolution:16,
+	      qram_len:256,
+	      common:	1,
+	      do_n_chan:4,
+	      ao_ability:1,
+	      ao_n_chan:2,
+	      range_ai:&range_ai_das1802,
+		},
+	{
+	      name:	"das-1801hc",
+	      ai_speed:3000,
+	      resolution:12,
+	      qram_len:64,
+	      common:	0,
+	      do_n_chan:8,
+	      ao_ability:1,
+	      ao_n_chan:2,
+	      range_ai:&range_ai_das1801,
+		},
+	{
+	      name:	"das-1802hc",
+	      ai_speed:3000,
+	      resolution:12,
+	      qram_len:64,
+	      common:	0,
+	      do_n_chan:8,
+	      ao_ability:1,
+	      ao_n_chan:2,
+	      range_ai:&range_ai_das1802,
+		},
+	{
+	      name:	"das-1801ao",
+	      ai_speed:3000,
+	      resolution:12,
+	      qram_len:256,
+	      common:	1,
+	      do_n_chan:4,
+	      ao_ability:2,
+	      ao_n_chan:2,
+	      range_ai:&range_ai_das1801,
+		},
+	{
+	      name:	"das-1802ao",
+	      ai_speed:3000,
+	      resolution:12,
+	      qram_len:256,
+	      common:	1,
+	      do_n_chan:4,
+	      ao_ability:2,
+	      ao_n_chan:2,
+	      range_ai:&range_ai_das1802,
+		},
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct das1800_board *)dev->board_ptr)
+
+struct das1800_private {
+	volatile unsigned int count;	/* number of data points left to be taken */
+	unsigned int divisor1;	/* value to load into board's counter 1 for timed conversions */
+	unsigned int divisor2;	/* value to load into board's counter 2 for timed conversions */
+	int do_bits;		/* digital output bits */
+	int irq_dma_bits;	/* bits for control register b */
+	/* dma bits for control register b, stored so that dma can be
+	 * turned on and off */
+	int dma_bits;
+	unsigned int dma0;	/* dma channels used */
+	unsigned int dma1;
+	volatile unsigned int dma_current;	/* dma channel currently in use */
+	uint16_t *ai_buf0;	/* pointers to dma buffers */
+	uint16_t *ai_buf1;
+	uint16_t *dma_current_buf;	/* pointer to dma buffer currently being used */
+	unsigned int dma_transfer_size;	/* size of transfer currently used, in bytes */
+	unsigned long iobase2;	/* secondary io address used for analog out on 'ao' boards */
+	short ao_update_bits;	/* remembers the last write to the 'update' dac */
+};
+
+#define devpriv ((struct das1800_private *)dev->private)
+
+// analog out range for boards with basic analog out
+static const struct comedi_lrange range_ao_1 = {
+	1,
+	{
+			RANGE(-10, 10),
+		}
+};
+
+// analog out range for 'ao' boards
+/*
+static const struct comedi_lrange range_ao_2 = {
+	2,
+	{
+		RANGE(-10, 10),
+		RANGE(-5, 5),
+	}
+};
+*/
+
+static struct comedi_driver driver_das1800 = {
+      driver_name:"das1800",
+      module:THIS_MODULE,
+      attach:das1800_attach,
+      detach:das1800_detach,
+      num_names:sizeof(das1800_boards) / sizeof(struct das1800_board),
+      board_name:&das1800_boards[0].name,
+      offset:sizeof(struct das1800_board),
+};
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver_das1800);
+
+static int das1800_init_dma(struct comedi_device * dev, unsigned int dma0,
+	unsigned int dma1)
+{
+	unsigned long flags;
+
+	// need an irq to do dma
+	if (dev->irq && dma0) {
+		//encode dma0 and dma1 into 2 digit hexadecimal for switch
+		switch ((dma0 & 0x7) | (dma1 << 4)) {
+		case 0x5:	// dma0 == 5
+			devpriv->dma_bits |= DMA_CH5;
+			break;
+		case 0x6:	// dma0 == 6
+			devpriv->dma_bits |= DMA_CH6;
+			break;
+		case 0x7:	// dma0 == 7
+			devpriv->dma_bits |= DMA_CH7;
+			break;
+		case 0x65:	// dma0 == 5, dma1 == 6
+			devpriv->dma_bits |= DMA_CH5_CH6;
+			break;
+		case 0x76:	// dma0 == 6, dma1 == 7
+			devpriv->dma_bits |= DMA_CH6_CH7;
+			break;
+		case 0x57:	// dma0 == 7, dma1 == 5
+			devpriv->dma_bits |= DMA_CH7_CH5;
+			break;
+		default:
+			printk(" only supports dma channels 5 through 7\n"
+				" Dual dma only allows the following combinations:\n"
+				" dma 5,6 / 6,7 / or 7,5\n");
+			return -EINVAL;
+			break;
+		}
+		if (request_dma(dma0, driver_das1800.driver_name)) {
+			printk(" failed to allocate dma channel %i\n", dma0);
+			return -EINVAL;
+		}
+		devpriv->dma0 = dma0;
+		devpriv->dma_current = dma0;
+		if (dma1) {
+			if (request_dma(dma1, driver_das1800.driver_name)) {
+				printk(" failed to allocate dma channel %i\n",
+					dma1);
+				return -EINVAL;
+			}
+			devpriv->dma1 = dma1;
+		}
+		devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
+		if (devpriv->ai_buf0 == NULL)
+			return -ENOMEM;
+		devpriv->dma_current_buf = devpriv->ai_buf0;
+		if (dma1) {
+			devpriv->ai_buf1 =
+				kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
+			if (devpriv->ai_buf1 == NULL)
+				return -ENOMEM;
+		}
+		flags = claim_dma_lock();
+		disable_dma(devpriv->dma0);
+		set_dma_mode(devpriv->dma0, DMA_MODE_READ);
+		if (dma1) {
+			disable_dma(devpriv->dma1);
+			set_dma_mode(devpriv->dma1, DMA_MODE_READ);
+		}
+		release_dma_lock(flags);
+	}
+	return 0;
+}
+
+static int das1800_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	unsigned long iobase = it->options[0];
+	unsigned int irq = it->options[1];
+	unsigned int dma0 = it->options[2];
+	unsigned int dma1 = it->options[3];
+	unsigned long iobase2;
+	int board;
+	int retval;
+
+	/* allocate and initialize dev->private */
+	if (alloc_private(dev, sizeof(struct das1800_private)) < 0)
+		return -ENOMEM;
+
+	printk("comedi%d: %s: io 0x%lx", dev->minor, driver_das1800.driver_name,
+		iobase);
+	if (irq) {
+		printk(", irq %u", irq);
+		if (dma0) {
+			printk(", dma %u", dma0);
+			if (dma1)
+				printk(" and %u", dma1);
+		}
+	}
+	printk("\n");
+
+	if (iobase == 0) {
+		printk(" io base address required\n");
+		return -EINVAL;
+	}
+
+	/* check if io addresses are available */
+	if (!request_region(iobase, DAS1800_SIZE, driver_das1800.driver_name)) {
+		printk(" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", iobase, iobase + DAS1800_SIZE - 1);
+		return -EIO;
+	}
+	dev->iobase = iobase;
+
+	board = das1800_probe(dev);
+	if (board < 0) {
+		printk(" unable to determine board type\n");
+		return -ENODEV;
+	}
+
+	dev->board_ptr = das1800_boards + board;
+	dev->board_name = thisboard->name;
+
+	// if it is an 'ao' board with fancy analog out then we need extra io ports
+	if (thisboard->ao_ability == 2) {
+		iobase2 = iobase + IOBASE2;
+		if (!request_region(iobase2, DAS1800_SIZE,
+				driver_das1800.driver_name)) {
+			printk(" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", iobase2, iobase2 + DAS1800_SIZE - 1);
+			return -EIO;
+		}
+		devpriv->iobase2 = iobase2;
+	}
+
+	/* grab our IRQ */
+	if (irq) {
+		if (comedi_request_irq(irq, das1800_interrupt, 0,
+				driver_das1800.driver_name, dev)) {
+			printk(" unable to allocate irq %u\n", irq);
+			return -EINVAL;
+		}
+	}
+	dev->irq = irq;
+
+	// set bits that tell card which irq to use
+	switch (irq) {
+	case 0:
+		break;
+	case 3:
+		devpriv->irq_dma_bits |= 0x8;
+		break;
+	case 5:
+		devpriv->irq_dma_bits |= 0x10;
+		break;
+	case 7:
+		devpriv->irq_dma_bits |= 0x18;
+		break;
+	case 10:
+		devpriv->irq_dma_bits |= 0x28;
+		break;
+	case 11:
+		devpriv->irq_dma_bits |= 0x30;
+		break;
+	case 15:
+		devpriv->irq_dma_bits |= 0x38;
+		break;
+	default:
+		printk(" irq out of range\n");
+		return -EINVAL;
+		break;
+	}
+
+	retval = das1800_init_dma(dev, dma0, dma1);
+	if (retval < 0)
+		return retval;
+
+	if (devpriv->ai_buf0 == NULL) {
+		devpriv->ai_buf0 =
+			kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL);
+		if (devpriv->ai_buf0 == NULL)
+			return -ENOMEM;
+	}
+
+	if (alloc_subdevices(dev, 4) < 0)
+		return -ENOMEM;
+
+	/* analog input subdevice */
+	s = dev->subdevices + 0;
+	dev->read_subdev = s;
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND | SDF_CMD_READ;
+	if (thisboard->common)
+		s->subdev_flags |= SDF_COMMON;
+	s->n_chan = thisboard->qram_len;
+	s->len_chanlist = thisboard->qram_len;
+	s->maxdata = (1 << thisboard->resolution) - 1;
+	s->range_table = thisboard->range_ai;
+	s->do_cmd = das1800_ai_do_cmd;
+	s->do_cmdtest = das1800_ai_do_cmdtest;
+	s->insn_read = das1800_ai_rinsn;
+	s->poll = das1800_ai_poll;
+	s->cancel = das1800_cancel;
+
+	/* analog out */
+	s = dev->subdevices + 1;
+	if (thisboard->ao_ability == 1) {
+		s->type = COMEDI_SUBD_AO;
+		s->subdev_flags = SDF_WRITABLE;
+		s->n_chan = thisboard->ao_n_chan;
+		s->maxdata = (1 << thisboard->resolution) - 1;
+		s->range_table = &range_ao_1;
+		s->insn_write = das1800_ao_winsn;
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	/* di */
+	s = dev->subdevices + 2;
+	s->type = COMEDI_SUBD_DI;
+	s->subdev_flags = SDF_READABLE;
+	s->n_chan = 4;
+	s->maxdata = 1;
+	s->range_table = &range_digital;
+	s->insn_bits = das1800_di_rbits;
+
+	/* do */
+	s = dev->subdevices + 3;
+	s->type = COMEDI_SUBD_DO;
+	s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+	s->n_chan = thisboard->do_n_chan;
+	s->maxdata = 1;
+	s->range_table = &range_digital;
+	s->insn_bits = das1800_do_wbits;
+
+	das1800_cancel(dev, dev->read_subdev);
+
+	// initialize digital out channels
+	outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
+
+	// initialize analog out channels
+	if (thisboard->ao_ability == 1) {
+		// select 'update' dac channel for baseAddress + 0x0
+		outb(DAC(thisboard->ao_n_chan - 1),
+			dev->iobase + DAS1800_SELECT);
+		outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
+	}
+
+	return 0;
+};
+
+static int das1800_detach(struct comedi_device * dev)
+{
+	/* only free stuff if it has been allocated by _attach */
+	if (dev->iobase)
+		release_region(dev->iobase, DAS1800_SIZE);
+	if (dev->irq)
+		comedi_free_irq(dev->irq, dev);
+	if (dev->private) {
+		if (devpriv->iobase2)
+			release_region(devpriv->iobase2, DAS1800_SIZE);
+		if (devpriv->dma0)
+			free_dma(devpriv->dma0);
+		if (devpriv->dma1)
+			free_dma(devpriv->dma1);
+		if (devpriv->ai_buf0)
+			kfree(devpriv->ai_buf0);
+		if (devpriv->ai_buf1)
+			kfree(devpriv->ai_buf1);
+	}
+
+	printk("comedi%d: %s: remove\n", dev->minor,
+		driver_das1800.driver_name);
+
+	return 0;
+};
+
+/* probes and checks das-1800 series board type
+ */
+static int das1800_probe(struct comedi_device * dev)
+{
+	int id;
+	int board;
+
+	id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf;	/* get id bits */
+	board = ((struct das1800_board *) dev->board_ptr) - das1800_boards;
+
+	switch (id) {
+	case 0x3:
+		if (board == das1801st_da || board == das1802st_da ||
+			board == das1701st_da || board == das1702st_da) {
+			printk(" Board model: %s\n",
+				das1800_boards[board].name);
+			return board;
+		}
+		printk(" Board model (probed, not recommended): das-1800st-da series\n");
+		return das1801st;
+		break;
+	case 0x4:
+		if (board == das1802hr_da || board == das1702hr_da) {
+			printk(" Board model: %s\n",
+				das1800_boards[board].name);
+			return board;
+		}
+		printk(" Board model (probed, not recommended): das-1802hr-da\n");
+		return das1802hr;
+		break;
+	case 0x5:
+		if (board == das1801ao || board == das1802ao ||
+			board == das1701ao || board == das1702ao) {
+			printk(" Board model: %s\n",
+				das1800_boards[board].name);
+			return board;
+		}
+		printk(" Board model (probed, not recommended): das-1800ao series\n");
+		return das1801ao;
+		break;
+	case 0x6:
+		if (board == das1802hr || board == das1702hr) {
+			printk(" Board model: %s\n",
+				das1800_boards[board].name);
+			return board;
+		}
+		printk(" Board model (probed, not recommended): das-1802hr\n");
+		return das1802hr;
+		break;
+	case 0x7:
+		if (board == das1801st || board == das1802st ||
+			board == das1701st || board == das1702st) {
+			printk(" Board model: %s\n",
+				das1800_boards[board].name);
+			return board;
+		}
+		printk(" Board model (probed, not recommended): das-1800st series\n");
+		return das1801st;
+		break;
+	case 0x8:
+		if (board == das1801hc || board == das1802hc) {
+			printk(" Board model: %s\n",
+				das1800_boards[board].name);
+			return board;
+		}
+		printk(" Board model (probed, not recommended): das-1800hc series\n");
+		return das1801hc;
+		break;
+	default:
+		printk(" Board model: probe returned 0x%x (unknown, please report)\n", id);
+		return board;
+		break;
+	}
+	return -1;
+}
+
+static int das1800_ai_poll(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	unsigned long flags;
+
+	// prevent race with interrupt handler
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	das1800_ai_handler(dev);
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	return s->async->buf_write_count - s->async->buf_read_count;
+}
+
+static irqreturn_t das1800_interrupt(int irq, void *d PT_REGS_ARG)
+{
+	struct comedi_device *dev = d;
+	unsigned int status;
+
+	if (dev->attached == 0) {
+		comedi_error(dev, "premature interrupt");
+		return IRQ_HANDLED;
+	}
+
+	/* Prevent race with das1800_ai_poll() on multi processor systems.
+	 * Also protects indirect addressing in das1800_ai_handler */
+	spin_lock(&dev->spinlock);
+	status = inb(dev->iobase + DAS1800_STATUS);
+
+	/* if interrupt was not caused by das-1800 */
+	if (!(status & INT)) {
+		spin_unlock(&dev->spinlock);
+		return IRQ_NONE;
+	}
+	/* clear the interrupt status bit INT */
+	outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS);
+	// handle interrupt
+	das1800_ai_handler(dev);
+
+	spin_unlock(&dev->spinlock);
+	return IRQ_HANDLED;
+}
+
+// the guts of the interrupt handler, that is shared with das1800_ai_poll
+static void das1800_ai_handler(struct comedi_device * dev)
+{
+	struct comedi_subdevice *s = dev->subdevices + 0;	/* analog input subdevice */
+	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+	unsigned int status = inb(dev->iobase + DAS1800_STATUS);
+
+	async->events = 0;
+	// select adc for base address + 0
+	outb(ADC, dev->iobase + DAS1800_SELECT);
+	// dma buffer full
+	if (devpriv->irq_dma_bits & DMA_ENABLED) {
+		// look for data from dma transfer even if dma terminal count hasn't happened yet
+		das1800_handle_dma(dev, s, status);
+	} else if (status & FHF) {	// if fifo half full
+		das1800_handle_fifo_half_full(dev, s);
+	} else if (status & FNE) {	// if fifo not empty
+		das1800_handle_fifo_not_empty(dev, s);
+	}
+
+	async->events |= COMEDI_CB_BLOCK;
+	/* if the card's fifo has overflowed */
+	if (status & OVF) {
+		// clear OVF interrupt bit
+		outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS);
+		comedi_error(dev, "DAS1800 FIFO overflow");
+		das1800_cancel(dev, s);
+		async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+		comedi_event(dev, s);
+		return;
+	}
+	// stop taking data if appropriate
+	/* stop_src TRIG_EXT */
+	if (status & CT0TC) {
+		// clear CT0TC interrupt bit
+		outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS);
+		// make sure we get all remaining data from board before quitting
+		if (devpriv->irq_dma_bits & DMA_ENABLED)
+			das1800_flush_dma(dev, s);
+		else
+			das1800_handle_fifo_not_empty(dev, s);
+		das1800_cancel(dev, s);	/* disable hardware conversions */
+		async->events |= COMEDI_CB_EOA;
+	} else if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) {	// stop_src TRIG_COUNT
+		das1800_cancel(dev, s);	/* disable hardware conversions */
+		async->events |= COMEDI_CB_EOA;
+	}
+
+	comedi_event(dev, s);
+
+	return;
+}
+
+static void das1800_handle_dma(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int status)
+{
+	unsigned long flags;
+	const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
+
+	flags = claim_dma_lock();
+	das1800_flush_dma_channel(dev, s, devpriv->dma_current,
+		devpriv->dma_current_buf);
+	// re-enable  dma channel
+	set_dma_addr(devpriv->dma_current,
+		virt_to_bus(devpriv->dma_current_buf));
+	set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size);
+	enable_dma(devpriv->dma_current);
+	release_dma_lock(flags);
+
+	if (status & DMATC) {
+		// clear DMATC interrupt bit
+		outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS);
+		// switch dma channels for next time, if appropriate
+		if (dual_dma) {
+			// read data from the other channel next time
+			if (devpriv->dma_current == devpriv->dma0) {
+				devpriv->dma_current = devpriv->dma1;
+				devpriv->dma_current_buf = devpriv->ai_buf1;
+			} else {
+				devpriv->dma_current = devpriv->dma0;
+				devpriv->dma_current_buf = devpriv->ai_buf0;
+			}
+		}
+	}
+
+	return;
+}
+
+static inline uint16_t munge_bipolar_sample(const struct comedi_device * dev,
+	uint16_t sample)
+{
+	sample += 1 << (thisboard->resolution - 1);
+	return sample;
+}
+
+static void munge_data(struct comedi_device * dev, uint16_t * array,
+	unsigned int num_elements)
+{
+	unsigned int i;
+	int unipolar;
+
+	/* see if card is using a unipolar or bipolar range so we can munge data correctly */
+	unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
+
+	/* convert to unsigned type if we are in a bipolar mode */
+	if (!unipolar) {
+		for (i = 0; i < num_elements; i++) {
+			array[i] = munge_bipolar_sample(dev, array[i]);
+		}
+	}
+}
+
+/* Utility function used by das1800_flush_dma() and das1800_handle_dma().
+ * Assumes dma lock is held */
+static void das1800_flush_dma_channel(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int channel, uint16_t * buffer)
+{
+	unsigned int num_bytes, num_samples;
+	struct comedi_cmd *cmd = &s->async->cmd;
+
+	disable_dma(channel);
+
+	/* clear flip-flop to make sure 2-byte registers
+	 * get set correctly */
+	clear_dma_ff(channel);
+
+	// figure out how many points to read
+	num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel);
+	num_samples = num_bytes / sizeof(short);
+
+	/* if we only need some of the points */
+	if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples)
+		num_samples = devpriv->count;
+
+	munge_data(dev, buffer, num_samples);
+	cfc_write_array_to_buffer(s, buffer, num_bytes);
+	if (s->async->cmd.stop_src == TRIG_COUNT)
+		devpriv->count -= num_samples;
+
+	return;
+}
+
+/* flushes remaining data from board when external trigger has stopped aquisition
+ * and we are using dma transfers */
+static void das1800_flush_dma(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	unsigned long flags;
+	const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
+
+	flags = claim_dma_lock();
+	das1800_flush_dma_channel(dev, s, devpriv->dma_current,
+		devpriv->dma_current_buf);
+
+	if (dual_dma) {
+		// switch to other channel and flush it
+		if (devpriv->dma_current == devpriv->dma0) {
+			devpriv->dma_current = devpriv->dma1;
+			devpriv->dma_current_buf = devpriv->ai_buf1;
+		} else {
+			devpriv->dma_current = devpriv->dma0;
+			devpriv->dma_current_buf = devpriv->ai_buf0;
+		}
+		das1800_flush_dma_channel(dev, s, devpriv->dma_current,
+			devpriv->dma_current_buf);
+	}
+
+	release_dma_lock(flags);
+
+	// get any remaining samples in fifo
+	das1800_handle_fifo_not_empty(dev, s);
+
+	return;
+}
+
+static void das1800_handle_fifo_half_full(struct comedi_device * dev,
+	struct comedi_subdevice * s)
+{
+	int numPoints = 0;	/* number of points to read */
+	struct comedi_cmd *cmd = &s->async->cmd;
+
+	numPoints = FIFO_SIZE / 2;
+	/* if we only need some of the points */
+	if (cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints)
+		numPoints = devpriv->count;
+	insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints);
+	munge_data(dev, devpriv->ai_buf0, numPoints);
+	cfc_write_array_to_buffer(s, devpriv->ai_buf0,
+		numPoints * sizeof(devpriv->ai_buf0[0]));
+	if (cmd->stop_src == TRIG_COUNT)
+		devpriv->count -= numPoints;
+	return;
+}
+
+static void das1800_handle_fifo_not_empty(struct comedi_device * dev,
+	struct comedi_subdevice * s)
+{
+	short dpnt;
+	int unipolar;
+	struct comedi_cmd *cmd = &s->async->cmd;
+
+	unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
+
+	while (inb(dev->iobase + DAS1800_STATUS) & FNE) {
+		if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0)
+			break;
+		dpnt = inw(dev->iobase + DAS1800_FIFO);
+		/* convert to unsigned type if we are in a bipolar mode */
+		if (!unipolar) ;
+		dpnt = munge_bipolar_sample(dev, dpnt);
+		cfc_write_to_buffer(s, dpnt);
+		if (cmd->stop_src == TRIG_COUNT)
+			devpriv->count--;
+	}
+
+	return;
+}
+
+static int das1800_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	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 */
+	if (devpriv->dma0)
+		disable_dma(devpriv->dma0);
+	if (devpriv->dma1)
+		disable_dma(devpriv->dma1);
+	return 0;
+}
+
+/* test analog input cmd */
+static int das1800_ai_do_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp;
+	unsigned int tmp_arg;
+	int i;
+	int unipolar;
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW | TRIG_EXT;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	// uniqueness check
+	if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
+		err++;
+	if (cmd->scan_begin_src != TRIG_FOLLOW &&
+		cmd->scan_begin_src != TRIG_TIMER &&
+		cmd->scan_begin_src != TRIG_EXT)
+		err++;
+	if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+		err++;
+	if (cmd->stop_src != TRIG_COUNT &&
+		cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT)
+		err++;
+	//compatibility check
+	if (cmd->scan_begin_src != TRIG_FOLLOW &&
+		cmd->convert_src != TRIG_TIMER)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+	if (cmd->convert_src == TRIG_TIMER) {
+		if (cmd->convert_arg < thisboard->ai_speed) {
+			cmd->convert_arg = thisboard->ai_speed;
+			err++;
+		}
+	}
+	if (!cmd->chanlist_len) {
+		cmd->chanlist_len = 1;
+		err++;
+	}
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+
+	switch (cmd->stop_src) {
+	case TRIG_COUNT:
+		if (!cmd->stop_arg) {
+			cmd->stop_arg = 1;
+			err++;
+		}
+		break;
+	case TRIG_NONE:
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+		break;
+	default:
+		break;
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	if (cmd->convert_src == TRIG_TIMER) {
+		// if we are not in burst mode
+		if (cmd->scan_begin_src == TRIG_FOLLOW) {
+			tmp_arg = cmd->convert_arg;
+			/* calculate counter values that give desired timing */
+			i8253_cascade_ns_to_timer_2div(TIMER_BASE,
+				&(devpriv->divisor1), &(devpriv->divisor2),
+				&(cmd->convert_arg),
+				cmd->flags & TRIG_ROUND_MASK);
+			if (tmp_arg != cmd->convert_arg)
+				err++;
+		}
+		// if we are in burst mode
+		else {
+			// check that convert_arg is compatible
+			tmp_arg = cmd->convert_arg;
+			cmd->convert_arg =
+				burst_convert_arg(cmd->convert_arg,
+				cmd->flags & TRIG_ROUND_MASK);
+			if (tmp_arg != cmd->convert_arg)
+				err++;
+
+			if (cmd->scan_begin_src == TRIG_TIMER) {
+				// if scans are timed faster than conversion rate allows
+				if (cmd->convert_arg * cmd->chanlist_len >
+					cmd->scan_begin_arg) {
+					cmd->scan_begin_arg =
+						cmd->convert_arg *
+						cmd->chanlist_len;
+					err++;
+				}
+				tmp_arg = cmd->scan_begin_arg;
+				/* calculate counter values that give desired timing */
+				i8253_cascade_ns_to_timer_2div(TIMER_BASE,
+					&(devpriv->divisor1),
+					&(devpriv->divisor2),
+					&(cmd->scan_begin_arg),
+					cmd->flags & TRIG_ROUND_MASK);
+				if (tmp_arg != cmd->scan_begin_arg)
+					err++;
+			}
+		}
+	}
+
+	if (err)
+		return 4;
+
+	// make sure user is not trying to mix unipolar and bipolar ranges
+	if (cmd->chanlist) {
+		unipolar = CR_RANGE(cmd->chanlist[0]) & UNIPOLAR;
+		for (i = 1; i < cmd->chanlist_len; i++) {
+			if (unipolar != (CR_RANGE(cmd->chanlist[i]) & UNIPOLAR)) {
+				comedi_error(dev,
+					"unipolar and bipolar ranges cannot be mixed in the chanlist");
+				err++;
+				break;
+			}
+		}
+	}
+
+	if (err)
+		return 5;
+
+	return 0;
+}
+
+/* analog input cmd interface */
+
+// first, some utility functions used in the main ai_do_cmd()
+
+// returns appropriate bits for control register a, depending on command
+static int control_a_bits(struct comedi_cmd cmd)
+{
+	int control_a;
+
+	control_a = FFEN;	//enable fifo
+	if (cmd.stop_src == TRIG_EXT) {
+		control_a |= ATEN;
+	}
+	switch (cmd.start_src) {
+	case TRIG_EXT:
+		control_a |= TGEN | CGSL;
+		break;
+	case TRIG_NOW:
+		control_a |= CGEN;
+		break;
+	default:
+		break;
+	}
+
+	return control_a;
+}
+
+// returns appropriate bits for control register c, depending on command
+static int control_c_bits(struct comedi_cmd cmd)
+{
+	int control_c;
+	int aref;
+
+	/* set clock source to internal or external, select analog reference,
+	 * select unipolar / bipolar
+	 */
+	aref = CR_AREF(cmd.chanlist[0]);
+	control_c = UQEN;	//enable upper qram addresses
+	if (aref != AREF_DIFF)
+		control_c |= SD;
+	if (aref == AREF_COMMON)
+		control_c |= CMEN;
+	/* if a unipolar range was selected */
+	if (CR_RANGE(cmd.chanlist[0]) & UNIPOLAR)
+		control_c |= UB;
+	switch (cmd.scan_begin_src) {
+	case TRIG_FOLLOW:	// not in burst mode
+		switch (cmd.convert_src) {
+		case TRIG_TIMER:
+			/* trig on cascaded counters */
+			control_c |= IPCLK;
+			break;
+		case TRIG_EXT:
+			/* trig on falling edge of external trigger */
+			control_c |= XPCLK;
+			break;
+		default:
+			break;
+		}
+		break;
+	case TRIG_TIMER:
+		// burst mode with internal pacer clock
+		control_c |= BMDE | IPCLK;
+		break;
+	case TRIG_EXT:
+		// burst mode with external trigger
+		control_c |= BMDE | XPCLK;
+		break;
+	default:
+		break;
+	}
+
+	return control_c;
+}
+
+// sets up counters
+static int setup_counters(struct comedi_device * dev, struct comedi_cmd cmd)
+{
+	// setup cascaded counters for conversion/scan frequency
+	switch (cmd.scan_begin_src) {
+	case TRIG_FOLLOW:	// not in burst mode
+		if (cmd.convert_src == TRIG_TIMER) {
+			/* set conversion frequency */
+			i8253_cascade_ns_to_timer_2div(TIMER_BASE,
+				&(devpriv->divisor1), &(devpriv->divisor2),
+				&(cmd.convert_arg),
+				cmd.flags & TRIG_ROUND_MASK);
+			if (das1800_set_frequency(dev) < 0) {
+				return -1;
+			}
+		}
+		break;
+	case TRIG_TIMER:	// in burst mode
+		/* set scan frequency */
+		i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
+			&(devpriv->divisor2), &(cmd.scan_begin_arg),
+			cmd.flags & TRIG_ROUND_MASK);
+		if (das1800_set_frequency(dev) < 0) {
+			return -1;
+		}
+		break;
+	default:
+		break;
+	}
+
+	// setup counter 0 for 'about triggering'
+	if (cmd.stop_src == TRIG_EXT) {
+		// load counter 0 in mode 0
+		i8254_load(dev->iobase + DAS1800_COUNTER, 0, 0, 1, 0);
+	}
+
+	return 0;
+}
+
+// sets up dma
+static void setup_dma(struct comedi_device * dev, struct comedi_cmd cmd)
+{
+	unsigned long lock_flags;
+	const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
+
+	if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0)
+		return;
+
+	/* determine a reasonable dma transfer size */
+	devpriv->dma_transfer_size = suggest_transfer_size(&cmd);
+	lock_flags = claim_dma_lock();
+	disable_dma(devpriv->dma0);
+	/* clear flip-flop to make sure 2-byte registers for
+	 * count and address get set correctly */
+	clear_dma_ff(devpriv->dma0);
+	set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->ai_buf0));
+	// set appropriate size of transfer
+	set_dma_count(devpriv->dma0, devpriv->dma_transfer_size);
+	devpriv->dma_current = devpriv->dma0;
+	devpriv->dma_current_buf = devpriv->ai_buf0;
+	enable_dma(devpriv->dma0);
+	// set up dual dma if appropriate
+	if (dual_dma) {
+		disable_dma(devpriv->dma1);
+		/* clear flip-flop to make sure 2-byte registers for
+		 * count and address get set correctly */
+		clear_dma_ff(devpriv->dma1);
+		set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->ai_buf1));
+		// set appropriate size of transfer
+		set_dma_count(devpriv->dma1, devpriv->dma_transfer_size);
+		enable_dma(devpriv->dma1);
+	}
+	release_dma_lock(lock_flags);
+
+	return;
+}
+
+// programs channel/gain list into card
+static void program_chanlist(struct comedi_device * dev, struct comedi_cmd cmd)
+{
+	int i, n, chan_range;
+	unsigned long irq_flags;
+	const int range_mask = 0x3;	//masks unipolar/bipolar bit off range
+	const int range_bitshift = 8;
+
+	n = cmd.chanlist_len;
+	// spinlock protects indirect addressing
+	comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+	outb(QRAM, dev->iobase + DAS1800_SELECT);	/* select QRAM for baseAddress + 0x0 */
+	outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS);	/*set QRAM address start */
+	/* make channel / gain list */
+	for (i = 0; i < n; i++) {
+		chan_range =
+			CR_CHAN(cmd.chanlist[i]) | ((CR_RANGE(cmd.
+					chanlist[i]) & range_mask) <<
+			range_bitshift);
+		outw(chan_range, dev->iobase + DAS1800_QRAM);
+	}
+	outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS);	/*finish write to QRAM */
+	comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+	return;
+}
+
+// analog input do_cmd
+static int das1800_ai_do_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	int ret;
+	int control_a, control_c;
+	struct comedi_async *async = s->async;
+	struct comedi_cmd cmd = async->cmd;
+
+	if (!dev->irq) {
+		comedi_error(dev,
+			"no irq assigned for das-1800, cannot do hardware conversions");
+		return -1;
+	}
+
+	/* disable dma on TRIG_WAKE_EOS, or TRIG_RT
+	 * (because dma in handler is unsafe at hard real-time priority) */
+	if (cmd.flags & (TRIG_WAKE_EOS | TRIG_RT)) {
+		devpriv->irq_dma_bits &= ~DMA_ENABLED;
+	} else {
+		devpriv->irq_dma_bits |= devpriv->dma_bits;
+	}
+	// interrupt on end of conversion for TRIG_WAKE_EOS
+	if (cmd.flags & TRIG_WAKE_EOS) {
+		// interrupt fifo not empty
+		devpriv->irq_dma_bits &= ~FIMD;
+	} else {
+		// interrupt fifo half full
+		devpriv->irq_dma_bits |= FIMD;
+	}
+	// determine how many conversions we need
+	if (cmd.stop_src == TRIG_COUNT) {
+		devpriv->count = cmd.stop_arg * cmd.chanlist_len;
+	}
+
+	das1800_cancel(dev, s);
+
+	// determine proper bits for control registers
+	control_a = control_a_bits(cmd);
+	control_c = control_c_bits(cmd);
+
+	/* setup card and start */
+	program_chanlist(dev, cmd);
+	ret = setup_counters(dev, cmd);
+	if (ret < 0) {
+		comedi_error(dev, "Error setting up counters");
+		return ret;
+	}
+	setup_dma(dev, cmd);
+	outb(control_c, dev->iobase + DAS1800_CONTROL_C);
+	// set conversion rate and length for burst mode
+	if (control_c & BMDE) {
+		// program conversion period with number of microseconds minus 1
+		outb(cmd.convert_arg / 1000 - 1,
+			dev->iobase + DAS1800_BURST_RATE);
+		outb(cmd.chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH);
+	}
+	outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B);	// enable irq/dma
+	outb(control_a, dev->iobase + DAS1800_CONTROL_A);	/* enable fifo and triggering */
+	outb(CVEN, dev->iobase + DAS1800_STATUS);	/* enable conversions */
+
+	return 0;
+}
+
+/* read analog input */
+static int das1800_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i, n;
+	int chan, range, aref, chan_range;
+	int timeout = 1000;
+	short dpnt;
+	int conv_flags = 0;
+	unsigned long irq_flags;
+
+	/* set up analog reference and unipolar / bipolar mode */
+	aref = CR_AREF(insn->chanspec);
+	conv_flags |= UQEN;
+	if (aref != AREF_DIFF)
+		conv_flags |= SD;
+	if (aref == AREF_COMMON)
+		conv_flags |= CMEN;
+	/* if a unipolar range was selected */
+	if (CR_RANGE(insn->chanspec) & UNIPOLAR)
+		conv_flags |= UB;
+
+	outb(conv_flags, dev->iobase + DAS1800_CONTROL_C);	/* software conversion enabled */
+	outb(CVEN, dev->iobase + DAS1800_STATUS);	/* enable conversions */
+	outb(0x0, dev->iobase + DAS1800_CONTROL_A);	/* reset fifo */
+	outb(FFEN, dev->iobase + DAS1800_CONTROL_A);
+
+	chan = CR_CHAN(insn->chanspec);
+	/* mask of unipolar/bipolar bit from range */
+	range = CR_RANGE(insn->chanspec) & 0x3;
+	chan_range = chan | (range << 8);
+	comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+	outb(QRAM, dev->iobase + DAS1800_SELECT);	/* select QRAM for baseAddress + 0x0 */
+	outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS);	/* set QRAM address start */
+	outw(chan_range, dev->iobase + DAS1800_QRAM);
+	outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS);	/*finish write to QRAM */
+	outb(ADC, dev->iobase + DAS1800_SELECT);	/* select ADC for baseAddress + 0x0 */
+
+	for (n = 0; n < insn->n; n++) {
+		/* trigger conversion */
+		outb(0, dev->iobase + DAS1800_FIFO);
+		for (i = 0; i < timeout; i++) {
+			if (inb(dev->iobase + DAS1800_STATUS) & FNE)
+				break;
+		}
+		if (i == timeout) {
+			comedi_error(dev, "timeout");
+			return -ETIME;
+		}
+		dpnt = inw(dev->iobase + DAS1800_FIFO);
+		/* shift data to offset binary for bipolar ranges */
+		if ((conv_flags & UB) == 0)
+			dpnt += 1 << (thisboard->resolution - 1);
+		data[n] = dpnt;
+	}
+	comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+	return n;
+}
+
+/* writes to an analog output channel */
+static int das1800_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int chan = CR_CHAN(insn->chanspec);
+//      int range = CR_RANGE(insn->chanspec);
+	int update_chan = thisboard->ao_n_chan - 1;
+	short output;
+	unsigned long irq_flags;
+
+	//  card expects two's complement data
+	output = data[0] - (1 << (thisboard->resolution - 1));
+	// if the write is to the 'update' channel, we need to remember its value
+	if (chan == update_chan)
+		devpriv->ao_update_bits = output;
+	// write to channel
+	comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+	outb(DAC(chan), dev->iobase + DAS1800_SELECT);	/* select dac channel for baseAddress + 0x0 */
+	outw(output, dev->iobase + DAS1800_DAC);
+	// now we need to write to 'update' channel to update all dac channels
+	if (chan != update_chan) {
+		outb(DAC(update_chan), dev->iobase + DAS1800_SELECT);	/* select 'update' channel for baseAddress + 0x0 */
+		outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
+	}
+	comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+	return 1;
+}
+
+/* reads from digital input channels */
+static int das1800_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+
+	data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf;
+	data[0] = 0;
+
+	return 2;
+}
+
+/* writes to digital output channels */
+static int das1800_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int wbits;
+
+	// only set bits that have been masked
+	data[0] &= (1 << s->n_chan) - 1;
+	wbits = devpriv->do_bits;
+	wbits &= ~data[0];
+	wbits |= data[0] & data[1];
+	devpriv->do_bits = wbits;
+
+	outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
+
+	data[1] = devpriv->do_bits;
+
+	return 2;
+}
+
+/* loads counters with divisor1, divisor2 from private structure */
+static int das1800_set_frequency(struct comedi_device * dev)
+{
+	int err = 0;
+
+	// counter 1, mode 2
+	if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 1, devpriv->divisor1,
+			2))
+		err++;
+	// counter 2, mode 2
+	if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 2, devpriv->divisor2,
+			2))
+		err++;
+	if (err)
+		return -1;
+
+	return 0;
+}
+
+/* converts requested conversion timing to timing compatible with
+ * hardware, used only when card is in 'burst mode'
+ */
+static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode)
+{
+	unsigned int micro_sec;
+
+	// in burst mode, the maximum conversion time is 64 microseconds
+	if (convert_arg > 64000)
+		convert_arg = 64000;
+
+	// the conversion time must be an integral number of microseconds
+	switch (round_mode) {
+	case TRIG_ROUND_NEAREST:
+	default:
+		micro_sec = (convert_arg + 500) / 1000;
+		break;
+	case TRIG_ROUND_DOWN:
+		micro_sec = convert_arg / 1000;
+		break;
+	case TRIG_ROUND_UP:
+		micro_sec = (convert_arg - 1) / 1000 + 1;
+		break;
+	}
+
+	// return number of nanoseconds
+	return micro_sec * 1000;
+}
+
+// utility function that suggests a dma transfer size based on the conversion period 'ns'
+static unsigned int suggest_transfer_size(struct comedi_cmd * cmd)
+{
+	unsigned int size = DMA_BUF_SIZE;
+	static const int sample_size = 2;	// size in bytes of one sample from board
+	unsigned int fill_time = 300000000;	// target time in nanoseconds for filling dma buffer
+	unsigned int max_size;	// maximum size we will allow for a transfer
+
+	// make dma buffer fill in 0.3 seconds for timed modes
+	switch (cmd->scan_begin_src) {
+	case TRIG_FOLLOW:	// not in burst mode
+		if (cmd->convert_src == TRIG_TIMER)
+			size = (fill_time / cmd->convert_arg) * sample_size;
+		break;
+	case TRIG_TIMER:
+		size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) *
+			sample_size;
+		break;
+	default:
+		size = DMA_BUF_SIZE;
+		break;
+	}
+
+	// set a minimum and maximum size allowed
+	max_size = DMA_BUF_SIZE;
+	// if we are taking limited number of conversions, limit transfer size to that
+	if (cmd->stop_src == TRIG_COUNT &&
+		cmd->stop_arg * cmd->chanlist_len * sample_size < max_size)
+		max_size = cmd->stop_arg * cmd->chanlist_len * sample_size;
+
+	if (size > max_size)
+		size = max_size;
+	if (size < sample_size)
+		size = sample_size;
+
+	return size;
+}
diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c
new file mode 100644
index 0000000..2a8ca05
--- /dev/null
+++ b/drivers/staging/comedi/drivers/das6402.c
@@ -0,0 +1,354 @@
+/*
+   Some comments on the code..
+
+   - it shouldn't be necessary to use outb_p().
+
+   - ignoreirq creates a race condition.  It needs to be fixed.
+
+ */
+
+/*
+   comedi/drivers/das6402.c
+   An experimental driver for Computerboards' DAS6402 I/O card
+
+   Copyright (C) 1999 Oystein Svendsen <svendsen@pvv.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.
+
+   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.
+
+ */
+/*
+Driver: das6402
+Description: Keithley Metrabyte DAS6402 (& compatibles)
+Author: Oystein Svendsen <svendsen@pvv.org>
+Status: bitrotten
+Devices: [Keithley Metrabyte] DAS6402 (das6402)
+
+This driver has suffered bitrot.
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define DAS6402_SIZE 16
+
+#define N_WORDS 3000*64
+
+#define STOP    0
+#define START   1
+
+#define SCANL 0x3f00
+#define BYTE unsigned char
+#define WORD unsigned short
+
+/*----- register 8 ----*/
+#define CLRINT 0x01
+#define CLRXTR 0x02
+#define CLRXIN 0x04
+#define EXTEND 0x10
+#define ARMED 0x20		/* enable conting of post sample conv */
+#define POSTMODE 0x40
+#define MHZ 0x80		/* 10 MHz clock */
+/*---------------------*/
+
+/*----- register 9 ----*/
+#define IRQ (0x04 << 4)		/* these two are                         */
+#define IRQV 10			/*               dependent on each other */
+
+#define CONVSRC 0x03		/* trig src is Intarnal pacer */
+#define BURSTEN 0x04		/* enable burst */
+#define XINTE 0x08		/* use external int. trig */
+#define INTE 0x80		/* enable analog interrupts */
+/*---------------------*/
+
+/*----- register 10 ---*/
+#define TGEN 0x01		/* Use pin DI1 for externl trigging? */
+#define TGSEL 0x02		/* Use edge triggering */
+#define TGPOL 0x04		/* active edge is falling */
+#define PRETRIG 0x08		/* pretrig */
+/*---------------------*/
+
+/*----- register 11 ---*/
+#define EOB 0x0c
+#define FIFOHFULL 0x08
+#define GAIN 0x01
+#define FIFONEPTY 0x04
+#define MODE 0x10
+#define SEM 0x20
+#define BIP 0x40
+/*---------------------*/
+
+#define M0 0x00
+#define M2 0x04
+
+#define	C0 0x00
+#define	C1 0x40
+#define	C2 0x80
+#define	RWLH 0x30
+
+static int das6402_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int das6402_detach(struct comedi_device * dev);
+static struct comedi_driver driver_das6402 = {
+      driver_name:"das6402",
+      module:THIS_MODULE,
+      attach:das6402_attach,
+      detach:das6402_detach,
+};
+
+COMEDI_INITCLEANUP(driver_das6402);
+
+struct das6402_private {
+	int ai_bytes_to_read;
+
+	int das6402_ignoreirq;
+};
+#define devpriv ((struct das6402_private *)dev->private)
+
+static void das6402_ai_fifo_dregs(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static void das6402_setcounter(struct comedi_device * dev)
+{
+	BYTE p;
+	unsigned short ctrlwrd;
+
+	/* set up counter0 first, mode 0 */
+	p = M0 | C0 | RWLH;
+	outb_p(p, dev->iobase + 15);
+	ctrlwrd = 2000;
+	p = (BYTE) (0xff & ctrlwrd);
+	outb_p(p, dev->iobase + 12);
+	p = (BYTE) (0xff & (ctrlwrd >> 8));
+	outb_p(p, dev->iobase + 12);
+
+	/* set up counter1, mode 2 */
+	p = M2 | C1 | RWLH;
+	outb_p(p, dev->iobase + 15);
+	ctrlwrd = 10;
+	p = (BYTE) (0xff & ctrlwrd);
+	outb_p(p, dev->iobase + 13);
+	p = (BYTE) (0xff & (ctrlwrd >> 8));
+	outb_p(p, dev->iobase + 13);
+
+	/* set up counter1, mode 2 */
+	p = M2 | C2 | RWLH;
+	outb_p(p, dev->iobase + 15);
+	ctrlwrd = 1000;
+	p = (BYTE) (0xff & ctrlwrd);
+	outb_p(p, dev->iobase + 14);
+	p = (BYTE) (0xff & (ctrlwrd >> 8));
+	outb_p(p, dev->iobase + 14);
+}
+
+static irqreturn_t intr_handler(int irq, void *d PT_REGS_ARG)
+{
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s = dev->subdevices;
+
+	if (!dev->attached || devpriv->das6402_ignoreirq) {
+		printk("das6402: BUG: spurious interrupt\n");
+		return IRQ_HANDLED;
+	}
+#ifdef DEBUG
+	printk("das6402: interrupt! das6402_irqcount=%i\n",
+		devpriv->das6402_irqcount);
+	printk("das6402: iobase+2=%i\n", inw_p(dev->iobase + 2));
+#endif
+
+	das6402_ai_fifo_dregs(dev, s);
+
+	if (s->async->buf_write_count >= devpriv->ai_bytes_to_read) {
+		outw_p(SCANL, dev->iobase + 2);	/* clears the fifo */
+		outb(0x07, dev->iobase + 8);	/* clears all flip-flops */
+#ifdef DEBUG
+		printk("das6402: Got %i samples\n\n",
+			devpriv->das6402_wordsread - diff);
+#endif
+		s->async->events |= COMEDI_CB_EOA;
+		comedi_event(dev, s);
+	}
+
+	outb(0x01, dev->iobase + 8);	/* clear only the interrupt flip-flop */
+
+	comedi_event(dev, s);
+	return IRQ_HANDLED;
+}
+
+#if 0
+static void das6402_ai_fifo_read(struct comedi_device * dev, short * data, int n)
+{
+	int i;
+
+	for (i = 0; i < n; i++)
+		data[i] = inw(dev->iobase);
+}
+#endif
+
+static void das6402_ai_fifo_dregs(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	while (1) {
+		if (!(inb(dev->iobase + 8) & 0x01))
+			return;
+		comedi_buf_put(s->async, inw(dev->iobase));
+	}
+}
+
+static int das6402_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	/*
+	 *  This function should reset the board from whatever condition it
+	 *  is in (i.e., acquiring data), to a non-active state.
+	 */
+
+	devpriv->das6402_ignoreirq = 1;
+#ifdef DEBUG
+	printk("das6402: Stopping acquisition\n");
+#endif
+	devpriv->das6402_ignoreirq = 1;
+	outb_p(0x02, dev->iobase + 10);	/* disable external trigging */
+	outw_p(SCANL, dev->iobase + 2);	/* resets the card fifo */
+	outb_p(0, dev->iobase + 9);	/* disables interrupts */
+
+	outw_p(SCANL, dev->iobase + 2);
+
+	return 0;
+}
+
+#ifdef unused
+static int das6402_ai_mode2(struct comedi_device * dev, struct comedi_subdevice * s,
+	comedi_trig * it)
+{
+	devpriv->das6402_ignoreirq = 1;
+
+#ifdef DEBUG
+	printk("das6402: Starting acquisition\n");
+#endif
+	outb_p(0x03, dev->iobase + 10);	/* enable external trigging */
+	outw_p(SCANL, dev->iobase + 2);	/* resets the card fifo */
+	outb_p(IRQ | CONVSRC | BURSTEN | INTE, dev->iobase + 9);
+
+	devpriv->ai_bytes_to_read = it->n * sizeof(short);
+
+	/* um... ignoreirq is a nasty race condition */
+	devpriv->das6402_ignoreirq = 0;
+
+	outw_p(SCANL, dev->iobase + 2);
+
+	return 0;
+}
+#endif
+
+static int board_init(struct comedi_device * dev)
+{
+	BYTE b;
+
+	devpriv->das6402_ignoreirq = 1;
+
+	outb(0x07, dev->iobase + 8);
+
+	/* register 11  */
+	outb_p(MODE, dev->iobase + 11);
+	b = BIP | SEM | MODE | GAIN | FIFOHFULL;
+	outb_p(b, dev->iobase + 11);
+
+	/* register 8   */
+	outb_p(EXTEND, dev->iobase + 8);
+	b = EXTEND | MHZ;
+	outb_p(b, dev->iobase + 8);
+	b = MHZ | CLRINT | CLRXTR | CLRXIN;
+	outb_p(b, dev->iobase + 8);
+
+	/* register 9    */
+	b = IRQ | CONVSRC | BURSTEN | INTE;
+	outb_p(b, dev->iobase + 9);
+
+	/* register 10   */
+	b = TGSEL | TGEN;
+	outb_p(b, dev->iobase + 10);
+
+	b = 0x07;
+	outb_p(b, dev->iobase + 8);
+
+	das6402_setcounter(dev);
+
+	outw_p(SCANL, dev->iobase + 2);	/* reset card fifo */
+
+	devpriv->das6402_ignoreirq = 0;
+
+	return 0;
+}
+
+static int das6402_detach(struct comedi_device * dev)
+{
+	if (dev->irq)
+		comedi_free_irq(dev->irq, dev);
+	if (dev->iobase)
+		release_region(dev->iobase, DAS6402_SIZE);
+
+	return 0;
+}
+
+static int das6402_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	unsigned int irq;
+	unsigned long iobase;
+	int ret;
+	struct comedi_subdevice *s;
+
+	dev->board_name = "das6402";
+
+	iobase = it->options[0];
+	if (iobase == 0)
+		iobase = 0x300;
+
+	printk("comedi%d: das6402: 0x%04lx", dev->minor, iobase);
+
+	if (!request_region(iobase, DAS6402_SIZE, "das6402")) {
+		printk(" I/O port conflict\n");
+		return -EIO;
+	}
+	dev->iobase = iobase;
+
+	/* should do a probe here */
+
+	irq = it->options[0];
+	printk(" ( irq = %u )", irq);
+	ret = comedi_request_irq(irq, intr_handler, 0, "das6402", dev);
+	if (ret < 0) {
+		printk("irq conflict\n");
+		return ret;
+	}
+	dev->irq = irq;
+
+	if ((ret = alloc_private(dev, sizeof(struct das6402_private))) < 0)
+		return ret;
+
+	if ((ret = alloc_subdevices(dev, 1)) < 0)
+		return ret;
+
+	/* ai subdevice */
+	s = dev->subdevices + 0;
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE | SDF_GROUND;
+	s->n_chan = 8;
+	//s->trig[2]=das6402_ai_mode2;
+	s->cancel = das6402_ai_cancel;
+	s->maxdata = (1 << 12) - 1;
+	s->len_chanlist = 16;	/* ? */
+	s->range_table = &range_unknown;
+
+	board_init(dev);
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c
new file mode 100644
index 0000000..7a6656b
--- /dev/null
+++ b/drivers/staging/comedi/drivers/das800.c
@@ -0,0 +1,894 @@
+/*
+    comedi/drivers/das800.c
+    Driver for Keitley das800 series boards and compatibles
+    Copyright (C) 2000 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000 David A. Schleef <ds@schleef.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.
+
+    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.
+
+************************************************************************
+*/
+/*
+Driver: das800
+Description: Keithley Metrabyte DAS800 (& compatibles)
+Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+Devices: [Keithley Metrabyte] DAS-800 (das-800), DAS-801 (das-801),
+  DAS-802 (das-802),
+  [Measurement Computing] CIO-DAS800 (cio-das800),
+  CIO-DAS801 (cio-das801), CIO-DAS802 (cio-das802),
+  CIO-DAS802/16 (cio-das802/16)
+Status: works, cio-das802/16 untested - email me if you have tested it
+
+Configuration options:
+  [0] - I/O port base address
+  [1] - IRQ (optional, required for timed or externally triggered conversions)
+
+Notes:
+	IRQ can be omitted, although the cmd interface will not work without it.
+
+	All entries in the channel/gain list must use the same gain and be
+	consecutive channels counting upwards in channel number (these are
+	hardware limitations.)
+
+	I've never tested the gain setting stuff since I only have a
+	DAS-800 board with fixed gain.
+
+	The cio-das802/16 does not have a fifo-empty status bit!  Therefore
+	only fifo-half-full transfers are possible with this card.
+*/
+/*
+
+cmd triggers supported:
+	start_src:      TRIG_NOW | TRIG_EXT
+	scan_begin_src: TRIG_FOLLOW
+	scan_end_src:   TRIG_COUNT
+	convert_src:    TRIG_TIMER | TRIG_EXT
+	stop_src:       TRIG_NONE | TRIG_COUNT
+
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/delay.h>
+
+#include "8253.h"
+#include "comedi_fc.h"
+
+#define DAS800_SIZE           8
+#define TIMER_BASE            1000
+#define N_CHAN_AI             8	// number of analog input channels
+
+/* Registers for the das800 */
+
+#define DAS800_LSB            0
+#define   FIFO_EMPTY            0x1
+#define   FIFO_OVF              0x2
+#define DAS800_MSB            1
+#define DAS800_CONTROL1       2
+#define   CONTROL1_INTE         0x8
+#define DAS800_CONV_CONTROL   2
+#define   ITE                   0x1
+#define   CASC                  0x2
+#define   DTEN                  0x4
+#define   IEOC                  0x8
+#define   EACS                  0x10
+#define   CONV_HCEN             0x80
+#define DAS800_SCAN_LIMITS    2
+#define DAS800_STATUS         2
+#define   IRQ                   0x8
+#define   BUSY                  0x80
+#define DAS800_GAIN           3
+#define   CIO_FFOV              0x8	// fifo overflow for cio-das802/16
+#define   CIO_ENHF              0x90	// interrupt fifo half full for cio-das802/16
+#define   CONTROL1              0x80
+#define   CONV_CONTROL          0xa0
+#define   SCAN_LIMITS           0xc0
+#define   ID                    0xe0
+#define DAS800_8254           4
+#define DAS800_STATUS2        7
+#define   STATUS2_HCEN          0x80
+#define   STATUS2_INTE          0X20
+#define DAS800_ID             7
+
+struct das800_board {
+	const char *name;
+	int ai_speed;
+	const struct comedi_lrange *ai_range;
+	int resolution;
+};
+
+//analog input ranges
+static const struct comedi_lrange range_das800_ai = {
+	1,
+	{
+			RANGE(-5, 5),
+		}
+};
+
+static const struct comedi_lrange range_das801_ai = {
+	9,
+	{
+			RANGE(-5, 5),
+			RANGE(-10, 10),
+			RANGE(0, 10),
+			RANGE(-0.5, 0.5),
+			RANGE(0, 1),
+			RANGE(-0.05, 0.05),
+			RANGE(0, 0.1),
+			RANGE(-0.01, 0.01),
+			RANGE(0, 0.02),
+		}
+};
+
+static const struct comedi_lrange range_cio_das801_ai = {
+	9,
+	{
+			RANGE(-5, 5),
+			RANGE(-10, 10),
+			RANGE(0, 10),
+			RANGE(-0.5, 0.5),
+			RANGE(0, 1),
+			RANGE(-0.05, 0.05),
+			RANGE(0, 0.1),
+			RANGE(-0.005, 0.005),
+			RANGE(0, 0.01),
+		}
+};
+
+static const struct comedi_lrange range_das802_ai = {
+	9,
+	{
+			RANGE(-5, 5),
+			RANGE(-10, 10),
+			RANGE(0, 10),
+			RANGE(-2.5, 2.5),
+			RANGE(0, 5),
+			RANGE(-1.25, 1.25),
+			RANGE(0, 2.5),
+			RANGE(-0.625, 0.625),
+			RANGE(0, 1.25),
+		}
+};
+
+static const struct comedi_lrange range_das80216_ai = {
+	8,
+	{
+			RANGE(-10, 10),
+			RANGE(0, 10),
+			RANGE(-5, 5),
+			RANGE(0, 5),
+			RANGE(-2.5, 2.5),
+			RANGE(0, 2.5),
+			RANGE(-1.25, 1.25),
+			RANGE(0, 1.25),
+		}
+};
+
+enum { das800, ciodas800, das801, ciodas801, das802, ciodas802, ciodas80216 };
+
+static const struct das800_board das800_boards[] = {
+	{
+	      name:	"das-800",
+	      ai_speed:25000,
+	      ai_range:&range_das800_ai,
+	      resolution:12,
+		},
+	{
+	      name:	"cio-das800",
+	      ai_speed:20000,
+	      ai_range:&range_das800_ai,
+	      resolution:12,
+		},
+	{
+	      name:	"das-801",
+	      ai_speed:25000,
+	      ai_range:&range_das801_ai,
+	      resolution:12,
+		},
+	{
+	      name:	"cio-das801",
+	      ai_speed:20000,
+	      ai_range:&range_cio_das801_ai,
+	      resolution:12,
+		},
+	{
+	      name:	"das-802",
+	      ai_speed:25000,
+	      ai_range:&range_das802_ai,
+	      resolution:12,
+		},
+	{
+	      name:	"cio-das802",
+	      ai_speed:20000,
+	      ai_range:&range_das802_ai,
+	      resolution:12,
+		},
+	{
+	      name:	"cio-das802/16",
+	      ai_speed:10000,
+	      ai_range:&range_das80216_ai,
+	      resolution:16,
+		},
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct das800_board *)dev->board_ptr)
+
+struct das800_private {
+	volatile unsigned int count;	/* number of data points left to be taken */
+	volatile int forever;	/* flag indicating whether we should take data forever */
+	unsigned int divisor1;	/* value to load into board's counter 1 for timed conversions */
+	unsigned int divisor2;	/* value to load into board's counter 2 for timed conversions */
+	volatile int do_bits;	/* digital output bits */
+};
+
+#define devpriv ((struct das800_private *)dev->private)
+
+static int das800_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int das800_detach(struct comedi_device * dev);
+static int das800_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static struct comedi_driver driver_das800 = {
+      driver_name:"das800",
+      module:THIS_MODULE,
+      attach:das800_attach,
+      detach:das800_detach,
+      num_names:sizeof(das800_boards) / sizeof(struct das800_board),
+      board_name:&das800_boards[0].name,
+      offset:sizeof(struct das800_board),
+};
+
+static irqreturn_t das800_interrupt(int irq, void *d PT_REGS_ARG);
+static void enable_das800(struct comedi_device * dev);
+static void disable_das800(struct comedi_device * dev);
+static int das800_ai_do_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd);
+static int das800_ai_do_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int das800_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int das800_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int das800_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int das800_probe(struct comedi_device * dev);
+static int das800_set_frequency(struct comedi_device * dev);
+
+/* checks and probes das-800 series board type */
+static int das800_probe(struct comedi_device * dev)
+{
+	int id_bits;
+	unsigned long irq_flags;
+	int board;
+
+	// 'comedi spin lock irqsave' disables even rt interrupts, we use them to protect indirect addressing
+	comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+	outb(ID, dev->iobase + DAS800_GAIN);	/* select base address + 7 to be ID register */
+	id_bits = inb(dev->iobase + DAS800_ID) & 0x3;	/* get id bits */
+	comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+	board = thisboard - das800_boards;
+
+	switch (id_bits) {
+	case 0x0:
+		if (board == das800) {
+			printk(" Board model: DAS-800\n");
+			return board;
+		}
+		if (board == ciodas800) {
+			printk(" Board model: CIO-DAS800\n");
+			return board;
+		}
+		printk(" Board model (probed): DAS-800\n");
+		return das800;
+		break;
+	case 0x2:
+		if (board == das801) {
+			printk(" Board model: DAS-801\n");
+			return board;
+		}
+		if (board == ciodas801) {
+			printk(" Board model: CIO-DAS801\n");
+			return board;
+		}
+		printk(" Board model (probed): DAS-801\n");
+		return das801;
+		break;
+	case 0x3:
+		if (board == das802) {
+			printk(" Board model: DAS-802\n");
+			return board;
+		}
+		if (board == ciodas802) {
+			printk(" Board model: CIO-DAS802\n");
+			return board;
+		}
+		if (board == ciodas80216) {
+			printk(" Board model: CIO-DAS802/16\n");
+			return board;
+		}
+		printk(" Board model (probed): DAS-802\n");
+		return das802;
+		break;
+	default:
+		printk(" Board model: probe returned 0x%x (unknown)\n",
+			id_bits);
+		return board;
+		break;
+	}
+	return -1;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver_das800);
+
+/* interrupt service routine */
+static irqreturn_t das800_interrupt(int irq, void *d PT_REGS_ARG)
+{
+	short i;		/* loop index */
+	short dataPoint = 0;
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s = dev->read_subdev;	/* analog input subdevice */
+	struct comedi_async *async;
+	int status;
+	unsigned long irq_flags;
+	static const int max_loops = 128;	// half-fifo size for cio-das802/16
+	// flags
+	int fifo_empty = 0;
+	int fifo_overflow = 0;
+
+	status = inb(dev->iobase + DAS800_STATUS);
+	/* if interrupt was not generated by board or driver not attached, quit */
+	if (!(status & IRQ))
+		return IRQ_NONE;
+	if (!(dev->attached))
+		return IRQ_HANDLED;
+
+	/* wait until here to initialize async, since we will get null dereference
+	 * if interrupt occurs before driver is fully attached!
+	 */
+	async = s->async;
+
+	// if hardware conversions are not enabled, then quit
+	comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+	outb(CONTROL1, dev->iobase + DAS800_GAIN);	/* select base address + 7 to be STATUS2 register */
+	status = inb(dev->iobase + DAS800_STATUS2) & STATUS2_HCEN;
+	/* don't release spinlock yet since we want to make sure noone else disables hardware conversions */
+	if (status == 0) {
+		comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+		return IRQ_HANDLED;
+	}
+
+	/* loop while card's fifo is not empty (and limit to half fifo for cio-das802/16) */
+	for (i = 0; i < max_loops; i++) {
+		/* read 16 bits from dev->iobase and dev->iobase + 1 */
+		dataPoint = inb(dev->iobase + DAS800_LSB);
+		dataPoint += inb(dev->iobase + DAS800_MSB) << 8;
+		if (thisboard->resolution == 12) {
+			fifo_empty = dataPoint & FIFO_EMPTY;
+			fifo_overflow = dataPoint & FIFO_OVF;
+			if (fifo_overflow)
+				break;
+		} else {
+			fifo_empty = 0;	// cio-das802/16 has no fifo empty status bit
+		}
+		if (fifo_empty) {
+			break;
+		}
+		/* strip off extraneous bits for 12 bit cards */
+		if (thisboard->resolution == 12)
+			dataPoint = (dataPoint >> 4) & 0xfff;
+		/* if there are more data points to collect */
+		if (devpriv->count > 0 || devpriv->forever == 1) {
+			/* write data point to buffer */
+			cfc_write_to_buffer(s, dataPoint);
+			if (devpriv->count > 0)
+				devpriv->count--;
+		}
+	}
+	async->events |= COMEDI_CB_BLOCK;
+	/* check for fifo overflow */
+	if (thisboard->resolution == 12) {
+		fifo_overflow = dataPoint & FIFO_OVF;
+		// else cio-das802/16
+	} else {
+		fifo_overflow = inb(dev->iobase + DAS800_GAIN) & CIO_FFOV;
+	}
+	if (fifo_overflow) {
+		comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+		comedi_error(dev, "DAS800 FIFO overflow");
+		das800_cancel(dev, dev->subdevices + 0);
+		async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+		comedi_event(dev, s);
+		async->events = 0;
+		return IRQ_HANDLED;
+	}
+	if (devpriv->count > 0 || devpriv->forever == 1) {
+		/* Re-enable card's interrupt.
+		 * We already have spinlock, so indirect addressing is safe */
+		outb(CONTROL1, dev->iobase + DAS800_GAIN);	/* select dev->iobase + 2 to be control register 1 */
+		outb(CONTROL1_INTE | devpriv->do_bits,
+			dev->iobase + DAS800_CONTROL1);
+		comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+		/* otherwise, stop taking data */
+	} else {
+		comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+		disable_das800(dev);	/* diable hardware triggered conversions */
+		async->events |= COMEDI_CB_EOA;
+	}
+	comedi_event(dev, s);
+	async->events = 0;
+	return IRQ_HANDLED;
+}
+
+static int das800_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	unsigned long iobase = it->options[0];
+	unsigned int irq = it->options[1];
+	unsigned long irq_flags;
+	int board;
+
+	printk("comedi%d: das800: io 0x%lx", dev->minor, iobase);
+	if (irq) {
+		printk(", irq %u", irq);
+	}
+	printk("\n");
+
+	/* allocate and initialize dev->private */
+	if (alloc_private(dev, sizeof(struct das800_private)) < 0)
+		return -ENOMEM;
+
+	if (iobase == 0) {
+		printk("io base address required for das800\n");
+		return -EINVAL;
+	}
+
+	/* check if io addresses are available */
+	if (!request_region(iobase, DAS800_SIZE, "das800")) {
+		printk("I/O port conflict\n");
+		return -EIO;
+	}
+	dev->iobase = iobase;
+
+	board = das800_probe(dev);
+	if (board < 0) {
+		printk("unable to determine board type\n");
+		return -ENODEV;
+	}
+	dev->board_ptr = das800_boards + board;
+
+	/* grab our IRQ */
+	if (irq == 1 || irq > 7) {
+		printk("irq out of range\n");
+		return -EINVAL;
+	}
+	if (irq) {
+		if (comedi_request_irq(irq, das800_interrupt, 0, "das800", dev)) {
+			printk("unable to allocate irq %u\n", irq);
+			return -EINVAL;
+		}
+	}
+	dev->irq = irq;
+
+	dev->board_name = thisboard->name;
+
+	if (alloc_subdevices(dev, 3) < 0)
+		return -ENOMEM;
+
+	/* analog input subdevice */
+	s = dev->subdevices + 0;
+	dev->read_subdev = s;
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
+	s->n_chan = 8;
+	s->len_chanlist = 8;
+	s->maxdata = (1 << thisboard->resolution) - 1;
+	s->range_table = thisboard->ai_range;
+	s->do_cmd = das800_ai_do_cmd;
+	s->do_cmdtest = das800_ai_do_cmdtest;
+	s->insn_read = das800_ai_rinsn;
+	s->cancel = das800_cancel;
+
+	/* di */
+	s = dev->subdevices + 1;
+	s->type = COMEDI_SUBD_DI;
+	s->subdev_flags = SDF_READABLE;
+	s->n_chan = 3;
+	s->maxdata = 1;
+	s->range_table = &range_digital;
+	s->insn_bits = das800_di_rbits;
+
+	/* do */
+	s = dev->subdevices + 2;
+	s->type = COMEDI_SUBD_DO;
+	s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+	s->n_chan = 4;
+	s->maxdata = 1;
+	s->range_table = &range_digital;
+	s->insn_bits = das800_do_wbits;
+
+	disable_das800(dev);
+
+	/* initialize digital out channels */
+	comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+	outb(CONTROL1, dev->iobase + DAS800_GAIN);	/* select dev->iobase + 2 to be control register 1 */
+	outb(CONTROL1_INTE | devpriv->do_bits, dev->iobase + DAS800_CONTROL1);
+	comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+	return 0;
+};
+
+static int das800_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: das800: remove\n", dev->minor);
+
+	/* only free stuff if it has been allocated by _attach */
+	if (dev->iobase)
+		release_region(dev->iobase, DAS800_SIZE);
+	if (dev->irq)
+		comedi_free_irq(dev->irq, dev);
+	return 0;
+};
+
+static int das800_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	devpriv->forever = 0;
+	devpriv->count = 0;
+	disable_das800(dev);
+	return 0;
+}
+
+/* enable_das800 makes the card start taking hardware triggered conversions */
+static void enable_das800(struct comedi_device * dev)
+{
+	unsigned long irq_flags;
+	comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+	// enable fifo-half full interrupts for cio-das802/16
+	if (thisboard->resolution == 16)
+		outb(CIO_ENHF, dev->iobase + DAS800_GAIN);
+	outb(CONV_CONTROL, dev->iobase + DAS800_GAIN);	/* select dev->iobase + 2 to be conversion control register */
+	outb(CONV_HCEN, dev->iobase + DAS800_CONV_CONTROL);	/* enable hardware triggering */
+	outb(CONTROL1, dev->iobase + DAS800_GAIN);	/* select dev->iobase + 2 to be control register 1 */
+	outb(CONTROL1_INTE | devpriv->do_bits, dev->iobase + DAS800_CONTROL1);	/* enable card's interrupt */
+	comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+}
+
+/* disable_das800 stops hardware triggered conversions */
+static void disable_das800(struct comedi_device * dev)
+{
+	unsigned long irq_flags;
+	comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+	outb(CONV_CONTROL, dev->iobase + DAS800_GAIN);	/* select dev->iobase + 2 to be conversion control register */
+	outb(0x0, dev->iobase + DAS800_CONV_CONTROL);	/* disable hardware triggering of conversions */
+	comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+}
+
+static int das800_ai_do_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp;
+	int gain, startChan;
+	int i;
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW | TRIG_EXT;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_FOLLOW;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
+		err++;
+	if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+		err++;
+	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+	if (cmd->convert_src == TRIG_TIMER) {
+		if (cmd->convert_arg < thisboard->ai_speed) {
+			cmd->convert_arg = thisboard->ai_speed;
+			err++;
+		}
+	}
+	if (!cmd->chanlist_len) {
+		cmd->chanlist_len = 1;
+		err++;
+	}
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+	if (cmd->stop_src == TRIG_COUNT) {
+		if (!cmd->stop_arg) {
+			cmd->stop_arg = 1;
+			err++;
+		}
+	} else {		/* TRIG_NONE */
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	if (cmd->convert_src == TRIG_TIMER) {
+		tmp = cmd->convert_arg;
+		/* calculate counter values that give desired timing */
+		i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
+			&(devpriv->divisor2), &(cmd->convert_arg),
+			cmd->flags & TRIG_ROUND_MASK);
+		if (tmp != cmd->convert_arg)
+			err++;
+	}
+
+	if (err)
+		return 4;
+
+	// check channel/gain list against card's limitations
+	if (cmd->chanlist) {
+		gain = CR_RANGE(cmd->chanlist[0]);
+		startChan = CR_CHAN(cmd->chanlist[0]);
+		for (i = 1; i < cmd->chanlist_len; i++) {
+			if (CR_CHAN(cmd->chanlist[i]) !=
+				(startChan + i) % N_CHAN_AI) {
+				comedi_error(dev,
+					"entries in chanlist must be consecutive channels, counting upwards\n");
+				err++;
+			}
+			if (CR_RANGE(cmd->chanlist[i]) != gain) {
+				comedi_error(dev,
+					"entries in chanlist must all have the same gain\n");
+				err++;
+			}
+		}
+	}
+
+	if (err)
+		return 5;
+
+	return 0;
+}
+
+static int das800_ai_do_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	int startChan, endChan, scan, gain;
+	int conv_bits;
+	unsigned long irq_flags;
+	struct comedi_async *async = s->async;
+
+	if (!dev->irq) {
+		comedi_error(dev,
+			"no irq assigned for das-800, cannot do hardware conversions");
+		return -1;
+	}
+
+	disable_das800(dev);
+
+	/* set channel scan limits */
+	startChan = CR_CHAN(async->cmd.chanlist[0]);
+	endChan = (startChan + async->cmd.chanlist_len - 1) % 8;
+	scan = (endChan << 3) | startChan;
+
+	comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+	outb(SCAN_LIMITS, dev->iobase + DAS800_GAIN);	/* select base address + 2 to be scan limits register */
+	outb(scan, dev->iobase + DAS800_SCAN_LIMITS);	/* set scan limits */
+	comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+	/* set gain */
+	gain = CR_RANGE(async->cmd.chanlist[0]);
+	if (thisboard->resolution == 12 && gain > 0)
+		gain += 0x7;
+	gain &= 0xf;
+	outb(gain, dev->iobase + DAS800_GAIN);
+
+	switch (async->cmd.stop_src) {
+	case TRIG_COUNT:
+		devpriv->count = async->cmd.stop_arg * async->cmd.chanlist_len;
+		devpriv->forever = 0;
+		break;
+	case TRIG_NONE:
+		devpriv->forever = 1;
+		devpriv->count = 0;
+		break;
+	default:
+		break;
+	}
+
+	/* enable auto channel scan, send interrupts on end of conversion
+	 * and set clock source to internal or external
+	 */
+	conv_bits = 0;
+	conv_bits |= EACS | IEOC;
+	if (async->cmd.start_src == TRIG_EXT)
+		conv_bits |= DTEN;
+	switch (async->cmd.convert_src) {
+	case TRIG_TIMER:
+		conv_bits |= CASC | ITE;
+		/* set conversion frequency */
+		i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
+			&(devpriv->divisor2), &(async->cmd.convert_arg),
+			async->cmd.flags & TRIG_ROUND_MASK);
+		if (das800_set_frequency(dev) < 0) {
+			comedi_error(dev, "Error setting up counters");
+			return -1;
+		}
+		break;
+	case TRIG_EXT:
+		break;
+	default:
+		break;
+	}
+
+	comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+	outb(CONV_CONTROL, dev->iobase + DAS800_GAIN);	/* select dev->iobase + 2 to be conversion control register */
+	outb(conv_bits, dev->iobase + DAS800_CONV_CONTROL);
+	comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+	async->events = 0;
+	enable_das800(dev);
+	return 0;
+}
+
+static int das800_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i, n;
+	int chan;
+	int range;
+	int lsb, msb;
+	int timeout = 1000;
+	unsigned long irq_flags;
+
+	disable_das800(dev);	/* disable hardware conversions (enables software conversions) */
+
+	/* set multiplexer */
+	chan = CR_CHAN(insn->chanspec);
+
+	comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+	outb(CONTROL1, dev->iobase + DAS800_GAIN);	/* select dev->iobase + 2 to be control register 1 */
+	outb(chan | devpriv->do_bits, dev->iobase + DAS800_CONTROL1);
+	comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+	/* set gain / range */
+	range = CR_RANGE(insn->chanspec);
+	if (thisboard->resolution == 12 && range)
+		range += 0x7;
+	range &= 0xf;
+	outb(range, dev->iobase + DAS800_GAIN);
+
+	comedi_udelay(5);
+
+	for (n = 0; n < insn->n; n++) {
+		/* trigger conversion */
+		outb_p(0, dev->iobase + DAS800_MSB);
+
+		for (i = 0; i < timeout; i++) {
+			if (!(inb(dev->iobase + DAS800_STATUS) & BUSY))
+				break;
+		}
+		if (i == timeout) {
+			comedi_error(dev, "timeout");
+			return -ETIME;
+		}
+		lsb = inb(dev->iobase + DAS800_LSB);
+		msb = inb(dev->iobase + DAS800_MSB);
+		if (thisboard->resolution == 12) {
+			data[n] = (lsb >> 4) & 0xff;
+			data[n] |= (msb << 4);
+		} else {
+			data[n] = (msb << 8) | lsb;
+		}
+	}
+
+	return n;
+}
+
+static int das800_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int bits;
+
+	bits = inb(dev->iobase + DAS800_STATUS) >> 4;
+	bits &= 0x7;
+	data[1] = bits;
+	data[0] = 0;
+
+	return 2;
+}
+
+static int das800_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int wbits;
+	unsigned long irq_flags;
+
+	// only set bits that have been masked
+	data[0] &= 0xf;
+	wbits = devpriv->do_bits >> 4;
+	wbits &= ~data[0];
+	wbits |= data[0] & data[1];
+	devpriv->do_bits = wbits << 4;
+
+	comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+	outb(CONTROL1, dev->iobase + DAS800_GAIN);	/* select dev->iobase + 2 to be control register 1 */
+	outb(devpriv->do_bits | CONTROL1_INTE, dev->iobase + DAS800_CONTROL1);
+	comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+	data[1] = wbits;
+
+	return 2;
+}
+
+/* loads counters with divisor1, divisor2 from private structure */
+static int das800_set_frequency(struct comedi_device * dev)
+{
+	int err = 0;
+
+	if (i8254_load(dev->iobase + DAS800_8254, 0, 1, devpriv->divisor1, 2))
+		err++;
+	if (i8254_load(dev->iobase + DAS800_8254, 0, 2, devpriv->divisor2, 2))
+		err++;
+	if (err)
+		return -1;
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c
new file mode 100644
index 0000000..8290836
--- /dev/null
+++ b/drivers/staging/comedi/drivers/dmm32at.c
@@ -0,0 +1,1081 @@
+/*
+    comedi/drivers/dmm32at.c
+    Diamond Systems mm32at code for a Comedi driver
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: dmm32at
+Description: Diamond Systems mm32at driver.
+Devices:
+Author: Perry J. Piplani <perry.j.piplani@nasa.gov>
+Updated: Fri Jun  4 09:13:24 CDT 2004
+Status: experimental
+
+This driver is for the Diamond Systems MM-32-AT board
+http://www.diamondsystems.com/products/diamondmm32at It is being used
+on serveral projects inside NASA, without problems so far. For analog
+input commands, TRIG_EXT is not yet supported at all..
+
+Configuration Options:
+  comedi_config /dev/comedi0 dmm32at baseaddr,irq
+*/
+
+/*
+ * The previous block comment is used to automatically generate
+ * documentation in Comedi and Comedilib.  The fields:
+ *
+ * Driver: the name of the driver
+ * Description: a short phrase describing the driver.  Don't list boards.
+ * Devices: a full list of the boards that attempt to be supported by
+ *   the driver.  Format is "(manufacturer) board name [comedi name]",
+ *   where comedi_name is the name that is used to configure the board.
+ *   See the comment near board_name: in the struct comedi_driver structure
+ *   below.  If (manufacturer) or [comedi name] is missing, the previous
+ *   value is used.
+ * Author: you
+ * Updated: date when the _documentation_ was last updated.  Use 'date -R'
+ *   to get a value for this.
+ * Status: a one-word description of the status.  Valid values are:
+ *   works - driver works correctly on most boards supported, and
+ *     passes comedi_test.
+ *   unknown - unknown.  Usually put there by ds.
+ *   experimental - may not work in any particular release.  Author
+ *     probably wants assistance testing it.
+ *   bitrotten - driver has not been update in a long time, probably
+ *     doesn't work, and probably is missing support for significant
+ *     Comedi interface features.
+ *   untested - author probably wrote it "blind", and is believed to
+ *     work, but no confirmation.
+ *
+ * These headers should be followed by a blank line, and any comments
+ * you wish to say about the driver.  The comment area is the place
+ * to put any known bugs, limitations, unsupported features, supported
+ * command triggers, whether or not commands are supported on particular
+ * subdevices, etc.
+ *
+ * Somewhere in the comment should be information about configuration
+ * options that are used with comedi_config.
+ */
+
+#include "../comedidev.h"
+#include <linux/ioport.h>
+
+/* Board register addresses */
+
+#define DMM32AT_MEMSIZE 0x10
+
+#define DMM32AT_CONV 0x00
+#define DMM32AT_AILSB 0x00
+#define DMM32AT_AUXDOUT 0x01
+#define DMM32AT_AIMSB 0x01
+#define DMM32AT_AILOW 0x02
+#define DMM32AT_AIHIGH 0x03
+
+#define DMM32AT_DACLSB 0x04
+#define DMM32AT_DACSTAT 0x04
+#define DMM32AT_DACMSB 0x05
+
+#define DMM32AT_FIFOCNTRL 0x07
+#define DMM32AT_FIFOSTAT 0x07
+
+#define DMM32AT_CNTRL 0x08
+#define DMM32AT_AISTAT 0x08
+
+#define DMM32AT_INTCLOCK 0x09
+
+#define DMM32AT_CNTRDIO 0x0a
+
+#define DMM32AT_AICONF 0x0b
+#define DMM32AT_AIRBACK 0x0b
+
+#define DMM32AT_CLK1 0x0d
+#define DMM32AT_CLK2 0x0e
+#define DMM32AT_CLKCT 0x0f
+
+#define DMM32AT_DIOA 0x0c
+#define DMM32AT_DIOB 0x0d
+#define DMM32AT_DIOC 0x0e
+#define DMM32AT_DIOCONF 0x0f
+
+#define dmm_inb(cdev,reg) inb((cdev->iobase)+reg)
+#define dmm_outb(cdev,reg,valu) outb(valu,(cdev->iobase)+reg)
+
+/* Board register values. */
+
+/* DMM32AT_DACSTAT 0x04 */
+#define DMM32AT_DACBUSY 0x80
+
+/* DMM32AT_FIFOCNTRL 0x07 */
+#define DMM32AT_FIFORESET 0x02
+#define DMM32AT_SCANENABLE 0x04
+
+/* DMM32AT_CNTRL 0x08 */
+#define DMM32AT_RESET 0x20
+#define DMM32AT_INTRESET 0x08
+#define DMM32AT_CLKACC 0x00
+#define DMM32AT_DIOACC 0x01
+
+/* DMM32AT_AISTAT 0x08 */
+#define DMM32AT_STATUS 0x80
+
+/* DMM32AT_INTCLOCK 0x09 */
+#define DMM32AT_ADINT 0x80
+#define DMM32AT_CLKSEL 0x03
+
+/* DMM32AT_CNTRDIO 0x0a */
+#define DMM32AT_FREQ12 0x80
+
+/* DMM32AT_AICONF 0x0b */
+#define DMM32AT_RANGE_U10 0x0c
+#define DMM32AT_RANGE_U5 0x0d
+#define DMM32AT_RANGE_B10 0x08
+#define DMM32AT_RANGE_B5 0x00
+#define DMM32AT_SCINT_20 0x00
+#define DMM32AT_SCINT_15 0x10
+#define DMM32AT_SCINT_10 0x20
+#define DMM32AT_SCINT_5 0x30
+
+/* DMM32AT_CLKCT 0x0f */
+#define DMM32AT_CLKCT1 0x56	/* mode3 counter 1 - write low byte only */
+#define DMM32AT_CLKCT2 0xb6	/*  mode3 counter 2 - write high and low byte */
+
+/* DMM32AT_DIOCONF 0x0f */
+#define DMM32AT_DIENABLE 0x80
+#define DMM32AT_DIRA 0x10
+#define DMM32AT_DIRB 0x02
+#define DMM32AT_DIRCL 0x01
+#define DMM32AT_DIRCH 0x08
+
+/* board AI ranges in comedi structure */
+static const struct comedi_lrange dmm32at_airanges = {
+	4,
+	{
+			UNI_RANGE(10),
+			UNI_RANGE(5),
+			BIP_RANGE(10),
+			BIP_RANGE(5),
+		}
+};
+
+/* register values for above ranges */
+static const unsigned char dmm32at_rangebits[] = {
+	DMM32AT_RANGE_U10,
+	DMM32AT_RANGE_U5,
+	DMM32AT_RANGE_B10,
+	DMM32AT_RANGE_B5,
+};
+
+/* only one of these ranges is valid, as set by a jumper on the
+ * board. The application should only use the range set by the jumper
+ */
+static const struct comedi_lrange dmm32at_aoranges = {
+	4,
+	{
+			UNI_RANGE(10),
+			UNI_RANGE(5),
+			BIP_RANGE(10),
+			BIP_RANGE(5),
+		}
+};
+
+/*
+ * Board descriptions for two imaginary boards.  Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct dmm32at_board {
+	const char *name;
+	int ai_chans;
+	int ai_bits;
+	const struct comedi_lrange *ai_ranges;
+	int ao_chans;
+	int ao_bits;
+	const struct comedi_lrange *ao_ranges;
+	int have_dio;
+	int dio_chans;
+};
+static const struct dmm32at_board dmm32at_boards[] = {
+	{
+	      name:	"dmm32at",
+	      ai_chans:32,
+	      ai_bits:	16,
+	      ai_ranges:&dmm32at_airanges,
+	      ao_chans:4,
+	      ao_bits:	12,
+	      ao_ranges:&dmm32at_aoranges,
+	      have_dio:1,
+	      dio_chans:24,
+		},
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct dmm32at_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver.  If
+ * several hardware drivers keep similar information in this structure,
+ * feel free to suggest moving the variable to the struct comedi_device struct.
+ */
+struct dmm32at_private {
+
+	int data;
+	int ai_inuse;
+	unsigned int ai_scans_left;
+
+	/* Used for AO readback */
+	unsigned int ao_readback[4];
+	unsigned char dio_config;
+
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct dmm32at_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int dmm32at_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dmm32at_detach(struct comedi_device * dev);
+static struct comedi_driver driver_dmm32at = {
+      driver_name:"dmm32at",
+      module:THIS_MODULE,
+      attach:dmm32at_attach,
+      detach:dmm32at_detach,
+/* It is not necessary to implement the following members if you are
+ * writing a driver for a ISA PnP or PCI card */
+/* Most drivers will support multiple types of boards by
+ * having an array of board structures.  These were defined
+ * in dmm32at_boards[] above.  Note that the element 'name'
+ * was first in the structure -- Comedi uses this fact to
+ * extract the name of the board without knowing any details
+ * about the structure except for its length.
+ * When a device is attached (by comedi_config), the name
+ * of the device is given to Comedi, and Comedi tries to
+ * match it by going through the list of board names.  If
+ * there is a match, the address of the pointer is put
+ * into dev->board_ptr and driver->attach() is called.
+ *
+ * Note that these are not necessary if you can determine
+ * the type of board in software.  ISA PnP, PCI, and PCMCIA
+ * devices are such boards.
+ */
+      board_name:&dmm32at_boards[0].name,
+      offset:sizeof(struct dmm32at_board),
+      num_names:sizeof(dmm32at_boards) / sizeof(struct dmm32at_board),
+};
+
+/* prototypes for driver functions below */
+static int dmm32at_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int dmm32at_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int dmm32at_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int dmm32at_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int dmm32at_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int dmm32at_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd);
+static int dmm32at_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int dmm32at_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static int dmm32at_ns_to_timer(unsigned int *ns, int round);
+static irqreturn_t dmm32at_isr(int irq, void *d PT_REGS_ARG);
+void dmm32at_setaitimer(struct comedi_device * dev, unsigned int nansec);
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board.  If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int dmm32at_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	int ret;
+	struct comedi_subdevice *s;
+	unsigned char aihi, ailo, fifostat, aistat, intstat, airback;
+	unsigned long iobase;
+	unsigned int irq;
+
+	iobase = it->options[0];
+	irq = it->options[1];
+
+	printk("comedi%d: dmm32at: attaching\n", dev->minor);
+	printk("dmm32at: probing at address 0x%04lx, irq %u\n", iobase, irq);
+
+	/* register address space */
+	if (!request_region(iobase, DMM32AT_MEMSIZE, thisboard->name)) {
+		printk("I/O port conflict\n");
+		return -EIO;
+	}
+	dev->iobase = iobase;
+
+	/* the following just makes sure the board is there and gets
+	   it to a known state */
+
+	/* reset the board */
+	dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_RESET);
+
+	/* allow a millisecond to reset */
+	udelay(1000);
+
+	/* zero scan and fifo control */
+	dmm_outb(dev, DMM32AT_FIFOCNTRL, 0x0);
+
+	/* zero interrupt and clock control */
+	dmm_outb(dev, DMM32AT_INTCLOCK, 0x0);
+
+	/* write a test channel range, the high 3 bits should drop */
+	dmm_outb(dev, DMM32AT_AILOW, 0x80);
+	dmm_outb(dev, DMM32AT_AIHIGH, 0xff);
+
+	/* set the range at 10v unipolar */
+	dmm_outb(dev, DMM32AT_AICONF, DMM32AT_RANGE_U10);
+
+	/* should take 10 us to settle, here's a hundred */
+	udelay(100);
+
+	/* read back the values */
+	ailo = dmm_inb(dev, DMM32AT_AILOW);
+	aihi = dmm_inb(dev, DMM32AT_AIHIGH);
+	fifostat = dmm_inb(dev, DMM32AT_FIFOSTAT);
+	aistat = dmm_inb(dev, DMM32AT_AISTAT);
+	intstat = dmm_inb(dev, DMM32AT_INTCLOCK);
+	airback = dmm_inb(dev, DMM32AT_AIRBACK);
+
+	printk("dmm32at: lo=0x%02x hi=0x%02x fifostat=0x%02x\n",
+		ailo, aihi, fifostat);
+	printk("dmm32at: aistat=0x%02x intstat=0x%02x airback=0x%02x\n",
+		aistat, intstat, airback);
+
+	if ((ailo != 0x00) || (aihi != 0x1f) || (fifostat != 0x80) ||
+		(aistat != 0x60 || (intstat != 0x00) || airback != 0x0c)) {
+		printk("dmmat32: board detection failed\n");
+		return -EIO;
+	}
+
+	/* board is there, register interrupt */
+	if (irq) {
+		ret = comedi_request_irq(irq, dmm32at_isr, 0, thisboard->name,
+			dev);
+		if (ret < 0) {
+			printk("irq conflict\n");
+			return ret;
+		}
+		dev->irq = irq;
+	}
+
+/*
+ * If you can probe the device to determine what device in a series
+ * it is, this is the place to do it.  Otherwise, dev->board_ptr
+ * should already be initialized.
+ */
+	//dev->board_ptr = dmm32at_probe(dev);
+
+/*
+ * Initialize dev->board_name.  Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+	dev->board_name = thisboard->name;
+
+/*
+ * Allocate the private structure area.  alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+	if (alloc_private(dev, sizeof(struct dmm32at_private)) < 0)
+		return -ENOMEM;
+
+/*
+ * Allocate the subdevice structures.  alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+	if (alloc_subdevices(dev, 3) < 0)
+		return -ENOMEM;
+
+	s = dev->subdevices + 0;
+	dev->read_subdev = s;
+	/* analog input subdevice */
+	s->type = COMEDI_SUBD_AI;
+	/* we support single-ended (ground) and differential */
+	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
+	s->n_chan = thisboard->ai_chans;
+	s->maxdata = (1 << thisboard->ai_bits) - 1;
+	s->range_table = thisboard->ai_ranges;
+	s->len_chanlist = 32;	/* This is the maximum chanlist length that
+				   the board can handle */
+	s->insn_read = dmm32at_ai_rinsn;
+	s->do_cmd = dmm32at_ai_cmd;
+	s->do_cmdtest = dmm32at_ai_cmdtest;
+	s->cancel = dmm32at_ai_cancel;
+
+	s = dev->subdevices + 1;
+	/* analog output subdevice */
+	s->type = COMEDI_SUBD_AO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->n_chan = thisboard->ao_chans;
+	s->maxdata = (1 << thisboard->ao_bits) - 1;
+	s->range_table = thisboard->ao_ranges;
+	s->insn_write = dmm32at_ao_winsn;
+	s->insn_read = dmm32at_ao_rinsn;
+
+	s = dev->subdevices + 2;
+	/* digital i/o subdevice */
+	if (thisboard->have_dio) {
+
+		/* get access to the DIO regs */
+		dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_DIOACC);
+		/* set the DIO's to the defualt input setting */
+		devpriv->dio_config = DMM32AT_DIRA | DMM32AT_DIRB |
+			DMM32AT_DIRCL | DMM32AT_DIRCH | DMM32AT_DIENABLE;
+		dmm_outb(dev, DMM32AT_DIOCONF, devpriv->dio_config);
+
+		/* set up the subdevice */
+		s->type = COMEDI_SUBD_DIO;
+		s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+		s->n_chan = thisboard->dio_chans;
+		s->maxdata = 1;
+		s->state = 0;
+		s->range_table = &range_digital;
+		s->insn_bits = dmm32at_dio_insn_bits;
+		s->insn_config = dmm32at_dio_insn_config;
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	/* success */
+	printk("comedi%d: dmm32at: attached\n", dev->minor);
+
+	return 1;
+
+}
+
+/*
+ * _detach is called to deconfigure a device.  It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach().  dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int dmm32at_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: dmm32at: remove\n", dev->minor);
+	if (dev->irq)
+		comedi_free_irq(dev->irq, dev);
+	if (dev->iobase)
+		release_region(dev->iobase, DMM32AT_MEMSIZE);
+
+	return 0;
+}
+
+/*
+ * "instructions" read/write data in "one-shot" or "software-triggered"
+ * mode.
+ */
+
+static int dmm32at_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n, i;
+	unsigned int d;
+	unsigned char status;
+	unsigned short msb, lsb;
+	unsigned char chan;
+	int range;
+
+	/* get the channel and range number */
+
+	chan = CR_CHAN(insn->chanspec) & (s->n_chan - 1);
+	range = CR_RANGE(insn->chanspec);
+
+	//printk("channel=0x%02x, range=%d\n",chan,range);
+
+	/* zero scan and fifo control and reset fifo */
+	dmm_outb(dev, DMM32AT_FIFOCNTRL, DMM32AT_FIFORESET);
+
+	/* write the ai channel range regs */
+	dmm_outb(dev, DMM32AT_AILOW, chan);
+	dmm_outb(dev, DMM32AT_AIHIGH, chan);
+	/* set the range bits */
+	dmm_outb(dev, DMM32AT_AICONF, dmm32at_rangebits[range]);
+
+	/* wait for circuit to settle */
+	for (i = 0; i < 40000; i++) {
+		status = dmm_inb(dev, DMM32AT_AIRBACK);
+		if ((status & DMM32AT_STATUS) == 0)
+			break;
+	}
+	if (i == 40000) {
+		printk("timeout\n");
+		return -ETIMEDOUT;
+	}
+
+	/* convert n samples */
+	for (n = 0; n < insn->n; n++) {
+		/* trigger conversion */
+		dmm_outb(dev, DMM32AT_CONV, 0xff);
+		/* wait for conversion to end */
+		for (i = 0; i < 40000; i++) {
+			status = dmm_inb(dev, DMM32AT_AISTAT);
+			if ((status & DMM32AT_STATUS) == 0)
+				break;
+		}
+		if (i == 40000) {
+			printk("timeout\n");
+			return -ETIMEDOUT;
+		}
+
+		/* read data */
+		lsb = dmm_inb(dev, DMM32AT_AILSB);
+		msb = dmm_inb(dev, DMM32AT_AIMSB);
+
+		/* invert sign bit to make range unsigned, this is an
+		   idiosyncracy of the diamond board, it return
+		   conversions as a signed value, i.e. -32768 to
+		   32767, flipping the bit and interpreting it as
+		   signed gives you a range of 0 to 65535 which is
+		   used by comedi */
+		d = ((msb ^ 0x0080) << 8) + lsb;
+
+		data[n] = d;
+	}
+
+	/* return the number of samples read/written */
+	return n;
+}
+
+static int dmm32at_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp;
+	int start_chan, gain, i;
+
+	//printk("dmmat32 in command test\n");
+
+	/* cmdtest tests a particular command to see if it is valid.
+	 * Using the cmdtest ioctl, a user can create a valid cmd
+	 * and then have it executes by the cmd ioctl.
+	 *
+	 * cmdtest returns 1,2,3,4 or 0, depending on which tests
+	 * the command passes. */
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_TIMER /*| TRIG_EXT */ ;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_TIMER /*| TRIG_EXT */ ;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	/* note that mutual compatiblity is not an issue here */
+	if (cmd->scan_begin_src != TRIG_TIMER &&
+		cmd->scan_begin_src != TRIG_EXT)
+		err++;
+	if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+		err++;
+	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+#define MAX_SCAN_SPEED	1000000	/* in nanoseconds */
+#define MIN_SCAN_SPEED	1000000000	/* in nanoseconds */
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		if (cmd->scan_begin_arg < MAX_SCAN_SPEED) {
+			cmd->scan_begin_arg = MAX_SCAN_SPEED;
+			err++;
+		}
+		if (cmd->scan_begin_arg > MIN_SCAN_SPEED) {
+			cmd->scan_begin_arg = MIN_SCAN_SPEED;
+			err++;
+		}
+	} else {
+		/* external trigger */
+		/* should be level/edge, hi/lo specification here */
+		/* should specify multiple external triggers */
+		if (cmd->scan_begin_arg > 9) {
+			cmd->scan_begin_arg = 9;
+			err++;
+		}
+	}
+	if (cmd->convert_src == TRIG_TIMER) {
+		if (cmd->convert_arg >= 17500)
+			cmd->convert_arg = 20000;
+		else if (cmd->convert_arg >= 12500)
+			cmd->convert_arg = 15000;
+		else if (cmd->convert_arg >= 7500)
+			cmd->convert_arg = 10000;
+		else
+			cmd->convert_arg = 5000;
+
+	} else {
+		/* external trigger */
+		/* see above */
+		if (cmd->convert_arg > 9) {
+			cmd->convert_arg = 9;
+			err++;
+		}
+	}
+
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+	if (cmd->stop_src == TRIG_COUNT) {
+		if (cmd->stop_arg > 0xfffffff0) {
+			cmd->stop_arg = 0xfffffff0;
+			err++;
+		}
+		if (cmd->stop_arg == 0) {
+			cmd->stop_arg = 1;
+			err++;
+		}
+	} else {
+		/* TRIG_NONE */
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		tmp = cmd->scan_begin_arg;
+		dmm32at_ns_to_timer(&cmd->scan_begin_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+		if (tmp != cmd->scan_begin_arg)
+			err++;
+	}
+	if (cmd->convert_src == TRIG_TIMER) {
+		tmp = cmd->convert_arg;
+		dmm32at_ns_to_timer(&cmd->convert_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+		if (tmp != cmd->convert_arg)
+			err++;
+		if (cmd->scan_begin_src == TRIG_TIMER &&
+			cmd->scan_begin_arg <
+			cmd->convert_arg * cmd->scan_end_arg) {
+			cmd->scan_begin_arg =
+				cmd->convert_arg * cmd->scan_end_arg;
+			err++;
+		}
+	}
+
+	if (err)
+		return 4;
+
+	/* step 5 check the channel list, the channel list for this
+	   board must be consecutive and gains must be the same */
+
+	if (cmd->chanlist) {
+		gain = CR_RANGE(cmd->chanlist[0]);
+		start_chan = CR_CHAN(cmd->chanlist[0]);
+		for (i = 1; i < cmd->chanlist_len; i++) {
+			if (CR_CHAN(cmd->chanlist[i]) !=
+				(start_chan + i) % s->n_chan) {
+				comedi_error(dev,
+					"entries in chanlist must be consecutive channels, counting upwards\n");
+				err++;
+			}
+			if (CR_RANGE(cmd->chanlist[i]) != gain) {
+				comedi_error(dev,
+					"entries in chanlist must all have the same gain\n");
+				err++;
+			}
+		}
+	}
+
+	if (err)
+		return 5;
+
+	return 0;
+}
+
+static int dmm32at_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_cmd *cmd = &s->async->cmd;
+	int i, range;
+	unsigned char chanlo, chanhi, status;
+
+	if (!cmd->chanlist)
+		return -EINVAL;
+
+	/* get the channel list and range */
+	chanlo = CR_CHAN(cmd->chanlist[0]) & (s->n_chan - 1);
+	chanhi = chanlo + cmd->chanlist_len - 1;
+	if (chanhi >= s->n_chan)
+		return -EINVAL;
+	range = CR_RANGE(cmd->chanlist[0]);
+
+	/* reset fifo */
+	dmm_outb(dev, DMM32AT_FIFOCNTRL, DMM32AT_FIFORESET);
+
+	/* set scan enable */
+	dmm_outb(dev, DMM32AT_FIFOCNTRL, DMM32AT_SCANENABLE);
+
+	/* write the ai channel range regs */
+	dmm_outb(dev, DMM32AT_AILOW, chanlo);
+	dmm_outb(dev, DMM32AT_AIHIGH, chanhi);
+
+	/* set the range bits */
+	dmm_outb(dev, DMM32AT_AICONF, dmm32at_rangebits[range]);
+
+	/* reset the interrupt just in case */
+	dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_INTRESET);
+
+	if (cmd->stop_src == TRIG_COUNT)
+		devpriv->ai_scans_left = cmd->stop_arg;
+	else {			/* TRIG_NONE */
+		devpriv->ai_scans_left = 0xffffffff;	/* indicates TRIG_NONE to isr */
+	}
+
+	/* wait for circuit to settle */
+	for (i = 0; i < 40000; i++) {
+		status = dmm_inb(dev, DMM32AT_AIRBACK);
+		if ((status & DMM32AT_STATUS) == 0)
+			break;
+	}
+	if (i == 40000) {
+		printk("timeout\n");
+		return -ETIMEDOUT;
+	}
+
+	if (devpriv->ai_scans_left > 1) {
+		/* start the clock and enable the interrupts */
+		dmm32at_setaitimer(dev, cmd->scan_begin_arg);
+	} else {
+		/* start the interrups and initiate a single scan */
+		dmm_outb(dev, DMM32AT_INTCLOCK, DMM32AT_ADINT);
+		dmm_outb(dev, DMM32AT_CONV, 0xff);
+	}
+
+/* 	printk("dmmat32 in command\n"); */
+
+/* 	for(i=0;i<cmd->chanlist_len;i++) */
+/* 		comedi_buf_put(s->async,i*100); */
+
+/* 	s->async->events |= COMEDI_CB_EOA; */
+/* 	comedi_event(dev, s); */
+
+	return 0;
+
+}
+
+static int dmm32at_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	devpriv->ai_scans_left = 1;
+	return 0;
+}
+
+static irqreturn_t dmm32at_isr(int irq, void *d PT_REGS_ARG)
+{
+	unsigned char intstat;
+	unsigned int samp;
+	unsigned short msb, lsb;
+	int i;
+	struct comedi_device *dev = d;
+
+	if (!dev->attached) {
+		comedi_error(dev, "spurious interrupt");
+		return IRQ_HANDLED;
+	}
+
+	intstat = dmm_inb(dev, DMM32AT_INTCLOCK);
+
+	if (intstat & DMM32AT_ADINT) {
+		struct comedi_subdevice *s = dev->read_subdev;
+		struct comedi_cmd *cmd = &s->async->cmd;
+
+		for (i = 0; i < cmd->chanlist_len; i++) {
+			/* read data */
+			lsb = dmm_inb(dev, DMM32AT_AILSB);
+			msb = dmm_inb(dev, DMM32AT_AIMSB);
+
+			/* invert sign bit to make range unsigned */
+			samp = ((msb ^ 0x0080) << 8) + lsb;
+			comedi_buf_put(s->async, samp);
+		}
+
+		if (devpriv->ai_scans_left != 0xffffffff) {	/* TRIG_COUNT */
+			devpriv->ai_scans_left--;
+			if (devpriv->ai_scans_left == 0) {
+				/* disable further interrupts and clocks */
+				dmm_outb(dev, DMM32AT_INTCLOCK, 0x0);
+				/* set the buffer to be flushed with an EOF */
+				s->async->events |= COMEDI_CB_EOA;
+			}
+
+		}
+		/* flush the buffer */
+		comedi_event(dev, s);
+	}
+
+	/* reset the interrupt */
+	dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_INTRESET);
+	return IRQ_HANDLED;
+}
+
+/* This function doesn't require a particular form, this is just
+ * what happens to be used in some of the drivers.  It should
+ * convert ns nanoseconds to a counter value suitable for programming
+ * the device.  Also, it should adjust ns so that it cooresponds to
+ * the actual time that the device will use. */
+static int dmm32at_ns_to_timer(unsigned int *ns, int round)
+{
+	/* trivial timer */
+	/* if your timing is done through two cascaded timers, the
+	 * i8253_cascade_ns_to_timer() function in 8253.h can be
+	 * very helpful.  There are also i8254_load() and i8254_mm_load()
+	 * which can be used to load values into the ubiquitous 8254 counters
+	 */
+
+	return *ns;
+}
+
+static int dmm32at_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+	unsigned char hi, lo, status;
+
+	/* Writing a list of values to an AO channel is probably not
+	 * very useful, but that's how the interface is defined. */
+	for (i = 0; i < insn->n; i++) {
+
+		devpriv->ao_readback[chan] = data[i];
+
+		/* get the low byte */
+		lo = data[i] & 0x00ff;
+		/* high byte also contains channel number */
+		hi = (data[i] >> 8) + chan * (1 << 6);
+		//printk("writing 0x%02x  0x%02x\n",hi,lo);
+		/* write the low and high values to the board */
+		dmm_outb(dev, DMM32AT_DACLSB, lo);
+		dmm_outb(dev, DMM32AT_DACMSB, hi);
+
+		/* wait for circuit to settle */
+		for (i = 0; i < 40000; i++) {
+			status = dmm_inb(dev, DMM32AT_DACSTAT);
+			if ((status & DMM32AT_DACBUSY) == 0)
+				break;
+		}
+		if (i == 40000) {
+			printk("timeout\n");
+			return -ETIMEDOUT;
+		}
+		/* dummy read to update trigger the output */
+		status = dmm_inb(dev, DMM32AT_DACMSB);
+
+	}
+
+	/* return the number of samples read/written */
+	return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+ * Usually this means copying a value stored in devpriv. */
+static int dmm32at_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+
+	for (i = 0; i < insn->n; i++)
+		data[i] = devpriv->ao_readback[chan];
+
+	return i;
+}
+
+/* DIO devices are slightly special.  Although it is possible to
+ * implement the insn_read/insn_write interface, it is much more
+ * useful to applications if you implement the insn_bits interface.
+ * This allows packed reading/writing of the DIO channels.  The
+ * comedi core can convert between insn_bits and insn_read/write */
+static int dmm32at_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned char diobits;
+
+	if (insn->n != 2)
+		return -EINVAL;
+
+	/* The insn data is a mask in data[0] and the new data
+	 * in data[1], each channel cooresponding to a bit. */
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= data[0] & data[1];
+		/* Write out the new digital output lines */
+		//outw(s->state,dev->iobase + DMM32AT_DIO);
+	}
+
+	/* get access to the DIO regs */
+	dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_DIOACC);
+
+	/* if either part of dio is set for output */
+	if (((devpriv->dio_config & DMM32AT_DIRCL) == 0) ||
+		((devpriv->dio_config & DMM32AT_DIRCH) == 0)) {
+		diobits = (s->state & 0x00ff0000) >> 16;
+		dmm_outb(dev, DMM32AT_DIOC, diobits);
+	}
+	if ((devpriv->dio_config & DMM32AT_DIRB) == 0) {
+		diobits = (s->state & 0x0000ff00) >> 8;
+		dmm_outb(dev, DMM32AT_DIOB, diobits);
+	}
+	if ((devpriv->dio_config & DMM32AT_DIRA) == 0) {
+		diobits = (s->state & 0x000000ff);
+		dmm_outb(dev, DMM32AT_DIOA, diobits);
+	}
+
+	/* now read the state back in */
+	s->state = dmm_inb(dev, DMM32AT_DIOC);
+	s->state <<= 8;
+	s->state |= dmm_inb(dev, DMM32AT_DIOB);
+	s->state <<= 8;
+	s->state |= dmm_inb(dev, DMM32AT_DIOA);
+	data[1] = s->state;
+
+	/* on return, data[1] contains the value of the digital
+	 * input and output lines. */
+	//data[1]=inw(dev->iobase + DMM32AT_DIO);
+	/* or we could just return the software copy of the output values if
+	 * it was a purely digital output subdevice */
+	//data[1]=s->state;
+
+	return 2;
+}
+
+static int dmm32at_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned char chanbit;
+	int chan = CR_CHAN(insn->chanspec);
+
+	if (insn->n != 1)
+		return -EINVAL;
+
+	if (chan < 8)
+		chanbit = DMM32AT_DIRA;
+	else if (chan < 16)
+		chanbit = DMM32AT_DIRB;
+	else if (chan < 20)
+		chanbit = DMM32AT_DIRCL;
+	else
+		chanbit = DMM32AT_DIRCH;
+
+	/* The input or output configuration of each digital line is
+	 * configured by a special insn_config instruction.  chanspec
+	 * contains the channel to be changed, and data[0] contains the
+	 * value COMEDI_INPUT or COMEDI_OUTPUT. */
+
+	/* if output clear the bit, otherwise set it */
+	if (data[0] == COMEDI_OUTPUT) {
+		devpriv->dio_config &= ~chanbit;
+	} else {
+		devpriv->dio_config |= chanbit;
+	}
+	/* get access to the DIO regs */
+	dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_DIOACC);
+	/* set the DIO's to the new configuration setting */
+	dmm_outb(dev, DMM32AT_DIOCONF, devpriv->dio_config);
+
+	return 1;
+}
+
+void dmm32at_setaitimer(struct comedi_device * dev, unsigned int nansec)
+{
+	unsigned char lo1, lo2, hi2;
+	unsigned short both2;
+
+	/* based on 10mhz clock */
+	lo1 = 200;
+	both2 = nansec / 20000;
+	hi2 = (both2 & 0xff00) >> 8;
+	lo2 = both2 & 0x00ff;
+
+	/* set the counter frequency to 10mhz */
+	dmm_outb(dev, DMM32AT_CNTRDIO, 0);
+
+	/* get access to the clock regs */
+	dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_CLKACC);
+
+	/* write the counter 1 control word and low byte to counter */
+	dmm_outb(dev, DMM32AT_CLKCT, DMM32AT_CLKCT1);
+	dmm_outb(dev, DMM32AT_CLK1, lo1);
+
+	/* write the counter 2 control word and low byte then to counter */
+	dmm_outb(dev, DMM32AT_CLKCT, DMM32AT_CLKCT2);
+	dmm_outb(dev, DMM32AT_CLK2, lo2);
+	dmm_outb(dev, DMM32AT_CLK2, hi2);
+
+	/* enable the ai conversion interrupt and the clock to start scans */
+	dmm_outb(dev, DMM32AT_INTCLOCK, DMM32AT_ADINT | DMM32AT_CLKSEL);
+
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver_dmm32at);
diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c
new file mode 100644
index 0000000..5e0eed8
--- /dev/null
+++ b/drivers/staging/comedi/drivers/dt2801.c
@@ -0,0 +1,697 @@
+/*
+ * comedi/drivers/dt2801.c
+ * Device Driver for DataTranslation DT2801
+ *
+ */
+/*
+Driver: dt2801
+Description: Data Translation DT2801 series and DT01-EZ
+Author: ds
+Status: works
+Devices: [Data Translation] DT2801 (dt2801), DT2801-A, DT2801/5716A,
+  DT2805, DT2805/5716A, DT2808, DT2818, DT2809, DT01-EZ
+
+This driver can autoprobe the type of board.
+
+Configuration options:
+  [0] - I/O port base address
+  [1] - unused
+  [2] - A/D reference 0=differential, 1=single-ended
+  [3] - A/D range
+          0 = [-10,10]
+	  1 = [0,10]
+  [4] - D/A 0 range
+          0 = [-10,10]
+	  1 = [-5,5]
+	  2 = [-2.5,2.5]
+	  3 = [0,10]
+	  4 = [0,5]
+  [5] - D/A 1 range (same choices)
+*/
+
+#include "../comedidev.h"
+#include <linux/delay.h>
+#include <linux/ioport.h>
+
+#define DT2801_TIMEOUT 1000
+
+/* Hardware Configuration */
+/* ====================== */
+
+#define DT2801_MAX_DMA_SIZE (64 * 1024)
+
+/* Ports */
+#define DT2801_IOSIZE 2
+
+/* define's */
+/* ====================== */
+
+/* Commands */
+#define DT_C_RESET       0x0
+#define DT_C_CLEAR_ERR   0x1
+#define DT_C_READ_ERRREG 0x2
+#define DT_C_SET_CLOCK   0x3
+
+#define DT_C_TEST        0xb
+#define DT_C_STOP        0xf
+
+#define DT_C_SET_DIGIN   0x4
+#define DT_C_SET_DIGOUT  0x5
+#define DT_C_READ_DIG    0x6
+#define DT_C_WRITE_DIG   0x7
+
+#define DT_C_WRITE_DAIM  0x8
+#define DT_C_SET_DA      0x9
+#define DT_C_WRITE_DA    0xa
+
+#define DT_C_READ_ADIM   0xc
+#define DT_C_SET_AD      0xd
+#define DT_C_READ_AD     0xe
+
+/* Command modifiers (only used with read/write), EXTTRIG can be
+   used with some other commands.
+*/
+#define DT_MOD_DMA     (1<<4)
+#define DT_MOD_CONT    (1<<5)
+#define DT_MOD_EXTCLK  (1<<6)
+#define DT_MOD_EXTTRIG (1<<7)
+
+/* Bits in status register */
+#define DT_S_DATA_OUT_READY   (1<<0)
+#define DT_S_DATA_IN_FULL     (1<<1)
+#define DT_S_READY            (1<<2)
+#define DT_S_COMMAND          (1<<3)
+#define DT_S_COMPOSITE_ERROR  (1<<7)
+
+/* registers */
+#define DT2801_DATA		0
+#define DT2801_STATUS		1
+#define DT2801_CMD		1
+
+static int dt2801_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dt2801_detach(struct comedi_device * dev);
+static struct comedi_driver driver_dt2801 = {
+      driver_name:"dt2801",
+      module:THIS_MODULE,
+      attach:dt2801_attach,
+      detach:dt2801_detach,
+};
+
+COMEDI_INITCLEANUP(driver_dt2801);
+
+#if 0
+// ignore 'defined but not used' warning
+static const struct comedi_lrange range_dt2801_ai_pgh_bipolar = { 4, {
+			RANGE(-10, 10),
+			RANGE(-5, 5),
+			RANGE(-2.5, 2.5),
+			RANGE(-1.25, 1.25),
+	}
+};
+#endif
+static const struct comedi_lrange range_dt2801_ai_pgl_bipolar = { 4, {
+			RANGE(-10, 10),
+			RANGE(-1, 1),
+			RANGE(-0.1, 0.1),
+			RANGE(-0.02, 0.02),
+	}
+};
+
+#if 0
+// ignore 'defined but not used' warning
+static const struct comedi_lrange range_dt2801_ai_pgh_unipolar = { 4, {
+			RANGE(0, 10),
+			RANGE(0, 5),
+			RANGE(0, 2.5),
+			RANGE(0, 1.25),
+	}
+};
+#endif
+static const struct comedi_lrange range_dt2801_ai_pgl_unipolar = { 4, {
+			RANGE(0, 10),
+			RANGE(0, 1),
+			RANGE(0, 0.1),
+			RANGE(0, 0.02),
+	}
+};
+
+struct dt2801_board {
+
+	const char *name;
+	int boardcode;
+	int ad_diff;
+	int ad_chan;
+	int adbits;
+	int adrangetype;
+	int dabits;
+};
+
+
+/* Typeid's for the different boards of the DT2801-series
+   (taken from the test-software, that comes with the board)
+   */
+static const struct dt2801_board boardtypes[] = {
+	{
+	      name:	"dt2801",
+	      boardcode:0x09,
+	      ad_diff:	2,
+	      ad_chan:	16,
+	      adbits:	12,
+	      adrangetype:0,
+      dabits:	12},
+	{
+	      name:	"dt2801-a",
+	      boardcode:0x52,
+	      ad_diff:	2,
+	      ad_chan:	16,
+	      adbits:	12,
+	      adrangetype:0,
+      dabits:	12},
+	{
+	      name:	"dt2801/5716a",
+	      boardcode:0x82,
+	      ad_diff:	1,
+	      ad_chan:	16,
+	      adbits:	16,
+	      adrangetype:1,
+      dabits:	12},
+	{
+	      name:	"dt2805",
+	      boardcode:0x12,
+	      ad_diff:	1,
+	      ad_chan:	16,
+	      adbits:	12,
+	      adrangetype:0,
+      dabits:	12},
+	{
+	      name:	"dt2805/5716a",
+	      boardcode:0x92,
+	      ad_diff:	1,
+	      ad_chan:	16,
+	      adbits:	16,
+	      adrangetype:1,
+      dabits:	12},
+	{
+	      name:	"dt2808",
+	      boardcode:0x20,
+	      ad_diff:	0,
+	      ad_chan:	16,
+	      adbits:	12,
+	      adrangetype:2,
+      dabits:	8},
+	{
+	      name:	"dt2818",
+	      boardcode:0xa2,
+	      ad_diff:	0,
+	      ad_chan:	4,
+	      adbits:	12,
+	      adrangetype:0,
+      dabits:	12},
+	{
+	      name:	"dt2809",
+	      boardcode:0xb0,
+	      ad_diff:	0,
+	      ad_chan:	8,
+	      adbits:	12,
+	      adrangetype:1,
+      dabits:	12},
+};
+
+#define n_boardtypes ((sizeof(boardtypes))/(sizeof(boardtypes[0])))
+#define boardtype (*(const struct dt2801_board *)dev->board_ptr)
+
+struct dt2801_private {
+
+	const struct comedi_lrange *dac_range_types[2];
+	unsigned int ao_readback[2];
+};
+
+#define devpriv ((struct dt2801_private *)dev->private)
+
+static int dt2801_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int dt2801_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int dt2801_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int dt2801_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int dt2801_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+/* These are the low-level routines:
+   writecommand: write a command to the board
+   writedata: write data byte
+   readdata: read data byte
+ */
+
+/* Only checks DataOutReady-flag, not the Ready-flag as it is done
+   in the examples of the manual. I don't see why this should be
+   necessary. */
+static int dt2801_readdata(struct comedi_device * dev, int *data)
+{
+	int stat = 0;
+	int timeout = DT2801_TIMEOUT;
+
+	do {
+		stat = inb_p(dev->iobase + DT2801_STATUS);
+		if (stat & (DT_S_COMPOSITE_ERROR | DT_S_READY)) {
+			return stat;
+		}
+		if (stat & DT_S_DATA_OUT_READY) {
+			*data = inb_p(dev->iobase + DT2801_DATA);
+			return 0;
+		}
+	} while (--timeout > 0);
+
+	return -ETIME;
+}
+
+static int dt2801_readdata2(struct comedi_device * dev, int *data)
+{
+	int lb, hb;
+	int ret;
+
+	ret = dt2801_readdata(dev, &lb);
+	if (ret)
+		return ret;
+	ret = dt2801_readdata(dev, &hb);
+	if (ret)
+		return ret;
+
+	*data = (hb << 8) + lb;
+	return 0;
+}
+
+static int dt2801_writedata(struct comedi_device * dev, unsigned int data)
+{
+	int stat = 0;
+	int timeout = DT2801_TIMEOUT;
+
+	do {
+		stat = inb_p(dev->iobase + DT2801_STATUS);
+
+		if (stat & DT_S_COMPOSITE_ERROR) {
+			return stat;
+		}
+		if (!(stat & DT_S_DATA_IN_FULL)) {
+			outb_p(data & 0xff, dev->iobase + DT2801_DATA);
+			return 0;
+		}
+#if 0
+		if (stat & DT_S_READY) {
+			printk("dt2801: ready flag set (bad!) in dt2801_writedata()\n");
+			return -EIO;
+		}
+#endif
+	} while (--timeout > 0);
+
+	return -ETIME;
+}
+
+static int dt2801_writedata2(struct comedi_device * dev, unsigned int data)
+{
+	int ret;
+
+	ret = dt2801_writedata(dev, data & 0xff);
+	if (ret < 0)
+		return ret;
+	ret = dt2801_writedata(dev, (data >> 8));
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int dt2801_wait_for_ready(struct comedi_device * dev)
+{
+	int timeout = DT2801_TIMEOUT;
+	int stat;
+
+	stat = inb_p(dev->iobase + DT2801_STATUS);
+	if (stat & DT_S_READY) {
+		return 0;
+	}
+	do {
+		stat = inb_p(dev->iobase + DT2801_STATUS);
+
+		if (stat & DT_S_COMPOSITE_ERROR) {
+			return stat;
+		}
+		if (stat & DT_S_READY) {
+			return 0;
+		}
+	} while (--timeout > 0);
+
+	return -ETIME;
+}
+
+static int dt2801_writecmd(struct comedi_device * dev, int command)
+{
+	int stat;
+
+	dt2801_wait_for_ready(dev);
+
+	stat = inb_p(dev->iobase + DT2801_STATUS);
+	if (stat & DT_S_COMPOSITE_ERROR) {
+		printk("dt2801: composite-error in dt2801_writecmd(), ignoring\n");
+	}
+	if (!(stat & DT_S_READY)) {
+		printk("dt2801: !ready in dt2801_writecmd(), ignoring\n");
+	}
+	outb_p(command, dev->iobase + DT2801_CMD);
+
+	return 0;
+}
+
+static int dt2801_reset(struct comedi_device * dev)
+{
+	int board_code = 0;
+	unsigned int stat;
+	int timeout;
+
+	DPRINTK("dt2801: resetting board...\n");
+	DPRINTK("fingerprint: 0x%02x 0x%02x\n", inb_p(dev->iobase),
+		inb_p(dev->iobase + 1));
+
+	/* pull random data from data port */
+	inb_p(dev->iobase + DT2801_DATA);
+	inb_p(dev->iobase + DT2801_DATA);
+	inb_p(dev->iobase + DT2801_DATA);
+	inb_p(dev->iobase + DT2801_DATA);
+
+	DPRINTK("dt2801: stop\n");
+	//dt2801_writecmd(dev,DT_C_STOP);
+	outb_p(DT_C_STOP, dev->iobase + DT2801_CMD);
+
+	//dt2801_wait_for_ready(dev);
+	comedi_udelay(100);
+	timeout = 10000;
+	do {
+		stat = inb_p(dev->iobase + DT2801_STATUS);
+		if (stat & DT_S_READY)
+			break;
+	} while (timeout--);
+	if (!timeout) {
+		printk("dt2801: timeout 1 status=0x%02x\n", stat);
+	}
+	//printk("dt2801: reading dummy\n");
+	//dt2801_readdata(dev,&board_code);
+
+	DPRINTK("dt2801: reset\n");
+	outb_p(DT_C_RESET, dev->iobase + DT2801_CMD);
+	//dt2801_writecmd(dev,DT_C_RESET);
+
+	comedi_udelay(100);
+	timeout = 10000;
+	do {
+		stat = inb_p(dev->iobase + DT2801_STATUS);
+		if (stat & DT_S_READY)
+			break;
+	} while (timeout--);
+	if (!timeout) {
+		printk("dt2801: timeout 2 status=0x%02x\n", stat);
+	}
+
+	DPRINTK("dt2801: reading code\n");
+	dt2801_readdata(dev, &board_code);
+
+	DPRINTK("dt2801: ok.  code=0x%02x\n", board_code);
+
+	return board_code;
+}
+
+static int probe_number_of_ai_chans(struct comedi_device * dev)
+{
+	int n_chans;
+	int stat;
+	int data;
+
+	for (n_chans = 0; n_chans < 16; n_chans++) {
+		stat = dt2801_writecmd(dev, DT_C_READ_ADIM);
+		dt2801_writedata(dev, 0);
+		dt2801_writedata(dev, n_chans);
+		stat = dt2801_readdata2(dev, &data);
+
+		if (stat)
+			break;
+	}
+
+	dt2801_reset(dev);
+	dt2801_reset(dev);
+
+	return n_chans;
+}
+
+static const struct comedi_lrange *dac_range_table[] = {
+	&range_bipolar10,
+	&range_bipolar5,
+	&range_bipolar2_5,
+	&range_unipolar10,
+	&range_unipolar5
+};
+
+static const struct comedi_lrange *dac_range_lkup(int opt)
+{
+	if (opt < 0 || opt > 5)
+		return &range_unknown;
+	return dac_range_table[opt];
+}
+
+static const struct comedi_lrange *ai_range_lkup(int type, int opt)
+{
+	switch (type) {
+	case 0:
+		return (opt) ?
+			&range_dt2801_ai_pgl_unipolar :
+			&range_dt2801_ai_pgl_bipolar;
+	case 1:
+		return (opt) ? &range_unipolar10 : &range_bipolar10;
+	case 2:
+		return &range_unipolar5;
+	}
+	return &range_unknown;
+}
+
+/*
+   options:
+	[0] - i/o base
+	[1] - unused
+	[2] - a/d 0=differential, 1=single-ended
+	[3] - a/d range 0=[-10,10], 1=[0,10]
+	[4] - dac0 range 0=[-10,10], 1=[-5,5], 2=[-2.5,2.5] 3=[0,10], 4=[0,5]
+	[5] - dac1 range 0=[-10,10], 1=[-5,5], 2=[-2.5,2.5] 3=[0,10], 4=[0,5]
+*/
+static int dt2801_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	unsigned long iobase;
+	int board_code, type;
+	int ret = 0;
+	int n_ai_chans;
+
+	iobase = it->options[0];
+	if (!request_region(iobase, DT2801_IOSIZE, "dt2801")) {
+		comedi_error(dev, "I/O port conflict");
+		return -EIO;
+	}
+	dev->iobase = iobase;
+
+	/* do some checking */
+
+	board_code = dt2801_reset(dev);
+
+	/* heh.  if it didn't work, try it again. */
+	if (!board_code)
+		board_code = dt2801_reset(dev);
+
+	for (type = 0; type < n_boardtypes; type++) {
+		if (boardtypes[type].boardcode == board_code)
+			goto havetype;
+	}
+	printk("dt2801: unrecognized board code=0x%02x, contact author\n",
+		board_code);
+	type = 0;
+
+      havetype:
+	dev->board_ptr = boardtypes + type;
+	printk("dt2801: %s at port 0x%lx", boardtype.name, iobase);
+
+	n_ai_chans = probe_number_of_ai_chans(dev);
+	printk(" (ai channels = %d)", n_ai_chans);
+
+	if ((ret = alloc_subdevices(dev, 4)) < 0)
+		goto out;
+
+	if ((ret = alloc_private(dev, sizeof(struct dt2801_private))) < 0)
+		goto out;
+
+	dev->board_name = boardtype.name;
+
+	s = dev->subdevices + 0;
+	/* ai subdevice */
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE | SDF_GROUND;
+#if 1
+	s->n_chan = n_ai_chans;
+#else
+	if (it->options[2])
+		s->n_chan = boardtype.ad_chan;
+	else
+		s->n_chan = boardtype.ad_chan / 2;
+#endif
+	s->maxdata = (1 << boardtype.adbits) - 1;
+	s->range_table = ai_range_lkup(boardtype.adrangetype, it->options[3]);
+	s->insn_read = dt2801_ai_insn_read;
+
+	s++;
+	/* ao subdevice */
+	s->type = COMEDI_SUBD_AO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->n_chan = 2;
+	s->maxdata = (1 << boardtype.dabits) - 1;
+	s->range_table_list = devpriv->dac_range_types;
+	devpriv->dac_range_types[0] = dac_range_lkup(it->options[4]);
+	devpriv->dac_range_types[1] = dac_range_lkup(it->options[5]);
+	s->insn_read = dt2801_ao_insn_read;
+	s->insn_write = dt2801_ao_insn_write;
+
+	s++;
+	/* 1st digital subdevice */
+	s->type = COMEDI_SUBD_DIO;
+	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+	s->n_chan = 8;
+	s->maxdata = 1;
+	s->range_table = &range_digital;
+	s->insn_bits = dt2801_dio_insn_bits;
+	s->insn_config = dt2801_dio_insn_config;
+
+	s++;
+	/* 2nd digital subdevice */
+	s->type = COMEDI_SUBD_DIO;
+	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+	s->n_chan = 8;
+	s->maxdata = 1;
+	s->range_table = &range_digital;
+	s->insn_bits = dt2801_dio_insn_bits;
+	s->insn_config = dt2801_dio_insn_config;
+
+	ret = 0;
+      out:
+	printk("\n");
+
+	return ret;
+}
+
+static int dt2801_detach(struct comedi_device * dev)
+{
+	if (dev->iobase)
+		release_region(dev->iobase, DT2801_IOSIZE);
+
+	return 0;
+}
+
+static int dt2801_error(struct comedi_device * dev, int stat)
+{
+	if (stat < 0) {
+		if (stat == -ETIME) {
+			printk("dt2801: timeout\n");
+		} else {
+			printk("dt2801: error %d\n", stat);
+		}
+		return stat;
+	}
+	printk("dt2801: error status 0x%02x, resetting...\n", stat);
+
+	dt2801_reset(dev);
+	dt2801_reset(dev);
+
+	return -EIO;
+}
+
+static int dt2801_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int d;
+	int stat;
+	int i;
+
+	for (i = 0; i < insn->n; i++) {
+		stat = dt2801_writecmd(dev, DT_C_READ_ADIM);
+		dt2801_writedata(dev, CR_RANGE(insn->chanspec));
+		dt2801_writedata(dev, CR_CHAN(insn->chanspec));
+		stat = dt2801_readdata2(dev, &d);
+
+		if (stat != 0)
+			return dt2801_error(dev, stat);
+
+		data[i] = d;
+	}
+
+	return i;
+}
+
+static int dt2801_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	data[0] = devpriv->ao_readback[CR_CHAN(insn->chanspec)];
+
+	return 1;
+}
+
+static int dt2801_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	dt2801_writecmd(dev, DT_C_WRITE_DAIM);
+	dt2801_writedata(dev, CR_CHAN(insn->chanspec));
+	dt2801_writedata2(dev, data[0]);
+
+	devpriv->ao_readback[CR_CHAN(insn->chanspec)] = data[0];
+
+	return 1;
+}
+
+static int dt2801_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int which = 0;
+
+	if (s == dev->subdevices + 4)
+		which = 1;
+
+	if (insn->n != 2)
+		return -EINVAL;
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= (data[0] & data[1]);
+		dt2801_writecmd(dev, DT_C_WRITE_DIG);
+		dt2801_writedata(dev, which);
+		dt2801_writedata(dev, s->state);
+	}
+	dt2801_writecmd(dev, DT_C_READ_DIG);
+	dt2801_writedata(dev, which);
+	dt2801_readdata(dev, data + 1);
+
+	return 2;
+}
+
+static int dt2801_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int which = 0;
+
+	if (s == dev->subdevices + 4)
+		which = 1;
+
+	/* configure */
+	if (data[0]) {
+		s->io_bits = 0xff;
+		dt2801_writecmd(dev, DT_C_SET_DIGOUT);
+	} else {
+		s->io_bits = 0;
+		dt2801_writecmd(dev, DT_C_SET_DIGIN);
+	}
+	dt2801_writedata(dev, which);
+
+	return 1;
+}
diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c
new file mode 100644
index 0000000..795932e
--- /dev/null
+++ b/drivers/staging/comedi/drivers/dt2811.c
@@ -0,0 +1,604 @@
+/*
+   comedi/drivers/dt2811.c
+   Hardware driver for Data Translation DT2811
+
+   COMEDI - Linux Control and Measurement Device Interface
+   History:
+   Base Version  - David A. Schleef <ds@schleef.org>
+   December 1998 - Updated to work.  David does not have a DT2811
+   board any longer so this was suffering from bitrot.
+   Updated performed by ...
+
+   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.
+ */
+/*
+Driver: dt2811
+Description: Data Translation DT2811
+Author: ds
+Devices: [Data Translation] DT2811-PGL (dt2811-pgl), DT2811-PGH (dt2811-pgh)
+Status: works
+
+Configuration options:
+  [0] - I/O port base address
+  [1] - IRQ, although this is currently unused
+  [2] - A/D reference
+          0 = signle-ended
+          1 = differential
+	  2 = pseudo-differential (common reference)
+  [3] - A/D range
+          0 = [-5,5]
+	  1 = [-2.5,2.5]
+	  2 = [0,5]
+  [4] - D/A 0 range (same choices)
+  [4] - D/A 1 range (same choices)
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+static const char *driver_name = "dt2811";
+
+static const struct comedi_lrange range_dt2811_pgh_ai_5_unipolar = { 4, {
+			RANGE(0, 5),
+			RANGE(0, 2.5),
+			RANGE(0, 1.25),
+			RANGE(0, 0.625)
+	}
+};
+static const struct comedi_lrange range_dt2811_pgh_ai_2_5_bipolar = { 4, {
+			RANGE(-2.5, 2.5),
+			RANGE(-1.25, 1.25),
+			RANGE(-0.625, 0.625),
+			RANGE(-0.3125, 0.3125)
+	}
+};
+static const struct comedi_lrange range_dt2811_pgh_ai_5_bipolar = { 4, {
+			RANGE(-5, 5),
+			RANGE(-2.5, 2.5),
+			RANGE(-1.25, 1.25),
+			RANGE(-0.625, 0.625)
+	}
+};
+static const struct comedi_lrange range_dt2811_pgl_ai_5_unipolar = { 4, {
+			RANGE(0, 5),
+			RANGE(0, 0.5),
+			RANGE(0, 0.05),
+			RANGE(0, 0.01)
+	}
+};
+static const struct comedi_lrange range_dt2811_pgl_ai_2_5_bipolar = { 4, {
+			RANGE(-2.5, 2.5),
+			RANGE(-0.25, 0.25),
+			RANGE(-0.025, 0.025),
+			RANGE(-0.005, 0.005)
+	}
+};
+static const struct comedi_lrange range_dt2811_pgl_ai_5_bipolar = { 4, {
+			RANGE(-5, 5),
+			RANGE(-0.5, 0.5),
+			RANGE(-0.05, 0.05),
+			RANGE(-0.01, 0.01)
+	}
+};
+
+/*
+
+   0x00    ADCSR R/W  A/D Control/Status Register
+   bit 7 - (R) 1 indicates A/D conversion done
+   reading ADDAT clears bit
+   (W) ignored
+   bit 6 - (R) 1 indicates A/D error
+   (W) ignored
+   bit 5 - (R) 1 indicates A/D busy, cleared at end
+   of conversion
+   (W) ignored
+   bit 4 - (R) 0
+   (W)
+   bit 3 - (R) 0
+   bit 2 - (R/W) 1 indicates interrupts enabled
+   bits 1,0 - (R/W) mode bits
+   00  single conversion on ADGCR load
+   01  continuous conversion, internal clock,
+   (clock enabled on ADGCR load)
+   10  continuous conversion, internal clock,
+   external trigger
+   11  continuous conversion, external clock,
+   external trigger
+
+   0x01    ADGCR R/W A/D Gain/Channel Register
+   bit 6,7 - (R/W) gain select
+   00  gain=1, both PGH, PGL models
+   01  gain=2 PGH, 10 PGL
+   10  gain=4 PGH, 100 PGL
+   11  gain=8 PGH, 500 PGL
+   bit 4,5 - reserved
+   bit 3-0 - (R/W) channel select
+   channel number from 0-15
+
+   0x02,0x03 (R) ADDAT A/D Data Register
+   (W) DADAT0 D/A Data Register 0
+   0x02 low byte
+   0x03 high byte
+
+   0x04,0x05 (W) DADAT0 D/A Data Register 1
+
+   0x06 (R) DIO0 Digital Input Port 0
+   (W) DIO1 Digital Output Port 1
+
+   0x07 TMRCTR (R/W) Timer/Counter Register
+   bits 6,7 - reserved
+   bits 5-3 - Timer frequency control (mantissa)
+   543  divisor  freqency (kHz)
+   000  1        600
+   001  10       60
+   010  2        300
+   011  3        200
+   100  4        150
+   101  5        120
+   110  6        100
+   111  12       50
+   bits 2-0 - Timer frequency control (exponent)
+   210  multiply divisor/divide frequency by
+   000  1
+   001  10
+   010  100
+   011  1000
+   100  10000
+   101  100000
+   110  1000000
+   111  10000000
+
+ */
+
+#define TIMEOUT 10000
+
+#define DT2811_SIZE 8
+
+#define DT2811_ADCSR 0
+#define DT2811_ADGCR 1
+#define DT2811_ADDATLO 2
+#define DT2811_ADDATHI 3
+#define DT2811_DADAT0LO 2
+#define DT2811_DADAT0HI 3
+#define DT2811_DADAT1LO 4
+#define DT2811_DADAT1HI 5
+#define DT2811_DIO 6
+#define DT2811_TMRCTR 7
+
+/*
+ * flags
+ */
+
+/* ADCSR */
+
+#define DT2811_ADDONE   0x80
+#define DT2811_ADERROR  0x40
+#define DT2811_ADBUSY   0x20
+#define DT2811_CLRERROR 0x10
+#define DT2811_INTENB   0x04
+#define DT2811_ADMODE   0x03
+
+struct dt2811_board {
+
+	const char *name;
+	const struct comedi_lrange *bip_5;
+	const struct comedi_lrange *bip_2_5;
+	const struct comedi_lrange *unip_5;
+};
+
+static const struct dt2811_board boardtypes[] = {
+	{"dt2811-pgh",
+			&range_dt2811_pgh_ai_5_bipolar,
+			&range_dt2811_pgh_ai_2_5_bipolar,
+			&range_dt2811_pgh_ai_5_unipolar,
+		},
+	{"dt2811-pgl",
+			&range_dt2811_pgl_ai_5_bipolar,
+			&range_dt2811_pgl_ai_2_5_bipolar,
+			&range_dt2811_pgl_ai_5_unipolar,
+		},
+};
+
+#define this_board ((const struct dt2811_board *)dev->board_ptr)
+
+static int dt2811_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dt2811_detach(struct comedi_device * dev);
+static struct comedi_driver driver_dt2811 = {
+      driver_name:"dt2811",
+      module:THIS_MODULE,
+      attach:dt2811_attach,
+      detach:dt2811_detach,
+      board_name:&boardtypes[0].name,
+      num_names:sizeof(boardtypes) / sizeof(struct dt2811_board),
+      offset:sizeof(struct dt2811_board),
+};
+
+COMEDI_INITCLEANUP(driver_dt2811);
+
+static int dt2811_ai_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int dt2811_ao_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int dt2811_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int dt2811_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int dt2811_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+enum { card_2811_pgh, card_2811_pgl };
+
+struct dt2811_private {
+	int ntrig;
+	int curadchan;
+	enum {
+		adc_singleended, adc_diff, adc_pseudo_diff
+	} adc_mux;
+	enum {
+		dac_bipolar_5, dac_bipolar_2_5, dac_unipolar_5
+	} dac_range[2];
+	const struct comedi_lrange *range_type_list[2];
+	unsigned int ao_readback[2];
+};
+
+#define devpriv ((struct dt2811_private *)dev->private)
+
+static const struct comedi_lrange *dac_range_types[] = {
+	&range_bipolar5,
+	&range_bipolar2_5,
+	&range_unipolar5
+};
+
+#define DT2811_TIMEOUT 5
+
+#if 0
+static irqreturn_t dt2811_interrupt(int irq, void *d PT_REGS_ARG)
+{
+	int lo, hi;
+	int data;
+	struct comedi_device *dev = d;
+
+	if (!dev->attached) {
+		comedi_error(dev, "spurious interrupt");
+		return IRQ_HANDLED;
+	}
+
+	lo = inb(dev->iobase + DT2811_ADDATLO);
+	hi = inb(dev->iobase + DT2811_ADDATHI);
+
+	data = lo + (hi << 8);
+
+	if (!(--devpriv->ntrig)) {
+		/* how to turn off acquisition */
+		s->async->events |= COMEDI_SB_EOA;
+	}
+	comedi_event(dev, s);
+	return IRQ_HANDLED;
+}
+#endif
+
+/*
+  options[0]   Board base address
+  options[1]   IRQ
+  options[2]   Input configuration
+                 0 == single-ended
+                 1 == differential
+                 2 == pseudo-differential
+  options[3]   Analog input range configuration
+                 0 == bipolar 5  (-5V -- +5V)
+                 1 == bipolar 2.5V  (-2.5V -- +2.5V)
+                 2 == unipolar 5V  (0V -- +5V)
+  options[4]   Analog output 0 range configuration
+                 0 == bipolar 5  (-5V -- +5V)
+                 1 == bipolar 2.5V  (-2.5V -- +2.5V)
+                 2 == unipolar 5V  (0V -- +5V)
+  options[5]   Analog output 1 range configuration
+                 0 == bipolar 5  (-5V -- +5V)
+                 1 == bipolar 2.5V  (-2.5V -- +2.5V)
+                 2 == unipolar 5V  (0V -- +5V)
+*/
+
+static int dt2811_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	//int i, irq;
+	//unsigned long irqs;
+	//long flags;
+	int ret;
+	struct comedi_subdevice *s;
+	unsigned long iobase;
+
+	iobase = it->options[0];
+
+	printk("comedi%d: dt2811: base=0x%04lx\n", dev->minor, iobase);
+
+	if (!request_region(iobase, DT2811_SIZE, driver_name)) {
+		printk("I/O port conflict\n");
+		return -EIO;
+	}
+
+	dev->iobase = iobase;
+	dev->board_name = this_board->name;
+
+#if 0
+	outb(0, dev->iobase + DT2811_ADCSR);
+	comedi_udelay(100);
+	i = inb(dev->iobase + DT2811_ADDATLO);
+	i = inb(dev->iobase + DT2811_ADDATHI);
+#endif
+
+#if 0
+	irq = it->options[1];
+	if (irq < 0) {
+		save_flags(flags);
+		sti();
+		irqs = probe_irq_on();
+
+		outb(DT2811_CLRERROR | DT2811_INTENB,
+			dev->iobase + DT2811_ADCSR);
+		outb(0, dev->iobase + DT2811_ADGCR);
+
+		comedi_udelay(100);
+
+		irq = probe_irq_off(irqs);
+		restore_flags(flags);
+
+		/*outb(DT2811_CLRERROR|DT2811_INTENB,dev->iobase+DT2811_ADCSR); */
+
+		if (inb(dev->iobase + DT2811_ADCSR) & DT2811_ADERROR) {
+			printk("error probing irq (bad) \n");
+		}
+		dev->irq = 0;
+		if (irq > 0) {
+			i = inb(dev->iobase + DT2811_ADDATLO);
+			i = inb(dev->iobase + DT2811_ADDATHI);
+			printk("(irq = %d)\n", irq);
+			ret = comedi_request_irq(irq, dt2811_interrupt, 0,
+				driver_name, dev);
+			if (ret < 0)
+				return -EIO;
+			dev->irq = irq;
+		} else if (irq == 0) {
+			printk("(no irq)\n");
+		} else {
+			printk("( multiple irq's -- this is bad! )\n");
+		}
+	}
+#endif
+
+	if ((ret = alloc_subdevices(dev, 4)) < 0)
+		return ret;
+	if ((ret = alloc_private(dev, sizeof(struct dt2811_private))) < 0)
+		return ret;
+	switch (it->options[2]) {
+	case 0:
+		devpriv->adc_mux = adc_singleended;
+		break;
+	case 1:
+		devpriv->adc_mux = adc_diff;
+		break;
+	case 2:
+		devpriv->adc_mux = adc_pseudo_diff;
+		break;
+	default:
+		devpriv->adc_mux = adc_singleended;
+		break;
+	}
+	switch (it->options[4]) {
+	case 0:
+		devpriv->dac_range[0] = dac_bipolar_5;
+		break;
+	case 1:
+		devpriv->dac_range[0] = dac_bipolar_2_5;
+		break;
+	case 2:
+		devpriv->dac_range[0] = dac_unipolar_5;
+		break;
+	default:
+		devpriv->dac_range[0] = dac_bipolar_5;
+		break;
+	}
+	switch (it->options[5]) {
+	case 0:
+		devpriv->dac_range[1] = dac_bipolar_5;
+		break;
+	case 1:
+		devpriv->dac_range[1] = dac_bipolar_2_5;
+		break;
+	case 2:
+		devpriv->dac_range[1] = dac_unipolar_5;
+		break;
+	default:
+		devpriv->dac_range[1] = dac_bipolar_5;
+		break;
+	}
+
+	s = dev->subdevices + 0;
+	/* initialize the ADC subdevice */
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE | SDF_GROUND;
+	s->n_chan = devpriv->adc_mux == adc_diff ? 8 : 16;
+	s->insn_read = dt2811_ai_insn;
+	s->maxdata = 0xfff;
+	switch (it->options[3]) {
+	case 0:
+	default:
+		s->range_table = this_board->bip_5;
+		break;
+	case 1:
+		s->range_table = this_board->bip_2_5;
+		break;
+	case 2:
+		s->range_table = this_board->unip_5;
+		break;
+	}
+
+	s = dev->subdevices + 1;
+	/* ao subdevice */
+	s->type = COMEDI_SUBD_AO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->n_chan = 2;
+	s->insn_write = dt2811_ao_insn;
+	s->insn_read = dt2811_ao_insn_read;
+	s->maxdata = 0xfff;
+	s->range_table_list = devpriv->range_type_list;
+	devpriv->range_type_list[0] = dac_range_types[devpriv->dac_range[0]];
+	devpriv->range_type_list[1] = dac_range_types[devpriv->dac_range[1]];
+
+	s = dev->subdevices + 2;
+	/* di subdevice */
+	s->type = COMEDI_SUBD_DI;
+	s->subdev_flags = SDF_READABLE;
+	s->n_chan = 8;
+	s->insn_bits = dt2811_di_insn_bits;
+	s->maxdata = 1;
+	s->range_table = &range_digital;
+
+	s = dev->subdevices + 3;
+	/* do subdevice */
+	s->type = COMEDI_SUBD_DO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->n_chan = 8;
+	s->insn_bits = dt2811_do_insn_bits;
+	s->maxdata = 1;
+	s->state = 0;
+	s->range_table = &range_digital;
+
+	return 0;
+}
+
+static int dt2811_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: dt2811: remove\n", dev->minor);
+
+	if (dev->irq) {
+		comedi_free_irq(dev->irq, dev);
+	}
+	if (dev->iobase) {
+		release_region(dev->iobase, DT2811_SIZE);
+	}
+
+	return 0;
+}
+
+static int dt2811_ai_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int chan = CR_CHAN(insn->chanspec);
+	int timeout = DT2811_TIMEOUT;
+	int i;
+
+	for (i = 0; i < insn->n; i++) {
+		outb(chan, dev->iobase + DT2811_ADGCR);
+
+		while (timeout
+			&& inb(dev->iobase + DT2811_ADCSR) & DT2811_ADBUSY)
+			timeout--;
+		if (!timeout)
+			return -ETIME;
+
+		data[i] = inb(dev->iobase + DT2811_ADDATLO);
+		data[i] |= inb(dev->iobase + DT2811_ADDATHI) << 8;
+		data[i] &= 0xfff;
+	}
+
+	return i;
+}
+
+#if 0
+/* Wow.  This is code from the Comedi stone age.  But it hasn't been
+ * replaced, so I'll let it stay. */
+int dt2811_adtrig(kdev_t minor, comedi_adtrig * adtrig)
+{
+	struct comedi_device *dev = comedi_devices + minor;
+
+	if (adtrig->n < 1)
+		return 0;
+	dev->curadchan = adtrig->chan;
+	switch (dev->i_admode) {
+	case COMEDI_MDEMAND:
+		dev->ntrig = adtrig->n - 1;
+		/*printk("dt2811: AD soft trigger\n"); */
+		/*outb(DT2811_CLRERROR|DT2811_INTENB,dev->iobase+DT2811_ADCSR); *//* not neccessary */
+		outb(dev->curadchan, dev->iobase + DT2811_ADGCR);
+		do_gettimeofday(&trigtime);
+		break;
+	case COMEDI_MCONTS:
+		dev->ntrig = adtrig->n;
+		break;
+	}
+
+	return 0;
+}
+#endif
+
+static int dt2811_ao_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan;
+
+	chan = CR_CHAN(insn->chanspec);
+
+	for (i = 0; i < insn->n; i++) {
+		outb(data[i] & 0xff, dev->iobase + DT2811_DADAT0LO + 2 * chan);
+		outb((data[i] >> 8) & 0xff,
+			dev->iobase + DT2811_DADAT0HI + 2 * chan);
+		devpriv->ao_readback[chan] = data[i];
+	}
+
+	return i;
+}
+
+static int dt2811_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan;
+
+	chan = CR_CHAN(insn->chanspec);
+
+	for (i = 0; i < insn->n; i++) {
+		data[i] = devpriv->ao_readback[chan];
+	}
+
+	return i;
+}
+
+static int dt2811_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	data[1] = inb(dev->iobase + DT2811_DIO);
+
+	return 2;
+}
+
+static int dt2811_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	s->state &= ~data[0];
+	s->state |= data[0] & data[1];
+	outb(s->state, dev->iobase + DT2811_DIO);
+
+	data[1] = s->state;
+
+	return 2;
+}
diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c
new file mode 100644
index 0000000..8320139
--- /dev/null
+++ b/drivers/staging/comedi/drivers/dt2814.c
@@ -0,0 +1,383 @@
+/*
+    comedi/drivers/dt2814.c
+    Hardware driver for Data Translation DT2814
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 1998 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: dt2814
+Description: Data Translation DT2814
+Author: ds
+Status: complete
+Devices: [Data Translation] DT2814 (dt2814)
+
+Configuration options:
+  [0] - I/O port base address
+  [1] - IRQ
+
+This card has 16 analog inputs multiplexed onto a 12 bit ADC.  There
+is a minimally useful onboard clock.  The base frequency for the
+clock is selected by jumpers, and the clock divider can be selected
+via programmed I/O.  Unfortunately, the clock divider can only be
+a power of 10, from 1 to 10^7, of which only 3 or 4 are useful.  In
+addition, the clock does not seem to be very accurate.
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/delay.h>
+
+#define DT2814_SIZE 2
+
+#define DT2814_CSR 0
+#define DT2814_DATA 1
+
+/*
+ * flags
+ */
+
+#define DT2814_FINISH 0x80
+#define DT2814_ERR 0x40
+#define DT2814_BUSY 0x20
+#define DT2814_ENB 0x10
+#define DT2814_CHANMASK 0x0f
+
+static int dt2814_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dt2814_detach(struct comedi_device * dev);
+static struct comedi_driver driver_dt2814 = {
+      driver_name:"dt2814",
+      module:THIS_MODULE,
+      attach:dt2814_attach,
+      detach:dt2814_detach,
+};
+
+COMEDI_INITCLEANUP(driver_dt2814);
+
+static irqreturn_t dt2814_interrupt(int irq, void *dev PT_REGS_ARG);
+
+struct dt2814_private {
+
+	int ntrig;
+	int curadchan;
+};
+
+#define devpriv ((struct dt2814_private *)dev->private)
+
+#define DT2814_TIMEOUT 10
+#define DT2814_MAX_SPEED 100000	/* Arbitrary 10 khz limit */
+
+static int dt2814_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n, i, hi, lo;
+	int chan;
+	int status = 0;
+
+	for (n = 0; n < insn->n; n++) {
+		chan = CR_CHAN(insn->chanspec);
+
+		outb(chan, dev->iobase + DT2814_CSR);
+		for (i = 0; i < DT2814_TIMEOUT; i++) {
+			status = inb(dev->iobase + DT2814_CSR);
+			printk("dt2814: status: %02x\n", status);
+			comedi_udelay(10);
+			if (status & DT2814_FINISH)
+				break;
+		}
+		if (i >= DT2814_TIMEOUT) {
+			printk("dt2814: status: %02x\n", status);
+			return -ETIMEDOUT;
+		}
+
+		hi = inb(dev->iobase + DT2814_DATA);
+		lo = inb(dev->iobase + DT2814_DATA);
+
+		data[n] = (hi << 4) | (lo >> 4);
+	}
+
+	return n;
+}
+
+static int dt2814_ns_to_timer(unsigned int *ns, unsigned int flags)
+{
+	int i;
+	unsigned int f;
+
+	/* XXX ignores flags */
+
+	f = 10000;		/* ns */
+	for (i = 0; i < 8; i++) {
+		if ((2 * (*ns)) < (f * 11))
+			break;
+		f *= 10;
+	}
+
+	*ns = f;
+
+	return i;
+}
+
+static int dt2814_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp;
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_TIMER;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_NOW;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	/* note that mutual compatiblity is not an issue here */
+	if (cmd->stop_src != TRIG_TIMER && cmd->stop_src != TRIG_EXT)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+	if (cmd->scan_begin_arg > 1000000000) {
+		cmd->scan_begin_arg = 1000000000;
+		err++;
+	}
+	if (cmd->scan_begin_arg < DT2814_MAX_SPEED) {
+		cmd->scan_begin_arg = DT2814_MAX_SPEED;
+		err++;
+	}
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+	if (cmd->stop_src == TRIG_COUNT) {
+		if (cmd->stop_arg < 2) {
+			cmd->stop_arg = 2;
+			err++;
+		}
+	} else {
+		/* TRIG_NONE */
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	tmp = cmd->scan_begin_arg;
+	dt2814_ns_to_timer(&cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK);
+	if (tmp != cmd->scan_begin_arg)
+		err++;
+
+	if (err)
+		return 4;
+
+	return 0;
+}
+
+static int dt2814_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_cmd *cmd = &s->async->cmd;
+	int chan;
+	int trigvar;
+
+	trigvar =
+		dt2814_ns_to_timer(&cmd->scan_begin_arg,
+		cmd->flags & TRIG_ROUND_MASK);
+
+	chan = CR_CHAN(cmd->chanlist[0]);
+
+	devpriv->ntrig = cmd->stop_arg;
+	outb(chan | DT2814_ENB | (trigvar << 5), dev->iobase + DT2814_CSR);
+
+	return 0;
+
+}
+
+static int dt2814_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	int i, irq;
+	int ret;
+	struct comedi_subdevice *s;
+	unsigned long iobase;
+
+	iobase = it->options[0];
+	printk("comedi%d: dt2814: 0x%04lx ", dev->minor, iobase);
+	if (!request_region(iobase, DT2814_SIZE, "dt2814")) {
+		printk("I/O port conflict\n");
+		return -EIO;
+	}
+	dev->iobase = iobase;
+	dev->board_name = "dt2814";
+
+	outb(0, dev->iobase + DT2814_CSR);
+	comedi_udelay(100);
+	if (inb(dev->iobase + DT2814_CSR) & DT2814_ERR) {
+		printk("reset error (fatal)\n");
+		return -EIO;
+	}
+	i = inb(dev->iobase + DT2814_DATA);
+	i = inb(dev->iobase + DT2814_DATA);
+
+	irq = it->options[1];
+#if 0
+	if (irq < 0) {
+		save_flags(flags);
+		sti();
+		irqs = probe_irq_on();
+
+		outb(0, dev->iobase + DT2814_CSR);
+
+		comedi_udelay(100);
+
+		irq = probe_irq_off(irqs);
+		restore_flags(flags);
+		if (inb(dev->iobase + DT2814_CSR) & DT2814_ERR) {
+			printk("error probing irq (bad) \n");
+		}
+
+		i = inb(dev->iobase + DT2814_DATA);
+		i = inb(dev->iobase + DT2814_DATA);
+	}
+#endif
+	dev->irq = 0;
+	if (irq > 0) {
+		if (comedi_request_irq(irq, dt2814_interrupt, 0, "dt2814", dev)) {
+			printk("(irq %d unavailable)\n", irq);
+		} else {
+			printk("( irq = %d )\n", irq);
+			dev->irq = irq;
+		}
+	} else if (irq == 0) {
+		printk("(no irq)\n");
+	} else {
+#if 0
+		printk("(probe returned multiple irqs--bad)\n");
+#else
+		printk("(irq probe not implemented)\n");
+#endif
+	}
+
+	if ((ret = alloc_subdevices(dev, 1)) < 0)
+		return ret;
+	if ((ret = alloc_private(dev, sizeof(struct dt2814_private))) < 0)
+		return ret;
+
+	s = dev->subdevices + 0;
+	dev->read_subdev = s;
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
+	s->n_chan = 16;		/* XXX */
+	s->len_chanlist = 1;
+	s->insn_read = dt2814_ai_insn_read;
+	s->do_cmd = dt2814_ai_cmd;
+	s->do_cmdtest = dt2814_ai_cmdtest;
+	s->maxdata = 0xfff;
+	s->range_table = &range_unknown;	/* XXX */
+
+	return 0;
+}
+
+static int dt2814_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: dt2814: remove\n", dev->minor);
+
+	if (dev->irq) {
+		comedi_free_irq(dev->irq, dev);
+	}
+	if (dev->iobase) {
+		release_region(dev->iobase, DT2814_SIZE);
+	}
+
+	return 0;
+}
+
+static irqreturn_t dt2814_interrupt(int irq, void *d PT_REGS_ARG)
+{
+	int lo, hi;
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s;
+	int data;
+
+	if (!dev->attached) {
+		comedi_error(dev, "spurious interrupt");
+		return IRQ_HANDLED;
+	}
+
+	s = dev->subdevices + 0;
+
+	hi = inb(dev->iobase + DT2814_DATA);
+	lo = inb(dev->iobase + DT2814_DATA);
+
+	data = (hi << 4) | (lo >> 4);
+
+	if (!(--devpriv->ntrig)) {
+		int i;
+
+		outb(0, dev->iobase + DT2814_CSR);
+		/* note: turning off timed mode triggers another
+		   sample. */
+
+		for (i = 0; i < DT2814_TIMEOUT; i++) {
+			if (inb(dev->iobase + DT2814_CSR) & DT2814_FINISH)
+				break;
+		}
+		inb(dev->iobase + DT2814_DATA);
+		inb(dev->iobase + DT2814_DATA);
+
+		s->async->events |= COMEDI_CB_EOA;
+	}
+	comedi_event(dev, s);
+	return IRQ_HANDLED;
+}
diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c
new file mode 100644
index 0000000..fccec8a
--- /dev/null
+++ b/drivers/staging/comedi/drivers/dt2815.c
@@ -0,0 +1,264 @@
+/*
+   comedi/drivers/dt2815.c
+   Hardware driver for Data Translation DT2815
+
+   COMEDI - Linux Control and Measurement Device Interface
+   Copyright (C) 1999 Anders Blomdell <anders.blomdell@control.lth.se>
+
+   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.
+
+ */
+/*
+Driver: dt2815
+Description: Data Translation DT2815
+Author: ds
+Status: mostly complete, untested
+Devices: [Data Translation] DT2815 (dt2815)
+
+I'm not sure anyone has ever tested this board.  If you have information
+contrary, please update.
+
+Configuration options:
+  [0] - I/O port base base address
+  [1] - IRQ (unused)
+  [2] - Voltage unipolar/bipolar configuration
+          0 == unipolar 5V  (0V -- +5V)
+	  1 == bipolar 5V  (-5V -- +5V)
+  [3] - Current offset configuration
+          0 == disabled  (0mA -- +32mAV)
+          1 == enabled  (+4mA -- +20mAV)
+  [4] - Firmware program configuration
+          0 == program 1 (see manual table 5-4)
+          1 == program 2 (see manual table 5-4)
+          2 == program 3 (see manual table 5-4)
+          3 == program 4 (see manual table 5-4)
+  [5] - Analog output 0 range configuration
+          0 == voltage
+          1 == current
+  [6] - Analog output 1 range configuration (same options)
+  [7] - Analog output 2 range configuration (same options)
+  [8] - Analog output 3 range configuration (same options)
+  [9] - Analog output 4 range configuration (same options)
+  [10] - Analog output 5 range configuration (same options)
+  [11] - Analog output 6 range configuration (same options)
+  [12] - Analog output 7 range configuration (same options)
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/delay.h>
+
+static const struct comedi_lrange range_dt2815_ao_32_current = { 1, {
+			RANGE_mA(0, 32)
+	}
+};
+static const struct comedi_lrange range_dt2815_ao_20_current = { 1, {
+			RANGE_mA(4, 20)
+	}
+};
+
+#define DT2815_SIZE 2
+
+#define DT2815_DATA 0
+#define DT2815_STATUS 1
+
+static int dt2815_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dt2815_detach(struct comedi_device * dev);
+static struct comedi_driver driver_dt2815 = {
+      driver_name:"dt2815",
+      module:THIS_MODULE,
+      attach:dt2815_attach,
+      detach:dt2815_detach,
+};
+
+COMEDI_INITCLEANUP(driver_dt2815);
+
+static void dt2815_free_resources(struct comedi_device * dev);
+
+struct dt2815_private {
+
+	const struct comedi_lrange *range_type_list[8];
+	unsigned int ao_readback[8];
+};
+
+
+#define devpriv ((struct dt2815_private *)dev->private)
+
+static int dt2815_wait_for_status(struct comedi_device * dev, int status)
+{
+	int i;
+
+	for (i = 0; i < 100; i++) {
+		if (inb(dev->iobase + DT2815_STATUS) == status)
+			break;
+	}
+	return status;
+}
+
+static int dt2815_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+
+	for (i = 0; i < insn->n; i++) {
+		data[i] = devpriv->ao_readback[chan];
+	}
+
+	return i;
+}
+
+static int dt2815_ao_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+	unsigned int status;
+	unsigned int lo, hi;
+
+	for (i = 0; i < insn->n; i++) {
+		lo = ((data[i] & 0x0f) << 4) | (chan << 1) | 0x01;
+		hi = (data[i] & 0xff0) >> 4;
+
+		status = dt2815_wait_for_status(dev, 0x00);
+		if (status != 0) {
+			rt_printk
+				("dt2815: failed to write low byte on %d reason %x\n",
+				chan, status);
+			return -EBUSY;
+		}
+
+		outb(lo, dev->iobase + DT2815_DATA);
+
+		status = dt2815_wait_for_status(dev, 0x10);
+		if (status != 0x10) {
+			rt_printk
+				("dt2815: failed to write high byte on %d reason %x\n",
+				chan, status);
+			return -EBUSY;
+		}
+		devpriv->ao_readback[chan] = data[i];
+	}
+	return i;
+}
+
+/*
+  options[0]   Board base address
+  options[1]   IRQ (not applicable)
+  options[2]   Voltage unipolar/bipolar configuration
+                 0 == unipolar 5V  (0V -- +5V)
+		 1 == bipolar 5V  (-5V -- +5V)
+  options[3]   Current offset configuration
+                 0 == disabled  (0mA -- +32mAV)
+                 1 == enabled  (+4mA -- +20mAV)
+  options[4]   Firmware program configuration
+                 0 == program 1 (see manual table 5-4)
+                 1 == program 2 (see manual table 5-4)
+                 2 == program 3 (see manual table 5-4)
+                 3 == program 4 (see manual table 5-4)
+  options[5]   Analog output 0 range configuration
+                 0 == voltage
+                 1 == current
+  options[6]   Analog output 1 range configuration
+  ...
+  options[12]   Analog output 7 range configuration
+                 0 == voltage
+                 1 == current
+ */
+
+static int dt2815_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	int i;
+	const struct comedi_lrange *current_range_type, *voltage_range_type;
+	unsigned long iobase;
+
+	iobase = it->options[0];
+	printk("comedi%d: dt2815: 0x%04lx ", dev->minor, iobase);
+	if (!request_region(iobase, DT2815_SIZE, "dt2815")) {
+		printk("I/O port conflict\n");
+		return -EIO;
+	}
+
+	dev->iobase = iobase;
+	dev->board_name = "dt2815";
+
+	if (alloc_subdevices(dev, 1) < 0)
+		return -ENOMEM;
+	if (alloc_private(dev, sizeof(struct dt2815_private)) < 0)
+		return -ENOMEM;
+
+	s = dev->subdevices;
+	/* ao subdevice */
+	s->type = COMEDI_SUBD_AO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->maxdata = 0xfff;
+	s->n_chan = 8;
+	s->insn_write = dt2815_ao_insn;
+	s->insn_read = dt2815_ao_insn_read;
+	s->range_table_list = devpriv->range_type_list;
+
+	current_range_type = (it->options[3])
+		? &range_dt2815_ao_20_current : &range_dt2815_ao_32_current;
+	voltage_range_type = (it->options[2])
+		? &range_bipolar5 : &range_unipolar5;
+	for (i = 0; i < 8; i++) {
+		devpriv->range_type_list[i] = (it->options[5 + i])
+			? current_range_type : voltage_range_type;
+	}
+
+	/* Init the 2815 */
+	outb(0x00, dev->iobase + DT2815_STATUS);
+	for (i = 0; i < 100; i++) {
+		/* This is incredibly slow (approx 20 ms) */
+		unsigned int status;
+
+		comedi_udelay(1000);
+		status = inb(dev->iobase + DT2815_STATUS);
+		if (status == 4) {
+			unsigned int program;
+			program = (it->options[4] & 0x3) << 3 | 0x7;
+			outb(program, dev->iobase + DT2815_DATA);
+			printk(", program: 0x%x (@t=%d)\n", program, i);
+			break;
+		} else if (status != 0x00) {
+			printk("dt2815: unexpected status 0x%x (@t=%d)\n",
+				status, i);
+			if (status & 0x60) {
+				outb(0x00, dev->iobase + DT2815_STATUS);
+			}
+		}
+	}
+
+	printk("\n");
+
+	return 0;
+}
+
+static void dt2815_free_resources(struct comedi_device * dev)
+{
+	if (dev->iobase)
+		release_region(dev->iobase, DT2815_SIZE);
+}
+
+static int dt2815_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: dt2815: remove\n", dev->minor);
+
+	dt2815_free_resources(dev);
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/dt2817.c b/drivers/staging/comedi/drivers/dt2817.c
new file mode 100644
index 0000000..2dc396a
--- /dev/null
+++ b/drivers/staging/comedi/drivers/dt2817.c
@@ -0,0 +1,178 @@
+/*
+    comedi/drivers/dt2817.c
+    Hardware driver for Data Translation DT2817
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 1998 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: dt2817
+Description: Data Translation DT2817
+Author: ds
+Status: complete
+Devices: [Data Translation] DT2817 (dt2817)
+
+A very simple digital I/O card.  Four banks of 8 lines, each bank
+is configurable for input or output.  One wonders why it takes a
+50 page manual to describe this thing.
+
+The driver (which, btw, is much less than 50 pages) has 1 subdevice
+with 32 channels, configurable in groups of 8.
+
+Configuration options:
+  [0] - I/O port base base address
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define DT2817_SIZE 5
+
+#define DT2817_CR 0
+#define DT2817_DATA 1
+
+static int dt2817_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dt2817_detach(struct comedi_device * dev);
+static struct comedi_driver driver_dt2817 = {
+      driver_name:"dt2817",
+      module:THIS_MODULE,
+      attach:dt2817_attach,
+      detach:dt2817_detach,
+};
+
+COMEDI_INITCLEANUP(driver_dt2817);
+
+static int dt2817_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int mask;
+	int chan;
+	int oe = 0;
+
+	if (insn->n != 1)
+		return -EINVAL;
+
+	chan = CR_CHAN(insn->chanspec);
+	if (chan < 8) {
+		mask = 0xff;
+	} else if (chan < 16) {
+		mask = 0xff00;
+	} else if (chan < 24) {
+		mask = 0xff0000;
+	} else
+		mask = 0xff000000;
+	if (data[0])
+		s->io_bits |= mask;
+	else
+		s->io_bits &= ~mask;
+
+	if (s->io_bits & 0x000000ff)
+		oe |= 0x1;
+	if (s->io_bits & 0x0000ff00)
+		oe |= 0x2;
+	if (s->io_bits & 0x00ff0000)
+		oe |= 0x4;
+	if (s->io_bits & 0xff000000)
+		oe |= 0x8;
+
+	outb(oe, dev->iobase + DT2817_CR);
+
+	return 1;
+}
+
+static int dt2817_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int changed;
+
+	/* It's questionable whether it is more important in
+	 * a driver like this to be deterministic or fast.
+	 * We choose fast. */
+
+	if (data[0]) {
+		changed = s->state;
+		s->state &= ~data[0];
+		s->state |= (data[0] & data[1]);
+		changed ^= s->state;
+		changed &= s->io_bits;
+		if (changed & 0x000000ff)
+			outb(s->state & 0xff, dev->iobase + DT2817_DATA + 0);
+		if (changed & 0x0000ff00)
+			outb((s->state >> 8) & 0xff,
+				dev->iobase + DT2817_DATA + 1);
+		if (changed & 0x00ff0000)
+			outb((s->state >> 16) & 0xff,
+				dev->iobase + DT2817_DATA + 2);
+		if (changed & 0xff000000)
+			outb((s->state >> 24) & 0xff,
+				dev->iobase + DT2817_DATA + 3);
+	}
+	data[1] = inb(dev->iobase + DT2817_DATA + 0);
+	data[1] |= (inb(dev->iobase + DT2817_DATA + 1) << 8);
+	data[1] |= (inb(dev->iobase + DT2817_DATA + 2) << 16);
+	data[1] |= (inb(dev->iobase + DT2817_DATA + 3) << 24);
+
+	return 2;
+}
+
+static int dt2817_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	int ret;
+	struct comedi_subdevice *s;
+	unsigned long iobase;
+
+	iobase = it->options[0];
+	printk("comedi%d: dt2817: 0x%04lx ", dev->minor, iobase);
+	if (!request_region(iobase, DT2817_SIZE, "dt2817")) {
+		printk("I/O port conflict\n");
+		return -EIO;
+	}
+	dev->iobase = iobase;
+	dev->board_name = "dt2817";
+
+	if ((ret = alloc_subdevices(dev, 1)) < 0)
+		return ret;
+
+	s = dev->subdevices + 0;
+
+	s->n_chan = 32;
+	s->type = COMEDI_SUBD_DIO;
+	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+	s->range_table = &range_digital;
+	s->maxdata = 1;
+	s->insn_bits = dt2817_dio_insn_bits;
+	s->insn_config = dt2817_dio_insn_config;
+
+	s->state = 0;
+	outb(0, dev->iobase + DT2817_CR);
+
+	printk("\n");
+
+	return 0;
+}
+
+static int dt2817_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: dt2817: remove\n", dev->minor);
+
+	if (dev->iobase)
+		release_region(dev->iobase, DT2817_SIZE);
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c
new file mode 100644
index 0000000..4882c3e
--- /dev/null
+++ b/drivers/staging/comedi/drivers/dt282x.c
@@ -0,0 +1,1471 @@
+/*
+   comedi/drivers/dt282x.c
+   Hardware driver for Data Translation DT2821 series
+
+   COMEDI - Linux Control and Measurement Device Interface
+   Copyright (C) 1997-8 David A. Schleef <ds@schleef.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.
+
+   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.
+
+ */
+/*
+Driver: dt282x
+Description: Data Translation DT2821 series (including DT-EZ)
+Author: ds
+Devices: [Data Translation] DT2821 (dt2821),
+  DT2821-F-16SE (dt2821-f), DT2821-F-8DI (dt2821-f),
+  DT2821-G-16SE (dt2821-f), DT2821-G-8DI (dt2821-g),
+  DT2823 (dt2823),
+  DT2824-PGH (dt2824-pgh), DT2824-PGL (dt2824-pgl), DT2825 (dt2825),
+  DT2827 (dt2827), DT2828 (dt2828), DT21-EZ (dt21-ez), DT23-EZ (dt23-ez),
+  DT24-EZ (dt24-ez), DT24-EZ-PGL (dt24-ez-pgl)
+Status: complete
+Updated: Wed, 22 Aug 2001 17:11:34 -0700
+
+Configuration options:
+  [0] - I/O port base address
+  [1] - IRQ
+  [2] - DMA 1
+  [3] - DMA 2
+  [4] - AI jumpered for 0=single ended, 1=differential
+  [5] - AI jumpered for 0=straight binary, 1=2's complement
+  [6] - AO 0 jumpered for 0=straight binary, 1=2's complement
+  [7] - AO 1 jumpered for 0=straight binary, 1=2's complement
+  [8] - AI jumpered for 0=[-10,10]V, 1=[0,10], 2=[-5,5], 3=[0,5]
+  [9] - AO 0 jumpered for 0=[-10,10]V, 1=[0,10], 2=[-5,5], 3=[0,5],
+        4=[-2.5,2.5]
+  [10]- A0 1 jumpered for 0=[-10,10]V, 1=[0,10], 2=[-5,5], 3=[0,5],
+        4=[-2.5,2.5]
+
+Notes:
+  - AO commands might be broken.
+  - If you try to run a command on both the AI and AO subdevices
+    simultaneously, bad things will happen.  The driver needs to
+    be fixed to check for this situation and return an error.
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <asm/dma.h>
+#include "comedi_fc.h"
+
+#define DEBUG
+
+#define DT2821_TIMEOUT		100	/* 500 us */
+#define DT2821_SIZE 0x10
+
+/*
+ *    Registers in the DT282x
+ */
+
+#define DT2821_ADCSR	0x00	/* A/D Control/Status             */
+#define DT2821_CHANCSR	0x02	/* Channel Control/Status */
+#define DT2821_ADDAT	0x04	/* A/D data                       */
+#define DT2821_DACSR	0x06	/* D/A Control/Status             */
+#define DT2821_DADAT	0x08	/* D/A data                       */
+#define DT2821_DIODAT	0x0a	/* digital data                   */
+#define DT2821_SUPCSR	0x0c	/* Supervisor Control/Status      */
+#define DT2821_TMRCTR	0x0e	/* Timer/Counter          */
+
+/*
+ *  At power up, some registers are in a well-known state.  The
+ *  masks and values are as follows:
+ */
+
+#define DT2821_ADCSR_MASK 0xfff0
+#define DT2821_ADCSR_VAL 0x7c00
+
+#define DT2821_CHANCSR_MASK 0xf0f0
+#define DT2821_CHANCSR_VAL 0x70f0
+
+#define DT2821_DACSR_MASK 0x7c93
+#define DT2821_DACSR_VAL 0x7c90
+
+#define DT2821_SUPCSR_MASK 0xf8ff
+#define DT2821_SUPCSR_VAL 0x0000
+
+#define DT2821_TMRCTR_MASK 0xff00
+#define DT2821_TMRCTR_VAL 0xf000
+
+/*
+ *    Bit fields of each register
+ */
+
+/* ADCSR */
+
+#define DT2821_ADERR	0x8000	/* (R)   1 for A/D error  */
+#define DT2821_ADCLK	0x0200	/* (R/W) A/D clock enable */
+		/*      0x7c00           read as 1's            */
+#define DT2821_MUXBUSY	0x0100	/* (R)   multiplexer busy */
+#define DT2821_ADDONE	0x0080	/* (R)   A/D done         */
+#define DT2821_IADDONE	0x0040	/* (R/W) interrupt on A/D done    */
+		/*      0x0030           gain select            */
+		/*      0x000f           channel select         */
+
+/* CHANCSR */
+
+#define DT2821_LLE	0x8000	/* (R/W) Load List Enable */
+		/*      0x7000           read as 1's            */
+		/*      0x0f00     (R)   present address        */
+		/*      0x00f0           read as 1's            */
+		/*      0x000f     (R)   number of entries - 1  */
+
+/* DACSR */
+
+#define DT2821_DAERR	0x8000	/* (R)   D/A error                */
+#define DT2821_YSEL	0x0200	/* (R/W) DAC 1 select             */
+#define DT2821_SSEL	0x0100	/* (R/W) single channel select    */
+#define DT2821_DACRDY	0x0080	/* (R)   DAC ready                */
+#define DT2821_IDARDY	0x0040	/* (R/W) interrupt on DAC ready   */
+#define DT2821_DACLK	0x0020	/* (R/W) D/A clock enable */
+#define DT2821_HBOE	0x0002	/* (R/W) DIO high byte output enable      */
+#define DT2821_LBOE	0x0001	/* (R/W) DIO low byte output enable       */
+
+/* SUPCSR */
+
+#define DT2821_DMAD	0x8000	/* (R)   DMA done                 */
+#define DT2821_ERRINTEN	0x4000	/* (R/W) interrupt on error               */
+#define DT2821_CLRDMADNE 0x2000	/* (W)   clear DMA done                   */
+#define DT2821_DDMA	0x1000	/* (R/W) dual DMA                 */
+#define DT2821_DS1	0x0800	/* (R/W) DMA select 1                     */
+#define DT2821_DS0	0x0400	/* (R/W) DMA select 0                     */
+#define DT2821_BUFFB	0x0200	/* (R/W) buffer B selected                */
+#define DT2821_SCDN	0x0100	/* (R)   scan done                        */
+#define DT2821_DACON	0x0080	/* (W)   DAC single conversion            */
+#define DT2821_ADCINIT	0x0040	/* (W)   A/D initialize                   */
+#define DT2821_DACINIT	0x0020	/* (W)   D/A initialize                   */
+#define DT2821_PRLD	0x0010	/* (W)   preload multiplexer              */
+#define DT2821_STRIG	0x0008	/* (W)   software trigger         */
+#define DT2821_XTRIG	0x0004	/* (R/W) external trigger enable  */
+#define DT2821_XCLK	0x0002	/* (R/W) external clock enable            */
+#define DT2821_BDINIT	0x0001	/* (W)   initialize board         */
+
+static const struct comedi_lrange range_dt282x_ai_lo_bipolar = { 4, {
+			RANGE(-10, 10),
+			RANGE(-5, 5),
+			RANGE(-2.5, 2.5),
+			RANGE(-1.25, 1.25)
+	}
+};
+static const struct comedi_lrange range_dt282x_ai_lo_unipolar = { 4, {
+			RANGE(0, 10),
+			RANGE(0, 5),
+			RANGE(0, 2.5),
+			RANGE(0, 1.25)
+	}
+};
+static const struct comedi_lrange range_dt282x_ai_5_bipolar = { 4, {
+			RANGE(-5, 5),
+			RANGE(-2.5, 2.5),
+			RANGE(-1.25, 1.25),
+			RANGE(-0.625, 0.625),
+	}
+};
+static const struct comedi_lrange range_dt282x_ai_5_unipolar = { 4, {
+			RANGE(0, 5),
+			RANGE(0, 2.5),
+			RANGE(0, 1.25),
+			RANGE(0, 0.625),
+	}
+};
+static const struct comedi_lrange range_dt282x_ai_hi_bipolar = { 4, {
+			RANGE(-10, 10),
+			RANGE(-1, 1),
+			RANGE(-0.1, 0.1),
+			RANGE(-0.02, 0.02)
+	}
+};
+static const struct comedi_lrange range_dt282x_ai_hi_unipolar = { 4, {
+			RANGE(0, 10),
+			RANGE(0, 1),
+			RANGE(0, 0.1),
+			RANGE(0, 0.02)
+	}
+};
+
+struct dt282x_board {
+	const char *name;
+	int adbits;
+	int adchan_se;
+	int adchan_di;
+	int ai_speed;
+	int ispgl;
+	int dachan;
+	int dabits;
+};
+
+static const struct dt282x_board boardtypes[] = {
+      {name:"dt2821",
+	      adbits:	12,
+	      adchan_se:16,
+	      adchan_di:8,
+	      ai_speed:20000,
+	      ispgl:	0,
+	      dachan:	2,
+	      dabits:	12,
+		},
+      {name:"dt2821-f",
+	      adbits:	12,
+	      adchan_se:16,
+	      adchan_di:8,
+	      ai_speed:6500,
+	      ispgl:	0,
+	      dachan:	2,
+	      dabits:	12,
+		},
+      {name:"dt2821-g",
+	      adbits:	12,
+	      adchan_se:16,
+	      adchan_di:8,
+	      ai_speed:4000,
+	      ispgl:	0,
+	      dachan:	2,
+	      dabits:	12,
+		},
+      {name:"dt2823",
+	      adbits:	16,
+	      adchan_se:0,
+	      adchan_di:4,
+	      ai_speed:10000,
+	      ispgl:	0,
+	      dachan:	2,
+	      dabits:	16,
+		},
+      {name:"dt2824-pgh",
+	      adbits:	12,
+	      adchan_se:16,
+	      adchan_di:8,
+	      ai_speed:20000,
+	      ispgl:	0,
+	      dachan:	0,
+	      dabits:	0,
+		},
+      {name:"dt2824-pgl",
+	      adbits:	12,
+	      adchan_se:16,
+	      adchan_di:8,
+	      ai_speed:20000,
+	      ispgl:	1,
+	      dachan:	0,
+	      dabits:	0,
+		},
+      {name:"dt2825",
+	      adbits:	12,
+	      adchan_se:16,
+	      adchan_di:8,
+	      ai_speed:20000,
+	      ispgl:	1,
+	      dachan:	2,
+	      dabits:	12,
+		},
+      {name:"dt2827",
+	      adbits:	16,
+	      adchan_se:0,
+	      adchan_di:4,
+	      ai_speed:10000,
+	      ispgl:	0,
+	      dachan:	2,
+	      dabits:	12,
+		},
+      {name:"dt2828",
+	      adbits:	12,
+	      adchan_se:4,
+	      adchan_di:0,
+	      ai_speed:10000,
+	      ispgl:	0,
+	      dachan:	2,
+	      dabits:	12,
+		},
+      {name:"dt2829",
+	      adbits:	16,
+	      adchan_se:8,
+	      adchan_di:0,
+	      ai_speed:33250,
+	      ispgl:	0,
+	      dachan:	2,
+	      dabits:	16,
+		},
+      {name:"dt21-ez",
+	      adbits:	12,
+	      adchan_se:16,
+	      adchan_di:8,
+	      ai_speed:10000,
+	      ispgl:	0,
+	      dachan:	2,
+	      dabits:	12,
+		},
+      {name:"dt23-ez",
+	      adbits:	16,
+	      adchan_se:16,
+	      adchan_di:8,
+	      ai_speed:10000,
+	      ispgl:	0,
+	      dachan:	0,
+	      dabits:	0,
+		},
+      {name:"dt24-ez",
+	      adbits:	12,
+	      adchan_se:16,
+	      adchan_di:8,
+	      ai_speed:10000,
+	      ispgl:	0,
+	      dachan:	0,
+	      dabits:	0,
+		},
+      {name:"dt24-ez-pgl",
+	      adbits:	12,
+	      adchan_se:16,
+	      adchan_di:8,
+	      ai_speed:10000,
+	      ispgl:	1,
+	      dachan:	0,
+	      dabits:	0,
+		},
+};
+
+#define n_boardtypes sizeof(boardtypes)/sizeof(struct dt282x_board)
+#define this_board ((const struct dt282x_board *)dev->board_ptr)
+
+struct dt282x_private {
+	int ad_2scomp;		/* we have 2's comp jumper set  */
+	int da0_2scomp;		/* same, for DAC0               */
+	int da1_2scomp;		/* same, for DAC1               */
+
+	const struct comedi_lrange *darangelist[2];
+
+	short ao[2];
+
+	volatile int dacsr;	/* software copies of registers */
+	volatile int adcsr;
+	volatile int supcsr;
+
+	volatile int ntrig;
+	volatile int nread;
+
+	struct {
+		int chan;
+		short *buf;	/* DMA buffer */
+		volatile int size;	/* size of current transfer */
+	} dma[2];
+	int dma_maxsize;	/* max size of DMA transfer (in bytes) */
+	int usedma;		/* driver uses DMA              */
+	volatile int current_dma_index;
+	int dma_dir;
+};
+
+#define devpriv ((struct dt282x_private *)dev->private)
+#define boardtype (*(const struct dt282x_board *)dev->board_ptr)
+
+/*
+ *    Some useless abstractions
+ */
+#define chan_to_DAC(a)	((a)&1)
+#define update_dacsr(a)	outw(devpriv->dacsr|(a),dev->iobase+DT2821_DACSR)
+#define update_adcsr(a)	outw(devpriv->adcsr|(a),dev->iobase+DT2821_ADCSR)
+#define mux_busy() (inw(dev->iobase+DT2821_ADCSR)&DT2821_MUXBUSY)
+#define ad_done() (inw(dev->iobase+DT2821_ADCSR)&DT2821_ADDONE)
+#define update_supcsr(a)	outw(devpriv->supcsr|(a),dev->iobase+DT2821_SUPCSR)
+
+/*
+ *    danger! macro abuse... a is the expression to wait on, and b is
+ *      the statement(s) to execute if it doesn't happen.
+ */
+#define wait_for(a,b)	 				\
+	do{						\
+		int _i;					\
+		for(_i=0;_i<DT2821_TIMEOUT;_i++){	\
+			if(a){_i=0;break;}		\
+			comedi_udelay(5);			\
+		}					\
+		if(_i){b}				\
+	}while(0)
+
+static int dt282x_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dt282x_detach(struct comedi_device * dev);
+static struct comedi_driver driver_dt282x = {
+      driver_name:"dt282x",
+      module:THIS_MODULE,
+      attach:dt282x_attach,
+      detach:dt282x_detach,
+      board_name:&boardtypes[0].name,
+      num_names:n_boardtypes,
+      offset:sizeof(struct dt282x_board),
+};
+
+COMEDI_INITCLEANUP(driver_dt282x);
+
+static void free_resources(struct comedi_device * dev);
+static int prep_ai_dma(struct comedi_device * dev, int chan, int size);
+static int prep_ao_dma(struct comedi_device * dev, int chan, int size);
+static int dt282x_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static int dt282x_ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static int dt282x_ns_to_timer(int *nanosec, int round_mode);
+static void dt282x_disable_dma(struct comedi_device * dev);
+
+static int dt282x_grab_dma(struct comedi_device * dev, int dma1, int dma2);
+
+static void dt282x_munge(struct comedi_device * dev, short * buf,
+	unsigned int nbytes)
+{
+	unsigned int i;
+	unsigned short mask = (1 << boardtype.adbits) - 1;
+	unsigned short sign = 1 << (boardtype.adbits - 1);
+	int n;
+
+	if (devpriv->ad_2scomp) {
+		sign = 1 << (boardtype.adbits - 1);
+	} else {
+		sign = 0;
+	}
+
+	if (nbytes % 2)
+		comedi_error(dev, "bug! odd number of bytes from dma xfer");
+	n = nbytes / 2;
+	for (i = 0; i < n; i++) {
+		buf[i] = (buf[i] & mask) ^ sign;
+	}
+}
+
+static void dt282x_ao_dma_interrupt(struct comedi_device * dev)
+{
+	void *ptr;
+	int size;
+	int i;
+	struct comedi_subdevice *s = dev->subdevices + 1;
+
+	update_supcsr(DT2821_CLRDMADNE);
+
+	if (!s->async->prealloc_buf) {
+		printk("async->data disappeared.  dang!\n");
+		return;
+	}
+
+	i = devpriv->current_dma_index;
+	ptr = devpriv->dma[i].buf;
+
+	disable_dma(devpriv->dma[i].chan);
+
+	devpriv->current_dma_index = 1 - i;
+
+	size = cfc_read_array_from_buffer(s, ptr, devpriv->dma_maxsize);
+	if (size == 0) {
+		rt_printk("dt282x: AO underrun\n");
+		dt282x_ao_cancel(dev, s);
+		s->async->events |= COMEDI_CB_OVERFLOW;
+		return;
+	}
+	prep_ao_dma(dev, i, size);
+	return;
+}
+
+static void dt282x_ai_dma_interrupt(struct comedi_device * dev)
+{
+	void *ptr;
+	int size;
+	int i;
+	int ret;
+	struct comedi_subdevice *s = dev->subdevices;
+
+	update_supcsr(DT2821_CLRDMADNE);
+
+	if (!s->async->prealloc_buf) {
+		printk("async->data disappeared.  dang!\n");
+		return;
+	}
+
+	i = devpriv->current_dma_index;
+	ptr = devpriv->dma[i].buf;
+	size = devpriv->dma[i].size;
+
+	disable_dma(devpriv->dma[i].chan);
+
+	devpriv->current_dma_index = 1 - i;
+
+	dt282x_munge(dev, ptr, size);
+	ret = cfc_write_array_to_buffer(s, ptr, size);
+	if (ret != size) {
+		dt282x_ai_cancel(dev, s);
+		return;
+	}
+	devpriv->nread -= size / 2;
+
+	if (devpriv->nread < 0) {
+		printk("dt282x: off by one\n");
+		devpriv->nread = 0;
+	}
+	if (!devpriv->nread) {
+		dt282x_ai_cancel(dev, s);
+		s->async->events |= COMEDI_CB_EOA;
+		return;
+	}
+#if 0
+	/* clear the dual dma flag, making this the last dma segment */
+	/* XXX probably wrong */
+	if (!devpriv->ntrig) {
+		devpriv->supcsr &= ~(DT2821_DDMA);
+		update_supcsr(0);
+	}
+#endif
+	/* restart the channel */
+	prep_ai_dma(dev, i, 0);
+}
+
+static int prep_ai_dma(struct comedi_device * dev, int dma_index, int n)
+{
+	int dma_chan;
+	unsigned long dma_ptr;
+	unsigned long flags;
+
+	if (!devpriv->ntrig)
+		return 0;
+
+	if (n == 0)
+		n = devpriv->dma_maxsize;
+	if (n > devpriv->ntrig * 2)
+		n = devpriv->ntrig * 2;
+	devpriv->ntrig -= n / 2;
+
+	devpriv->dma[dma_index].size = n;
+	dma_chan = devpriv->dma[dma_index].chan;
+	dma_ptr = virt_to_bus(devpriv->dma[dma_index].buf);
+
+	set_dma_mode(dma_chan, DMA_MODE_READ);
+	flags = claim_dma_lock();
+	clear_dma_ff(dma_chan);
+	set_dma_addr(dma_chan, dma_ptr);
+	set_dma_count(dma_chan, n);
+	release_dma_lock(flags);
+
+	enable_dma(dma_chan);
+
+	return n;
+}
+
+static int prep_ao_dma(struct comedi_device * dev, int dma_index, int n)
+{
+	int dma_chan;
+	unsigned long dma_ptr;
+	unsigned long flags;
+
+	devpriv->dma[dma_index].size = n;
+	dma_chan = devpriv->dma[dma_index].chan;
+	dma_ptr = virt_to_bus(devpriv->dma[dma_index].buf);
+
+	set_dma_mode(dma_chan, DMA_MODE_WRITE);
+	flags = claim_dma_lock();
+	clear_dma_ff(dma_chan);
+	set_dma_addr(dma_chan, dma_ptr);
+	set_dma_count(dma_chan, n);
+	release_dma_lock(flags);
+
+	enable_dma(dma_chan);
+
+	return n;
+}
+
+static irqreturn_t dt282x_interrupt(int irq, void *d PT_REGS_ARG)
+{
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s;
+	struct comedi_subdevice *s_ao;
+	unsigned int supcsr, adcsr, dacsr;
+	int handled = 0;
+
+	if (!dev->attached) {
+		comedi_error(dev, "spurious interrupt");
+		return IRQ_HANDLED;
+	}
+
+	s = dev->subdevices + 0;
+	s_ao = dev->subdevices + 1;
+	adcsr = inw(dev->iobase + DT2821_ADCSR);
+	dacsr = inw(dev->iobase + DT2821_DACSR);
+	supcsr = inw(dev->iobase + DT2821_SUPCSR);
+	if (supcsr & DT2821_DMAD) {
+		if (devpriv->dma_dir == DMA_MODE_READ)
+			dt282x_ai_dma_interrupt(dev);
+		else
+			dt282x_ao_dma_interrupt(dev);
+		handled = 1;
+	}
+	if (adcsr & DT2821_ADERR) {
+		if (devpriv->nread != 0) {
+			comedi_error(dev, "A/D error");
+			dt282x_ai_cancel(dev, s);
+			s->async->events |= COMEDI_CB_ERROR;
+		}
+		handled = 1;
+	}
+	if (dacsr & DT2821_DAERR) {
+#if 0
+		static int warn = 5;
+		if (--warn <= 0) {
+			disable_irq(dev->irq);
+			printk("disabling irq\n");
+		}
+#endif
+		comedi_error(dev, "D/A error");
+		dt282x_ao_cancel(dev, s_ao);
+		s->async->events |= COMEDI_CB_ERROR;
+		handled = 1;
+	}
+#if 0
+	if (adcsr & DT2821_ADDONE) {
+		int ret;
+		short data;
+
+		data = (short) inw(dev->iobase + DT2821_ADDAT);
+		data &= (1 << boardtype.adbits) - 1;
+		if (devpriv->ad_2scomp) {
+			data ^= 1 << (boardtype.adbits - 1);
+		}
+		ret = comedi_buf_put(s->async, data);
+		if (ret == 0) {
+			s->async->events |= COMEDI_CB_OVERFLOW;
+		}
+
+		devpriv->nread--;
+		if (!devpriv->nread) {
+			s->async->events |= COMEDI_CB_EOA;
+		} else {
+			if (supcsr & DT2821_SCDN)
+				update_supcsr(DT2821_STRIG);
+		}
+		handled = 1;
+	}
+#endif
+	comedi_event(dev, s);
+	/* printk("adcsr=0x%02x dacsr-0x%02x supcsr=0x%02x\n", adcsr, dacsr, supcsr); */
+	return IRQ_RETVAL(handled);
+}
+
+static void dt282x_load_changain(struct comedi_device * dev, int n,
+	unsigned int *chanlist)
+{
+	unsigned int i;
+	unsigned int chan, range;
+
+	outw(DT2821_LLE | (n - 1), dev->iobase + DT2821_CHANCSR);
+	for (i = 0; i < n; i++) {
+		chan = CR_CHAN(chanlist[i]);
+		range = CR_RANGE(chanlist[i]);
+		update_adcsr((range << 4) | (chan));
+	}
+	outw(n - 1, dev->iobase + DT2821_CHANCSR);
+}
+
+/*
+ *    Performs a single A/D conversion.
+ *      - Put channel/gain into channel-gain list
+ *      - preload multiplexer
+ *      - trigger conversion and wait for it to finish
+ */
+static int dt282x_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+
+	/* XXX should we really be enabling the ad clock here? */
+	devpriv->adcsr = DT2821_ADCLK;
+	update_adcsr(0);
+
+	dt282x_load_changain(dev, 1, &insn->chanspec);
+
+	update_supcsr(DT2821_PRLD);
+	wait_for(!mux_busy(), comedi_error(dev, "timeout\n");
+		return -ETIME;
+		);
+
+	for (i = 0; i < insn->n; i++) {
+		update_supcsr(DT2821_STRIG);
+		wait_for(ad_done(), comedi_error(dev, "timeout\n");
+			return -ETIME;
+			);
+
+		data[i] =
+			inw(dev->iobase +
+			DT2821_ADDAT) & ((1 << boardtype.adbits) - 1);
+		if (devpriv->ad_2scomp)
+			data[i] ^= (1 << (boardtype.adbits - 1));
+	}
+
+	return i;
+}
+
+static int dt282x_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp;
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_EXT;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_TIMER;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	/* note that mutual compatiblity is not an issue here */
+	if (cmd->scan_begin_src != TRIG_FOLLOW &&
+		cmd->scan_begin_src != TRIG_EXT)
+		err++;
+	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+	if (cmd->scan_begin_src == TRIG_FOLLOW) {
+		/* internal trigger */
+		if (cmd->scan_begin_arg != 0) {
+			cmd->scan_begin_arg = 0;
+			err++;
+		}
+	} else {
+		/* external trigger */
+		/* should be level/edge, hi/lo specification here */
+		if (cmd->scan_begin_arg != 0) {
+			cmd->scan_begin_arg = 0;
+			err++;
+		}
+	}
+	if (cmd->convert_arg < 4000) {
+		/* XXX board dependent */
+		cmd->convert_arg = 4000;
+		err++;
+	}
+#define SLOWEST_TIMER	(250*(1<<15)*255)
+	if (cmd->convert_arg > SLOWEST_TIMER) {
+		cmd->convert_arg = SLOWEST_TIMER;
+		err++;
+	}
+	if (cmd->convert_arg < this_board->ai_speed) {
+		cmd->convert_arg = this_board->ai_speed;
+		err++;
+	}
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+	if (cmd->stop_src == TRIG_COUNT) {
+		/* any count is allowed */
+	} else {
+		/* TRIG_NONE */
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	tmp = cmd->convert_arg;
+	dt282x_ns_to_timer(&cmd->convert_arg, cmd->flags & TRIG_ROUND_MASK);
+	if (tmp != cmd->convert_arg)
+		err++;
+
+	if (err)
+		return 4;
+
+	return 0;
+}
+
+static int dt282x_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_cmd *cmd = &s->async->cmd;
+	int timer;
+
+	if (devpriv->usedma == 0) {
+		comedi_error(dev,
+			"driver requires 2 dma channels to execute command");
+		return -EIO;
+	}
+
+	dt282x_disable_dma(dev);
+
+	if (cmd->convert_arg < this_board->ai_speed)
+		cmd->convert_arg = this_board->ai_speed;
+	timer = dt282x_ns_to_timer(&cmd->convert_arg, TRIG_ROUND_NEAREST);
+	outw(timer, dev->iobase + DT2821_TMRCTR);
+
+	if (cmd->scan_begin_src == TRIG_FOLLOW) {
+		/* internal trigger */
+		devpriv->supcsr = DT2821_ERRINTEN | DT2821_DS0;
+	} else {
+		/* external trigger */
+		devpriv->supcsr = DT2821_ERRINTEN | DT2821_DS0 | DT2821_DS1;
+	}
+	update_supcsr(DT2821_CLRDMADNE | DT2821_BUFFB | DT2821_ADCINIT);
+
+	devpriv->ntrig = cmd->stop_arg * cmd->scan_end_arg;
+	devpriv->nread = devpriv->ntrig;
+
+	devpriv->dma_dir = DMA_MODE_READ;
+	devpriv->current_dma_index = 0;
+	prep_ai_dma(dev, 0, 0);
+	if (devpriv->ntrig) {
+		prep_ai_dma(dev, 1, 0);
+		devpriv->supcsr |= DT2821_DDMA;
+		update_supcsr(0);
+	}
+
+	devpriv->adcsr = 0;
+
+	dt282x_load_changain(dev, cmd->chanlist_len, cmd->chanlist);
+
+	devpriv->adcsr = DT2821_ADCLK | DT2821_IADDONE;
+	update_adcsr(0);
+
+	update_supcsr(DT2821_PRLD);
+	wait_for(!mux_busy(), comedi_error(dev, "timeout\n");
+		return -ETIME;
+		);
+
+	if (cmd->scan_begin_src == TRIG_FOLLOW) {
+		update_supcsr(DT2821_STRIG);
+	} else {
+		devpriv->supcsr |= DT2821_XTRIG;
+		update_supcsr(0);
+	}
+
+	return 0;
+}
+
+static void dt282x_disable_dma(struct comedi_device * dev)
+{
+	if (devpriv->usedma) {
+		disable_dma(devpriv->dma[0].chan);
+		disable_dma(devpriv->dma[1].chan);
+	}
+}
+
+static int dt282x_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	dt282x_disable_dma(dev);
+
+	devpriv->adcsr = 0;
+	update_adcsr(0);
+
+	devpriv->supcsr = 0;
+	update_supcsr(DT2821_ADCINIT);
+
+	return 0;
+}
+
+static int dt282x_ns_to_timer(int *nanosec, int round_mode)
+{
+	int prescale, base, divider;
+
+	for (prescale = 0; prescale < 16; prescale++) {
+		if (prescale == 1)
+			continue;
+		base = 250 * (1 << prescale);
+		switch (round_mode) {
+		case TRIG_ROUND_NEAREST:
+		default:
+			divider = (*nanosec + base / 2) / base;
+			break;
+		case TRIG_ROUND_DOWN:
+			divider = (*nanosec) / base;
+			break;
+		case TRIG_ROUND_UP:
+			divider = (*nanosec + base - 1) / base;
+			break;
+		}
+		if (divider < 256) {
+			*nanosec = divider * base;
+			return (prescale << 8) | (255 - divider);
+		}
+	}
+	base = 250 * (1 << 15);
+	divider = 255;
+	*nanosec = divider * base;
+	return (15 << 8) | (255 - divider);
+}
+
+/*
+ *    Analog output routine.  Selects single channel conversion,
+ *      selects correct channel, converts from 2's compliment to
+ *      offset binary if necessary, loads the data into the DAC
+ *      data register, and performs the conversion.
+ */
+static int dt282x_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	data[0] = devpriv->ao[CR_CHAN(insn->chanspec)];
+
+	return 1;
+}
+
+static int dt282x_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	short d;
+	unsigned int chan;
+
+	chan = CR_CHAN(insn->chanspec);
+	d = data[0];
+	d &= (1 << boardtype.dabits) - 1;
+	devpriv->ao[chan] = d;
+
+	devpriv->dacsr |= DT2821_SSEL;
+
+	if (chan) {
+		/* select channel */
+		devpriv->dacsr |= DT2821_YSEL;
+		if (devpriv->da0_2scomp)
+			d ^= (1 << (boardtype.dabits - 1));
+	} else {
+		devpriv->dacsr &= ~DT2821_YSEL;
+		if (devpriv->da1_2scomp)
+			d ^= (1 << (boardtype.dabits - 1));
+	}
+
+	update_dacsr(0);
+
+	outw(d, dev->iobase + DT2821_DADAT);
+
+	update_supcsr(DT2821_DACON);
+
+	return 1;
+}
+
+static int dt282x_ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp;
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_INT;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_TIMER;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_NOW;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	/* note that mutual compatiblity is not an issue here */
+	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+	if (cmd->scan_begin_arg < 5000 /* XXX unknown */ ) {
+		cmd->scan_begin_arg = 5000;
+		err++;
+	}
+	if (cmd->convert_arg != 0) {
+		cmd->convert_arg = 0;
+		err++;
+	}
+	if (cmd->scan_end_arg > 2) {
+		/* XXX chanlist stuff? */
+		cmd->scan_end_arg = 2;
+		err++;
+	}
+	if (cmd->stop_src == TRIG_COUNT) {
+		/* any count is allowed */
+	} else {
+		/* TRIG_NONE */
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	tmp = cmd->scan_begin_arg;
+	dt282x_ns_to_timer(&cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK);
+	if (tmp != cmd->scan_begin_arg)
+		err++;
+
+	if (err)
+		return 4;
+
+	return 0;
+
+}
+
+static int dt282x_ao_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int x)
+{
+	int size;
+
+	if (x != 0)
+		return -EINVAL;
+
+	size = cfc_read_array_from_buffer(s, devpriv->dma[0].buf,
+		devpriv->dma_maxsize);
+	if (size == 0) {
+		rt_printk("dt282x: AO underrun\n");
+		return -EPIPE;
+	}
+	prep_ao_dma(dev, 0, size);
+
+	size = cfc_read_array_from_buffer(s, devpriv->dma[1].buf,
+		devpriv->dma_maxsize);
+	if (size == 0) {
+		rt_printk("dt282x: AO underrun\n");
+		return -EPIPE;
+	}
+	prep_ao_dma(dev, 1, size);
+
+	update_supcsr(DT2821_STRIG);
+	s->async->inttrig = NULL;
+
+	return 1;
+}
+
+static int dt282x_ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	int timer;
+	struct comedi_cmd *cmd = &s->async->cmd;
+
+	if (devpriv->usedma == 0) {
+		comedi_error(dev,
+			"driver requires 2 dma channels to execute command");
+		return -EIO;
+	}
+
+	dt282x_disable_dma(dev);
+
+	devpriv->supcsr = DT2821_ERRINTEN | DT2821_DS1 | DT2821_DDMA;
+	update_supcsr(DT2821_CLRDMADNE | DT2821_BUFFB | DT2821_DACINIT);
+
+	devpriv->ntrig = cmd->stop_arg * cmd->chanlist_len;
+	devpriv->nread = devpriv->ntrig;
+
+	devpriv->dma_dir = DMA_MODE_WRITE;
+	devpriv->current_dma_index = 0;
+
+	timer = dt282x_ns_to_timer(&cmd->scan_begin_arg, TRIG_ROUND_NEAREST);
+	outw(timer, dev->iobase + DT2821_TMRCTR);
+
+	devpriv->dacsr = DT2821_SSEL | DT2821_DACLK | DT2821_IDARDY;
+	update_dacsr(0);
+
+	s->async->inttrig = dt282x_ao_inttrig;
+
+	return 0;
+}
+
+static int dt282x_ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	dt282x_disable_dma(dev);
+
+	devpriv->dacsr = 0;
+	update_dacsr(0);
+
+	devpriv->supcsr = 0;
+	update_supcsr(DT2821_DACINIT);
+
+	return 0;
+}
+
+static int dt282x_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= (data[0] & data[1]);
+
+		outw(s->state, dev->iobase + DT2821_DIODAT);
+	}
+	data[1] = inw(dev->iobase + DT2821_DIODAT);
+
+	return 2;
+}
+
+static int dt282x_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int mask;
+
+	mask = (CR_CHAN(insn->chanspec) < 8) ? 0x00ff : 0xff00;
+	if (data[0])
+		s->io_bits |= mask;
+	else
+		s->io_bits &= ~mask;
+
+	if (s->io_bits & 0x00ff)
+		devpriv->dacsr |= DT2821_LBOE;
+	else
+		devpriv->dacsr &= ~DT2821_LBOE;
+	if (s->io_bits & 0xff00)
+		devpriv->dacsr |= DT2821_HBOE;
+	else
+		devpriv->dacsr &= ~DT2821_HBOE;
+
+	outw(devpriv->dacsr, dev->iobase + DT2821_DACSR);
+
+	return 1;
+}
+
+static const struct comedi_lrange *const ai_range_table[] = {
+	&range_dt282x_ai_lo_bipolar,
+	&range_dt282x_ai_lo_unipolar,
+	&range_dt282x_ai_5_bipolar,
+	&range_dt282x_ai_5_unipolar
+};
+static const struct comedi_lrange *const ai_range_pgl_table[] = {
+	&range_dt282x_ai_hi_bipolar,
+	&range_dt282x_ai_hi_unipolar
+};
+static const struct comedi_lrange *opt_ai_range_lkup(int ispgl, int x)
+{
+	if (ispgl) {
+		if (x < 0 || x >= 2)
+			x = 0;
+		return ai_range_pgl_table[x];
+	} else {
+		if (x < 0 || x >= 4)
+			x = 0;
+		return ai_range_table[x];
+	}
+}
+static const struct comedi_lrange *const ao_range_table[] = {
+	&range_bipolar10,
+	&range_unipolar10,
+	&range_bipolar5,
+	&range_unipolar5,
+	&range_bipolar2_5
+};
+static const struct comedi_lrange *opt_ao_range_lkup(int x)
+{
+	if (x < 0 || x >= 5)
+		x = 0;
+	return ao_range_table[x];
+}
+
+enum { opt_iobase = 0, opt_irq, opt_dma1, opt_dma2,	/* i/o base, irq, dma channels */
+	opt_diff,		/* differential */
+	opt_ai_twos, opt_ao0_twos, opt_ao1_twos,	/* twos comp */
+	opt_ai_range, opt_ao0_range, opt_ao1_range,	/* range */
+};
+
+/*
+   options:
+   0	i/o base
+   1	irq
+   2	dma1
+   3	dma2
+   4	0=single ended, 1=differential
+   5	ai 0=straight binary, 1=2's comp
+   6	ao0 0=straight binary, 1=2's comp
+   7	ao1 0=straight binary, 1=2's comp
+   8	ai 0=±10 V, 1=0-10 V, 2=±5 V, 3=0-5 V
+   9	ao0 0=±10 V, 1=0-10 V, 2=±5 V, 3=0-5 V, 4=±2.5 V
+   10	ao1 0=±10 V, 1=0-10 V, 2=±5 V, 3=0-5 V, 4=±2.5 V
+ */
+static int dt282x_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	int i, irq;
+	int ret;
+	struct comedi_subdevice *s;
+	unsigned long iobase;
+
+	dev->board_name = this_board->name;
+
+	iobase = it->options[opt_iobase];
+	if (!iobase)
+		iobase = 0x240;
+
+	printk("comedi%d: dt282x: 0x%04lx", dev->minor, iobase);
+	if (!request_region(iobase, DT2821_SIZE, "dt282x")) {
+		printk(" I/O port conflict\n");
+		return -EBUSY;
+	}
+	dev->iobase = iobase;
+
+	outw(DT2821_BDINIT, dev->iobase + DT2821_SUPCSR);
+	i = inw(dev->iobase + DT2821_ADCSR);
+#ifdef DEBUG
+	printk(" fingerprint=%x,%x,%x,%x,%x",
+		inw(dev->iobase + DT2821_ADCSR),
+		inw(dev->iobase + DT2821_CHANCSR),
+		inw(dev->iobase + DT2821_DACSR),
+		inw(dev->iobase + DT2821_SUPCSR),
+		inw(dev->iobase + DT2821_TMRCTR));
+#endif
+
+	if (((inw(dev->iobase + DT2821_ADCSR) & DT2821_ADCSR_MASK)
+			!= DT2821_ADCSR_VAL) ||
+		((inw(dev->iobase + DT2821_CHANCSR) & DT2821_CHANCSR_MASK)
+			!= DT2821_CHANCSR_VAL) ||
+		((inw(dev->iobase + DT2821_DACSR) & DT2821_DACSR_MASK)
+			!= DT2821_DACSR_VAL) ||
+		((inw(dev->iobase + DT2821_SUPCSR) & DT2821_SUPCSR_MASK)
+			!= DT2821_SUPCSR_VAL) ||
+		((inw(dev->iobase + DT2821_TMRCTR) & DT2821_TMRCTR_MASK)
+			!= DT2821_TMRCTR_VAL)) {
+		printk(" board not found");
+		return -EIO;
+	}
+	/* should do board test */
+
+	irq = it->options[opt_irq];
+#if 0
+	if (irq < 0) {
+		unsigned long flags;
+		int irqs;
+
+		save_flags(flags);
+		sti();
+		irqs = probe_irq_on();
+
+		/* trigger interrupt */
+
+		comedi_udelay(100);
+
+		irq = probe_irq_off(irqs);
+		restore_flags(flags);
+		if (0 /* error */ ) {
+			printk(" error probing irq (bad)");
+		}
+	}
+#endif
+	if (irq > 0) {
+		printk(" ( irq = %d )", irq);
+		ret = comedi_request_irq(irq, dt282x_interrupt, 0, "dt282x",
+			dev);
+		if (ret < 0) {
+			printk(" failed to get irq\n");
+			return -EIO;
+		}
+		dev->irq = irq;
+	} else if (irq == 0) {
+		printk(" (no irq)");
+	} else {
+#if 0
+		printk(" (probe returned multiple irqs--bad)");
+#else
+		printk(" (irq probe not implemented)");
+#endif
+	}
+
+	if ((ret = alloc_private(dev, sizeof(struct dt282x_private))) < 0)
+		return ret;
+
+	ret = dt282x_grab_dma(dev, it->options[opt_dma1],
+		it->options[opt_dma2]);
+	if (ret < 0)
+		return ret;
+
+	if ((ret = alloc_subdevices(dev, 3)) < 0)
+		return ret;
+
+	s = dev->subdevices + 0;
+
+	dev->read_subdev = s;
+	/* ai subdevice */
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE | SDF_CMD_READ |
+		((it->options[opt_diff]) ? SDF_DIFF : SDF_COMMON);
+	s->n_chan =
+		(it->options[opt_diff]) ? boardtype.adchan_di : boardtype.
+		adchan_se;
+	s->insn_read = dt282x_ai_insn_read;
+	s->do_cmdtest = dt282x_ai_cmdtest;
+	s->do_cmd = dt282x_ai_cmd;
+	s->cancel = dt282x_ai_cancel;
+	s->maxdata = (1 << boardtype.adbits) - 1;
+	s->len_chanlist = 16;
+	s->range_table =
+		opt_ai_range_lkup(boardtype.ispgl, it->options[opt_ai_range]);
+	devpriv->ad_2scomp = it->options[opt_ai_twos];
+
+	s++;
+	if ((s->n_chan = boardtype.dachan)) {
+		/* ao subsystem */
+		s->type = COMEDI_SUBD_AO;
+		dev->write_subdev = s;
+		s->subdev_flags = SDF_WRITABLE | SDF_CMD_WRITE;
+		s->insn_read = dt282x_ao_insn_read;
+		s->insn_write = dt282x_ao_insn_write;
+		s->do_cmdtest = dt282x_ao_cmdtest;
+		s->do_cmd = dt282x_ao_cmd;
+		s->cancel = dt282x_ao_cancel;
+		s->maxdata = (1 << boardtype.dabits) - 1;
+		s->len_chanlist = 2;
+		s->range_table_list = devpriv->darangelist;
+		devpriv->darangelist[0] =
+			opt_ao_range_lkup(it->options[opt_ao0_range]);
+		devpriv->darangelist[1] =
+			opt_ao_range_lkup(it->options[opt_ao1_range]);
+		devpriv->da0_2scomp = it->options[opt_ao0_twos];
+		devpriv->da1_2scomp = it->options[opt_ao1_twos];
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	s++;
+	/* dio subsystem */
+	s->type = COMEDI_SUBD_DIO;
+	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+	s->n_chan = 16;
+	s->insn_bits = dt282x_dio_insn_bits;
+	s->insn_config = dt282x_dio_insn_config;
+	s->maxdata = 1;
+	s->range_table = &range_digital;
+
+	printk("\n");
+
+	return 0;
+}
+
+static void free_resources(struct comedi_device * dev)
+{
+	if (dev->irq) {
+		comedi_free_irq(dev->irq, dev);
+	}
+	if (dev->iobase)
+		release_region(dev->iobase, DT2821_SIZE);
+	if (dev->private) {
+		if (devpriv->dma[0].chan)
+			free_dma(devpriv->dma[0].chan);
+		if (devpriv->dma[1].chan)
+			free_dma(devpriv->dma[1].chan);
+		if (devpriv->dma[0].buf)
+			free_page((unsigned long)devpriv->dma[0].buf);
+		if (devpriv->dma[1].buf)
+			free_page((unsigned long)devpriv->dma[1].buf);
+	}
+}
+
+static int dt282x_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: dt282x: remove\n", dev->minor);
+
+	free_resources(dev);
+
+	return 0;
+}
+
+static int dt282x_grab_dma(struct comedi_device * dev, int dma1, int dma2)
+{
+	int ret;
+
+	devpriv->usedma = 0;
+
+	if (!dma1 && !dma2) {
+		printk(" (no dma)");
+		return 0;
+	}
+
+	if (dma1 == dma2 || dma1 < 5 || dma2 < 5 || dma1 > 7 || dma2 > 7)
+		return -EINVAL;
+
+	if (dma2 < dma1) {
+		int i;
+		i = dma1;
+		dma1 = dma2;
+		dma2 = i;
+	}
+
+	ret = request_dma(dma1, "dt282x A");
+	if (ret)
+		return -EBUSY;
+	devpriv->dma[0].chan = dma1;
+
+	ret = request_dma(dma2, "dt282x B");
+	if (ret)
+		return -EBUSY;
+	devpriv->dma[1].chan = dma2;
+
+	devpriv->dma_maxsize = PAGE_SIZE;
+	devpriv->dma[0].buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
+	devpriv->dma[1].buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
+	if (!devpriv->dma[0].buf || !devpriv->dma[1].buf) {
+		printk(" can't get DMA memory");
+		return -ENOMEM;
+	}
+
+	printk(" (dma=%d,%d)", dma1, dma2);
+
+	devpriv->usedma = 1;
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c
new file mode 100644
index 0000000..d946798
--- /dev/null
+++ b/drivers/staging/comedi/drivers/dt3000.c
@@ -0,0 +1,983 @@
+/*
+    comedi/drivers/dt3000.c
+    Data Translation DT3000 series driver
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 1999 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: dt3000
+Description: Data Translation DT3000 series
+Author: ds
+Devices: [Data Translation] DT3001 (dt3000), DT3001-PGL, DT3002, DT3003,
+  DT3003-PGL, DT3004, DT3005, DT3004-200
+Updated: Mon, 14 Apr 2008 15:41:24 +0100
+Status: works
+
+Configuration Options:
+  [0] - PCI bus of device (optional)
+  [1] - PCI slot of device (optional)
+  If bus/slot is not specified, the first supported
+  PCI device found will be used.
+
+There is code to support AI commands, but it may not work.
+
+AO commands are not supported.
+*/
+
+/*
+   The DT3000 series is Data Translation's attempt to make a PCI
+   data acquisition board.  The design of this series is very nice,
+   since each board has an on-board DSP (Texas Instruments TMS320C52).
+   However, a few details are a little annoying.  The boards lack
+   bus-mastering DMA, which eliminates them from serious work.
+   They also are not capable of autocalibration, which is a common
+   feature in modern hardware.  The default firmware is pretty bad,
+   making it nearly impossible to write an RT compatible driver.
+   It would make an interesting project to write a decent firmware
+   for these boards.
+
+   Data Translation originally wanted an NDA for the documentation
+   for the 3k series.  However, if you ask nicely, they might send
+   you the docs without one, also.
+*/
+
+#define DEBUG 1
+
+#include "../comedidev.h"
+#include <linux/delay.h>
+
+#include "comedi_pci.h"
+
+#define PCI_VENDOR_ID_DT	0x1116
+
+static const struct comedi_lrange range_dt3000_ai = { 4, {
+			RANGE(-10, 10),
+			RANGE(-5, 5),
+			RANGE(-2.5, 2.5),
+			RANGE(-1.25, 1.25)
+	}
+};
+static const struct comedi_lrange range_dt3000_ai_pgl = { 4, {
+			RANGE(-10, 10),
+			RANGE(-1, 1),
+			RANGE(-0.1, 0.1),
+			RANGE(-0.02, 0.02)
+	}
+};
+
+struct dt3k_boardtype {
+
+	const char *name;
+	unsigned int device_id;
+	int adchan;
+	int adbits;
+	int ai_speed;
+	const struct comedi_lrange *adrange;
+	int dachan;
+	int dabits;
+};
+
+
+static const struct dt3k_boardtype dt3k_boardtypes[] = {
+      {name:"dt3001",
+	      device_id:0x22,
+	      adchan:	16,
+	      adbits:	12,
+	      adrange:	&range_dt3000_ai,
+	      ai_speed:3000,
+	      dachan:	2,
+	      dabits:	12,
+		},
+      {name:"dt3001-pgl",
+	      device_id:0x27,
+	      adchan:	16,
+	      adbits:	12,
+	      adrange:	&range_dt3000_ai_pgl,
+	      ai_speed:3000,
+	      dachan:	2,
+	      dabits:	12,
+		},
+      {name:"dt3002",
+	      device_id:0x23,
+	      adchan:	32,
+	      adbits:	12,
+	      adrange:	&range_dt3000_ai,
+	      ai_speed:3000,
+	      dachan:	0,
+	      dabits:	0,
+		},
+      {name:"dt3003",
+	      device_id:0x24,
+	      adchan:	64,
+	      adbits:	12,
+	      adrange:	&range_dt3000_ai,
+	      ai_speed:3000,
+	      dachan:	2,
+	      dabits:	12,
+		},
+      {name:"dt3003-pgl",
+	      device_id:0x28,
+	      adchan:	64,
+	      adbits:	12,
+	      adrange:	&range_dt3000_ai_pgl,
+	      ai_speed:3000,
+	      dachan:	2,
+	      dabits:	12,
+		},
+      {name:"dt3004",
+	      device_id:0x25,
+	      adchan:	16,
+	      adbits:	16,
+	      adrange:	&range_dt3000_ai,
+	      ai_speed:10000,
+	      dachan:	2,
+	      dabits:	12,
+		},
+      {name:"dt3005",		/* a.k.a. 3004-200 */
+	      device_id:0x26,
+	      adchan:	16,
+	      adbits:	16,
+	      adrange:	&range_dt3000_ai,
+	      ai_speed:5000,
+	      dachan:	2,
+	      dabits:	12,
+		},
+};
+
+#define n_dt3k_boards sizeof(dt3k_boardtypes)/sizeof(struct dt3k_boardtype)
+#define this_board ((const struct dt3k_boardtype *)dev->board_ptr)
+
+static DEFINE_PCI_DEVICE_TABLE(dt3k_pci_table) = {
+	{PCI_VENDOR_ID_DT, 0x0022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_DT, 0x0027, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_DT, 0x0023, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_DT, 0x0024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_DT, 0x0028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_DT, 0x0025, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_DT, 0x0026, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, dt3k_pci_table);
+
+#define DT3000_SIZE		(4*0x1000)
+
+/* dual-ported RAM location definitions */
+
+#define DPR_DAC_buffer		(4*0x000)
+#define DPR_ADC_buffer		(4*0x800)
+#define DPR_Command		(4*0xfd3)
+#define DPR_SubSys		(4*0xfd3)
+#define DPR_Encode		(4*0xfd4)
+#define DPR_Params(a)		(4*(0xfd5+(a)))
+#define DPR_Tick_Reg_Lo		(4*0xff5)
+#define DPR_Tick_Reg_Hi		(4*0xff6)
+#define DPR_DA_Buf_Front	(4*0xff7)
+#define DPR_DA_Buf_Rear		(4*0xff8)
+#define DPR_AD_Buf_Front	(4*0xff9)
+#define DPR_AD_Buf_Rear		(4*0xffa)
+#define DPR_Int_Mask		(4*0xffb)
+#define DPR_Intr_Flag		(4*0xffc)
+#define DPR_Response_Mbx	(4*0xffe)
+#define DPR_Command_Mbx		(4*0xfff)
+
+#define AI_FIFO_DEPTH	2003
+#define AO_FIFO_DEPTH	2048
+
+/* command list */
+
+#define CMD_GETBRDINFO		0
+#define CMD_CONFIG		1
+#define CMD_GETCONFIG		2
+#define CMD_START		3
+#define CMD_STOP		4
+#define CMD_READSINGLE		5
+#define CMD_WRITESINGLE		6
+#define CMD_CALCCLOCK		7
+#define CMD_READEVENTS		8
+#define CMD_WRITECTCTRL		16
+#define CMD_READCTCTRL		17
+#define CMD_WRITECT		18
+#define CMD_READCT		19
+#define CMD_WRITEDATA		32
+#define CMD_READDATA		33
+#define CMD_WRITEIO		34
+#define CMD_READIO		35
+#define CMD_WRITECODE		36
+#define CMD_READCODE		37
+#define CMD_EXECUTE		38
+#define CMD_HALT		48
+
+#define SUBS_AI		0
+#define SUBS_AO		1
+#define SUBS_DIN	2
+#define SUBS_DOUT	3
+#define SUBS_MEM	4
+#define SUBS_CT		5
+
+/* interrupt flags */
+#define DT3000_CMDONE		0x80
+#define DT3000_CTDONE		0x40
+#define DT3000_DAHWERR		0x20
+#define DT3000_DASWERR		0x10
+#define DT3000_DAEMPTY		0x08
+#define DT3000_ADHWERR		0x04
+#define DT3000_ADSWERR		0x02
+#define DT3000_ADFULL		0x01
+
+#define DT3000_COMPLETION_MASK	0xff00
+#define DT3000_COMMAND_MASK	0x00ff
+#define DT3000_NOTPROCESSED	0x0000
+#define DT3000_NOERROR		0x5500
+#define DT3000_ERROR		0xaa00
+#define DT3000_NOTSUPPORTED	0xff00
+
+#define DT3000_EXTERNAL_CLOCK	1
+#define DT3000_RISING_EDGE	2
+
+#define TMODE_MASK		0x1c
+
+#define DT3000_AD_TRIG_INTERNAL		(0<<2)
+#define DT3000_AD_TRIG_EXTERNAL		(1<<2)
+#define DT3000_AD_RETRIG_INTERNAL	(2<<2)
+#define DT3000_AD_RETRIG_EXTERNAL	(3<<2)
+#define DT3000_AD_EXTRETRIG		(4<<2)
+
+#define DT3000_CHANNEL_MODE_SE		0
+#define DT3000_CHANNEL_MODE_DI		1
+
+struct dt3k_private {
+
+	struct pci_dev *pci_dev;
+	resource_size_t phys_addr;
+	void *io_addr;
+	unsigned int lock;
+	unsigned int ao_readback[2];
+	unsigned int ai_front;
+	unsigned int ai_rear;
+};
+
+#define devpriv ((struct dt3k_private *)dev->private)
+
+static int dt3000_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dt3000_detach(struct comedi_device * dev);
+static struct comedi_driver driver_dt3000 = {
+      driver_name:"dt3000",
+      module:THIS_MODULE,
+      attach:dt3000_attach,
+      detach:dt3000_detach,
+};
+
+COMEDI_PCI_INITCLEANUP(driver_dt3000, dt3k_pci_table);
+
+static void dt3k_ai_empty_fifo(struct comedi_device * dev, struct comedi_subdevice * s);
+static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *arg,
+	unsigned int round_mode);
+static int dt3k_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+#ifdef DEBUG
+static void debug_intr_flags(unsigned int flags);
+#endif
+
+#define TIMEOUT 100
+
+static int dt3k_send_cmd(struct comedi_device * dev, unsigned int cmd)
+{
+	int i;
+	unsigned int status = 0;
+
+	writew(cmd, devpriv->io_addr + DPR_Command_Mbx);
+
+	for (i = 0; i < TIMEOUT; i++) {
+		status = readw(devpriv->io_addr + DPR_Command_Mbx);
+		if ((status & DT3000_COMPLETION_MASK) != DT3000_NOTPROCESSED)
+			break;
+		comedi_udelay(1);
+	}
+	if ((status & DT3000_COMPLETION_MASK) == DT3000_NOERROR) {
+		return 0;
+	}
+
+	printk("dt3k_send_cmd() timeout/error status=0x%04x\n", status);
+
+	return -ETIME;
+}
+
+static unsigned int dt3k_readsingle(struct comedi_device * dev, unsigned int subsys,
+	unsigned int chan, unsigned int gain)
+{
+	writew(subsys, devpriv->io_addr + DPR_SubSys);
+
+	writew(chan, devpriv->io_addr + DPR_Params(0));
+	writew(gain, devpriv->io_addr + DPR_Params(1));
+
+	dt3k_send_cmd(dev, CMD_READSINGLE);
+
+	return readw(devpriv->io_addr + DPR_Params(2));
+}
+
+static void dt3k_writesingle(struct comedi_device * dev, unsigned int subsys,
+	unsigned int chan, unsigned int data)
+{
+	writew(subsys, devpriv->io_addr + DPR_SubSys);
+
+	writew(chan, devpriv->io_addr + DPR_Params(0));
+	writew(0, devpriv->io_addr + DPR_Params(1));
+	writew(data, devpriv->io_addr + DPR_Params(2));
+
+	dt3k_send_cmd(dev, CMD_WRITESINGLE);
+}
+
+static int debug_n_ints = 0;
+
+// FIXME! Assumes shared interrupt is for this card.
+// What's this debug_n_ints stuff? Obviously needs some work...
+static irqreturn_t dt3k_interrupt(int irq, void *d PT_REGS_ARG)
+{
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s;
+	unsigned int status;
+
+	if (!dev->attached) {
+		return IRQ_NONE;
+	}
+
+	s = dev->subdevices + 0;
+	status = readw(devpriv->io_addr + DPR_Intr_Flag);
+#ifdef DEBUG
+	debug_intr_flags(status);
+#endif
+
+	if (status & DT3000_ADFULL) {
+		dt3k_ai_empty_fifo(dev, s);
+		s->async->events |= COMEDI_CB_BLOCK;
+	}
+
+	if (status & (DT3000_ADSWERR | DT3000_ADHWERR)) {
+		s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+	}
+
+	debug_n_ints++;
+	if (debug_n_ints >= 10) {
+		dt3k_ai_cancel(dev, s);
+		s->async->events |= COMEDI_CB_EOA;
+	}
+
+	comedi_event(dev, s);
+	return IRQ_HANDLED;
+}
+
+#ifdef DEBUG
+static char *intr_flags[] = {
+	"AdFull", "AdSwError", "AdHwError", "DaEmpty",
+	"DaSwError", "DaHwError", "CtDone", "CmDone",
+};
+static void debug_intr_flags(unsigned int flags)
+{
+	int i;
+	printk("dt3k: intr_flags:");
+	for (i = 0; i < 8; i++) {
+		if (flags & (1 << i)) {
+			printk(" %s", intr_flags[i]);
+		}
+	}
+	printk("\n");
+}
+#endif
+
+static void dt3k_ai_empty_fifo(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	int front;
+	int rear;
+	int count;
+	int i;
+	short data;
+
+	front = readw(devpriv->io_addr + DPR_AD_Buf_Front);
+	count = front - devpriv->ai_front;
+	if (count < 0)
+		count += AI_FIFO_DEPTH;
+
+	printk("reading %d samples\n", count);
+
+	rear = devpriv->ai_rear;
+
+	for (i = 0; i < count; i++) {
+		data = readw(devpriv->io_addr + DPR_ADC_buffer + rear);
+		comedi_buf_put(s->async, data);
+		rear++;
+		if (rear >= AI_FIFO_DEPTH)
+			rear = 0;
+	}
+
+	devpriv->ai_rear = rear;
+	writew(rear, devpriv->io_addr + DPR_AD_Buf_Rear);
+}
+
+static int dt3k_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp;
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_TIMER;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_TIMER;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		if (cmd->scan_begin_arg < this_board->ai_speed) {
+			cmd->scan_begin_arg = this_board->ai_speed;
+			err++;
+		}
+		if (cmd->scan_begin_arg > 100 * 16 * 65535) {
+			cmd->scan_begin_arg = 100 * 16 * 65535;
+			err++;
+		}
+	} else {
+		/* not supported */
+	}
+	if (cmd->convert_src == TRIG_TIMER) {
+		if (cmd->convert_arg < this_board->ai_speed) {
+			cmd->convert_arg = this_board->ai_speed;
+			err++;
+		}
+		if (cmd->convert_arg > 50 * 16 * 65535) {
+			cmd->convert_arg = 50 * 16 * 65535;
+			err++;
+		}
+	} else {
+		/* not supported */
+	}
+
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+	if (cmd->stop_src == TRIG_COUNT) {
+		if (cmd->stop_arg > 0x00ffffff) {
+			cmd->stop_arg = 0x00ffffff;
+			err++;
+		}
+	} else {
+		/* TRIG_NONE */
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		tmp = cmd->scan_begin_arg;
+		dt3k_ns_to_timer(100, &cmd->scan_begin_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+		if (tmp != cmd->scan_begin_arg)
+			err++;
+	} else {
+		/* not supported */
+	}
+	if (cmd->convert_src == TRIG_TIMER) {
+		tmp = cmd->convert_arg;
+		dt3k_ns_to_timer(50, &cmd->convert_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+		if (tmp != cmd->convert_arg)
+			err++;
+		if (cmd->scan_begin_src == TRIG_TIMER &&
+			cmd->scan_begin_arg <
+			cmd->convert_arg * cmd->scan_end_arg) {
+			cmd->scan_begin_arg =
+				cmd->convert_arg * cmd->scan_end_arg;
+			err++;
+		}
+	} else {
+		/* not supported */
+	}
+
+	if (err)
+		return 4;
+
+	return 0;
+}
+
+static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *nanosec,
+	unsigned int round_mode)
+{
+	int divider, base, prescale;
+
+	/* This function needs improvment */
+	/* Don't know if divider==0 works. */
+
+	for (prescale = 0; prescale < 16; prescale++) {
+		base = timer_base * (prescale + 1);
+		switch (round_mode) {
+		case TRIG_ROUND_NEAREST:
+		default:
+			divider = (*nanosec + base / 2) / base;
+			break;
+		case TRIG_ROUND_DOWN:
+			divider = (*nanosec) / base;
+			break;
+		case TRIG_ROUND_UP:
+			divider = (*nanosec) / base;
+			break;
+		}
+		if (divider < 65536) {
+			*nanosec = divider * base;
+			return (prescale << 16) | (divider);
+		}
+	}
+
+	prescale = 15;
+	base = timer_base * (1 << prescale);
+	divider = 65535;
+	*nanosec = divider * base;
+	return (prescale << 16) | (divider);
+}
+
+static int dt3k_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_cmd *cmd = &s->async->cmd;
+	int i;
+	unsigned int chan, range, aref;
+	unsigned int divider;
+	unsigned int tscandiv;
+	int ret;
+	unsigned int mode;
+
+	printk("dt3k_ai_cmd:\n");
+	for (i = 0; i < cmd->chanlist_len; i++) {
+		chan = CR_CHAN(cmd->chanlist[i]);
+		range = CR_RANGE(cmd->chanlist[i]);
+
+		writew((range << 6) | chan,
+			devpriv->io_addr + DPR_ADC_buffer + i);
+	}
+	aref = CR_AREF(cmd->chanlist[0]);
+
+	writew(cmd->scan_end_arg, devpriv->io_addr + DPR_Params(0));
+	printk("param[0]=0x%04x\n", cmd->scan_end_arg);
+
+	if (cmd->convert_src == TRIG_TIMER) {
+		divider = dt3k_ns_to_timer(50, &cmd->convert_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+		writew((divider >> 16), devpriv->io_addr + DPR_Params(1));
+		printk("param[1]=0x%04x\n", divider >> 16);
+		writew((divider & 0xffff), devpriv->io_addr + DPR_Params(2));
+		printk("param[2]=0x%04x\n", divider & 0xffff);
+	} else {
+		/* not supported */
+	}
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		tscandiv = dt3k_ns_to_timer(100, &cmd->scan_begin_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+		writew((tscandiv >> 16), devpriv->io_addr + DPR_Params(3));
+		printk("param[3]=0x%04x\n", tscandiv >> 16);
+		writew((tscandiv & 0xffff), devpriv->io_addr + DPR_Params(4));
+		printk("param[4]=0x%04x\n", tscandiv & 0xffff);
+	} else {
+		/* not supported */
+	}
+
+	mode = DT3000_AD_RETRIG_INTERNAL | 0 | 0;
+	writew(mode, devpriv->io_addr + DPR_Params(5));
+	printk("param[5]=0x%04x\n", mode);
+	writew(aref == AREF_DIFF, devpriv->io_addr + DPR_Params(6));
+	printk("param[6]=0x%04x\n", aref == AREF_DIFF);
+
+	writew(AI_FIFO_DEPTH / 2, devpriv->io_addr + DPR_Params(7));
+	printk("param[7]=0x%04x\n", AI_FIFO_DEPTH / 2);
+
+	writew(SUBS_AI, devpriv->io_addr + DPR_SubSys);
+	ret = dt3k_send_cmd(dev, CMD_CONFIG);
+
+	writew(DT3000_ADFULL | DT3000_ADSWERR | DT3000_ADHWERR,
+		devpriv->io_addr + DPR_Int_Mask);
+
+	debug_n_ints = 0;
+
+	writew(SUBS_AI, devpriv->io_addr + DPR_SubSys);
+	ret = dt3k_send_cmd(dev, CMD_START);
+
+	return 0;
+}
+
+static int dt3k_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	int ret;
+
+	writew(SUBS_AI, devpriv->io_addr + DPR_SubSys);
+	ret = dt3k_send_cmd(dev, CMD_STOP);
+
+	writew(0, devpriv->io_addr + DPR_Int_Mask);
+
+	return 0;
+}
+
+static int dt3k_ai_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	unsigned int chan, gain, aref;
+
+	chan = CR_CHAN(insn->chanspec);
+	gain = CR_RANGE(insn->chanspec);
+	/* XXX docs don't explain how to select aref */
+	aref = CR_AREF(insn->chanspec);
+
+	for (i = 0; i < insn->n; i++) {
+		data[i] = dt3k_readsingle(dev, SUBS_AI, chan, gain);
+	}
+
+	return i;
+}
+
+static int dt3k_ao_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	unsigned int chan;
+
+	chan = CR_CHAN(insn->chanspec);
+	for (i = 0; i < insn->n; i++) {
+		dt3k_writesingle(dev, SUBS_AO, chan, data[i]);
+		devpriv->ao_readback[chan] = data[i];
+	}
+
+	return i;
+}
+
+static int dt3k_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	unsigned int chan;
+
+	chan = CR_CHAN(insn->chanspec);
+	for (i = 0; i < insn->n; i++) {
+		data[i] = devpriv->ao_readback[chan];
+	}
+
+	return i;
+}
+
+static void dt3k_dio_config(struct comedi_device * dev, int bits)
+{
+	/* XXX */
+	writew(SUBS_DOUT, devpriv->io_addr + DPR_SubSys);
+
+	writew(bits, devpriv->io_addr + DPR_Params(0));
+#if 0
+	/* don't know */
+	writew(0, devpriv->io_addr + DPR_Params(1));
+	writew(0, devpriv->io_addr + DPR_Params(2));
+#endif
+
+	dt3k_send_cmd(dev, CMD_CONFIG);
+}
+
+static int dt3k_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int mask;
+
+	mask = (CR_CHAN(insn->chanspec) < 4) ? 0x0f : 0xf0;
+
+	switch (data[0]) {
+	case INSN_CONFIG_DIO_OUTPUT:
+		s->io_bits |= mask;
+		break;
+	case INSN_CONFIG_DIO_INPUT:
+		s->io_bits &= ~mask;
+		break;
+	case INSN_CONFIG_DIO_QUERY:
+		data[1] =
+			(s->io_bits & (1 << CR_CHAN(insn->
+					chanspec))) ? COMEDI_OUTPUT :
+			COMEDI_INPUT;
+		return insn->n;
+		break;
+	default:
+		return -EINVAL;
+		break;
+	}
+	mask = (s->io_bits & 0x01) | ((s->io_bits & 0x10) >> 3);
+	dt3k_dio_config(dev, mask);
+
+	return insn->n;
+}
+
+static int dt3k_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= data[1] & data[0];
+		dt3k_writesingle(dev, SUBS_DOUT, 0, s->state);
+	}
+	data[1] = dt3k_readsingle(dev, SUBS_DIN, 0, 0);
+
+	return 2;
+}
+
+static int dt3k_mem_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int addr = CR_CHAN(insn->chanspec);
+	int i;
+
+	for (i = 0; i < insn->n; i++) {
+		writew(SUBS_MEM, devpriv->io_addr + DPR_SubSys);
+		writew(addr, devpriv->io_addr + DPR_Params(0));
+		writew(1, devpriv->io_addr + DPR_Params(1));
+
+		dt3k_send_cmd(dev, CMD_READCODE);
+
+		data[i] = readw(devpriv->io_addr + DPR_Params(2));
+	}
+
+	return i;
+}
+
+static int dt_pci_probe(struct comedi_device * dev, int bus, int slot);
+
+static int dt3000_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	int bus, slot;
+	int ret = 0;
+
+	printk("dt3000:");
+	bus = it->options[0];
+	slot = it->options[1];
+
+	if ((ret = alloc_private(dev, sizeof(struct dt3k_private))) < 0)
+		return ret;
+
+	ret = dt_pci_probe(dev, bus, slot);
+	if (ret < 0)
+		return ret;
+	if (ret == 0) {
+		printk(" no DT board found\n");
+		return -ENODEV;
+	}
+
+	dev->board_name = this_board->name;
+
+	if (comedi_request_irq(devpriv->pci_dev->irq, dt3k_interrupt,
+			IRQF_SHARED, "dt3000", dev)) {
+		printk(" unable to allocate IRQ %u\n", devpriv->pci_dev->irq);
+		return -EINVAL;
+	}
+	dev->irq = devpriv->pci_dev->irq;
+
+	if ((ret = alloc_subdevices(dev, 4)) < 0)
+		return ret;
+
+	s = dev->subdevices;
+	dev->read_subdev = s;
+
+	/* ai subdevice */
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
+	s->n_chan = this_board->adchan;
+	s->insn_read = dt3k_ai_insn;
+	s->maxdata = (1 << this_board->adbits) - 1;
+	s->len_chanlist = 512;
+	s->range_table = &range_dt3000_ai;	/* XXX */
+	s->do_cmd = dt3k_ai_cmd;
+	s->do_cmdtest = dt3k_ai_cmdtest;
+	s->cancel = dt3k_ai_cancel;
+
+	s++;
+	/* ao subsystem */
+	s->type = COMEDI_SUBD_AO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->n_chan = 2;
+	s->insn_read = dt3k_ao_insn_read;
+	s->insn_write = dt3k_ao_insn;
+	s->maxdata = (1 << this_board->dabits) - 1;
+	s->len_chanlist = 1;
+	s->range_table = &range_bipolar10;
+
+	s++;
+	/* dio subsystem */
+	s->type = COMEDI_SUBD_DIO;
+	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+	s->n_chan = 8;
+	s->insn_config = dt3k_dio_insn_config;
+	s->insn_bits = dt3k_dio_insn_bits;
+	s->maxdata = 1;
+	s->len_chanlist = 8;
+	s->range_table = &range_digital;
+
+	s++;
+	/* mem subsystem */
+	s->type = COMEDI_SUBD_MEMORY;
+	s->subdev_flags = SDF_READABLE;
+	s->n_chan = 0x1000;
+	s->insn_read = dt3k_mem_insn_read;
+	s->maxdata = 0xff;
+	s->len_chanlist = 1;
+	s->range_table = &range_unknown;
+
+#if 0
+	s++;
+	/* proc subsystem */
+	s->type = COMEDI_SUBD_PROC;
+#endif
+
+	return 0;
+}
+
+static int dt3000_detach(struct comedi_device * dev)
+{
+	if (dev->irq)
+		comedi_free_irq(dev->irq, dev);
+
+	if (devpriv) {
+		if (devpriv->pci_dev) {
+			if (devpriv->phys_addr) {
+				comedi_pci_disable(devpriv->pci_dev);
+			}
+			pci_dev_put(devpriv->pci_dev);
+		}
+		if (devpriv->io_addr)
+			iounmap(devpriv->io_addr);
+	}
+	/* XXX */
+
+	return 0;
+}
+
+static struct pci_dev *dt_pci_find_device(struct pci_dev *from, int *board);
+static int setup_pci(struct comedi_device * dev);
+
+static int dt_pci_probe(struct comedi_device * dev, int bus, int slot)
+{
+	int board;
+	int ret;
+	struct pci_dev *pcidev;
+
+	pcidev = NULL;
+	while ((pcidev = dt_pci_find_device(pcidev, &board)) != NULL) {
+		if ((bus == 0 && slot == 0) ||
+			(pcidev->bus->number == bus &&
+			 PCI_SLOT(pcidev->devfn) == slot)) {
+			break;
+		}
+	}
+	devpriv->pci_dev = pcidev;
+
+	if (board >= 0)
+		dev->board_ptr = dt3k_boardtypes + board;
+
+	if (!devpriv->pci_dev)
+		return 0;
+
+	if ((ret = setup_pci(dev)) < 0)
+		return ret;
+
+	return 1;
+}
+
+static int setup_pci(struct comedi_device * dev)
+{
+	resource_size_t addr;
+	int ret;
+
+	ret = comedi_pci_enable(devpriv->pci_dev, "dt3000");
+	if (ret < 0)
+		return ret;
+
+	addr = pci_resource_start(devpriv->pci_dev, 0);
+	devpriv->phys_addr = addr;
+	devpriv->io_addr = ioremap(devpriv->phys_addr, DT3000_SIZE);
+	if (!devpriv->io_addr)
+		return -ENOMEM;
+#if DEBUG
+	printk("0x%08llx mapped to %p, ",
+		(unsigned long long)devpriv->phys_addr, devpriv->io_addr);
+#endif
+
+	return 0;
+}
+
+static struct pci_dev *dt_pci_find_device(struct pci_dev *from, int *board)
+{
+	int i;
+
+	for (from = pci_get_device(PCI_VENDOR_ID_DT, PCI_ANY_ID, from);
+		from != NULL;
+		from = pci_get_device(PCI_VENDOR_ID_DT, PCI_ANY_ID, from)) {
+		for (i = 0; i < n_dt3k_boards; i++) {
+			if (from->device == dt3k_boardtypes[i].device_id) {
+				*board = i;
+				return from;
+			}
+		}
+		printk("unknown Data Translation PCI device found with device_id=0x%04x\n", from->device);
+	}
+	*board = -1;
+	return from;
+}
diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c
index f2d2173..cc4c046 100644
--- a/drivers/staging/comedi/drivers/dt9812.c
+++ b/drivers/staging/comedi/drivers/dt9812.c
@@ -300,22 +300,22 @@
 	struct comedi_dt9812 *comedi;
 };
 
-static const comedi_lrange dt9812_10_ain_range = { 1, {
+static const struct comedi_lrange dt9812_10_ain_range = { 1, {
 			BIP_RANGE(10),
 	}
 };
 
-static const comedi_lrange dt9812_2pt5_ain_range = { 1, {
+static const struct comedi_lrange dt9812_2pt5_ain_range = { 1, {
 			UNI_RANGE(2.5),
 	}
 };
 
-static const comedi_lrange dt9812_10_aout_range = { 1, {
+static const struct comedi_lrange dt9812_10_aout_range = { 1, {
 			BIP_RANGE(10),
 	}
 };
 
-static const comedi_lrange dt9812_2pt5_aout_range = { 1, {
+static const struct comedi_lrange dt9812_2pt5_aout_range = { 1, {
 			UNI_RANGE(2.5),
 	}
 };
@@ -892,12 +892,12 @@
  * Comedi functions
  */
 
-static void dt9812_comedi_open(comedi_device *dev)
+static void dt9812_comedi_open(struct comedi_device *dev)
 {
 	down(&devpriv->slot->mutex);
 	if (devpriv->slot->usb) {
 		/* We have an attached device, fill in current range info */
-		comedi_subdevice *s;
+		struct comedi_subdevice *s;
 
 		s = &dev->subdevices[0];
 		s->n_chan = 8;
@@ -940,8 +940,8 @@
 	up(&devpriv->slot->mutex);
 }
 
-static int dt9812_di_rinsn(comedi_device *dev, comedi_subdevice *s,
-			   comedi_insn *insn, lsampl_t *data)
+static int dt9812_di_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
+			   struct comedi_insn *insn, unsigned int *data)
 {
 	int n;
 	u8 bits = 0;
@@ -952,8 +952,8 @@
 	return n;
 }
 
-static int dt9812_do_winsn(comedi_device *dev, comedi_subdevice *s,
-			   comedi_insn *insn, lsampl_t *data)
+static int dt9812_do_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
+			   struct comedi_insn *insn, unsigned int *data)
 {
 	int n;
 	u8 bits = 0;
@@ -970,8 +970,8 @@
 	return n;
 }
 
-static int dt9812_ai_rinsn(comedi_device *dev, comedi_subdevice *s,
-			   comedi_insn *insn, lsampl_t *data)
+static int dt9812_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
+			   struct comedi_insn *insn, unsigned int *data)
 {
 	int n;
 
@@ -985,8 +985,8 @@
 	return n;
 }
 
-static int dt9812_ao_rinsn(comedi_device *dev, comedi_subdevice *s,
-			   comedi_insn *insn, lsampl_t *data)
+static int dt9812_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
+			   struct comedi_insn *insn, unsigned int *data)
 {
 	int n;
 	u16 value;
@@ -999,8 +999,8 @@
 	return n;
 }
 
-static int dt9812_ao_winsn(comedi_device *dev, comedi_subdevice *s,
-			   comedi_insn *insn, lsampl_t *data)
+static int dt9812_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
+			   struct comedi_insn *insn, unsigned int *data)
 {
 	int n;
 
@@ -1009,10 +1009,10 @@
 	return n;
 }
 
-static int dt9812_attach(comedi_device *dev, comedi_devconfig *it)
+static int dt9812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
 	int i;
-	comedi_subdevice *s;
+	struct comedi_subdevice *s;
 
 	dev->board_name = "dt9812";
 
@@ -1103,12 +1103,12 @@
 	return 0;
 }
 
-static int dt9812_detach(comedi_device *dev)
+static int dt9812_detach(struct comedi_device *dev)
 {
 	return 0;
 }
 
-static comedi_driver dt9812_comedi_driver = {
+static struct comedi_driver dt9812_comedi_driver = {
 	.module = THIS_MODULE,
 	.driver_name = "dt9812",
 	.attach = dt9812_attach,
diff --git a/drivers/staging/comedi/drivers/fl512.c b/drivers/staging/comedi/drivers/fl512.c
new file mode 100644
index 0000000..6d7bb37
--- /dev/null
+++ b/drivers/staging/comedi/drivers/fl512.c
@@ -0,0 +1,186 @@
+/*
+    comedi/drivers/fl512.c
+    Anders Gnistrup <ex18@kalman.iau.dtu.dk>
+*/
+
+/*
+Driver: fl512
+Description: unknown
+Author: Anders Gnistrup <ex18@kalman.iau.dtu.dk>
+Devices: [unknown] FL512 (fl512)
+Status: unknown
+
+Digital I/O is not supported.
+
+Configuration options:
+  [0] - I/O port base address
+*/
+
+#define DEBUG 0
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+#include <linux/ioport.h>
+
+#define FL512_SIZE 16		/* the size of the used memory */
+struct fl512_private {
+
+	short ao_readback[2];
+};
+
+#define devpriv ((struct fl512_private *) dev->private)
+
+static const struct comedi_lrange range_fl512 = { 4, {
+			BIP_RANGE(0.5),
+			BIP_RANGE(1),
+			BIP_RANGE(5),
+			BIP_RANGE(10),
+			UNI_RANGE(1),
+			UNI_RANGE(5),
+			UNI_RANGE(10),
+	}
+};
+
+static int fl512_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int fl512_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver_fl512 = {
+      driver_name:"fl512",
+      module:THIS_MODULE,
+      attach:fl512_attach,
+      detach:fl512_detach,
+};
+
+COMEDI_INITCLEANUP(driver_fl512);
+
+static int fl512_ai_insn(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+static int fl512_ao_insn(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+static int fl512_ao_insn_readback(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+/*
+ * fl512_ai_insn : this is the analog input function
+ */
+static int fl512_ai_insn(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	int n;
+	unsigned int lo_byte, hi_byte;
+	char chan = CR_CHAN(insn->chanspec);
+	unsigned long iobase = dev->iobase;
+
+	for (n = 0; n < insn->n; n++) {	/* sample n times on selected channel */
+		/* XXX probably can move next step out of for() loop -- will make
+		 * AI a little bit faster. */
+		outb(chan, iobase + 2);	/* select chan */
+		outb(0, iobase + 3);	/* start conversion */
+		/* XXX should test "done" flag instead of delay */
+		comedi_udelay(30);	/* sleep 30 usec */
+		lo_byte = inb(iobase + 2);	/* low 8 byte */
+		hi_byte = inb(iobase + 3) & 0xf;	/* high 4 bit and mask */
+		data[n] = lo_byte + (hi_byte << 8);
+	}
+	return n;
+}
+
+/*
+ * fl512_ao_insn : used to write to a DA port n times
+ */
+static int fl512_ao_insn(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	int n;
+	int chan = CR_CHAN(insn->chanspec);	/* get chan to write */
+	unsigned long iobase = dev->iobase;	/* get base address  */
+
+	for (n = 0; n < insn->n; n++) {	/* write n data set */
+		outb(data[n] & 0x0ff, iobase + 4 + 2 * chan);	/* write low byte   */
+		outb((data[n] & 0xf00) >> 8, iobase + 4 + 2 * chan);	/* write high byte  */
+		inb(iobase + 4 + 2 * chan);	/* trig */
+
+		devpriv->ao_readback[chan] = data[n];
+	}
+	return n;
+}
+
+/*
+ * fl512_ao_insn_readback : used to read previous values written to
+ * DA port
+ */
+static int fl512_ao_insn_readback(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	int n;
+	int chan = CR_CHAN(insn->chanspec);
+
+	for (n = 0; n < insn->n; n++) {
+		data[n] = devpriv->ao_readback[chan];
+	}
+
+	return n;
+}
+
+/*
+ * start attach
+ */
+static int fl512_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	unsigned long iobase;
+	struct comedi_subdevice *s;	/* pointer to the subdevice:
+				   Analog in, Analog out, ( not made ->and Digital IO) */
+
+	iobase = it->options[0];
+	printk("comedi:%d fl512: 0x%04lx", dev->minor, iobase);
+	if (!request_region(iobase, FL512_SIZE, "fl512")) {
+		printk(" I/O port conflict\n");
+		return -EIO;
+	}
+	dev->iobase = iobase;
+	dev->board_name = "fl512";
+	if (alloc_private(dev, sizeof(struct fl512_private)) < 0)
+		return -ENOMEM;
+
+#if DEBUG
+	printk("malloc ok\n");
+#endif
+
+	if (alloc_subdevices(dev, 2) < 0)
+		return -ENOMEM;
+
+	/*
+	 * this if the definitions of the supdevices, 2 have been defined
+	 */
+	/* Analog indput */
+	s = dev->subdevices + 0;
+	s->type = COMEDI_SUBD_AI;	/* define subdevice as Analog In   */
+	s->subdev_flags = SDF_READABLE | SDF_GROUND;	/* you can read it from userspace  */
+	s->n_chan = 16;		/* Number of Analog input channels */
+	s->maxdata = 0x0fff;	/* accept only 12 bits of data     */
+	s->range_table = &range_fl512;	/* device use one of the ranges    */
+	s->insn_read = fl512_ai_insn;	/* function to call when read AD   */
+	printk("comedi: fl512: subdevice 0 initialized\n");
+
+	/* Analog output */
+	s = dev->subdevices + 1;
+	s->type = COMEDI_SUBD_AO;	/* define subdevice as Analog OUT   */
+	s->subdev_flags = SDF_WRITABLE;	/* you can write it from userspace  */
+	s->n_chan = 2;		/* Number of Analog output channels */
+	s->maxdata = 0x0fff;	/* accept only 12 bits of data      */
+	s->range_table = &range_fl512;	/* device use one of the ranges     */
+	s->insn_write = fl512_ao_insn;	/* function to call when write DA   */
+	s->insn_read = fl512_ao_insn_readback;	/* function to call when reading DA   */
+	printk("comedi: fl512: subdevice 1 initialized\n");
+
+	return 1;
+}
+
+static int fl512_detach(struct comedi_device * dev)
+{
+	if (dev->iobase)
+		release_region(dev->iobase, FL512_SIZE);
+	printk("comedi%d: fl512: dummy i detach\n", dev->minor);
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c
new file mode 100644
index 0000000..49e5c86
--- /dev/null
+++ b/drivers/staging/comedi/drivers/gsc_hpdi.c
@@ -0,0 +1,1060 @@
+/*
+    comedi/drivers/gsc_hpdi.c
+    This is a driver for the General Standards Corporation High
+    Speed Parallel Digital Interface rs485 boards.
+
+    Author:  Frank Mori Hess <fmhess@users.sourceforge.net>
+    Copyright (C) 2003 Coherent Imaging Systems
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 1997-8 David A. Schleef <ds@schleef.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.
+
+    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.
+
+************************************************************************/
+
+/*
+
+Driver: gsc_hpdi
+Description: General Standards Corporation High
+    Speed Parallel Digital Interface rs485 boards
+Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+Status: only receive mode works, transmit not supported
+Updated: 2003-02-20
+Devices: [General Standards Corporation] PCI-HPDI32 (gsc_hpdi),
+  PMC-HPDI32
+
+Configuration options:
+   [0] - PCI bus of device (optional)
+   [1] - PCI slot of device (optional)
+
+There are some additional hpdi models available from GSC for which
+support could be added to this driver.
+
+*/
+
+#include "../comedidev.h"
+#include <linux/delay.h>
+
+#include "comedi_pci.h"
+#include "plx9080.h"
+#include "comedi_fc.h"
+
+static int hpdi_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int hpdi_detach(struct comedi_device * dev);
+void abort_dma(struct comedi_device * dev, unsigned int channel);
+static int hpdi_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int hpdi_cmd_test(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd);
+static int hpdi_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static irqreturn_t handle_interrupt(int irq, void *d PT_REGS_ARG);
+static int dio_config_block_size(struct comedi_device * dev, unsigned int * data);
+
+#undef HPDI_DEBUG		// disable debugging messages
+//#define HPDI_DEBUG    // enable debugging code
+
+#ifdef HPDI_DEBUG
+#define DEBUG_PRINT(format, args...)  rt_printk(format , ## args )
+#else
+#define DEBUG_PRINT(format, args...)
+#endif
+
+#define TIMER_BASE 50		// 20MHz master clock
+#define DMA_BUFFER_SIZE 0x10000
+#define NUM_DMA_BUFFERS 4
+#define NUM_DMA_DESCRIPTORS 256
+
+// indices of base address regions
+enum base_address_regions {
+	PLX9080_BADDRINDEX = 0,
+	HPDI_BADDRINDEX = 2,
+};
+
+enum hpdi_registers {
+	FIRMWARE_REV_REG = 0x0,
+	BOARD_CONTROL_REG = 0x4,
+	BOARD_STATUS_REG = 0x8,
+	TX_PROG_ALMOST_REG = 0xc,
+	RX_PROG_ALMOST_REG = 0x10,
+	FEATURES_REG = 0x14,
+	FIFO_REG = 0x18,
+	TX_STATUS_COUNT_REG = 0x1c,
+	TX_LINE_VALID_COUNT_REG = 0x20,
+	TX_LINE_INVALID_COUNT_REG = 0x24,
+	RX_STATUS_COUNT_REG = 0x28,
+	RX_LINE_COUNT_REG = 0x2c,
+	INTERRUPT_CONTROL_REG = 0x30,
+	INTERRUPT_STATUS_REG = 0x34,
+	TX_CLOCK_DIVIDER_REG = 0x38,
+	TX_FIFO_SIZE_REG = 0x40,
+	RX_FIFO_SIZE_REG = 0x44,
+	TX_FIFO_WORDS_REG = 0x48,
+	RX_FIFO_WORDS_REG = 0x4c,
+	INTERRUPT_EDGE_LEVEL_REG = 0x50,
+	INTERRUPT_POLARITY_REG = 0x54,
+};
+
+int command_channel_valid(unsigned int channel)
+{
+	if (channel == 0 || channel > 6) {
+		rt_printk("gsc_hpdi: bug! invalid cable command channel\n");
+		return 0;
+	}
+	return 1;
+}
+
+// bit definitions
+
+enum firmware_revision_bits {
+	FEATURES_REG_PRESENT_BIT = 0x8000,
+};
+int firmware_revision(uint32_t fwr_bits)
+{
+	return fwr_bits & 0xff;
+}
+
+int pcb_revision(uint32_t fwr_bits)
+{
+	return (fwr_bits >> 8) & 0xff;
+}
+
+int hpdi_subid(uint32_t fwr_bits)
+{
+	return (fwr_bits >> 16) & 0xff;
+}
+
+enum board_control_bits {
+	BOARD_RESET_BIT = 0x1,	/* wait 10usec before accessing fifos */
+	TX_FIFO_RESET_BIT = 0x2,
+	RX_FIFO_RESET_BIT = 0x4,
+	TX_ENABLE_BIT = 0x10,
+	RX_ENABLE_BIT = 0x20,
+	DEMAND_DMA_DIRECTION_TX_BIT = 0x40,	/* for channel 0, channel 1 can only transmit (when present) */
+	LINE_VALID_ON_STATUS_VALID_BIT = 0x80,
+	START_TX_BIT = 0x10,
+	CABLE_THROTTLE_ENABLE_BIT = 0x20,
+	TEST_MODE_ENABLE_BIT = 0x80000000,
+};
+uint32_t command_discrete_output_bits(unsigned int channel, int output,
+	int output_value)
+{
+	uint32_t bits = 0;
+
+	if (command_channel_valid(channel) == 0)
+		return 0;
+	if (output) {
+		bits |= 0x1 << (16 + channel);
+		if (output_value)
+			bits |= 0x1 << (24 + channel);
+	} else
+		bits |= 0x1 << (24 + channel);
+
+	return bits;
+}
+
+enum board_status_bits {
+	COMMAND_LINE_STATUS_MASK = 0x7f,
+	TX_IN_PROGRESS_BIT = 0x80,
+	TX_NOT_EMPTY_BIT = 0x100,
+	TX_NOT_ALMOST_EMPTY_BIT = 0x200,
+	TX_NOT_ALMOST_FULL_BIT = 0x400,
+	TX_NOT_FULL_BIT = 0x800,
+	RX_NOT_EMPTY_BIT = 0x1000,
+	RX_NOT_ALMOST_EMPTY_BIT = 0x2000,
+	RX_NOT_ALMOST_FULL_BIT = 0x4000,
+	RX_NOT_FULL_BIT = 0x8000,
+	BOARD_JUMPER0_INSTALLED_BIT = 0x10000,
+	BOARD_JUMPER1_INSTALLED_BIT = 0x20000,
+	TX_OVERRUN_BIT = 0x200000,
+	RX_UNDERRUN_BIT = 0x400000,
+	RX_OVERRUN_BIT = 0x800000,
+};
+
+uint32_t almost_full_bits(unsigned int num_words)
+{
+// XXX need to add or subtract one?
+	return (num_words << 16) & 0xff0000;
+}
+
+uint32_t almost_empty_bits(unsigned int num_words)
+{
+	return num_words & 0xffff;
+}
+unsigned int almost_full_num_words(uint32_t bits)
+{
+// XXX need to add or subtract one?
+	return (bits >> 16) & 0xffff;
+}
+unsigned int almost_empty_num_words(uint32_t bits)
+{
+	return bits & 0xffff;
+}
+
+enum features_bits {
+	FIFO_SIZE_PRESENT_BIT = 0x1,
+	FIFO_WORDS_PRESENT_BIT = 0x2,
+	LEVEL_EDGE_INTERRUPTS_PRESENT_BIT = 0x4,
+	GPIO_SUPPORTED_BIT = 0x8,
+	PLX_DMA_CH1_SUPPORTED_BIT = 0x10,
+	OVERRUN_UNDERRUN_SUPPORTED_BIT = 0x20,
+};
+
+enum interrupt_sources {
+	FRAME_VALID_START_INTR = 0,
+	FRAME_VALID_END_INTR = 1,
+	TX_FIFO_EMPTY_INTR = 8,
+	TX_FIFO_ALMOST_EMPTY_INTR = 9,
+	TX_FIFO_ALMOST_FULL_INTR = 10,
+	TX_FIFO_FULL_INTR = 11,
+	RX_EMPTY_INTR = 12,
+	RX_ALMOST_EMPTY_INTR = 13,
+	RX_ALMOST_FULL_INTR = 14,
+	RX_FULL_INTR = 15,
+};
+int command_intr_source(unsigned int channel)
+{
+	if (command_channel_valid(channel) == 0)
+		channel = 1;
+	return channel + 1;
+}
+
+uint32_t intr_bit(int interrupt_source)
+{
+	return 0x1 << interrupt_source;
+}
+
+uint32_t tx_clock_divisor_bits(unsigned int divisor)
+{
+	return divisor & 0xff;
+}
+
+unsigned int fifo_size(uint32_t fifo_size_bits)
+{
+	return fifo_size_bits & 0xfffff;
+}
+
+unsigned int fifo_words(uint32_t fifo_words_bits)
+{
+	return fifo_words_bits & 0xfffff;
+}
+
+uint32_t intr_edge_bit(int interrupt_source)
+{
+	return 0x1 << interrupt_source;
+}
+
+uint32_t intr_active_high_bit(int interrupt_source)
+{
+	return 0x1 << interrupt_source;
+}
+
+struct hpdi_board {
+
+	char *name;
+	int device_id;		// pci device id
+	int subdevice_id;	// pci subdevice id
+};
+
+
+static const struct hpdi_board hpdi_boards[] = {
+	{
+	      name:	"pci-hpdi32",
+	      device_id:PCI_DEVICE_ID_PLX_9080,
+	      subdevice_id:0x2400,
+		},
+#if 0
+	{
+	      name:	"pxi-hpdi32",
+	      device_id:0x9656,
+	      subdevice_id:0x2705,
+		},
+#endif
+};
+
+static inline unsigned int num_boards(void)
+{
+	return sizeof(hpdi_boards) / sizeof(struct hpdi_board);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(hpdi_pci_table) = {
+	{PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9080, PCI_VENDOR_ID_PLX, 0x2400,
+		0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, hpdi_pci_table);
+
+static inline struct hpdi_board *board(const struct comedi_device * dev)
+{
+	return (struct hpdi_board *) dev->board_ptr;
+}
+
+struct hpdi_private {
+
+	struct pci_dev *hw_dev;	// pointer to board's pci_dev struct
+	// base addresses (physical)
+	resource_size_t plx9080_phys_iobase;
+	resource_size_t hpdi_phys_iobase;
+	// base addresses (ioremapped)
+	void *plx9080_iobase;
+	void *hpdi_iobase;
+	uint32_t *dio_buffer[NUM_DMA_BUFFERS];	// dma buffers
+	dma_addr_t dio_buffer_phys_addr[NUM_DMA_BUFFERS];	// physical addresses of dma buffers
+	struct plx_dma_desc *dma_desc;	// array of dma descriptors read by plx9080, allocated to get proper alignment
+	dma_addr_t dma_desc_phys_addr;	// physical address of dma descriptor array
+	unsigned int num_dma_descriptors;
+	uint32_t *desc_dio_buffer[NUM_DMA_DESCRIPTORS];	// pointer to start of buffers indexed by descriptor
+	volatile unsigned int dma_desc_index;	// index of the dma descriptor that is currently being used
+	unsigned int tx_fifo_size;
+	unsigned int rx_fifo_size;
+	volatile unsigned long dio_count;
+	volatile uint32_t bits[24];	// software copies of values written to hpdi registers
+	volatile unsigned int block_size;	// number of bytes at which to generate COMEDI_CB_BLOCK events
+	unsigned dio_config_output:1;
+};
+
+
+static inline struct hpdi_private *priv(struct comedi_device * dev)
+{
+	return dev->private;
+}
+
+static struct comedi_driver driver_hpdi = {
+      driver_name:"gsc_hpdi",
+      module:THIS_MODULE,
+      attach:hpdi_attach,
+      detach:hpdi_detach,
+};
+
+COMEDI_PCI_INITCLEANUP(driver_hpdi, hpdi_pci_table);
+
+static int dio_config_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	switch (data[0]) {
+	case INSN_CONFIG_DIO_OUTPUT:
+		priv(dev)->dio_config_output = 1;
+		return insn->n;
+		break;
+	case INSN_CONFIG_DIO_INPUT:
+		priv(dev)->dio_config_output = 0;
+		return insn->n;
+		break;
+	case INSN_CONFIG_DIO_QUERY:
+		data[1] =
+			priv(dev)->
+			dio_config_output ? COMEDI_OUTPUT : COMEDI_INPUT;
+		return insn->n;
+		break;
+	case INSN_CONFIG_BLOCK_SIZE:
+		return dio_config_block_size(dev, data);
+		break;
+	default:
+		break;
+	}
+
+	return -EINVAL;
+}
+
+static void disable_plx_interrupts(struct comedi_device * dev)
+{
+	writel(0, priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
+}
+
+// initialize plx9080 chip
+static void init_plx9080(struct comedi_device * dev)
+{
+	uint32_t bits;
+	void *plx_iobase = priv(dev)->plx9080_iobase;
+
+	// plx9080 dump
+	DEBUG_PRINT(" plx interrupt status 0x%x\n",
+		readl(plx_iobase + PLX_INTRCS_REG));
+	DEBUG_PRINT(" plx id bits 0x%x\n", readl(plx_iobase + PLX_ID_REG));
+	DEBUG_PRINT(" plx control reg 0x%x\n",
+		readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG));
+
+	DEBUG_PRINT(" plx revision 0x%x\n",
+		readl(plx_iobase + PLX_REVISION_REG));
+	DEBUG_PRINT(" plx dma channel 0 mode 0x%x\n",
+		readl(plx_iobase + PLX_DMA0_MODE_REG));
+	DEBUG_PRINT(" plx dma channel 1 mode 0x%x\n",
+		readl(plx_iobase + PLX_DMA1_MODE_REG));
+	DEBUG_PRINT(" plx dma channel 0 pci address 0x%x\n",
+		readl(plx_iobase + PLX_DMA0_PCI_ADDRESS_REG));
+	DEBUG_PRINT(" plx dma channel 0 local address 0x%x\n",
+		readl(plx_iobase + PLX_DMA0_LOCAL_ADDRESS_REG));
+	DEBUG_PRINT(" plx dma channel 0 transfer size 0x%x\n",
+		readl(plx_iobase + PLX_DMA0_TRANSFER_SIZE_REG));
+	DEBUG_PRINT(" plx dma channel 0 descriptor 0x%x\n",
+		readl(plx_iobase + PLX_DMA0_DESCRIPTOR_REG));
+	DEBUG_PRINT(" plx dma channel 0 command status 0x%x\n",
+		readb(plx_iobase + PLX_DMA0_CS_REG));
+	DEBUG_PRINT(" plx dma channel 0 threshold 0x%x\n",
+		readl(plx_iobase + PLX_DMA0_THRESHOLD_REG));
+	DEBUG_PRINT(" plx bigend 0x%x\n", readl(plx_iobase + PLX_BIGEND_REG));
+#ifdef __BIG_ENDIAN
+	bits = BIGEND_DMA0 | BIGEND_DMA1;
+#else
+	bits = 0;
+#endif
+	writel(bits, priv(dev)->plx9080_iobase + PLX_BIGEND_REG);
+
+	disable_plx_interrupts(dev);
+
+	abort_dma(dev, 0);
+	abort_dma(dev, 1);
+
+	// configure dma0 mode
+	bits = 0;
+	// enable ready input
+	bits |= PLX_DMA_EN_READYIN_BIT;
+	// enable dma chaining
+	bits |= PLX_EN_CHAIN_BIT;
+	// enable interrupt on dma done (probably don't need this, since chain never finishes)
+	bits |= PLX_EN_DMA_DONE_INTR_BIT;
+	// don't increment local address during transfers (we are transferring from a fixed fifo register)
+	bits |= PLX_LOCAL_ADDR_CONST_BIT;
+	// route dma interrupt to pci bus
+	bits |= PLX_DMA_INTR_PCI_BIT;
+	// enable demand mode
+	bits |= PLX_DEMAND_MODE_BIT;
+	// enable local burst mode
+	bits |= PLX_DMA_LOCAL_BURST_EN_BIT;
+	bits |= PLX_LOCAL_BUS_32_WIDE_BITS;
+	writel(bits, plx_iobase + PLX_DMA0_MODE_REG);
+}
+
+/* Allocate and initialize the subdevice structures.
+ */
+static int setup_subdevices(struct comedi_device * dev)
+{
+	struct comedi_subdevice *s;
+
+	if (alloc_subdevices(dev, 1) < 0)
+		return -ENOMEM;
+
+	s = dev->subdevices + 0;
+	/* analog input subdevice */
+	dev->read_subdev = s;
+/*	dev->write_subdev = s; */
+	s->type = COMEDI_SUBD_DIO;
+	s->subdev_flags =
+		SDF_READABLE | SDF_WRITEABLE | SDF_LSAMPL | SDF_CMD_READ;
+	s->n_chan = 32;
+	s->len_chanlist = 32;
+	s->maxdata = 1;
+	s->range_table = &range_digital;
+	s->insn_config = dio_config_insn;
+	s->do_cmd = hpdi_cmd;
+	s->do_cmdtest = hpdi_cmd_test;
+	s->cancel = hpdi_cancel;
+
+	return 0;
+}
+
+static int init_hpdi(struct comedi_device * dev)
+{
+	uint32_t plx_intcsr_bits;
+
+	writel(BOARD_RESET_BIT, priv(dev)->hpdi_iobase + BOARD_CONTROL_REG);
+	comedi_udelay(10);
+
+	writel(almost_empty_bits(32) | almost_full_bits(32),
+		priv(dev)->hpdi_iobase + RX_PROG_ALMOST_REG);
+	writel(almost_empty_bits(32) | almost_full_bits(32),
+		priv(dev)->hpdi_iobase + TX_PROG_ALMOST_REG);
+
+	priv(dev)->tx_fifo_size = fifo_size(readl(priv(dev)->hpdi_iobase +
+			TX_FIFO_SIZE_REG));
+	priv(dev)->rx_fifo_size = fifo_size(readl(priv(dev)->hpdi_iobase +
+			RX_FIFO_SIZE_REG));
+
+	writel(0, priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG);
+
+	// enable interrupts
+	plx_intcsr_bits =
+		ICS_AERR | ICS_PERR | ICS_PIE | ICS_PLIE | ICS_PAIE | ICS_LIE |
+		ICS_DMA0_E;
+	writel(plx_intcsr_bits, priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
+
+	return 0;
+}
+
+// setup dma descriptors so a link completes every 'transfer_size' bytes
+static int setup_dma_descriptors(struct comedi_device * dev,
+	unsigned int transfer_size)
+{
+	unsigned int buffer_index, buffer_offset;
+	uint32_t next_bits = PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT |
+		PLX_XFER_LOCAL_TO_PCI;
+	unsigned int i;
+
+	if (transfer_size > DMA_BUFFER_SIZE)
+		transfer_size = DMA_BUFFER_SIZE;
+	transfer_size -= transfer_size % sizeof(uint32_t);
+	if (transfer_size == 0)
+		return -1;
+
+	DEBUG_PRINT(" transfer_size %i\n", transfer_size);
+	DEBUG_PRINT(" descriptors at 0x%lx\n",
+		(unsigned long)priv(dev)->dma_desc_phys_addr);
+
+	buffer_offset = 0;
+	buffer_index = 0;
+	for (i = 0; i < NUM_DMA_DESCRIPTORS &&
+		buffer_index < NUM_DMA_BUFFERS; i++) {
+		priv(dev)->dma_desc[i].pci_start_addr =
+			cpu_to_le32(priv(dev)->
+			dio_buffer_phys_addr[buffer_index] + buffer_offset);
+		priv(dev)->dma_desc[i].local_start_addr = cpu_to_le32(FIFO_REG);
+		priv(dev)->dma_desc[i].transfer_size =
+			cpu_to_le32(transfer_size);
+		priv(dev)->dma_desc[i].next =
+			cpu_to_le32((priv(dev)->dma_desc_phys_addr + (i +
+					1) *
+				sizeof(priv(dev)->dma_desc[0])) | next_bits);
+
+		priv(dev)->desc_dio_buffer[i] =
+			priv(dev)->dio_buffer[buffer_index] +
+			(buffer_offset / sizeof(uint32_t));
+
+		buffer_offset += transfer_size;
+		if (transfer_size + buffer_offset > DMA_BUFFER_SIZE) {
+			buffer_offset = 0;
+			buffer_index++;
+		}
+
+		DEBUG_PRINT(" desc %i\n", i);
+		DEBUG_PRINT(" start addr virt 0x%p, phys 0x%lx\n",
+			priv(dev)->desc_dio_buffer[i],
+			(unsigned long)priv(dev)->dma_desc[i].pci_start_addr);
+		DEBUG_PRINT(" next 0x%lx\n",
+			(unsigned long)priv(dev)->dma_desc[i].next);
+	}
+	priv(dev)->num_dma_descriptors = i;
+	// fix last descriptor to point back to first
+	priv(dev)->dma_desc[i - 1].next =
+		cpu_to_le32(priv(dev)->dma_desc_phys_addr | next_bits);
+	DEBUG_PRINT(" desc %i next fixup 0x%lx\n", i - 1,
+		(unsigned long)priv(dev)->dma_desc[i - 1].next);
+
+	priv(dev)->block_size = transfer_size;
+
+	return transfer_size;
+}
+
+static int hpdi_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct pci_dev *pcidev;
+	int i;
+	int retval;
+
+	printk("comedi%d: gsc_hpdi\n", dev->minor);
+
+	if (alloc_private(dev, sizeof(struct hpdi_private)) < 0)
+		return -ENOMEM;
+
+	pcidev = NULL;
+	for (i = 0; i < num_boards() && dev->board_ptr == NULL; i++) {
+		do {
+			pcidev = pci_get_subsys(PCI_VENDOR_ID_PLX,
+				hpdi_boards[i].device_id, PCI_VENDOR_ID_PLX,
+				hpdi_boards[i].subdevice_id, pcidev);
+			// was a particular bus/slot requested?
+			if (it->options[0] || it->options[1]) {
+				// are we on the wrong bus/slot?
+				if (pcidev->bus->number != it->options[0] ||
+					PCI_SLOT(pcidev->devfn) !=
+					it->options[1])
+					continue;
+			}
+			if (pcidev) {
+				priv(dev)->hw_dev = pcidev;
+				dev->board_ptr = hpdi_boards + i;
+				break;
+			}
+		} while (pcidev != NULL);
+	}
+	if (dev->board_ptr == NULL) {
+		printk("gsc_hpdi: no hpdi card found\n");
+		return -EIO;
+	}
+
+	printk("gsc_hpdi: found %s on bus %i, slot %i\n", board(dev)->name,
+		pcidev->bus->number, PCI_SLOT(pcidev->devfn));
+
+	if (comedi_pci_enable(pcidev, driver_hpdi.driver_name)) {
+		printk(KERN_WARNING
+			" failed enable PCI device and request regions\n");
+		return -EIO;
+	}
+	pci_set_master(pcidev);
+
+	//Initialize dev->board_name
+	dev->board_name = board(dev)->name;
+
+	priv(dev)->plx9080_phys_iobase =
+		pci_resource_start(pcidev, PLX9080_BADDRINDEX);
+	priv(dev)->hpdi_phys_iobase =
+		pci_resource_start(pcidev, HPDI_BADDRINDEX);
+
+	// remap, won't work with 2.0 kernels but who cares
+	priv(dev)->plx9080_iobase = ioremap(priv(dev)->plx9080_phys_iobase,
+		pci_resource_len(pcidev, PLX9080_BADDRINDEX));
+	priv(dev)->hpdi_iobase = ioremap(priv(dev)->hpdi_phys_iobase,
+		pci_resource_len(pcidev, HPDI_BADDRINDEX));
+	if (!priv(dev)->plx9080_iobase || !priv(dev)->hpdi_iobase) {
+		printk(" failed to remap io memory\n");
+		return -ENOMEM;
+	}
+
+	DEBUG_PRINT(" plx9080 remapped to 0x%p\n", priv(dev)->plx9080_iobase);
+	DEBUG_PRINT(" hpdi remapped to 0x%p\n", priv(dev)->hpdi_iobase);
+
+	init_plx9080(dev);
+
+	// get irq
+	if (comedi_request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED,
+			driver_hpdi.driver_name, dev)) {
+		printk(" unable to allocate irq %u\n", pcidev->irq);
+		return -EINVAL;
+	}
+	dev->irq = pcidev->irq;
+
+	printk(" irq %u\n", dev->irq);
+
+	// alocate pci dma buffers
+	for (i = 0; i < NUM_DMA_BUFFERS; i++) {
+		priv(dev)->dio_buffer[i] =
+			pci_alloc_consistent(priv(dev)->hw_dev, DMA_BUFFER_SIZE,
+			&priv(dev)->dio_buffer_phys_addr[i]);
+		DEBUG_PRINT("dio_buffer at virt 0x%p, phys 0x%lx\n",
+			priv(dev)->dio_buffer[i],
+			(unsigned long)priv(dev)->dio_buffer_phys_addr[i]);
+	}
+	// allocate dma descriptors
+	priv(dev)->dma_desc = pci_alloc_consistent(priv(dev)->hw_dev,
+		sizeof(struct plx_dma_desc) * NUM_DMA_DESCRIPTORS,
+		&priv(dev)->dma_desc_phys_addr);
+	if (priv(dev)->dma_desc_phys_addr & 0xf) {
+		printk(" dma descriptors not quad-word aligned (bug)\n");
+		return -EIO;
+	}
+
+	retval = setup_dma_descriptors(dev, 0x1000);
+	if (retval < 0)
+		return retval;
+
+	retval = setup_subdevices(dev);
+	if (retval < 0)
+		return retval;
+
+	return init_hpdi(dev);
+}
+
+static int hpdi_detach(struct comedi_device * dev)
+{
+	unsigned int i;
+
+	printk("comedi%d: gsc_hpdi: remove\n", dev->minor);
+
+	if (dev->irq)
+		comedi_free_irq(dev->irq, dev);
+	if (priv(dev)) {
+		if (priv(dev)->hw_dev) {
+			if (priv(dev)->plx9080_iobase) {
+				disable_plx_interrupts(dev);
+				iounmap((void *)priv(dev)->plx9080_iobase);
+			}
+			if (priv(dev)->hpdi_iobase)
+				iounmap((void *)priv(dev)->hpdi_iobase);
+			// free pci dma buffers
+			for (i = 0; i < NUM_DMA_BUFFERS; i++) {
+				if (priv(dev)->dio_buffer[i])
+					pci_free_consistent(priv(dev)->hw_dev,
+						DMA_BUFFER_SIZE,
+						priv(dev)->dio_buffer[i],
+						priv(dev)->
+						dio_buffer_phys_addr[i]);
+			}
+			// free dma descriptors
+			if (priv(dev)->dma_desc)
+				pci_free_consistent(priv(dev)->hw_dev,
+					sizeof(struct plx_dma_desc) *
+					NUM_DMA_DESCRIPTORS,
+					priv(dev)->dma_desc,
+					priv(dev)->dma_desc_phys_addr);
+			if (priv(dev)->hpdi_phys_iobase) {
+				comedi_pci_disable(priv(dev)->hw_dev);
+			}
+			pci_dev_put(priv(dev)->hw_dev);
+		}
+	}
+	return 0;
+}
+
+static int dio_config_block_size(struct comedi_device * dev, unsigned int * data)
+{
+	unsigned int requested_block_size;
+	int retval;
+
+	requested_block_size = data[1];
+
+	retval = setup_dma_descriptors(dev, requested_block_size);
+	if (retval < 0)
+		return retval;
+
+	data[1] = retval;
+
+	return 2;
+}
+
+static int di_cmd_test(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp;
+	int i;
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_EXT;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_NOW;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	// uniqueness check
+	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (!cmd->chanlist_len) {
+		cmd->chanlist_len = 32;
+		err++;
+	}
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+
+	switch (cmd->stop_src) {
+	case TRIG_COUNT:
+		if (!cmd->stop_arg) {
+			cmd->stop_arg = 1;
+			err++;
+		}
+		break;
+	case TRIG_NONE:
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+		break;
+	default:
+		break;
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	if (err)
+		return 4;
+
+	if (cmd->chanlist) {
+		for (i = 1; i < cmd->chanlist_len; i++) {
+			if (CR_CHAN(cmd->chanlist[i]) != i) {
+				// XXX could support 8 channels or 16 channels
+				comedi_error(dev,
+					"chanlist must be channels 0 to 31 in order");
+				err++;
+				break;
+			}
+		}
+	}
+
+	if (err)
+		return 5;
+
+	return 0;
+}
+
+static int hpdi_cmd_test(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	if (priv(dev)->dio_config_output) {
+		return -EINVAL;
+	} else
+		return di_cmd_test(dev, s, cmd);
+}
+
+static inline void hpdi_writel(struct comedi_device * dev, uint32_t bits,
+	unsigned int offset)
+{
+	writel(bits | priv(dev)->bits[offset / sizeof(uint32_t)],
+		priv(dev)->hpdi_iobase + offset);
+}
+
+static int di_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	uint32_t bits;
+	unsigned long flags;
+	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+
+	hpdi_writel(dev, RX_FIFO_RESET_BIT, BOARD_CONTROL_REG);
+
+	DEBUG_PRINT("hpdi: in di_cmd\n");
+
+	abort_dma(dev, 0);
+
+	priv(dev)->dma_desc_index = 0;
+
+	/* These register are supposedly unused during chained dma,
+	 * but I have found that left over values from last operation
+	 * occasionally cause problems with transfer of first dma
+	 * block.  Initializing them to zero seems to fix the problem. */
+	writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_TRANSFER_SIZE_REG);
+	writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG);
+	writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_LOCAL_ADDRESS_REG);
+	// give location of first dma descriptor
+	bits = priv(dev)->
+		dma_desc_phys_addr | PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT |
+		PLX_XFER_LOCAL_TO_PCI;
+	writel(bits, priv(dev)->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG);
+
+	// spinlock for plx dma control/status reg
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	// enable dma transfer
+	writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT | PLX_CLEAR_DMA_INTR_BIT,
+		priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	if (cmd->stop_src == TRIG_COUNT)
+		priv(dev)->dio_count = cmd->stop_arg;
+	else
+		priv(dev)->dio_count = 1;
+
+	// clear over/under run status flags
+	writel(RX_UNDERRUN_BIT | RX_OVERRUN_BIT,
+		priv(dev)->hpdi_iobase + BOARD_STATUS_REG);
+	// enable interrupts
+	writel(intr_bit(RX_FULL_INTR),
+		priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG);
+
+	DEBUG_PRINT("hpdi: starting rx\n");
+	hpdi_writel(dev, RX_ENABLE_BIT, BOARD_CONTROL_REG);
+
+	return 0;
+}
+
+static int hpdi_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	if (priv(dev)->dio_config_output) {
+		return -EINVAL;
+	} else
+		return di_cmd(dev, s);
+}
+
+static void drain_dma_buffers(struct comedi_device * dev, unsigned int channel)
+{
+	struct comedi_async *async = dev->read_subdev->async;
+	uint32_t next_transfer_addr;
+	int j;
+	int num_samples = 0;
+	void *pci_addr_reg;
+
+	if (channel)
+		pci_addr_reg =
+			priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG;
+	else
+		pci_addr_reg =
+			priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG;
+
+	// loop until we have read all the full buffers
+	j = 0;
+	for (next_transfer_addr = readl(pci_addr_reg);
+		(next_transfer_addr <
+			le32_to_cpu(priv(dev)->dma_desc[priv(dev)->
+					dma_desc_index].pci_start_addr)
+			|| next_transfer_addr >=
+			le32_to_cpu(priv(dev)->dma_desc[priv(dev)->
+					dma_desc_index].pci_start_addr) +
+			priv(dev)->block_size)
+		&& j < priv(dev)->num_dma_descriptors; j++) {
+		// transfer data from dma buffer to comedi buffer
+		num_samples = priv(dev)->block_size / sizeof(uint32_t);
+		if (async->cmd.stop_src == TRIG_COUNT) {
+			if (num_samples > priv(dev)->dio_count)
+				num_samples = priv(dev)->dio_count;
+			priv(dev)->dio_count -= num_samples;
+		}
+		cfc_write_array_to_buffer(dev->read_subdev,
+			priv(dev)->desc_dio_buffer[priv(dev)->dma_desc_index],
+			num_samples * sizeof(uint32_t));
+		priv(dev)->dma_desc_index++;
+		priv(dev)->dma_desc_index %= priv(dev)->num_dma_descriptors;
+
+		DEBUG_PRINT("next desc addr 0x%lx\n", (unsigned long)
+			priv(dev)->dma_desc[priv(dev)->dma_desc_index].next);
+		DEBUG_PRINT("pci addr reg 0x%x\n", next_transfer_addr);
+	}
+	// XXX check for buffer overrun somehow
+}
+
+static irqreturn_t handle_interrupt(int irq, void *d PT_REGS_ARG)
+{
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s = dev->read_subdev;
+	struct comedi_async *async = s->async;
+	uint32_t hpdi_intr_status, hpdi_board_status;
+	uint32_t plx_status;
+	uint32_t plx_bits;
+	uint8_t dma0_status, dma1_status;
+	unsigned long flags;
+
+	if (!dev->attached) {
+		return IRQ_NONE;
+	}
+
+	plx_status = readl(priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
+	if ((plx_status & (ICS_DMA0_A | ICS_DMA1_A | ICS_LIA)) == 0) {
+		return IRQ_NONE;
+	}
+
+	hpdi_intr_status = readl(priv(dev)->hpdi_iobase + INTERRUPT_STATUS_REG);
+	hpdi_board_status = readl(priv(dev)->hpdi_iobase + BOARD_STATUS_REG);
+
+	async->events = 0;
+
+	if (hpdi_intr_status) {
+		DEBUG_PRINT("hpdi: intr status 0x%x, ", hpdi_intr_status);
+		writel(hpdi_intr_status,
+			priv(dev)->hpdi_iobase + INTERRUPT_STATUS_REG);
+	}
+	// spin lock makes sure noone else changes plx dma control reg
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	dma0_status = readb(priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+	if (plx_status & ICS_DMA0_A) {	// dma chan 0 interrupt
+		writeb((dma0_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
+			priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+
+		DEBUG_PRINT("dma0 status 0x%x\n", dma0_status);
+		if (dma0_status & PLX_DMA_EN_BIT) {
+			drain_dma_buffers(dev, 0);
+		}
+		DEBUG_PRINT(" cleared dma ch0 interrupt\n");
+	}
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	// spin lock makes sure noone else changes plx dma control reg
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	dma1_status = readb(priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
+	if (plx_status & ICS_DMA1_A)	// XXX
+	{			// dma chan 1 interrupt
+		writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
+			priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
+		DEBUG_PRINT("dma1 status 0x%x\n", dma1_status);
+
+		DEBUG_PRINT(" cleared dma ch1 interrupt\n");
+	}
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	// clear possible plx9080 interrupt sources
+	if (plx_status & ICS_LDIA) {	// clear local doorbell interrupt
+		plx_bits = readl(priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG);
+		writel(plx_bits, priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG);
+		DEBUG_PRINT(" cleared local doorbell bits 0x%x\n", plx_bits);
+	}
+
+	if (hpdi_board_status & RX_OVERRUN_BIT) {
+		comedi_error(dev, "rx fifo overrun");
+		async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+		DEBUG_PRINT("dma0_status 0x%x\n",
+			(int)readb(priv(dev)->plx9080_iobase +
+				PLX_DMA0_CS_REG));
+	}
+
+	if (hpdi_board_status & RX_UNDERRUN_BIT) {
+		comedi_error(dev, "rx fifo underrun");
+		async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+	}
+
+	if (priv(dev)->dio_count == 0)
+		async->events |= COMEDI_CB_EOA;
+
+	DEBUG_PRINT("board status 0x%x, ", hpdi_board_status);
+	DEBUG_PRINT("plx status 0x%x\n", plx_status);
+	if (async->events)
+		DEBUG_PRINT(" events 0x%x\n", async->events);
+
+	cfc_handle_events(dev, s);
+
+	return IRQ_HANDLED;
+}
+
+void abort_dma(struct comedi_device * dev, unsigned int channel)
+{
+	unsigned long flags;
+
+	// spinlock for plx dma control/status reg
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+
+	plx9080_abort_dma(priv(dev)->plx9080_iobase, channel);
+
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+}
+
+static int hpdi_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	hpdi_writel(dev, 0, BOARD_CONTROL_REG);
+
+	writel(0, priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG);
+
+	abort_dma(dev, 0);
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c
index 59144d7..15fce01 100644
--- a/drivers/staging/comedi/drivers/icp_multi.c
+++ b/drivers/staging/comedi/drivers/icp_multi.c
@@ -61,7 +61,7 @@
 
 #define ICP_MULTI_EXTDEBUG
 
-// Hardware types of the cards
+/*  Hardware types of the cards */
 #define TYPE_ICP_MULTI	0
 
 #define IORANGE_ICP_MULTI 	32
@@ -81,20 +81,20 @@
 
 #define ICP_MULTI_SIZE		0x20	/* 32 bytes */
 
-// Define bits from ADC command/status register
+/*  Define bits from ADC command/status register */
 #define	ADC_ST		0x0001	/* Start ADC */
 #define	ADC_BSY		0x0001	/* ADC busy */
 #define ADC_BI		0x0010	/* Bipolar input range 1 = bipolar */
 #define ADC_RA		0x0020	/* Input range 0 = 5V, 1 = 10V */
 #define	ADC_DI		0x0040	/* Differential input mode 1 = differential */
 
-// Define bits from DAC command/status register
+/*  Define bits from DAC command/status register */
 #define	DAC_ST		0x0001	/* Start DAC */
 #define DAC_BSY		0x0001	/* DAC busy */
 #define	DAC_BI		0x0010	/* Bipolar input range 1 = bipolar */
 #define	DAC_RA		0x0020	/* Input range 0 = 5V, 1 = 10V */
 
-// Define bits from interrupt enable/status registers
+/*  Define bits from interrupt enable/status registers */
 #define	ADC_READY	0x0001	/* A/d conversion ready interrupt */
 #define	DAC_READY	0x0002	/* D/a conversion ready interrupt */
 #define	DOUT_ERROR	0x0004	/* Digital output error interrupt */
@@ -104,11 +104,11 @@
 #define	CIE2		0x0040	/* Counter 2 overrun interrupt */
 #define	CIE3		0x0080	/* Counter 3 overrun interrupt */
 
-// Useful definitions
-#define	Status_IRQ	0x00ff	// All interrupts
+/*  Useful definitions */
+#define	Status_IRQ	0x00ff	/*  All interrupts */
 
-// Define analogue range
-static const comedi_lrange range_analog = { 4, {
+/*  Define analogue range */
+static const struct comedi_lrange range_analog = { 4, {
 			UNI_RANGE(5),
 			UNI_RANGE(10),
 			BIP_RANGE(5),
@@ -123,8 +123,8 @@
 	Forward declarations
 ==============================================================================
 */
-static int icp_multi_attach(comedi_device * dev, comedi_devconfig * it);
-static int icp_multi_detach(comedi_device * dev);
+static int icp_multi_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int icp_multi_detach(struct comedi_device *dev);
 
 /*
 ==============================================================================
@@ -133,79 +133,79 @@
 */
 static unsigned short pci_list_builded = 0;	/*>0 list of card is known */
 
-typedef struct {
-	const char *name;	// driver name
+struct boardtype {
+	const char *name;	/*  driver name */
 	int device_id;
-	int iorange;		// I/O range len
-	char have_irq;		// 1=card support IRQ
-	char cardtype;		// 0=ICP Multi
-	int n_aichan;		// num of A/D chans
-	int n_aichand;		// num of A/D chans in diff mode
-	int n_aochan;		// num of D/A chans
-	int n_dichan;		// num of DI chans
-	int n_dochan;		// num of DO chans
-	int n_ctrs;		// num of counters
-	int ai_maxdata;		// resolution of A/D
-	int ao_maxdata;		// resolution of D/A
-	const comedi_lrange *rangelist_ai;	// rangelist for A/D
-	const char *rangecode;	// range codes for programming
-	const comedi_lrange *rangelist_ao;	// rangelist for D/A
-} boardtype;
-
-static const boardtype boardtypes[] = {
-	{"icp_multi",		// Driver name
-			DEVICE_ID,	// PCI device ID
-			IORANGE_ICP_MULTI,	// I/O range length
-			1,	// 1=Card supports interrupts
-			TYPE_ICP_MULTI,	// Card type = ICP MULTI
-			16,	// Num of A/D channels
-			8,	// Num of A/D channels in diff mode
-			4,	// Num of D/A channels
-			16,	// Num of digital inputs
-			8,	// Num of digital outputs
-			4,	// Num of counters
-			0x0fff,	// Resolution of A/D
-			0x0fff,	// Resolution of D/A
-			&range_analog,	// Rangelist for A/D
-			range_codes_analog,	// Range codes for programming
-		&range_analog},	// Rangelist for D/A
+	int iorange;		/*  I/O range len */
+	char have_irq;		/*  1=card support IRQ */
+	char cardtype;		/*  0=ICP Multi */
+	int n_aichan;		/*  num of A/D chans */
+	int n_aichand;		/*  num of A/D chans in diff mode */
+	int n_aochan;		/*  num of D/A chans */
+	int n_dichan;		/*  num of DI chans */
+	int n_dochan;		/*  num of DO chans */
+	int n_ctrs;		/*  num of counters */
+	int ai_maxdata;		/*  resolution of A/D */
+	int ao_maxdata;		/*  resolution of D/A */
+	const struct comedi_lrange *rangelist_ai;	/*  rangelist for A/D */
+	const char *rangecode;	/*  range codes for programming */
+	const struct comedi_lrange *rangelist_ao;	/*  rangelist for D/A */
 };
 
-#define n_boardtypes (sizeof(boardtypes)/sizeof(boardtype))
+static const struct boardtype boardtypes[] = {
+	{"icp_multi",		/*  Driver name */
+			DEVICE_ID,	/*  PCI device ID */
+			IORANGE_ICP_MULTI,	/*  I/O range length */
+			1,	/*  1=Card supports interrupts */
+			TYPE_ICP_MULTI,	/*  Card type = ICP MULTI */
+			16,	/*  Num of A/D channels */
+			8,	/*  Num of A/D channels in diff mode */
+			4,	/*  Num of D/A channels */
+			16,	/*  Num of digital inputs */
+			8,	/*  Num of digital outputs */
+			4,	/*  Num of counters */
+			0x0fff,	/*  Resolution of A/D */
+			0x0fff,	/*  Resolution of D/A */
+			&range_analog,	/*  Rangelist for A/D */
+			range_codes_analog,	/*  Range codes for programming */
+		&range_analog},	/*  Rangelist for D/A */
+};
 
-static comedi_driver driver_icp_multi = {
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype))
+
+static struct comedi_driver driver_icp_multi = {
       driver_name:"icp_multi",
-      module:THIS_MODULE,
-      attach:icp_multi_attach,
-      detach:icp_multi_detach,
-      num_names:n_boardtypes,
-      board_name:&boardtypes[0].name,
-      offset:sizeof(boardtype),
+      module : THIS_MODULE,
+      attach : icp_multi_attach,
+      detach : icp_multi_detach,
+      num_names : n_boardtypes,
+      board_name : &boardtypes[0].name,
+      offset : sizeof(struct boardtype),
 };
 
 COMEDI_INITCLEANUP(driver_icp_multi);
 
-typedef struct {
-	struct pcilst_struct *card;	// pointer to card
-	char valid;		// card is usable
-	void *io_addr;		// Pointer to mapped io address
-	resource_size_t phys_iobase;	// Physical io address
-	unsigned int AdcCmdStatus;	// ADC Command/Status register
-	unsigned int DacCmdStatus;	// DAC Command/Status register
-	unsigned int IntEnable;	// Interrupt Enable register
-	unsigned int IntStatus;	// Interrupt Status register
-	unsigned int act_chanlist[32];	// list of scaned channel
-	unsigned char act_chanlist_len;	// len of scanlist
-	unsigned char act_chanlist_pos;	// actual position in MUX list
-	unsigned int *ai_chanlist;	// actaul chanlist
-	sampl_t *ai_data;	// data buffer
-	sampl_t ao_data[4];	// data output buffer
-	sampl_t di_data;	// Digital input data
-	unsigned int do_data;	// Remember digital output data
-} icp_multi_private;
+struct icp_multi_private {
+	struct pcilst_struct *card;	/*  pointer to card */
+	char valid;		/*  card is usable */
+	void *io_addr;		/*  Pointer to mapped io address */
+	resource_size_t phys_iobase;	/*  Physical io address */
+	unsigned int AdcCmdStatus;	/*  ADC Command/Status register */
+	unsigned int DacCmdStatus;	/*  DAC Command/Status register */
+	unsigned int IntEnable;	/*  Interrupt Enable register */
+	unsigned int IntStatus;	/*  Interrupt Status register */
+	unsigned int act_chanlist[32];	/*  list of scaned channel */
+	unsigned char act_chanlist_len;	/*  len of scanlist */
+	unsigned char act_chanlist_pos;	/*  actual position in MUX list */
+	unsigned int *ai_chanlist;	/*  actaul chanlist */
+	short *ai_data;	/*  data buffer */
+	short ao_data[4];	/*  data output buffer */
+	short di_data;	/*  Digital input data */
+	unsigned int do_data;	/*  Remember digital output data */
+};
 
-#define devpriv ((icp_multi_private *)dev->private)
-#define this_board ((const boardtype *)dev->board_ptr)
+#define devpriv ((struct icp_multi_private *)dev->private)
+#define this_board ((const struct boardtype *)dev->board_ptr)
 
 /*
 ==============================================================================
@@ -214,12 +214,12 @@
 */
 
 #if 0
-static int check_channel_list(comedi_device * dev, comedi_subdevice * s,
+static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
 	unsigned int *chanlist, unsigned int n_chan);
 #endif
-static void setup_channel_list(comedi_device * dev, comedi_subdevice * s,
+static void setup_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
 	unsigned int *chanlist, unsigned int n_chan);
-static int icp_multi_reset(comedi_device * dev);
+static int icp_multi_reset(struct comedi_device *dev);
 
 /*
 ==============================================================================
@@ -236,32 +236,32 @@
 		This function reads a single analogue input.
 
 	Parameters:
-		comedi_device *dev	Pointer to current device structure
-		comedi_subdevice *s	Pointer to current subdevice structure
-		comedi_insn *insn	Pointer to current comedi instruction
-		lsampl_t *data		Pointer to analogue input data
+		struct comedi_device *dev	Pointer to current device structure
+		struct comedi_subdevice *s	Pointer to current subdevice structure
+		struct comedi_insn *insn	Pointer to current comedi instruction
+		unsigned int *data		Pointer to analogue input data
 
 	Returns:int			Nmuber of instructions executed
 
 ==============================================================================
 */
-static int icp_multi_insn_read_ai(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data)
+static int icp_multi_insn_read_ai(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data)
 {
 	int n, timeout;
 
 #ifdef ICP_MULTI_EXTDEBUG
 	printk("icp multi EDBG: BGN: icp_multi_insn_read_ai(...)\n");
 #endif
-	// Disable A/D conversion ready interrupt
+	/*  Disable A/D conversion ready interrupt */
 	devpriv->IntEnable &= ~ADC_READY;
 	writew(devpriv->IntEnable, devpriv->io_addr + ICP_MULTI_INT_EN);
 
-	// Clear interrupt status
+	/*  Clear interrupt status */
 	devpriv->IntStatus |= ADC_READY;
 	writew(devpriv->IntStatus, devpriv->io_addr + ICP_MULTI_INT_STAT);
 
-	// Set up appropriate channel, mode and range data, for specified channel
+	/*  Set up appropriate channel, mode and range data, for specified channel */
 	setup_channel_list(dev, s, &insn->chanspec, 1);
 
 #ifdef ICP_MULTI_EXTDEBUG
@@ -271,7 +271,7 @@
 #endif
 
 	for (n = 0; n < insn->n; n++) {
-		// Set start ADC bit
+		/*  Set start ADC bit */
 		devpriv->AdcCmdStatus |= ADC_ST;
 		writew(devpriv->AdcCmdStatus,
 			devpriv->io_addr + ICP_MULTI_ADC_CSR);
@@ -289,7 +289,7 @@
 			readw(devpriv->io_addr + ICP_MULTI_ADC_CSR));
 #endif
 
-		// Wait for conversion to complete, or get fed up waiting
+		/*  Wait for conversion to complete, or get fed up waiting */
 		timeout = 100;
 		while (timeout--) {
 			if (!(readw(devpriv->io_addr +
@@ -307,19 +307,19 @@
 			comedi_udelay(1);
 		}
 
-		// If we reach here, a timeout has occurred
+		/*  If we reach here, a timeout has occurred */
 		comedi_error(dev, "A/D insn timeout");
 
-		// Disable interrupt
+		/*  Disable interrupt */
 		devpriv->IntEnable &= ~ADC_READY;
 		writew(devpriv->IntEnable, devpriv->io_addr + ICP_MULTI_INT_EN);
 
-		// Clear interrupt status
+		/*  Clear interrupt status */
 		devpriv->IntStatus |= ADC_READY;
 		writew(devpriv->IntStatus,
 			devpriv->io_addr + ICP_MULTI_INT_STAT);
 
-		// Clear data received
+		/*  Clear data received */
 		data[n] = 0;
 
 #ifdef ICP_MULTI_EXTDEBUG
@@ -332,11 +332,11 @@
 			(readw(devpriv->io_addr + ICP_MULTI_AI) >> 4) & 0x0fff;
 	}
 
-	// Disable interrupt
+	/*  Disable interrupt */
 	devpriv->IntEnable &= ~ADC_READY;
 	writew(devpriv->IntEnable, devpriv->io_addr + ICP_MULTI_INT_EN);
 
-	// Clear interrupt status
+	/*  Clear interrupt status */
 	devpriv->IntStatus |= ADC_READY;
 	writew(devpriv->IntStatus, devpriv->io_addr + ICP_MULTI_INT_STAT);
 
@@ -355,40 +355,40 @@
 		This function writes a single analogue output.
 
 	Parameters:
-		comedi_device *dev	Pointer to current device structure
-		comedi_subdevice *s	Pointer to current subdevice structure
-		comedi_insn *insn	Pointer to current comedi instruction
-		lsampl_t *data		Pointer to analogue output data
+		struct comedi_device *dev	Pointer to current device structure
+		struct comedi_subdevice *s	Pointer to current subdevice structure
+		struct comedi_insn *insn	Pointer to current comedi instruction
+		unsigned int *data		Pointer to analogue output data
 
 	Returns:int			Nmuber of instructions executed
 
 ==============================================================================
 */
-static int icp_multi_insn_write_ao(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data)
+static int icp_multi_insn_write_ao(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data)
 {
 	int n, chan, range, timeout;
 
 #ifdef ICP_MULTI_EXTDEBUG
 	printk("icp multi EDBG: BGN: icp_multi_insn_write_ao(...)\n");
 #endif
-	// Disable D/A conversion ready interrupt
+	/*  Disable D/A conversion ready interrupt */
 	devpriv->IntEnable &= ~DAC_READY;
 	writew(devpriv->IntEnable, devpriv->io_addr + ICP_MULTI_INT_EN);
 
-	// Clear interrupt status
+	/*  Clear interrupt status */
 	devpriv->IntStatus |= DAC_READY;
 	writew(devpriv->IntStatus, devpriv->io_addr + ICP_MULTI_INT_STAT);
 
-	// Get channel number and range
+	/*  Get channel number and range */
 	chan = CR_CHAN(insn->chanspec);
 	range = CR_RANGE(insn->chanspec);
 
-	// Set up range and channel data
-	// Bit 4 = 1 : Bipolar
-	// Bit 5 = 0 : 5V
-	// Bit 5 = 1 : 10V
-	// Bits 8-9 : Channel number
+	/*  Set up range and channel data */
+	/*  Bit 4 = 1 : Bipolar */
+	/*  Bit 5 = 0 : 5V */
+	/*  Bit 5 = 1 : 10V */
+	/*  Bits 8-9 : Channel number */
 	devpriv->DacCmdStatus &= 0xfccf;
 	devpriv->DacCmdStatus |= this_board->rangecode[range];
 	devpriv->DacCmdStatus |= (chan << 8);
@@ -396,7 +396,7 @@
 	writew(devpriv->DacCmdStatus, devpriv->io_addr + ICP_MULTI_DAC_CSR);
 
 	for (n = 0; n < insn->n; n++) {
-		// Wait for analogue output data register to be ready for new data, or get fed up waiting
+		/*  Wait for analogue output data register to be ready for new data, or get fed up waiting */
 		timeout = 100;
 		while (timeout--) {
 			if (!(readw(devpriv->io_addr +
@@ -414,19 +414,19 @@
 			comedi_udelay(1);
 		}
 
-		// If we reach here, a timeout has occurred
+		/*  If we reach here, a timeout has occurred */
 		comedi_error(dev, "D/A insn timeout");
 
-		// Disable interrupt
+		/*  Disable interrupt */
 		devpriv->IntEnable &= ~DAC_READY;
 		writew(devpriv->IntEnable, devpriv->io_addr + ICP_MULTI_INT_EN);
 
-		// Clear interrupt status
+		/*  Clear interrupt status */
 		devpriv->IntStatus |= DAC_READY;
 		writew(devpriv->IntStatus,
 			devpriv->io_addr + ICP_MULTI_INT_STAT);
 
-		// Clear data received
+		/*  Clear data received */
 		devpriv->ao_data[chan] = 0;
 
 #ifdef ICP_MULTI_EXTDEBUG
@@ -435,16 +435,16 @@
 		return -ETIME;
 
 	      dac_ready:
-		// Write data to analogue output data register
+		/*  Write data to analogue output data register */
 		writew(data[n], devpriv->io_addr + ICP_MULTI_AO);
 
-		// Set DAC_ST bit to write the data to selected channel
+		/*  Set DAC_ST bit to write the data to selected channel */
 		devpriv->DacCmdStatus |= DAC_ST;
 		writew(devpriv->DacCmdStatus,
 			devpriv->io_addr + ICP_MULTI_DAC_CSR);
 		devpriv->DacCmdStatus &= ~DAC_ST;
 
-		// Save analogue output data
+		/*  Save analogue output data */
 		devpriv->ao_data[chan] = data[n];
 	}
 
@@ -463,24 +463,24 @@
 		This function reads a single analogue output.
 
 	Parameters:
-		comedi_device *dev	Pointer to current device structure
-		comedi_subdevice *s	Pointer to current subdevice structure
-		comedi_insn *insn	Pointer to current comedi instruction
-		lsampl_t *data		Pointer to analogue output data
+		struct comedi_device *dev	Pointer to current device structure
+		struct comedi_subdevice *s	Pointer to current subdevice structure
+		struct comedi_insn *insn	Pointer to current comedi instruction
+		unsigned int *data		Pointer to analogue output data
 
 	Returns:int			Nmuber of instructions executed
 
 ==============================================================================
 */
-static int icp_multi_insn_read_ao(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data)
+static int icp_multi_insn_read_ao(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data)
 {
 	int n, chan;
 
-	// Get channel number
+	/*  Get channel number */
 	chan = CR_CHAN(insn->chanspec);
 
-	// Read analogue outputs
+	/*  Read analogue outputs */
 	for (n = 0; n < insn->n; n++)
 		data[n] = devpriv->ao_data[chan];
 
@@ -496,17 +496,17 @@
 		This function reads the digital inputs.
 
 	Parameters:
-		comedi_device *dev	Pointer to current device structure
-		comedi_subdevice *s	Pointer to current subdevice structure
-		comedi_insn *insn	Pointer to current comedi instruction
-		lsampl_t *data		Pointer to analogue output data
+		struct comedi_device *dev	Pointer to current device structure
+		struct comedi_subdevice *s	Pointer to current subdevice structure
+		struct comedi_insn *insn	Pointer to current comedi instruction
+		unsigned int *data		Pointer to analogue output data
 
 	Returns:int			Nmuber of instructions executed
 
 ==============================================================================
 */
-static int icp_multi_insn_bits_di(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data)
+static int icp_multi_insn_bits_di(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data)
 {
 	data[1] = readw(devpriv->io_addr + ICP_MULTI_DI);
 
@@ -522,17 +522,17 @@
 		This function writes the appropriate digital outputs.
 
 	Parameters:
-		comedi_device *dev	Pointer to current device structure
-		comedi_subdevice *s	Pointer to current subdevice structure
-		comedi_insn *insn	Pointer to current comedi instruction
-		lsampl_t *data		Pointer to analogue output data
+		struct comedi_device *dev	Pointer to current device structure
+		struct comedi_subdevice *s	Pointer to current subdevice structure
+		struct comedi_insn *insn	Pointer to current comedi instruction
+		unsigned int *data		Pointer to analogue output data
 
 	Returns:int			Nmuber of instructions executed
 
 ==============================================================================
 */
-static int icp_multi_insn_bits_do(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data)
+static int icp_multi_insn_bits_do(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data)
 {
 #ifdef ICP_MULTI_EXTDEBUG
 	printk("icp multi EDBG: BGN: icp_multi_insn_bits_do(...)\n");
@@ -564,17 +564,17 @@
 		This function reads the specified counter.
 
 	Parameters:
-		comedi_device *dev	Pointer to current device structure
-		comedi_subdevice *s	Pointer to current subdevice structure
-		comedi_insn *insn	Pointer to current comedi instruction
-		lsampl_t *data		Pointer to counter data
+		struct comedi_device *dev	Pointer to current device structure
+		struct comedi_subdevice *s	Pointer to current subdevice structure
+		struct comedi_insn *insn	Pointer to current comedi instruction
+		unsigned int *data		Pointer to counter data
 
 	Returns:int			Nmuber of instructions executed
 
 ==============================================================================
 */
-static int icp_multi_insn_read_ctr(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data)
+static int icp_multi_insn_read_ctr(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data)
 {
 	return 0;
 }
@@ -588,17 +588,17 @@
 		This function write to the specified counter.
 
 	Parameters:
-		comedi_device *dev	Pointer to current device structure
-		comedi_subdevice *s	Pointer to current subdevice structure
-		comedi_insn *insn	Pointer to current comedi instruction
-		lsampl_t *data		Pointer to counter data
+		struct comedi_device *dev	Pointer to current device structure
+		struct comedi_subdevice *s	Pointer to current subdevice structure
+		struct comedi_insn *insn	Pointer to current comedi instruction
+		unsigned int *data		Pointer to counter data
 
 	Returns:int			Nmuber of instructions executed
 
 ==============================================================================
 */
-static int icp_multi_insn_write_ctr(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data)
+static int icp_multi_insn_write_ctr(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data)
 {
 	return 0;
 }
@@ -620,7 +620,7 @@
 */
 static irqreturn_t interrupt_service_icp_multi(int irq, void *d PT_REGS_ARG)
 {
-	comedi_device *dev = d;
+	struct comedi_device *dev = d;
 	int int_no;
 
 #ifdef ICP_MULTI_EXTDEBUG
@@ -628,10 +628,10 @@
 		irq);
 #endif
 
-	// Is this interrupt from our board?
+	/*  Is this interrupt from our board? */
 	int_no = readw(devpriv->io_addr + ICP_MULTI_INT_STAT) & Status_IRQ;
 	if (!int_no)
-		// No, exit
+		/*  No, exit */
 		return IRQ_NONE;
 
 #ifdef ICP_MULTI_EXTDEBUG
@@ -639,7 +639,7 @@
 		readw(devpriv->io_addr + ICP_MULTI_INT_STAT));
 #endif
 
-	// Determine which interrupt is active & handle it
+	/*  Determine which interrupt is active & handle it */
 	switch (int_no) {
 	case ADC_READY:
 		break;
@@ -679,8 +679,8 @@
 		is built correctly
 
 	Parameters:
-		comedi_device *dev	Pointer to current sevice structure
-		comedi_subdevice *s	Pointer to current subdevice structure
+		struct comedi_device *dev	Pointer to current sevice structure
+		struct comedi_subdevice *s	Pointer to current subdevice structure
 		unsigned int *chanlist	Pointer to packed channel list
 		unsigned int n_chan	Number of channels to scan
 
@@ -689,7 +689,7 @@
 
 ==============================================================================
 */
-static int check_channel_list(comedi_device * dev, comedi_subdevice * s,
+static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
 	unsigned int *chanlist, unsigned int n_chan)
 {
 	unsigned int i;
@@ -697,14 +697,14 @@
 #ifdef ICP_MULTI_EXTDEBUG
 	printk("icp multi EDBG:  check_channel_list(...,%d)\n", n_chan);
 #endif
-	// Check that we at least have one channel to check
+	/*  Check that we at least have one channel to check */
 	if (n_chan < 1) {
 		comedi_error(dev, "range/channel list is empty!");
 		return 0;
 	}
-	// Check all channels
+	/*  Check all channels */
 	for (i = 0; i < n_chan; i++) {
-		// Check that channel number is < maximum
+		/*  Check that channel number is < maximum */
 		if (CR_AREF(chanlist[i]) == AREF_DIFF) {
 			if (CR_CHAN(chanlist[i]) > this_board->n_aichand) {
 				comedi_error(dev,
@@ -734,8 +734,8 @@
 		Status register.
 
 	Parameters:
-		comedi_device *dev	Pointer to current sevice structure
-		comedi_subdevice *s	Pointer to current subdevice structure
+		struct comedi_device *dev	Pointer to current sevice structure
+		struct comedi_subdevice *s	Pointer to current subdevice structure
 		unsigned int *chanlist	Pointer to packed channel list
 		unsigned int n_chan	Number of channels to scan
 
@@ -743,7 +743,7 @@
 
 ==============================================================================
 */
-static void setup_channel_list(comedi_device * dev, comedi_subdevice * s,
+static void setup_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
 	unsigned int *chanlist, unsigned int n_chan)
 {
 	unsigned int i, range, chanprog;
@@ -756,10 +756,10 @@
 	devpriv->act_chanlist_pos = 0;
 
 	for (i = 0; i < n_chan; i++) {
-		// Get channel
+		/*  Get channel */
 		chanprog = CR_CHAN(chanlist[i]);
 
-		// Determine if it is a differential channel (Bit 15  = 1)
+		/*  Determine if it is a differential channel (Bit 15  = 1) */
 		if (CR_AREF(chanlist[i]) == AREF_DIFF) {
 			diff = 1;
 			chanprog &= 0x0007;
@@ -768,21 +768,21 @@
 			chanprog &= 0x000f;
 		}
 
-		// Clear channel, range and input mode bits in A/D command/status register
+		/*  Clear channel, range and input mode bits in A/D command/status register */
 		devpriv->AdcCmdStatus &= 0xf00f;
 
-		// Set channel number and differential mode status bit
+		/*  Set channel number and differential mode status bit */
 		if (diff) {
-			// Set channel number, bits 9-11 & mode, bit 6
+			/*  Set channel number, bits 9-11 & mode, bit 6 */
 			devpriv->AdcCmdStatus |= (chanprog << 9);
 			devpriv->AdcCmdStatus |= ADC_DI;
 		} else
-			// Set channel number, bits 8-11
+			/*  Set channel number, bits 8-11 */
 			devpriv->AdcCmdStatus |= (chanprog << 8);
 
-		// Get range for current channel
+		/*  Get range for current channel */
 		range = this_board->rangecode[CR_RANGE(chanlist[i])];
-		// Set range. bits 4-5
+		/*  Set range. bits 4-5 */
 		devpriv->AdcCmdStatus |= range;
 
 		/* Output channel, range, mode to ICP Multi */
@@ -806,45 +806,45 @@
 		This function resets the icp multi device to a 'safe' state
 
 	Parameters:
-		comedi_device *dev	Pointer to current sevice structure
+		struct comedi_device *dev	Pointer to current sevice structure
 
 	Returns:int	0 = success
 
 ==============================================================================
 */
-static int icp_multi_reset(comedi_device * dev)
+static int icp_multi_reset(struct comedi_device *dev)
 {
 	unsigned int i;
 
 #ifdef ICP_MULTI_EXTDEBUG
 	printk("icp_multi EDBG: BGN: icp_multi_reset(...)\n");
 #endif
-	// Clear INT enables and requests
+	/*  Clear INT enables and requests */
 	writew(0, devpriv->io_addr + ICP_MULTI_INT_EN);
 	writew(0x00ff, devpriv->io_addr + ICP_MULTI_INT_STAT);
 
 	if (this_board->n_aochan)
-		// Set DACs to 0..5V range and 0V output
+		/*  Set DACs to 0..5V range and 0V output */
 		for (i = 0; i < this_board->n_aochan; i++) {
 			devpriv->DacCmdStatus &= 0xfcce;
 
-			// Set channel number
+			/*  Set channel number */
 			devpriv->DacCmdStatus |= (i << 8);
 
-			// Output 0V
+			/*  Output 0V */
 			writew(0, devpriv->io_addr + ICP_MULTI_AO);
 
-			// Set start conversion bit
+			/*  Set start conversion bit */
 			devpriv->DacCmdStatus |= DAC_ST;
 
-			// Output to command / status register
+			/*  Output to command / status register */
 			writew(devpriv->DacCmdStatus,
 				devpriv->io_addr + ICP_MULTI_DAC_CSR);
 
-			// Delay to allow DAC time to recover
+			/*  Delay to allow DAC time to recover */
 			comedi_udelay(1);
 		}
-	// Digital outputs to 0
+	/*  Digital outputs to 0 */
 	writew(0, devpriv->io_addr + ICP_MULTI_DO);
 
 #ifdef ICP_MULTI_EXTDEBUG
@@ -863,16 +863,16 @@
 		device.
 
 	Parameters:
-		comedi_device *dev	Pointer to current device structure
-		comedi_devconfig *it	Pointer to current device configuration
+		struct comedi_device *dev	Pointer to current device structure
+		struct comedi_devconfig *it	Pointer to current device configuration
 
 	Returns:int	0 = success
 
 ==============================================================================
 */
-static int icp_multi_attach(comedi_device * dev, comedi_devconfig * it)
+static int icp_multi_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
-	comedi_subdevice *s;
+	struct comedi_subdevice *s;
 	int ret, subdev, n_subdevices;
 	unsigned int irq;
 	struct pcilst_struct *card = NULL;
@@ -881,11 +881,12 @@
 
 	printk("icp_multi EDBG: BGN: icp_multi_attach(...)\n");
 
-	// Alocate private data storage space
-	if ((ret = alloc_private(dev, sizeof(icp_multi_private))) < 0)
+	/*  Alocate private data storage space */
+	ret = alloc_private(dev, sizeof(struct icp_multi_private));
+	if (ret < 0)
 		return ret;
 
-	// Initialise list of PCI cards in system, if not already done so
+	/*  Initialise list of PCI cards in system, if not already done so */
 	if (pci_list_builded++ == 0) {
 		pci_card_list_init(PCI_VENDOR_ID_ICP,
 #ifdef ICP_MULTI_EXTDEBUG
@@ -899,9 +900,11 @@
 	printk("Anne's comedi%d: icp_multi: board=%s", dev->minor,
 		this_board->name);
 
-	if ((card = select_and_alloc_pci_card(PCI_VENDOR_ID_ICP,
-				this_board->device_id, it->options[0],
-				it->options[1])) == NULL)
+	card = select_and_alloc_pci_card(PCI_VENDOR_ID_ICP,
+					 this_board->device_id, it->options[0],
+					 it->options[1]);
+
+	if (card == NULL)
 		return -EIO;
 
 	devpriv->card = card;
@@ -943,9 +946,9 @@
 	if (this_board->n_ctrs)
 		n_subdevices++;
 
-	if ((ret = alloc_subdevices(dev, n_subdevices)) < 0) {
+	ret = alloc_subdevices(dev, n_subdevices);
+	if (ret < 0)
 		return ret;
-	}
 
 	icp_multi_reset(dev);
 
@@ -1055,13 +1058,13 @@
 		device.
 
 	Parameters:
-		comedi_device *dev	Pointer to current device structure
+		struct comedi_device *dev	Pointer to current device structure
 
 	Returns:int	0 = success
 
 ==============================================================================
 */
-static int icp_multi_detach(comedi_device * dev)
+static int icp_multi_detach(struct comedi_device *dev)
 {
 
 	if (dev->private)
@@ -1077,9 +1080,8 @@
 	if (dev->private && devpriv->card)
 		pci_card_free(devpriv->card);
 
-	if (--pci_list_builded == 0) {
+	if (--pci_list_builded == 0)
 		pci_card_list_cleanup(PCI_VENDOR_ID_ICP);
-	}
 
 	return 0;
 }
diff --git a/drivers/staging/comedi/drivers/icp_multi.h b/drivers/staging/comedi/drivers/icp_multi.h
index 6df4a8d..21d8476 100644
--- a/drivers/staging/comedi/drivers/icp_multi.h
+++ b/drivers/staging/comedi/drivers/icp_multi.h
@@ -28,7 +28,8 @@
 	unsigned int irq;
 };
 
-struct pcilst_struct *inova_devices;	// ptr to root list of all Inova devices
+struct pcilst_struct *inova_devices;
+/* ptr to root list of all Inova devices */
 
 /****************************************************************************/
 
@@ -150,14 +151,14 @@
 			&& (inova->pci_slot == pci_slot)) {
 			if (!(inova->used)) {
 				*card = inova;
-				return 0;	// ok, card is found
+				return 0;	/* ok, card is found */
 			} else {
-				return 2;	// card exist but is used
+				return 2;	/* card exist but is used */
 			}
 		}
 	}
 
-	return 1;		// no card found
+	return 1;		/* no card found */
 }
 
 /****************************************************************************/
@@ -243,9 +244,10 @@
 	struct pcilst_struct *card;
 	int err;
 
-	if ((pci_bus < 1) & (pci_slot < 1)) {	// use autodetection
-		if ((card = find_free_pci_card_by_device(vendor_id,
-					device_id)) == NULL) {
+	if ((pci_bus < 1) & (pci_slot < 1)) {	/* use autodetection */
+
+		card = find_free_pci_card_by_device(vendor_id, device_id);
+		if (card == NULL) {
 			rt_printk(" - Unused card not found in system!\n");
 			return NULL;
 		}
@@ -265,7 +267,8 @@
 		}
 	}
 
-	if ((err = pci_card_alloc(card)) != 0) {
+	err = pci_card_alloc(card);
+	if (err != 0) {
 		if (err > 0)
 			rt_printk(" - Can't allocate card!\n");
 		/* else: error already printed. */
diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c
new file mode 100644
index 0000000..80825ba
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ii_pci20kc.c
@@ -0,0 +1,612 @@
+/*
+ *	comedi/drivers/ii_pci20kc.c
+ *	Driver for Intelligent Instruments PCI-20001C carrier board
+ *	and modules.
+ *
+ *	Copyright (C) 2000 Markus Kempf <kempf@matsci.uni-sb.de>
+ *	with suggestions from David Schleef
+ *			16.06.2000
+ *
+ *	Linux device driver for COMEDI
+ *	Intelligent Instrumentation
+ *	PCI-20001 C-2A Carrier Board
+ *	PCI-20341 M-1A 16-Bit analog input module
+ *				- differential
+ *				- range (-5V - +5V)
+ *				- 16 bit
+ *	PCI-20006 M-2 16-Bit analog output module
+ *				- ranges (-10V - +10V) (0V - +10V) (-5V - +5V)
+ *				- 16 bit
+ *
+ *	only ONE PCI-20341 module possible
+ * 	only ONE PCI-20006 module possible
+ *	no extern trigger implemented
+ *
+ *	NOT WORKING (but soon) only 4 on-board differential channels supported
+ *	NOT WORKING (but soon) only ONE di-port and ONE do-port supported instead of 4 digital ports
+ *	di-port == Port 0
+ *	do-port == Port 1
+ *
+ *	The state of this driver is only a starting point for a complete
+ *	COMEDI-driver. The final driver should support all features of the
+ *	carrier board and modules.
+ *
+ *	The test configuration:
+ *
+ *	kernel 2.2.14 with RTAI v1.2  and patch-2.2.14rthal2
+ *	COMEDI 0.7.45
+ *	COMEDILIB 0.7.9
+ *
+ */
+/*
+Driver: ii_pci20kc
+Description: Intelligent Instruments PCI-20001C carrier board
+Author: Markus Kempf <kempf@matsci.uni-sb.de>
+Devices: [Intelligent Instrumentation] PCI-20001C (ii_pci20kc)
+Status: works
+
+Supports the PCI-20001 C-2a Carrier board, and could probably support
+the other carrier boards with small modifications.  Modules supported
+are:
+	PCI-20006 M-2 16-bit analog output module
+	PCI-20341 M-1A 16-bit analog input module
+
+Options:
+  0   Board base address
+  1   IRQ
+  2   first option for module 1
+  3   second option for module 1
+  4   first option for module 2
+  5   second option for module 2
+  6   first option for module 3
+  7   second option for module 3
+
+options for PCI-20006M:
+  first:   Analog output channel 0 range configuration
+             0  bipolar 10  (-10V -- +10V)
+             1  unipolar 10  (0V -- +10V)
+             2  bipolar 5  (-5V -- 5V)
+  second:  Analog output channel 1 range configuration
+
+options for PCI-20341M:
+  first:   Analog input gain configuration
+             0  1
+             1  10
+             2  100
+             3  200
+*/
+
+/* XXX needs to use ioremap() for compatibility with 2.4 kernels.  Should also
+ * check_mem_region() etc. - fmhess */
+
+#include "../comedidev.h"
+
+#define PCI20000_ID			0x1d
+#define PCI20341_ID    			0x77
+#define PCI20006_ID      		0xe3
+#define PCI20xxx_EMPTY_ID		0xff
+
+#define PCI20000_OFFSET 		0x100
+#define PCI20000_MODULES		3
+
+#define PCI20000_DIO_0			0x80
+#define PCI20000_DIO_1			0x81
+#define PCI20000_DIO_2			0xc0
+#define PCI20000_DIO_3			0xc1
+#define PCI20000_DIO_CONTROL_01		0x83	/* port 0, 1 control */
+#define PCI20000_DIO_CONTROL_23		0xc3	/* port 2, 3 control */
+#define PCI20000_DIO_BUFFER		0x82	/* buffer direction and enable */
+#define PCI20000_DIO_EOC		0xef	/* even port, control output */
+#define PCI20000_DIO_OOC		0xfd	/* odd port, control output */
+#define PCI20000_DIO_EIC		0x90	/* even port, control input */
+#define PCI20000_DIO_OIC		0x82	/* odd port, control input */
+#define DIO_CAND			0x12	/* and bit 1, bit 4 of control */
+#define DIO_BE				0x01	/* buffer: port enable */
+#define DIO_BO				0x04	/* buffer: output */
+#define DIO_BI				0x05	/* buffer: input */
+#define DIO_PS_0			0x00	/* buffer: port shift 0 */
+#define DIO_PS_1			0x01	/* buffer: port shift 1 */
+#define DIO_PS_2			0x04	/* buffer: port shift 2 */
+#define DIO_PS_3			0x05	/* buffer: port shift 3 */
+
+#define PCI20006_LCHAN0			0x0d
+#define PCI20006_STROBE0		0x0b
+#define PCI20006_LCHAN1			0x15
+#define PCI20006_STROBE1		0x13
+
+#define PCI20341_INIT			0x04
+#define PCI20341_REPMODE		0x00	/* single shot mode */
+#define PCI20341_PACER			0x00	/* Hardware Pacer disabled */
+#define PCI20341_CHAN_NR		0x04	/* number of input channels */
+#define PCI20341_CONFIG_REG		0x10
+#define PCI20341_MOD_STATUS		0x01
+#define PCI20341_OPT_REG		0x11
+#define PCI20341_SET_TIME_REG		0x15
+#define PCI20341_LCHAN_ADDR_REG		0x13
+#define PCI20341_CHAN_LIST		0x80
+#define PCI20341_CC_RESET		0x1b
+#define PCI20341_CHAN_RESET		0x19
+#define PCI20341_SOFT_PACER		0x04
+#define PCI20341_STATUS_REG		0x12
+#define PCI20341_LDATA			0x02
+#define PCI20341_DAISY_CHAIN		0x20	/* On-board inputs only */
+#define PCI20341_MUX			0x04	/* Enable on-board MUX */
+#define PCI20341_SCANLIST		0x80	/* Channel/Gain Scan List */
+
+union pci20xxx_subdev_private {
+	void *iobase;
+	struct {
+		void *iobase;
+		const struct comedi_lrange *ao_range_list[2];	/* range of channels of ao module */
+		unsigned int last_data[2];
+	} pci20006;
+	struct {
+		void *iobase;
+		int timebase;
+		int settling_time;
+		int ai_gain;
+	} pci20341;
+};
+
+struct pci20xxx_private {
+
+	void *ioaddr;
+	union pci20xxx_subdev_private subdev_private[PCI20000_MODULES];
+};
+
+
+#define devpriv ((struct pci20xxx_private *)dev->private)
+#define CHAN (CR_CHAN(it->chanlist[0]))
+
+static int pci20xxx_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci20xxx_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver_pci20xxx = {
+      driver_name:"ii_pci20kc",
+      module:THIS_MODULE,
+      attach:pci20xxx_attach,
+      detach:pci20xxx_detach,
+};
+
+static int pci20006_init(struct comedi_device * dev, struct comedi_subdevice * s,
+	int opt0, int opt1);
+static int pci20341_init(struct comedi_device * dev, struct comedi_subdevice * s,
+	int opt0, int opt1);
+static int pci20xxx_dio_init(struct comedi_device * dev, struct comedi_subdevice * s);
+
+/*
+  options[0]	Board base address
+  options[1]	IRQ
+  options[2]	first option for module 1
+  options[3]	second option for module 1
+  options[4]	first option for module 2
+  options[5]	second option for module 2
+  options[6]	first option for module 3
+  options[7]	second option for module 3
+
+  options for PCI-20341M:
+  first		Analog input gain configuration
+		0 == 1
+		1 == 10
+		2 == 100
+		3 == 200
+
+  options for PCI-20006M:
+  first		Analog output channel 0 range configuration
+		0 == bipolar 10  (-10V -- +10V)
+		1 == unipolar 10V  (0V -- +10V)
+		2 == bipolar 5V  (-5V -- +5V)
+  second	Analog output channel 1 range configuration
+		0 == bipolar 10  (-10V -- +10V)
+		1 == unipolar 10V  (0V -- +10V)
+		2 == bipolar 5V  (-5V -- +5V)
+*/
+static int pci20xxx_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	unsigned char i;
+	int ret;
+	int id;
+	struct comedi_subdevice *s;
+	union pci20xxx_subdev_private *sdp;
+
+	if ((ret = alloc_subdevices(dev, 1 + PCI20000_MODULES)) < 0)
+		return ret;
+	if ((ret = alloc_private(dev, sizeof(struct pci20xxx_private))) < 0)
+		return ret;
+
+	devpriv->ioaddr = (void *)(unsigned long)it->options[0];
+	dev->board_name = "pci20kc";
+
+	/* Check PCI-20001 C-2A Carrier Board ID */
+	if ((readb(devpriv->ioaddr) & PCI20000_ID) != PCI20000_ID) {
+		printk("comedi%d: ii_pci20kc", dev->minor);
+		printk(" PCI-20001 C-2A Carrier Board at base=0x%p not found !\n", devpriv->ioaddr);
+		return -EINVAL;
+	}
+	printk("comedi%d:\n", dev->minor);
+	printk("ii_pci20kc: PCI-20001 C-2A at base=0x%p\n", devpriv->ioaddr);
+
+	for (i = 0; i < PCI20000_MODULES; i++) {
+		s = dev->subdevices + i;
+		id = readb(devpriv->ioaddr + (i + 1) * PCI20000_OFFSET);
+		s->private = devpriv->subdev_private + i;
+		sdp = s->private;
+		switch (id) {
+		case PCI20006_ID:
+			sdp->pci20006.iobase =
+				devpriv->ioaddr + (i + 1) * PCI20000_OFFSET;
+			pci20006_init(dev, s, it->options[2 * i + 2],
+				it->options[2 * i + 3]);
+			printk("comedi%d: ii_pci20kc", dev->minor);
+			printk(" PCI-20006 module in slot %d \n", i + 1);
+			break;
+		case PCI20341_ID:
+			sdp->pci20341.iobase =
+				devpriv->ioaddr + (i + 1) * PCI20000_OFFSET;
+			pci20341_init(dev, s, it->options[2 * i + 2],
+				it->options[2 * i + 3]);
+			printk("comedi%d: ii_pci20kc", dev->minor);
+			printk(" PCI-20341 module in slot %d \n", i + 1);
+			break;
+		default:
+			printk("ii_pci20kc: unknown module code 0x%02x in slot %d: module disabled\n", id, i);
+			/* fall through */
+		case PCI20xxx_EMPTY_ID:
+			s->type = COMEDI_SUBD_UNUSED;
+			break;
+		}
+	}
+
+	/* initialize struct pci20xxx_private */
+	pci20xxx_dio_init(dev, dev->subdevices + PCI20000_MODULES);
+
+	return 1;
+}
+
+static int pci20xxx_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: pci20xxx: remove\n", dev->minor);
+
+	return 0;
+}
+
+/* pci20006m */
+
+static int pci20006_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int pci20006_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+static const struct comedi_lrange *pci20006_range_list[] = {
+	&range_bipolar10,
+	&range_unipolar10,
+	&range_bipolar5,
+};
+
+static int pci20006_init(struct comedi_device * dev, struct comedi_subdevice * s,
+	int opt0, int opt1)
+{
+	union pci20xxx_subdev_private *sdp = s->private;
+
+	if (opt0 < 0 || opt0 > 2)
+		opt0 = 0;
+	if (opt1 < 0 || opt1 > 2)
+		opt1 = 0;
+
+	sdp->pci20006.ao_range_list[0] = pci20006_range_list[opt0];
+	sdp->pci20006.ao_range_list[1] = pci20006_range_list[opt1];
+
+	/* ao subdevice */
+	s->type = COMEDI_SUBD_AO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->n_chan = 2;
+	s->len_chanlist = 2;
+	s->insn_read = pci20006_insn_read;
+	s->insn_write = pci20006_insn_write;
+	s->maxdata = 0xffff;
+	s->range_table_list = sdp->pci20006.ao_range_list;
+	return 0;
+}
+
+static int pci20006_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	union pci20xxx_subdev_private *sdp = s->private;
+
+	data[0] = sdp->pci20006.last_data[CR_CHAN(insn->chanspec)];
+
+	return 1;
+}
+
+static int pci20006_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	union pci20xxx_subdev_private *sdp = s->private;
+	int hi, lo;
+	unsigned int boarddata;
+
+	sdp->pci20006.last_data[CR_CHAN(insn->chanspec)] = data[0];
+	boarddata = (((unsigned int)data[0] + 0x8000) & 0xffff);	/* comedi-data -> board-data */
+	lo = (boarddata & 0xff);
+	hi = ((boarddata >> 8) & 0xff);
+
+	switch (CR_CHAN(insn->chanspec)) {
+	case 0:
+		writeb(lo, sdp->iobase + PCI20006_LCHAN0);
+		writeb(hi, sdp->iobase + PCI20006_LCHAN0 + 1);
+		writeb(0x00, sdp->iobase + PCI20006_STROBE0);
+		break;
+	case 1:
+		writeb(lo, sdp->iobase + PCI20006_LCHAN1);
+		writeb(hi, sdp->iobase + PCI20006_LCHAN1 + 1);
+		writeb(0x00, sdp->iobase + PCI20006_STROBE1);
+		break;
+	default:
+		printk(" comedi%d: pci20xxx: ao channel Error!\n", dev->minor);
+		return -EINVAL;
+	}
+
+	return 1;
+}
+
+/* PCI20341M */
+
+static int pci20341_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+static const int pci20341_timebase[] = { 0x00, 0x00, 0x00, 0x04 };
+static const int pci20341_settling_time[] = { 0x58, 0x58, 0x93, 0x99 };
+
+static const struct comedi_lrange range_bipolar0_5 = { 1, {BIP_RANGE(0.5)} };
+static const struct comedi_lrange range_bipolar0_05 = { 1, {BIP_RANGE(0.05)} };
+static const struct comedi_lrange range_bipolar0_025 = { 1, {BIP_RANGE(0.025)} };
+
+static const struct comedi_lrange *const pci20341_ranges[] = {
+	&range_bipolar5,
+	&range_bipolar0_5,
+	&range_bipolar0_05,
+	&range_bipolar0_025,
+};
+
+static int pci20341_init(struct comedi_device * dev, struct comedi_subdevice * s,
+	int opt0, int opt1)
+{
+	union pci20xxx_subdev_private *sdp = s->private;
+	int option;
+
+	/* options handling */
+	if (opt0 < 0 || opt0 > 3)
+		opt0 = 0;
+	sdp->pci20341.timebase = pci20341_timebase[opt0];
+	sdp->pci20341.settling_time = pci20341_settling_time[opt0];
+
+	/* ai subdevice */
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE;
+	s->n_chan = PCI20341_CHAN_NR;
+	s->len_chanlist = PCI20341_SCANLIST;
+	s->insn_read = pci20341_insn_read;
+	s->maxdata = 0xffff;
+	s->range_table = pci20341_ranges[opt0];
+
+	option = sdp->pci20341.timebase | PCI20341_REPMODE;	/* depends on gain, trigger, repetition mode */
+
+	writeb(PCI20341_INIT, sdp->iobase + PCI20341_CONFIG_REG);	/* initialize Module */
+	writeb(PCI20341_PACER, sdp->iobase + PCI20341_MOD_STATUS);	/* set Pacer */
+	writeb(option, sdp->iobase + PCI20341_OPT_REG);	/* option register */
+	writeb(sdp->pci20341.settling_time, sdp->iobase + PCI20341_SET_TIME_REG);	/* settling time counter */
+	/* trigger not implemented */
+	return 0;
+}
+
+static int pci20341_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+        union pci20xxx_subdev_private *sdp = s->private;
+	unsigned int i = 0, j = 0;
+	int lo, hi;
+	unsigned char eoc;	/* end of conversion */
+	unsigned int clb;	/* channel list byte */
+	unsigned int boarddata;
+
+	writeb(1, sdp->iobase + PCI20341_LCHAN_ADDR_REG);	/* write number of input channels */
+	clb = PCI20341_DAISY_CHAIN | PCI20341_MUX | (sdp->pci20341.ai_gain << 3)
+		| CR_CHAN(insn->chanspec);
+	writeb(clb, sdp->iobase + PCI20341_CHAN_LIST);
+	writeb(0x00, sdp->iobase + PCI20341_CC_RESET);	/* reset settling time counter and trigger delay counter */
+	writeb(0x00, sdp->iobase + PCI20341_CHAN_RESET);
+
+	/* generate Pacer */
+
+	for (i = 0; i < insn->n; i++) {
+		/* data polling isn't the niciest way to get the data, I know,
+		 * but there are only 6 cycles (mean) and it is easier than
+		 * the whole interrupt stuff
+		 */
+		j = 0;
+		readb(sdp->iobase + PCI20341_SOFT_PACER);	/* generate Pacer */
+		eoc = readb(sdp->iobase + PCI20341_STATUS_REG);
+		while ((eoc < 0x80) && j < 100) {	/* poll Interrupt Flag */
+			j++;
+			eoc = readb(sdp->iobase + PCI20341_STATUS_REG);
+		}
+		if (j >= 100) {
+			printk("comedi%d:  pci20xxx: AI interrupt channel %i polling exit !\n", dev->minor, i);
+			return -EINVAL;
+		}
+		lo = readb(sdp->iobase + PCI20341_LDATA);
+		hi = readb(sdp->iobase + PCI20341_LDATA + 1);
+		boarddata = lo + 0x100 * hi;
+		data[i] = (short) ((boarddata + 0x8000) & 0xffff);	/* board-data -> comedi-data */
+	}
+
+	return i;
+}
+
+/* native DIO */
+
+static void pci20xxx_dio_config(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pci20xxx_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int pci20xxx_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+/* initialize struct pci20xxx_private */
+static int pci20xxx_dio_init(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+
+	s->type = COMEDI_SUBD_DIO;
+	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+	s->n_chan = 32;
+	s->insn_bits = pci20xxx_dio_insn_bits;
+	s->insn_config = pci20xxx_dio_insn_config;
+	s->maxdata = 1;
+	s->len_chanlist = 32;
+	s->range_table = &range_digital;
+	s->io_bits = 0;
+
+	/* digital I/O lines default to input on board reset. */
+	pci20xxx_dio_config(dev, s);
+
+	return 0;
+}
+
+static int pci20xxx_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int mask, bits;
+
+	mask = 1 << CR_CHAN(insn->chanspec);
+	if (mask & 0x000000ff) {
+		bits = 0x000000ff;
+	} else if (mask & 0x0000ff00) {
+		bits = 0x0000ff00;
+	} else if (mask & 0x00ff0000) {
+		bits = 0x00ff0000;
+	} else {
+		bits = 0xff000000;
+	}
+	if (data[0]) {
+		s->io_bits |= bits;
+	} else {
+		s->io_bits &= ~bits;
+	}
+	pci20xxx_dio_config(dev, s);
+
+	return 1;
+}
+
+static int pci20xxx_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int mask = data[0];
+
+	s->state &= ~mask;
+	s->state |= (mask & data[1]);
+
+	mask &= s->io_bits;
+	if (mask & 0x000000ff)
+		writeb((s->state >> 0) & 0xff,
+			devpriv->ioaddr + PCI20000_DIO_0);
+	if (mask & 0x0000ff00)
+		writeb((s->state >> 8) & 0xff,
+			devpriv->ioaddr + PCI20000_DIO_1);
+	if (mask & 0x00ff0000)
+		writeb((s->state >> 16) & 0xff,
+			devpriv->ioaddr + PCI20000_DIO_2);
+	if (mask & 0xff000000)
+		writeb((s->state >> 24) & 0xff,
+			devpriv->ioaddr + PCI20000_DIO_3);
+
+	data[1] = readb(devpriv->ioaddr + PCI20000_DIO_0);
+	data[1] |= readb(devpriv->ioaddr + PCI20000_DIO_1) << 8;
+	data[1] |= readb(devpriv->ioaddr + PCI20000_DIO_2) << 16;
+	data[1] |= readb(devpriv->ioaddr + PCI20000_DIO_3) << 24;
+
+	return 2;
+}
+
+static void pci20xxx_dio_config(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	unsigned char control_01;
+	unsigned char control_23;
+	unsigned char buffer;
+
+	control_01 = readb(devpriv->ioaddr + PCI20000_DIO_CONTROL_01);
+	control_23 = readb(devpriv->ioaddr + PCI20000_DIO_CONTROL_23);
+	buffer = readb(devpriv->ioaddr + PCI20000_DIO_BUFFER);
+
+	if (s->io_bits & 0x000000ff) {
+		/* output port 0 */
+		control_01 &= PCI20000_DIO_EOC;
+		buffer = (buffer & (~(DIO_BE << DIO_PS_0))) | (DIO_BO <<
+			DIO_PS_0);
+	} else {
+		/* input port 0 */
+		control_01 = (control_01 & DIO_CAND) | PCI20000_DIO_EIC;
+		buffer = (buffer & (~(DIO_BI << DIO_PS_0)));
+	}
+	if (s->io_bits & 0x0000ff00) {
+		/* output port 1 */
+		control_01 &= PCI20000_DIO_OOC;
+		buffer = (buffer & (~(DIO_BE << DIO_PS_1))) | (DIO_BO <<
+			DIO_PS_1);
+	} else {
+		/* input port 1 */
+		control_01 = (control_01 & DIO_CAND) | PCI20000_DIO_OIC;
+		buffer = (buffer & (~(DIO_BI << DIO_PS_1)));
+	}
+	if (s->io_bits & 0x00ff0000) {
+		/* output port 2 */
+		control_23 &= PCI20000_DIO_EOC;
+		buffer = (buffer & (~(DIO_BE << DIO_PS_2))) | (DIO_BO <<
+			DIO_PS_2);
+	} else {
+		/* input port 2 */
+		control_23 = (control_23 & DIO_CAND) | PCI20000_DIO_EIC;
+		buffer = (buffer & (~(DIO_BI << DIO_PS_2)));
+	}
+	if (s->io_bits & 0xff000000) {
+		/* output port 3 */
+		control_23 &= PCI20000_DIO_OOC;
+		buffer = (buffer & (~(DIO_BE << DIO_PS_3))) | (DIO_BO <<
+			DIO_PS_3);
+	} else {
+		/* input port 3 */
+		control_23 = (control_23 & DIO_CAND) | PCI20000_DIO_OIC;
+		buffer = (buffer & (~(DIO_BI << DIO_PS_3)));
+	}
+	writeb(control_01, devpriv->ioaddr + PCI20000_DIO_CONTROL_01);
+	writeb(control_23, devpriv->ioaddr + PCI20000_DIO_CONTROL_23);
+	writeb(buffer, devpriv->ioaddr + PCI20000_DIO_BUFFER);
+}
+
+#if 0
+static void pci20xxx_do(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	/* XXX if the channel is configured for input, does this
+	   do bad things? */
+	/* XXX it would be a good idea to only update the registers
+	   that _need_ to be updated.  This requires changes to
+	   comedi, however. */
+	writeb((s->state >> 0) & 0xff, devpriv->ioaddr + PCI20000_DIO_0);
+	writeb((s->state >> 8) & 0xff, devpriv->ioaddr + PCI20000_DIO_1);
+	writeb((s->state >> 16) & 0xff, devpriv->ioaddr + PCI20000_DIO_2);
+	writeb((s->state >> 24) & 0xff, devpriv->ioaddr + PCI20000_DIO_3);
+}
+
+static unsigned int pci20xxx_di(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	/* XXX same note as above */
+	unsigned int bits;
+
+	bits = readb(devpriv->ioaddr + PCI20000_DIO_0);
+	bits |= readb(devpriv->ioaddr + PCI20000_DIO_1) << 8;
+	bits |= readb(devpriv->ioaddr + PCI20000_DIO_2) << 16;
+	bits |= readb(devpriv->ioaddr + PCI20000_DIO_3) << 24;
+
+	return bits;
+}
+#endif
+
+COMEDI_INITCLEANUP(driver_pci20xxx);
diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c
new file mode 100644
index 0000000..a3c887f
--- /dev/null
+++ b/drivers/staging/comedi/drivers/jr3_pci.c
@@ -0,0 +1,976 @@
+/*
+  comedi/drivers/jr3_pci.c
+  hardware driver for JR3/PCI force sensor board
+
+  COMEDI - Linux Control and Measurement Device Interface
+  Copyright (C) 2007 Anders Blomdell <anders.blomdell@control.lth.se>
+
+  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.
+
+*/
+/*
+Driver: jr3_pci
+Description: JR3/PCI force sensor board
+Author: Anders Blomdell <anders.blomdell@control.lth.se>
+Status: works
+Devices: [JR3] PCI force sensor board (jr3_pci)
+
+  The DSP on the board requires initialization code, which can
+  be loaded by placing it in /lib/firmware/comedi.
+  The initialization code should be somewhere on the media you got
+  with your card. One version is available from http://www.comedi.org
+  in the comedi_nonfree_firmware tarball.
+
+  Configuration options:
+  [0] - PCI bus number - if bus number and slot number are 0,
+                         then driver search for first unused card
+  [1] - PCI slot number
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+#include <linux/ctype.h>
+#include <linux/firmware.h>
+#include "comedi_pci.h"
+#include "jr3_pci.h"
+
+/* Hotplug firmware loading stuff */
+
+static void comedi_fw_release(struct device *dev)
+{
+	printk(KERN_DEBUG "firmware_sample_driver: ghost_release\n");
+}
+
+static struct device comedi_fw_device = {
+	.init_name = "comedi",
+	.release = comedi_fw_release
+};
+
+typedef int comedi_firmware_callback(struct comedi_device * dev,
+	const u8 * data, size_t size);
+
+static int comedi_load_firmware(struct comedi_device * dev,
+	char *name, comedi_firmware_callback cb)
+{
+	int result = 0;
+	const struct firmware *fw;
+	char *firmware_path;
+	static const char *prefix = "comedi/";
+
+	firmware_path = kmalloc(strlen(prefix) + strlen(name) + 1, GFP_KERNEL);
+	if (!firmware_path) {
+		result = -ENOMEM;
+	} else {
+		firmware_path[0] = '\0';
+		strcat(firmware_path, prefix);
+		strcat(firmware_path, name);
+		result = device_register(&comedi_fw_device);
+		if (result == 0) {
+			result = request_firmware(&fw, firmware_path,
+				&comedi_fw_device);
+			if (result == 0) {
+				if (!cb) {
+					result = -EINVAL;
+				} else {
+					result = cb(dev, fw->data, fw->size);
+				}
+				release_firmware(fw);
+			}
+			device_unregister(&comedi_fw_device);
+		}
+		kfree(firmware_path);
+	}
+	return result;
+}
+
+#define PCI_VENDOR_ID_JR3 0x1762
+#define PCI_DEVICE_ID_JR3_1_CHANNEL 0x3111
+#define PCI_DEVICE_ID_JR3_2_CHANNEL 0x3112
+#define PCI_DEVICE_ID_JR3_3_CHANNEL 0x3113
+#define PCI_DEVICE_ID_JR3_4_CHANNEL 0x3114
+
+static int jr3_pci_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int jr3_pci_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver_jr3_pci = {
+      driver_name:"jr3_pci",
+      module:THIS_MODULE,
+      attach:jr3_pci_attach,
+      detach:jr3_pci_detach,
+};
+
+static DEFINE_PCI_DEVICE_TABLE(jr3_pci_pci_table) = {
+	{PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_1_CHANNEL,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_2_CHANNEL,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_3_CHANNEL,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_4_CHANNEL,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, jr3_pci_pci_table);
+
+struct jr3_pci_dev_private {
+
+	struct pci_dev *pci_dev;
+	int pci_enabled;
+	volatile struct jr3_t *iobase;
+	int n_channels;
+	struct timer_list timer;
+};
+
+
+struct poll_delay_t {
+
+	int min;
+	int max;
+};
+
+
+struct jr3_pci_subdev_private {
+	volatile struct jr3_channel *channel;
+	unsigned long next_time_min;
+	unsigned long next_time_max;
+	enum { state_jr3_poll,
+		state_jr3_init_wait_for_offset,
+		state_jr3_init_transform_complete,
+		state_jr3_init_set_full_scale_complete,
+		state_jr3_init_use_offset_complete,
+		state_jr3_done
+	} state;
+	int channel_no;
+	int serial_no;
+	int model_no;
+	struct {
+		int length;
+		struct comedi_krange range;
+	} range[9];
+	const struct comedi_lrange *range_table_list[8 * 7 + 2];
+	unsigned int maxdata_list[8 * 7 + 2];
+	u16 errors;
+	int retries;
+};
+
+static struct poll_delay_t poll_delay_min_max(int min, int max)
+{
+	struct poll_delay_t result;
+
+	result.min = min;
+	result.max = max;
+	return result;
+}
+
+static int is_complete(volatile struct jr3_channel *channel)
+{
+	return get_s16(&channel->command_word0) == 0;
+}
+
+struct transform_t {
+	struct {
+		u16 link_type;
+		s16 link_amount;
+	} link[8];
+};
+
+static void set_transforms(volatile struct jr3_channel *channel,
+	struct transform_t transf, short num)
+{
+	int i;
+
+	num &= 0x000f;		// Make sure that 0 <= num <= 15
+	for (i = 0; i < 8; i++) {
+
+		set_u16(&channel->transforms[num].link[i].link_type,
+			transf.link[i].link_type);
+		comedi_udelay(1);
+		set_s16(&channel->transforms[num].link[i].link_amount,
+			transf.link[i].link_amount);
+		comedi_udelay(1);
+		if (transf.link[i].link_type == end_x_form) {
+			break;
+		}
+	}
+}
+
+static void use_transform(volatile struct jr3_channel *channel, short transf_num)
+{
+	set_s16(&channel->command_word0, 0x0500 + (transf_num & 0x000f));
+}
+
+static void use_offset(volatile struct jr3_channel *channel, short offset_num)
+{
+	set_s16(&channel->command_word0, 0x0600 + (offset_num & 0x000f));
+}
+
+static void set_offset(volatile struct jr3_channel *channel)
+{
+	set_s16(&channel->command_word0, 0x0700);
+}
+
+struct six_axis_t {
+	s16 fx;
+	s16 fy;
+	s16 fz;
+	s16 mx;
+	s16 my;
+	s16 mz;
+};
+
+static void set_full_scales(volatile struct jr3_channel *channel,
+	struct six_axis_t full_scale)
+{
+	printk("%d %d %d %d %d %d\n",
+		full_scale.fx,
+		full_scale.fy,
+		full_scale.fz, full_scale.mx, full_scale.my, full_scale.mz);
+	set_s16(&channel->full_scale.fx, full_scale.fx);
+	set_s16(&channel->full_scale.fy, full_scale.fy);
+	set_s16(&channel->full_scale.fz, full_scale.fz);
+	set_s16(&channel->full_scale.mx, full_scale.mx);
+	set_s16(&channel->full_scale.my, full_scale.my);
+	set_s16(&channel->full_scale.mz, full_scale.mz);
+	set_s16(&channel->command_word0, 0x0a00);
+}
+
+static struct six_axis_t get_min_full_scales(volatile struct jr3_channel *channel)
+{
+	struct six_axis_t result;
+	result.fx = get_s16(&channel->min_full_scale.fx);
+	result.fy = get_s16(&channel->min_full_scale.fy);
+	result.fz = get_s16(&channel->min_full_scale.fz);
+	result.mx = get_s16(&channel->min_full_scale.mx);
+	result.my = get_s16(&channel->min_full_scale.my);
+	result.mz = get_s16(&channel->min_full_scale.mz);
+	return result;
+}
+
+static struct six_axis_t get_max_full_scales(volatile struct jr3_channel *channel)
+{
+	struct six_axis_t result;
+	result.fx = get_s16(&channel->max_full_scale.fx);
+	result.fy = get_s16(&channel->max_full_scale.fy);
+	result.fz = get_s16(&channel->max_full_scale.fz);
+	result.mx = get_s16(&channel->max_full_scale.mx);
+	result.my = get_s16(&channel->max_full_scale.my);
+	result.mz = get_s16(&channel->max_full_scale.mz);
+	return result;
+}
+
+static int jr3_pci_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int result;
+	struct jr3_pci_subdev_private *p;
+	int channel;
+
+	p = s->private;
+	channel = CR_CHAN(insn->chanspec);
+	if (p == NULL || channel > 57) {
+		result = -EINVAL;
+	} else {
+		int i;
+
+		result = insn->n;
+		if (p->state != state_jr3_done ||
+			(get_u16(&p->channel->
+					errors) & (watch_dog | watch_dog2 |
+					sensor_change))) {
+			/* No sensor or sensor changed */
+			if (p->state == state_jr3_done) {
+				/* Restart polling */
+				p->state = state_jr3_poll;
+			}
+			result = -EAGAIN;
+		}
+		for (i = 0; i < insn->n; i++) {
+			if (channel < 56) {
+				int axis, filter;
+
+				axis = channel % 8;
+				filter = channel / 8;
+				if (p->state != state_jr3_done) {
+					data[i] = 0;
+				} else {
+					int F = 0;
+					switch (axis) {
+					case 0:{
+							F = get_s16(&p->
+								channel->
+								filter[filter].
+								fx);
+						}
+						break;
+					case 1:{
+							F = get_s16(&p->
+								channel->
+								filter[filter].
+								fy);
+						}
+						break;
+					case 2:{
+							F = get_s16(&p->
+								channel->
+								filter[filter].
+								fz);
+						}
+						break;
+					case 3:{
+							F = get_s16(&p->
+								channel->
+								filter[filter].
+								mx);
+						}
+						break;
+					case 4:{
+							F = get_s16(&p->
+								channel->
+								filter[filter].
+								my);
+						}
+						break;
+					case 5:{
+							F = get_s16(&p->
+								channel->
+								filter[filter].
+								mz);
+						}
+						break;
+					case 6:{
+							F = get_s16(&p->
+								channel->
+								filter[filter].
+								v1);
+						}
+						break;
+					case 7:{
+							F = get_s16(&p->
+								channel->
+								filter[filter].
+								v2);
+						}
+						break;
+					}
+					data[i] = F + 0x4000;
+				}
+			} else if (channel == 56) {
+				if (p->state != state_jr3_done) {
+					data[i] = 0;
+				} else {
+					data[i] =
+						get_u16(&p->channel->model_no);
+				}
+			} else if (channel == 57) {
+				if (p->state != state_jr3_done) {
+					data[i] = 0;
+				} else {
+					data[i] =
+						get_u16(&p->channel->serial_no);
+				}
+			}
+		}
+	}
+	return result;
+}
+
+static void jr3_pci_open(struct comedi_device * dev)
+{
+	int i;
+	struct jr3_pci_dev_private *devpriv = dev->private;
+
+	printk("jr3_pci_open\n");
+	for (i = 0; i < devpriv->n_channels; i++) {
+		struct jr3_pci_subdev_private *p;
+
+		p = dev->subdevices[i].private;
+		if (p) {
+			printk("serial: %p %d (%d)\n", p, p->serial_no,
+				p->channel_no);
+		}
+	}
+}
+
+int read_idm_word(const u8 * data, size_t size, int *pos, unsigned int *val)
+{
+	int result = 0;
+	if (pos != 0 && val != 0) {
+		// Skip over non hex
+		for (; *pos < size && !isxdigit(data[*pos]); (*pos)++) {
+		}
+		// Collect value
+		*val = 0;
+		for (; *pos < size && isxdigit(data[*pos]); (*pos)++) {
+			char ch = tolower(data[*pos]);
+			result = 1;
+			if ('0' <= ch && ch <= '9') {
+				*val = (*val << 4) + (ch - '0');
+			} else if ('a' <= ch && ch <= 'f') {
+				*val = (*val << 4) + (ch - 'a' + 10);
+			}
+		}
+	}
+	return result;
+}
+
+static int jr3_download_firmware(struct comedi_device * dev, const u8 * data,
+	size_t size)
+{
+	/*
+	 * IDM file format is:
+	 *   { count, address, data <count> } *
+	 *   ffff
+	 */
+	int result, more, pos, OK;
+
+	result = 0;
+	more = 1;
+	pos = 0;
+	OK = 0;
+	while (more) {
+		unsigned int count, addr;
+
+		more = more && read_idm_word(data, size, &pos, &count);
+		if (more && count == 0xffff) {
+			OK = 1;
+			break;
+		}
+		more = more && read_idm_word(data, size, &pos, &addr);
+		while (more && count > 0) {
+			unsigned int dummy;
+			more = more && read_idm_word(data, size, &pos, &dummy);
+			count--;
+		}
+	}
+
+	if (!OK) {
+		result = -ENODATA;
+	} else {
+		int i;
+		struct jr3_pci_dev_private *p = dev->private;
+
+		for (i = 0; i < p->n_channels; i++) {
+			struct jr3_pci_subdev_private *sp;
+
+			sp = dev->subdevices[i].private;
+			more = 1;
+			pos = 0;
+			while (more) {
+				unsigned int count, addr;
+				more = more
+					&& read_idm_word(data, size, &pos,
+					&count);
+				if (more && count == 0xffff) {
+					break;
+				}
+				more = more
+					&& read_idm_word(data, size, &pos,
+					&addr);
+				printk("Loading#%d %4.4x bytes at %4.4x\n", i,
+					count, addr);
+				while (more && count > 0) {
+					if (addr & 0x4000) {
+						// 16 bit data, never seen in real life!!
+						unsigned int data1;
+
+						more = more
+							&& read_idm_word(data,
+							size, &pos, &data1);
+						count--;
+						// printk("jr3_data, not tested\n");
+						//        jr3[addr + 0x20000 * pnum] = data1;
+					} else {
+						//  Download 24 bit program
+						unsigned int data1, data2;
+
+						more = more
+							&& read_idm_word(data,
+							size, &pos, &data1);
+						more = more
+							&& read_idm_word(data,
+							size, &pos, &data2);
+						count -= 2;
+						if (more) {
+							set_u16(&p->iobase->
+								channel[i].
+								program_low
+								[addr], data1);
+							comedi_udelay(1);
+							set_u16(&p->iobase->
+								channel[i].
+								program_high
+								[addr], data2);
+							comedi_udelay(1);
+
+						}
+					}
+					addr++;
+				}
+			}
+		}
+	}
+	return result;
+}
+
+static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice * s)
+{
+	struct poll_delay_t result = poll_delay_min_max(1000, 2000);
+	struct jr3_pci_subdev_private *p = s->private;
+
+	if (p) {
+		volatile struct jr3_channel *channel = p->channel;
+		int errors = get_u16(&channel->errors);
+
+		if (errors != p->errors) {
+			printk("Errors: %x -> %x\n", p->errors, errors);
+			p->errors = errors;
+		}
+		if (errors & (watch_dog | watch_dog2 | sensor_change)) {
+			// Sensor communication lost, force poll mode
+			p->state = state_jr3_poll;
+
+		}
+		switch (p->state) {
+		case state_jr3_poll:{
+				u16 model_no = get_u16(&channel->model_no);
+				u16 serial_no = get_u16(&channel->serial_no);
+				if ((errors & (watch_dog | watch_dog2)) ||
+					model_no == 0 || serial_no == 0) {
+					// Still no sensor, keep on polling. Since it takes up to
+					// 10 seconds for offsets to stabilize, polling each
+					// second should suffice.
+					result = poll_delay_min_max(1000, 2000);
+				} else {
+					p->retries = 0;
+					p->state =
+						state_jr3_init_wait_for_offset;
+					result = poll_delay_min_max(1000, 2000);
+				}
+			}
+			break;
+		case state_jr3_init_wait_for_offset:{
+				p->retries++;
+				if (p->retries < 10) {
+					// Wait for offeset to stabilize (< 10 s according to manual)
+					result = poll_delay_min_max(1000, 2000);
+				} else {
+					struct transform_t transf;
+
+					p->model_no =
+						get_u16(&channel->model_no);
+					p->serial_no =
+						get_u16(&channel->serial_no);
+
+					printk("Setting transform for channel %d\n", p->channel_no);
+					printk("Sensor Model     = %i\n",
+						p->model_no);
+					printk("Sensor Serial    = %i\n",
+						p->serial_no);
+
+					// Transformation all zeros
+					transf.link[0].link_type =
+						(enum link_types)0;
+					transf.link[0].link_amount = 0;
+					transf.link[1].link_type =
+						(enum link_types)0;
+					transf.link[1].link_amount = 0;
+					transf.link[2].link_type =
+						(enum link_types)0;
+					transf.link[2].link_amount = 0;
+					transf.link[3].link_type =
+						(enum link_types)0;
+					transf.link[3].link_amount = 0;
+
+					set_transforms(channel, transf, 0);
+					use_transform(channel, 0);
+					p->state =
+						state_jr3_init_transform_complete;
+					result = poll_delay_min_max(20, 100);	// Allow 20 ms for completion
+				}
+			} break;
+		case state_jr3_init_transform_complete:{
+				if (!is_complete(channel)) {
+					printk("state_jr3_init_transform_complete complete = %d\n", is_complete(channel));
+					result = poll_delay_min_max(20, 100);
+				} else {
+					// Set full scale
+					struct six_axis_t min_full_scale;
+					struct six_axis_t max_full_scale;
+
+					min_full_scale =
+						get_min_full_scales(channel);
+					printk("Obtained Min. Full Scales:\n");
+					printk("%i   ", (min_full_scale).fx);
+					printk("%i   ", (min_full_scale).fy);
+					printk("%i   ", (min_full_scale).fz);
+					printk("%i   ", (min_full_scale).mx);
+					printk("%i   ", (min_full_scale).my);
+					printk("%i   ", (min_full_scale).mz);
+					printk("\n");
+
+					max_full_scale =
+						get_max_full_scales(channel);
+					printk("Obtained Max. Full Scales:\n");
+					printk("%i   ", (max_full_scale).fx);
+					printk("%i   ", (max_full_scale).fy);
+					printk("%i   ", (max_full_scale).fz);
+					printk("%i   ", (max_full_scale).mx);
+					printk("%i   ", (max_full_scale).my);
+					printk("%i   ", (max_full_scale).mz);
+					printk("\n");
+
+					set_full_scales(channel,
+						max_full_scale);
+
+					p->state =
+						state_jr3_init_set_full_scale_complete;
+					result = poll_delay_min_max(20, 100);	// Allow 20 ms for completion
+				}
+			}
+			break;
+		case state_jr3_init_set_full_scale_complete:{
+				if (!is_complete(channel)) {
+					printk("state_jr3_init_set_full_scale_complete complete = %d\n", is_complete(channel));
+					result = poll_delay_min_max(20, 100);
+				} else {
+					volatile struct force_array *full_scale;
+
+					// Use ranges in kN or we will overflow arount 2000N!
+					full_scale = &channel->full_scale;
+					p->range[0].range.min =
+						-get_s16(&full_scale->fx) *
+						1000;
+					p->range[0].range.max =
+						get_s16(&full_scale->fx) * 1000;
+					p->range[1].range.min =
+						-get_s16(&full_scale->fy) *
+						1000;
+					p->range[1].range.max =
+						get_s16(&full_scale->fy) * 1000;
+					p->range[2].range.min =
+						-get_s16(&full_scale->fz) *
+						1000;
+					p->range[2].range.max =
+						get_s16(&full_scale->fz) * 1000;
+					p->range[3].range.min =
+						-get_s16(&full_scale->mx) * 100;
+					p->range[3].range.max =
+						get_s16(&full_scale->mx) * 100;
+					p->range[4].range.min =
+						-get_s16(&full_scale->my) * 100;
+					p->range[4].range.max =
+						get_s16(&full_scale->my) * 100;
+					p->range[5].range.min =
+						-get_s16(&full_scale->mz) * 100;
+					p->range[5].range.max =
+						get_s16(&full_scale->mz) * 100;
+					p->range[6].range.min = -get_s16(&full_scale->v1) * 100;	// ??
+					p->range[6].range.max = get_s16(&full_scale->v1) * 100;	// ??
+					p->range[7].range.min = -get_s16(&full_scale->v2) * 100;	// ??
+					p->range[7].range.max = get_s16(&full_scale->v2) * 100;	// ??
+					p->range[8].range.min = 0;
+					p->range[8].range.max = 65535;
+
+					{
+						int i;
+						for (i = 0; i < 9; i++) {
+							printk("%d %d - %d\n",
+								i,
+								p->range[i].
+								range.min,
+								p->range[i].
+								range.max);
+						}
+					}
+
+					use_offset(channel, 0);
+					p->state =
+						state_jr3_init_use_offset_complete;
+					result = poll_delay_min_max(40, 100);	// Allow 40 ms for completion
+				}
+			}
+			break;
+		case state_jr3_init_use_offset_complete:{
+				if (!is_complete(channel)) {
+					printk("state_jr3_init_use_offset_complete complete = %d\n", is_complete(channel));
+					result = poll_delay_min_max(20, 100);
+				} else {
+					printk("Default offsets %d %d %d %d %d %d\n", get_s16(&channel->offsets.fx), get_s16(&channel->offsets.fy), get_s16(&channel->offsets.fz), get_s16(&channel->offsets.mx), get_s16(&channel->offsets.my), get_s16(&channel->offsets.mz));
+
+					set_s16(&channel->offsets.fx, 0);
+					set_s16(&channel->offsets.fy, 0);
+					set_s16(&channel->offsets.fz, 0);
+					set_s16(&channel->offsets.mx, 0);
+					set_s16(&channel->offsets.my, 0);
+					set_s16(&channel->offsets.mz, 0);
+
+					set_offset(channel);
+
+					p->state = state_jr3_done;
+				}
+			}
+			break;
+		case state_jr3_done:{
+				poll_delay_min_max(10000, 20000);
+			}
+			break;
+		default:{
+				poll_delay_min_max(1000, 2000);
+			}
+			break;
+		}
+	}
+	return result;
+}
+
+static void jr3_pci_poll_dev(unsigned long data)
+{
+	unsigned long flags;
+	struct comedi_device *dev = (struct comedi_device *) data;
+	struct jr3_pci_dev_private *devpriv = dev->private;
+	unsigned long now;
+	int delay;
+	int i;
+
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	delay = 1000;
+	now = jiffies;
+	// Poll all channels that are ready to be polled
+	for (i = 0; i < devpriv->n_channels; i++) {
+		struct jr3_pci_subdev_private *subdevpriv = dev->subdevices[i].private;
+		if (now > subdevpriv->next_time_min) {
+			struct poll_delay_t sub_delay;
+
+			sub_delay = jr3_pci_poll_subdevice(&dev->subdevices[i]);
+			subdevpriv->next_time_min =
+				jiffies + msecs_to_jiffies(sub_delay.min);
+			subdevpriv->next_time_max =
+				jiffies + msecs_to_jiffies(sub_delay.max);
+			if (sub_delay.max && sub_delay.max < delay) {
+				// Wake up as late as possible -> poll as many channels as
+				// possible at once
+				delay = sub_delay.max;
+			}
+		}
+	}
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	devpriv->timer.expires = jiffies + msecs_to_jiffies(delay);
+	add_timer(&devpriv->timer);
+}
+
+static int jr3_pci_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	int result = 0;
+	struct pci_dev *card = NULL;
+	int opt_bus, opt_slot, i;
+	struct jr3_pci_dev_private *devpriv;
+
+	printk("comedi%d: jr3_pci\n", dev->minor);
+
+	opt_bus = it->options[0];
+	opt_slot = it->options[1];
+
+	if (sizeof(struct jr3_channel) != 0xc00) {
+		printk("sizeof(struct jr3_channel) = %x [expected %x]\n",
+			(unsigned)sizeof(struct jr3_channel), 0xc00);
+		return -EINVAL;
+	}
+
+	result = alloc_private(dev, sizeof(struct jr3_pci_dev_private));
+	if (result < 0) {
+		return -ENOMEM;
+	}
+	card = NULL;
+	devpriv = dev->private;
+	init_timer(&devpriv->timer);
+	while (1) {
+		card = pci_get_device(PCI_VENDOR_ID_JR3, PCI_ANY_ID, card);
+		if (card == NULL) {
+			/* No card found */
+			break;
+		} else {
+			switch (card->device) {
+			case PCI_DEVICE_ID_JR3_1_CHANNEL:{
+					devpriv->n_channels = 1;
+				}
+				break;
+			case PCI_DEVICE_ID_JR3_2_CHANNEL:{
+					devpriv->n_channels = 2;
+				}
+				break;
+			case PCI_DEVICE_ID_JR3_3_CHANNEL:{
+					devpriv->n_channels = 3;
+				}
+				break;
+			case PCI_DEVICE_ID_JR3_4_CHANNEL:{
+					devpriv->n_channels = 4;
+				}
+				break;
+			default:{
+					devpriv->n_channels = 0;
+				}
+			}
+			if (devpriv->n_channels >= 1) {
+				if (opt_bus == 0 && opt_slot == 0) {
+					/* Take first available card */
+					break;
+				} else if (opt_bus == card->bus->number &&
+					opt_slot == PCI_SLOT(card->devfn)) {
+					/* Take requested card */
+					break;
+				}
+			}
+		}
+	}
+	if (!card) {
+		printk(" no jr3_pci found\n");
+		return -EIO;
+	} else {
+		devpriv->pci_dev = card;
+		dev->board_name = "jr3_pci";
+	}
+	if ((result = comedi_pci_enable(card, "jr3_pci")) < 0) {
+		return -EIO;
+	}
+	devpriv->pci_enabled = 1;
+	devpriv->iobase = ioremap(pci_resource_start(card, 0), sizeof(struct jr3_t));
+	result = alloc_subdevices(dev, devpriv->n_channels);
+	if (result < 0)
+		goto out;
+
+	dev->open = jr3_pci_open;
+	for (i = 0; i < devpriv->n_channels; i++) {
+		dev->subdevices[i].type = COMEDI_SUBD_AI;
+		dev->subdevices[i].subdev_flags = SDF_READABLE | SDF_GROUND;
+		dev->subdevices[i].n_chan = 8 * 7 + 2;
+		dev->subdevices[i].insn_read = jr3_pci_ai_insn_read;
+		dev->subdevices[i].private =
+			kzalloc(sizeof(struct jr3_pci_subdev_private), GFP_KERNEL);
+		if (dev->subdevices[i].private) {
+			struct jr3_pci_subdev_private *p;
+			int j;
+
+			p = dev->subdevices[i].private;
+			p->channel = &devpriv->iobase->channel[i].data;
+			printk("p->channel %p %p (%tx)\n",
+				p->channel, devpriv->iobase,
+				((char *)(p->channel) -
+					(char *)(devpriv->iobase)));
+			p->channel_no = i;
+			for (j = 0; j < 8; j++) {
+				int k;
+
+				p->range[j].length = 1;
+				p->range[j].range.min = -1000000;
+				p->range[j].range.max = 1000000;
+				for (k = 0; k < 7; k++) {
+					p->range_table_list[j + k * 8] =
+						(struct comedi_lrange *) & p->range[j];
+					p->maxdata_list[j + k * 8] = 0x7fff;
+				}
+			}
+			p->range[8].length = 1;
+			p->range[8].range.min = 0;
+			p->range[8].range.max = 65536;
+
+			p->range_table_list[56] =
+				(struct comedi_lrange *) & p->range[8];
+			p->range_table_list[57] =
+				(struct comedi_lrange *) & p->range[8];
+			p->maxdata_list[56] = 0xffff;
+			p->maxdata_list[57] = 0xffff;
+			// Channel specific range and maxdata
+			dev->subdevices[i].range_table = 0;
+			dev->subdevices[i].range_table_list =
+				p->range_table_list;
+			dev->subdevices[i].maxdata = 0;
+			dev->subdevices[i].maxdata_list = p->maxdata_list;
+		}
+	}
+
+	// Reset DSP card
+	devpriv->iobase->channel[0].reset = 0;
+
+	result = comedi_load_firmware(dev, "jr3pci.idm", jr3_download_firmware);
+	printk("Firmare load %d\n", result);
+
+	if (result < 0) {
+		goto out;
+	}
+	// TODO: use firmware to load preferred offset tables. Suggested format:
+	// model serial Fx Fy Fz Mx My Mz\n
+	//
+	// comedi_load_firmware(dev, "jr3_offsets_table", jr3_download_firmware);
+
+	// It takes a few milliseconds for software to settle
+	// as much as we can read firmware version
+	msleep_interruptible(25);
+	for (i = 0; i < 0x18; i++) {
+		printk("%c",
+			get_u16(&devpriv->iobase->channel[0].data.
+				copyright[i]) >> 8);
+	}
+
+	// Start card timer
+	for (i = 0; i < devpriv->n_channels; i++) {
+		struct jr3_pci_subdev_private *p = dev->subdevices[i].private;
+
+		p->next_time_min = jiffies + msecs_to_jiffies(500);
+		p->next_time_max = jiffies + msecs_to_jiffies(2000);
+	}
+
+	devpriv->timer.data = (unsigned long)dev;
+	devpriv->timer.function = jr3_pci_poll_dev;
+	devpriv->timer.expires = jiffies + msecs_to_jiffies(1000);
+	add_timer(&devpriv->timer);
+
+      out:
+	return result;
+}
+
+static int jr3_pci_detach(struct comedi_device * dev)
+{
+	int i;
+	struct jr3_pci_dev_private *devpriv = dev->private;
+
+	printk("comedi%d: jr3_pci: remove\n", dev->minor);
+	if (devpriv) {
+		del_timer_sync(&devpriv->timer);
+
+		if (dev->subdevices) {
+			for (i = 0; i < devpriv->n_channels; i++) {
+				kfree(dev->subdevices[i].private);
+			}
+		}
+
+		if (devpriv->iobase) {
+			iounmap((void *)devpriv->iobase);
+		}
+		if (devpriv->pci_enabled) {
+			comedi_pci_disable(devpriv->pci_dev);
+		}
+
+		if (devpriv->pci_dev) {
+			pci_dev_put(devpriv->pci_dev);
+		}
+	}
+	return 0;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_jr3_pci, jr3_pci_pci_table);
diff --git a/drivers/staging/comedi/drivers/jr3_pci.h b/drivers/staging/comedi/drivers/jr3_pci.h
new file mode 100644
index 0000000..3585f29
--- /dev/null
+++ b/drivers/staging/comedi/drivers/jr3_pci.h
@@ -0,0 +1,681 @@
+/* Helper types to take care of the fact that the DSP card memory
+ * is 16 bits, but aligned on a 32 bit PCI boundary
+ */
+
+static inline u16 get_u16(volatile const u32 * p)
+{
+	return (u16) readl(p);
+}
+
+static inline void set_u16(volatile u32 * p, u16 val)
+{
+	writel(val, p);
+}
+
+static inline s16 get_s16(volatile const s32 * p)
+{
+	return (s16) readl(p);
+}
+
+static inline void set_s16(volatile s32 * p, s16 val)
+{
+	writel(val, p);
+}
+
+/* The raw data is stored in a format which facilitates rapid
+ * processing by the JR3 DSP chip. The raw_channel structure shows the
+ * format for a single channel of data. Each channel takes four,
+ * two-byte words.
+ *
+ * Raw_time is an unsigned integer which shows the value of the JR3
+ * DSP's internal clock at the time the sample was received. The clock
+ * runs at 1/10 the JR3 DSP cycle time. JR3's slowest DSP runs at 10
+ * Mhz. At 10 Mhz raw_time would therefore clock at 1 Mhz.
+ *
+ * Raw_data is the raw data received directly from the sensor. The
+ * sensor data stream is capable of representing 16 different
+ * channels. Channel 0 shows the excitation voltage at the sensor. It
+ * is used to regulate the voltage over various cable lengths.
+ * Channels 1-6 contain the coupled force data Fx through Mz. Channel
+ * 7 contains the sensor's calibration data. The use of channels 8-15
+ * varies with different sensors.
+ */
+
+struct raw_channel {
+	u32 raw_time;
+	s32 raw_data;
+	s32 reserved[2];
+};
+
+/* The force_array structure shows the layout for the decoupled and
+ * filtered force data.
+ */
+struct force_array {
+	s32 fx;
+	s32 fy;
+	s32 fz;
+	s32 mx;
+	s32 my;
+	s32 mz;
+	s32 v1;
+	s32 v2;
+};
+
+/* The six_axis_array structure shows the layout for the offsets and
+ * the full scales.
+ */
+struct six_axis_array {
+	s32 fx;
+	s32 fy;
+	s32 fz;
+	s32 mx;
+	s32 my;
+	s32 mz;
+};
+
+/* VECT_BITS */
+/* The vect_bits structure shows the layout for indicating
+ * which axes to use in computing the vectors. Each bit signifies
+ * selection of a single axis. The V1x axis bit corresponds to a hex
+ * value of 0x0001 and the V2z bit corresponds to a hex value of
+ * 0x0020. Example: to specify the axes V1x, V1y, V2x, and V2z the
+ * pattern would be 0x002b. Vector 1 defaults to a force vector and
+ * vector 2 defaults to a moment vector. It is possible to change one
+ * or the other so that two force vectors or two moment vectors are
+ * calculated. Setting the changeV1 bit or the changeV2 bit will
+ * change that vector to be the opposite of its default. Therefore to
+ * have two force vectors, set changeV1 to 1.
+ */
+
+/* vect_bits appears to be unused at this time */
+enum {
+	fx = 0x0001,
+	fy = 0x0002,
+	fz = 0x0004,
+	mx = 0x0008,
+	my = 0x0010,
+	mz = 0x0020,
+	changeV2 = 0x0040,
+	changeV1 = 0x0080
+} vect_bits_t;
+
+/* WARNING_BITS */
+/* The warning_bits structure shows the bit pattern for the warning
+ * word. The bit fields are shown from bit 0 (lsb) to bit 15 (msb).
+ */
+
+/*  XX_NEAR_SET */
+/* The xx_near_sat bits signify that the indicated axis has reached or
+ * exceeded the near saturation value.
+ */
+
+enum {
+	fx_near_sat = 0x0001,
+	fy_near_sat = 0x0002,
+	fz_near_sat = 0x0004,
+	mx_near_sat = 0x0008,
+	my_near_sat = 0x0010,
+	mz_near_sat = 0x0020
+} warning_bits_t;
+
+/*  ERROR_BITS */
+/*  XX_SAT */
+/*  MEMORY_ERROR */
+/*  SENSOR_CHANGE */
+
+/* The error_bits structure shows the bit pattern for the error word.
+ * The bit fields are shown from bit 0 (lsb) to bit 15 (msb). The
+ * xx_sat bits signify that the indicated axis has reached or exceeded
+ * the saturation value. The memory_error bit indicates that a problem
+ * was detected in the on-board RAM during the power-up
+ * initialization. The sensor_change bit indicates that a sensor other
+ * than the one originally plugged in has passed its CRC check. This
+ * bit latches, and must be reset by the user.
+ *
+ */
+
+/*  SYSTEM_BUSY */
+
+/* The system_busy bit indicates that the JR3 DSP is currently busy
+ * and is not calculating force data. This occurs when a new
+ * coordinate transformation, or new sensor full scale is set by the
+ * user. A very fast system using the force data for feedback might
+ * become unstable during the approximately 4 ms needed to accomplish
+ * these calculations. This bit will also become active when a new
+ * sensor is plugged in and the system needs to recalculate the
+ * calibration CRC.
+ */
+
+/*  CAL_CRC_BAD */
+
+/* The cal_crc_bad bit indicates that the calibration CRC has not
+ * calculated to zero. CRC is short for cyclic redundancy code. It is
+ * a method for determining the integrity of messages in data
+ * communication. The calibration data stored inside the sensor is
+ * transmitted to the JR3 DSP along with the sensor data. The
+ * calibration data has a CRC attached to the end of it, to assist in
+ * determining the completeness and integrity of the calibration data
+ * received from the sensor. There are two reasons the CRC may not
+ * have calculated to zero. The first is that all the calibration data
+ * has not yet been received, the second is that the calibration data
+ * has been corrupted. A typical sensor transmits the entire contents
+ * of its calibration matrix over 30 times a second. Therefore, if
+ * this bit is not zero within a couple of seconds after the sensor
+ * has been plugged in, there is a problem with the sensor's
+ * calibration data.
+ */
+
+/* WATCH_DOG */
+/* WATCH_DOG2 */
+
+/* The watch_dog and watch_dog2 bits are sensor, not processor, watch
+ * dog bits. Watch_dog indicates that the sensor data line seems to be
+ * acting correctly, while watch_dog2 indicates that sensor data and
+ * clock are being received. It is possible for watch_dog2 to go off
+ * while watch_dog does not. This would indicate an improper clock
+ * signal, while data is acting correctly. If either watch dog barks,
+ * the sensor data is not being received correctly.
+ */
+
+enum error_bits_t {
+	fx_sat = 0x0001,
+	fy_sat = 0x0002,
+	fz_sat = 0x0004,
+	mx_sat = 0x0008,
+	my_sat = 0x0010,
+	mz_sat = 0x0020,
+	memory_error = 0x0400,
+	sensor_change = 0x0800,
+	system_busy = 0x1000,
+	cal_crc_bad = 0x2000,
+	watch_dog2 = 0x4000,
+	watch_dog = 0x8000
+};
+
+/*  THRESH_STRUCT */
+
+/* This structure shows the layout for a single threshold packet inside of a
+ * load envelope. Each load envelope can contain several threshold structures.
+ * 1. data_address contains the address of the data for that threshold. This
+ *    includes filtered, unfiltered, raw, rate, counters, error and warning data
+ * 2. threshold is the is the value at which, if data is above or below, the
+ *    bits will be set ... (pag.24).
+ * 3. bit_pattern contains the bits that will be set if the threshold value is
+ *    met or exceeded.
+ */
+
+struct thresh_struct {
+	s32 data_address;
+	s32 threshold;
+	s32 bit_pattern;
+};
+
+/*  LE_STRUCT */
+
+/* Layout of a load enveloped packet. Four thresholds are showed ... for more
+ * see manual (pag.25)
+ * 1. latch_bits is a bit pattern that show which bits the user wants to latch.
+ *    The latched bits will not be reset once the threshold which set them is
+ *    no longer true. In that case the user must reset them using the reset_bit
+ *    command.
+ * 2. number_of_xx_thresholds specify how many GE/LE threshold there are.
+ */
+struct le_struct {
+	s32 latch_bits;
+	s32 number_of_ge_thresholds;
+	s32 number_of_le_thresholds;
+	struct thresh_struct thresholds[4];
+	s32 reserved;
+};
+
+/*  LINK_TYPES */
+/* Link types is an enumerated value showing the different possible transform
+ * link types.
+ * 0 - end transform packet
+ * 1 - translate along X axis (TX)
+ * 2 - translate along Y axis (TY)
+ * 3 - translate along Z axis (TZ)
+ * 4 - rotate about X axis (RX)
+ * 5 - rotate about Y axis (RY)
+ * 6 - rotate about Z axis (RZ)
+ * 7 - negate all axes (NEG)
+ */
+
+enum link_types {
+	end_x_form,
+	tx,
+	ty,
+	tz,
+	rx,
+	ry,
+	rz,
+	neg
+};
+
+/*  TRANSFORM */
+/*  Structure used to describe a transform. */
+struct intern_transform {
+	struct {
+		u32 link_type;
+		s32 link_amount;
+	} link[8];
+};
+
+/*  JR3 force/torque sensor data definition. For more information see sensor and */
+/*  hardware manuals. */
+
+struct jr3_channel {
+	/*  Raw_channels is the area used to store the raw data coming from */
+	/*  the sensor. */
+
+	struct raw_channel raw_channels[16];	/* offset 0x0000 */
+
+	/*  Copyright is a null terminated ASCII string containing the JR3 */
+	/*  copyright notice. */
+
+	u32 copyright[0x0018];	/* offset 0x0040 */
+	s32 reserved1[0x0008];	/* offset 0x0058 */
+
+	/* Shunts contains the sensor shunt readings. Some JR3 sensors have
+	 * the ability to have their gains adjusted. This allows the
+	 * hardware full scales to be adjusted to potentially allow
+	 * better resolution or dynamic range. For sensors that have
+	 * this ability, the gain of each sensor channel is measured at
+	 * the time of calibration using a shunt resistor. The shunt
+	 * resistor is placed across one arm of the resistor bridge, and
+	 * the resulting change in the output of that channel is
+	 * measured. This measurement is called the shunt reading, and
+	 * is recorded here. If the user has changed the gain of the //
+	 * sensor, and made new shunt measurements, those shunt
+	 * measurements can be placed here. The JR3 DSP will then scale
+	 * the calibration matrix such so that the gains are again
+	 * proper for the indicated shunt readings. If shunts is 0, then
+	 * the sensor cannot have its gain changed. For details on
+	 * changing the sensor gain, and making shunts readings, please
+	 * see the sensor manual. To make these values take effect the
+	 * user must call either command (5) use transform # (pg. 33) or
+	 * command (10) set new full scales (pg. 38).
+	 */
+
+	struct six_axis_array shunts;	/* offset 0x0060 */
+	s32 reserved2[2];	/* offset 0x0066 */
+
+	/* Default_FS contains the full scale that is used if the user does */
+	/* not set a full scale. */
+
+	struct six_axis_array default_FS;	/* offset 0x0068 */
+	s32 reserved3;	/* offset 0x006e */
+
+	/* Load_envelope_num is the load envelope number that is currently
+	 * in use. This value is set by the user after one of the load
+	 * envelopes has been initialized.
+	 */
+
+	s32 load_envelope_num;	/* offset 0x006f */
+
+	/* Min_full_scale is the recommend minimum full scale. */
+
+	/* These values in conjunction with max_full_scale (pg. 9) helps
+	 * determine the appropriate value for setting the full scales. The
+	 * software allows the user to set the sensor full scale to an
+	 * arbitrary value. But setting the full scales has some hazards. If
+	 * the full scale is set too low, the data will saturate
+	 * prematurely, and dynamic range will be lost. If the full scale is
+	 * set too high, then resolution is lost as the data is shifted to
+	 * the right and the least significant bits are lost. Therefore the
+	 * maximum full scale is the maximum value at which no resolution is
+	 * lost, and the minimum full scale is the value at which the data
+	 * will not saturate prematurely. These values are calculated
+	 * whenever a new coordinate transformation is calculated. It is
+	 * possible for the recommended maximum to be less than the
+	 * recommended minimum. This comes about primarily when using
+	 * coordinate translations. If this is the case, it means that any
+	 * full scale selection will be a compromise between dynamic range
+	 * and resolution. It is usually recommended to compromise in favor
+	 * of resolution which means that the recommend maximum full scale
+	 * should be chosen.
+	 *
+	 * WARNING: Be sure that the full scale is no less than 0.4% of the
+	 * recommended minimum full scale. Full scales below this value will
+	 * cause erroneous results.
+	 */
+
+	struct six_axis_array min_full_scale;	/* offset 0x0070 */
+	s32 reserved4;	/* offset 0x0076 */
+
+	/* Transform_num is the transform number that is currently in use.
+	 * This value is set by the JR3 DSP after the user has used command
+	 * (5) use transform # (pg. 33).
+	 */
+
+	s32 transform_num;	/* offset 0x0077 */
+
+	/*  Max_full_scale is the recommended maximum full scale. See */
+	/*  min_full_scale (pg. 9) for more details. */
+
+	struct six_axis_array max_full_scale;	/* offset 0x0078 */
+	s32 reserved5;	/* offset 0x007e */
+
+	/* Peak_address is the address of the data which will be monitored
+	 * by the peak routine. This value is set by the user. The peak
+	 * routine will monitor any 8 contiguous addresses for peak values.
+	 * (ex. to watch filter3 data for peaks, set this value to 0x00a8).
+	 */
+
+	s32 peak_address;	/* offset 0x007f */
+
+	/* Full_scale is the sensor full scales which are currently in use.
+	 * Decoupled and filtered data is scaled so that +/- 16384 is equal
+	 * to the full scales. The engineering units used are indicated by
+	 * the units value discussed on page 16. The full scales for Fx, Fy,
+	 * Fz, Mx, My and Mz can be written by the user prior to calling
+	 * command (10) set new full scales (pg. 38). The full scales for V1
+	 * and V2 are set whenever the full scales are changed or when the
+	 * axes used to calculate the vectors are changed. The full scale of
+	 * V1 and V2 will always be equal to the largest full scale of the
+	 * axes used for each vector respectively.
+	 */
+
+	struct force_array full_scale;	/* offset 0x0080 */
+
+	/* Offsets contains the sensor offsets. These values are subtracted from
+	 * the sensor data to obtain the decoupled data. The offsets are set a
+	 * few seconds (< 10) after the calibration data has been received.
+	 * They are set so that the output data will be zero. These values
+	 * can be written as well as read. The JR3 DSP will use the values
+	 * written here within 2 ms of being written. To set future
+	 * decoupled data to zero, add these values to the current decoupled
+	 * data values and place the sum here. The JR3 DSP will change these
+	 * values when a new transform is applied. So if the offsets are
+	 * such that FX is 5 and all other values are zero, after rotating
+	 * about Z by 90 degrees, FY would be 5 and all others would be zero.
+	 */
+
+	struct six_axis_array offsets;	/* offset 0x0088 */
+
+	/* Offset_num is the number of the offset currently in use. This
+	 * value is set by the JR3 DSP after the user has executed the use
+	 * offset # command (pg. 34). It can vary between 0 and 15.
+	 */
+
+	s32 offset_num;	/* offset 0x008e */
+
+	/* Vect_axes is a bit map showing which of the axes are being used
+	 * in the vector calculations. This value is set by the JR3 DSP
+	 * after the user has executed the set vector axes command (pg. 37).
+	 */
+
+	u32 vect_axes;	/* offset 0x008f */
+
+	/* Filter0 is the decoupled, unfiltered data from the JR3 sensor.
+	 * This data has had the offsets removed.
+	 *
+	 * These force_arrays hold the filtered data. The decoupled data is
+	 * passed through cascaded low pass filters. Each succeeding filter
+	 * has a cutoff frequency of 1/4 of the preceding filter. The cutoff
+	 * frequency of filter1 is 1/16 of the sample rate from the sensor.
+	 * For a typical sensor with a sample rate of 8 kHz, the cutoff
+	 * frequency of filter1 would be 500 Hz. The following filters would
+	 * cutoff at 125 Hz, 31.25 Hz, 7.813 Hz, 1.953 Hz and 0.4883 Hz.
+	 */
+
+	struct force_array filter[7];	/* offset 0x0090,
+					   offset 0x0098,
+					   offset 0x00a0,
+					   offset 0x00a8,
+					   offset 0x00b0,
+					   offset 0x00b8 ,
+					   offset 0x00c0 */
+
+	/* Rate_data is the calculated rate data. It is a first derivative
+	 * calculation. It is calculated at a frequency specified by the
+	 * variable rate_divisor (pg. 12). The data on which the rate is
+	 * calculated is specified by the variable rate_address (pg. 12).
+	 */
+
+	struct force_array rate_data;	/* offset 0x00c8 */
+
+	/* Minimum_data & maximum_data are the minimum and maximum (peak)
+	 * data values. The JR3 DSP can monitor any 8 contiguous data items
+	 * for minimums and maximums at full sensor bandwidth. This area is
+	 * only updated at user request. This is done so that the user does
+	 * not miss any peaks. To read the data, use either the read peaks
+	 * command (pg. 40), or the read and reset peaks command (pg. 39).
+	 * The address of the data to watch for peaks is stored in the
+	 * variable peak_address (pg. 10). Peak data is lost when executing
+	 * a coordinate transformation or a full scale change. Peak data is
+	 * also lost when plugging in a new sensor.
+	 */
+
+	struct force_array minimum_data;	/* offset 0x00d0 */
+	struct force_array maximum_data;	/* offset 0x00d8 */
+
+	/* Near_sat_value & sat_value contain the value used to determine if
+	 * the raw sensor is saturated. Because of decoupling and offset
+	 * removal, it is difficult to tell from the processed data if the
+	 * sensor is saturated. These values, in conjunction with the error
+	 * and warning words (pg. 14), provide this critical information.
+	 * These two values may be set by the host processor. These values
+	 * are positive signed values, since the saturation logic uses the
+	 * absolute values of the raw data. The near_sat_value defaults to
+	 * approximately 80% of the ADC's full scale, which is 26214, while
+	 * sat_value defaults to the ADC's full scale:
+	 *
+	 *   sat_value = 32768 - 2^(16 - ADC bits)
+	 */
+
+	s32 near_sat_value;	/* offset 0x00e0 */
+	s32 sat_value;	/* offset 0x00e1 */
+
+	/* Rate_address, rate_divisor & rate_count contain the data used to
+	 * control the calculations of the rates. Rate_address is the
+	 * address of the data used for the rate calculation. The JR3 DSP
+	 * will calculate rates for any 8 contiguous values (ex. to
+	 * calculate rates for filter3 data set rate_address to 0x00a8).
+	 * Rate_divisor is how often the rate is calculated. If rate_divisor
+	 * is 1, the rates are calculated at full sensor bandwidth. If
+	 * rate_divisor is 200, rates are calculated every 200 samples.
+	 * Rate_divisor can be any value between 1 and 65536. Set
+	 * rate_divisor to 0 to calculate rates every 65536 samples.
+	 * Rate_count starts at zero and counts until it equals
+	 * rate_divisor, at which point the rates are calculated, and
+	 * rate_count is reset to 0. When setting a new rate divisor, it is
+	 * a good idea to set rate_count to one less than rate divisor. This
+	 * will minimize the time necessary to start the rate calculations.
+	 */
+
+	s32 rate_address;	/* offset 0x00e2 */
+	u32 rate_divisor;	/* offset 0x00e3 */
+	u32 rate_count;	/* offset 0x00e4 */
+
+	/* Command_word2 through command_word0 are the locations used to
+	 * send commands to the JR3 DSP. Their usage varies with the command
+	 * and is detailed later in the Command Definitions section (pg.
+	 * 29). In general the user places values into various memory
+	 * locations, and then places the command word into command_word0.
+	 * The JR3 DSP will process the command and place a 0 into
+	 * command_word0 to indicate successful completion. Alternatively
+	 * the JR3 DSP will place a negative number into command_word0 to
+	 * indicate an error condition. Please note the command locations
+	 * are numbered backwards. (I.E. command_word2 comes before
+	 * command_word1).
+	 */
+
+	s32 command_word2;	/* offset 0x00e5 */
+	s32 command_word1;	/* offset 0x00e6 */
+	s32 command_word0;	/* offset 0x00e7 */
+
+	/* Count1 through count6 are unsigned counters which are incremented
+	 * every time the matching filters are calculated. Filter1 is
+	 * calculated at the sensor data bandwidth. So this counter would
+	 * increment at 8 kHz for a typical sensor. The rest of the counters
+	 * are incremented at 1/4 the interval of the counter immediately
+	 * preceding it, so they would count at 2 kHz, 500 Hz, 125 Hz etc.
+	 * These counters can be used to wait for data. Each time the
+	 * counter changes, the corresponding data set can be sampled, and
+	 * this will insure that the user gets each sample, once, and only
+	 * once.
+	 */
+
+	u32 count1;		/* offset 0x00e8 */
+	u32 count2;		/* offset 0x00e9 */
+	u32 count3;		/* offset 0x00ea */
+	u32 count4;		/* offset 0x00eb */
+	u32 count5;		/* offset 0x00ec */
+	u32 count6;		/* offset 0x00ed */
+
+	/* Error_count is a running count of data reception errors. If this
+	 * counter is changing rapidly, it probably indicates a bad sensor
+	 * cable connection or other hardware problem. In most installations
+	 * error_count should not change at all. But it is possible in an
+	 * extremely noisy environment to experience occasional errors even
+	 * without a hardware problem. If the sensor is well grounded, this
+	 * is probably unavoidable in these environments. On the occasions
+	 * where this counter counts a bad sample, that sample is ignored.
+	 */
+
+	u32 error_count;	/* offset 0x00ee */
+
+	/* Count_x is a counter which is incremented every time the JR3 DSP
+	 * searches its job queues and finds nothing to do. It indicates the
+	 * amount of idle time the JR3 DSP has available. It can also be
+	 * used to determine if the JR3 DSP is alive. See the Performance
+	 * Issues section on pg. 49 for more details.
+	 */
+
+	u32 count_x;	/* offset 0x00ef */
+
+	/* Warnings & errors contain the warning and error bits
+	 * respectively. The format of these two words is discussed on page
+	 * 21 under the headings warnings_bits and error_bits.
+	 */
+
+	u32 warnings;	/* offset 0x00f0 */
+	u32 errors;		/* offset 0x00f1 */
+
+	/* Threshold_bits is a word containing the bits that are set by the
+	 * load envelopes. See load_envelopes (pg. 17) and thresh_struct
+	 * (pg. 23) for more details.
+	 */
+
+	s32 threshold_bits;	/* offset 0x00f2 */
+
+	/* Last_crc is the value that shows the actual calculated CRC. CRC
+	 * is short for cyclic redundancy code. It should be zero. See the
+	 * description for cal_crc_bad (pg. 21) for more information.
+	 */
+
+	s32 last_CRC;	/* offset 0x00f3 */
+
+	/* EEProm_ver_no contains the version number of the sensor EEProm.
+	 * EEProm version numbers can vary between 0 and 255.
+	 * Software_ver_no contains the software version number. Version
+	 * 3.02 would be stored as 302.
+	 */
+
+	s32 eeprom_ver_no;	/* offset 0x00f4 */
+	s32 software_ver_no;	/* offset 0x00f5 */
+
+	/* Software_day & software_year are the release date of the software
+	 * the JR3 DSP is currently running. Day is the day of the year,
+	 * with January 1 being 1, and December 31, being 365 for non leap
+	 * years.
+	 */
+
+	s32 software_day;	/* offset 0x00f6 */
+	s32 software_year;	/* offset 0x00f7 */
+
+	/* Serial_no & model_no are the two values which uniquely identify a
+	 * sensor. This model number does not directly correspond to the JR3
+	 * model number, but it will provide a unique identifier for
+	 * different sensor configurations.
+	 */
+
+	u32 serial_no;	/* offset 0x00f8 */
+	u32 model_no;	/* offset 0x00f9 */
+
+	/* Cal_day & cal_year are the sensor calibration date. Day is the
+	 * day of the year, with January 1 being 1, and December 31, being
+	 * 366 for leap years.
+	 */
+
+	s32 cal_day;	/* offset 0x00fa */
+	s32 cal_year;	/* offset 0x00fb */
+
+	/* Units is an enumerated read only value defining the engineering
+	 * units used in the sensor full scale. The meanings of particular
+	 * values are discussed in the section detailing the force_units
+	 * structure on page 22. The engineering units are setto customer
+	 * specifications during sensor manufacture and cannot be changed by
+	 * writing to Units.
+	 *
+	 * Bits contains the number of bits of resolution of the ADC
+	 * currently in use.
+	 *
+	 * Channels is a bit field showing which channels the current sensor
+	 * is capable of sending. If bit 0 is active, this sensor can send
+	 * channel 0, if bit 13 is active, this sensor can send channel 13,
+	 * etc. This bit can be active, even if the sensor is not currently
+	 * sending this channel. Some sensors are configurable as to which
+	 * channels to send, and this field only contains information on the
+	 * channels available to send, not on the current configuration. To
+	 * find which channels are currently being sent, monitor the
+	 * Raw_time fields (pg. 19) in the raw_channels array (pg. 7). If
+	 * the time is changing periodically, then that channel is being
+	 * received.
+	 */
+
+	u32 units;		/* offset 0x00fc */
+	s32 bits;		/* offset 0x00fd */
+	s32 channels;	/* offset 0x00fe */
+
+	/* Thickness specifies the overall thickness of the sensor from
+	 * flange to flange. The engineering units for this value are
+	 * contained in units (pg. 16). The sensor calibration is relative
+	 * to the center of the sensor. This value allows easy coordinate
+	 * transformation from the center of the sensor to either flange.
+	 */
+
+	s32 thickness;	/* offset 0x00ff */
+
+	/* Load_envelopes is a table containing the load envelope
+	 * descriptions. There are 16 possible load envelope slots in the
+	 * table. The slots are on 16 word boundaries and are numbered 0-15.
+	 * Each load envelope needs to start at the beginning of a slot but
+	 * need not be fully contained in that slot. That is to say that a
+	 * single load envelope can be larger than a single slot. The
+	 * software has been tested and ran satisfactorily with 50
+	 * thresholds active. A single load envelope this large would take
+	 * up 5 of the 16 slots. The load envelope data is laid out in an
+	 * order that is most efficient for the JR3 DSP. The structure is
+	 * detailed later in the section showing the definition of the
+	 * le_struct structure (pg. 23).
+	 */
+
+	struct le_struct load_envelopes[0x10];	/* offset 0x0100 */
+
+	/* Transforms is a table containing the transform descriptions.
+	 * There are 16 possible transform slots in the table. The slots are
+	 * on 16 word boundaries and are numbered 0-15. Each transform needs
+	 * to start at the beginning of a slot but need not be fully
+	 * contained in that slot. That is to say that a single transform
+	 * can be larger than a single slot. A transform is 2 * no of links
+	 * + 1 words in length. So a single slot can contain a transform
+	 * with 7 links. Two slots can contain a transform that is 15 links.
+	 * The layout is detailed later in the section showing the
+	 * definition of the transform structure (pg. 26).
+	 */
+
+	struct intern_transform transforms[0x10];	/* offset 0x0200 */
+};
+
+struct jr3_t {
+	struct {
+		u32 program_low[0x4000];	/*  0x00000 - 0x10000 */
+		struct jr3_channel data;	/*  0x10000 - 0x10c00 */
+		char pad2[0x30000 - 0x00c00];	/*  0x10c00 - 0x40000 */
+		u32 program_high[0x8000];	/*  0x40000 - 0x60000 */
+		u32 reset;	/*  0x60000 - 0x60004 */
+		char pad3[0x20000 - 0x00004];	/*  0x60004 - 0x80000 */
+	} channel[4];
+};
diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c
new file mode 100644
index 0000000..79f6fe5
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ke_counter.c
@@ -0,0 +1,254 @@
+/*
+    comedi/drivers/ke_counter.c
+    Comedi driver for Kolter-Electronic PCI Counter 1 Card
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: ke_counter
+Description: Driver for Kolter Electronic Counter Card
+Devices: [Kolter Electronic] PCI Counter Card (ke_counter)
+Author: Michael Hillmann
+Updated: Mon, 14 Apr 2008 15:42:42 +0100
+Status: tested
+
+Configuration Options:
+  [0] - PCI bus of device (optional)
+  [1] - PCI slot of device (optional)
+  If bus/slot is not specified, the first supported
+  PCI device found will be used.
+
+This driver is a simple driver to read the counter values from
+Kolter Electronic PCI Counter Card.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+#define CNT_DRIVER_NAME         "ke_counter"
+#define PCI_VENDOR_ID_KOLTER    0x1001
+#define CNT_CARD_DEVICE_ID      0x0014
+
+/*-- function prototypes ----------------------------------------------------*/
+
+static int cnt_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int cnt_detach(struct comedi_device * dev);
+
+static DEFINE_PCI_DEVICE_TABLE(cnt_pci_table) = {
+	{PCI_VENDOR_ID_KOLTER, CNT_CARD_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, cnt_pci_table);
+
+/*-- board specification structure ------------------------------------------*/
+
+struct cnt_board_struct {
+
+	const char *name;
+	int device_id;
+	int cnt_channel_nbr;
+	int cnt_bits;
+};
+
+
+static const struct cnt_board_struct cnt_boards[] = {
+	{
+	      name:	CNT_DRIVER_NAME,
+	      device_id:CNT_CARD_DEVICE_ID,
+	      cnt_channel_nbr:3,
+      cnt_bits:24}
+};
+
+#define cnt_board_nbr (sizeof(cnt_boards)/sizeof(struct cnt_board_struct))
+
+/*-- device private structure -----------------------------------------------*/
+
+struct cnt_device_private {
+
+	struct pci_dev *pcidev;
+};
+
+
+#define devpriv ((struct cnt_device_private *)dev->private)
+
+static struct comedi_driver cnt_driver = {
+      driver_name:CNT_DRIVER_NAME,
+      module:THIS_MODULE,
+      attach:cnt_attach,
+      detach:cnt_detach,
+};
+
+COMEDI_PCI_INITCLEANUP(cnt_driver, cnt_pci_table);
+
+/*-- counter write ----------------------------------------------------------*/
+
+/* This should be used only for resetting the counters; maybe it is better
+   to make a special command 'reset'. */
+static int cnt_winsn(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	int chan = CR_CHAN(insn->chanspec);
+
+	outb((unsigned char)((data[0] >> 24) & 0xff),
+		dev->iobase + chan * 0x20 + 0x10);
+	outb((unsigned char)((data[0] >> 16) & 0xff),
+		dev->iobase + chan * 0x20 + 0x0c);
+	outb((unsigned char)((data[0] >> 8) & 0xff),
+		dev->iobase + chan * 0x20 + 0x08);
+	outb((unsigned char)((data[0] >> 0) & 0xff),
+		dev->iobase + chan * 0x20 + 0x04);
+
+	/* return the number of samples written */
+	return 1;
+}
+
+/*-- counter read -----------------------------------------------------------*/
+
+static int cnt_rinsn(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned char a0, a1, a2, a3, a4;
+	int chan = CR_CHAN(insn->chanspec);
+	int result;
+
+	a0 = inb(dev->iobase + chan * 0x20);
+	a1 = inb(dev->iobase + chan * 0x20 + 0x04);
+	a2 = inb(dev->iobase + chan * 0x20 + 0x08);
+	a3 = inb(dev->iobase + chan * 0x20 + 0x0c);
+	a4 = inb(dev->iobase + chan * 0x20 + 0x10);
+
+	result = (a1 + (a2 * 256) + (a3 * 65536));
+	if (a4 > 0)
+		result = result - s->maxdata;
+
+	*data = (unsigned int) result;
+
+	/* return the number of samples read */
+	return 1;
+}
+
+/*-- attach -----------------------------------------------------------------*/
+
+static int cnt_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *subdevice;
+	struct pci_dev *pci_device;
+	struct cnt_board_struct *board;
+	unsigned long io_base;
+	int error, i;
+
+	/* allocate device private structure */
+	if ((error = alloc_private(dev, sizeof(struct cnt_device_private))) < 0) {
+		return error;
+	}
+
+	/* Probe the device to determine what device in the series it is. */
+	for (pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+		pci_device != NULL;
+		pci_device =
+		pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
+		if (pci_device->vendor == PCI_VENDOR_ID_KOLTER) {
+			for (i = 0; i < cnt_board_nbr; i++) {
+				if (cnt_boards[i].device_id ==
+					pci_device->device) {
+					/* was a particular bus/slot requested? */
+					if ((it->options[0] != 0)
+						|| (it->options[1] != 0)) {
+						/* are we on the wrong bus/slot? */
+						if (pci_device->bus->number !=
+							it->options[0]
+							|| PCI_SLOT(pci_device->
+								devfn) !=
+							it->options[1]) {
+							continue;
+						}
+					}
+
+					dev->board_ptr = cnt_boards + i;
+					board = (struct cnt_board_struct *) dev->
+						board_ptr;
+					goto found;
+				}
+			}
+		}
+	}
+	printk("comedi%d: no supported board found! (req. bus/slot: %d/%d)\n",
+		dev->minor, it->options[0], it->options[1]);
+	return -EIO;
+
+      found:
+	printk("comedi%d: found %s at PCI bus %d, slot %d\n", dev->minor,
+		board->name, pci_device->bus->number,
+		PCI_SLOT(pci_device->devfn));
+	devpriv->pcidev = pci_device;
+	dev->board_name = board->name;
+
+	/* enable PCI device and request regions */
+	if ((error = comedi_pci_enable(pci_device, CNT_DRIVER_NAME)) < 0) {
+		printk("comedi%d: failed to enable PCI device and request regions!\n", dev->minor);
+		return error;
+	}
+
+	/* read register base address [PCI_BASE_ADDRESS #0] */
+	io_base = pci_resource_start(pci_device, 0);
+	dev->iobase = io_base;
+
+	/* allocate the subdevice structures */
+	if ((error = alloc_subdevices(dev, 1)) < 0) {
+		return error;
+	}
+
+	subdevice = dev->subdevices + 0;
+	dev->read_subdev = subdevice;
+
+	subdevice->type = COMEDI_SUBD_COUNTER;
+	subdevice->subdev_flags = SDF_READABLE /* | SDF_COMMON */ ;
+	subdevice->n_chan = board->cnt_channel_nbr;
+	subdevice->maxdata = (1 << board->cnt_bits) - 1;
+	subdevice->insn_read = cnt_rinsn;
+	subdevice->insn_write = cnt_winsn;
+
+	// select 20MHz clock
+	outb(3, dev->iobase + 248);
+
+	// reset all counters
+	outb(0, dev->iobase);
+	outb(0, dev->iobase + 0x20);
+	outb(0, dev->iobase + 0x40);
+
+	printk("comedi%d: " CNT_DRIVER_NAME " attached.\n", dev->minor);
+	return 0;
+}
+
+/*-- detach -----------------------------------------------------------------*/
+
+static int cnt_detach(struct comedi_device * dev)
+{
+	if (devpriv && devpriv->pcidev) {
+		if (dev->iobase) {
+			comedi_pci_disable(devpriv->pcidev);
+		}
+		pci_dev_put(devpriv->pcidev);
+	}
+	printk("comedi%d: " CNT_DRIVER_NAME " remove\n", dev->minor);
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c
index b432aa7..12481a0 100644
--- a/drivers/staging/comedi/drivers/me4000.c
+++ b/drivers/staging/comedi/drivers/me4000.c
@@ -92,7 +92,7 @@
 
 MODULE_DEVICE_TABLE(pci, me4000_pci_table);
 
-static const me4000_board_t me4000_boards[] = {
+static const struct me4000_board me4000_boards[] = {
 	{"ME-4650", 0x4650, {0, 0}, {16, 0, 0, 0}, {4}, {0}},
 
 	{"ME-4660", 0x4660, {0, 0}, {32, 0, 16, 0}, {4}, {3}},
@@ -113,108 +113,108 @@
 	{0},
 };
 
-#define ME4000_BOARD_VERSIONS (sizeof(me4000_boards) / sizeof(me4000_board_t) - 1)
+#define ME4000_BOARD_VERSIONS (sizeof(me4000_boards) / sizeof(struct me4000_board) - 1)
 
 /*-----------------------------------------------------------------------------
   Comedi function prototypes
   ---------------------------------------------------------------------------*/
-static int me4000_attach(comedi_device * dev, comedi_devconfig * it);
-static int me4000_detach(comedi_device * dev);
-static comedi_driver driver_me4000 = {
+static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int me4000_detach(struct comedi_device *dev);
+static struct comedi_driver driver_me4000 = {
       driver_name:"me4000",
-      module:THIS_MODULE,
-      attach:me4000_attach,
-      detach:me4000_detach,
+      module : THIS_MODULE,
+      attach : me4000_attach,
+      detach : me4000_detach,
 };
 
 /*-----------------------------------------------------------------------------
   Meilhaus function prototypes
   ---------------------------------------------------------------------------*/
-static int me4000_probe(comedi_device * dev, comedi_devconfig * it);
-static int get_registers(comedi_device * dev, struct pci_dev *pci_dev_p);
-static int init_board_info(comedi_device * dev, struct pci_dev *pci_dev_p);
-static int init_ao_context(comedi_device * dev);
-static int init_ai_context(comedi_device * dev);
-static int init_dio_context(comedi_device * dev);
-static int init_cnt_context(comedi_device * dev);
-static int xilinx_download(comedi_device * dev);
-static int reset_board(comedi_device * dev);
+static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it);
+static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p);
+static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p);
+static int init_ao_context(struct comedi_device *dev);
+static int init_ai_context(struct comedi_device *dev);
+static int init_dio_context(struct comedi_device *dev);
+static int init_cnt_context(struct comedi_device *dev);
+static int xilinx_download(struct comedi_device *dev);
+static int reset_board(struct comedi_device *dev);
 
-static int me4000_dio_insn_bits(comedi_device * dev,
-	comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
+static int me4000_dio_insn_bits(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
 
-static int me4000_dio_insn_config(comedi_device * dev,
-	comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
+static int me4000_dio_insn_config(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
 
-static int cnt_reset(comedi_device * dev, unsigned int channel);
+static int cnt_reset(struct comedi_device *dev, unsigned int channel);
 
-static int cnt_config(comedi_device * dev,
+static int cnt_config(struct comedi_device *dev,
 	unsigned int channel, unsigned int mode);
 
-static int me4000_cnt_insn_config(comedi_device * dev,
-	comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
+static int me4000_cnt_insn_config(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
 
-static int me4000_cnt_insn_write(comedi_device * dev,
-	comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
+static int me4000_cnt_insn_write(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
 
-static int me4000_cnt_insn_read(comedi_device * dev,
-	comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
+static int me4000_cnt_insn_read(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
 
-static int me4000_ai_insn_read(comedi_device * dev,
-	comedi_subdevice * subdevice, comedi_insn * insn, lsampl_t * data);
+static int me4000_ai_insn_read(struct comedi_device *dev,
+	struct comedi_subdevice *subdevice, struct comedi_insn *insn, unsigned int *data);
 
-static int me4000_ai_cancel(comedi_device * dev, comedi_subdevice * s);
+static int me4000_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
 
-static int ai_check_chanlist(comedi_device * dev,
-	comedi_subdevice * s, comedi_cmd * cmd);
+static int ai_check_chanlist(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_cmd *cmd);
 
-static int ai_round_cmd_args(comedi_device * dev,
-	comedi_subdevice * s,
-	comedi_cmd * cmd,
+static int ai_round_cmd_args(struct comedi_device *dev,
+	struct comedi_subdevice *s,
+	struct comedi_cmd *cmd,
 	unsigned int *init_ticks,
 	unsigned int *scan_ticks, unsigned int *chan_ticks);
 
-static int ai_prepare(comedi_device * dev,
-	comedi_subdevice * s,
-	comedi_cmd * cmd,
+static int ai_prepare(struct comedi_device *dev,
+	struct comedi_subdevice *s,
+	struct comedi_cmd *cmd,
 	unsigned int init_ticks,
 	unsigned int scan_ticks, unsigned int chan_ticks);
 
-static int ai_write_chanlist(comedi_device * dev,
-	comedi_subdevice * s, comedi_cmd * cmd);
+static int ai_write_chanlist(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_cmd *cmd);
 
 static irqreturn_t me4000_ai_isr(int irq, void *dev_id PT_REGS_ARG);
 
-static int me4000_ai_do_cmd_test(comedi_device * dev,
-	comedi_subdevice * s, comedi_cmd * cmd);
+static int me4000_ai_do_cmd_test(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_cmd *cmd);
 
-static int me4000_ai_do_cmd(comedi_device * dev, comedi_subdevice * s);
+static int me4000_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
 
-static int me4000_ao_insn_write(comedi_device * dev,
-	comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
+static int me4000_ao_insn_write(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
 
-static int me4000_ao_insn_read(comedi_device * dev,
-	comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
+static int me4000_ao_insn_read(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
 
 /*-----------------------------------------------------------------------------
   Meilhaus inline functions
   ---------------------------------------------------------------------------*/
 
-static inline void me4000_outb(comedi_device * dev, unsigned char value,
+static inline void me4000_outb(struct comedi_device *dev, unsigned char value,
 	unsigned long port)
 {
 	PORT_PDEBUG("--> 0x%02X port 0x%04lX\n", value, port);
 	outb(value, port);
 }
 
-static inline void me4000_outl(comedi_device * dev, unsigned long value,
+static inline void me4000_outl(struct comedi_device *dev, unsigned long value,
 	unsigned long port)
 {
 	PORT_PDEBUG("--> 0x%08lX port 0x%04lX\n", value, port);
 	outl(value, port);
 }
 
-static inline unsigned long me4000_inl(comedi_device * dev, unsigned long port)
+static inline unsigned long me4000_inl(struct comedi_device *dev, unsigned long port)
 {
 	unsigned long value;
 	value = inl(port);
@@ -222,7 +222,7 @@
 	return value;
 }
 
-static inline unsigned char me4000_inb(comedi_device * dev, unsigned long port)
+static inline unsigned char me4000_inb(struct comedi_device *dev, unsigned long port)
 {
 	unsigned char value;
 	value = inb(port);
@@ -230,7 +230,7 @@
 	return value;
 }
 
-static const comedi_lrange me4000_ai_range = {
+static const struct comedi_lrange me4000_ai_range = {
 	4,
 	{
 			UNI_RANGE(2.5),
@@ -240,16 +240,16 @@
 		}
 };
 
-static const comedi_lrange me4000_ao_range = {
+static const struct comedi_lrange me4000_ao_range = {
 	1,
 	{
 			BIP_RANGE(10),
 		}
 };
 
-static int me4000_attach(comedi_device * dev, comedi_devconfig * it)
+static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
-	comedi_subdevice *s;
+	struct comedi_subdevice *s;
 	int result;
 
 	CALL_PDEBUG("In me4000_attach()\n");
@@ -277,7 +277,7 @@
 		s->subdev_flags =
 			SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
 		s->n_chan = thisboard->ai.count;
-		s->maxdata = 0xFFFF;	// 16 bit ADC
+		s->maxdata = 0xFFFF;	/*  16 bit ADC */
 		s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT;
 		s->range_table = &me4000_ai_range;
 		s->insn_read = me4000_ai_insn_read;
@@ -312,7 +312,7 @@
 		s->type = COMEDI_SUBD_AO;
 		s->subdev_flags = SDF_WRITEABLE | SDF_COMMON | SDF_GROUND;
 		s->n_chan = thisboard->ao.count;
-		s->maxdata = 0xFFFF;	// 16 bit DAC
+		s->maxdata = 0xFFFF;	/*  16 bit DAC */
 		s->range_table = &me4000_ao_range;
 		s->insn_write = me4000_ao_insn_write;
 		s->insn_read = me4000_ao_insn_read;
@@ -358,7 +358,7 @@
 		s->type = COMEDI_SUBD_COUNTER;
 		s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
 		s->n_chan = thisboard->cnt.count;
-		s->maxdata = 0xFFFF;	// 16 bit counters
+		s->maxdata = 0xFFFF;	/*  16 bit counters */
 		s->insn_read = me4000_cnt_insn_read;
 		s->insn_write = me4000_cnt_insn_write;
 		s->insn_config = me4000_cnt_insn_config;
@@ -369,18 +369,18 @@
 	return 0;
 }
 
-static int me4000_probe(comedi_device * dev, comedi_devconfig * it)
+static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it)
 {
 	struct pci_dev *pci_device;
 	int result, i;
-	me4000_board_t *board;
+	struct me4000_board *board;
 
 	CALL_PDEBUG("In me4000_probe()\n");
 
 	/* Allocate private memory */
-	if (alloc_private(dev, sizeof(me4000_info_t)) < 0) {
+	if (alloc_private(dev, sizeof(struct me4000_info)) < 0)
 		return -ENOMEM;
-	}
+
 	/*
 	 * Probe the device to determine what device in the series it is.
 	 */
@@ -405,7 +405,7 @@
 						}
 					}
 					dev->board_ptr = me4000_boards + i;
-					board = (me4000_board_t *) dev->
+					board = (struct me4000_board *) dev->
 						board_ptr;
 					info->pci_dev_p = pci_device;
 					goto found;
@@ -512,7 +512,7 @@
 	return 0;
 }
 
-static int get_registers(comedi_device * dev, struct pci_dev *pci_dev_p)
+static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p)
 {
 
 	CALL_PDEBUG("In get_registers()\n");
@@ -564,27 +564,25 @@
 	return 0;
 }
 
-static int init_board_info(comedi_device * dev, struct pci_dev *pci_dev_p)
+static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p)
 {
 	int result;
 
 	CALL_PDEBUG("In init_board_info()\n");
 
 	/* Init spin locks */
-	//spin_lock_init(&info->preload_lock);
-	//spin_lock_init(&info->ai_ctrl_lock);
+	/* spin_lock_init(&info->preload_lock); */
+	/* spin_lock_init(&info->ai_ctrl_lock); */
 
 	/* Get the serial number */
 	result = pci_read_config_dword(pci_dev_p, 0x2C, &info->serial_no);
-	if (result != PCIBIOS_SUCCESSFUL) {
+	if (result != PCIBIOS_SUCCESSFUL)
 		return result;
-	}
 
 	/* Get the hardware revision */
 	result = pci_read_config_byte(pci_dev_p, 0x08, &info->hw_revision);
-	if (result != PCIBIOS_SUCCESSFUL) {
+	if (result != PCIBIOS_SUCCESSFUL)
 		return result;
-	}
 
 	/* Get the vendor id */
 	info->vendor_id = pci_dev_p->vendor;
@@ -598,14 +596,14 @@
 	return 0;
 }
 
-static int init_ao_context(comedi_device * dev)
+static int init_ao_context(struct comedi_device *dev)
 {
 	int i;
 
 	CALL_PDEBUG("In init_ao_context()\n");
 
 	for (i = 0; i < thisboard->ao.count; i++) {
-		//spin_lock_init(&info->ao_context[i].use_lock);
+		/* spin_lock_init(&info->ao_context[i].use_lock); */
 		info->ao_context[i].irq = info->irq;
 
 		switch (i) {
@@ -681,7 +679,7 @@
 	return 0;
 }
 
-static int init_ai_context(comedi_device * dev)
+static int init_ai_context(struct comedi_device *dev)
 {
 
 	CALL_PDEBUG("In init_ai_context()\n");
@@ -715,7 +713,7 @@
 	return 0;
 }
 
-static int init_dio_context(comedi_device * dev)
+static int init_dio_context(struct comedi_device *dev)
 {
 
 	CALL_PDEBUG("In init_dio_context()\n");
@@ -734,7 +732,7 @@
 	return 0;
 }
 
-static int init_cnt_context(comedi_device * dev)
+static int init_cnt_context(struct comedi_device *dev)
 {
 
 	CALL_PDEBUG("In init_cnt_context()\n");
@@ -755,7 +753,7 @@
 extern unsigned char *xilinx_firm;
 #endif
 
-static int xilinx_download(comedi_device * dev)
+static int xilinx_download(struct comedi_device *dev)
 {
 	u32 value = 0;
 	wait_queue_head_t queue;
@@ -782,7 +780,7 @@
 
 	/* Wait until /INIT pin is set */
 	udelay(20);
-	if (!inl(info->plx_regbase + PLX_INTCSR) & 0x20) {
+	if (!(inl(info->plx_regbase + PLX_INTCSR) & 0x20)) {
 		printk(KERN_ERR
 			"comedi%d: me4000: xilinx_download(): Can't init Xilinx\n",
 			dev->minor);
@@ -837,7 +835,7 @@
 	return 0;
 }
 
-static int reset_board(comedi_device * dev)
+static int reset_board(struct comedi_device *dev)
 {
 	unsigned long icr;
 
@@ -895,16 +893,15 @@
 	return 0;
 }
 
-static int me4000_detach(comedi_device * dev)
+static int me4000_detach(struct comedi_device *dev)
 {
 	CALL_PDEBUG("In me4000_detach()\n");
 
 	if (info) {
 		if (info->pci_dev_p) {
 			reset_board(dev);
-			if (info->plx_regbase) {
+			if (info->plx_regbase)
 				comedi_pci_disable(info->pci_dev_p);
-			}
 			pci_dev_put(info->pci_dev_p);
 		}
 	}
@@ -916,8 +913,8 @@
   Analog input section
   ===========================================================================*/
 
-static int me4000_ai_insn_read(comedi_device * dev,
-	comedi_subdevice * subdevice, comedi_insn * insn, lsampl_t * data)
+static int me4000_ai_insn_read(struct comedi_device *dev,
+	struct comedi_subdevice *subdevice, struct comedi_insn *insn, unsigned int *data)
 {
 
 	int chan = CR_CHAN(insn->chanspec);
@@ -1040,7 +1037,7 @@
 	return 1;
 }
 
-static int me4000_ai_cancel(comedi_device * dev, comedi_subdevice * s)
+static int me4000_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	unsigned long tmp;
 
@@ -1057,8 +1054,8 @@
 	return 0;
 }
 
-static int ai_check_chanlist(comedi_device * dev,
-	comedi_subdevice * s, comedi_cmd * cmd)
+static int ai_check_chanlist(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	int aref;
 	int i;
@@ -1138,9 +1135,9 @@
 	return 0;
 }
 
-static int ai_round_cmd_args(comedi_device * dev,
-	comedi_subdevice * s,
-	comedi_cmd * cmd,
+static int ai_round_cmd_args(struct comedi_device *dev,
+	struct comedi_subdevice *s,
+	struct comedi_cmd *cmd,
 	unsigned int *init_ticks,
 	unsigned int *scan_ticks, unsigned int *chan_ticks)
 {
@@ -1163,9 +1160,8 @@
 		rest = (cmd->start_arg * 33) % 1000;
 
 		if (cmd->flags & TRIG_ROUND_NEAREST) {
-			if (rest > 33) {
+			if (rest > 33)
 				(*init_ticks)++;
-			}
 		} else if (cmd->flags & TRIG_ROUND_UP) {
 			if (rest)
 				(*init_ticks)++;
@@ -1177,9 +1173,8 @@
 		rest = (cmd->scan_begin_arg * 33) % 1000;
 
 		if (cmd->flags & TRIG_ROUND_NEAREST) {
-			if (rest > 33) {
+			if (rest > 33)
 				(*scan_ticks)++;
-			}
 		} else if (cmd->flags & TRIG_ROUND_UP) {
 			if (rest)
 				(*scan_ticks)++;
@@ -1191,9 +1186,8 @@
 		rest = (cmd->convert_arg * 33) % 1000;
 
 		if (cmd->flags & TRIG_ROUND_NEAREST) {
-			if (rest > 33) {
+			if (rest > 33)
 				(*chan_ticks)++;
-			}
 		} else if (cmd->flags & TRIG_ROUND_UP) {
 			if (rest)
 				(*chan_ticks)++;
@@ -1207,7 +1201,7 @@
 	return 0;
 }
 
-static void ai_write_timer(comedi_device * dev,
+static void ai_write_timer(struct comedi_device *dev,
 	unsigned int init_ticks,
 	unsigned int scan_ticks, unsigned int chan_ticks)
 {
@@ -1228,9 +1222,9 @@
 	me4000_outl(dev, chan_ticks - 1, info->ai_context.chan_timer_reg);
 }
 
-static int ai_prepare(comedi_device * dev,
-	comedi_subdevice * s,
-	comedi_cmd * cmd,
+static int ai_prepare(struct comedi_device *dev,
+	struct comedi_subdevice *s,
+	struct comedi_cmd *cmd,
 	unsigned int init_ticks,
 	unsigned int scan_ticks, unsigned int chan_ticks)
 {
@@ -1297,8 +1291,8 @@
 	return 0;
 }
 
-static int ai_write_chanlist(comedi_device * dev,
-	comedi_subdevice * s, comedi_cmd * cmd)
+static int ai_write_chanlist(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	unsigned int entry;
 	unsigned int chan;
@@ -1337,13 +1331,13 @@
 	return 0;
 }
 
-static int me4000_ai_do_cmd(comedi_device * dev, comedi_subdevice * s)
+static int me4000_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	int err;
 	unsigned int init_ticks = 0;
 	unsigned int scan_ticks = 0;
 	unsigned int chan_ticks = 0;
-	comedi_cmd *cmd = &s->async->cmd;
+	struct comedi_cmd *cmd = &s->async->cmd;
 
 	CALL_PDEBUG("In me4000_ai_do_cmd()\n");
 
@@ -1381,8 +1375,8 @@
  * - invalid chanlist
  * So I tried to adopt this scheme.
  */
-static int me4000_ai_do_cmd_test(comedi_device * dev,
-	comedi_subdevice * s, comedi_cmd * cmd)
+static int me4000_ai_do_cmd_test(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 
 	unsigned int init_ticks;
@@ -1503,9 +1497,8 @@
 		cmd->stop_src = TRIG_NONE;
 		err++;
 	}
-	if (err) {
+	if (err)
 		return 1;
-	}
 
 	/*
 	 * Stage 2. Check for trigger source conflicts.
@@ -1553,9 +1546,8 @@
 		cmd->scan_end_src = TRIG_NONE;
 		err++;
 	}
-	if (err) {
+	if (err)
 		return 2;
-	}
 
 	/*
 	 * Stage 3. Check if arguments are generally valid.
@@ -1588,9 +1580,9 @@
 		cmd->convert_arg = 2000;
 		err++;
 	}
-	if (err) {
+
+	if (err)
 		return 3;
-	}
 
 	/*
 	 * Stage 4. Check for argument conflicts.
@@ -1604,21 +1596,21 @@
 			printk(KERN_ERR
 				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
 				dev->minor);
-			cmd->start_arg = 2000;	// 66 ticks at least
+			cmd->start_arg = 2000;	/*  66 ticks at least */
 			err++;
 		}
 		if (chan_ticks < ME4000_AI_MIN_TICKS) {
 			printk(KERN_ERR
 				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
 				dev->minor);
-			cmd->convert_arg = 2000;	// 66 ticks at least
+			cmd->convert_arg = 2000;	/*  66 ticks at least */
 			err++;
 		}
 		if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
 			printk(KERN_ERR
 				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n",
 				dev->minor);
-			cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;	// At least one tick more
+			cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;	/*  At least one tick more */
 			err++;
 		}
 	} else if (cmd->start_src == TRIG_NOW &&
@@ -1630,14 +1622,14 @@
 			printk(KERN_ERR
 				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
 				dev->minor);
-			cmd->start_arg = 2000;	// 66 ticks at least
+			cmd->start_arg = 2000;	/*  66 ticks at least */
 			err++;
 		}
 		if (chan_ticks < ME4000_AI_MIN_TICKS) {
 			printk(KERN_ERR
 				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
 				dev->minor);
-			cmd->convert_arg = 2000;	// 66 ticks at least
+			cmd->convert_arg = 2000;	/*  66 ticks at least */
 			err++;
 		}
 	} else if (cmd->start_src == TRIG_EXT &&
@@ -1649,21 +1641,21 @@
 			printk(KERN_ERR
 				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
 				dev->minor);
-			cmd->start_arg = 2000;	// 66 ticks at least
+			cmd->start_arg = 2000;	/*  66 ticks at least */
 			err++;
 		}
 		if (chan_ticks < ME4000_AI_MIN_TICKS) {
 			printk(KERN_ERR
 				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
 				dev->minor);
-			cmd->convert_arg = 2000;	// 66 ticks at least
+			cmd->convert_arg = 2000;	/*  66 ticks at least */
 			err++;
 		}
 		if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
 			printk(KERN_ERR
 				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n",
 				dev->minor);
-			cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;	// At least one tick more
+			cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31;	/*  At least one tick more */
 			err++;
 		}
 	} else if (cmd->start_src == TRIG_EXT &&
@@ -1675,14 +1667,14 @@
 			printk(KERN_ERR
 				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
 				dev->minor);
-			cmd->start_arg = 2000;	// 66 ticks at least
+			cmd->start_arg = 2000;	/*  66 ticks at least */
 			err++;
 		}
 		if (chan_ticks < ME4000_AI_MIN_TICKS) {
 			printk(KERN_ERR
 				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
 				dev->minor);
-			cmd->convert_arg = 2000;	// 66 ticks at least
+			cmd->convert_arg = 2000;	/*  66 ticks at least */
 			err++;
 		}
 	} else if (cmd->start_src == TRIG_EXT &&
@@ -1694,14 +1686,14 @@
 			printk(KERN_ERR
 				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
 				dev->minor);
-			cmd->start_arg = 2000;	// 66 ticks at least
+			cmd->start_arg = 2000;	/*  66 ticks at least */
 			err++;
 		}
 		if (chan_ticks < ME4000_AI_MIN_TICKS) {
 			printk(KERN_ERR
 				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
 				dev->minor);
-			cmd->convert_arg = 2000;	// 66 ticks at least
+			cmd->convert_arg = 2000;	/*  66 ticks at least */
 			err++;
 		}
 	} else if (cmd->start_src == TRIG_EXT &&
@@ -1713,7 +1705,7 @@
 			printk(KERN_ERR
 				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
 				dev->minor);
-			cmd->start_arg = 2000;	// 66 ticks at least
+			cmd->start_arg = 2000;	/*  66 ticks at least */
 			err++;
 		}
 	}
@@ -1735,9 +1727,9 @@
 			err++;
 		}
 	}
-	if (err) {
+
+	if (err)
 		return 4;
-	}
 
 	/*
 	 * Stage 5. Check the channel list.
@@ -1751,9 +1743,9 @@
 static irqreturn_t me4000_ai_isr(int irq, void *dev_id PT_REGS_ARG)
 {
 	unsigned int tmp;
-	comedi_device *dev = dev_id;
-	comedi_subdevice *s = dev->subdevices;
-	me4000_ai_context_t *ai_context = &info->ai_context;
+	struct comedi_device *dev = dev_id;
+	struct comedi_subdevice *s = dev->subdevices;
+	struct me4000_ai_context *ai_context = &info->ai_context;
 	int i;
 	int c = 0;
 	long lval;
@@ -1911,8 +1903,8 @@
   Analog output section
   ===========================================================================*/
 
-static int me4000_ao_insn_write(comedi_device * dev,
-	comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int me4000_ao_insn_write(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
 {
 
 	int chan = CR_CHAN(insn->chanspec);
@@ -1969,8 +1961,8 @@
 	return 1;
 }
 
-static int me4000_ao_insn_read(comedi_device * dev,
-	comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int me4000_ao_insn_read(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
 {
 	int chan = CR_CHAN(insn->chanspec);
 
@@ -1990,16 +1982,16 @@
   Digital I/O section
   ===========================================================================*/
 
-static int me4000_dio_insn_bits(comedi_device * dev,
-	comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int me4000_dio_insn_bits(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
 {
 
 	CALL_PDEBUG("In me4000_dio_insn_bits()\n");
 
 	/* Length of data must be 2 (mask and new data, see below) */
-	if (insn->n == 0) {
+	if (insn->n == 0)
 		return 0;
-	}
+
 	if (insn->n != 2) {
 		printk("comedi%d: me4000: me4000_dio_insn_bits(): Invalid instruction length\n", dev->minor);
 		return -EINVAL;
@@ -2041,8 +2033,8 @@
 	return 2;
 }
 
-static int me4000_dio_insn_config(comedi_device * dev,
-	comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int me4000_dio_insn_config(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
 {
 	unsigned long tmp;
 	int chan = CR_CHAN(insn->chanspec);
@@ -2135,7 +2127,7 @@
   Counter section
   ===========================================================================*/
 
-static int cnt_reset(comedi_device * dev, unsigned int channel)
+static int cnt_reset(struct comedi_device *dev, unsigned int channel)
 {
 
 	CALL_PDEBUG("In cnt_reset()\n");
@@ -2166,7 +2158,7 @@
 	return 0;
 }
 
-static int cnt_config(comedi_device * dev, unsigned int channel,
+static int cnt_config(struct comedi_device *dev, unsigned int channel,
 	unsigned int mode)
 {
 	int tmp = 0;
@@ -2223,8 +2215,8 @@
 	return 0;
 }
 
-static int me4000_cnt_insn_config(comedi_device * dev,
-	comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int me4000_cnt_insn_config(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
 {
 
 	int err;
@@ -2266,17 +2258,17 @@
 	return 2;
 }
 
-static int me4000_cnt_insn_read(comedi_device * dev,
-	comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int me4000_cnt_insn_read(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
 {
 
 	unsigned short tmp;
 
 	CALL_PDEBUG("In me4000_cnt_insn_read()\n");
 
-	if (insn->n == 0) {
+	if (insn->n == 0)
 		return 0;
-	}
+
 	if (insn->n > 1) {
 		printk(KERN_ERR
 			"comedi%d: me4000: me4000_cnt_insn_read(): Invalid instruction length %d\n",
@@ -2313,8 +2305,8 @@
 	return 1;
 }
 
-static int me4000_cnt_insn_write(comedi_device * dev,
-	comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int me4000_cnt_insn_write(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
 {
 
 	unsigned short tmp;
diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h
index f12b887..733b192 100644
--- a/drivers/staging/comedi/drivers/me4000.h
+++ b/drivers/staging/comedi/drivers/me4000.h
@@ -28,37 +28,37 @@
   Debug section
   ===========================================================================*/
 
-#undef ME4000_CALL_DEBUG	// Debug function entry and exit
-#undef ME4000_PORT_DEBUG	// Debug port access
-#undef ME4000_ISR_DEBUG		// Debug the interrupt service routine
-#undef ME4000_DEBUG		// General purpose debug masseges
+#undef ME4000_CALL_DEBUG	/*  Debug function entry and exit */
+#undef ME4000_PORT_DEBUG	/*  Debug port access */
+#undef ME4000_ISR_DEBUG		/*  Debug the interrupt service routine */
+#undef ME4000_DEBUG		/*  General purpose debug masseges */
 
 #ifdef ME4000_CALL_DEBUG
 #undef CALL_PDEBUG
 #define CALL_PDEBUG(fmt, args...) printk(KERN_DEBUG"comedi%d: me4000: " fmt, dev->minor, ##args)
 #else
-# define CALL_PDEBUG(fmt, args...)	// no debugging, do nothing
+# define CALL_PDEBUG(fmt, args...)	/*  no debugging, do nothing */
 #endif
 
 #ifdef ME4000_PORT_DEBUG
 #undef PORT_PDEBUG
 #define PORT_PDEBUG(fmt, args...) printk(KERN_DEBUG"comedi%d: me4000: " fmt, dev->minor,  ##args)
 #else
-#define PORT_PDEBUG(fmt, args...)	// no debugging, do nothing
+#define PORT_PDEBUG(fmt, args...)	/*  no debugging, do nothing */
 #endif
 
 #ifdef ME4000_ISR_DEBUG
 #undef ISR_PDEBUG
 #define ISR_PDEBUG(fmt, args...) printk(KERN_DEBUG"comedi%d: me4000: " fmt, dev->minor,  ##args)
 #else
-#define ISR_PDEBUG(fmt, args...)	// no debugging, do nothing
+#define ISR_PDEBUG(fmt, args...)	/*  no debugging, do nothing */
 #endif
 
 #ifdef ME4000_DEBUG
 #undef PDEBUG
 #define PDEBUG(fmt, args...) printk(KERN_DEBUG"comedi%d: me4000: " fmt, dev->minor,  ##args)
 #else
-#define PDEBUG(fmt, args...)	// no debugging, do nothing
+#define PDEBUG(fmt, args...)	/*  no debugging, do nothing */
 #endif
 
 /*=============================================================================
@@ -67,78 +67,78 @@
 
 #define PCI_VENDOR_ID_MEILHAUS 0x1402
 
-#define PCI_DEVICE_ID_MEILHAUS_ME4650	0x4650	// Low Cost version
+#define PCI_DEVICE_ID_MEILHAUS_ME4650	0x4650	/*  Low Cost version */
 
-#define PCI_DEVICE_ID_MEILHAUS_ME4660	0x4660	// Standard version
-#define PCI_DEVICE_ID_MEILHAUS_ME4660I	0x4661	// Isolated version
-#define PCI_DEVICE_ID_MEILHAUS_ME4660S	0x4662	// Standard version with Sample and Hold
-#define PCI_DEVICE_ID_MEILHAUS_ME4660IS	0x4663	// Isolated version with Sample and Hold
+#define PCI_DEVICE_ID_MEILHAUS_ME4660	0x4660	/*  Standard version */
+#define PCI_DEVICE_ID_MEILHAUS_ME4660I	0x4661	/*  Isolated version */
+#define PCI_DEVICE_ID_MEILHAUS_ME4660S	0x4662	/*  Standard version with Sample and Hold */
+#define PCI_DEVICE_ID_MEILHAUS_ME4660IS	0x4663	/*  Isolated version with Sample and Hold */
 
-#define PCI_DEVICE_ID_MEILHAUS_ME4670	0x4670	// Standard version
-#define PCI_DEVICE_ID_MEILHAUS_ME4670I	0x4671	// Isolated version
-#define PCI_DEVICE_ID_MEILHAUS_ME4670S	0x4672	// Standard version with Sample and Hold
-#define PCI_DEVICE_ID_MEILHAUS_ME4670IS	0x4673	// Isolated version with Sample and Hold
+#define PCI_DEVICE_ID_MEILHAUS_ME4670	0x4670	/*  Standard version */
+#define PCI_DEVICE_ID_MEILHAUS_ME4670I	0x4671	/*  Isolated version */
+#define PCI_DEVICE_ID_MEILHAUS_ME4670S	0x4672	/*  Standard version with Sample and Hold */
+#define PCI_DEVICE_ID_MEILHAUS_ME4670IS	0x4673	/*  Isolated version with Sample and Hold */
 
-#define PCI_DEVICE_ID_MEILHAUS_ME4680	0x4680	// Standard version
-#define PCI_DEVICE_ID_MEILHAUS_ME4680I	0x4681	// Isolated version
-#define PCI_DEVICE_ID_MEILHAUS_ME4680S	0x4682	// Standard version with Sample and Hold
-#define PCI_DEVICE_ID_MEILHAUS_ME4680IS	0x4683	// Isolated version with Sample and Hold
+#define PCI_DEVICE_ID_MEILHAUS_ME4680	0x4680	/*  Standard version */
+#define PCI_DEVICE_ID_MEILHAUS_ME4680I	0x4681	/*  Isolated version */
+#define PCI_DEVICE_ID_MEILHAUS_ME4680S	0x4682	/*  Standard version with Sample and Hold */
+#define PCI_DEVICE_ID_MEILHAUS_ME4680IS	0x4683	/*  Isolated version with Sample and Hold */
 
 /*=============================================================================
   ME-4000 base register offsets
   ===========================================================================*/
 
-#define ME4000_AO_00_CTRL_REG			0x00	// R/W
-#define ME4000_AO_00_STATUS_REG			0x04	// R/_
-#define ME4000_AO_00_FIFO_REG			0x08	// _/W
-#define ME4000_AO_00_SINGLE_REG			0x0C	// R/W
-#define ME4000_AO_00_TIMER_REG			0x10	// _/W
+#define ME4000_AO_00_CTRL_REG			0x00	/*  R/W */
+#define ME4000_AO_00_STATUS_REG			0x04	/*  R/_ */
+#define ME4000_AO_00_FIFO_REG			0x08	/*  _/W */
+#define ME4000_AO_00_SINGLE_REG			0x0C	/*  R/W */
+#define ME4000_AO_00_TIMER_REG			0x10	/*  _/W */
 
-#define ME4000_AO_01_CTRL_REG			0x18	// R/W
-#define ME4000_AO_01_STATUS_REG			0x1C	// R/_
-#define ME4000_AO_01_FIFO_REG			0x20	// _/W
-#define ME4000_AO_01_SINGLE_REG			0x24	// R/W
-#define ME4000_AO_01_TIMER_REG			0x28	// _/W
+#define ME4000_AO_01_CTRL_REG			0x18	/*  R/W */
+#define ME4000_AO_01_STATUS_REG			0x1C	/*  R/_ */
+#define ME4000_AO_01_FIFO_REG			0x20	/*  _/W */
+#define ME4000_AO_01_SINGLE_REG			0x24	/*  R/W */
+#define ME4000_AO_01_TIMER_REG			0x28	/*  _/W */
 
-#define ME4000_AO_02_CTRL_REG			0x30	// R/W
-#define ME4000_AO_02_STATUS_REG			0x34	// R/_
-#define ME4000_AO_02_FIFO_REG			0x38	// _/W
-#define ME4000_AO_02_SINGLE_REG			0x3C	// R/W
-#define ME4000_AO_02_TIMER_REG			0x40	// _/W
+#define ME4000_AO_02_CTRL_REG			0x30	/*  R/W */
+#define ME4000_AO_02_STATUS_REG			0x34	/*  R/_ */
+#define ME4000_AO_02_FIFO_REG			0x38	/*  _/W */
+#define ME4000_AO_02_SINGLE_REG			0x3C	/*  R/W */
+#define ME4000_AO_02_TIMER_REG			0x40	/*  _/W */
 
-#define ME4000_AO_03_CTRL_REG			0x48	// R/W
-#define ME4000_AO_03_STATUS_REG			0x4C	// R/_
-#define ME4000_AO_03_FIFO_REG			0x50	// _/W
-#define ME4000_AO_03_SINGLE_REG			0x54	// R/W
-#define ME4000_AO_03_TIMER_REG			0x58	// _/W
+#define ME4000_AO_03_CTRL_REG			0x48	/*  R/W */
+#define ME4000_AO_03_STATUS_REG			0x4C	/*  R/_ */
+#define ME4000_AO_03_FIFO_REG			0x50	/*  _/W */
+#define ME4000_AO_03_SINGLE_REG			0x54	/*  R/W */
+#define ME4000_AO_03_TIMER_REG			0x58	/*  _/W */
 
-#define ME4000_AI_CTRL_REG			0x74	// _/W
-#define ME4000_AI_STATUS_REG			0x74	// R/_
-#define ME4000_AI_CHANNEL_LIST_REG		0x78	// _/W
-#define ME4000_AI_DATA_REG			0x7C	// R/_
-#define ME4000_AI_CHAN_TIMER_REG		0x80	// _/W
-#define ME4000_AI_CHAN_PRE_TIMER_REG		0x84	// _/W
-#define ME4000_AI_SCAN_TIMER_LOW_REG		0x88	// _/W
-#define ME4000_AI_SCAN_TIMER_HIGH_REG		0x8C	// _/W
-#define ME4000_AI_SCAN_PRE_TIMER_LOW_REG	0x90	// _/W
-#define ME4000_AI_SCAN_PRE_TIMER_HIGH_REG	0x94	// _/W
-#define ME4000_AI_START_REG			0x98	// R/_
+#define ME4000_AI_CTRL_REG			0x74	/*  _/W */
+#define ME4000_AI_STATUS_REG			0x74	/*  R/_ */
+#define ME4000_AI_CHANNEL_LIST_REG		0x78	/*  _/W */
+#define ME4000_AI_DATA_REG			0x7C	/*  R/_ */
+#define ME4000_AI_CHAN_TIMER_REG		0x80	/*  _/W */
+#define ME4000_AI_CHAN_PRE_TIMER_REG		0x84	/*  _/W */
+#define ME4000_AI_SCAN_TIMER_LOW_REG		0x88	/*  _/W */
+#define ME4000_AI_SCAN_TIMER_HIGH_REG		0x8C	/*  _/W */
+#define ME4000_AI_SCAN_PRE_TIMER_LOW_REG	0x90	/*  _/W */
+#define ME4000_AI_SCAN_PRE_TIMER_HIGH_REG	0x94	/*  _/W */
+#define ME4000_AI_START_REG			0x98	/*  R/_ */
 
-#define ME4000_IRQ_STATUS_REG			0x9C	// R/_
+#define ME4000_IRQ_STATUS_REG			0x9C	/*  R/_ */
 
-#define ME4000_DIO_PORT_0_REG			0xA0	// R/W
-#define ME4000_DIO_PORT_1_REG			0xA4	// R/W
-#define ME4000_DIO_PORT_2_REG			0xA8	// R/W
-#define ME4000_DIO_PORT_3_REG			0xAC	// R/W
-#define ME4000_DIO_DIR_REG			0xB0	// R/W
+#define ME4000_DIO_PORT_0_REG			0xA0	/*  R/W */
+#define ME4000_DIO_PORT_1_REG			0xA4	/*  R/W */
+#define ME4000_DIO_PORT_2_REG			0xA8	/*  R/W */
+#define ME4000_DIO_PORT_3_REG			0xAC	/*  R/W */
+#define ME4000_DIO_DIR_REG			0xB0	/*  R/W */
 
-#define ME4000_AO_LOADSETREG_XX			0xB4	// R/W
+#define ME4000_AO_LOADSETREG_XX			0xB4	/*  R/W */
 
-#define ME4000_DIO_CTRL_REG			0xB8	// R/W
+#define ME4000_DIO_CTRL_REG			0xB8	/*  R/W */
 
-#define ME4000_AO_DEMUX_ADJUST_REG		0xBC	// -/W
+#define ME4000_AO_DEMUX_ADJUST_REG		0xBC	/*  -/W */
 
-#define ME4000_AI_SAMPLE_COUNTER_REG		0xC0	// _/W
+#define ME4000_AI_SAMPLE_COUNTER_REG		0xC0	/*  _/W */
 
 /*=============================================================================
   Value to adjust Demux
@@ -159,21 +159,21 @@
   PLX base register offsets
   ===========================================================================*/
 
-#define PLX_INTCSR	0x4C	// Interrupt control and status register
-#define PLX_ICR		0x50	// Initialization control register
+#define PLX_INTCSR	0x4C	/*  Interrupt control and status register */
+#define PLX_ICR		0x50	/*  Initialization control register */
 
 /*=============================================================================
   Bits for the PLX_ICSR register
   ===========================================================================*/
 
-#define PLX_INTCSR_LOCAL_INT1_EN             0x01	// If set, local interrupt 1 is enabled (r/w)
-#define PLX_INTCSR_LOCAL_INT1_POL            0x02	// If set, local interrupt 1 polarity is active high (r/w)
-#define PLX_INTCSR_LOCAL_INT1_STATE          0x04	// If set, local interrupt 1 is active (r/_)
-#define PLX_INTCSR_LOCAL_INT2_EN             0x08	// If set, local interrupt 2 is enabled (r/w)
-#define PLX_INTCSR_LOCAL_INT2_POL            0x10	// If set, local interrupt 2 polarity is active high (r/w)
-#define PLX_INTCSR_LOCAL_INT2_STATE          0x20	// If set, local interrupt 2 is active  (r/_)
-#define PLX_INTCSR_PCI_INT_EN                0x40	// If set, PCI interrupt is enabled (r/w)
-#define PLX_INTCSR_SOFT_INT                  0x80	// If set, a software interrupt is generated (r/w)
+#define PLX_INTCSR_LOCAL_INT1_EN             0x01	/*  If set, local interrupt 1 is enabled (r/w) */
+#define PLX_INTCSR_LOCAL_INT1_POL            0x02	/*  If set, local interrupt 1 polarity is active high (r/w) */
+#define PLX_INTCSR_LOCAL_INT1_STATE          0x04	/*  If set, local interrupt 1 is active (r/_) */
+#define PLX_INTCSR_LOCAL_INT2_EN             0x08	/*  If set, local interrupt 2 is enabled (r/w) */
+#define PLX_INTCSR_LOCAL_INT2_POL            0x10	/*  If set, local interrupt 2 polarity is active high (r/w) */
+#define PLX_INTCSR_LOCAL_INT2_STATE          0x20	/*  If set, local interrupt 2 is active  (r/_) */
+#define PLX_INTCSR_PCI_INT_EN                0x40	/*  If set, PCI interrupt is enabled (r/w) */
+#define PLX_INTCSR_SOFT_INT                  0x80	/*  If set, a software interrupt is generated (r/w) */
 
 /*=============================================================================
   Bits for the PLX_ICR register
@@ -293,45 +293,45 @@
   Information about the hardware capabilities
   ===========================================================================*/
 
-typedef struct me4000_ao_info {
+struct me4000_ao_info {
 	int count;
 	int fifo_count;
-} me4000_ao_info_t;
+};
 
-typedef struct me4000_ai_info {
+struct me4000_ai_info {
 	int count;
 	int sh_count;
 	int diff_count;
 	int ex_trig_analog;
-} me4000_ai_info_t;
+};
 
-typedef struct me4000_dio_info {
+struct me4000_dio_info {
 	int count;
-} me4000_dio_info_t;
+};
 
-typedef struct me4000_cnt_info {
+struct me4000_cnt_info {
 	int count;
-} me4000_cnt_info_t;
+};
 
-typedef struct me4000_board {
+struct me4000_board {
 	const char *name;
 	unsigned short device_id;
-	me4000_ao_info_t ao;
-	me4000_ai_info_t ai;
-	me4000_dio_info_t dio;
-	me4000_cnt_info_t cnt;
-} me4000_board_t;
+	struct me4000_ao_info ao;
+	struct me4000_ai_info ai;
+	struct me4000_dio_info dio;
+	struct me4000_cnt_info cnt;
+};
 
-#define thisboard ((const me4000_board_t *)dev->board_ptr)
+#define thisboard ((const struct me4000_board *)dev->board_ptr)
 
 /*=============================================================================
   Global board and subdevice information structures
   ===========================================================================*/
 
-typedef struct me4000_ao_context {
+struct me4000_ao_context {
 	int irq;
 
-	unsigned long mirror;	// Store the last written value
+	unsigned long mirror;	/*  Store the last written value */
 
 	unsigned long ctrl_reg;
 	unsigned long status_reg;
@@ -340,9 +340,9 @@
 	unsigned long timer_reg;
 	unsigned long irq_status_reg;
 	unsigned long preload_reg;
-} me4000_ao_context_t;
+};
 
-typedef struct me4000_ai_context {
+struct me4000_ai_context {
 	int irq;
 
 	unsigned long ctrl_reg;
@@ -358,51 +358,51 @@
 	unsigned long start_reg;
 	unsigned long irq_status_reg;
 	unsigned long sample_counter_reg;
-} me4000_ai_context_t;
+};
 
-typedef struct me4000_dio_context {
+struct me4000_dio_context {
 	unsigned long dir_reg;
 	unsigned long ctrl_reg;
 	unsigned long port_0_reg;
 	unsigned long port_1_reg;
 	unsigned long port_2_reg;
 	unsigned long port_3_reg;
-} me4000_dio_context_t;
+};
 
-typedef struct me4000_cnt_context {
+struct me4000_cnt_context {
 	unsigned long ctrl_reg;
 	unsigned long counter_0_reg;
 	unsigned long counter_1_reg;
 	unsigned long counter_2_reg;
-} me4000_cnt_context_t;
+};
 
-typedef struct me4000_info {
-	unsigned long plx_regbase;	// PLX configuration space base address
-	unsigned long me4000_regbase;	// Base address of the ME4000
-	unsigned long timer_regbase;	// Base address of the timer circuit
-	unsigned long program_regbase;	// Base address to set the program pin for the xilinx
+struct me4000_info {
+	unsigned long plx_regbase;	/*  PLX configuration space base address */
+	unsigned long me4000_regbase;	/*  Base address of the ME4000 */
+	unsigned long timer_regbase;	/*  Base address of the timer circuit */
+	unsigned long program_regbase;	/*  Base address to set the program pin for the xilinx */
 
-	unsigned long plx_regbase_size;	// PLX register set space
-	unsigned long me4000_regbase_size;	// ME4000 register set space
-	unsigned long timer_regbase_size;	// Timer circuit register set space
-	unsigned long program_regbase_size;	// Size of program base address of the ME4000
+	unsigned long plx_regbase_size;	/*  PLX register set space */
+	unsigned long me4000_regbase_size;	/*  ME4000 register set space */
+	unsigned long timer_regbase_size;	/*  Timer circuit register set space */
+	unsigned long program_regbase_size;	/*  Size of program base address of the ME4000 */
 
-	unsigned int serial_no;	// Serial number of the board
-	unsigned char hw_revision;	// Hardware revision of the board
-	unsigned short vendor_id;	// Meilhaus vendor id
-	unsigned short device_id;	// Device id
+	unsigned int serial_no;	/*  Serial number of the board */
+	unsigned char hw_revision;	/*  Hardware revision of the board */
+	unsigned short vendor_id;	/*  Meilhaus vendor id */
+	unsigned short device_id;	/*  Device id */
 
-	struct pci_dev *pci_dev_p;	// General PCI information
+	struct pci_dev *pci_dev_p;	/*  General PCI information */
 
-	unsigned int irq;	// IRQ assigned from the PCI BIOS
+	unsigned int irq;	/*  IRQ assigned from the PCI BIOS */
 
-	struct me4000_ai_context ai_context;	// Analog input  specific context
-	struct me4000_ao_context ao_context[4];	// Vector with analog output specific context
-	struct me4000_dio_context dio_context;	// Digital I/O specific context
-	struct me4000_cnt_context cnt_context;	// Counter specific context
-} me4000_info_t;
+	struct me4000_ai_context ai_context;	/*  Analog input  specific context */
+	struct me4000_ao_context ao_context[4];	/*  Vector with analog output specific context */
+	struct me4000_dio_context dio_context;	/*  Digital I/O specific context */
+	struct me4000_cnt_context cnt_context;	/*  Counter specific context */
+};
 
-#define info	((me4000_info_t *)dev->private)
+#define info	((struct me4000_info *)dev->private)
 
 /*-----------------------------------------------------------------------------
   Defines for analog input
@@ -412,7 +412,7 @@
 #define ME4000_AI_FIFO_COUNT			2048
 
 #define ME4000_AI_MIN_TICKS			66
-#define ME4000_AI_MIN_SAMPLE_TIME		2000	// Minimum sample time [ns]
+#define ME4000_AI_MIN_SAMPLE_TIME		2000	/*  Minimum sample time [ns] */
 #define ME4000_AI_BASE_FREQUENCY		(unsigned int) 33E6
 
 /* Channel list defines and masks */
@@ -436,11 +436,11 @@
 #define ME4000_CNT_COUNTER_1  0x40
 #define ME4000_CNT_COUNTER_2  0x80
 
-#define ME4000_CNT_MODE_0     0x00	// Change state if zero crossing
-#define ME4000_CNT_MODE_1     0x02	// Retriggerable One-Shot
-#define ME4000_CNT_MODE_2     0x04	// Asymmetrical divider
-#define ME4000_CNT_MODE_3     0x06	// Symmetrical divider
-#define ME4000_CNT_MODE_4     0x08	// Counter start by software trigger
-#define ME4000_CNT_MODE_5     0x0A	// Counter start by hardware trigger
+#define ME4000_CNT_MODE_0     0x00	/*  Change state if zero crossing */
+#define ME4000_CNT_MODE_1     0x02	/*  Retriggerable One-Shot */
+#define ME4000_CNT_MODE_2     0x04	/*  Asymmetrical divider */
+#define ME4000_CNT_MODE_3     0x06	/*  Symmetrical divider */
+#define ME4000_CNT_MODE_4     0x08	/*  Counter start by software trigger */
+#define ME4000_CNT_MODE_5     0x0A	/*  Counter start by hardware trigger */
 
 #endif
diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c
index 6accec2..0f023d00 100644
--- a/drivers/staging/comedi/drivers/me_daq.c
+++ b/drivers/staging/comedi/drivers/me_daq.c
@@ -144,10 +144,10 @@
 #define ME_COUNTER_VALUE_B		0x0022	/* R | - */
 
 /* Function prototypes */
-static int me_attach(comedi_device *dev, comedi_devconfig *it);
-static int me_detach(comedi_device *dev);
+static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int me_detach(struct comedi_device *dev);
 
-static const comedi_lrange me2000_ai_range = {
+static const struct comedi_lrange me2000_ai_range = {
 	8,
 	{
 		BIP_RANGE(10),
@@ -161,7 +161,7 @@
 	}
 };
 
-static const comedi_lrange me2600_ai_range = {
+static const struct comedi_lrange me2600_ai_range = {
 	8,
 	{
 			BIP_RANGE(10),
@@ -175,7 +175,7 @@
 		}
 };
 
-static const comedi_lrange me2600_ao_range = {
+static const struct comedi_lrange me2600_ao_range = {
 	3,
 	{
 			BIP_RANGE(10),
@@ -201,11 +201,11 @@
 	int ao_channel_nbr;	/* DA config */
 	int ao_resolution;
 	int ao_resolution_mask;
-	const comedi_lrange *ao_range_list;
+	const struct comedi_lrange *ao_range_list;
 	int ai_channel_nbr;	/* AD config */
 	int ai_resolution;
 	int ai_resolution_mask;
-	const comedi_lrange *ai_range_list;
+	const struct comedi_lrange *ai_range_list;
 	int dio_channel_nbr;	/* DIO config */
 };
 
@@ -246,7 +246,8 @@
 
 #define me_board_nbr (sizeof(me_boards)/sizeof(struct me_board))
 
-static comedi_driver me_driver = {
+
+static struct comedi_driver me_driver = {
       .driver_name =	ME_DRIVER_NAME,
       .module =		THIS_MODULE,
       .attach =		me_attach,
@@ -290,8 +291,8 @@
  *
  * ------------------------------------------------------------------
  */
-static int me_dio_insn_config(comedi_device *dev, comedi_subdevice *s,
-			      comedi_insn *insn, lsampl_t *data)
+static int me_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+			      struct comedi_insn *insn, unsigned int *data)
 {
 	int bits;
 	int mask = 1 << CR_CHAN(insn->chanspec);
@@ -326,8 +327,8 @@
 }
 
 /* Digital instant input/outputs */
-static int me_dio_insn_bits(comedi_device *dev, comedi_subdevice *s,
-			    comedi_insn *insn, lsampl_t *data)
+static int me_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+			    struct comedi_insn *insn, unsigned int *data)
 {
 	unsigned int mask = data[0];
 	s->state &= ~mask;
@@ -362,8 +363,8 @@
  */
 
 /* Analog instant input */
-static int me_ai_insn_read(comedi_device *dev, comedi_subdevice *subdevice,
-			   comedi_insn *insn, lsampl_t *data)
+static int me_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *subdevice,
+			   struct comedi_insn *insn, unsigned int *data)
 {
 	unsigned short value;
 	int chan = CR_CHAN((&insn->chanspec)[0]);
@@ -436,7 +437,7 @@
  */
 
 /* Cancel analog input autoscan */
-static int me_ai_cancel(comedi_device *dev, comedi_subdevice *s)
+static int me_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	/* disable interrupts */
 
@@ -448,14 +449,14 @@
 }
 
 /* Test analog input command */
-static int me_ai_do_cmd_test(comedi_device *dev, comedi_subdevice *s,
-			     comedi_cmd *cmd)
+static int me_ai_do_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
+			     struct comedi_cmd *cmd)
 {
 	return 0;
 }
 
 /* Analog input command */
-static int me_ai_do_cmd(comedi_device *dev, comedi_subdevice *subdevice)
+static int me_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *subdevice)
 {
 	return 0;
 }
@@ -469,8 +470,8 @@
  */
 
 /* Analog instant output */
-static int me_ao_insn_write(comedi_device *dev, comedi_subdevice *s,
-			    comedi_insn *insn, lsampl_t *data)
+static int me_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
+			    struct comedi_insn *insn, unsigned int *data)
 {
 	int chan;
 	int rang;
@@ -519,8 +520,8 @@
 }
 
 /* Analog output readback */
-static int me_ao_insn_read(comedi_device *dev, comedi_subdevice *s,
-			   comedi_insn *insn, lsampl_t *data)
+static int me_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+			   struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 
@@ -541,7 +542,7 @@
  */
 
 /* Xilinx firmware download for card: ME-2600i */
-static int me2600_xilinx_download(comedi_device *dev,
+static int me2600_xilinx_download(struct comedi_device *dev,
 				  unsigned char *me2600_firmware,
 				  unsigned int length)
 {
@@ -609,7 +610,7 @@
 }
 
 /* Reset device */
-static int me_reset(comedi_device *dev)
+static int me_reset(struct comedi_device *dev)
 {
 	/* Reset board */
 	writew(0x00, dev_private->me_regbase + ME_CONTROL_1);
@@ -631,10 +632,10 @@
  * - Register PCI device
  * - Declare device driver capability
  */
-static int me_attach(comedi_device *dev, comedi_devconfig *it)
+static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
 	struct pci_dev *pci_device;
-	comedi_subdevice *subdevice;
+	struct comedi_subdevice *subdevice;
 	struct me_board *board;
 	resource_size_t plx_regbase_tmp;
 	unsigned long plx_regbase_size_tmp;
@@ -825,7 +826,7 @@
 }
 
 /* Detach */
-static int me_detach(comedi_device *dev)
+static int me_detach(struct comedi_device *dev)
 {
 	if (dev_private) {
 		if (dev_private->me_regbase) {
diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c
index 9cc5274..ae90177 100644
--- a/drivers/staging/comedi/drivers/mite.c
+++ b/drivers/staging/comedi/drivers/mite.c
@@ -47,7 +47,7 @@
 
 */
 
-//#define USE_KMALLOC
+/* #define USE_KMALLOC */
 
 #include "mite.h"
 
@@ -63,7 +63,7 @@
 
 MODULE_LICENSE("GPL");
 
-struct mite_struct *mite_devices = NULL;
+struct mite_struct *mite_devices;
 
 #define TOP_OF_PAGE(x) ((x)|(~(PAGE_MASK)))
 
@@ -103,7 +103,7 @@
 	printk("mite: num channels = %i, write post fifo depth = %i, wins = %i, iowins = %i\n", mite_csigr_dmac(csigr_bits), mite_csigr_wpdep(csigr_bits), mite_csigr_wins(csigr_bits), mite_csigr_iowins(csigr_bits));
 }
 
-unsigned mite_fifo_size(struct mite_struct * mite, unsigned channel)
+unsigned mite_fifo_size(struct mite_struct *mite, unsigned channel)
 {
 	unsigned fcr_bits = readl(mite->mite_io_addr +
 		MITE_FCR(channel));
@@ -139,7 +139,7 @@
 	addr = pci_resource_start(mite->pcidev, 1);
 	mite->daq_phys_addr = addr;
 	length = pci_resource_len(mite->pcidev, 1);
-	// In case of a 660x board, DAQ size is 8k instead of 4k (see as shown by lspci output)
+	/*  In case of a 660x board, DAQ size is 8k instead of 4k (see as shown by lspci output) */
 	mite->daq_io_addr = ioremap(mite->daq_phys_addr, length);
 	if (!mite->daq_io_addr) {
 		printk("failed to remap daq io memory address\n");
@@ -212,7 +212,7 @@
 
 void mite_unsetup(struct mite_struct *mite)
 {
-	//unsigned long offset, start, length;
+	/* unsigned long offset, start, length; */
 
 	if (!mite)
 		return;
@@ -257,7 +257,7 @@
 	unsigned long flags;
 	struct mite_channel *channel = NULL;
 
-	// spin lock so mite_release_channel can be called safely from interrupts
+	/*  spin lock so mite_release_channel can be called safely from interrupts */
 	comedi_spin_lock_irqsave(&mite->lock, flags);
 	for (i = min_channel; i <= max_channel; ++i) {
 		if (mite->channel_allocated[i] == 0) {
@@ -276,7 +276,7 @@
 	struct mite_struct *mite = mite_chan->mite;
 	unsigned long flags;
 
-	// spin lock to prevent races with mite_request_channel
+	/*  spin lock to prevent races with mite_request_channel */
 	comedi_spin_lock_irqsave(&mite->lock, flags);
 	if (mite->channel_allocated[mite_chan->channel]) {
 		mite_dma_disarm(mite_chan);
@@ -312,12 +312,12 @@
 	writel(chor, mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
 	mmiowb();
 	comedi_spin_unlock_irqrestore(&mite->lock, flags);
-//      mite_dma_tcr(mite, channel);
+/*       mite_dma_tcr(mite, channel); */
 }
 
 /**************************************/
 
-int mite_buf_change(struct mite_dma_descriptor_ring *ring, comedi_async * async)
+int mite_buf_change(struct mite_dma_descriptor_ring *ring, struct comedi_async * async)
 {
 	unsigned int n_links;
 	int i;
@@ -331,9 +331,9 @@
 	ring->descriptors_dma_addr = 0;
 	ring->n_links = 0;
 
-	if (async->prealloc_bufsz == 0) {
+	if (async->prealloc_bufsz == 0)
 		return 0;
-	}
+
 	n_links = async->prealloc_bufsz >> PAGE_SHIFT;
 
 	MDPRINTK("ring->hw_dev=%p, n_links=0x%04x\n", ring->hw_dev, n_links);
@@ -395,9 +395,9 @@
 		   on e-series boards.  */
 		chcr |= CHCR_BYTE_SWAP_DEVICE | CHCR_BYTE_SWAP_MEMORY;
 	}
-	if (mite_chan->dir == COMEDI_INPUT) {
+	if (mite_chan->dir == COMEDI_INPUT)
 		chcr |= CHCR_DEV_TO_MEM;
-	}
+
 	writel(chcr, mite->mite_io_addr + MITE_CHCR(mite_chan->channel));
 
 	/* to/from memory */
@@ -459,15 +459,15 @@
 	return readl(mite->mite_io_addr + MITE_DAR(mite_chan->channel));
 }
 
-u32 mite_bytes_in_transit(struct mite_channel * mite_chan)
+u32 mite_bytes_in_transit(struct mite_channel *mite_chan)
 {
 	struct mite_struct *mite = mite_chan->mite;
 	return readl(mite->mite_io_addr +
 		MITE_FCR(mite_chan->channel)) & 0x000000FF;
 }
 
-// returns lower bound for number of bytes transferred from device to memory
-u32 mite_bytes_written_to_memory_lb(struct mite_channel * mite_chan)
+/*  returns lower bound for number of bytes transferred from device to memory */
+u32 mite_bytes_written_to_memory_lb(struct mite_channel *mite_chan)
 {
 	u32 device_byte_count;
 
@@ -475,8 +475,8 @@
 	return device_byte_count - mite_bytes_in_transit(mite_chan);
 }
 
-// returns upper bound for number of bytes transferred from device to memory
-u32 mite_bytes_written_to_memory_ub(struct mite_channel * mite_chan)
+/*  returns upper bound for number of bytes transferred from device to memory */
+u32 mite_bytes_written_to_memory_ub(struct mite_channel *mite_chan)
 {
 	u32 in_transit_count;
 
@@ -484,8 +484,8 @@
 	return mite_device_bytes_transferred(mite_chan) - in_transit_count;
 }
 
-// returns lower bound for number of bytes read from memory for transfer to device
-u32 mite_bytes_read_from_memory_lb(struct mite_channel * mite_chan)
+/*  returns lower bound for number of bytes read from memory for transfer to device */
+u32 mite_bytes_read_from_memory_lb(struct mite_channel *mite_chan)
 {
 	u32 device_byte_count;
 
@@ -493,8 +493,8 @@
 	return device_byte_count + mite_bytes_in_transit(mite_chan);
 }
 
-// returns upper bound for number of bytes read from memory for transfer to device
-u32 mite_bytes_read_from_memory_ub(struct mite_channel * mite_chan)
+/*  returns upper bound for number of bytes read from memory for transfer to device */
+u32 mite_bytes_read_from_memory_ub(struct mite_channel *mite_chan)
 {
 	u32 in_transit_count;
 
@@ -526,14 +526,14 @@
 	writel(chor, mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
 }
 
-int mite_sync_input_dma(struct mite_channel *mite_chan, comedi_async * async)
+int mite_sync_input_dma(struct mite_channel *mite_chan, struct comedi_async * async)
 {
 	int count;
 	unsigned int nbytes, old_alloc_count;
 	const unsigned bytes_per_scan = cfc_bytes_per_scan(async->subdevice);
 
 	old_alloc_count = async->buf_write_alloc_count;
-	// write alloc as much as we can
+	/*  write alloc as much as we can */
 	comedi_buf_write_alloc(async, async->prealloc_bufsz);
 
 	nbytes = mite_bytes_written_to_memory_lb(mite_chan);
@@ -547,9 +547,9 @@
 	count = nbytes - async->buf_write_count;
 	/* it's possible count will be negative due to
 	 * conservative value returned by mite_bytes_written_to_memory_lb */
-	if (count <= 0) {
+	if (count <= 0)
 		return 0;
-	}
+
 	comedi_buf_write_free(async, count);
 
 	async->scan_progress += count;
@@ -561,7 +561,7 @@
 	return 0;
 }
 
-int mite_sync_output_dma(struct mite_channel *mite_chan, comedi_async * async)
+int mite_sync_output_dma(struct mite_channel *mite_chan, struct comedi_async * async)
 {
 	int count;
 	u32 nbytes_ub, nbytes_lb;
@@ -570,7 +570,7 @@
 		async->cmd.stop_arg * cfc_bytes_per_scan(async->subdevice);
 
 	old_alloc_count = async->buf_read_alloc_count;
-	// read alloc as much as we can
+	/*  read alloc as much as we can */
 	comedi_buf_read_alloc(async, async->prealloc_bufsz);
 	nbytes_lb = mite_bytes_read_from_memory_lb(mite_chan);
 	if (async->cmd.stop_src == TRIG_COUNT &&
@@ -586,9 +586,9 @@
 		return -1;
 	}
 	count = nbytes_lb - async->buf_read_count;
-	if (count <= 0) {
+	if (count <= 0)
 		return 0;
-	}
+
 	if (count) {
 		comedi_buf_read_free(async, count);
 		async->events |= COMEDI_CB_BLOCK;
@@ -753,9 +753,8 @@
 	int i;
 
 	for (i = 31; i >= 0; i--) {
-		if (bits & (1 << i)) {
+		if (bits & (1 << i))
 			printk(" %s", bit_str[i]);
-		}
 	}
 	printk("\n");
 }
diff --git a/drivers/staging/comedi/drivers/mite.h b/drivers/staging/comedi/drivers/mite.h
index b84eafa..cdaf8a3 100644
--- a/drivers/staging/comedi/drivers/mite.h
+++ b/drivers/staging/comedi/drivers/mite.h
@@ -29,13 +29,13 @@
 
 #define PCI_VENDOR_ID_NATINST		0x1093
 
-// #define DEBUG_MITE
+/*  #define DEBUG_MITE */
 #define PCIMIO_COMPAT
 
 #ifdef DEBUG_MITE
-#define MDPRINTK(format,args...)	printk(format , ## args )
+#define MDPRINTK(format, args...)	printk(format , ## args)
 #else
-#define MDPRINTK(format,args...)
+#define MDPRINTK(format, args...)
 #endif
 
 #define MAX_MITE_DMA_CHANNELS 8
@@ -142,8 +142,8 @@
 unsigned mite_dma_tcr(struct mite_channel *mite_chan);
 void mite_dma_arm(struct mite_channel *mite_chan);
 void mite_dma_disarm(struct mite_channel *mite_chan);
-int mite_sync_input_dma(struct mite_channel *mite_chan, comedi_async * async);
-int mite_sync_output_dma(struct mite_channel *mite_chan, comedi_async * async);
+int mite_sync_input_dma(struct mite_channel *mite_chan, struct comedi_async * async);
+int mite_sync_output_dma(struct mite_channel *mite_chan, struct comedi_async * async);
 u32 mite_bytes_written_to_memory_lb(struct mite_channel *mite_chan);
 u32 mite_bytes_written_to_memory_ub(struct mite_channel *mite_chan);
 u32 mite_bytes_read_from_memory_lb(struct mite_channel *mite_chan);
@@ -153,7 +153,7 @@
 int mite_done(struct mite_channel *mite_chan);
 
 #if 0
-unsigned long mite_ll_from_kvmem(struct mite_struct *mite, comedi_async * async,
+unsigned long mite_ll_from_kvmem(struct mite_struct *mite, struct comedi_async * async,
 	int len);
 void mite_setregs(struct mite_struct *mite, unsigned long ll_start, int chan,
 	int dir);
@@ -162,7 +162,7 @@
 void mite_prep_dma(struct mite_channel *mite_chan,
 	unsigned int num_device_bits, unsigned int num_memory_bits);
 int mite_buf_change(struct mite_dma_descriptor_ring *ring,
-	comedi_async * async);
+	struct comedi_async *async);
 
 #ifdef DEBUG_MITE
 void mite_print_chsr(unsigned int chsr);
@@ -179,83 +179,83 @@
 	   written and read back.  The bits 0x1f always read as 1.
 	   The rest always read as zero. */
 	MITE_UNKNOWN_DMA_BURST_REG = 0x28,
-	MITE_IODWBSR = 0xc0,	//IO Device Window Base Size Register
-	MITE_IODWBSR_1 = 0xc4,	// IO Device Window Base Size Register 1
+	MITE_IODWBSR = 0xc0,	/* IO Device Window Base Size Register */
+	MITE_IODWBSR_1 = 0xc4,	/*  IO Device Window Base Size Register 1 */
 	MITE_IODWCR_1 = 0xf4,
 	MITE_PCI_CONFIG_OFFSET = 0x300,
-	MITE_CSIGR = 0x460	//chip signature
+	MITE_CSIGR = 0x460	/* chip signature */
 };
-static inline int MITE_CHOR(int channel)	// channel operation
+static inline int MITE_CHOR(int channel)	/*  channel operation */
 {
 	return CHAN_OFFSET(channel) + 0x0;
 };
-static inline int MITE_CHCR(int channel)	// channel control
+static inline int MITE_CHCR(int channel)	/*  channel control */
 {
 	return CHAN_OFFSET(channel) + 0x4;
 };
-static inline int MITE_TCR(int channel)	// transfer count
+static inline int MITE_TCR(int channel)	/*  transfer count */
 {
 	return CHAN_OFFSET(channel) + 0x8;
 };
-static inline int MITE_MCR(int channel)	// memory configuration
+static inline int MITE_MCR(int channel)	/*  memory configuration */
 {
 	return CHAN_OFFSET(channel) + 0xc;
 };
-static inline int MITE_MAR(int channel)	// memory address
+static inline int MITE_MAR(int channel)	/*  memory address */
 {
 	return CHAN_OFFSET(channel) + 0x10;
 };
-static inline int MITE_DCR(int channel)	// device configuration
+static inline int MITE_DCR(int channel)	/*  device configuration */
 {
 	return CHAN_OFFSET(channel) + 0x14;
 };
-static inline int MITE_DAR(int channel)	// device address
+static inline int MITE_DAR(int channel)	/*  device address */
 {
 	return CHAN_OFFSET(channel) + 0x18;
 };
-static inline int MITE_LKCR(int channel)	// link configuration
+static inline int MITE_LKCR(int channel)	/*  link configuration */
 {
 	return CHAN_OFFSET(channel) + 0x1c;
 };
-static inline int MITE_LKAR(int channel)	// link address
+static inline int MITE_LKAR(int channel)	/*  link address */
 {
 	return CHAN_OFFSET(channel) + 0x20;
 };
-static inline int MITE_LLKAR(int channel)	// see mite section of tnt5002 manual
+static inline int MITE_LLKAR(int channel)	/*  see mite section of tnt5002 manual */
 {
 	return CHAN_OFFSET(channel) + 0x24;
 };
-static inline int MITE_BAR(int channel)	// base address
+static inline int MITE_BAR(int channel)	/*  base address */
 {
 	return CHAN_OFFSET(channel) + 0x28;
 };
-static inline int MITE_BCR(int channel)	// base count
+static inline int MITE_BCR(int channel)	/*  base count */
 {
 	return CHAN_OFFSET(channel) + 0x2c;
 };
-static inline int MITE_SAR(int channel)	// ? address
+static inline int MITE_SAR(int channel)	/*  ? address */
 {
 	return CHAN_OFFSET(channel) + 0x30;
 };
-static inline int MITE_WSCR(int channel)	// ?
+static inline int MITE_WSCR(int channel)	/*  ? */
 {
 	return CHAN_OFFSET(channel) + 0x34;
 };
-static inline int MITE_WSER(int channel)	// ?
+static inline int MITE_WSER(int channel)	/*  ? */
 {
 	return CHAN_OFFSET(channel) + 0x38;
 };
-static inline int MITE_CHSR(int channel)	// channel status
+static inline int MITE_CHSR(int channel)	/*  channel status */
 {
 	return CHAN_OFFSET(channel) + 0x3c;
 };
-static inline int MITE_FCR(int channel)	// fifo count
+static inline int MITE_FCR(int channel)	/*  fifo count */
 {
 	return CHAN_OFFSET(channel) + 0x40;
 };
 
 enum MITE_IODWBSR_bits {
-	WENAB = 0x80,		// window enable
+	WENAB = 0x80,		/*  window enable */
 };
 
 static inline unsigned MITE_IODWBSR_1_WSIZE_bits(unsigned size)
@@ -276,23 +276,23 @@
 	return csigr_bits & 0xf;
 };
 static inline int mite_csigr_type(u32 csigr_bits)
-{				// original mite = 0, minimite = 1
+{				/*  original mite = 0, minimite = 1 */
 	return (csigr_bits >> 4) & 0xf;
 };
 static inline int mite_csigr_mmode(u32 csigr_bits)
-{				// mite mode, minimite = 1
+{				/*  mite mode, minimite = 1 */
 	return (csigr_bits >> 8) & 0x3;
 };
 static inline int mite_csigr_imode(u32 csigr_bits)
-{				// cpu port interface mode, pci = 0x3
+{				/*  cpu port interface mode, pci = 0x3 */
 	return (csigr_bits >> 12) & 0x3;
 };
 static inline int mite_csigr_dmac(u32 csigr_bits)
-{				// number of dma channels
+{				/*  number of dma channels */
 	return (csigr_bits >> 16) & 0xf;
 };
 static inline int mite_csigr_wpdep(u32 csigr_bits)
-{				// write post fifo depth
+{				/*  write post fifo depth */
 	unsigned int wpdep_bits = (csigr_bits >> 20) & 0x7;
 	if (wpdep_bits == 0)
 		return 0;
@@ -304,7 +304,7 @@
 	return (csigr_bits >> 24) & 0x1f;
 };
 static inline int mite_csigr_iowins(u32 csigr_bits)
-{				// number of io windows
+{				/*  number of io windows */
 	return (csigr_bits >> 29) & 0x7;
 };
 
diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c
new file mode 100644
index 0000000..a151602
--- /dev/null
+++ b/drivers/staging/comedi/drivers/mpc624.c
@@ -0,0 +1,386 @@
+/*
+    comedi/drivers/mpc624.c
+    Hardware driver for a Micro/sys inc. MPC-624 PC/104 board
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: mpc624
+Description: Micro/sys MPC-624 PC/104 board
+Devices: [Micro/sys] MPC-624 (mpc624)
+Author: Stanislaw Raczynski <sraczynski@op.pl>
+Updated: Thu, 15 Sep 2005 12:01:18 +0200
+Status: working
+
+    The Micro/sys MPC-624 board is based on the LTC2440 24-bit sigma-delta
+    ADC chip.
+
+    Subdevices supported by the driver:
+    - Analog In:   supported
+    - Digital I/O: not supported
+    - LEDs:        not supported
+    - EEPROM:      not supported
+
+Configuration Options:
+  [0] - I/O base address
+  [1] - convertion rate
+            Convertion rate  RMS noise  Effective Number Of Bits
+         0      3.52kHz        23uV                17
+         1      1.76kHz       3.5uV                20
+         2       880Hz         2uV                21.3
+         3       440Hz        1.4uV               21.8
+         4       220Hz         1uV                22.4
+         5       110Hz        750uV               22.9
+         6       55Hz         510nV               23.4
+         7      27.5Hz        375nV                24
+         8      13.75Hz       250nV               24.4
+         9      6.875Hz       200nV               24.6
+   [2] - voltage range
+         0      -1.01V .. +1.01V
+         1      -10.1V .. +10.1V
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/delay.h>
+
+// Consecutive I/O port addresses
+#define MPC624_SIZE             16
+
+// Offsets of different ports
+#define MPC624_MASTER_CONTROL	0	// not used
+#define MPC624_GNMUXCH          1	// Gain, Mux, Channel of ADC
+#define MPC624_ADC              2	// read/write to/from ADC
+#define MPC624_EE               3	// read/write to/from serial EEPROM via I2C
+#define MPC624_LEDS             4	// write to LEDs
+#define MPC624_DIO              5	// read/write to/from digital I/O ports
+#define MPC624_IRQ_MASK         6	// IRQ masking enable/disable
+
+// Register bits' names
+#define MPC624_ADBUSY           (1<<5)
+#define MPC624_ADSDO            (1<<4)
+#define MPC624_ADFO             (1<<3)
+#define MPC624_ADCS             (1<<2)
+#define MPC624_ADSCK            (1<<1)
+#define MPC624_ADSDI            (1<<0)
+
+// SDI Speed/Resolution Programming bits
+#define MPC624_OSR4             (1<<31)
+#define MPC624_OSR3             (1<<30)
+#define MPC624_OSR2             (1<<29)
+#define MPC624_OSR1             (1<<28)
+#define MPC624_OSR0             (1<<27)
+
+// 32-bit output value bits' names
+#define MPC624_EOC_BIT          (1<<31)
+#define MPC624_DMY_BIT          (1<<30)
+#define MPC624_SGN_BIT          (1<<29)
+
+// Convertion speeds
+/* OSR4 OSR3 OSR2 OSR1 OSR0  Convertion rate  RMS noise  ENOB^
+ *  X    0    0    0    1        3.52kHz        23uV      17
+ *  X    0    0    1    0        1.76kHz       3.5uV      20
+ *  X    0    0    1    1         880Hz         2uV      21.3
+ *  X    0    1    0    0         440Hz        1.4uV     21.8
+ *  X    0    1    0    1         220Hz         1uV      22.4
+ *  X    0    1    1    0         110Hz        750uV     22.9
+ *  X    0    1    1    1          55Hz        510nV     23.4
+ *  X    1    0    0    0         27.5Hz       375nV      24
+ *  X    1    0    0    1        13.75Hz       250nV     24.4
+ *  X    1    1    1    1        6.875Hz       200nV     24.6
+ *
+ * ^ - Effective Number Of Bits
+ */
+
+#define MPC624_SPEED_3_52_kHz   (MPC624_OSR4                                           | MPC624_OSR0)
+#define MPC624_SPEED_1_76_kHz   (MPC624_OSR4                             | MPC624_OSR1              )
+#define MPC624_SPEED_880_Hz     (MPC624_OSR4                             | MPC624_OSR1 | MPC624_OSR0)
+#define MPC624_SPEED_440_Hz     (MPC624_OSR4               | MPC624_OSR2                            )
+#define MPC624_SPEED_220_Hz     (MPC624_OSR4               | MPC624_OSR2               | MPC624_OSR0)
+#define MPC624_SPEED_110_Hz     (MPC624_OSR4               | MPC624_OSR2 | MPC624_OSR1              )
+#define MPC624_SPEED_55_Hz      (MPC624_OSR4               | MPC624_OSR2 | MPC624_OSR1 | MPC624_OSR0)
+#define MPC624_SPEED_27_5_Hz    (MPC624_OSR4 | MPC624_OSR3                                          )
+#define MPC624_SPEED_13_75_Hz   (MPC624_OSR4 | MPC624_OSR3                             | MPC624_OSR0)
+#define MPC624_SPEED_6_875_Hz   (MPC624_OSR4 | MPC624_OSR3 | MPC624_OSR2 | MPC624_OSR1 | MPC624_OSR0)
+//----------------------------------------------------------------------------
+struct skel_private {
+
+	unsigned long int ulConvertionRate;	// set by mpc624_attach() from driver's parameters
+};
+
+
+#define devpriv ((struct skel_private *)dev->private)
+//----------------------------------------------------------------------------
+static const struct comedi_lrange range_mpc624_bipolar1 = {
+	1,
+	{
+//    BIP_RANGE(1.01) // this is correct,
+			// but my MPC-624 actually seems to have a range of 2.02
+			BIP_RANGE(2.02)
+		}
+};
+static const struct comedi_lrange range_mpc624_bipolar10 = {
+	1,
+	{
+//    BIP_RANGE(10.1) // this is correct,
+			// but my MPC-624 actually seems to have a range of 20.2
+			BIP_RANGE(20.2)
+		}
+};
+
+//----------------------------------------------------------------------------
+static int mpc624_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int mpc624_detach(struct comedi_device * dev);
+//----------------------------------------------------------------------------
+static struct comedi_driver driver_mpc624 = {
+      driver_name:"mpc624",
+      module:THIS_MODULE,
+      attach:mpc624_attach,
+      detach:mpc624_detach
+};
+
+//----------------------------------------------------------------------------
+static int mpc624_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+//----------------------------------------------------------------------------
+static int mpc624_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	unsigned long iobase;
+
+	iobase = it->options[0];
+	rt_printk("comedi%d: mpc624 [0x%04lx, ", dev->minor, iobase);
+	if (request_region(iobase, MPC624_SIZE, "mpc624") == NULL) {
+		rt_printk("I/O port(s) in use\n");
+		return -EIO;
+	}
+
+	dev->iobase = iobase;
+	dev->board_name = "mpc624";
+
+	// Private structure initialization
+	if (alloc_private(dev, sizeof(struct skel_private)) < 0)
+		return -ENOMEM;
+
+	switch (it->options[1]) {
+	case 0:
+		devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz;
+		rt_printk("3.52 kHz, ");
+		break;
+	case 1:
+		devpriv->ulConvertionRate = MPC624_SPEED_1_76_kHz;
+		rt_printk("1.76 kHz, ");
+		break;
+	case 2:
+		devpriv->ulConvertionRate = MPC624_SPEED_880_Hz;
+		rt_printk("880 Hz, ");
+		break;
+	case 3:
+		devpriv->ulConvertionRate = MPC624_SPEED_440_Hz;
+		rt_printk("440 Hz, ");
+		break;
+	case 4:
+		devpriv->ulConvertionRate = MPC624_SPEED_220_Hz;
+		rt_printk("220 Hz, ");
+		break;
+	case 5:
+		devpriv->ulConvertionRate = MPC624_SPEED_110_Hz;
+		rt_printk("110 Hz, ");
+		break;
+	case 6:
+		devpriv->ulConvertionRate = MPC624_SPEED_55_Hz;
+		rt_printk("55 Hz, ");
+		break;
+	case 7:
+		devpriv->ulConvertionRate = MPC624_SPEED_27_5_Hz;
+		rt_printk("27.5 Hz, ");
+		break;
+	case 8:
+		devpriv->ulConvertionRate = MPC624_SPEED_13_75_Hz;
+		rt_printk("13.75 Hz, ");
+		break;
+	case 9:
+		devpriv->ulConvertionRate = MPC624_SPEED_6_875_Hz;
+		rt_printk("6.875 Hz, ");
+		break;
+	default:
+		rt_printk
+			("illegal convertion rate setting! Valid numbers are 0..9. Using 9 => 6.875 Hz, ");
+		devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz;
+	}
+
+	// Subdevices structures
+	if (alloc_subdevices(dev, 1) < 0)
+		return -ENOMEM;
+
+	s = dev->subdevices + 0;
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE | SDF_DIFF;
+	s->n_chan = 8;
+	switch (it->options[1]) {
+	default:
+		s->maxdata = 0x3FFFFFFF;
+		rt_printk("30 bit, ");
+	}
+
+	switch (it->options[1]) {
+	case 0:
+		s->range_table = &range_mpc624_bipolar1;
+		rt_printk("1.01V]: ");
+		break;
+	default:
+		s->range_table = &range_mpc624_bipolar10;
+		rt_printk("10.1V]: ");
+	}
+	s->len_chanlist = 1;
+	s->insn_read = mpc624_ai_rinsn;
+
+	rt_printk("attached\n");
+
+	return 1;
+}
+
+static int mpc624_detach(struct comedi_device * dev)
+{
+	rt_printk("comedi%d: mpc624: remove\n", dev->minor);
+
+	if (dev->iobase)
+		release_region(dev->iobase, MPC624_SIZE);
+
+	return 0;
+}
+
+// Timeout 200ms
+#define TIMEOUT 200
+
+static int mpc624_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n, i;
+	unsigned long int data_in, data_out;
+	unsigned char ucPort;
+
+	// WARNING: We always write 0 to GNSWA bit, so the channel range is +-/10.1Vdc
+	outb(insn->chanspec, dev->iobase + MPC624_GNMUXCH);
+//    rt_printk("Channel %d: \n", insn->chanspec);
+	if (!insn->n) {
+		rt_printk("MPC624: Warning, no data to aquire\n");
+		return 0;
+	}
+
+	for (n = 0; n < insn->n; n++) {
+		// Trigger the convertion
+		outb(MPC624_ADSCK, dev->iobase + MPC624_ADC);
+		comedi_udelay(1);
+		outb(MPC624_ADCS | MPC624_ADSCK, dev->iobase + MPC624_ADC);
+		comedi_udelay(1);
+		outb(0, dev->iobase + MPC624_ADC);
+		comedi_udelay(1);
+
+		// Wait for the convertion to end
+		for (i = 0; i < TIMEOUT; i++) {
+			ucPort = inb(dev->iobase + MPC624_ADC);
+			if (ucPort & MPC624_ADBUSY)
+				comedi_udelay(1000);
+			else
+				break;
+		}
+		if (i == TIMEOUT) {
+			rt_printk("MPC624: timeout (%dms)\n", TIMEOUT);
+			data[n] = 0;
+			return -ETIMEDOUT;
+		}
+		// Start reading data
+		data_in = 0;
+		data_out = devpriv->ulConvertionRate;
+		comedi_udelay(1);
+		for (i = 0; i < 32; i++) {
+			// Set the clock low
+			outb(0, dev->iobase + MPC624_ADC);
+			comedi_udelay(1);
+
+			if (data_out & (1 << 31))	// the next bit is a 1
+			{
+				// Set the ADSDI line (send to MPC624)
+				outb(MPC624_ADSDI, dev->iobase + MPC624_ADC);
+				comedi_udelay(1);
+				// Set the clock high
+				outb(MPC624_ADSCK | MPC624_ADSDI,
+					dev->iobase + MPC624_ADC);
+			} else	// the next bit is a 0
+			{
+				// Set the ADSDI line (send to MPC624)
+				outb(0, dev->iobase + MPC624_ADC);
+				comedi_udelay(1);
+				// Set the clock high
+				outb(MPC624_ADSCK, dev->iobase + MPC624_ADC);
+			}
+			// Read ADSDO on high clock (receive from MPC624)
+			comedi_udelay(1);
+			data_in <<= 1;
+			data_in |=
+				(inb(dev->iobase +
+					MPC624_ADC) & MPC624_ADSDO) >> 4;
+			comedi_udelay(1);
+
+			data_out <<= 1;
+		}
+
+		// Received 32-bit long value consist of:
+		//   31: EOC (End Of Transmission) bit - should be 0
+		//   30: DMY (Dummy) bit               - should be 0
+		//   29: SIG (Sign) bit                - 1 if the voltage is positive, 0 if negative
+		//   28: MSB (Most Significant Bit)    - the first bit of convertion result
+		//   ....
+		//   05: LSB (Least Significant Bit)   - the last bit of convertion result
+		//   04: sub-LSB                       - sub-LSBs are basically noise, but when
+		//   03: sub-LSB                         averaged properly, they can increase convertion
+		//   02: sub-LSB                         precision up to 29 bits; they can be discarded
+		//   01: sub-LSB                         without loss of resolution.
+		//   00: sub-LSB
+
+		if (data_in & MPC624_EOC_BIT)
+			rt_printk("MPC624: EOC bit is set (data_in=%lu)!",
+				data_in);
+		if (data_in & MPC624_DMY_BIT)
+			rt_printk("MPC624: DMY bit is set (data_in=%lu)!",
+				data_in);
+		if (data_in & MPC624_SGN_BIT)	// check the sign bit
+		{		// The voltage is positive
+			data_in &= 0x3FFFFFFF;	// EOC and DMY should be 0, but we will mask them out just to be sure
+			data[n] = data_in;	// comedi operates on unsigned numbers, so we don't clear the SGN bit
+			// SGN bit is still set! It's correct, since we're converting to unsigned.
+		} else {	// The voltage is negative
+			// data_in contains a number in 30-bit two's complement code and we must deal with it
+			data_in |= MPC624_SGN_BIT;
+			data_in = ~data_in;
+			data_in += 1;
+			data_in &= ~(MPC624_EOC_BIT | MPC624_DMY_BIT);
+			// clear EOC and DMY bits
+			data_in = 0x20000000 - data_in;
+			data[n] = data_in;
+		}
+	}
+
+	// Return the number of samples read/written
+	return n;
+}
+
+COMEDI_INITCLEANUP(driver_mpc624);
diff --git a/drivers/staging/comedi/drivers/mpc8260cpm.c b/drivers/staging/comedi/drivers/mpc8260cpm.c
new file mode 100644
index 0000000..bac0a7b
--- /dev/null
+++ b/drivers/staging/comedi/drivers/mpc8260cpm.c
@@ -0,0 +1,169 @@
+/*
+    comedi/drivers/mpc8260.c
+    driver for digital I/O pins on the MPC 8260 CPM module
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000,2001 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: mpc8260cpm
+Description: MPC8260 CPM module generic digital I/O lines
+Devices: [Motorola] MPC8260 CPM (mpc8260cpm)
+Author: ds
+Status: experimental
+Updated: Sat, 16 Mar 2002 17:34:48 -0800
+
+This driver is specific to the Motorola MPC8260 processor, allowing
+you to access the processor's generic digital I/O lines.
+
+It is apparently missing some code.
+*/
+
+#include "../comedidev.h"
+
+extern unsigned long mpc8260_dio_reserved[4];
+
+struct mpc8260cpm_private {
+
+	int data;
+
+};
+
+#define devpriv ((struct mpc8260cpm_private *)dev->private)
+
+static int mpc8260cpm_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int mpc8260cpm_detach(struct comedi_device * dev);
+static struct comedi_driver driver_mpc8260cpm = {
+      driver_name:"mpc8260cpm",
+      module:THIS_MODULE,
+      attach:mpc8260cpm_attach,
+      detach:mpc8260cpm_detach,
+};
+
+COMEDI_INITCLEANUP(driver_mpc8260cpm);
+
+static int mpc8260cpm_dio_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int mpc8260cpm_dio_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+static int mpc8260cpm_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	int i;
+
+	printk("comedi%d: mpc8260cpm: ", dev->minor);
+
+	dev->board_ptr = mpc8260cpm_boards + dev->board;
+
+	dev->board_name = thisboard->name;
+
+	if (alloc_private(dev, sizeof(struct mpc8260cpm_private)) < 0)
+		return -ENOMEM;
+
+	if (alloc_subdevices(dev, 4) < 0)
+		return -ENOMEM;
+
+	for (i = 0; i < 4; i++) {
+		s = dev->subdevices + i;
+		s->type = COMEDI_SUBD_DIO;
+		s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+		s->n_chan = 32;
+		s->maxdata = 1;
+		s->range_table = &range_digital;
+		s->insn_config = mpc8260cpm_dio_config;
+		s->insn_bits = mpc8260cpm_dio_bits;
+	}
+
+	return 1;
+}
+
+static int mpc8260cpm_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: mpc8260cpm: remove\n", dev->minor);
+
+	return 0;
+}
+
+static unsigned long *cpm_pdat(int port)
+{
+	switch (port) {
+	case 0:
+		return &io->iop_pdata;
+	case 1:
+		return &io->iop_pdatb;
+	case 2:
+		return &io->iop_pdatc;
+	case 3:
+		return &io->iop_pdatd;
+	}
+}
+
+static int mpc8260cpm_dio_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n;
+	unsigned int d;
+	unsigned int mask;
+	int port;
+
+	port = (int)s->private;
+	mask = 1 << CR_CHAN(insn->chanspec);
+	if (mask & cpm_reserved_bits[port]) {
+		return -EINVAL;
+	}
+
+	switch (data[0]) {
+	case INSN_CONFIG_DIO_OUTPUT:
+		s->io_bits |= mask;
+		break;
+	case INSN_CONFIG_DIO_INPUT:
+		s->io_bits &= ~mask;
+		break;
+	case INSN_CONFIG_DIO_QUERY:
+		data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
+		return insn->n;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (port) {
+	case 0:
+		return &io->iop_pdira;
+	case 1:
+		return &io->iop_pdirb;
+	case 2:
+		return &io->iop_pdirc;
+	case 3:
+		return &io->iop_pdird;
+	}
+
+	return 1;
+}
+
+static int mpc8260cpm_dio_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int port;
+	unsigned long *p;
+
+	p = cpm_pdat((int)s->private);
+
+	return 2;
+}
diff --git a/drivers/staging/comedi/drivers/multiq3.c b/drivers/staging/comedi/drivers/multiq3.c
new file mode 100644
index 0000000..9e47574
--- /dev/null
+++ b/drivers/staging/comedi/drivers/multiq3.c
@@ -0,0 +1,333 @@
+/*
+   comedi/drivers/multiq3.c
+   Hardware driver for Quanser Consulting MultiQ-3 board
+
+   COMEDI - Linux Control and Measurement Device Interface
+   Copyright (C) 1999 Anders Blomdell <anders.blomdell@control.lth.se>
+
+   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.
+
+ */
+/*
+Driver: multiq3
+Description: Quanser Consulting MultiQ-3
+Author: Anders Blomdell <anders.blomdell@control.lth.se>
+Status: works
+Devices: [Quanser Consulting] MultiQ-3 (multiq3)
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define MULTIQ3_SIZE 16
+
+/*
+ * MULTIQ-3 port offsets
+ */
+#define MULTIQ3_DIGIN_PORT 0
+#define MULTIQ3_DIGOUT_PORT 0
+#define MULTIQ3_DAC_DATA 2
+#define MULTIQ3_AD_DATA 4
+#define MULTIQ3_AD_CS 4
+#define MULTIQ3_STATUS 6
+#define MULTIQ3_CONTROL 6
+#define MULTIQ3_CLK_DATA 8
+#define MULTIQ3_ENC_DATA 12
+#define MULTIQ3_ENC_CONTROL 14
+
+/*
+ * flags for CONTROL register
+ */
+#define MULTIQ3_AD_MUX_EN      0x0040
+#define MULTIQ3_AD_AUTOZ       0x0080
+#define MULTIQ3_AD_AUTOCAL     0x0100
+#define MULTIQ3_AD_SH          0x0200
+#define MULTIQ3_AD_CLOCK_4M    0x0400
+#define MULTIQ3_DA_LOAD                0x1800
+
+#define MULTIQ3_CONTROL_MUST    0x0600
+
+/*
+ * flags for STATUS register
+ */
+#define MULTIQ3_STATUS_EOC      0x008
+#define MULTIQ3_STATUS_EOC_I    0x010
+
+/*
+ * flags for encoder control
+ */
+#define MULTIQ3_CLOCK_DATA      0x00
+#define MULTIQ3_CLOCK_SETUP     0x18
+#define MULTIQ3_INPUT_SETUP     0x41
+#define MULTIQ3_QUAD_X4         0x38
+#define MULTIQ3_BP_RESET        0x01
+#define MULTIQ3_CNTR_RESET      0x02
+#define MULTIQ3_TRSFRPR_CTR     0x08
+#define MULTIQ3_TRSFRCNTR_OL    0x10
+#define MULTIQ3_EFLAG_RESET     0x06
+
+#define MULTIQ3_TIMEOUT 30
+
+static int multiq3_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int multiq3_detach(struct comedi_device * dev);
+static struct comedi_driver driver_multiq3 = {
+      driver_name:"multiq3",
+      module:THIS_MODULE,
+      attach:multiq3_attach,
+      detach:multiq3_detach,
+};
+
+COMEDI_INITCLEANUP(driver_multiq3);
+
+struct multiq3_private {
+	unsigned int ao_readback[2];
+};
+#define devpriv ((struct multiq3_private *)dev->private)
+
+static int multiq3_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i, n;
+	int chan;
+	unsigned int hi, lo;
+
+	chan = CR_CHAN(insn->chanspec);
+	outw(MULTIQ3_CONTROL_MUST | MULTIQ3_AD_MUX_EN | (chan << 3),
+		dev->iobase + MULTIQ3_CONTROL);
+
+	for (i = 0; i < MULTIQ3_TIMEOUT; i++) {
+		if (inw(dev->iobase + MULTIQ3_STATUS) & MULTIQ3_STATUS_EOC)
+			break;
+	}
+	if (i == MULTIQ3_TIMEOUT)
+		return -ETIMEDOUT;
+
+	for (n = 0; n < insn->n; n++) {
+		outw(0, dev->iobase + MULTIQ3_AD_CS);
+		for (i = 0; i < MULTIQ3_TIMEOUT; i++) {
+			if (inw(dev->iobase +
+					MULTIQ3_STATUS) & MULTIQ3_STATUS_EOC_I)
+				break;
+		}
+		if (i == MULTIQ3_TIMEOUT)
+			return -ETIMEDOUT;
+
+		hi = inb(dev->iobase + MULTIQ3_AD_CS);
+		lo = inb(dev->iobase + MULTIQ3_AD_CS);
+		data[n] = (((hi << 8) | lo) + 0x1000) & 0x1fff;
+	}
+
+	return n;
+}
+
+static int multiq3_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+
+	for (i = 0; i < insn->n; i++) {
+		data[i] = devpriv->ao_readback[chan];
+	}
+
+	return i;
+}
+
+static int multiq3_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+
+	for (i = 0; i < insn->n; i++) {
+		outw(MULTIQ3_CONTROL_MUST | MULTIQ3_DA_LOAD | chan,
+			dev->iobase + MULTIQ3_CONTROL);
+		outw(data[i], dev->iobase + MULTIQ3_DAC_DATA);
+		outw(MULTIQ3_CONTROL_MUST, dev->iobase + MULTIQ3_CONTROL);
+
+		devpriv->ao_readback[chan] = data[i];
+	}
+
+	return i;
+}
+
+static int multiq3_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	data[1] = inw(dev->iobase + MULTIQ3_DIGIN_PORT);
+
+	return 2;
+}
+
+static int multiq3_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	s->state &= ~data[0];
+	s->state |= (data[0] & data[1]);
+	outw(s->state, dev->iobase + MULTIQ3_DIGOUT_PORT);
+
+	data[1] = s->state;
+
+	return 2;
+}
+
+static int multiq3_encoder_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n;
+	int chan = CR_CHAN(insn->chanspec);
+	int control = MULTIQ3_CONTROL_MUST | MULTIQ3_AD_MUX_EN | (chan << 3);
+
+	for (n = 0; n < insn->n; n++) {
+		int value;
+		outw(control, dev->iobase + MULTIQ3_CONTROL);
+		outb(MULTIQ3_BP_RESET, dev->iobase + MULTIQ3_ENC_CONTROL);
+		outb(MULTIQ3_TRSFRCNTR_OL, dev->iobase + MULTIQ3_ENC_CONTROL);
+		value = inb(dev->iobase + MULTIQ3_ENC_DATA);
+		value |= (inb(dev->iobase + MULTIQ3_ENC_DATA) << 8);
+		value |= (inb(dev->iobase + MULTIQ3_ENC_DATA) << 16);
+		data[n] = (value + 0x800000) & 0xffffff;
+	}
+
+	return n;
+}
+
+static void encoder_reset(struct comedi_device * dev)
+{
+	int chan;
+	for (chan = 0; chan < dev->subdevices[4].n_chan; chan++) {
+		int control =
+			MULTIQ3_CONTROL_MUST | MULTIQ3_AD_MUX_EN | (chan << 3);
+		outw(control, dev->iobase + MULTIQ3_CONTROL);
+		outb(MULTIQ3_EFLAG_RESET, dev->iobase + MULTIQ3_ENC_CONTROL);
+		outb(MULTIQ3_BP_RESET, dev->iobase + MULTIQ3_ENC_CONTROL);
+		outb(MULTIQ3_CLOCK_DATA, dev->iobase + MULTIQ3_ENC_DATA);
+		outb(MULTIQ3_CLOCK_SETUP, dev->iobase + MULTIQ3_ENC_CONTROL);
+		outb(MULTIQ3_INPUT_SETUP, dev->iobase + MULTIQ3_ENC_CONTROL);
+		outb(MULTIQ3_QUAD_X4, dev->iobase + MULTIQ3_ENC_CONTROL);
+		outb(MULTIQ3_CNTR_RESET, dev->iobase + MULTIQ3_ENC_CONTROL);
+	}
+}
+
+/*
+   options[0] - I/O port
+   options[1] - irq
+   options[2] - number of encoder chips installed
+ */
+
+static int multiq3_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	int result = 0;
+	unsigned long iobase;
+	unsigned int irq;
+	struct comedi_subdevice *s;
+
+	iobase = it->options[0];
+	printk("comedi%d: multiq3: 0x%04lx ", dev->minor, iobase);
+	if (!request_region(iobase, MULTIQ3_SIZE, "multiq3")) {
+		printk("comedi%d: I/O port conflict\n", dev->minor);
+		return -EIO;
+	}
+
+	dev->iobase = iobase;
+
+	irq = it->options[1];
+	if (irq) {
+		printk("comedi%d: irq = %u ignored\n", dev->minor, irq);
+	} else {
+		printk("comedi%d: no irq\n", dev->minor);
+	}
+	dev->board_name = "multiq3";
+	result = alloc_subdevices(dev, 5);
+	if (result < 0)
+		return result;
+
+	result = alloc_private(dev, sizeof(struct multiq3_private));
+	if (result < 0)
+		return result;
+
+	s = dev->subdevices + 0;
+	/* ai subdevice */
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE | SDF_GROUND;
+	s->n_chan = 8;
+	s->insn_read = multiq3_ai_insn_read;
+	s->maxdata = 0x1fff;
+	s->range_table = &range_bipolar5;
+
+	s = dev->subdevices + 1;
+	/* ao subdevice */
+	s->type = COMEDI_SUBD_AO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->n_chan = 8;
+	s->insn_read = multiq3_ao_insn_read;
+	s->insn_write = multiq3_ao_insn_write;
+	s->maxdata = 0xfff;
+	s->range_table = &range_bipolar5;
+
+	s = dev->subdevices + 2;
+	/* di subdevice */
+	s->type = COMEDI_SUBD_DI;
+	s->subdev_flags = SDF_READABLE;
+	s->n_chan = 16;
+	s->insn_bits = multiq3_di_insn_bits;
+	s->maxdata = 1;
+	s->range_table = &range_digital;
+
+	s = dev->subdevices + 3;
+	/* do subdevice */
+	s->type = COMEDI_SUBD_DO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->n_chan = 16;
+	s->insn_bits = multiq3_do_insn_bits;
+	s->maxdata = 1;
+	s->range_table = &range_digital;
+	s->state = 0;
+
+	s = dev->subdevices + 4;
+	/* encoder (counter) subdevice */
+	s->type = COMEDI_SUBD_COUNTER;
+	s->subdev_flags = SDF_READABLE | SDF_LSAMPL;
+	s->n_chan = it->options[2] * 2;
+	s->insn_read = multiq3_encoder_insn_read;
+	s->maxdata = 0xffffff;
+	s->range_table = &range_unknown;
+
+	encoder_reset(dev);
+
+	return 0;
+}
+
+static int multiq3_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: multiq3: remove\n", dev->minor);
+
+	if (dev->iobase) {
+		release_region(dev->iobase, MULTIQ3_SIZE);
+	}
+	if (dev->irq) {
+		free_irq(dev->irq, dev);
+	}
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c
new file mode 100644
index 0000000..e01ecb6
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_6527.c
@@ -0,0 +1,489 @@
+/*
+    comedi/drivers/ni_6527.c
+    driver for National Instruments PCI-6527
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 1999,2002,2003 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: ni_6527
+Description: National Instruments 6527
+Author: ds
+Status: works
+Devices: [National Instruments] PCI-6527 (ni6527), PXI-6527
+Updated: Sat, 25 Jan 2003 13:24:40 -0800
+
+
+*/
+
+/*
+   Manuals (available from ftp://ftp.natinst.com/support/manuals)
+
+	370106b.pdf	6527 Register Level Programmer Manual
+
+ */
+
+#define DEBUG 1
+#define DEBUG_FLAGS
+
+#include "../comedidev.h"
+
+#include "mite.h"
+
+#define NI6527_DIO_SIZE 4096
+#define NI6527_MITE_SIZE 4096
+
+#define Port_Register(x)			(0x00+(x))
+#define ID_Register				0x06
+
+#define Clear_Register				0x07
+#define ClrEdge				0x08
+#define ClrOverflow			0x04
+#define ClrFilter			0x02
+#define ClrInterval			0x01
+
+#define Filter_Interval(x)			(0x08+(x))
+#define Filter_Enable(x)			(0x0c+(x))
+
+#define Change_Status				0x14
+#define MasterInterruptStatus		0x04
+#define Overflow			0x02
+#define EdgeStatus			0x01
+
+#define Master_Interrupt_Control		0x15
+#define FallingEdgeIntEnable		0x10
+#define RisingEdgeIntEnable		0x08
+#define MasterInterruptEnable		0x04
+#define OverflowIntEnable		0x02
+#define EdgeIntEnable			0x01
+
+#define Rising_Edge_Detection_Enable(x)		(0x018+(x))
+#define Falling_Edge_Detection_Enable(x)	(0x020+(x))
+
+static int ni6527_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int ni6527_detach(struct comedi_device * dev);
+static struct comedi_driver driver_ni6527 = {
+      driver_name:"ni6527",
+      module:THIS_MODULE,
+      attach:ni6527_attach,
+      detach:ni6527_detach,
+};
+
+struct ni6527_board {
+
+	int dev_id;
+	const char *name;
+};
+
+static const struct ni6527_board ni6527_boards[] = {
+	{
+	      dev_id:	0x2b20,
+	      name:	"pci-6527",
+		},
+	{
+	      dev_id:	0x2b10,
+	      name:	"pxi-6527",
+		},
+};
+
+#define n_ni6527_boards (sizeof(ni6527_boards)/sizeof(ni6527_boards[0]))
+#define this_board ((const struct ni6527_board *)dev->board_ptr)
+
+static DEFINE_PCI_DEVICE_TABLE(ni6527_pci_table) = {
+	{PCI_VENDOR_ID_NATINST, 0x2b10, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x2b20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, ni6527_pci_table);
+
+struct ni6527_private {
+	struct mite_struct *mite;
+	unsigned int filter_interval;
+	unsigned int filter_enable;
+};
+
+#define devpriv ((struct ni6527_private *)dev->private)
+
+static int ni6527_find_device(struct comedi_device * dev, int bus, int slot);
+
+static int ni6527_di_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int chan = CR_CHAN(insn->chanspec);
+	unsigned int interval;
+
+	if (insn->n != 2)
+		return -EINVAL;
+
+	if (data[0] != INSN_CONFIG_FILTER)
+		return -EINVAL;
+
+	if (data[1]) {
+		interval = (data[1] + 100) / 200;
+		data[1] = interval * 200;
+
+		if (interval != devpriv->filter_interval) {
+			writeb(interval & 0xff,
+				devpriv->mite->daq_io_addr +
+				Filter_Interval(0));
+			writeb((interval >> 8) & 0xff,
+				devpriv->mite->daq_io_addr +
+				Filter_Interval(1));
+			writeb((interval >> 16) & 0x0f,
+				devpriv->mite->daq_io_addr +
+				Filter_Interval(2));
+
+			writeb(ClrInterval,
+				devpriv->mite->daq_io_addr + Clear_Register);
+
+			devpriv->filter_interval = interval;
+		}
+
+		devpriv->filter_enable |= 1 << chan;
+	} else {
+		devpriv->filter_enable &= ~(1 << chan);
+	}
+
+	writeb(devpriv->filter_enable,
+		devpriv->mite->daq_io_addr + Filter_Enable(0));
+	writeb(devpriv->filter_enable >> 8,
+		devpriv->mite->daq_io_addr + Filter_Enable(1));
+	writeb(devpriv->filter_enable >> 16,
+		devpriv->mite->daq_io_addr + Filter_Enable(2));
+
+	return 2;
+}
+
+static int ni6527_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	data[1] = readb(devpriv->mite->daq_io_addr + Port_Register(0));
+	data[1] |= readb(devpriv->mite->daq_io_addr + Port_Register(1)) << 8;
+	data[1] |= readb(devpriv->mite->daq_io_addr + Port_Register(2)) << 16;
+
+	return 2;
+}
+
+static int ni6527_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= (data[0] & data[1]);
+
+		/* The open relay state on the board cooresponds to 1,
+		 * but in Comedi, it is represented by 0. */
+		if (data[0] & 0x0000ff) {
+			writeb((s->state ^ 0xff),
+				devpriv->mite->daq_io_addr + Port_Register(3));
+		}
+		if (data[0] & 0x00ff00) {
+			writeb((s->state >> 8) ^ 0xff,
+				devpriv->mite->daq_io_addr + Port_Register(4));
+		}
+		if (data[0] & 0xff0000) {
+			writeb((s->state >> 16) ^ 0xff,
+				devpriv->mite->daq_io_addr + Port_Register(5));
+		}
+	}
+	data[1] = s->state;
+
+	return 2;
+}
+
+static irqreturn_t ni6527_interrupt(int irq, void *d PT_REGS_ARG)
+{
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s = dev->subdevices + 2;
+	unsigned int status;
+
+	status = readb(devpriv->mite->daq_io_addr + Change_Status);
+	if ((status & MasterInterruptStatus) == 0)
+		return IRQ_NONE;
+	if ((status & EdgeStatus) == 0)
+		return IRQ_NONE;
+
+	writeb(ClrEdge | ClrOverflow,
+		devpriv->mite->daq_io_addr + Clear_Register);
+
+	comedi_buf_put(s->async, 0);
+	s->async->events |= COMEDI_CB_EOS;
+	comedi_event(dev, s);
+	return IRQ_HANDLED;
+}
+
+static int ni6527_intr_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp;
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_OTHER;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_FOLLOW;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+	if (cmd->scan_begin_arg != 0) {
+		cmd->scan_begin_arg = 0;
+		err++;
+	}
+	if (cmd->convert_arg != 0) {
+		cmd->convert_arg = 0;
+		err++;
+	}
+
+	if (cmd->scan_end_arg != 1) {
+		cmd->scan_end_arg = 1;
+		err++;
+	}
+	if (cmd->stop_arg != 0) {
+		cmd->stop_arg = 0;
+		err++;
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	if (err)
+		return 4;
+
+	return 0;
+}
+
+static int ni6527_intr_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	//struct comedi_cmd *cmd = &s->async->cmd;
+
+	writeb(ClrEdge | ClrOverflow,
+		devpriv->mite->daq_io_addr + Clear_Register);
+	writeb(FallingEdgeIntEnable | RisingEdgeIntEnable |
+		MasterInterruptEnable | EdgeIntEnable,
+		devpriv->mite->daq_io_addr + Master_Interrupt_Control);
+
+	return 0;
+}
+
+static int ni6527_intr_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control);
+
+	return 0;
+}
+
+static int ni6527_intr_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n < 1)
+		return -EINVAL;
+
+	data[1] = 0;
+	return 2;
+}
+
+static int ni6527_intr_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n < 1)
+		return -EINVAL;
+	if (data[0] != INSN_CONFIG_CHANGE_NOTIFY)
+		return -EINVAL;
+
+	writeb(data[1],
+		devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(0));
+	writeb(data[1] >> 8,
+		devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(1));
+	writeb(data[1] >> 16,
+		devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(2));
+
+	writeb(data[2],
+		devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(0));
+	writeb(data[2] >> 8,
+		devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(1));
+	writeb(data[2] >> 16,
+		devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(2));
+
+	return 2;
+}
+
+static int ni6527_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	int ret;
+
+	printk("comedi%d: ni6527:", dev->minor);
+
+	if ((ret = alloc_private(dev, sizeof(struct ni6527_private))) < 0)
+		return ret;
+
+	ret = ni6527_find_device(dev, it->options[0], it->options[1]);
+	if (ret < 0)
+		return ret;
+
+	ret = mite_setup(devpriv->mite);
+	if (ret < 0) {
+		printk("error setting up mite\n");
+		return ret;
+	}
+
+	dev->board_name = this_board->name;
+	printk(" %s", dev->board_name);
+
+	printk(" ID=0x%02x", readb(devpriv->mite->daq_io_addr + ID_Register));
+
+	if ((ret = alloc_subdevices(dev, 3)) < 0)
+		return ret;
+
+	s = dev->subdevices + 0;
+	s->type = COMEDI_SUBD_DI;
+	s->subdev_flags = SDF_READABLE;
+	s->n_chan = 24;
+	s->range_table = &range_digital;
+	s->maxdata = 1;
+	s->insn_config = ni6527_di_insn_config;
+	s->insn_bits = ni6527_di_insn_bits;
+
+	s = dev->subdevices + 1;
+	s->type = COMEDI_SUBD_DO;
+	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+	s->n_chan = 24;
+	s->range_table = &range_unknown;	/* FIXME: actually conductance */
+	s->maxdata = 1;
+	s->insn_bits = ni6527_do_insn_bits;
+
+	s = dev->subdevices + 2;
+	dev->read_subdev = s;
+	s->type = COMEDI_SUBD_DI;
+	s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+	s->n_chan = 1;
+	s->range_table = &range_unknown;
+	s->maxdata = 1;
+	s->do_cmdtest = ni6527_intr_cmdtest;
+	s->do_cmd = ni6527_intr_cmd;
+	s->cancel = ni6527_intr_cancel;
+	s->insn_bits = ni6527_intr_insn_bits;
+	s->insn_config = ni6527_intr_insn_config;
+
+	writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(0));
+	writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(1));
+	writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(2));
+
+	writeb(ClrEdge | ClrOverflow | ClrFilter | ClrInterval,
+		devpriv->mite->daq_io_addr + Clear_Register);
+	writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control);
+
+	ret = comedi_request_irq(mite_irq(devpriv->mite), ni6527_interrupt,
+		IRQF_SHARED, "ni6527", dev);
+	if (ret < 0) {
+		printk(" irq not available");
+	} else
+		dev->irq = mite_irq(devpriv->mite);
+
+	printk("\n");
+
+	return 0;
+}
+
+static int ni6527_detach(struct comedi_device * dev)
+{
+	if (devpriv && devpriv->mite && devpriv->mite->daq_io_addr) {
+		writeb(0x00,
+			devpriv->mite->daq_io_addr + Master_Interrupt_Control);
+	}
+
+	if (dev->irq) {
+		comedi_free_irq(dev->irq, dev);
+	}
+
+	if (devpriv && devpriv->mite) {
+		mite_unsetup(devpriv->mite);
+	}
+
+	return 0;
+}
+
+static int ni6527_find_device(struct comedi_device * dev, int bus, int slot)
+{
+	struct mite_struct *mite;
+	int i;
+
+	for (mite = mite_devices; mite; mite = mite->next) {
+		if (mite->used)
+			continue;
+		if (bus || slot) {
+			if (bus != mite->pcidev->bus->number ||
+				slot != PCI_SLOT(mite->pcidev->devfn))
+				continue;
+		}
+		for (i = 0; i < n_ni6527_boards; i++) {
+			if (mite_device_id(mite) == ni6527_boards[i].dev_id) {
+				dev->board_ptr = ni6527_boards + i;
+				devpriv->mite = mite;
+				return 0;
+			}
+		}
+	}
+	printk("no device found\n");
+	mite_list_devices();
+	return -EIO;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_ni6527, ni6527_pci_table);
diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c
new file mode 100644
index 0000000..6e85da1
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_65xx.c
@@ -0,0 +1,809 @@
+/*
+    comedi/drivers/ni_6514.c
+    driver for National Instruments PCI-6514
+
+    Copyright (C) 2006 Jon Grierson <jd@renko.co.uk>
+    Copyright (C) 2006 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 1999,2002,2003 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: ni_65xx
+Description: National Instruments 65xx static dio boards
+Author: Jon Grierson <jd@renko.co.uk>, Frank Mori Hess <fmhess@users.sourceforge.net>
+Status: testing
+Devices: [National Instruments] PCI-6509 (ni_65xx), PXI-6509, PCI-6510, PCI-6511,
+  PXI-6511, PCI-6512, PXI-6512, PCI-6513, PXI-6513, PCI-6514, PXI-6514, PCI-6515,
+  PXI-6515, PCI-6516, PCI-6517, PCI-6518, PCI-6519, PCI-6520, PCI-6521, PXI-6521,
+  PCI-6528, PXI-6528
+Updated: Wed Oct 18 08:59:11 EDT 2006
+
+Based on the PCI-6527 driver by ds.
+The interrupt subdevice (subdevice 3) is probably broken for all boards
+except maybe the 6514.
+
+*/
+
+/*
+   Manuals (available from ftp://ftp.natinst.com/support/manuals)
+
+	370106b.pdf	6514 Register Level Programmer Manual
+
+ */
+
+#define _GNU_SOURCE
+#define DEBUG 1
+#define DEBUG_FLAGS
+#include "../comedidev.h"
+
+#include "mite.h"
+
+#define NI6514_DIO_SIZE 4096
+#define NI6514_MITE_SIZE 4096
+
+#define NI_65XX_MAX_NUM_PORTS 12
+static const unsigned ni_65xx_channels_per_port = 8;
+static const unsigned ni_65xx_port_offset = 0x10;
+
+static inline unsigned Port_Data(unsigned port)
+{
+	return 0x40 + port * ni_65xx_port_offset;
+}
+static inline unsigned Port_Select(unsigned port)
+{
+	return 0x41 + port * ni_65xx_port_offset;
+}
+static inline unsigned Rising_Edge_Detection_Enable(unsigned port)
+{
+	return 0x42 + port * ni_65xx_port_offset;
+}
+static inline unsigned Falling_Edge_Detection_Enable(unsigned port)
+{
+	return 0x43 + port * ni_65xx_port_offset;
+}
+static inline unsigned Filter_Enable(unsigned port)
+{
+	return 0x44 + port * ni_65xx_port_offset;
+}
+
+#define ID_Register				0x00
+
+#define Clear_Register				0x01
+#define ClrEdge				0x08
+#define ClrOverflow			0x04
+
+#define Filter_Interval			0x08
+
+#define Change_Status				0x02
+#define MasterInterruptStatus		0x04
+#define Overflow			0x02
+#define EdgeStatus			0x01
+
+#define Master_Interrupt_Control		0x03
+#define FallingEdgeIntEnable		0x10
+#define RisingEdgeIntEnable		0x08
+#define MasterInterruptEnable		0x04
+#define OverflowIntEnable		0x02
+#define EdgeIntEnable			0x01
+
+static int ni_65xx_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int ni_65xx_detach(struct comedi_device * dev);
+static struct comedi_driver driver_ni_65xx = {
+      driver_name:"ni_65xx",
+      module:THIS_MODULE,
+      attach:ni_65xx_attach,
+      detach:ni_65xx_detach,
+};
+
+struct ni_65xx_board {
+
+	int dev_id;
+	const char *name;
+	unsigned num_dio_ports;
+	unsigned num_di_ports;
+	unsigned num_do_ports;
+	unsigned invert_outputs:1;
+};
+
+static const struct ni_65xx_board ni_65xx_boards[] = {
+	{
+	      dev_id:	0x7085,
+	      name:	"pci-6509",
+	      num_dio_ports:12,
+      invert_outputs:0},
+	{
+	      dev_id:	0x1710,
+	      name:	"pxi-6509",
+	      num_dio_ports:12,
+      invert_outputs:0},
+	{
+	      dev_id:	0x7124,
+	      name:	"pci-6510",
+      num_di_ports:4},
+	{
+	      dev_id:	0x70c3,
+	      name:	"pci-6511",
+      num_di_ports:8},
+	{
+	      dev_id:	0x70d3,
+	      name:	"pxi-6511",
+      num_di_ports:8},
+	{
+	      dev_id:	0x70cc,
+	      name:	"pci-6512",
+      num_do_ports:8},
+	{
+	      dev_id:	0x70d2,
+	      name:	"pxi-6512",
+      num_do_ports:8},
+	{
+	      dev_id:	0x70c8,
+	      name:	"pci-6513",
+	      num_do_ports:8,
+      invert_outputs:1},
+	{
+	      dev_id:	0x70d1,
+	      name:	"pxi-6513",
+	      num_do_ports:8,
+      invert_outputs:1},
+	{
+	      dev_id:	0x7088,
+	      name:	"pci-6514",
+	      num_di_ports:4,
+	      num_do_ports:4,
+      invert_outputs:1},
+	{
+	      dev_id:	0x70CD,
+	      name:	"pxi-6514",
+	      num_di_ports:4,
+	      num_do_ports:4,
+      invert_outputs:1},
+	{
+	      dev_id:	0x7087,
+	      name:	"pci-6515",
+	      num_di_ports:4,
+	      num_do_ports:4,
+      invert_outputs:1},
+	{
+	      dev_id:	0x70c9,
+	      name:	"pxi-6515",
+	      num_di_ports:4,
+	      num_do_ports:4,
+      invert_outputs:1},
+	{
+	      dev_id:	0x7125,
+	      name:	"pci-6516",
+	      num_do_ports:4,
+      invert_outputs:1},
+	{
+	      dev_id:	0x7126,
+	      name:	"pci-6517",
+	      num_do_ports:4,
+      invert_outputs:1},
+	{
+	      dev_id:	0x7127,
+	      name:	"pci-6518",
+	      num_di_ports:2,
+	      num_do_ports:2,
+      invert_outputs:1},
+	{
+	      dev_id:	0x7128,
+	      name:	"pci-6519",
+	      num_di_ports:2,
+	      num_do_ports:2,
+      invert_outputs:1},
+	{
+	      dev_id:	0x71c5,
+	      name:	"pci-6520",
+	      num_di_ports:1,
+	      num_do_ports:1,
+		},
+	{
+	      dev_id:	0x718b,
+	      name:	"pci-6521",
+	      num_di_ports:1,
+	      num_do_ports:1,
+		},
+	{
+	      dev_id:	0x718c,
+	      name:	"pxi-6521",
+	      num_di_ports:1,
+	      num_do_ports:1,
+		},
+	{
+	      dev_id:	0x70a9,
+	      name:	"pci-6528",
+	      num_di_ports:3,
+	      num_do_ports:3,
+		},
+	{
+	      dev_id:	0x7086,
+	      name:	"pxi-6528",
+	      num_di_ports:3,
+	      num_do_ports:3,
+		},
+};
+
+#define n_ni_65xx_boards (sizeof(ni_65xx_boards)/sizeof(ni_65xx_boards[0]))
+static inline const struct ni_65xx_board *board(struct comedi_device * dev)
+{
+	return dev->board_ptr;
+}
+static inline unsigned ni_65xx_port_by_channel(unsigned channel)
+{
+	return channel / ni_65xx_channels_per_port;
+}
+static inline unsigned ni_65xx_total_num_ports(const struct ni_65xx_board * board)
+{
+	return board->num_dio_ports + board->num_di_ports + board->num_do_ports;
+}
+
+static DEFINE_PCI_DEVICE_TABLE(ni_65xx_pci_table) = {
+	{PCI_VENDOR_ID_NATINST, 0x1710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x7085, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x7086, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x7087, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x7088, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x70a9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x70c3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x70c8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x70c9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x70cc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x70CD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x70d1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x70d2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x70d3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x7124, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x7126, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x7127, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x7128, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x718b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x718c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x71c5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, ni_65xx_pci_table);
+
+struct ni_65xx_private {
+	struct mite_struct *mite;
+	unsigned int filter_interval;
+	unsigned short filter_enable[NI_65XX_MAX_NUM_PORTS];
+	unsigned short output_bits[NI_65XX_MAX_NUM_PORTS];
+	unsigned short dio_direction[NI_65XX_MAX_NUM_PORTS];
+};
+
+static inline struct ni_65xx_private *private(struct comedi_device * dev)
+{
+	return dev->private;
+}
+
+struct ni_65xx_subdevice_private {
+	unsigned base_port;
+};
+
+static inline struct ni_65xx_subdevice_private *sprivate(struct comedi_subdevice * subdev)
+{
+	return subdev->private;
+}
+static struct ni_65xx_subdevice_private *ni_65xx_alloc_subdevice_private(void)
+{
+	struct ni_65xx_subdevice_private *subdev_private =
+		kzalloc(sizeof(struct ni_65xx_subdevice_private), GFP_KERNEL);
+	if (subdev_private == NULL)
+		return NULL;
+	return subdev_private;
+}
+
+static int ni_65xx_find_device(struct comedi_device * dev, int bus, int slot);
+
+static int ni_65xx_config_filter(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	const unsigned chan = CR_CHAN(insn->chanspec);
+	const unsigned port =
+		sprivate(s)->base_port + ni_65xx_port_by_channel(chan);
+
+	if (data[0] != INSN_CONFIG_FILTER)
+		return -EINVAL;
+	if (data[1]) {
+		static const unsigned filter_resolution_ns = 200;
+		static const unsigned max_filter_interval = 0xfffff;
+		unsigned interval =
+			(data[1] +
+			(filter_resolution_ns / 2)) / filter_resolution_ns;
+		if (interval > max_filter_interval)
+			interval = max_filter_interval;
+		data[1] = interval * filter_resolution_ns;
+
+		if (interval != private(dev)->filter_interval) {
+			writeb(interval,
+				private(dev)->mite->daq_io_addr +
+				Filter_Interval);
+			private(dev)->filter_interval = interval;
+		}
+
+		private(dev)->filter_enable[port] |=
+			1 << (chan % ni_65xx_channels_per_port);
+	} else {
+		private(dev)->filter_enable[port] &=
+			~(1 << (chan % ni_65xx_channels_per_port));
+	}
+
+	writeb(private(dev)->filter_enable[port],
+		private(dev)->mite->daq_io_addr + Filter_Enable(port));
+
+	return 2;
+}
+
+static int ni_65xx_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned port;
+
+	if (insn->n < 1)
+		return -EINVAL;
+	port = sprivate(s)->base_port +
+		ni_65xx_port_by_channel(CR_CHAN(insn->chanspec));
+	switch (data[0]) {
+	case INSN_CONFIG_FILTER:
+		return ni_65xx_config_filter(dev, s, insn, data);
+		break;
+	case INSN_CONFIG_DIO_OUTPUT:
+		if (s->type != COMEDI_SUBD_DIO)
+			return -EINVAL;
+		private(dev)->dio_direction[port] = COMEDI_OUTPUT;
+		writeb(0, private(dev)->mite->daq_io_addr + Port_Select(port));
+		return 1;
+		break;
+	case INSN_CONFIG_DIO_INPUT:
+		if (s->type != COMEDI_SUBD_DIO)
+			return -EINVAL;
+		private(dev)->dio_direction[port] = COMEDI_INPUT;
+		writeb(1, private(dev)->mite->daq_io_addr + Port_Select(port));
+		return 1;
+		break;
+	case INSN_CONFIG_DIO_QUERY:
+		if (s->type != COMEDI_SUBD_DIO)
+			return -EINVAL;
+		data[1] = private(dev)->dio_direction[port];
+		return insn->n;
+		break;
+	default:
+		break;
+	}
+	return -EINVAL;
+}
+
+static int ni_65xx_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned base_bitfield_channel;
+	const unsigned max_ports_per_bitfield = 5;
+	unsigned read_bits = 0;
+	unsigned j;
+	if (insn->n != 2)
+		return -EINVAL;
+	base_bitfield_channel = CR_CHAN(insn->chanspec);
+	for (j = 0; j < max_ports_per_bitfield; ++j) {
+		const unsigned port =
+			sprivate(s)->base_port +
+			ni_65xx_port_by_channel(base_bitfield_channel) + j;
+		unsigned base_port_channel;
+		unsigned port_mask, port_data, port_read_bits;
+		int bitshift;
+		if (port >= ni_65xx_total_num_ports(board(dev)))
+			break;
+		base_port_channel = port * ni_65xx_channels_per_port;
+		port_mask = data[0];
+		port_data = data[1];
+		bitshift = base_port_channel - base_bitfield_channel;
+		if (bitshift >= 32 || bitshift <= -32)
+			break;
+		if (bitshift > 0) {
+			port_mask >>= bitshift;
+			port_data >>= bitshift;
+		} else {
+			port_mask <<= -bitshift;
+			port_data <<= -bitshift;
+		}
+		port_mask &= 0xff;
+		port_data &= 0xff;
+		if (port_mask) {
+			unsigned bits;
+			private(dev)->output_bits[port] &= ~port_mask;
+			private(dev)->output_bits[port] |=
+				port_data & port_mask;
+			bits = private(dev)->output_bits[port];
+			if (board(dev)->invert_outputs)
+				bits = ~bits;
+			writeb(bits,
+				private(dev)->mite->daq_io_addr +
+				Port_Data(port));
+//                      rt_printk("wrote 0x%x to port %i\n", bits, port);
+		}
+		port_read_bits =
+			readb(private(dev)->mite->daq_io_addr +
+			Port_Data(port));
+//              rt_printk("read 0x%x from port %i\n", port_read_bits, port);
+		if (bitshift > 0) {
+			port_read_bits <<= bitshift;
+		} else {
+			port_read_bits >>= -bitshift;
+		}
+		read_bits |= port_read_bits;
+	}
+	data[1] = read_bits;
+	return insn->n;
+}
+
+static irqreturn_t ni_65xx_interrupt(int irq, void *d PT_REGS_ARG)
+{
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s = dev->subdevices + 2;
+	unsigned int status;
+
+	status = readb(private(dev)->mite->daq_io_addr + Change_Status);
+	if ((status & MasterInterruptStatus) == 0)
+		return IRQ_NONE;
+	if ((status & EdgeStatus) == 0)
+		return IRQ_NONE;
+
+	writeb(ClrEdge | ClrOverflow,
+		private(dev)->mite->daq_io_addr + Clear_Register);
+
+	comedi_buf_put(s->async, 0);
+	s->async->events |= COMEDI_CB_EOS;
+	comedi_event(dev, s);
+	return IRQ_HANDLED;
+}
+
+static int ni_65xx_intr_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp;
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_OTHER;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_FOLLOW;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+	if (cmd->scan_begin_arg != 0) {
+		cmd->scan_begin_arg = 0;
+		err++;
+	}
+	if (cmd->convert_arg != 0) {
+		cmd->convert_arg = 0;
+		err++;
+	}
+
+	if (cmd->scan_end_arg != 1) {
+		cmd->scan_end_arg = 1;
+		err++;
+	}
+	if (cmd->stop_arg != 0) {
+		cmd->stop_arg = 0;
+		err++;
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	if (err)
+		return 4;
+
+	return 0;
+}
+
+static int ni_65xx_intr_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	//struct comedi_cmd *cmd = &s->async->cmd;
+
+	writeb(ClrEdge | ClrOverflow,
+		private(dev)->mite->daq_io_addr + Clear_Register);
+	writeb(FallingEdgeIntEnable | RisingEdgeIntEnable |
+		MasterInterruptEnable | EdgeIntEnable,
+		private(dev)->mite->daq_io_addr + Master_Interrupt_Control);
+
+	return 0;
+}
+
+static int ni_65xx_intr_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	writeb(0x00,
+		private(dev)->mite->daq_io_addr + Master_Interrupt_Control);
+
+	return 0;
+}
+
+static int ni_65xx_intr_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n < 1)
+		return -EINVAL;
+
+	data[1] = 0;
+	return 2;
+}
+
+static int ni_65xx_intr_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n < 1)
+		return -EINVAL;
+	if (data[0] != INSN_CONFIG_CHANGE_NOTIFY)
+		return -EINVAL;
+
+	writeb(data[1],
+		private(dev)->mite->daq_io_addr +
+		Rising_Edge_Detection_Enable(0));
+	writeb(data[1] >> 8,
+		private(dev)->mite->daq_io_addr +
+		Rising_Edge_Detection_Enable(0x10));
+	writeb(data[1] >> 16,
+		private(dev)->mite->daq_io_addr +
+		Rising_Edge_Detection_Enable(0x20));
+	writeb(data[1] >> 24,
+		private(dev)->mite->daq_io_addr +
+		Rising_Edge_Detection_Enable(0x30));
+
+	writeb(data[2],
+		private(dev)->mite->daq_io_addr +
+		Falling_Edge_Detection_Enable(0));
+	writeb(data[2] >> 8,
+		private(dev)->mite->daq_io_addr +
+		Falling_Edge_Detection_Enable(0x10));
+	writeb(data[2] >> 16,
+		private(dev)->mite->daq_io_addr +
+		Falling_Edge_Detection_Enable(0x20));
+	writeb(data[2] >> 24,
+		private(dev)->mite->daq_io_addr +
+		Falling_Edge_Detection_Enable(0x30));
+
+	return 2;
+}
+
+static int ni_65xx_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	unsigned i;
+	int ret;
+
+	printk("comedi%d: ni_65xx:", dev->minor);
+
+	if ((ret = alloc_private(dev, sizeof(struct ni_65xx_private))) < 0)
+		return ret;
+
+	ret = ni_65xx_find_device(dev, it->options[0], it->options[1]);
+	if (ret < 0)
+		return ret;
+
+	ret = mite_setup(private(dev)->mite);
+	if (ret < 0) {
+		printk("error setting up mite\n");
+		return ret;
+	}
+
+	dev->board_name = board(dev)->name;
+	dev->irq = mite_irq(private(dev)->mite);
+	printk(" %s", dev->board_name);
+
+	printk(" ID=0x%02x",
+		readb(private(dev)->mite->daq_io_addr + ID_Register));
+
+	if ((ret = alloc_subdevices(dev, 4)) < 0)
+		return ret;
+
+	s = dev->subdevices + 0;
+	if (board(dev)->num_di_ports) {
+		s->type = COMEDI_SUBD_DI;
+		s->subdev_flags = SDF_READABLE;
+		s->n_chan =
+			board(dev)->num_di_ports * ni_65xx_channels_per_port;
+		s->range_table = &range_digital;
+		s->maxdata = 1;
+		s->insn_config = ni_65xx_dio_insn_config;
+		s->insn_bits = ni_65xx_dio_insn_bits;
+		s->private = ni_65xx_alloc_subdevice_private();
+		if (s->private == NULL)
+			return -ENOMEM;
+		sprivate(s)->base_port = 0;
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	s = dev->subdevices + 1;
+	if (board(dev)->num_do_ports) {
+		s->type = COMEDI_SUBD_DO;
+		s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+		s->n_chan =
+			board(dev)->num_do_ports * ni_65xx_channels_per_port;
+		s->range_table = &range_digital;
+		s->maxdata = 1;
+		s->insn_bits = ni_65xx_dio_insn_bits;
+		s->private = ni_65xx_alloc_subdevice_private();
+		if (s->private == NULL)
+			return -ENOMEM;
+		sprivate(s)->base_port = board(dev)->num_di_ports;
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	s = dev->subdevices + 2;
+	if (board(dev)->num_dio_ports) {
+		s->type = COMEDI_SUBD_DIO;
+		s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+		s->n_chan =
+			board(dev)->num_dio_ports * ni_65xx_channels_per_port;
+		s->range_table = &range_digital;
+		s->maxdata = 1;
+		s->insn_config = ni_65xx_dio_insn_config;
+		s->insn_bits = ni_65xx_dio_insn_bits;
+		s->private = ni_65xx_alloc_subdevice_private();
+		if (s->private == NULL)
+			return -ENOMEM;
+		sprivate(s)->base_port = 0;
+		for (i = 0; i < board(dev)->num_dio_ports; ++i) {
+			// configure all ports for input
+			writeb(0x1,
+				private(dev)->mite->daq_io_addr +
+				Port_Select(i));
+		}
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	s = dev->subdevices + 3;
+	dev->read_subdev = s;
+	s->type = COMEDI_SUBD_DI;
+	s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+	s->n_chan = 1;
+	s->range_table = &range_unknown;
+	s->maxdata = 1;
+	s->do_cmdtest = ni_65xx_intr_cmdtest;
+	s->do_cmd = ni_65xx_intr_cmd;
+	s->cancel = ni_65xx_intr_cancel;
+	s->insn_bits = ni_65xx_intr_insn_bits;
+	s->insn_config = ni_65xx_intr_insn_config;
+
+	for (i = 0; i < ni_65xx_total_num_ports(board(dev)); ++i) {
+		writeb(0x00,
+			private(dev)->mite->daq_io_addr + Filter_Enable(i));
+		if (board(dev)->invert_outputs)
+			writeb(0x01,
+				private(dev)->mite->daq_io_addr + Port_Data(i));
+		else
+			writeb(0x00,
+				private(dev)->mite->daq_io_addr + Port_Data(i));
+	}
+	writeb(ClrEdge | ClrOverflow,
+		private(dev)->mite->daq_io_addr + Clear_Register);
+	writeb(0x00,
+		private(dev)->mite->daq_io_addr + Master_Interrupt_Control);
+
+	/* Set filter interval to 0  (32bit reg) */
+	writeb(0x00000000, private(dev)->mite->daq_io_addr + Filter_Interval);
+
+	ret = comedi_request_irq(dev->irq, ni_65xx_interrupt, IRQF_SHARED,
+		"ni_65xx", dev);
+	if (ret < 0) {
+		dev->irq = 0;
+		printk(" irq not available");
+	}
+
+	printk("\n");
+
+	return 0;
+}
+
+static int ni_65xx_detach(struct comedi_device * dev)
+{
+	if (private(dev) && private(dev)->mite
+		&& private(dev)->mite->daq_io_addr) {
+		writeb(0x00,
+			private(dev)->mite->daq_io_addr +
+			Master_Interrupt_Control);
+	}
+
+	if (dev->irq) {
+		comedi_free_irq(dev->irq, dev);
+	}
+
+	if (private(dev)) {
+		unsigned i;
+		for (i = 0; i < dev->n_subdevices; ++i) {
+			if (dev->subdevices[i].private) {
+				kfree(dev->subdevices[i].private);
+				dev->subdevices[i].private = NULL;
+			}
+		}
+		if (private(dev)->mite) {
+			mite_unsetup(private(dev)->mite);
+		}
+	}
+	return 0;
+}
+
+static int ni_65xx_find_device(struct comedi_device * dev, int bus, int slot)
+{
+	struct mite_struct *mite;
+	int i;
+
+	for (mite = mite_devices; mite; mite = mite->next) {
+		if (mite->used)
+			continue;
+		if (bus || slot) {
+			if (bus != mite->pcidev->bus->number ||
+				slot != PCI_SLOT(mite->pcidev->devfn))
+				continue;
+		}
+		for (i = 0; i < n_ni_65xx_boards; i++) {
+			if (mite_device_id(mite) == ni_65xx_boards[i].dev_id) {
+				dev->board_ptr = ni_65xx_boards + i;
+				private(dev)->mite = mite;
+				return 0;
+			}
+		}
+	}
+	printk("no device found\n");
+	mite_list_devices();
+	return -EIO;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_ni_65xx, ni_65xx_pci_table);
diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c
new file mode 100644
index 0000000..14e35ba
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_660x.c
@@ -0,0 +1,1324 @@
+/*
+  comedi/drivers/ni_660x.c
+  Hardware driver for NI 660x devices
+
+  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.
+*/
+
+/*
+Driver: ni_660x
+Description: National Instruments 660x counter/timer boards
+Devices:
+[National Instruments] PCI-6601 (ni_660x), PCI-6602, PXI-6602,
+	PXI-6608
+Author: J.P. Mellor <jpmellor@rose-hulman.edu>,
+	Herman.Bruyninckx@mech.kuleuven.ac.be,
+	Wim.Meeussen@mech.kuleuven.ac.be,
+	Klaas.Gadeyne@mech.kuleuven.ac.be,
+	Frank Mori Hess <fmhess@users.sourceforge.net>
+Updated: Thu Oct 18 12:56:06 EDT 2007
+Status: experimental
+
+Encoders work.  PulseGeneration (both single pulse and pulse train)
+works. Buffered commands work for input but not output.
+
+References:
+DAQ 660x Register-Level Programmer Manual  (NI 370505A-01)
+DAQ 6601/6602 User Manual (NI 322137B-01)
+
+*/
+
+#include "../comedidev.h"
+#include "mite.h"
+#include "ni_tio.h"
+
+enum ni_660x_constants {
+	min_counter_pfi_chan = 8,
+	max_dio_pfi_chan = 31,
+	counters_per_chip = 4
+};
+
+#define NUM_PFI_CHANNELS 40
+// really there are only up to 3 dma channels, but the register layout allows for 4
+#define MAX_DMA_CHANNEL 4
+
+/* See Register-Level Programmer Manual page 3.1 */
+enum NI_660x_Register {
+	G0InterruptAcknowledge,
+	G0StatusRegister,
+	G1InterruptAcknowledge,
+	G1StatusRegister,
+	G01StatusRegister,
+	G0CommandRegister,
+	STCDIOParallelInput,
+	G1CommandRegister,
+	G0HWSaveRegister,
+	G1HWSaveRegister,
+	STCDIOOutput,
+	STCDIOControl,
+	G0SWSaveRegister,
+	G1SWSaveRegister,
+	G0ModeRegister,
+	G01JointStatus1Register,
+	G1ModeRegister,
+	STCDIOSerialInput,
+	G0LoadARegister,
+	G01JointStatus2Register,
+	G0LoadBRegister,
+	G1LoadARegister,
+	G1LoadBRegister,
+	G0InputSelectRegister,
+	G1InputSelectRegister,
+	G0AutoincrementRegister,
+	G1AutoincrementRegister,
+	G01JointResetRegister,
+	G0InterruptEnable,
+	G1InterruptEnable,
+	G0CountingModeRegister,
+	G1CountingModeRegister,
+	G0SecondGateRegister,
+	G1SecondGateRegister,
+	G0DMAConfigRegister,
+	G0DMAStatusRegister,
+	G1DMAConfigRegister,
+	G1DMAStatusRegister,
+	G2InterruptAcknowledge,
+	G2StatusRegister,
+	G3InterruptAcknowledge,
+	G3StatusRegister,
+	G23StatusRegister,
+	G2CommandRegister,
+	G3CommandRegister,
+	G2HWSaveRegister,
+	G3HWSaveRegister,
+	G2SWSaveRegister,
+	G3SWSaveRegister,
+	G2ModeRegister,
+	G23JointStatus1Register,
+	G3ModeRegister,
+	G2LoadARegister,
+	G23JointStatus2Register,
+	G2LoadBRegister,
+	G3LoadARegister,
+	G3LoadBRegister,
+	G2InputSelectRegister,
+	G3InputSelectRegister,
+	G2AutoincrementRegister,
+	G3AutoincrementRegister,
+	G23JointResetRegister,
+	G2InterruptEnable,
+	G3InterruptEnable,
+	G2CountingModeRegister,
+	G3CountingModeRegister,
+	G3SecondGateRegister,
+	G2SecondGateRegister,
+	G2DMAConfigRegister,
+	G2DMAStatusRegister,
+	G3DMAConfigRegister,
+	G3DMAStatusRegister,
+	DIO32Input,
+	DIO32Output,
+	ClockConfigRegister,
+	GlobalInterruptStatusRegister,
+	DMAConfigRegister,
+	GlobalInterruptConfigRegister,
+	IOConfigReg0_1,
+	IOConfigReg2_3,
+	IOConfigReg4_5,
+	IOConfigReg6_7,
+	IOConfigReg8_9,
+	IOConfigReg10_11,
+	IOConfigReg12_13,
+	IOConfigReg14_15,
+	IOConfigReg16_17,
+	IOConfigReg18_19,
+	IOConfigReg20_21,
+	IOConfigReg22_23,
+	IOConfigReg24_25,
+	IOConfigReg26_27,
+	IOConfigReg28_29,
+	IOConfigReg30_31,
+	IOConfigReg32_33,
+	IOConfigReg34_35,
+	IOConfigReg36_37,
+	IOConfigReg38_39,
+	NumRegisters,
+};
+
+static inline unsigned IOConfigReg(unsigned pfi_channel)
+{
+	unsigned reg = IOConfigReg0_1 + pfi_channel / 2;
+	BUG_ON(reg > IOConfigReg38_39);
+	return reg;
+}
+
+enum ni_660x_register_width {
+	DATA_1B,
+	DATA_2B,
+	DATA_4B
+};
+
+enum ni_660x_register_direction {
+	NI_660x_READ,
+	NI_660x_WRITE,
+	NI_660x_READ_WRITE
+};
+
+enum ni_660x_pfi_output_select {
+	pfi_output_select_high_Z = 0,
+	pfi_output_select_counter = 1,
+	pfi_output_select_do = 2,
+	num_pfi_output_selects
+};
+
+enum ni_660x_subdevices {
+	NI_660X_DIO_SUBDEV = 1,
+	NI_660X_GPCT_SUBDEV_0 = 2
+};
+static inline unsigned NI_660X_GPCT_SUBDEV(unsigned index)
+{
+	return NI_660X_GPCT_SUBDEV_0 + index;
+}
+
+struct NI_660xRegisterData {
+
+	const char *name;	// Register Name
+	int offset;		// Offset from base address from GPCT chip
+	enum ni_660x_register_direction direction;
+	enum ni_660x_register_width size;	// 1 byte, 2 bytes, or 4 bytes
+};
+
+
+static const struct NI_660xRegisterData registerData[NumRegisters] = {
+	{"G0 Interrupt Acknowledge", 0x004, NI_660x_WRITE, DATA_2B},
+	{"G0 Status Register", 0x004, NI_660x_READ, DATA_2B},
+	{"G1 Interrupt Acknowledge", 0x006, NI_660x_WRITE, DATA_2B},
+	{"G1 Status Register", 0x006, NI_660x_READ, DATA_2B},
+	{"G01 Status Register ", 0x008, NI_660x_READ, DATA_2B},
+	{"G0 Command Register", 0x00C, NI_660x_WRITE, DATA_2B},
+	{"STC DIO Parallel Input", 0x00E, NI_660x_READ, DATA_2B},
+	{"G1 Command Register", 0x00E, NI_660x_WRITE, DATA_2B},
+	{"G0 HW Save Register", 0x010, NI_660x_READ, DATA_4B},
+	{"G1 HW Save Register", 0x014, NI_660x_READ, DATA_4B},
+	{"STC DIO Output", 0x014, NI_660x_WRITE, DATA_2B},
+	{"STC DIO Control", 0x016, NI_660x_WRITE, DATA_2B},
+	{"G0 SW Save Register", 0x018, NI_660x_READ, DATA_4B},
+	{"G1 SW Save Register", 0x01C, NI_660x_READ, DATA_4B},
+	{"G0 Mode Register", 0x034, NI_660x_WRITE, DATA_2B},
+	{"G01 Joint Status 1 Register", 0x036, NI_660x_READ, DATA_2B},
+	{"G1 Mode Register", 0x036, NI_660x_WRITE, DATA_2B},
+	{"STC DIO Serial Input", 0x038, NI_660x_READ, DATA_2B},
+	{"G0 Load A Register", 0x038, NI_660x_WRITE, DATA_4B},
+	{"G01 Joint Status 2 Register", 0x03A, NI_660x_READ, DATA_2B},
+	{"G0 Load B Register", 0x03C, NI_660x_WRITE, DATA_4B},
+	{"G1 Load A Register", 0x040, NI_660x_WRITE, DATA_4B},
+	{"G1 Load B Register", 0x044, NI_660x_WRITE, DATA_4B},
+	{"G0 Input Select Register", 0x048, NI_660x_WRITE, DATA_2B},
+	{"G1 Input Select Register", 0x04A, NI_660x_WRITE, DATA_2B},
+	{"G0 Autoincrement Register", 0x088, NI_660x_WRITE, DATA_2B},
+	{"G1 Autoincrement Register", 0x08A, NI_660x_WRITE, DATA_2B},
+	{"G01 Joint Reset Register", 0x090, NI_660x_WRITE, DATA_2B},
+	{"G0 Interrupt Enable", 0x092, NI_660x_WRITE, DATA_2B},
+	{"G1 Interrupt Enable", 0x096, NI_660x_WRITE, DATA_2B},
+	{"G0 Counting Mode Register", 0x0B0, NI_660x_WRITE, DATA_2B},
+	{"G1 Counting Mode Register", 0x0B2, NI_660x_WRITE, DATA_2B},
+	{"G0 Second Gate Register", 0x0B4, NI_660x_WRITE, DATA_2B},
+	{"G1 Second Gate Register", 0x0B6, NI_660x_WRITE, DATA_2B},
+	{"G0 DMA Config Register", 0x0B8, NI_660x_WRITE, DATA_2B},
+	{"G0 DMA Status Register", 0x0B8, NI_660x_READ, DATA_2B},
+	{"G1 DMA Config Register", 0x0BA, NI_660x_WRITE, DATA_2B},
+	{"G1 DMA Status Register", 0x0BA, NI_660x_READ, DATA_2B},
+	{"G2 Interrupt Acknowledge", 0x104, NI_660x_WRITE, DATA_2B},
+	{"G2 Status Register", 0x104, NI_660x_READ, DATA_2B},
+	{"G3 Interrupt Acknowledge", 0x106, NI_660x_WRITE, DATA_2B},
+	{"G3 Status Register", 0x106, NI_660x_READ, DATA_2B},
+	{"G23 Status Register", 0x108, NI_660x_READ, DATA_2B},
+	{"G2 Command Register", 0x10C, NI_660x_WRITE, DATA_2B},
+	{"G3 Command Register", 0x10E, NI_660x_WRITE, DATA_2B},
+	{"G2 HW Save Register", 0x110, NI_660x_READ, DATA_4B},
+	{"G3 HW Save Register", 0x114, NI_660x_READ, DATA_4B},
+	{"G2 SW Save Register", 0x118, NI_660x_READ, DATA_4B},
+	{"G3 SW Save Register", 0x11C, NI_660x_READ, DATA_4B},
+	{"G2 Mode Register", 0x134, NI_660x_WRITE, DATA_2B},
+	{"G23 Joint Status 1 Register", 0x136, NI_660x_READ, DATA_2B},
+	{"G3 Mode Register", 0x136, NI_660x_WRITE, DATA_2B},
+	{"G2 Load A Register", 0x138, NI_660x_WRITE, DATA_4B},
+	{"G23 Joint Status 2 Register", 0x13A, NI_660x_READ, DATA_2B},
+	{"G2 Load B Register", 0x13C, NI_660x_WRITE, DATA_4B},
+	{"G3 Load A Register", 0x140, NI_660x_WRITE, DATA_4B},
+	{"G3 Load B Register", 0x144, NI_660x_WRITE, DATA_4B},
+	{"G2 Input Select Register", 0x148, NI_660x_WRITE, DATA_2B},
+	{"G3 Input Select Register", 0x14A, NI_660x_WRITE, DATA_2B},
+	{"G2 Autoincrement Register", 0x188, NI_660x_WRITE, DATA_2B},
+	{"G3 Autoincrement Register", 0x18A, NI_660x_WRITE, DATA_2B},
+	{"G23 Joint Reset Register", 0x190, NI_660x_WRITE, DATA_2B},
+	{"G2 Interrupt Enable", 0x192, NI_660x_WRITE, DATA_2B},
+	{"G3 Interrupt Enable", 0x196, NI_660x_WRITE, DATA_2B},
+	{"G2 Counting Mode Register", 0x1B0, NI_660x_WRITE, DATA_2B},
+	{"G3 Counting Mode Register", 0x1B2, NI_660x_WRITE, DATA_2B},
+	{"G3 Second Gate Register", 0x1B6, NI_660x_WRITE, DATA_2B},
+	{"G2 Second Gate Register", 0x1B4, NI_660x_WRITE, DATA_2B},
+	{"G2 DMA Config Register", 0x1B8, NI_660x_WRITE, DATA_2B},
+	{"G2 DMA Status Register", 0x1B8, NI_660x_READ, DATA_2B},
+	{"G3 DMA Config Register", 0x1BA, NI_660x_WRITE, DATA_2B},
+	{"G3 DMA Status Register", 0x1BA, NI_660x_READ, DATA_2B},
+	{"32 bit Digital Input", 0x414, NI_660x_READ, DATA_4B},
+	{"32 bit Digital Output", 0x510, NI_660x_WRITE, DATA_4B},
+	{"Clock Config Register", 0x73C, NI_660x_WRITE, DATA_4B},
+	{"Global Interrupt Status Register", 0x754, NI_660x_READ, DATA_4B},
+	{"DMA Configuration Register", 0x76C, NI_660x_WRITE, DATA_4B},
+	{"Global Interrupt Config Register", 0x770, NI_660x_WRITE, DATA_4B},
+	{"IO Config Register 0-1", 0x77C, NI_660x_READ_WRITE, DATA_2B},
+	{"IO Config Register 2-3", 0x77E, NI_660x_READ_WRITE, DATA_2B},
+	{"IO Config Register 4-5", 0x780, NI_660x_READ_WRITE, DATA_2B},
+	{"IO Config Register 6-7", 0x782, NI_660x_READ_WRITE, DATA_2B},
+	{"IO Config Register 8-9", 0x784, NI_660x_READ_WRITE, DATA_2B},
+	{"IO Config Register 10-11", 0x786, NI_660x_READ_WRITE, DATA_2B},
+	{"IO Config Register 12-13", 0x788, NI_660x_READ_WRITE, DATA_2B},
+	{"IO Config Register 14-15", 0x78A, NI_660x_READ_WRITE, DATA_2B},
+	{"IO Config Register 16-17", 0x78C, NI_660x_READ_WRITE, DATA_2B},
+	{"IO Config Register 18-19", 0x78E, NI_660x_READ_WRITE, DATA_2B},
+	{"IO Config Register 20-21", 0x790, NI_660x_READ_WRITE, DATA_2B},
+	{"IO Config Register 22-23", 0x792, NI_660x_READ_WRITE, DATA_2B},
+	{"IO Config Register 24-25", 0x794, NI_660x_READ_WRITE, DATA_2B},
+	{"IO Config Register 26-27", 0x796, NI_660x_READ_WRITE, DATA_2B},
+	{"IO Config Register 28-29", 0x798, NI_660x_READ_WRITE, DATA_2B},
+	{"IO Config Register 30-31", 0x79A, NI_660x_READ_WRITE, DATA_2B},
+	{"IO Config Register 32-33", 0x79C, NI_660x_READ_WRITE, DATA_2B},
+	{"IO Config Register 34-35", 0x79E, NI_660x_READ_WRITE, DATA_2B},
+	{"IO Config Register 36-37", 0x7A0, NI_660x_READ_WRITE, DATA_2B},
+	{"IO Config Register 38-39", 0x7A2, NI_660x_READ_WRITE, DATA_2B}
+};
+
+// kind of ENABLE for the second counter
+enum clock_config_register_bits {
+	CounterSwap = 0x1 << 21
+};
+
+// ioconfigreg
+static inline unsigned ioconfig_bitshift(unsigned pfi_channel)
+{
+	if (pfi_channel % 2)
+		return 0;
+	else
+		return 8;
+}
+static inline unsigned pfi_output_select_mask(unsigned pfi_channel)
+{
+	return 0x3 << ioconfig_bitshift(pfi_channel);
+}
+static inline unsigned pfi_output_select_bits(unsigned pfi_channel,
+	unsigned output_select)
+{
+	return (output_select & 0x3) << ioconfig_bitshift(pfi_channel);
+}
+static inline unsigned pfi_input_select_mask(unsigned pfi_channel)
+{
+	return 0x7 << (4 + ioconfig_bitshift(pfi_channel));
+}
+static inline unsigned pfi_input_select_bits(unsigned pfi_channel,
+	unsigned input_select)
+{
+	return (input_select & 0x7) << (4 + ioconfig_bitshift(pfi_channel));
+}
+
+// dma configuration register bits
+static inline unsigned dma_select_mask(unsigned dma_channel)
+{
+	BUG_ON(dma_channel >= MAX_DMA_CHANNEL);
+	return 0x1f << (8 * dma_channel);
+}
+enum dma_selection {
+	dma_selection_none = 0x1f,
+};
+static inline unsigned dma_selection_counter(unsigned counter_index)
+{
+	BUG_ON(counter_index >= counters_per_chip);
+	return counter_index;
+}
+static inline unsigned dma_select_bits(unsigned dma_channel, unsigned selection)
+{
+	BUG_ON(dma_channel >= MAX_DMA_CHANNEL);
+	return (selection << (8 * dma_channel)) & dma_select_mask(dma_channel);
+}
+static inline unsigned dma_reset_bit(unsigned dma_channel)
+{
+	BUG_ON(dma_channel >= MAX_DMA_CHANNEL);
+	return 0x80 << (8 * dma_channel);
+}
+
+enum global_interrupt_status_register_bits {
+	Counter_0_Int_Bit = 0x100,
+	Counter_1_Int_Bit = 0x200,
+	Counter_2_Int_Bit = 0x400,
+	Counter_3_Int_Bit = 0x800,
+	Cascade_Int_Bit = 0x20000000,
+	Global_Int_Bit = 0x80000000
+};
+
+enum global_interrupt_config_register_bits {
+	Cascade_Int_Enable_Bit = 0x20000000,
+	Global_Int_Polarity_Bit = 0x40000000,
+	Global_Int_Enable_Bit = 0x80000000
+};
+
+// Offset of the GPCT chips from the base-adress of the card
+static const unsigned GPCT_OFFSET[2] = { 0x0, 0x800 };	/* First chip is at base-address +
+							   0x00, etc. */
+
+/* Board description*/
+struct ni_660x_board {
+	unsigned short dev_id;	/* `lspci` will show you this */
+	const char *name;
+	unsigned n_chips;	/* total number of TIO chips */
+};
+
+static const struct ni_660x_board ni_660x_boards[] = {
+	{
+	      dev_id:	0x2c60,
+	      name:	"PCI-6601",
+	      n_chips:	1,
+		},
+	{
+	      dev_id:	0x1310,
+	      name:	"PCI-6602",
+	      n_chips:	2,
+		},
+	{
+	      dev_id:	0x1360,
+	      name:	"PXI-6602",
+	      n_chips:	2,
+		},
+	{
+	      dev_id:	0x2cc0,
+	      name:	"PXI-6608",
+	      n_chips:	2,
+		},
+};
+
+#define NI_660X_MAX_NUM_CHIPS 2
+#define NI_660X_MAX_NUM_COUNTERS (NI_660X_MAX_NUM_CHIPS * counters_per_chip)
+
+static DEFINE_PCI_DEVICE_TABLE(ni_660x_pci_table) = {
+	{PCI_VENDOR_ID_NATINST, 0x2c60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x1310, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x2cc0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, ni_660x_pci_table);
+
+struct ni_660x_private {
+	struct mite_struct *mite;
+	struct ni_gpct_device *counter_dev;
+	uint64_t pfi_direction_bits;
+	struct mite_dma_descriptor_ring
+	*mite_rings[NI_660X_MAX_NUM_CHIPS][counters_per_chip];
+	spinlock_t mite_channel_lock;
+	unsigned dma_configuration_soft_copies[NI_660X_MAX_NUM_CHIPS];
+	spinlock_t soft_reg_copy_lock;
+	unsigned short pfi_output_selects[NUM_PFI_CHANNELS];
+};
+
+static inline struct ni_660x_private *private(struct comedi_device * dev)
+{
+	return dev->private;
+}
+
+/* initialized in ni_660x_find_device() */
+static inline const struct ni_660x_board *board(struct comedi_device * dev)
+{
+	return dev->board_ptr;
+}
+
+#define n_ni_660x_boards (sizeof(ni_660x_boards)/sizeof(ni_660x_boards[0]))
+
+static int ni_660x_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int ni_660x_detach(struct comedi_device * dev);
+static void init_tio_chip(struct comedi_device * dev, int chipset);
+static void ni_660x_select_pfi_output(struct comedi_device * dev, unsigned pfi_channel,
+	unsigned output_select);
+
+static struct comedi_driver driver_ni_660x = {
+      driver_name:"ni_660x",
+      module:THIS_MODULE,
+      attach:ni_660x_attach,
+      detach:ni_660x_detach,
+};
+
+COMEDI_PCI_INITCLEANUP(driver_ni_660x, ni_660x_pci_table);
+
+static int ni_660x_find_device(struct comedi_device * dev, int bus, int slot);
+static int ni_660x_set_pfi_routing(struct comedi_device * dev, unsigned chan,
+	unsigned source);
+
+/* Possible instructions for a GPCT */
+static int ni_660x_GPCT_rinsn(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+static int ni_660x_GPCT_insn_config(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+static int ni_660x_GPCT_winsn(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+/* Possible instructions for Digital IO */
+static int ni_660x_dio_insn_config(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+static int ni_660x_dio_insn_bits(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+static inline unsigned ni_660x_num_counters(struct comedi_device * dev)
+{
+	return board(dev)->n_chips * counters_per_chip;
+}
+
+static enum NI_660x_Register ni_gpct_to_660x_register(enum ni_gpct_register reg)
+{
+	enum NI_660x_Register ni_660x_register;
+	switch (reg) {
+	case NITIO_G0_Autoincrement_Reg:
+		ni_660x_register = G0AutoincrementRegister;
+		break;
+	case NITIO_G1_Autoincrement_Reg:
+		ni_660x_register = G1AutoincrementRegister;
+		break;
+	case NITIO_G2_Autoincrement_Reg:
+		ni_660x_register = G2AutoincrementRegister;
+		break;
+	case NITIO_G3_Autoincrement_Reg:
+		ni_660x_register = G3AutoincrementRegister;
+		break;
+	case NITIO_G0_Command_Reg:
+		ni_660x_register = G0CommandRegister;
+		break;
+	case NITIO_G1_Command_Reg:
+		ni_660x_register = G1CommandRegister;
+		break;
+	case NITIO_G2_Command_Reg:
+		ni_660x_register = G2CommandRegister;
+		break;
+	case NITIO_G3_Command_Reg:
+		ni_660x_register = G3CommandRegister;
+		break;
+	case NITIO_G0_HW_Save_Reg:
+		ni_660x_register = G0HWSaveRegister;
+		break;
+	case NITIO_G1_HW_Save_Reg:
+		ni_660x_register = G1HWSaveRegister;
+		break;
+	case NITIO_G2_HW_Save_Reg:
+		ni_660x_register = G2HWSaveRegister;
+		break;
+	case NITIO_G3_HW_Save_Reg:
+		ni_660x_register = G3HWSaveRegister;
+		break;
+	case NITIO_G0_SW_Save_Reg:
+		ni_660x_register = G0SWSaveRegister;
+		break;
+	case NITIO_G1_SW_Save_Reg:
+		ni_660x_register = G1SWSaveRegister;
+		break;
+	case NITIO_G2_SW_Save_Reg:
+		ni_660x_register = G2SWSaveRegister;
+		break;
+	case NITIO_G3_SW_Save_Reg:
+		ni_660x_register = G3SWSaveRegister;
+		break;
+	case NITIO_G0_Mode_Reg:
+		ni_660x_register = G0ModeRegister;
+		break;
+	case NITIO_G1_Mode_Reg:
+		ni_660x_register = G1ModeRegister;
+		break;
+	case NITIO_G2_Mode_Reg:
+		ni_660x_register = G2ModeRegister;
+		break;
+	case NITIO_G3_Mode_Reg:
+		ni_660x_register = G3ModeRegister;
+		break;
+	case NITIO_G0_LoadA_Reg:
+		ni_660x_register = G0LoadARegister;
+		break;
+	case NITIO_G1_LoadA_Reg:
+		ni_660x_register = G1LoadARegister;
+		break;
+	case NITIO_G2_LoadA_Reg:
+		ni_660x_register = G2LoadARegister;
+		break;
+	case NITIO_G3_LoadA_Reg:
+		ni_660x_register = G3LoadARegister;
+		break;
+	case NITIO_G0_LoadB_Reg:
+		ni_660x_register = G0LoadBRegister;
+		break;
+	case NITIO_G1_LoadB_Reg:
+		ni_660x_register = G1LoadBRegister;
+		break;
+	case NITIO_G2_LoadB_Reg:
+		ni_660x_register = G2LoadBRegister;
+		break;
+	case NITIO_G3_LoadB_Reg:
+		ni_660x_register = G3LoadBRegister;
+		break;
+	case NITIO_G0_Input_Select_Reg:
+		ni_660x_register = G0InputSelectRegister;
+		break;
+	case NITIO_G1_Input_Select_Reg:
+		ni_660x_register = G1InputSelectRegister;
+		break;
+	case NITIO_G2_Input_Select_Reg:
+		ni_660x_register = G2InputSelectRegister;
+		break;
+	case NITIO_G3_Input_Select_Reg:
+		ni_660x_register = G3InputSelectRegister;
+		break;
+	case NITIO_G01_Status_Reg:
+		ni_660x_register = G01StatusRegister;
+		break;
+	case NITIO_G23_Status_Reg:
+		ni_660x_register = G23StatusRegister;
+		break;
+	case NITIO_G01_Joint_Reset_Reg:
+		ni_660x_register = G01JointResetRegister;
+		break;
+	case NITIO_G23_Joint_Reset_Reg:
+		ni_660x_register = G23JointResetRegister;
+		break;
+	case NITIO_G01_Joint_Status1_Reg:
+		ni_660x_register = G01JointStatus1Register;
+		break;
+	case NITIO_G23_Joint_Status1_Reg:
+		ni_660x_register = G23JointStatus1Register;
+		break;
+	case NITIO_G01_Joint_Status2_Reg:
+		ni_660x_register = G01JointStatus2Register;
+		break;
+	case NITIO_G23_Joint_Status2_Reg:
+		ni_660x_register = G23JointStatus2Register;
+		break;
+	case NITIO_G0_Counting_Mode_Reg:
+		ni_660x_register = G0CountingModeRegister;
+		break;
+	case NITIO_G1_Counting_Mode_Reg:
+		ni_660x_register = G1CountingModeRegister;
+		break;
+	case NITIO_G2_Counting_Mode_Reg:
+		ni_660x_register = G2CountingModeRegister;
+		break;
+	case NITIO_G3_Counting_Mode_Reg:
+		ni_660x_register = G3CountingModeRegister;
+		break;
+	case NITIO_G0_Second_Gate_Reg:
+		ni_660x_register = G0SecondGateRegister;
+		break;
+	case NITIO_G1_Second_Gate_Reg:
+		ni_660x_register = G1SecondGateRegister;
+		break;
+	case NITIO_G2_Second_Gate_Reg:
+		ni_660x_register = G2SecondGateRegister;
+		break;
+	case NITIO_G3_Second_Gate_Reg:
+		ni_660x_register = G3SecondGateRegister;
+		break;
+	case NITIO_G0_DMA_Config_Reg:
+		ni_660x_register = G0DMAConfigRegister;
+		break;
+	case NITIO_G0_DMA_Status_Reg:
+		ni_660x_register = G0DMAStatusRegister;
+		break;
+	case NITIO_G1_DMA_Config_Reg:
+		ni_660x_register = G1DMAConfigRegister;
+		break;
+	case NITIO_G1_DMA_Status_Reg:
+		ni_660x_register = G1DMAStatusRegister;
+		break;
+	case NITIO_G2_DMA_Config_Reg:
+		ni_660x_register = G2DMAConfigRegister;
+		break;
+	case NITIO_G2_DMA_Status_Reg:
+		ni_660x_register = G2DMAStatusRegister;
+		break;
+	case NITIO_G3_DMA_Config_Reg:
+		ni_660x_register = G3DMAConfigRegister;
+		break;
+	case NITIO_G3_DMA_Status_Reg:
+		ni_660x_register = G3DMAStatusRegister;
+		break;
+	case NITIO_G0_Interrupt_Acknowledge_Reg:
+		ni_660x_register = G0InterruptAcknowledge;
+		break;
+	case NITIO_G1_Interrupt_Acknowledge_Reg:
+		ni_660x_register = G1InterruptAcknowledge;
+		break;
+	case NITIO_G2_Interrupt_Acknowledge_Reg:
+		ni_660x_register = G2InterruptAcknowledge;
+		break;
+	case NITIO_G3_Interrupt_Acknowledge_Reg:
+		ni_660x_register = G3InterruptAcknowledge;
+		break;
+	case NITIO_G0_Status_Reg:
+		ni_660x_register = G0StatusRegister;
+		break;
+	case NITIO_G1_Status_Reg:
+		ni_660x_register = G0StatusRegister;
+		break;
+	case NITIO_G2_Status_Reg:
+		ni_660x_register = G0StatusRegister;
+		break;
+	case NITIO_G3_Status_Reg:
+		ni_660x_register = G0StatusRegister;
+		break;
+	case NITIO_G0_Interrupt_Enable_Reg:
+		ni_660x_register = G0InterruptEnable;
+		break;
+	case NITIO_G1_Interrupt_Enable_Reg:
+		ni_660x_register = G1InterruptEnable;
+		break;
+	case NITIO_G2_Interrupt_Enable_Reg:
+		ni_660x_register = G2InterruptEnable;
+		break;
+	case NITIO_G3_Interrupt_Enable_Reg:
+		ni_660x_register = G3InterruptEnable;
+		break;
+	default:
+		rt_printk("%s: unhandled register 0x%x in switch.\n",
+			__FUNCTION__, reg);
+		BUG();
+		return 0;
+		break;
+	}
+	return ni_660x_register;
+}
+
+static inline void ni_660x_write_register(struct comedi_device * dev,
+	unsigned chip_index, unsigned bits, enum NI_660x_Register reg)
+{
+	void *const write_address =
+		private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] +
+		registerData[reg].offset;
+
+	switch (registerData[reg].size) {
+	case DATA_2B:
+		writew(bits, write_address);
+		break;
+	case DATA_4B:
+		writel(bits, write_address);
+		break;
+	default:
+		rt_printk("%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
+			__FILE__, __FUNCTION__, reg);
+		BUG();
+		break;
+	}
+}
+
+static inline unsigned ni_660x_read_register(struct comedi_device * dev,
+	unsigned chip_index, enum NI_660x_Register reg)
+{
+	void *const read_address =
+		private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] +
+		registerData[reg].offset;
+
+	switch (registerData[reg].size) {
+	case DATA_2B:
+		return readw(read_address);
+		break;
+	case DATA_4B:
+		return readl(read_address);
+		break;
+	default:
+		rt_printk("%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
+			__FILE__, __FUNCTION__, reg);
+		BUG();
+		break;
+	}
+	return 0;
+}
+
+static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits,
+	enum ni_gpct_register reg)
+{
+	struct comedi_device *dev = counter->counter_dev->dev;
+	enum NI_660x_Register ni_660x_register = ni_gpct_to_660x_register(reg);
+	ni_660x_write_register(dev, counter->chip_index, bits,
+		ni_660x_register);
+}
+
+static unsigned ni_gpct_read_register(struct ni_gpct *counter,
+	enum ni_gpct_register reg)
+{
+	struct comedi_device *dev = counter->counter_dev->dev;
+	enum NI_660x_Register ni_660x_register = ni_gpct_to_660x_register(reg);
+	return ni_660x_read_register(dev, counter->chip_index,
+		ni_660x_register);
+}
+
+static inline struct mite_dma_descriptor_ring *mite_ring(struct ni_660x_private * priv,
+	struct ni_gpct *counter)
+{
+	return priv->mite_rings[counter->chip_index][counter->counter_index];
+}
+
+static inline void ni_660x_set_dma_channel(struct comedi_device * dev,
+	unsigned mite_channel, struct ni_gpct *counter)
+{
+	unsigned long flags;
+	comedi_spin_lock_irqsave(&private(dev)->soft_reg_copy_lock, flags);
+	private(dev)->dma_configuration_soft_copies[counter->chip_index] &=
+		~dma_select_mask(mite_channel);
+	private(dev)->dma_configuration_soft_copies[counter->chip_index] |=
+		dma_select_bits(mite_channel,
+		dma_selection_counter(counter->counter_index));
+	ni_660x_write_register(dev, counter->chip_index,
+		private(dev)->dma_configuration_soft_copies[counter->
+			chip_index] | dma_reset_bit(mite_channel),
+		DMAConfigRegister);
+	mmiowb();
+	comedi_spin_unlock_irqrestore(&private(dev)->soft_reg_copy_lock, flags);
+}
+
+static inline void ni_660x_unset_dma_channel(struct comedi_device * dev,
+	unsigned mite_channel, struct ni_gpct *counter)
+{
+	unsigned long flags;
+	comedi_spin_lock_irqsave(&private(dev)->soft_reg_copy_lock, flags);
+	private(dev)->dma_configuration_soft_copies[counter->chip_index] &=
+		~dma_select_mask(mite_channel);
+	private(dev)->dma_configuration_soft_copies[counter->chip_index] |=
+		dma_select_bits(mite_channel, dma_selection_none);
+	ni_660x_write_register(dev, counter->chip_index,
+		private(dev)->dma_configuration_soft_copies[counter->
+			chip_index], DMAConfigRegister);
+	mmiowb();
+	comedi_spin_unlock_irqrestore(&private(dev)->soft_reg_copy_lock, flags);
+}
+
+static int ni_660x_request_mite_channel(struct comedi_device * dev,
+	struct ni_gpct *counter, enum comedi_io_direction direction)
+{
+	unsigned long flags;
+	struct mite_channel *mite_chan;
+
+	comedi_spin_lock_irqsave(&private(dev)->mite_channel_lock, flags);
+	BUG_ON(counter->mite_chan);
+	mite_chan =
+		mite_request_channel(private(dev)->mite, mite_ring(private(dev),
+			counter));
+	if (mite_chan == NULL) {
+		comedi_spin_unlock_irqrestore(&private(dev)->mite_channel_lock,
+			flags);
+		comedi_error(dev,
+			"failed to reserve mite dma channel for counter.");
+		return -EBUSY;
+	}
+	mite_chan->dir = direction;
+	ni_tio_set_mite_channel(counter, mite_chan);
+	ni_660x_set_dma_channel(dev, mite_chan->channel, counter);
+	comedi_spin_unlock_irqrestore(&private(dev)->mite_channel_lock, flags);
+	return 0;
+}
+
+void ni_660x_release_mite_channel(struct comedi_device * dev, struct ni_gpct *counter)
+{
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&private(dev)->mite_channel_lock, flags);
+	if (counter->mite_chan) {
+		struct mite_channel *mite_chan = counter->mite_chan;
+
+		ni_660x_unset_dma_channel(dev, mite_chan->channel, counter);
+		ni_tio_set_mite_channel(counter, NULL);
+		mite_release_channel(mite_chan);
+	}
+	comedi_spin_unlock_irqrestore(&private(dev)->mite_channel_lock, flags);
+}
+
+static int ni_660x_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	int retval;
+
+	struct ni_gpct *counter = subdev_to_counter(s);
+//      const struct comedi_cmd *cmd = &s->async->cmd;
+
+	retval = ni_660x_request_mite_channel(dev, counter, COMEDI_INPUT);
+	if (retval) {
+		comedi_error(dev,
+			"no dma channel available for use by counter");
+		return retval;
+	}
+	ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL);
+	retval = ni_tio_cmd(counter, s->async);
+
+	return retval;
+}
+
+static int ni_660x_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	struct ni_gpct *counter = subdev_to_counter(s);
+
+	return ni_tio_cmdtest(counter, cmd);
+}
+
+static int ni_660x_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct ni_gpct *counter = subdev_to_counter(s);
+	int retval;
+
+	retval = ni_tio_cancel(counter);
+	ni_660x_release_mite_channel(dev, counter);
+	return retval;
+}
+
+static void set_tio_counterswap(struct comedi_device * dev, int chipset)
+{
+	/* See P. 3.5 of the Register-Level Programming manual.  The
+	   CounterSwap bit has to be set on the second chip, otherwise
+	   it will try to use the same pins as the first chip.
+	 */
+	if (chipset)
+		ni_660x_write_register(dev, chipset, CounterSwap,
+			ClockConfigRegister);
+	else
+		ni_660x_write_register(dev, chipset, 0, ClockConfigRegister);
+}
+
+static void ni_660x_handle_gpct_interrupt(struct comedi_device * dev,
+	struct comedi_subdevice * s)
+{
+	ni_tio_handle_interrupt(subdev_to_counter(s), s);
+	if (s->async->events) {
+		if (s->async->
+			events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
+				COMEDI_CB_OVERFLOW)) {
+			ni_660x_cancel(dev, s);
+		}
+		comedi_event(dev, s);
+	}
+}
+
+static irqreturn_t ni_660x_interrupt(int irq, void *d PT_REGS_ARG)
+{
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s;
+	unsigned i;
+
+	if (dev->attached == 0)
+		return IRQ_NONE;
+	smp_mb();
+	for (i = 0; i < ni_660x_num_counters(dev); ++i) {
+		s = dev->subdevices + NI_660X_GPCT_SUBDEV(i);
+		ni_660x_handle_gpct_interrupt(dev, s);
+	}
+	return IRQ_HANDLED;
+}
+
+static int ni_660x_buf_change(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned long new_size)
+{
+	int ret;
+
+	ret = mite_buf_change(mite_ring(private(dev), subdev_to_counter(s)),
+		s->async);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int ni_660x_allocate_private(struct comedi_device * dev)
+{
+	int retval;
+	unsigned i;
+
+	if ((retval = alloc_private(dev, sizeof(struct ni_660x_private))) < 0)
+		return retval;
+	spin_lock_init(&private(dev)->mite_channel_lock);
+	spin_lock_init(&private(dev)->soft_reg_copy_lock);
+	for (i = 0; i < NUM_PFI_CHANNELS; ++i) {
+		private(dev)->pfi_output_selects[i] = pfi_output_select_counter;
+	}
+	return 0;
+}
+
+static int ni_660x_alloc_mite_rings(struct comedi_device * dev)
+{
+	unsigned i;
+	unsigned j;
+
+	for (i = 0; i < board(dev)->n_chips; ++i) {
+		for (j = 0; j < counters_per_chip; ++j) {
+			private(dev)->mite_rings[i][j] =
+				mite_alloc_ring(private(dev)->mite);
+			if (private(dev)->mite_rings[i][j] == NULL) {
+				return -ENOMEM;
+			}
+		}
+	}
+	return 0;
+}
+
+static void ni_660x_free_mite_rings(struct comedi_device * dev)
+{
+	unsigned i;
+	unsigned j;
+
+	for (i = 0; i < board(dev)->n_chips; ++i) {
+		for (j = 0; j < counters_per_chip; ++j) {
+			mite_free_ring(private(dev)->mite_rings[i][j]);
+		}
+	}
+}
+
+static int ni_660x_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	int ret;
+	unsigned i;
+	unsigned global_interrupt_config_bits;
+
+	printk("comedi%d: ni_660x: ", dev->minor);
+
+	ret = ni_660x_allocate_private(dev);
+	if (ret < 0)
+		return ret;
+	ret = ni_660x_find_device(dev, it->options[0], it->options[1]);
+	if (ret < 0)
+		return ret;
+
+	dev->board_name = board(dev)->name;
+
+	ret = mite_setup2(private(dev)->mite, 1);
+	if (ret < 0) {
+		printk("error setting up mite\n");
+		return ret;
+	}
+	comedi_set_hw_dev(dev, &private(dev)->mite->pcidev->dev);
+	ret = ni_660x_alloc_mite_rings(dev);
+	if (ret < 0)
+		return ret;
+
+	printk(" %s ", dev->board_name);
+
+	dev->n_subdevices = 2 + NI_660X_MAX_NUM_COUNTERS;
+
+	if (alloc_subdevices(dev, dev->n_subdevices) < 0)
+		return -ENOMEM;
+
+	s = dev->subdevices + 0;
+	/* Old GENERAL-PURPOSE COUNTER/TIME (GPCT) subdevice, no longer used */
+	s->type = COMEDI_SUBD_UNUSED;
+
+	s = dev->subdevices + NI_660X_DIO_SUBDEV;
+	/* DIGITAL I/O SUBDEVICE */
+	s->type = COMEDI_SUBD_DIO;
+	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+	s->n_chan = NUM_PFI_CHANNELS;
+	s->maxdata = 1;
+	s->range_table = &range_digital;
+	s->insn_bits = ni_660x_dio_insn_bits;
+	s->insn_config = ni_660x_dio_insn_config;
+	s->io_bits = 0;		/* all bits default to input */
+	// we use the ioconfig registers to control dio direction, so zero output enables in stc dio control reg
+	ni_660x_write_register(dev, 0, 0, STCDIOControl);
+
+	private(dev)->counter_dev = ni_gpct_device_construct(dev,
+		&ni_gpct_write_register, &ni_gpct_read_register,
+		ni_gpct_variant_660x, ni_660x_num_counters(dev));
+	if (private(dev)->counter_dev == NULL)
+		return -ENOMEM;
+	for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) {
+		s = dev->subdevices + NI_660X_GPCT_SUBDEV(i);
+		if (i < ni_660x_num_counters(dev)) {
+			s->type = COMEDI_SUBD_COUNTER;
+			s->subdev_flags =
+				SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL |
+				SDF_CMD_READ /* | SDF_CMD_WRITE */ ;
+			s->n_chan = 3;
+			s->maxdata = 0xffffffff;
+			s->insn_read = ni_660x_GPCT_rinsn;
+			s->insn_write = ni_660x_GPCT_winsn;
+			s->insn_config = ni_660x_GPCT_insn_config;
+			s->do_cmd = &ni_660x_cmd;
+			s->len_chanlist = 1;
+			s->do_cmdtest = &ni_660x_cmdtest;
+			s->cancel = &ni_660x_cancel;
+			s->async_dma_dir = DMA_BIDIRECTIONAL;
+			s->buf_change = &ni_660x_buf_change;
+			s->private = &private(dev)->counter_dev->counters[i];
+
+			private(dev)->counter_dev->counters[i].chip_index =
+				i / counters_per_chip;
+			private(dev)->counter_dev->counters[i].counter_index =
+				i % counters_per_chip;
+		} else {
+			s->type = COMEDI_SUBD_UNUSED;
+		}
+	}
+	for (i = 0; i < board(dev)->n_chips; ++i) {
+		init_tio_chip(dev, i);
+	}
+	for (i = 0; i < ni_660x_num_counters(dev); ++i) {
+		ni_tio_init_counter(&private(dev)->counter_dev->counters[i]);
+	}
+	for (i = 0; i < NUM_PFI_CHANNELS; ++i) {
+		if (i < min_counter_pfi_chan)
+			ni_660x_set_pfi_routing(dev, i, pfi_output_select_do);
+		else
+			ni_660x_set_pfi_routing(dev, i,
+				pfi_output_select_counter);
+		ni_660x_select_pfi_output(dev, i, pfi_output_select_high_Z);
+	}
+	/* to be safe, set counterswap bits on tio chips after all the counter
+	   outputs have been set to high impedance mode */
+	for (i = 0; i < board(dev)->n_chips; ++i) {
+		set_tio_counterswap(dev, i);
+	}
+	if ((ret = comedi_request_irq(mite_irq(private(dev)->mite),
+				&ni_660x_interrupt, IRQF_SHARED, "ni_660x",
+				dev)) < 0) {
+		printk(" irq not available\n");
+		return ret;
+	}
+	dev->irq = mite_irq(private(dev)->mite);
+	global_interrupt_config_bits = Global_Int_Enable_Bit;
+	if (board(dev)->n_chips > 1)
+		global_interrupt_config_bits |= Cascade_Int_Enable_Bit;
+	ni_660x_write_register(dev, 0, global_interrupt_config_bits,
+		GlobalInterruptConfigRegister);
+	printk("attached\n");
+	return 0;
+}
+
+static int ni_660x_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: ni_660x: remove\n", dev->minor);
+
+	/* Free irq */
+	if (dev->irq)
+		comedi_free_irq(dev->irq, dev);
+
+	if (dev->private) {
+		if (private(dev)->counter_dev)
+			ni_gpct_device_destroy(private(dev)->counter_dev);
+		if (private(dev)->mite) {
+			ni_660x_free_mite_rings(dev);
+			mite_unsetup(private(dev)->mite);
+		}
+	}
+	return 0;
+}
+
+static int
+ni_660x_GPCT_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	return ni_tio_rinsn(subdev_to_counter(s), insn, data);
+}
+
+static void init_tio_chip(struct comedi_device * dev, int chipset)
+{
+	unsigned i;
+
+	// init dma configuration register
+	private(dev)->dma_configuration_soft_copies[chipset] = 0;
+	for (i = 0; i < MAX_DMA_CHANNEL; ++i) {
+		private(dev)->dma_configuration_soft_copies[chipset] |=
+			dma_select_bits(i,
+			dma_selection_none) & dma_select_mask(i);
+	}
+	ni_660x_write_register(dev, chipset,
+		private(dev)->dma_configuration_soft_copies[chipset],
+		DMAConfigRegister);
+	for(i = 0; i < NUM_PFI_CHANNELS; ++i)
+	{
+		ni_660x_write_register(dev, chipset, 0, IOConfigReg(i));
+	}
+}
+
+static int
+ni_660x_GPCT_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	return ni_tio_insn_config(subdev_to_counter(s), insn, data);
+}
+
+static int ni_660x_GPCT_winsn(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	return ni_tio_winsn(subdev_to_counter(s), insn, data);
+}
+
+static int ni_660x_find_device(struct comedi_device * dev, int bus, int slot)
+{
+	struct mite_struct *mite;
+	int i;
+
+	for (mite = mite_devices; mite; mite = mite->next) {
+		if (mite->used)
+			continue;
+		if (bus || slot) {
+			if (bus != mite->pcidev->bus->number ||
+				slot != PCI_SLOT(mite->pcidev->devfn))
+				continue;
+		}
+
+		for (i = 0; i < n_ni_660x_boards; i++) {
+			if (mite_device_id(mite) == ni_660x_boards[i].dev_id) {
+				dev->board_ptr = ni_660x_boards + i;
+				private(dev)->mite = mite;
+				return 0;
+			}
+		}
+	}
+	printk("no device found\n");
+	mite_list_devices();
+	return -EIO;
+}
+
+static int ni_660x_dio_insn_bits(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned base_bitfield_channel = CR_CHAN(insn->chanspec);
+
+	// Check if we have to write some bits
+	if (data[0]) {
+		s->state &= ~(data[0] << base_bitfield_channel);
+		s->state |= (data[0] & data[1]) << base_bitfield_channel;
+		/* Write out the new digital output lines */
+		ni_660x_write_register(dev, 0, s->state, DIO32Output);
+	}
+	/* on return, data[1] contains the value of the digital
+	 * input and output lines. */
+	data[1] =
+		(ni_660x_read_register(dev, 0,
+			DIO32Input) >> base_bitfield_channel);
+	return 2;
+}
+
+static void ni_660x_select_pfi_output(struct comedi_device * dev, unsigned pfi_channel,
+	unsigned output_select)
+{
+	static const unsigned counter_4_7_first_pfi = 8;
+	static const unsigned counter_4_7_last_pfi = 23;
+	unsigned active_chipset = 0;
+	unsigned idle_chipset = 0;
+	unsigned active_bits;
+	unsigned idle_bits;
+
+	if(board(dev)->n_chips > 1) {
+		if(output_select == pfi_output_select_counter &&
+			pfi_channel >= counter_4_7_first_pfi &&
+			pfi_channel <= counter_4_7_last_pfi) {
+			active_chipset = 1;
+			idle_chipset = 0;
+		}else {
+			active_chipset = 0;
+			idle_chipset = 1;
+		}
+	}
+
+	if(idle_chipset != active_chipset) {
+		idle_bits = ni_660x_read_register(dev, idle_chipset, IOConfigReg(pfi_channel));
+		idle_bits &= ~pfi_output_select_mask(pfi_channel);
+		idle_bits |= pfi_output_select_bits(pfi_channel, pfi_output_select_high_Z);
+		ni_660x_write_register(dev, idle_chipset, idle_bits, IOConfigReg(pfi_channel));
+	}
+
+	active_bits = ni_660x_read_register(dev, active_chipset, IOConfigReg(pfi_channel));
+	active_bits &= ~pfi_output_select_mask(pfi_channel);
+	active_bits |= pfi_output_select_bits(pfi_channel, output_select);
+	ni_660x_write_register(dev, active_chipset, active_bits, IOConfigReg(pfi_channel));
+}
+
+static int ni_660x_set_pfi_routing(struct comedi_device * dev, unsigned chan,
+	unsigned source)
+{
+	if (source > num_pfi_output_selects)
+		return -EINVAL;
+	if (source == pfi_output_select_high_Z)
+		return -EINVAL;
+	if (chan < min_counter_pfi_chan) {
+		if (source == pfi_output_select_counter)
+			return -EINVAL;
+	} else if (chan > max_dio_pfi_chan) {
+		if (source == pfi_output_select_do)
+			return -EINVAL;
+	}
+	BUG_ON(chan >= NUM_PFI_CHANNELS);
+
+	private(dev)->pfi_output_selects[chan] = source;
+	if (private(dev)->pfi_direction_bits & (((uint64_t) 1) << chan))
+		ni_660x_select_pfi_output(dev, chan,
+			private(dev)->pfi_output_selects[chan]);
+	return 0;
+}
+
+static unsigned ni_660x_get_pfi_routing(struct comedi_device * dev, unsigned chan)
+{
+	BUG_ON(chan >= NUM_PFI_CHANNELS);
+	return private(dev)->pfi_output_selects[chan];
+}
+
+static void ni660x_config_filter(struct comedi_device * dev, unsigned pfi_channel,
+	enum ni_gpct_filter_select filter)
+{
+	unsigned bits = ni_660x_read_register(dev, 0, IOConfigReg(pfi_channel));
+	bits &= ~pfi_input_select_mask(pfi_channel);
+	bits |= pfi_input_select_bits(pfi_channel, filter);
+	ni_660x_write_register(dev, 0, bits, IOConfigReg(pfi_channel));
+}
+
+static int ni_660x_dio_insn_config(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	int chan = CR_CHAN(insn->chanspec);
+
+	/* The input or output configuration of each digital line is
+	 * configured by a special insn_config instruction.  chanspec
+	 * contains the channel to be changed, and data[0] contains the
+	 * value COMEDI_INPUT or COMEDI_OUTPUT. */
+
+	switch (data[0]) {
+	case INSN_CONFIG_DIO_OUTPUT:
+		private(dev)->pfi_direction_bits |= ((uint64_t) 1) << chan;
+		ni_660x_select_pfi_output(dev, chan,
+			private(dev)->pfi_output_selects[chan]);
+		break;
+	case INSN_CONFIG_DIO_INPUT:
+		private(dev)->pfi_direction_bits &= ~(((uint64_t) 1) << chan);
+		ni_660x_select_pfi_output(dev, chan, pfi_output_select_high_Z);
+		break;
+	case INSN_CONFIG_DIO_QUERY:
+		data[1] =
+			(private(dev)->
+			pfi_direction_bits & (((uint64_t) 1) << chan)) ?
+			COMEDI_OUTPUT : COMEDI_INPUT;
+		return 0;
+	case INSN_CONFIG_SET_ROUTING:
+		return ni_660x_set_pfi_routing(dev, chan, data[1]);
+		break;
+	case INSN_CONFIG_GET_ROUTING:
+		data[1] = ni_660x_get_pfi_routing(dev, chan);
+		break;
+	case INSN_CONFIG_FILTER:
+		ni660x_config_filter(dev, chan, data[1]);
+		break;
+	default:
+		return -EINVAL;
+		break;
+	};
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c
new file mode 100644
index 0000000..d1312e0
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_670x.c
@@ -0,0 +1,337 @@
+/*
+    comedi/drivers/ni_670x.c
+    Hardware driver for NI 670x devices
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 1997-2001 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: ni_670x
+Description: National Instruments 670x
+Author: Bart Joris <bjoris@advalvas.be>
+Updated: Wed, 11 Dec 2002 18:25:35 -0800
+Devices: [National Instruments] PCI-6703 (ni_670x), PCI-6704
+Status: unknown
+
+Commands are not supported.
+*/
+
+/*
+	Bart Joris <bjoris@advalvas.be> Last updated on 20/08/2001
+
+	Manuals:
+
+	322110a.pdf	PCI/PXI-6704 User Manual
+	322110b.pdf	PCI/PXI-6703/6704 User Manual
+
+*/
+
+#include "../comedidev.h"
+
+#include "mite.h"
+
+#define PCI_VENDOR_ID_NATINST	0x1093
+
+#define AO_VALUE_OFFSET			0x00
+#define	AO_CHAN_OFFSET			0x0c
+#define	AO_STATUS_OFFSET		0x10
+#define AO_CONTROL_OFFSET		0x10
+#define	DIO_PORT0_DIR_OFFSET	0x20
+#define	DIO_PORT0_DATA_OFFSET	0x24
+#define	DIO_PORT1_DIR_OFFSET	0x28
+#define	DIO_PORT1_DATA_OFFSET	0x2c
+#define	MISC_STATUS_OFFSET		0x14
+#define	MISC_CONTROL_OFFSET		0x14
+
+/* Board description*/
+
+struct ni_670x_board {
+	unsigned short dev_id;
+	const char *name;
+	unsigned short ao_chans;
+	unsigned short ao_bits;
+};
+
+static const struct ni_670x_board ni_670x_boards[] = {
+	{
+	      dev_id:	0x2c90,
+	      name:	"PCI-6703",
+	      ao_chans:16,
+	      ao_bits:	16,
+		},
+	{
+	      dev_id:	0x1920,
+	      name:	"PXI-6704",
+	      ao_chans:32,
+	      ao_bits:	16,
+		},
+	{
+	      dev_id:	0x1290,
+	      name:	"PCI-6704",
+	      ao_chans:32,
+	      ao_bits:	16,
+		},
+};
+
+static DEFINE_PCI_DEVICE_TABLE(ni_670x_pci_table) = {
+	{PCI_VENDOR_ID_NATINST, 0x2c90, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x1920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	//{ PCI_VENDOR_ID_NATINST, 0x0000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, ni_670x_pci_table);
+
+#define thisboard ((struct ni_670x_board *)dev->board_ptr)
+
+struct ni_670x_private {
+
+	struct mite_struct *mite;
+	int boardtype;
+	int dio;
+	unsigned int ao_readback[32];
+};
+
+
+#define devpriv ((struct ni_670x_private *)dev->private)
+#define n_ni_670x_boards (sizeof(ni_670x_boards)/sizeof(ni_670x_boards[0]))
+
+static int ni_670x_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int ni_670x_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver_ni_670x = {
+      driver_name:"ni_670x",
+      module:THIS_MODULE,
+      attach:ni_670x_attach,
+      detach:ni_670x_detach,
+};
+
+COMEDI_PCI_INITCLEANUP(driver_ni_670x, ni_670x_pci_table);
+
+static struct comedi_lrange range_0_20mA = { 1, {RANGE_mA(0, 20)} };
+
+static int ni_670x_find_device(struct comedi_device * dev, int bus, int slot);
+
+static int ni_670x_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int ni_670x_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int ni_670x_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int ni_670x_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+static int ni_670x_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	int ret;
+	int i;
+
+	printk("comedi%d: ni_670x: ", dev->minor);
+
+	if ((ret = alloc_private(dev, sizeof(struct ni_670x_private))) < 0)
+		return ret;
+
+	ret = ni_670x_find_device(dev, it->options[0], it->options[1]);
+	if (ret < 0)
+		return ret;
+
+	ret = mite_setup(devpriv->mite);
+	if (ret < 0) {
+		printk("error setting up mite\n");
+		return ret;
+	}
+	dev->board_name = thisboard->name;
+	dev->irq = mite_irq(devpriv->mite);
+	printk(" %s", dev->board_name);
+
+	if (alloc_subdevices(dev, 2) < 0)
+		return -ENOMEM;
+
+	s = dev->subdevices + 0;
+	/* analog output subdevice */
+	s->type = COMEDI_SUBD_AO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->n_chan = thisboard->ao_chans;
+	s->maxdata = 0xffff;
+	if (s->n_chan == 32) {
+		const struct comedi_lrange **range_table_list;
+
+		range_table_list = kmalloc(sizeof(struct comedi_lrange *) * 32,
+			GFP_KERNEL);
+		if (!range_table_list)
+			return -ENOMEM;
+		s->range_table_list = range_table_list;
+		for (i = 0; i < 16; i++) {
+			range_table_list[i] = &range_bipolar10;
+			range_table_list[16 + i] = &range_0_20mA;
+		}
+	} else {
+		s->range_table = &range_bipolar10;
+	}
+	s->insn_write = &ni_670x_ao_winsn;
+	s->insn_read = &ni_670x_ao_rinsn;
+
+	s = dev->subdevices + 1;
+	/* digital i/o subdevice */
+	s->type = COMEDI_SUBD_DIO;
+	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+	s->n_chan = 8;
+	s->maxdata = 1;
+	s->range_table = &range_digital;
+	s->insn_bits = ni_670x_dio_insn_bits;
+	s->insn_config = ni_670x_dio_insn_config;
+
+	writel(0x10, devpriv->mite->daq_io_addr + MISC_CONTROL_OFFSET);	/* Config of misc registers */
+	writel(0x00, devpriv->mite->daq_io_addr + AO_CONTROL_OFFSET);	/* Config of ao registers */
+
+	printk("attached\n");
+
+	return 1;
+}
+
+static int ni_670x_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: ni_670x: remove\n", dev->minor);
+
+	if (dev->subdevices[0].range_table_list) {
+		kfree(dev->subdevices[0].range_table_list);
+	}
+	if (dev->private && devpriv->mite)
+		mite_unsetup(devpriv->mite);
+
+	if (dev->irq)
+		comedi_free_irq(dev->irq, dev);
+
+	return 0;
+}
+
+static int ni_670x_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+
+	/* Channel number mapping :
+
+	   NI 6703/ NI 6704     | NI 6704 Only
+	   ----------------------------------------------------
+	   vch(0)       :       0       | ich(16)       :       1
+	   vch(1)       :       2       | ich(17)       :       3
+	   .    :       .       |   .                   .
+	   .    :       .       |   .                   .
+	   .    :       .       |   .                   .
+	   vch(15)      :       30      | ich(31)       :       31      */
+
+	for (i = 0; i < insn->n; i++) {
+		writel(((chan & 15) << 1) | ((chan & 16) >> 4), devpriv->mite->daq_io_addr + AO_CHAN_OFFSET);	/* First write in channel register which channel to use */
+		writel(data[i], devpriv->mite->daq_io_addr + AO_VALUE_OFFSET);	/* write channel value */
+		devpriv->ao_readback[chan] = data[i];
+	}
+
+	return i;
+}
+
+static int ni_670x_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+
+	for (i = 0; i < insn->n; i++)
+		data[i] = devpriv->ao_readback[chan];
+
+	return i;
+}
+
+static int ni_670x_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	/* The insn data is a mask in data[0] and the new data
+	 * in data[1], each channel cooresponding to a bit. */
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= data[0] & data[1];
+		writel(s->state,
+			devpriv->mite->daq_io_addr + DIO_PORT0_DATA_OFFSET);
+	}
+
+	/* on return, data[1] contains the value of the digital
+	 * input lines. */
+	data[1] = readl(devpriv->mite->daq_io_addr + DIO_PORT0_DATA_OFFSET);
+
+	return 2;
+}
+
+static int ni_670x_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int chan = CR_CHAN(insn->chanspec);
+
+	switch (data[0]) {
+	case INSN_CONFIG_DIO_OUTPUT:
+		s->io_bits |= 1 << chan;
+		break;
+	case INSN_CONFIG_DIO_INPUT:
+		s->io_bits &= ~(1 << chan);
+		break;
+	case INSN_CONFIG_DIO_QUERY:
+		data[1] =
+			(s->
+			io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+		return insn->n;
+		break;
+	default:
+		return -EINVAL;
+		break;
+	}
+	writel(s->io_bits, devpriv->mite->daq_io_addr + DIO_PORT0_DIR_OFFSET);
+
+	return insn->n;
+}
+
+static int ni_670x_find_device(struct comedi_device * dev, int bus, int slot)
+{
+	struct mite_struct *mite;
+	int i;
+
+	for (mite = mite_devices; mite; mite = mite->next) {
+		if (mite->used)
+			continue;
+		if (bus || slot) {
+			if (bus != mite->pcidev->bus->number
+				|| slot != PCI_SLOT(mite->pcidev->devfn))
+				continue;
+		}
+
+		for (i = 0; i < n_ni_670x_boards; i++) {
+			if (mite_device_id(mite) == ni_670x_boards[i].dev_id) {
+				dev->board_ptr = ni_670x_boards + i;
+				devpriv->mite = mite;
+
+				return 0;
+			}
+		}
+	}
+	printk("no device found\n");
+	mite_list_devices();
+	return -EIO;
+}
diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c
new file mode 100644
index 0000000..5d45bf2
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_at_a2150.c
@@ -0,0 +1,909 @@
+/*
+    comedi/drivers/ni_at_a2150.c
+    Driver for National Instruments AT-A2150 boards
+    Copyright (C) 2001, 2002 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000 David A. Schleef <ds@schleef.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.
+
+    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.
+
+************************************************************************
+*/
+/*
+Driver: ni_at_a2150
+Description: National Instruments AT-A2150
+Author: Frank Mori Hess
+Status: works
+Devices: [National Instruments] AT-A2150C (at_a2150c), AT-2150S (at_a2150s)
+
+If you want to ac couple the board's inputs, use AREF_OTHER.
+
+Configuration options:
+  [0] - I/O port base address
+  [1] - IRQ (optional, required for timed conversions)
+  [2] - DMA (optional, required for timed conversions)
+
+*/
+/*
+Yet another driver for obsolete hardware brought to you by Frank Hess.
+Testing and debugging help provided by Dave Andruczyk.
+
+This driver supports the boards:
+
+AT-A2150C
+AT-A2150S
+
+The only difference is their master clock frequencies.
+
+Options:
+	[0] - base io address
+	[1] - irq
+	[2] - dma channel
+
+References (from ftp://ftp.natinst.com/support/manuals):
+
+	   320360.pdf  AT-A2150 User Manual
+
+TODO:
+
+analog level triggering
+TRIG_WAKE_EOS
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <asm/dma.h>
+
+#include "8253.h"
+#include "comedi_fc.h"
+
+#define A2150_SIZE           28
+#define A2150_DMA_BUFFER_SIZE	0xff00	// size in bytes of dma buffer
+
+//#define A2150_DEBUG   // enable debugging code
+#undef A2150_DEBUG		// disable debugging code
+
+/* Registers and bits */
+#define CONFIG_REG		0x0
+#define   CHANNEL_BITS(x)		((x) & 0x7)
+#define   CHANNEL_MASK		0x7
+#define   CLOCK_SELECT_BITS(x)		(((x) & 0x3) << 3)
+#define   CLOCK_DIVISOR_BITS(x)		(((x) & 0x3) << 5)
+#define   CLOCK_MASK		(0xf << 3)
+#define   ENABLE0_BIT		0x80	// enable (don't internally ground) channels 0 and 1
+#define   ENABLE1_BIT		0x100	// enable (don't internally ground) channels 2 and 3
+#define   AC0_BIT		0x200	// ac couple channels 0,1
+#define   AC1_BIT		0x400	// ac couple channels 2,3
+#define   APD_BIT		0x800	// analog power down
+#define   DPD_BIT		0x1000	// digital power down
+#define TRIGGER_REG		0x2	// trigger config register
+#define   POST_TRIGGER_BITS		0x2
+#define   DELAY_TRIGGER_BITS		0x3
+#define   HW_TRIG_EN		0x10	// enable hardware trigger
+#define FIFO_START_REG		0x6	// software start aquistion trigger
+#define FIFO_RESET_REG		0x8	// clears fifo + fifo flags
+#define FIFO_DATA_REG		0xa	// read data
+#define DMA_TC_CLEAR_REG		0xe	// clear dma terminal count interrupt
+#define STATUS_REG		0x12	// read only
+#define   FNE_BIT		0x1	// fifo not empty
+#define   OVFL_BIT		0x8	// fifo overflow
+#define   EDAQ_BIT		0x10	// end of aquisition interrupt
+#define   DCAL_BIT		0x20	// offset calibration in progress
+#define   INTR_BIT		0x40	// interrupt has occured
+#define   DMA_TC_BIT		0x80	// dma terminal count interrupt has occured
+#define   ID_BITS(x)	(((x) >> 8) & 0x3)
+#define IRQ_DMA_CNTRL_REG		0x12	// write only
+#define   DMA_CHAN_BITS(x)		((x) & 0x7)	// sets dma channel
+#define   DMA_EN_BIT		0x8	// enables dma
+#define   IRQ_LVL_BITS(x)		(((x) & 0xf) << 4)	// sets irq level
+#define   FIFO_INTR_EN_BIT		0x100	// enable fifo interrupts
+#define   FIFO_INTR_FHF_BIT		0x200	// interrupt fifo half full
+#define   DMA_INTR_EN_BIT 		0x800	// enable interrupt on dma terminal count
+#define   DMA_DEM_EN_BIT	0x1000	// enables demand mode dma
+#define I8253_BASE_REG		0x14
+#define I8253_MODE_REG		0x17
+#define   HW_COUNT_DISABLE		0x30	// disable hardware counting of conversions
+
+struct a2150_board {
+	const char *name;
+	int clock[4];		// master clock periods, in nanoseconds
+	int num_clocks;		// number of available master clock speeds
+	int ai_speed;		// maximum conversion rate in nanoseconds
+};
+
+//analog input range
+static const struct comedi_lrange range_a2150 = {
+	1,
+	{
+			RANGE(-2.828, 2.828),
+		}
+};
+
+// enum must match board indices
+enum { a2150_c, a2150_s };
+static const struct a2150_board a2150_boards[] = {
+	{
+	      name:	"at-a2150c",
+	      clock:	{31250, 22676, 20833, 19531},
+	      num_clocks:4,
+	      ai_speed:19531,
+		},
+	{
+	      name:	"at-a2150s",
+	      clock:	{62500, 50000, 41667, 0},
+	      num_clocks:3,
+	      ai_speed:41667,
+		},
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct a2150_board *)dev->board_ptr)
+
+struct a2150_private {
+
+	volatile unsigned int count;	/* number of data points left to be taken */
+	unsigned int dma;	// dma channel
+	s16 *dma_buffer;	// dma buffer
+	unsigned int dma_transfer_size;	// size in bytes of dma transfers
+	int irq_dma_bits;	// irq/dma register bits
+	int config_bits;	// config register bits
+};
+
+
+#define devpriv ((struct a2150_private *)dev->private)
+
+static int a2150_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int a2150_detach(struct comedi_device * dev);
+static int a2150_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static struct comedi_driver driver_a2150 = {
+      driver_name:"ni_at_a2150",
+      module:THIS_MODULE,
+      attach:a2150_attach,
+      detach:a2150_detach,
+};
+
+static irqreturn_t a2150_interrupt(int irq, void *d PT_REGS_ARG);
+static int a2150_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd);
+static int a2150_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int a2150_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int a2150_get_timing(struct comedi_device * dev, unsigned int *period,
+	int flags);
+static int a2150_probe(struct comedi_device * dev);
+static int a2150_set_chanlist(struct comedi_device * dev, unsigned int start_channel,
+	unsigned int num_channels);
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver_a2150);
+
+#ifdef A2150_DEBUG
+
+static void ni_dump_regs(struct comedi_device * dev)
+{
+	rt_printk("config bits 0x%x\n", devpriv->config_bits);
+	rt_printk("irq dma bits 0x%x\n", devpriv->irq_dma_bits);
+	rt_printk("status bits 0x%x\n", inw(dev->iobase + STATUS_REG));
+}
+
+#endif
+
+/* interrupt service routine */
+static irqreturn_t a2150_interrupt(int irq, void *d PT_REGS_ARG)
+{
+	int i;
+	int status;
+	unsigned long flags;
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s = dev->read_subdev;
+	struct comedi_async *async;
+	struct comedi_cmd *cmd;
+	unsigned int max_points, num_points, residue, leftover;
+	short dpnt;
+	static const int sample_size = sizeof(devpriv->dma_buffer[0]);
+
+	if (dev->attached == 0) {
+		comedi_error(dev, "premature interrupt");
+		return IRQ_HANDLED;
+	}
+	// initialize async here to make sure s is not NULL
+	async = s->async;
+	async->events = 0;
+	cmd = &async->cmd;
+
+	status = inw(dev->iobase + STATUS_REG);
+
+	if ((status & INTR_BIT) == 0) {
+		comedi_error(dev, "spurious interrupt");
+		return IRQ_NONE;
+	}
+
+	if (status & OVFL_BIT) {
+		comedi_error(dev, "fifo overflow");
+		a2150_cancel(dev, s);
+		async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+	}
+
+	if ((status & DMA_TC_BIT) == 0) {
+		comedi_error(dev, "caught non-dma interrupt?  Aborting.");
+		a2150_cancel(dev, s);
+		async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+		comedi_event(dev, s);
+		return IRQ_HANDLED;
+	}
+
+	flags = claim_dma_lock();
+	disable_dma(devpriv->dma);
+	/* clear flip-flop to make sure 2-byte registers for
+	 * count and address get set correctly */
+	clear_dma_ff(devpriv->dma);
+
+	// figure out how many points to read
+	max_points = devpriv->dma_transfer_size / sample_size;
+	/* residue is the number of points left to be done on the dma
+	 * transfer.  It should always be zero at this point unless
+	 * the stop_src is set to external triggering.
+	 */
+	residue = get_dma_residue(devpriv->dma) / sample_size;
+	num_points = max_points - residue;
+	if (devpriv->count < num_points && cmd->stop_src == TRIG_COUNT)
+		num_points = devpriv->count;
+
+	// figure out how many points will be stored next time
+	leftover = 0;
+	if (cmd->stop_src == TRIG_NONE) {
+		leftover = devpriv->dma_transfer_size / sample_size;
+	} else if (devpriv->count > max_points) {
+		leftover = devpriv->count - max_points;
+		if (leftover > max_points)
+			leftover = max_points;
+	}
+	/* there should only be a residue if collection was stopped by having
+	 * the stop_src set to an external trigger, in which case there
+	 * will be no more data
+	 */
+	if (residue)
+		leftover = 0;
+
+	for (i = 0; i < num_points; i++) {
+		/* write data point to comedi buffer */
+		dpnt = devpriv->dma_buffer[i];
+		// convert from 2's complement to unsigned coding
+		dpnt ^= 0x8000;
+		cfc_write_to_buffer(s, dpnt);
+		if (cmd->stop_src == TRIG_COUNT) {
+			if (--devpriv->count == 0) {	/* end of acquisition */
+				a2150_cancel(dev, s);
+				async->events |= COMEDI_CB_EOA;
+				break;
+			}
+		}
+	}
+	// re-enable  dma
+	if (leftover) {
+		set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer));
+		set_dma_count(devpriv->dma, leftover * sample_size);
+		enable_dma(devpriv->dma);
+	}
+	release_dma_lock(flags);
+
+	async->events |= COMEDI_CB_BLOCK;
+
+	comedi_event(dev, s);
+
+	/* clear interrupt */
+	outw(0x00, dev->iobase + DMA_TC_CLEAR_REG);
+
+	return IRQ_HANDLED;
+}
+
+// probes board type, returns offset
+static int a2150_probe(struct comedi_device * dev)
+{
+	int status = inw(dev->iobase + STATUS_REG);
+	return ID_BITS(status);
+}
+
+static int a2150_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	unsigned long iobase = it->options[0];
+	unsigned int irq = it->options[1];
+	unsigned int dma = it->options[2];
+	static const int timeout = 2000;
+	int i;
+
+	printk("comedi%d: %s: io 0x%lx", dev->minor, driver_a2150.driver_name,
+		iobase);
+	if (irq) {
+		printk(", irq %u", irq);
+	} else {
+		printk(", no irq");
+	}
+	if (dma) {
+		printk(", dma %u", dma);
+	} else {
+		printk(", no dma");
+	}
+	printk("\n");
+
+	/* allocate and initialize dev->private */
+	if (alloc_private(dev, sizeof(struct a2150_private)) < 0)
+		return -ENOMEM;
+
+	if (iobase == 0) {
+		printk(" io base address required\n");
+		return -EINVAL;
+	}
+
+	/* check if io addresses are available */
+	if (!request_region(iobase, A2150_SIZE, driver_a2150.driver_name)) {
+		printk(" I/O port conflict\n");
+		return -EIO;
+	}
+	dev->iobase = iobase;
+
+	/* grab our IRQ */
+	if (irq) {
+		// check that irq is supported
+		if (irq < 3 || irq == 8 || irq == 13 || irq > 15) {
+			printk(" invalid irq line %u\n", irq);
+			return -EINVAL;
+		}
+		if (comedi_request_irq(irq, a2150_interrupt, 0,
+				driver_a2150.driver_name, dev)) {
+			printk("unable to allocate irq %u\n", irq);
+			return -EINVAL;
+		}
+		devpriv->irq_dma_bits |= IRQ_LVL_BITS(irq);
+		dev->irq = irq;
+	}
+	// initialize dma
+	if (dma) {
+		if (dma == 4 || dma > 7) {
+			printk(" invalid dma channel %u\n", dma);
+			return -EINVAL;
+		}
+		if (request_dma(dma, driver_a2150.driver_name)) {
+			printk(" failed to allocate dma channel %u\n", dma);
+			return -EINVAL;
+		}
+		devpriv->dma = dma;
+		devpriv->dma_buffer =
+			kmalloc(A2150_DMA_BUFFER_SIZE, GFP_KERNEL | GFP_DMA);
+		if (devpriv->dma_buffer == NULL)
+			return -ENOMEM;
+
+		disable_dma(dma);
+		set_dma_mode(dma, DMA_MODE_READ);
+
+		devpriv->irq_dma_bits |= DMA_CHAN_BITS(dma);
+	}
+
+	dev->board_ptr = a2150_boards + a2150_probe(dev);
+	dev->board_name = thisboard->name;
+
+	if (alloc_subdevices(dev, 1) < 0)
+		return -ENOMEM;
+
+	/* analog input subdevice */
+	s = dev->subdevices + 0;
+	dev->read_subdev = s;
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_OTHER | SDF_CMD_READ;
+	s->n_chan = 4;
+	s->len_chanlist = 4;
+	s->maxdata = 0xffff;
+	s->range_table = &range_a2150;
+	s->do_cmd = a2150_ai_cmd;
+	s->do_cmdtest = a2150_ai_cmdtest;
+	s->insn_read = a2150_ai_rinsn;
+	s->cancel = a2150_cancel;
+
+	/* need to do this for software counting of completed conversions, to
+	 * prevent hardware count from stopping aquisition */
+	outw(HW_COUNT_DISABLE, dev->iobase + I8253_MODE_REG);
+
+	// set card's irq and dma levels
+	outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
+
+	// reset and sync adc clock circuitry
+	outw_p(DPD_BIT | APD_BIT, dev->iobase + CONFIG_REG);
+	outw_p(DPD_BIT, dev->iobase + CONFIG_REG);
+	// initialize configuration register
+	devpriv->config_bits = 0;
+	outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
+	// wait until offset calibration is done, then enable analog inputs
+	for (i = 0; i < timeout; i++) {
+		if ((DCAL_BIT & inw(dev->iobase + STATUS_REG)) == 0)
+			break;
+		comedi_udelay(1000);
+	}
+	if (i == timeout) {
+		printk(" timed out waiting for offset calibration to complete\n");
+		return -ETIME;
+	}
+	devpriv->config_bits |= ENABLE0_BIT | ENABLE1_BIT;
+	outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
+
+	return 0;
+};
+
+static int a2150_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: %s: remove\n", dev->minor, driver_a2150.driver_name);
+
+	/* only free stuff if it has been allocated by _attach */
+	if (dev->iobase) {
+		// put board in power-down mode
+		outw(APD_BIT | DPD_BIT, dev->iobase + CONFIG_REG);
+		release_region(dev->iobase, A2150_SIZE);
+	}
+
+	if (dev->irq)
+		comedi_free_irq(dev->irq, dev);
+	if (devpriv) {
+		if (devpriv->dma)
+			free_dma(devpriv->dma);
+		if (devpriv->dma_buffer)
+			kfree(devpriv->dma_buffer);
+	}
+
+	return 0;
+};
+
+static int a2150_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	// disable dma on card
+	devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
+	outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
+
+	// disable computer's dma
+	disable_dma(devpriv->dma);
+
+	// clear fifo and reset triggering circuitry
+	outw(0, dev->iobase + FIFO_RESET_REG);
+
+	return 0;
+}
+
+static int a2150_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp;
+	int startChan;
+	int i;
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW | TRIG_EXT;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_TIMER;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_NOW;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
+		err++;
+	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+	if (cmd->convert_src == TRIG_TIMER) {
+		if (cmd->convert_arg < thisboard->ai_speed) {
+			cmd->convert_arg = thisboard->ai_speed;
+			err++;
+		}
+	}
+	if (!cmd->chanlist_len) {
+		cmd->chanlist_len = 1;
+		err++;
+	}
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+	if (cmd->stop_src == TRIG_COUNT) {
+		if (!cmd->stop_arg) {
+			cmd->stop_arg = 1;
+			err++;
+		}
+	} else {		/* TRIG_NONE */
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		tmp = cmd->scan_begin_arg;
+		a2150_get_timing(dev, &cmd->scan_begin_arg, cmd->flags);
+		if (tmp != cmd->scan_begin_arg)
+			err++;
+	}
+
+	if (err)
+		return 4;
+
+	// check channel/gain list against card's limitations
+	if (cmd->chanlist) {
+		startChan = CR_CHAN(cmd->chanlist[0]);
+		for (i = 1; i < cmd->chanlist_len; i++) {
+			if (CR_CHAN(cmd->chanlist[i]) != (startChan + i)) {
+				comedi_error(dev,
+					"entries in chanlist must be consecutive channels, counting upwards\n");
+				err++;
+			}
+		}
+		if (cmd->chanlist_len == 2 && CR_CHAN(cmd->chanlist[0]) == 1) {
+			comedi_error(dev,
+				"length 2 chanlist must be channels 0,1 or channels 2,3");
+			err++;
+		}
+		if (cmd->chanlist_len == 3) {
+			comedi_error(dev,
+				"chanlist must have 1,2 or 4 channels");
+			err++;
+		}
+		if (CR_AREF(cmd->chanlist[0]) != CR_AREF(cmd->chanlist[1]) ||
+			CR_AREF(cmd->chanlist[2]) != CR_AREF(cmd->chanlist[3]))
+		{
+			comedi_error(dev,
+				"channels 0/1 and 2/3 must have the same analog reference");
+			err++;
+		}
+	}
+
+	if (err)
+		return 5;
+
+	return 0;
+}
+
+static int a2150_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+	unsigned long lock_flags;
+	unsigned int old_config_bits = devpriv->config_bits;
+	unsigned int trigger_bits;
+
+	if (!dev->irq || !devpriv->dma) {
+		comedi_error(dev,
+			" irq and dma required, cannot do hardware conversions");
+		return -1;
+	}
+	if (cmd->flags & TRIG_RT) {
+		comedi_error(dev,
+			" dma incompatible with hard real-time interrupt (TRIG_RT), aborting");
+		return -1;
+	}
+	// clear fifo and reset triggering circuitry
+	outw(0, dev->iobase + FIFO_RESET_REG);
+
+	/* setup chanlist */
+	if (a2150_set_chanlist(dev, CR_CHAN(cmd->chanlist[0]),
+			cmd->chanlist_len) < 0)
+		return -1;
+
+	// setup ac/dc coupling
+	if (CR_AREF(cmd->chanlist[0]) == AREF_OTHER)
+		devpriv->config_bits |= AC0_BIT;
+	else
+		devpriv->config_bits &= ~AC0_BIT;
+	if (CR_AREF(cmd->chanlist[2]) == AREF_OTHER)
+		devpriv->config_bits |= AC1_BIT;
+	else
+		devpriv->config_bits &= ~AC1_BIT;
+
+	// setup timing
+	a2150_get_timing(dev, &cmd->scan_begin_arg, cmd->flags);
+
+	// send timing, channel, config bits
+	outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
+
+	// initialize number of samples remaining
+	devpriv->count = cmd->stop_arg * cmd->chanlist_len;
+
+	// enable computer's dma
+	lock_flags = claim_dma_lock();
+	disable_dma(devpriv->dma);
+	/* clear flip-flop to make sure 2-byte registers for
+	 * count and address get set correctly */
+	clear_dma_ff(devpriv->dma);
+	set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer));
+	// set size of transfer to fill in 1/3 second
+#define ONE_THIRD_SECOND 333333333
+	devpriv->dma_transfer_size =
+		sizeof(devpriv->dma_buffer[0]) * cmd->chanlist_len *
+		ONE_THIRD_SECOND / cmd->scan_begin_arg;
+	if (devpriv->dma_transfer_size > A2150_DMA_BUFFER_SIZE)
+		devpriv->dma_transfer_size = A2150_DMA_BUFFER_SIZE;
+	if (devpriv->dma_transfer_size < sizeof(devpriv->dma_buffer[0]))
+		devpriv->dma_transfer_size = sizeof(devpriv->dma_buffer[0]);
+	devpriv->dma_transfer_size -=
+		devpriv->dma_transfer_size % sizeof(devpriv->dma_buffer[0]);
+	set_dma_count(devpriv->dma, devpriv->dma_transfer_size);
+	enable_dma(devpriv->dma);
+	release_dma_lock(lock_flags);
+
+	/* clear dma interrupt before enabling it, to try and get rid of that
+	 * one spurious interrupt that has been happening */
+	outw(0x00, dev->iobase + DMA_TC_CLEAR_REG);
+
+	// enable dma on card
+	devpriv->irq_dma_bits |= DMA_INTR_EN_BIT | DMA_EN_BIT;
+	outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
+
+	// may need to wait 72 sampling periods if timing was changed
+	i8254_load(dev->iobase + I8253_BASE_REG, 0, 2, 72, 0);
+
+	// setup start triggering
+	trigger_bits = 0;
+	// decide if we need to wait 72 periods for valid data
+	if (cmd->start_src == TRIG_NOW &&
+		(old_config_bits & CLOCK_MASK) !=
+		(devpriv->config_bits & CLOCK_MASK)) {
+		// set trigger source to delay trigger
+		trigger_bits |= DELAY_TRIGGER_BITS;
+	} else {
+		// otherwise no delay
+		trigger_bits |= POST_TRIGGER_BITS;
+	}
+	// enable external hardware trigger
+	if (cmd->start_src == TRIG_EXT) {
+		trigger_bits |= HW_TRIG_EN;
+	} else if (cmd->start_src == TRIG_OTHER) {
+		// XXX add support for level/slope start trigger using TRIG_OTHER
+		comedi_error(dev, "you shouldn't see this?");
+	}
+	// send trigger config bits
+	outw(trigger_bits, dev->iobase + TRIGGER_REG);
+
+	// start aquisition for soft trigger
+	if (cmd->start_src == TRIG_NOW) {
+		outw(0, dev->iobase + FIFO_START_REG);
+	}
+#ifdef A2150_DEBUG
+	ni_dump_regs(dev);
+#endif
+
+	return 0;
+}
+
+static int a2150_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int i, n;
+	static const int timeout = 100000;
+	static const int filter_delay = 36;
+
+	// clear fifo and reset triggering circuitry
+	outw(0, dev->iobase + FIFO_RESET_REG);
+
+	/* setup chanlist */
+	if (a2150_set_chanlist(dev, CR_CHAN(insn->chanspec), 1) < 0)
+		return -1;
+
+	// set dc coupling
+	devpriv->config_bits &= ~AC0_BIT;
+	devpriv->config_bits &= ~AC1_BIT;
+
+	// send timing, channel, config bits
+	outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
+
+	// disable dma on card
+	devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
+	outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
+
+	// setup start triggering
+	outw(0, dev->iobase + TRIGGER_REG);
+
+	// start aquisition for soft trigger
+	outw(0, dev->iobase + FIFO_START_REG);
+
+	/* there is a 35.6 sample delay for data to get through the antialias filter */
+	for (n = 0; n < filter_delay; n++) {
+		for (i = 0; i < timeout; i++) {
+			if (inw(dev->iobase + STATUS_REG) & FNE_BIT)
+				break;
+			comedi_udelay(1);
+		}
+		if (i == timeout) {
+			comedi_error(dev, "timeout");
+			return -ETIME;
+		}
+		inw(dev->iobase + FIFO_DATA_REG);
+	}
+
+	// read data
+	for (n = 0; n < insn->n; n++) {
+		for (i = 0; i < timeout; i++) {
+			if (inw(dev->iobase + STATUS_REG) & FNE_BIT)
+				break;
+			comedi_udelay(1);
+		}
+		if (i == timeout) {
+			comedi_error(dev, "timeout");
+			return -ETIME;
+		}
+#ifdef A2150_DEBUG
+		ni_dump_regs(dev);
+#endif
+		data[n] = inw(dev->iobase + FIFO_DATA_REG);
+#ifdef A2150_DEBUG
+		rt_printk(" data is %i\n", data[n]);
+#endif
+		data[n] ^= 0x8000;
+	}
+
+	// clear fifo and reset triggering circuitry
+	outw(0, dev->iobase + FIFO_RESET_REG);
+
+	return n;
+}
+
+/* sets bits in devpriv->clock_bits to nearest approximation of requested period,
+ * adjusts requested period to actual timing. */
+static int a2150_get_timing(struct comedi_device * dev, unsigned int *period,
+	int flags)
+{
+	int lub, glb, temp;
+	int lub_divisor_shift, lub_index, glb_divisor_shift, glb_index;
+	int i, j;
+
+	// initialize greatest lower and least upper bounds
+	lub_divisor_shift = 3;
+	lub_index = 0;
+	lub = thisboard->clock[lub_index] * (1 << lub_divisor_shift);
+	glb_divisor_shift = 0;
+	glb_index = thisboard->num_clocks - 1;
+	glb = thisboard->clock[glb_index] * (1 << glb_divisor_shift);
+
+	// make sure period is in available range
+	if (*period < glb)
+		*period = glb;
+	if (*period > lub)
+		*period = lub;
+
+	// we can multiply period by 1, 2, 4, or 8, using (1 << i)
+	for (i = 0; i < 4; i++) {
+		// there are a maximum of 4 master clocks
+		for (j = 0; j < thisboard->num_clocks; j++) {
+			// temp is the period in nanosec we are evaluating
+			temp = thisboard->clock[j] * (1 << i);
+			// if it is the best match yet
+			if (temp < lub && temp >= *period) {
+				lub_divisor_shift = i;
+				lub_index = j;
+				lub = temp;
+			}
+			if (temp > glb && temp <= *period) {
+				glb_divisor_shift = i;
+				glb_index = j;
+				glb = temp;
+			}
+		}
+	}
+	flags &= TRIG_ROUND_MASK;
+	switch (flags) {
+	case TRIG_ROUND_NEAREST:
+	default:
+		// if least upper bound is better approximation
+		if (lub - *period < *period - glb) {
+			*period = lub;
+		} else {
+			*period = glb;
+		}
+		break;
+	case TRIG_ROUND_UP:
+		*period = lub;
+		break;
+	case TRIG_ROUND_DOWN:
+		*period = glb;
+		break;
+	}
+
+	// set clock bits for config register appropriately
+	devpriv->config_bits &= ~CLOCK_MASK;
+	if (*period == lub) {
+		devpriv->config_bits |=
+			CLOCK_SELECT_BITS(lub_index) |
+			CLOCK_DIVISOR_BITS(lub_divisor_shift);
+	} else {
+		devpriv->config_bits |=
+			CLOCK_SELECT_BITS(glb_index) |
+			CLOCK_DIVISOR_BITS(glb_divisor_shift);
+	}
+
+	return 0;
+}
+
+static int a2150_set_chanlist(struct comedi_device * dev, unsigned int start_channel,
+	unsigned int num_channels)
+{
+	if (start_channel + num_channels > 4)
+		return -1;
+
+	devpriv->config_bits &= ~CHANNEL_MASK;
+
+	switch (num_channels) {
+	case 1:
+		devpriv->config_bits |= CHANNEL_BITS(0x4 | start_channel);
+		break;
+	case 2:
+		if (start_channel == 0) {
+			devpriv->config_bits |= CHANNEL_BITS(0x2);
+		} else if (start_channel == 2) {
+			devpriv->config_bits |= CHANNEL_BITS(0x3);
+		} else {
+			return -1;
+		}
+		break;
+	case 4:
+		devpriv->config_bits |= CHANNEL_BITS(0x1);
+		break;
+	default:
+		return -1;
+		break;
+	}
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/ni_at_ao.c b/drivers/staging/comedi/drivers/ni_at_ao.c
new file mode 100644
index 0000000..2cc46b6
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_at_ao.c
@@ -0,0 +1,454 @@
+/*
+    comedi/drivers/ni_at_ao.c
+    Driver for NI AT-AO-6/10 boards
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000,2002 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: ni_at_ao
+Description: National Instruments AT-AO-6/10
+Devices: [National Instruments] AT-AO-6 (at-ao-6), AT-AO-10 (at-ao-10)
+Status: should work
+Author: ds
+Updated: Sun Dec 26 12:26:28 EST 2004
+
+Configuration options:
+  [0] - I/O port base address
+  [1] - IRQ (unused)
+  [2] - DMA (unused)
+  [3] - analog output range, set by jumpers on hardware (0 for -10 to 10V bipolar, 1 for 0V to 10V unipolar)
+
+*/
+/*
+ * Register-level programming information can be found in NI
+ * document 320379.pdf.
+ */
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+/* board egisters */
+/* registers with _2_ are accessed when GRP2WR is set in CFG1 */
+
+#define ATAO_SIZE 0x20
+
+#define ATAO_2_DMATCCLR		0x00	/* W 16 */
+#define ATAO_DIN		0x00	/* R 16 */
+#define ATAO_DOUT		0x00	/* W 16 */
+
+#define ATAO_CFG2		0x02	/* W 16 */
+#define CALLD1	0x8000
+#define CALLD0	0x4000
+#define FFRTEN	0x2000
+#define DAC2S8	0x1000
+#define DAC2S6	0x0800
+#define DAC2S4	0x0400
+#define DAC2S2	0x0200
+#define DAC2S0	0x0100
+#define LDAC8		0x0080
+#define LDAC6		0x0040
+#define LDAC4		0x0020
+#define LDAC2		0x0010
+#define LDAC0		0x0008
+#define PROMEN	0x0004
+#define SCLK		0x0002
+#define SDATA		0x0001
+
+#define ATAO_2_INT1CLR		0x02	/* W 16 */
+
+#define ATAO_CFG3		0x04	/* W 16 */
+#define DMAMODE	0x0040
+#define CLKOUT	0x0020
+#define RCLKEN	0x0010
+#define DOUTEN2	0x0008
+#define DOUTEN1	0x0004
+#define EN2_5V	0x0002
+#define SCANEN	0x0001
+
+#define ATAO_2_INT2CLR		0x04	/* W 16 */
+
+#define ATAO_82C53_BASE		0x06	/* RW 8 */
+
+#define ATAO_82C53_CNTR1	0x06	/* RW 8 */
+#define ATAO_82C53_CNTR2	0x07	/* RW 8 */
+#define ATAO_82C53_CNTR3	0x08	/* RW 8 */
+#define ATAO_82C53_CNTRCMD	0x09	/* W 8 */
+#define CNTRSEL1	0x80
+#define CNTRSEL0	0x40
+#define RWSEL1	0x20
+#define RWSEL0	0x10
+#define MODESEL2	0x08
+#define MODESEL1	0x04
+#define MODESEL0	0x02
+#define BCDSEL	0x01
+  /* read-back command */
+#define COUNT		0x20
+#define STATUS	0x10
+#define CNTR3		0x08
+#define CNTR2		0x04
+#define CNTR1		0x02
+  /* status */
+#define OUT		0x80
+#define _NULL		0x40
+#define RW1		0x20
+#define RW0		0x10
+#define MODE2		0x08
+#define MODE1		0x04
+#define MODE0		0x02
+#define BCD		0x01
+
+#define ATAO_2_RTSISHFT		0x06	/* W 8 */
+#define RSI		0x01
+
+#define ATAO_2_RTSISTRB		0x07	/* W 8 */
+
+#define ATAO_CFG1		0x0a	/* W 16 */
+#define EXTINT2EN	0x8000
+#define EXTINT1EN	0x4000
+#define CNTINT2EN	0x2000
+#define CNTINT1EN	0x1000
+#define TCINTEN	0x0800
+#define CNT1SRC	0x0400
+#define CNT2SRC	0x0200
+#define FIFOEN	0x0100
+#define GRP2WR	0x0080
+#define EXTUPDEN	0x0040
+#define DMARQ		0x0020
+#define DMAEN		0x0010
+#define CH_mask	0x000f
+#define ATAO_STATUS		0x0a	/* R 16 */
+#define FH		0x0040
+#define FE		0x0020
+#define FF		0x0010
+#define INT2		0x0008
+#define INT1		0x0004
+#define TCINT		0x0002
+#define PROMOUT	0x0001
+
+#define ATAO_FIFO_WRITE		0x0c	/* W 16 */
+#define ATAO_FIFO_CLEAR		0x0c	/* R 16 */
+#define ATAO_DACn(x)		(0x0c + 2*(x))	/* W */
+
+/*
+ * Board descriptions for two imaginary boards.  Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct atao_board {
+	const char *name;
+	int n_ao_chans;
+};
+
+static const struct atao_board atao_boards[] = {
+	{
+	      name:	"ai-ao-6",
+	      n_ao_chans:6,
+		},
+	{
+	      name:	"ai-ao-10",
+	      n_ao_chans:10,
+		},
+};
+
+#define thisboard ((struct atao_board *)dev->board_ptr)
+
+struct atao_private {
+
+	unsigned short cfg1;
+	unsigned short cfg2;
+	unsigned short cfg3;
+
+	/* Used for AO readback */
+	unsigned int ao_readback[10];
+};
+
+#define devpriv ((struct atao_private *)dev->private)
+
+static int atao_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int atao_detach(struct comedi_device * dev);
+static struct comedi_driver driver_atao = {
+      driver_name:"ni_at_ao",
+      module:THIS_MODULE,
+      attach:atao_attach,
+      detach:atao_detach,
+      board_name:&atao_boards[0].name,
+      offset:sizeof(struct atao_board),
+      num_names:sizeof(atao_boards) / sizeof(struct atao_board),
+};
+
+COMEDI_INITCLEANUP(driver_atao);
+
+static void atao_reset(struct comedi_device * dev);
+
+static int atao_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int atao_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int atao_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int atao_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int atao_calib_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int atao_calib_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+static int atao_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	unsigned long iobase;
+	int ao_unipolar;
+
+	iobase = it->options[0];
+	if (iobase == 0)
+		iobase = 0x1c0;
+	ao_unipolar = it->options[3];
+
+	printk("comedi%d: ni_at_ao: 0x%04lx", dev->minor, iobase);
+
+	if (!request_region(iobase, ATAO_SIZE, "ni_at_ao")) {
+		printk(" I/O port conflict\n");
+		return -EIO;
+	}
+	dev->iobase = iobase;
+
+	//dev->board_ptr = atao_probe(dev);
+
+	dev->board_name = thisboard->name;
+
+	if (alloc_private(dev, sizeof(struct atao_private)) < 0)
+		return -ENOMEM;
+
+	if (alloc_subdevices(dev, 4) < 0)
+		return -ENOMEM;
+
+	s = dev->subdevices + 0;
+	/* analog output subdevice */
+	s->type = COMEDI_SUBD_AO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->n_chan = thisboard->n_ao_chans;
+	s->maxdata = (1 << 12) - 1;
+	if (ao_unipolar)
+		s->range_table = &range_unipolar10;
+	else
+		s->range_table = &range_bipolar10;
+	s->insn_write = &atao_ao_winsn;
+	s->insn_read = &atao_ao_rinsn;
+
+	s = dev->subdevices + 1;
+	/* digital i/o subdevice */
+	s->type = COMEDI_SUBD_DIO;
+	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+	s->n_chan = 8;
+	s->maxdata = 1;
+	s->range_table = &range_digital;
+	s->insn_bits = atao_dio_insn_bits;
+	s->insn_config = atao_dio_insn_config;
+
+	s = dev->subdevices + 2;
+	/* caldac subdevice */
+	s->type = COMEDI_SUBD_CALIB;
+	s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL;
+	s->n_chan = 21;
+	s->maxdata = 0xff;
+	s->insn_read = atao_calib_insn_read;
+	s->insn_write = atao_calib_insn_write;
+
+	s = dev->subdevices + 3;
+	/* eeprom subdevice */
+	//s->type=COMEDI_SUBD_EEPROM;
+	s->type = COMEDI_SUBD_UNUSED;
+
+	atao_reset(dev);
+
+	printk("\n");
+
+	return 0;
+}
+
+static int atao_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: atao: remove\n", dev->minor);
+
+	if (dev->iobase)
+		release_region(dev->iobase, ATAO_SIZE);
+
+	return 0;
+}
+
+static void atao_reset(struct comedi_device * dev)
+{
+	/* This is the reset sequence described in the manual */
+
+	devpriv->cfg1 = 0;
+	outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
+
+	outb(RWSEL0 | MODESEL2, dev->iobase + ATAO_82C53_CNTRCMD);
+	outb(0x03, dev->iobase + ATAO_82C53_CNTR1);
+	outb(CNTRSEL0 | RWSEL0 | MODESEL2, dev->iobase + ATAO_82C53_CNTRCMD);
+
+	devpriv->cfg2 = 0;
+	outw(devpriv->cfg2, dev->iobase + ATAO_CFG2);
+
+	devpriv->cfg3 = 0;
+	outw(devpriv->cfg3, dev->iobase + ATAO_CFG3);
+
+	inw(dev->iobase + ATAO_FIFO_CLEAR);
+
+	devpriv->cfg1 |= GRP2WR;
+	outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
+
+	outw(0, dev->iobase + ATAO_2_INT1CLR);
+	outw(0, dev->iobase + ATAO_2_INT2CLR);
+	outw(0, dev->iobase + ATAO_2_DMATCCLR);
+
+	devpriv->cfg1 &= ~GRP2WR;
+	outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
+}
+
+static int atao_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+	short bits;
+
+	for (i = 0; i < insn->n; i++) {
+		bits = data[i] - 0x800;
+		if (chan == 0) {
+			devpriv->cfg1 |= GRP2WR;
+			outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
+		}
+		outw(bits, dev->iobase + ATAO_DACn(chan));
+		if (chan == 0) {
+			devpriv->cfg1 &= ~GRP2WR;
+			outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
+		}
+		devpriv->ao_readback[chan] = data[i];
+	}
+
+	return i;
+}
+
+static int atao_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+
+	for (i = 0; i < insn->n; i++)
+		data[i] = devpriv->ao_readback[chan];
+
+	return i;
+}
+
+static int atao_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= data[0] & data[1];
+		outw(s->state, dev->iobase + ATAO_DOUT);
+	}
+
+	data[1] = inw(dev->iobase + ATAO_DIN);
+
+	return 2;
+}
+
+static int atao_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int chan = CR_CHAN(insn->chanspec);
+	unsigned int mask, bit;
+
+	/* The input or output configuration of each digital line is
+	 * configured by a special insn_config instruction.  chanspec
+	 * contains the channel to be changed, and data[0] contains the
+	 * value COMEDI_INPUT or COMEDI_OUTPUT. */
+
+	mask = (chan < 4) ? 0x0f : 0xf0;
+	bit = (chan < 4) ? DOUTEN1 : DOUTEN2;
+
+	switch (data[0]) {
+	case INSN_CONFIG_DIO_OUTPUT:
+		s->io_bits |= mask;
+		devpriv->cfg3 |= bit;
+		break;
+	case INSN_CONFIG_DIO_INPUT:
+		s->io_bits &= ~mask;
+		devpriv->cfg3 &= ~bit;
+		break;
+	case INSN_CONFIG_DIO_QUERY:
+		data[1] =
+			(s->
+			io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+		return insn->n;
+		break;
+	default:
+		return -EINVAL;
+		break;
+	}
+
+	outw(devpriv->cfg3, dev->iobase + ATAO_CFG3);
+
+	return 1;
+}
+
+/*
+ * Figure 2-1 in the manual shows 3 chips labeled DAC8800, which
+ * are 8-channel 8-bit DACs.  These are most likely the calibration
+ * DACs.  It is not explicitly stated in the manual how to access
+ * the caldacs, but we can guess.
+ */
+static int atao_calib_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	for (i = 0; i < insn->n; i++) {
+		data[i] = 0;	/* XXX */
+	}
+	return insn->n;
+}
+
+static int atao_calib_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int bitstring, bit;
+	unsigned int chan = CR_CHAN(insn->chanspec);
+
+	bitstring = ((chan & 0x7) << 8) | (data[insn->n - 1] & 0xff);
+
+	for (bit = 1 << (11 - 1); bit; bit >>= 1) {
+		outw(devpriv->cfg2 | ((bit & bitstring) ? SDATA : 0),
+			dev->iobase + ATAO_CFG2);
+		outw(devpriv->cfg2 | SCLK | ((bit & bitstring) ? SDATA : 0),
+			dev->iobase + ATAO_CFG2);
+	}
+	/* strobe the appropriate caldac */
+	outw(devpriv->cfg2 | (((chan >> 3) + 1) << 14),
+		dev->iobase + ATAO_CFG2);
+	outw(devpriv->cfg2, dev->iobase + ATAO_CFG2);
+
+	return insn->n;
+}
diff --git a/drivers/staging/comedi/drivers/ni_atmio.c b/drivers/staging/comedi/drivers/ni_atmio.c
new file mode 100644
index 0000000..fcc3853
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_atmio.c
@@ -0,0 +1,513 @@
+/*
+    comedi/drivers/ni_atmio.c
+    Hardware driver for NI AT-MIO E series cards
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 1997-2001 David A. Schleef <ds@schleef.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.
+
+    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.
+*/
+/*
+Driver: ni_atmio
+Description: National Instruments AT-MIO-E series
+Author: ds
+Devices: [National Instruments] AT-MIO-16E-1 (ni_atmio),
+  AT-MIO-16E-2, AT-MIO-16E-10, AT-MIO-16DE-10, AT-MIO-64E-3,
+  AT-MIO-16XE-50, AT-MIO-16XE-10, AT-AI-16XE-10
+Status: works
+Updated: Thu May  1 20:03:02 CDT 2003
+
+The driver has 2.6 kernel isapnp support, and
+will automatically probe for a supported board if the
+I/O base is left unspecified with comedi_config.
+However, many of
+the isapnp id numbers are unknown.  If your board is not
+recognized, please send the output of 'cat /proc/isapnp'
+(you may need to modprobe the isa-pnp module for
+/proc/isapnp to exist) so the
+id numbers for your board can be added to the driver.
+
+Otherwise, you can use the isapnptools package to configure
+your board.  Use isapnp to
+configure the I/O base and IRQ for the board, and then pass
+the same values as
+parameters in comedi_config.  A sample isapnp.conf file is included
+in the etc/ directory of Comedilib.
+
+Comedilib includes a utility to autocalibrate these boards.  The
+boards seem to boot into a state where the all calibration DACs
+are at one extreme of their range, thus the default calibration
+is terrible.  Calibration at boot is strongly encouraged.
+
+To use the extended digital I/O on some of the boards, enable the
+8255 driver when configuring the Comedi source tree.
+
+External triggering is supported for some events.  The channel index
+(scan_begin_arg, etc.) maps to PFI0 - PFI9.
+
+Some of the more esoteric triggering possibilities of these boards
+are not supported.
+*/
+/*
+	The real guts of the driver is in ni_mio_common.c, which is included
+	both here and in ni_pcimio.c
+
+	Interrupt support added by Truxton Fulton <trux@truxton.com>
+
+	References for specifications:
+
+	   340747b.pdf  Register Level Programmer Manual (obsolete)
+	   340747c.pdf  Register Level Programmer Manual (new)
+	   DAQ-STC reference manual
+
+	Other possibly relevant info:
+
+	   320517c.pdf  User manual (obsolete)
+	   320517f.pdf  User manual (new)
+	   320889a.pdf  delete
+	   320906c.pdf  maximum signal ratings
+	   321066a.pdf  about 16x
+	   321791a.pdf  discontinuation of at-mio-16e-10 rev. c
+	   321808a.pdf  about at-mio-16e-10 rev P
+	   321837a.pdf  discontinuation of at-mio-16de-10 rev d
+	   321838a.pdf  about at-mio-16de-10 rev N
+
+	ISSUES:
+
+	need to deal with external reference for DAC, and other DAC
+	properties in board properties
+
+	deal with at-mio-16de-10 revision D to N changes, etc.
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+#include <linux/isapnp.h>
+
+#include "ni_stc.h"
+#include "8255.h"
+
+#undef DEBUG
+
+#define ATMIO 1
+#undef PCIMIO
+
+/*
+ *  AT specific setup
+ */
+
+#define NI_SIZE 0x20
+
+#define MAX_N_CALDACS 32
+
+static const ni_board ni_boards[] = {
+      {device_id:44,
+	      isapnp_id:0x0000,/* XXX unknown */
+	      name:	"at-mio-16e-1",
+	      n_adchan:16,
+	      adbits:	12,
+	      ai_fifo_depth:8192,
+	      alwaysdither:0,
+	      gainlkup:ai_gain_16,
+	      ai_speed:800,
+	      n_aochan:2,
+	      aobits:	12,
+	      ao_fifo_depth:2048,
+			.ao_range_table = &range_ni_E_ao_ext,
+	      ao_unipolar:1,
+	      ao_speed:1000,
+	      has_8255:0,
+			.num_p0_dio_channels = 8,
+	      caldac:	{mb88341},
+		},
+      {device_id:25,
+	      isapnp_id:0x1900,
+	      name:	"at-mio-16e-2",
+	      n_adchan:16,
+	      adbits:	12,
+	      ai_fifo_depth:2048,
+	      alwaysdither:0,
+	      gainlkup:ai_gain_16,
+	      ai_speed:2000,
+	      n_aochan:2,
+	      aobits:	12,
+	      ao_fifo_depth:2048,
+			.ao_range_table = &range_ni_E_ao_ext,
+	      ao_unipolar:1,
+	      ao_speed:1000,
+	      has_8255:0,
+			.num_p0_dio_channels = 8,
+	      caldac:	{mb88341},
+		},
+      {device_id:36,
+	      isapnp_id:0x2400,
+	      name:	"at-mio-16e-10",
+	      n_adchan:16,
+	      adbits:	12,
+	      ai_fifo_depth:512,
+	      alwaysdither:0,
+	      gainlkup:ai_gain_16,
+	      ai_speed:10000,
+	      n_aochan:2,
+	      aobits:	12,
+	      ao_fifo_depth:0,
+			.ao_range_table = &range_ni_E_ao_ext,
+	      ao_unipolar:1,
+	      ao_speed:10000,
+			.num_p0_dio_channels = 8,
+	      caldac:	{ad8804_debug},
+	      has_8255:0,
+		},
+      {device_id:37,
+	      isapnp_id:0x2500,
+	      name:	"at-mio-16de-10",
+	      n_adchan:16,
+	      adbits:	12,
+	      ai_fifo_depth:512,
+	      alwaysdither:0,
+	      gainlkup:ai_gain_16,
+	      ai_speed:10000,
+	      n_aochan:2,
+	      aobits:	12,
+	      ao_fifo_depth:0,
+			.ao_range_table = &range_ni_E_ao_ext,
+	      ao_unipolar:1,
+	      ao_speed:10000,
+			.num_p0_dio_channels = 8,
+	      caldac:	{ad8804_debug},
+	      has_8255:1,
+		},
+      {device_id:38,
+	      isapnp_id:0x2600,
+	      name:	"at-mio-64e-3",
+	      n_adchan:64,
+	      adbits:	12,
+	      ai_fifo_depth:2048,
+	      alwaysdither:0,
+	      gainlkup:ai_gain_16,
+	      ai_speed:2000,
+	      n_aochan:2,
+	      aobits:	12,
+	      ao_fifo_depth:2048,
+			.ao_range_table = &range_ni_E_ao_ext,
+	      ao_unipolar:1,
+	      ao_speed:1000,
+	      has_8255:0,
+			.num_p0_dio_channels = 8,
+	      caldac:	{ad8804_debug},
+		},
+      {device_id:39,
+	      isapnp_id:0x2700,
+	      name:	"at-mio-16xe-50",
+	      n_adchan:16,
+	      adbits:	16,
+	      ai_fifo_depth:512,
+	      alwaysdither:1,
+	      gainlkup:ai_gain_8,
+	      ai_speed:50000,
+	      n_aochan:2,
+	      aobits:	12,
+	      ao_fifo_depth:0,
+			.ao_range_table = &range_bipolar10,
+	      ao_unipolar:0,
+	      ao_speed:50000,
+			.num_p0_dio_channels = 8,
+	      caldac:	{dac8800, dac8043},
+	      has_8255:0,
+		},
+      {device_id:50,
+	      isapnp_id:0x0000,/* XXX unknown */
+	      name:	"at-mio-16xe-10",
+	      n_adchan:16,
+	      adbits:	16,
+	      ai_fifo_depth:512,
+	      alwaysdither:1,
+	      gainlkup:ai_gain_14,
+	      ai_speed:10000,
+	      n_aochan:2,
+	      aobits:	16,
+	      ao_fifo_depth:2048,
+			.ao_range_table = &range_ni_E_ao_ext,
+	      ao_unipolar:1,
+	      ao_speed:1000,
+			.num_p0_dio_channels = 8,
+	      caldac:	{dac8800, dac8043, ad8522},
+	      has_8255:0,
+		},
+      {device_id:51,
+	      isapnp_id:0x0000,/* XXX unknown */
+	      name:	"at-ai-16xe-10",
+	      n_adchan:16,
+	      adbits:	16,
+	      ai_fifo_depth:512,
+	      alwaysdither:1,	/* unknown */
+	      gainlkup:ai_gain_14,
+	      ai_speed:10000,
+	      n_aochan:0,
+	      aobits:	0,
+	      ao_fifo_depth:0,
+	      ao_unipolar:0,
+			.num_p0_dio_channels = 8,
+	      caldac:	{dac8800, dac8043, ad8522},
+	      has_8255:0,
+		}
+};
+
+static const int ni_irqpin[] =
+	{ -1, -1, -1, 0, 1, 2, -1, 3, -1, -1, 4, 5, 6, -1, -1, 7 };
+
+#define interrupt_pin(a)	(ni_irqpin[(a)])
+
+#define IRQ_POLARITY 0
+
+#define NI_E_IRQ_FLAGS		0
+
+typedef struct {
+	struct pnp_dev *isapnp_dev;
+ NI_PRIVATE_COMMON} ni_private;
+#define devpriv ((ni_private *)dev->private)
+
+/* How we access registers */
+
+#define ni_writel(a,b)		(outl((a),(b)+dev->iobase))
+#define ni_readl(a)		(inl((a)+dev->iobase))
+#define ni_writew(a,b)		(outw((a),(b)+dev->iobase))
+#define ni_readw(a)		(inw((a)+dev->iobase))
+#define ni_writeb(a,b)		(outb((a),(b)+dev->iobase))
+#define ni_readb(a)		(inb((a)+dev->iobase))
+
+/* How we access windowed registers */
+
+/* We automatically take advantage of STC registers that can be
+ * read/written directly in the I/O space of the board.  The
+ * AT-MIO devices map the low 8 STC registers to iobase+addr*2. */
+
+static void ni_atmio_win_out(struct comedi_device * dev, uint16_t data, int addr)
+{
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+	if ((addr) < 8) {
+		ni_writew(data, addr * 2);
+	} else {
+		ni_writew(addr, Window_Address);
+		ni_writew(data, Window_Data);
+	}
+	comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+}
+
+static uint16_t ni_atmio_win_in(struct comedi_device * dev, int addr)
+{
+	unsigned long flags;
+	uint16_t ret;
+
+	comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+	if (addr < 8) {
+		ret = ni_readw(addr * 2);
+	} else {
+		ni_writew(addr, Window_Address);
+		ret = ni_readw(Window_Data);
+	}
+	comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+
+	return ret;
+}
+
+static struct pnp_device_id device_ids[] = {
+	{.id = "NIC1900",.driver_data = 0},
+	{.id = "NIC2400",.driver_data = 0},
+	{.id = "NIC2500",.driver_data = 0},
+	{.id = "NIC2600",.driver_data = 0},
+	{.id = "NIC2700",.driver_data = 0},
+	{.id = ""}
+};
+
+MODULE_DEVICE_TABLE(pnp, device_ids);
+
+static int ni_atmio_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int ni_atmio_detach(struct comedi_device * dev);
+static struct comedi_driver driver_atmio = {
+      driver_name:"ni_atmio",
+      module:THIS_MODULE,
+      attach:ni_atmio_attach,
+      detach:ni_atmio_detach,
+};
+
+COMEDI_INITCLEANUP(driver_atmio);
+
+#include "ni_mio_common.c"
+
+static int ni_getboardtype(struct comedi_device * dev);
+
+/* clean up allocated resources */
+static int ni_atmio_detach(struct comedi_device * dev)
+{
+	mio_common_detach(dev);
+
+	if (dev->iobase)
+		release_region(dev->iobase, NI_SIZE);
+	if (dev->irq) {
+		comedi_free_irq(dev->irq, dev);
+	}
+	if (devpriv->isapnp_dev)
+		pnp_device_detach(devpriv->isapnp_dev);
+
+	return 0;
+}
+
+static int ni_isapnp_find_board(struct pnp_dev **dev)
+{
+	struct pnp_dev *isapnp_dev = NULL;
+	int i;
+
+	for (i = 0; i < n_ni_boards; i++) {
+		isapnp_dev = pnp_find_dev(NULL,
+			ISAPNP_VENDOR('N', 'I', 'C'),
+			ISAPNP_FUNCTION(ni_boards[i].isapnp_id), NULL);
+
+		if (isapnp_dev == NULL || isapnp_dev->card == NULL)
+			continue;
+
+		if (pnp_device_attach(isapnp_dev) < 0) {
+			printk("ni_atmio: %s found but already active, skipping.\n", ni_boards[i].name);
+			continue;
+		}
+		if (pnp_activate_dev(isapnp_dev) < 0) {
+			pnp_device_detach(isapnp_dev);
+			return -EAGAIN;
+		}
+		if (!pnp_port_valid(isapnp_dev, 0)
+			|| !pnp_irq_valid(isapnp_dev, 0)) {
+			pnp_device_detach(isapnp_dev);
+			printk("ni_atmio: pnp invalid port or irq, aborting\n");
+			return -ENOMEM;
+		}
+		break;
+	}
+	if (i == n_ni_boards)
+		return -ENODEV;
+	*dev = isapnp_dev;
+	return 0;
+}
+
+static int ni_atmio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct pnp_dev *isapnp_dev;
+	int ret;
+	unsigned long iobase;
+	int board;
+	unsigned int irq;
+
+	/* allocate private area */
+	if ((ret = ni_alloc_private(dev)) < 0)
+		return ret;
+	devpriv->stc_writew = &ni_atmio_win_out;
+	devpriv->stc_readw = &ni_atmio_win_in;
+	devpriv->stc_writel = &win_out2;
+	devpriv->stc_readl = &win_in2;
+
+	iobase = it->options[0];
+	irq = it->options[1];
+	isapnp_dev = NULL;
+	if (iobase == 0) {
+		ret = ni_isapnp_find_board(&isapnp_dev);
+		if (ret < 0)
+			return ret;
+
+		iobase = pnp_port_start(isapnp_dev, 0);
+		irq = pnp_irq(isapnp_dev, 0);
+		devpriv->isapnp_dev = isapnp_dev;
+	}
+
+	/* reserve our I/O region */
+
+	printk("comedi%d: ni_atmio: 0x%04lx", dev->minor, iobase);
+	if (!request_region(iobase, NI_SIZE, "ni_atmio")) {
+		printk(" I/O port conflict\n");
+		return -EIO;
+	}
+
+	dev->iobase = iobase;
+
+#ifdef DEBUG
+	/* board existence sanity check */
+	{
+		int i;
+
+		printk(" board fingerprint:");
+		for (i = 0; i < 16; i += 2) {
+			printk(" %04x %02x", inw(dev->iobase + i),
+				inb(dev->iobase + i + 1));
+		}
+	}
+#endif
+
+	/* get board type */
+
+	board = ni_getboardtype(dev);
+	if (board < 0)
+		return -EIO;
+
+	dev->board_ptr = ni_boards + board;
+
+	printk(" %s", boardtype.name);
+	dev->board_name = boardtype.name;
+
+	/* irq stuff */
+
+	if (irq != 0) {
+		if (irq > 15 || ni_irqpin[irq] == -1) {
+			printk(" invalid irq %u\n", irq);
+			return -EINVAL;
+		}
+		printk(" ( irq = %u )", irq);
+		if ((ret = comedi_request_irq(irq, ni_E_interrupt,
+					NI_E_IRQ_FLAGS, "ni_atmio", dev)) < 0) {
+			printk(" irq not available\n");
+			return -EINVAL;
+		}
+		dev->irq = irq;
+	}
+
+	/* generic E series stuff in ni_mio_common.c */
+
+	if ((ret = ni_E_init(dev, it)) < 0) {
+		return ret;
+	}
+
+	return 0;
+}
+
+static int ni_getboardtype(struct comedi_device * dev)
+{
+	int device_id = ni_read_eeprom(dev, 511);
+	int i;
+
+	for (i = 0; i < n_ni_boards; i++) {
+		if (ni_boards[i].device_id == device_id) {
+			return i;
+		}
+	}
+	if (device_id == 255) {
+		printk(" can't find board\n");
+	} else if (device_id == 0) {
+		printk(" EEPROM read error (?) or device not found\n");
+	} else {
+		printk(" unknown device ID %d -- contact author\n", device_id);
+	}
+	return -1;
+}
diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c
new file mode 100644
index 0000000..35fcd17
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_atmio16d.c
@@ -0,0 +1,860 @@
+/*
+   comedi/drivers/ni_atmio16d.c
+   Hardware driver for National Instruments AT-MIO16D board
+   Copyright (C) 2000 Chris R. Baugher <baugher@enteract.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, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+/*
+Driver: ni_atmio16d
+Description: National Instruments AT-MIO-16D
+Author: Chris R. Baugher <baugher@enteract.com>
+Status: unknown
+Devices: [National Instruments] AT-MIO-16 (atmio16), AT-MIO-16D (atmio16d)
+*/
+/*
+ * I must give credit here to Michal Dobes <dobes@tesnet.cz> who
+ * wrote the driver for Advantec's pcl812 boards. I used the interrupt
+ * handling code from his driver as an example for this one.
+ *
+ * Chris Baugher
+ * 5/1/2000
+ *
+ */
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#include "8255.h"
+
+/* Configuration and Status Registers */
+#define COM_REG_1	0x00	/* wo 16 */
+#define STAT_REG	0x00	/* ro 16 */
+#define COM_REG_2	0x02	/* wo 16 */
+/* Event Strobe Registers */
+#define START_CONVERT_REG	0x08	/* wo 16 */
+#define START_DAQ_REG		0x0A	/* wo 16 */
+#define AD_CLEAR_REG		0x0C	/* wo 16 */
+#define EXT_STROBE_REG		0x0E	/* wo 16 */
+/* Analog Output Registers */
+#define DAC0_REG		0x10	/* wo 16 */
+#define DAC1_REG		0x12	/* wo 16 */
+#define INT2CLR_REG		0x14	/* wo 16 */
+/* Analog Input Registers */
+#define MUX_CNTR_REG		0x04	/* wo 16 */
+#define MUX_GAIN_REG		0x06	/* wo 16 */
+#define AD_FIFO_REG		0x16	/* ro 16 */
+#define DMA_TC_INT_CLR_REG	0x16	/* wo 16 */
+/* AM9513A Counter/Timer Registers */
+#define AM9513A_DATA_REG	0x18	/* rw 16 */
+#define AM9513A_COM_REG		0x1A	/* wo 16 */
+#define AM9513A_STAT_REG	0x1A	/* ro 16 */
+/* MIO-16 Digital I/O Registers */
+#define MIO_16_DIG_IN_REG	0x1C	/* ro 16 */
+#define MIO_16_DIG_OUT_REG	0x1C	/* wo 16 */
+/* RTSI Switch Registers */
+#define RTSI_SW_SHIFT_REG	0x1E	/* wo 8 */
+#define RTSI_SW_STROBE_REG	0x1F	/* wo 8 */
+/* DIO-24 Registers */
+#define DIO_24_PORTA_REG	0x00	/* rw 8 */
+#define DIO_24_PORTB_REG	0x01	/* rw 8 */
+#define DIO_24_PORTC_REG	0x02	/* rw 8 */
+#define DIO_24_CNFG_REG		0x03	/* wo 8 */
+
+/* Command Register bits */
+#define COMREG1_2SCADC		0x0001
+#define COMREG1_1632CNT		0x0002
+#define COMREG1_SCANEN		0x0008
+#define COMREG1_DAQEN		0x0010
+#define COMREG1_DMAEN		0x0020
+#define COMREG1_CONVINTEN	0x0080
+#define COMREG2_SCN2		0x0010
+#define COMREG2_INTEN		0x0080
+#define COMREG2_DOUTEN0		0x0100
+#define COMREG2_DOUTEN1		0x0200
+/* Status Register bits */
+#define STAT_AD_OVERRUN		0x0100
+#define STAT_AD_OVERFLOW	0x0200
+#define STAT_AD_DAQPROG		0x0800
+#define STAT_AD_CONVAVAIL	0x2000
+#define STAT_AD_DAQSTOPINT	0x4000
+/* AM9513A Counter/Timer defines */
+#define CLOCK_1_MHZ		0x8B25
+#define CLOCK_100_KHZ	0x8C25
+#define CLOCK_10_KHZ	0x8D25
+#define CLOCK_1_KHZ		0x8E25
+#define CLOCK_100_HZ	0x8F25
+/* Other miscellaneous defines */
+#define ATMIO16D_SIZE	32	/* bus address range */
+#define devpriv ((struct atmio16d_private *)dev->private)
+#define ATMIO16D_TIMEOUT 10
+
+struct atmio16_board_t {
+
+	const char *name;
+	int has_8255;
+};
+
+static const struct atmio16_board_t atmio16_boards[] = {
+	{
+	      name:	"atmio16",
+	      has_8255:0,
+		},
+	{
+	      name:	"atmio16d",
+	      has_8255:1,
+		},
+};
+
+#define n_atmio16_boards sizeof(atmio16_boards)/sizeof(atmio16_boards[0])
+
+#define boardtype ((const struct atmio16_board_t *)dev->board_ptr)
+
+/* function prototypes */
+static int atmio16d_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int atmio16d_detach(struct comedi_device * dev);
+static irqreturn_t atmio16d_interrupt(int irq, void *d PT_REGS_ARG);
+static int atmio16d_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd);
+static int atmio16d_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int atmio16d_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void reset_counters(struct comedi_device * dev);
+static void reset_atmio16d(struct comedi_device * dev);
+
+/* main driver struct */
+static struct comedi_driver driver_atmio16d = {
+      driver_name:"atmio16",
+      module:THIS_MODULE,
+      attach:atmio16d_attach,
+      detach:atmio16d_detach,
+      board_name:&atmio16_boards[0].name,
+      num_names:n_atmio16_boards,
+      offset:sizeof(struct atmio16_board_t),
+};
+
+COMEDI_INITCLEANUP(driver_atmio16d);
+
+/* range structs */
+static const struct comedi_lrange range_atmio16d_ai_10_bipolar = { 4, {
+			BIP_RANGE(10),
+			BIP_RANGE(1),
+			BIP_RANGE(0.1),
+			BIP_RANGE(0.02)
+	}
+};
+
+static const struct comedi_lrange range_atmio16d_ai_5_bipolar = { 4, {
+			BIP_RANGE(5),
+			BIP_RANGE(0.5),
+			BIP_RANGE(0.05),
+			BIP_RANGE(0.01)
+	}
+};
+
+static const struct comedi_lrange range_atmio16d_ai_unipolar = { 4, {
+			UNI_RANGE(10),
+			UNI_RANGE(1),
+			UNI_RANGE(0.1),
+			UNI_RANGE(0.02)
+	}
+};
+
+/* private data struct */
+struct atmio16d_private {
+	enum { adc_diff, adc_singleended } adc_mux;
+	enum { adc_bipolar10, adc_bipolar5, adc_unipolar10 } adc_range;
+	enum { adc_2comp, adc_straight } adc_coding;
+	enum { dac_bipolar, dac_unipolar } dac0_range, dac1_range;
+	enum { dac_internal, dac_external } dac0_reference, dac1_reference;
+	enum { dac_2comp, dac_straight } dac0_coding, dac1_coding;
+	const struct comedi_lrange *ao_range_type_list[2];
+	unsigned int ao_readback[2];
+	unsigned int com_reg_1_state;	/* current state of command register 1 */
+	unsigned int com_reg_2_state;	/* current state of command register 2 */
+};
+
+static void reset_counters(struct comedi_device * dev)
+{
+	/* Counter 2 */
+	outw(0xFFC2, dev->iobase + AM9513A_COM_REG);
+	outw(0xFF02, dev->iobase + AM9513A_COM_REG);
+	outw(0x4, dev->iobase + AM9513A_DATA_REG);
+	outw(0xFF0A, dev->iobase + AM9513A_COM_REG);
+	outw(0x3, dev->iobase + AM9513A_DATA_REG);
+	outw(0xFF42, dev->iobase + AM9513A_COM_REG);
+	outw(0xFF42, dev->iobase + AM9513A_COM_REG);
+	/* Counter 3 */
+	outw(0xFFC4, dev->iobase + AM9513A_COM_REG);
+	outw(0xFF03, dev->iobase + AM9513A_COM_REG);
+	outw(0x4, dev->iobase + AM9513A_DATA_REG);
+	outw(0xFF0B, dev->iobase + AM9513A_COM_REG);
+	outw(0x3, dev->iobase + AM9513A_DATA_REG);
+	outw(0xFF44, dev->iobase + AM9513A_COM_REG);
+	outw(0xFF44, dev->iobase + AM9513A_COM_REG);
+	/* Counter 4 */
+	outw(0xFFC8, dev->iobase + AM9513A_COM_REG);
+	outw(0xFF04, dev->iobase + AM9513A_COM_REG);
+	outw(0x4, dev->iobase + AM9513A_DATA_REG);
+	outw(0xFF0C, dev->iobase + AM9513A_COM_REG);
+	outw(0x3, dev->iobase + AM9513A_DATA_REG);
+	outw(0xFF48, dev->iobase + AM9513A_COM_REG);
+	outw(0xFF48, dev->iobase + AM9513A_COM_REG);
+	/* Counter 5 */
+	outw(0xFFD0, dev->iobase + AM9513A_COM_REG);
+	outw(0xFF05, dev->iobase + AM9513A_COM_REG);
+	outw(0x4, dev->iobase + AM9513A_DATA_REG);
+	outw(0xFF0D, dev->iobase + AM9513A_COM_REG);
+	outw(0x3, dev->iobase + AM9513A_DATA_REG);
+	outw(0xFF50, dev->iobase + AM9513A_COM_REG);
+	outw(0xFF50, dev->iobase + AM9513A_COM_REG);
+
+	outw(0, dev->iobase + AD_CLEAR_REG);
+}
+
+static void reset_atmio16d(struct comedi_device * dev)
+{
+	int i;
+
+	/* now we need to initialize the board */
+	outw(0, dev->iobase + COM_REG_1);
+	outw(0, dev->iobase + COM_REG_2);
+	outw(0, dev->iobase + MUX_GAIN_REG);
+	/* init AM9513A timer */
+	outw(0xFFFF, dev->iobase + AM9513A_COM_REG);
+	outw(0xFFEF, dev->iobase + AM9513A_COM_REG);
+	outw(0xFF17, dev->iobase + AM9513A_COM_REG);
+	outw(0xF000, dev->iobase + AM9513A_DATA_REG);
+	for (i = 1; i <= 5; ++i) {
+		outw(0xFF00 + i, dev->iobase + AM9513A_COM_REG);
+		outw(0x0004, dev->iobase + AM9513A_DATA_REG);
+		outw(0xFF08 + i, dev->iobase + AM9513A_COM_REG);
+		outw(0x3, dev->iobase + AM9513A_DATA_REG);
+	}
+	outw(0xFF5F, dev->iobase + AM9513A_COM_REG);
+	/* timer init done */
+	outw(0, dev->iobase + AD_CLEAR_REG);
+	outw(0, dev->iobase + INT2CLR_REG);
+	/* select straight binary mode for Analog Input */
+	devpriv->com_reg_1_state |= 1;
+	outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
+	devpriv->adc_coding = adc_straight;
+	/* zero the analog outputs */
+	outw(2048, dev->iobase + DAC0_REG);
+	outw(2048, dev->iobase + DAC1_REG);
+}
+
+static irqreturn_t atmio16d_interrupt(int irq, void *d PT_REGS_ARG)
+{
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s = dev->subdevices + 0;
+
+//      printk("atmio16d_interrupt!\n");
+
+	comedi_buf_put(s->async, inw(dev->iobase + AD_FIFO_REG));
+
+	comedi_event(dev, s);
+	return IRQ_HANDLED;
+}
+
+static int atmio16d_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0, tmp;
+#ifdef DEBUG1
+	printk("atmio16d_ai_cmdtest\n");
+#endif
+	/* make sure triggers are valid */
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_TIMER;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+	/* note that mutual compatiblity is not an issue here */
+	if (cmd->scan_begin_src != TRIG_FOLLOW &&
+		cmd->scan_begin_src != TRIG_EXT &&
+		cmd->scan_begin_src != TRIG_TIMER)
+		err++;
+	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+	if (cmd->scan_begin_src == TRIG_FOLLOW) {
+		/* internal trigger */
+		if (cmd->scan_begin_arg != 0) {
+			cmd->scan_begin_arg = 0;
+			err++;
+		}
+	} else {
+#if 0
+		/* external trigger */
+		/* should be level/edge, hi/lo specification here */
+		if (cmd->scan_begin_arg != 0) {
+			cmd->scan_begin_arg = 0;
+			err++;
+		}
+#endif
+	}
+
+	if (cmd->convert_arg < 10000) {
+		cmd->convert_arg = 10000;
+		err++;
+	}
+#if 0
+	if (cmd->convert_arg > SLOWEST_TIMER) {
+		cmd->convert_arg = SLOWEST_TIMER;
+		err++;
+	}
+#endif
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+	if (cmd->stop_src == TRIG_COUNT) {
+		/* any count is allowed */
+	} else {
+		/* TRIG_NONE */
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (err)
+		return 3;
+
+	return 0;
+}
+
+static int atmio16d_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int timer, base_clock;
+	unsigned int sample_count, tmp, chan, gain;
+	int i;
+#ifdef DEBUG1
+	printk("atmio16d_ai_cmd\n");
+#endif
+	/* This is slowly becoming a working command interface. *
+	 * It is still uber-experimental */
+
+	reset_counters(dev);
+	s->async->cur_chan = 0;
+
+	/* check if scanning multiple channels */
+	if (cmd->chanlist_len < 2) {
+		devpriv->com_reg_1_state &= ~COMREG1_SCANEN;
+		outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
+	} else {
+		devpriv->com_reg_1_state |= COMREG1_SCANEN;
+		devpriv->com_reg_2_state |= COMREG2_SCN2;
+		outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
+		outw(devpriv->com_reg_2_state, dev->iobase + COM_REG_2);
+	}
+
+	/* Setup the Mux-Gain Counter */
+	for (i = 0; i < cmd->chanlist_len; ++i) {
+		chan = CR_CHAN(cmd->chanlist[i]);
+		gain = CR_RANGE(cmd->chanlist[i]);
+		outw(i, dev->iobase + MUX_CNTR_REG);
+		tmp = chan | (gain << 6);
+		if (i == cmd->scan_end_arg - 1)
+			tmp |= 0x0010;	/* set LASTONE bit */
+		outw(tmp, dev->iobase + MUX_GAIN_REG);
+	}
+
+	/* Now program the sample interval timer */
+	/* Figure out which clock to use then get an
+	 * appropriate timer value */
+	if (cmd->convert_arg < 65536000) {
+		base_clock = CLOCK_1_MHZ;
+		timer = cmd->convert_arg / 1000;
+	} else if (cmd->convert_arg < 655360000) {
+		base_clock = CLOCK_100_KHZ;
+		timer = cmd->convert_arg / 10000;
+	} else if (cmd->convert_arg <= 0xffffffff /* 6553600000 */ ) {
+		base_clock = CLOCK_10_KHZ;
+		timer = cmd->convert_arg / 100000;
+	} else if (cmd->convert_arg <= 0xffffffff /* 65536000000 */ ) {
+		base_clock = CLOCK_1_KHZ;
+		timer = cmd->convert_arg / 1000000;
+	}
+	outw(0xFF03, dev->iobase + AM9513A_COM_REG);
+	outw(base_clock, dev->iobase + AM9513A_DATA_REG);
+	outw(0xFF0B, dev->iobase + AM9513A_COM_REG);
+	outw(0x2, dev->iobase + AM9513A_DATA_REG);
+	outw(0xFF44, dev->iobase + AM9513A_COM_REG);
+	outw(0xFFF3, dev->iobase + AM9513A_COM_REG);
+	outw(timer, dev->iobase + AM9513A_DATA_REG);
+	outw(0xFF24, dev->iobase + AM9513A_COM_REG);
+
+	/* Now figure out how many samples to get */
+	/* and program the sample counter */
+	sample_count = cmd->stop_arg * cmd->scan_end_arg;
+	outw(0xFF04, dev->iobase + AM9513A_COM_REG);
+	outw(0x1025, dev->iobase + AM9513A_DATA_REG);
+	outw(0xFF0C, dev->iobase + AM9513A_COM_REG);
+	if (sample_count < 65536) {
+		/* use only Counter 4 */
+		outw(sample_count, dev->iobase + AM9513A_DATA_REG);
+		outw(0xFF48, dev->iobase + AM9513A_COM_REG);
+		outw(0xFFF4, dev->iobase + AM9513A_COM_REG);
+		outw(0xFF28, dev->iobase + AM9513A_COM_REG);
+		devpriv->com_reg_1_state &= ~COMREG1_1632CNT;
+		outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
+	} else {
+		/* Counter 4 and 5 are needed */
+		if ((tmp = sample_count & 0xFFFF)) {
+			outw(tmp - 1, dev->iobase + AM9513A_DATA_REG);
+		} else {
+			outw(0xFFFF, dev->iobase + AM9513A_DATA_REG);
+		}
+		outw(0xFF48, dev->iobase + AM9513A_COM_REG);
+		outw(0, dev->iobase + AM9513A_DATA_REG);
+		outw(0xFF28, dev->iobase + AM9513A_COM_REG);
+		outw(0xFF05, dev->iobase + AM9513A_COM_REG);
+		outw(0x25, dev->iobase + AM9513A_DATA_REG);
+		outw(0xFF0D, dev->iobase + AM9513A_COM_REG);
+		tmp = sample_count & 0xFFFF;
+		if ((tmp == 0) || (tmp == 1)) {
+			outw((sample_count >> 16) & 0xFFFF,
+				dev->iobase + AM9513A_DATA_REG);
+		} else {
+			outw(((sample_count >> 16) & 0xFFFF) + 1,
+				dev->iobase + AM9513A_DATA_REG);
+		}
+		outw(0xFF70, dev->iobase + AM9513A_COM_REG);
+		devpriv->com_reg_1_state |= COMREG1_1632CNT;
+		outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
+	}
+
+	/* Program the scan interval timer ONLY IF SCANNING IS ENABLED */
+	/* Figure out which clock to use then get an
+	 * appropriate timer value */
+	if (cmd->chanlist_len > 1) {
+		if (cmd->scan_begin_arg < 65536000) {
+			base_clock = CLOCK_1_MHZ;
+			timer = cmd->scan_begin_arg / 1000;
+		} else if (cmd->scan_begin_arg < 655360000) {
+			base_clock = CLOCK_100_KHZ;
+			timer = cmd->scan_begin_arg / 10000;
+		} else if (cmd->scan_begin_arg < 0xffffffff /* 6553600000 */ ) {
+			base_clock = CLOCK_10_KHZ;
+			timer = cmd->scan_begin_arg / 100000;
+		} else if (cmd->scan_begin_arg < 0xffffffff /* 65536000000 */ ) {
+			base_clock = CLOCK_1_KHZ;
+			timer = cmd->scan_begin_arg / 1000000;
+		}
+		outw(0xFF02, dev->iobase + AM9513A_COM_REG);
+		outw(base_clock, dev->iobase + AM9513A_DATA_REG);
+		outw(0xFF0A, dev->iobase + AM9513A_COM_REG);
+		outw(0x2, dev->iobase + AM9513A_DATA_REG);
+		outw(0xFF42, dev->iobase + AM9513A_COM_REG);
+		outw(0xFFF2, dev->iobase + AM9513A_COM_REG);
+		outw(timer, dev->iobase + AM9513A_DATA_REG);
+		outw(0xFF22, dev->iobase + AM9513A_COM_REG);
+	}
+
+	/* Clear the A/D FIFO and reset the MUX counter */
+	outw(0, dev->iobase + AD_CLEAR_REG);
+	outw(0, dev->iobase + MUX_CNTR_REG);
+	outw(0, dev->iobase + INT2CLR_REG);
+	/* enable this acquisition operation */
+	devpriv->com_reg_1_state |= COMREG1_DAQEN;
+	outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
+	/* enable interrupts for conversion completion */
+	devpriv->com_reg_1_state |= COMREG1_CONVINTEN;
+	devpriv->com_reg_2_state |= COMREG2_INTEN;
+	outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
+	outw(devpriv->com_reg_2_state, dev->iobase + COM_REG_2);
+	/* apply a trigger. this starts the counters! */
+	outw(0, dev->iobase + START_DAQ_REG);
+
+	return 0;
+}
+
+/* This will cancel a running acquisition operation */
+static int atmio16d_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	reset_atmio16d(dev);
+
+	return 0;
+}
+
+/* Mode 0 is used to get a single conversion on demand */
+static int atmio16d_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i, t;
+	int chan;
+	int gain;
+	int status;
+
+#ifdef DEBUG1
+	printk("atmio16d_ai_insn_read\n");
+#endif
+	chan = CR_CHAN(insn->chanspec);
+	gain = CR_RANGE(insn->chanspec);
+
+	/* reset the Analog input circuitry */
+	//outw( 0, dev->iobase+AD_CLEAR_REG );
+	/* reset the Analog Input MUX Counter to 0 */
+	//outw( 0, dev->iobase+MUX_CNTR_REG );
+
+	/* set the Input MUX gain */
+	outw(chan | (gain << 6), dev->iobase + MUX_GAIN_REG);
+
+	for (i = 0; i < insn->n; i++) {
+		/* start the conversion */
+		outw(0, dev->iobase + START_CONVERT_REG);
+		/* wait for it to finish */
+		for (t = 0; t < ATMIO16D_TIMEOUT; t++) {
+			/* check conversion status */
+			status = inw(dev->iobase + STAT_REG);
+#ifdef DEBUG1
+			printk("status=%x\n", status);
+#endif
+			if (status & STAT_AD_CONVAVAIL) {
+				/* read the data now */
+				data[i] = inw(dev->iobase + AD_FIFO_REG);
+				/* change to two's complement if need be */
+				if (devpriv->adc_coding == adc_2comp) {
+					data[i] ^= 0x800;
+				}
+				break;
+			}
+			if (status & STAT_AD_OVERFLOW) {
+				printk("atmio16d: a/d FIFO overflow\n");
+				outw(0, dev->iobase + AD_CLEAR_REG);
+
+				return -ETIME;
+			}
+		}
+		/* end waiting, now check if it timed out */
+		if (t == ATMIO16D_TIMEOUT) {
+			rt_printk("atmio16d: timeout\n");
+
+			return -ETIME;
+		}
+	}
+
+	return i;
+}
+
+static int atmio16d_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+#ifdef DEBUG1
+	printk("atmio16d_ao_insn_read\n");
+#endif
+
+	for (i = 0; i < insn->n; i++) {
+		data[i] = devpriv->ao_readback[CR_CHAN(insn->chanspec)];
+	}
+
+	return i;
+}
+
+static int atmio16d_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan;
+	int d;
+#ifdef DEBUG1
+	printk("atmio16d_ao_insn_write\n");
+#endif
+
+	chan = CR_CHAN(insn->chanspec);
+
+	for (i = 0; i < insn->n; i++) {
+		d = data[i];
+		switch (chan) {
+		case 0:
+			if (devpriv->dac0_coding == dac_2comp) {
+				d ^= 0x800;
+			}
+			outw(d, dev->iobase + DAC0_REG);
+			break;
+		case 1:
+			if (devpriv->dac1_coding == dac_2comp) {
+				d ^= 0x800;
+			}
+			outw(d, dev->iobase + DAC1_REG);
+			break;
+		default:
+			return -EINVAL;
+		}
+		devpriv->ao_readback[chan] = data[i];
+	}
+	return i;
+}
+
+static int atmio16d_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= (data[0] | data[1]);
+		outw(s->state, dev->iobase + MIO_16_DIG_OUT_REG);
+	}
+	data[1] = inw(dev->iobase + MIO_16_DIG_IN_REG);
+
+	return 2;
+}
+
+static int atmio16d_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int mask;
+
+	for (i = 0; i < insn->n; i++) {
+		mask = (CR_CHAN(insn->chanspec) < 4) ? 0x0f : 0xf0;
+		s->io_bits &= ~mask;
+		if (data[i])
+			s->io_bits |= mask;
+	}
+	devpriv->com_reg_2_state &= ~(COMREG2_DOUTEN0 | COMREG2_DOUTEN1);
+	if (s->io_bits & 0x0f)
+		devpriv->com_reg_2_state |= COMREG2_DOUTEN0;
+	if (s->io_bits & 0xf0)
+		devpriv->com_reg_2_state |= COMREG2_DOUTEN1;
+	outw(devpriv->com_reg_2_state, dev->iobase + COM_REG_2);
+
+	return i;
+}
+
+/*
+   options[0] - I/O port
+   options[1] - MIO irq
+                0 == no irq
+                N == irq N {3,4,5,6,7,9,10,11,12,14,15}
+   options[2] - DIO irq
+                0 == no irq
+                N == irq N {3,4,5,6,7,9}
+   options[3] - DMA1 channel
+                0 == no DMA
+                N == DMA N {5,6,7}
+   options[4] - DMA2 channel
+                0 == no DMA
+                N == DMA N {5,6,7}
+
+   options[5] - a/d mux
+   	0=differential, 1=single
+   options[6] - a/d range
+   	0=bipolar10, 1=bipolar5, 2=unipolar10
+
+   options[7] - dac0 range
+   	0=bipolar, 1=unipolar
+   options[8] - dac0 reference
+    0=internal, 1=external
+   options[9] - dac0 coding
+   	0=2's comp, 1=straight binary
+
+   options[10] - dac1 range
+   options[11] - dac1 reference
+   options[12] - dac1 coding
+ */
+
+static int atmio16d_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	unsigned int irq;
+	unsigned long iobase;
+	int ret;
+
+	struct comedi_subdevice *s;
+
+	/* make sure the address range is free and allocate it */
+	iobase = it->options[0];
+	printk("comedi%d: atmio16d: 0x%04lx ", dev->minor, iobase);
+	if (!request_region(iobase, ATMIO16D_SIZE, "ni_atmio16d")) {
+		printk("I/O port conflict\n");
+		return -EIO;
+	}
+	dev->iobase = iobase;
+
+	/* board name */
+	dev->board_name = boardtype->name;
+
+	if ((ret = alloc_subdevices(dev, 4)) < 0)
+		return ret;
+	if ((ret = alloc_private(dev, sizeof(struct atmio16d_private))) < 0)
+		return ret;
+
+	/* reset the atmio16d hardware */
+	reset_atmio16d(dev);
+
+	/* check if our interrupt is available and get it */
+	irq = it->options[1];
+	if (irq) {
+		if ((ret = comedi_request_irq(irq, atmio16d_interrupt,
+					0, "atmio16d", dev)) < 0) {
+			printk("failed to allocate irq %u\n", irq);
+			return ret;
+		}
+		dev->irq = irq;
+		printk("( irq = %u )\n", irq);
+	} else {
+		printk("( no irq )");
+	}
+
+	/* set device options */
+	devpriv->adc_mux = it->options[5];
+	devpriv->adc_range = it->options[6];
+
+	devpriv->dac0_range = it->options[7];
+	devpriv->dac0_reference = it->options[8];
+	devpriv->dac0_coding = it->options[9];
+	devpriv->dac1_range = it->options[10];
+	devpriv->dac1_reference = it->options[11];
+	devpriv->dac1_coding = it->options[12];
+
+	/* setup sub-devices */
+	s = dev->subdevices + 0;
+	dev->read_subdev = s;
+	/* ai subdevice */
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
+	s->n_chan = (devpriv->adc_mux ? 16 : 8);
+	s->len_chanlist = 16;
+	s->insn_read = atmio16d_ai_insn_read;
+	s->do_cmdtest = atmio16d_ai_cmdtest;
+	s->do_cmd = atmio16d_ai_cmd;
+	s->cancel = atmio16d_ai_cancel;
+	s->maxdata = 0xfff;	/* 4095 decimal */
+	switch (devpriv->adc_range) {
+	case adc_bipolar10:
+		s->range_table = &range_atmio16d_ai_10_bipolar;
+		break;
+	case adc_bipolar5:
+		s->range_table = &range_atmio16d_ai_5_bipolar;
+		break;
+	case adc_unipolar10:
+		s->range_table = &range_atmio16d_ai_unipolar;
+		break;
+	}
+
+	/* ao subdevice */
+	s++;
+	s->type = COMEDI_SUBD_AO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->n_chan = 2;
+	s->insn_read = atmio16d_ao_insn_read;
+	s->insn_write = atmio16d_ao_insn_write;
+	s->maxdata = 0xfff;	/* 4095 decimal */
+	s->range_table_list = devpriv->ao_range_type_list;
+	switch (devpriv->dac0_range) {
+	case dac_bipolar:
+		devpriv->ao_range_type_list[0] = &range_bipolar10;
+		break;
+	case dac_unipolar:
+		devpriv->ao_range_type_list[0] = &range_unipolar10;
+		break;
+	}
+	switch (devpriv->dac1_range) {
+	case dac_bipolar:
+		devpriv->ao_range_type_list[1] = &range_bipolar10;
+		break;
+	case dac_unipolar:
+		devpriv->ao_range_type_list[1] = &range_unipolar10;
+		break;
+	}
+
+	/* Digital I/O */
+	s++;
+	s->type = COMEDI_SUBD_DIO;
+	s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+	s->n_chan = 8;
+	s->insn_bits = atmio16d_dio_insn_bits;
+	s->insn_config = atmio16d_dio_insn_config;
+	s->maxdata = 1;
+	s->range_table = &range_digital;
+
+	/* 8255 subdevice */
+	s++;
+	if (boardtype->has_8255) {
+		subdev_8255_init(dev, s, NULL, dev->iobase);
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+/* don't yet know how to deal with counter/timers */
+#if 0
+	s++;
+	/* do */
+	s->type = COMEDI_SUBD_TIMER;
+	s->n_chan = 0;
+	s->maxdata = 0
+#endif
+		printk("\n");
+
+	return 0;
+}
+
+static int atmio16d_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: atmio16d: remove\n", dev->minor);
+
+	if (dev->subdevices && boardtype->has_8255)
+		subdev_8255_cleanup(dev, dev->subdevices + 3);
+
+	if (dev->irq)
+		comedi_free_irq(dev->irq, dev);
+
+	reset_atmio16d(dev);
+
+	if (dev->iobase)
+		release_region(dev->iobase, ATMIO16D_SIZE);
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c
new file mode 100644
index 0000000..61a31ad
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_daq_700.c
@@ -0,0 +1,841 @@
+/*
+ *     comedi/drivers/ni_daq_700.c
+ *     Driver for DAQCard-700 DIO only
+ *     copied from 8255
+ *
+ *     COMEDI - Linux Control and Measurement Device Interface
+ *     Copyright (C) 1998 David A. Schleef <ds@schleef.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.
+ *
+ *     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.
+ *
+ */
+
+/*
+Driver: ni_daq_700
+Description: National Instruments PCMCIA DAQCard-700 DIO only
+Author: Fred Brooks <nsaspook@nsaspook.com>,
+  based on ni_daq_dio24 by Daniel Vecino Castel <dvecino@able.es>
+Devices: [National Instruments] PCMCIA DAQ-Card-700 (ni_daq_700)
+Status: works
+Updated: Thu, 21 Feb 2008 12:07:20 +0000
+
+The daqcard-700 appears in Comedi as a single digital I/O subdevice with
+16 channels.  The channel 0 corresponds to the daqcard-700's output
+port, bit 0; channel 8 corresponds to the input port, bit 0.
+
+Direction configuration: channels 0-7 output, 8-15 input (8225 device
+emu as port A output, port B input, port C N/A).
+
+IRQ is assigned but not used.
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ds.h>
+
+static struct pcmcia_device *pcmcia_cur_dev = NULL;
+
+#define DIO700_SIZE 8		// size of io region used by board
+
+static int dio700_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dio700_detach(struct comedi_device * dev);
+
+enum dio700_bustype { pcmcia_bustype };
+
+struct dio700_board {
+	const char *name;
+	int device_id;		// device id for pcmcia board
+	enum dio700_bustype bustype;	// PCMCIA
+	int have_dio;		// have daqcard-700 dio
+	// function pointers so we can use inb/outb or readb/writeb
+	// as appropriate
+	unsigned int (*read_byte) (unsigned int address);
+	void (*write_byte) (unsigned int byte, unsigned int address);
+};
+
+static const struct dio700_board dio700_boards[] = {
+	{
+	      name:	"daqcard-700",
+	      device_id:0x4743,// 0x10b is manufacturer id, 0x4743 is device id
+	      bustype:	pcmcia_bustype,
+	      have_dio:1,
+		},
+	{
+	      name:	"ni_daq_700",
+	      device_id:0x4743,// 0x10b is manufacturer id, 0x4743 is device id
+	      bustype:	pcmcia_bustype,
+	      have_dio:1,
+		},
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct dio700_board *)dev->board_ptr)
+
+struct dio700_private {
+
+	int data;		/* number of data points left to be taken */
+};
+
+
+#define devpriv ((struct dio700_private *)dev->private)
+
+static struct comedi_driver driver_dio700 = {
+      driver_name:"ni_daq_700",
+      module:THIS_MODULE,
+      attach:dio700_attach,
+      detach:dio700_detach,
+      num_names:sizeof(dio700_boards) / sizeof(struct dio700_board),
+      board_name:&dio700_boards[0].name,
+      offset:sizeof(struct dio700_board),
+};
+
+/*	the real driver routines	*/
+
+#define _700_SIZE 8
+
+#define _700_DATA 0
+
+#define DIO_W		0x04
+#define DIO_R		0x05
+
+struct subdev_700_struct {
+	unsigned long cb_arg;
+	int (*cb_func) (int, int, int, unsigned long);
+	int have_irq;
+};
+
+#define CALLBACK_ARG	(((struct subdev_700_struct *)s->private)->cb_arg)
+#define CALLBACK_FUNC	(((struct subdev_700_struct *)s->private)->cb_func)
+#define subdevpriv	((struct subdev_700_struct *)s->private)
+
+static void do_config(struct comedi_device * dev, struct comedi_subdevice * s);
+
+void subdev_700_interrupt(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	short d;
+
+	d = CALLBACK_FUNC(0, _700_DATA, 0, CALLBACK_ARG);
+
+	comedi_buf_put(s->async, d);
+	s->async->events |= COMEDI_CB_EOS;
+
+	comedi_event(dev, s);
+}
+
+static int subdev_700_cb(int dir, int port, int data, unsigned long arg)
+{
+	/* port is always A for output and B for input (8255 emu) */
+	unsigned long iobase = arg;
+
+	if (dir) {
+		outb(data, iobase + DIO_W);
+		return 0;
+	} else {
+		return inb(iobase + DIO_R);
+	}
+}
+
+static int subdev_700_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= (data[0] & data[1]);
+
+		if (data[0] & 0xff)
+			CALLBACK_FUNC(1, _700_DATA, s->state & 0xff,
+				CALLBACK_ARG);
+	}
+
+	data[1] = s->state & 0xff;
+	data[1] |= CALLBACK_FUNC(0, _700_DATA, 0, CALLBACK_ARG) << 8;
+
+	return 2;
+}
+
+static int subdev_700_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+
+	switch (data[0]) {
+	case INSN_CONFIG_DIO_INPUT:
+		break;
+	case INSN_CONFIG_DIO_OUTPUT:
+		break;
+	case INSN_CONFIG_DIO_QUERY:
+		data[1] =
+			(s->io_bits & (1 << CR_CHAN(insn->
+					chanspec))) ? COMEDI_OUTPUT :
+			COMEDI_INPUT;
+		return insn->n;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 1;
+}
+
+static void do_config(struct comedi_device * dev, struct comedi_subdevice * s)
+{				/* use powerup defaults */
+	return;
+}
+
+static int subdev_700_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	unsigned int tmp;
+
+	/* step 1 */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_EXT;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_FOLLOW;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2 */
+
+	if (err)
+		return 2;
+
+	/* step 3 */
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+	if (cmd->scan_begin_arg != 0) {
+		cmd->scan_begin_arg = 0;
+		err++;
+	}
+	if (cmd->convert_arg != 0) {
+		cmd->convert_arg = 0;
+		err++;
+	}
+	if (cmd->scan_end_arg != 1) {
+		cmd->scan_end_arg = 1;
+		err++;
+	}
+	if (cmd->stop_arg != 0) {
+		cmd->stop_arg = 0;
+		err++;
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4 */
+
+	if (err)
+		return 4;
+
+	return 0;
+}
+
+static int subdev_700_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	/* FIXME */
+
+	return 0;
+}
+
+static int subdev_700_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	/* FIXME */
+
+	return 0;
+}
+
+int subdev_700_init(struct comedi_device * dev, struct comedi_subdevice * s, int (*cb) (int,
+		int, int, unsigned long), unsigned long arg)
+{
+	s->type = COMEDI_SUBD_DIO;
+	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+	s->n_chan = 16;
+	s->range_table = &range_digital;
+	s->maxdata = 1;
+
+	s->private = kmalloc(sizeof(struct subdev_700_struct), GFP_KERNEL);
+	if (!s->private)
+		return -ENOMEM;
+
+	CALLBACK_ARG = arg;
+	if (cb == NULL) {
+		CALLBACK_FUNC = subdev_700_cb;
+	} else {
+		CALLBACK_FUNC = cb;
+	}
+	s->insn_bits = subdev_700_insn;
+	s->insn_config = subdev_700_insn_config;
+
+	s->state = 0;
+	s->io_bits = 0x00ff;
+	do_config(dev, s);
+
+	return 0;
+}
+
+int subdev_700_init_irq(struct comedi_device * dev, struct comedi_subdevice * s,
+	int (*cb) (int, int, int, unsigned long), unsigned long arg)
+{
+	int ret;
+
+	ret = subdev_700_init(dev, s, cb, arg);
+	if (ret < 0)
+		return ret;
+
+	s->do_cmdtest = subdev_700_cmdtest;
+	s->do_cmd = subdev_700_cmd;
+	s->cancel = subdev_700_cancel;
+
+	subdevpriv->have_irq = 1;
+
+	return 0;
+}
+
+void subdev_700_cleanup(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	if (s->private) {
+		if (subdevpriv->have_irq) {
+		}
+
+		kfree(s->private);
+	}
+}
+
+EXPORT_SYMBOL(subdev_700_init);
+EXPORT_SYMBOL(subdev_700_init_irq);
+EXPORT_SYMBOL(subdev_700_cleanup);
+EXPORT_SYMBOL(subdev_700_interrupt);
+
+static int dio700_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	unsigned long iobase = 0;
+#ifdef incomplete
+	unsigned int irq = 0;
+#endif
+	struct pcmcia_device *link;
+
+	/* allocate and initialize dev->private */
+	if (alloc_private(dev, sizeof(struct dio700_private)) < 0)
+		return -ENOMEM;
+
+	// get base address, irq etc. based on bustype
+	switch (thisboard->bustype) {
+	case pcmcia_bustype:
+		link = pcmcia_cur_dev;	/* XXX hack */
+		if (!link)
+			return -EIO;
+		iobase = link->io.BasePort1;
+#ifdef incomplete
+		irq = link->irq.AssignedIRQ;
+#endif
+		break;
+	default:
+		printk("bug! couldn't determine board type\n");
+		return -EINVAL;
+		break;
+	}
+	printk("comedi%d: ni_daq_700: %s, io 0x%lx", dev->minor,
+		thisboard->name, iobase);
+#ifdef incomplete
+	if (irq) {
+		printk(", irq %u", irq);
+	}
+#endif
+
+	printk("\n");
+
+	if (iobase == 0) {
+		printk("io base address is zero!\n");
+		return -EINVAL;
+	}
+
+	dev->iobase = iobase;
+
+#ifdef incomplete
+	/* grab our IRQ */
+	dev->irq = irq;
+#endif
+
+	dev->board_name = thisboard->name;
+
+	if (alloc_subdevices(dev, 1) < 0)
+		return -ENOMEM;
+
+	/* DAQCard-700 dio */
+	s = dev->subdevices + 0;
+	subdev_700_init(dev, s, NULL, dev->iobase);
+
+	return 0;
+};
+
+static int dio700_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: ni_daq_700: cs-remove\n", dev->minor);
+
+	if (dev->subdevices)
+		subdev_700_cleanup(dev, dev->subdevices + 0);
+
+	if (thisboard->bustype != pcmcia_bustype && dev->iobase)
+		release_region(dev->iobase, DIO700_SIZE);
+	if (dev->irq)
+		comedi_free_irq(dev->irq, dev);
+
+	return 0;
+};
+
+// PCMCIA crap
+
+/*
+   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
+   you do not define PCMCIA_DEBUG at all, all the debug code will be
+   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
+   be present but disabled -- but it can then be enabled for specific
+   modules at load time with a 'pc_debug=#' option to insmod.
+*/
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+module_param(pc_debug, int, 0644);
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+static char *version = "ni_daq_700.c, based on dummy_cs.c";
+#else
+#define DEBUG(n, args...)
+#endif
+
+/*====================================================================*/
+
+static void dio700_config(struct pcmcia_device *link);
+static void dio700_release(struct pcmcia_device *link);
+static int dio700_cs_suspend(struct pcmcia_device *p_dev);
+static int dio700_cs_resume(struct pcmcia_device *p_dev);
+
+/*
+   The attach() and detach() entry points are used to create and destroy
+   "instances" of the driver, where each instance represents everything
+   needed to manage one actual PCMCIA card.
+*/
+
+static int dio700_cs_attach(struct pcmcia_device *);
+static void dio700_cs_detach(struct pcmcia_device *);
+
+/*
+   You'll also need to prototype all the functions that will actually
+   be used to talk to your device.  See 'memory_cs' for a good example
+   of a fully self-sufficient driver; the other drivers rely more or
+   less on other parts of the kernel.
+*/
+
+/*
+   The dev_info variable is the "key" that is used to match up this
+   device driver with appropriate cards, through the card configuration
+   database.
+*/
+
+static const dev_info_t dev_info = "ni_daq_700";
+
+struct local_info_t {
+	struct pcmcia_device *link;
+	dev_node_t node;
+	int stop;
+	struct bus_operations *bus;
+};
+
+/*======================================================================
+
+    dio700_cs_attach() creates an "instance" of the driver, allocating
+    local data structures for one device.  The device is registered
+    with Card Services.
+
+    The dev_link structure is initialized, but we don't actually
+    configure the card at this point -- we wait until we receive a
+    card insertion event.
+
+======================================================================*/
+
+static int dio700_cs_attach(struct pcmcia_device *link)
+{
+	struct local_info_t *local;
+
+	printk(KERN_INFO "ni_daq_700:  cs-attach\n");
+
+	DEBUG(0, "dio700_cs_attach()\n");
+
+	/* Allocate space for private device-specific data */
+	local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
+	if (!local)
+		return -ENOMEM;
+	local->link = link;
+	link->priv = local;
+
+	/* Interrupt setup */
+	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+	link->irq.Handler = NULL;
+
+	/*
+	   General socket configuration defaults can go here.  In this
+	   client, we assume very little, and rely on the CIS for almost
+	   everything.  In most clients, many details (i.e., number, sizes,
+	   and attributes of IO windows) are fixed by the nature of the
+	   device, and can be hard-wired here.
+	 */
+	link->conf.Attributes = 0;
+	link->conf.IntType = INT_MEMORY_AND_IO;
+
+	pcmcia_cur_dev = link;
+
+	dio700_config(link);
+
+	return 0;
+}				/* dio700_cs_attach */
+
+/*======================================================================
+
+    This deletes a driver "instance".  The device is de-registered
+    with Card Services.  If it has been released, all local data
+    structures are freed.  Otherwise, the structures will be freed
+    when the device is released.
+
+======================================================================*/
+
+static void dio700_cs_detach(struct pcmcia_device *link)
+{
+
+	printk(KERN_INFO "ni_daq_700: cs-detach!\n");
+
+	DEBUG(0, "dio700_cs_detach(0x%p)\n", link);
+
+	if (link->dev_node) {
+		((struct local_info_t *) link->priv)->stop = 1;
+		dio700_release(link);
+	}
+
+	/* This points to the parent struct local_info_t struct */
+	if (link->priv)
+		kfree(link->priv);
+
+}				/* dio700_cs_detach */
+
+/*======================================================================
+
+    dio700_config() is scheduled to run after a CARD_INSERTION event
+    is received, to configure the PCMCIA socket, and to make the
+    device available to the system.
+
+======================================================================*/
+
+static void dio700_config(struct pcmcia_device *link)
+{
+	struct local_info_t *dev = link->priv;
+	tuple_t tuple;
+	cisparse_t parse;
+	int last_ret;
+	u_char buf[64];
+	win_req_t req;
+	memreq_t map;
+	cistpl_cftable_entry_t dflt = { 0 };
+
+	printk(KERN_INFO "ni_daq_700:  cs-config\n");
+
+	DEBUG(0, "dio700_config(0x%p)\n", link);
+
+	/*
+	   This reads the card's CONFIG tuple to find its configuration
+	   registers.
+	 */
+	tuple.DesiredTuple = CISTPL_CONFIG;
+	tuple.Attributes = 0;
+	tuple.TupleData = buf;
+	tuple.TupleDataMax = sizeof(buf);
+	tuple.TupleOffset = 0;
+	if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) {
+		cs_error(link, GetFirstTuple, last_ret);
+		goto cs_failed;
+	}
+	if ((last_ret = pcmcia_get_tuple_data(link, &tuple)) != 0) {
+		cs_error(link, GetTupleData, last_ret);
+		goto cs_failed;
+	}
+	if ((last_ret = pcmcia_parse_tuple(&tuple, &parse)) != 0) {
+		cs_error(link, ParseTuple, last_ret);
+		goto cs_failed;
+	}
+	link->conf.ConfigBase = parse.config.base;
+	link->conf.Present = parse.config.rmask[0];
+
+	/*
+	   In this loop, we scan the CIS for configuration table entries,
+	   each of which describes a valid card configuration, including
+	   voltage, IO window, memory window, and interrupt settings.
+
+	   We make no assumptions about the card to be configured: we use
+	   just the information available in the CIS.  In an ideal world,
+	   this would work for any PCMCIA card, but it requires a complete
+	   and accurate CIS.  In practice, a driver usually "knows" most of
+	   these things without consulting the CIS, and most client drivers
+	   will only use the CIS to fill in implementation-defined details.
+	 */
+	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+	if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) {
+		cs_error(link, GetFirstTuple, last_ret);
+		goto cs_failed;
+	}
+	while (1) {
+		cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+		if (pcmcia_get_tuple_data(link, &tuple) != 0)
+			goto next_entry;
+		if (pcmcia_parse_tuple(&tuple, &parse) != 0)
+			goto next_entry;
+
+		if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+			dflt = *cfg;
+		if (cfg->index == 0)
+			goto next_entry;
+		link->conf.ConfigIndex = cfg->index;
+
+		/* Does this card need audio output? */
+		if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+			link->conf.Attributes |= CONF_ENABLE_SPKR;
+			link->conf.Status = CCSR_AUDIO_ENA;
+		}
+
+		/* Do we need to allocate an interrupt? */
+		if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
+			link->conf.Attributes |= CONF_ENABLE_IRQ;
+
+		/* IO window settings */
+		link->io.NumPorts1 = link->io.NumPorts2 = 0;
+		if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+			cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+			link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+			if (!(io->flags & CISTPL_IO_8BIT))
+				link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+			if (!(io->flags & CISTPL_IO_16BIT))
+				link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+			link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+			link->io.BasePort1 = io->win[0].base;
+			link->io.NumPorts1 = io->win[0].len;
+			if (io->nwin > 1) {
+				link->io.Attributes2 = link->io.Attributes1;
+				link->io.BasePort2 = io->win[1].base;
+				link->io.NumPorts2 = io->win[1].len;
+			}
+			/* This reserves IO space but doesn't actually enable it */
+			if (pcmcia_request_io(link, &link->io) != 0)
+				goto next_entry;
+		}
+
+		if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
+			cistpl_mem_t *mem =
+				(cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
+			req.Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
+			req.Attributes |= WIN_ENABLE;
+			req.Base = mem->win[0].host_addr;
+			req.Size = mem->win[0].len;
+			if (req.Size < 0x1000)
+				req.Size = 0x1000;
+			req.AccessSpeed = 0;
+			if (pcmcia_request_window(&link, &req, &link->win))
+				goto next_entry;
+			map.Page = 0;
+			map.CardOffset = mem->win[0].card_addr;
+			if (pcmcia_map_mem_page(link->win, &map))
+				goto next_entry;
+		}
+		/* If we got this far, we're cool! */
+		break;
+
+	      next_entry:
+		if ((last_ret = pcmcia_get_next_tuple(link, &tuple)) != 0) {
+			cs_error(link, GetNextTuple, last_ret);
+			goto cs_failed;
+		}
+	}
+
+	/*
+	   Allocate an interrupt line.  Note that this does not assign a
+	   handler to the interrupt, unless the 'Handler' member of the
+	   irq structure is initialized.
+	 */
+	if (link->conf.Attributes & CONF_ENABLE_IRQ)
+		if ((last_ret = pcmcia_request_irq(link, &link->irq)) != 0) {
+			cs_error(link, RequestIRQ, last_ret);
+			goto cs_failed;
+		}
+
+	/*
+	   This actually configures the PCMCIA socket -- setting up
+	   the I/O windows and the interrupt mapping, and putting the
+	   card and host interface into "Memory and IO" mode.
+	 */
+	if ((last_ret = pcmcia_request_configuration(link, &link->conf)) != 0) {
+		cs_error(link, RequestConfiguration, last_ret);
+		goto cs_failed;
+	}
+
+	/*
+	   At this point, the dev_node_t structure(s) need to be
+	   initialized and arranged in a linked list at link->dev.
+	 */
+	sprintf(dev->node.dev_name, "ni_daq_700");
+	dev->node.major = dev->node.minor = 0;
+	link->dev_node = &dev->node;
+
+	/* Finally, report what we've done */
+	printk(KERN_INFO "%s: index 0x%02x",
+		dev->node.dev_name, link->conf.ConfigIndex);
+	if (link->conf.Attributes & CONF_ENABLE_IRQ)
+		printk(", irq %d", link->irq.AssignedIRQ);
+	if (link->io.NumPorts1)
+		printk(", io 0x%04x-0x%04x", link->io.BasePort1,
+			link->io.BasePort1 + link->io.NumPorts1 - 1);
+	if (link->io.NumPorts2)
+		printk(" & 0x%04x-0x%04x", link->io.BasePort2,
+			link->io.BasePort2 + link->io.NumPorts2 - 1);
+	if (link->win)
+		printk(", mem 0x%06lx-0x%06lx", req.Base,
+			req.Base + req.Size - 1);
+	printk("\n");
+
+	return;
+
+      cs_failed:
+	printk(KERN_INFO "ni_daq_700 cs failed");
+	dio700_release(link);
+
+}				/* dio700_config */
+
+static void dio700_release(struct pcmcia_device *link)
+{
+	DEBUG(0, "dio700_release(0x%p)\n", link);
+
+	pcmcia_disable_device(link);
+}				/* dio700_release */
+
+/*======================================================================
+
+    The card status event handler.  Mostly, this schedules other
+    stuff to run after an event is received.
+
+    When a CARD_REMOVAL event is received, we immediately set a
+    private flag to block future accesses to this device.  All the
+    functions that actually access the device should check this flag
+    to make sure the card is still present.
+
+======================================================================*/
+
+static int dio700_cs_suspend(struct pcmcia_device *link)
+{
+	struct local_info_t *local = link->priv;
+
+	/* Mark the device as stopped, to block IO until later */
+	local->stop = 1;
+	return 0;
+}				/* dio700_cs_suspend */
+
+static int dio700_cs_resume(struct pcmcia_device *link)
+{
+	struct local_info_t *local = link->priv;
+
+	local->stop = 0;
+	return 0;
+}				/* dio700_cs_resume */
+
+/*====================================================================*/
+
+static struct pcmcia_device_id dio700_cs_ids[] = {
+	/* N.B. These IDs should match those in dio700_boards */
+	PCMCIA_DEVICE_MANF_CARD(0x010b, 0x4743),	/* daqcard-700 */
+	PCMCIA_DEVICE_NULL
+};
+
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pcmcia, dio700_cs_ids);
+
+struct pcmcia_driver dio700_cs_driver = {
+	.probe = dio700_cs_attach,
+	.remove = dio700_cs_detach,
+	.suspend = dio700_cs_suspend,
+	.resume = dio700_cs_resume,
+	.id_table = dio700_cs_ids,
+	.owner = THIS_MODULE,
+	.drv = {
+			.name = dev_info,
+		},
+};
+
+static int __init init_dio700_cs(void)
+{
+	printk("ni_daq_700:  cs-init \n");
+	DEBUG(0, "%s\n", version);
+	pcmcia_register_driver(&dio700_cs_driver);
+	return 0;
+}
+
+static void __exit exit_dio700_cs(void)
+{
+	DEBUG(0, "ni_daq_700: unloading\n");
+	pcmcia_unregister_driver(&dio700_cs_driver);
+}
+int __init init_module(void)
+{
+	int ret;
+
+	ret = init_dio700_cs();
+	if (ret < 0)
+		return ret;
+
+	return comedi_driver_register(&driver_dio700);
+}
+
+void __exit cleanup_module(void)
+{
+	exit_dio700_cs();
+	comedi_driver_unregister(&driver_dio700);
+}
diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c
new file mode 100644
index 0000000..daec5c4b
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c
@@ -0,0 +1,598 @@
+/*
+    comedi/drivers/ni_daq_dio24.c
+    Driver for National Instruments PCMCIA DAQ-Card DIO-24
+    Copyright (C) 2002 Daniel Vecino Castel <dvecino@able.es>
+
+    PCMCIA crap at end of file is adapted from dummy_cs.c 1.31 2001/08/24 12:13:13
+    from the pcmcia package.
+    The initial developer of the pcmcia dummy_cs.c code is David A. Hinds
+    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
+    are Copyright (C) 1999 David A. Hinds.  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.
+
+    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.
+
+************************************************************************
+*/
+/*
+Driver: ni_daq_dio24
+Description: National Instruments PCMCIA DAQ-Card DIO-24
+Author: Daniel Vecino Castel <dvecino@able.es>
+Devices: [National Instruments] PCMCIA DAQ-Card DIO-24 (ni_daq_dio24)
+Status: ?
+Updated: Thu, 07 Nov 2002 21:53:06 -0800
+
+This is just a wrapper around the 8255.o driver to properly handle
+the PCMCIA interface.
+*/
+
+//#define LABPC_DEBUG   // enable debugging messages
+#undef LABPC_DEBUG
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#include "8255.h"
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ds.h>
+
+static struct pcmcia_device *pcmcia_cur_dev = NULL;
+
+#define DIO24_SIZE 4		// size of io region used by board
+
+static int dio24_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dio24_detach(struct comedi_device * dev);
+
+enum dio24_bustype { pcmcia_bustype };
+
+typedef struct dio24_board_struct {
+	const char *name;
+	int device_id;		// device id for pcmcia board
+	enum dio24_bustype bustype;	// PCMCIA
+	int have_dio;		// have 8255 chip
+	// function pointers so we can use inb/outb or readb/writeb as appropriate
+	unsigned int (*read_byte) (unsigned int address);
+	void (*write_byte) (unsigned int byte, unsigned int address);
+} dio24_board;
+
+static const dio24_board dio24_boards[] = {
+	{
+	      name:	"daqcard-dio24",
+	      device_id:0x475c,// 0x10b is manufacturer id, 0x475c is device id
+	      bustype:	pcmcia_bustype,
+	      have_dio:1,
+		},
+	{
+	      name:	"ni_daq_dio24",
+	      device_id:0x475c,// 0x10b is manufacturer id, 0x475c is device id
+	      bustype:	pcmcia_bustype,
+	      have_dio:1,
+		},
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const dio24_board *)dev->board_ptr)
+
+struct dio24_private {
+
+	int data;		/* number of data points left to be taken */
+};
+
+
+#define devpriv ((struct dio24_private *)dev->private)
+
+static struct comedi_driver driver_dio24 = {
+      driver_name:"ni_daq_dio24",
+      module:THIS_MODULE,
+      attach:dio24_attach,
+      detach:dio24_detach,
+      num_names:sizeof(dio24_boards) / sizeof(dio24_board),
+      board_name:&dio24_boards[0].name,
+      offset:sizeof(dio24_board),
+};
+
+static int dio24_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	unsigned long iobase = 0;
+#ifdef incomplete
+	unsigned int irq = 0;
+#endif
+	struct pcmcia_device *link;
+
+	/* allocate and initialize dev->private */
+	if (alloc_private(dev, sizeof(struct dio24_private)) < 0)
+		return -ENOMEM;
+
+	// get base address, irq etc. based on bustype
+	switch (thisboard->bustype) {
+	case pcmcia_bustype:
+		link = pcmcia_cur_dev;	/* XXX hack */
+		if (!link)
+			return -EIO;
+		iobase = link->io.BasePort1;
+#ifdef incomplete
+		irq = link->irq.AssignedIRQ;
+#endif
+		break;
+	default:
+		printk("bug! couldn't determine board type\n");
+		return -EINVAL;
+		break;
+	}
+	printk("comedi%d: ni_daq_dio24: %s, io 0x%lx", dev->minor,
+		thisboard->name, iobase);
+#ifdef incomplete
+	if (irq) {
+		printk(", irq %u", irq);
+	}
+#endif
+
+	printk("\n");
+
+	if (iobase == 0) {
+		printk("io base address is zero!\n");
+		return -EINVAL;
+	}
+
+	dev->iobase = iobase;
+
+#ifdef incomplete
+	/* grab our IRQ */
+	dev->irq = irq;
+#endif
+
+	dev->board_name = thisboard->name;
+
+	if (alloc_subdevices(dev, 1) < 0)
+		return -ENOMEM;
+
+	/* 8255 dio */
+	s = dev->subdevices + 0;
+	subdev_8255_init(dev, s, NULL, dev->iobase);
+
+	return 0;
+};
+
+static int dio24_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: ni_daq_dio24: remove\n", dev->minor);
+
+	if (dev->subdevices)
+		subdev_8255_cleanup(dev, dev->subdevices + 0);
+
+	if (thisboard->bustype != pcmcia_bustype && dev->iobase)
+		release_region(dev->iobase, DIO24_SIZE);
+	if (dev->irq)
+		comedi_free_irq(dev->irq, dev);
+
+	return 0;
+};
+
+// PCMCIA crap
+
+/*
+   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
+   you do not define PCMCIA_DEBUG at all, all the debug code will be
+   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
+   be present but disabled -- but it can then be enabled for specific
+   modules at load time with a 'pc_debug=#' option to insmod.
+*/
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+module_param(pc_debug, int, 0644);
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+static char *version = "ni_daq_dio24.c, based on dummy_cs.c";
+#else
+#define DEBUG(n, args...)
+#endif
+
+/*====================================================================*/
+
+static void dio24_config(struct pcmcia_device *link);
+static void dio24_release(struct pcmcia_device *link);
+static int dio24_cs_suspend(struct pcmcia_device *p_dev);
+static int dio24_cs_resume(struct pcmcia_device *p_dev);
+
+/*
+   The attach() and detach() entry points are used to create and destroy
+   "instances" of the driver, where each instance represents everything
+   needed to manage one actual PCMCIA card.
+*/
+
+static int dio24_cs_attach(struct pcmcia_device *);
+static void dio24_cs_detach(struct pcmcia_device *);
+
+/*
+   You'll also need to prototype all the functions that will actually
+   be used to talk to your device.  See 'memory_cs' for a good example
+   of a fully self-sufficient driver; the other drivers rely more or
+   less on other parts of the kernel.
+*/
+
+/*
+   The dev_info variable is the "key" that is used to match up this
+   device driver with appropriate cards, through the card configuration
+   database.
+*/
+
+static const dev_info_t dev_info = "ni_daq_dio24";
+
+typedef struct local_info_t {
+	struct pcmcia_device *link;
+	dev_node_t node;
+	int stop;
+	struct bus_operations *bus;
+} local_info_t;
+
+/*======================================================================
+
+    dio24_cs_attach() creates an "instance" of the driver, allocating
+    local data structures for one device.  The device is registered
+    with Card Services.
+
+    The dev_link structure is initialized, but we don't actually
+    configure the card at this point -- we wait until we receive a
+    card insertion event.
+
+======================================================================*/
+
+static int dio24_cs_attach(struct pcmcia_device *link)
+{
+	local_info_t *local;
+
+	printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - CS-attach!\n");
+
+	DEBUG(0, "dio24_cs_attach()\n");
+
+	/* Allocate space for private device-specific data */
+	local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
+	if (!local)
+		return -ENOMEM;
+	local->link = link;
+	link->priv = local;
+
+	/* Interrupt setup */
+	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+	link->irq.Handler = NULL;
+
+	/*
+	   General socket configuration defaults can go here.  In this
+	   client, we assume very little, and rely on the CIS for almost
+	   everything.  In most clients, many details (i.e., number, sizes,
+	   and attributes of IO windows) are fixed by the nature of the
+	   device, and can be hard-wired here.
+	 */
+	link->conf.Attributes = 0;
+	link->conf.IntType = INT_MEMORY_AND_IO;
+
+	pcmcia_cur_dev = link;
+
+	dio24_config(link);
+
+	return 0;
+}				/* dio24_cs_attach */
+
+/*======================================================================
+
+    This deletes a driver "instance".  The device is de-registered
+    with Card Services.  If it has been released, all local data
+    structures are freed.  Otherwise, the structures will be freed
+    when the device is released.
+
+======================================================================*/
+
+static void dio24_cs_detach(struct pcmcia_device *link)
+{
+
+	printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - cs-detach!\n");
+
+	DEBUG(0, "dio24_cs_detach(0x%p)\n", link);
+
+	if (link->dev_node) {
+		((local_info_t *) link->priv)->stop = 1;
+		dio24_release(link);
+	}
+
+	/* This points to the parent local_info_t struct */
+	if (link->priv)
+		kfree(link->priv);
+
+}				/* dio24_cs_detach */
+
+/*======================================================================
+
+    dio24_config() is scheduled to run after a CARD_INSERTION event
+    is received, to configure the PCMCIA socket, and to make the
+    device available to the system.
+
+======================================================================*/
+
+static void dio24_config(struct pcmcia_device *link)
+{
+	local_info_t *dev = link->priv;
+	tuple_t tuple;
+	cisparse_t parse;
+	int last_ret;
+	u_char buf[64];
+	win_req_t req;
+	memreq_t map;
+	cistpl_cftable_entry_t dflt = { 0 };
+
+	printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO! - config\n");
+
+	DEBUG(0, "dio24_config(0x%p)\n", link);
+
+	/*
+	   This reads the card's CONFIG tuple to find its configuration
+	   registers.
+	 */
+	tuple.DesiredTuple = CISTPL_CONFIG;
+	tuple.Attributes = 0;
+	tuple.TupleData = buf;
+	tuple.TupleDataMax = sizeof(buf);
+	tuple.TupleOffset = 0;
+	if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) {
+		cs_error(link, GetFirstTuple, last_ret);
+		goto cs_failed;
+	}
+	if ((last_ret = pcmcia_get_tuple_data(link, &tuple)) != 0) {
+		cs_error(link, GetTupleData, last_ret);
+		goto cs_failed;
+	}
+	if ((last_ret = pcmcia_parse_tuple(&tuple, &parse)) != 0) {
+		cs_error(link, ParseTuple, last_ret);
+		goto cs_failed;
+	}
+	link->conf.ConfigBase = parse.config.base;
+	link->conf.Present = parse.config.rmask[0];
+
+	/*
+	   In this loop, we scan the CIS for configuration table entries,
+	   each of which describes a valid card configuration, including
+	   voltage, IO window, memory window, and interrupt settings.
+
+	   We make no assumptions about the card to be configured: we use
+	   just the information available in the CIS.  In an ideal world,
+	   this would work for any PCMCIA card, but it requires a complete
+	   and accurate CIS.  In practice, a driver usually "knows" most of
+	   these things without consulting the CIS, and most client drivers
+	   will only use the CIS to fill in implementation-defined details.
+	 */
+	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+	if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) {
+		cs_error(link, GetFirstTuple, last_ret);
+		goto cs_failed;
+	}
+	while (1) {
+		cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+		if (pcmcia_get_tuple_data(link, &tuple) != 0)
+			goto next_entry;
+		if (pcmcia_parse_tuple(&tuple, &parse) != 0)
+			goto next_entry;
+
+		if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+			dflt = *cfg;
+		if (cfg->index == 0)
+			goto next_entry;
+		link->conf.ConfigIndex = cfg->index;
+
+		/* Does this card need audio output? */
+		if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+			link->conf.Attributes |= CONF_ENABLE_SPKR;
+			link->conf.Status = CCSR_AUDIO_ENA;
+		}
+
+		/* Do we need to allocate an interrupt? */
+		if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
+			link->conf.Attributes |= CONF_ENABLE_IRQ;
+
+		/* IO window settings */
+		link->io.NumPorts1 = link->io.NumPorts2 = 0;
+		if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+			cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+			link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+			if (!(io->flags & CISTPL_IO_8BIT))
+				link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+			if (!(io->flags & CISTPL_IO_16BIT))
+				link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+			link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+			link->io.BasePort1 = io->win[0].base;
+			link->io.NumPorts1 = io->win[0].len;
+			if (io->nwin > 1) {
+				link->io.Attributes2 = link->io.Attributes1;
+				link->io.BasePort2 = io->win[1].base;
+				link->io.NumPorts2 = io->win[1].len;
+			}
+			/* This reserves IO space but doesn't actually enable it */
+			if (pcmcia_request_io(link, &link->io) != 0)
+				goto next_entry;
+		}
+
+		if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
+			cistpl_mem_t *mem =
+				(cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
+			req.Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
+			req.Attributes |= WIN_ENABLE;
+			req.Base = mem->win[0].host_addr;
+			req.Size = mem->win[0].len;
+			if (req.Size < 0x1000)
+				req.Size = 0x1000;
+			req.AccessSpeed = 0;
+			if (pcmcia_request_window(&link, &req, &link->win))
+				goto next_entry;
+			map.Page = 0;
+			map.CardOffset = mem->win[0].card_addr;
+			if (pcmcia_map_mem_page(link->win, &map))
+				goto next_entry;
+		}
+		/* If we got this far, we're cool! */
+		break;
+
+	      next_entry:
+		if ((last_ret = pcmcia_get_next_tuple(link, &tuple)) != 0) {
+			cs_error(link, GetNextTuple, last_ret);
+			goto cs_failed;
+		}
+	}
+
+	/*
+	   Allocate an interrupt line.  Note that this does not assign a
+	   handler to the interrupt, unless the 'Handler' member of the
+	   irq structure is initialized.
+	 */
+	if (link->conf.Attributes & CONF_ENABLE_IRQ)
+		if ((last_ret = pcmcia_request_irq(link, &link->irq)) != 0) {
+			cs_error(link, RequestIRQ, last_ret);
+			goto cs_failed;
+		}
+
+	/*
+	   This actually configures the PCMCIA socket -- setting up
+	   the I/O windows and the interrupt mapping, and putting the
+	   card and host interface into "Memory and IO" mode.
+	 */
+	if ((last_ret = pcmcia_request_configuration(link, &link->conf)) != 0) {
+		cs_error(link, RequestConfiguration, last_ret);
+		goto cs_failed;
+	}
+
+	/*
+	   At this point, the dev_node_t structure(s) need to be
+	   initialized and arranged in a linked list at link->dev.
+	 */
+	sprintf(dev->node.dev_name, "ni_daq_dio24");
+	dev->node.major = dev->node.minor = 0;
+	link->dev_node = &dev->node;
+
+	/* Finally, report what we've done */
+	printk(KERN_INFO "%s: index 0x%02x",
+		dev->node.dev_name, link->conf.ConfigIndex);
+	if (link->conf.Attributes & CONF_ENABLE_IRQ)
+		printk(", irq %d", link->irq.AssignedIRQ);
+	if (link->io.NumPorts1)
+		printk(", io 0x%04x-0x%04x", link->io.BasePort1,
+			link->io.BasePort1 + link->io.NumPorts1 - 1);
+	if (link->io.NumPorts2)
+		printk(" & 0x%04x-0x%04x", link->io.BasePort2,
+			link->io.BasePort2 + link->io.NumPorts2 - 1);
+	if (link->win)
+		printk(", mem 0x%06lx-0x%06lx", req.Base,
+			req.Base + req.Size - 1);
+	printk("\n");
+
+	return;
+
+      cs_failed:
+	printk(KERN_INFO "Fallo");
+	dio24_release(link);
+
+}				/* dio24_config */
+
+static void dio24_release(struct pcmcia_device *link)
+{
+	DEBUG(0, "dio24_release(0x%p)\n", link);
+
+	pcmcia_disable_device(link);
+}				/* dio24_release */
+
+/*======================================================================
+
+    The card status event handler.  Mostly, this schedules other
+    stuff to run after an event is received.
+
+    When a CARD_REMOVAL event is received, we immediately set a
+    private flag to block future accesses to this device.  All the
+    functions that actually access the device should check this flag
+    to make sure the card is still present.
+
+======================================================================*/
+
+static int dio24_cs_suspend(struct pcmcia_device *link)
+{
+	local_info_t *local = link->priv;
+
+	/* Mark the device as stopped, to block IO until later */
+	local->stop = 1;
+	return 0;
+}				/* dio24_cs_suspend */
+
+static int dio24_cs_resume(struct pcmcia_device *link)
+{
+	local_info_t *local = link->priv;
+
+	local->stop = 0;
+	return 0;
+}				/* dio24_cs_resume */
+
+/*====================================================================*/
+
+static struct pcmcia_device_id dio24_cs_ids[] = {
+	/* N.B. These IDs should match those in dio24_boards */
+	PCMCIA_DEVICE_MANF_CARD(0x010b, 0x475c),	/* daqcard-dio24 */
+	PCMCIA_DEVICE_NULL
+};
+
+MODULE_DEVICE_TABLE(pcmcia, dio24_cs_ids);
+
+struct pcmcia_driver dio24_cs_driver = {
+	.probe = dio24_cs_attach,
+	.remove = dio24_cs_detach,
+	.suspend = dio24_cs_suspend,
+	.resume = dio24_cs_resume,
+	.id_table = dio24_cs_ids,
+	.owner = THIS_MODULE,
+	.drv = {
+			.name = dev_info,
+		},
+};
+
+static int __init init_dio24_cs(void)
+{
+	printk("ni_daq_dio24: HOLA SOY YO!\n");
+	DEBUG(0, "%s\n", version);
+	pcmcia_register_driver(&dio24_cs_driver);
+	return 0;
+}
+
+static void __exit exit_dio24_cs(void)
+{
+	DEBUG(0, "ni_dio24: unloading\n");
+	pcmcia_unregister_driver(&dio24_cs_driver);
+}
+
+int __init init_module(void)
+{
+	int ret;
+
+	ret = init_dio24_cs();
+	if (ret < 0)
+		return ret;
+
+	return comedi_driver_register(&driver_dio24);
+}
+
+void __exit cleanup_module(void)
+{
+	exit_dio24_cs();
+	comedi_driver_unregister(&driver_dio24);
+}
diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c
new file mode 100644
index 0000000..37898d8
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_labpc.c
@@ -0,0 +1,2005 @@
+/*
+    comedi/drivers/ni_labpc.c
+    Driver for National Instruments Lab-PC series boards and compatibles
+    Copyright (C) 2001, 2002, 2003 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+    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.
+
+************************************************************************
+*/
+/*
+Driver: ni_labpc
+Description: National Instruments Lab-PC (& compatibles)
+Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+Devices: [National Instruments] Lab-PC-1200 (labpc-1200),
+  Lab-PC-1200AI (labpc-1200ai), Lab-PC+ (lab-pc+), PCI-1200 (ni_labpc)
+Status: works
+
+Tested with lab-pc-1200.  For the older Lab-PC+, not all input ranges
+and analog references will work, the available ranges/arefs will
+depend on how you have configured the jumpers on your board
+(see your owner's manual).
+
+Kernel-level ISA plug-and-play support for the lab-pc-1200
+boards has not
+yet been added to the driver, mainly due to the fact that
+I don't know the device id numbers.  If you have one
+of these boards,
+please file a bug report at https://bugs.comedi.org/
+so I can get the necessary information from you.
+
+The 1200 series boards have onboard calibration dacs for correcting
+analog input/output offsets and gains.  The proper settings for these
+caldacs are stored on the board's eeprom.  To read the caldac values
+from the eeprom and store them into a file that can be then be used by
+comedilib, use the comedi_calibrate program.
+
+Configuration options - ISA boards:
+  [0] - I/O port base address
+  [1] - IRQ (optional, required for timed or externally triggered conversions)
+  [2] - DMA channel (optional)
+
+Configuration options - PCI boards:
+  [0] - bus (optional)
+  [1] - slot (optional)
+
+The Lab-pc+ has quirky chanlist requirements
+when scanning multiple channels.  Multiple channel scan
+sequence must start at highest channel, then decrement down to
+channel 0.  The rest of the cards can scan down like lab-pc+ or scan
+up from channel zero.  Chanlists consisting of all one channel
+are also legal, and allow you to pace conversions in bursts.
+
+*/
+
+/*
+
+NI manuals:
+341309a (labpc-1200 register manual)
+340914a (pci-1200)
+320502b (lab-pc+)
+
+*/
+
+#undef LABPC_DEBUG
+//#define LABPC_DEBUG   // enable debugging messages
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+#include <asm/dma.h>
+
+#include "8253.h"
+#include "8255.h"
+#include "mite.h"
+#include "comedi_fc.h"
+#include "ni_labpc.h"
+
+#define DRV_NAME "ni_labpc"
+
+#define LABPC_SIZE           32	// size of io region used by board
+#define LABPC_TIMER_BASE            500	// 2 MHz master clock
+
+/* Registers for the lab-pc+ */
+
+//write-only registers
+#define COMMAND1_REG	0x0
+#define   ADC_GAIN_MASK	(0x7 << 4)
+#define   ADC_CHAN_BITS(x)	((x) & 0x7)
+#define   ADC_SCAN_EN_BIT	0x80	// enables multi channel scans
+#define COMMAND2_REG	0x1
+#define   PRETRIG_BIT	0x1	// enable pretriggering (used in conjunction with SWTRIG)
+#define   HWTRIG_BIT	0x2	// enable paced conversions on external trigger
+#define   SWTRIG_BIT	0x4	// enable paced conversions
+#define   CASCADE_BIT	0x8	// use two cascaded counters for pacing
+#define   DAC_PACED_BIT(channel)	(0x40 << ((channel) & 0x1))
+#define COMMAND3_REG	0x2
+#define   DMA_EN_BIT	0x1	// enable dma transfers
+#define   DIO_INTR_EN_BIT	0x2	// enable interrupts for 8255
+#define   DMATC_INTR_EN_BIT	0x4	// enable dma terminal count interrupt
+#define   TIMER_INTR_EN_BIT	0x8	// enable timer interrupt
+#define   ERR_INTR_EN_BIT	0x10	// enable error interrupt
+#define   ADC_FNE_INTR_EN_BIT	0x20	// enable fifo not empty interrupt
+#define ADC_CONVERT_REG	0x3
+#define DAC_LSB_REG(channel)	(0x4 + 2 * ((channel) & 0x1))
+#define DAC_MSB_REG(channel)	(0x5 + 2 * ((channel) & 0x1))
+#define ADC_CLEAR_REG	0x8
+#define DMATC_CLEAR_REG	0xa
+#define TIMER_CLEAR_REG	0xc
+#define COMMAND6_REG	0xe	// 1200 boards only
+#define   ADC_COMMON_BIT	0x1	// select ground or common-mode reference
+#define   ADC_UNIP_BIT	0x2	// adc unipolar
+#define   DAC_UNIP_BIT(channel)	(0x4 << ((channel) & 0x1))	// dac unipolar
+#define   ADC_FHF_INTR_EN_BIT	0x20	// enable fifo half full interrupt
+#define   A1_INTR_EN_BIT	0x40	// enable interrupt on end of hardware count
+#define   ADC_SCAN_UP_BIT 0x80	// scan up from channel zero instead of down to zero
+#define COMMAND4_REG	0xf
+#define   INTERVAL_SCAN_EN_BIT	0x1	// enables 'interval' scanning
+#define   EXT_SCAN_EN_BIT	0x2	// enables external signal on counter b1 output to trigger scan
+#define   EXT_CONVERT_OUT_BIT	0x4	// chooses direction (output or input) for EXTCONV* line
+#define   ADC_DIFF_BIT	0x8	// chooses differential inputs for adc (in conjunction with board jumper)
+#define   EXT_CONVERT_DISABLE_BIT	0x10
+#define COMMAND5_REG	0x1c	// 1200 boards only, calibration stuff
+#define   EEPROM_WRITE_UNPROTECT_BIT	0x4	// enable eeprom for write
+#define   DITHER_EN_BIT	0x8	// enable dithering
+#define   CALDAC_LOAD_BIT	0x10	// load calibration dac
+#define   SCLOCK_BIT	0x20	// serial clock - rising edge writes, falling edge reads
+#define   SDATA_BIT	0x40	// serial data bit for writing to eeprom or calibration dacs
+#define   EEPROM_EN_BIT	0x80	// enable eeprom for read/write
+#define INTERVAL_COUNT_REG	0x1e
+#define INTERVAL_LOAD_REG	0x1f
+#define   INTERVAL_LOAD_BITS	0x1
+
+// read-only registers
+#define STATUS1_REG	0x0
+#define   DATA_AVAIL_BIT	0x1	// data is available in fifo
+#define   OVERRUN_BIT	0x2	// overrun has occurred
+#define   OVERFLOW_BIT	0x4	// fifo overflow
+#define   TIMER_BIT	0x8	// timer interrupt has occured
+#define   DMATC_BIT	0x10	// dma terminal count has occured
+#define   EXT_TRIG_BIT	0x40	// external trigger has occured
+#define STATUS2_REG	0x1d	// 1200 boards only
+#define   EEPROM_OUT_BIT	0x1	// programmable eeprom serial output
+#define   A1_TC_BIT	0x2	// counter A1 terminal count
+#define   FNHF_BIT	0x4	// fifo not half full
+#define ADC_FIFO_REG	0xa
+
+#define DIO_BASE_REG	0x10
+#define COUNTER_A_BASE_REG	0x14
+#define COUNTER_A_CONTROL_REG	(COUNTER_A_BASE_REG + 0x3)
+#define   INIT_A0_BITS	0x14	// check modes put conversion pacer output in harmless state (a0 mode 2)
+#define   INIT_A1_BITS	0x70	// put hardware conversion counter output in harmless state (a1 mode 0)
+#define COUNTER_B_BASE_REG	0x18
+
+static int labpc_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int labpc_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static irqreturn_t labpc_interrupt(int irq, void *d PT_REGS_ARG);
+static int labpc_drain_fifo(struct comedi_device * dev);
+static void labpc_drain_dma(struct comedi_device * dev);
+static void handle_isa_dma(struct comedi_device * dev);
+static void labpc_drain_dregs(struct comedi_device * dev);
+static int labpc_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd);
+static int labpc_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int labpc_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int labpc_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int labpc_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int labpc_calib_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int labpc_calib_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int labpc_eeprom_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int labpc_eeprom_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static unsigned int labpc_suggest_transfer_size(struct comedi_cmd cmd);
+static void labpc_adc_timing(struct comedi_device * dev, struct comedi_cmd * cmd);
+#ifdef CONFIG_COMEDI_PCI
+static int labpc_find_device(struct comedi_device *dev, int bus, int slot);
+#endif
+static int labpc_dio_mem_callback(int dir, int port, int data,
+	unsigned long arg);
+static void labpc_serial_out(struct comedi_device * dev, unsigned int value,
+	unsigned int num_bits);
+static unsigned int labpc_serial_in(struct comedi_device * dev);
+static unsigned int labpc_eeprom_read(struct comedi_device * dev,
+	unsigned int address);
+static unsigned int labpc_eeprom_read_status(struct comedi_device * dev);
+static unsigned int labpc_eeprom_write(struct comedi_device * dev,
+	unsigned int address, unsigned int value);
+static void write_caldac(struct comedi_device * dev, unsigned int channel,
+	unsigned int value);
+
+enum scan_mode {
+	MODE_SINGLE_CHAN,
+	MODE_SINGLE_CHAN_INTERVAL,
+	MODE_MULT_CHAN_UP,
+	MODE_MULT_CHAN_DOWN,
+};
+
+//analog input ranges
+#define NUM_LABPC_PLUS_AI_RANGES 16
+// indicates unipolar ranges
+static const int labpc_plus_is_unipolar[NUM_LABPC_PLUS_AI_RANGES] = {
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	1,
+	1,
+	1,
+	1,
+	1,
+	1,
+	1,
+	1,
+};
+
+// map range index to gain bits
+static const int labpc_plus_ai_gain_bits[NUM_LABPC_PLUS_AI_RANGES] = {
+	0x00,
+	0x10,
+	0x20,
+	0x30,
+	0x40,
+	0x50,
+	0x60,
+	0x70,
+	0x00,
+	0x10,
+	0x20,
+	0x30,
+	0x40,
+	0x50,
+	0x60,
+	0x70,
+};
+static const struct comedi_lrange range_labpc_plus_ai = {
+	NUM_LABPC_PLUS_AI_RANGES,
+	{
+			BIP_RANGE(5),
+			BIP_RANGE(4),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1),
+			BIP_RANGE(0.5),
+			BIP_RANGE(0.25),
+			BIP_RANGE(0.1),
+			BIP_RANGE(0.05),
+			UNI_RANGE(10),
+			UNI_RANGE(8),
+			UNI_RANGE(5),
+			UNI_RANGE(2),
+			UNI_RANGE(1),
+			UNI_RANGE(0.5),
+			UNI_RANGE(0.2),
+			UNI_RANGE(0.1),
+		}
+};
+
+#define NUM_LABPC_1200_AI_RANGES 14
+// indicates unipolar ranges
+const int labpc_1200_is_unipolar[NUM_LABPC_1200_AI_RANGES] = {
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	1,
+	1,
+	1,
+	1,
+	1,
+	1,
+	1,
+};
+
+// map range index to gain bits
+const int labpc_1200_ai_gain_bits[NUM_LABPC_1200_AI_RANGES] = {
+	0x00,
+	0x20,
+	0x30,
+	0x40,
+	0x50,
+	0x60,
+	0x70,
+	0x00,
+	0x20,
+	0x30,
+	0x40,
+	0x50,
+	0x60,
+	0x70,
+};
+const struct comedi_lrange range_labpc_1200_ai = {
+	NUM_LABPC_1200_AI_RANGES,
+	{
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1),
+			BIP_RANGE(0.5),
+			BIP_RANGE(0.25),
+			BIP_RANGE(0.1),
+			BIP_RANGE(0.05),
+			UNI_RANGE(10),
+			UNI_RANGE(5),
+			UNI_RANGE(2),
+			UNI_RANGE(1),
+			UNI_RANGE(0.5),
+			UNI_RANGE(0.2),
+			UNI_RANGE(0.1),
+		}
+};
+
+//analog output ranges
+#define AO_RANGE_IS_UNIPOLAR 0x1
+static const struct comedi_lrange range_labpc_ao = {
+	2,
+	{
+			BIP_RANGE(5),
+			UNI_RANGE(10),
+		}
+};
+
+/* functions that do inb/outb and readb/writeb so we can use
+ * function pointers to decide which to use */
+static inline unsigned int labpc_inb(unsigned long address)
+{
+	return inb(address);
+}
+static inline void labpc_outb(unsigned int byte, unsigned long address)
+{
+	outb(byte, address);
+}
+static inline unsigned int labpc_readb(unsigned long address)
+{
+	return readb((void *)address);
+}
+static inline void labpc_writeb(unsigned int byte, unsigned long address)
+{
+	writeb(byte, (void *)address);
+}
+
+static const labpc_board labpc_boards[] = {
+	{
+	      name:	"lab-pc-1200",
+	      ai_speed:10000,
+	      bustype:	isa_bustype,
+	      register_layout:labpc_1200_layout,
+	      has_ao:	1,
+	      ai_range_table:&range_labpc_1200_ai,
+	      ai_range_code:labpc_1200_ai_gain_bits,
+	      ai_range_is_unipolar:labpc_1200_is_unipolar,
+	      ai_scan_up:1,
+	      memory_mapped_io:0,
+		},
+	{
+	      name:	"lab-pc-1200ai",
+	      ai_speed:10000,
+	      bustype:	isa_bustype,
+	      register_layout:labpc_1200_layout,
+	      has_ao:	0,
+	      ai_range_table:&range_labpc_1200_ai,
+	      ai_range_code:labpc_1200_ai_gain_bits,
+	      ai_range_is_unipolar:labpc_1200_is_unipolar,
+	      ai_scan_up:1,
+	      memory_mapped_io:0,
+		},
+	{
+	      name:	"lab-pc+",
+	      ai_speed:12000,
+	      bustype:	isa_bustype,
+	      register_layout:labpc_plus_layout,
+	      has_ao:	1,
+	      ai_range_table:&range_labpc_plus_ai,
+	      ai_range_code:labpc_plus_ai_gain_bits,
+	      ai_range_is_unipolar:labpc_plus_is_unipolar,
+	      ai_scan_up:0,
+	      memory_mapped_io:0,
+		},
+#ifdef CONFIG_COMEDI_PCI
+	{
+		name:	"pci-1200",
+		device_id:0x161,
+		ai_speed:10000,
+		bustype:	pci_bustype,
+		register_layout:labpc_1200_layout,
+		has_ao:	1,
+		ai_range_table:&range_labpc_1200_ai,
+		ai_range_code:labpc_1200_ai_gain_bits,
+		ai_range_is_unipolar:labpc_1200_is_unipolar,
+		ai_scan_up:1,
+		memory_mapped_io:1,
+		},
+	// dummy entry so pci board works when comedi_config is passed driver name
+	{
+		.name = DRV_NAME,
+		.bustype = pci_bustype,
+		},
+#endif
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((labpc_board *)dev->board_ptr)
+
+static const int dma_buffer_size = 0xff00;	// size in bytes of dma buffer
+static const int sample_size = 2;	// 2 bytes per sample
+
+#define devpriv ((labpc_private *)dev->private)
+
+static struct comedi_driver driver_labpc = {
+	.driver_name = DRV_NAME,
+	.module = THIS_MODULE,
+	.attach = labpc_attach,
+	.detach = labpc_common_detach,
+	.num_names = sizeof(labpc_boards) / sizeof(labpc_board),
+	.board_name = &labpc_boards[0].name,
+	.offset = sizeof(labpc_board),
+};
+
+#ifdef CONFIG_COMEDI_PCI
+static DEFINE_PCI_DEVICE_TABLE(labpc_pci_table) = {
+	{PCI_VENDOR_ID_NATINST, 0x161, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, labpc_pci_table);
+#endif /* CONFIG_COMEDI_PCI */
+
+static inline int labpc_counter_load(struct comedi_device * dev,
+	unsigned long base_address, unsigned int counter_number,
+	unsigned int count, unsigned int mode)
+{
+	if (thisboard->memory_mapped_io)
+		return i8254_mm_load((void *)base_address, 0, counter_number,
+			count, mode);
+	else
+		return i8254_load(base_address, 0, counter_number, count, mode);
+}
+
+int labpc_common_attach(struct comedi_device * dev, unsigned long iobase,
+	unsigned int irq, unsigned int dma_chan)
+{
+	struct comedi_subdevice *s;
+	int i;
+	unsigned long dma_flags, isr_flags;
+	short lsb, msb;
+
+	printk("comedi%d: ni_labpc: %s, io 0x%lx", dev->minor, thisboard->name,
+		iobase);
+	if (irq) {
+		printk(", irq %u", irq);
+	}
+	if (dma_chan) {
+		printk(", dma %u", dma_chan);
+	}
+	printk("\n");
+
+	if (iobase == 0) {
+		printk("io base address is zero!\n");
+		return -EINVAL;
+	}
+	// request io regions for isa boards
+	if (thisboard->bustype == isa_bustype) {
+		/* check if io addresses are available */
+		if (!request_region(iobase, LABPC_SIZE,
+				driver_labpc.driver_name)) {
+			printk("I/O port conflict\n");
+			return -EIO;
+		}
+	}
+	dev->iobase = iobase;
+
+	if (thisboard->memory_mapped_io) {
+		devpriv->read_byte = labpc_readb;
+		devpriv->write_byte = labpc_writeb;
+	} else {
+		devpriv->read_byte = labpc_inb;
+		devpriv->write_byte = labpc_outb;
+	}
+	// initialize board's command registers
+	devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG);
+	devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
+	devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
+	devpriv->write_byte(devpriv->command4_bits, dev->iobase + COMMAND4_REG);
+	if (thisboard->register_layout == labpc_1200_layout) {
+		devpriv->write_byte(devpriv->command5_bits,
+			dev->iobase + COMMAND5_REG);
+		devpriv->write_byte(devpriv->command6_bits,
+			dev->iobase + COMMAND6_REG);
+	}
+
+	/* grab our IRQ */
+	if (irq) {
+		isr_flags = 0;
+		if (thisboard->bustype == pci_bustype)
+			isr_flags |= IRQF_SHARED;
+		if (comedi_request_irq(irq, labpc_interrupt, isr_flags,
+				driver_labpc.driver_name, dev)) {
+			printk("unable to allocate irq %u\n", irq);
+			return -EINVAL;
+		}
+	}
+	dev->irq = irq;
+
+	// grab dma channel
+	if (dma_chan > 3) {
+		printk(" invalid dma channel %u\n", dma_chan);
+		return -EINVAL;
+	} else if (dma_chan) {
+		// allocate dma buffer
+		devpriv->dma_buffer =
+			kmalloc(dma_buffer_size, GFP_KERNEL | GFP_DMA);
+		if (devpriv->dma_buffer == NULL) {
+			printk(" failed to allocate dma buffer\n");
+			return -ENOMEM;
+		}
+		if (request_dma(dma_chan, driver_labpc.driver_name)) {
+			printk(" failed to allocate dma channel %u\n",
+				dma_chan);
+			return -EINVAL;
+		}
+		devpriv->dma_chan = dma_chan;
+		dma_flags = claim_dma_lock();
+		disable_dma(devpriv->dma_chan);
+		set_dma_mode(devpriv->dma_chan, DMA_MODE_READ);
+		release_dma_lock(dma_flags);
+	}
+
+	dev->board_name = thisboard->name;
+
+	if (alloc_subdevices(dev, 5) < 0)
+		return -ENOMEM;
+
+	/* analog input subdevice */
+	s = dev->subdevices + 0;
+	dev->read_subdev = s;
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags =
+		SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF |
+		SDF_CMD_READ;
+	s->n_chan = 8;
+	s->len_chanlist = 8;
+	s->maxdata = (1 << 12) - 1;	// 12 bit resolution
+	s->range_table = thisboard->ai_range_table;
+	s->do_cmd = labpc_ai_cmd;
+	s->do_cmdtest = labpc_ai_cmdtest;
+	s->insn_read = labpc_ai_rinsn;
+	s->cancel = labpc_cancel;
+
+	/* analog output */
+	s = dev->subdevices + 1;
+	if (thisboard->has_ao) {
+/* Could provide command support, except it only has a one sample
+ * hardware buffer for analog output and no underrun flag. */
+		s->type = COMEDI_SUBD_AO;
+		s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
+		s->n_chan = NUM_AO_CHAN;
+		s->maxdata = (1 << 12) - 1;	// 12 bit resolution
+		s->range_table = &range_labpc_ao;
+		s->insn_read = labpc_ao_rinsn;
+		s->insn_write = labpc_ao_winsn;
+		/* initialize analog outputs to a known value */
+		for (i = 0; i < s->n_chan; i++) {
+			devpriv->ao_value[i] = s->maxdata / 2;
+			lsb = devpriv->ao_value[i] & 0xff;
+			msb = (devpriv->ao_value[i] >> 8) & 0xff;
+			devpriv->write_byte(lsb, dev->iobase + DAC_LSB_REG(i));
+			devpriv->write_byte(msb, dev->iobase + DAC_MSB_REG(i));
+		}
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	/* 8255 dio */
+	s = dev->subdevices + 2;
+	// if board uses io memory we have to give a custom callback function to the 8255 driver
+	if (thisboard->memory_mapped_io)
+		subdev_8255_init(dev, s, labpc_dio_mem_callback,
+			(unsigned long)(dev->iobase + DIO_BASE_REG));
+	else
+		subdev_8255_init(dev, s, NULL, dev->iobase + DIO_BASE_REG);
+
+	// calibration subdevices for boards that have one
+	s = dev->subdevices + 3;
+	if (thisboard->register_layout == labpc_1200_layout) {
+		s->type = COMEDI_SUBD_CALIB;
+		s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+		s->n_chan = 16;
+		s->maxdata = 0xff;
+		s->insn_read = labpc_calib_read_insn;
+		s->insn_write = labpc_calib_write_insn;
+
+		for (i = 0; i < s->n_chan; i++)
+			write_caldac(dev, i, s->maxdata / 2);
+	} else
+		s->type = COMEDI_SUBD_UNUSED;
+
+	/* EEPROM */
+	s = dev->subdevices + 4;
+	if (thisboard->register_layout == labpc_1200_layout) {
+		s->type = COMEDI_SUBD_MEMORY;
+		s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+		s->n_chan = EEPROM_SIZE;
+		s->maxdata = 0xff;
+		s->insn_read = labpc_eeprom_read_insn;
+		s->insn_write = labpc_eeprom_write_insn;
+
+		for (i = 0; i < EEPROM_SIZE; i++) {
+			devpriv->eeprom_data[i] = labpc_eeprom_read(dev, i);
+		}
+#ifdef LABPC_DEBUG
+		printk(" eeprom:");
+		for (i = 0; i < EEPROM_SIZE; i++) {
+			printk(" %i:0x%x ", i, devpriv->eeprom_data[i]);
+		}
+		printk("\n");
+#endif
+	} else
+		s->type = COMEDI_SUBD_UNUSED;
+
+	return 0;
+}
+
+static int labpc_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	unsigned long iobase = 0;
+	unsigned int irq = 0;
+	unsigned int dma_chan = 0;
+#ifdef CONFIG_COMEDI_PCI
+	int retval;
+#endif
+
+	/* allocate and initialize dev->private */
+	if (alloc_private(dev, sizeof(labpc_private)) < 0)
+		return -ENOMEM;
+
+	// get base address, irq etc. based on bustype
+	switch (thisboard->bustype) {
+	case isa_bustype:
+		iobase = it->options[0];
+		irq = it->options[1];
+		dma_chan = it->options[2];
+		break;
+	case pci_bustype:
+#ifdef CONFIG_COMEDI_PCI
+		retval = labpc_find_device(dev, it->options[0], it->options[1]);
+		if (retval < 0) {
+			return retval;
+		}
+		retval = mite_setup(devpriv->mite);
+		if (retval < 0)
+			return retval;
+		iobase = (unsigned long)devpriv->mite->daq_io_addr;
+		irq = mite_irq(devpriv->mite);
+#else
+		printk(" this driver has not been built with PCI support.\n");
+		return -EINVAL;
+#endif
+		break;
+	case pcmcia_bustype:
+		printk(" this driver does not support pcmcia cards, use ni_labpc_cs.o\n");
+		return -EINVAL;
+		break;
+	default:
+		printk("bug! couldn't determine board type\n");
+		return -EINVAL;
+		break;
+	}
+
+	return labpc_common_attach(dev, iobase, irq, dma_chan);
+}
+
+// adapted from ni_pcimio for finding mite based boards (pc-1200)
+#ifdef CONFIG_COMEDI_PCI
+static int labpc_find_device(struct comedi_device *dev, int bus, int slot)
+{
+	struct mite_struct *mite;
+	int i;
+	for (mite = mite_devices; mite; mite = mite->next) {
+		if (mite->used)
+			continue;
+		// if bus/slot are specified then make sure we have the right bus/slot
+		if (bus || slot) {
+			if (bus != mite->pcidev->bus->number
+				|| slot != PCI_SLOT(mite->pcidev->devfn))
+				continue;
+		}
+		for (i = 0; i < driver_labpc.num_names; i++) {
+			if (labpc_boards[i].bustype != pci_bustype)
+				continue;
+			if (mite_device_id(mite) == labpc_boards[i].device_id) {
+				devpriv->mite = mite;
+				// fixup board pointer, in case we were using the dummy "ni_labpc" entry
+				dev->board_ptr = &labpc_boards[i];
+				return 0;
+			}
+		}
+	}
+	printk("no device found\n");
+	mite_list_devices();
+	return -EIO;
+}
+#endif
+
+int labpc_common_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: ni_labpc: detach\n", dev->minor);
+
+	if (dev->subdevices)
+		subdev_8255_cleanup(dev, dev->subdevices + 2);
+
+	/* only free stuff if it has been allocated by _attach */
+	if (devpriv->dma_buffer)
+		kfree(devpriv->dma_buffer);
+	if (devpriv->dma_chan)
+		free_dma(devpriv->dma_chan);
+	if (dev->irq)
+		comedi_free_irq(dev->irq, dev);
+	if (thisboard->bustype == isa_bustype && dev->iobase)
+		release_region(dev->iobase, LABPC_SIZE);
+#ifdef CONFIG_COMEDI_PCI
+	if (devpriv->mite)
+		mite_unsetup(devpriv->mite);
+#endif
+
+	return 0;
+};
+
+static void labpc_clear_adc_fifo(const struct comedi_device * dev)
+{
+	devpriv->write_byte(0x1, dev->iobase + ADC_CLEAR_REG);
+	devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
+	devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
+}
+
+static int labpc_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	devpriv->command2_bits &= ~SWTRIG_BIT & ~HWTRIG_BIT & ~PRETRIG_BIT;
+	devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	devpriv->command3_bits = 0;
+	devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
+
+	return 0;
+}
+
+static enum scan_mode labpc_ai_scan_mode(const struct comedi_cmd * cmd)
+{
+	if (cmd->chanlist_len == 1)
+		return MODE_SINGLE_CHAN;
+
+	/* chanlist may be NULL during cmdtest. */
+	if (cmd->chanlist == NULL)
+		return MODE_MULT_CHAN_UP;
+
+	if (CR_CHAN(cmd->chanlist[0]) == CR_CHAN(cmd->chanlist[1]))
+		return MODE_SINGLE_CHAN_INTERVAL;
+
+	if (CR_CHAN(cmd->chanlist[0]) < CR_CHAN(cmd->chanlist[1]))
+		return MODE_MULT_CHAN_UP;
+
+	if (CR_CHAN(cmd->chanlist[0]) > CR_CHAN(cmd->chanlist[1]))
+		return MODE_MULT_CHAN_DOWN;
+
+	rt_printk("ni_labpc: bug! this should never happen\n");
+
+	return 0;
+}
+
+static int labpc_ai_chanlist_invalid(const struct comedi_device * dev,
+	const struct comedi_cmd * cmd)
+{
+	int mode, channel, range, aref, i;
+
+	if (cmd->chanlist == NULL)
+		return 0;
+
+	mode = labpc_ai_scan_mode(cmd);
+
+	if (mode == MODE_SINGLE_CHAN)
+		return 0;
+
+	if (mode == MODE_SINGLE_CHAN_INTERVAL) {
+		if (cmd->chanlist_len > 0xff) {
+			comedi_error(dev,
+				"ni_labpc: chanlist too long for single channel interval mode\n");
+			return 1;
+		}
+	}
+
+	channel = CR_CHAN(cmd->chanlist[0]);
+	range = CR_RANGE(cmd->chanlist[0]);
+	aref = CR_AREF(cmd->chanlist[0]);
+
+	for (i = 0; i < cmd->chanlist_len; i++) {
+
+		switch (mode) {
+		case MODE_SINGLE_CHAN_INTERVAL:
+			if (CR_CHAN(cmd->chanlist[i]) != channel) {
+				comedi_error(dev,
+					"channel scanning order specified in chanlist is not supported by hardware.\n");
+				return 1;
+			}
+			break;
+		case MODE_MULT_CHAN_UP:
+			if (CR_CHAN(cmd->chanlist[i]) != i) {
+				comedi_error(dev,
+					"channel scanning order specified in chanlist is not supported by hardware.\n");
+				return 1;
+			}
+			break;
+		case MODE_MULT_CHAN_DOWN:
+			if (CR_CHAN(cmd->chanlist[i]) !=
+				cmd->chanlist_len - i - 1) {
+				comedi_error(dev,
+					"channel scanning order specified in chanlist is not supported by hardware.\n");
+				return 1;
+			}
+			break;
+		default:
+			rt_printk("ni_labpc: bug! in chanlist check\n");
+			return 1;
+			break;
+		}
+
+		if (CR_RANGE(cmd->chanlist[i]) != range) {
+			comedi_error(dev,
+				"entries in chanlist must all have the same range\n");
+			return 1;
+		}
+
+		if (CR_AREF(cmd->chanlist[i]) != aref) {
+			comedi_error(dev,
+				"entries in chanlist must all have the same reference\n");
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+static int labpc_use_continuous_mode(const struct comedi_cmd * cmd)
+{
+	if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN)
+		return 1;
+
+	if (cmd->scan_begin_src == TRIG_FOLLOW)
+		return 1;
+
+	return 0;
+}
+
+static unsigned int labpc_ai_convert_period(const struct comedi_cmd * cmd)
+{
+	if (cmd->convert_src != TRIG_TIMER)
+		return 0;
+
+	if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN &&
+		cmd->scan_begin_src == TRIG_TIMER)
+		return cmd->scan_begin_arg;
+
+	return cmd->convert_arg;
+}
+
+static void labpc_set_ai_convert_period(struct comedi_cmd * cmd, unsigned int ns)
+{
+	if (cmd->convert_src != TRIG_TIMER)
+		return;
+
+	if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN &&
+		cmd->scan_begin_src == TRIG_TIMER) {
+		cmd->scan_begin_arg = ns;
+		if (cmd->convert_arg > cmd->scan_begin_arg)
+			cmd->convert_arg = cmd->scan_begin_arg;
+	} else
+		cmd->convert_arg = ns;
+}
+
+static unsigned int labpc_ai_scan_period(const struct comedi_cmd * cmd)
+{
+	if (cmd->scan_begin_src != TRIG_TIMER)
+		return 0;
+
+	if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN &&
+		cmd->convert_src == TRIG_TIMER)
+		return 0;
+
+	return cmd->scan_begin_arg;
+}
+
+static void labpc_set_ai_scan_period(struct comedi_cmd * cmd, unsigned int ns)
+{
+	if (cmd->scan_begin_src != TRIG_TIMER)
+		return;
+
+	if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN &&
+		cmd->convert_src == TRIG_TIMER)
+		return;
+
+	cmd->scan_begin_arg = ns;
+}
+
+static int labpc_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp, tmp2;
+	int stop_mask;
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW | TRIG_EXT;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	stop_mask = TRIG_COUNT | TRIG_NONE;
+	if (thisboard->register_layout == labpc_1200_layout)
+		stop_mask |= TRIG_EXT;
+	cmd->stop_src &= stop_mask;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
+		err++;
+	if (cmd->scan_begin_src != TRIG_TIMER &&
+		cmd->scan_begin_src != TRIG_FOLLOW &&
+		cmd->scan_begin_src != TRIG_EXT)
+		err++;
+	if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+		err++;
+	if (cmd->stop_src != TRIG_COUNT &&
+		cmd->stop_src != TRIG_EXT && cmd->stop_src != TRIG_NONE)
+		err++;
+
+	// can't have external stop and start triggers at once
+	if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->start_arg == TRIG_NOW && cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+
+	if (!cmd->chanlist_len) {
+		err++;
+	}
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+
+	if (cmd->convert_src == TRIG_TIMER) {
+		if (cmd->convert_arg < thisboard->ai_speed) {
+			cmd->convert_arg = thisboard->ai_speed;
+			err++;
+		}
+	}
+	// make sure scan timing is not too fast
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		if (cmd->convert_src == TRIG_TIMER &&
+			cmd->scan_begin_arg <
+			cmd->convert_arg * cmd->chanlist_len) {
+			cmd->scan_begin_arg =
+				cmd->convert_arg * cmd->chanlist_len;
+			err++;
+		}
+		if (cmd->scan_begin_arg <
+			thisboard->ai_speed * cmd->chanlist_len) {
+			cmd->scan_begin_arg =
+				thisboard->ai_speed * cmd->chanlist_len;
+			err++;
+		}
+	}
+	// stop source
+	switch (cmd->stop_src) {
+	case TRIG_COUNT:
+		if (!cmd->stop_arg) {
+			cmd->stop_arg = 1;
+			err++;
+		}
+		break;
+	case TRIG_NONE:
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+		break;
+		// TRIG_EXT doesn't care since it doesn't trigger off a numbered channel
+	default:
+		break;
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	tmp = cmd->convert_arg;
+	tmp2 = cmd->scan_begin_arg;
+	labpc_adc_timing(dev, cmd);
+	if (tmp != cmd->convert_arg || tmp2 != cmd->scan_begin_arg)
+		err++;
+
+	if (err)
+		return 4;
+
+	if (labpc_ai_chanlist_invalid(dev, cmd))
+		return 5;
+
+	return 0;
+}
+
+static int labpc_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	int channel, range, aref;
+	unsigned long irq_flags;
+	int ret;
+	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+	enum transfer_type xfer;
+	unsigned long flags;
+
+	if (!dev->irq) {
+		comedi_error(dev, "no irq assigned, cannot perform command");
+		return -1;
+	}
+
+	range = CR_RANGE(cmd->chanlist[0]);
+	aref = CR_AREF(cmd->chanlist[0]);
+
+	// make sure board is disabled before setting up aquisition
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	devpriv->command2_bits &= ~SWTRIG_BIT & ~HWTRIG_BIT & ~PRETRIG_BIT;
+	devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	devpriv->command3_bits = 0;
+	devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
+
+	// initialize software conversion count
+	if (cmd->stop_src == TRIG_COUNT) {
+		devpriv->count = cmd->stop_arg * cmd->chanlist_len;
+	}
+	// setup hardware conversion counter
+	if (cmd->stop_src == TRIG_EXT) {
+		// load counter a1 with count of 3 (pc+ manual says this is minimum allowed) using mode 0
+		ret = labpc_counter_load(dev, dev->iobase + COUNTER_A_BASE_REG,
+			1, 3, 0);
+		if (ret < 0) {
+			comedi_error(dev, "error loading counter a1");
+			return -1;
+		}
+	} else			// otherwise, just put a1 in mode 0 with no count to set its output low
+		devpriv->write_byte(INIT_A1_BITS,
+			dev->iobase + COUNTER_A_CONTROL_REG);
+
+	// figure out what method we will use to transfer data
+	if (devpriv->dma_chan &&	// need a dma channel allocated
+		// dma unsafe at RT priority, and too much setup time for TRIG_WAKE_EOS for
+		(cmd->flags & (TRIG_WAKE_EOS | TRIG_RT)) == 0 &&
+		// only available on the isa boards
+		thisboard->bustype == isa_bustype) {
+		xfer = isa_dma_transfer;
+	} else if (thisboard->register_layout == labpc_1200_layout &&	// pc-plus has no fifo-half full interrupt
+		// wake-end-of-scan should interrupt on fifo not empty
+		(cmd->flags & TRIG_WAKE_EOS) == 0 &&
+		// make sure we are taking more than just a few points
+		(cmd->stop_src != TRIG_COUNT || devpriv->count > 256)) {
+		xfer = fifo_half_full_transfer;
+	} else
+		xfer = fifo_not_empty_transfer;
+	devpriv->current_transfer = xfer;
+
+	// setup command6 register for 1200 boards
+	if (thisboard->register_layout == labpc_1200_layout) {
+		// reference inputs to ground or common?
+		if (aref != AREF_GROUND)
+			devpriv->command6_bits |= ADC_COMMON_BIT;
+		else
+			devpriv->command6_bits &= ~ADC_COMMON_BIT;
+		// bipolar or unipolar range?
+		if (thisboard->ai_range_is_unipolar[range])
+			devpriv->command6_bits |= ADC_UNIP_BIT;
+		else
+			devpriv->command6_bits &= ~ADC_UNIP_BIT;
+		// interrupt on fifo half full?
+		if (xfer == fifo_half_full_transfer)
+			devpriv->command6_bits |= ADC_FHF_INTR_EN_BIT;
+		else
+			devpriv->command6_bits &= ~ADC_FHF_INTR_EN_BIT;
+		// enable interrupt on counter a1 terminal count?
+		if (cmd->stop_src == TRIG_EXT)
+			devpriv->command6_bits |= A1_INTR_EN_BIT;
+		else
+			devpriv->command6_bits &= ~A1_INTR_EN_BIT;
+		// are we scanning up or down through channels?
+		if (labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_UP)
+			devpriv->command6_bits |= ADC_SCAN_UP_BIT;
+		else
+			devpriv->command6_bits &= ~ADC_SCAN_UP_BIT;
+		// write to register
+		devpriv->write_byte(devpriv->command6_bits,
+			dev->iobase + COMMAND6_REG);
+	}
+
+	/* setup channel list, etc (command1 register) */
+	devpriv->command1_bits = 0;
+	if (labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_UP)
+		channel = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]);
+	else
+		channel = CR_CHAN(cmd->chanlist[0]);
+	// munge channel bits for differential / scan disabled mode
+	if (labpc_ai_scan_mode(cmd) != MODE_SINGLE_CHAN && aref == AREF_DIFF)
+		channel *= 2;
+	devpriv->command1_bits |= ADC_CHAN_BITS(channel);
+	devpriv->command1_bits |= thisboard->ai_range_code[range];
+	devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG);
+	// manual says to set scan enable bit on second pass
+	if (labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_UP ||
+		labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_DOWN) {
+		devpriv->command1_bits |= ADC_SCAN_EN_BIT;
+		/* need a brief delay before enabling scan, or scan list will get screwed when you switch
+		 * between scan up to scan down mode - dunno why */
+		comedi_udelay(1);
+		devpriv->write_byte(devpriv->command1_bits,
+			dev->iobase + COMMAND1_REG);
+	}
+	// setup any external triggering/pacing (command4 register)
+	devpriv->command4_bits = 0;
+	if (cmd->convert_src != TRIG_EXT)
+		devpriv->command4_bits |= EXT_CONVERT_DISABLE_BIT;
+	/* XXX should discard first scan when using interval scanning
+	 * since manual says it is not synced with scan clock */
+	if (labpc_use_continuous_mode(cmd) == 0) {
+		devpriv->command4_bits |= INTERVAL_SCAN_EN_BIT;
+		if (cmd->scan_begin_src == TRIG_EXT)
+			devpriv->command4_bits |= EXT_SCAN_EN_BIT;
+	}
+	// single-ended/differential
+	if (aref == AREF_DIFF)
+		devpriv->command4_bits |= ADC_DIFF_BIT;
+	devpriv->write_byte(devpriv->command4_bits, dev->iobase + COMMAND4_REG);
+
+	devpriv->write_byte(cmd->chanlist_len,
+		dev->iobase + INTERVAL_COUNT_REG);
+	// load count
+	devpriv->write_byte(INTERVAL_LOAD_BITS,
+		dev->iobase + INTERVAL_LOAD_REG);
+
+	if (cmd->convert_src == TRIG_TIMER || cmd->scan_begin_src == TRIG_TIMER) {
+		// set up pacing
+		labpc_adc_timing(dev, cmd);
+		// load counter b0 in mode 3
+		ret = labpc_counter_load(dev, dev->iobase + COUNTER_B_BASE_REG,
+			0, devpriv->divisor_b0, 3);
+		if (ret < 0) {
+			comedi_error(dev, "error loading counter b0");
+			return -1;
+		}
+	}
+	// set up conversion pacing
+	if (labpc_ai_convert_period(cmd)) {
+		// load counter a0 in mode 2
+		ret = labpc_counter_load(dev, dev->iobase + COUNTER_A_BASE_REG,
+			0, devpriv->divisor_a0, 2);
+		if (ret < 0) {
+			comedi_error(dev, "error loading counter a0");
+			return -1;
+		}
+	} else
+		devpriv->write_byte(INIT_A0_BITS,
+			dev->iobase + COUNTER_A_CONTROL_REG);
+
+	// set up scan pacing
+	if (labpc_ai_scan_period(cmd)) {
+		// load counter b1 in mode 2
+		ret = labpc_counter_load(dev, dev->iobase + COUNTER_B_BASE_REG,
+			1, devpriv->divisor_b1, 2);
+		if (ret < 0) {
+			comedi_error(dev, "error loading counter b1");
+			return -1;
+		}
+	}
+
+	labpc_clear_adc_fifo(dev);
+
+	// set up dma transfer
+	if (xfer == isa_dma_transfer) {
+		irq_flags = claim_dma_lock();
+		disable_dma(devpriv->dma_chan);
+		/* clear flip-flop to make sure 2-byte registers for
+		 * count and address get set correctly */
+		clear_dma_ff(devpriv->dma_chan);
+		set_dma_addr(devpriv->dma_chan,
+			virt_to_bus(devpriv->dma_buffer));
+		// set appropriate size of transfer
+		devpriv->dma_transfer_size = labpc_suggest_transfer_size(*cmd);
+		if (cmd->stop_src == TRIG_COUNT &&
+			devpriv->count * sample_size <
+			devpriv->dma_transfer_size) {
+			devpriv->dma_transfer_size =
+				devpriv->count * sample_size;
+		}
+		set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
+		enable_dma(devpriv->dma_chan);
+		release_dma_lock(irq_flags);
+		// enable board's dma
+		devpriv->command3_bits |= DMA_EN_BIT | DMATC_INTR_EN_BIT;
+	} else
+		devpriv->command3_bits &= ~DMA_EN_BIT & ~DMATC_INTR_EN_BIT;
+
+	// enable error interrupts
+	devpriv->command3_bits |= ERR_INTR_EN_BIT;
+	// enable fifo not empty interrupt?
+	if (xfer == fifo_not_empty_transfer)
+		devpriv->command3_bits |= ADC_FNE_INTR_EN_BIT;
+	else
+		devpriv->command3_bits &= ~ADC_FNE_INTR_EN_BIT;
+	devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
+
+	// startup aquisition
+
+	// command2 reg
+	// use 2 cascaded counters for pacing
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	devpriv->command2_bits |= CASCADE_BIT;
+	switch (cmd->start_src) {
+	case TRIG_EXT:
+		devpriv->command2_bits |= HWTRIG_BIT;
+		devpriv->command2_bits &= ~PRETRIG_BIT & ~SWTRIG_BIT;
+		break;
+	case TRIG_NOW:
+		devpriv->command2_bits |= SWTRIG_BIT;
+		devpriv->command2_bits &= ~PRETRIG_BIT & ~HWTRIG_BIT;
+		break;
+	default:
+		comedi_error(dev, "bug with start_src");
+		return -1;
+		break;
+	}
+	switch (cmd->stop_src) {
+	case TRIG_EXT:
+		devpriv->command2_bits |= HWTRIG_BIT | PRETRIG_BIT;
+		break;
+	case TRIG_COUNT:
+	case TRIG_NONE:
+		break;
+	default:
+		comedi_error(dev, "bug with stop_src");
+		return -1;
+	}
+	devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	return 0;
+}
+
+/* interrupt service routine */
+static irqreturn_t labpc_interrupt(int irq, void *d PT_REGS_ARG)
+{
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s = dev->read_subdev;
+	struct comedi_async *async;
+	struct comedi_cmd *cmd;
+
+	if (dev->attached == 0) {
+		comedi_error(dev, "premature interrupt");
+		return IRQ_HANDLED;
+	}
+
+	async = s->async;
+	cmd = &async->cmd;
+	async->events = 0;
+
+	// read board status
+	devpriv->status1_bits = devpriv->read_byte(dev->iobase + STATUS1_REG);
+	if (thisboard->register_layout == labpc_1200_layout)
+		devpriv->status2_bits =
+			devpriv->read_byte(dev->iobase + STATUS2_REG);
+
+	if ((devpriv->status1_bits & (DMATC_BIT | TIMER_BIT | OVERFLOW_BIT |
+				OVERRUN_BIT | DATA_AVAIL_BIT)) == 0
+		&& (devpriv->status2_bits & A1_TC_BIT) == 0
+		&& (devpriv->status2_bits & FNHF_BIT)) {
+		return IRQ_NONE;
+	}
+
+	if (devpriv->status1_bits & OVERRUN_BIT) {
+		// clear error interrupt
+		devpriv->write_byte(0x1, dev->iobase + ADC_CLEAR_REG);
+		async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+		comedi_event(dev, s);
+		comedi_error(dev, "overrun");
+		return IRQ_HANDLED;
+	}
+
+	if (devpriv->current_transfer == isa_dma_transfer) {
+		// if a dma terminal count of external stop trigger has occurred
+		if (devpriv->status1_bits & DMATC_BIT ||
+			(thisboard->register_layout == labpc_1200_layout
+				&& devpriv->status2_bits & A1_TC_BIT)) {
+			handle_isa_dma(dev);
+		}
+	} else
+		labpc_drain_fifo(dev);
+
+	if (devpriv->status1_bits & TIMER_BIT) {
+		comedi_error(dev, "handled timer interrupt?");
+		// clear it
+		devpriv->write_byte(0x1, dev->iobase + TIMER_CLEAR_REG);
+	}
+
+	if (devpriv->status1_bits & OVERFLOW_BIT) {
+		// clear error interrupt
+		devpriv->write_byte(0x1, dev->iobase + ADC_CLEAR_REG);
+		async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+		comedi_event(dev, s);
+		comedi_error(dev, "overflow");
+		return IRQ_HANDLED;
+	}
+	// handle external stop trigger
+	if (cmd->stop_src == TRIG_EXT) {
+		if (devpriv->status2_bits & A1_TC_BIT) {
+			labpc_drain_dregs(dev);
+			labpc_cancel(dev, s);
+			async->events |= COMEDI_CB_EOA;
+		}
+	}
+
+	/* TRIG_COUNT end of acquisition */
+	if (cmd->stop_src == TRIG_COUNT) {
+		if (devpriv->count == 0) {
+			labpc_cancel(dev, s);
+			async->events |= COMEDI_CB_EOA;
+		}
+	}
+
+	comedi_event(dev, s);
+	return IRQ_HANDLED;
+}
+
+// read all available samples from ai fifo
+static int labpc_drain_fifo(struct comedi_device * dev)
+{
+	unsigned int lsb, msb;
+	short data;
+	struct comedi_async *async = dev->read_subdev->async;
+	const int timeout = 10000;
+	unsigned int i;
+
+	devpriv->status1_bits = devpriv->read_byte(dev->iobase + STATUS1_REG);
+
+	for (i = 0; (devpriv->status1_bits & DATA_AVAIL_BIT) && i < timeout;
+		i++) {
+		// quit if we have all the data we want
+		if (async->cmd.stop_src == TRIG_COUNT) {
+			if (devpriv->count == 0)
+				break;
+			devpriv->count--;
+		}
+		lsb = devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
+		msb = devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
+		data = (msb << 8) | lsb;
+		cfc_write_to_buffer(dev->read_subdev, data);
+		devpriv->status1_bits =
+			devpriv->read_byte(dev->iobase + STATUS1_REG);
+	}
+	if (i == timeout) {
+		comedi_error(dev, "ai timeout, fifo never empties");
+		async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+		return -1;
+	}
+
+	return 0;
+}
+
+static void labpc_drain_dma(struct comedi_device * dev)
+{
+	struct comedi_subdevice *s = dev->read_subdev;
+	struct comedi_async *async = s->async;
+	int status;
+	unsigned long flags;
+	unsigned int max_points, num_points, residue, leftover;
+	int i;
+
+	status = devpriv->status1_bits;
+
+	flags = claim_dma_lock();
+	disable_dma(devpriv->dma_chan);
+	/* clear flip-flop to make sure 2-byte registers for
+	 * count and address get set correctly */
+	clear_dma_ff(devpriv->dma_chan);
+
+	// figure out how many points to read
+	max_points = devpriv->dma_transfer_size / sample_size;
+	/* residue is the number of points left to be done on the dma
+	 * transfer.  It should always be zero at this point unless
+	 * the stop_src is set to external triggering.
+	 */
+	residue = get_dma_residue(devpriv->dma_chan) / sample_size;
+	num_points = max_points - residue;
+	if (devpriv->count < num_points && async->cmd.stop_src == TRIG_COUNT)
+		num_points = devpriv->count;
+
+	// figure out how many points will be stored next time
+	leftover = 0;
+	if (async->cmd.stop_src != TRIG_COUNT) {
+		leftover = devpriv->dma_transfer_size / sample_size;
+	} else if (devpriv->count > num_points) {
+		leftover = devpriv->count - num_points;
+		if (leftover > max_points)
+			leftover = max_points;
+	}
+
+	/* write data to comedi buffer */
+	for (i = 0; i < num_points; i++) {
+		cfc_write_to_buffer(s, devpriv->dma_buffer[i]);
+	}
+	if (async->cmd.stop_src == TRIG_COUNT)
+		devpriv->count -= num_points;
+
+	// set address and count for next transfer
+	set_dma_addr(devpriv->dma_chan, virt_to_bus(devpriv->dma_buffer));
+	set_dma_count(devpriv->dma_chan, leftover * sample_size);
+	release_dma_lock(flags);
+
+	async->events |= COMEDI_CB_BLOCK;
+}
+
+static void handle_isa_dma(struct comedi_device * dev)
+{
+	labpc_drain_dma(dev);
+
+	enable_dma(devpriv->dma_chan);
+
+	// clear dma tc interrupt
+	devpriv->write_byte(0x1, dev->iobase + DMATC_CLEAR_REG);
+}
+
+/* makes sure all data aquired by board is transfered to comedi (used
+ * when aquisition is terminated by stop_src == TRIG_EXT). */
+static void labpc_drain_dregs(struct comedi_device * dev)
+{
+	if (devpriv->current_transfer == isa_dma_transfer)
+		labpc_drain_dma(dev);
+
+	labpc_drain_fifo(dev);
+}
+
+static int labpc_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i, n;
+	int chan, range;
+	int lsb, msb;
+	int timeout = 1000;
+	unsigned long flags;
+
+	// disable timed conversions
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	devpriv->command2_bits &= ~SWTRIG_BIT & ~HWTRIG_BIT & ~PRETRIG_BIT;
+	devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	// disable interrupt generation and dma
+	devpriv->command3_bits = 0;
+	devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
+
+	/* set gain and channel */
+	devpriv->command1_bits = 0;
+	chan = CR_CHAN(insn->chanspec);
+	range = CR_RANGE(insn->chanspec);
+	devpriv->command1_bits |= thisboard->ai_range_code[range];
+	// munge channel bits for differential/scan disabled mode
+	if (CR_AREF(insn->chanspec) == AREF_DIFF)
+		chan *= 2;
+	devpriv->command1_bits |= ADC_CHAN_BITS(chan);
+	devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG);
+
+	// setup command6 register for 1200 boards
+	if (thisboard->register_layout == labpc_1200_layout) {
+		// reference inputs to ground or common?
+		if (CR_AREF(insn->chanspec) != AREF_GROUND)
+			devpriv->command6_bits |= ADC_COMMON_BIT;
+		else
+			devpriv->command6_bits &= ~ADC_COMMON_BIT;
+		// bipolar or unipolar range?
+		if (thisboard->ai_range_is_unipolar[range])
+			devpriv->command6_bits |= ADC_UNIP_BIT;
+		else
+			devpriv->command6_bits &= ~ADC_UNIP_BIT;
+		// don't interrupt on fifo half full
+		devpriv->command6_bits &= ~ADC_FHF_INTR_EN_BIT;
+		// don't enable interrupt on counter a1 terminal count?
+		devpriv->command6_bits &= ~A1_INTR_EN_BIT;
+		// write to register
+		devpriv->write_byte(devpriv->command6_bits,
+			dev->iobase + COMMAND6_REG);
+	}
+	// setup command4 register
+	devpriv->command4_bits = 0;
+	devpriv->command4_bits |= EXT_CONVERT_DISABLE_BIT;
+	// single-ended/differential
+	if (CR_AREF(insn->chanspec) == AREF_DIFF)
+		devpriv->command4_bits |= ADC_DIFF_BIT;
+	devpriv->write_byte(devpriv->command4_bits, dev->iobase + COMMAND4_REG);
+
+	// initialize pacer counter output to make sure it doesn't cause any problems
+	devpriv->write_byte(INIT_A0_BITS, dev->iobase + COUNTER_A_CONTROL_REG);
+
+	labpc_clear_adc_fifo(dev);
+
+	for (n = 0; n < insn->n; n++) {
+		/* trigger conversion */
+		devpriv->write_byte(0x1, dev->iobase + ADC_CONVERT_REG);
+
+		for (i = 0; i < timeout; i++) {
+			if (devpriv->read_byte(dev->iobase +
+					STATUS1_REG) & DATA_AVAIL_BIT)
+				break;
+			comedi_udelay(1);
+		}
+		if (i == timeout) {
+			comedi_error(dev, "timeout");
+			return -ETIME;
+		}
+		lsb = devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
+		msb = devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
+		data[n] = (msb << 8) | lsb;
+	}
+
+	return n;
+}
+
+// analog output insn
+static int labpc_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int channel, range;
+	unsigned long flags;
+	int lsb, msb;
+
+	channel = CR_CHAN(insn->chanspec);
+
+	// turn off pacing of analog output channel
+	/* note: hardware bug in daqcard-1200 means pacing cannot
+	 * be independently enabled/disabled for its the two channels */
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	devpriv->command2_bits &= ~DAC_PACED_BIT(channel);
+	devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	// set range
+	if (thisboard->register_layout == labpc_1200_layout) {
+		range = CR_RANGE(insn->chanspec);
+		if (range & AO_RANGE_IS_UNIPOLAR)
+			devpriv->command6_bits |= DAC_UNIP_BIT(channel);
+		else
+			devpriv->command6_bits &= ~DAC_UNIP_BIT(channel);
+		// write to register
+		devpriv->write_byte(devpriv->command6_bits,
+			dev->iobase + COMMAND6_REG);
+	}
+	// send data
+	lsb = data[0] & 0xff;
+	msb = (data[0] >> 8) & 0xff;
+	devpriv->write_byte(lsb, dev->iobase + DAC_LSB_REG(channel));
+	devpriv->write_byte(msb, dev->iobase + DAC_MSB_REG(channel));
+
+	// remember value for readback
+	devpriv->ao_value[channel] = data[0];
+
+	return 1;
+}
+
+// analog output readback insn
+static int labpc_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)];
+
+	return 1;
+}
+
+static int labpc_calib_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	data[0] = devpriv->caldac[CR_CHAN(insn->chanspec)];
+
+	return 1;
+}
+
+static int labpc_calib_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int channel = CR_CHAN(insn->chanspec);
+
+	write_caldac(dev, channel, data[0]);
+	return 1;
+}
+
+static int labpc_eeprom_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	data[0] = devpriv->eeprom_data[CR_CHAN(insn->chanspec)];
+
+	return 1;
+}
+
+static int labpc_eeprom_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int channel = CR_CHAN(insn->chanspec);
+	int ret;
+
+	// only allow writes to user area of eeprom
+	if (channel < 16 || channel > 127) {
+		printk("eeprom writes are only allowed to channels 16 through 127 (the pointer and user areas)");
+		return -EINVAL;
+	}
+
+	ret = labpc_eeprom_write(dev, channel, data[0]);
+	if (ret < 0)
+		return ret;
+
+	return 1;
+}
+
+// utility function that suggests a dma transfer size in bytes
+static unsigned int labpc_suggest_transfer_size(struct comedi_cmd cmd)
+{
+	unsigned int size;
+	unsigned int freq;
+
+	if (cmd.convert_src == TRIG_TIMER)
+		freq = 1000000000 / cmd.convert_arg;
+	// return some default value
+	else
+		freq = 0xffffffff;
+
+	// make buffer fill in no more than 1/3 second
+	size = (freq / 3) * sample_size;
+
+	// set a minimum and maximum size allowed
+	if (size > dma_buffer_size)
+		size = dma_buffer_size - dma_buffer_size % sample_size;
+	else if (size < sample_size)
+		size = sample_size;
+
+	return size;
+}
+
+// figures out what counter values to use based on command
+static void labpc_adc_timing(struct comedi_device * dev, struct comedi_cmd * cmd)
+{
+	const int max_counter_value = 0x10000;	// max value for 16 bit counter in mode 2
+	const int min_counter_value = 2;	// min value for 16 bit counter in mode 2
+	unsigned int base_period;
+
+	// if both convert and scan triggers are TRIG_TIMER, then they both rely on counter b0
+	if (labpc_ai_convert_period(cmd) && labpc_ai_scan_period(cmd)) {
+		// pick the lowest b0 divisor value we can (for maximum input clock speed on convert and scan counters)
+		devpriv->divisor_b0 = (labpc_ai_scan_period(cmd) - 1) /
+			(LABPC_TIMER_BASE * max_counter_value) + 1;
+		if (devpriv->divisor_b0 < min_counter_value)
+			devpriv->divisor_b0 = min_counter_value;
+		if (devpriv->divisor_b0 > max_counter_value)
+			devpriv->divisor_b0 = max_counter_value;
+
+		base_period = LABPC_TIMER_BASE * devpriv->divisor_b0;
+
+		// set a0 for conversion frequency and b1 for scan frequency
+		switch (cmd->flags & TRIG_ROUND_MASK) {
+		default:
+		case TRIG_ROUND_NEAREST:
+			devpriv->divisor_a0 =
+				(labpc_ai_convert_period(cmd) +
+				(base_period / 2)) / base_period;
+			devpriv->divisor_b1 =
+				(labpc_ai_scan_period(cmd) +
+				(base_period / 2)) / base_period;
+			break;
+		case TRIG_ROUND_UP:
+			devpriv->divisor_a0 =
+				(labpc_ai_convert_period(cmd) + (base_period -
+					1)) / base_period;
+			devpriv->divisor_b1 =
+				(labpc_ai_scan_period(cmd) + (base_period -
+					1)) / base_period;
+			break;
+		case TRIG_ROUND_DOWN:
+			devpriv->divisor_a0 =
+				labpc_ai_convert_period(cmd) / base_period;
+			devpriv->divisor_b1 =
+				labpc_ai_scan_period(cmd) / base_period;
+			break;
+		}
+		// make sure a0 and b1 values are acceptable
+		if (devpriv->divisor_a0 < min_counter_value)
+			devpriv->divisor_a0 = min_counter_value;
+		if (devpriv->divisor_a0 > max_counter_value)
+			devpriv->divisor_a0 = max_counter_value;
+		if (devpriv->divisor_b1 < min_counter_value)
+			devpriv->divisor_b1 = min_counter_value;
+		if (devpriv->divisor_b1 > max_counter_value)
+			devpriv->divisor_b1 = max_counter_value;
+		// write corrected timings to command
+		labpc_set_ai_convert_period(cmd,
+			base_period * devpriv->divisor_a0);
+		labpc_set_ai_scan_period(cmd,
+			base_period * devpriv->divisor_b1);
+		// if only one TRIG_TIMER is used, we can employ the generic cascaded timing functions
+	} else if (labpc_ai_scan_period(cmd)) {
+		unsigned int scan_period;
+
+		scan_period = labpc_ai_scan_period(cmd);
+		/* calculate cascaded counter values that give desired scan timing */
+		i8253_cascade_ns_to_timer_2div(LABPC_TIMER_BASE,
+			&(devpriv->divisor_b1), &(devpriv->divisor_b0),
+			&scan_period, cmd->flags & TRIG_ROUND_MASK);
+		labpc_set_ai_scan_period(cmd, scan_period);
+	} else if (labpc_ai_convert_period(cmd)) {
+		unsigned int convert_period;
+
+		convert_period = labpc_ai_convert_period(cmd);
+		/* calculate cascaded counter values that give desired conversion timing */
+		i8253_cascade_ns_to_timer_2div(LABPC_TIMER_BASE,
+			&(devpriv->divisor_a0), &(devpriv->divisor_b0),
+			&convert_period, cmd->flags & TRIG_ROUND_MASK);
+		labpc_set_ai_convert_period(cmd, convert_period);
+	}
+}
+
+static int labpc_dio_mem_callback(int dir, int port, int data,
+	unsigned long iobase)
+{
+	if (dir) {
+		writeb(data, (void *)(iobase + port));
+		return 0;
+	} else {
+		return readb((void *)(iobase + port));
+	}
+}
+
+// lowlevel write to eeprom/dac
+static void labpc_serial_out(struct comedi_device * dev, unsigned int value,
+	unsigned int value_width)
+{
+	int i;
+
+	for (i = 1; i <= value_width; i++) {
+		// clear serial clock
+		devpriv->command5_bits &= ~SCLOCK_BIT;
+		// send bits most significant bit first
+		if (value & (1 << (value_width - i)))
+			devpriv->command5_bits |= SDATA_BIT;
+		else
+			devpriv->command5_bits &= ~SDATA_BIT;
+		comedi_udelay(1);
+		devpriv->write_byte(devpriv->command5_bits,
+			dev->iobase + COMMAND5_REG);
+		// set clock to load bit
+		devpriv->command5_bits |= SCLOCK_BIT;
+		comedi_udelay(1);
+		devpriv->write_byte(devpriv->command5_bits,
+			dev->iobase + COMMAND5_REG);
+	}
+}
+
+// lowlevel read from eeprom
+static unsigned int labpc_serial_in(struct comedi_device * dev)
+{
+	unsigned int value = 0;
+	int i;
+	const int value_width = 8;	// number of bits wide values are
+
+	for (i = 1; i <= value_width; i++) {
+		// set serial clock
+		devpriv->command5_bits |= SCLOCK_BIT;
+		comedi_udelay(1);
+		devpriv->write_byte(devpriv->command5_bits,
+			dev->iobase + COMMAND5_REG);
+		// clear clock bit
+		devpriv->command5_bits &= ~SCLOCK_BIT;
+		comedi_udelay(1);
+		devpriv->write_byte(devpriv->command5_bits,
+			dev->iobase + COMMAND5_REG);
+		// read bits most significant bit first
+		comedi_udelay(1);
+		devpriv->status2_bits =
+			devpriv->read_byte(dev->iobase + STATUS2_REG);
+		if (devpriv->status2_bits & EEPROM_OUT_BIT) {
+			value |= 1 << (value_width - i);
+		}
+	}
+
+	return value;
+}
+
+static unsigned int labpc_eeprom_read(struct comedi_device * dev, unsigned int address)
+{
+	unsigned int value;
+	const int read_instruction = 0x3;	// bits to tell eeprom to expect a read
+	const int write_length = 8;	// 8 bit write lengths to eeprom
+
+	// enable read/write to eeprom
+	devpriv->command5_bits &= ~EEPROM_EN_BIT;
+	comedi_udelay(1);
+	devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+	devpriv->command5_bits |= EEPROM_EN_BIT | EEPROM_WRITE_UNPROTECT_BIT;
+	comedi_udelay(1);
+	devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+	// send read instruction
+	labpc_serial_out(dev, read_instruction, write_length);
+	// send 8 bit address to read from
+	labpc_serial_out(dev, address, write_length);
+	// read result
+	value = labpc_serial_in(dev);
+
+	// disable read/write to eeprom
+	devpriv->command5_bits &= ~EEPROM_EN_BIT & ~EEPROM_WRITE_UNPROTECT_BIT;
+	comedi_udelay(1);
+	devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+	return value;
+}
+
+static unsigned int labpc_eeprom_write(struct comedi_device * dev,
+	unsigned int address, unsigned int value)
+{
+	const int write_enable_instruction = 0x6;
+	const int write_instruction = 0x2;
+	const int write_length = 8;	// 8 bit write lengths to eeprom
+	const int write_in_progress_bit = 0x1;
+	const int timeout = 10000;
+	int i;
+
+	// make sure there isn't already a write in progress
+	for (i = 0; i < timeout; i++) {
+		if ((labpc_eeprom_read_status(dev) & write_in_progress_bit) ==
+			0)
+			break;
+	}
+	if (i == timeout) {
+		comedi_error(dev, "eeprom write timed out");
+		return -ETIME;
+	}
+	// update software copy of eeprom
+	devpriv->eeprom_data[address] = value;
+
+	// enable read/write to eeprom
+	devpriv->command5_bits &= ~EEPROM_EN_BIT;
+	comedi_udelay(1);
+	devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+	devpriv->command5_bits |= EEPROM_EN_BIT | EEPROM_WRITE_UNPROTECT_BIT;
+	comedi_udelay(1);
+	devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+	// send write_enable instruction
+	labpc_serial_out(dev, write_enable_instruction, write_length);
+	devpriv->command5_bits &= ~EEPROM_EN_BIT;
+	comedi_udelay(1);
+	devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+	// send write instruction
+	devpriv->command5_bits |= EEPROM_EN_BIT;
+	comedi_udelay(1);
+	devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+	labpc_serial_out(dev, write_instruction, write_length);
+	// send 8 bit address to write to
+	labpc_serial_out(dev, address, write_length);
+	// write value
+	labpc_serial_out(dev, value, write_length);
+	devpriv->command5_bits &= ~EEPROM_EN_BIT;
+	comedi_udelay(1);
+	devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+	// disable read/write to eeprom
+	devpriv->command5_bits &= ~EEPROM_EN_BIT & ~EEPROM_WRITE_UNPROTECT_BIT;
+	comedi_udelay(1);
+	devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+	return 0;
+}
+
+static unsigned int labpc_eeprom_read_status(struct comedi_device * dev)
+{
+	unsigned int value;
+	const int read_status_instruction = 0x5;
+	const int write_length = 8;	// 8 bit write lengths to eeprom
+
+	// enable read/write to eeprom
+	devpriv->command5_bits &= ~EEPROM_EN_BIT;
+	comedi_udelay(1);
+	devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+	devpriv->command5_bits |= EEPROM_EN_BIT | EEPROM_WRITE_UNPROTECT_BIT;
+	comedi_udelay(1);
+	devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+	// send read status instruction
+	labpc_serial_out(dev, read_status_instruction, write_length);
+	// read result
+	value = labpc_serial_in(dev);
+
+	// disable read/write to eeprom
+	devpriv->command5_bits &= ~EEPROM_EN_BIT & ~EEPROM_WRITE_UNPROTECT_BIT;
+	comedi_udelay(1);
+	devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+	return value;
+}
+
+// writes to 8 bit calibration dacs
+static void write_caldac(struct comedi_device * dev, unsigned int channel,
+	unsigned int value)
+{
+	if (value == devpriv->caldac[channel])
+		return;
+	devpriv->caldac[channel] = value;
+
+	// clear caldac load bit and make sure we don't write to eeprom
+	devpriv->command5_bits &=
+		~CALDAC_LOAD_BIT & ~EEPROM_EN_BIT & ~EEPROM_WRITE_UNPROTECT_BIT;
+	comedi_udelay(1);
+	devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+	// write 4 bit channel
+	labpc_serial_out(dev, channel, 4);
+	// write 8 bit caldac value
+	labpc_serial_out(dev, value, 8);
+
+	// set and clear caldac bit to load caldac value
+	devpriv->command5_bits |= CALDAC_LOAD_BIT;
+	comedi_udelay(1);
+	devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+	devpriv->command5_bits &= ~CALDAC_LOAD_BIT;
+	comedi_udelay(1);
+	devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+}
+
+#ifdef CONFIG_COMEDI_PCI
+COMEDI_PCI_INITCLEANUP(driver_labpc, labpc_pci_table);
+#else
+COMEDI_INITCLEANUP(driver_labpc);
+#endif
+
+EXPORT_SYMBOL_GPL(labpc_common_attach);
+EXPORT_SYMBOL_GPL(labpc_common_detach);
+EXPORT_SYMBOL_GPL(range_labpc_1200_ai);
+EXPORT_SYMBOL_GPL(labpc_1200_ai_gain_bits);
+EXPORT_SYMBOL_GPL(labpc_1200_is_unipolar);
diff --git a/drivers/staging/comedi/drivers/ni_labpc.h b/drivers/staging/comedi/drivers/ni_labpc.h
new file mode 100644
index 0000000..b44b0d3
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_labpc.h
@@ -0,0 +1,85 @@
+/*
+    ni_labpc.h
+
+    Header for ni_labpc.c and ni_labpc_cs.c
+
+    Copyright (C) 2003 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+    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.
+
+*/
+
+#ifndef _NI_LABPC_H
+#define _NI_LABPC_H
+
+#define EEPROM_SIZE	256	// 256 byte eeprom
+#define NUM_AO_CHAN	2	// boards have two analog output channels
+
+enum labpc_bustype { isa_bustype, pci_bustype, pcmcia_bustype };
+enum labpc_register_layout { labpc_plus_layout, labpc_1200_layout };
+enum transfer_type { fifo_not_empty_transfer, fifo_half_full_transfer,
+		isa_dma_transfer };
+
+typedef struct labpc_board_struct {
+	const char *name;
+	int device_id;		// device id for pci and pcmcia boards
+	int ai_speed;		// maximum input speed in nanoseconds
+	enum labpc_bustype bustype;	// ISA/PCI/etc.
+	enum labpc_register_layout register_layout;	// 1200 has extra registers compared to pc+
+	int has_ao;		// has analog output true/false
+	const struct comedi_lrange *ai_range_table;
+	const int *ai_range_code;
+	const int *ai_range_is_unipolar;
+	unsigned ai_scan_up:1;	// board can auto scan up in ai channels, not just down
+	unsigned memory_mapped_io:1;	/* uses memory mapped io instead of ioports */
+} labpc_board;
+
+typedef struct {
+	struct mite_struct *mite;	// for mite chip on pci-1200
+	volatile unsigned long long count;	/* number of data points left to be taken */
+	unsigned int ao_value[NUM_AO_CHAN];	// software copy of analog output values
+	// software copys of bits written to command registers
+	volatile unsigned int command1_bits;
+	volatile unsigned int command2_bits;
+	volatile unsigned int command3_bits;
+	volatile unsigned int command4_bits;
+	volatile unsigned int command5_bits;
+	volatile unsigned int command6_bits;
+	// store last read of board status registers
+	volatile unsigned int status1_bits;
+	volatile unsigned int status2_bits;
+	unsigned int divisor_a0;	/* value to load into board's counter a0 (conversion pacing) for timed conversions */
+	unsigned int divisor_b0;	/* value to load into board's counter b0 (master) for timed conversions */
+	unsigned int divisor_b1;	/* value to load into board's counter b1 (scan pacing) for timed conversions */
+	unsigned int dma_chan;	// dma channel to use
+	u16 *dma_buffer;	// buffer ai will dma into
+	unsigned int dma_transfer_size;	// transfer size in bytes for current transfer
+	enum transfer_type current_transfer;	// we are using dma/fifo-half-full/etc.
+	unsigned int eeprom_data[EEPROM_SIZE];	// stores contents of board's eeprom
+	unsigned int caldac[16];	// stores settings of calibration dacs
+	// function pointers so we can use inb/outb or readb/writeb as appropriate
+	unsigned int (*read_byte) (unsigned long address);
+	void (*write_byte) (unsigned int byte, unsigned long address);
+} labpc_private;
+
+int labpc_common_attach(struct comedi_device * dev, unsigned long iobase,
+	unsigned int irq, unsigned int dma);
+int labpc_common_detach(struct comedi_device * dev);
+
+extern const int labpc_1200_is_unipolar[];
+extern const int labpc_1200_ai_gain_bits[];
+extern const struct comedi_lrange range_labpc_1200_ai;
+
+#endif /* _NI_LABPC_H */
diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c
new file mode 100644
index 0000000..ac0ce2f
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c
@@ -0,0 +1,573 @@
+/*
+    comedi/drivers/ni_labpc_cs.c
+    Driver for National Instruments daqcard-1200 boards
+    Copyright (C) 2001, 2002, 2003 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+    PCMCIA crap is adapted from dummy_cs.c 1.31 2001/08/24 12:13:13
+    from the pcmcia package.
+    The initial developer of the pcmcia dummy_cs.c code is David A. Hinds
+    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
+    are Copyright (C) 1999 David A. Hinds.
+
+    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.
+
+************************************************************************
+*/
+/*
+Driver: ni_labpc_cs
+Description: National Instruments Lab-PC (& compatibles)
+Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+Devices: [National Instruments] DAQCard-1200 (daqcard-1200)
+Status: works
+
+Thanks go to Fredrik Lingvall for much testing and perseverance in
+helping to debug daqcard-1200 support.
+
+The 1200 series boards have onboard calibration dacs for correcting
+analog input/output offsets and gains.  The proper settings for these
+caldacs are stored on the board's eeprom.  To read the caldac values
+from the eeprom and store them into a file that can be then be used by
+comedilib, use the comedi_calibrate program.
+
+Configuration options:
+  none
+
+The daqcard-1200 has quirky chanlist requirements
+when scanning multiple channels.  Multiple channel scan
+sequence must start at highest channel, then decrement down to
+channel 0.  Chanlists consisting of all one channel
+are also legal, and allow you to pace conversions in bursts.
+
+*/
+
+/*
+
+NI manuals:
+340988a (daqcard-1200)
+
+*/
+
+#undef LABPC_DEBUG
+//#define LABPC_DEBUG   // enable debugging messages
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+
+#include "8253.h"
+#include "8255.h"
+#include "comedi_fc.h"
+#include "ni_labpc.h"
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ds.h>
+
+static struct pcmcia_device *pcmcia_cur_dev = NULL;
+
+static int labpc_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+
+static const labpc_board labpc_cs_boards[] = {
+	{
+	      name:	"daqcard-1200",
+	      device_id:0x103,	// 0x10b is manufacturer id, 0x103 is device id
+	      ai_speed:10000,
+	      bustype:	pcmcia_bustype,
+	      register_layout:labpc_1200_layout,
+	      has_ao:	1,
+	      ai_range_table:&range_labpc_1200_ai,
+	      ai_range_code:labpc_1200_ai_gain_bits,
+	      ai_range_is_unipolar:labpc_1200_is_unipolar,
+	      ai_scan_up:0,
+	      memory_mapped_io:0,
+		},
+	/* duplicate entry, to support using alternate name */
+	{
+	      name:	"ni_labpc_cs",
+	      device_id:0x103,
+	      ai_speed:10000,
+	      bustype:	pcmcia_bustype,
+	      register_layout:labpc_1200_layout,
+	      has_ao:	1,
+	      ai_range_table:&range_labpc_1200_ai,
+	      ai_range_code:labpc_1200_ai_gain_bits,
+	      ai_range_is_unipolar:labpc_1200_is_unipolar,
+	      ai_scan_up:0,
+	      memory_mapped_io:0,
+		},
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const labpc_board *)dev->board_ptr)
+
+static struct comedi_driver driver_labpc_cs = {
+	.driver_name = "ni_labpc_cs",
+	.module = THIS_MODULE,
+	.attach = &labpc_attach,
+	.detach = &labpc_common_detach,
+	.num_names = sizeof(labpc_cs_boards) / sizeof(labpc_board),
+	.board_name = &labpc_cs_boards[0].name,
+	.offset = sizeof(labpc_board),
+};
+
+static int labpc_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	unsigned long iobase = 0;
+	unsigned int irq = 0;
+	struct pcmcia_device *link;
+
+	/* allocate and initialize dev->private */
+	if (alloc_private(dev, sizeof(labpc_private)) < 0)
+		return -ENOMEM;
+
+	// get base address, irq etc. based on bustype
+	switch (thisboard->bustype) {
+	case pcmcia_bustype:
+		link = pcmcia_cur_dev;	/* XXX hack */
+		if (!link)
+			return -EIO;
+		iobase = link->io.BasePort1;
+		irq = link->irq.AssignedIRQ;
+		break;
+	default:
+		printk("bug! couldn't determine board type\n");
+		return -EINVAL;
+		break;
+	}
+	return labpc_common_attach(dev, iobase, irq, 0);
+}
+
+/*
+   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
+   you do not define PCMCIA_DEBUG at all, all the debug code will be
+   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
+   be present but disabled -- but it can then be enabled for specific
+   modules at load time with a 'pc_debug=#' option to insmod.
+*/
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+module_param(pc_debug, int, 0644);
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+static const char *version =
+	"ni_labpc.c, based on dummy_cs.c 1.31 2001/08/24 12:13:13";
+#else
+#define DEBUG(n, args...)
+#endif
+
+/*====================================================================*/
+
+/*
+   The event() function is this driver's Card Services event handler.
+   It will be called by Card Services when an appropriate card status
+   event is received.  The config() and release() entry points are
+   used to configure or release a socket, in response to card
+   insertion and ejection events.  They are invoked from the dummy
+   event handler.
+
+   Kernel version 2.6.16 upwards uses suspend() and resume() functions
+   instead of an event() function.
+*/
+
+static void labpc_config(struct pcmcia_device *link);
+static void labpc_release(struct pcmcia_device *link);
+static int labpc_cs_suspend(struct pcmcia_device *p_dev);
+static int labpc_cs_resume(struct pcmcia_device *p_dev);
+
+/*
+   The attach() and detach() entry points are used to create and destroy
+   "instances" of the driver, where each instance represents everything
+   needed to manage one actual PCMCIA card.
+*/
+
+static int labpc_cs_attach(struct pcmcia_device *);
+static void labpc_cs_detach(struct pcmcia_device *);
+
+/*
+   You'll also need to prototype all the functions that will actually
+   be used to talk to your device.  See 'memory_cs' for a good example
+   of a fully self-sufficient driver; the other drivers rely more or
+   less on other parts of the kernel.
+*/
+
+/*
+   The dev_info variable is the "key" that is used to match up this
+   device driver with appropriate cards, through the card configuration
+   database.
+*/
+
+static const dev_info_t dev_info = "daqcard-1200";
+
+typedef struct local_info_t {
+	struct pcmcia_device *link;
+	dev_node_t node;
+	int stop;
+	struct bus_operations *bus;
+} local_info_t;
+
+/*======================================================================
+
+    labpc_cs_attach() creates an "instance" of the driver, allocating
+    local data structures for one device.  The device is registered
+    with Card Services.
+
+    The dev_link structure is initialized, but we don't actually
+    configure the card at this point -- we wait until we receive a
+    card insertion event.
+
+======================================================================*/
+
+static int labpc_cs_attach(struct pcmcia_device *link)
+{
+	local_info_t *local;
+
+	DEBUG(0, "labpc_cs_attach()\n");
+
+	/* Allocate space for private device-specific data */
+	local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
+	if (!local)
+		return -ENOMEM;
+	local->link = link;
+	link->priv = local;
+
+	/* Interrupt setup */
+	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_FORCED_PULSE;
+	link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_PULSE_ID;
+	link->irq.Handler = NULL;
+
+	/*
+	   General socket configuration defaults can go here.  In this
+	   client, we assume very little, and rely on the CIS for almost
+	   everything.  In most clients, many details (i.e., number, sizes,
+	   and attributes of IO windows) are fixed by the nature of the
+	   device, and can be hard-wired here.
+	 */
+	link->conf.Attributes = 0;
+	link->conf.IntType = INT_MEMORY_AND_IO;
+
+	pcmcia_cur_dev = link;
+
+	labpc_config(link);
+
+	return 0;
+}				/* labpc_cs_attach */
+
+/*======================================================================
+
+    This deletes a driver "instance".  The device is de-registered
+    with Card Services.  If it has been released, all local data
+    structures are freed.  Otherwise, the structures will be freed
+    when the device is released.
+
+======================================================================*/
+
+static void labpc_cs_detach(struct pcmcia_device *link)
+{
+	DEBUG(0, "labpc_cs_detach(0x%p)\n", link);
+
+	/*
+	   If the device is currently configured and active, we won't
+	   actually delete it yet.  Instead, it is marked so that when
+	   the release() function is called, that will trigger a proper
+	   detach().
+	 */
+	if (link->dev_node) {
+		((local_info_t *) link->priv)->stop = 1;
+		labpc_release(link);
+	}
+
+	/* This points to the parent local_info_t struct */
+	if (link->priv)
+		kfree(link->priv);
+
+}				/* labpc_cs_detach */
+
+/*======================================================================
+
+    labpc_config() is scheduled to run after a CARD_INSERTION event
+    is received, to configure the PCMCIA socket, and to make the
+    device available to the system.
+
+======================================================================*/
+
+static void labpc_config(struct pcmcia_device *link)
+{
+	local_info_t *dev = link->priv;
+	tuple_t tuple;
+	cisparse_t parse;
+	int last_ret;
+	u_char buf[64];
+	win_req_t req;
+	memreq_t map;
+	cistpl_cftable_entry_t dflt = { 0 };
+
+	DEBUG(0, "labpc_config(0x%p)\n", link);
+
+	/*
+	   This reads the card's CONFIG tuple to find its configuration
+	   registers.
+	 */
+	tuple.DesiredTuple = CISTPL_CONFIG;
+	tuple.Attributes = 0;
+	tuple.TupleData = buf;
+	tuple.TupleDataMax = sizeof(buf);
+	tuple.TupleOffset = 0;
+	if ((last_ret = pcmcia_get_first_tuple(link, &tuple))) {
+		cs_error(link, GetFirstTuple, last_ret);
+		goto cs_failed;
+	}
+	if ((last_ret = pcmcia_get_tuple_data(link, &tuple))) {
+		cs_error(link, GetTupleData, last_ret);
+		goto cs_failed;
+	}
+	if ((last_ret = pcmcia_parse_tuple(&tuple, &parse))) {
+		cs_error(link, ParseTuple, last_ret);
+		goto cs_failed;
+	}
+	link->conf.ConfigBase = parse.config.base;
+	link->conf.Present = parse.config.rmask[0];
+
+	/*
+	   In this loop, we scan the CIS for configuration table entries,
+	   each of which describes a valid card configuration, including
+	   voltage, IO window, memory window, and interrupt settings.
+
+	   We make no assumptions about the card to be configured: we use
+	   just the information available in the CIS.  In an ideal world,
+	   this would work for any PCMCIA card, but it requires a complete
+	   and accurate CIS.  In practice, a driver usually "knows" most of
+	   these things without consulting the CIS, and most client drivers
+	   will only use the CIS to fill in implementation-defined details.
+	 */
+	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+	if ((last_ret = pcmcia_get_first_tuple(link, &tuple))) {
+		cs_error(link, GetFirstTuple, last_ret);
+		goto cs_failed;
+	}
+	while (1) {
+		cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+		if (pcmcia_get_tuple_data(link, &tuple))
+			goto next_entry;
+		if (pcmcia_parse_tuple(&tuple, &parse))
+			goto next_entry;
+
+		if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+			dflt = *cfg;
+		if (cfg->index == 0)
+			goto next_entry;
+		link->conf.ConfigIndex = cfg->index;
+
+		/* Does this card need audio output? */
+		if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+			link->conf.Attributes |= CONF_ENABLE_SPKR;
+			link->conf.Status = CCSR_AUDIO_ENA;
+		}
+
+		/* Do we need to allocate an interrupt? */
+		if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
+			link->conf.Attributes |= CONF_ENABLE_IRQ;
+
+		/* IO window settings */
+		link->io.NumPorts1 = link->io.NumPorts2 = 0;
+		if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+			cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+			link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+			link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+			link->io.BasePort1 = io->win[0].base;
+			link->io.NumPorts1 = io->win[0].len;
+			if (io->nwin > 1) {
+				link->io.Attributes2 = link->io.Attributes1;
+				link->io.BasePort2 = io->win[1].base;
+				link->io.NumPorts2 = io->win[1].len;
+			}
+			/* This reserves IO space but doesn't actually enable it */
+			if (pcmcia_request_io(link, &link->io))
+				goto next_entry;
+		}
+
+		if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
+			cistpl_mem_t *mem =
+				(cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
+			req.Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
+			req.Attributes |= WIN_ENABLE;
+			req.Base = mem->win[0].host_addr;
+			req.Size = mem->win[0].len;
+			if (req.Size < 0x1000)
+				req.Size = 0x1000;
+			req.AccessSpeed = 0;
+			link->win = (window_handle_t) link;
+			if (pcmcia_request_window(&link, &req, &link->win))
+				goto next_entry;
+			map.Page = 0;
+			map.CardOffset = mem->win[0].card_addr;
+			if (pcmcia_map_mem_page(link->win, &map))
+				goto next_entry;
+		}
+		/* If we got this far, we're cool! */
+		break;
+
+	      next_entry:
+		if ((last_ret = pcmcia_get_next_tuple(link, &tuple))) {
+			cs_error(link, GetNextTuple, last_ret);
+			goto cs_failed;
+		}
+	}
+
+	/*
+	   Allocate an interrupt line.  Note that this does not assign a
+	   handler to the interrupt, unless the 'Handler' member of the
+	   irq structure is initialized.
+	 */
+	if (link->conf.Attributes & CONF_ENABLE_IRQ)
+		if ((last_ret = pcmcia_request_irq(link, &link->irq))) {
+			cs_error(link, RequestIRQ, last_ret);
+			goto cs_failed;
+		}
+
+	/*
+	   This actually configures the PCMCIA socket -- setting up
+	   the I/O windows and the interrupt mapping, and putting the
+	   card and host interface into "Memory and IO" mode.
+	 */
+	if ((last_ret = pcmcia_request_configuration(link, &link->conf))) {
+		cs_error(link, RequestConfiguration, last_ret);
+		goto cs_failed;
+	}
+
+	/*
+	   At this point, the dev_node_t structure(s) need to be
+	   initialized and arranged in a linked list at link->dev.
+	 */
+	sprintf(dev->node.dev_name, "daqcard-1200");
+	dev->node.major = dev->node.minor = 0;
+	link->dev_node = &dev->node;
+
+	/* Finally, report what we've done */
+	printk(KERN_INFO "%s: index 0x%02x",
+		dev->node.dev_name, link->conf.ConfigIndex);
+	if (link->conf.Attributes & CONF_ENABLE_IRQ)
+		printk(", irq %d", link->irq.AssignedIRQ);
+	if (link->io.NumPorts1)
+		printk(", io 0x%04x-0x%04x", link->io.BasePort1,
+			link->io.BasePort1 + link->io.NumPorts1 - 1);
+	if (link->io.NumPorts2)
+		printk(" & 0x%04x-0x%04x", link->io.BasePort2,
+			link->io.BasePort2 + link->io.NumPorts2 - 1);
+	if (link->win)
+		printk(", mem 0x%06lx-0x%06lx", req.Base,
+			req.Base + req.Size - 1);
+	printk("\n");
+
+	return;
+
+      cs_failed:
+	labpc_release(link);
+
+}				/* labpc_config */
+
+static void labpc_release(struct pcmcia_device *link)
+{
+	DEBUG(0, "labpc_release(0x%p)\n", link);
+
+	pcmcia_disable_device(link);
+}				/* labpc_release */
+
+/*======================================================================
+
+    The card status event handler.  Mostly, this schedules other
+    stuff to run after an event is received.
+
+    When a CARD_REMOVAL event is received, we immediately set a
+    private flag to block future accesses to this device.  All the
+    functions that actually access the device should check this flag
+    to make sure the card is still present.
+
+======================================================================*/
+
+static int labpc_cs_suspend(struct pcmcia_device *link)
+{
+	local_info_t *local = link->priv;
+
+	/* Mark the device as stopped, to block IO until later */
+	local->stop = 1;
+	return 0;
+}				/* labpc_cs_suspend */
+
+static int labpc_cs_resume(struct pcmcia_device *link)
+{
+	local_info_t *local = link->priv;
+
+	local->stop = 0;
+	return 0;
+}				/* labpc_cs_resume */
+
+/*====================================================================*/
+
+static struct pcmcia_device_id labpc_cs_ids[] = {
+	/* N.B. These IDs should match those in labpc_cs_boards (ni_labpc.c) */
+	PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0103),	/* daqcard-1200 */
+	PCMCIA_DEVICE_NULL
+};
+
+MODULE_DEVICE_TABLE(pcmcia, labpc_cs_ids);
+
+struct pcmcia_driver labpc_cs_driver = {
+	.probe = labpc_cs_attach,
+	.remove = labpc_cs_detach,
+	.suspend = labpc_cs_suspend,
+	.resume = labpc_cs_resume,
+	.id_table = labpc_cs_ids,
+	.owner = THIS_MODULE,
+	.drv = {
+			.name = dev_info,
+		},
+};
+
+static int __init init_labpc_cs(void)
+{
+	DEBUG(0, "%s\n", version);
+	pcmcia_register_driver(&labpc_cs_driver);
+	return 0;
+}
+
+static void __exit exit_labpc_cs(void)
+{
+	DEBUG(0, "ni_labpc: unloading\n");
+	pcmcia_unregister_driver(&labpc_cs_driver);
+}
+
+int __init labpc_init_module(void)
+{
+	int ret;
+
+	ret = init_labpc_cs();
+	if (ret < 0)
+		return ret;
+
+	return comedi_driver_register(&driver_labpc_cs);
+}
+
+void __exit labpc_exit_module(void)
+{
+	exit_labpc_cs();
+	comedi_driver_unregister(&driver_labpc_cs);
+}
+
+MODULE_LICENSE("GPL");
+module_init(labpc_init_module);
+module_exit(labpc_exit_module);
diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c
new file mode 100644
index 0000000..542bd0d
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_mio_common.c
@@ -0,0 +1,5862 @@
+/*
+    comedi/drivers/ni_mio_common.c
+    Hardware driver for DAQ-STC based boards
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org>
+    Copyright (C) 2002-2006 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+    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.
+
+*/
+
+/*
+	This file is meant to be included by another file, e.g.,
+	ni_atmio.c or ni_pcimio.c.
+
+	Interrupt support originally added by Truxton Fulton
+	<trux@truxton.com>
+
+	References (from ftp://ftp.natinst.com/support/manuals):
+
+	   340747b.pdf  AT-MIO E series Register Level Programmer Manual
+	   341079b.pdf  PCI E Series RLPM
+	   340934b.pdf  DAQ-STC reference manual
+	67xx and 611x registers (from http://www.ni.com/pdf/daq/us)
+	release_ni611x.pdf
+	release_ni67xx.pdf
+	Other possibly relevant info:
+
+	   320517c.pdf  User manual (obsolete)
+	   320517f.pdf  User manual (new)
+	   320889a.pdf  delete
+	   320906c.pdf  maximum signal ratings
+	   321066a.pdf  about 16x
+	   321791a.pdf  discontinuation of at-mio-16e-10 rev. c
+	   321808a.pdf  about at-mio-16e-10 rev P
+	   321837a.pdf  discontinuation of at-mio-16de-10 rev d
+	   321838a.pdf  about at-mio-16de-10 rev N
+
+	ISSUES:
+
+	 - the interrupt routine needs to be cleaned up
+
+	2006-02-07: S-Series PCI-6143: Support has been added but is not
+		fully tested as yet. Terry Barnaby, BEAM Ltd.
+*/
+
+//#define DEBUG_INTERRUPT
+//#define DEBUG_STATUS_A
+//#define DEBUG_STATUS_B
+
+#include "8255.h"
+#include "mite.h"
+#include "comedi_fc.h"
+
+#ifndef MDPRINTK
+#define MDPRINTK(format,args...)
+#endif
+
+/* A timeout count */
+#define NI_TIMEOUT 1000
+static const unsigned old_RTSI_clock_channel = 7;
+
+/* Note: this table must match the ai_gain_* definitions */
+static const short ni_gainlkup[][16] = {
+	[ai_gain_16] = {0, 1, 2, 3, 4, 5, 6, 7,
+		0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107},
+	[ai_gain_8] = {1, 2, 4, 7, 0x101, 0x102, 0x104, 0x107},
+	[ai_gain_14] = {1, 2, 3, 4, 5, 6, 7,
+		0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107},
+	[ai_gain_4] = {0, 1, 4, 7},
+	[ai_gain_611x] = {0x00a, 0x00b, 0x001, 0x002,
+		0x003, 0x004, 0x005, 0x006},
+	[ai_gain_622x] = {0, 1, 4, 5},
+	[ai_gain_628x] = {1, 2, 3, 4, 5, 6, 7},
+	[ai_gain_6143] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+};
+
+static const struct comedi_lrange range_ni_E_ai = { 16, {
+			RANGE(-10, 10),
+			RANGE(-5, 5),
+			RANGE(-2.5, 2.5),
+			RANGE(-1, 1),
+			RANGE(-0.5, 0.5),
+			RANGE(-0.25, 0.25),
+			RANGE(-0.1, 0.1),
+			RANGE(-0.05, 0.05),
+			RANGE(0, 20),
+			RANGE(0, 10),
+			RANGE(0, 5),
+			RANGE(0, 2),
+			RANGE(0, 1),
+			RANGE(0, 0.5),
+			RANGE(0, 0.2),
+			RANGE(0, 0.1),
+	}
+};
+static const struct comedi_lrange range_ni_E_ai_limited = { 8, {
+			RANGE(-10, 10),
+			RANGE(-5, 5),
+			RANGE(-1, 1),
+			RANGE(-0.1, 0.1),
+			RANGE(0, 10),
+			RANGE(0, 5),
+			RANGE(0, 1),
+			RANGE(0, 0.1),
+	}
+};
+static const struct comedi_lrange range_ni_E_ai_limited14 = { 14, {
+			RANGE(-10, 10),
+			RANGE(-5, 5),
+			RANGE(-2, 2),
+			RANGE(-1, 1),
+			RANGE(-0.5, 0.5),
+			RANGE(-0.2, 0.2),
+			RANGE(-0.1, 0.1),
+			RANGE(0, 10),
+			RANGE(0, 5),
+			RANGE(0, 2),
+			RANGE(0, 1),
+			RANGE(0, 0.5),
+			RANGE(0, 0.2),
+			RANGE(0, 0.1),
+	}
+};
+static const struct comedi_lrange range_ni_E_ai_bipolar4 = { 4, {
+			RANGE(-10, 10),
+			RANGE(-5, 5),
+			RANGE(-0.5, 0.5),
+			RANGE(-0.05, 0.05),
+	}
+};
+static const struct comedi_lrange range_ni_E_ai_611x = { 8, {
+			RANGE(-50, 50),
+			RANGE(-20, 20),
+			RANGE(-10, 10),
+			RANGE(-5, 5),
+			RANGE(-2, 2),
+			RANGE(-1, 1),
+			RANGE(-0.5, 0.5),
+			RANGE(-0.2, 0.2),
+	}
+};
+static const struct comedi_lrange range_ni_M_ai_622x = { 4, {
+			RANGE(-10, 10),
+			RANGE(-5, 5),
+			RANGE(-1, 1),
+			RANGE(-0.2, 0.2),
+	}
+};
+static const struct comedi_lrange range_ni_M_ai_628x = { 7, {
+			RANGE(-10, 10),
+			RANGE(-5, 5),
+			RANGE(-2, 2),
+			RANGE(-1, 1),
+			RANGE(-0.5, 0.5),
+			RANGE(-0.2, 0.2),
+			RANGE(-0.1, 0.1),
+	}
+};
+static const struct comedi_lrange range_ni_S_ai_6143 = { 1, {
+			RANGE(-5, +5),
+	}
+};
+static const struct comedi_lrange range_ni_E_ao_ext = { 4, {
+			RANGE(-10, 10),
+			RANGE(0, 10),
+			RANGE_ext(-1, 1),
+			RANGE_ext(0, 1),
+	}
+};
+
+static const struct comedi_lrange *const ni_range_lkup[] = {
+	[ai_gain_16] = &range_ni_E_ai,
+	[ai_gain_8] = &range_ni_E_ai_limited,
+	[ai_gain_14] = &range_ni_E_ai_limited14,
+	[ai_gain_4] = &range_ni_E_ai_bipolar4,
+	[ai_gain_611x] = &range_ni_E_ai_611x,
+	[ai_gain_622x] = &range_ni_M_ai_622x,
+	[ai_gain_628x] = &range_ni_M_ai_628x,
+	[ai_gain_6143] = &range_ni_S_ai_6143
+};
+
+static int ni_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int ni_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int ni_cdio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd);
+static int ni_cdio_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int ni_cdio_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void handle_cdio_interrupt(struct comedi_device * dev);
+static int ni_cdo_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int trignum);
+
+static int ni_serial_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int ni_serial_hw_readwrite8(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned char data_out, unsigned char *data_in);
+static int ni_serial_sw_readwrite8(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned char data_out, unsigned char *data_in);
+
+static int ni_calib_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int ni_calib_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+static int ni_eeprom_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int ni_m_series_eeprom_insn_read(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+static int ni_pfi_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int ni_pfi_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static unsigned ni_old_get_pfi_routing(struct comedi_device * dev, unsigned chan);
+
+static void ni_rtsi_init(struct comedi_device * dev);
+static int ni_rtsi_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int ni_rtsi_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+static void caldac_setup(struct comedi_device * dev, struct comedi_subdevice * s);
+static int ni_read_eeprom(struct comedi_device * dev, int addr);
+
+#ifdef DEBUG_STATUS_A
+static void ni_mio_print_status_a(int status);
+#else
+#define ni_mio_print_status_a(a)
+#endif
+#ifdef DEBUG_STATUS_B
+static void ni_mio_print_status_b(int status);
+#else
+#define ni_mio_print_status_b(a)
+#endif
+
+static int ni_ai_reset(struct comedi_device * dev, struct comedi_subdevice * s);
+#ifndef PCIDMA
+static void ni_handle_fifo_half_full(struct comedi_device * dev);
+static int ni_ao_fifo_half_empty(struct comedi_device * dev, struct comedi_subdevice * s);
+#endif
+static void ni_handle_fifo_dregs(struct comedi_device * dev);
+static int ni_ai_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int trignum);
+static void ni_load_channelgain_list(struct comedi_device * dev, unsigned int n_chan,
+	unsigned int *list);
+static void shutdown_ai_command(struct comedi_device * dev);
+
+static int ni_ao_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int trignum);
+
+static int ni_ao_reset(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static int ni_8255_callback(int dir, int port, int data, unsigned long arg);
+
+static int ni_gpct_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int ni_gpct_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int ni_gpct_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int ni_gpct_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int ni_gpct_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd);
+static int ni_gpct_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void handle_gpct_interrupt(struct comedi_device * dev,
+	unsigned short counter_index);
+
+static int init_cs5529(struct comedi_device * dev);
+static int cs5529_do_conversion(struct comedi_device * dev, unsigned short *data);
+static int cs5529_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+#ifdef NI_CS5529_DEBUG
+static unsigned int cs5529_config_read(struct comedi_device * dev,
+	unsigned int reg_select_bits);
+#endif
+static void cs5529_config_write(struct comedi_device * dev, unsigned int value,
+	unsigned int reg_select_bits);
+
+static int ni_m_series_pwm_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int ni_6143_pwm_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+static int ni_set_master_clock(struct comedi_device * dev, unsigned source,
+	unsigned period_ns);
+static void ack_a_interrupt(struct comedi_device * dev, unsigned short a_status);
+static void ack_b_interrupt(struct comedi_device * dev, unsigned short b_status);
+
+enum aimodes {
+	AIMODE_NONE = 0,
+	AIMODE_HALF_FULL = 1,
+	AIMODE_SCAN = 2,
+	AIMODE_SAMPLE = 3,
+};
+
+enum ni_common_subdevices {
+	NI_AI_SUBDEV,
+	NI_AO_SUBDEV,
+	NI_DIO_SUBDEV,
+	NI_8255_DIO_SUBDEV,
+	NI_UNUSED_SUBDEV,
+	NI_CALIBRATION_SUBDEV,
+	NI_EEPROM_SUBDEV,
+	NI_PFI_DIO_SUBDEV,
+	NI_CS5529_CALIBRATION_SUBDEV,
+	NI_SERIAL_SUBDEV,
+	NI_RTSI_SUBDEV,
+	NI_GPCT0_SUBDEV,
+	NI_GPCT1_SUBDEV,
+	NI_FREQ_OUT_SUBDEV,
+	NI_NUM_SUBDEVICES
+};
+static inline unsigned NI_GPCT_SUBDEV(unsigned counter_index)
+{
+	switch (counter_index) {
+	case 0:
+		return NI_GPCT0_SUBDEV;
+		break;
+	case 1:
+		return NI_GPCT1_SUBDEV;
+		break;
+	default:
+		break;
+	}
+	BUG();
+	return NI_GPCT0_SUBDEV;
+}
+
+enum timebase_nanoseconds {
+	TIMEBASE_1_NS = 50,
+	TIMEBASE_2_NS = 10000
+};
+
+#define SERIAL_DISABLED		0
+#define SERIAL_600NS		600
+#define SERIAL_1_2US		1200
+#define SERIAL_10US			10000
+
+static const int num_adc_stages_611x = 3;
+
+static void handle_a_interrupt(struct comedi_device * dev, unsigned short status,
+	unsigned ai_mite_status);
+static void handle_b_interrupt(struct comedi_device * dev, unsigned short status,
+	unsigned ao_mite_status);
+static void get_last_sample_611x(struct comedi_device * dev);
+static void get_last_sample_6143(struct comedi_device * dev);
+
+static inline void ni_set_bitfield(struct comedi_device * dev, int reg,
+	unsigned bit_mask, unsigned bit_values)
+{
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags);
+	switch (reg) {
+	case Interrupt_A_Enable_Register:
+		devpriv->int_a_enable_reg &= ~bit_mask;
+		devpriv->int_a_enable_reg |= bit_values & bit_mask;
+		devpriv->stc_writew(dev, devpriv->int_a_enable_reg,
+			Interrupt_A_Enable_Register);
+		break;
+	case Interrupt_B_Enable_Register:
+		devpriv->int_b_enable_reg &= ~bit_mask;
+		devpriv->int_b_enable_reg |= bit_values & bit_mask;
+		devpriv->stc_writew(dev, devpriv->int_b_enable_reg,
+			Interrupt_B_Enable_Register);
+		break;
+	case IO_Bidirection_Pin_Register:
+		devpriv->io_bidirection_pin_reg &= ~bit_mask;
+		devpriv->io_bidirection_pin_reg |= bit_values & bit_mask;
+		devpriv->stc_writew(dev, devpriv->io_bidirection_pin_reg,
+			IO_Bidirection_Pin_Register);
+		break;
+	case AI_AO_Select:
+		devpriv->ai_ao_select_reg &= ~bit_mask;
+		devpriv->ai_ao_select_reg |= bit_values & bit_mask;
+		ni_writeb(devpriv->ai_ao_select_reg, AI_AO_Select);
+		break;
+	case G0_G1_Select:
+		devpriv->g0_g1_select_reg &= ~bit_mask;
+		devpriv->g0_g1_select_reg |= bit_values & bit_mask;
+		ni_writeb(devpriv->g0_g1_select_reg, G0_G1_Select);
+		break;
+	default:
+		rt_printk("Warning %s() called with invalid register\n",
+			__FUNCTION__);
+		rt_printk("reg is %d\n", reg);
+		break;
+	}
+	mmiowb();
+	comedi_spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags);
+}
+
+#ifdef PCIDMA
+static int ni_ai_drain_dma(struct comedi_device * dev);
+
+/* DMA channel setup */
+
+// negative channel means no channel
+static inline void ni_set_ai_dma_channel(struct comedi_device * dev, int channel)
+{
+	unsigned bitfield;
+
+	if (channel >= 0) {
+		bitfield =
+			(ni_stc_dma_channel_select_bitfield(channel) <<
+			AI_DMA_Select_Shift) & AI_DMA_Select_Mask;
+	} else {
+		bitfield = 0;
+	}
+	ni_set_bitfield(dev, AI_AO_Select, AI_DMA_Select_Mask, bitfield);
+}
+
+// negative channel means no channel
+static inline void ni_set_ao_dma_channel(struct comedi_device * dev, int channel)
+{
+	unsigned bitfield;
+
+	if (channel >= 0) {
+		bitfield =
+			(ni_stc_dma_channel_select_bitfield(channel) <<
+			AO_DMA_Select_Shift) & AO_DMA_Select_Mask;
+	} else {
+		bitfield = 0;
+	}
+	ni_set_bitfield(dev, AI_AO_Select, AO_DMA_Select_Mask, bitfield);
+}
+
+// negative mite_channel means no channel
+static inline void ni_set_gpct_dma_channel(struct comedi_device * dev,
+	unsigned gpct_index, int mite_channel)
+{
+	unsigned bitfield;
+
+	if (mite_channel >= 0) {
+		bitfield = GPCT_DMA_Select_Bits(gpct_index, mite_channel);
+	} else {
+		bitfield = 0;
+	}
+	ni_set_bitfield(dev, G0_G1_Select, GPCT_DMA_Select_Mask(gpct_index),
+		bitfield);
+}
+
+// negative mite_channel means no channel
+static inline void ni_set_cdo_dma_channel(struct comedi_device * dev, int mite_channel)
+{
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags);
+	devpriv->cdio_dma_select_reg &= ~CDO_DMA_Select_Mask;
+	if (mite_channel >= 0) {
+		/*XXX just guessing ni_stc_dma_channel_select_bitfield() returns the right bits,
+		   under the assumption the cdio dma selection works just like ai/ao/gpct.
+		   Definitely works for dma channels 0 and 1. */
+		devpriv->cdio_dma_select_reg |=
+			(ni_stc_dma_channel_select_bitfield(mite_channel) <<
+			CDO_DMA_Select_Shift) & CDO_DMA_Select_Mask;
+	}
+	ni_writeb(devpriv->cdio_dma_select_reg, M_Offset_CDIO_DMA_Select);
+	mmiowb();
+	comedi_spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags);
+}
+
+static int ni_request_ai_mite_channel(struct comedi_device * dev)
+{
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+	BUG_ON(devpriv->ai_mite_chan);
+	devpriv->ai_mite_chan =
+		mite_request_channel(devpriv->mite, devpriv->ai_mite_ring);
+	if (devpriv->ai_mite_chan == NULL) {
+		comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock,
+			flags);
+		comedi_error(dev,
+			"failed to reserve mite dma channel for analog input.");
+		return -EBUSY;
+	}
+	devpriv->ai_mite_chan->dir = COMEDI_INPUT;
+	ni_set_ai_dma_channel(dev, devpriv->ai_mite_chan->channel);
+	comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+	return 0;
+}
+
+static int ni_request_ao_mite_channel(struct comedi_device * dev)
+{
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+	BUG_ON(devpriv->ao_mite_chan);
+	devpriv->ao_mite_chan =
+		mite_request_channel(devpriv->mite, devpriv->ao_mite_ring);
+	if (devpriv->ao_mite_chan == NULL) {
+		comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock,
+			flags);
+		comedi_error(dev,
+			"failed to reserve mite dma channel for analog outut.");
+		return -EBUSY;
+	}
+	devpriv->ao_mite_chan->dir = COMEDI_OUTPUT;
+	ni_set_ao_dma_channel(dev, devpriv->ao_mite_chan->channel);
+	comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+	return 0;
+}
+
+static int ni_request_gpct_mite_channel(struct comedi_device * dev,
+	unsigned gpct_index, enum comedi_io_direction direction)
+{
+	unsigned long flags;
+	struct mite_channel *mite_chan;
+
+	BUG_ON(gpct_index >= NUM_GPCT);
+	comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+	BUG_ON(devpriv->counter_dev->counters[gpct_index].mite_chan);
+	mite_chan =
+		mite_request_channel(devpriv->mite,
+		devpriv->gpct_mite_ring[gpct_index]);
+	if (mite_chan == NULL) {
+		comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock,
+			flags);
+		comedi_error(dev,
+			"failed to reserve mite dma channel for counter.");
+		return -EBUSY;
+	}
+	mite_chan->dir = direction;
+	ni_tio_set_mite_channel(&devpriv->counter_dev->counters[gpct_index],
+		mite_chan);
+	ni_set_gpct_dma_channel(dev, gpct_index, mite_chan->channel);
+	comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+	return 0;
+}
+
+#endif // PCIDMA
+
+static int ni_request_cdo_mite_channel(struct comedi_device * dev)
+{
+#ifdef PCIDMA
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+	BUG_ON(devpriv->cdo_mite_chan);
+	devpriv->cdo_mite_chan =
+		mite_request_channel(devpriv->mite, devpriv->cdo_mite_ring);
+	if (devpriv->cdo_mite_chan == NULL) {
+		comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock,
+			flags);
+		comedi_error(dev,
+			"failed to reserve mite dma channel for correlated digital outut.");
+		return -EBUSY;
+	}
+	devpriv->cdo_mite_chan->dir = COMEDI_OUTPUT;
+	ni_set_cdo_dma_channel(dev, devpriv->cdo_mite_chan->channel);
+	comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+#endif // PCIDMA
+	return 0;
+}
+
+static void ni_release_ai_mite_channel(struct comedi_device * dev)
+{
+#ifdef PCIDMA
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+	if (devpriv->ai_mite_chan) {
+		ni_set_ai_dma_channel(dev, -1);
+		mite_release_channel(devpriv->ai_mite_chan);
+		devpriv->ai_mite_chan = NULL;
+	}
+	comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+#endif // PCIDMA
+}
+
+static void ni_release_ao_mite_channel(struct comedi_device * dev)
+{
+#ifdef PCIDMA
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+	if (devpriv->ao_mite_chan) {
+		ni_set_ao_dma_channel(dev, -1);
+		mite_release_channel(devpriv->ao_mite_chan);
+		devpriv->ao_mite_chan = NULL;
+	}
+	comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+#endif // PCIDMA
+}
+
+void ni_release_gpct_mite_channel(struct comedi_device * dev, unsigned gpct_index)
+{
+#ifdef PCIDMA
+	unsigned long flags;
+
+	BUG_ON(gpct_index >= NUM_GPCT);
+	comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+	if (devpriv->counter_dev->counters[gpct_index].mite_chan) {
+		struct mite_channel *mite_chan =
+			devpriv->counter_dev->counters[gpct_index].mite_chan;
+
+		ni_set_gpct_dma_channel(dev, gpct_index, -1);
+		ni_tio_set_mite_channel(&devpriv->counter_dev->
+			counters[gpct_index], NULL);
+		mite_release_channel(mite_chan);
+	}
+	comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+#endif // PCIDMA
+}
+
+static void ni_release_cdo_mite_channel(struct comedi_device * dev)
+{
+#ifdef PCIDMA
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+	if (devpriv->cdo_mite_chan) {
+		ni_set_cdo_dma_channel(dev, -1);
+		mite_release_channel(devpriv->cdo_mite_chan);
+		devpriv->cdo_mite_chan = NULL;
+	}
+	comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+#endif // PCIDMA
+}
+
+// e-series boards use the second irq signals to generate dma requests for their counters
+#ifdef PCIDMA
+static void ni_e_series_enable_second_irq(struct comedi_device * dev,
+	unsigned gpct_index, short enable)
+{
+	if (boardtype.reg_type & ni_reg_m_series_mask)
+		return;
+	switch (gpct_index) {
+	case 0:
+		if (enable) {
+			devpriv->stc_writew(dev, G0_Gate_Second_Irq_Enable,
+				Second_IRQ_A_Enable_Register);
+		} else {
+			devpriv->stc_writew(dev, 0,
+				Second_IRQ_A_Enable_Register);
+		}
+		break;
+	case 1:
+		if (enable) {
+			devpriv->stc_writew(dev, G1_Gate_Second_Irq_Enable,
+				Second_IRQ_B_Enable_Register);
+		} else {
+			devpriv->stc_writew(dev, 0,
+				Second_IRQ_B_Enable_Register);
+		}
+		break;
+	default:
+		BUG();
+		break;
+	}
+}
+#endif // PCIDMA
+
+static void ni_clear_ai_fifo(struct comedi_device * dev)
+{
+	if (boardtype.reg_type == ni_reg_6143) {
+		// Flush the 6143 data FIFO
+		ni_writel(0x10, AIFIFO_Control_6143);	// Flush fifo
+		ni_writel(0x00, AIFIFO_Control_6143);	// Flush fifo
+		while (ni_readl(AIFIFO_Status_6143) & 0x10) ;	// Wait for complete
+	} else {
+		devpriv->stc_writew(dev, 1, ADC_FIFO_Clear);
+		if (boardtype.reg_type == ni_reg_625x) {
+			ni_writeb(0, M_Offset_Static_AI_Control(0));
+			ni_writeb(1, M_Offset_Static_AI_Control(0));
+#if 0
+			/* the NI example code does 3 convert pulses for 625x boards,
+			   but that appears to be wrong in practice. */
+			devpriv->stc_writew(dev, AI_CONVERT_Pulse,
+				AI_Command_1_Register);
+			devpriv->stc_writew(dev, AI_CONVERT_Pulse,
+				AI_Command_1_Register);
+			devpriv->stc_writew(dev, AI_CONVERT_Pulse,
+				AI_Command_1_Register);
+#endif
+		}
+	}
+}
+
+static void win_out2(struct comedi_device * dev, uint32_t data, int reg)
+{
+	devpriv->stc_writew(dev, data >> 16, reg);
+	devpriv->stc_writew(dev, data & 0xffff, reg + 1);
+}
+
+static uint32_t win_in2(struct comedi_device * dev, int reg)
+{
+	uint32_t bits;
+	bits = devpriv->stc_readw(dev, reg) << 16;
+	bits |= devpriv->stc_readw(dev, reg + 1);
+	return bits;
+}
+
+#define ao_win_out(data,addr) ni_ao_win_outw(dev,data,addr)
+static inline void ni_ao_win_outw(struct comedi_device * dev, uint16_t data, int addr)
+{
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+	ni_writew(addr, AO_Window_Address_611x);
+	ni_writew(data, AO_Window_Data_611x);
+	comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+}
+
+static inline void ni_ao_win_outl(struct comedi_device * dev, uint32_t data, int addr)
+{
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+	ni_writew(addr, AO_Window_Address_611x);
+	ni_writel(data, AO_Window_Data_611x);
+	comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+}
+
+static inline unsigned short ni_ao_win_inw(struct comedi_device * dev, int addr)
+{
+	unsigned long flags;
+	unsigned short data;
+
+	comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+	ni_writew(addr, AO_Window_Address_611x);
+	data = ni_readw(AO_Window_Data_611x);
+	comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+	return data;
+}
+
+/* ni_set_bits( ) allows different parts of the ni_mio_common driver to
+* share registers (such as Interrupt_A_Register) without interfering with
+* each other.
+*
+* NOTE: the switch/case statements are optimized out for a constant argument
+* so this is actually quite fast---  If you must wrap another function around this
+* make it inline to avoid a large speed penalty.
+*
+* value should only be 1 or 0.
+*/
+static inline void ni_set_bits(struct comedi_device * dev, int reg, unsigned bits,
+	unsigned value)
+{
+	unsigned bit_values;
+
+	if (value)
+		bit_values = bits;
+	else
+		bit_values = 0;
+	ni_set_bitfield(dev, reg, bits, bit_values);
+}
+
+static irqreturn_t ni_E_interrupt(int irq, void *d PT_REGS_ARG)
+{
+	struct comedi_device *dev = d;
+	unsigned short a_status;
+	unsigned short b_status;
+	unsigned int ai_mite_status = 0;
+	unsigned int ao_mite_status = 0;
+	unsigned long flags;
+#ifdef PCIDMA
+	struct mite_struct *mite = devpriv->mite;
+#endif
+
+	if (dev->attached == 0)
+		return IRQ_NONE;
+	smp_mb();		// make sure dev->attached is checked before handler does anything else.
+
+	// lock to avoid race with comedi_poll
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+	a_status = devpriv->stc_readw(dev, AI_Status_1_Register);
+	b_status = devpriv->stc_readw(dev, AO_Status_1_Register);
+#ifdef PCIDMA
+	if (mite) {
+		unsigned long flags_too;
+
+		comedi_spin_lock_irqsave(&devpriv->mite_channel_lock,
+			flags_too);
+		if (devpriv->ai_mite_chan) {
+			ai_mite_status = mite_get_status(devpriv->ai_mite_chan);
+			if (ai_mite_status & CHSR_LINKC)
+				writel(CHOR_CLRLC,
+					devpriv->mite->mite_io_addr +
+					MITE_CHOR(devpriv->ai_mite_chan->
+						channel));
+		}
+		if (devpriv->ao_mite_chan) {
+			ao_mite_status = mite_get_status(devpriv->ao_mite_chan);
+			if (ao_mite_status & CHSR_LINKC)
+				writel(CHOR_CLRLC,
+					mite->mite_io_addr +
+					MITE_CHOR(devpriv->ao_mite_chan->
+						channel));
+		}
+		comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock,
+			flags_too);
+	}
+#endif
+	ack_a_interrupt(dev, a_status);
+	ack_b_interrupt(dev, b_status);
+	if ((a_status & Interrupt_A_St) || (ai_mite_status & CHSR_INT))
+		handle_a_interrupt(dev, a_status, ai_mite_status);
+	if ((b_status & Interrupt_B_St) || (ao_mite_status & CHSR_INT))
+		handle_b_interrupt(dev, b_status, ao_mite_status);
+	handle_gpct_interrupt(dev, 0);
+	handle_gpct_interrupt(dev, 1);
+	handle_cdio_interrupt(dev);
+
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+	return IRQ_HANDLED;
+}
+
+#ifdef PCIDMA
+static void ni_sync_ai_dma(struct comedi_device * dev)
+{
+	struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+	if (devpriv->ai_mite_chan)
+		mite_sync_input_dma(devpriv->ai_mite_chan, s->async);
+	comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+}
+
+static void mite_handle_b_linkc(struct mite_struct *mite, struct comedi_device * dev)
+{
+	struct comedi_subdevice *s = dev->subdevices + NI_AO_SUBDEV;
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+	if (devpriv->ao_mite_chan) {
+		mite_sync_output_dma(devpriv->ao_mite_chan, s->async);
+	}
+	comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+}
+
+static int ni_ao_wait_for_dma_load(struct comedi_device * dev)
+{
+	static const int timeout = 10000;
+	int i;
+	for (i = 0; i < timeout; i++) {
+		unsigned short b_status;
+
+		b_status = devpriv->stc_readw(dev, AO_Status_1_Register);
+		if (b_status & AO_FIFO_Half_Full_St)
+			break;
+		/* if we poll too often, the pci bus activity seems
+		   to slow the dma transfer down */
+		comedi_udelay(10);
+	}
+	if (i == timeout) {
+		comedi_error(dev, "timed out waiting for dma load");
+		return -EPIPE;
+	}
+	return 0;
+}
+
+#endif //PCIDMA
+static void ni_handle_eos(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	if (devpriv->aimode == AIMODE_SCAN) {
+#ifdef PCIDMA
+		static const int timeout = 10;
+		int i;
+
+		for (i = 0; i < timeout; i++) {
+			ni_sync_ai_dma(dev);
+			if ((s->async->events & COMEDI_CB_EOS))
+				break;
+			comedi_udelay(1);
+		}
+#else
+		ni_handle_fifo_dregs(dev);
+		s->async->events |= COMEDI_CB_EOS;
+#endif
+	}
+	/* handle special case of single scan using AI_End_On_End_Of_Scan */
+	if ((devpriv->ai_cmd2 & AI_End_On_End_Of_Scan)) {
+		shutdown_ai_command(dev);
+	}
+}
+
+static void shutdown_ai_command(struct comedi_device * dev)
+{
+	struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
+
+#ifdef PCIDMA
+	ni_ai_drain_dma(dev);
+#endif
+	ni_handle_fifo_dregs(dev);
+	get_last_sample_611x(dev);
+	get_last_sample_6143(dev);
+
+	s->async->events |= COMEDI_CB_EOA;
+}
+
+static void ni_event(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	if (s->async->
+		events & (COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW | COMEDI_CB_EOA))
+	{
+		switch (s - dev->subdevices) {
+		case NI_AI_SUBDEV:
+			ni_ai_reset(dev, s);
+			break;
+		case NI_AO_SUBDEV:
+			ni_ao_reset(dev, s);
+			break;
+		case NI_GPCT0_SUBDEV:
+		case NI_GPCT1_SUBDEV:
+			ni_gpct_cancel(dev, s);
+			break;
+		case NI_DIO_SUBDEV:
+			ni_cdio_cancel(dev, s);
+			break;
+		default:
+			break;
+		}
+	}
+	comedi_event(dev, s);
+}
+
+static void handle_gpct_interrupt(struct comedi_device * dev,
+	unsigned short counter_index)
+{
+#ifdef PCIDMA
+	struct comedi_subdevice *s = dev->subdevices + NI_GPCT_SUBDEV(counter_index);
+
+	ni_tio_handle_interrupt(&devpriv->counter_dev->counters[counter_index],
+		s);
+	if (s->async->events)
+		ni_event(dev, s);
+#endif
+}
+
+static void ack_a_interrupt(struct comedi_device * dev, unsigned short a_status)
+{
+	unsigned short ack = 0;
+
+	if (a_status & AI_SC_TC_St) {
+		ack |= AI_SC_TC_Interrupt_Ack;
+	}
+	if (a_status & AI_START1_St) {
+		ack |= AI_START1_Interrupt_Ack;
+	}
+	if (a_status & AI_START_St) {
+		ack |= AI_START_Interrupt_Ack;
+	}
+	if (a_status & AI_STOP_St) {
+		/* not sure why we used to ack the START here also, instead of doing it independently. Frank Hess 2007-07-06 */
+		ack |= AI_STOP_Interrupt_Ack /*| AI_START_Interrupt_Ack */ ;
+	}
+	if (ack)
+		devpriv->stc_writew(dev, ack, Interrupt_A_Ack_Register);
+}
+
+static void handle_a_interrupt(struct comedi_device * dev, unsigned short status,
+	unsigned ai_mite_status)
+{
+	struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
+
+	//67xx boards don't have ai subdevice, but their gpct0 might generate an a interrupt
+	if (s->type == COMEDI_SUBD_UNUSED)
+		return;
+
+#ifdef DEBUG_INTERRUPT
+	rt_printk
+		("ni_mio_common: interrupt: a_status=%04x ai_mite_status=%08x\n",
+		status, ai_mite_status);
+	ni_mio_print_status_a(status);
+#endif
+#ifdef PCIDMA
+	if (ai_mite_status & CHSR_LINKC) {
+		ni_sync_ai_dma(dev);
+	}
+
+	if (ai_mite_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY |
+			CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR |
+			CHSR_SABORT | CHSR_XFERR | CHSR_LxERR_mask)) {
+		rt_printk
+			("unknown mite interrupt, ack! (ai_mite_status=%08x)\n",
+			ai_mite_status);
+		//mite_print_chsr(ai_mite_status);
+		s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+		//disable_irq(dev->irq);
+	}
+#endif
+
+	/* test for all uncommon interrupt events at the same time */
+	if (status & (AI_Overrun_St | AI_Overflow_St | AI_SC_TC_Error_St |
+			AI_SC_TC_St | AI_START1_St)) {
+		if (status == 0xffff) {
+			rt_printk
+				("ni_mio_common: a_status=0xffff.  Card removed?\n");
+			/* we probably aren't even running a command now,
+			 * so it's a good idea to be careful. */
+			if (comedi_get_subdevice_runflags(s) & SRF_RUNNING) {
+				s->async->events |=
+					COMEDI_CB_ERROR | COMEDI_CB_EOA;
+				ni_event(dev, s);
+			}
+			return;
+		}
+		if (status & (AI_Overrun_St | AI_Overflow_St |
+				AI_SC_TC_Error_St)) {
+			rt_printk("ni_mio_common: ai error a_status=%04x\n",
+				status);
+			ni_mio_print_status_a(status);
+
+			shutdown_ai_command(dev);
+
+			s->async->events |= COMEDI_CB_ERROR;
+			if (status & (AI_Overrun_St | AI_Overflow_St))
+				s->async->events |= COMEDI_CB_OVERFLOW;
+
+			ni_event(dev, s);
+
+			return;
+		}
+		if (status & AI_SC_TC_St) {
+#ifdef DEBUG_INTERRUPT
+			rt_printk("ni_mio_common: SC_TC interrupt\n");
+#endif
+			if (!devpriv->ai_continuous) {
+				shutdown_ai_command(dev);
+			}
+		}
+	}
+#ifndef PCIDMA
+	if (status & AI_FIFO_Half_Full_St) {
+		int i;
+		static const int timeout = 10;
+		/* pcmcia cards (at least 6036) seem to stop producing interrupts if we
+		 *fail to get the fifo less than half full, so loop to be sure.*/
+		for (i = 0; i < timeout; ++i) {
+			ni_handle_fifo_half_full(dev);
+			if ((devpriv->stc_readw(dev,
+						AI_Status_1_Register) &
+					AI_FIFO_Half_Full_St) == 0)
+				break;
+		}
+	}
+#endif // !PCIDMA
+
+	if ((status & AI_STOP_St)) {
+		ni_handle_eos(dev, s);
+	}
+
+	ni_event(dev, s);
+
+#ifdef DEBUG_INTERRUPT
+	status = devpriv->stc_readw(dev, AI_Status_1_Register);
+	if (status & Interrupt_A_St) {
+		rt_printk
+			("handle_a_interrupt: didn't clear interrupt? status=0x%x\n",
+			status);
+	}
+#endif
+}
+
+static void ack_b_interrupt(struct comedi_device * dev, unsigned short b_status)
+{
+	unsigned short ack = 0;
+	if (b_status & AO_BC_TC_St) {
+		ack |= AO_BC_TC_Interrupt_Ack;
+	}
+	if (b_status & AO_Overrun_St) {
+		ack |= AO_Error_Interrupt_Ack;
+	}
+	if (b_status & AO_START_St) {
+		ack |= AO_START_Interrupt_Ack;
+	}
+	if (b_status & AO_START1_St) {
+		ack |= AO_START1_Interrupt_Ack;
+	}
+	if (b_status & AO_UC_TC_St) {
+		ack |= AO_UC_TC_Interrupt_Ack;
+	}
+	if (b_status & AO_UI2_TC_St) {
+		ack |= AO_UI2_TC_Interrupt_Ack;
+	}
+	if (b_status & AO_UPDATE_St) {
+		ack |= AO_UPDATE_Interrupt_Ack;
+	}
+	if (ack)
+		devpriv->stc_writew(dev, ack, Interrupt_B_Ack_Register);
+}
+
+static void handle_b_interrupt(struct comedi_device * dev, unsigned short b_status,
+	unsigned ao_mite_status)
+{
+	struct comedi_subdevice *s = dev->subdevices + NI_AO_SUBDEV;
+	//unsigned short ack=0;
+#ifdef DEBUG_INTERRUPT
+	rt_printk("ni_mio_common: interrupt: b_status=%04x m1_status=%08x\n",
+		b_status, ao_mite_status);
+	ni_mio_print_status_b(b_status);
+#endif
+
+#ifdef PCIDMA
+	/* Currently, mite.c requires us to handle LINKC */
+	if (ao_mite_status & CHSR_LINKC) {
+		mite_handle_b_linkc(devpriv->mite, dev);
+	}
+
+	if (ao_mite_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY |
+			CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR |
+			CHSR_SABORT | CHSR_XFERR | CHSR_LxERR_mask)) {
+		rt_printk
+			("unknown mite interrupt, ack! (ao_mite_status=%08x)\n",
+			ao_mite_status);
+		//mite_print_chsr(ao_mite_status);
+		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+	}
+#endif
+
+	if (b_status == 0xffff)
+		return;
+	if (b_status & AO_Overrun_St) {
+		rt_printk
+			("ni_mio_common: AO FIFO underrun status=0x%04x status2=0x%04x\n",
+			b_status, devpriv->stc_readw(dev,
+				AO_Status_2_Register));
+		s->async->events |= COMEDI_CB_OVERFLOW;
+	}
+
+	if (b_status & AO_BC_TC_St) {
+		MDPRINTK("ni_mio_common: AO BC_TC status=0x%04x status2=0x%04x\n", b_status, devpriv->stc_readw(dev, AO_Status_2_Register));
+		s->async->events |= COMEDI_CB_EOA;
+	}
+#ifndef PCIDMA
+	if (b_status & AO_FIFO_Request_St) {
+		int ret;
+
+		ret = ni_ao_fifo_half_empty(dev, s);
+		if (!ret) {
+			rt_printk("ni_mio_common: AO buffer underrun\n");
+			ni_set_bits(dev, Interrupt_B_Enable_Register,
+				AO_FIFO_Interrupt_Enable |
+				AO_Error_Interrupt_Enable, 0);
+			s->async->events |= COMEDI_CB_OVERFLOW;
+		}
+	}
+#endif
+
+	ni_event(dev, s);
+}
+
+#ifdef DEBUG_STATUS_A
+static const char *const status_a_strings[] = {
+	"passthru0", "fifo", "G0_gate", "G0_TC",
+	"stop", "start", "sc_tc", "start1",
+	"start2", "sc_tc_error", "overflow", "overrun",
+	"fifo_empty", "fifo_half_full", "fifo_full", "interrupt_a"
+};
+
+static void ni_mio_print_status_a(int status)
+{
+	int i;
+
+	rt_printk("A status:");
+	for (i = 15; i >= 0; i--) {
+		if (status & (1 << i)) {
+			rt_printk(" %s", status_a_strings[i]);
+		}
+	}
+	rt_printk("\n");
+}
+#endif
+
+#ifdef DEBUG_STATUS_B
+static const char *const status_b_strings[] = {
+	"passthru1", "fifo", "G1_gate", "G1_TC",
+	"UI2_TC", "UPDATE", "UC_TC", "BC_TC",
+	"start1", "overrun", "start", "bc_tc_error",
+	"fifo_empty", "fifo_half_full", "fifo_full", "interrupt_b"
+};
+
+static void ni_mio_print_status_b(int status)
+{
+	int i;
+
+	rt_printk("B status:");
+	for (i = 15; i >= 0; i--) {
+		if (status & (1 << i)) {
+			rt_printk(" %s", status_b_strings[i]);
+		}
+	}
+	rt_printk("\n");
+}
+#endif
+
+#ifndef PCIDMA
+
+static void ni_ao_fifo_load(struct comedi_device * dev, struct comedi_subdevice * s, int n)
+{
+	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+	int chan;
+	int i;
+	short d;
+	u32 packed_data;
+	int range;
+	int err = 1;
+
+	chan = async->cur_chan;
+	for (i = 0; i < n; i++) {
+		err &= comedi_buf_get(async, &d);
+		if (err == 0)
+			break;
+
+		range = CR_RANGE(cmd->chanlist[chan]);
+
+		if (boardtype.reg_type & ni_reg_6xxx_mask) {
+			packed_data = d & 0xffff;
+			/* 6711 only has 16 bit wide ao fifo */
+			if (boardtype.reg_type != ni_reg_6711) {
+				err &= comedi_buf_get(async, &d);
+				if (err == 0)
+					break;
+				chan++;
+				i++;
+				packed_data |= (d << 16) & 0xffff0000;
+			}
+			ni_writel(packed_data, DAC_FIFO_Data_611x);
+		} else {
+			ni_writew(d, DAC_FIFO_Data);
+		}
+		chan++;
+		chan %= cmd->chanlist_len;
+	}
+	async->cur_chan = chan;
+	if (err == 0) {
+		async->events |= COMEDI_CB_OVERFLOW;
+	}
+}
+
+/*
+ *  There's a small problem if the FIFO gets really low and we
+ *  don't have the data to fill it.  Basically, if after we fill
+ *  the FIFO with all the data available, the FIFO is _still_
+ *  less than half full, we never clear the interrupt.  If the
+ *  IRQ is in edge mode, we never get another interrupt, because
+ *  this one wasn't cleared.  If in level mode, we get flooded
+ *  with interrupts that we can't fulfill, because nothing ever
+ *  gets put into the buffer.
+ *
+ *  This kind of situation is recoverable, but it is easier to
+ *  just pretend we had a FIFO underrun, since there is a good
+ *  chance it will happen anyway.  This is _not_ the case for
+ *  RT code, as RT code might purposely be running close to the
+ *  metal.  Needs to be fixed eventually.
+ */
+static int ni_ao_fifo_half_empty(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	int n;
+
+	n = comedi_buf_read_n_available(s->async);
+	if (n == 0) {
+		s->async->events |= COMEDI_CB_OVERFLOW;
+		return 0;
+	}
+
+	n /= sizeof(short);
+	if (n > boardtype.ao_fifo_depth / 2)
+		n = boardtype.ao_fifo_depth / 2;
+
+	ni_ao_fifo_load(dev, s, n);
+
+	s->async->events |= COMEDI_CB_BLOCK;
+
+	return 1;
+}
+
+static int ni_ao_prep_fifo(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	int n;
+
+	/* reset fifo */
+	devpriv->stc_writew(dev, 1, DAC_FIFO_Clear);
+	if (boardtype.reg_type & ni_reg_6xxx_mask)
+		ni_ao_win_outl(dev, 0x6, AO_FIFO_Offset_Load_611x);
+
+	/* load some data */
+	n = comedi_buf_read_n_available(s->async);
+	if (n == 0)
+		return 0;
+
+	n /= sizeof(short);
+	if (n > boardtype.ao_fifo_depth)
+		n = boardtype.ao_fifo_depth;
+
+	ni_ao_fifo_load(dev, s, n);
+
+	return n;
+}
+
+static void ni_ai_fifo_read(struct comedi_device * dev, struct comedi_subdevice * s, int n)
+{
+	struct comedi_async *async = s->async;
+	int i;
+
+	if (boardtype.reg_type == ni_reg_611x) {
+		short data[2];
+		u32 dl;
+
+		for (i = 0; i < n / 2; i++) {
+			dl = ni_readl(ADC_FIFO_Data_611x);
+			/* This may get the hi/lo data in the wrong order */
+			data[0] = (dl >> 16) & 0xffff;
+			data[1] = dl & 0xffff;
+			cfc_write_array_to_buffer(s, data, sizeof(data));
+		}
+		/* Check if there's a single sample stuck in the FIFO */
+		if (n % 2) {
+			dl = ni_readl(ADC_FIFO_Data_611x);
+			data[0] = dl & 0xffff;
+			cfc_write_to_buffer(s, data[0]);
+		}
+	} else if (boardtype.reg_type == ni_reg_6143) {
+		short data[2];
+		u32 dl;
+
+		// This just reads the FIFO assuming the data is present, no checks on the FIFO status are performed
+		for (i = 0; i < n / 2; i++) {
+			dl = ni_readl(AIFIFO_Data_6143);
+
+			data[0] = (dl >> 16) & 0xffff;
+			data[1] = dl & 0xffff;
+			cfc_write_array_to_buffer(s, data, sizeof(data));
+		}
+		if (n % 2) {
+			/* Assume there is a single sample stuck in the FIFO */
+			ni_writel(0x01, AIFIFO_Control_6143);	// Get stranded sample into FIFO
+			dl = ni_readl(AIFIFO_Data_6143);
+			data[0] = (dl >> 16) & 0xffff;
+			cfc_write_to_buffer(s, data[0]);
+		}
+	} else {
+		if (n > sizeof(devpriv->ai_fifo_buffer) /
+			sizeof(devpriv->ai_fifo_buffer[0])) {
+			comedi_error(dev, "bug! ai_fifo_buffer too small");
+			async->events |= COMEDI_CB_ERROR;
+			return;
+		}
+		for (i = 0; i < n; i++) {
+			devpriv->ai_fifo_buffer[i] =
+				ni_readw(ADC_FIFO_Data_Register);
+		}
+		cfc_write_array_to_buffer(s, devpriv->ai_fifo_buffer,
+			n * sizeof(devpriv->ai_fifo_buffer[0]));
+	}
+}
+
+static void ni_handle_fifo_half_full(struct comedi_device * dev)
+{
+	int n;
+	struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
+
+	n = boardtype.ai_fifo_depth / 2;
+
+	ni_ai_fifo_read(dev, s, n);
+}
+#endif
+
+#ifdef PCIDMA
+static int ni_ai_drain_dma(struct comedi_device * dev)
+{
+	int i;
+	static const int timeout = 10000;
+	unsigned long flags;
+	int retval = 0;
+
+	comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+	if (devpriv->ai_mite_chan) {
+		for (i = 0; i < timeout; i++) {
+			if ((devpriv->stc_readw(dev,
+						AI_Status_1_Register) &
+					AI_FIFO_Empty_St)
+				&& mite_bytes_in_transit(devpriv->
+					ai_mite_chan) == 0)
+				break;
+			comedi_udelay(5);
+		}
+		if (i == timeout) {
+			rt_printk
+				("ni_mio_common: wait for dma drain timed out\n");
+			rt_printk
+				("mite_bytes_in_transit=%i, AI_Status1_Register=0x%x\n",
+				mite_bytes_in_transit(devpriv->ai_mite_chan),
+				devpriv->stc_readw(dev, AI_Status_1_Register));
+			retval = -1;
+		}
+	}
+	comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+
+	ni_sync_ai_dma(dev);
+
+	return retval;
+}
+#endif
+/*
+   Empties the AI fifo
+*/
+static void ni_handle_fifo_dregs(struct comedi_device * dev)
+{
+	struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
+	short data[2];
+	u32 dl;
+	short fifo_empty;
+	int i;
+
+	if (boardtype.reg_type == ni_reg_611x) {
+		while ((devpriv->stc_readw(dev,
+					AI_Status_1_Register) &
+				AI_FIFO_Empty_St) == 0) {
+			dl = ni_readl(ADC_FIFO_Data_611x);
+
+			/* This may get the hi/lo data in the wrong order */
+			data[0] = (dl >> 16);
+			data[1] = (dl & 0xffff);
+			cfc_write_array_to_buffer(s, data, sizeof(data));
+		}
+	} else if (boardtype.reg_type == ni_reg_6143) {
+		i = 0;
+		while (ni_readl(AIFIFO_Status_6143) & 0x04) {
+			dl = ni_readl(AIFIFO_Data_6143);
+
+			/* This may get the hi/lo data in the wrong order */
+			data[0] = (dl >> 16);
+			data[1] = (dl & 0xffff);
+			cfc_write_array_to_buffer(s, data, sizeof(data));
+			i += 2;
+		}
+		// Check if stranded sample is present
+		if (ni_readl(AIFIFO_Status_6143) & 0x01) {
+			ni_writel(0x01, AIFIFO_Control_6143);	// Get stranded sample into FIFO
+			dl = ni_readl(AIFIFO_Data_6143);
+			data[0] = (dl >> 16) & 0xffff;
+			cfc_write_to_buffer(s, data[0]);
+		}
+
+	} else {
+		fifo_empty =
+			devpriv->stc_readw(dev,
+			AI_Status_1_Register) & AI_FIFO_Empty_St;
+		while (fifo_empty == 0) {
+			for (i = 0;
+				i <
+				sizeof(devpriv->ai_fifo_buffer) /
+				sizeof(devpriv->ai_fifo_buffer[0]); i++) {
+				fifo_empty =
+					devpriv->stc_readw(dev,
+					AI_Status_1_Register) &
+					AI_FIFO_Empty_St;
+				if (fifo_empty)
+					break;
+				devpriv->ai_fifo_buffer[i] =
+					ni_readw(ADC_FIFO_Data_Register);
+			}
+			cfc_write_array_to_buffer(s, devpriv->ai_fifo_buffer,
+				i * sizeof(devpriv->ai_fifo_buffer[0]));
+		}
+	}
+}
+
+static void get_last_sample_611x(struct comedi_device * dev)
+{
+	struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
+	short data;
+	u32 dl;
+
+	if (boardtype.reg_type != ni_reg_611x)
+		return;
+
+	/* Check if there's a single sample stuck in the FIFO */
+	if (ni_readb(XXX_Status) & 0x80) {
+		dl = ni_readl(ADC_FIFO_Data_611x);
+		data = (dl & 0xffff);
+		cfc_write_to_buffer(s, data);
+	}
+}
+
+static void get_last_sample_6143(struct comedi_device * dev)
+{
+	struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
+	short data;
+	u32 dl;
+
+	if (boardtype.reg_type != ni_reg_6143)
+		return;
+
+	/* Check if there's a single sample stuck in the FIFO */
+	if (ni_readl(AIFIFO_Status_6143) & 0x01) {
+		ni_writel(0x01, AIFIFO_Control_6143);	// Get stranded sample into FIFO
+		dl = ni_readl(AIFIFO_Data_6143);
+
+		/* This may get the hi/lo data in the wrong order */
+		data = (dl >> 16) & 0xffff;
+		cfc_write_to_buffer(s, data);
+	}
+}
+
+static void ni_ai_munge(struct comedi_device * dev, struct comedi_subdevice * s,
+	void *data, unsigned int num_bytes, unsigned int chan_index)
+{
+	struct comedi_async *async = s->async;
+	unsigned int i;
+	unsigned int length = num_bytes / bytes_per_sample(s);
+	short *array = data;
+	unsigned int *larray = data;
+	for (i = 0; i < length; i++) {
+#ifdef PCIDMA
+		if (s->subdev_flags & SDF_LSAMPL)
+			larray[i] = le32_to_cpu(larray[i]);
+		else
+			array[i] = le16_to_cpu(array[i]);
+#endif
+		if (s->subdev_flags & SDF_LSAMPL)
+			larray[i] += devpriv->ai_offset[chan_index];
+		else
+			array[i] += devpriv->ai_offset[chan_index];
+		chan_index++;
+		chan_index %= async->cmd.chanlist_len;
+	}
+}
+
+#ifdef PCIDMA
+
+static int ni_ai_setup_MITE_dma(struct comedi_device * dev)
+{
+	struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
+	int retval;
+	unsigned long flags;
+
+	retval = ni_request_ai_mite_channel(dev);
+	if (retval)
+		return retval;
+//      rt_printk("comedi_debug: using mite channel %i for ai.\n", devpriv->ai_mite_chan->channel);
+
+	/* write alloc the entire buffer */
+	comedi_buf_write_alloc(s->async, s->async->prealloc_bufsz);
+
+	comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+	if(devpriv->ai_mite_chan == NULL)
+	{
+		comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+		return -EIO;
+	}
+
+	switch (boardtype.reg_type) {
+	case ni_reg_611x:
+	case ni_reg_6143:
+		mite_prep_dma(devpriv->ai_mite_chan, 32, 16);
+		break;
+	case ni_reg_628x:
+		mite_prep_dma(devpriv->ai_mite_chan, 32, 32);
+		break;
+	default:
+		mite_prep_dma(devpriv->ai_mite_chan, 16, 16);
+		break;
+	};
+	/*start the MITE */
+	mite_dma_arm(devpriv->ai_mite_chan);
+	comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+
+	return 0;
+}
+
+static int ni_ao_setup_MITE_dma(struct comedi_device * dev)
+{
+	struct comedi_subdevice *s = dev->subdevices + NI_AO_SUBDEV;
+	int retval;
+	unsigned long flags;
+
+	retval = ni_request_ao_mite_channel(dev);
+	if (retval)
+		return retval;
+
+	/* read alloc the entire buffer */
+	comedi_buf_read_alloc(s->async, s->async->prealloc_bufsz);
+
+	comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+	if (devpriv->ao_mite_chan) {
+		if (boardtype.reg_type & (ni_reg_611x | ni_reg_6713)) {
+			mite_prep_dma(devpriv->ao_mite_chan, 32, 32);
+		} else {
+			/* doing 32 instead of 16 bit wide transfers from memory
+			   makes the mite do 32 bit pci transfers, doubling pci bandwidth. */
+			mite_prep_dma(devpriv->ao_mite_chan, 16, 32);
+		}
+		mite_dma_arm(devpriv->ao_mite_chan);
+	} else
+		retval = -EIO;
+	comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+
+	return retval;
+}
+
+#endif // PCIDMA
+
+/*
+   used for both cancel ioctl and board initialization
+
+   this is pretty harsh for a cancel, but it works...
+ */
+
+static int ni_ai_reset(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	ni_release_ai_mite_channel(dev);
+	/* ai configuration */
+	devpriv->stc_writew(dev, AI_Configuration_Start | AI_Reset,
+		Joint_Reset_Register);
+
+	ni_set_bits(dev, Interrupt_A_Enable_Register,
+		AI_SC_TC_Interrupt_Enable | AI_START1_Interrupt_Enable |
+		AI_START2_Interrupt_Enable | AI_START_Interrupt_Enable |
+		AI_STOP_Interrupt_Enable | AI_Error_Interrupt_Enable |
+		AI_FIFO_Interrupt_Enable, 0);
+
+	ni_clear_ai_fifo(dev);
+
+	if (boardtype.reg_type != ni_reg_6143)
+		ni_writeb(0, Misc_Command);
+
+	devpriv->stc_writew(dev, AI_Disarm, AI_Command_1_Register);	/* reset pulses */
+	devpriv->stc_writew(dev,
+		AI_Start_Stop | AI_Mode_1_Reserved /*| AI_Trigger_Once */ ,
+		AI_Mode_1_Register);
+	devpriv->stc_writew(dev, 0x0000, AI_Mode_2_Register);
+	/* generate FIFO interrupts on non-empty */
+	devpriv->stc_writew(dev, (0 << 6) | 0x0000, AI_Mode_3_Register);
+	if (boardtype.reg_type == ni_reg_611x) {
+		devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width |
+			AI_SOC_Polarity |
+			AI_LOCALMUX_CLK_Pulse_Width, AI_Personal_Register);
+		devpriv->stc_writew(dev, AI_SCAN_IN_PROG_Output_Select(3) |
+			AI_EXTMUX_CLK_Output_Select(0) |
+			AI_LOCALMUX_CLK_Output_Select(2) |
+			AI_SC_TC_Output_Select(3) |
+			AI_CONVERT_Output_Select(AI_CONVERT_Output_Enable_High),
+			AI_Output_Control_Register);
+	} else if (boardtype.reg_type == ni_reg_6143) {
+		devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width |
+			AI_SOC_Polarity |
+			AI_LOCALMUX_CLK_Pulse_Width, AI_Personal_Register);
+		devpriv->stc_writew(dev, AI_SCAN_IN_PROG_Output_Select(3) |
+			AI_EXTMUX_CLK_Output_Select(0) |
+			AI_LOCALMUX_CLK_Output_Select(2) |
+			AI_SC_TC_Output_Select(3) |
+			AI_CONVERT_Output_Select(AI_CONVERT_Output_Enable_Low),
+			AI_Output_Control_Register);
+	} else {
+		unsigned ai_output_control_bits;
+		devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width |
+			AI_SOC_Polarity |
+			AI_CONVERT_Pulse_Width |
+			AI_LOCALMUX_CLK_Pulse_Width, AI_Personal_Register);
+		ai_output_control_bits = AI_SCAN_IN_PROG_Output_Select(3) |
+			AI_EXTMUX_CLK_Output_Select(0) |
+			AI_LOCALMUX_CLK_Output_Select(2) |
+			AI_SC_TC_Output_Select(3);
+		if (boardtype.reg_type == ni_reg_622x)
+			ai_output_control_bits |=
+				AI_CONVERT_Output_Select
+				(AI_CONVERT_Output_Enable_High);
+		else
+			ai_output_control_bits |=
+				AI_CONVERT_Output_Select
+				(AI_CONVERT_Output_Enable_Low);
+		devpriv->stc_writew(dev, ai_output_control_bits,
+			AI_Output_Control_Register);
+	}
+	/* the following registers should not be changed, because there
+	 * are no backup registers in devpriv.  If you want to change
+	 * any of these, add a backup register and other appropriate code:
+	 *      AI_Mode_1_Register
+	 *      AI_Mode_3_Register
+	 *      AI_Personal_Register
+	 *      AI_Output_Control_Register
+	 */
+	devpriv->stc_writew(dev, AI_SC_TC_Error_Confirm | AI_START_Interrupt_Ack | AI_START2_Interrupt_Ack | AI_START1_Interrupt_Ack | AI_SC_TC_Interrupt_Ack | AI_Error_Interrupt_Ack | AI_STOP_Interrupt_Ack, Interrupt_A_Ack_Register);	/* clear interrupts */
+
+	devpriv->stc_writew(dev, AI_Configuration_End, Joint_Reset_Register);
+
+	return 0;
+}
+
+static int ni_ai_poll(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	unsigned long flags = 0;
+	int count;
+
+	// lock to avoid race with interrupt handler
+	if (in_interrupt() == 0)
+		comedi_spin_lock_irqsave(&dev->spinlock, flags);
+#ifndef PCIDMA
+	ni_handle_fifo_dregs(dev);
+#else
+	ni_sync_ai_dma(dev);
+#endif
+	count = s->async->buf_write_count - s->async->buf_read_count;
+	if (in_interrupt() == 0)
+		comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	return count;
+}
+
+static int ni_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i, n;
+	const unsigned int mask = (1 << boardtype.adbits) - 1;
+	unsigned signbits;
+	unsigned short d;
+	unsigned long dl;
+
+	ni_load_channelgain_list(dev, 1, &insn->chanspec);
+
+	ni_clear_ai_fifo(dev);
+
+	signbits = devpriv->ai_offset[0];
+	if (boardtype.reg_type == ni_reg_611x) {
+		for (n = 0; n < num_adc_stages_611x; n++) {
+			devpriv->stc_writew(dev, AI_CONVERT_Pulse,
+				AI_Command_1_Register);
+			comedi_udelay(1);
+		}
+		for (n = 0; n < insn->n; n++) {
+			devpriv->stc_writew(dev, AI_CONVERT_Pulse,
+				AI_Command_1_Register);
+			/* The 611x has screwy 32-bit FIFOs. */
+			d = 0;
+			for (i = 0; i < NI_TIMEOUT; i++) {
+				if (ni_readb(XXX_Status) & 0x80) {
+					d = (ni_readl(ADC_FIFO_Data_611x) >> 16)
+						& 0xffff;
+					break;
+				}
+				if (!(devpriv->stc_readw(dev,
+							AI_Status_1_Register) &
+						AI_FIFO_Empty_St)) {
+					d = ni_readl(ADC_FIFO_Data_611x) &
+						0xffff;
+					break;
+				}
+			}
+			if (i == NI_TIMEOUT) {
+				rt_printk
+					("ni_mio_common: timeout in 611x ni_ai_insn_read\n");
+				return -ETIME;
+			}
+			d += signbits;
+			data[n] = d;
+		}
+	} else if (boardtype.reg_type == ni_reg_6143) {
+		for (n = 0; n < insn->n; n++) {
+			devpriv->stc_writew(dev, AI_CONVERT_Pulse,
+				AI_Command_1_Register);
+
+			/* The 6143 has 32-bit FIFOs. You need to strobe a bit to move a single 16bit stranded sample into the FIFO */
+			dl = 0;
+			for (i = 0; i < NI_TIMEOUT; i++) {
+				if (ni_readl(AIFIFO_Status_6143) & 0x01) {
+					ni_writel(0x01, AIFIFO_Control_6143);	// Get stranded sample into FIFO
+					dl = ni_readl(AIFIFO_Data_6143);
+					break;
+				}
+			}
+			if (i == NI_TIMEOUT) {
+				rt_printk
+					("ni_mio_common: timeout in 6143 ni_ai_insn_read\n");
+				return -ETIME;
+			}
+			data[n] = (((dl >> 16) & 0xFFFF) + signbits) & 0xFFFF;
+		}
+	} else {
+		for (n = 0; n < insn->n; n++) {
+			devpriv->stc_writew(dev, AI_CONVERT_Pulse,
+				AI_Command_1_Register);
+			for (i = 0; i < NI_TIMEOUT; i++) {
+				if (!(devpriv->stc_readw(dev,
+							AI_Status_1_Register) &
+						AI_FIFO_Empty_St))
+					break;
+			}
+			if (i == NI_TIMEOUT) {
+				rt_printk
+					("ni_mio_common: timeout in ni_ai_insn_read\n");
+				return -ETIME;
+			}
+			if (boardtype.reg_type & ni_reg_m_series_mask) {
+				data[n] =
+					ni_readl(M_Offset_AI_FIFO_Data) & mask;
+			} else {
+				d = ni_readw(ADC_FIFO_Data_Register);
+				d += signbits;	/* subtle: needs to be short addition */
+				data[n] = d;
+			}
+		}
+	}
+	return insn->n;
+}
+
+void ni_prime_channelgain_list(struct comedi_device * dev)
+{
+	int i;
+	devpriv->stc_writew(dev, AI_CONVERT_Pulse, AI_Command_1_Register);
+	for (i = 0; i < NI_TIMEOUT; ++i) {
+		if (!(devpriv->stc_readw(dev,
+					AI_Status_1_Register) &
+				AI_FIFO_Empty_St)) {
+			devpriv->stc_writew(dev, 1, ADC_FIFO_Clear);
+			return;
+		}
+		comedi_udelay(1);
+	}
+	rt_printk("ni_mio_common: timeout loading channel/gain list\n");
+}
+
+static void ni_m_series_load_channelgain_list(struct comedi_device * dev,
+	unsigned int n_chan, unsigned int *list)
+{
+	unsigned int chan, range, aref;
+	unsigned int i;
+	unsigned offset;
+	unsigned int dither;
+	unsigned range_code;
+
+	devpriv->stc_writew(dev, 1, Configuration_Memory_Clear);
+
+//      offset = 1 << (boardtype.adbits - 1);
+	if ((list[0] & CR_ALT_SOURCE)) {
+		unsigned bypass_bits;
+		chan = CR_CHAN(list[0]);
+		range = CR_RANGE(list[0]);
+		range_code = ni_gainlkup[boardtype.gainlkup][range];
+		dither = ((list[0] & CR_ALT_FILTER) != 0);
+		bypass_bits = MSeries_AI_Bypass_Config_FIFO_Bit;
+		bypass_bits |= chan;
+		bypass_bits |=
+			(devpriv->
+			ai_calib_source) & (MSeries_AI_Bypass_Cal_Sel_Pos_Mask |
+			MSeries_AI_Bypass_Cal_Sel_Neg_Mask |
+			MSeries_AI_Bypass_Mode_Mux_Mask |
+			MSeries_AO_Bypass_AO_Cal_Sel_Mask);
+		bypass_bits |= MSeries_AI_Bypass_Gain_Bits(range_code);
+		if (dither)
+			bypass_bits |= MSeries_AI_Bypass_Dither_Bit;
+		// don't use 2's complement encoding
+		bypass_bits |= MSeries_AI_Bypass_Polarity_Bit;
+		ni_writel(bypass_bits, M_Offset_AI_Config_FIFO_Bypass);
+	} else {
+		ni_writel(0, M_Offset_AI_Config_FIFO_Bypass);
+	}
+	offset = 0;
+	for (i = 0; i < n_chan; i++) {
+		unsigned config_bits = 0;
+		chan = CR_CHAN(list[i]);
+		aref = CR_AREF(list[i]);
+		range = CR_RANGE(list[i]);
+		dither = ((list[i] & CR_ALT_FILTER) != 0);
+
+		range_code = ni_gainlkup[boardtype.gainlkup][range];
+		devpriv->ai_offset[i] = offset;
+		switch (aref) {
+		case AREF_DIFF:
+			config_bits |=
+				MSeries_AI_Config_Channel_Type_Differential_Bits;
+			break;
+		case AREF_COMMON:
+			config_bits |=
+				MSeries_AI_Config_Channel_Type_Common_Ref_Bits;
+			break;
+		case AREF_GROUND:
+			config_bits |=
+				MSeries_AI_Config_Channel_Type_Ground_Ref_Bits;
+			break;
+		case AREF_OTHER:
+			break;
+		}
+		config_bits |= MSeries_AI_Config_Channel_Bits(chan);
+		config_bits |=
+			MSeries_AI_Config_Bank_Bits(boardtype.reg_type, chan);
+		config_bits |= MSeries_AI_Config_Gain_Bits(range_code);
+		if (i == n_chan - 1)
+			config_bits |= MSeries_AI_Config_Last_Channel_Bit;
+		if (dither)
+			config_bits |= MSeries_AI_Config_Dither_Bit;
+		// don't use 2's complement encoding
+		config_bits |= MSeries_AI_Config_Polarity_Bit;
+		ni_writew(config_bits, M_Offset_AI_Config_FIFO_Data);
+	}
+	ni_prime_channelgain_list(dev);
+}
+
+/*
+ * Notes on the 6110 and 6111:
+ * These boards a slightly different than the rest of the series, since
+ * they have multiple A/D converters.
+ * From the driver side, the configuration memory is a
+ * little different.
+ * Configuration Memory Low:
+ *   bits 15-9: same
+ *   bit 8: unipolar/bipolar (should be 0 for bipolar)
+ *   bits 0-3: gain.  This is 4 bits instead of 3 for the other boards
+ *       1001 gain=0.1 (+/- 50)
+ *       1010 0.2
+ *       1011 0.1
+ *       0001 1
+ *       0010 2
+ *       0011 5
+ *       0100 10
+ *       0101 20
+ *       0110 50
+ * Configuration Memory High:
+ *   bits 12-14: Channel Type
+ *       001 for differential
+ *       000 for calibration
+ *   bit 11: coupling  (this is not currently handled)
+ *       1 AC coupling
+ *       0 DC coupling
+ *   bits 0-2: channel
+ *       valid channels are 0-3
+ */
+static void ni_load_channelgain_list(struct comedi_device * dev, unsigned int n_chan,
+	unsigned int *list)
+{
+	unsigned int chan, range, aref;
+	unsigned int i;
+	unsigned int hi, lo;
+	unsigned offset;
+	unsigned int dither;
+
+	if (boardtype.reg_type & ni_reg_m_series_mask) {
+		ni_m_series_load_channelgain_list(dev, n_chan, list);
+		return;
+	}
+	if (n_chan == 1 && (boardtype.reg_type != ni_reg_611x)
+		&& (boardtype.reg_type != ni_reg_6143)) {
+		if (devpriv->changain_state
+			&& devpriv->changain_spec == list[0]) {
+			// ready to go.
+			return;
+		}
+		devpriv->changain_state = 1;
+		devpriv->changain_spec = list[0];
+	} else {
+		devpriv->changain_state = 0;
+	}
+
+	devpriv->stc_writew(dev, 1, Configuration_Memory_Clear);
+
+	// Set up Calibration mode if required
+	if (boardtype.reg_type == ni_reg_6143) {
+		if ((list[0] & CR_ALT_SOURCE)
+			&& !devpriv->ai_calib_source_enabled) {
+			// Strobe Relay enable bit
+			ni_writew(devpriv->
+				ai_calib_source |
+				Calibration_Channel_6143_RelayOn,
+				Calibration_Channel_6143);
+			ni_writew(devpriv->ai_calib_source,
+				Calibration_Channel_6143);
+			devpriv->ai_calib_source_enabled = 1;
+			msleep_interruptible(100);	// Allow relays to change
+		} else if (!(list[0] & CR_ALT_SOURCE)
+			&& devpriv->ai_calib_source_enabled) {
+			// Strobe Relay disable bit
+			ni_writew(devpriv->
+				ai_calib_source |
+				Calibration_Channel_6143_RelayOff,
+				Calibration_Channel_6143);
+			ni_writew(devpriv->ai_calib_source,
+				Calibration_Channel_6143);
+			devpriv->ai_calib_source_enabled = 0;
+			msleep_interruptible(100);	// Allow relays to change
+		}
+	}
+
+	offset = 1 << (boardtype.adbits - 1);
+	for (i = 0; i < n_chan; i++) {
+		if ((boardtype.reg_type != ni_reg_6143)
+			&& (list[i] & CR_ALT_SOURCE)) {
+			chan = devpriv->ai_calib_source;
+		} else {
+			chan = CR_CHAN(list[i]);
+		}
+		aref = CR_AREF(list[i]);
+		range = CR_RANGE(list[i]);
+		dither = ((list[i] & CR_ALT_FILTER) != 0);
+
+		/* fix the external/internal range differences */
+		range = ni_gainlkup[boardtype.gainlkup][range];
+		if (boardtype.reg_type == ni_reg_611x)
+			devpriv->ai_offset[i] = offset;
+		else
+			devpriv->ai_offset[i] = (range & 0x100) ? 0 : offset;
+
+		hi = 0;
+		if ((list[i] & CR_ALT_SOURCE)) {
+			if (boardtype.reg_type == ni_reg_611x)
+				ni_writew(CR_CHAN(list[i]) & 0x0003,
+					Calibration_Channel_Select_611x);
+		} else {
+			if (boardtype.reg_type == ni_reg_611x)
+				aref = AREF_DIFF;
+			else if (boardtype.reg_type == ni_reg_6143)
+				aref = AREF_OTHER;
+			switch (aref) {
+			case AREF_DIFF:
+				hi |= AI_DIFFERENTIAL;
+				break;
+			case AREF_COMMON:
+				hi |= AI_COMMON;
+				break;
+			case AREF_GROUND:
+				hi |= AI_GROUND;
+				break;
+			case AREF_OTHER:
+				break;
+			}
+		}
+		hi |= AI_CONFIG_CHANNEL(chan);
+
+		ni_writew(hi, Configuration_Memory_High);
+
+		if (boardtype.reg_type != ni_reg_6143) {
+			lo = range;
+			if (i == n_chan - 1)
+				lo |= AI_LAST_CHANNEL;
+			if (dither)
+				lo |= AI_DITHER;
+
+			ni_writew(lo, Configuration_Memory_Low);
+		}
+	}
+
+	/* prime the channel/gain list */
+	if ((boardtype.reg_type != ni_reg_611x)
+		&& (boardtype.reg_type != ni_reg_6143)) {
+		ni_prime_channelgain_list(dev);
+	}
+}
+
+static int ni_ns_to_timer(const struct comedi_device * dev, unsigned nanosec,
+	int round_mode)
+{
+	int divider;
+	switch (round_mode) {
+	case TRIG_ROUND_NEAREST:
+	default:
+		divider = (nanosec + devpriv->clock_ns / 2) / devpriv->clock_ns;
+		break;
+	case TRIG_ROUND_DOWN:
+		divider = (nanosec) / devpriv->clock_ns;
+		break;
+	case TRIG_ROUND_UP:
+		divider = (nanosec + devpriv->clock_ns - 1) / devpriv->clock_ns;
+		break;
+	}
+	return divider - 1;
+}
+
+static unsigned ni_timer_to_ns(const struct comedi_device * dev, int timer)
+{
+	return devpriv->clock_ns * (timer + 1);
+}
+
+static unsigned ni_min_ai_scan_period_ns(struct comedi_device * dev,
+	unsigned num_channels)
+{
+	switch (boardtype.reg_type) {
+	case ni_reg_611x:
+	case ni_reg_6143:
+		// simultaneously-sampled inputs
+		return boardtype.ai_speed;
+		break;
+	default:
+		// multiplexed inputs
+		break;
+	};
+	return boardtype.ai_speed * num_channels;
+}
+
+static int ni_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp;
+	int sources;
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	if ((cmd->flags & CMDF_WRITE)) {
+		cmd->flags &= ~CMDF_WRITE;
+	}
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW | TRIG_INT | TRIG_EXT;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	sources = TRIG_TIMER | TRIG_EXT;
+	if ((boardtype.reg_type == ni_reg_611x)
+		|| (boardtype.reg_type == ni_reg_6143))
+		sources |= TRIG_NOW;
+	cmd->convert_src &= sources;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	/* note that mutual compatiblity is not an issue here */
+	if (cmd->start_src != TRIG_NOW &&
+		cmd->start_src != TRIG_INT && cmd->start_src != TRIG_EXT)
+		err++;
+	if (cmd->scan_begin_src != TRIG_TIMER &&
+		cmd->scan_begin_src != TRIG_EXT &&
+		cmd->scan_begin_src != TRIG_OTHER)
+		err++;
+	if (cmd->convert_src != TRIG_TIMER &&
+		cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
+		err++;
+	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->start_src == TRIG_EXT) {
+		/* external trigger */
+		unsigned int tmp = CR_CHAN(cmd->start_arg);
+
+		if (tmp > 16)
+			tmp = 16;
+		tmp |= (cmd->start_arg & (CR_INVERT | CR_EDGE));
+		if (cmd->start_arg != tmp) {
+			cmd->start_arg = tmp;
+			err++;
+		}
+	} else {
+		if (cmd->start_arg != 0) {
+			/* true for both TRIG_NOW and TRIG_INT */
+			cmd->start_arg = 0;
+			err++;
+		}
+	}
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		if (cmd->scan_begin_arg < ni_min_ai_scan_period_ns(dev,
+				cmd->chanlist_len)) {
+			cmd->scan_begin_arg =
+				ni_min_ai_scan_period_ns(dev,
+				cmd->chanlist_len);
+			err++;
+		}
+		if (cmd->scan_begin_arg > devpriv->clock_ns * 0xffffff) {
+			cmd->scan_begin_arg = devpriv->clock_ns * 0xffffff;
+			err++;
+		}
+	} else if (cmd->scan_begin_src == TRIG_EXT) {
+		/* external trigger */
+		unsigned int tmp = CR_CHAN(cmd->scan_begin_arg);
+
+		if (tmp > 16)
+			tmp = 16;
+		tmp |= (cmd->scan_begin_arg & (CR_INVERT | CR_EDGE));
+		if (cmd->scan_begin_arg != tmp) {
+			cmd->scan_begin_arg = tmp;
+			err++;
+		}
+	} else {		/* TRIG_OTHER */
+		if (cmd->scan_begin_arg) {
+			cmd->scan_begin_arg = 0;
+			err++;
+		}
+	}
+	if (cmd->convert_src == TRIG_TIMER) {
+		if ((boardtype.reg_type == ni_reg_611x)
+			|| (boardtype.reg_type == ni_reg_6143)) {
+			if (cmd->convert_arg != 0) {
+				cmd->convert_arg = 0;
+				err++;
+			}
+		} else {
+			if (cmd->convert_arg < boardtype.ai_speed) {
+				cmd->convert_arg = boardtype.ai_speed;
+				err++;
+			}
+			if (cmd->convert_arg > devpriv->clock_ns * 0xffff) {
+				cmd->convert_arg = devpriv->clock_ns * 0xffff;
+				err++;
+			}
+		}
+	} else if (cmd->convert_src == TRIG_EXT) {
+		/* external trigger */
+		unsigned int tmp = CR_CHAN(cmd->convert_arg);
+
+		if (tmp > 16)
+			tmp = 16;
+		tmp |= (cmd->convert_arg & (CR_ALT_FILTER | CR_INVERT));
+		if (cmd->convert_arg != tmp) {
+			cmd->convert_arg = tmp;
+			err++;
+		}
+	} else if (cmd->convert_src == TRIG_NOW) {
+		if (cmd->convert_arg != 0) {
+			cmd->convert_arg = 0;
+			err++;
+		}
+	}
+
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+	if (cmd->stop_src == TRIG_COUNT) {
+		unsigned int max_count = 0x01000000;
+
+		if (boardtype.reg_type == ni_reg_611x)
+			max_count -= num_adc_stages_611x;
+		if (cmd->stop_arg > max_count) {
+			cmd->stop_arg = max_count;
+			err++;
+		}
+		if (cmd->stop_arg < 1) {
+			cmd->stop_arg = 1;
+			err++;
+		}
+	} else {
+		/* TRIG_NONE */
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		tmp = cmd->scan_begin_arg;
+		cmd->scan_begin_arg =
+			ni_timer_to_ns(dev, ni_ns_to_timer(dev,
+				cmd->scan_begin_arg,
+				cmd->flags & TRIG_ROUND_MASK));
+		if (tmp != cmd->scan_begin_arg)
+			err++;
+	}
+	if (cmd->convert_src == TRIG_TIMER) {
+		if ((boardtype.reg_type != ni_reg_611x)
+			&& (boardtype.reg_type != ni_reg_6143)) {
+			tmp = cmd->convert_arg;
+			cmd->convert_arg =
+				ni_timer_to_ns(dev, ni_ns_to_timer(dev,
+					cmd->convert_arg,
+					cmd->flags & TRIG_ROUND_MASK));
+			if (tmp != cmd->convert_arg)
+				err++;
+			if (cmd->scan_begin_src == TRIG_TIMER &&
+				cmd->scan_begin_arg <
+				cmd->convert_arg * cmd->scan_end_arg) {
+				cmd->scan_begin_arg =
+					cmd->convert_arg * cmd->scan_end_arg;
+				err++;
+			}
+		}
+	}
+
+	if (err)
+		return 4;
+
+	return 0;
+}
+
+static int ni_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	const struct comedi_cmd *cmd = &s->async->cmd;
+	int timer;
+	int mode1 = 0;		/* mode1 is needed for both stop and convert */
+	int mode2 = 0;
+	int start_stop_select = 0;
+	unsigned int stop_count;
+	int interrupt_a_enable = 0;
+
+	MDPRINTK("ni_ai_cmd\n");
+	if (dev->irq == 0) {
+		comedi_error(dev, "cannot run command without an irq");
+		return -EIO;
+	}
+	ni_clear_ai_fifo(dev);
+
+	ni_load_channelgain_list(dev, cmd->chanlist_len, cmd->chanlist);
+
+	/* start configuration */
+	devpriv->stc_writew(dev, AI_Configuration_Start, Joint_Reset_Register);
+
+	/* disable analog triggering for now, since it
+	 * interferes with the use of pfi0 */
+	devpriv->an_trig_etc_reg &= ~Analog_Trigger_Enable;
+	devpriv->stc_writew(dev, devpriv->an_trig_etc_reg,
+		Analog_Trigger_Etc_Register);
+
+	switch (cmd->start_src) {
+	case TRIG_INT:
+	case TRIG_NOW:
+		devpriv->stc_writew(dev, AI_START2_Select(0) |
+			AI_START1_Sync | AI_START1_Edge | AI_START1_Select(0),
+			AI_Trigger_Select_Register);
+		break;
+	case TRIG_EXT:
+		{
+			int chan = CR_CHAN(cmd->start_arg);
+			unsigned int bits = AI_START2_Select(0) |
+				AI_START1_Sync | AI_START1_Select(chan + 1);
+
+			if (cmd->start_arg & CR_INVERT)
+				bits |= AI_START1_Polarity;
+			if (cmd->start_arg & CR_EDGE)
+				bits |= AI_START1_Edge;
+			devpriv->stc_writew(dev, bits,
+				AI_Trigger_Select_Register);
+			break;
+		}
+	}
+
+	mode2 &= ~AI_Pre_Trigger;
+	mode2 &= ~AI_SC_Initial_Load_Source;
+	mode2 &= ~AI_SC_Reload_Mode;
+	devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
+
+	if (cmd->chanlist_len == 1 || (boardtype.reg_type == ni_reg_611x)
+		|| (boardtype.reg_type == ni_reg_6143)) {
+		start_stop_select |= AI_STOP_Polarity;
+		start_stop_select |= AI_STOP_Select(31);	// logic low
+		start_stop_select |= AI_STOP_Sync;
+	} else {
+		start_stop_select |= AI_STOP_Select(19);	// ai configuration memory
+	}
+	devpriv->stc_writew(dev, start_stop_select,
+		AI_START_STOP_Select_Register);
+
+	devpriv->ai_cmd2 = 0;
+	switch (cmd->stop_src) {
+	case TRIG_COUNT:
+		stop_count = cmd->stop_arg - 1;
+
+		if (boardtype.reg_type == ni_reg_611x) {
+			// have to take 3 stage adc pipeline into account
+			stop_count += num_adc_stages_611x;
+		}
+		/* stage number of scans */
+		devpriv->stc_writel(dev, stop_count, AI_SC_Load_A_Registers);
+
+		mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Trigger_Once;
+		devpriv->stc_writew(dev, mode1, AI_Mode_1_Register);
+		/* load SC (Scan Count) */
+		devpriv->stc_writew(dev, AI_SC_Load, AI_Command_1_Register);
+
+		devpriv->ai_continuous = 0;
+		if (stop_count == 0) {
+			devpriv->ai_cmd2 |= AI_End_On_End_Of_Scan;
+			interrupt_a_enable |= AI_STOP_Interrupt_Enable;
+			// this is required to get the last sample for chanlist_len > 1, not sure why
+			if (cmd->chanlist_len > 1)
+				start_stop_select |=
+					AI_STOP_Polarity | AI_STOP_Edge;
+		}
+		break;
+	case TRIG_NONE:
+		/* stage number of scans */
+		devpriv->stc_writel(dev, 0, AI_SC_Load_A_Registers);
+
+		mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Continuous;
+		devpriv->stc_writew(dev, mode1, AI_Mode_1_Register);
+
+		/* load SC (Scan Count) */
+		devpriv->stc_writew(dev, AI_SC_Load, AI_Command_1_Register);
+
+		devpriv->ai_continuous = 1;
+
+		break;
+	}
+
+	switch (cmd->scan_begin_src) {
+	case TRIG_TIMER:
+		/*
+		   stop bits for non 611x boards
+		   AI_SI_Special_Trigger_Delay=0
+		   AI_Pre_Trigger=0
+		   AI_START_STOP_Select_Register:
+		   AI_START_Polarity=0 (?)      rising edge
+		   AI_START_Edge=1              edge triggered
+		   AI_START_Sync=1 (?)
+		   AI_START_Select=0            SI_TC
+		   AI_STOP_Polarity=0           rising edge
+		   AI_STOP_Edge=0               level
+		   AI_STOP_Sync=1
+		   AI_STOP_Select=19            external pin (configuration mem)
+		 */
+		start_stop_select |= AI_START_Edge | AI_START_Sync;
+		devpriv->stc_writew(dev, start_stop_select,
+			AI_START_STOP_Select_Register);
+
+		mode2 |= AI_SI_Reload_Mode(0);
+		/* AI_SI_Initial_Load_Source=A */
+		mode2 &= ~AI_SI_Initial_Load_Source;
+		//mode2 |= AI_SC_Reload_Mode;
+		devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
+
+		/* load SI */
+		timer = ni_ns_to_timer(dev, cmd->scan_begin_arg,
+			TRIG_ROUND_NEAREST);
+		devpriv->stc_writel(dev, timer, AI_SI_Load_A_Registers);
+		devpriv->stc_writew(dev, AI_SI_Load, AI_Command_1_Register);
+		break;
+	case TRIG_EXT:
+		if (cmd->scan_begin_arg & CR_EDGE)
+			start_stop_select |= AI_START_Edge;
+		/* AI_START_Polarity==1 is falling edge */
+		if (cmd->scan_begin_arg & CR_INVERT)
+			start_stop_select |= AI_START_Polarity;
+		if (cmd->scan_begin_src != cmd->convert_src ||
+			(cmd->scan_begin_arg & ~CR_EDGE) !=
+			(cmd->convert_arg & ~CR_EDGE))
+			start_stop_select |= AI_START_Sync;
+		start_stop_select |=
+			AI_START_Select(1 + CR_CHAN(cmd->scan_begin_arg));
+		devpriv->stc_writew(dev, start_stop_select,
+			AI_START_STOP_Select_Register);
+		break;
+	}
+
+	switch (cmd->convert_src) {
+	case TRIG_TIMER:
+	case TRIG_NOW:
+		if (cmd->convert_arg == 0 || cmd->convert_src == TRIG_NOW)
+			timer = 1;
+		else
+			timer = ni_ns_to_timer(dev, cmd->convert_arg,
+				TRIG_ROUND_NEAREST);
+		devpriv->stc_writew(dev, 1, AI_SI2_Load_A_Register);	/* 0,0 does not work. */
+		devpriv->stc_writew(dev, timer, AI_SI2_Load_B_Register);
+
+		/* AI_SI2_Reload_Mode = alternate */
+		/* AI_SI2_Initial_Load_Source = A */
+		mode2 &= ~AI_SI2_Initial_Load_Source;
+		mode2 |= AI_SI2_Reload_Mode;
+		devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
+
+		/* AI_SI2_Load */
+		devpriv->stc_writew(dev, AI_SI2_Load, AI_Command_1_Register);
+
+		mode2 |= AI_SI2_Reload_Mode;	// alternate
+		mode2 |= AI_SI2_Initial_Load_Source;	// B
+
+		devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
+		break;
+	case TRIG_EXT:
+		mode1 |= AI_CONVERT_Source_Select(1 + cmd->convert_arg);
+		if ((cmd->convert_arg & CR_INVERT) == 0)
+			mode1 |= AI_CONVERT_Source_Polarity;
+		devpriv->stc_writew(dev, mode1, AI_Mode_1_Register);
+
+		mode2 |= AI_Start_Stop_Gate_Enable | AI_SC_Gate_Enable;
+		devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
+
+		break;
+	}
+
+	if (dev->irq) {
+
+		/* interrupt on FIFO, errors, SC_TC */
+		interrupt_a_enable |= AI_Error_Interrupt_Enable |
+			AI_SC_TC_Interrupt_Enable;
+
+#ifndef PCIDMA
+		interrupt_a_enable |= AI_FIFO_Interrupt_Enable;
+#endif
+
+		if (cmd->flags & TRIG_WAKE_EOS
+			|| (devpriv->ai_cmd2 & AI_End_On_End_Of_Scan)) {
+			/* wake on end-of-scan */
+			devpriv->aimode = AIMODE_SCAN;
+		} else {
+			devpriv->aimode = AIMODE_HALF_FULL;
+		}
+
+		switch (devpriv->aimode) {
+		case AIMODE_HALF_FULL:
+			/*generate FIFO interrupts and DMA requests on half-full */
+#ifdef PCIDMA
+			devpriv->stc_writew(dev, AI_FIFO_Mode_HF_to_E,
+				AI_Mode_3_Register);
+#else
+			devpriv->stc_writew(dev, AI_FIFO_Mode_HF,
+				AI_Mode_3_Register);
+#endif
+			break;
+		case AIMODE_SAMPLE:
+			/*generate FIFO interrupts on non-empty */
+			devpriv->stc_writew(dev, AI_FIFO_Mode_NE,
+				AI_Mode_3_Register);
+			break;
+		case AIMODE_SCAN:
+#ifdef PCIDMA
+			devpriv->stc_writew(dev, AI_FIFO_Mode_NE,
+				AI_Mode_3_Register);
+#else
+			devpriv->stc_writew(dev, AI_FIFO_Mode_HF,
+				AI_Mode_3_Register);
+#endif
+			interrupt_a_enable |= AI_STOP_Interrupt_Enable;
+			break;
+		default:
+			break;
+		}
+
+		devpriv->stc_writew(dev, AI_Error_Interrupt_Ack | AI_STOP_Interrupt_Ack | AI_START_Interrupt_Ack | AI_START2_Interrupt_Ack | AI_START1_Interrupt_Ack | AI_SC_TC_Interrupt_Ack | AI_SC_TC_Error_Confirm, Interrupt_A_Ack_Register);	/* clear interrupts */
+
+		ni_set_bits(dev, Interrupt_A_Enable_Register,
+			interrupt_a_enable, 1);
+
+		MDPRINTK("Interrupt_A_Enable_Register = 0x%04x\n",
+			devpriv->int_a_enable_reg);
+	} else {
+		/* interrupt on nothing */
+		ni_set_bits(dev, Interrupt_A_Enable_Register, ~0, 0);
+
+		/* XXX start polling if necessary */
+		MDPRINTK("interrupting on nothing\n");
+	}
+
+	/* end configuration */
+	devpriv->stc_writew(dev, AI_Configuration_End, Joint_Reset_Register);
+
+	switch (cmd->scan_begin_src) {
+	case TRIG_TIMER:
+		devpriv->stc_writew(dev,
+			AI_SI2_Arm | AI_SI_Arm | AI_DIV_Arm | AI_SC_Arm,
+			AI_Command_1_Register);
+		break;
+	case TRIG_EXT:
+		/* XXX AI_SI_Arm? */
+		devpriv->stc_writew(dev,
+			AI_SI2_Arm | AI_SI_Arm | AI_DIV_Arm | AI_SC_Arm,
+			AI_Command_1_Register);
+		break;
+	}
+
+#ifdef PCIDMA
+	{
+		int retval = ni_ai_setup_MITE_dma(dev);
+		if (retval)
+			return retval;
+	}
+	//mite_dump_regs(devpriv->mite);
+#endif
+
+	switch (cmd->start_src) {
+	case TRIG_NOW:
+		/* AI_START1_Pulse */
+		devpriv->stc_writew(dev, AI_START1_Pulse | devpriv->ai_cmd2,
+			AI_Command_2_Register);
+		s->async->inttrig = NULL;
+		break;
+	case TRIG_EXT:
+		s->async->inttrig = NULL;
+		break;
+	case TRIG_INT:
+		s->async->inttrig = &ni_ai_inttrig;
+		break;
+	}
+
+	MDPRINTK("exit ni_ai_cmd\n");
+
+	return 0;
+}
+
+static int ni_ai_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int trignum)
+{
+	if (trignum != 0)
+		return -EINVAL;
+
+	devpriv->stc_writew(dev, AI_START1_Pulse | devpriv->ai_cmd2,
+		AI_Command_2_Register);
+	s->async->inttrig = NULL;
+
+	return 1;
+}
+
+static int ni_ai_config_analog_trig(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+static int ni_ai_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n < 1)
+		return -EINVAL;
+
+	switch (data[0]) {
+	case INSN_CONFIG_ANALOG_TRIG:
+		return ni_ai_config_analog_trig(dev, s, insn, data);
+	case INSN_CONFIG_ALT_SOURCE:
+		if (boardtype.reg_type & ni_reg_m_series_mask) {
+			if (data[1] & ~(MSeries_AI_Bypass_Cal_Sel_Pos_Mask |
+					MSeries_AI_Bypass_Cal_Sel_Neg_Mask |
+					MSeries_AI_Bypass_Mode_Mux_Mask |
+					MSeries_AO_Bypass_AO_Cal_Sel_Mask)) {
+				return -EINVAL;
+			}
+			devpriv->ai_calib_source = data[1];
+		} else if (boardtype.reg_type == ni_reg_6143) {
+			unsigned int calib_source;
+
+			calib_source = data[1] & 0xf;
+
+			if (calib_source > 0xF)
+				return -EINVAL;
+
+			devpriv->ai_calib_source = calib_source;
+			ni_writew(calib_source, Calibration_Channel_6143);
+		} else {
+			unsigned int calib_source;
+			unsigned int calib_source_adjust;
+
+			calib_source = data[1] & 0xf;
+			calib_source_adjust = (data[1] >> 4) & 0xff;
+
+			if (calib_source >= 8)
+				return -EINVAL;
+			devpriv->ai_calib_source = calib_source;
+			if (boardtype.reg_type == ni_reg_611x) {
+				ni_writeb(calib_source_adjust,
+					Cal_Gain_Select_611x);
+			}
+		}
+		return 2;
+	default:
+		break;
+	}
+
+	return -EINVAL;
+}
+
+static int ni_ai_config_analog_trig(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int a, b, modebits;
+	int err = 0;
+
+	/* data[1] is flags
+	 * data[2] is analog line
+	 * data[3] is set level
+	 * data[4] is reset level */
+	if (!boardtype.has_analog_trig)
+		return -EINVAL;
+	if ((data[1] & 0xffff0000) != COMEDI_EV_SCAN_BEGIN) {
+		data[1] &= (COMEDI_EV_SCAN_BEGIN | 0xffff);
+		err++;
+	}
+	if (data[2] >= boardtype.n_adchan) {
+		data[2] = boardtype.n_adchan - 1;
+		err++;
+	}
+	if (data[3] > 255) {	/* a */
+		data[3] = 255;
+		err++;
+	}
+	if (data[4] > 255) {	/* b */
+		data[4] = 255;
+		err++;
+	}
+	/*
+	 * 00 ignore
+	 * 01 set
+	 * 10 reset
+	 *
+	 * modes:
+	 *   1 level:                    +b-   +a-
+	 *     high mode                00 00 01 10
+	 *     low mode                 00 00 10 01
+	 *   2 level: (a<b)
+	 *     hysteresis low mode      10 00 00 01
+	 *     hysteresis high mode     01 00 00 10
+	 *     middle mode              10 01 01 10
+	 */
+
+	a = data[3];
+	b = data[4];
+	modebits = data[1] & 0xff;
+	if (modebits & 0xf0) {
+		/* two level mode */
+		if (b < a) {
+			/* swap order */
+			a = data[4];
+			b = data[3];
+			modebits =
+				((data[1] & 0xf) << 4) | ((data[1] & 0xf0) >>
+				4);
+		}
+		devpriv->atrig_low = a;
+		devpriv->atrig_high = b;
+		switch (modebits) {
+		case 0x81:	/* low hysteresis mode */
+			devpriv->atrig_mode = 6;
+			break;
+		case 0x42:	/* high hysteresis mode */
+			devpriv->atrig_mode = 3;
+			break;
+		case 0x96:	/* middle window mode */
+			devpriv->atrig_mode = 2;
+			break;
+		default:
+			data[1] &= ~0xff;
+			err++;
+		}
+	} else {
+		/* one level mode */
+		if (b != 0) {
+			data[4] = 0;
+			err++;
+		}
+		switch (modebits) {
+		case 0x06:	/* high window mode */
+			devpriv->atrig_high = a;
+			devpriv->atrig_mode = 0;
+			break;
+		case 0x09:	/* low window mode */
+			devpriv->atrig_low = a;
+			devpriv->atrig_mode = 1;
+			break;
+		default:
+			data[1] &= ~0xff;
+			err++;
+		}
+	}
+	if (err)
+		return -EAGAIN;
+	return 5;
+}
+
+/* munge data from unsigned to 2's complement for analog output bipolar modes */
+static void ni_ao_munge(struct comedi_device * dev, struct comedi_subdevice * s,
+	void *data, unsigned int num_bytes, unsigned int chan_index)
+{
+	struct comedi_async *async = s->async;
+	unsigned int range;
+	unsigned int i;
+	unsigned int offset;
+	unsigned int length = num_bytes / sizeof(short);
+	short *array = data;
+
+	offset = 1 << (boardtype.aobits - 1);
+	for (i = 0; i < length; i++) {
+		range = CR_RANGE(async->cmd.chanlist[chan_index]);
+		if (boardtype.ao_unipolar == 0 || (range & 1) == 0)
+			array[i] -= offset;
+#ifdef PCIDMA
+		array[i] = cpu_to_le16(array[i]);
+#endif
+		chan_index++;
+		chan_index %= async->cmd.chanlist_len;
+	}
+}
+
+static int ni_m_series_ao_config_chanlist(struct comedi_device * dev,
+	struct comedi_subdevice * s, unsigned int chanspec[], unsigned int n_chans,
+	int timed)
+{
+	unsigned int range;
+	unsigned int chan;
+	unsigned int conf;
+	int i;
+	int invert = 0;
+
+	if(timed) {
+		for (i = 0; i < boardtype.n_aochan; ++i) {
+			devpriv->ao_conf[i] &= ~MSeries_AO_Update_Timed_Bit;
+			ni_writeb(devpriv->ao_conf[i], M_Offset_AO_Config_Bank(i));
+			ni_writeb(0xf, M_Offset_AO_Waveform_Order(i));
+		}
+	}
+	for (i = 0; i < n_chans; i++) {
+		const struct comedi_krange *krange;
+		chan = CR_CHAN(chanspec[i]);
+		range = CR_RANGE(chanspec[i]);
+		krange = s->range_table->range + range;
+		invert = 0;
+		conf = 0;
+		switch (krange->max - krange->min) {
+		case 20000000:
+			conf |= MSeries_AO_DAC_Reference_10V_Internal_Bits;
+			ni_writeb(0, M_Offset_AO_Reference_Attenuation(chan));
+			break;
+		case 10000000:
+			conf |= MSeries_AO_DAC_Reference_5V_Internal_Bits;
+			ni_writeb(0, M_Offset_AO_Reference_Attenuation(chan));
+			break;
+		case 4000000:
+			conf |= MSeries_AO_DAC_Reference_10V_Internal_Bits;
+			ni_writeb(MSeries_Attenuate_x5_Bit,
+				M_Offset_AO_Reference_Attenuation(chan));
+			break;
+		case 2000000:
+			conf |= MSeries_AO_DAC_Reference_5V_Internal_Bits;
+			ni_writeb(MSeries_Attenuate_x5_Bit,
+				M_Offset_AO_Reference_Attenuation(chan));
+			break;
+		default:
+			rt_printk("%s: bug! unhandled ao reference voltage\n",
+				__FUNCTION__);
+			break;
+		}
+		switch (krange->max + krange->min) {
+		case 0:
+			conf |= MSeries_AO_DAC_Offset_0V_Bits;
+			break;
+		case 10000000:
+			conf |= MSeries_AO_DAC_Offset_5V_Bits;
+			break;
+		default:
+			rt_printk("%s: bug! unhandled ao offset voltage\n",
+				__FUNCTION__);
+			break;
+		}
+		if (timed)
+			conf |= MSeries_AO_Update_Timed_Bit;
+		ni_writeb(conf, M_Offset_AO_Config_Bank(chan));
+		devpriv->ao_conf[chan] = conf;
+		ni_writeb(i, M_Offset_AO_Waveform_Order(chan));
+	}
+	return invert;
+}
+
+static int ni_old_ao_config_chanlist(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int chanspec[], unsigned int n_chans)
+{
+	unsigned int range;
+	unsigned int chan;
+	unsigned int conf;
+	int i;
+	int invert = 0;
+
+	for (i = 0; i < n_chans; i++) {
+		chan = CR_CHAN(chanspec[i]);
+		range = CR_RANGE(chanspec[i]);
+		conf = AO_Channel(chan);
+
+		if (boardtype.ao_unipolar) {
+			if ((range & 1) == 0) {
+				conf |= AO_Bipolar;
+				invert = (1 << (boardtype.aobits - 1));
+			} else {
+				invert = 0;
+			}
+			if (range & 2)
+				conf |= AO_Ext_Ref;
+		} else {
+			conf |= AO_Bipolar;
+			invert = (1 << (boardtype.aobits - 1));
+		}
+
+		/* not all boards can deglitch, but this shouldn't hurt */
+		if (chanspec[i] & CR_DEGLITCH)
+			conf |= AO_Deglitch;
+
+		/* analog reference */
+		/* AREF_OTHER connects AO ground to AI ground, i think */
+		conf |= (CR_AREF(chanspec[i]) ==
+			AREF_OTHER) ? AO_Ground_Ref : 0;
+
+		ni_writew(conf, AO_Configuration);
+		devpriv->ao_conf[chan] = conf;
+	}
+	return invert;
+}
+
+static int ni_ao_config_chanlist(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int chanspec[], unsigned int n_chans, int timed)
+{
+	if (boardtype.reg_type & ni_reg_m_series_mask)
+		return ni_m_series_ao_config_chanlist(dev, s, chanspec, n_chans,
+			timed);
+	else
+		return ni_old_ao_config_chanlist(dev, s, chanspec, n_chans);
+}
+static int ni_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	data[0] = devpriv->ao[CR_CHAN(insn->chanspec)];
+
+	return 1;
+}
+
+static int ni_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int chan = CR_CHAN(insn->chanspec);
+	unsigned int invert;
+
+	invert = ni_ao_config_chanlist(dev, s, &insn->chanspec, 1, 0);
+
+	devpriv->ao[chan] = data[0];
+
+	if (boardtype.reg_type & ni_reg_m_series_mask) {
+		ni_writew(data[0], M_Offset_DAC_Direct_Data(chan));
+	} else
+		ni_writew(data[0] ^ invert,
+			(chan) ? DAC1_Direct_Data : DAC0_Direct_Data);
+
+	return 1;
+}
+
+static int ni_ao_insn_write_671x(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int chan = CR_CHAN(insn->chanspec);
+	unsigned int invert;
+
+	ao_win_out(1 << chan, AO_Immediate_671x);
+	invert = 1 << (boardtype.aobits - 1);
+
+	ni_ao_config_chanlist(dev, s, &insn->chanspec, 1, 0);
+
+	devpriv->ao[chan] = data[0];
+	ao_win_out(data[0] ^ invert, DACx_Direct_Data_671x(chan));
+
+	return 1;
+}
+
+static int ni_ao_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	switch (data[0]) {
+	case INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE:
+		switch(data[1])
+		{
+		case COMEDI_OUTPUT:
+			data[2] = 1 + boardtype.ao_fifo_depth * sizeof(short);
+			if(devpriv->mite) data[2] += devpriv->mite->fifo_size;
+			break;
+		case COMEDI_INPUT:
+			data[2] = 0;
+			break;
+		default:
+			return -EINVAL;
+			break;
+		}
+		return 0;
+	default:
+		break;
+	}
+
+	return -EINVAL;
+}
+
+static int ni_ao_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int trignum)
+{
+	int ret;
+	int interrupt_b_bits;
+	int i;
+	static const int timeout = 1000;
+
+	if (trignum != 0)
+		return -EINVAL;
+
+	/* Null trig at beginning prevent ao start trigger from executing more than
+	   once per command (and doing things like trying to allocate the ao dma channel
+	   multiple times) */
+	s->async->inttrig = NULL;
+
+	ni_set_bits(dev, Interrupt_B_Enable_Register,
+		AO_FIFO_Interrupt_Enable | AO_Error_Interrupt_Enable, 0);
+	interrupt_b_bits = AO_Error_Interrupt_Enable;
+#ifdef PCIDMA
+	devpriv->stc_writew(dev, 1, DAC_FIFO_Clear);
+	if (boardtype.reg_type & ni_reg_6xxx_mask)
+		ni_ao_win_outl(dev, 0x6, AO_FIFO_Offset_Load_611x);
+	ret = ni_ao_setup_MITE_dma(dev);
+	if (ret)
+		return ret;
+	ret = ni_ao_wait_for_dma_load(dev);
+	if (ret < 0)
+		return ret;
+#else
+	ret = ni_ao_prep_fifo(dev, s);
+	if (ret == 0)
+		return -EPIPE;
+
+	interrupt_b_bits |= AO_FIFO_Interrupt_Enable;
+#endif
+
+	devpriv->stc_writew(dev, devpriv->ao_mode3 | AO_Not_An_UPDATE,
+		AO_Mode_3_Register);
+	devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
+	/* wait for DACs to be loaded */
+	for (i = 0; i < timeout; i++) {
+		comedi_udelay(1);
+		if ((devpriv->stc_readw(dev,
+					Joint_Status_2_Register) &
+				AO_TMRDACWRs_In_Progress_St) == 0)
+			break;
+	}
+	if (i == timeout) {
+		comedi_error(dev,
+			"timed out waiting for AO_TMRDACWRs_In_Progress_St to clear");
+		return -EIO;
+	}
+	// stc manual says we are need to clear error interrupt after AO_TMRDACWRs_In_Progress_St clears
+	devpriv->stc_writew(dev, AO_Error_Interrupt_Ack,
+		Interrupt_B_Ack_Register);
+
+	ni_set_bits(dev, Interrupt_B_Enable_Register, interrupt_b_bits, 1);
+
+	devpriv->stc_writew(dev,
+		devpriv->
+		ao_cmd1 | AO_UI_Arm | AO_UC_Arm | AO_BC_Arm |
+		AO_DAC1_Update_Mode | AO_DAC0_Update_Mode,
+		AO_Command_1_Register);
+
+	devpriv->stc_writew(dev, devpriv->ao_cmd2 | AO_START1_Pulse,
+		AO_Command_2_Register);
+
+	return 0;
+}
+
+static int ni_ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	const struct comedi_cmd *cmd = &s->async->cmd;
+	int bits;
+	int i;
+	unsigned trigvar;
+
+	if (dev->irq == 0) {
+		comedi_error(dev, "cannot run command without an irq");
+		return -EIO;
+	}
+
+	devpriv->stc_writew(dev, AO_Configuration_Start, Joint_Reset_Register);
+
+	devpriv->stc_writew(dev, AO_Disarm, AO_Command_1_Register);
+
+	if (boardtype.reg_type & ni_reg_6xxx_mask) {
+		ao_win_out(CLEAR_WG, AO_Misc_611x);
+
+		bits = 0;
+		for (i = 0; i < cmd->chanlist_len; i++) {
+			int chan;
+
+			chan = CR_CHAN(cmd->chanlist[i]);
+			bits |= 1 << chan;
+			ao_win_out(chan, AO_Waveform_Generation_611x);
+		}
+		ao_win_out(bits, AO_Timed_611x);
+	}
+
+	ni_ao_config_chanlist(dev, s, cmd->chanlist, cmd->chanlist_len, 1);
+
+	if (cmd->stop_src == TRIG_NONE) {
+		devpriv->ao_mode1 |= AO_Continuous;
+		devpriv->ao_mode1 &= ~AO_Trigger_Once;
+	} else {
+		devpriv->ao_mode1 &= ~AO_Continuous;
+		devpriv->ao_mode1 |= AO_Trigger_Once;
+	}
+	devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
+	switch (cmd->start_src) {
+	case TRIG_INT:
+	case TRIG_NOW:
+		devpriv->ao_trigger_select &=
+			~(AO_START1_Polarity | AO_START1_Select(-1));
+		devpriv->ao_trigger_select |= AO_START1_Edge | AO_START1_Sync;
+		devpriv->stc_writew(dev, devpriv->ao_trigger_select,
+			AO_Trigger_Select_Register);
+		break;
+	case TRIG_EXT:
+                devpriv->ao_trigger_select = AO_START1_Select(CR_CHAN(cmd->start_arg)+1);
+		if (cmd->start_arg & CR_INVERT)
+			devpriv->ao_trigger_select |= AO_START1_Polarity;  // 0=active high, 1=active low. see daq-stc 3-24 (p186)
+		if (cmd->start_arg & CR_EDGE)
+			devpriv->ao_trigger_select |= AO_START1_Edge;      // 0=edge detection disabled, 1=enabled
+		devpriv->stc_writew(dev, devpriv->ao_trigger_select, AO_Trigger_Select_Register);
+		break;
+	default:
+		BUG();
+		break;
+	}
+	devpriv->ao_mode3 &= ~AO_Trigger_Length;
+	devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
+
+	devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
+	devpriv->ao_mode2 &= ~AO_BC_Initial_Load_Source;
+	devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
+	if (cmd->stop_src == TRIG_NONE) {
+		devpriv->stc_writel(dev, 0xffffff, AO_BC_Load_A_Register);
+	} else {
+		devpriv->stc_writel(dev, 0, AO_BC_Load_A_Register);
+	}
+	devpriv->stc_writew(dev, AO_BC_Load, AO_Command_1_Register);
+	devpriv->ao_mode2 &= ~AO_UC_Initial_Load_Source;
+	devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
+	switch (cmd->stop_src) {
+	case TRIG_COUNT:
+		if(boardtype.reg_type & ni_reg_m_series_mask)
+		{
+			// this is how the NI example code does it for m-series boards, verified correct with 6259
+			devpriv->stc_writel(dev, cmd->stop_arg - 1, AO_UC_Load_A_Register);
+			devpriv->stc_writew(dev, AO_UC_Load, AO_Command_1_Register);
+		}else
+		{
+			devpriv->stc_writel(dev, cmd->stop_arg, AO_UC_Load_A_Register);
+			devpriv->stc_writew(dev, AO_UC_Load, AO_Command_1_Register);
+			devpriv->stc_writel(dev, cmd->stop_arg - 1,
+				AO_UC_Load_A_Register);
+		}
+		break;
+	case TRIG_NONE:
+		devpriv->stc_writel(dev, 0xffffff, AO_UC_Load_A_Register);
+		devpriv->stc_writew(dev, AO_UC_Load, AO_Command_1_Register);
+		devpriv->stc_writel(dev, 0xffffff, AO_UC_Load_A_Register);
+		break;
+	default:
+		devpriv->stc_writel(dev, 0, AO_UC_Load_A_Register);
+		devpriv->stc_writew(dev, AO_UC_Load, AO_Command_1_Register);
+		devpriv->stc_writel(dev, cmd->stop_arg, AO_UC_Load_A_Register);
+	}
+
+	devpriv->ao_mode1 &=
+		~(AO_UI_Source_Select(0x1f) | AO_UI_Source_Polarity |
+		AO_UPDATE_Source_Select(0x1f) | AO_UPDATE_Source_Polarity);
+	switch (cmd->scan_begin_src) {
+	case TRIG_TIMER:
+		devpriv->ao_cmd2 &= ~AO_BC_Gate_Enable;
+		trigvar =
+			ni_ns_to_timer(dev, cmd->scan_begin_arg,
+			TRIG_ROUND_NEAREST);
+		devpriv->stc_writel(dev, 1, AO_UI_Load_A_Register);
+		devpriv->stc_writew(dev, AO_UI_Load, AO_Command_1_Register);
+		devpriv->stc_writel(dev, trigvar, AO_UI_Load_A_Register);
+		break;
+	case TRIG_EXT:
+		devpriv->ao_mode1 |=
+			AO_UPDATE_Source_Select(cmd->scan_begin_arg);
+		if (cmd->scan_begin_arg & CR_INVERT)
+			devpriv->ao_mode1 |= AO_UPDATE_Source_Polarity;
+		devpriv->ao_cmd2 |= AO_BC_Gate_Enable;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	devpriv->stc_writew(dev, devpriv->ao_cmd2, AO_Command_2_Register);
+	devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
+	devpriv->ao_mode2 &=
+		~(AO_UI_Reload_Mode(3) | AO_UI_Initial_Load_Source);
+	devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
+
+	if (cmd->scan_end_arg > 1) {
+		devpriv->ao_mode1 |= AO_Multiple_Channels;
+		devpriv->stc_writew(dev,
+			AO_Number_Of_Channels(cmd->scan_end_arg -
+				1) |
+			AO_UPDATE_Output_Select
+			(AO_Update_Output_High_Z),
+			AO_Output_Control_Register);
+	} else {
+		unsigned bits;
+		devpriv->ao_mode1 &= ~AO_Multiple_Channels;
+		bits = AO_UPDATE_Output_Select(AO_Update_Output_High_Z);
+		if (boardtype.reg_type & (ni_reg_m_series_mask | ni_reg_6xxx_mask)) {
+			bits |= AO_Number_Of_Channels(0);
+		} else {
+			bits |= AO_Number_Of_Channels(CR_CHAN(cmd->
+					chanlist[0]));
+		}
+		devpriv->stc_writew(dev, bits,
+			AO_Output_Control_Register);
+	}
+	devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
+
+	devpriv->stc_writew(dev, AO_DAC0_Update_Mode | AO_DAC1_Update_Mode,
+		AO_Command_1_Register);
+
+	devpriv->ao_mode3 |= AO_Stop_On_Overrun_Error;
+	devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
+
+	devpriv->ao_mode2 &= ~AO_FIFO_Mode_Mask;
+#ifdef PCIDMA
+	devpriv->ao_mode2 |= AO_FIFO_Mode_HF_to_F;
+#else
+	devpriv->ao_mode2 |= AO_FIFO_Mode_HF;
+#endif
+	devpriv->ao_mode2 &= ~AO_FIFO_Retransmit_Enable;
+	devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
+
+	bits = AO_BC_Source_Select | AO_UPDATE_Pulse_Width |
+		AO_TMRDACWR_Pulse_Width;
+	if (boardtype.ao_fifo_depth)
+		bits |= AO_FIFO_Enable;
+	else
+		bits |= AO_DMA_PIO_Control;
+#if 0
+	/* F Hess: windows driver does not set AO_Number_Of_DAC_Packages bit for 6281,
+	   verified with bus analyzer. */
+	if (boardtype.reg_type & ni_reg_m_series_mask)
+		bits |= AO_Number_Of_DAC_Packages;
+#endif
+	devpriv->stc_writew(dev, bits, AO_Personal_Register);
+	// enable sending of ao dma requests
+	devpriv->stc_writew(dev, AO_AOFREQ_Enable, AO_Start_Select_Register);
+
+	devpriv->stc_writew(dev, AO_Configuration_End, Joint_Reset_Register);
+
+	if (cmd->stop_src == TRIG_COUNT) {
+		devpriv->stc_writew(dev, AO_BC_TC_Interrupt_Ack,
+			Interrupt_B_Ack_Register);
+		ni_set_bits(dev, Interrupt_B_Enable_Register,
+			AO_BC_TC_Interrupt_Enable, 1);
+	}
+
+	s->async->inttrig = &ni_ao_inttrig;
+
+	return 0;
+}
+
+static int ni_ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp;
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	if ((cmd->flags & CMDF_WRITE) == 0) {
+		cmd->flags |= CMDF_WRITE;
+	}
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_INT | TRIG_EXT;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_NOW;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->start_src == TRIG_EXT) {
+		/* external trigger */
+		unsigned int tmp = CR_CHAN(cmd->start_arg);
+
+		if (tmp > 18)
+			tmp = 18;
+		tmp |= (cmd->start_arg & (CR_INVERT | CR_EDGE));
+		if (cmd->start_arg != tmp) {
+			cmd->start_arg = tmp;
+			err++;
+		}
+	} else {
+		if (cmd->start_arg != 0) {
+			/* true for both TRIG_NOW and TRIG_INT */
+			cmd->start_arg = 0;
+			err++;
+		}
+	}
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		if (cmd->scan_begin_arg < boardtype.ao_speed) {
+			cmd->scan_begin_arg = boardtype.ao_speed;
+			err++;
+		}
+		if (cmd->scan_begin_arg > devpriv->clock_ns * 0xffffff) {	/* XXX check */
+			cmd->scan_begin_arg = devpriv->clock_ns * 0xffffff;
+			err++;
+		}
+	}
+	if (cmd->convert_arg != 0) {
+		cmd->convert_arg = 0;
+		err++;
+	}
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+	if (cmd->stop_src == TRIG_COUNT) {	/* XXX check */
+		if (cmd->stop_arg > 0x00ffffff) {
+			cmd->stop_arg = 0x00ffffff;
+			err++;
+		}
+	} else {
+		/* TRIG_NONE */
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		tmp = cmd->scan_begin_arg;
+		cmd->scan_begin_arg =
+			ni_timer_to_ns(dev, ni_ns_to_timer(dev,
+				cmd->scan_begin_arg,
+				cmd->flags & TRIG_ROUND_MASK));
+		if (tmp != cmd->scan_begin_arg)
+			err++;
+	}
+	if (err)
+		return 4;
+
+	/* step 5: fix up chanlist */
+
+	if (err)
+		return 5;
+
+	return 0;
+}
+
+static int ni_ao_reset(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	//devpriv->ao0p=0x0000;
+	//ni_writew(devpriv->ao0p,AO_Configuration);
+
+	//devpriv->ao1p=AO_Channel(1);
+	//ni_writew(devpriv->ao1p,AO_Configuration);
+
+	ni_release_ao_mite_channel(dev);
+
+	devpriv->stc_writew(dev, AO_Configuration_Start, Joint_Reset_Register);
+	devpriv->stc_writew(dev, AO_Disarm, AO_Command_1_Register);
+	ni_set_bits(dev, Interrupt_B_Enable_Register, ~0, 0);
+	devpriv->stc_writew(dev, AO_BC_Source_Select, AO_Personal_Register);
+	devpriv->stc_writew(dev, 0x3f98, Interrupt_B_Ack_Register);
+	devpriv->stc_writew(dev, AO_BC_Source_Select | AO_UPDATE_Pulse_Width |
+		AO_TMRDACWR_Pulse_Width, AO_Personal_Register);
+	devpriv->stc_writew(dev, 0, AO_Output_Control_Register);
+	devpriv->stc_writew(dev, 0, AO_Start_Select_Register);
+	devpriv->ao_cmd1 = 0;
+	devpriv->stc_writew(dev, devpriv->ao_cmd1, AO_Command_1_Register);
+	devpriv->ao_cmd2 = 0;
+	devpriv->stc_writew(dev, devpriv->ao_cmd2, AO_Command_2_Register);
+	devpriv->ao_mode1 = 0;
+	devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
+	devpriv->ao_mode2 = 0;
+	devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
+	if (boardtype.reg_type & ni_reg_m_series_mask)
+		devpriv->ao_mode3 = AO_Last_Gate_Disable;
+	else
+		devpriv->ao_mode3 = 0;
+	devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
+	devpriv->ao_trigger_select = 0;
+	devpriv->stc_writew(dev, devpriv->ao_trigger_select,
+		AO_Trigger_Select_Register);
+	if (boardtype.reg_type & ni_reg_6xxx_mask) {
+		unsigned immediate_bits = 0;
+		unsigned i;
+		for(i = 0; i < s->n_chan; ++i)
+		{
+			immediate_bits |= 1 << i;
+		}
+		ao_win_out(immediate_bits, AO_Immediate_671x);
+		ao_win_out(CLEAR_WG, AO_Misc_611x);
+	}
+	devpriv->stc_writew(dev, AO_Configuration_End, Joint_Reset_Register);
+
+	return 0;
+}
+
+// digital io
+
+static int ni_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+#ifdef DEBUG_DIO
+	rt_printk("ni_dio_insn_config() chan=%d io=%d\n",
+		CR_CHAN(insn->chanspec), data[0]);
+#endif
+	switch (data[0]) {
+	case INSN_CONFIG_DIO_OUTPUT:
+		s->io_bits |= 1 << CR_CHAN(insn->chanspec);
+		break;
+	case INSN_CONFIG_DIO_INPUT:
+		s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
+		break;
+	case INSN_CONFIG_DIO_QUERY:
+		data[1] =
+			(s->io_bits & (1 << CR_CHAN(insn->
+					chanspec))) ? COMEDI_OUTPUT :
+			COMEDI_INPUT;
+		return insn->n;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	devpriv->dio_control &= ~DIO_Pins_Dir_Mask;
+	devpriv->dio_control |= DIO_Pins_Dir(s->io_bits);
+	devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
+
+	return 1;
+}
+
+static int ni_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+#ifdef DEBUG_DIO
+	rt_printk("ni_dio_insn_bits() mask=0x%x bits=0x%x\n", data[0], data[1]);
+#endif
+	if (insn->n != 2)
+		return -EINVAL;
+	if (data[0]) {
+		/* Perform check to make sure we're not using the
+		   serial part of the dio */
+		if ((data[0] & (DIO_SDIN | DIO_SDOUT))
+			&& devpriv->serial_interval_ns)
+			return -EBUSY;
+
+		s->state &= ~data[0];
+		s->state |= (data[0] & data[1]);
+		devpriv->dio_output &= ~DIO_Parallel_Data_Mask;
+		devpriv->dio_output |= DIO_Parallel_Data_Out(s->state);
+		devpriv->stc_writew(dev, devpriv->dio_output,
+			DIO_Output_Register);
+	}
+	data[1] = devpriv->stc_readw(dev, DIO_Parallel_Input_Register);
+
+	return 2;
+}
+
+static int ni_m_series_dio_insn_config(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+#ifdef DEBUG_DIO
+	rt_printk("ni_m_series_dio_insn_config() chan=%d io=%d\n",
+		CR_CHAN(insn->chanspec), data[0]);
+#endif
+	switch (data[0]) {
+	case INSN_CONFIG_DIO_OUTPUT:
+		s->io_bits |= 1 << CR_CHAN(insn->chanspec);
+		break;
+	case INSN_CONFIG_DIO_INPUT:
+		s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
+		break;
+	case INSN_CONFIG_DIO_QUERY:
+		data[1] =
+			(s->io_bits & (1 << CR_CHAN(insn->
+					chanspec))) ? COMEDI_OUTPUT :
+			COMEDI_INPUT;
+		return insn->n;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	ni_writel(s->io_bits, M_Offset_DIO_Direction);
+
+	return 1;
+}
+
+static int ni_m_series_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+#ifdef DEBUG_DIO
+	rt_printk("ni_m_series_dio_insn_bits() mask=0x%x bits=0x%x\n", data[0],
+		data[1]);
+#endif
+	if (insn->n != 2)
+		return -EINVAL;
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= (data[0] & data[1]);
+		ni_writel(s->state, M_Offset_Static_Digital_Output);
+	}
+	data[1] = ni_readl(M_Offset_Static_Digital_Input);
+
+	return 2;
+}
+
+static int ni_cdio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp;
+	int sources;
+	unsigned i;
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	sources = TRIG_INT;
+	cmd->start_src &= sources;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_EXT;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_NOW;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique... */
+
+	if (cmd->start_src != TRIG_INT)
+		err++;
+	if (cmd->scan_begin_src != TRIG_EXT)
+		err++;
+	if (cmd->convert_src != TRIG_NOW)
+		err++;
+	if (cmd->stop_src != TRIG_NONE)
+		err++;
+	/* ... and mutually compatible */
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+	if (cmd->start_src == TRIG_INT) {
+		if (cmd->start_arg != 0) {
+			cmd->start_arg = 0;
+			err++;
+		}
+	}
+	if (cmd->scan_begin_src == TRIG_EXT) {
+		tmp = cmd->scan_begin_arg;
+		tmp &= CR_PACK_FLAGS(CDO_Sample_Source_Select_Mask, 0, 0,
+			CR_INVERT);
+		if (tmp != cmd->scan_begin_arg) {
+			err++;
+		}
+	}
+	if (cmd->convert_src == TRIG_NOW) {
+		if (cmd->convert_arg) {
+			cmd->convert_arg = 0;
+			err++;
+		}
+	}
+
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+
+	if (cmd->stop_src == TRIG_NONE) {
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	if (err)
+		return 4;
+
+	/* step 5: check chanlist */
+
+	for (i = 0; i < cmd->chanlist_len; ++i) {
+		if (cmd->chanlist[i] != i)
+			err = 1;
+	}
+
+	if (err)
+		return 5;
+
+	return 0;
+}
+
+static int ni_cdio_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	const struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned cdo_mode_bits = CDO_FIFO_Mode_Bit | CDO_Halt_On_Error_Bit;
+	int retval;
+
+	ni_writel(CDO_Reset_Bit, M_Offset_CDIO_Command);
+	switch (cmd->scan_begin_src) {
+	case TRIG_EXT:
+		cdo_mode_bits |=
+			CR_CHAN(cmd->
+			scan_begin_arg) & CDO_Sample_Source_Select_Mask;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	if (cmd->scan_begin_arg & CR_INVERT)
+		cdo_mode_bits |= CDO_Polarity_Bit;
+	ni_writel(cdo_mode_bits, M_Offset_CDO_Mode);
+	if (s->io_bits) {
+		ni_writel(s->state, M_Offset_CDO_FIFO_Data);
+		ni_writel(CDO_SW_Update_Bit, M_Offset_CDIO_Command);
+		ni_writel(s->io_bits, M_Offset_CDO_Mask_Enable);
+	} else {
+		comedi_error(dev,
+			"attempted to run digital output command with no lines configured as outputs");
+		return -EIO;
+	}
+	retval = ni_request_cdo_mite_channel(dev);
+	if (retval < 0) {
+		return retval;
+	}
+	s->async->inttrig = &ni_cdo_inttrig;
+	return 0;
+}
+
+static int ni_cdo_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int trignum)
+{
+#ifdef PCIDMA
+	unsigned long flags;
+#endif
+	int retval = 0;
+	unsigned i;
+	const unsigned timeout = 100;
+
+	s->async->inttrig = NULL;
+
+	/* read alloc the entire buffer */
+	comedi_buf_read_alloc(s->async, s->async->prealloc_bufsz);
+
+#ifdef PCIDMA
+	comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+	if (devpriv->cdo_mite_chan) {
+		mite_prep_dma(devpriv->cdo_mite_chan, 32, 32);
+		mite_dma_arm(devpriv->cdo_mite_chan);
+	} else {
+		comedi_error(dev, "BUG: no cdo mite channel?");
+		retval = -EIO;
+	}
+	comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+	if (retval < 0)
+		return retval;
+#endif
+// XXX not sure what interrupt C group does
+//      ni_writeb(Interrupt_Group_C_Enable_Bit, M_Offset_Interrupt_C_Enable);
+	//wait for dma to fill output fifo
+	for (i = 0; i < timeout; ++i) {
+		if (ni_readl(M_Offset_CDIO_Status) & CDO_FIFO_Full_Bit)
+			break;
+		comedi_udelay(10);
+	}
+	if (i == timeout) {
+		comedi_error(dev, "dma failed to fill cdo fifo!");
+		ni_cdio_cancel(dev, s);
+		return -EIO;
+	}
+	ni_writel(CDO_Arm_Bit | CDO_Error_Interrupt_Enable_Set_Bit |
+		CDO_Empty_FIFO_Interrupt_Enable_Set_Bit, M_Offset_CDIO_Command);
+	return retval;
+}
+
+static int ni_cdio_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	ni_writel(CDO_Disarm_Bit | CDO_Error_Interrupt_Enable_Clear_Bit |
+		CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit |
+		CDO_FIFO_Request_Interrupt_Enable_Clear_Bit,
+		M_Offset_CDIO_Command);
+// XXX not sure what interrupt C group does
+//      ni_writeb(0, M_Offset_Interrupt_C_Enable);
+	ni_writel(0, M_Offset_CDO_Mask_Enable);
+	ni_release_cdo_mite_channel(dev);
+	return 0;
+}
+
+static void handle_cdio_interrupt(struct comedi_device * dev)
+{
+	unsigned cdio_status;
+	struct comedi_subdevice *s = dev->subdevices + NI_DIO_SUBDEV;
+#ifdef PCIDMA
+	unsigned long flags;
+#endif
+
+	if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) {
+		return;
+	}
+#ifdef PCIDMA
+	comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+	if (devpriv->cdo_mite_chan) {
+		unsigned cdo_mite_status =
+			mite_get_status(devpriv->cdo_mite_chan);
+		if (cdo_mite_status & CHSR_LINKC) {
+			writel(CHOR_CLRLC,
+				devpriv->mite->mite_io_addr +
+				MITE_CHOR(devpriv->cdo_mite_chan->channel));
+		}
+		mite_sync_output_dma(devpriv->cdo_mite_chan, s->async);
+	}
+	comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+#endif
+
+	cdio_status = ni_readl(M_Offset_CDIO_Status);
+	if (cdio_status & (CDO_Overrun_Bit | CDO_Underflow_Bit)) {
+//              rt_printk("cdio error: statux=0x%x\n", cdio_status);
+		ni_writel(CDO_Error_Interrupt_Confirm_Bit, M_Offset_CDIO_Command);	// XXX just guessing this is needed and does something useful
+		s->async->events |= COMEDI_CB_OVERFLOW;
+	}
+	if (cdio_status & CDO_FIFO_Empty_Bit) {
+//              rt_printk("cdio fifo empty\n");
+		ni_writel(CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit,
+			M_Offset_CDIO_Command);
+//              s->async->events |= COMEDI_CB_EOA;
+	}
+	ni_event(dev, s);
+}
+
+static int ni_serial_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int err = insn->n;
+	unsigned char byte_out, byte_in = 0;
+
+	if (insn->n != 2)
+		return -EINVAL;
+
+	switch (data[0]) {
+	case INSN_CONFIG_SERIAL_CLOCK:
+
+#ifdef DEBUG_DIO
+		rt_printk("SPI serial clock Config cd\n", data[1]);
+#endif
+		devpriv->serial_hw_mode = 1;
+		devpriv->dio_control |= DIO_HW_Serial_Enable;
+
+		if (data[1] == SERIAL_DISABLED) {
+			devpriv->serial_hw_mode = 0;
+			devpriv->dio_control &= ~(DIO_HW_Serial_Enable |
+				DIO_Software_Serial_Control);
+			data[1] = SERIAL_DISABLED;
+			devpriv->serial_interval_ns = data[1];
+		} else if (data[1] <= SERIAL_600NS) {
+			/* Warning: this clock speed is too fast to reliably
+			   control SCXI. */
+			devpriv->dio_control &= ~DIO_HW_Serial_Timebase;
+			devpriv->clock_and_fout |= Slow_Internal_Timebase;
+			devpriv->clock_and_fout &= ~DIO_Serial_Out_Divide_By_2;
+			data[1] = SERIAL_600NS;
+			devpriv->serial_interval_ns = data[1];
+		} else if (data[1] <= SERIAL_1_2US) {
+			devpriv->dio_control &= ~DIO_HW_Serial_Timebase;
+			devpriv->clock_and_fout |= Slow_Internal_Timebase |
+				DIO_Serial_Out_Divide_By_2;
+			data[1] = SERIAL_1_2US;
+			devpriv->serial_interval_ns = data[1];
+		} else if (data[1] <= SERIAL_10US) {
+			devpriv->dio_control |= DIO_HW_Serial_Timebase;
+			devpriv->clock_and_fout |= Slow_Internal_Timebase |
+				DIO_Serial_Out_Divide_By_2;
+			/* Note: DIO_Serial_Out_Divide_By_2 only affects
+			   600ns/1.2us. If you turn divide_by_2 off with the
+			   slow clock, you will still get 10us, except then
+			   all your delays are wrong. */
+			data[1] = SERIAL_10US;
+			devpriv->serial_interval_ns = data[1];
+		} else {
+			devpriv->dio_control &= ~(DIO_HW_Serial_Enable |
+				DIO_Software_Serial_Control);
+			devpriv->serial_hw_mode = 0;
+			data[1] = (data[1] / 1000) * 1000;
+			devpriv->serial_interval_ns = data[1];
+		}
+
+		devpriv->stc_writew(dev, devpriv->dio_control,
+			DIO_Control_Register);
+		devpriv->stc_writew(dev, devpriv->clock_and_fout,
+			Clock_and_FOUT_Register);
+		return 1;
+
+		break;
+
+	case INSN_CONFIG_BIDIRECTIONAL_DATA:
+
+		if (devpriv->serial_interval_ns == 0) {
+			return -EINVAL;
+		}
+
+		byte_out = data[1] & 0xFF;
+
+		if (devpriv->serial_hw_mode) {
+			err = ni_serial_hw_readwrite8(dev, s, byte_out,
+				&byte_in);
+		} else if (devpriv->serial_interval_ns > 0) {
+			err = ni_serial_sw_readwrite8(dev, s, byte_out,
+				&byte_in);
+		} else {
+			rt_printk("ni_serial_insn_config: serial disabled!\n");
+			return -EINVAL;
+		}
+		if (err < 0)
+			return err;
+		data[1] = byte_in & 0xFF;
+		return insn->n;
+
+		break;
+	default:
+		return -EINVAL;
+	}
+
+}
+
+static int ni_serial_hw_readwrite8(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned char data_out, unsigned char *data_in)
+{
+	unsigned int status1;
+	int err = 0, count = 20;
+
+#ifdef DEBUG_DIO
+	rt_printk("ni_serial_hw_readwrite8: outputting 0x%x\n", data_out);
+#endif
+
+	devpriv->dio_output &= ~DIO_Serial_Data_Mask;
+	devpriv->dio_output |= DIO_Serial_Data_Out(data_out);
+	devpriv->stc_writew(dev, devpriv->dio_output, DIO_Output_Register);
+
+	status1 = devpriv->stc_readw(dev, Joint_Status_1_Register);
+	if (status1 & DIO_Serial_IO_In_Progress_St) {
+		err = -EBUSY;
+		goto Error;
+	}
+
+	devpriv->dio_control |= DIO_HW_Serial_Start;
+	devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
+	devpriv->dio_control &= ~DIO_HW_Serial_Start;
+
+	/* Wait until STC says we're done, but don't loop infinitely. */
+	while ((status1 =
+			devpriv->stc_readw(dev,
+				Joint_Status_1_Register)) &
+		DIO_Serial_IO_In_Progress_St) {
+		/* Delay one bit per loop */
+		comedi_udelay((devpriv->serial_interval_ns + 999) / 1000);
+		if (--count < 0) {
+			rt_printk
+				("ni_serial_hw_readwrite8: SPI serial I/O didn't finish in time!\n");
+			err = -ETIME;
+			goto Error;
+		}
+	}
+
+	/* Delay for last bit. This delay is absolutely necessary, because
+	   DIO_Serial_IO_In_Progress_St goes high one bit too early. */
+	comedi_udelay((devpriv->serial_interval_ns + 999) / 1000);
+
+	if (data_in != NULL) {
+		*data_in = devpriv->stc_readw(dev, DIO_Serial_Input_Register);
+#ifdef DEBUG_DIO
+		rt_printk("ni_serial_hw_readwrite8: inputted 0x%x\n", *data_in);
+#endif
+	}
+
+      Error:
+	devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
+
+	return err;
+}
+
+static int ni_serial_sw_readwrite8(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned char data_out, unsigned char *data_in)
+{
+	unsigned char mask, input = 0;
+
+#ifdef DEBUG_DIO
+	rt_printk("ni_serial_sw_readwrite8: outputting 0x%x\n", data_out);
+#endif
+
+	/* Wait for one bit before transfer */
+	comedi_udelay((devpriv->serial_interval_ns + 999) / 1000);
+
+	for (mask = 0x80; mask; mask >>= 1) {
+		/* Output current bit; note that we cannot touch s->state
+		   because it is a per-subdevice field, and serial is
+		   a separate subdevice from DIO. */
+		devpriv->dio_output &= ~DIO_SDOUT;
+		if (data_out & mask) {
+			devpriv->dio_output |= DIO_SDOUT;
+		}
+		devpriv->stc_writew(dev, devpriv->dio_output,
+			DIO_Output_Register);
+
+		/* Assert SDCLK (active low, inverted), wait for half of
+		   the delay, deassert SDCLK, and wait for the other half. */
+		devpriv->dio_control |= DIO_Software_Serial_Control;
+		devpriv->stc_writew(dev, devpriv->dio_control,
+			DIO_Control_Register);
+
+		comedi_udelay((devpriv->serial_interval_ns + 999) / 2000);
+
+		devpriv->dio_control &= ~DIO_Software_Serial_Control;
+		devpriv->stc_writew(dev, devpriv->dio_control,
+			DIO_Control_Register);
+
+		comedi_udelay((devpriv->serial_interval_ns + 999) / 2000);
+
+		/* Input current bit */
+		if (devpriv->stc_readw(dev,
+				DIO_Parallel_Input_Register) & DIO_SDIN) {
+/*			rt_printk("DIO_P_I_R: 0x%x\n", devpriv->stc_readw(dev, DIO_Parallel_Input_Register)); */
+			input |= mask;
+		}
+	}
+#ifdef DEBUG_DIO
+	rt_printk("ni_serial_sw_readwrite8: inputted 0x%x\n", input);
+#endif
+	if (data_in)
+		*data_in = input;
+
+	return 0;
+}
+
+static void mio_common_detach(struct comedi_device * dev)
+{
+	if (dev->private) {
+		if (devpriv->counter_dev) {
+			ni_gpct_device_destroy(devpriv->counter_dev);
+		}
+	}
+	if (dev->subdevices && boardtype.has_8255)
+		subdev_8255_cleanup(dev, dev->subdevices + NI_8255_DIO_SUBDEV);
+}
+
+static void init_ao_67xx(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	int i;
+
+	for (i = 0; i < s->n_chan; i++)
+	{
+		ni_ao_win_outw(dev, AO_Channel(i) | 0x0,
+			AO_Configuration_2_67xx);
+	}
+	ao_win_out(0x0, AO_Later_Single_Point_Updates);
+}
+
+static unsigned ni_gpct_to_stc_register(enum ni_gpct_register reg)
+{
+	unsigned stc_register;
+	switch (reg) {
+	case NITIO_G0_Autoincrement_Reg:
+		stc_register = G_Autoincrement_Register(0);
+		break;
+	case NITIO_G1_Autoincrement_Reg:
+		stc_register = G_Autoincrement_Register(1);
+		break;
+	case NITIO_G0_Command_Reg:
+		stc_register = G_Command_Register(0);
+		break;
+	case NITIO_G1_Command_Reg:
+		stc_register = G_Command_Register(1);
+		break;
+	case NITIO_G0_HW_Save_Reg:
+		stc_register = G_HW_Save_Register(0);
+		break;
+	case NITIO_G1_HW_Save_Reg:
+		stc_register = G_HW_Save_Register(1);
+		break;
+	case NITIO_G0_SW_Save_Reg:
+		stc_register = G_Save_Register(0);
+		break;
+	case NITIO_G1_SW_Save_Reg:
+		stc_register = G_Save_Register(1);
+		break;
+	case NITIO_G0_Mode_Reg:
+		stc_register = G_Mode_Register(0);
+		break;
+	case NITIO_G1_Mode_Reg:
+		stc_register = G_Mode_Register(1);
+		break;
+	case NITIO_G0_LoadA_Reg:
+		stc_register = G_Load_A_Register(0);
+		break;
+	case NITIO_G1_LoadA_Reg:
+		stc_register = G_Load_A_Register(1);
+		break;
+	case NITIO_G0_LoadB_Reg:
+		stc_register = G_Load_B_Register(0);
+		break;
+	case NITIO_G1_LoadB_Reg:
+		stc_register = G_Load_B_Register(1);
+		break;
+	case NITIO_G0_Input_Select_Reg:
+		stc_register = G_Input_Select_Register(0);
+		break;
+	case NITIO_G1_Input_Select_Reg:
+		stc_register = G_Input_Select_Register(1);
+		break;
+	case NITIO_G01_Status_Reg:
+		stc_register = G_Status_Register;
+		break;
+	case NITIO_G01_Joint_Reset_Reg:
+		stc_register = Joint_Reset_Register;
+		break;
+	case NITIO_G01_Joint_Status1_Reg:
+		stc_register = Joint_Status_1_Register;
+		break;
+	case NITIO_G01_Joint_Status2_Reg:
+		stc_register = Joint_Status_2_Register;
+		break;
+	case NITIO_G0_Interrupt_Acknowledge_Reg:
+		stc_register = Interrupt_A_Ack_Register;
+		break;
+	case NITIO_G1_Interrupt_Acknowledge_Reg:
+		stc_register = Interrupt_B_Ack_Register;
+		break;
+	case NITIO_G0_Status_Reg:
+		stc_register = AI_Status_1_Register;
+		break;
+	case NITIO_G1_Status_Reg:
+		stc_register = AO_Status_1_Register;
+		break;
+	case NITIO_G0_Interrupt_Enable_Reg:
+		stc_register = Interrupt_A_Enable_Register;
+		break;
+	case NITIO_G1_Interrupt_Enable_Reg:
+		stc_register = Interrupt_B_Enable_Register;
+		break;
+	default:
+		rt_printk("%s: unhandled register 0x%x in switch.\n",
+			__FUNCTION__, reg);
+		BUG();
+		return 0;
+		break;
+	}
+	return stc_register;
+}
+
+static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits,
+	enum ni_gpct_register reg)
+{
+	struct comedi_device *dev = counter->counter_dev->dev;
+	unsigned stc_register;
+	/* bits in the join reset register which are relevant to counters */
+	static const unsigned gpct_joint_reset_mask = G0_Reset | G1_Reset;
+	static const unsigned gpct_interrupt_a_enable_mask =
+		G0_Gate_Interrupt_Enable | G0_TC_Interrupt_Enable;
+	static const unsigned gpct_interrupt_b_enable_mask =
+		G1_Gate_Interrupt_Enable | G1_TC_Interrupt_Enable;
+
+	switch (reg) {
+		/* m-series-only registers */
+	case NITIO_G0_Counting_Mode_Reg:
+		ni_writew(bits, M_Offset_G0_Counting_Mode);
+		break;
+	case NITIO_G1_Counting_Mode_Reg:
+		ni_writew(bits, M_Offset_G1_Counting_Mode);
+		break;
+	case NITIO_G0_Second_Gate_Reg:
+		ni_writew(bits, M_Offset_G0_Second_Gate);
+		break;
+	case NITIO_G1_Second_Gate_Reg:
+		ni_writew(bits, M_Offset_G1_Second_Gate);
+		break;
+	case NITIO_G0_DMA_Config_Reg:
+		ni_writew(bits, M_Offset_G0_DMA_Config);
+		break;
+	case NITIO_G1_DMA_Config_Reg:
+		ni_writew(bits, M_Offset_G1_DMA_Config);
+		break;
+	case NITIO_G0_ABZ_Reg:
+		ni_writew(bits, M_Offset_G0_MSeries_ABZ);
+		break;
+	case NITIO_G1_ABZ_Reg:
+		ni_writew(bits, M_Offset_G1_MSeries_ABZ);
+		break;
+
+		/* 32 bit registers */
+	case NITIO_G0_LoadA_Reg:
+	case NITIO_G1_LoadA_Reg:
+	case NITIO_G0_LoadB_Reg:
+	case NITIO_G1_LoadB_Reg:
+		stc_register = ni_gpct_to_stc_register(reg);
+		devpriv->stc_writel(dev, bits, stc_register);
+		break;
+
+		/* 16 bit registers */
+	case NITIO_G0_Interrupt_Enable_Reg:
+		BUG_ON(bits & ~gpct_interrupt_a_enable_mask);
+		ni_set_bitfield(dev, Interrupt_A_Enable_Register,
+			gpct_interrupt_a_enable_mask, bits);
+		break;
+	case NITIO_G1_Interrupt_Enable_Reg:
+		BUG_ON(bits & ~gpct_interrupt_b_enable_mask);
+		ni_set_bitfield(dev, Interrupt_B_Enable_Register,
+			gpct_interrupt_b_enable_mask, bits);
+		break;
+	case NITIO_G01_Joint_Reset_Reg:
+		BUG_ON(bits & ~gpct_joint_reset_mask);
+		/* fall-through */
+	default:
+		stc_register = ni_gpct_to_stc_register(reg);
+		devpriv->stc_writew(dev, bits, stc_register);
+	}
+}
+
+static unsigned ni_gpct_read_register(struct ni_gpct *counter,
+	enum ni_gpct_register reg)
+{
+	struct comedi_device *dev = counter->counter_dev->dev;
+	unsigned stc_register;
+	switch (reg) {
+		/* m-series only registers */
+	case NITIO_G0_DMA_Status_Reg:
+		return ni_readw(M_Offset_G0_DMA_Status);
+		break;
+	case NITIO_G1_DMA_Status_Reg:
+		return ni_readw(M_Offset_G1_DMA_Status);
+		break;
+
+		/* 32 bit registers */
+	case NITIO_G0_HW_Save_Reg:
+	case NITIO_G1_HW_Save_Reg:
+	case NITIO_G0_SW_Save_Reg:
+	case NITIO_G1_SW_Save_Reg:
+		stc_register = ni_gpct_to_stc_register(reg);
+		return devpriv->stc_readl(dev, stc_register);
+		break;
+
+		/* 16 bit registers */
+	default:
+		stc_register = ni_gpct_to_stc_register(reg);
+		return devpriv->stc_readw(dev, stc_register);
+		break;
+	}
+	return 0;
+}
+
+static int ni_freq_out_insn_read(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	data[0] = devpriv->clock_and_fout & FOUT_Divider_mask;
+	return 1;
+}
+
+static int ni_freq_out_insn_write(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	devpriv->clock_and_fout &= ~FOUT_Enable;
+	devpriv->stc_writew(dev, devpriv->clock_and_fout,
+		Clock_and_FOUT_Register);
+	devpriv->clock_and_fout &= ~FOUT_Divider_mask;
+	devpriv->clock_and_fout |= FOUT_Divider(data[0]);
+	devpriv->clock_and_fout |= FOUT_Enable;
+	devpriv->stc_writew(dev, devpriv->clock_and_fout,
+		Clock_and_FOUT_Register);
+	return insn->n;
+}
+
+static int ni_set_freq_out_clock(struct comedi_device * dev, unsigned int clock_source)
+{
+	switch (clock_source) {
+	case NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC:
+		devpriv->clock_and_fout &= ~FOUT_Timebase_Select;
+		break;
+	case NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC:
+		devpriv->clock_and_fout |= FOUT_Timebase_Select;
+		break;
+	default:
+		return -EINVAL;
+	}
+	devpriv->stc_writew(dev, devpriv->clock_and_fout,
+		Clock_and_FOUT_Register);
+	return 3;
+}
+
+static void ni_get_freq_out_clock(struct comedi_device * dev, unsigned int * clock_source,
+	unsigned int * clock_period_ns)
+{
+	if (devpriv->clock_and_fout & FOUT_Timebase_Select) {
+		*clock_source = NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC;
+		*clock_period_ns = TIMEBASE_2_NS;
+	} else {
+		*clock_source = NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC;
+		*clock_period_ns = TIMEBASE_1_NS * 2;
+	}
+}
+
+static int ni_freq_out_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	switch (data[0]) {
+	case INSN_CONFIG_SET_CLOCK_SRC:
+		return ni_set_freq_out_clock(dev, data[1]);
+		break;
+	case INSN_CONFIG_GET_CLOCK_SRC:
+		ni_get_freq_out_clock(dev, &data[1], &data[2]);
+		return 3;
+	default:
+		break;
+	}
+	return -EINVAL;
+}
+
+static int ni_alloc_private(struct comedi_device * dev)
+{
+	int ret;
+
+	ret = alloc_private(dev, sizeof(ni_private));
+	if (ret < 0)
+		return ret;
+
+	spin_lock_init(&devpriv->window_lock);
+	spin_lock_init(&devpriv->soft_reg_copy_lock);
+	spin_lock_init(&devpriv->mite_channel_lock);
+
+	return 0;
+};
+
+static int ni_E_init(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	unsigned j;
+	enum ni_gpct_variant counter_variant;
+
+	if (boardtype.n_aochan > MAX_N_AO_CHAN) {
+		printk("bug! boardtype.n_aochan > MAX_N_AO_CHAN\n");
+		return -EINVAL;
+	}
+
+	if (alloc_subdevices(dev, NI_NUM_SUBDEVICES) < 0)
+		return -ENOMEM;
+
+	/* analog input subdevice */
+
+	s = dev->subdevices + NI_AI_SUBDEV;
+	dev->read_subdev = s;
+	if (boardtype.n_adchan) {
+		s->type = COMEDI_SUBD_AI;
+		s->subdev_flags =
+			SDF_READABLE | SDF_DIFF | SDF_DITHER | SDF_CMD_READ;
+		if (boardtype.reg_type != ni_reg_611x)
+			s->subdev_flags |= SDF_GROUND | SDF_COMMON | SDF_OTHER;
+		if (boardtype.adbits > 16)
+			s->subdev_flags |= SDF_LSAMPL;
+		if (boardtype.reg_type & ni_reg_m_series_mask)
+			s->subdev_flags |= SDF_SOFT_CALIBRATED;
+		s->n_chan = boardtype.n_adchan;
+		s->len_chanlist = 512;
+		s->maxdata = (1 << boardtype.adbits) - 1;
+		s->range_table = ni_range_lkup[boardtype.gainlkup];
+		s->insn_read = &ni_ai_insn_read;
+		s->insn_config = &ni_ai_insn_config;
+		s->do_cmdtest = &ni_ai_cmdtest;
+		s->do_cmd = &ni_ai_cmd;
+		s->cancel = &ni_ai_reset;
+		s->poll = &ni_ai_poll;
+		s->munge = &ni_ai_munge;
+#ifdef PCIDMA
+		s->async_dma_dir = DMA_FROM_DEVICE;
+#endif
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	/* analog output subdevice */
+
+	s = dev->subdevices + NI_AO_SUBDEV;
+	if (boardtype.n_aochan) {
+		s->type = COMEDI_SUBD_AO;
+		s->subdev_flags = SDF_WRITABLE | SDF_DEGLITCH | SDF_GROUND;
+		if (boardtype.reg_type & ni_reg_m_series_mask)
+			s->subdev_flags |= SDF_SOFT_CALIBRATED;
+		s->n_chan = boardtype.n_aochan;
+		s->maxdata = (1 << boardtype.aobits) - 1;
+		s->range_table = boardtype.ao_range_table;
+		s->insn_read = &ni_ao_insn_read;
+		if (boardtype.reg_type & ni_reg_6xxx_mask) {
+			s->insn_write = &ni_ao_insn_write_671x;
+		} else {
+			s->insn_write = &ni_ao_insn_write;
+		}
+		s->insn_config = &ni_ao_insn_config;
+#ifdef PCIDMA
+		if (boardtype.n_aochan) {
+			s->async_dma_dir = DMA_TO_DEVICE;
+#else
+		if (boardtype.ao_fifo_depth) {
+#endif
+			dev->write_subdev = s;
+			s->subdev_flags |= SDF_CMD_WRITE;
+			s->do_cmd = &ni_ao_cmd;
+			s->do_cmdtest = &ni_ao_cmdtest;
+			s->len_chanlist = boardtype.n_aochan;
+			if ((boardtype.reg_type & ni_reg_m_series_mask) == 0)
+				s->munge = ni_ao_munge;
+		}
+		s->cancel = &ni_ao_reset;
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+	if ((boardtype.reg_type & ni_reg_67xx_mask))
+		init_ao_67xx(dev, s);
+
+	/* digital i/o subdevice */
+
+	s = dev->subdevices + NI_DIO_SUBDEV;
+	s->type = COMEDI_SUBD_DIO;
+	s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+	s->maxdata = 1;
+	s->io_bits = 0;		/* all bits input */
+	s->range_table = &range_digital;
+	s->n_chan = boardtype.num_p0_dio_channels;
+	if (boardtype.reg_type & ni_reg_m_series_mask) {
+		s->subdev_flags |=
+			SDF_LSAMPL | SDF_CMD_WRITE /* | SDF_CMD_READ */ ;
+		s->insn_bits = &ni_m_series_dio_insn_bits;
+		s->insn_config = &ni_m_series_dio_insn_config;
+		s->do_cmd = &ni_cdio_cmd;
+		s->do_cmdtest = &ni_cdio_cmdtest;
+		s->cancel = &ni_cdio_cancel;
+		s->async_dma_dir = DMA_BIDIRECTIONAL;
+		s->len_chanlist = s->n_chan;
+
+		ni_writel(CDO_Reset_Bit | CDI_Reset_Bit, M_Offset_CDIO_Command);
+		ni_writel(s->io_bits, M_Offset_DIO_Direction);
+	} else {
+		s->insn_bits = &ni_dio_insn_bits;
+		s->insn_config = &ni_dio_insn_config;
+		devpriv->dio_control = DIO_Pins_Dir(s->io_bits);
+		ni_writew(devpriv->dio_control, DIO_Control_Register);
+	}
+
+	/* 8255 device */
+	s = dev->subdevices + NI_8255_DIO_SUBDEV;
+	if (boardtype.has_8255) {
+		subdev_8255_init(dev, s, ni_8255_callback, (unsigned long)dev);
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	/* formerly general purpose counter/timer device, but no longer used */
+	s = dev->subdevices + NI_UNUSED_SUBDEV;
+	s->type = COMEDI_SUBD_UNUSED;
+
+	/* calibration subdevice -- ai and ao */
+	s = dev->subdevices + NI_CALIBRATION_SUBDEV;
+	s->type = COMEDI_SUBD_CALIB;
+	if (boardtype.reg_type & ni_reg_m_series_mask) {
+		// internal PWM analog output used for AI nonlinearity calibration
+		s->subdev_flags = SDF_INTERNAL;
+		s->insn_config = &ni_m_series_pwm_config;
+		s->n_chan = 1;
+		s->maxdata = 0;
+		ni_writel(0x0, M_Offset_Cal_PWM);
+	} else if (boardtype.reg_type == ni_reg_6143) {
+		// internal PWM analog output used for AI nonlinearity calibration
+		s->subdev_flags = SDF_INTERNAL;
+		s->insn_config = &ni_6143_pwm_config;
+		s->n_chan = 1;
+		s->maxdata = 0;
+	} else {
+		s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL;
+		s->insn_read = &ni_calib_insn_read;
+		s->insn_write = &ni_calib_insn_write;
+		caldac_setup(dev, s);
+	}
+
+	/* EEPROM */
+	s = dev->subdevices + NI_EEPROM_SUBDEV;
+	s->type = COMEDI_SUBD_MEMORY;
+	s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
+	s->maxdata = 0xff;
+	if (boardtype.reg_type & ni_reg_m_series_mask) {
+		s->n_chan = M_SERIES_EEPROM_SIZE;
+		s->insn_read = &ni_m_series_eeprom_insn_read;
+	} else {
+		s->n_chan = 512;
+		s->insn_read = &ni_eeprom_insn_read;
+	}
+
+	/* PFI */
+	s = dev->subdevices + NI_PFI_DIO_SUBDEV;
+	s->type = COMEDI_SUBD_DIO;
+	s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+	if (boardtype.reg_type & ni_reg_m_series_mask) {
+		unsigned i;
+		s->n_chan = 16;
+		ni_writew(s->state, M_Offset_PFI_DO);
+		for (i = 0; i < NUM_PFI_OUTPUT_SELECT_REGS; ++i) {
+			ni_writew(devpriv->pfi_output_select_reg[i],
+				M_Offset_PFI_Output_Select(i + 1));
+		}
+	} else {
+		s->n_chan = 10;
+	}
+	s->maxdata = 1;
+	if (boardtype.reg_type & ni_reg_m_series_mask) {
+		s->insn_bits = &ni_pfi_insn_bits;
+	}
+	s->insn_config = &ni_pfi_insn_config;
+	ni_set_bits(dev, IO_Bidirection_Pin_Register, ~0, 0);
+
+	/* cs5529 calibration adc */
+	s = dev->subdevices + NI_CS5529_CALIBRATION_SUBDEV;
+	if (boardtype.reg_type & ni_reg_67xx_mask) {
+		s->type = COMEDI_SUBD_AI;
+		s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_INTERNAL;
+		// one channel for each analog output channel
+		s->n_chan = boardtype.n_aochan;
+		s->maxdata = (1 << 16) - 1;
+		s->range_table = &range_unknown;	/* XXX */
+		s->insn_read = cs5529_ai_insn_read;
+		s->insn_config = NULL;
+		init_cs5529(dev);
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	/* Serial */
+	s = dev->subdevices + NI_SERIAL_SUBDEV;
+	s->type = COMEDI_SUBD_SERIAL;
+	s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+	s->n_chan = 1;
+	s->maxdata = 0xff;
+	s->insn_config = ni_serial_insn_config;
+	devpriv->serial_interval_ns = 0;
+	devpriv->serial_hw_mode = 0;
+
+	/* RTSI */
+	s = dev->subdevices + NI_RTSI_SUBDEV;
+	s->type = COMEDI_SUBD_DIO;
+	s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+	s->n_chan = 8;
+	s->maxdata = 1;
+	s->insn_bits = ni_rtsi_insn_bits;
+	s->insn_config = ni_rtsi_insn_config;
+	ni_rtsi_init(dev);
+
+	if (boardtype.reg_type & ni_reg_m_series_mask) {
+		counter_variant = ni_gpct_variant_m_series;
+	} else {
+		counter_variant = ni_gpct_variant_e_series;
+	}
+	devpriv->counter_dev = ni_gpct_device_construct(dev,
+		&ni_gpct_write_register, &ni_gpct_read_register,
+		counter_variant, NUM_GPCT);
+	/* General purpose counters */
+	for (j = 0; j < NUM_GPCT; ++j) {
+		s = dev->subdevices + NI_GPCT_SUBDEV(j);
+		s->type = COMEDI_SUBD_COUNTER;
+		s->subdev_flags =
+			SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_CMD_READ
+			/* | SDF_CMD_WRITE */ ;
+		s->n_chan = 3;
+		if (boardtype.reg_type & ni_reg_m_series_mask)
+			s->maxdata = 0xffffffff;
+		else
+			s->maxdata = 0xffffff;
+		s->insn_read = &ni_gpct_insn_read;
+		s->insn_write = &ni_gpct_insn_write;
+		s->insn_config = &ni_gpct_insn_config;
+		s->do_cmd = &ni_gpct_cmd;
+		s->len_chanlist = 1;
+		s->do_cmdtest = &ni_gpct_cmdtest;
+		s->cancel = &ni_gpct_cancel;
+		s->async_dma_dir = DMA_BIDIRECTIONAL;
+		s->private = &devpriv->counter_dev->counters[j];
+
+		devpriv->counter_dev->counters[j].chip_index = 0;
+		devpriv->counter_dev->counters[j].counter_index = j;
+		ni_tio_init_counter(&devpriv->counter_dev->counters[j]);
+	}
+
+	/* Frequency output */
+	s = dev->subdevices + NI_FREQ_OUT_SUBDEV;
+	s->type = COMEDI_SUBD_COUNTER;
+	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+	s->n_chan = 1;
+	s->maxdata = 0xf;
+	s->insn_read = &ni_freq_out_insn_read;
+	s->insn_write = &ni_freq_out_insn_write;
+	s->insn_config = &ni_freq_out_insn_config;
+
+	/* ai configuration */
+	ni_ai_reset(dev, dev->subdevices + NI_AI_SUBDEV);
+	if ((boardtype.reg_type & ni_reg_6xxx_mask) == 0) {
+		// BEAM is this needed for PCI-6143 ??
+		devpriv->clock_and_fout =
+			Slow_Internal_Time_Divide_By_2 |
+			Slow_Internal_Timebase |
+			Clock_To_Board_Divide_By_2 |
+			Clock_To_Board |
+			AI_Output_Divide_By_2 | AO_Output_Divide_By_2;
+	} else {
+		devpriv->clock_and_fout =
+			Slow_Internal_Time_Divide_By_2 |
+			Slow_Internal_Timebase |
+			Clock_To_Board_Divide_By_2 | Clock_To_Board;
+	}
+	devpriv->stc_writew(dev, devpriv->clock_and_fout,
+		Clock_and_FOUT_Register);
+
+	/* analog output configuration */
+	ni_ao_reset(dev, dev->subdevices + NI_AO_SUBDEV);
+
+	if (dev->irq) {
+		devpriv->stc_writew(dev,
+			(IRQ_POLARITY ? Interrupt_Output_Polarity : 0) |
+			(Interrupt_Output_On_3_Pins & 0) | Interrupt_A_Enable |
+			Interrupt_B_Enable |
+			Interrupt_A_Output_Select(interrupt_pin(dev->
+					irq)) |
+			Interrupt_B_Output_Select(interrupt_pin(dev->irq)),
+			Interrupt_Control_Register);
+	}
+
+	/* DMA setup */
+	ni_writeb(devpriv->ai_ao_select_reg, AI_AO_Select);
+	ni_writeb(devpriv->g0_g1_select_reg, G0_G1_Select);
+
+	if (boardtype.reg_type & ni_reg_6xxx_mask) {
+		ni_writeb(0, Magic_611x);
+	} else if (boardtype.reg_type & ni_reg_m_series_mask) {
+		int channel;
+		for (channel = 0; channel < boardtype.n_aochan; ++channel) {
+			ni_writeb(0xf, M_Offset_AO_Waveform_Order(channel));
+			ni_writeb(0x0,
+				M_Offset_AO_Reference_Attenuation(channel));
+		}
+		ni_writeb(0x0, M_Offset_AO_Calibration);
+	}
+
+	printk("\n");
+	return 0;
+}
+
+static int ni_8255_callback(int dir, int port, int data, unsigned long arg)
+{
+	struct comedi_device *dev = (struct comedi_device *) arg;
+
+	if (dir) {
+		ni_writeb(data, Port_A + 2 * port);
+		return 0;
+	} else {
+		return ni_readb(Port_A + 2 * port);
+	}
+}
+
+/*
+	presents the EEPROM as a subdevice
+*/
+
+static int ni_eeprom_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	data[0] = ni_read_eeprom(dev, CR_CHAN(insn->chanspec));
+
+	return 1;
+}
+
+/*
+	reads bytes out of eeprom
+*/
+
+static int ni_read_eeprom(struct comedi_device * dev, int addr)
+{
+	int bit;
+	int bitstring;
+
+	bitstring = 0x0300 | ((addr & 0x100) << 3) | (addr & 0xff);
+	ni_writeb(0x04, Serial_Command);
+	for (bit = 0x8000; bit; bit >>= 1) {
+		ni_writeb(0x04 | ((bit & bitstring) ? 0x02 : 0),
+			Serial_Command);
+		ni_writeb(0x05 | ((bit & bitstring) ? 0x02 : 0),
+			Serial_Command);
+	}
+	bitstring = 0;
+	for (bit = 0x80; bit; bit >>= 1) {
+		ni_writeb(0x04, Serial_Command);
+		ni_writeb(0x05, Serial_Command);
+		bitstring |= ((ni_readb(XXX_Status) & PROMOUT) ? bit : 0);
+	}
+	ni_writeb(0x00, Serial_Command);
+
+	return bitstring;
+}
+
+static int ni_m_series_eeprom_insn_read(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+	data[0] = devpriv->eeprom_buffer[CR_CHAN(insn->chanspec)];
+
+	return 1;
+}
+
+static int ni_get_pwm_config(struct comedi_device * dev, unsigned int * data)
+{
+	data[1] = devpriv->pwm_up_count * devpriv->clock_ns;
+	data[2] = devpriv->pwm_down_count * devpriv->clock_ns;
+	return 3;
+}
+
+static int ni_m_series_pwm_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned up_count, down_count;
+	switch (data[0]) {
+	case INSN_CONFIG_PWM_OUTPUT:
+		switch (data[1]) {
+		case TRIG_ROUND_NEAREST:
+			up_count =
+				(data[2] +
+				devpriv->clock_ns / 2) / devpriv->clock_ns;
+			break;
+		case TRIG_ROUND_DOWN:
+			up_count = data[2] / devpriv->clock_ns;
+			break;
+		case TRIG_ROUND_UP:
+			up_count =
+				(data[2] + devpriv->clock_ns -
+				1) / devpriv->clock_ns;
+			break;
+		default:
+			return -EINVAL;
+			break;
+		}
+		switch (data[3]) {
+		case TRIG_ROUND_NEAREST:
+			down_count =
+				(data[4] +
+				devpriv->clock_ns / 2) / devpriv->clock_ns;
+			break;
+		case TRIG_ROUND_DOWN:
+			down_count = data[4] / devpriv->clock_ns;
+			break;
+		case TRIG_ROUND_UP:
+			down_count =
+				(data[4] + devpriv->clock_ns -
+				1) / devpriv->clock_ns;
+			break;
+		default:
+			return -EINVAL;
+			break;
+		}
+		if (up_count * devpriv->clock_ns != data[2] ||
+			down_count * devpriv->clock_ns != data[4]) {
+			data[2] = up_count * devpriv->clock_ns;
+			data[4] = down_count * devpriv->clock_ns;
+			return -EAGAIN;
+		}
+		ni_writel(MSeries_Cal_PWM_High_Time_Bits(up_count) |
+			MSeries_Cal_PWM_Low_Time_Bits(down_count),
+			M_Offset_Cal_PWM);
+		devpriv->pwm_up_count = up_count;
+		devpriv->pwm_down_count = down_count;
+		return 5;
+		break;
+	case INSN_CONFIG_GET_PWM_OUTPUT:
+		return ni_get_pwm_config(dev, data);
+		break;
+	default:
+		return -EINVAL;
+		break;
+	}
+	return 0;
+}
+
+static int ni_6143_pwm_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned up_count, down_count;
+	switch (data[0]) {
+	case INSN_CONFIG_PWM_OUTPUT:
+		switch (data[1]) {
+		case TRIG_ROUND_NEAREST:
+			up_count =
+				(data[2] +
+				devpriv->clock_ns / 2) / devpriv->clock_ns;
+			break;
+		case TRIG_ROUND_DOWN:
+			up_count = data[2] / devpriv->clock_ns;
+			break;
+		case TRIG_ROUND_UP:
+			up_count =
+				(data[2] + devpriv->clock_ns -
+				1) / devpriv->clock_ns;
+			break;
+		default:
+			return -EINVAL;
+			break;
+		}
+		switch (data[3]) {
+		case TRIG_ROUND_NEAREST:
+			down_count =
+				(data[4] +
+				devpriv->clock_ns / 2) / devpriv->clock_ns;
+			break;
+		case TRIG_ROUND_DOWN:
+			down_count = data[4] / devpriv->clock_ns;
+			break;
+		case TRIG_ROUND_UP:
+			down_count =
+				(data[4] + devpriv->clock_ns -
+				1) / devpriv->clock_ns;
+			break;
+		default:
+			return -EINVAL;
+			break;
+		}
+		if (up_count * devpriv->clock_ns != data[2] ||
+			down_count * devpriv->clock_ns != data[4]) {
+			data[2] = up_count * devpriv->clock_ns;
+			data[4] = down_count * devpriv->clock_ns;
+			return -EAGAIN;
+		}
+		ni_writel(up_count, Calibration_HighTime_6143);
+		devpriv->pwm_up_count = up_count;
+		ni_writel(down_count, Calibration_LowTime_6143);
+		devpriv->pwm_down_count = down_count;
+		return 5;
+		break;
+	case INSN_CONFIG_GET_PWM_OUTPUT:
+		return ni_get_pwm_config(dev, data);
+	default:
+		return -EINVAL;
+		break;
+	}
+	return 0;
+}
+
+static void ni_write_caldac(struct comedi_device * dev, int addr, int val);
+/*
+	calibration subdevice
+*/
+static int ni_calib_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	ni_write_caldac(dev, CR_CHAN(insn->chanspec), data[0]);
+
+	return 1;
+}
+
+static int ni_calib_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	data[0] = devpriv->caldacs[CR_CHAN(insn->chanspec)];
+
+	return 1;
+}
+
+static int pack_mb88341(int addr, int val, int *bitstring);
+static int pack_dac8800(int addr, int val, int *bitstring);
+static int pack_dac8043(int addr, int val, int *bitstring);
+static int pack_ad8522(int addr, int val, int *bitstring);
+static int pack_ad8804(int addr, int val, int *bitstring);
+static int pack_ad8842(int addr, int val, int *bitstring);
+
+struct caldac_struct {
+	int n_chans;
+	int n_bits;
+	int (*packbits) (int, int, int *);
+};
+
+static struct caldac_struct caldacs[] = {
+	[mb88341] = {12, 8, pack_mb88341},
+	[dac8800] = {8, 8, pack_dac8800},
+	[dac8043] = {1, 12, pack_dac8043},
+	[ad8522] = {2, 12, pack_ad8522},
+	[ad8804] = {12, 8, pack_ad8804},
+	[ad8842] = {8, 8, pack_ad8842},
+	[ad8804_debug] = {16, 8, pack_ad8804},
+};
+
+static void caldac_setup(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	int i, j;
+	int n_dacs;
+	int n_chans = 0;
+	int n_bits;
+	int diffbits = 0;
+	int type;
+	int chan;
+
+	type = boardtype.caldac[0];
+	if (type == caldac_none)
+		return;
+	n_bits = caldacs[type].n_bits;
+	for (i = 0; i < 3; i++) {
+		type = boardtype.caldac[i];
+		if (type == caldac_none)
+			break;
+		if (caldacs[type].n_bits != n_bits)
+			diffbits = 1;
+		n_chans += caldacs[type].n_chans;
+	}
+	n_dacs = i;
+	s->n_chan = n_chans;
+
+	if (diffbits) {
+		unsigned int *maxdata_list;
+
+		if (n_chans > MAX_N_CALDACS) {
+			printk("BUG! MAX_N_CALDACS too small\n");
+		}
+		s->maxdata_list = maxdata_list = devpriv->caldac_maxdata_list;
+		chan = 0;
+		for (i = 0; i < n_dacs; i++) {
+			type = boardtype.caldac[i];
+			for (j = 0; j < caldacs[type].n_chans; j++) {
+				maxdata_list[chan] =
+					(1 << caldacs[type].n_bits) - 1;
+				chan++;
+			}
+		}
+
+		for (chan = 0; chan < s->n_chan; chan++)
+			ni_write_caldac(dev, i, s->maxdata_list[i] / 2);
+	} else {
+		type = boardtype.caldac[0];
+		s->maxdata = (1 << caldacs[type].n_bits) - 1;
+
+		for (chan = 0; chan < s->n_chan; chan++)
+			ni_write_caldac(dev, i, s->maxdata / 2);
+	}
+}
+
+static void ni_write_caldac(struct comedi_device * dev, int addr, int val)
+{
+	unsigned int loadbit = 0, bits = 0, bit, bitstring = 0;
+	int i;
+	int type;
+
+	//printk("ni_write_caldac: chan=%d val=%d\n",addr,val);
+	if (devpriv->caldacs[addr] == val)
+		return;
+	devpriv->caldacs[addr] = val;
+
+	for (i = 0; i < 3; i++) {
+		type = boardtype.caldac[i];
+		if (type == caldac_none)
+			break;
+		if (addr < caldacs[type].n_chans) {
+			bits = caldacs[type].packbits(addr, val, &bitstring);
+			loadbit = SerDacLd(i);
+			//printk("caldac: using i=%d addr=%d %x\n",i,addr,bitstring);
+			break;
+		}
+		addr -= caldacs[type].n_chans;
+	}
+
+	for (bit = 1 << (bits - 1); bit; bit >>= 1) {
+		ni_writeb(((bit & bitstring) ? 0x02 : 0), Serial_Command);
+		comedi_udelay(1);
+		ni_writeb(1 | ((bit & bitstring) ? 0x02 : 0), Serial_Command);
+		comedi_udelay(1);
+	}
+	ni_writeb(loadbit, Serial_Command);
+	comedi_udelay(1);
+	ni_writeb(0, Serial_Command);
+}
+
+static int pack_mb88341(int addr, int val, int *bitstring)
+{
+	/*
+	   Fujitsu MB 88341
+	   Note that address bits are reversed.  Thanks to
+	   Ingo Keen for noticing this.
+
+	   Note also that the 88341 expects address values from
+	   1-12, whereas we use channel numbers 0-11.  The NI
+	   docs use 1-12, also, so be careful here.
+	 */
+	addr++;
+	*bitstring = ((addr & 0x1) << 11) |
+		((addr & 0x2) << 9) |
+		((addr & 0x4) << 7) | ((addr & 0x8) << 5) | (val & 0xff);
+	return 12;
+}
+
+static int pack_dac8800(int addr, int val, int *bitstring)
+{
+	*bitstring = ((addr & 0x7) << 8) | (val & 0xff);
+	return 11;
+}
+
+static int pack_dac8043(int addr, int val, int *bitstring)
+{
+	*bitstring = val & 0xfff;
+	return 12;
+}
+
+static int pack_ad8522(int addr, int val, int *bitstring)
+{
+	*bitstring = (val & 0xfff) | (addr ? 0xc000 : 0xa000);
+	return 16;
+}
+
+static int pack_ad8804(int addr, int val, int *bitstring)
+{
+	*bitstring = ((addr & 0xf) << 8) | (val & 0xff);
+	return 12;
+}
+
+static int pack_ad8842(int addr, int val, int *bitstring)
+{
+	*bitstring = ((addr + 1) << 8) | (val & 0xff);
+	return 12;
+}
+
+#if 0
+/*
+ *	Read the GPCTs current value.
+ */
+static int GPCT_G_Watch(struct comedi_device * dev, int chan)
+{
+	unsigned int hi1, hi2, lo;
+
+	devpriv->gpct_command[chan] &= ~G_Save_Trace;
+	devpriv->stc_writew(dev, devpriv->gpct_command[chan],
+		G_Command_Register(chan));
+
+	devpriv->gpct_command[chan] |= G_Save_Trace;
+	devpriv->stc_writew(dev, devpriv->gpct_command[chan],
+		G_Command_Register(chan));
+
+	/* This procedure is used because the two registers cannot
+	 * be read atomically. */
+	do {
+		hi1 = devpriv->stc_readw(dev, G_Save_Register_High(chan));
+		lo = devpriv->stc_readw(dev, G_Save_Register_Low(chan));
+		hi2 = devpriv->stc_readw(dev, G_Save_Register_High(chan));
+	} while (hi1 != hi2);
+
+	return (hi1 << 16) | lo;
+}
+
+static void GPCT_Reset(struct comedi_device * dev, int chan)
+{
+	int temp_ack_reg = 0;
+
+	//printk("GPCT_Reset...");
+	devpriv->gpct_cur_operation[chan] = GPCT_RESET;
+
+	switch (chan) {
+	case 0:
+		devpriv->stc_writew(dev, G0_Reset, Joint_Reset_Register);
+		ni_set_bits(dev, Interrupt_A_Enable_Register,
+			G0_TC_Interrupt_Enable, 0);
+		ni_set_bits(dev, Interrupt_A_Enable_Register,
+			G0_Gate_Interrupt_Enable, 0);
+		temp_ack_reg |= G0_Gate_Error_Confirm;
+		temp_ack_reg |= G0_TC_Error_Confirm;
+		temp_ack_reg |= G0_TC_Interrupt_Ack;
+		temp_ack_reg |= G0_Gate_Interrupt_Ack;
+		devpriv->stc_writew(dev, temp_ack_reg,
+			Interrupt_A_Ack_Register);
+
+		//problem...this interferes with the other ctr...
+		devpriv->an_trig_etc_reg |= GPFO_0_Output_Enable;
+		devpriv->stc_writew(dev, devpriv->an_trig_etc_reg,
+			Analog_Trigger_Etc_Register);
+		break;
+	case 1:
+		devpriv->stc_writew(dev, G1_Reset, Joint_Reset_Register);
+		ni_set_bits(dev, Interrupt_B_Enable_Register,
+			G1_TC_Interrupt_Enable, 0);
+		ni_set_bits(dev, Interrupt_B_Enable_Register,
+			G0_Gate_Interrupt_Enable, 0);
+		temp_ack_reg |= G1_Gate_Error_Confirm;
+		temp_ack_reg |= G1_TC_Error_Confirm;
+		temp_ack_reg |= G1_TC_Interrupt_Ack;
+		temp_ack_reg |= G1_Gate_Interrupt_Ack;
+		devpriv->stc_writew(dev, temp_ack_reg,
+			Interrupt_B_Ack_Register);
+
+		devpriv->an_trig_etc_reg |= GPFO_1_Output_Enable;
+		devpriv->stc_writew(dev, devpriv->an_trig_etc_reg,
+			Analog_Trigger_Etc_Register);
+		break;
+	};
+
+	devpriv->gpct_mode[chan] = 0;
+	devpriv->gpct_input_select[chan] = 0;
+	devpriv->gpct_command[chan] = 0;
+
+	devpriv->gpct_command[chan] |= G_Synchronized_Gate;
+
+	devpriv->stc_writew(dev, devpriv->gpct_mode[chan],
+		G_Mode_Register(chan));
+	devpriv->stc_writew(dev, devpriv->gpct_input_select[chan],
+		G_Input_Select_Register(chan));
+	devpriv->stc_writew(dev, 0, G_Autoincrement_Register(chan));
+
+	//printk("exit GPCT_Reset\n");
+}
+
+#endif
+
+static int ni_gpct_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	struct ni_gpct *counter = s->private;
+	return ni_tio_insn_config(counter, insn, data);
+}
+
+static int ni_gpct_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	struct ni_gpct *counter = s->private;
+	return ni_tio_rinsn(counter, insn, data);
+}
+
+static int ni_gpct_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	struct ni_gpct *counter = s->private;
+	return ni_tio_winsn(counter, insn, data);
+}
+
+static int ni_gpct_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	int retval;
+#ifdef PCIDMA
+	struct ni_gpct *counter = s->private;
+//      const struct comedi_cmd *cmd = &s->async->cmd;
+
+	retval = ni_request_gpct_mite_channel(dev, counter->counter_index,
+		COMEDI_INPUT);
+	if (retval) {
+		comedi_error(dev,
+			"no dma channel available for use by counter");
+		return retval;
+	}
+	ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL);
+	ni_e_series_enable_second_irq(dev, counter->counter_index, 1);
+	retval = ni_tio_cmd(counter, s->async);
+#else
+	retval = -ENOTSUPP;
+#endif
+	return retval;
+}
+
+static int ni_gpct_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+#ifdef PCIDMA
+	struct ni_gpct *counter = s->private;
+
+	return ni_tio_cmdtest(counter, cmd);
+#else
+	return -ENOTSUPP;
+#endif
+}
+
+static int ni_gpct_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+#ifdef PCIDMA
+	struct ni_gpct *counter = s->private;
+	int retval;
+
+	retval = ni_tio_cancel(counter);
+	ni_e_series_enable_second_irq(dev, counter->counter_index, 0);
+	ni_release_gpct_mite_channel(dev, counter->counter_index);
+	return retval;
+#else
+	return 0;
+#endif
+}
+
+/*
+ *
+ *  Programmable Function Inputs
+ *
+ */
+
+static int ni_m_series_set_pfi_routing(struct comedi_device * dev, unsigned chan,
+	unsigned source)
+{
+	unsigned pfi_reg_index;
+	unsigned array_offset;
+	if ((source & 0x1f) != source)
+		return -EINVAL;
+	pfi_reg_index = 1 + chan / 3;
+	array_offset = pfi_reg_index - 1;
+	devpriv->pfi_output_select_reg[array_offset] &=
+		~MSeries_PFI_Output_Select_Mask(chan);
+	devpriv->pfi_output_select_reg[array_offset] |=
+		MSeries_PFI_Output_Select_Bits(chan, source);
+	ni_writew(devpriv->pfi_output_select_reg[array_offset],
+		M_Offset_PFI_Output_Select(pfi_reg_index));
+	return 2;
+}
+
+static int ni_old_set_pfi_routing(struct comedi_device * dev, unsigned chan,
+	unsigned source)
+{
+	// pre-m-series boards have fixed signals on pfi pins
+	if (source != ni_old_get_pfi_routing(dev, chan))
+		return -EINVAL;
+	return 2;
+}
+
+static int ni_set_pfi_routing(struct comedi_device * dev, unsigned chan,
+	unsigned source)
+{
+	if (boardtype.reg_type & ni_reg_m_series_mask)
+		return ni_m_series_set_pfi_routing(dev, chan, source);
+	else
+		return ni_old_set_pfi_routing(dev, chan, source);
+}
+
+static unsigned ni_m_series_get_pfi_routing(struct comedi_device * dev, unsigned chan)
+{
+	const unsigned array_offset = chan / 3;
+	return MSeries_PFI_Output_Select_Source(chan,
+		devpriv->pfi_output_select_reg[array_offset]);
+}
+
+static unsigned ni_old_get_pfi_routing(struct comedi_device * dev, unsigned chan)
+{
+	// pre-m-series boards have fixed signals on pfi pins
+	switch (chan) {
+	case 0:
+		return NI_PFI_OUTPUT_AI_START1;
+		break;
+	case 1:
+		return NI_PFI_OUTPUT_AI_START2;
+		break;
+	case 2:
+		return NI_PFI_OUTPUT_AI_CONVERT;
+		break;
+	case 3:
+		return NI_PFI_OUTPUT_G_SRC1;
+		break;
+	case 4:
+		return NI_PFI_OUTPUT_G_GATE1;
+		break;
+	case 5:
+		return NI_PFI_OUTPUT_AO_UPDATE_N;
+		break;
+	case 6:
+		return NI_PFI_OUTPUT_AO_START1;
+		break;
+	case 7:
+		return NI_PFI_OUTPUT_AI_START_PULSE;
+		break;
+	case 8:
+		return NI_PFI_OUTPUT_G_SRC0;
+		break;
+	case 9:
+		return NI_PFI_OUTPUT_G_GATE0;
+		break;
+	default:
+		rt_printk("%s: bug, unhandled case in switch.\n", __FUNCTION__);
+		break;
+	}
+	return 0;
+}
+
+static unsigned ni_get_pfi_routing(struct comedi_device * dev, unsigned chan)
+{
+	if (boardtype.reg_type & ni_reg_m_series_mask)
+		return ni_m_series_get_pfi_routing(dev, chan);
+	else
+		return ni_old_get_pfi_routing(dev, chan);
+}
+
+static int ni_config_filter(struct comedi_device * dev, unsigned pfi_channel,
+	enum ni_pfi_filter_select filter)
+{
+	unsigned bits;
+	if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) {
+		return -ENOTSUPP;
+	}
+	bits = ni_readl(M_Offset_PFI_Filter);
+	bits &= ~MSeries_PFI_Filter_Select_Mask(pfi_channel);
+	bits |= MSeries_PFI_Filter_Select_Bits(pfi_channel, filter);
+	ni_writel(bits, M_Offset_PFI_Filter);
+	return 0;
+}
+
+static int ni_pfi_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) {
+		return -ENOTSUPP;
+	}
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= (data[0] & data[1]);
+		ni_writew(s->state, M_Offset_PFI_DO);
+	}
+	data[1] = ni_readw(M_Offset_PFI_DI);
+	return 2;
+}
+
+static int ni_pfi_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int chan;
+
+	if (insn->n < 1)
+		return -EINVAL;
+
+	chan = CR_CHAN(insn->chanspec);
+
+	switch (data[0]) {
+	case COMEDI_OUTPUT:
+		ni_set_bits(dev, IO_Bidirection_Pin_Register, 1 << chan, 1);
+		break;
+	case COMEDI_INPUT:
+		ni_set_bits(dev, IO_Bidirection_Pin_Register, 1 << chan, 0);
+		break;
+	case INSN_CONFIG_DIO_QUERY:
+		data[1] =
+			(devpriv->
+			io_bidirection_pin_reg & (1 << chan)) ? COMEDI_OUTPUT :
+			COMEDI_INPUT;
+		return 0;
+		break;
+	case INSN_CONFIG_SET_ROUTING:
+		return ni_set_pfi_routing(dev, chan, data[1]);
+		break;
+	case INSN_CONFIG_GET_ROUTING:
+		data[1] = ni_get_pfi_routing(dev, chan);
+		break;
+	case INSN_CONFIG_FILTER:
+		return ni_config_filter(dev, chan, data[1]);
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/*
+ *
+ *  NI RTSI Bus Functions
+ *
+ */
+static void ni_rtsi_init(struct comedi_device * dev)
+{
+	// Initialises the RTSI bus signal switch to a default state
+
+	// Set clock mode to internal
+	devpriv->clock_and_fout2 = MSeries_RTSI_10MHz_Bit;
+	if (ni_set_master_clock(dev, NI_MIO_INTERNAL_CLOCK, 0) < 0) {
+		rt_printk("ni_set_master_clock failed, bug?");
+	}
+	// default internal lines routing to RTSI bus lines
+	devpriv->rtsi_trig_a_output_reg =
+		RTSI_Trig_Output_Bits(0,
+		NI_RTSI_OUTPUT_ADR_START1) | RTSI_Trig_Output_Bits(1,
+		NI_RTSI_OUTPUT_ADR_START2) | RTSI_Trig_Output_Bits(2,
+		NI_RTSI_OUTPUT_SCLKG) | RTSI_Trig_Output_Bits(3,
+		NI_RTSI_OUTPUT_DACUPDN);
+	devpriv->stc_writew(dev, devpriv->rtsi_trig_a_output_reg,
+		RTSI_Trig_A_Output_Register);
+	devpriv->rtsi_trig_b_output_reg =
+		RTSI_Trig_Output_Bits(4,
+		NI_RTSI_OUTPUT_DA_START1) | RTSI_Trig_Output_Bits(5,
+		NI_RTSI_OUTPUT_G_SRC0) | RTSI_Trig_Output_Bits(6,
+		NI_RTSI_OUTPUT_G_GATE0);
+	if (boardtype.reg_type & ni_reg_m_series_mask)
+		devpriv->rtsi_trig_b_output_reg |=
+			RTSI_Trig_Output_Bits(7, NI_RTSI_OUTPUT_RTSI_OSC);
+	devpriv->stc_writew(dev, devpriv->rtsi_trig_b_output_reg,
+		RTSI_Trig_B_Output_Register);
+
+	// Sets the source and direction of the 4 on board lines
+//      devpriv->stc_writew(dev, 0x0000, RTSI_Board_Register);
+}
+
+static int ni_rtsi_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	data[1] = 0;
+
+	return 2;
+}
+
+/* Find best multiplier/divider to try and get the PLL running at 80 MHz
+ * given an arbitrary frequency input clock */
+static int ni_mseries_get_pll_parameters(unsigned reference_period_ns,
+	unsigned *freq_divider, unsigned *freq_multiplier,
+	unsigned *actual_period_ns)
+{
+	unsigned div;
+	unsigned best_div = 1;
+	static const unsigned max_div = 0x10;
+	unsigned mult;
+	unsigned best_mult = 1;
+	static const unsigned max_mult = 0x100;
+	static const unsigned pico_per_nano = 1000;
+
+	const unsigned reference_picosec = reference_period_ns * pico_per_nano;
+	/* m-series wants the phased-locked loop to output 80MHz, which is divided by 4 to
+	 * 20 MHz for most timing clocks */
+	static const unsigned target_picosec = 12500;
+	static const unsigned fudge_factor_80_to_20Mhz = 4;
+	int best_period_picosec = 0;
+	for (div = 1; div <= max_div; ++div) {
+		for (mult = 1; mult <= max_mult; ++mult) {
+			unsigned new_period_ps =
+				(reference_picosec * div) / mult;
+			if (abs(new_period_ps - target_picosec) <
+				abs(best_period_picosec - target_picosec)) {
+				best_period_picosec = new_period_ps;
+				best_div = div;
+				best_mult = mult;
+			}
+		}
+	}
+	if (best_period_picosec == 0) {
+		rt_printk("%s: bug, failed to find pll parameters\n",
+			__FUNCTION__);
+		return -EIO;
+	}
+	*freq_divider = best_div;
+	*freq_multiplier = best_mult;
+	*actual_period_ns =
+		(best_period_picosec * fudge_factor_80_to_20Mhz +
+		(pico_per_nano / 2)) / pico_per_nano;
+	return 0;
+}
+
+static inline unsigned num_configurable_rtsi_channels(struct comedi_device * dev)
+{
+	if (boardtype.reg_type & ni_reg_m_series_mask)
+		return 8;
+	else
+		return 7;
+}
+
+static int ni_mseries_set_pll_master_clock(struct comedi_device * dev, unsigned source,
+	unsigned period_ns)
+{
+	static const unsigned min_period_ns = 50;
+	static const unsigned max_period_ns = 1000;
+	static const unsigned timeout = 1000;
+	unsigned pll_control_bits;
+	unsigned freq_divider;
+	unsigned freq_multiplier;
+	unsigned i;
+	int retval;
+	if (source == NI_MIO_PLL_PXI10_CLOCK)
+		period_ns = 100;
+	// these limits are somewhat arbitrary, but NI advertises 1 to 20MHz range so we'll use that
+	if (period_ns < min_period_ns || period_ns > max_period_ns) {
+		rt_printk
+			("%s: you must specify an input clock frequency between %i and %i nanosec "
+			"for the phased-lock loop.\n", __FUNCTION__,
+			min_period_ns, max_period_ns);
+		return -EINVAL;
+	}
+	devpriv->rtsi_trig_direction_reg &= ~Use_RTSI_Clock_Bit;
+	devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
+		RTSI_Trig_Direction_Register);
+	pll_control_bits =
+		MSeries_PLL_Enable_Bit | MSeries_PLL_VCO_Mode_75_150MHz_Bits;
+	devpriv->clock_and_fout2 |=
+		MSeries_Timebase1_Select_Bit | MSeries_Timebase3_Select_Bit;
+	devpriv->clock_and_fout2 &= ~MSeries_PLL_In_Source_Select_Mask;
+	switch (source) {
+	case NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK:
+		devpriv->clock_and_fout2 |=
+			MSeries_PLL_In_Source_Select_Star_Trigger_Bits;
+		retval = ni_mseries_get_pll_parameters(period_ns, &freq_divider,
+			&freq_multiplier, &devpriv->clock_ns);
+		if (retval < 0)
+			return retval;
+		break;
+	case NI_MIO_PLL_PXI10_CLOCK:
+		/* pxi clock is 10MHz */
+		devpriv->clock_and_fout2 |=
+			MSeries_PLL_In_Source_Select_PXI_Clock10;
+		retval = ni_mseries_get_pll_parameters(period_ns, &freq_divider,
+			&freq_multiplier, &devpriv->clock_ns);
+		if (retval < 0)
+			return retval;
+		break;
+	default:
+		{
+			unsigned rtsi_channel;
+			static const unsigned max_rtsi_channel = 7;
+			for (rtsi_channel = 0; rtsi_channel <= max_rtsi_channel;
+				++rtsi_channel) {
+				if (source ==
+					NI_MIO_PLL_RTSI_CLOCK(rtsi_channel)) {
+					devpriv->clock_and_fout2 |=
+						MSeries_PLL_In_Source_Select_RTSI_Bits
+						(rtsi_channel);
+					break;
+				}
+			}
+			if (rtsi_channel > max_rtsi_channel)
+				return -EINVAL;
+			retval = ni_mseries_get_pll_parameters(period_ns,
+				&freq_divider, &freq_multiplier,
+				&devpriv->clock_ns);
+			if (retval < 0)
+				return retval;
+		}
+		break;
+	}
+	ni_writew(devpriv->clock_and_fout2, M_Offset_Clock_and_Fout2);
+	pll_control_bits |=
+		MSeries_PLL_Divisor_Bits(freq_divider) |
+		MSeries_PLL_Multiplier_Bits(freq_multiplier);
+//      rt_printk("using divider=%i, multiplier=%i for PLL.  pll_control_bits = 0x%x\n", freq_divider, freq_multiplier, pll_control_bits);
+//      rt_printk("clock_ns=%d\n", devpriv->clock_ns);
+	ni_writew(pll_control_bits, M_Offset_PLL_Control);
+	devpriv->clock_source = source;
+	/* it seems to typically take a few hundred microseconds for PLL to lock */
+	for (i = 0; i < timeout; ++i) {
+		if (ni_readw(M_Offset_PLL_Status) & MSeries_PLL_Locked_Bit) {
+			break;
+		}
+		udelay(1);
+	}
+	if (i == timeout) {
+		rt_printk
+			("%s: timed out waiting for PLL to lock to reference clock source %i with period %i ns.\n",
+			__FUNCTION__, source, period_ns);
+		return -ETIMEDOUT;
+	}
+	return 3;
+}
+
+static int ni_set_master_clock(struct comedi_device * dev, unsigned source,
+	unsigned period_ns)
+{
+	if (source == NI_MIO_INTERNAL_CLOCK) {
+		devpriv->rtsi_trig_direction_reg &= ~Use_RTSI_Clock_Bit;
+		devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
+			RTSI_Trig_Direction_Register);
+		devpriv->clock_ns = TIMEBASE_1_NS;
+		if (boardtype.reg_type & ni_reg_m_series_mask) {
+			devpriv->clock_and_fout2 &=
+				~(MSeries_Timebase1_Select_Bit |
+				MSeries_Timebase3_Select_Bit);
+			ni_writew(devpriv->clock_and_fout2,
+				M_Offset_Clock_and_Fout2);
+			ni_writew(0, M_Offset_PLL_Control);
+		}
+		devpriv->clock_source = source;
+	} else {
+		if (boardtype.reg_type & ni_reg_m_series_mask) {
+			return ni_mseries_set_pll_master_clock(dev, source,
+				period_ns);
+		} else {
+			if (source == NI_MIO_RTSI_CLOCK) {
+				devpriv->rtsi_trig_direction_reg |=
+					Use_RTSI_Clock_Bit;
+				devpriv->stc_writew(dev,
+					devpriv->rtsi_trig_direction_reg,
+					RTSI_Trig_Direction_Register);
+				if (period_ns == 0) {
+					rt_printk
+						("%s: we don't handle an unspecified clock period correctly yet, returning error.\n",
+						__FUNCTION__);
+					return -EINVAL;
+				} else {
+					devpriv->clock_ns = period_ns;
+				}
+				devpriv->clock_source = source;
+			} else
+				return -EINVAL;
+		}
+	}
+	return 3;
+}
+
+static int ni_valid_rtsi_output_source(struct comedi_device * dev, unsigned chan,
+	unsigned source)
+{
+	if (chan >= num_configurable_rtsi_channels(dev)) {
+		if (chan == old_RTSI_clock_channel) {
+			if (source == NI_RTSI_OUTPUT_RTSI_OSC)
+				return 1;
+			else {
+				rt_printk
+					("%s: invalid source for channel=%i, channel %i is always the RTSI clock for pre-m-series boards.\n",
+					__FUNCTION__, chan,
+					old_RTSI_clock_channel);
+				return 0;
+			}
+		}
+		return 0;
+	}
+	switch (source) {
+	case NI_RTSI_OUTPUT_ADR_START1:
+	case NI_RTSI_OUTPUT_ADR_START2:
+	case NI_RTSI_OUTPUT_SCLKG:
+	case NI_RTSI_OUTPUT_DACUPDN:
+	case NI_RTSI_OUTPUT_DA_START1:
+	case NI_RTSI_OUTPUT_G_SRC0:
+	case NI_RTSI_OUTPUT_G_GATE0:
+	case NI_RTSI_OUTPUT_RGOUT0:
+	case NI_RTSI_OUTPUT_RTSI_BRD_0:
+		return 1;
+		break;
+	case NI_RTSI_OUTPUT_RTSI_OSC:
+		if (boardtype.reg_type & ni_reg_m_series_mask)
+			return 1;
+		else
+			return 0;
+		break;
+	default:
+		return 0;
+		break;
+	}
+}
+
+static int ni_set_rtsi_routing(struct comedi_device * dev, unsigned chan,
+	unsigned source)
+{
+	if (ni_valid_rtsi_output_source(dev, chan, source) == 0)
+		return -EINVAL;
+	if (chan < 4) {
+		devpriv->rtsi_trig_a_output_reg &= ~RTSI_Trig_Output_Mask(chan);
+		devpriv->rtsi_trig_a_output_reg |=
+			RTSI_Trig_Output_Bits(chan, source);
+		devpriv->stc_writew(dev, devpriv->rtsi_trig_a_output_reg,
+			RTSI_Trig_A_Output_Register);
+	} else if (chan < 8) {
+		devpriv->rtsi_trig_b_output_reg &= ~RTSI_Trig_Output_Mask(chan);
+		devpriv->rtsi_trig_b_output_reg |=
+			RTSI_Trig_Output_Bits(chan, source);
+		devpriv->stc_writew(dev, devpriv->rtsi_trig_b_output_reg,
+			RTSI_Trig_B_Output_Register);
+	}
+	return 2;
+}
+
+static unsigned ni_get_rtsi_routing(struct comedi_device * dev, unsigned chan)
+{
+	if (chan < 4) {
+		return RTSI_Trig_Output_Source(chan,
+			devpriv->rtsi_trig_a_output_reg);
+	} else if (chan < num_configurable_rtsi_channels(dev)) {
+		return RTSI_Trig_Output_Source(chan,
+			devpriv->rtsi_trig_b_output_reg);
+	} else {
+		if (chan == old_RTSI_clock_channel)
+			return NI_RTSI_OUTPUT_RTSI_OSC;
+		rt_printk("%s: bug! should never get here?\n", __FUNCTION__);
+		return 0;
+	}
+}
+
+static int ni_rtsi_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int chan = CR_CHAN(insn->chanspec);
+	switch (data[0]) {
+	case INSN_CONFIG_DIO_OUTPUT:
+		if (chan < num_configurable_rtsi_channels(dev)) {
+			devpriv->rtsi_trig_direction_reg |=
+				RTSI_Output_Bit(chan,
+				(boardtype.reg_type & ni_reg_m_series_mask) !=
+				0);
+		} else if (chan == old_RTSI_clock_channel) {
+			devpriv->rtsi_trig_direction_reg |=
+				Drive_RTSI_Clock_Bit;
+		}
+		devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
+			RTSI_Trig_Direction_Register);
+		break;
+	case INSN_CONFIG_DIO_INPUT:
+		if (chan < num_configurable_rtsi_channels(dev)) {
+			devpriv->rtsi_trig_direction_reg &=
+				~RTSI_Output_Bit(chan,
+				(boardtype.reg_type & ni_reg_m_series_mask) !=
+				0);
+		} else if (chan == old_RTSI_clock_channel) {
+			devpriv->rtsi_trig_direction_reg &=
+				~Drive_RTSI_Clock_Bit;
+		}
+		devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
+			RTSI_Trig_Direction_Register);
+		break;
+	case INSN_CONFIG_DIO_QUERY:
+		if (chan < num_configurable_rtsi_channels(dev)) {
+			data[1] =
+				(devpriv->
+				rtsi_trig_direction_reg & RTSI_Output_Bit(chan,
+					(boardtype.
+						reg_type & ni_reg_m_series_mask)
+					!=
+					0)) ? INSN_CONFIG_DIO_OUTPUT :
+				INSN_CONFIG_DIO_INPUT;
+		} else if (chan == old_RTSI_clock_channel) {
+			data[1] =
+				(devpriv->
+				rtsi_trig_direction_reg & Drive_RTSI_Clock_Bit)
+				? INSN_CONFIG_DIO_OUTPUT :
+				INSN_CONFIG_DIO_INPUT;
+		}
+		return 2;
+		break;
+	case INSN_CONFIG_SET_CLOCK_SRC:
+		return ni_set_master_clock(dev, data[1], data[2]);
+		break;
+	case INSN_CONFIG_GET_CLOCK_SRC:
+		data[1] = devpriv->clock_source;
+		data[2] = devpriv->clock_ns;
+		return 3;
+		break;
+	case INSN_CONFIG_SET_ROUTING:
+		return ni_set_rtsi_routing(dev, chan, data[1]);
+		break;
+	case INSN_CONFIG_GET_ROUTING:
+		data[1] = ni_get_rtsi_routing(dev, chan);
+		return 2;
+		break;
+	default:
+		return -EINVAL;
+		break;
+	}
+	return 1;
+}
+
+static int cs5529_wait_for_idle(struct comedi_device * dev)
+{
+	unsigned short status;
+	const int timeout = HZ;
+	int i;
+
+	for (i = 0; i < timeout; i++) {
+		status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx);
+		if ((status & CSS_ADC_BUSY) == 0) {
+			break;
+		}
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (schedule_timeout(1)) {
+			return -EIO;
+		}
+	}
+//printk("looped %i times waiting for idle\n", i);
+	if (i == timeout) {
+		rt_printk("%s: %s: timeout\n", __FILE__, __FUNCTION__);
+		return -ETIME;
+	}
+	return 0;
+}
+
+static void cs5529_command(struct comedi_device * dev, unsigned short value)
+{
+	static const int timeout = 100;
+	int i;
+
+	ni_ao_win_outw(dev, value, CAL_ADC_Command_67xx);
+	/* give time for command to start being serially clocked into cs5529.
+	 * this insures that the CSS_ADC_BUSY bit will get properly
+	 * set before we exit this function.
+	 */
+	for (i = 0; i < timeout; i++) {
+		if ((ni_ao_win_inw(dev, CAL_ADC_Status_67xx) & CSS_ADC_BUSY))
+			break;
+		comedi_udelay(1);
+	}
+//printk("looped %i times writing command to cs5529\n", i);
+	if (i == timeout) {
+		comedi_error(dev, "possible problem - never saw adc go busy?");
+	}
+}
+
+/* write to cs5529 register */
+static void cs5529_config_write(struct comedi_device * dev, unsigned int value,
+	unsigned int reg_select_bits)
+{
+	ni_ao_win_outw(dev, ((value >> 16) & 0xff),
+		CAL_ADC_Config_Data_High_Word_67xx);
+	ni_ao_win_outw(dev, (value & 0xffff),
+		CAL_ADC_Config_Data_Low_Word_67xx);
+	reg_select_bits &= CSCMD_REGISTER_SELECT_MASK;
+	cs5529_command(dev, CSCMD_COMMAND | reg_select_bits);
+	if (cs5529_wait_for_idle(dev))
+		comedi_error(dev, "time or signal in cs5529_config_write()");
+}
+
+#ifdef NI_CS5529_DEBUG
+/* read from cs5529 register */
+static unsigned int cs5529_config_read(struct comedi_device * dev,
+	unsigned int reg_select_bits)
+{
+	unsigned int value;
+
+	reg_select_bits &= CSCMD_REGISTER_SELECT_MASK;
+	cs5529_command(dev, CSCMD_COMMAND | CSCMD_READ | reg_select_bits);
+	if (cs5529_wait_for_idle(dev))
+		comedi_error(dev, "timeout or signal in cs5529_config_read()");
+	value = (ni_ao_win_inw(dev,
+			CAL_ADC_Config_Data_High_Word_67xx) << 16) & 0xff0000;
+	value |= ni_ao_win_inw(dev, CAL_ADC_Config_Data_Low_Word_67xx) & 0xffff;
+	return value;
+}
+#endif
+
+static int cs5529_do_conversion(struct comedi_device * dev, unsigned short *data)
+{
+	int retval;
+	unsigned short status;
+
+	cs5529_command(dev, CSCMD_COMMAND | CSCMD_SINGLE_CONVERSION);
+	retval = cs5529_wait_for_idle(dev);
+	if (retval) {
+		comedi_error(dev,
+			"timeout or signal in cs5529_do_conversion()");
+		return -ETIME;
+	}
+	status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx);
+	if (status & CSS_OSC_DETECT) {
+		rt_printk
+			("ni_mio_common: cs5529 conversion error, status CSS_OSC_DETECT\n");
+		return -EIO;
+	}
+	if (status & CSS_OVERRANGE) {
+		rt_printk
+			("ni_mio_common: cs5529 conversion error, overrange (ignoring)\n");
+	}
+	if (data) {
+		*data = ni_ao_win_inw(dev, CAL_ADC_Data_67xx);
+		/* cs5529 returns 16 bit signed data in bipolar mode */
+		*data ^= (1 << 15);
+	}
+	return 0;
+}
+
+static int cs5529_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n, retval;
+	unsigned short sample;
+	unsigned int channel_select;
+	const unsigned int INTERNAL_REF = 0x1000;
+
+	/* Set calibration adc source.  Docs lie, reference select bits 8 to 11
+	 * do nothing. bit 12 seems to chooses internal reference voltage, bit
+	 * 13 causes the adc input to go overrange (maybe reads external reference?) */
+	if (insn->chanspec & CR_ALT_SOURCE)
+		channel_select = INTERNAL_REF;
+	else
+		channel_select = CR_CHAN(insn->chanspec);
+	ni_ao_win_outw(dev, channel_select, AO_Calibration_Channel_Select_67xx);
+
+	for (n = 0; n < insn->n; n++) {
+		retval = cs5529_do_conversion(dev, &sample);
+		if (retval < 0)
+			return retval;
+		data[n] = sample;
+	}
+	return insn->n;
+}
+
+static int init_cs5529(struct comedi_device * dev)
+{
+	unsigned int config_bits =
+		CSCFG_PORT_MODE | CSCFG_WORD_RATE_2180_CYCLES;
+
+#if 1
+	/* do self-calibration */
+	cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET_GAIN,
+		CSCMD_CONFIG_REGISTER);
+	/* need to force a conversion for calibration to run */
+	cs5529_do_conversion(dev, NULL);
+#else
+	/* force gain calibration to 1 */
+	cs5529_config_write(dev, 0x400000, CSCMD_GAIN_REGISTER);
+	cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET,
+		CSCMD_CONFIG_REGISTER);
+	if (cs5529_wait_for_idle(dev))
+		comedi_error(dev, "timeout or signal in init_cs5529()\n");
+#endif
+#ifdef NI_CS5529_DEBUG
+	rt_printk("config: 0x%x\n", cs5529_config_read(dev,
+		CSCMD_CONFIG_REGISTER));
+	rt_printk("gain: 0x%x\n", cs5529_config_read(dev,
+		CSCMD_GAIN_REGISTER));
+	rt_printk("offset: 0x%x\n", cs5529_config_read(dev,
+		CSCMD_OFFSET_REGISTER));
+#endif
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c
new file mode 100644
index 0000000..d6357c2
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_mio_cs.c
@@ -0,0 +1,551 @@
+/*
+    comedi/drivers/ni_mio_cs.c
+    Hardware driver for NI PCMCIA MIO E series cards
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 1997-2000 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: ni_mio_cs
+Description: National Instruments DAQCard E series
+Author: ds
+Status: works
+Devices: [National Instruments] DAQCard-AI-16XE-50 (ni_mio_cs),
+  DAQCard-AI-16E-4, DAQCard-6062E, DAQCard-6024E, DAQCard-6036E
+Updated: Thu Oct 23 19:43:17 CDT 2003
+
+See the notes in the ni_atmio.o driver.
+*/
+/*
+	The real guts of the driver is in ni_mio_common.c, which is
+	included by all the E series drivers.
+
+	References for specifications:
+
+	   341080a.pdf  DAQCard E Series Register Level Programmer Manual
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+
+#include "ni_stc.h"
+#include "8255.h"
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+
+#undef DEBUG
+
+#define ATMIO 1
+#undef PCIMIO
+
+/*
+ *  AT specific setup
+ */
+
+#define NI_SIZE 0x20
+
+#define MAX_N_CALDACS 32
+
+static const ni_board ni_boards[] = {
+      {device_id:0x010d,
+	      name:	"DAQCard-ai-16xe-50",
+	      n_adchan:16,
+	      adbits:	16,
+	      ai_fifo_depth:1024,
+	      alwaysdither:0,
+	      gainlkup:ai_gain_8,
+	      ai_speed:5000,
+	      n_aochan:0,
+	      aobits:	0,
+	      ao_fifo_depth:0,
+	      ao_unipolar:0,
+	      num_p0_dio_channels:8,
+	      has_8255:0,
+	      caldac:	{dac8800, dac8043},
+		},
+      {device_id:0x010c,
+	      name:	"DAQCard-ai-16e-4",
+	      n_adchan:16,
+	      adbits:	12,
+	      ai_fifo_depth:1024,
+	      alwaysdither:0,
+	      gainlkup:ai_gain_16,
+	      ai_speed:4000,
+	      n_aochan:0,
+	      aobits:	0,
+	      ao_fifo_depth:0,
+	      ao_unipolar:0,
+	      num_p0_dio_channels:8,
+	      has_8255:0,
+	      caldac:	{mb88341},	/* verified */
+		},
+      {device_id:0x02c4,
+	      name:	"DAQCard-6062E",
+	      n_adchan:16,
+	      adbits:	12,
+	      ai_fifo_depth:8192,
+	      alwaysdither:0,
+	      gainlkup:ai_gain_16,
+	      ai_speed:2000,
+	      n_aochan:2,
+	      aobits:	12,
+	      ao_fifo_depth:2048,
+	      ao_range_table:&range_bipolar10,
+	      ao_unipolar:0,
+	      ao_speed:1176,
+	      num_p0_dio_channels:8,
+	      has_8255:0,
+	      caldac:	{ad8804_debug},	/* verified */
+		},
+      {device_id:0x075e,
+	      name:	"DAQCard-6024E",	/* specs incorrect! */
+	      n_adchan:16,
+	      adbits:	12,
+	      ai_fifo_depth:1024,
+	      alwaysdither:0,
+	      gainlkup:ai_gain_16,
+	      ai_speed:5000,
+	      n_aochan:2,
+	      aobits:	12,
+	      ao_fifo_depth:0,
+	      ao_range_table:&range_bipolar10,
+	      ao_unipolar:0,
+	      ao_speed:1000000,
+	      num_p0_dio_channels:8,
+	      has_8255:0,
+	      caldac:	{ad8804_debug},
+		},
+      {device_id:0x0245,
+	      name:	"DAQCard-6036E",	/* specs incorrect! */
+	      n_adchan:16,
+	      adbits:	16,
+	      ai_fifo_depth:1024,
+	      alwaysdither:1,
+	      gainlkup:ai_gain_4,
+	      ai_speed:5000,
+	      n_aochan:2,
+	      aobits:	16,
+	      ao_fifo_depth:0,
+	      ao_range_table:&range_bipolar10,
+	      ao_unipolar:0,
+	      ao_speed:1000000,
+	      num_p0_dio_channels:8,
+	      has_8255:0,
+	      caldac:	{ad8804_debug},
+		},
+#if 0
+      {device_id:0x0000,	/* unknown */
+	      name:	"DAQCard-6715",
+	      n_adchan:0,
+	      n_aochan:8,
+	      aobits:	12,
+	      ao_671x:	8192,
+	      num_p0_dio_channels:8,
+	      caldac:	{mb88341, mb88341},
+		},
+#endif
+	/* N.B. Update ni_mio_cs_ids[] when entries added above. */
+};
+
+#define interrupt_pin(a)	0
+
+#define IRQ_POLARITY 1
+
+#define NI_E_IRQ_FLAGS		IRQF_SHARED
+
+struct ni_private {
+
+	struct pcmcia_device *link;
+
+ NI_PRIVATE_COMMON};
+
+#define devpriv ((struct ni_private *)dev->private)
+
+/* How we access registers */
+
+#define ni_writel(a,b)		(outl((a),(b)+dev->iobase))
+#define ni_readl(a)		(inl((a)+dev->iobase))
+#define ni_writew(a,b)		(outw((a),(b)+dev->iobase))
+#define ni_readw(a)		(inw((a)+dev->iobase))
+#define ni_writeb(a,b)		(outb((a),(b)+dev->iobase))
+#define ni_readb(a)		(inb((a)+dev->iobase))
+
+/* How we access windowed registers */
+
+/* We automatically take advantage of STC registers that can be
+ * read/written directly in the I/O space of the board.  The
+ * DAQCard devices map the low 8 STC registers to iobase+addr*2. */
+
+static void mio_cs_win_out(struct comedi_device * dev, uint16_t data, int addr)
+{
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+	if (addr < 8) {
+		ni_writew(data, addr * 2);
+	} else {
+		ni_writew(addr, Window_Address);
+		ni_writew(data, Window_Data);
+	}
+	comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+}
+
+static uint16_t mio_cs_win_in(struct comedi_device * dev, int addr)
+{
+	unsigned long flags;
+	uint16_t ret;
+
+	comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+	if (addr < 8) {
+		ret = ni_readw(addr * 2);
+	} else {
+		ni_writew(addr, Window_Address);
+		ret = ni_readw(Window_Data);
+	}
+	comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+
+	return ret;
+}
+
+static int mio_cs_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int mio_cs_detach(struct comedi_device * dev);
+static struct comedi_driver driver_ni_mio_cs = {
+      driver_name:"ni_mio_cs",
+      module:THIS_MODULE,
+      attach:mio_cs_attach,
+      detach:mio_cs_detach,
+};
+
+#include "ni_mio_common.c"
+
+static int ni_getboardtype(struct comedi_device * dev, struct pcmcia_device *link);
+
+/* clean up allocated resources */
+/* called when driver is removed */
+static int mio_cs_detach(struct comedi_device * dev)
+{
+	mio_common_detach(dev);
+
+	/* PCMCIA layer frees the IO region */
+
+	if (dev->irq) {
+		comedi_free_irq(dev->irq, dev);
+	}
+
+	return 0;
+}
+
+static void mio_cs_config(struct pcmcia_device *link);
+static void cs_release(struct pcmcia_device *link);
+static void cs_detach(struct pcmcia_device *);
+
+static struct pcmcia_device *cur_dev = NULL;
+static const dev_info_t dev_info = "ni_mio_cs";
+static dev_node_t dev_node = {
+	"ni_mio_cs",
+	COMEDI_MAJOR, 0,
+	NULL
+};
+static int cs_attach(struct pcmcia_device *link)
+{
+	link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+	link->io.NumPorts1 = 16;
+	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+	link->conf.Attributes = CONF_ENABLE_IRQ;
+	link->conf.IntType = INT_MEMORY_AND_IO;
+
+	cur_dev = link;
+
+	mio_cs_config(link);
+
+	return 0;
+}
+
+static void cs_release(struct pcmcia_device *link)
+{
+	pcmcia_disable_device(link);
+}
+
+static void cs_detach(struct pcmcia_device *link)
+{
+	DPRINTK("cs_detach(link=%p)\n", link);
+
+	if (link->dev_node) {
+		cs_release(link);
+	}
+}
+
+static int mio_cs_suspend(struct pcmcia_device *link)
+{
+	DPRINTK("pm suspend\n");
+
+	return 0;
+}
+
+static int mio_cs_resume(struct pcmcia_device *link)
+{
+	DPRINTK("pm resume\n");
+	return 0;
+}
+
+static void mio_cs_config(struct pcmcia_device *link)
+{
+	tuple_t tuple;
+	u_short buf[128];
+	cisparse_t parse;
+	int manfid = 0, prodid = 0;
+	int ret;
+
+	DPRINTK("mio_cs_config(link=%p)\n", link);
+
+	tuple.TupleData = (cisdata_t *) buf;
+	tuple.TupleOffset = 0;
+	tuple.TupleDataMax = 255;
+	tuple.Attributes = 0;
+
+	tuple.DesiredTuple = CISTPL_CONFIG;
+	ret = pcmcia_get_first_tuple(link, &tuple);
+	ret = pcmcia_get_tuple_data(link, &tuple);
+	ret = pcmcia_parse_tuple(&tuple, &parse);
+	link->conf.ConfigBase = parse.config.base;
+	link->conf.Present = parse.config.rmask[0];
+
+#if 0
+	tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
+	tuple.Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
+	info->multi(first_tuple(link, &tuple, &parse) == 0);
+#endif
+
+	tuple.DesiredTuple = CISTPL_MANFID;
+	tuple.Attributes = TUPLE_RETURN_COMMON;
+	if ((pcmcia_get_first_tuple(link, &tuple) == 0) &&
+		(pcmcia_get_tuple_data(link, &tuple) == 0)) {
+		manfid = le16_to_cpu(buf[0]);
+		prodid = le16_to_cpu(buf[1]);
+	}
+	//printk("manfid = 0x%04x, 0x%04x\n",manfid,prodid);
+
+	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+	tuple.Attributes = 0;
+	ret = pcmcia_get_first_tuple(link, &tuple);
+	ret = pcmcia_get_tuple_data(link, &tuple);
+	ret = pcmcia_parse_tuple(&tuple, &parse);
+
+#if 0
+	printk(" index: 0x%x\n", parse.cftable_entry.index);
+	printk(" flags: 0x%x\n", parse.cftable_entry.flags);
+	printk(" io flags: 0x%x\n", parse.cftable_entry.io.flags);
+	printk(" io nwin: 0x%x\n", parse.cftable_entry.io.nwin);
+	printk(" io base: 0x%x\n", parse.cftable_entry.io.win[0].base);
+	printk(" io len: 0x%x\n", parse.cftable_entry.io.win[0].len);
+	printk(" irq1: 0x%x\n", parse.cftable_entry.irq.IRQInfo1);
+	printk(" irq2: 0x%x\n", parse.cftable_entry.irq.IRQInfo2);
+	printk(" mem flags: 0x%x\n", parse.cftable_entry.mem.flags);
+	printk(" mem nwin: 0x%x\n", parse.cftable_entry.mem.nwin);
+	printk(" subtuples: 0x%x\n", parse.cftable_entry.subtuples);
+#endif
+
+#if 0
+	link->io.NumPorts1 = 0x20;
+	link->io.IOAddrLines = 5;
+	link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+#endif
+	link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
+	link->io.IOAddrLines =
+		parse.cftable_entry.io.flags & CISTPL_IO_LINES_MASK;
+	link->io.NumPorts2 = 0;
+
+	{
+		int base;
+		for (base = 0x000; base < 0x400; base += 0x20) {
+			link->io.BasePort1 = base;
+			ret = pcmcia_request_io(link, &link->io);
+			//printk("RequestIO 0x%02x\n",ret);
+			if (!ret)
+				break;
+		}
+	}
+
+	link->irq.IRQInfo1 = parse.cftable_entry.irq.IRQInfo1;
+	link->irq.IRQInfo2 = parse.cftable_entry.irq.IRQInfo2;
+	ret = pcmcia_request_irq(link, &link->irq);
+	if (ret) {
+		printk("pcmcia_request_irq() returned error: %i\n", ret);
+	}
+	//printk("RequestIRQ 0x%02x\n",ret);
+
+	link->conf.ConfigIndex = 1;
+
+	ret = pcmcia_request_configuration(link, &link->conf);
+	//printk("RequestConfiguration %d\n",ret);
+
+	link->dev_node = &dev_node;
+}
+
+static int mio_cs_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct pcmcia_device *link;
+	unsigned int irq;
+	int ret;
+
+	DPRINTK("mio_cs_attach(dev=%p,it=%p)\n", dev, it);
+
+	link = cur_dev;		/* XXX hack */
+	if (!link)
+		return -EIO;
+
+	dev->driver = &driver_ni_mio_cs;
+	dev->iobase = link->io.BasePort1;
+
+	irq = link->irq.AssignedIRQ;
+
+	printk("comedi%d: %s: DAQCard: io 0x%04lx, irq %u, ",
+		dev->minor, dev->driver->driver_name, dev->iobase, irq);
+
+#if 0
+	{
+		int i;
+
+		printk(" board fingerprint:");
+		for (i = 0; i < 32; i += 2) {
+			printk(" %04x %02x", inw(dev->iobase + i),
+				inb(dev->iobase + i + 1));
+		}
+		printk("\n");
+		printk(" board fingerprint (windowed):");
+		for (i = 0; i < 10; i++) {
+			printk(" 0x%04x", win_in(i));
+		}
+		printk("\n");
+	}
+#endif
+
+	dev->board_ptr = ni_boards + ni_getboardtype(dev, link);
+
+	printk(" %s", boardtype.name);
+	dev->board_name = boardtype.name;
+
+	if ((ret = comedi_request_irq(irq, ni_E_interrupt, NI_E_IRQ_FLAGS,
+				"ni_mio_cs", dev)) < 0) {
+		printk(" irq not available\n");
+		return -EINVAL;
+	}
+	dev->irq = irq;
+
+	/* allocate private area */
+	if ((ret = ni_alloc_private(dev)) < 0)
+		return ret;
+	devpriv->stc_writew = &mio_cs_win_out;
+	devpriv->stc_readw = &mio_cs_win_in;
+	devpriv->stc_writel = &win_out2;
+	devpriv->stc_readl = &win_in2;
+
+	if ((ret = ni_E_init(dev, it)) < 0) {
+		return ret;
+	}
+
+	return 0;
+}
+
+static int get_prodid(struct comedi_device * dev, struct pcmcia_device *link)
+{
+	tuple_t tuple;
+	u_short buf[128];
+	int prodid = 0;
+
+	tuple.TupleData = (cisdata_t *) buf;
+	tuple.TupleOffset = 0;
+	tuple.TupleDataMax = 255;
+	tuple.DesiredTuple = CISTPL_MANFID;
+	tuple.Attributes = TUPLE_RETURN_COMMON;
+	if ((pcmcia_get_first_tuple(link, &tuple) == 0) &&
+		(pcmcia_get_tuple_data(link, &tuple) == 0)) {
+		prodid = le16_to_cpu(buf[1]);
+	}
+
+	return prodid;
+}
+
+static int ni_getboardtype(struct comedi_device * dev, struct pcmcia_device *link)
+{
+	int id;
+	int i;
+
+	id = get_prodid(dev, link);
+
+	for (i = 0; i < n_ni_boards; i++) {
+		if (ni_boards[i].device_id == id) {
+			return i;
+		}
+	}
+
+	printk("unknown board 0x%04x -- pretend it is a ", id);
+
+	return 0;
+}
+
+#ifdef MODULE
+
+MODULE_LICENSE("GPL");
+
+static struct pcmcia_device_id ni_mio_cs_ids[] = {
+	PCMCIA_DEVICE_MANF_CARD(0x010b, 0x010d),	/* DAQCard-ai-16xe-50 */
+	PCMCIA_DEVICE_MANF_CARD(0x010b, 0x010c),	/* DAQCard-ai-16e-4 */
+	PCMCIA_DEVICE_MANF_CARD(0x010b, 0x02c4),	/* DAQCard-6062E */
+	PCMCIA_DEVICE_MANF_CARD(0x010b, 0x075e),	/* DAQCard-6024E */
+	PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0245),	/* DAQCard-6036E */
+	PCMCIA_DEVICE_NULL
+};
+
+MODULE_DEVICE_TABLE(pcmcia, ni_mio_cs_ids);
+
+struct pcmcia_driver ni_mio_cs_driver = {
+	.probe = &cs_attach,
+	.remove = &cs_detach,
+	.suspend = &mio_cs_suspend,
+	.resume = &mio_cs_resume,
+	.id_table = ni_mio_cs_ids,
+	.owner = THIS_MODULE,
+	.drv = {
+			.name = dev_info,
+		},
+};
+
+int init_module(void)
+{
+	pcmcia_register_driver(&ni_mio_cs_driver);
+	comedi_driver_register(&driver_ni_mio_cs);
+	return 0;
+}
+
+void cleanup_module(void)
+{
+	pcmcia_unregister_driver(&ni_mio_cs_driver);
+#if 0
+	while (cur_dev != NULL)
+		cs_detach(cur_dev->handle);
+#endif
+	comedi_driver_unregister(&driver_ni_mio_cs);
+}
+#endif
diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c
new file mode 100644
index 0000000..87def2c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_pcidio.c
@@ -0,0 +1,1302 @@
+/*
+    comedi/drivers/ni_pcidio.c
+    driver for National Instruments PCI-DIO-96/PCI-6508
+               National Instruments PCI-DIO-32HS
+               National Instruments PCI-6503
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 1999,2002 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: ni_pcidio
+Description: National Instruments PCI-DIO32HS, PCI-DIO96, PCI-6533, PCI-6503
+Author: ds
+Status: works
+Devices: [National Instruments] PCI-DIO-32HS (ni_pcidio), PXI-6533,
+  PCI-DIO-96, PCI-DIO-96B, PXI-6508, PCI-6503, PCI-6503B, PCI-6503X,
+  PXI-6503, PCI-6533, PCI-6534
+Updated: Sun, 21 Apr 2002 21:03:38 -0700
+
+The DIO-96 appears as four 8255 subdevices.  See the 8255
+driver notes for details.
+
+The DIO32HS board appears as one subdevice, with 32 channels.
+Each channel is individually I/O configurable.  The channel order
+is 0=A0, 1=A1, 2=A2, ... 8=B0, 16=C0, 24=D0.  The driver only
+supports simple digital I/O; no handshaking is supported.
+
+DMA mostly works for the PCI-DIO32HS, but only in timed input mode.
+
+This driver could be easily modified to support AT-MIO32HS and
+AT-MIO96.
+
+The PCI-6534 requires a firmware upload after power-up to work, the
+firmware data and instructions for loading it with comedi_config
+it are contained in the
+comedi_nonfree_firmware tarball available from http://www.comedi.org
+*/
+
+/*
+   This driver is for both the NI PCI-DIO-32HS and the PCI-DIO-96,
+   which have very different architectures.  But, since the '96 is
+   so simple, it is included here.
+
+   Manuals (available from ftp://ftp.natinst.com/support/manuals)
+
+	320938c.pdf	PCI-DIO-96/PXI-6508/PCI-6503 User Manual
+	321464b.pdf	AT/PCI-DIO-32HS User Manual
+	341329A.pdf	PCI-6533 Register-Level Programmer Manual
+	341330A.pdf	DAQ-DIO Technical Reference Manual
+
+ */
+
+#define USE_DMA
+//#define DEBUG 1
+//#define DEBUG_FLAGS
+
+#include "../comedidev.h"
+
+#include "mite.h"
+#include "8255.h"
+
+#undef DPRINTK
+#ifdef DEBUG
+#define DPRINTK(format, args...)	printk(format, ## args)
+#else
+#define DPRINTK(format, args...)
+#endif
+
+#define PCI_VENDOR_ID_NATINST	0x1093
+
+#define PCI_DIO_SIZE 4096
+#define PCI_MITE_SIZE 4096
+
+/* defines for the PCI-DIO-96 */
+
+#define NIDIO_8255_BASE(x)	((x)*4)
+#define NIDIO_A 0
+#define NIDIO_B 4
+#define NIDIO_C 8
+#define NIDIO_D 12
+
+/* defines for the PCI-DIO-32HS */
+
+#define Window_Address			4	/* W */
+#define Interrupt_And_Window_Status	4	/* R */
+#define IntStatus1				(1<<0)
+#define IntStatus2				(1<<1)
+#define WindowAddressStatus_mask		0x7c
+
+#define Master_DMA_And_Interrupt_Control 5	/* W */
+#define InterruptLine(x)			((x)&3)
+#define OpenInt				(1<<2)
+#define Group_Status			5	/* R */
+#define DataLeft				(1<<0)
+#define Req					(1<<2)
+#define StopTrig				(1<<3)
+
+#define Group_1_Flags			6	/* R */
+#define Group_2_Flags			7	/* R */
+#define TransferReady				(1<<0)
+#define CountExpired				(1<<1)
+#define Waited				(1<<5)
+#define PrimaryTC				(1<<6)
+#define SecondaryTC				(1<<7)
+  //#define SerialRose
+  //#define ReqRose
+  //#define Paused
+
+#define Group_1_First_Clear		6	/* W */
+#define Group_2_First_Clear		7	/* W */
+#define ClearWaited				(1<<3)
+#define ClearPrimaryTC			(1<<4)
+#define ClearSecondaryTC			(1<<5)
+#define DMAReset				(1<<6)
+#define FIFOReset				(1<<7)
+#define ClearAll				0xf8
+
+#define Group_1_FIFO			8	/* W */
+#define Group_2_FIFO			12	/* W */
+
+#define Transfer_Count			20
+#define Chip_ID_D			24
+#define Chip_ID_I			25
+#define Chip_ID_O			26
+#define Chip_Version			27
+#define Port_IO(x)			(28+(x))
+#define Port_Pin_Directions(x)		(32+(x))
+#define Port_Pin_Mask(x)		(36+(x))
+#define Port_Pin_Polarities(x)		(40+(x))
+
+#define Master_Clock_Routing		45
+#define RTSIClocking(x)			(((x)&3)<<4)
+
+#define Group_1_Second_Clear		46	/* W */
+#define Group_2_Second_Clear		47	/* W */
+#define ClearExpired				(1<<0)
+
+#define Port_Pattern(x)			(48+(x))
+
+#define Data_Path			64
+#define FIFOEnableA		(1<<0)
+#define FIFOEnableB		(1<<1)
+#define FIFOEnableC		(1<<2)
+#define FIFOEnableD		(1<<3)
+#define Funneling(x)		(((x)&3)<<4)
+#define GroupDirection	(1<<7)
+
+#define Protocol_Register_1		65
+#define OpMode				Protocol_Register_1
+#define RunMode(x)		((x)&7)
+#define Numbered		(1<<3)
+
+#define Protocol_Register_2		66
+#define ClockReg			Protocol_Register_2
+#define ClockLine(x)		(((x)&3)<<5)
+#define InvertStopTrig	(1<<7)
+#define DataLatching(x)       (((x)&3)<<5)
+
+#define Protocol_Register_3		67
+#define Sequence			Protocol_Register_3
+
+#define Protocol_Register_14		68	/* 16 bit */
+#define ClockSpeed			Protocol_Register_14
+
+#define Protocol_Register_4		70
+#define ReqReg				Protocol_Register_4
+#define ReqConditioning(x)	(((x)&7)<<3)
+
+#define Protocol_Register_5		71
+#define BlockMode			Protocol_Register_5
+
+#define FIFO_Control			72
+#define ReadyLevel(x)		((x)&7)
+
+#define Protocol_Register_6		73
+#define LinePolarities			Protocol_Register_6
+#define InvertAck		(1<<0)
+#define InvertReq		(1<<1)
+#define InvertClock		(1<<2)
+#define InvertSerial		(1<<3)
+#define OpenAck		(1<<4)
+#define OpenClock		(1<<5)
+
+#define Protocol_Register_7		74
+#define AckSer				Protocol_Register_7
+#define AckLine(x)		(((x)&3)<<2)
+#define ExchangePins		(1<<7)
+
+#define Interrupt_Control		75
+  /* bits same as flags */
+
+#define DMA_Line_Control_Group1		76
+#define DMA_Line_Control_Group2		108
+// channel zero is none
+static inline unsigned primary_DMAChannel_bits(unsigned channel)
+{
+	return channel & 0x3;
+}
+static inline unsigned secondary_DMAChannel_bits(unsigned channel)
+{
+	return (channel << 2) & 0xc;
+}
+
+#define Transfer_Size_Control		77
+#define TransferWidth(x)	((x)&3)
+#define TransferLength(x)	(((x)&3)<<3)
+#define RequireRLevel		(1<<5)
+
+#define Protocol_Register_15		79
+#define DAQOptions			Protocol_Register_15
+#define StartSource(x)			((x)&0x3)
+#define InvertStart				(1<<2)
+#define StopSource(x)				(((x)&0x3)<<3)
+#define ReqStart				(1<<6)
+#define PreStart				(1<<7)
+
+#define Pattern_Detection		81
+#define DetectionMethod			(1<<0)
+#define InvertMatch				(1<<1)
+#define IE_Pattern_Detection			(1<<2)
+
+#define Protocol_Register_9		82
+#define ReqDelay			Protocol_Register_9
+
+#define Protocol_Register_10		83
+#define ReqNotDelay			Protocol_Register_10
+
+#define Protocol_Register_11		84
+#define AckDelay			Protocol_Register_11
+
+#define Protocol_Register_12		85
+#define AckNotDelay			Protocol_Register_12
+
+#define Protocol_Register_13		86
+#define Data1Delay			Protocol_Register_13
+
+#define Protocol_Register_8		88	/* 32 bit */
+#define StartDelay			Protocol_Register_8
+
+enum pci_6534_firmware_registers {	/* 16 bit */
+	Firmware_Control_Register = 0x100,
+	Firmware_Status_Register = 0x104,
+	Firmware_Data_Register = 0x108,
+	Firmware_Mask_Register = 0x10c,
+	Firmware_Debug_Register = 0x110,
+};
+/* main fpga registers (32 bit)*/
+enum pci_6534_fpga_registers {
+	FPGA_Control1_Register = 0x200,
+	FPGA_Control2_Register = 0x204,
+	FPGA_Irq_Mask_Register = 0x208,
+	FPGA_Status_Register = 0x20c,
+	FPGA_Signature_Register = 0x210,
+	FPGA_SCALS_Counter_Register = 0x280,	/*write-clear */
+	FPGA_SCAMS_Counter_Register = 0x284,	/*write-clear */
+	FPGA_SCBLS_Counter_Register = 0x288,	/*write-clear */
+	FPGA_SCBMS_Counter_Register = 0x28c,	/*write-clear */
+	FPGA_Temp_Control_Register = 0x2a0,
+	FPGA_DAR_Register = 0x2a8,
+	FPGA_ELC_Read_Register = 0x2b8,
+	FPGA_ELC_Write_Register = 0x2bc,
+};
+enum FPGA_Control_Bits {
+	FPGA_Enable_Bit = 0x8000,
+};
+
+#define TIMER_BASE 50		/* nanoseconds */
+
+#ifdef USE_DMA
+#define IntEn (CountExpired|Waited|PrimaryTC|SecondaryTC)
+#else
+#define IntEn (TransferReady|CountExpired|Waited|PrimaryTC|SecondaryTC)
+#endif
+
+static int nidio_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int nidio_detach(struct comedi_device * dev);
+static int ni_pcidio_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static struct comedi_driver driver_pcidio = {
+      driver_name:"ni_pcidio",
+      module:THIS_MODULE,
+      attach:nidio_attach,
+      detach:nidio_detach,
+};
+
+struct nidio_board {
+
+	int dev_id;
+	const char *name;
+	int n_8255;
+	unsigned int is_diodaq:1;
+	unsigned int uses_firmware:1;
+};
+
+static const struct nidio_board nidio_boards[] = {
+	{
+	      dev_id:	0x1150,
+	      name:	"pci-dio-32hs",
+	      n_8255:	0,
+	      is_diodaq:1,
+		},
+	{
+	      dev_id:	0x1320,
+	      name:	"pxi-6533",
+	      n_8255:	0,
+	      is_diodaq:1,
+		},
+	{
+	      dev_id:	0x12b0,
+	      name:	"pci-6534",
+	      n_8255:	0,
+	      is_diodaq:1,
+	      uses_firmware:1,
+		},
+	{
+	      dev_id:	0x0160,
+	      name:	"pci-dio-96",
+	      n_8255:	4,
+	      is_diodaq:0,
+		},
+	{
+	      dev_id:	0x1630,
+	      name:	"pci-dio-96b",
+	      n_8255:	4,
+	      is_diodaq:0,
+		},
+	{
+	      dev_id:	0x13c0,
+	      name:	"pxi-6508",
+	      n_8255:	4,
+	      is_diodaq:0,
+		},
+	{
+	      dev_id:	0x0400,
+	      name:	"pci-6503",
+	      n_8255:	1,
+	      is_diodaq:0,
+		},
+	{
+	      dev_id:	0x1250,
+	      name:	"pci-6503b",
+	      n_8255:	1,
+	      is_diodaq:0,
+		},
+	{
+	      dev_id:	0x17d0,
+	      name:	"pci-6503x",
+	      n_8255:	1,
+	      is_diodaq:0,
+		},
+	{
+	      dev_id:	0x1800,
+	      name:	"pxi-6503",
+	      n_8255:	1,
+	      is_diodaq:0,
+		},
+};
+
+#define n_nidio_boards (sizeof(nidio_boards)/sizeof(nidio_boards[0]))
+#define this_board ((const struct nidio_board *)dev->board_ptr)
+
+static DEFINE_PCI_DEVICE_TABLE(ni_pcidio_pci_table) = {
+	{PCI_VENDOR_ID_NATINST, 0x1150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x1320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x12b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x0160, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x1630, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x13c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x0400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x1250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x17d0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x1800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, ni_pcidio_pci_table);
+
+struct nidio96_private {
+	struct mite_struct *mite;
+	int boardtype;
+	int dio;
+	unsigned short OpModeBits;
+	struct mite_channel *di_mite_chan;
+	struct mite_dma_descriptor_ring *di_mite_ring;
+	spinlock_t mite_channel_lock;
+};
+#define devpriv ((struct nidio96_private *)dev->private)
+
+static int ni_pcidio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd);
+static int ni_pcidio_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int ni_pcidio_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int trignum);
+static int nidio_find_device(struct comedi_device * dev, int bus, int slot);
+static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode);
+static int setup_mite_dma(struct comedi_device * dev, struct comedi_subdevice * s);
+
+#ifdef DEBUG_FLAGS
+static void ni_pcidio_print_flags(unsigned int flags);
+static void ni_pcidio_print_status(unsigned int status);
+#else
+#define ni_pcidio_print_flags(x)
+#define ni_pcidio_print_status(x)
+#endif
+
+static int ni_pcidio_request_di_mite_channel(struct comedi_device * dev)
+{
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+	BUG_ON(devpriv->di_mite_chan);
+	devpriv->di_mite_chan =
+		mite_request_channel_in_range(devpriv->mite,
+		devpriv->di_mite_ring, 1, 2);
+	if (devpriv->di_mite_chan == NULL) {
+		comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock,
+			flags);
+		comedi_error(dev, "failed to reserve mite dma channel.");
+		return -EBUSY;
+	}
+	writeb(primary_DMAChannel_bits(devpriv->di_mite_chan->channel) |
+		secondary_DMAChannel_bits(devpriv->di_mite_chan->channel),
+		devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
+	mmiowb();
+	comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+	return 0;
+}
+
+static void ni_pcidio_release_di_mite_channel(struct comedi_device * dev)
+{
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+	if (devpriv->di_mite_chan) {
+		mite_dma_disarm(devpriv->di_mite_chan);
+		mite_dma_reset(devpriv->di_mite_chan);
+		mite_release_channel(devpriv->di_mite_chan);
+		devpriv->di_mite_chan = NULL;
+		writeb(primary_DMAChannel_bits(0) |
+			secondary_DMAChannel_bits(0),
+			devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
+		mmiowb();
+	}
+	comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+}
+
+static int nidio96_8255_cb(int dir, int port, int data, unsigned long iobase)
+{
+	if (dir) {
+		writeb(data, (void *)(iobase + port));
+		return 0;
+	} else {
+		return readb((void *)(iobase + port));
+	}
+}
+
+void ni_pcidio_event(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	if (s->async->
+		events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW))
+	{
+		ni_pcidio_cancel(dev, s);
+	}
+	comedi_event(dev, s);
+}
+
+static irqreturn_t nidio_interrupt(int irq, void *d PT_REGS_ARG)
+{
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s = dev->subdevices;
+	struct comedi_async *async = s->async;
+	struct mite_struct *mite = devpriv->mite;
+
+	//int i, j;
+	long int AuxData = 0;
+	short data1 = 0;
+	short data2 = 0;
+	int flags;
+	int status;
+	int work = 0;
+	unsigned int m_status = 0;
+	unsigned long irq_flags;
+
+	//interrupcions parasites
+	if (dev->attached == 0) {
+		// assume it's from another card
+		return IRQ_NONE;
+	}
+
+	status = readb(devpriv->mite->daq_io_addr +
+		Interrupt_And_Window_Status);
+	flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
+
+	DPRINTK("ni_pcidio_interrupt: status=0x%02x,flags=0x%02x\n",
+		status, flags);
+	ni_pcidio_print_flags(flags);
+	ni_pcidio_print_status(status);
+
+	//printk("buf[0]=%08x\n",*(unsigned int *)async->prealloc_buf);
+	//printk("buf[4096]=%08x\n",*(unsigned int *)(async->prealloc_buf+4096));
+
+	comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, irq_flags);
+	if (devpriv->di_mite_chan)
+		m_status = mite_get_status(devpriv->di_mite_chan);
+#ifdef MITE_DEBUG
+	mite_print_chsr(m_status);
+#endif
+	//printk("mite_bytes_transferred: %d\n",mite_bytes_transferred(mite,DI_DMA_CHAN));
+	//mite_dump_regs(mite);
+	if (m_status & CHSR_INT) {
+		if (m_status & CHSR_LINKC) {
+			writel(CHOR_CLRLC,
+				mite->mite_io_addr +
+				MITE_CHOR(devpriv->di_mite_chan->channel));
+			mite_sync_input_dma(devpriv->di_mite_chan, s->async);
+			/* XXX need to byteswap */
+		}
+		if (m_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_DRDY |
+				CHSR_DRQ1 | CHSR_MRDY)) {
+			DPRINTK("unknown mite interrupt, disabling IRQ\n");
+			async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+			disable_irq(dev->irq);
+		}
+	}
+	comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, irq_flags);
+
+	while (status & DataLeft) {
+		work++;
+		if (work > 20) {
+			DPRINTK("too much work in interrupt\n");
+			writeb(0x00,
+				devpriv->mite->daq_io_addr +
+				Master_DMA_And_Interrupt_Control);
+			break;
+		}
+
+		flags &= IntEn;
+
+		if (flags & TransferReady) {
+			//DPRINTK("TransferReady\n");
+			while (flags & TransferReady) {
+				work++;
+				if (work > 100) {
+					DPRINTK("too much work in interrupt\n");
+					writeb(0x00,
+						devpriv->mite->daq_io_addr +
+						Master_DMA_And_Interrupt_Control);
+					goto out;
+				}
+				AuxData =
+					readl(devpriv->mite->daq_io_addr +
+					Group_1_FIFO);
+				data1 = AuxData & 0xffff;
+				data2 = (AuxData & 0xffff0000) >> 16;
+				comedi_buf_put(async, data1);
+				comedi_buf_put(async, data2);
+				//DPRINTK("read:%d, %d\n",data1,data2);
+				flags = readb(devpriv->mite->daq_io_addr +
+					Group_1_Flags);
+			}
+			//DPRINTK("buf_int_count: %d\n",async->buf_int_count);
+			//DPRINTK("1) IntEn=%d,flags=%d,status=%d\n",IntEn,flags,status);
+			//ni_pcidio_print_flags(flags);
+			//ni_pcidio_print_status(status);
+			async->events |= COMEDI_CB_BLOCK;
+		}
+
+		if (flags & CountExpired) {
+			DPRINTK("CountExpired\n");
+			writeb(ClearExpired,
+				devpriv->mite->daq_io_addr +
+				Group_1_Second_Clear);
+			async->events |= COMEDI_CB_EOA;
+
+			writeb(0x00, devpriv->mite->daq_io_addr + OpMode);
+			break;
+		} else if (flags & Waited) {
+			DPRINTK("Waited\n");
+			writeb(ClearWaited,
+				devpriv->mite->daq_io_addr +
+				Group_1_First_Clear);
+			async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+			break;
+		} else if (flags & PrimaryTC) {
+			DPRINTK("PrimaryTC\n");
+			writeb(ClearPrimaryTC,
+				devpriv->mite->daq_io_addr +
+				Group_1_First_Clear);
+			async->events |= COMEDI_CB_EOA;
+		} else if (flags & SecondaryTC) {
+			DPRINTK("SecondaryTC\n");
+			writeb(ClearSecondaryTC,
+				devpriv->mite->daq_io_addr +
+				Group_1_First_Clear);
+			async->events |= COMEDI_CB_EOA;
+		}
+#if 0
+		else {
+			printk("ni_pcidio: unknown interrupt\n");
+			async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+			writeb(0x00,
+				devpriv->mite->daq_io_addr +
+				Master_DMA_And_Interrupt_Control);
+		}
+#endif
+		flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
+		status = readb(devpriv->mite->daq_io_addr +
+			Interrupt_And_Window_Status);
+		//DPRINTK("loop end: IntEn=0x%02x,flags=0x%02x,status=0x%02x\n",
+		//      IntEn,flags,status);
+		//ni_pcidio_print_flags(flags);
+		//ni_pcidio_print_status(status);
+	}
+
+      out:
+	ni_pcidio_event(dev, s);
+#if 0
+	if (!tag) {
+		writeb(0x03,
+			devpriv->mite->daq_io_addr +
+			Master_DMA_And_Interrupt_Control);
+	}
+#endif
+	return IRQ_HANDLED;
+}
+
+#ifdef DEBUG_FLAGS
+static const char *const flags_strings[] = {
+	"TransferReady", "CountExpired", "2", "3",
+	"4", "Waited", "PrimaryTC", "SecondaryTC",
+};
+static void ni_pcidio_print_flags(unsigned int flags)
+{
+	int i;
+
+	printk("group_1_flags:");
+	for (i = 7; i >= 0; i--) {
+		if (flags & (1 << i)) {
+			printk(" %s", flags_strings[i]);
+		}
+	}
+	printk("\n");
+}
+static char *status_strings[] = {
+	"DataLeft1", "Reserved1", "Req1", "StopTrig1",
+	"DataLeft2", "Reserved2", "Req2", "StopTrig2",
+};
+static void ni_pcidio_print_status(unsigned int flags)
+{
+	int i;
+
+	printk("group_status:");
+	for (i = 7; i >= 0; i--) {
+		if (flags & (1 << i)) {
+			printk(" %s", status_strings[i]);
+		}
+	}
+	printk("\n");
+}
+#endif
+
+#ifdef unused
+static void debug_int(struct comedi_device * dev)
+{
+	int a, b;
+	static int n_int = 0;
+	struct timeval tv;
+
+	do_gettimeofday(&tv);
+	a = readb(devpriv->mite->daq_io_addr + Group_Status);
+	b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
+
+	if (n_int < 10) {
+		DPRINTK("status 0x%02x flags 0x%02x time %06d\n", a, b,
+			(int)tv.tv_usec);
+	}
+
+	while (b & 1) {
+		writew(0xff, devpriv->mite->daq_io_addr + Group_1_FIFO);
+		b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
+	}
+
+	b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
+
+	if (n_int < 10) {
+		DPRINTK("new status 0x%02x\n", b);
+		n_int++;
+	}
+}
+#endif
+
+static int ni_pcidio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 1)
+		return -EINVAL;
+	switch (data[0]) {
+	case INSN_CONFIG_DIO_OUTPUT:
+		s->io_bits |= 1 << CR_CHAN(insn->chanspec);
+		break;
+	case INSN_CONFIG_DIO_INPUT:
+		s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
+		break;
+	case INSN_CONFIG_DIO_QUERY:
+		data[1] =
+			(s->io_bits & (1 << CR_CHAN(insn->
+					chanspec))) ? COMEDI_OUTPUT :
+			COMEDI_INPUT;
+		return insn->n;
+		break;
+	default:
+		return -EINVAL;
+	}
+	writel(s->io_bits, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
+
+	return 1;
+}
+
+static int ni_pcidio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= (data[0] & data[1]);
+		writel(s->state, devpriv->mite->daq_io_addr + Port_IO(0));
+	}
+	data[1] = readl(devpriv->mite->daq_io_addr + Port_IO(0));
+
+	return 2;
+}
+
+static int ni_pcidio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp;
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW | TRIG_INT;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_NOW;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	/* note that mutual compatiblity is not an issue here */
+	if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_INT)
+		err++;
+	if (cmd->scan_begin_src != TRIG_TIMER &&
+		cmd->scan_begin_src != TRIG_EXT)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->start_arg != 0) {
+		/* same for both TRIG_INT and TRIG_NOW */
+		cmd->start_arg = 0;
+		err++;
+	}
+#define MAX_SPEED	(TIMER_BASE)	/* in nanoseconds */
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		if (cmd->scan_begin_arg < MAX_SPEED) {
+			cmd->scan_begin_arg = MAX_SPEED;
+			err++;
+		}
+		/* no minumum speed */
+	} else {
+		/* TRIG_EXT */
+		/* should be level/edge, hi/lo specification here */
+		if (cmd->scan_begin_arg != 0) {
+			cmd->scan_begin_arg = 0;
+			err++;
+		}
+	}
+	if (cmd->convert_arg != 0) {
+		cmd->convert_arg = 0;
+		err++;
+	}
+
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+	if (cmd->stop_src == TRIG_COUNT) {
+		/* no limit */
+	} else {
+		/* TRIG_NONE */
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		tmp = cmd->scan_begin_arg;
+		ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+		if (tmp != cmd->scan_begin_arg)
+			err++;
+	}
+
+	if (err)
+		return 4;
+
+	return 0;
+}
+
+static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode)
+{
+	int divider, base;
+
+	base = TIMER_BASE;
+
+	switch (round_mode) {
+	case TRIG_ROUND_NEAREST:
+	default:
+		divider = (*nanosec + base / 2) / base;
+		break;
+	case TRIG_ROUND_DOWN:
+		divider = (*nanosec) / base;
+		break;
+	case TRIG_ROUND_UP:
+		divider = (*nanosec + base - 1) / base;
+		break;
+	}
+
+	*nanosec = base * divider;
+	return divider;
+}
+
+static int ni_pcidio_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_cmd *cmd = &s->async->cmd;
+
+	/* XXX configure ports for input */
+	writel(0x0000, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
+
+	if (1) {
+		/* enable fifos A B C D */
+		writeb(0x0f, devpriv->mite->daq_io_addr + Data_Path);
+
+		/* set transfer width a 32 bits */
+		writeb(TransferWidth(0) | TransferLength(0),
+			devpriv->mite->daq_io_addr + Transfer_Size_Control);
+	} else {
+		writeb(0x03, devpriv->mite->daq_io_addr + Data_Path);
+		writeb(TransferWidth(3) | TransferLength(0),
+			devpriv->mite->daq_io_addr + Transfer_Size_Control);
+	}
+
+	/* protocol configuration */
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		/* page 4-5, "input with internal REQs" */
+		writeb(0, devpriv->mite->daq_io_addr + OpMode);
+		writeb(0x00, devpriv->mite->daq_io_addr + ClockReg);
+		writeb(1, devpriv->mite->daq_io_addr + Sequence);
+		writeb(0x04, devpriv->mite->daq_io_addr + ReqReg);
+		writeb(4, devpriv->mite->daq_io_addr + BlockMode);
+		writeb(3, devpriv->mite->daq_io_addr + LinePolarities);
+		writeb(0xc0, devpriv->mite->daq_io_addr + AckSer);
+		writel(ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
+				TRIG_ROUND_NEAREST),
+			devpriv->mite->daq_io_addr + StartDelay);
+		writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
+		writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay);
+		writeb(1, devpriv->mite->daq_io_addr + AckDelay);
+		writeb(0x0b, devpriv->mite->daq_io_addr + AckNotDelay);
+		writeb(0x01, devpriv->mite->daq_io_addr + Data1Delay);
+		/* manual, page 4-5: ClockSpeed comment is incorrectly listed
+		 * on DAQOptions */
+		writew(0, devpriv->mite->daq_io_addr + ClockSpeed);
+		writeb(0, devpriv->mite->daq_io_addr + DAQOptions);
+	} else {
+		/* TRIG_EXT */
+		/* page 4-5, "input with external REQs" */
+		writeb(0, devpriv->mite->daq_io_addr + OpMode);
+		writeb(0x00, devpriv->mite->daq_io_addr + ClockReg);
+		writeb(0, devpriv->mite->daq_io_addr + Sequence);
+		writeb(0x00, devpriv->mite->daq_io_addr + ReqReg);
+		writeb(4, devpriv->mite->daq_io_addr + BlockMode);
+		writeb(0, devpriv->mite->daq_io_addr + LinePolarities);
+		writeb(0x00, devpriv->mite->daq_io_addr + AckSer);
+		writel(1, devpriv->mite->daq_io_addr + StartDelay);
+		writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
+		writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay);
+		writeb(1, devpriv->mite->daq_io_addr + AckDelay);
+		writeb(0x0C, devpriv->mite->daq_io_addr + AckNotDelay);
+		writeb(0x10, devpriv->mite->daq_io_addr + Data1Delay);
+		writew(0, devpriv->mite->daq_io_addr + ClockSpeed);
+		writeb(0x60, devpriv->mite->daq_io_addr + DAQOptions);
+	}
+
+	if (cmd->stop_src == TRIG_COUNT) {
+		writel(cmd->stop_arg,
+			devpriv->mite->daq_io_addr + Transfer_Count);
+	} else {
+		/* XXX */
+	}
+
+#ifdef USE_DMA
+	writeb(ClearPrimaryTC | ClearSecondaryTC,
+		devpriv->mite->daq_io_addr + Group_1_First_Clear);
+
+	{
+		int retval = setup_mite_dma(dev, s);
+		if (retval)
+			return retval;
+	}
+#else
+	writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
+#endif
+	writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group2);
+
+	/* clear and enable interrupts */
+	writeb(0xff, devpriv->mite->daq_io_addr + Group_1_First_Clear);
+	//writeb(ClearExpired,devpriv->mite->daq_io_addr+Group_1_Second_Clear);
+
+	writeb(IntEn, devpriv->mite->daq_io_addr + Interrupt_Control);
+	writeb(0x03,
+		devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);
+
+	if (cmd->stop_src == TRIG_NONE) {
+		devpriv->OpModeBits = DataLatching(0) | RunMode(7);
+	} else {		// TRIG_TIMER
+		devpriv->OpModeBits = Numbered | RunMode(7);
+	}
+	if (cmd->start_src == TRIG_NOW) {
+		/* start */
+		writeb(devpriv->OpModeBits,
+			devpriv->mite->daq_io_addr + OpMode);
+		s->async->inttrig = NULL;
+	} else {
+		/* TRIG_INT */
+		s->async->inttrig = ni_pcidio_inttrig;
+	}
+
+	DPRINTK("ni_pcidio: command started\n");
+	return 0;
+}
+
+static int setup_mite_dma(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	int retval;
+
+	retval = ni_pcidio_request_di_mite_channel(dev);
+	if (retval)
+		return retval;
+
+	devpriv->di_mite_chan->dir = COMEDI_INPUT;
+
+	mite_prep_dma(devpriv->di_mite_chan, 32, 32);
+
+	mite_dma_arm(devpriv->di_mite_chan);
+	return 0;
+}
+
+static int ni_pcidio_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int trignum)
+{
+	if (trignum != 0)
+		return -EINVAL;
+
+	writeb(devpriv->OpModeBits, devpriv->mite->daq_io_addr + OpMode);
+	s->async->inttrig = NULL;
+
+	return 1;
+}
+
+static int ni_pcidio_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	writeb(0x00,
+		devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);
+	ni_pcidio_release_di_mite_channel(dev);
+
+	return 0;
+}
+
+static int ni_pcidio_change(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned long new_size)
+{
+	int ret;
+
+	ret = mite_buf_change(devpriv->di_mite_ring, s->async);
+	if (ret < 0)
+		return ret;
+
+	memset(s->async->prealloc_buf, 0xaa, s->async->prealloc_bufsz);
+
+	return 0;
+}
+
+static int pci_6534_load_fpga(struct comedi_device * dev, int fpga_index, u8 * data,
+	int data_len)
+{
+	static const int timeout = 1000;
+	int i, j;
+	writew(0x80 | fpga_index,
+		devpriv->mite->daq_io_addr + Firmware_Control_Register);
+	writew(0xc0 | fpga_index,
+		devpriv->mite->daq_io_addr + Firmware_Control_Register);
+	for (i = 0;
+		(readw(devpriv->mite->daq_io_addr +
+				Firmware_Status_Register) & 0x2) == 0
+		&& i < timeout; ++i) {
+		udelay(1);
+	}
+	if (i == timeout) {
+		printk("ni_pcidio: failed to load fpga %i, waiting for status 0x2\n", fpga_index);
+		return -EIO;
+	}
+	writew(0x80 | fpga_index,
+		devpriv->mite->daq_io_addr + Firmware_Control_Register);
+	for (i = 0;
+		readw(devpriv->mite->daq_io_addr + Firmware_Status_Register) !=
+		0x3 && i < timeout; ++i) {
+		udelay(1);
+	}
+	if (i == timeout) {
+		printk("ni_pcidio: failed to load fpga %i, waiting for status 0x3\n", fpga_index);
+		return -EIO;
+	}
+	for (j = 0; j + 1 < data_len;) {
+		unsigned int value = data[j++];
+		value |= data[j++] << 8;
+		writew(value,
+			devpriv->mite->daq_io_addr + Firmware_Data_Register);
+		for (i = 0;
+			(readw(devpriv->mite->daq_io_addr +
+					Firmware_Status_Register) & 0x2) == 0
+			&& i < timeout; ++i) {
+			udelay(1);
+		}
+		if (i == timeout) {
+			printk("ni_pcidio: failed to load word into fpga %i\n",
+				fpga_index);
+			return -EIO;
+		}
+		if (need_resched())
+			schedule();
+	}
+	writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register);
+	return 0;
+}
+
+static int pci_6534_reset_fpga(struct comedi_device * dev, int fpga_index)
+{
+	return pci_6534_load_fpga(dev, fpga_index, NULL, 0);
+}
+
+static int pci_6534_reset_fpgas(struct comedi_device * dev)
+{
+	int ret;
+	int i;
+	writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register);
+	for (i = 0; i < 3; ++i) {
+		ret = pci_6534_reset_fpga(dev, i);
+		if (ret < 0)
+			break;
+	}
+	writew(0x0, devpriv->mite->daq_io_addr + Firmware_Mask_Register);
+	return ret;
+}
+
+static void pci_6534_init_main_fpga(struct comedi_device * dev)
+{
+	writel(0, devpriv->mite->daq_io_addr + FPGA_Control1_Register);
+	writel(0, devpriv->mite->daq_io_addr + FPGA_Control2_Register);
+	writel(0, devpriv->mite->daq_io_addr + FPGA_SCALS_Counter_Register);
+	writel(0, devpriv->mite->daq_io_addr + FPGA_SCAMS_Counter_Register);
+	writel(0, devpriv->mite->daq_io_addr + FPGA_SCBLS_Counter_Register);
+	writel(0, devpriv->mite->daq_io_addr + FPGA_SCBMS_Counter_Register);
+}
+
+static int pci_6534_upload_firmware(struct comedi_device * dev, int options[])
+{
+	int ret;
+	void *main_fpga_data, *scarab_a_data, *scarab_b_data;
+	int main_fpga_data_len, scarab_a_data_len, scarab_b_data_len;
+
+	if (options[COMEDI_DEVCONF_AUX_DATA_LENGTH] == 0)
+		return 0;
+	ret = pci_6534_reset_fpgas(dev);
+	if (ret < 0)
+		return ret;
+	main_fpga_data = comedi_aux_data(options, 0);
+	main_fpga_data_len = options[COMEDI_DEVCONF_AUX_DATA0_LENGTH];
+	ret = pci_6534_load_fpga(dev, 2, main_fpga_data, main_fpga_data_len);
+	if (ret < 0)
+		return ret;
+	pci_6534_init_main_fpga(dev);
+	scarab_a_data = comedi_aux_data(options, 1);
+	scarab_a_data_len = options[COMEDI_DEVCONF_AUX_DATA1_LENGTH];
+	ret = pci_6534_load_fpga(dev, 0, scarab_a_data, scarab_a_data_len);
+	if (ret < 0)
+		return ret;
+	scarab_b_data = comedi_aux_data(options, 2);
+	scarab_b_data_len = options[COMEDI_DEVCONF_AUX_DATA2_LENGTH];
+	ret = pci_6534_load_fpga(dev, 1, scarab_b_data, scarab_b_data_len);
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+static int nidio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	int i;
+	int ret;
+	int n_subdevices;
+	unsigned int irq;
+
+	printk("comedi%d: nidio:", dev->minor);
+
+	if ((ret = alloc_private(dev, sizeof(struct nidio96_private))) < 0)
+		return ret;
+	spin_lock_init(&devpriv->mite_channel_lock);
+
+	ret = nidio_find_device(dev, it->options[0], it->options[1]);
+	if (ret < 0)
+		return ret;
+
+	ret = mite_setup(devpriv->mite);
+	if (ret < 0) {
+		printk("error setting up mite\n");
+		return ret;
+	}
+	comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev);
+	devpriv->di_mite_ring = mite_alloc_ring(devpriv->mite);
+	if (devpriv->di_mite_ring == NULL)
+		return -ENOMEM;
+
+	dev->board_name = this_board->name;
+	irq = mite_irq(devpriv->mite);
+	printk(" %s", dev->board_name);
+	if (this_board->uses_firmware) {
+		ret = pci_6534_upload_firmware(dev, it->options);
+		if (ret < 0)
+			return ret;
+	}
+	if (!this_board->is_diodaq) {
+		n_subdevices = this_board->n_8255;
+	} else {
+		n_subdevices = 1;
+	}
+	if ((ret = alloc_subdevices(dev, n_subdevices)) < 0)
+		return ret;
+
+	if (!this_board->is_diodaq) {
+		for (i = 0; i < this_board->n_8255; i++) {
+			subdev_8255_init(dev, dev->subdevices + i,
+				nidio96_8255_cb,
+				(unsigned long)(devpriv->mite->daq_io_addr +
+					NIDIO_8255_BASE(i)));
+		}
+	} else {
+
+		printk(" rev=%d",
+			readb(devpriv->mite->daq_io_addr + Chip_Version));
+
+		s = dev->subdevices + 0;
+
+		dev->read_subdev = s;
+		s->type = COMEDI_SUBD_DIO;
+		s->subdev_flags =
+			SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_PACKED |
+			SDF_CMD_READ;
+		s->n_chan = 32;
+		s->range_table = &range_digital;
+		s->maxdata = 1;
+		s->insn_config = &ni_pcidio_insn_config;
+		s->insn_bits = &ni_pcidio_insn_bits;
+		s->do_cmd = &ni_pcidio_cmd;
+		s->do_cmdtest = &ni_pcidio_cmdtest;
+		s->cancel = &ni_pcidio_cancel;
+		s->len_chanlist = 32;	/* XXX */
+		s->buf_change = &ni_pcidio_change;
+		s->async_dma_dir = DMA_BIDIRECTIONAL;
+
+		writel(0, devpriv->mite->daq_io_addr + Port_IO(0));
+		writel(0, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
+		writel(0, devpriv->mite->daq_io_addr + Port_Pin_Mask(0));
+
+		/* disable interrupts on board */
+		writeb(0x00,
+			devpriv->mite->daq_io_addr +
+			Master_DMA_And_Interrupt_Control);
+
+		ret = comedi_request_irq(irq, nidio_interrupt, IRQF_SHARED,
+			"ni_pcidio", dev);
+		if (ret < 0) {
+			printk(" irq not available");
+		}
+		dev->irq = irq;
+	}
+
+	printk("\n");
+
+	return 0;
+}
+
+static int nidio_detach(struct comedi_device * dev)
+{
+	int i;
+
+	if (this_board && !this_board->is_diodaq) {
+		for (i = 0; i < this_board->n_8255; i++) {
+			subdev_8255_cleanup(dev, dev->subdevices + i);
+		}
+	}
+
+	if (dev->irq)
+		comedi_free_irq(dev->irq, dev);
+
+	if (devpriv) {
+		if (devpriv->di_mite_ring) {
+			mite_free_ring(devpriv->di_mite_ring);
+			devpriv->di_mite_ring = NULL;
+		}
+		if (devpriv->mite)
+			mite_unsetup(devpriv->mite);
+	}
+	return 0;
+}
+
+static int nidio_find_device(struct comedi_device * dev, int bus, int slot)
+{
+	struct mite_struct *mite;
+	int i;
+
+	for (mite = mite_devices; mite; mite = mite->next) {
+		if (mite->used)
+			continue;
+		if (bus || slot) {
+			if (bus != mite->pcidev->bus->number ||
+				slot != PCI_SLOT(mite->pcidev->devfn))
+				continue;
+		}
+		for (i = 0; i < n_nidio_boards; i++) {
+			if (mite_device_id(mite) == nidio_boards[i].dev_id) {
+				dev->board_ptr = nidio_boards + i;
+				devpriv->mite = mite;
+
+				return 0;
+			}
+		}
+	}
+	printk("no device found\n");
+	mite_list_devices();
+	return -EIO;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_pcidio, ni_pcidio_pci_table);
diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c
new file mode 100644
index 0000000..3a2aba7
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_pcimio.c
@@ -0,0 +1,1788 @@
+/*
+    comedi/drivers/ni_pcimio.c
+    Hardware driver for NI PCI-MIO E series cards
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 1997-8 David A. Schleef <ds@schleef.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.
+
+    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.
+*/
+/*
+Driver: ni_pcimio
+Description: National Instruments PCI-MIO-E series and M series (all boards)
+Author: ds, John Hallen, Frank Mori Hess, Rolf Mueller, Herbert Peremans,
+  Herman Bruyninckx, Terry Barnaby
+Status: works
+Devices: [National Instruments] PCI-MIO-16XE-50 (ni_pcimio),
+  PCI-MIO-16XE-10, PXI-6030E, PCI-MIO-16E-1, PCI-MIO-16E-4, PCI-6014, PCI-6040E,
+  PXI-6040E, PCI-6030E, PCI-6031E, PCI-6032E, PCI-6033E, PCI-6071E, PCI-6023E,
+  PCI-6024E, PCI-6025E, PXI-6025E, PCI-6034E, PCI-6035E, PCI-6052E,
+  PCI-6110, PCI-6111, PCI-6220, PCI-6221, PCI-6224, PXI-6224, PCI-6225,
+  PCI-6229, PCI-6250, PCI-6251, PCIe-6251, PCI-6254, PCI-6259, PCIe-6259,
+  PCI-6280, PCI-6281, PXI-6281, PCI-6284, PCI-6289,
+  PCI-6711, PXI-6711, PCI-6713, PXI-6713,
+  PXI-6071E, PCI-6070E, PXI-6070E,
+  PXI-6052E, PCI-6036E, PCI-6731, PCI-6733, PXI-6733,
+  PCI-6143, PXI-6143
+Updated: Wed, 03 Dec 2008 10:51:47 +0000
+
+These boards are almost identical to the AT-MIO E series, except that
+they use the PCI bus instead of ISA (i.e., AT).  See the notes for
+the ni_atmio.o driver for additional information about these boards.
+
+Autocalibration is supported on many of the devices, using the
+comedi_calibrate (or comedi_soft_calibrate for m-series) utility.
+M-Series boards do analog input and analog output calibration entirely
+in software. The software calibration corrects
+the analog input for offset, gain and
+nonlinearity.  The analog outputs are corrected for offset and gain.
+See the comedilib documentation on comedi_get_softcal_converter() for
+more information.
+
+By default, the driver uses DMA to transfer analog input data to
+memory.  When DMA is enabled, not all triggering features are
+supported.
+
+Digital I/O may not work on 673x.
+
+Note that the PCI-6143 is a simultaineous sampling device with 8 convertors.
+With this board all of the convertors perform one simultaineous sample during
+a scan interval. The period for a scan is used for the convert time in a
+Comedi cmd. The convert trigger source is normally set to TRIG_NOW by default.
+
+The RTSI trigger bus is supported on these cards on
+subdevice 10. See the comedilib documentation for details.
+
+Information (number of channels, bits, etc.) for some devices may be
+incorrect.  Please check this and submit a bug if there are problems
+for your device.
+
+SCXI is probably broken for m-series boards.
+
+Bugs:
+ - When DMA is enabled, COMEDI_EV_CONVERT does
+   not work correctly.
+
+*/
+/*
+	The PCI-MIO E series driver was originally written by
+	Tomasz Motylewski <...>, and ported to comedi by ds.
+
+	References:
+
+	   341079b.pdf  PCI E Series Register-Level Programmer Manual
+	   340934b.pdf  DAQ-STC reference manual
+
+	   322080b.pdf  6711/6713/6715 User Manual
+
+	   320945c.pdf  PCI E Series User Manual
+	   322138a.pdf  PCI-6052E and DAQPad-6052E User Manual
+
+	ISSUES:
+
+	need to deal with external reference for DAC, and other DAC
+	properties in board properties
+
+	deal with at-mio-16de-10 revision D to N changes, etc.
+
+	need to add other CALDAC type
+
+	need to slow down DAC loading.  I don't trust NI's claim that
+	two writes to the PCI bus slows IO enough.  I would prefer to
+	use comedi_udelay().  Timing specs: (clock)
+		AD8522		30ns
+		DAC8043		120ns
+		DAC8800		60ns
+		MB88341		?
+
+*/
+
+#include "../comedidev.h"
+
+#include <asm/byteorder.h>
+#include <linux/delay.h>
+
+#include "ni_stc.h"
+#include "mite.h"
+
+//#define PCI_DEBUG
+
+#define PCIDMA
+
+#define PCIMIO 1
+#undef ATMIO
+
+#define MAX_N_CALDACS (16+16+2)
+
+#define DRV_NAME "ni_pcimio"
+
+/* The following two tables must be in the same order */
+static DEFINE_PCI_DEVICE_TABLE(ni_pci_table) = {
+	{PCI_VENDOR_ID_NATINST, 0x0162, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x1170, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x1180, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x1190, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x11b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x11c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x11d0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x1270, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x1330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x1340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x1350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x14e0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x14f0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x1580, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x15b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x1880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x1870, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x18b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x18c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x2410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x2420, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x2430, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x2890, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x28c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x2a60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x2a70, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x2a80, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x2ab0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x2b80, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x2b90, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x2c80, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x2ca0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x70aa, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x70ab, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x70ac, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x70af, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x70b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x70b4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x70b6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x70b7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x70b8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x70bc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x70bd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x70bf, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x70c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x70f2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x710d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x716c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x717f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x71bc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_NATINST, 0x717d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, ni_pci_table);
+
+/* These are not all the possible ao ranges for 628x boards.
+ They can do OFFSET +- REFERENCE where OFFSET can be
+ 0V, 5V, APFI<0,1>, or AO<0...3> and RANGE can
+ be 10V, 5V, 2V, 1V, APFI<0,1>, AO<0...3>.  That's
+ 63 different possibilities.  An AO channel
+ can not act as it's own OFFSET or REFERENCE.
+*/
+static const struct comedi_lrange range_ni_M_628x_ao = { 8, {
+			RANGE(-10, 10),
+			RANGE(-5, 5),
+			RANGE(-2, 2),
+			RANGE(-1, 1),
+			RANGE(-5, 15),
+			RANGE(0, 10),
+			RANGE(3, 7),
+			RANGE(4, 6),
+			RANGE_ext(-1, 1)
+	}
+};
+static const struct comedi_lrange range_ni_M_625x_ao = { 3, {
+			RANGE(-10, 10),
+			RANGE(-5, 5),
+			RANGE_ext(-1, 1)
+	}
+};
+static const struct comedi_lrange range_ni_M_622x_ao = { 1, {
+			RANGE(-10, 10),
+	}
+};
+
+static const ni_board ni_boards[] = {
+	{
+			.device_id = 0x0162,	// NI also says 0x1620.  typo?
+			.name = "pci-mio-16xe-50",
+			.n_adchan = 16,
+			.adbits = 16,
+			.ai_fifo_depth = 2048,
+			.alwaysdither = 1,
+			.gainlkup = ai_gain_8,
+			.ai_speed = 50000,
+			.n_aochan = 2,
+			.aobits = 12,
+			.ao_fifo_depth = 0,
+			.ao_range_table = &range_bipolar10,
+			.ao_unipolar = 0,
+			.ao_speed = 50000,
+			.num_p0_dio_channels = 8,
+			.caldac = {dac8800, dac8043},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x1170,
+			.name = "pci-mio-16xe-10",	// aka pci-6030E
+			.n_adchan = 16,
+			.adbits = 16,
+			.ai_fifo_depth = 512,
+			.alwaysdither = 1,
+			.gainlkup = ai_gain_14,
+			.ai_speed = 10000,
+			.n_aochan = 2,
+			.aobits = 16,
+			.ao_fifo_depth = 2048,
+			.ao_range_table = &range_ni_E_ao_ext,
+			.ao_unipolar = 1,
+			.ao_speed = 10000,
+			.num_p0_dio_channels = 8,
+			.caldac = {dac8800, dac8043, ad8522},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x28c0,
+			.name = "pci-6014",
+			.n_adchan = 16,
+			.adbits = 16,
+			.ai_fifo_depth = 512,
+			.alwaysdither = 1,
+			.gainlkup = ai_gain_4,
+			.ai_speed = 5000,
+			.n_aochan = 2,
+			.aobits = 16,
+			.ao_fifo_depth = 0,
+			.ao_range_table = &range_bipolar10,
+			.ao_unipolar = 0,
+			.ao_speed = 100000,
+			.num_p0_dio_channels = 8,
+			.caldac = {ad8804_debug},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x11d0,
+			.name = "pxi-6030e",
+			.n_adchan = 16,
+			.adbits = 16,
+			.ai_fifo_depth = 512,
+			.alwaysdither = 1,
+			.gainlkup = ai_gain_14,
+			.ai_speed = 10000,
+			.n_aochan = 2,
+			.aobits = 16,
+			.ao_fifo_depth = 2048,
+			.ao_range_table = &range_ni_E_ao_ext,
+			.ao_unipolar = 1,
+			.ao_speed = 10000,
+			.num_p0_dio_channels = 8,
+			.caldac = {dac8800, dac8043, ad8522},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x1180,
+			.name = "pci-mio-16e-1",	/* aka pci-6070e */
+			.n_adchan = 16,
+			.adbits = 12,
+			.ai_fifo_depth = 512,
+			.alwaysdither = 0,
+			.gainlkup = ai_gain_16,
+			.ai_speed = 800,
+			.n_aochan = 2,
+			.aobits = 12,
+			.ao_fifo_depth = 2048,
+			.ao_range_table = &range_ni_E_ao_ext,
+			.ao_unipolar = 1,
+			.ao_speed = 1000,
+			.num_p0_dio_channels = 8,
+			.caldac = {mb88341},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x1190,
+			.name = "pci-mio-16e-4",	/* aka pci-6040e */
+			.n_adchan = 16,
+			.adbits = 12,
+			.ai_fifo_depth = 512,
+			.alwaysdither = 0,
+			.gainlkup = ai_gain_16,
+			/* Note: there have been reported problems with full speed
+			 * on this board */
+			.ai_speed = 2000,
+			.n_aochan = 2,
+			.aobits = 12,
+			.ao_fifo_depth = 512,
+			.ao_range_table = &range_ni_E_ao_ext,
+			.ao_unipolar = 1,
+			.ao_speed = 1000,
+			.num_p0_dio_channels = 8,
+			.caldac = {ad8804_debug},	// doc says mb88341
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x11c0,
+			.name = "pxi-6040e",
+			.n_adchan = 16,
+			.adbits = 12,
+			.ai_fifo_depth = 512,
+			.alwaysdither = 0,
+			.gainlkup = ai_gain_16,
+			.ai_speed = 2000,
+			.n_aochan = 2,
+			.aobits = 12,
+			.ao_fifo_depth = 512,
+			.ao_range_table = &range_ni_E_ao_ext,
+			.ao_unipolar = 1,
+			.ao_speed = 1000,
+			.num_p0_dio_channels = 8,
+			.caldac = {mb88341},
+			.has_8255 = 0,
+		},
+
+	{
+			.device_id = 0x1330,
+			.name = "pci-6031e",
+			.n_adchan = 64,
+			.adbits = 16,
+			.ai_fifo_depth = 512,
+			.alwaysdither = 1,
+			.gainlkup = ai_gain_14,
+			.ai_speed = 10000,
+			.n_aochan = 2,
+			.aobits = 16,
+			.ao_fifo_depth = 2048,
+			.ao_range_table = &range_ni_E_ao_ext,
+			.ao_unipolar = 1,
+			.ao_speed = 10000,
+			.num_p0_dio_channels = 8,
+			.caldac = {dac8800, dac8043, ad8522},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x1270,
+			.name = "pci-6032e",
+			.n_adchan = 16,
+			.adbits = 16,
+			.ai_fifo_depth = 512,
+			.alwaysdither = 1,
+			.gainlkup = ai_gain_14,
+			.ai_speed = 10000,
+			.n_aochan = 0,
+			.aobits = 0,
+			.ao_fifo_depth = 0,
+			.ao_unipolar = 0,
+			.num_p0_dio_channels = 8,
+			.caldac = {dac8800, dac8043, ad8522},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x1340,
+			.name = "pci-6033e",
+			.n_adchan = 64,
+			.adbits = 16,
+			.ai_fifo_depth = 512,
+			.alwaysdither = 1,
+			.gainlkup = ai_gain_14,
+			.ai_speed = 10000,
+			.n_aochan = 0,
+			.aobits = 0,
+			.ao_fifo_depth = 0,
+			.ao_unipolar = 0,
+			.num_p0_dio_channels = 8,
+			.caldac = {dac8800, dac8043, ad8522},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x1350,
+			.name = "pci-6071e",
+			.n_adchan = 64,
+			.adbits = 12,
+			.ai_fifo_depth = 512,
+			.alwaysdither = 1,
+			.gainlkup = ai_gain_16,
+			.ai_speed = 800,
+			.n_aochan = 2,
+			.aobits = 12,
+			.ao_fifo_depth = 2048,
+			.ao_range_table = &range_ni_E_ao_ext,
+			.ao_unipolar = 1,
+			.ao_speed = 1000,
+			.num_p0_dio_channels = 8,
+			.caldac = {ad8804_debug},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x2a60,
+			.name = "pci-6023e",
+			.n_adchan = 16,
+			.adbits = 12,
+			.ai_fifo_depth = 512,
+			.alwaysdither = 0,
+			.gainlkup = ai_gain_4,
+			.ai_speed = 5000,
+			.n_aochan = 0,
+			.aobits = 0,
+			.ao_unipolar = 0,
+			.num_p0_dio_channels = 8,
+			.caldac = {ad8804_debug},	/* manual is wrong */
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x2a70,
+			.name = "pci-6024e",
+			.n_adchan = 16,
+			.adbits = 12,
+			.ai_fifo_depth = 512,
+			.alwaysdither = 0,
+			.gainlkup = ai_gain_4,
+			.ai_speed = 5000,
+			.n_aochan = 2,
+			.aobits = 12,
+			.ao_fifo_depth = 0,
+			.ao_range_table = &range_bipolar10,
+			.ao_unipolar = 0,
+			.ao_speed = 100000,
+			.num_p0_dio_channels = 8,
+			.caldac = {ad8804_debug},	/* manual is wrong */
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x2a80,
+			.name = "pci-6025e",
+			.n_adchan = 16,
+			.adbits = 12,
+			.ai_fifo_depth = 512,
+			.alwaysdither = 0,
+			.gainlkup = ai_gain_4,
+			.ai_speed = 5000,
+			.n_aochan = 2,
+			.aobits = 12,
+			.ao_fifo_depth = 0,
+			.ao_range_table = &range_bipolar10,
+			.ao_unipolar = 0,
+			.ao_speed = 100000,
+			.num_p0_dio_channels = 8,
+			.caldac = {ad8804_debug},	/* manual is wrong */
+			.has_8255 = 1,
+		},
+	{
+			.device_id = 0x2ab0,
+			.name = "pxi-6025e",
+			.n_adchan = 16,
+			.adbits = 12,
+			.ai_fifo_depth = 512,
+			.alwaysdither = 0,
+			.gainlkup = ai_gain_4,
+			.ai_speed = 5000,
+			.n_aochan = 2,
+			.aobits = 12,
+			.ao_fifo_depth = 0,
+			.ao_range_table = &range_ni_E_ao_ext,
+			.ao_unipolar = 1,
+			.ao_speed = 100000,
+			.num_p0_dio_channels = 8,
+			.caldac = {ad8804_debug},	/* manual is wrong */
+			.has_8255 = 1,
+		},
+
+	{
+			.device_id = 0x2ca0,
+			.name = "pci-6034e",
+			.n_adchan = 16,
+			.adbits = 16,
+			.ai_fifo_depth = 512,
+			.alwaysdither = 1,
+			.gainlkup = ai_gain_4,
+			.ai_speed = 5000,
+			.n_aochan = 0,
+			.aobits = 0,
+			.ao_fifo_depth = 0,
+			.ao_unipolar = 0,
+			.num_p0_dio_channels = 8,
+			.caldac = {ad8804_debug},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x2c80,
+			.name = "pci-6035e",
+			.n_adchan = 16,
+			.adbits = 16,
+			.ai_fifo_depth = 512,
+			.alwaysdither = 1,
+			.gainlkup = ai_gain_4,
+			.ai_speed = 5000,
+			.n_aochan = 2,
+			.aobits = 12,
+			.ao_fifo_depth = 0,
+			.ao_range_table = &range_bipolar10,
+			.ao_unipolar = 0,
+			.ao_speed = 100000,
+			.num_p0_dio_channels = 8,
+			.caldac = {ad8804_debug},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x18b0,
+			.name = "pci-6052e",
+			.n_adchan = 16,
+			.adbits = 16,
+			.ai_fifo_depth = 512,
+			.alwaysdither = 1,
+			.gainlkup = ai_gain_16,
+			.ai_speed = 3000,
+			.n_aochan = 2,
+			.aobits = 16,
+			.ao_unipolar = 1,
+			.ao_fifo_depth = 2048,
+			.ao_range_table = &range_ni_E_ao_ext,
+			.ao_speed = 3000,
+			.num_p0_dio_channels = 8,
+			.caldac = {ad8804_debug, ad8804_debug, ad8522},	/* manual is wrong */
+		},
+	{.device_id = 0x14e0,
+			.name = "pci-6110",
+			.n_adchan = 4,
+			.adbits = 12,
+			.ai_fifo_depth = 8192,
+			.alwaysdither = 0,
+			.gainlkup = ai_gain_611x,
+			.ai_speed = 200,
+			.n_aochan = 2,
+			.aobits = 16,
+			.reg_type = ni_reg_611x,
+			.ao_range_table = &range_bipolar10,
+			.ao_unipolar = 0,
+			.ao_fifo_depth = 2048,
+			.ao_speed = 250,
+			.num_p0_dio_channels = 8,
+			.caldac = {ad8804, ad8804},
+		},
+	{
+			.device_id = 0x14f0,
+			.name = "pci-6111",
+			.n_adchan = 2,
+			.adbits = 12,
+			.ai_fifo_depth = 8192,
+			.alwaysdither = 0,
+			.gainlkup = ai_gain_611x,
+			.ai_speed = 200,
+			.n_aochan = 2,
+			.aobits = 16,
+			.reg_type = ni_reg_611x,
+			.ao_range_table = &range_bipolar10,
+			.ao_unipolar = 0,
+			.ao_fifo_depth = 2048,
+			.ao_speed = 250,
+			.num_p0_dio_channels = 8,
+			.caldac = {ad8804, ad8804},
+		},
+#if 0
+	/* The 6115 boards probably need their own driver */
+	{
+			.device_id = 0x2ed0,
+			.name = "pci-6115",
+			.n_adchan = 4,
+			.adbits = 12,
+			.ai_fifo_depth = 8192,
+			.alwaysdither = 0,
+			.gainlkup = ai_gain_611x,
+			.ai_speed = 100,
+			.n_aochan = 2,
+			.aobits = 16,
+			.ao_671x = 1,
+			.ao_unipolar = 0,
+			.ao_fifo_depth = 2048,
+			.ao_speed = 250,
+			.num_p0_dio_channels = 8,
+			.reg_611x = 1,
+			.caldac = {ad8804_debug, ad8804_debug, ad8804_debug},	/* XXX */
+		},
+#endif
+#if 0
+	{
+			.device_id = 0x0000,
+			.name = "pxi-6115",
+			.n_adchan = 4,
+			.adbits = 12,
+			.ai_fifo_depth = 8192,
+			.alwaysdither = 0,
+			.gainlkup = ai_gain_611x,
+			.ai_speed = 100,
+			.n_aochan = 2,
+			.aobits = 16,
+			.ao_671x = 1,
+			.ao_unipolar = 0,
+			.ao_fifo_depth = 2048,
+			.ao_speed = 250,
+			.reg_611x = 1,
+			.num_p0_dio_channels = 8,
+			caldac = {ad8804_debug, ad8804_debug, ad8804_debug},	/* XXX */
+		},
+#endif
+	{
+			.device_id = 0x1880,
+			.name = "pci-6711",
+			.n_adchan = 0,	/* no analog input */
+			.n_aochan = 4,
+			.aobits = 12,
+			.ao_unipolar = 0,
+			.ao_fifo_depth = 16384,
+			/* data sheet says 8192, but fifo really holds 16384 samples */
+			.ao_range_table = &range_bipolar10,
+			.ao_speed = 1000,
+			.num_p0_dio_channels = 8,
+			.reg_type = ni_reg_6711,
+			.caldac = {ad8804_debug},
+		},
+	{
+			.device_id = 0x2b90,
+			.name = "pxi-6711",
+			.n_adchan = 0,	/* no analog input */
+			.n_aochan = 4,
+			.aobits = 12,
+			.ao_unipolar = 0,
+			.ao_fifo_depth = 16384,
+			.ao_range_table = &range_bipolar10,
+			.ao_speed = 1000,
+			.num_p0_dio_channels = 8,
+			.reg_type = ni_reg_6711,
+			.caldac = {ad8804_debug},
+		},
+	{
+			.device_id = 0x1870,
+			.name = "pci-6713",
+			.n_adchan = 0,	/* no analog input */
+			.n_aochan = 8,
+			.aobits = 12,
+			.ao_unipolar = 0,
+			.ao_fifo_depth = 16384,
+			.ao_range_table = &range_bipolar10,
+			.ao_speed = 1000,
+			.num_p0_dio_channels = 8,
+			.reg_type = ni_reg_6713,
+			.caldac = {ad8804_debug, ad8804_debug},
+		},
+	{
+			.device_id = 0x2b80,
+			.name = "pxi-6713",
+			.n_adchan = 0,	/* no analog input */
+			.n_aochan = 8,
+			.aobits = 12,
+			.ao_unipolar = 0,
+			.ao_fifo_depth = 16384,
+			.ao_range_table = &range_bipolar10,
+			.ao_speed = 1000,
+			.num_p0_dio_channels = 8,
+			.reg_type = ni_reg_6713,
+			.caldac = {ad8804_debug, ad8804_debug},
+		},
+	{
+			.device_id = 0x2430,
+			.name = "pci-6731",
+			.n_adchan = 0,	/* no analog input */
+			.n_aochan = 4,
+			.aobits = 16,
+			.ao_unipolar = 0,
+			.ao_fifo_depth = 8192,
+			.ao_range_table = &range_bipolar10,
+			.ao_speed = 1000,
+			.num_p0_dio_channels = 8,
+			.reg_type = ni_reg_6711,
+			.caldac = {ad8804_debug},
+		},
+#if 0				/* need device ids */
+	{
+			.device_id = 0x0,
+			.name = "pxi-6731",
+			.n_adchan = 0,	/* no analog input */
+			.n_aochan = 4,
+			.aobits = 16,
+			.ao_unipolar = 0,
+			.ao_fifo_depth = 8192,
+			.ao_range_table = &range_bipolar10,
+			.num_p0_dio_channels = 8,
+			.reg_type = ni_reg_6711,
+			.caldac = {ad8804_debug},
+		},
+#endif
+	{
+			.device_id = 0x2410,
+			.name = "pci-6733",
+			.n_adchan = 0,	/* no analog input */
+			.n_aochan = 8,
+			.aobits = 16,
+			.ao_unipolar = 0,
+			.ao_fifo_depth = 16384,
+			.ao_range_table = &range_bipolar10,
+			.ao_speed = 1000,
+			.num_p0_dio_channels = 8,
+			.reg_type = ni_reg_6713,
+			.caldac = {ad8804_debug, ad8804_debug},
+		},
+	{
+			.device_id = 0x2420,
+			.name = "pxi-6733",
+			.n_adchan = 0,	/* no analog input */
+			.n_aochan = 8,
+			.aobits = 16,
+			.ao_unipolar = 0,
+			.ao_fifo_depth = 16384,
+			.ao_range_table = &range_bipolar10,
+			.ao_speed = 1000,
+			.num_p0_dio_channels = 8,
+			.reg_type = ni_reg_6713,
+			.caldac = {ad8804_debug, ad8804_debug},
+		},
+	{
+			.device_id = 0x15b0,
+			.name = "pxi-6071e",
+			.n_adchan = 64,
+			.adbits = 12,
+			.ai_fifo_depth = 512,
+			.alwaysdither = 1,
+			.gainlkup = ai_gain_16,
+			.ai_speed = 800,
+			.n_aochan = 2,
+			.aobits = 12,
+			.ao_fifo_depth = 2048,
+			.ao_range_table = &range_ni_E_ao_ext,
+			.ao_unipolar = 1,
+			.ao_speed = 1000,
+			.num_p0_dio_channels = 8,
+			.caldac = {ad8804_debug},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x11b0,
+			.name = "pxi-6070e",
+			.n_adchan = 16,
+			.adbits = 12,
+			.ai_fifo_depth = 512,
+			.alwaysdither = 1,
+			.gainlkup = ai_gain_16,
+			.ai_speed = 800,
+			.n_aochan = 2,
+			.aobits = 12,
+			.ao_fifo_depth = 2048,
+			.ao_range_table = &range_ni_E_ao_ext,
+			.ao_unipolar = 1,
+			.ao_speed = 1000,
+			.num_p0_dio_channels = 8,
+			.caldac = {ad8804_debug},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x18c0,
+			.name = "pxi-6052e",
+			.n_adchan = 16,
+			.adbits = 16,
+			.ai_fifo_depth = 512,
+			.alwaysdither = 1,
+			.gainlkup = ai_gain_16,
+			.ai_speed = 3000,
+			.n_aochan = 2,
+			.aobits = 16,
+			.ao_unipolar = 1,
+			.ao_fifo_depth = 2048,
+			.ao_range_table = &range_ni_E_ao_ext,
+			.ao_speed = 3000,
+			.num_p0_dio_channels = 8,
+			.caldac = {mb88341, mb88341, ad8522},
+		},
+	{
+			.device_id = 0x1580,
+			.name = "pxi-6031e",
+			.n_adchan = 64,
+			.adbits = 16,
+			.ai_fifo_depth = 512,
+			.alwaysdither = 1,
+			.gainlkup = ai_gain_14,
+			.ai_speed = 10000,
+			.n_aochan = 2,
+			.aobits = 16,
+			.ao_fifo_depth = 2048,
+			.ao_range_table = &range_ni_E_ao_ext,
+			.ao_unipolar = 1,
+			.ao_speed = 10000,
+			.num_p0_dio_channels = 8,
+			.caldac = {dac8800, dac8043, ad8522},
+		},
+	{
+			.device_id = 0x2890,
+			.name = "pci-6036e",
+			.n_adchan = 16,
+			.adbits = 16,
+			.ai_fifo_depth = 512,
+			.alwaysdither = 1,
+			.gainlkup = ai_gain_4,
+			.ai_speed = 5000,
+			.n_aochan = 2,
+			.aobits = 16,
+			.ao_fifo_depth = 0,
+			.ao_range_table = &range_bipolar10,
+			.ao_unipolar = 0,
+			.ao_speed = 100000,
+			.num_p0_dio_channels = 8,
+			.caldac = {ad8804_debug},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x70b0,
+			.name = "pci-6220",
+			.n_adchan = 16,
+			.adbits = 16,
+			.ai_fifo_depth = 512,
+			//FIXME:  guess
+			.gainlkup = ai_gain_622x,
+			.ai_speed = 4000,
+			.n_aochan = 0,
+			.aobits = 0,
+			.ao_fifo_depth = 0,
+			.num_p0_dio_channels = 8,
+			.reg_type = ni_reg_622x,
+			.ao_unipolar = 0,
+			.caldac = {caldac_none},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x70af,
+			.name = "pci-6221",
+			.n_adchan = 16,
+			.adbits = 16,
+			.ai_fifo_depth = 4095,
+			.gainlkup = ai_gain_622x,
+			.ai_speed = 4000,
+			.n_aochan = 2,
+			.aobits = 16,
+			.ao_fifo_depth = 8191,
+			.ao_range_table = &range_ni_M_622x_ao,
+			.reg_type = ni_reg_622x,
+			.ao_unipolar = 0,
+			.ao_speed = 1200,
+			.num_p0_dio_channels = 8,
+			.caldac = {caldac_none},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x71bc,
+			.name = "pci-6221_37pin",
+			.n_adchan = 16,
+			.adbits = 16,
+			.ai_fifo_depth = 4095,
+			.gainlkup = ai_gain_622x,
+			.ai_speed = 4000,
+			.n_aochan = 2,
+			.aobits = 16,
+			.ao_fifo_depth = 8191,
+			.ao_range_table = &range_ni_M_622x_ao,
+			.reg_type = ni_reg_622x,
+			.ao_unipolar = 0,
+			.ao_speed = 1200,
+			.num_p0_dio_channels = 8,
+			.caldac = {caldac_none},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x70f2,
+			.name = "pci-6224",
+			.n_adchan = 32,
+			.adbits = 16,
+			.ai_fifo_depth = 4095,
+			.gainlkup = ai_gain_622x,
+			.ai_speed = 4000,
+			.n_aochan = 0,
+			.aobits = 0,
+			.ao_fifo_depth = 0,
+			.reg_type = ni_reg_622x,
+			.ao_unipolar = 0,
+			.num_p0_dio_channels = 32,
+			.caldac = {caldac_none},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x70f3,
+			.name = "pxi-6224",
+			.n_adchan = 32,
+			.adbits = 16,
+			.ai_fifo_depth = 4095,
+			.gainlkup = ai_gain_622x,
+			.ai_speed = 4000,
+			.n_aochan = 0,
+			.aobits = 0,
+			.ao_fifo_depth = 0,
+			.reg_type = ni_reg_622x,
+			.ao_unipolar = 0,
+			.num_p0_dio_channels = 32,
+			.caldac = {caldac_none},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x716c,
+			.name = "pci-6225",
+			.n_adchan = 80,
+			.adbits = 16,
+			.ai_fifo_depth = 4095,
+			.gainlkup = ai_gain_622x,
+			.ai_speed = 4000,
+			.n_aochan = 2,
+			.aobits = 16,
+			.ao_fifo_depth = 8191,
+			.ao_range_table = &range_ni_M_622x_ao,
+			.reg_type = ni_reg_622x,
+			.ao_unipolar = 0,
+			.ao_speed = 1200,
+			.num_p0_dio_channels = 32,
+			.caldac = {caldac_none},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x70aa,
+			.name = "pci-6229",
+			.n_adchan = 32,
+			.adbits = 16,
+			.ai_fifo_depth = 4095,
+			.gainlkup = ai_gain_622x,
+			.ai_speed = 4000,
+			.n_aochan = 4,
+			.aobits = 16,
+			.ao_fifo_depth = 8191,
+			.ao_range_table = &range_ni_M_622x_ao,
+			.reg_type = ni_reg_622x,
+			.ao_unipolar = 0,
+			.ao_speed = 1200,
+			.num_p0_dio_channels = 32,
+			.caldac = {caldac_none},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x70b4,
+			.name = "pci-6250",
+			.n_adchan = 16,
+			.adbits = 16,
+			.ai_fifo_depth = 4095,
+			.gainlkup = ai_gain_628x,
+			.ai_speed = 800,
+			.n_aochan = 0,
+			.aobits = 0,
+			.ao_fifo_depth = 0,
+			.reg_type = ni_reg_625x,
+			.ao_unipolar = 0,
+			.num_p0_dio_channels = 8,
+			.caldac = {caldac_none},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x70b8,
+			.name = "pci-6251",
+			.n_adchan = 16,
+			.adbits = 16,
+			.ai_fifo_depth = 4095,
+			.gainlkup = ai_gain_628x,
+			.ai_speed = 800,
+			.n_aochan = 2,
+			.aobits = 16,
+			.ao_fifo_depth = 8191,
+			.ao_range_table = &range_ni_M_625x_ao,
+			.reg_type = ni_reg_625x,
+			.ao_unipolar = 0,
+			.ao_speed = 357,
+			.num_p0_dio_channels = 8,
+			.caldac = {caldac_none},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x717d,
+			.name = "pcie-6251",
+			.n_adchan = 16,
+			.adbits = 16,
+			.ai_fifo_depth = 4095,
+			.gainlkup = ai_gain_628x,
+			.ai_speed = 800,
+			.n_aochan = 2,
+			.aobits = 16,
+			.ao_fifo_depth = 8191,
+			.ao_range_table = &range_ni_M_625x_ao,
+			.reg_type = ni_reg_625x,
+			.ao_unipolar = 0,
+			.ao_speed = 357,
+			.num_p0_dio_channels = 8,
+			.caldac = {caldac_none},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x70b7,
+			.name = "pci-6254",
+			.n_adchan = 32,
+			.adbits = 16,
+			.ai_fifo_depth = 4095,
+			.gainlkup = ai_gain_628x,
+			.ai_speed = 800,
+			.n_aochan = 0,
+			.aobits = 0,
+			.ao_fifo_depth = 0,
+			.reg_type = ni_reg_625x,
+			.ao_unipolar = 0,
+			.num_p0_dio_channels = 32,
+			.caldac = {caldac_none},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x70ab,
+			.name = "pci-6259",
+			.n_adchan = 32,
+			.adbits = 16,
+			.ai_fifo_depth = 4095,
+			.gainlkup = ai_gain_628x,
+			.ai_speed = 800,
+			.n_aochan = 4,
+			.aobits = 16,
+			.ao_fifo_depth = 8191,
+			.ao_range_table = &range_ni_M_625x_ao,
+			.reg_type = ni_reg_625x,
+			.ao_unipolar = 0,
+			.ao_speed = 357,
+			.num_p0_dio_channels = 32,
+			.caldac = {caldac_none},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x717f,
+			.name = "pcie-6259",
+			.n_adchan = 32,
+			.adbits = 16,
+			.ai_fifo_depth = 4095,
+			.gainlkup = ai_gain_628x,
+			.ai_speed = 800,
+			.n_aochan = 4,
+			.aobits = 16,
+			.ao_fifo_depth = 8191,
+			.ao_range_table = &range_ni_M_625x_ao,
+			.reg_type = ni_reg_625x,
+			.ao_unipolar = 0,
+			.ao_speed = 357,
+			.num_p0_dio_channels = 32,
+			.caldac = {caldac_none},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x70b6,
+			.name = "pci-6280",
+			.n_adchan = 16,
+			.adbits = 18,
+			.ai_fifo_depth = 2047,
+			.gainlkup = ai_gain_628x,
+			.ai_speed = 1600,
+			.n_aochan = 0,
+			.aobits = 0,
+			.ao_fifo_depth = 8191,
+			.reg_type = ni_reg_628x,
+			.ao_unipolar = 0,
+			.num_p0_dio_channels = 8,
+			.caldac = {caldac_none},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x70bd,
+			.name = "pci-6281",
+			.n_adchan = 16,
+			.adbits = 18,
+			.ai_fifo_depth = 2047,
+			.gainlkup = ai_gain_628x,
+			.ai_speed = 1600,
+			.n_aochan = 2,
+			.aobits = 16,
+			.ao_fifo_depth = 8191,
+			.ao_range_table = &range_ni_M_628x_ao,
+			.reg_type = ni_reg_628x,
+			.ao_unipolar = 1,
+			.ao_speed = 357,
+			.num_p0_dio_channels = 8,
+			.caldac = {caldac_none},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x70bf,
+			.name = "pxi-6281",
+			.n_adchan = 16,
+			.adbits = 18,
+			.ai_fifo_depth = 2047,
+			.gainlkup = ai_gain_628x,
+			.ai_speed = 1600,
+			.n_aochan = 2,
+			.aobits = 16,
+			.ao_fifo_depth = 8191,
+			.ao_range_table = &range_ni_M_628x_ao,
+			.reg_type = ni_reg_628x,
+			.ao_unipolar = 1,
+			.ao_speed = 357,
+			.num_p0_dio_channels = 8,
+			.caldac = {caldac_none},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x70bc,
+			.name = "pci-6284",
+			.n_adchan = 32,
+			.adbits = 18,
+			.ai_fifo_depth = 2047,
+			.gainlkup = ai_gain_628x,
+			.ai_speed = 1600,
+			.n_aochan = 0,
+			.aobits = 0,
+			.ao_fifo_depth = 0,
+			.reg_type = ni_reg_628x,
+			.ao_unipolar = 0,
+			.num_p0_dio_channels = 32,
+			.caldac = {caldac_none},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x70ac,
+			.name = "pci-6289",
+			.n_adchan = 32,
+			.adbits = 18,
+			.ai_fifo_depth = 2047,
+			.gainlkup = ai_gain_628x,
+			.ai_speed = 1600,
+			.n_aochan = 4,
+			.aobits = 16,
+			.ao_fifo_depth = 8191,
+			.ao_range_table = &range_ni_M_628x_ao,
+			.reg_type = ni_reg_628x,
+			.ao_unipolar = 1,
+			.ao_speed = 357,
+			.num_p0_dio_channels = 32,
+			.caldac = {caldac_none},
+			.has_8255 = 0,
+		},
+	{
+			.device_id = 0x70C0,
+			.name = "pci-6143",
+			.n_adchan = 8,
+			.adbits = 16,
+			.ai_fifo_depth = 1024,
+			.alwaysdither = 0,
+			.gainlkup = ai_gain_6143,
+			.ai_speed = 4000,
+			.n_aochan = 0,
+			.aobits = 0,
+			.reg_type = ni_reg_6143,
+			.ao_unipolar = 0,
+			.ao_fifo_depth = 0,
+			.num_p0_dio_channels = 8,
+			.caldac = {ad8804_debug, ad8804_debug},
+		},
+	{
+			.device_id = 0x710D,
+			.name = "pxi-6143",
+			.n_adchan = 8,
+			.adbits = 16,
+			.ai_fifo_depth = 1024,
+			.alwaysdither = 0,
+			.gainlkup = ai_gain_6143,
+			.ai_speed = 4000,
+			.n_aochan = 0,
+			.aobits = 0,
+			.reg_type = ni_reg_6143,
+			.ao_unipolar = 0,
+			.ao_fifo_depth = 0,
+			.num_p0_dio_channels = 8,
+			.caldac = {ad8804_debug, ad8804_debug},
+		},
+};
+
+#define n_pcimio_boards ((sizeof(ni_boards)/sizeof(ni_boards[0])))
+
+static int pcimio_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcimio_detach(struct comedi_device * dev);
+static struct comedi_driver driver_pcimio = {
+	driver_name: DRV_NAME,
+	module:THIS_MODULE,
+	attach:pcimio_attach,
+	detach:pcimio_detach,
+};
+
+COMEDI_PCI_INITCLEANUP(driver_pcimio, ni_pci_table)
+
+typedef struct {
+NI_PRIVATE_COMMON} ni_private;
+#define devpriv ((ni_private *)dev->private)
+
+/* How we access registers */
+
+#define ni_writel(a,b)	(writel((a), devpriv->mite->daq_io_addr + (b)))
+#define ni_readl(a)	(readl(devpriv->mite->daq_io_addr + (a)))
+#define ni_writew(a,b)	(writew((a), devpriv->mite->daq_io_addr + (b)))
+#define ni_readw(a)	(readw(devpriv->mite->daq_io_addr + (a)))
+#define ni_writeb(a,b)	(writeb((a), devpriv->mite->daq_io_addr + (b)))
+#define ni_readb(a)	(readb(devpriv->mite->daq_io_addr + (a)))
+
+/* How we access STC registers */
+
+/* We automatically take advantage of STC registers that can be
+ * read/written directly in the I/O space of the board.  Most
+ * PCIMIO devices map the low 8 STC registers to iobase+addr*2.
+ * The 611x devices map the write registers to iobase+addr*2, and
+ * the read registers to iobase+(addr-1)*2. */
+/* However, the 611x boards still aren't working, so I'm disabling
+ * non-windowed STC access temporarily */
+
+static void e_series_win_out(struct comedi_device * dev, uint16_t data, int reg)
+{
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+	ni_writew(reg, Window_Address);
+	ni_writew(data, Window_Data);
+	comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+}
+
+static uint16_t e_series_win_in(struct comedi_device * dev, int reg)
+{
+	unsigned long flags;
+	uint16_t ret;
+
+	comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+	ni_writew(reg, Window_Address);
+	ret = ni_readw(Window_Data);
+	comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+
+	return ret;
+}
+
+static void m_series_stc_writew(struct comedi_device * dev, uint16_t data, int reg)
+{
+	unsigned offset;
+	switch (reg) {
+	case ADC_FIFO_Clear:
+		offset = M_Offset_AI_FIFO_Clear;
+		break;
+	case AI_Command_1_Register:
+		offset = M_Offset_AI_Command_1;
+		break;
+	case AI_Command_2_Register:
+		offset = M_Offset_AI_Command_2;
+		break;
+	case AI_Mode_1_Register:
+		offset = M_Offset_AI_Mode_1;
+		break;
+	case AI_Mode_2_Register:
+		offset = M_Offset_AI_Mode_2;
+		break;
+	case AI_Mode_3_Register:
+		offset = M_Offset_AI_Mode_3;
+		break;
+	case AI_Output_Control_Register:
+		offset = M_Offset_AI_Output_Control;
+		break;
+	case AI_Personal_Register:
+		offset = M_Offset_AI_Personal;
+		break;
+	case AI_SI2_Load_A_Register:
+		// this is actually a 32 bit register on m series boards
+		ni_writel(data, M_Offset_AI_SI2_Load_A);
+		return;
+		break;
+	case AI_SI2_Load_B_Register:
+		// this is actually a 32 bit register on m series boards
+		ni_writel(data, M_Offset_AI_SI2_Load_B);
+		return;
+		break;
+	case AI_START_STOP_Select_Register:
+		offset = M_Offset_AI_START_STOP_Select;
+		break;
+	case AI_Trigger_Select_Register:
+		offset = M_Offset_AI_Trigger_Select;
+		break;
+	case Analog_Trigger_Etc_Register:
+		offset = M_Offset_Analog_Trigger_Etc;
+		break;
+	case AO_Command_1_Register:
+		offset = M_Offset_AO_Command_1;
+		break;
+	case AO_Command_2_Register:
+		offset = M_Offset_AO_Command_2;
+		break;
+	case AO_Mode_1_Register:
+		offset = M_Offset_AO_Mode_1;
+		break;
+	case AO_Mode_2_Register:
+		offset = M_Offset_AO_Mode_2;
+		break;
+	case AO_Mode_3_Register:
+		offset = M_Offset_AO_Mode_3;
+		break;
+	case AO_Output_Control_Register:
+		offset = M_Offset_AO_Output_Control;
+		break;
+	case AO_Personal_Register:
+		offset = M_Offset_AO_Personal;
+		break;
+	case AO_Start_Select_Register:
+		offset = M_Offset_AO_Start_Select;
+		break;
+	case AO_Trigger_Select_Register:
+		offset = M_Offset_AO_Trigger_Select;
+		break;
+	case Clock_and_FOUT_Register:
+		offset = M_Offset_Clock_and_FOUT;
+		break;
+	case Configuration_Memory_Clear:
+		offset = M_Offset_Configuration_Memory_Clear;
+		break;
+	case DAC_FIFO_Clear:
+		offset = M_Offset_AO_FIFO_Clear;
+		break;
+	case DIO_Control_Register:
+		rt_printk
+			("%s: FIXME: register 0x%x does not map cleanly on to m-series boards.\n",
+			__FUNCTION__, reg);
+		return;
+		break;
+	case G_Autoincrement_Register(0):
+		offset = M_Offset_G0_Autoincrement;
+		break;
+	case G_Autoincrement_Register(1):
+		offset = M_Offset_G1_Autoincrement;
+		break;
+	case G_Command_Register(0):
+		offset = M_Offset_G0_Command;
+		break;
+	case G_Command_Register(1):
+		offset = M_Offset_G1_Command;
+		break;
+	case G_Input_Select_Register(0):
+		offset = M_Offset_G0_Input_Select;
+		break;
+	case G_Input_Select_Register(1):
+		offset = M_Offset_G1_Input_Select;
+		break;
+	case G_Mode_Register(0):
+		offset = M_Offset_G0_Mode;
+		break;
+	case G_Mode_Register(1):
+		offset = M_Offset_G1_Mode;
+		break;
+	case Interrupt_A_Ack_Register:
+		offset = M_Offset_Interrupt_A_Ack;
+		break;
+	case Interrupt_A_Enable_Register:
+		offset = M_Offset_Interrupt_A_Enable;
+		break;
+	case Interrupt_B_Ack_Register:
+		offset = M_Offset_Interrupt_B_Ack;
+		break;
+	case Interrupt_B_Enable_Register:
+		offset = M_Offset_Interrupt_B_Enable;
+		break;
+	case Interrupt_Control_Register:
+		offset = M_Offset_Interrupt_Control;
+		break;
+	case IO_Bidirection_Pin_Register:
+		offset = M_Offset_IO_Bidirection_Pin;
+		break;
+	case Joint_Reset_Register:
+		offset = M_Offset_Joint_Reset;
+		break;
+	case RTSI_Trig_A_Output_Register:
+		offset = M_Offset_RTSI_Trig_A_Output;
+		break;
+	case RTSI_Trig_B_Output_Register:
+		offset = M_Offset_RTSI_Trig_B_Output;
+		break;
+	case RTSI_Trig_Direction_Register:
+		offset = M_Offset_RTSI_Trig_Direction;
+		break;
+		/* FIXME: DIO_Output_Register (16 bit reg) is replaced by M_Offset_Static_Digital_Output (32 bit)
+		   and M_Offset_SCXI_Serial_Data_Out (8 bit) */
+	default:
+		rt_printk("%s: bug! unhandled register=0x%x in switch.\n",
+			__FUNCTION__, reg);
+		BUG();
+		return;
+		break;
+	}
+	ni_writew(data, offset);
+}
+
+static uint16_t m_series_stc_readw(struct comedi_device * dev, int reg)
+{
+	unsigned offset;
+	switch (reg) {
+	case AI_Status_1_Register:
+		offset = M_Offset_AI_Status_1;
+		break;
+	case AO_Status_1_Register:
+		offset = M_Offset_AO_Status_1;
+		break;
+	case AO_Status_2_Register:
+		offset = M_Offset_AO_Status_2;
+		break;
+	case DIO_Serial_Input_Register:
+		return ni_readb(M_Offset_SCXI_Serial_Data_In);
+		break;
+	case Joint_Status_1_Register:
+		offset = M_Offset_Joint_Status_1;
+		break;
+	case Joint_Status_2_Register:
+		offset = M_Offset_Joint_Status_2;
+		break;
+	case G_Status_Register:
+		offset = M_Offset_G01_Status;
+		break;
+	default:
+		rt_printk("%s: bug! unhandled register=0x%x in switch.\n",
+			__FUNCTION__, reg);
+		BUG();
+		return 0;
+		break;
+	}
+	return ni_readw(offset);
+}
+
+static void m_series_stc_writel(struct comedi_device * dev, uint32_t data, int reg)
+{
+	unsigned offset;
+	switch (reg) {
+	case AI_SC_Load_A_Registers:
+		offset = M_Offset_AI_SC_Load_A;
+		break;
+	case AI_SI_Load_A_Registers:
+		offset = M_Offset_AI_SI_Load_A;
+		break;
+	case AO_BC_Load_A_Register:
+		offset = M_Offset_AO_BC_Load_A;
+		break;
+	case AO_UC_Load_A_Register:
+		offset = M_Offset_AO_UC_Load_A;
+		break;
+	case AO_UI_Load_A_Register:
+		offset = M_Offset_AO_UI_Load_A;
+		break;
+	case G_Load_A_Register(0):
+		offset = M_Offset_G0_Load_A;
+		break;
+	case G_Load_A_Register(1):
+		offset = M_Offset_G1_Load_A;
+		break;
+	case G_Load_B_Register(0):
+		offset = M_Offset_G0_Load_B;
+		break;
+	case G_Load_B_Register(1):
+		offset = M_Offset_G1_Load_B;
+		break;
+	default:
+		rt_printk("%s: bug! unhandled register=0x%x in switch.\n",
+			__FUNCTION__, reg);
+		BUG();
+		return;
+		break;
+	}
+	ni_writel(data, offset);
+}
+
+static uint32_t m_series_stc_readl(struct comedi_device * dev, int reg)
+{
+	unsigned offset;
+	switch (reg) {
+	case G_HW_Save_Register(0):
+		offset = M_Offset_G0_HW_Save;
+		break;
+	case G_HW_Save_Register(1):
+		offset = M_Offset_G1_HW_Save;
+		break;
+	case G_Save_Register(0):
+		offset = M_Offset_G0_Save;
+		break;
+	case G_Save_Register(1):
+		offset = M_Offset_G1_Save;
+		break;
+	default:
+		rt_printk("%s: bug! unhandled register=0x%x in switch.\n",
+			__FUNCTION__, reg);
+		BUG();
+		return 0;
+		break;
+	}
+	return ni_readl(offset);
+}
+
+#define interrupt_pin(a)	0
+#define IRQ_POLARITY 1
+
+#define NI_E_IRQ_FLAGS		IRQF_SHARED
+
+#include "ni_mio_common.c"
+
+static int pcimio_find_device(struct comedi_device * dev, int bus, int slot);
+static int pcimio_ai_change(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned long new_size);
+static int pcimio_ao_change(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned long new_size);
+static int pcimio_gpct0_change(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned long new_size);
+static int pcimio_gpct1_change(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned long new_size);
+static int pcimio_dio_change(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned long new_size);
+
+static void m_series_init_eeprom_buffer(struct comedi_device * dev)
+{
+	static const int Start_Cal_EEPROM = 0x400;
+	static const unsigned window_size = 10;
+	static const int serial_number_eeprom_offset = 0x4;
+	static const int serial_number_eeprom_length = 0x4;
+	unsigned old_iodwbsr_bits;
+	unsigned old_iodwbsr1_bits;
+	unsigned old_iodwcr1_bits;
+	int i;
+
+	old_iodwbsr_bits = readl(devpriv->mite->mite_io_addr + MITE_IODWBSR);
+	old_iodwbsr1_bits = readl(devpriv->mite->mite_io_addr + MITE_IODWBSR_1);
+	old_iodwcr1_bits = readl(devpriv->mite->mite_io_addr + MITE_IODWCR_1);
+	writel(0x0, devpriv->mite->mite_io_addr + MITE_IODWBSR);
+	writel(((0x80 | window_size) | devpriv->mite->daq_phys_addr),
+		devpriv->mite->mite_io_addr + MITE_IODWBSR_1);
+	writel(0x1 | old_iodwcr1_bits, devpriv->mite->mite_io_addr + MITE_IODWCR_1);
+	writel(0xf, devpriv->mite->mite_io_addr + 0x30);
+
+	BUG_ON(serial_number_eeprom_length > sizeof(devpriv->serial_number));
+	for (i = 0; i < serial_number_eeprom_length; ++i) {
+		char *byte_ptr = (char*)&devpriv->serial_number + i;
+		*byte_ptr = ni_readb(serial_number_eeprom_offset + i);
+	}
+	devpriv->serial_number = be32_to_cpu(devpriv->serial_number);
+
+	for (i = 0; i < M_SERIES_EEPROM_SIZE; ++i) {
+		devpriv->eeprom_buffer[i] = ni_readb(Start_Cal_EEPROM + i);
+	}
+
+	writel(old_iodwbsr1_bits, devpriv->mite->mite_io_addr + MITE_IODWBSR_1);
+	writel(old_iodwbsr_bits, devpriv->mite->mite_io_addr + MITE_IODWBSR);
+	writel(old_iodwcr1_bits, devpriv->mite->mite_io_addr + MITE_IODWCR_1);
+	writel(0x0, devpriv->mite->mite_io_addr + 0x30);
+}
+
+static void init_6143(struct comedi_device * dev)
+{
+	// Disable interrupts
+	devpriv->stc_writew(dev, 0, Interrupt_Control_Register);
+
+	// Initialise 6143 AI specific bits
+	ni_writeb(0x00, Magic_6143);	// Set G0,G1 DMA mode to E series version
+	ni_writeb(0x80, PipelineDelay_6143);	// Set EOCMode, ADCMode and pipelinedelay
+	ni_writeb(0x00, EOC_Set_6143);	// Set EOC Delay
+
+	ni_writel(boardtype.ai_fifo_depth / 2, AIFIFO_Flag_6143);	// Set the FIFO half full level
+
+	// Strobe Relay disable bit
+	devpriv->ai_calib_source_enabled = 0;
+	ni_writew(devpriv->ai_calib_source | Calibration_Channel_6143_RelayOff,
+		Calibration_Channel_6143);
+	ni_writew(devpriv->ai_calib_source, Calibration_Channel_6143);
+}
+
+/* cleans up allocated resources */
+static int pcimio_detach(struct comedi_device * dev)
+{
+	mio_common_detach(dev);
+	if (dev->irq) {
+		comedi_free_irq(dev->irq, dev);
+	}
+	if (dev->private) {
+		mite_free_ring(devpriv->ai_mite_ring);
+		mite_free_ring(devpriv->ao_mite_ring);
+		mite_free_ring(devpriv->cdo_mite_ring);
+		mite_free_ring(devpriv->gpct_mite_ring[0]);
+		mite_free_ring(devpriv->gpct_mite_ring[1]);
+		if (devpriv->mite)
+			mite_unsetup(devpriv->mite);
+	}
+
+	return 0;
+}
+
+static int pcimio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	int ret;
+
+	printk("comedi%d: ni_pcimio:", dev->minor);
+
+	ret = ni_alloc_private(dev);
+	if (ret < 0)
+		return ret;
+
+	ret = pcimio_find_device(dev, it->options[0], it->options[1]);
+	if (ret < 0)
+		return ret;
+
+	printk(" %s", boardtype.name);
+	dev->board_name = boardtype.name;
+
+	if (boardtype.reg_type & ni_reg_m_series_mask) {
+		devpriv->stc_writew = &m_series_stc_writew;
+		devpriv->stc_readw = &m_series_stc_readw;
+		devpriv->stc_writel = &m_series_stc_writel;
+		devpriv->stc_readl = &m_series_stc_readl;
+	} else {
+		devpriv->stc_writew = &e_series_win_out;
+		devpriv->stc_readw = &e_series_win_in;
+		devpriv->stc_writel = &win_out2;
+		devpriv->stc_readl = &win_in2;
+	}
+
+	ret = mite_setup(devpriv->mite);
+	if (ret < 0) {
+		printk(" error setting up mite\n");
+		return ret;
+	}
+	comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev);
+	devpriv->ai_mite_ring = mite_alloc_ring(devpriv->mite);
+	if (devpriv->ai_mite_ring == NULL)
+		return -ENOMEM;
+	devpriv->ao_mite_ring = mite_alloc_ring(devpriv->mite);
+	if (devpriv->ao_mite_ring == NULL)
+		return -ENOMEM;
+	devpriv->cdo_mite_ring = mite_alloc_ring(devpriv->mite);
+	if (devpriv->cdo_mite_ring == NULL)
+		return -ENOMEM;
+	devpriv->gpct_mite_ring[0] = mite_alloc_ring(devpriv->mite);
+	if (devpriv->gpct_mite_ring[0] == NULL)
+		return -ENOMEM;
+	devpriv->gpct_mite_ring[1] = mite_alloc_ring(devpriv->mite);
+	if (devpriv->gpct_mite_ring[1] == NULL)
+		return -ENOMEM;
+
+	if (boardtype.reg_type & ni_reg_m_series_mask)
+		m_series_init_eeprom_buffer(dev);
+	if (boardtype.reg_type == ni_reg_6143)
+		init_6143(dev);
+
+	dev->irq = mite_irq(devpriv->mite);
+
+	if (dev->irq == 0) {
+		printk(" unknown irq (bad)\n");
+	} else {
+		printk(" ( irq = %u )", dev->irq);
+		if ((ret = comedi_request_irq(dev->irq, ni_E_interrupt,
+					NI_E_IRQ_FLAGS, DRV_NAME,
+					dev)) < 0) {
+			printk(" irq not available\n");
+			dev->irq = 0;
+		}
+	}
+
+	ret = ni_E_init(dev, it);
+	if (ret < 0)
+		return ret;
+
+	dev->subdevices[NI_AI_SUBDEV].buf_change = &pcimio_ai_change;
+	dev->subdevices[NI_AO_SUBDEV].buf_change = &pcimio_ao_change;
+	dev->subdevices[NI_GPCT_SUBDEV(0)].buf_change = &pcimio_gpct0_change;
+	dev->subdevices[NI_GPCT_SUBDEV(1)].buf_change = &pcimio_gpct1_change;
+	dev->subdevices[NI_DIO_SUBDEV].buf_change = &pcimio_dio_change;
+
+	return ret;
+}
+
+static int pcimio_find_device(struct comedi_device * dev, int bus, int slot)
+{
+	struct mite_struct *mite;
+	int i;
+
+	for (mite = mite_devices; mite; mite = mite->next) {
+		if (mite->used)
+			continue;
+		if (bus || slot) {
+			if (bus != mite->pcidev->bus->number ||
+				slot != PCI_SLOT(mite->pcidev->devfn))
+				continue;
+		}
+
+		for (i = 0; i < n_pcimio_boards; i++) {
+			if (mite_device_id(mite) == ni_boards[i].device_id) {
+				dev->board_ptr = ni_boards + i;
+				devpriv->mite = mite;
+
+				return 0;
+			}
+		}
+	}
+	printk("no device found\n");
+	mite_list_devices();
+	return -EIO;
+}
+
+static int pcimio_ai_change(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned long new_size)
+{
+	int ret;
+
+	ret = mite_buf_change(devpriv->ai_mite_ring, s->async);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int pcimio_ao_change(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned long new_size)
+{
+	int ret;
+
+	ret = mite_buf_change(devpriv->ao_mite_ring, s->async);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int pcimio_gpct0_change(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned long new_size)
+{
+	int ret;
+
+	ret = mite_buf_change(devpriv->gpct_mite_ring[0], s->async);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int pcimio_gpct1_change(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned long new_size)
+{
+	int ret;
+
+	ret = mite_buf_change(devpriv->gpct_mite_ring[1], s->async);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int pcimio_dio_change(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned long new_size)
+{
+	int ret;
+
+	ret = mite_buf_change(devpriv->cdo_mite_ring, s->async);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/ni_stc.h b/drivers/staging/comedi/drivers/ni_stc.h
new file mode 100644
index 0000000..1ebf521
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_stc.h
@@ -0,0 +1,1498 @@
+/*
+    module/ni_stc.h
+    Register descriptions for NI DAQ-STC chip
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 1998-9 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+
+/*
+	References:
+	    DAQ-STC Technical Reference Manual
+*/
+
+#ifndef _COMEDI_NI_STC_H
+#define _COMEDI_NI_STC_H
+
+#include "ni_tio.h"
+
+#define _bit15		0x8000
+#define _bit14		0x4000
+#define _bit13		0x2000
+#define _bit12		0x1000
+#define _bit11		0x0800
+#define _bit10		0x0400
+#define _bit9		0x0200
+#define _bit8		0x0100
+#define _bit7		0x0080
+#define _bit6		0x0040
+#define _bit5		0x0020
+#define _bit4		0x0010
+#define _bit3		0x0008
+#define _bit2		0x0004
+#define _bit1		0x0002
+#define _bit0		0x0001
+
+#define NUM_PFI_OUTPUT_SELECT_REGS 6
+
+/* Registers in the National Instruments DAQ-STC chip */
+
+#define Interrupt_A_Ack_Register	2
+#define G0_Gate_Interrupt_Ack			_bit15
+#define G0_TC_Interrupt_Ack			_bit14
+#define AI_Error_Interrupt_Ack			_bit13
+#define AI_STOP_Interrupt_Ack			_bit12
+#define AI_START_Interrupt_Ack			_bit11
+#define AI_START2_Interrupt_Ack			_bit10
+#define AI_START1_Interrupt_Ack			_bit9
+#define AI_SC_TC_Interrupt_Ack			_bit8
+#define AI_SC_TC_Error_Confirm			_bit7
+#define G0_TC_Error_Confirm			_bit6
+#define G0_Gate_Error_Confirm			_bit5
+
+#define AI_Status_1_Register		2
+#define Interrupt_A_St				0x8000
+#define AI_FIFO_Full_St				0x4000
+#define AI_FIFO_Half_Full_St			0x2000
+#define AI_FIFO_Empty_St			0x1000
+#define AI_Overrun_St				0x0800
+#define AI_Overflow_St				0x0400
+#define AI_SC_TC_Error_St			0x0200
+#define AI_START2_St				0x0100
+#define AI_START1_St				0x0080
+#define AI_SC_TC_St				0x0040
+#define AI_START_St				0x0020
+#define AI_STOP_St				0x0010
+#define G0_TC_St				0x0008
+#define G0_Gate_Interrupt_St			0x0004
+#define AI_FIFO_Request_St			0x0002
+#define Pass_Thru_0_Interrupt_St		0x0001
+
+#define AI_Status_2_Register		5
+
+#define Interrupt_B_Ack_Register	3
+enum Interrupt_B_Ack_Bits {
+	G1_Gate_Error_Confirm = _bit1,
+	G1_TC_Error_Confirm = _bit2,
+	AO_BC_TC_Trigger_Error_Confirm = _bit3,
+	AO_BC_TC_Error_Confirm = _bit4,
+	AO_UI2_TC_Error_Confrim = _bit5,
+	AO_UI2_TC_Interrupt_Ack = _bit6,
+	AO_UC_TC_Interrupt_Ack = _bit7,
+	AO_BC_TC_Interrupt_Ack = _bit8,
+	AO_START1_Interrupt_Ack = _bit9,
+	AO_UPDATE_Interrupt_Ack = _bit10,
+	AO_START_Interrupt_Ack = _bit11,
+	AO_STOP_Interrupt_Ack = _bit12,
+	AO_Error_Interrupt_Ack = _bit13,
+	G1_TC_Interrupt_Ack = _bit14,
+	G1_Gate_Interrupt_Ack = _bit15
+};
+
+#define AO_Status_1_Register		3
+#define Interrupt_B_St				_bit15
+#define AO_FIFO_Full_St				_bit14
+#define AO_FIFO_Half_Full_St			_bit13
+#define AO_FIFO_Empty_St			_bit12
+#define AO_BC_TC_Error_St			_bit11
+#define AO_START_St				_bit10
+#define AO_Overrun_St				_bit9
+#define AO_START1_St				_bit8
+#define AO_BC_TC_St				_bit7
+#define AO_UC_TC_St				_bit6
+#define AO_UPDATE_St				_bit5
+#define AO_UI2_TC_St				_bit4
+#define G1_TC_St				_bit3
+#define G1_Gate_Interrupt_St			_bit2
+#define AO_FIFO_Request_St			_bit1
+#define Pass_Thru_1_Interrupt_St		_bit0
+
+#define AI_Command_2_Register		4
+#define AI_End_On_SC_TC				_bit15
+#define AI_End_On_End_Of_Scan			_bit14
+#define AI_START1_Disable			_bit11
+#define AI_SC_Save_Trace			_bit10
+#define AI_SI_Switch_Load_On_SC_TC		_bit9
+#define AI_SI_Switch_Load_On_STOP		_bit8
+#define AI_SI_Switch_Load_On_TC			_bit7
+#define AI_SC_Switch_Load_On_TC			_bit4
+#define AI_STOP_Pulse				_bit3
+#define AI_START_Pulse				_bit2
+#define AI_START2_Pulse				_bit1
+#define AI_START1_Pulse				_bit0
+
+#define AO_Command_2_Register		5
+#define AO_End_On_BC_TC(x)			(((x) & 0x3) << 14)
+#define AO_Start_Stop_Gate_Enable		_bit13
+#define AO_UC_Save_Trace			_bit12
+#define AO_BC_Gate_Enable			_bit11
+#define AO_BC_Save_Trace			_bit10
+#define AO_UI_Switch_Load_On_BC_TC		_bit9
+#define AO_UI_Switch_Load_On_Stop		_bit8
+#define AO_UI_Switch_Load_On_TC			_bit7
+#define AO_UC_Switch_Load_On_BC_TC		_bit6
+#define AO_UC_Switch_Load_On_TC			_bit5
+#define AO_BC_Switch_Load_On_TC			_bit4
+#define AO_Mute_B				_bit3
+#define AO_Mute_A				_bit2
+#define AO_UPDATE2_Pulse			_bit1
+#define AO_START1_Pulse				_bit0
+
+#define AO_Status_2_Register		6
+
+#define DIO_Parallel_Input_Register	7
+
+#define AI_Command_1_Register		8
+#define AI_Analog_Trigger_Reset			_bit14
+#define AI_Disarm				_bit13
+#define AI_SI2_Arm				_bit12
+#define AI_SI2_Load				_bit11
+#define AI_SI_Arm				_bit10
+#define AI_SI_Load				_bit9
+#define AI_DIV_Arm				_bit8
+#define AI_DIV_Load				_bit7
+#define AI_SC_Arm				_bit6
+#define AI_SC_Load				_bit5
+#define AI_SCAN_IN_PROG_Pulse			_bit4
+#define AI_EXTMUX_CLK_Pulse			_bit3
+#define AI_LOCALMUX_CLK_Pulse			_bit2
+#define AI_SC_TC_Pulse			 	_bit1
+#define AI_CONVERT_Pulse			_bit0
+
+#define AO_Command_1_Register		9
+#define AO_Analog_Trigger_Reset			_bit15
+#define AO_START_Pulse				_bit14
+#define AO_Disarm				_bit13
+#define AO_UI2_Arm_Disarm			_bit12
+#define AO_UI2_Load				_bit11
+#define AO_UI_Arm				_bit10
+#define AO_UI_Load				_bit9
+#define AO_UC_Arm				_bit8
+#define AO_UC_Load				_bit7
+#define AO_BC_Arm				_bit6
+#define AO_BC_Load				_bit5
+#define AO_DAC1_Update_Mode			_bit4
+#define AO_LDAC1_Source_Select			_bit3
+#define AO_DAC0_Update_Mode			_bit2
+#define AO_LDAC0_Source_Select			_bit1
+#define AO_UPDATE_Pulse				_bit0
+
+#define DIO_Output_Register		10
+#define DIO_Parallel_Data_Out(a)                ((a)&0xff)
+#define DIO_Parallel_Data_Mask                  0xff
+#define DIO_SDOUT                               _bit0
+#define DIO_SDIN                                _bit4
+#define DIO_Serial_Data_Out(a)                  (((a)&0xff)<<8)
+#define DIO_Serial_Data_Mask                    0xff00
+
+#define DIO_Control_Register		11
+#define DIO_Software_Serial_Control             _bit11
+#define DIO_HW_Serial_Timebase                  _bit10
+#define DIO_HW_Serial_Enable                    _bit9
+#define DIO_HW_Serial_Start                     _bit8
+#define DIO_Pins_Dir(a)                         ((a)&0xff)
+#define DIO_Pins_Dir_Mask                       0xff
+
+#define AI_Mode_1_Register		12
+#define AI_CONVERT_Source_Select(a)		(((a) & 0x1f) << 11)
+#define AI_SI_Source_select(a)			(((a) & 0x1f) << 6)
+#define AI_CONVERT_Source_Polarity		_bit5
+#define AI_SI_Source_Polarity		_bit4
+#define AI_Start_Stop				_bit3
+#define AI_Mode_1_Reserved			_bit2
+#define AI_Continuous				_bit1
+#define AI_Trigger_Once				_bit0
+
+#define AI_Mode_2_Register		13
+#define AI_SC_Gate_Enable			_bit15
+#define AI_Start_Stop_Gate_Enable		_bit14
+#define AI_Pre_Trigger				_bit13
+#define AI_External_MUX_Present			_bit12
+#define AI_SI2_Initial_Load_Source		_bit9
+#define AI_SI2_Reload_Mode			_bit8
+#define AI_SI_Initial_Load_Source		_bit7
+#define AI_SI_Reload_Mode(a)			(((a) & 0x7)<<4)
+#define AI_SI_Write_Switch			_bit3
+#define AI_SC_Initial_Load_Source		_bit2
+#define AI_SC_Reload_Mode			_bit1
+#define AI_SC_Write_Switch			_bit0
+
+#define AI_SI_Load_A_Registers		14
+#define AI_SI_Load_B_Registers		16
+#define AI_SC_Load_A_Registers		18
+#define AI_SC_Load_B_Registers		20
+#define AI_SI_Save_Registers		64
+#define AI_SC_Save_Registers		66
+
+#define AI_SI2_Load_A_Register		23
+#define AI_SI2_Load_B_Register		25
+
+#define Joint_Status_1_Register         27
+#define DIO_Serial_IO_In_Progress_St            _bit12
+
+#define DIO_Serial_Input_Register       28
+#define Joint_Status_2_Register         29
+enum Joint_Status_2_Bits {
+	AO_TMRDACWRs_In_Progress_St = 0x20,
+};
+
+#define AO_Mode_1_Register		38
+#define AO_UPDATE_Source_Select(x)		(((x)&0x1f)<<11)
+#define AO_UI_Source_Select(x)			(((x)&0x1f)<<6)
+#define AO_Multiple_Channels			_bit5
+#define AO_UPDATE_Source_Polarity		_bit4
+#define AO_UI_Source_Polarity			_bit3
+#define AO_UC_Switch_Load_Every_TC		_bit2
+#define AO_Continuous				_bit1
+#define AO_Trigger_Once				_bit0
+
+#define AO_Mode_2_Register		39
+#define AO_FIFO_Mode_Mask ( 0x3 << 14 )
+enum AO_FIFO_Mode_Bits {
+	AO_FIFO_Mode_HF_to_F = (3 << 14),
+	AO_FIFO_Mode_F = (2 << 14),
+	AO_FIFO_Mode_HF = (1 << 14),
+	AO_FIFO_Mode_E = (0 << 14),
+};
+#define AO_FIFO_Retransmit_Enable		_bit13
+#define AO_START1_Disable			_bit12
+#define AO_UC_Initial_Load_Source		_bit11
+#define AO_UC_Write_Switch			_bit10
+#define AO_UI2_Initial_Load_Source		_bit9
+#define AO_UI2_Reload_Mode			_bit8
+#define AO_UI_Initial_Load_Source		_bit7
+#define AO_UI_Reload_Mode(x)			(((x) & 0x7) << 4)
+#define AO_UI_Write_Switch			_bit3
+#define AO_BC_Initial_Load_Source		_bit2
+#define AO_BC_Reload_Mode			_bit1
+#define AO_BC_Write_Switch			_bit0
+
+#define AO_UI_Load_A_Register		40
+#define AO_UI_Load_A_Register_High	40
+#define AO_UI_Load_A_Register_Low	41
+#define AO_UI_Load_B_Register		42
+#define AO_UI_Save_Registers		16
+#define AO_BC_Load_A_Register		44
+#define AO_BC_Load_A_Register_High	44
+#define AO_BC_Load_A_Register_Low	45
+#define AO_BC_Load_B_Register		46
+#define AO_BC_Load_B_Register_High	46
+#define AO_BC_Load_B_Register_Low	47
+#define AO_BC_Save_Registers		18
+#define AO_UC_Load_A_Register		48
+#define AO_UC_Load_A_Register_High	48
+#define AO_UC_Load_A_Register_Low	49
+#define AO_UC_Load_B_Register		50
+#define AO_UC_Save_Registers		20
+
+#define Clock_and_FOUT_Register		56
+enum Clock_and_FOUT_bits {
+	FOUT_Enable = _bit15,
+	FOUT_Timebase_Select = _bit14,
+	DIO_Serial_Out_Divide_By_2 = _bit13,
+	Slow_Internal_Time_Divide_By_2 = _bit12,
+	Slow_Internal_Timebase = _bit11,
+	G_Source_Divide_By_2 = _bit10,
+	Clock_To_Board_Divide_By_2 = _bit9,
+	Clock_To_Board = _bit8,
+	AI_Output_Divide_By_2 = _bit7,
+	AI_Source_Divide_By_2 = _bit6,
+	AO_Output_Divide_By_2 = _bit5,
+	AO_Source_Divide_By_2 = _bit4,
+	FOUT_Divider_mask = 0xf
+};
+static inline unsigned FOUT_Divider(unsigned divider)
+{
+	return (divider & FOUT_Divider_mask);
+}
+
+#define IO_Bidirection_Pin_Register	57
+#define	RTSI_Trig_Direction_Register	58
+enum RTSI_Trig_Direction_Bits {
+	Drive_RTSI_Clock_Bit = 0x1,
+	Use_RTSI_Clock_Bit = 0x2,
+};
+static inline unsigned RTSI_Output_Bit(unsigned channel, int is_mseries)
+{
+	unsigned max_channel;
+	unsigned base_bit_shift;
+	if (is_mseries) {
+		base_bit_shift = 8;
+		max_channel = 7;
+	} else {
+		base_bit_shift = 9;
+		max_channel = 6;
+	}
+	if (channel > max_channel) {
+		rt_printk("%s: bug, invalid RTSI_channel=%i\n", __FUNCTION__,
+			channel);
+		return 0;
+	}
+	return 1 << (base_bit_shift + channel);
+}
+
+#define Interrupt_Control_Register	59
+#define Interrupt_B_Enable			_bit15
+#define Interrupt_B_Output_Select(x)		((x)<<12)
+#define Interrupt_A_Enable			_bit11
+#define Interrupt_A_Output_Select(x)		((x)<<8)
+#define Pass_Thru_0_Interrupt_Polarity		_bit3
+#define Pass_Thru_1_Interrupt_Polarity		_bit2
+#define Interrupt_Output_On_3_Pins		_bit1
+#define Interrupt_Output_Polarity		_bit0
+
+#define AI_Output_Control_Register	60
+#define AI_START_Output_Select			_bit10
+#define AI_SCAN_IN_PROG_Output_Select(x)	(((x) & 0x3) << 8)
+#define AI_EXTMUX_CLK_Output_Select(x)		(((x) & 0x3) << 6)
+#define AI_LOCALMUX_CLK_Output_Select(x)	((x)<<4)
+#define AI_SC_TC_Output_Select(x)		((x)<<2)
+enum ai_convert_output_selection {
+	AI_CONVERT_Output_High_Z = 0,
+	AI_CONVERT_Output_Ground = 1,
+	AI_CONVERT_Output_Enable_Low = 2,
+	AI_CONVERT_Output_Enable_High = 3
+};
+static unsigned AI_CONVERT_Output_Select(enum ai_convert_output_selection
+	selection)
+{
+	return selection & 0x3;
+}
+
+#define AI_START_STOP_Select_Register	62
+#define AI_START_Polarity			_bit15
+#define AI_STOP_Polarity			_bit14
+#define AI_STOP_Sync				_bit13
+#define AI_STOP_Edge				_bit12
+#define AI_STOP_Select(a)			(((a) & 0x1f)<<7)
+#define AI_START_Sync				_bit6
+#define AI_START_Edge				_bit5
+#define AI_START_Select(a)			((a) & 0x1f)
+
+#define AI_Trigger_Select_Register	63
+#define AI_START1_Polarity			_bit15
+#define AI_START2_Polarity			_bit14
+#define AI_START2_Sync				_bit13
+#define AI_START2_Edge				_bit12
+#define AI_START2_Select(a)			(((a) & 0x1f) << 7)
+#define AI_START1_Sync				_bit6
+#define AI_START1_Edge				_bit5
+#define AI_START1_Select(a)			((a) & 0x1f)
+
+#define AI_DIV_Load_A_Register	64
+
+#define AO_Start_Select_Register	66
+#define AO_UI2_Software_Gate			_bit15
+#define AO_UI2_External_Gate_Polarity		_bit14
+#define AO_START_Polarity			_bit13
+#define AO_AOFREQ_Enable			_bit12
+#define AO_UI2_External_Gate_Select(a)		(((a) & 0x1f) << 7)
+#define AO_START_Sync				_bit6
+#define AO_START_Edge				_bit5
+#define AO_START_Select(a)			((a) & 0x1f)
+
+#define AO_Trigger_Select_Register	67
+#define AO_UI2_External_Gate_Enable		_bit15
+#define AO_Delayed_START1			_bit14
+#define AO_START1_Polarity			_bit13
+#define AO_UI2_Source_Polarity			_bit12
+#define AO_UI2_Source_Select(x)			(((x)&0x1f)<<7)
+#define AO_START1_Sync				_bit6
+#define AO_START1_Edge				_bit5
+#define AO_START1_Select(x)			(((x)&0x1f)<<0)
+
+#define AO_Mode_3_Register		70
+#define AO_UI2_Switch_Load_Next_TC		_bit13
+#define AO_UC_Switch_Load_Every_BC_TC		_bit12
+#define AO_Trigger_Length			_bit11
+#define AO_Stop_On_Overrun_Error		_bit5
+#define AO_Stop_On_BC_TC_Trigger_Error		_bit4
+#define AO_Stop_On_BC_TC_Error			_bit3
+#define AO_Not_An_UPDATE			_bit2
+#define AO_Software_Gate			_bit1
+#define AO_Last_Gate_Disable		_bit0	/* M Series only */
+
+#define Joint_Reset_Register		72
+#define Software_Reset			_bit11
+#define AO_Configuration_End			_bit9
+#define AI_Configuration_End			_bit8
+#define AO_Configuration_Start			_bit5
+#define AI_Configuration_Start			_bit4
+#define G1_Reset				_bit3
+#define G0_Reset				_bit2
+#define AO_Reset				_bit1
+#define AI_Reset				_bit0
+
+#define Interrupt_A_Enable_Register	73
+#define Pass_Thru_0_Interrupt_Enable		_bit9
+#define G0_Gate_Interrupt_Enable		_bit8
+#define AI_FIFO_Interrupt_Enable		_bit7
+#define G0_TC_Interrupt_Enable			_bit6
+#define AI_Error_Interrupt_Enable		_bit5
+#define AI_STOP_Interrupt_Enable		_bit4
+#define AI_START_Interrupt_Enable		_bit3
+#define AI_START2_Interrupt_Enable		_bit2
+#define AI_START1_Interrupt_Enable		_bit1
+#define AI_SC_TC_Interrupt_Enable		_bit0
+
+#define Interrupt_B_Enable_Register	75
+#define Pass_Thru_1_Interrupt_Enable		_bit11
+#define G1_Gate_Interrupt_Enable		_bit10
+#define G1_TC_Interrupt_Enable			_bit9
+#define AO_FIFO_Interrupt_Enable		_bit8
+#define AO_UI2_TC_Interrupt_Enable		_bit7
+#define AO_UC_TC_Interrupt_Enable		_bit6
+#define AO_Error_Interrupt_Enable		_bit5
+#define AO_STOP_Interrupt_Enable		_bit4
+#define AO_START_Interrupt_Enable		_bit3
+#define AO_UPDATE_Interrupt_Enable		_bit2
+#define AO_START1_Interrupt_Enable		_bit1
+#define AO_BC_TC_Interrupt_Enable		_bit0
+
+#define Second_IRQ_A_Enable_Register	74
+enum Second_IRQ_A_Enable_Bits {
+	AI_SC_TC_Second_Irq_Enable = _bit0,
+	AI_START1_Second_Irq_Enable = _bit1,
+	AI_START2_Second_Irq_Enable = _bit2,
+	AI_START_Second_Irq_Enable = _bit3,
+	AI_STOP_Second_Irq_Enable = _bit4,
+	AI_Error_Second_Irq_Enable = _bit5,
+	G0_TC_Second_Irq_Enable = _bit6,
+	AI_FIFO_Second_Irq_Enable = _bit7,
+	G0_Gate_Second_Irq_Enable = _bit8,
+	Pass_Thru_0_Second_Irq_Enable = _bit9
+};
+
+#define Second_IRQ_B_Enable_Register	76
+enum Second_IRQ_B_Enable_Bits {
+	AO_BC_TC_Second_Irq_Enable = _bit0,
+	AO_START1_Second_Irq_Enable = _bit1,
+	AO_UPDATE_Second_Irq_Enable = _bit2,
+	AO_START_Second_Irq_Enable = _bit3,
+	AO_STOP_Second_Irq_Enable = _bit4,
+	AO_Error_Second_Irq_Enable = _bit5,
+	AO_UC_TC_Second_Irq_Enable = _bit6,
+	AO_UI2_TC_Second_Irq_Enable = _bit7,
+	AO_FIFO_Second_Irq_Enable = _bit8,
+	G1_TC_Second_Irq_Enable = _bit9,
+	G1_Gate_Second_Irq_Enable = _bit10,
+	Pass_Thru_1_Second_Irq_Enable = _bit11
+};
+
+#define AI_Personal_Register		77
+#define AI_SHIFTIN_Pulse_Width			_bit15
+#define AI_EOC_Polarity				_bit14
+#define AI_SOC_Polarity				_bit13
+#define AI_SHIFTIN_Polarity			_bit12
+#define AI_CONVERT_Pulse_Timebase		_bit11
+#define AI_CONVERT_Pulse_Width			_bit10
+#define AI_CONVERT_Original_Pulse		_bit9
+#define AI_FIFO_Flags_Polarity			_bit8
+#define AI_Overrun_Mode				_bit7
+#define AI_EXTMUX_CLK_Pulse_Width		_bit6
+#define AI_LOCALMUX_CLK_Pulse_Width		_bit5
+#define AI_AIFREQ_Polarity			_bit4
+
+#define AO_Personal_Register		78
+enum AO_Personal_Bits {
+	AO_Interval_Buffer_Mode = 1 << 3,
+	AO_BC_Source_Select = 1 << 4,
+	AO_UPDATE_Pulse_Width = 1 << 5,
+	AO_UPDATE_Pulse_Timebase = 1 << 6,
+	AO_UPDATE_Original_Pulse = 1 << 7,
+	AO_DMA_PIO_Control = 1 << 8,	/* M Series: reserved */
+	AO_AOFREQ_Polarity = 1 << 9,	/* M Series: reserved */
+	AO_FIFO_Enable = 1 << 10,
+	AO_FIFO_Flags_Polarity = 1 << 11,	/* M Series: reserved */
+	AO_TMRDACWR_Pulse_Width = 1 << 12,
+	AO_Fast_CPU = 1 << 13,	/* M Series: reserved */
+	AO_Number_Of_DAC_Packages = 1 << 14,	// 1 for "single" mode, 0 for "dual"
+	AO_Multiple_DACS_Per_Package = 1 << 15	// m-series only
+};
+#define	RTSI_Trig_A_Output_Register	79
+#define	RTSI_Trig_B_Output_Register	80
+enum RTSI_Trig_B_Output_Bits {
+	RTSI_Sub_Selection_1_Bit = 0x8000	// not for m-series
+};
+static inline unsigned RTSI_Trig_Output_Bits(unsigned rtsi_channel,
+	unsigned source)
+{
+	return (source & 0xf) << ((rtsi_channel % 4) * 4);
+};
+static inline unsigned RTSI_Trig_Output_Mask(unsigned rtsi_channel)
+{
+	return 0xf << ((rtsi_channel % 4) * 4);
+};
+
+// inverse to RTSI_Trig_Output_Bits()
+static inline unsigned RTSI_Trig_Output_Source(unsigned rtsi_channel,
+	unsigned bits)
+{
+	return (bits >> ((rtsi_channel % 4) * 4)) & 0xf;
+};
+
+#define	RTSI_Board_Register		81
+#define Write_Strobe_0_Register		82
+#define Write_Strobe_1_Register		83
+#define Write_Strobe_2_Register		84
+#define Write_Strobe_3_Register		85
+
+#define AO_Output_Control_Register	86
+#define AO_External_Gate_Enable			_bit15
+#define AO_External_Gate_Select(x)		(((x)&0x1f)<<10)
+#define AO_Number_Of_Channels(x)		(((x)&0xf)<<6)
+#define AO_UPDATE2_Output_Select(x)		(((x)&0x3)<<4)
+#define AO_External_Gate_Polarity		_bit3
+#define AO_UPDATE2_Output_Toggle		_bit2
+enum ao_update_output_selection {
+	AO_Update_Output_High_Z = 0,
+	AO_Update_Output_Ground = 1,
+	AO_Update_Output_Enable_Low = 2,
+	AO_Update_Output_Enable_High = 3
+};
+static unsigned AO_UPDATE_Output_Select(enum ao_update_output_selection
+	selection)
+{
+	return selection & 0x3;
+}
+
+#define AI_Mode_3_Register		87
+#define AI_Trigger_Length			_bit15
+#define AI_Delay_START				_bit14
+#define AI_Software_Gate			_bit13
+#define AI_SI_Special_Trigger_Delay		_bit12
+#define AI_SI2_Source_Select			_bit11
+#define AI_Delayed_START2			_bit10
+#define AI_Delayed_START1			_bit9
+#define AI_External_Gate_Mode			_bit8
+#define AI_FIFO_Mode_HF_to_E			(3<<6)
+#define AI_FIFO_Mode_F				(2<<6)
+#define AI_FIFO_Mode_HF				(1<<6)
+#define AI_FIFO_Mode_NE				(0<<6)
+#define AI_External_Gate_Polarity		_bit5
+#define AI_External_Gate_Select(a)		((a) & 0x1f)
+
+#define G_Autoincrement_Register(a)	(68+(a))
+#define G_Command_Register(a)		(6+(a))
+#define G_HW_Save_Register(a)		(8+(a)*2)
+#define G_HW_Save_Register_High(a)	(8+(a)*2)
+#define G_HW_Save_Register_Low(a)	(9+(a)*2)
+#define G_Input_Select_Register(a)	(36+(a))
+#define G_Load_A_Register(a)		(28+(a)*4)
+#define G_Load_A_Register_High(a)	(28+(a)*4)
+#define G_Load_A_Register_Low(a)	(29+(a)*4)
+#define G_Load_B_Register(a)		(30+(a)*4)
+#define G_Load_B_Register_High(a)	(30+(a)*4)
+#define G_Load_B_Register_Low(a)	(31+(a)*4)
+#define G_Mode_Register(a)		(26+(a))
+#define G_Save_Register(a)		(12+(a)*2)
+#define G_Save_Register_High(a)		(12+(a)*2)
+#define G_Save_Register_Low(a)		(13+(a)*2)
+#define G_Status_Register		4
+#define Analog_Trigger_Etc_Register	61
+
+/* command register */
+#define G_Disarm_Copy			_bit15	/* strobe */
+#define G_Save_Trace_Copy		_bit14
+#define G_Arm_Copy			_bit13	/* strobe */
+#define G_Bank_Switch_Start		_bit10	/* strobe */
+#define G_Little_Big_Endian		_bit9
+#define G_Synchronized_Gate		_bit8
+#define G_Write_Switch			_bit7
+#define G_Up_Down(a)			(((a)&0x03)<<5)
+#define G_Disarm			_bit4	/* strobe */
+#define G_Analog_Trigger_Reset		_bit3	/* strobe */
+#define G_Save_Trace			_bit1
+#define G_Arm				_bit0	/* strobe */
+
+/*channel agnostic names for the command register #defines */
+#define G_Bank_Switch_Enable		_bit12
+#define G_Bank_Switch_Mode		_bit11
+#define G_Load				_bit2	/* strobe */
+
+/* input select register */
+#define G_Gate_Select(a)		(((a)&0x1f)<<7)
+#define G_Source_Select(a)		(((a)&0x1f)<<2)
+#define G_Write_Acknowledges_Irq	_bit1
+#define G_Read_Acknowledges_Irq		_bit0
+
+/* same input select register, but with channel agnostic names */
+#define G_Source_Polarity		_bit15
+#define G_Output_Polarity		_bit14
+#define G_OR_Gate			_bit13
+#define G_Gate_Select_Load_Source	_bit12
+
+/* mode register */
+#define G_Loading_On_TC			_bit12
+#define G_Output_Mode(a)		(((a)&0x03)<<8)
+#define G_Trigger_Mode_For_Edge_Gate(a)	(((a)&0x03)<<3)
+#define G_Gating_Mode(a)		(((a)&0x03)<<0)
+
+/* same input mode register, but with channel agnostic names */
+#define G_Load_Source_Select		_bit7
+#define G_Reload_Source_Switching	_bit15
+#define G_Loading_On_Gate		_bit14
+#define G_Gate_Polarity 		_bit13
+
+#define G_Counting_Once(a)		(((a)&0x03)<<10)
+#define G_Stop_Mode(a)			(((a)&0x03)<<5)
+#define G_Gate_On_Both_Edges		_bit2
+
+/* G_Status_Register */
+#define G1_Gate_Error_St		_bit15
+#define G0_Gate_Error_St		_bit14
+#define G1_TC_Error_St			_bit13
+#define G0_TC_Error_St			_bit12
+#define G1_No_Load_Between_Gates_St	_bit11
+#define G0_No_Load_Between_Gates_St	_bit10
+#define G1_Armed_St			_bit9
+#define G0_Armed_St			_bit8
+#define G1_Stale_Data_St		_bit7
+#define G0_Stale_Data_St		_bit6
+#define G1_Next_Load_Source_St		_bit5
+#define G0_Next_Load_Source_St		_bit4
+#define G1_Counting_St			_bit3
+#define G0_Counting_St			_bit2
+#define G1_Save_St			_bit1
+#define G0_Save_St			_bit0
+
+/* general purpose counter timer */
+#define G_Autoincrement(a)              ((a)<<0)
+
+/*Analog_Trigger_Etc_Register*/
+#define Analog_Trigger_Mode(x) ((x) & 0x7)
+#define Analog_Trigger_Enable _bit3
+#define Analog_Trigger_Drive _bit4
+#define GPFO_1_Output_Select		_bit7
+#define GPFO_0_Output_Select(a)		((a)<<11)
+#define GPFO_0_Output_Enable		_bit14
+#define GPFO_1_Output_Enable		_bit15
+
+/* Additional windowed registers unique to E series */
+
+/* 16 bit registers shadowed from DAQ-STC */
+#define Window_Address			0x00
+#define Window_Data			0x02
+
+#define Configuration_Memory_Clear	82
+#define ADC_FIFO_Clear			83
+#define DAC_FIFO_Clear			84
+
+/* i/o port offsets */
+
+/* 8 bit registers */
+#define XXX_Status			0x01
+enum XXX_Status_Bits {
+	PROMOUT = 0x1,
+	AI_FIFO_LOWER_NOT_EMPTY = 0x8,
+};
+#define Serial_Command			0x0d
+#define Misc_Command			0x0f
+#define Port_A				0x19
+#define Port_B				0x1b
+#define Port_C				0x1d
+#define Configuration			0x1f
+#define Strobes				0x01
+#define Channel_A_Mode			0x03
+#define Channel_B_Mode			0x05
+#define Channel_C_Mode			0x07
+#define AI_AO_Select			0x09
+enum AI_AO_Select_Bits {
+	AI_DMA_Select_Shift = 0,
+	AI_DMA_Select_Mask = 0xf,
+	AO_DMA_Select_Shift = 4,
+	AO_DMA_Select_Mask = 0xf << AO_DMA_Select_Shift
+};
+#define G0_G1_Select			0x0b
+static inline unsigned ni_stc_dma_channel_select_bitfield(unsigned channel)
+{
+	if (channel < 4)
+		return 1 << channel;
+	if (channel == 4)
+		return 0x3;
+	if (channel == 5)
+		return 0x5;
+	BUG();
+	return 0;
+}
+static inline unsigned GPCT_DMA_Select_Bits(unsigned gpct_index,
+	unsigned mite_channel)
+{
+	BUG_ON(gpct_index > 1);
+	return ni_stc_dma_channel_select_bitfield(mite_channel) << (4 *
+		gpct_index);
+}
+static inline unsigned GPCT_DMA_Select_Mask(unsigned gpct_index)
+{
+	BUG_ON(gpct_index > 1);
+	return 0xf << (4 * gpct_index);
+}
+
+/* 16 bit registers */
+
+#define Configuration_Memory_Low	0x10
+enum Configuration_Memory_Low_Bits {
+	AI_DITHER = 0x200,
+	AI_LAST_CHANNEL = 0x8000,
+};
+#define Configuration_Memory_High	0x12
+enum Configuration_Memory_High_Bits {
+	AI_AC_COUPLE = 0x800,
+	AI_DIFFERENTIAL = 0x1000,
+	AI_COMMON = 0x2000,
+	AI_GROUND = 0x3000,
+};
+static inline unsigned int AI_CONFIG_CHANNEL(unsigned int channel)
+{
+	return (channel & 0x3f);
+}
+
+#define ADC_FIFO_Data_Register		0x1c
+
+#define AO_Configuration		0x16
+#define AO_Bipolar		_bit0
+#define AO_Deglitch		_bit1
+#define AO_Ext_Ref		_bit2
+#define AO_Ground_Ref		_bit3
+#define AO_Channel(x)		((x) << 8)
+
+#define DAC_FIFO_Data			0x1e
+#define DAC0_Direct_Data		0x18
+#define DAC1_Direct_Data		0x1a
+
+/* 611x registers (these boards differ from the e-series) */
+
+#define Magic_611x			0x19	/* w8 (new) */
+#define Calibration_Channel_Select_611x	0x1a	/* w16 (new) */
+#define ADC_FIFO_Data_611x		0x1c	/* r32 (incompatible) */
+#define AI_FIFO_Offset_Load_611x	0x05	/* r8 (new) */
+#define DAC_FIFO_Data_611x		0x14	/* w32 (incompatible) */
+#define Cal_Gain_Select_611x		0x05	/* w8 (new) */
+
+#define AO_Window_Address_611x		0x18
+#define AO_Window_Data_611x		0x1e
+
+/* 6143 registers */
+#define Magic_6143			0x19	/* w8 */
+#define G0G1_DMA_Select_6143		0x0B	/* w8 */
+#define PipelineDelay_6143		0x1f	/* w8 */
+#define EOC_Set_6143			0x1D	/* w8 */
+#define AIDMA_Select_6143		0x09	/* w8 */
+#define AIFIFO_Data_6143		0x8C	/* w32 */
+#define AIFIFO_Flag_6143		0x84	/* w32 */
+#define AIFIFO_Control_6143		0x88	/* w32 */
+#define AIFIFO_Status_6143		0x88	/* w32 */
+#define AIFIFO_DMAThreshold_6143	0x90	/* w32 */
+#define AIFIFO_Words_Available_6143	0x94	/* w32 */
+
+#define Calibration_Channel_6143	0x42	/* w16 */
+#define Calibration_LowTime_6143	0x20	/* w16 */
+#define Calibration_HighTime_6143	0x22	/* w16 */
+#define Relay_Counter_Load_Val__6143	0x4C	/* w32 */
+#define Signature_6143			0x50	/* w32 */
+#define Release_Date_6143		0x54	/* w32 */
+#define Release_Oldest_Date_6143	0x58	/* w32 */
+
+#define Calibration_Channel_6143_RelayOn	0x8000	/* Calibration relay switch On */
+#define Calibration_Channel_6143_RelayOff	0x4000	/* Calibration relay switch Off */
+#define Calibration_Channel_Gnd_Gnd	0x00	/* Offset Calibration */
+#define Calibration_Channel_2v5_Gnd	0x02	/* 2.5V Reference */
+#define Calibration_Channel_Pwm_Gnd	0x05	/* +/- 5V Self Cal */
+#define Calibration_Channel_2v5_Pwm	0x0a	/* PWM Calibration */
+#define Calibration_Channel_Pwm_Pwm	0x0d	/* CMRR */
+#define Calibration_Channel_Gnd_Pwm	0x0e	/* PWM Calibration */
+
+/* 671x, 611x registers */
+
+/* 671xi, 611x windowed ao registers */
+enum windowed_regs_67xx_61xx {
+	AO_Immediate_671x = 0x11,	/* W 16 */
+	AO_Timed_611x = 0x10,	/* W 16 */
+	AO_FIFO_Offset_Load_611x = 0x13,	/* W32 */
+	AO_Later_Single_Point_Updates = 0x14,	/* W 16 */
+	AO_Waveform_Generation_611x = 0x15,	/* W 16 */
+	AO_Misc_611x = 0x16,	/* W 16 */
+	AO_Calibration_Channel_Select_67xx = 0x17,	/* W 16 */
+	AO_Configuration_2_67xx = 0x18,	/* W 16 */
+	CAL_ADC_Command_67xx = 0x19,	/* W 8 */
+	CAL_ADC_Status_67xx = 0x1a,	/* R 8 */
+	CAL_ADC_Data_67xx = 0x1b,	/* R 16 */
+	CAL_ADC_Config_Data_High_Word_67xx = 0x1c,	/* RW 16 */
+	CAL_ADC_Config_Data_Low_Word_67xx = 0x1d,	/* RW 16 */
+};
+static inline unsigned int DACx_Direct_Data_671x(int channel)
+{
+	return channel;
+}
+enum AO_Misc_611x_Bits {
+	CLEAR_WG = 1,
+};
+enum cs5529_configuration_bits {
+	CSCFG_CAL_CONTROL_MASK = 0x7,
+	CSCFG_SELF_CAL_OFFSET = 0x1,
+	CSCFG_SELF_CAL_GAIN = 0x2,
+	CSCFG_SELF_CAL_OFFSET_GAIN = 0x3,
+	CSCFG_SYSTEM_CAL_OFFSET = 0x5,
+	CSCFG_SYSTEM_CAL_GAIN = 0x6,
+	CSCFG_DONE = 1 << 3,
+	CSCFG_POWER_SAVE_SELECT = 1 << 4,
+	CSCFG_PORT_MODE = 1 << 5,
+	CSCFG_RESET_VALID = 1 << 6,
+	CSCFG_RESET = 1 << 7,
+	CSCFG_UNIPOLAR = 1 << 12,
+	CSCFG_WORD_RATE_2180_CYCLES = 0x0 << 13,
+	CSCFG_WORD_RATE_1092_CYCLES = 0x1 << 13,
+	CSCFG_WORD_RATE_532_CYCLES = 0x2 << 13,
+	CSCFG_WORD_RATE_388_CYCLES = 0x3 << 13,
+	CSCFG_WORD_RATE_324_CYCLES = 0x4 << 13,
+	CSCFG_WORD_RATE_17444_CYCLES = 0x5 << 13,
+	CSCFG_WORD_RATE_8724_CYCLES = 0x6 << 13,
+	CSCFG_WORD_RATE_4364_CYCLES = 0x7 << 13,
+	CSCFG_WORD_RATE_MASK = 0x7 << 13,
+	CSCFG_LOW_POWER = 1 << 16,
+};
+static inline unsigned int CS5529_CONFIG_DOUT(int output)
+{
+	return 1 << (18 + output);
+}
+static inline unsigned int CS5529_CONFIG_AOUT(int output)
+{
+	return 1 << (22 + output);
+}
+enum cs5529_command_bits {
+	CSCMD_POWER_SAVE = 0x1,
+	CSCMD_REGISTER_SELECT_MASK = 0xe,
+	CSCMD_OFFSET_REGISTER = 0x0,
+	CSCMD_GAIN_REGISTER = 0x2,
+	CSCMD_CONFIG_REGISTER = 0x4,
+	CSCMD_READ = 0x10,
+	CSCMD_CONTINUOUS_CONVERSIONS = 0x20,
+	CSCMD_SINGLE_CONVERSION = 0x40,
+	CSCMD_COMMAND = 0x80,
+};
+enum cs5529_status_bits {
+	CSS_ADC_BUSY = 0x1,
+	CSS_OSC_DETECT = 0x2,	/* indicates adc error */
+	CSS_OVERRANGE = 0x4,
+};
+#define SerDacLd(x)			(0x08<<(x))
+
+/*
+	This is stuff unique to the NI E series drivers,
+	but I thought I'd put it here anyway.
+*/
+
+enum { ai_gain_16 =
+		0, ai_gain_8, ai_gain_14, ai_gain_4, ai_gain_611x, ai_gain_622x,
+		ai_gain_628x, ai_gain_6143 };
+enum caldac_enum { caldac_none = 0, mb88341, dac8800, dac8043, ad8522,
+	ad8804, ad8842, ad8804_debug
+};
+enum ni_reg_type {
+	ni_reg_normal = 0x0,
+	ni_reg_611x = 0x1,
+	ni_reg_6711 = 0x2,
+	ni_reg_6713 = 0x4,
+	ni_reg_67xx_mask = 0x6,
+	ni_reg_6xxx_mask = 0x7,
+	ni_reg_622x = 0x8,
+	ni_reg_625x = 0x10,
+	ni_reg_628x = 0x18,
+	ni_reg_m_series_mask = 0x18,
+	ni_reg_6143 = 0x20
+};
+
+static const struct comedi_lrange range_ni_E_ao_ext;
+
+enum m_series_register_offsets {
+	M_Offset_CDIO_DMA_Select = 0x7,	// write
+	M_Offset_SCXI_Status = 0x7,	// read
+	M_Offset_AI_AO_Select = 0x9,	// write, same offset as e-series
+	M_Offset_SCXI_Serial_Data_In = 0x9,	// read
+	M_Offset_G0_G1_Select = 0xb,	// write, same offset as e-series
+	M_Offset_Misc_Command = 0xf,
+	M_Offset_SCXI_Serial_Data_Out = 0x11,
+	M_Offset_SCXI_Control = 0x13,
+	M_Offset_SCXI_Output_Enable = 0x15,
+	M_Offset_AI_FIFO_Data = 0x1c,
+	M_Offset_Static_Digital_Output = 0x24,	// write
+	M_Offset_Static_Digital_Input = 0x24,	// read
+	M_Offset_DIO_Direction = 0x28,
+	M_Offset_Cal_PWM = 0x40,
+	M_Offset_AI_Config_FIFO_Data = 0x5e,
+	M_Offset_Interrupt_C_Enable = 0x88,	// write
+	M_Offset_Interrupt_C_Status = 0x88,	// read
+	M_Offset_Analog_Trigger_Control = 0x8c,
+	M_Offset_AO_Serial_Interrupt_Enable = 0xa0,
+	M_Offset_AO_Serial_Interrupt_Ack = 0xa1,	// write
+	M_Offset_AO_Serial_Interrupt_Status = 0xa1,	// read
+	M_Offset_AO_Calibration = 0xa3,
+	M_Offset_AO_FIFO_Data = 0xa4,
+	M_Offset_PFI_Filter = 0xb0,
+	M_Offset_RTSI_Filter = 0xb4,
+	M_Offset_SCXI_Legacy_Compatibility = 0xbc,
+	M_Offset_Interrupt_A_Ack = 0x104,	// write
+	M_Offset_AI_Status_1 = 0x104,	// read
+	M_Offset_Interrupt_B_Ack = 0x106,	// write
+	M_Offset_AO_Status_1 = 0x106,	// read
+	M_Offset_AI_Command_2 = 0x108,	// write
+	M_Offset_G01_Status = 0x108,	// read
+	M_Offset_AO_Command_2 = 0x10a,
+	M_Offset_AO_Status_2 = 0x10c,	// read
+	M_Offset_G0_Command = 0x10c,	// write
+	M_Offset_G1_Command = 0x10e,	// write
+	M_Offset_G0_HW_Save = 0x110,
+	M_Offset_G0_HW_Save_High = 0x110,
+	M_Offset_AI_Command_1 = 0x110,
+	M_Offset_G0_HW_Save_Low = 0x112,
+	M_Offset_AO_Command_1 = 0x112,
+	M_Offset_G1_HW_Save = 0x114,
+	M_Offset_G1_HW_Save_High = 0x114,
+	M_Offset_G1_HW_Save_Low = 0x116,
+	M_Offset_AI_Mode_1 = 0x118,
+	M_Offset_G0_Save = 0x118,
+	M_Offset_G0_Save_High = 0x118,
+	M_Offset_AI_Mode_2 = 0x11a,
+	M_Offset_G0_Save_Low = 0x11a,
+	M_Offset_AI_SI_Load_A = 0x11c,
+	M_Offset_G1_Save = 0x11c,
+	M_Offset_G1_Save_High = 0x11c,
+	M_Offset_G1_Save_Low = 0x11e,
+	M_Offset_AI_SI_Load_B = 0x120,	// write
+	M_Offset_AO_UI_Save = 0x120,	// read
+	M_Offset_AI_SC_Load_A = 0x124,	// write
+	M_Offset_AO_BC_Save = 0x124,	// read
+	M_Offset_AI_SC_Load_B = 0x128,	// write
+	M_Offset_AO_UC_Save = 0x128,	//read
+	M_Offset_AI_SI2_Load_A = 0x12c,
+	M_Offset_AI_SI2_Load_B = 0x130,
+	M_Offset_G0_Mode = 0x134,
+	M_Offset_G1_Mode = 0x136,	// write
+	M_Offset_Joint_Status_1 = 0x136,	// read
+	M_Offset_G0_Load_A = 0x138,
+	M_Offset_Joint_Status_2 = 0x13a,
+	M_Offset_G0_Load_B = 0x13c,
+	M_Offset_G1_Load_A = 0x140,
+	M_Offset_G1_Load_B = 0x144,
+	M_Offset_G0_Input_Select = 0x148,
+	M_Offset_G1_Input_Select = 0x14a,
+	M_Offset_AO_Mode_1 = 0x14c,
+	M_Offset_AO_Mode_2 = 0x14e,
+	M_Offset_AO_UI_Load_A = 0x150,
+	M_Offset_AO_UI_Load_B = 0x154,
+	M_Offset_AO_BC_Load_A = 0x158,
+	M_Offset_AO_BC_Load_B = 0x15c,
+	M_Offset_AO_UC_Load_A = 0x160,
+	M_Offset_AO_UC_Load_B = 0x164,
+	M_Offset_Clock_and_FOUT = 0x170,
+	M_Offset_IO_Bidirection_Pin = 0x172,
+	M_Offset_RTSI_Trig_Direction = 0x174,
+	M_Offset_Interrupt_Control = 0x176,
+	M_Offset_AI_Output_Control = 0x178,
+	M_Offset_Analog_Trigger_Etc = 0x17a,
+	M_Offset_AI_START_STOP_Select = 0x17c,
+	M_Offset_AI_Trigger_Select = 0x17e,
+	M_Offset_AI_SI_Save = 0x180,	// read
+	M_Offset_AI_DIV_Load_A = 0x180,	// write
+	M_Offset_AI_SC_Save = 0x184,	// read
+	M_Offset_AO_Start_Select = 0x184,	// write
+	M_Offset_AO_Trigger_Select = 0x186,
+	M_Offset_AO_Mode_3 = 0x18c,
+	M_Offset_G0_Autoincrement = 0x188,
+	M_Offset_G1_Autoincrement = 0x18a,
+	M_Offset_Joint_Reset = 0x190,
+	M_Offset_Interrupt_A_Enable = 0x192,
+	M_Offset_Interrupt_B_Enable = 0x196,
+	M_Offset_AI_Personal = 0x19a,
+	M_Offset_AO_Personal = 0x19c,
+	M_Offset_RTSI_Trig_A_Output = 0x19e,
+	M_Offset_RTSI_Trig_B_Output = 0x1a0,
+	M_Offset_RTSI_Shared_MUX = 0x1a2,
+	M_Offset_AO_Output_Control = 0x1ac,
+	M_Offset_AI_Mode_3 = 0x1ae,
+	M_Offset_Configuration_Memory_Clear = 0x1a4,
+	M_Offset_AI_FIFO_Clear = 0x1a6,
+	M_Offset_AO_FIFO_Clear = 0x1a8,
+	M_Offset_G0_Counting_Mode = 0x1b0,
+	M_Offset_G1_Counting_Mode = 0x1b2,
+	M_Offset_G0_Second_Gate = 0x1b4,
+	M_Offset_G1_Second_Gate = 0x1b6,
+	M_Offset_G0_DMA_Config = 0x1b8,	// write
+	M_Offset_G0_DMA_Status = 0x1b8,	// read
+	M_Offset_G1_DMA_Config = 0x1ba,	// write
+	M_Offset_G1_DMA_Status = 0x1ba,	// read
+	M_Offset_G0_MSeries_ABZ = 0x1c0,
+	M_Offset_G1_MSeries_ABZ = 0x1c2,
+	M_Offset_Clock_and_Fout2 = 0x1c4,
+	M_Offset_PLL_Control = 0x1c6,
+	M_Offset_PLL_Status = 0x1c8,
+	M_Offset_PFI_Output_Select_1 = 0x1d0,
+	M_Offset_PFI_Output_Select_2 = 0x1d2,
+	M_Offset_PFI_Output_Select_3 = 0x1d4,
+	M_Offset_PFI_Output_Select_4 = 0x1d6,
+	M_Offset_PFI_Output_Select_5 = 0x1d8,
+	M_Offset_PFI_Output_Select_6 = 0x1da,
+	M_Offset_PFI_DI = 0x1dc,
+	M_Offset_PFI_DO = 0x1de,
+	M_Offset_AI_Config_FIFO_Bypass = 0x218,
+	M_Offset_SCXI_DIO_Enable = 0x21c,
+	M_Offset_CDI_FIFO_Data = 0x220,	// read
+	M_Offset_CDO_FIFO_Data = 0x220,	// write
+	M_Offset_CDIO_Status = 0x224,	// read
+	M_Offset_CDIO_Command = 0x224,	// write
+	M_Offset_CDI_Mode = 0x228,
+	M_Offset_CDO_Mode = 0x22c,
+	M_Offset_CDI_Mask_Enable = 0x230,
+	M_Offset_CDO_Mask_Enable = 0x234,
+};
+static inline int M_Offset_AO_Waveform_Order(int channel)
+{
+	return 0xc2 + 0x4 * channel;
+};
+static inline int M_Offset_AO_Config_Bank(int channel)
+{
+	return 0xc3 + 0x4 * channel;
+};
+static inline int M_Offset_DAC_Direct_Data(int channel)
+{
+	return 0xc0 + 0x4 * channel;
+}
+static inline int M_Offset_Gen_PWM(int channel)
+{
+	return 0x44 + 0x2 * channel;
+}
+static inline int M_Offset_Static_AI_Control(int i)
+{
+	int offset[] = {
+		0x64,
+		0x261,
+		0x262,
+		0x263,
+	};
+	if (((unsigned)i) >= sizeof(offset) / sizeof(offset[0])) {
+		rt_printk("%s: invalid channel=%i\n", __FUNCTION__, i);
+		return offset[0];
+	}
+	return offset[i];
+};
+static inline int M_Offset_AO_Reference_Attenuation(int channel)
+{
+	int offset[] = {
+		0x264,
+		0x265,
+		0x266,
+		0x267
+	};
+	if (((unsigned)channel) >= sizeof(offset) / sizeof(offset[0])) {
+		rt_printk("%s: invalid channel=%i\n", __FUNCTION__, channel);
+		return offset[0];
+	}
+	return offset[channel];
+};
+static inline unsigned M_Offset_PFI_Output_Select(unsigned n)
+{
+	if (n < 1 || n > NUM_PFI_OUTPUT_SELECT_REGS) {
+		rt_printk("%s: invalid pfi output select register=%i\n",
+			__FUNCTION__, n);
+		return M_Offset_PFI_Output_Select_1;
+	}
+	return M_Offset_PFI_Output_Select_1 + (n - 1) * 2;
+}
+
+enum MSeries_AI_Config_FIFO_Data_Bits {
+	MSeries_AI_Config_Channel_Type_Mask = 0x7 << 6,
+	MSeries_AI_Config_Channel_Type_Calibration_Bits = 0x0,
+	MSeries_AI_Config_Channel_Type_Differential_Bits = 0x1 << 6,
+	MSeries_AI_Config_Channel_Type_Common_Ref_Bits = 0x2 << 6,
+	MSeries_AI_Config_Channel_Type_Ground_Ref_Bits = 0x3 << 6,
+	MSeries_AI_Config_Channel_Type_Aux_Bits = 0x5 << 6,
+	MSeries_AI_Config_Channel_Type_Ghost_Bits = 0x7 << 6,
+	MSeries_AI_Config_Polarity_Bit = 0x1000,	// 0 for 2's complement encoding
+	MSeries_AI_Config_Dither_Bit = 0x2000,
+	MSeries_AI_Config_Last_Channel_Bit = 0x4000,
+};
+static inline unsigned MSeries_AI_Config_Channel_Bits(unsigned channel)
+{
+	return channel & 0xf;
+}
+static inline unsigned MSeries_AI_Config_Bank_Bits(enum ni_reg_type reg_type,
+	unsigned channel)
+{
+	unsigned bits = channel & 0x30;
+	if (reg_type == ni_reg_622x) {
+		if (channel & 0x40)
+			bits |= 0x400;
+	}
+	return bits;
+}
+static inline unsigned MSeries_AI_Config_Gain_Bits(unsigned range)
+{
+	return (range & 0x7) << 9;
+}
+
+enum MSeries_Clock_and_Fout2_Bits {
+	MSeries_PLL_In_Source_Select_RTSI0_Bits = 0xb,
+	MSeries_PLL_In_Source_Select_Star_Trigger_Bits = 0x14,
+	MSeries_PLL_In_Source_Select_RTSI7_Bits = 0x1b,
+	MSeries_PLL_In_Source_Select_PXI_Clock10 = 0x1d,
+	MSeries_PLL_In_Source_Select_Mask = 0x1f,
+	MSeries_Timebase1_Select_Bit = 0x20,	// use PLL for timebase 1
+	MSeries_Timebase3_Select_Bit = 0x40,	// use PLL for timebase 3
+	/* use 10MHz instead of 20MHz for RTSI clock frequency.  Appears
+	   to have no effect, at least on pxi-6281, which always uses
+	   20MHz rtsi clock frequency */
+	MSeries_RTSI_10MHz_Bit = 0x80
+};
+static inline unsigned MSeries_PLL_In_Source_Select_RTSI_Bits(unsigned
+	RTSI_channel)
+{
+	if (RTSI_channel > 7) {
+		rt_printk("%s: bug, invalid RTSI_channel=%i\n", __FUNCTION__,
+			RTSI_channel);
+		return 0;
+	}
+	if (RTSI_channel == 7)
+		return MSeries_PLL_In_Source_Select_RTSI7_Bits;
+	else
+		return MSeries_PLL_In_Source_Select_RTSI0_Bits + RTSI_channel;
+}
+
+enum MSeries_PLL_Control_Bits {
+	MSeries_PLL_Enable_Bit = 0x1000,
+	MSeries_PLL_VCO_Mode_200_325MHz_Bits = 0x0,
+	MSeries_PLL_VCO_Mode_175_225MHz_Bits = 0x2000,
+	MSeries_PLL_VCO_Mode_100_225MHz_Bits = 0x4000,
+	MSeries_PLL_VCO_Mode_75_150MHz_Bits = 0x6000,
+};
+static inline unsigned MSeries_PLL_Divisor_Bits(unsigned divisor)
+{
+	static const unsigned max_divisor = 0x10;
+	if (divisor < 1 || divisor > max_divisor) {
+		rt_printk("%s: bug, invalid divisor=%i\n", __FUNCTION__,
+			divisor);
+		return 0;
+	}
+	return (divisor & 0xf) << 8;
+}
+static inline unsigned MSeries_PLL_Multiplier_Bits(unsigned multiplier)
+{
+	static const unsigned max_multiplier = 0x100;
+	if (multiplier < 1 || multiplier > max_multiplier) {
+		rt_printk("%s: bug, invalid multiplier=%i\n", __FUNCTION__,
+			multiplier);
+		return 0;
+	}
+	return multiplier & 0xff;
+}
+
+enum MSeries_PLL_Status {
+	MSeries_PLL_Locked_Bit = 0x1
+};
+
+enum MSeries_AI_Config_FIFO_Bypass_Bits {
+	MSeries_AI_Bypass_Channel_Mask = 0x7,
+	MSeries_AI_Bypass_Bank_Mask = 0x78,
+	MSeries_AI_Bypass_Cal_Sel_Pos_Mask = 0x380,
+	MSeries_AI_Bypass_Cal_Sel_Neg_Mask = 0x1c00,
+	MSeries_AI_Bypass_Mode_Mux_Mask = 0x6000,
+	MSeries_AO_Bypass_AO_Cal_Sel_Mask = 0x38000,
+	MSeries_AI_Bypass_Gain_Mask = 0x1c0000,
+	MSeries_AI_Bypass_Dither_Bit = 0x200000,
+	MSeries_AI_Bypass_Polarity_Bit = 0x400000,	// 0 for 2's complement encoding
+	MSeries_AI_Bypass_Config_FIFO_Bit = 0x80000000
+};
+static inline unsigned MSeries_AI_Bypass_Cal_Sel_Pos_Bits(int
+	calibration_source)
+{
+	return (calibration_source << 7) & MSeries_AI_Bypass_Cal_Sel_Pos_Mask;
+}
+static inline unsigned MSeries_AI_Bypass_Cal_Sel_Neg_Bits(int
+	calibration_source)
+{
+	return (calibration_source << 10) & MSeries_AI_Bypass_Cal_Sel_Pos_Mask;
+}
+static inline unsigned MSeries_AI_Bypass_Gain_Bits(int gain)
+{
+	return (gain << 18) & MSeries_AI_Bypass_Gain_Mask;
+}
+
+enum MSeries_AO_Config_Bank_Bits {
+	MSeries_AO_DAC_Offset_Select_Mask = 0x7,
+	MSeries_AO_DAC_Offset_0V_Bits = 0x0,
+	MSeries_AO_DAC_Offset_5V_Bits = 0x1,
+	MSeries_AO_DAC_Reference_Mask = 0x38,
+	MSeries_AO_DAC_Reference_10V_Internal_Bits = 0x0,
+	MSeries_AO_DAC_Reference_5V_Internal_Bits = 0x8,
+	MSeries_AO_Update_Timed_Bit = 0x40,
+	MSeries_AO_Bipolar_Bit = 0x80	// turns on 2's complement encoding
+};
+
+enum MSeries_AO_Reference_Attenuation_Bits {
+	MSeries_Attenuate_x5_Bit = 0x1
+};
+
+static inline unsigned MSeries_Cal_PWM_High_Time_Bits(unsigned count)
+{
+	return (count << 16) & 0xffff0000;
+}
+
+static inline unsigned MSeries_Cal_PWM_Low_Time_Bits(unsigned count)
+{
+	return count & 0xffff;
+}
+
+static inline unsigned MSeries_PFI_Output_Select_Mask(unsigned channel)
+{
+	return 0x1f << (channel % 3) * 5;
+};
+static inline unsigned MSeries_PFI_Output_Select_Bits(unsigned channel,
+	unsigned source)
+{
+	return (source & 0x1f) << ((channel % 3) * 5);
+};
+
+// inverse to MSeries_PFI_Output_Select_Bits
+static inline unsigned MSeries_PFI_Output_Select_Source(unsigned channel,
+	unsigned bits)
+{
+	return (bits >> ((channel % 3) * 5)) & 0x1f;
+};
+
+enum MSeries_Gi_DMA_Config_Bits {
+	Gi_DMA_BankSW_Error_Bit = 0x10,
+	Gi_DMA_Reset_Bit = 0x8,
+	Gi_DMA_Int_Enable_Bit = 0x4,
+	Gi_DMA_Write_Bit = 0x2,
+	Gi_DMA_Enable_Bit = 0x1,
+};
+
+static inline unsigned MSeries_PFI_Filter_Select_Mask(unsigned channel)
+{
+	return 0x3 << (channel * 2);
+}
+static inline unsigned MSeries_PFI_Filter_Select_Bits(unsigned channel,
+	unsigned filter)
+{
+	return (filter << (channel *
+			2)) & MSeries_PFI_Filter_Select_Mask(channel);
+}
+
+enum CDIO_DMA_Select_Bits {
+	CDI_DMA_Select_Shift = 0,
+	CDI_DMA_Select_Mask = 0xf,
+	CDO_DMA_Select_Shift = 4,
+	CDO_DMA_Select_Mask = 0xf << CDO_DMA_Select_Shift
+};
+
+enum CDIO_Status_Bits {
+	CDO_FIFO_Empty_Bit = 0x1,
+	CDO_FIFO_Full_Bit = 0x2,
+	CDO_FIFO_Request_Bit = 0x4,
+	CDO_Overrun_Bit = 0x8,
+	CDO_Underflow_Bit = 0x10,
+	CDI_FIFO_Empty_Bit = 0x10000,
+	CDI_FIFO_Full_Bit = 0x20000,
+	CDI_FIFO_Request_Bit = 0x40000,
+	CDI_Overrun_Bit = 0x80000,
+	CDI_Overflow_Bit = 0x100000
+};
+
+enum CDIO_Command_Bits {
+	CDO_Disarm_Bit = 0x1,
+	CDO_Arm_Bit = 0x2,
+	CDI_Disarm_Bit = 0x4,
+	CDI_Arm_Bit = 0x8,
+	CDO_Reset_Bit = 0x10,
+	CDI_Reset_Bit = 0x20,
+	CDO_Error_Interrupt_Enable_Set_Bit = 0x40,
+	CDO_Error_Interrupt_Enable_Clear_Bit = 0x80,
+	CDI_Error_Interrupt_Enable_Set_Bit = 0x100,
+	CDI_Error_Interrupt_Enable_Clear_Bit = 0x200,
+	CDO_FIFO_Request_Interrupt_Enable_Set_Bit = 0x400,
+	CDO_FIFO_Request_Interrupt_Enable_Clear_Bit = 0x800,
+	CDI_FIFO_Request_Interrupt_Enable_Set_Bit = 0x1000,
+	CDI_FIFO_Request_Interrupt_Enable_Clear_Bit = 0x2000,
+	CDO_Error_Interrupt_Confirm_Bit = 0x4000,
+	CDI_Error_Interrupt_Confirm_Bit = 0x8000,
+	CDO_Empty_FIFO_Interrupt_Enable_Set_Bit = 0x10000,
+	CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit = 0x20000,
+	CDO_SW_Update_Bit = 0x80000,
+	CDI_SW_Update_Bit = 0x100000
+};
+
+enum CDI_Mode_Bits {
+	CDI_Sample_Source_Select_Mask = 0x3f,
+	CDI_Halt_On_Error_Bit = 0x200,
+	CDI_Polarity_Bit = 0x400,	// sample clock on falling edge
+	CDI_FIFO_Mode_Bit = 0x800,	// set for half full mode, clear for not empty mode
+	CDI_Data_Lane_Mask = 0x3000,	// data lanes specify which dio channels map to byte or word accesses to the dio fifos
+	CDI_Data_Lane_0_15_Bits = 0x0,
+	CDI_Data_Lane_16_31_Bits = 0x1000,
+	CDI_Data_Lane_0_7_Bits = 0x0,
+	CDI_Data_Lane_8_15_Bits = 0x1000,
+	CDI_Data_Lane_16_23_Bits = 0x2000,
+	CDI_Data_Lane_24_31_Bits = 0x3000
+};
+
+enum CDO_Mode_Bits {
+	CDO_Sample_Source_Select_Mask = 0x3f,
+	CDO_Retransmit_Bit = 0x100,
+	CDO_Halt_On_Error_Bit = 0x200,
+	CDO_Polarity_Bit = 0x400,	// sample clock on falling edge
+	CDO_FIFO_Mode_Bit = 0x800,	// set for half full mode, clear for not full mode
+	CDO_Data_Lane_Mask = 0x3000,	// data lanes specify which dio channels map to byte or word accesses to the dio fifos
+	CDO_Data_Lane_0_15_Bits = 0x0,
+	CDO_Data_Lane_16_31_Bits = 0x1000,
+	CDO_Data_Lane_0_7_Bits = 0x0,
+	CDO_Data_Lane_8_15_Bits = 0x1000,
+	CDO_Data_Lane_16_23_Bits = 0x2000,
+	CDO_Data_Lane_24_31_Bits = 0x3000
+};
+
+enum Interrupt_C_Enable_Bits {
+	Interrupt_Group_C_Enable_Bit = 0x1
+};
+
+enum Interrupt_C_Status_Bits {
+	Interrupt_Group_C_Status_Bit = 0x1
+};
+
+#define M_SERIES_EEPROM_SIZE 1024
+
+typedef struct ni_board_struct {
+	int device_id;
+	int isapnp_id;
+	char *name;
+
+	int n_adchan;
+	int adbits;
+
+	int ai_fifo_depth;
+	unsigned int alwaysdither:1;
+	int gainlkup;
+	int ai_speed;
+
+	int n_aochan;
+	int aobits;
+	int ao_fifo_depth;
+	const struct comedi_lrange *ao_range_table;
+	unsigned ao_speed;
+
+	unsigned num_p0_dio_channels;
+
+	int reg_type;
+	unsigned int ao_unipolar:1;
+	unsigned int has_8255:1;
+	unsigned int has_analog_trig:1;
+
+	enum caldac_enum caldac[3];
+} ni_board;
+
+#define n_ni_boards  (sizeof(ni_boards)/sizeof(ni_board))
+
+#define boardtype (*(ni_board *)dev->board_ptr)
+
+#define MAX_N_AO_CHAN 8
+#define NUM_GPCT 2
+
+#define NI_PRIVATE_COMMON					\
+	uint16_t (*stc_readw)(struct comedi_device *dev, int register);	\
+	uint32_t (*stc_readl)(struct comedi_device *dev, int register);	\
+	void (*stc_writew)(struct comedi_device *dev, uint16_t value, int register);	\
+	void (*stc_writel)(struct comedi_device *dev, uint32_t value, int register);	\
+	\
+	unsigned short dio_output;				\
+	unsigned short dio_control;				\
+	int ao0p,ao1p;						\
+	int lastchan;						\
+	int last_do;						\
+	int rt_irq;						\
+	int irqmask;						\
+	int aimode;						\
+	int ai_continuous;					\
+	int blocksize;						\
+	int n_left;						\
+	unsigned int ai_calib_source;				\
+	unsigned int ai_calib_source_enabled;			\
+	spinlock_t window_lock; \
+	spinlock_t soft_reg_copy_lock; \
+	spinlock_t mite_channel_lock; \
+								\
+	int changain_state;					\
+	unsigned int changain_spec;				\
+								\
+	unsigned int caldac_maxdata_list[MAX_N_CALDACS];	\
+	unsigned short ao[MAX_N_AO_CHAN];					\
+	unsigned short caldacs[MAX_N_CALDACS];				\
+								\
+	unsigned short ai_cmd2;	\
+								\
+	unsigned short ao_conf[MAX_N_AO_CHAN];				\
+	unsigned short ao_mode1;				\
+	unsigned short ao_mode2;				\
+	unsigned short ao_mode3;				\
+	unsigned short ao_cmd1;					\
+	unsigned short ao_cmd2;					\
+	unsigned short ao_cmd3;					\
+	unsigned short ao_trigger_select;			\
+								\
+	struct ni_gpct_device *counter_dev;	\
+	unsigned short an_trig_etc_reg;				\
+								\
+	unsigned ai_offset[512];				\
+								\
+	unsigned long serial_interval_ns;                       \
+	unsigned char serial_hw_mode;                           \
+	unsigned short clock_and_fout;				\
+	unsigned short clock_and_fout2;				\
+								\
+	unsigned short int_a_enable_reg;			\
+	unsigned short int_b_enable_reg;			\
+	unsigned short io_bidirection_pin_reg;			\
+	unsigned short rtsi_trig_direction_reg;			\
+	unsigned short rtsi_trig_a_output_reg; \
+	unsigned short rtsi_trig_b_output_reg; \
+	unsigned short pfi_output_select_reg[NUM_PFI_OUTPUT_SELECT_REGS]; \
+	unsigned short ai_ao_select_reg; \
+	unsigned short g0_g1_select_reg; \
+	unsigned short cdio_dma_select_reg; \
+	\
+	unsigned clock_ns; \
+	unsigned clock_source; \
+	\
+	unsigned short atrig_mode;				\
+	unsigned short atrig_high;				\
+	unsigned short atrig_low;				\
+	\
+	unsigned short pwm_up_count;	\
+	unsigned short pwm_down_count;	\
+	\
+	short ai_fifo_buffer[0x2000];				\
+	uint8_t eeprom_buffer[M_SERIES_EEPROM_SIZE]; \
+	uint32_t serial_number; \
+	\
+	struct mite_struct *mite; \
+	struct mite_channel *ai_mite_chan; \
+	struct mite_channel *ao_mite_chan;\
+	struct mite_channel *cdo_mite_chan;\
+	struct mite_dma_descriptor_ring *ai_mite_ring; \
+	struct mite_dma_descriptor_ring *ao_mite_ring; \
+	struct mite_dma_descriptor_ring *cdo_mite_ring; \
+	struct mite_dma_descriptor_ring *gpct_mite_ring[NUM_GPCT];
+
+#endif /* _COMEDI_NI_STC_H */
diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c
new file mode 100644
index 0000000..05a9575
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_tio.c
@@ -0,0 +1,1691 @@
+/*
+  comedi/drivers/ni_tio.c
+  Support for NI general purpose counters
+
+  Copyright (C) 2006 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+  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.
+*/
+
+/*
+Driver: ni_tio
+Description: National Instruments general purpose counters
+Devices:
+Author: J.P. Mellor <jpmellor@rose-hulman.edu>,
+	Herman.Bruyninckx@mech.kuleuven.ac.be,
+	Wim.Meeussen@mech.kuleuven.ac.be,
+	Klaas.Gadeyne@mech.kuleuven.ac.be,
+	Frank Mori Hess <fmhess@users.sourceforge.net>
+Updated: Thu Nov 16 09:50:32 EST 2006
+Status: works
+
+This module is not used directly by end-users.  Rather, it
+is used by other drivers (for example ni_660x and ni_pcimio)
+to provide support for NI's general purpose counters.  It was
+originally based on the counter code from ni_660x.c and
+ni_mio_common.c.
+
+References:
+DAQ 660x Register-Level Programmer Manual  (NI 370505A-01)
+DAQ 6601/6602 User Manual (NI 322137B-01)
+340934b.pdf  DAQ-STC reference manual
+
+*/
+/*
+TODO:
+	Support use of both banks X and Y
+*/
+
+#include "ni_tio_internal.h"
+
+static uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter,
+	unsigned generic_clock_source);
+static unsigned ni_tio_generic_clock_src_select(const struct ni_gpct *counter);
+
+MODULE_AUTHOR("Comedi <comedi@comedi.org>");
+MODULE_DESCRIPTION("Comedi support for NI general-purpose counters");
+MODULE_LICENSE("GPL");
+
+static inline enum Gi_Counting_Mode_Reg_Bits Gi_Alternate_Sync_Bit(enum
+	ni_gpct_variant variant)
+{
+	switch (variant) {
+	case ni_gpct_variant_e_series:
+		return 0;
+		break;
+	case ni_gpct_variant_m_series:
+		return Gi_M_Series_Alternate_Sync_Bit;
+		break;
+	case ni_gpct_variant_660x:
+		return Gi_660x_Alternate_Sync_Bit;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+static inline enum Gi_Counting_Mode_Reg_Bits Gi_Prescale_X2_Bit(enum
+	ni_gpct_variant variant)
+{
+	switch (variant) {
+	case ni_gpct_variant_e_series:
+		return 0;
+		break;
+	case ni_gpct_variant_m_series:
+		return Gi_M_Series_Prescale_X2_Bit;
+		break;
+	case ni_gpct_variant_660x:
+		return Gi_660x_Prescale_X2_Bit;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+static inline enum Gi_Counting_Mode_Reg_Bits Gi_Prescale_X8_Bit(enum
+	ni_gpct_variant variant)
+{
+	switch (variant) {
+	case ni_gpct_variant_e_series:
+		return 0;
+		break;
+	case ni_gpct_variant_m_series:
+		return Gi_M_Series_Prescale_X8_Bit;
+		break;
+	case ni_gpct_variant_660x:
+		return Gi_660x_Prescale_X8_Bit;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+static inline enum Gi_Counting_Mode_Reg_Bits Gi_HW_Arm_Select_Mask(enum
+	ni_gpct_variant variant)
+{
+	switch (variant) {
+	case ni_gpct_variant_e_series:
+		return 0;
+		break;
+	case ni_gpct_variant_m_series:
+		return Gi_M_Series_HW_Arm_Select_Mask;
+		break;
+	case ni_gpct_variant_660x:
+		return Gi_660x_HW_Arm_Select_Mask;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+
+/* clock sources for ni_660x boards, get bits with Gi_Source_Select_Bits() */
+enum ni_660x_clock_source {
+	NI_660x_Timebase_1_Clock = 0x0,	/* 20MHz */
+	NI_660x_Source_Pin_i_Clock = 0x1,
+	NI_660x_Next_Gate_Clock = 0xa,
+	NI_660x_Timebase_2_Clock = 0x12,	/* 100KHz */
+	NI_660x_Next_TC_Clock = 0x13,
+	NI_660x_Timebase_3_Clock = 0x1e,	/* 80MHz */
+	NI_660x_Logic_Low_Clock = 0x1f,
+};
+static const unsigned ni_660x_max_rtsi_channel = 6;
+static inline unsigned NI_660x_RTSI_Clock(unsigned n)
+{
+	BUG_ON(n > ni_660x_max_rtsi_channel);
+	return (0xb + n);
+}
+static const unsigned ni_660x_max_source_pin = 7;
+static inline unsigned NI_660x_Source_Pin_Clock(unsigned n)
+{
+	BUG_ON(n > ni_660x_max_source_pin);
+	return (0x2 + n);
+}
+
+/* clock sources for ni e and m series boards, get bits with Gi_Source_Select_Bits() */
+enum ni_m_series_clock_source {
+	NI_M_Series_Timebase_1_Clock = 0x0,	/* 20MHz */
+	NI_M_Series_Timebase_2_Clock = 0x12,	/* 100KHz */
+	NI_M_Series_Next_TC_Clock = 0x13,
+	NI_M_Series_Next_Gate_Clock = 0x14,	/* when Gi_Src_SubSelect = 0 */
+	NI_M_Series_PXI_Star_Trigger_Clock = 0x14,	/* when Gi_Src_SubSelect = 1 */
+	NI_M_Series_PXI10_Clock = 0x1d,
+	NI_M_Series_Timebase_3_Clock = 0x1e,	/* 80MHz, when Gi_Src_SubSelect = 0 */
+	NI_M_Series_Analog_Trigger_Out_Clock = 0x1e,	/* when Gi_Src_SubSelect = 1 */
+	NI_M_Series_Logic_Low_Clock = 0x1f,
+};
+static const unsigned ni_m_series_max_pfi_channel = 15;
+static inline unsigned NI_M_Series_PFI_Clock(unsigned n)
+{
+	BUG_ON(n > ni_m_series_max_pfi_channel);
+	if (n < 10)
+		return 1 + n;
+	else
+		return 0xb + n;
+}
+static const unsigned ni_m_series_max_rtsi_channel = 7;
+static inline unsigned NI_M_Series_RTSI_Clock(unsigned n)
+{
+	BUG_ON(n > ni_m_series_max_rtsi_channel);
+	if (n == 7)
+		return 0x1b;
+	else
+		return 0xb + n;
+}
+
+enum ni_660x_gate_select {
+	NI_660x_Source_Pin_i_Gate_Select = 0x0,
+	NI_660x_Gate_Pin_i_Gate_Select = 0x1,
+	NI_660x_Next_SRC_Gate_Select = 0xa,
+	NI_660x_Next_Out_Gate_Select = 0x14,
+	NI_660x_Logic_Low_Gate_Select = 0x1f,
+};
+static const unsigned ni_660x_max_gate_pin = 7;
+static inline unsigned NI_660x_Gate_Pin_Gate_Select(unsigned n)
+{
+	BUG_ON(n > ni_660x_max_gate_pin);
+	return 0x2 + n;
+}
+static inline unsigned NI_660x_RTSI_Gate_Select(unsigned n)
+{
+	BUG_ON(n > ni_660x_max_rtsi_channel);
+	return 0xb + n;
+}
+
+enum ni_m_series_gate_select {
+	NI_M_Series_Timestamp_Mux_Gate_Select = 0x0,
+	NI_M_Series_AI_START2_Gate_Select = 0x12,
+	NI_M_Series_PXI_Star_Trigger_Gate_Select = 0x13,
+	NI_M_Series_Next_Out_Gate_Select = 0x14,
+	NI_M_Series_AI_START1_Gate_Select = 0x1c,
+	NI_M_Series_Next_SRC_Gate_Select = 0x1d,
+	NI_M_Series_Analog_Trigger_Out_Gate_Select = 0x1e,
+	NI_M_Series_Logic_Low_Gate_Select = 0x1f,
+};
+static inline unsigned NI_M_Series_RTSI_Gate_Select(unsigned n)
+{
+	BUG_ON(n > ni_m_series_max_rtsi_channel);
+	if (n == 7)
+		return 0x1b;
+	return 0xb + n;
+}
+static inline unsigned NI_M_Series_PFI_Gate_Select(unsigned n)
+{
+	BUG_ON(n > ni_m_series_max_pfi_channel);
+	if (n < 10)
+		return 1 + n;
+	return 0xb + n;
+}
+
+static inline unsigned Gi_Source_Select_Bits(unsigned source)
+{
+	return (source << Gi_Source_Select_Shift) & Gi_Source_Select_Mask;
+}
+static inline unsigned Gi_Gate_Select_Bits(unsigned gate_select)
+{
+	return (gate_select << Gi_Gate_Select_Shift) & Gi_Gate_Select_Mask;
+}
+
+enum ni_660x_second_gate_select {
+	NI_660x_Source_Pin_i_Second_Gate_Select = 0x0,
+	NI_660x_Up_Down_Pin_i_Second_Gate_Select = 0x1,
+	NI_660x_Next_SRC_Second_Gate_Select = 0xa,
+	NI_660x_Next_Out_Second_Gate_Select = 0x14,
+	NI_660x_Selected_Gate_Second_Gate_Select = 0x1e,
+	NI_660x_Logic_Low_Second_Gate_Select = 0x1f,
+};
+static const unsigned ni_660x_max_up_down_pin = 7;
+static inline unsigned NI_660x_Up_Down_Pin_Second_Gate_Select(unsigned n)
+{
+	BUG_ON(n > ni_660x_max_up_down_pin);
+	return 0x2 + n;
+}
+static inline unsigned NI_660x_RTSI_Second_Gate_Select(unsigned n)
+{
+	BUG_ON(n > ni_660x_max_rtsi_channel);
+	return 0xb + n;
+}
+
+static const unsigned int counter_status_mask =
+	COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING;
+
+static int __init ni_tio_init_module(void)
+{
+	return 0;
+}
+
+module_init(ni_tio_init_module);
+
+static void __exit ni_tio_cleanup_module(void)
+{
+}
+
+module_exit(ni_tio_cleanup_module);
+
+struct ni_gpct_device *ni_gpct_device_construct(struct comedi_device * dev,
+	void (*write_register) (struct ni_gpct * counter, unsigned bits,
+		enum ni_gpct_register reg),
+	unsigned (*read_register) (struct ni_gpct * counter,
+		enum ni_gpct_register reg), enum ni_gpct_variant variant,
+	unsigned num_counters)
+{
+	unsigned i;
+
+	struct ni_gpct_device *counter_dev =
+		kzalloc(sizeof(struct ni_gpct_device), GFP_KERNEL);
+	if (counter_dev == NULL)
+		return NULL;
+	counter_dev->dev = dev;
+	counter_dev->write_register = write_register;
+	counter_dev->read_register = read_register;
+	counter_dev->variant = variant;
+	spin_lock_init(&counter_dev->regs_lock);
+	BUG_ON(num_counters == 0);
+	counter_dev->counters =
+		kzalloc(sizeof(struct ni_gpct) * num_counters, GFP_KERNEL);
+	if (counter_dev->counters == NULL) {
+		kfree(counter_dev);
+		return NULL;
+	}
+	for (i = 0; i < num_counters; ++i) {
+		counter_dev->counters[i].counter_dev = counter_dev;
+		spin_lock_init(&counter_dev->counters[i].lock);
+	}
+	counter_dev->num_counters = num_counters;
+	return counter_dev;
+}
+
+void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev)
+{
+	if (counter_dev->counters == NULL)
+		return;
+	kfree(counter_dev->counters);
+	kfree(counter_dev);
+}
+
+static int ni_tio_second_gate_registers_present(const struct ni_gpct_device
+	*counter_dev)
+{
+	switch (counter_dev->variant) {
+	case ni_gpct_variant_e_series:
+		return 0;
+		break;
+	case ni_gpct_variant_m_series:
+	case ni_gpct_variant_660x:
+		return 1;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+
+static void ni_tio_reset_count_and_disarm(struct ni_gpct *counter)
+{
+	write_register(counter, Gi_Reset_Bit(counter->counter_index),
+		NITIO_Gxx_Joint_Reset_Reg(counter->counter_index));
+}
+
+void ni_tio_init_counter(struct ni_gpct *counter)
+{
+	struct ni_gpct_device *counter_dev = counter->counter_dev;
+
+	ni_tio_reset_count_and_disarm(counter);
+	/* initialize counter registers */
+	counter_dev->regs[NITIO_Gi_Autoincrement_Reg(counter->counter_index)] =
+		0x0;
+	write_register(counter,
+		counter_dev->regs[NITIO_Gi_Autoincrement_Reg(counter->
+				counter_index)],
+		NITIO_Gi_Autoincrement_Reg(counter->counter_index));
+	ni_tio_set_bits(counter, NITIO_Gi_Command_Reg(counter->counter_index),
+		~0, Gi_Synchronize_Gate_Bit);
+	ni_tio_set_bits(counter, NITIO_Gi_Mode_Reg(counter->counter_index), ~0,
+		0);
+	counter_dev->regs[NITIO_Gi_LoadA_Reg(counter->counter_index)] = 0x0;
+	write_register(counter,
+		counter_dev->regs[NITIO_Gi_LoadA_Reg(counter->counter_index)],
+		NITIO_Gi_LoadA_Reg(counter->counter_index));
+	counter_dev->regs[NITIO_Gi_LoadB_Reg(counter->counter_index)] = 0x0;
+	write_register(counter,
+		counter_dev->regs[NITIO_Gi_LoadB_Reg(counter->counter_index)],
+		NITIO_Gi_LoadB_Reg(counter->counter_index));
+	ni_tio_set_bits(counter,
+		NITIO_Gi_Input_Select_Reg(counter->counter_index), ~0, 0);
+	if (ni_tio_counting_mode_registers_present(counter_dev)) {
+		ni_tio_set_bits(counter,
+			NITIO_Gi_Counting_Mode_Reg(counter->counter_index), ~0,
+			0);
+	}
+	if (ni_tio_second_gate_registers_present(counter_dev)) {
+		counter_dev->regs[NITIO_Gi_Second_Gate_Reg(counter->
+				counter_index)] = 0x0;
+		write_register(counter,
+			counter_dev->regs[NITIO_Gi_Second_Gate_Reg(counter->
+					counter_index)],
+			NITIO_Gi_Second_Gate_Reg(counter->counter_index));
+	}
+	ni_tio_set_bits(counter,
+		NITIO_Gi_DMA_Config_Reg(counter->counter_index), ~0, 0x0);
+	ni_tio_set_bits(counter,
+		NITIO_Gi_Interrupt_Enable_Reg(counter->counter_index), ~0, 0x0);
+}
+
+static unsigned int ni_tio_counter_status(struct ni_gpct *counter)
+{
+	unsigned int status = 0;
+	const unsigned bits = read_register(counter,
+		NITIO_Gxx_Status_Reg(counter->counter_index));
+	if (bits & Gi_Armed_Bit(counter->counter_index)) {
+		status |= COMEDI_COUNTER_ARMED;
+		if (bits & Gi_Counting_Bit(counter->counter_index))
+			status |= COMEDI_COUNTER_COUNTING;
+	}
+	return status;
+}
+
+static void ni_tio_set_sync_mode(struct ni_gpct *counter, int force_alt_sync)
+{
+	struct ni_gpct_device *counter_dev = counter->counter_dev;
+	const unsigned counting_mode_reg =
+		NITIO_Gi_Counting_Mode_Reg(counter->counter_index);
+	static const uint64_t min_normal_sync_period_ps = 25000;
+	const uint64_t clock_period_ps = ni_tio_clock_period_ps(counter,
+		ni_tio_generic_clock_src_select(counter));
+
+	if (ni_tio_counting_mode_registers_present(counter_dev) == 0)
+		return;
+
+	switch (ni_tio_get_soft_copy(counter,
+			counting_mode_reg) & Gi_Counting_Mode_Mask) {
+	case Gi_Counting_Mode_QuadratureX1_Bits:
+	case Gi_Counting_Mode_QuadratureX2_Bits:
+	case Gi_Counting_Mode_QuadratureX4_Bits:
+	case Gi_Counting_Mode_Sync_Source_Bits:
+		force_alt_sync = 1;
+		break;
+	default:
+		break;
+	}
+	/* It's not clear what we should do if clock_period is unknown, so we are not
+	   using the alt sync bit in that case, but allow the caller to decide by using the
+	   force_alt_sync parameter. */
+	if (force_alt_sync ||
+		(clock_period_ps
+			&& clock_period_ps < min_normal_sync_period_ps)) {
+		ni_tio_set_bits(counter, counting_mode_reg,
+			Gi_Alternate_Sync_Bit(counter_dev->variant),
+			Gi_Alternate_Sync_Bit(counter_dev->variant));
+	} else {
+		ni_tio_set_bits(counter, counting_mode_reg,
+			Gi_Alternate_Sync_Bit(counter_dev->variant), 0x0);
+	}
+}
+
+static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned mode)
+{
+	struct ni_gpct_device *counter_dev = counter->counter_dev;
+	unsigned mode_reg_mask;
+	unsigned mode_reg_values;
+	unsigned input_select_bits = 0;
+	/* these bits map directly on to the mode register */
+	static const unsigned mode_reg_direct_mask =
+		NI_GPCT_GATE_ON_BOTH_EDGES_BIT | NI_GPCT_EDGE_GATE_MODE_MASK |
+		NI_GPCT_STOP_MODE_MASK | NI_GPCT_OUTPUT_MODE_MASK |
+		NI_GPCT_HARDWARE_DISARM_MASK | NI_GPCT_LOADING_ON_TC_BIT |
+		NI_GPCT_LOADING_ON_GATE_BIT | NI_GPCT_LOAD_B_SELECT_BIT;
+
+	mode_reg_mask = mode_reg_direct_mask | Gi_Reload_Source_Switching_Bit;
+	mode_reg_values = mode & mode_reg_direct_mask;
+	switch (mode & NI_GPCT_RELOAD_SOURCE_MASK) {
+	case NI_GPCT_RELOAD_SOURCE_FIXED_BITS:
+		break;
+	case NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS:
+		mode_reg_values |= Gi_Reload_Source_Switching_Bit;
+		break;
+	case NI_GPCT_RELOAD_SOURCE_GATE_SELECT_BITS:
+		input_select_bits |= Gi_Gate_Select_Load_Source_Bit;
+		mode_reg_mask |= Gi_Gating_Mode_Mask;
+		mode_reg_values |= Gi_Level_Gating_Bits;
+		break;
+	default:
+		break;
+	}
+	ni_tio_set_bits(counter, NITIO_Gi_Mode_Reg(counter->counter_index),
+		mode_reg_mask, mode_reg_values);
+
+	if (ni_tio_counting_mode_registers_present(counter_dev)) {
+		unsigned counting_mode_bits = 0;
+		counting_mode_bits |=
+			(mode >> NI_GPCT_COUNTING_MODE_SHIFT) &
+			Gi_Counting_Mode_Mask;
+		counting_mode_bits |=
+			((mode >> NI_GPCT_INDEX_PHASE_BITSHIFT) <<
+			Gi_Index_Phase_Bitshift) & Gi_Index_Phase_Mask;
+		if (mode & NI_GPCT_INDEX_ENABLE_BIT) {
+			counting_mode_bits |= Gi_Index_Mode_Bit;
+		}
+		ni_tio_set_bits(counter,
+			NITIO_Gi_Counting_Mode_Reg(counter->counter_index),
+			Gi_Counting_Mode_Mask | Gi_Index_Phase_Mask |
+			Gi_Index_Mode_Bit, counting_mode_bits);
+		ni_tio_set_sync_mode(counter, 0);
+	}
+
+	ni_tio_set_bits(counter, NITIO_Gi_Command_Reg(counter->counter_index),
+		Gi_Up_Down_Mask,
+		(mode >> NI_GPCT_COUNTING_DIRECTION_SHIFT) << Gi_Up_Down_Shift);
+
+	if (mode & NI_GPCT_OR_GATE_BIT) {
+		input_select_bits |= Gi_Or_Gate_Bit;
+	}
+	if (mode & NI_GPCT_INVERT_OUTPUT_BIT) {
+		input_select_bits |= Gi_Output_Polarity_Bit;
+	}
+	ni_tio_set_bits(counter,
+		NITIO_Gi_Input_Select_Reg(counter->counter_index),
+		Gi_Gate_Select_Load_Source_Bit | Gi_Or_Gate_Bit |
+		Gi_Output_Polarity_Bit, input_select_bits);
+
+	return 0;
+}
+
+int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger)
+{
+	struct ni_gpct_device *counter_dev = counter->counter_dev;
+
+	unsigned command_transient_bits = 0;
+
+	if (arm) {
+		switch (start_trigger) {
+		case NI_GPCT_ARM_IMMEDIATE:
+			command_transient_bits |= Gi_Arm_Bit;
+			break;
+		case NI_GPCT_ARM_PAIRED_IMMEDIATE:
+			command_transient_bits |= Gi_Arm_Bit | Gi_Arm_Copy_Bit;
+			break;
+		default:
+			break;
+		}
+		if (ni_tio_counting_mode_registers_present(counter_dev)) {
+			unsigned counting_mode_bits = 0;
+
+			switch (start_trigger) {
+			case NI_GPCT_ARM_IMMEDIATE:
+			case NI_GPCT_ARM_PAIRED_IMMEDIATE:
+				break;
+			default:
+				if (start_trigger & NI_GPCT_ARM_UNKNOWN) {
+					/* pass-through the least significant bits so we can figure out what select later */
+					unsigned hw_arm_select_bits =
+						(start_trigger <<
+						Gi_HW_Arm_Select_Shift) &
+						Gi_HW_Arm_Select_Mask
+						(counter_dev->variant);
+
+					counting_mode_bits |=
+						Gi_HW_Arm_Enable_Bit |
+						hw_arm_select_bits;
+				} else {
+					return -EINVAL;
+				}
+				break;
+			}
+			ni_tio_set_bits(counter,
+				NITIO_Gi_Counting_Mode_Reg(counter->
+					counter_index),
+				Gi_HW_Arm_Select_Mask(counter_dev->
+					variant) | Gi_HW_Arm_Enable_Bit,
+				counting_mode_bits);
+		}
+	} else {
+		command_transient_bits |= Gi_Disarm_Bit;
+	}
+	ni_tio_set_bits_transient(counter,
+		NITIO_Gi_Command_Reg(counter->counter_index), 0, 0,
+		command_transient_bits);
+	return 0;
+}
+
+static unsigned ni_660x_source_select_bits(unsigned int clock_source)
+{
+	unsigned ni_660x_clock;
+	unsigned i;
+	const unsigned clock_select_bits =
+		clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK;
+
+	switch (clock_select_bits) {
+	case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
+		ni_660x_clock = NI_660x_Timebase_1_Clock;
+		break;
+	case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS:
+		ni_660x_clock = NI_660x_Timebase_2_Clock;
+		break;
+	case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
+		ni_660x_clock = NI_660x_Timebase_3_Clock;
+		break;
+	case NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS:
+		ni_660x_clock = NI_660x_Logic_Low_Clock;
+		break;
+	case NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS:
+		ni_660x_clock = NI_660x_Source_Pin_i_Clock;
+		break;
+	case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS:
+		ni_660x_clock = NI_660x_Next_Gate_Clock;
+		break;
+	case NI_GPCT_NEXT_TC_CLOCK_SRC_BITS:
+		ni_660x_clock = NI_660x_Next_TC_Clock;
+		break;
+	default:
+		for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
+			if (clock_select_bits == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) {
+				ni_660x_clock = NI_660x_RTSI_Clock(i);
+				break;
+			}
+		}
+		if (i <= ni_660x_max_rtsi_channel)
+			break;
+		for (i = 0; i <= ni_660x_max_source_pin; ++i) {
+			if (clock_select_bits ==
+				NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i)) {
+				ni_660x_clock = NI_660x_Source_Pin_Clock(i);
+				break;
+			}
+		}
+		if (i <= ni_660x_max_source_pin)
+			break;
+		ni_660x_clock = 0;
+		BUG();
+		break;
+	}
+	return Gi_Source_Select_Bits(ni_660x_clock);
+}
+
+static unsigned ni_m_series_source_select_bits(unsigned int clock_source)
+{
+	unsigned ni_m_series_clock;
+	unsigned i;
+	const unsigned clock_select_bits =
+		clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK;
+	switch (clock_select_bits) {
+	case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
+		ni_m_series_clock = NI_M_Series_Timebase_1_Clock;
+		break;
+	case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS:
+		ni_m_series_clock = NI_M_Series_Timebase_2_Clock;
+		break;
+	case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
+		ni_m_series_clock = NI_M_Series_Timebase_3_Clock;
+		break;
+	case NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS:
+		ni_m_series_clock = NI_M_Series_Logic_Low_Clock;
+		break;
+	case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS:
+		ni_m_series_clock = NI_M_Series_Next_Gate_Clock;
+		break;
+	case NI_GPCT_NEXT_TC_CLOCK_SRC_BITS:
+		ni_m_series_clock = NI_M_Series_Next_TC_Clock;
+		break;
+	case NI_GPCT_PXI10_CLOCK_SRC_BITS:
+		ni_m_series_clock = NI_M_Series_PXI10_Clock;
+		break;
+	case NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS:
+		ni_m_series_clock = NI_M_Series_PXI_Star_Trigger_Clock;
+		break;
+	case NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS:
+		ni_m_series_clock = NI_M_Series_Analog_Trigger_Out_Clock;
+		break;
+	default:
+		for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) {
+			if (clock_select_bits == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) {
+				ni_m_series_clock = NI_M_Series_RTSI_Clock(i);
+				break;
+			}
+		}
+		if (i <= ni_m_series_max_rtsi_channel)
+			break;
+		for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) {
+			if (clock_select_bits == NI_GPCT_PFI_CLOCK_SRC_BITS(i)) {
+				ni_m_series_clock = NI_M_Series_PFI_Clock(i);
+				break;
+			}
+		}
+		if (i <= ni_m_series_max_pfi_channel)
+			break;
+		rt_printk("invalid clock source 0x%lx\n",
+			(unsigned long)clock_source);
+		BUG();
+		ni_m_series_clock = 0;
+		break;
+	}
+	return Gi_Source_Select_Bits(ni_m_series_clock);
+};
+
+static void ni_tio_set_source_subselect(struct ni_gpct *counter,
+	unsigned int clock_source)
+{
+	struct ni_gpct_device *counter_dev = counter->counter_dev;
+	const unsigned second_gate_reg =
+		NITIO_Gi_Second_Gate_Reg(counter->counter_index);
+
+	if (counter_dev->variant != ni_gpct_variant_m_series)
+		return;
+	switch (clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK) {
+		/* Gi_Source_Subselect is zero */
+	case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS:
+	case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
+		counter_dev->regs[second_gate_reg] &= ~Gi_Source_Subselect_Bit;
+		break;
+		/* Gi_Source_Subselect is one */
+	case NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS:
+	case NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS:
+		counter_dev->regs[second_gate_reg] |= Gi_Source_Subselect_Bit;
+		break;
+		/* Gi_Source_Subselect doesn't matter */
+	default:
+		return;
+		break;
+	}
+	write_register(counter, counter_dev->regs[second_gate_reg],
+		second_gate_reg);
+}
+
+static int ni_tio_set_clock_src(struct ni_gpct *counter,
+	unsigned int clock_source, unsigned int period_ns)
+{
+	struct ni_gpct_device *counter_dev = counter->counter_dev;
+	unsigned input_select_bits = 0;
+	static const uint64_t pico_per_nano = 1000;
+
+/*FIXME: validate clock source */
+	switch (counter_dev->variant) {
+	case ni_gpct_variant_660x:
+		input_select_bits |= ni_660x_source_select_bits(clock_source);
+		break;
+	case ni_gpct_variant_e_series:
+	case ni_gpct_variant_m_series:
+		input_select_bits |=
+			ni_m_series_source_select_bits(clock_source);
+		break;
+	default:
+		BUG();
+		break;
+	}
+	if (clock_source & NI_GPCT_INVERT_CLOCK_SRC_BIT)
+		input_select_bits |= Gi_Source_Polarity_Bit;
+	ni_tio_set_bits(counter,
+		NITIO_Gi_Input_Select_Reg(counter->counter_index),
+		Gi_Source_Select_Mask | Gi_Source_Polarity_Bit,
+		input_select_bits);
+	ni_tio_set_source_subselect(counter, clock_source);
+	if (ni_tio_counting_mode_registers_present(counter_dev)) {
+		const unsigned prescaling_mode =
+			clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK;
+		unsigned counting_mode_bits = 0;
+
+		switch (prescaling_mode) {
+		case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS:
+			break;
+		case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS:
+			counting_mode_bits |=
+				Gi_Prescale_X2_Bit(counter_dev->variant);
+			break;
+		case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS:
+			counting_mode_bits |=
+				Gi_Prescale_X8_Bit(counter_dev->variant);
+			break;
+		default:
+			return -EINVAL;
+			break;
+		}
+		ni_tio_set_bits(counter,
+			NITIO_Gi_Counting_Mode_Reg(counter->counter_index),
+			Gi_Prescale_X2_Bit(counter_dev->
+				variant) | Gi_Prescale_X8_Bit(counter_dev->
+				variant), counting_mode_bits);
+	}
+	counter->clock_period_ps = pico_per_nano * period_ns;
+	ni_tio_set_sync_mode(counter, 0);
+	return 0;
+}
+
+static unsigned ni_tio_clock_src_modifiers(const struct ni_gpct *counter)
+{
+	struct ni_gpct_device *counter_dev = counter->counter_dev;
+	const unsigned counting_mode_bits = ni_tio_get_soft_copy(counter,
+		NITIO_Gi_Counting_Mode_Reg(counter->counter_index));
+	unsigned bits = 0;
+
+	if (ni_tio_get_soft_copy(counter,
+			NITIO_Gi_Input_Select_Reg(counter->
+				counter_index)) & Gi_Source_Polarity_Bit)
+		bits |= NI_GPCT_INVERT_CLOCK_SRC_BIT;
+	if (counting_mode_bits & Gi_Prescale_X2_Bit(counter_dev->variant))
+		bits |= NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS;
+	if (counting_mode_bits & Gi_Prescale_X8_Bit(counter_dev->variant))
+		bits |= NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS;
+	return bits;
+}
+
+static unsigned ni_m_series_clock_src_select(const struct ni_gpct *counter)
+{
+	struct ni_gpct_device *counter_dev = counter->counter_dev;
+	const unsigned second_gate_reg =
+		NITIO_Gi_Second_Gate_Reg(counter->counter_index);
+	unsigned clock_source = 0;
+	unsigned i;
+	const unsigned input_select = (ni_tio_get_soft_copy(counter,
+			NITIO_Gi_Input_Select_Reg(counter->
+				counter_index)) & Gi_Source_Select_Mask) >>
+		Gi_Source_Select_Shift;
+
+	switch (input_select) {
+	case NI_M_Series_Timebase_1_Clock:
+		clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS;
+		break;
+	case NI_M_Series_Timebase_2_Clock:
+		clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS;
+		break;
+	case NI_M_Series_Timebase_3_Clock:
+		if (counter_dev->
+			regs[second_gate_reg] & Gi_Source_Subselect_Bit)
+			clock_source =
+				NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS;
+		else
+			clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS;
+		break;
+	case NI_M_Series_Logic_Low_Clock:
+		clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS;
+		break;
+	case NI_M_Series_Next_Gate_Clock:
+		if (counter_dev->
+			regs[second_gate_reg] & Gi_Source_Subselect_Bit)
+			clock_source = NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS;
+		else
+			clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS;
+		break;
+	case NI_M_Series_PXI10_Clock:
+		clock_source = NI_GPCT_PXI10_CLOCK_SRC_BITS;
+		break;
+	case NI_M_Series_Next_TC_Clock:
+		clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS;
+		break;
+	default:
+		for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) {
+			if (input_select == NI_M_Series_RTSI_Clock(i)) {
+				clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i);
+				break;
+			}
+		}
+		if (i <= ni_m_series_max_rtsi_channel)
+			break;
+		for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) {
+			if (input_select == NI_M_Series_PFI_Clock(i)) {
+				clock_source = NI_GPCT_PFI_CLOCK_SRC_BITS(i);
+				break;
+			}
+		}
+		if (i <= ni_m_series_max_pfi_channel)
+			break;
+		BUG();
+		break;
+	}
+	clock_source |= ni_tio_clock_src_modifiers(counter);
+	return clock_source;
+}
+
+static unsigned ni_660x_clock_src_select(const struct ni_gpct *counter)
+{
+	unsigned clock_source = 0;
+	unsigned i;
+	const unsigned input_select = (ni_tio_get_soft_copy(counter,
+			NITIO_Gi_Input_Select_Reg(counter->
+				counter_index)) & Gi_Source_Select_Mask) >>
+		Gi_Source_Select_Shift;
+
+	switch (input_select) {
+	case NI_660x_Timebase_1_Clock:
+		clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS;
+		break;
+	case NI_660x_Timebase_2_Clock:
+		clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS;
+		break;
+	case NI_660x_Timebase_3_Clock:
+		clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS;
+		break;
+	case NI_660x_Logic_Low_Clock:
+		clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS;
+		break;
+	case NI_660x_Source_Pin_i_Clock:
+		clock_source = NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS;
+		break;
+	case NI_660x_Next_Gate_Clock:
+		clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS;
+		break;
+	case NI_660x_Next_TC_Clock:
+		clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS;
+		break;
+	default:
+		for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
+			if (input_select == NI_660x_RTSI_Clock(i)) {
+				clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i);
+				break;
+			}
+		}
+		if (i <= ni_660x_max_rtsi_channel)
+			break;
+		for (i = 0; i <= ni_660x_max_source_pin; ++i) {
+			if (input_select == NI_660x_Source_Pin_Clock(i)) {
+				clock_source =
+					NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i);
+				break;
+			}
+		}
+		if (i <= ni_660x_max_source_pin)
+			break;
+		BUG();
+		break;
+	}
+	clock_source |= ni_tio_clock_src_modifiers(counter);
+	return clock_source;
+}
+
+static unsigned ni_tio_generic_clock_src_select(const struct ni_gpct *counter)
+{
+	switch (counter->counter_dev->variant) {
+	case ni_gpct_variant_e_series:
+	case ni_gpct_variant_m_series:
+		return ni_m_series_clock_src_select(counter);
+		break;
+	case ni_gpct_variant_660x:
+		return ni_660x_clock_src_select(counter);
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+
+static uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter,
+	unsigned generic_clock_source)
+{
+	uint64_t clock_period_ps;
+
+	switch (generic_clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK) {
+	case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
+		clock_period_ps = 50000;
+		break;
+	case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS:
+		clock_period_ps = 10000000;
+		break;
+	case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
+		clock_period_ps = 12500;
+		break;
+	case NI_GPCT_PXI10_CLOCK_SRC_BITS:
+		clock_period_ps = 100000;
+		break;
+	default:
+		/* clock period is specified by user with prescaling already taken into account. */
+		return counter->clock_period_ps;
+		break;
+	}
+
+	switch (generic_clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK) {
+	case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS:
+		break;
+	case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS:
+		clock_period_ps *= 2;
+		break;
+	case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS:
+		clock_period_ps *= 8;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return clock_period_ps;
+}
+
+static void ni_tio_get_clock_src(struct ni_gpct *counter,
+	unsigned int * clock_source, unsigned int * period_ns)
+{
+	static const unsigned pico_per_nano = 1000;
+	uint64_t temp64;
+	*clock_source = ni_tio_generic_clock_src_select(counter);
+	temp64 = ni_tio_clock_period_ps(counter, *clock_source);
+	do_div(temp64, pico_per_nano);
+	*period_ns = temp64;
+}
+
+static void ni_tio_set_first_gate_modifiers(struct ni_gpct *counter,
+	unsigned int gate_source)
+{
+	const unsigned mode_mask = Gi_Gate_Polarity_Bit | Gi_Gating_Mode_Mask;
+	unsigned mode_values = 0;
+
+	if (gate_source & CR_INVERT) {
+		mode_values |= Gi_Gate_Polarity_Bit;
+	}
+	if (gate_source & CR_EDGE) {
+		mode_values |= Gi_Rising_Edge_Gating_Bits;
+	} else {
+		mode_values |= Gi_Level_Gating_Bits;
+	}
+	ni_tio_set_bits(counter, NITIO_Gi_Mode_Reg(counter->counter_index),
+		mode_mask, mode_values);
+}
+
+static int ni_660x_set_first_gate(struct ni_gpct *counter, unsigned int gate_source)
+{
+	const unsigned selected_gate = CR_CHAN(gate_source);
+	/* bits of selected_gate that may be meaningful to input select register */
+	const unsigned selected_gate_mask = 0x1f;
+	unsigned ni_660x_gate_select;
+	unsigned i;
+
+	switch (selected_gate) {
+	case NI_GPCT_NEXT_SOURCE_GATE_SELECT:
+		ni_660x_gate_select = NI_660x_Next_SRC_Gate_Select;
+		break;
+	case NI_GPCT_NEXT_OUT_GATE_SELECT:
+	case NI_GPCT_LOGIC_LOW_GATE_SELECT:
+	case NI_GPCT_SOURCE_PIN_i_GATE_SELECT:
+	case NI_GPCT_GATE_PIN_i_GATE_SELECT:
+		ni_660x_gate_select = selected_gate & selected_gate_mask;
+		break;
+	default:
+		for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
+			if (selected_gate == NI_GPCT_RTSI_GATE_SELECT(i)) {
+				ni_660x_gate_select =
+					selected_gate & selected_gate_mask;
+				break;
+			}
+		}
+		if (i <= ni_660x_max_rtsi_channel)
+			break;
+		for (i = 0; i <= ni_660x_max_gate_pin; ++i) {
+			if (selected_gate == NI_GPCT_GATE_PIN_GATE_SELECT(i)) {
+				ni_660x_gate_select =
+					selected_gate & selected_gate_mask;
+				break;
+			}
+		}
+		if (i <= ni_660x_max_gate_pin)
+			break;
+		return -EINVAL;
+		break;
+	}
+	ni_tio_set_bits(counter,
+		NITIO_Gi_Input_Select_Reg(counter->counter_index),
+		Gi_Gate_Select_Mask, Gi_Gate_Select_Bits(ni_660x_gate_select));
+	return 0;
+}
+
+static int ni_m_series_set_first_gate(struct ni_gpct *counter,
+	unsigned int gate_source)
+{
+	const unsigned selected_gate = CR_CHAN(gate_source);
+	/* bits of selected_gate that may be meaningful to input select register */
+	const unsigned selected_gate_mask = 0x1f;
+	unsigned ni_m_series_gate_select;
+	unsigned i;
+
+	switch (selected_gate) {
+	case NI_GPCT_TIMESTAMP_MUX_GATE_SELECT:
+	case NI_GPCT_AI_START2_GATE_SELECT:
+	case NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT:
+	case NI_GPCT_NEXT_OUT_GATE_SELECT:
+	case NI_GPCT_AI_START1_GATE_SELECT:
+	case NI_GPCT_NEXT_SOURCE_GATE_SELECT:
+	case NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT:
+	case NI_GPCT_LOGIC_LOW_GATE_SELECT:
+		ni_m_series_gate_select = selected_gate & selected_gate_mask;
+		break;
+	default:
+		for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) {
+			if (selected_gate == NI_GPCT_RTSI_GATE_SELECT(i)) {
+				ni_m_series_gate_select =
+					selected_gate & selected_gate_mask;
+				break;
+			}
+		}
+		if (i <= ni_m_series_max_rtsi_channel)
+			break;
+		for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) {
+			if (selected_gate == NI_GPCT_PFI_GATE_SELECT(i)) {
+				ni_m_series_gate_select =
+					selected_gate & selected_gate_mask;
+				break;
+			}
+		}
+		if (i <= ni_m_series_max_pfi_channel)
+			break;
+		return -EINVAL;
+		break;
+	}
+	ni_tio_set_bits(counter,
+		NITIO_Gi_Input_Select_Reg(counter->counter_index),
+		Gi_Gate_Select_Mask,
+		Gi_Gate_Select_Bits(ni_m_series_gate_select));
+	return 0;
+}
+
+static int ni_660x_set_second_gate(struct ni_gpct *counter,
+	unsigned int gate_source)
+{
+	struct ni_gpct_device *counter_dev = counter->counter_dev;
+	const unsigned second_gate_reg =
+		NITIO_Gi_Second_Gate_Reg(counter->counter_index);
+	const unsigned selected_second_gate = CR_CHAN(gate_source);
+	/* bits of second_gate that may be meaningful to second gate register */
+	static const unsigned selected_second_gate_mask = 0x1f;
+	unsigned ni_660x_second_gate_select;
+	unsigned i;
+
+	switch (selected_second_gate) {
+	case NI_GPCT_SOURCE_PIN_i_GATE_SELECT:
+	case NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT:
+	case NI_GPCT_SELECTED_GATE_GATE_SELECT:
+	case NI_GPCT_NEXT_OUT_GATE_SELECT:
+	case NI_GPCT_LOGIC_LOW_GATE_SELECT:
+		ni_660x_second_gate_select =
+			selected_second_gate & selected_second_gate_mask;
+		break;
+	case NI_GPCT_NEXT_SOURCE_GATE_SELECT:
+		ni_660x_second_gate_select =
+			NI_660x_Next_SRC_Second_Gate_Select;
+		break;
+	default:
+		for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
+			if (selected_second_gate == NI_GPCT_RTSI_GATE_SELECT(i)) {
+				ni_660x_second_gate_select =
+					selected_second_gate &
+					selected_second_gate_mask;
+				break;
+			}
+		}
+		if (i <= ni_660x_max_rtsi_channel)
+			break;
+		for (i = 0; i <= ni_660x_max_up_down_pin; ++i) {
+			if (selected_second_gate ==
+				NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i)) {
+				ni_660x_second_gate_select =
+					selected_second_gate &
+					selected_second_gate_mask;
+				break;
+			}
+		}
+		if (i <= ni_660x_max_up_down_pin)
+			break;
+		return -EINVAL;
+		break;
+	};
+	counter_dev->regs[second_gate_reg] |= Gi_Second_Gate_Mode_Bit;
+	counter_dev->regs[second_gate_reg] &= ~Gi_Second_Gate_Select_Mask;
+	counter_dev->regs[second_gate_reg] |=
+		Gi_Second_Gate_Select_Bits(ni_660x_second_gate_select);
+	write_register(counter, counter_dev->regs[second_gate_reg],
+		second_gate_reg);
+	return 0;
+}
+
+static int ni_m_series_set_second_gate(struct ni_gpct *counter,
+	unsigned int gate_source)
+{
+	struct ni_gpct_device *counter_dev = counter->counter_dev;
+	const unsigned second_gate_reg =
+		NITIO_Gi_Second_Gate_Reg(counter->counter_index);
+	const unsigned selected_second_gate = CR_CHAN(gate_source);
+	/* bits of second_gate that may be meaningful to second gate register */
+	static const unsigned selected_second_gate_mask = 0x1f;
+	unsigned ni_m_series_second_gate_select;
+
+	/* FIXME: We don't know what the m-series second gate codes are, so we'll just pass
+	   the bits through for now. */
+	switch (selected_second_gate) {
+	default:
+		ni_m_series_second_gate_select =
+			selected_second_gate & selected_second_gate_mask;
+		break;
+	};
+	counter_dev->regs[second_gate_reg] |= Gi_Second_Gate_Mode_Bit;
+	counter_dev->regs[second_gate_reg] &= ~Gi_Second_Gate_Select_Mask;
+	counter_dev->regs[second_gate_reg] |=
+		Gi_Second_Gate_Select_Bits(ni_m_series_second_gate_select);
+	write_register(counter, counter_dev->regs[second_gate_reg],
+		second_gate_reg);
+	return 0;
+}
+
+int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned gate_index,
+	unsigned int gate_source)
+{
+	struct ni_gpct_device *counter_dev = counter->counter_dev;
+	const unsigned second_gate_reg =
+		NITIO_Gi_Second_Gate_Reg(counter->counter_index);
+
+	switch (gate_index) {
+	case 0:
+		if (CR_CHAN(gate_source) == NI_GPCT_DISABLED_GATE_SELECT) {
+			ni_tio_set_bits(counter,
+				NITIO_Gi_Mode_Reg(counter->counter_index),
+				Gi_Gating_Mode_Mask, Gi_Gating_Disabled_Bits);
+			return 0;
+		}
+		ni_tio_set_first_gate_modifiers(counter, gate_source);
+		switch (counter_dev->variant) {
+		case ni_gpct_variant_e_series:
+		case ni_gpct_variant_m_series:
+			return ni_m_series_set_first_gate(counter, gate_source);
+			break;
+		case ni_gpct_variant_660x:
+			return ni_660x_set_first_gate(counter, gate_source);
+			break;
+		default:
+			BUG();
+			break;
+		}
+		break;
+	case 1:
+		if (ni_tio_second_gate_registers_present(counter_dev) == 0)
+			return -EINVAL;
+		if (CR_CHAN(gate_source) == NI_GPCT_DISABLED_GATE_SELECT) {
+			counter_dev->regs[second_gate_reg] &=
+				~Gi_Second_Gate_Mode_Bit;
+			write_register(counter,
+				counter_dev->regs[second_gate_reg],
+				second_gate_reg);
+			return 0;
+		}
+		if (gate_source & CR_INVERT) {
+			counter_dev->regs[second_gate_reg] |=
+				Gi_Second_Gate_Polarity_Bit;
+		} else {
+			counter_dev->regs[second_gate_reg] &=
+				~Gi_Second_Gate_Polarity_Bit;
+		}
+		switch (counter_dev->variant) {
+		case ni_gpct_variant_m_series:
+			return ni_m_series_set_second_gate(counter,
+				gate_source);
+			break;
+		case ni_gpct_variant_660x:
+			return ni_660x_set_second_gate(counter, gate_source);
+			break;
+		default:
+			BUG();
+			break;
+		}
+		break;
+	default:
+		return -EINVAL;
+		break;
+	}
+	return 0;
+}
+
+static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned index,
+	unsigned int source)
+{
+	struct ni_gpct_device *counter_dev = counter->counter_dev;
+
+	if (counter_dev->variant == ni_gpct_variant_m_series) {
+		unsigned int abz_reg, shift, mask;
+
+		abz_reg = NITIO_Gi_ABZ_Reg(counter->counter_index);
+		switch (index) {
+		case NI_GPCT_SOURCE_ENCODER_A:
+			shift = 10;
+			break;
+		case NI_GPCT_SOURCE_ENCODER_B:
+			shift = 5;
+			break;
+		case NI_GPCT_SOURCE_ENCODER_Z:
+			shift = 0;
+			break;
+		default:
+			return -EINVAL;
+			break;
+		}
+		mask = 0x1f << shift;
+		if (source > 0x1f) {
+			/* Disable gate */
+			source = 0x1f;
+		}
+		counter_dev->regs[abz_reg] &= ~mask;
+		counter_dev->regs[abz_reg] |= (source << shift) & mask;
+		write_register(counter, counter_dev->regs[abz_reg], abz_reg);
+//              rt_printk("%s %x %d %d\n", __FUNCTION__, counter_dev->regs[abz_reg], index, source);
+		return 0;
+	}
+	return -EINVAL;
+}
+
+static unsigned ni_660x_first_gate_to_generic_gate_source(unsigned
+	ni_660x_gate_select)
+{
+	unsigned i;
+
+	switch (ni_660x_gate_select) {
+	case NI_660x_Source_Pin_i_Gate_Select:
+		return NI_GPCT_SOURCE_PIN_i_GATE_SELECT;
+		break;
+	case NI_660x_Gate_Pin_i_Gate_Select:
+		return NI_GPCT_GATE_PIN_i_GATE_SELECT;
+		break;
+	case NI_660x_Next_SRC_Gate_Select:
+		return NI_GPCT_NEXT_SOURCE_GATE_SELECT;
+		break;
+	case NI_660x_Next_Out_Gate_Select:
+		return NI_GPCT_NEXT_OUT_GATE_SELECT;
+		break;
+	case NI_660x_Logic_Low_Gate_Select:
+		return NI_GPCT_LOGIC_LOW_GATE_SELECT;
+		break;
+	default:
+		for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
+			if (ni_660x_gate_select == NI_660x_RTSI_Gate_Select(i)) {
+				return NI_GPCT_RTSI_GATE_SELECT(i);
+				break;
+			}
+		}
+		if (i <= ni_660x_max_rtsi_channel)
+			break;
+		for (i = 0; i <= ni_660x_max_gate_pin; ++i) {
+			if (ni_660x_gate_select ==
+				NI_660x_Gate_Pin_Gate_Select(i)) {
+				return NI_GPCT_GATE_PIN_GATE_SELECT(i);
+				break;
+			}
+		}
+		if (i <= ni_660x_max_gate_pin)
+			break;
+		BUG();
+		break;
+	}
+	return 0;
+};
+
+static unsigned ni_m_series_first_gate_to_generic_gate_source(unsigned
+	ni_m_series_gate_select)
+{
+	unsigned i;
+
+	switch (ni_m_series_gate_select) {
+	case NI_M_Series_Timestamp_Mux_Gate_Select:
+		return NI_GPCT_TIMESTAMP_MUX_GATE_SELECT;
+		break;
+	case NI_M_Series_AI_START2_Gate_Select:
+		return NI_GPCT_AI_START2_GATE_SELECT;
+		break;
+	case NI_M_Series_PXI_Star_Trigger_Gate_Select:
+		return NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT;
+		break;
+	case NI_M_Series_Next_Out_Gate_Select:
+		return NI_GPCT_NEXT_OUT_GATE_SELECT;
+		break;
+	case NI_M_Series_AI_START1_Gate_Select:
+		return NI_GPCT_AI_START1_GATE_SELECT;
+		break;
+	case NI_M_Series_Next_SRC_Gate_Select:
+		return NI_GPCT_NEXT_SOURCE_GATE_SELECT;
+		break;
+	case NI_M_Series_Analog_Trigger_Out_Gate_Select:
+		return NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT;
+		break;
+	case NI_M_Series_Logic_Low_Gate_Select:
+		return NI_GPCT_LOGIC_LOW_GATE_SELECT;
+		break;
+	default:
+		for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) {
+			if (ni_m_series_gate_select ==
+				NI_M_Series_RTSI_Gate_Select(i)) {
+				return NI_GPCT_RTSI_GATE_SELECT(i);
+				break;
+			}
+		}
+		if (i <= ni_m_series_max_rtsi_channel)
+			break;
+		for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) {
+			if (ni_m_series_gate_select ==
+				NI_M_Series_PFI_Gate_Select(i)) {
+				return NI_GPCT_PFI_GATE_SELECT(i);
+				break;
+			}
+		}
+		if (i <= ni_m_series_max_pfi_channel)
+			break;
+		BUG();
+		break;
+	}
+	return 0;
+};
+
+static unsigned ni_660x_second_gate_to_generic_gate_source(unsigned
+	ni_660x_gate_select)
+{
+	unsigned i;
+
+	switch (ni_660x_gate_select) {
+	case NI_660x_Source_Pin_i_Second_Gate_Select:
+		return NI_GPCT_SOURCE_PIN_i_GATE_SELECT;
+		break;
+	case NI_660x_Up_Down_Pin_i_Second_Gate_Select:
+		return NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT;
+		break;
+	case NI_660x_Next_SRC_Second_Gate_Select:
+		return NI_GPCT_NEXT_SOURCE_GATE_SELECT;
+		break;
+	case NI_660x_Next_Out_Second_Gate_Select:
+		return NI_GPCT_NEXT_OUT_GATE_SELECT;
+		break;
+	case NI_660x_Selected_Gate_Second_Gate_Select:
+		return NI_GPCT_SELECTED_GATE_GATE_SELECT;
+		break;
+	case NI_660x_Logic_Low_Second_Gate_Select:
+		return NI_GPCT_LOGIC_LOW_GATE_SELECT;
+		break;
+	default:
+		for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
+			if (ni_660x_gate_select ==
+				NI_660x_RTSI_Second_Gate_Select(i)) {
+				return NI_GPCT_RTSI_GATE_SELECT(i);
+				break;
+			}
+		}
+		if (i <= ni_660x_max_rtsi_channel)
+			break;
+		for (i = 0; i <= ni_660x_max_up_down_pin; ++i) {
+			if (ni_660x_gate_select ==
+				NI_660x_Up_Down_Pin_Second_Gate_Select(i)) {
+				return NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i);
+				break;
+			}
+		}
+		if (i <= ni_660x_max_up_down_pin)
+			break;
+		BUG();
+		break;
+	}
+	return 0;
+};
+
+static unsigned ni_m_series_second_gate_to_generic_gate_source(unsigned
+	ni_m_series_gate_select)
+{
+	/*FIXME: the second gate sources for the m series are undocumented, so we just return
+	 * the raw bits for now. */
+	switch (ni_m_series_gate_select) {
+	default:
+		return ni_m_series_gate_select;
+		break;
+	}
+	return 0;
+};
+
+static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned gate_index,
+	unsigned int * gate_source)
+{
+	struct ni_gpct_device *counter_dev = counter->counter_dev;
+	const unsigned mode_bits = ni_tio_get_soft_copy(counter,
+		NITIO_Gi_Mode_Reg(counter->counter_index));
+	const unsigned second_gate_reg =
+		NITIO_Gi_Second_Gate_Reg(counter->counter_index);
+	unsigned gate_select_bits;
+
+	switch (gate_index) {
+	case 0:
+		if ((mode_bits & Gi_Gating_Mode_Mask) ==
+			Gi_Gating_Disabled_Bits) {
+			*gate_source = NI_GPCT_DISABLED_GATE_SELECT;
+			return 0;
+		} else {
+			gate_select_bits =
+				(ni_tio_get_soft_copy(counter,
+					NITIO_Gi_Input_Select_Reg(counter->
+						counter_index)) &
+				Gi_Gate_Select_Mask) >> Gi_Gate_Select_Shift;
+		}
+		switch (counter_dev->variant) {
+		case ni_gpct_variant_e_series:
+		case ni_gpct_variant_m_series:
+			*gate_source =
+				ni_m_series_first_gate_to_generic_gate_source
+				(gate_select_bits);
+			break;
+		case ni_gpct_variant_660x:
+			*gate_source =
+				ni_660x_first_gate_to_generic_gate_source
+				(gate_select_bits);
+			break;
+		default:
+			BUG();
+			break;
+		}
+		if (mode_bits & Gi_Gate_Polarity_Bit) {
+			*gate_source |= CR_INVERT;
+		}
+		if ((mode_bits & Gi_Gating_Mode_Mask) != Gi_Level_Gating_Bits) {
+			*gate_source |= CR_EDGE;
+		}
+		break;
+	case 1:
+		if ((mode_bits & Gi_Gating_Mode_Mask) == Gi_Gating_Disabled_Bits
+			|| (counter_dev->
+				regs[second_gate_reg] & Gi_Second_Gate_Mode_Bit)
+			== 0) {
+			*gate_source = NI_GPCT_DISABLED_GATE_SELECT;
+			return 0;
+		} else {
+			gate_select_bits =
+				(counter_dev->
+				regs[second_gate_reg] &
+				Gi_Second_Gate_Select_Mask) >>
+				Gi_Second_Gate_Select_Shift;
+		}
+		switch (counter_dev->variant) {
+		case ni_gpct_variant_e_series:
+		case ni_gpct_variant_m_series:
+			*gate_source =
+				ni_m_series_second_gate_to_generic_gate_source
+				(gate_select_bits);
+			break;
+		case ni_gpct_variant_660x:
+			*gate_source =
+				ni_660x_second_gate_to_generic_gate_source
+				(gate_select_bits);
+			break;
+		default:
+			BUG();
+			break;
+		}
+		if (counter_dev->
+			regs[second_gate_reg] & Gi_Second_Gate_Polarity_Bit) {
+			*gate_source |= CR_INVERT;
+		}
+		/* second gate can't have edge/level mode set independently */
+		if ((mode_bits & Gi_Gating_Mode_Mask) != Gi_Level_Gating_Bits) {
+			*gate_source |= CR_EDGE;
+		}
+		break;
+	default:
+		return -EINVAL;
+		break;
+	}
+	return 0;
+}
+
+int ni_tio_insn_config(struct ni_gpct *counter,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	switch (data[0]) {
+	case INSN_CONFIG_SET_COUNTER_MODE:
+		return ni_tio_set_counter_mode(counter, data[1]);
+		break;
+	case INSN_CONFIG_ARM:
+		return ni_tio_arm(counter, 1, data[1]);
+		break;
+	case INSN_CONFIG_DISARM:
+		ni_tio_arm(counter, 0, 0);
+		return 0;
+		break;
+	case INSN_CONFIG_GET_COUNTER_STATUS:
+		data[1] = ni_tio_counter_status(counter);
+		data[2] = counter_status_mask;
+		return 0;
+		break;
+	case INSN_CONFIG_SET_CLOCK_SRC:
+		return ni_tio_set_clock_src(counter, data[1], data[2]);
+		break;
+	case INSN_CONFIG_GET_CLOCK_SRC:
+		ni_tio_get_clock_src(counter, &data[1], &data[2]);
+		return 0;
+		break;
+	case INSN_CONFIG_SET_GATE_SRC:
+		return ni_tio_set_gate_src(counter, data[1], data[2]);
+		break;
+	case INSN_CONFIG_GET_GATE_SRC:
+		return ni_tio_get_gate_src(counter, data[1], &data[2]);
+		break;
+	case INSN_CONFIG_SET_OTHER_SRC:
+		return ni_tio_set_other_src(counter, data[1], data[2]);
+		break;
+	case INSN_CONFIG_RESET:
+		ni_tio_reset_count_and_disarm(counter);
+		return 0;
+		break;
+	default:
+		break;
+	}
+	return -EINVAL;
+}
+
+int ni_tio_rinsn(struct ni_gpct *counter, struct comedi_insn * insn, unsigned int * data)
+{
+	struct ni_gpct_device *counter_dev = counter->counter_dev;
+	const unsigned channel = CR_CHAN(insn->chanspec);
+	unsigned first_read;
+	unsigned second_read;
+	unsigned correct_read;
+
+	if (insn->n < 1)
+		return 0;
+	switch (channel) {
+	case 0:
+		ni_tio_set_bits(counter,
+			NITIO_Gi_Command_Reg(counter->counter_index),
+			Gi_Save_Trace_Bit, 0);
+		ni_tio_set_bits(counter,
+			NITIO_Gi_Command_Reg(counter->counter_index),
+			Gi_Save_Trace_Bit, Gi_Save_Trace_Bit);
+		/* The count doesn't get latched until the next clock edge, so it is possible the count
+		   may change (once) while we are reading.  Since the read of the SW_Save_Reg isn't
+		   atomic (apparently even when it's a 32 bit register according to 660x docs),
+		   we need to read twice and make sure the reading hasn't changed.  If it has,
+		   a third read will be correct since the count value will definitely have latched by then. */
+		first_read =
+			read_register(counter,
+			NITIO_Gi_SW_Save_Reg(counter->counter_index));
+		second_read =
+			read_register(counter,
+			NITIO_Gi_SW_Save_Reg(counter->counter_index));
+		if (first_read != second_read)
+			correct_read =
+				read_register(counter,
+				NITIO_Gi_SW_Save_Reg(counter->counter_index));
+		else
+			correct_read = first_read;
+		data[0] = correct_read;
+		return 0;
+		break;
+	case 1:
+		data[0] =
+			counter_dev->regs[NITIO_Gi_LoadA_Reg(counter->
+				counter_index)];
+		break;
+	case 2:
+		data[0] =
+			counter_dev->regs[NITIO_Gi_LoadB_Reg(counter->
+				counter_index)];
+		break;
+	};
+	return 0;
+}
+
+static unsigned ni_tio_next_load_register(struct ni_gpct *counter)
+{
+	const unsigned bits = read_register(counter,
+		NITIO_Gxx_Status_Reg(counter->counter_index));
+
+	if (bits & Gi_Next_Load_Source_Bit(counter->counter_index)) {
+		return NITIO_Gi_LoadB_Reg(counter->counter_index);
+	} else {
+		return NITIO_Gi_LoadA_Reg(counter->counter_index);
+	}
+}
+
+int ni_tio_winsn(struct ni_gpct *counter, struct comedi_insn * insn, unsigned int * data)
+{
+	struct ni_gpct_device *counter_dev = counter->counter_dev;
+	const unsigned channel = CR_CHAN(insn->chanspec);
+	unsigned load_reg;
+
+	if (insn->n < 1)
+		return 0;
+	switch (channel) {
+	case 0:
+		/* Unsafe if counter is armed.  Should probably check status and return -EBUSY if armed. */
+		/* Don't disturb load source select, just use whichever load register is already selected. */
+		load_reg = ni_tio_next_load_register(counter);
+		write_register(counter, data[0], load_reg);
+		ni_tio_set_bits_transient(counter,
+			NITIO_Gi_Command_Reg(counter->counter_index), 0, 0,
+			Gi_Load_Bit);
+		/* restore state of load reg to whatever the user set last set it to */
+		write_register(counter, counter_dev->regs[load_reg], load_reg);
+		break;
+	case 1:
+		counter_dev->regs[NITIO_Gi_LoadA_Reg(counter->counter_index)] =
+			data[0];
+		write_register(counter, data[0],
+			NITIO_Gi_LoadA_Reg(counter->counter_index));
+		break;
+	case 2:
+		counter_dev->regs[NITIO_Gi_LoadB_Reg(counter->counter_index)] =
+			data[0];
+		write_register(counter, data[0],
+			NITIO_Gi_LoadB_Reg(counter->counter_index));
+		break;
+	default:
+		return -EINVAL;
+		break;
+	}
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(ni_tio_rinsn);
+EXPORT_SYMBOL_GPL(ni_tio_winsn);
+EXPORT_SYMBOL_GPL(ni_tio_insn_config);
+EXPORT_SYMBOL_GPL(ni_tio_init_counter);
+EXPORT_SYMBOL_GPL(ni_tio_arm);
+EXPORT_SYMBOL_GPL(ni_tio_set_gate_src);
+EXPORT_SYMBOL_GPL(ni_gpct_device_construct);
+EXPORT_SYMBOL_GPL(ni_gpct_device_destroy);
diff --git a/drivers/staging/comedi/drivers/ni_tio.h b/drivers/staging/comedi/drivers/ni_tio.h
new file mode 100644
index 0000000..0729d60
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_tio.h
@@ -0,0 +1,163 @@
+/*
+    drivers/ni_tio.h
+    Header file for NI general purpose counter support code (ni_tio.c)
+
+    COMEDI - Linux Control and Measurement Device Interface
+
+    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.
+
+*/
+
+#ifndef _COMEDI_NI_TIO_H
+#define _COMEDI_NI_TIO_H
+
+#include "../comedidev.h"
+
+// forward declarations
+struct mite_struct;
+struct ni_gpct_device;
+
+enum ni_gpct_register {
+	NITIO_G0_Autoincrement_Reg,
+	NITIO_G1_Autoincrement_Reg,
+	NITIO_G2_Autoincrement_Reg,
+	NITIO_G3_Autoincrement_Reg,
+	NITIO_G0_Command_Reg,
+	NITIO_G1_Command_Reg,
+	NITIO_G2_Command_Reg,
+	NITIO_G3_Command_Reg,
+	NITIO_G0_HW_Save_Reg,
+	NITIO_G1_HW_Save_Reg,
+	NITIO_G2_HW_Save_Reg,
+	NITIO_G3_HW_Save_Reg,
+	NITIO_G0_SW_Save_Reg,
+	NITIO_G1_SW_Save_Reg,
+	NITIO_G2_SW_Save_Reg,
+	NITIO_G3_SW_Save_Reg,
+	NITIO_G0_Mode_Reg,
+	NITIO_G1_Mode_Reg,
+	NITIO_G2_Mode_Reg,
+	NITIO_G3_Mode_Reg,
+	NITIO_G0_LoadA_Reg,
+	NITIO_G1_LoadA_Reg,
+	NITIO_G2_LoadA_Reg,
+	NITIO_G3_LoadA_Reg,
+	NITIO_G0_LoadB_Reg,
+	NITIO_G1_LoadB_Reg,
+	NITIO_G2_LoadB_Reg,
+	NITIO_G3_LoadB_Reg,
+	NITIO_G0_Input_Select_Reg,
+	NITIO_G1_Input_Select_Reg,
+	NITIO_G2_Input_Select_Reg,
+	NITIO_G3_Input_Select_Reg,
+	NITIO_G0_Counting_Mode_Reg,
+	NITIO_G1_Counting_Mode_Reg,
+	NITIO_G2_Counting_Mode_Reg,
+	NITIO_G3_Counting_Mode_Reg,
+	NITIO_G0_Second_Gate_Reg,
+	NITIO_G1_Second_Gate_Reg,
+	NITIO_G2_Second_Gate_Reg,
+	NITIO_G3_Second_Gate_Reg,
+	NITIO_G01_Status_Reg,
+	NITIO_G23_Status_Reg,
+	NITIO_G01_Joint_Reset_Reg,
+	NITIO_G23_Joint_Reset_Reg,
+	NITIO_G01_Joint_Status1_Reg,
+	NITIO_G23_Joint_Status1_Reg,
+	NITIO_G01_Joint_Status2_Reg,
+	NITIO_G23_Joint_Status2_Reg,
+	NITIO_G0_DMA_Config_Reg,
+	NITIO_G1_DMA_Config_Reg,
+	NITIO_G2_DMA_Config_Reg,
+	NITIO_G3_DMA_Config_Reg,
+	NITIO_G0_DMA_Status_Reg,
+	NITIO_G1_DMA_Status_Reg,
+	NITIO_G2_DMA_Status_Reg,
+	NITIO_G3_DMA_Status_Reg,
+	NITIO_G0_ABZ_Reg,
+	NITIO_G1_ABZ_Reg,
+	NITIO_G0_Interrupt_Acknowledge_Reg,
+	NITIO_G1_Interrupt_Acknowledge_Reg,
+	NITIO_G2_Interrupt_Acknowledge_Reg,
+	NITIO_G3_Interrupt_Acknowledge_Reg,
+	NITIO_G0_Status_Reg,
+	NITIO_G1_Status_Reg,
+	NITIO_G2_Status_Reg,
+	NITIO_G3_Status_Reg,
+	NITIO_G0_Interrupt_Enable_Reg,
+	NITIO_G1_Interrupt_Enable_Reg,
+	NITIO_G2_Interrupt_Enable_Reg,
+	NITIO_G3_Interrupt_Enable_Reg,
+	NITIO_Num_Registers,
+};
+
+enum ni_gpct_variant {
+	ni_gpct_variant_e_series,
+	ni_gpct_variant_m_series,
+	ni_gpct_variant_660x
+};
+
+struct ni_gpct {
+	struct ni_gpct_device *counter_dev;
+	unsigned counter_index;
+	unsigned chip_index;
+	uint64_t clock_period_ps;	/* clock period in picoseconds */
+	struct mite_channel *mite_chan;
+	spinlock_t lock;
+};
+
+struct ni_gpct_device {
+	struct comedi_device *dev;
+	void (*write_register) (struct ni_gpct * counter, unsigned bits,
+		enum ni_gpct_register reg);
+	unsigned (*read_register) (struct ni_gpct * counter,
+		enum ni_gpct_register reg);
+	enum ni_gpct_variant variant;
+	struct ni_gpct *counters;
+	unsigned num_counters;
+	unsigned regs[NITIO_Num_Registers];
+	spinlock_t regs_lock;
+};
+
+extern struct ni_gpct_device *ni_gpct_device_construct(struct comedi_device * dev,
+	void (*write_register) (struct ni_gpct * counter, unsigned bits,
+		enum ni_gpct_register reg),
+	unsigned (*read_register) (struct ni_gpct * counter,
+		enum ni_gpct_register reg), enum ni_gpct_variant variant,
+	unsigned num_counters);
+extern void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev);
+extern void ni_tio_init_counter(struct ni_gpct *counter);
+extern int ni_tio_rinsn(struct ni_gpct *counter,
+	struct comedi_insn * insn, unsigned int * data);
+extern int ni_tio_insn_config(struct ni_gpct *counter,
+	struct comedi_insn * insn, unsigned int * data);
+extern int ni_tio_winsn(struct ni_gpct *counter,
+	struct comedi_insn * insn, unsigned int * data);
+extern int ni_tio_cmd(struct ni_gpct *counter, struct comedi_async *async);
+extern int ni_tio_cmdtest(struct ni_gpct *counter, struct comedi_cmd * cmd);
+extern int ni_tio_cancel(struct ni_gpct *counter);
+extern void ni_tio_handle_interrupt(struct ni_gpct *counter,
+	struct comedi_subdevice * s);
+extern void ni_tio_set_mite_channel(struct ni_gpct *counter,
+	struct mite_channel *mite_chan);
+extern void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter,
+	int *gate_error, int *tc_error, int *perm_stale_data, int *stale_data);
+
+static inline struct ni_gpct *subdev_to_counter(struct comedi_subdevice * s)
+{
+	return s->private;
+}
+
+#endif /* _COMEDI_NI_TIO_H */
diff --git a/drivers/staging/comedi/drivers/ni_tio_internal.h b/drivers/staging/comedi/drivers/ni_tio_internal.h
new file mode 100644
index 0000000..ac5b171
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_tio_internal.h
@@ -0,0 +1,774 @@
+/*
+    drivers/ni_tio_internal.h
+    Header file for NI general purpose counter support code (ni_tio.c and
+    ni_tiocmd.c)
+
+    COMEDI - Linux Control and Measurement Device Interface
+
+    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.
+
+*/
+
+#ifndef _COMEDI_NI_TIO_INTERNAL_H
+#define _COMEDI_NI_TIO_INTERNAL_H
+
+#include "ni_tio.h"
+
+static inline enum ni_gpct_register NITIO_Gi_Autoincrement_Reg(unsigned
+	counter_index)
+{
+	switch (counter_index) {
+	case 0:
+		return NITIO_G0_Autoincrement_Reg;
+		break;
+	case 1:
+		return NITIO_G1_Autoincrement_Reg;
+		break;
+	case 2:
+		return NITIO_G2_Autoincrement_Reg;
+		break;
+	case 3:
+		return NITIO_G3_Autoincrement_Reg;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_Command_Reg(unsigned counter_index)
+{
+	switch (counter_index) {
+	case 0:
+		return NITIO_G0_Command_Reg;
+		break;
+	case 1:
+		return NITIO_G1_Command_Reg;
+		break;
+	case 2:
+		return NITIO_G2_Command_Reg;
+		break;
+	case 3:
+		return NITIO_G3_Command_Reg;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_Counting_Mode_Reg(unsigned
+	counter_index)
+{
+	switch (counter_index) {
+	case 0:
+		return NITIO_G0_Counting_Mode_Reg;
+		break;
+	case 1:
+		return NITIO_G1_Counting_Mode_Reg;
+		break;
+	case 2:
+		return NITIO_G2_Counting_Mode_Reg;
+		break;
+	case 3:
+		return NITIO_G3_Counting_Mode_Reg;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_Input_Select_Reg(unsigned
+	counter_index)
+{
+	switch (counter_index) {
+	case 0:
+		return NITIO_G0_Input_Select_Reg;
+		break;
+	case 1:
+		return NITIO_G1_Input_Select_Reg;
+		break;
+	case 2:
+		return NITIO_G2_Input_Select_Reg;
+		break;
+	case 3:
+		return NITIO_G3_Input_Select_Reg;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gxx_Joint_Reset_Reg(unsigned
+	counter_index)
+{
+	switch (counter_index) {
+	case 0:
+	case 1:
+		return NITIO_G01_Joint_Reset_Reg;
+		break;
+	case 2:
+	case 3:
+		return NITIO_G23_Joint_Reset_Reg;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gxx_Joint_Status1_Reg(unsigned
+	counter_index)
+{
+	switch (counter_index) {
+	case 0:
+	case 1:
+		return NITIO_G01_Joint_Status1_Reg;
+		break;
+	case 2:
+	case 3:
+		return NITIO_G23_Joint_Status1_Reg;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gxx_Joint_Status2_Reg(unsigned
+	counter_index)
+{
+	switch (counter_index) {
+	case 0:
+	case 1:
+		return NITIO_G01_Joint_Status2_Reg;
+		break;
+	case 2:
+	case 3:
+		return NITIO_G23_Joint_Status2_Reg;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gxx_Status_Reg(unsigned counter_index)
+{
+	switch (counter_index) {
+	case 0:
+	case 1:
+		return NITIO_G01_Status_Reg;
+		break;
+	case 2:
+	case 3:
+		return NITIO_G23_Status_Reg;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_LoadA_Reg(unsigned counter_index)
+{
+	switch (counter_index) {
+	case 0:
+		return NITIO_G0_LoadA_Reg;
+		break;
+	case 1:
+		return NITIO_G1_LoadA_Reg;
+		break;
+	case 2:
+		return NITIO_G2_LoadA_Reg;
+		break;
+	case 3:
+		return NITIO_G3_LoadA_Reg;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_LoadB_Reg(unsigned counter_index)
+{
+	switch (counter_index) {
+	case 0:
+		return NITIO_G0_LoadB_Reg;
+		break;
+	case 1:
+		return NITIO_G1_LoadB_Reg;
+		break;
+	case 2:
+		return NITIO_G2_LoadB_Reg;
+		break;
+	case 3:
+		return NITIO_G3_LoadB_Reg;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_Mode_Reg(unsigned counter_index)
+{
+	switch (counter_index) {
+	case 0:
+		return NITIO_G0_Mode_Reg;
+		break;
+	case 1:
+		return NITIO_G1_Mode_Reg;
+		break;
+	case 2:
+		return NITIO_G2_Mode_Reg;
+		break;
+	case 3:
+		return NITIO_G3_Mode_Reg;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_SW_Save_Reg(int counter_index)
+{
+	switch (counter_index) {
+	case 0:
+		return NITIO_G0_SW_Save_Reg;
+		break;
+	case 1:
+		return NITIO_G1_SW_Save_Reg;
+		break;
+	case 2:
+		return NITIO_G2_SW_Save_Reg;
+		break;
+	case 3:
+		return NITIO_G3_SW_Save_Reg;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_Second_Gate_Reg(int counter_index)
+{
+	switch (counter_index) {
+	case 0:
+		return NITIO_G0_Second_Gate_Reg;
+		break;
+	case 1:
+		return NITIO_G1_Second_Gate_Reg;
+		break;
+	case 2:
+		return NITIO_G2_Second_Gate_Reg;
+		break;
+	case 3:
+		return NITIO_G3_Second_Gate_Reg;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_DMA_Config_Reg(int counter_index)
+{
+	switch (counter_index) {
+	case 0:
+		return NITIO_G0_DMA_Config_Reg;
+		break;
+	case 1:
+		return NITIO_G1_DMA_Config_Reg;
+		break;
+	case 2:
+		return NITIO_G2_DMA_Config_Reg;
+		break;
+	case 3:
+		return NITIO_G3_DMA_Config_Reg;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_DMA_Status_Reg(int counter_index)
+{
+	switch (counter_index) {
+	case 0:
+		return NITIO_G0_DMA_Status_Reg;
+		break;
+	case 1:
+		return NITIO_G1_DMA_Status_Reg;
+		break;
+	case 2:
+		return NITIO_G2_DMA_Status_Reg;
+		break;
+	case 3:
+		return NITIO_G3_DMA_Status_Reg;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_ABZ_Reg(int counter_index)
+{
+	switch (counter_index) {
+	case 0:
+		return NITIO_G0_ABZ_Reg;
+		break;
+	case 1:
+		return NITIO_G1_ABZ_Reg;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_Interrupt_Acknowledge_Reg(int
+	counter_index)
+{
+	switch (counter_index) {
+	case 0:
+		return NITIO_G0_Interrupt_Acknowledge_Reg;
+		break;
+	case 1:
+		return NITIO_G1_Interrupt_Acknowledge_Reg;
+		break;
+	case 2:
+		return NITIO_G2_Interrupt_Acknowledge_Reg;
+		break;
+	case 3:
+		return NITIO_G3_Interrupt_Acknowledge_Reg;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_Status_Reg(int counter_index)
+{
+	switch (counter_index) {
+	case 0:
+		return NITIO_G0_Status_Reg;
+		break;
+	case 1:
+		return NITIO_G1_Status_Reg;
+		break;
+	case 2:
+		return NITIO_G2_Status_Reg;
+		break;
+	case 3:
+		return NITIO_G3_Status_Reg;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_Interrupt_Enable_Reg(int
+	counter_index)
+{
+	switch (counter_index) {
+	case 0:
+		return NITIO_G0_Interrupt_Enable_Reg;
+		break;
+	case 1:
+		return NITIO_G1_Interrupt_Enable_Reg;
+		break;
+	case 2:
+		return NITIO_G2_Interrupt_Enable_Reg;
+		break;
+	case 3:
+		return NITIO_G3_Interrupt_Enable_Reg;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+
+enum Gi_Auto_Increment_Reg_Bits {
+	Gi_Auto_Increment_Mask = 0xff
+};
+
+#define Gi_Up_Down_Shift 5
+enum Gi_Command_Reg_Bits {
+	Gi_Arm_Bit = 0x1,
+	Gi_Save_Trace_Bit = 0x2,
+	Gi_Load_Bit = 0x4,
+	Gi_Disarm_Bit = 0x10,
+	Gi_Up_Down_Mask = 0x3 << Gi_Up_Down_Shift,
+	Gi_Always_Down_Bits = 0x0 << Gi_Up_Down_Shift,
+	Gi_Always_Up_Bits = 0x1 << Gi_Up_Down_Shift,
+	Gi_Up_Down_Hardware_IO_Bits = 0x2 << Gi_Up_Down_Shift,
+	Gi_Up_Down_Hardware_Gate_Bits = 0x3 << Gi_Up_Down_Shift,
+	Gi_Write_Switch_Bit = 0x80,
+	Gi_Synchronize_Gate_Bit = 0x100,
+	Gi_Little_Big_Endian_Bit = 0x200,
+	Gi_Bank_Switch_Start_Bit = 0x400,
+	Gi_Bank_Switch_Mode_Bit = 0x800,
+	Gi_Bank_Switch_Enable_Bit = 0x1000,
+	Gi_Arm_Copy_Bit = 0x2000,
+	Gi_Save_Trace_Copy_Bit = 0x4000,
+	Gi_Disarm_Copy_Bit = 0x8000
+};
+
+#define Gi_Index_Phase_Bitshift 5
+#define Gi_HW_Arm_Select_Shift 8
+enum Gi_Counting_Mode_Reg_Bits {
+	Gi_Counting_Mode_Mask = 0x7,
+	Gi_Counting_Mode_Normal_Bits = 0x0,
+	Gi_Counting_Mode_QuadratureX1_Bits = 0x1,
+	Gi_Counting_Mode_QuadratureX2_Bits = 0x2,
+	Gi_Counting_Mode_QuadratureX4_Bits = 0x3,
+	Gi_Counting_Mode_Two_Pulse_Bits = 0x4,
+	Gi_Counting_Mode_Sync_Source_Bits = 0x6,
+	Gi_Index_Mode_Bit = 0x10,
+	Gi_Index_Phase_Mask = 0x3 << Gi_Index_Phase_Bitshift,
+	Gi_Index_Phase_LowA_LowB = 0x0 << Gi_Index_Phase_Bitshift,
+	Gi_Index_Phase_LowA_HighB = 0x1 << Gi_Index_Phase_Bitshift,
+	Gi_Index_Phase_HighA_LowB = 0x2 << Gi_Index_Phase_Bitshift,
+	Gi_Index_Phase_HighA_HighB = 0x3 << Gi_Index_Phase_Bitshift,
+	Gi_HW_Arm_Enable_Bit = 0x80,	/* from m-series example code, not documented in 660x register level manual */
+	Gi_660x_HW_Arm_Select_Mask = 0x7 << Gi_HW_Arm_Select_Shift,	/* from m-series example code, not documented in 660x register level manual */
+	Gi_660x_Prescale_X8_Bit = 0x1000,
+	Gi_M_Series_Prescale_X8_Bit = 0x2000,
+	Gi_M_Series_HW_Arm_Select_Mask = 0x1f << Gi_HW_Arm_Select_Shift,
+	/* must be set for clocks over 40MHz, which includes synchronous counting and quadrature modes */
+	Gi_660x_Alternate_Sync_Bit = 0x2000,
+	Gi_M_Series_Alternate_Sync_Bit = 0x4000,
+	Gi_660x_Prescale_X2_Bit = 0x4000,	/* from m-series example code, not documented in 660x register level manual */
+	Gi_M_Series_Prescale_X2_Bit = 0x8000,
+};
+
+#define Gi_Source_Select_Shift 2
+#define Gi_Gate_Select_Shift 7
+enum Gi_Input_Select_Bits {
+	Gi_Read_Acknowledges_Irq = 0x1,	// not present on 660x
+	Gi_Write_Acknowledges_Irq = 0x2,	// not present on 660x
+	Gi_Source_Select_Mask = 0x7c,
+	Gi_Gate_Select_Mask = 0x1f << Gi_Gate_Select_Shift,
+	Gi_Gate_Select_Load_Source_Bit = 0x1000,
+	Gi_Or_Gate_Bit = 0x2000,
+	Gi_Output_Polarity_Bit = 0x4000,	/* set to invert */
+	Gi_Source_Polarity_Bit = 0x8000	/* set to invert */
+};
+
+enum Gi_Mode_Bits {
+	Gi_Gating_Mode_Mask = 0x3,
+	Gi_Gating_Disabled_Bits = 0x0,
+	Gi_Level_Gating_Bits = 0x1,
+	Gi_Rising_Edge_Gating_Bits = 0x2,
+	Gi_Falling_Edge_Gating_Bits = 0x3,
+	Gi_Gate_On_Both_Edges_Bit = 0x4,	/* used in conjunction with rising edge gating mode */
+	Gi_Trigger_Mode_for_Edge_Gate_Mask = 0x18,
+	Gi_Edge_Gate_Starts_Stops_Bits = 0x0,
+	Gi_Edge_Gate_Stops_Starts_Bits = 0x8,
+	Gi_Edge_Gate_Starts_Bits = 0x10,
+	Gi_Edge_Gate_No_Starts_or_Stops_Bits = 0x18,
+	Gi_Stop_Mode_Mask = 0x60,
+	Gi_Stop_on_Gate_Bits = 0x00,
+	Gi_Stop_on_Gate_or_TC_Bits = 0x20,
+	Gi_Stop_on_Gate_or_Second_TC_Bits = 0x40,
+	Gi_Load_Source_Select_Bit = 0x80,
+	Gi_Output_Mode_Mask = 0x300,
+	Gi_Output_TC_Pulse_Bits = 0x100,
+	Gi_Output_TC_Toggle_Bits = 0x200,
+	Gi_Output_TC_or_Gate_Toggle_Bits = 0x300,
+	Gi_Counting_Once_Mask = 0xc00,
+	Gi_No_Hardware_Disarm_Bits = 0x000,
+	Gi_Disarm_at_TC_Bits = 0x400,
+	Gi_Disarm_at_Gate_Bits = 0x800,
+	Gi_Disarm_at_TC_or_Gate_Bits = 0xc00,
+	Gi_Loading_On_TC_Bit = 0x1000,
+	Gi_Gate_Polarity_Bit = 0x2000,
+	Gi_Loading_On_Gate_Bit = 0x4000,
+	Gi_Reload_Source_Switching_Bit = 0x8000
+};
+
+#define Gi_Second_Gate_Select_Shift 7
+/*FIXME: m-series has a second gate subselect bit */
+/*FIXME: m-series second gate sources are undocumented (by NI)*/
+enum Gi_Second_Gate_Bits {
+	Gi_Second_Gate_Mode_Bit = 0x1,
+	Gi_Second_Gate_Select_Mask = 0x1f << Gi_Second_Gate_Select_Shift,
+	Gi_Second_Gate_Polarity_Bit = 0x2000,
+	Gi_Second_Gate_Subselect_Bit = 0x4000,	/* m-series only */
+	Gi_Source_Subselect_Bit = 0x8000	/* m-series only */
+};
+static inline unsigned Gi_Second_Gate_Select_Bits(unsigned second_gate_select)
+{
+	return (second_gate_select << Gi_Second_Gate_Select_Shift) &
+		Gi_Second_Gate_Select_Mask;
+}
+
+enum Gxx_Status_Bits {
+	G0_Save_Bit = 0x1,
+	G1_Save_Bit = 0x2,
+	G0_Counting_Bit = 0x4,
+	G1_Counting_Bit = 0x8,
+	G0_Next_Load_Source_Bit = 0x10,
+	G1_Next_Load_Source_Bit = 0x20,
+	G0_Stale_Data_Bit = 0x40,
+	G1_Stale_Data_Bit = 0x80,
+	G0_Armed_Bit = 0x100,
+	G1_Armed_Bit = 0x200,
+	G0_No_Load_Between_Gates_Bit = 0x400,
+	G1_No_Load_Between_Gates_Bit = 0x800,
+	G0_TC_Error_Bit = 0x1000,
+	G1_TC_Error_Bit = 0x2000,
+	G0_Gate_Error_Bit = 0x4000,
+	G1_Gate_Error_Bit = 0x8000
+};
+static inline enum Gxx_Status_Bits Gi_Counting_Bit(unsigned counter_index)
+{
+	if (counter_index % 2)
+		return G1_Counting_Bit;
+	return G0_Counting_Bit;
+}
+static inline enum Gxx_Status_Bits Gi_Armed_Bit(unsigned counter_index)
+{
+	if (counter_index % 2)
+		return G1_Armed_Bit;
+	return G0_Armed_Bit;
+}
+static inline enum Gxx_Status_Bits Gi_Next_Load_Source_Bit(unsigned
+	counter_index)
+{
+	if (counter_index % 2)
+		return G1_Next_Load_Source_Bit;
+	return G0_Next_Load_Source_Bit;
+}
+static inline enum Gxx_Status_Bits Gi_Stale_Data_Bit(unsigned counter_index)
+{
+	if (counter_index % 2)
+		return G1_Stale_Data_Bit;
+	return G0_Stale_Data_Bit;
+}
+static inline enum Gxx_Status_Bits Gi_TC_Error_Bit(unsigned counter_index)
+{
+	if (counter_index % 2)
+		return G1_TC_Error_Bit;
+	return G0_TC_Error_Bit;
+}
+static inline enum Gxx_Status_Bits Gi_Gate_Error_Bit(unsigned counter_index)
+{
+	if (counter_index % 2)
+		return G1_Gate_Error_Bit;
+	return G0_Gate_Error_Bit;
+}
+
+/* joint reset register bits */
+static inline unsigned Gi_Reset_Bit(unsigned counter_index)
+{
+	return 0x1 << (2 + (counter_index % 2));
+}
+
+enum Gxx_Joint_Status2_Bits {
+	G0_Output_Bit = 0x1,
+	G1_Output_Bit = 0x2,
+	G0_HW_Save_Bit = 0x1000,
+	G1_HW_Save_Bit = 0x2000,
+	G0_Permanent_Stale_Bit = 0x4000,
+	G1_Permanent_Stale_Bit = 0x8000
+};
+static inline enum Gxx_Joint_Status2_Bits Gi_Permanent_Stale_Bit(unsigned
+	counter_index)
+{
+	if (counter_index % 2)
+		return G1_Permanent_Stale_Bit;
+	return G0_Permanent_Stale_Bit;
+}
+
+enum Gi_DMA_Config_Reg_Bits {
+	Gi_DMA_Enable_Bit = 0x1,
+	Gi_DMA_Write_Bit = 0x2,
+	Gi_DMA_Int_Bit = 0x4
+};
+
+enum Gi_DMA_Status_Reg_Bits {
+	Gi_DMA_Readbank_Bit = 0x2000,
+	Gi_DRQ_Error_Bit = 0x4000,
+	Gi_DRQ_Status_Bit = 0x8000
+};
+
+enum G02_Interrupt_Acknowledge_Bits {
+	G0_Gate_Error_Confirm_Bit = 0x20,
+	G0_TC_Error_Confirm_Bit = 0x40
+};
+enum G13_Interrupt_Acknowledge_Bits {
+	G1_Gate_Error_Confirm_Bit = 0x2,
+	G1_TC_Error_Confirm_Bit = 0x4
+};
+static inline unsigned Gi_Gate_Error_Confirm_Bit(unsigned counter_index)
+{
+	if (counter_index % 2)
+		return G1_Gate_Error_Confirm_Bit;
+	return G0_Gate_Error_Confirm_Bit;
+}
+static inline unsigned Gi_TC_Error_Confirm_Bit(unsigned counter_index)
+{
+	if (counter_index % 2)
+		return G1_TC_Error_Confirm_Bit;
+	return G0_TC_Error_Confirm_Bit;
+}
+
+// bits that are the same in G0/G2 and G1/G3 interrupt acknowledge registers
+enum Gxx_Interrupt_Acknowledge_Bits {
+	Gi_TC_Interrupt_Ack_Bit = 0x4000,
+	Gi_Gate_Interrupt_Ack_Bit = 0x8000
+};
+
+enum Gi_Status_Bits {
+	Gi_Gate_Interrupt_Bit = 0x4,
+	Gi_TC_Bit = 0x8,
+	Gi_Interrupt_Bit = 0x8000
+};
+
+enum G02_Interrupt_Enable_Bits {
+	G0_TC_Interrupt_Enable_Bit = 0x40,
+	G0_Gate_Interrupt_Enable_Bit = 0x100
+};
+enum G13_Interrupt_Enable_Bits {
+	G1_TC_Interrupt_Enable_Bit = 0x200,
+	G1_Gate_Interrupt_Enable_Bit = 0x400
+};
+static inline unsigned Gi_Gate_Interrupt_Enable_Bit(unsigned counter_index)
+{
+	unsigned bit;
+
+	if (counter_index % 2) {
+		bit = G1_Gate_Interrupt_Enable_Bit;
+	} else {
+		bit = G0_Gate_Interrupt_Enable_Bit;
+	}
+	return bit;
+}
+
+static inline void write_register(struct ni_gpct *counter, unsigned bits,
+	enum ni_gpct_register reg)
+{
+	BUG_ON(reg >= NITIO_Num_Registers);
+	counter->counter_dev->write_register(counter, bits, reg);
+}
+
+static inline unsigned read_register(struct ni_gpct *counter,
+	enum ni_gpct_register reg)
+{
+	BUG_ON(reg >= NITIO_Num_Registers);
+	return counter->counter_dev->read_register(counter, reg);
+}
+
+static inline int ni_tio_counting_mode_registers_present(
+	const struct ni_gpct_device *counter_dev)
+{
+	switch (counter_dev->variant) {
+	case ni_gpct_variant_e_series:
+		return 0;
+		break;
+	case ni_gpct_variant_m_series:
+	case ni_gpct_variant_660x:
+		return 1;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return 0;
+}
+
+static inline void ni_tio_set_bits_transient(struct ni_gpct *counter,
+	enum ni_gpct_register register_index, unsigned bit_mask,
+	unsigned bit_values, unsigned transient_bit_values)
+{
+	struct ni_gpct_device *counter_dev = counter->counter_dev;
+	unsigned long flags;
+
+	BUG_ON(register_index >= NITIO_Num_Registers);
+	comedi_spin_lock_irqsave(&counter_dev->regs_lock, flags);
+	counter_dev->regs[register_index] &= ~bit_mask;
+	counter_dev->regs[register_index] |= (bit_values & bit_mask);
+	write_register(counter,
+		counter_dev->regs[register_index] | transient_bit_values,
+		register_index);
+	mmiowb();
+	comedi_spin_unlock_irqrestore(&counter_dev->regs_lock, flags);
+}
+
+/* ni_tio_set_bits( ) is for safely writing to registers whose bits may be
+twiddled in interrupt context, or whose software copy may be read in interrupt context.
+*/
+static inline void ni_tio_set_bits(struct ni_gpct *counter,
+	enum ni_gpct_register register_index, unsigned bit_mask,
+	unsigned bit_values)
+{
+	ni_tio_set_bits_transient(counter, register_index, bit_mask, bit_values,
+		0x0);
+}
+
+/* ni_tio_get_soft_copy( ) is for safely reading the software copy of a register
+whose bits might be modified in interrupt context, or whose software copy
+might need to be read in interrupt context.
+*/
+static inline unsigned ni_tio_get_soft_copy(const struct ni_gpct *counter,
+	enum ni_gpct_register register_index)
+{
+	struct ni_gpct_device *counter_dev = counter->counter_dev;
+	unsigned long flags;
+	unsigned value;
+
+	BUG_ON(register_index >= NITIO_Num_Registers);
+	comedi_spin_lock_irqsave(&counter_dev->regs_lock, flags);
+	value = counter_dev->regs[register_index];
+	comedi_spin_unlock_irqrestore(&counter_dev->regs_lock, flags);
+	return value;
+}
+
+int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger);
+int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned gate_index,
+	unsigned int gate_source);
+
+#endif /* _COMEDI_NI_TIO_INTERNAL_H */
diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c
new file mode 100644
index 0000000..16a26e7
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_tiocmd.c
@@ -0,0 +1,523 @@
+/*
+  comedi/drivers/ni_tiocmd.c
+  Command support for NI general purpose counters
+
+  Copyright (C) 2006 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+  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.
+*/
+
+/*
+Driver: ni_tiocmd
+Description: National Instruments general purpose counters command support
+Devices:
+Author: J.P. Mellor <jpmellor@rose-hulman.edu>,
+	Herman.Bruyninckx@mech.kuleuven.ac.be,
+	Wim.Meeussen@mech.kuleuven.ac.be,
+	Klaas.Gadeyne@mech.kuleuven.ac.be,
+	Frank Mori Hess <fmhess@users.sourceforge.net>
+Updated: Fri, 11 Apr 2008 12:32:35 +0100
+Status: works
+
+This module is not used directly by end-users.  Rather, it
+is used by other drivers (for example ni_660x and ni_pcimio)
+to provide command support for NI's general purpose counters.
+It was originally split out of ni_tio.c to stop the 'ni_tio'
+module depending on the 'mite' module.
+
+References:
+DAQ 660x Register-Level Programmer Manual  (NI 370505A-01)
+DAQ 6601/6602 User Manual (NI 322137B-01)
+340934b.pdf  DAQ-STC reference manual
+
+*/
+/*
+TODO:
+	Support use of both banks X and Y
+*/
+
+#include "ni_tio_internal.h"
+#include "mite.h"
+
+MODULE_AUTHOR("Comedi <comedi@comedi.org>");
+MODULE_DESCRIPTION("Comedi command support for NI general-purpose counters");
+MODULE_LICENSE("GPL");
+
+static void ni_tio_configure_dma(struct ni_gpct *counter, short enable,
+	short read_not_write)
+{
+	struct ni_gpct_device *counter_dev = counter->counter_dev;
+	unsigned input_select_bits = 0;
+
+	if (enable) {
+		if (read_not_write) {
+			input_select_bits |= Gi_Read_Acknowledges_Irq;
+		} else {
+			input_select_bits |= Gi_Write_Acknowledges_Irq;
+		}
+	}
+	ni_tio_set_bits(counter,
+		NITIO_Gi_Input_Select_Reg(counter->counter_index),
+		Gi_Read_Acknowledges_Irq | Gi_Write_Acknowledges_Irq,
+		input_select_bits);
+	switch (counter_dev->variant) {
+	case ni_gpct_variant_e_series:
+		break;
+	case ni_gpct_variant_m_series:
+	case ni_gpct_variant_660x:
+		{
+			unsigned gi_dma_config_bits = 0;
+
+			if (enable) {
+				gi_dma_config_bits |= Gi_DMA_Enable_Bit;
+				gi_dma_config_bits |= Gi_DMA_Int_Bit;
+			}
+			if (read_not_write == 0) {
+				gi_dma_config_bits |= Gi_DMA_Write_Bit;
+			}
+			ni_tio_set_bits(counter,
+				NITIO_Gi_DMA_Config_Reg(counter->counter_index),
+				Gi_DMA_Enable_Bit | Gi_DMA_Int_Bit |
+				Gi_DMA_Write_Bit, gi_dma_config_bits);
+		}
+		break;
+	}
+}
+
+static int ni_tio_input_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int trignum)
+{
+	unsigned long flags;
+	int retval = 0;
+	struct ni_gpct *counter = s->private;
+
+	BUG_ON(counter == NULL);
+	if (trignum != 0)
+		return -EINVAL;
+
+	comedi_spin_lock_irqsave(&counter->lock, flags);
+	if (counter->mite_chan)
+		mite_dma_arm(counter->mite_chan);
+	else
+		retval = -EIO;
+	comedi_spin_unlock_irqrestore(&counter->lock, flags);
+	if (retval < 0)
+		return retval;
+	retval = ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE);
+	s->async->inttrig = NULL;
+
+	return retval;
+}
+
+static int ni_tio_input_cmd(struct ni_gpct *counter, struct comedi_async *async)
+{
+	struct ni_gpct_device *counter_dev = counter->counter_dev;
+	struct comedi_cmd *cmd = &async->cmd;
+	int retval = 0;
+
+	/* write alloc the entire buffer */
+	comedi_buf_write_alloc(async, async->prealloc_bufsz);
+	counter->mite_chan->dir = COMEDI_INPUT;
+	switch (counter_dev->variant) {
+	case ni_gpct_variant_m_series:
+	case ni_gpct_variant_660x:
+		mite_prep_dma(counter->mite_chan, 32, 32);
+		break;
+	case ni_gpct_variant_e_series:
+		mite_prep_dma(counter->mite_chan, 16, 32);
+		break;
+	default:
+		BUG();
+		break;
+	}
+	ni_tio_set_bits(counter, NITIO_Gi_Command_Reg(counter->counter_index),
+		Gi_Save_Trace_Bit, 0);
+	ni_tio_configure_dma(counter, 1, 1);
+	switch (cmd->start_src) {
+	case TRIG_NOW:
+		async->inttrig = NULL;
+		mite_dma_arm(counter->mite_chan);
+		retval = ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE);
+		break;
+	case TRIG_INT:
+		async->inttrig = &ni_tio_input_inttrig;
+		break;
+	case TRIG_EXT:
+		async->inttrig = NULL;
+		mite_dma_arm(counter->mite_chan);
+		retval = ni_tio_arm(counter, 1, cmd->start_arg);
+	case TRIG_OTHER:
+		async->inttrig = NULL;
+		mite_dma_arm(counter->mite_chan);
+		break;
+	default:
+		BUG();
+		break;
+	}
+	return retval;
+}
+
+static int ni_tio_output_cmd(struct ni_gpct *counter, struct comedi_async *async)
+{
+	rt_printk("ni_tio: output commands not yet implemented.\n");
+	return -ENOTSUPP;
+
+	counter->mite_chan->dir = COMEDI_OUTPUT;
+	mite_prep_dma(counter->mite_chan, 32, 32);
+	ni_tio_configure_dma(counter, 1, 0);
+	mite_dma_arm(counter->mite_chan);
+	return ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE);
+}
+
+static int ni_tio_cmd_setup(struct ni_gpct *counter, struct comedi_async *async)
+{
+	struct comedi_cmd *cmd = &async->cmd;
+	int set_gate_source = 0;
+	unsigned gate_source;
+	int retval = 0;
+
+	if (cmd->scan_begin_src == TRIG_EXT) {
+		set_gate_source = 1;
+		gate_source = cmd->scan_begin_arg;
+	} else if (cmd->convert_src == TRIG_EXT) {
+		set_gate_source = 1;
+		gate_source = cmd->convert_arg;
+	}
+	if (set_gate_source) {
+		retval = ni_tio_set_gate_src(counter, 0, gate_source);
+	}
+	if (cmd->flags & TRIG_WAKE_EOS) {
+		ni_tio_set_bits(counter,
+			NITIO_Gi_Interrupt_Enable_Reg(counter->counter_index),
+			Gi_Gate_Interrupt_Enable_Bit(counter->counter_index),
+			Gi_Gate_Interrupt_Enable_Bit(counter->counter_index));
+	}
+	return retval;
+}
+
+int ni_tio_cmd(struct ni_gpct *counter, struct comedi_async *async)
+{
+	struct comedi_cmd *cmd = &async->cmd;
+	int retval = 0;
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&counter->lock, flags);
+	if (counter->mite_chan == NULL) {
+		rt_printk
+			("ni_tio: commands only supported with DMA.  Interrupt-driven commands not yet implemented.\n");
+		retval = -EIO;
+	} else {
+		retval = ni_tio_cmd_setup(counter, async);
+		if (retval == 0) {
+			if (cmd->flags & CMDF_WRITE) {
+				retval = ni_tio_output_cmd(counter, async);
+			} else {
+				retval = ni_tio_input_cmd(counter, async);
+			}
+		}
+	}
+	comedi_spin_unlock_irqrestore(&counter->lock, flags);
+	return retval;
+}
+
+int ni_tio_cmdtest(struct ni_gpct *counter, struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp;
+	int sources;
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	sources = TRIG_NOW | TRIG_INT | TRIG_OTHER;
+	if (ni_tio_counting_mode_registers_present(counter->counter_dev))
+		sources |= TRIG_EXT;
+	cmd->start_src &= sources;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_EXT | TRIG_OTHER;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	sources = TRIG_NOW | TRIG_EXT | TRIG_OTHER;
+	cmd->convert_src &= sources;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique... */
+
+	if (cmd->start_src != TRIG_NOW &&
+		cmd->start_src != TRIG_INT &&
+		cmd->start_src != TRIG_EXT && cmd->start_src != TRIG_OTHER)
+		err++;
+	if (cmd->scan_begin_src != TRIG_FOLLOW &&
+		cmd->scan_begin_src != TRIG_EXT &&
+		cmd->scan_begin_src != TRIG_OTHER)
+		err++;
+	if (cmd->convert_src != TRIG_OTHER &&
+		cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
+		err++;
+	if (cmd->stop_src != TRIG_NONE)
+		err++;
+	/* ... and mutually compatible */
+	if (cmd->convert_src != TRIG_NOW && cmd->scan_begin_src != TRIG_FOLLOW)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+	if (cmd->start_src != TRIG_EXT) {
+		if (cmd->start_arg != 0) {
+			cmd->start_arg = 0;
+			err++;
+		}
+	}
+	if (cmd->scan_begin_src != TRIG_EXT) {
+		if (cmd->scan_begin_arg) {
+			cmd->scan_begin_arg = 0;
+			err++;
+		}
+	}
+	if (cmd->convert_src != TRIG_EXT) {
+		if (cmd->convert_arg) {
+			cmd->convert_arg = 0;
+			err++;
+		}
+	}
+
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+
+	if (cmd->stop_src == TRIG_NONE) {
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	if (err)
+		return 4;
+
+	return 0;
+}
+
+int ni_tio_cancel(struct ni_gpct *counter)
+{
+	unsigned long flags;
+
+	ni_tio_arm(counter, 0, 0);
+	comedi_spin_lock_irqsave(&counter->lock, flags);
+	if (counter->mite_chan) {
+		mite_dma_disarm(counter->mite_chan);
+	}
+	comedi_spin_unlock_irqrestore(&counter->lock, flags);
+	ni_tio_configure_dma(counter, 0, 0);
+
+	ni_tio_set_bits(counter,
+		NITIO_Gi_Interrupt_Enable_Reg(counter->counter_index),
+		Gi_Gate_Interrupt_Enable_Bit(counter->counter_index), 0x0);
+	return 0;
+}
+
+	/* During buffered input counter operation for e-series, the gate interrupt is acked
+	   automatically by the dma controller, due to the Gi_Read/Write_Acknowledges_IRQ bits
+	   in the input select register.  */
+static int should_ack_gate(struct ni_gpct *counter)
+{
+	unsigned long flags;
+	int retval = 0;
+
+	switch (counter->counter_dev->variant) {
+	case ni_gpct_variant_m_series:
+	case ni_gpct_variant_660x:	// not sure if 660x really supports gate interrupts (the bits are not listed in register-level manual)
+		return 1;
+		break;
+	case ni_gpct_variant_e_series:
+		comedi_spin_lock_irqsave(&counter->lock, flags);
+		{
+			if (counter->mite_chan == NULL ||
+				counter->mite_chan->dir != COMEDI_INPUT ||
+				(mite_done(counter->mite_chan))) {
+				retval = 1;
+			}
+		}
+		comedi_spin_unlock_irqrestore(&counter->lock, flags);
+		break;
+	}
+	return retval;
+}
+
+void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error,
+	int *tc_error, int *perm_stale_data, int *stale_data)
+{
+	const unsigned short gxx_status = read_register(counter,
+		NITIO_Gxx_Status_Reg(counter->counter_index));
+	const unsigned short gi_status = read_register(counter,
+		NITIO_Gi_Status_Reg(counter->counter_index));
+	unsigned ack = 0;
+
+	if (gate_error)
+		*gate_error = 0;
+	if (tc_error)
+		*tc_error = 0;
+	if (perm_stale_data)
+		*perm_stale_data = 0;
+	if (stale_data)
+		*stale_data = 0;
+
+	if (gxx_status & Gi_Gate_Error_Bit(counter->counter_index)) {
+		ack |= Gi_Gate_Error_Confirm_Bit(counter->counter_index);
+		if (gate_error) {
+			/*660x don't support automatic acknowledgement of gate interrupt via dma read/write
+			   and report bogus gate errors */
+			if (counter->counter_dev->variant !=
+				ni_gpct_variant_660x) {
+				*gate_error = 1;
+			}
+		}
+	}
+	if (gxx_status & Gi_TC_Error_Bit(counter->counter_index)) {
+		ack |= Gi_TC_Error_Confirm_Bit(counter->counter_index);
+		if (tc_error)
+			*tc_error = 1;
+	}
+	if (gi_status & Gi_TC_Bit) {
+		ack |= Gi_TC_Interrupt_Ack_Bit;
+	}
+	if (gi_status & Gi_Gate_Interrupt_Bit) {
+		if (should_ack_gate(counter))
+			ack |= Gi_Gate_Interrupt_Ack_Bit;
+	}
+	if (ack)
+		write_register(counter, ack,
+			NITIO_Gi_Interrupt_Acknowledge_Reg(counter->
+				counter_index));
+	if (ni_tio_get_soft_copy(counter,
+			NITIO_Gi_Mode_Reg(counter->
+				counter_index)) & Gi_Loading_On_Gate_Bit) {
+		if (gxx_status & Gi_Stale_Data_Bit(counter->counter_index)) {
+			if (stale_data)
+				*stale_data = 1;
+		}
+		if (read_register(counter,
+				NITIO_Gxx_Joint_Status2_Reg(counter->
+					counter_index)) &
+			Gi_Permanent_Stale_Bit(counter->counter_index)) {
+			rt_printk("%s: Gi_Permanent_Stale_Data detected.\n",
+				__FUNCTION__);
+			if (perm_stale_data)
+				*perm_stale_data = 1;
+		}
+	}
+}
+
+void ni_tio_handle_interrupt(struct ni_gpct *counter, struct comedi_subdevice * s)
+{
+	unsigned gpct_mite_status;
+	unsigned long flags;
+	int gate_error;
+	int tc_error;
+	int perm_stale_data;
+
+	ni_tio_acknowledge_and_confirm(counter, &gate_error, &tc_error,
+		&perm_stale_data, NULL);
+	if (gate_error) {
+		rt_printk("%s: Gi_Gate_Error detected.\n", __FUNCTION__);
+		s->async->events |= COMEDI_CB_OVERFLOW;
+	}
+	if (perm_stale_data) {
+		s->async->events |= COMEDI_CB_ERROR;
+	}
+	switch (counter->counter_dev->variant) {
+	case ni_gpct_variant_m_series:
+	case ni_gpct_variant_660x:
+		if (read_register(counter,
+				NITIO_Gi_DMA_Status_Reg(counter->
+					counter_index)) & Gi_DRQ_Error_Bit) {
+			rt_printk("%s: Gi_DRQ_Error detected.\n", __FUNCTION__);
+			s->async->events |= COMEDI_CB_OVERFLOW;
+		}
+		break;
+	case ni_gpct_variant_e_series:
+		break;
+	}
+	comedi_spin_lock_irqsave(&counter->lock, flags);
+	if (counter->mite_chan == NULL) {
+		comedi_spin_unlock_irqrestore(&counter->lock, flags);
+		return;
+	}
+	gpct_mite_status = mite_get_status(counter->mite_chan);
+	if (gpct_mite_status & CHSR_LINKC) {
+		writel(CHOR_CLRLC,
+			counter->mite_chan->mite->mite_io_addr +
+			MITE_CHOR(counter->mite_chan->channel));
+	}
+	mite_sync_input_dma(counter->mite_chan, s->async);
+	comedi_spin_unlock_irqrestore(&counter->lock, flags);
+}
+
+void ni_tio_set_mite_channel(struct ni_gpct *counter,
+	struct mite_channel *mite_chan)
+{
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&counter->lock, flags);
+	counter->mite_chan = mite_chan;
+	comedi_spin_unlock_irqrestore(&counter->lock, flags);
+}
+
+static int __init ni_tiocmd_init_module(void)
+{
+	return 0;
+}
+
+module_init(ni_tiocmd_init_module);
+
+static void __exit ni_tiocmd_cleanup_module(void)
+{
+}
+
+module_exit(ni_tiocmd_cleanup_module);
+
+EXPORT_SYMBOL_GPL(ni_tio_cmd);
+EXPORT_SYMBOL_GPL(ni_tio_cmdtest);
+EXPORT_SYMBOL_GPL(ni_tio_cancel);
+EXPORT_SYMBOL_GPL(ni_tio_handle_interrupt);
+EXPORT_SYMBOL_GPL(ni_tio_set_mite_channel);
+EXPORT_SYMBOL_GPL(ni_tio_acknowledge_and_confirm);
diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c
new file mode 100644
index 0000000..ce42506
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcl711.c
@@ -0,0 +1,623 @@
+/*
+   comedi/drivers/pcl711.c
+   hardware driver for PC-LabCard PCL-711 and AdSys ACL-8112
+   and compatibles
+
+   COMEDI - Linux Control and Measurement Device Interface
+   Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+   Janne Jalkanen <jalkanen@cs.hut.fi>
+   Eric Bunn <ebu@cs.hut.fi>
+
+   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.
+
+ */
+/*
+Driver: pcl711
+Description: Advantech PCL-711 and 711b, ADLink ACL-8112
+Author: ds, Janne Jalkanen <jalkanen@cs.hut.fi>, Eric Bunn <ebu@cs.hut.fi>
+Status: mostly complete
+Devices: [Advantech] PCL-711 (pcl711), PCL-711B (pcl711b),
+  [AdLink] ACL-8112HG (acl8112hg), ACL-8112DG (acl8112dg)
+
+Since these boards do not have DMA or FIFOs, only immediate mode is
+supported.
+
+*/
+
+/*
+   Dave Andruczyk <dave@tech.buffalostate.edu> also wrote a
+   driver for the PCL-711.  I used a few ideas from his driver
+   here.  His driver also has more comments, if you are
+   interested in understanding how this driver works.
+   http://tech.buffalostate.edu/~dave/driver/
+
+   The ACL-8112 driver was hacked from the sources of the PCL-711
+   driver (the 744 chip used on the 8112 is almost the same as
+   the 711b chip, but it has more I/O channels) by
+   Janne Jalkanen (jalkanen@cs.hut.fi) and
+   Erik Bunn (ebu@cs.hut.fi).  Remerged with the PCL-711 driver
+   by ds.
+
+   [acl-8112]
+   This driver supports both TRIGNOW and TRIGCLK,
+   but does not yet support DMA transfers.  It also supports
+   both high (HG) and low (DG) versions of the card, though
+   the HG version has been untested.
+
+ */
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/delay.h>
+
+#include "8253.h"
+
+#define PCL711_SIZE 16
+
+#define PCL711_CTR0 0
+#define PCL711_CTR1 1
+#define PCL711_CTR2 2
+#define PCL711_CTRCTL 3
+#define PCL711_AD_LO 4
+#define PCL711_DA0_LO 4
+#define PCL711_AD_HI 5
+#define PCL711_DA0_HI 5
+#define PCL711_DI_LO 6
+#define PCL711_DA1_LO 6
+#define PCL711_DI_HI 7
+#define PCL711_DA1_HI 7
+#define PCL711_CLRINTR 8
+#define PCL711_GAIN 9
+#define PCL711_MUX 10
+#define PCL711_MODE 11
+#define PCL711_SOFTTRIG 12
+#define PCL711_DO_LO 13
+#define PCL711_DO_HI 14
+
+static const struct comedi_lrange range_pcl711b_ai = { 5, {
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+			BIP_RANGE(0.625),
+			BIP_RANGE(0.3125)
+	}
+};
+static const struct comedi_lrange range_acl8112hg_ai = { 12, {
+			BIP_RANGE(5),
+			BIP_RANGE(0.5),
+			BIP_RANGE(0.05),
+			BIP_RANGE(0.005),
+			UNI_RANGE(10),
+			UNI_RANGE(1),
+			UNI_RANGE(0.1),
+			UNI_RANGE(0.01),
+			BIP_RANGE(10),
+			BIP_RANGE(1),
+			BIP_RANGE(0.1),
+			BIP_RANGE(0.01)
+	}
+};
+static const struct comedi_lrange range_acl8112dg_ai = { 9, {
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+			BIP_RANGE(0.625),
+			UNI_RANGE(10),
+			UNI_RANGE(5),
+			UNI_RANGE(2.5),
+			UNI_RANGE(1.25),
+			BIP_RANGE(10)
+	}
+};
+
+/*
+ * flags
+ */
+
+#define PCL711_TIMEOUT 100
+#define PCL711_DRDY 0x10
+
+static const int i8253_osc_base = 500;	/* 2 Mhz */
+
+struct pcl711_board {
+
+	const char *name;
+	int is_pcl711b;
+	int is_8112;
+	int is_dg;
+	int n_ranges;
+	int n_aichan;
+	int n_aochan;
+	int maxirq;
+	const struct comedi_lrange *ai_range_type;
+};
+
+
+static const struct pcl711_board boardtypes[] = {
+	{"pcl711", 0, 0, 0, 5, 8, 1, 0, &range_bipolar5},
+	{"pcl711b", 1, 0, 0, 5, 8, 1, 7, &range_pcl711b_ai},
+	{"acl8112hg", 0, 1, 0, 12, 16, 2, 15, &range_acl8112hg_ai},
+	{"acl8112dg", 0, 1, 1, 9, 16, 2, 15, &range_acl8112dg_ai},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl711_board))
+#define this_board ((const struct pcl711_board *)dev->board_ptr)
+
+static int pcl711_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcl711_detach(struct comedi_device * dev);
+static struct comedi_driver driver_pcl711 = {
+      driver_name:"pcl711",
+      module:THIS_MODULE,
+      attach:pcl711_attach,
+      detach:pcl711_detach,
+      board_name:&boardtypes[0].name,
+      num_names:n_boardtypes,
+      offset:sizeof(struct pcl711_board),
+};
+
+COMEDI_INITCLEANUP(driver_pcl711);
+
+struct pcl711_private {
+
+	int board;
+	int adchan;
+	int ntrig;
+	int aip[8];
+	int mode;
+	unsigned int ao_readback[2];
+	unsigned int divisor1;
+	unsigned int divisor2;
+};
+
+
+#define devpriv ((struct pcl711_private *)dev->private)
+
+static irqreturn_t pcl711_interrupt(int irq, void *d PT_REGS_ARG)
+{
+	int lo, hi;
+	int data;
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s = dev->subdevices + 0;
+
+	if (!dev->attached) {
+		comedi_error(dev, "spurious interrupt");
+		return IRQ_HANDLED;
+	}
+
+	hi = inb(dev->iobase + PCL711_AD_HI);
+	lo = inb(dev->iobase + PCL711_AD_LO);
+	outb(0, dev->iobase + PCL711_CLRINTR);
+
+	data = (hi << 8) | lo;
+
+	/* FIXME! Nothing else sets ntrig! */
+	if (!(--devpriv->ntrig)) {
+		if (this_board->is_8112) {
+			outb(1, dev->iobase + PCL711_MODE);
+		} else {
+			outb(0, dev->iobase + PCL711_MODE);
+		}
+
+		s->async->events |= COMEDI_CB_EOA;
+	}
+	comedi_event(dev, s);
+	return IRQ_HANDLED;
+}
+
+static void pcl711_set_changain(struct comedi_device * dev, int chan)
+{
+	int chan_register;
+
+	outb(CR_RANGE(chan), dev->iobase + PCL711_GAIN);
+
+	chan_register = CR_CHAN(chan);
+
+	if (this_board->is_8112) {
+
+		/*
+		 *  Set the correct channel.  The two channel banks are switched
+		 *  using the mask value.
+		 *  NB: To use differential channels, you should use mask = 0x30,
+		 *  but I haven't written the support for this yet. /JJ
+		 */
+
+		if (chan_register >= 8) {
+			chan_register = 0x20 | (chan_register & 0x7);
+		} else {
+			chan_register |= 0x10;
+		}
+	} else {
+		outb(chan_register, dev->iobase + PCL711_MUX);
+	}
+}
+
+static int pcl711_ai_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i, n;
+	int hi, lo;
+
+	pcl711_set_changain(dev, insn->chanspec);
+
+	for (n = 0; n < insn->n; n++) {
+		/*
+		 *  Write the correct mode (software polling) and start polling by writing
+		 *  to the trigger register
+		 */
+		outb(1, dev->iobase + PCL711_MODE);
+
+		if (this_board->is_8112) {
+		} else {
+			outb(0, dev->iobase + PCL711_SOFTTRIG);
+		}
+
+		i = PCL711_TIMEOUT;
+		while (--i) {
+			hi = inb(dev->iobase + PCL711_AD_HI);
+			if (!(hi & PCL711_DRDY))
+				goto ok;
+			comedi_udelay(1);
+		}
+		rt_printk("comedi%d: pcl711: A/D timeout\n", dev->minor);
+		return -ETIME;
+
+	      ok:
+		lo = inb(dev->iobase + PCL711_AD_LO);
+
+		data[n] = ((hi & 0xf) << 8) | lo;
+	}
+
+	return n;
+}
+
+static int pcl711_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int tmp;
+	int err = 0;
+
+	/* step 1 */
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_NOW;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2 */
+
+	if (cmd->scan_begin_src != TRIG_TIMER &&
+		cmd->scan_begin_src != TRIG_EXT)
+		err++;
+	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3 */
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+	if (cmd->scan_begin_src == TRIG_EXT) {
+		if (cmd->scan_begin_arg != 0) {
+			cmd->scan_begin_arg = 0;
+			err++;
+		}
+	} else {
+#define MAX_SPEED 1000
+#define TIMER_BASE 100
+		if (cmd->scan_begin_arg < MAX_SPEED) {
+			cmd->scan_begin_arg = MAX_SPEED;
+			err++;
+		}
+	}
+	if (cmd->convert_arg != 0) {
+		cmd->convert_arg = 0;
+		err++;
+	}
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+	if (cmd->stop_src == TRIG_NONE) {
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	} else {
+		/* ignore */
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4 */
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		tmp = cmd->scan_begin_arg;
+		i8253_cascade_ns_to_timer_2div(TIMER_BASE,
+			&devpriv->divisor1, &devpriv->divisor2,
+			&cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK);
+		if (tmp != cmd->scan_begin_arg)
+			err++;
+	}
+
+	if (err)
+		return 4;
+
+	return 0;
+}
+
+static int pcl711_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	int timer1, timer2;
+	struct comedi_cmd *cmd = &s->async->cmd;
+
+	pcl711_set_changain(dev, cmd->chanlist[0]);
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		/*
+		 *  Set timers
+		 *      timer chip is an 8253, with timers 1 and 2
+		 *      cascaded
+		 *  0x74 = Select Counter 1 | LSB/MSB | Mode=2 | Binary
+		 *        Mode 2 = Rate generator
+		 *
+		 *  0xb4 = Select Counter 2 | LSB/MSB | Mode=2 | Binary
+		 */
+
+		i8253_cascade_ns_to_timer(i8253_osc_base, &timer1, &timer2,
+			&cmd->scan_begin_arg, TRIG_ROUND_NEAREST);
+
+		outb(0x74, dev->iobase + PCL711_CTRCTL);
+		outb(timer1 & 0xff, dev->iobase + PCL711_CTR1);
+		outb((timer1 >> 8) & 0xff, dev->iobase + PCL711_CTR1);
+		outb(0xb4, dev->iobase + PCL711_CTRCTL);
+		outb(timer2 & 0xff, dev->iobase + PCL711_CTR2);
+		outb((timer2 >> 8) & 0xff, dev->iobase + PCL711_CTR2);
+
+		/* clear pending interrupts (just in case) */
+		outb(0, dev->iobase + PCL711_CLRINTR);
+
+		/*
+		 *  Set mode to IRQ transfer
+		 */
+		outb(devpriv->mode | 6, dev->iobase + PCL711_MODE);
+	} else {
+		/* external trigger */
+		outb(devpriv->mode | 3, dev->iobase + PCL711_MODE);
+	}
+
+	return 0;
+}
+
+/*
+   analog output
+*/
+static int pcl711_ao_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n;
+	int chan = CR_CHAN(insn->chanspec);
+
+	for (n = 0; n < insn->n; n++) {
+		outb((data[n] & 0xff),
+			dev->iobase + (chan ? PCL711_DA1_LO : PCL711_DA0_LO));
+		outb((data[n] >> 8),
+			dev->iobase + (chan ? PCL711_DA1_HI : PCL711_DA0_HI));
+
+		devpriv->ao_readback[chan] = data[n];
+	}
+
+	return n;
+}
+
+static int pcl711_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n;
+	int chan = CR_CHAN(insn->chanspec);
+
+	for (n = 0; n < insn->n; n++) {
+		data[n] = devpriv->ao_readback[chan];
+	}
+
+	return n;
+
+}
+
+/* Digital port read - Untested on 8112 */
+static int pcl711_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	data[1] = inb(dev->iobase + PCL711_DI_LO) |
+		(inb(dev->iobase + PCL711_DI_HI) << 8);
+
+	return 2;
+}
+
+/* Digital port write - Untested on 8112 */
+static int pcl711_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= data[0] & data[1];
+	}
+	if (data[0] & 0x00ff)
+		outb(s->state & 0xff, dev->iobase + PCL711_DO_LO);
+	if (data[0] & 0xff00)
+		outb((s->state >> 8), dev->iobase + PCL711_DO_HI);
+
+	data[1] = s->state;
+
+	return 2;
+}
+
+/*  Free any resources that we have claimed  */
+static int pcl711_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: pcl711: remove\n", dev->minor);
+
+	if (dev->irq)
+		comedi_free_irq(dev->irq, dev);
+
+	if (dev->iobase)
+		release_region(dev->iobase, PCL711_SIZE);
+
+	return 0;
+}
+
+/*  Initialization */
+static int pcl711_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	int ret;
+	unsigned long iobase;
+	unsigned int irq;
+	struct comedi_subdevice *s;
+
+	/* claim our I/O space */
+
+	iobase = it->options[0];
+	printk("comedi%d: pcl711: 0x%04lx ", dev->minor, iobase);
+	if (!request_region(iobase, PCL711_SIZE, "pcl711")) {
+		printk("I/O port conflict\n");
+		return -EIO;
+	}
+	dev->iobase = iobase;
+
+	/* there should be a sanity check here */
+
+	/* set up some name stuff */
+	dev->board_name = this_board->name;
+
+	/* grab our IRQ */
+	irq = it->options[1];
+	if (irq > this_board->maxirq) {
+		printk("irq out of range\n");
+		return -EINVAL;
+	}
+	if (irq) {
+		if (comedi_request_irq(irq, pcl711_interrupt, 0, "pcl711", dev)) {
+			printk("unable to allocate irq %u\n", irq);
+			return -EINVAL;
+		} else {
+			printk("( irq = %u )\n", irq);
+		}
+	}
+	dev->irq = irq;
+
+	if ((ret = alloc_subdevices(dev, 4)) < 0)
+		return ret;
+	if ((ret = alloc_private(dev, sizeof(struct pcl711_private))) < 0)
+		return ret;
+
+	s = dev->subdevices + 0;
+	/* AI subdevice */
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE | SDF_GROUND;
+	s->n_chan = this_board->n_aichan;
+	s->maxdata = 0xfff;
+	s->len_chanlist = 1;
+	s->range_table = this_board->ai_range_type;
+	s->insn_read = pcl711_ai_insn;
+	if (irq) {
+		dev->read_subdev = s;
+		s->subdev_flags |= SDF_CMD_READ;
+		s->do_cmdtest = pcl711_ai_cmdtest;
+		s->do_cmd = pcl711_ai_cmd;
+	}
+
+	s++;
+	/* AO subdevice */
+	s->type = COMEDI_SUBD_AO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->n_chan = this_board->n_aochan;
+	s->maxdata = 0xfff;
+	s->len_chanlist = 1;
+	s->range_table = &range_bipolar5;
+	s->insn_write = pcl711_ao_insn;
+	s->insn_read = pcl711_ao_insn_read;
+
+	s++;
+	/* 16-bit digital input */
+	s->type = COMEDI_SUBD_DI;
+	s->subdev_flags = SDF_READABLE;
+	s->n_chan = 16;
+	s->maxdata = 1;
+	s->len_chanlist = 16;
+	s->range_table = &range_digital;
+	s->insn_bits = pcl711_di_insn_bits;
+
+	s++;
+	/* 16-bit digital out */
+	s->type = COMEDI_SUBD_DO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->n_chan = 16;
+	s->maxdata = 1;
+	s->len_chanlist = 16;
+	s->range_table = &range_digital;
+	s->state = 0;
+	s->insn_bits = pcl711_do_insn_bits;
+
+	/*
+	   this is the "base value" for the mode register, which is
+	   used for the irq on the PCL711
+	 */
+	if (this_board->is_pcl711b) {
+		devpriv->mode = (dev->irq << 4);
+	}
+
+	/* clear DAC */
+	outb(0, dev->iobase + PCL711_DA0_LO);
+	outb(0, dev->iobase + PCL711_DA0_HI);
+	outb(0, dev->iobase + PCL711_DA1_LO);
+	outb(0, dev->iobase + PCL711_DA1_HI);
+
+	printk("\n");
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcl724.c b/drivers/staging/comedi/drivers/pcl724.c
new file mode 100644
index 0000000..cd1e784
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcl724.c
@@ -0,0 +1,222 @@
+/*
+    comedi/drivers/pcl724.c
+
+    Michal Dobes <dobes@tesnet.cz>
+
+    hardware driver for Advantech cards:
+     card:   PCL-724, PCL-722, PCL-731
+     driver: pcl724,  pcl722,  pcl731
+    and ADLink cards:
+     card:   ACL-7122, ACL-7124, PET-48DIO
+     driver: acl7122,  acl7124,  pet48dio
+
+    Options for PCL-724, PCL-731, ACL-7124 and PET-48DIO:
+     [0] - IO Base
+
+    Options for PCL-722 and ACL-7122:
+     [0] - IO Base
+     [1] - IRQ (0=disable IRQ) IRQ isn't supported at this time!
+     [2] -number of DIO:
+              0, 144: 144 DIO configuration
+	      1,  96:  96 DIO configuration
+*/
+/*
+Driver: pcl724
+Description: Advantech PCL-724, PCL-722, PCL-731 ADLink ACL-7122, ACL-7124,
+  PET-48DIO
+Author: Michal Dobes <dobes@tesnet.cz>
+Devices: [Advantech] PCL-724 (pcl724), PCL-722 (pcl722), PCL-731 (pcl731),
+  [ADLink] ACL-7122 (acl7122), ACL-7124 (acl7124), PET-48DIO (pet48dio)
+Status: untested
+
+This is driver for digital I/O boards PCL-722/724/731 with 144/24/48 DIO
+and for digital I/O boards ACL-7122/7124/PET-48DIO with 144/24/48 DIO.
+It need 8255.o for operations and only immediate mode is supported.
+See the source for configuration details.
+*/
+/*
+ * check_driver overrides:
+ *   struct comedi_insn
+ */
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/delay.h>
+
+#include "8255.h"
+
+#define PCL722_SIZE    32
+#define PCL722_96_SIZE 16
+#define PCL724_SIZE     4
+#define PCL731_SIZE     8
+#define PET48_SIZE      2
+
+#define SIZE_8255	4
+
+// #define PCL724_IRQ   1  /* no IRQ support now */
+
+static int pcl724_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcl724_detach(struct comedi_device * dev);
+
+struct pcl724_board {
+
+	const char *name;	// board name
+	int dio;		// num of DIO
+	int numofports;		// num of 8255 subdevices
+	unsigned int IRQbits;	// allowed interrupts
+	unsigned int io_range;	// len of IO space
+	char can_have96;
+	char is_pet48;
+};
+
+
+static const struct pcl724_board boardtypes[] = {
+	{"pcl724", 24, 1, 0x00fc, PCL724_SIZE, 0, 0,},
+	{"pcl722", 144, 6, 0x00fc, PCL722_SIZE, 1, 0,},
+	{"pcl731", 48, 2, 0x9cfc, PCL731_SIZE, 0, 0,},
+	{"acl7122", 144, 6, 0x9ee8, PCL722_SIZE, 1, 0,},
+	{"acl7124", 24, 1, 0x00fc, PCL724_SIZE, 0, 0,},
+	{"pet48dio", 48, 2, 0x9eb8, PET48_SIZE, 0, 1,},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl724_board))
+#define this_board ((const struct pcl724_board *)dev->board_ptr)
+
+static struct comedi_driver driver_pcl724 = {
+      driver_name:"pcl724",
+      module:THIS_MODULE,
+      attach:pcl724_attach,
+      detach:pcl724_detach,
+      board_name:&boardtypes[0].name,
+      num_names:n_boardtypes,
+      offset:sizeof(struct pcl724_board),
+};
+
+COMEDI_INITCLEANUP(driver_pcl724);
+
+static int subdev_8255_cb(int dir, int port, int data, unsigned long arg)
+{
+	unsigned long iobase = arg;
+
+	if (dir) {
+		outb(data, iobase + port);
+		return 0;
+	} else {
+		return inb(iobase + port);
+	}
+}
+
+static int subdev_8255mapped_cb(int dir, int port, int data,
+	unsigned long iobase)
+{
+	int movport = SIZE_8255 * (iobase >> 12);
+
+	iobase &= 0x0fff;
+
+	if (dir) {
+		outb(port + movport, iobase);
+		outb(data, iobase + 1);
+		return 0;
+	} else {
+		outb(port + movport, iobase);
+		return inb(iobase + 1);
+	}
+}
+
+static int pcl724_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	unsigned long iobase;
+	unsigned int iorange;
+	int ret, i, n_subdevices;
+#ifdef PCL724_IRQ
+	unsigned int irq;
+#endif
+
+	iobase = it->options[0];
+	iorange = this_board->io_range;
+	if ((this_board->can_have96) && ((it->options[1] == 1)
+			|| (it->options[1] == 96)))
+		iorange = PCL722_96_SIZE;	// PCL-724 in 96 DIO configuration
+	printk("comedi%d: pcl724: board=%s, 0x%03lx ", dev->minor,
+		this_board->name, iobase);
+	if (!request_region(iobase, iorange, "pcl724")) {
+		printk("I/O port conflict\n");
+		return -EIO;
+	}
+
+	dev->iobase = iobase;
+
+	dev->board_name = this_board->name;
+
+#ifdef PCL724_IRQ
+	irq = 0;
+	if (this_board->IRQbits != 0) {	/* board support IRQ */
+		irq = it->options[1];
+		if (irq) {	/* we want to use IRQ */
+			if (((1 << irq) & this_board->IRQbits) == 0) {
+				rt_printk
+					(", IRQ %u is out of allowed range, DISABLING IT",
+					irq);
+				irq = 0;	/* Bad IRQ */
+			} else {
+				if (comedi_request_irq(irq, interrupt_pcl724, 0,
+						"pcl724", dev)) {
+					rt_printk
+						(", unable to allocate IRQ %u, DISABLING IT",
+						irq);
+					irq = 0;	/* Can't use IRQ */
+				} else {
+					rt_printk(", irq=%u", irq);
+				}
+			}
+		}
+	}
+
+	dev->irq = irq;
+#endif
+
+	printk("\n");
+
+	n_subdevices = this_board->numofports;
+	if ((this_board->can_have96) && ((it->options[1] == 1)
+			|| (it->options[1] == 96)))
+		n_subdevices = 4;	// PCL-724 in 96 DIO configuration
+
+	if ((ret = alloc_subdevices(dev, n_subdevices)) < 0)
+		return ret;
+
+	for (i = 0; i < dev->n_subdevices; i++) {
+		if (this_board->is_pet48) {
+			subdev_8255_init(dev, dev->subdevices + i,
+				subdev_8255mapped_cb,
+				(unsigned long)(dev->iobase + i * 0x1000));
+		} else
+			subdev_8255_init(dev, dev->subdevices + i,
+				subdev_8255_cb,
+				(unsigned long)(dev->iobase + SIZE_8255 * i));
+	};
+
+	return 0;
+}
+
+static int pcl724_detach(struct comedi_device * dev)
+{
+	int i;
+
+//      printk("comedi%d: pcl724: remove\n",dev->minor);
+
+	for (i = 0; i < dev->n_subdevices; i++) {
+		subdev_8255_cleanup(dev, dev->subdevices + i);
+	}
+
+#ifdef PCL724_IRQ
+	if (dev->irq) {
+		comedi_free_irq(dev->irq, dev);
+	}
+#endif
+
+	release_region(dev->iobase, this_board->io_range);
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcl725.c b/drivers/staging/comedi/drivers/pcl725.c
new file mode 100644
index 0000000..0766ba0
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcl725.c
@@ -0,0 +1,111 @@
+/*
+ * comedi/drivers/pcl725.c
+ * Driver for PCL725 and clones
+ * David A. Schleef
+ */
+/*
+Driver: pcl725
+Description: Advantech PCL-725 (& compatibles)
+Author: ds
+Status: unknown
+Devices: [Advantech] PCL-725 (pcl725)
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define PCL725_SIZE 2
+
+#define PCL725_DO 0
+#define PCL725_DI 1
+
+static int pcl725_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcl725_detach(struct comedi_device * dev);
+static struct comedi_driver driver_pcl725 = {
+      driver_name:"pcl725",
+      module:THIS_MODULE,
+      attach:pcl725_attach,
+      detach:pcl725_detach,
+};
+
+COMEDI_INITCLEANUP(driver_pcl725);
+
+static int pcl725_do_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= (data[0] & data[1]);
+		outb(s->state, dev->iobase + PCL725_DO);
+	}
+
+	data[1] = s->state;
+
+	return 2;
+}
+
+static int pcl725_di_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	data[1] = inb(dev->iobase + PCL725_DI);
+
+	return 2;
+}
+
+static int pcl725_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	unsigned long iobase;
+
+	iobase = it->options[0];
+	printk("comedi%d: pcl725: 0x%04lx ", dev->minor, iobase);
+	if (!request_region(iobase, PCL725_SIZE, "pcl725")) {
+		printk("I/O port conflict\n");
+		return -EIO;
+	}
+	dev->board_name = "pcl725";
+	dev->iobase = iobase;
+	dev->irq = 0;
+
+	if (alloc_subdevices(dev, 2) < 0)
+		return -ENOMEM;
+
+	s = dev->subdevices + 0;
+	/* do */
+	s->type = COMEDI_SUBD_DO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->maxdata = 1;
+	s->n_chan = 8;
+	s->insn_bits = pcl725_do_insn;
+	s->range_table = &range_digital;
+
+	s = dev->subdevices + 1;
+	/* di */
+	s->type = COMEDI_SUBD_DI;
+	s->subdev_flags = SDF_READABLE;
+	s->maxdata = 1;
+	s->n_chan = 8;
+	s->insn_bits = pcl725_di_insn;
+	s->range_table = &range_digital;
+
+	printk("\n");
+
+	return 0;
+}
+
+static int pcl725_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: pcl725: remove\n", dev->minor);
+
+	if (dev->iobase)
+		release_region(dev->iobase, PCL725_SIZE);
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c
new file mode 100644
index 0000000..6dbd33d
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcl726.c
@@ -0,0 +1,377 @@
+/*
+    comedi/drivers/pcl726.c
+
+    hardware driver for Advantech cards:
+     card:   PCL-726, PCL-727, PCL-728
+     driver: pcl726,  pcl727,  pcl728
+    and for ADLink cards:
+     card:   ACL-6126, ACL-6128
+     driver: acl6126,  acl6128
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 1998 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: pcl726
+Description: Advantech PCL-726 & compatibles
+Author: ds
+Status: untested
+Devices: [Advantech] PCL-726 (pcl726), PCL-727 (pcl727), PCL-728 (pcl728),
+  [ADLink] ACL-6126 (acl6126), ACL-6128 (acl6128)
+
+Interrupts are not supported.
+
+    Options for PCL-726:
+     [0] - IO Base
+     [2]...[7] - D/A output range for channel 1-6:
+               0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
+	       4: 4-20mA, 5: unknown (external reference)
+
+    Options for PCL-727:
+     [0] - IO Base
+     [2]...[13] - D/A output range for channel 1-12:
+               0: 0-5V, 1: 0-10V, 2: +/-5V,
+	       3: 4-20mA
+
+    Options for PCL-728 and ACL-6128:
+     [0] - IO Base
+     [2], [3] - D/A output range for channel 1 and 2:
+               0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
+	       4: 4-20mA, 5: 0-20mA
+
+    Options for ACL-6126:
+     [0] - IO Base
+     [1] - IRQ (0=disable, 3, 5, 6, 7, 9, 10, 11, 12, 15) (currently ignored)
+     [2]...[7] - D/A output range for channel 1-6:
+               0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
+	       4: 4-20mA
+*/
+
+/*
+    Thanks to Circuit Specialists for having programming info (!) on
+    their web page.  (http://www.cir.com/)
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#undef ACL6126_IRQ		/* no interrupt support (yet) */
+
+#define PCL726_SIZE 16
+#define PCL727_SIZE 32
+#define PCL728_SIZE 8
+
+#define PCL726_DAC0_HI 0
+#define PCL726_DAC0_LO 1
+
+#define PCL726_DO_HI 12
+#define PCL726_DO_LO 13
+#define PCL726_DI_HI 14
+#define PCL726_DI_LO 15
+
+#define PCL727_DO_HI 24
+#define PCL727_DO_LO 25
+#define PCL727_DI_HI  0
+#define PCL727_DI_LO  1
+
+static const struct comedi_lrange range_4_20mA = { 1, {RANGE_mA(4, 20)} };
+static const struct comedi_lrange range_0_20mA = { 1, {RANGE_mA(0, 20)} };
+
+static const struct comedi_lrange *const rangelist_726[] = {
+	&range_unipolar5, &range_unipolar10,
+	&range_bipolar5, &range_bipolar10,
+	&range_4_20mA, &range_unknown
+};
+
+static const struct comedi_lrange *const rangelist_727[] = {
+	&range_unipolar5, &range_unipolar10,
+	&range_bipolar5,
+	&range_4_20mA
+};
+
+static const struct comedi_lrange *const rangelist_728[] = {
+	&range_unipolar5, &range_unipolar10,
+	&range_bipolar5, &range_bipolar10,
+	&range_4_20mA, &range_0_20mA
+};
+
+static int pcl726_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcl726_detach(struct comedi_device * dev);
+
+struct pcl726_board {
+
+	const char *name;	// driver name
+	int n_aochan;		// num of D/A chans
+	int num_of_ranges;	// num of ranges
+	unsigned int IRQbits;	// allowed interrupts
+	unsigned int io_range;	// len of IO space
+	char have_dio;		// 1=card have DI/DO ports
+	int di_hi;		// ports for DI/DO operations
+	int di_lo;
+	int do_hi;
+	int do_lo;
+	const struct comedi_lrange *const *range_type_list;	// list of supported ranges
+};
+
+
+static const struct pcl726_board boardtypes[] = {
+	{"pcl726", 6, 6, 0x0000, PCL726_SIZE, 1,
+			PCL726_DI_HI, PCL726_DI_LO, PCL726_DO_HI, PCL726_DO_LO,
+		&rangelist_726[0],},
+	{"pcl727", 12, 4, 0x0000, PCL727_SIZE, 1,
+			PCL727_DI_HI, PCL727_DI_LO, PCL727_DO_HI, PCL727_DO_LO,
+		&rangelist_727[0],},
+	{"pcl728", 2, 6, 0x0000, PCL728_SIZE, 0,
+			0, 0, 0, 0,
+		&rangelist_728[0],},
+	{"acl6126", 6, 5, 0x96e8, PCL726_SIZE, 1,
+			PCL726_DI_HI, PCL726_DI_LO, PCL726_DO_HI, PCL726_DO_LO,
+		&rangelist_726[0],},
+	{"acl6128", 2, 6, 0x0000, PCL728_SIZE, 0,
+			0, 0, 0, 0,
+		&rangelist_728[0],},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl726_board))
+#define this_board ((const struct pcl726_board *)dev->board_ptr)
+
+static struct comedi_driver driver_pcl726 = {
+      driver_name:"pcl726",
+      module:THIS_MODULE,
+      attach:pcl726_attach,
+      detach:pcl726_detach,
+      board_name:&boardtypes[0].name,
+      num_names:n_boardtypes,
+      offset:sizeof(struct pcl726_board),
+};
+
+COMEDI_INITCLEANUP(driver_pcl726);
+
+struct pcl726_private {
+
+	int bipolar[12];
+	const struct comedi_lrange *rangelist[12];
+	unsigned int ao_readback[12];
+};
+
+#define devpriv ((struct pcl726_private *)dev->private)
+
+static int pcl726_ao_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int hi, lo;
+	int n;
+	int chan = CR_CHAN(insn->chanspec);
+
+	for (n = 0; n < insn->n; n++) {
+		lo = data[n] & 0xff;
+		hi = (data[n] >> 8) & 0xf;
+		if (devpriv->bipolar[chan])
+			hi ^= 0x8;
+		/*
+		 * the programming info did not say which order
+		 * to write bytes.  switch the order of the next
+		 * two lines if you get glitches.
+		 */
+		outb(hi, dev->iobase + PCL726_DAC0_HI + 2 * chan);
+		outb(lo, dev->iobase + PCL726_DAC0_LO + 2 * chan);
+		devpriv->ao_readback[chan] = data[n];
+	}
+
+	return n;
+}
+
+static int pcl726_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int chan = CR_CHAN(insn->chanspec);
+	int n;
+
+	for (n = 0; n < insn->n; n++) {
+		data[n] = devpriv->ao_readback[chan];
+	}
+	return n;
+}
+
+static int pcl726_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	data[1] = inb(dev->iobase + this_board->di_lo) |
+		(inb(dev->iobase + this_board->di_hi) << 8);
+
+	return 2;
+}
+
+static int pcl726_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= data[0] & data[1];
+	}
+	if (data[1] & 0x00ff)
+		outb(s->state & 0xff, dev->iobase + this_board->do_lo);
+	if (data[1] & 0xff00)
+		outb((s->state >> 8), dev->iobase + this_board->do_hi);
+
+	data[1] = s->state;
+
+	return 2;
+}
+
+static int pcl726_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	unsigned long iobase;
+	unsigned int iorange;
+	int ret, i;
+#ifdef ACL6126_IRQ
+	unsigned int irq;
+#endif
+
+	iobase = it->options[0];
+	iorange = this_board->io_range;
+	printk("comedi%d: pcl726: board=%s, 0x%03lx ", dev->minor,
+		this_board->name, iobase);
+	if (!request_region(iobase, iorange, "pcl726")) {
+		printk("I/O port conflict\n");
+		return -EIO;
+	}
+
+	dev->iobase = iobase;
+
+	dev->board_name = this_board->name;
+
+	if ((ret = alloc_private(dev, sizeof(struct pcl726_private))) < 0)
+		return -ENOMEM;
+
+	for (i = 0; i < 12; i++) {
+		devpriv->bipolar[i] = 0;
+		devpriv->rangelist[i] = &range_unknown;
+	}
+
+#ifdef ACL6126_IRQ
+	irq = 0;
+	if (boardtypes[board].IRQbits != 0) {	/* board support IRQ */
+		irq = it->options[1];
+		devpriv->first_chan = 2;
+		if (irq) {	/* we want to use IRQ */
+			if (((1 << irq) & boardtypes[board].IRQbits) == 0) {
+				rt_printk
+					(", IRQ %d is out of allowed range, DISABLING IT",
+					irq);
+				irq = 0;	/* Bad IRQ */
+			} else {
+				if (comedi_request_irq(irq, interrupt_pcl818, 0,
+						"pcl726", dev)) {
+					rt_printk
+						(", unable to allocate IRQ %d, DISABLING IT",
+						irq);
+					irq = 0;	/* Can't use IRQ */
+				} else {
+					rt_printk(", irq=%d", irq);
+				}
+			}
+		}
+	}
+
+	dev->irq = irq;
+#endif
+
+	printk("\n");
+
+	if ((ret = alloc_subdevices(dev, 3)) < 0)
+		return ret;
+
+	s = dev->subdevices + 0;
+	/* ao */
+	s->type = COMEDI_SUBD_AO;
+	s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
+	s->n_chan = this_board->n_aochan;
+	s->maxdata = 0xfff;
+	s->len_chanlist = 1;
+	s->insn_write = pcl726_ao_insn;
+	s->insn_read = pcl726_ao_insn_read;
+	s->range_table_list = devpriv->rangelist;
+	for (i = 0; i < this_board->n_aochan; i++) {
+		int j;
+
+		j = it->options[2 + 1];
+		if ((j < 0) || (j >= this_board->num_of_ranges)) {
+			printk("Invalid range for channel %d! Must be 0<=%d<%d\n", i, j, this_board->num_of_ranges - 1);
+			j = 0;
+		}
+		devpriv->rangelist[i] = this_board->range_type_list[j];
+		if (devpriv->rangelist[i]->range[0].min ==
+			-devpriv->rangelist[i]->range[0].max)
+			devpriv->bipolar[i] = 1;	/* bipolar range */
+	}
+
+	s = dev->subdevices + 1;
+	/* di */
+	if (!this_board->have_dio) {
+		s->type = COMEDI_SUBD_UNUSED;
+	} else {
+		s->type = COMEDI_SUBD_DI;
+		s->subdev_flags = SDF_READABLE | SDF_GROUND;
+		s->n_chan = 16;
+		s->maxdata = 1;
+		s->len_chanlist = 1;
+		s->insn_bits = pcl726_di_insn_bits;
+		s->range_table = &range_digital;
+	}
+
+	s = dev->subdevices + 2;
+	/* do */
+	if (!this_board->have_dio) {
+		s->type = COMEDI_SUBD_UNUSED;
+	} else {
+		s->type = COMEDI_SUBD_DO;
+		s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
+		s->n_chan = 16;
+		s->maxdata = 1;
+		s->len_chanlist = 1;
+		s->insn_bits = pcl726_do_insn_bits;
+		s->range_table = &range_digital;
+	}
+
+	return 0;
+}
+
+static int pcl726_detach(struct comedi_device * dev)
+{
+//      printk("comedi%d: pcl726: remove\n",dev->minor);
+
+#ifdef ACL6126_IRQ
+	if (dev->irq) {
+		comedi_free_irq(dev->irq, dev);
+	}
+#endif
+
+	if (dev->iobase)
+		release_region(dev->iobase, this_board->io_range);
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcl730.c b/drivers/staging/comedi/drivers/pcl730.c
new file mode 100644
index 0000000..f2c6d7c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcl730.c
@@ -0,0 +1,168 @@
+/*
+ * comedi/drivers/pcl730.c
+ * Driver for Advantech PCL-730 and clones
+ * José Luis Sánchez
+ */
+/*
+Driver: pcl730
+Description: Advantech PCL-730 (& compatibles)
+Author: José Luis Sánchez (jsanchezv@teleline.es)
+Status: untested
+Devices: [Advantech] PCL-730 (pcl730), [ICP] ISO-730 (iso730),
+		 [Adlink] ACL-7130 (acl7130)
+
+Interrupts are not supported.
+The ACL-7130 card have an 8254 timer/counter not supported by this driver.
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define PCL730_SIZE		4
+#define ACL7130_SIZE	8
+#define PCL730_IDIO_LO	0	/* Isolated Digital I/O low byte (ID0-ID7) */
+#define PCL730_IDIO_HI	1	/* Isolated Digital I/O high byte (ID8-ID15) */
+#define PCL730_DIO_LO	2	/* TTL Digital I/O low byte (D0-D7) */
+#define PCL730_DIO_HI	3	/* TTL Digital I/O high byte (D8-D15) */
+
+static int pcl730_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcl730_detach(struct comedi_device * dev);
+
+struct pcl730_board {
+
+	const char *name;	// board name
+	unsigned int io_range;	// len of I/O space
+};
+
+
+static const struct pcl730_board boardtypes[] = {
+	{"pcl730", PCL730_SIZE,},
+	{"iso730", PCL730_SIZE,},
+	{"acl7130", ACL7130_SIZE,},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl730_board))
+#define this_board ((const struct pcl730_board *)dev->board_ptr)
+
+static struct comedi_driver driver_pcl730 = {
+      driver_name:"pcl730",
+      module:THIS_MODULE,
+      attach:pcl730_attach,
+      detach:pcl730_detach,
+      board_name:&boardtypes[0].name,
+      num_names:n_boardtypes,
+      offset:sizeof(struct pcl730_board),
+};
+
+COMEDI_INITCLEANUP(driver_pcl730);
+
+static int pcl730_do_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= (data[0] & data[1]);
+	}
+	if (data[0] & 0x00ff)
+		outb(s->state & 0xff,
+			dev->iobase + ((unsigned long)s->private));
+	if (data[0] & 0xff00)
+		outb((s->state >> 8),
+			dev->iobase + ((unsigned long)s->private) + 1);
+
+	data[1] = s->state;
+
+	return 2;
+}
+
+static int pcl730_di_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	data[1] = inb(dev->iobase + ((unsigned long)s->private)) |
+		(inb(dev->iobase + ((unsigned long)s->private) + 1) << 8);
+
+	return 2;
+}
+
+static int pcl730_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	unsigned long iobase;
+	unsigned int iorange;
+
+	iobase = it->options[0];
+	iorange = this_board->io_range;
+	printk("comedi%d: pcl730: board=%s 0x%04lx ", dev->minor,
+		this_board->name, iobase);
+	if (!request_region(iobase, iorange, "pcl730")) {
+		printk("I/O port conflict\n");
+		return -EIO;
+	}
+	dev->board_name = this_board->name;
+	dev->iobase = iobase;
+	dev->irq = 0;
+
+	if (alloc_subdevices(dev, 4) < 0)
+		return -ENOMEM;
+
+	s = dev->subdevices + 0;
+	/* Isolated do */
+	s->type = COMEDI_SUBD_DO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->maxdata = 1;
+	s->n_chan = 16;
+	s->insn_bits = pcl730_do_insn;
+	s->range_table = &range_digital;
+	s->private = (void *)PCL730_IDIO_LO;
+
+	s = dev->subdevices + 1;
+	/* Isolated di */
+	s->type = COMEDI_SUBD_DI;
+	s->subdev_flags = SDF_READABLE;
+	s->maxdata = 1;
+	s->n_chan = 16;
+	s->insn_bits = pcl730_di_insn;
+	s->range_table = &range_digital;
+	s->private = (void *)PCL730_IDIO_LO;
+
+	s = dev->subdevices + 2;
+	/* TTL do */
+	s->type = COMEDI_SUBD_DO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->maxdata = 1;
+	s->n_chan = 16;
+	s->insn_bits = pcl730_do_insn;
+	s->range_table = &range_digital;
+	s->private = (void *)PCL730_DIO_LO;
+
+	s = dev->subdevices + 3;
+	/* TTL di */
+	s->type = COMEDI_SUBD_DI;
+	s->subdev_flags = SDF_READABLE;
+	s->maxdata = 1;
+	s->n_chan = 16;
+	s->insn_bits = pcl730_di_insn;
+	s->range_table = &range_digital;
+	s->private = (void *)PCL730_DIO_LO;
+
+	printk("\n");
+
+	return 0;
+}
+
+static int pcl730_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: pcl730: remove\n", dev->minor);
+
+	if (dev->iobase)
+		release_region(dev->iobase, this_board->io_range);
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c
new file mode 100644
index 0000000..11dfd23
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcl812.c
@@ -0,0 +1,1605 @@
+/*
+ * comedi/drivers/pcl812.c
+ *
+ * Author: Michal Dobes <dobes@tesnet.cz>
+ *
+ * hardware driver for Advantech cards
+ *  card:   PCL-812, PCL-812PG, PCL-813, PCL-813B
+ *  driver: pcl812,  pcl812pg,  pcl813,  pcl813b
+ * and for ADlink cards
+ *  card:   ACL-8112DG, ACL-8112HG, ACL-8112PG, ACL-8113, ACL-8216
+ *  driver: acl8112dg,  acl8112hg,  acl8112pg,  acl8113,  acl8216
+ * and for ICP DAS cards
+ *  card:   ISO-813, A-821PGH, A-821PGL, A-821PGL-NDA, A-822PGH, A-822PGL,
+ *  driver: iso813,  a821pgh,  a-821pgl, a-821pglnda,  a822pgh,  a822pgl,
+ *  card:   A-823PGH, A-823PGL, A-826PG
+ * driver:  a823pgh,  a823pgl,  a826pg
+ */
+/*
+Driver: pcl812
+Description: Advantech PCL-812/PG, PCL-813/B,
+             ADLink ACL-8112DG/HG/PG, ACL-8113, ACL-8216,
+             ICP DAS A-821PGH/PGL/PGL-NDA, A-822PGH/PGL, A-823PGH/PGL, A-826PG,
+             ICP DAS ISO-813
+Author: Michal Dobes <dobes@tesnet.cz>
+Devices: [Advantech] PCL-812 (pcl812), PCL-812PG (pcl812pg),
+  PCL-813 (pcl813), PCL-813B (pcl813b), [ADLink] ACL-8112DG (acl8112dg),
+  ACL-8112HG (acl8112hg), ACL-8113 (acl-8113), ACL-8216 (acl8216),
+  [ICP] ISO-813 (iso813), A-821PGH (a821pgh), A-821PGL (a821pgl),
+  A-821PGL-NDA (a821pclnda), A-822PGH (a822pgh), A-822PGL (a822pgl),
+  A-823PGH (a823pgh), A-823PGL (a823pgl), A-826PG (a826pg)
+Updated: Mon, 06 Aug 2007 12:03:15 +0100
+Status: works (I hope. My board fire up under my hands
+               and I cann't test all features.)
+
+This driver supports insn and cmd interfaces. Some boards support only insn
+becouse their hardware don't allow more (PCL-813/B, ACL-8113, ISO-813).
+Data transfer over DMA is supported only when you measure only one
+channel, this is too hardware limitation of these boards.
+
+Options for PCL-812:
+  [0] - IO Base
+  [1] - IRQ  (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15)
+  [2] - DMA  (0=disable, 1, 3)
+  [3] - 0=trigger source is internal 8253 with 2MHz clock
+        1=trigger source is external
+  [4] - 0=A/D input range is +/-10V
+        1=A/D input range is +/-5V
+        2=A/D input range is +/-2.5V
+        3=A/D input range is +/-1.25V
+        4=A/D input range is +/-0.625V
+        5=A/D input range is +/-0.3125V
+  [5] - 0=D/A outputs 0-5V  (internal reference -5V)
+        1=D/A outputs 0-10V (internal reference -10V)
+        2=D/A outputs unknow (external reference)
+
+Options for PCL-812PG, ACL-8112PG:
+  [0] - IO Base
+  [1] - IRQ  (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15)
+  [2] - DMA  (0=disable, 1, 3)
+  [3] - 0=trigger source is internal 8253 with 2MHz clock
+        1=trigger source is external
+  [4] - 0=A/D have max +/-5V input
+        1=A/D have max +/-10V input
+  [5] - 0=D/A outputs 0-5V  (internal reference -5V)
+        1=D/A outputs 0-10V (internal reference -10V)
+        2=D/A outputs unknow (external reference)
+
+Options for ACL-8112DG/HG, A-822PGL/PGH, A-823PGL/PGH, ACL-8216, A-826PG:
+  [0] - IO Base
+  [1] - IRQ  (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15)
+  [2] - DMA  (0=disable, 1, 3)
+  [3] - 0=trigger source is internal 8253 with 2MHz clock
+        1=trigger source is external
+  [4] - 0=A/D channels are S.E.
+        1=A/D channels are DIFF
+  [5] - 0=D/A outputs 0-5V  (internal reference -5V)
+        1=D/A outputs 0-10V (internal reference -10V)
+        2=D/A outputs unknow (external reference)
+
+Options for A-821PGL/PGH:
+  [0] - IO Base
+  [1] - IRQ  (0=disable, 2, 3, 4, 5, 6, 7)
+  [2] - 0=A/D channels are S.E.
+        1=A/D channels are DIFF
+  [3] - 0=D/A output 0-5V  (internal reference -5V)
+        1=D/A output 0-10V (internal reference -10V)
+
+Options for A-821PGL-NDA:
+  [0] - IO Base
+  [1] - IRQ  (0=disable, 2, 3, 4, 5, 6, 7)
+  [2] - 0=A/D channels are S.E.
+        1=A/D channels are DIFF
+
+Options for PCL-813:
+  [0] - IO Base
+
+Options for PCL-813B:
+  [0] - IO Base
+  [1] - 0= bipolar inputs
+        1= unipolar inputs
+
+Options for ACL-8113, ISO-813:
+  [0] - IO Base
+  [1] - 0= 10V bipolar inputs
+        1= 10V unipolar inputs
+        2= 20V bipolar inputs
+        3= 20V unipolar inputs
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <asm/dma.h>
+
+#include "8253.h"
+
+#undef PCL812_EXTDEBUG		/* if this is defined then a lot of messages is printed */
+
+// hardware types of the cards
+#define boardPCL812PG 		 0	/* and ACL-8112PG */
+#define boardPCL813B 		 1
+#define boardPCL812		 2
+#define boardPCL813 		 3
+#define boardISO813 		 5
+#define boardACL8113 		 6
+#define boardACL8112 		 7	/* ACL-8112DG/HG, A-822PGL/PGH, A-823PGL/PGH */
+#define boardACL8216		 8	/* and ICP DAS A-826PG */
+#define boardA821		 9	/* PGH, PGL, PGL/NDA versions */
+
+#define PCLx1x_IORANGE 		16
+
+#define PCL812_CTR0		 0
+#define PCL812_CTR1		 1
+#define PCL812_CTR2		 2
+#define PCL812_CTRCTL		 3
+#define PCL812_AD_LO		 4
+#define PCL812_DA1_LO		 4
+#define PCL812_AD_HI		 5
+#define PCL812_DA1_HI		 5
+#define PCL812_DA2_LO		 6
+#define PCL812_DI_LO		 6
+#define PCL812_DA2_HI		 7
+#define PCL812_DI_HI		 7
+#define PCL812_CLRINT		 8
+#define PCL812_GAIN		 9
+#define PCL812_MUX		10
+#define PCL812_MODE		11
+#define PCL812_CNTENABLE 	10
+#define PCL812_SOFTTRIG 	12
+#define PCL812_DO_LO		13
+#define PCL812_DO_HI 		14
+
+#define PCL812_DRDY 		0x10	/* =0 data ready */
+
+#define ACL8216_STATUS 		 8	/* 5. bit signalize data ready */
+
+#define ACL8216_DRDY 		0x20	/* =0 data ready */
+
+#define MAX_CHANLIST_LEN	256	/* length of scan list */
+
+static const struct comedi_lrange range_pcl812pg_ai = { 5, {
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+			BIP_RANGE(0.625),
+			BIP_RANGE(0.3125),
+	}
+};
+static const struct comedi_lrange range_pcl812pg2_ai = { 5, {
+			BIP_RANGE(10),
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+			BIP_RANGE(0.625),
+	}
+};
+static const struct comedi_lrange range812_bipolar1_25 = { 1, {
+			BIP_RANGE(1.25),
+	}
+};
+static const struct comedi_lrange range812_bipolar0_625 = { 1, {
+			BIP_RANGE(0.625),
+	}
+};
+static const struct comedi_lrange range812_bipolar0_3125 = { 1, {
+			BIP_RANGE(0.3125),
+	}
+};
+static const struct comedi_lrange range_pcl813b_ai = { 4, {
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+			BIP_RANGE(0.625),
+	}
+};
+static const struct comedi_lrange range_pcl813b2_ai = { 4, {
+			UNI_RANGE(10),
+			UNI_RANGE(5),
+			UNI_RANGE(2.5),
+			UNI_RANGE(1.25),
+	}
+};
+static const struct comedi_lrange range_iso813_1_ai = { 5, {
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+			BIP_RANGE(0.625),
+			BIP_RANGE(0.3125),
+	}
+};
+static const struct comedi_lrange range_iso813_1_2_ai = { 5, {
+			UNI_RANGE(10),
+			UNI_RANGE(5),
+			UNI_RANGE(2.5),
+			UNI_RANGE(1.25),
+			UNI_RANGE(0.625),
+	}
+};
+static const struct comedi_lrange range_iso813_2_ai = { 4, {
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+			BIP_RANGE(0.625),
+	}
+};
+static const struct comedi_lrange range_iso813_2_2_ai = { 4, {
+			UNI_RANGE(10),
+			UNI_RANGE(5),
+			UNI_RANGE(2.5),
+			UNI_RANGE(1.25),
+	}
+};
+static const struct comedi_lrange range_acl8113_1_ai = { 4, {
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+			BIP_RANGE(0.625),
+	}
+};
+static const struct comedi_lrange range_acl8113_1_2_ai = { 4, {
+			UNI_RANGE(10),
+			UNI_RANGE(5),
+			UNI_RANGE(2.5),
+			UNI_RANGE(1.25),
+	}
+};
+static const struct comedi_lrange range_acl8113_2_ai = { 3, {
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+	}
+};
+static const struct comedi_lrange range_acl8113_2_2_ai = { 3, {
+			UNI_RANGE(10),
+			UNI_RANGE(5),
+			UNI_RANGE(2.5),
+	}
+};
+static const struct comedi_lrange range_acl8112dg_ai = { 9, {
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+			BIP_RANGE(0.625),
+			UNI_RANGE(10),
+			UNI_RANGE(5),
+			UNI_RANGE(2.5),
+			UNI_RANGE(1.25),
+			BIP_RANGE(10),
+	}
+};
+static const struct comedi_lrange range_acl8112hg_ai = { 12, {
+			BIP_RANGE(5),
+			BIP_RANGE(0.5),
+			BIP_RANGE(0.05),
+			BIP_RANGE(0.005),
+			UNI_RANGE(10),
+			UNI_RANGE(1),
+			UNI_RANGE(0.1),
+			UNI_RANGE(0.01),
+			BIP_RANGE(10),
+			BIP_RANGE(1),
+			BIP_RANGE(0.1),
+			BIP_RANGE(0.01),
+	}
+};
+static const struct comedi_lrange range_a821pgh_ai = { 4, {
+			BIP_RANGE(5),
+			BIP_RANGE(0.5),
+			BIP_RANGE(0.05),
+			BIP_RANGE(0.005),
+	}
+};
+
+static int pcl812_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcl812_detach(struct comedi_device * dev);
+
+struct pcl812_board {
+
+	const char *name;	// board name
+	int board_type;		// type of this board
+	int n_aichan;		// num of AI chans in S.E.
+	int n_aichan_diff;	// DIFF num of chans
+	int n_aochan;		// num of DA chans
+	int n_dichan;		// DI and DO chans
+	int n_dochan;
+	int ai_maxdata;		// AI resolution
+	unsigned int ai_ns_min;	// max sample speed of card v ns
+	unsigned int i8254_osc_base;	// clock base
+	const struct comedi_lrange *rangelist_ai;	// rangelist for A/D
+	const struct comedi_lrange *rangelist_ao;	// rangelist for D/A
+	unsigned int IRQbits;	// allowed IRQ
+	unsigned char DMAbits;	// allowed DMA chans
+	unsigned char io_range;	// iorange for this board
+	unsigned char haveMPC508;	// 1=board use MPC508A multiplexor
+};
+
+
+static const struct pcl812_board boardtypes[] = {
+	{"pcl812", boardPCL812, 16, 0, 2, 16, 16, 0x0fff,
+			33000, 500, &range_bipolar10, &range_unipolar5,
+		0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
+	{"pcl812pg", boardPCL812PG, 16, 0, 2, 16, 16, 0x0fff,
+			33000, 500, &range_pcl812pg_ai, &range_unipolar5,
+		0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
+	{"acl8112pg", boardPCL812PG, 16, 0, 2, 16, 16, 0x0fff,
+			10000, 500, &range_pcl812pg_ai, &range_unipolar5,
+		0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
+	{"acl8112dg", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
+			10000, 500, &range_acl8112dg_ai, &range_unipolar5,
+		0xdcfc, 0x0a, PCLx1x_IORANGE, 1},
+	{"acl8112hg", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
+			10000, 500, &range_acl8112hg_ai, &range_unipolar5,
+		0xdcfc, 0x0a, PCLx1x_IORANGE, 1},
+	{"a821pgl", boardA821, 16, 8, 1, 16, 16, 0x0fff,
+			10000, 500, &range_pcl813b_ai, &range_unipolar5,
+		0x000c, 0x00, PCLx1x_IORANGE, 0},
+	{"a821pglnda", boardA821, 16, 8, 0, 0, 0, 0x0fff,
+			10000, 500, &range_pcl813b_ai, NULL,
+		0x000c, 0x00, PCLx1x_IORANGE, 0},
+	{"a821pgh", boardA821, 16, 8, 1, 16, 16, 0x0fff,
+			10000, 500, &range_a821pgh_ai, &range_unipolar5,
+		0x000c, 0x00, PCLx1x_IORANGE, 0},
+	{"a822pgl", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
+			10000, 500, &range_acl8112dg_ai, &range_unipolar5,
+		0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
+	{"a822pgh", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
+			10000, 500, &range_acl8112hg_ai, &range_unipolar5,
+		0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
+	{"a823pgl", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
+			8000, 500, &range_acl8112dg_ai, &range_unipolar5,
+		0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
+	{"a823pgh", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
+			8000, 500, &range_acl8112hg_ai, &range_unipolar5,
+		0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
+	{"pcl813", boardPCL813, 32, 0, 0, 0, 0, 0x0fff,
+			0, 0, &range_pcl813b_ai, NULL,
+		0x0000, 0x00, PCLx1x_IORANGE, 0},
+	{"pcl813b", boardPCL813B, 32, 0, 0, 0, 0, 0x0fff,
+			0, 0, &range_pcl813b_ai, NULL,
+		0x0000, 0x00, PCLx1x_IORANGE, 0},
+	{"acl8113", boardACL8113, 32, 0, 0, 0, 0, 0x0fff,
+			0, 0, &range_acl8113_1_ai, NULL,
+		0x0000, 0x00, PCLx1x_IORANGE, 0},
+	{"iso813", boardISO813, 32, 0, 0, 0, 0, 0x0fff,
+			0, 0, &range_iso813_1_ai, NULL,
+		0x0000, 0x00, PCLx1x_IORANGE, 0},
+	{"acl8216", boardACL8216, 16, 8, 2, 16, 16, 0xffff,
+			10000, 500, &range_pcl813b2_ai, &range_unipolar5,
+		0xdcfc, 0x0a, PCLx1x_IORANGE, 1},
+	{"a826pg", boardACL8216, 16, 8, 2, 16, 16, 0xffff,
+			10000, 500, &range_pcl813b2_ai, &range_unipolar5,
+		0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl812_board))
+#define this_board ((const struct pcl812_board *)dev->board_ptr)
+
+static struct comedi_driver driver_pcl812 = {
+      driver_name:"pcl812",
+      module:THIS_MODULE,
+      attach:pcl812_attach,
+      detach:pcl812_detach,
+      board_name:&boardtypes[0].name,
+      num_names:n_boardtypes,
+      offset:sizeof(struct pcl812_board),
+};
+
+COMEDI_INITCLEANUP(driver_pcl812);
+
+struct pcl812_private {
+
+	unsigned char valid;	// =1 device is OK
+	unsigned char dma;	// >0 use dma ( usedDMA channel)
+	unsigned char use_diff;	// =1 diff inputs
+	unsigned char use_MPC;	// 1=board uses MPC508A multiplexor
+	unsigned char use_ext_trg;	// 1=board uses external trigger
+	unsigned char range_correction;	// =1 we must add 1 to range number
+	unsigned char old_chan_reg;	// lastly used chan/gain pair
+	unsigned char old_gain_reg;
+	unsigned char mode_reg_int;	// there is stored INT number for some card
+	unsigned char ai_neverending;	// =1 we do unlimited AI
+	unsigned char ai_eos;	// 1=EOS wake up
+	unsigned char ai_dma;	// =1 we use DMA
+	unsigned int ai_poll_ptr;	// how many sampes transfer poll
+	unsigned int ai_scans;	// len of scanlist
+	unsigned int ai_act_scan;	// how many scans we finished
+	unsigned int ai_chanlist[MAX_CHANLIST_LEN];	// our copy of channel/range list
+	unsigned int ai_n_chan;	// how many channels is measured
+	unsigned int ai_flags;	// flaglist
+	unsigned int ai_data_len;	// len of data buffer
+	short *ai_data;	// data buffer
+	unsigned int ai_is16b;	// =1 we have 16 bit card
+	unsigned long dmabuf[2];	// PTR to DMA buf
+	unsigned int dmapages[2];	// how many pages we have allocated
+	unsigned int hwdmaptr[2];	// HW PTR to DMA buf
+	unsigned int hwdmasize[2];	// DMA buf size in bytes
+	unsigned int dmabytestomove[2];	// how many bytes DMA transfer
+	int next_dma_buf;	// which buffer is next to use
+	unsigned int dma_runs_to_end;	// how many times we must switch DMA buffers
+	unsigned int last_dma_run;	// how many bytes to transfer on last DMA buffer
+	unsigned int max_812_ai_mode0_rangewait;	// setling time for gain
+	unsigned int ao_readback[2];	// data for AO readback
+};
+
+
+#define devpriv ((struct pcl812_private *)dev->private)
+
+/*
+==============================================================================
+*/
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+	unsigned int divisor2);
+static void setup_range_channel(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int rangechan, char wait);
+static int pcl812_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+/*
+==============================================================================
+*/
+static int pcl812_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n;
+	int timeout, hi;
+
+	outb(devpriv->mode_reg_int | 1, dev->iobase + PCL812_MODE);	/* select software trigger */
+	setup_range_channel(dev, s, insn->chanspec, 1);	// select channel and renge
+	for (n = 0; n < insn->n; n++) {
+		outb(255, dev->iobase + PCL812_SOFTTRIG);	/* start conversion */
+		comedi_udelay(5);
+		timeout = 50;	/* wait max 50us, it must finish under 33us */
+		while (timeout--) {
+			hi = inb(dev->iobase + PCL812_AD_HI);
+			if (!(hi & PCL812_DRDY))
+				goto conv_finish;
+			comedi_udelay(1);
+		}
+		rt_printk
+			("comedi%d: pcl812: (%s at 0x%lx) A/D insn read timeout\n",
+			dev->minor, dev->board_name, dev->iobase);
+		outb(devpriv->mode_reg_int | 0, dev->iobase + PCL812_MODE);
+		return -ETIME;
+
+	      conv_finish:
+		data[n] = ((hi & 0xf) << 8) | inb(dev->iobase + PCL812_AD_LO);
+	}
+	outb(devpriv->mode_reg_int | 0, dev->iobase + PCL812_MODE);
+	return n;
+}
+
+/*
+==============================================================================
+*/
+static int acl8216_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n;
+	int timeout;
+
+	outb(1, dev->iobase + PCL812_MODE);	/* select software trigger */
+	setup_range_channel(dev, s, insn->chanspec, 1);	// select channel and renge
+	for (n = 0; n < insn->n; n++) {
+		outb(255, dev->iobase + PCL812_SOFTTRIG);	/* start conversion */
+		comedi_udelay(5);
+		timeout = 50;	/* wait max 50us, it must finish under 33us */
+		while (timeout--) {
+			if (!(inb(dev->iobase + ACL8216_STATUS) & ACL8216_DRDY))
+				goto conv_finish;
+			comedi_udelay(1);
+		}
+		rt_printk
+			("comedi%d: pcl812: (%s at 0x%lx) A/D insn read timeout\n",
+			dev->minor, dev->board_name, dev->iobase);
+		outb(0, dev->iobase + PCL812_MODE);
+		return -ETIME;
+
+	      conv_finish:
+		data[n] =
+			(inb(dev->iobase +
+				PCL812_AD_HI) << 8) | inb(dev->iobase +
+			PCL812_AD_LO);
+	}
+	outb(0, dev->iobase + PCL812_MODE);
+	return n;
+}
+
+/*
+==============================================================================
+*/
+static int pcl812_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int chan = CR_CHAN(insn->chanspec);
+	int i;
+
+	for (i = 0; i < insn->n; i++) {
+		outb((data[i] & 0xff),
+			dev->iobase + (chan ? PCL812_DA2_LO : PCL812_DA1_LO));
+		outb((data[i] >> 8) & 0x0f,
+			dev->iobase + (chan ? PCL812_DA2_HI : PCL812_DA1_HI));
+		devpriv->ao_readback[chan] = data[i];
+	}
+
+	return i;
+}
+
+/*
+==============================================================================
+*/
+static int pcl812_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int chan = CR_CHAN(insn->chanspec);
+	int i;
+
+	for (i = 0; i < insn->n; i++) {
+		data[i] = devpriv->ao_readback[chan];
+	}
+
+	return i;
+}
+
+/*
+==============================================================================
+*/
+static int pcl812_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	data[1] = inb(dev->iobase + PCL812_DI_LO);
+	data[1] |= inb(dev->iobase + PCL812_DI_HI) << 8;
+
+	return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pcl812_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= data[0] & data[1];
+		outb(s->state & 0xff, dev->iobase + PCL812_DO_LO);
+		outb((s->state >> 8), dev->iobase + PCL812_DO_HI);
+	}
+	data[1] = s->state;
+
+	return 2;
+}
+
+#ifdef PCL812_EXTDEBUG
+/*
+==============================================================================
+*/
+static void pcl812_cmdtest_out(int e, struct comedi_cmd * cmd)
+{
+	rt_printk("pcl812 e=%d startsrc=%x scansrc=%x convsrc=%x\n", e,
+		cmd->start_src, cmd->scan_begin_src, cmd->convert_src);
+	rt_printk("pcl812 e=%d startarg=%d scanarg=%d convarg=%d\n", e,
+		cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg);
+	rt_printk("pcl812 e=%d stopsrc=%x scanend=%x\n", e, cmd->stop_src,
+		cmd->scan_end_src);
+	rt_printk("pcl812 e=%d stoparg=%d scanendarg=%d chanlistlen=%d\n", e,
+		cmd->stop_arg, cmd->scan_end_arg, cmd->chanlist_len);
+}
+#endif
+
+/*
+==============================================================================
+*/
+static int pcl812_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp, divisor1, divisor2;
+
+#ifdef PCL812_EXTDEBUG
+	rt_printk("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...)\n");
+	pcl812_cmdtest_out(-1, cmd);
+#endif
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_FOLLOW;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	if (devpriv->use_ext_trg) {
+		cmd->convert_src &= TRIG_EXT;
+	} else {
+		cmd->convert_src &= TRIG_TIMER;
+	}
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err) {
+#ifdef PCL812_EXTDEBUG
+		pcl812_cmdtest_out(1, cmd);
+		rt_printk
+			("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...) err=%d ret=1\n",
+			err);
+#endif
+		return 1;
+	}
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	if (cmd->start_src != TRIG_NOW) {
+		cmd->start_src = TRIG_NOW;
+		err++;
+	}
+
+	if (cmd->scan_begin_src != TRIG_FOLLOW) {
+		cmd->scan_begin_src = TRIG_FOLLOW;
+		err++;
+	}
+
+	if (devpriv->use_ext_trg) {
+		if (cmd->convert_src != TRIG_EXT) {
+			cmd->convert_src = TRIG_EXT;
+			err++;
+		}
+	} else {
+		if (cmd->convert_src != TRIG_TIMER) {
+			cmd->convert_src = TRIG_TIMER;
+			err++;
+		}
+	}
+
+	if (cmd->scan_end_src != TRIG_COUNT) {
+		cmd->scan_end_src = TRIG_COUNT;
+		err++;
+	}
+
+	if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
+		err++;
+
+	if (err) {
+#ifdef PCL812_EXTDEBUG
+		pcl812_cmdtest_out(2, cmd);
+		rt_printk
+			("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...) err=%d ret=2\n",
+			err);
+#endif
+		return 2;
+	}
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+
+	if (cmd->scan_begin_arg != 0) {
+		cmd->scan_begin_arg = 0;
+		err++;
+	}
+
+	if (cmd->convert_src == TRIG_TIMER) {
+		if (cmd->convert_arg < this_board->ai_ns_min) {
+			cmd->convert_arg = this_board->ai_ns_min;
+			err++;
+		}
+	} else {		/* TRIG_EXT */
+		if (cmd->convert_arg != 0) {
+			cmd->convert_arg = 0;
+			err++;
+		}
+	}
+
+	if (!cmd->chanlist_len) {
+		cmd->chanlist_len = 1;
+		err++;
+	}
+	if (cmd->chanlist_len > MAX_CHANLIST_LEN) {
+		cmd->chanlist_len = this_board->n_aichan;
+		err++;
+	}
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+	if (cmd->stop_src == TRIG_COUNT) {
+		if (!cmd->stop_arg) {
+			cmd->stop_arg = 1;
+			err++;
+		}
+	} else {		/* TRIG_NONE */
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (err) {
+#ifdef PCL812_EXTDEBUG
+		pcl812_cmdtest_out(3, cmd);
+		rt_printk
+			("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...) err=%d ret=3\n",
+			err);
+#endif
+		return 3;
+	}
+
+	/* step 4: fix up any arguments */
+
+	if (cmd->convert_src == TRIG_TIMER) {
+		tmp = cmd->convert_arg;
+		i8253_cascade_ns_to_timer(this_board->i8254_osc_base, &divisor1,
+			&divisor2, &cmd->convert_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+		if (cmd->convert_arg < this_board->ai_ns_min)
+			cmd->convert_arg = this_board->ai_ns_min;
+		if (tmp != cmd->convert_arg)
+			err++;
+	}
+
+	if (err) {
+#ifdef PCL812_EXTDEBUG
+		rt_printk
+			("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...) err=%d ret=4\n",
+			err);
+#endif
+		return 4;
+	}
+
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pcl812_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	unsigned int divisor1 = 0, divisor2 = 0, i, dma_flags, bytes;
+	struct comedi_cmd *cmd = &s->async->cmd;
+
+#ifdef PCL812_EXTDEBUG
+	rt_printk("pcl812 EDBG: BGN: pcl812_ai_cmd(...)\n");
+#endif
+
+	if (cmd->start_src != TRIG_NOW)
+		return -EINVAL;
+	if (cmd->scan_begin_src != TRIG_FOLLOW)
+		return -EINVAL;
+	if (devpriv->use_ext_trg) {
+		if (cmd->convert_src != TRIG_EXT)
+			return -EINVAL;
+	} else {
+		if (cmd->convert_src != TRIG_TIMER)
+			return -EINVAL;
+	}
+	if (cmd->scan_end_src != TRIG_COUNT)
+		return -EINVAL;
+	if (cmd->scan_end_arg != cmd->chanlist_len)
+		return -EINVAL;
+	if (cmd->chanlist_len > MAX_CHANLIST_LEN)
+		return -EINVAL;
+
+	if (cmd->convert_src == TRIG_TIMER) {
+		if (cmd->convert_arg < this_board->ai_ns_min)
+			cmd->convert_arg = this_board->ai_ns_min;
+		i8253_cascade_ns_to_timer(this_board->i8254_osc_base,
+			&divisor1, &divisor2, &cmd->convert_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+	}
+
+	start_pacer(dev, -1, 0, 0);	// stop pacer
+
+	devpriv->ai_n_chan = cmd->chanlist_len;
+	memcpy(devpriv->ai_chanlist, cmd->chanlist,
+		sizeof(unsigned int) * cmd->scan_end_arg);
+	setup_range_channel(dev, s, devpriv->ai_chanlist[0], 1);	// select first channel and range
+
+	if (devpriv->dma) {	// check if we can use DMA transfer
+		devpriv->ai_dma = 1;
+		for (i = 1; i < devpriv->ai_n_chan; i++)
+			if (devpriv->ai_chanlist[0] != devpriv->ai_chanlist[i]) {
+				devpriv->ai_dma = 0;	// we cann't use DMA :-(
+				break;
+			}
+	} else
+		devpriv->ai_dma = 0;
+
+	devpriv->ai_flags = cmd->flags;
+	devpriv->ai_data_len = s->async->prealloc_bufsz;
+	devpriv->ai_data = s->async->prealloc_buf;
+	if (cmd->stop_src == TRIG_COUNT) {
+		devpriv->ai_scans = cmd->stop_arg;
+		devpriv->ai_neverending = 0;
+	} else {
+		devpriv->ai_scans = 0;
+		devpriv->ai_neverending = 1;
+	}
+
+	devpriv->ai_act_scan = 0;
+	devpriv->ai_poll_ptr = 0;
+	s->async->cur_chan = 0;
+
+	if ((devpriv->ai_flags & TRIG_WAKE_EOS)) {	// don't we want wake up every scan?
+		devpriv->ai_eos = 1;
+		if (devpriv->ai_n_chan == 1)
+			devpriv->ai_dma = 0;	// DMA is useless for this situation
+	}
+
+	if (devpriv->ai_dma) {
+		if (devpriv->ai_eos) {	// we use EOS, so adapt DMA buffer to one scan
+			devpriv->dmabytestomove[0] =
+				devpriv->ai_n_chan * sizeof(short);
+			devpriv->dmabytestomove[1] =
+				devpriv->ai_n_chan * sizeof(short);
+			devpriv->dma_runs_to_end = 1;
+		} else {
+			devpriv->dmabytestomove[0] = devpriv->hwdmasize[0];
+			devpriv->dmabytestomove[1] = devpriv->hwdmasize[1];
+			if (devpriv->ai_data_len < devpriv->hwdmasize[0])
+				devpriv->dmabytestomove[0] =
+					devpriv->ai_data_len;
+			if (devpriv->ai_data_len < devpriv->hwdmasize[1])
+				devpriv->dmabytestomove[1] =
+					devpriv->ai_data_len;
+			if (devpriv->ai_neverending) {
+				devpriv->dma_runs_to_end = 1;
+			} else {
+				bytes = devpriv->ai_n_chan * devpriv->ai_scans * sizeof(short);	// how many samples we must transfer?
+				devpriv->dma_runs_to_end = bytes / devpriv->dmabytestomove[0];	// how many DMA pages we must fill
+				devpriv->last_dma_run = bytes % devpriv->dmabytestomove[0];	//on last dma transfer must be moved
+				if (devpriv->dma_runs_to_end == 0)
+					devpriv->dmabytestomove[0] =
+						devpriv->last_dma_run;
+				devpriv->dma_runs_to_end--;
+			}
+		}
+		if (devpriv->dmabytestomove[0] > devpriv->hwdmasize[0]) {
+			devpriv->dmabytestomove[0] = devpriv->hwdmasize[0];
+			devpriv->ai_eos = 0;
+		}
+		if (devpriv->dmabytestomove[1] > devpriv->hwdmasize[1]) {
+			devpriv->dmabytestomove[1] = devpriv->hwdmasize[1];
+			devpriv->ai_eos = 0;
+		}
+		devpriv->next_dma_buf = 0;
+		set_dma_mode(devpriv->dma, DMA_MODE_READ);
+		dma_flags = claim_dma_lock();
+		clear_dma_ff(devpriv->dma);
+		set_dma_addr(devpriv->dma, devpriv->hwdmaptr[0]);
+		set_dma_count(devpriv->dma, devpriv->dmabytestomove[0]);
+		release_dma_lock(dma_flags);
+		enable_dma(devpriv->dma);
+#ifdef PCL812_EXTDEBUG
+		rt_printk
+			("pcl812 EDBG:   DMA %d PTR 0x%0x/0x%0x LEN %u/%u EOS %d\n",
+			devpriv->dma, devpriv->hwdmaptr[0],
+			devpriv->hwdmaptr[1], devpriv->dmabytestomove[0],
+			devpriv->dmabytestomove[1], devpriv->ai_eos);
+#endif
+	}
+
+	switch (cmd->convert_src) {
+	case TRIG_TIMER:
+		start_pacer(dev, 1, divisor1, divisor2);
+		break;
+	}
+
+	if (devpriv->ai_dma) {
+		outb(devpriv->mode_reg_int | 2, dev->iobase + PCL812_MODE);	// let's go!
+	} else {
+		outb(devpriv->mode_reg_int | 6, dev->iobase + PCL812_MODE);	// let's go!
+	}
+
+#ifdef PCL812_EXTDEBUG
+	rt_printk("pcl812 EDBG: END: pcl812_ai_cmd(...)\n");
+#endif
+
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+static irqreturn_t interrupt_pcl812_ai_int(int irq, void *d)
+{
+	char err = 1;
+	unsigned int mask, timeout;
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s = dev->subdevices + 0;
+
+	s->async->events = 0;
+
+	timeout = 50;		/* wait max 50us, it must finish under 33us */
+	if (devpriv->ai_is16b) {
+		mask = 0xffff;
+		while (timeout--) {
+			if (!(inb(dev->iobase + ACL8216_STATUS) & ACL8216_DRDY)) {
+				err = 0;
+				break;
+			}
+			comedi_udelay(1);
+		}
+	} else {
+		mask = 0x0fff;
+		while (timeout--) {
+			if (!(inb(dev->iobase + PCL812_AD_HI) & PCL812_DRDY)) {
+				err = 0;
+				break;
+			}
+			comedi_udelay(1);
+		}
+	}
+
+	if (err) {
+		rt_printk
+			("comedi%d: pcl812: (%s at 0x%lx) A/D cmd IRQ without DRDY!\n",
+			dev->minor, dev->board_name, dev->iobase);
+		pcl812_ai_cancel(dev, s);
+		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+		comedi_event(dev, s);
+		return IRQ_HANDLED;
+	}
+
+	comedi_buf_put(s->async,
+		((inb(dev->iobase + PCL812_AD_HI) << 8) | inb(dev->iobase +
+				PCL812_AD_LO)) & mask);
+
+	outb(0, dev->iobase + PCL812_CLRINT);	/* clear INT request */
+
+	if (s->async->cur_chan == 0) {	/* one scan done */
+		devpriv->ai_act_scan++;
+		if (!(devpriv->ai_neverending))
+			if (devpriv->ai_act_scan >= devpriv->ai_scans) {	/* all data sampled */
+				pcl812_ai_cancel(dev, s);
+				s->async->events |= COMEDI_CB_EOA;
+			}
+	}
+
+	comedi_event(dev, s);
+	return IRQ_HANDLED;
+}
+
+/*
+==============================================================================
+*/
+static void transfer_from_dma_buf(struct comedi_device * dev, struct comedi_subdevice * s,
+	short * ptr, unsigned int bufptr, unsigned int len)
+{
+	unsigned int i;
+
+	s->async->events = 0;
+	for (i = len; i; i--) {
+		comedi_buf_put(s->async, ptr[bufptr++]);	// get one sample
+
+		if (s->async->cur_chan == 0) {
+			devpriv->ai_act_scan++;
+			if (!devpriv->ai_neverending)
+				if (devpriv->ai_act_scan >= devpriv->ai_scans) {	/* all data sampled */
+					pcl812_ai_cancel(dev, s);
+					s->async->events |= COMEDI_CB_EOA;
+					break;
+				}
+		}
+	}
+
+	comedi_event(dev, s);
+}
+
+/*
+==============================================================================
+*/
+static irqreturn_t interrupt_pcl812_ai_dma(int irq, void *d)
+{
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s = dev->subdevices + 0;
+	unsigned long dma_flags;
+	int len, bufptr;
+	short *ptr;
+
+#ifdef PCL812_EXTDEBUG
+	rt_printk("pcl812 EDBG: BGN: interrupt_pcl812_ai_dma(...)\n");
+#endif
+	ptr = (short *) devpriv->dmabuf[devpriv->next_dma_buf];
+	len = (devpriv->dmabytestomove[devpriv->next_dma_buf] >> 1) -
+		devpriv->ai_poll_ptr;
+
+	devpriv->next_dma_buf = 1 - devpriv->next_dma_buf;
+	disable_dma(devpriv->dma);
+	set_dma_mode(devpriv->dma, DMA_MODE_READ);
+	dma_flags = claim_dma_lock();
+	set_dma_addr(devpriv->dma, devpriv->hwdmaptr[devpriv->next_dma_buf]);
+	if (devpriv->ai_eos) {
+		set_dma_count(devpriv->dma,
+			devpriv->dmabytestomove[devpriv->next_dma_buf]);
+	} else {
+		if (devpriv->dma_runs_to_end) {
+			set_dma_count(devpriv->dma,
+				devpriv->dmabytestomove[devpriv->next_dma_buf]);
+		} else {
+			set_dma_count(devpriv->dma, devpriv->last_dma_run);
+		}
+		devpriv->dma_runs_to_end--;
+	}
+	release_dma_lock(dma_flags);
+	enable_dma(devpriv->dma);
+
+	outb(0, dev->iobase + PCL812_CLRINT);	/* clear INT request */
+
+	bufptr = devpriv->ai_poll_ptr;
+	devpriv->ai_poll_ptr = 0;
+
+	transfer_from_dma_buf(dev, s, ptr, bufptr, len);
+
+#ifdef PCL812_EXTDEBUG
+	rt_printk("pcl812 EDBG: END: interrupt_pcl812_ai_dma(...)\n");
+#endif
+	return IRQ_HANDLED;
+}
+
+/*
+==============================================================================
+*/
+static irqreturn_t interrupt_pcl812(int irq, void *d PT_REGS_ARG)
+{
+	struct comedi_device *dev = d;
+
+	if (!dev->attached) {
+		comedi_error(dev, "spurious interrupt");
+		return IRQ_HANDLED;
+	}
+	if (devpriv->ai_dma) {
+		return interrupt_pcl812_ai_dma(irq, d);
+	} else {
+		return interrupt_pcl812_ai_int(irq, d);
+	};
+}
+
+/*
+==============================================================================
+*/
+static int pcl812_ai_poll(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	unsigned long flags;
+	unsigned int top1, top2, i;
+
+	if (!devpriv->ai_dma)
+		return 0;	// poll is valid only for DMA transfer
+
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+
+	for (i = 0; i < 10; i++) {
+		top1 = get_dma_residue(devpriv->ai_dma);	// where is now DMA
+		top2 = get_dma_residue(devpriv->ai_dma);
+		if (top1 == top2)
+			break;
+	}
+
+	if (top1 != top2) {
+		comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+		return 0;
+	}
+
+	top1 = devpriv->dmabytestomove[1 - devpriv->next_dma_buf] - top1;	// where is now DMA in buffer
+	top1 >>= 1;		// sample position
+	top2 = top1 - devpriv->ai_poll_ptr;
+	if (top2 < 1) {		// no new samples
+		comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+		return 0;
+	}
+
+	transfer_from_dma_buf(dev, s,
+		(void *)devpriv->dmabuf[1 - devpriv->next_dma_buf],
+		devpriv->ai_poll_ptr, top2);
+
+	devpriv->ai_poll_ptr = top1;	// new buffer position
+
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	return s->async->buf_write_count - s->async->buf_read_count;
+}
+
+/*
+==============================================================================
+*/
+static void setup_range_channel(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int rangechan, char wait)
+{
+	unsigned char chan_reg = CR_CHAN(rangechan);	// normal board
+	unsigned char gain_reg = CR_RANGE(rangechan) + devpriv->range_correction;	// gain index
+
+	if ((chan_reg == devpriv->old_chan_reg)
+		&& (gain_reg == devpriv->old_gain_reg))
+		return;		// we can return, no change
+
+	devpriv->old_chan_reg = chan_reg;
+	devpriv->old_gain_reg = gain_reg;
+
+	if (devpriv->use_MPC) {
+		if (devpriv->use_diff) {
+			chan_reg = chan_reg | 0x30;	// DIFF inputs
+		} else {
+			if (chan_reg & 0x80) {
+				chan_reg = chan_reg | 0x20;	// SE inputs 8-15
+			} else {
+				chan_reg = chan_reg | 0x10;	// SE inputs 0-7
+			}
+		}
+	}
+
+	outb(chan_reg, dev->iobase + PCL812_MUX);	/* select channel */
+	outb(gain_reg, dev->iobase + PCL812_GAIN);	/* select gain */
+
+	if (wait) {
+		comedi_udelay(devpriv->max_812_ai_mode0_rangewait);	// XXX this depends on selected range and can be very long for some high gain ranges!
+	}
+}
+
+/*
+==============================================================================
+*/
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+	unsigned int divisor2)
+{
+#ifdef PCL812_EXTDEBUG
+	rt_printk("pcl812 EDBG: BGN: start_pacer(%d,%u,%u)\n", mode, divisor1,
+		divisor2);
+#endif
+	outb(0xb4, dev->iobase + PCL812_CTRCTL);
+	outb(0x74, dev->iobase + PCL812_CTRCTL);
+	comedi_udelay(1);
+
+	if (mode == 1) {
+		outb(divisor2 & 0xff, dev->iobase + PCL812_CTR2);
+		outb((divisor2 >> 8) & 0xff, dev->iobase + PCL812_CTR2);
+		outb(divisor1 & 0xff, dev->iobase + PCL812_CTR1);
+		outb((divisor1 >> 8) & 0xff, dev->iobase + PCL812_CTR1);
+	}
+#ifdef PCL812_EXTDEBUG
+	rt_printk("pcl812 EDBG: END: start_pacer(...)\n");
+#endif
+}
+
+/*
+==============================================================================
+*/
+static void free_resources(struct comedi_device * dev)
+{
+
+	if (dev->private) {
+		if (devpriv->dmabuf[0])
+			free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]);
+		if (devpriv->dmabuf[1])
+			free_pages(devpriv->dmabuf[1], devpriv->dmapages[1]);
+		if (devpriv->dma)
+			free_dma(devpriv->dma);
+	}
+	if (dev->irq)
+		comedi_free_irq(dev->irq, dev);
+	if (dev->iobase)
+		release_region(dev->iobase, this_board->io_range);
+}
+
+/*
+==============================================================================
+*/
+static int pcl812_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+#ifdef PCL812_EXTDEBUG
+	rt_printk("pcl812 EDBG: BGN: pcl812_ai_cancel(...)\n");
+#endif
+	if (devpriv->ai_dma)
+		disable_dma(devpriv->dma);
+	outb(0, dev->iobase + PCL812_CLRINT);	/* clear INT request */
+	outb(devpriv->mode_reg_int | 0, dev->iobase + PCL812_MODE);	/* Stop A/D */
+	start_pacer(dev, -1, 0, 0);	// stop 8254
+	outb(0, dev->iobase + PCL812_CLRINT);	/* clear INT request */
+#ifdef PCL812_EXTDEBUG
+	rt_printk("pcl812 EDBG: END: pcl812_ai_cancel(...)\n");
+#endif
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+static void pcl812_reset(struct comedi_device * dev)
+{
+#ifdef PCL812_EXTDEBUG
+	rt_printk("pcl812 EDBG: BGN: pcl812_reset(...)\n");
+#endif
+	outb(0, dev->iobase + PCL812_MUX);
+	outb(0 + devpriv->range_correction, dev->iobase + PCL812_GAIN);
+	devpriv->old_chan_reg = -1;	// invalidate chain/gain memory
+	devpriv->old_gain_reg = -1;
+
+	switch (this_board->board_type) {
+	case boardPCL812PG:
+	case boardPCL812:
+	case boardACL8112:
+	case boardACL8216:
+		outb(0, dev->iobase + PCL812_DA2_LO);
+		outb(0, dev->iobase + PCL812_DA2_HI);
+	case boardA821:
+		outb(0, dev->iobase + PCL812_DA1_LO);
+		outb(0, dev->iobase + PCL812_DA1_HI);
+		start_pacer(dev, -1, 0, 0);	// stop 8254
+		outb(0, dev->iobase + PCL812_DO_HI);
+		outb(0, dev->iobase + PCL812_DO_LO);
+		outb(devpriv->mode_reg_int | 0, dev->iobase + PCL812_MODE);
+		outb(0, dev->iobase + PCL812_CLRINT);
+		break;
+	case boardPCL813B:
+	case boardPCL813:
+	case boardISO813:
+	case boardACL8113:
+		comedi_udelay(5);
+		break;
+	}
+	comedi_udelay(5);
+#ifdef PCL812_EXTDEBUG
+	rt_printk("pcl812 EDBG: END: pcl812_reset(...)\n");
+#endif
+}
+
+/*
+==============================================================================
+*/
+static int pcl812_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	int ret, subdev;
+	unsigned long iobase;
+	unsigned int irq;
+	unsigned int dma;
+	unsigned long pages;
+	struct comedi_subdevice *s;
+	int n_subdevices;
+
+	iobase = it->options[0];
+	printk("comedi%d: pcl812:  board=%s, ioport=0x%03lx", dev->minor,
+		this_board->name, iobase);
+
+	if (!request_region(iobase, this_board->io_range, "pcl812")) {
+		printk("I/O port conflict\n");
+		return -EIO;
+	}
+	dev->iobase = iobase;
+
+	if ((ret = alloc_private(dev, sizeof(struct pcl812_private))) < 0) {
+		free_resources(dev);
+		return ret;	/* Can't alloc mem */
+	}
+
+	dev->board_name = this_board->name;
+
+	irq = 0;
+	if (this_board->IRQbits != 0) {	/* board support IRQ */
+		irq = it->options[1];
+		if (irq) {	/* we want to use IRQ */
+			if (((1 << irq) & this_board->IRQbits) == 0) {
+				printk(", IRQ %u is out of allowed range, DISABLING IT", irq);
+				irq = 0;	/* Bad IRQ */
+			} else {
+				if (comedi_request_irq(irq, interrupt_pcl812, 0,
+						"pcl812", dev)) {
+					printk(", unable to allocate IRQ %u, DISABLING IT", irq);
+					irq = 0;	/* Can't use IRQ */
+				} else {
+					printk(", irq=%u", irq);
+				}
+			}
+		}
+	}
+
+	dev->irq = irq;
+
+	dma = 0;
+	devpriv->dma = dma;
+	if (!dev->irq)
+		goto no_dma;	/* if we haven't IRQ, we can't use DMA */
+	if (this_board->DMAbits != 0) {	/* board support DMA */
+		dma = it->options[2];
+		if (((1 << dma) & this_board->DMAbits) == 0) {
+			printk(", DMA is out of allowed range, FAIL!\n");
+			return -EINVAL;	/* Bad DMA */
+		}
+		ret = request_dma(dma, "pcl812");
+		if (ret) {
+			printk(", unable to allocate DMA %u, FAIL!\n", dma);
+			return -EBUSY;	/* DMA isn't free */
+		}
+		devpriv->dma = dma;
+		printk(", dma=%u", dma);
+		pages = 1;	/* we want 8KB */
+		devpriv->dmabuf[0] = __get_dma_pages(GFP_KERNEL, pages);
+		if (!devpriv->dmabuf[0]) {
+			printk(", unable to allocate DMA buffer, FAIL!\n");
+			/* maybe experiment with try_to_free_pages() will help .... */
+			free_resources(dev);
+			return -EBUSY;	/* no buffer :-( */
+		}
+		devpriv->dmapages[0] = pages;
+		devpriv->hwdmaptr[0] = virt_to_bus((void *)devpriv->dmabuf[0]);
+		devpriv->hwdmasize[0] = PAGE_SIZE * (1 << pages);
+		devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages);
+		if (!devpriv->dmabuf[1]) {
+			printk(", unable to allocate DMA buffer, FAIL!\n");
+			free_resources(dev);
+			return -EBUSY;
+		}
+		devpriv->dmapages[1] = pages;
+		devpriv->hwdmaptr[1] = virt_to_bus((void *)devpriv->dmabuf[1]);
+		devpriv->hwdmasize[1] = PAGE_SIZE * (1 << pages);
+	}
+      no_dma:
+
+	n_subdevices = 0;
+	if (this_board->n_aichan > 0)
+		n_subdevices++;
+	if (this_board->n_aochan > 0)
+		n_subdevices++;
+	if (this_board->n_dichan > 0)
+		n_subdevices++;
+	if (this_board->n_dochan > 0)
+		n_subdevices++;
+
+	if ((ret = alloc_subdevices(dev, n_subdevices)) < 0) {
+		free_resources(dev);
+		return ret;
+	}
+
+	subdev = 0;
+
+	/* analog input */
+	if (this_board->n_aichan > 0) {
+		s = dev->subdevices + subdev;
+		s->type = COMEDI_SUBD_AI;
+		s->subdev_flags = SDF_READABLE;
+		switch (this_board->board_type) {
+		case boardA821:
+			if (it->options[2] == 1) {
+				s->n_chan = this_board->n_aichan_diff;
+				s->subdev_flags |= SDF_DIFF;
+				devpriv->use_diff = 1;
+			} else {
+				s->n_chan = this_board->n_aichan;
+				s->subdev_flags |= SDF_GROUND;
+			}
+			break;
+		case boardACL8112:
+		case boardACL8216:
+			if (it->options[4] == 1) {
+				s->n_chan = this_board->n_aichan_diff;
+				s->subdev_flags |= SDF_DIFF;
+				devpriv->use_diff = 1;
+			} else {
+				s->n_chan = this_board->n_aichan;
+				s->subdev_flags |= SDF_GROUND;
+			}
+			break;
+		default:
+			s->n_chan = this_board->n_aichan;
+			s->subdev_flags |= SDF_GROUND;
+			break;
+		}
+		s->maxdata = this_board->ai_maxdata;
+		s->len_chanlist = MAX_CHANLIST_LEN;
+		s->range_table = this_board->rangelist_ai;
+		if (this_board->board_type == boardACL8216) {
+			s->insn_read = acl8216_ai_insn_read;
+		} else {
+			s->insn_read = pcl812_ai_insn_read;
+		}
+		devpriv->use_MPC = this_board->haveMPC508;
+		s->cancel = pcl812_ai_cancel;
+		if (dev->irq) {
+			dev->read_subdev = s;
+			s->subdev_flags |= SDF_CMD_READ;
+			s->do_cmdtest = pcl812_ai_cmdtest;
+			s->do_cmd = pcl812_ai_cmd;
+			s->poll = pcl812_ai_poll;
+		}
+		switch (this_board->board_type) {
+		case boardPCL812PG:
+			if (it->options[4] == 1)
+				s->range_table = &range_pcl812pg2_ai;
+			break;
+		case boardPCL812:
+			switch (it->options[4]) {
+			case 0:
+				s->range_table = &range_bipolar10;
+				break;
+			case 1:
+				s->range_table = &range_bipolar5;
+				break;
+			case 2:
+				s->range_table = &range_bipolar2_5;
+				break;
+			case 3:
+				s->range_table = &range812_bipolar1_25;
+				break;
+			case 4:
+				s->range_table = &range812_bipolar0_625;
+				break;
+			case 5:
+				s->range_table = &range812_bipolar0_3125;
+				break;
+			default:
+				s->range_table = &range_bipolar10;
+				break;
+				printk(", incorrect range number %d, changing to 0 (+/-10V)", it->options[4]);
+				break;
+			}
+			break;
+			break;
+		case boardPCL813B:
+			if (it->options[1] == 1)
+				s->range_table = &range_pcl813b2_ai;
+			break;
+		case boardISO813:
+			switch (it->options[1]) {
+			case 0:
+				s->range_table = &range_iso813_1_ai;
+				break;
+			case 1:
+				s->range_table = &range_iso813_1_2_ai;
+				break;
+			case 2:
+				s->range_table = &range_iso813_2_ai;
+				devpriv->range_correction = 1;
+				break;
+			case 3:
+				s->range_table = &range_iso813_2_2_ai;
+				devpriv->range_correction = 1;
+				break;
+			default:
+				s->range_table = &range_iso813_1_ai;
+				break;
+				printk(", incorrect range number %d, changing to 0 ", it->options[1]);
+				break;
+			}
+			break;
+		case boardACL8113:
+			switch (it->options[1]) {
+			case 0:
+				s->range_table = &range_acl8113_1_ai;
+				break;
+			case 1:
+				s->range_table = &range_acl8113_1_2_ai;
+				break;
+			case 2:
+				s->range_table = &range_acl8113_2_ai;
+				devpriv->range_correction = 1;
+				break;
+			case 3:
+				s->range_table = &range_acl8113_2_2_ai;
+				devpriv->range_correction = 1;
+				break;
+			default:
+				s->range_table = &range_acl8113_1_ai;
+				break;
+				printk(", incorrect range number %d, changing to 0 ", it->options[1]);
+				break;
+			}
+			break;
+		}
+		subdev++;
+	}
+
+	/* analog output */
+	if (this_board->n_aochan > 0) {
+		s = dev->subdevices + subdev;
+		s->type = COMEDI_SUBD_AO;
+		s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
+		s->n_chan = this_board->n_aochan;
+		s->maxdata = 0xfff;
+		s->len_chanlist = 1;
+		s->range_table = this_board->rangelist_ao;
+		s->insn_read = pcl812_ao_insn_read;
+		s->insn_write = pcl812_ao_insn_write;
+		switch (this_board->board_type) {
+		case boardA821:
+			if (it->options[3] == 1)
+				s->range_table = &range_unipolar10;
+			break;
+		case boardPCL812:
+		case boardACL8112:
+		case boardPCL812PG:
+		case boardACL8216:
+			if (it->options[5] == 1)
+				s->range_table = &range_unipolar10;
+			if (it->options[5] == 2)
+				s->range_table = &range_unknown;
+			break;
+		}
+		subdev++;
+	}
+
+	/* digital input */
+	if (this_board->n_dichan > 0) {
+		s = dev->subdevices + subdev;
+		s->type = COMEDI_SUBD_DI;
+		s->subdev_flags = SDF_READABLE;
+		s->n_chan = this_board->n_dichan;
+		s->maxdata = 1;
+		s->len_chanlist = this_board->n_dichan;
+		s->range_table = &range_digital;
+		s->insn_bits = pcl812_di_insn_bits;
+		subdev++;
+	}
+
+	/* digital output */
+	if (this_board->n_dochan > 0) {
+		s = dev->subdevices + subdev;
+		s->type = COMEDI_SUBD_DO;
+		s->subdev_flags = SDF_WRITABLE;
+		s->n_chan = this_board->n_dochan;
+		s->maxdata = 1;
+		s->len_chanlist = this_board->n_dochan;
+		s->range_table = &range_digital;
+		s->insn_bits = pcl812_do_insn_bits;
+		subdev++;
+	}
+
+	switch (this_board->board_type) {
+	case boardACL8216:
+		devpriv->ai_is16b = 1;
+	case boardPCL812PG:
+	case boardPCL812:
+	case boardACL8112:
+		devpriv->max_812_ai_mode0_rangewait = 1;
+		if (it->options[3] > 0)
+			devpriv->use_ext_trg = 1;	// we use external trigger
+	case boardA821:
+		devpriv->max_812_ai_mode0_rangewait = 1;
+		devpriv->mode_reg_int = (irq << 4) & 0xf0;
+		break;
+	case boardPCL813B:
+	case boardPCL813:
+	case boardISO813:
+	case boardACL8113:
+		devpriv->max_812_ai_mode0_rangewait = 5;	/* maybe there must by greatest timeout */
+		break;
+	}
+
+	printk("\n");
+	devpriv->valid = 1;
+
+	pcl812_reset(dev);
+
+	return 0;
+}
+
+/*
+==============================================================================
+ */
+static int pcl812_detach(struct comedi_device * dev)
+{
+
+#ifdef PCL812_EXTDEBUG
+	rt_printk("comedi%d: pcl812: remove\n", dev->minor);
+#endif
+	free_resources(dev);
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c
new file mode 100644
index 0000000..515ba74
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcl816.c
@@ -0,0 +1,1251 @@
+/*
+   comedi/drivers/pcl816.c
+
+   Author:  Juan Grigera <juan@grigera.com.ar>
+            based on pcl818 by Michal Dobes <dobes@tesnet.cz> and bits of pcl812
+
+   hardware driver for Advantech cards:
+    card:   PCL-816, PCL814B
+    driver: pcl816
+*/
+/*
+Driver: pcl816
+Description: Advantech PCL-816 cards, PCL-814
+Author: Juan Grigera <juan@grigera.com.ar>
+Devices: [Advantech] PCL-816 (pcl816), PCL-814B (pcl814b)
+Status: works
+Updated: Tue,  2 Apr 2002 23:15:21 -0800
+
+PCL 816 and 814B have 16 SE/DIFF ADCs, 16 DACs, 16 DI and 16 DO.
+Differences are at resolution (16 vs 12 bits).
+
+The driver support AI command mode, other subdevices not written.
+
+Analog output and digital input and output are not supported.
+
+Configuration Options:
+  [0] - IO Base
+  [1] - IRQ	(0=disable, 2, 3, 4, 5, 6, 7)
+  [2] - DMA	(0=disable, 1, 3)
+  [3] - 0, 10=10MHz clock for 8254
+            1= 1MHz clock for 8254
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/mc146818rtc.h>
+#include <linux/delay.h>
+#include <asm/dma.h>
+
+#include "8253.h"
+
+#define DEBUG(x) x
+
+// boards constants
+// IO space len
+#define PCLx1x_RANGE 16
+
+//#define outb(x,y)  printk("OUTB(%x, 200+%d)\n", x,y-0x200); outb(x,y)
+
+// INTEL 8254 counters
+#define PCL816_CTR0 4
+#define PCL816_CTR1 5
+#define PCL816_CTR2 6
+// R: counter read-back register W: counter control
+#define PCL816_CTRCTL 7
+
+// R: A/D high byte W: A/D range control
+#define PCL816_RANGE 9
+// W: clear INT request
+#define PCL816_CLRINT 10
+// R: next mux scan channel W: mux scan channel & range control pointer
+#define PCL816_MUX 11
+// R/W: operation control register
+#define PCL816_CONTROL 12
+
+// R: return status byte  W: set DMA/IRQ
+#define PCL816_STATUS 13
+#define PCL816_STATUS_DRDY_MASK 0x80
+
+// R: low byte of A/D W: soft A/D trigger
+#define PCL816_AD_LO 8
+// R: high byte of A/D W: A/D range control
+#define PCL816_AD_HI 9
+
+// type of interrupt handler
+#define INT_TYPE_AI1_INT 1
+#define INT_TYPE_AI1_DMA 2
+#define INT_TYPE_AI3_INT 4
+#define INT_TYPE_AI3_DMA 5
+#ifdef unused
+#define INT_TYPE_AI1_DMA_RTC 9
+#define INT_TYPE_AI3_DMA_RTC 10
+
+// RTC stuff...
+#define RTC_IRQ 	8
+#define RTC_IO_EXTENT	0x10
+#endif
+
+#define MAGIC_DMA_WORD 0x5a5a
+
+static const struct comedi_lrange range_pcl816 = { 8, {
+			BIP_RANGE(10),
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+			UNI_RANGE(10),
+			UNI_RANGE(5),
+			UNI_RANGE(2.5),
+			UNI_RANGE(1.25),
+	}
+};
+struct pcl816_board {
+
+	const char *name;	// board name
+	int n_ranges;		// len of range list
+	int n_aichan;		// num of A/D chans in diferencial mode
+	unsigned int ai_ns_min;	// minimal alllowed delay between samples (in ns)
+	int n_aochan;		// num of D/A chans
+	int n_dichan;		// num of DI chans
+	int n_dochan;		// num of DO chans
+	const struct comedi_lrange *ai_range_type;	// default A/D rangelist
+	const struct comedi_lrange *ao_range_type;	// dafault D/A rangelist
+	unsigned int io_range;	// len of IO space
+	unsigned int IRQbits;	// allowed interrupts
+	unsigned int DMAbits;	// allowed DMA chans
+	int ai_maxdata;		// maxdata for A/D
+	int ao_maxdata;		// maxdata for D/A
+	int ai_chanlist;	// allowed len of channel list A/D
+	int ao_chanlist;	// allowed len of channel list D/A
+	int i8254_osc_base;	// 1/frequency of on board oscilator in ns
+};
+
+
+static const struct pcl816_board boardtypes[] = {
+	{"pcl816", 8, 16, 10000, 1, 16, 16, &range_pcl816,
+			&range_pcl816, PCLx1x_RANGE,
+			0x00fc,	// IRQ mask
+			0x0a,	// DMA mask
+			0xffff,	// 16-bit card
+			0xffff,	// D/A maxdata
+			1024,
+			1,	// ao chan list
+		100},
+	{"pcl814b", 8, 16, 10000, 1, 16, 16, &range_pcl816,
+			&range_pcl816, PCLx1x_RANGE,
+			0x00fc,
+			0x0a,
+			0x3fff,	/* 14 bit card */
+			0x3fff,
+			1024,
+			1,
+		100},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl816_board))
+#define devpriv ((struct pcl816_private *)dev->private)
+#define this_board ((const struct pcl816_board *)dev->board_ptr)
+
+static int pcl816_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcl816_detach(struct comedi_device * dev);
+
+#ifdef unused
+static int RTC_lock = 0;	/* RTC lock */
+static int RTC_timer_lock = 0;	/* RTC int lock */
+#endif
+
+static struct comedi_driver driver_pcl816 = {
+      driver_name:"pcl816",
+      module:THIS_MODULE,
+      attach:pcl816_attach,
+      detach:pcl816_detach,
+      board_name:&boardtypes[0].name,
+      num_names:n_boardtypes,
+      offset:sizeof(struct pcl816_board),
+};
+
+COMEDI_INITCLEANUP(driver_pcl816);
+
+struct pcl816_private {
+
+	unsigned int dma;	// used DMA, 0=don't use DMA
+	int dma_rtc;		// 1=RTC used with DMA, 0=no RTC alloc
+#ifdef unused
+	unsigned long rtc_iobase;	// RTC port region
+	unsigned int rtc_iosize;
+	unsigned int rtc_irq;
+#endif
+	unsigned long dmabuf[2];	// pointers to begin of DMA buffers
+	unsigned int dmapages[2];	// len of DMA buffers in PAGE_SIZEs
+	unsigned int hwdmaptr[2];	// hardware address of DMA buffers
+	unsigned int hwdmasize[2];	// len of DMA buffers in Bytes
+	unsigned int dmasamplsize;	// size in samples hwdmasize[0]/2
+	unsigned int last_top_dma;	// DMA pointer in last RTC int
+	int next_dma_buf;	// which DMA buffer will be used next round
+	long dma_runs_to_end;	// how many we must permorm DMA transfer to end of record
+	unsigned long last_dma_run;	// how many bytes we must transfer on last DMA page
+
+	unsigned int ai_scans;	// len of scanlist
+	unsigned char ai_neverending;	// if=1, then we do neverending record (you must use cancel())
+	int irq_free;		// 1=have allocated IRQ
+	int irq_blocked;	// 1=IRQ now uses any subdev
+#ifdef unused
+	int rtc_irq_blocked;	// 1=we now do AI with DMA&RTC
+#endif
+	int irq_was_now_closed;	// when IRQ finish, there's stored int816_mode for last interrupt
+	int int816_mode;	// who now uses IRQ - 1=AI1 int, 2=AI1 dma, 3=AI3 int, 4AI3 dma
+	struct comedi_subdevice *last_int_sub;	// ptr to subdevice which now finish
+	int ai_act_scan;	// how many scans we finished
+	unsigned int ai_act_chanlist[16];	// MUX setting for actual AI operations
+	unsigned int ai_act_chanlist_len;	// how long is actual MUX list
+	unsigned int ai_act_chanlist_pos;	// actual position in MUX list
+	unsigned int ai_poll_ptr;	// how many sampes transfer poll
+	struct comedi_subdevice *sub_ai;	// ptr to AI subdevice
+#ifdef unused
+	struct timer_list rtc_irq_timer;	// timer for RTC sanity check
+	unsigned long rtc_freq;	// RTC int freq
+#endif
+};
+
+
+/*
+==============================================================================
+*/
+static int check_and_setup_channel_list(struct comedi_device * dev,
+	struct comedi_subdevice * s, unsigned int *chanlist, int chanlen);
+static int pcl816_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+	unsigned int divisor2);
+#ifdef unused
+static int set_rtc_irq_bit(unsigned char bit);
+#endif
+
+static int pcl816_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd);
+static int pcl816_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+
+/*
+==============================================================================
+   ANALOG INPUT MODE0, 816 cards, slow version
+*/
+static int pcl816_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n;
+	int timeout;
+
+	DPRINTK("mode 0 analog input\n");
+	// software trigger, DMA and INT off
+	outb(0, dev->iobase + PCL816_CONTROL);
+	// clear INT (conversion end) flag
+	outb(0, dev->iobase + PCL816_CLRINT);
+
+	// Set the input channel
+	outb(CR_CHAN(insn->chanspec) & 0xf, dev->iobase + PCL816_MUX);
+	outb(CR_RANGE(insn->chanspec), dev->iobase + PCL816_RANGE);	/* select gain */
+
+	for (n = 0; n < insn->n; n++) {
+
+		outb(0, dev->iobase + PCL816_AD_LO);	/* start conversion */
+
+		timeout = 100;
+		while (timeout--) {
+			if (!(inb(dev->iobase + PCL816_STATUS) &
+					PCL816_STATUS_DRDY_MASK)) {
+				// return read value
+				data[n] =
+					((inb(dev->iobase +
+							PCL816_AD_HI) << 8) |
+					(inb(dev->iobase + PCL816_AD_LO)));
+
+				outb(0, dev->iobase + PCL816_CLRINT);	/* clear INT (conversion end) flag */
+				break;
+			}
+			comedi_udelay(1);
+		}
+		// Return timeout error
+		if (!timeout) {
+			comedi_error(dev, "A/D insn timeout\n");
+			data[0] = 0;
+			outb(0, dev->iobase + PCL816_CLRINT);	/* clear INT (conversion end) flag */
+			return -EIO;
+		}
+
+	}
+	return n;
+}
+
+/*
+==============================================================================
+   analog input interrupt mode 1 & 3, 818 cards
+   one sample per interrupt version
+*/
+static irqreturn_t interrupt_pcl816_ai_mode13_int(int irq, void *d)
+{
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s = dev->subdevices + 0;
+	int low, hi;
+	int timeout = 50;	/* wait max 50us */
+
+	while (timeout--) {
+		if (!(inb(dev->iobase + PCL816_STATUS) &
+				PCL816_STATUS_DRDY_MASK))
+			break;
+		comedi_udelay(1);
+	}
+	if (!timeout) {		// timeout, bail error
+		outb(0, dev->iobase + PCL816_CLRINT);	/* clear INT request */
+		comedi_error(dev, "A/D mode1/3 IRQ without DRDY!");
+		pcl816_ai_cancel(dev, s);
+		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+		comedi_event(dev, s);
+		return IRQ_HANDLED;
+
+	}
+
+	// get the sample
+	low = inb(dev->iobase + PCL816_AD_LO);
+	hi = inb(dev->iobase + PCL816_AD_HI);
+
+	comedi_buf_put(s->async, (hi << 8) | low);
+
+	outb(0, dev->iobase + PCL816_CLRINT);	/* clear INT request */
+
+	if (++devpriv->ai_act_chanlist_pos >= devpriv->ai_act_chanlist_len)
+		devpriv->ai_act_chanlist_pos = 0;
+
+	if (s->async->cur_chan == 0) {
+		devpriv->ai_act_scan++;
+	}
+
+	if (!devpriv->ai_neverending)
+		if (devpriv->ai_act_scan >= devpriv->ai_scans) {	/* all data sampled */
+			/* all data sampled */
+			pcl816_ai_cancel(dev, s);
+			s->async->events |= COMEDI_CB_EOA;
+		}
+	comedi_event(dev, s);
+	return IRQ_HANDLED;
+}
+
+/*
+==============================================================================
+   analog input dma mode 1 & 3, 816 cards
+*/
+static void transfer_from_dma_buf(struct comedi_device * dev, struct comedi_subdevice * s,
+	short * ptr, unsigned int bufptr, unsigned int len)
+{
+	int i;
+
+	s->async->events = 0;
+
+	for (i = 0; i < len; i++) {
+
+		comedi_buf_put(s->async, ptr[bufptr++]);
+
+		if (++devpriv->ai_act_chanlist_pos >=
+			devpriv->ai_act_chanlist_len) {
+			devpriv->ai_act_chanlist_pos = 0;
+			devpriv->ai_act_scan++;
+		}
+
+		if (!devpriv->ai_neverending)
+			if (devpriv->ai_act_scan >= devpriv->ai_scans) {	// all data sampled
+				pcl816_ai_cancel(dev, s);
+				s->async->events |= COMEDI_CB_EOA;
+				s->async->events |= COMEDI_CB_BLOCK;
+				break;
+			}
+	}
+
+	comedi_event(dev, s);
+}
+
+static irqreturn_t interrupt_pcl816_ai_mode13_dma(int irq, void *d)
+{
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s = dev->subdevices + 0;
+	int len, bufptr, this_dma_buf;
+	unsigned long dma_flags;
+	short *ptr;
+
+	disable_dma(devpriv->dma);
+	this_dma_buf = devpriv->next_dma_buf;
+
+	if ((devpriv->dma_runs_to_end > -1) || devpriv->ai_neverending) {	// switch dma bufs
+
+		devpriv->next_dma_buf = 1 - devpriv->next_dma_buf;
+		set_dma_mode(devpriv->dma, DMA_MODE_READ);
+		dma_flags = claim_dma_lock();
+//  clear_dma_ff (devpriv->dma);
+		set_dma_addr(devpriv->dma,
+			devpriv->hwdmaptr[devpriv->next_dma_buf]);
+		if (devpriv->dma_runs_to_end) {
+			set_dma_count(devpriv->dma,
+				devpriv->hwdmasize[devpriv->next_dma_buf]);
+		} else {
+			set_dma_count(devpriv->dma, devpriv->last_dma_run);
+		}
+		release_dma_lock(dma_flags);
+		enable_dma(devpriv->dma);
+	}
+
+	devpriv->dma_runs_to_end--;
+	outb(0, dev->iobase + PCL816_CLRINT);	/* clear INT request */
+
+	ptr = (short *) devpriv->dmabuf[this_dma_buf];
+
+	len = (devpriv->hwdmasize[0] >> 1) - devpriv->ai_poll_ptr;
+	bufptr = devpriv->ai_poll_ptr;
+	devpriv->ai_poll_ptr = 0;
+
+	transfer_from_dma_buf(dev, s, ptr, bufptr, len);
+	return IRQ_HANDLED;
+}
+
+/*
+==============================================================================
+    INT procedure
+*/
+static irqreturn_t interrupt_pcl816(int irq, void *d PT_REGS_ARG)
+{
+	struct comedi_device *dev = d;
+	DPRINTK("<I>");
+
+	if (!dev->attached) {
+		comedi_error(dev, "premature interrupt");
+		return IRQ_HANDLED;
+	}
+
+	switch (devpriv->int816_mode) {
+	case INT_TYPE_AI1_DMA:
+	case INT_TYPE_AI3_DMA:
+		return interrupt_pcl816_ai_mode13_dma(irq, d);
+	case INT_TYPE_AI1_INT:
+	case INT_TYPE_AI3_INT:
+		return interrupt_pcl816_ai_mode13_int(irq, d);
+	}
+
+	outb(0, dev->iobase + PCL816_CLRINT);	/* clear INT request */
+	if ((!dev->irq) | (!devpriv->irq_free) | (!devpriv->irq_blocked) |
+		(!devpriv->int816_mode)) {
+		if (devpriv->irq_was_now_closed) {
+			devpriv->irq_was_now_closed = 0;
+			// comedi_error(dev,"last IRQ..");
+			return IRQ_HANDLED;
+		}
+		comedi_error(dev, "bad IRQ!");
+		return IRQ_NONE;
+	}
+	comedi_error(dev, "IRQ from unknow source!");
+	return IRQ_NONE;
+}
+
+/*
+==============================================================================
+   COMMAND MODE
+*/
+static void pcl816_cmdtest_out(int e, struct comedi_cmd * cmd)
+{
+	rt_printk("pcl816 e=%d startsrc=%x scansrc=%x convsrc=%x\n", e,
+		cmd->start_src, cmd->scan_begin_src, cmd->convert_src);
+	rt_printk("pcl816 e=%d startarg=%d scanarg=%d convarg=%d\n", e,
+		cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg);
+	rt_printk("pcl816 e=%d stopsrc=%x scanend=%x\n", e, cmd->stop_src,
+		cmd->scan_end_src);
+	rt_printk("pcl816 e=%d stoparg=%d scanendarg=%d chanlistlen=%d\n", e,
+		cmd->stop_arg, cmd->scan_end_arg, cmd->chanlist_len);
+}
+
+/*
+==============================================================================
+*/
+static int pcl816_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp, divisor1, divisor2;
+
+	DEBUG(rt_printk("pcl816 pcl812_ai_cmdtest\n");
+		pcl816_cmdtest_out(-1, cmd););
+
+	/* step 1: make sure trigger sources are trivially valid */
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_FOLLOW;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	if (!cmd->convert_src & (TRIG_EXT | TRIG_TIMER))
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err) {
+		return 1;
+	}
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	if (cmd->start_src != TRIG_NOW) {
+		cmd->start_src = TRIG_NOW;
+		err++;
+	}
+
+	if (cmd->scan_begin_src != TRIG_FOLLOW) {
+		cmd->scan_begin_src = TRIG_FOLLOW;
+		err++;
+	}
+
+	if (cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_TIMER) {
+		cmd->convert_src = TRIG_TIMER;
+		err++;
+	}
+
+	if (cmd->scan_end_src != TRIG_COUNT) {
+		cmd->scan_end_src = TRIG_COUNT;
+		err++;
+	}
+
+	if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
+		err++;
+
+	if (err) {
+		return 2;
+	}
+
+	/* step 3: make sure arguments are trivially compatible */
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+
+	if (cmd->scan_begin_arg != 0) {
+		cmd->scan_begin_arg = 0;
+		err++;
+	}
+	if (cmd->convert_src == TRIG_TIMER) {
+		if (cmd->convert_arg < this_board->ai_ns_min) {
+			cmd->convert_arg = this_board->ai_ns_min;
+			err++;
+		}
+	} else {		/* TRIG_EXT */
+		if (cmd->convert_arg != 0) {
+			cmd->convert_arg = 0;
+			err++;
+		}
+	}
+
+	if (!cmd->chanlist_len) {
+		cmd->chanlist_len = 1;
+		err++;
+	}
+	if (cmd->chanlist_len > this_board->n_aichan) {
+		cmd->chanlist_len = this_board->n_aichan;
+		err++;
+	}
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+	if (cmd->stop_src == TRIG_COUNT) {
+		if (!cmd->stop_arg) {
+			cmd->stop_arg = 1;
+			err++;
+		}
+	} else {		/* TRIG_NONE */
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (err) {
+		return 3;
+	}
+
+	/* step 4: fix up any arguments */
+	if (cmd->convert_src == TRIG_TIMER) {
+		tmp = cmd->convert_arg;
+		i8253_cascade_ns_to_timer(this_board->i8254_osc_base,
+			&divisor1, &divisor2, &cmd->convert_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+		if (cmd->convert_arg < this_board->ai_ns_min)
+			cmd->convert_arg = this_board->ai_ns_min;
+		if (tmp != cmd->convert_arg)
+			err++;
+	}
+
+	if (err) {
+		return 4;
+	}
+
+	return 0;
+}
+
+static int pcl816_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	unsigned int divisor1 = 0, divisor2 = 0, dma_flags, bytes, dmairq;
+	struct comedi_cmd *cmd = &s->async->cmd;
+
+	if (cmd->start_src != TRIG_NOW)
+		return -EINVAL;
+	if (cmd->scan_begin_src != TRIG_FOLLOW)
+		return -EINVAL;
+	if (cmd->scan_end_src != TRIG_COUNT)
+		return -EINVAL;
+	if (cmd->scan_end_arg != cmd->chanlist_len)
+		return -EINVAL;
+//      if(cmd->chanlist_len>MAX_CHANLIST_LEN) return -EINVAL;
+	if (devpriv->irq_blocked)
+		return -EBUSY;
+
+	if (cmd->convert_src == TRIG_TIMER) {
+		if (cmd->convert_arg < this_board->ai_ns_min)
+			cmd->convert_arg = this_board->ai_ns_min;
+
+		i8253_cascade_ns_to_timer(this_board->i8254_osc_base, &divisor1,
+			&divisor2, &cmd->convert_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+		if (divisor1 == 1) {	// PCL816 crash if any divisor is set to 1
+			divisor1 = 2;
+			divisor2 /= 2;
+		}
+		if (divisor2 == 1) {
+			divisor2 = 2;
+			divisor1 /= 2;
+		}
+	}
+
+	start_pacer(dev, -1, 0, 0);	// stop pacer
+
+	if (!check_and_setup_channel_list(dev, s, cmd->chanlist,
+			cmd->chanlist_len))
+		return -EINVAL;
+	comedi_udelay(1);
+
+	devpriv->ai_act_scan = 0;
+	s->async->cur_chan = 0;
+	devpriv->irq_blocked = 1;
+	devpriv->ai_poll_ptr = 0;
+	devpriv->irq_was_now_closed = 0;
+
+	if (cmd->stop_src == TRIG_COUNT) {
+		devpriv->ai_scans = cmd->stop_arg;
+		devpriv->ai_neverending = 0;
+	} else {
+		devpriv->ai_scans = 0;
+		devpriv->ai_neverending = 1;
+	}
+
+	if ((cmd->flags & TRIG_WAKE_EOS)) {	// don't we want wake up every scan?
+		printk("pl816: You wankt WAKE_EOS but I dont want handle it");
+		//              devpriv->ai_eos=1;
+		//if (devpriv->ai_n_chan==1)
+		//      devpriv->dma=0; // DMA is useless for this situation
+	}
+
+	if (devpriv->dma) {
+		bytes = devpriv->hwdmasize[0];
+		if (!devpriv->ai_neverending) {
+			bytes = s->async->cmd.chanlist_len * s->async->cmd.chanlist_len * sizeof(short);	// how many
+			devpriv->dma_runs_to_end = bytes / devpriv->hwdmasize[0];	// how many DMA pages we must fill
+			devpriv->last_dma_run = bytes % devpriv->hwdmasize[0];	//on last dma transfer must be moved
+			devpriv->dma_runs_to_end--;
+			if (devpriv->dma_runs_to_end >= 0)
+				bytes = devpriv->hwdmasize[0];
+		} else
+			devpriv->dma_runs_to_end = -1;
+
+		devpriv->next_dma_buf = 0;
+		set_dma_mode(devpriv->dma, DMA_MODE_READ);
+		dma_flags = claim_dma_lock();
+		clear_dma_ff(devpriv->dma);
+		set_dma_addr(devpriv->dma, devpriv->hwdmaptr[0]);
+		set_dma_count(devpriv->dma, bytes);
+		release_dma_lock(dma_flags);
+		enable_dma(devpriv->dma);
+	}
+
+	start_pacer(dev, 1, divisor1, divisor2);
+	dmairq = ((devpriv->dma & 0x3) << 4) | (dev->irq & 0x7);
+
+	switch (cmd->convert_src) {
+	case TRIG_TIMER:
+		devpriv->int816_mode = INT_TYPE_AI1_DMA;
+		outb(0x32, dev->iobase + PCL816_CONTROL);	// Pacer+IRQ+DMA
+		outb(dmairq, dev->iobase + PCL816_STATUS);	// write irq and DMA to card
+		break;
+
+	default:
+		devpriv->int816_mode = INT_TYPE_AI3_DMA;
+		outb(0x34, dev->iobase + PCL816_CONTROL);	// Ext trig+IRQ+DMA
+		outb(dmairq, dev->iobase + PCL816_STATUS);	// write irq to card
+		break;
+	}
+
+	DPRINTK("pcl816 END: pcl812_ai_cmd()\n");
+	return 0;
+}
+
+static int pcl816_ai_poll(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	unsigned long flags;
+	unsigned int top1, top2, i;
+
+	if (!devpriv->dma)
+		return 0;	// poll is valid only for DMA transfer
+
+	comedi_spin_lock_irqsave(&dev->spinlock, flags);
+
+	for (i = 0; i < 20; i++) {
+		top1 = get_dma_residue(devpriv->dma);	// where is now DMA
+		top2 = get_dma_residue(devpriv->dma);
+		if (top1 == top2)
+			break;
+	}
+	if (top1 != top2) {
+		comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+		return 0;
+	}
+
+	top1 = devpriv->hwdmasize[0] - top1;	// where is now DMA in buffer
+	top1 >>= 1;		// sample position
+	top2 = top1 - devpriv->ai_poll_ptr;
+	if (top2 < 1) {		// no new samples
+		comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+		return 0;
+	}
+
+	transfer_from_dma_buf(dev, s,
+		(short *) devpriv->dmabuf[devpriv->next_dma_buf],
+		devpriv->ai_poll_ptr, top2);
+
+	devpriv->ai_poll_ptr = top1;	// new buffer position
+	comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	return s->async->buf_write_count - s->async->buf_read_count;
+}
+
+/*
+==============================================================================
+ cancel any mode 1-4 AI
+*/
+static int pcl816_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+//  DEBUG(rt_printk("pcl816_ai_cancel()\n");)
+
+	if (devpriv->irq_blocked > 0) {
+		switch (devpriv->int816_mode) {
+#ifdef unused
+		case INT_TYPE_AI1_DMA_RTC:
+		case INT_TYPE_AI3_DMA_RTC:
+			set_rtc_irq_bit(0);	// stop RTC
+			del_timer(&devpriv->rtc_irq_timer);
+#endif
+		case INT_TYPE_AI1_DMA:
+		case INT_TYPE_AI3_DMA:
+			disable_dma(devpriv->dma);
+		case INT_TYPE_AI1_INT:
+		case INT_TYPE_AI3_INT:
+			outb(inb(dev->iobase + PCL816_CONTROL) & 0x73, dev->iobase + PCL816_CONTROL);	/* Stop A/D */
+			comedi_udelay(1);
+			outb(0, dev->iobase + PCL816_CONTROL);	/* Stop A/D */
+			outb(0xb0, dev->iobase + PCL816_CTRCTL);	/* Stop pacer */
+			outb(0x70, dev->iobase + PCL816_CTRCTL);
+			outb(0, dev->iobase + PCL816_AD_LO);
+			inb(dev->iobase + PCL816_AD_LO);
+			inb(dev->iobase + PCL816_AD_HI);
+			outb(0, dev->iobase + PCL816_CLRINT);	/* clear INT request */
+			outb(0, dev->iobase + PCL816_CONTROL);	/* Stop A/D */
+			devpriv->irq_blocked = 0;
+			devpriv->irq_was_now_closed = devpriv->int816_mode;
+			devpriv->int816_mode = 0;
+			devpriv->last_int_sub = s;
+//        s->busy = 0;
+			break;
+		}
+	}
+
+	DEBUG(rt_printk("comedi: pcl816_ai_cancel() successful\n");
+		)
+		return 0;
+}
+
+/*
+==============================================================================
+ chech for PCL816
+*/
+static int pcl816_check(unsigned long iobase)
+{
+	outb(0x00, iobase + PCL816_MUX);
+	comedi_udelay(1);
+	if (inb(iobase + PCL816_MUX) != 0x00)
+		return 1;	//there isn't card
+	outb(0x55, iobase + PCL816_MUX);
+	comedi_udelay(1);
+	if (inb(iobase + PCL816_MUX) != 0x55)
+		return 1;	//there isn't card
+	outb(0x00, iobase + PCL816_MUX);
+	comedi_udelay(1);
+	outb(0x18, iobase + PCL816_CONTROL);
+	comedi_udelay(1);
+	if (inb(iobase + PCL816_CONTROL) != 0x18)
+		return 1;	//there isn't card
+	return 0;		// ok, card exist
+}
+
+/*
+==============================================================================
+ reset whole PCL-816 cards
+*/
+static void pcl816_reset(struct comedi_device * dev)
+{
+//  outb (0, dev->iobase + PCL818_DA_LO);       // DAC=0V
+//  outb (0, dev->iobase + PCL818_DA_HI);
+//  comedi_udelay (1);
+//  outb (0, dev->iobase + PCL818_DO_HI);       // DO=$0000
+//  outb (0, dev->iobase + PCL818_DO_LO);
+//  comedi_udelay (1);
+	outb(0, dev->iobase + PCL816_CONTROL);
+	outb(0, dev->iobase + PCL816_MUX);
+	outb(0, dev->iobase + PCL816_CLRINT);
+	outb(0xb0, dev->iobase + PCL816_CTRCTL);	/* Stop pacer */
+	outb(0x70, dev->iobase + PCL816_CTRCTL);
+	outb(0x30, dev->iobase + PCL816_CTRCTL);
+	outb(0, dev->iobase + PCL816_RANGE);
+}
+
+/*
+==============================================================================
+ Start/stop pacer onboard pacer
+*/
+static void
+start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+	unsigned int divisor2)
+{
+	outb(0x32, dev->iobase + PCL816_CTRCTL);
+	outb(0xff, dev->iobase + PCL816_CTR0);
+	outb(0x00, dev->iobase + PCL816_CTR0);
+	comedi_udelay(1);
+	outb(0xb4, dev->iobase + PCL816_CTRCTL);	// set counter 2 as mode 3
+	outb(0x74, dev->iobase + PCL816_CTRCTL);	// set counter 1 as mode 3
+	comedi_udelay(1);
+
+	if (mode == 1) {
+		DPRINTK("mode %d, divisor1 %d, divisor2 %d\n", mode, divisor1,
+			divisor2);
+		outb(divisor2 & 0xff, dev->iobase + PCL816_CTR2);
+		outb((divisor2 >> 8) & 0xff, dev->iobase + PCL816_CTR2);
+		outb(divisor1 & 0xff, dev->iobase + PCL816_CTR1);
+		outb((divisor1 >> 8) & 0xff, dev->iobase + PCL816_CTR1);
+	}
+
+	/* clear pending interrupts (just in case) */
+//      outb(0, dev->iobase + PCL816_CLRINT);
+}
+
+/*
+==============================================================================
+ Check if channel list from user is builded correctly
+ If it's ok, then program scan/gain logic
+*/
+static int
+check_and_setup_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int *chanlist, int chanlen)
+{
+	unsigned int chansegment[16];
+	unsigned int i, nowmustbechan, seglen, segpos;
+
+	// correct channel and range number check itself comedi/range.c
+	if (chanlen < 1) {
+		comedi_error(dev, "range/channel list is empty!");
+		return 0;
+	}
+
+	if (chanlen > 1) {
+		chansegment[0] = chanlist[0];	// first channel is everytime ok
+		for (i = 1, seglen = 1; i < chanlen; i++, seglen++) {
+			// build part of chanlist
+			DEBUG(rt_printk("%d. %d %d\n", i, CR_CHAN(chanlist[i]),
+					CR_RANGE(chanlist[i]));
+				)
+				if (chanlist[0] == chanlist[i])
+				break;	// we detect loop, this must by finish
+			nowmustbechan =
+				(CR_CHAN(chansegment[i - 1]) + 1) % chanlen;
+			if (nowmustbechan != CR_CHAN(chanlist[i])) {
+				// channel list isn't continous :-(
+				rt_printk
+					("comedi%d: pcl816: channel list must be continous! chanlist[%i]=%d but must be %d or %d!\n",
+					dev->minor, i, CR_CHAN(chanlist[i]),
+					nowmustbechan, CR_CHAN(chanlist[0]));
+				return 0;
+			}
+			chansegment[i] = chanlist[i];	// well, this is next correct channel in list
+		}
+
+		for (i = 0, segpos = 0; i < chanlen; i++) {	// check whole chanlist
+			DEBUG(rt_printk("%d %d=%d %d\n",
+					CR_CHAN(chansegment[i % seglen]),
+					CR_RANGE(chansegment[i % seglen]),
+					CR_CHAN(chanlist[i]),
+					CR_RANGE(chanlist[i]));
+				)
+				if (chanlist[i] != chansegment[i % seglen]) {
+				rt_printk
+					("comedi%d: pcl816: bad channel or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
+					dev->minor, i, CR_CHAN(chansegment[i]),
+					CR_RANGE(chansegment[i]),
+					CR_AREF(chansegment[i]),
+					CR_CHAN(chanlist[i % seglen]),
+					CR_RANGE(chanlist[i % seglen]),
+					CR_AREF(chansegment[i % seglen]));
+				return 0;	// chan/gain list is strange
+			}
+		}
+	} else {
+		seglen = 1;
+	}
+
+	devpriv->ai_act_chanlist_len = seglen;
+	devpriv->ai_act_chanlist_pos = 0;
+
+	for (i = 0; i < seglen; i++) {	// store range list to card
+		devpriv->ai_act_chanlist[i] = CR_CHAN(chanlist[i]);
+		outb(CR_CHAN(chanlist[0]) & 0xf, dev->iobase + PCL816_MUX);
+		outb(CR_RANGE(chanlist[0]), dev->iobase + PCL816_RANGE);	/* select gain */
+	}
+
+	comedi_udelay(1);
+
+	outb(devpriv->ai_act_chanlist[0] | (devpriv->ai_act_chanlist[seglen - 1] << 4), dev->iobase + PCL816_MUX);	/* select channel interval to scan */
+
+	return 1;		// we can serve this with MUX logic
+}
+
+#ifdef unused
+/*
+==============================================================================
+  Enable(1)/disable(0) periodic interrupts from RTC
+*/
+static int set_rtc_irq_bit(unsigned char bit)
+{
+	unsigned char val;
+	unsigned long flags;
+
+	if (bit == 1) {
+		RTC_timer_lock++;
+		if (RTC_timer_lock > 1)
+			return 0;
+	} else {
+		RTC_timer_lock--;
+		if (RTC_timer_lock < 0)
+			RTC_timer_lock = 0;
+		if (RTC_timer_lock > 0)
+			return 0;
+	}
+
+	save_flags(flags);
+	cli();
+	val = CMOS_READ(RTC_CONTROL);
+	if (bit) {
+		val |= RTC_PIE;
+	} else {
+		val &= ~RTC_PIE;
+	}
+	CMOS_WRITE(val, RTC_CONTROL);
+	CMOS_READ(RTC_INTR_FLAGS);
+	restore_flags(flags);
+	return 0;
+}
+#endif
+
+/*
+==============================================================================
+  Free any resources that we have claimed
+*/
+static void free_resources(struct comedi_device * dev)
+{
+	//rt_printk("free_resource()\n");
+	if (dev->private) {
+		pcl816_ai_cancel(dev, devpriv->sub_ai);
+		pcl816_reset(dev);
+		if (devpriv->dma)
+			free_dma(devpriv->dma);
+		if (devpriv->dmabuf[0])
+			free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]);
+		if (devpriv->dmabuf[1])
+			free_pages(devpriv->dmabuf[1], devpriv->dmapages[1]);
+#ifdef unused
+		if (devpriv->rtc_irq)
+			comedi_free_irq(devpriv->rtc_irq, dev);
+		if ((devpriv->dma_rtc) && (RTC_lock == 1)) {
+			if (devpriv->rtc_iobase)
+				release_region(devpriv->rtc_iobase,
+					devpriv->rtc_iosize);
+		}
+#endif
+	}
+
+	if (dev->irq)
+		free_irq(dev->irq, dev);
+	if (dev->iobase)
+		release_region(dev->iobase, this_board->io_range);
+	//rt_printk("free_resource() end\n");
+}
+
+/*
+==============================================================================
+
+   Initialization
+
+*/
+static int pcl816_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	int ret;
+	unsigned long iobase;
+	unsigned int irq, dma;
+	unsigned long pages;
+	//int i;
+	struct comedi_subdevice *s;
+
+	/* claim our I/O space */
+	iobase = it->options[0];
+	printk("comedi%d: pcl816:  board=%s, ioport=0x%03lx", dev->minor,
+		this_board->name, iobase);
+
+	if (!request_region(iobase, this_board->io_range, "pcl816")) {
+		rt_printk("I/O port conflict\n");
+		return -EIO;
+	}
+
+	dev->iobase = iobase;
+
+	if (pcl816_check(iobase)) {
+		rt_printk(", I cann't detect board. FAIL!\n");
+		return -EIO;
+	}
+
+	if ((ret = alloc_private(dev, sizeof(struct pcl816_private))) < 0)
+		return ret;	/* Can't alloc mem */
+
+	/* set up some name stuff */
+	dev->board_name = this_board->name;
+
+	/* grab our IRQ */
+	irq = 0;
+	if (this_board->IRQbits != 0) {	/* board support IRQ */
+		irq = it->options[1];
+		if (irq) {	/* we want to use IRQ */
+			if (((1 << irq) & this_board->IRQbits) == 0) {
+				rt_printk
+					(", IRQ %u is out of allowed range, DISABLING IT",
+					irq);
+				irq = 0;	/* Bad IRQ */
+			} else {
+				if (comedi_request_irq(irq, interrupt_pcl816, 0,
+						"pcl816", dev)) {
+					rt_printk
+						(", unable to allocate IRQ %u, DISABLING IT",
+						irq);
+					irq = 0;	/* Can't use IRQ */
+				} else {
+					rt_printk(", irq=%u", irq);
+				}
+			}
+		}
+	}
+
+	dev->irq = irq;
+	if (irq) {
+		devpriv->irq_free = 1;
+	} /* 1=we have allocated irq */
+	else {
+		devpriv->irq_free = 0;
+	}
+	devpriv->irq_blocked = 0;	/* number of subdevice which use IRQ */
+	devpriv->int816_mode = 0;	/* mode of irq */
+
+#ifdef unused
+	/* grab RTC for DMA operations */
+	devpriv->dma_rtc = 0;
+	if (it->options[2] > 0) {	// we want to use DMA
+		if (RTC_lock == 0) {
+			if (!request_region(RTC_PORT(0), RTC_IO_EXTENT,
+					"pcl816 (RTC)"))
+				goto no_rtc;
+		}
+		devpriv->rtc_iobase = RTC_PORT(0);
+		devpriv->rtc_iosize = RTC_IO_EXTENT;
+		RTC_lock++;
+#ifdef UNTESTED_CODE
+		if (!comedi_request_irq(RTC_IRQ,
+				interrupt_pcl816_ai_mode13_dma_rtc, 0,
+				"pcl816 DMA (RTC)", dev)) {
+			devpriv->dma_rtc = 1;
+			devpriv->rtc_irq = RTC_IRQ;
+			rt_printk(", dma_irq=%u", devpriv->rtc_irq);
+		} else {
+			RTC_lock--;
+			if (RTC_lock == 0) {
+				if (devpriv->rtc_iobase)
+					release_region(devpriv->rtc_iobase,
+						devpriv->rtc_iosize);
+			}
+			devpriv->rtc_iobase = 0;
+			devpriv->rtc_iosize = 0;
+		}
+#else
+		printk("pcl816: RTC code missing");
+#endif
+
+	}
+
+      no_rtc:
+#endif
+	/* grab our DMA */
+	dma = 0;
+	devpriv->dma = dma;
+	if ((devpriv->irq_free == 0) && (devpriv->dma_rtc == 0))
+		goto no_dma;	/* if we haven't IRQ, we can't use DMA */
+
+	if (this_board->DMAbits != 0) {	/* board support DMA */
+		dma = it->options[2];
+		if (dma < 1)
+			goto no_dma;	/* DMA disabled */
+
+		if (((1 << dma) & this_board->DMAbits) == 0) {
+			rt_printk(", DMA is out of allowed range, FAIL!\n");
+			return -EINVAL;	/* Bad DMA */
+		}
+		ret = request_dma(dma, "pcl816");
+		if (ret) {
+			rt_printk(", unable to allocate DMA %u, FAIL!\n", dma);
+			return -EBUSY;	/* DMA isn't free */
+		}
+
+		devpriv->dma = dma;
+		rt_printk(", dma=%u", dma);
+		pages = 2;	/* we need 16KB */
+		devpriv->dmabuf[0] = __get_dma_pages(GFP_KERNEL, pages);
+
+		if (!devpriv->dmabuf[0]) {
+			rt_printk(", unable to allocate DMA buffer, FAIL!\n");
+			/* maybe experiment with try_to_free_pages() will help .... */
+			return -EBUSY;	/* no buffer :-( */
+		}
+		devpriv->dmapages[0] = pages;
+		devpriv->hwdmaptr[0] = virt_to_bus((void *)devpriv->dmabuf[0]);
+		devpriv->hwdmasize[0] = (1 << pages) * PAGE_SIZE;
+		//rt_printk("%d %d %ld, ",devpriv->dmapages[0],devpriv->hwdmasize[0],PAGE_SIZE);
+
+		if (devpriv->dma_rtc == 0) {	// we must do duble buff :-(
+			devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages);
+			if (!devpriv->dmabuf[1]) {
+				rt_printk
+					(", unable to allocate DMA buffer, FAIL!\n");
+				return -EBUSY;
+			}
+			devpriv->dmapages[1] = pages;
+			devpriv->hwdmaptr[1] =
+				virt_to_bus((void *)devpriv->dmabuf[1]);
+			devpriv->hwdmasize[1] = (1 << pages) * PAGE_SIZE;
+		}
+	}
+
+      no_dma:
+
+/*  if (this_board->n_aochan > 0)
+    subdevs[1] = COMEDI_SUBD_AO;
+  if (this_board->n_dichan > 0)
+    subdevs[2] = COMEDI_SUBD_DI;
+  if (this_board->n_dochan > 0)
+    subdevs[3] = COMEDI_SUBD_DO;
+*/
+	if ((ret = alloc_subdevices(dev, 1)) < 0)
+		return ret;
+
+	s = dev->subdevices + 0;
+	if (this_board->n_aichan > 0) {
+		s->type = COMEDI_SUBD_AI;
+		devpriv->sub_ai = s;
+		dev->read_subdev = s;
+		s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+		s->n_chan = this_board->n_aichan;
+		s->subdev_flags |= SDF_DIFF;
+		//printk (", %dchans DIFF DAC - %d", s->n_chan, i);
+		s->maxdata = this_board->ai_maxdata;
+		s->len_chanlist = this_board->ai_chanlist;
+		s->range_table = this_board->ai_range_type;
+		s->cancel = pcl816_ai_cancel;
+		s->do_cmdtest = pcl816_ai_cmdtest;
+		s->do_cmd = pcl816_ai_cmd;
+		s->poll = pcl816_ai_poll;
+		s->insn_read = pcl816_ai_insn_read;
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+#if 0
+case COMEDI_SUBD_AO:
+	s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
+	s->n_chan = this_board->n_aochan;
+	s->maxdata = this_board->ao_maxdata;
+	s->len_chanlist = this_board->ao_chanlist;
+	s->range_table = this_board->ao_range_type;
+	break;
+
+case COMEDI_SUBD_DI:
+	s->subdev_flags = SDF_READABLE;
+	s->n_chan = this_board->n_dichan;
+	s->maxdata = 1;
+	s->len_chanlist = this_board->n_dichan;
+	s->range_table = &range_digital;
+	break;
+
+case COMEDI_SUBD_DO:
+	s->subdev_flags = SDF_WRITABLE;
+	s->n_chan = this_board->n_dochan;
+	s->maxdata = 1;
+	s->len_chanlist = this_board->n_dochan;
+	s->range_table = &range_digital;
+	break;
+#endif
+
+	pcl816_reset(dev);
+
+	rt_printk("\n");
+
+	return 0;
+}
+
+/*
+==============================================================================
+  Removes device
+ */
+static int pcl816_detach(struct comedi_device * dev)
+{
+	DEBUG(rt_printk("comedi%d: pcl816: remove\n", dev->minor);
+		)
+		free_resources(dev);
+#ifdef unused
+	if (devpriv->dma_rtc)
+		RTC_lock--;
+#endif
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c
new file mode 100644
index 0000000..43a9d56
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcl818.c
@@ -0,0 +1,1988 @@
+/*
+   comedi/drivers/pcl818.c
+
+   Author:  Michal Dobes <dobes@tesnet.cz>
+
+   hardware driver for Advantech cards:
+    card:   PCL-818L, PCL-818H, PCL-818HD, PCL-818HG, PCL-818, PCL-718
+    driver: pcl818l,  pcl818h,  pcl818hd,  pcl818hg,  pcl818,  pcl718
+*/
+/*
+Driver: pcl818
+Description: Advantech PCL-818 cards, PCL-718
+Author: Michal Dobes <dobes@tesnet.cz>
+Devices: [Advantech] PCL-818L (pcl818l), PCL-818H (pcl818h),
+  PCL-818HD (pcl818hd), PCL-818HG (pcl818hg), PCL-818 (pcl818),
+  PCL-718 (pcl718)
+Status: works
+
+All cards have 16 SE/8 DIFF ADCs, one or two DACs, 16 DI and 16 DO.
+Differences are only at maximal sample speed, range list and FIFO
+support.
+The driver support AI mode 0, 1, 3 other subdevices (AO, DI, DO) support
+only mode 0. If DMA/FIFO/INT are disabled then AI support only mode 0.
+PCL-818HD and PCL-818HG support 1kword FIFO. Driver support this FIFO
+but this code is untested.
+A word or two about DMA. Driver support DMA operations at two ways:
+1) DMA uses two buffers and after one is filled then is generated
+   INT and DMA restart with second buffer. With this mode I'm unable run
+   more that 80Ksamples/secs without data dropouts on K6/233.
+2) DMA uses one buffer and run in autoinit mode and the data are
+   from DMA buffer moved on the fly with 2kHz interrupts from RTC.
+   This mode is used if the interrupt 8 is available for allocation.
+   If not, then first DMA mode is used. With this I can run at
+   full speed one card (100ksamples/secs) or two cards with
+   60ksamples/secs each (more is problem on account of ISA limitations).
+   To use this mode you must have compiled  kernel with disabled
+   "Enhanced Real Time Clock Support".
+   Maybe you can have problems if you use xntpd or similar.
+   If you've data dropouts with DMA mode 2 then:
+    a) disable IDE DMA
+    b) switch text mode console to fb.
+
+   Options for PCL-818L:
+    [0] - IO Base
+    [1] - IRQ	(0=disable, 2, 3, 4, 5, 6, 7)
+    [2] - DMA	(0=disable, 1, 3)
+    [3] - 0, 10=10MHz clock for 8254
+              1= 1MHz clock for 8254
+    [4] - 0,  5=A/D input  -5V.. +5V
+          1, 10=A/D input -10V..+10V
+    [5] - 0,  5=D/A output 0-5V  (internal reference -5V)
+          1, 10=D/A output 0-10V (internal reference -10V)
+	  2    =D/A output unknow (external reference)
+
+   Options for PCL-818, PCL-818H:
+    [0] - IO Base
+    [1] - IRQ	(0=disable, 2, 3, 4, 5, 6, 7)
+    [2] - DMA	(0=disable, 1, 3)
+    [3] - 0, 10=10MHz clock for 8254
+              1= 1MHz clock for 8254
+    [4] - 0,  5=D/A output 0-5V  (internal reference -5V)
+          1, 10=D/A output 0-10V (internal reference -10V)
+	  2    =D/A output unknow (external reference)
+
+   Options for PCL-818HD, PCL-818HG:
+    [0] - IO Base
+    [1] - IRQ	(0=disable, 2, 3, 4, 5, 6, 7)
+    [2] - DMA/FIFO  (-1=use FIFO, 0=disable both FIFO and DMA,
+                      1=use DMA ch 1, 3=use DMA ch 3)
+    [3] - 0, 10=10MHz clock for 8254
+              1= 1MHz clock for 8254
+    [4] - 0,  5=D/A output 0-5V  (internal reference -5V)
+          1, 10=D/A output 0-10V (internal reference -10V)
+   	  2    =D/A output unknow (external reference)
+
+   Options for PCL-718:
+    [0] - IO Base
+    [1] - IRQ	(0=disable, 2, 3, 4, 5, 6, 7)
+    [2] - DMA	(0=disable, 1, 3)
+    [3] - 0, 10=10MHz clock for 8254
+              1= 1MHz clock for 8254
+    [4] -     0=A/D Range is +/-10V
+	      1=             +/-5V
+	      2=             +/-2.5V
+	      3=             +/-1V
+	      4=             +/-0.5V
+	      5=  	     user defined bipolar
+	      6=	     0-10V
+	      7=	     0-5V
+ 	      8=	     0-2V
+	      9=	     0-1V
+	     10=	     user defined unipolar
+    [5] - 0,  5=D/A outputs 0-5V  (internal reference -5V)
+          1, 10=D/A outputs 0-10V (internal reference -10V)
+	      2=D/A outputs unknow (external reference)
+    [6] - 0, 60=max  60kHz A/D sampling
+          1,100=max 100kHz A/D sampling (PCL-718 with Option 001 installed)
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/mc146818rtc.h>
+#include <linux/delay.h>
+#include <asm/dma.h>
+
+#include "8253.h"
+
+// #define PCL818_MODE13_AO 1
+
+// boards constants
+
+#define boardPCL818L 0
+#define boardPCL818H 1
+#define boardPCL818HD 2
+#define boardPCL818HG 3
+#define boardPCL818 4
+#define boardPCL718 5
+
+// IO space len
+#define PCLx1x_RANGE 16
+// IO space len if we use FIFO
+#define PCLx1xFIFO_RANGE 32
+
+// W: clear INT request
+#define PCL818_CLRINT 8
+// R: return status byte
+#define PCL818_STATUS 8
+// R: A/D high byte W: A/D range control
+#define PCL818_RANGE 1
+// R: next mux scan channel W: mux scan channel & range control pointer
+#define PCL818_MUX 2
+// R/W: operation control register
+#define PCL818_CONTROL 9
+// W: counter enable
+#define PCL818_CNTENABLE 10
+
+// R: low byte of A/D W: soft A/D trigger
+#define PCL818_AD_LO 0
+// R: high byte of A/D W: A/D range control
+#define PCL818_AD_HI 1
+// W: D/A low&high byte
+#define PCL818_DA_LO 4
+#define PCL818_DA_HI 5
+// R: low&high byte of DI
+#define PCL818_DI_LO 3
+#define PCL818_DI_HI 11
+// W: low&high byte of DO
+#define PCL818_DO_LO 3
+#define PCL818_DO_HI 11
+// W: PCL718 second D/A
+#define PCL718_DA2_LO 6
+#define PCL718_DA2_HI 7
+// counters
+#define PCL818_CTR0 12
+#define PCL818_CTR1 13
+#define PCL818_CTR2 14
+// W: counter control
+#define PCL818_CTRCTL 15
+
+// W: fifo enable/disable
+#define PCL818_FI_ENABLE 6
+// W: fifo interrupt clear
+#define PCL818_FI_INTCLR 20
+// W: fifo interrupt clear
+#define PCL818_FI_FLUSH 25
+// R: fifo status
+#define PCL818_FI_STATUS 25
+// R: one record from FIFO
+#define PCL818_FI_DATALO 23
+#define PCL818_FI_DATAHI 23
+
+// type of interrupt handler
+#define INT_TYPE_AI1_INT 1
+#define INT_TYPE_AI1_DMA 2
+#define INT_TYPE_AI1_FIFO 3
+#define INT_TYPE_AI3_INT 4
+#define INT_TYPE_AI3_DMA 5
+#define INT_TYPE_AI3_FIFO 6
+#ifdef PCL818_MODE13_AO
+#define INT_TYPE_AO1_INT 7
+#define INT_TYPE_AO3_INT 8
+#endif
+
+#ifdef unused
+// RTC stuff...
+#define INT_TYPE_AI1_DMA_RTC 9
+#define INT_TYPE_AI3_DMA_RTC 10
+
+#define RTC_IRQ 	8
+#define RTC_IO_EXTENT	0x10
+#endif
+
+#define MAGIC_DMA_WORD 0x5a5a
+
+static const struct comedi_lrange range_pcl818h_ai = { 9, {
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+			BIP_RANGE(0.625),
+			UNI_RANGE(10),
+			UNI_RANGE(5),
+			UNI_RANGE(2.5),
+			UNI_RANGE(1.25),
+			BIP_RANGE(10),
+	}
+};
+
+static const struct comedi_lrange range_pcl818hg_ai = { 10, {
+			BIP_RANGE(5),
+			BIP_RANGE(0.5),
+			BIP_RANGE(0.05),
+			BIP_RANGE(0.005),
+			UNI_RANGE(10),
+			UNI_RANGE(1),
+			UNI_RANGE(0.1),
+			UNI_RANGE(0.01),
+			BIP_RANGE(10),
+			BIP_RANGE(1),
+			BIP_RANGE(0.1),
+			BIP_RANGE(0.01),
+	}
+};
+
+static const struct comedi_lrange range_pcl818l_l_ai = { 4, {
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+			BIP_RANGE(0.625),
+	}
+};
+
+static const struct comedi_lrange range_pcl818l_h_ai = { 4, {
+			BIP_RANGE(10),
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25),
+	}
+};
+
+static const struct comedi_lrange range718_bipolar1 = { 1, {BIP_RANGE(1),} };
+static const struct comedi_lrange range718_bipolar0_5 = { 1, {BIP_RANGE(0.5),} };
+static const struct comedi_lrange range718_unipolar2 = { 1, {UNI_RANGE(2),} };
+static const struct comedi_lrange range718_unipolar1 = { 1, {BIP_RANGE(1),} };
+
+static int pcl818_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcl818_detach(struct comedi_device * dev);
+
+#ifdef unused
+static int RTC_lock = 0;	/* RTC lock */
+static int RTC_timer_lock = 0;	/* RTC int lock */
+#endif
+
+struct pcl818_board {
+
+	const char *name;	// driver name
+	int n_ranges;		// len of range list
+	int n_aichan_se;	// num of A/D chans in single ended  mode
+	int n_aichan_diff;	// num of A/D chans in diferencial mode
+	unsigned int ns_min;	// minimal alllowed delay between samples (in ns)
+	int n_aochan;		// num of D/A chans
+	int n_dichan;		// num of DI chans
+	int n_dochan;		// num of DO chans
+	const struct comedi_lrange *ai_range_type;	// default A/D rangelist
+	const struct comedi_lrange *ao_range_type;	// default D/A rangelist
+	unsigned int io_range;	// len of IO space
+	unsigned int IRQbits;	// allowed interrupts
+	unsigned int DMAbits;	// allowed DMA chans
+	int ai_maxdata;		// maxdata for A/D
+	int ao_maxdata;		// maxdata for D/A
+	unsigned char fifo;	// 1=board has FIFO
+	int is_818;
+};
+
+
+static const struct pcl818_board boardtypes[] = {
+	{"pcl818l", 4, 16, 8, 25000, 1, 16, 16, &range_pcl818l_l_ai,
+			&range_unipolar5, PCLx1x_RANGE, 0x00fc,
+		0x0a, 0xfff, 0xfff, 0, 1},
+	{"pcl818h", 9, 16, 8, 10000, 1, 16, 16, &range_pcl818h_ai,
+			&range_unipolar5, PCLx1x_RANGE, 0x00fc,
+		0x0a, 0xfff, 0xfff, 0, 1},
+	{"pcl818hd", 9, 16, 8, 10000, 1, 16, 16, &range_pcl818h_ai,
+			&range_unipolar5, PCLx1x_RANGE, 0x00fc,
+		0x0a, 0xfff, 0xfff, 1, 1},
+	{"pcl818hg", 12, 16, 8, 10000, 1, 16, 16, &range_pcl818hg_ai,
+			&range_unipolar5, PCLx1x_RANGE, 0x00fc,
+		0x0a, 0xfff, 0xfff, 1, 1},
+	{"pcl818", 9, 16, 8, 10000, 2, 16, 16, &range_pcl818h_ai,
+			&range_unipolar5, PCLx1x_RANGE, 0x00fc,
+		0x0a, 0xfff, 0xfff, 0, 1},
+	{"pcl718", 1, 16, 8, 16000, 2, 16, 16, &range_unipolar5,
+			&range_unipolar5, PCLx1x_RANGE, 0x00fc,
+		0x0a, 0xfff, 0xfff, 0, 0},
+	/* pcm3718 */
+	{"pcm3718", 9, 16, 8, 10000, 0, 16, 16, &range_pcl818h_ai,
+			&range_unipolar5, PCLx1x_RANGE, 0x00fc,
+		0x0a, 0xfff, 0xfff, 0, 1 /* XXX ? */ },
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl818_board))
+
+static struct comedi_driver driver_pcl818 = {
+      driver_name:"pcl818",
+      module:THIS_MODULE,
+      attach:pcl818_attach,
+      detach:pcl818_detach,
+      board_name:&boardtypes[0].name,
+      num_names:n_boardtypes,
+      offset:sizeof(struct pcl818_board),
+};
+
+COMEDI_INITCLEANUP(driver_pcl818);
+
+struct pcl818_private {
+
+	unsigned int dma;	// used DMA, 0=don't use DMA
+	int dma_rtc;		// 1=RTC used with DMA, 0=no RTC alloc
+	unsigned int io_range;
+#ifdef unused
+	unsigned long rtc_iobase;	// RTC port region
+	unsigned int rtc_iosize;
+	unsigned int rtc_irq;
+	struct timer_list rtc_irq_timer;	// timer for RTC sanity check
+	unsigned long rtc_freq;	// RTC int freq
+	int rtc_irq_blocked;	// 1=we now do AI with DMA&RTC
+#endif
+	unsigned long dmabuf[2];	// pointers to begin of DMA buffers
+	unsigned int dmapages[2];	// len of DMA buffers in PAGE_SIZEs
+	unsigned int hwdmaptr[2];	// hardware address of DMA buffers
+	unsigned int hwdmasize[2];	// len of DMA buffers in Bytes
+	unsigned int dmasamplsize;	// size in samples hwdmasize[0]/2
+	unsigned int last_top_dma;	// DMA pointer in last RTC int
+	int next_dma_buf;	// which DMA buffer will be used next round
+	long dma_runs_to_end;	// how many we must permorm DMA transfer to end of record
+	unsigned long last_dma_run;	// how many bytes we must transfer on last DMA page
+	unsigned char neverending_ai;	// if=1, then we do neverending record (you must use cancel())
+	unsigned int ns_min;	// manimal alllowed delay between samples (in us) for actual card
+	int i8253_osc_base;	// 1/frequency of on board oscilator in ns
+	int irq_free;		// 1=have allocated IRQ
+	int irq_blocked;	// 1=IRQ now uses any subdev
+	int irq_was_now_closed;	// when IRQ finish, there's stored int818_mode for last interrupt
+	int ai_mode;		// who now uses IRQ - 1=AI1 int, 2=AI1 dma, 3=AI3 int, 4AI3 dma
+	struct comedi_subdevice *last_int_sub;	// ptr to subdevice which now finish
+	int ai_act_scan;	// how many scans we finished
+	int ai_act_chan;	// actual position in actual scan
+	unsigned int act_chanlist[16];	// MUX setting for actual AI operations
+	unsigned int act_chanlist_len;	// how long is actual MUX list
+	unsigned int act_chanlist_pos;	// actual position in MUX list
+	unsigned int ai_scans;	// len of scanlist
+	unsigned int ai_n_chan;	// how many channels is measured
+	unsigned int *ai_chanlist;	// actaul chanlist
+	unsigned int ai_flags;	// flaglist
+	unsigned int ai_data_len;	// len of data buffer
+	short *ai_data;	// data buffer
+	unsigned int ai_timer1;	// timers
+	unsigned int ai_timer2;
+	struct comedi_subdevice *sub_ai;	// ptr to AI subdevice
+	unsigned char usefifo;	// 1=use fifo
+	unsigned int ao_readback[2];
+};
+
+
+static const unsigned int muxonechan[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,	// used for gain list programming
+	0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
+};
+
+#define devpriv ((struct pcl818_private *)dev->private)
+#define this_board ((const struct pcl818_board *)dev->board_ptr)
+
+/*
+==============================================================================
+*/
+static void setup_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int *chanlist, unsigned int n_chan, unsigned int seglen);
+static int check_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int *chanlist, unsigned int n_chan);
+
+static int pcl818_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+	unsigned int divisor2);
+
+#ifdef unused
+static int set_rtc_irq_bit(unsigned char bit);
+static void rtc_dropped_irq(unsigned long data);
+static int rtc_setfreq_irq(int freq);
+#endif
+
+/*
+==============================================================================
+   ANALOG INPUT MODE0, 818 cards, slow version
+*/
+static int pcl818_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n;
+	int timeout;
+
+	/* software trigger, DMA and INT off */
+	outb(0, dev->iobase + PCL818_CONTROL);
+
+	/* select channel */
+	outb(muxonechan[CR_CHAN(insn->chanspec)], dev->iobase + PCL818_MUX);
+
+	/* select gain */
+	outb(CR_RANGE(insn->chanspec), dev->iobase + PCL818_RANGE);
+
+	for (n = 0; n < insn->n; n++) {
+
+		/* clear INT (conversion end) flag */
+		outb(0, dev->iobase + PCL818_CLRINT);
+
+		/* start conversion */
+		outb(0, dev->iobase + PCL818_AD_LO);
+
+		timeout = 100;
+		while (timeout--) {
+			if (inb(dev->iobase + PCL818_STATUS) & 0x10)
+				goto conv_finish;
+			comedi_udelay(1);
+		}
+		comedi_error(dev, "A/D insn timeout");
+		/* clear INT (conversion end) flag */
+		outb(0, dev->iobase + PCL818_CLRINT);
+		return -EIO;
+
+	      conv_finish:
+		data[n] = ((inb(dev->iobase + PCL818_AD_HI) << 4) |
+			(inb(dev->iobase + PCL818_AD_LO) >> 4));
+	}
+
+	return n;
+}
+
+/*
+==============================================================================
+   ANALOG OUTPUT MODE0, 818 cards
+   only one sample per call is supported
+*/
+static int pcl818_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n;
+	int chan = CR_CHAN(insn->chanspec);
+
+	for (n = 0; n < insn->n; n++) {
+		data[n] = devpriv->ao_readback[chan];
+	}
+
+	return n;
+}
+
+static int pcl818_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n;
+	int chan = CR_CHAN(insn->chanspec);
+
+	for (n = 0; n < insn->n; n++) {
+		devpriv->ao_readback[chan] = data[n];
+		outb((data[n] & 0x000f) << 4, dev->iobase +
+			(chan) ? PCL718_DA2_LO : PCL818_DA_LO);
+		outb((data[n] & 0x0ff0) >> 4, dev->iobase +
+			(chan) ? PCL718_DA2_HI : PCL818_DA_HI);
+	}
+
+	return n;
+}
+
+/*
+==============================================================================
+   DIGITAL INPUT MODE0, 818 cards
+
+   only one sample per call is supported
+*/
+static int pcl818_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	data[1] = inb(dev->iobase + PCL818_DI_LO) |
+		(inb(dev->iobase + PCL818_DI_HI) << 8);
+
+	return 2;
+}
+
+/*
+==============================================================================
+   DIGITAL OUTPUT MODE0, 818 cards
+
+   only one sample per call is supported
+*/
+static int pcl818_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	s->state &= ~data[0];
+	s->state |= (data[0] & data[1]);
+
+	outb(s->state & 0xff, dev->iobase + PCL818_DO_LO);
+	outb((s->state >> 8), dev->iobase + PCL818_DO_HI);
+
+	data[1] = s->state;
+
+	return 2;
+}
+
+/*
+==============================================================================
+   analog input interrupt mode 1 & 3, 818 cards
+   one sample per interrupt version
+*/
+static irqreturn_t interrupt_pcl818_ai_mode13_int(int irq, void *d)
+{
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s = dev->subdevices + 0;
+	int low;
+	int timeout = 50;	/* wait max 50us */
+
+	while (timeout--) {
+		if (inb(dev->iobase + PCL818_STATUS) & 0x10)
+			goto conv_finish;
+		comedi_udelay(1);
+	}
+	outb(0, dev->iobase + PCL818_STATUS);	/* clear INT request */
+	comedi_error(dev, "A/D mode1/3 IRQ without DRDY!");
+	pcl818_ai_cancel(dev, s);
+	s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+	comedi_event(dev, s);
+	return IRQ_HANDLED;
+
+      conv_finish:
+	low = inb(dev->iobase + PCL818_AD_LO);
+	comedi_buf_put(s->async, ((inb(dev->iobase + PCL818_AD_HI) << 4) | (low >> 4)));	// get one sample
+	outb(0, dev->iobase + PCL818_CLRINT);	/* clear INT request */
+
+	if ((low & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) {	// dropout!
+		rt_printk
+			("comedi: A/D mode1/3 IRQ - channel dropout %x!=%x !\n",
+			(low & 0xf),
+			devpriv->act_chanlist[devpriv->act_chanlist_pos]);
+		pcl818_ai_cancel(dev, s);
+		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+		comedi_event(dev, s);
+		return IRQ_HANDLED;
+	}
+	if (s->async->cur_chan == 0) {
+		// rt_printk("E");
+		devpriv->ai_act_scan--;
+	}
+
+	if (!devpriv->neverending_ai) {
+		if (devpriv->ai_act_scan == 0) {	/* all data sampled */
+			pcl818_ai_cancel(dev, s);
+			s->async->events |= COMEDI_CB_EOA;
+		}
+	}
+	comedi_event(dev, s);
+	return IRQ_HANDLED;
+}
+
+/*
+==============================================================================
+   analog input dma mode 1 & 3, 818 cards
+*/
+static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d)
+{
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s = dev->subdevices + 0;
+	int i, len, bufptr;
+	unsigned long flags;
+	short *ptr;
+
+	disable_dma(devpriv->dma);
+	devpriv->next_dma_buf = 1 - devpriv->next_dma_buf;
+	if ((devpriv->dma_runs_to_end) > -1 || devpriv->neverending_ai) {	// switch dma bufs
+		set_dma_mode(devpriv->dma, DMA_MODE_READ);
+		flags = claim_dma_lock();
+		set_dma_addr(devpriv->dma,
+			devpriv->hwdmaptr[devpriv->next_dma_buf]);
+		if (devpriv->dma_runs_to_end || devpriv->neverending_ai) {
+			set_dma_count(devpriv->dma,
+				devpriv->hwdmasize[devpriv->next_dma_buf]);
+		} else {
+			set_dma_count(devpriv->dma, devpriv->last_dma_run);
+		}
+		release_dma_lock(flags);
+		enable_dma(devpriv->dma);
+	}
+	rt_printk("comedi: A/D mode1/3 IRQ \n");
+
+	devpriv->dma_runs_to_end--;
+	outb(0, dev->iobase + PCL818_CLRINT);	/* clear INT request */
+	ptr = (short *) devpriv->dmabuf[1 - devpriv->next_dma_buf];
+
+	len = devpriv->hwdmasize[0] >> 1;
+	bufptr = 0;
+
+	for (i = 0; i < len; i++) {
+		if ((ptr[bufptr] & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) {	// dropout!
+			rt_printk
+				("comedi: A/D mode1/3 DMA - channel dropout %d(card)!=%d(chanlist) at %d !\n",
+				(ptr[bufptr] & 0xf),
+				devpriv->act_chanlist[devpriv->
+					act_chanlist_pos],
+				devpriv->act_chanlist_pos);
+			pcl818_ai_cancel(dev, s);
+			s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+			comedi_event(dev, s);
+			return IRQ_HANDLED;
+		}
+
+		comedi_buf_put(s->async, ptr[bufptr++] >> 4);	// get one sample
+
+		devpriv->act_chanlist_pos++;
+		if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) {
+			devpriv->ai_act_scan--;
+			devpriv->act_chanlist_pos = 0;
+		}
+
+		if (!devpriv->neverending_ai)
+			if (devpriv->ai_act_scan == 0) {	/* all data sampled */
+				pcl818_ai_cancel(dev, s);
+				s->async->events |= COMEDI_CB_EOA;
+				comedi_event(dev, s);
+				// printk("done int ai13 dma\n");
+				return IRQ_HANDLED;
+			}
+	}
+
+	if (len > 0)
+		comedi_event(dev, s);
+	return IRQ_HANDLED;
+}
+
+#ifdef unused
+/*
+==============================================================================
+   analog input dma mode 1 & 3 over RTC, 818 cards
+*/
+static irqreturn_t interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d)
+{
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s = dev->subdevices + 0;
+	unsigned long tmp;
+	unsigned int top1, top2, i, bufptr;
+	long ofs_dats;
+	short *dmabuf = (short *) devpriv->dmabuf[0];
+
+	//outb(2,0x378);
+	switch (devpriv->ai_mode) {
+	case INT_TYPE_AI1_DMA_RTC:
+	case INT_TYPE_AI3_DMA_RTC:
+		tmp = (CMOS_READ(RTC_INTR_FLAGS) & 0xF0);
+		mod_timer(&devpriv->rtc_irq_timer,
+			jiffies + HZ / devpriv->rtc_freq + 2 * HZ / 100);
+
+		for (i = 0; i < 10; i++) {
+			top1 = get_dma_residue(devpriv->dma);
+			top2 = get_dma_residue(devpriv->dma);
+			if (top1 == top2)
+				break;
+		}
+
+		if (top1 != top2)
+			return IRQ_HANDLED;
+		top1 = devpriv->hwdmasize[0] - top1;	// where is now DMA in buffer
+		top1 >>= 1;
+		ofs_dats = top1 - devpriv->last_top_dma;	// new samples from last call
+		if (ofs_dats < 0)
+			ofs_dats = (devpriv->dmasamplsize) + ofs_dats;
+		if (!ofs_dats)
+			return IRQ_HANDLED;	// exit=no new samples from last call
+		// obsluz data
+		i = devpriv->last_top_dma - 1;
+		i &= (devpriv->dmasamplsize - 1);
+
+		if (dmabuf[i] != MAGIC_DMA_WORD) {	// DMA overflow!
+			comedi_error(dev, "A/D mode1/3 DMA buffer overflow!");
+			//rt_printk("I %d dmabuf[i] %d %d\n",i,dmabuf[i],devpriv->dmasamplsize);
+			pcl818_ai_cancel(dev, s);
+			s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+			comedi_event(dev, s);
+			return IRQ_HANDLED;
+		}
+		//rt_printk("r %ld ",ofs_dats);
+
+		bufptr = devpriv->last_top_dma;
+
+		for (i = 0; i < ofs_dats; i++) {
+			if ((dmabuf[bufptr] & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) {	// dropout!
+				rt_printk
+					("comedi: A/D mode1/3 DMA - channel dropout %d!=%d !\n",
+					(dmabuf[bufptr] & 0xf),
+					devpriv->act_chanlist[devpriv->
+						act_chanlist_pos]);
+				pcl818_ai_cancel(dev, s);
+				s->async->events |=
+					COMEDI_CB_EOA | COMEDI_CB_ERROR;
+				comedi_event(dev, s);
+				return IRQ_HANDLED;
+			}
+
+			comedi_buf_put(s->async, dmabuf[bufptr++] >> 4);	// get one sample
+			bufptr &= (devpriv->dmasamplsize - 1);
+
+			if (s->async->cur_chan == 0) {
+				devpriv->ai_act_scan--;
+			}
+
+			if (!devpriv->neverending_ai)
+				if (devpriv->ai_act_scan == 0) {	/* all data sampled */
+					pcl818_ai_cancel(dev, s);
+					s->async->events |= COMEDI_CB_EOA;
+					comedi_event(dev, s);
+					//printk("done int ai13 dma\n");
+					return IRQ_HANDLED;
+				}
+		}
+
+		devpriv->last_top_dma = bufptr;
+		bufptr--;
+		bufptr &= (devpriv->dmasamplsize - 1);
+		dmabuf[bufptr] = MAGIC_DMA_WORD;
+		comedi_event(dev, s);
+		//outb(0,0x378);
+		return IRQ_HANDLED;
+	}
+
+	//outb(0,0x378);
+	return IRQ_HANDLED;
+}
+#endif
+
+/*
+==============================================================================
+   analog input interrupt mode 1 & 3, 818HD/HG cards
+*/
+static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d)
+{
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s = dev->subdevices + 0;
+	int i, len, lo;
+
+	outb(0, dev->iobase + PCL818_FI_INTCLR);	// clear fifo int request
+
+	lo = inb(dev->iobase + PCL818_FI_STATUS);
+
+	if (lo & 4) {
+		comedi_error(dev, "A/D mode1/3 FIFO overflow!");
+		pcl818_ai_cancel(dev, s);
+		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+		comedi_event(dev, s);
+		return IRQ_HANDLED;
+	}
+
+	if (lo & 1) {
+		comedi_error(dev, "A/D mode1/3 FIFO interrupt without data!");
+		pcl818_ai_cancel(dev, s);
+		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+		comedi_event(dev, s);
+		return IRQ_HANDLED;
+	}
+
+	if (lo & 2) {
+		len = 512;
+	} else {
+		len = 0;
+	}
+
+	for (i = 0; i < len; i++) {
+		lo = inb(dev->iobase + PCL818_FI_DATALO);
+		if ((lo & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) {	// dropout!
+			rt_printk
+				("comedi: A/D mode1/3 FIFO - channel dropout %d!=%d !\n",
+				(lo & 0xf),
+				devpriv->act_chanlist[devpriv->
+					act_chanlist_pos]);
+			pcl818_ai_cancel(dev, s);
+			s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+			comedi_event(dev, s);
+			return IRQ_HANDLED;
+		}
+
+		comedi_buf_put(s->async, (lo >> 4) | (inb(dev->iobase + PCL818_FI_DATAHI) << 4));	// get one sample
+
+		if (s->async->cur_chan == 0) {
+			devpriv->ai_act_scan--;
+		}
+
+		if (!devpriv->neverending_ai)
+			if (devpriv->ai_act_scan == 0) {	/* all data sampled */
+				pcl818_ai_cancel(dev, s);
+				s->async->events |= COMEDI_CB_EOA;
+				comedi_event(dev, s);
+				return IRQ_HANDLED;
+			}
+	}
+
+	if (len > 0)
+		comedi_event(dev, s);
+	return IRQ_HANDLED;
+}
+
+/*
+==============================================================================
+    INT procedure
+*/
+static irqreturn_t interrupt_pcl818(int irq, void *d PT_REGS_ARG)
+{
+	struct comedi_device *dev = d;
+
+	if (!dev->attached) {
+		comedi_error(dev, "premature interrupt");
+		return IRQ_HANDLED;
+	}
+	//rt_printk("I\n");
+
+	switch (devpriv->ai_mode) {
+	case INT_TYPE_AI1_DMA:
+	case INT_TYPE_AI3_DMA:
+		return interrupt_pcl818_ai_mode13_dma(irq, d);
+	case INT_TYPE_AI1_INT:
+	case INT_TYPE_AI3_INT:
+		return interrupt_pcl818_ai_mode13_int(irq, d);
+	case INT_TYPE_AI1_FIFO:
+	case INT_TYPE_AI3_FIFO:
+		return interrupt_pcl818_ai_mode13_fifo(irq, d);
+#ifdef PCL818_MODE13_AO
+	case INT_TYPE_AO1_INT:
+	case INT_TYPE_AO3_INT:
+		return interrupt_pcl818_ao_mode13_int(irq, d);
+#endif
+	default:
+		break;
+	}
+
+	outb(0, dev->iobase + PCL818_CLRINT);	/* clear INT request */
+
+	if ((!dev->irq) || (!devpriv->irq_free) || (!devpriv->irq_blocked)
+		|| (!devpriv->ai_mode)) {
+		if (devpriv->irq_was_now_closed) {
+			if (devpriv->neverending_ai &&
+				(devpriv->ai_mode == INT_TYPE_AI1_DMA
+					|| devpriv->ai_mode ==
+					INT_TYPE_AI3_DMA)) {
+				/* we had neverending ai but ai_cancel() has been called
+				   the cleanup from ai_cancel() has been delayed until know
+				   because the card doesn't seem to like being reprogrammed
+				   while a DMA transfer is in progress
+				 */
+				struct comedi_subdevice *s = dev->subdevices + 0;
+				devpriv->ai_mode = devpriv->irq_was_now_closed;
+				devpriv->irq_was_now_closed = 0;
+				devpriv->neverending_ai = 0;
+				pcl818_ai_cancel(dev, s);
+			}
+			devpriv->irq_was_now_closed = 0;
+			return IRQ_HANDLED;
+		}
+		comedi_error(dev, "bad IRQ!");
+		return IRQ_NONE;
+	}
+
+	comedi_error(dev, "IRQ from unknow source!");
+	return IRQ_NONE;
+}
+
+/*
+==============================================================================
+   ANALOG INPUT MODE 1 or 3 DMA , 818 cards
+*/
+static void pcl818_ai_mode13dma_int(int mode, struct comedi_device * dev,
+	struct comedi_subdevice * s)
+{
+	unsigned int flags;
+	unsigned int bytes;
+
+	rt_printk("mode13dma_int, mode: %d\n", mode);
+	disable_dma(devpriv->dma);	// disable dma
+	bytes = devpriv->hwdmasize[0];
+	if (!devpriv->neverending_ai) {
+		bytes = devpriv->ai_n_chan * devpriv->ai_scans * sizeof(short);	// how many
+		devpriv->dma_runs_to_end = bytes / devpriv->hwdmasize[0];	// how many DMA pages we must fiil
+		devpriv->last_dma_run = bytes % devpriv->hwdmasize[0];	//on last dma transfer must be moved
+		devpriv->dma_runs_to_end--;
+		if (devpriv->dma_runs_to_end >= 0)
+			bytes = devpriv->hwdmasize[0];
+	}
+
+	devpriv->next_dma_buf = 0;
+	set_dma_mode(devpriv->dma, DMA_MODE_READ);
+	flags = claim_dma_lock();
+	clear_dma_ff(devpriv->dma);
+	set_dma_addr(devpriv->dma, devpriv->hwdmaptr[0]);
+	set_dma_count(devpriv->dma, bytes);
+	release_dma_lock(flags);
+	enable_dma(devpriv->dma);
+
+	if (mode == 1) {
+		devpriv->ai_mode = INT_TYPE_AI1_DMA;
+		outb(0x87 | (dev->irq << 4), dev->iobase + PCL818_CONTROL);	/* Pacer+IRQ+DMA */
+	} else {
+		devpriv->ai_mode = INT_TYPE_AI3_DMA;
+		outb(0x86 | (dev->irq << 4), dev->iobase + PCL818_CONTROL);	/* Ext trig+IRQ+DMA */
+	};
+}
+
+#ifdef unused
+/*
+==============================================================================
+   ANALOG INPUT MODE 1 or 3 DMA rtc, 818 cards
+*/
+static void pcl818_ai_mode13dma_rtc(int mode, struct comedi_device * dev,
+	struct comedi_subdevice * s)
+{
+	unsigned int flags;
+	short *pole;
+
+	set_dma_mode(devpriv->dma, DMA_MODE_READ | DMA_AUTOINIT);
+	flags = claim_dma_lock();
+	clear_dma_ff(devpriv->dma);
+	set_dma_addr(devpriv->dma, devpriv->hwdmaptr[0]);
+	set_dma_count(devpriv->dma, devpriv->hwdmasize[0]);
+	release_dma_lock(flags);
+	enable_dma(devpriv->dma);
+	devpriv->last_top_dma = 0;	//devpriv->hwdmasize[0];
+	pole = (short *) devpriv->dmabuf[0];
+	devpriv->dmasamplsize = devpriv->hwdmasize[0] / 2;
+	pole[devpriv->dmasamplsize - 1] = MAGIC_DMA_WORD;
+#ifdef unused
+	devpriv->rtc_freq = rtc_setfreq_irq(2048);
+	devpriv->rtc_irq_timer.expires =
+		jiffies + HZ / devpriv->rtc_freq + 2 * HZ / 100;
+	devpriv->rtc_irq_timer.data = (unsigned long)dev;
+	devpriv->rtc_irq_timer.function = rtc_dropped_irq;
+
+	add_timer(&devpriv->rtc_irq_timer);
+#endif
+
+	if (mode == 1) {
+		devpriv->int818_mode = INT_TYPE_AI1_DMA_RTC;
+		outb(0x07 | (dev->irq << 4), dev->iobase + PCL818_CONTROL);	/* Pacer+DMA */
+	} else {
+		devpriv->int818_mode = INT_TYPE_AI3_DMA_RTC;
+		outb(0x06 | (dev->irq << 4), dev->iobase + PCL818_CONTROL);	/* Ext trig+DMA */
+	};
+}
+#endif
+
+/*
+==============================================================================
+   ANALOG INPUT MODE 1 or 3, 818 cards
+*/
+static int pcl818_ai_cmd_mode(int mode, struct comedi_device * dev,
+	struct comedi_subdevice * s)
+{
+	struct comedi_cmd *cmd = &s->async->cmd;
+	int divisor1, divisor2;
+	unsigned int seglen;
+
+	rt_printk("pcl818_ai_cmd_mode()\n");
+	if ((!dev->irq) && (!devpriv->dma_rtc)) {
+		comedi_error(dev, "IRQ not defined!");
+		return -EINVAL;
+	}
+
+	if (devpriv->irq_blocked)
+		return -EBUSY;
+
+	start_pacer(dev, -1, 0, 0);	// stop pacer
+
+	seglen = check_channel_list(dev, s, devpriv->ai_chanlist,
+		devpriv->ai_n_chan);
+	if (seglen < 1)
+		return -EINVAL;
+	setup_channel_list(dev, s, devpriv->ai_chanlist,
+		devpriv->ai_n_chan, seglen);
+
+	comedi_udelay(1);
+
+	devpriv->ai_act_scan = devpriv->ai_scans;
+	devpriv->ai_act_chan = 0;
+	devpriv->irq_blocked = 1;
+	devpriv->irq_was_now_closed = 0;
+	devpriv->neverending_ai = 0;
+	devpriv->act_chanlist_pos = 0;
+	devpriv->dma_runs_to_end = 0;
+
+	if ((devpriv->ai_scans == 0) || (devpriv->ai_scans == -1))
+		devpriv->neverending_ai = 1;	//well, user want neverending
+
+	if (mode == 1) {
+		i8253_cascade_ns_to_timer(devpriv->i8253_osc_base, &divisor1,
+			&divisor2, &cmd->convert_arg, TRIG_ROUND_NEAREST);
+		if (divisor1 == 1) {	/* PCL718/818 crash if any divisor is set to 1 */
+			divisor1 = 2;
+			divisor2 /= 2;
+		}
+		if (divisor2 == 1) {
+			divisor2 = 2;
+			divisor1 /= 2;
+		}
+	}
+
+	outb(0, dev->iobase + PCL818_CNTENABLE);	/* enable pacer */
+
+	switch (devpriv->dma) {
+	case 1:		// DMA
+	case 3:
+		if (devpriv->dma_rtc == 0) {
+			pcl818_ai_mode13dma_int(mode, dev, s);
+		}
+#ifdef unused
+		else {
+			pcl818_ai_mode13dma_rtc(mode, dev, s);
+		}
+#else
+		else {
+			return -EINVAL;
+		}
+#endif
+		break;
+	case 0:		// IRQ
+		// rt_printk("IRQ\n");
+		if (mode == 1) {
+			devpriv->ai_mode = INT_TYPE_AI1_INT;
+			outb(0x83 | (dev->irq << 4), dev->iobase + PCL818_CONTROL);	/* Pacer+IRQ */
+		} else {
+			devpriv->ai_mode = INT_TYPE_AI3_INT;
+			outb(0x82 | (dev->irq << 4), dev->iobase + PCL818_CONTROL);	/* Ext trig+IRQ */
+		};
+		break;
+	case -1:		// FIFO
+		outb(1, dev->iobase + PCL818_FI_ENABLE);	// enable FIFO
+		if (mode == 1) {
+			devpriv->ai_mode = INT_TYPE_AI1_FIFO;
+			outb(0x03, dev->iobase + PCL818_CONTROL);	/* Pacer */
+		} else {
+			devpriv->ai_mode = INT_TYPE_AI3_FIFO;
+			outb(0x02, dev->iobase + PCL818_CONTROL);
+		};		/* Ext trig */
+		break;
+	}
+
+	start_pacer(dev, mode, divisor1, divisor2);
+
+#ifdef unused
+	switch (devpriv->ai_mode) {
+	case INT_TYPE_AI1_DMA_RTC:
+	case INT_TYPE_AI3_DMA_RTC:
+		set_rtc_irq_bit(1);	/* start RTC */
+		break;
+	}
+#endif
+	rt_printk("pcl818_ai_cmd_mode() end\n");
+	return 0;
+}
+
+#ifdef unused
+/*
+==============================================================================
+   ANALOG OUTPUT MODE 1 or 3, 818 cards
+*/
+#ifdef PCL818_MODE13_AO
+static int pcl818_ao_mode13(int mode, struct comedi_device * dev, struct comedi_subdevice * s,
+	comedi_trig * it)
+{
+	int divisor1, divisor2;
+
+	if (!dev->irq) {
+		comedi_error(dev, "IRQ not defined!");
+		return -EINVAL;
+	}
+
+	if (devpriv->irq_blocked)
+		return -EBUSY;
+
+	start_pacer(dev, -1, 0, 0);	// stop pacer
+
+	devpriv->int13_act_scan = it->n;
+	devpriv->int13_act_chan = 0;
+	devpriv->irq_blocked = 1;
+	devpriv->irq_was_now_closed = 0;
+	devpriv->neverending_ai = 0;
+	devpriv->act_chanlist_pos = 0;
+
+	if (mode == 1) {
+		i8253_cascade_ns_to_timer(devpriv->i8253_osc_base, &divisor1,
+			&divisor2, &it->trigvar, TRIG_ROUND_NEAREST);
+		if (divisor1 == 1) {	/* PCL818 crash if any divisor is set to 1 */
+			divisor1 = 2;
+			divisor2 /= 2;
+		}
+		if (divisor2 == 1) {
+			divisor2 = 2;
+			divisor1 /= 2;
+		}
+	}
+
+	outb(0, dev->iobase + PCL818_CNTENABLE);	/* enable pacer */
+	if (mode == 1) {
+		devpriv->int818_mode = INT_TYPE_AO1_INT;
+		outb(0x83 | (dev->irq << 4), dev->iobase + PCL818_CONTROL);	/* Pacer+IRQ */
+	} else {
+		devpriv->int818_mode = INT_TYPE_AO3_INT;
+		outb(0x82 | (dev->irq << 4), dev->iobase + PCL818_CONTROL);	/* Ext trig+IRQ */
+	};
+
+	start_pacer(dev, mode, divisor1, divisor2);
+
+	return 0;
+}
+
+/*
+==============================================================================
+   ANALOG OUTPUT MODE 1, 818 cards
+*/
+static int pcl818_ao_mode1(struct comedi_device * dev, struct comedi_subdevice * s,
+	comedi_trig * it)
+{
+	return pcl818_ao_mode13(1, dev, s, it);
+}
+
+/*
+==============================================================================
+   ANALOG OUTPUT MODE 3, 818 cards
+*/
+static int pcl818_ao_mode3(struct comedi_device * dev, struct comedi_subdevice * s,
+	comedi_trig * it)
+{
+	return pcl818_ao_mode13(3, dev, s, it);
+}
+#endif
+#endif
+
+/*
+==============================================================================
+ Start/stop pacer onboard pacer
+*/
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+	unsigned int divisor2)
+{
+	outb(0xb4, dev->iobase + PCL818_CTRCTL);
+	outb(0x74, dev->iobase + PCL818_CTRCTL);
+	comedi_udelay(1);
+
+	if (mode == 1) {
+		outb(divisor2 & 0xff, dev->iobase + PCL818_CTR2);
+		outb((divisor2 >> 8) & 0xff, dev->iobase + PCL818_CTR2);
+		outb(divisor1 & 0xff, dev->iobase + PCL818_CTR1);
+		outb((divisor1 >> 8) & 0xff, dev->iobase + PCL818_CTR1);
+	}
+}
+
+/*
+==============================================================================
+ Check if channel list from user is builded correctly
+ If it's ok, then program scan/gain logic
+*/
+static int check_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int *chanlist, unsigned int n_chan)
+{
+	unsigned int chansegment[16];
+	unsigned int i, nowmustbechan, seglen, segpos;
+
+	/* correct channel and range number check itself comedi/range.c */
+	if (n_chan < 1) {
+		comedi_error(dev, "range/channel list is empty!");
+		return 0;
+	}
+
+	if (n_chan > 1) {
+		// first channel is everytime ok
+		chansegment[0] = chanlist[0];
+		// build part of chanlist
+		for (i = 1, seglen = 1; i < n_chan; i++, seglen++) {
+			// rt_printk("%d. %d %d\n",i,CR_CHAN(it->chanlist[i]),CR_RANGE(it->chanlist[i]));
+			// we detect loop, this must by finish
+			if (chanlist[0] == chanlist[i])
+				break;
+			nowmustbechan =
+				(CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan;
+			if (nowmustbechan != CR_CHAN(chanlist[i])) {	// channel list isn't continous :-(
+				rt_printk
+					("comedi%d: pcl818: channel list must be continous! chanlist[%i]=%d but must be %d or %d!\n",
+					dev->minor, i, CR_CHAN(chanlist[i]),
+					nowmustbechan, CR_CHAN(chanlist[0]));
+				return 0;
+			}
+			// well, this is next correct channel in list
+			chansegment[i] = chanlist[i];
+		}
+
+		// check whole chanlist
+		for (i = 0, segpos = 0; i < n_chan; i++) {
+			//rt_printk("%d %d=%d %d\n",CR_CHAN(chansegment[i%seglen]),CR_RANGE(chansegment[i%seglen]),CR_CHAN(it->chanlist[i]),CR_RANGE(it->chanlist[i]));
+			if (chanlist[i] != chansegment[i % seglen]) {
+				rt_printk
+					("comedi%d: pcl818: bad channel or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
+					dev->minor, i, CR_CHAN(chansegment[i]),
+					CR_RANGE(chansegment[i]),
+					CR_AREF(chansegment[i]),
+					CR_CHAN(chanlist[i % seglen]),
+					CR_RANGE(chanlist[i % seglen]),
+					CR_AREF(chansegment[i % seglen]));
+				return 0;	// chan/gain list is strange
+			}
+		}
+	} else {
+		seglen = 1;
+	}
+	rt_printk("check_channel_list: seglen %d\n", seglen);
+	return seglen;
+}
+
+static void setup_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int *chanlist, unsigned int n_chan, unsigned int seglen)
+{
+	int i;
+
+	devpriv->act_chanlist_len = seglen;
+	devpriv->act_chanlist_pos = 0;
+
+	for (i = 0; i < seglen; i++) {	// store range list to card
+		devpriv->act_chanlist[i] = CR_CHAN(chanlist[i]);
+		outb(muxonechan[CR_CHAN(chanlist[i])], dev->iobase + PCL818_MUX);	/* select channel */
+		outb(CR_RANGE(chanlist[i]), dev->iobase + PCL818_RANGE);	/* select gain */
+	}
+
+	comedi_udelay(1);
+
+	/* select channel interval to scan */
+	outb(devpriv->act_chanlist[0] | (devpriv->act_chanlist[seglen -
+				1] << 4), dev->iobase + PCL818_MUX);
+}
+
+/*
+==============================================================================
+ Check if board is switched to SE (1) or DIFF(0) mode
+*/
+static int check_single_ended(unsigned int port)
+{
+	if (inb(port + PCL818_STATUS) & 0x20) {
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+/*
+==============================================================================
+*/
+static int ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp, divisor1, divisor2;
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_FOLLOW;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err) {
+		return 1;
+	}
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	if (cmd->start_src != TRIG_NOW) {
+		cmd->start_src = TRIG_NOW;
+		err++;
+	}
+	if (cmd->scan_begin_src != TRIG_FOLLOW) {
+		cmd->scan_begin_src = TRIG_FOLLOW;
+		err++;
+	}
+	if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+		err++;
+
+	if (cmd->scan_end_src != TRIG_COUNT) {
+		cmd->scan_end_src = TRIG_COUNT;
+		err++;
+	}
+
+	if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
+		err++;
+
+	if (err) {
+		return 2;
+	}
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+
+	if (cmd->scan_begin_arg != 0) {
+		cmd->scan_begin_arg = 0;
+		err++;
+	}
+
+	if (cmd->convert_src == TRIG_TIMER) {
+		if (cmd->convert_arg < this_board->ns_min) {
+			cmd->convert_arg = this_board->ns_min;
+			err++;
+		}
+	} else {		/* TRIG_EXT */
+		if (cmd->convert_arg != 0) {
+			cmd->convert_arg = 0;
+			err++;
+		}
+	}
+
+	if (!cmd->chanlist_len) {
+		cmd->chanlist_len = 1;
+		err++;
+	}
+	if (cmd->chanlist_len > s->n_chan) {
+		cmd->chanlist_len = s->n_chan;
+		err++;
+	}
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+	if (cmd->stop_src == TRIG_COUNT) {
+		if (!cmd->stop_arg) {
+			cmd->stop_arg = 1;
+			err++;
+		}
+	} else {		/* TRIG_NONE */
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (err) {
+		return 3;
+	}
+
+	/* step 4: fix up any arguments */
+
+	if (cmd->convert_src == TRIG_TIMER) {
+		tmp = cmd->convert_arg;
+		i8253_cascade_ns_to_timer(devpriv->i8253_osc_base, &divisor1,
+			&divisor2, &cmd->convert_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+		if (cmd->convert_arg < this_board->ns_min)
+			cmd->convert_arg = this_board->ns_min;
+		if (tmp != cmd->convert_arg)
+			err++;
+	}
+
+	if (err) {
+		return 4;
+	}
+
+	/* step 5: complain about special chanlist considerations */
+
+	if (cmd->chanlist) {
+		if (!check_channel_list(dev, s, cmd->chanlist,
+				cmd->chanlist_len))
+			return 5;	// incorrect channels list
+	}
+
+	return 0;
+}
+
+/*
+==============================================================================
+*/
+static int ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_cmd *cmd = &s->async->cmd;
+	int retval;
+
+	rt_printk("pcl818_ai_cmd()\n");
+	devpriv->ai_n_chan = cmd->chanlist_len;
+	devpriv->ai_chanlist = cmd->chanlist;
+	devpriv->ai_flags = cmd->flags;
+	devpriv->ai_data_len = s->async->prealloc_bufsz;
+	devpriv->ai_data = s->async->prealloc_buf;
+	devpriv->ai_timer1 = 0;
+	devpriv->ai_timer2 = 0;
+
+	if (cmd->stop_src == TRIG_COUNT) {
+		devpriv->ai_scans = cmd->stop_arg;
+	} else {
+		devpriv->ai_scans = 0;
+	}
+
+	if (cmd->scan_begin_src == TRIG_FOLLOW) {	// mode 1, 3
+		if (cmd->convert_src == TRIG_TIMER) {	// mode 1
+			devpriv->ai_timer1 = cmd->convert_arg;
+			retval = pcl818_ai_cmd_mode(1, dev, s);
+			rt_printk("pcl818_ai_cmd() end\n");
+			return retval;
+		}
+		if (cmd->convert_src == TRIG_EXT) {	// mode 3
+			return pcl818_ai_cmd_mode(3, dev, s);
+		}
+	}
+
+	return -1;
+}
+
+/*
+==============================================================================
+ cancel any mode 1-4 AI
+*/
+static int pcl818_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	if (devpriv->irq_blocked > 0) {
+		rt_printk("pcl818_ai_cancel()\n");
+		devpriv->irq_was_now_closed = devpriv->ai_mode;
+		devpriv->ai_mode = 0;
+
+		switch (devpriv->irq_was_now_closed) {
+#ifdef unused
+		case INT_TYPE_AI1_DMA_RTC:
+		case INT_TYPE_AI3_DMA_RTC:
+			set_rtc_irq_bit(0);	// stop RTC
+			del_timer(&devpriv->rtc_irq_timer);
+#endif
+		case INT_TYPE_AI1_DMA:
+		case INT_TYPE_AI3_DMA:
+			if (devpriv->neverending_ai) {
+				/* wait for running dma transfer to end, do cleanup in interrupt */
+				goto end;
+			}
+			disable_dma(devpriv->dma);
+		case INT_TYPE_AI1_INT:
+		case INT_TYPE_AI3_INT:
+		case INT_TYPE_AI1_FIFO:
+		case INT_TYPE_AI3_FIFO:
+#ifdef PCL818_MODE13_AO
+		case INT_TYPE_AO1_INT:
+		case INT_TYPE_AO3_INT:
+#endif
+			outb(inb(dev->iobase + PCL818_CONTROL) & 0x73, dev->iobase + PCL818_CONTROL);	/* Stop A/D */
+			comedi_udelay(1);
+			start_pacer(dev, -1, 0, 0);
+			outb(0, dev->iobase + PCL818_AD_LO);
+			inb(dev->iobase + PCL818_AD_LO);
+			inb(dev->iobase + PCL818_AD_HI);
+			outb(0, dev->iobase + PCL818_CLRINT);	/* clear INT request */
+			outb(0, dev->iobase + PCL818_CONTROL);	/* Stop A/D */
+			if (devpriv->usefifo) {	// FIFO shutdown
+				outb(0, dev->iobase + PCL818_FI_INTCLR);
+				outb(0, dev->iobase + PCL818_FI_FLUSH);
+				outb(0, dev->iobase + PCL818_FI_ENABLE);
+			}
+			devpriv->irq_blocked = 0;
+			devpriv->last_int_sub = s;
+			devpriv->neverending_ai = 0;
+			break;
+		}
+	}
+
+      end:
+	rt_printk("pcl818_ai_cancel() end\n");
+	return 0;
+}
+
+/*
+==============================================================================
+ chech for PCL818
+*/
+static int pcl818_check(unsigned long iobase)
+{
+	outb(0x00, iobase + PCL818_MUX);
+	comedi_udelay(1);
+	if (inb(iobase + PCL818_MUX) != 0x00)
+		return 1;	//there isn't card
+	outb(0x55, iobase + PCL818_MUX);
+	comedi_udelay(1);
+	if (inb(iobase + PCL818_MUX) != 0x55)
+		return 1;	//there isn't card
+	outb(0x00, iobase + PCL818_MUX);
+	comedi_udelay(1);
+	outb(0x18, iobase + PCL818_CONTROL);
+	comedi_udelay(1);
+	if (inb(iobase + PCL818_CONTROL) != 0x18)
+		return 1;	//there isn't card
+	return 0;		// ok, card exist
+}
+
+/*
+==============================================================================
+ reset whole PCL-818 cards
+*/
+static void pcl818_reset(struct comedi_device * dev)
+{
+	if (devpriv->usefifo) {	// FIFO shutdown
+		outb(0, dev->iobase + PCL818_FI_INTCLR);
+		outb(0, dev->iobase + PCL818_FI_FLUSH);
+		outb(0, dev->iobase + PCL818_FI_ENABLE);
+	}
+	outb(0, dev->iobase + PCL818_DA_LO);	// DAC=0V
+	outb(0, dev->iobase + PCL818_DA_HI);
+	comedi_udelay(1);
+	outb(0, dev->iobase + PCL818_DO_HI);	// DO=$0000
+	outb(0, dev->iobase + PCL818_DO_LO);
+	comedi_udelay(1);
+	outb(0, dev->iobase + PCL818_CONTROL);
+	outb(0, dev->iobase + PCL818_CNTENABLE);
+	outb(0, dev->iobase + PCL818_MUX);
+	outb(0, dev->iobase + PCL818_CLRINT);
+	outb(0xb0, dev->iobase + PCL818_CTRCTL);	/* Stop pacer */
+	outb(0x70, dev->iobase + PCL818_CTRCTL);
+	outb(0x30, dev->iobase + PCL818_CTRCTL);
+	if (this_board->is_818) {
+		outb(0, dev->iobase + PCL818_RANGE);
+	} else {
+		outb(0, dev->iobase + PCL718_DA2_LO);
+		outb(0, dev->iobase + PCL718_DA2_HI);
+	}
+}
+
+#ifdef unused
+/*
+==============================================================================
+  Enable(1)/disable(0) periodic interrupts from RTC
+*/
+static int set_rtc_irq_bit(unsigned char bit)
+{
+	unsigned char val;
+	unsigned long flags;
+
+	if (bit == 1) {
+		RTC_timer_lock++;
+		if (RTC_timer_lock > 1)
+			return 0;
+	} else {
+		RTC_timer_lock--;
+		if (RTC_timer_lock < 0)
+			RTC_timer_lock = 0;
+		if (RTC_timer_lock > 0)
+			return 0;
+	}
+
+	save_flags(flags);
+	cli();
+	val = CMOS_READ(RTC_CONTROL);
+	if (bit) {
+		val |= RTC_PIE;
+	} else {
+		val &= ~RTC_PIE;
+	}
+	CMOS_WRITE(val, RTC_CONTROL);
+	CMOS_READ(RTC_INTR_FLAGS);
+	restore_flags(flags);
+	return 0;
+}
+
+/*
+==============================================================================
+  Restart RTC if something stop it (xntpd every 11 mins or large IDE transfers)
+*/
+static void rtc_dropped_irq(unsigned long data)
+{
+	struct comedi_device *dev = (void *)data;
+	unsigned long flags, tmp;
+
+	switch (devpriv->int818_mode) {
+	case INT_TYPE_AI1_DMA_RTC:
+	case INT_TYPE_AI3_DMA_RTC:
+		mod_timer(&devpriv->rtc_irq_timer,
+			jiffies + HZ / devpriv->rtc_freq + 2 * HZ / 100);
+		save_flags(flags);
+		cli();
+		tmp = (CMOS_READ(RTC_INTR_FLAGS) & 0xF0);	/* restart */
+		restore_flags(flags);
+		break;
+	};
+}
+
+/*
+==============================================================================
+  Set frequency of interrupts from RTC
+*/
+static int rtc_setfreq_irq(int freq)
+{
+	int tmp = 0;
+	int rtc_freq;
+	unsigned char val;
+	unsigned long flags;
+
+	if (freq < 2)
+		freq = 2;
+	if (freq > 8192)
+		freq = 8192;
+
+	while (freq > (1 << tmp))
+		tmp++;
+
+	rtc_freq = 1 << tmp;
+
+	save_flags(flags);
+	cli();
+	val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0;
+	val |= (16 - tmp);
+	CMOS_WRITE(val, RTC_FREQ_SELECT);
+	restore_flags(flags);
+	return rtc_freq;
+}
+#endif
+
+/*
+==============================================================================
+  Free any resources that we have claimed
+*/
+static void free_resources(struct comedi_device * dev)
+{
+	//rt_printk("free_resource()\n");
+	if (dev->private) {
+		pcl818_ai_cancel(dev, devpriv->sub_ai);
+		pcl818_reset(dev);
+		if (devpriv->dma)
+			free_dma(devpriv->dma);
+		if (devpriv->dmabuf[0])
+			free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]);
+		if (devpriv->dmabuf[1])
+			free_pages(devpriv->dmabuf[1], devpriv->dmapages[1]);
+#ifdef unused
+		if (devpriv->rtc_irq)
+			comedi_free_irq(devpriv->rtc_irq, dev);
+		if ((devpriv->dma_rtc) && (RTC_lock == 1)) {
+			if (devpriv->rtc_iobase)
+				release_region(devpriv->rtc_iobase,
+					devpriv->rtc_iosize);
+		}
+		if (devpriv->dma_rtc)
+			RTC_lock--;
+#endif
+	}
+
+	if (dev->irq)
+		free_irq(dev->irq, dev);
+	if (dev->iobase)
+		release_region(dev->iobase, devpriv->io_range);
+	//rt_printk("free_resource() end\n");
+}
+
+/*
+==============================================================================
+
+   Initialization
+
+*/
+static int pcl818_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	int ret;
+	unsigned long iobase;
+	unsigned int irq, dma;
+	unsigned long pages;
+	struct comedi_subdevice *s;
+
+	if ((ret = alloc_private(dev, sizeof(struct pcl818_private))) < 0)
+		return ret;	/* Can't alloc mem */
+
+	/* claim our I/O space */
+	iobase = it->options[0];
+	printk("comedi%d: pcl818:  board=%s, ioport=0x%03lx",
+		dev->minor, this_board->name, iobase);
+	devpriv->io_range = this_board->io_range;
+	if ((this_board->fifo) && (it->options[2] == -1)) {	// we've board with FIFO and we want to use FIFO
+		devpriv->io_range = PCLx1xFIFO_RANGE;
+		devpriv->usefifo = 1;
+	}
+	if (!request_region(iobase, devpriv->io_range, "pcl818")) {
+		rt_printk("I/O port conflict\n");
+		return -EIO;
+	}
+
+	dev->iobase = iobase;
+
+	if (pcl818_check(iobase)) {
+		rt_printk(", I can't detect board. FAIL!\n");
+		return -EIO;
+	}
+
+	/* set up some name stuff */
+	dev->board_name = this_board->name;
+	/* grab our IRQ */
+	irq = 0;
+	if (this_board->IRQbits != 0) {	/* board support IRQ */
+		irq = it->options[1];
+		if (irq) {	/* we want to use IRQ */
+			if (((1 << irq) & this_board->IRQbits) == 0) {
+				rt_printk
+					(", IRQ %u is out of allowed range, DISABLING IT",
+					irq);
+				irq = 0;	/* Bad IRQ */
+			} else {
+				if (comedi_request_irq(irq, interrupt_pcl818, 0,
+						"pcl818", dev)) {
+					rt_printk
+						(", unable to allocate IRQ %u, DISABLING IT",
+						irq);
+					irq = 0;	/* Can't use IRQ */
+				} else {
+					rt_printk(", irq=%u", irq);
+				}
+			}
+		}
+	}
+
+	dev->irq = irq;
+	if (irq) {
+		devpriv->irq_free = 1;
+	} /* 1=we have allocated irq */
+	else {
+		devpriv->irq_free = 0;
+	}
+	devpriv->irq_blocked = 0;	/* number of subdevice which use IRQ */
+	devpriv->ai_mode = 0;	/* mode of irq */
+
+#ifdef unused
+	/* grab RTC for DMA operations */
+	devpriv->dma_rtc = 0;
+	if (it->options[2] > 0) {	// we want to use DMA
+		if (RTC_lock == 0) {
+			if (!request_region(RTC_PORT(0), RTC_IO_EXTENT,
+					"pcl818 (RTC)"))
+				goto no_rtc;
+		}
+		devpriv->rtc_iobase = RTC_PORT(0);
+		devpriv->rtc_iosize = RTC_IO_EXTENT;
+		RTC_lock++;
+		if (!comedi_request_irq(RTC_IRQ,
+				interrupt_pcl818_ai_mode13_dma_rtc, 0,
+				"pcl818 DMA (RTC)", dev)) {
+			devpriv->dma_rtc = 1;
+			devpriv->rtc_irq = RTC_IRQ;
+			rt_printk(", dma_irq=%u", devpriv->rtc_irq);
+		} else {
+			RTC_lock--;
+			if (RTC_lock == 0) {
+				if (devpriv->rtc_iobase)
+					release_region(devpriv->rtc_iobase,
+						devpriv->rtc_iosize);
+			}
+			devpriv->rtc_iobase = 0;
+			devpriv->rtc_iosize = 0;
+		}
+	}
+
+      no_rtc:
+#endif
+	/* grab our DMA */
+	dma = 0;
+	devpriv->dma = dma;
+	if ((devpriv->irq_free == 0) && (devpriv->dma_rtc == 0))
+		goto no_dma;	/* if we haven't IRQ, we can't use DMA */
+	if (this_board->DMAbits != 0) {	/* board support DMA */
+		dma = it->options[2];
+		if (dma < 1)
+			goto no_dma;	/* DMA disabled */
+		if (((1 << dma) & this_board->DMAbits) == 0) {
+			rt_printk(", DMA is out of allowed range, FAIL!\n");
+			return -EINVAL;	/* Bad DMA */
+		}
+		ret = request_dma(dma, "pcl818");
+		if (ret) {
+			rt_printk(", unable to allocate DMA %u, FAIL!\n", dma);
+			return -EBUSY;	/* DMA isn't free */
+		}
+		devpriv->dma = dma;
+		rt_printk(", dma=%u", dma);
+		pages = 2;	/* we need 16KB */
+		devpriv->dmabuf[0] = __get_dma_pages(GFP_KERNEL, pages);
+		if (!devpriv->dmabuf[0]) {
+			rt_printk(", unable to allocate DMA buffer, FAIL!\n");
+			/* maybe experiment with try_to_free_pages() will help .... */
+			return -EBUSY;	/* no buffer :-( */
+		}
+		devpriv->dmapages[0] = pages;
+		devpriv->hwdmaptr[0] = virt_to_bus((void *)devpriv->dmabuf[0]);
+		devpriv->hwdmasize[0] = (1 << pages) * PAGE_SIZE;
+		//rt_printk("%d %d %ld, ",devpriv->dmapages[0],devpriv->hwdmasize[0],PAGE_SIZE);
+		if (devpriv->dma_rtc == 0) {	// we must do duble buff :-(
+			devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages);
+			if (!devpriv->dmabuf[1]) {
+				rt_printk
+					(", unable to allocate DMA buffer, FAIL!\n");
+				return -EBUSY;
+			}
+			devpriv->dmapages[1] = pages;
+			devpriv->hwdmaptr[1] =
+				virt_to_bus((void *)devpriv->dmabuf[1]);
+			devpriv->hwdmasize[1] = (1 << pages) * PAGE_SIZE;
+		}
+	}
+
+      no_dma:
+
+	if ((ret = alloc_subdevices(dev, 4)) < 0)
+		return ret;
+
+	s = dev->subdevices + 0;
+	if (!this_board->n_aichan_se) {
+		s->type = COMEDI_SUBD_UNUSED;
+	} else {
+		s->type = COMEDI_SUBD_AI;
+		devpriv->sub_ai = s;
+		s->subdev_flags = SDF_READABLE;
+		if (check_single_ended(dev->iobase)) {
+			s->n_chan = this_board->n_aichan_se;
+			s->subdev_flags |= SDF_COMMON | SDF_GROUND;
+			printk(", %dchans S.E. DAC", s->n_chan);
+		} else {
+			s->n_chan = this_board->n_aichan_diff;
+			s->subdev_flags |= SDF_DIFF;
+			printk(", %dchans DIFF DAC", s->n_chan);
+		}
+		s->maxdata = this_board->ai_maxdata;
+		s->len_chanlist = s->n_chan;
+		s->range_table = this_board->ai_range_type;
+		s->cancel = pcl818_ai_cancel;
+		s->insn_read = pcl818_ai_insn_read;
+		if ((irq) || (devpriv->dma_rtc)) {
+			dev->read_subdev = s;
+			s->subdev_flags |= SDF_CMD_READ;
+			s->do_cmdtest = ai_cmdtest;
+			s->do_cmd = ai_cmd;
+		}
+		if (this_board->is_818) {
+			if ((it->options[4] == 1) || (it->options[4] == 10))
+				s->range_table = &range_pcl818l_h_ai;	// secondary range list jumper selectable
+		} else {
+			switch (it->options[4]) {
+			case 0:
+				s->range_table = &range_bipolar10;
+				break;
+			case 1:
+				s->range_table = &range_bipolar5;
+				break;
+			case 2:
+				s->range_table = &range_bipolar2_5;
+				break;
+			case 3:
+				s->range_table = &range718_bipolar1;
+				break;
+			case 4:
+				s->range_table = &range718_bipolar0_5;
+				break;
+			case 6:
+				s->range_table = &range_unipolar10;
+				break;
+			case 7:
+				s->range_table = &range_unipolar5;
+				break;
+			case 8:
+				s->range_table = &range718_unipolar2;
+				break;
+			case 9:
+				s->range_table = &range718_unipolar1;
+				break;
+			default:
+				s->range_table = &range_unknown;
+				break;
+			}
+		}
+	}
+
+	s = dev->subdevices + 1;
+	if (!this_board->n_aochan) {
+		s->type = COMEDI_SUBD_UNUSED;
+	} else {
+		s->type = COMEDI_SUBD_AO;
+		s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
+		s->n_chan = this_board->n_aochan;
+		s->maxdata = this_board->ao_maxdata;
+		s->len_chanlist = this_board->n_aochan;
+		s->range_table = this_board->ao_range_type;
+		s->insn_read = pcl818_ao_insn_read;
+		s->insn_write = pcl818_ao_insn_write;
+#ifdef unused
+#ifdef PCL818_MODE13_AO
+		if (irq) {
+			s->trig[1] = pcl818_ao_mode1;
+			s->trig[3] = pcl818_ao_mode3;
+		}
+#endif
+#endif
+		if (this_board->is_818) {
+			if ((it->options[4] == 1) || (it->options[4] == 10))
+				s->range_table = &range_unipolar10;
+			if (it->options[4] == 2)
+				s->range_table = &range_unknown;
+		} else {
+			if ((it->options[5] == 1) || (it->options[5] == 10))
+				s->range_table = &range_unipolar10;
+			if (it->options[5] == 2)
+				s->range_table = &range_unknown;
+		}
+	}
+
+	s = dev->subdevices + 2;
+	if (!this_board->n_dichan) {
+		s->type = COMEDI_SUBD_UNUSED;
+	} else {
+		s->type = COMEDI_SUBD_DI;
+		s->subdev_flags = SDF_READABLE;
+		s->n_chan = this_board->n_dichan;
+		s->maxdata = 1;
+		s->len_chanlist = this_board->n_dichan;
+		s->range_table = &range_digital;
+		s->insn_bits = pcl818_di_insn_bits;
+	}
+
+	s = dev->subdevices + 3;
+	if (!this_board->n_dochan) {
+		s->type = COMEDI_SUBD_UNUSED;
+	} else {
+		s->type = COMEDI_SUBD_DO;
+		s->subdev_flags = SDF_WRITABLE;
+		s->n_chan = this_board->n_dochan;
+		s->maxdata = 1;
+		s->len_chanlist = this_board->n_dochan;
+		s->range_table = &range_digital;
+		s->insn_bits = pcl818_do_insn_bits;
+	}
+
+	/* select 1/10MHz oscilator */
+	if ((it->options[3] == 0) || (it->options[3] == 10)) {
+		devpriv->i8253_osc_base = 100;
+	} else {
+		devpriv->i8253_osc_base = 1000;
+	}
+
+	/* max sampling speed */
+	devpriv->ns_min = this_board->ns_min;
+
+	if (!this_board->is_818) {
+		if ((it->options[6] == 1) || (it->options[6] == 100))
+			devpriv->ns_min = 10000;	/* extended PCL718 to 100kHz DAC */
+	}
+
+	pcl818_reset(dev);
+
+	rt_printk("\n");
+
+	return 0;
+}
+
+/*
+==============================================================================
+  Removes device
+ */
+static int pcl818_detach(struct comedi_device * dev)
+{
+	//  rt_printk("comedi%d: pcl818: remove\n", dev->minor);
+	free_resources(dev);
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c
new file mode 100644
index 0000000..a3ed3a0
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcm3724.c
@@ -0,0 +1,307 @@
+/*
+    comedi/drivers/pcm724.c
+
+    Drew Csillag <drew_csillag@yahoo.com>
+
+    hardware driver for Advantech card:
+     card:   PCM-3724
+     driver: pcm3724
+
+    Options for PCM-3724
+     [0] - IO Base
+*/
+/*
+Driver: pcm3724
+Description: Advantech PCM-3724
+Author: Drew Csillag <drew_csillag@yahoo.com>
+Devices: [Advantech] PCM-3724 (pcm724)
+Status: tested
+
+This is driver for digital I/O boards PCM-3724 with 48 DIO.
+It needs 8255.o for operations and only immediate mode is supported.
+See the source for configuration details.
+
+Copy/pasted/hacked from pcm724.c
+*/
+/*
+ * check_driver overrides:
+ *   struct comedi_insn
+ */
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/delay.h>
+
+#include "8255.h"
+
+#define PCM3724_SIZE   16
+#define SIZE_8255	4
+
+#define BUF_C0 0x1
+#define BUF_B0 0x2
+#define BUF_A0 0x4
+#define BUF_C1 0x8
+#define BUF_B1 0x10
+#define BUF_A1 0x20
+
+#define GATE_A0 0x4
+#define GATE_B0	0x2
+#define GATE_C0	0x1
+#define GATE_A1	0x20
+#define GATE_B1	0x10
+#define GATE_C1 0x8
+
+/* from 8255.c */
+#define CR_CW		0x80
+#define _8255_CR 3
+#define CR_B_IO		0x02
+#define CR_B_MODE	0x04
+#define CR_C_IO	        0x09
+#define CR_A_IO		0x10
+#define CR_A_MODE(a)	((a)<<5)
+#define CR_CW		0x80
+
+static int pcm3724_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcm3724_detach(struct comedi_device * dev);
+
+struct pcm3724_board {
+	const char *name;	// driver name
+	int dio;		// num of DIO
+	int numofports;		// num of 8255 subdevices
+	unsigned int IRQbits;	// allowed interrupts
+	unsigned int io_range;	// len of IO space
+};
+
+//used to track configured dios
+struct priv_pcm3724 {
+	int dio_1;
+	int dio_2;
+};
+
+static const struct pcm3724_board boardtypes[] = {
+	{"pcm3724", 48, 2, 0x00fc, PCM3724_SIZE,},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcm3724_board))
+#define this_board ((const struct pcm3724_board *)dev->board_ptr)
+
+static struct comedi_driver driver_pcm3724 = {
+      driver_name:"pcm3724",
+      module:THIS_MODULE,
+      attach:pcm3724_attach,
+      detach:pcm3724_detach,
+      board_name:&boardtypes[0].name,
+      num_names:n_boardtypes,
+      offset:sizeof(struct pcm3724_board),
+};
+
+COMEDI_INITCLEANUP(driver_pcm3724);
+
+//          (setq c-basic-offset 8)
+
+static int subdev_8255_cb(int dir, int port, int data, unsigned long arg)
+{
+	unsigned long iobase = arg;
+	unsigned char inbres;
+	//printk("8255cb %d %d %d %lx\n", dir,port,data,arg);
+	if (dir) {
+		//printk("8255 cb   outb(%x, %lx)\n", data, iobase+port);
+		outb(data, iobase + port);
+		return 0;
+	} else {
+		inbres = inb(iobase + port);
+		//printk("8255 cb   inb(%lx) = %x\n", iobase+port, inbres);
+		return inbres;
+	}
+}
+
+static int compute_buffer(int config, int devno, struct comedi_subdevice * s)
+{
+	/* 1 in io_bits indicates output */
+	if (s->io_bits & 0x0000ff) {
+		if (devno == 0) {
+			config |= BUF_A0;
+		} else {
+			config |= BUF_A1;
+		}
+	}
+	if (s->io_bits & 0x00ff00) {
+		if (devno == 0) {
+			config |= BUF_B0;
+		} else {
+			config |= BUF_B1;
+		}
+	}
+	if (s->io_bits & 0xff0000) {
+		if (devno == 0) {
+			config |= BUF_C0;
+		} else {
+			config |= BUF_C1;
+		}
+	}
+	return config;
+}
+
+static void do_3724_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	int chanspec)
+{
+	int config;
+	int buffer_config;
+	unsigned long port_8255_cfg;
+
+	config = CR_CW;
+	buffer_config = 0;
+
+	/* 1 in io_bits indicates output, 1 in config indicates input */
+	if (!(s->io_bits & 0x0000ff)) {
+		config |= CR_A_IO;
+	}
+	if (!(s->io_bits & 0x00ff00)) {
+		config |= CR_B_IO;
+	}
+	if (!(s->io_bits & 0xff0000)) {
+		config |= CR_C_IO;
+	}
+
+	buffer_config = compute_buffer(0, 0, dev->subdevices);
+	buffer_config = compute_buffer(buffer_config, 1, (dev->subdevices) + 1);
+
+	if (s == dev->subdevices) {
+		port_8255_cfg = dev->iobase + _8255_CR;
+	} else {
+		port_8255_cfg = dev->iobase + SIZE_8255 + _8255_CR;
+	}
+	outb(buffer_config, dev->iobase + 8);	/* update buffer register */
+	//printk("pcm3724 buffer_config (%lx) %d, %x\n", dev->iobase + _8255_CR, chanspec, buffer_config);
+	outb(config, port_8255_cfg);
+}
+
+static void enable_chan(struct comedi_device * dev, struct comedi_subdevice * s, int chanspec)
+{
+	unsigned int mask;
+	int gatecfg;
+	struct priv_pcm3724 *priv;
+
+	gatecfg = 0;
+	priv = (struct priv_pcm3724 *) (dev->private);
+
+	mask = 1 << CR_CHAN(chanspec);
+	if (s == dev->subdevices) {	// subdev 0
+		priv->dio_1 |= mask;
+	} else {		//subdev 1
+		priv->dio_2 |= mask;
+	}
+	if (priv->dio_1 & 0xff0000) {
+		gatecfg |= GATE_C0;
+	}
+	if (priv->dio_1 & 0xff00) {
+		gatecfg |= GATE_B0;
+	}
+	if (priv->dio_1 & 0xff) {
+		gatecfg |= GATE_A0;
+	}
+	if (priv->dio_2 & 0xff0000) {
+		gatecfg |= GATE_C1;
+	}
+	if (priv->dio_2 & 0xff00) {
+		gatecfg |= GATE_B1;
+	}
+	if (priv->dio_2 & 0xff) {
+		gatecfg |= GATE_A1;
+	}
+	//      printk("gate control %x\n", gatecfg);
+	outb(gatecfg, dev->iobase + 9);
+}
+
+/* overriding the 8255 insn config */
+static int subdev_3724_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	unsigned int mask;
+	unsigned int bits;
+
+	mask = 1 << CR_CHAN(insn->chanspec);
+	if (mask & 0x0000ff) {
+		bits = 0x0000ff;
+	} else if (mask & 0x00ff00) {
+		bits = 0x00ff00;
+	} else if (mask & 0x0f0000) {
+		bits = 0x0f0000;
+	} else {
+		bits = 0xf00000;
+	}
+
+	switch (data[0]) {
+	case INSN_CONFIG_DIO_INPUT:
+		s->io_bits &= ~bits;
+		break;
+	case INSN_CONFIG_DIO_OUTPUT:
+		s->io_bits |= bits;
+		break;
+	case INSN_CONFIG_DIO_QUERY:
+		data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
+		return insn->n;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	do_3724_config(dev, s, insn->chanspec);
+	enable_chan(dev, s, insn->chanspec);
+	return 1;
+}
+
+static int pcm3724_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	unsigned long iobase;
+	unsigned int iorange;
+	int ret, i, n_subdevices;
+
+	iobase = it->options[0];
+	iorange = this_board->io_range;
+	if ((ret = alloc_private(dev, sizeof(struct priv_pcm3724))) < 0)
+		return -ENOMEM;
+
+	((struct priv_pcm3724 *) (dev->private))->dio_1 = 0;
+	((struct priv_pcm3724 *) (dev->private))->dio_2 = 0;
+
+	printk("comedi%d: pcm3724: board=%s, 0x%03lx ", dev->minor,
+		this_board->name, iobase);
+	if (!iobase || !request_region(iobase, iorange, "pcm3724")) {
+		printk("I/O port conflict\n");
+		return -EIO;
+	}
+
+	dev->iobase = iobase;
+	dev->board_name = this_board->name;
+	printk("\n");
+
+	n_subdevices = this_board->numofports;
+
+	if ((ret = alloc_subdevices(dev, n_subdevices)) < 0)
+		return ret;
+
+	for (i = 0; i < dev->n_subdevices; i++) {
+		subdev_8255_init(dev, dev->subdevices + i, subdev_8255_cb,
+			(unsigned long)(dev->iobase + SIZE_8255 * i));
+		((dev->subdevices) + i)->insn_config = subdev_3724_insn_config;
+	};
+	return 0;
+}
+
+static int pcm3724_detach(struct comedi_device * dev)
+{
+	int i;
+
+	if (dev->subdevices) {
+		for (i = 0; i < dev->n_subdevices; i++) {
+			subdev_8255_cleanup(dev, dev->subdevices + i);
+		}
+	}
+	if (dev->iobase) {
+		release_region(dev->iobase, this_board->io_range);
+	}
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcm3730.c b/drivers/staging/comedi/drivers/pcm3730.c
new file mode 100644
index 0000000..1de555f
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcm3730.c
@@ -0,0 +1,152 @@
+/*
+ * comedi/drivers/pcm3730.c
+ * Driver for PCM3730 and clones
+ * Blaine Lee
+ * from pcl725 by David S.
+ */
+/*
+Driver: pcm3730
+Description: PCM3730
+Author: Blaine Lee
+Devices: [Advantech] PCM-3730 (pcm3730)
+Status: unknown
+
+Configuration options:
+  [0] - I/O port base
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define PCM3730_SIZE 4		// consecutive io port addresses
+
+#define PCM3730_DOA 0		// offsets for each port
+#define PCM3730_DOB 2
+#define PCM3730_DOC 3
+#define PCM3730_DIA 0
+#define PCM3730_DIB 2
+#define PCM3730_DIC 3
+
+static int pcm3730_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcm3730_detach(struct comedi_device * dev);
+static struct comedi_driver driver_pcm3730 = {
+      driver_name:"pcm3730",
+      module:THIS_MODULE,
+      attach:pcm3730_attach,
+      detach:pcm3730_detach,
+};
+
+COMEDI_INITCLEANUP(driver_pcm3730);
+
+static int pcm3730_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= (data[0] & data[1]);
+		outb(s->state, dev->iobase + (unsigned long)(s->private));
+	}
+	data[1] = s->state;
+
+	return 2;
+}
+
+static int pcm3730_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+	data[1] = inb(dev->iobase + (unsigned long)(s->private));
+	return 2;
+}
+
+static int pcm3730_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	unsigned long iobase;
+
+	iobase = it->options[0];
+	printk("comedi%d: pcm3730: 0x%04lx ", dev->minor, iobase);
+	if (!request_region(iobase, PCM3730_SIZE, "pcm3730")) {
+		printk("I/O port conflict\n");
+		return -EIO;
+	}
+	dev->iobase = iobase;
+	dev->board_name = "pcm3730";
+	dev->iobase = dev->iobase;
+	dev->irq = 0;
+
+	if (alloc_subdevices(dev, 6) < 0)
+		return -ENOMEM;
+
+	s = dev->subdevices + 0;
+	s->type = COMEDI_SUBD_DO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->maxdata = 1;
+	s->n_chan = 8;
+	s->insn_bits = pcm3730_do_insn_bits;
+	s->range_table = &range_digital;
+	s->private = (void *)PCM3730_DOA;
+
+	s = dev->subdevices + 1;
+	s->type = COMEDI_SUBD_DO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->maxdata = 1;
+	s->n_chan = 8;
+	s->insn_bits = pcm3730_do_insn_bits;
+	s->range_table = &range_digital;
+	s->private = (void *)PCM3730_DOB;
+
+	s = dev->subdevices + 2;
+	s->type = COMEDI_SUBD_DO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->maxdata = 1;
+	s->n_chan = 8;
+	s->insn_bits = pcm3730_do_insn_bits;
+	s->range_table = &range_digital;
+	s->private = (void *)PCM3730_DOC;
+
+	s = dev->subdevices + 3;
+	s->type = COMEDI_SUBD_DI;
+	s->subdev_flags = SDF_READABLE;
+	s->maxdata = 1;
+	s->n_chan = 8;
+	s->insn_bits = pcm3730_di_insn_bits;
+	s->range_table = &range_digital;
+	s->private = (void *)PCM3730_DIA;
+
+	s = dev->subdevices + 4;
+	s->type = COMEDI_SUBD_DI;
+	s->subdev_flags = SDF_READABLE;
+	s->maxdata = 1;
+	s->n_chan = 8;
+	s->insn_bits = pcm3730_di_insn_bits;
+	s->range_table = &range_digital;
+	s->private = (void *)PCM3730_DIB;
+
+	s = dev->subdevices + 5;
+	s->type = COMEDI_SUBD_DI;
+	s->subdev_flags = SDF_READABLE;
+	s->maxdata = 1;
+	s->n_chan = 8;
+	s->insn_bits = pcm3730_di_insn_bits;
+	s->range_table = &range_digital;
+	s->private = (void *)PCM3730_DIC;
+
+	printk("\n");
+
+	return 0;
+}
+
+static int pcm3730_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: pcm3730: remove\n", dev->minor);
+
+	if (dev->iobase)
+		release_region(dev->iobase, PCM3730_SIZE);
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcmad.c b/drivers/staging/comedi/drivers/pcmad.c
new file mode 100644
index 0000000..fc2a73d
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcmad.c
@@ -0,0 +1,173 @@
+/*
+    comedi/drivers/pcmad.c
+    Hardware driver for Winsystems PCM-A/D12 and PCM-A/D16
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000,2001 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: pcmad
+Description: Winsystems PCM-A/D12, PCM-A/D16
+Author: ds
+Devices: [Winsystems] PCM-A/D12 (pcmad12), PCM-A/D16 (pcmad16)
+Status: untested
+
+This driver was written on a bet that I couldn't write a driver
+in less than 2 hours.  I won the bet, but never got paid.  =(
+
+Configuration options:
+  [0] - I/O port base
+  [1] - unused
+  [2] - Analog input reference
+          0 = single ended
+          1 = differential
+  [3] - Analog input encoding (must match jumpers)
+          0 = straight binary
+          1 = two's complement
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define PCMAD_SIZE		4
+
+#define PCMAD_STATUS		0
+#define PCMAD_LSB		1
+#define PCMAD_MSB		2
+#define PCMAD_CONVERT		1
+
+struct pcmad_board_struct {
+	const char *name;
+	int n_ai_bits;
+};
+static const struct pcmad_board_struct pcmad_boards[] = {
+	{
+	      name:	"pcmad12",
+	      n_ai_bits:12,
+		},
+	{
+	      name:	"pcmad16",
+	      n_ai_bits:16,
+		},
+};
+
+#define this_board ((const struct pcmad_board_struct *)(dev->board_ptr))
+#define n_pcmad_boards (sizeof(pcmad_boards)/sizeof(pcmad_boards[0]))
+
+struct pcmad_priv_struct {
+	int differential;
+	int twos_comp;
+};
+#define devpriv ((struct pcmad_priv_struct *)dev->private)
+
+static int pcmad_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcmad_detach(struct comedi_device * dev);
+static struct comedi_driver driver_pcmad = {
+      driver_name:"pcmad",
+      module:THIS_MODULE,
+      attach:pcmad_attach,
+      detach:pcmad_detach,
+      board_name:&pcmad_boards[0].name,
+      num_names:n_pcmad_boards,
+      offset:sizeof(pcmad_boards[0]),
+};
+
+COMEDI_INITCLEANUP(driver_pcmad);
+
+#define TIMEOUT	100
+
+static int pcmad_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan;
+	int n;
+
+	chan = CR_CHAN(insn->chanspec);
+
+	for (n = 0; n < insn->n; n++) {
+		outb(chan, dev->iobase + PCMAD_CONVERT);
+
+		for (i = 0; i < TIMEOUT; i++) {
+			if ((inb(dev->iobase + PCMAD_STATUS) & 0x3) == 0x3)
+				break;
+		}
+		data[n] = inb(dev->iobase + PCMAD_LSB);
+		data[n] |= (inb(dev->iobase + PCMAD_MSB) << 8);
+
+		if (devpriv->twos_comp) {
+			data[n] ^= (1 << (this_board->n_ai_bits - 1));
+		}
+	}
+
+	return n;
+}
+
+/*
+ * options:
+ * 0	i/o base
+ * 1	unused
+ * 2	0=single ended 1=differential
+ * 3	0=straight binary 1=two's comp
+ */
+static int pcmad_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	int ret;
+	struct comedi_subdevice *s;
+	unsigned long iobase;
+
+	iobase = it->options[0];
+	printk("comedi%d: pcmad: 0x%04lx ", dev->minor, iobase);
+	if (!request_region(iobase, PCMAD_SIZE, "pcmad")) {
+		printk("I/O port conflict\n");
+		return -EIO;
+	}
+	dev->iobase = iobase;
+
+	if ((ret = alloc_subdevices(dev, 1)) < 0)
+		return ret;
+	if ((ret = alloc_private(dev, sizeof(struct pcmad_priv_struct))) < 0)
+		return ret;
+
+	dev->board_name = this_board->name;
+
+	s = dev->subdevices + 0;
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE | AREF_GROUND;
+	s->n_chan = 16;		/* XXX */
+	s->len_chanlist = 1;
+	s->insn_read = pcmad_ai_insn_read;
+	s->maxdata = (1 << this_board->n_ai_bits) - 1;
+	s->range_table = &range_unknown;
+
+	return 0;
+}
+
+static int pcmad_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: pcmad: remove\n", dev->minor);
+
+	if (dev->irq) {
+		free_irq(dev->irq, dev);
+	}
+	if (dev->iobase)
+		release_region(dev->iobase, PCMAD_SIZE);
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcmda12.c b/drivers/staging/comedi/drivers/pcmda12.c
new file mode 100644
index 0000000..2a1ff46
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcmda12.c
@@ -0,0 +1,306 @@
+/*
+    comedi/drivers/pcmda12.c
+    Driver for Winsystems PC-104 based PCM-D/A-12 8-channel AO board.
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2006 Calin A. Culianu <calin@ajvar.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.
+
+    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.
+*/
+/*
+Driver: pcmda12
+Description: A driver for the Winsystems PCM-D/A-12
+Devices: [Winsystems] PCM-D/A-12 (pcmda12)
+Author: Calin Culianu <calin@ajvar.org>
+Updated: Fri, 13 Jan 2006 12:01:01 -0500
+Status: works
+
+A driver for the relatively straightforward-to-program PCM-D/A-12.
+This board doesn't support commands, and the only way to set its
+analog output range is to jumper the board.  As such,
+comedi_data_write() ignores the range value specified.
+
+The board uses 16 consecutive I/O addresses starting at the I/O port
+base address.  Each address corresponds to the LSB then MSB of a
+particular channel from 0-7.
+
+Note that the board is not ISA-PNP capable and thus
+needs the I/O port comedi_config parameter.
+
+Note that passing a nonzero value as the second config option will
+enable "simultaneous xfer" mode for this board, in which AO writes
+will not take effect until a subsequent read of any AO channel.  This
+is so that one can speed up programming by preloading all AO registers
+with values before simultaneously setting them to take effect with one
+read command.
+
+Configuration Options:
+  [0] - I/O port base address
+  [1] - Do Simultaneous Xfer (see description)
+*/
+
+#include "../comedidev.h"
+
+#include <linux/pci.h>		/* for PCI devices */
+
+#define MIN(a,b) ( ((a) < (b)) ? (a) : (b) )
+#define SDEV_NO ((int)(s - dev->subdevices))
+#define CHANS 8
+#define IOSIZE 16
+#define LSB(x) ((unsigned char)((x) & 0xff))
+#define MSB(x) ((unsigned char)((((unsigned short)(x))>>8) & 0xff))
+#define LSB_PORT(chan) (dev->iobase + (chan)*2)
+#define MSB_PORT(chan) (LSB_PORT(chan)+1)
+#define BITS 12
+
+/*
+ * Bords
+ */
+struct pcmda12_board {
+	const char *name;
+};
+
+/* note these have no effect and are merely here for reference..
+   these are configured by jumpering the board! */
+static const struct comedi_lrange pcmda12_ranges = {
+	3,
+	{
+			UNI_RANGE(5), UNI_RANGE(10), BIP_RANGE(5)
+		}
+};
+
+static const struct pcmda12_board pcmda12_boards[] = {
+	{
+	      name:	"pcmda12",
+		},
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct pcmda12_board *)dev->board_ptr)
+
+struct pcmda12_private {
+
+	unsigned int ao_readback[CHANS];
+	int simultaneous_xfer_mode;
+};
+
+
+#define devpriv ((struct pcmda12_private *)(dev->private))
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pcmda12_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcmda12_detach(struct comedi_device * dev);
+
+static void zero_chans(struct comedi_device * dev);
+
+static struct comedi_driver driver = {
+      driver_name:"pcmda12",
+      module:THIS_MODULE,
+      attach:pcmda12_attach,
+      detach:pcmda12_detach,
+/* It is not necessary to implement the following members if you are
+ * writing a driver for a ISA PnP or PCI card */
+	/* Most drivers will support multiple types of boards by
+	 * having an array of board structures.  These were defined
+	 * in pcmda12_boards[] above.  Note that the element 'name'
+	 * was first in the structure -- Comedi uses this fact to
+	 * extract the name of the board without knowing any details
+	 * about the structure except for its length.
+	 * When a device is attached (by comedi_config), the name
+	 * of the device is given to Comedi, and Comedi tries to
+	 * match it by going through the list of board names.  If
+	 * there is a match, the address of the pointer is put
+	 * into dev->board_ptr and driver->attach() is called.
+	 *
+	 * Note that these are not necessary if you can determine
+	 * the type of board in software.  ISA PnP, PCI, and PCMCIA
+	 * devices are such boards.
+	 */
+      board_name:&pcmda12_boards[0].name,
+      offset:sizeof(struct pcmda12_board),
+      num_names:sizeof(pcmda12_boards) / sizeof(struct pcmda12_board),
+};
+
+static int ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board.  If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pcmda12_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	unsigned long iobase;
+
+	iobase = it->options[0];
+	printk("comedi%d: %s: io: %lx %s ", dev->minor, driver.driver_name,
+		iobase, it->options[1] ? "simultaneous xfer mode enabled" : "");
+
+	if (!request_region(iobase, IOSIZE, driver.driver_name)) {
+		printk("I/O port conflict\n");
+		return -EIO;
+	}
+	dev->iobase = iobase;
+
+/*
+ * Initialize dev->board_name.  Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+	dev->board_name = thisboard->name;
+
+/*
+ * Allocate the private structure area.  alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+	if (alloc_private(dev, sizeof(struct pcmda12_private)) < 0) {
+		printk("cannot allocate private data structure\n");
+		return -ENOMEM;
+	}
+
+	devpriv->simultaneous_xfer_mode = it->options[1];
+
+	/*
+	 * Allocate the subdevice structures.  alloc_subdevice() is a
+	 * convenient macro defined in comedidev.h.
+	 *
+	 * Allocate 2 subdevs (32 + 16 DIO lines) or 3 32 DIO subdevs for the
+	 * 96-channel version of the board.
+	 */
+	if (alloc_subdevices(dev, 1) < 0) {
+		printk("cannot allocate subdevice data structures\n");
+		return -ENOMEM;
+	}
+
+	s = dev->subdevices;
+	s->private = NULL;
+	s->maxdata = (0x1 << BITS) - 1;
+	s->range_table = &pcmda12_ranges;
+	s->type = COMEDI_SUBD_AO;
+	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+	s->n_chan = CHANS;
+	s->insn_write = &ao_winsn;
+	s->insn_read = &ao_rinsn;
+
+	zero_chans(dev);	/* clear out all the registers, basically */
+
+	printk("attached\n");
+
+	return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device.  It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach().  dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pcmda12_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: %s: remove\n", dev->minor, driver.driver_name);
+	if (dev->iobase)
+		release_region(dev->iobase, IOSIZE);
+	return 0;
+}
+
+static void zero_chans(struct comedi_device * dev)
+{				/* sets up an
+				   ASIC chip to defaults */
+	int i;
+	for (i = 0; i < CHANS; ++i) {
+/*      /\* do this as one instruction?? *\/ */
+/*      outw(0, LSB_PORT(chan)); */
+		outb(0, LSB_PORT(i));
+		outb(0, MSB_PORT(i));
+	}
+	inb(LSB_PORT(0));	/* update chans. */
+}
+
+static int ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+
+	/* Writing a list of values to an AO channel is probably not
+	 * very useful, but that's how the interface is defined. */
+	for (i = 0; i < insn->n; ++i) {
+
+/*      /\* do this as one instruction?? *\/ */
+/*      outw(data[i], LSB_PORT(chan)); */
+
+		/* Need to do this as two instructions due to 8-bit bus?? */
+		/*  first, load the low byte */
+		outb(LSB(data[i]), LSB_PORT(chan));
+		/*  next, write the high byte */
+		outb(MSB(data[i]), MSB_PORT(chan));
+
+		/* save shadow register */
+		devpriv->ao_readback[chan] = data[i];
+
+		if (!devpriv->simultaneous_xfer_mode)
+			inb(LSB_PORT(chan));
+	}
+
+	/* return the number of samples written */
+	return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+
+   Usually this means copying a value stored in devpriv->ao_readback.
+   However, since this driver supports simultaneous xfer then sometimes
+   this function actually accomplishes work.
+
+   Simultaneaous xfer mode is accomplished by loading ALL the values
+   you want for AO in all the channels, then READing off one of the AO
+   registers to initiate the instantaneous simultaneous update of all
+   DAC outputs, which makes all AO channels update simultaneously.
+   This is useful for some control applications, I would imagine.
+*/
+static int ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+
+	for (i = 0; i < insn->n; i++) {
+		if (devpriv->simultaneous_xfer_mode)
+			inb(LSB_PORT(chan));
+		/* read back shadow register */
+		data[i] = devpriv->ao_readback[chan];
+	}
+
+	return i;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver);
diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c
new file mode 100644
index 0000000..01e40f1
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcmmio.c
@@ -0,0 +1,1333 @@
+/*
+    comedi/drivers/pcmmio.c
+    Driver for Winsystems PC-104 based multifunction IO board.
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2007 Calin A. Culianu <calin@ajvar.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.
+
+    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.
+*/
+/*
+Driver: pcmmio
+Description: A driver for the PCM-MIO multifunction board
+Devices: [Winsystems] PCM-MIO (pcmmio)
+Author: Calin Culianu <calin@ajvar.org>
+Updated: Wed, May 16 2007 16:21:10 -0500
+Status: works
+
+A driver for the relatively new PCM-MIO multifunction board from
+Winsystems.  This board is a PC-104 based I/O board.  It contains
+four subdevices:
+  subdevice 0 - 16 channels of 16-bit AI
+  subdevice 1 - 8 channels of 16-bit AO
+  subdevice 2 - first 24 channels of the 48 channel of DIO (with edge-triggered interrupt support)
+  subdevice 3 - last 24 channels of the 48 channel DIO (no interrupt support for this bank of channels)
+
+  Some notes:
+
+  Synchronous reads and writes are the only things implemented for AI and AO,
+  even though the hardware itself can do streaming acquisition, etc.  Anyone
+  want to add asynchronous I/O for AI/AO as a feature?  Be my guest...
+
+  Asynchronous I/O for the DIO subdevices *is* implemented, however!  They are
+  basically edge-triggered interrupts for any configuration of the first
+  24 DIO-lines.
+
+  Also note that this interrupt support is untested.
+
+  A few words about edge-detection IRQ support (commands on DIO):
+
+  * To use edge-detection IRQ support for the DIO subdevice, pass the IRQ
+    of the board to the comedi_config command.  The board IRQ is not jumpered
+    but rather configured through software, so any IRQ from 1-15 is OK.
+
+  * Due to the genericity of the comedi API, you need to create a special
+    comedi_command in order to use edge-triggered interrupts for DIO.
+
+  * Use comedi_commands with TRIG_NOW.  Your callback will be called each
+    time an edge is detected on the specified DIO line(s), and the data
+    values will be two sample_t's, which should be concatenated to form
+    one 32-bit unsigned int.  This value is the mask of channels that had
+    edges detected from your channel list.  Note that the bits positions
+    in the mask correspond to positions in your chanlist when you
+    specified the command and *not* channel id's!
+
+ *  To set the polarity of the edge-detection interrupts pass a nonzero value
+    for either CR_RANGE or CR_AREF for edge-up polarity, or a zero
+    value for both CR_RANGE and CR_AREF if you want edge-down polarity.
+
+Configuration Options:
+  [0] - I/O port base address
+  [1] - IRQ (optional -- for edge-detect interrupt support only, leave out if you don't need this feature)
+*/
+
+#include "../comedidev.h"
+#include <linux/pci.h>		/* for PCI devices */
+
+#define MIN(a,b) ( ((a) < (b)) ? (a) : (b) )
+
+/* This stuff is all from pcmuio.c -- it refers to the DIO subdevices only */
+#define CHANS_PER_PORT   8
+#define PORTS_PER_ASIC   6
+#define INTR_PORTS_PER_ASIC   3
+#define MAX_CHANS_PER_SUBDEV 24	/* number of channels per comedi subdevice */
+#define PORTS_PER_SUBDEV (MAX_CHANS_PER_SUBDEV/CHANS_PER_PORT)
+#define CHANS_PER_ASIC (CHANS_PER_PORT*PORTS_PER_ASIC)
+#define INTR_CHANS_PER_ASIC 24
+#define INTR_PORTS_PER_SUBDEV (INTR_CHANS_PER_ASIC/CHANS_PER_PORT)
+#define MAX_DIO_CHANS   (PORTS_PER_ASIC*1*CHANS_PER_PORT)
+#define MAX_ASICS       (MAX_DIO_CHANS/CHANS_PER_ASIC)
+#define SDEV_NO ((int)(s - dev->subdevices))
+#define CALC_N_DIO_SUBDEVS(nchans) ((nchans)/MAX_CHANS_PER_SUBDEV + (!!((nchans)%MAX_CHANS_PER_SUBDEV)) /*+ (nchans > INTR_CHANS_PER_ASIC ? 2 : 1)*/)
+/* IO Memory sizes */
+#define ASIC_IOSIZE (0x0B)
+#define PCMMIO48_IOSIZE ASIC_IOSIZE
+
+/* Some offsets - these are all in the 16byte IO memory offset from
+   the base address.  Note that there is a paging scheme to swap out
+   offsets 0x8-0xA using the PAGELOCK register.  See the table below.
+
+  Register(s)       Pages        R/W?        Description
+  --------------------------------------------------------------
+  REG_PORTx         All          R/W         Read/Write/Configure IO
+  REG_INT_PENDING   All          ReadOnly    Quickly see which INT_IDx has int.
+  REG_PAGELOCK      All          WriteOnly   Select a page
+  REG_POLx          Pg. 1 only   WriteOnly   Select edge-detection polarity
+  REG_ENABx         Pg. 2 only   WriteOnly   Enable/Disable edge-detect. int.
+  REG_INT_IDx       Pg. 3 only   R/W         See which ports/bits have ints.
+ */
+#define REG_PORT0 0x0
+#define REG_PORT1 0x1
+#define REG_PORT2 0x2
+#define REG_PORT3 0x3
+#define REG_PORT4 0x4
+#define REG_PORT5 0x5
+#define REG_INT_PENDING 0x6
+#define REG_PAGELOCK 0x7	/* page selector register, upper 2 bits select a page
+				   and bits 0-5 are used to 'lock down' a particular
+				   port above to make it readonly.  */
+#define REG_POL0 0x8
+#define REG_POL1 0x9
+#define REG_POL2 0xA
+#define REG_ENAB0 0x8
+#define REG_ENAB1 0x9
+#define REG_ENAB2 0xA
+#define REG_INT_ID0 0x8
+#define REG_INT_ID1 0x9
+#define REG_INT_ID2 0xA
+
+#define NUM_PAGED_REGS 3
+#define NUM_PAGES 4
+#define FIRST_PAGED_REG 0x8
+#define REG_PAGE_BITOFFSET 6
+#define REG_LOCK_BITOFFSET 0
+#define REG_PAGE_MASK (~((0x1<<REG_PAGE_BITOFFSET)-1))
+#define REG_LOCK_MASK ~(REG_PAGE_MASK)
+#define PAGE_POL 1
+#define PAGE_ENAB 2
+#define PAGE_INT_ID 3
+
+typedef int (*comedi_insn_fn_t) (struct comedi_device *, struct comedi_subdevice *,
+	struct comedi_insn *, unsigned int *);
+
+static int ai_rinsn(struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+	unsigned int *);
+static int ao_rinsn(struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+	unsigned int *);
+static int ao_winsn(struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+	unsigned int *);
+
+/*
+ * Board descriptions for two imaginary boards.  Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct pcmmio_board {
+	const char *name;
+	const int dio_num_asics;
+	const int dio_num_ports;
+	const int total_iosize;
+	const int ai_bits;
+	const int ao_bits;
+	const int n_ai_chans;
+	const int n_ao_chans;
+	const struct comedi_lrange *ai_range_table, *ao_range_table;
+	comedi_insn_fn_t ai_rinsn, ao_rinsn, ao_winsn;
+};
+
+static const struct comedi_lrange ranges_ai =
+	{ 4, {RANGE(-5., 5.), RANGE(-10., 10.), RANGE(0., 5.), RANGE(0.,
+		10.)}
+};
+
+static const struct comedi_lrange ranges_ao =
+	{ 6, {RANGE(0., 5.), RANGE(0., 10.), RANGE(-5., 5.), RANGE(-10., 10.),
+	RANGE(-2.5, 2.5), RANGE(-2.5, 7.5)}
+};
+
+static const struct pcmmio_board pcmmio_boards[] = {
+	{
+	      name:	"pcmmio",
+	      dio_num_asics:1,
+	      dio_num_ports:6,
+	      total_iosize:32,
+	      ai_bits:	16,
+	      ao_bits:	16,
+	      n_ai_chans:16,
+	      n_ao_chans:8,
+	      ai_range_table:&ranges_ai,
+	      ao_range_table:&ranges_ao,
+	      ai_rinsn:ai_rinsn,
+	      ao_rinsn:ao_rinsn,
+      ao_winsn:ao_winsn},
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct pcmmio_board *)dev->board_ptr)
+
+/* this structure is for data unique to this subdevice.  */
+struct pcmmio_subdev_private {
+
+	union {
+		/* for DIO: mapping of halfwords (bytes) in port/chanarray to iobase */
+		unsigned long iobases[PORTS_PER_SUBDEV];
+
+		/* for AI/AO */
+		unsigned long iobase;
+	};
+	union {
+		struct {
+
+			/* The below is only used for intr subdevices */
+			struct {
+				int asic;	/* if non-negative, this subdev has an interrupt asic */
+				int first_chan;	/* if nonnegative, the first channel id for
+						   interrupts. */
+				int num_asic_chans;	/* the number of asic channels in this subdev
+							   that have interrutps */
+				int asic_chan;	/* if nonnegative, the first channel id with
+						   respect to the asic that has interrupts */
+				int enabled_mask;	/* subdev-relative channel mask for channels
+							   we are interested in */
+				int active;
+				int stop_count;
+				int continuous;
+				spinlock_t spinlock;
+			} intr;
+		} dio;
+		struct {
+			unsigned int shadow_samples[8];	/* the last unsigned int data written */
+		} ao;
+	};
+};
+
+/* this structure is for data unique to this hardware driver.  If
+   several hardware drivers keep similar information in this structure,
+   feel free to suggest moving the variable to the struct comedi_device struct.  */
+struct pcmmio_private {
+	/* stuff for DIO */
+	struct {
+		unsigned char pagelock;	/* current page and lock */
+		unsigned char pol[NUM_PAGED_REGS];	/* shadow of POLx registers */
+		unsigned char enab[NUM_PAGED_REGS];	/* shadow of ENABx registers */
+		int num;
+		unsigned long iobase;
+		unsigned int irq;
+		spinlock_t spinlock;
+	} asics[MAX_ASICS];
+	struct pcmmio_subdev_private *sprivs;
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct pcmmio_private *)dev->private)
+#define subpriv ((struct pcmmio_subdev_private *)s->private)
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pcmmio_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcmmio_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver = {
+      driver_name:"pcmmio",
+      module:THIS_MODULE,
+      attach:pcmmio_attach,
+      detach:pcmmio_detach,
+/* It is not necessary to implement the following members if you are
+ * writing a driver for a ISA PnP or PCI card */
+	/* Most drivers will support multiple types of boards by
+	 * having an array of board structures.  These were defined
+	 * in pcmmio_boards[] above.  Note that the element 'name'
+	 * was first in the structure -- Comedi uses this fact to
+	 * extract the name of the board without knowing any details
+	 * about the structure except for its length.
+	 * When a device is attached (by comedi_config), the name
+	 * of the device is given to Comedi, and Comedi tries to
+	 * match it by going through the list of board names.  If
+	 * there is a match, the address of the pointer is put
+	 * into dev->board_ptr and driver->attach() is called.
+	 *
+	 * Note that these are not necessary if you can determine
+	 * the type of board in software.  ISA PnP, PCI, and PCMCIA
+	 * devices are such boards.
+	 */
+      board_name:&pcmmio_boards[0].name,
+      offset:sizeof(struct pcmmio_board),
+      num_names:sizeof(pcmmio_boards) / sizeof(struct pcmmio_board),
+};
+
+static int pcmmio_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int pcmmio_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+static irqreturn_t interrupt_pcmmio(int irq, void *d PT_REGS_ARG);
+static void pcmmio_stop_intr(struct comedi_device *, struct comedi_subdevice *);
+static int pcmmio_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pcmmio_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pcmmio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd);
+
+/* some helper functions to deal with specifics of this device's registers */
+static void init_asics(struct comedi_device * dev);	/* sets up/clears ASIC chips to defaults */
+static void switch_page(struct comedi_device * dev, int asic, int page);
+#ifdef notused
+static void lock_port(struct comedi_device * dev, int asic, int port);
+static void unlock_port(struct comedi_device * dev, int asic, int port);
+#endif
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board.  If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pcmmio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	int sdev_no, chans_left, n_dio_subdevs, n_subdevs, port, asic,
+		thisasic_chanct = 0;
+	unsigned long iobase;
+	unsigned int irq[MAX_ASICS];
+
+	iobase = it->options[0];
+	irq[0] = it->options[1];
+
+	printk("comedi%d: %s: io: %lx ", dev->minor, driver.driver_name,
+		iobase);
+
+	dev->iobase = iobase;
+
+	if (!iobase || !request_region(iobase,
+			thisboard->total_iosize, driver.driver_name)) {
+		printk("I/O port conflict\n");
+		return -EIO;
+	}
+
+/*
+ * Initialize dev->board_name.  Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+	dev->board_name = thisboard->name;
+
+/*
+ * Allocate the private structure area.  alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+	if (alloc_private(dev, sizeof(struct pcmmio_private)) < 0) {
+		printk("cannot allocate private data structure\n");
+		return -ENOMEM;
+	}
+
+	for (asic = 0; asic < MAX_ASICS; ++asic) {
+		devpriv->asics[asic].num = asic;
+		devpriv->asics[asic].iobase =
+			dev->iobase + 16 + asic * ASIC_IOSIZE;
+		devpriv->asics[asic].irq = 0;	/* this gets actually set at the end of
+						   this function when we
+						   comedi_request_irqs */
+		spin_lock_init(&devpriv->asics[asic].spinlock);
+	}
+
+	chans_left = CHANS_PER_ASIC * thisboard->dio_num_asics;
+	n_dio_subdevs = CALC_N_DIO_SUBDEVS(chans_left);
+	n_subdevs = n_dio_subdevs + 2;
+	devpriv->sprivs =
+		kcalloc(n_subdevs, sizeof(struct pcmmio_subdev_private), GFP_KERNEL);
+	if (!devpriv->sprivs) {
+		printk("cannot allocate subdevice private data structures\n");
+		return -ENOMEM;
+	}
+	/*
+	 * Allocate the subdevice structures.  alloc_subdevice() is a
+	 * convenient macro defined in comedidev.h.
+	 *
+	 * Allocate 1 AI + 1 AO + 2 DIO subdevs (24 lines per DIO)
+	 */
+	if (alloc_subdevices(dev, n_subdevs) < 0) {
+		printk("cannot allocate subdevice data structures\n");
+		return -ENOMEM;
+	}
+
+	/* First, AI */
+	sdev_no = 0;
+	s = dev->subdevices + sdev_no;
+	s->private = devpriv->sprivs + sdev_no;
+	s->maxdata = (1 << thisboard->ai_bits) - 1;
+	s->range_table = thisboard->ai_range_table;
+	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
+	s->type = COMEDI_SUBD_AI;
+	s->n_chan = thisboard->n_ai_chans;
+	s->len_chanlist = s->n_chan;
+	s->insn_read = thisboard->ai_rinsn;
+	subpriv->iobase = dev->iobase + 0;
+	/* initialize the resource enable register by clearing it */
+	outb(0, subpriv->iobase + 3);
+	outb(0, subpriv->iobase + 4 + 3);
+
+	/* Next, AO */
+	++sdev_no;
+	s = dev->subdevices + sdev_no;
+	s->private = devpriv->sprivs + sdev_no;
+	s->maxdata = (1 << thisboard->ao_bits) - 1;
+	s->range_table = thisboard->ao_range_table;
+	s->subdev_flags = SDF_READABLE;
+	s->type = COMEDI_SUBD_AO;
+	s->n_chan = thisboard->n_ao_chans;
+	s->len_chanlist = s->n_chan;
+	s->insn_read = thisboard->ao_rinsn;
+	s->insn_write = thisboard->ao_winsn;
+	subpriv->iobase = dev->iobase + 8;
+	/* initialize the resource enable register by clearing it */
+	outb(0, subpriv->iobase + 3);
+	outb(0, subpriv->iobase + 4 + 3);
+
+	++sdev_no;
+	port = 0;
+	asic = 0;
+	for (; sdev_no < (int)dev->n_subdevices; ++sdev_no) {
+		int byte_no;
+
+		s = dev->subdevices + sdev_no;
+		s->private = devpriv->sprivs + sdev_no;
+		s->maxdata = 1;
+		s->range_table = &range_digital;
+		s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+		s->type = COMEDI_SUBD_DIO;
+		s->insn_bits = pcmmio_dio_insn_bits;
+		s->insn_config = pcmmio_dio_insn_config;
+		s->n_chan = MIN(chans_left, MAX_CHANS_PER_SUBDEV);
+		subpriv->dio.intr.asic = -1;
+		subpriv->dio.intr.first_chan = -1;
+		subpriv->dio.intr.asic_chan = -1;
+		subpriv->dio.intr.num_asic_chans = -1;
+		subpriv->dio.intr.active = 0;
+		s->len_chanlist = 1;
+
+		/* save the ioport address for each 'port' of 8 channels in the
+		   subdevice */
+		for (byte_no = 0; byte_no < PORTS_PER_SUBDEV; ++byte_no, ++port) {
+			if (port >= PORTS_PER_ASIC) {
+				port = 0;
+				++asic;
+				thisasic_chanct = 0;
+			}
+			subpriv->iobases[byte_no] =
+				devpriv->asics[asic].iobase + port;
+
+			if (thisasic_chanct <
+				CHANS_PER_PORT * INTR_PORTS_PER_ASIC
+				&& subpriv->dio.intr.asic < 0) {
+				/* this is an interrupt subdevice, so setup the struct */
+				subpriv->dio.intr.asic = asic;
+				subpriv->dio.intr.active = 0;
+				subpriv->dio.intr.stop_count = 0;
+				subpriv->dio.intr.first_chan = byte_no * 8;
+				subpriv->dio.intr.asic_chan = thisasic_chanct;
+				subpriv->dio.intr.num_asic_chans =
+					s->n_chan -
+					subpriv->dio.intr.first_chan;
+				s->cancel = pcmmio_cancel;
+				s->do_cmd = pcmmio_cmd;
+				s->do_cmdtest = pcmmio_cmdtest;
+				s->len_chanlist =
+					subpriv->dio.intr.num_asic_chans;
+			}
+			thisasic_chanct += CHANS_PER_PORT;
+		}
+		spin_lock_init(&subpriv->dio.intr.spinlock);
+
+		chans_left -= s->n_chan;
+
+		if (!chans_left) {
+			asic = 0;	/* reset the asic to our first asic, to do intr subdevs */
+			port = 0;
+		}
+
+	}
+
+	init_asics(dev);	/* clear out all the registers, basically */
+
+	for (asic = 0; irq[0] && asic < MAX_ASICS; ++asic) {
+		if (irq[asic]
+			&& comedi_request_irq(irq[asic], interrupt_pcmmio,
+				IRQF_SHARED, thisboard->name, dev)) {
+			int i;
+			/* unroll the allocated irqs.. */
+			for (i = asic - 1; i >= 0; --i) {
+				comedi_free_irq(irq[i], dev);
+				devpriv->asics[i].irq = irq[i] = 0;
+			}
+			irq[asic] = 0;
+		}
+		devpriv->asics[asic].irq = irq[asic];
+	}
+
+	dev->irq = irq[0];	/* grr.. wish comedi dev struct supported multiple
+				   irqs.. */
+
+	if (irq[0]) {
+		printk("irq: %u ", irq[0]);
+		if (irq[1] && thisboard->dio_num_asics == 2)
+			printk("second ASIC irq: %u ", irq[1]);
+	} else {
+		printk("(IRQ mode disabled) ");
+	}
+
+	printk("attached\n");
+
+	return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device.  It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach().  dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pcmmio_detach(struct comedi_device * dev)
+{
+	int i;
+
+	printk("comedi%d: %s: remove\n", dev->minor, driver.driver_name);
+	if (dev->iobase)
+		release_region(dev->iobase, thisboard->total_iosize);
+
+	for (i = 0; i < MAX_ASICS; ++i) {
+		if (devpriv && devpriv->asics[i].irq)
+			comedi_free_irq(devpriv->asics[i].irq, dev);
+	}
+
+	if (devpriv && devpriv->sprivs)
+		kfree(devpriv->sprivs);
+
+	return 0;
+}
+
+/* DIO devices are slightly special.  Although it is possible to
+ * implement the insn_read/insn_write interface, it is much more
+ * useful to applications if you implement the insn_bits interface.
+ * This allows packed reading/writing of the DIO channels.  The
+ * comedi core can convert between insn_bits and insn_read/write */
+static int pcmmio_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int byte_no;
+	if (insn->n != 2)
+		return -EINVAL;
+
+	/* NOTE:
+	   reading a 0 means this channel was high
+	   writine a 0 sets the channel high
+	   reading a 1 means this channel was low
+	   writing a 1 means set this channel low
+
+	   Therefore everything is always inverted. */
+
+	/* The insn data is a mask in data[0] and the new data
+	 * in data[1], each channel cooresponding to a bit. */
+
+#ifdef DAMMIT_ITS_BROKEN
+	/* DEBUG */
+	printk("write mask: %08x  data: %08x\n", data[0], data[1]);
+#endif
+
+	s->state = 0;
+
+	for (byte_no = 0; byte_no < s->n_chan / CHANS_PER_PORT; ++byte_no) {
+		/* address of 8-bit port */
+		unsigned long ioaddr = subpriv->iobases[byte_no],
+			/* bit offset of port in 32-bit doubleword */
+			offset = byte_no * 8;
+		/* this 8-bit port's data */
+		unsigned char byte = 0,
+			/* The write mask for this port (if any) */
+			write_mask_byte = (data[0] >> offset) & 0xff,
+			/* The data byte for this port */
+			data_byte = (data[1] >> offset) & 0xff;
+
+		byte = inb(ioaddr);	/* read all 8-bits for this port */
+
+#ifdef DAMMIT_ITS_BROKEN
+		/* DEBUG */
+		printk("byte %d wmb %02x db %02x offset %02d io %04x, data_in %02x ", byte_no, (unsigned)write_mask_byte, (unsigned)data_byte, offset, ioaddr, (unsigned)byte);
+#endif
+
+		if (write_mask_byte) {
+			/* this byte has some write_bits -- so set the output lines */
+			byte &= ~write_mask_byte;	/* clear bits for write mask */
+			byte |= ~data_byte & write_mask_byte;	/* set to inverted data_byte */
+			/* Write out the new digital output state */
+			outb(byte, ioaddr);
+		}
+#ifdef DAMMIT_ITS_BROKEN
+		/* DEBUG */
+		printk("data_out_byte %02x\n", (unsigned)byte);
+#endif
+		/* save the digital input lines for this byte.. */
+		s->state |= ((unsigned int)byte) << offset;
+	}
+
+	/* now return the DIO lines to data[1] - note they came inverted! */
+	data[1] = ~s->state;
+
+#ifdef DAMMIT_ITS_BROKEN
+	/* DEBUG */
+	printk("s->state %08x data_out %08x\n", s->state, data[1]);
+#endif
+
+	return 2;
+}
+
+/* The input or output configuration of each digital line is
+ * configured by a special insn_config instruction.  chanspec
+ * contains the channel to be changed, and data[0] contains the
+ * value COMEDI_INPUT or COMEDI_OUTPUT. */
+static int pcmmio_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int chan = CR_CHAN(insn->chanspec), byte_no = chan / 8, bit_no =
+		chan % 8;
+	unsigned long ioaddr;
+	unsigned char byte;
+
+	/* Compute ioaddr for this channel */
+	ioaddr = subpriv->iobases[byte_no];
+
+	/* NOTE:
+	   writing a 0 an IO channel's bit sets the channel to INPUT
+	   and pulls the line high as well
+
+	   writing a 1 to an IO channel's  bit pulls the line low
+
+	   All channels are implicitly always in OUTPUT mode -- but when
+	   they are high they can be considered to be in INPUT mode..
+
+	   Thus, we only force channels low if the config request was INPUT,
+	   otherwise we do nothing to the hardware.    */
+
+	switch (data[0]) {
+	case INSN_CONFIG_DIO_OUTPUT:
+		/* save to io_bits -- don't actually do anything since
+		   all input channels are also output channels... */
+		s->io_bits |= 1 << chan;
+		break;
+	case INSN_CONFIG_DIO_INPUT:
+		/* write a 0 to the actual register representing the channel
+		   to set it to 'input'.  0 means "float high". */
+		byte = inb(ioaddr);
+		byte &= ~(1 << bit_no);
+				/**< set input channel to '0' */
+
+		/* write out byte -- this is the only time we actually affect the
+		   hardware as all channels are implicitly output -- but input
+		   channels are set to float-high */
+		outb(byte, ioaddr);
+
+		/* save to io_bits */
+		s->io_bits &= ~(1 << chan);
+		break;
+
+	case INSN_CONFIG_DIO_QUERY:
+		/* retreive from shadow register */
+		data[1] =
+			(s->
+			io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+		return insn->n;
+		break;
+
+	default:
+		return -EINVAL;
+		break;
+	}
+
+	return insn->n;
+}
+
+static void init_asics(struct comedi_device * dev)
+{				/* sets up an
+				   ASIC chip to defaults */
+	int asic;
+
+	for (asic = 0; asic < thisboard->dio_num_asics; ++asic) {
+		int port, page;
+		unsigned long baseaddr = devpriv->asics[asic].iobase;
+
+		switch_page(dev, asic, 0);	/* switch back to page 0 */
+
+		/* first, clear all the DIO port bits */
+		for (port = 0; port < PORTS_PER_ASIC; ++port)
+			outb(0, baseaddr + REG_PORT0 + port);
+
+		/* Next, clear all the paged registers for each page */
+		for (page = 1; page < NUM_PAGES; ++page) {
+			int reg;
+			/* now clear all the paged registers */
+			switch_page(dev, asic, page);
+			for (reg = FIRST_PAGED_REG;
+				reg < FIRST_PAGED_REG + NUM_PAGED_REGS; ++reg)
+				outb(0, baseaddr + reg);
+		}
+
+		/* DEBUG  set rising edge interrupts on port0 of both asics */
+		/*switch_page(dev, asic, PAGE_POL);
+		   outb(0xff, baseaddr + REG_POL0);
+		   switch_page(dev, asic, PAGE_ENAB);
+		   outb(0xff, baseaddr + REG_ENAB0); */
+		/* END DEBUG */
+
+		switch_page(dev, asic, 0);	/* switch back to default page 0 */
+
+	}
+}
+
+static void switch_page(struct comedi_device * dev, int asic, int page)
+{
+	if (asic < 0 || asic >= thisboard->dio_num_asics)
+		return;		/* paranoia */
+	if (page < 0 || page >= NUM_PAGES)
+		return;		/* more paranoia */
+
+	devpriv->asics[asic].pagelock &= ~REG_PAGE_MASK;
+	devpriv->asics[asic].pagelock |= page << REG_PAGE_BITOFFSET;
+
+	/* now write out the shadow register */
+	outb(devpriv->asics[asic].pagelock,
+		devpriv->asics[asic].iobase + REG_PAGELOCK);
+}
+
+#ifdef notused
+static void lock_port(struct comedi_device * dev, int asic, int port)
+{
+	if (asic < 0 || asic >= thisboard->dio_num_asics)
+		return;		/* paranoia */
+	if (port < 0 || port >= PORTS_PER_ASIC)
+		return;		/* more paranoia */
+
+	devpriv->asics[asic].pagelock |= 0x1 << port;
+	/* now write out the shadow register */
+	outb(devpriv->asics[asic].pagelock,
+		devpriv->asics[asic].iobase + REG_PAGELOCK);
+	return;
+}
+
+static void unlock_port(struct comedi_device * dev, int asic, int port)
+{
+	if (asic < 0 || asic >= thisboard->dio_num_asics)
+		return;		/* paranoia */
+	if (port < 0 || port >= PORTS_PER_ASIC)
+		return;		/* more paranoia */
+	devpriv->asics[asic].pagelock &= ~(0x1 << port) | REG_LOCK_MASK;
+	/* now write out the shadow register */
+	outb(devpriv->asics[asic].pagelock,
+		devpriv->asics[asic].iobase + REG_PAGELOCK);
+}
+#endif /* notused */
+
+static irqreturn_t interrupt_pcmmio(int irq, void *d PT_REGS_ARG)
+{
+	int asic, got1 = 0;
+	struct comedi_device *dev = (struct comedi_device *) d;
+
+	for (asic = 0; asic < MAX_ASICS; ++asic) {
+		if (irq == devpriv->asics[asic].irq) {
+			unsigned long flags;
+			unsigned triggered = 0;
+			unsigned long iobase = devpriv->asics[asic].iobase;
+			/* it is an interrupt for ASIC #asic */
+			unsigned char int_pend;
+
+			comedi_spin_lock_irqsave(&devpriv->asics[asic].spinlock,
+				flags);
+
+			int_pend = inb(iobase + REG_INT_PENDING) & 0x07;
+
+			if (int_pend) {
+				int port;
+				for (port = 0; port < INTR_PORTS_PER_ASIC;
+					++port) {
+					if (int_pend & (0x1 << port)) {
+						unsigned char
+							io_lines_with_edges = 0;
+						switch_page(dev, asic,
+							PAGE_INT_ID);
+						io_lines_with_edges =
+							inb(iobase +
+							REG_INT_ID0 + port);
+
+						if (io_lines_with_edges)
+							/* clear pending interrupt */
+							outb(0, iobase +
+								REG_INT_ID0 +
+								port);
+
+						triggered |=
+							io_lines_with_edges <<
+							port * 8;
+					}
+				}
+
+				++got1;
+			}
+
+			comedi_spin_unlock_irqrestore(&devpriv->asics[asic].
+				spinlock, flags);
+
+			if (triggered) {
+				struct comedi_subdevice *s;
+				/* TODO here: dispatch io lines to subdevs with commands.. */
+				printk("PCMMIO DEBUG: got edge detect interrupt %d asic %d which_chans: %06x\n", irq, asic, triggered);
+				for (s = dev->subdevices + 2;
+					s < dev->subdevices + dev->n_subdevices;
+					++s) {
+					if (subpriv->dio.intr.asic == asic) {	/* this is an interrupt subdev, and it matches this asic! */
+						unsigned long flags;
+						unsigned oldevents;
+
+						comedi_spin_lock_irqsave
+							(&subpriv->dio.intr.
+							spinlock, flags);
+
+						oldevents = s->async->events;
+
+						if (subpriv->dio.intr.active) {
+							unsigned mytrig =
+								((triggered >>
+									subpriv->
+									dio.
+									intr.
+									asic_chan)
+								& ((0x1 << subpriv->dio.intr.num_asic_chans) - 1)) << subpriv->dio.intr.first_chan;
+							if (mytrig & subpriv->
+								dio.intr.
+								enabled_mask) {
+								unsigned int val =
+									0;
+								unsigned int n,
+									ch, len;
+
+								len = s->async->
+									cmd.
+									chanlist_len;
+								for (n = 0;
+									n < len;
+									n++) {
+									ch = CR_CHAN(s->async->cmd.chanlist[n]);
+									if (mytrig & (1U << ch)) {
+										val |= (1U << n);
+									}
+								}
+								/* Write the scan to the buffer. */
+								if (comedi_buf_put(s->async, ((short *) & val)[0])
+									&&
+									comedi_buf_put
+									(s->async, ((short *) & val)[1])) {
+									s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
+								} else {
+									/* Overflow! Stop acquisition!! */
+									/* TODO: STOP_ACQUISITION_CALL_HERE!! */
+									pcmmio_stop_intr
+										(dev,
+										s);
+								}
+
+								/* Check for end of acquisition. */
+								if (!subpriv->
+									dio.
+									intr.
+									continuous)
+								{
+									/* stop_src == TRIG_COUNT */
+									if (subpriv->dio.intr.stop_count > 0) {
+										subpriv->
+											dio.
+											intr.
+											stop_count--;
+										if (subpriv->dio.intr.stop_count == 0) {
+											s->async->events |= COMEDI_CB_EOA;
+											/* TODO: STOP_ACQUISITION_CALL_HERE!! */
+											pcmmio_stop_intr
+												(dev,
+												s);
+										}
+									}
+								}
+							}
+						}
+
+						comedi_spin_unlock_irqrestore
+							(&subpriv->dio.intr.
+							spinlock, flags);
+
+						if (oldevents !=
+							s->async->events) {
+							comedi_event(dev, s);
+						}
+
+					}
+
+				}
+			}
+
+		}
+	}
+	if (!got1)
+		return IRQ_NONE;	/* interrupt from other source */
+	return IRQ_HANDLED;
+}
+
+static void pcmmio_stop_intr(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	int nports, firstport, asic, port;
+
+	if ((asic = subpriv->dio.intr.asic) < 0)
+		return;		/* not an interrupt subdev */
+
+	subpriv->dio.intr.enabled_mask = 0;
+	subpriv->dio.intr.active = 0;
+	s->async->inttrig = 0;
+	nports = subpriv->dio.intr.num_asic_chans / CHANS_PER_PORT;
+	firstport = subpriv->dio.intr.asic_chan / CHANS_PER_PORT;
+	switch_page(dev, asic, PAGE_ENAB);
+	for (port = firstport; port < firstport + nports; ++port) {
+		/* disable all intrs for this subdev.. */
+		outb(0, devpriv->asics[asic].iobase + REG_ENAB0 + port);
+	}
+}
+
+static int pcmmio_start_intr(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	if (!subpriv->dio.intr.continuous && subpriv->dio.intr.stop_count == 0) {
+		/* An empty acquisition! */
+		s->async->events |= COMEDI_CB_EOA;
+		subpriv->dio.intr.active = 0;
+		return 1;
+	} else {
+		unsigned bits = 0, pol_bits = 0, n;
+		int nports, firstport, asic, port;
+		struct comedi_cmd *cmd = &s->async->cmd;
+
+		if ((asic = subpriv->dio.intr.asic) < 0)
+			return 1;	/* not an interrupt
+					   subdev */
+		subpriv->dio.intr.enabled_mask = 0;
+		subpriv->dio.intr.active = 1;
+		nports = subpriv->dio.intr.num_asic_chans / CHANS_PER_PORT;
+		firstport = subpriv->dio.intr.asic_chan / CHANS_PER_PORT;
+		if (cmd->chanlist) {
+			for (n = 0; n < cmd->chanlist_len; n++) {
+				bits |= (1U << CR_CHAN(cmd->chanlist[n]));
+				pol_bits |= (CR_AREF(cmd->chanlist[n])
+					|| CR_RANGE(cmd->chanlist[n]) ? 1U : 0U)
+					<< CR_CHAN(cmd->chanlist[n]);
+			}
+		}
+		bits &= ((0x1 << subpriv->dio.intr.num_asic_chans) -
+			1) << subpriv->dio.intr.first_chan;
+		subpriv->dio.intr.enabled_mask = bits;
+
+		{		/* the below code configures the board to use a specific IRQ from 0-15. */
+			unsigned char b;
+			/* set resource enable register to enable IRQ operation */
+			outb(1 << 4, dev->iobase + 3);
+			/* set bits 0-3 of b to the irq number from 0-15 */
+			b = dev->irq & ((1 << 4) - 1);
+			outb(b, dev->iobase + 2);
+			/* done, we told the board what irq to use */
+		}
+
+		switch_page(dev, asic, PAGE_ENAB);
+		for (port = firstport; port < firstport + nports; ++port) {
+			unsigned enab =
+				bits >> (subpriv->dio.intr.first_chan + (port -
+					firstport) * 8) & 0xff, pol =
+				pol_bits >> (subpriv->dio.intr.first_chan +
+				(port - firstport) * 8) & 0xff;
+			/* set enab intrs for this subdev.. */
+			outb(enab,
+				devpriv->asics[asic].iobase + REG_ENAB0 + port);
+			switch_page(dev, asic, PAGE_POL);
+			outb(pol,
+				devpriv->asics[asic].iobase + REG_ENAB0 + port);
+		}
+	}
+	return 0;
+}
+
+static int pcmmio_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&subpriv->dio.intr.spinlock, flags);
+	if (subpriv->dio.intr.active)
+		pcmmio_stop_intr(dev, s);
+	comedi_spin_unlock_irqrestore(&subpriv->dio.intr.spinlock, flags);
+
+	return 0;
+}
+
+/*
+ * Internal trigger function to start acquisition for an 'INTERRUPT' subdevice.
+ */
+static int
+pcmmio_inttrig_start_intr(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int trignum)
+{
+	unsigned long flags;
+	int event = 0;
+
+	if (trignum != 0)
+		return -EINVAL;
+
+	comedi_spin_lock_irqsave(&subpriv->dio.intr.spinlock, flags);
+	s->async->inttrig = 0;
+	if (subpriv->dio.intr.active) {
+		event = pcmmio_start_intr(dev, s);
+	}
+	comedi_spin_unlock_irqrestore(&subpriv->dio.intr.spinlock, flags);
+
+	if (event) {
+		comedi_event(dev, s);
+	}
+
+	return 1;
+}
+
+/*
+ * 'do_cmd' function for an 'INTERRUPT' subdevice.
+ */
+static int pcmmio_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned long flags;
+	int event = 0;
+
+	comedi_spin_lock_irqsave(&subpriv->dio.intr.spinlock, flags);
+	subpriv->dio.intr.active = 1;
+
+	/* Set up end of acquisition. */
+	switch (cmd->stop_src) {
+	case TRIG_COUNT:
+		subpriv->dio.intr.continuous = 0;
+		subpriv->dio.intr.stop_count = cmd->stop_arg;
+		break;
+	default:
+		/* TRIG_NONE */
+		subpriv->dio.intr.continuous = 1;
+		subpriv->dio.intr.stop_count = 0;
+		break;
+	}
+
+	/* Set up start of acquisition. */
+	switch (cmd->start_src) {
+	case TRIG_INT:
+		s->async->inttrig = pcmmio_inttrig_start_intr;
+		break;
+	default:
+		/* TRIG_NOW */
+		event = pcmmio_start_intr(dev, s);
+		break;
+	}
+	comedi_spin_unlock_irqrestore(&subpriv->dio.intr.spinlock, flags);
+
+	if (event) {
+		comedi_event(dev, s);
+	}
+
+	return 0;
+}
+
+/*
+ * 'do_cmdtest' function for an 'INTERRUPT' subdevice.
+ */
+static int
+pcmmio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s, struct comedi_cmd * cmd)
+{
+	int err = 0;
+	unsigned int tmp;
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= (TRIG_NOW | TRIG_INT);
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_EXT;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_NOW;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= (TRIG_COUNT | TRIG_NONE);
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	/* these tests are true if more than one _src bit is set */
+	if ((cmd->start_src & (cmd->start_src - 1)) != 0)
+		err++;
+	if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
+		err++;
+	if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
+		err++;
+	if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
+		err++;
+	if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	/* cmd->start_src == TRIG_NOW || cmd->start_src == TRIG_INT */
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+
+	/* cmd->scan_begin_src == TRIG_EXT */
+	if (cmd->scan_begin_arg != 0) {
+		cmd->scan_begin_arg = 0;
+		err++;
+	}
+
+	/* cmd->convert_src == TRIG_NOW */
+	if (cmd->convert_arg != 0) {
+		cmd->convert_arg = 0;
+		err++;
+	}
+
+	/* cmd->scan_end_src == TRIG_COUNT */
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+
+	switch (cmd->stop_src) {
+	case TRIG_COUNT:
+		/* any count allowed */
+		break;
+	case TRIG_NONE:
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+		break;
+	default:
+		break;
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	/* if (err) return 4; */
+
+	return 0;
+}
+
+static int adc_wait_ready(unsigned long iobase)
+{
+	unsigned long retry = 100000;
+	while (retry--)
+		if (inb(iobase + 3) & 0x80)
+			return 0;
+	return 1;
+}
+
+/* All this is for AI and AO */
+static int ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n;
+	unsigned long iobase = subpriv->iobase;
+
+	/*
+	   1. write the CMD byte (to BASE+2)
+	   2. read junk lo byte (BASE+0)
+	   3. read junk hi byte (BASE+1)
+	   4. (mux settled so) write CMD byte again (BASE+2)
+	   5. read valid lo byte(BASE+0)
+	   6. read valid hi byte(BASE+1)
+
+	   Additionally note that the BASE += 4 if the channel >= 8
+	 */
+
+	/* convert n samples */
+	for (n = 0; n < insn->n; n++) {
+		unsigned chan = CR_CHAN(insn->chanspec), range =
+			CR_RANGE(insn->chanspec), aref =
+			CR_AREF(insn->chanspec);
+		unsigned char command_byte = 0;
+		unsigned iooffset = 0;
+		short sample, adc_adjust = 0;
+
+		if (chan > 7)
+			chan -= 8, iooffset = 4;	/* use the second dword for channels > 7 */
+
+		if (aref != AREF_DIFF) {
+			aref = AREF_GROUND;
+			command_byte |= 1 << 7;	/* set bit 7 to indicate single-ended */
+		}
+		if (range < 2)
+			adc_adjust = 0x8000;	/* bipolar ranges (-5,5 .. -10,10 need to be adjusted -- that is.. they need to wrap around by adding 0x8000 */
+
+		if (chan % 2) {
+			command_byte |= 1 << 6;	/* odd-numbered channels have bit 6 set */
+		}
+
+		/* select the channel, bits 4-5 == chan/2 */
+		command_byte |= ((chan / 2) & 0x3) << 4;
+
+		/* set the range, bits 2-3 */
+		command_byte |= (range & 0x3) << 2;
+
+		/* need to do this twice to make sure mux settled */
+		outb(command_byte, iobase + iooffset + 2);	/* chan/range/aref select */
+
+		adc_wait_ready(iobase + iooffset);	/* wait for the adc to say it finised the conversion */
+
+		outb(command_byte, iobase + iooffset + 2);	/* select the chan/range/aref AGAIN */
+
+		adc_wait_ready(iobase + iooffset);
+
+		sample = inb(iobase + iooffset + 0);	/* read data lo byte */
+		sample |= inb(iobase + iooffset + 1) << 8;	/* read data hi byte */
+		sample += adc_adjust;	/* adjustment .. munge data */
+		data[n] = sample;
+	}
+	/* return the number of samples read/written */
+	return n;
+}
+
+static int ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n;
+	for (n = 0; n < insn->n; n++) {
+		unsigned chan = CR_CHAN(insn->chanspec);
+		if (chan < s->n_chan)
+			data[n] = subpriv->ao.shadow_samples[chan];
+	}
+	return n;
+}
+
+static int wait_dac_ready(unsigned long iobase)
+{
+	unsigned long retry = 100000L;
+
+	/* This may seem like an absurd way to handle waiting and violates the
+	   "no busy waiting" policy. The fact is that the hardware is
+	   normally so fast that we usually only need one time through the loop
+	   anyway. The longer timeout is for rare occasions and for detecting
+	   non-existant hardware.  */
+
+	while (retry--) {
+		if (inb(iobase + 3) & 0x80)
+			return 0;
+
+	}
+	return 1;
+}
+
+static int ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n;
+	unsigned iobase = subpriv->iobase, iooffset = 0;
+
+	for (n = 0; n < insn->n; n++) {
+		unsigned chan = CR_CHAN(insn->chanspec), range =
+			CR_RANGE(insn->chanspec);
+		if (chan < s->n_chan) {
+			unsigned char command_byte = 0, range_byte =
+				range & ((1 << 4) - 1);
+			if (chan >= 4)
+				chan -= 4, iooffset += 4;
+			/* set the range.. */
+			outb(range_byte, iobase + iooffset + 0);
+			outb(0, iobase + iooffset + 1);
+
+			/* tell it to begin */
+			command_byte = (chan << 1) | 0x60;
+			outb(command_byte, iobase + iooffset + 2);
+
+			wait_dac_ready(iobase + iooffset);
+
+			outb(data[n] & 0xff, iobase + iooffset + 0);	/* low order byte */
+			outb((data[n] >> 8) & 0xff, iobase + iooffset + 1);	/* high order byte */
+			command_byte = 0x70 | (chan << 1);	/* set bit 4 of command byte to indicate data is loaded and trigger conversion */
+			/* trigger converion */
+			outb(command_byte, iobase + iooffset + 2);
+
+			wait_dac_ready(iobase + iooffset);
+
+			subpriv->ao.shadow_samples[chan] = data[n];	/* save to shadow register for ao_rinsn */
+		}
+	}
+	return n;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver);
diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c
new file mode 100644
index 0000000..4e7d8b6
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcmuio.c
@@ -0,0 +1,1101 @@
+/*
+    comedi/drivers/pcmuio.c
+    Driver for Winsystems PC-104 based 48-channel and 96-channel DIO boards.
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2006 Calin A. Culianu <calin@ajvar.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.
+
+    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.
+*/
+/*
+Driver: pcmuio
+Description: A driver for the PCM-UIO48A and PCM-UIO96A boards from Winsystems.
+Devices: [Winsystems] PCM-UIO48A (pcmuio48), PCM-UIO96A (pcmuio96)
+Author: Calin Culianu <calin@ajvar.org>
+Updated: Fri, 13 Jan 2006 12:01:01 -0500
+Status: works
+
+A driver for the relatively straightforward-to-program PCM-UIO48A and
+PCM-UIO96A boards from Winsystems.  These boards use either one or two
+(in the 96-DIO version) WS16C48 ASIC HighDensity I/O Chips (HDIO).
+This chip is interesting in that each I/O line is individually
+programmable for INPUT or OUTPUT (thus comedi_dio_config can be done
+on a per-channel basis).  Also, each chip supports edge-triggered
+interrupts for the first 24 I/O lines.  Of course, since the
+96-channel version of the board has two ASICs, it can detect polarity
+changes on up to 48 I/O lines.  Since this is essentially an (non-PnP)
+ISA board, I/O Address and IRQ selection are done through jumpers on
+the board.  You need to pass that information to this driver as the
+first and second comedi_config option, respectively.  Note that the
+48-channel version uses 16 bytes of IO memory and the 96-channel
+version uses 32-bytes (in case you are worried about conflicts).  The
+48-channel board is split into two 24-channel comedi subdevices.
+The 96-channel board is split into 4 24-channel DIO subdevices.
+
+Note that IRQ support has been added, but it is untested.
+
+To use edge-detection IRQ support, pass the IRQs of both ASICS
+(for the 96 channel version) or just 1 ASIC (for 48-channel version).
+Then, use use comedi_commands with TRIG_NOW.
+Your callback will be called each time an edge is triggered, and the data
+values will be two sample_t's, which should be concatenated to form one
+32-bit unsigned int.  This value is the mask of channels that had
+edges detected from your channel list.  Note that the bits positions
+in the mask correspond to positions in your chanlist when you specified
+the command and *not* channel id's!
+
+To set the polarity of the edge-detection interrupts pass a nonzero value for
+either CR_RANGE or CR_AREF for edge-up polarity, or a zero value for both
+CR_RANGE and CR_AREF if you want edge-down polarity.
+
+In the 48-channel version:
+
+On subdev 0, the first 24 channels channels are edge-detect channels.
+
+In the 96-channel board you have the collowing channels that can do edge detection:
+
+subdev 0, channels 0-24  (first 24 channels of 1st ASIC)
+subdev 2, channels 0-24  (first 24 channels of 2nd ASIC)
+
+Configuration Options:
+  [0] - I/O port base address
+  [1] - IRQ (for first ASIC, or first 24 channels)
+  [2] - IRQ for second ASIC (pcmuio96 only - IRQ for chans 48-72 .. can be the same as first irq!)
+*/
+
+#include "../comedidev.h"
+
+#include <linux/pci.h>		/* for PCI devices */
+
+#define MIN(a,b) ( ((a) < (b)) ? (a) : (b) )
+#define CHANS_PER_PORT   8
+#define PORTS_PER_ASIC   6
+#define INTR_PORTS_PER_ASIC   3
+#define MAX_CHANS_PER_SUBDEV 24	/* number of channels per comedi subdevice */
+#define PORTS_PER_SUBDEV (MAX_CHANS_PER_SUBDEV/CHANS_PER_PORT)
+#define CHANS_PER_ASIC (CHANS_PER_PORT*PORTS_PER_ASIC)
+#define INTR_CHANS_PER_ASIC 24
+#define INTR_PORTS_PER_SUBDEV (INTR_CHANS_PER_ASIC/CHANS_PER_PORT)
+#define MAX_DIO_CHANS   (PORTS_PER_ASIC*2*CHANS_PER_PORT)
+#define MAX_ASICS       (MAX_DIO_CHANS/CHANS_PER_ASIC)
+#define SDEV_NO ((int)(s - dev->subdevices))
+#define CALC_N_SUBDEVS(nchans) ((nchans)/MAX_CHANS_PER_SUBDEV + (!!((nchans)%MAX_CHANS_PER_SUBDEV)) /*+ (nchans > INTR_CHANS_PER_ASIC ? 2 : 1)*/)
+/* IO Memory sizes */
+#define ASIC_IOSIZE (0x10)
+#define PCMUIO48_IOSIZE ASIC_IOSIZE
+#define PCMUIO96_IOSIZE (ASIC_IOSIZE*2)
+
+/* Some offsets - these are all in the 16byte IO memory offset from
+   the base address.  Note that there is a paging scheme to swap out
+   offsets 0x8-0xA using the PAGELOCK register.  See the table below.
+
+  Register(s)       Pages        R/W?        Description
+  --------------------------------------------------------------
+  REG_PORTx         All          R/W         Read/Write/Configure IO
+  REG_INT_PENDING   All          ReadOnly    Quickly see which INT_IDx has int.
+  REG_PAGELOCK      All          WriteOnly   Select a page
+  REG_POLx          Pg. 1 only   WriteOnly   Select edge-detection polarity
+  REG_ENABx         Pg. 2 only   WriteOnly   Enable/Disable edge-detect. int.
+  REG_INT_IDx       Pg. 3 only   R/W         See which ports/bits have ints.
+ */
+#define REG_PORT0 0x0
+#define REG_PORT1 0x1
+#define REG_PORT2 0x2
+#define REG_PORT3 0x3
+#define REG_PORT4 0x4
+#define REG_PORT5 0x5
+#define REG_INT_PENDING 0x6
+#define REG_PAGELOCK 0x7	/* page selector register, upper 2 bits select a page
+				   and bits 0-5 are used to 'lock down' a particular
+				   port above to make it readonly.  */
+#define REG_POL0 0x8
+#define REG_POL1 0x9
+#define REG_POL2 0xA
+#define REG_ENAB0 0x8
+#define REG_ENAB1 0x9
+#define REG_ENAB2 0xA
+#define REG_INT_ID0 0x8
+#define REG_INT_ID1 0x9
+#define REG_INT_ID2 0xA
+
+#define NUM_PAGED_REGS 3
+#define NUM_PAGES 4
+#define FIRST_PAGED_REG 0x8
+#define REG_PAGE_BITOFFSET 6
+#define REG_LOCK_BITOFFSET 0
+#define REG_PAGE_MASK (~((0x1<<REG_PAGE_BITOFFSET)-1))
+#define REG_LOCK_MASK ~(REG_PAGE_MASK)
+#define PAGE_POL 1
+#define PAGE_ENAB 2
+#define PAGE_INT_ID 3
+
+/*
+ * Board descriptions for two imaginary boards.  Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct pcmuio_board {
+	const char *name;
+	const int num_asics;
+	const int num_channels_per_port;
+	const int num_ports;
+};
+
+static const struct pcmuio_board pcmuio_boards[] = {
+	{
+	      name:	"pcmuio48",
+	      num_asics:1,
+	      num_ports:6,
+		},
+	{
+	      name:	"pcmuio96",
+	      num_asics:2,
+	      num_ports:12,
+		},
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct pcmuio_board *)dev->board_ptr)
+
+/* this structure is for data unique to this subdevice.  */
+struct pcmuio_subdev_private {
+	/* mapping of halfwords (bytes) in port/chanarray to iobase */
+	unsigned long iobases[PORTS_PER_SUBDEV];
+
+	/* The below is only used for intr subdevices */
+	struct {
+		int asic;	/* if non-negative, this subdev has an interrupt asic */
+		int first_chan;	/* if nonnegative, the first channel id for
+				   interrupts. */
+		int num_asic_chans;	/* the number of asic channels in this subdev
+					   that have interrutps */
+		int asic_chan;	/* if nonnegative, the first channel id with
+				   respect to the asic that has interrupts */
+		int enabled_mask;	/* subdev-relative channel mask for channels
+					   we are interested in */
+		int active;
+		int stop_count;
+		int continuous;
+		spinlock_t spinlock;
+	} intr;
+};
+
+/* this structure is for data unique to this hardware driver.  If
+   several hardware drivers keep similar information in this structure,
+   feel free to suggest moving the variable to the struct comedi_device struct.  */
+struct pcmuio_private {
+	struct {
+		unsigned char pagelock;	/* current page and lock */
+		unsigned char pol[NUM_PAGED_REGS];	/* shadow of POLx registers */
+		unsigned char enab[NUM_PAGED_REGS];	/* shadow of ENABx registers */
+		int num;
+		unsigned long iobase;
+		unsigned int irq;
+		spinlock_t spinlock;
+	} asics[MAX_ASICS];
+	struct pcmuio_subdev_private *sprivs;
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct pcmuio_private *)dev->private)
+#define subpriv ((struct pcmuio_subdev_private *)s->private)
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pcmuio_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcmuio_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver = {
+      driver_name:"pcmuio",
+      module:THIS_MODULE,
+      attach:pcmuio_attach,
+      detach:pcmuio_detach,
+/* It is not necessary to implement the following members if you are
+ * writing a driver for a ISA PnP or PCI card */
+	/* Most drivers will support multiple types of boards by
+	 * having an array of board structures.  These were defined
+	 * in pcmuio_boards[] above.  Note that the element 'name'
+	 * was first in the structure -- Comedi uses this fact to
+	 * extract the name of the board without knowing any details
+	 * about the structure except for its length.
+	 * When a device is attached (by comedi_config), the name
+	 * of the device is given to Comedi, and Comedi tries to
+	 * match it by going through the list of board names.  If
+	 * there is a match, the address of the pointer is put
+	 * into dev->board_ptr and driver->attach() is called.
+	 *
+	 * Note that these are not necessary if you can determine
+	 * the type of board in software.  ISA PnP, PCI, and PCMCIA
+	 * devices are such boards.
+	 */
+      board_name:&pcmuio_boards[0].name,
+      offset:sizeof(struct pcmuio_board),
+      num_names:sizeof(pcmuio_boards) / sizeof(struct pcmuio_board),
+};
+
+static int pcmuio_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int pcmuio_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+static irqreturn_t interrupt_pcmuio(int irq, void *d PT_REGS_ARG);
+static void pcmuio_stop_intr(struct comedi_device *, struct comedi_subdevice *);
+static int pcmuio_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pcmuio_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pcmuio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd);
+
+/* some helper functions to deal with specifics of this device's registers */
+static void init_asics(struct comedi_device * dev);	/* sets up/clears ASIC chips to defaults */
+static void switch_page(struct comedi_device * dev, int asic, int page);
+#ifdef notused
+static void lock_port(struct comedi_device * dev, int asic, int port);
+static void unlock_port(struct comedi_device * dev, int asic, int port);
+#endif
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board.  If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pcmuio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	int sdev_no, chans_left, n_subdevs, port, asic, thisasic_chanct = 0;
+	unsigned long iobase;
+	unsigned int irq[MAX_ASICS];
+
+	iobase = it->options[0];
+	irq[0] = it->options[1];
+	irq[1] = it->options[2];
+
+	printk("comedi%d: %s: io: %lx ", dev->minor, driver.driver_name,
+		iobase);
+
+	dev->iobase = iobase;
+
+	if (!iobase || !request_region(iobase,
+			thisboard->num_asics * ASIC_IOSIZE,
+			driver.driver_name)) {
+		printk("I/O port conflict\n");
+		return -EIO;
+	}
+
+/*
+ * Initialize dev->board_name.  Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+	dev->board_name = thisboard->name;
+
+/*
+ * Allocate the private structure area.  alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+	if (alloc_private(dev, sizeof(struct pcmuio_private)) < 0) {
+		printk("cannot allocate private data structure\n");
+		return -ENOMEM;
+	}
+
+	for (asic = 0; asic < MAX_ASICS; ++asic) {
+		devpriv->asics[asic].num = asic;
+		devpriv->asics[asic].iobase = dev->iobase + asic * ASIC_IOSIZE;
+		devpriv->asics[asic].irq = 0;	/* this gets actually set at the end of
+						   this function when we
+						   comedi_request_irqs */
+		spin_lock_init(&devpriv->asics[asic].spinlock);
+	}
+
+	chans_left = CHANS_PER_ASIC * thisboard->num_asics;
+	n_subdevs = CALC_N_SUBDEVS(chans_left);
+	devpriv->sprivs =
+		kcalloc(n_subdevs, sizeof(struct pcmuio_subdev_private), GFP_KERNEL);
+	if (!devpriv->sprivs) {
+		printk("cannot allocate subdevice private data structures\n");
+		return -ENOMEM;
+	}
+	/*
+	 * Allocate the subdevice structures.  alloc_subdevice() is a
+	 * convenient macro defined in comedidev.h.
+	 *
+	 * Allocate 2 subdevs (32 + 16 DIO lines) or 3 32 DIO subdevs for the
+	 * 96-channel version of the board.
+	 */
+	if (alloc_subdevices(dev, n_subdevs) < 0) {
+		printk("cannot allocate subdevice data structures\n");
+		return -ENOMEM;
+	}
+
+	port = 0;
+	asic = 0;
+	for (sdev_no = 0; sdev_no < (int)dev->n_subdevices; ++sdev_no) {
+		int byte_no;
+
+		s = dev->subdevices + sdev_no;
+		s->private = devpriv->sprivs + sdev_no;
+		s->maxdata = 1;
+		s->range_table = &range_digital;
+		s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+		s->type = COMEDI_SUBD_DIO;
+		s->insn_bits = pcmuio_dio_insn_bits;
+		s->insn_config = pcmuio_dio_insn_config;
+		s->n_chan = MIN(chans_left, MAX_CHANS_PER_SUBDEV);
+		subpriv->intr.asic = -1;
+		subpriv->intr.first_chan = -1;
+		subpriv->intr.asic_chan = -1;
+		subpriv->intr.num_asic_chans = -1;
+		subpriv->intr.active = 0;
+		s->len_chanlist = 1;
+
+		/* save the ioport address for each 'port' of 8 channels in the
+		   subdevice */
+		for (byte_no = 0; byte_no < PORTS_PER_SUBDEV; ++byte_no, ++port) {
+			if (port >= PORTS_PER_ASIC) {
+				port = 0;
+				++asic;
+				thisasic_chanct = 0;
+			}
+			subpriv->iobases[byte_no] =
+				devpriv->asics[asic].iobase + port;
+
+			if (thisasic_chanct <
+				CHANS_PER_PORT * INTR_PORTS_PER_ASIC
+				&& subpriv->intr.asic < 0) {
+				/* this is an interrupt subdevice, so setup the struct */
+				subpriv->intr.asic = asic;
+				subpriv->intr.active = 0;
+				subpriv->intr.stop_count = 0;
+				subpriv->intr.first_chan = byte_no * 8;
+				subpriv->intr.asic_chan = thisasic_chanct;
+				subpriv->intr.num_asic_chans =
+					s->n_chan - subpriv->intr.first_chan;
+				dev->read_subdev = s;
+				s->subdev_flags |= SDF_CMD_READ;
+				s->cancel = pcmuio_cancel;
+				s->do_cmd = pcmuio_cmd;
+				s->do_cmdtest = pcmuio_cmdtest;
+				s->len_chanlist = subpriv->intr.num_asic_chans;
+			}
+			thisasic_chanct += CHANS_PER_PORT;
+		}
+		spin_lock_init(&subpriv->intr.spinlock);
+
+		chans_left -= s->n_chan;
+
+		if (!chans_left) {
+			asic = 0;	/* reset the asic to our first asic, to do intr subdevs */
+			port = 0;
+		}
+
+	}
+
+	init_asics(dev);	/* clear out all the registers, basically */
+
+	for (asic = 0; irq[0] && asic < MAX_ASICS; ++asic) {
+		if (irq[asic]
+			&& comedi_request_irq(irq[asic], interrupt_pcmuio,
+				IRQF_SHARED, thisboard->name, dev)) {
+			int i;
+			/* unroll the allocated irqs.. */
+			for (i = asic - 1; i >= 0; --i) {
+				comedi_free_irq(irq[i], dev);
+				devpriv->asics[i].irq = irq[i] = 0;
+			}
+			irq[asic] = 0;
+		}
+		devpriv->asics[asic].irq = irq[asic];
+	}
+
+	dev->irq = irq[0];	/* grr.. wish comedi dev struct supported multiple
+				   irqs.. */
+
+	if (irq[0]) {
+		printk("irq: %u ", irq[0]);
+		if (irq[1] && thisboard->num_asics == 2)
+			printk("second ASIC irq: %u ", irq[1]);
+	} else {
+		printk("(IRQ mode disabled) ");
+	}
+
+	printk("attached\n");
+
+	return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device.  It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach().  dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pcmuio_detach(struct comedi_device * dev)
+{
+	int i;
+
+	printk("comedi%d: %s: remove\n", dev->minor, driver.driver_name);
+	if (dev->iobase)
+		release_region(dev->iobase, ASIC_IOSIZE * thisboard->num_asics);
+
+	for (i = 0; i < MAX_ASICS; ++i) {
+		if (devpriv->asics[i].irq)
+			comedi_free_irq(devpriv->asics[i].irq, dev);
+	}
+
+	if (devpriv && devpriv->sprivs)
+		kfree(devpriv->sprivs);
+
+	return 0;
+}
+
+/* DIO devices are slightly special.  Although it is possible to
+ * implement the insn_read/insn_write interface, it is much more
+ * useful to applications if you implement the insn_bits interface.
+ * This allows packed reading/writing of the DIO channels.  The
+ * comedi core can convert between insn_bits and insn_read/write */
+static int pcmuio_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int byte_no;
+	if (insn->n != 2)
+		return -EINVAL;
+
+	/* NOTE:
+	   reading a 0 means this channel was high
+	   writine a 0 sets the channel high
+	   reading a 1 means this channel was low
+	   writing a 1 means set this channel low
+
+	   Therefore everything is always inverted. */
+
+	/* The insn data is a mask in data[0] and the new data
+	 * in data[1], each channel cooresponding to a bit. */
+
+#ifdef DAMMIT_ITS_BROKEN
+	/* DEBUG */
+	printk("write mask: %08x  data: %08x\n", data[0], data[1]);
+#endif
+
+	s->state = 0;
+
+	for (byte_no = 0; byte_no < s->n_chan / CHANS_PER_PORT; ++byte_no) {
+		/* address of 8-bit port */
+		unsigned long ioaddr = subpriv->iobases[byte_no],
+			/* bit offset of port in 32-bit doubleword */
+			offset = byte_no * 8;
+		/* this 8-bit port's data */
+		unsigned char byte = 0,
+			/* The write mask for this port (if any) */
+			write_mask_byte = (data[0] >> offset) & 0xff,
+			/* The data byte for this port */
+			data_byte = (data[1] >> offset) & 0xff;
+
+		byte = inb(ioaddr);	/* read all 8-bits for this port */
+
+#ifdef DAMMIT_ITS_BROKEN
+		/* DEBUG */
+		printk("byte %d wmb %02x db %02x offset %02d io %04x, data_in %02x ", byte_no, (unsigned)write_mask_byte, (unsigned)data_byte, offset, ioaddr, (unsigned)byte);
+#endif
+
+		if (write_mask_byte) {
+			/* this byte has some write_bits -- so set the output lines */
+			byte &= ~write_mask_byte;	/* clear bits for write mask */
+			byte |= ~data_byte & write_mask_byte;	/* set to inverted data_byte */
+			/* Write out the new digital output state */
+			outb(byte, ioaddr);
+		}
+#ifdef DAMMIT_ITS_BROKEN
+		/* DEBUG */
+		printk("data_out_byte %02x\n", (unsigned)byte);
+#endif
+		/* save the digital input lines for this byte.. */
+		s->state |= ((unsigned int)byte) << offset;
+	}
+
+	/* now return the DIO lines to data[1] - note they came inverted! */
+	data[1] = ~s->state;
+
+#ifdef DAMMIT_ITS_BROKEN
+	/* DEBUG */
+	printk("s->state %08x data_out %08x\n", s->state, data[1]);
+#endif
+
+	return 2;
+}
+
+/* The input or output configuration of each digital line is
+ * configured by a special insn_config instruction.  chanspec
+ * contains the channel to be changed, and data[0] contains the
+ * value COMEDI_INPUT or COMEDI_OUTPUT. */
+static int pcmuio_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int chan = CR_CHAN(insn->chanspec), byte_no = chan / 8, bit_no =
+		chan % 8;
+	unsigned long ioaddr;
+	unsigned char byte;
+
+	/* Compute ioaddr for this channel */
+	ioaddr = subpriv->iobases[byte_no];
+
+	/* NOTE:
+	   writing a 0 an IO channel's bit sets the channel to INPUT
+	   and pulls the line high as well
+
+	   writing a 1 to an IO channel's  bit pulls the line low
+
+	   All channels are implicitly always in OUTPUT mode -- but when
+	   they are high they can be considered to be in INPUT mode..
+
+	   Thus, we only force channels low if the config request was INPUT,
+	   otherwise we do nothing to the hardware.    */
+
+	switch (data[0]) {
+	case INSN_CONFIG_DIO_OUTPUT:
+		/* save to io_bits -- don't actually do anything since
+		   all input channels are also output channels... */
+		s->io_bits |= 1 << chan;
+		break;
+	case INSN_CONFIG_DIO_INPUT:
+		/* write a 0 to the actual register representing the channel
+		   to set it to 'input'.  0 means "float high". */
+		byte = inb(ioaddr);
+		byte &= ~(1 << bit_no);
+				/**< set input channel to '0' */
+
+		/* write out byte -- this is the only time we actually affect the
+		   hardware as all channels are implicitly output -- but input
+		   channels are set to float-high */
+		outb(byte, ioaddr);
+
+		/* save to io_bits */
+		s->io_bits &= ~(1 << chan);
+		break;
+
+	case INSN_CONFIG_DIO_QUERY:
+		/* retreive from shadow register */
+		data[1] =
+			(s->
+			io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+		return insn->n;
+		break;
+
+	default:
+		return -EINVAL;
+		break;
+	}
+
+	return insn->n;
+}
+
+static void init_asics(struct comedi_device * dev)
+{				/* sets up an
+				   ASIC chip to defaults */
+	int asic;
+
+	for (asic = 0; asic < thisboard->num_asics; ++asic) {
+		int port, page;
+		unsigned long baseaddr = dev->iobase + asic * ASIC_IOSIZE;
+
+		switch_page(dev, asic, 0);	/* switch back to page 0 */
+
+		/* first, clear all the DIO port bits */
+		for (port = 0; port < PORTS_PER_ASIC; ++port)
+			outb(0, baseaddr + REG_PORT0 + port);
+
+		/* Next, clear all the paged registers for each page */
+		for (page = 1; page < NUM_PAGES; ++page) {
+			int reg;
+			/* now clear all the paged registers */
+			switch_page(dev, asic, page);
+			for (reg = FIRST_PAGED_REG;
+				reg < FIRST_PAGED_REG + NUM_PAGED_REGS; ++reg)
+				outb(0, baseaddr + reg);
+		}
+
+		/* DEBUG  set rising edge interrupts on port0 of both asics */
+		/*switch_page(dev, asic, PAGE_POL);
+		   outb(0xff, baseaddr + REG_POL0);
+		   switch_page(dev, asic, PAGE_ENAB);
+		   outb(0xff, baseaddr + REG_ENAB0); */
+		/* END DEBUG */
+
+		switch_page(dev, asic, 0);	/* switch back to default page 0 */
+
+	}
+}
+
+static void switch_page(struct comedi_device * dev, int asic, int page)
+{
+	if (asic < 0 || asic >= thisboard->num_asics)
+		return;		/* paranoia */
+	if (page < 0 || page >= NUM_PAGES)
+		return;		/* more paranoia */
+
+	devpriv->asics[asic].pagelock &= ~REG_PAGE_MASK;
+	devpriv->asics[asic].pagelock |= page << REG_PAGE_BITOFFSET;
+
+	/* now write out the shadow register */
+	outb(devpriv->asics[asic].pagelock,
+		dev->iobase + ASIC_IOSIZE * asic + REG_PAGELOCK);
+}
+
+#ifdef notused
+static void lock_port(struct comedi_device * dev, int asic, int port)
+{
+	if (asic < 0 || asic >= thisboard->num_asics)
+		return;		/* paranoia */
+	if (port < 0 || port >= PORTS_PER_ASIC)
+		return;		/* more paranoia */
+
+	devpriv->asics[asic].pagelock |= 0x1 << port;
+	/* now write out the shadow register */
+	outb(devpriv->asics[asic].pagelock,
+		dev->iobase + ASIC_IOSIZE * asic + REG_PAGELOCK);
+}
+
+static void unlock_port(struct comedi_device * dev, int asic, int port)
+{
+	if (asic < 0 || asic >= thisboard->num_asics)
+		return;		/* paranoia */
+	if (port < 0 || port >= PORTS_PER_ASIC)
+		return;		/* more paranoia */
+	devpriv->asics[asic].pagelock &= ~(0x1 << port) | REG_LOCK_MASK;
+	/* now write out the shadow register */
+	outb(devpriv->asics[asic].pagelock,
+		dev->iobase + ASIC_IOSIZE * asic + REG_PAGELOCK);
+}
+#endif /* notused */
+
+static irqreturn_t interrupt_pcmuio(int irq, void *d PT_REGS_ARG)
+{
+	int asic, got1 = 0;
+	struct comedi_device *dev = (struct comedi_device *) d;
+
+	for (asic = 0; asic < MAX_ASICS; ++asic) {
+		if (irq == devpriv->asics[asic].irq) {
+			unsigned long flags;
+			unsigned triggered = 0;
+			unsigned long iobase = devpriv->asics[asic].iobase;
+			/* it is an interrupt for ASIC #asic */
+			unsigned char int_pend;
+
+			comedi_spin_lock_irqsave(&devpriv->asics[asic].spinlock,
+				flags);
+
+			int_pend = inb(iobase + REG_INT_PENDING) & 0x07;
+
+			if (int_pend) {
+				int port;
+				for (port = 0; port < INTR_PORTS_PER_ASIC;
+					++port) {
+					if (int_pend & (0x1 << port)) {
+						unsigned char
+							io_lines_with_edges = 0;
+						switch_page(dev, asic,
+							PAGE_INT_ID);
+						io_lines_with_edges =
+							inb(iobase +
+							REG_INT_ID0 + port);
+
+						if (io_lines_with_edges)
+							/* clear pending interrupt */
+							outb(0, iobase +
+								REG_INT_ID0 +
+								port);
+
+						triggered |=
+							io_lines_with_edges <<
+							port * 8;
+					}
+				}
+
+				++got1;
+			}
+
+			comedi_spin_unlock_irqrestore(&devpriv->asics[asic].
+				spinlock, flags);
+
+			if (triggered) {
+				struct comedi_subdevice *s;
+				/* TODO here: dispatch io lines to subdevs with commands.. */
+				printk("PCMUIO DEBUG: got edge detect interrupt %d asic %d which_chans: %06x\n", irq, asic, triggered);
+				for (s = dev->subdevices;
+					s < dev->subdevices + dev->n_subdevices;
+					++s) {
+					if (subpriv->intr.asic == asic) {	/* this is an interrupt subdev, and it matches this asic! */
+						unsigned long flags;
+						unsigned oldevents;
+
+						comedi_spin_lock_irqsave
+							(&subpriv->intr.
+							spinlock, flags);
+
+						oldevents = s->async->events;
+
+						if (subpriv->intr.active) {
+							unsigned mytrig =
+								((triggered >>
+									subpriv->
+									intr.
+									asic_chan)
+								& ((0x1 << subpriv->intr.num_asic_chans) - 1)) << subpriv->intr.first_chan;
+							if (mytrig & subpriv->
+								intr.
+								enabled_mask) {
+								unsigned int val =
+									0;
+								unsigned int n,
+									ch, len;
+
+								len = s->async->
+									cmd.
+									chanlist_len;
+								for (n = 0;
+									n < len;
+									n++) {
+									ch = CR_CHAN(s->async->cmd.chanlist[n]);
+									if (mytrig & (1U << ch)) {
+										val |= (1U << n);
+									}
+								}
+								/* Write the scan to the buffer. */
+								if (comedi_buf_put(s->async, ((short *) & val)[0])
+									&&
+									comedi_buf_put
+									(s->async, ((short *) & val)[1])) {
+									s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
+								} else {
+									/* Overflow! Stop acquisition!! */
+									/* TODO: STOP_ACQUISITION_CALL_HERE!! */
+									pcmuio_stop_intr
+										(dev,
+										s);
+								}
+
+								/* Check for end of acquisition. */
+								if (!subpriv->
+									intr.
+									continuous)
+								{
+									/* stop_src == TRIG_COUNT */
+									if (subpriv->intr.stop_count > 0) {
+										subpriv->
+											intr.
+											stop_count--;
+										if (subpriv->intr.stop_count == 0) {
+											s->async->events |= COMEDI_CB_EOA;
+											/* TODO: STOP_ACQUISITION_CALL_HERE!! */
+											pcmuio_stop_intr
+												(dev,
+												s);
+										}
+									}
+								}
+							}
+						}
+
+						comedi_spin_unlock_irqrestore
+							(&subpriv->intr.
+							spinlock, flags);
+
+						if (oldevents !=
+							s->async->events) {
+							comedi_event(dev, s);
+						}
+
+					}
+
+				}
+			}
+
+		}
+	}
+	if (!got1)
+		return IRQ_NONE;	/* interrupt from other source */
+	return IRQ_HANDLED;
+}
+
+static void pcmuio_stop_intr(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	int nports, firstport, asic, port;
+
+	if ((asic = subpriv->intr.asic) < 0)
+		return;		/* not an interrupt subdev */
+
+	subpriv->intr.enabled_mask = 0;
+	subpriv->intr.active = 0;
+	s->async->inttrig = 0;
+	nports = subpriv->intr.num_asic_chans / CHANS_PER_PORT;
+	firstport = subpriv->intr.asic_chan / CHANS_PER_PORT;
+	switch_page(dev, asic, PAGE_ENAB);
+	for (port = firstport; port < firstport + nports; ++port) {
+		/* disable all intrs for this subdev.. */
+		outb(0, devpriv->asics[asic].iobase + REG_ENAB0 + port);
+	}
+}
+
+static int pcmuio_start_intr(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	if (!subpriv->intr.continuous && subpriv->intr.stop_count == 0) {
+		/* An empty acquisition! */
+		s->async->events |= COMEDI_CB_EOA;
+		subpriv->intr.active = 0;
+		return 1;
+	} else {
+		unsigned bits = 0, pol_bits = 0, n;
+		int nports, firstport, asic, port;
+		struct comedi_cmd *cmd = &s->async->cmd;
+
+		if ((asic = subpriv->intr.asic) < 0)
+			return 1;	/* not an interrupt
+					   subdev */
+		subpriv->intr.enabled_mask = 0;
+		subpriv->intr.active = 1;
+		nports = subpriv->intr.num_asic_chans / CHANS_PER_PORT;
+		firstport = subpriv->intr.asic_chan / CHANS_PER_PORT;
+		if (cmd->chanlist) {
+			for (n = 0; n < cmd->chanlist_len; n++) {
+				bits |= (1U << CR_CHAN(cmd->chanlist[n]));
+				pol_bits |= (CR_AREF(cmd->chanlist[n])
+					|| CR_RANGE(cmd->chanlist[n]) ? 1U : 0U)
+					<< CR_CHAN(cmd->chanlist[n]);
+			}
+		}
+		bits &= ((0x1 << subpriv->intr.num_asic_chans) -
+			1) << subpriv->intr.first_chan;
+		subpriv->intr.enabled_mask = bits;
+
+		switch_page(dev, asic, PAGE_ENAB);
+		for (port = firstport; port < firstport + nports; ++port) {
+			unsigned enab =
+				bits >> (subpriv->intr.first_chan + (port -
+					firstport) * 8) & 0xff, pol =
+				pol_bits >> (subpriv->intr.first_chan + (port -
+					firstport) * 8) & 0xff;
+			/* set enab intrs for this subdev.. */
+			outb(enab,
+				devpriv->asics[asic].iobase + REG_ENAB0 + port);
+			switch_page(dev, asic, PAGE_POL);
+			outb(pol,
+				devpriv->asics[asic].iobase + REG_ENAB0 + port);
+		}
+	}
+	return 0;
+}
+
+static int pcmuio_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	unsigned long flags;
+
+	comedi_spin_lock_irqsave(&subpriv->intr.spinlock, flags);
+	if (subpriv->intr.active)
+		pcmuio_stop_intr(dev, s);
+	comedi_spin_unlock_irqrestore(&subpriv->intr.spinlock, flags);
+
+	return 0;
+}
+
+/*
+ * Internal trigger function to start acquisition for an 'INTERRUPT' subdevice.
+ */
+static int
+pcmuio_inttrig_start_intr(struct comedi_device * dev, struct comedi_subdevice * s,
+	unsigned int trignum)
+{
+	unsigned long flags;
+	int event = 0;
+
+	if (trignum != 0)
+		return -EINVAL;
+
+	comedi_spin_lock_irqsave(&subpriv->intr.spinlock, flags);
+	s->async->inttrig = 0;
+	if (subpriv->intr.active) {
+		event = pcmuio_start_intr(dev, s);
+	}
+	comedi_spin_unlock_irqrestore(&subpriv->intr.spinlock, flags);
+
+	if (event) {
+		comedi_event(dev, s);
+	}
+
+	return 1;
+}
+
+/*
+ * 'do_cmd' function for an 'INTERRUPT' subdevice.
+ */
+static int pcmuio_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned long flags;
+	int event = 0;
+
+	comedi_spin_lock_irqsave(&subpriv->intr.spinlock, flags);
+	subpriv->intr.active = 1;
+
+	/* Set up end of acquisition. */
+	switch (cmd->stop_src) {
+	case TRIG_COUNT:
+		subpriv->intr.continuous = 0;
+		subpriv->intr.stop_count = cmd->stop_arg;
+		break;
+	default:
+		/* TRIG_NONE */
+		subpriv->intr.continuous = 1;
+		subpriv->intr.stop_count = 0;
+		break;
+	}
+
+	/* Set up start of acquisition. */
+	switch (cmd->start_src) {
+	case TRIG_INT:
+		s->async->inttrig = pcmuio_inttrig_start_intr;
+		break;
+	default:
+		/* TRIG_NOW */
+		event = pcmuio_start_intr(dev, s);
+		break;
+	}
+	comedi_spin_unlock_irqrestore(&subpriv->intr.spinlock, flags);
+
+	if (event) {
+		comedi_event(dev, s);
+	}
+
+	return 0;
+}
+
+/*
+ * 'do_cmdtest' function for an 'INTERRUPT' subdevice.
+ */
+static int
+pcmuio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s, struct comedi_cmd * cmd)
+{
+	int err = 0;
+	unsigned int tmp;
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= (TRIG_NOW | TRIG_INT);
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_EXT;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_NOW;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= (TRIG_COUNT | TRIG_NONE);
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	/* these tests are true if more than one _src bit is set */
+	if ((cmd->start_src & (cmd->start_src - 1)) != 0)
+		err++;
+	if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
+		err++;
+	if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
+		err++;
+	if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
+		err++;
+	if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	/* cmd->start_src == TRIG_NOW || cmd->start_src == TRIG_INT */
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+
+	/* cmd->scan_begin_src == TRIG_EXT */
+	if (cmd->scan_begin_arg != 0) {
+		cmd->scan_begin_arg = 0;
+		err++;
+	}
+
+	/* cmd->convert_src == TRIG_NOW */
+	if (cmd->convert_arg != 0) {
+		cmd->convert_arg = 0;
+		err++;
+	}
+
+	/* cmd->scan_end_src == TRIG_COUNT */
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+
+	switch (cmd->stop_src) {
+	case TRIG_COUNT:
+		/* any count allowed */
+		break;
+	case TRIG_NONE:
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+		break;
+	default:
+		break;
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	/* if (err) return 4; */
+
+	return 0;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver);
diff --git a/drivers/staging/comedi/drivers/plx9052.h b/drivers/staging/comedi/drivers/plx9052.h
new file mode 100644
index 0000000..5894739
--- /dev/null
+++ b/drivers/staging/comedi/drivers/plx9052.h
@@ -0,0 +1,86 @@
+/*
+    comedi/drivers/plx9052.h
+    Definitions for the PLX-9052 PCI interface chip
+
+    Copyright (C) 2002 MEV Ltd. <http://www.mev.co.uk/>
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000 David A. Schleef <ds@schleef.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.
+
+    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 _PLX9052_H_
+#define _PLX9052_H_
+
+/*
+ * PLX PCI9052 INTCSR register.
+ */
+#define PLX9052_INTCSR	0x4C	/* Offset in Local Configuration Registers */
+/* Local Interrupt 1 Enable */
+#define PLX9052_INTCSR_LI1ENAB_MASK		0x0001
+#define PLX9052_INTCSR_LI1ENAB_DISABLED		0x0000
+#define PLX9052_INTCSR_LI1ENAB_ENABLED		0x0001
+/* Local Interrupt 1 Polarity */
+#define PLX9052_INTCSR_LI1POL_MASK		0x0002
+#define PLX9052_INTCSR_LI1POL_LOW		0x0000
+#define PLX9052_INTCSR_LI1POL_HIGH		0x0002
+/* Local Interrupt 1 Status (read-only) */
+#define PLX9052_INTCSR_LI1STAT_MASK		0x0004
+#define PLX9052_INTCSR_LI1STAT_INACTIVE		0x0000
+#define PLX9052_INTCSR_LI1STAT_ACTIVE		0x0004
+/* Local Interrupt 2 Enable */
+#define PLX9052_INTCSR_LI2ENAB_MASK		0x0008
+#define PLX9052_INTCSR_LI2ENAB_DISABLED		0x0000
+#define PLX9052_INTCSR_LI2ENAB_ENABLED		0x0008
+/* Local Interrupt 2 Polarity */
+#define PLX9052_INTCSR_LI2POL_MASK		0x0010
+#define PLX9052_INTCSR_LI2POL_LOW		0x0000
+#define PLX9052_INTCSR_LI2POL_HIGH		0x0010
+/* Local Interrupt 2 Status (read-only) */
+#define PLX9052_INTCSR_LI2STAT_MASK		0x0020
+#define PLX9052_INTCSR_LI2STAT_INACTIVE		0x0000
+#define PLX9052_INTCSR_LI2STAT_ACTIVE		0x0020
+/* PCI Interrupt Enable */
+#define PLX9052_INTCSR_PCIENAB_MASK		0x0040
+#define PLX9052_INTCSR_PCIENAB_DISABLED		0x0000
+#define PLX9052_INTCSR_PCIENAB_ENABLED		0x0040
+/* Software Interrupt */
+#define PLX9052_INTCSR_SOFTINT_MASK		0x0080
+#define PLX9052_INTCSR_SOFTINT_UNASSERTED	0x0000
+#define PLX9052_INTCSR_SOFTINT_ASSERTED		0x0080
+/* Local Interrupt 1 Select Enable */
+#define PLX9052_INTCSR_LI1SEL_MASK		0x0100
+#define PLX9052_INTCSR_LI1SEL_LEVEL		0x0000
+#define PLX9052_INTCSR_LI1SEL_EDGE		0x0100
+/* Local Interrupt 2 Select Enable */
+#define PLX9052_INTCSR_LI2SEL_MASK		0x0200
+#define PLX9052_INTCSR_LI2SEL_LEVEL		0x0000
+#define PLX9052_INTCSR_LI2SEL_EDGE		0x0200
+/* Local Edge Triggerable Interrupt 1 Clear Bit */
+#define PLX9052_INTCSR_LI1CLRINT_MASK		0x0400
+#define PLX9052_INTCSR_LI1CLRINT_UNASSERTED	0x0000
+#define PLX9052_INTCSR_LI1CLRINT_ASSERTED	0x0400
+/* Local Edge Triggerable Interrupt 2 Clear Bit */
+#define PLX9052_INTCSR_LI2CLRINT_MASK		0x0800
+#define PLX9052_INTCSR_LI2CLRINT_UNASSERTED	0x0000
+#define PLX9052_INTCSR_LI2CLRINT_ASSERTED	0x0800
+/* ISA Interface Mode Enable (read-only over PCI bus) */
+#define PLX9052_INTCSR_ISAMODE_MASK		0x1000
+#define PLX9052_INTCSR_ISAMODE_DISABLED		0x0000
+#define PLX9052_INTCSR_ISAMODE_ENABLED		0x1000
+
+#endif /* _PLX9052_H_ */
diff --git a/drivers/staging/comedi/drivers/plx9080.h b/drivers/staging/comedi/drivers/plx9080.h
index a5a1a68..9231ba8 100644
--- a/drivers/staging/comedi/drivers/plx9080.h
+++ b/drivers/staging/comedi/drivers/plx9080.h
@@ -27,7 +27,7 @@
 #ifndef __COMEDI_PLX9080_H
 #define __COMEDI_PLX9080_H
 
-// descriptor block used for chained dma transfers
+/*  descriptor block used for chained dma transfers */
 struct plx_dma_desc {
 	volatile uint32_t pci_start_addr;
 	volatile uint32_t local_start_addr;
@@ -52,14 +52,14 @@
 #define  LRNG_ANY32        0x00000000	/* Locate anywhere in 32 bit */
 #define  LRNG_LT1MB        0x00000002	/* Locate in 1st meg */
 #define  LRNG_ANY64        0x00000004	/* Locate anywhere in 64 bit */
-#define  LRNG_MEM_MASK     0xfffffff0	// bits that specify range for memory io
-#define  LRNG_IO_MASK     0xfffffffa	// bits that specify range for normal io
+#define  LRNG_MEM_MASK     0xfffffff0	/*  bits that specify range for memory io */
+#define  LRNG_IO_MASK     0xfffffffa	/*  bits that specify range for normal io */
 
 #define PLX_LAS0MAP_REG         0x0004	/* L, Local Addr Space 0 Remap Register */
 #define PLX_LAS1MAP_REG         0x00f4	/* L, Local Addr Space 1 Remap Register */
 #define  LMAP_EN           0x00000001	/* Enable slave decode */
-#define  LMAP_MEM_MASK     0xfffffff0	// bits that specify decode for memory io
-#define  LMAP_IO_MASK     0xfffffffa	// bits that specify decode bits for normal io
+#define  LMAP_MEM_MASK     0xfffffff0	/*  bits that specify decode for memory io */
+#define  LMAP_IO_MASK     0xfffffffa	/*  bits that specify decode bits for normal io */
 
 /* Mode/Arbitration Register.
 */
@@ -169,7 +169,7 @@
 #define  ICS_AERR          0x00000001	/* Assert LSERR on ABORT */
 #define  ICS_PERR          0x00000002	/* Assert LSERR on Parity Error */
 #define  ICS_SERR          0x00000004	/* Generate PCI SERR# */
-#define  ICS_MBIE          0x00000008	// mailbox interrupt enable
+#define  ICS_MBIE          0x00000008	/*  mailbox interrupt enable */
 #define  ICS_PIE           0x00000100	/* PCI Interrupt Enable */
 #define  ICS_PDIE          0x00000200	/* PCI Doorbell Interrupt Enable */
 #define  ICS_PAIE          0x00000400	/* PCI Abort Interrupt Enable */
@@ -190,7 +190,7 @@
 #define  ICS_TA_DMA0       0x02000000	/* Target Abort - DMA #0 */
 #define  ICS_TA_DMA1       0x04000000	/* Target Abort - DMA #1 */
 #define  ICS_TA_RA         0x08000000	/* Target Abort - Retry Timeout */
-#define  ICS_MBIA(x)       (0x10000000 << ((x) & 0x3))	// mailbox x is active
+#define  ICS_MBIA(x)       (0x10000000 << ((x) & 0x3))	/*  mailbox x is active */
 
 #define PLX_CONTROL_REG        0x006C	/* L, EEPROM Cntl & PCI Cmd Codes */
 #define  CTL_RDMA          0x0000000E	/* DMA Read Command */
@@ -208,51 +208,51 @@
 #define  CTL_RESET         0x40000000	/* !! Adapter Reset !! */
 #define  CTL_READY         0x80000000	/* Local Init Done */
 
-#define PLX_ID_REG	0x70	// hard-coded plx vendor and device ids
+#define PLX_ID_REG	0x70	/*  hard-coded plx vendor and device ids */
 
-#define PLX_REVISION_REG	0x74	// silicon revision
+#define PLX_REVISION_REG	0x74	/*  silicon revision */
 
-#define PLX_DMA0_MODE_REG	0x80	// dma channel 0 mode register
-#define PLX_DMA1_MODE_REG	0x94	// dma channel 0 mode register
+#define PLX_DMA0_MODE_REG	0x80	/*  dma channel 0 mode register */
+#define PLX_DMA1_MODE_REG	0x94	/*  dma channel 0 mode register */
 #define  PLX_LOCAL_BUS_16_WIDE_BITS	0x1
 #define  PLX_LOCAL_BUS_32_WIDE_BITS	0x3
 #define  PLX_LOCAL_BUS_WIDTH_MASK	0x3
-#define  PLX_DMA_EN_READYIN_BIT	0x40	// enable ready in input
-#define  PLX_EN_BTERM_BIT	0x80	// enable BTERM# input
-#define  PLX_DMA_LOCAL_BURST_EN_BIT	0x100	// enable local burst mode
-#define  PLX_EN_CHAIN_BIT	0x200	// enables chaining
-#define  PLX_EN_DMA_DONE_INTR_BIT	0x400	// enables interrupt on dma done
-#define  PLX_LOCAL_ADDR_CONST_BIT	0x800	// hold local address constant (don't increment)
-#define  PLX_DEMAND_MODE_BIT	0x1000	// enables demand-mode for dma transfer
+#define  PLX_DMA_EN_READYIN_BIT	0x40	/*  enable ready in input */
+#define  PLX_EN_BTERM_BIT	0x80	/*  enable BTERM# input */
+#define  PLX_DMA_LOCAL_BURST_EN_BIT	0x100	/*  enable local burst mode */
+#define  PLX_EN_CHAIN_BIT	0x200	/*  enables chaining */
+#define  PLX_EN_DMA_DONE_INTR_BIT	0x400	/*  enables interrupt on dma done */
+#define  PLX_LOCAL_ADDR_CONST_BIT	0x800	/*  hold local address constant (don't increment) */
+#define  PLX_DEMAND_MODE_BIT	0x1000	/*  enables demand-mode for dma transfer */
 #define  PLX_EOT_ENABLE_BIT	0x4000
 #define  PLX_STOP_MODE_BIT 0x8000
-#define  PLX_DMA_INTR_PCI_BIT	0x20000	// routes dma interrupt to pci bus (instead of local bus)
+#define  PLX_DMA_INTR_PCI_BIT	0x20000	/*  routes dma interrupt to pci bus (instead of local bus) */
 
-#define PLX_DMA0_PCI_ADDRESS_REG	0x84	// pci address that dma transfers start at
+#define PLX_DMA0_PCI_ADDRESS_REG	0x84	/*  pci address that dma transfers start at */
 #define PLX_DMA1_PCI_ADDRESS_REG	0x98
 
-#define PLX_DMA0_LOCAL_ADDRESS_REG	0x88	// local address that dma transfers start at
+#define PLX_DMA0_LOCAL_ADDRESS_REG	0x88	/*  local address that dma transfers start at */
 #define PLX_DMA1_LOCAL_ADDRESS_REG	0x9c
 
-#define PLX_DMA0_TRANSFER_SIZE_REG	0x8c	// number of bytes to transfer (first 23 bits)
+#define PLX_DMA0_TRANSFER_SIZE_REG	0x8c	/*  number of bytes to transfer (first 23 bits) */
 #define PLX_DMA1_TRANSFER_SIZE_REG	0xa0
 
-#define PLX_DMA0_DESCRIPTOR_REG	0x90	// descriptor pointer register
+#define PLX_DMA0_DESCRIPTOR_REG	0x90	/*  descriptor pointer register */
 #define PLX_DMA1_DESCRIPTOR_REG	0xa4
-#define  PLX_DESC_IN_PCI_BIT	0x1	// descriptor is located in pci space (not local space)
-#define  PLX_END_OF_CHAIN_BIT	0x2	// end of chain bit
-#define  PLX_INTR_TERM_COUNT	0x4	// interrupt when this descriptor's transfer is finished
-#define  PLX_XFER_LOCAL_TO_PCI 0x8	// transfer from local to pci bus (not pci to local)
+#define  PLX_DESC_IN_PCI_BIT	0x1	/*  descriptor is located in pci space (not local space) */
+#define  PLX_END_OF_CHAIN_BIT	0x2	/*  end of chain bit */
+#define  PLX_INTR_TERM_COUNT	0x4	/*  interrupt when this descriptor's transfer is finished */
+#define  PLX_XFER_LOCAL_TO_PCI 0x8	/*  transfer from local to pci bus (not pci to local) */
 
-#define PLX_DMA0_CS_REG	0xa8	// command status register
+#define PLX_DMA0_CS_REG	0xa8	/*  command status register */
 #define PLX_DMA1_CS_REG	0xa9
-#define  PLX_DMA_EN_BIT	0x1	// enable dma channel
-#define  PLX_DMA_START_BIT	0x2	// start dma transfer
-#define  PLX_DMA_ABORT_BIT	0x4	// abort dma transfer
-#define  PLX_CLEAR_DMA_INTR_BIT	0x8	// clear dma interrupt
-#define  PLX_DMA_DONE_BIT	0x10	// transfer done status bit
+#define  PLX_DMA_EN_BIT	0x1	/*  enable dma channel */
+#define  PLX_DMA_START_BIT	0x2	/*  start dma transfer */
+#define  PLX_DMA_ABORT_BIT	0x4	/*  abort dma transfer */
+#define  PLX_CLEAR_DMA_INTR_BIT	0x8	/*  clear dma interrupt */
+#define  PLX_DMA_DONE_BIT	0x10	/*  transfer done status bit */
 
-#define PLX_DMA0_THRESHOLD_REG	0xb0	// command status register
+#define PLX_DMA0_THRESHOLD_REG	0xb0	/*  command status register */
 
 /*
  * Accesses near the end of memory can cause the PLX chip
@@ -392,12 +392,12 @@
 	else
 		dma_cs_addr = iobase + PLX_DMA0_CS_REG;
 
-	// abort dma transfer if necessary
+	/*  abort dma transfer if necessary */
 	dma_status = readb(dma_cs_addr);
-	if ((dma_status & PLX_DMA_EN_BIT) == 0) {
+	if ((dma_status & PLX_DMA_EN_BIT) == 0)
 		return 0;
-	}
-	// wait to make sure done bit is zero
+
+	/*  wait to make sure done bit is zero */
 	for (i = 0; (dma_status & PLX_DMA_DONE_BIT) && i < timeout; i++) {
 		comedi_udelay(1);
 		dma_status = readb(dma_cs_addr);
@@ -408,9 +408,9 @@
 			channel);
 		return -ETIMEDOUT;
 	}
-	// disable and abort channel
+	/*  disable and abort channel */
 	writeb(PLX_DMA_ABORT_BIT, dma_cs_addr);
-	// wait for dma done bit
+	/*  wait for dma done bit */
 	dma_status = readb(dma_cs_addr);
 	for (i = 0; (dma_status & PLX_DMA_DONE_BIT) == 0 && i < timeout; i++) {
 		comedi_udelay(1);
diff --git a/drivers/staging/comedi/drivers/poc.c b/drivers/staging/comedi/drivers/poc.c
new file mode 100644
index 0000000..8a0bf68
--- /dev/null
+++ b/drivers/staging/comedi/drivers/poc.c
@@ -0,0 +1,247 @@
+/*
+    comedi/drivers/poc.c
+    Mini-drivers for POC (Piece of Crap) boards
+    Copyright (C) 2000 Frank Mori Hess <fmhess@users.sourceforge.net>
+    Copyright (C) 2001 David A. Schleef <ds@schleef.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.
+
+    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.
+*/
+/*
+Driver: poc
+Description: Generic driver for very simple devices
+Author: ds
+Devices: [Keithley Metrabyte] DAC-02 (dac02), [Advantech] PCL-733 (pcl733),
+  PCL-734 (pcl734)
+Updated: Sat, 16 Mar 2002 17:34:48 -0800
+Status: unknown
+
+This driver is indended to support very simple ISA-based devices,
+including:
+  dac02 - Keithley DAC-02 analog output board
+  pcl733 - Advantech PCL-733
+  pcl734 - Advantech PCL-734
+
+Configuration options:
+  [0] - I/O port base
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+static int poc_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int poc_detach(struct comedi_device * dev);
+static int readback_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+static int dac02_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int pcl733_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int pcl734_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+struct boarddef_struct {
+	const char *name;
+	unsigned int iosize;
+	int (*setup) (struct comedi_device *);
+	int type;
+	int n_chan;
+	int n_bits;
+	int (*winsn) (struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+		unsigned int *);
+	int (*rinsn) (struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+		unsigned int *);
+	int (*insnbits) (struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+		unsigned int *);
+	const struct comedi_lrange *range;
+};
+static const struct boarddef_struct boards[] = {
+	{
+	      name:	"dac02",
+	      iosize:	8,
+			//setup:                dac02_setup,
+	      type:	COMEDI_SUBD_AO,
+	      n_chan:	2,
+	      n_bits:	12,
+	      winsn:	dac02_ao_winsn,
+	      rinsn:	readback_insn,
+	      range:	&range_unknown,
+		},
+	{
+	      name:	"pcl733",
+	      iosize:	4,
+	      type:	COMEDI_SUBD_DI,
+	      n_chan:	32,
+	      n_bits:	1,
+	      insnbits:pcl733_insn_bits,
+	      range:	&range_digital,
+		},
+	{
+	      name:	"pcl734",
+	      iosize:	4,
+	      type:	COMEDI_SUBD_DO,
+	      n_chan:	32,
+	      n_bits:	1,
+	      insnbits:pcl734_insn_bits,
+	      range:	&range_digital,
+		},
+};
+
+#define n_boards (sizeof(boards)/sizeof(boards[0]))
+#define this_board ((const struct boarddef_struct *)dev->board_ptr)
+
+static struct comedi_driver driver_poc = {
+      driver_name:"poc",
+      module:THIS_MODULE,
+      attach:poc_attach,
+      detach:poc_detach,
+      board_name:&boards[0].name,
+      num_names:n_boards,
+      offset:sizeof(boards[0]),
+};
+
+static int poc_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	unsigned long iobase;
+	unsigned int iosize;
+
+	iobase = it->options[0];
+	printk("comedi%d: poc: using %s iobase 0x%lx\n", dev->minor,
+		this_board->name, iobase);
+
+	dev->board_name = this_board->name;
+
+	if (iobase == 0) {
+		printk("io base address required\n");
+		return -EINVAL;
+	}
+
+	iosize = this_board->iosize;
+	/* check if io addresses are available */
+	if (!request_region(iobase, iosize, "dac02")) {
+		printk("I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", iobase, iobase + iosize - 1);
+		return -EIO;
+	}
+	dev->iobase = iobase;
+
+	if (alloc_subdevices(dev, 1) < 0)
+		return -ENOMEM;
+	if (alloc_private(dev, sizeof(unsigned int) * this_board->n_chan) < 0)
+		return -ENOMEM;
+
+	/* analog output subdevice */
+	s = dev->subdevices + 0;
+	s->type = this_board->type;
+	s->n_chan = this_board->n_chan;
+	s->maxdata = (1 << this_board->n_bits) - 1;
+	s->range_table = this_board->range;
+	s->insn_write = this_board->winsn;
+	s->insn_read = this_board->rinsn;
+	s->insn_bits = this_board->insnbits;
+	if (s->type == COMEDI_SUBD_AO || s->type == COMEDI_SUBD_DO) {
+		s->subdev_flags = SDF_WRITABLE;
+	}
+
+	return 0;
+}
+
+static int poc_detach(struct comedi_device * dev)
+{
+	/* only free stuff if it has been allocated by _attach */
+	if (dev->iobase)
+		release_region(dev->iobase, this_board->iosize);
+
+	printk("comedi%d: dac02: remove\n", dev->minor);
+
+	return 0;
+}
+
+static int readback_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int chan;
+
+	chan = CR_CHAN(insn->chanspec);
+	data[0] = ((unsigned int *) dev->private)[chan];
+
+	return 1;
+}
+
+/* DAC-02 registers */
+#define DAC02_LSB(a)	(2 * a)
+#define DAC02_MSB(a)	(2 * a + 1)
+
+static int dac02_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int temp;
+	int chan;
+	int output;
+
+	chan = CR_CHAN(insn->chanspec);
+	((unsigned int *) dev->private)[chan] = data[0];
+	output = data[0];
+#ifdef wrong
+	// convert to complementary binary if range is bipolar
+	if ((CR_RANGE(insn->chanspec) & 0x2) == 0)
+		output = ~output;
+#endif
+	temp = (output << 4) & 0xf0;
+	outb(temp, dev->iobase + DAC02_LSB(chan));
+	temp = (output >> 4) & 0xff;
+	outb(temp, dev->iobase + DAC02_MSB(chan));
+
+	return 1;
+}
+
+static int pcl733_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	data[1] = inb(dev->iobase + 0);
+	data[1] |= (inb(dev->iobase + 1) << 8);
+	data[1] |= (inb(dev->iobase + 2) << 16);
+	data[1] |= (inb(dev->iobase + 3) << 24);
+
+	return 2;
+}
+
+static int pcl734_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= (data[0] & data[1]);
+		if ((data[0] >> 0) & 0xff)
+			outb((s->state >> 0) & 0xff, dev->iobase + 0);
+		if ((data[0] >> 8) & 0xff)
+			outb((s->state >> 8) & 0xff, dev->iobase + 1);
+		if ((data[0] >> 16) & 0xff)
+			outb((s->state >> 16) & 0xff, dev->iobase + 2);
+		if ((data[0] >> 24) & 0xff)
+			outb((s->state >> 24) & 0xff, dev->iobase + 3);
+	}
+	data[1] = s->state;
+
+	return 2;
+}
+
+COMEDI_INITCLEANUP(driver_poc);
diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
new file mode 100644
index 0000000..795c452
--- /dev/null
+++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
@@ -0,0 +1,1363 @@
+/*======================================================================
+
+    comedi/drivers/quatech_daqp_cs.c
+
+    Quatech DAQP PCMCIA data capture cards COMEDI client driver
+    Copyright (C) 2000, 2003 Brent Baccala <baccala@freesoft.org>
+    The DAQP interface code in this file is released into the public domain.
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+    http://www.comedi.org/
+
+    quatech_daqp_cs.c 1.10
+
+    Documentation for the DAQP PCMCIA cards can be found on Quatech's site:
+
+                ftp://ftp.quatech.com/Manuals/daqp-208.pdf
+
+    This manual is for both the DAQP-208 and the DAQP-308.
+
+    What works:
+
+	- A/D conversion
+	    - 8 channels
+	    - 4 gain ranges
+	    - ground ref or differential
+	    - single-shot and timed both supported
+	- D/A conversion, single-shot
+	- digital I/O
+
+    What doesn't:
+
+	- any kind of triggering - external or D/A channel 1
+	- the card's optional expansion board
+	- the card's timer (for anything other than A/D conversion)
+	- D/A update modes other than immediate (i.e, timed)
+	- fancier timing modes
+	- setting card's FIFO buffer thresholds to anything but default
+
+======================================================================*/
+
+/*
+Driver: quatech_daqp_cs
+Description: Quatech DAQP PCMCIA data capture cards
+Author: Brent Baccala <baccala@freesoft.org>
+Status: works
+Devices: [Quatech] DAQP-208 (daqp), DAQP-308
+*/
+
+#include "../comedidev.h"
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ds.h>
+
+/*
+   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
+   you do not define PCMCIA_DEBUG at all, all the debug code will be
+   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
+   be present but disabled -- but it can then be enabled for specific
+   modules at load time with a 'pc_debug=#' option to insmod.
+*/
+
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+module_param(pc_debug, int, 0644);
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+static char *version = "quatech_daqp_cs.c 1.10 2003/04/21 (Brent Baccala)";
+#else
+#define DEBUG(n, args...)
+#endif
+
+/* Maximum number of separate DAQP devices we'll allow */
+#define MAX_DEV         4
+
+struct local_info_t {
+	struct pcmcia_device *link;
+	dev_node_t node;
+	int stop;
+	int table_index;
+	char board_name[32];
+
+	enum { semaphore, buffer } interrupt_mode;
+
+	struct semaphore eos;
+
+	struct comedi_device *dev;
+	struct comedi_subdevice *s;
+	int count;
+};
+
+/* A list of "instances" of the device. */
+
+static struct local_info_t *dev_table[MAX_DEV] = { NULL, /* ... */  };
+
+/* The DAQP communicates with the system through a 16 byte I/O window. */
+
+#define DAQP_FIFO_SIZE		4096
+
+#define DAQP_FIFO		0
+#define DAQP_SCANLIST		1
+#define DAQP_CONTROL		2
+#define DAQP_STATUS		2
+#define DAQP_DIGITAL_IO		3
+#define DAQP_PACER_LOW		4
+#define DAQP_PACER_MID		5
+#define DAQP_PACER_HIGH		6
+#define DAQP_COMMAND		7
+#define DAQP_DA			8
+#define DAQP_TIMER		10
+#define DAQP_AUX		15
+
+#define DAQP_SCANLIST_DIFFERENTIAL	0x4000
+#define DAQP_SCANLIST_GAIN(x)		((x)<<12)
+#define DAQP_SCANLIST_CHANNEL(x)	((x)<<8)
+#define DAQP_SCANLIST_START		0x0080
+#define DAQP_SCANLIST_EXT_GAIN(x)	((x)<<4)
+#define DAQP_SCANLIST_EXT_CHANNEL(x)	(x)
+
+#define DAQP_CONTROL_PACER_100kHz	0xc0
+#define DAQP_CONTROL_PACER_1MHz		0x80
+#define DAQP_CONTROL_PACER_5MHz		0x40
+#define DAQP_CONTROL_PACER_EXTERNAL	0x00
+#define DAQP_CONTORL_EXPANSION		0x20
+#define DAQP_CONTROL_EOS_INT_ENABLE	0x10
+#define DAQP_CONTROL_FIFO_INT_ENABLE	0x08
+#define DAQP_CONTROL_TRIGGER_ONESHOT	0x00
+#define DAQP_CONTROL_TRIGGER_CONTINUOUS	0x04
+#define DAQP_CONTROL_TRIGGER_INTERNAL	0x00
+#define DAQP_CONTROL_TRIGGER_EXTERNAL	0x02
+#define DAQP_CONTROL_TRIGGER_RISING	0x00
+#define DAQP_CONTROL_TRIGGER_FALLING	0x01
+
+#define DAQP_STATUS_IDLE		0x80
+#define DAQP_STATUS_RUNNING		0x40
+#define DAQP_STATUS_EVENTS		0x38
+#define DAQP_STATUS_DATA_LOST		0x20
+#define DAQP_STATUS_END_OF_SCAN		0x10
+#define DAQP_STATUS_FIFO_THRESHOLD	0x08
+#define DAQP_STATUS_FIFO_FULL		0x04
+#define DAQP_STATUS_FIFO_NEARFULL	0x02
+#define DAQP_STATUS_FIFO_EMPTY		0x01
+
+#define DAQP_COMMAND_ARM		0x80
+#define DAQP_COMMAND_RSTF		0x40
+#define DAQP_COMMAND_RSTQ		0x20
+#define DAQP_COMMAND_STOP		0x10
+#define DAQP_COMMAND_LATCH		0x08
+#define DAQP_COMMAND_100kHz		0x00
+#define DAQP_COMMAND_50kHz		0x02
+#define DAQP_COMMAND_25kHz		0x04
+#define DAQP_COMMAND_FIFO_DATA		0x01
+#define DAQP_COMMAND_FIFO_PROGRAM	0x00
+
+#define DAQP_AUX_TRIGGER_TTL		0x00
+#define DAQP_AUX_TRIGGER_ANALOG		0x80
+#define DAQP_AUX_TRIGGER_PRETRIGGER	0x40
+#define DAQP_AUX_TIMER_INT_ENABLE	0x20
+#define DAQP_AUX_TIMER_RELOAD		0x00
+#define DAQP_AUX_TIMER_PAUSE		0x08
+#define DAQP_AUX_TIMER_GO		0x10
+#define DAQP_AUX_TIMER_GO_EXTERNAL	0x18
+#define DAQP_AUX_TIMER_EXTERNAL_SRC	0x04
+#define DAQP_AUX_TIMER_INTERNAL_SRC	0x00
+#define DAQP_AUX_DA_DIRECT		0x00
+#define DAQP_AUX_DA_OVERFLOW		0x01
+#define DAQP_AUX_DA_EXTERNAL		0x02
+#define DAQP_AUX_DA_PACER		0x03
+
+#define DAQP_AUX_RUNNING		0x80
+#define DAQP_AUX_TRIGGERED		0x40
+#define DAQP_AUX_DA_BUFFER		0x20
+#define DAQP_AUX_TIMER_OVERFLOW		0x10
+#define DAQP_AUX_CONVERSION		0x08
+#define DAQP_AUX_DATA_LOST		0x04
+#define DAQP_AUX_FIFO_NEARFULL		0x02
+#define DAQP_AUX_FIFO_EMPTY		0x01
+
+/* These range structures tell COMEDI how the sample values map to
+ * voltages.  The A/D converter has four ranges: +/- 10V through
+ * +/- 1.25V, and the D/A converter has only one: +/- 5V.
+ */
+
+static const struct comedi_lrange range_daqp_ai = { 4, {
+			BIP_RANGE(10),
+			BIP_RANGE(5),
+			BIP_RANGE(2.5),
+			BIP_RANGE(1.25)
+	}
+};
+
+static const struct comedi_lrange range_daqp_ao = { 1, {BIP_RANGE(5)} };
+
+/*====================================================================*/
+
+/* comedi interface code */
+
+static int daqp_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int daqp_detach(struct comedi_device * dev);
+static struct comedi_driver driver_daqp = {
+      driver_name:"quatech_daqp_cs",
+      module:THIS_MODULE,
+      attach:daqp_attach,
+      detach:daqp_detach,
+};
+
+#ifdef DAQP_DEBUG
+
+static void daqp_dump(struct comedi_device * dev)
+{
+	printk("DAQP: status %02x; aux status %02x\n",
+		inb(dev->iobase + DAQP_STATUS), inb(dev->iobase + DAQP_AUX));
+}
+
+static void hex_dump(char *str, void *ptr, int len)
+{
+	unsigned char *cptr = ptr;
+	int i;
+
+	printk(str);
+
+	for (i = 0; i < len; i++) {
+		if (i % 16 == 0) {
+			printk("\n0x%08x:", (unsigned int)cptr);
+		}
+		printk(" %02x", *(cptr++));
+	}
+	printk("\n");
+}
+
+#endif
+
+/* Cancel a running acquisition */
+
+static int daqp_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct local_info_t *local = (struct local_info_t *) s->private;
+
+	if (local->stop) {
+		return -EIO;
+	}
+
+	outb(DAQP_COMMAND_STOP, dev->iobase + DAQP_COMMAND);
+
+	/* flush any linguring data in FIFO - superfluous here */
+	/* outb(DAQP_COMMAND_RSTF, dev->iobase+DAQP_COMMAND); */
+
+	local->interrupt_mode = semaphore;
+
+	return 0;
+}
+
+/* Interrupt handler
+ *
+ * Operates in one of two modes.  If local->interrupt_mode is
+ * 'semaphore', just signal the local->eos semaphore and return
+ * (one-shot mode).  Otherwise (continuous mode), read data in from
+ * the card, transfer it to the buffer provided by the higher-level
+ * comedi kernel module, and signal various comedi callback routines,
+ * which run pretty quick.
+ */
+
+static void daqp_interrupt(int irq, void *dev_id PT_REGS_ARG)
+{
+	struct local_info_t *local = (struct local_info_t *) dev_id;
+	struct comedi_device *dev;
+	struct comedi_subdevice *s;
+	int loop_limit = 10000;
+	int status;
+
+	if (local == NULL) {
+		printk(KERN_WARNING
+			"daqp_interrupt(): irq %d for unknown device.\n", irq);
+		return;
+	}
+
+	dev = local->dev;
+	if (dev == NULL) {
+		printk(KERN_WARNING "daqp_interrupt(): NULL comedi_device.\n");
+		return;
+	}
+
+	if (!dev->attached) {
+		printk(KERN_WARNING
+			"daqp_interrupt(): struct comedi_device not yet attached.\n");
+		return;
+	}
+
+	s = local->s;
+	if (s == NULL) {
+		printk(KERN_WARNING
+			"daqp_interrupt(): NULL comedi_subdevice.\n");
+		return;
+	}
+
+	if ((struct local_info_t *) s->private != local) {
+		printk(KERN_WARNING
+			"daqp_interrupt(): invalid comedi_subdevice.\n");
+		return;
+	}
+
+	switch (local->interrupt_mode) {
+
+	case semaphore:
+
+		up(&local->eos);
+		break;
+
+	case buffer:
+
+		while (!((status = inb(dev->iobase + DAQP_STATUS))
+				& DAQP_STATUS_FIFO_EMPTY)) {
+
+			short data;
+
+			if (status & DAQP_STATUS_DATA_LOST) {
+				s->async->events |=
+					COMEDI_CB_EOA | COMEDI_CB_OVERFLOW;
+				printk("daqp: data lost\n");
+				daqp_ai_cancel(dev, s);
+				break;
+			}
+
+			data = inb(dev->iobase + DAQP_FIFO);
+			data |= inb(dev->iobase + DAQP_FIFO) << 8;
+			data ^= 0x8000;
+
+			comedi_buf_put(s->async, data);
+
+			/* If there's a limit, decrement it
+			 * and stop conversion if zero
+			 */
+
+			if (local->count > 0) {
+				local->count--;
+				if (local->count == 0) {
+					daqp_ai_cancel(dev, s);
+					s->async->events |= COMEDI_CB_EOA;
+					break;
+				}
+			}
+
+			if ((loop_limit--) <= 0)
+				break;
+		}
+
+		if (loop_limit <= 0) {
+			printk(KERN_WARNING
+				"loop_limit reached in daqp_interrupt()\n");
+			daqp_ai_cancel(dev, s);
+			s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+		}
+
+		s->async->events |= COMEDI_CB_BLOCK;
+
+		comedi_event(dev, s);
+	}
+}
+
+/* One-shot analog data acquisition routine */
+
+static int daqp_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	struct local_info_t *local = (struct local_info_t *) s->private;
+	int i;
+	int v;
+	int counter = 10000;
+
+	if (local->stop) {
+		return -EIO;
+	}
+
+	/* Stop any running conversion */
+	daqp_ai_cancel(dev, s);
+
+	outb(0, dev->iobase + DAQP_AUX);
+
+	/* Reset scan list queue */
+	outb(DAQP_COMMAND_RSTQ, dev->iobase + DAQP_COMMAND);
+
+	/* Program one scan list entry */
+
+	v = DAQP_SCANLIST_CHANNEL(CR_CHAN(insn->chanspec))
+		| DAQP_SCANLIST_GAIN(CR_RANGE(insn->chanspec));
+
+	if (CR_AREF(insn->chanspec) == AREF_DIFF) {
+		v |= DAQP_SCANLIST_DIFFERENTIAL;
+	}
+
+	v |= DAQP_SCANLIST_START;
+
+	outb(v & 0xff, dev->iobase + DAQP_SCANLIST);
+	outb(v >> 8, dev->iobase + DAQP_SCANLIST);
+
+	/* Reset data FIFO (see page 28 of DAQP User's Manual) */
+
+	outb(DAQP_COMMAND_RSTF, dev->iobase + DAQP_COMMAND);
+
+	/* Set trigger */
+
+	v = DAQP_CONTROL_TRIGGER_ONESHOT | DAQP_CONTROL_TRIGGER_INTERNAL
+		| DAQP_CONTROL_PACER_100kHz | DAQP_CONTROL_EOS_INT_ENABLE;
+
+	outb(v, dev->iobase + DAQP_CONTROL);
+
+	/* Reset any pending interrupts (my card has a tendancy to require
+	 * require multiple reads on the status register to achieve this)
+	 */
+
+	while (--counter
+		&& (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) ;
+	if (!counter) {
+		printk("daqp: couldn't clear interrupts in status register\n");
+		return -1;
+	}
+
+	/* Make sure semaphore is blocked */
+	sema_init(&local->eos, 0);
+	local->interrupt_mode = semaphore;
+	local->dev = dev;
+	local->s = s;
+
+	for (i = 0; i < insn->n; i++) {
+
+		/* Start conversion */
+		outb(DAQP_COMMAND_ARM | DAQP_COMMAND_FIFO_DATA,
+			dev->iobase + DAQP_COMMAND);
+
+		/* Wait for interrupt service routine to unblock semaphore */
+		/* Maybe could use a timeout here, but it's interruptible */
+		if (down_interruptible(&local->eos))
+			return -EINTR;
+
+		data[i] = inb(dev->iobase + DAQP_FIFO);
+		data[i] |= inb(dev->iobase + DAQP_FIFO) << 8;
+		data[i] ^= 0x8000;
+	}
+
+	return insn->n;
+}
+
+/* This function converts ns nanoseconds to a counter value suitable
+ * for programming the device.  We always use the DAQP's 5 MHz clock,
+ * which with its 24-bit counter, allows values up to 84 seconds.
+ * Also, the function adjusts ns so that it cooresponds to the actual
+ * time that the device will use.
+ */
+
+static int daqp_ns_to_timer(unsigned int *ns, int round)
+{
+	int timer;
+
+	timer = *ns / 200;
+	*ns = timer * 200;
+
+	return timer;
+}
+
+/* cmdtest tests a particular command to see if it is valid.
+ * Using the cmdtest ioctl, a user can create a valid cmd
+ * and then have it executed by the cmd ioctl.
+ *
+ * cmdtest returns 1,2,3,4 or 0, depending on which tests
+ * the command passes.
+ */
+
+static int daqp_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp;
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_TIMER | TRIG_FOLLOW;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_TIMER | TRIG_NOW;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	/* note that mutual compatiblity is not an issue here */
+	if (cmd->scan_begin_src != TRIG_TIMER &&
+		cmd->scan_begin_src != TRIG_FOLLOW)
+		err++;
+	if (cmd->convert_src != TRIG_NOW && cmd->convert_src != TRIG_TIMER)
+		err++;
+	if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
+		err++;
+	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+#define MAX_SPEED	10000	/* 100 kHz - in nanoseconds */
+
+	if (cmd->scan_begin_src == TRIG_TIMER
+		&& cmd->scan_begin_arg < MAX_SPEED) {
+		cmd->scan_begin_arg = MAX_SPEED;
+		err++;
+	}
+
+	/* If both scan_begin and convert are both timer values, the only
+	 * way that can make sense is if the scan time is the number of
+	 * conversions times the convert time
+	 */
+
+	if (cmd->scan_begin_src == TRIG_TIMER && cmd->convert_src == TRIG_TIMER
+		&& cmd->scan_begin_arg !=
+		cmd->convert_arg * cmd->scan_end_arg) {
+		err++;
+	}
+
+	if (cmd->convert_src == TRIG_TIMER && cmd->convert_arg < MAX_SPEED) {
+		cmd->convert_arg = MAX_SPEED;
+		err++;
+	}
+
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+	if (cmd->stop_src == TRIG_COUNT) {
+		if (cmd->stop_arg > 0x00ffffff) {
+			cmd->stop_arg = 0x00ffffff;
+			err++;
+		}
+	} else {
+		/* TRIG_NONE */
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		tmp = cmd->scan_begin_arg;
+		daqp_ns_to_timer(&cmd->scan_begin_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+		if (tmp != cmd->scan_begin_arg)
+			err++;
+	}
+
+	if (cmd->convert_src == TRIG_TIMER) {
+		tmp = cmd->convert_arg;
+		daqp_ns_to_timer(&cmd->convert_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+		if (tmp != cmd->convert_arg)
+			err++;
+	}
+
+	if (err)
+		return 4;
+
+	return 0;
+}
+
+static int daqp_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+	struct local_info_t *local = (struct local_info_t *) s->private;
+	struct comedi_cmd *cmd = &s->async->cmd;
+	int counter = 100;
+	int scanlist_start_on_every_entry;
+	int threshold;
+
+	int i;
+	int v;
+
+	if (local->stop) {
+		return -EIO;
+	}
+
+	/* Stop any running conversion */
+	daqp_ai_cancel(dev, s);
+
+	outb(0, dev->iobase + DAQP_AUX);
+
+	/* Reset scan list queue */
+	outb(DAQP_COMMAND_RSTQ, dev->iobase + DAQP_COMMAND);
+
+	/* Program pacer clock
+	 *
+	 * There's two modes we can operate in.  If convert_src is
+	 * TRIG_TIMER, then convert_arg specifies the time between
+	 * each conversion, so we program the pacer clock to that
+	 * frequency and set the SCANLIST_START bit on every scanlist
+	 * entry.  Otherwise, convert_src is TRIG_NOW, which means
+	 * we want the fastest possible conversions, scan_begin_src
+	 * is TRIG_TIMER, and scan_begin_arg specifies the time between
+	 * each scan, so we program the pacer clock to this frequency
+	 * and only set the SCANLIST_START bit on the first entry.
+	 */
+
+	if (cmd->convert_src == TRIG_TIMER) {
+		int counter = daqp_ns_to_timer(&cmd->convert_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+		outb(counter & 0xff, dev->iobase + DAQP_PACER_LOW);
+		outb((counter >> 8) & 0xff, dev->iobase + DAQP_PACER_MID);
+		outb((counter >> 16) & 0xff, dev->iobase + DAQP_PACER_HIGH);
+		scanlist_start_on_every_entry = 1;
+	} else {
+		int counter = daqp_ns_to_timer(&cmd->scan_begin_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+		outb(counter & 0xff, dev->iobase + DAQP_PACER_LOW);
+		outb((counter >> 8) & 0xff, dev->iobase + DAQP_PACER_MID);
+		outb((counter >> 16) & 0xff, dev->iobase + DAQP_PACER_HIGH);
+		scanlist_start_on_every_entry = 0;
+	}
+
+	/* Program scan list */
+
+	for (i = 0; i < cmd->chanlist_len; i++) {
+
+		int chanspec = cmd->chanlist[i];
+
+		/* Program one scan list entry */
+
+		v = DAQP_SCANLIST_CHANNEL(CR_CHAN(chanspec))
+			| DAQP_SCANLIST_GAIN(CR_RANGE(chanspec));
+
+		if (CR_AREF(chanspec) == AREF_DIFF) {
+			v |= DAQP_SCANLIST_DIFFERENTIAL;
+		}
+
+		if (i == 0 || scanlist_start_on_every_entry) {
+			v |= DAQP_SCANLIST_START;
+		}
+
+		outb(v & 0xff, dev->iobase + DAQP_SCANLIST);
+		outb(v >> 8, dev->iobase + DAQP_SCANLIST);
+	}
+
+	/* Now it's time to program the FIFO threshold, basically the
+	 * number of samples the card will buffer before it interrupts
+	 * the CPU.
+	 *
+	 * If we don't have a stop count, then use half the size of
+	 * the FIFO (the manufacturer's recommendation).  Consider
+	 * that the FIFO can hold 2K samples (4K bytes).  With the
+	 * threshold set at half the FIFO size, we have a margin of
+	 * error of 1024 samples.  At the chip's maximum sample rate
+	 * of 100,000 Hz, the CPU would have to delay interrupt
+	 * service for a full 10 milliseconds in order to lose data
+	 * here (as opposed to higher up in the kernel).  I've never
+	 * seen it happen.  However, for slow sample rates it may
+	 * buffer too much data and introduce too much delay for the
+	 * user application.
+	 *
+	 * If we have a stop count, then things get more interesting.
+	 * If the stop count is less than the FIFO size (actually
+	 * three-quarters of the FIFO size - see below), we just use
+	 * the stop count itself as the threshold, the card interrupts
+	 * us when that many samples have been taken, and we kill the
+	 * acquisition at that point and are done.  If the stop count
+	 * is larger than that, then we divide it by 2 until it's less
+	 * than three quarters of the FIFO size (we always leave the
+	 * top quarter of the FIFO as protection against sluggish CPU
+	 * interrupt response) and use that as the threshold.  So, if
+	 * the stop count is 4000 samples, we divide by two twice to
+	 * get 1000 samples, use that as the threshold, take four
+	 * interrupts to get our 4000 samples and are done.
+	 *
+	 * The algorithm could be more clever.  For example, if 81000
+	 * samples are requested, we could set the threshold to 1500
+	 * samples and take 54 interrupts to get 81000.  But 54 isn't
+	 * a power of two, so this algorithm won't find that option.
+	 * Instead, it'll set the threshold at 1266 and take 64
+	 * interrupts to get 81024 samples, of which the last 24 will
+	 * be discarded... but we won't get the last interrupt until
+	 * they've been collected.  To find the first option, the
+	 * computer could look at the prime decomposition of the
+	 * sample count (81000 = 3^4 * 5^3 * 2^3) and factor it into a
+	 * threshold (1500 = 3 * 5^3 * 2^2) and an interrupt count (54
+	 * = 3^3 * 2).  Hmmm... a one-line while loop or prime
+	 * decomposition of integers... I'll leave it the way it is.
+	 *
+	 * I'll also note a mini-race condition before ignoring it in
+	 * the code.  Let's say we're taking 4000 samples, as before.
+	 * After 1000 samples, we get an interrupt.  But before that
+	 * interrupt is completely serviced, another sample is taken
+	 * and loaded into the FIFO.  Since the interrupt handler
+	 * empties the FIFO before returning, it will read 1001 samples.
+	 * If that happens four times, we'll end up taking 4004 samples,
+	 * not 4000.  The interrupt handler will discard the extra four
+	 * samples (by halting the acquisition with four samples still
+	 * in the FIFO), but we will have to wait for them.
+	 *
+	 * In short, this code works pretty well, but for either of
+	 * the two reasons noted, might end up waiting for a few more
+	 * samples than actually requested.  Shouldn't make too much
+	 * of a difference.
+	 */
+
+	/* Save away the number of conversions we should perform, and
+	 * compute the FIFO threshold (in bytes, not samples - that's
+	 * why we multiple local->count by 2 = sizeof(sample))
+	 */
+
+	if (cmd->stop_src == TRIG_COUNT) {
+		local->count = cmd->stop_arg * cmd->scan_end_arg;
+		threshold = 2 * local->count;
+		while (threshold > DAQP_FIFO_SIZE * 3 / 4)
+			threshold /= 2;
+	} else {
+		local->count = -1;
+		threshold = DAQP_FIFO_SIZE / 2;
+	}
+
+	/* Reset data FIFO (see page 28 of DAQP User's Manual) */
+
+	outb(DAQP_COMMAND_RSTF, dev->iobase + DAQP_COMMAND);
+
+	/* Set FIFO threshold.  First two bytes are near-empty
+	 * threshold, which is unused; next two bytes are near-full
+	 * threshold.  We computed the number of bytes we want in the
+	 * FIFO when the interrupt is generated, what the card wants
+	 * is actually the number of available bytes left in the FIFO
+	 * when the interrupt is to happen.
+	 */
+
+	outb(0x00, dev->iobase + DAQP_FIFO);
+	outb(0x00, dev->iobase + DAQP_FIFO);
+
+	outb((DAQP_FIFO_SIZE - threshold) & 0xff, dev->iobase + DAQP_FIFO);
+	outb((DAQP_FIFO_SIZE - threshold) >> 8, dev->iobase + DAQP_FIFO);
+
+	/* Set trigger */
+
+	v = DAQP_CONTROL_TRIGGER_CONTINUOUS | DAQP_CONTROL_TRIGGER_INTERNAL
+		| DAQP_CONTROL_PACER_5MHz | DAQP_CONTROL_FIFO_INT_ENABLE;
+
+	outb(v, dev->iobase + DAQP_CONTROL);
+
+	/* Reset any pending interrupts (my card has a tendancy to require
+	 * require multiple reads on the status register to achieve this)
+	 */
+
+	while (--counter
+		&& (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) ;
+	if (!counter) {
+		printk("daqp: couldn't clear interrupts in status register\n");
+		return -1;
+	}
+
+	local->interrupt_mode = buffer;
+	local->dev = dev;
+	local->s = s;
+
+	/* Start conversion */
+	outb(DAQP_COMMAND_ARM | DAQP_COMMAND_FIFO_DATA,
+		dev->iobase + DAQP_COMMAND);
+
+	return 0;
+}
+
+/* Single-shot analog output routine */
+
+static int daqp_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	struct local_info_t *local = (struct local_info_t *) s->private;
+	int d;
+	unsigned int chan;
+
+	if (local->stop) {
+		return -EIO;
+	}
+
+	chan = CR_CHAN(insn->chanspec);
+	d = data[0];
+	d &= 0x0fff;
+	d ^= 0x0800;		/* Flip the sign */
+	d |= chan << 12;
+
+	/* Make sure D/A update mode is direct update */
+	outb(0, dev->iobase + DAQP_AUX);
+
+	outw(d, dev->iobase + DAQP_DA);
+
+	return 1;
+}
+
+/* Digital input routine */
+
+static int daqp_di_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	struct local_info_t *local = (struct local_info_t *) s->private;
+
+	if (local->stop) {
+		return -EIO;
+	}
+
+	data[0] = inb(dev->iobase + DAQP_DIGITAL_IO);
+
+	return 1;
+}
+
+/* Digital output routine */
+
+static int daqp_do_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	struct local_info_t *local = (struct local_info_t *) s->private;
+
+	if (local->stop) {
+		return -EIO;
+	}
+
+	outw(data[0] & 0xf, dev->iobase + DAQP_DIGITAL_IO);
+
+	return 1;
+}
+
+/* daqp_attach is called via comedi_config to attach a comedi device
+ * to a /dev/comedi*.  Note that this is different from daqp_cs_attach()
+ * which is called by the pcmcia subsystem to attach the PCMCIA card
+ * when it is inserted.
+ */
+
+static int daqp_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	int ret;
+	struct local_info_t *local = dev_table[it->options[0]];
+	tuple_t tuple;
+	int i;
+	struct comedi_subdevice *s;
+
+	if (it->options[0] < 0 || it->options[0] >= MAX_DEV || !local) {
+		printk("comedi%d: No such daqp device %d\n",
+			dev->minor, it->options[0]);
+		return -EIO;
+	}
+
+	/* Typically brittle code that I don't completely understand,
+	 * but "it works on my card".  The intent is to pull the model
+	 * number of the card out the PCMCIA CIS and stash it away as
+	 * the COMEDI board_name.  Looks like the third field in
+	 * CISTPL_VERS_1 (offset 2) holds what we're looking for.  If
+	 * it doesn't work, who cares, just leave it as "DAQP".
+	 */
+
+	strcpy(local->board_name, "DAQP");
+	dev->board_name = local->board_name;
+
+	tuple.DesiredTuple = CISTPL_VERS_1;
+	if (pcmcia_get_first_tuple(local->link, &tuple) == 0) {
+		u_char buf[128];
+
+		buf[0] = buf[sizeof(buf) - 1] = 0;
+		tuple.TupleData = buf;
+		tuple.TupleDataMax = sizeof(buf);
+		tuple.TupleOffset = 2;
+		if (pcmcia_get_tuple_data(local->link, &tuple) == 0) {
+
+			for (i = 0; i < tuple.TupleDataLen - 4; i++)
+				if (buf[i] == 0)
+					break;
+			for (i++; i < tuple.TupleDataLen - 4; i++)
+				if (buf[i] == 0)
+					break;
+			i++;
+			if ((i < tuple.TupleDataLen - 4)
+				&& (strncmp(buf + i, "DAQP", 4) == 0)) {
+				strncpy(local->board_name, buf + i,
+					sizeof(local->board_name));
+			}
+		}
+	}
+
+	dev->iobase = local->link->io.BasePort1;
+
+	if ((ret = alloc_subdevices(dev, 4)) < 0)
+		return ret;
+
+	printk("comedi%d: attaching daqp%d (io 0x%04lx)\n",
+		dev->minor, it->options[0], dev->iobase);
+
+	s = dev->subdevices + 0;
+	dev->read_subdev = s;
+	s->private = local;
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
+	s->n_chan = 8;
+	s->len_chanlist = 2048;
+	s->maxdata = 0xffff;
+	s->range_table = &range_daqp_ai;
+	s->insn_read = daqp_ai_insn_read;
+	s->do_cmdtest = daqp_ai_cmdtest;
+	s->do_cmd = daqp_ai_cmd;
+	s->cancel = daqp_ai_cancel;
+
+	s = dev->subdevices + 1;
+	dev->write_subdev = s;
+	s->private = local;
+	s->type = COMEDI_SUBD_AO;
+	s->subdev_flags = SDF_WRITEABLE;
+	s->n_chan = 2;
+	s->len_chanlist = 1;
+	s->maxdata = 0x0fff;
+	s->range_table = &range_daqp_ao;
+	s->insn_write = daqp_ao_insn_write;
+
+	s = dev->subdevices + 2;
+	s->private = local;
+	s->type = COMEDI_SUBD_DI;
+	s->subdev_flags = SDF_READABLE;
+	s->n_chan = 1;
+	s->len_chanlist = 1;
+	s->insn_read = daqp_di_insn_read;
+
+	s = dev->subdevices + 3;
+	s->private = local;
+	s->type = COMEDI_SUBD_DO;
+	s->subdev_flags = SDF_WRITEABLE;
+	s->n_chan = 1;
+	s->len_chanlist = 1;
+	s->insn_write = daqp_do_insn_write;
+
+	return 1;
+}
+
+/* daqp_detach (called from comedi_comdig) does nothing. If the PCMCIA
+ * card is removed, daqp_cs_detach() is called by the pcmcia subsystem.
+ */
+
+static int daqp_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: detaching daqp\n", dev->minor);
+
+	return 0;
+}
+
+/*====================================================================
+
+    PCMCIA interface code
+
+    The rest of the code in this file is based on dummy_cs.c v1.24
+    from the Linux pcmcia_cs distribution v3.1.8 and is subject
+    to the following license agreement.
+
+    The remaining contents of this file are subject to the Mozilla Public
+    License Version 1.1 (the "License"); you may not use this file
+    except in compliance with the License. You may obtain a copy of
+    the License at http://www.mozilla.org/MPL/
+
+    Software distributed under the License is distributed on an "AS
+    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+    implied. See the License for the specific language governing
+    rights and limitations under the License.
+
+    The initial developer of the original code is David A. Hinds
+    <dhinds@pcmcia.sourceforge.org>.  Portions created by David A. Hinds
+    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
+
+    Alternatively, the contents of this file may be used under the
+    terms of the GNU Public License version 2 (the "GPL"), in which
+    case the provisions of the GPL are applicable instead of the
+    above.  If you wish to allow the use of your version of this file
+    only under the terms of the GPL and not to allow others to use
+    your version of this file under the MPL, indicate your decision
+    by deleting the provisions above and replace them with the notice
+    and other provisions required by the GPL.  If you do not delete
+    the provisions above, a recipient may use your version of this
+    file under either the MPL or the GPL.
+
+======================================================================*/
+
+/*
+   The event() function is this driver's Card Services event handler.
+   It will be called by Card Services when an appropriate card status
+   event is received.  The config() and release() entry points are
+   used to configure or release a socket, in response to card
+   insertion and ejection events.
+
+   Kernel version 2.6.16 upwards uses suspend() and resume() functions
+   instead of an event() function.
+*/
+
+static void daqp_cs_config(struct pcmcia_device *link);
+static void daqp_cs_release(struct pcmcia_device *link);
+static int daqp_cs_suspend(struct pcmcia_device *p_dev);
+static int daqp_cs_resume(struct pcmcia_device *p_dev);
+
+/*
+   The attach() and detach() entry points are used to create and destroy
+   "instances" of the driver, where each instance represents everything
+   needed to manage one actual PCMCIA card.
+*/
+
+static int daqp_cs_attach(struct pcmcia_device *);
+static void daqp_cs_detach(struct pcmcia_device *);
+
+/*
+   The dev_info variable is the "key" that is used to match up this
+   device driver with appropriate cards, through the card configuration
+   database.
+*/
+
+static const dev_info_t dev_info = "quatech_daqp_cs";
+
+/*======================================================================
+
+    daqp_cs_attach() creates an "instance" of the driver, allocating
+    local data structures for one device.  The device is registered
+    with Card Services.
+
+    The dev_link structure is initialized, but we don't actually
+    configure the card at this point -- we wait until we receive a
+    card insertion event.
+
+======================================================================*/
+
+static int daqp_cs_attach(struct pcmcia_device *link)
+{
+	struct local_info_t *local;
+	int i;
+
+	DEBUG(0, "daqp_cs_attach()\n");
+
+	for (i = 0; i < MAX_DEV; i++)
+		if (dev_table[i] == NULL)
+			break;
+	if (i == MAX_DEV) {
+		printk(KERN_NOTICE "daqp_cs: no devices available\n");
+		return -ENODEV;
+	}
+
+	/* Allocate space for private device-specific data */
+	local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
+	if (!local)
+		return -ENOMEM;
+
+	local->table_index = i;
+	dev_table[i] = local;
+	local->link = link;
+	link->priv = local;
+
+	/* Interrupt setup */
+	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+	link->irq.Handler = daqp_interrupt;
+	link->irq.Instance = local;
+
+	/*
+	   General socket configuration defaults can go here.  In this
+	   client, we assume very little, and rely on the CIS for almost
+	   everything.  In most clients, many details (i.e., number, sizes,
+	   and attributes of IO windows) are fixed by the nature of the
+	   device, and can be hard-wired here.
+	 */
+	link->conf.Attributes = 0;
+	link->conf.IntType = INT_MEMORY_AND_IO;
+
+	daqp_cs_config(link);
+
+	return 0;
+}				/* daqp_cs_attach */
+
+/*======================================================================
+
+    This deletes a driver "instance".  The device is de-registered
+    with Card Services.  If it has been released, all local data
+    structures are freed.  Otherwise, the structures will be freed
+    when the device is released.
+
+======================================================================*/
+
+static void daqp_cs_detach(struct pcmcia_device *link)
+{
+	struct local_info_t *dev = link->priv;
+
+	DEBUG(0, "daqp_cs_detach(0x%p)\n", link);
+
+	if (link->dev_node) {
+		dev->stop = 1;
+		daqp_cs_release(link);
+	}
+
+	/* Unlink device structure, and free it */
+	dev_table[dev->table_index] = NULL;
+	if (dev)
+		kfree(dev);
+
+}				/* daqp_cs_detach */
+
+/*======================================================================
+
+    daqp_cs_config() is scheduled to run after a CARD_INSERTION event
+    is received, to configure the PCMCIA socket, and to make the
+    device available to the system.
+
+======================================================================*/
+
+static void daqp_cs_config(struct pcmcia_device *link)
+{
+	struct local_info_t *dev = link->priv;
+	tuple_t tuple;
+	cisparse_t parse;
+	int last_ret;
+	u_char buf[64];
+
+	DEBUG(0, "daqp_cs_config(0x%p)\n", link);
+
+	/*
+	   This reads the card's CONFIG tuple to find its configuration
+	   registers.
+	 */
+	tuple.DesiredTuple = CISTPL_CONFIG;
+	tuple.Attributes = 0;
+	tuple.TupleData = buf;
+	tuple.TupleDataMax = sizeof(buf);
+	tuple.TupleOffset = 0;
+	if ((last_ret = pcmcia_get_first_tuple(link, &tuple))) {
+		cs_error(link, GetFirstTuple, last_ret);
+		goto cs_failed;
+	}
+	if ((last_ret = pcmcia_get_tuple_data(link, &tuple))) {
+		cs_error(link, GetTupleData, last_ret);
+		goto cs_failed;
+	}
+	if ((last_ret = pcmcia_parse_tuple(&tuple, &parse))) {
+		cs_error(link, ParseTuple, last_ret);
+		goto cs_failed;
+	}
+	link->conf.ConfigBase = parse.config.base;
+	link->conf.Present = parse.config.rmask[0];
+
+	/*
+	   In this loop, we scan the CIS for configuration table entries,
+	   each of which describes a valid card configuration, including
+	   voltage, IO window, memory window, and interrupt settings.
+
+	   We make no assumptions about the card to be configured: we use
+	   just the information available in the CIS.  In an ideal world,
+	   this would work for any PCMCIA card, but it requires a complete
+	   and accurate CIS.  In practice, a driver usually "knows" most of
+	   these things without consulting the CIS, and most client drivers
+	   will only use the CIS to fill in implementation-defined details.
+	 */
+	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+	if ((last_ret = pcmcia_get_first_tuple(link, &tuple))) {
+		cs_error(link, GetFirstTuple, last_ret);
+		goto cs_failed;
+	}
+	while (1) {
+		cistpl_cftable_entry_t dflt = { 0 };
+		cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+		if (pcmcia_get_tuple_data(link, &tuple))
+			goto next_entry;
+		if (pcmcia_parse_tuple(&tuple, &parse))
+			goto next_entry;
+
+		if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+			dflt = *cfg;
+		if (cfg->index == 0)
+			goto next_entry;
+		link->conf.ConfigIndex = cfg->index;
+
+		/* Do we need to allocate an interrupt? */
+		if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
+			link->conf.Attributes |= CONF_ENABLE_IRQ;
+
+		/* IO window settings */
+		link->io.NumPorts1 = link->io.NumPorts2 = 0;
+		if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+			cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+			link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+			if (!(io->flags & CISTPL_IO_8BIT))
+				link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+			if (!(io->flags & CISTPL_IO_16BIT))
+				link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+			link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+			link->io.BasePort1 = io->win[0].base;
+			link->io.NumPorts1 = io->win[0].len;
+			if (io->nwin > 1) {
+				link->io.Attributes2 = link->io.Attributes1;
+				link->io.BasePort2 = io->win[1].base;
+				link->io.NumPorts2 = io->win[1].len;
+			}
+		}
+
+		/* This reserves IO space but doesn't actually enable it */
+		if (pcmcia_request_io(link, &link->io))
+			goto next_entry;
+
+		/* If we got this far, we're cool! */
+		break;
+
+	      next_entry:
+		if ((last_ret = pcmcia_get_next_tuple(link, &tuple))) {
+			cs_error(link, GetNextTuple, last_ret);
+			goto cs_failed;
+		}
+	}
+
+	/*
+	   Allocate an interrupt line.  Note that this does not assign a
+	   handler to the interrupt, unless the 'Handler' member of the
+	   irq structure is initialized.
+	 */
+	if (link->conf.Attributes & CONF_ENABLE_IRQ)
+		if ((last_ret = pcmcia_request_irq(link, &link->irq))) {
+			cs_error(link, RequestIRQ, last_ret);
+			goto cs_failed;
+		}
+
+	/*
+	   This actually configures the PCMCIA socket -- setting up
+	   the I/O windows and the interrupt mapping, and putting the
+	   card and host interface into "Memory and IO" mode.
+	 */
+	if ((last_ret = pcmcia_request_configuration(link, &link->conf))) {
+		cs_error(link, RequestConfiguration, last_ret);
+		goto cs_failed;
+	}
+
+	/*
+	   At this point, the dev_node_t structure(s) need to be
+	   initialized and arranged in a linked list at link->dev.
+	 */
+	/* Comedi's PCMCIA script uses this device name (extracted
+	 * from /var/lib/pcmcia/stab) to pass to comedi_config
+	 */
+	/* sprintf(dev->node.dev_name, "daqp%d", dev->table_index); */
+	sprintf(dev->node.dev_name, "quatech_daqp_cs");
+	dev->node.major = dev->node.minor = 0;
+	link->dev_node = &dev->node;
+
+	/* Finally, report what we've done */
+	printk(KERN_INFO "%s: index 0x%02x",
+		dev->node.dev_name, link->conf.ConfigIndex);
+	if (link->conf.Attributes & CONF_ENABLE_IRQ)
+		printk(", irq %u", link->irq.AssignedIRQ);
+	if (link->io.NumPorts1)
+		printk(", io 0x%04x-0x%04x", link->io.BasePort1,
+			link->io.BasePort1 + link->io.NumPorts1 - 1);
+	if (link->io.NumPorts2)
+		printk(" & 0x%04x-0x%04x", link->io.BasePort2,
+			link->io.BasePort2 + link->io.NumPorts2 - 1);
+	printk("\n");
+
+	return;
+
+      cs_failed:
+	daqp_cs_release(link);
+
+}				/* daqp_cs_config */
+
+static void daqp_cs_release(struct pcmcia_device *link)
+{
+	DEBUG(0, "daqp_cs_release(0x%p)\n", link);
+
+	pcmcia_disable_device(link);
+}				/* daqp_cs_release */
+
+/*======================================================================
+
+    The card status event handler.  Mostly, this schedules other
+    stuff to run after an event is received.
+
+    When a CARD_REMOVAL event is received, we immediately set a
+    private flag to block future accesses to this device.  All the
+    functions that actually access the device should check this flag
+    to make sure the card is still present.
+
+======================================================================*/
+
+static int daqp_cs_suspend(struct pcmcia_device *link)
+{
+	struct local_info_t *local = link->priv;
+
+	/* Mark the device as stopped, to block IO until later */
+	local->stop = 1;
+	return 0;
+}
+
+static int daqp_cs_resume(struct pcmcia_device *link)
+{
+	struct local_info_t *local = link->priv;
+
+	local->stop = 0;
+
+	return 0;
+}
+
+/*====================================================================*/
+
+#ifdef MODULE
+
+static struct pcmcia_device_id daqp_cs_id_table[] = {
+	PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0027),
+	PCMCIA_DEVICE_NULL
+};
+
+MODULE_DEVICE_TABLE(pcmcia, daqp_cs_id_table);
+
+struct pcmcia_driver daqp_cs_driver = {
+	.probe = daqp_cs_attach,
+	.remove = daqp_cs_detach,
+	.suspend = daqp_cs_suspend,
+	.resume = daqp_cs_resume,
+	.id_table = daqp_cs_id_table,
+	.owner = THIS_MODULE,
+	.drv = {
+			.name = dev_info,
+		},
+};
+
+int __init init_module(void)
+{
+	DEBUG(0, "%s\n", version);
+	pcmcia_register_driver(&daqp_cs_driver);
+	comedi_driver_register(&driver_daqp);
+	return 0;
+}
+
+void __exit cleanup_module(void)
+{
+	DEBUG(0, "daqp_cs: unloading\n");
+	comedi_driver_unregister(&driver_daqp);
+	pcmcia_unregister_driver(&daqp_cs_driver);
+}
+
+#endif
diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c
index 65d5242..ca347f2 100644
--- a/drivers/staging/comedi/drivers/rtd520.c
+++ b/drivers/staging/comedi/drivers/rtd520.c
@@ -196,7 +196,7 @@
 /*
   The board has 3 input modes and the gains of 1,2,4,...32 (, 64, 128)
 */
-static const comedi_lrange rtd_ai_7520_range = { 18, {
+static const struct comedi_lrange rtd_ai_7520_range = { 18, {
 			/* +-5V input range gain steps */
 			BIP_RANGE(5.0),
 			BIP_RANGE(5.0 / 2),
@@ -223,7 +223,7 @@
 };
 
 /* PCI4520 has two more gains (6 more entries) */
-static const comedi_lrange rtd_ai_4520_range = { 24, {
+static const struct comedi_lrange rtd_ai_4520_range = { 24, {
 			/* +-5V input range gain steps */
 			BIP_RANGE(5.0),
 			BIP_RANGE(5.0 / 2),
@@ -255,7 +255,7 @@
 };
 
 /* Table order matches range values */
-static const comedi_lrange rtd_ao_range = { 4, {
+static const struct comedi_lrange rtd_ao_range = { 4, {
 			RANGE(0, 5),
 			RANGE(0, 10),
 			RANGE(-5, 5),
@@ -266,7 +266,7 @@
 /*
   Board descriptions
  */
-typedef struct rtdBoard_struct {
+struct rtdBoard {
 	const char *name;	/* must be first */
 	int device_id;
 	int aiChans;
@@ -274,12 +274,12 @@
 	int aiMaxGain;
 	int range10Start;	/* start of +-10V range */
 	int rangeUniStart;	/* start of +10V range */
-} rtdBoard;
+};
 
-static const rtdBoard rtd520Boards[] = {
+static const struct rtdBoard rtd520Boards[] = {
 	{
 	      name:	"DM7520",
-	      device_id:0x7520,
+	      device_id : 0x7520,
 	      aiChans:	16,
 	      aiBits:	12,
 	      aiMaxGain:32,
@@ -288,7 +288,7 @@
 		},
 	{
 	      name:	"PCI4520",
-	      device_id:0x4520,
+	      device_id : 0x4520,
 	      aiChans:	16,
 	      aiBits:	12,
 	      aiMaxGain:128,
@@ -308,13 +308,13 @@
 /*
  * Useful for shorthand access to the particular board structure
  */
-#define thisboard ((const rtdBoard *)dev->board_ptr)
+#define thisboard ((const struct rtdBoard *)dev->board_ptr)
 
 /*
    This structure is for data unique to this hardware driver.
    This is also unique for each board in the system.
 */
-typedef struct {
+struct rtdPrivate {
 	/* memory mapped board structures */
 	void *las0;
 	void *las1;
@@ -334,7 +334,7 @@
 	unsigned char chanBipolar[RTD_MAX_CHANLIST / 8];	/* bit array */
 
 	/* read back data */
-	lsampl_t aoValue[2];	/* Used for AO read back */
+	unsigned int aoValue[2];	/* Used for AO read back */
 
 	/* timer gate (when enabled) */
 	u8 utcGate[4];		/* 1 extra allows simple range check */
@@ -358,7 +358,7 @@
 	u8 dma1Control;
 #endif				/* USE_DMA */
 	unsigned fifoLen;
-} rtdPrivate;
+};
 
 /* bit defines for "flags" */
 #define SEND_EOS	0x01	/* send End Of Scan events */
@@ -366,18 +366,18 @@
 #define DMA1_ACTIVE	0x04	/* DMA1 is active */
 
 /* Macros for accessing channel list bit array */
-#define CHAN_ARRAY_TEST(array,index) \
+#define CHAN_ARRAY_TEST(array, index) \
 	(((array)[(index)/8] >> ((index) & 0x7)) & 0x1)
-#define CHAN_ARRAY_SET(array,index) \
+#define CHAN_ARRAY_SET(array, index) \
 	(((array)[(index)/8] |= 1 << ((index) & 0x7)))
-#define CHAN_ARRAY_CLEAR(array,index) \
+#define CHAN_ARRAY_CLEAR(array, index) \
 	(((array)[(index)/8] &= ~(1 << ((index) & 0x7))))
 
 /*
  * most drivers define the following macro to make it easy to
  * access the private structure.
  */
-#define devpriv ((rtdPrivate *)dev->private)
+#define devpriv ((struct rtdPrivate *)dev->private)
 
 /* Macros to access registers */
 
@@ -394,15 +394,15 @@
     writel (0, devpriv->las0+LAS0_CGT_CLEAR)
 
 /* Reset channel gain table read and write pointers */
-#define RtdEnableCGT(dev,v) \
+#define RtdEnableCGT(dev, v) \
     writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_CGT_ENABLE)
 
 /* Write channel gain table entry */
-#define RtdWriteCGTable(dev,v) \
+#define RtdWriteCGTable(dev, v) \
     writel (v, devpriv->las0+LAS0_CGT_WRITE)
 
 /* Write Channel Gain Latch */
-#define RtdWriteCGLatch(dev,v) \
+#define RtdWriteCGLatch(dev, v) \
     writel (v, devpriv->las0+LAS0_CGL_WRITE)
 
 /* Reset ADC FIFO */
@@ -410,39 +410,39 @@
     writel (0, devpriv->las0+LAS0_ADC_FIFO_CLEAR)
 
 /* Set ADC start conversion source select (write only) */
-#define RtdAdcConversionSource(dev,v) \
+#define RtdAdcConversionSource(dev, v) \
     writel (v, devpriv->las0+LAS0_ADC_CONVERSION)
 
 /* Set burst start source select (write only) */
-#define RtdBurstStartSource(dev,v) \
+#define RtdBurstStartSource(dev, v) \
     writel (v, devpriv->las0+LAS0_BURST_START)
 
 /* Set Pacer start source select (write only) */
-#define RtdPacerStartSource(dev,v) \
+#define RtdPacerStartSource(dev, v) \
     writel (v, devpriv->las0+LAS0_PACER_START)
 
 /* Set Pacer stop source select (write only) */
-#define RtdPacerStopSource(dev,v) \
+#define RtdPacerStopSource(dev, v) \
     writel (v, devpriv->las0+LAS0_PACER_STOP)
 
 /* Set Pacer clock source select (write only) 0=external 1=internal */
-#define RtdPacerClockSource(dev,v) \
+#define RtdPacerClockSource(dev, v) \
     writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_PACER_SELECT)
 
 /* Set sample counter source select (write only) */
-#define RtdAdcSampleCounterSource(dev,v) \
+#define RtdAdcSampleCounterSource(dev, v) \
     writel (v, devpriv->las0+LAS0_ADC_SCNT_SRC)
 
 /* Set Pacer trigger mode select (write only) 0=single cycle, 1=repeat */
-#define RtdPacerTriggerMode(dev,v) \
+#define RtdPacerTriggerMode(dev, v) \
     writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_PACER_REPEAT)
 
 /* Set About counter stop enable (write only) */
-#define RtdAboutStopEnable(dev,v) \
+#define RtdAboutStopEnable(dev, v) \
     writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_ACNT_STOP_ENABLE)
 
 /* Set external trigger polarity (write only) 0=positive edge, 1=negative */
-#define RtdTriggerPolarity(dev,v) \
+#define RtdTriggerPolarity(dev, v) \
     writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_ETRG_POLARITY)
 
 /* Start single ADC conversion */
@@ -473,15 +473,15 @@
     readw (devpriv->las0+LAS0_IT)
 
 /* Interrupt mask */
-#define RtdInterruptMask(dev,v) \
-    writew ((devpriv->intMask = (v)),devpriv->las0+LAS0_IT)
+#define RtdInterruptMask(dev, v) \
+    writew ((devpriv->intMask = (v)), devpriv->las0+LAS0_IT)
 
 /* Interrupt status clear (only bits set in mask) */
 #define RtdInterruptClear(dev) \
     readw (devpriv->las0+LAS0_CLEAR)
 
 /* Interrupt clear mask */
-#define RtdInterruptClearMask(dev,v) \
+#define RtdInterruptClearMask(dev, v) \
     writew ((devpriv->intClearMask = (v)), devpriv->las0+LAS0_CLEAR)
 
 /* Interrupt overrun status */
@@ -495,92 +495,92 @@
 /* Pacer counter, 24bit */
 #define RtdPacerCount(dev) \
     readl (devpriv->las0+LAS0_PCLK)
-#define RtdPacerCounter(dev,v) \
-    writel ((v) & 0xffffff,devpriv->las0+LAS0_PCLK)
+#define RtdPacerCounter(dev, v) \
+    writel ((v) & 0xffffff, devpriv->las0+LAS0_PCLK)
 
 /* Burst counter, 10bit */
 #define RtdBurstCount(dev) \
     readl (devpriv->las0+LAS0_BCLK)
-#define RtdBurstCounter(dev,v) \
-    writel ((v) & 0x3ff,devpriv->las0+LAS0_BCLK)
+#define RtdBurstCounter(dev, v) \
+    writel ((v) & 0x3ff, devpriv->las0+LAS0_BCLK)
 
 /* Delay counter, 16bit */
 #define RtdDelayCount(dev) \
     readl (devpriv->las0+LAS0_DCLK)
-#define RtdDelayCounter(dev,v) \
+#define RtdDelayCounter(dev, v) \
     writel ((v) & 0xffff, devpriv->las0+LAS0_DCLK)
 
 /* About counter, 16bit */
 #define RtdAboutCount(dev) \
     readl (devpriv->las0+LAS0_ACNT)
-#define RtdAboutCounter(dev,v) \
+#define RtdAboutCounter(dev, v) \
     writel ((v) & 0xffff, devpriv->las0+LAS0_ACNT)
 
 /* ADC sample counter, 10bit */
 #define RtdAdcSampleCount(dev) \
     readl (devpriv->las0+LAS0_ADC_SCNT)
-#define RtdAdcSampleCounter(dev,v) \
+#define RtdAdcSampleCounter(dev, v) \
     writel ((v) & 0x3ff, devpriv->las0+LAS0_ADC_SCNT)
 
 /* User Timer/Counter (8254) */
-#define RtdUtcCounterGet(dev,n) \
+#define RtdUtcCounterGet(dev, n) \
     readb (devpriv->las0 \
         + ((n <= 0) ? LAS0_UTC0 : ((1 == n) ? LAS0_UTC1 : LAS0_UTC2)))
 
-#define RtdUtcCounterPut(dev,n,v) \
+#define RtdUtcCounterPut(dev, n, v) \
     writeb ((v) & 0xff, devpriv->las0 \
         + ((n <= 0) ? LAS0_UTC0 : ((1 == n) ? LAS0_UTC1 : LAS0_UTC2)))
 
 /* Set UTC (8254) control byte  */
-#define RtdUtcCtrlPut(dev,n,v) \
+#define RtdUtcCtrlPut(dev, n, v) \
     writeb (devpriv->utcCtrl[(n) & 3] = (((n) & 3) << 6) | ((v) & 0x3f), \
       devpriv->las0 + LAS0_UTC_CTRL)
 
 /* Set UTCn clock source (write only) */
-#define RtdUtcClockSource(dev,n,v) \
+#define RtdUtcClockSource(dev, n, v) \
     writew (v, devpriv->las0 \
         + ((n <= 0) ? LAS0_UTC0_CLOCK : \
            ((1 == n) ? LAS0_UTC1_CLOCK : LAS0_UTC2_CLOCK)))
 
 /* Set UTCn gate source (write only) */
-#define RtdUtcGateSource(dev,n,v) \
+#define RtdUtcGateSource(dev, n, v) \
     writew (v, devpriv->las0 \
         + ((n <= 0) ? LAS0_UTC0_GATE : \
            ((1 == n) ? LAS0_UTC1_GATE : LAS0_UTC2_GATE)))
 
 /* User output N source select (write only) */
-#define RtdUsrOutSource(dev,n,v) \
-    writel (v,devpriv->las0+((n <= 0) ? LAS0_UOUT0_SELECT : LAS0_UOUT1_SELECT))
+#define RtdUsrOutSource(dev, n, v) \
+    writel (v, devpriv->las0+((n <= 0) ? LAS0_UOUT0_SELECT : LAS0_UOUT1_SELECT))
 
 /* Digital IO */
 #define RtdDio0Read(dev) \
     (readw (devpriv->las0+LAS0_DIO0) & 0xff)
-#define RtdDio0Write(dev,v) \
+#define RtdDio0Write(dev, v) \
     writew ((v) & 0xff, devpriv->las0+LAS0_DIO0)
 
 #define RtdDio1Read(dev) \
     (readw (devpriv->las0+LAS0_DIO1) & 0xff)
-#define RtdDio1Write(dev,v) \
+#define RtdDio1Write(dev, v) \
     writew ((v) & 0xff, devpriv->las0+LAS0_DIO1)
 
 #define RtdDioStatusRead(dev) \
     (readw (devpriv->las0+LAS0_DIO_STATUS) & 0xff)
-#define RtdDioStatusWrite(dev,v) \
+#define RtdDioStatusWrite(dev, v) \
     writew ((devpriv->dioStatus = (v)), devpriv->las0+LAS0_DIO_STATUS)
 
 #define RtdDio0CtrlRead(dev) \
     (readw (devpriv->las0+LAS0_DIO0_CTRL) & 0xff)
-#define RtdDio0CtrlWrite(dev,v) \
+#define RtdDio0CtrlWrite(dev, v) \
     writew ((v) & 0xff, devpriv->las0+LAS0_DIO0_CTRL)
 
 /* Digital to Analog converter */
 /* Write one data value (sign + 12bit + marker bits) */
 /* Note: matches what DMA would put.  Actual value << 3 */
-#define RtdDacFifoPut(dev,n,v) \
+#define RtdDacFifoPut(dev, n, v) \
     writew ((v), devpriv->las1 +(((n) == 0) ? LAS1_DAC1_FIFO : LAS1_DAC2_FIFO))
 
 /* Start single DAC conversion */
-#define RtdDacUpdate(dev,n) \
+#define RtdDacUpdate(dev, n) \
     writew (0, devpriv->las0 +(((n) == 0) ? LAS0_DAC1 : LAS0_DAC2))
 
 /* Start single DAC conversion on both DACs */
@@ -588,20 +588,20 @@
     writew (0, devpriv->las0+LAS0_DAC)
 
 /* Set DAC output type and range */
-#define RtdDacRange(dev,n,v) \
+#define RtdDacRange(dev, n, v) \
     writew ((v) & 7, devpriv->las0 \
 	+(((n) == 0) ? LAS0_DAC1_CTRL : LAS0_DAC2_CTRL))
 
 /* Reset DAC FIFO */
-#define RtdDacClearFifo(dev,n) \
+#define RtdDacClearFifo(dev, n) \
     writel (0, devpriv->las0+(((n) == 0) ? LAS0_DAC1_RESET : LAS0_DAC2_RESET))
 
 /* Set source for DMA 0 (write only, shadow?) */
-#define RtdDma0Source(dev,n) \
+#define RtdDma0Source(dev, n) \
     writel ((n) & 0xf, devpriv->las0+LAS0_DMA0_SRC)
 
 /* Set source for DMA 1 (write only, shadow?) */
-#define RtdDma1Source(dev,n) \
+#define RtdDma1Source(dev, n) \
     writel ((n) & 0xf, devpriv->las0+LAS0_DMA1_SRC)
 
 /* Reset board state for DMA 0 */
@@ -615,51 +615,51 @@
 /* PLX9080 interrupt mask and status */
 #define RtdPlxInterruptRead(dev) \
     readl (devpriv->lcfg+LCFG_ITCSR)
-#define RtdPlxInterruptWrite(dev,v) \
+#define RtdPlxInterruptWrite(dev, v) \
     writel (v, devpriv->lcfg+LCFG_ITCSR)
 
 /* Set  mode for DMA 0 */
-#define RtdDma0Mode(dev,m) \
+#define RtdDma0Mode(dev, m) \
     writel ((m), devpriv->lcfg+LCFG_DMAMODE0)
 
 /* Set PCI address for DMA 0 */
-#define RtdDma0PciAddr(dev,a) \
+#define RtdDma0PciAddr(dev, a) \
     writel ((a), devpriv->lcfg+LCFG_DMAPADR0)
 
 /* Set local address for DMA 0 */
-#define RtdDma0LocalAddr(dev,a) \
+#define RtdDma0LocalAddr(dev, a) \
     writel ((a), devpriv->lcfg+LCFG_DMALADR0)
 
 /* Set byte count for DMA 0 */
-#define RtdDma0Count(dev,c) \
+#define RtdDma0Count(dev, c) \
     writel ((c), devpriv->lcfg+LCFG_DMASIZ0)
 
 /* Set next descriptor for DMA 0 */
-#define RtdDma0Next(dev,a) \
+#define RtdDma0Next(dev, a) \
     writel ((a), devpriv->lcfg+LCFG_DMADPR0)
 
 /* Set  mode for DMA 1 */
-#define RtdDma1Mode(dev,m) \
+#define RtdDma1Mode(dev, m) \
     writel ((m), devpriv->lcfg+LCFG_DMAMODE1)
 
 /* Set PCI address for DMA 1 */
-#define RtdDma1PciAddr(dev,a) \
+#define RtdDma1PciAddr(dev, a) \
     writel ((a), devpriv->lcfg+LCFG_DMAADR1)
 
 /* Set local address for DMA 1 */
-#define RtdDma1LocalAddr(dev,a) \
+#define RtdDma1LocalAddr(dev, a) \
     writel ((a), devpriv->lcfg+LCFG_DMALADR1)
 
 /* Set byte count for DMA 1 */
-#define RtdDma1Count(dev,c) \
+#define RtdDma1Count(dev, c) \
     writel ((c), devpriv->lcfg+LCFG_DMASIZ1)
 
 /* Set next descriptor for DMA 1 */
-#define RtdDma1Next(dev,a) \
+#define RtdDma1Next(dev, a) \
     writel ((a), devpriv->lcfg+LCFG_DMADPR1)
 
 /* Set control for DMA 0 (write only, shadow?) */
-#define RtdDma0Control(dev,n) \
+#define RtdDma0Control(dev, n) \
     writeb (devpriv->dma0Control = (n), devpriv->lcfg+LCFG_DMACSR0)
 
 /* Get status for DMA 0 */
@@ -667,7 +667,7 @@
     readb (devpriv->lcfg+LCFG_DMACSR0)
 
 /* Set control for DMA 1 (write only, shadow?) */
-#define RtdDma1Control(dev,n) \
+#define RtdDma1Control(dev, n) \
     writeb (devpriv->dma1Control = (n), devpriv->lcfg+LCFG_DMACSR1)
 
 /* Get status for DMA 1 */
@@ -675,39 +675,39 @@
     readb (devpriv->lcfg+LCFG_DMACSR1)
 
 /*
- * The comedi_driver structure tells the Comedi core module
+ * The struct comedi_driver structure tells the Comedi core module
  * which functions to call to configure/deconfigure (attac/detach)
  * the board, and also about the kernel module that contains
  * the device code.
  */
-static int rtd_attach(comedi_device * dev, comedi_devconfig * it);
-static int rtd_detach(comedi_device * dev);
+static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int rtd_detach(struct comedi_device *dev);
 
-static comedi_driver rtd520Driver = {
+static struct comedi_driver rtd520Driver = {
       driver_name: DRV_NAME,
-      module:THIS_MODULE,
-      attach:rtd_attach,
-      detach:rtd_detach,
+      module : THIS_MODULE,
+      attach : rtd_attach,
+      detach : rtd_detach,
 };
 
-static int rtd_ai_rinsn(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data);
-static int rtd_ao_winsn(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data);
-static int rtd_ao_rinsn(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data);
-static int rtd_dio_insn_bits(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data);
-static int rtd_dio_insn_config(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data);
-static int rtd_ai_cmdtest(comedi_device * dev, comedi_subdevice * s,
-	comedi_cmd * cmd);
-static int rtd_ai_cmd(comedi_device * dev, comedi_subdevice * s);
-static int rtd_ai_cancel(comedi_device * dev, comedi_subdevice * s);
-//static int rtd_ai_poll (comedi_device *dev,comedi_subdevice *s);
+static int rtd_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data);
+static int rtd_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data);
+static int rtd_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data);
+static int rtd_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data);
+static int rtd_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data);
+static int rtd_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_cmd *cmd);
+static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
+static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
+/* static int rtd_ai_poll (struct comedi_device *dev,struct comedi_subdevice *s); */
 static int rtd_ns_to_timer(unsigned int *ns, int roundMode);
 static irqreturn_t rtd_interrupt(int irq, void *d PT_REGS_ARG);
-static int rtd520_probe_fifo_depth(comedi_device *dev);
+static int rtd520_probe_fifo_depth(struct comedi_device *dev);
 
 /*
  * Attach is called by the Comedi core to configure the driver
@@ -715,9 +715,9 @@
  * in the driver structure, dev->board_ptr contains that
  * address.
  */
-static int rtd_attach(comedi_device * dev, comedi_devconfig * it)
+static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {				/* board name and options flags */
-	comedi_subdevice *s;
+	struct comedi_subdevice *s;
 	struct pci_dev *pcidev;
 	int ret;
 	resource_size_t physLas0;	/* configuation */
@@ -739,7 +739,7 @@
 	 * Allocate the private structure area.  alloc_private() is a
 	 * convenient macro defined in comedidev.h.
 	 */
-	if (alloc_private(dev, sizeof(rtdPrivate)) < 0)
+	if (alloc_private(dev, sizeof(struct rtdPrivate)) < 0)
 		return -ENOMEM;
 
 	/*
@@ -779,7 +779,8 @@
 	devpriv->pci_dev = pcidev;
 	dev->board_name = thisboard->name;
 
-	if ((ret = comedi_pci_enable(pcidev, DRV_NAME)) < 0) {
+	ret = comedi_pci_enable(pcidev, DRV_NAME);
+	if (ret < 0) {
 		printk("Failed to enable PCI device and request regions.\n");
 		return ret;
 	}
@@ -866,7 +867,7 @@
 	s->do_cmd = rtd_ai_cmd;
 	s->do_cmdtest = rtd_ai_cmdtest;
 	s->cancel = rtd_ai_cancel;
-	/*s->poll = rtd_ai_poll; *//* not ready yet */
+	/* s->poll = rtd_ai_poll; */ /* not ready yet */
 
 	s = dev->subdevices + 1;
 	/* analog output subdevice */
@@ -918,8 +919,10 @@
 	/* TODO: set user out source ??? */
 
 	/* check if our interrupt is available and get it */
-	if ((ret = comedi_request_irq(devpriv->pci_dev->irq, rtd_interrupt,
-				IRQF_SHARED, DRV_NAME, dev)) < 0) {
+	ret = comedi_request_irq(devpriv->pci_dev->irq, rtd_interrupt,
+				 IRQF_SHARED, DRV_NAME, dev);
+
+	if (ret < 0) {
 		printk("Could not get interrupt! (%u)\n",
 			devpriv->pci_dev->irq);
 		return ret;
@@ -1005,7 +1008,7 @@
 
 #if 0
 	/* hit an error, clean up memory and return ret */
-//rtd_attach_die_error:
+/* rtd_attach_die_error: */
 #ifdef USE_DMA
 	for (index = 0; index < DMA_CHAIN_COUNT; index++) {
 		if (NULL != devpriv->dma0Buff[index]) {	/* free buffer memory */
@@ -1057,7 +1060,7 @@
  * allocated by _attach().  dev->private and dev->subdevices are
  * deallocated automatically by the core.
  */
-static int rtd_detach(comedi_device * dev)
+static int rtd_detach(struct comedi_device *dev)
 {
 #ifdef USE_DMA
 	int index;
@@ -1137,7 +1140,7 @@
 /*
   Convert a single comedi channel-gain entry to a RTD520 table entry
 */
-static unsigned short rtdConvertChanGain(comedi_device * dev,
+static unsigned short rtdConvertChanGain(struct comedi_device *dev,
 	unsigned int comediChan, int chanIndex)
 {				/* index in channel list */
 	unsigned int chan, range, aref;
@@ -1187,7 +1190,7 @@
 /*
   Setup the channel-gain table from a comedi list
 */
-static void rtd_load_channelgain_list(comedi_device * dev,
+static void rtd_load_channelgain_list(struct comedi_device *dev,
 	unsigned int n_chan, unsigned int *list)
 {
 	if (n_chan > 1) {	/* setup channel gain table */
@@ -1206,9 +1209,9 @@
 
 /* determine fifo size by doing adc conversions until the fifo half
 empty status flag clears */
-static int rtd520_probe_fifo_depth(comedi_device *dev)
+static int rtd520_probe_fifo_depth(struct comedi_device *dev)
 {
-	lsampl_t chanspec = CR_PACK(0, 0, AREF_GROUND);
+	unsigned int chanspec = CR_PACK(0, 0, AREF_GROUND);
 	unsigned i;
 	static const unsigned limit = 0x2000;
 	unsigned fifo_size = 0;
@@ -1234,7 +1237,7 @@
 		return -EIO;
 	}
 	RtdAdcClearFifo(dev);
-	if(fifo_size != 0x400 || fifo_size != 0x2000)
+	if(fifo_size != 0x400 && fifo_size != 0x2000)
 	{
 		rt_printk("\ncomedi: %s: unexpected fifo size of %i, expected 1024 or 8192.\n",
 			DRV_NAME, fifo_size);
@@ -1251,8 +1254,8 @@
   Note, we don't do any settling delays.  Use a instruction list to
   select, delay, then read.
  */
-static int rtd_ai_rinsn(comedi_device * dev,
-	comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int rtd_ai_rinsn(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
 {
 	int n, ii;
 	int stat;
@@ -1304,12 +1307,12 @@
 
   The manual claims that we can do a lword read, but it doesn't work here.
 */
-static int ai_read_n(comedi_device * dev, comedi_subdevice * s, int count)
+static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s, int count)
 {
 	int ii;
 
 	for (ii = 0; ii < count; ii++) {
-		sampl_t sample;
+		short sample;
 		s16 d;
 
 		if (0 == devpriv->aiCount) {	/* done */
@@ -1343,10 +1346,10 @@
 /*
   unknown amout of data is waiting in fifo.
 */
-static int ai_read_dregs(comedi_device * dev, comedi_subdevice * s)
+static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	while (RtdFifoStatus(dev) & FS_ADC_NOT_EMPTY) {	/* 1 -> not empty */
-		sampl_t sample;
+		short sample;
 		s16 d = RtdAdcFifoGet(dev);	/* get 2s comp value */
 
 		if (0 == devpriv->aiCount) {	/* done */
@@ -1372,20 +1375,20 @@
 /*
   Terminate a DMA transfer and wait for everything to quiet down
 */
-void abort_dma(comedi_device * dev, unsigned int channel)
+void abort_dma(struct comedi_device *dev, unsigned int channel)
 {				/* DMA channel 0, 1 */
 	unsigned long dma_cs_addr;	/* the control/status register */
 	uint8_t status;
 	unsigned int ii;
-	//unsigned long flags;
+	/* unsigned long flags; */
 
 	dma_cs_addr = (unsigned long)devpriv->lcfg
 		+ ((channel == 0) ? LCFG_DMACSR0 : LCFG_DMACSR1);
 
-	// spinlock for plx dma control/status reg
-	//comedi_spin_lock_irqsave( &dev->spinlock, flags );
+	/*  spinlock for plx dma control/status reg */
+	/* comedi_spin_lock_irqsave( &dev->spinlock, flags ); */
 
-	// abort dma transfer if necessary
+	/*  abort dma transfer if necessary */
 	status = readb(dma_cs_addr);
 	if ((status & PLX_DMA_EN_BIT) == 0) {	/* not enabled (Error?) */
 		DPRINTK("rtd520: AbortDma on non-active channel %d (0x%x)\n",
@@ -1410,7 +1413,7 @@
 	/* set abort bit for channel */
 	writeb(PLX_DMA_ABORT_BIT, dma_cs_addr);
 
-	// wait for dma done bit to be set
+	/*  wait for dma done bit to be set */
 	status = readb(dma_cs_addr);
 	for (ii = 0;
 		(status & PLX_DMA_DONE_BIT) == 0 && ii < RTD_DMA_TIMEOUT;
@@ -1424,14 +1427,14 @@
 	}
 
       abortDmaExit:
-	//comedi_spin_unlock_irqrestore( &dev->spinlock, flags );
+	/* comedi_spin_unlock_irqrestore( &dev->spinlock, flags ); */
 }
 
 /*
   Process what is in the DMA transfer buffer and pass to comedi
   Note: this is not re-entrant
 */
-static int ai_process_dma(comedi_device * dev, comedi_subdevice * s)
+static int ai_process_dma(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	int ii, n;
 	s16 *dp;
@@ -1441,7 +1444,7 @@
 
 	dp = devpriv->dma0Buff[devpriv->dma0Offset];
 	for (ii = 0; ii < devpriv->fifoLen / 2;) {	/* convert samples */
-		sampl_t sample;
+		short sample;
 
 		if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) {
 			sample = (*dp >> 3) + 2048;	/* convert to comedi unsigned data */
@@ -1494,10 +1497,10 @@
 	void *d			/* our data */
 	PT_REGS_ARG)
 {				/* cpu context (ignored) */
-	comedi_device *dev = d;	/* must be called "dev" for devpriv */
+	struct comedi_device *dev = d;	/* must be called "dev" for devpriv */
 	u16 status;
 	u16 fifoStatus;
-	comedi_subdevice *s = dev->subdevices + 0;	/* analog in subdevice */
+	struct comedi_subdevice *s = dev->subdevices + 0;	/* analog in subdevice */
 
 	if (!dev->attached) {
 		return IRQ_NONE;
@@ -1645,7 +1648,7 @@
 /*
   return the number of samples available
 */
-static int rtd_ai_poll(comedi_device * dev, comedi_subdevice * s)
+static int rtd_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	/* TODO: This needs to mask interrupts, read_dregs, and then re-enable */
 	/* Not sure what to do if DMA is active */
@@ -1662,8 +1665,8 @@
   the command passes.
 */
 
-static int rtd_ai_cmdtest(comedi_device * dev,
-	comedi_subdevice * s, comedi_cmd * cmd)
+static int rtd_ai_cmdtest(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -1867,9 +1870,9 @@
   This is usually done by an interrupt handler.
   Userland gets to the data using read calls.
 */
-static int rtd_ai_cmd(comedi_device * dev, comedi_subdevice * s)
+static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
-	comedi_cmd *cmd = &s->async->cmd;
+	struct comedi_cmd *cmd = &s->async->cmd;
 	int timer;
 
 	/* stop anything currently running */
@@ -2064,7 +2067,7 @@
 /*
   Stop a running data aquisition.
 */
-static int rtd_ai_cancel(comedi_device * dev, comedi_subdevice * s)
+static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	u16 status;
 
@@ -2132,8 +2135,8 @@
 /*
   Output one (or more) analog values to a single port as fast as possible.
 */
-static int rtd_ao_winsn(comedi_device * dev,
-	comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int rtd_ao_winsn(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 	int chan = CR_CHAN(insn->chanspec);
@@ -2152,7 +2155,7 @@
 		/* VERIFY: comedi range and offset conversions */
 
 		if ((range > 1)	/* bipolar */
-			&&(data[i] < 2048)) {
+			&& (data[i] < 2048)) {
 			/* offset and sign extend */
 			val = (((int)data[i]) - 2048) << 3;
 		} else {	/* unipolor */
@@ -2187,8 +2190,8 @@
 
 /* AO subdevices should have a read insn as well as a write insn.
  * Usually this means copying a value stored in devpriv. */
-static int rtd_ao_rinsn(comedi_device * dev,
-	comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int rtd_ao_rinsn(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 	int chan = CR_CHAN(insn->chanspec);
@@ -2210,8 +2213,8 @@
  * This allows packed reading/writing of the DIO channels.  The
  * comedi core can convert between insn_bits and insn_read/write
  */
-static int rtd_dio_insn_bits(comedi_device * dev,
-	comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int rtd_dio_insn_bits(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
 {
 	if (insn->n != 2)
 		return -EINVAL;
@@ -2237,8 +2240,8 @@
 /*
   Configure one bit on a IO port as Input or Output (hence the name :-).
 */
-static int rtd_dio_insn_config(comedi_device * dev,
-	comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int rtd_dio_insn_config(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
 {
 	int chan = CR_CHAN(insn->chanspec);
 
diff --git a/drivers/staging/comedi/drivers/rtd520.h b/drivers/staging/comedi/drivers/rtd520.h
index 0eb50b8..a3ec259 100644
--- a/drivers/staging/comedi/drivers/rtd520.h
+++ b/drivers/staging/comedi/drivers/rtd520.h
@@ -29,366 +29,366 @@
   LAS0 Runtime Area
   Local Address Space 0 Offset		Read Function	Write Function
 */
-#define LAS0_SPARE_00    0x0000	// -                               -
-#define LAS0_SPARE_04    0x0004	// -                               -
-#define LAS0_USER_IO     0x0008	// Read User Inputs                Write User Outputs
-#define LAS0_SPARE_0C    0x000C	// -                               -
-#define LAS0_ADC         0x0010	// Read FIFO Status                Software A/D Start
-#define LAS0_DAC1        0x0014	// -                               Software D/A1 Update
-#define LAS0_DAC2        0x0018	// -                               Software D/A2 Update
-#define LAS0_SPARE_1C    0x001C	// -                               -
-#define LAS0_SPARE_20    0x0020	// -                               -
-#define LAS0_DAC         0x0024	// -                               Software Simultaneous D/A1 and D/A2 Update
-#define LAS0_PACER       0x0028	// Software Pacer Start            Software Pacer Stop
-#define LAS0_TIMER       0x002C	// Read Timer Counters Status      HDIN Software Trigger
-#define LAS0_IT          0x0030	// Read Interrupt Status           Write Interrupt Enable Mask Register
-#define LAS0_CLEAR       0x0034	// Clear ITs set by Clear Mask     Set Interrupt Clear Mask
-#define LAS0_OVERRUN     0x0038	// Read pending interrupts         Clear Overrun Register
-#define LAS0_SPARE_3C    0x003C	// -                               -
+#define LAS0_SPARE_00    0x0000	/*  -                               - */
+#define LAS0_SPARE_04    0x0004	/*  -                               - */
+#define LAS0_USER_IO     0x0008	/*  Read User Inputs                Write User Outputs */
+#define LAS0_SPARE_0C    0x000C	/*  -                               - */
+#define LAS0_ADC         0x0010	/*  Read FIFO Status                Software A/D Start */
+#define LAS0_DAC1        0x0014	/*  -                               Software D/A1 Update */
+#define LAS0_DAC2        0x0018	/*  -                               Software D/A2 Update */
+#define LAS0_SPARE_1C    0x001C	/*  -                               - */
+#define LAS0_SPARE_20    0x0020	/*  -                               - */
+#define LAS0_DAC         0x0024	/*  -                               Software Simultaneous D/A1 and D/A2 Update */
+#define LAS0_PACER       0x0028	/*  Software Pacer Start            Software Pacer Stop */
+#define LAS0_TIMER       0x002C	/*  Read Timer Counters Status      HDIN Software Trigger */
+#define LAS0_IT          0x0030	/*  Read Interrupt Status           Write Interrupt Enable Mask Register */
+#define LAS0_CLEAR       0x0034	/*  Clear ITs set by Clear Mask     Set Interrupt Clear Mask */
+#define LAS0_OVERRUN     0x0038	/*  Read pending interrupts         Clear Overrun Register */
+#define LAS0_SPARE_3C    0x003C	/*  -                               - */
 
 /*
   LAS0 Runtime Area Timer/Counter,Dig.IO
   Name			Local Address			Function
 */
-#define LAS0_PCLK        0x0040	// Pacer Clock value (24bit)             Pacer Clock load (24bit)
-#define LAS0_BCLK        0x0044	// Burst Clock value (10bit)             Burst Clock load (10bit)
-#define LAS0_ADC_SCNT    0x0048	// A/D Sample counter value (10bit)      A/D Sample counter load (10bit)
-#define LAS0_DAC1_UCNT   0x004C	// D/A1 Update counter value (10 bit)    D/A1 Update counter load (10bit)
-#define LAS0_DAC2_UCNT   0x0050	// D/A2 Update counter value (10 bit)    D/A2 Update counter load (10bit)
-#define LAS0_DCNT        0x0054	// Delay counter value (16 bit)          Delay counter load (16bit)
-#define LAS0_ACNT        0x0058	// About counter value (16 bit)          About counter load (16bit)
-#define LAS0_DAC_CLK     0x005C	// DAC clock value (16bit)               DAC clock load (16bit)
-#define LAS0_UTC0        0x0060	// 8254 TC Counter 0 User TC 0 value     Load count in TC Counter 0
-#define LAS0_UTC1        0x0064	// 8254 TC Counter 1 User TC 1 value     Load count in TC Counter 1
-#define LAS0_UTC2        0x0068	// 8254 TC Counter 2 User TC 2 value     Load count in TC Counter 2
-#define LAS0_UTC_CTRL    0x006C	// 8254 TC Control Word                  Program counter mode for TC
-#define LAS0_DIO0        0x0070	// Digital I/O Port 0 Read Port          Digital I/O Port 0 Write Port
-#define LAS0_DIO1        0x0074	// Digital I/O Port 1 Read Port          Digital I/O Port 1 Write Port
-#define LAS0_DIO0_CTRL   0x0078	// Clear digital IRQ status flag/read    Clear digital chip/program Port 0
-#define LAS0_DIO_STATUS  0x007C	// Read Digital I/O Status word          Program digital control register &
+#define LAS0_PCLK        0x0040	/*  Pacer Clock value (24bit)             Pacer Clock load (24bit) */
+#define LAS0_BCLK        0x0044	/*  Burst Clock value (10bit)             Burst Clock load (10bit) */
+#define LAS0_ADC_SCNT    0x0048	/*  A/D Sample counter value (10bit)      A/D Sample counter load (10bit) */
+#define LAS0_DAC1_UCNT   0x004C	/*  D/A1 Update counter value (10 bit)    D/A1 Update counter load (10bit) */
+#define LAS0_DAC2_UCNT   0x0050	/*  D/A2 Update counter value (10 bit)    D/A2 Update counter load (10bit) */
+#define LAS0_DCNT        0x0054	/*  Delay counter value (16 bit)          Delay counter load (16bit) */
+#define LAS0_ACNT        0x0058	/*  About counter value (16 bit)          About counter load (16bit) */
+#define LAS0_DAC_CLK     0x005C	/*  DAC clock value (16bit)               DAC clock load (16bit) */
+#define LAS0_UTC0        0x0060	/*  8254 TC Counter 0 User TC 0 value     Load count in TC Counter 0 */
+#define LAS0_UTC1        0x0064	/*  8254 TC Counter 1 User TC 1 value     Load count in TC Counter 1 */
+#define LAS0_UTC2        0x0068	/*  8254 TC Counter 2 User TC 2 value     Load count in TC Counter 2 */
+#define LAS0_UTC_CTRL    0x006C	/*  8254 TC Control Word                  Program counter mode for TC */
+#define LAS0_DIO0        0x0070	/*  Digital I/O Port 0 Read Port          Digital I/O Port 0 Write Port */
+#define LAS0_DIO1        0x0074	/*  Digital I/O Port 1 Read Port          Digital I/O Port 1 Write Port */
+#define LAS0_DIO0_CTRL   0x0078	/*  Clear digital IRQ status flag/read    Clear digital chip/program Port 0 */
+#define LAS0_DIO_STATUS  0x007C	/*  Read Digital I/O Status word          Program digital control register & */
 
 /*
   LAS0 Setup Area
   Name			Local Address			Function
 */
-#define LAS0_BOARD_RESET        0x0100	// Board reset
-#define LAS0_DMA0_SRC           0x0104	// DMA 0 Sources select
-#define LAS0_DMA1_SRC           0x0108	// DMA 1 Sources select
-#define LAS0_ADC_CONVERSION     0x010C	// A/D Conversion Signal select
-#define LAS0_BURST_START        0x0110	// Burst Clock Start Trigger select
-#define LAS0_PACER_START        0x0114	// Pacer Clock Start Trigger select
-#define LAS0_PACER_STOP         0x0118	// Pacer Clock Stop Trigger select
-#define LAS0_ACNT_STOP_ENABLE   0x011C	// About Counter Stop Enable
-#define LAS0_PACER_REPEAT       0x0120	// Pacer Start Trigger Mode select
-#define LAS0_DIN_START          0x0124	// High Speed Digital Input Sampling Signal select
-#define LAS0_DIN_FIFO_CLEAR     0x0128	// Digital Input FIFO Clear
-#define LAS0_ADC_FIFO_CLEAR     0x012C	// A/D FIFO Clear
-#define LAS0_CGT_WRITE          0x0130	// Channel Gain Table Write
-#define LAS0_CGL_WRITE          0x0134	// Channel Gain Latch Write
-#define LAS0_CG_DATA            0x0138	// Digital Table Write
-#define LAS0_CGT_ENABLE		0x013C	// Channel Gain Table Enable
-#define LAS0_CG_ENABLE          0x0140	// Digital Table Enable
-#define LAS0_CGT_PAUSE          0x0144	// Table Pause Enable
-#define LAS0_CGT_RESET          0x0148	// Reset Channel Gain Table
-#define LAS0_CGT_CLEAR          0x014C	// Clear Channel Gain Table
-#define LAS0_DAC1_CTRL          0x0150	// D/A1 output type/range
-#define LAS0_DAC1_SRC           0x0154	// D/A1 update source
-#define LAS0_DAC1_CYCLE         0x0158	// D/A1 cycle mode
-#define LAS0_DAC1_RESET         0x015C	// D/A1 FIFO reset
-#define LAS0_DAC1_FIFO_CLEAR    0x0160	// D/A1 FIFO clear
-#define LAS0_DAC2_CTRL          0x0164	// D/A2 output type/range
-#define LAS0_DAC2_SRC           0x0168	// D/A2 update source
-#define LAS0_DAC2_CYCLE         0x016C	// D/A2 cycle mode
-#define LAS0_DAC2_RESET         0x0170	// D/A2 FIFO reset
-#define LAS0_DAC2_FIFO_CLEAR    0x0174	// D/A2 FIFO clear
-#define LAS0_ADC_SCNT_SRC       0x0178	// A/D Sample Counter Source select
-#define LAS0_PACER_SELECT       0x0180	// Pacer Clock select
-#define LAS0_SBUS0_SRC          0x0184	// SyncBus 0 Source select
-#define LAS0_SBUS0_ENABLE       0x0188	// SyncBus 0 enable
-#define LAS0_SBUS1_SRC          0x018C	// SyncBus 1 Source select
-#define LAS0_SBUS1_ENABLE       0x0190	// SyncBus 1 enable
-#define LAS0_SBUS2_SRC          0x0198	// SyncBus 2 Source select
-#define LAS0_SBUS2_ENABLE       0x019C	// SyncBus 2 enable
-#define LAS0_ETRG_POLARITY      0x01A4	// External Trigger polarity select
-#define LAS0_EINT_POLARITY      0x01A8	// External Interrupt polarity select
-#define LAS0_UTC0_CLOCK         0x01AC	// UTC0 Clock select
-#define LAS0_UTC0_GATE          0x01B0	// UTC0 Gate select
-#define LAS0_UTC1_CLOCK         0x01B4	// UTC1 Clock select
-#define LAS0_UTC1_GATE          0x01B8	// UTC1 Gate select
-#define LAS0_UTC2_CLOCK         0x01BC	// UTC2 Clock select
-#define LAS0_UTC2_GATE          0x01C0	// UTC2 Gate select
-#define LAS0_UOUT0_SELECT       0x01C4	// User Output 0 source select
-#define LAS0_UOUT1_SELECT       0x01C8	// User Output 1 source select
-#define LAS0_DMA0_RESET         0x01CC	// DMA0 Request state machine reset
-#define LAS0_DMA1_RESET         0x01D0	// DMA1 Request state machine reset
+#define LAS0_BOARD_RESET        0x0100	/*  Board reset */
+#define LAS0_DMA0_SRC           0x0104	/*  DMA 0 Sources select */
+#define LAS0_DMA1_SRC           0x0108	/*  DMA 1 Sources select */
+#define LAS0_ADC_CONVERSION     0x010C	/*  A/D Conversion Signal select */
+#define LAS0_BURST_START        0x0110	/*  Burst Clock Start Trigger select */
+#define LAS0_PACER_START        0x0114	/*  Pacer Clock Start Trigger select */
+#define LAS0_PACER_STOP         0x0118	/*  Pacer Clock Stop Trigger select */
+#define LAS0_ACNT_STOP_ENABLE   0x011C	/*  About Counter Stop Enable */
+#define LAS0_PACER_REPEAT       0x0120	/*  Pacer Start Trigger Mode select */
+#define LAS0_DIN_START          0x0124	/*  High Speed Digital Input Sampling Signal select */
+#define LAS0_DIN_FIFO_CLEAR     0x0128	/*  Digital Input FIFO Clear */
+#define LAS0_ADC_FIFO_CLEAR     0x012C	/*  A/D FIFO Clear */
+#define LAS0_CGT_WRITE          0x0130	/*  Channel Gain Table Write */
+#define LAS0_CGL_WRITE          0x0134	/*  Channel Gain Latch Write */
+#define LAS0_CG_DATA            0x0138	/*  Digital Table Write */
+#define LAS0_CGT_ENABLE		0x013C	/*  Channel Gain Table Enable */
+#define LAS0_CG_ENABLE          0x0140	/*  Digital Table Enable */
+#define LAS0_CGT_PAUSE          0x0144	/*  Table Pause Enable */
+#define LAS0_CGT_RESET          0x0148	/*  Reset Channel Gain Table */
+#define LAS0_CGT_CLEAR          0x014C	/*  Clear Channel Gain Table */
+#define LAS0_DAC1_CTRL          0x0150	/*  D/A1 output type/range */
+#define LAS0_DAC1_SRC           0x0154	/*  D/A1 update source */
+#define LAS0_DAC1_CYCLE         0x0158	/*  D/A1 cycle mode */
+#define LAS0_DAC1_RESET         0x015C	/*  D/A1 FIFO reset */
+#define LAS0_DAC1_FIFO_CLEAR    0x0160	/*  D/A1 FIFO clear */
+#define LAS0_DAC2_CTRL          0x0164	/*  D/A2 output type/range */
+#define LAS0_DAC2_SRC           0x0168	/*  D/A2 update source */
+#define LAS0_DAC2_CYCLE         0x016C	/*  D/A2 cycle mode */
+#define LAS0_DAC2_RESET         0x0170	/*  D/A2 FIFO reset */
+#define LAS0_DAC2_FIFO_CLEAR    0x0174	/*  D/A2 FIFO clear */
+#define LAS0_ADC_SCNT_SRC       0x0178	/*  A/D Sample Counter Source select */
+#define LAS0_PACER_SELECT       0x0180	/*  Pacer Clock select */
+#define LAS0_SBUS0_SRC          0x0184	/*  SyncBus 0 Source select */
+#define LAS0_SBUS0_ENABLE       0x0188	/*  SyncBus 0 enable */
+#define LAS0_SBUS1_SRC          0x018C	/*  SyncBus 1 Source select */
+#define LAS0_SBUS1_ENABLE       0x0190	/*  SyncBus 1 enable */
+#define LAS0_SBUS2_SRC          0x0198	/*  SyncBus 2 Source select */
+#define LAS0_SBUS2_ENABLE       0x019C	/*  SyncBus 2 enable */
+#define LAS0_ETRG_POLARITY      0x01A4	/*  External Trigger polarity select */
+#define LAS0_EINT_POLARITY      0x01A8	/*  External Interrupt polarity select */
+#define LAS0_UTC0_CLOCK         0x01AC	/*  UTC0 Clock select */
+#define LAS0_UTC0_GATE          0x01B0	/*  UTC0 Gate select */
+#define LAS0_UTC1_CLOCK         0x01B4	/*  UTC1 Clock select */
+#define LAS0_UTC1_GATE          0x01B8	/*  UTC1 Gate select */
+#define LAS0_UTC2_CLOCK         0x01BC	/*  UTC2 Clock select */
+#define LAS0_UTC2_GATE          0x01C0	/*  UTC2 Gate select */
+#define LAS0_UOUT0_SELECT       0x01C4	/*  User Output 0 source select */
+#define LAS0_UOUT1_SELECT       0x01C8	/*  User Output 1 source select */
+#define LAS0_DMA0_RESET         0x01CC	/*  DMA0 Request state machine reset */
+#define LAS0_DMA1_RESET         0x01D0	/*  DMA1 Request state machine reset */
 
 /*
   LAS1
   Name			Local Address			Function
 */
-#define LAS1_ADC_FIFO            0x0000	// Read A/D FIFO (16bit) -
-#define LAS1_HDIO_FIFO           0x0004	// Read High Speed Digital Input FIFO (16bit) -
-#define LAS1_DAC1_FIFO           0x0008	// - Write D/A1 FIFO (16bit)
-#define LAS1_DAC2_FIFO           0x000C	// - Write D/A2 FIFO (16bit)
+#define LAS1_ADC_FIFO            0x0000	/*  Read A/D FIFO (16bit) - */
+#define LAS1_HDIO_FIFO           0x0004	/*  Read High Speed Digital Input FIFO (16bit) - */
+#define LAS1_DAC1_FIFO           0x0008	/*  - Write D/A1 FIFO (16bit) */
+#define LAS1_DAC2_FIFO           0x000C	/*  - Write D/A2 FIFO (16bit) */
 
 /*
   LCFG: PLX 9080 local config & runtime registers
   Name			Local Address			Function
 */
-#define LCFG_ITCSR              0x0068	// INTCSR, Interrupt Control/Status Register
-#define LCFG_DMAMODE0           0x0080	// DMA Channel 0 Mode Register
-#define LCFG_DMAPADR0           0x0084	// DMA Channel 0 PCI Address Register
-#define LCFG_DMALADR0           0x0088	// DMA Channel 0 Local Address Reg
-#define LCFG_DMASIZ0            0x008C	// DMA Channel 0 Transfer Size (Bytes) Register
-#define LCFG_DMADPR0            0x0090	// DMA Channel 0 Descriptor Pointer Register
-#define LCFG_DMAMODE1           0x0094	// DMA Channel 1 Mode Register
-#define LCFG_DMAPADR1           0x0098	// DMA Channel 1 PCI Address Register
-#define LCFG_DMALADR1           0x009C	// DMA Channel 1 Local Address Register
-#define LCFG_DMASIZ1            0x00A0	// DMA Channel 1 Transfer Size (Bytes) Register
-#define LCFG_DMADPR1            0x00A4	// DMA Channel 1 Descriptor Pointer Register
-#define LCFG_DMACSR0            0x00A8	// DMA Channel 0 Command/Status Register
-#define LCFG_DMACSR1            0x00A9	// DMA Channel 0 Command/Status Register
-#define LCFG_DMAARB             0x00AC	// DMA Arbitration Register
-#define LCFG_DMATHR             0x00B0	// DMA Threshold Register
+#define LCFG_ITCSR              0x0068	/*  INTCSR, Interrupt Control/Status Register */
+#define LCFG_DMAMODE0           0x0080	/*  DMA Channel 0 Mode Register */
+#define LCFG_DMAPADR0           0x0084	/*  DMA Channel 0 PCI Address Register */
+#define LCFG_DMALADR0           0x0088	/*  DMA Channel 0 Local Address Reg */
+#define LCFG_DMASIZ0            0x008C	/*  DMA Channel 0 Transfer Size (Bytes) Register */
+#define LCFG_DMADPR0            0x0090	/*  DMA Channel 0 Descriptor Pointer Register */
+#define LCFG_DMAMODE1           0x0094	/*  DMA Channel 1 Mode Register */
+#define LCFG_DMAPADR1           0x0098	/*  DMA Channel 1 PCI Address Register */
+#define LCFG_DMALADR1           0x009C	/*  DMA Channel 1 Local Address Register */
+#define LCFG_DMASIZ1            0x00A0	/*  DMA Channel 1 Transfer Size (Bytes) Register */
+#define LCFG_DMADPR1            0x00A4	/*  DMA Channel 1 Descriptor Pointer Register */
+#define LCFG_DMACSR0            0x00A8	/*  DMA Channel 0 Command/Status Register */
+#define LCFG_DMACSR1            0x00A9	/*  DMA Channel 0 Command/Status Register */
+#define LCFG_DMAARB             0x00AC	/*  DMA Arbitration Register */
+#define LCFG_DMATHR             0x00B0	/*  DMA Threshold Register */
 
 /*======================================================================
   Resister bit definitions
 ======================================================================*/
 
-// FIFO Status Word Bits (RtdFifoStatus)
-#define FS_DAC1_NOT_EMPTY    0x0001	// D0  - DAC1 FIFO not empty
-#define FS_DAC1_HEMPTY   0x0002	// D1  - DAC1 FIFO half empty
-#define FS_DAC1_NOT_FULL     0x0004	// D2  - DAC1 FIFO not full
-#define FS_DAC2_NOT_EMPTY    0x0010	// D4  - DAC2 FIFO not empty
-#define FS_DAC2_HEMPTY   0x0020	// D5  - DAC2 FIFO half empty
-#define FS_DAC2_NOT_FULL     0x0040	// D6  - DAC2 FIFO not full
-#define FS_ADC_NOT_EMPTY     0x0100	// D8  - ADC FIFO not empty
-#define FS_ADC_HEMPTY    0x0200	// D9  - ADC FIFO half empty
-#define FS_ADC_NOT_FULL      0x0400	// D10 - ADC FIFO not full
-#define FS_DIN_NOT_EMPTY     0x1000	// D12 - DIN FIFO not empty
-#define FS_DIN_HEMPTY    0x2000	// D13 - DIN FIFO half empty
-#define FS_DIN_NOT_FULL      0x4000	// D14 - DIN FIFO not full
+/*  FIFO Status Word Bits (RtdFifoStatus) */
+#define FS_DAC1_NOT_EMPTY    0x0001	/*  D0  - DAC1 FIFO not empty */
+#define FS_DAC1_HEMPTY   0x0002	/*  D1  - DAC1 FIFO half empty */
+#define FS_DAC1_NOT_FULL     0x0004	/*  D2  - DAC1 FIFO not full */
+#define FS_DAC2_NOT_EMPTY    0x0010	/*  D4  - DAC2 FIFO not empty */
+#define FS_DAC2_HEMPTY   0x0020	/*  D5  - DAC2 FIFO half empty */
+#define FS_DAC2_NOT_FULL     0x0040	/*  D6  - DAC2 FIFO not full */
+#define FS_ADC_NOT_EMPTY     0x0100	/*  D8  - ADC FIFO not empty */
+#define FS_ADC_HEMPTY    0x0200	/*  D9  - ADC FIFO half empty */
+#define FS_ADC_NOT_FULL      0x0400	/*  D10 - ADC FIFO not full */
+#define FS_DIN_NOT_EMPTY     0x1000	/*  D12 - DIN FIFO not empty */
+#define FS_DIN_HEMPTY    0x2000	/*  D13 - DIN FIFO half empty */
+#define FS_DIN_NOT_FULL      0x4000	/*  D14 - DIN FIFO not full */
 
-// Timer Status Word Bits (GetTimerStatus)
+/*  Timer Status Word Bits (GetTimerStatus) */
 #define TS_PCLK_GATE   0x0001
-// D0 - Pacer Clock Gate [0 - gated, 1 - enabled]
+/*  D0 - Pacer Clock Gate [0 - gated, 1 - enabled] */
 #define TS_BCLK_GATE   0x0002
-// D1 - Burst Clock Gate [0 - disabled, 1 - running]
+/*  D1 - Burst Clock Gate [0 - disabled, 1 - running] */
 #define TS_DCNT_GATE   0x0004
-// D2 - Pacer Clock Delayed Start Trigger [0 - delay over, 1 - delay in
-// progress]
+/*  D2 - Pacer Clock Delayed Start Trigger [0 - delay over, 1 - delay in */
+/*  progress] */
 #define TS_ACNT_GATE   0x0008
-// D3 - Pacer Clock About Trigger [0 - completed, 1 - in progress]
+/*  D3 - Pacer Clock About Trigger [0 - completed, 1 - in progress] */
 #define TS_PCLK_RUN    0x0010
-// D4 - Pacer Clock Shutdown Flag [0 - Pacer Clock cannot be start
-// triggered only by Software Pacer Start Command, 1 - Pacer Clock can
-// be start triggered]
+/*  D4 - Pacer Clock Shutdown Flag [0 - Pacer Clock cannot be start */
+/*  triggered only by Software Pacer Start Command, 1 - Pacer Clock can */
+/*  be start triggered] */
 
-// External Trigger polarity select
-// External Interrupt polarity select
-#define POL_POSITIVE         0x0	// positive edge
-#define POL_NEGATIVE         0x1	// negative edge
+/*  External Trigger polarity select */
+/*  External Interrupt polarity select */
+#define POL_POSITIVE         0x0	/*  positive edge */
+#define POL_NEGATIVE         0x1	/*  negative edge */
 
-// User Output Signal select (SetUout0Source, SetUout1Source)
-#define UOUT_ADC                0x0	// A/D Conversion Signal
-#define UOUT_DAC1               0x1	// D/A1 Update
-#define UOUT_DAC2               0x2	// D/A2 Update
-#define UOUT_SOFTWARE           0x3	// Software Programmable
+/*  User Output Signal select (SetUout0Source, SetUout1Source) */
+#define UOUT_ADC                0x0	/*  A/D Conversion Signal */
+#define UOUT_DAC1               0x1	/*  D/A1 Update */
+#define UOUT_DAC2               0x2	/*  D/A2 Update */
+#define UOUT_SOFTWARE           0x3	/*  Software Programmable */
 
-// Pacer clock select (SetPacerSource)
-#define PCLK_INTERNAL           1	// Internal Pacer Clock
-#define PCLK_EXTERNAL           0	// External Pacer Clock
+/*  Pacer clock select (SetPacerSource) */
+#define PCLK_INTERNAL           1	/*  Internal Pacer Clock */
+#define PCLK_EXTERNAL           0	/*  External Pacer Clock */
 
-// A/D Sample Counter Sources (SetAdcntSource, SetupSampleCounter)
-#define ADC_SCNT_CGT_RESET         0x0	// needs restart with StartPacer
+/*  A/D Sample Counter Sources (SetAdcntSource, SetupSampleCounter) */
+#define ADC_SCNT_CGT_RESET         0x0	/*  needs restart with StartPacer */
 #define ADC_SCNT_FIFO_WRITE        0x1
 
-// A/D Conversion Signal Select (for SetConversionSelect)
-#define ADC_START_SOFTWARE         0x0	// Software A/D Start
-#define ADC_START_PCLK             0x1	// Pacer Clock (Ext. Int. see Func.509)
-#define ADC_START_BCLK             0x2	// Burst Clock
-#define ADC_START_DIGITAL_IT       0x3	// Digital Interrupt
-#define ADC_START_DAC1_MARKER1     0x4	// D/A 1 Data Marker 1
-#define ADC_START_DAC2_MARKER1     0x5	// D/A 2 Data Marker 1
-#define ADC_START_SBUS0            0x6	// SyncBus 0
-#define ADC_START_SBUS1            0x7	// SyncBus 1
-#define ADC_START_SBUS2            0x8	// SyncBus 2
+/*  A/D Conversion Signal Select (for SetConversionSelect) */
+#define ADC_START_SOFTWARE         0x0	/*  Software A/D Start */
+#define ADC_START_PCLK             0x1	/*  Pacer Clock (Ext. Int. see Func.509) */
+#define ADC_START_BCLK             0x2	/*  Burst Clock */
+#define ADC_START_DIGITAL_IT       0x3	/*  Digital Interrupt */
+#define ADC_START_DAC1_MARKER1     0x4	/*  D/A 1 Data Marker 1 */
+#define ADC_START_DAC2_MARKER1     0x5	/*  D/A 2 Data Marker 1 */
+#define ADC_START_SBUS0            0x6	/*  SyncBus 0 */
+#define ADC_START_SBUS1            0x7	/*  SyncBus 1 */
+#define ADC_START_SBUS2            0x8	/*  SyncBus 2 */
 
-// Burst Clock start trigger select (SetBurstStart)
-#define BCLK_START_SOFTWARE        0x0	// Software A/D Start (StartBurst)
-#define BCLK_START_PCLK            0x1	// Pacer Clock
-#define BCLK_START_ETRIG           0x2	// External Trigger
-#define BCLK_START_DIGITAL_IT      0x3	// Digital Interrupt
-#define BCLK_START_SBUS0           0x4	// SyncBus 0
-#define BCLK_START_SBUS1           0x5	// SyncBus 1
-#define BCLK_START_SBUS2           0x6	// SyncBus 2
+/*  Burst Clock start trigger select (SetBurstStart) */
+#define BCLK_START_SOFTWARE        0x0	/*  Software A/D Start (StartBurst) */
+#define BCLK_START_PCLK            0x1	/*  Pacer Clock */
+#define BCLK_START_ETRIG           0x2	/*  External Trigger */
+#define BCLK_START_DIGITAL_IT      0x3	/*  Digital Interrupt */
+#define BCLK_START_SBUS0           0x4	/*  SyncBus 0 */
+#define BCLK_START_SBUS1           0x5	/*  SyncBus 1 */
+#define BCLK_START_SBUS2           0x6	/*  SyncBus 2 */
 
-// Pacer Clock start trigger select (SetPacerStart)
-#define PCLK_START_SOFTWARE        0x0	// Software Pacer Start (StartPacer)
-#define PCLK_START_ETRIG           0x1	// External trigger
-#define PCLK_START_DIGITAL_IT      0x2	// Digital interrupt
-#define PCLK_START_UTC2            0x3	// User TC 2 out
-#define PCLK_START_SBUS0           0x4	// SyncBus 0
-#define PCLK_START_SBUS1           0x5	// SyncBus 1
-#define PCLK_START_SBUS2           0x6	// SyncBus 2
-#define PCLK_START_D_SOFTWARE      0x8	// Delayed Software Pacer Start
-#define PCLK_START_D_ETRIG         0x9	// Delayed external trigger
-#define PCLK_START_D_DIGITAL_IT    0xA	// Delayed digital interrupt
-#define PCLK_START_D_UTC2          0xB	// Delayed User TC 2 out
-#define PCLK_START_D_SBUS0         0xC	// Delayed SyncBus 0
-#define PCLK_START_D_SBUS1         0xD	// Delayed SyncBus 1
-#define PCLK_START_D_SBUS2         0xE	// Delayed SyncBus 2
-#define PCLK_START_ETRIG_GATED     0xF	// External Trigger Gated controlled mode
+/*  Pacer Clock start trigger select (SetPacerStart) */
+#define PCLK_START_SOFTWARE        0x0	/*  Software Pacer Start (StartPacer) */
+#define PCLK_START_ETRIG           0x1	/*  External trigger */
+#define PCLK_START_DIGITAL_IT      0x2	/*  Digital interrupt */
+#define PCLK_START_UTC2            0x3	/*  User TC 2 out */
+#define PCLK_START_SBUS0           0x4	/*  SyncBus 0 */
+#define PCLK_START_SBUS1           0x5	/*  SyncBus 1 */
+#define PCLK_START_SBUS2           0x6	/*  SyncBus 2 */
+#define PCLK_START_D_SOFTWARE      0x8	/*  Delayed Software Pacer Start */
+#define PCLK_START_D_ETRIG         0x9	/*  Delayed external trigger */
+#define PCLK_START_D_DIGITAL_IT    0xA	/*  Delayed digital interrupt */
+#define PCLK_START_D_UTC2          0xB	/*  Delayed User TC 2 out */
+#define PCLK_START_D_SBUS0         0xC	/*  Delayed SyncBus 0 */
+#define PCLK_START_D_SBUS1         0xD	/*  Delayed SyncBus 1 */
+#define PCLK_START_D_SBUS2         0xE	/*  Delayed SyncBus 2 */
+#define PCLK_START_ETRIG_GATED     0xF	/*  External Trigger Gated controlled mode */
 
-// Pacer Clock Stop Trigger select (SetPacerStop)
-#define PCLK_STOP_SOFTWARE         0x0	// Software Pacer Stop (StopPacer)
-#define PCLK_STOP_ETRIG            0x1	// External Trigger
-#define PCLK_STOP_DIGITAL_IT       0x2	// Digital Interrupt
-#define PCLK_STOP_ACNT             0x3	// About Counter
-#define PCLK_STOP_UTC2             0x4	// User TC2 out
-#define PCLK_STOP_SBUS0            0x5	// SyncBus 0
-#define PCLK_STOP_SBUS1            0x6	// SyncBus 1
-#define PCLK_STOP_SBUS2            0x7	// SyncBus 2
-#define PCLK_STOP_A_SOFTWARE       0x8	// About Software Pacer Stop
-#define PCLK_STOP_A_ETRIG          0x9	// About External Trigger
-#define PCLK_STOP_A_DIGITAL_IT     0xA	// About Digital Interrupt
-#define PCLK_STOP_A_UTC2           0xC	// About User TC2 out
-#define PCLK_STOP_A_SBUS0          0xD	// About SyncBus 0
-#define PCLK_STOP_A_SBUS1          0xE	// About SyncBus 1
-#define PCLK_STOP_A_SBUS2          0xF	// About SyncBus 2
+/*  Pacer Clock Stop Trigger select (SetPacerStop) */
+#define PCLK_STOP_SOFTWARE         0x0	/*  Software Pacer Stop (StopPacer) */
+#define PCLK_STOP_ETRIG            0x1	/*  External Trigger */
+#define PCLK_STOP_DIGITAL_IT       0x2	/*  Digital Interrupt */
+#define PCLK_STOP_ACNT             0x3	/*  About Counter */
+#define PCLK_STOP_UTC2             0x4	/*  User TC2 out */
+#define PCLK_STOP_SBUS0            0x5	/*  SyncBus 0 */
+#define PCLK_STOP_SBUS1            0x6	/*  SyncBus 1 */
+#define PCLK_STOP_SBUS2            0x7	/*  SyncBus 2 */
+#define PCLK_STOP_A_SOFTWARE       0x8	/*  About Software Pacer Stop */
+#define PCLK_STOP_A_ETRIG          0x9	/*  About External Trigger */
+#define PCLK_STOP_A_DIGITAL_IT     0xA	/*  About Digital Interrupt */
+#define PCLK_STOP_A_UTC2           0xC	/*  About User TC2 out */
+#define PCLK_STOP_A_SBUS0          0xD	/*  About SyncBus 0 */
+#define PCLK_STOP_A_SBUS1          0xE	/*  About SyncBus 1 */
+#define PCLK_STOP_A_SBUS2          0xF	/*  About SyncBus 2 */
 
-// About Counter Stop Enable
-#define ACNT_STOP                  0x0	// stop enable
-#define ACNT_NO_STOP               0x1	// stop disabled
+/*  About Counter Stop Enable */
+#define ACNT_STOP                  0x0	/*  stop enable */
+#define ACNT_NO_STOP               0x1	/*  stop disabled */
 
-// DAC update source (SetDAC1Start & SetDAC2Start)
-#define DAC_START_SOFTWARE         0x0	// Software Update
-#define DAC_START_CGT              0x1	// CGT controlled Update
-#define DAC_START_DAC_CLK          0x2	// D/A Clock
-#define DAC_START_EPCLK            0x3	// External Pacer Clock
-#define DAC_START_SBUS0            0x4	// SyncBus 0
-#define DAC_START_SBUS1            0x5	// SyncBus 1
-#define DAC_START_SBUS2            0x6	// SyncBus 2
+/*  DAC update source (SetDAC1Start & SetDAC2Start) */
+#define DAC_START_SOFTWARE         0x0	/*  Software Update */
+#define DAC_START_CGT              0x1	/*  CGT controlled Update */
+#define DAC_START_DAC_CLK          0x2	/*  D/A Clock */
+#define DAC_START_EPCLK            0x3	/*  External Pacer Clock */
+#define DAC_START_SBUS0            0x4	/*  SyncBus 0 */
+#define DAC_START_SBUS1            0x5	/*  SyncBus 1 */
+#define DAC_START_SBUS2            0x6	/*  SyncBus 2 */
 
-// DAC Cycle Mode (SetDAC1Cycle, SetDAC2Cycle, SetupDAC)
-#define DAC_CYCLE_SINGLE           0x0	// not cycle
-#define DAC_CYCLE_MULTI            0x1	// cycle
+/*  DAC Cycle Mode (SetDAC1Cycle, SetDAC2Cycle, SetupDAC) */
+#define DAC_CYCLE_SINGLE           0x0	/*  not cycle */
+#define DAC_CYCLE_MULTI            0x1	/*  cycle */
 
-// 8254 Operation Modes (Set8254Mode, SetupTimerCounter)
-#define M8254_EVENT_COUNTER        0	// Event Counter
-#define M8254_HW_ONE_SHOT          1	// Hardware-Retriggerable One-Shot
-#define M8254_RATE_GENERATOR       2	// Rate Generator
-#define M8254_SQUARE_WAVE          3	// Square Wave Mode
-#define M8254_SW_STROBE            4	// Software Triggered Strobe
-#define M8254_HW_STROBE            5	// Hardware Triggered Strobe (Retriggerable)
+/*  8254 Operation Modes (Set8254Mode, SetupTimerCounter) */
+#define M8254_EVENT_COUNTER        0	/*  Event Counter */
+#define M8254_HW_ONE_SHOT          1	/*  Hardware-Retriggerable One-Shot */
+#define M8254_RATE_GENERATOR       2	/*  Rate Generator */
+#define M8254_SQUARE_WAVE          3	/*  Square Wave Mode */
+#define M8254_SW_STROBE            4	/*  Software Triggered Strobe */
+#define M8254_HW_STROBE            5	/*  Hardware Triggered Strobe (Retriggerable) */
 
-// User Timer/Counter 0 Clock Select (SetUtc0Clock)
-#define CUTC0_8MHZ                 0x0	// 8MHz
-#define CUTC0_EXT_TC_CLOCK1        0x1	// Ext. TC Clock 1
-#define CUTC0_EXT_TC_CLOCK2        0x2	// Ext. TC Clock 2
-#define CUTC0_EXT_PCLK             0x3	// Ext. Pacer Clock
+/*  User Timer/Counter 0 Clock Select (SetUtc0Clock) */
+#define CUTC0_8MHZ                 0x0	/*  8MHz */
+#define CUTC0_EXT_TC_CLOCK1        0x1	/*  Ext. TC Clock 1 */
+#define CUTC0_EXT_TC_CLOCK2        0x2	/*  Ext. TC Clock 2 */
+#define CUTC0_EXT_PCLK             0x3	/*  Ext. Pacer Clock */
 
-// User Timer/Counter 1 Clock Select (SetUtc1Clock)
-#define CUTC1_8MHZ                 0x0	// 8MHz
-#define CUTC1_EXT_TC_CLOCK1        0x1	// Ext. TC Clock 1
-#define CUTC1_EXT_TC_CLOCK2        0x2	// Ext. TC Clock 2
-#define CUTC1_EXT_PCLK             0x3	// Ext. Pacer Clock
-#define CUTC1_UTC0_OUT             0x4	// User Timer/Counter 0 out
-#define CUTC1_DIN_SIGNAL           0x5	// High-Speed Digital Input   Sampling signal
+/*  User Timer/Counter 1 Clock Select (SetUtc1Clock) */
+#define CUTC1_8MHZ                 0x0	/*  8MHz */
+#define CUTC1_EXT_TC_CLOCK1        0x1	/*  Ext. TC Clock 1 */
+#define CUTC1_EXT_TC_CLOCK2        0x2	/*  Ext. TC Clock 2 */
+#define CUTC1_EXT_PCLK             0x3	/*  Ext. Pacer Clock */
+#define CUTC1_UTC0_OUT             0x4	/*  User Timer/Counter 0 out */
+#define CUTC1_DIN_SIGNAL           0x5	/*  High-Speed Digital Input   Sampling signal */
 
-// User Timer/Counter 2 Clock Select (SetUtc2Clock)
-#define CUTC2_8MHZ                 0x0	// 8MHz
-#define CUTC2_EXT_TC_CLOCK1        0x1	// Ext. TC Clock 1
-#define CUTC2_EXT_TC_CLOCK2        0x2	// Ext. TC Clock 2
-#define CUTC2_EXT_PCLK             0x3	// Ext. Pacer Clock
-#define CUTC2_UTC1_OUT             0x4	// User Timer/Counter 1 out
+/*  User Timer/Counter 2 Clock Select (SetUtc2Clock) */
+#define CUTC2_8MHZ                 0x0	/*  8MHz */
+#define CUTC2_EXT_TC_CLOCK1        0x1	/*  Ext. TC Clock 1 */
+#define CUTC2_EXT_TC_CLOCK2        0x2	/*  Ext. TC Clock 2 */
+#define CUTC2_EXT_PCLK             0x3	/*  Ext. Pacer Clock */
+#define CUTC2_UTC1_OUT             0x4	/*  User Timer/Counter 1 out */
 
-// User Timer/Counter 0 Gate Select (SetUtc0Gate)
-#define GUTC0_NOT_GATED            0x0	// Not gated
-#define GUTC0_GATED                0x1	// Gated
-#define GUTC0_EXT_TC_GATE1         0x2	// Ext. TC Gate 1
-#define GUTC0_EXT_TC_GATE2         0x3	// Ext. TC Gate 2
+/*  User Timer/Counter 0 Gate Select (SetUtc0Gate) */
+#define GUTC0_NOT_GATED            0x0	/*  Not gated */
+#define GUTC0_GATED                0x1	/*  Gated */
+#define GUTC0_EXT_TC_GATE1         0x2	/*  Ext. TC Gate 1 */
+#define GUTC0_EXT_TC_GATE2         0x3	/*  Ext. TC Gate 2 */
 
-// User Timer/Counter 1 Gate Select (SetUtc1Gate)
-#define GUTC1_NOT_GATED            0x0	// Not gated
-#define GUTC1_GATED                0x1	// Gated
-#define GUTC1_EXT_TC_GATE1         0x2	// Ext. TC Gate 1
-#define GUTC1_EXT_TC_GATE2         0x3	// Ext. TC Gate 2
-#define GUTC1_UTC0_OUT             0x4	// User Timer/Counter 0 out
+/*  User Timer/Counter 1 Gate Select (SetUtc1Gate) */
+#define GUTC1_NOT_GATED            0x0	/*  Not gated */
+#define GUTC1_GATED                0x1	/*  Gated */
+#define GUTC1_EXT_TC_GATE1         0x2	/*  Ext. TC Gate 1 */
+#define GUTC1_EXT_TC_GATE2         0x3	/*  Ext. TC Gate 2 */
+#define GUTC1_UTC0_OUT             0x4	/*  User Timer/Counter 0 out */
 
-// User Timer/Counter 2 Gate Select (SetUtc2Gate)
-#define GUTC2_NOT_GATED            0x0	// Not gated
-#define GUTC2_GATED                0x1	// Gated
-#define GUTC2_EXT_TC_GATE1         0x2	// Ext. TC Gate 1
-#define GUTC2_EXT_TC_GATE2         0x3	// Ext. TC Gate 2
-#define GUTC2_UTC1_OUT             0x4	// User Timer/Counter 1 out
+/*  User Timer/Counter 2 Gate Select (SetUtc2Gate) */
+#define GUTC2_NOT_GATED            0x0	/*  Not gated */
+#define GUTC2_GATED                0x1	/*  Gated */
+#define GUTC2_EXT_TC_GATE1         0x2	/*  Ext. TC Gate 1 */
+#define GUTC2_EXT_TC_GATE2         0x3	/*  Ext. TC Gate 2 */
+#define GUTC2_UTC1_OUT             0x4	/*  User Timer/Counter 1 out */
 
-// Interrupt Source Masks (SetITMask, ClearITMask, GetITStatus)
-#define IRQM_ADC_FIFO_WRITE        0x0001	// ADC FIFO Write
-#define IRQM_CGT_RESET             0x0002	// Reset CGT
-#define IRQM_CGT_PAUSE             0x0008	// Pause CGT
-#define IRQM_ADC_ABOUT_CNT         0x0010	// About Counter out
-#define IRQM_ADC_DELAY_CNT         0x0020	// Delay Counter out
-#define IRQM_ADC_SAMPLE_CNT	   0x0040	// ADC Sample Counter
-#define IRQM_DAC1_UCNT             0x0080	// DAC1 Update Counter
-#define IRQM_DAC2_UCNT             0x0100	// DAC2 Update Counter
-#define IRQM_UTC1                  0x0200	// User TC1 out
-#define IRQM_UTC1_INV              0x0400	// User TC1 out, inverted
-#define IRQM_UTC2                  0x0800	// User TC2 out
-#define IRQM_DIGITAL_IT            0x1000	// Digital Interrupt
-#define IRQM_EXTERNAL_IT           0x2000	// External Interrupt
-#define IRQM_ETRIG_RISING          0x4000	// External Trigger rising-edge
-#define IRQM_ETRIG_FALLING         0x8000	// External Trigger falling-edge
+/*  Interrupt Source Masks (SetITMask, ClearITMask, GetITStatus) */
+#define IRQM_ADC_FIFO_WRITE        0x0001	/*  ADC FIFO Write */
+#define IRQM_CGT_RESET             0x0002	/*  Reset CGT */
+#define IRQM_CGT_PAUSE             0x0008	/*  Pause CGT */
+#define IRQM_ADC_ABOUT_CNT         0x0010	/*  About Counter out */
+#define IRQM_ADC_DELAY_CNT         0x0020	/*  Delay Counter out */
+#define IRQM_ADC_SAMPLE_CNT	   0x0040	/*  ADC Sample Counter */
+#define IRQM_DAC1_UCNT             0x0080	/*  DAC1 Update Counter */
+#define IRQM_DAC2_UCNT             0x0100	/*  DAC2 Update Counter */
+#define IRQM_UTC1                  0x0200	/*  User TC1 out */
+#define IRQM_UTC1_INV              0x0400	/*  User TC1 out, inverted */
+#define IRQM_UTC2                  0x0800	/*  User TC2 out */
+#define IRQM_DIGITAL_IT            0x1000	/*  Digital Interrupt */
+#define IRQM_EXTERNAL_IT           0x2000	/*  External Interrupt */
+#define IRQM_ETRIG_RISING          0x4000	/*  External Trigger rising-edge */
+#define IRQM_ETRIG_FALLING         0x8000	/*  External Trigger falling-edge */
 
-// DMA Request Sources (LAS0)
-#define DMAS_DISABLED              0x0	// DMA Disabled
-#define DMAS_ADC_SCNT              0x1	// ADC Sample Counter
-#define DMAS_DAC1_UCNT             0x2	// D/A1 Update Counter
-#define DMAS_DAC2_UCNT             0x3	// D/A2 Update Counter
-#define DMAS_UTC1                  0x4	// User TC1 out
-#define DMAS_ADFIFO_HALF_FULL      0x8	// A/D FIFO half full
-#define DMAS_DAC1_FIFO_HALF_EMPTY  0x9	// D/A1 FIFO half empty
-#define DMAS_DAC2_FIFO_HALF_EMPTY  0xA	// D/A2 FIFO half empty
+/*  DMA Request Sources (LAS0) */
+#define DMAS_DISABLED              0x0	/*  DMA Disabled */
+#define DMAS_ADC_SCNT              0x1	/*  ADC Sample Counter */
+#define DMAS_DAC1_UCNT             0x2	/*  D/A1 Update Counter */
+#define DMAS_DAC2_UCNT             0x3	/*  D/A2 Update Counter */
+#define DMAS_UTC1                  0x4	/*  User TC1 out */
+#define DMAS_ADFIFO_HALF_FULL      0x8	/*  A/D FIFO half full */
+#define DMAS_DAC1_FIFO_HALF_EMPTY  0x9	/*  D/A1 FIFO half empty */
+#define DMAS_DAC2_FIFO_HALF_EMPTY  0xA	/*  D/A2 FIFO half empty */
 
-// DMA Local Addresses   (0x40000000+LAS1 offset)
-#define DMALADDR_ADC       0x40000000	// A/D FIFO
-#define DMALADDR_HDIN      0x40000004	// High Speed Digital Input FIFO
-#define DMALADDR_DAC1      0x40000008	// D/A1 FIFO
-#define DMALADDR_DAC2      0x4000000C	// D/A2 FIFO
+/*  DMA Local Addresses   (0x40000000+LAS1 offset) */
+#define DMALADDR_ADC       0x40000000	/*  A/D FIFO */
+#define DMALADDR_HDIN      0x40000004	/*  High Speed Digital Input FIFO */
+#define DMALADDR_DAC1      0x40000008	/*  D/A1 FIFO */
+#define DMALADDR_DAC2      0x4000000C	/*  D/A2 FIFO */
 
-// Port 0 compare modes (SetDIO0CompareMode)
-#define DIO_MODE_EVENT     0	// Event Mode
-#define DIO_MODE_MATCH     1	// Match Mode
+/*  Port 0 compare modes (SetDIO0CompareMode) */
+#define DIO_MODE_EVENT     0	/*  Event Mode */
+#define DIO_MODE_MATCH     1	/*  Match Mode */
 
-// Digital Table Enable (Port 1 disable)
-#define DTBL_DISABLE       0	// Enable Digital Table
-#define DTBL_ENABLE        1	// Disable Digital Table
+/*  Digital Table Enable (Port 1 disable) */
+#define DTBL_DISABLE       0	/*  Enable Digital Table */
+#define DTBL_ENABLE        1	/*  Disable Digital Table */
 
-// Sampling Signal for High Speed Digital Input (SetHdinStart)
-#define HDIN_SOFTWARE      0x0	// Software Trigger
-#define HDIN_ADC           0x1	// A/D Conversion Signal
-#define HDIN_UTC0          0x2	// User TC out 0
-#define HDIN_UTC1          0x3	// User TC out 1
-#define HDIN_UTC2          0x4	// User TC out 2
-#define HDIN_EPCLK         0x5	// External Pacer Clock
-#define HDIN_ETRG          0x6	// External Trigger
+/*  Sampling Signal for High Speed Digital Input (SetHdinStart) */
+#define HDIN_SOFTWARE      0x0	/*  Software Trigger */
+#define HDIN_ADC           0x1	/*  A/D Conversion Signal */
+#define HDIN_UTC0          0x2	/*  User TC out 0 */
+#define HDIN_UTC1          0x3	/*  User TC out 1 */
+#define HDIN_UTC2          0x4	/*  User TC out 2 */
+#define HDIN_EPCLK         0x5	/*  External Pacer Clock */
+#define HDIN_ETRG          0x6	/*  External Trigger */
 
-// Channel Gain Table / Channel Gain Latch
-#define CSC_LATCH          0	// Channel Gain Latch mode
-#define CSC_CGT            1	// Channel Gain Table mode
+/*  Channel Gain Table / Channel Gain Latch */
+#define CSC_LATCH          0	/*  Channel Gain Latch mode */
+#define CSC_CGT            1	/*  Channel Gain Table mode */
 
-// Channel Gain Table Pause Enable
-#define CGT_PAUSE_DISABLE  0	// Channel Gain Table Pause Disable
-#define CGT_PAUSE_ENABLE   1	// Channel Gain Table Pause Enable
+/*  Channel Gain Table Pause Enable */
+#define CGT_PAUSE_DISABLE  0	/*  Channel Gain Table Pause Disable */
+#define CGT_PAUSE_ENABLE   1	/*  Channel Gain Table Pause Enable */
 
-// DAC output type/range (p63)
-#define AOUT_UNIP5         0	// 0..+5 Volt
-#define AOUT_UNIP10        1	// 0..+10 Volt
-#define AOUT_BIP5          2	// -5..+5 Volt
-#define AOUT_BIP10         3	// -10..+10 Volt
+/*  DAC output type/range (p63) */
+#define AOUT_UNIP5         0	/*  0..+5 Volt */
+#define AOUT_UNIP10        1	/*  0..+10 Volt */
+#define AOUT_BIP5          2	/*  -5..+5 Volt */
+#define AOUT_BIP10         3	/*  -10..+10 Volt */
 
-// Ghannel Gain Table field definitions (p61)
-// Gain
+/*  Ghannel Gain Table field definitions (p61) */
+/*  Gain */
 #define GAIN1              0
 #define GAIN2              1
 #define GAIN4              2
@@ -398,15 +398,15 @@
 #define GAIN64             6
 #define GAIN128            7
 
-// Input range/polarity
-#define AIN_BIP5           0	// -5..+5 Volt
-#define AIN_BIP10          1	// -10..+10 Volt
-#define AIN_UNIP10         2	// 0..+10 Volt
+/*  Input range/polarity */
+#define AIN_BIP5           0	/*  -5..+5 Volt */
+#define AIN_BIP10          1	/*  -10..+10 Volt */
+#define AIN_UNIP10         2	/*  0..+10 Volt */
 
-// non referenced single ended select bit
-#define NRSE_AGND          0	// AGND referenced SE input
-#define NRSE_AINS          1	// AIN SENSE referenced SE input
+/*  non referenced single ended select bit */
+#define NRSE_AGND          0	/*  AGND referenced SE input */
+#define NRSE_AINS          1	/*  AIN SENSE referenced SE input */
 
-// single ended vs differential
-#define GND_SE		0	// Single-Ended
-#define GND_DIFF	1	// Differential
+/*  single ended vs differential */
+#define GND_SE		0	/*  Single-Ended */
+#define GND_DIFF	1	/*  Differential */
diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c
new file mode 100644
index 0000000..334ac57
--- /dev/null
+++ b/drivers/staging/comedi/drivers/rti800.c
@@ -0,0 +1,458 @@
+/*
+   comedi/drivers/rti800.c
+   Hardware driver for Analog Devices RTI-800/815 board
+
+   COMEDI - Linux Control and Measurement Device Interface
+   Copyright (C) 1998 David A. Schleef <ds@schleef.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.
+
+   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.
+
+ */
+/*
+Driver: rti800
+Description: Analog Devices RTI-800/815
+Author: ds
+Status: unknown
+Updated: Fri, 05 Sep 2008 14:50:44 +0100
+Devices: [Analog Devices] RTI-800 (rti800), RTI-815 (rti815)
+
+Configuration options:
+  [0] - I/O port base address
+  [1] - IRQ
+  [2] - A/D reference
+          0 = differential
+          1 = pseudodifferential (common)
+          2 = single-ended
+  [3] - A/D range
+          0 = [-10,10]
+          1 = [-5,5]
+          2 = [0,10]
+  [4] - A/D encoding
+          0 = two's complement
+          1 = straight binary
+  [5] - DAC 0 range
+          0 = [-10,10]
+          1 = [0,10]
+  [6] - DAC 0 encoding
+          0 = two's complement
+          1 = straight binary
+  [7] - DAC 1 range (same as DAC 0)
+  [8] - DAC 1 encoding (same as DAC 0)
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define RTI800_SIZE 16
+
+#define RTI800_CSR 0
+#define RTI800_MUXGAIN 1
+#define RTI800_CONVERT 2
+#define RTI800_ADCLO 3
+#define RTI800_ADCHI 4
+#define RTI800_DAC0LO 5
+#define RTI800_DAC0HI 6
+#define RTI800_DAC1LO 7
+#define RTI800_DAC1HI 8
+#define RTI800_CLRFLAGS 9
+#define RTI800_DI 10
+#define RTI800_DO 11
+#define RTI800_9513A_DATA 12
+#define RTI800_9513A_CNTRL 13
+#define RTI800_9513A_STATUS 13
+
+/*
+ * flags for CSR register
+ */
+
+#define RTI800_BUSY		0x80
+#define RTI800_DONE		0x40
+#define RTI800_OVERRUN		0x20
+#define RTI800_TCR		0x10
+#define RTI800_DMA_ENAB		0x08
+#define RTI800_INTR_TC		0x04
+#define RTI800_INTR_EC		0x02
+#define RTI800_INTR_OVRN	0x01
+
+#define Am9513_8BITBUS
+
+#define Am9513_output_control(a)	outb(a,dev->iobase+RTI800_9513A_CNTRL)
+#define Am9513_output_data(a)		outb(a,dev->iobase+RTI800_9513A_DATA)
+#define Am9513_input_data()		inb(dev->iobase+RTI800_9513A_DATA)
+#define Am9513_input_status()		inb(dev->iobase+RTI800_9513A_STATUS)
+
+#include "am9513.h"
+
+static const struct comedi_lrange range_rti800_ai_10_bipolar = { 4, {
+			BIP_RANGE(10),
+			BIP_RANGE(1),
+			BIP_RANGE(0.1),
+			BIP_RANGE(0.02)
+	}
+};
+static const struct comedi_lrange range_rti800_ai_5_bipolar = { 4, {
+			BIP_RANGE(5),
+			BIP_RANGE(0.5),
+			BIP_RANGE(0.05),
+			BIP_RANGE(0.01)
+	}
+};
+static const struct comedi_lrange range_rti800_ai_unipolar = { 4, {
+			UNI_RANGE(10),
+			UNI_RANGE(1),
+			UNI_RANGE(0.1),
+			UNI_RANGE(0.02)
+	}
+};
+
+struct rti800_board {
+
+	const char *name;
+	int has_ao;
+};
+
+static const struct rti800_board boardtypes[] = {
+	{"rti800", 0},
+	{"rti815", 1},
+};
+
+#define this_board ((const struct rti800_board *)dev->board_ptr)
+
+static int rti800_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int rti800_detach(struct comedi_device * dev);
+static struct comedi_driver driver_rti800 = {
+      driver_name:"rti800",
+      module:THIS_MODULE,
+      attach:rti800_attach,
+      detach:rti800_detach,
+      num_names:sizeof(boardtypes) / sizeof(struct rti800_board),
+      board_name:&boardtypes[0].name,
+      offset:sizeof(struct rti800_board),
+};
+
+COMEDI_INITCLEANUP(driver_rti800);
+
+static irqreturn_t rti800_interrupt(int irq, void *dev PT_REGS_ARG);
+
+struct rti800_private {
+	enum {
+		adc_diff, adc_pseudodiff, adc_singleended
+	} adc_mux;
+	enum {
+		adc_bipolar10, adc_bipolar5, adc_unipolar10
+	} adc_range;
+	enum {
+		adc_2comp, adc_straight
+	} adc_coding;
+	enum {
+		dac_bipolar10, dac_unipolar10
+	} dac0_range, dac1_range;
+	enum {
+		dac_2comp, dac_straight
+	} dac0_coding, dac1_coding;
+	const struct comedi_lrange *ao_range_type_list[2];
+	unsigned int ao_readback[2];
+	int muxgain_bits;
+};
+
+#define devpriv ((struct rti800_private *)dev->private)
+
+#define RTI800_TIMEOUT 100
+
+static irqreturn_t rti800_interrupt(int irq, void *dev PT_REGS_ARG)
+{
+	return IRQ_HANDLED;
+}
+
+// settling delay times in usec for different gains
+static const int gaindelay[] = { 10, 20, 40, 80 };
+
+static int rti800_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i, t;
+	int status;
+	int chan = CR_CHAN(insn->chanspec);
+	unsigned gain = CR_RANGE(insn->chanspec);
+	unsigned muxgain_bits;
+
+	inb(dev->iobase + RTI800_ADCHI);
+	outb(0, dev->iobase + RTI800_CLRFLAGS);
+
+	muxgain_bits = chan | (gain << 5);
+	if (muxgain_bits != devpriv->muxgain_bits) {
+		devpriv->muxgain_bits = muxgain_bits;
+		outb(devpriv->muxgain_bits, dev->iobase + RTI800_MUXGAIN);
+		/* without a delay here, the RTI_OVERRUN bit
+		 * gets set, and you will have an error. */
+		if (insn->n > 0) {
+			BUG_ON(gain >=
+				sizeof(gaindelay) / sizeof(gaindelay[0]));
+			comedi_udelay(gaindelay[gain]);
+		}
+	}
+
+	for (i = 0; i < insn->n; i++) {
+		outb(0, dev->iobase + RTI800_CONVERT);
+		for (t = RTI800_TIMEOUT; t; t--) {
+			status = inb(dev->iobase + RTI800_CSR);
+			if (status & RTI800_OVERRUN) {
+				rt_printk("rti800: a/d overrun\n");
+				outb(0, dev->iobase + RTI800_CLRFLAGS);
+				return -EIO;
+			}
+			if (status & RTI800_DONE)
+				break;
+			comedi_udelay(1);
+		}
+		if (t == 0) {
+			rt_printk("rti800: timeout\n");
+			return -ETIME;
+		}
+		data[i] = inb(dev->iobase + RTI800_ADCLO);
+		data[i] |= (0xf & inb(dev->iobase + RTI800_ADCHI)) << 8;
+
+		if (devpriv->adc_coding == adc_2comp) {
+			data[i] ^= 0x800;
+		}
+	}
+
+	return i;
+}
+
+static int rti800_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+
+	for (i = 0; i < insn->n; i++)
+		data[i] = devpriv->ao_readback[chan];
+
+	return i;
+}
+
+static int rti800_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int chan = CR_CHAN(insn->chanspec);
+	int d;
+	int i;
+
+	for (i = 0; i < insn->n; i++) {
+		devpriv->ao_readback[chan] = d = data[i];
+		if (devpriv->dac0_coding == dac_2comp) {
+			d ^= 0x800;
+		}
+		outb(d & 0xff,
+			dev->iobase + (chan ? RTI800_DAC1LO : RTI800_DAC0LO));
+		outb(d >> 8,
+			dev->iobase + (chan ? RTI800_DAC1HI : RTI800_DAC0HI));
+	}
+	return i;
+}
+
+static int rti800_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+	data[1] = inb(dev->iobase + RTI800_DI);
+	return 2;
+}
+
+static int rti800_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= data[0] & data[1];
+		/* Outputs are inverted... */
+		outb(s->state ^ 0xff, dev->iobase + RTI800_DO);
+	}
+
+	data[1] = s->state;
+
+	return 2;
+}
+
+/*
+   options[0] - I/O port
+   options[1] - irq
+   options[2] - a/d mux
+   	0=differential, 1=pseudodiff, 2=single
+   options[3] - a/d range
+   	0=bipolar10, 1=bipolar5, 2=unipolar10
+   options[4] - a/d coding
+   	0=2's comp, 1=straight binary
+   options[5] - dac0 range
+   	0=bipolar10, 1=unipolar10
+   options[6] - dac0 coding
+   	0=2's comp, 1=straight binary
+   options[7] - dac1 range
+   options[8] - dac1 coding
+ */
+
+static int rti800_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	unsigned int irq;
+	unsigned long iobase;
+	int ret;
+	struct comedi_subdevice *s;
+
+	iobase = it->options[0];
+	printk("comedi%d: rti800: 0x%04lx ", dev->minor, iobase);
+	if (!request_region(iobase, RTI800_SIZE, "rti800")) {
+		printk("I/O port conflict\n");
+		return -EIO;
+	}
+	dev->iobase = iobase;
+
+#ifdef DEBUG
+	printk("fingerprint=%x,%x,%x,%x,%x ",
+		inb(dev->iobase + 0),
+		inb(dev->iobase + 1),
+		inb(dev->iobase + 2),
+		inb(dev->iobase + 3), inb(dev->iobase + 4));
+#endif
+
+	outb(0, dev->iobase + RTI800_CSR);
+	inb(dev->iobase + RTI800_ADCHI);
+	outb(0, dev->iobase + RTI800_CLRFLAGS);
+
+	irq = it->options[1];
+	if (irq) {
+		printk("( irq = %u )", irq);
+		if ((ret = comedi_request_irq(irq, rti800_interrupt, 0,
+					"rti800", dev)) < 0) {
+			printk(" Failed to allocate IRQ\n");
+			return ret;
+		}
+		dev->irq = irq;
+	} else {
+		printk("( no irq )");
+	}
+
+	dev->board_name = this_board->name;
+
+	if ((ret = alloc_subdevices(dev, 4)) < 0)
+		return ret;
+	if ((ret = alloc_private(dev, sizeof(struct rti800_private))) < 0)
+		return ret;
+
+	devpriv->adc_mux = it->options[2];
+	devpriv->adc_range = it->options[3];
+	devpriv->adc_coding = it->options[4];
+	devpriv->dac0_range = it->options[5];
+	devpriv->dac0_coding = it->options[6];
+	devpriv->dac1_range = it->options[7];
+	devpriv->dac1_coding = it->options[8];
+	devpriv->muxgain_bits = -1;
+
+	s = dev->subdevices + 0;
+	/* ai subdevice */
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE | SDF_GROUND;
+	s->n_chan = (devpriv->adc_mux ? 16 : 8);
+	s->insn_read = rti800_ai_insn_read;
+	s->maxdata = 0xfff;
+	switch (devpriv->adc_range) {
+	case adc_bipolar10:
+		s->range_table = &range_rti800_ai_10_bipolar;
+		break;
+	case adc_bipolar5:
+		s->range_table = &range_rti800_ai_5_bipolar;
+		break;
+	case adc_unipolar10:
+		s->range_table = &range_rti800_ai_unipolar;
+		break;
+	}
+
+	s++;
+	if (this_board->has_ao) {
+		/* ao subdevice (only on rti815) */
+		s->type = COMEDI_SUBD_AO;
+		s->subdev_flags = SDF_WRITABLE;
+		s->n_chan = 2;
+		s->insn_read = rti800_ao_insn_read;
+		s->insn_write = rti800_ao_insn_write;
+		s->maxdata = 0xfff;
+		s->range_table_list = devpriv->ao_range_type_list;
+		switch (devpriv->dac0_range) {
+		case dac_bipolar10:
+			devpriv->ao_range_type_list[0] = &range_bipolar10;
+			break;
+		case dac_unipolar10:
+			devpriv->ao_range_type_list[0] = &range_unipolar10;
+			break;
+		}
+		switch (devpriv->dac1_range) {
+		case dac_bipolar10:
+			devpriv->ao_range_type_list[1] = &range_bipolar10;
+			break;
+		case dac_unipolar10:
+			devpriv->ao_range_type_list[1] = &range_unipolar10;
+			break;
+		}
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	s++;
+	/* di */
+	s->type = COMEDI_SUBD_DI;
+	s->subdev_flags = SDF_READABLE;
+	s->n_chan = 8;
+	s->insn_bits = rti800_di_insn_bits;
+	s->maxdata = 1;
+	s->range_table = &range_digital;
+
+	s++;
+	/* do */
+	s->type = COMEDI_SUBD_DO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->n_chan = 8;
+	s->insn_bits = rti800_do_insn_bits;
+	s->maxdata = 1;
+	s->range_table = &range_digital;
+
+/* don't yet know how to deal with counter/timers */
+#if 0
+	s++;
+	/* do */
+	s->type = COMEDI_SUBD_TIMER;
+#endif
+
+	printk("\n");
+
+	return 0;
+}
+
+static int rti800_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: rti800: remove\n", dev->minor);
+
+	if (dev->iobase)
+		release_region(dev->iobase, RTI800_SIZE);
+
+	if (dev->irq)
+		comedi_free_irq(dev->irq, dev);
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/rti802.c b/drivers/staging/comedi/drivers/rti802.c
new file mode 100644
index 0000000..cc2c385
--- /dev/null
+++ b/drivers/staging/comedi/drivers/rti802.c
@@ -0,0 +1,151 @@
+/*
+   comedi/drivers/rti802.c
+   Hardware driver for Analog Devices RTI-802 board
+
+   COMEDI - Linux Control and Measurement Device Interface
+   Copyright (C) 1999 Anders Blomdell <anders.blomdell@control.lth.se>
+
+   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.
+
+ */
+/*
+Driver: rti802
+Description: Analog Devices RTI-802
+Author: Anders Blomdell <anders.blomdell@control.lth.se>
+Devices: [Analog Devices] RTI-802 (rti802)
+Status: works
+
+Configuration Options:
+    [0] - i/o base
+    [1] - unused
+    [2] - dac#0  0=two's comp, 1=straight
+    [3] - dac#0  0=bipolar, 1=unipolar
+    [4] - dac#1 ...
+    ...
+    [17] - dac#7 ...
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define RTI802_SIZE 4
+
+#define RTI802_SELECT 0
+#define RTI802_DATALOW 1
+#define RTI802_DATAHIGH 2
+
+static int rti802_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int rti802_detach(struct comedi_device * dev);
+static struct comedi_driver driver_rti802 = {
+      driver_name:"rti802",
+      module:THIS_MODULE,
+      attach:rti802_attach,
+      detach:rti802_detach,
+};
+
+COMEDI_INITCLEANUP(driver_rti802);
+
+struct rti802_private {
+	enum {
+		dac_2comp, dac_straight
+	} dac_coding[8];
+	const struct comedi_lrange *range_type_list[8];
+	unsigned int ao_readback[8];
+};
+
+#define devpriv ((struct rti802_private *)dev->private)
+
+static int rti802_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+
+	for (i = 0; i < insn->n; i++)
+		data[i] = devpriv->ao_readback[CR_CHAN(insn->chanspec)];
+
+	return i;
+}
+
+static int rti802_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i, d;
+	int chan = CR_CHAN(insn->chanspec);
+
+	for (i = 0; i < insn->n; i++) {
+		d = devpriv->ao_readback[chan] = data[i];
+		if (devpriv->dac_coding[chan] == dac_2comp)
+			d ^= 0x800;
+		outb(chan, dev->iobase + RTI802_SELECT);
+		outb(d & 0xff, dev->iobase + RTI802_DATALOW);
+		outb(d >> 8, dev->iobase + RTI802_DATAHIGH);
+	}
+	return i;
+}
+
+static int rti802_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	int i;
+	unsigned long iobase;
+
+	iobase = it->options[0];
+	printk("comedi%d: rti802: 0x%04lx ", dev->minor, iobase);
+	if (!request_region(iobase, RTI802_SIZE, "rti802")) {
+		printk("I/O port conflict\n");
+		return -EIO;
+	}
+	dev->iobase = iobase;
+
+	dev->board_name = "rti802";
+
+	if (alloc_subdevices(dev, 1) < 0
+		|| alloc_private(dev, sizeof(struct rti802_private))) {
+		return -ENOMEM;
+	}
+
+	s = dev->subdevices;
+	/* ao subdevice */
+	s->type = COMEDI_SUBD_AO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->maxdata = 0xfff;
+	s->n_chan = 8;
+	s->insn_read = rti802_ao_insn_read;
+	s->insn_write = rti802_ao_insn_write;
+	s->range_table_list = devpriv->range_type_list;
+
+	for (i = 0; i < 8; i++) {
+		devpriv->dac_coding[i] = (it->options[3 + 2 * i])
+			? (dac_straight)
+			: (dac_2comp);
+		devpriv->range_type_list[i] = (it->options[2 + 2 * i])
+			? &range_unipolar10 : &range_bipolar10;
+	}
+
+	printk("\n");
+
+	return 0;
+}
+
+static int rti802_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: rti802: remove\n", dev->minor);
+
+	if (dev->iobase)
+		release_region(dev->iobase, RTI802_SIZE);
+
+	return 0;
+}
diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c
new file mode 100644
index 0000000..a7b6f71
--- /dev/null
+++ b/drivers/staging/comedi/drivers/s526.c
@@ -0,0 +1,977 @@
+/*
+    comedi/drivers/s526.c
+    Sensoray s526 Comedi driver
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: s526
+Description: Sensoray 526 driver
+Devices: [Sensoray] 526 (s526)
+Author: Richie
+	Everett Wang <everett.wang@everteq.com>
+Updated: Thu, 14 Sep. 2006
+Status: experimental
+
+Encoder works
+Analog input works
+Analog output works
+PWM output works
+Commands are not supported yet.
+
+Configuration Options:
+
+comedi_config /dev/comedi0 s526 0x2C0,0x3
+
+*/
+
+#include "../comedidev.h"
+#include <linux/ioport.h>
+
+#define S526_SIZE 64
+
+#define S526_START_AI_CONV	0
+#define S526_AI_READ		0
+
+/* Ports */
+#define S526_IOSIZE 0x40
+#define S526_NUM_PORTS 27
+
+/* registers */
+#define REG_TCR 0x00
+#define REG_WDC 0x02
+#define REG_DAC 0x04
+#define REG_ADC 0x06
+#define REG_ADD 0x08
+#define REG_DIO 0x0A
+#define REG_IER 0x0C
+#define REG_ISR 0x0E
+#define REG_MSC 0x10
+#define REG_C0L 0x12
+#define REG_C0H 0x14
+#define REG_C0M 0x16
+#define REG_C0C 0x18
+#define REG_C1L 0x1A
+#define REG_C1H 0x1C
+#define REG_C1M 0x1E
+#define REG_C1C 0x20
+#define REG_C2L 0x22
+#define REG_C2H 0x24
+#define REG_C2M 0x26
+#define REG_C2C 0x28
+#define REG_C3L 0x2A
+#define REG_C3H 0x2C
+#define REG_C3M 0x2E
+#define REG_C3C 0x30
+#define REG_EED 0x32
+#define REG_EEC 0x34
+
+static const int s526_ports[] = {
+	REG_TCR,
+	REG_WDC,
+	REG_DAC,
+	REG_ADC,
+	REG_ADD,
+	REG_DIO,
+	REG_IER,
+	REG_ISR,
+	REG_MSC,
+	REG_C0L,
+	REG_C0H,
+	REG_C0M,
+	REG_C0C,
+	REG_C1L,
+	REG_C1H,
+	REG_C1M,
+	REG_C1C,
+	REG_C2L,
+	REG_C2H,
+	REG_C2M,
+	REG_C2C,
+	REG_C3L,
+	REG_C3H,
+	REG_C3M,
+	REG_C3C,
+	REG_EED,
+	REG_EEC
+};
+
+struct counter_mode_register_t {
+	unsigned short coutSource:1;
+	unsigned short coutPolarity:1;
+	unsigned short autoLoadResetRcap:3;
+	unsigned short hwCtEnableSource:2;
+	unsigned short ctEnableCtrl:2;
+	unsigned short clockSource:2;
+	unsigned short countDir:1;
+	unsigned short countDirCtrl:1;
+	unsigned short outputRegLatchCtrl:1;
+	unsigned short preloadRegSel:1;
+	unsigned short reserved:1;
+};
+
+union {
+	struct counter_mode_register_t reg;
+	unsigned short value;
+} cmReg;
+
+#define MAX_GPCT_CONFIG_DATA 6
+
+/* Different Application Classes for GPCT Subdevices */
+/* The list is not exhaustive and needs discussion! */
+enum S526_GPCT_APP_CLASS {
+	CountingAndTimeMeasurement,
+	SinglePulseGeneration,
+	PulseTrainGeneration,
+	PositionMeasurement,
+	Miscellaneous
+};
+
+/* Config struct for different GPCT subdevice Application Classes and
+   their options
+*/
+struct s526GPCTConfig {
+	enum S526_GPCT_APP_CLASS app;
+	int data[MAX_GPCT_CONFIG_DATA];
+};
+
+/*
+ * Board descriptions for two imaginary boards.  Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct s526_board {
+	const char *name;
+	int gpct_chans;
+	int gpct_bits;
+	int ad_chans;
+	int ad_bits;
+	int da_chans;
+	int da_bits;
+	int have_dio;
+};
+
+static const struct s526_board s526_boards[] = {
+	{
+	      name:	"s526",
+	      gpct_chans:4,
+	      gpct_bits:24,
+	      ad_chans:8,
+	      ad_bits:	16,
+	      da_chans:4,
+	      da_bits:	16,
+	      have_dio:1,
+		}
+};
+
+#define ADDR_REG(reg) (dev->iobase + (reg))
+#define ADDR_CHAN_REG(reg, chan) (dev->iobase + (reg) + (chan) * 8)
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct s526_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver.  If
+   several hardware drivers keep similar information in this structure,
+   feel free to suggest moving the variable to the struct comedi_device struct.  */
+struct s526_private {
+
+	int data;
+
+	/* would be useful for a PCI device */
+	struct pci_dev *pci_dev;
+
+	/* Used for AO readback */
+	unsigned int ao_readback[2];
+
+	struct s526GPCTConfig s526_gpct_config[4];
+	unsigned short s526_ai_config;
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct s526_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int s526_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int s526_detach(struct comedi_device * dev);
+static struct comedi_driver driver_s526 = {
+      driver_name:"s526",
+      module:THIS_MODULE,
+      attach:s526_attach,
+      detach:s526_detach,
+/* It is not necessary to implement the following members if you are
+ * writing a driver for a ISA PnP or PCI card */
+	/* Most drivers will support multiple types of boards by
+	 * having an array of board structures.  These were defined
+	 * in s526_boards[] above.  Note that the element 'name'
+	 * was first in the structure -- Comedi uses this fact to
+	 * extract the name of the board without knowing any details
+	 * about the structure except for its length.
+	 * When a device is attached (by comedi_config), the name
+	 * of the device is given to Comedi, and Comedi tries to
+	 * match it by going through the list of board names.  If
+	 * there is a match, the address of the pointer is put
+	 * into dev->board_ptr and driver->attach() is called.
+	 *
+	 * Note that these are not necessary if you can determine
+	 * the type of board in software.  ISA PnP, PCI, and PCMCIA
+	 * devices are such boards.
+	 */
+      board_name:&s526_boards[0].name,
+      offset:sizeof(struct s526_board),
+      num_names:sizeof(s526_boards) / sizeof(struct s526_board),
+};
+
+static int s526_gpct_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int s526_gpct_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int s526_gpct_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int s526_ai_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int s526_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int s526_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int s526_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int s526_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int s526_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board.  If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int s526_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+	int iobase;
+	int i, n;
+//      short value;
+//      int subdev_channel = 0;
+
+	printk("comedi%d: s526: ", dev->minor);
+
+	iobase = it->options[0];
+	if (!iobase || !request_region(iobase, S526_IOSIZE, thisboard->name)) {
+		comedi_error(dev, "I/O port conflict");
+		return -EIO;
+	}
+	dev->iobase = iobase;
+
+	printk("iobase=0x%lx\n", dev->iobase);
+
+	/*** make it a little quieter, exw, 8/29/06
+	for (i = 0; i < S526_NUM_PORTS; i++) {
+		printk("0x%02x: 0x%04x\n", ADDR_REG(s526_ports[i]), inw(ADDR_REG(s526_ports[i])));
+	}
+	***/
+
+/*
+ * Initialize dev->board_name.  Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+	dev->board_ptr = &s526_boards[0];
+
+	dev->board_name = thisboard->name;
+
+/*
+ * Allocate the private structure area.  alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+	if (alloc_private(dev, sizeof(struct s526_private)) < 0)
+		return -ENOMEM;
+
+/*
+ * Allocate the subdevice structures.  alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+	dev->n_subdevices = 4;
+	if (alloc_subdevices(dev, dev->n_subdevices) < 0)
+		return -ENOMEM;
+
+	s = dev->subdevices + 0;
+	/* GENERAL-PURPOSE COUNTER/TIME (GPCT) */
+	s->type = COMEDI_SUBD_COUNTER;
+	s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL;
+	/* KG: What does SDF_LSAMPL (see multiq3.c) mean? */
+	s->n_chan = thisboard->gpct_chans;
+	s->maxdata = 0x00ffffff;	/* 24 bit counter */
+	s->insn_read = s526_gpct_rinsn;
+	s->insn_config = s526_gpct_insn_config;
+	s->insn_write = s526_gpct_winsn;
+
+	/* Command are not implemented yet, however they are necessary to
+	   allocate the necessary memory for the comedi_async struct (used
+	   to trigger the GPCT in case of pulsegenerator function */
+	//s->do_cmd = s526_gpct_cmd;
+	//s->do_cmdtest = s526_gpct_cmdtest;
+	//s->cancel = s526_gpct_cancel;
+
+	s = dev->subdevices + 1;
+	//dev->read_subdev=s;
+	/* analog input subdevice */
+	s->type = COMEDI_SUBD_AI;
+	/* we support differential */
+	s->subdev_flags = SDF_READABLE | SDF_DIFF;
+	/* channels 0 to 7 are the regular differential inputs */
+	/* channel 8 is "reference 0" (+10V), channel 9 is "reference 1" (0V) */
+	s->n_chan = 10;
+	s->maxdata = 0xffff;
+	s->range_table = &range_bipolar10;
+	s->len_chanlist = 16;	/* This is the maximum chanlist length that
+				   the board can handle */
+	s->insn_read = s526_ai_rinsn;
+	s->insn_config = s526_ai_insn_config;
+
+	s = dev->subdevices + 2;
+	/* analog output subdevice */
+	s->type = COMEDI_SUBD_AO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->n_chan = 4;
+	s->maxdata = 0xffff;
+	s->range_table = &range_bipolar10;
+	s->insn_write = s526_ao_winsn;
+	s->insn_read = s526_ao_rinsn;
+
+	s = dev->subdevices + 3;
+	/* digital i/o subdevice */
+	if (thisboard->have_dio) {
+		s->type = COMEDI_SUBD_DIO;
+		s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+		s->n_chan = 2;
+		s->maxdata = 1;
+		s->range_table = &range_digital;
+		s->insn_bits = s526_dio_insn_bits;
+		s->insn_config = s526_dio_insn_config;
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	printk("attached\n");
+
+	return 1;
+
+#if 0
+	// Example of Counter Application
+	//One-shot (software trigger)
+	cmReg.reg.coutSource = 0;	// out RCAP
+	cmReg.reg.coutPolarity = 1;	// Polarity inverted
+	cmReg.reg.autoLoadResetRcap = 1;	// Auto load 0:disabled, 1:enabled
+	cmReg.reg.hwCtEnableSource = 3;	// NOT RCAP
+	cmReg.reg.ctEnableCtrl = 2;	// Hardware
+	cmReg.reg.clockSource = 2;	// Internal
+	cmReg.reg.countDir = 1;	// Down
+	cmReg.reg.countDirCtrl = 1;	// Software
+	cmReg.reg.outputRegLatchCtrl = 0;	// latch on read
+	cmReg.reg.preloadRegSel = 0;	// PR0
+	cmReg.reg.reserved = 0;
+
+	outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+
+	outw(0x0001, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+	outw(0x3C68, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+
+	outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel));	// Reset the counter
+	outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel));	// Load the counter from PR0
+
+	outw(0x0008, ADDR_CHAN_REG(REG_C0C, subdev_channel));	// Reset RCAP (fires one-shot)
+
+#else
+
+	// Set Counter Mode Register
+	cmReg.reg.coutSource = 0;	// out RCAP
+	cmReg.reg.coutPolarity = 0;	// Polarity inverted
+	cmReg.reg.autoLoadResetRcap = 0;	// Auto load disabled
+	cmReg.reg.hwCtEnableSource = 2;	// NOT RCAP
+	cmReg.reg.ctEnableCtrl = 1;	// 1: Software,  >1 : Hardware
+	cmReg.reg.clockSource = 3;	// x4
+	cmReg.reg.countDir = 0;	// up
+	cmReg.reg.countDirCtrl = 0;	// quadrature
+	cmReg.reg.outputRegLatchCtrl = 0;	// latch on read
+	cmReg.reg.preloadRegSel = 0;	// PR0
+	cmReg.reg.reserved = 0;
+
+	n = 0;
+	printk("Mode reg=0x%04x, 0x%04lx\n", cmReg.value, ADDR_CHAN_REG(REG_C0M,
+			n));
+	outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, n));
+	udelay(1000);
+	printk("Read back mode reg=0x%04x\n", inw(ADDR_CHAN_REG(REG_C0M, n)));
+
+	// Load the pre-laod register high word
+//                      value = (short) (0x55);
+//                      outw(value, ADDR_CHAN_REG(REG_C0H, n));
+
+	// Load the pre-laod register low word
+//                      value = (short)(0xaa55);
+//                      outw(value, ADDR_CHAN_REG(REG_C0L, n));
+
+	// Write the Counter Control Register
+//                      outw(value, ADDR_CHAN_REG(REG_C0C, 0));
+
+	// Reset the counter if it is software preload
+	if (cmReg.reg.autoLoadResetRcap == 0) {
+		outw(0x8000, ADDR_CHAN_REG(REG_C0C, n));	// Reset the counter
+		outw(0x4000, ADDR_CHAN_REG(REG_C0C, n));	// Load the counter from PR0
+	}
+
+	outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, n));
+	udelay(1000);
+	printk("Read back mode reg=0x%04x\n", inw(ADDR_CHAN_REG(REG_C0M, n)));
+
+#endif
+	printk("Current registres:\n");
+
+	for (i = 0; i < S526_NUM_PORTS; i++) {
+		printk("0x%02lx: 0x%04x\n", ADDR_REG(s526_ports[i]),
+			inw(ADDR_REG(s526_ports[i])));
+	}
+	return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device.  It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach().  dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int s526_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: s526: remove\n", dev->minor);
+
+	if (dev->iobase > 0)
+		release_region(dev->iobase, S526_IOSIZE);
+
+	return 0;
+}
+
+static int s526_gpct_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;			// counts the Data
+	int counter_channel = CR_CHAN(insn->chanspec);
+	unsigned short datalow;
+	unsigned short datahigh;
+
+	// Check if (n > 0)
+	if (insn->n <= 0) {
+		printk("s526: INSN_READ: n should be > 0\n");
+		return -EINVAL;
+	}
+	// Read the low word first
+	for (i = 0; i < insn->n; i++) {
+		datalow = inw(ADDR_CHAN_REG(REG_C0L, counter_channel));
+		datahigh = inw(ADDR_CHAN_REG(REG_C0H, counter_channel));
+		data[i] = (int)(datahigh & 0x00FF);
+		data[i] = (data[i] << 16) | (datalow & 0xFFFF);
+//              printk("s526 GPCT[%d]: %x(0x%04x, 0x%04x)\n", counter_channel, data[i], datahigh, datalow);
+	}
+	return i;
+}
+
+static int s526_gpct_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int subdev_channel = CR_CHAN(insn->chanspec);	// Unpack chanspec
+	int i;
+	short value;
+
+//        printk("s526: GPCT_INSN_CONFIG: Configuring Channel %d\n", subdev_channel);
+
+	for (i = 0; i < MAX_GPCT_CONFIG_DATA; i++) {
+		devpriv->s526_gpct_config[subdev_channel].data[i] =
+			insn->data[i];
+//              printk("data[%d]=%x\n", i, insn->data[i]);
+	}
+
+	// Check what type of Counter the user requested, data[0] contains
+	// the Application type
+	switch (insn->data[0]) {
+	case INSN_CONFIG_GPCT_QUADRATURE_ENCODER:
+		/*
+		   data[0]: Application Type
+		   data[1]: Counter Mode Register Value
+		   data[2]: Pre-load Register Value
+		   data[3]: Conter Control Register
+		 */
+		printk("s526: GPCT_INSN_CONFIG: Configuring Encoder\n");
+		devpriv->s526_gpct_config[subdev_channel].app =
+			PositionMeasurement;
+
+/*
+			// Example of Counter Application
+			//One-shot (software trigger)
+			cmReg.reg.coutSource		= 0; // out RCAP
+			cmReg.reg.coutPolarity		= 1; // Polarity inverted
+			cmReg.reg.autoLoadResetRcap	= 0; // Auto load disabled
+			cmReg.reg.hwCtEnableSource	= 3; // NOT RCAP
+			cmReg.reg.ctEnableCtrl		= 2; // Hardware
+			cmReg.reg.clockSource		= 2; // Internal
+			cmReg.reg.countDir		= 1; // Down
+			cmReg.reg.countDirCtrl		= 1; // Software
+			cmReg.reg.outputRegLatchCtrl	= 0; // latch on read
+			cmReg.reg.preloadRegSel		= 0; // PR0
+			cmReg.reg.reserved		= 0;
+
+			outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+
+			outw(0x0001, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+			outw(0x3C68, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+
+			outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel));	// Reset the counter
+			outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel));	// Load the counter from PR0
+
+			outw(0x0008, ADDR_CHAN_REG(REG_C0C, subdev_channel));  // Reset RCAP (fires one-shot)
+
+*/
+
+#if 1
+		// Set Counter Mode Register
+		cmReg.reg.coutSource = 0;	// out RCAP
+		cmReg.reg.coutPolarity = 0;	// Polarity inverted
+		cmReg.reg.autoLoadResetRcap = 0;	// Auto load disabled
+		cmReg.reg.hwCtEnableSource = 2;	// NOT RCAP
+		cmReg.reg.ctEnableCtrl = 1;	// 1: Software,  >1 : Hardware
+		cmReg.reg.clockSource = 3;	// x4
+		cmReg.reg.countDir = 0;	// up
+		cmReg.reg.countDirCtrl = 0;	// quadrature
+		cmReg.reg.outputRegLatchCtrl = 0;	// latch on read
+		cmReg.reg.preloadRegSel = 0;	// PR0
+		cmReg.reg.reserved = 0;
+
+		// Set Counter Mode Register
+//                      printk("s526: Counter Mode register=%x\n", cmReg.value);
+		outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+
+		// Reset the counter if it is software preload
+		if (cmReg.reg.autoLoadResetRcap == 0) {
+			outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel));	// Reset the counter
+//                              outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel));   // Load the counter from PR0
+		}
+#else
+		cmReg.reg.countDirCtrl = 0;	// 0 quadrature, 1 software control
+
+		// data[1] contains GPCT_X1, GPCT_X2 or GPCT_X4
+		if (insn->data[1] == GPCT_X2) {
+			cmReg.reg.clockSource = 1;
+		} else if (insn->data[1] == GPCT_X4) {
+			cmReg.reg.clockSource = 2;
+		} else {
+			cmReg.reg.clockSource = 0;
+		}
+
+		// When to take into account the indexpulse:
+		if (insn->data[2] == GPCT_IndexPhaseLowLow) {
+		} else if (insn->data[2] == GPCT_IndexPhaseLowHigh) {
+		} else if (insn->data[2] == GPCT_IndexPhaseHighLow) {
+		} else if (insn->data[2] == GPCT_IndexPhaseHighHigh) {
+		}
+		// Take into account the index pulse?
+		if (insn->data[3] == GPCT_RESET_COUNTER_ON_INDEX)
+			cmReg.reg.autoLoadResetRcap = 4;	// Auto load with INDEX^
+
+		// Set Counter Mode Register
+		cmReg.value = (short) (insn->data[1] & 0xFFFF);
+		outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+
+		// Load the pre-laod register high word
+		value = (short) ((insn->data[2] >> 16) & 0xFFFF);
+		outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+
+		// Load the pre-laod register low word
+		value = (short) (insn->data[2] & 0xFFFF);
+		outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+
+		// Write the Counter Control Register
+		if (insn->data[3] != 0) {
+			value = (short) (insn->data[3] & 0xFFFF);
+			outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel));
+		}
+		// Reset the counter if it is software preload
+		if (cmReg.reg.autoLoadResetRcap == 0) {
+			outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel));	// Reset the counter
+			outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel));	// Load the counter from PR0
+		}
+#endif
+		break;
+
+	case INSN_CONFIG_GPCT_SINGLE_PULSE_GENERATOR:
+		/*
+		   data[0]: Application Type
+		   data[1]: Counter Mode Register Value
+		   data[2]: Pre-load Register 0 Value
+		   data[3]: Pre-load Register 1 Value
+		   data[4]: Conter Control Register
+		 */
+		printk("s526: GPCT_INSN_CONFIG: Configuring SPG\n");
+		devpriv->s526_gpct_config[subdev_channel].app =
+			SinglePulseGeneration;
+
+		// Set Counter Mode Register
+		cmReg.value = (short) (insn->data[1] & 0xFFFF);
+		cmReg.reg.preloadRegSel = 0;	// PR0
+		outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+
+		// Load the pre-laod register 0 high word
+		value = (short) ((insn->data[2] >> 16) & 0xFFFF);
+		outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+
+		// Load the pre-laod register 0 low word
+		value = (short) (insn->data[2] & 0xFFFF);
+		outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+
+		// Set Counter Mode Register
+		cmReg.value = (short) (insn->data[1] & 0xFFFF);
+		cmReg.reg.preloadRegSel = 1;	// PR1
+		outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+
+		// Load the pre-laod register 1 high word
+		value = (short) ((insn->data[3] >> 16) & 0xFFFF);
+		outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+
+		// Load the pre-laod register 1 low word
+		value = (short) (insn->data[3] & 0xFFFF);
+		outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+
+		// Write the Counter Control Register
+		if (insn->data[3] != 0) {
+			value = (short) (insn->data[3] & 0xFFFF);
+			outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel));
+		}
+		break;
+
+	case INSN_CONFIG_GPCT_PULSE_TRAIN_GENERATOR:
+		/*
+		   data[0]: Application Type
+		   data[1]: Counter Mode Register Value
+		   data[2]: Pre-load Register 0 Value
+		   data[3]: Pre-load Register 1 Value
+		   data[4]: Conter Control Register
+		 */
+		printk("s526: GPCT_INSN_CONFIG: Configuring PTG\n");
+		devpriv->s526_gpct_config[subdev_channel].app =
+			PulseTrainGeneration;
+
+		// Set Counter Mode Register
+		cmReg.value = (short) (insn->data[1] & 0xFFFF);
+		cmReg.reg.preloadRegSel = 0;	// PR0
+		outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+
+		// Load the pre-laod register 0 high word
+		value = (short) ((insn->data[2] >> 16) & 0xFFFF);
+		outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+
+		// Load the pre-laod register 0 low word
+		value = (short) (insn->data[2] & 0xFFFF);
+		outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+
+		// Set Counter Mode Register
+		cmReg.value = (short) (insn->data[1] & 0xFFFF);
+		cmReg.reg.preloadRegSel = 1;	// PR1
+		outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+
+		// Load the pre-laod register 1 high word
+		value = (short) ((insn->data[3] >> 16) & 0xFFFF);
+		outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+
+		// Load the pre-laod register 1 low word
+		value = (short) (insn->data[3] & 0xFFFF);
+		outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+
+		// Write the Counter Control Register
+		if (insn->data[3] != 0) {
+			value = (short) (insn->data[3] & 0xFFFF);
+			outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel));
+		}
+		break;
+
+	default:
+		printk("s526: unsupported GPCT_insn_config\n");
+		return -EINVAL;
+		break;
+	}
+
+	return insn->n;
+}
+
+static int s526_gpct_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int subdev_channel = CR_CHAN(insn->chanspec);	// Unpack chanspec
+	short value;
+
+	printk("s526: GPCT_INSN_WRITE on channel %d\n", subdev_channel);
+	cmReg.value = inw(ADDR_CHAN_REG(REG_C0M, subdev_channel));
+	printk("s526: Counter Mode Register: %x\n", cmReg.value);
+	// Check what Application of Counter this channel is configured for
+	switch (devpriv->s526_gpct_config[subdev_channel].app) {
+	case PositionMeasurement:
+		printk("S526: INSN_WRITE: PM\n");
+		outw(0xFFFF & ((*data) >> 16), ADDR_CHAN_REG(REG_C0H,
+				subdev_channel));
+		outw(0xFFFF & (*data), ADDR_CHAN_REG(REG_C0L, subdev_channel));
+		break;
+
+	case SinglePulseGeneration:
+		printk("S526: INSN_WRITE: SPG\n");
+		outw(0xFFFF & ((*data) >> 16), ADDR_CHAN_REG(REG_C0H,
+				subdev_channel));
+		outw(0xFFFF & (*data), ADDR_CHAN_REG(REG_C0L, subdev_channel));
+		break;
+
+	case PulseTrainGeneration:
+		/* data[0] contains the PULSE_WIDTH
+		   data[1] contains the PULSE_PERIOD
+		   @pre PULSE_PERIOD > PULSE_WIDTH > 0
+		   The above periods must be expressed as a multiple of the
+		   pulse frequency on the selected source
+		 */
+		printk("S526: INSN_WRITE: PTG\n");
+		if ((insn->data[1] > insn->data[0]) && (insn->data[0] > 0)) {
+			(devpriv->s526_gpct_config[subdev_channel]).data[0] =
+				insn->data[0];
+			(devpriv->s526_gpct_config[subdev_channel]).data[1] =
+				insn->data[1];
+		} else {
+			printk("%d \t %d\n", insn->data[1], insn->data[2]);
+			printk("s526: INSN_WRITE: PTG: Problem with Pulse params\n");
+			return -EINVAL;
+		}
+
+		value = (short) ((*data >> 16) & 0xFFFF);
+		outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+		value = (short) (*data & 0xFFFF);
+		outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+		break;
+	default:		// Impossible
+		printk("s526: INSN_WRITE: Functionality %d not implemented yet\n", devpriv->s526_gpct_config[subdev_channel].app);
+		return -EINVAL;
+		break;
+	}
+	// return the number of samples written
+	return insn->n;
+}
+
+#define ISR_ADC_DONE 0x4
+static int s526_ai_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int result = -EINVAL;
+
+	if (insn->n < 1)
+		return result;
+
+	result = insn->n;
+
+	/* data[0] : channels was set in relevant bits.
+	   data[1] : delay
+	 */
+	/* COMMENT: abbotti 2008-07-24: I don't know why you'd want to
+	 * enable channels here.  The channel should be enabled in the
+	 * INSN_READ handler. */
+
+	// Enable ADC interrupt
+	outw(ISR_ADC_DONE, ADDR_REG(REG_IER));
+//      printk("s526: ADC current value: 0x%04x\n", inw(ADDR_REG(REG_ADC)));
+	devpriv->s526_ai_config = (data[0] & 0x3FF) << 5;
+	if (data[1] > 0)
+		devpriv->s526_ai_config |= 0x8000;	//set the delay
+
+	devpriv->s526_ai_config |= 0x0001;	// ADC start bit.
+
+	return result;
+}
+
+/*
+ * "instructions" read/write data in "one-shot" or "software-triggered"
+ * mode.
+ */
+static int s526_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n, i;
+	int chan = CR_CHAN(insn->chanspec);
+	unsigned short value;
+	unsigned int d;
+	unsigned int status;
+
+	/* Set configured delay, enable channel for this channel only,
+	 * select "ADC read" channel, set "ADC start" bit. */
+	value = (devpriv->s526_ai_config & 0x8000) |
+		((1 << 5) << chan) | (chan << 1) | 0x0001;
+
+	/* convert n samples */
+	for (n = 0; n < insn->n; n++) {
+		/* trigger conversion */
+		outw(value, ADDR_REG(REG_ADC));
+//              printk("s526: Wrote 0x%04x to ADC\n", value);
+//              printk("s526: ADC reg=0x%04x\n", inw(ADDR_REG(REG_ADC)));
+
+#define TIMEOUT 100
+		/* wait for conversion to end */
+		for (i = 0; i < TIMEOUT; i++) {
+			status = inw(ADDR_REG(REG_ISR));
+			if (status & ISR_ADC_DONE) {
+				outw(ISR_ADC_DONE, ADDR_REG(REG_ISR));
+				break;
+			}
+		}
+		if (i == TIMEOUT) {
+			/* rt_printk() should be used instead of printk()
+			 * whenever the code can be called from real-time. */
+			rt_printk("s526: ADC(0x%04x) timeout\n",
+				inw(ADDR_REG(REG_ISR)));
+			return -ETIMEDOUT;
+		}
+
+		/* read data */
+		d = inw(ADDR_REG(REG_ADD));
+//              printk("AI[%d]=0x%04x\n", n, (unsigned short)(d & 0xFFFF));
+
+		/* munge data */
+		data[n] = d ^ 0x8000;
+	}
+
+	/* return the number of samples read/written */
+	return n;
+}
+
+static int s526_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+	unsigned short val;
+
+//      printk("s526_ao_winsn\n");
+	val = chan << 1;
+//      outw(val, dev->iobase + REG_DAC);
+	outw(val, ADDR_REG(REG_DAC));
+
+	/* Writing a list of values to an AO channel is probably not
+	 * very useful, but that's how the interface is defined. */
+	for (i = 0; i < insn->n; i++) {
+		/* a typical programming sequence */
+//              outw(data[i], dev->iobase + REG_ADD);  // write the data to preload register
+		outw(data[i], ADDR_REG(REG_ADD));	// write the data to preload register
+		devpriv->ao_readback[chan] = data[i];
+//              outw(val + 1, dev->iobase + REG_DAC); // starts the D/A conversion.
+		outw(val + 1, ADDR_REG(REG_DAC));	// starts the D/A conversion.
+	}
+
+	/* return the number of samples read/written */
+	return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+ * Usually this means copying a value stored in devpriv. */
+static int s526_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+
+	for (i = 0; i < insn->n; i++)
+		data[i] = devpriv->ao_readback[chan];
+
+	return i;
+}
+
+/* DIO devices are slightly special.  Although it is possible to
+ * implement the insn_read/insn_write interface, it is much more
+ * useful to applications if you implement the insn_bits interface.
+ * This allows packed reading/writing of the DIO channels.  The
+ * comedi core can convert between insn_bits and insn_read/write */
+static int s526_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	/* The insn data is a mask in data[0] and the new data
+	 * in data[1], each channel cooresponding to a bit. */
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= data[0] & data[1];
+		/* Write out the new digital output lines */
+		outw(s->state, ADDR_REG(REG_DIO));
+	}
+
+	/* on return, data[1] contains the value of the digital
+	 * input and output lines. */
+	data[1] = inw(ADDR_REG(REG_DIO)) & 0xFF;	// low 8 bits are the data
+	/* or we could just return the software copy of the output values if
+	 * it was a purely digital output subdevice */
+	//data[1]=s->state;
+
+	return 2;
+}
+
+static int s526_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int chan = CR_CHAN(insn->chanspec);
+	short value;
+
+	printk("S526 DIO insn_config\n");
+
+	if (insn->n != 1)
+		return -EINVAL;
+
+	value = inw(ADDR_REG(REG_DIO));
+
+	/* The input or output configuration of each digital line is
+	 * configured by a special insn_config instruction.  chanspec
+	 * contains the channel to be changed, and data[0] contains the
+	 * value COMEDI_INPUT or COMEDI_OUTPUT. */
+
+	if (data[0] == COMEDI_OUTPUT) {
+		value |= 1 << (chan + 10);	// bit 10/11 set the group 1/2's mode
+		s->io_bits |= (0xF << chan);
+	} else {
+		value &= ~(1 << (chan + 10));	// 1 is output, 0 is input.
+		s->io_bits &= ~(0xF << chan);
+	}
+	outw(value, ADDR_REG(REG_DIO));
+
+	return 1;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver_s526);
diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c
index 469ee8c..30dec9d 100644
--- a/drivers/staging/comedi/drivers/s626.c
+++ b/drivers/staging/comedi/drivers/s626.c
@@ -82,7 +82,7 @@
 MODULE_DESCRIPTION("Sensoray 626 Comedi driver module");
 MODULE_LICENSE("GPL");
 
-typedef struct s626_board_struct {
+struct s626_board {
 	const char *name;
 	int ai_chans;
 	int ai_bits;
@@ -91,22 +91,22 @@
 	int dio_chans;
 	int dio_banks;
 	int enc_chans;
-} s626_board;
+};
 
-static const s626_board s626_boards[] = {
+static const struct s626_board s626_boards[] = {
 	{
 	      name:	"s626",
-	      ai_chans:S626_ADC_CHANNELS,
+	      ai_chans : S626_ADC_CHANNELS,
 	      ai_bits:	14,
-	      ao_chans:S626_DAC_CHANNELS,
+	      ao_chans : S626_DAC_CHANNELS,
 	      ao_bits:	13,
-	      dio_chans:S626_DIO_CHANNELS,
-	      dio_banks:S626_DIO_BANKS,
-	      enc_chans:S626_ENCODER_CHANNELS,
+	      dio_chans : S626_DIO_CHANNELS,
+	      dio_banks : S626_DIO_BANKS,
+	      enc_chans : S626_ENCODER_CHANNELS,
 		}
 };
 
-#define thisboard ((const s626_board *)dev->board_ptr)
+#define thisboard ((const struct s626_board *)dev->board_ptr)
 #define PCI_VENDOR_ID_S626 0x1131
 #define PCI_DEVICE_ID_S626 0x7146
 
@@ -118,57 +118,49 @@
 
 MODULE_DEVICE_TABLE(pci, s626_pci_table);
 
-static int s626_attach(comedi_device * dev, comedi_devconfig * it);
-static int s626_detach(comedi_device * dev);
+static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int s626_detach(struct comedi_device *dev);
 
-static comedi_driver driver_s626 = {
+static struct comedi_driver driver_s626 = {
       driver_name:"s626",
-      module:THIS_MODULE,
-      attach:s626_attach,
-      detach:s626_detach,
+      module : THIS_MODULE,
+      attach : s626_attach,
+      detach : s626_detach,
 };
 
-typedef struct {
+struct s626_private {
 	struct pci_dev *pdev;
 	void *base_addr;
 	int got_regions;
 	short allocatedBuf;
-	uint8_t ai_cmd_running;	// ai_cmd is running
-	uint8_t ai_continous;	// continous aquisition
-	int ai_sample_count;	// number of samples to aquire
-	unsigned int ai_sample_timer;	// time between samples in
-	// units of the timer
-	int ai_convert_count;	// conversion counter
-	unsigned int ai_convert_timer;	// time between conversion in
-	// units of the timer
-	uint16_t CounterIntEnabs;	//Counter interrupt enable
-	//mask for MISC2 register.
-	uint8_t AdcItems;	//Number of items in ADC poll
-	//list.
-	DMABUF RPSBuf;		//DMA buffer used to hold ADC
-	//(RPS1) program.
-	DMABUF ANABuf;		//DMA buffer used to receive
-	//ADC data and hold DAC data.
-	uint32_t *pDacWBuf;	//Pointer to logical adrs of
-	//DMA buffer used to hold DAC
-	//data.
-	uint16_t Dacpol;	//Image of DAC polarity
-	//register.
-	uint8_t TrimSetpoint[12];	//Images of TrimDAC setpoints.
-	//registers.
-	uint16_t ChargeEnabled;	//Image of MISC2 Battery
-	//Charge Enabled (0 or
-	//WRMISC2_CHARGE_ENABLE).
-	uint16_t WDInterval;	//Image of MISC2 watchdog
-	//interval control bits.
-	uint32_t I2CAdrs;	//I2C device address for
-	//onboard EEPROM (board rev
-	//dependent).
-	//  short         I2Cards;
-	lsampl_t ao_readback[S626_DAC_CHANNELS];
-} s626_private;
+	uint8_t ai_cmd_running;	/*  ai_cmd is running */
+	uint8_t ai_continous;	/*  continous aquisition */
+	int ai_sample_count;	/*  number of samples to aquire */
+	unsigned int ai_sample_timer;
+	/*  time between samples in  units of the timer */
+	int ai_convert_count;	/*  conversion counter */
+	unsigned int ai_convert_timer;
+	/*  time between conversion in  units of the timer */
+	uint16_t CounterIntEnabs;
+	/* Counter interrupt enable  mask for MISC2 register. */
+	uint8_t AdcItems;	/* Number of items in ADC poll  list. */
+	struct bufferDMA RPSBuf;		/* DMA buffer used to hold ADC (RPS1) program. */
+	struct bufferDMA ANABuf;
+	/* DMA buffer used to receive ADC data and hold DAC data. */
+	uint32_t *pDacWBuf;
+	/* Pointer to logical adrs of DMA buffer used to hold DAC  data. */
+	uint16_t Dacpol;	/* Image of DAC polarity register. */
+	uint8_t TrimSetpoint[12];	/* Images of TrimDAC setpoints */
+	uint16_t ChargeEnabled;	/* Image of MISC2 Battery */
+	/* Charge Enabled (0 or WRMISC2_CHARGE_ENABLE). */
+	uint16_t WDInterval;	/* Image of MISC2 watchdog interval control bits. */
+	uint32_t I2CAdrs;
+	/* I2C device address for onboard EEPROM (board rev dependent). */
+	/*   short         I2Cards; */
+	unsigned int ao_readback[S626_DAC_CHANNELS];
+};
 
-typedef struct {
+struct dio_private {
 	uint16_t RDDIn;
 	uint16_t WRDOut;
 	uint16_t RDEdgSel;
@@ -178,324 +170,322 @@
 	uint16_t RDCapFlg;
 	uint16_t RDIntSel;
 	uint16_t WRIntSel;
-} dio_private;
+};
 
-static dio_private dio_private_A = {
+static struct dio_private dio_private_A = {
       RDDIn:LP_RDDINA,
-      WRDOut:LP_WRDOUTA,
-      RDEdgSel:LP_RDEDGSELA,
-      WREdgSel:LP_WREDGSELA,
-      RDCapSel:LP_RDCAPSELA,
-      WRCapSel:LP_WRCAPSELA,
-      RDCapFlg:LP_RDCAPFLGA,
-      RDIntSel:LP_RDINTSELA,
-      WRIntSel:LP_WRINTSELA,
+      WRDOut : LP_WRDOUTA,
+      RDEdgSel : LP_RDEDGSELA,
+      WREdgSel : LP_WREDGSELA,
+      RDCapSel : LP_RDCAPSELA,
+      WRCapSel : LP_WRCAPSELA,
+      RDCapFlg : LP_RDCAPFLGA,
+      RDIntSel : LP_RDINTSELA,
+      WRIntSel : LP_WRINTSELA,
 };
 
-static dio_private dio_private_B = {
+static struct dio_private dio_private_B = {
       RDDIn:LP_RDDINB,
-      WRDOut:LP_WRDOUTB,
-      RDEdgSel:LP_RDEDGSELB,
-      WREdgSel:LP_WREDGSELB,
-      RDCapSel:LP_RDCAPSELB,
-      WRCapSel:LP_WRCAPSELB,
-      RDCapFlg:LP_RDCAPFLGB,
-      RDIntSel:LP_RDINTSELB,
-      WRIntSel:LP_WRINTSELB,
+      WRDOut : LP_WRDOUTB,
+      RDEdgSel : LP_RDEDGSELB,
+      WREdgSel : LP_WREDGSELB,
+      RDCapSel : LP_RDCAPSELB,
+      WRCapSel : LP_WRCAPSELB,
+      RDCapFlg : LP_RDCAPFLGB,
+      RDIntSel : LP_RDINTSELB,
+      WRIntSel : LP_WRINTSELB,
 };
 
-static dio_private dio_private_C = {
+static struct dio_private dio_private_C = {
       RDDIn:LP_RDDINC,
-      WRDOut:LP_WRDOUTC,
-      RDEdgSel:LP_RDEDGSELC,
-      WREdgSel:LP_WREDGSELC,
-      RDCapSel:LP_RDCAPSELC,
-      WRCapSel:LP_WRCAPSELC,
-      RDCapFlg:LP_RDCAPFLGC,
-      RDIntSel:LP_RDINTSELC,
-      WRIntSel:LP_WRINTSELC,
+      WRDOut : LP_WRDOUTC,
+      RDEdgSel : LP_RDEDGSELC,
+      WREdgSel : LP_WREDGSELC,
+      RDCapSel : LP_RDCAPSELC,
+      WRCapSel : LP_WRCAPSELC,
+      RDCapFlg : LP_RDCAPFLGC,
+      RDIntSel : LP_RDINTSELC,
+      WRIntSel : LP_WRINTSELC,
 };
 
 /* to group dio devices (48 bits mask and data are not allowed ???)
-static dio_private *dio_private_word[]={
+static struct dio_private *dio_private_word[]={
   &dio_private_A,
   &dio_private_B,
   &dio_private_C,
 };
 */
 
-#define devpriv ((s626_private *)dev->private)
-#define diopriv ((dio_private *)s->private)
+#define devpriv ((struct s626_private *)dev->private)
+#define diopriv ((struct dio_private *)s->private)
 
 COMEDI_PCI_INITCLEANUP_NOMODULE(driver_s626, s626_pci_table);
 
-//ioctl routines
-static int s626_ai_insn_config(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data);
-/* static int s626_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data); */
-static int s626_ai_insn_read(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data);
-static int s626_ai_cmd(comedi_device * dev, comedi_subdevice * s);
-static int s626_ai_cmdtest(comedi_device * dev, comedi_subdevice * s,
-	comedi_cmd * cmd);
-static int s626_ai_cancel(comedi_device * dev, comedi_subdevice * s);
-static int s626_ao_winsn(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data);
-static int s626_ao_rinsn(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data);
-static int s626_dio_insn_bits(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data);
-static int s626_dio_insn_config(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data);
-static int s626_dio_set_irq(comedi_device * dev, unsigned int chan);
-static int s626_dio_reset_irq(comedi_device * dev, unsigned int gruop,
+/* ioctl routines */
+static int s626_ai_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data);
+/* static int s626_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data); */
+static int s626_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data);
+static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
+static int s626_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_cmd *cmd);
+static int s626_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
+static int s626_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data);
+static int s626_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data);
+static int s626_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data);
+static int s626_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data);
+static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan);
+static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int gruop,
 	unsigned int mask);
-static int s626_dio_clear_irq(comedi_device * dev);
-static int s626_enc_insn_config(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data);
-static int s626_enc_insn_read(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data);
-static int s626_enc_insn_write(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data);
+static int s626_dio_clear_irq(struct comedi_device *dev);
+static int s626_enc_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data);
+static int s626_enc_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data);
+static int s626_enc_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data);
 static int s626_ns_to_timer(int *nanosec, int round_mode);
-static int s626_ai_load_polllist(uint8_t * ppl, comedi_cmd * cmd);
-static int s626_ai_inttrig(comedi_device * dev, comedi_subdevice * s,
+static int s626_ai_load_polllist(uint8_t *ppl, struct comedi_cmd *cmd);
+static int s626_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
 	unsigned int trignum);
 static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG);
-static lsampl_t s626_ai_reg_to_uint(int data);
-/* static lsampl_t s626_uint_to_reg(comedi_subdevice *s, int data); */
+static unsigned int s626_ai_reg_to_uint(int data);
+/* static unsigned int s626_uint_to_reg(struct comedi_subdevice *s, int data); */
 
-//end ioctl routines
+/* end ioctl routines */
 
-//internal routines
-static void s626_dio_init(comedi_device * dev);
-static void ResetADC(comedi_device * dev, uint8_t * ppl);
-static void LoadTrimDACs(comedi_device * dev);
-static void WriteTrimDAC(comedi_device * dev, uint8_t LogicalChan,
+/* internal routines */
+static void s626_dio_init(struct comedi_device *dev);
+static void ResetADC(struct comedi_device *dev, uint8_t *ppl);
+static void LoadTrimDACs(struct comedi_device *dev);
+static void WriteTrimDAC(struct comedi_device *dev, uint8_t LogicalChan,
 	uint8_t DacData);
-static uint8_t I2Cread(comedi_device * dev, uint8_t addr);
-static uint32_t I2Chandshake(comedi_device * dev, uint32_t val);
-static void SetDAC(comedi_device * dev, uint16_t chan, short dacdata);
-static void SendDAC(comedi_device * dev, uint32_t val);
-static void WriteMISC2(comedi_device * dev, uint16_t NewImage);
-static void DEBItransfer(comedi_device * dev);
-static uint16_t DEBIread(comedi_device * dev, uint16_t addr);
-static void DEBIwrite(comedi_device * dev, uint16_t addr, uint16_t wdata);
-static void DEBIreplace(comedi_device * dev, uint16_t addr, uint16_t mask,
+static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr);
+static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val);
+static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata);
+static void SendDAC(struct comedi_device *dev, uint32_t val);
+static void WriteMISC2(struct comedi_device *dev, uint16_t NewImage);
+static void DEBItransfer(struct comedi_device *dev);
+static uint16_t DEBIread(struct comedi_device *dev, uint16_t addr);
+static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata);
+static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask,
 	uint16_t wdata);
-static void CloseDMAB(comedi_device * dev, DMABUF * pdma, size_t bsize);
+static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma, size_t bsize);
 
-// COUNTER OBJECT ------------------------------------------------
-typedef struct enc_private_struct {
-	// Pointers to functions that differ for A and B counters:
-	uint16_t(*GetEnable) (comedi_device * dev, struct enc_private_struct *);	//Return clock enable.
-	uint16_t(*GetIntSrc) (comedi_device * dev, struct enc_private_struct *);	//Return interrupt source.
-	uint16_t(*GetLoadTrig) (comedi_device * dev, struct enc_private_struct *);	//Return preload trigger source.
-	uint16_t(*GetMode) (comedi_device * dev, struct enc_private_struct *);	//Return standardized operating mode.
-	void (*PulseIndex) (comedi_device * dev, struct enc_private_struct *);	//Generate soft index strobe.
-	void (*SetEnable) (comedi_device * dev, struct enc_private_struct *, uint16_t enab);	//Program clock enable.
-	void (*SetIntSrc) (comedi_device * dev, struct enc_private_struct *, uint16_t IntSource);	//Program interrupt source.
-	void (*SetLoadTrig) (comedi_device * dev, struct enc_private_struct *, uint16_t Trig);	//Program preload trigger source.
-	void (*SetMode) (comedi_device * dev, struct enc_private_struct *, uint16_t Setup, uint16_t DisableIntSrc);	//Program standardized operating mode.
-	void (*ResetCapFlags) (comedi_device * dev, struct enc_private_struct *);	//Reset event capture flags.
+/*  COUNTER OBJECT ------------------------------------------------ */
+struct enc_private {
+	/*  Pointers to functions that differ for A and B counters: */
+	uint16_t(*GetEnable) (struct comedi_device *dev, struct enc_private *);	/* Return clock enable. */
+	uint16_t(*GetIntSrc) (struct comedi_device *dev, struct enc_private *);	/* Return interrupt source. */
+	uint16_t(*GetLoadTrig) (struct comedi_device *dev, struct enc_private *);	/* Return preload trigger source. */
+	uint16_t(*GetMode) (struct comedi_device *dev, struct enc_private *);	/* Return standardized operating mode. */
+	void (*PulseIndex) (struct comedi_device *dev, struct enc_private *);	/* Generate soft index strobe. */
+	void (*SetEnable) (struct comedi_device *dev, struct enc_private *, uint16_t enab);	/* Program clock enable. */
+	void (*SetIntSrc) (struct comedi_device *dev, struct enc_private *, uint16_t IntSource);	/* Program interrupt source. */
+	void (*SetLoadTrig) (struct comedi_device *dev, struct enc_private *, uint16_t Trig);	/* Program preload trigger source. */
+	void (*SetMode) (struct comedi_device *dev, struct enc_private *, uint16_t Setup, uint16_t DisableIntSrc);	/* Program standardized operating mode. */
+	void (*ResetCapFlags) (struct comedi_device *dev, struct enc_private *);	/* Reset event capture flags. */
 
-	uint16_t MyCRA;		//   Address of CRA register.
-	uint16_t MyCRB;		//   Address of CRB register.
-	uint16_t MyLatchLsw;	//   Address of Latch least-significant-word
-	//   register.
-	uint16_t MyEventBits[4];	//   Bit translations for IntSrc -->RDMISC2.
-} enc_private;			//counter object
+	uint16_t MyCRA;		/*    Address of CRA register. */
+	uint16_t MyCRB;		/*    Address of CRB register. */
+	uint16_t MyLatchLsw;	/*    Address of Latch least-significant-word */
+	/*    register. */
+	uint16_t MyEventBits[4];	/*    Bit translations for IntSrc -->RDMISC2. */
+};
 
-#define encpriv ((enc_private *)(dev->subdevices+5)->private)
+#define encpriv ((struct enc_private *)(dev->subdevices+5)->private)
 
-//counters routines
-static void s626_timer_load(comedi_device * dev, enc_private * k, int tick);
-static uint32_t ReadLatch(comedi_device * dev, enc_private * k);
-static void ResetCapFlags_A(comedi_device * dev, enc_private * k);
-static void ResetCapFlags_B(comedi_device * dev, enc_private * k);
-static uint16_t GetMode_A(comedi_device * dev, enc_private * k);
-static uint16_t GetMode_B(comedi_device * dev, enc_private * k);
-static void SetMode_A(comedi_device * dev, enc_private * k, uint16_t Setup,
+/* counters routines */
+static void s626_timer_load(struct comedi_device *dev, struct enc_private *k, int tick);
+static uint32_t ReadLatch(struct comedi_device *dev, struct enc_private *k);
+static void ResetCapFlags_A(struct comedi_device *dev, struct enc_private *k);
+static void ResetCapFlags_B(struct comedi_device *dev, struct enc_private *k);
+static uint16_t GetMode_A(struct comedi_device *dev, struct enc_private *k);
+static uint16_t GetMode_B(struct comedi_device *dev, struct enc_private *k);
+static void SetMode_A(struct comedi_device *dev, struct enc_private *k, uint16_t Setup,
 	uint16_t DisableIntSrc);
-static void SetMode_B(comedi_device * dev, enc_private * k, uint16_t Setup,
+static void SetMode_B(struct comedi_device *dev, struct enc_private *k, uint16_t Setup,
 	uint16_t DisableIntSrc);
-static void SetEnable_A(comedi_device * dev, enc_private * k, uint16_t enab);
-static void SetEnable_B(comedi_device * dev, enc_private * k, uint16_t enab);
-static uint16_t GetEnable_A(comedi_device * dev, enc_private * k);
-static uint16_t GetEnable_B(comedi_device * dev, enc_private * k);
-static void SetLatchSource(comedi_device * dev, enc_private * k,
+static void SetEnable_A(struct comedi_device *dev, struct enc_private *k, uint16_t enab);
+static void SetEnable_B(struct comedi_device *dev, struct enc_private *k, uint16_t enab);
+static uint16_t GetEnable_A(struct comedi_device *dev, struct enc_private *k);
+static uint16_t GetEnable_B(struct comedi_device *dev, struct enc_private *k);
+static void SetLatchSource(struct comedi_device *dev, struct enc_private *k,
 	uint16_t value);
-/* static uint16_t GetLatchSource(comedi_device *dev, enc_private *k ); */
-static void SetLoadTrig_A(comedi_device * dev, enc_private * k, uint16_t Trig);
-static void SetLoadTrig_B(comedi_device * dev, enc_private * k, uint16_t Trig);
-static uint16_t GetLoadTrig_A(comedi_device * dev, enc_private * k);
-static uint16_t GetLoadTrig_B(comedi_device * dev, enc_private * k);
-static void SetIntSrc_B(comedi_device * dev, enc_private * k,
+/* static uint16_t GetLatchSource(struct comedi_device *dev, struct enc_private *k ); */
+static void SetLoadTrig_A(struct comedi_device *dev, struct enc_private *k, uint16_t Trig);
+static void SetLoadTrig_B(struct comedi_device *dev, struct enc_private *k, uint16_t Trig);
+static uint16_t GetLoadTrig_A(struct comedi_device *dev, struct enc_private *k);
+static uint16_t GetLoadTrig_B(struct comedi_device *dev, struct enc_private *k);
+static void SetIntSrc_B(struct comedi_device *dev, struct enc_private *k,
 	uint16_t IntSource);
-static void SetIntSrc_A(comedi_device * dev, enc_private * k,
+static void SetIntSrc_A(struct comedi_device *dev, struct enc_private *k,
 	uint16_t IntSource);
-static uint16_t GetIntSrc_A(comedi_device * dev, enc_private * k);
-static uint16_t GetIntSrc_B(comedi_device * dev, enc_private * k);
-/* static void SetClkMult(comedi_device *dev, enc_private *k, uint16_t value ) ; */
-/* static uint16_t GetClkMult(comedi_device *dev, enc_private *k ) ; */
-/* static void SetIndexPol(comedi_device *dev, enc_private *k, uint16_t value ); */
-/* static uint16_t GetClkPol(comedi_device *dev, enc_private *k ) ; */
-/* static void SetIndexSrc( comedi_device *dev,enc_private *k, uint16_t value );  */
-/* static uint16_t GetClkSrc( comedi_device *dev,enc_private *k );  */
-/* static void SetIndexSrc( comedi_device *dev,enc_private *k, uint16_t value );  */
-/* static uint16_t GetIndexSrc( comedi_device *dev,enc_private *k );  */
-static void PulseIndex_A(comedi_device * dev, enc_private * k);
-static void PulseIndex_B(comedi_device * dev, enc_private * k);
-static void Preload(comedi_device * dev, enc_private * k, uint32_t value);
-static void CountersInit(comedi_device * dev);
-//end internal routines
+static uint16_t GetIntSrc_A(struct comedi_device *dev, struct enc_private *k);
+static uint16_t GetIntSrc_B(struct comedi_device *dev, struct enc_private *k);
+/* static void SetClkMult(struct comedi_device *dev, struct enc_private *k, uint16_t value ) ; */
+/* static uint16_t GetClkMult(struct comedi_device *dev, struct enc_private *k ) ; */
+/* static void SetIndexPol(struct comedi_device *dev, struct enc_private *k, uint16_t value ); */
+/* static uint16_t GetClkPol(struct comedi_device *dev, struct enc_private *k ) ; */
+/* static void SetIndexSrc( struct comedi_device *dev,struct enc_private *k, uint16_t value );  */
+/* static uint16_t GetClkSrc( struct comedi_device *dev,struct enc_private *k );  */
+/* static void SetIndexSrc( struct comedi_device *dev,struct enc_private *k, uint16_t value );  */
+/* static uint16_t GetIndexSrc( struct comedi_device *dev,struct enc_private *k );  */
+static void PulseIndex_A(struct comedi_device *dev, struct enc_private *k);
+static void PulseIndex_B(struct comedi_device *dev, struct enc_private *k);
+static void Preload(struct comedi_device *dev, struct enc_private *k, uint32_t value);
+static void CountersInit(struct comedi_device *dev);
+/* end internal routines */
 
-/////////////////////////////////////////////////////////////////////////
-// Counter objects constructor.
+/*  Counter objects constructor. */
 
-// Counter overflow/index event flag masks for RDMISC2.
-#define INDXMASK(C)		( 1 << ( ( (C) > 2 ) ? ( (C) * 2 - 1 ) : ( (C) * 2 +  4 ) ) )
-#define OVERMASK(C)		( 1 << ( ( (C) > 2 ) ? ( (C) * 2 + 5 ) : ( (C) * 2 + 10 ) ) )
+/*  Counter overflow/index event flag masks for RDMISC2. */
+#define INDXMASK(C)		(1 << (((C) > 2) ? ((C) * 2 - 1) : ((C) * 2 +  4)))
+#define OVERMASK(C)		(1 << (((C) > 2) ? ((C) * 2 + 5) : ((C) * 2 + 10)))
 #define EVBITS(C)		{ 0, OVERMASK(C), INDXMASK(C), OVERMASK(C) | INDXMASK(C) }
 
-// Translation table to map IntSrc into equivalent RDMISC2 event flag
-// bits.
-//static const uint16_t EventBits[][4] = { EVBITS(0), EVBITS(1), EVBITS(2), EVBITS(3), EVBITS(4), EVBITS(5) };
+/*  Translation table to map IntSrc into equivalent RDMISC2 event flag  bits. */
+/* static const uint16_t EventBits[][4] = { EVBITS(0), EVBITS(1), EVBITS(2), EVBITS(3), EVBITS(4), EVBITS(5) }; */
 
-/* enc_private; */
-static enc_private enc_private_data[] = {
+/* struct enc_private; */
+static struct enc_private enc_private_data[] = {
 	{
 	      GetEnable:GetEnable_A,
-	      GetIntSrc:GetIntSrc_A,
-	      GetLoadTrig:GetLoadTrig_A,
-	      GetMode:	GetMode_A,
-	      PulseIndex:PulseIndex_A,
-	      SetEnable:SetEnable_A,
-	      SetIntSrc:SetIntSrc_A,
-	      SetLoadTrig:SetLoadTrig_A,
-	      SetMode:	SetMode_A,
-	      ResetCapFlags:ResetCapFlags_A,
-	      MyCRA:	LP_CR0A,
-	      MyCRB:	LP_CR0B,
-	      MyLatchLsw:LP_CNTR0ALSW,
-	      MyEventBits:EVBITS(0),
+	      GetIntSrc : GetIntSrc_A,
+	      GetLoadTrig : GetLoadTrig_A,
+	      GetMode :	GetMode_A,
+	      PulseIndex : PulseIndex_A,
+	      SetEnable : SetEnable_A,
+	      SetIntSrc : SetIntSrc_A,
+	      SetLoadTrig : SetLoadTrig_A,
+	      SetMode :	SetMode_A,
+	      ResetCapFlags : ResetCapFlags_A,
+	      MyCRA :	LP_CR0A,
+	      MyCRB :	LP_CR0B,
+	      MyLatchLsw : LP_CNTR0ALSW,
+	      MyEventBits : EVBITS(0),
 		},
 	{
 	      GetEnable:GetEnable_A,
-	      GetIntSrc:GetIntSrc_A,
-	      GetLoadTrig:GetLoadTrig_A,
-	      GetMode:	GetMode_A,
-	      PulseIndex:PulseIndex_A,
-	      SetEnable:SetEnable_A,
-	      SetIntSrc:SetIntSrc_A,
-	      SetLoadTrig:SetLoadTrig_A,
-	      SetMode:	SetMode_A,
-	      ResetCapFlags:ResetCapFlags_A,
-	      MyCRA:	LP_CR1A,
-	      MyCRB:	LP_CR1B,
-	      MyLatchLsw:LP_CNTR1ALSW,
-	      MyEventBits:EVBITS(1),
+	      GetIntSrc : GetIntSrc_A,
+	      GetLoadTrig : GetLoadTrig_A,
+	      GetMode :	GetMode_A,
+	      PulseIndex : PulseIndex_A,
+	      SetEnable : SetEnable_A,
+	      SetIntSrc : SetIntSrc_A,
+	      SetLoadTrig : SetLoadTrig_A,
+	      SetMode :	SetMode_A,
+	      ResetCapFlags : ResetCapFlags_A,
+	      MyCRA :	LP_CR1A,
+	      MyCRB :	LP_CR1B,
+	      MyLatchLsw : LP_CNTR1ALSW,
+	      MyEventBits : EVBITS(1),
 		},
 	{
 	      GetEnable:GetEnable_A,
-	      GetIntSrc:GetIntSrc_A,
-	      GetLoadTrig:GetLoadTrig_A,
-	      GetMode:	GetMode_A,
-	      PulseIndex:PulseIndex_A,
-	      SetEnable:SetEnable_A,
-	      SetIntSrc:SetIntSrc_A,
-	      SetLoadTrig:SetLoadTrig_A,
-	      SetMode:	SetMode_A,
-	      ResetCapFlags:ResetCapFlags_A,
-	      MyCRA:	LP_CR2A,
-	      MyCRB:	LP_CR2B,
-	      MyLatchLsw:LP_CNTR2ALSW,
-	      MyEventBits:EVBITS(2),
+	      GetIntSrc : GetIntSrc_A,
+	      GetLoadTrig : GetLoadTrig_A,
+	      GetMode :	GetMode_A,
+	      PulseIndex : PulseIndex_A,
+	      SetEnable : SetEnable_A,
+	      SetIntSrc : SetIntSrc_A,
+	      SetLoadTrig : SetLoadTrig_A,
+	      SetMode :	SetMode_A,
+	      ResetCapFlags : ResetCapFlags_A,
+	      MyCRA :	LP_CR2A,
+	      MyCRB :	LP_CR2B,
+	      MyLatchLsw : LP_CNTR2ALSW,
+	      MyEventBits : EVBITS(2),
 		},
 	{
 	      GetEnable:GetEnable_B,
-	      GetIntSrc:GetIntSrc_B,
-	      GetLoadTrig:GetLoadTrig_B,
-	      GetMode:	GetMode_B,
-	      PulseIndex:PulseIndex_B,
-	      SetEnable:SetEnable_B,
-	      SetIntSrc:SetIntSrc_B,
-	      SetLoadTrig:SetLoadTrig_B,
-	      SetMode:	SetMode_B,
-	      ResetCapFlags:ResetCapFlags_B,
-	      MyCRA:	LP_CR0A,
-	      MyCRB:	LP_CR0B,
-	      MyLatchLsw:LP_CNTR0BLSW,
-	      MyEventBits:EVBITS(3),
+	      GetIntSrc : GetIntSrc_B,
+	      GetLoadTrig : GetLoadTrig_B,
+	      GetMode :	GetMode_B,
+	      PulseIndex : PulseIndex_B,
+	      SetEnable : SetEnable_B,
+	      SetIntSrc : SetIntSrc_B,
+	      SetLoadTrig : SetLoadTrig_B,
+	      SetMode :	SetMode_B,
+	      ResetCapFlags : ResetCapFlags_B,
+	      MyCRA :	LP_CR0A,
+	      MyCRB :	LP_CR0B,
+	      MyLatchLsw : LP_CNTR0BLSW,
+	      MyEventBits : EVBITS(3),
 		},
 	{
 	      GetEnable:GetEnable_B,
-	      GetIntSrc:GetIntSrc_B,
-	      GetLoadTrig:GetLoadTrig_B,
-	      GetMode:	GetMode_B,
-	      PulseIndex:PulseIndex_B,
-	      SetEnable:SetEnable_B,
-	      SetIntSrc:SetIntSrc_B,
-	      SetLoadTrig:SetLoadTrig_B,
-	      SetMode:	SetMode_B,
-	      ResetCapFlags:ResetCapFlags_B,
-	      MyCRA:	LP_CR1A,
-	      MyCRB:	LP_CR1B,
-	      MyLatchLsw:LP_CNTR1BLSW,
-	      MyEventBits:EVBITS(4),
+	      GetIntSrc : GetIntSrc_B,
+	      GetLoadTrig : GetLoadTrig_B,
+	      GetMode :	GetMode_B,
+	      PulseIndex : PulseIndex_B,
+	      SetEnable : SetEnable_B,
+	      SetIntSrc : SetIntSrc_B,
+	      SetLoadTrig : SetLoadTrig_B,
+	      SetMode :	SetMode_B,
+	      ResetCapFlags : ResetCapFlags_B,
+	      MyCRA :	LP_CR1A,
+	      MyCRB :	LP_CR1B,
+	      MyLatchLsw : LP_CNTR1BLSW,
+	      MyEventBits : EVBITS(4),
 		},
 	{
 	      GetEnable:GetEnable_B,
-	      GetIntSrc:GetIntSrc_B,
-	      GetLoadTrig:GetLoadTrig_B,
-	      GetMode:	GetMode_B,
-	      PulseIndex:PulseIndex_B,
-	      SetEnable:SetEnable_B,
-	      SetIntSrc:SetIntSrc_B,
-	      SetLoadTrig:SetLoadTrig_B,
-	      SetMode:	SetMode_B,
-	      ResetCapFlags:ResetCapFlags_B,
-	      MyCRA:	LP_CR2A,
-	      MyCRB:	LP_CR2B,
-	      MyLatchLsw:LP_CNTR2BLSW,
-	      MyEventBits:EVBITS(5),
+	      GetIntSrc : GetIntSrc_B,
+	      GetLoadTrig : GetLoadTrig_B,
+	      GetMode :	GetMode_B,
+	      PulseIndex : PulseIndex_B,
+	      SetEnable : SetEnable_B,
+	      SetIntSrc : SetIntSrc_B,
+	      SetLoadTrig : SetLoadTrig_B,
+	      SetMode :	SetMode_B,
+	      ResetCapFlags : ResetCapFlags_B,
+	      MyCRA :	LP_CR2A,
+	      MyCRB :	LP_CR2B,
+	      MyLatchLsw : LP_CNTR2BLSW,
+	      MyEventBits : EVBITS(5),
 		},
 };
 
-// enab/disable a function or test status bit(s) that are accessed
-// through Main Control Registers 1 or 2.
-#define MC_ENABLE( REGADRS, CTRLWORD )	writel(  ( (uint32_t)( CTRLWORD ) << 16 ) | (uint32_t)( CTRLWORD ),devpriv->base_addr+( REGADRS ) )
+/*  enab/disable a function or test status bit(s) that are accessed */
+/*  through Main Control Registers 1 or 2. */
+#define MC_ENABLE(REGADRS, CTRLWORD)	writel(((uint32_t)(CTRLWORD) << 16) | (uint32_t)(CTRLWORD), devpriv->base_addr+(REGADRS))
 
-#define MC_DISABLE( REGADRS, CTRLWORD )	writel(  (uint32_t)( CTRLWORD ) << 16 , devpriv->base_addr+( REGADRS ) )
+#define MC_DISABLE(REGADRS, CTRLWORD)	writel((uint32_t)(CTRLWORD) << 16 , devpriv->base_addr+(REGADRS))
 
-#define MC_TEST( REGADRS, CTRLWORD )	( ( readl(devpriv->base_addr+( REGADRS )) & CTRLWORD ) != 0 )
+#define MC_TEST(REGADRS, CTRLWORD)	((readl(devpriv->base_addr+(REGADRS)) & CTRLWORD) != 0)
 
 /* #define WR7146(REGARDS,CTRLWORD)
     writel(CTRLWORD,(uint32_t)(devpriv->base_addr+(REGARDS))) */
-#define WR7146(REGARDS,CTRLWORD) writel(CTRLWORD,devpriv->base_addr+(REGARDS))
+#define WR7146(REGARDS, CTRLWORD) writel(CTRLWORD, devpriv->base_addr+(REGARDS))
 
 /* #define RR7146(REGARDS)
     readl((uint32_t)(devpriv->base_addr+(REGARDS))) */
 #define RR7146(REGARDS)		readl(devpriv->base_addr+(REGARDS))
 
-#define BUGFIX_STREG(REGADRS)   ( REGADRS - 4 )
+#define BUGFIX_STREG(REGADRS)   (REGADRS - 4)
 
-// Write a time slot control record to TSL2.
-#define VECTPORT( VECTNUM )		(P_TSL2 + ( (VECTNUM) << 2 ))
-#define SETVECT( VECTNUM, VECTVAL )	WR7146(VECTPORT( VECTNUM ), (VECTVAL))
+/*  Write a time slot control record to TSL2. */
+#define VECTPORT(VECTNUM)		(P_TSL2 + ((VECTNUM) << 2))
+#define SETVECT(VECTNUM, VECTVAL)	WR7146(VECTPORT(VECTNUM), (VECTVAL))
 
-// Code macros used for constructing I2C command bytes.
-#define I2C_B2(ATTR,VAL)	( ( (ATTR) << 6 ) | ( (VAL) << 24 ) )
-#define I2C_B1(ATTR,VAL)	( ( (ATTR) << 4 ) | ( (VAL) << 16 ) )
-#define I2C_B0(ATTR,VAL)	( ( (ATTR) << 2 ) | ( (VAL) <<  8 ) )
+/*  Code macros used for constructing I2C command bytes. */
+#define I2C_B2(ATTR, VAL)	(((ATTR) << 6) | ((VAL) << 24))
+#define I2C_B1(ATTR, VAL)	(((ATTR) << 4) | ((VAL) << 16))
+#define I2C_B0(ATTR, VAL)	(((ATTR) << 2) | ((VAL) <<  8))
 
-static const comedi_lrange s626_range_table = { 2, {
+static const struct comedi_lrange s626_range_table = { 2, {
 			RANGE(-5, 5),
 			RANGE(-10, 10),
 	}
 };
 
-static int s626_attach(comedi_device * dev, comedi_devconfig * it)
+static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
 /*   uint8_t	PollList; */
 /*   uint16_t	AdcData; */
@@ -507,10 +497,10 @@
 	int ret;
 	resource_size_t resourceStart;
 	dma_addr_t appdma;
-	comedi_subdevice *s;
+	struct comedi_subdevice *s;
 	struct pci_dev *pdev;
 
-	if (alloc_private(dev, sizeof(s626_private)) < 0)
+	if (alloc_private(dev, sizeof(struct s626_private)) < 0)
 		return -ENOMEM;
 
 	for (pdev = pci_get_device(PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626,
@@ -535,7 +525,8 @@
 		return -ENODEV;
 	}
 
-	if ((result = comedi_pci_enable(pdev, "s626")) < 0) {
+	result = comedi_pci_enable(pdev, "s626");
+	if (result < 0) {
 		printk("s626_attach: comedi_pci_enable fails\n");
 		return -ENODEV;
 	}
@@ -550,21 +541,22 @@
 	}
 
 	if (devpriv->base_addr) {
-		//disable master interrupt
+		/* disable master interrupt */
 		writel(0, devpriv->base_addr + P_IER);
 
-		//soft reset
+		/* soft reset */
 		writel(MC1_SOFT_RESET, devpriv->base_addr + P_MC1);
 
-		//DMA FIXME DMA//
+		/* DMA FIXME DMA// */
 		DEBUG("s626_attach: DMA ALLOCATION\n");
 
-		//adc buffer allocation
+		/* adc buffer allocation */
 		devpriv->allocatedBuf = 0;
 
-		if ((devpriv->ANABuf.LogicalBase =
-				pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE,
-					&appdma)) == NULL) {
+		devpriv->ANABuf.LogicalBase =
+			pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE, &appdma);
+
+		if (devpriv->ANABuf.LogicalBase == NULL) {
 			printk("s626_attach: DMA Memory mapping error\n");
 			return -ENOMEM;
 		}
@@ -575,9 +567,10 @@
 
 		devpriv->allocatedBuf++;
 
-		if ((devpriv->RPSBuf.LogicalBase =
-				pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE,
-					&appdma)) == NULL) {
+		devpriv->RPSBuf.LogicalBase =
+			pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE,  &appdma);
+
+		if (devpriv->RPSBuf.LogicalBase == NULL) {
 			printk("s626_attach: DMA Memory mapping error\n");
 			return -ENOMEM;
 		}
@@ -599,12 +592,14 @@
 	dev->iobase = (unsigned long)devpriv->base_addr;
 	dev->irq = devpriv->pdev->irq;
 
-	//set up interrupt handler
+	/* set up interrupt handler */
 	if (dev->irq == 0) {
 		printk(" unknown irq (bad)\n");
 	} else {
-		if ((ret = comedi_request_irq(dev->irq, s626_irq_handler,
-					IRQF_SHARED, "s626", dev)) < 0) {
+		ret = comedi_request_irq(dev->irq, s626_irq_handler,
+					 IRQF_SHARED, "s626", dev);
+
+		if (ret < 0) {
 			printk(" irq not available\n");
 			dev->irq = 0;
 		}
@@ -689,119 +684,121 @@
 	s->maxdata = 0xffffff;
 	s->range_table = &range_unknown;
 
-	//stop ai_command
+	/* stop ai_command */
 	devpriv->ai_cmd_running = 0;
 
 	if (devpriv->base_addr && (devpriv->allocatedBuf == 2)) {
 		dma_addr_t pPhysBuf;
 		uint16_t chan;
 
-		// enab DEBI and audio pins, enable I2C interface.
+		/*  enab DEBI and audio pins, enable I2C interface. */
 		MC_ENABLE(P_MC1, MC1_DEBI | MC1_AUDIO | MC1_I2C);
-		// Configure DEBI operating mode.
-		WR7146(P_DEBICFG, DEBI_CFG_SLAVE16	// Local bus is 16
-			// bits wide.
-			| (DEBI_TOUT << DEBI_CFG_TOUT_BIT)	// Declare DEBI
-			// transfer timeout
-			// interval.
-			| DEBI_SWAP	// Set up byte lane
-			// steering.
-			| DEBI_CFG_INTEL);	// Intel-compatible
-		// local bus (DEBI
-		// never times out).
+		/*  Configure DEBI operating mode. */
+		WR7146(P_DEBICFG, DEBI_CFG_SLAVE16	/*  Local bus is 16 */
+			/*  bits wide. */
+			| (DEBI_TOUT << DEBI_CFG_TOUT_BIT)	/*  Declare DEBI */
+			/*  transfer timeout */
+			/*  interval. */
+			| DEBI_SWAP	/*  Set up byte lane */
+			/*  steering. */
+			| DEBI_CFG_INTEL);	/*  Intel-compatible */
+		/*  local bus (DEBI */
+		/*  never times out). */
 		DEBUG("s626_attach: %d debi init -- %d\n",
 			DEBI_CFG_SLAVE16 | (DEBI_TOUT << DEBI_CFG_TOUT_BIT) |
 			DEBI_SWAP | DEBI_CFG_INTEL,
 			DEBI_CFG_INTEL | DEBI_CFG_TOQ | DEBI_CFG_INCQ |
 			DEBI_CFG_16Q);
 
-		//DEBI INIT S626 WR7146( P_DEBICFG, DEBI_CFG_INTEL | DEBI_CFG_TOQ
-		//| DEBI_CFG_INCQ| DEBI_CFG_16Q); //end
+		/* DEBI INIT S626 WR7146( P_DEBICFG, DEBI_CFG_INTEL | DEBI_CFG_TOQ */
+		/* | DEBI_CFG_INCQ| DEBI_CFG_16Q); //end */
 
-		// Paging is disabled.
-		WR7146(P_DEBIPAGE, DEBI_PAGE_DISABLE);	// Disable MMU paging.
+		/*  Paging is disabled. */
+		WR7146(P_DEBIPAGE, DEBI_PAGE_DISABLE);	/*  Disable MMU paging. */
 
-		// Init GPIO so that ADC Start* is negated.
+		/*  Init GPIO so that ADC Start* is negated. */
 		WR7146(P_GPIO, GPIO_BASE | GPIO1_HI);
 
-		//IsBoardRevA is a boolean that indicates whether the board is
-		//RevA.
+    /* IsBoardRevA is a boolean that indicates whether the board is RevA.
+     *
+     * VERSION 2.01 CHANGE: REV A & B BOARDS NOW SUPPORTED BY DYNAMIC
+     * EEPROM ADDRESS SELECTION.  Initialize the I2C interface, which
+     * is used to access the onboard serial EEPROM.  The EEPROM's I2C
+     * DeviceAddress is hardwired to a value that is dependent on the
+     * 626 board revision.  On all board revisions, the EEPROM stores
+     * TrimDAC calibration constants for analog I/O.  On RevB and
+     * higher boards, the DeviceAddress is hardwired to 0 to enable
+     * the EEPROM to also store the PCI SubVendorID and SubDeviceID;
+     * this is the address at which the SAA7146 expects a
+     * configuration EEPROM to reside.  On RevA boards, the EEPROM
+     * device address, which is hardwired to 4, prevents the SAA7146
+     * from retrieving PCI sub-IDs, so the SAA7146 uses its built-in
+     * default values, instead.
+     */
 
-		// VERSION 2.01 CHANGE: REV A & B BOARDS NOW SUPPORTED BY DYNAMIC
-		// EEPROM ADDRESS SELECTION.  Initialize the I2C interface, which
-		// is used to access the onboard serial EEPROM.  The EEPROM's I2C
-		// DeviceAddress is hardwired to a value that is dependent on the
-		// 626 board revision.  On all board revisions, the EEPROM stores
-		// TrimDAC calibration constants for analog I/O.  On RevB and
-		// higher boards, the DeviceAddress is hardwired to 0 to enable
-		// the EEPROM to also store the PCI SubVendorID and SubDeviceID;
-		// this is the address at which the SAA7146 expects a
-		// configuration EEPROM to reside.  On RevA boards, the EEPROM
-		// device address, which is hardwired to 4, prevents the SAA7146
-		// from retrieving PCI sub-IDs, so the SAA7146 uses its built-in
-		// default values, instead.
+		/*     devpriv->I2Cards= IsBoardRevA ? 0xA8 : 0xA0; // Set I2C EEPROM */
+		/*  DeviceType (0xA0) */
+		/*  and DeviceAddress<<1. */
 
-		//    devpriv->I2Cards= IsBoardRevA ? 0xA8 : 0xA0; // Set I2C EEPROM
-		// DeviceType (0xA0)
-		// and DeviceAddress<<1.
+		devpriv->I2CAdrs = 0xA0;	/*  I2C device address for onboard */
+		/*  eeprom(revb) */
 
-		devpriv->I2CAdrs = 0xA0;	// I2C device address for onboard
-		// eeprom(revb)
+		/*  Issue an I2C ABORT command to halt any I2C operation in */
+		/* progress and reset BUSY flag. */
+		WR7146(P_I2CSTAT, I2C_CLKSEL | I2C_ABORT);
+		/*  Write I2C control: abort any I2C activity. */
+		MC_ENABLE(P_MC2, MC2_UPLD_IIC);
+		/*  Invoke command  upload */
+		while ((RR7146(P_MC2) & MC2_UPLD_IIC) == 0)
+			;
+		/*  and wait for upload to complete. */
 
-		// Issue an I2C ABORT command to halt any I2C operation in
-		//progress and reset BUSY flag.
-		WR7146(P_I2CSTAT, I2C_CLKSEL | I2C_ABORT);	// Write I2C control:
-		// abort any I2C
-		// activity.
-		MC_ENABLE(P_MC2, MC2_UPLD_IIC);	// Invoke command
-		// upload
-		while ((RR7146(P_MC2) & MC2_UPLD_IIC) == 0) ;	// and wait for
-		// upload to
-		// complete.
-
-		// Per SAA7146 data sheet, write to STATUS reg twice to reset all
-		// I2C error flags.
+		/* Per SAA7146 data sheet, write to STATUS reg twice to
+		 * reset all  I2C error flags. */
 		for (i = 0; i < 2; i++) {
-			WR7146(P_I2CSTAT, I2C_CLKSEL);	// Write I2C control: reset
-			// error flags.
-			MC_ENABLE(P_MC2, MC2_UPLD_IIC);	// Invoke command upload
-			while (!MC_TEST(P_MC2, MC2_UPLD_IIC)) ;	//   and wait for
-			//   upload to
-			//   complete.
+			WR7146(P_I2CSTAT, I2C_CLKSEL);
+			/*  Write I2C control: reset  error flags. */
+			MC_ENABLE(P_MC2, MC2_UPLD_IIC);	/*  Invoke command upload */
+			while (!MC_TEST(P_MC2, MC2_UPLD_IIC))
+				;
+			/* and wait for upload to complete. */
 		}
 
-		// Init audio interface functional attributes: set DAC/ADC serial
-		// clock rates, invert DAC serial clock so that DAC data setup
-		// times are satisfied, enable DAC serial clock out.
+		/* Init audio interface functional attributes: set DAC/ADC
+		 * serial clock rates, invert DAC serial clock so that
+		 * DAC data setup times are satisfied, enable DAC serial
+		 * clock out.
+		 */
+
 		WR7146(P_ACON2, ACON2_INIT);
 
-		// Set up TSL1 slot list, which is used to control the
-		// accumulation of ADC data: RSD1 = shift data in on SD1.  SIB_A1
-		// = store data uint8_t at next available location in FB BUFFER1
-		// register.
-		WR7146(P_TSL1, RSD1 | SIB_A1);	// Fetch ADC high data
-		// uint8_t.
-		WR7146(P_TSL1 + 4, RSD1 | SIB_A1 | EOS);	// Fetch ADC low data
-		// uint8_t; end of
-		// TSL1.
+		/* Set up TSL1 slot list, which is used to control the
+		 * accumulation of ADC data: RSD1 = shift data in on SD1.
+		 * SIB_A1  = store data uint8_t at next available location in
+		 * FB BUFFER1  register. */
+		WR7146(P_TSL1, RSD1 | SIB_A1);
+		/*  Fetch ADC high data uint8_t. */
+		WR7146(P_TSL1 + 4, RSD1 | SIB_A1 | EOS);
+		/*  Fetch ADC low data uint8_t; end of TSL1. */
 
-		// enab TSL1 slot list so that it executes all the time.
+		/*  enab TSL1 slot list so that it executes all the time. */
 		WR7146(P_ACON1, ACON1_ADCSTART);
 
-		// Initialize RPS registers used for ADC.
+		/*  Initialize RPS registers used for ADC. */
 
-		//Physical start of RPS program.
+		/* Physical start of RPS program. */
 		WR7146(P_RPSADDR1, (uint32_t) devpriv->RPSBuf.PhysicalBase);
 
-		WR7146(P_RPSPAGE1, 0);	// RPS program performs no
-		// explicit mem writes.
-		WR7146(P_RPS1_TOUT, 0);	// Disable RPS timeouts.
+		WR7146(P_RPSPAGE1, 0);
+		/*  RPS program performs no explicit mem writes. */
+		WR7146(P_RPS1_TOUT, 0);	/*  Disable RPS timeouts. */
 
-		// SAA7146 BUG WORKAROUND.  Initialize SAA7146 ADC interface to a
-		// known state by invoking ADCs until FB BUFFER 1 register shows
-		// that it is correctly receiving ADC data.  This is necessary
-		// because the SAA7146 ADC interface does not start up in a
-		// defined state after a PCI reset.
+		/* SAA7146 BUG WORKAROUND.  Initialize SAA7146 ADC interface
+		 * to a known state by invoking ADCs until FB BUFFER 1
+		 * register shows that it is correctly receiving ADC data.
+		 * This is necessary because the SAA7146 ADC interface does
+		 * not start up in a defined state after a PCI reset.
+		 */
 
 /*     PollList = EOPL;			// Create a simple polling */
 /* 					// list for analog input */
@@ -829,115 +826,123 @@
 /* 	  break; */
 /*       } */
 
-		// end initADC
+		/*  end initADC */
 
-		// init the DAC interface
+		/*  init the DAC interface */
 
-		// Init Audio2's output DMAC attributes: burst length = 1 DWORD,
-		// threshold = 1 DWORD.
+		/* Init Audio2's output DMAC attributes: burst length = 1
+		 * DWORD,  threshold = 1 DWORD.
+		 */
 		WR7146(P_PCI_BT_A, 0);
 
-		// Init Audio2's output DMA physical addresses.  The protection
-		// address is set to 1 DWORD past the base address so that a
-		// single DWORD will be transferred each time a DMA transfer is
-		// enabled.
+		/* Init Audio2's output DMA physical addresses.  The protection
+		 * address is set to 1 DWORD past the base address so that a
+		 * single DWORD will be transferred each time a DMA transfer is
+		 * enabled. */
 
 		pPhysBuf =
 			devpriv->ANABuf.PhysicalBase +
 			(DAC_WDMABUF_OS * sizeof(uint32_t));
 
-		WR7146(P_BASEA2_OUT, (uint32_t) pPhysBuf);	// Buffer base adrs.
-		WR7146(P_PROTA2_OUT, (uint32_t) (pPhysBuf + sizeof(uint32_t)));	// Protection address.
+		WR7146(P_BASEA2_OUT, (uint32_t) pPhysBuf);	/*  Buffer base adrs. */
+		WR7146(P_PROTA2_OUT, (uint32_t) (pPhysBuf + sizeof(uint32_t)));	/*  Protection address. */
 
-		// Cache Audio2's output DMA buffer logical address.  This is
-		// where DAC data is buffered for A2 output DMA transfers.
+		/* Cache Audio2's output DMA buffer logical address.  This is
+		 * where DAC data is buffered for A2 output DMA transfers. */
 		devpriv->pDacWBuf =
 			(uint32_t *) devpriv->ANABuf.LogicalBase +
 			DAC_WDMABUF_OS;
 
-		// Audio2's output channels does not use paging.  The protection
-		// violation handling bit is set so that the DMAC will
-		// automatically halt and its PCI address pointer will be reset
-		// when the protection address is reached.
+		/* Audio2's output channels does not use paging.  The protection
+		 * violation handling bit is set so that the DMAC will
+		 * automatically halt and its PCI address pointer will be reset
+		 * when the protection address is reached. */
+
 		WR7146(P_PAGEA2_OUT, 8);
 
-		// Initialize time slot list 2 (TSL2), which is used to control
-		// the clock generation for and serialization of data to be sent
-		// to the DAC devices.  Slot 0 is a NOP that is used to trap TSL
-		// execution; this permits other slots to be safely modified
-		// without first turning off the TSL sequencer (which is
-		// apparently impossible to do).  Also, SD3 (which is driven by a
-		// pull-up resistor) is shifted in and stored to the MSB of
-		// FB_BUFFER2 to be used as evidence that the slot sequence has
-		// not yet finished executing.
-		SETVECT(0, XSD2 | RSD3 | SIB_A2 | EOS);	// Slot 0: Trap TSL
-		// execution, shift 0xFF
-		// into FB_BUFFER2.
+		/* Initialize time slot list 2 (TSL2), which is used to control
+		 * the clock generation for and serialization of data to be sent
+		 * to the DAC devices.  Slot 0 is a NOP that is used to trap TSL
+		 * execution; this permits other slots to be safely modified
+		 * without first turning off the TSL sequencer (which is
+		 * apparently impossible to do).  Also, SD3 (which is driven by a
+		 * pull-up resistor) is shifted in and stored to the MSB of
+		 * FB_BUFFER2 to be used as evidence that the slot sequence has
+		 * not yet finished executing.
+		 */
 
-		// Initialize slot 1, which is constant.  Slot 1 causes a DWORD to
-		// be transferred from audio channel 2's output FIFO to the FIFO's
-		// output buffer so that it can be serialized and sent to the DAC
-		// during subsequent slots.  All remaining slots are dynamically
-		// populated as required by the target DAC device.
-		SETVECT(1, LF_A2);	// Slot 1: Fetch DWORD from Audio2's
-		// output FIFO.
+		SETVECT(0, XSD2 | RSD3 | SIB_A2 | EOS);
+		/*  Slot 0: Trap TSL execution, shift 0xFF into FB_BUFFER2. */
 
-		// Start DAC's audio interface (TSL2) running.
+		/* Initialize slot 1, which is constant.  Slot 1 causes a
+		 * DWORD to be transferred from audio channel 2's output FIFO
+		 * to the FIFO's output buffer so that it can be serialized
+		 * and sent to the DAC during subsequent slots.  All remaining
+		 * slots are dynamically populated as required by the target
+		 * DAC device.
+		 */
+		SETVECT(1, LF_A2);
+		/*  Slot 1: Fetch DWORD from Audio2's output FIFO. */
+
+		/*  Start DAC's audio interface (TSL2) running. */
 		WR7146(P_ACON1, ACON1_DACSTART);
 
-		////////////////////////////////////////////////////////
+		/* end init DAC interface */
 
-		// end init DAC interface
-
-		// Init Trim DACs to calibrated values.  Do it twice because the
-		// SAA7146 audio channel does not always reset properly and
-		// sometimes causes the first few TrimDAC writes to malfunction.
+		/* Init Trim DACs to calibrated values.  Do it twice because the
+		 * SAA7146 audio channel does not always reset properly and
+		 * sometimes causes the first few TrimDAC writes to malfunction.
+		 */
 
 		LoadTrimDACs(dev);
-		LoadTrimDACs(dev);	// Insurance.
+		LoadTrimDACs(dev);	/*  Insurance. */
 
-		//////////////////////////////////////////////////////////////////
-		// Manually init all gate array hardware in case this is a soft
-		// reset (we have no way of determining whether this is a warm or
-		// cold start).  This is necessary because the gate array will
-		// reset only in response to a PCI hard reset; there is no soft
-		// reset function.
+		/* Manually init all gate array hardware in case this is a soft
+		 * reset (we have no way of determining whether this is a warm
+		 * or cold start).  This is necessary because the gate array will
+		 * reset only in response to a PCI hard reset; there is no soft
+		 * reset function. */
 
-		// Init all DAC outputs to 0V and init all DAC setpoint and
-		// polarity images.
+		/* Init all DAC outputs to 0V and init all DAC setpoint and
+		 * polarity images.
+		 */
 		for (chan = 0; chan < S626_DAC_CHANNELS; chan++)
 			SetDAC(dev, chan, 0);
 
-		// Init image of WRMISC2 Battery Charger Enabled control bit.
-		// This image is used when the state of the charger control bit,
-		// which has no direct hardware readback mechanism, is queried.
+		/* Init image of WRMISC2 Battery Charger Enabled control bit.
+		 * This image is used when the state of the charger control bit,
+		 * which has no direct hardware readback mechanism, is queried.
+		 */
 		devpriv->ChargeEnabled = 0;
 
-		// Init image of watchdog timer interval in WRMISC2.  This image
-		// maintains the value of the control bits of MISC2 are
-		// continuously reset to zero as long as the WD timer is disabled.
+		/* Init image of watchdog timer interval in WRMISC2.  This image
+		 * maintains the value of the control bits of MISC2 are
+		 * continuously reset to zero as long as the WD timer is disabled.
+		 */
 		devpriv->WDInterval = 0;
 
-		// Init Counter Interrupt enab mask for RDMISC2.  This mask is
-		// applied against MISC2 when testing to determine which timer
-		// events are requesting interrupt service.
+		/* Init Counter Interrupt enab mask for RDMISC2.  This mask is
+		 * applied against MISC2 when testing to determine which timer
+		 * events are requesting interrupt service.
+		 */
 		devpriv->CounterIntEnabs = 0;
 
-		// Init counters.
+		/*  Init counters. */
 		CountersInit(dev);
 
-		// Without modifying the state of the Battery Backup enab, disable
-		// the watchdog timer, set DIO channels 0-5 to operate in the
-		// standard DIO (vs. counter overflow) mode, disable the battery
-		// charger, and reset the watchdog interval selector to zero.
+		/* Without modifying the state of the Battery Backup enab, disable
+		 * the watchdog timer, set DIO channels 0-5 to operate in the
+		 * standard DIO (vs. counter overflow) mode, disable the battery
+		 * charger, and reset the watchdog interval selector to zero.
+		 */
 		WriteMISC2(dev, (uint16_t) (DEBIread(dev,
 					LP_RDMISC2) & MISC2_BATT_ENABLE));
 
-		// Initialize the digital I/O subsystem.
+		/*  Initialize the digital I/O subsystem. */
 		s626_dio_init(dev);
 
-		//enable interrupt test
-		// writel(IRQ_GPIO3 | IRQ_RPS1,devpriv->base_addr+P_IER);
+		/* enable interrupt test */
+		/*  writel(IRQ_GPIO3 | IRQ_RPS1,devpriv->base_addr+P_IER); */
 	}
 
 	DEBUG("s626_attach: comedi%d s626 attached %04x\n", dev->minor,
@@ -946,9 +951,9 @@
 	return 1;
 }
 
-static lsampl_t s626_ai_reg_to_uint(int data)
+static unsigned int s626_ai_reg_to_uint(int data)
 {
-	lsampl_t tempdata;
+	unsigned int tempdata;
 
 	tempdata = (data >> 18);
 	if (tempdata & 0x2000)
@@ -959,21 +964,21 @@
 	return tempdata;
 }
 
-/* static lsampl_t s626_uint_to_reg(comedi_subdevice *s, int data){ */
+/* static unsigned int s626_uint_to_reg(struct comedi_subdevice *s, int data){ */
 /*   return 0; */
 /* } */
 
 static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
 {
-	comedi_device *dev = d;
-	comedi_subdevice *s;
-	comedi_cmd *cmd;
-	enc_private *k;
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s;
+	struct comedi_cmd *cmd;
+	struct enc_private *k;
 	unsigned long flags;
 	int32_t *readaddr;
 	uint32_t irqtype, irqstatus;
 	int i = 0;
-	sampl_t tempdata;
+	short tempdata;
 	uint8_t group;
 	uint16_t irqbit;
 
@@ -981,47 +986,48 @@
 
 	if (dev->attached == 0)
 		return IRQ_NONE;
-	// lock to avoid race with comedi_poll
+	/*  lock to avoid race with comedi_poll */
 	comedi_spin_lock_irqsave(&dev->spinlock, flags);
 
-	//save interrupt enable register state
+	/* save interrupt enable register state */
 	irqstatus = readl(devpriv->base_addr + P_IER);
 
-	//read interrupt type
+	/* read interrupt type */
 	irqtype = readl(devpriv->base_addr + P_ISR);
 
-	//disable master interrupt
+	/* disable master interrupt */
 	writel(0, devpriv->base_addr + P_IER);
 
-	//clear interrupt
+	/* clear interrupt */
 	writel(irqtype, devpriv->base_addr + P_ISR);
 
-	//do somethings
+	/* do somethings */
 	DEBUG("s626_irq_handler: interrupt type %d\n", irqtype);
 
 	switch (irqtype) {
-	case IRQ_RPS1:		// end_of_scan occurs
+	case IRQ_RPS1:		/*  end_of_scan occurs */
 
 		DEBUG("s626_irq_handler: RPS1 irq detected\n");
 
-		// manage ai subdevice
+		/*  manage ai subdevice */
 		s = dev->subdevices;
 		cmd = &(s->async->cmd);
 
-		// Init ptr to DMA buffer that holds new ADC data.  We skip the
-		// first uint16_t in the buffer because it contains junk data from
-		// the final ADC of the previous poll list scan.
+		/* Init ptr to DMA buffer that holds new ADC data.  We skip the
+		 * first uint16_t in the buffer because it contains junk data from
+		 * the final ADC of the previous poll list scan.
+		 */
 		readaddr = (int32_t *) devpriv->ANABuf.LogicalBase + 1;
 
-		// get the data and hand it over to comedi
+		/*  get the data and hand it over to comedi */
 		for (i = 0; i < (s->async->cmd.chanlist_len); i++) {
-			// Convert ADC data to 16-bit integer values and copy to application
-			// buffer.
+			/*  Convert ADC data to 16-bit integer values and copy to application */
+			/*  buffer. */
 			tempdata = s626_ai_reg_to_uint((int)*readaddr);
 			readaddr++;
 
-			//put data into read buffer
-			// comedi_buf_put(s->async, tempdata);
+			/* put data into read buffer */
+			/*  comedi_buf_put(s->async, tempdata); */
 			if (cfc_write_to_buffer(s, tempdata) == 0)
 				printk("s626_irq_handler: cfc_write_to_buffer error!\n");
 
@@ -1029,7 +1035,7 @@
 				i, tempdata);
 		}
 
-		//end of scan occurs
+		/* end of scan occurs */
 		s->async->events |= COMEDI_CB_EOS;
 
 		if (!(devpriv->ai_continous))
@@ -1037,13 +1043,13 @@
 		if (devpriv->ai_sample_count <= 0) {
 			devpriv->ai_cmd_running = 0;
 
-			// Stop RPS program.
+			/*  Stop RPS program. */
 			MC_DISABLE(P_MC1, MC1_ERPS1);
 
-			//send end of acquisition
+			/* send end of acquisition */
 			s->async->events |= COMEDI_CB_EOA;
 
-			//disable master interrupt
+			/* disable master interrupt */
 			irqstatus = 0;
 		}
 
@@ -1054,40 +1060,40 @@
 
 			DEBUG("s626_irq_handler: External trigger is set!!!\n");
 		}
-		// tell comedi that data is there
+		/*  tell comedi that data is there */
 		DEBUG("s626_irq_handler: events %d\n", s->async->events);
 		comedi_event(dev, s);
 		break;
-	case IRQ_GPIO3:	//check dio and conter interrupt
+	case IRQ_GPIO3:	/* check dio and conter interrupt */
 
 		DEBUG("s626_irq_handler: GPIO3 irq detected\n");
 
-		// manage ai subdevice
+		/*  manage ai subdevice */
 		s = dev->subdevices;
 		cmd = &(s->async->cmd);
 
-		//s626_dio_clear_irq(dev);
+		/* s626_dio_clear_irq(dev); */
 
 		for (group = 0; group < S626_DIO_BANKS; group++) {
 			irqbit = 0;
-			//read interrupt type
+			/* read interrupt type */
 			irqbit = DEBIread(dev,
-				((dio_private *) (dev->subdevices + 2 +
+				((struct dio_private *) (dev->subdevices + 2 +
 						group)->private)->RDCapFlg);
 
-			//check if interrupt is generated from dio channels
+			/* check if interrupt is generated from dio channels */
 			if (irqbit) {
 				s626_dio_reset_irq(dev, group, irqbit);
 				DEBUG("s626_irq_handler: check interrupt on dio group %d %d\n", group, i);
 				if (devpriv->ai_cmd_running) {
-					//check if interrupt is an ai acquisition start trigger
+					/* check if interrupt is an ai acquisition start trigger */
 					if ((irqbit >> (cmd->start_arg -
 								(16 * group)))
 						== 1
 						&& cmd->start_src == TRIG_EXT) {
 						DEBUG("s626_irq_handler: Edge capture interrupt recieved from channel %d\n", cmd->start_arg);
 
-						// Start executing the RPS program.
+						/*  Start executing the RPS program. */
 						MC_ENABLE(P_MC1, MC1_ERPS1);
 
 						DEBUG("s626_irq_handler: aquisition start triggered!!!\n");
@@ -1110,7 +1116,7 @@
 						TRIG_EXT) {
 						DEBUG("s626_irq_handler: Edge capture interrupt recieved from channel %d\n", cmd->scan_begin_arg);
 
-						// Trigger ADC scan loop start by setting RPS Signal 0.
+						/*  Trigger ADC scan loop start by setting RPS Signal 0. */
 						MC_ENABLE(P_MC2, MC2_ADC_RPS);
 
 						DEBUG("s626_irq_handler: scan triggered!!! %d\n", devpriv->ai_sample_count);
@@ -1151,7 +1157,7 @@
 						TRIG_EXT) {
 						DEBUG("s626_irq_handler: Edge capture interrupt recieved from channel %d\n", cmd->convert_arg);
 
-						// Trigger ADC scan loop start by setting RPS Signal 0.
+						/*  Trigger ADC scan loop start by setting RPS Signal 0. */
 						MC_ENABLE(P_MC2, MC2_ADC_RPS);
 
 						DEBUG("s626_irq_handler: adc convert triggered!!!\n");
@@ -1175,10 +1181,10 @@
 			}
 		}
 
-		//read interrupt type
+		/* read interrupt type */
 		irqbit = DEBIread(dev, LP_RDMISC2);
 
-		//check interrupt on counters
+		/* check interrupt on counters */
 		DEBUG("s626_irq_handler: check counters interrupt %d\n",
 			irqbit);
 
@@ -1186,35 +1192,35 @@
 			DEBUG("s626_irq_handler: interrupt on counter 1A overflow\n");
 			k = &encpriv[0];
 
-			//clear interrupt capture flag
+			/* clear interrupt capture flag */
 			k->ResetCapFlags(dev, k);
 		}
 		if (irqbit & IRQ_COINT2A) {
 			DEBUG("s626_irq_handler: interrupt on counter 2A overflow\n");
 			k = &encpriv[1];
 
-			//clear interrupt capture flag
+			/* clear interrupt capture flag */
 			k->ResetCapFlags(dev, k);
 		}
 		if (irqbit & IRQ_COINT3A) {
 			DEBUG("s626_irq_handler: interrupt on counter 3A overflow\n");
 			k = &encpriv[2];
 
-			//clear interrupt capture flag
+			/* clear interrupt capture flag */
 			k->ResetCapFlags(dev, k);
 		}
 		if (irqbit & IRQ_COINT1B) {
 			DEBUG("s626_irq_handler: interrupt on counter 1B overflow\n");
 			k = &encpriv[3];
 
-			//clear interrupt capture flag
+			/* clear interrupt capture flag */
 			k->ResetCapFlags(dev, k);
 		}
 		if (irqbit & IRQ_COINT2B) {
 			DEBUG("s626_irq_handler: interrupt on counter 2B overflow\n");
 			k = &encpriv[4];
 
-			//clear interrupt capture flag
+			/* clear interrupt capture flag */
 			k->ResetCapFlags(dev, k);
 
 			if (devpriv->ai_convert_count > 0) {
@@ -1225,7 +1231,7 @@
 				if (cmd->convert_src == TRIG_TIMER) {
 					DEBUG("s626_irq_handler: conver timer trigger!!! %d\n", devpriv->ai_convert_count);
 
-					// Trigger ADC scan loop start by setting RPS Signal 0.
+					/*  Trigger ADC scan loop start by setting RPS Signal 0. */
 					MC_ENABLE(P_MC2, MC2_ADC_RPS);
 				}
 			}
@@ -1234,13 +1240,13 @@
 			DEBUG("s626_irq_handler: interrupt on counter 3B overflow\n");
 			k = &encpriv[5];
 
-			//clear interrupt capture flag
+			/* clear interrupt capture flag */
 			k->ResetCapFlags(dev, k);
 
 			if (cmd->scan_begin_src == TRIG_TIMER) {
 				DEBUG("s626_irq_handler: scan timer trigger!!!\n");
 
-				// Trigger ADC scan loop start by setting RPS Signal 0.
+				/*  Trigger ADC scan loop start by setting RPS Signal 0. */
 				MC_ENABLE(P_MC2, MC2_ADC_RPS);
 			}
 
@@ -1253,7 +1259,7 @@
 		}
 	}
 
-	//enable interrupt
+	/* enable interrupt */
 	writel(irqstatus, devpriv->base_addr + P_IER);
 
 	DEBUG("s626_irq_handler: exit interrupt service routine.\n");
@@ -1262,21 +1268,21 @@
 	return IRQ_HANDLED;
 }
 
-static int s626_detach(comedi_device * dev)
+static int s626_detach(struct comedi_device *dev)
 {
 	if (devpriv) {
-		//stop ai_command
+		/* stop ai_command */
 		devpriv->ai_cmd_running = 0;
 
 		if (devpriv->base_addr) {
-			//interrupt mask
-			WR7146(P_IER, 0);	// Disable master interrupt.
-			WR7146(P_ISR, IRQ_GPIO3 | IRQ_RPS1);	// Clear board's IRQ status flag.
+			/* interrupt mask */
+			WR7146(P_IER, 0);	/*  Disable master interrupt. */
+			WR7146(P_ISR, IRQ_GPIO3 | IRQ_RPS1);	/*  Clear board's IRQ status flag. */
 
-			// Disable the watchdog timer and battery charger.
+			/*  Disable the watchdog timer and battery charger. */
 			WriteMISC2(dev, 0);
 
-			// Close all interfaces on 7146 device.
+			/*  Close all interfaces on 7146 device. */
 			WR7146(P_MC1, MC1_SHUTDOWN);
 			WR7146(P_ACON1, ACON1_BASE);
 
@@ -1284,18 +1290,15 @@
 			CloseDMAB(dev, &devpriv->ANABuf, DMABUF_SIZE);
 		}
 
-		if (dev->irq) {
+		if (dev->irq)
 			comedi_free_irq(dev->irq, dev);
-		}
 
-		if (devpriv->base_addr) {
+		if (devpriv->base_addr)
 			iounmap(devpriv->base_addr);
-		}
 
 		if (devpriv->pdev) {
-			if (devpriv->got_regions) {
+			if (devpriv->got_regions)
 				comedi_pci_disable(devpriv->pdev);
-			}
 			pci_dev_put(devpriv->pdev);
 		}
 	}
@@ -1308,213 +1311,225 @@
 /*
  * this functions build the RPS program for hardware driven acquistion
  */
-void ResetADC(comedi_device * dev, uint8_t * ppl)
+void ResetADC(struct comedi_device *dev, uint8_t *ppl)
 {
 	register uint32_t *pRPS;
 	uint32_t JmpAdrs;
 	uint16_t i;
 	uint16_t n;
 	uint32_t LocalPPL;
-	comedi_cmd *cmd = &(dev->subdevices->async->cmd);
+	struct comedi_cmd *cmd = &(dev->subdevices->async->cmd);
 
-	// Stop RPS program in case it is currently running.
+	/*  Stop RPS program in case it is currently running. */
 	MC_DISABLE(P_MC1, MC1_ERPS1);
 
-	// Set starting logical address to write RPS commands.
+	/*  Set starting logical address to write RPS commands. */
 	pRPS = (uint32_t *) devpriv->RPSBuf.LogicalBase;
 
-	// Initialize RPS instruction pointer.
+	/*  Initialize RPS instruction pointer. */
 	WR7146(P_RPSADDR1, (uint32_t) devpriv->RPSBuf.PhysicalBase);
 
-	// Construct RPS program in RPSBuf DMA buffer
+	/*  Construct RPS program in RPSBuf DMA buffer */
 
 	if (cmd != NULL && cmd->scan_begin_src != TRIG_FOLLOW) {
 		DEBUG("ResetADC: scan_begin pause inserted\n");
-		// Wait for Start trigger.
+		/*  Wait for Start trigger. */
 		*pRPS++ = RPS_PAUSE | RPS_SIGADC;
 		*pRPS++ = RPS_CLRSIGNAL | RPS_SIGADC;
 	}
-	// SAA7146 BUG WORKAROUND Do a dummy DEBI Write.  This is necessary
-	// because the first RPS DEBI Write following a non-RPS DEBI write
-	// seems to always fail.  If we don't do this dummy write, the ADC
-	// gain might not be set to the value required for the first slot in
-	// the poll list; the ADC gain would instead remain unchanged from
-	// the previously programmed value.
-	*pRPS++ = RPS_LDREG | (P_DEBICMD >> 2);	// Write DEBI Write command
-	// and address to shadow RAM.
-	*pRPS++ = DEBI_CMD_WRWORD | LP_GSEL;
-	*pRPS++ = RPS_LDREG | (P_DEBIAD >> 2);	// Write DEBI immediate data
-	// to shadow RAM:
-	*pRPS++ = GSEL_BIPOLAR5V;	// arbitrary immediate data
-	// value.
-	*pRPS++ = RPS_CLRSIGNAL | RPS_DEBI;	// Reset "shadow RAM
-	// uploaded" flag.
-	*pRPS++ = RPS_UPLOAD | RPS_DEBI;	// Invoke shadow RAM upload.
-	*pRPS++ = RPS_PAUSE | RPS_DEBI;	// Wait for shadow upload to finish.
 
-	// Digitize all slots in the poll list. This is implemented as a
-	// for loop to limit the slot count to 16 in case the application
-	// forgot to set the EOPL flag in the final slot.
+	/* SAA7146 BUG WORKAROUND Do a dummy DEBI Write.  This is necessary
+	 * because the first RPS DEBI Write following a non-RPS DEBI write
+	 * seems to always fail.  If we don't do this dummy write, the ADC
+	 * gain might not be set to the value required for the first slot in
+	 * the poll list; the ADC gain would instead remain unchanged from
+	 * the previously programmed value.
+	 */
+	*pRPS++ = RPS_LDREG | (P_DEBICMD >> 2);
+	/* Write DEBI Write command and address to shadow RAM. */
+
+	*pRPS++ = DEBI_CMD_WRWORD | LP_GSEL;
+	*pRPS++ = RPS_LDREG | (P_DEBIAD >> 2);
+	/*  Write DEBI immediate data  to shadow RAM: */
+
+	*pRPS++ = GSEL_BIPOLAR5V;
+	/*  arbitrary immediate data  value. */
+
+	*pRPS++ = RPS_CLRSIGNAL | RPS_DEBI;
+	/*  Reset "shadow RAM  uploaded" flag. */
+	*pRPS++ = RPS_UPLOAD | RPS_DEBI;	/*  Invoke shadow RAM upload. */
+	*pRPS++ = RPS_PAUSE | RPS_DEBI;	/*  Wait for shadow upload to finish. */
+
+	/* Digitize all slots in the poll list. This is implemented as a
+	 * for loop to limit the slot count to 16 in case the application
+	 * forgot to set the EOPL flag in the final slot.
+	 */
 	for (devpriv->AdcItems = 0; devpriv->AdcItems < 16; devpriv->AdcItems++) {
-		// Convert application's poll list item to private board class
-		// format.  Each app poll list item is an uint8_t with form
-		// (EOPL,x,x,RANGE,CHAN<3:0>), where RANGE code indicates 0 =
-		// +-10V, 1 = +-5V, and EOPL = End of Poll List marker.
+	 /* Convert application's poll list item to private board class
+	  * format.  Each app poll list item is an uint8_t with form
+	  * (EOPL,x,x,RANGE,CHAN<3:0>), where RANGE code indicates 0 =
+	  * +-10V, 1 = +-5V, and EOPL = End of Poll List marker.
+	  */
 		LocalPPL =
 			(*ppl << 8) | (*ppl & 0x10 ? GSEL_BIPOLAR5V :
 			GSEL_BIPOLAR10V);
 
-		// Switch ADC analog gain.
-		*pRPS++ = RPS_LDREG | (P_DEBICMD >> 2);	// Write DEBI command
-		// and address to
-		// shadow RAM.
+		/*  Switch ADC analog gain. */
+		*pRPS++ = RPS_LDREG | (P_DEBICMD >> 2);	/*  Write DEBI command */
+		/*  and address to */
+		/*  shadow RAM. */
 		*pRPS++ = DEBI_CMD_WRWORD | LP_GSEL;
-		*pRPS++ = RPS_LDREG | (P_DEBIAD >> 2);	// Write DEBI
-		// immediate data to
-		// shadow RAM.
+		*pRPS++ = RPS_LDREG | (P_DEBIAD >> 2);	/*  Write DEBI */
+		/*  immediate data to */
+		/*  shadow RAM. */
 		*pRPS++ = LocalPPL;
-		*pRPS++ = RPS_CLRSIGNAL | RPS_DEBI;	// Reset "shadow RAM uploaded"
-		// flag.
-		*pRPS++ = RPS_UPLOAD | RPS_DEBI;	// Invoke shadow RAM upload.
-		*pRPS++ = RPS_PAUSE | RPS_DEBI;	// Wait for shadow upload to
-		// finish.
+		*pRPS++ = RPS_CLRSIGNAL | RPS_DEBI;	/*  Reset "shadow RAM uploaded" */
+		/*  flag. */
+		*pRPS++ = RPS_UPLOAD | RPS_DEBI;	/*  Invoke shadow RAM upload. */
+		*pRPS++ = RPS_PAUSE | RPS_DEBI;	/*  Wait for shadow upload to */
+		/*  finish. */
 
-		// Select ADC analog input channel.
-		*pRPS++ = RPS_LDREG | (P_DEBICMD >> 2);	// Write DEBI command
-		// and address to
-		// shadow RAM.
+		/*  Select ADC analog input channel. */
+		*pRPS++ = RPS_LDREG | (P_DEBICMD >> 2);
+		/*  Write DEBI command and address to  shadow RAM. */
 		*pRPS++ = DEBI_CMD_WRWORD | LP_ISEL;
-		*pRPS++ = RPS_LDREG | (P_DEBIAD >> 2);	// Write DEBI
-		// immediate data to
-		// shadow RAM.
+		*pRPS++ = RPS_LDREG | (P_DEBIAD >> 2);
+		/*  Write DEBI immediate data to shadow RAM. */
 		*pRPS++ = LocalPPL;
-		*pRPS++ = RPS_CLRSIGNAL | RPS_DEBI;	// Reset "shadow RAM uploaded"
-		// flag.
-		*pRPS++ = RPS_UPLOAD | RPS_DEBI;	// Invoke shadow RAM upload.
-		*pRPS++ = RPS_PAUSE | RPS_DEBI;	// Wait for shadow upload to
-		// finish.
+		*pRPS++ = RPS_CLRSIGNAL | RPS_DEBI;
+		/*  Reset "shadow RAM uploaded"  flag. */
 
-		// Delay at least 10 microseconds for analog input settling.
-		// Instead of padding with NOPs, we use RPS_JUMP instructions
-		// here; this allows us to produce a longer delay than is
-		// possible with NOPs because each RPS_JUMP flushes the RPS'
-		// instruction prefetch pipeline.
+		*pRPS++ = RPS_UPLOAD | RPS_DEBI;
+		/*  Invoke shadow RAM upload. */
+
+		*pRPS++ = RPS_PAUSE | RPS_DEBI;
+		/*  Wait for shadow upload to finish. */
+
+		/* Delay at least 10 microseconds for analog input settling.
+		 * Instead of padding with NOPs, we use RPS_JUMP instructions
+		 * here; this allows us to produce a longer delay than is
+		 * possible with NOPs because each RPS_JUMP flushes the RPS'
+		 * instruction prefetch pipeline.
+		 */
 		JmpAdrs =
 			(uint32_t) devpriv->RPSBuf.PhysicalBase +
 			(uint32_t) ((unsigned long)pRPS -
 			(unsigned long)devpriv->RPSBuf.LogicalBase);
 		for (i = 0; i < (10 * RPSCLK_PER_US / 2); i++) {
-			JmpAdrs += 8;	// Repeat to implement time delay:
-			*pRPS++ = RPS_JUMP;	// Jump to next RPS instruction.
+			JmpAdrs += 8;	/*  Repeat to implement time delay: */
+			*pRPS++ = RPS_JUMP;	/*  Jump to next RPS instruction. */
 			*pRPS++ = JmpAdrs;
 		}
 
 		if (cmd != NULL && cmd->convert_src != TRIG_NOW) {
 			DEBUG("ResetADC: convert pause inserted\n");
-			// Wait for Start trigger.
+			/*  Wait for Start trigger. */
 			*pRPS++ = RPS_PAUSE | RPS_SIGADC;
 			*pRPS++ = RPS_CLRSIGNAL | RPS_SIGADC;
 		}
-		// Start ADC by pulsing GPIO1.
-		*pRPS++ = RPS_LDREG | (P_GPIO >> 2);	// Begin ADC Start pulse.
+		/*  Start ADC by pulsing GPIO1. */
+		*pRPS++ = RPS_LDREG | (P_GPIO >> 2);	/*  Begin ADC Start pulse. */
 		*pRPS++ = GPIO_BASE | GPIO1_LO;
 		*pRPS++ = RPS_NOP;
-		// VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE.
-		*pRPS++ = RPS_LDREG | (P_GPIO >> 2);	// End ADC Start pulse.
+		/*  VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE. */
+		*pRPS++ = RPS_LDREG | (P_GPIO >> 2);	/*  End ADC Start pulse. */
 		*pRPS++ = GPIO_BASE | GPIO1_HI;
 
-		// Wait for ADC to complete (GPIO2 is asserted high when ADC not
-		// busy) and for data from previous conversion to shift into FB
-		// BUFFER 1 register.
-		*pRPS++ = RPS_PAUSE | RPS_GPIO2;	// Wait for ADC done.
+		/* Wait for ADC to complete (GPIO2 is asserted high when ADC not
+		 * busy) and for data from previous conversion to shift into FB
+		 * BUFFER 1 register.
+		 */
+		*pRPS++ = RPS_PAUSE | RPS_GPIO2;	/*  Wait for ADC done. */
 
-		// Transfer ADC data from FB BUFFER 1 register to DMA buffer.
+		/*  Transfer ADC data from FB BUFFER 1 register to DMA buffer. */
 		*pRPS++ = RPS_STREG | (BUGFIX_STREG(P_FB_BUFFER1) >> 2);
 		*pRPS++ =
 			(uint32_t) devpriv->ANABuf.PhysicalBase +
 			(devpriv->AdcItems << 2);
 
-		// If this slot's EndOfPollList flag is set, all channels have
-		// now been processed.
+		/*  If this slot's EndOfPollList flag is set, all channels have */
+		/*  now been processed. */
 		if (*ppl++ & EOPL) {
-			devpriv->AdcItems++;	// Adjust poll list item count.
-			break;	// Exit poll list processing loop.
+			devpriv->AdcItems++;	/*  Adjust poll list item count. */
+			break;	/*  Exit poll list processing loop. */
 		}
 	}
 	DEBUG("ResetADC: ADC items %d \n", devpriv->AdcItems);
 
-	// VERSION 2.01 CHANGE: DELAY CHANGED FROM 250NS to 2US.  Allow the
-	// ADC to stabilize for 2 microseconds before starting the final
-	// (dummy) conversion.  This delay is necessary to allow sufficient
-	// time between last conversion finished and the start of the dummy
-	// conversion.  Without this delay, the last conversion's data value
-	// is sometimes set to the previous conversion's data value.
+	/* VERSION 2.01 CHANGE: DELAY CHANGED FROM 250NS to 2US.  Allow the
+	 * ADC to stabilize for 2 microseconds before starting the final
+	 * (dummy) conversion.  This delay is necessary to allow sufficient
+	 * time between last conversion finished and the start of the dummy
+	 * conversion.  Without this delay, the last conversion's data value
+	 * is sometimes set to the previous conversion's data value.
+	 */
 	for (n = 0; n < (2 * RPSCLK_PER_US); n++)
 		*pRPS++ = RPS_NOP;
 
-	// Start a dummy conversion to cause the data from the last
-	// conversion of interest to be shifted in.
-	*pRPS++ = RPS_LDREG | (P_GPIO >> 2);	// Begin ADC Start pulse.
+	/* Start a dummy conversion to cause the data from the last
+	 * conversion of interest to be shifted in.
+	 */
+	*pRPS++ = RPS_LDREG | (P_GPIO >> 2);	/*  Begin ADC Start pulse. */
 	*pRPS++ = GPIO_BASE | GPIO1_LO;
 	*pRPS++ = RPS_NOP;
-	// VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE.
-	*pRPS++ = RPS_LDREG | (P_GPIO >> 2);	// End ADC Start pulse.
+	/* VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE. */
+	*pRPS++ = RPS_LDREG | (P_GPIO >> 2);	/*  End ADC Start pulse. */
 	*pRPS++ = GPIO_BASE | GPIO1_HI;
 
-	// Wait for the data from the last conversion of interest to arrive
-	// in FB BUFFER 1 register.
-	*pRPS++ = RPS_PAUSE | RPS_GPIO2;	// Wait for ADC done.
+	/* Wait for the data from the last conversion of interest to arrive
+	 * in FB BUFFER 1 register.
+	 */
+	*pRPS++ = RPS_PAUSE | RPS_GPIO2;	/*  Wait for ADC done. */
 
-	// Transfer final ADC data from FB BUFFER 1 register to DMA buffer.
-	*pRPS++ = RPS_STREG | (BUGFIX_STREG(P_FB_BUFFER1) >> 2);	//
+	/*  Transfer final ADC data from FB BUFFER 1 register to DMA buffer. */
+	*pRPS++ = RPS_STREG | (BUGFIX_STREG(P_FB_BUFFER1) >> 2);	/*  */
 	*pRPS++ =
 		(uint32_t) devpriv->ANABuf.PhysicalBase +
 		(devpriv->AdcItems << 2);
 
-	// Indicate ADC scan loop is finished.
-	// *pRPS++= RPS_CLRSIGNAL | RPS_SIGADC ;  // Signal ReadADC() that scan is done.
+	/*  Indicate ADC scan loop is finished. */
+	/*  *pRPS++= RPS_CLRSIGNAL | RPS_SIGADC ;  // Signal ReadADC() that scan is done. */
 
-	//invoke interrupt
+	/* invoke interrupt */
 	if (devpriv->ai_cmd_running == 1) {
 		DEBUG("ResetADC: insert irq in ADC RPS task\n");
 		*pRPS++ = RPS_IRQ;
 	}
-	// Restart RPS program at its beginning.
-	*pRPS++ = RPS_JUMP;	// Branch to start of RPS program.
+	/*  Restart RPS program at its beginning. */
+	*pRPS++ = RPS_JUMP;	/*  Branch to start of RPS program. */
 	*pRPS++ = (uint32_t) devpriv->RPSBuf.PhysicalBase;
 
-	// End of RPS program build
-	// ------------------------------------------------------------
+	/*  End of RPS program build */
 }
 
 /* TO COMPLETE, IF NECESSARY */
-static int s626_ai_insn_config(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data)
+static int s626_ai_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data)
 {
 
 	return -EINVAL;
 }
 
-/* static int s626_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) */
+/* static int s626_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) */
 /* { */
 /*   register uint8_t	i; */
 /*   register int32_t	*readaddr; */
 
 /*   DEBUG("as626_ai_rinsn: ai_rinsn enter \n");  */
 
-/*   // Trigger ADC scan loop start by setting RPS Signal 0. */
+/*   Trigger ADC scan loop start by setting RPS Signal 0. */
 /*   MC_ENABLE( P_MC2, MC2_ADC_RPS ); */
 
-/*   // Wait until ADC scan loop is finished (RPS Signal 0 reset). */
+/*   Wait until ADC scan loop is finished (RPS Signal 0 reset). */
 /*   while ( MC_TEST( P_MC2, MC2_ADC_RPS ) ); */
 
-/*   // Init ptr to DMA buffer that holds new ADC data.  We skip the */
-/*   // first uint16_t in the buffer because it contains junk data from */
-/*   // the final ADC of the previous poll list scan. */
+/* Init ptr to DMA buffer that holds new ADC data.  We skip the
+ * first uint16_t in the buffer because it contains junk data from
+ * the final ADC of the previous poll list scan.
+ */
 /*   readaddr = (uint32_t *)devpriv->ANABuf.LogicalBase + 1; */
 
-/*   // Convert ADC data to 16-bit integer values and copy to application */
-/*   // buffer.	 */
+/*  Convert ADC data to 16-bit integer values and copy to application buffer. */
 /*   for ( i = 0; i < devpriv->AdcItems; i++ ) { */
 /*     *data = s626_ai_reg_to_uint( *readaddr++ ); */
 /*     DEBUG("s626_ai_rinsn: data %d \n",*data); */
@@ -1525,8 +1540,8 @@
 /*   return i; */
 /* } */
 
-static int s626_ai_insn_read(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data)
+static int s626_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data)
 {
 	uint16_t chan = CR_CHAN(insn->chanspec);
 	uint16_t range = CR_RANGE(insn->chanspec);
@@ -1534,86 +1549,87 @@
 	uint32_t GpioImage;
 	int n;
 
-/*   //interrupt call test  */
-/*   writel(IRQ_GPIO3,devpriv->base_addr+P_PSR); //Writing a logical 1 */
-/* 					     //into any of the RPS_PSR */
-/* 					     //bits causes the */
-/* 					     //corresponding interrupt */
-/* 					     //to be generated if */
-/* 					     //enabled */
+ /* interrupt call test  */
+/*   writel(IRQ_GPIO3,devpriv->base_addr+P_PSR); */
+	/* Writing a logical 1 into any of the RPS_PSR bits causes the
+	 * corresponding interrupt to be generated if enabled
+	 */
 
 	DEBUG("s626_ai_insn_read: entering\n");
 
-	// Convert application's ADC specification into form
-	// appropriate for register programming.
+	/* Convert application's ADC specification into form
+	 *  appropriate for register programming.
+	 */
 	if (range == 0)
 		AdcSpec = (chan << 8) | (GSEL_BIPOLAR5V);
 	else
 		AdcSpec = (chan << 8) | (GSEL_BIPOLAR10V);
 
-	// Switch ADC analog gain.
-	DEBIwrite(dev, LP_GSEL, AdcSpec);	// Set gain.
+	/*  Switch ADC analog gain. */
+	DEBIwrite(dev, LP_GSEL, AdcSpec);	/*  Set gain. */
 
-	// Select ADC analog input channel.
-	DEBIwrite(dev, LP_ISEL, AdcSpec);	// Select channel.
+	/*  Select ADC analog input channel. */
+	DEBIwrite(dev, LP_ISEL, AdcSpec);	/*  Select channel. */
 
 	for (n = 0; n < insn->n; n++) {
 
-		// Delay 10 microseconds for analog input settling.
+		/*  Delay 10 microseconds for analog input settling. */
 		comedi_udelay(10);
 
-		// Start ADC by pulsing GPIO1 low.
+		/*  Start ADC by pulsing GPIO1 low. */
 		GpioImage = RR7146(P_GPIO);
-		// Assert ADC Start command
+		/*  Assert ADC Start command */
 		WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
-		//   and stretch it out.
+		/*    and stretch it out. */
 		WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
 		WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
-		// Negate ADC Start command.
+		/*  Negate ADC Start command. */
 		WR7146(P_GPIO, GpioImage | GPIO1_HI);
 
-		// Wait for ADC to complete (GPIO2 is asserted high when
-		// ADC not busy) and for data from previous conversion to
-		// shift into FB BUFFER 1 register.
+		/*  Wait for ADC to complete (GPIO2 is asserted high when */
+		/*  ADC not busy) and for data from previous conversion to */
+		/*  shift into FB BUFFER 1 register. */
 
-		// Wait for ADC done.
-		while (!(RR7146(P_PSR) & PSR_GPIO2)) ;
+		/*  Wait for ADC done. */
+		while (!(RR7146(P_PSR) & PSR_GPIO2))
+			;
 
-		// Fetch ADC data.
+		/*  Fetch ADC data. */
 		if (n != 0)
 			data[n - 1] = s626_ai_reg_to_uint(RR7146(P_FB_BUFFER1));
 
-		// Allow the ADC to stabilize for 4 microseconds before
-		// starting the next (final) conversion.  This delay is
-		// necessary to allow sufficient time between last
-		// conversion finished and the start of the next
-		// conversion.  Without this delay, the last conversion's
-		// data value is sometimes set to the previous
-		// conversion's data value.
+		/* Allow the ADC to stabilize for 4 microseconds before
+		 * starting the next (final) conversion.  This delay is
+		 * necessary to allow sufficient time between last
+		 * conversion finished and the start of the next
+		 * conversion.  Without this delay, the last conversion's
+		 * data value is sometimes set to the previous
+		 * conversion's data value.
+		 */
 		comedi_udelay(4);
 	}
 
-	// Start a dummy conversion to cause the data from the
-	// previous conversion to be shifted in.
+	/* Start a dummy conversion to cause the data from the
+	 * previous conversion to be shifted in. */
 	GpioImage = RR7146(P_GPIO);
 
-	//Assert ADC Start command
+	/* Assert ADC Start command */
 	WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
-	//   and stretch it out.
+	/*    and stretch it out. */
 	WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
 	WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
-	// Negate ADC Start command.
+	/*  Negate ADC Start command. */
 	WR7146(P_GPIO, GpioImage | GPIO1_HI);
 
-	// Wait for the data to arrive in FB BUFFER 1 register.
+	/*  Wait for the data to arrive in FB BUFFER 1 register. */
 
-	// Wait for ADC done.
-	while (!(RR7146(P_PSR) & PSR_GPIO2)) ;
+	/*  Wait for ADC done. */
+	while (!(RR7146(P_PSR) & PSR_GPIO2))
+		;
 
-	// Fetch ADC data from audio interface's input shift
-	// register.
+	/*  Fetch ADC data from audio interface's input shift register. */
 
-	// Fetch ADC data.
+	/*  Fetch ADC data. */
 	if (n != 0)
 		data[n - 1] = s626_ai_reg_to_uint(RR7146(P_FB_BUFFER1));
 
@@ -1622,7 +1638,7 @@
 	return n;
 }
 
-static int s626_ai_load_polllist(uint8_t * ppl, comedi_cmd * cmd)
+static int s626_ai_load_polllist(uint8_t *ppl, struct comedi_cmd *cmd)
 {
 
 	int n;
@@ -1638,7 +1654,7 @@
 	return n;
 }
 
-static int s626_ai_inttrig(comedi_device * dev, comedi_subdevice * s,
+static int s626_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
 	unsigned int trignum)
 {
 	if (trignum != 0)
@@ -1646,7 +1662,7 @@
 
 	DEBUG("s626_ai_inttrig: trigger adc start...");
 
-	// Start executing the RPS program.
+	/*  Start executing the RPS program. */
 	MC_ENABLE(P_MC1, MC1_ERPS1);
 
 	s->async->inttrig = NULL;
@@ -1657,12 +1673,12 @@
 }
 
 /*  TO COMPLETE  */
-static int s626_ai_cmd(comedi_device * dev, comedi_subdevice * s)
+static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 
 	uint8_t ppl[16];
-	comedi_cmd *cmd = &s->async->cmd;
-	enc_private *k;
+	struct comedi_cmd *cmd = &s->async->cmd;
+	struct enc_private *k;
 	int tick;
 
 	DEBUG("s626_ai_cmd: entering command function\n");
@@ -1672,20 +1688,20 @@
 			dev->minor);
 		return -EBUSY;
 	}
-	//disable interrupt
+	/* disable interrupt */
 	writel(0, devpriv->base_addr + P_IER);
 
-	//clear interrupt request
+	/* clear interrupt request */
 	writel(IRQ_RPS1 | IRQ_GPIO3, devpriv->base_addr + P_ISR);
 
-	//clear any pending interrupt
+	/* clear any pending interrupt */
 	s626_dio_clear_irq(dev);
-	//  s626_enc_clear_irq(dev);
+	/*   s626_enc_clear_irq(dev); */
 
-	//reset ai_cmd_running flag
+	/* reset ai_cmd_running flag */
 	devpriv->ai_cmd_running = 0;
 
-	// test if cmd is valid
+	/*  test if cmd is valid */
 	if (cmd == NULL) {
 		DEBUG("s626_ai_cmd: NULL command\n");
 		return -EINVAL;
@@ -1707,12 +1723,12 @@
 	case TRIG_FOLLOW:
 		break;
 	case TRIG_TIMER:
-		// set a conter to generate adc trigger at scan_begin_arg interval
+		/*  set a conter to generate adc trigger at scan_begin_arg interval */
 		k = &encpriv[5];
 		tick = s626_ns_to_timer((int *)&cmd->scan_begin_arg,
 			cmd->flags & TRIG_ROUND_MASK);
 
-		//load timer value and enable interrupt
+		/* load timer value and enable interrupt */
 		s626_timer_load(dev, k, tick);
 		k->SetEnable(dev, k, CLKENAB_ALWAYS);
 
@@ -1721,7 +1737,7 @@
 
 		break;
 	case TRIG_EXT:
-		// set the digital line and interrupt for scan trigger
+		/*  set the digital line and interrupt for scan trigger */
 		if (cmd->start_src != TRIG_EXT)
 			s626_dio_set_irq(dev, cmd->scan_begin_arg);
 
@@ -1734,19 +1750,19 @@
 	case TRIG_NOW:
 		break;
 	case TRIG_TIMER:
-		// set a conter to generate adc trigger at convert_arg interval
+		/*  set a conter to generate adc trigger at convert_arg interval */
 		k = &encpriv[4];
 		tick = s626_ns_to_timer((int *)&cmd->convert_arg,
 			cmd->flags & TRIG_ROUND_MASK);
 
-		//load timer value and enable interrupt
+		/* load timer value and enable interrupt */
 		s626_timer_load(dev, k, tick);
 		k->SetEnable(dev, k, CLKENAB_INDEX);
 
 		DEBUG("s626_ai_cmd: convert trigger timer is set with value %d\n", tick);
 		break;
 	case TRIG_EXT:
-		// set the digital line and interrupt for convert trigger
+		/*  set the digital line and interrupt for convert trigger */
 		if (cmd->scan_begin_src != TRIG_EXT
 			&& cmd->start_src == TRIG_EXT)
 			s626_dio_set_irq(dev, cmd->convert_arg);
@@ -1758,12 +1774,12 @@
 
 	switch (cmd->stop_src) {
 	case TRIG_COUNT:
-		// data arrives as one packet
+		/*  data arrives as one packet */
 		devpriv->ai_sample_count = cmd->stop_arg;
 		devpriv->ai_continous = 0;
 		break;
 	case TRIG_NONE:
-		// continous aquisition
+		/*  continous aquisition */
 		devpriv->ai_continous = 1;
 		devpriv->ai_sample_count = 0;
 		break;
@@ -1773,17 +1789,17 @@
 
 	switch (cmd->start_src) {
 	case TRIG_NOW:
-		// Trigger ADC scan loop start by setting RPS Signal 0.
-		// MC_ENABLE( P_MC2, MC2_ADC_RPS );
+		/*  Trigger ADC scan loop start by setting RPS Signal 0. */
+		/*  MC_ENABLE( P_MC2, MC2_ADC_RPS ); */
 
-		// Start executing the RPS program.
+		/*  Start executing the RPS program. */
 		MC_ENABLE(P_MC1, MC1_ERPS1);
 
 		DEBUG("s626_ai_cmd: ADC triggered\n");
 		s->async->inttrig = NULL;
 		break;
 	case TRIG_EXT:
-		//configure DIO channel for acquisition trigger
+		/* configure DIO channel for acquisition trigger */
 		s626_dio_set_irq(dev, cmd->start_arg);
 
 		DEBUG("s626_ai_cmd: External start trigger is set!!!\n");
@@ -1795,7 +1811,7 @@
 		break;
 	}
 
-	//enable interrupt
+	/* enable interrupt */
 	writel(IRQ_GPIO3 | IRQ_RPS1, devpriv->base_addr + P_IER);
 
 	DEBUG("s626_ai_cmd: command function terminated\n");
@@ -1803,8 +1819,8 @@
 	return 0;
 }
 
-static int s626_ai_cmdtest(comedi_device * dev, comedi_subdevice * s,
-	comedi_cmd * cmd)
+static int s626_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -1988,12 +2004,12 @@
 	return 0;
 }
 
-static int s626_ai_cancel(comedi_device * dev, comedi_subdevice * s)
+static int s626_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 {
-	// Stop RPS program in case it is currently running.
+	/*  Stop RPS program in case it is currently running. */
 	MC_DISABLE(P_MC1, MC1_ERPS1);
 
-	//disable master interrupt
+	/* disable master interrupt */
 	writel(0, devpriv->base_addr + P_IER);
 
 	devpriv->ai_cmd_running = 0;
@@ -2010,7 +2026,7 @@
 {
 	int divider, base;
 
-	base = 500;		//2MHz internal clock
+	base = 500;		/* 2MHz internal clock */
 
 	switch (round_mode) {
 	case TRIG_ROUND_NEAREST:
@@ -2029,8 +2045,8 @@
 	return divider - 1;
 }
 
-static int s626_ao_winsn(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data)
+static int s626_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data)
 {
 
 	int i;
@@ -2048,45 +2064,42 @@
 	return i;
 }
 
-static int s626_ao_rinsn(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data)
+static int s626_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 
-	for (i = 0; i < insn->n; i++) {
+	for (i = 0; i < insn->n; i++)
 		data[i] = devpriv->ao_readback[CR_CHAN(insn->chanspec)];
-	}
 
 	return i;
 }
 
-/////////////////////////////////////////////////////////////////////
-///////////////  DIGITAL I/O FUNCTIONS  /////////////////////////////
-/////////////////////////////////////////////////////////////////////
-// All DIO functions address a group of DIO channels by means of
-// "group" argument.  group may be 0, 1 or 2, which correspond to DIO
-// ports A, B and C, respectively.
-/////////////////////////////////////////////////////////////////////
+/* *************** DIGITAL I/O FUNCTIONS ***************
+ * All DIO functions address a group of DIO channels by means of
+ * "group" argument.  group may be 0, 1 or 2, which correspond to DIO
+ * ports A, B and C, respectively.
+ */
 
-static void s626_dio_init(comedi_device * dev)
+static void s626_dio_init(struct comedi_device *dev)
 {
 	uint16_t group;
-	comedi_subdevice *s;
+	struct comedi_subdevice *s;
 
-	// Prepare to treat writes to WRCapSel as capture disables.
+	/*  Prepare to treat writes to WRCapSel as capture disables. */
 	DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
 
-	// For each group of sixteen channels ...
+	/*  For each group of sixteen channels ... */
 	for (group = 0; group < S626_DIO_BANKS; group++) {
 		s = dev->subdevices + 2 + group;
-		DEBIwrite(dev, diopriv->WRIntSel, 0);	// Disable all interrupts.
-		DEBIwrite(dev, diopriv->WRCapSel, 0xFFFF);	// Disable all event
-		// captures.
-		DEBIwrite(dev, diopriv->WREdgSel, 0);	// Init all DIOs to
-		// default edge
-		// polarity.
-		DEBIwrite(dev, diopriv->WRDOut, 0);	// Program all outputs
-		// to inactive state.
+		DEBIwrite(dev, diopriv->WRIntSel, 0);	/*  Disable all interrupts. */
+		DEBIwrite(dev, diopriv->WRCapSel, 0xFFFF);	/*  Disable all event */
+		/*  captures. */
+		DEBIwrite(dev, diopriv->WREdgSel, 0);	/*  Init all DIOs to */
+		/*  default edge */
+		/*  polarity. */
+		DEBIwrite(dev, diopriv->WRDOut, 0);	/*  Program all outputs */
+		/*  to inactive state. */
 	}
 	DEBUG("s626_dio_init: DIO initialized \n");
 }
@@ -2097,14 +2110,14 @@
  * This allows packed reading/writing of the DIO channels.  The comedi
  * core can convert between insn_bits and insn_read/write */
 
-static int s626_dio_insn_bits(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data)
+static int s626_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data)
 {
 
 	/* Length of data must be 2 (mask and new data, see below) */
-	if (insn->n == 0) {
+	if (insn->n == 0)
 		return 0;
-	}
+
 	if (insn->n != 2) {
 		printk("comedi%d: s626: s626_dio_insn_bits(): Invalid instruction length\n", dev->minor);
 		return -EINVAL;
@@ -2133,8 +2146,8 @@
 	return 2;
 }
 
-static int s626_dio_insn_config(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data)
+static int s626_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data)
 {
 
 	switch (data[0]) {
@@ -2160,75 +2173,75 @@
 	return 1;
 }
 
-static int s626_dio_set_irq(comedi_device * dev, unsigned int chan)
+static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan)
 {
 	unsigned int group;
 	unsigned int bitmask;
 	unsigned int status;
 
-	//select dio bank
+	/* select dio bank */
 	group = chan / 16;
 	bitmask = 1 << (chan - (16 * group));
 	DEBUG("s626_dio_set_irq: enable interrupt on dio channel %d group %d\n",
 		chan - (16 * group), group);
 
-	//set channel to capture positive edge
+	/* set channel to capture positive edge */
 	status = DEBIread(dev,
-		((dio_private *) (dev->subdevices + 2 +
+		((struct dio_private *) (dev->subdevices + 2 +
 				group)->private)->RDEdgSel);
 	DEBIwrite(dev,
-		((dio_private *) (dev->subdevices + 2 +
+		((struct dio_private *) (dev->subdevices + 2 +
 				group)->private)->WREdgSel, bitmask | status);
 
-	//enable interrupt on selected channel
+	/* enable interrupt on selected channel */
 	status = DEBIread(dev,
-		((dio_private *) (dev->subdevices + 2 +
+		((struct dio_private *) (dev->subdevices + 2 +
 				group)->private)->RDIntSel);
 	DEBIwrite(dev,
-		((dio_private *) (dev->subdevices + 2 +
+		((struct dio_private *) (dev->subdevices + 2 +
 				group)->private)->WRIntSel, bitmask | status);
 
-	//enable edge capture write command
+	/* enable edge capture write command */
 	DEBIwrite(dev, LP_MISC1, MISC1_EDCAP);
 
-	//enable edge capture on selected channel
+	/* enable edge capture on selected channel */
 	status = DEBIread(dev,
-		((dio_private *) (dev->subdevices + 2 +
+		((struct dio_private *) (dev->subdevices + 2 +
 				group)->private)->RDCapSel);
 	DEBIwrite(dev,
-		((dio_private *) (dev->subdevices + 2 +
+		((struct dio_private *) (dev->subdevices + 2 +
 				group)->private)->WRCapSel, bitmask | status);
 
 	return 0;
 }
 
-static int s626_dio_reset_irq(comedi_device * dev, unsigned int group,
+static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int group,
 	unsigned int mask)
 {
 	DEBUG("s626_dio_reset_irq: disable  interrupt on dio channel %d group %d\n", mask, group);
 
-	//disable edge capture write command
+	/* disable edge capture write command */
 	DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
 
-	//enable edge capture on selected channel
+	/* enable edge capture on selected channel */
 	DEBIwrite(dev,
-		((dio_private *) (dev->subdevices + 2 +
+		((struct dio_private *) (dev->subdevices + 2 +
 				group)->private)->WRCapSel, mask);
 
 	return 0;
 }
 
-static int s626_dio_clear_irq(comedi_device * dev)
+static int s626_dio_clear_irq(struct comedi_device *dev)
 {
 	unsigned int group;
 
-	//disable edge capture write command
+	/* disable edge capture write command */
 	DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
 
 	for (group = 0; group < S626_DIO_BANKS; group++) {
-		//clear pending events and interrupt
+		/* clear pending events and interrupt */
 		DEBIwrite(dev,
-			((dio_private *) (dev->subdevices + 2 +
+			((struct dio_private *) (dev->subdevices + 2 +
 					group)->private)->WRCapSel, 0xffff);
 	}
 
@@ -2238,26 +2251,26 @@
 /* Now this function initializes the value of the counter (data[0])
    and set the subdevice. To complete with trigger and interrupt
    configuration */
-static int s626_enc_insn_config(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data)
+static int s626_enc_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data)
 {
-	uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) |	// Preload upon
-		// index.
-		(INDXSRC_SOFT << BF_INDXSRC) |	// Disable hardware index.
-		(CLKSRC_COUNTER << BF_CLKSRC) |	// Operating mode is Counter.
-		(CLKPOL_POS << BF_CLKPOL) |	// Active high clock.
-		//( CNTDIR_UP << BF_CLKPOL ) |      // Count direction is Down.
-		(CLKMULT_1X << BF_CLKMULT) |	// Clock multiplier is 1x.
+	uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) |	/*  Preload upon */
+		/*  index. */
+		(INDXSRC_SOFT << BF_INDXSRC) |	/*  Disable hardware index. */
+		(CLKSRC_COUNTER << BF_CLKSRC) |	/*  Operating mode is Counter. */
+		(CLKPOL_POS << BF_CLKPOL) |	/*  Active high clock. */
+		/* ( CNTDIR_UP << BF_CLKPOL ) |      // Count direction is Down. */
+		(CLKMULT_1X << BF_CLKMULT) |	/*  Clock multiplier is 1x. */
 		(CLKENAB_INDEX << BF_CLKENAB);
 	/*   uint16_t DisableIntSrc=TRUE; */
-	// uint32_t Preloadvalue;              //Counter initial value
+	/*  uint32_t Preloadvalue;              //Counter initial value */
 	uint16_t valueSrclatch = LATCHSRC_AB_READ;
 	uint16_t enab = CLKENAB_ALWAYS;
-	enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
+	struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
 
 	DEBUG("s626_enc_insn_config: encoder config\n");
 
-	//  (data==NULL) ? (Preloadvalue=0) : (Preloadvalue=data[0]);
+	/*   (data==NULL) ? (Preloadvalue=0) : (Preloadvalue=data[0]); */
 
 	k->SetMode(dev, k, Setup, TRUE);
 	Preload(dev, k, *(insn->data));
@@ -2268,12 +2281,12 @@
 	return insn->n;
 }
 
-static int s626_enc_insn_read(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data)
+static int s626_enc_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data)
 {
 
 	int n;
-	enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
+	struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
 
 	DEBUG("s626_enc_insn_read: encoder read channel %d \n",
 		CR_CHAN(insn->chanspec));
@@ -2286,20 +2299,20 @@
 	return n;
 }
 
-static int s626_enc_insn_write(comedi_device * dev, comedi_subdevice * s,
-	comedi_insn * insn, lsampl_t * data)
+static int s626_enc_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
+	struct comedi_insn *insn, unsigned int *data)
 {
 
-	enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
+	struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
 
 	DEBUG("s626_enc_insn_write: encoder write channel %d \n",
 		CR_CHAN(insn->chanspec));
 
-	// Set the preload register
+	/*  Set the preload register */
 	Preload(dev, k, data[0]);
 
-	// Software index pulse forces the preload register to load
-	// into the counter
+	/*  Software index pulse forces the preload register to load */
+	/*  into the counter */
 	k->SetLoadTrig(dev, k, 0);
 	k->PulseIndex(dev, k);
 	k->SetLoadTrig(dev, k, 2);
@@ -2309,175 +2322,165 @@
 	return 1;
 }
 
-static void s626_timer_load(comedi_device * dev, enc_private * k, int tick)
+static void s626_timer_load(struct comedi_device *dev, struct enc_private *k, int tick)
 {
-	uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) |	// Preload upon
-		// index.
-		(INDXSRC_SOFT << BF_INDXSRC) |	// Disable hardware index.
-		(CLKSRC_TIMER << BF_CLKSRC) |	// Operating mode is Timer.
-		(CLKPOL_POS << BF_CLKPOL) |	// Active high clock.
-		(CNTDIR_DOWN << BF_CLKPOL) |	// Count direction is Down.
-		(CLKMULT_1X << BF_CLKMULT) |	// Clock multiplier is 1x.
+	uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) |	/*  Preload upon */
+		/*  index. */
+		(INDXSRC_SOFT << BF_INDXSRC) |	/*  Disable hardware index. */
+		(CLKSRC_TIMER << BF_CLKSRC) |	/*  Operating mode is Timer. */
+		(CLKPOL_POS << BF_CLKPOL) |	/*  Active high clock. */
+		(CNTDIR_DOWN << BF_CLKPOL) |	/*  Count direction is Down. */
+		(CLKMULT_1X << BF_CLKMULT) |	/*  Clock multiplier is 1x. */
 		(CLKENAB_INDEX << BF_CLKENAB);
 	uint16_t valueSrclatch = LATCHSRC_A_INDXA;
-	//  uint16_t enab=CLKENAB_ALWAYS;
+	/*   uint16_t enab=CLKENAB_ALWAYS; */
 
 	k->SetMode(dev, k, Setup, FALSE);
 
-	// Set the preload register
+	/*  Set the preload register */
 	Preload(dev, k, tick);
 
-	// Software index pulse forces the preload register to load
-	// into the counter
+	/*  Software index pulse forces the preload register to load */
+	/*  into the counter */
 	k->SetLoadTrig(dev, k, 0);
 	k->PulseIndex(dev, k);
 
-	//set reload on counter overflow
+	/* set reload on counter overflow */
 	k->SetLoadTrig(dev, k, 1);
 
-	//set interrupt on overflow
+	/* set interrupt on overflow */
 	k->SetIntSrc(dev, k, INTSRC_OVER);
 
 	SetLatchSource(dev, k, valueSrclatch);
-	//  k->SetEnable(dev,k,(uint16_t)(enab != 0));
+	/*   k->SetEnable(dev,k,(uint16_t)(enab != 0)); */
 }
 
-///////////////////////////////////////////////////////////////////////
-/////////////////////  DAC FUNCTIONS /////////////////////////////////
-///////////////////////////////////////////////////////////////////////
+/* ***********  DAC FUNCTIONS *********** */
 
-// Slot 0 base settings.
-#define VECT0	( XSD2 | RSD3 | SIB_A2 )	// Slot 0 always shifts in
-					 // 0xFF and store it to
-					 // FB_BUFFER2.
+/*  Slot 0 base settings. */
+#define VECT0	(XSD2 | RSD3 | SIB_A2)
+/*  Slot 0 always shifts in  0xFF and store it to  FB_BUFFER2. */
 
-// TrimDac LogicalChan-to-PhysicalChan mapping table.
+/*  TrimDac LogicalChan-to-PhysicalChan mapping table. */
 static uint8_t trimchan[] = { 10, 9, 8, 3, 2, 7, 6, 1, 0, 5, 4 };
 
-// TrimDac LogicalChan-to-EepromAdrs mapping table.
+/*  TrimDac LogicalChan-to-EepromAdrs mapping table. */
 static uint8_t trimadrs[] =
 	{ 0x40, 0x41, 0x42, 0x50, 0x51, 0x52, 0x53, 0x60, 0x61, 0x62, 0x63 };
 
-static void LoadTrimDACs(comedi_device * dev)
+static void LoadTrimDACs(struct comedi_device *dev)
 {
 	register uint8_t i;
 
-	// Copy TrimDac setpoint values from EEPROM to TrimDacs.
+	/*  Copy TrimDac setpoint values from EEPROM to TrimDacs. */
 	for (i = 0; i < (sizeof(trimchan) / sizeof(trimchan[0])); i++)
 		WriteTrimDAC(dev, i, I2Cread(dev, trimadrs[i]));
 }
 
-static void WriteTrimDAC(comedi_device * dev, uint8_t LogicalChan,
+static void WriteTrimDAC(struct comedi_device *dev, uint8_t LogicalChan,
 	uint8_t DacData)
 {
 	uint32_t chan;
 
-	// Save the new setpoint in case the application needs to read it back later.
+	/*  Save the new setpoint in case the application needs to read it back later. */
 	devpriv->TrimSetpoint[LogicalChan] = (uint8_t) DacData;
 
-	// Map logical channel number to physical channel number.
+	/*  Map logical channel number to physical channel number. */
 	chan = (uint32_t) trimchan[LogicalChan];
 
-	// Set up TSL2 records for TrimDac write operation.  All slots shift
-	// 0xFF in from pulled-up SD3 so that the end of the slot sequence
-	// can be detected.
-	SETVECT(2, XSD2 | XFIFO_1 | WS3);	// Slot 2: Send high uint8_t
-	// to target TrimDac.
-	SETVECT(3, XSD2 | XFIFO_0 | WS3);	// Slot 3: Send low uint8_t to
-	// target TrimDac.
-	SETVECT(4, XSD2 | XFIFO_3 | WS1);	// Slot 4: Send NOP high
-	// uint8_t to DAC0 to keep
-	// clock running.
-	SETVECT(5, XSD2 | XFIFO_2 | WS1 | EOS);	// Slot 5: Send NOP low
-	// uint8_t to DAC0.
+	/* Set up TSL2 records for TrimDac write operation.  All slots shift
+	 * 0xFF in from pulled-up SD3 so that the end of the slot sequence
+	 * can be detected.
+	 */
 
-	// Construct and transmit target DAC's serial packet: ( 0000 AAAA
-	// ),( DDDD DDDD ),( 0x00 ),( 0x00 ) where A<3:0> is the DAC
-	// channel's address, and D<7:0> is the DAC setpoint.  Append a WORD
-	// value (that writes a channel 0 NOP command to a non-existent main
-	// DAC channel) that serves to keep the clock running after the
-	// packet has been sent to the target DAC.
+	SETVECT(2, XSD2 | XFIFO_1 | WS3);
+	/* Slot 2: Send high uint8_t to target TrimDac. */
+	SETVECT(3, XSD2 | XFIFO_0 | WS3);
+	/* Slot 3: Send low uint8_t to target TrimDac. */
+	SETVECT(4, XSD2 | XFIFO_3 | WS1);
+	/* Slot 4: Send NOP high uint8_t to DAC0 to keep clock running. */
+	SETVECT(5, XSD2 | XFIFO_2 | WS1 | EOS);
+	/* Slot 5: Send NOP low  uint8_t to DAC0. */
 
-	SendDAC(dev, ((uint32_t) chan << 8)	// Address the DAC channel
-		// within the trimdac device.
-		| (uint32_t) DacData);	// Include DAC setpoint data.
+	/* Construct and transmit target DAC's serial packet:
+	 * ( 0000 AAAA ), ( DDDD DDDD ),( 0x00 ),( 0x00 ) where A<3:0> is the
+	 * DAC channel's address, and D<7:0> is the DAC setpoint.  Append a
+	 * WORD value (that writes a channel 0 NOP command to a non-existent
+	 * main DAC channel) that serves to keep the clock running after the
+	 * packet has been sent to the target DAC.
+	 */
+
+	/*  Address the DAC channel within the trimdac device. */
+	SendDAC(dev, ((uint32_t) chan << 8)
+		| (uint32_t) DacData);	/*  Include DAC setpoint data. */
 }
 
-/////////////////////////////////////////////////////////////////////////
-////////////////  EEPROM ACCESS FUNCTIONS  //////////////////////////////
-/////////////////////////////////////////////////////////////////////////
+/* **************  EEPROM ACCESS FUNCTIONS  ************** */
+/*  Read uint8_t from EEPROM. */
 
-///////////////////////////////////////////
-// Read uint8_t from EEPROM.
-
-static uint8_t I2Cread(comedi_device * dev, uint8_t addr)
+static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr)
 {
 	uint8_t rtnval;
 
-	// Send EEPROM target address.
-	if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CW)	// Byte2 = I2C
-			// command:
-			// write to
-			// I2C EEPROM
-			// device.
-			| I2C_B1(I2C_ATTRSTOP, addr)	// Byte1 = EEPROM
-			// internal target
-			// address.
-			| I2C_B0(I2C_ATTRNOP, 0)))	// Byte0 = Not
-		// sent.
-	{
-		// Abort function and declare error if handshake failed.
+	/*  Send EEPROM target address. */
+	if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CW)
+			 /* Byte2 = I2C command: write to I2C EEPROM  device. */
+			| I2C_B1(I2C_ATTRSTOP, addr)
+			 /* Byte1 = EEPROM internal target address. */
+			| I2C_B0(I2C_ATTRNOP, 0))) {	/*  Byte0 = Not sent. */
+		/*  Abort function and declare error if handshake failed. */
 		DEBUG("I2Cread: error handshake I2Cread  a\n");
 		return 0;
 	}
-	// Execute EEPROM read.
-	if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CR)	// Byte2 = I2C
-			// command: read
-			// from I2C EEPROM
-			// device.
-			| I2C_B1(I2C_ATTRSTOP, 0)	// Byte1 receives
-			// uint8_t from
-			// EEPROM.
-			| I2C_B0(I2C_ATTRNOP, 0)))	// Byte0 = Not
-		// sent.
-	{
-		// Abort function and declare error if handshake failed.
+	/*  Execute EEPROM read. */
+	if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CR)	/*  Byte2 = I2C */
+			/*  command: read */
+			/*  from I2C EEPROM */
+			/*  device. */
+			| I2C_B1(I2C_ATTRSTOP, 0)	/*  Byte1 receives */
+			/*  uint8_t from */
+			/*  EEPROM. */
+			| I2C_B0(I2C_ATTRNOP, 0))) {	/*  Byte0 = Not  sent. */
+
+		/*  Abort function and declare error if handshake failed. */
 		DEBUG("I2Cread: error handshake I2Cread b\n");
 		return 0;
 	}
-	// Return copy of EEPROM value.
+	/*  Return copy of EEPROM value. */
 	rtnval = (uint8_t) (RR7146(P_I2CCTRL) >> 16);
 	return rtnval;
 }
 
-static uint32_t I2Chandshake(comedi_device * dev, uint32_t val)
+static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val)
 {
-	// Write I2C command to I2C Transfer Control shadow register.
+	/*  Write I2C command to I2C Transfer Control shadow register. */
 	WR7146(P_I2CCTRL, val);
 
-	// Upload I2C shadow registers into working registers and wait for
-	// upload confirmation.
+	/*  Upload I2C shadow registers into working registers and wait for */
+	/*  upload confirmation. */
 
 	MC_ENABLE(P_MC2, MC2_UPLD_IIC);
-	while (!MC_TEST(P_MC2, MC2_UPLD_IIC)) ;
+	while (!MC_TEST(P_MC2, MC2_UPLD_IIC))
+		;
 
-	// Wait until I2C bus transfer is finished or an error occurs.
-	while ((RR7146(P_I2CCTRL) & (I2C_BUSY | I2C_ERR)) == I2C_BUSY) ;
+	/*  Wait until I2C bus transfer is finished or an error occurs. */
+	while ((RR7146(P_I2CCTRL) & (I2C_BUSY | I2C_ERR)) == I2C_BUSY)
+		;
 
-	// Return non-zero if I2C error occured.
+	/*  Return non-zero if I2C error occured. */
 	return RR7146(P_I2CCTRL) & I2C_ERR;
 
 }
 
-// Private helper function: Write setpoint to an application DAC channel.
+/*  Private helper function: Write setpoint to an application DAC channel. */
 
-static void SetDAC(comedi_device * dev, uint16_t chan, short dacdata)
+static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata)
 {
 	register uint16_t signmask;
 	register uint32_t WSImage;
 
-	// Adjust DAC data polarity and set up Polarity Control Register
-	// image.
+	/*  Adjust DAC data polarity and set up Polarity Control Register */
+	/*  image. */
 	signmask = 1 << chan;
 	if (dacdata < 0) {
 		dacdata = -dacdata;
@@ -2485,237 +2488,252 @@
 	} else
 		devpriv->Dacpol &= ~signmask;
 
-	// Limit DAC setpoint value to valid range.
+	/*  Limit DAC setpoint value to valid range. */
 	if ((uint16_t) dacdata > 0x1FFF)
 		dacdata = 0x1FFF;
 
-	// Set up TSL2 records (aka "vectors") for DAC update.  Vectors V2
-	// and V3 transmit the setpoint to the target DAC.  V4 and V5 send
-	// data to a non-existent TrimDac channel just to keep the clock
-	// running after sending data to the target DAC.  This is necessary
-	// to eliminate the clock glitch that would otherwise occur at the
-	// end of the target DAC's serial data stream.  When the sequence
-	// restarts at V0 (after executing V5), the gate array automatically
-	// disables gating for the DAC clock and all DAC chip selects.
-	WSImage = (chan & 2) ? WS1 : WS2;	// Choose DAC chip select to
-	// be asserted.
-	SETVECT(2, XSD2 | XFIFO_1 | WSImage);	// Slot 2: Transmit high
-	// data byte to target DAC.
-	SETVECT(3, XSD2 | XFIFO_0 | WSImage);	// Slot 3: Transmit low data
-	// byte to target DAC.
-	SETVECT(4, XSD2 | XFIFO_3 | WS3);	// Slot 4: Transmit to
-	// non-existent TrimDac
-	// channel to keep clock
-	SETVECT(5, XSD2 | XFIFO_2 | WS3 | EOS);	// Slot 5: running after
-	// writing target DAC's
-	// low data byte.
+	/* Set up TSL2 records (aka "vectors") for DAC update.  Vectors V2
+	 * and V3 transmit the setpoint to the target DAC.  V4 and V5 send
+	 * data to a non-existent TrimDac channel just to keep the clock
+	 * running after sending data to the target DAC.  This is necessary
+	 * to eliminate the clock glitch that would otherwise occur at the
+	 * end of the target DAC's serial data stream.  When the sequence
+	 * restarts at V0 (after executing V5), the gate array automatically
+	 * disables gating for the DAC clock and all DAC chip selects.
+	 */
 
-	// Construct and transmit target DAC's serial packet: ( A10D DDDD
-	// ),( DDDD DDDD ),( 0x0F ),( 0x00 ) where A is chan<0>, and D<12:0>
-	// is the DAC setpoint.  Append a WORD value (that writes to a
-	// non-existent TrimDac channel) that serves to keep the clock
-	// running after the packet has been sent to the target DAC.
-	SendDAC(dev, 0x0F000000	//Continue clock after target DAC
-		//data (write to non-existent
-		//trimdac).
-		| 0x00004000	// Address the two main dual-DAC
-		// devices (TSL's chip select enables
-		// target device).
-		| ((uint32_t) (chan & 1) << 15)	// Address the DAC
-		// channel within the
-		// device.
-		| (uint32_t) dacdata);	// Include DAC setpoint data.
+	WSImage = (chan & 2) ? WS1 : WS2;
+	/* Choose DAC chip select to be asserted. */
+	SETVECT(2, XSD2 | XFIFO_1 | WSImage);
+	/* Slot 2: Transmit high data byte to target DAC. */
+	SETVECT(3, XSD2 | XFIFO_0 | WSImage);
+	/* Slot 3: Transmit low data byte to target DAC. */
+	SETVECT(4, XSD2 | XFIFO_3 | WS3);
+	/* Slot 4: Transmit to non-existent TrimDac channel to keep clock */
+	SETVECT(5, XSD2 | XFIFO_2 | WS3 | EOS);
+	/* Slot 5: running after writing target DAC's low data byte. */
+
+	/*  Construct and transmit target DAC's serial packet:
+	 * ( A10D DDDD ),( DDDD DDDD ),( 0x0F ),( 0x00 ) where A is chan<0>,
+	 * and D<12:0> is the DAC setpoint.  Append a WORD value (that writes
+	 * to a  non-existent TrimDac channel) that serves to keep the clock
+	 * running after the packet has been sent to the target DAC.
+	 */
+	SendDAC(dev, 0x0F000000
+		/* Continue clock after target DAC data (write to non-existent trimdac). */
+		| 0x00004000
+		/* Address the two main dual-DAC devices (TSL's chip select enables
+		 * target device). */
+		| ((uint32_t) (chan & 1) << 15)
+		/*  Address the DAC channel within the  device. */
+		| (uint32_t) dacdata);	/*  Include DAC setpoint data. */
 
 }
 
-////////////////////////////////////////////////////////
-// Private helper function: Transmit serial data to DAC via Audio
-// channel 2.  Assumes: (1) TSL2 slot records initialized, and (2)
-// Dacpol contains valid target image.
+/* Private helper function: Transmit serial data to DAC via Audio
+ * channel 2.  Assumes: (1) TSL2 slot records initialized, and (2)
+ * Dacpol contains valid target image.
+ */
 
-static void SendDAC(comedi_device * dev, uint32_t val)
+static void SendDAC(struct comedi_device *dev, uint32_t val)
 {
 
-	// START THE SERIAL CLOCK RUNNING -------------
+	/* START THE SERIAL CLOCK RUNNING ------------- */
 
-	// Assert DAC polarity control and enable gating of DAC serial clock
-	// and audio bit stream signals.  At this point in time we must be
-	// assured of being in time slot 0.  If we are not in slot 0, the
-	// serial clock and audio stream signals will be disabled; this is
-	// because the following DEBIwrite statement (which enables signals
-	// to be passed through the gate array) would execute before the
-	// trailing edge of WS1/WS3 (which turns off the signals), thus
-	// causing the signals to be inactive during the DAC write.
+	/* Assert DAC polarity control and enable gating of DAC serial clock
+	 * and audio bit stream signals.  At this point in time we must be
+	 * assured of being in time slot 0.  If we are not in slot 0, the
+	 * serial clock and audio stream signals will be disabled; this is
+	 * because the following DEBIwrite statement (which enables signals
+	 * to be passed through the gate array) would execute before the
+	 * trailing edge of WS1/WS3 (which turns off the signals), thus
+	 * causing the signals to be inactive during the DAC write.
+	 */
 	DEBIwrite(dev, LP_DACPOL, devpriv->Dacpol);
 
-	// TRANSFER OUTPUT DWORD VALUE INTO A2'S OUTPUT FIFO ----------------
+	/* TRANSFER OUTPUT DWORD VALUE INTO A2'S OUTPUT FIFO ---------------- */
 
-	// Copy DAC setpoint value to DAC's output DMA buffer.
+	/* Copy DAC setpoint value to DAC's output DMA buffer. */
 
-	//WR7146( (uint32_t)devpriv->pDacWBuf, val );
+	/* WR7146( (uint32_t)devpriv->pDacWBuf, val ); */
 	*devpriv->pDacWBuf = val;
 
-	// enab the output DMA transfer.  This will cause the DMAC to copy
-	// the DAC's data value to A2's output FIFO.  The DMA transfer will
-	// then immediately terminate because the protection address is
-	// reached upon transfer of the first DWORD value.
+	/* enab the output DMA transfer.  This will cause the DMAC to copy
+	 * the DAC's data value to A2's output FIFO.  The DMA transfer will
+	 * then immediately terminate because the protection address is
+	 * reached upon transfer of the first DWORD value.
+	 */
 	MC_ENABLE(P_MC1, MC1_A2OUT);
 
-	// While the DMA transfer is executing ...
+	/*  While the DMA transfer is executing ... */
 
-	// Reset Audio2 output FIFO's underflow flag (along with any other
-	// FIFO underflow/overflow flags).  When set, this flag will
-	// indicate that we have emerged from slot 0.
+	/* Reset Audio2 output FIFO's underflow flag (along with any other
+	 * FIFO underflow/overflow flags).  When set, this flag will
+	 * indicate that we have emerged from slot 0.
+	 */
 	WR7146(P_ISR, ISR_AFOU);
 
-	// Wait for the DMA transfer to finish so that there will be data
-	// available in the FIFO when time slot 1 tries to transfer a DWORD
-	// from the FIFO to the output buffer register.  We test for DMA
-	// Done by polling the DMAC enable flag; this flag is automatically
-	// cleared when the transfer has finished.
-	while ((RR7146(P_MC1) & MC1_A2OUT) != 0) ;
+	/* Wait for the DMA transfer to finish so that there will be data
+	 * available in the FIFO when time slot 1 tries to transfer a DWORD
+	 * from the FIFO to the output buffer register.  We test for DMA
+	 * Done by polling the DMAC enable flag; this flag is automatically
+	 * cleared when the transfer has finished.
+	 */
+	while ((RR7146(P_MC1) & MC1_A2OUT) != 0)
+		;
 
-	// START THE OUTPUT STREAM TO THE TARGET DAC --------------------
+	/* START THE OUTPUT STREAM TO THE TARGET DAC -------------------- */
 
-	// FIFO data is now available, so we enable execution of time slots
-	// 1 and higher by clearing the EOS flag in slot 0.  Note that SD3
-	// will be shifted in and stored in FB_BUFFER2 for end-of-slot-list
-	// detection.
+	/* FIFO data is now available, so we enable execution of time slots
+	 * 1 and higher by clearing the EOS flag in slot 0.  Note that SD3
+	 * will be shifted in and stored in FB_BUFFER2 for end-of-slot-list
+	 * detection.
+	 */
 	SETVECT(0, XSD2 | RSD3 | SIB_A2);
 
-	// Wait for slot 1 to execute to ensure that the Packet will be
-	// transmitted.  This is detected by polling the Audio2 output FIFO
-	// underflow flag, which will be set when slot 1 execution has
-	// finished transferring the DAC's data DWORD from the output FIFO
-	// to the output buffer register.
-	while ((RR7146(P_SSR) & SSR_AF2_OUT) == 0) ;
+	/* Wait for slot 1 to execute to ensure that the Packet will be
+	 * transmitted.  This is detected by polling the Audio2 output FIFO
+	 * underflow flag, which will be set when slot 1 execution has
+	 * finished transferring the DAC's data DWORD from the output FIFO
+	 * to the output buffer register.
+	 */
+	while ((RR7146(P_SSR) & SSR_AF2_OUT) == 0)
+		;
 
-	// Set up to trap execution at slot 0 when the TSL sequencer cycles
-	// back to slot 0 after executing the EOS in slot 5.  Also,
-	// simultaneously shift out and in the 0x00 that is ALWAYS the value
-	// stored in the last byte to be shifted out of the FIFO's DWORD
-	// buffer register.
+	/* Set up to trap execution at slot 0 when the TSL sequencer cycles
+	 * back to slot 0 after executing the EOS in slot 5.  Also,
+	 * simultaneously shift out and in the 0x00 that is ALWAYS the value
+	 * stored in the last byte to be shifted out of the FIFO's DWORD
+	 * buffer register.
+	 */
 	SETVECT(0, XSD2 | XFIFO_2 | RSD2 | SIB_A2 | EOS);
 
-	// WAIT FOR THE TRANSACTION TO FINISH -----------------------
+	/* WAIT FOR THE TRANSACTION TO FINISH ----------------------- */
 
-	// Wait for the TSL to finish executing all time slots before
-	// exiting this function.  We must do this so that the next DAC
-	// write doesn't start, thereby enabling clock/chip select signals:
-	// 1. Before the TSL sequence cycles back to slot 0, which disables
-	// the clock/cs signal gating and traps slot // list execution.  If
-	// we have not yet finished slot 5 then the clock/cs signals are
-	// still gated and we have // not finished transmitting the stream.
-	// 2. While slots 2-5 are executing due to a late slot 0 trap.  In
-	// this case, the slot sequence is currently // repeating, but with
-	// clock/cs signals disabled.  We must wait for slot 0 to trap
-	// execution before setting // up the next DAC setpoint DMA transfer
-	// and enabling the clock/cs signals.  To detect the end of slot 5,
-	// we test for the FB_BUFFER2 MSB contents to be equal to 0xFF.  If
-	// the TSL has not yet finished executing slot 5 ...
+	/* Wait for the TSL to finish executing all time slots before
+	 * exiting this function.  We must do this so that the next DAC
+	 * write doesn't start, thereby enabling clock/chip select signals:
+	 *
+	 * 1. Before the TSL sequence cycles back to slot 0, which disables
+	 *    the clock/cs signal gating and traps slot // list execution.
+	 *    we have not yet finished slot 5 then the clock/cs signals are
+	 *    still gated and we have not finished transmitting the stream.
+	 *
+	 * 2. While slots 2-5 are executing due to a late slot 0 trap.  In
+	 *    this case, the slot sequence is currently repeating, but with
+	 *    clock/cs signals disabled.  We must wait for slot 0 to trap
+	 *    execution before setting up the next DAC setpoint DMA transfer
+	 *    and enabling the clock/cs signals.  To detect the end of slot 5,
+	 *    we test for the FB_BUFFER2 MSB contents to be equal to 0xFF.  If
+	 *    the TSL has not yet finished executing slot 5 ...
+	 */
 	if ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0) {
-		// The trap was set on time and we are still executing somewhere
-		// in slots 2-5, so we now wait for slot 0 to execute and trap
-		// TSL execution.  This is detected when FB_BUFFER2 MSB changes
-		// from 0xFF to 0x00, which slot 0 causes to happen by shifting
-		// out/in on SD2 the 0x00 that is always referenced by slot 5.
-		while ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0) ;
+		/* The trap was set on time and we are still executing somewhere
+		 * in slots 2-5, so we now wait for slot 0 to execute and trap
+		 * TSL execution.  This is detected when FB_BUFFER2 MSB changes
+		 * from 0xFF to 0x00, which slot 0 causes to happen by shifting
+		 * out/in on SD2 the 0x00 that is always referenced by slot 5.
+		 */
+		 while ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0)
+			;
 	}
-	// Either (1) we were too late setting the slot 0 trap; the TSL
-	// sequencer restarted slot 0 before we could set the EOS trap flag,
-	// or (2) we were not late and execution is now trapped at slot 0.
-	// In either case, we must now change slot 0 so that it will store
-	// value 0xFF (instead of 0x00) to FB_BUFFER2 next time it executes.
-	// In order to do this, we reprogram slot 0 so that it will shift in
-	// SD3, which is driven only by a pull-up resistor.
+	/* Either (1) we were too late setting the slot 0 trap; the TSL
+	 * sequencer restarted slot 0 before we could set the EOS trap flag,
+	 * or (2) we were not late and execution is now trapped at slot 0.
+	 * In either case, we must now change slot 0 so that it will store
+	 * value 0xFF (instead of 0x00) to FB_BUFFER2 next time it executes.
+	 * In order to do this, we reprogram slot 0 so that it will shift in
+	 * SD3, which is driven only by a pull-up resistor.
+	 */
 	SETVECT(0, RSD3 | SIB_A2 | EOS);
 
-	// Wait for slot 0 to execute, at which time the TSL is setup for
-	// the next DAC write.  This is detected when FB_BUFFER2 MSB changes
-	// from 0x00 to 0xFF.
-	while ((RR7146(P_FB_BUFFER2) & 0xFF000000) == 0) ;
+	/* Wait for slot 0 to execute, at which time the TSL is setup for
+	 * the next DAC write.  This is detected when FB_BUFFER2 MSB changes
+	 * from 0x00 to 0xFF.
+	 */
+	while ((RR7146(P_FB_BUFFER2) & 0xFF000000) == 0)
+		;
 }
 
-static void WriteMISC2(comedi_device * dev, uint16_t NewImage)
+static void WriteMISC2(struct comedi_device *dev, uint16_t NewImage)
 {
-	DEBIwrite(dev, LP_MISC1, MISC1_WENABLE);	// enab writes to
-	// MISC2 register.
-	DEBIwrite(dev, LP_WRMISC2, NewImage);	// Write new image to MISC2.
-	DEBIwrite(dev, LP_MISC1, MISC1_WDISABLE);	// Disable writes to MISC2.
+	DEBIwrite(dev, LP_MISC1, MISC1_WENABLE);	/*  enab writes to */
+	/*  MISC2 register. */
+	DEBIwrite(dev, LP_WRMISC2, NewImage);	/*  Write new image to MISC2. */
+	DEBIwrite(dev, LP_MISC1, MISC1_WDISABLE);	/*  Disable writes to MISC2. */
 }
 
-/////////////////////////////////////////////////////////////////////
-// Initialize the DEBI interface for all transfers.
+/*  Initialize the DEBI interface for all transfers. */
 
-static uint16_t DEBIread(comedi_device * dev, uint16_t addr)
+static uint16_t DEBIread(struct comedi_device *dev, uint16_t addr)
 {
 	uint16_t retval;
 
-	// Set up DEBI control register value in shadow RAM.
+	/*  Set up DEBI control register value in shadow RAM. */
 	WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr);
 
-	// Execute the DEBI transfer.
+	/*  Execute the DEBI transfer. */
 	DEBItransfer(dev);
 
-	// Fetch target register value.
+	/*  Fetch target register value. */
 	retval = (uint16_t) RR7146(P_DEBIAD);
 
-	// Return register value.
+	/*  Return register value. */
 	return retval;
 }
 
-// Execute a DEBI transfer.  This must be called from within a
-// critical section.
-static void DEBItransfer(comedi_device * dev)
+/*  Execute a DEBI transfer.  This must be called from within a */
+/*  critical section. */
+static void DEBItransfer(struct comedi_device *dev)
 {
-	// Initiate upload of shadow RAM to DEBI control register.
+	/*  Initiate upload of shadow RAM to DEBI control register. */
 	MC_ENABLE(P_MC2, MC2_UPLD_DEBI);
 
-	// Wait for completion of upload from shadow RAM to DEBI control
-	// register.
-	while (!MC_TEST(P_MC2, MC2_UPLD_DEBI)) ;
+	/*  Wait for completion of upload from shadow RAM to DEBI control */
+	/*  register. */
+	while (!MC_TEST(P_MC2, MC2_UPLD_DEBI))
+		;
 
-	// Wait until DEBI transfer is done.
-	while (RR7146(P_PSR) & PSR_DEBI_S) ;
+	/*  Wait until DEBI transfer is done. */
+	while (RR7146(P_PSR) & PSR_DEBI_S)
+		;
 }
 
-// Write a value to a gate array register.
-static void DEBIwrite(comedi_device * dev, uint16_t addr, uint16_t wdata)
+/*  Write a value to a gate array register. */
+static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata)
 {
 
-	// Set up DEBI control register value in shadow RAM.
+	/*  Set up DEBI control register value in shadow RAM. */
 	WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr);
 	WR7146(P_DEBIAD, wdata);
 
-	// Execute the DEBI transfer.
+	/*  Execute the DEBI transfer. */
 	DEBItransfer(dev);
 }
 
-/////////////////////////////////////////////////////////////////////////////
-// Replace the specified bits in a gate array register.  Imports: mask
-// specifies bits that are to be preserved, wdata is new value to be
-// or'd with the masked original.
-static void DEBIreplace(comedi_device * dev, uint16_t addr, uint16_t mask,
+/* Replace the specified bits in a gate array register.  Imports: mask
+ * specifies bits that are to be preserved, wdata is new value to be
+ * or'd with the masked original.
+ */
+static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask,
 	uint16_t wdata)
 {
 
-	// Copy target gate array register into P_DEBIAD register.
-	WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr);	// Set up DEBI control
-	// reg value in shadow
-	// RAM.
-	DEBItransfer(dev);	// Execute the DEBI
-	// Read transfer.
+	/*  Copy target gate array register into P_DEBIAD register. */
+	WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr);
+	/* Set up DEBI control reg value in shadow RAM. */
+	DEBItransfer(dev);	/*  Execute the DEBI Read transfer. */
 
-	// Write back the modified image.
-	WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr);	// Set up DEBI control
-	// reg value in shadow
-	// RAM.
+	/*  Write back the modified image. */
+	WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr);
+	/* Set up DEBI control reg value in shadow  RAM. */
 
-	WR7146(P_DEBIAD, wdata | ((uint16_t) RR7146(P_DEBIAD) & mask));	// Modify the register image.
-	DEBItransfer(dev);	// Execute the DEBI Write transfer.
+	WR7146(P_DEBIAD, wdata | ((uint16_t) RR7146(P_DEBIAD) & mask));
+	/* Modify the register image. */
+	DEBItransfer(dev);	/*  Execute the DEBI Write transfer. */
 }
 
-static void CloseDMAB(comedi_device * dev, DMABUF * pdma, size_t bsize)
+static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma, size_t bsize)
 {
 	void *vbptr;
 	dma_addr_t vpptr;
@@ -2723,7 +2741,7 @@
 	DEBUG("CloseDMAB: Entering S626DRV_CloseDMAB():\n");
 	if (pdma == NULL)
 		return;
-	//find the matching allocation from the board struct
+	/* find the matching allocation from the board struct */
 
 	vbptr = pdma->LogicalBase;
 	vpptr = pdma->PhysicalBase;
@@ -2737,268 +2755,260 @@
 	}
 }
 
-////////////////////////////////////////////////////////////////////////
-/////////////////  COUNTER FUNCTIONS  //////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-// All counter functions address a specific counter by means of the
-// "Counter" argument, which is a logical counter number.  The Counter
-// argument may have any of the following legal values: 0=0A, 1=1A,
-// 2=2A, 3=0B, 4=1B, 5=2B.
-////////////////////////////////////////////////////////////////////////
+/* ******  COUNTER FUNCTIONS  ******* */
+/* All counter functions address a specific counter by means of the
+ * "Counter" argument, which is a logical counter number.  The Counter
+ * argument may have any of the following legal values: 0=0A, 1=1A,
+ * 2=2A, 3=0B, 4=1B, 5=2B.
+ */
 
-// Forward declarations for functions that are common to both A and B
-// counters:
+/* Forward declarations for functions that are common to both A and B counters: */
 
-/////////////////////////////////////////////////////////////////////
-//////////////////// PRIVATE COUNTER FUNCTIONS  /////////////////////
-/////////////////////////////////////////////////////////////////////
+/* ******  PRIVATE COUNTER FUNCTIONS ****** */
 
-/////////////////////////////////////////////////////////////////
-// Read a counter's output latch.
+/*  Read a counter's output latch. */
 
-static uint32_t ReadLatch(comedi_device * dev, enc_private * k)
+static uint32_t ReadLatch(struct comedi_device *dev, struct enc_private *k)
 {
 	register uint32_t value;
-	//DEBUG FIXME DEBUG("ReadLatch: Read Latch enter\n");
+	/* DEBUG FIXME DEBUG("ReadLatch: Read Latch enter\n"); */
 
-	// Latch counts and fetch LSW of latched counts value.
+	/*  Latch counts and fetch LSW of latched counts value. */
 	value = (uint32_t) DEBIread(dev, k->MyLatchLsw);
 
-	// Fetch MSW of latched counts and combine with LSW.
+	/*  Fetch MSW of latched counts and combine with LSW. */
 	value |= ((uint32_t) DEBIread(dev, k->MyLatchLsw + 2) << 16);
 
-	// DEBUG FIXME DEBUG("ReadLatch: Read Latch exit\n");
+	/*  DEBUG FIXME DEBUG("ReadLatch: Read Latch exit\n"); */
 
-	// Return latched counts.
+	/*  Return latched counts. */
 	return value;
 }
 
-///////////////////////////////////////////////////////////////////
-// Reset a counter's index and overflow event capture flags.
+/*  Reset a counter's index and overflow event capture flags. */
 
-static void ResetCapFlags_A(comedi_device * dev, enc_private * k)
+static void ResetCapFlags_A(struct comedi_device *dev, struct enc_private *k)
 {
 	DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL),
 		CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A);
 }
 
-static void ResetCapFlags_B(comedi_device * dev, enc_private * k)
+static void ResetCapFlags_B(struct comedi_device *dev, struct enc_private *k)
 {
 	DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL),
 		CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B);
 }
 
-/////////////////////////////////////////////////////////////////////////
-// Return counter setup in a format (COUNTER_SETUP) that is consistent
-// for both A and B counters.
+/*  Return counter setup in a format (COUNTER_SETUP) that is consistent */
+/*  for both A and B counters. */
 
-static uint16_t GetMode_A(comedi_device * dev, enc_private * k)
+static uint16_t GetMode_A(struct comedi_device *dev, struct enc_private *k)
 {
 	register uint16_t cra;
 	register uint16_t crb;
 	register uint16_t setup;
 
-	// Fetch CRA and CRB register images.
+	/*  Fetch CRA and CRB register images. */
 	cra = DEBIread(dev, k->MyCRA);
 	crb = DEBIread(dev, k->MyCRB);
 
-	// Populate the standardized counter setup bit fields.  Note:
-	// IndexSrc is restricted to ENC_X or IndxPol.
-	setup = ((cra & STDMSK_LOADSRC)	// LoadSrc  = LoadSrcA.
-		| ((crb << (STDBIT_LATCHSRC - CRBBIT_LATCHSRC)) & STDMSK_LATCHSRC)	// LatchSrc = LatchSrcA.
-		| ((cra << (STDBIT_INTSRC - CRABIT_INTSRC_A)) & STDMSK_INTSRC)	// IntSrc   = IntSrcA.
-		| ((cra << (STDBIT_INDXSRC - (CRABIT_INDXSRC_A + 1))) & STDMSK_INDXSRC)	// IndxSrc  = IndxSrcA<1>.
-		| ((cra >> (CRABIT_INDXPOL_A - STDBIT_INDXPOL)) & STDMSK_INDXPOL)	// IndxPol  = IndxPolA.
-		| ((crb >> (CRBBIT_CLKENAB_A - STDBIT_CLKENAB)) & STDMSK_CLKENAB));	// ClkEnab  = ClkEnabA.
+	/*  Populate the standardized counter setup bit fields.  Note: */
+	/*  IndexSrc is restricted to ENC_X or IndxPol. */
+	setup = ((cra & STDMSK_LOADSRC)	/*  LoadSrc  = LoadSrcA. */
+		| ((crb << (STDBIT_LATCHSRC - CRBBIT_LATCHSRC)) & STDMSK_LATCHSRC)	/*  LatchSrc = LatchSrcA. */
+		| ((cra << (STDBIT_INTSRC - CRABIT_INTSRC_A)) & STDMSK_INTSRC)	/*  IntSrc   = IntSrcA. */
+		| ((cra << (STDBIT_INDXSRC - (CRABIT_INDXSRC_A + 1))) & STDMSK_INDXSRC)	/*  IndxSrc  = IndxSrcA<1>. */
+		| ((cra >> (CRABIT_INDXPOL_A - STDBIT_INDXPOL)) & STDMSK_INDXPOL)	/*  IndxPol  = IndxPolA. */
+		| ((crb >> (CRBBIT_CLKENAB_A - STDBIT_CLKENAB)) & STDMSK_CLKENAB));	/*  ClkEnab  = ClkEnabA. */
 
-	// Adjust mode-dependent parameters.
-	if (cra & (2 << CRABIT_CLKSRC_A))	// If Timer mode (ClkSrcA<1> == 1):
-		setup |= ((CLKSRC_TIMER << STDBIT_CLKSRC)	//   Indicate Timer mode.
-			| ((cra << (STDBIT_CLKPOL - CRABIT_CLKSRC_A)) & STDMSK_CLKPOL)	//   Set ClkPol to indicate count direction (ClkSrcA<0>).
-			| (MULT_X1 << STDBIT_CLKMULT));	//   ClkMult must be 1x in Timer mode.
+	/*  Adjust mode-dependent parameters. */
+	if (cra & (2 << CRABIT_CLKSRC_A))	/*  If Timer mode (ClkSrcA<1> == 1): */
+		setup |= ((CLKSRC_TIMER << STDBIT_CLKSRC)	/*    Indicate Timer mode. */
+			| ((cra << (STDBIT_CLKPOL - CRABIT_CLKSRC_A)) & STDMSK_CLKPOL)	/*    Set ClkPol to indicate count direction (ClkSrcA<0>). */
+			| (MULT_X1 << STDBIT_CLKMULT));	/*    ClkMult must be 1x in Timer mode. */
 
-	else			// If Counter mode (ClkSrcA<1> == 0):
-		setup |= ((CLKSRC_COUNTER << STDBIT_CLKSRC)	//   Indicate Counter mode.
-			| ((cra >> (CRABIT_CLKPOL_A - STDBIT_CLKPOL)) & STDMSK_CLKPOL)	//   Pass through ClkPol.
-			| (((cra & CRAMSK_CLKMULT_A) == (MULT_X0 << CRABIT_CLKMULT_A)) ?	//   Force ClkMult to 1x if not legal, else pass through.
+	else			/*  If Counter mode (ClkSrcA<1> == 0): */
+		setup |= ((CLKSRC_COUNTER << STDBIT_CLKSRC)	/*    Indicate Counter mode. */
+			| ((cra >> (CRABIT_CLKPOL_A - STDBIT_CLKPOL)) & STDMSK_CLKPOL)	/*    Pass through ClkPol. */
+			| (((cra & CRAMSK_CLKMULT_A) == (MULT_X0 << CRABIT_CLKMULT_A)) ?	/*    Force ClkMult to 1x if not legal, else pass through. */
 				(MULT_X1 << STDBIT_CLKMULT) :
 				((cra >> (CRABIT_CLKMULT_A -
 							STDBIT_CLKMULT)) &
 					STDMSK_CLKMULT)));
 
-	// Return adjusted counter setup.
+	/*  Return adjusted counter setup. */
 	return setup;
 }
 
-static uint16_t GetMode_B(comedi_device * dev, enc_private * k)
+static uint16_t GetMode_B(struct comedi_device *dev, struct enc_private *k)
 {
 	register uint16_t cra;
 	register uint16_t crb;
 	register uint16_t setup;
 
-	// Fetch CRA and CRB register images.
+	/*  Fetch CRA and CRB register images. */
 	cra = DEBIread(dev, k->MyCRA);
 	crb = DEBIread(dev, k->MyCRB);
 
-	// Populate the standardized counter setup bit fields.  Note:
-	// IndexSrc is restricted to ENC_X or IndxPol.
-	setup = (((crb << (STDBIT_INTSRC - CRBBIT_INTSRC_B)) & STDMSK_INTSRC)	// IntSrc   = IntSrcB.
-		| ((crb << (STDBIT_LATCHSRC - CRBBIT_LATCHSRC)) & STDMSK_LATCHSRC)	// LatchSrc = LatchSrcB.
-		| ((crb << (STDBIT_LOADSRC - CRBBIT_LOADSRC_B)) & STDMSK_LOADSRC)	// LoadSrc  = LoadSrcB.
-		| ((crb << (STDBIT_INDXPOL - CRBBIT_INDXPOL_B)) & STDMSK_INDXPOL)	// IndxPol  = IndxPolB.
-		| ((crb >> (CRBBIT_CLKENAB_B - STDBIT_CLKENAB)) & STDMSK_CLKENAB)	// ClkEnab  = ClkEnabB.
-		| ((cra >> ((CRABIT_INDXSRC_B + 1) - STDBIT_INDXSRC)) & STDMSK_INDXSRC));	// IndxSrc  = IndxSrcB<1>.
+	/*  Populate the standardized counter setup bit fields.  Note: */
+	/*  IndexSrc is restricted to ENC_X or IndxPol. */
+	setup = (((crb << (STDBIT_INTSRC - CRBBIT_INTSRC_B)) & STDMSK_INTSRC)	/*  IntSrc   = IntSrcB. */
+		| ((crb << (STDBIT_LATCHSRC - CRBBIT_LATCHSRC)) & STDMSK_LATCHSRC)	/*  LatchSrc = LatchSrcB. */
+		| ((crb << (STDBIT_LOADSRC - CRBBIT_LOADSRC_B)) & STDMSK_LOADSRC)	/*  LoadSrc  = LoadSrcB. */
+		| ((crb << (STDBIT_INDXPOL - CRBBIT_INDXPOL_B)) & STDMSK_INDXPOL)	/*  IndxPol  = IndxPolB. */
+		| ((crb >> (CRBBIT_CLKENAB_B - STDBIT_CLKENAB)) & STDMSK_CLKENAB)	/*  ClkEnab  = ClkEnabB. */
+		| ((cra >> ((CRABIT_INDXSRC_B + 1) - STDBIT_INDXSRC)) & STDMSK_INDXSRC));	/*  IndxSrc  = IndxSrcB<1>. */
 
-	// Adjust mode-dependent parameters.
-	if ((crb & CRBMSK_CLKMULT_B) == (MULT_X0 << CRBBIT_CLKMULT_B))	// If Extender mode (ClkMultB == MULT_X0):
-		setup |= ((CLKSRC_EXTENDER << STDBIT_CLKSRC)	//   Indicate Extender mode.
-			| (MULT_X1 << STDBIT_CLKMULT)	//   Indicate multiplier is 1x.
-			| ((cra >> (CRABIT_CLKSRC_B - STDBIT_CLKPOL)) & STDMSK_CLKPOL));	//   Set ClkPol equal to Timer count direction (ClkSrcB<0>).
+	/*  Adjust mode-dependent parameters. */
+	if ((crb & CRBMSK_CLKMULT_B) == (MULT_X0 << CRBBIT_CLKMULT_B))	/*  If Extender mode (ClkMultB == MULT_X0): */
+		setup |= ((CLKSRC_EXTENDER << STDBIT_CLKSRC)	/*    Indicate Extender mode. */
+			| (MULT_X1 << STDBIT_CLKMULT)	/*    Indicate multiplier is 1x. */
+			| ((cra >> (CRABIT_CLKSRC_B - STDBIT_CLKPOL)) & STDMSK_CLKPOL));	/*    Set ClkPol equal to Timer count direction (ClkSrcB<0>). */
 
-	else if (cra & (2 << CRABIT_CLKSRC_B))	// If Timer mode (ClkSrcB<1> == 1):
-		setup |= ((CLKSRC_TIMER << STDBIT_CLKSRC)	//   Indicate Timer mode.
-			| (MULT_X1 << STDBIT_CLKMULT)	//   Indicate multiplier is 1x.
-			| ((cra >> (CRABIT_CLKSRC_B - STDBIT_CLKPOL)) & STDMSK_CLKPOL));	//   Set ClkPol equal to Timer count direction (ClkSrcB<0>).
+	else if (cra & (2 << CRABIT_CLKSRC_B))	/*  If Timer mode (ClkSrcB<1> == 1): */
+		setup |= ((CLKSRC_TIMER << STDBIT_CLKSRC)	/*    Indicate Timer mode. */
+			| (MULT_X1 << STDBIT_CLKMULT)	/*    Indicate multiplier is 1x. */
+			| ((cra >> (CRABIT_CLKSRC_B - STDBIT_CLKPOL)) & STDMSK_CLKPOL));	/*    Set ClkPol equal to Timer count direction (ClkSrcB<0>). */
 
-	else			// If Counter mode (ClkSrcB<1> == 0):
-		setup |= ((CLKSRC_COUNTER << STDBIT_CLKSRC)	//   Indicate Timer mode.
-			| ((crb >> (CRBBIT_CLKMULT_B - STDBIT_CLKMULT)) & STDMSK_CLKMULT)	//   Clock multiplier is passed through.
-			| ((crb << (STDBIT_CLKPOL - CRBBIT_CLKPOL_B)) & STDMSK_CLKPOL));	//   Clock polarity is passed through.
+	else			/*  If Counter mode (ClkSrcB<1> == 0): */
+		setup |= ((CLKSRC_COUNTER << STDBIT_CLKSRC)	/*    Indicate Timer mode. */
+			| ((crb >> (CRBBIT_CLKMULT_B - STDBIT_CLKMULT)) & STDMSK_CLKMULT)	/*    Clock multiplier is passed through. */
+			| ((crb << (STDBIT_CLKPOL - CRBBIT_CLKPOL_B)) & STDMSK_CLKPOL));	/*    Clock polarity is passed through. */
 
-	// Return adjusted counter setup.
+	/*  Return adjusted counter setup. */
 	return setup;
 }
 
-/////////////////////////////////////////////////////////////////////////////////////////////
-// Set the operating mode for the specified counter.  The setup
-// parameter is treated as a COUNTER_SETUP data type.  The following
-// parameters are programmable (all other parms are ignored): ClkMult,
-// ClkPol, ClkEnab, IndexSrc, IndexPol, LoadSrc.
+/*
+ * Set the operating mode for the specified counter.  The setup
+ * parameter is treated as a COUNTER_SETUP data type.  The following
+ * parameters are programmable (all other parms are ignored): ClkMult,
+ * ClkPol, ClkEnab, IndexSrc, IndexPol, LoadSrc.
+ */
 
-static void SetMode_A(comedi_device * dev, enc_private * k, uint16_t Setup,
+static void SetMode_A(struct comedi_device *dev, struct enc_private *k, uint16_t Setup,
 	uint16_t DisableIntSrc)
 {
 	register uint16_t cra;
 	register uint16_t crb;
-	register uint16_t setup = Setup;	// Cache the Standard Setup.
+	register uint16_t setup = Setup;	/*  Cache the Standard Setup. */
 
-	// Initialize CRA and CRB images.
-	cra = ((setup & CRAMSK_LOADSRC_A)	// Preload trigger is passed through.
-		| ((setup & STDMSK_INDXSRC) >> (STDBIT_INDXSRC - (CRABIT_INDXSRC_A + 1))));	// IndexSrc is restricted to ENC_X or IndxPol.
+	/*  Initialize CRA and CRB images. */
+	cra = ((setup & CRAMSK_LOADSRC_A)	/*  Preload trigger is passed through. */
+		| ((setup & STDMSK_INDXSRC) >> (STDBIT_INDXSRC - (CRABIT_INDXSRC_A + 1))));	/*  IndexSrc is restricted to ENC_X or IndxPol. */
 
-	crb = (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A	// Reset any pending CounterA event captures.
-		| ((setup & STDMSK_CLKENAB) << (CRBBIT_CLKENAB_A - STDBIT_CLKENAB)));	// Clock enable is passed through.
+	crb = (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A	/*  Reset any pending CounterA event captures. */
+		| ((setup & STDMSK_CLKENAB) << (CRBBIT_CLKENAB_A - STDBIT_CLKENAB)));	/*  Clock enable is passed through. */
 
-	// Force IntSrc to Disabled if DisableIntSrc is asserted.
+	/*  Force IntSrc to Disabled if DisableIntSrc is asserted. */
 	if (!DisableIntSrc)
 		cra |= ((setup & STDMSK_INTSRC) >> (STDBIT_INTSRC -
 				CRABIT_INTSRC_A));
 
-	// Populate all mode-dependent attributes of CRA & CRB images.
+	/*  Populate all mode-dependent attributes of CRA & CRB images. */
 	switch ((setup & STDMSK_CLKSRC) >> STDBIT_CLKSRC) {
-	case CLKSRC_EXTENDER:	// Extender Mode: Force to Timer mode
-		// (Extender valid only for B counters).
+	case CLKSRC_EXTENDER:	/*  Extender Mode: Force to Timer mode */
+		/*  (Extender valid only for B counters). */
 
-	case CLKSRC_TIMER:	// Timer Mode:
-		cra |= ((2 << CRABIT_CLKSRC_A)	//   ClkSrcA<1> selects system clock
-			| ((setup & STDMSK_CLKPOL) >> (STDBIT_CLKPOL - CRABIT_CLKSRC_A))	//     with count direction (ClkSrcA<0>) obtained from ClkPol.
-			| (1 << CRABIT_CLKPOL_A)	//   ClkPolA behaves as always-on clock enable.
-			| (MULT_X1 << CRABIT_CLKMULT_A));	//   ClkMult must be 1x.
+	case CLKSRC_TIMER:	/*  Timer Mode: */
+		cra |= ((2 << CRABIT_CLKSRC_A)	/*    ClkSrcA<1> selects system clock */
+			| ((setup & STDMSK_CLKPOL) >> (STDBIT_CLKPOL - CRABIT_CLKSRC_A))	/*      with count direction (ClkSrcA<0>) obtained from ClkPol. */
+			| (1 << CRABIT_CLKPOL_A)	/*    ClkPolA behaves as always-on clock enable. */
+			| (MULT_X1 << CRABIT_CLKMULT_A));	/*    ClkMult must be 1x. */
 		break;
 
-	default:		// Counter Mode:
-		cra |= (CLKSRC_COUNTER	//   Select ENC_C and ENC_D as clock/direction inputs.
-			| ((setup & STDMSK_CLKPOL) << (CRABIT_CLKPOL_A - STDBIT_CLKPOL))	//   Clock polarity is passed through.
-			| (((setup & STDMSK_CLKMULT) == (MULT_X0 << STDBIT_CLKMULT)) ?	//   Force multiplier to x1 if not legal, otherwise pass through.
+	default:		/*  Counter Mode: */
+		cra |= (CLKSRC_COUNTER	/*    Select ENC_C and ENC_D as clock/direction inputs. */
+			| ((setup & STDMSK_CLKPOL) << (CRABIT_CLKPOL_A - STDBIT_CLKPOL))	/*    Clock polarity is passed through. */
+			| (((setup & STDMSK_CLKMULT) == (MULT_X0 << STDBIT_CLKMULT)) ?	/*    Force multiplier to x1 if not legal, otherwise pass through. */
 				(MULT_X1 << CRABIT_CLKMULT_A) :
 				((setup & STDMSK_CLKMULT) << (CRABIT_CLKMULT_A -
 						STDBIT_CLKMULT))));
 	}
 
-	// Force positive index polarity if IndxSrc is software-driven only,
-	// otherwise pass it through.
+	/*  Force positive index polarity if IndxSrc is software-driven only, */
+	/*  otherwise pass it through. */
 	if (~setup & STDMSK_INDXSRC)
 		cra |= ((setup & STDMSK_INDXPOL) << (CRABIT_INDXPOL_A -
 				STDBIT_INDXPOL));
 
-	// If IntSrc has been forced to Disabled, update the MISC2 interrupt
-	// enable mask to indicate the counter interrupt is disabled.
+	/*  If IntSrc has been forced to Disabled, update the MISC2 interrupt */
+	/*  enable mask to indicate the counter interrupt is disabled. */
 	if (DisableIntSrc)
 		devpriv->CounterIntEnabs &= ~k->MyEventBits[3];
 
-	// While retaining CounterB and LatchSrc configurations, program the
-	// new counter operating mode.
+	/*  While retaining CounterB and LatchSrc configurations, program the */
+	/*  new counter operating mode. */
 	DEBIreplace(dev, k->MyCRA, CRAMSK_INDXSRC_B | CRAMSK_CLKSRC_B, cra);
 	DEBIreplace(dev, k->MyCRB,
 		(uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A)), crb);
 }
 
-static void SetMode_B(comedi_device * dev, enc_private * k, uint16_t Setup,
+static void SetMode_B(struct comedi_device *dev, struct enc_private *k, uint16_t Setup,
 	uint16_t DisableIntSrc)
 {
 	register uint16_t cra;
 	register uint16_t crb;
-	register uint16_t setup = Setup;	// Cache the Standard Setup.
+	register uint16_t setup = Setup;	/*  Cache the Standard Setup. */
 
-	// Initialize CRA and CRB images.
-	cra = ((setup & STDMSK_INDXSRC) << ((CRABIT_INDXSRC_B + 1) - STDBIT_INDXSRC));	// IndexSrc field is restricted to ENC_X or IndxPol.
+	/*  Initialize CRA and CRB images. */
+	cra = ((setup & STDMSK_INDXSRC) << ((CRABIT_INDXSRC_B + 1) - STDBIT_INDXSRC));	/*  IndexSrc field is restricted to ENC_X or IndxPol. */
 
-	crb = (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B	// Reset event captures and disable interrupts.
-		| ((setup & STDMSK_CLKENAB) << (CRBBIT_CLKENAB_B - STDBIT_CLKENAB))	// Clock enable is passed through.
-		| ((setup & STDMSK_LOADSRC) >> (STDBIT_LOADSRC - CRBBIT_LOADSRC_B)));	// Preload trigger source is passed through.
+	crb = (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B	/*  Reset event captures and disable interrupts. */
+		| ((setup & STDMSK_CLKENAB) << (CRBBIT_CLKENAB_B - STDBIT_CLKENAB))	/*  Clock enable is passed through. */
+		| ((setup & STDMSK_LOADSRC) >> (STDBIT_LOADSRC - CRBBIT_LOADSRC_B)));	/*  Preload trigger source is passed through. */
 
-	// Force IntSrc to Disabled if DisableIntSrc is asserted.
+	/*  Force IntSrc to Disabled if DisableIntSrc is asserted. */
 	if (!DisableIntSrc)
 		crb |= ((setup & STDMSK_INTSRC) >> (STDBIT_INTSRC -
 				CRBBIT_INTSRC_B));
 
-	// Populate all mode-dependent attributes of CRA & CRB images.
+	/*  Populate all mode-dependent attributes of CRA & CRB images. */
 	switch ((setup & STDMSK_CLKSRC) >> STDBIT_CLKSRC) {
-	case CLKSRC_TIMER:	// Timer Mode:
-		cra |= ((2 << CRABIT_CLKSRC_B)	//   ClkSrcB<1> selects system clock
-			| ((setup & STDMSK_CLKPOL) << (CRABIT_CLKSRC_B - STDBIT_CLKPOL)));	//     with direction (ClkSrcB<0>) obtained from ClkPol.
-		crb |= ((1 << CRBBIT_CLKPOL_B)	//   ClkPolB behaves as always-on clock enable.
-			| (MULT_X1 << CRBBIT_CLKMULT_B));	//   ClkMultB must be 1x.
+	case CLKSRC_TIMER:	/*  Timer Mode: */
+		cra |= ((2 << CRABIT_CLKSRC_B)	/*    ClkSrcB<1> selects system clock */
+			| ((setup & STDMSK_CLKPOL) << (CRABIT_CLKSRC_B - STDBIT_CLKPOL)));	/*      with direction (ClkSrcB<0>) obtained from ClkPol. */
+		crb |= ((1 << CRBBIT_CLKPOL_B)	/*    ClkPolB behaves as always-on clock enable. */
+			| (MULT_X1 << CRBBIT_CLKMULT_B));	/*    ClkMultB must be 1x. */
 		break;
 
-	case CLKSRC_EXTENDER:	// Extender Mode:
-		cra |= ((2 << CRABIT_CLKSRC_B)	//   ClkSrcB source is OverflowA (same as "timer")
-			| ((setup & STDMSK_CLKPOL) << (CRABIT_CLKSRC_B - STDBIT_CLKPOL)));	//     with direction obtained from ClkPol.
-		crb |= ((1 << CRBBIT_CLKPOL_B)	//   ClkPolB controls IndexB -- always set to active.
-			| (MULT_X0 << CRBBIT_CLKMULT_B));	//   ClkMultB selects OverflowA as the clock source.
+	case CLKSRC_EXTENDER:	/*  Extender Mode: */
+		cra |= ((2 << CRABIT_CLKSRC_B)	/*    ClkSrcB source is OverflowA (same as "timer") */
+			| ((setup & STDMSK_CLKPOL) << (CRABIT_CLKSRC_B - STDBIT_CLKPOL)));	/*      with direction obtained from ClkPol. */
+		crb |= ((1 << CRBBIT_CLKPOL_B)	/*    ClkPolB controls IndexB -- always set to active. */
+			| (MULT_X0 << CRBBIT_CLKMULT_B));	/*    ClkMultB selects OverflowA as the clock source. */
 		break;
 
-	default:		// Counter Mode:
-		cra |= (CLKSRC_COUNTER << CRABIT_CLKSRC_B);	//   Select ENC_C and ENC_D as clock/direction inputs.
-		crb |= (((setup & STDMSK_CLKPOL) >> (STDBIT_CLKPOL - CRBBIT_CLKPOL_B))	//   ClkPol is passed through.
-			| (((setup & STDMSK_CLKMULT) == (MULT_X0 << STDBIT_CLKMULT)) ?	//   Force ClkMult to x1 if not legal, otherwise pass through.
+	default:		/*  Counter Mode: */
+		cra |= (CLKSRC_COUNTER << CRABIT_CLKSRC_B);	/*    Select ENC_C and ENC_D as clock/direction inputs. */
+		crb |= (((setup & STDMSK_CLKPOL) >> (STDBIT_CLKPOL - CRBBIT_CLKPOL_B))	/*    ClkPol is passed through. */
+			| (((setup & STDMSK_CLKMULT) == (MULT_X0 << STDBIT_CLKMULT)) ?	/*    Force ClkMult to x1 if not legal, otherwise pass through. */
 				(MULT_X1 << CRBBIT_CLKMULT_B) :
 				((setup & STDMSK_CLKMULT) << (CRBBIT_CLKMULT_B -
 						STDBIT_CLKMULT))));
 	}
 
-	// Force positive index polarity if IndxSrc is software-driven only,
-	// otherwise pass it through.
+	/*  Force positive index polarity if IndxSrc is software-driven only, */
+	/*  otherwise pass it through. */
 	if (~setup & STDMSK_INDXSRC)
 		crb |= ((setup & STDMSK_INDXPOL) >> (STDBIT_INDXPOL -
 				CRBBIT_INDXPOL_B));
 
-	// If IntSrc has been forced to Disabled, update the MISC2 interrupt
-	// enable mask to indicate the counter interrupt is disabled.
+	/*  If IntSrc has been forced to Disabled, update the MISC2 interrupt */
+	/*  enable mask to indicate the counter interrupt is disabled. */
 	if (DisableIntSrc)
 		devpriv->CounterIntEnabs &= ~k->MyEventBits[3];
 
-	// While retaining CounterA and LatchSrc configurations, program the
-	// new counter operating mode.
+	/*  While retaining CounterA and LatchSrc configurations, program the */
+	/*  new counter operating mode. */
 	DEBIreplace(dev, k->MyCRA,
 		(uint16_t) (~(CRAMSK_INDXSRC_B | CRAMSK_CLKSRC_B)), cra);
 	DEBIreplace(dev, k->MyCRB, CRBMSK_CLKENAB_A | CRBMSK_LATCHSRC, crb);
 }
 
-////////////////////////////////////////////////////////////////////////
-// Return/set a counter's enable.  enab: 0=always enabled, 1=enabled by index.
+/*  Return/set a counter's enable.  enab: 0=always enabled, 1=enabled by index. */
 
-static void SetEnable_A(comedi_device * dev, enc_private * k, uint16_t enab)
+static void SetEnable_A(struct comedi_device *dev, struct enc_private *k, uint16_t enab)
 {
 	DEBUG("SetEnable_A: SetEnable_A enter 3541\n");
 	DEBIreplace(dev, k->MyCRB,
@@ -3006,29 +3016,29 @@
 		(uint16_t) (enab << CRBBIT_CLKENAB_A));
 }
 
-static void SetEnable_B(comedi_device * dev, enc_private * k, uint16_t enab)
+static void SetEnable_B(struct comedi_device *dev, struct enc_private *k, uint16_t enab)
 {
 	DEBIreplace(dev, k->MyCRB,
 		(uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_B)),
 		(uint16_t) (enab << CRBBIT_CLKENAB_B));
 }
 
-static uint16_t GetEnable_A(comedi_device * dev, enc_private * k)
+static uint16_t GetEnable_A(struct comedi_device *dev, struct enc_private *k)
 {
 	return (DEBIread(dev, k->MyCRB) >> CRBBIT_CLKENAB_A) & 1;
 }
 
-static uint16_t GetEnable_B(comedi_device * dev, enc_private * k)
+static uint16_t GetEnable_B(struct comedi_device *dev, struct enc_private *k)
 {
 	return (DEBIread(dev, k->MyCRB) >> CRBBIT_CLKENAB_B) & 1;
 }
 
-////////////////////////////////////////////////////////////////////////
-// Return/set a counter pair's latch trigger source.  0: On read
-// access, 1: A index latches A, 2: B index latches B, 3: A overflow
-// latches B.
+/* Return/set a counter pair's latch trigger source.  0: On read
+ * access, 1: A index latches A, 2: B index latches B, 3: A overflow
+ * latches B.
+ */
 
-static void SetLatchSource(comedi_device * dev, enc_private * k, uint16_t value)
+static void SetLatchSource(struct comedi_device *dev, struct enc_private *k, uint16_t value)
 {
 	DEBUG("SetLatchSource: SetLatchSource enter 3550 \n");
 	DEBIreplace(dev, k->MyCRB,
@@ -3038,210 +3048,206 @@
 	DEBUG("SetLatchSource: SetLatchSource exit \n");
 }
 
-/* static uint16_t GetLatchSource(comedi_device *dev, enc_private *k ) */
-/* { */
-/*   return ( DEBIread( dev, k->MyCRB) >> CRBBIT_LATCHSRC ) & 3; */
-/* } */
+/*
+ * static uint16_t GetLatchSource(struct comedi_device *dev, struct enc_private *k )
+ * {
+ * 	return ( DEBIread( dev, k->MyCRB) >> CRBBIT_LATCHSRC ) & 3;
+ * }
+ */
 
-/////////////////////////////////////////////////////////////////////////
-// Return/set the event that will trigger transfer of the preload
-// register into the counter.  0=ThisCntr_Index, 1=ThisCntr_Overflow,
-// 2=OverflowA (B counters only), 3=disabled.
+/*
+ * Return/set the event that will trigger transfer of the preload
+ * register into the counter.  0=ThisCntr_Index, 1=ThisCntr_Overflow,
+ * 2=OverflowA (B counters only), 3=disabled.
+ */
 
-static void SetLoadTrig_A(comedi_device * dev, enc_private * k, uint16_t Trig)
+static void SetLoadTrig_A(struct comedi_device *dev, struct enc_private *k, uint16_t Trig)
 {
 	DEBIreplace(dev, k->MyCRA, (uint16_t) (~CRAMSK_LOADSRC_A),
 		(uint16_t) (Trig << CRABIT_LOADSRC_A));
 }
 
-static void SetLoadTrig_B(comedi_device * dev, enc_private * k, uint16_t Trig)
+static void SetLoadTrig_B(struct comedi_device *dev, struct enc_private *k, uint16_t Trig)
 {
 	DEBIreplace(dev, k->MyCRB,
 		(uint16_t) (~(CRBMSK_LOADSRC_B | CRBMSK_INTCTRL)),
 		(uint16_t) (Trig << CRBBIT_LOADSRC_B));
 }
 
-static uint16_t GetLoadTrig_A(comedi_device * dev, enc_private * k)
+static uint16_t GetLoadTrig_A(struct comedi_device *dev, struct enc_private *k)
 {
 	return (DEBIread(dev, k->MyCRA) >> CRABIT_LOADSRC_A) & 3;
 }
 
-static uint16_t GetLoadTrig_B(comedi_device * dev, enc_private * k)
+static uint16_t GetLoadTrig_B(struct comedi_device *dev, struct enc_private *k)
 {
 	return (DEBIread(dev, k->MyCRB) >> CRBBIT_LOADSRC_B) & 3;
 }
 
-////////////////////
-// Return/set counter interrupt source and clear any captured
-// index/overflow events.  IntSource: 0=Disabled, 1=OverflowOnly,
-// 2=IndexOnly, 3=IndexAndOverflow.
+/* Return/set counter interrupt source and clear any captured
+ * index/overflow events.  IntSource: 0=Disabled, 1=OverflowOnly,
+ * 2=IndexOnly, 3=IndexAndOverflow.
+ */
 
-static void SetIntSrc_A(comedi_device * dev, enc_private * k,
+static void SetIntSrc_A(struct comedi_device *dev, struct enc_private *k,
 	uint16_t IntSource)
 {
-	// Reset any pending counter overflow or index captures.
+	/*  Reset any pending counter overflow or index captures. */
 	DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL),
 		CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A);
 
-	// Program counter interrupt source.
+	/*  Program counter interrupt source. */
 	DEBIreplace(dev, k->MyCRA, ~CRAMSK_INTSRC_A,
 		(uint16_t) (IntSource << CRABIT_INTSRC_A));
 
-	// Update MISC2 interrupt enable mask.
+	/*  Update MISC2 interrupt enable mask. */
 	devpriv->CounterIntEnabs =
 		(devpriv->CounterIntEnabs & ~k->MyEventBits[3]) | k->
 		MyEventBits[IntSource];
 }
 
-static void SetIntSrc_B(comedi_device * dev, enc_private * k,
+static void SetIntSrc_B(struct comedi_device *dev, struct enc_private *k,
 	uint16_t IntSource)
 {
 	uint16_t crb;
 
-	// Cache writeable CRB register image.
+	/*  Cache writeable CRB register image. */
 	crb = DEBIread(dev, k->MyCRB) & ~CRBMSK_INTCTRL;
 
-	// Reset any pending counter overflow or index captures.
+	/*  Reset any pending counter overflow or index captures. */
 	DEBIwrite(dev, k->MyCRB,
 		(uint16_t) (crb | CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B));
 
-	// Program counter interrupt source.
+	/*  Program counter interrupt source. */
 	DEBIwrite(dev, k->MyCRB,
 		(uint16_t) ((crb & ~CRBMSK_INTSRC_B) | (IntSource <<
 				CRBBIT_INTSRC_B)));
 
-	// Update MISC2 interrupt enable mask.
+	/*  Update MISC2 interrupt enable mask. */
 	devpriv->CounterIntEnabs =
 		(devpriv->CounterIntEnabs & ~k->MyEventBits[3]) | k->
 		MyEventBits[IntSource];
 }
 
-static uint16_t GetIntSrc_A(comedi_device * dev, enc_private * k)
+static uint16_t GetIntSrc_A(struct comedi_device *dev, struct enc_private *k)
 {
 	return (DEBIread(dev, k->MyCRA) >> CRABIT_INTSRC_A) & 3;
 }
 
-static uint16_t GetIntSrc_B(comedi_device * dev, enc_private * k)
+static uint16_t GetIntSrc_B(struct comedi_device *dev, struct enc_private *k)
 {
 	return (DEBIread(dev, k->MyCRB) >> CRBBIT_INTSRC_B) & 3;
 }
 
-/////////////////////////////////////////////////////////////////////////
-// Return/set the clock multiplier.
+/*  Return/set the clock multiplier. */
 
-/* static void SetClkMult(comedi_device *dev, enc_private *k, uint16_t value )  */
+/* static void SetClkMult(struct comedi_device *dev, struct enc_private *k, uint16_t value )  */
 /* { */
 /*   k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_CLKMULT ) | ( value << STDBIT_CLKMULT ) ), FALSE ); */
 /* } */
 
-/* static uint16_t GetClkMult(comedi_device *dev, enc_private *k )  */
+/* static uint16_t GetClkMult(struct comedi_device *dev, struct enc_private *k )  */
 /* { */
 /*   return ( k->GetMode(dev, k ) >> STDBIT_CLKMULT ) & 3; */
 /* } */
 
-/* ////////////////////////////////////////////////////////////////////////// */
-/* // Return/set the clock polarity. */
+/* Return/set the clock polarity. */
 
-/* static void SetClkPol( comedi_device *dev,enc_private *k, uint16_t value )  */
+/* static void SetClkPol( struct comedi_device *dev,struct enc_private *k, uint16_t value )  */
 /* { */
 /*   k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_CLKPOL ) | ( value << STDBIT_CLKPOL ) ), FALSE ); */
 /* } */
 
-/* static uint16_t GetClkPol(comedi_device *dev, enc_private *k )  */
+/* static uint16_t GetClkPol(struct comedi_device *dev, struct enc_private *k )  */
 /* { */
 /*   return ( k->GetMode(dev, k ) >> STDBIT_CLKPOL ) & 1; */
 /* } */
 
-/* /////////////////////////////////////////////////////////////////////// */
-/* // Return/set the clock source. */
+/* Return/set the clock source.  */
 
-/* static void SetClkSrc( comedi_device *dev,enc_private *k, uint16_t value )  */
+/* static void SetClkSrc( struct comedi_device *dev,struct enc_private *k, uint16_t value )  */
 /* { */
 /*   k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_CLKSRC ) | ( value << STDBIT_CLKSRC ) ), FALSE ); */
 /* } */
 
-/* static uint16_t GetClkSrc( comedi_device *dev,enc_private *k )  */
+/* static uint16_t GetClkSrc( struct comedi_device *dev,struct enc_private *k )  */
 /* { */
 /*   return ( k->GetMode(dev, k ) >> STDBIT_CLKSRC ) & 3; */
 /* } */
 
-/* //////////////////////////////////////////////////////////////////////// */
-/* // Return/set the index polarity. */
+/* Return/set the index polarity. */
 
-/* static void SetIndexPol(comedi_device *dev, enc_private *k, uint16_t value )  */
+/* static void SetIndexPol(struct comedi_device *dev, struct enc_private *k, uint16_t value )  */
 /* { */
 /*   k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_INDXPOL ) | ( (value != 0) << STDBIT_INDXPOL ) ), FALSE ); */
 /* } */
 
-/* static uint16_t GetIndexPol(comedi_device *dev, enc_private *k )  */
+/* static uint16_t GetIndexPol(struct comedi_device *dev, struct enc_private *k )  */
 /* { */
 /*   return ( k->GetMode(dev, k ) >> STDBIT_INDXPOL ) & 1; */
 /* } */
 
-/* //////////////////////////////////////////////////////////////////////// */
-/* // Return/set the index source. */
+/*  Return/set the index source. */
 
-/* static void SetIndexSrc(comedi_device *dev, enc_private *k, uint16_t value )  */
+/* static void SetIndexSrc(struct comedi_device *dev, struct enc_private *k, uint16_t value )  */
 /* { */
 /*   DEBUG("SetIndexSrc: set index src enter 3700\n"); */
 /*   k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_INDXSRC ) | ( (value != 0) << STDBIT_INDXSRC ) ), FALSE ); */
 /* } */
 
-/* static uint16_t GetIndexSrc(comedi_device *dev, enc_private *k )  */
+/* static uint16_t GetIndexSrc(struct comedi_device *dev, struct enc_private *k )  */
 /* { */
 /*   return ( k->GetMode(dev, k ) >> STDBIT_INDXSRC ) & 1; */
 /* } */
 
-///////////////////////////////////////////////////////////////////
-// Generate an index pulse.
+/*  Generate an index pulse. */
 
-static void PulseIndex_A(comedi_device * dev, enc_private * k)
+static void PulseIndex_A(struct comedi_device *dev, struct enc_private *k)
 {
 	register uint16_t cra;
 
 	DEBUG("PulseIndex_A: pulse index enter\n");
 
-	cra = DEBIread(dev, k->MyCRA);	// Pulse index.
+	cra = DEBIread(dev, k->MyCRA);	/*  Pulse index. */
 	DEBIwrite(dev, k->MyCRA, (uint16_t) (cra ^ CRAMSK_INDXPOL_A));
 	DEBUG("PulseIndex_A: pulse index step1\n");
 	DEBIwrite(dev, k->MyCRA, cra);
 }
 
-static void PulseIndex_B(comedi_device * dev, enc_private * k)
+static void PulseIndex_B(struct comedi_device *dev, struct enc_private *k)
 {
 	register uint16_t crb;
 
-	crb = DEBIread(dev, k->MyCRB) & ~CRBMSK_INTCTRL;	// Pulse index.
+	crb = DEBIread(dev, k->MyCRB) & ~CRBMSK_INTCTRL;	/*  Pulse index. */
 	DEBIwrite(dev, k->MyCRB, (uint16_t) (crb ^ CRBMSK_INDXPOL_B));
 	DEBIwrite(dev, k->MyCRB, crb);
 }
 
-/////////////////////////////////////////////////////////
-// Write value into counter preload register.
+/*  Write value into counter preload register. */
 
-static void Preload(comedi_device * dev, enc_private * k, uint32_t value)
+static void Preload(struct comedi_device *dev, struct enc_private *k, uint32_t value)
 {
 	DEBUG("Preload: preload enter\n");
-	DEBIwrite(dev, (uint16_t) (k->MyLatchLsw), (uint16_t) value);	// Write value to preload register.
+	DEBIwrite(dev, (uint16_t) (k->MyLatchLsw), (uint16_t) value);	/*  Write value to preload register. */
 	DEBUG("Preload: preload step 1\n");
 	DEBIwrite(dev, (uint16_t) (k->MyLatchLsw + 2),
 		(uint16_t) (value >> 16));
 }
 
-static void CountersInit(comedi_device * dev)
+static void CountersInit(struct comedi_device *dev)
 {
 	int chan;
-	enc_private *k;
-	uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) |	// Preload upon
-		// index.
-		(INDXSRC_SOFT << BF_INDXSRC) |	// Disable hardware index.
-		(CLKSRC_COUNTER << BF_CLKSRC) |	// Operating mode is counter.
-		(CLKPOL_POS << BF_CLKPOL) |	// Active high clock.
-		(CNTDIR_UP << BF_CLKPOL) |	// Count direction is up.
-		(CLKMULT_1X << BF_CLKMULT) |	// Clock multiplier is 1x.
-		(CLKENAB_INDEX << BF_CLKENAB);	// Enabled by index
+	struct enc_private *k;
+	uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) |	/*  Preload upon */
+		/*  index. */
+		(INDXSRC_SOFT << BF_INDXSRC) |	/*  Disable hardware index. */
+		(CLKSRC_COUNTER << BF_CLKSRC) |	/*  Operating mode is counter. */
+		(CLKPOL_POS << BF_CLKPOL) |	/*  Active high clock. */
+		(CNTDIR_UP << BF_CLKPOL) |	/*  Count direction is up. */
+		(CLKMULT_1X << BF_CLKMULT) |	/*  Clock multiplier is 1x. */
+		(CLKENAB_INDEX << BF_CLKENAB);	/*  Enabled by index */
 
-	// Disable all counter interrupts and clear any captured counter events.
+	/*  Disable all counter interrupts and clear any captured counter events. */
 	for (chan = 0; chan < S626_ENCODER_CHANNELS; chan++) {
 		k = &encpriv[chan];
 		k->SetMode(dev, k, Setup, TRUE);
diff --git a/drivers/staging/comedi/drivers/s626.h b/drivers/staging/comedi/drivers/s626.h
index 11d8b1c..891126f 100644
--- a/drivers/staging/comedi/drivers/s626.h
+++ b/drivers/staging/comedi/drivers/s626.h
@@ -51,15 +51,15 @@
 
    Example code
 
-   insn.insn=INSN_CONFIG;   //configuration instruction
-   insn.n=1;                //number of operation (must be 1)
-   insn.data=&initialvalue; //initial value loaded into encoder
-                            //during configuration
-   insn.subdev=5;           //encoder subdevice
-   insn.chanspec=CR_PACK(encoder_channel,0,AREF_OTHER); //encoder_channel
-                                                        //to configure
+   insn.insn=INSN_CONFIG;   // configuration instruction
+   insn.n=1;                // number of operation (must be 1)
+   insn.data=&initialvalue; // initial value loaded into encoder
+                            // during configuration
+   insn.subdev=5;           // encoder subdevice
+   insn.chanspec=CR_PACK(encoder_channel,0,AREF_OTHER); // encoder_channel
+                                                        // to configure
 
-   comedi_do_insn(cf,&insn); //executing configuration
+   comedi_do_insn(cf,&insn); // executing configuration
 */
 
 #ifdef _DEBUG_
@@ -88,147 +88,136 @@
 #define INLINE static __inline
 #endif
 
-/////////////////////////////////////////////////////
 #include<linux/slab.h>
 
 #define S626_SIZE 0x0200
 #define SIZEOF_ADDRESS_SPACE		0x0200
-#define DMABUF_SIZE			4096	// 4k pages
+#define DMABUF_SIZE			4096	/*  4k pages */
 
 #define S626_ADC_CHANNELS       16
 #define S626_DAC_CHANNELS       4
 #define S626_ENCODER_CHANNELS   6
 #define S626_DIO_CHANNELS       48
-#define S626_DIO_BANKS		3	// Number of DIO groups.
-#define S626_DIO_EXTCHANS	40	// Number of
-					// extended-capability
-					// DIO channels.
+#define S626_DIO_BANKS		3	/*  Number of DIO groups. */
+#define S626_DIO_EXTCHANS	40	/*  Number of */
+					/*  extended-capability */
+					/*  DIO channels. */
 
-#define NUM_TRIMDACS	12	// Number of valid TrimDAC channels.
+#define NUM_TRIMDACS	12	/*  Number of valid TrimDAC channels. */
 
-// PCI bus interface types.
-#define INTEL				1	// Intel bus type.
-#define MOTOROLA			2	// Motorola bus type.
+/*  PCI bus interface types. */
+#define INTEL				1	/*  Intel bus type. */
+#define MOTOROLA			2	/*  Motorola bus type. */
 
-//////////////////////////////////////////////////////////
+#define PLATFORM		INTEL	/*  *** SELECT PLATFORM TYPE *** */
 
-//////////////////////////////////////////////////////////
-#define PLATFORM		INTEL	// *** SELECT PLATFORM TYPE ***
-//////////////////////////////////////////////////////////
+#define RANGE_5V                0x10	/*  +/-5V range */
+#define RANGE_10V               0x00	/*  +/-10V range */
 
-#define RANGE_5V                0x10	// +/-5V range
-#define RANGE_10V               0x00	// +/-10V range
+#define EOPL			0x80	/*  End of ADC poll list marker. */
+#define GSEL_BIPOLAR5V		0x00F0	/*  LP_GSEL setting for 5V bipolar range. */
+#define GSEL_BIPOLAR10V		0x00A0	/*  LP_GSEL setting for 10V bipolar range. */
 
-#define EOPL			0x80	// End of ADC poll list marker.
-#define GSEL_BIPOLAR5V		0x00F0	// LP_GSEL setting for 5V bipolar range.
-#define GSEL_BIPOLAR10V		0x00A0	// LP_GSEL setting for 10V bipolar range.
+/*  Error codes that must be visible to this base class. */
+#define ERR_ILLEGAL_PARM	0x00010000	/*  Illegal function parameter value was specified. */
+#define ERR_I2C			0x00020000	/*  I2C error. */
+#define ERR_COUNTERSETUP	0x00200000	/*  Illegal setup specified for counter channel. */
+#define ERR_DEBI_TIMEOUT	0x00400000	/*  DEBI transfer timed out. */
 
-// Error codes that must be visible to this base class.
-#define ERR_ILLEGAL_PARM	0x00010000	// Illegal function parameter value was specified.
-#define ERR_I2C			0x00020000	// I2C error.
-#define ERR_COUNTERSETUP	0x00200000	// Illegal setup specified for counter channel.
-#define ERR_DEBI_TIMEOUT	0x00400000	// DEBI transfer timed out.
+/*  Organization (physical order) and size (in DWORDs) of logical DMA buffers contained by ANA_DMABUF. */
+#define ADC_DMABUF_DWORDS	40	/*  ADC DMA buffer must hold 16 samples, plus pre/post garbage samples. */
+#define DAC_WDMABUF_DWORDS	1	/*  DAC output DMA buffer holds a single sample. */
 
-// Organization (physical order) and size (in DWORDs) of logical DMA buffers contained by ANA_DMABUF.
-#define ADC_DMABUF_DWORDS	40	// ADC DMA buffer must hold 16 samples, plus pre/post garbage samples.
-#define DAC_WDMABUF_DWORDS	1	// DAC output DMA buffer holds a single sample.
+/*  All remaining space in 4KB DMA buffer is available for the RPS1 program. */
 
-// All remaining space in 4KB DMA buffer is available for the RPS1 program.
-
-// Address offsets, in DWORDS, from base of DMA buffer.
+/*  Address offsets, in DWORDS, from base of DMA buffer. */
 #define DAC_WDMABUF_OS		ADC_DMABUF_DWORDS
 
-// Interrupt enab bit in ISR and IER.
-#define IRQ_GPIO3		0x00000040	// IRQ enable for GPIO3.
+/*  Interrupt enab bit in ISR and IER. */
+#define IRQ_GPIO3		0x00000040  /*  IRQ enable for GPIO3. */
 #define IRQ_RPS1                0x10000000
-#define ISR_AFOU		0x00000800	// Audio fifo
-						// under/overflow
-						// detected.
-#define IRQ_COINT1A             0x0400	// conter 1A overflow
-						// interrupt mask
-#define IRQ_COINT1B             0x0800	// conter 1B overflow
-						// interrupt mask
-#define IRQ_COINT2A             0x1000	// conter 2A overflow
-						// interrupt mask
-#define IRQ_COINT2B             0x2000	// conter 2B overflow
-						// interrupt mask
-#define IRQ_COINT3A             0x4000	// conter 3A overflow
-						// interrupt mask
-#define IRQ_COINT3B             0x8000	// conter 3B overflow
-						// interrupt mask
+#define ISR_AFOU		0x00000800
+/* Audio fifo under/overflow  detected. */
 
-// RPS command codes.
-#define RPS_CLRSIGNAL		0x00000000	// CLEAR SIGNAL
-#define RPS_SETSIGNAL		0x10000000	// SET SIGNAL
-#define RPS_NOP			0x00000000	// NOP
-#define RPS_PAUSE		0x20000000	// PAUSE
-#define RPS_UPLOAD		0x40000000	// UPLOAD
-#define RPS_JUMP		0x80000000	// JUMP
-#define RPS_LDREG		0x90000100	// LDREG (1 uint32_t only)
-#define RPS_STREG		0xA0000100	// STREG (1 uint32_t only)
-#define RPS_STOP		0x50000000	// STOP
-#define RPS_IRQ                 0x60000000	// IRQ
+#define IRQ_COINT1A             0x0400 /* conter 1A overflow interrupt mask */
+#define IRQ_COINT1B             0x0800 /* conter 1B overflow interrupt mask */
+#define IRQ_COINT2A             0x1000 /* conter 2A overflow interrupt mask */
+#define IRQ_COINT2B             0x2000 /* conter 2B overflow interrupt mask */
+#define IRQ_COINT3A             0x4000 /* conter 3A overflow interrupt mask */
+#define IRQ_COINT3B             0x8000 /* conter 3B overflow interrupt mask */
 
-#define RPS_LOGICAL_OR		0x08000000	// Logical OR conditionals.
-#define RPS_INVERT		0x04000000	// Test for negated semaphores.
-#define RPS_DEBI		0x00000002	// DEBI done
+/*  RPS command codes. */
+#define RPS_CLRSIGNAL		0x00000000	/*  CLEAR SIGNAL */
+#define RPS_SETSIGNAL		0x10000000	/*  SET SIGNAL */
+#define RPS_NOP			0x00000000	/*  NOP */
+#define RPS_PAUSE		0x20000000	/*  PAUSE */
+#define RPS_UPLOAD		0x40000000	/*  UPLOAD */
+#define RPS_JUMP		0x80000000	/*  JUMP */
+#define RPS_LDREG		0x90000100	/*  LDREG (1 uint32_t only) */
+#define RPS_STREG		0xA0000100	/*  STREG (1 uint32_t only) */
+#define RPS_STOP		0x50000000	/*  STOP */
+#define RPS_IRQ                 0x60000000	/*  IRQ */
 
-#define RPS_SIG0		0x00200000	// RPS semaphore 0 (used by ADC).
-#define RPS_SIG1		0x00400000	// RPS semaphore 1 (used by DAC).
-#define RPS_SIG2		0x00800000	// RPS semaphore 2 (not used).
-#define RPS_GPIO2		0x00080000	// RPS GPIO2
-#define RPS_GPIO3		0x00100000	// RPS GPIO3
+#define RPS_LOGICAL_OR		0x08000000	/*  Logical OR conditionals. */
+#define RPS_INVERT		0x04000000	/*  Test for negated semaphores. */
+#define RPS_DEBI		0x00000002	/*  DEBI done */
 
-#define RPS_SIGADC		RPS_SIG0	// Trigger/status for ADC's RPS program.
-#define RPS_SIGDAC		RPS_SIG1	// Trigger/status for DAC's RPS program.
+#define RPS_SIG0		0x00200000	/*  RPS semaphore 0 (used by ADC). */
+#define RPS_SIG1		0x00400000	/*  RPS semaphore 1 (used by DAC). */
+#define RPS_SIG2		0x00800000	/*  RPS semaphore 2 (not used). */
+#define RPS_GPIO2		0x00080000	/*  RPS GPIO2 */
+#define RPS_GPIO3		0x00100000	/*  RPS GPIO3 */
 
-// RPS clock parameters.
-#define RPSCLK_SCALAR		8	// This is apparent ratio of PCI/RPS clks (undocumented!!).
-#define RPSCLK_PER_US		( 33 / RPSCLK_SCALAR )	// Number of RPS clocks in one microsecond.
+#define RPS_SIGADC		RPS_SIG0	/*  Trigger/status for ADC's RPS program. */
+#define RPS_SIGDAC		RPS_SIG1	/*  Trigger/status for DAC's RPS program. */
 
-// Event counter source addresses.
-#define SBA_RPS_A0		0x27	// Time of RPS0 busy, in PCI clocks.
+/*  RPS clock parameters. */
+#define RPSCLK_SCALAR		8	/*  This is apparent ratio of PCI/RPS clks (undocumented!!). */
+#define RPSCLK_PER_US		(33 / RPSCLK_SCALAR)	/*  Number of RPS clocks in one microsecond. */
 
-// GPIO constants.
-#define GPIO_BASE		0x10004000	// GPIO 0,2,3 = inputs, GPIO3 = IRQ; GPIO1 = out.
-#define GPIO1_LO		0x00000000	// GPIO1 set to LOW.
-#define GPIO1_HI		0x00001000	// GPIO1 set to HIGH.
+/*  Event counter source addresses. */
+#define SBA_RPS_A0		0x27	/*  Time of RPS0 busy, in PCI clocks. */
 
-// Primary Status Register (PSR) constants.
-#define PSR_DEBI_E		0x00040000	// DEBI event flag.
-#define PSR_DEBI_S		0x00080000	// DEBI status flag.
-#define PSR_A2_IN		0x00008000	// Audio output DMA2 protection address reached.
-#define PSR_AFOU		0x00000800	// Audio FIFO under/overflow detected.
-#define PSR_GPIO2		0x00000020	// GPIO2 input pin: 0=AdcBusy, 1=AdcIdle.
-#define PSR_EC0S		0x00000001	// Event counter 0 threshold reached.
+/*  GPIO constants. */
+#define GPIO_BASE		0x10004000	/*  GPIO 0,2,3 = inputs, GPIO3 = IRQ; GPIO1 = out. */
+#define GPIO1_LO		0x00000000	/*  GPIO1 set to LOW. */
+#define GPIO1_HI		0x00001000	/*  GPIO1 set to HIGH. */
 
-// Secondary Status Register (SSR) constants.
-#define SSR_AF2_OUT		0x00000200	// Audio 2 output FIFO under/overflow detected.
+/*  Primary Status Register (PSR) constants. */
+#define PSR_DEBI_E		0x00040000	/*  DEBI event flag. */
+#define PSR_DEBI_S		0x00080000	/*  DEBI status flag. */
+#define PSR_A2_IN		0x00008000	/*  Audio output DMA2 protection address reached. */
+#define PSR_AFOU		0x00000800	/*  Audio FIFO under/overflow detected. */
+#define PSR_GPIO2		0x00000020	/*  GPIO2 input pin: 0=AdcBusy, 1=AdcIdle. */
+#define PSR_EC0S		0x00000001	/*  Event counter 0 threshold reached. */
 
-// Master Control Register 1 (MC1) constants.
-#define MC1_SOFT_RESET		0x80000000	// Invoke 7146 soft reset.
-#define MC1_SHUTDOWN		0x3FFF0000	// Shut down all MC1-controlled enables.
+/*  Secondary Status Register (SSR) constants. */
+#define SSR_AF2_OUT		0x00000200	/*  Audio 2 output FIFO under/overflow detected. */
 
-#define MC1_ERPS1		0x2000	// enab/disable RPS task 1.
-#define MC1_ERPS0		0x1000	// enab/disable RPS task 0.
-#define MC1_DEBI		0x0800	// enab/disable DEBI pins.
-#define MC1_AUDIO		0x0200	// enab/disable audio port pins.
-#define MC1_I2C			0x0100	// enab/disable I2C interface.
-#define MC1_A2OUT		0x0008	// enab/disable transfer on A2 out.
-#define MC1_A2IN		0x0004	// enab/disable transfer on A2 in.
-#define MC1_A1IN		0x0001	// enab/disable transfer on A1 in.
+/*  Master Control Register 1 (MC1) constants. */
+#define MC1_SOFT_RESET		0x80000000	/*  Invoke 7146 soft reset. */
+#define MC1_SHUTDOWN		0x3FFF0000	/*  Shut down all MC1-controlled enables. */
 
-// Master Control Register 2 (MC2) constants.
-#define MC2_UPLD_DEBIq		0x00020002	// Upload DEBI registers.
-#define MC2_UPLD_IICq		0x00010001	// Upload I2C registers.
-#define MC2_RPSSIG2_ONq		0x20002000	// Assert RPS_SIG2.
-#define MC2_RPSSIG1_ONq		0x10001000	// Assert RPS_SIG1.
-#define MC2_RPSSIG0_ONq		0x08000800	// Assert RPS_SIG0.
-#define MC2_UPLD_DEBI_MASKq	0x00000002	// Upload DEBI mask.
-#define MC2_UPLD_IIC_MASKq	0x00000001	// Upload I2C mask.
-#define MC2_RPSSIG2_MASKq	0x00002000	// RPS_SIG2 bit mask.
-#define MC2_RPSSIG1_MASKq	0x00001000	// RPS_SIG1 bit mask.
-#define MC2_RPSSIG0_MASKq	0x00000800	// RPS_SIG0 bit mask.
+#define MC1_ERPS1		0x2000	/*  enab/disable RPS task 1. */
+#define MC1_ERPS0		0x1000	/*  enab/disable RPS task 0. */
+#define MC1_DEBI		0x0800	/*  enab/disable DEBI pins. */
+#define MC1_AUDIO		0x0200	/*  enab/disable audio port pins. */
+#define MC1_I2C			0x0100	/*  enab/disable I2C interface. */
+#define MC1_A2OUT		0x0008	/*  enab/disable transfer on A2 out. */
+#define MC1_A2IN		0x0004	/*  enab/disable transfer on A2 in. */
+#define MC1_A1IN		0x0001	/*  enab/disable transfer on A1 in. */
+
+/*  Master Control Register 2 (MC2) constants. */
+#define MC2_UPLD_DEBIq		0x00020002	/*  Upload DEBI registers. */
+#define MC2_UPLD_IICq		0x00010001	/*  Upload I2C registers. */
+#define MC2_RPSSIG2_ONq		0x20002000	/*  Assert RPS_SIG2. */
+#define MC2_RPSSIG1_ONq		0x10001000	/*  Assert RPS_SIG1. */
+#define MC2_RPSSIG0_ONq		0x08000800	/*  Assert RPS_SIG0. */
+#define MC2_UPLD_DEBI_MASKq	0x00000002	/*  Upload DEBI mask. */
+#define MC2_UPLD_IIC_MASKq	0x00000001	/*  Upload I2C mask. */
+#define MC2_RPSSIG2_MASKq	0x00002000	/*  RPS_SIG2 bit mask. */
+#define MC2_RPSSIG1_MASKq	0x00001000	/*  RPS_SIG1 bit mask. */
+#define MC2_RPSSIG0_MASKq	0x00000800	/*  RPS_SIG0 bit mask. */
 
 #define MC2_DELAYTRIG_4USq	MC2_RPSSIG1_ON
 #define MC2_DELAYBUSY_4USq	MC2_RPSSIG1_MASK
@@ -236,469 +225,425 @@
 #define	MC2_DELAYTRIG_6USq	MC2_RPSSIG2_ON
 #define MC2_DELAYBUSY_6USq	MC2_RPSSIG2_MASK
 
-#define MC2_UPLD_DEBI		0x0002	// Upload DEBI.
-#define MC2_UPLD_IIC		0x0001	// Upload I2C.
-#define MC2_RPSSIG2		0x2000	// RPS signal 2 (not used).
-#define MC2_RPSSIG1		0x1000	// RPS signal 1 (DAC RPS busy).
-#define MC2_RPSSIG0		0x0800	// RPS signal 0 (ADC RPS busy).
+#define MC2_UPLD_DEBI		0x0002	/*  Upload DEBI. */
+#define MC2_UPLD_IIC		0x0001	/*  Upload I2C. */
+#define MC2_RPSSIG2		0x2000	/*  RPS signal 2 (not used). */
+#define MC2_RPSSIG1		0x1000	/*  RPS signal 1 (DAC RPS busy). */
+#define MC2_RPSSIG0		0x0800	/*  RPS signal 0 (ADC RPS busy). */
 
-#define MC2_ADC_RPS		MC2_RPSSIG0	// ADC RPS busy.
-#define MC2_DAC_RPS		MC2_RPSSIG1	// DAC RPS busy.
+#define MC2_ADC_RPS		MC2_RPSSIG0	/*  ADC RPS busy. */
+#define MC2_DAC_RPS		MC2_RPSSIG1	/*  DAC RPS busy. */
 
-///////////////////oldies///////////
-#define MC2_UPLD_DEBIQ		0x00020002	// Upload DEBI registers.
-#define MC2_UPLD_IICQ		0x00010001	// Upload I2C registers.
-////////////////////////////////////////
+/* ***** oldies ***** */
+#define MC2_UPLD_DEBIQ		0x00020002	/*  Upload DEBI registers. */
+#define MC2_UPLD_IICQ		0x00010001	/*  Upload I2C registers. */
 
-// PCI BUS (SAA7146) REGISTER ADDRESS OFFSETS ////////////////////////
-#define P_PCI_BT_A		0x004C	// Audio DMA
-						// burst/threshold
-						// control.
-#define P_DEBICFG               0x007C	// DEBI configuration.
-#define P_DEBICMD               0x0080	// DEBI command.
-#define P_DEBIPAGE              0x0084	// DEBI page.
-#define P_DEBIAD                0x0088	// DEBI target address.
-#define P_I2CCTRL               0x008C	// I2C control.
-#define P_I2CSTAT               0x0090	// I2C status.
-#define P_BASEA2_IN		0x00AC	// Audio input 2 base
-						// physical DMAbuf
-						// address.
-#define P_PROTA2_IN		0x00B0	// Audio input 2
-						// physical DMAbuf
-						// protection address.
-#define P_PAGEA2_IN		0x00B4	// Audio input 2
-						// paging attributes.
-#define P_BASEA2_OUT		0x00B8	// Audio output 2 base
-						// physical DMAbuf
-						// address.
-#define P_PROTA2_OUT		0x00BC	// Audio output 2
-						// physical DMAbuf
-						// protection address.
-#define P_PAGEA2_OUT		0x00C0	// Audio output 2
-						// paging attributes.
-#define P_RPSPAGE0              0x00C4	// RPS0 page.
-#define P_RPSPAGE1              0x00C8	// RPS1 page.
-#define P_RPS0_TOUT		0x00D4	// RPS0 time-out.
-#define P_RPS1_TOUT		0x00D8	// RPS1 time-out.
-#define P_IER                   0x00DC	// Interrupt enable.
-#define P_GPIO                  0x00E0	// General-purpose I/O.
-#define P_EC1SSR		0x00E4	// Event counter set 1
-						// source select.
-#define P_ECT1R			0x00EC	// Event counter
-						// threshold set 1.
-#define P_ACON1                 0x00F4	// Audio control 1.
-#define P_ACON2                 0x00F8	// Audio control 2.
-#define P_MC1                   0x00FC	// Master control 1.
-#define P_MC2                   0x0100	// Master control 2.
-#define P_RPSADDR0              0x0104	// RPS0 instruction pointer.
-#define P_RPSADDR1              0x0108	// RPS1 instruction pointer.
-#define P_ISR                   0x010C	// Interrupt status.
-#define P_PSR                   0x0110	// Primary status.
-#define P_SSR                   0x0114	// Secondary status.
-#define P_EC1R			0x0118	// Event counter set 1.
-#define P_ADP4			0x0138	// Logical audio DMA
-						// pointer of audio
-						// input FIFO A2_IN.
-#define P_FB_BUFFER1            0x0144	// Audio feedback buffer 1.
-#define P_FB_BUFFER2            0x0148	// Audio feedback buffer 2.
-#define P_TSL1                  0x0180	// Audio time slot list 1.
-#define P_TSL2                  0x01C0	// Audio time slot list 2.
+/*  PCI BUS (SAA7146) REGISTER ADDRESS OFFSETS */
+#define P_PCI_BT_A		0x004C	/* Audio DMA burst/threshold control. */
+#define P_DEBICFG               0x007C	/* DEBI configuration. */
+#define P_DEBICMD               0x0080	/* DEBI command. */
+#define P_DEBIPAGE              0x0084	/* DEBI page. */
+#define P_DEBIAD                0x0088	/* DEBI target address. */
+#define P_I2CCTRL               0x008C	/* I2C control. */
+#define P_I2CSTAT               0x0090	/* I2C status. */
+#define P_BASEA2_IN		0x00AC	/* Audio input 2 base physical DMAbuf
+					 * address. */
+#define P_PROTA2_IN		0x00B0	/* Audio input 2 physical DMAbuf
+					 * protection address. */
+#define P_PAGEA2_IN		0x00B4	/* Audio input 2 paging attributes. */
+#define P_BASEA2_OUT		0x00B8	/* Audio output 2 base physical DMAbuf
+					 * address. */
+#define P_PROTA2_OUT		0x00BC	/* Audio output 2 physical DMAbuf
+					 * protection address. */
+#define P_PAGEA2_OUT		0x00C0	/* Audio output 2 paging attributes. */
+#define P_RPSPAGE0              0x00C4	/* RPS0 page. */
+#define P_RPSPAGE1              0x00C8	/* RPS1 page. */
+#define P_RPS0_TOUT		0x00D4	/* RPS0 time-out. */
+#define P_RPS1_TOUT		0x00D8	/* RPS1 time-out. */
+#define P_IER                   0x00DC	/* Interrupt enable. */
+#define P_GPIO                  0x00E0	/* General-purpose I/O. */
+#define P_EC1SSR		0x00E4	/* Event counter set 1 source select. */
+#define P_ECT1R			0x00EC	/* Event counter threshold set 1. */
+#define P_ACON1                 0x00F4	/* Audio control 1. */
+#define P_ACON2                 0x00F8	/* Audio control 2. */
+#define P_MC1                   0x00FC	/* Master control 1. */
+#define P_MC2                   0x0100	/* Master control 2. */
+#define P_RPSADDR0              0x0104	/* RPS0 instruction pointer. */
+#define P_RPSADDR1              0x0108	/* RPS1 instruction pointer. */
+#define P_ISR                   0x010C	/* Interrupt status. */
+#define P_PSR                   0x0110	/* Primary status. */
+#define P_SSR                   0x0114	/* Secondary status. */
+#define P_EC1R			0x0118	/* Event counter set 1. */
+#define P_ADP4			0x0138	/* Logical audio DMA pointer of audio
+					 * input FIFO A2_IN. */
+#define P_FB_BUFFER1            0x0144	/* Audio feedback buffer 1. */
+#define P_FB_BUFFER2            0x0148	/* Audio feedback buffer 2. */
+#define P_TSL1                  0x0180	/* Audio time slot list 1. */
+#define P_TSL2                  0x01C0	/* Audio time slot list 2. */
 
-// LOCAL BUS (GATE ARRAY) REGISTER ADDRESS OFFSETS /////////////////
-// Analog I/O registers:
-#define LP_DACPOL		0x0082	//  Write DAC polarity.
-#define LP_GSEL			0x0084	//  Write ADC gain.
-#define LP_ISEL			0x0086	//  Write ADC channel select.
-// Digital I/O (write only):
-#define LP_WRINTSELA		0x0042	//  Write A interrupt enable.
-#define LP_WREDGSELA		0x0044	//  Write A edge selection.
-#define LP_WRCAPSELA		0x0046	//  Write A capture enable.
-#define LP_WRDOUTA		0x0048	//  Write A digital output.
-#define LP_WRINTSELB		0x0052	//  Write B interrupt enable.
-#define LP_WREDGSELB		0x0054	//  Write B edge selection.
-#define LP_WRCAPSELB		0x0056	//  Write B capture enable.
-#define LP_WRDOUTB		0x0058	//  Write B digital output.
-#define LP_WRINTSELC		0x0062	//  Write C interrupt enable.
-#define LP_WREDGSELC		0x0064	//  Write C edge selection.
-#define LP_WRCAPSELC		0x0066	//  Write C capture enable.
-#define LP_WRDOUTC		0x0068	//  Write C digital output.
+/*  LOCAL BUS (GATE ARRAY) REGISTER ADDRESS OFFSETS */
+/*  Analog I/O registers: */
+#define LP_DACPOL		0x0082	/*   Write DAC polarity. */
+#define LP_GSEL			0x0084	/*   Write ADC gain. */
+#define LP_ISEL			0x0086	/*   Write ADC channel select. */
+/*  Digital I/O (write only): */
+#define LP_WRINTSELA		0x0042	/*   Write A interrupt enable. */
+#define LP_WREDGSELA		0x0044	/*   Write A edge selection. */
+#define LP_WRCAPSELA		0x0046	/*   Write A capture enable. */
+#define LP_WRDOUTA		0x0048	/*   Write A digital output. */
+#define LP_WRINTSELB		0x0052	/*   Write B interrupt enable. */
+#define LP_WREDGSELB		0x0054	/*   Write B edge selection. */
+#define LP_WRCAPSELB		0x0056	/*   Write B capture enable. */
+#define LP_WRDOUTB		0x0058	/*   Write B digital output. */
+#define LP_WRINTSELC		0x0062	/*   Write C interrupt enable. */
+#define LP_WREDGSELC		0x0064	/*   Write C edge selection. */
+#define LP_WRCAPSELC		0x0066	/*   Write C capture enable. */
+#define LP_WRDOUTC		0x0068	/*   Write C digital output. */
 
-// Digital I/O (read only):
-#define LP_RDDINA		0x0040	//  Read digital input.
-#define LP_RDCAPFLGA		0x0048	//  Read edges captured.
-#define LP_RDINTSELA		0x004A	//  Read interrupt
-						//  enable register.
-#define LP_RDEDGSELA		0x004C	//  Read edge
-						//  selection
-						//  register.
-#define LP_RDCAPSELA		0x004E	//  Read capture
-						//  enable register.
-#define LP_RDDINB		0x0050	//  Read digital input.
-#define LP_RDCAPFLGB		0x0058	//  Read edges captured.
-#define LP_RDINTSELB		0x005A	//  Read interrupt
-						//  enable register.
-#define LP_RDEDGSELB		0x005C	//  Read edge
-						//  selection
-						//  register.
-#define LP_RDCAPSELB		0x005E	//  Read capture
-						//  enable register.
-#define LP_RDDINC		0x0060	//  Read digital input.
-#define LP_RDCAPFLGC		0x0068	//  Read edges captured.
-#define LP_RDINTSELC		0x006A	//  Read interrupt
-						//  enable register.
-#define LP_RDEDGSELC		0x006C	//  Read edge
-						//  selection
-						//  register.
-#define LP_RDCAPSELC		0x006E	//  Read capture
-						//  enable register.
-// Counter Registers (read/write):
-#define LP_CR0A			0x0000	//  0A setup register.
-#define LP_CR0B			0x0002	//  0B setup register.
-#define LP_CR1A			0x0004	//  1A setup register.
-#define LP_CR1B			0x0006	//  1B setup register.
-#define LP_CR2A			0x0008	//  2A setup register.
-#define LP_CR2B			0x000A	//  2B setup register.
-// Counter PreLoad (write) and Latch (read) Registers:
-#define	LP_CNTR0ALSW		0x000C	//  0A lsw.
-#define	LP_CNTR0AMSW		0x000E	//  0A msw.
-#define	LP_CNTR0BLSW		0x0010	//  0B lsw.
-#define	LP_CNTR0BMSW		0x0012	//  0B msw.
-#define	LP_CNTR1ALSW		0x0014	//  1A lsw.
-#define	LP_CNTR1AMSW		0x0016	//  1A msw.
-#define	LP_CNTR1BLSW		0x0018	//  1B lsw.
-#define	LP_CNTR1BMSW		0x001A	//  1B msw.
-#define	LP_CNTR2ALSW		0x001C	//  2A lsw.
-#define	LP_CNTR2AMSW		0x001E	//  2A msw.
-#define	LP_CNTR2BLSW		0x0020	//  2B lsw.
-#define	LP_CNTR2BMSW		0x0022	//  2B msw.
-// Miscellaneous Registers (read/write):
-#define LP_MISC1		0x0088	//  Read/write Misc1.
-#define LP_WRMISC2		0x0090	//  Write Misc2.
-#define LP_RDMISC2		0x0082	//  Read Misc2.
+/*  Digital I/O (read only): */
+#define LP_RDDINA		0x0040	/*   Read digital input. */
+#define LP_RDCAPFLGA		0x0048	/*   Read edges captured. */
+#define LP_RDINTSELA		0x004A	/*   Read interrupt enable register. */
+#define LP_RDEDGSELA		0x004C	/*   Read edge selection register. */
+#define LP_RDCAPSELA		0x004E	/*   Read capture enable register. */
+#define LP_RDDINB		0x0050	/*   Read digital input. */
+#define LP_RDCAPFLGB		0x0058	/*   Read edges captured. */
+#define LP_RDINTSELB		0x005A	/*   Read interrupt enable register. */
+#define LP_RDEDGSELB		0x005C	/*   Read edge selection register. */
+#define LP_RDCAPSELB		0x005E	/*   Read capture enable register. */
+#define LP_RDDINC		0x0060	/*   Read digital input. */
+#define LP_RDCAPFLGC		0x0068	/*   Read edges captured. */
+#define LP_RDINTSELC		0x006A	/*   Read interrupt enable register. */
+#define LP_RDEDGSELC		0x006C	/*   Read edge selection register. */
+#define LP_RDCAPSELC		0x006E	/*   Read capture enable register. */
 
-// Bit masks for MISC1 register that are the same for reads and writes.
-#define MISC1_WENABLE		0x8000	// enab writes to
-						// MISC2 (except Clear
-						// Watchdog bit).
-#define MISC1_WDISABLE		0x0000	// Disable writes to MISC2.
-#define MISC1_EDCAP		0x1000	// enab edge capture
-						// on DIO chans
-						// specified by
-						// LP_WRCAPSELx.
-#define MISC1_NOEDCAP		0x0000	// Disable edge
-						// capture on
-						// specified DIO
-						// chans.
+/*  Counter Registers (read/write): */
+#define LP_CR0A			0x0000	/*   0A setup register. */
+#define LP_CR0B			0x0002	/*   0B setup register. */
+#define LP_CR1A			0x0004	/*   1A setup register. */
+#define LP_CR1B			0x0006	/*   1B setup register. */
+#define LP_CR2A			0x0008	/*   2A setup register. */
+#define LP_CR2B			0x000A	/*   2B setup register. */
 
-// Bit masks for MISC1 register reads.
-#define RDMISC1_WDTIMEOUT	0x4000	// Watchdog timer timed out.
+/*  Counter PreLoad (write) and Latch (read) Registers: */
+#define	LP_CNTR0ALSW		0x000C	/*   0A lsw. */
+#define	LP_CNTR0AMSW		0x000E	/*   0A msw. */
+#define	LP_CNTR0BLSW		0x0010	/*   0B lsw. */
+#define	LP_CNTR0BMSW		0x0012	/*   0B msw. */
+#define	LP_CNTR1ALSW		0x0014	/*   1A lsw. */
+#define	LP_CNTR1AMSW		0x0016	/*   1A msw. */
+#define	LP_CNTR1BLSW		0x0018	/*   1B lsw. */
+#define	LP_CNTR1BMSW		0x001A	/*   1B msw. */
+#define	LP_CNTR2ALSW		0x001C	/*   2A lsw. */
+#define	LP_CNTR2AMSW		0x001E	/*   2A msw. */
+#define	LP_CNTR2BLSW		0x0020	/*   2B lsw. */
+#define	LP_CNTR2BMSW		0x0022	/*   2B msw. */
 
-// Bit masks for MISC2 register writes.
-#define WRMISC2_WDCLEAR		0x8000	// Reset watchdog
-						// timer to zero.
-#define WRMISC2_CHARGE_ENABLE	0x4000	// enab battery
-						// trickle charging.
+/*  Miscellaneous Registers (read/write): */
+#define LP_MISC1		0x0088	/*   Read/write Misc1. */
+#define LP_WRMISC2		0x0090	/*   Write Misc2. */
+#define LP_RDMISC2		0x0082	/*   Read Misc2. */
 
-// Bit masks for MISC2 register that are the same for reads and writes.
-#define MISC2_BATT_ENABLE	0x0008	// Backup battery enable.
-#define MISC2_WDENABLE		0x0004	// Watchdog timer enable.
-#define MISC2_WDPERIOD_MASK	0x0003	// Watchdog interval
-						// select mask.
+/*  Bit masks for MISC1 register that are the same for reads and writes. */
+#define MISC1_WENABLE		0x8000	/* enab writes to MISC2 (except Clear
+					 * Watchdog bit). */
+#define MISC1_WDISABLE		0x0000	/* Disable writes to MISC2. */
+#define MISC1_EDCAP		0x1000	/* enab edge capture on DIO chans
+					 * specified by  LP_WRCAPSELx. */
+#define MISC1_NOEDCAP		0x0000	/* Disable edge capture on specified
+					 * DIO chans. */
 
-// Bit masks for ACON1 register.
-#define A2_RUN			0x40000000	// Run A2 based on TSL2.
-#define A1_RUN			0x20000000	// Run A1 based on TSL1.
-#define A1_SWAP			0x00200000	// Use big-endian for A1.
-#define A2_SWAP			0x00100000	// Use big-endian for A2.
-#define WS_MODES		0x00019999	// WS0 = TSL1 trigger
-						// input, WS1-WS4 =
-						// CS* outputs.
+/*  Bit masks for MISC1 register reads. */
+#define RDMISC1_WDTIMEOUT	0x4000	/*  Watchdog timer timed out. */
 
-#if PLATFORM == INTEL		// Base ACON1 config:
-						// always run A1 based
-						// on TSL1.
-#define ACON1_BASE		( WS_MODES | A1_RUN )
+/*  Bit masks for MISC2 register writes. */
+#define WRMISC2_WDCLEAR		0x8000	/*  Reset watchdog timer to zero. */
+#define WRMISC2_CHARGE_ENABLE	0x4000	/*  enab battery trickle charging. */
+
+/*  Bit masks for MISC2 register that are the same for reads and writes. */
+#define MISC2_BATT_ENABLE	0x0008	/*  Backup battery enable. */
+#define MISC2_WDENABLE		0x0004	/*  Watchdog timer enable. */
+#define MISC2_WDPERIOD_MASK	0x0003	/*  Watchdog interval */
+						/*  select mask. */
+
+/*  Bit masks for ACON1 register. */
+#define A2_RUN			0x40000000	/*  Run A2 based on TSL2. */
+#define A1_RUN			0x20000000	/*  Run A1 based on TSL1. */
+#define A1_SWAP			0x00200000	/*  Use big-endian for A1. */
+#define A2_SWAP			0x00100000	/*  Use big-endian for A2. */
+#define WS_MODES		0x00019999	/*  WS0 = TSL1 trigger */
+						/*  input, WS1-WS4 = */
+						/*  CS* outputs. */
+
+#if PLATFORM == INTEL		/* Base ACON1 config: always run A1 based
+				 * on TSL1. */
+#define ACON1_BASE		(WS_MODES | A1_RUN)
 #elif PLATFORM == MOTOROLA
-#define ACON1_BASE		( WS_MODES | A1_RUN | A1_SWAP | A2_SWAP )
+#define ACON1_BASE		(WS_MODES | A1_RUN | A1_SWAP | A2_SWAP)
 #endif
 
-#define ACON1_ADCSTART		ACON1_BASE	// Start ADC: run A1
-						// based on TSL1.
-#define ACON1_DACSTART		( ACON1_BASE | A2_RUN )	// Start
-							// transmit to
-							// DAC: run A2
-							// based on
-							// TSL2.
-#define ACON1_DACSTOP		ACON1_BASE	// Halt A2.
+#define ACON1_ADCSTART		ACON1_BASE	/* Start ADC: run A1
+						 *  based on TSL1. */
+#define ACON1_DACSTART		(ACON1_BASE | A2_RUN)
+/* Start transmit to DAC: run A2 based on TSL2. */
+#define ACON1_DACSTOP		ACON1_BASE	/*  Halt A2. */
 
-// Bit masks for ACON2 register.
-#define A1_CLKSRC_BCLK1		0x00000000	// A1 bit rate = BCLK1 (ADC).
-#define A2_CLKSRC_X1		0x00800000	// A2 bit rate = ACLK/1 (DACs).
-#define A2_CLKSRC_X2		0x00C00000	// A2 bit rate = ACLK/2 (DACs).
-#define A2_CLKSRC_X4		0x01400000	// A2 bit rate = ACLK/4 (DACs).
-#define INVERT_BCLK2		0x00100000	// Invert BCLK2 (DACs).
-#define BCLK2_OE		0x00040000	// enab BCLK2 (DACs).
-#define ACON2_XORMASK		0x000C0000	// XOR mask for ACON2
-						// active-low bits.
+/*  Bit masks for ACON2 register. */
+#define A1_CLKSRC_BCLK1		0x00000000	/*  A1 bit rate = BCLK1 (ADC). */
+#define A2_CLKSRC_X1		0x00800000	/*  A2 bit rate = ACLK/1 (DACs). */
+#define A2_CLKSRC_X2		0x00C00000	/*  A2 bit rate = ACLK/2 (DACs). */
+#define A2_CLKSRC_X4		0x01400000	/*  A2 bit rate = ACLK/4 (DACs). */
+#define INVERT_BCLK2		0x00100000	/*  Invert BCLK2 (DACs). */
+#define BCLK2_OE		0x00040000	/*  enab BCLK2 (DACs). */
+#define ACON2_XORMASK		0x000C0000	/*  XOR mask for ACON2 */
+						/*  active-low bits. */
 
-#define ACON2_INIT		( ACON2_XORMASK ^ ( A1_CLKSRC_BCLK1 | A2_CLKSRC_X2 | INVERT_BCLK2 | BCLK2_OE ) )
+#define ACON2_INIT		(ACON2_XORMASK ^ (A1_CLKSRC_BCLK1 | A2_CLKSRC_X2 | INVERT_BCLK2 | BCLK2_OE))
 
-// Bit masks for timeslot records.
-#define WS1		     	0x40000000	// WS output to assert.
+/*  Bit masks for timeslot records. */
+#define WS1		     	0x40000000	/*  WS output to assert. */
 #define WS2		     	0x20000000
 #define WS3		     	0x10000000
 #define WS4		     	0x08000000
-#define RSD1			0x01000000	// Shift A1 data in on SD1.
-#define SDW_A1			0x00800000	// Store rcv'd char at
-						// next char slot of
-						// DWORD1 buffer.
-#define SIB_A1			0x00400000	// Store rcv'd char at
-						// next char slot of
-						// FB1 buffer.
-#define SF_A1			0x00200000	// Write unsigned long
-						// buffer to input
-						// FIFO.
+#define RSD1			0x01000000	/* Shift A1 data in on SD1. */
+#define SDW_A1			0x00800000	/* Store rcv'd char at next
+						 * char slot of DWORD1 buffer. */
+#define SIB_A1			0x00400000	/* Store rcv'd char at next
+						 * char slot of FB1 buffer. */
+#define SF_A1			0x00200000	/* Write unsigned long
+						 * buffer to input FIFO. */
 
-//Select parallel-to-serial converter's data source:
-#define XFIFO_0			0x00000000	//   Data fifo byte 0.
-#define XFIFO_1			0x00000010	//   Data fifo byte 1.
-#define XFIFO_2			0x00000020	//   Data fifo byte 2.
-#define XFIFO_3			0x00000030	//   Data fifo byte 3.
-#define XFB0			0x00000040	//   FB_BUFFER byte 0.
-#define XFB1			0x00000050	//   FB_BUFFER byte 1.
-#define XFB2			0x00000060	//   FB_BUFFER byte 2.
-#define XFB3			0x00000070	//   FB_BUFFER byte 3.
-#define SIB_A2			0x00000200	// Store next dword
-						// from A2's input
-						// shifter to FB2
-						// buffer.
-#define SF_A2			0x00000100	// Store next dword
-						// from A2's input
-						// shifter to its
-						// input fifo.
-#define LF_A2			0x00000080	// Load next dword
-						// from A2's output
-						// fifo into its
-						// output dword
-						// buffer.
-#define XSD2			0x00000008	// Shift data out on SD2.
-#define RSD3			0x00001800	// Shift data in on SD3.
-#define RSD2			0x00001000	// Shift data in on SD2.
-#define LOW_A2			0x00000002	// Drive last SD low
-						// for 7 clks, then
-						// tri-state.
-#define EOS		     	0x00000001	// End of superframe.
+/* Select parallel-to-serial converter's data source: */
+#define XFIFO_0			0x00000000	/*    Data fifo byte 0. */
+#define XFIFO_1			0x00000010	/*    Data fifo byte 1. */
+#define XFIFO_2			0x00000020	/*    Data fifo byte 2. */
+#define XFIFO_3			0x00000030	/*    Data fifo byte 3. */
+#define XFB0			0x00000040	/*    FB_BUFFER byte 0. */
+#define XFB1			0x00000050	/*    FB_BUFFER byte 1. */
+#define XFB2			0x00000060	/*    FB_BUFFER byte 2. */
+#define XFB3			0x00000070	/*    FB_BUFFER byte 3. */
+#define SIB_A2			0x00000200	/* Store next dword from A2's
+						 * input shifter to FB2 buffer. */
+#define SF_A2			0x00000100	/* Store next dword from A2's
+						 * input shifter to its input
+						 * fifo. */
+#define LF_A2			0x00000080	/* Load next dword from A2's
+						 * output fifo into its
+						 * output dword buffer. */
+#define XSD2			0x00000008	/*  Shift data out on SD2. */
+#define RSD3			0x00001800	/*  Shift data in on SD3. */
+#define RSD2			0x00001000	/*  Shift data in on SD2. */
+#define LOW_A2			0x00000002	/*  Drive last SD low */
+						/*  for 7 clks, then */
+						/*  tri-state. */
+#define EOS		     	0x00000001	/*  End of superframe. */
 
-//////////////////////
 
-// I2C configuration constants.
-#define I2C_CLKSEL		0x0400	// I2C bit rate =
-						// PCIclk/480 = 68.75
-						// KHz.
-#define I2C_BITRATE		68.75	// I2C bus data bit
-						// rate (determined by
-						// I2C_CLKSEL) in KHz.
-#define I2C_WRTIME		15.0	// Worst case time,in
-						// msec, for EEPROM
-						// internal write op.
+/*  I2C configuration constants. */
+#define I2C_CLKSEL		0x0400
+/* I2C bit rate = PCIclk/480 = 68.75 KHz. */
 
-// I2C manifest constants.
+#define I2C_BITRATE		68.75
+/* I2C bus data bit rate (determined by I2C_CLKSEL) in KHz. */
 
-// Max retries to wait for EEPROM write.
-#define I2C_RETRIES		( I2C_WRTIME * I2C_BITRATE / 9.0 )
-#define I2C_ERR			0x0002	// I2C control/status
-						// flag ERROR.
-#define I2C_BUSY		0x0001	// I2C control/status
-						// flag BUSY.
-#define I2C_ABORT		0x0080	// I2C status flag ABORT.
-#define I2C_ATTRSTART		0x3	// I2C attribute START.
-#define I2C_ATTRCONT		0x2	// I2C attribute CONT.
-#define I2C_ATTRSTOP		0x1	// I2C attribute STOP.
-#define I2C_ATTRNOP		0x0	// I2C attribute NOP.
+#define I2C_WRTIME		15.0
+/* Worst case time, in msec, for EEPROM internal write op. */
 
-// I2C read command  | EEPROM address.
-#define I2CR			( devpriv->I2CAdrs | 1 )
+/*  I2C manifest constants. */
 
-// I2C write command | EEPROM address.
-#define I2CW			( devpriv->I2CAdrs )
+/*  Max retries to wait for EEPROM write. */
+#define I2C_RETRIES		(I2C_WRTIME * I2C_BITRATE / 9.0)
+#define I2C_ERR			0x0002	/*  I2C control/status */
+						/*  flag ERROR. */
+#define I2C_BUSY		0x0001	/*  I2C control/status */
+						/*  flag BUSY. */
+#define I2C_ABORT		0x0080	/*  I2C status flag ABORT. */
+#define I2C_ATTRSTART		0x3	/*  I2C attribute START. */
+#define I2C_ATTRCONT		0x2	/*  I2C attribute CONT. */
+#define I2C_ATTRSTOP		0x1	/*  I2C attribute STOP. */
+#define I2C_ATTRNOP		0x0	/*  I2C attribute NOP. */
 
-// Code macros used for constructing I2C command bytes.
-#define I2C_B2(ATTR,VAL)	( ( (ATTR) << 6 ) | ( (VAL) << 24 ) )
-#define I2C_B1(ATTR,VAL)	( ( (ATTR) << 4 ) | ( (VAL) << 16 ) )
-#define I2C_B0(ATTR,VAL)	( ( (ATTR) << 2 ) | ( (VAL) <<  8 ) )
+/*  I2C read command  | EEPROM address. */
+#define I2CR			(devpriv->I2CAdrs | 1)
 
-////////////////////////////////////////////////////////
-//oldest
-#define P_DEBICFGq              0x007C	// DEBI configuration.
-#define P_DEBICMDq              0x0080	// DEBI command.
-#define P_DEBIPAGEq             0x0084	// DEBI page.
-#define P_DEBIADq               0x0088	// DEBI target address.
+/*  I2C write command | EEPROM address. */
+#define I2CW			(devpriv->I2CAdrs)
 
-#define DEBI_CFG_TOQ		0x03C00000	// timeout (15 PCI cycles)
-#define DEBI_CFG_FASTQ		0x10000000	// fast mode enable
-#define DEBI_CFG_16Q		0x00080000	// 16-bit access enable
-#define DEBI_CFG_INCQ		0x00040000	// enable address increment
-#define DEBI_CFG_TIMEROFFQ	0x00010000	// disable timer
-#define DEBI_CMD_RDQ		0x00050000	// read immediate 2 bytes
-#define DEBI_CMD_WRQ		0x00040000	// write immediate 2 bytes
-#define DEBI_PAGE_DISABLEQ	0x00000000	// paging disable
+/*  Code macros used for constructing I2C command bytes. */
+#define I2C_B2(ATTR, VAL)	(((ATTR) << 6) | ((VAL) << 24))
+#define I2C_B1(ATTR, VAL)	(((ATTR) << 4) | ((VAL) << 16))
+#define I2C_B0(ATTR, VAL)	(((ATTR) << 2) | ((VAL) <<  8))
 
-///////////////////////////////////////////
-// DEBI command constants.
-#define DEBI_CMD_SIZE16		( 2 << 17 )	// Transfer size is
-						// always 2 bytes.
-#define DEBI_CMD_READ		0x00010000	// Read operation.
-#define DEBI_CMD_WRITE		0x00000000	// Write operation.
+/* oldest */
+#define P_DEBICFGq              0x007C	/*  DEBI configuration. */
+#define P_DEBICMDq              0x0080	/*  DEBI command. */
+#define P_DEBIPAGEq             0x0084	/*  DEBI page. */
+#define P_DEBIADq               0x0088	/*  DEBI target address. */
 
-// Read immediate 2 bytes.
-#define DEBI_CMD_RDWORD		( DEBI_CMD_READ  | DEBI_CMD_SIZE16 )
+#define DEBI_CFG_TOQ		0x03C00000	/*  timeout (15 PCI cycles) */
+#define DEBI_CFG_FASTQ		0x10000000	/*  fast mode enable */
+#define DEBI_CFG_16Q		0x00080000	/*  16-bit access enable */
+#define DEBI_CFG_INCQ		0x00040000	/*  enable address increment */
+#define DEBI_CFG_TIMEROFFQ	0x00010000	/*  disable timer */
+#define DEBI_CMD_RDQ		0x00050000	/*  read immediate 2 bytes */
+#define DEBI_CMD_WRQ		0x00040000	/*  write immediate 2 bytes */
+#define DEBI_PAGE_DISABLEQ	0x00000000	/*  paging disable */
 
-// Write immediate 2 bytes.
-#define DEBI_CMD_WRWORD		( DEBI_CMD_WRITE | DEBI_CMD_SIZE16 )
+/*  DEBI command constants. */
+#define DEBI_CMD_SIZE16		(2 << 17)	/*  Transfer size is */
+						/*  always 2 bytes. */
+#define DEBI_CMD_READ		0x00010000	/*  Read operation. */
+#define DEBI_CMD_WRITE		0x00000000	/*  Write operation. */
 
-// DEBI configuration constants.
-#define DEBI_CFG_XIRQ_EN	0x80000000	// enab external
-						// interrupt on GPIO3.
-#define DEBI_CFG_XRESUME	0x40000000	// Resume block
-						// transfer when XIRQ
-						// deasserted.
-#define DEBI_CFG_FAST		0x10000000	// Fast mode enable.
+/*  Read immediate 2 bytes. */
+#define DEBI_CMD_RDWORD		(DEBI_CMD_READ  | DEBI_CMD_SIZE16)
 
-// 4-bit field that specifies DEBI timeout value in PCI clock cycles:
-#define DEBI_CFG_TOUT_BIT	22	//   Finish DEBI cycle after
-					//   this many clocks.
+/*  Write immediate 2 bytes. */
+#define DEBI_CMD_WRWORD		(DEBI_CMD_WRITE | DEBI_CMD_SIZE16)
 
-// 2-bit field that specifies Endian byte lane steering:
-#define DEBI_CFG_SWAP_NONE	0x00000000	//   Straight - don't
-						//   swap any bytes
-						//   (Intel).
-#define DEBI_CFG_SWAP_2		0x00100000	//   2-byte swap (Motorola).
-#define DEBI_CFG_SWAP_4		0x00200000	//   4-byte swap.
-#define DEBI_CFG_16		0x00080000	// Slave is able to
-						// serve 16-bit
-						// cycles.
+/*  DEBI configuration constants. */
+#define DEBI_CFG_XIRQ_EN	0x80000000	/*  enab external */
+						/*  interrupt on GPIO3. */
+#define DEBI_CFG_XRESUME	0x40000000	/*  Resume block */
+						/*  transfer when XIRQ */
+						/*  deasserted. */
+#define DEBI_CFG_FAST		0x10000000	/*  Fast mode enable. */
 
-#define DEBI_CFG_SLAVE16	0x00080000	// Slave is able to
-						// serve 16-bit
-						// cycles.
-#define DEBI_CFG_INC		0x00040000	// enab address
-						// increment for block
-						// transfers.
-#define DEBI_CFG_INTEL		0x00020000	// Intel style local bus.
-#define DEBI_CFG_TIMEROFF	0x00010000	// Disable timer.
+/*  4-bit field that specifies DEBI timeout value in PCI clock cycles: */
+#define DEBI_CFG_TOUT_BIT	22	/*    Finish DEBI cycle after */
+					/*    this many clocks. */
+
+/*  2-bit field that specifies Endian byte lane steering: */
+#define DEBI_CFG_SWAP_NONE	0x00000000	/*    Straight - don't */
+						/*    swap any bytes */
+						/*    (Intel). */
+#define DEBI_CFG_SWAP_2		0x00100000	/*    2-byte swap (Motorola). */
+#define DEBI_CFG_SWAP_4		0x00200000	/*    4-byte swap. */
+#define DEBI_CFG_16		0x00080000	/*  Slave is able to */
+						/*  serve 16-bit */
+						/*  cycles. */
+
+#define DEBI_CFG_SLAVE16	0x00080000	/*  Slave is able to */
+						/*  serve 16-bit */
+						/*  cycles. */
+#define DEBI_CFG_INC		0x00040000	/*  enab address */
+						/*  increment for block */
+						/*  transfers. */
+#define DEBI_CFG_INTEL		0x00020000	/*  Intel style local bus. */
+#define DEBI_CFG_TIMEROFF	0x00010000	/*  Disable timer. */
 
 #if PLATFORM == INTEL
 
-#define DEBI_TOUT		7	// Wait 7 PCI clocks
-						// (212 ns) before
-						// polling RDY.
+#define DEBI_TOUT		7	/*  Wait 7 PCI clocks */
+						/*  (212 ns) before */
+						/*  polling RDY. */
 
-// Intel byte lane steering (pass through all byte lanes).
+/*  Intel byte lane steering (pass through all byte lanes). */
 #define DEBI_SWAP		DEBI_CFG_SWAP_NONE
 
 #elif PLATFORM == MOTOROLA
 
-#define DEBI_TOUT		15	// Wait 15 PCI clocks (454 ns)
-					// maximum before timing out.
-#define DEBI_SWAP		DEBI_CFG_SWAP_2	// Motorola byte lane steering.
+#define DEBI_TOUT		15	/*  Wait 15 PCI clocks (454 ns) */
+					/*  maximum before timing out. */
+#define DEBI_SWAP		DEBI_CFG_SWAP_2	/*  Motorola byte lane steering. */
 
 #endif
 
-// DEBI page table constants.
-#define DEBI_PAGE_DISABLE	0x00000000	// Paging disable.
+/*  DEBI page table constants. */
+#define DEBI_PAGE_DISABLE	0x00000000	/*  Paging disable. */
 
-///////////////////EXTRA FROM OTHER SANSORAY  * .h////////
+/* ******* EXTRA FROM OTHER SANSORAY  * .h  ******* */
 
-// LoadSrc values:
-#define LOADSRC_INDX		0	// Preload core in response to
-					// Index.
-#define LOADSRC_OVER		1	// Preload core in response to
-					// Overflow.
-#define LOADSRCB_OVERA		2	// Preload B core in response
-					// to A Overflow.
-#define LOADSRC_NONE		3	// Never preload core.
+/*  LoadSrc values: */
+#define LOADSRC_INDX		0	/*  Preload core in response to */
+					/*  Index. */
+#define LOADSRC_OVER		1	/*  Preload core in response to */
+					/*  Overflow. */
+#define LOADSRCB_OVERA		2	/*  Preload B core in response */
+					/*  to A Overflow. */
+#define LOADSRC_NONE		3	/*  Never preload core. */
 
-// IntSrc values:
-#define INTSRC_NONE 		0	// Interrupts disabled.
-#define INTSRC_OVER 		1	// Interrupt on Overflow.
-#define INTSRC_INDX 		2	// Interrupt on Index.
-#define INTSRC_BOTH 		3	// Interrupt on Index or Overflow.
+/*  IntSrc values: */
+#define INTSRC_NONE 		0	/*  Interrupts disabled. */
+#define INTSRC_OVER 		1	/*  Interrupt on Overflow. */
+#define INTSRC_INDX 		2	/*  Interrupt on Index. */
+#define INTSRC_BOTH 		3	/*  Interrupt on Index or Overflow. */
 
-// LatchSrc values:
-#define LATCHSRC_AB_READ	0	// Latch on read.
-#define LATCHSRC_A_INDXA	1	// Latch A on A Index.
-#define LATCHSRC_B_INDXB	2	// Latch B on B Index.
-#define LATCHSRC_B_OVERA	3	// Latch B on A Overflow.
+/*  LatchSrc values: */
+#define LATCHSRC_AB_READ	0	/*  Latch on read. */
+#define LATCHSRC_A_INDXA	1	/*  Latch A on A Index. */
+#define LATCHSRC_B_INDXB	2	/*  Latch B on B Index. */
+#define LATCHSRC_B_OVERA	3	/*  Latch B on A Overflow. */
 
-// IndxSrc values:
-#define INDXSRC_HARD		0	// Hardware or software index.
-#define INDXSRC_SOFT		1	// Software index only.
+/*  IndxSrc values: */
+#define INDXSRC_HARD		0	/*  Hardware or software index. */
+#define INDXSRC_SOFT		1	/*  Software index only. */
 
-// IndxPol values:
-#define INDXPOL_POS 		0	// Index input is active high.
-#define INDXPOL_NEG 		1	// Index input is active low.
+/*  IndxPol values: */
+#define INDXPOL_POS 		0	/*  Index input is active high. */
+#define INDXPOL_NEG 		1	/*  Index input is active low. */
 
-// ClkSrc values:
-#define CLKSRC_COUNTER		0	// Counter mode.
-#define CLKSRC_TIMER		2	// Timer mode.
-#define CLKSRC_EXTENDER		3	// Extender mode.
+/*  ClkSrc values: */
+#define CLKSRC_COUNTER		0	/*  Counter mode. */
+#define CLKSRC_TIMER		2	/*  Timer mode. */
+#define CLKSRC_EXTENDER		3	/*  Extender mode. */
 
-// ClkPol values:
-#define CLKPOL_POS		0	// Counter/Extender clock is
-					// active high.
-#define CLKPOL_NEG		1	// Counter/Extender clock is
-					// active low.
-#define CNTDIR_UP		0	// Timer counts up.
-#define CNTDIR_DOWN 		1	// Timer counts down.
+/*  ClkPol values: */
+#define CLKPOL_POS		0	/*  Counter/Extender clock is */
+					/*  active high. */
+#define CLKPOL_NEG		1	/*  Counter/Extender clock is */
+					/*  active low. */
+#define CNTDIR_UP		0	/*  Timer counts up. */
+#define CNTDIR_DOWN 		1	/*  Timer counts down. */
 
-// ClkEnab values:
-#define CLKENAB_ALWAYS		0	// Clock always enabled.
-#define CLKENAB_INDEX		1	// Clock is enabled by index.
+/*  ClkEnab values: */
+#define CLKENAB_ALWAYS		0	/*  Clock always enabled. */
+#define CLKENAB_INDEX		1	/*  Clock is enabled by index. */
 
-// ClkMult values:
-#define CLKMULT_4X 		0	// 4x clock multiplier.
-#define CLKMULT_2X 		1	// 2x clock multiplier.
-#define CLKMULT_1X 		2	// 1x clock multiplier.
+/*  ClkMult values: */
+#define CLKMULT_4X 		0	/*  4x clock multiplier. */
+#define CLKMULT_2X 		1	/*  2x clock multiplier. */
+#define CLKMULT_1X 		2	/*  1x clock multiplier. */
 
-// Bit Field positions in COUNTER_SETUP structure:
-#define BF_LOADSRC		9	// Preload trigger.
-#define BF_INDXSRC		7	// Index source.
-#define BF_INDXPOL		6	// Index polarity.
-#define BF_CLKSRC		4	// Clock source.
-#define BF_CLKPOL		3	// Clock polarity/count direction.
-#define BF_CLKMULT		1	// Clock multiplier.
-#define BF_CLKENAB		0	// Clock enable.
+/*  Bit Field positions in COUNTER_SETUP structure: */
+#define BF_LOADSRC		9	/*  Preload trigger. */
+#define BF_INDXSRC		7	/*  Index source. */
+#define BF_INDXPOL		6	/*  Index polarity. */
+#define BF_CLKSRC		4	/*  Clock source. */
+#define BF_CLKPOL		3	/*  Clock polarity/count direction. */
+#define BF_CLKMULT		1	/*  Clock multiplier. */
+#define BF_CLKENAB		0	/*  Clock enable. */
 
-// Enumerated counter operating modes specified by ClkSrc bit field in
-// a COUNTER_SETUP.
+/*  Enumerated counter operating modes specified by ClkSrc bit field in */
+/*  a COUNTER_SETUP. */
 
-#define CLKSRC_COUNTER		0	// Counter: ENC_C clock, ENC_D
-					// direction.
-#define CLKSRC_TIMER		2	// Timer: SYS_C clock,
-					// direction specified by
-					// ClkPol.
-#define CLKSRC_EXTENDER		3	// Extender: OVR_A clock,
-					// ENC_D direction.
+#define CLKSRC_COUNTER		0	/*  Counter: ENC_C clock, ENC_D */
+					/*  direction. */
+#define CLKSRC_TIMER		2	/*  Timer: SYS_C clock, */
+					/*  direction specified by */
+					/*  ClkPol. */
+#define CLKSRC_EXTENDER		3	/*  Extender: OVR_A clock, */
+					/*  ENC_D direction. */
 
-// Enumerated counter clock multipliers.
+/*  Enumerated counter clock multipliers. */
 
-#define MULT_X0			0x0003	// Supports no multipliers;
-					// fixed physical multiplier =
-					// 3.
-#define MULT_X1			0x0002	// Supports multiplier x1;
-					// fixed physical multiplier =
-					// 2.
-#define MULT_X2			0x0001	// Supports multipliers x1,
-					// x2; physical multipliers =
-					// 1 or 2.
-#define MULT_X4			0x0000	// Supports multipliers x1,
-					// x2, x4; physical
-					// multipliers = 0, 1 or 2.
+#define MULT_X0			0x0003	/*  Supports no multipliers; */
+					/*  fixed physical multiplier = */
+					/*  3. */
+#define MULT_X1			0x0002	/*  Supports multiplier x1; */
+					/*  fixed physical multiplier = */
+					/*  2. */
+#define MULT_X2			0x0001	/*  Supports multipliers x1, */
+					/*  x2; physical multipliers = */
+					/*  1 or 2. */
+#define MULT_X4			0x0000	/*  Supports multipliers x1, */
+					/*  x2, x4; physical */
+					/*  multipliers = 0, 1 or 2. */
 
-// Sanity-check limits for parameters.
+/*  Sanity-check limits for parameters. */
 
-#define NUM_COUNTERS		6	// Maximum valid counter
-					// logical channel number.
+#define NUM_COUNTERS		6	/*  Maximum valid counter */
+					/*  logical channel number. */
 #define NUM_INTSOURCES		4
 #define NUM_LATCHSOURCES	4
 #define NUM_CLKMULTS		4
@@ -708,59 +653,59 @@
 #define NUM_INDEXSOURCES	2
 #define NUM_LOADTRIGS		4
 
-// Bit field positions in CRA and CRB counter control registers.
+/*  Bit field positions in CRA and CRB counter control registers. */
 
-// Bit field positions in CRA:
-#define CRABIT_INDXSRC_B	14	//   B index source.
-#define CRABIT_CLKSRC_B		12	//   B clock source.
-#define CRABIT_INDXPOL_A	11	//   A index polarity.
-#define CRABIT_LOADSRC_A	 9	//   A preload trigger.
-#define CRABIT_CLKMULT_A	 7	//   A clock multiplier.
-#define CRABIT_INTSRC_A		 5	//   A interrupt source.
-#define CRABIT_CLKPOL_A		 4	//   A clock polarity.
-#define CRABIT_INDXSRC_A	 2	//   A index source.
-#define CRABIT_CLKSRC_A		 0	//   A clock source.
+/*  Bit field positions in CRA: */
+#define CRABIT_INDXSRC_B	14	/*    B index source. */
+#define CRABIT_CLKSRC_B		12	/*    B clock source. */
+#define CRABIT_INDXPOL_A	11	/*    A index polarity. */
+#define CRABIT_LOADSRC_A	 9	/*    A preload trigger. */
+#define CRABIT_CLKMULT_A	 7	/*    A clock multiplier. */
+#define CRABIT_INTSRC_A		 5	/*    A interrupt source. */
+#define CRABIT_CLKPOL_A		 4	/*    A clock polarity. */
+#define CRABIT_INDXSRC_A	 2	/*    A index source. */
+#define CRABIT_CLKSRC_A		 0	/*    A clock source. */
 
-// Bit field positions in CRB:
-#define CRBBIT_INTRESETCMD	15	//   Interrupt reset command.
-#define CRBBIT_INTRESET_B	14	//   B interrupt reset enable.
-#define CRBBIT_INTRESET_A	13	//   A interrupt reset enable.
-#define CRBBIT_CLKENAB_A	12	//   A clock enable.
-#define CRBBIT_INTSRC_B		10	//   B interrupt source.
-#define CRBBIT_LATCHSRC		 8	//   A/B latch source.
-#define CRBBIT_LOADSRC_B	 6	//   B preload trigger.
-#define CRBBIT_CLKMULT_B	 3	//   B clock multiplier.
-#define CRBBIT_CLKENAB_B	 2	//   B clock enable.
-#define CRBBIT_INDXPOL_B	 1	//   B index polarity.
-#define CRBBIT_CLKPOL_B		 0	//   B clock polarity.
+/*  Bit field positions in CRB: */
+#define CRBBIT_INTRESETCMD	15	/*    Interrupt reset command. */
+#define CRBBIT_INTRESET_B	14	/*    B interrupt reset enable. */
+#define CRBBIT_INTRESET_A	13	/*    A interrupt reset enable. */
+#define CRBBIT_CLKENAB_A	12	/*    A clock enable. */
+#define CRBBIT_INTSRC_B		10	/*    B interrupt source. */
+#define CRBBIT_LATCHSRC		 8	/*    A/B latch source. */
+#define CRBBIT_LOADSRC_B	 6	/*    B preload trigger. */
+#define CRBBIT_CLKMULT_B	 3	/*    B clock multiplier. */
+#define CRBBIT_CLKENAB_B	 2	/*    B clock enable. */
+#define CRBBIT_INDXPOL_B	 1	/*    B index polarity. */
+#define CRBBIT_CLKPOL_B		 0	/*    B clock polarity. */
 
-// Bit field masks for CRA and CRB.
+/*  Bit field masks for CRA and CRB. */
 
-#define CRAMSK_INDXSRC_B	( (uint16_t)( 3 << CRABIT_INDXSRC_B) )
-#define CRAMSK_CLKSRC_B		( (uint16_t)( 3 << CRABIT_CLKSRC_B) )
-#define CRAMSK_INDXPOL_A	( (uint16_t)( 1 << CRABIT_INDXPOL_A) )
-#define CRAMSK_LOADSRC_A	( (uint16_t)( 3 << CRABIT_LOADSRC_A) )
-#define CRAMSK_CLKMULT_A	( (uint16_t)( 3 << CRABIT_CLKMULT_A) )
-#define CRAMSK_INTSRC_A		( (uint16_t)( 3 << CRABIT_INTSRC_A) )
-#define CRAMSK_CLKPOL_A		( (uint16_t)( 3 << CRABIT_CLKPOL_A) )
-#define CRAMSK_INDXSRC_A	( (uint16_t)( 3 << CRABIT_INDXSRC_A) )
-#define CRAMSK_CLKSRC_A		( (uint16_t)( 3 << CRABIT_CLKSRC_A) )
+#define CRAMSK_INDXSRC_B	((uint16_t)(3 << CRABIT_INDXSRC_B))
+#define CRAMSK_CLKSRC_B		((uint16_t)(3 << CRABIT_CLKSRC_B))
+#define CRAMSK_INDXPOL_A	((uint16_t)(1 << CRABIT_INDXPOL_A))
+#define CRAMSK_LOADSRC_A	((uint16_t)(3 << CRABIT_LOADSRC_A))
+#define CRAMSK_CLKMULT_A	((uint16_t)(3 << CRABIT_CLKMULT_A))
+#define CRAMSK_INTSRC_A		((uint16_t)(3 << CRABIT_INTSRC_A))
+#define CRAMSK_CLKPOL_A		((uint16_t)(3 << CRABIT_CLKPOL_A))
+#define CRAMSK_INDXSRC_A	((uint16_t)(3 << CRABIT_INDXSRC_A))
+#define CRAMSK_CLKSRC_A		((uint16_t)(3 << CRABIT_CLKSRC_A))
 
-#define CRBMSK_INTRESETCMD	( (uint16_t)( 1 << CRBBIT_INTRESETCMD) )
-#define CRBMSK_INTRESET_B	( (uint16_t)( 1 << CRBBIT_INTRESET_B) )
-#define CRBMSK_INTRESET_A	( (uint16_t)( 1 << CRBBIT_INTRESET_A) )
-#define CRBMSK_CLKENAB_A	( (uint16_t)( 1 << CRBBIT_CLKENAB_A) )
-#define CRBMSK_INTSRC_B		( (uint16_t)( 3 << CRBBIT_INTSRC_B) )
-#define CRBMSK_LATCHSRC		( (uint16_t)( 3 << CRBBIT_LATCHSRC) )
-#define CRBMSK_LOADSRC_B	( (uint16_t)( 3 << CRBBIT_LOADSRC_B) )
-#define CRBMSK_CLKMULT_B	( (uint16_t)( 3 << CRBBIT_CLKMULT_B) )
-#define CRBMSK_CLKENAB_B	( (uint16_t)( 1 << CRBBIT_CLKENAB_B) )
-#define CRBMSK_INDXPOL_B	( (uint16_t)( 1 << CRBBIT_INDXPOL_B) )
-#define CRBMSK_CLKPOL_B		( (uint16_t)( 1 << CRBBIT_CLKPOL_B) )
+#define CRBMSK_INTRESETCMD	((uint16_t)(1 << CRBBIT_INTRESETCMD))
+#define CRBMSK_INTRESET_B	((uint16_t)(1 << CRBBIT_INTRESET_B))
+#define CRBMSK_INTRESET_A	((uint16_t)(1 << CRBBIT_INTRESET_A))
+#define CRBMSK_CLKENAB_A	((uint16_t)(1 << CRBBIT_CLKENAB_A))
+#define CRBMSK_INTSRC_B		((uint16_t)(3 << CRBBIT_INTSRC_B))
+#define CRBMSK_LATCHSRC		((uint16_t)(3 << CRBBIT_LATCHSRC))
+#define CRBMSK_LOADSRC_B	((uint16_t)(3 << CRBBIT_LOADSRC_B))
+#define CRBMSK_CLKMULT_B	((uint16_t)(3 << CRBBIT_CLKMULT_B))
+#define CRBMSK_CLKENAB_B	((uint16_t)(1 << CRBBIT_CLKENAB_B))
+#define CRBMSK_INDXPOL_B	((uint16_t)(1 << CRBBIT_INDXPOL_B))
+#define CRBMSK_CLKPOL_B		((uint16_t)(1 << CRBBIT_CLKPOL_B))
 
-#define CRBMSK_INTCTRL		( CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A | CRBMSK_INTRESET_B )	// Interrupt reset control bits.
+#define CRBMSK_INTCTRL		(CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A | CRBMSK_INTRESET_B)	/*  Interrupt reset control bits. */
 
-// Bit field positions for standardized SETUP structure.
+/*  Bit field positions for standardized SETUP structure. */
 
 #define STDBIT_INTSRC		13
 #define STDBIT_LATCHSRC		11
@@ -772,19 +717,18 @@
 #define STDBIT_CLKMULT		 1
 #define STDBIT_CLKENAB		 0
 
-// Bit field masks for standardized SETUP structure.
+/*  Bit field masks for standardized SETUP structure. */
 
-#define STDMSK_INTSRC		( (uint16_t)( 3 << STDBIT_INTSRC   ) )
-#define STDMSK_LATCHSRC		( (uint16_t)( 3 << STDBIT_LATCHSRC ) )
-#define STDMSK_LOADSRC		( (uint16_t)( 3 << STDBIT_LOADSRC  ) )
-#define STDMSK_INDXSRC		( (uint16_t)( 1 << STDBIT_INDXSRC  ) )
-#define STDMSK_INDXPOL		( (uint16_t)( 1 << STDBIT_INDXPOL  ) )
-#define STDMSK_CLKSRC		( (uint16_t)( 3 << STDBIT_CLKSRC   ) )
-#define STDMSK_CLKPOL		( (uint16_t)( 1 << STDBIT_CLKPOL   ) )
-#define STDMSK_CLKMULT		( (uint16_t)( 3 << STDBIT_CLKMULT  ) )
-#define STDMSK_CLKENAB		( (uint16_t)( 1 << STDBIT_CLKENAB  ) )
+#define STDMSK_INTSRC		((uint16_t)(3 << STDBIT_INTSRC))
+#define STDMSK_LATCHSRC		((uint16_t)(3 << STDBIT_LATCHSRC))
+#define STDMSK_LOADSRC		((uint16_t)(3 << STDBIT_LOADSRC))
+#define STDMSK_INDXSRC		((uint16_t)(1 << STDBIT_INDXSRC))
+#define STDMSK_INDXPOL		((uint16_t)(1 << STDBIT_INDXPOL))
+#define STDMSK_CLKSRC		((uint16_t)(3 << STDBIT_CLKSRC))
+#define STDMSK_CLKPOL		((uint16_t)(1 << STDBIT_CLKPOL))
+#define STDMSK_CLKMULT		((uint16_t)(3 << STDBIT_CLKMULT))
+#define STDMSK_CLKENAB		((uint16_t)(1 << STDBIT_CLKENAB))
 
-//////////////////////////////////////////////////////////
 
 /* typedef struct indexCounter */
 /* { */
@@ -795,8 +739,8 @@
 /*   unsigned int enc; */
 /* }CallCounter; */
 
-typedef struct bufferDMA {
+struct bufferDMA {
 	dma_addr_t PhysicalBase;
 	void *LogicalBase;
 	uint32_t DMAHandle;
-} DMABUF;
+};
diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c
new file mode 100644
index 0000000..844fd5e
--- /dev/null
+++ b/drivers/staging/comedi/drivers/serial2002.c
@@ -0,0 +1,870 @@
+/*
+    comedi/drivers/serial2002.c
+    Skeleton code for a Comedi driver
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2002 Anders Blomdell <anders.blomdell@control.lth.se>
+
+    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.
+
+*/
+
+/*
+Driver: serial2002
+Description: Driver for serial connected hardware
+Devices:
+Author: Anders Blomdell
+Updated: Fri,  7 Jun 2002 12:56:45 -0700
+Status: in development
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+#include <linux/ioport.h>
+
+#include <asm/termios.h>
+#include <asm/ioctls.h>
+#include <linux/serial.h>
+#include <linux/poll.h>
+
+/*
+ * Board descriptions for two imaginary boards.  Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct serial2002_board {
+	const char *name;
+};
+
+static const struct serial2002_board serial2002_boards[] = {
+	{
+      name:	"serial2002"}
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct serial2002_board *)dev->board_ptr)
+
+struct serial2002_range_table_t {
+
+	// HACK...
+	int length;
+	struct comedi_krange range;
+};
+
+
+struct serial2002_private {
+
+	int port;		// /dev/ttyS<port>
+	int speed;		// baudrate
+	struct file *tty;
+	unsigned int ao_readback[32];
+	unsigned char digital_in_mapping[32];
+	unsigned char digital_out_mapping[32];
+	unsigned char analog_in_mapping[32];
+	unsigned char analog_out_mapping[32];
+	unsigned char encoder_in_mapping[32];
+	struct serial2002_range_table_t in_range[32], out_range[32];
+};
+
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct serial2002_private *)dev->private)
+
+static int serial2002_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int serial2002_detach(struct comedi_device * dev);
+struct comedi_driver driver_serial2002 = {
+      driver_name:"serial2002",
+      module:THIS_MODULE,
+      attach:serial2002_attach,
+      detach:serial2002_detach,
+      board_name:&serial2002_boards[0].name,
+      offset:sizeof(struct serial2002_board),
+      num_names:sizeof(serial2002_boards) / sizeof(struct serial2002_board),
+};
+
+static int serial2002_di_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int serial2002_do_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int serial2002_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int serial2002_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int serial2002_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+
+struct serial_data {
+	enum { is_invalid, is_digital, is_channel } kind;
+	int index;
+	unsigned long value;
+};
+
+static long tty_ioctl(struct file *f, unsigned op, unsigned long param)
+{
+#ifdef HAVE_UNLOCKED_IOCTL
+  	if (f->f_op->unlocked_ioctl) {
+		return f->f_op->unlocked_ioctl(f, op, param);
+	}
+#endif
+	if (f->f_op->ioctl) {
+	  	return f->f_op->ioctl(f->f_dentry->d_inode, f, op, param);
+	}
+	return -ENOSYS;
+}
+
+static int tty_write(struct file *f, unsigned char *buf, int count)
+{
+	int result;
+	mm_segment_t oldfs;
+
+	oldfs = get_fs();
+	set_fs(KERNEL_DS);
+	f->f_pos = 0;
+	result = f->f_op->write(f, buf, count, &f->f_pos);
+	set_fs(oldfs);
+	return result;
+}
+
+#if 0
+/*
+ * On 2.6.26.3 this occaisonally gave me page faults, worked around by
+ * settings.c_cc[VMIN] = 0; settings.c_cc[VTIME] = 0
+ */
+static int tty_available(struct file *f)
+{
+	long result = 0;
+	mm_segment_t oldfs;
+
+	oldfs = get_fs();
+	set_fs(KERNEL_DS);
+	tty_ioctl(f, FIONREAD, (unsigned long)&result);
+	set_fs(oldfs);
+	return result;
+}
+#endif
+
+static int tty_read(struct file *f, int timeout)
+{
+	int result;
+
+	result = -1;
+	if (!IS_ERR(f)) {
+		mm_segment_t oldfs;
+
+		oldfs = get_fs();
+		set_fs(KERNEL_DS);
+		if (f->f_op->poll) {
+			struct poll_wqueues table;
+			struct timeval start, now;
+
+			do_gettimeofday(&start);
+			poll_initwait(&table);
+			while (1) {
+				long elapsed;
+				int mask;
+
+				mask = f->f_op->poll(f, &table.pt);
+				if (mask & (POLLRDNORM | POLLRDBAND | POLLIN |
+						POLLHUP | POLLERR)) {
+					break;
+				}
+				do_gettimeofday(&now);
+				elapsed =
+					(1000000 * (now.tv_sec - start.tv_sec) +
+					now.tv_usec - start.tv_usec);
+				if (elapsed > timeout) {
+					break;
+				}
+				set_current_state(TASK_INTERRUPTIBLE);
+				schedule_timeout(((timeout -
+							elapsed) * HZ) / 10000);
+			}
+			poll_freewait(&table);
+			{
+			  unsigned char ch;
+
+			  f->f_pos = 0;
+			  if (f->f_op->read(f, &ch, 1, &f->f_pos) == 1) {
+			    result = ch;
+			  }
+			}
+		} else {
+			/* Device does not support poll, busy wait */
+			int retries = 0;
+			while (1) {
+			  	unsigned char ch;
+
+				retries++;
+				if (retries >= timeout) {
+					break;
+				}
+
+				f->f_pos = 0;
+				if (f->f_op->read(f, &ch, 1, &f->f_pos) == 1) {
+				  	result = ch;
+					break;
+				}
+				comedi_udelay(100);
+			}
+		}
+		set_fs(oldfs);
+	}
+	return result;
+}
+
+static void tty_setspeed(struct file *f, int speed)
+{
+	mm_segment_t oldfs;
+
+	oldfs = get_fs();
+	set_fs(KERNEL_DS);
+	{
+		// Set speed
+		struct termios settings;
+
+		tty_ioctl(f, TCGETS, (unsigned long)&settings);
+//    printk("Speed: %d\n", settings.c_cflag & (CBAUD | CBAUDEX));
+		settings.c_iflag = 0;
+		settings.c_oflag = 0;
+		settings.c_lflag = 0;
+		settings.c_cflag = CLOCAL | CS8 | CREAD;
+		settings.c_cc[VMIN] = 0;
+		settings.c_cc[VTIME] = 0;
+		switch (speed) {
+		case 2400:{
+				settings.c_cflag |= B2400;
+			}
+			break;
+		case 4800:{
+				settings.c_cflag |= B4800;
+			}
+			break;
+		case 9600:{
+				settings.c_cflag |= B9600;
+			}
+			break;
+		case 19200:{
+				settings.c_cflag |= B19200;
+			}
+			break;
+		case 38400:{
+				settings.c_cflag |= B38400;
+			}
+			break;
+		case 57600:{
+				settings.c_cflag |= B57600;
+			}
+			break;
+		case 115200:{
+				settings.c_cflag |= B115200;
+			}
+			break;
+		default:{
+				settings.c_cflag |= B9600;
+			}
+			break;
+		}
+		tty_ioctl(f, TCSETS, (unsigned long)&settings);
+//    printk("Speed: %d\n", settings.c_cflag & (CBAUD | CBAUDEX));
+	}
+	{
+		// Set low latency
+		struct serial_struct settings;
+
+		tty_ioctl(f, TIOCGSERIAL, (unsigned long)&settings);
+		settings.flags |= ASYNC_LOW_LATENCY;
+		tty_ioctl(f, TIOCSSERIAL, (unsigned long)&settings);
+	}
+
+	set_fs(oldfs);
+}
+
+static void poll_digital(struct file *f, int channel)
+{
+	char cmd;
+
+	cmd = 0x40 | (channel & 0x1f);
+	tty_write(f, &cmd, 1);
+}
+
+static void poll_channel(struct file *f, int channel)
+{
+	char cmd;
+
+	cmd = 0x60 | (channel & 0x1f);
+	tty_write(f, &cmd, 1);
+}
+
+static struct serial_data serial_read(struct file *f, int timeout)
+{
+	struct serial_data result;
+	int length;
+
+	result.kind = is_invalid;
+	result.index = 0;
+	result.value = 0;
+	length = 0;
+	while (1) {
+		int data = tty_read(f, timeout);
+
+		length++;
+		if (data < 0) {
+			printk("serial2002 error\n");
+			break;
+		} else if (data & 0x80) {
+			result.value = (result.value << 7) | (data & 0x7f);
+		} else {
+			if (length == 1) {
+				switch ((data >> 5) & 0x03) {
+				case 0:{
+						result.value = 0;
+						result.kind = is_digital;
+					}
+					break;
+				case 1:{
+						result.value = 1;
+						result.kind = is_digital;
+					}
+					break;
+				}
+			} else {
+				result.value =
+					(result.
+					value << 2) | ((data & 0x60) >> 5);
+				result.kind = is_channel;
+			}
+			result.index = data & 0x1f;
+			break;
+		}
+	}
+	return result;
+
+}
+
+static void serial_write(struct file *f, struct serial_data data)
+{
+	if (data.kind == is_digital) {
+		unsigned char ch =
+			((data.value << 5) & 0x20) | (data.index & 0x1f);
+		tty_write(f, &ch, 1);
+	} else {
+		unsigned char ch[6];
+		int i = 0;
+		if (data.value >= (1L << 30)) {
+			ch[i] = 0x80 | ((data.value >> 30) & 0x03);
+			i++;
+		}
+		if (data.value >= (1L << 23)) {
+			ch[i] = 0x80 | ((data.value >> 23) & 0x7f);
+			i++;
+		}
+		if (data.value >= (1L << 16)) {
+			ch[i] = 0x80 | ((data.value >> 16) & 0x7f);
+			i++;
+		}
+		if (data.value >= (1L << 9)) {
+			ch[i] = 0x80 | ((data.value >> 9) & 0x7f);
+			i++;
+		}
+		ch[i] = 0x80 | ((data.value >> 2) & 0x7f);
+		i++;
+		ch[i] = ((data.value << 5) & 0x60) | (data.index & 0x1f);
+		i++;
+		tty_write(f, ch, i);
+	}
+}
+
+static void serial_2002_open(struct comedi_device * dev)
+{
+	char port[20];
+
+	sprintf(port, "/dev/ttyS%d", devpriv->port);
+	devpriv->tty = filp_open(port, 0, O_RDWR);
+	if (IS_ERR(devpriv->tty)) {
+		printk("serial_2002: file open error = %ld\n",
+			PTR_ERR(devpriv->tty));
+	} else {
+		struct config_t {
+
+			int kind;
+			int bits;
+			int min;
+			int max;
+		};
+
+		struct config_t dig_in_config[32];
+		struct config_t dig_out_config[32];
+		struct config_t chan_in_config[32];
+		struct config_t chan_out_config[32];
+		int i;
+
+		for (i = 0; i < 32; i++) {
+			dig_in_config[i].kind = 0;
+			dig_in_config[i].bits = 0;
+			dig_in_config[i].min = 0;
+			dig_in_config[i].max = 0;
+			dig_out_config[i].kind = 0;
+			dig_out_config[i].bits = 0;
+			dig_out_config[i].min = 0;
+			dig_out_config[i].max = 0;
+			chan_in_config[i].kind = 0;
+			chan_in_config[i].bits = 0;
+			chan_in_config[i].min = 0;
+			chan_in_config[i].max = 0;
+			chan_out_config[i].kind = 0;
+			chan_out_config[i].bits = 0;
+			chan_out_config[i].min = 0;
+			chan_out_config[i].max = 0;
+		}
+
+		tty_setspeed(devpriv->tty, devpriv->speed);
+		poll_channel(devpriv->tty, 31);	// Start reading configuration
+		while (1) {
+			struct serial_data data;
+
+			data = serial_read(devpriv->tty, 1000);
+			if (data.kind != is_channel || data.index != 31
+				|| !(data.value & 0xe0)) {
+				break;
+			} else {
+				int command, channel, kind;
+				struct config_t *cur_config = 0;
+
+				channel = data.value & 0x1f;
+				kind = (data.value >> 5) & 0x7;
+				command = (data.value >> 8) & 0x3;
+				switch (kind) {
+				case 1:{
+						cur_config = dig_in_config;
+					}
+					break;
+				case 2:{
+						cur_config = dig_out_config;
+					}
+					break;
+				case 3:{
+						cur_config = chan_in_config;
+					}
+					break;
+				case 4:{
+						cur_config = chan_out_config;
+					}
+					break;
+				case 5:{
+						cur_config = chan_in_config;
+					}
+					break;
+				}
+
+				if (cur_config) {
+					cur_config[channel].kind = kind;
+					switch (command) {
+					case 0:{
+							cur_config[channel].
+								bits =
+								(data.
+								value >> 10) &
+								0x3f;
+						}
+						break;
+					case 1:{
+							int unit, sign, min;
+							unit = (data.
+								value >> 10) &
+								0x7;
+							sign = (data.
+								value >> 13) &
+								0x1;
+							min = (data.
+								value >> 14) &
+								0xfffff;
+
+							switch (unit) {
+							case 0:{
+									min = min * 1000000;
+								}
+								break;
+							case 1:{
+									min = min * 1000;
+								}
+								break;
+							case 2:{
+									min = min * 1;
+								}
+								break;
+							}
+							if (sign) {
+								min = -min;
+							}
+							cur_config[channel].
+								min = min;
+						}
+						break;
+					case 2:{
+							int unit, sign, max;
+							unit = (data.
+								value >> 10) &
+								0x7;
+							sign = (data.
+								value >> 13) &
+								0x1;
+							max = (data.
+								value >> 14) &
+								0xfffff;
+
+							switch (unit) {
+							case 0:{
+									max = max * 1000000;
+								}
+								break;
+							case 1:{
+									max = max * 1000;
+								}
+								break;
+							case 2:{
+									max = max * 1;
+								}
+								break;
+							}
+							if (sign) {
+								max = -max;
+							}
+							cur_config[channel].
+								max = max;
+						}
+						break;
+					}
+				}
+			}
+		}
+		for (i = 0; i <= 4; i++) {
+			// Fill in subdev data
+			struct config_t *c;
+			unsigned char *mapping = 0;
+			struct serial2002_range_table_t *range = 0;
+			int kind = 0;
+
+			switch (i) {
+			case 0:{
+					c = dig_in_config;
+					mapping = devpriv->digital_in_mapping;
+					kind = 1;
+				}
+				break;
+			case 1:{
+					c = dig_out_config;
+					mapping = devpriv->digital_out_mapping;
+					kind = 2;
+				}
+				break;
+			case 2:{
+					c = chan_in_config;
+					mapping = devpriv->analog_in_mapping;
+					range = devpriv->in_range;
+					kind = 3;
+				}
+				break;
+			case 3:{
+					c = chan_out_config;
+					mapping = devpriv->analog_out_mapping;
+					range = devpriv->out_range;
+					kind = 4;
+				}
+				break;
+			case 4:{
+					c = chan_in_config;
+					mapping = devpriv->encoder_in_mapping;
+					range = devpriv->in_range;
+					kind = 5;
+				}
+				break;
+			default:{
+					c = 0;
+				}
+				break;
+			}
+			if (c) {
+				struct comedi_subdevice *s;
+				const struct comedi_lrange **range_table_list = NULL;
+				unsigned int *maxdata_list;
+				int j, chan;
+
+				for (chan = 0, j = 0; j < 32; j++) {
+					if (c[j].kind == kind) {
+						chan++;
+					}
+				}
+				s = &dev->subdevices[i];
+				s->n_chan = chan;
+				s->maxdata = 0;
+				if (s->maxdata_list) {
+					kfree(s->maxdata_list);
+				}
+				s->maxdata_list = maxdata_list =
+					kmalloc(sizeof(unsigned int) * s->n_chan,
+					GFP_KERNEL);
+				if (s->range_table_list) {
+					kfree(s->range_table_list);
+				}
+				if (range) {
+					s->range_table = 0;
+					s->range_table_list = range_table_list =
+						kmalloc(sizeof
+						(struct serial2002_range_table_t) *
+						s->n_chan, GFP_KERNEL);
+				}
+				for (chan = 0, j = 0; j < 32; j++) {
+					if (c[j].kind == kind) {
+						if (mapping) {
+							mapping[chan] = j;
+						}
+						if (range) {
+							range[j].length = 1;
+							range[j].range.min =
+								c[j].min;
+							range[j].range.max =
+								c[j].max;
+							range_table_list[chan] =
+								(const struct
+								comedi_lrange *)
+								&range[j];
+						}
+						maxdata_list[chan] =
+							((long long)1 << c[j].
+							bits) - 1;
+						chan++;
+					}
+				}
+			}
+		}
+	}
+}
+
+static void serial_2002_close(struct comedi_device * dev)
+{
+	if (!IS_ERR(devpriv->tty) && (devpriv->tty != 0)) {
+		filp_close(devpriv->tty, 0);
+	}
+}
+
+static int serial2002_di_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n;
+	int chan;
+
+	chan = devpriv->digital_in_mapping[CR_CHAN(insn->chanspec)];
+	for (n = 0; n < insn->n; n++) {
+		struct serial_data read;
+
+		poll_digital(devpriv->tty, chan);
+		while (1) {
+			read = serial_read(devpriv->tty, 1000);
+			if (read.kind != is_digital || read.index == chan) {
+				break;
+			}
+		}
+		data[n] = read.value;
+	}
+	return n;
+}
+
+static int serial2002_do_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n;
+	int chan;
+
+	chan = devpriv->digital_out_mapping[CR_CHAN(insn->chanspec)];
+	for (n = 0; n < insn->n; n++) {
+		struct serial_data write;
+
+		write.kind = is_digital;
+		write.index = chan;
+		write.value = data[n];
+		serial_write(devpriv->tty, write);
+	}
+	return n;
+}
+
+static int serial2002_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n;
+	int chan;
+
+	chan = devpriv->analog_in_mapping[CR_CHAN(insn->chanspec)];
+	for (n = 0; n < insn->n; n++) {
+		struct serial_data read;
+
+		poll_channel(devpriv->tty, chan);
+		while (1) {
+			read = serial_read(devpriv->tty, 1000);
+			if (read.kind != is_channel || read.index == chan) {
+				break;
+			}
+		}
+		data[n] = read.value;
+	}
+	return n;
+}
+
+static int serial2002_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n;
+	int chan;
+
+	chan = devpriv->analog_out_mapping[CR_CHAN(insn->chanspec)];
+	for (n = 0; n < insn->n; n++) {
+		struct serial_data write;
+
+		write.kind = is_channel;
+		write.index = chan;
+		write.value = data[n];
+		serial_write(devpriv->tty, write);
+		devpriv->ao_readback[chan] = data[n];
+	}
+	return n;
+}
+
+static int serial2002_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n;
+	int chan = CR_CHAN(insn->chanspec);
+
+	for (n = 0; n < insn->n; n++) {
+		data[n] = devpriv->ao_readback[chan];
+	}
+
+	return n;
+}
+
+static int serial2002_ei_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n;
+	int chan;
+
+	chan = devpriv->encoder_in_mapping[CR_CHAN(insn->chanspec)];
+	for (n = 0; n < insn->n; n++) {
+		struct serial_data read;
+
+		poll_channel(devpriv->tty, chan);
+		while (1) {
+			read = serial_read(devpriv->tty, 1000);
+			if (read.kind != is_channel || read.index == chan) {
+				break;
+			}
+		}
+		data[n] = read.value;
+	}
+	return n;
+}
+
+static int serial2002_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+
+	printk("comedi%d: serial2002: ", dev->minor);
+	dev->board_name = thisboard->name;
+	if (alloc_private(dev, sizeof(struct serial2002_private)) < 0) {
+		return -ENOMEM;
+	}
+	dev->open = serial_2002_open;
+	dev->close = serial_2002_close;
+	devpriv->port = it->options[0];
+	devpriv->speed = it->options[1];
+	printk("/dev/ttyS%d @ %d\n", devpriv->port, devpriv->speed);
+
+	if (alloc_subdevices(dev, 5) < 0)
+		return -ENOMEM;
+
+	/* digital input subdevice */
+	s = dev->subdevices + 0;
+	s->type = COMEDI_SUBD_DI;
+	s->subdev_flags = SDF_READABLE;
+	s->n_chan = 0;
+	s->maxdata = 1;
+	s->range_table = &range_digital;
+	s->insn_read = &serial2002_di_rinsn;
+
+	/* digital output subdevice */
+	s = dev->subdevices + 1;
+	s->type = COMEDI_SUBD_DO;
+	s->subdev_flags = SDF_WRITEABLE;
+	s->n_chan = 0;
+	s->maxdata = 1;
+	s->range_table = &range_digital;
+	s->insn_write = &serial2002_do_winsn;
+
+	/* analog input subdevice */
+	s = dev->subdevices + 2;
+	s->type = COMEDI_SUBD_AI;
+	s->subdev_flags = SDF_READABLE | SDF_GROUND;
+	s->n_chan = 0;
+	s->maxdata = 1;
+	s->range_table = 0;
+	s->insn_read = &serial2002_ai_rinsn;
+
+	/* analog output subdevice */
+	s = dev->subdevices + 3;
+	s->type = COMEDI_SUBD_AO;
+	s->subdev_flags = SDF_WRITEABLE;
+	s->n_chan = 0;
+	s->maxdata = 1;
+	s->range_table = 0;
+	s->insn_write = &serial2002_ao_winsn;
+	s->insn_read = &serial2002_ao_rinsn;
+
+	/* encoder input subdevice */
+	s = dev->subdevices + 4;
+	s->type = COMEDI_SUBD_COUNTER;
+	s->subdev_flags = SDF_READABLE | SDF_LSAMPL;
+	s->n_chan = 0;
+	s->maxdata = 1;
+	s->range_table = 0;
+	s->insn_read = &serial2002_ei_rinsn;
+
+	return 1;
+}
+
+static int serial2002_detach(struct comedi_device * dev)
+{
+	struct comedi_subdevice *s;
+	int i;
+
+	printk("comedi%d: serial2002: remove\n", dev->minor);
+	for (i = 0; i < 4; i++) {
+		s = &dev->subdevices[i];
+		if (s->maxdata_list) {
+			kfree(s->maxdata_list);
+		}
+		if (s->range_table_list) {
+			kfree(s->range_table_list);
+		}
+	}
+	return 0;
+}
+
+COMEDI_INITCLEANUP(driver_serial2002);
diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c
new file mode 100644
index 0000000..c7700d1
--- /dev/null
+++ b/drivers/staging/comedi/drivers/skel.c
@@ -0,0 +1,624 @@
+/*
+    comedi/drivers/skel.c
+    Skeleton code for a Comedi driver
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: skel
+Description: Skeleton driver, an example for driver writers
+Devices:
+Author: ds
+Updated: Mon, 18 Mar 2002 15:34:01 -0800
+Status: works
+
+This driver is a documented example on how Comedi drivers are
+written.
+
+Configuration Options:
+  none
+*/
+
+/*
+ * The previous block comment is used to automatically generate
+ * documentation in Comedi and Comedilib.  The fields:
+ *
+ * Driver: the name of the driver
+ * Description: a short phrase describing the driver.  Don't list boards.
+ * Devices: a full list of the boards that attempt to be supported by
+ *   the driver.  Format is "(manufacturer) board name [comedi name]",
+ *   where comedi_name is the name that is used to configure the board.
+ *   See the comment near board_name: in the struct comedi_driver structure
+ *   below.  If (manufacturer) or [comedi name] is missing, the previous
+ *   value is used.
+ * Author: you
+ * Updated: date when the _documentation_ was last updated.  Use 'date -R'
+ *   to get a value for this.
+ * Status: a one-word description of the status.  Valid values are:
+ *   works - driver works correctly on most boards supported, and
+ *     passes comedi_test.
+ *   unknown - unknown.  Usually put there by ds.
+ *   experimental - may not work in any particular release.  Author
+ *     probably wants assistance testing it.
+ *   bitrotten - driver has not been update in a long time, probably
+ *     doesn't work, and probably is missing support for significant
+ *     Comedi interface features.
+ *   untested - author probably wrote it "blind", and is believed to
+ *     work, but no confirmation.
+ *
+ * These headers should be followed by a blank line, and any comments
+ * you wish to say about the driver.  The comment area is the place
+ * to put any known bugs, limitations, unsupported features, supported
+ * command triggers, whether or not commands are supported on particular
+ * subdevices, etc.
+ *
+ * Somewhere in the comment should be information about configuration
+ * options that are used with comedi_config.
+ */
+
+#include "../comedidev.h"
+
+#include <linux/pci.h>		/* for PCI devices */
+
+/* Imaginary registers for the imaginary board */
+
+#define SKEL_SIZE 0
+
+#define SKEL_START_AI_CONV	0
+#define SKEL_AI_READ		0
+
+/*
+ * Board descriptions for two imaginary boards.  Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct skel_board {
+	const char *name;
+	int ai_chans;
+	int ai_bits;
+	int have_dio;
+};
+
+static const struct skel_board skel_boards[] = {
+	{
+	      name:	"skel-100",
+	      ai_chans:16,
+	      ai_bits:	12,
+	      have_dio:1,
+		},
+	{
+	      name:	"skel-200",
+	      ai_chans:8,
+	      ai_bits:	16,
+	      have_dio:0,
+		},
+};
+
+/* This is used by modprobe to translate PCI IDs to drivers.  Should
+ * only be used for PCI and ISA-PnP devices */
+/* Please add your PCI vendor ID to comedidev.h, and it will be forwarded
+ * upstream. */
+#define PCI_VENDOR_ID_SKEL 0xdafe
+static DEFINE_PCI_DEVICE_TABLE(skel_pci_table) = {
+	{PCI_VENDOR_ID_SKEL, 0x0100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VENDOR_ID_SKEL, 0x0200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, skel_pci_table);
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct skel_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver.  If
+   several hardware drivers keep similar information in this structure,
+   feel free to suggest moving the variable to the struct comedi_device struct.  */
+struct skel_private {
+
+	int data;
+
+	/* would be useful for a PCI device */
+	struct pci_dev *pci_dev;
+
+	/* Used for AO readback */
+	unsigned int ao_readback[2];
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct skel_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int skel_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int skel_detach(struct comedi_device * dev);
+static struct comedi_driver driver_skel = {
+      driver_name:"dummy",
+      module:THIS_MODULE,
+      attach:skel_attach,
+      detach:skel_detach,
+/* It is not necessary to implement the following members if you are
+ * writing a driver for a ISA PnP or PCI card */
+	/* Most drivers will support multiple types of boards by
+	 * having an array of board structures.  These were defined
+	 * in skel_boards[] above.  Note that the element 'name'
+	 * was first in the structure -- Comedi uses this fact to
+	 * extract the name of the board without knowing any details
+	 * about the structure except for its length.
+	 * When a device is attached (by comedi_config), the name
+	 * of the device is given to Comedi, and Comedi tries to
+	 * match it by going through the list of board names.  If
+	 * there is a match, the address of the pointer is put
+	 * into dev->board_ptr and driver->attach() is called.
+	 *
+	 * Note that these are not necessary if you can determine
+	 * the type of board in software.  ISA PnP, PCI, and PCMCIA
+	 * devices are such boards.
+	 */
+      board_name:&skel_boards[0].name,
+      offset:sizeof(struct skel_board),
+      num_names:sizeof(skel_boards) / sizeof(struct skel_board),
+};
+
+static int skel_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int skel_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int skel_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int skel_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int skel_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data);
+static int skel_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd);
+static int skel_ns_to_timer(unsigned int *ns, int round);
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board.  If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int skel_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	struct comedi_subdevice *s;
+
+	printk("comedi%d: skel: ", dev->minor);
+
+/*
+ * If you can probe the device to determine what device in a series
+ * it is, this is the place to do it.  Otherwise, dev->board_ptr
+ * should already be initialized.
+ */
+	/* dev->board_ptr = skel_probe(dev, it); */
+
+/*
+ * Initialize dev->board_name.  Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+	dev->board_name = thisboard->name;
+
+/*
+ * Allocate the private structure area.  alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+	if (alloc_private(dev, sizeof(struct skel_private)) < 0)
+		return -ENOMEM;
+
+/*
+ * Allocate the subdevice structures.  alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+	if (alloc_subdevices(dev, 3) < 0)
+		return -ENOMEM;
+
+	s = dev->subdevices + 0;
+	/* dev->read_subdev=s; */
+	/* analog input subdevice */
+	s->type = COMEDI_SUBD_AI;
+	/* we support single-ended (ground) and differential */
+	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
+	s->n_chan = thisboard->ai_chans;
+	s->maxdata = (1 << thisboard->ai_bits) - 1;
+	s->range_table = &range_bipolar10;
+	s->len_chanlist = 16;	/* This is the maximum chanlist length that
+				   the board can handle */
+	s->insn_read = skel_ai_rinsn;
+/*
+*       s->subdev_flags |= SDF_CMD_READ;
+*       s->do_cmd = skel_ai_cmd;
+*/
+	s->do_cmdtest = skel_ai_cmdtest;
+
+	s = dev->subdevices + 1;
+	/* analog output subdevice */
+	s->type = COMEDI_SUBD_AO;
+	s->subdev_flags = SDF_WRITABLE;
+	s->n_chan = 1;
+	s->maxdata = 0xffff;
+	s->range_table = &range_bipolar5;
+	s->insn_write = skel_ao_winsn;
+	s->insn_read = skel_ao_rinsn;
+
+	s = dev->subdevices + 2;
+	/* digital i/o subdevice */
+	if (thisboard->have_dio) {
+		s->type = COMEDI_SUBD_DIO;
+		s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+		s->n_chan = 16;
+		s->maxdata = 1;
+		s->range_table = &range_digital;
+		s->insn_bits = skel_dio_insn_bits;
+		s->insn_config = skel_dio_insn_config;
+	} else {
+		s->type = COMEDI_SUBD_UNUSED;
+	}
+
+	printk("attached\n");
+
+	return 0;
+}
+
+/*
+ * _detach is called to deconfigure a device.  It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach().  dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int skel_detach(struct comedi_device * dev)
+{
+	printk("comedi%d: skel: remove\n", dev->minor);
+
+	return 0;
+}
+
+/*
+ * "instructions" read/write data in "one-shot" or "software-triggered"
+ * mode.
+ */
+static int skel_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int n, i;
+	unsigned int d;
+	unsigned int status;
+
+	/* a typical programming sequence */
+
+	/* write channel to multiplexer */
+	/* outw(chan,dev->iobase + SKEL_MUX); */
+
+	/* don't wait for mux to settle */
+
+	/* convert n samples */
+	for (n = 0; n < insn->n; n++) {
+		/* trigger conversion */
+		/* outw(0,dev->iobase + SKEL_CONVERT); */
+
+#define TIMEOUT 100
+		/* wait for conversion to end */
+		for (i = 0; i < TIMEOUT; i++) {
+			status = 1;
+			/* status = inb(dev->iobase + SKEL_STATUS); */
+			if (status)
+				break;
+		}
+		if (i == TIMEOUT) {
+			/* rt_printk() should be used instead of printk()
+			 * whenever the code can be called from real-time. */
+			rt_printk("timeout\n");
+			return -ETIMEDOUT;
+		}
+
+		/* read data */
+		/* d = inw(dev->iobase + SKEL_AI_DATA); */
+		d = 0;
+
+		/* mangle the data as necessary */
+		d ^= 1 << (thisboard->ai_bits - 1);
+
+		data[n] = d;
+	}
+
+	/* return the number of samples read/written */
+	return n;
+}
+
+static int skel_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_cmd * cmd)
+{
+	int err = 0;
+	int tmp;
+
+	/* cmdtest tests a particular command to see if it is valid.
+	 * Using the cmdtest ioctl, a user can create a valid cmd
+	 * and then have it executes by the cmd ioctl.
+	 *
+	 * cmdtest returns 1,2,3,4 or 0, depending on which tests
+	 * the command passes. */
+
+	/* step 1: make sure trigger sources are trivially valid */
+
+	tmp = cmd->start_src;
+	cmd->start_src &= TRIG_NOW;
+	if (!cmd->start_src || tmp != cmd->start_src)
+		err++;
+
+	tmp = cmd->scan_begin_src;
+	cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+		err++;
+
+	tmp = cmd->convert_src;
+	cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+	if (!cmd->convert_src || tmp != cmd->convert_src)
+		err++;
+
+	tmp = cmd->scan_end_src;
+	cmd->scan_end_src &= TRIG_COUNT;
+	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+		err++;
+
+	tmp = cmd->stop_src;
+	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+	if (!cmd->stop_src || tmp != cmd->stop_src)
+		err++;
+
+	if (err)
+		return 1;
+
+	/* step 2: make sure trigger sources are unique and mutually compatible */
+
+	/* note that mutual compatiblity is not an issue here */
+	if (cmd->scan_begin_src != TRIG_TIMER &&
+		cmd->scan_begin_src != TRIG_EXT)
+		err++;
+	if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+		err++;
+	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+		err++;
+
+	if (err)
+		return 2;
+
+	/* step 3: make sure arguments are trivially compatible */
+
+	if (cmd->start_arg != 0) {
+		cmd->start_arg = 0;
+		err++;
+	}
+#define MAX_SPEED	10000	/* in nanoseconds */
+#define MIN_SPEED	1000000000	/* in nanoseconds */
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		if (cmd->scan_begin_arg < MAX_SPEED) {
+			cmd->scan_begin_arg = MAX_SPEED;
+			err++;
+		}
+		if (cmd->scan_begin_arg > MIN_SPEED) {
+			cmd->scan_begin_arg = MIN_SPEED;
+			err++;
+		}
+	} else {
+		/* external trigger */
+		/* should be level/edge, hi/lo specification here */
+		/* should specify multiple external triggers */
+		if (cmd->scan_begin_arg > 9) {
+			cmd->scan_begin_arg = 9;
+			err++;
+		}
+	}
+	if (cmd->convert_src == TRIG_TIMER) {
+		if (cmd->convert_arg < MAX_SPEED) {
+			cmd->convert_arg = MAX_SPEED;
+			err++;
+		}
+		if (cmd->convert_arg > MIN_SPEED) {
+			cmd->convert_arg = MIN_SPEED;
+			err++;
+		}
+	} else {
+		/* external trigger */
+		/* see above */
+		if (cmd->convert_arg > 9) {
+			cmd->convert_arg = 9;
+			err++;
+		}
+	}
+
+	if (cmd->scan_end_arg != cmd->chanlist_len) {
+		cmd->scan_end_arg = cmd->chanlist_len;
+		err++;
+	}
+	if (cmd->stop_src == TRIG_COUNT) {
+		if (cmd->stop_arg > 0x00ffffff) {
+			cmd->stop_arg = 0x00ffffff;
+			err++;
+		}
+	} else {
+		/* TRIG_NONE */
+		if (cmd->stop_arg != 0) {
+			cmd->stop_arg = 0;
+			err++;
+		}
+	}
+
+	if (err)
+		return 3;
+
+	/* step 4: fix up any arguments */
+
+	if (cmd->scan_begin_src == TRIG_TIMER) {
+		tmp = cmd->scan_begin_arg;
+		skel_ns_to_timer(&cmd->scan_begin_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+		if (tmp != cmd->scan_begin_arg)
+			err++;
+	}
+	if (cmd->convert_src == TRIG_TIMER) {
+		tmp = cmd->convert_arg;
+		skel_ns_to_timer(&cmd->convert_arg,
+			cmd->flags & TRIG_ROUND_MASK);
+		if (tmp != cmd->convert_arg)
+			err++;
+		if (cmd->scan_begin_src == TRIG_TIMER &&
+			cmd->scan_begin_arg <
+			cmd->convert_arg * cmd->scan_end_arg) {
+			cmd->scan_begin_arg =
+				cmd->convert_arg * cmd->scan_end_arg;
+			err++;
+		}
+	}
+
+	if (err)
+		return 4;
+
+	return 0;
+}
+
+/* This function doesn't require a particular form, this is just
+ * what happens to be used in some of the drivers.  It should
+ * convert ns nanoseconds to a counter value suitable for programming
+ * the device.  Also, it should adjust ns so that it cooresponds to
+ * the actual time that the device will use. */
+static int skel_ns_to_timer(unsigned int *ns, int round)
+{
+	/* trivial timer */
+	/* if your timing is done through two cascaded timers, the
+	 * i8253_cascade_ns_to_timer() function in 8253.h can be
+	 * very helpful.  There are also i8254_load() and i8254_mm_load()
+	 * which can be used to load values into the ubiquitous 8254 counters
+	 */
+
+	return *ns;
+}
+
+static int skel_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+
+	printk("skel_ao_winsn\n");
+	/* Writing a list of values to an AO channel is probably not
+	 * very useful, but that's how the interface is defined. */
+	for (i = 0; i < insn->n; i++) {
+		/* a typical programming sequence */
+		/* outw(data[i],dev->iobase + SKEL_DA0 + chan); */
+		devpriv->ao_readback[chan] = data[i];
+	}
+
+	/* return the number of samples read/written */
+	return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+ * Usually this means copying a value stored in devpriv. */
+static int skel_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int i;
+	int chan = CR_CHAN(insn->chanspec);
+
+	for (i = 0; i < insn->n; i++)
+		data[i] = devpriv->ao_readback[chan];
+
+	return i;
+}
+
+/* DIO devices are slightly special.  Although it is possible to
+ * implement the insn_read/insn_write interface, it is much more
+ * useful to applications if you implement the insn_bits interface.
+ * This allows packed reading/writing of the DIO channels.  The
+ * comedi core can convert between insn_bits and insn_read/write */
+static int skel_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	if (insn->n != 2)
+		return -EINVAL;
+
+	/* The insn data is a mask in data[0] and the new data
+	 * in data[1], each channel cooresponding to a bit. */
+	if (data[0]) {
+		s->state &= ~data[0];
+		s->state |= data[0] & data[1];
+		/* Write out the new digital output lines */
+		/* outw(s->state,dev->iobase + SKEL_DIO); */
+	}
+
+	/* on return, data[1] contains the value of the digital
+	 * input and output lines. */
+	/* data[1]=inw(dev->iobase + SKEL_DIO); */
+	/* or we could just return the software copy of the output values if
+	 * it was a purely digital output subdevice */
+	/* data[1]=s->state; */
+
+	return 2;
+}
+
+static int skel_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int chan = CR_CHAN(insn->chanspec);
+
+	/* The input or output configuration of each digital line is
+	 * configured by a special insn_config instruction.  chanspec
+	 * contains the channel to be changed, and data[0] contains the
+	 * value COMEDI_INPUT or COMEDI_OUTPUT. */
+	switch (data[0]) {
+	case INSN_CONFIG_DIO_OUTPUT:
+		s->io_bits |= 1 << chan;
+		break;
+	case INSN_CONFIG_DIO_INPUT:
+		s->io_bits &= ~(1 << chan);
+		break;
+	case INSN_CONFIG_DIO_QUERY:
+		data[1] =
+			(s->
+			io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+		return insn->n;
+		break;
+	default:
+		return -EINVAL;
+		break;
+	}
+	/* outw(s->io_bits,dev->iobase + SKEL_DIO_CONFIG); */
+
+	return insn->n;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver_skel);
+/* If you are writing a PCI driver you should use COMEDI_PCI_INITCLEANUP instead.
+*/
+/* COMEDI_PCI_INITCLEANUP(driver_skel, skel_pci_table) */
diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c
new file mode 100644
index 0000000..1628d21
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ssv_dnp.c
@@ -0,0 +1,311 @@
+/*
+    comedi/drivers/ssv_dnp.c
+    generic comedi driver for SSV Embedded Systems' DIL/Net-PCs
+    Copyright (C) 2001 Robert Schwebel <robert@schwebel.de>
+
+    COMEDI - Linux Control and Measurement Device Interface
+    Copyright (C) 2000 David A. Schleef <ds@schleef.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.
+
+    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.
+
+*/
+/*
+Driver: ssv_dnp
+Description: SSV Embedded Systems DIL/Net-PC
+Author: Robert Schwebel <robert@schwebel.de>
+Devices: [SSV Embedded Systems] DIL/Net-PC 1486 (dnp-1486)
+Status: unknown
+*/
+
+/* include files ----------------------------------------------------------- */
+
+#include "../comedidev.h"
+
+/* Some global definitions: the registers of the DNP ----------------------- */
+/*                                                                           */
+/* For port A and B the mode register has bits corresponding to the output   */
+/* pins, where Bit-N = 0 -> input, Bit-N = 1 -> output. Note that bits       */
+/* 4 to 7 correspond to pin 0..3 for port C data register. Ensure that bits  */
+/* 0..3 remain unchanged! For details about Port C Mode Register see         */
+/* the remarks in dnp_insn_config() below.                                   */
+
+#define CSCIR 0x22		/* Chip Setup and Control Index Register       */
+#define CSCDR 0x23		/* Chip Setup and Control Data Register        */
+#define PAMR  0xa5		/* Port A Mode Register                        */
+#define PADR  0xa9		/* Port A Data Register                        */
+#define PBMR  0xa4		/* Port B Mode Register                        */
+#define PBDR  0xa8		/* Port B Data Register                        */
+#define PCMR  0xa3		/* Port C Mode Register                        */
+#define PCDR  0xa7		/* Port C Data Register                        */
+
+/* This data structure holds information about the supported boards -------- */
+
+struct dnp_board {
+	const char *name;
+	int ai_chans;
+	int ai_bits;
+	int have_dio;
+};
+
+static const struct dnp_board dnp_boards[] = {	/* we only support one DNP 'board'   */
+	{			/* variant at the moment             */
+	      name:	"dnp-1486",
+	      ai_chans:16,
+	      ai_bits:	12,
+	      have_dio:1,
+		},
+};
+
+/* Useful for shorthand access to the particular board structure ----------- */
+#define thisboard ((const struct dnp_board *)dev->board_ptr)
+
+/* This structure is for data unique to the DNP driver --------------------- */
+struct dnp_private_data {
+
+	//
+};
+
+
+/* Shorthand macro for faster access to the private data ------------------- */
+#define devpriv ((dnp_private *)dev->private)
+
+/* ------------------------------------------------------------------------- */
+/* The struct comedi_driver structure tells the Comedi core module which functions  */
+/* to call to configure/deconfigure (attach/detach) the board, and also      */
+/* about the kernel module that contains the device code.                    */
+/*                                                                           */
+/* In the following section we define the API of this driver.                */
+/* ------------------------------------------------------------------------- */
+
+static int dnp_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dnp_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver_dnp = {
+      driver_name:"ssv_dnp",
+      module:THIS_MODULE,
+      attach:dnp_attach,
+      detach:dnp_detach,
+      board_name:&dnp_boards[0].name,
+	/* only necessary for non-PnP devs   */
+      offset:sizeof(struct dnp_board),/* like ISA-PnP, PCI or PCMCIA.      */
+      num_names:sizeof(dnp_boards) / sizeof(struct dnp_board),
+};
+
+COMEDI_INITCLEANUP(driver_dnp);
+
+static int dnp_dio_insn_bits(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+static int dnp_dio_insn_config(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+/* ------------------------------------------------------------------------- */
+/* Attach is called by comedi core to configure the driver for a particular  */
+/* board. If you specified a board_name array in the driver structure,       */
+/* dev->board_ptr contains that address.                                     */
+/* ------------------------------------------------------------------------- */
+
+static int dnp_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+
+	struct comedi_subdevice *s;
+
+	printk("comedi%d: dnp: ", dev->minor);
+
+	/* Autoprobing: this should find out which board we have. Currently only   */
+	/* the 1486 board is supported and autoprobing is not implemented :-)      */
+	//dev->board_ptr = dnp_probe(dev);
+
+	/* Initialize the name of the board. We can use the "thisboard" macro now. */
+	dev->board_name = thisboard->name;
+
+	/* Allocate the private structure area. alloc_private() is a convenient    */
+	/* macro defined in comedidev.h.                                           */
+	if (alloc_private(dev, sizeof(struct dnp_private_data)) < 0)
+		return -ENOMEM;
+
+	/* Allocate the subdevice structures. alloc_subdevice() is a convenient    */
+	/* macro defined in comedidev.h.                                           */
+
+	if (alloc_subdevices(dev, 1) < 0)
+		return -ENOMEM;
+
+	s = dev->subdevices + 0;
+	/* digital i/o subdevice                                                   */
+	s->type = COMEDI_SUBD_DIO;
+	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+	s->n_chan = 20;
+	s->maxdata = 1;
+	s->range_table = &range_digital;
+	s->insn_bits = dnp_dio_insn_bits;
+	s->insn_config = dnp_dio_insn_config;
+
+	printk("attached\n");
+
+	/* We use the I/O ports 0x22,0x23 and 0xa3-0xa9, which are always
+	 * allocated for the primary 8259, so we don't need to allocate them
+	 * ourselves. */
+
+	/* configure all ports as input (default)                                  */
+	outb(PAMR, CSCIR);
+	outb(0x00, CSCDR);
+	outb(PBMR, CSCIR);
+	outb(0x00, CSCDR);
+	outb(PCMR, CSCIR);
+	outb((inb(CSCDR) & 0xAA), CSCDR);
+
+	return 1;
+
+}
+
+/* ------------------------------------------------------------------------- */
+/* detach is called to deconfigure a device. It should deallocate the        */
+/* resources. This function is also called when _attach() fails, so it       */
+/* should be careful not to release resources that were not necessarily      */
+/* allocated by _attach(). dev->private and dev->subdevices are              */
+/* deallocated automatically by the core.                                    */
+/* ------------------------------------------------------------------------- */
+
+static int dnp_detach(struct comedi_device * dev)
+{
+
+	/* configure all ports as input (default)                                  */
+	outb(PAMR, CSCIR);
+	outb(0x00, CSCDR);
+	outb(PBMR, CSCIR);
+	outb(0x00, CSCDR);
+	outb(PCMR, CSCIR);
+	outb((inb(CSCDR) & 0xAA), CSCDR);
+
+	/* announce that we are finished                                           */
+	printk("comedi%d: dnp: remove\n", dev->minor);
+
+	return 0;
+
+}
+
+/* ------------------------------------------------------------------------- */
+/* The insn_bits interface allows packed reading/writing of DIO channels.    */
+/* The comedi core can convert between insn_bits and insn_read/write, so you */
+/* are able to use these instructions as well.                               */
+/* ------------------------------------------------------------------------- */
+
+static int dnp_dio_insn_bits(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+
+	if (insn->n != 2)
+		return -EINVAL;	/* insn uses data[0] and data[1]     */
+
+	/* The insn data is a mask in data[0] and the new data in data[1], each    */
+	/* channel cooresponding to a bit.                                         */
+
+	/* Ports A and B are straight forward: each bit corresponds to an output   */
+	/* pin with the same order. Port C is different: bits 0...3 correspond to  */
+	/* bits 4...7 of the output register (PCDR).                               */
+
+	if (data[0]) {
+
+		outb(PADR, CSCIR);
+		outb((inb(CSCDR)
+				& ~(u8) (data[0] & 0x0000FF))
+			| (u8) (data[1] & 0x0000FF), CSCDR);
+
+		outb(PBDR, CSCIR);
+		outb((inb(CSCDR)
+				& ~(u8) ((data[0] & 0x00FF00) >> 8))
+			| (u8) ((data[1] & 0x00FF00) >> 8), CSCDR);
+
+		outb(PCDR, CSCIR);
+		outb((inb(CSCDR)
+				& ~(u8) ((data[0] & 0x0F0000) >> 12))
+			| (u8) ((data[1] & 0x0F0000) >> 12), CSCDR);
+	}
+
+	/* on return, data[1] contains the value of the digital input lines.       */
+	outb(PADR, CSCIR);
+	data[0] = inb(CSCDR);
+	outb(PBDR, CSCIR);
+	data[0] += inb(CSCDR) << 8;
+	outb(PCDR, CSCIR);
+	data[0] += ((inb(CSCDR) & 0xF0) << 12);
+
+	return 2;
+
+}
+
+/* ------------------------------------------------------------------------- */
+/* Configure the direction of the bidirectional digital i/o pins. chanspec   */
+/* contains the channel to be changed and data[0] contains either            */
+/* COMEDI_INPUT or COMEDI_OUTPUT.                                            */
+/* ------------------------------------------------------------------------- */
+
+static int dnp_dio_insn_config(struct comedi_device * dev,
+	struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+
+	u8 register_buffer;
+
+	int chan = CR_CHAN(insn->chanspec);	/* reduces chanspec to lower 16 bits */
+
+	switch (data[0]) {
+	case INSN_CONFIG_DIO_OUTPUT:
+	case INSN_CONFIG_DIO_INPUT:
+		break;
+	case INSN_CONFIG_DIO_QUERY:
+		data[1] =
+			(inb(CSCDR) & (1 << chan)) ? COMEDI_OUTPUT :
+			COMEDI_INPUT;
+		return insn->n;
+		break;
+	default:
+		return -EINVAL;
+		break;
+	}
+	/* Test: which port does the channel belong to?                            */
+
+	/* We have to pay attention with port C: this is the meaning of PCMR:      */
+	/* Bit in PCMR:              7 6 5 4 3 2 1 0                               */
+	/* Corresponding port C pin: d 3 d 2 d 1 d 0   d= don't touch              */
+
+	if ((chan >= 0) && (chan <= 7)) {
+		/* this is port A */
+		outb(PAMR, CSCIR);
+	} else if ((chan >= 8) && (chan <= 15)) {
+		/* this is port B */
+		chan -= 8;
+		outb(PBMR, CSCIR);
+	} else if ((chan >= 16) && (chan <= 19)) {
+		/* this is port C; multiplication with 2 brings bits into correct        */
+		/* position for PCMR!                                                    */
+		chan -= 16;
+		chan *= 2;
+		outb(PCMR, CSCIR);
+	} else {
+		return -EINVAL;
+	}
+
+	/* read 'old' direction of the port and set bits (out=1, in=0)             */
+	register_buffer = inb(CSCDR);
+	if (data[0] == COMEDI_OUTPUT) {
+		register_buffer |= (1 << chan);
+	} else {
+		register_buffer &= ~(1 << chan);
+	}
+	outb(register_buffer, CSCDR);
+
+	return 1;
+
+}
diff --git a/drivers/staging/comedi/drivers/unioxx5.c b/drivers/staging/comedi/drivers/unioxx5.c
new file mode 100644
index 0000000..dd3b111
--- /dev/null
+++ b/drivers/staging/comedi/drivers/unioxx5.c
@@ -0,0 +1,515 @@
+/***************************************************************************
+ *                                                                         *
+ *  comedi/drivers/unioxx5.c                                               *
+ *  Driver for Fastwel UNIOxx-5 (analog and digital i/o) boards.           *
+ *                                                                         *
+ *  Copyright (C) 2006 Kruchinin Daniil (asgard) [asgard@etersoft.ru]      *
+ *                                                                         *
+ *  COMEDI - Linux Control and Measurement Device Interface                *
+ *  Copyright (C) 1998,2000 David A. Schleef <ds@schleef.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.                           *
+ *                                                                         *
+ *  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.              *
+ *                                                                         *
+ ***************************************************************************/
+/*
+
+Driver: unioxx5
+Description: Driver for Fastwel UNIOxx-5 (analog and digital i/o) boards.
+Author: Kruchinin Daniil (asgard) <asgard@etersoft.ru>
+Status: unknown
+Updated: 2006-10-09
+Devices: [Fastwel] UNIOxx-5 (unioxx5),
+
+ This card supports digital and analog I/O. It written for g01
+ subdevices only.
+ channels range: 0 .. 23 dio channels
+ and 0 .. 11 analog modules range
+ During attaching unioxx5 module displays modules identifiers
+ (see dmesg after comedi_config) in format:
+ | [module_number] module_id |
+
+*/
+
+#include "../comedidev.h"
+#include <linux/ioport.h>
+
+#define DRIVER_NAME "unioxx5"
+#define UNIOXX5_SIZE 0x10
+#define UNIOXX5_SUBDEV_BASE 0xA000	/* base addr of first subdev */
+#define UNIOXX5_SUBDEV_ODDS 0x400
+
+/* modules types */
+#define MODULE_DIGITAL 0
+#define MODULE_OUTPUT_MASK 0x80	/* analog input/output */
+
+/* constants for digital i/o */
+#define UNIOXX5_NUM_OF_CHANS 24
+
+/* constants for analog i/o */
+#define TxBE  0x10		/* transmit buffer enable */
+#define RxCA  0x20		/* 1 receive character available */
+#define Rx2CA 0x40		/* 2 receive character available */
+#define Rx4CA 0x80		/* 4 receive character available */
+
+/* bytes mask errors */
+#define Rx2CA_ERR_MASK 0x04	/* 2 bytes receiving error */
+#define Rx4CA_ERR_MASK 0x08	/* 4 bytes receiving error */
+
+/* channel modes */
+#define ALL_2_INPUT  0		/* config all digital channels to input */
+#define ALL_2_OUTPUT 1		/* config all digital channels to output */
+
+/* 'private' structure for each subdevice */
+struct unioxx5_subd_priv {
+	int usp_iobase;
+	unsigned char usp_module_type[12];	/* 12 modules. each can be 70L or 73L */
+	unsigned char usp_extra_data[12][4];	/* for saving previous written value for analog modules */
+	unsigned char usp_prev_wr_val[3];	/* previous written value */
+	unsigned char usp_prev_cn_val[3];	/* previous channel value */
+};
+
+static int unioxx5_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int unioxx5_subdev_write(struct comedi_device * dev, struct comedi_subdevice * subdev,
+	struct comedi_insn * insn, unsigned int * data);
+static int unioxx5_subdev_read(struct comedi_device * dev, struct comedi_subdevice * subdev,
+	struct comedi_insn * insn, unsigned int * data);
+static int unioxx5_insn_config(struct comedi_device * dev, struct comedi_subdevice * subdev,
+	struct comedi_insn * insn, unsigned int * data);
+static int unioxx5_detach(struct comedi_device * dev);
+static int __unioxx5_subdev_init(struct comedi_subdevice * subdev, int subdev_iobase,
+	int minor);
+static int __unioxx5_digital_write(struct unioxx5_subd_priv * usp, unsigned int * data,
+	int channel, int minor);
+static int __unioxx5_digital_read(struct unioxx5_subd_priv * usp, unsigned int * data,
+	int channel, int minor);
+//static void __unioxx5_digital_config(struct unioxx5_subd_priv* usp, int mode);
+static int __unioxx5_analog_write(struct unioxx5_subd_priv * usp, unsigned int * data,
+	int channel, int minor);
+static int __unioxx5_analog_read(struct unioxx5_subd_priv * usp, unsigned int * data,
+	int channel, int minor);
+static int __unioxx5_define_chan_offset(int chan_num);
+static void __unioxx5_analog_config(struct unioxx5_subd_priv * usp, int channel);
+
+static struct comedi_driver unioxx5_driver = {
+      driver_name:DRIVER_NAME,
+      module:THIS_MODULE,
+      attach:unioxx5_attach,
+      detach:unioxx5_detach
+};
+
+COMEDI_INITCLEANUP(unioxx5_driver);
+
+static int unioxx5_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+	int iobase, i, n_subd;
+	int id, num, ba;
+
+	iobase = it->options[0];
+
+	dev->board_name = DRIVER_NAME;
+	dev->iobase = iobase;
+	iobase += UNIOXX5_SUBDEV_BASE;
+
+	/* defining number of subdevices and getting they types (it must be 'g01')  */
+	for (i = n_subd = 0, ba = iobase; i < 4; i++, ba += UNIOXX5_SUBDEV_ODDS) {
+		id = inb(ba + 0xE);
+		num = inb(ba + 0xF);
+
+		if (id != 'g' || num != 1)
+			continue;
+
+		n_subd++;
+	}
+
+	/* unioxx5 can has from two to four subdevices */
+	if (n_subd < 2) {
+		printk(KERN_ERR
+			"your card must has at least 2 'g01' subdevices\n");
+		return -1;
+	}
+
+	if (alloc_subdevices(dev, n_subd) < 0) {
+		printk(KERN_ERR "out of memory\n");
+		return -ENOMEM;
+	}
+
+	/* initializing each of for same subdevices */
+	for (i = 0; i < n_subd; i++, iobase += UNIOXX5_SUBDEV_ODDS) {
+		if (__unioxx5_subdev_init(&dev->subdevices[i], iobase,
+				dev->minor) < 0)
+			return -1;
+	}
+
+	printk("attached\n");
+	return 0;
+}
+
+static int unioxx5_subdev_read(struct comedi_device * dev, struct comedi_subdevice * subdev,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	struct unioxx5_subd_priv *usp = subdev->private;
+	int channel, type;
+
+	channel = CR_CHAN(insn->chanspec);
+	type = usp->usp_module_type[channel / 2];	/* defining module type(analog or digital) */
+
+	if (type == MODULE_DIGITAL) {
+		if (!__unioxx5_digital_read(usp, data, channel, dev->minor))
+			return -1;
+	} else {
+		if (!__unioxx5_analog_read(usp, data, channel, dev->minor))
+			return -1;
+	}
+
+	return 1;
+}
+
+static int unioxx5_subdev_write(struct comedi_device * dev, struct comedi_subdevice * subdev,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	struct unioxx5_subd_priv *usp = subdev->private;
+	int channel, type;
+
+	channel = CR_CHAN(insn->chanspec);
+	type = usp->usp_module_type[channel / 2];	/* defining module type(analog or digital) */
+
+	if (type == MODULE_DIGITAL) {
+		if (!__unioxx5_digital_write(usp, data, channel, dev->minor))
+			return -1;
+	} else {
+		if (!__unioxx5_analog_write(usp, data, channel, dev->minor))
+			return -1;
+	}
+
+	return 1;
+}
+
+/* for digital modules only */
+static int unioxx5_insn_config(struct comedi_device * dev, struct comedi_subdevice * subdev,
+	struct comedi_insn * insn, unsigned int * data)
+{
+	int channel_offset, flags, channel = CR_CHAN(insn->chanspec), type;
+	struct unioxx5_subd_priv *usp = subdev->private;
+	int mask = 1 << (channel & 0x07);
+
+	type = usp->usp_module_type[channel / 2];
+
+	if (type != MODULE_DIGITAL) {
+		printk(KERN_ERR
+			"comedi%d: channel configuration accessible only for digital modules\n",
+			dev->minor);
+		return -1;
+	}
+
+	if ((channel_offset = __unioxx5_define_chan_offset(channel)) < 0) {
+		printk(KERN_ERR
+			"comedi%d: undefined channel %d. channel range is 0 .. 23\n",
+			dev->minor, channel);
+		return -1;
+	}
+
+	/* gets previously written value */
+	flags = usp->usp_prev_cn_val[channel_offset - 1];
+
+	switch (*data) {
+	case COMEDI_INPUT:
+		flags &= ~mask;
+		break;
+	case COMEDI_OUTPUT:
+		flags |= mask;
+		break;
+	default:
+		printk(KERN_ERR "comedi%d: unknown flag\n", dev->minor);
+		return -1;
+	}
+
+	/*                                                        *\
+	 * sets channels buffer to 1(after this we are allowed to *
+	 * change channel type on input or output)                *
+	 \*                                                        */
+	outb(1, usp->usp_iobase + 0);
+	outb(flags, usp->usp_iobase + channel_offset);	/* changes type of _one_ channel */
+	outb(0, usp->usp_iobase + 0);	/* sets channels bank to 0(allows directly input/output) */
+	usp->usp_prev_cn_val[channel_offset - 1] = flags;	/* saves written value */
+
+	return 0;
+}
+
+static int unioxx5_detach(struct comedi_device * dev)
+{
+	int i;
+	struct comedi_subdevice *subdev;
+	struct unioxx5_subd_priv *usp;
+
+	for (i = 0; i < dev->n_subdevices; i++) {
+		subdev = &dev->subdevices[i];
+		usp = subdev->private;
+		release_region(usp->usp_iobase, UNIOXX5_SIZE);
+		kfree(subdev->private);
+	}
+
+	return 0;
+}
+
+/* initializing subdevice with given address */
+static int __unioxx5_subdev_init(struct comedi_subdevice * subdev, int subdev_iobase,
+	int minor)
+{
+	struct unioxx5_subd_priv *usp;
+	int i, to, ndef_flag = 0;
+
+	if (!request_region(subdev_iobase, UNIOXX5_SIZE, DRIVER_NAME)) {
+		printk(KERN_ERR "comedi%d: I/O port conflict\n", minor);
+		return -EIO;
+	}
+
+	if ((usp = (struct unioxx5_subd_priv *) kzalloc(sizeof(*usp),
+				GFP_KERNEL)) == NULL) {
+		printk(KERN_ERR "comedi%d: erorr! --> out of memory!\n", minor);
+		return -1;
+	}
+
+	usp->usp_iobase = subdev_iobase;
+	printk("comedi%d: |", minor);
+
+	/* defining modules types */
+	for (i = 0; i < 12; i++) {
+		to = 10000;
+
+		__unioxx5_analog_config(usp, i * 2);
+		outb(i + 1, subdev_iobase + 5);	/* sends channel number to card */
+		outb('H', subdev_iobase + 6);	/* requests EEPROM world */
+		while (!(inb(subdev_iobase + 0) & TxBE)) ;	/* waits while writting will be allowed */
+		outb(0, subdev_iobase + 6);
+
+		/* waits while reading of two bytes will be allowed */
+		while (!(inb(subdev_iobase + 0) & Rx2CA)) {
+			if (--to <= 0) {
+				ndef_flag = 1;
+				break;
+			}
+		}
+
+		if (ndef_flag) {
+			usp->usp_module_type[i] = 0;
+			ndef_flag = 0;
+		} else
+			usp->usp_module_type[i] = inb(subdev_iobase + 6);
+
+		printk(" [%d] 0x%02x |", i, usp->usp_module_type[i]);
+		comedi_udelay(1);
+	}
+
+	printk("\n");
+
+	/* initial subdevice for digital or analog i/o */
+	subdev->type = COMEDI_SUBD_DIO;
+	subdev->private = usp;
+	subdev->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+	subdev->n_chan = UNIOXX5_NUM_OF_CHANS;
+	subdev->maxdata = 0xFFF;
+	subdev->range_table = &range_digital;
+	subdev->insn_read = unioxx5_subdev_read;
+	subdev->insn_write = unioxx5_subdev_write;
+	subdev->insn_config = unioxx5_insn_config;	/* for digital modules only!!! */
+
+	printk("subdevice configured\n");
+
+	return 0;
+}
+
+static int __unioxx5_digital_write(struct unioxx5_subd_priv * usp, unsigned int * data,
+	int channel, int minor)
+{
+	int channel_offset, val;
+	int mask = 1 << (channel & 0x07);
+
+	if ((channel_offset = __unioxx5_define_chan_offset(channel)) < 0) {
+		printk(KERN_ERR
+			"comedi%d: undefined channel %d. channel range is 0 .. 23\n",
+			minor, channel);
+		return 0;
+	}
+
+	val = usp->usp_prev_wr_val[channel_offset - 1];	/* getting previous written value */
+
+	if (*data)
+		val |= mask;
+	else
+		val &= ~mask;
+
+	outb(val, usp->usp_iobase + channel_offset);
+	usp->usp_prev_wr_val[channel_offset - 1] = val;	/* saving new written value */
+
+	return 1;
+}
+
+/* function for digital reading */
+static int __unioxx5_digital_read(struct unioxx5_subd_priv * usp, unsigned int * data,
+	int channel, int minor)
+{
+	int channel_offset, mask = 1 << (channel & 0x07);
+
+	if ((channel_offset = __unioxx5_define_chan_offset(channel)) < 0) {
+		printk(KERN_ERR
+			"comedi%d: undefined channel %d. channel range is 0 .. 23\n",
+			minor, channel);
+		return 0;
+	}
+
+	*data = inb(usp->usp_iobase + channel_offset);
+	*data &= mask;
+
+	if (channel_offset > 1)
+		channel -= 2 << channel_offset;	/* this operation is created for correct readed value to 0 or 1 */
+
+	*data >>= channel;
+	return 1;
+}
+
+#if 0				/* not used? */
+static void __unioxx5_digital_config(struct unioxx5_subd_priv * usp, int mode)
+{
+	int i, mask;
+
+	mask = (mode == ALL_2_OUTPUT) ? 0xFF : 0x00;
+	printk("COMEDI: mode = %d\n", mask);
+
+	outb(1, usp->usp_iobase + 0);
+
+	for (i = 0; i < 3; i++)
+		outb(mask, usp->usp_iobase + i);
+
+	outb(0, usp->usp_iobase + 0);
+}
+#endif
+
+static int __unioxx5_analog_write(struct unioxx5_subd_priv * usp, unsigned int * data,
+	int channel, int minor)
+{
+	int module, i;
+
+	module = channel / 2;	/* definig module number(0 .. 11) */
+	i = (channel % 2) << 1;	/* depends on type of channel (A or B) */
+
+	/* defining if given module can work on output */
+	if (!(usp->usp_module_type[module] & MODULE_OUTPUT_MASK)) {
+		printk(KERN_ERR
+			"comedi%d: module in position %d with id 0x%0x is for input only!\n",
+			minor, module, usp->usp_module_type[module]);
+		return 0;
+	}
+
+	__unioxx5_analog_config(usp, channel);
+	/* saving minor byte */
+	usp->usp_extra_data[module][i++] = (unsigned char)(*data & 0x00FF);
+	/* saving major byte */
+	usp->usp_extra_data[module][i] = (unsigned char)((*data & 0xFF00) >> 8);
+
+	//while(!((inb(usp->usp_iobase + 0)) & TxBE));
+	outb(module + 1, usp->usp_iobase + 5);	/* sending module number to card(1 .. 12) */
+	outb('W', usp->usp_iobase + 6);	/* sends (W)rite command to module */
+
+	/* sending for bytes to module(one byte per cycle iteration) */
+	for (i = 0; i < 4; i++) {
+		while (!((inb(usp->usp_iobase + 0)) & TxBE)) ;	/* waits while writting will be allowed */
+		outb(usp->usp_extra_data[module][i], usp->usp_iobase + 6);
+	}
+
+	return 1;
+}
+
+static int __unioxx5_analog_read(struct unioxx5_subd_priv * usp, unsigned int * data,
+	int channel, int minor)
+{
+	int module_no, read_ch;
+	char control;
+
+	module_no = channel / 2;
+	read_ch = channel % 2;	/* depend on type of channel (A or B) */
+
+	/* defining if given module can work on input */
+	if (usp->usp_module_type[module_no] & MODULE_OUTPUT_MASK) {
+		printk(KERN_ERR
+			"comedi%d: module in position %d with id 0x%02x is for output only",
+			minor, module_no, usp->usp_module_type[module_no]);
+		return 0;
+	}
+
+	__unioxx5_analog_config(usp, channel);
+	outb(module_no + 1, usp->usp_iobase + 5);	/* sends module number to card(1 .. 12) */
+	outb('V', usp->usp_iobase + 6);	/* sends to module (V)erify command */
+	control = inb(usp->usp_iobase);	/* get control register byte */
+
+	/* waits while reading four bytes will be allowed */
+	while (!((control = inb(usp->usp_iobase + 0)) & Rx4CA)) ;
+
+	/* if four bytes readding error occurs - return 0(false) */
+	if ((control & Rx4CA_ERR_MASK)) {
+		printk("COMEDI: 4 bytes error\n");
+		return 0;
+	}
+
+	if (read_ch)
+		*data = inw(usp->usp_iobase + 6);	/* channel B */
+	else
+		*data = inw(usp->usp_iobase + 4);	/* channel A */
+
+	return 1;
+}
+
+/* configure channels for analog i/o (even to output, odd to input) */
+static void __unioxx5_analog_config(struct unioxx5_subd_priv * usp, int channel)
+{
+	int chan_a, chan_b, conf, channel_offset;
+
+	channel_offset = __unioxx5_define_chan_offset(channel);
+	conf = usp->usp_prev_cn_val[channel_offset - 1];
+	chan_a = chan_b = 1;
+
+	/* setting channel A and channel B mask */
+	if (channel % 2 == 0) {
+		chan_a <<= channel & 0x07;
+		chan_b <<= (channel + 1) & 0x07;
+	} else {
+		chan_a <<= (channel - 1) & 0x07;
+		chan_b <<= channel & 0x07;
+	}
+
+	conf |= chan_a;		/* even channel ot output */
+	conf &= ~chan_b;	/* odd channel to input */
+
+	outb(1, usp->usp_iobase + 0);
+	outb(conf, usp->usp_iobase + channel_offset);
+	outb(0, usp->usp_iobase + 0);
+
+	usp->usp_prev_cn_val[channel_offset - 1] = conf;
+}
+
+/*                                                    *\
+ * this function defines if the given channel number  *
+ * enters in default numeric interspace(from 0 to 23) *
+ * and it returns address offset for usage needed     *
+ * channel.                                           *
+\*                                                    */
+
+static int __unioxx5_define_chan_offset(int chan_num)
+{
+
+	if (chan_num < 0 || chan_num > 23)
+		return -1;
+
+	return (chan_num >> 3) + 1;
+}
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c
index 3513825..d0b59e9 100644
--- a/drivers/staging/comedi/drivers/usbdux.c
+++ b/drivers/staging/comedi/drivers/usbdux.c
@@ -1,4 +1,4 @@
-#define DRIVER_VERSION "v2.1"
+#define DRIVER_VERSION "v2.2"
 #define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com"
 #define DRIVER_DESC "Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com"
 /*
@@ -25,8 +25,8 @@
 Description: University of Stirling USB DAQ & INCITE Technology Limited
 Devices: [ITL] USB-DUX (usbdux.o)
 Author: Bernd Porr <BerndPorr@f2s.com>
-Updated: 25 Nov 2007
-Status: Testing
+Updated: 8 Dec 2008
+Status: Stable
 Configuration options:
   You have to upload firmware with the -i option. The
   firmware is usually installed under /usr/share/usb or
@@ -79,6 +79,7 @@
  * 1.2:  added PWM suport via EP4
  * 2.0:  PWM seems to be stable and is not interfering with the other functions
  * 2.1:  changed PWM API
+ * 2.2:  added firmware kernel request to fix an udev problem
  *
  */
 
@@ -94,6 +95,7 @@
 #include <linux/smp_lock.h>
 #include <linux/fcntl.h>
 #include <linux/compiler.h>
+#include <linux/firmware.h>
 
 #include "../comedidev.h"
 
@@ -212,7 +214,7 @@
 
 /**************************************************/
 /* comedi constants */
-static const comedi_lrange range_usbdux_ai_range = { 4, {
+static const struct comedi_lrange range_usbdux_ai_range = { 4, {
 			BIP_RANGE(4.096),
 			BIP_RANGE(4.096 / 2),
 			UNI_RANGE(4.096),
@@ -220,7 +222,7 @@
 	}
 };
 
-static const comedi_lrange range_usbdux_ao_range = { 2, {
+static const struct comedi_lrange range_usbdux_ao_range = { 2, {
 			BIP_RANGE(4.096),
 			UNI_RANGE(4.096),
 	}
@@ -251,7 +253,7 @@
 	/* pwm-transfer handling */
 	struct urb *urbPwm;
 	/* PWM period */
-	lsampl_t pwmPeriod;
+	unsigned int pwmPeriod;
 	/* PWM internal delay for the GPIF in the FX2 */
 	int8_t pwmDelay;
 	/* size of the PWM buffer which holds the bit pattern */
@@ -267,7 +269,7 @@
 	/* interface structure in 2.6 */
 	struct usb_interface *interface;
 	/* comedi device for the interrupt context */
-	comedi_device *comedidev;
+	struct comedi_device *comedidev;
 	/* is it USB_SPEED_HIGH or not? */
 	short int high_speed;
 	/* asynchronous command is running */
@@ -361,7 +363,7 @@
  * This will cancel a running acquisition operation.
  * This is called by comedi but never from inside the driver.
  */
-static int usbdux_ai_cancel(comedi_device *dev, comedi_subdevice *s)
+static int usbdux_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct usbduxsub *this_usbduxsub;
 	int res = 0;
@@ -390,8 +392,8 @@
 {
 	int i, err, n;
 	struct usbduxsub *this_usbduxsub;
-	comedi_device *this_comedidev;
-	comedi_subdevice *s;
+	struct comedi_device *this_comedidev;
+	struct comedi_subdevice *s;
 
 	/* the context variable points to the subdevice */
 	this_comedidev = urb->context;
@@ -559,7 +561,7 @@
 }
 
 /* force unlink, is called by comedi */
-static int usbdux_ao_cancel(comedi_device *dev, comedi_subdevice *s)
+static int usbdux_ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct usbduxsub *this_usbduxsub = dev->private;
 	int res = 0;
@@ -584,8 +586,8 @@
 	int i, ret;
 	int8_t *datap;
 	struct usbduxsub *this_usbduxsub;
-	comedi_device *this_comedidev;
-	comedi_subdevice *s;
+	struct comedi_device *this_comedidev;
+	struct comedi_subdevice *s;
 
 	/* the context variable points to the subdevice */
 	this_comedidev = urb->context;
@@ -654,7 +656,7 @@
 		((uint8_t *) (urb->transfer_buffer))[0] =
 			s->async->cmd.chanlist_len;
 		for (i = 0; i < s->async->cmd.chanlist_len; i++) {
-			sampl_t temp;
+			short temp;
 			if (i >= NUMOUTCHANNELS)
 				break;
 
@@ -718,31 +720,29 @@
 	int errcode = 0;
 	uint8_t local_transfer_buffer[16];
 
-	if (usbduxsub->probed) {
-		/* 7f92 to zero */
-		local_transfer_buffer[0] = 0;
-		errcode = usb_control_msg(usbduxsub->usbdev,
-			/* create a pipe for a control transfer */
-			usb_sndctrlpipe(usbduxsub->usbdev, 0),
-			/* bRequest, "Firmware" */
-			USBDUXSUB_FIRMWARE,
-			/* bmRequestType */
-			VENDOR_DIR_OUT,
-			/* Value */
-			USBDUXSUB_CPUCS,
-			/* Index */
-			0x0000,
-			/* address of the transfer buffer */
-			local_transfer_buffer,
-			/* Length */
-			1,
-			/* Timeout */
-			EZTIMEOUT);
-		if (errcode < 0) {
-			dev_err(&usbduxsub->interface->dev,
-				"comedi_: control msg failed (start)\n");
-			return errcode;
-		}
+	/* 7f92 to zero */
+	local_transfer_buffer[0] = 0;
+	errcode = usb_control_msg(usbduxsub->usbdev,
+				  /* create a pipe for a control transfer */
+				  usb_sndctrlpipe(usbduxsub->usbdev, 0),
+				  /* bRequest, "Firmware" */
+				  USBDUXSUB_FIRMWARE,
+				  /* bmRequestType */
+				  VENDOR_DIR_OUT,
+				  /* Value */
+				  USBDUXSUB_CPUCS,
+				  /* Index */
+				  0x0000,
+				  /* address of the transfer buffer */
+				  local_transfer_buffer,
+				  /* Length */
+				  1,
+				  /* Timeout */
+				  EZTIMEOUT);
+	if (errcode < 0) {
+		dev_err(&usbduxsub->interface->dev,
+			"comedi_: control msg failed (start)\n");
+		return errcode;
 	}
 	return 0;
 }
@@ -752,28 +752,27 @@
 	int errcode = 0;
 
 	uint8_t local_transfer_buffer[16];
-	if (usbduxsub->probed) {
-		/* 7f92 to one */
-		local_transfer_buffer[0] = 1;
-		errcode = usb_control_msg(usbduxsub->usbdev,
-			usb_sndctrlpipe(usbduxsub->usbdev, 0),
-			/* bRequest, "Firmware" */
-			USBDUXSUB_FIRMWARE,
-			/* bmRequestType */
-			VENDOR_DIR_OUT,
-			/* Value */
-			USBDUXSUB_CPUCS,
-			/* Index */
-			0x0000, local_transfer_buffer,
-			/* Length */
-			1,
-			/* Timeout */
-			EZTIMEOUT);
-		if (errcode < 0) {
-			dev_err(&usbduxsub->interface->dev,
-				"comedi_: control msg failed (stop)\n");
-			return errcode;
-		}
+
+	/* 7f92 to one */
+	local_transfer_buffer[0] = 1;
+	errcode = usb_control_msg(usbduxsub->usbdev,
+				  usb_sndctrlpipe(usbduxsub->usbdev, 0),
+				  /* bRequest, "Firmware" */
+				  USBDUXSUB_FIRMWARE,
+				  /* bmRequestType */
+				  VENDOR_DIR_OUT,
+				  /* Value */
+				  USBDUXSUB_CPUCS,
+				  /* Index */
+				  0x0000, local_transfer_buffer,
+				  /* Length */
+				  1,
+				  /* Timeout */
+				  EZTIMEOUT);
+	if (errcode < 0) {
+		dev_err(&usbduxsub->interface->dev,
+			"comedi_: control msg failed (stop)\n");
+		return errcode;
 	}
 	return 0;
 }
@@ -784,13 +783,7 @@
 {
 	int errcode;
 
-	if (usbduxsub->probed) {
-		dev_dbg(&usbduxsub->interface->dev,
-			"comedi%d: usbdux: uploading %d bytes"
-			" to addr %d, first byte=%d.\n",
-			usbduxsub->comedidev->minor, len,
-			startAddr, local_transfer_buffer[0]);
-		errcode = usb_control_msg(usbduxsub->usbdev,
+	errcode = usb_control_msg(usbduxsub->usbdev,
 			usb_sndctrlpipe(usbduxsub->usbdev, 0),
 			/* brequest, firmware */
 			USBDUXSUB_FIRMWARE,
@@ -806,16 +799,12 @@
 			len,
 			/* timeout */
 			EZTIMEOUT);
-		dev_dbg(&usbduxsub->interface->dev,
-			"comedi_: result=%d\n", errcode);
-		if (errcode < 0) {
-			dev_err(&usbduxsub->interface->dev,
-				"comedi_: upload failed\n");
-			return errcode;
-		}
-	} else {
-		/* no device on the bus for this index */
-		return -EFAULT;
+	dev_dbg(&usbduxsub->interface->dev,
+		"comedi_: result=%d\n", errcode);
+	if (errcode < 0) {
+		dev_err(&usbduxsub->interface->dev,
+		"comedi_: upload failed\n");
+		return errcode;
 	}
 	return 0;
 }
@@ -907,8 +896,8 @@
 	return 0;
 }
 
-static int usbdux_ai_cmdtest(comedi_device *dev, comedi_subdevice *s,
-			     comedi_cmd *cmd)
+static int usbdux_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+			     struct comedi_cmd *cmd)
 {
 	int err = 0, tmp, i;
 	unsigned int tmpTimer;
@@ -1127,7 +1116,7 @@
 	return -EFAULT;
 }
 
-static int usbdux_ai_inttrig(comedi_device *dev, comedi_subdevice *s,
+static int usbdux_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
 			     unsigned int trignum)
 {
 	int ret;
@@ -1171,9 +1160,9 @@
 	return 1;
 }
 
-static int usbdux_ai_cmd(comedi_device *dev, comedi_subdevice *s)
+static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
-	comedi_cmd *cmd = &s->async->cmd;
+	struct comedi_cmd *cmd = &s->async->cmd;
 	unsigned int chan, range;
 	int i, ret;
 	struct usbduxsub *this_usbduxsub = dev->private;
@@ -1287,11 +1276,11 @@
 }
 
 /* Mode 0 is used to get a single conversion on demand */
-static int usbdux_ai_insn_read(comedi_device *dev, comedi_subdevice *s,
-			       comedi_insn *insn, lsampl_t *data)
+static int usbdux_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+			       struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
-	lsampl_t one = 0;
+	unsigned int one = 0;
 	int chan, range;
 	int err;
 	struct usbduxsub *this_usbduxsub = dev->private;
@@ -1348,8 +1337,8 @@
 /************************************/
 /* analog out */
 
-static int usbdux_ao_insn_read(comedi_device *dev, comedi_subdevice *s,
-			       comedi_insn *insn, lsampl_t *data)
+static int usbdux_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+			       struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 	int chan = CR_CHAN(insn->chanspec);
@@ -1370,8 +1359,8 @@
 	return i;
 }
 
-static int usbdux_ao_insn_write(comedi_device *dev, comedi_subdevice *s,
-				comedi_insn *insn, lsampl_t *data)
+static int usbdux_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data)
 {
 	int i, err;
 	int chan = CR_CHAN(insn->chanspec);
@@ -1420,7 +1409,7 @@
 	return i;
 }
 
-static int usbdux_ao_inttrig(comedi_device *dev, comedi_subdevice *s,
+static int usbdux_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
 			     unsigned int trignum)
 {
 	int ret;
@@ -1461,8 +1450,8 @@
 	return 1;
 }
 
-static int usbdux_ao_cmdtest(comedi_device *dev, comedi_subdevice *s,
-			     comedi_cmd *cmd)
+static int usbdux_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+			     struct comedi_cmd *cmd)
 {
 	int err = 0, tmp;
 	struct usbduxsub *this_usbduxsub = dev->private;
@@ -1600,9 +1589,9 @@
 	return 0;
 }
 
-static int usbdux_ao_cmd(comedi_device *dev, comedi_subdevice *s)
+static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
-	comedi_cmd *cmd = &s->async->cmd;
+	struct comedi_cmd *cmd = &s->async->cmd;
 	unsigned int chan, gain;
 	int i, ret;
 	struct usbduxsub *this_usbduxsub = dev->private;
@@ -1708,8 +1697,8 @@
 	return 0;
 }
 
-static int usbdux_dio_insn_config(comedi_device *dev, comedi_subdevice *s,
-				  comedi_insn *insn, lsampl_t *data)
+static int usbdux_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+				  struct comedi_insn *insn, unsigned int *data)
 {
 	int chan = CR_CHAN(insn->chanspec);
 
@@ -1739,8 +1728,8 @@
 	return insn->n;
 }
 
-static int usbdux_dio_insn_bits(comedi_device *dev, comedi_subdevice *s,
-				comedi_insn *insn, lsampl_t *data)
+static int usbdux_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data)
 {
 
 	struct usbduxsub *this_usbduxsub = dev->private;
@@ -1786,8 +1775,8 @@
 }
 
 /* reads the 4 counters, only two are used just now */
-static int usbdux_counter_read(comedi_device *dev, comedi_subdevice *s,
-			       comedi_insn *insn, lsampl_t *data)
+static int usbdux_counter_read(struct comedi_device *dev, struct comedi_subdevice *s,
+			       struct comedi_insn *insn, unsigned int *data)
 {
 	struct usbduxsub *this_usbduxsub = dev->private;
 	int chan = insn->chanspec;
@@ -1820,8 +1809,8 @@
 	return 1;
 }
 
-static int usbdux_counter_write(comedi_device *dev, comedi_subdevice *s,
-				comedi_insn *insn, lsampl_t *data)
+static int usbdux_counter_write(struct comedi_device *dev, struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data)
 {
 	struct usbduxsub *this_usbduxsub = dev->private;
 	int err;
@@ -1850,8 +1839,8 @@
 	return 1;
 }
 
-static int usbdux_counter_config(comedi_device *dev, comedi_subdevice *s,
-				 comedi_insn *insn, lsampl_t *data)
+static int usbdux_counter_config(struct comedi_device *dev, struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data)
 {
 	/* nothing to do so far */
 	return 2;
@@ -1894,7 +1883,7 @@
 }
 
 /* force unlink - is called by comedi */
-static int usbdux_pwm_cancel(comedi_device *dev, comedi_subdevice *s)
+static int usbdux_pwm_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct usbduxsub *this_usbduxsub = dev->private;
 	int res = 0;
@@ -1916,8 +1905,8 @@
 {
 	int ret;
 	struct usbduxsub *this_usbduxsub;
-	comedi_device *this_comedidev;
-	comedi_subdevice *s;
+	struct comedi_device *this_comedidev;
+	struct comedi_subdevice *s;
 
 	/* printk(KERN_DEBUG "PWM: IRQ\n"); */
 
@@ -2007,8 +1996,8 @@
 	return 0;
 }
 
-static int usbdux_pwm_period(comedi_device *dev, comedi_subdevice *s,
-			     lsampl_t period)
+static int usbdux_pwm_period(struct comedi_device *dev, struct comedi_subdevice *s,
+			     unsigned int period)
 {
 	struct usbduxsub *this_usbduxsub = dev->private;
 	int fx2delay = 255;
@@ -2035,7 +2024,7 @@
 }
 
 /* is called from insn so there's no need to do all the sanity checks */
-static int usbdux_pwm_start(comedi_device *dev, comedi_subdevice *s)
+static int usbdux_pwm_start(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	int ret, i;
 	struct usbduxsub *this_usbduxsub = dev->private;
@@ -2067,8 +2056,8 @@
 }
 
 /* generates the bit pattern for PWM with the optional sign bit */
-static int usbdux_pwm_pattern(comedi_device *dev, comedi_subdevice *s,
-			      int channel, lsampl_t value, lsampl_t sign)
+static int usbdux_pwm_pattern(struct comedi_device *dev, struct comedi_subdevice *s,
+			      int channel, unsigned int value, unsigned int sign)
 {
 	struct usbduxsub *this_usbduxsub = dev->private;
 	int i, szbuf;
@@ -2108,8 +2097,8 @@
 	return 1;
 }
 
-static int usbdux_pwm_write(comedi_device *dev, comedi_subdevice *s,
-			    comedi_insn *insn, lsampl_t *data)
+static int usbdux_pwm_write(struct comedi_device *dev, struct comedi_subdevice *s,
+			    struct comedi_insn *insn, unsigned int *data)
 {
 	struct usbduxsub *this_usbduxsub = dev->private;
 
@@ -2133,16 +2122,16 @@
 				  data[0], 0);
 }
 
-static int usbdux_pwm_read(comedi_device *x1, comedi_subdevice *x2,
-			   comedi_insn *x3, lsampl_t *x4)
+static int usbdux_pwm_read(struct comedi_device *x1, struct comedi_subdevice *x2,
+			   struct comedi_insn *x3, unsigned int *x4)
 {
 	/* not needed */
 	return -EINVAL;
 };
 
 /* switches on/off PWM */
-static int usbdux_pwm_config(comedi_device *dev, comedi_subdevice *s,
-			     comedi_insn *insn, lsampl_t *data)
+static int usbdux_pwm_config(struct comedi_device *dev, struct comedi_subdevice *s,
+			     struct comedi_insn *insn, unsigned int *data)
 {
 	struct usbduxsub *this_usbduxsub = dev->private;
 	switch (data[0]) {
@@ -2292,13 +2281,13 @@
 #define FIRMWARE_MAX_LEN 0x2000
 
 /* taken from David Brownell's fxload and adjusted for this driver */
-static int read_firmware(struct usbduxsub *usbduxsub, void *firmwarePtr,
+static int read_firmware(struct usbduxsub *usbduxsub, const void *firmwarePtr,
 			 long size)
 {
 	struct device *dev = &usbduxsub->interface->dev;
 	int i = 0;
 	unsigned char *fp = (char *)firmwarePtr;
-	unsigned char *firmwareBinary = NULL;
+	unsigned char *firmwareBinary;
 	int res = 0;
 	int maxAddr = 0;
 
@@ -2322,6 +2311,7 @@
 			j++;
 			if (j >= sizeof(buf)) {
 				dev_err(dev, "comedi_: bogus firmware file!\n");
+				kfree(firmwareBinary);
 				return -1;
 			}
 		}
@@ -2344,6 +2334,7 @@
 		if (buf[0] != ':') {
 			dev_err(dev, "comedi_: upload: not an ihex record: %s",
 				buf);
+			kfree(firmwareBinary);
 			return -EFAULT;
 		}
 
@@ -2360,6 +2351,7 @@
 		if (maxAddr >= FIRMWARE_MAX_LEN) {
 			dev_err(dev, "comedi_: firmware upload goes "
 				"beyond FX2 RAM boundaries.\n");
+			kfree(firmwareBinary);
 			return -EFAULT;
 		}
 		/* dev_dbg(dev, "comedi_: off=%x, len=%x:\n", off, len); */
@@ -2375,6 +2367,7 @@
 		if (type != 0) {
 			dev_err(dev, "comedi_: unsupported record type: %u\n",
 				type);
+			kfree(firmwareBinary);
 			return -EFAULT;
 		}
 
@@ -2395,6 +2388,34 @@
 	return res;
 }
 
+static void usbdux_firmware_request_complete_handler(const struct firmware *fw,
+						     void *context)
+{
+	struct usbduxsub *usbduxsub_tmp = context;
+	struct usb_device *usbdev = usbduxsub_tmp->usbdev;
+	int ret;
+
+	if (fw == NULL) {
+		dev_err(&usbdev->dev,
+			"Firmware complete handler without firmware!\n");
+		return;
+	}
+
+	/*
+	 * we need to upload the firmware here because fw will be
+	 * freed once we've left this function
+	 */
+	ret = read_firmware(usbduxsub_tmp, fw->data, fw->size);
+
+	if (ret) {
+		dev_err(&usbdev->dev,
+			"Could not upload firmware (err=%d)\n",
+			ret);
+		return;
+	}
+	comedi_usb_auto_config(usbdev, BOARDNAME);
+}
+
 /* allocate memory for the urbs and initialise them */
 static int usbduxsub_probe(struct usb_interface *uinterf,
 			   const struct usb_device_id *id)
@@ -2403,6 +2424,7 @@
 	struct device *dev = &uinterf->dev;
 	int i;
 	int index;
+	int ret;
 
 	dev_dbg(dev, "comedi_: usbdux_: "
 		"finding a free structure for the usb-device\n");
@@ -2637,6 +2659,19 @@
 	/* we've reached the bottom of the function */
 	usbduxsub[index].probed = 1;
 	up(&start_stop_sem);
+
+	ret = request_firmware_nowait(THIS_MODULE,
+				      FW_ACTION_HOTPLUG,
+				      "usbdux_firmware.hex",
+				      &udev->dev,
+				      usbduxsub + index,
+				      usbdux_firmware_request_complete_handler);
+
+	if (ret) {
+		dev_err(dev, "Could not load firmware (err=%d)\n", ret);
+		return ret;
+	}
+
 	dev_info(dev, "comedi_: usbdux%d "
 		 "has been successfully initialised.\n", index);
 	/* success */
@@ -2658,6 +2693,7 @@
 			"comedi_: BUG! called with wrong ptr!!!\n");
 		return;
 	}
+	comedi_usb_auto_unconfig(udev);
 	down(&start_stop_sem);
 	down(&usbduxsub_tmp->sem);
 	tidy_up(usbduxsub_tmp);
@@ -2667,14 +2703,14 @@
 }
 
 /* is called when comedi-config is called */
-static int usbdux_attach(comedi_device *dev, comedi_devconfig *it)
+static int usbdux_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
 	int ret;
 	int index;
 	int i;
 	struct usbduxsub *udev;
 
-	comedi_subdevice *s = NULL;
+	struct comedi_subdevice *s = NULL;
 	dev->private = NULL;
 
 	down(&start_stop_sem);
@@ -2834,7 +2870,7 @@
 	return 0;
 }
 
-static int usbdux_detach(comedi_device *dev)
+static int usbdux_detach(struct comedi_device *dev)
 {
 	struct usbduxsub *usbduxsub_tmp;
 
@@ -2867,26 +2903,13 @@
 }
 
 /* main driver struct */
-static comedi_driver driver_usbdux = {
+static struct comedi_driver driver_usbdux = {
       .driver_name =	"usbdux",
       .module =		THIS_MODULE,
       .attach =		usbdux_attach,
       .detach =		usbdux_detach,
 };
 
-static void init_usb_devices(void)
-{
-	int index;
-
-	/* all devices entries are invalid to begin with */
-	/* they will become valid by the probe function */
-	/* and then finally by the attach-function */
-	for (index = 0; index < NUMUSBDUX; index++) {
-		memset(&(usbduxsub[index]), 0x00, sizeof(usbduxsub[index]));
-		init_MUTEX(&(usbduxsub[index].sem));
-	}
-}
-
 /* Table with the USB-devices: just now only testing IDs */
 static struct usb_device_id usbduxsub_table[] = {
 	{USB_DEVICE(0x13d8, 0x0001) },
@@ -2907,18 +2930,17 @@
 /* Can't use the nice macro as I have also to initialise the USB */
 /* subsystem: */
 /* registering the usb-system _and_ the comedi-driver */
-static int init_usbdux(void)
+static int __init init_usbdux(void)
 {
 	printk(KERN_INFO KBUILD_MODNAME ": "
 	       DRIVER_VERSION ":" DRIVER_DESC "\n");
-	init_usb_devices();
 	usb_register(&usbduxsub_driver);
 	comedi_driver_register(&driver_usbdux);
 	return 0;
 }
 
 /* deregistering the comedi driver and the usb-subsystem */
-static void exit_usbdux(void)
+static void __exit exit_usbdux(void)
 {
 	comedi_driver_unregister(&driver_usbdux);
 	usb_deregister(&usbduxsub_driver);
diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c
index 3a00ff0..2fb64de 100644
--- a/drivers/staging/comedi/drivers/usbduxfast.c
+++ b/drivers/staging/comedi/drivers/usbduxfast.c
@@ -1,33 +1,20 @@
-#define DRIVER_VERSION "v0.99a"
-#define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com"
-#define DRIVER_DESC "USB-DUXfast, BerndPorr@f2s.com"
 /*
-   comedi/drivers/usbduxfast.c
-   Copyright (C) 2004 Bernd Porr, Bernd.Porr@f2s.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, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
-Driver: usbduxfast
-Description: ITL USB-DUXfast
-Devices: [ITL] USB-DUX (usbduxfast.o)
-Author: Bernd Porr <BerndPorr@f2s.com>
-Updated: 04 Dec 2006
-Status: testing
-*/
+ *  Copyright (C) 2004 Bernd Porr, Bernd.Porr@f2s.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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
 
 /*
  * I must give credit here to Chris Baugher who
@@ -42,12 +29,16 @@
  * 0.9: Dropping the first data packet which seems to be from the last transfer.
  *      Buffer overflows in the FX2 are handed over to comedi.
  * 0.92: Dropping now 4 packets. The quad buffer has to be emptied.
- *       Added insn command basically for testing. Sample rate is 1MHz/16ch=62.5kHz
+ *       Added insn command basically for testing. Sample rate is
+ *       1MHz/16ch=62.5kHz
  * 0.99: Ian Abbott pointed out a bug which has been corrected. Thanks!
  * 0.99a: added external trigger.
+ * 1.00: added firmware kernel request to the driver which fixed
+ *       udev coldplug problem
  */
 
 #include <linux/kernel.h>
+#include <linux/firmware.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
@@ -59,536 +50,549 @@
 #include "comedi_fc.h"
 #include "../comedidev.h"
 
-// (un)comment this if you want to have debug info.
-//#define CONFIG_COMEDI_DEBUG
-#undef  CONFIG_COMEDI_DEBUG
 
+#define DRIVER_VERSION "v1.0"
+#define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com"
+#define DRIVER_DESC "USB-DUXfast, BerndPorr@f2s.com"
 #define BOARDNAME "usbduxfast"
 
-// timeout for the USB-transfer
-#define EZTIMEOUT 30
+/*
+ * timeout for the USB-transfer
+ */
+#define EZTIMEOUT	30
 
-// constants for "firmware" upload and download
-#define USBDUXFASTSUB_FIRMWARE 0xA0
-#define VENDOR_DIR_IN  0xC0
-#define VENDOR_DIR_OUT 0x40
+/*
+ * constants for "firmware" upload and download
+ */
+#define USBDUXFASTSUB_FIRMWARE	0xA0
+#define VENDOR_DIR_IN		0xC0
+#define VENDOR_DIR_OUT		0x40
 
-// internal adresses of the 8051 processor
-#define USBDUXFASTSUB_CPUCS 0xE600
+/*
+ * internal adresses of the 8051 processor
+ */
+#define USBDUXFASTSUB_CPUCS	0xE600
 
-// max lenghth of the transfer-buffer for software upload
-#define TB_LEN 0x2000
+/*
+ * max lenghth of the transfer-buffer for software upload
+ */
+#define TB_LEN	0x2000
 
-// Input endpoint number
-#define BULKINEP           6
+/*
+ * input endpoint number
+ */
+#define BULKINEP	6
 
-// Endpoint for the A/D channellist: bulk OUT
-#define CHANNELLISTEP     4
+/*
+ * endpoint for the A/D channellist: bulk OUT
+ */
+#define CHANNELLISTEP	4
 
-// Number of channels
-#define NUMCHANNELS       32
+/*
+ * number of channels
+ */
+#define NUMCHANNELS	32
 
-// size of the waveform descriptor
-#define WAVESIZE          0x20
+/*
+ * size of the waveform descriptor
+ */
+#define WAVESIZE	0x20
 
-// Size of one A/D value
-#define SIZEADIN          ((sizeof(int16_t)))
+/*
+ * size of one A/D value
+ */
+#define SIZEADIN	(sizeof(int16_t))
 
-// Size of the input-buffer IN BYTES
-#define SIZEINBUF         512
+/*
+ * size of the input-buffer IN BYTES
+ */
+#define SIZEINBUF	512
 
-// 16 bytes.
-#define SIZEINSNBUF       512
+/*
+ * 16 bytes
+ */
+#define SIZEINSNBUF	512
 
-// Size of the buffer for the dux commands
-#define SIZEOFDUXBUFFER    256	// bytes
+/*
+ * size of the buffer for the dux commands in bytes
+ */
+#define SIZEOFDUXBUFFER	256
 
-// Number of in-URBs which receive the data: min=5
-#define NUMOFINBUFFERSHIGH     10
+/*
+ * number of in-URBs which receive the data: min=5
+ */
+#define NUMOFINBUFFERSHIGH	10
 
-// Total number of usbduxfast devices
-#define NUMUSBDUXFAST             16
+/*
+ * total number of usbduxfast devices
+ */
+#define NUMUSBDUXFAST	16
 
-// Number of subdevices
-#define N_SUBDEVICES          1
+/*
+ * number of subdevices
+ */
+#define N_SUBDEVICES	1
 
-// Analogue in subdevice
-#define SUBDEV_AD             0
+/*
+ * analogue in subdevice
+ */
+#define SUBDEV_AD	0
 
-// min delay steps for more than one channel
-// basically when the mux gives up. ;-)
-#define MIN_SAMPLING_PERIOD 9	// steps at 30MHz in the FX2
+/*
+ * min delay steps for more than one channel
+ * basically when the mux gives up ;-)
+ *
+ * steps at 30MHz in the FX2
+ */
+#define MIN_SAMPLING_PERIOD	9
 
-// Max number of 1/30MHz delay steps:
-#define MAX_SAMPLING_PERIOD 500
+/*
+ * max number of 1/30MHz delay steps
+ */
+#define MAX_SAMPLING_PERIOD	500
 
-// Number of received packets to ignore before we start handing data over to comedi.
-// It's quad buffering and we have to ignore 4 packets.
-#define PACKETS_TO_IGNORE 4
+/*
+ * number of received packets to ignore before we start handing data
+ * over to comedi, it's quad buffering and we have to ignore 4 packets
+ */
+#define PACKETS_TO_IGNORE	4
 
-/////////////////////////////////////////////
-// comedi constants
-static const comedi_lrange range_usbduxfast_ai_range = { 2, {
-			BIP_RANGE(0.75),
-			BIP_RANGE(0.5),
-	}
+/*
+ * comedi constants
+ */
+static const struct comedi_lrange range_usbduxfast_ai_range = {
+	2, { BIP_RANGE(0.75), BIP_RANGE(0.5) }
 };
 
 /*
  * private structure of one subdevice
+ *
+ * this is the structure which holds all the data of this driver
+ * one sub device just now: A/D
  */
-
-// This is the structure which holds all the data of this driver
-// one sub device just now: A/D
-typedef struct {
-	// attached?
-	int attached;
-	// is it associated with a subdevice?
-	int probed;
-	// pointer to the usb-device
-	struct usb_device *usbdev;
-	// BULK-transfer handling: urb
-	struct urb *urbIn;
+struct usbduxfastsub_s {
+	int attached;			/* is attached? */
+	int probed;			/* is it associated with a subdevice? */
+	struct usb_device *usbdev;	/* pointer to the usb-device */
+	struct urb *urbIn;		/* BULK-transfer handling: urb */
 	int8_t *transfer_buffer;
-	// input buffer for single insn
-	int16_t *insnBuffer;
-	// interface number
-	int ifnum;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-	// interface structure in 2.6
-	struct usb_interface *interface;
-#endif
-	// comedi device for the interrupt context
-	comedi_device *comedidev;
-	// asynchronous command is running
-	short int ai_cmd_running;
-	// continous aquisition
-	short int ai_continous;
-	// number of samples to aquire
-	long int ai_sample_count;
-	// commands
-	uint8_t *dux_commands;
-	// counter which ignores the first buffers
-	int ignore;
+	int16_t *insnBuffer;		/* input buffer for single insn */
+	int ifnum;			/* interface number */
+	struct usb_interface *interface;	/* interface structure */
+	struct comedi_device *comedidev;	/* comedi device for the interrupt
+					   context */
+	short int ai_cmd_running;	/* asynchronous command is running */
+	short int ai_continous;		/* continous aquisition */
+	long int ai_sample_count;	/* number of samples to aquire */
+	uint8_t *dux_commands;		/* commands */
+	int ignore;			/* counter which ignores the first
+					   buffers */
 	struct semaphore sem;
-} usbduxfastsub_t;
+};
 
-// The pointer to the private usb-data of the driver
-// is also the private data for the comedi-device.
-// This has to be global as the usb subsystem needs
-// global variables. The other reason is that this
-// structure must be there _before_ any comedi
-// command is issued. The usb subsystem must be
-// initialised before comedi can access it.
-static usbduxfastsub_t usbduxfastsub[NUMUSBDUXFAST];
+/*
+ * The pointer to the private usb-data of the driver
+ * is also the private data for the comedi-device.
+ * This has to be global as the usb subsystem needs
+ * global variables. The other reason is that this
+ * structure must be there _before_ any comedi
+ * command is issued. The usb subsystem must be
+ * initialised before comedi can access it.
+ */
+static struct usbduxfastsub_s usbduxfastsub[NUMUSBDUXFAST];
 
 static DECLARE_MUTEX(start_stop_sem);
 
-// bulk transfers to usbduxfast
-
+/*
+ * bulk transfers to usbduxfast
+ */
 #define SENDADCOMMANDS            0
 #define SENDINITEP6               1
 
-static int send_dux_commands(usbduxfastsub_t * this_usbduxfastsub, int cmd_type)
+static int send_dux_commands(struct usbduxfastsub_s *udfs, int cmd_type)
 {
-	int result, nsent;
-	this_usbduxfastsub->dux_commands[0] = cmd_type;
+	int tmp, nsent;
+
+	udfs->dux_commands[0] = cmd_type;
+
 #ifdef CONFIG_COMEDI_DEBUG
-	int i;
-	printk("comedi%d: usbduxfast: dux_commands: ",
-		this_usbduxfastsub->comedidev->minor);
-	for (i = 0; i < SIZEOFDUXBUFFER; i++) {
-		printk(" %02x", this_usbduxfastsub->dux_commands[i]);
-	}
+	printk(KERN_DEBUG "comedi%d: usbduxfast: dux_commands: ",
+		udfs->comedidev->minor);
+	for (tmp = 0; tmp < SIZEOFDUXBUFFER; tmp++)
+		printk(" %02x", udfs->dux_commands[tmp]);
 	printk("\n");
 #endif
-	result = usb_bulk_msg(this_usbduxfastsub->usbdev,
-			      usb_sndbulkpipe(this_usbduxfastsub->usbdev,
-					      CHANNELLISTEP),
-			      this_usbduxfastsub->dux_commands, SIZEOFDUXBUFFER,
-			      &nsent, 10000);
-	if (result < 0) {
-		printk("comedi%d: could not transmit dux_commands to the usb-device, err=%d\n", this_usbduxfastsub->comedidev->minor, result);
-	}
-	return result;
+
+	tmp = usb_bulk_msg(udfs->usbdev,
+			   usb_sndbulkpipe(udfs->usbdev, CHANNELLISTEP),
+			   udfs->dux_commands, SIZEOFDUXBUFFER, &nsent, 10000);
+	if (tmp < 0)
+		printk(KERN_ERR "comedi%d: could not transmit dux_commands to"
+		      "the usb-device, err=%d\n", udfs->comedidev->minor, tmp);
+	return tmp;
 }
 
-// Stops the data acquision
-// It should be safe to call this function from any context
-static int usbduxfastsub_unlink_InURBs(usbduxfastsub_t * usbduxfastsub_tmp)
+/*
+ * Stops the data acquision.
+ * It should be safe to call this function from any context.
+ */
+static int usbduxfastsub_unlink_InURBs(struct usbduxfastsub_s *udfs)
 {
 	int j = 0;
 	int err = 0;
 
-	if (usbduxfastsub_tmp && usbduxfastsub_tmp->urbIn) {
-		usbduxfastsub_tmp->ai_cmd_running = 0;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8)
-		j = usb_unlink_urb(usbduxfastsub_tmp->urbIn);
-		if (j < 0) {
-			err = j;
-		}
-#else
-		// waits until a running transfer is over
-		usb_kill_urb(usbduxfastsub_tmp->urbIn);
+	if (udfs && udfs->urbIn) {
+		udfs->ai_cmd_running = 0;
+		/* waits until a running transfer is over */
+		usb_kill_urb(udfs->urbIn);
 		j = 0;
-#endif
 	}
 #ifdef CONFIG_COMEDI_DEBUG
-	printk("comedi: usbduxfast: unlinked InURB: res=%d\n", j);
+	printk(KERN_DEBUG "comedi: usbduxfast: unlinked InURB: res=%d\n", j);
 #endif
 	return err;
 }
 
-/* This will stop a running acquisition operation */
-// Is called from within this driver from both the
-// interrupt context and from comedi
-static int usbduxfast_ai_stop(usbduxfastsub_t * this_usbduxfastsub,
+/*
+ * This will stop a running acquisition operation.
+ * Is called from within this driver from both the
+ * interrupt context and from comedi.
+ */
+static int usbduxfast_ai_stop(struct usbduxfastsub_s *udfs,
 	int do_unlink)
 {
 	int ret = 0;
 
-	if (!this_usbduxfastsub) {
-		printk("comedi?: usbduxfast_ai_stop: this_usbduxfastsub=NULL!\n");
+	if (!udfs) {
+		printk(KERN_ERR "comedi?: usbduxfast_ai_stop: udfs=NULL!\n");
 		return -EFAULT;
 	}
+
 #ifdef CONFIG_COMEDI_DEBUG
-	printk("comedi: usbduxfast_ai_stop\n");
+	printk(KERN_DEBUG "comedi: usbduxfast_ai_stop\n");
 #endif
 
-	this_usbduxfastsub->ai_cmd_running = 0;
+	udfs->ai_cmd_running = 0;
 
-	if (do_unlink) {
-		// stop aquistion
-		ret = usbduxfastsub_unlink_InURBs(this_usbduxfastsub);
-	}
+	if (do_unlink)
+		ret = usbduxfastsub_unlink_InURBs(udfs); /* stop aquistion */
 
 	return ret;
 }
 
-// This will cancel a running acquisition operation.
-// This is called by comedi but never from inside the
-// driver.
-static int usbduxfast_ai_cancel(comedi_device * dev, comedi_subdevice * s)
+/*
+ * This will cancel a running acquisition operation.
+ * This is called by comedi but never from inside the driver.
+ */
+static int usbduxfast_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 {
-	usbduxfastsub_t *this_usbduxfastsub;
-	int res = 0;
+	struct usbduxfastsub_s *udfs;
+	int ret;
 
-	// force unlink of all urbs
+	/* force unlink of all urbs */
 #ifdef CONFIG_COMEDI_DEBUG
-	printk("comedi: usbduxfast_ai_cancel\n");
+	printk(KERN_DEBUG "comedi: usbduxfast_ai_cancel\n");
 #endif
-	this_usbduxfastsub = dev->private;
-	if (!this_usbduxfastsub) {
-		printk("comedi: usbduxfast_ai_cancel: this_usbduxfastsub=NULL\n");
+	udfs = dev->private;
+	if (!udfs) {
+		printk(KERN_ERR "comedi: usbduxfast_ai_cancel: udfs=NULL\n");
 		return -EFAULT;
 	}
-	down(&this_usbduxfastsub->sem);
-	if (!(this_usbduxfastsub->probed)) {
-		up(&this_usbduxfastsub->sem);
+	down(&udfs->sem);
+	if (!udfs->probed) {
+		up(&udfs->sem);
 		return -ENODEV;
 	}
-	// unlink
-	res = usbduxfast_ai_stop(this_usbduxfastsub, 1);
-	up(&this_usbduxfastsub->sem);
+	/* unlink */
+	ret = usbduxfast_ai_stop(udfs, 1);
+	up(&udfs->sem);
 
-	return res;
+	return ret;
 }
 
-// analogue IN
-// interrupt service routine
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-static void usbduxfastsub_ai_Irq(struct urb *urb)
-#else
+/*
+ * analogue IN
+ * interrupt service routine
+ */
 static void usbduxfastsub_ai_Irq(struct urb *urb PT_REGS_ARG)
-#endif
 {
 	int n, err;
-	usbduxfastsub_t *this_usbduxfastsub;
-	comedi_device *this_comedidev;
-	comedi_subdevice *s;
+	struct usbduxfastsub_s *udfs;
+	struct comedi_device *this_comedidev;
+	struct comedi_subdevice *s;
 	uint16_t *p;
 
-	// sanity checks
-	// is the urb there?
+	/* sanity checks - is the urb there? */
 	if (!urb) {
-		printk("comedi_: usbduxfast_: ao int-handler called with urb=NULL!\n");
+		printk(KERN_ERR "comedi_: usbduxfast_: ao int-handler called "
+		       "with urb=NULL!\n");
 		return;
 	}
-	// the context variable points to the subdevice
+	/* the context variable points to the subdevice */
 	this_comedidev = urb->context;
 	if (!this_comedidev) {
-		printk("comedi_: usbduxfast_: urb context is a NULL pointer!\n");
+		printk(KERN_ERR "comedi_: usbduxfast_: urb context is a NULL "
+		       "pointer!\n");
 		return;
 	}
-	// the private structure of the subdevice is usbduxfastsub_t
-	this_usbduxfastsub = this_comedidev->private;
-	if (!this_usbduxfastsub) {
-		printk("comedi_: usbduxfast_: private of comedi subdev is a NULL pointer!\n");
+	/* the private structure of the subdevice is usbduxfastsub_s */
+	udfs = this_comedidev->private;
+	if (!udfs) {
+		printk(KERN_ERR "comedi_: usbduxfast_: private of comedi "
+		       "subdev is a NULL pointer!\n");
 		return;
 	}
-	// are we running a command?
-	if (unlikely(!(this_usbduxfastsub->ai_cmd_running))) {
-		// not running a command
-		// do not continue execution if no asynchronous command is running
-		// in particular not resubmit
+	/* are we running a command? */
+	if (unlikely(!udfs->ai_cmd_running)) {
+		/*
+		 * not running a command
+		 * do not continue execution if no asynchronous command
+		 * is running in particular not resubmit
+		 */
 		return;
 	}
 
-	if (unlikely(!(this_usbduxfastsub->attached))) {
-		// no comedi device there
+	if (unlikely(!udfs->attached)) {
+		/* no comedi device there */
 		return;
 	}
-	// subdevice which is the AD converter
+	/* subdevice which is the AD converter */
 	s = this_comedidev->subdevices + SUBDEV_AD;
 
-	// first we test if something unusual has just happened
+	/* first we test if something unusual has just happened */
 	switch (urb->status) {
 	case 0:
 		break;
 
-		// happens after an unlink command or when the device is plugged out
+		/*
+		 * happens after an unlink command or when the device
+		 * is plugged out
+		 */
 	case -ECONNRESET:
 	case -ENOENT:
 	case -ESHUTDOWN:
 	case -ECONNABORTED:
-		// tell this comedi
+		/* tell this comedi */
 		s->async->events |= COMEDI_CB_EOA;
 		s->async->events |= COMEDI_CB_ERROR;
-		comedi_event(this_usbduxfastsub->comedidev, s);
-		// stop the transfer w/o unlink
-		usbduxfast_ai_stop(this_usbduxfastsub, 0);
+		comedi_event(udfs->comedidev, s);
+		/* stop the transfer w/o unlink */
+		usbduxfast_ai_stop(udfs, 0);
 		return;
 
 	default:
-		printk("comedi%d: usbduxfast: non-zero urb status received in ai intr context: %d\n", this_usbduxfastsub->comedidev->minor, urb->status);
+		printk("comedi%d: usbduxfast: non-zero urb status received in "
+		       "ai intr context: %d\n",
+		       udfs->comedidev->minor, urb->status);
 		s->async->events |= COMEDI_CB_EOA;
 		s->async->events |= COMEDI_CB_ERROR;
-		comedi_event(this_usbduxfastsub->comedidev, s);
-		usbduxfast_ai_stop(this_usbduxfastsub, 0);
+		comedi_event(udfs->comedidev, s);
+		usbduxfast_ai_stop(udfs, 0);
 		return;
 	}
 
 	p = urb->transfer_buffer;
-	if (!this_usbduxfastsub->ignore) {
-		if (!(this_usbduxfastsub->ai_continous)) {
-			// not continous, fixed number of samples
+	if (!udfs->ignore) {
+		if (!udfs->ai_continous) {
+			/* not continous, fixed number of samples */
 			n = urb->actual_length / sizeof(uint16_t);
-			if (unlikely(this_usbduxfastsub->ai_sample_count < n)) {
-				// we have send only a fraction of the bytes received
+			if (unlikely(udfs->ai_sample_count < n)) {
+				/*
+				 * we have send only a fraction of the bytes
+				 * received
+				 */
 				cfc_write_array_to_buffer(s,
 					urb->transfer_buffer,
-					this_usbduxfastsub->ai_sample_count *
-					sizeof(uint16_t));
-				usbduxfast_ai_stop(this_usbduxfastsub, 0);
-				// say comedi that the acquistion is over
+					udfs->ai_sample_count
+					* sizeof(uint16_t));
+				usbduxfast_ai_stop(udfs, 0);
+				/* say comedi that the acquistion is over */
 				s->async->events |= COMEDI_CB_EOA;
-				comedi_event(this_usbduxfastsub->comedidev, s);
+				comedi_event(udfs->comedidev, s);
 				return;
 			}
-			this_usbduxfastsub->ai_sample_count -= n;
+			udfs->ai_sample_count -= n;
 		}
-		// write the full buffer to comedi
-		cfc_write_array_to_buffer(s,
-			urb->transfer_buffer, urb->actual_length);
+		/* write the full buffer to comedi */
+		cfc_write_array_to_buffer(s, urb->transfer_buffer,
+					  urb->actual_length);
 
-		// tell comedi that data is there
-		comedi_event(this_usbduxfastsub->comedidev, s);
+		/* tell comedi that data is there */
+		comedi_event(udfs->comedidev, s);
 
 	} else {
-		// ignore this packet
-		this_usbduxfastsub->ignore--;
+		/* ignore this packet */
+		udfs->ignore--;
 	}
 
-	// command is still running
-	// resubmit urb for BULK transfer
-	urb->dev = this_usbduxfastsub->usbdev;
+	/*
+	 * command is still running
+	 * resubmit urb for BULK transfer
+	 */
+	urb->dev = udfs->usbdev;
 	urb->status = 0;
 	err = usb_submit_urb(urb, GFP_ATOMIC);
 	if (err < 0) {
-		printk("comedi%d: usbduxfast: urb resubm failed: %d",
-			this_usbduxfastsub->comedidev->minor, err);
+		printk(KERN_ERR "comedi%d: usbduxfast: urb resubm failed: %d",
+			udfs->comedidev->minor, err);
 		s->async->events |= COMEDI_CB_EOA;
 		s->async->events |= COMEDI_CB_ERROR;
-		comedi_event(this_usbduxfastsub->comedidev, s);
-		usbduxfast_ai_stop(this_usbduxfastsub, 0);
+		comedi_event(udfs->comedidev, s);
+		usbduxfast_ai_stop(udfs, 0);
 	}
 }
 
-static int usbduxfastsub_start(usbduxfastsub_t * usbduxfastsub)
+static int usbduxfastsub_start(struct usbduxfastsub_s *udfs)
 {
-	int errcode = 0;
+	int ret;
 	unsigned char local_transfer_buffer[16];
 
-	if (usbduxfastsub->probed) {
-		// 7f92 to zero
-		local_transfer_buffer[0] = 0;
-		errcode = usb_control_msg(usbduxfastsub->usbdev,
-			// create a pipe for a control transfer
-			usb_sndctrlpipe(usbduxfastsub->usbdev, 0),
-			// bRequest, "Firmware"
-			USBDUXFASTSUB_FIRMWARE,
-			// bmRequestType
-			VENDOR_DIR_OUT,
-			// Value
-			USBDUXFASTSUB_CPUCS,
-			// Index
-			0x0000,
-			// address of the transfer buffer
-			local_transfer_buffer,
-			// Length
-			1,
-			// Timeout
-			EZTIMEOUT);
-		if (errcode < 0) {
-			printk("comedi_: usbduxfast_: control msg failed (start)\n");
-			return errcode;
-		}
+	/* 7f92 to zero */
+	local_transfer_buffer[0] = 0;
+	ret = usb_control_msg(udfs->usbdev,
+		usb_sndctrlpipe(udfs->usbdev, 0),
+		USBDUXFASTSUB_FIRMWARE,	/* bRequest, "Firmware" */
+		VENDOR_DIR_OUT,		/* bmRequestType */
+		USBDUXFASTSUB_CPUCS,	/* Value */
+		0x0000,			/* Index */
+		local_transfer_buffer,	/* address of the transfer buffer */
+		1,			/* Length */
+		EZTIMEOUT);		/* Timeout */
+	if (ret < 0) {
+		printk("comedi_: usbduxfast_: control msg failed (start)\n");
+		return ret;
 	}
+
 	return 0;
 }
 
-static int usbduxfastsub_stop(usbduxfastsub_t * usbduxfastsub)
+static int usbduxfastsub_stop(struct usbduxfastsub_s *udfs)
 {
-	int errcode = 0;
-
+	int ret;
 	unsigned char local_transfer_buffer[16];
-	if (usbduxfastsub->probed) {
-		// 7f92 to one
-		local_transfer_buffer[0] = 1;
-		errcode = usb_control_msg(usbduxfastsub->usbdev,
-			usb_sndctrlpipe(usbduxfastsub->usbdev, 0),
-			// bRequest, "Firmware"
-			USBDUXFASTSUB_FIRMWARE,
-			// bmRequestType
-			VENDOR_DIR_OUT,
-			// Value
-			USBDUXFASTSUB_CPUCS,
-			// Index
-			0x0000, local_transfer_buffer,
-			// Length
-			1,
-			// Timeout
-			EZTIMEOUT);
-		if (errcode < 0) {
-			printk("comedi_: usbduxfast: control msg failed (stop)\n");
-			return errcode;
-		}
+
+	/* 7f92 to one */
+	local_transfer_buffer[0] = 1;
+	ret = usb_control_msg(udfs->usbdev,
+		usb_sndctrlpipe(udfs->usbdev, 0),
+		USBDUXFASTSUB_FIRMWARE,	/* bRequest, "Firmware" */
+		VENDOR_DIR_OUT,		/* bmRequestType */
+		USBDUXFASTSUB_CPUCS,	/* Value */
+		0x0000,			/* Index */
+		local_transfer_buffer,
+		1,			/* Length */
+		EZTIMEOUT);		/* Timeout */
+	if (ret < 0) {
+		printk(KERN_ERR "comedi_: usbduxfast: control msg failed "
+		       "(stop)\n");
+		return ret;
 	}
+
 	return 0;
 }
 
-static int usbduxfastsub_upload(usbduxfastsub_t * usbduxfastsub,
+static int usbduxfastsub_upload(struct usbduxfastsub_s *udfs,
 	unsigned char *local_transfer_buffer,
 	unsigned int startAddr, unsigned int len)
 {
-	int errcode;
+	int ret;
 
-	if (usbduxfastsub->probed) {
 #ifdef CONFIG_COMEDI_DEBUG
-		printk("comedi%d: usbduxfast: uploading %d bytes",
-			usbduxfastsub->comedidev->minor, len);
-		printk(" to addr %d, first byte=%d.\n",
-			startAddr, local_transfer_buffer[0]);
+	printk(KERN_DEBUG "comedi: usbduxfast: uploading %d bytes", len);
+	printk(KERN_DEBUG " to addr %d, first byte=%d.\n",
+		startAddr, local_transfer_buffer[0]);
 #endif
-		errcode = usb_control_msg(usbduxfastsub->usbdev,
-			usb_sndctrlpipe(usbduxfastsub->usbdev, 0),
-			// brequest, firmware
-			USBDUXFASTSUB_FIRMWARE,
-			// bmRequestType
-			VENDOR_DIR_OUT,
-			// value
-			startAddr,
-			// index
-			0x0000,
-			// our local safe buffer
-			local_transfer_buffer,
-			// length
-			len,
-			// timeout
-			EZTIMEOUT);
+	ret = usb_control_msg(udfs->usbdev,
+		usb_sndctrlpipe(udfs->usbdev, 0),
+		USBDUXFASTSUB_FIRMWARE, /* brequest, firmware */
+		VENDOR_DIR_OUT,		/* bmRequestType */
+		startAddr,		/* value */
+		0x0000,			/* index */
+		local_transfer_buffer,	/* our local safe buffer */
+		len,			/* length */
+		EZTIMEOUT);		/* timeout */
+
 #ifdef CONFIG_COMEDI_DEBUG
-		printk("comedi_: usbduxfast: result=%d\n", errcode);
+	printk(KERN_DEBUG "comedi_: usbduxfast: result=%d\n", ret);
 #endif
-		if (errcode < 0) {
-			printk("comedi_: usbduxfast: uppload failed\n");
-			return errcode;
-		}
-	} else {
-		// no device on the bus for this index
-		return -EFAULT;
+
+	if (ret < 0) {
+		printk(KERN_ERR "comedi_: usbduxfast: uppload failed\n");
+		return ret;
 	}
+
 	return 0;
 }
 
-int firmwareUpload(usbduxfastsub_t * usbduxfastsub,
-	unsigned char *firmwareBinary, int sizeFirmware)
+int firmwareUpload(struct usbduxfastsub_s *udfs, unsigned char *firmwareBinary,
+		   int sizeFirmware)
 {
 	int ret;
 
-	if (!firmwareBinary) {
+	if (!firmwareBinary)
 		return 0;
-	}
-	ret = usbduxfastsub_stop(usbduxfastsub);
+
+	ret = usbduxfastsub_stop(udfs);
 	if (ret < 0) {
-		printk("comedi_: usbduxfast: can not stop firmware\n");
+		printk(KERN_ERR "comedi_: usbduxfast: can not stop firmware\n");
 		return ret;
 	}
-	ret = usbduxfastsub_upload(usbduxfastsub,
-		firmwareBinary, 0, sizeFirmware);
+	ret = usbduxfastsub_upload(udfs, firmwareBinary, 0, sizeFirmware);
 	if (ret < 0) {
-		printk("comedi_: usbduxfast: firmware upload failed\n");
+		printk(KERN_ERR "comedi_: usbduxfast: firmware upload failed\n");
 		return ret;
 	}
-	ret = usbduxfastsub_start(usbduxfastsub);
+	ret = usbduxfastsub_start(udfs);
 	if (ret < 0) {
-		printk("comedi_: usbduxfast: can not start firmware\n");
+		printk(KERN_ERR "comedi_: usbduxfast: can not start firmware\n");
 		return ret;
 	}
+
 	return 0;
 }
 
-int usbduxfastsub_submit_InURBs(usbduxfastsub_t * usbduxfastsub)
+int usbduxfastsub_submit_InURBs(struct usbduxfastsub_s *udfs)
 {
-	int errFlag;
+	int ret;
 
-	if (!usbduxfastsub) {
+	if (!udfs)
 		return -EFAULT;
-	}
-	usb_fill_bulk_urb(usbduxfastsub->urbIn,
-		usbduxfastsub->usbdev,
-		usb_rcvbulkpipe(usbduxfastsub->usbdev, BULKINEP),
-		usbduxfastsub->transfer_buffer,
-		SIZEINBUF, usbduxfastsub_ai_Irq, usbduxfastsub->comedidev);
+
+	usb_fill_bulk_urb(udfs->urbIn, udfs->usbdev,
+			  usb_rcvbulkpipe(udfs->usbdev, BULKINEP),
+			  udfs->transfer_buffer,
+			  SIZEINBUF, usbduxfastsub_ai_Irq, udfs->comedidev);
 
 #ifdef CONFIG_COMEDI_DEBUG
-	printk("comedi%d: usbduxfast: submitting in-urb: %x,%x\n",
-		usbduxfastsub->comedidev->minor,
-		(int)(usbduxfastsub->urbIn->context),
-		(int)(usbduxfastsub->urbIn->dev));
+	printk(KERN_DEBUG "comedi%d: usbduxfast: submitting in-urb: "
+	       "0x%p,0x%p\n", udfs->comedidev->minor, udfs->urbIn->context,
+		udfs->urbIn->dev);
 #endif
-	errFlag = usb_submit_urb(usbduxfastsub->urbIn, GFP_ATOMIC);
-	if (errFlag) {
-		printk("comedi_: usbduxfast: ai: usb_submit_urb error %d\n",
-			errFlag);
-		return errFlag;
+	ret = usb_submit_urb(udfs->urbIn, GFP_ATOMIC);
+	if (ret) {
+		printk(KERN_ERR "comedi_: usbduxfast: ai: usb_submit_urb error"
+		       " %d\n", ret);
+		return ret;
 	}
 	return 0;
 }
 
-static int usbduxfast_ai_cmdtest(comedi_device * dev,
-	comedi_subdevice * s, comedi_cmd * cmd)
+static int usbduxfast_ai_cmdtest(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	int err = 0, stop_mask = 0;
-	long int steps, tmp = 0;
+	long int steps, tmp;
 	int minSamplPer;
-	usbduxfastsub_t *this_usbduxfastsub = dev->private;
-	if (!(this_usbduxfastsub->probed)) {
+	struct usbduxfastsub_s *udfs = dev->private;
+
+	if (!udfs->probed)
 		return -ENODEV;
-	}
+
 #ifdef CONFIG_COMEDI_DEBUG
-	printk("comedi%d: usbduxfast_ai_cmdtest\n", dev->minor);
-	printk("comedi%d: usbduxfast: convert_arg=%u scan_begin_arg=%u\n",
-		dev->minor, cmd->convert_arg, cmd->scan_begin_arg);
+	printk(KERN_DEBUG "comedi%d: usbduxfast_ai_cmdtest\n", dev->minor);
+	printk(KERN_DEBUG "comedi%d: usbduxfast: convert_arg=%u "
+	       "scan_begin_arg=%u\n",
+	       dev->minor, cmd->convert_arg, cmd->scan_begin_arg);
 #endif
 	/* step 1: make sure trigger sources are trivially valid */
 
@@ -621,7 +625,9 @@
 	if (err)
 		return 1;
 
-	/* step 2: make sure trigger sources are unique and mutually compatible */
+	/*
+	 * step 2: make sure trigger sources are unique and mutually compatible
+	 */
 
 	if (cmd->start_src != TRIG_NOW &&
 		cmd->start_src != TRIG_EXT && cmd->start_src != TRIG_INT)
@@ -636,7 +642,7 @@
 		cmd->stop_src != TRIG_EXT && cmd->stop_src != TRIG_NONE)
 		err++;
 
-	// can't have external stop and start triggers at once
+	/* can't have external stop and start triggers at once */
 	if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT)
 		err++;
 
@@ -650,29 +656,28 @@
 		err++;
 	}
 
-	if (!cmd->chanlist_len) {
+	if (!cmd->chanlist_len)
 		err++;
-	}
+
 	if (cmd->scan_end_arg != cmd->chanlist_len) {
 		cmd->scan_end_arg = cmd->chanlist_len;
 		err++;
 	}
 
-	if (cmd->chanlist_len == 1) {
+	if (cmd->chanlist_len == 1)
 		minSamplPer = 1;
-	} else {
+	else
 		minSamplPer = MIN_SAMPLING_PERIOD;
-	}
 
 	if (cmd->convert_src == TRIG_TIMER) {
 		steps = cmd->convert_arg * 30;
-		if (steps < (minSamplPer * 1000)) {
+		if (steps < (minSamplPer * 1000))
 			steps = minSamplPer * 1000;
-		}
-		if (steps > (MAX_SAMPLING_PERIOD * 1000)) {
+
+		if (steps > (MAX_SAMPLING_PERIOD * 1000))
 			steps = MAX_SAMPLING_PERIOD * 1000;
-		}
-		// calc arg again
+
+		/* calc arg again */
 		tmp = steps / 30;
 		if (cmd->convert_arg != tmp) {
 			cmd->convert_arg = tmp;
@@ -680,10 +685,10 @@
 		}
 	}
 
-	if (cmd->scan_begin_src == TRIG_TIMER) {
+	if (cmd->scan_begin_src == TRIG_TIMER)
 		err++;
-	}
-	// stop source
+
+	/* stop source */
 	switch (cmd->stop_src) {
 	case TRIG_COUNT:
 		if (!cmd->stop_arg) {
@@ -697,7 +702,10 @@
 			err++;
 		}
 		break;
-		// TRIG_EXT doesn't care since it doesn't trigger off a numbered channel
+		/*
+		 * TRIG_EXT doesn't care since it doesn't trigger
+		 * off a numbered channel
+		 */
 	default:
 		break;
 	}
@@ -711,600 +719,688 @@
 
 }
 
-static int usbduxfast_ai_inttrig(comedi_device * dev,
-	comedi_subdevice * s, unsigned int trignum)
+static int usbduxfast_ai_inttrig(struct comedi_device *dev,
+	struct comedi_subdevice *s, unsigned int trignum)
 {
 	int ret;
-	usbduxfastsub_t *this_usbduxfastsub = dev->private;
-	if (!this_usbduxfastsub) {
+	struct usbduxfastsub_s *udfs = dev->private;
+
+	if (!udfs)
 		return -EFAULT;
-	}
-	down(&this_usbduxfastsub->sem);
-	if (!(this_usbduxfastsub->probed)) {
-		up(&this_usbduxfastsub->sem);
+
+	down(&udfs->sem);
+	if (!udfs->probed) {
+		up(&udfs->sem);
 		return -ENODEV;
 	}
 #ifdef CONFIG_COMEDI_DEBUG
-	printk("comedi%d: usbduxfast_ai_inttrig\n", dev->minor);
+	printk(KERN_DEBUG "comedi%d: usbduxfast_ai_inttrig\n", dev->minor);
 #endif
 
 	if (trignum != 0) {
-		printk("comedi%d: usbduxfast_ai_inttrig: invalid trignum\n",
-			dev->minor);
-		up(&this_usbduxfastsub->sem);
+		printk(KERN_ERR "comedi%d: usbduxfast_ai_inttrig: invalid"
+		       " trignum\n", dev->minor);
+		up(&udfs->sem);
 		return -EINVAL;
 	}
-	if (!(this_usbduxfastsub->ai_cmd_running)) {
-		this_usbduxfastsub->ai_cmd_running = 1;
-		ret = usbduxfastsub_submit_InURBs(this_usbduxfastsub);
+	if (!udfs->ai_cmd_running) {
+		udfs->ai_cmd_running = 1;
+		ret = usbduxfastsub_submit_InURBs(udfs);
 		if (ret < 0) {
-			printk("comedi%d: usbduxfast_ai_inttrig: urbSubmit: err=%d\n", dev->minor, ret);
-			this_usbduxfastsub->ai_cmd_running = 0;
-			up(&this_usbduxfastsub->sem);
+			printk(KERN_ERR "comedi%d: usbduxfast_ai_inttrig: "
+			       "urbSubmit: err=%d\n", dev->minor, ret);
+			udfs->ai_cmd_running = 0;
+			up(&udfs->sem);
 			return ret;
 		}
 		s->async->inttrig = NULL;
 	} else {
-		printk("comedi%d: ai_inttrig but acqu is already running\n",
-			dev->minor);
+		printk(KERN_ERR "comedi%d: ai_inttrig but acqu is already"
+		       " running\n", dev->minor);
 	}
-	up(&this_usbduxfastsub->sem);
+	up(&udfs->sem);
 	return 1;
 }
 
-// offsets for the GPIF bytes
-// the first byte is the command byte
-#define LENBASE 1+0x00
-#define OPBASE  1+0x08
-#define OUTBASE 1+0x10
-#define LOGBASE 1+0x18
+/*
+ * offsets for the GPIF bytes
+ * the first byte is the command byte
+ */
+#define LENBASE	(1+0x00)
+#define OPBASE	(1+0x08)
+#define OUTBASE	(1+0x10)
+#define LOGBASE	(1+0x18)
 
-static int usbduxfast_ai_cmd(comedi_device * dev, comedi_subdevice * s)
+static int usbduxfast_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
-	comedi_cmd *cmd = &s->async->cmd;
+	struct comedi_cmd *cmd = &s->async->cmd;
 	unsigned int chan, gain, rngmask = 0xff;
 	int i, j, ret;
-	usbduxfastsub_t *this_usbduxfastsub = dev->private;
+	struct usbduxfastsub_s *udfs;
 	int result;
 	long steps, steps_tmp;
 
 #ifdef CONFIG_COMEDI_DEBUG
-	printk("comedi%d: usbduxfast_ai_cmd\n", dev->minor);
+	printk(KERN_DEBUG "comedi%d: usbduxfast_ai_cmd\n", dev->minor);
 #endif
-	if (!this_usbduxfastsub) {
+	udfs = dev->private;
+	if (!udfs)
 		return -EFAULT;
-	}
-	down(&this_usbduxfastsub->sem);
-	if (!(this_usbduxfastsub->probed)) {
-		up(&this_usbduxfastsub->sem);
+
+	down(&udfs->sem);
+	if (!udfs->probed) {
+		up(&udfs->sem);
 		return -ENODEV;
 	}
-	if (this_usbduxfastsub->ai_cmd_running) {
-		printk("comedi%d: ai_cmd not possible. Another ai_cmd is running.\n", dev->minor);
-		up(&this_usbduxfastsub->sem);
+	if (udfs->ai_cmd_running) {
+		printk(KERN_ERR "comedi%d: ai_cmd not possible. Another ai_cmd"
+		       " is running.\n", dev->minor);
+		up(&udfs->sem);
 		return -EBUSY;
 	}
-	// set current channel of the running aquisition to zero
+	/* set current channel of the running aquisition to zero */
 	s->async->cur_chan = 0;
 
-	// ignore the first buffers from the device if there is an error condition
-	this_usbduxfastsub->ignore = PACKETS_TO_IGNORE;
+	/*
+	 * ignore the first buffers from the device if there
+	 * is an error condition
+	 */
+	udfs->ignore = PACKETS_TO_IGNORE;
 
 	if (cmd->chanlist_len > 0) {
 		gain = CR_RANGE(cmd->chanlist[0]);
 		for (i = 0; i < cmd->chanlist_len; ++i) {
 			chan = CR_CHAN(cmd->chanlist[i]);
 			if (chan != i) {
-				printk("comedi%d: cmd is accepting only consecutive channels.\n", dev->minor);
-				up(&this_usbduxfastsub->sem);
+				printk(KERN_ERR "comedi%d: cmd is accepting "
+				       "only consecutive channels.\n",
+				       dev->minor);
+				up(&udfs->sem);
 				return -EINVAL;
 			}
 			if ((gain != CR_RANGE(cmd->chanlist[i]))
 				&& (cmd->chanlist_len > 3)) {
-				printk("comedi%d: the gain must be the same for all channels.\n", dev->minor);
-				up(&this_usbduxfastsub->sem);
+				printk(KERN_ERR "comedi%d: the gain must be"
+				       " the same for all channels.\n",
+				       dev->minor);
+				up(&udfs->sem);
 				return -EINVAL;
 			}
 			if (i >= NUMCHANNELS) {
-				printk("comedi%d: channel list too long\n",
-					dev->minor);
+				printk(KERN_ERR "comedi%d: channel list too"
+				       " long\n", dev->minor);
 				break;
 			}
 		}
 	}
 	steps = 0;
 	if (cmd->scan_begin_src == TRIG_TIMER) {
-		printk("comedi%d: usbduxfast: scan_begin_src==TRIG_TIMER not valid.\n", dev->minor);
-		up(&this_usbduxfastsub->sem);
+		printk(KERN_ERR "comedi%d: usbduxfast: "
+		       "scan_begin_src==TRIG_TIMER not valid.\n", dev->minor);
+		up(&udfs->sem);
 		return -EINVAL;
 	}
-	if (cmd->convert_src == TRIG_TIMER) {
+	if (cmd->convert_src == TRIG_TIMER)
 		steps = (cmd->convert_arg * 30) / 1000;
-	}
+
 	if ((steps < MIN_SAMPLING_PERIOD) && (cmd->chanlist_len != 1)) {
-		printk("comedi%d: usbduxfast: ai_cmd: steps=%ld, scan_begin_arg=%d. Not properly tested by cmdtest?\n", dev->minor, steps, cmd->scan_begin_arg);
-		up(&this_usbduxfastsub->sem);
+		printk(KERN_ERR "comedi%d: usbduxfast: ai_cmd: steps=%ld, "
+		       "scan_begin_arg=%d. Not properly tested by cmdtest?\n",
+		       dev->minor, steps, cmd->scan_begin_arg);
+		up(&udfs->sem);
 		return -EINVAL;
 	}
 	if (steps > MAX_SAMPLING_PERIOD) {
-		printk("comedi%d: usbduxfast: ai_cmd: sampling rate too low.\n",
-			dev->minor);
-		up(&this_usbduxfastsub->sem);
+		printk(KERN_ERR "comedi%d: usbduxfast: ai_cmd: sampling rate "
+		       "too low.\n", dev->minor);
+		up(&udfs->sem);
 		return -EINVAL;
 	}
 	if ((cmd->start_src == TRIG_EXT) && (cmd->chanlist_len != 1)
 		&& (cmd->chanlist_len != 16)) {
-		printk("comedi%d: usbduxfast: ai_cmd: TRIG_EXT only with 1 or 16 channels possible.\n", dev->minor);
-		up(&this_usbduxfastsub->sem);
+		printk(KERN_ERR "comedi%d: usbduxfast: ai_cmd: TRIG_EXT only"
+		       " with 1 or 16 channels possible.\n", dev->minor);
+		up(&udfs->sem);
 		return -EINVAL;
 	}
 #ifdef CONFIG_COMEDI_DEBUG
-	printk("comedi%d: usbduxfast: steps=%ld, convert_arg=%u, ai_timer=%u\n",
-		dev->minor,
-		steps, cmd->convert_arg, this_usbduxfastsub->ai_timer);
+	printk(KERN_DEBUG "comedi%d: usbduxfast: steps=%ld, convert_arg=%u\n",
+	       dev->minor, steps, cmd->convert_arg);
 #endif
 
 	switch (cmd->chanlist_len) {
-		// one channel
 	case 1:
+		/*
+		 * one channel
+		 */
+
 		if (CR_RANGE(cmd->chanlist[0]) > 0)
 			rngmask = 0xff - 0x04;
 		else
 			rngmask = 0xff;
 
-		// for external trigger: looping in this state until the RDY0 pin
-		// becomes zero
-		if (cmd->start_src == TRIG_EXT) {	// we loop here until ready has been set
-			this_usbduxfastsub->dux_commands[LENBASE + 0] = 0x01;	// branch back to state 0
-			this_usbduxfastsub->dux_commands[OPBASE + 0] = 0x01;	// deceision state w/o data
-			this_usbduxfastsub->dux_commands[OUTBASE + 0] =
-				0xFF & rngmask;
-			this_usbduxfastsub->dux_commands[LOGBASE + 0] = 0x00;	// RDY0 = 0
-		} else {	// we just proceed to state 1
-			this_usbduxfastsub->dux_commands[LENBASE + 0] = 1;
-			this_usbduxfastsub->dux_commands[OPBASE + 0] = 0;
-			this_usbduxfastsub->dux_commands[OUTBASE + 0] =
-				0xFF & rngmask;
-			this_usbduxfastsub->dux_commands[LOGBASE + 0] = 0;
+		/*
+		 * for external trigger: looping in this state until
+		 * the RDY0 pin becomes zero
+		 */
+
+		/* we loop here until ready has been set */
+		if (cmd->start_src == TRIG_EXT) {
+			/* branch back to state 0 */
+			udfs->dux_commands[LENBASE+0] = 0x01;
+			/* deceision state w/o data */
+			udfs->dux_commands[OPBASE+0] = 0x01;
+			udfs->dux_commands[OUTBASE+0] = 0xFF & rngmask;
+			/* RDY0 = 0 */
+			udfs->dux_commands[LOGBASE+0] = 0x00;
+		} else {	/* we just proceed to state 1 */
+			udfs->dux_commands[LENBASE+0] = 1;
+			udfs->dux_commands[OPBASE+0] = 0;
+			udfs->dux_commands[OUTBASE+0] = 0xFF & rngmask;
+			udfs->dux_commands[LOGBASE+0] = 0;
 		}
 
 		if (steps < MIN_SAMPLING_PERIOD) {
-			// for fast single channel aqu without mux
+			/* for fast single channel aqu without mux */
 			if (steps <= 1) {
-				// we just stay here at state 1 and rexecute the same state
-				// this gives us 30MHz sampling rate
-				this_usbduxfastsub->dux_commands[LENBASE + 1] = 0x89;	// branch back to state 1
-				this_usbduxfastsub->dux_commands[OPBASE + 1] = 0x03;	// deceision state with data
-				this_usbduxfastsub->dux_commands[OUTBASE + 1] =
-					0xFF & rngmask;
-				this_usbduxfastsub->dux_commands[LOGBASE + 1] = 0xFF;	// doesn't matter
-			} else {
-				// we loop through two states: data and delay: max rate is 15Mhz
-				this_usbduxfastsub->dux_commands[LENBASE + 1] =
-					steps - 1;
-				this_usbduxfastsub->dux_commands[OPBASE + 1] = 0x02;	// data
-				this_usbduxfastsub->dux_commands[OUTBASE + 1] =
-					0xFF & rngmask;
-				this_usbduxfastsub->dux_commands[LOGBASE + 1] = 0;	// doesn't matter
+				/*
+				 * we just stay here at state 1 and rexecute
+				 * the same state this gives us 30MHz sampling
+				 * rate
+				 */
 
-				this_usbduxfastsub->dux_commands[LENBASE + 2] = 0x09;	// branch back to state 1
-				this_usbduxfastsub->dux_commands[OPBASE + 2] = 0x01;	// deceision state w/o data
-				this_usbduxfastsub->dux_commands[OUTBASE + 2] =
-					0xFF & rngmask;
-				this_usbduxfastsub->dux_commands[LOGBASE + 2] = 0xFF;	// doesn't matter
+				/* branch back to state 1 */
+				udfs->dux_commands[LENBASE+1] = 0x89;
+				/* deceision state with data */
+				udfs->dux_commands[OPBASE+1] = 0x03;
+				udfs->dux_commands[OUTBASE+1] = 0xFF & rngmask;
+				/* doesn't matter */
+				udfs->dux_commands[LOGBASE+1] = 0xFF;
+			} else {
+				/*
+				 * we loop through two states: data and delay
+				 * max rate is 15MHz
+				 */
+				udfs->dux_commands[LENBASE+1] = steps - 1;
+				/* data */
+				udfs->dux_commands[OPBASE+1] = 0x02;
+				udfs->dux_commands[OUTBASE+1] = 0xFF & rngmask;
+				/* doesn't matter */
+				udfs->dux_commands[LOGBASE+1] = 0;
+				/* branch back to state 1 */
+				udfs->dux_commands[LENBASE+2] = 0x09;
+				/* deceision state w/o data */
+				udfs->dux_commands[OPBASE+2] = 0x01;
+				udfs->dux_commands[OUTBASE+2] = 0xFF & rngmask;
+				/* doesn't matter */
+				udfs->dux_commands[LOGBASE+2] = 0xFF;
 			}
 		} else {
-			// we loop through 3 states: 2x delay and 1x data. This gives a min
-			// sampling rate of 60kHz.
+			/*
+			 * we loop through 3 states: 2x delay and 1x data
+			 * this gives a min sampling rate of 60kHz
+			 */
 
-			// we have 1 state with duration 1
+			/* we have 1 state with duration 1 */
 			steps = steps - 1;
 
-			// do the first part of the delay
-			this_usbduxfastsub->dux_commands[LENBASE + 1] =
-				steps / 2;
-			this_usbduxfastsub->dux_commands[OPBASE + 1] = 0;
-			this_usbduxfastsub->dux_commands[OUTBASE + 1] =
-				0xFF & rngmask;
-			this_usbduxfastsub->dux_commands[LOGBASE + 1] = 0;
+			/* do the first part of the delay */
+			udfs->dux_commands[LENBASE+1] = steps / 2;
+			udfs->dux_commands[OPBASE+1] = 0;
+			udfs->dux_commands[OUTBASE+1] = 0xFF & rngmask;
+			udfs->dux_commands[LOGBASE+1] = 0;
 
-			// and the second part
-			this_usbduxfastsub->dux_commands[LENBASE + 2] =
-				steps - steps / 2;
-			this_usbduxfastsub->dux_commands[OPBASE + 2] = 0;
-			this_usbduxfastsub->dux_commands[OUTBASE + 2] =
-				0xFF & rngmask;
-			this_usbduxfastsub->dux_commands[LOGBASE + 2] = 0;
+			/* and the second part */
+			udfs->dux_commands[LENBASE+2] = steps - steps / 2;
+			udfs->dux_commands[OPBASE+2] = 0;
+			udfs->dux_commands[OUTBASE+2] = 0xFF & rngmask;
+			udfs->dux_commands[LOGBASE+2] = 0;
 
-			// get the data and branch back
-			this_usbduxfastsub->dux_commands[LENBASE + 3] = 0x09;	// branch back to state 1
-			this_usbduxfastsub->dux_commands[OPBASE + 3] = 0x03;	// deceision state w data
-			this_usbduxfastsub->dux_commands[OUTBASE + 3] =
-				0xFF & rngmask;
-			this_usbduxfastsub->dux_commands[LOGBASE + 3] = 0xFF;	// doesn't matter
+			/* get the data and branch back */
+
+			/* branch back to state 1 */
+			udfs->dux_commands[LENBASE+3] = 0x09;
+			/* deceision state w data */
+			udfs->dux_commands[OPBASE+3] = 0x03;
+			udfs->dux_commands[OUTBASE+3] = 0xFF & rngmask;
+			/* doesn't matter */
+			udfs->dux_commands[LOGBASE+3] = 0xFF;
 		}
 		break;
 
 	case 2:
-		// two channels
-		// commit data to the FIFO
+		/*
+		 * two channels
+		 * commit data to the FIFO
+		 */
+
 		if (CR_RANGE(cmd->chanlist[0]) > 0)
 			rngmask = 0xff - 0x04;
 		else
 			rngmask = 0xff;
-		this_usbduxfastsub->dux_commands[LENBASE + 0] = 1;
-		this_usbduxfastsub->dux_commands[OPBASE + 0] = 0x02;	// data
-		this_usbduxfastsub->dux_commands[OUTBASE + 0] = 0xFF & rngmask;
-		this_usbduxfastsub->dux_commands[LOGBASE + 0] = 0;
 
-		// we have 1 state with duration 1: state 0
+		udfs->dux_commands[LENBASE+0] = 1;
+		/* data */
+		udfs->dux_commands[OPBASE+0] = 0x02;
+		udfs->dux_commands[OUTBASE+0] = 0xFF & rngmask;
+		udfs->dux_commands[LOGBASE+0] = 0;
+
+		/* we have 1 state with duration 1: state 0 */
 		steps_tmp = steps - 1;
 
 		if (CR_RANGE(cmd->chanlist[1]) > 0)
 			rngmask = 0xff - 0x04;
 		else
 			rngmask = 0xff;
-		// do the first part of the delay
-		this_usbduxfastsub->dux_commands[LENBASE + 1] = steps_tmp / 2;
-		this_usbduxfastsub->dux_commands[OPBASE + 1] = 0;
-		this_usbduxfastsub->dux_commands[OUTBASE + 1] = 0xFE & rngmask;	//count
-		this_usbduxfastsub->dux_commands[LOGBASE + 1] = 0;
 
-		// and the second part
-		this_usbduxfastsub->dux_commands[LENBASE + 2] =
-			steps_tmp - steps_tmp / 2;
-		this_usbduxfastsub->dux_commands[OPBASE + 2] = 0;
-		this_usbduxfastsub->dux_commands[OUTBASE + 2] = 0xFF & rngmask;
-		this_usbduxfastsub->dux_commands[LOGBASE + 2] = 0;
+		/* do the first part of the delay */
+		udfs->dux_commands[LENBASE+1] = steps_tmp / 2;
+		udfs->dux_commands[OPBASE+1] = 0;
+		/* count */
+		udfs->dux_commands[OUTBASE+1] = 0xFE & rngmask;
+		udfs->dux_commands[LOGBASE+1] = 0;
 
-		this_usbduxfastsub->dux_commands[LENBASE + 3] = 1;
-		this_usbduxfastsub->dux_commands[OPBASE + 3] = 0x02;	// data
-		this_usbduxfastsub->dux_commands[OUTBASE + 3] = 0xFF & rngmask;
-		this_usbduxfastsub->dux_commands[LOGBASE + 3] = 0;
+		/* and the second part */
+		udfs->dux_commands[LENBASE+2] = steps_tmp - steps_tmp / 2;
+		udfs->dux_commands[OPBASE+2] = 0;
+		udfs->dux_commands[OUTBASE+2] = 0xFF & rngmask;
+		udfs->dux_commands[LOGBASE+2] = 0;
 
-		// we have 2 states with duration 1: step 6 and the IDLE state
+		udfs->dux_commands[LENBASE+3] = 1;
+		/* data */
+		udfs->dux_commands[OPBASE+3] = 0x02;
+		udfs->dux_commands[OUTBASE+3] = 0xFF & rngmask;
+		udfs->dux_commands[LOGBASE+3] = 0;
+
+		/*
+		 * we have 2 states with duration 1: step 6 and
+		 * the IDLE state
+		 */
 		steps_tmp = steps - 2;
 
 		if (CR_RANGE(cmd->chanlist[0]) > 0)
 			rngmask = 0xff - 0x04;
 		else
 			rngmask = 0xff;
-		// do the first part of the delay
-		this_usbduxfastsub->dux_commands[LENBASE + 4] = steps_tmp / 2;
-		this_usbduxfastsub->dux_commands[OPBASE + 4] = 0;
-		this_usbduxfastsub->dux_commands[OUTBASE + 4] = (0xFF - 0x02) & rngmask;	//reset
-		this_usbduxfastsub->dux_commands[LOGBASE + 4] = 0;
 
-		// and the second part
-		this_usbduxfastsub->dux_commands[LENBASE + 5] =
-			steps_tmp - steps_tmp / 2;
-		this_usbduxfastsub->dux_commands[OPBASE + 5] = 0;
-		this_usbduxfastsub->dux_commands[OUTBASE + 5] = 0xFF & rngmask;
-		this_usbduxfastsub->dux_commands[LOGBASE + 5] = 0;
+		/* do the first part of the delay */
+		udfs->dux_commands[LENBASE+4] = steps_tmp / 2;
+		udfs->dux_commands[OPBASE+4] = 0;
+		/* reset */
+		udfs->dux_commands[OUTBASE+4] = (0xFF - 0x02) & rngmask;
+		udfs->dux_commands[LOGBASE+4] = 0;
 
-		this_usbduxfastsub->dux_commands[LENBASE + 6] = 1;
-		this_usbduxfastsub->dux_commands[OPBASE + 6] = 0;
-		this_usbduxfastsub->dux_commands[OUTBASE + 6] = 0xFF & rngmask;
-		this_usbduxfastsub->dux_commands[LOGBASE + 6] = 0;
+		/* and the second part */
+		udfs->dux_commands[LENBASE+5] = steps_tmp - steps_tmp / 2;
+		udfs->dux_commands[OPBASE+5] = 0;
+		udfs->dux_commands[OUTBASE+5] = 0xFF & rngmask;
+		udfs->dux_commands[LOGBASE+5] = 0;
+
+		udfs->dux_commands[LENBASE+6] = 1;
+		udfs->dux_commands[OPBASE+6] = 0;
+		udfs->dux_commands[OUTBASE+6] = 0xFF & rngmask;
+		udfs->dux_commands[LOGBASE+6] = 0;
 		break;
 
 	case 3:
-		// three channels
+		/*
+		 * three channels
+		 */
 		for (j = 0; j < 1; j++) {
 			if (CR_RANGE(cmd->chanlist[j]) > 0)
 				rngmask = 0xff - 0x04;
 			else
 				rngmask = 0xff;
-			// commit data to the FIFO and do the first part of the delay
-			this_usbduxfastsub->dux_commands[LENBASE + j * 2] =
-				steps / 2;
-			this_usbduxfastsub->dux_commands[OPBASE + j * 2] = 0x02;	// data
-			this_usbduxfastsub->dux_commands[OUTBASE + j * 2] = 0xFF & rngmask;	// no change
-			this_usbduxfastsub->dux_commands[LOGBASE + j * 2] = 0;
+			/*
+			 * commit data to the FIFO and do the first part
+			 * of the delay
+			 */
+			udfs->dux_commands[LENBASE+j*2] = steps / 2;
+			/* data */
+			udfs->dux_commands[OPBASE+j*2] = 0x02;
+			/* no change */
+			udfs->dux_commands[OUTBASE+j*2] = 0xFF & rngmask;
+			udfs->dux_commands[LOGBASE+j*2] = 0;
 
 			if (CR_RANGE(cmd->chanlist[j + 1]) > 0)
 				rngmask = 0xff - 0x04;
 			else
 				rngmask = 0xff;
-			// do the second part of the delay
-			this_usbduxfastsub->dux_commands[LENBASE + j * 2 + 1] =
-				steps - steps / 2;
-			this_usbduxfastsub->dux_commands[OPBASE + j * 2 + 1] = 0;	// no data
-			this_usbduxfastsub->dux_commands[OUTBASE + j * 2 + 1] = 0xFE & rngmask;	//count
-			this_usbduxfastsub->dux_commands[LOGBASE + j * 2 + 1] =
-				0;
+
+			/* do the second part of the delay */
+			udfs->dux_commands[LENBASE+j*2+1] = steps - steps / 2;
+			/* no data */
+			udfs->dux_commands[OPBASE+j*2+1] = 0;
+			/* count */
+			udfs->dux_commands[OUTBASE+j*2+1] = 0xFE & rngmask;
+			udfs->dux_commands[LOGBASE+j*2+1] = 0;
 		}
 
-		// 2 steps with duration 1: the idele step and step 6:
+		/* 2 steps with duration 1: the idele step and step 6: */
 		steps_tmp = steps - 2;
-		// commit data to the FIFO and do the first part of the delay
-		this_usbduxfastsub->dux_commands[LENBASE + 4] = steps_tmp / 2;
-		this_usbduxfastsub->dux_commands[OPBASE + 4] = 0x02;	// data
-		this_usbduxfastsub->dux_commands[OUTBASE + 4] = 0xFF & rngmask;	// no change
-		this_usbduxfastsub->dux_commands[LOGBASE + 4] = 0;
+
+		/* commit data to the FIFO and do the first part of the delay */
+		udfs->dux_commands[LENBASE+4] = steps_tmp / 2;
+		/* data */
+		udfs->dux_commands[OPBASE+4] = 0x02;
+		udfs->dux_commands[OUTBASE+4] = 0xFF & rngmask;
+		udfs->dux_commands[LOGBASE+4] = 0;
 
 		if (CR_RANGE(cmd->chanlist[0]) > 0)
 			rngmask = 0xff - 0x04;
 		else
 			rngmask = 0xff;
-		// do the second part of the delay
-		this_usbduxfastsub->dux_commands[LENBASE + 5] =
-			steps_tmp - steps_tmp / 2;
-		this_usbduxfastsub->dux_commands[OPBASE + 5] = 0;	// no data
-		this_usbduxfastsub->dux_commands[OUTBASE + 5] = (0xFF - 0x02) & rngmask;	// reset
-		this_usbduxfastsub->dux_commands[LOGBASE + 5] = 0;
 
-		this_usbduxfastsub->dux_commands[LENBASE + 6] = 1;
-		this_usbduxfastsub->dux_commands[OPBASE + 6] = 0;
-		this_usbduxfastsub->dux_commands[OUTBASE + 6] = 0xFF & rngmask;
-		this_usbduxfastsub->dux_commands[LOGBASE + 6] = 0;
+		/* do the second part of the delay */
+		udfs->dux_commands[LENBASE+5] = steps_tmp - steps_tmp / 2;
+		/* no data */
+		udfs->dux_commands[OPBASE+5] = 0;
+		/* reset */
+		udfs->dux_commands[OUTBASE+5] = (0xFF - 0x02) & rngmask;
+		udfs->dux_commands[LOGBASE+5] = 0;
+
+		udfs->dux_commands[LENBASE+6] = 1;
+		udfs->dux_commands[OPBASE+6] = 0;
+		udfs->dux_commands[OUTBASE+6] = 0xFF & rngmask;
+		udfs->dux_commands[LOGBASE+6] = 0;
 
 	case 16:
 		if (CR_RANGE(cmd->chanlist[0]) > 0)
 			rngmask = 0xff - 0x04;
 		else
 			rngmask = 0xff;
-		if (cmd->start_src == TRIG_EXT) {	// we loop here until ready has been set
-			this_usbduxfastsub->dux_commands[LENBASE + 0] = 0x01;	// branch back to state 0
-			this_usbduxfastsub->dux_commands[OPBASE + 0] = 0x01;	// deceision state w/o data
-			this_usbduxfastsub->dux_commands[OUTBASE + 0] = (0xFF - 0x02) & rngmask;	// reset
-			this_usbduxfastsub->dux_commands[LOGBASE + 0] = 0x00;	// RDY0 = 0
-		} else {	// we just proceed to state 1
-			this_usbduxfastsub->dux_commands[LENBASE + 0] = 255;	// 30us reset pulse
-			this_usbduxfastsub->dux_commands[OPBASE + 0] = 0;
-			this_usbduxfastsub->dux_commands[OUTBASE + 0] = (0xFF - 0x02) & rngmask;	// reset
-			this_usbduxfastsub->dux_commands[LOGBASE + 0] = 0;
+
+		if (cmd->start_src == TRIG_EXT) {
+			/*
+			 * we loop here until ready has been set
+			 */
+
+			/* branch back to state 0 */
+			udfs->dux_commands[LENBASE+0] = 0x01;
+			/* deceision state w/o data */
+			udfs->dux_commands[OPBASE+0] = 0x01;
+			/* reset */
+			udfs->dux_commands[OUTBASE+0] = (0xFF-0x02) & rngmask;
+			/* RDY0 = 0 */
+			udfs->dux_commands[LOGBASE+0] = 0x00;
+		} else {
+			/*
+			 * we just proceed to state 1
+			 */
+
+			/* 30us reset pulse */
+			udfs->dux_commands[LENBASE+0] = 255;
+			udfs->dux_commands[OPBASE+0] = 0;
+			/* reset */
+			udfs->dux_commands[OUTBASE+0] = (0xFF-0x02) & rngmask;
+			udfs->dux_commands[LOGBASE+0] = 0;
 		}
 
-		// commit data to the FIFO
-		this_usbduxfastsub->dux_commands[LENBASE + 1] = 1;
-		this_usbduxfastsub->dux_commands[OPBASE + 1] = 0x02;	// data
-		this_usbduxfastsub->dux_commands[OUTBASE + 1] = 0xFF & rngmask;
-		this_usbduxfastsub->dux_commands[LOGBASE + 1] = 0;
+		/* commit data to the FIFO */
+		udfs->dux_commands[LENBASE+1] = 1;
+		/* data */
+		udfs->dux_commands[OPBASE+1] = 0x02;
+		udfs->dux_commands[OUTBASE+1] = 0xFF & rngmask;
+		udfs->dux_commands[LOGBASE+1] = 0;
 
-		// we have 2 states with duration 1
+		/* we have 2 states with duration 1 */
 		steps = steps - 2;
 
-		// do the first part of the delay
-		this_usbduxfastsub->dux_commands[LENBASE + 2] = steps / 2;
-		this_usbduxfastsub->dux_commands[OPBASE + 2] = 0;
-		this_usbduxfastsub->dux_commands[OUTBASE + 2] = 0xFE & rngmask;
-		this_usbduxfastsub->dux_commands[LOGBASE + 2] = 0;
+		/* do the first part of the delay */
+		udfs->dux_commands[LENBASE+2] = steps / 2;
+		udfs->dux_commands[OPBASE+2] = 0;
+		udfs->dux_commands[OUTBASE+2] = 0xFE & rngmask;
+		udfs->dux_commands[LOGBASE+2] = 0;
 
-		// and the second part
-		this_usbduxfastsub->dux_commands[LENBASE + 3] =
-			steps - steps / 2;
-		this_usbduxfastsub->dux_commands[OPBASE + 3] = 0;
-		this_usbduxfastsub->dux_commands[OUTBASE + 3] = 0xFF & rngmask;
-		this_usbduxfastsub->dux_commands[LOGBASE + 3] = 0;
+		/* and the second part */
+		udfs->dux_commands[LENBASE+3] = steps - steps / 2;
+		udfs->dux_commands[OPBASE+3] = 0;
+		udfs->dux_commands[OUTBASE+3] = 0xFF & rngmask;
+		udfs->dux_commands[LOGBASE+3] = 0;
 
-		this_usbduxfastsub->dux_commands[LENBASE + 4] = 0x09;	// branch back to state 1
-		this_usbduxfastsub->dux_commands[OPBASE + 4] = 0x01;	// deceision state w/o data
-		this_usbduxfastsub->dux_commands[OUTBASE + 4] = 0xFF & rngmask;
-		this_usbduxfastsub->dux_commands[LOGBASE + 4] = 0xFF;	// doesn't matter
+		/* branch back to state 1 */
+		udfs->dux_commands[LENBASE+4] = 0x09;
+		/* deceision state w/o data */
+		udfs->dux_commands[OPBASE+4] = 0x01;
+		udfs->dux_commands[OUTBASE+4] = 0xFF & rngmask;
+		/* doesn't matter */
+		udfs->dux_commands[LOGBASE+4] = 0xFF;
 
 		break;
 
 	default:
-		printk("comedi %d: unsupported combination of channels\n",
-			dev->minor);
-		up(&this_usbduxfastsub->sem);
+		printk(KERN_ERR "comedi %d: unsupported combination of "
+		       "channels\n", dev->minor);
+		up(&udfs->sem);
 		return -EFAULT;
 	}
 
 #ifdef CONFIG_COMEDI_DEBUG
-	printk("comedi %d: sending commands to the usb device\n", dev->minor);
+	printk(KERN_DEBUG "comedi %d: sending commands to the usb device\n",
+	       dev->minor);
 #endif
-	// 0 means that the AD commands are sent
-	result = send_dux_commands(this_usbduxfastsub, SENDADCOMMANDS);
+	/* 0 means that the AD commands are sent */
+	result = send_dux_commands(udfs, SENDADCOMMANDS);
 	if (result < 0) {
-		printk("comedi%d: adc command could not be submitted. Aborting...\n", dev->minor);
-		up(&this_usbduxfastsub->sem);
+		printk(KERN_ERR "comedi%d: adc command could not be submitted."
+		       "Aborting...\n", dev->minor);
+		up(&udfs->sem);
 		return result;
 	}
 	if (cmd->stop_src == TRIG_COUNT) {
-		this_usbduxfastsub->ai_sample_count =
-			(cmd->stop_arg) * (cmd->scan_end_arg);
-		if (usbduxfastsub->ai_sample_count < 1) {
-			printk("comedi%d: (cmd->stop_arg)*(cmd->scan_end_arg)<1, aborting.\n", dev->minor);
-			up(&this_usbduxfastsub->sem);
+		udfs->ai_sample_count =	cmd->stop_arg * cmd->scan_end_arg;
+		if (udfs->ai_sample_count < 1) {
+			printk(KERN_ERR "comedi%d: "
+			       "(cmd->stop_arg)*(cmd->scan_end_arg)<1, "
+			       "aborting.\n", dev->minor);
+			up(&udfs->sem);
 			return -EFAULT;
 		}
-		this_usbduxfastsub->ai_continous = 0;
+		udfs->ai_continous = 0;
 	} else {
-		// continous aquisition
-		this_usbduxfastsub->ai_continous = 1;
-		this_usbduxfastsub->ai_sample_count = 0;
+		/* continous aquisition */
+		udfs->ai_continous = 1;
+		udfs->ai_sample_count = 0;
 	}
 
 	if ((cmd->start_src == TRIG_NOW) || (cmd->start_src == TRIG_EXT)) {
-		// enable this acquisition operation
-		this_usbduxfastsub->ai_cmd_running = 1;
-		ret = usbduxfastsub_submit_InURBs(this_usbduxfastsub);
+		/* enable this acquisition operation */
+		udfs->ai_cmd_running = 1;
+		ret = usbduxfastsub_submit_InURBs(udfs);
 		if (ret < 0) {
-			this_usbduxfastsub->ai_cmd_running = 0;
-			// fixme: unlink here??
-			up(&this_usbduxfastsub->sem);
+			udfs->ai_cmd_running = 0;
+			/* fixme: unlink here?? */
+			up(&udfs->sem);
 			return ret;
 		}
 		s->async->inttrig = NULL;
 	} else {
-		/* TRIG_INT */
-		// don't enable the acquision operation
-		// wait for an internal signal
+		/*
+		 * TRIG_INT
+		 * don't enable the acquision operation
+		 * wait for an internal signal
+		 */
 		s->async->inttrig = usbduxfast_ai_inttrig;
 	}
-	up(&this_usbduxfastsub->sem);
+	up(&udfs->sem);
 
 	return 0;
 }
 
-/* Mode 0 is used to get a single conversion on demand */
-static int usbduxfast_ai_insn_read(comedi_device * dev,
-	comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+/*
+ * Mode 0 is used to get a single conversion on demand.
+ */
+static int usbduxfast_ai_insn_read(struct comedi_device *dev,
+	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
 {
 	int i, j, n, actual_length;
 	int chan, range, rngmask;
 	int err;
-	usbduxfastsub_t *usbduxfastsub = dev->private;
+	struct usbduxfastsub_s *udfs;
 
-	if (!usbduxfastsub) {
-		printk("comedi%d: ai_insn_read: no usb dev.\n", dev->minor);
+	udfs = dev->private;
+	if (!udfs) {
+		printk(KERN_ERR "comedi%d: ai_insn_read: no usb dev.\n",
+		       dev->minor);
 		return -ENODEV;
 	}
 #ifdef CONFIG_COMEDI_DEBUG
-	printk("comedi%d: ai_insn_read, insn->n=%d, insn->subdev=%d\n",
-		dev->minor, insn->n, insn->subdev);
+	printk(KERN_DEBUG "comedi%d: ai_insn_read, insn->n=%d, "
+	       "insn->subdev=%d\n", dev->minor, insn->n, insn->subdev);
 #endif
-	down(&usbduxfastsub->sem);
-	if (!(usbduxfastsub->probed)) {
-		up(&usbduxfastsub->sem);
+	down(&udfs->sem);
+	if (!udfs->probed) {
+		up(&udfs->sem);
 		return -ENODEV;
 	}
-	if (usbduxfastsub->ai_cmd_running) {
-		printk("comedi%d: ai_insn_read not possible. Async Command is running.\n", dev->minor);
-		up(&usbduxfastsub->sem);
+	if (udfs->ai_cmd_running) {
+		printk(KERN_ERR "comedi%d: ai_insn_read not possible. Async "
+		       "Command is running.\n", dev->minor);
+		up(&udfs->sem);
 		return -EBUSY;
 	}
-	// sample one channel
+	/* sample one channel */
 	chan = CR_CHAN(insn->chanspec);
 	range = CR_RANGE(insn->chanspec);
-	// set command for the first channel
+	/* set command for the first channel */
 
 	if (range > 0)
 		rngmask = 0xff - 0x04;
 	else
 		rngmask = 0xff;
-	// commit data to the FIFO
-	usbduxfastsub->dux_commands[LENBASE + 0] = 1;
-	usbduxfastsub->dux_commands[OPBASE + 0] = 0x02;	// data
-	usbduxfastsub->dux_commands[OUTBASE + 0] = 0xFF & rngmask;
-	usbduxfastsub->dux_commands[LOGBASE + 0] = 0;
 
-	// do the first part of the delay
-	usbduxfastsub->dux_commands[LENBASE + 1] = 12;
-	usbduxfastsub->dux_commands[OPBASE + 1] = 0;
-	usbduxfastsub->dux_commands[OUTBASE + 1] = 0xFE & rngmask;
-	usbduxfastsub->dux_commands[LOGBASE + 1] = 0;
+	/* commit data to the FIFO */
+	udfs->dux_commands[LENBASE+0] = 1;
+	/* data */
+	udfs->dux_commands[OPBASE+0] = 0x02;
+	udfs->dux_commands[OUTBASE+0] = 0xFF & rngmask;
+	udfs->dux_commands[LOGBASE+0] = 0;
 
-	usbduxfastsub->dux_commands[LENBASE + 2] = 1;
-	usbduxfastsub->dux_commands[OPBASE + 2] = 0;
-	usbduxfastsub->dux_commands[OUTBASE + 2] = 0xFE & rngmask;
-	usbduxfastsub->dux_commands[LOGBASE + 2] = 0;
+	/* do the first part of the delay */
+	udfs->dux_commands[LENBASE+1] = 12;
+	udfs->dux_commands[OPBASE+1] = 0;
+	udfs->dux_commands[OUTBASE+1] = 0xFE & rngmask;
+	udfs->dux_commands[LOGBASE+1] = 0;
 
-	usbduxfastsub->dux_commands[LENBASE + 3] = 1;
-	usbduxfastsub->dux_commands[OPBASE + 3] = 0;
-	usbduxfastsub->dux_commands[OUTBASE + 3] = 0xFE & rngmask;
-	usbduxfastsub->dux_commands[LOGBASE + 3] = 0;
+	udfs->dux_commands[LENBASE+2] = 1;
+	udfs->dux_commands[OPBASE+2] = 0;
+	udfs->dux_commands[OUTBASE+2] = 0xFE & rngmask;
+	udfs->dux_commands[LOGBASE+2] = 0;
 
-	usbduxfastsub->dux_commands[LENBASE + 4] = 1;
-	usbduxfastsub->dux_commands[OPBASE + 4] = 0;
-	usbduxfastsub->dux_commands[OUTBASE + 4] = 0xFE & rngmask;
-	usbduxfastsub->dux_commands[LOGBASE + 4] = 0;
+	udfs->dux_commands[LENBASE+3] = 1;
+	udfs->dux_commands[OPBASE+3] = 0;
+	udfs->dux_commands[OUTBASE+3] = 0xFE & rngmask;
+	udfs->dux_commands[LOGBASE+3] = 0;
 
-	// second part
-	usbduxfastsub->dux_commands[LENBASE + 5] = 12;
-	usbduxfastsub->dux_commands[OPBASE + 5] = 0;
-	usbduxfastsub->dux_commands[OUTBASE + 5] = 0xFF & rngmask;
-	usbduxfastsub->dux_commands[LOGBASE + 5] = 0;
+	udfs->dux_commands[LENBASE+4] = 1;
+	udfs->dux_commands[OPBASE+4] = 0;
+	udfs->dux_commands[OUTBASE+4] = 0xFE & rngmask;
+	udfs->dux_commands[LOGBASE+4] = 0;
 
-	usbduxfastsub->dux_commands[LENBASE + 6] = 1;
-	usbduxfastsub->dux_commands[OPBASE + 6] = 0;
-	usbduxfastsub->dux_commands[OUTBASE + 6] = 0xFF & rngmask;
-	usbduxfastsub->dux_commands[LOGBASE + 0] = 0;
+	/* second part */
+	udfs->dux_commands[LENBASE+5] = 12;
+	udfs->dux_commands[OPBASE+5] = 0;
+	udfs->dux_commands[OUTBASE+5] = 0xFF & rngmask;
+	udfs->dux_commands[LOGBASE+5] = 0;
+
+	udfs->dux_commands[LENBASE+6] = 1;
+	udfs->dux_commands[OPBASE+6] = 0;
+	udfs->dux_commands[OUTBASE+6] = 0xFF & rngmask;
+	udfs->dux_commands[LOGBASE+0] = 0;
 
 #ifdef CONFIG_COMEDI_DEBUG
-	printk("comedi %d: sending commands to the usb device\n", dev->minor);
+	printk(KERN_DEBUG "comedi %d: sending commands to the usb device\n",
+	       dev->minor);
 #endif
-	// 0 means that the AD commands are sent
-	err = send_dux_commands(usbduxfastsub, SENDADCOMMANDS);
+	/* 0 means that the AD commands are sent */
+	err = send_dux_commands(udfs, SENDADCOMMANDS);
 	if (err < 0) {
-		printk("comedi%d: adc command could not be submitted. Aborting...\n", dev->minor);
-		up(&usbduxfastsub->sem);
+		printk(KERN_ERR "comedi%d: adc command could not be submitted."
+		       "Aborting...\n", dev->minor);
+		up(&udfs->sem);
 		return err;
 	}
 #ifdef CONFIG_COMEDI_DEBUG
-	printk("comedi%d: usbduxfast: submitting in-urb: %x,%x\n",
-		usbduxfastsub->comedidev->minor,
-		(int)(usbduxfastsub->urbIn->context),
-		(int)(usbduxfastsub->urbIn->dev));
+	printk(KERN_DEBUG "comedi%d: usbduxfast: submitting in-urb: "
+	       "0x%p,0x%p\n", udfs->comedidev->minor, udfs->urbIn->context,
+	       udfs->urbIn->dev);
 #endif
 	for (i = 0; i < PACKETS_TO_IGNORE; i++) {
-		err = usb_bulk_msg(usbduxfastsub->usbdev,
-				   usb_rcvbulkpipe(usbduxfastsub->usbdev,
-						   BULKINEP),
-				   usbduxfastsub->transfer_buffer, SIZEINBUF,
+		err = usb_bulk_msg(udfs->usbdev,
+				   usb_rcvbulkpipe(udfs->usbdev, BULKINEP),
+				   udfs->transfer_buffer, SIZEINBUF,
 				   &actual_length, 10000);
 		if (err < 0) {
-			printk("comedi%d: insn timeout. No data.\n",
+			printk(KERN_ERR "comedi%d: insn timeout. No data.\n",
 				dev->minor);
-			up(&usbduxfastsub->sem);
+			up(&udfs->sem);
 			return err;
 		}
 	}
-	// data points
+	/* data points */
 	for (i = 0; i < insn->n;) {
-		err = usb_bulk_msg(usbduxfastsub->usbdev,
-				   usb_rcvbulkpipe(usbduxfastsub->usbdev,
-						   BULKINEP),
-				   usbduxfastsub->transfer_buffer, SIZEINBUF,
+		err = usb_bulk_msg(udfs->usbdev,
+				   usb_rcvbulkpipe(udfs->usbdev, BULKINEP),
+				   udfs->transfer_buffer, SIZEINBUF,
 				   &actual_length, 10000);
 		if (err < 0) {
-			printk("comedi%d: insn data error: %d\n",
+			printk(KERN_ERR "comedi%d: insn data error: %d\n",
 				dev->minor, err);
-			up(&usbduxfastsub->sem);
+			up(&udfs->sem);
 			return err;
 		}
 		n = actual_length / sizeof(uint16_t);
 		if ((n % 16) != 0) {
-			printk("comedi%d: insn data packet corrupted.\n",
-				dev->minor);
-			up(&usbduxfastsub->sem);
+			printk(KERN_ERR "comedi%d: insn data packet "
+			       "corrupted.\n", dev->minor);
+			up(&udfs->sem);
 			return -EINVAL;
 		}
 		for (j = chan; (j < n) && (i < insn->n); j = j + 16) {
-			data[i] =
-				((uint16_t *) (usbduxfastsub->
-					transfer_buffer))[j];
+			data[i] = ((uint16_t *) (udfs->transfer_buffer))[j];
 			i++;
 		}
 	}
-	up(&usbduxfastsub->sem);
+	up(&udfs->sem);
 	return i;
 }
 
 static unsigned hex2unsigned(char *h)
 {
 	unsigned hi, lo;
-	if (h[0] > '9') {
+
+	if (h[0] > '9')
 		hi = h[0] - 'A' + 0x0a;
-	} else {
+	else
 		hi = h[0] - '0';
-	}
-	if (h[1] > '9') {
+
+	if (h[1] > '9')
 		lo = h[1] - 'A' + 0x0a;
-	} else {
+	else
 		lo = h[1] - '0';
-	}
+
 	return hi * 0x10 + lo;
 }
 
-// for FX2
+/* for FX2 */
 #define FIRMWARE_MAX_LEN 0x2000
 
-// taken from David Brownell's fxload and adjusted for this driver
-static int read_firmware(usbduxfastsub_t * usbduxfastsub, void *firmwarePtr,
-	long size)
+/*
+ * taken from David Brownell's fxload and adjusted for this driver
+ */
+static int read_firmware(struct usbduxfastsub_s *udfs, const void *firmwarePtr,
+			 long size)
 {
 	int i = 0;
 	unsigned char *fp = (char *)firmwarePtr;
-	unsigned char *firmwareBinary = NULL;
+	unsigned char *firmwareBinary;
 	int res = 0;
 	int maxAddr = 0;
 
 	firmwareBinary = kmalloc(FIRMWARE_MAX_LEN, GFP_KERNEL);
 	if (!firmwareBinary) {
-		printk("comedi_: usbduxfast: mem alloc for firmware failed\n");
+		printk(KERN_ERR "comedi_: usbduxfast: mem alloc for firmware "
+		       " failed\n");
 		return -ENOMEM;
 	}
 
@@ -1315,31 +1411,37 @@
 		int idx, off;
 		int j = 0;
 
-		// get one line
+		/* get one line */
 		while ((i < size) && (fp[i] != 13) && (fp[i] != 10)) {
 			buf[j] = fp[i];
 			i++;
 			j++;
 			if (j >= sizeof(buf)) {
-				printk("comedi_: usbduxfast: bogus firmware file!\n");
+				printk(KERN_ERR "comedi_: usbduxfast: bogus "
+				       "firmware file!\n");
+				kfree(firmwareBinary);
 				return -1;
 			}
 		}
-		// get rid of LF/CR/...
+		/* get rid of LF/CR/... */
 		while ((i < size) && ((fp[i] == 13) || (fp[i] == 10)
-				|| (fp[i] == 0))) {
+					|| (fp[i] == 0)))
 			i++;
-		}
 
 		buf[j] = 0;
-		//printk("comedi_: buf=%s\n",buf);
+		/* printk("comedi_: buf=%s\n",buf); */
 
-		/* EXTENSION: "# comment-till-end-of-line", for copyrights etc */
+		/*
+		 * EXTENSION: "# comment-till-end-of-line",
+		 * for copyrights etc
+		 */
 		if (buf[0] == '#')
 			continue;
 
 		if (buf[0] != ':') {
-			printk("comedi_: usbduxfast: upload: not an ihex record: %s", buf);
+			printk(KERN_ERR "comedi_: usbduxfast: upload: not an "
+			       "ihex record: %s", buf);
+			kfree(firmwareBinary);
 			return -EFAULT;
 		}
 
@@ -1349,266 +1451,309 @@
 		/* Read the target offset */
 		off = (hex2unsigned(buf + 3) * 0x0100) + hex2unsigned(buf + 5);
 
-		if ((off + len) > maxAddr) {
+		if ((off + len) > maxAddr)
 			maxAddr = off + len;
-		}
 
 		if (maxAddr >= FIRMWARE_MAX_LEN) {
-			printk("comedi_: usbduxfast: firmware upload goes beyond FX2 RAM boundaries.");
+			printk(KERN_ERR "comedi_: usbduxfast: firmware upload "
+			       "goes beyond FX2 RAM boundaries.");
+			kfree(firmwareBinary);
 			return -EFAULT;
 		}
-		//printk("comedi_: usbduxfast: off=%x, len=%x:",off,len);
+		/* printk("comedi_: usbduxfast: off=%x, len=%x:",off,len); */
 
 		/* Read the record type */
 		type = hex2unsigned(buf + 7);
 
 		/* If this is an EOF record, then make it so. */
-		if (type == 1) {
+		if (type == 1)
 			break;
-		}
 
 		if (type != 0) {
-			printk("comedi_: usbduxfast: unsupported record type: %u\n", type);
+			printk(KERN_ERR "comedi_: usbduxfast: unsupported "
+			       "record type: %u\n", type);
+			kfree(firmwareBinary);
 			return -EFAULT;
 		}
 
 		for (idx = 0, cp = buf + 9; idx < len; idx += 1, cp += 2) {
 			firmwareBinary[idx + off] = hex2unsigned(cp);
-			//printk("%02x ",firmwareBinary[idx+off]);
+			/* printk("%02x ",firmwareBinary[idx+off]); */
 		}
-		//printk("\n");
+
+		/* printk("\n"); */
 
 		if (i >= size) {
-			printk("comedi_: usbduxfast: unexpected end of hex file\n");
+			printk(KERN_ERR "comedi_: usbduxfast: unexpected end "
+			       "of hex file\n");
 			break;
 		}
 
 	}
-	res = firmwareUpload(usbduxfastsub, firmwareBinary, maxAddr + 1);
+	res = firmwareUpload(udfs, firmwareBinary, maxAddr + 1);
 	kfree(firmwareBinary);
 	return res;
 }
 
-static void tidy_up(usbduxfastsub_t * usbduxfastsub_tmp)
+static void tidy_up(struct usbduxfastsub_s *udfs)
 {
 #ifdef CONFIG_COMEDI_DEBUG
-	printk("comedi_: usbduxfast: tiding up\n");
+	printk(KERN_DEBUG "comedi_: usbduxfast: tiding up\n");
 #endif
-	if (!usbduxfastsub_tmp) {
+
+	if (!udfs)
 		return;
-	}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-	// shows the usb subsystem that the driver is down
-	if (usbduxfastsub_tmp->interface) {
-		usb_set_intfdata(usbduxfastsub_tmp->interface, NULL);
-	}
-#endif
 
-	usbduxfastsub_tmp->probed = 0;
+	/* shows the usb subsystem that the driver is down */
+	if (udfs->interface)
+		usb_set_intfdata(udfs->interface, NULL);
 
-	if (usbduxfastsub_tmp->urbIn) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8)
-		// waits until a running transfer is over
-		// thus, under 2.4 hotplugging while a command
-		// is running is not safe
-		usb_kill_urb(usbduxfastsub_tmp->urbIn);
-#endif
-		if (usbduxfastsub_tmp->transfer_buffer) {
-			kfree(usbduxfastsub_tmp->transfer_buffer);
-			usbduxfastsub_tmp->transfer_buffer = NULL;
-		}
-		usb_free_urb(usbduxfastsub_tmp->urbIn);
-		usbduxfastsub_tmp->urbIn = NULL;
+	udfs->probed = 0;
+
+	if (udfs->urbIn) {
+		/* waits until a running transfer is over */
+		usb_kill_urb(udfs->urbIn);
+
+		kfree(udfs->transfer_buffer);
+		udfs->transfer_buffer = NULL;
+
+		usb_free_urb(udfs->urbIn);
+		udfs->urbIn = NULL;
 	}
-	if (usbduxfastsub_tmp->insnBuffer) {
-		kfree(usbduxfastsub_tmp->insnBuffer);
-		usbduxfastsub_tmp->insnBuffer = NULL;
-	}
-	if (usbduxfastsub_tmp->dux_commands) {
-		kfree(usbduxfastsub_tmp->dux_commands);
-		usbduxfastsub_tmp->dux_commands = NULL;
-	}
-	usbduxfastsub_tmp->ai_cmd_running = 0;
+
+	kfree(udfs->insnBuffer);
+	udfs->insnBuffer = NULL;
+
+	kfree(udfs->dux_commands);
+	udfs->dux_commands = NULL;
+
+	udfs->ai_cmd_running = 0;
 }
 
-// allocate memory for the urbs and initialise them
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-static void *usbduxfastsub_probe(struct usb_device *udev,
-	unsigned int interfnum, const struct usb_device_id *id)
+static void usbduxfast_firmware_request_complete_handler(const struct firmware *fw,
+							 void *context)
 {
-#else
+	struct usbduxfastsub_s *usbduxfastsub_tmp = context;
+	struct usb_device *usbdev = usbduxfastsub_tmp->usbdev;
+	int ret;
+
+	if (fw == NULL)
+		return;
+
+	/*
+	 * we need to upload the firmware here because fw will be
+	 * freed once we've left this function
+	 */
+	ret = read_firmware(usbduxfastsub_tmp, fw->data, fw->size);
+
+	if (ret) {
+		dev_err(&usbdev->dev,
+			"Could not upload firmware (err=%d)\n",
+			ret);
+		return;
+	}
+
+	comedi_usb_auto_config(usbdev, BOARDNAME);
+}
+
+/*
+ * allocate memory for the urbs and initialise them
+ */
 static int usbduxfastsub_probe(struct usb_interface *uinterf,
 	const struct usb_device_id *id)
 {
 	struct usb_device *udev = interface_to_usbdev(uinterf);
-#endif
 	int i;
 	int index;
+	int ret;
 
 	if (udev->speed != USB_SPEED_HIGH) {
-		printk("comedi_: usbduxfast_: This driver needs USB 2.0 to operate. Aborting...\n");
+		printk(KERN_ERR "comedi_: usbduxfast_: This driver needs"
+		       "USB 2.0 to operate. Aborting...\n");
 		return -ENODEV;
 	}
 #ifdef CONFIG_COMEDI_DEBUG
-	printk("comedi_: usbduxfast_: finding a free structure for the usb-device\n");
+	printk(KERN_DEBUG "comedi_: usbduxfast_: finding a free structure for "
+	       "the usb-device\n");
 #endif
 	down(&start_stop_sem);
-	// look for a free place in the usbduxfast array
+	/* look for a free place in the usbduxfast array */
 	index = -1;
 	for (i = 0; i < NUMUSBDUXFAST; i++) {
-		if (!(usbduxfastsub[i].probed)) {
+		if (!usbduxfastsub[i].probed) {
 			index = i;
 			break;
 		}
 	}
 
-	// no more space
+	/* no more space */
 	if (index == -1) {
-		printk("Too many usbduxfast-devices connected.\n");
+		printk(KERN_ERR "Too many usbduxfast-devices connected.\n");
 		up(&start_stop_sem);
 		return -EMFILE;
 	}
 #ifdef CONFIG_COMEDI_DEBUG
-	printk("comedi_: usbduxfast: usbduxfastsub[%d] is ready to connect to comedi.\n", index);
+	printk(KERN_DEBUG "comedi_: usbduxfast: usbduxfastsub[%d] is ready to "
+	       "connect to comedi.\n", index);
 #endif
 
 	init_MUTEX(&(usbduxfastsub[index].sem));
-	// save a pointer to the usb device
+	/* save a pointer to the usb device */
 	usbduxfastsub[index].usbdev = udev;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-	// save the interface number
-	usbduxfastsub[index].ifnum = interfnum;
-#else
-	// 2.6: save the interface itself
+	/* save the interface itself */
 	usbduxfastsub[index].interface = uinterf;
-	// get the interface number from the interface
+	/* get the interface number from the interface */
 	usbduxfastsub[index].ifnum = uinterf->altsetting->desc.bInterfaceNumber;
-	// hand the private data over to the usb subsystem
-	// will be needed for disconnect
+	/*
+	 * hand the private data over to the usb subsystem
+	 * will be needed for disconnect
+	 */
 	usb_set_intfdata(uinterf, &(usbduxfastsub[index]));
-#endif
 
 #ifdef CONFIG_COMEDI_DEBUG
-	printk("comedi_: usbduxfast: ifnum=%d\n", usbduxfastsub[index].ifnum);
+	printk(KERN_DEBUG "comedi_: usbduxfast: ifnum=%d\n",
+	       usbduxfastsub[index].ifnum);
 #endif
-	// create space for the commands going to the usb device
+	/* create space for the commands going to the usb device */
 	usbduxfastsub[index].dux_commands = kmalloc(SIZEOFDUXBUFFER,
-		GFP_KERNEL);
+						    GFP_KERNEL);
 	if (!usbduxfastsub[index].dux_commands) {
-		printk("comedi_: usbduxfast: error alloc space for dac commands\n");
+		printk(KERN_ERR "comedi_: usbduxfast: error alloc space for "
+		       "dac commands\n");
 		tidy_up(&(usbduxfastsub[index]));
 		up(&start_stop_sem);
 		return -ENOMEM;
 	}
-	// create space of the instruction buffer
+	/* create space of the instruction buffer */
 	usbduxfastsub[index].insnBuffer = kmalloc(SIZEINSNBUF, GFP_KERNEL);
-	if (!(usbduxfastsub[index].insnBuffer)) {
-		printk("comedi_: usbduxfast: could not alloc space for insnBuffer\n");
+	if (!usbduxfastsub[index].insnBuffer) {
+		printk(KERN_ERR "comedi_: usbduxfast: could not alloc space "
+		       "for insnBuffer\n");
 		tidy_up(&(usbduxfastsub[index]));
 		up(&start_stop_sem);
 		return -ENOMEM;
 	}
-	// setting to alternate setting 1: enabling bulk ep
+	/* setting to alternate setting 1: enabling bulk ep */
 	i = usb_set_interface(usbduxfastsub[index].usbdev,
 		usbduxfastsub[index].ifnum, 1);
 	if (i < 0) {
-		printk("comedi_: usbduxfast%d: could not switch to alternate setting 1.\n", index);
+		printk(KERN_ERR "comedi_: usbduxfast%d: could not switch to "
+		       "alternate setting 1.\n", index);
 		tidy_up(&(usbduxfastsub[index]));
 		up(&start_stop_sem);
 		return -ENODEV;
 	}
 	usbduxfastsub[index].urbIn = usb_alloc_urb(0, GFP_KERNEL);
-	if (usbduxfastsub[index].urbIn == NULL) {
-		printk("comedi_: usbduxfast%d: Could not alloc. urb\n", index);
+	if (!usbduxfastsub[index].urbIn) {
+		printk(KERN_ERR "comedi_: usbduxfast%d: Could not alloc."
+		       "urb\n", index);
 		tidy_up(&(usbduxfastsub[index]));
 		up(&start_stop_sem);
 		return -ENOMEM;
 	}
 	usbduxfastsub[index].transfer_buffer = kmalloc(SIZEINBUF, GFP_KERNEL);
-	if (!(usbduxfastsub[index].transfer_buffer)) {
-		printk("comedi_: usbduxfast%d: could not alloc. transb.\n",
-			index);
+	if (!usbduxfastsub[index].transfer_buffer) {
+		printk(KERN_ERR "comedi_: usbduxfast%d: could not alloc. "
+		       "transb.\n", index);
 		tidy_up(&(usbduxfastsub[index]));
 		up(&start_stop_sem);
 		return -ENOMEM;
 	}
-	// we've reached the bottom of the function
+	/* we've reached the bottom of the function */
 	usbduxfastsub[index].probed = 1;
 	up(&start_stop_sem);
-	printk("comedi_: usbduxfast%d has been successfully initialized.\n",
-		index);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-	return (void *)(&usbduxfastsub[index]);
-#else
-	// success
+
+	ret = request_firmware_nowait(THIS_MODULE,
+				      FW_ACTION_HOTPLUG,
+				      "usbduxfast_firmware.hex",
+				      &udev->dev,
+				      usbduxfastsub + index,
+				      usbduxfast_firmware_request_complete_handler);
+
+	if (ret) {
+		dev_err(&udev->dev, "could not load firmware (err=%d)\n",
+			ret);
+		return ret;
+	}
+
+	printk(KERN_INFO "comedi_: usbduxfast%d has been successfully "
+	       "initialized.\n", index);
+	/* success */
 	return 0;
-#endif
 }
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-static void usbduxfastsub_disconnect(struct usb_device *udev, void *ptr)
-{
-	usbduxfastsub_t *usbduxfastsub_tmp = (usbduxfastsub_t *) ptr;
-#else
 static void usbduxfastsub_disconnect(struct usb_interface *intf)
 {
-	usbduxfastsub_t *usbduxfastsub_tmp = usb_get_intfdata(intf);
+	struct usbduxfastsub_s *udfs = usb_get_intfdata(intf);
 	struct usb_device *udev = interface_to_usbdev(intf);
-#endif
-	if (!usbduxfastsub_tmp) {
-		printk("comedi_: usbduxfast: disconnect called with null pointer.\n");
+
+	if (!udfs) {
+		printk(KERN_ERR "comedi_: usbduxfast: disconnect called with "
+		       "null pointer.\n");
 		return;
 	}
-	if (usbduxfastsub_tmp->usbdev != udev) {
-		printk("comedi_: usbduxfast: BUG! called with wrong ptr!!!\n");
+	if (udfs->usbdev != udev) {
+		printk(KERN_ERR "comedi_: usbduxfast: BUG! called with wrong "
+		       "ptr!!!\n");
 		return;
 	}
+
+	comedi_usb_auto_unconfig(udev);
+
 	down(&start_stop_sem);
-	down(&usbduxfastsub_tmp->sem);
-	tidy_up(usbduxfastsub_tmp);
-	up(&usbduxfastsub_tmp->sem);
+	down(&udfs->sem);
+	tidy_up(udfs);
+	up(&udfs->sem);
 	up(&start_stop_sem);
+
 #ifdef CONFIG_COMEDI_DEBUG
-	printk("comedi_: usbduxfast: disconnected from the usb\n");
+	printk(KERN_DEBUG "comedi_: usbduxfast: disconnected from the usb\n");
 #endif
 }
 
-// is called when comedi-config is called
-static int usbduxfast_attach(comedi_device * dev, comedi_devconfig * it)
+/*
+ * is called when comedi-config is called
+ */
+static int usbduxfast_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
 	int ret;
 	int index;
 	int i;
-	comedi_subdevice *s = NULL;
+	struct comedi_subdevice *s = NULL;
 	dev->private = NULL;
 
 	down(&start_stop_sem);
-	// find a valid device which has been detected by the probe function of the usb
+	/*
+	 * find a valid device which has been detected by the
+	 * probe function of the usb
+	 */
 	index = -1;
 	for (i = 0; i < NUMUSBDUXFAST; i++) {
-		if ((usbduxfastsub[i].probed) && (!usbduxfastsub[i].attached)) {
+		if (usbduxfastsub[i].probed && !usbduxfastsub[i].attached) {
 			index = i;
 			break;
 		}
 	}
 
 	if (index < 0) {
-		printk("comedi%d: usbduxfast: error: attach failed, no usbduxfast devs connected to the usb bus.\n", dev->minor);
+		printk(KERN_ERR "comedi%d: usbduxfast: error: attach failed, "
+		       "no usbduxfast devs connected to the usb bus.\n",
+		       dev->minor);
 		up(&start_stop_sem);
 		return -ENODEV;
 	}
 
 	down(&(usbduxfastsub[index].sem));
-	// pointer back to the corresponding comedi device
+	/* pointer back to the corresponding comedi device */
 	usbduxfastsub[index].comedidev = dev;
 
-	// trying to upload the firmware into the chip
+	/* trying to upload the firmware into the chip */
 	if (comedi_aux_data(it->options, 0) &&
-		it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) {
-		read_firmware(usbduxfastsub,
-			comedi_aux_data(it->options, 0),
-			it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]);
+	    it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) {
+		read_firmware(&usbduxfastsub[index],
+			      comedi_aux_data(it->options, 0),
+			      it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]);
 	}
 
 	dev->board_name = BOARDNAME;
@@ -1616,155 +1761,150 @@
 	/* set number of subdevices */
 	dev->n_subdevices = N_SUBDEVICES;
 
-	// allocate space for the subdevices
-	if ((ret = alloc_subdevices(dev, N_SUBDEVICES)) < 0) {
-		printk("comedi%d: usbduxfast: error alloc space for subdev\n",
-			dev->minor);
+	/* allocate space for the subdevices */
+	ret = alloc_subdevices(dev, N_SUBDEVICES);
+	if (ret < 0) {
+		printk(KERN_ERR "comedi%d: usbduxfast: error alloc space for "
+		       "subdev\n", dev->minor);
+		up(&(usbduxfastsub[index].sem));
 		up(&start_stop_sem);
 		return ret;
 	}
 
-	printk("comedi%d: usbduxfast: usb-device %d is attached to comedi.\n",
-		dev->minor, index);
-	// private structure is also simply the usb-structure
+	printk(KERN_INFO "comedi%d: usbduxfast: usb-device %d is attached to "
+	       "comedi.\n", dev->minor, index);
+	/* private structure is also simply the usb-structure */
 	dev->private = usbduxfastsub + index;
-	// the first subdevice is the A/D converter
+	/* the first subdevice is the A/D converter */
 	s = dev->subdevices + SUBDEV_AD;
-	// the URBs get the comedi subdevice
-	// which is responsible for reading
-	// this is the subdevice which reads data
+	/*
+	 * the URBs get the comedi subdevice which is responsible for reading
+	 * this is the subdevice which reads data
+	 */
 	dev->read_subdev = s;
-	// the subdevice receives as private structure the
-	// usb-structure
+	/* the subdevice receives as private structure the usb-structure */
 	s->private = NULL;
-	// analog input
+	/* analog input */
 	s->type = COMEDI_SUBD_AI;
-	// readable and ref is to ground
+	/* readable and ref is to ground */
 	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
-	// 16 channels
+	/* 16 channels */
 	s->n_chan = 16;
-	// length of the channellist
+	/* length of the channellist */
 	s->len_chanlist = 16;
-	// callback functions
+	/* callback functions */
 	s->insn_read = usbduxfast_ai_insn_read;
 	s->do_cmdtest = usbduxfast_ai_cmdtest;
 	s->do_cmd = usbduxfast_ai_cmd;
 	s->cancel = usbduxfast_ai_cancel;
-	// max value from the A/D converter (12bit+1 bit for overflow)
+	/* max value from the A/D converter (12bit+1 bit for overflow) */
 	s->maxdata = 0x1000;
-	// range table to convert to physical units
+	/* range table to convert to physical units */
 	s->range_table = &range_usbduxfast_ai_range;
 
-	// finally decide that it's attached
+	/* finally decide that it's attached */
 	usbduxfastsub[index].attached = 1;
 
 	up(&(usbduxfastsub[index].sem));
-
 	up(&start_stop_sem);
-
-	printk("comedi%d: successfully attached to usbduxfast.\n", dev->minor);
+	printk(KERN_INFO "comedi%d: successfully attached to usbduxfast.\n",
+	       dev->minor);
 
 	return 0;
 }
 
-static int usbduxfast_detach(comedi_device * dev)
+static int usbduxfast_detach(struct comedi_device *dev)
 {
-	usbduxfastsub_t *usbduxfastsub_tmp;
-
-#ifdef CONFIG_COMEDI_DEBUG
-	printk("comedi%d: usbduxfast: detach usb device\n", dev->minor);
-#endif
+	struct usbduxfastsub_s *udfs;
 
 	if (!dev) {
-		printk("comedi?: usbduxfast: detach without dev variable...\n");
+		printk(KERN_ERR "comedi?: usbduxfast: detach without dev "
+		       "variable...\n");
 		return -EFAULT;
 	}
 
-	usbduxfastsub_tmp = dev->private;
-	if (!usbduxfastsub_tmp) {
-		printk("comedi?: usbduxfast: detach without ptr to usbduxfastsub[]\n");
-		return -EFAULT;
-	}
-
-	down(&usbduxfastsub_tmp->sem);
-	down(&start_stop_sem);
-	// Don't allow detach to free the private structure
-	// It's one entry of of usbduxfastsub[]
-	dev->private = NULL;
-	usbduxfastsub_tmp->attached = 0;
-	usbduxfastsub_tmp->comedidev = NULL;
 #ifdef CONFIG_COMEDI_DEBUG
-	printk("comedi%d: usbduxfast: detach: successfully removed\n",
-		dev->minor);
+	printk(KERN_DEBUG "comedi%d: usbduxfast: detach usb device\n",
+	       dev->minor);
+#endif
+
+	udfs = dev->private;
+	if (!udfs) {
+		printk(KERN_ERR "comedi?: usbduxfast: detach without ptr to "
+		       "usbduxfastsub[]\n");
+		return -EFAULT;
+	}
+
+	down(&udfs->sem);
+	down(&start_stop_sem);
+	/*
+	 * Don't allow detach to free the private structure
+	 * It's one entry of of usbduxfastsub[]
+	 */
+	dev->private = NULL;
+	udfs->attached = 0;
+	udfs->comedidev = NULL;
+#ifdef CONFIG_COMEDI_DEBUG
+	printk(KERN_DEBUG "comedi%d: usbduxfast: detach: successfully "
+	       "removed\n", dev->minor);
 #endif
 	up(&start_stop_sem);
-	up(&usbduxfastsub_tmp->sem);
+	up(&udfs->sem);
 	return 0;
 }
 
-/* main driver struct */
-static comedi_driver driver_usbduxfast = {
-      driver_name:"usbduxfast",
-      module:THIS_MODULE,
-      attach:usbduxfast_attach,
-      detach:usbduxfast_detach,
+/*
+ * main driver struct
+ */
+static struct comedi_driver driver_usbduxfast = {
+	.driver_name	= "usbduxfast",
+	.module		= THIS_MODULE,
+	.attach		= usbduxfast_attach,
+	.detach		= usbduxfast_detach
 };
 
-static void init_usb_devices(void)
-{
-	int index;
-#ifdef CONFIG_COMEDI_DEBUG
-	printk("comedi_: usbduxfast: setting all possible devs to invalid\n");
-#endif
-	// all devices entries are invalid to begin with
-	// they will become valid by the probe function
-	// and then finally by the attach-function
-	for (index = 0; index < NUMUSBDUXFAST; index++) {
-		memset(&(usbduxfastsub[index]), 0x00,
-			sizeof(usbduxfastsub[index]));
-		init_MUTEX(&(usbduxfastsub[index].sem));
-	}
-}
-
-// Table with the USB-devices: just now only testing IDs
+/*
+ * Table with the USB-devices: just now only testing IDs
+ */
 static struct usb_device_id usbduxfastsub_table[] = {
-	//        { USB_DEVICE(0x4b4, 0x8613), //testing
-	//        },
-	{USB_DEVICE(0x13d8, 0x0010)	//real ID
-		},
-	{USB_DEVICE(0x13d8, 0x0011)	//real ID
-		},
-	{}			/* Terminating entry */
+	/* { USB_DEVICE(0x4b4, 0x8613) }, testing */
+	{ USB_DEVICE(0x13d8, 0x0010) },	/* real ID */
+	{ USB_DEVICE(0x13d8, 0x0011) },	/* real ID */
+	{ }			/* Terminating entry */
 };
 
 MODULE_DEVICE_TABLE(usb, usbduxfastsub_table);
 
-// The usbduxfastsub-driver
+/*
+ * The usbduxfastsub-driver
+ */
 static struct usb_driver usbduxfastsub_driver = {
 #ifdef COMEDI_HAVE_USB_DRIVER_OWNER
-      owner:THIS_MODULE,
+	.owner		= THIS_MODULE,
 #endif
-      name:BOARDNAME,
-      probe:usbduxfastsub_probe,
-      disconnect:usbduxfastsub_disconnect,
-      id_table:usbduxfastsub_table,
+	.name		= BOARDNAME,
+	.probe		= usbduxfastsub_probe,
+	.disconnect	= usbduxfastsub_disconnect,
+	.id_table	= usbduxfastsub_table
 };
 
-// Can't use the nice macro as I have also to initialise the USB
-// subsystem:
-// registering the usb-system _and_ the comedi-driver
-static int init_usbduxfast(void)
+/*
+ * Can't use the nice macro as I have also to initialise the USB subsystem:
+ * registering the usb-system _and_ the comedi-driver
+ */
+static int __init init_usbduxfast(void)
 {
-	printk(KERN_INFO KBUILD_MODNAME ": "
-	       DRIVER_VERSION ":" DRIVER_DESC "\n");
-	init_usb_devices();
+	printk(KERN_INFO
+	       KBUILD_MODNAME ": " DRIVER_VERSION ":" DRIVER_DESC "\n");
 	usb_register(&usbduxfastsub_driver);
 	comedi_driver_register(&driver_usbduxfast);
 	return 0;
 }
 
-// deregistering the comedi driver and the usb-subsystem
-static void exit_usbduxfast(void)
+/*
+ * deregistering the comedi driver and the usb-subsystem
+ */
+static void __exit exit_usbduxfast(void)
 {
 	comedi_driver_unregister(&driver_usbduxfast);
 	usb_deregister(&usbduxfastsub_driver);
diff --git a/drivers/staging/comedi/interrupt.h b/drivers/staging/comedi/interrupt.h
index 3038e46..d1f0989 100644
--- a/drivers/staging/comedi/interrupt.h
+++ b/drivers/staging/comedi/interrupt.h
@@ -21,15 +21,6 @@
 
 #include <linux/interrupt.h>
 
-#include <linux/version.h>
-
-#ifndef IRQ_NONE
-typedef void irqreturn_t;
-#define IRQ_NONE
-#define IRQ_HANDLED
-#define IRQ_RETVAL(x) (void)(x)
-#endif
-
 #ifndef IRQF_DISABLED
 #define IRQF_DISABLED           SA_INTERRUPT
 #define IRQF_SAMPLE_RANDOM      SA_SAMPLE_RANDOM
diff --git a/drivers/staging/comedi/kcomedilib/data.c b/drivers/staging/comedi/kcomedilib/data.c
index 79aec204..9797e13 100644
--- a/drivers/staging/comedi/kcomedilib/data.c
+++ b/drivers/staging/comedi/kcomedilib/data.c
@@ -27,10 +27,10 @@
 
 #include <linux/string.h>
 
-int comedi_data_write(comedi_t * dev, unsigned int subdev, unsigned int chan,
-	unsigned int range, unsigned int aref, lsampl_t data)
+int comedi_data_write(void *dev, unsigned int subdev, unsigned int chan,
+	unsigned int range, unsigned int aref, unsigned int data)
 {
-	comedi_insn insn;
+	struct comedi_insn insn;
 
 	memset(&insn, 0, sizeof(insn));
 	insn.insn = INSN_WRITE;
@@ -42,10 +42,10 @@
 	return comedi_do_insn(dev, &insn);
 }
 
-int comedi_data_read(comedi_t * dev, unsigned int subdev, unsigned int chan,
-	unsigned int range, unsigned int aref, lsampl_t * data)
+int comedi_data_read(void *dev, unsigned int subdev, unsigned int chan,
+	unsigned int range, unsigned int aref, unsigned int *data)
 {
-	comedi_insn insn;
+	struct comedi_insn insn;
 
 	memset(&insn, 0, sizeof(insn));
 	insn.insn = INSN_READ;
@@ -57,11 +57,11 @@
 	return comedi_do_insn(dev, &insn);
 }
 
-int comedi_data_read_hint(comedi_t * dev, unsigned int subdev,
+int comedi_data_read_hint(void *dev, unsigned int subdev,
 	unsigned int chan, unsigned int range, unsigned int aref)
 {
-	comedi_insn insn;
-	lsampl_t dummy_data;
+	struct comedi_insn insn;
+	unsigned int dummy_data;
 
 	memset(&insn, 0, sizeof(insn));
 	insn.insn = INSN_READ;
@@ -73,9 +73,9 @@
 	return comedi_do_insn(dev, &insn);
 }
 
-int comedi_data_read_delayed(comedi_t * dev, unsigned int subdev,
+int comedi_data_read_delayed(void *dev, unsigned int subdev,
 	unsigned int chan, unsigned int range, unsigned int aref,
-	lsampl_t * data, unsigned int nano_sec)
+	unsigned int *data, unsigned int nano_sec)
 {
 	int retval;
 
diff --git a/drivers/staging/comedi/kcomedilib/dio.c b/drivers/staging/comedi/kcomedilib/dio.c
index a9f488a..8595567 100644
--- a/drivers/staging/comedi/kcomedilib/dio.c
+++ b/drivers/staging/comedi/kcomedilib/dio.c
@@ -26,10 +26,10 @@
 
 #include <linux/string.h>
 
-int comedi_dio_config(comedi_t * dev, unsigned int subdev, unsigned int chan,
+int comedi_dio_config(void *dev, unsigned int subdev, unsigned int chan,
 	unsigned int io)
 {
-	comedi_insn insn;
+	struct comedi_insn insn;
 
 	memset(&insn, 0, sizeof(insn));
 	insn.insn = INSN_CONFIG;
@@ -41,10 +41,10 @@
 	return comedi_do_insn(dev, &insn);
 }
 
-int comedi_dio_read(comedi_t * dev, unsigned int subdev, unsigned int chan,
+int comedi_dio_read(void *dev, unsigned int subdev, unsigned int chan,
 	unsigned int *val)
 {
-	comedi_insn insn;
+	struct comedi_insn insn;
 
 	memset(&insn, 0, sizeof(insn));
 	insn.insn = INSN_READ;
@@ -56,10 +56,10 @@
 	return comedi_do_insn(dev, &insn);
 }
 
-int comedi_dio_write(comedi_t * dev, unsigned int subdev, unsigned int chan,
+int comedi_dio_write(void *dev, unsigned int subdev, unsigned int chan,
 	unsigned int val)
 {
-	comedi_insn insn;
+	struct comedi_insn insn;
 
 	memset(&insn, 0, sizeof(insn));
 	insn.insn = INSN_WRITE;
@@ -71,11 +71,11 @@
 	return comedi_do_insn(dev, &insn);
 }
 
-int comedi_dio_bitfield(comedi_t * dev, unsigned int subdev, unsigned int mask,
+int comedi_dio_bitfield(void *dev, unsigned int subdev, unsigned int mask,
 	unsigned int *bits)
 {
-	comedi_insn insn;
-	lsampl_t data[2];
+	struct comedi_insn insn;
+	unsigned int data[2];
 	int ret;
 
 	memset(&insn, 0, sizeof(insn));
diff --git a/drivers/staging/comedi/kcomedilib/get.c b/drivers/staging/comedi/kcomedilib/get.c
index 2004ad4..b6b726a 100644
--- a/drivers/staging/comedi/kcomedilib/get.c
+++ b/drivers/staging/comedi/kcomedilib/get.c
@@ -26,51 +26,51 @@
 #include "../comedilib.h"
 #include "../comedidev.h"
 
-int comedi_get_n_subdevices(comedi_t * d)
+int comedi_get_n_subdevices(void *d)
 {
-	comedi_device *dev = (comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *) d;
 
 	return dev->n_subdevices;
 }
 
-int comedi_get_version_code(comedi_t * d)
+int comedi_get_version_code(void *d)
 {
 	return COMEDI_VERSION_CODE;
 }
 
-const char *comedi_get_driver_name(comedi_t * d)
+const char *comedi_get_driver_name(void * d)
 {
-	comedi_device *dev = (comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *) d;
 
 	return dev->driver->driver_name;
 }
 
-const char *comedi_get_board_name(comedi_t * d)
+const char *comedi_get_board_name(void * d)
 {
-	comedi_device *dev = (comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *) d;
 
 	return dev->board_name;
 }
 
-int comedi_get_subdevice_type(comedi_t * d, unsigned int subdevice)
+int comedi_get_subdevice_type(void *d, unsigned int subdevice)
 {
-	comedi_device *dev = (comedi_device *) d;
-	comedi_subdevice *s = dev->subdevices + subdevice;
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s = dev->subdevices + subdevice;
 
 	return s->type;
 }
 
-unsigned int comedi_get_subdevice_flags(comedi_t * d, unsigned int subdevice)
+unsigned int comedi_get_subdevice_flags(void *d, unsigned int subdevice)
 {
-	comedi_device *dev = (comedi_device *) d;
-	comedi_subdevice *s = dev->subdevices + subdevice;
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s = dev->subdevices + subdevice;
 
 	return s->subdev_flags;
 }
 
-int comedi_find_subdevice_by_type(comedi_t * d, int type, unsigned int subd)
+int comedi_find_subdevice_by_type(void *d, int type, unsigned int subd)
 {
-	comedi_device *dev = (comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *) d;
 
 	if (subd > dev->n_subdevices)
 		return -ENODEV;
@@ -82,27 +82,27 @@
 	return -1;
 }
 
-int comedi_get_n_channels(comedi_t * d, unsigned int subdevice)
+int comedi_get_n_channels(void *d, unsigned int subdevice)
 {
-	comedi_device *dev = (comedi_device *) d;
-	comedi_subdevice *s = dev->subdevices + subdevice;
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s = dev->subdevices + subdevice;
 
 	return s->n_chan;
 }
 
-int comedi_get_len_chanlist(comedi_t * d, unsigned int subdevice)
+int comedi_get_len_chanlist(void *d, unsigned int subdevice)
 {
-	comedi_device *dev = (comedi_device *) d;
-	comedi_subdevice *s = dev->subdevices + subdevice;
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s = dev->subdevices + subdevice;
 
 	return s->len_chanlist;
 }
 
-lsampl_t comedi_get_maxdata(comedi_t * d, unsigned int subdevice,
+unsigned int comedi_get_maxdata(void *d, unsigned int subdevice,
 	unsigned int chan)
 {
-	comedi_device *dev = (comedi_device *) d;
-	comedi_subdevice *s = dev->subdevices + subdevice;
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s = dev->subdevices + subdevice;
 
 	if (s->maxdata_list)
 		return s->maxdata_list[chan];
@@ -111,11 +111,11 @@
 }
 
 #ifdef KCOMEDILIB_DEPRECATED
-int comedi_get_rangetype(comedi_t * d, unsigned int subdevice,
+int comedi_get_rangetype(void *d, unsigned int subdevice,
 	unsigned int chan)
 {
-	comedi_device *dev = (comedi_device *) d;
-	comedi_subdevice *s = dev->subdevices + subdevice;
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s = dev->subdevices + subdevice;
 	int ret;
 
 	if (s->range_table_list) {
@@ -130,10 +130,10 @@
 }
 #endif
 
-int comedi_get_n_ranges(comedi_t * d, unsigned int subdevice, unsigned int chan)
+int comedi_get_n_ranges(void *d, unsigned int subdevice, unsigned int chan)
 {
-	comedi_device *dev = (comedi_device *) d;
-	comedi_subdevice *s = dev->subdevices + subdevice;
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s = dev->subdevices + subdevice;
 	int ret;
 
 	if (s->range_table_list) {
@@ -148,22 +148,22 @@
 /*
  * ALPHA (non-portable)
 */
-int comedi_get_krange(comedi_t * d, unsigned int subdevice, unsigned int chan,
-	unsigned int range, comedi_krange * krange)
+int comedi_get_krange(void *d, unsigned int subdevice, unsigned int chan,
+	unsigned int range, struct comedi_krange *krange)
 {
-	comedi_device *dev = (comedi_device *) d;
-	comedi_subdevice *s = dev->subdevices + subdevice;
-	const comedi_lrange *lr;
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s = dev->subdevices + subdevice;
+	const struct comedi_lrange *lr;
 
 	if (s->range_table_list) {
 		lr = s->range_table_list[chan];
 	} else {
 		lr = s->range_table;
 	}
-	if (range >= lr->length) {
+	if (range >= lr->length)
 		return -EINVAL;
-	}
-	memcpy(krange, lr->range + range, sizeof(comedi_krange));
+
+	memcpy(krange, lr->range + range, sizeof(struct comedi_krange));
 
 	return 0;
 }
@@ -171,11 +171,11 @@
 /*
  * ALPHA (may be renamed)
 */
-unsigned int comedi_get_buf_head_pos(comedi_t * d, unsigned int subdevice)
+unsigned int comedi_get_buf_head_pos(void *d, unsigned int subdevice)
 {
-	comedi_device *dev = (comedi_device *) d;
-	comedi_subdevice *s = dev->subdevices + subdevice;
-	comedi_async *async;
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s = dev->subdevices + subdevice;
+	struct comedi_async *async;
 
 	async = s->async;
 	if (async == NULL)
@@ -184,11 +184,11 @@
 	return async->buf_write_count;
 }
 
-int comedi_get_buffer_contents(comedi_t * d, unsigned int subdevice)
+int comedi_get_buffer_contents(void *d, unsigned int subdevice)
 {
-	comedi_device *dev = (comedi_device *) d;
-	comedi_subdevice *s = dev->subdevices + subdevice;
-	comedi_async *async;
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s = dev->subdevices + subdevice;
+	struct comedi_async *async;
 	unsigned int num_bytes;
 
 	if (subdevice >= dev->n_subdevices)
@@ -203,12 +203,12 @@
 /*
  * ALPHA
 */
-int comedi_set_user_int_count(comedi_t * d, unsigned int subdevice,
+int comedi_set_user_int_count(void *d, unsigned int subdevice,
 	unsigned int buf_user_count)
 {
-	comedi_device *dev = (comedi_device *) d;
-	comedi_subdevice *s = dev->subdevices + subdevice;
-	comedi_async *async;
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s = dev->subdevices + subdevice;
+	struct comedi_async *async;
 	int num_bytes;
 
 	async = s->async;
@@ -224,12 +224,12 @@
 	return 0;
 }
 
-int comedi_mark_buffer_read(comedi_t * d, unsigned int subdevice,
+int comedi_mark_buffer_read(void *d, unsigned int subdevice,
 	unsigned int num_bytes)
 {
-	comedi_device *dev = (comedi_device *) d;
-	comedi_subdevice *s = dev->subdevices + subdevice;
-	comedi_async *async;
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s = dev->subdevices + subdevice;
+	struct comedi_async *async;
 
 	if (subdevice >= dev->n_subdevices)
 		return -1;
@@ -243,12 +243,12 @@
 	return 0;
 }
 
-int comedi_mark_buffer_written(comedi_t * d, unsigned int subdevice,
+int comedi_mark_buffer_written(void *d, unsigned int subdevice,
 	unsigned int num_bytes)
 {
-	comedi_device *dev = (comedi_device *) d;
-	comedi_subdevice *s = dev->subdevices + subdevice;
-	comedi_async *async;
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s = dev->subdevices + subdevice;
+	struct comedi_async *async;
 	int bytes_written;
 
 	if (subdevice >= dev->n_subdevices)
@@ -263,11 +263,11 @@
 	return 0;
 }
 
-int comedi_get_buffer_size(comedi_t * d, unsigned int subdev)
+int comedi_get_buffer_size(void *d, unsigned int subdev)
 {
-	comedi_device *dev = (comedi_device *) d;
-	comedi_subdevice *s = dev->subdevices + subdev;
-	comedi_async *async;
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s = dev->subdevices + subdev;
+	struct comedi_async *async;
 
 	if (subdev >= dev->n_subdevices)
 		return -1;
@@ -278,11 +278,11 @@
 	return async->prealloc_bufsz;
 }
 
-int comedi_get_buffer_offset(comedi_t * d, unsigned int subdevice)
+int comedi_get_buffer_offset(void *d, unsigned int subdevice)
 {
-	comedi_device *dev = (comedi_device *) d;
-	comedi_subdevice *s = dev->subdevices + subdevice;
-	comedi_async *async;
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s = dev->subdevices + subdevice;
+	struct comedi_async *async;
 
 	if (subdevice >= dev->n_subdevices)
 		return -1;
diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
index 510fbdc..a4fa957 100644
--- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
+++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
@@ -42,10 +42,10 @@
 MODULE_DESCRIPTION("Comedi kernel library");
 MODULE_LICENSE("GPL");
 
-comedi_t *comedi_open(const char *filename)
+void *comedi_open(const char *filename)
 {
 	struct comedi_device_file_info *dev_file_info;
-	comedi_device *dev;
+	struct comedi_device *dev;
 	unsigned int minor;
 
 	if (strncmp(filename, "/dev/comedi", 11) != 0)
@@ -57,41 +57,41 @@
 		return NULL;
 
 	dev_file_info = comedi_get_device_file_info(minor);
-	if(dev_file_info == NULL)
+	if (dev_file_info == NULL)
 		return NULL;
 	dev = dev_file_info->device;
 
-	if(dev == NULL || !dev->attached)
+	if (dev == NULL || !dev->attached)
 		return NULL;
 
 	if (!try_module_get(dev->driver->module))
 		return NULL;
 
-	return (comedi_t *) dev;
+	return (void *) dev;
 }
 
-comedi_t *comedi_open_old(unsigned int minor)
+void *comedi_open_old(unsigned int minor)
 {
 	struct comedi_device_file_info *dev_file_info;
-	comedi_device *dev;
+	struct comedi_device *dev;
 
 	if (minor >= COMEDI_NUM_MINORS)
 		return NULL;
 
 	dev_file_info = comedi_get_device_file_info(minor);
-	if(dev_file_info == NULL)
+	if (dev_file_info == NULL)
 		return NULL;
 	dev = dev_file_info->device;
 
-	if(dev == NULL || !dev->attached)
+	if (dev == NULL || !dev->attached)
 		return NULL;
 
-	return (comedi_t *) dev;
+	return (void *) dev;
 }
 
-int comedi_close(comedi_t * d)
+int comedi_close(void *d)
 {
-	comedi_device *dev = (comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *) d;
 
 	module_put(dev->driver->module);
 
@@ -113,19 +113,19 @@
 	return "unknown error";
 }
 
-int comedi_fileno(comedi_t * d)
+int comedi_fileno(void *d)
 {
-	comedi_device *dev = (comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *) d;
 
 	/* return something random */
 	return dev->minor;
 }
 
-int comedi_command(comedi_t * d, comedi_cmd * cmd)
+int comedi_command(void *d, struct comedi_cmd *cmd)
 {
-	comedi_device *dev = (comedi_device *) d;
-	comedi_subdevice *s;
-	comedi_async *async;
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s;
+	struct comedi_async *async;
 	unsigned runflags;
 
 	if (cmd->subdev >= dev->n_subdevices)
@@ -161,10 +161,10 @@
 	return s->do_cmd(dev, s);
 }
 
-int comedi_command_test(comedi_t * d, comedi_cmd * cmd)
+int comedi_command_test(void *d, struct comedi_cmd *cmd)
 {
-	comedi_device *dev = (comedi_device *) d;
-	comedi_subdevice *s;
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s;
 
 	if (cmd->subdev >= dev->n_subdevices)
 		return -ENODEV;
@@ -183,10 +183,10 @@
  *	COMEDI_INSN
  *	perform an instruction
  */
-int comedi_do_insn(comedi_t * d, comedi_insn * insn)
+int comedi_do_insn(void *d, struct comedi_insn *insn)
 {
-	comedi_device *dev = (comedi_device *) d;
-	comedi_subdevice *s;
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s;
 	int ret = 0;
 
 	if (insn->insn & INSN_MASK_SPECIAL) {
@@ -256,7 +256,8 @@
 
 		/* XXX check lock */
 
-		if ((ret = check_chanlist(s, 1, &insn->chanspec)) < 0) {
+		ret = check_chanlist(s, 1, &insn->chanspec);
+		if (ret < 0) {
 			rt_printk("bad chanspec\n");
 			ret = -EINVAL;
 			goto error;
@@ -323,16 +324,16 @@
 	- lock while subdevice being programmed
 
 */
-int comedi_lock(comedi_t * d, unsigned int subdevice)
+int comedi_lock(void *d, unsigned int subdevice)
 {
-	comedi_device *dev = (comedi_device *) d;
-	comedi_subdevice *s;
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s;
 	unsigned long flags;
 	int ret = 0;
 
-	if (subdevice >= dev->n_subdevices) {
+	if (subdevice >= dev->n_subdevices)
 		return -EINVAL;
-	}
+
 	s = dev->subdevices + subdevice;
 
 	comedi_spin_lock_irqsave(&s->spin_lock, flags);
@@ -366,17 +367,17 @@
 		none
 
 */
-int comedi_unlock(comedi_t * d, unsigned int subdevice)
+int comedi_unlock(void *d, unsigned int subdevice)
 {
-	comedi_device *dev = (comedi_device *) d;
-	comedi_subdevice *s;
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s;
 	unsigned long flags;
-	comedi_async *async;
+	struct comedi_async *async;
 	int ret;
 
-	if (subdevice >= dev->n_subdevices) {
+	if (subdevice >= dev->n_subdevices)
 		return -EINVAL;
-	}
+
 	s = dev->subdevices + subdevice;
 
 	async = s->async;
@@ -418,15 +419,15 @@
 		nothing
 
 */
-int comedi_cancel(comedi_t * d, unsigned int subdevice)
+int comedi_cancel(void *d, unsigned int subdevice)
 {
-	comedi_device *dev = (comedi_device *) d;
-	comedi_subdevice *s;
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s;
 	int ret = 0;
 
-	if (subdevice >= dev->n_subdevices) {
+	if (subdevice >= dev->n_subdevices)
 		return -EINVAL;
-	}
+
 	s = dev->subdevices + subdevice;
 
 	if (s->lock && s->lock != d)
@@ -443,13 +444,15 @@
 	if (!s->cancel || !s->async)
 		return -EINVAL;
 
-	if ((ret = s->cancel(dev, s)))
+	ret = s->cancel(dev, s);
+
+	if (ret)
 		return ret;
 
 #ifdef CONFIG_COMEDI_RT
-	if (comedi_get_subdevice_runflags(s) & SRF_RT) {
+	if (comedi_get_subdevice_runflags(s) & SRF_RT)
 		comedi_switch_to_non_rt(dev);
-	}
+
 #endif
 	comedi_set_subdevice_runflags(s, SRF_RUNNING | SRF_RT, 0);
 	s->async->inttrig = NULL;
@@ -461,16 +464,16 @@
 /*
    registration of callback functions
  */
-int comedi_register_callback(comedi_t * d, unsigned int subdevice,
+int comedi_register_callback(void *d, unsigned int subdevice,
 	unsigned int mask, int (*cb) (unsigned int, void *), void *arg)
 {
-	comedi_device *dev = (comedi_device *) d;
-	comedi_subdevice *s;
-	comedi_async *async;
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s;
+	struct comedi_async *async;
 
-	if (subdevice >= dev->n_subdevices) {
+	if (subdevice >= dev->n_subdevices)
 		return -EINVAL;
-	}
+
 	s = dev->subdevices + subdevice;
 
 	async = s->async;
@@ -498,15 +501,15 @@
 	return 0;
 }
 
-int comedi_poll(comedi_t * d, unsigned int subdevice)
+int comedi_poll(void *d, unsigned int subdevice)
 {
-	comedi_device *dev = (comedi_device *) d;
-	comedi_subdevice *s = dev->subdevices;
-	comedi_async *async;
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s = dev->subdevices;
+	struct comedi_async *async;
 
-	if (subdevice >= dev->n_subdevices) {
+	if (subdevice >= dev->n_subdevices)
 		return -EINVAL;
-	}
+
 	s = dev->subdevices + subdevice;
 
 	async = s->async;
@@ -525,22 +528,21 @@
 }
 
 /* WARNING: not portable */
-int comedi_map(comedi_t * d, unsigned int subdevice, void *ptr)
+int comedi_map(void *d, unsigned int subdevice, void *ptr)
 {
-	comedi_device *dev = (comedi_device *) d;
-	comedi_subdevice *s;
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s;
 
-	if (subdevice >= dev->n_subdevices) {
+	if (subdevice >= dev->n_subdevices)
 		return -EINVAL;
-	}
+
 	s = dev->subdevices + subdevice;
 
 	if (!s->async)
 		return -EINVAL;
 
-	if (ptr) {
+	if (ptr)
 		*((void **)ptr) = s->async->prealloc_buf;
-	}
 
 	/* XXX no reference counting */
 
@@ -548,14 +550,14 @@
 }
 
 /* WARNING: not portable */
-int comedi_unmap(comedi_t * d, unsigned int subdevice)
+int comedi_unmap(void *d, unsigned int subdevice)
 {
-	comedi_device *dev = (comedi_device *) d;
-	comedi_subdevice *s;
+	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_subdevice *s;
 
-	if (subdevice >= dev->n_subdevices) {
+	if (subdevice >= dev->n_subdevices)
 		return -EINVAL;
-	}
+
 	s = dev->subdevices + subdevice;
 
 	if (!s->async)
diff --git a/drivers/staging/comedi/kcomedilib/ksyms.c b/drivers/staging/comedi/kcomedilib/ksyms.c
index 76b4506..3db86da 100644
--- a/drivers/staging/comedi/kcomedilib/ksyms.c
+++ b/drivers/staging/comedi/kcomedilib/ksyms.c
@@ -40,8 +40,6 @@
 #include <linux/mm.h>
 #include <linux/slab.h>
 
-#if LINUX_VERSION_CODE >= 0x020200
-
 /* functions specific to kcomedilib */
 
 EXPORT_SYMBOL(comedi_register_callback);
@@ -140,5 +138,3 @@
 
 /* alpha */
 //EXPORT_SYMBOL(comedi_set_global_oor_behavior);
-
-#endif
diff --git a/drivers/staging/comedi/pci_ids.h b/drivers/staging/comedi/pci_ids.h
index c61ba90..d979aa8 100644
--- a/drivers/staging/comedi/pci_ids.h
+++ b/drivers/staging/comedi/pci_ids.h
@@ -28,4 +28,4 @@
 #define PCI_DEVICE_ID_QUANCOM_GPIB	0x3302
 #endif
 
-#endif // __COMPAT_LINUX_PCI_IDS_H
+#endif /* __COMPAT_LINUX_PCI_IDS_H */
diff --git a/drivers/staging/comedi/proc.c b/drivers/staging/comedi/proc.c
index 5a2b72d..36ae2cd 100644
--- a/drivers/staging/comedi/proc.c
+++ b/drivers/staging/comedi/proc.c
@@ -31,12 +31,12 @@
 #define __NO_VERSION__
 #include "comedidev.h"
 #include <linux/proc_fs.h>
-//#include <linux/string.h>
+/* #include <linux/string.h> */
 
 int comedi_read_procmem(char *buf, char **start, off_t offset, int len,
 	int *eof, void *data);
 
-extern comedi_driver *comedi_drivers;
+extern struct comedi_driver *comedi_drivers;
 
 int comedi_read_procmem(char *buf, char **start, off_t offset, int len,
 	int *eof, void *data)
@@ -44,7 +44,7 @@
 	int i;
 	int devices_q = 0;
 	int l = 0;
-	comedi_driver *driv;
+	struct comedi_driver *driv;
 
 	l += sprintf(buf + l,
 		"comedi version " COMEDI_RELEASE "\n"
@@ -53,9 +53,10 @@
 
 	for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) {
 		struct comedi_device_file_info *dev_file_info = comedi_get_device_file_info(i);
-		comedi_device *dev;
+		struct comedi_device *dev;
 
-		if(dev_file_info == NULL) continue;
+		if (dev_file_info == NULL)
+			continue;
 		dev = dev_file_info->device;
 
 		if (dev->attached) {
@@ -66,9 +67,8 @@
 				dev->board_name, dev->n_subdevices);
 		}
 	}
-	if (!devices_q) {
+	if (!devices_q)
 		l += sprintf(buf + l, "no devices\n");
-	}
 
 	for (driv = comedi_drivers; driv; driv = driv->next) {
 		l += sprintf(buf + l, "%s:\n", driv->driver_name);
@@ -77,9 +77,8 @@
 				*(char **)((char *)driv->board_name +
 					i * driv->offset));
 		}
-		if (!driv->num_names) {
+		if (!driv->num_names)
 			l += sprintf(buf + l, " %s\n", driv->driver_name);
-		}
 	}
 
 	return l;
diff --git a/drivers/staging/comedi/range.c b/drivers/staging/comedi/range.c
index 61dc3cd..ac200d9 100644
--- a/drivers/staging/comedi/range.c
+++ b/drivers/staging/comedi/range.c
@@ -24,12 +24,12 @@
 #include "comedidev.h"
 #include <asm/uaccess.h>
 
-const comedi_lrange range_bipolar10 = { 1, {BIP_RANGE(10)} };
-const comedi_lrange range_bipolar5 = { 1, {BIP_RANGE(5)} };
-const comedi_lrange range_bipolar2_5 = { 1, {BIP_RANGE(2.5)} };
-const comedi_lrange range_unipolar10 = { 1, {UNI_RANGE(10)} };
-const comedi_lrange range_unipolar5 = { 1, {UNI_RANGE(5)} };
-const comedi_lrange range_unknown = { 1, {{0, 1000000, UNIT_none}} };
+const struct comedi_lrange range_bipolar10 = { 1, {BIP_RANGE(10)} };
+const struct comedi_lrange range_bipolar5 = { 1, {BIP_RANGE(5)} };
+const struct comedi_lrange range_bipolar2_5 = { 1, {BIP_RANGE(2.5)} };
+const struct comedi_lrange range_unipolar10 = { 1, {UNI_RANGE(10)} };
+const struct comedi_lrange range_unipolar5 = { 1, {UNI_RANGE(5)} };
+const struct comedi_lrange range_unknown = { 1, {{0, 1000000, UNIT_none}} };
 
 /*
    	COMEDI_RANGEINFO
@@ -42,16 +42,16 @@
 		range info structure
 
 	writes:
-		n comedi_krange structures to rangeinfo->range_ptr
+		n struct comedi_krange structures to rangeinfo->range_ptr
 */
-int do_rangeinfo_ioctl(comedi_device * dev, comedi_rangeinfo * arg)
+int do_rangeinfo_ioctl(struct comedi_device *dev, struct comedi_rangeinfo *arg)
 {
-	comedi_rangeinfo it;
+	struct comedi_rangeinfo it;
 	int subd, chan;
-	const comedi_lrange *lr;
-	comedi_subdevice *s;
+	const struct comedi_lrange *lr;
+	struct comedi_subdevice *s;
 
-	if (copy_from_user(&it, arg, sizeof(comedi_rangeinfo)))
+	if (copy_from_user(&it, arg, sizeof(struct comedi_rangeinfo)))
 		return -EFAULT;
 	subd = (it.range_type >> 24) & 0xf;
 	chan = (it.range_type >> 16) & 0xff;
@@ -78,17 +78,17 @@
 	}
 
 	if (copy_to_user(it.range_ptr, lr->range,
-			sizeof(comedi_krange) * lr->length))
+			sizeof(struct comedi_krange) * lr->length))
 		return -EFAULT;
 
 	return 0;
 }
 
-static int aref_invalid(comedi_subdevice * s, unsigned int chanspec)
+static int aref_invalid(struct comedi_subdevice *s, unsigned int chanspec)
 {
 	unsigned int aref;
 
-	// disable reporting invalid arefs... maybe someday
+	/*  disable reporting invalid arefs... maybe someday */
 	return 0;
 
 	aref = CR_AREF(chanspec);
@@ -120,7 +120,7 @@
    This function checks each element in a channel/gain list to make
    make sure it is valid.
 */
-int check_chanlist(comedi_subdevice * s, int n, unsigned int *chanlist)
+int check_chanlist(struct comedi_subdevice *s, int n, unsigned int *chanlist)
 {
 	int i;
 	int chan;
@@ -135,9 +135,8 @@
 					i, chanlist[i], s->n_chan,
 					s->range_table->length);
 #if 0
-				for (i = 0; i < n; i++) {
+				for (i = 0; i < n; i++)
 					printk("[%d]=0x%08x\n", i, chanlist[i]);
-				}
 #endif
 				return -EINVAL;
 			}
diff --git a/drivers/staging/comedi/rt.c b/drivers/staging/comedi/rt.c
index 385b81b..e9f5777 100644
--- a/drivers/staging/comedi/rt.c
+++ b/drivers/staging/comedi/rt.c
@@ -57,7 +57,7 @@
 	 irqreturn_t(*handler) (int irq, void *dev_id PT_REGS_ARG);
 	unsigned long flags;
 	const char *device;
-	comedi_device *dev_id;
+	struct comedi_device *dev_id;
 };
 
 static int comedi_rt_get_irq(struct comedi_irq_struct *it);
@@ -67,7 +67,7 @@
 
 int comedi_request_irq(unsigned irq, irqreturn_t(*handler) (int,
 		void *PT_REGS_ARG), unsigned long flags, const char *device,
-	comedi_device * dev_id)
+	struct comedi_device *dev_id)
 {
 	struct comedi_irq_struct *it;
 	int ret;
@@ -78,15 +78,15 @@
 
 	ret = request_irq(irq, handler, unshared_flags, device, dev_id);
 	if (ret < 0) {
-		// we failed, so fall back on allowing shared interrupt (which we won't ever make RT)
+		/*  we failed, so fall back on allowing shared interrupt (which we won't ever make RT) */
 		if (flags & IRQF_SHARED) {
 			rt_printk
 				("comedi: cannot get unshared interrupt, will not use RT interrupts.\n");
 			ret = request_irq(irq, handler, flags, device, dev_id);
 		}
-		if (ret < 0) {
+		if (ret < 0)
 			return ret;
-		}
+
 	} else {
 		it = kzalloc(sizeof(struct comedi_irq_struct), GFP_KERNEL);
 		if (!it)
@@ -102,7 +102,7 @@
 	return 0;
 }
 
-void comedi_free_irq(unsigned int irq, comedi_device * dev_id)
+void comedi_free_irq(unsigned int irq, struct comedi_device *dev_id)
 {
 	struct comedi_irq_struct *it;
 
@@ -121,7 +121,7 @@
 	comedi_irqs[irq] = NULL;
 }
 
-int comedi_switch_to_rt(comedi_device * dev)
+int comedi_switch_to_rt(struct comedi_device *dev)
 {
 	struct comedi_irq_struct *it;
 	unsigned long flags;
@@ -145,7 +145,7 @@
 	return 0;
 }
 
-void comedi_switch_to_non_rt(comedi_device * dev)
+void comedi_switch_to_non_rt(struct comedi_device *dev)
 {
 	struct comedi_irq_struct *it;
 	unsigned long flags;
@@ -170,7 +170,7 @@
 	wake_up_interruptible((wait_queue_head_t *) arg2);
 }
 
-void comedi_rt_pend_wakeup(wait_queue_head_t * q)
+void comedi_rt_pend_wakeup(wait_queue_head_t *q)
 {
 	rt_pend_call(wake_up_int_handler, 0, q);
 }
@@ -180,7 +180,7 @@
 
 #ifndef HAVE_RT_REQUEST_IRQ_WITH_ARG
 #define DECLARE_VOID_IRQ(irq) \
-static void handle_void_irq_ ## irq (void){ handle_void_irq(irq);}
+static void handle_void_irq_ ## irq (void){ handle_void_irq(irq); }
 
 static void handle_void_irq(int irq)
 {
@@ -192,7 +192,7 @@
 		return;
 	}
 	it->handler(irq, it->dev_id PT_REGS_NULL);
-	rt_enable_irq(irq);	//needed by rtai-adeos, seems like it shouldn't hurt earlier versions
+	rt_enable_irq(irq);	/* needed by rtai-adeos, seems like it shouldn't hurt earlier versions */
 }
 
 DECLARE_VOID_IRQ(0);
@@ -220,8 +220,7 @@
 DECLARE_VOID_IRQ(22);
 DECLARE_VOID_IRQ(23);
 
-typedef void (*V_FP_V) (void);
-static V_FP_V handle_void_irq_ptrs[] = {
+static void handle_void_irq_ptrs[] = {
 	handle_void_irq_0,
 	handle_void_irq_1,
 	handle_void_irq_2,
@@ -402,11 +401,11 @@
 
 void comedi_rt_init(void)
 {
-	//rt_pend_tq_init();
+	/* rt_pend_tq_init(); */
 }
 
 void comedi_rt_cleanup(void)
 {
-	//rt_pend_tq_cleanup();
+	/* rt_pend_tq_cleanup(); */
 }
 #endif
diff --git a/drivers/staging/comedi/rt_pend_tq.c b/drivers/staging/comedi/rt_pend_tq.c
index 995f076..f9dfd9d 100644
--- a/drivers/staging/comedi/rt_pend_tq.c
+++ b/drivers/staging/comedi/rt_pend_tq.c
@@ -3,7 +3,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
-#include "comedidev.h"	// for rt spinlocks
+#include "comedidev.h"	/* for rt spinlocks */
 #include "rt_pend_tq.h"
 #ifdef CONFIG_COMEDI_RTAI
 #include <rtai.h>
@@ -25,9 +25,9 @@
 volatile static struct rt_pend_tq *volatile rt_pend_head = rt_pend_tq,
 	*volatile rt_pend_tail = rt_pend_tq;
 int rt_pend_tq_irq = 0;
-spinlock_t rt_pend_tq_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(rt_pend_tq_lock);
 
-// WARNING: following code not checked against race conditions yet.
+/* WARNING: following code not checked against race conditions yet. */
 #define INC_CIRCULAR_PTR(ptr,begin,size) do {if(++(ptr)>=(begin)+(size)) (ptr)=(begin); } while(0)
 #define DEC_CIRCULAR_PTR(ptr,begin,size) do {if(--(ptr)<(begin)) (ptr)=(begin)+(size)-1; } while(0)
 
@@ -42,7 +42,7 @@
 	comedi_spin_lock_irqsave(&rt_pend_tq_lock, flags);
 	INC_CIRCULAR_PTR(rt_pend_head, rt_pend_tq, RT_PEND_TQ_SIZE);
 	if (rt_pend_head == rt_pend_tail) {
-		// overflow, we just refuse to take this request
+		/* overflow, we just refuse to take this request */
 		DEC_CIRCULAR_PTR(rt_pend_head, rt_pend_tq, RT_PEND_TQ_SIZE);
 		comedi_spin_unlock_irqrestore(&rt_pend_tq_lock, flags);
 		return -EAGAIN;
diff --git a/drivers/staging/dst/Kconfig b/drivers/staging/dst/Kconfig
new file mode 100644
index 0000000..448d342a
--- /dev/null
+++ b/drivers/staging/dst/Kconfig
@@ -0,0 +1,67 @@
+config DST
+	tristate "Distributed storage"
+	depends on NET && CRYPTO && SYSFS && BLK_DEV
+	select CONNECTOR
+	---help---
+	DST is a network block device storage, which can be used to organize
+	exported storage on the remote nodes into the local block device.
+
+	DST works on top of any network media and protocol; it is just a matter
+	of configuration utility to understand the correct addresses. The most
+	common example is TCP over IP, which allows to pass through firewalls and
+	create remote backup storage in a different datacenter. DST requires
+	single port to be enabled on the exporting node and outgoing connections
+	on the local node.
+
+	DST works with in-kernel client and server, which improves performance by
+	eliminating unneded data copies and by not depending on the version
+	of the external IO components. It requires userspace configuration utility
+	though.
+
+	DST uses transaction model, when each store has to be explicitly acked
+	from the remote node to be considered as successfully written. There
+	may be lots of in-flight transactions. When remote host does not ack
+	the transaction it will be resent predefined number of times with specified
+	timeouts between them. All those parameters are configurable. Transactions
+	are marked as failed after all resends complete unsuccessfully; having
+	long enough resend timeout and/or large number of resends allows not to
+	return error to the higher (FS usually) layer in case of short network
+	problems or remote node outages. In case of network RAID setup this means
+	that storage will not degrade until transactions are marked as failed, and
+	thus will not force checksum recalculation and data rebuild. In case of
+	connection failure DST will try to reconnect to the remote node automatically.
+	DST sends ping commands at idle time to detect if remote node is alive.
+
+	Because of transactional model it is possible to use zero-copy sending
+	without worry of data corruption (which in turn could be detected by the
+	strong checksums though).
+
+	DST may fully encrypt the data channel in case of untrusted channel and implement
+	strong checksum of the transferred data. It is possible to configure algorithms
+	and crypto keys; they should match on both sides of the network channel.
+	Crypto processing does not introduce noticeble performance overhead, since DST
+	uses configurable pool of threads to perform crypto processing.
+
+	DST utilizes memory pool model of all its transaction allocations (it is the
+	only additional allocation on the client) and server allocations (bio pools,
+	while pages are allocated from the slab).
+
+	At startup DST performs a simple negotiation with the export node to determine
+	access permissions and size of the exported storage. It can be extended if
+	new parameters should be autonegotiated.
+
+	DST carries block IO flags in the protocol, which allows to transparently implement
+	barriers and sync/flush operations. Those flags are used in the export node where
+	IO against the local storage is performed, which means that sync write will be sync
+	on the remote node too, which in turn improves data integrity and improved resistance
+	to errors and data corruption during power outages or storage damages.
+
+	Homepage: http://www.ioremap.net/projects/dst
+	Userspace configuration utility and the latest releases: http://www.ioremap.net/archive/dst/
+
+config DST_DEBUG
+	bool "DST debug"
+	depends on DST
+	---help---
+	This option will enable HEAVY debugging of the DST.
+	Turn it on ONLY if you have to debug some really obscure problem.
diff --git a/drivers/staging/dst/Makefile b/drivers/staging/dst/Makefile
new file mode 100644
index 0000000..3a8b0cf
--- /dev/null
+++ b/drivers/staging/dst/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_DST) += nst.o
+
+nst-y := dcore.o state.o export.o thread_pool.o crypto.o trans.o
diff --git a/drivers/staging/dst/crypto.c b/drivers/staging/dst/crypto.c
new file mode 100644
index 0000000..7250f90
--- /dev/null
+++ b/drivers/staging/dst/crypto.c
@@ -0,0 +1,731 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * 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.
+ *
+ * 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/bio.h>
+#include <linux/crypto.h>
+#include <linux/dst.h>
+#include <linux/kernel.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+
+/*
+ * Tricky bastard, but IV can be more complex with time...
+ */
+static inline u64 dst_gen_iv(struct dst_trans *t)
+{
+	return t->gen;
+}
+
+/*
+ * Crypto machinery: hash/cipher support for the given crypto controls.
+ */
+static struct crypto_hash *dst_init_hash(struct dst_crypto_ctl *ctl, u8 *key)
+{
+	int err;
+	struct crypto_hash *hash;
+
+	hash = crypto_alloc_hash(ctl->hash_algo, 0, CRYPTO_ALG_ASYNC);
+	if (IS_ERR(hash)) {
+		err = PTR_ERR(hash);
+		dprintk("%s: failed to allocate hash '%s', err: %d.\n",
+				__func__, ctl->hash_algo, err);
+		goto err_out_exit;
+	}
+
+	ctl->crypto_attached_size = crypto_hash_digestsize(hash);
+
+	if (!ctl->hash_keysize)
+		return hash;
+
+	err = crypto_hash_setkey(hash, key, ctl->hash_keysize);
+	if (err) {
+		dprintk("%s: failed to set key for hash '%s', err: %d.\n",
+				__func__, ctl->hash_algo, err);
+		goto err_out_free;
+	}
+
+	return hash;
+
+err_out_free:
+	crypto_free_hash(hash);
+err_out_exit:
+	return ERR_PTR(err);
+}
+
+static struct crypto_ablkcipher *dst_init_cipher(struct dst_crypto_ctl *ctl, u8 *key)
+{
+	int err = -EINVAL;
+	struct crypto_ablkcipher *cipher;
+
+	if (!ctl->cipher_keysize)
+		goto err_out_exit;
+
+	cipher = crypto_alloc_ablkcipher(ctl->cipher_algo, 0, 0);
+	if (IS_ERR(cipher)) {
+		err = PTR_ERR(cipher);
+		dprintk("%s: failed to allocate cipher '%s', err: %d.\n",
+				__func__, ctl->cipher_algo, err);
+		goto err_out_exit;
+	}
+
+	crypto_ablkcipher_clear_flags(cipher, ~0);
+
+	err = crypto_ablkcipher_setkey(cipher, key, ctl->cipher_keysize);
+	if (err) {
+		dprintk("%s: failed to set key for cipher '%s', err: %d.\n",
+				__func__, ctl->cipher_algo, err);
+		goto err_out_free;
+	}
+
+	return cipher;
+
+err_out_free:
+	crypto_free_ablkcipher(cipher);
+err_out_exit:
+	return ERR_PTR(err);
+}
+
+/*
+ * Crypto engine has a pool of pages to encrypt data into before sending
+ * it over the network. This pool is freed/allocated here.
+ */
+static void dst_crypto_pages_free(struct dst_crypto_engine *e)
+{
+	unsigned int i;
+
+	for (i=0; i<e->page_num; ++i)
+		__free_page(e->pages[i]);
+	kfree(e->pages);
+}
+
+static int dst_crypto_pages_alloc(struct dst_crypto_engine *e, int num)
+{
+	int i;
+
+	e->pages = kmalloc(num * sizeof(struct page **), GFP_KERNEL);
+	if (!e->pages)
+		return -ENOMEM;
+
+	for (i=0; i<num; ++i) {
+		e->pages[i] = alloc_page(GFP_KERNEL);
+		if (!e->pages[i])
+			goto err_out_free_pages;
+	}
+
+	e->page_num = num;
+	return 0;
+
+err_out_free_pages:
+	while (--i >= 0)
+		__free_page(e->pages[i]);
+
+	kfree(e->pages);
+	return -ENOMEM;
+}
+
+/*
+ * Initialize crypto engine for given node.
+ * Setup cipher/hash, keys, pool of threads and private data.
+ */
+static int dst_crypto_engine_init(struct dst_crypto_engine *e, struct dst_node *n)
+{
+	int err;
+	struct dst_crypto_ctl *ctl = &n->crypto;
+
+	err = dst_crypto_pages_alloc(e, n->max_pages);
+	if (err)
+		goto err_out_exit;
+
+	e->size = PAGE_SIZE;
+	e->data = kmalloc(e->size, GFP_KERNEL);
+	if (!e->data) {
+		err = -ENOMEM;
+		goto err_out_free_pages;
+	}
+
+	if (ctl->hash_algo[0]) {
+		e->hash = dst_init_hash(ctl, n->hash_key);
+		if (IS_ERR(e->hash)) {
+			err = PTR_ERR(e->hash);
+			e->hash = NULL;
+			goto err_out_free;
+		}
+	}
+
+	if (ctl->cipher_algo[0]) {
+		e->cipher = dst_init_cipher(ctl, n->cipher_key);
+		if (IS_ERR(e->cipher)) {
+			err = PTR_ERR(e->cipher);
+			e->cipher = NULL;
+			goto err_out_free_hash;
+		}
+	}
+
+	return 0;
+
+err_out_free_hash:
+	crypto_free_hash(e->hash);
+err_out_free:
+	kfree(e->data);
+err_out_free_pages:
+	dst_crypto_pages_free(e);
+err_out_exit:
+	return err;
+}
+
+static void dst_crypto_engine_exit(struct dst_crypto_engine *e)
+{
+	if (e->hash)
+		crypto_free_hash(e->hash);
+	if (e->cipher)
+		crypto_free_ablkcipher(e->cipher);
+	dst_crypto_pages_free(e);
+	kfree(e->data);
+}
+
+/*
+ * Waiting for cipher processing to be completed.
+ */
+struct dst_crypto_completion
+{
+	struct completion		complete;
+	int				error;
+};
+
+static void dst_crypto_complete(struct crypto_async_request *req, int err)
+{
+	struct dst_crypto_completion *c = req->data;
+
+	if (err == -EINPROGRESS)
+		return;
+
+	dprintk("%s: req: %p, err: %d.\n", __func__, req, err);
+	c->error = err;
+	complete(&c->complete);
+}
+
+static int dst_crypto_process(struct ablkcipher_request *req,
+		struct scatterlist *sg_dst, struct scatterlist *sg_src,
+		void *iv, int enc, unsigned long timeout)
+{
+	struct dst_crypto_completion c;
+	int err;
+
+	init_completion(&c.complete);
+	c.error = -EINPROGRESS;
+
+	ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+					dst_crypto_complete, &c);
+
+	ablkcipher_request_set_crypt(req, sg_src, sg_dst, sg_src->length, iv);
+
+	if (enc)
+		err = crypto_ablkcipher_encrypt(req);
+	else
+		err = crypto_ablkcipher_decrypt(req);
+
+	switch (err) {
+		case -EINPROGRESS:
+		case -EBUSY:
+			err = wait_for_completion_interruptible_timeout(&c.complete,
+					timeout);
+			if (!err)
+				err = -ETIMEDOUT;
+			else
+				err = c.error;
+			break;
+		default:
+			break;
+	}
+
+	return err;
+}
+
+/*
+ * DST uses generic iteration approach for data crypto processing.
+ * Single block IO request is switched into array of scatterlists,
+ * which are submitted to the crypto processing iterator.
+ *
+ * Input and output iterator initialization are different, since
+ * in output case we can not encrypt data in-place and need a
+ * temporary storage, which is then being sent to the remote peer.
+ */
+static int dst_trans_iter_out(struct bio *bio, struct dst_crypto_engine *e,
+		int (* iterator) (struct dst_crypto_engine *e,
+				  struct scatterlist *dst,
+				  struct scatterlist *src))
+{
+	struct bio_vec *bv;
+	int err, i;
+
+	sg_init_table(e->src, bio->bi_vcnt);
+	sg_init_table(e->dst, bio->bi_vcnt);
+
+	bio_for_each_segment(bv, bio, i) {
+		sg_set_page(&e->src[i], bv->bv_page, bv->bv_len, bv->bv_offset);
+		sg_set_page(&e->dst[i], e->pages[i], bv->bv_len, bv->bv_offset);
+
+		err = iterator(e, &e->dst[i], &e->src[i]);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
+static int dst_trans_iter_in(struct bio *bio, struct dst_crypto_engine *e,
+		int (* iterator) (struct dst_crypto_engine *e,
+				  struct scatterlist *dst,
+				  struct scatterlist *src))
+{
+	struct bio_vec *bv;
+	int err, i;
+
+	sg_init_table(e->src, bio->bi_vcnt);
+	sg_init_table(e->dst, bio->bi_vcnt);
+
+	bio_for_each_segment(bv, bio, i) {
+		sg_set_page(&e->src[i], bv->bv_page, bv->bv_len, bv->bv_offset);
+		sg_set_page(&e->dst[i], bv->bv_page, bv->bv_len, bv->bv_offset);
+
+		err = iterator(e, &e->dst[i], &e->src[i]);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
+static int dst_crypt_iterator(struct dst_crypto_engine *e,
+		struct scatterlist *sg_dst, struct scatterlist *sg_src)
+{
+	struct ablkcipher_request *req = e->data;
+	u8 iv[32];
+
+	memset(iv, 0, sizeof(iv));
+
+	memcpy(iv, &e->iv, sizeof(e->iv));
+
+	return dst_crypto_process(req, sg_dst, sg_src, iv, e->enc, e->timeout);
+}
+
+static int dst_crypt(struct dst_crypto_engine *e, struct bio *bio)
+{
+	struct ablkcipher_request *req = e->data;
+
+	memset(req, 0, sizeof(struct ablkcipher_request));
+	ablkcipher_request_set_tfm(req, e->cipher);
+
+	if (e->enc)
+		return dst_trans_iter_out(bio, e, dst_crypt_iterator);
+	else
+		return dst_trans_iter_in(bio, e, dst_crypt_iterator);
+}
+
+static int dst_hash_iterator(struct dst_crypto_engine *e,
+		struct scatterlist *sg_dst, struct scatterlist *sg_src)
+{
+	return crypto_hash_update(e->data, sg_src, sg_src->length);
+}
+
+static int dst_hash(struct dst_crypto_engine *e, struct bio *bio, void *dst)
+{
+	struct hash_desc *desc = e->data;
+	int err;
+
+	desc->tfm = e->hash;
+	desc->flags = 0;
+
+	err = crypto_hash_init(desc);
+	if (err)
+		return err;
+
+	err = dst_trans_iter_in(bio, e, dst_hash_iterator);
+	if (err)
+		return err;
+
+	err = crypto_hash_final(desc, dst);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+/*
+ * Initialize/cleanup a crypto thread. The only thing it should
+ * do is to allocate a pool of pages as temporary storage.
+ * And to setup cipher and/or hash.
+ */
+static void *dst_crypto_thread_init(void *data)
+{
+	struct dst_node *n = data;
+	struct dst_crypto_engine *e;
+	int err = -ENOMEM;
+
+	e = kzalloc(sizeof(struct dst_crypto_engine), GFP_KERNEL);
+	if (!e)
+		goto err_out_exit;
+	e->src = kcalloc(2 * n->max_pages, sizeof(struct scatterlist),
+			GFP_KERNEL);
+	if (!e->src)
+		goto err_out_free;
+
+	e->dst = e->src + n->max_pages;
+
+	err = dst_crypto_engine_init(e, n);
+	if (err)
+		goto err_out_free_all;
+
+	return e;
+
+err_out_free_all:
+	kfree(e->src);
+err_out_free:
+	kfree(e);
+err_out_exit:
+	return ERR_PTR(err);
+}
+
+static void dst_crypto_thread_cleanup(void *private)
+{
+	struct dst_crypto_engine *e = private;
+
+	dst_crypto_engine_exit(e);
+	kfree(e->src);
+	kfree(e);
+}
+
+/*
+ * Initialize crypto engine for given node: store keys, create pool
+ * of threads, initialize each one.
+ *
+ * Each thread has unique ID, but 0 and 1 are reserved for receiving and accepting
+ * threads (if export node), so IDs could start from 2, but starting them
+ * from 10 allows easily understand what this thread is for.
+ */
+int dst_node_crypto_init(struct dst_node *n, struct dst_crypto_ctl *ctl)
+{
+	void *key = (ctl + 1);
+	int err = -ENOMEM, i;
+	char name[32];
+
+	if (ctl->hash_keysize) {
+		n->hash_key = kmalloc(ctl->hash_keysize, GFP_KERNEL);
+		if (!n->hash_key)
+			goto err_out_exit;
+		memcpy(n->hash_key, key, ctl->hash_keysize);
+	}
+
+	if (ctl->cipher_keysize) {
+		n->cipher_key = kmalloc(ctl->cipher_keysize, GFP_KERNEL);
+		if (!n->cipher_key)
+			goto err_out_free_hash;
+		memcpy(n->cipher_key, key, ctl->cipher_keysize);
+	}
+	memcpy(&n->crypto, ctl, sizeof(struct dst_crypto_ctl));
+
+	for (i=0; i<ctl->thread_num; ++i) {
+		snprintf(name, sizeof(name), "%s-crypto-%d", n->name, i);
+		/* Unique ids... */
+		err = thread_pool_add_worker(n->pool, name, i+10,
+			dst_crypto_thread_init, dst_crypto_thread_cleanup, n);
+		if (err)
+			goto err_out_free_threads;
+	}
+
+	return 0;
+
+err_out_free_threads:
+	while (--i >= 0)
+		thread_pool_del_worker_id(n->pool, i+10);
+
+	if (ctl->cipher_keysize)
+		kfree(n->cipher_key);
+	ctl->cipher_keysize = 0;
+err_out_free_hash:
+	if (ctl->hash_keysize)
+		kfree(n->hash_key);
+	ctl->hash_keysize = 0;
+err_out_exit:
+	return err;
+}
+
+void dst_node_crypto_exit(struct dst_node *n)
+{
+	struct dst_crypto_ctl *ctl = &n->crypto;
+
+	if (ctl->cipher_algo[0] || ctl->hash_algo[0]) {
+		kfree(n->hash_key);
+		kfree(n->cipher_key);
+	}
+}
+
+/*
+ * Thrad pool setup callback. Just stores a transaction in private data.
+ */
+static int dst_trans_crypto_setup(void *crypto_engine, void *trans)
+{
+	struct dst_crypto_engine *e = crypto_engine;
+
+	e->private = trans;
+	return 0;
+}
+
+#if 0
+static void dst_dump_bio(struct bio *bio)
+{
+	u8 *p;
+	struct bio_vec *bv;
+	int i;
+
+	bio_for_each_segment(bv, bio, i) {
+		dprintk("%s: %llu/%u: size: %u, offset: %u, data: ",
+				__func__, bio->bi_sector, bio->bi_size,
+				bv->bv_len, bv->bv_offset);
+
+		p = kmap(bv->bv_page) + bv->bv_offset;
+		for (i=0; i<bv->bv_len; ++i)
+			printk("%02x ", p[i]);
+		kunmap(bv->bv_page);
+		printk("\n");
+	}
+}
+#endif
+
+/*
+ * Encrypt/hash data and send it to the network.
+ */
+static int dst_crypto_process_sending(struct dst_crypto_engine *e,
+		struct bio *bio, u8 *hash)
+{
+	int err;
+
+	if (e->cipher) {
+		err = dst_crypt(e, bio);
+		if (err)
+			goto err_out_exit;
+	}
+
+	if (e->hash) {
+		err = dst_hash(e, bio, hash);
+		if (err)
+			goto err_out_exit;
+
+#ifdef CONFIG_DST_DEBUG
+		{
+			unsigned int i;
+
+			/* dst_dump_bio(bio); */
+
+			printk(KERN_DEBUG "%s: bio: %llu/%u, rw: %lu, hash: ",
+				__func__, (u64)bio->bi_sector,
+				bio->bi_size, bio_data_dir(bio));
+			for (i=0; i<crypto_hash_digestsize(e->hash); ++i)
+					printk("%02x ", hash[i]);
+			printk("\n");
+		}
+#endif
+	}
+
+	return 0;
+
+err_out_exit:
+	return err;
+}
+
+/*
+ * Check if received data is valid. Decipher if it is.
+ */
+static int dst_crypto_process_receiving(struct dst_crypto_engine *e,
+		struct bio *bio, u8 *hash, u8 *recv_hash)
+{
+	int err;
+
+	if (e->hash) {
+		int mismatch;
+
+		err = dst_hash(e, bio, hash);
+		if (err)
+			goto err_out_exit;
+
+		mismatch = !!memcmp(recv_hash, hash,
+				crypto_hash_digestsize(e->hash));
+#ifdef CONFIG_DST_DEBUG
+		/* dst_dump_bio(bio); */
+
+		printk(KERN_DEBUG "%s: bio: %llu/%u, rw: %lu, hash mismatch: %d",
+			__func__, (u64)bio->bi_sector, bio->bi_size,
+			bio_data_dir(bio), mismatch);
+		if (mismatch) {
+			unsigned int i;
+
+			printk(", recv/calc: ");
+			for (i=0; i<crypto_hash_digestsize(e->hash); ++i) {
+				printk("%02x/%02x ", recv_hash[i], hash[i]);
+			}
+		}
+		printk("\n");
+#endif
+		err = -1;
+		if (mismatch)
+			goto err_out_exit;
+	}
+
+	if (e->cipher) {
+		err = dst_crypt(e, bio);
+		if (err)
+			goto err_out_exit;
+	}
+
+	return 0;
+
+err_out_exit:
+	return err;
+}
+
+/*
+ * Thread pool callback to encrypt data and send it to the netowork.
+ */
+static int dst_trans_crypto_action(void *crypto_engine, void *schedule_data)
+{
+	struct dst_crypto_engine *e = crypto_engine;
+	struct dst_trans *t = schedule_data;
+	struct bio *bio = t->bio;
+	int err;
+
+	dprintk("%s: t: %p, gen: %llu, cipher: %p, hash: %p.\n",
+			__func__, t, t->gen, e->cipher, e->hash);
+
+	e->enc = t->enc;
+	e->iv = dst_gen_iv(t);
+
+	if (bio_data_dir(bio) == WRITE) {
+		err = dst_crypto_process_sending(e, bio, t->cmd.hash);
+		if (err)
+			goto err_out_exit;
+
+		if (e->hash) {
+			t->cmd.csize = crypto_hash_digestsize(e->hash);
+			t->cmd.size += t->cmd.csize;
+		}
+
+		return dst_trans_send(t);
+	} else {
+		u8 *hash = e->data + e->size/2;
+
+		err = dst_crypto_process_receiving(e, bio, hash, t->cmd.hash);
+		if (err)
+			goto err_out_exit;
+
+		dst_trans_remove(t);
+		dst_trans_put(t);
+	}
+
+	return 0;
+
+err_out_exit:
+	t->error = err;
+	dst_trans_put(t);
+	return err;
+}
+
+/*
+ * Schedule crypto processing for given transaction.
+ */
+int dst_trans_crypto(struct dst_trans *t)
+{
+	struct dst_node *n = t->n;
+	int err;
+
+	err = thread_pool_schedule(n->pool,
+		dst_trans_crypto_setup, dst_trans_crypto_action,
+		t, MAX_SCHEDULE_TIMEOUT);
+	if (err)
+		goto err_out_exit;
+
+	return 0;
+
+err_out_exit:
+	dst_trans_put(t);
+	return err;
+}
+
+/*
+ * Crypto machinery for the export node.
+ */
+static int dst_export_crypto_setup(void *crypto_engine, void *bio)
+{
+	struct dst_crypto_engine *e = crypto_engine;
+
+	e->private = bio;
+	return 0;
+}
+
+static int dst_export_crypto_action(void *crypto_engine, void *schedule_data)
+{
+	struct dst_crypto_engine *e = crypto_engine;
+	struct bio *bio = schedule_data;
+	struct dst_export_priv *p = bio->bi_private;
+	int err;
+
+	dprintk("%s: e: %p, data: %p, bio: %llu/%u, dir: %lu.\n", __func__,
+		e, e->data, (u64)bio->bi_sector, bio->bi_size, bio_data_dir(bio));
+
+	e->enc = (bio_data_dir(bio) == READ);
+	e->iv = p->cmd.id;
+
+	if (bio_data_dir(bio) == WRITE) {
+		u8 *hash = e->data + e->size/2;
+
+		err = dst_crypto_process_receiving(e, bio, hash, p->cmd.hash);
+		if (err)
+			goto err_out_exit;
+
+		generic_make_request(bio);
+	} else {
+		err = dst_crypto_process_sending(e, bio, p->cmd.hash);
+		if (err)
+			goto err_out_exit;
+
+		if (e->hash) {
+			p->cmd.csize = crypto_hash_digestsize(e->hash);
+			p->cmd.size += p->cmd.csize;
+		}
+
+		err = dst_export_send_bio(bio);
+	}
+	return 0;
+
+err_out_exit:
+	bio_put(bio);
+	return err;
+}
+
+int dst_export_crypto(struct dst_node *n, struct bio *bio)
+{
+	int err;
+
+	err = thread_pool_schedule(n->pool,
+		dst_export_crypto_setup, dst_export_crypto_action,
+		bio, MAX_SCHEDULE_TIMEOUT);
+	if (err)
+		goto err_out_exit;
+
+	return 0;
+
+err_out_exit:
+	bio_put(bio);
+	return err;
+}
diff --git a/drivers/staging/dst/dcore.c b/drivers/staging/dst/dcore.c
new file mode 100644
index 0000000..fad25b7
--- /dev/null
+++ b/drivers/staging/dst/dcore.c
@@ -0,0 +1,995 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * 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.
+ *
+ * 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/module.h>
+#include <linux/kernel.h>
+#include <linux/blkdev.h>
+#include <linux/bio.h>
+#include <linux/buffer_head.h>
+#include <linux/connector.h>
+#include <linux/dst.h>
+#include <linux/device.h>
+#include <linux/jhash.h>
+#include <linux/idr.h>
+#include <linux/init.h>
+#include <linux/namei.h>
+#include <linux/slab.h>
+#include <linux/socket.h>
+
+#include <linux/in.h>
+#include <linux/in6.h>
+
+#include <net/sock.h>
+
+static int dst_major;
+
+static DEFINE_MUTEX(dst_hash_lock);
+static struct list_head *dst_hashtable;
+static unsigned int dst_hashtable_size = 128;
+module_param(dst_hashtable_size, uint, 0644);
+
+static char dst_name[] = "Dementianting goldfish";
+
+static DEFINE_IDR(dst_index_idr);
+static struct cb_id cn_dst_id = { CN_DST_IDX, CN_DST_VAL };
+
+/*
+ * DST sysfs tree for device called 'storage':
+ *
+ * /sys/bus/dst/devices/storage/
+ * /sys/bus/dst/devices/storage/type : 192.168.4.80:1025
+ * /sys/bus/dst/devices/storage/size : 800
+ * /sys/bus/dst/devices/storage/name : storage
+ */
+
+static int dst_dev_match(struct device *dev, struct device_driver *drv)
+{
+	return 1;
+}
+
+static struct bus_type dst_dev_bus_type = {
+	.name 		= "dst",
+	.match 		= &dst_dev_match,
+};
+
+static void dst_node_release(struct device *dev)
+{
+	struct dst_info *info = container_of(dev, struct dst_info, device);
+
+	kfree(info);
+}
+
+static struct device dst_node_dev = {
+	.bus 		= &dst_dev_bus_type,
+	.release 	= &dst_node_release
+};
+
+/*
+ * Setting size of the node after it was changed.
+ */
+static void dst_node_set_size(struct dst_node *n)
+{
+	struct block_device *bdev;
+
+	set_capacity(n->disk, n->size >> 9);
+
+	bdev = bdget_disk(n->disk, 0);
+	if (bdev) {
+		mutex_lock(&bdev->bd_inode->i_mutex);
+		i_size_write(bdev->bd_inode, n->size);
+		mutex_unlock(&bdev->bd_inode->i_mutex);
+		bdput(bdev);
+	}
+}
+
+/*
+ * Distributed storage request processing function.
+ */
+static int dst_request(struct request_queue *q, struct bio *bio)
+{
+	struct dst_node *n = q->queuedata;
+	int err = -EIO;
+
+	if (bio_empty_barrier(bio) && !q->prepare_discard_fn) {
+		/*
+		 * This is a dirty^Wnice hack, but if we complete this
+		 * operation with -EOPNOTSUPP like intended, XFS
+		 * will stuck and freeze the machine. This may be
+		 * not particulary XFS problem though, but it is the
+		 * only FS which sends empty barrier at umount time
+		 * I worked with.
+		 *
+		 * Empty barriers are not allowed anyway, see 51fd77bd9f512
+		 * for example, although later it was changed to bio_discard()
+		 * only, which does not work in this case.
+		 */
+		//err = -EOPNOTSUPP;
+		err = 0;
+		goto end_io;
+	}
+
+	bio_get(bio);
+
+	return dst_process_bio(n, bio);
+
+end_io:
+	bio_endio(bio, err);
+	return err;
+}
+
+/*
+ * Open/close callbacks for appropriate block device.
+ */
+static int dst_bdev_open(struct block_device *bdev, fmode_t mode)
+{
+	struct dst_node *n = bdev->bd_disk->private_data;
+
+	dst_node_get(n);
+	return 0;
+}
+
+static int dst_bdev_release(struct gendisk *disk, fmode_t mode)
+{
+	struct dst_node *n = disk->private_data;
+
+	dst_node_put(n);
+	return 0;
+}
+
+static struct block_device_operations dst_blk_ops = {
+	.open		= dst_bdev_open,
+	.release	= dst_bdev_release,
+	.owner		= THIS_MODULE,
+};
+
+/*
+ * Block layer binding - disk is created when array is fully configured
+ * by userspace request.
+ */
+static int dst_node_create_disk(struct dst_node *n)
+{
+	int err = -ENOMEM;
+	u32 index = 0;
+
+	n->queue = blk_init_queue(NULL, NULL);
+	if (!n->queue)
+		goto err_out_exit;
+
+	n->queue->queuedata = n;
+	blk_queue_make_request(n->queue, dst_request);
+	blk_queue_max_phys_segments(n->queue, n->max_pages);
+	blk_queue_max_hw_segments(n->queue, n->max_pages);
+
+	err = -ENOMEM;
+	n->disk = alloc_disk(1);
+	if (!n->disk)
+		goto err_out_free_queue;
+
+	if (!(n->state->permissions & DST_PERM_WRITE)) {
+		printk(KERN_INFO "DST node %s attached read-only.\n", n->name);
+		set_disk_ro(n->disk, 1);
+	}
+
+	if (!idr_pre_get(&dst_index_idr, GFP_KERNEL))
+		goto err_out_put;
+
+	mutex_lock(&dst_hash_lock);
+	err = idr_get_new(&dst_index_idr, NULL, &index);
+	mutex_unlock(&dst_hash_lock);
+	if (err)
+		goto err_out_put;
+
+	n->disk->major = dst_major;
+	n->disk->first_minor = index;
+	n->disk->fops = &dst_blk_ops;
+	n->disk->queue = n->queue;
+	n->disk->private_data = n;
+	snprintf(n->disk->disk_name, sizeof(n->disk->disk_name), "dst-%s", n->name);
+
+	return 0;
+
+err_out_put:
+	put_disk(n->disk);
+err_out_free_queue:
+	blk_cleanup_queue(n->queue);
+err_out_exit:
+	return err;
+}
+
+/*
+ * Sysfs machinery: show device's size.
+ */
+static ssize_t dst_show_size(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct dst_info *info = container_of(dev, struct dst_info, device);
+
+	return sprintf(buf, "%llu\n", info->size);
+}
+
+/*
+ * Show local exported device.
+ */
+static ssize_t dst_show_local(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct dst_info *info = container_of(dev, struct dst_info, device);
+
+	return sprintf(buf, "%s\n", info->local);
+}
+
+/*
+ * Shows type of the remote node - device major/minor number
+ * for local nodes and address (af_inet ipv4/ipv6 only) for remote nodes.
+ */
+static ssize_t dst_show_type(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct dst_info *info = container_of(dev, struct dst_info, device);
+	int family = info->net.addr.sa_family;
+
+	if (family == AF_INET) {
+		struct sockaddr_in *sin = (struct sockaddr_in *)&info->net.addr;
+		return sprintf(buf, "%u.%u.%u.%u:%d\n",
+			NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
+	} else if (family == AF_INET6) {
+		struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&info->net.addr;
+		return sprintf(buf,
+			"%pi6:%d\n",
+			&sin->sin6_addr, ntohs(sin->sin6_port));
+	} else {
+		int i, sz = PAGE_SIZE - 2; /* 0 symbol and '\n' below */
+		int size, addrlen = info->net.addr.sa_data_len;
+		unsigned char *a = (unsigned char *)&info->net.addr.sa_data;
+		char *buf_orig = buf;
+
+		size = snprintf(buf, sz, "family: %d, addrlen: %u, addr: ",
+				family, addrlen);
+		sz -= size;
+		buf += size;
+
+		for (i=0; i<addrlen; ++i) {
+			if (sz < 3)
+				break;
+
+			size = snprintf(buf, sz, "%02x ", a[i]);
+			sz -= size;
+			buf += size;
+		}
+		buf += sprintf(buf, "\n");
+
+		return buf - buf_orig;
+	}
+	return 0;
+}
+
+static struct device_attribute dst_node_attrs[] = {
+	__ATTR(size, 0444, dst_show_size, NULL),
+	__ATTR(type, 0444, dst_show_type, NULL),
+	__ATTR(local, 0444, dst_show_local, NULL),
+};
+
+static int dst_create_node_attributes(struct dst_node *n)
+{
+	int err, i;
+
+	for (i=0; i<ARRAY_SIZE(dst_node_attrs); ++i) {
+		err = device_create_file(&n->info->device,
+				&dst_node_attrs[i]);
+		if (err)
+			goto err_out_remove_all;
+	}
+	return 0;
+
+err_out_remove_all:
+	while (--i >= 0)
+		device_remove_file(&n->info->device,
+				&dst_node_attrs[i]);
+
+	return err;
+}
+
+static void dst_remove_node_attributes(struct dst_node *n)
+{
+	int i;
+
+	for (i=0; i<ARRAY_SIZE(dst_node_attrs); ++i)
+		device_remove_file(&n->info->device,
+				&dst_node_attrs[i]);
+}
+
+/*
+ * Sysfs cleanup and initialization.
+ * Shows number of useful parameters.
+ */
+static void dst_node_sysfs_exit(struct dst_node *n)
+{
+	if (n->info) {
+		dst_remove_node_attributes(n);
+		device_unregister(&n->info->device);
+		n->info = NULL;
+	}
+}
+
+static int dst_node_sysfs_init(struct dst_node *n)
+{
+	int err;
+
+	n->info = kzalloc(sizeof(struct dst_info), GFP_KERNEL);
+	if (!n->info)
+		return -ENOMEM;
+
+	memcpy(&n->info->device, &dst_node_dev, sizeof(struct device));
+	n->info->size = n->size;
+
+	dev_set_name(&n->info->device, "dst-%s", n->name);
+	err = device_register(&n->info->device);
+	if (err) {
+		dprintk(KERN_ERR "Failed to register node '%s', err: %d.\n",
+				n->name, err);
+		goto err_out_exit;
+	}
+
+	dst_create_node_attributes(n);
+
+	return 0;
+
+err_out_exit:
+	kfree(n->info);
+	n->info = NULL;
+	return err;
+}
+
+/*
+ * DST node hash tables machinery.
+ */
+static inline unsigned int dst_hash(char *str, unsigned int size)
+{
+	return (jhash(str, size, 0) % dst_hashtable_size);
+}
+
+static void dst_node_remove(struct dst_node *n)
+{
+	mutex_lock(&dst_hash_lock);
+	list_del_init(&n->node_entry);
+	mutex_unlock(&dst_hash_lock);
+}
+
+static void dst_node_add(struct dst_node *n)
+{
+	unsigned hash = dst_hash(n->name, sizeof(n->name));
+
+	mutex_lock(&dst_hash_lock);
+	list_add_tail(&n->node_entry, &dst_hashtable[hash]);
+	mutex_unlock(&dst_hash_lock);
+}
+
+/*
+ * Cleaning node when it is about to be freed.
+ * There are still users of the socket though,
+ * so connection cleanup should be protected.
+ */
+static void dst_node_cleanup(struct dst_node *n)
+{
+	struct dst_state *st = n->state;
+
+	if (!st)
+		return;
+
+	if (n->queue) {
+		blk_cleanup_queue(n->queue);
+
+		mutex_lock(&dst_hash_lock);
+		idr_remove(&dst_index_idr, n->disk->first_minor);
+		mutex_unlock(&dst_hash_lock);
+
+		put_disk(n->disk);
+	}
+
+	if (n->bdev) {
+		sync_blockdev(n->bdev);
+		blkdev_put(n->bdev, FMODE_READ|FMODE_WRITE);
+	}
+
+	dst_state_lock(st);
+	st->need_exit = 1;
+	dst_state_exit_connected(st);
+	dst_state_unlock(st);
+
+	wake_up(&st->thread_wait);
+
+	dst_state_put(st);
+	n->state = NULL;
+}
+
+/*
+ * Free security attributes attached to given node.
+ */
+static void dst_security_exit(struct dst_node *n)
+{
+	struct dst_secure *s, *tmp;
+
+	list_for_each_entry_safe(s, tmp, &n->security_list, sec_entry) {
+		list_del(&s->sec_entry);
+		kfree(s);
+	}
+}
+
+/*
+ * Free node when there are no more users.
+ * Actually node has to be freed on behalf od userspace process,
+ * since there are number of threads, which are embedded in the
+ * node, so they can not exit and free node from there, that is
+ * why there is a wakeup if reference counter is not equal to zero.
+ */
+void dst_node_put(struct dst_node *n)
+{
+	if (unlikely(!n))
+		return;
+
+	dprintk("%s: n: %p, refcnt: %d.\n",
+			__func__, n, atomic_read(&n->refcnt));
+
+	if (atomic_dec_and_test(&n->refcnt)) {
+		dst_node_remove(n);
+		n->trans_scan_timeout = 0;
+		dst_node_cleanup(n);
+		thread_pool_destroy(n->pool);
+		dst_node_sysfs_exit(n);
+		dst_node_crypto_exit(n);
+		dst_security_exit(n);
+		dst_node_trans_exit(n);
+
+		kfree(n);
+
+		dprintk("%s: freed n: %p.\n", __func__, n);
+	} else {
+		wake_up(&n->wait);
+	}
+}
+
+/*
+ * This function finds devices major/minor numbers for given pathname.
+ */
+static int dst_lookup_device(const char *path, dev_t *dev)
+{
+	int err;
+	struct nameidata nd;
+	struct inode *inode;
+
+	err = path_lookup(path, LOOKUP_FOLLOW, &nd);
+	if (err)
+		return err;
+
+	inode = nd.path.dentry->d_inode;
+	if (!inode) {
+		err = -ENOENT;
+		goto out;
+	}
+
+	if (!S_ISBLK(inode->i_mode)) {
+		err = -ENOTBLK;
+		goto out;
+	}
+
+	*dev = inode->i_rdev;
+
+out:
+	path_put(&nd.path);
+	return err;
+}
+
+/*
+ * Setting up export device: lookup by the name, get its size
+ * and setup listening socket, which will accept clients, which
+ * will submit IO for given storage.
+ */
+static int dst_setup_export(struct dst_node *n, struct dst_ctl *ctl,
+		struct dst_export_ctl *le)
+{
+	int err;
+	dev_t dev = 0; /* gcc likes to scream here */
+
+	snprintf(n->info->local, sizeof(n->info->local), "%s", le->device);
+
+	err = dst_lookup_device(le->device, &dev);
+	if (err)
+		return err;
+
+	n->bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE);
+	if (!n->bdev)
+		return -ENODEV;
+
+	if (n->size != 0)
+		n->size = min_t(loff_t, n->bdev->bd_inode->i_size, n->size);
+	else
+		n->size = n->bdev->bd_inode->i_size;
+
+	n->info->size = n->size;
+	err = dst_node_init_listened(n, le);
+	if (err)
+		goto err_out_cleanup;
+
+	return 0;
+
+err_out_cleanup:
+	blkdev_put(n->bdev, FMODE_READ|FMODE_WRITE);
+	n->bdev = NULL;
+
+	return err;
+}
+
+/* Empty thread pool callbacks for the network processing threads. */
+static inline void *dst_thread_network_init(void *data)
+{
+	dprintk("%s: data: %p.\n", __func__, data);
+	return data;
+}
+
+static inline void dst_thread_network_cleanup(void *data)
+{
+	dprintk("%s: data: %p.\n", __func__, data);
+}
+
+/*
+ * Allocate DST node and initialize some of its parameters.
+ */
+static struct dst_node *dst_alloc_node(struct dst_ctl *ctl,
+		int (*start)(struct dst_node *),
+		int num)
+{
+	struct dst_node *n;
+	int err;
+
+	n = kzalloc(sizeof(struct dst_node), GFP_KERNEL);
+	if (!n)
+		return NULL;
+
+	INIT_LIST_HEAD(&n->node_entry);
+
+	INIT_LIST_HEAD(&n->security_list);
+	mutex_init(&n->security_lock);
+
+	init_waitqueue_head(&n->wait);
+
+	n->trans_scan_timeout = msecs_to_jiffies(ctl->trans_scan_timeout);
+	if (!n->trans_scan_timeout)
+		n->trans_scan_timeout = HZ;
+
+	n->trans_max_retries = ctl->trans_max_retries;
+	if (!n->trans_max_retries)
+		n->trans_max_retries = 10;
+
+	/*
+	 * Pretty much arbitrary default numbers.
+	 * 32 matches maximum number of pages in bio originated from ext3 (31).
+	 */
+	n->max_pages = ctl->max_pages;
+	if (!n->max_pages)
+		n->max_pages = 32;
+
+	if (n->max_pages > 1024)
+		n->max_pages = 1024;
+
+	n->start = start;
+	n->size = ctl->size;
+
+	atomic_set(&n->refcnt, 1);
+	atomic_long_set(&n->gen, 0);
+	snprintf(n->name, sizeof(n->name), "%s", ctl->name);
+
+	err = dst_node_sysfs_init(n);
+	if (err)
+		goto err_out_free;
+
+	n->pool = thread_pool_create(num, n->name, dst_thread_network_init,
+			dst_thread_network_cleanup, n);
+	if (IS_ERR(n->pool)) {
+		err = PTR_ERR(n->pool);
+		goto err_out_sysfs_exit;
+	}
+
+	dprintk("%s: n: %p, name: %s.\n", __func__, n, n->name);
+
+	return n;
+
+err_out_sysfs_exit:
+	dst_node_sysfs_exit(n);
+err_out_free:
+	kfree(n);
+	return NULL;
+}
+
+/*
+ * Starting a node, connected to the remote server:
+ * register block device and initialize transaction mechanism.
+ * In revers order though.
+ *
+ * It will autonegotiate some parameters with the remote node
+ * and update local if needed.
+ *
+ * Transaction initialization should be the last thing before
+ * starting the node, since transaction should include not only
+ * block IO, but also crypto related data (if any), which are
+ * initialized separately.
+ */
+static int dst_start_remote(struct dst_node *n)
+{
+	int err;
+
+	err = dst_node_trans_init(n, sizeof(struct dst_trans));
+	if (err)
+		return err;
+
+	err = dst_node_create_disk(n);
+	if (err)
+		return err;
+
+	dst_node_set_size(n);
+	add_disk(n->disk);
+
+	dprintk("DST: started remote node '%s', minor: %d.\n", n->name, n->disk->first_minor);
+
+	return 0;
+}
+
+/*
+ * Adding remote node and initialize connection.
+ */
+static int dst_add_remote(struct dst_node *n, struct dst_ctl *ctl,
+		void *data, unsigned int size)
+{
+	int err;
+	struct dst_network_ctl *rctl = data;
+
+	if (n)
+		return -EEXIST;
+
+	if (size != sizeof(struct dst_network_ctl))
+		return -EINVAL;
+
+	n = dst_alloc_node(ctl, dst_start_remote, 1);
+	if (!n)
+		return -ENOMEM;
+
+	memcpy(&n->info->net, rctl, sizeof(struct dst_network_ctl));
+	err = dst_node_init_connected(n, rctl);
+	if (err)
+		goto err_out_free;
+
+	dst_node_add(n);
+
+	return 0;
+
+err_out_free:
+	dst_node_put(n);
+	return err;
+}
+
+/*
+ * Adding export node: initializing block device and listening socket.
+ */
+static int dst_add_export(struct dst_node *n, struct dst_ctl *ctl,
+		void *data, unsigned int size)
+{
+	int err;
+	struct dst_export_ctl *le = data;
+
+	if (n)
+		return -EEXIST;
+
+	if (size != sizeof(struct dst_export_ctl))
+		return -EINVAL;
+
+	n = dst_alloc_node(ctl, dst_start_export, 2);
+	if (!n)
+		return -EINVAL;
+
+	err = dst_setup_export(n, ctl, le);
+	if (err)
+		goto err_out_free;
+
+	dst_node_add(n);
+
+	return 0;
+
+err_out_free:
+	dst_node_put(n);
+	return err;
+}
+
+static int dst_node_remove_unload(struct dst_node *n)
+{
+	printk(KERN_INFO "STOPPED name: '%s', size: %llu.\n",
+			n->name, n->size);
+
+	if (n->disk)
+		del_gendisk(n->disk);
+
+	dst_node_remove(n);
+	dst_node_sysfs_exit(n);
+
+	/*
+	 * This is not a hack. Really.
+	 * Node's reference counter allows to implement fine grained
+	 * node freeing, but since all transactions (which hold node's
+	 * reference counter) are processed in the dedicated thread,
+	 * it is possible that reference will hit zero in that thread,
+	 * so we will not be able to exit thread and cleanup the node.
+	 *
+	 * So, we remove disk, so no new activity is possible, and
+	 * wait until all pending transaction are completed (either
+	 * in receiving thread or by timeout in workqueue), in this
+	 * case reference counter will be less or equal to 2 (once set in
+	 * dst_alloc_node() and then in connector message parser;
+	 * or when we force module unloading, and connector message
+	 * parser does not hold a reference, in this case reference
+	 * counter will be equal to 1),
+	 * and subsequent dst_node_put() calls will free the node.
+	 */
+	dprintk("%s: going to sleep with %d refcnt.\n", __func__, atomic_read(&n->refcnt));
+	wait_event(n->wait, atomic_read(&n->refcnt) <= 2);
+
+	dst_node_put(n);
+	return 0;
+}
+
+/*
+ * Remove node from the hash table.
+ */
+static int dst_del_node(struct dst_node *n, struct dst_ctl *ctl,
+		void *data, unsigned int size)
+{
+	if (!n)
+		return -ENODEV;
+
+	return dst_node_remove_unload(n);
+}
+
+/*
+ * Initialize crypto processing for given node.
+ */
+static int dst_crypto_init(struct dst_node *n, struct dst_ctl *ctl,
+		void *data, unsigned int size)
+{
+	struct dst_crypto_ctl *crypto = data;
+
+	if (!n)
+		return -ENODEV;
+
+	if (size != sizeof(struct dst_crypto_ctl) + crypto->hash_keysize +
+			crypto->cipher_keysize)
+		return -EINVAL;
+
+	if (n->trans_cache)
+		return -EEXIST;
+
+	return dst_node_crypto_init(n, crypto);
+}
+
+/*
+ * Security attributes for given node.
+ */
+static int dst_security_init(struct dst_node *n, struct dst_ctl *ctl,
+		void *data, unsigned int size)
+{
+	struct dst_secure *s;
+
+	if (!n)
+		return -ENODEV;
+
+	if (size != sizeof(struct dst_secure_user))
+		return -EINVAL;
+
+	s = kmalloc(sizeof(struct dst_secure), GFP_KERNEL);
+	if (!s)
+		return -ENOMEM;
+
+	memcpy(&s->sec, data, size);
+
+	mutex_lock(&n->security_lock);
+	list_add_tail(&s->sec_entry, &n->security_list);
+	mutex_unlock(&n->security_lock);
+
+	return 0;
+}
+
+/*
+ * Kill'em all!
+ */
+static int dst_start_node(struct dst_node *n, struct dst_ctl *ctl,
+		void *data, unsigned int size)
+{
+	int err;
+
+	if (!n)
+		return -ENODEV;
+
+	if (n->trans_cache)
+		return 0;
+
+	err = n->start(n);
+	if (err)
+		return err;
+
+	printk(KERN_INFO "STARTED name: '%s', size: %llu.\n", n->name, n->size);
+	return 0;
+}
+
+typedef int (*dst_command_func)(struct dst_node *n, struct dst_ctl *ctl,
+		void *data, unsigned int size);
+
+/*
+ * List of userspace commands.
+ */
+static dst_command_func dst_commands[] = {
+	[DST_ADD_REMOTE] = &dst_add_remote,
+	[DST_ADD_EXPORT] = &dst_add_export,
+	[DST_DEL_NODE] = &dst_del_node,
+	[DST_CRYPTO] = &dst_crypto_init,
+	[DST_SECURITY] = &dst_security_init,
+	[DST_START] = &dst_start_node,
+};
+
+/*
+ * Configuration parser.
+ */
+static void cn_dst_callback(void *data)
+{
+	struct dst_ctl *ctl;
+	struct cn_msg *msg = data;
+	int err;
+	struct dst_ctl_ack ack;
+	struct dst_node *n = NULL, *tmp;
+	unsigned int hash;
+
+	if (msg->len < sizeof(struct dst_ctl)) {
+		err = -EBADMSG;
+		goto out;
+	}
+
+	ctl = (struct dst_ctl *)msg->data;
+
+	if (ctl->cmd >= DST_CMD_MAX) {
+		err = -EINVAL;
+		goto out;
+	}
+	hash = dst_hash(ctl->name, sizeof(ctl->name));
+
+	mutex_lock(&dst_hash_lock);
+	list_for_each_entry(tmp, &dst_hashtable[hash], node_entry) {
+		if (!memcmp(tmp->name, ctl->name, sizeof(tmp->name))) {
+			n = tmp;
+			dst_node_get(n);
+			break;
+		}
+	}
+	mutex_unlock(&dst_hash_lock);
+
+	err = dst_commands[ctl->cmd](n, ctl, msg->data + sizeof(struct dst_ctl),
+			msg->len - sizeof(struct dst_ctl));
+
+	dst_node_put(n);
+out:
+	memcpy(&ack.msg, msg, sizeof(struct cn_msg));
+
+	ack.msg.ack = msg->ack + 1;
+	ack.msg.len = sizeof(struct dst_ctl_ack) - sizeof(struct cn_msg);
+
+	ack.error = err;
+
+	cn_netlink_send(&ack.msg, 0, GFP_KERNEL);
+}
+
+/*
+ * Global initialization: sysfs, hash table, block device registration,
+ * connector and various caches.
+ */
+static int __init dst_sysfs_init(void)
+{
+	return bus_register(&dst_dev_bus_type);
+}
+
+static void dst_sysfs_exit(void)
+{
+	bus_unregister(&dst_dev_bus_type);
+}
+
+static int __init dst_hashtable_init(void)
+{
+	unsigned int i;
+
+	dst_hashtable = kcalloc(dst_hashtable_size, sizeof(struct list_head),
+			GFP_KERNEL);
+	if (!dst_hashtable)
+		return -ENOMEM;
+
+	for (i=0; i<dst_hashtable_size; ++i)
+		INIT_LIST_HEAD(&dst_hashtable[i]);
+
+	return 0;
+}
+
+static void dst_hashtable_exit(void)
+{
+	unsigned int i;
+	struct dst_node *n, *tmp;
+
+	for (i=0; i<dst_hashtable_size; ++i) {
+		list_for_each_entry_safe(n, tmp, &dst_hashtable[i], node_entry) {
+			dst_node_remove_unload(n);
+		}
+	}
+
+	kfree(dst_hashtable);
+}
+
+static int __init dst_sys_init(void)
+{
+	int err = -ENOMEM;
+
+	err = dst_hashtable_init();
+	if (err)
+		goto err_out_exit;
+
+	err = dst_export_init();
+	if (err)
+		goto err_out_hashtable_exit;
+
+	err = register_blkdev(dst_major, DST_NAME);
+	if (err < 0)
+		goto err_out_export_exit;
+	if (err)
+		dst_major = err;
+
+	err = dst_sysfs_init();
+	if (err)
+		goto err_out_unregister;
+
+	err = cn_add_callback(&cn_dst_id, "DST", cn_dst_callback);
+	if (err)
+		goto err_out_sysfs_exit;
+
+	printk(KERN_INFO "Distributed storage, '%s' release.\n", dst_name);
+
+	return 0;
+
+err_out_sysfs_exit:
+	dst_sysfs_exit();
+err_out_unregister:
+	unregister_blkdev(dst_major, DST_NAME);
+err_out_export_exit:
+	dst_export_exit();
+err_out_hashtable_exit:
+	dst_hashtable_exit();
+err_out_exit:
+	return err;
+}
+
+static void __exit dst_sys_exit(void)
+{
+	cn_del_callback(&cn_dst_id);
+	unregister_blkdev(dst_major, DST_NAME);
+	dst_hashtable_exit();
+	dst_sysfs_exit();
+	dst_export_exit();
+}
+
+module_init(dst_sys_init);
+module_exit(dst_sys_exit);
+
+MODULE_DESCRIPTION("Distributed storage");
+MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/dst/export.c b/drivers/staging/dst/export.c
new file mode 100644
index 0000000..80ae4eb
--- /dev/null
+++ b/drivers/staging/dst/export.c
@@ -0,0 +1,657 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * 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.
+ *
+ * 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/blkdev.h>
+#include <linux/bio.h>
+#include <linux/dst.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/poll.h>
+#include <linux/slab.h>
+#include <linux/socket.h>
+
+#include <net/sock.h>
+
+/*
+ * Export bioset is used for server block IO requests.
+ */
+static struct bio_set *dst_bio_set;
+
+int __init dst_export_init(void)
+{
+	int err = -ENOMEM;
+
+	dst_bio_set = bioset_create(32, sizeof(struct dst_export_priv));
+	if (!dst_bio_set)
+		goto err_out_exit;
+
+	return 0;
+
+err_out_exit:
+	return err;
+}
+
+void dst_export_exit(void)
+{
+	bioset_free(dst_bio_set);
+}
+
+/*
+ * When client connects and autonegotiates with the server node,
+ * its permissions are checked in a security attributes and sent
+ * back.
+ */
+static unsigned int dst_check_permissions(struct dst_state *main, struct dst_state *st)
+{
+	struct dst_node *n = main->node;
+	struct dst_secure *sentry;
+	struct dst_secure_user *s;
+	struct saddr *sa = &st->ctl.addr;
+	unsigned int perm = 0;
+
+	mutex_lock(&n->security_lock);
+	list_for_each_entry(sentry, &n->security_list, sec_entry) {
+		s = &sentry->sec;
+
+		if (s->addr.sa_family != sa->sa_family)
+			continue;
+
+		if (s->addr.sa_data_len != sa->sa_data_len)
+			continue;
+
+		/*
+		 * This '2' below is a port field. This may be very wrong to do
+		 * in atalk for example though. If there will be any need to extent
+		 * protocol to something else, I can create per-family helpers and
+		 * use them instead of this memcmp.
+		 */
+		if (memcmp(s->addr.sa_data + 2, sa->sa_data + 2,
+					sa->sa_data_len - 2))
+			continue;
+
+		perm = s->permissions;
+	}
+	mutex_unlock(&n->security_lock);
+
+	return perm;
+}
+
+/*
+ * Accept new client: allocate appropriate network state and check permissions.
+ */
+static struct dst_state *dst_accept_client(struct dst_state *st)
+{
+	unsigned int revents = 0;
+	unsigned int err_mask = POLLERR | POLLHUP | POLLRDHUP;
+	unsigned int mask = err_mask | POLLIN;
+	struct dst_node *n = st->node;
+	int err = 0;
+	struct socket *sock = NULL;
+	struct dst_state *new;
+
+	while (!err && !sock) {
+		revents = dst_state_poll(st);
+
+		if (!(revents & mask)) {
+			DEFINE_WAIT(wait);
+
+			for (;;) {
+				prepare_to_wait(&st->thread_wait,
+						&wait, TASK_INTERRUPTIBLE);
+				if (!n->trans_scan_timeout || st->need_exit)
+					break;
+
+				revents = dst_state_poll(st);
+
+				if (revents & mask)
+					break;
+
+				if (signal_pending(current))
+					break;
+
+				/*
+				 * Magic HZ? Polling check above is not safe in
+				 * all cases (like socket reset in BH context),
+				 * so it is simpler just to postpone it to the
+				 * process context instead of implementing special
+				 * locking there.
+				 */
+				schedule_timeout(HZ);
+			}
+			finish_wait(&st->thread_wait, &wait);
+		}
+
+		err = -ECONNRESET;
+		dst_state_lock(st);
+
+		dprintk("%s: st: %p, revents: %x [err: %d, in: %d].\n",
+			__func__, st, revents, revents & err_mask,
+			revents & POLLIN);
+
+		if (revents & err_mask) {
+			dprintk("%s: revents: %x, socket: %p, err: %d.\n",
+					__func__, revents, st->socket, err);
+			err = -ECONNRESET;
+		}
+
+		if (!n->trans_scan_timeout || st->need_exit)
+			err = -ENODEV;
+
+		if (st->socket && (revents & POLLIN))
+			err = kernel_accept(st->socket, &sock, 0);
+
+		dst_state_unlock(st);
+	}
+
+	if (err)
+		goto err_out_exit;
+
+	new = dst_state_alloc(st->node);
+	if (!new) {
+		err = -ENOMEM;
+		goto err_out_release;
+	}
+	new->socket = sock;
+
+	new->ctl.addr.sa_data_len = sizeof(struct sockaddr);
+	err = kernel_getpeername(sock, (struct sockaddr *)&new->ctl.addr,
+			(int *)&new->ctl.addr.sa_data_len);
+	if (err)
+		goto err_out_put;
+
+	new->permissions = dst_check_permissions(st, new);
+	if (new->permissions == 0) {
+		err = -EPERM;
+		dst_dump_addr(sock, (struct sockaddr *)&new->ctl.addr,
+				"Client is not allowed to connect");
+		goto err_out_put;
+	}
+
+	err = dst_poll_init(new);
+	if (err)
+		goto err_out_put;
+
+	dst_dump_addr(sock, (struct sockaddr *)&new->ctl.addr,
+			"Connected client");
+
+	return new;
+
+err_out_put:
+	dst_state_put(new);
+err_out_release:
+	sock_release(sock);
+err_out_exit:
+	return ERR_PTR(err);
+}
+
+/*
+ * Each server's block request sometime finishes.
+ * Usually it happens in hard irq context of the appropriate controller,
+ * so to play good with all cases we just queue BIO into the queue
+ * and wake up processing thread, which gets completed request and
+ * send (encrypting if needed) it back to the client (if it was a read
+ * request), or sends back reply that writing succesfully completed.
+ */
+static int dst_export_process_request_queue(struct dst_state *st)
+{
+	unsigned long flags;
+	struct dst_export_priv *p = NULL;
+	struct bio *bio;
+	int err = 0;
+
+	while (!list_empty(&st->request_list)) {
+		spin_lock_irqsave(&st->request_lock, flags);
+		if (!list_empty(&st->request_list)) {
+			p = list_first_entry(&st->request_list,
+				struct dst_export_priv, request_entry);
+			list_del(&p->request_entry);
+		}
+		spin_unlock_irqrestore(&st->request_lock, flags);
+
+		if (!p)
+			break;
+
+		bio = p->bio;
+
+		if (dst_need_crypto(st->node) && (bio_data_dir(bio) == READ))
+			err = dst_export_crypto(st->node, bio);
+		else
+			err = dst_export_send_bio(bio);
+
+		if (err)
+			break;
+	}
+
+	return err;
+}
+
+/*
+ * Cleanup export state.
+ * It has to wait until all requests are finished,
+ * and then free them all.
+ */
+static void dst_state_cleanup_export(struct dst_state *st)
+{
+	struct dst_export_priv *p;
+	unsigned long flags;
+
+	/*
+	 * This loop waits for all pending bios to be completed and freed.
+	 */
+	while (atomic_read(&st->refcnt) > 1) {
+		dprintk("%s: st: %p, refcnt: %d, list_empty: %d.\n",
+				__func__, st, atomic_read(&st->refcnt),
+				list_empty(&st->request_list));
+		wait_event_timeout(st->thread_wait,
+				(atomic_read(&st->refcnt) == 1) ||
+				!list_empty(&st->request_list),
+				HZ/2);
+
+		while (!list_empty(&st->request_list)) {
+			p = NULL;
+			spin_lock_irqsave(&st->request_lock, flags);
+			if (!list_empty(&st->request_list)) {
+				p = list_first_entry(&st->request_list,
+					struct dst_export_priv, request_entry);
+				list_del(&p->request_entry);
+			}
+			spin_unlock_irqrestore(&st->request_lock, flags);
+
+			if (p)
+				bio_put(p->bio);
+
+			dprintk("%s: st: %p, refcnt: %d, list_empty: %d, p: %p.\n",
+				__func__, st, atomic_read(&st->refcnt),
+				list_empty(&st->request_list), p);
+		}
+	}
+
+	dst_state_put(st);
+}
+
+/*
+ * Client accepting thread.
+ * Not only accepts new connection, but also schedules receiving thread
+ * and performs request completion described above.
+ */
+static int dst_accept(void *init_data, void *schedule_data)
+{
+	struct dst_state *main_st = schedule_data;
+	struct dst_node *n = init_data;
+	struct dst_state *st;
+	int err;
+
+	while (n->trans_scan_timeout && !main_st->need_exit) {
+		dprintk("%s: main_st: %p, n: %p.\n", __func__, main_st, n);
+		st = dst_accept_client(main_st);
+		if (IS_ERR(st))
+			continue;
+
+		err = dst_state_schedule_receiver(st);
+		if (!err) {
+			while (n->trans_scan_timeout) {
+				err = wait_event_interruptible_timeout(st->thread_wait,
+						!list_empty(&st->request_list) ||
+						!n->trans_scan_timeout ||
+						st->need_exit,
+					HZ);
+
+				if (!n->trans_scan_timeout || st->need_exit)
+					break;
+
+				if (list_empty(&st->request_list))
+					continue;
+
+				err = dst_export_process_request_queue(st);
+				if (err)
+					break;
+			}
+
+			st->need_exit = 1;
+			wake_up(&st->thread_wait);
+		}
+
+		dst_state_cleanup_export(st);
+	}
+
+	dprintk("%s: freeing listening socket st: %p.\n", __func__, main_st);
+
+	dst_state_lock(main_st);
+	dst_poll_exit(main_st);
+	dst_state_socket_release(main_st);
+	dst_state_unlock(main_st);
+	dst_state_put(main_st);
+	dprintk("%s: freed listening socket st: %p.\n", __func__, main_st);
+
+	return 0;
+}
+
+int dst_start_export(struct dst_node *n)
+{
+	if (list_empty(&n->security_list)) {
+		printk(KERN_ERR "You are trying to export node '%s' without security attributes.\n"
+				"No clients will be allowed to connect. Exiting.\n", n->name);
+		return -EINVAL;
+	}
+	return dst_node_trans_init(n, sizeof(struct dst_export_priv));
+}
+
+/*
+ * Initialize listening state and schedule accepting thread.
+ */
+int dst_node_init_listened(struct dst_node *n, struct dst_export_ctl *le)
+{
+	struct dst_state *st;
+	int err = -ENOMEM;
+	struct dst_network_ctl *ctl = &le->ctl;
+
+	memcpy(&n->info->net, ctl, sizeof(struct dst_network_ctl));
+
+	st = dst_state_alloc(n);
+	if (IS_ERR(st)) {
+		err = PTR_ERR(st);
+		goto err_out_exit;
+	}
+	memcpy(&st->ctl, ctl, sizeof(struct dst_network_ctl));
+
+	err = dst_state_socket_create(st);
+	if (err)
+		goto err_out_put;
+
+	st->socket->sk->sk_reuse = 1;
+
+	err = kernel_bind(st->socket, (struct sockaddr *)&ctl->addr,
+			ctl->addr.sa_data_len);
+	if (err)
+		goto err_out_socket_release;
+
+	err = kernel_listen(st->socket, 1024);
+	if (err)
+		goto err_out_socket_release;
+	n->state = st;
+
+	err = dst_poll_init(st);
+	if (err)
+		goto err_out_socket_release;
+
+	dst_state_get(st);
+
+	err = thread_pool_schedule(n->pool, dst_thread_setup,
+			dst_accept, st, MAX_SCHEDULE_TIMEOUT);
+	if (err)
+		goto err_out_poll_exit;
+
+	return 0;
+
+err_out_poll_exit:
+	dst_poll_exit(st);
+err_out_socket_release:
+	dst_state_socket_release(st);
+err_out_put:
+	dst_state_put(st);
+err_out_exit:
+	n->state = NULL;
+	return err;
+}
+
+/*
+ * Free bio and related private data.
+ * Also drop a reference counter for appropriate state,
+ * which waits when there are no more block IOs in-flight.
+ */
+static void dst_bio_destructor(struct bio *bio)
+{
+	struct bio_vec *bv;
+	struct dst_export_priv *priv = bio->bi_private;
+	int i;
+
+	bio_for_each_segment(bv, bio, i) {
+		if (!bv->bv_page)
+			break;
+
+		__free_page(bv->bv_page);
+	}
+
+	if (priv)
+		dst_state_put(priv->state);
+	bio_free(bio, dst_bio_set);
+}
+
+/*
+ * Block IO completion. Queue request to be sent back to
+ * the client (or just confirmation).
+ */
+static void dst_bio_end_io(struct bio *bio, int err)
+{
+	struct dst_export_priv *p = bio->bi_private;
+	struct dst_state *st = p->state;
+	unsigned long flags;
+
+	spin_lock_irqsave(&st->request_lock, flags);
+	list_add_tail(&p->request_entry, &st->request_list);
+	spin_unlock_irqrestore(&st->request_lock, flags);
+
+	wake_up(&st->thread_wait);
+}
+
+/*
+ * Allocate read request for the server.
+ */
+static int dst_export_read_request(struct bio *bio, unsigned int total_size)
+{
+	unsigned int size;
+	struct page *page;
+	int err;
+
+	while (total_size) {
+		err = -ENOMEM;
+		page = alloc_page(GFP_KERNEL);
+		if (!page)
+			goto err_out_exit;
+
+		size = min_t(unsigned int, PAGE_SIZE, total_size);
+
+		err = bio_add_page(bio, page, size, 0);
+		dprintk("%s: bio: %llu/%u, size: %u, err: %d.\n",
+				__func__, (u64)bio->bi_sector, bio->bi_size,
+				size, err);
+		if (err <= 0)
+			goto err_out_free_page;
+
+		total_size -= size;
+	}
+
+	return 0;
+
+err_out_free_page:
+	__free_page(page);
+err_out_exit:
+	return err;
+}
+
+/*
+ * Allocate write request for the server.
+ * Should not only get pages, but also read data from the network.
+ */
+static int dst_export_write_request(struct dst_state *st,
+		struct bio *bio, unsigned int total_size)
+{
+	unsigned int size;
+	struct page *page;
+	void *data;
+	int err;
+
+	while (total_size) {
+		err = -ENOMEM;
+		page = alloc_page(GFP_KERNEL);
+		if (!page)
+			goto err_out_exit;
+
+		data = kmap(page);
+		if (!data)
+			goto err_out_free_page;
+
+		size = min_t(unsigned int, PAGE_SIZE, total_size);
+
+		err = dst_data_recv(st, data, size);
+		if (err)
+			goto err_out_unmap_page;
+
+		err = bio_add_page(bio, page, size, 0);
+		if (err <= 0)
+			goto err_out_unmap_page;
+
+		kunmap(page);
+
+		total_size -= size;
+	}
+
+	return 0;
+
+err_out_unmap_page:
+	kunmap(page);
+err_out_free_page:
+	__free_page(page);
+err_out_exit:
+	return err;
+}
+
+/*
+ * Groovy, we've gotten an IO request from the client.
+ * Allocate BIO from the bioset, private data from the mempool
+ * and lots of pages for IO.
+ */
+int dst_process_io(struct dst_state *st)
+{
+	struct dst_node *n = st->node;
+	struct dst_cmd *cmd = st->data;
+	struct bio *bio;
+	struct dst_export_priv *priv;
+	int err = -ENOMEM;
+
+	if (unlikely(!n->bdev)) {
+		err = -EINVAL;
+		goto err_out_exit;
+	}
+
+	bio = bio_alloc_bioset(GFP_KERNEL,
+			PAGE_ALIGN(cmd->size) >> PAGE_SHIFT,
+			dst_bio_set);
+	if (!bio)
+		goto err_out_exit;
+
+	priv = (struct dst_export_priv *)(((void *)bio) - sizeof (struct dst_export_priv));
+
+	priv->state = dst_state_get(st);
+	priv->bio = bio;
+
+	bio->bi_private = priv;
+	bio->bi_end_io = dst_bio_end_io;
+	bio->bi_destructor = dst_bio_destructor;
+	bio->bi_bdev = n->bdev;
+
+	/*
+	 * Server side is only interested in two low bits:
+	 * uptodate (set by itself actually) and rw block
+	 */
+	bio->bi_flags |= cmd->flags & 3;
+
+	bio->bi_rw = cmd->rw;
+	bio->bi_size = 0;
+	bio->bi_sector = cmd->sector;
+
+	dst_bio_to_cmd(bio, &priv->cmd, DST_IO_RESPONSE, cmd->id);
+
+	priv->cmd.flags = 0;
+	priv->cmd.size = cmd->size;
+
+	if (bio_data_dir(bio) == WRITE) {
+		err = dst_recv_cdata(st, priv->cmd.hash);
+		if (err)
+			goto err_out_free;
+
+		err = dst_export_write_request(st, bio, cmd->size);
+		if (err)
+			goto err_out_free;
+
+		if (dst_need_crypto(n))
+			return dst_export_crypto(n, bio);
+	} else {
+		err = dst_export_read_request(bio, cmd->size);
+		if (err)
+			goto err_out_free;
+	}
+
+	dprintk("%s: bio: %llu/%u, rw: %lu, dir: %lu, flags: %lx, phys: %d.\n",
+			__func__, (u64)bio->bi_sector, bio->bi_size,
+			bio->bi_rw, bio_data_dir(bio),
+			bio->bi_flags, bio->bi_phys_segments);
+
+	generic_make_request(bio);
+
+	return 0;
+
+err_out_free:
+	bio_put(bio);
+err_out_exit:
+	return err;
+}
+
+/*
+ * Ok, block IO is ready, let's send it back to the client...
+ */
+int dst_export_send_bio(struct bio *bio)
+{
+	struct dst_export_priv *p = bio->bi_private;
+	struct dst_state *st = p->state;
+	struct dst_cmd *cmd = &p->cmd;
+	int err;
+
+	dprintk("%s: id: %llu, bio: %llu/%u, csize: %u, flags: %lu, rw: %lu.\n",
+			__func__, cmd->id, (u64)bio->bi_sector, bio->bi_size,
+			cmd->csize, bio->bi_flags, bio->bi_rw);
+
+	dst_convert_cmd(cmd);
+
+	dst_state_lock(st);
+	if (!st->socket) {
+		err = -ECONNRESET;
+		goto err_out_unlock;
+	}
+
+	if (bio_data_dir(bio) == WRITE) {
+		/* ... or just confirmation that writing has completed. */
+		cmd->size = cmd->csize = 0;
+		err = dst_data_send_header(st->socket, cmd,
+				sizeof(struct dst_cmd), 0);
+		if (err)
+			goto err_out_unlock;
+	} else {
+		err = dst_send_bio(st, cmd, bio);
+		if (err)
+			goto err_out_unlock;
+	}
+
+	dst_state_unlock(st);
+
+	bio_put(bio);
+	return 0;
+
+err_out_unlock:
+	dst_state_unlock(st);
+
+	bio_put(bio);
+	return err;
+}
diff --git a/drivers/staging/dst/state.c b/drivers/staging/dst/state.c
new file mode 100644
index 0000000..d057e52
--- /dev/null
+++ b/drivers/staging/dst/state.c
@@ -0,0 +1,839 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * 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.
+ *
+ * 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/buffer_head.h>
+#include <linux/blkdev.h>
+#include <linux/bio.h>
+#include <linux/connector.h>
+#include <linux/dst.h>
+#include <linux/device.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/socket.h>
+#include <linux/slab.h>
+
+#include <net/sock.h>
+
+/*
+ * Polling machinery.
+ */
+
+struct dst_poll_helper
+{
+	poll_table 		pt;
+	struct dst_state	*st;
+};
+
+static int dst_queue_wake(wait_queue_t *wait, unsigned mode, int sync, void *key)
+{
+	struct dst_state *st = container_of(wait, struct dst_state, wait);
+
+	wake_up(&st->thread_wait);
+	return 1;
+}
+
+static void dst_queue_func(struct file *file, wait_queue_head_t *whead,
+				 poll_table *pt)
+{
+	struct dst_state *st = container_of(pt, struct dst_poll_helper, pt)->st;
+
+	st->whead = whead;
+	init_waitqueue_func_entry(&st->wait, dst_queue_wake);
+	add_wait_queue(whead, &st->wait);
+}
+
+void dst_poll_exit(struct dst_state *st)
+{
+	if (st->whead) {
+		remove_wait_queue(st->whead, &st->wait);
+		st->whead = NULL;
+	}
+}
+
+int dst_poll_init(struct dst_state *st)
+{
+	struct dst_poll_helper ph;
+
+	ph.st = st;
+	init_poll_funcptr(&ph.pt, &dst_queue_func);
+
+	st->socket->ops->poll(NULL, st->socket, &ph.pt);
+	return 0;
+}
+
+/*
+ * Header receiving function - may block.
+ */
+static int dst_data_recv_header(struct socket *sock,
+		void *data, unsigned int size, int block)
+{
+	struct msghdr msg;
+	struct kvec iov;
+	int err;
+
+	iov.iov_base = data;
+	iov.iov_len = size;
+
+	msg.msg_iov = (struct iovec *)&iov;
+	msg.msg_iovlen = 1;
+	msg.msg_name = NULL;
+	msg.msg_namelen = 0;
+	msg.msg_control = NULL;
+	msg.msg_controllen = 0;
+	msg.msg_flags = (block)?MSG_WAITALL:MSG_DONTWAIT;
+
+	err = kernel_recvmsg(sock, &msg, &iov, 1, iov.iov_len,
+			msg.msg_flags);
+	if (err != size)
+		return -1;
+
+	return 0;
+}
+
+/*
+ * Header sending function - may block.
+ */
+int dst_data_send_header(struct socket *sock,
+		void *data, unsigned int size, int more)
+{
+	struct msghdr msg;
+	struct kvec iov;
+	int err;
+
+	iov.iov_base = data;
+	iov.iov_len = size;
+
+	msg.msg_iov = (struct iovec *)&iov;
+	msg.msg_iovlen = 1;
+	msg.msg_name = NULL;
+	msg.msg_namelen = 0;
+	msg.msg_control = NULL;
+	msg.msg_controllen = 0;
+	msg.msg_flags = MSG_WAITALL | (more)?MSG_MORE:0;
+
+	err = kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len);
+	if (err != size) {
+		dprintk("%s: size: %u, more: %d, err: %d.\n",
+				__func__, size, more, err);
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * Block autoconfiguration: request size of the storage and permissions.
+ */
+static int dst_request_remote_config(struct dst_state *st)
+{
+	struct dst_node *n = st->node;
+	int err = -EINVAL;
+	struct dst_cmd *cmd = st->data;
+
+	memset(cmd, 0, sizeof(struct dst_cmd));
+	cmd->cmd = DST_CFG;
+
+	dst_convert_cmd(cmd);
+
+	err = dst_data_send_header(st->socket, cmd, sizeof(struct dst_cmd), 0);
+	if (err)
+		goto out;
+
+	err = dst_data_recv_header(st->socket, cmd, sizeof(struct dst_cmd), 1);
+	if (err)
+		goto out;
+
+	dst_convert_cmd(cmd);
+
+	if (cmd->cmd != DST_CFG) {
+		err = -EINVAL;
+		dprintk("%s: checking result: cmd: %d, size reported: %llu.\n",
+			__func__, cmd->cmd, cmd->sector);
+		goto out;
+	}
+
+	if (n->size != 0)
+		n->size = min_t(loff_t, n->size, cmd->sector);
+	else
+		n->size = cmd->sector;
+
+	n->info->size = n->size;
+	st->permissions = cmd->rw;
+
+out:
+	dprintk("%s: n: %p, err: %d, size: %llu, permission: %x.\n",
+			__func__, n, err, n->size, st->permissions);
+	return err;
+}
+
+/*
+ * Socket machinery.
+ */
+
+#define DST_DEFAULT_TIMEO	20000
+
+int dst_state_socket_create(struct dst_state *st)
+{
+	int err;
+	struct socket *sock;
+	struct dst_network_ctl *ctl = &st->ctl;
+
+	err = sock_create(ctl->addr.sa_family, ctl->type, ctl->proto, &sock);
+	if (err < 0)
+		return err;
+
+	sock->sk->sk_sndtimeo = sock->sk->sk_rcvtimeo =
+		msecs_to_jiffies(DST_DEFAULT_TIMEO);
+	sock->sk->sk_allocation = GFP_NOIO;
+
+	st->socket = st->read_socket = sock;
+	return 0;
+}
+
+void dst_state_socket_release(struct dst_state *st)
+{
+	dprintk("%s: st: %p, socket: %p, n: %p.\n",
+			__func__, st, st->socket, st->node);
+	if (st->socket) {
+		sock_release(st->socket);
+		st->socket = NULL;
+		st->read_socket = NULL;
+	}
+}
+
+void dst_dump_addr(struct socket *sk, struct sockaddr *sa, char *str)
+{
+	if (sk->ops->family == AF_INET) {
+		struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+		printk(KERN_INFO "%s %u.%u.%u.%u:%d.\n",
+			str, NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
+	} else if (sk->ops->family == AF_INET6) {
+		struct sockaddr_in6 *sin = (struct sockaddr_in6 *)sa;
+		printk(KERN_INFO "%s %pi6:%d",
+			str, &sin->sin6_addr, ntohs(sin->sin6_port));
+	}
+}
+
+void dst_state_exit_connected(struct dst_state *st)
+{
+	if (st->socket) {
+		dst_poll_exit(st);
+		st->socket->ops->shutdown(st->socket, 2);
+
+		dst_dump_addr(st->socket, (struct sockaddr *)&st->ctl.addr,
+				"Disconnected peer");
+		dst_state_socket_release(st);
+	}
+}
+
+static int dst_state_init_connected(struct dst_state *st)
+{
+	int err;
+	struct dst_network_ctl *ctl = &st->ctl;
+
+	err = dst_state_socket_create(st);
+	if (err)
+		goto err_out_exit;
+
+	err = kernel_connect(st->socket, (struct sockaddr *)&st->ctl.addr,
+			st->ctl.addr.sa_data_len, 0);
+	if (err)
+		goto err_out_release;
+
+	err = dst_poll_init(st);
+	if (err)
+		goto err_out_release;
+
+	dst_dump_addr(st->socket, (struct sockaddr *)&ctl->addr,
+			"Connected to peer");
+
+	return 0;
+
+err_out_release:
+	dst_state_socket_release(st);
+err_out_exit:
+	return err;
+}
+
+/*
+ * State reset is used to reconnect to the remote peer.
+ * May fail, but who cares, we will try again later.
+ */
+static void inline dst_state_reset_nolock(struct dst_state *st)
+{
+	dst_state_exit_connected(st);
+	dst_state_init_connected(st);
+}
+
+static void inline dst_state_reset(struct dst_state *st)
+{
+	dst_state_lock(st);
+	dst_state_reset_nolock(st);
+	dst_state_unlock(st);
+}
+
+/*
+ * Basic network sending/receiving functions.
+ * Blocked mode is used.
+ */
+static int dst_data_recv_raw(struct dst_state *st, void *buf, u64 size)
+{
+	struct msghdr msg;
+	struct kvec iov;
+	int err;
+
+	BUG_ON(!size);
+
+	iov.iov_base = buf;
+	iov.iov_len = size;
+
+	msg.msg_iov = (struct iovec *)&iov;
+	msg.msg_iovlen = 1;
+	msg.msg_name = NULL;
+	msg.msg_namelen = 0;
+	msg.msg_control = NULL;
+	msg.msg_controllen = 0;
+	msg.msg_flags = MSG_DONTWAIT;
+
+	err = kernel_recvmsg(st->socket, &msg, &iov, 1, iov.iov_len,
+			msg.msg_flags);
+	if (err <= 0) {
+		dprintk("%s: failed to recv data: size: %llu, err: %d.\n",
+				__func__, size, err);
+		if (err == 0)
+			err = -ECONNRESET;
+
+		dst_state_exit_connected(st);
+	}
+
+	return err;
+}
+
+/*
+ * Ping command to early detect failed nodes.
+ */
+static int dst_send_ping(struct dst_state *st)
+{
+	struct dst_cmd *cmd = st->data;
+	int err = -ECONNRESET;
+
+	dst_state_lock(st);
+	if (st->socket) {
+		memset(cmd, 0, sizeof(struct dst_cmd));
+
+		cmd->cmd = __cpu_to_be32(DST_PING);
+
+		err = dst_data_send_header(st->socket, cmd, sizeof(struct dst_cmd), 0);
+	}
+	dprintk("%s: st: %p, socket: %p, err: %d.\n", __func__, st, st->socket, err);
+	dst_state_unlock(st);
+
+	return err;
+}
+
+/*
+ * Receiving function, which should either return error or read
+ * whole block request. If there was no traffic for a one second,
+ * send a ping, since remote node may die.
+ */
+int dst_data_recv(struct dst_state *st, void *data, unsigned int size)
+{
+	unsigned int revents = 0;
+	unsigned int err_mask = POLLERR | POLLHUP | POLLRDHUP;
+	unsigned int mask = err_mask | POLLIN;
+	struct dst_node *n = st->node;
+	int err = 0;
+
+	while (size && !err) {
+		revents = dst_state_poll(st);
+
+		if (!(revents & mask)) {
+			DEFINE_WAIT(wait);
+
+			for (;;) {
+				prepare_to_wait(&st->thread_wait, &wait,
+						TASK_INTERRUPTIBLE);
+				if (!n->trans_scan_timeout || st->need_exit)
+					break;
+
+				revents = dst_state_poll(st);
+
+				if (revents & mask)
+					break;
+
+				if (signal_pending(current))
+					break;
+
+				if (!schedule_timeout(HZ)) {
+					err = dst_send_ping(st);
+					if (err)
+						return err;
+				}
+
+				continue;
+			}
+			finish_wait(&st->thread_wait, &wait);
+		}
+
+		err = -ECONNRESET;
+		dst_state_lock(st);
+
+		if (		st->socket &&
+				(st->read_socket == st->socket) &&
+				(revents & POLLIN)) {
+			err = dst_data_recv_raw(st, data, size);
+			if (err > 0) {
+				data += err;
+				size -= err;
+				err = 0;
+			}
+		}
+
+		if (revents & err_mask || !st->socket) {
+			dprintk("%s: revents: %x, socket: %p, size: %u, err: %d.\n",
+					__func__, revents, st->socket, size, err);
+			err = -ECONNRESET;
+		}
+
+		dst_state_unlock(st);
+
+		if (!n->trans_scan_timeout)
+			err = -ENODEV;
+	}
+
+	return err;
+}
+
+/*
+ * Send block autoconf reply.
+ */
+static int dst_process_cfg(struct dst_state *st)
+{
+	struct dst_node *n = st->node;
+	struct dst_cmd *cmd = st->data;
+	int err;
+
+	cmd->sector = n->size;
+	cmd->rw = st->permissions;
+
+	dst_convert_cmd(cmd);
+
+	dst_state_lock(st);
+	err = dst_data_send_header(st->socket, cmd, sizeof(struct dst_cmd), 0);
+	dst_state_unlock(st);
+
+	return err;
+}
+
+/*
+ * Receive block IO from the network.
+ */
+static int dst_recv_bio(struct dst_state *st, struct bio *bio, unsigned int total_size)
+{
+	struct bio_vec *bv;
+	int i, err;
+	void *data;
+	unsigned int sz;
+
+	bio_for_each_segment(bv, bio, i) {
+		sz = min(total_size, bv->bv_len);
+
+		dprintk("%s: bio: %llu/%u, total: %u, len: %u, sz: %u, off: %u.\n",
+			__func__, (u64)bio->bi_sector, bio->bi_size, total_size,
+			bv->bv_len, sz, bv->bv_offset);
+
+		data = kmap(bv->bv_page) + bv->bv_offset;
+		err = dst_data_recv(st, data, sz);
+		kunmap(bv->bv_page);
+
+		bv->bv_len = sz;
+
+		if (err)
+			return err;
+
+		total_size -= sz;
+		if (total_size == 0)
+			break;
+	}
+
+	return 0;
+}
+
+/*
+ * Our block IO has just completed and arrived: get it.
+ */
+static int dst_process_io_response(struct dst_state *st)
+{
+	struct dst_node *n = st->node;
+	struct dst_cmd *cmd = st->data;
+	struct dst_trans *t;
+	int err = 0;
+	struct bio *bio;
+
+	mutex_lock(&n->trans_lock);
+	t = dst_trans_search(n, cmd->id);
+	mutex_unlock(&n->trans_lock);
+
+	if (!t)
+		goto err_out_exit;
+
+	bio = t->bio;
+
+	dprintk("%s: bio: %llu/%u, cmd_size: %u, csize: %u, dir: %lu.\n",
+		__func__, (u64)bio->bi_sector, bio->bi_size, cmd->size,
+		cmd->csize, bio_data_dir(bio));
+
+	if (bio_data_dir(bio) == READ) {
+		if (bio->bi_size != cmd->size - cmd->csize)
+			goto err_out_exit;
+
+		if (dst_need_crypto(n)) {
+			err = dst_recv_cdata(st, t->cmd.hash);
+			if (err)
+				goto err_out_exit;
+		}
+
+		err = dst_recv_bio(st, t->bio, bio->bi_size);
+		if (err)
+			goto err_out_exit;
+
+		if (dst_need_crypto(n))
+			return dst_trans_crypto(t);
+	} else {
+		err = -EBADMSG;
+		if (cmd->size || cmd->csize)
+			goto err_out_exit;
+	}
+
+	dst_trans_remove(t);
+	dst_trans_put(t);
+
+	return 0;
+
+err_out_exit:
+	return err;
+}
+
+/*
+ * Receive crypto data.
+ */
+int dst_recv_cdata(struct dst_state *st, void *cdata)
+{
+	struct dst_cmd *cmd = st->data;
+	struct dst_node *n = st->node;
+	struct dst_crypto_ctl *c = &n->crypto;
+	int err;
+
+	if (cmd->csize != c->crypto_attached_size) {
+		dprintk("%s: cmd: cmd: %u, sector: %llu, size: %u, "
+				"csize: %u != digest size %u.\n",
+				__func__, cmd->cmd, cmd->sector, cmd->size,
+				cmd->csize, c->crypto_attached_size);
+		err = -EINVAL;
+		goto err_out_exit;
+	}
+
+	err = dst_data_recv(st, cdata, cmd->csize);
+	if (err)
+		goto err_out_exit;
+
+	cmd->size -= cmd->csize;
+	return 0;
+
+err_out_exit:
+	return err;
+}
+
+/*
+ * Receive the command and start its processing.
+ */
+static int dst_recv_processing(struct dst_state *st)
+{
+	int err = -EINTR;
+	struct dst_cmd *cmd = st->data;
+
+	/*
+	 * If socket will be reset after this statement, then
+	 * dst_data_recv() will just fail and loop will
+	 * start again, so it can be done without any locks.
+	 *
+	 * st->read_socket is needed to prevents state machine
+	 * breaking between this data reading and subsequent one
+	 * in protocol specific functions during connection reset.
+	 * In case of reset we have to read next command and do
+	 * not expect data for old command to magically appear in
+	 * new connection.
+	 */
+	st->read_socket = st->socket;
+	err = dst_data_recv(st, cmd, sizeof(struct dst_cmd));
+	if (err)
+		goto out_exit;
+
+	dst_convert_cmd(cmd);
+
+	dprintk("%s: cmd: %u, size: %u, csize: %u, id: %llu, "
+			"sector: %llu, flags: %llx, rw: %llx.\n",
+			__func__, cmd->cmd, cmd->size,
+			cmd->csize, cmd->id, cmd->sector,
+			cmd->flags, cmd->rw);
+
+	/*
+	 * This should catch protocol breakage and random garbage instead of commands.
+	 */
+	if (unlikely(cmd->csize > st->size - sizeof(struct dst_cmd))) {
+		err = -EBADMSG;
+		goto out_exit;
+	}
+
+	err = -EPROTO;
+	switch (cmd->cmd) {
+		case DST_IO_RESPONSE:
+			err = dst_process_io_response(st);
+			break;
+		case DST_IO:
+			err = dst_process_io(st);
+			break;
+		case DST_CFG:
+			err = dst_process_cfg(st);
+			break;
+		case DST_PING:
+			err = 0;
+			break;
+		default:
+			break;
+	}
+
+out_exit:
+	return err;
+}
+
+/*
+ * Receiving thread. For the client node we should try to reconnect,
+ * for accepted client we just drop the state and expect it to reconnect.
+ */
+static int dst_recv(void *init_data, void *schedule_data)
+{
+	struct dst_state *st = schedule_data;
+	struct dst_node *n = init_data;
+	int err = 0;
+
+	dprintk("%s: start st: %p, n: %p, scan: %lu, need_exit: %d.\n",
+			__func__, st, n, n->trans_scan_timeout, st->need_exit);
+
+	while (n->trans_scan_timeout && !st->need_exit) {
+		err = dst_recv_processing(st);
+		if (err < 0) {
+			if (!st->ctl.type)
+				break;
+
+			if (!n->trans_scan_timeout || st->need_exit)
+				break;
+
+			dst_state_reset(st);
+			msleep(1000);
+		}
+	}
+
+	st->need_exit = 1;
+	wake_up(&st->thread_wait);
+
+	dprintk("%s: freeing receiving socket st: %p.\n", __func__, st);
+	dst_state_lock(st);
+	dst_state_exit_connected(st);
+	dst_state_unlock(st);
+	dst_state_put(st);
+
+	dprintk("%s: freed receiving socket st: %p.\n", __func__, st);
+
+	return err;
+}
+
+/*
+ * Network state dies here and borns couple of lines below.
+ * This object is the main network state processing engine:
+ * sending, receiving, reconnections, all network related
+ * tasks are handled on behalf of the state.
+ */
+static void dst_state_free(struct dst_state *st)
+{
+	dprintk("%s: st: %p.\n", __func__, st);
+	if (st->cleanup)
+		st->cleanup(st);
+	kfree(st->data);
+	kfree(st);
+}
+
+struct dst_state *dst_state_alloc(struct dst_node *n)
+{
+	struct dst_state *st;
+	int err = -ENOMEM;
+
+	st = kzalloc(sizeof(struct dst_state), GFP_KERNEL);
+	if (!st)
+		goto err_out_exit;
+
+	st->node = n;
+	st->need_exit = 0;
+
+	st->size = PAGE_SIZE;
+	st->data = kmalloc(st->size, GFP_KERNEL);
+	if (!st->data)
+		goto err_out_free;
+
+	spin_lock_init(&st->request_lock);
+	INIT_LIST_HEAD(&st->request_list);
+
+	mutex_init(&st->state_lock);
+	init_waitqueue_head(&st->thread_wait);
+
+	/*
+	 * One for processing thread, another one for node itself.
+	 */
+	atomic_set(&st->refcnt, 2);
+
+	dprintk("%s: st: %p, n: %p.\n", __func__, st, st->node);
+
+	return st;
+
+err_out_free:
+	kfree(st);
+err_out_exit:
+	return ERR_PTR(err);
+}
+
+int dst_state_schedule_receiver(struct dst_state *st)
+{
+	return thread_pool_schedule_private(st->node->pool, dst_thread_setup,
+			dst_recv, st, MAX_SCHEDULE_TIMEOUT, st->node);
+}
+
+/*
+ * Initialize client's connection to the remote peer: allocate state,
+ * connect and perform block IO autoconfiguration.
+ */
+int dst_node_init_connected(struct dst_node *n, struct dst_network_ctl *r)
+{
+	struct dst_state *st;
+	int err = -ENOMEM;
+
+	st = dst_state_alloc(n);
+	if (IS_ERR(st)) {
+		err = PTR_ERR(st);
+		goto err_out_exit;
+	}
+	memcpy(&st->ctl, r, sizeof(struct dst_network_ctl));
+
+	err = dst_state_init_connected(st);
+	if (err)
+		goto err_out_free_data;
+
+	err = dst_request_remote_config(st);
+	if (err)
+		goto err_out_exit_connected;
+	n->state = st;
+
+	err = dst_state_schedule_receiver(st);
+	if (err)
+		goto err_out_exit_connected;
+
+	return 0;
+
+err_out_exit_connected:
+	dst_state_exit_connected(st);
+err_out_free_data:
+	dst_state_free(st);
+err_out_exit:
+	n->state = NULL;
+	return err;
+}
+
+void dst_state_put(struct dst_state *st)
+{
+	dprintk("%s: st: %p, refcnt: %d.\n",
+			__func__, st, atomic_read(&st->refcnt));
+	if (atomic_dec_and_test(&st->refcnt))
+		dst_state_free(st);
+}
+
+/*
+ * Send block IO to the network one by one using zero-copy ->sendpage().
+ */
+int dst_send_bio(struct dst_state *st, struct dst_cmd *cmd, struct bio *bio)
+{
+	struct bio_vec *bv;
+	struct dst_crypto_ctl *c = &st->node->crypto;
+	int err, i = 0;
+	int flags = MSG_WAITALL;
+
+	err = dst_data_send_header(st->socket, cmd,
+		sizeof(struct dst_cmd) + c->crypto_attached_size, bio->bi_vcnt);
+	if (err)
+		goto err_out_exit;
+
+	bio_for_each_segment(bv, bio, i) {
+		if (i < bio->bi_vcnt - 1)
+			flags |= MSG_MORE;
+
+		err = kernel_sendpage(st->socket, bv->bv_page, bv->bv_offset,
+				bv->bv_len, flags);
+		if (err <= 0)
+			goto err_out_exit;
+	}
+
+	return 0;
+
+err_out_exit:
+	dprintk("%s: %d/%d, flags: %x, err: %d.\n",
+			__func__, i, bio->bi_vcnt, flags, err);
+	return err;
+}
+
+/*
+ * Send transaction to the remote peer.
+ */
+int dst_trans_send(struct dst_trans *t)
+{
+	int err;
+	struct dst_state *st = t->n->state;
+	struct bio *bio = t->bio;
+
+	dst_convert_cmd(&t->cmd);
+
+	dst_state_lock(st);
+	if (!st->socket) {
+		err = dst_state_init_connected(st);
+		if (err)
+			goto err_out_unlock;
+	}
+
+	if (bio_data_dir(bio) == WRITE) {
+		err = dst_send_bio(st, &t->cmd, t->bio);
+	} else {
+		err = dst_data_send_header(st->socket, &t->cmd,
+				sizeof(struct dst_cmd), 0);
+	}
+	if (err)
+		goto err_out_reset;
+
+	dst_state_unlock(st);
+	return 0;
+
+err_out_reset:
+	dst_state_reset_nolock(st);
+err_out_unlock:
+	dst_state_unlock(st);
+
+	return err;
+}
diff --git a/drivers/staging/dst/thread_pool.c b/drivers/staging/dst/thread_pool.c
new file mode 100644
index 0000000..7bed4e8
--- /dev/null
+++ b/drivers/staging/dst/thread_pool.c
@@ -0,0 +1,345 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * 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.
+ *
+ * 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/dst.h>
+#include <linux/kthread.h>
+#include <linux/slab.h>
+
+/*
+ * Thread pool abstraction allows to schedule a work to be performed
+ * on behalf of kernel thread. One does not operate with threads itself,
+ * instead user provides setup and cleanup callbacks for thread pool itself,
+ * and action and cleanup callbacks for each submitted work.
+ *
+ * Each worker has private data initialized at creation time and data,
+ * provided by user at scheduling time.
+ *
+ * When action is being performed, thread can not be used by other users,
+ * instead they will sleep until there is free thread to pick their work.
+ */
+struct thread_pool_worker
+{
+	struct list_head	worker_entry;
+
+	struct task_struct	*thread;
+
+	struct thread_pool	*pool;
+
+	int			error;
+	int			has_data;
+	int			need_exit;
+	unsigned int		id;
+
+	wait_queue_head_t	wait;
+
+	void			*private;
+	void			*schedule_data;
+
+	int			(* action)(void *private, void *schedule_data);
+	void			(* cleanup)(void *private);
+};
+
+static void thread_pool_exit_worker(struct thread_pool_worker *w)
+{
+	kthread_stop(w->thread);
+
+	w->cleanup(w->private);
+	kfree(w);
+}
+
+/*
+ * Called to mark thread as ready and allow users to schedule new work.
+ */
+static void thread_pool_worker_make_ready(struct thread_pool_worker *w)
+{
+	struct thread_pool *p = w->pool;
+
+	mutex_lock(&p->thread_lock);
+
+	if (!w->need_exit) {
+		list_move_tail(&w->worker_entry, &p->ready_list);
+		w->has_data = 0;
+		mutex_unlock(&p->thread_lock);
+
+		wake_up(&p->wait);
+	} else {
+		p->thread_num--;
+		list_del(&w->worker_entry);
+		mutex_unlock(&p->thread_lock);
+
+		thread_pool_exit_worker(w);
+	}
+}
+
+/*
+ * Thread action loop: waits until there is new work.
+ */
+static int thread_pool_worker_func(void *data)
+{
+	struct thread_pool_worker *w = data;
+
+	while (!kthread_should_stop()) {
+		wait_event_interruptible(w->wait,
+			kthread_should_stop() || w->has_data);
+
+		if (kthread_should_stop())
+			break;
+
+		if (!w->has_data)
+			continue;
+
+		w->action(w->private, w->schedule_data);
+		thread_pool_worker_make_ready(w);
+	}
+
+	return 0;
+}
+
+/*
+ * Remove single worker without specifying which one.
+ */
+void thread_pool_del_worker(struct thread_pool *p)
+{
+	struct thread_pool_worker *w = NULL;
+
+	while (!w && p->thread_num) {
+		wait_event(p->wait, !list_empty(&p->ready_list) || !p->thread_num);
+
+		dprintk("%s: locking list_empty: %d, thread_num: %d.\n",
+				__func__, list_empty(&p->ready_list), p->thread_num);
+
+		mutex_lock(&p->thread_lock);
+		if (!list_empty(&p->ready_list)) {
+			w = list_first_entry(&p->ready_list,
+					struct thread_pool_worker,
+					worker_entry);
+
+			dprintk("%s: deleting w: %p, thread_num: %d, list: %p [%p.%p].\n",
+					__func__, w, p->thread_num, &p->ready_list,
+					p->ready_list.prev, p->ready_list.next);
+
+			p->thread_num--;
+			list_del(&w->worker_entry);
+		}
+		mutex_unlock(&p->thread_lock);
+	}
+
+	if (w)
+		thread_pool_exit_worker(w);
+	dprintk("%s: deleted w: %p, thread_num: %d.\n",
+			__func__, w, p->thread_num);
+}
+
+/*
+ * Remove a worker with given ID.
+ */
+void thread_pool_del_worker_id(struct thread_pool *p, unsigned int id)
+{
+	struct thread_pool_worker *w;
+	int found = 0;
+
+	mutex_lock(&p->thread_lock);
+	list_for_each_entry(w, &p->ready_list, worker_entry) {
+		if (w->id == id) {
+			found = 1;
+			p->thread_num--;
+			list_del(&w->worker_entry);
+			break;
+		}
+	}
+
+	if (!found) {
+		list_for_each_entry(w, &p->active_list, worker_entry) {
+			if (w->id == id) {
+				w->need_exit = 1;
+				break;
+			}
+		}
+	}
+	mutex_unlock(&p->thread_lock);
+
+	if (found)
+		thread_pool_exit_worker(w);
+}
+
+/*
+ * Add new worker thread with given parameters.
+ * If initialization callback fails, return error.
+ */
+int thread_pool_add_worker(struct thread_pool *p,
+		char *name,
+		unsigned int id,
+		void *(* init)(void *private),
+		void (* cleanup)(void *private),
+		void *private)
+{
+	struct thread_pool_worker *w;
+	int err = -ENOMEM;
+
+	w = kzalloc(sizeof(struct thread_pool_worker), GFP_KERNEL);
+	if (!w)
+		goto err_out_exit;
+
+	w->pool = p;
+	init_waitqueue_head(&w->wait);
+	w->cleanup = cleanup;
+	w->id = id;
+
+	w->thread = kthread_run(thread_pool_worker_func, w, "%s", name);
+	if (IS_ERR(w->thread)) {
+		err = PTR_ERR(w->thread);
+		goto err_out_free;
+	}
+
+	w->private = init(private);
+	if (IS_ERR(w->private)) {
+		err = PTR_ERR(w->private);
+		goto err_out_stop_thread;
+	}
+
+	mutex_lock(&p->thread_lock);
+	list_add_tail(&w->worker_entry, &p->ready_list);
+	p->thread_num++;
+	mutex_unlock(&p->thread_lock);
+
+	return 0;
+
+err_out_stop_thread:
+	kthread_stop(w->thread);
+err_out_free:
+	kfree(w);
+err_out_exit:
+	return err;
+}
+
+/*
+ * Destroy the whole pool.
+ */
+void thread_pool_destroy(struct thread_pool *p)
+{
+	while (p->thread_num) {
+		dprintk("%s: num: %d.\n", __func__, p->thread_num);
+		thread_pool_del_worker(p);
+	}
+
+	kfree(p);
+}
+
+/*
+ * Create a pool with given number of threads.
+ * They will have sequential IDs started from zero.
+ */
+struct thread_pool *thread_pool_create(int num, char *name,
+		void *(* init)(void *private),
+		void (* cleanup)(void *private),
+		void *private)
+{
+	struct thread_pool_worker *w, *tmp;
+	struct thread_pool *p;
+	int err = -ENOMEM;
+	int i;
+
+	p = kzalloc(sizeof(struct thread_pool), GFP_KERNEL);
+	if (!p)
+		goto err_out_exit;
+
+	init_waitqueue_head(&p->wait);
+	mutex_init(&p->thread_lock);
+	INIT_LIST_HEAD(&p->ready_list);
+	INIT_LIST_HEAD(&p->active_list);
+	p->thread_num = 0;
+
+	for (i=0; i<num; ++i) {
+		err = thread_pool_add_worker(p, name, i, init,
+				cleanup, private);
+		if (err)
+			goto err_out_free_all;
+	}
+
+	return p;
+
+err_out_free_all:
+	list_for_each_entry_safe(w, tmp, &p->ready_list, worker_entry) {
+		list_del(&w->worker_entry);
+		thread_pool_exit_worker(w);
+	}
+	kfree(p);
+err_out_exit:
+	return ERR_PTR(err);
+}
+
+/*
+ * Schedule execution of the action on a given thread,
+ * provided ID pointer has to match previously stored
+ * private data.
+ */
+int thread_pool_schedule_private(struct thread_pool *p,
+		int (* setup)(void *private, void *data),
+		int (* action)(void *private, void *data),
+		void *data, long timeout, void *id)
+{
+	struct thread_pool_worker *w, *tmp, *worker = NULL;
+	int err = 0;
+
+	while (!worker && !err) {
+		timeout = wait_event_interruptible_timeout(p->wait,
+				!list_empty(&p->ready_list),
+				timeout);
+
+		if (!timeout) {
+			err = -ETIMEDOUT;
+			break;
+		}
+
+		worker = NULL;
+		mutex_lock(&p->thread_lock);
+		list_for_each_entry_safe(w, tmp, &p->ready_list, worker_entry) {
+			if (id && id != w->private)
+				continue;
+
+			worker = w;
+
+			list_move_tail(&w->worker_entry, &p->active_list);
+
+			err = setup(w->private, data);
+			if (!err) {
+				w->schedule_data = data;
+				w->action = action;
+				w->has_data = 1;
+				wake_up(&w->wait);
+			} else {
+				list_move_tail(&w->worker_entry, &p->ready_list);
+			}
+
+			break;
+		}
+		mutex_unlock(&p->thread_lock);
+	}
+
+	return err;
+}
+
+/*
+ * Schedule execution on arbitrary thread from the pool.
+ */
+int thread_pool_schedule(struct thread_pool *p,
+		int (* setup)(void *private, void *data),
+		int (* action)(void *private, void *data),
+		void *data, long timeout)
+{
+	return thread_pool_schedule_private(p, setup,
+			action, data, timeout, NULL);
+}
diff --git a/drivers/staging/dst/trans.c b/drivers/staging/dst/trans.c
new file mode 100644
index 0000000..557d372
--- /dev/null
+++ b/drivers/staging/dst/trans.c
@@ -0,0 +1,335 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * 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.
+ *
+ * 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/bio.h>
+#include <linux/dst.h>
+#include <linux/slab.h>
+#include <linux/mempool.h>
+
+/*
+ * Transaction memory pool size.
+ */
+static int dst_mempool_num = 32;
+module_param(dst_mempool_num, int, 0644);
+
+/*
+ * Transaction tree management.
+ */
+static inline int dst_trans_cmp(dst_gen_t gen, dst_gen_t new)
+{
+	if (gen < new)
+		return 1;
+	if (gen > new)
+		return -1;
+	return 0;
+}
+
+struct dst_trans *dst_trans_search(struct dst_node *node, dst_gen_t gen)
+{
+	struct rb_root *root = &node->trans_root;
+	struct rb_node *n = root->rb_node;
+	struct dst_trans *t, *ret = NULL;
+	int cmp;
+
+	while (n) {
+		t = rb_entry(n, struct dst_trans, trans_entry);
+
+		cmp = dst_trans_cmp(t->gen, gen);
+		if (cmp < 0)
+			n = n->rb_left;
+		else if (cmp > 0)
+			n = n->rb_right;
+		else {
+			ret = t;
+			break;
+		}
+	}
+
+	dprintk("%s: %s transaction: id: %llu.\n", __func__,
+			(ret)?"found":"not found", gen);
+
+	return ret;
+}
+
+static int dst_trans_insert(struct dst_trans *new)
+{
+	struct rb_root *root = &new->n->trans_root;
+	struct rb_node **n = &root->rb_node, *parent = NULL;
+	struct dst_trans *ret = NULL, *t;
+	int cmp;
+
+	while (*n) {
+		parent = *n;
+
+		t = rb_entry(parent, struct dst_trans, trans_entry);
+
+		cmp = dst_trans_cmp(t->gen, new->gen);
+		if (cmp < 0)
+			n = &parent->rb_left;
+		else if (cmp > 0)
+			n = &parent->rb_right;
+		else {
+			ret = t;
+			break;
+		}
+	}
+
+	new->send_time = jiffies;
+	if (ret) {
+		printk("%s: exist: old: gen: %llu, bio: %llu/%u, send_time: %lu, "
+				"new: gen: %llu, bio: %llu/%u, send_time: %lu.\n",
+			__func__,
+			ret->gen, (u64)ret->bio->bi_sector,
+			ret->bio->bi_size, ret->send_time,
+			new->gen, (u64)new->bio->bi_sector,
+			new->bio->bi_size, new->send_time);
+		return -EEXIST;
+	}
+
+	rb_link_node(&new->trans_entry, parent, n);
+	rb_insert_color(&new->trans_entry, root);
+
+	dprintk("%s: inserted: gen: %llu, bio: %llu/%u, send_time: %lu.\n",
+		__func__, new->gen, (u64)new->bio->bi_sector,
+		new->bio->bi_size, new->send_time);
+
+	return 0;
+}
+
+int dst_trans_remove_nolock(struct dst_trans *t)
+{
+	struct dst_node *n = t->n;
+
+	if (t->trans_entry.rb_parent_color) {
+		rb_erase(&t->trans_entry, &n->trans_root);
+		t->trans_entry.rb_parent_color = 0;
+	}
+	return 0;
+}
+
+int dst_trans_remove(struct dst_trans *t)
+{
+	int ret;
+	struct dst_node *n = t->n;
+
+	mutex_lock(&n->trans_lock);
+	ret = dst_trans_remove_nolock(t);
+	mutex_unlock(&n->trans_lock);
+
+	return ret;
+}
+
+/*
+ * When transaction is completed and there are no more users,
+ * we complete appriate block IO request with given error status.
+ */
+void dst_trans_put(struct dst_trans *t)
+{
+	if (atomic_dec_and_test(&t->refcnt)) {
+		struct bio *bio = t->bio;
+
+		dprintk("%s: completed t: %p, gen: %llu, bio: %p.\n",
+				__func__, t, t->gen, bio);
+
+		bio_endio(bio, t->error);
+		bio_put(bio);
+
+		dst_node_put(t->n);
+		mempool_free(t, t->n->trans_pool);
+	}
+}
+
+/*
+ * Process given block IO request: allocate transaction, insert it into the tree
+ * and send/schedule crypto processing.
+ */
+int dst_process_bio(struct dst_node *n, struct bio *bio)
+{
+	struct dst_trans *t;
+	int err = -ENOMEM;
+
+	t = mempool_alloc(n->trans_pool, GFP_NOFS);
+	if (!t)
+		goto err_out_exit;
+
+	t->n = dst_node_get(n);
+	t->bio = bio;
+	t->error = 0;
+	t->retries = 0;
+	atomic_set(&t->refcnt, 1);
+	t->gen = atomic_long_inc_return(&n->gen);
+
+	t->enc = bio_data_dir(bio);
+	dst_bio_to_cmd(bio, &t->cmd, DST_IO, t->gen);
+
+	mutex_lock(&n->trans_lock);
+	err = dst_trans_insert(t);
+	mutex_unlock(&n->trans_lock);
+	if (err)
+		goto err_out_free;
+
+	dprintk("%s: gen: %llu, bio: %llu/%u, dir/enc: %d, need_crypto: %d.\n",
+			__func__, t->gen, (u64)bio->bi_sector,
+			bio->bi_size, t->enc, dst_need_crypto(n));
+
+	if (dst_need_crypto(n) && t->enc)
+		dst_trans_crypto(t);
+	else
+		dst_trans_send(t);
+
+	return 0;
+
+err_out_free:
+	dst_node_put(n);
+	mempool_free(t, n->trans_pool);
+err_out_exit:
+	bio_endio(bio, err);
+	bio_put(bio);
+	return err;
+}
+
+/*
+ * Scan for timeout/stale transactions.
+ * Each transaction is being resent multiple times before error completion.
+ */
+static void dst_trans_scan(struct work_struct *work)
+{
+	struct dst_node *n = container_of(work, struct dst_node, trans_work.work);
+	struct rb_node *rb_node;
+	struct dst_trans *t;
+	unsigned long timeout = n->trans_scan_timeout;
+	int num = 10 * n->trans_max_retries;
+
+	mutex_lock(&n->trans_lock);
+
+	for (rb_node = rb_first(&n->trans_root); rb_node; ) {
+		t = rb_entry(rb_node, struct dst_trans, trans_entry);
+
+		if (timeout && time_after(t->send_time + timeout, jiffies)
+				&& t->retries == 0)
+			break;
+#if 0
+		dprintk("%s: t: %p, gen: %llu, n: %s, retries: %u, max: %u.\n",
+			__func__, t, t->gen, n->name,
+			t->retries, n->trans_max_retries);
+#endif
+		if (--num == 0)
+			break;
+
+		dst_trans_get(t);
+
+		rb_node = rb_next(rb_node);
+
+		if (timeout && (++t->retries < n->trans_max_retries)) {
+			dst_trans_send(t);
+		} else {
+			t->error = -ETIMEDOUT;
+			dst_trans_remove_nolock(t);
+			dst_trans_put(t);
+		}
+
+		dst_trans_put(t);
+	}
+
+	mutex_unlock(&n->trans_lock);
+
+	/*
+	 * If no timeout specified then system is in the middle of exiting process,
+	 * so no need to reschedule scanning process again.
+	 */
+	if (timeout) {
+		if (!num)
+			timeout = HZ;
+		schedule_delayed_work(&n->trans_work, timeout);
+	}
+}
+
+/*
+ * Flush all transactions and mark them as timed out.
+ * Destroy transaction pools.
+ */
+void dst_node_trans_exit(struct dst_node *n)
+{
+	struct dst_trans *t;
+	struct rb_node *rb_node;
+
+	if (!n->trans_cache)
+		return;
+
+	dprintk("%s: n: %p, cancelling the work.\n", __func__, n);
+	cancel_delayed_work_sync(&n->trans_work);
+	flush_scheduled_work();
+	dprintk("%s: n: %p, work has been cancelled.\n", __func__, n);
+
+	for (rb_node = rb_first(&n->trans_root); rb_node; ) {
+		t = rb_entry(rb_node, struct dst_trans, trans_entry);
+
+		dprintk("%s: t: %p, gen: %llu, n: %s.\n",
+			__func__, t, t->gen, n->name);
+
+		rb_node = rb_next(rb_node);
+
+		t->error = -ETIMEDOUT;
+		dst_trans_remove_nolock(t);
+		dst_trans_put(t);
+	}
+
+	mempool_destroy(n->trans_pool);
+	kmem_cache_destroy(n->trans_cache);
+}
+
+/*
+ * Initialize transaction storage for given node.
+ * Transaction stores not only control information,
+ * but also network command and crypto data (if needed)
+ * to reduce number of allocations. Thus transaction size
+ * differs from node to node.
+ */
+int dst_node_trans_init(struct dst_node *n, unsigned int size)
+{
+	/*
+	 * We need this, since node with given name can be dropped from the
+	 * hash table, but be still alive, so subsequent creation of the node
+	 * with the same name may collide with existing cache name.
+	 */
+
+	snprintf(n->cache_name, sizeof(n->cache_name), "%s-%p", n->name, n);
+
+	n->trans_cache = kmem_cache_create(n->cache_name,
+			size + n->crypto.crypto_attached_size,
+			0, 0, NULL);
+	if (!n->trans_cache)
+		goto err_out_exit;
+
+	n->trans_pool = mempool_create_slab_pool(dst_mempool_num, n->trans_cache);
+	if (!n->trans_pool)
+		goto err_out_cache_destroy;
+
+	mutex_init(&n->trans_lock);
+	n->trans_root = RB_ROOT;
+
+	INIT_DELAYED_WORK(&n->trans_work, dst_trans_scan);
+	schedule_delayed_work(&n->trans_work, n->trans_scan_timeout);
+
+	dprintk("%s: n: %p, size: %u, crypto: %u.\n",
+		__func__, n, size, n->crypto.crypto_attached_size);
+
+	return 0;
+
+err_out_cache_destroy:
+	kmem_cache_destroy(n->trans_cache);
+err_out_exit:
+	return -ENOMEM;
+}
diff --git a/drivers/staging/echo/bit_operations.h b/drivers/staging/echo/bit_operations.h
index cecdcf3..4c4ccbc 100644
--- a/drivers/staging/echo/bit_operations.h
+++ b/drivers/staging/echo/bit_operations.h
@@ -21,8 +21,6 @@
  * 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.
- *
- * $Id: bit_operations.h,v 1.11 2006/11/28 15:37:03 steveu Exp $
  */
 
 /*! \file */
@@ -34,7 +32,7 @@
 /*! \brief Find the bit position of the highest set bit in a word
     \param bits The word to be searched
     \return The bit number of the highest set bit, or -1 if the word is zero. */
-static __inline__ int top_bit(unsigned int bits)
+static inline int top_bit(unsigned int bits)
 {
 	int res;
 
@@ -50,7 +48,7 @@
 /*! \brief Find the bit position of the lowest set bit in a word
     \param bits The word to be searched
     \return The bit number of the lowest set bit, or -1 if the word is zero. */
-static __inline__ int bottom_bit(unsigned int bits)
+static inline int bottom_bit(unsigned int bits)
 {
 	int res;
 
@@ -63,7 +61,7 @@
 	return res;
 }
 #else
-static __inline__ int top_bit(unsigned int bits)
+static inline int top_bit(unsigned int bits)
 {
 	int i;
 
@@ -93,7 +91,7 @@
 	return i;
 }
 
-static __inline__ int bottom_bit(unsigned int bits)
+static inline int bottom_bit(unsigned int bits)
 {
 	int i;
 
@@ -127,7 +125,7 @@
 /*! \brief Bit reverse a byte.
     \param data The byte to be reversed.
     \return The bit reversed version of data. */
-static __inline__ uint8_t bit_reverse8(uint8_t x)
+static inline uint8_t bit_reverse8(uint8_t x)
 {
 #if defined(__i386__)  ||  defined(__x86_64__)
 	/* If multiply is fast */
@@ -172,32 +170,32 @@
 uint16_t make_mask16(uint16_t x);
 
 /*! \brief Find the least significant one in a word, and return a word
-           with just that bit set.
+	    with just that bit set.
     \param x The word to be searched.
     \return The word with the single set bit. */
-static __inline__ uint32_t least_significant_one32(uint32_t x)
+static inline uint32_t least_significant_one32(uint32_t x)
 {
-	return (x & (-(int32_t) x));
+	return x & (-(int32_t) x);
 }
 
 /*! \brief Find the most significant one in a word, and return a word
-           with just that bit set.
+	    with just that bit set.
     \param x The word to be searched.
     \return The word with the single set bit. */
-static __inline__ uint32_t most_significant_one32(uint32_t x)
+static inline uint32_t most_significant_one32(uint32_t x)
 {
 #if defined(__i386__)  ||  defined(__x86_64__)
 	return 1 << top_bit(x);
 #else
 	x = make_mask32(x);
-	return (x ^ (x >> 1));
+	return x ^ (x >> 1);
 #endif
 }
 
 /*! \brief Find the parity of a byte.
     \param x The byte to be checked.
     \return 1 for odd, or 0 for even. */
-static __inline__ int parity8(uint8_t x)
+static inline int parity8(uint8_t x)
 {
 	x = (x ^ (x >> 4)) & 0x0F;
 	return (0x6996 >> x) & 1;
@@ -206,7 +204,7 @@
 /*! \brief Find the parity of a 16 bit word.
     \param x The word to be checked.
     \return 1 for odd, or 0 for even. */
-static __inline__ int parity16(uint16_t x)
+static inline int parity16(uint16_t x)
 {
 	x ^= (x >> 8);
 	x = (x ^ (x >> 4)) & 0x0F;
@@ -216,7 +214,7 @@
 /*! \brief Find the parity of a 32 bit word.
     \param x The word to be checked.
     \return 1 for odd, or 0 for even. */
-static __inline__ int parity32(uint32_t x)
+static inline int parity32(uint32_t x)
 {
 	x ^= (x >> 16);
 	x ^= (x >> 8);
diff --git a/drivers/staging/echo/echo.c b/drivers/staging/echo/echo.c
index fd4007e..6d7217e 100644
--- a/drivers/staging/echo/echo.c
+++ b/drivers/staging/echo/echo.c
@@ -27,8 +27,6 @@
  * 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.
- *
- * $Id: echo.c,v 1.20 2006/12/01 18:00:48 steveu Exp $
  */
 
 /*! \file */
@@ -113,17 +111,17 @@
 
 #define MIN_TX_POWER_FOR_ADAPTION   64
 #define MIN_RX_POWER_FOR_ADAPTION   64
-#define DTD_HANGOVER               600	/* 600 samples, or 75ms     */
-#define DC_LOG2BETA                  3	/* log2() of DC filter Beta */
+#define DTD_HANGOVER		 600	/* 600 samples, or 75ms     */
+#define DC_LOG2BETA		    3	/* log2() of DC filter Beta */
 
 /*-----------------------------------------------------------------------*\
-                               FUNCTIONS
+				   FUNCTIONS
 \*-----------------------------------------------------------------------*/
 
 /* adapting coeffs using the traditional stochastic descent (N)LMS algorithm */
 
 #ifdef __bfin__
-static void __inline__ lms_adapt_bg(struct oslec_state *ec, int clean,
+static inline void lms_adapt_bg(struct oslec_state *ec, int clean,
 				    int shift)
 {
 	int i, j;
@@ -147,13 +145,13 @@
 
 	/* st: and en: help us locate the assembler in echo.s */
 
-	//asm("st:");
+	/* asm("st:"); */
 	n = ec->taps;
 	for (i = 0, j = offset2; i < n; i++, j++) {
 		exp = *phist++ * factor;
 		ec->fir_taps16[1][i] += (int16_t) ((exp + (1 << 14)) >> 15);
 	}
-	//asm("en:");
+	/* asm("en:"); */
 
 	/* Note the asm for the inner loop above generated by Blackfin gcc
 	   4.1.1 is pretty good (note even parallel instructions used):
@@ -195,7 +193,7 @@
 */
 
 #else
-static __inline__ void lms_adapt_bg(struct oslec_state *ec, int clean,
+static inline void lms_adapt_bg(struct oslec_state *ec, int clean,
 				    int shift)
 {
 	int i;
@@ -249,9 +247,8 @@
 	fir16_create(&ec->fir_state, ec->fir_taps16[0], ec->taps);
 	fir16_create(&ec->fir_state_bg, ec->fir_taps16[1], ec->taps);
 
-	for (i = 0; i < 5; i++) {
+	for (i = 0; i < 5; i++)
 		ec->xvtx[i] = ec->yvtx[i] = ec->xvrx[i] = ec->yvrx[i] = 0;
-	}
 
 	ec->cng_level = 1000;
 	oslec_adaption_mode(ec, adaption_mode);
@@ -271,14 +268,13 @@
 
 	return ec;
 
-      error_oom:
+error_oom:
 	for (i = 0; i < 2; i++)
 		kfree(ec->fir_taps16[i]);
 
 	kfree(ec);
 	return NULL;
 }
-
 EXPORT_SYMBOL_GPL(oslec_create);
 
 void oslec_free(struct oslec_state *ec)
@@ -292,14 +288,12 @@
 	kfree(ec->snapshot);
 	kfree(ec);
 }
-
 EXPORT_SYMBOL_GPL(oslec_free);
 
 void oslec_adaption_mode(struct oslec_state *ec, int adaption_mode)
 {
 	ec->adaption_mode = adaption_mode;
 }
-
 EXPORT_SYMBOL_GPL(oslec_adaption_mode);
 
 void oslec_flush(struct oslec_state *ec)
@@ -326,14 +320,12 @@
 	ec->curr_pos = ec->taps - 1;
 	ec->Pstates = 0;
 }
-
 EXPORT_SYMBOL_GPL(oslec_flush);
 
 void oslec_snapshot(struct oslec_state *ec)
 {
 	memcpy(ec->snapshot, ec->fir_taps16[0], ec->taps * sizeof(int16_t));
 }
-
 EXPORT_SYMBOL_GPL(oslec_snapshot);
 
 /* Dual Path Echo Canceller ------------------------------------------------*/
@@ -399,7 +391,7 @@
 		/* efficient "out with the old and in with the new" algorithm so
 		   we don't have to recalculate over the whole block of
 		   samples. */
-		new = (int)tx *(int)tx;
+		new = (int)tx * (int)tx;
 		old = (int)ec->fir_state.history[ec->fir_state.curr_pos] *
 		    (int)ec->fir_state.history[ec->fir_state.curr_pos];
 		ec->Pstates +=
@@ -498,15 +490,15 @@
 
 	if ((ec->adaption_mode & ECHO_CAN_USE_ADAPTION) &&
 	    (ec->nonupdate_dwell == 0) &&
-	    (8 * ec->Lclean_bg <
-	     7 * ec->Lclean) /* (ec->Lclean_bg < 0.875*ec->Lclean) */ &&
-	    (8 * ec->Lclean_bg <
-	     ec->Ltx) /* (ec->Lclean_bg < 0.125*ec->Ltx)    */ ) {
+	    /* (ec->Lclean_bg < 0.875*ec->Lclean) */
+	    (8 * ec->Lclean_bg < 7 * ec->Lclean) &&
+	    /* (ec->Lclean_bg < 0.125*ec->Ltx) */
+	    (8 * ec->Lclean_bg < ec->Ltx)) {
 		if (ec->cond_met == 6) {
 			/* BG filter has had better results for 6 consecutive samples */
 			ec->adapt = 1;
 			memcpy(ec->fir_taps16[0], ec->fir_taps16[1],
-			       ec->taps * sizeof(int16_t));
+				ec->taps * sizeof(int16_t));
 		} else
 			ec->cond_met++;
 	} else
@@ -580,7 +572,6 @@
 
 	return (int16_t) ec->clean_nlp << 1;
 }
-
 EXPORT_SYMBOL_GPL(oslec_update);
 
 /* This function is seperated from the echo canceller is it is usually called
@@ -604,7 +595,7 @@
    precision, which noise shapes things, giving very clean DC removal.
 */
 
-int16_t oslec_hpf_tx(struct oslec_state * ec, int16_t tx)
+int16_t oslec_hpf_tx(struct oslec_state *ec, int16_t tx)
 {
 	int tmp, tmp1;
 
@@ -629,7 +620,6 @@
 
 	return tx;
 }
-
 EXPORT_SYMBOL_GPL(oslec_hpf_tx);
 
 MODULE_LICENSE("GPL");
diff --git a/drivers/staging/echo/echo.h b/drivers/staging/echo/echo.h
index 34fb816..c835e5c 100644
--- a/drivers/staging/echo/echo.h
+++ b/drivers/staging/echo/echo.h
@@ -23,8 +23,6 @@
  * 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.
- *
- * $Id: echo.h,v 1.9 2006/10/24 13:45:28 steveu Exp $
  */
 
 #ifndef __ECHO_H
diff --git a/drivers/staging/echo/fir.h b/drivers/staging/echo/fir.h
index d35f168..ac6c553 100644
--- a/drivers/staging/echo/fir.h
+++ b/drivers/staging/echo/fir.h
@@ -21,8 +21,6 @@
  * 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.
- *
- * $Id: fir.h,v 1.8 2006/10/24 13:45:28 steveu Exp $
  */
 
 /*! \page fir_page FIR filtering
@@ -102,8 +100,8 @@
 	float *history;
 };
 
-static __inline__ const int16_t *fir16_create(struct fir16_state_t *fir,
-					      const int16_t * coeffs, int taps)
+static inline const int16_t *fir16_create(struct fir16_state_t *fir,
+					      const int16_t *coeffs, int taps)
 {
 	fir->taps = taps;
 	fir->curr_pos = taps - 1;
@@ -116,7 +114,7 @@
 	return fir->history;
 }
 
-static __inline__ void fir16_flush(struct fir16_state_t *fir)
+static inline void fir16_flush(struct fir16_state_t *fir)
 {
 #if defined(USE_MMX)  ||  defined(USE_SSE2) || defined(__bfin__)
 	memset(fir->history, 0, 2 * fir->taps * sizeof(int16_t));
@@ -125,7 +123,7 @@
 #endif
 }
 
-static __inline__ void fir16_free(struct fir16_state_t *fir)
+static inline void fir16_free(struct fir16_state_t *fir)
 {
 	kfree(fir->history);
 }
@@ -148,16 +146,16 @@
 		"A0 += R0.L*R1.L (IS);\n\t"
 		"R0 = A0;\n\t"
 		"%0 = R0;\n\t"
-		:"=&d"(dot)
-		:"a"(x), "a"(y), "a"(len)
-		:"I0", "I1", "A1", "A0", "R0", "R1"
+		: "=&d"(dot)
+		: "a"(x), "a"(y), "a"(len)
+		: "I0", "I1", "A1", "A0", "R0", "R1"
 	);
 
 	return dot;
 }
 #endif
 
-static __inline__ int16_t fir16(struct fir16_state_t *fir, int16_t sample)
+static inline int16_t fir16(struct fir16_state_t *fir, int16_t sample)
 {
 	int32_t y;
 #if defined(USE_MMX)
@@ -250,8 +248,8 @@
 	return (int16_t) (y >> 15);
 }
 
-static __inline__ const int16_t *fir32_create(struct fir32_state_t *fir,
-					      const int32_t * coeffs, int taps)
+static inline const int16_t *fir32_create(struct fir32_state_t *fir,
+					      const int32_t *coeffs, int taps)
 {
 	fir->taps = taps;
 	fir->curr_pos = taps - 1;
@@ -260,17 +258,17 @@
 	return fir->history;
 }
 
-static __inline__ void fir32_flush(struct fir32_state_t *fir)
+static inline void fir32_flush(struct fir32_state_t *fir)
 {
 	memset(fir->history, 0, fir->taps * sizeof(int16_t));
 }
 
-static __inline__ void fir32_free(struct fir32_state_t *fir)
+static inline void fir32_free(struct fir32_state_t *fir)
 {
 	kfree(fir->history);
 }
 
-static __inline__ int16_t fir32(struct fir32_state_t *fir, int16_t sample)
+static inline int16_t fir32(struct fir32_state_t *fir, int16_t sample)
 {
 	int i;
 	int32_t y;
diff --git a/drivers/staging/echo/mmx.h b/drivers/staging/echo/mmx.h
index 44e5cfe..c1dcd72 100644
--- a/drivers/staging/echo/mmx.h
+++ b/drivers/staging/echo/mmx.h
@@ -44,238 +44,238 @@
 	char b[16];
 };
 
-#define         mmx_i2r(op,imm,reg) \
-        __asm__ __volatile__ (#op " %0, %%" #reg \
-                              : /* nothing */ \
-                              : "i" (imm) )
+#define	mmx_i2r(op, imm, reg) \
+	__asm__ __volatile__ (#op " %0, %%" #reg \
+				: /* nothing */ \
+				: "i" (imm))
 
-#define         mmx_m2r(op,mem,reg) \
-        __asm__ __volatile__ (#op " %0, %%" #reg \
-                              : /* nothing */ \
-                              : "m" (mem))
+#define	mmx_m2r(op, mem, reg) \
+	__asm__ __volatile__ (#op " %0, %%" #reg \
+				: /* nothing */ \
+				: "m" (mem))
 
-#define         mmx_r2m(op,reg,mem) \
-        __asm__ __volatile__ (#op " %%" #reg ", %0" \
-                              : "=m" (mem) \
-                              : /* nothing */ )
+#define	mmx_r2m(op, reg, mem) \
+	__asm__ __volatile__ (#op " %%" #reg ", %0" \
+				: "=m" (mem) \
+				: /* nothing */)
 
-#define         mmx_r2r(op,regs,regd) \
-        __asm__ __volatile__ (#op " %" #regs ", %" #regd)
+#define	mmx_r2r(op, regs, regd) \
+	__asm__ __volatile__ (#op " %" #regs ", %" #regd)
 
-#define         emms() __asm__ __volatile__ ("emms")
+#define	emms() __asm__ __volatile__ ("emms")
 
-#define         movd_m2r(var,reg)           mmx_m2r (movd, var, reg)
-#define         movd_r2m(reg,var)           mmx_r2m (movd, reg, var)
-#define         movd_r2r(regs,regd)         mmx_r2r (movd, regs, regd)
+#define	movd_m2r(var, reg)	mmx_m2r(movd, var, reg)
+#define	movd_r2m(reg, var)	mmx_r2m(movd, reg, var)
+#define	movd_r2r(regs, regd)	mmx_r2r(movd, regs, regd)
 
-#define         movq_m2r(var,reg)           mmx_m2r (movq, var, reg)
-#define         movq_r2m(reg,var)           mmx_r2m (movq, reg, var)
-#define         movq_r2r(regs,regd)         mmx_r2r (movq, regs, regd)
+#define	movq_m2r(var, reg)	mmx_m2r(movq, var, reg)
+#define	movq_r2m(reg, var)	mmx_r2m(movq, reg, var)
+#define	movq_r2r(regs, regd)	mmx_r2r(movq, regs, regd)
 
-#define         packssdw_m2r(var,reg)       mmx_m2r (packssdw, var, reg)
-#define         packssdw_r2r(regs,regd)     mmx_r2r (packssdw, regs, regd)
-#define         packsswb_m2r(var,reg)       mmx_m2r (packsswb, var, reg)
-#define         packsswb_r2r(regs,regd)     mmx_r2r (packsswb, regs, regd)
+#define	packssdw_m2r(var, reg)		mmx_m2r(packssdw, var, reg)
+#define	packssdw_r2r(regs, regd)	mmx_r2r(packssdw, regs, regd)
+#define	packsswb_m2r(var, reg)		mmx_m2r(packsswb, var, reg)
+#define	packsswb_r2r(regs, regd)	mmx_r2r(packsswb, regs, regd)
 
-#define         packuswb_m2r(var,reg)       mmx_m2r (packuswb, var, reg)
-#define         packuswb_r2r(regs,regd)     mmx_r2r (packuswb, regs, regd)
+#define	packuswb_m2r(var, reg)		mmx_m2r(packuswb, var, reg)
+#define	packuswb_r2r(regs, regd)	mmx_r2r(packuswb, regs, regd)
 
-#define         paddb_m2r(var,reg)          mmx_m2r (paddb, var, reg)
-#define         paddb_r2r(regs,regd)        mmx_r2r (paddb, regs, regd)
-#define         paddd_m2r(var,reg)          mmx_m2r (paddd, var, reg)
-#define         paddd_r2r(regs,regd)        mmx_r2r (paddd, regs, regd)
-#define         paddw_m2r(var,reg)          mmx_m2r (paddw, var, reg)
-#define         paddw_r2r(regs,regd)        mmx_r2r (paddw, regs, regd)
+#define	paddb_m2r(var, reg)	mmx_m2r(paddb, var, reg)
+#define	paddb_r2r(regs, regd)	mmx_r2r(paddb, regs, regd)
+#define	paddd_m2r(var, reg)	mmx_m2r(paddd, var, reg)
+#define	paddd_r2r(regs, regd)	mmx_r2r(paddd, regs, regd)
+#define	paddw_m2r(var, reg)	mmx_m2r(paddw, var, reg)
+#define	paddw_r2r(regs, regd)	mmx_r2r(paddw, regs, regd)
 
-#define         paddsb_m2r(var,reg)         mmx_m2r (paddsb, var, reg)
-#define         paddsb_r2r(regs,regd)       mmx_r2r (paddsb, regs, regd)
-#define         paddsw_m2r(var,reg)         mmx_m2r (paddsw, var, reg)
-#define         paddsw_r2r(regs,regd)       mmx_r2r (paddsw, regs, regd)
+#define	paddsb_m2r(var, reg)	mmx_m2r(paddsb, var, reg)
+#define	paddsb_r2r(regs, regd)	mmx_r2r(paddsb, regs, regd)
+#define	paddsw_m2r(var, reg)	mmx_m2r(paddsw, var, reg)
+#define	paddsw_r2r(regs, regd)	mmx_r2r(paddsw, regs, regd)
 
-#define         paddusb_m2r(var,reg)        mmx_m2r (paddusb, var, reg)
-#define         paddusb_r2r(regs,regd)      mmx_r2r (paddusb, regs, regd)
-#define         paddusw_m2r(var,reg)        mmx_m2r (paddusw, var, reg)
-#define         paddusw_r2r(regs,regd)      mmx_r2r (paddusw, regs, regd)
+#define	paddusb_m2r(var, reg)	mmx_m2r(paddusb, var, reg)
+#define	paddusb_r2r(regs, regd)	mmx_r2r(paddusb, regs, regd)
+#define	paddusw_m2r(var, reg)	mmx_m2r(paddusw, var, reg)
+#define	paddusw_r2r(regs, regd)	mmx_r2r(paddusw, regs, regd)
 
-#define         pand_m2r(var,reg)           mmx_m2r (pand, var, reg)
-#define         pand_r2r(regs,regd)         mmx_r2r (pand, regs, regd)
+#define	pand_m2r(var, reg)	mmx_m2r(pand, var, reg)
+#define	pand_r2r(regs, regd)	mmx_r2r(pand, regs, regd)
 
-#define         pandn_m2r(var,reg)          mmx_m2r (pandn, var, reg)
-#define         pandn_r2r(regs,regd)        mmx_r2r (pandn, regs, regd)
+#define	pandn_m2r(var, reg)	mmx_m2r(pandn, var, reg)
+#define	pandn_r2r(regs, regd)	mmx_r2r(pandn, regs, regd)
 
-#define         pcmpeqb_m2r(var,reg)        mmx_m2r (pcmpeqb, var, reg)
-#define         pcmpeqb_r2r(regs,regd)      mmx_r2r (pcmpeqb, regs, regd)
-#define         pcmpeqd_m2r(var,reg)        mmx_m2r (pcmpeqd, var, reg)
-#define         pcmpeqd_r2r(regs,regd)      mmx_r2r (pcmpeqd, regs, regd)
-#define         pcmpeqw_m2r(var,reg)        mmx_m2r (pcmpeqw, var, reg)
-#define         pcmpeqw_r2r(regs,regd)      mmx_r2r (pcmpeqw, regs, regd)
+#define	pcmpeqb_m2r(var, reg)	mmx_m2r(pcmpeqb, var, reg)
+#define	pcmpeqb_r2r(regs, regd)	mmx_r2r(pcmpeqb, regs, regd)
+#define	pcmpeqd_m2r(var, reg)	mmx_m2r(pcmpeqd, var, reg)
+#define	pcmpeqd_r2r(regs, regd)	mmx_r2r(pcmpeqd, regs, regd)
+#define	pcmpeqw_m2r(var, reg)	mmx_m2r(pcmpeqw, var, reg)
+#define	pcmpeqw_r2r(regs, regd)	mmx_r2r(pcmpeqw, regs, regd)
 
-#define         pcmpgtb_m2r(var,reg)        mmx_m2r (pcmpgtb, var, reg)
-#define         pcmpgtb_r2r(regs,regd)      mmx_r2r (pcmpgtb, regs, regd)
-#define         pcmpgtd_m2r(var,reg)        mmx_m2r (pcmpgtd, var, reg)
-#define         pcmpgtd_r2r(regs,regd)      mmx_r2r (pcmpgtd, regs, regd)
-#define         pcmpgtw_m2r(var,reg)        mmx_m2r (pcmpgtw, var, reg)
-#define         pcmpgtw_r2r(regs,regd)      mmx_r2r (pcmpgtw, regs, regd)
+#define	pcmpgtb_m2r(var, reg)	mmx_m2r(pcmpgtb, var, reg)
+#define	pcmpgtb_r2r(regs, regd)	mmx_r2r(pcmpgtb, regs, regd)
+#define	pcmpgtd_m2r(var, reg)	mmx_m2r(pcmpgtd, var, reg)
+#define	pcmpgtd_r2r(regs, regd)	mmx_r2r(pcmpgtd, regs, regd)
+#define	pcmpgtw_m2r(var, reg)	mmx_m2r(pcmpgtw, var, reg)
+#define	pcmpgtw_r2r(regs, regd)	mmx_r2r(pcmpgtw, regs, regd)
 
-#define         pmaddwd_m2r(var,reg)        mmx_m2r (pmaddwd, var, reg)
-#define         pmaddwd_r2r(regs,regd)      mmx_r2r (pmaddwd, regs, regd)
+#define	pmaddwd_m2r(var, reg)	mmx_m2r(pmaddwd, var, reg)
+#define	pmaddwd_r2r(regs, regd)	mmx_r2r(pmaddwd, regs, regd)
 
-#define         pmulhw_m2r(var,reg)         mmx_m2r (pmulhw, var, reg)
-#define         pmulhw_r2r(regs,regd)       mmx_r2r (pmulhw, regs, regd)
+#define	pmulhw_m2r(var, reg)	mmx_m2r(pmulhw, var, reg)
+#define	pmulhw_r2r(regs, regd)	mmx_r2r(pmulhw, regs, regd)
 
-#define         pmullw_m2r(var,reg)         mmx_m2r (pmullw, var, reg)
-#define         pmullw_r2r(regs,regd)       mmx_r2r (pmullw, regs, regd)
+#define	pmullw_m2r(var, reg)	mmx_m2r(pmullw, var, reg)
+#define	pmullw_r2r(regs, regd)	mmx_r2r(pmullw, regs, regd)
 
-#define         por_m2r(var,reg)            mmx_m2r (por, var, reg)
-#define         por_r2r(regs,regd)          mmx_r2r (por, regs, regd)
+#define	por_m2r(var, reg)	mmx_m2r(por, var, reg)
+#define	por_r2r(regs, regd)	mmx_r2r(por, regs, regd)
 
-#define         pslld_i2r(imm,reg)          mmx_i2r (pslld, imm, reg)
-#define         pslld_m2r(var,reg)          mmx_m2r (pslld, var, reg)
-#define         pslld_r2r(regs,regd)        mmx_r2r (pslld, regs, regd)
-#define         psllq_i2r(imm,reg)          mmx_i2r (psllq, imm, reg)
-#define         psllq_m2r(var,reg)          mmx_m2r (psllq, var, reg)
-#define         psllq_r2r(regs,regd)        mmx_r2r (psllq, regs, regd)
-#define         psllw_i2r(imm,reg)          mmx_i2r (psllw, imm, reg)
-#define         psllw_m2r(var,reg)          mmx_m2r (psllw, var, reg)
-#define         psllw_r2r(regs,regd)        mmx_r2r (psllw, regs, regd)
+#define	pslld_i2r(imm, reg)	mmx_i2r(pslld, imm, reg)
+#define	pslld_m2r(var, reg)	mmx_m2r(pslld, var, reg)
+#define	pslld_r2r(regs, regd)	mmx_r2r(pslld, regs, regd)
+#define	psllq_i2r(imm, reg)	mmx_i2r(psllq, imm, reg)
+#define	psllq_m2r(var, reg)	mmx_m2r(psllq, var, reg)
+#define	psllq_r2r(regs, regd)	mmx_r2r(psllq, regs, regd)
+#define	psllw_i2r(imm, reg)	mmx_i2r(psllw, imm, reg)
+#define	psllw_m2r(var, reg)	mmx_m2r(psllw, var, reg)
+#define	psllw_r2r(regs, regd)	mmx_r2r(psllw, regs, regd)
 
-#define         psrad_i2r(imm,reg)          mmx_i2r (psrad, imm, reg)
-#define         psrad_m2r(var,reg)          mmx_m2r (psrad, var, reg)
-#define         psrad_r2r(regs,regd)        mmx_r2r (psrad, regs, regd)
-#define         psraw_i2r(imm,reg)          mmx_i2r (psraw, imm, reg)
-#define         psraw_m2r(var,reg)          mmx_m2r (psraw, var, reg)
-#define         psraw_r2r(regs,regd)        mmx_r2r (psraw, regs, regd)
+#define	psrad_i2r(imm, reg)	mmx_i2r(psrad, imm, reg)
+#define	psrad_m2r(var, reg)	mmx_m2r(psrad, var, reg)
+#define	psrad_r2r(regs, regd)	mmx_r2r(psrad, regs, regd)
+#define	psraw_i2r(imm, reg)	mmx_i2r(psraw, imm, reg)
+#define	psraw_m2r(var, reg)	mmx_m2r(psraw, var, reg)
+#define	psraw_r2r(regs, regd)	mmx_r2r(psraw, regs, regd)
 
-#define         psrld_i2r(imm,reg)          mmx_i2r (psrld, imm, reg)
-#define         psrld_m2r(var,reg)          mmx_m2r (psrld, var, reg)
-#define         psrld_r2r(regs,regd)        mmx_r2r (psrld, regs, regd)
-#define         psrlq_i2r(imm,reg)          mmx_i2r (psrlq, imm, reg)
-#define         psrlq_m2r(var,reg)          mmx_m2r (psrlq, var, reg)
-#define         psrlq_r2r(regs,regd)        mmx_r2r (psrlq, regs, regd)
-#define         psrlw_i2r(imm,reg)          mmx_i2r (psrlw, imm, reg)
-#define         psrlw_m2r(var,reg)          mmx_m2r (psrlw, var, reg)
-#define         psrlw_r2r(regs,regd)        mmx_r2r (psrlw, regs, regd)
+#define	psrld_i2r(imm, reg)	mmx_i2r(psrld, imm, reg)
+#define	psrld_m2r(var, reg)	mmx_m2r(psrld, var, reg)
+#define	psrld_r2r(regs, regd)	mmx_r2r(psrld, regs, regd)
+#define	psrlq_i2r(imm, reg)	mmx_i2r(psrlq, imm, reg)
+#define	psrlq_m2r(var, reg)	mmx_m2r(psrlq, var, reg)
+#define	psrlq_r2r(regs, regd)	mmx_r2r(psrlq, regs, regd)
+#define	psrlw_i2r(imm, reg)	mmx_i2r(psrlw, imm, reg)
+#define	psrlw_m2r(var, reg)	mmx_m2r(psrlw, var, reg)
+#define	psrlw_r2r(regs, regd)	mmx_r2r(psrlw, regs, regd)
 
-#define         psubb_m2r(var,reg)          mmx_m2r (psubb, var, reg)
-#define         psubb_r2r(regs,regd)        mmx_r2r (psubb, regs, regd)
-#define         psubd_m2r(var,reg)          mmx_m2r (psubd, var, reg)
-#define         psubd_r2r(regs,regd)        mmx_r2r (psubd, regs, regd)
-#define         psubw_m2r(var,reg)          mmx_m2r (psubw, var, reg)
-#define         psubw_r2r(regs,regd)        mmx_r2r (psubw, regs, regd)
+#define	psubb_m2r(var, reg)	mmx_m2r(psubb, var, reg)
+#define	psubb_r2r(regs, regd)	mmx_r2r(psubb, regs, regd)
+#define	psubd_m2r(var, reg)	mmx_m2r(psubd, var, reg)
+#define	psubd_r2r(regs, regd)	mmx_r2r(psubd, regs, regd)
+#define	psubw_m2r(var, reg)	mmx_m2r(psubw, var, reg)
+#define	psubw_r2r(regs, regd)	mmx_r2r(psubw, regs, regd)
 
-#define         psubsb_m2r(var,reg)         mmx_m2r (psubsb, var, reg)
-#define         psubsb_r2r(regs,regd)       mmx_r2r (psubsb, regs, regd)
-#define         psubsw_m2r(var,reg)         mmx_m2r (psubsw, var, reg)
-#define         psubsw_r2r(regs,regd)       mmx_r2r (psubsw, regs, regd)
+#define	psubsb_m2r(var, reg)	mmx_m2r(psubsb, var, reg)
+#define	psubsb_r2r(regs, regd)	mmx_r2r(psubsb, regs, regd)
+#define	psubsw_m2r(var, reg)	mmx_m2r(psubsw, var, reg)
+#define	psubsw_r2r(regs, regd)	mmx_r2r(psubsw, regs, regd)
 
-#define         psubusb_m2r(var,reg)        mmx_m2r (psubusb, var, reg)
-#define         psubusb_r2r(regs,regd)      mmx_r2r (psubusb, regs, regd)
-#define         psubusw_m2r(var,reg)        mmx_m2r (psubusw, var, reg)
-#define         psubusw_r2r(regs,regd)      mmx_r2r (psubusw, regs, regd)
+#define	psubusb_m2r(var, reg)	mmx_m2r(psubusb, var, reg)
+#define	psubusb_r2r(regs, regd)	mmx_r2r(psubusb, regs, regd)
+#define	psubusw_m2r(var, reg)	mmx_m2r(psubusw, var, reg)
+#define	psubusw_r2r(regs, regd)	mmx_r2r(psubusw, regs, regd)
 
-#define         punpckhbw_m2r(var,reg)      mmx_m2r (punpckhbw, var, reg)
-#define         punpckhbw_r2r(regs,regd)    mmx_r2r (punpckhbw, regs, regd)
-#define         punpckhdq_m2r(var,reg)      mmx_m2r (punpckhdq, var, reg)
-#define         punpckhdq_r2r(regs,regd)    mmx_r2r (punpckhdq, regs, regd)
-#define         punpckhwd_m2r(var,reg)      mmx_m2r (punpckhwd, var, reg)
-#define         punpckhwd_r2r(regs,regd)    mmx_r2r (punpckhwd, regs, regd)
+#define	punpckhbw_m2r(var, reg)		mmx_m2r(punpckhbw, var, reg)
+#define	punpckhbw_r2r(regs, regd)	mmx_r2r(punpckhbw, regs, regd)
+#define	punpckhdq_m2r(var, reg)		mmx_m2r(punpckhdq, var, reg)
+#define	punpckhdq_r2r(regs, regd)	mmx_r2r(punpckhdq, regs, regd)
+#define	punpckhwd_m2r(var, reg)		mmx_m2r(punpckhwd, var, reg)
+#define	punpckhwd_r2r(regs, regd)	mmx_r2r(punpckhwd, regs, regd)
 
-#define         punpcklbw_m2r(var,reg)      mmx_m2r (punpcklbw, var, reg)
-#define         punpcklbw_r2r(regs,regd)    mmx_r2r (punpcklbw, regs, regd)
-#define         punpckldq_m2r(var,reg)      mmx_m2r (punpckldq, var, reg)
-#define         punpckldq_r2r(regs,regd)    mmx_r2r (punpckldq, regs, regd)
-#define         punpcklwd_m2r(var,reg)      mmx_m2r (punpcklwd, var, reg)
-#define         punpcklwd_r2r(regs,regd)    mmx_r2r (punpcklwd, regs, regd)
+#define	punpcklbw_m2r(var, reg)		mmx_m2r(punpcklbw, var, reg)
+#define	punpcklbw_r2r(regs, regd)	mmx_r2r(punpcklbw, regs, regd)
+#define	punpckldq_m2r(var, reg)		mmx_m2r(punpckldq, var, reg)
+#define	punpckldq_r2r(regs, regd)	mmx_r2r(punpckldq, regs, regd)
+#define	punpcklwd_m2r(var, reg)		mmx_m2r(punpcklwd, var, reg)
+#define	punpcklwd_r2r(regs, regd)	mmx_r2r(punpcklwd, regs, regd)
 
-#define         pxor_m2r(var,reg)           mmx_m2r (pxor, var, reg)
-#define         pxor_r2r(regs,regd)         mmx_r2r (pxor, regs, regd)
+#define	pxor_m2r(var, reg)	mmx_m2r(pxor, var, reg)
+#define	pxor_r2r(regs, regd)	mmx_r2r(pxor, regs, regd)
 
 /* 3DNOW extensions */
 
-#define         pavgusb_m2r(var,reg)        mmx_m2r (pavgusb, var, reg)
-#define         pavgusb_r2r(regs,regd)      mmx_r2r (pavgusb, regs, regd)
+#define	pavgusb_m2r(var, reg)	mmx_m2r(pavgusb, var, reg)
+#define	pavgusb_r2r(regs, regd)	mmx_r2r(pavgusb, regs, regd)
 
 /* AMD MMX extensions - also available in intel SSE */
 
-#define         mmx_m2ri(op,mem,reg,imm) \
-        __asm__ __volatile__ (#op " %1, %0, %%" #reg \
-                              : /* nothing */ \
-                              : "m" (mem), "i" (imm))
-#define         mmx_r2ri(op,regs,regd,imm) \
-        __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \
-                              : /* nothing */ \
-                              : "i" (imm) )
+#define	mmx_m2ri(op, mem, reg, imm) \
+	__asm__ __volatile__ (#op " %1, %0, %%" #reg \
+				: /* nothing */ \
+				: "m" (mem), "i" (imm))
+#define	mmx_r2ri(op, regs, regd, imm) \
+	__asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \
+				: /* nothing */ \
+				: "i" (imm))
 
-#define         mmx_fetch(mem,hint) \
-        __asm__ __volatile__ ("prefetch" #hint " %0" \
-                              : /* nothing */ \
-                              : "m" (mem))
+#define	mmx_fetch(mem, hint) \
+	__asm__ __volatile__ ("prefetch" #hint " %0" \
+				: /* nothing */ \
+				: "m" (mem))
 
-#define         maskmovq(regs,maskreg)      mmx_r2ri (maskmovq, regs, maskreg)
+#define	maskmovq(regs, maskreg)	mmx_r2ri(maskmovq, regs, maskreg)
 
-#define         movntq_r2m(mmreg,var)       mmx_r2m (movntq, mmreg, var)
+#define	movntq_r2m(mmreg, var)	mmx_r2m(movntq, mmreg, var)
 
-#define         pavgb_m2r(var,reg)          mmx_m2r (pavgb, var, reg)
-#define         pavgb_r2r(regs,regd)        mmx_r2r (pavgb, regs, regd)
-#define         pavgw_m2r(var,reg)          mmx_m2r (pavgw, var, reg)
-#define         pavgw_r2r(regs,regd)        mmx_r2r (pavgw, regs, regd)
+#define	pavgb_m2r(var, reg)	mmx_m2r(pavgb, var, reg)
+#define	pavgb_r2r(regs, regd)	mmx_r2r(pavgb, regs, regd)
+#define	pavgw_m2r(var, reg)	mmx_m2r(pavgw, var, reg)
+#define	pavgw_r2r(regs, regd)	mmx_r2r(pavgw, regs, regd)
 
-#define         pextrw_r2r(mmreg,reg,imm)   mmx_r2ri (pextrw, mmreg, reg, imm)
+#define	pextrw_r2r(mmreg, reg, imm)	mmx_r2ri(pextrw, mmreg, reg, imm)
 
-#define         pinsrw_r2r(reg,mmreg,imm)   mmx_r2ri (pinsrw, reg, mmreg, imm)
+#define	pinsrw_r2r(reg, mmreg, imm)	mmx_r2ri(pinsrw, reg, mmreg, imm)
 
-#define         pmaxsw_m2r(var,reg)         mmx_m2r (pmaxsw, var, reg)
-#define         pmaxsw_r2r(regs,regd)       mmx_r2r (pmaxsw, regs, regd)
+#define	pmaxsw_m2r(var, reg)	mmx_m2r(pmaxsw, var, reg)
+#define	pmaxsw_r2r(regs, regd)	mmx_r2r(pmaxsw, regs, regd)
 
-#define         pmaxub_m2r(var,reg)         mmx_m2r (pmaxub, var, reg)
-#define         pmaxub_r2r(regs,regd)       mmx_r2r (pmaxub, regs, regd)
+#define	pmaxub_m2r(var, reg)	mmx_m2r(pmaxub, var, reg)
+#define	pmaxub_r2r(regs, regd)	mmx_r2r(pmaxub, regs, regd)
 
-#define         pminsw_m2r(var,reg)         mmx_m2r (pminsw, var, reg)
-#define         pminsw_r2r(regs,regd)       mmx_r2r (pminsw, regs, regd)
+#define	pminsw_m2r(var, reg)	mmx_m2r(pminsw, var, reg)
+#define	pminsw_r2r(regs, regd)	mmx_r2r(pminsw, regs, regd)
 
-#define         pminub_m2r(var,reg)         mmx_m2r (pminub, var, reg)
-#define         pminub_r2r(regs,regd)       mmx_r2r (pminub, regs, regd)
+#define	pminub_m2r(var, reg)	mmx_m2r(pminub, var, reg)
+#define	pminub_r2r(regs, regd)	mmx_r2r(pminub, regs, regd)
 
-#define         pmovmskb(mmreg,reg) \
-        __asm__ __volatile__ ("movmskps %" #mmreg ", %" #reg)
+#define	pmovmskb(mmreg, reg) \
+	__asm__ __volatile__ ("movmskps %" #mmreg ", %" #reg)
 
-#define         pmulhuw_m2r(var,reg)        mmx_m2r (pmulhuw, var, reg)
-#define         pmulhuw_r2r(regs,regd)      mmx_r2r (pmulhuw, regs, regd)
+#define	pmulhuw_m2r(var, reg)	mmx_m2r(pmulhuw, var, reg)
+#define	pmulhuw_r2r(regs, regd)	mmx_r2r(pmulhuw, regs, regd)
 
-#define         prefetcht0(mem)             mmx_fetch (mem, t0)
-#define         prefetcht1(mem)             mmx_fetch (mem, t1)
-#define         prefetcht2(mem)             mmx_fetch (mem, t2)
-#define         prefetchnta(mem)            mmx_fetch (mem, nta)
+#define	prefetcht0(mem)		mmx_fetch(mem, t0)
+#define	prefetcht1(mem)		mmx_fetch(mem, t1)
+#define	prefetcht2(mem)		mmx_fetch(mem, t2)
+#define	prefetchnta(mem)	mmx_fetch(mem, nta)
 
-#define         psadbw_m2r(var,reg)         mmx_m2r (psadbw, var, reg)
-#define         psadbw_r2r(regs,regd)       mmx_r2r (psadbw, regs, regd)
+#define	psadbw_m2r(var, reg)	mmx_m2r(psadbw, var, reg)
+#define	psadbw_r2r(regs, regd)	mmx_r2r(psadbw, regs, regd)
 
-#define         pshufw_m2r(var,reg,imm)     mmx_m2ri(pshufw, var, reg, imm)
-#define         pshufw_r2r(regs,regd,imm)   mmx_r2ri(pshufw, regs, regd, imm)
+#define	pshufw_m2r(var, reg, imm)	mmx_m2ri(pshufw, var, reg, imm)
+#define	pshufw_r2r(regs, regd, imm)	mmx_r2ri(pshufw, regs, regd, imm)
 
-#define         sfence() __asm__ __volatile__ ("sfence\n\t")
+#define	sfence() __asm__ __volatile__ ("sfence\n\t")
 
 /* SSE2 */
-#define         pshufhw_m2r(var,reg,imm)    mmx_m2ri(pshufhw, var, reg, imm)
-#define         pshufhw_r2r(regs,regd,imm)  mmx_r2ri(pshufhw, regs, regd, imm)
-#define         pshuflw_m2r(var,reg,imm)    mmx_m2ri(pshuflw, var, reg, imm)
-#define         pshuflw_r2r(regs,regd,imm)  mmx_r2ri(pshuflw, regs, regd, imm)
+#define	pshufhw_m2r(var, reg, imm)	mmx_m2ri(pshufhw, var, reg, imm)
+#define	pshufhw_r2r(regs, regd, imm)	mmx_r2ri(pshufhw, regs, regd, imm)
+#define	pshuflw_m2r(var, reg, imm)	mmx_m2ri(pshuflw, var, reg, imm)
+#define	pshuflw_r2r(regs, regd, imm)	mmx_r2ri(pshuflw, regs, regd, imm)
 
-#define         pshufd_r2r(regs,regd,imm)   mmx_r2ri(pshufd, regs, regd, imm)
+#define	pshufd_r2r(regs, regd, imm)	mmx_r2ri(pshufd, regs, regd, imm)
 
-#define         movdqa_m2r(var,reg)         mmx_m2r (movdqa, var, reg)
-#define         movdqa_r2m(reg,var)         mmx_r2m (movdqa, reg, var)
-#define         movdqa_r2r(regs,regd)       mmx_r2r (movdqa, regs, regd)
-#define         movdqu_m2r(var,reg)         mmx_m2r (movdqu, var, reg)
-#define         movdqu_r2m(reg,var)         mmx_r2m (movdqu, reg, var)
-#define         movdqu_r2r(regs,regd)       mmx_r2r (movdqu, regs, regd)
+#define	movdqa_m2r(var, reg)	mmx_m2r(movdqa, var, reg)
+#define	movdqa_r2m(reg, var)	mmx_r2m(movdqa, reg, var)
+#define	movdqa_r2r(regs, regd)	mmx_r2r(movdqa, regs, regd)
+#define	movdqu_m2r(var, reg)	mmx_m2r(movdqu, var, reg)
+#define	movdqu_r2m(reg, var)	mmx_r2m(movdqu, reg, var)
+#define	movdqu_r2r(regs, regd)	mmx_r2r(movdqu, regs, regd)
 
-#define         pmullw_r2m(reg,var)         mmx_r2m (pmullw, reg, var)
+#define	pmullw_r2m(reg, var)	mmx_r2m(pmullw, reg, var)
 
-#define         pslldq_i2r(imm,reg)         mmx_i2r (pslldq, imm, reg)
-#define         psrldq_i2r(imm,reg)         mmx_i2r (psrldq, imm, reg)
+#define	pslldq_i2r(imm, reg)	mmx_i2r(pslldq, imm, reg)
+#define	psrldq_i2r(imm, reg)	mmx_i2r(psrldq, imm, reg)
 
-#define         punpcklqdq_r2r(regs,regd)   mmx_r2r (punpcklqdq, regs, regd)
-#define         punpckhqdq_r2r(regs,regd)   mmx_r2r (punpckhqdq, regs, regd)
+#define	punpcklqdq_r2r(regs, regd)	mmx_r2r(punpcklqdq, regs, regd)
+#define	punpckhqdq_r2r(regs, regd)	mmx_r2r(punpckhqdq, regs, regd)
 
 #endif /* AVCODEC_I386MMX_H */
diff --git a/drivers/staging/epl/Benchmark.h b/drivers/staging/epl/Benchmark.h
index 62dee3b..4cc01bd 100644
--- a/drivers/staging/epl/Benchmark.h
+++ b/drivers/staging/epl/Benchmark.h
@@ -73,12 +73,6 @@
 
 #include "global.h"
 
-#if (TARGET_SYSTEM == _NO_OS_) && (DEV_SYSTEM == _DEV_GNU_CF548X_)
-#include "common.h"
-
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
-
-//    #include <linux/config.h>
 #include <linux/kernel.h>
 
 #ifdef CONFIG_COLDFIRE
@@ -93,12 +87,6 @@
 #define BENCHMARK_MODULES           0x00000000
 #endif
 
-#else
-    // disable Benchmarking
-#undef BENCHMARK_MODULES
-#define BENCHMARK_MODULES               0x00000000
-#endif
-
 /***************************************************************************/
 /*                                                                         */
 /*                                                                         */
diff --git a/drivers/staging/epl/Debug.h b/drivers/staging/epl/Debug.h
index 05de9d5..851a222 100644
--- a/drivers/staging/epl/Debug.h
+++ b/drivers/staging/epl/Debug.h
@@ -163,25 +163,6 @@
 #endif
 
 //---------------------------------------------------------------------------
-#if (DEV_SYSTEM == _DEV_WIN32_) && defined (TRACE_MSG)
-
-    // For WIN32 the macro DEBUG_TRACE0 can be defined as function call TraceLvl()
-    // or as macro TRACE().
-    //
-    // Here the parameter 'lvl' can be used with more than one
-    // debug-level (using OR).
-    //
-    // Example: DEBUG_TRACE1(DEBUG_LVL_30 | DEBUG_LVL_02, "Hello %d", bCount);
-
-#define DEBUG_TRACE0(lvl,str)               TraceLvl((lvl),str)
-#define DEBUG_TRACE1(lvl,str,p1)            TraceLvl((lvl),str,p1)
-#define DEBUG_TRACE2(lvl,str,p1,p2)         TraceLvl((lvl),str,p1,p2)
-#define DEBUG_TRACE3(lvl,str,p1,p2,p3)      TraceLvl((lvl),str,p1,p2,p3)
-#define DEBUG_TRACE4(lvl,str,p1,p2,p3,p4)   TraceLvl((lvl),str,p1,p2,p3,p4)
-#define DEBUG_GLB_LVL()                     dwDebugLevel_g
-
-#else
-
     // At microcontrollers we do reduce the memory usage by deleting DEBUG_TRACE-lines
     // (compiler does delete the lines).
     //
@@ -643,25 +624,23 @@
 #define DEBUG_TRACE3(lvl,str,p1,p2,p3)                  lvl##_TRACE3(str,p1,p2,p3)
 #define DEBUG_TRACE4(lvl,str,p1,p2,p3,p4)               lvl##_TRACE4(str,p1,p2,p3,p4)
 
-#endif
-
 //---------------------------------------------------------------------------
 // The macro DEBUG_DUMP_DATA() can be used with the same debug-levels to dump
 // out data bytes. Function DumpData() has to be included.
 // NOTE: DUMP_DATA has to be defined in project settings.
-#if (!defined (NDEBUG) && defined (DUMP_DATA)) || (DEV_SYSTEM == _DEV_WIN32_)
+#if (!defined (NDEBUG) && defined (DUMP_DATA))
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-	void DumpData(char *szStr_p, BYTE MEM * pbData_p, WORD wSize_p);
+	void DumpData(char *szStr_p, u8 *pbData_p, u16 wSize_p);
 
 #ifdef __cplusplus
 }				// von extern "C"
 #endif
 #define DEBUG_DUMP_DATA(lvl,str,ptr,siz)    if ((DEBUG_GLB_LVL() & (lvl))==(lvl)) \
-                                                    DumpData (str, (BYTE MEM*) (ptr), (WORD) (siz));
+                                                    DumpData (str, (u8 *)(ptr), (u16)(siz));
 #else
 
 #define DEBUG_DUMP_DATA(lvl,str,ptr,siz)
@@ -675,24 +654,6 @@
 //       deleted from compiler (in release version too).
 #if !defined (NDEBUG) || defined (DEBUG_KEEP_ASSERT)
 
-#if (DEV_SYSTEM == _DEV_WIN32_)
-
-	// For WIN32 process will be killed after closing message box.
-
-#define DEBUG_ASSERT0(expr,str)         if (!(expr ) && ((DEBUG_GLB_LVL() & DEBUG_LVL_ASSERT)!=0)) { \
-                                                    MessageBox (NULL, \
-                                                        "Assertion failed: line " __LINE__ " file " __FILE__ \
-                                                        "\n    -> " str "\n"); \
-                                                    ExitProcess (-1); }
-
-#define DEBUG_ASSERT1(expr,str,p1)      if (!(expr ) && ((DEBUG_GLB_LVL() & DEBUG_LVL_ASSERT)!=0)) { \
-                                                    MessageBox (NULL, \
-                                                        "Assertion failed: line " __LINE__ " file " __FILE__ \
-                                                        "\n    -> " str "\n"); \
-                                                    ExitProcess (-1); }
-
-#else
-
 	// For microcontrollers process will be stopped using endless loop.
 
 #define DEBUG_ASSERT0(expr,str)         if (!(expr )) { \
@@ -705,10 +666,9 @@
                                                     DEBUG_LVL_ASSERT_TRACE4 ( \
                                                         "Assertion failed: line %d file '%s'\n" \
                                                         "    -> '%s'\n" \
-                                                        "    -> 0x%08lX\n", __LINE__, __FILE__, str, (DWORD) p1); \
+                                                        "    -> 0x%08lX\n", __LINE__, __FILE__, str, (u32) p1); \
                                                     while (1); }
 
-#endif
 
 #else
 
diff --git a/drivers/staging/epl/Edrv8139.c b/drivers/staging/epl/Edrv8139.c
index 296354a..44e3f7b 100644
--- a/drivers/staging/epl/Edrv8139.c
+++ b/drivers/staging/epl/Edrv8139.c
@@ -81,7 +81,6 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/major.h>
-#include <linux/version.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/atomic.h>
@@ -234,8 +233,8 @@
 
 // TracePoint support for realtime-debugging
 #ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
+void TgtDbgPostTraceValue(u32 dwTraceValue_p);
 #define TGT_DBG_SIGNAL_TRACE_POINT(p)   TgtDbgSignalTracePoint(p)
 #define TGT_DBG_POST_TRACE_VALUE(v)     TgtDbgPostTraceValue(v)
 #else
@@ -282,9 +281,9 @@
 typedef struct {
 	struct pci_dev *m_pPciDev;	// pointer to PCI device structure
 	void *m_pIoAddr;	// pointer to register space of Ethernet controller
-	BYTE *m_pbRxBuf;	// pointer to Rx buffer
+	u8 *m_pbRxBuf;	// pointer to Rx buffer
 	dma_addr_t m_pRxBufDma;
-	BYTE *m_pbTxBuf;	// pointer to Tx buffer
+	u8 *m_pbTxBuf;	// pointer to Tx buffer
 	dma_addr_t m_pTxBufDma;
 	BOOL m_afTxBufUsed[EDRV_MAX_TX_BUFFERS];
 	unsigned int m_uiCurTxDesc;
@@ -359,7 +358,7 @@
 // local function prototypes
 //---------------------------------------------------------------------------
 
-static BYTE EdrvCalcHash(BYTE * pbMAC_p);
+static u8 EdrvCalcHash(u8 * pbMAC_p);
 
 //---------------------------------------------------------------------------
 //
@@ -453,20 +452,20 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel EdrvDefineRxMacAddrEntry(BYTE * pbMacAddr_p)
+tEplKernel EdrvDefineRxMacAddrEntry(u8 * pbMacAddr_p)
 {
 	tEplKernel Ret = kEplSuccessful;
-	DWORD dwData;
-	BYTE bHash;
+	u32 dwData;
+	u8 bHash;
 
 	bHash = EdrvCalcHash(pbMacAddr_p);
 /*
     dwData = ether_crc(6, pbMacAddr_p);
 
     printk("EdrvDefineRxMacAddrEntry('%02X:%02X:%02X:%02X:%02X:%02X') hash = %u / %u  ether_crc = 0x%08lX\n",
-        (WORD) pbMacAddr_p[0], (WORD) pbMacAddr_p[1], (WORD) pbMacAddr_p[2],
-        (WORD) pbMacAddr_p[3], (WORD) pbMacAddr_p[4], (WORD) pbMacAddr_p[5],
-        (WORD) bHash, (WORD) (dwData >> 26), dwData);
+        (u16) pbMacAddr_p[0], (u16) pbMacAddr_p[1], (u16) pbMacAddr_p[2],
+        (u16) pbMacAddr_p[3], (u16) pbMacAddr_p[4], (u16) pbMacAddr_p[5],
+        (u16) bHash, (u16) (dwData >> 26), dwData);
 */
 	if (bHash > 31) {
 		dwData = EDRV_REGDW_READ(EDRV_REGDW_MAR4);
@@ -494,11 +493,11 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel EdrvUndefineRxMacAddrEntry(BYTE * pbMacAddr_p)
+tEplKernel EdrvUndefineRxMacAddrEntry(u8 * pbMacAddr_p)
 {
 	tEplKernel Ret = kEplSuccessful;
-	DWORD dwData;
-	BYTE bHash;
+	u32 dwData;
+	u8 bHash;
 
 	bHash = EdrvCalcHash(pbMacAddr_p);
 
@@ -532,7 +531,7 @@
 tEplKernel EdrvAllocTxMsgBuffer(tEdrvTxBuffer * pBuffer_p)
 {
 	tEplKernel Ret = kEplSuccessful;
-	DWORD i;
+	u32 i;
 
 	if (pBuffer_p->m_uiMaxBufferLen > EDRV_MAX_FRAME_SIZE) {
 		Ret = kEplEdrvNoFreeBufEntry;
@@ -605,7 +604,7 @@
 {
 	tEplKernel Ret = kEplSuccessful;
 	unsigned int uiBufferNumber;
-	DWORD dwTemp;
+	u32 dwTemp;
 
 	uiBufferNumber = pBuffer_p->m_uiBufferNumber;
 
@@ -620,11 +619,11 @@
 		dwTemp =
 		    EDRV_REGDW_READ((EDRV_REGDW_TSD0 +
 				     (EdrvInstance_l.m_uiCurTxDesc *
-				      sizeof(DWORD))));
-		printk("%s InvOp TSD%u = 0x%08lX", __func__,
+				      sizeof(u32))));
+		printk("%s InvOp TSD%u = 0x%08X", __func__,
 		       EdrvInstance_l.m_uiCurTxDesc, dwTemp);
 		printk("  Cmd = 0x%02X\n",
-		       (WORD) EDRV_REGB_READ(EDRV_REGB_COMMAND));
+		       (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND));
 		goto Exit;
 	}
 	// save pointer to buffer structure for TxHandler
@@ -640,22 +639,22 @@
 	}
 	// set DMA address of buffer
 	EDRV_REGDW_WRITE((EDRV_REGDW_TSAD0 +
-			  (EdrvInstance_l.m_uiCurTxDesc * sizeof(DWORD))),
+			  (EdrvInstance_l.m_uiCurTxDesc * sizeof(u32))),
 			 (EdrvInstance_l.m_pTxBufDma +
 			  (uiBufferNumber * EDRV_MAX_FRAME_SIZE)));
 	dwTemp =
 	    EDRV_REGDW_READ((EDRV_REGDW_TSAD0 +
-			     (EdrvInstance_l.m_uiCurTxDesc * sizeof(DWORD))));
+			     (EdrvInstance_l.m_uiCurTxDesc * sizeof(u32))));
 //    printk("%s TSAD%u = 0x%08lX", __func__, EdrvInstance_l.m_uiCurTxDesc, dwTemp);
 
 	// start transmission
 	EDRV_REGDW_WRITE((EDRV_REGDW_TSD0 +
-			  (EdrvInstance_l.m_uiCurTxDesc * sizeof(DWORD))),
+			  (EdrvInstance_l.m_uiCurTxDesc * sizeof(u32))),
 			 (EDRV_REGDW_TSD_TXTH_DEF | pBuffer_p->m_uiTxMsgLen));
 	dwTemp =
 	    EDRV_REGDW_READ((EDRV_REGDW_TSD0 +
-			     (EdrvInstance_l.m_uiCurTxDesc * sizeof(DWORD))));
-//    printk(" TSD%u = 0x%08lX / 0x%08lX\n", EdrvInstance_l.m_uiCurTxDesc, dwTemp, (DWORD)(EDRV_REGDW_TSD_TXTH_DEF | pBuffer_p->m_uiTxMsgLen));
+			     (EdrvInstance_l.m_uiCurTxDesc * sizeof(u32))));
+//    printk(" TSD%u = 0x%08lX / 0x%08lX\n", EdrvInstance_l.m_uiCurTxDesc, dwTemp, (u32)(EDRV_REGDW_TSD_TXTH_DEF | pBuffer_p->m_uiTxMsgLen));
 
       Exit:
 	return Ret;
@@ -720,7 +719,7 @@
 //---------------------------------------------------------------------------
 static void EdrvReinitRx(void)
 {
-	BYTE bCmd;
+	u8 bCmd;
 
 	// simply switch off and on the receiver
 	// this will reset the CAPR register
@@ -751,21 +750,16 @@
 }
 #endif
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
 static int TgtEthIsr(int nIrqNum_p, void *ppDevInstData_p)
-#else
-static int TgtEthIsr(int nIrqNum_p, void *ppDevInstData_p,
-		     struct pt_regs *ptRegs_p)
-#endif
 {
 //    EdrvInterruptHandler();
 	tEdrvRxBuffer RxBuffer;
 	tEdrvTxBuffer *pTxBuffer;
-	WORD wStatus;
-	DWORD dwTxStatus;
-	DWORD dwRxStatus;
-	WORD wCurRx;
-	BYTE *pbRxBuf;
+	u16 wStatus;
+	u32 dwTxStatus;
+	u32 dwRxStatus;
+	u16 wCurRx;
+	u8 *pbRxBuf;
 	unsigned int uiLength;
 	int iHandled = IRQ_HANDLED;
 
@@ -793,7 +787,7 @@
 		dwTxStatus =
 		    EDRV_REGDW_READ((EDRV_REGDW_TSD0 +
 				     (EdrvInstance_l.m_uiCurTxDesc *
-				      sizeof(DWORD))));
+				      sizeof(u32))));
 		if ((dwTxStatus & (EDRV_REGDW_TSD_TOK | EDRV_REGDW_TSD_TABT | EDRV_REGDW_TSD_TUN)) != 0) {	// transmit finished
 			EdrvInstance_l.m_uiCurTxDesc =
 			    (EdrvInstance_l.m_uiCurTxDesc + 1) & 0x03;
@@ -855,8 +849,8 @@
 			// calculate pointer to current frame in receive buffer
 			pbRxBuf = EdrvInstance_l.m_pbRxBuf + wCurRx;
 
-			// read receive status DWORD
-			dwRxStatus = le32_to_cpu(*((DWORD *) pbRxBuf));
+			// read receive status u32
+			dwRxStatus = le32_to_cpu(*((u32 *) pbRxBuf));
 
 			// calculate length of received frame
 			uiLength = dwRxStatus >> 16;
@@ -896,9 +890,9 @@
 				    m_pfnRxHandler(&RxBuffer);
 			}
 
-			// calulate new offset (DWORD aligned)
+			// calulate new offset (u32 aligned)
 			wCurRx =
-			    (WORD) ((wCurRx + uiLength + sizeof(dwRxStatus) +
+			    (u16) ((wCurRx + uiLength + sizeof(dwRxStatus) +
 				     3) & ~0x3);
 			EDRV_TRACE_CAPR(wCurRx - 0x10);
 			EDRV_REGW_WRITE(EDRV_REGW_CAPR, wCurRx - 0x10);
@@ -941,7 +935,7 @@
 static int EdrvInitOne(struct pci_dev *pPciDev, const struct pci_device_id *pId)
 {
 	int iResult = 0;
-	DWORD dwTemp;
+	u32 dwTemp;
 
 	if (EdrvInstance_l.m_pPciDev != NULL) {	// Edrv is already connected to a PCI device
 		printk("%s device %s discarded\n", __func__,
@@ -1008,7 +1002,7 @@
 	dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TCR);
 	if (((dwTemp & EDRV_REGDW_TCR_VER_MASK) != EDRV_REGDW_TCR_VER_C)
 	    && ((dwTemp & EDRV_REGDW_TCR_VER_MASK) != EDRV_REGDW_TCR_VER_D)) {	// unsupported chip
-		printk("%s Unsupported chip! TCR = 0x%08lX\n", __func__,
+		printk("%s Unsupported chip! TCR = 0x%08X\n", __func__,
 		       dwTemp);
 		iResult = -ENODEV;
 		goto Exit;
@@ -1043,11 +1037,11 @@
             printk("%s set local MAC address\n", __func__);
             // write this MAC address to controller
             EDRV_REGDW_WRITE(EDRV_REGDW_IDR0,
-                le32_to_cpu(*((DWORD*)&EdrvInstance_l.m_InitParam.m_abMyMacAddr[0])));
+                le32_to_cpu(*((u32*)&EdrvInstance_l.m_InitParam.m_abMyMacAddr[0])));
             dwTemp = EDRV_REGDW_READ(EDRV_REGDW_IDR0);
 
             EDRV_REGDW_WRITE(EDRV_REGDW_IDR4,
-                le32_to_cpu(*((DWORD*)&EdrvInstance_l.m_InitParam.m_abMyMacAddr[4])));
+                le32_to_cpu(*((u32*)&EdrvInstance_l.m_InitParam.m_abMyMacAddr[4])));
             dwTemp = EDRV_REGDW_READ(EDRV_REGDW_IDR4);
             break;
         }
@@ -1087,7 +1081,7 @@
 	dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TSAD3);
 
 	printk("    Command = 0x%02X\n",
-	       (WORD) EDRV_REGB_READ(EDRV_REGB_COMMAND));
+	       (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND));
 
 	// set pointer for receive buffer in controller
 	printk("%s set pointer to Rx buffer\n", __func__);
@@ -1098,7 +1092,7 @@
 	EDRV_REGB_WRITE(EDRV_REGB_COMMAND,
 			(EDRV_REGB_COMMAND_RE | EDRV_REGB_COMMAND_TE));
 	printk("  Command = 0x%02X\n",
-	       (WORD) EDRV_REGB_READ(EDRV_REGB_COMMAND));
+	       (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND));
 
 	// clear missed packet counter to enable Rx/Tx process
 	EDRV_REGDW_WRITE(EDRV_REGDW_MPC, 0);
@@ -1123,7 +1117,7 @@
     // enable transmitter and receiver
     printk("%s enable Tx and Rx", __func__);
     EDRV_REGB_WRITE(EDRV_REGB_COMMAND, (EDRV_REGB_COMMAND_RE | EDRV_REGB_COMMAND_TE));
-    printk("  Command = 0x%02X\n", (WORD) EDRV_REGB_READ(EDRV_REGB_COMMAND));
+    printk("  Command = 0x%02X\n", (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND));
 */
 	// disable early interrupts
 	EDRV_REGW_WRITE(EDRV_REGW_MULINT, 0);
@@ -1215,15 +1209,15 @@
 //#define CRC32_POLY    0xEDB88320  //
 // G(x) = x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
 
-static BYTE EdrvCalcHash(BYTE * pbMAC_p)
+static u8 EdrvCalcHash(u8 * pbMAC_p)
 {
-	DWORD dwByteCounter;
-	DWORD dwBitCounter;
-	DWORD dwData;
-	DWORD dwCrc;
-	DWORD dwCarry;
-	BYTE *pbData;
-	BYTE bHash;
+	u32 dwByteCounter;
+	u32 dwBitCounter;
+	u32 dwData;
+	u32 dwCrc;
+	u32 dwCarry;
+	u8 *pbData;
+	u8 bHash;
 
 	pbData = pbMAC_p;
 
@@ -1246,7 +1240,7 @@
 //    printk("MyCRC = 0x%08lX\n", dwCrc);
 	// only upper 6 bits (HASH_BITS) are used
 	// which point to specific bit in the hash registers
-	bHash = (BYTE) ((dwCrc >> (32 - HASH_BITS)) & 0x3f);
+	bHash = (u8) ((dwCrc >> (32 - HASH_BITS)) & 0x3f);
 
 	return bHash;
 }
diff --git a/drivers/staging/epl/EdrvFec.h b/drivers/staging/epl/EdrvFec.h
index 5f252fb..56728d1 100644
--- a/drivers/staging/epl/EdrvFec.h
+++ b/drivers/staging/epl/EdrvFec.h
@@ -96,9 +96,9 @@
 
 // Rx and Tx buffer descriptor format
 typedef struct {
-	WORD m_wStatus;		// control / status  ---  used by edrv, do not change in application
-	WORD m_wLength;		// transfer length
-	BYTE *m_pbData;		// buffer address
+	u16 m_wStatus;		// control / status  ---  used by edrv, do not change in application
+	u16 m_wLength;		// transfer length
+	u8 *m_pbData;		// buffer address
 } tBufferDescr;
 
 #if ((TARGET_HARDWARE & TGT_CPU_MASK_) == TGT_CPU_5282)
diff --git a/drivers/staging/epl/EdrvFec5282.h b/drivers/staging/epl/EdrvFec5282.h
deleted file mode 100644
index a16bb1d..0000000
--- a/drivers/staging/epl/EdrvFec5282.h
+++ /dev/null
@@ -1,340 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  interface for ethernetdriver
-                "fast ethernet controller" (FEC)
-                freescale coldfire MCF528x and compatible FEC
-
-  License:
-
-    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 SYSTEC electronic GmbH nor the names of its
-       contributors may be used to endorse or promote products derived
-       from this software without prior written permission. For written
-       permission, please contact info@systec-electronic.com.
-
-    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 HOLDERS 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.
-
-    Severability Clause:
-
-        If a provision of this License is or becomes illegal, invalid or
-        unenforceable in any jurisdiction, that shall not affect:
-        1. the validity or enforceability in that jurisdiction of any other
-           provision of this License; or
-        2. the validity or enforceability in other jurisdictions of that or
-           any other provision of this License.
-
-  -------------------------------------------------------------------------
-
-                $RCSfile: EdrvFec5282.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.3 $  $Date: 2008/04/17 21:36:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                Dev C++ and GNU-Compiler for m68k
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2005/08/01 m.b.:   start of implementation
-
-****************************************************************************/
-
-#ifndef _EDRVFEC_H_
-#define _EDRVFEC_H_
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-// base addresses
-#define FEC0_ADDR 0x0000
-#define FEC1_ADDR 0x0000	//tbd
-
-// control / status registers
-#define FEC_EIR                 0x1004	// interrupt event register
-#define FEC_EIMR                0x1008	// interrupt mask register
-#define FEC_RDAR                0x1010	// receive descriptor active register
-#define FEC_TDAR                0x1014	// transmit descriptor active register
-#define FEC_ECR                 0x1024	// ethernet control register
-#define FEC_MMFR                0x1040	// MII data register
-#define FEC_MSCR                0x1044	// MII speed register
-#define FEC_MIBC                0x1064	// MIB control/status register
-#define FEC_RCR                 0x1084	// receive control register
-#define FEC_TCR                 0x10C4	// transmit control register
-#define FEC_PALR                0x10E4	// physical address low register
-#define FEC_PAUR                0x10E8	// physical address high + type register
-#define FEC_OPD                 0x10EC	// opcode + pause register
-#define FEC_IAUR                0x1118	// upper 32 bit of individual hash table
-#define FEC_IALR                0x111C	// lower 32 bit of individual hash table
-#define FEC_GAUR                0x1120	// upper 32 bit of group hash table
-#define FEC_GALR                0x1124	// lower 32 bit of group hash table
-#define FEC_TFWR                0x1144	// transmit FIFO watermark
-#define FEC_FRBR                0x114C	// FIFO receive bound register
-#define FEC_FRSR                0x1150	// FIFO receive FIFO start register
-#define FEC_ERDSR               0x1180	// pointer to receive descriptor ring
-#define FEC_ETDSR               0x1184	// pointer to transmit descriptor ring
-#define FEC_EMRBR               0x1188	// maximum receive buffer size
-
-// mib block counters memory map
-#define FEC_RMON_T_DROP         0x1200	// count of frames not counted correctly
-#define FEC_RMON_T_PACKETS      0x1204	// RMON tx packet count
-#define FEC_RMON_T_BC_PKT       0x1208	// RMON tx broadcast packets
-#define FEC_RMON_T_MC_PKT       0x120C	// RMON tx multicast packets
-#define FEC_RMON_T_CRC_ALIGN    0x1210	// RMON tx packets w CRC/align error
-#define FEC_RMON_T_UNDERSIZE    0x1214	// RMON tx packets < 64 bytes, good CRC
-#define FEC_RMON_T_OVERSIZE     0x1218	// RMON tx packets > MAX_FL bytes, good CRC
-#define FEC_RMON_T_FRAG         0x121C	// RMON tx packets < 64 bytes, bad CRC
-#define FEC_RMON_T_JAB          0x1220	// RMON tx packets > MAX_FL bytes, bad CRC
-#define FEC_RMON_T_COL          0x1224	// RMON tx collision count
-#define FEC_RMON_T_P64          0x1228	// RMON tx           64 byte packets
-#define FEC_RMON_T_P65TO127     0x122C	// RMON tx   65 to  127 byte packets
-#define FEC_RMON_T_P128TO255    0x1230	// RMON tx  128 to  255 byte packets
-#define FEC_RMON_T_P256TO511    0x1234	// RMON tx  256 to  511 byte packets
-#define FEC_RMON_T_P512TO1023   0x1238	// RMON tx  512 to 1023 byte packets
-#define FEC_RMON_T_P1024TO2047  0x123C	// RMON tx 1024 to 2047 byte packets
-#define FEC_RMON_T_P_GTE2048    0x1240	// RMON tx w > 2048 bytes
-#define FEC_RMON_T_OCTETS       0x1244	// RMON tx octets
-#define FEC_IEEE_T_DROP         0x1248	// count of frames not counted correctly
-#define FEC_IEEE_T_FRAME_OK     0x124C	// frames transmitted OK
-#define FEC_IEEE_T_1COL         0x1250	// frames transmitted with single collision
-#define FEC_IEEE_T_MCOL         0x1254	// frames transmitted with multiple collisions
-#define FEC_IEEE_T_DEF          0x1258	// frames transmitted after deferral delay
-#define FEC_IEEE_T_LCOL         0x125C	// frames transmitted with late collisions
-#define FEC_IEEE_T_EXCOL        0x1260	// frames transmitted with excessive collisions
-#define FEC_IEEE_T_MACERR       0x1264	// frames transmitted with tx-FIFO underrun
-#define FEC_IEEE_T_CSERR        0x1268	// frames transmitted with carrier sense error
-#define FEC_IEEE_T_SQE          0x126C	// frames transmitted with SQE error
-#define FEC_IEEE_T_FDXFC        0x1270	// flow control pause frames transmitted
-#define FEC_IEEE_T_OCTETS_OK    0x1274	// octet count for frames transmitted w/o error
-#define FEC_RMON_R_PACKETS      0x1284	// RMON rx packet count
-#define FEC_RMON_R_BC_PKT       0x1288	// RMON rx broadcast packets
-#define FEC_RMON_R_MC_PKT       0x128C	// RMON rx multicast packets
-#define FEC_RMON_R_CRC_ALIGN    0x1290	// RMON rx packets w CRC/align error
-#define FEC_RMON_R_UNDERSIZE    0x1294	// RMON rx packets < 64 bytes, good CRC
-#define FEC_RMON_R_OVERSIZE     0x1298	// RMON rx packets > MAX_FL bytes, good CRC
-#define FEC_RMON_R_FRAG         0x129C	// RMON rx packets < 64 bytes, bad CRC
-#define FEC_RMON_R_JAB          0x12A0	// RMON rx packets > MAX_FL bytes, bad CRC
-#define FEC_RMON_R_RESVD_0      0x12A4	//
-#define FEC_RMON_R_P64          0x12A8	// RMON rx           64 byte packets
-#define FEC_RMON_R_P65T0127     0x12AC	// RMON rx   65 to  127 byte packets
-#define FEC_RMON_R_P128TO255    0x12B0	// RMON rx  128 to  255 byte packets
-#define FEC_RMON_R_P256TO511    0x12B4	// RMON rx  256 to  511 byte packets
-#define FEC_RMON_R_P512TO1023   0x12B8	// RMON rx  512 to 1023 byte packets
-#define FEC_RMON_R_P1024TO2047  0x12BC	// RMON rx 1024 to 2047 byte packets
-#define FEC_RMON_R_GTE2048      0x12C0	// RMON rx w > 2048 bytes
-#define FEC_RMON_R_OCTETS       0x12C4	// RMON rx octets
-#define FEC_IEEE_R_DROP         0x12C8	// count of frames not counted correctly
-#define FEC_IEEE_R_FRAME_OK     0x12CC	// frames received OK
-#define FEC_IEEE_R_CRC          0x12D0	// frames received with CRC error
-#define FEC_IEEE_R_ALIGN        0x12D4	// frames received with alignment error
-#define FEC_IEEE_R_MACERR       0x12D8	// receive FIFO overflow count
-#define FEC_IEEE_R_FDXFC        0x12DC	// flow control pause frames received
-#define FEC_IEEE_R_OCTETS_OK    0x12E0	// octet count for frames rcvd w/o error
-
-// register bit definitions and macros
-#define FEC_EIR_UN              (0x00080000)
-#define FEC_EIR_RL              (0x00100000)
-#define FEC_EIR_LC              (0x00200000)
-#define FEC_EIR_EBERR           (0x00400000)
-#define FEC_EIR_MII             (0x00800000)
-#define FEC_EIR_RXB             (0x01000000)
-#define FEC_EIR_RXF             (0x02000000)
-#define FEC_EIR_TXB             (0x04000000)
-#define FEC_EIR_TXF             (0x08000000)
-#define FEC_EIR_GRA             (0x10000000)
-#define FEC_EIR_BABT            (0x20000000)
-#define FEC_EIR_BABR            (0x40000000)
-#define FEC_EIR_HBERR           (0x80000000)
-
-#define FEC_EIMR_UN             (0x00080000)
-#define FEC_EIMR_RL             (0x00100000)
-#define FEC_EIMR_LC             (0x00200000)
-#define FEC_EIMR_EBERR          (0x00400000)
-#define FEC_EIMR_MII            (0x00800000)
-#define FEC_EIMR_RXB            (0x01000000)
-#define FEC_EIMR_RXF            (0x02000000)
-#define FEC_EIMR_TXB            (0x04000000)
-#define FEC_EIMR_TXF            (0x08000000)
-#define FEC_EIMR_GRA            (0x10000000)
-#define FEC_EIMR_BABT           (0x20000000)
-#define FEC_EIMR_BABR           (0x40000000)
-#define FEC_EIMR_HBERR          (0x80000000)
-
-#define FEC_RDAR_R_DES_ACTIVE   (0x01000000)
-
-#define FEC_TDAR_X_DES_ACTIVE   (0x01000000)
-
-#define FEC_ECR_RESET           (0x00000001)
-#define FEC_ECR_ETHER_EN        (0x00000002)
-
-#define FEC_MMFR_DATA(x)        (((x) & 0xFFFF))
-#define FEC_MMFR_TA             (0x00020000)
-#define FEC_MMFR_RA(x)          (((x) & 0x1F) << 18)
-#define FEC_MMFR_PA(x)          (((x) & 0x1F) << 23)
-#define FEC_MMFR_OP_WR          (0x10000000)
-#define FEC_MMFR_OP_RD          (0x20000000)
-#define FEC_MMFR_ST             (0x40000000)
-
-#define FEC_MSCR_MII_SPEED(x)   (((x) & 0x1F) << 1)
-#define FEC_MSCR_DIS_PREAMBLE   (0x00000008)
-
-#define FEC_MIBC_MIB_IDLE       (0x40000000)
-#define FEC_MIBC_MIB_DISABLE    (0x80000000)
-
-#define FEC_RCR_LOOP            (0x00000001)
-#define FEC_RCR_DRT             (0x00000002)
-#define FEC_RCR_MII_MODE        (0x00000004)
-#define FEC_RCR_PROM            (0x00000008)
-#define FEC_RCR_BC_REJ          (0x00000010)
-#define FEC_RCR_FCE             (0x00000020)
-#define FEC_RCR_MAX_FL(x)       (((x) & 0x07FF) << 16)
-
-#define FEC_TCR_GTS             (0x00000001)
-#define FEC_TCR_HBC             (0x00000002)
-#define FEC_TCR_FDEN            (0x00000004)
-#define FEC_TCR_TFC_PAUSE       (0x00000008)
-#define FEC_TCR_RFC_PAUSE       (0x00000010)
-
-#define FEC_PALR_BYTE3(x)       (((x) & 0xFF) <<  0)
-#define FEC_PALR_BYTE2(x)       (((x) & 0xFF) <<  8)
-#define FEC_PALR_BYTE1(x)       (((x) & 0xFF) << 16)
-#define FEC_PALR_BYTE0(x)       (((x) & 0xFF) << 24)
-
-//#define FEC_PAUR_TYPE(x)        (((x) & 0xFFFF) <<  0)
-#define FEC_PAUR_BYTE5(x)       (((x) &   0xFF) << 16)
-#define FEC_PAUR_BYTE4(x)       (((x) &   0xFF) << 24)
-
-#define FEC_OPD_PAUSE_DUR(x)    (((x) & 0xFFFF))
-//#define FEC_OPD_OPCODE(x)       (((x) & 0xFFFF) << 16)
-
-//m.b.
-#define FEC_IAUR_BYTE7(x)       (((x) & 0xFF) <<  0)
-#define FEC_IAUR_BYTE6(x)       (((x) & 0xFF) <<  8)
-#define FEC_IAUR_BYTE5(x)       (((x) & 0xFF) << 16)
-#define FEC_IAUR_BYTE4(x)       (((x) & 0xFF) << 24)
-
-#define FEC_IALR_BYTE3(x)       (((x) & 0xFF) <<  0)
-#define FEC_IALR_BYTE2(x)       (((x) & 0xFF) <<  8)
-#define FEC_IALR_BYTE1(x)       (((x) & 0xFF) << 16)
-#define FEC_IALR_BYTE0(x)       (((x) & 0xFF) << 24)
-
-#define FEC_GAUR_BYTE7(x)       (((x) & 0xFF) <<  0)
-#define FEC_GAUR_BYTE6(x)       (((x) & 0xFF) <<  8)
-#define FEC_GAUR_BYTE5(x)       (((x) & 0xFF) << 16)
-#define FEC_GAUR_BYTE4(x)       (((x) & 0xFF) << 24)
-
-#define FEC_GALR_BYTE3(x)       (((x) & 0xFF) <<  0)
-#define FEC_GALR_BYTE2(x)       (((x) & 0xFF) <<  8)
-#define FEC_GALR_BYTE1(x)       (((x) & 0xFF) << 16)
-#define FEC_GALR_BYTE0(x)       (((x) & 0xFF) << 24)
-// ^^^^
-
-#define FEC_TFWR_X_WMRK_64      (0x00000001)
-#define FEC_TFWR_X_WMRK_128     (0x00000002)
-#define FEC_TFWR_X_WMRK_192     (0x00000003)
-
-//m.b.
-#define FEC_FRBR_R_BOUND(x)     (((x) & 0xFF) << 2)
-
-//m.b.
-#define FEC_FRSR_R_FSTART(x)    (((x) & 0xFF) << 2)
-
-//m.b.
-#define FEC_ERDSR_R_DES_START(x)  (((x) & 0x3FFFFFFF) << 2)
-
-//m.b.
-#define FEC_ETSDR_X_DES_START(x)  (((x) & 0x3FFFFFFF) << 2)
-
-#define FEC_EMRBR_R_BUF_SIZE(x) (((x) & 0x7F) <<  4)
-
-#define FEC_RxBD_TR             0x0001
-#define FEC_RxBD_OV             0x0002
-#define FEC_RxBD_CR             0x0004
-#define FEC_RxBD_NO             0x0010
-#define FEC_RxBD_LG             0x0020
-#define FEC_RxBD_MC             0x0040
-#define FEC_RxBD_BC             0x0080
-#define FEC_RxBD_M              0x0100
-#define FEC_RxBD_L              0x0800
-#define FEC_RxBD_R02            0x1000
-#define FEC_RxBD_W              0x2000
-#define FEC_RxBD_R01            0x4000
-#define FEC_RxBD_INUSE          0x4000
-#define FEC_RxBD_E              0x8000
-
-//m.b.
-//#define FEC_TxBD_CSL            0x0001
-//#define FEC_TxBD_UN             0x0002
-//#define FEC_TxBD_RL             0x0040
-//#define FEC_TxBD_LC             0x0080
-//#define FEC_TxBD_HB             0x0100
-//#define FEC_TxBD_DEF            0x0200
-#define FEC_TxBD_ABC            0x0200
-// ^^^^
-#define FEC_TxBD_TC             0x0400
-#define FEC_TxBD_L              0x0800
-#define FEC_TxBD_TO2            0x1000
-#define FEC_TxBD_W              0x2000
-#define FEC_TxBD_TO1            0x4000
-#define FEC_TxBD_INUSE          0x4000
-#define FEC_TxBD_R              0x8000
-
-//---------------------------------------------------------------------------
-// types
-//---------------------------------------------------------------------------
-
-// Rx and Tx buffer descriptor format
-typedef struct {
-	WORD m_wStatus;		// control / status  ---  used by edrv, do not change in application
-	WORD m_wLength;		// transfer length
-	BYTE *m_pbData;		// buffer address
-} tBufferDescr;
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-#if (NO_OF_INSTANCES > 1)
-#define ECI_WRITE_DW_REG(off,val)       (*(DWORD *)(void *)(&__IPSBAR[off]) = val)
-#define ECI_READ_DW_REG(off)            (*(DWORD *)(void *)(&__IPSBAR[off]))
-#else
-#if (EDRV_USED_ETH_CTRL == 0)
-#define ECI_WRITE_DW_REG(off,val)       (*(DWORD *)(void *)(&__IPSBAR[FEC0_ADDR+off]) = val)
-#define ECI_READ_DW_REG(off)            (*(DWORD *)(void *)(&__IPSBAR[FEC0_ADDR+off]))
-#else
-#define ECI_WRITE_DW_REG(off,val)       (*(DWORD *)(void *)(&__IPSBAR[FEC1_ADDR+off]) = val)
-#define ECI_READ_DW_REG(off)            (*(DWORD *)(void *)(&__IPSBAR[FEC1_ADDR+off]))
-#endif
-#endif
-
-#endif // #ifndef _EDRV_FEC_H_
diff --git a/drivers/staging/epl/EdrvSim.h b/drivers/staging/epl/EdrvSim.h
index 39300e32..191ec14 100644
--- a/drivers/staging/epl/EdrvSim.h
+++ b/drivers/staging/epl/EdrvSim.h
@@ -83,7 +83,7 @@
 // function prototypes
 //---------------------------------------------------------------------------
 
-void EdrvRxInterruptHandler(BYTE bBufferInFrame_p, BYTE * pbEthernetData_p,
-			    WORD wDataLen_p);
+void EdrvRxInterruptHandler(u8 bBufferInFrame_p, u8 * pbEthernetData_p,
+			    u16 wDataLen_p);
 
 #endif // #ifndef _EDRVSIM_H_
diff --git a/drivers/staging/epl/Epl.h b/drivers/staging/epl/Epl.h
index be60f77..7f22b04 100644
--- a/drivers/staging/epl/Epl.h
+++ b/drivers/staging/epl/Epl.h
@@ -89,7 +89,7 @@
 	unsigned int m_uiNodeId;
 	tEplNmtState m_NmtState;
 	tEplNmtNodeEvent m_NodeEvent;
-	WORD m_wErrorCode;	// EPL error code if m_NodeEvent == kEplNmtNodeEventError
+	u16 m_wErrorCode;	// EPL error code if m_NodeEvent == kEplNmtNodeEventError
 	BOOL m_fMandatory;
 
 } tEplApiEventNode;
@@ -97,7 +97,7 @@
 typedef struct {
 	tEplNmtState m_NmtState;	// local NMT state
 	tEplNmtBootEvent m_BootEvent;
-	WORD m_wErrorCode;	// EPL error code if m_BootEvent == kEplNmtBootEventError
+	u16 m_wErrorCode;	// EPL error code if m_BootEvent == kEplNmtBootEventError
 
 } tEplApiEventBoot;
 
@@ -131,33 +131,33 @@
 
 } tEplApiEventArg;
 
-typedef tEplKernel(PUBLIC ROM * tEplApiCbEvent) (tEplApiEventType EventType_p,	// IN: event type (enum)
-						 tEplApiEventArg * pEventArg_p,	// IN: event argument (union)
-						 void GENERIC * pUserArg_p);
+typedef tEplKernel(*tEplApiCbEvent) (tEplApiEventType EventType_p,	// IN: event type (enum)
+				     tEplApiEventArg *pEventArg_p,	// IN: event argument (union)
+				      void *pUserArg_p);
 
 typedef struct {
 	unsigned int m_uiSizeOfStruct;
 	BOOL m_fAsyncOnly;	// do not need to register PRes
 	unsigned int m_uiNodeId;	// local node ID
-	BYTE m_abMacAddress[6];	// local MAC address
+	u8 m_abMacAddress[6];	// local MAC address
 
 	// 0x1F82: NMT_FeatureFlags_U32
-	DWORD m_dwFeatureFlags;
+	u32 m_dwFeatureFlags;
 	// Cycle Length (0x1006: NMT_CycleLen_U32) in [us]
-	DWORD m_dwCycleLen;	// required for error detection
+	u32 m_dwCycleLen;	// required for error detection
 	// 0x1F98: NMT_CycleTiming_REC
 	// 0x1F98.1: IsochrTxMaxPayload_U16
 	unsigned int m_uiIsochrTxMaxPayload;	// const
 	// 0x1F98.2: IsochrRxMaxPayload_U16
 	unsigned int m_uiIsochrRxMaxPayload;	// const
 	// 0x1F98.3: PResMaxLatency_U32
-	DWORD m_dwPresMaxLatency;	// const in [ns], only required for IdentRes
+	u32 m_dwPresMaxLatency;	// const in [ns], only required for IdentRes
 	// 0x1F98.4: PReqActPayloadLimit_U16
 	unsigned int m_uiPreqActPayloadLimit;	// required for initialisation (+28 bytes)
 	// 0x1F98.5: PResActPayloadLimit_U16
 	unsigned int m_uiPresActPayloadLimit;	// required for initialisation of Pres frame (+28 bytes)
 	// 0x1F98.6: ASndMaxLatency_U32
-	DWORD m_dwAsndMaxLatency;	// const in [ns], only required for IdentRes
+	u32 m_dwAsndMaxLatency;	// const in [ns], only required for IdentRes
 	// 0x1F98.7: MultiplCycleCnt_U8
 	unsigned int m_uiMultiplCycleCnt;	// required for error detection
 	// 0x1F98.8: AsyncMTU_U16
@@ -167,30 +167,30 @@
 	// $$$ Multiplexed Slot
 
 	// 0x1C14: DLL_LossOfFrameTolerance_U32 in [ns]
-	DWORD m_dwLossOfFrameTolerance;
+	u32 m_dwLossOfFrameTolerance;
 
 	// 0x1F8A: NMT_MNCycleTiming_REC
 	// 0x1F8A.1: WaitSoCPReq_U32 in [ns]
-	DWORD m_dwWaitSocPreq;
+	u32 m_dwWaitSocPreq;
 
 	// 0x1F8A.2: AsyncSlotTimeout_U32 in [ns]
-	DWORD m_dwAsyncSlotTimeout;
+	u32 m_dwAsyncSlotTimeout;
 
-	DWORD m_dwDeviceType;	// NMT_DeviceType_U32
-	DWORD m_dwVendorId;	// NMT_IdentityObject_REC.VendorId_U32
-	DWORD m_dwProductCode;	// NMT_IdentityObject_REC.ProductCode_U32
-	DWORD m_dwRevisionNumber;	// NMT_IdentityObject_REC.RevisionNo_U32
-	DWORD m_dwSerialNumber;	// NMT_IdentityObject_REC.SerialNo_U32
-	QWORD m_qwVendorSpecificExt1;
-	DWORD m_dwVerifyConfigurationDate;	// CFM_VerifyConfiguration_REC.ConfDate_U32
-	DWORD m_dwVerifyConfigurationTime;	// CFM_VerifyConfiguration_REC.ConfTime_U32
-	DWORD m_dwApplicationSwDate;	// PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device
-	DWORD m_dwApplicationSwTime;	// PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device
-	DWORD m_dwIpAddress;
-	DWORD m_dwSubnetMask;
-	DWORD m_dwDefaultGateway;
-	BYTE m_sHostname[32];
-	BYTE m_abVendorSpecificExt2[48];
+	u32 m_dwDeviceType;	// NMT_DeviceType_U32
+	u32 m_dwVendorId;	// NMT_IdentityObject_REC.VendorId_U32
+	u32 m_dwProductCode;	// NMT_IdentityObject_REC.ProductCode_U32
+	u32 m_dwRevisionNumber;	// NMT_IdentityObject_REC.RevisionNo_U32
+	u32 m_dwSerialNumber;	// NMT_IdentityObject_REC.SerialNo_U32
+	u64 m_qwVendorSpecificExt1;
+	u32 m_dwVerifyConfigurationDate;	// CFM_VerifyConfiguration_REC.ConfDate_U32
+	u32 m_dwVerifyConfigurationTime;	// CFM_VerifyConfiguration_REC.ConfTime_U32
+	u32 m_dwApplicationSwDate;	// PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device
+	u32 m_dwApplicationSwTime;	// PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device
+	u32 m_dwIpAddress;
+	u32 m_dwSubnetMask;
+	u32 m_dwDefaultGateway;
+	u8 m_sHostname[32];
+	u8 m_abVendorSpecificExt2[48];
 
 	char *m_pszDevName;	// NMT_ManufactDevName_VS (0x1008/0 local OD)
 	char *m_pszHwVersion;	// NMT_ManufactHwVers_VS  (0x1009/0 local OD)
@@ -212,62 +212,61 @@
 // function prototypes
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplApiInitialize(tEplApiInitParam * pInitParam_p);
+tEplKernel EplApiInitialize(tEplApiInitParam *pInitParam_p);
 
-tEplKernel PUBLIC EplApiShutdown(void);
+tEplKernel EplApiShutdown(void);
 
-tEplKernel PUBLIC EplApiReadObject(tEplSdoComConHdl * pSdoComConHdl_p,
-				   unsigned int uiNodeId_p,
-				   unsigned int uiIndex_p,
-				   unsigned int uiSubindex_p,
-				   void *pDstData_le_p,
-				   unsigned int *puiSize_p,
-				   tEplSdoType SdoType_p, void *pUserArg_p);
+tEplKernel EplApiReadObject(tEplSdoComConHdl *pSdoComConHdl_p,
+			    unsigned int uiNodeId_p,
+			    unsigned int uiIndex_p,
+			    unsigned int uiSubindex_p,
+			    void *pDstData_le_p,
+			    unsigned int *puiSize_p,
+			    tEplSdoType SdoType_p, void *pUserArg_p);
 
-tEplKernel PUBLIC EplApiWriteObject(tEplSdoComConHdl * pSdoComConHdl_p,
-				    unsigned int uiNodeId_p,
-				    unsigned int uiIndex_p,
-				    unsigned int uiSubindex_p,
-				    void *pSrcData_le_p,
-				    unsigned int uiSize_p,
-				    tEplSdoType SdoType_p, void *pUserArg_p);
+tEplKernel EplApiWriteObject(tEplSdoComConHdl *pSdoComConHdl_p,
+			     unsigned int uiNodeId_p,
+			     unsigned int uiIndex_p,
+			     unsigned int uiSubindex_p,
+			     void *pSrcData_le_p,
+			     unsigned int uiSize_p,
+			     tEplSdoType SdoType_p, void *pUserArg_p);
 
-tEplKernel PUBLIC EplApiFreeSdoChannel(tEplSdoComConHdl SdoComConHdl_p);
+tEplKernel EplApiFreeSdoChannel(tEplSdoComConHdl SdoComConHdl_p);
 
-tEplKernel PUBLIC EplApiReadLocalObject(unsigned int uiIndex_p,
-					unsigned int uiSubindex_p,
-					void *pDstData_p,
-					unsigned int *puiSize_p);
+tEplKernel EplApiReadLocalObject(unsigned int uiIndex_p,
+				 unsigned int uiSubindex_p,
+				 void *pDstData_p,
+				 unsigned int *puiSize_p);
 
-tEplKernel PUBLIC EplApiWriteLocalObject(unsigned int uiIndex_p,
-					 unsigned int uiSubindex_p,
-					 void *pSrcData_p,
-					 unsigned int uiSize_p);
+tEplKernel EplApiWriteLocalObject(unsigned int uiIndex_p,
+				  unsigned int uiSubindex_p,
+				  void *pSrcData_p,
+				  unsigned int uiSize_p);
 
-tEplKernel PUBLIC EplApiCbObdAccess(tEplObdCbParam MEM * pParam_p);
+tEplKernel EplApiCbObdAccess(tEplObdCbParam *pParam_p);
 
-tEplKernel PUBLIC EplApiLinkObject(unsigned int uiObjIndex_p,
-				   void *pVar_p,
-				   unsigned int *puiVarEntries_p,
-				   tEplObdSize * pEntrySize_p,
-				   unsigned int uiFirstSubindex_p);
+tEplKernel EplApiLinkObject(unsigned int uiObjIndex_p,
+			    void *pVar_p,
+			    unsigned int *puiVarEntries_p,
+			    tEplObdSize *pEntrySize_p,
+			    unsigned int uiFirstSubindex_p);
 
-tEplKernel PUBLIC EplApiExecNmtCommand(tEplNmtEvent NmtEvent_p);
+tEplKernel EplApiExecNmtCommand(tEplNmtEvent NmtEvent_p);
 
-tEplKernel PUBLIC EplApiProcess(void);
+tEplKernel EplApiProcess(void);
 
 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-tEplKernel PUBLIC EplApiMnTriggerStateChange(unsigned int uiNodeId_p,
-					     tEplNmtNodeCommand NodeCommand_p);
+tEplKernel EplApiMnTriggerStateChange(unsigned int uiNodeId_p,
+				      tEplNmtNodeCommand NodeCommand_p);
 #endif
 
-tEplKernel PUBLIC EplApiGetIdentResponse(unsigned int uiNodeId_p,
-					 tEplIdentResponse **
-					 ppIdentResponse_p);
+tEplKernel EplApiGetIdentResponse(unsigned int uiNodeId_p,
+				  tEplIdentResponse **ppIdentResponse_p);
 
 // functions for process image will be implemented in separate file
-tEplKernel PUBLIC EplApiProcessImageSetup(void);
-tEplKernel PUBLIC EplApiProcessImageExchangeIn(tEplApiProcessImage * pPI_p);
-tEplKernel PUBLIC EplApiProcessImageExchangeOut(tEplApiProcessImage * pPI_p);
+tEplKernel EplApiProcessImageSetup(void);
+tEplKernel EplApiProcessImageExchangeIn(tEplApiProcessImage *pPI_p);
+tEplKernel EplApiProcessImageExchangeOut(tEplApiProcessImage *pPI_p);
 
 #endif // #ifndef _EPL_API_H_
diff --git a/drivers/staging/epl/EplAmi.h b/drivers/staging/epl/EplAmi.h
index 6fa04a4..3b46ea1 100644
--- a/drivers/staging/epl/EplAmi.h
+++ b/drivers/staging/epl/EplAmi.h
@@ -69,7 +69,7 @@
 
    16.09.2002  -as
                To save code space the functions AmiSetByte and AmiGetByte
-               are replaced by macros. For targets which assign BYTE by
+               are replaced by macros. For targets which assign u8 by
                an 16Bit type, the definition of macros must changed to
                functions.
 
@@ -86,11 +86,6 @@
 #ifndef _EPLAMI_H_
 #define _EPLAMI_H_
 
-#if ((DEV_SYSTEM & _DEV_64BIT_SUPPORT_) == 0)
-//    #ifdef USE_VAR64
-#error 'ERROR: development system does not support 64 bit operations!'
-//    #endif
-#endif
 
 //---------------------------------------------------------------------------
 //  types
@@ -104,44 +99,21 @@
 extern "C" {
 #endif
 
-#if (TARGET_SYSTEM == _WIN32_)
-#if defined(INLINE_FUNCTION_DEF)
-#undef  INLINE_FUNCTION
-#define INLINE_FUNCTION     INLINE_FUNCTION_DEF
-#define INLINE_ENABLED      TRUE
-#define EPL_AMI_INLINED
-#include "../EplStack/amix86.c"
-#endif
-
-#elif (TARGET_SYSTEM == _LINUX_)
-#if defined(__m68k__)		// it is an big endian machine
-#if defined(INLINE_FUNCTION_DEF)
-#undef  INLINE_FUNCTION
-#define INLINE_FUNCTION     INLINE_FUNCTION_DEF
-#define INLINE_ENABLED      TRUE
-#define EPL_AMI_INLINED
-#include "../EplStack/amibe.c"
-#endif
-#endif
-#endif
-
 //---------------------------------------------------------------------------
 //
 // write functions
 //
 // To save code space the function AmiSetByte is replaced by
 // an macro.
-// void   PUBLIC  AmiSetByte  (void FAR* pAddr_p, BYTE bByteVal_p);
+// void  AmiSetByte  (void * pAddr_p, u8 bByteVal_p);
 
-#define AmiSetByteToBe(pAddr_p, bByteVal_p)  {*(BYTE FAR*)(pAddr_p) = (bByteVal_p);}
-#define AmiSetByteToLe(pAddr_p, bByteVal_p)  {*(BYTE FAR*)(pAddr_p) = (bByteVal_p);}
+#define AmiSetByteToBe(pAddr_p, bByteVal_p)  {*(u8 *)(pAddr_p) = (bByteVal_p);}
+#define AmiSetByteToLe(pAddr_p, bByteVal_p)  {*(u8 *)(pAddr_p) = (bByteVal_p);}
 
-#if !defined(INLINE_ENABLED)
-	void PUBLIC AmiSetWordToBe(void FAR * pAddr_p, WORD wWordVal_p);
-	void PUBLIC AmiSetDwordToBe(void FAR * pAddr_p, DWORD dwDwordVal_p);
-	void PUBLIC AmiSetWordToLe(void FAR * pAddr_p, WORD wWordVal_p);
-	void PUBLIC AmiSetDwordToLe(void FAR * pAddr_p, DWORD dwDwordVal_p);
-#endif
+void AmiSetWordToBe(void *pAddr_p, u16 wWordVal_p);
+void AmiSetDwordToBe(void *pAddr_p, u32 dwDwordVal_p);
+void AmiSetWordToLe(void *pAddr_p, u16 wWordVal_p);
+void AmiSetDwordToLe(void *pAddr_p, u32 dwDwordVal_p);
 
 //---------------------------------------------------------------------------
 //
@@ -149,17 +121,15 @@
 //
 // To save code space the function AmiGetByte is replaced by
 // an macro.
-// BYTE   PUBLIC  AmiGetByte  (void FAR* pAddr_p);
+// u8   AmiGetByte  (void * pAddr_p);
 
-#define AmiGetByteFromBe(pAddr_p)  (*(BYTE FAR*)(pAddr_p))
-#define AmiGetByteFromLe(pAddr_p)  (*(BYTE FAR*)(pAddr_p))
+#define AmiGetByteFromBe(pAddr_p)  (*(u8 *)(pAddr_p))
+#define AmiGetByteFromLe(pAddr_p)  (*(u8 *)(pAddr_p))
 
-#if !defined(INLINE_ENABLED)
-
-	WORD PUBLIC AmiGetWordFromBe(void FAR * pAddr_p);
-	DWORD PUBLIC AmiGetDwordFromBe(void FAR * pAddr_p);
-	WORD PUBLIC AmiGetWordFromLe(void FAR * pAddr_p);
-	DWORD PUBLIC AmiGetDwordFromLe(void FAR * pAddr_p);
+u16 AmiGetWordFromBe(void *pAddr_p);
+u32 AmiGetDwordFromBe(void *pAddr_p);
+u16 AmiGetWordFromLe(void *pAddr_p);
+u32 AmiGetDwordFromLe(void *pAddr_p);
 
 //---------------------------------------------------------------------------
 //
@@ -174,8 +144,8 @@
 //
 //---------------------------------------------------------------------------
 
-	void PUBLIC AmiSetDword24ToBe(void FAR * pAddr_p, DWORD dwDwordVal_p);
-	void PUBLIC AmiSetDword24ToLe(void FAR * pAddr_p, DWORD dwDwordVal_p);
+void AmiSetDword24ToBe(void *pAddr_p, u32 dwDwordVal_p);
+void AmiSetDword24ToLe(void *pAddr_p, u32 dwDwordVal_p);
 
 //---------------------------------------------------------------------------
 //
@@ -185,12 +155,12 @@
 //
 // Parameters:  pAddr_p         = pointer to source buffer
 //
-// Return:      DWORD           = read value
+// Return:      u32           = read value
 //
 //---------------------------------------------------------------------------
 
-	DWORD PUBLIC AmiGetDword24FromBe(void FAR * pAddr_p);
-	DWORD PUBLIC AmiGetDword24FromLe(void FAR * pAddr_p);
+u32 AmiGetDword24FromBe(void *pAddr_p);
+u32 AmiGetDword24FromLe(void *pAddr_p);
 
 //#ifdef USE_VAR64
 
@@ -207,8 +177,8 @@
 //
 //---------------------------------------------------------------------------
 
-	void PUBLIC AmiSetQword40ToBe(void FAR * pAddr_p, QWORD qwQwordVal_p);
-	void PUBLIC AmiSetQword40ToLe(void FAR * pAddr_p, QWORD qwQwordVal_p);
+void AmiSetQword40ToBe(void *pAddr_p, u64 qwQwordVal_p);
+void AmiSetQword40ToLe(void *pAddr_p, u64 qwQwordVal_p);
 
 //---------------------------------------------------------------------------
 //
@@ -218,12 +188,12 @@
 //
 // Parameters:  pAddr_p         = pointer to source buffer
 //
-// Return:      QWORD
+// Return:      u64
 //
 //---------------------------------------------------------------------------
 
-	QWORD PUBLIC AmiGetQword40FromBe(void FAR * pAddr_p);
-	QWORD PUBLIC AmiGetQword40FromLe(void FAR * pAddr_p);
+u64 AmiGetQword40FromBe(void *pAddr_p);
+u64 AmiGetQword40FromLe(void *pAddr_p);
 
 //---------------------------------------------------------------------------
 //
@@ -238,8 +208,8 @@
 //
 //---------------------------------------------------------------------------
 
-	void PUBLIC AmiSetQword48ToBe(void FAR * pAddr_p, QWORD qwQwordVal_p);
-	void PUBLIC AmiSetQword48ToLe(void FAR * pAddr_p, QWORD qwQwordVal_p);
+void AmiSetQword48ToBe(void *pAddr_p, u64 qwQwordVal_p);
+void AmiSetQword48ToLe(void *pAddr_p, u64 qwQwordVal_p);
 
 //---------------------------------------------------------------------------
 //
@@ -249,12 +219,12 @@
 //
 // Parameters:  pAddr_p         = pointer to source buffer
 //
-// Return:      QWORD
+// Return:      u64
 //
 //---------------------------------------------------------------------------
 
-	QWORD PUBLIC AmiGetQword48FromBe(void FAR * pAddr_p);
-	QWORD PUBLIC AmiGetQword48FromLe(void FAR * pAddr_p);
+u64 AmiGetQword48FromBe(void *pAddr_p);
+u64 AmiGetQword48FromLe(void *pAddr_p);
 
 //---------------------------------------------------------------------------
 //
@@ -269,8 +239,8 @@
 //
 //---------------------------------------------------------------------------
 
-	void PUBLIC AmiSetQword56ToBe(void FAR * pAddr_p, QWORD qwQwordVal_p);
-	void PUBLIC AmiSetQword56ToLe(void FAR * pAddr_p, QWORD qwQwordVal_p);
+void AmiSetQword56ToBe(void *pAddr_p, u64 qwQwordVal_p);
+void AmiSetQword56ToLe(void *pAddr_p, u64 qwQwordVal_p);
 
 //---------------------------------------------------------------------------
 //
@@ -280,12 +250,12 @@
 //
 // Parameters:  pAddr_p         = pointer to source buffer
 //
-// Return:      QWORD
+// Return:      u64
 //
 //---------------------------------------------------------------------------
 
-	QWORD PUBLIC AmiGetQword56FromBe(void FAR * pAddr_p);
-	QWORD PUBLIC AmiGetQword56FromLe(void FAR * pAddr_p);
+u64 AmiGetQword56FromBe(void *pAddr_p);
+u64 AmiGetQword56FromLe(void *pAddr_p);
 
 //---------------------------------------------------------------------------
 //
@@ -300,8 +270,8 @@
 //
 //---------------------------------------------------------------------------
 
-	void PUBLIC AmiSetQword64ToBe(void FAR * pAddr_p, QWORD qwQwordVal_p);
-	void PUBLIC AmiSetQword64ToLe(void FAR * pAddr_p, QWORD qwQwordVal_p);
+void AmiSetQword64ToBe(void *pAddr_p, u64 qwQwordVal_p);
+void AmiSetQword64ToLe(void *pAddr_p, u64 qwQwordVal_p);
 
 //---------------------------------------------------------------------------
 //
@@ -315,8 +285,8 @@
 //
 //---------------------------------------------------------------------------
 
-	QWORD PUBLIC AmiGetQword64FromBe(void FAR * pAddr_p);
-	QWORD PUBLIC AmiGetQword64FromLe(void FAR * pAddr_p);
+u64 AmiGetQword64FromBe(void *pAddr_p);
+u64 AmiGetQword64FromLe(void *pAddr_p);
 
 //---------------------------------------------------------------------------
 //
@@ -330,9 +300,7 @@
 // Return:      void
 //
 //---------------------------------------------------------------------------
-
-	void PUBLIC AmiSetTimeOfDay(void FAR * pAddr_p,
-				    tTimeOfDay FAR * pTimeOfDay_p);
+void AmiSetTimeOfDay(void *pAddr_p, tTimeOfDay *pTimeOfDay_p);
 
 //---------------------------------------------------------------------------
 //
@@ -346,14 +314,7 @@
 // Return:      void
 //
 //---------------------------------------------------------------------------
-
-	void PUBLIC AmiGetTimeOfDay(void FAR * pAddr_p,
-				    tTimeOfDay FAR * pTimeOfDay_p);
-
-#endif
-
-#undef  INLINE_ENABLED		// disable actual inlining of functions
-#define EPL_AMI_INCLUDED
+void AmiGetTimeOfDay(void *pAddr_p, tTimeOfDay *pTimeOfDay_p);
 
 #ifdef __cplusplus
 }
diff --git a/drivers/staging/epl/EplApiGeneric.c b/drivers/staging/epl/EplApiGeneric.c
index ae19e34..c4419569 100644
--- a/drivers/staging/epl/EplApiGeneric.c
+++ b/drivers/staging/epl/EplApiGeneric.c
@@ -162,44 +162,41 @@
 //---------------------------------------------------------------------------
 
 // NMT state change event callback function
-static tEplKernel PUBLIC EplApiCbNmtStateChange(tEplEventNmtStateChange
-						NmtStateChange_p);
+static tEplKernel EplApiCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p);
 
 // update DLL configuration from OD
-static tEplKernel PUBLIC EplApiUpdateDllConfig(BOOL fUpdateIdentity_p);
+static tEplKernel EplApiUpdateDllConfig(BOOL fUpdateIdentity_p);
 
 // update OD from init param
-static tEplKernel PUBLIC EplApiUpdateObd(void);
+static tEplKernel EplApiUpdateObd(void);
 
 // process events from user event queue
-static tEplKernel PUBLIC EplApiProcessEvent(tEplEvent * pEplEvent_p);
+static tEplKernel EplApiProcessEvent(tEplEvent *pEplEvent_p);
 
 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
 // callback function of SDO module
-static tEplKernel PUBLIC EplApiCbSdoCon(tEplSdoComFinished * pSdoComFinished_p);
+static tEplKernel EplApiCbSdoCon(tEplSdoComFinished *pSdoComFinished_p);
 #endif
 
 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
 // callback functions of NmtMnu module
-static tEplKernel PUBLIC EplApiCbNodeEvent(unsigned int uiNodeId_p,
-					   tEplNmtNodeEvent NodeEvent_p,
-					   tEplNmtState NmtState_p,
-					   WORD wErrorCode_p,
-					   BOOL fMandatory_p);
+static tEplKernel EplApiCbNodeEvent(unsigned int uiNodeId_p,
+				    tEplNmtNodeEvent NodeEvent_p,
+				    tEplNmtState NmtState_p,
+				    u16 wErrorCode_p, BOOL fMandatory_p);
 
-static tEplKernel PUBLIC EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
-					   tEplNmtState NmtState_p,
-					   WORD wErrorCode_p);
+static tEplKernel EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
+				    tEplNmtState NmtState_p,
+				    u16 wErrorCode_p);
 #endif
 
 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
 // callback function of Ledu module
-static tEplKernel PUBLIC EplApiCbLedStateChange(tEplLedType LedType_p,
-						BOOL fOn_p);
+static tEplKernel EplApiCbLedStateChange(tEplLedType LedType_p, BOOL fOn_p);
 #endif
 
 // OD initialization function (implemented in Objdict.c)
-tEplKernel PUBLIC EplObdInitRam(tEplObdInitParam MEM * pInitParam_p);
+tEplKernel EplObdInitRam(tEplObdInitParam *pInitParam_p);
 
 //=========================================================================//
 //                                                                         //
@@ -226,7 +223,7 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplApiInitialize(tEplApiInitParam * pInitParam_p)
+tEplKernel EplApiInitialize(tEplApiInitParam *pInitParam_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 	tEplObdInitParam ObdInitParam;
@@ -415,7 +412,7 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplApiShutdown(void)
+tEplKernel EplApiShutdown(void)
 {
 	tEplKernel Ret = kEplSuccessful;
 
@@ -523,7 +520,7 @@
 // State:
 //----------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplApiExecNmtCommand(tEplNmtEvent NmtEvent_p)
+tEplKernel EplApiExecNmtCommand(tEplNmtEvent NmtEvent_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 
@@ -553,15 +550,15 @@
 // State:
 //----------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplApiLinkObject(unsigned int uiObjIndex_p,
-				   void *pVar_p,
-				   unsigned int *puiVarEntries_p,
-				   tEplObdSize * pEntrySize_p,
-				   unsigned int uiFirstSubindex_p)
+tEplKernel EplApiLinkObject(unsigned int uiObjIndex_p,
+			    void *pVar_p,
+			    unsigned int *puiVarEntries_p,
+			    tEplObdSize *pEntrySize_p,
+			    unsigned int uiFirstSubindex_p)
 {
-	BYTE bVarEntries;
-	BYTE bIndexEntries;
-	BYTE MEM *pbData;
+	u8 bVarEntries;
+	u8 bIndexEntries;
+	u8 *pbData;
 	unsigned int uiSubindex;
 	tEplVarParam VarParam;
 	tEplObdSize EntrySize;
@@ -577,8 +574,8 @@
 		goto Exit;
 	}
 
-	pbData = (BYTE MEM *) pVar_p;
-	bVarEntries = (BYTE) * puiVarEntries_p;
+	pbData = (u8 *)pVar_p;
+	bVarEntries = (u8) * puiVarEntries_p;
 	UsedSize = 0;
 
 	// init VarParam structure with default values
@@ -591,7 +588,7 @@
 		EntrySize = (tEplObdSize) sizeof(bIndexEntries);
 		RetCode = EplObdReadEntry(uiObjIndex_p,
 					  0x00,
-					  (void GENERIC *)&bIndexEntries,
+					  (void *)&bIndexEntries,
 					  &EntrySize);
 
 		if ((RetCode != kEplSuccessful) || (bIndexEntries == 0x00)) {
@@ -610,7 +607,7 @@
 	// object actually has.
 	if ((bIndexEntries > (bVarEntries + uiFirstSubindex_p - 1)) &&
 	    (bVarEntries != 0x00)) {
-		bIndexEntries = (BYTE) (bVarEntries + uiFirstSubindex_p - 1);
+		bIndexEntries = (u8) (bVarEntries + uiFirstSubindex_p - 1);
 	}
 	// map entries
 	for (uiSubindex = uiFirstSubindex_p; uiSubindex <= bIndexEntries;
@@ -677,13 +674,13 @@
 //
 // ----------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplApiReadObject(tEplSdoComConHdl * pSdoComConHdl_p,
-				   unsigned int uiNodeId_p,
-				   unsigned int uiIndex_p,
-				   unsigned int uiSubindex_p,
-				   void *pDstData_le_p,
-				   unsigned int *puiSize_p,
-				   tEplSdoType SdoType_p, void *pUserArg_p)
+tEplKernel EplApiReadObject(tEplSdoComConHdl *pSdoComConHdl_p,
+			    unsigned int uiNodeId_p,
+			    unsigned int uiIndex_p,
+			    unsigned int uiSubindex_p,
+			    void *pDstData_le_p,
+			    unsigned int *puiSize_p,
+			    tEplSdoType SdoType_p, void *pUserArg_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 
@@ -765,13 +762,13 @@
 //
 // ----------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplApiWriteObject(tEplSdoComConHdl * pSdoComConHdl_p,
-				    unsigned int uiNodeId_p,
-				    unsigned int uiIndex_p,
-				    unsigned int uiSubindex_p,
-				    void *pSrcData_le_p,
-				    unsigned int uiSize_p,
-				    tEplSdoType SdoType_p, void *pUserArg_p)
+tEplKernel EplApiWriteObject(tEplSdoComConHdl *pSdoComConHdl_p,
+			     unsigned int uiNodeId_p,
+			     unsigned int uiIndex_p,
+			     unsigned int uiSubindex_p,
+			     void *pSrcData_le_p,
+			     unsigned int uiSize_p,
+			     tEplSdoType SdoType_p, void *pUserArg_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 
@@ -850,7 +847,7 @@
 //
 // ----------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplApiFreeSdoChannel(tEplSdoComConHdl SdoComConHdl_p)
+tEplKernel EplApiFreeSdoChannel(tEplSdoComConHdl SdoComConHdl_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 
@@ -881,10 +878,9 @@
 //
 // ----------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplApiReadLocalObject(unsigned int uiIndex_p,
-					unsigned int uiSubindex_p,
-					void *pDstData_p,
-					unsigned int *puiSize_p)
+tEplKernel EplApiReadLocalObject(unsigned int uiIndex_p,
+				 unsigned int uiSubindex_p,
+				 void *pDstData_p, unsigned int *puiSize_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 	tEplObdSize ObdSize;
@@ -911,10 +907,10 @@
 //
 // ----------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplApiWriteLocalObject(unsigned int uiIndex_p,
-					 unsigned int uiSubindex_p,
-					 void *pSrcData_p,
-					 unsigned int uiSize_p)
+tEplKernel EplApiWriteLocalObject(unsigned int uiIndex_p,
+				  unsigned int uiSubindex_p,
+				  void *pSrcData_p,
+				  unsigned int uiSize_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 
@@ -939,8 +935,8 @@
 //
 // ----------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplApiMnTriggerStateChange(unsigned int uiNodeId_p,
-					     tEplNmtNodeCommand NodeCommand_p)
+tEplKernel EplApiMnTriggerStateChange(unsigned int uiNodeId_p,
+				      tEplNmtNodeCommand NodeCommand_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 
@@ -966,7 +962,7 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplApiCbObdAccess(tEplObdCbParam MEM * pParam_p)
+tEplKernel EplApiCbObdAccess(tEplObdCbParam *pParam_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 
@@ -1001,8 +997,8 @@
 		{
 			if ((pParam_p->m_ObdEvent == kEplObdEvPostWrite)
 			    && (pParam_p->m_uiSubIndex == 3)
-			    && (*((DWORD *) pParam_p->m_pArg) != 0)) {
-				DWORD dwVerifyConfInvalid = 0;
+			    && (*((u32 *) pParam_p->m_pArg) != 0)) {
+				u32 dwVerifyConfInvalid = 0;
 				// set CFM_VerifyConfiguration_REC.VerifyConfInvalid_U32 to 0
 				Ret =
 				    EplObdWriteEntry(0x1020, 4,
@@ -1016,9 +1012,9 @@
 	case 0x1F9E:		// NMT_ResetCmd_U8
 		{
 			if (pParam_p->m_ObdEvent == kEplObdEvPreWrite) {
-				BYTE bNmtCommand;
+				u8 bNmtCommand;
 
-				bNmtCommand = *((BYTE *) pParam_p->m_pArg);
+				bNmtCommand = *((u8 *) pParam_p->m_pArg);
 				// check value range
 				switch ((tEplNmtCommand) bNmtCommand) {
 				case kEplNmtCmdResetNode:
@@ -1036,9 +1032,9 @@
 					break;
 				}
 			} else if (pParam_p->m_ObdEvent == kEplObdEvPostWrite) {
-				BYTE bNmtCommand;
+				u8 bNmtCommand;
 
-				bNmtCommand = *((BYTE *) pParam_p->m_pArg);
+				bNmtCommand = *((u8 *) pParam_p->m_pArg);
 				// check value range
 				switch ((tEplNmtCommand) bNmtCommand) {
 				case kEplNmtCmdResetNode:
@@ -1115,7 +1111,7 @@
 //
 //---------------------------------------------------------------------------
 
-static tEplKernel PUBLIC EplApiProcessEvent(tEplEvent * pEplEvent_p)
+static tEplKernel EplApiProcessEvent(tEplEvent *pEplEvent_p)
 {
 	tEplKernel Ret;
 	tEplEventError *pEventError;
@@ -1188,15 +1184,14 @@
 //
 //---------------------------------------------------------------------------
 
-static tEplKernel PUBLIC EplApiCbNmtStateChange(tEplEventNmtStateChange
-						NmtStateChange_p)
+static tEplKernel EplApiCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p)
 {
 	tEplKernel Ret = kEplSuccessful;
-	BYTE bNmtState;
+	u8 bNmtState;
 	tEplApiEventArg EventArg;
 
 	// save NMT state in OD
-	bNmtState = (BYTE) NmtStateChange_p.m_NewNmtState;
+	bNmtState = (u8) NmtStateChange_p.m_NewNmtState;
 	Ret = EplObdWriteEntry(0x1F8C, 0, &bNmtState, 1);
 	if (Ret != kEplSuccessful) {
 		goto Exit;
@@ -1275,7 +1270,7 @@
 	case kEplNmtCsNotActive:
 		{
 			// indicate completion of reset in NMT_ResetCmd_U8
-			bNmtState = (BYTE) kEplNmtCmdInvalidService;
+			bNmtState = (u8) kEplNmtCmdInvalidService;
 			Ret = EplObdWriteEntry(0x1F9E, 0, &bNmtState, 1);
 			if (Ret != kEplSuccessful) {
 				goto Exit;
@@ -1411,14 +1406,14 @@
 //
 //---------------------------------------------------------------------------
 
-static tEplKernel PUBLIC EplApiUpdateDllConfig(BOOL fUpdateIdentity_p)
+static tEplKernel EplApiUpdateDllConfig(BOOL fUpdateIdentity_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 	tEplDllConfigParam DllConfigParam;
 	tEplDllIdentParam DllIdentParam;
 	tEplObdSize ObdSize;
-	WORD wTemp;
-	BYTE bTemp;
+	u16 wTemp;
+	u8 bTemp;
 
 	// configure Dll
 	EPL_MEMSET(&DllConfigParam, 0, sizeof(DllConfigParam));
@@ -1634,11 +1629,11 @@
 //
 //---------------------------------------------------------------------------
 
-static tEplKernel PUBLIC EplApiUpdateObd(void)
+static tEplKernel EplApiUpdateObd(void)
 {
 	tEplKernel Ret = kEplSuccessful;
-	WORD wTemp;
-	BYTE bTemp;
+	u16 wTemp;
+	u8 bTemp;
 
 	// set node id in OD
 	Ret = EplObdSetNodeId(EplApiInstance_g.m_InitParam.m_uiNodeId,	// node id
@@ -1680,14 +1675,14 @@
 		   } */
 	}
 
-	wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiIsochrTxMaxPayload;
+	wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiIsochrTxMaxPayload;
 	Ret = EplObdWriteEntry(0x1F98, 1, &wTemp, 2);
 /*    if(Ret != kEplSuccessful)
     {
         goto Exit;
     }*/
 
-	wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiIsochrRxMaxPayload;
+	wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiIsochrRxMaxPayload;
 	Ret = EplObdWriteEntry(0x1F98, 2, &wTemp, 2);
 /*    if(Ret != kEplSuccessful)
     {
@@ -1706,7 +1701,7 @@
 	if (EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit <=
 	    EPL_C_DLL_ISOCHR_MAX_PAYL) {
 		wTemp =
-		    (WORD) EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit;
+		    (u16) EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit;
 		Ret = EplObdWriteEntry(0x1F98, 4, &wTemp, 2);
 /*    if(Ret != kEplSuccessful)
     {
@@ -1717,7 +1712,7 @@
 	if (EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit <=
 	    EPL_C_DLL_ISOCHR_MAX_PAYL) {
 		wTemp =
-		    (WORD) EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit;
+		    (u16) EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit;
 		Ret = EplObdWriteEntry(0x1F98, 5, &wTemp, 2);
 /*    if(Ret != kEplSuccessful)
     {
@@ -1735,7 +1730,7 @@
     }*/
 
 	if (EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt <= 0xFF) {
-		bTemp = (BYTE) EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt;
+		bTemp = (u8) EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt;
 		Ret = EplObdWriteEntry(0x1F98, 7, &bTemp, 1);
 /*    if(Ret != kEplSuccessful)
     {
@@ -1745,7 +1740,7 @@
 
 	if (EplApiInstance_g.m_InitParam.m_uiAsyncMtu <=
 	    EPL_C_DLL_MAX_ASYNC_MTU) {
-		wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiAsyncMtu;
+		wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiAsyncMtu;
 		Ret = EplObdWriteEntry(0x1F98, 8, &wTemp, 2);
 /*    if(Ret != kEplSuccessful)
     {
@@ -1754,7 +1749,7 @@
 	}
 
 	if (EplApiInstance_g.m_InitParam.m_uiPrescaler <= 1000) {
-		wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiPrescaler;
+		wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiPrescaler;
 		Ret = EplObdWriteEntry(0x1F98, 9, &wTemp, 2);
 		// ignore return code
 		Ret = kEplSuccessful;
@@ -1844,7 +1839,7 @@
 		// write Device Name (0x1008)
 		Ret =
 		    EplObdWriteEntry(0x1008, 0,
-				     (void GENERIC *)EplApiInstance_g.
+				     (void *)EplApiInstance_g.
 				     m_InitParam.m_pszDevName,
 				     (tEplObdSize) strlen(EplApiInstance_g.
 							  m_InitParam.
@@ -1859,7 +1854,7 @@
 		// write Hardware version (0x1009)
 		Ret =
 		    EplObdWriteEntry(0x1009, 0,
-				     (void GENERIC *)EplApiInstance_g.
+				     (void *)EplApiInstance_g.
 				     m_InitParam.m_pszHwVersion,
 				     (tEplObdSize) strlen(EplApiInstance_g.
 							  m_InitParam.
@@ -1874,7 +1869,7 @@
 		// write Software version (0x100A)
 		Ret =
 		    EplObdWriteEntry(0x100A, 0,
-				     (void GENERIC *)EplApiInstance_g.
+				     (void *)EplApiInstance_g.
 				     m_InitParam.m_pszSwVersion,
 				     (tEplObdSize) strlen(EplApiInstance_g.
 							  m_InitParam.
@@ -1905,7 +1900,7 @@
 //---------------------------------------------------------------------------
 
 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-static tEplKernel PUBLIC EplApiCbSdoCon(tEplSdoComFinished * pSdoComFinished_p)
+static tEplKernel EplApiCbSdoCon(tEplSdoComFinished *pSdoComFinished_p)
 {
 	tEplKernel Ret;
 	tEplApiEventArg EventArg;
@@ -1946,10 +1941,10 @@
 //
 //---------------------------------------------------------------------------
 
-static tEplKernel PUBLIC EplApiCbNodeEvent(unsigned int uiNodeId_p,
-					   tEplNmtNodeEvent NodeEvent_p,
-					   tEplNmtState NmtState_p,
-					   WORD wErrorCode_p, BOOL fMandatory_p)
+static tEplKernel EplApiCbNodeEvent(unsigned int uiNodeId_p,
+				    tEplNmtNodeEvent NodeEvent_p,
+				    tEplNmtState NmtState_p,
+				    u16 wErrorCode_p, BOOL fMandatory_p)
 {
 	tEplKernel Ret;
 	tEplApiEventArg EventArg;
@@ -1990,9 +1985,9 @@
 //
 //---------------------------------------------------------------------------
 
-static tEplKernel PUBLIC EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
-					   tEplNmtState NmtState_p,
-					   WORD wErrorCode_p)
+static tEplKernel EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
+				    tEplNmtState NmtState_p,
+				    u16 wErrorCode_p)
 {
 	tEplKernel Ret;
 	tEplApiEventArg EventArg;
@@ -2033,8 +2028,7 @@
 //
 //---------------------------------------------------------------------------
 
-static tEplKernel PUBLIC EplApiCbLedStateChange(tEplLedType LedType_p,
-						BOOL fOn_p)
+static tEplKernel EplApiCbLedStateChange(tEplLedType LedType_p, BOOL fOn_p)
 {
 	tEplKernel Ret;
 	tEplApiEventArg EventArg;
diff --git a/drivers/staging/epl/EplApiLinuxKernel.c b/drivers/staging/epl/EplApiLinuxKernel.c
index 05ca062..cb3e275 100644
--- a/drivers/staging/epl/EplApiLinuxKernel.c
+++ b/drivers/staging/epl/EplApiLinuxKernel.c
@@ -72,9 +72,6 @@
 
 // kernel modul and driver
 
-//#include <linux/version.h>
-//#include <linux/config.h>
-
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/cdev.h>
@@ -92,25 +89,11 @@
 #include <asm/uaccess.h>
 #include <linux/vmalloc.h>
 
-#ifdef CONFIG_DEVFS_FS
-#include <linux/major.h>
-#include <linux/devfs_fs_kernel.h>
-#endif
-
 #include "Epl.h"
 #include "EplApiLinux.h"
 //#include "kernel/EplPdokCal.h"
 #include "proc_fs.h"
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-    // remove ("make invisible") obsolete symbols for kernel versions 2.6
-    // and higher
-#define MOD_INC_USE_COUNT
-#define MOD_DEC_USE_COUNT
-#define EXPORT_NO_SYMBOLS
-#else
-#error "This driver needs a 2.6.x kernel or higher"
-#endif
 
 /***************************************************************************/
 /*                                                                         */
@@ -139,7 +122,7 @@
 
 // TracePoint support for realtime-debugging
 #ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
 #define TGT_DBG_SIGNAL_TRACE_POINT(p)   TgtDbgSignalTracePoint(p)
 #else
 #define TGT_DBG_SIGNAL_TRACE_POINT(p)
@@ -159,19 +142,10 @@
 //  Global variables
 //---------------------------------------------------------------------------
 
-#ifdef CONFIG_DEVFS_FS
-
-    // driver major number
-static int nDrvMajorNumber_g;
-
-#else
-
     // device number (major and minor)
 static dev_t nDevNum_g;
 static struct cdev *pEpl_cdev_g;
 
-#endif
-
 static volatile unsigned int uiEplState_g = EPL_STATE_NOTOPEN;
 
 static struct semaphore SemaphoreCbEvent_g;	// semaphore for EplLinCbEvent
@@ -204,11 +178,11 @@
 //  Prototypes of internal functions
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplLinCbEvent(tEplApiEventType EventType_p,	// IN: event type (enum)
-				tEplApiEventArg * pEventArg_p,	// IN: event argument (union)
-				void GENERIC * pUserArg_p);
+tEplKernel EplLinCbEvent(tEplApiEventType EventType_p,	// IN: event type (enum)
+			 tEplApiEventArg *pEventArg_p,	// IN: event argument (union)
+			 void *pUserArg_p);
 
-tEplKernel PUBLIC EplLinCbSync(void);
+tEplKernel EplLinCbSync(void);
 
 static int __init EplLinInit(void);
 static void __exit EplLinExit(void);
@@ -226,8 +200,6 @@
 //  Kernel Module specific Data Structures
 //---------------------------------------------------------------------------
 
-EXPORT_NO_SYMBOLS;
-
 module_init(EplLinInit);
 module_exit(EplLinExit);
 
@@ -259,9 +231,6 @@
 	tEplKernel EplRet;
 	int iErr;
 	int iRet;
-#ifdef CONFIG_DEVFS_FS
-	int nMinorNumber;
-#endif
 
 	TRACE0("EPL: + EplLinInit...\n");
 	TRACE2("EPL:   Driver build: %s / %s\n", __DATE__, __TIME__);
@@ -275,44 +244,6 @@
 	init_waitqueue_head(&WaitQueueProcess_g);
 	init_waitqueue_head(&WaitQueueRelease_g);
 
-#ifdef CONFIG_DEVFS_FS
-
-	// register character device handler
-	TRACE2("EPL:   Installing Driver '%s', Version %s...\n",
-	       EPLLIN_DRV_NAME, EPL_PRODUCT_VERSION);
-	TRACE0("EPL:   (using dynamic major number assignment)\n");
-	nDrvMajorNumber_g =
-	    register_chrdev(0, EPLLIN_DRV_NAME, &EplLinFileOps_g);
-	if (nDrvMajorNumber_g != 0) {
-		TRACE2
-		    ("EPL:   Driver '%s' installed successful, assigned MajorNumber=%d\n",
-		     EPLLIN_DRV_NAME, nDrvMajorNumber_g);
-	} else {
-		TRACE1
-		    ("EPL:   ERROR: Driver '%s' is unable to get a free MajorNumber!\n",
-		     EPLLIN_DRV_NAME);
-		iRet = -EIO;
-		goto Exit;
-	}
-
-	// create device node in DEVFS
-	nMinorNumber = 0;
-	TRACE1("EPL:   Creating device node '/dev/%s'...\n", EPLLIN_DEV_NAME);
-	iErr =
-	    devfs_mk_cdev(MKDEV(nDrvMajorNumber_g, nMinorNumber),
-			  S_IFCHR | S_IRUGO | S_IWUGO, EPLLIN_DEV_NAME);
-	if (iErr == 0) {
-		TRACE1("EPL:   Device node '/dev/%s' created successful.\n",
-		       EPLLIN_DEV_NAME);
-	} else {
-		TRACE1("EPL:   ERROR: unable to create device node '/dev/%s'\n",
-		       EPLLIN_DEV_NAME);
-		iRet = -EIO;
-		goto Exit;
-	}
-
-#else
-
 	// register character device handler
 	// only one Minor required
 	TRACE2("EPL:   Installing Driver '%s', Version %s...\n",
@@ -341,7 +272,6 @@
 		iRet = -EIO;
 		goto Exit;
 	}
-#endif
 
 	// create device node in PROCFS
 	EplRet = EplLinProcInit();
@@ -377,25 +307,12 @@
 
 	TRACE0("EPL: + EplLinExit...\n");
 
-#ifdef CONFIG_DEVFS_FS
-
-	// remove device node from DEVFS
-	devfs_remove(EPLLIN_DEV_NAME);
-	TRACE1("EPL:   Device node '/dev/%s' removed.\n", EPLLIN_DEV_NAME);
-
-	// unregister character device handler
-	unregister_chrdev(nDrvMajorNumber_g, EPLLIN_DRV_NAME);
-
-#else
-
 	// remove cdev structure
 	cdev_del(pEpl_cdev_g);
 
 	// unregister character device handler
 	unregister_chrdev_region(nDevNum_g, 1);
 
-#endif
-
 	TRACE1("EPL:   Driver '%s' removed.\n", EPLLIN_DRV_NAME);
 
 	TRACE0("EPL: - EplLinExit\n");
@@ -416,8 +333,6 @@
 
 	TRACE0("EPL: + EplLinOpen...\n");
 
-	MOD_INC_USE_COUNT;
-
 	if (uiEplState_g != EPL_STATE_NOTOPEN) {	// stack already initialized
 		iRet = -EALREADY;
 	} else {
@@ -490,8 +405,6 @@
 	uiEplState_g = EPL_STATE_NOTOPEN;
 	iRet = 0;
 
-	MOD_DEC_USE_COUNT;
-
 	TRACE1("EPL: - EplLinRelease (iRet=%d)\n", iRet);
 	return (iRet);
 
@@ -1158,9 +1071,9 @@
 //                                                                         //
 //=========================================================================//
 
-tEplKernel PUBLIC EplLinCbEvent(tEplApiEventType EventType_p,	// IN: event type (enum)
-				tEplApiEventArg * pEventArg_p,	// IN: event argument (union)
-				void GENERIC * pUserArg_p)
+tEplKernel EplLinCbEvent(tEplApiEventType EventType_p,	// IN: event type (enum)
+			 tEplApiEventArg *pEventArg_p,	// IN: event argument (union)
+			 void *pUserArg_p)
 {
 	tEplKernel EplRet = kEplSuccessful;
 	int iErr;
@@ -1224,7 +1137,7 @@
 	return EplRet;
 }
 
-tEplKernel PUBLIC EplLinCbSync(void)
+tEplKernel EplLinCbSync(void)
 {
 	tEplKernel EplRet = kEplSuccessful;
 	int iErr;
diff --git a/drivers/staging/epl/EplApiProcessImage.c b/drivers/staging/epl/EplApiProcessImage.c
index 2b2fdf2..7d55086 100644
--- a/drivers/staging/epl/EplApiProcessImage.c
+++ b/drivers/staging/epl/EplApiProcessImage.c
@@ -69,11 +69,8 @@
 ****************************************************************************/
 
 #include "Epl.h"
-//#include "kernel/EplPdokCal.h"
 
-#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
-#include <asm/uaccess.h>
-#endif
+#include <linux/uaccess.h>
 
 /***************************************************************************/
 /*                                                                         */
@@ -129,10 +126,10 @@
 #if ((EPL_API_PROCESS_IMAGE_SIZE_IN > 0) || (EPL_API_PROCESS_IMAGE_SIZE_OUT > 0))
 typedef struct {
 #if EPL_API_PROCESS_IMAGE_SIZE_IN > 0
-	BYTE m_abProcessImageInput[EPL_API_PROCESS_IMAGE_SIZE_IN];
+	u8 m_abProcessImageInput[EPL_API_PROCESS_IMAGE_SIZE_IN];
 #endif
 #if EPL_API_PROCESS_IMAGE_SIZE_OUT > 0
-	BYTE m_abProcessImageOutput[EPL_API_PROCESS_IMAGE_SIZE_OUT];
+	u8 m_abProcessImageOutput[EPL_API_PROCESS_IMAGE_SIZE_OUT];
 #endif
 
 } tEplApiProcessImageInstance;
@@ -169,7 +166,7 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplApiProcessImageSetup(void)
+tEplKernel EplApiProcessImageSetup(void)
 {
 	tEplKernel Ret = kEplSuccessful;
 #if ((EPL_API_PROCESS_IMAGE_SIZE_IN > 0) || (EPL_API_PROCESS_IMAGE_SIZE_OUT > 0))
@@ -280,24 +277,16 @@
 // State:
 //----------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplApiProcessImageExchangeIn(tEplApiProcessImage * pPI_p)
+tEplKernel EplApiProcessImageExchangeIn(tEplApiProcessImage *pPI_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 
 #if EPL_API_PROCESS_IMAGE_SIZE_IN > 0
-#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
 	copy_to_user(pPI_p->m_pImage,
 		     EplApiProcessImageInstance_g.m_abProcessImageInput,
 		     min(pPI_p->m_uiSize,
 			 sizeof(EplApiProcessImageInstance_g.
 				m_abProcessImageInput)));
-#else
-	EPL_MEMCPY(pPI_p->m_pImage,
-		   EplApiProcessImageInstance_g.m_abProcessImageInput,
-		   min(pPI_p->m_uiSize,
-		       sizeof(EplApiProcessImageInstance_g.
-			      m_abProcessImageInput)));
-#endif
 #endif
 
 	return Ret;
@@ -315,24 +304,16 @@
 // State:
 //----------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplApiProcessImageExchangeOut(tEplApiProcessImage * pPI_p)
+tEplKernel EplApiProcessImageExchangeOut(tEplApiProcessImage *pPI_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 
 #if EPL_API_PROCESS_IMAGE_SIZE_OUT > 0
-#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
 	copy_from_user(EplApiProcessImageInstance_g.m_abProcessImageOutput,
 		       pPI_p->m_pImage,
 		       min(pPI_p->m_uiSize,
 			   sizeof(EplApiProcessImageInstance_g.
 				  m_abProcessImageOutput)));
-#else
-	EPL_MEMCPY(EplApiProcessImageInstance_g.m_abProcessImageOutput,
-		   pPI_p->m_pImage,
-		   min(pPI_p->m_uiSize,
-		       sizeof(EplApiProcessImageInstance_g.
-			      m_abProcessImageOutput)));
-#endif
 #endif
 
 	return Ret;
diff --git a/drivers/staging/epl/EplDll.h b/drivers/staging/epl/EplDll.h
index 36657f2..b960199 100644
--- a/drivers/staging/epl/EplDll.h
+++ b/drivers/staging/epl/EplDll.h
@@ -135,22 +135,22 @@
 	unsigned int m_uiNodeId;	// local node ID
 
 	// 0x1F82: NMT_FeatureFlags_U32
-	DWORD m_dwFeatureFlags;
+	u32 m_dwFeatureFlags;
 	// Cycle Length (0x1006: NMT_CycleLen_U32) in [us]
-	DWORD m_dwCycleLen;	// required for error detection
+	u32 m_dwCycleLen;	// required for error detection
 	// 0x1F98: NMT_CycleTiming_REC
 	// 0x1F98.1: IsochrTxMaxPayload_U16
 	unsigned int m_uiIsochrTxMaxPayload;	// const
 	// 0x1F98.2: IsochrRxMaxPayload_U16
 	unsigned int m_uiIsochrRxMaxPayload;	// const
 	// 0x1F98.3: PResMaxLatency_U32
-	DWORD m_dwPresMaxLatency;	// const in [ns], only required for IdentRes
+	u32 m_dwPresMaxLatency;	// const in [ns], only required for IdentRes
 	// 0x1F98.4: PReqActPayloadLimit_U16
 	unsigned int m_uiPreqActPayloadLimit;	// required for initialisation (+24 bytes)
 	// 0x1F98.5: PResActPayloadLimit_U16
 	unsigned int m_uiPresActPayloadLimit;	// required for initialisation of Pres frame (+24 bytes)
 	// 0x1F98.6: ASndMaxLatency_U32
-	DWORD m_dwAsndMaxLatency;	// const in [ns], only required for IdentRes
+	u32 m_dwAsndMaxLatency;	// const in [ns], only required for IdentRes
 	// 0x1F98.7: MultiplCycleCnt_U8
 	unsigned int m_uiMultiplCycleCnt;	// required for error detection
 	// 0x1F98.8: AsyncMTU_U16
@@ -159,42 +159,42 @@
 	// $$$ Multiplexed Slot
 
 	// 0x1C14: DLL_LossOfFrameTolerance_U32 in [ns]
-	DWORD m_dwLossOfFrameTolerance;
+	u32 m_dwLossOfFrameTolerance;
 
 	// 0x1F8A: NMT_MNCycleTiming_REC
 	// 0x1F8A.1: WaitSoCPReq_U32 in [ns]
-	DWORD m_dwWaitSocPreq;
+	u32 m_dwWaitSocPreq;
 
 	// 0x1F8A.2: AsyncSlotTimeout_U32 in [ns]
-	DWORD m_dwAsyncSlotTimeout;
+	u32 m_dwAsyncSlotTimeout;
 
 } tEplDllConfigParam;
 
 typedef struct {
 	unsigned int m_uiSizeOfStruct;
-	DWORD m_dwDeviceType;	// NMT_DeviceType_U32
-	DWORD m_dwVendorId;	// NMT_IdentityObject_REC.VendorId_U32
-	DWORD m_dwProductCode;	// NMT_IdentityObject_REC.ProductCode_U32
-	DWORD m_dwRevisionNumber;	// NMT_IdentityObject_REC.RevisionNo_U32
-	DWORD m_dwSerialNumber;	// NMT_IdentityObject_REC.SerialNo_U32
-	QWORD m_qwVendorSpecificExt1;
-	DWORD m_dwVerifyConfigurationDate;	// CFM_VerifyConfiguration_REC.ConfDate_U32
-	DWORD m_dwVerifyConfigurationTime;	// CFM_VerifyConfiguration_REC.ConfTime_U32
-	DWORD m_dwApplicationSwDate;	// PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device
-	DWORD m_dwApplicationSwTime;	// PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device
-	DWORD m_dwIpAddress;
-	DWORD m_dwSubnetMask;
-	DWORD m_dwDefaultGateway;
-	BYTE m_sHostname[32];
-	BYTE m_abVendorSpecificExt2[48];
+	u32 m_dwDeviceType;	// NMT_DeviceType_U32
+	u32 m_dwVendorId;	// NMT_IdentityObject_REC.VendorId_U32
+	u32 m_dwProductCode;	// NMT_IdentityObject_REC.ProductCode_U32
+	u32 m_dwRevisionNumber;	// NMT_IdentityObject_REC.RevisionNo_U32
+	u32 m_dwSerialNumber;	// NMT_IdentityObject_REC.SerialNo_U32
+	u64 m_qwVendorSpecificExt1;
+	u32 m_dwVerifyConfigurationDate;	// CFM_VerifyConfiguration_REC.ConfDate_U32
+	u32 m_dwVerifyConfigurationTime;	// CFM_VerifyConfiguration_REC.ConfTime_U32
+	u32 m_dwApplicationSwDate;	// PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device
+	u32 m_dwApplicationSwTime;	// PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device
+	u32 m_dwIpAddress;
+	u32 m_dwSubnetMask;
+	u32 m_dwDefaultGateway;
+	u8 m_sHostname[32];
+	u8 m_abVendorSpecificExt2[48];
 
 } tEplDllIdentParam;
 
 typedef struct {
 	unsigned int m_uiNodeId;
-	WORD m_wPreqPayloadLimit;	// object 0x1F8B: NMT_MNPReqPayloadLimitList_AU16
-	WORD m_wPresPayloadLimit;	// object 0x1F8D: NMT_PResPayloadLimitList_AU16
-	DWORD m_dwPresTimeout;	// object 0x1F92: NMT_MNCNPResTimeout_AU32
+	u16 m_wPreqPayloadLimit;	// object 0x1F8B: NMT_MNPReqPayloadLimitList_AU16
+	u16 m_wPresPayloadLimit;	// object 0x1F8D: NMT_PResPayloadLimitList_AU16
+	u32 m_dwPresTimeout;	// object 0x1F92: NMT_MNCNPResTimeout_AU32
 
 } tEplDllNodeInfo;
 
diff --git a/drivers/staging/epl/EplDllCal.h b/drivers/staging/epl/EplDllCal.h
index 2446008..70b27b1 100644
--- a/drivers/staging/epl/EplDllCal.h
+++ b/drivers/staging/epl/EplDllCal.h
@@ -112,7 +112,7 @@
 typedef struct {
 	tEplDllReqServiceId m_Service;
 	unsigned int m_uiNodeId;
-	BYTE m_bSoaFlag1;
+	u8 m_bSoaFlag1;
 
 } tEplDllCalIssueRequest;
 
diff --git a/drivers/staging/epl/EplDllk.c b/drivers/staging/epl/EplDllk.c
index 9e226410..25d2c34 100644
--- a/drivers/staging/epl/EplDllk.c
+++ b/drivers/staging/epl/EplDllk.c
@@ -121,8 +121,8 @@
 
 // TracePoint support for realtime-debugging
 #ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
+void TgtDbgPostTraceValue(u32 dwTraceValue_p);
 #define TGT_DBG_SIGNAL_TRACE_POINT(p)   TgtDbgSignalTracePoint(p)
 #define TGT_DBG_POST_TRACE_VALUE(v)     TgtDbgPostTraceValue(v)
 #else
@@ -195,12 +195,12 @@
 } tEplDllState;
 
 typedef struct {
-	BYTE m_be_abSrcMac[6];
+	u8 m_be_abSrcMac[6];
 	tEdrvTxBuffer *m_pTxBuffer;	// Buffers for Tx-Frames
 	unsigned int m_uiMaxTxFrames;
-	BYTE m_bFlag1;		// Flag 1 with EN, EC for PRes, StatusRes
-	BYTE m_bMnFlag1;	// Flag 1 with EA, ER from PReq, SoA of MN
-	BYTE m_bFlag2;		// Flag 2 with PR and RS for PRes, StatusRes, IdentRes
+	u8 m_bFlag1;		// Flag 1 with EN, EC for PRes, StatusRes
+	u8 m_bMnFlag1;	// Flag 1 with EA, ER from PReq, SoA of MN
+	u8 m_bFlag2;		// Flag 2 with PR and RS for PRes, StatusRes, IdentRes
 	tEplDllConfigParam m_DllConfigParam;
 	tEplDllIdentParam m_DllIdentParam;
 	tEplDllState m_DllState;
@@ -257,7 +257,7 @@
 
 // called by high resolution timer module to monitor EPL cycle as CN
 #if EPL_TIMER_USE_HIGHRES != FALSE
-static tEplKernel PUBLIC EplDllkCbCnTimer(tEplTimerEventArg * pEventArg_p);
+static tEplKernel EplDllkCbCnTimer(tEplTimerEventArg *pEventArg_p);
 #endif
 
 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
@@ -278,10 +278,9 @@
 					       ReqServiceId_p,
 					       unsigned int uiNodeId_p);
 
-static tEplKernel PUBLIC EplDllkCbMnTimerCycle(tEplTimerEventArg * pEventArg_p);
+static tEplKernel EplDllkCbMnTimerCycle(tEplTimerEventArg *pEventArg_p);
 
-static tEplKernel PUBLIC EplDllkCbMnTimerResponse(tEplTimerEventArg *
-						  pEventArg_p);
+static tEplKernel EplDllkCbMnTimerResponse(tEplTimerEventArg *pEventArg_p);
 
 #endif
 
@@ -514,7 +513,7 @@
 			       EPL_C_DLL_ETHERTYPE_EPL);
 		// source node ID
 		AmiSetByteToLe(&pTxFrame->m_le_bSrcNodeId,
-			       (BYTE) EplDllkInstance_g.m_DllConfigParam.
+			       (u8) EplDllkInstance_g.m_DllConfigParam.
 			       m_uiNodeId);
 		// source MAC address
 		EPL_MEMCPY(&pTxFrame->m_be_abSrcMac[0],
@@ -531,7 +530,7 @@
 				{	// IdentResponses and StatusResponses are Broadcast
 					AmiSetByteToLe(&pTxFrame->
 						       m_le_bDstNodeId,
-						       (BYTE)
+						       (u8)
 						       EPL_C_ADR_BROADCAST);
 					break;
 				}
@@ -550,10 +549,10 @@
 					  EPL_C_DLL_MULTICAST_SOC);
 			// destination node ID
 			AmiSetByteToLe(&pTxFrame->m_le_bDstNodeId,
-				       (BYTE) EPL_C_ADR_BROADCAST);
+				       (u8) EPL_C_ADR_BROADCAST);
 			// reset Flags
-			//AmiSetByteToLe(&pTxFrame->m_Data.m_Soc.m_le_bFlag1, (BYTE) 0);
-			//AmiSetByteToLe(&pTxFrame->m_Data.m_Soc.m_le_bFlag2, (BYTE) 0);
+			//AmiSetByteToLe(&pTxFrame->m_Data.m_Soc.m_le_bFlag1, (u8) 0);
+			//AmiSetByteToLe(&pTxFrame->m_Data.m_Soc.m_le_bFlag2, (u8) 0);
 			break;
 
 		case kEplMsgTypeSoa:
@@ -562,13 +561,13 @@
 					  EPL_C_DLL_MULTICAST_SOA);
 			// destination node ID
 			AmiSetByteToLe(&pTxFrame->m_le_bDstNodeId,
-				       (BYTE) EPL_C_ADR_BROADCAST);
+				       (u8) EPL_C_ADR_BROADCAST);
 			// reset Flags
-			//AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bFlag1, (BYTE) 0);
-			//AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bFlag2, (BYTE) 0);
+			//AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bFlag1, (u8) 0);
+			//AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bFlag2, (u8) 0);
 			// EPL profile version
 			AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bEplVersion,
-				       (BYTE) EPL_SPEC_VERSION);
+				       (u8) EPL_SPEC_VERSION);
 			break;
 
 		case kEplMsgTypePres:
@@ -577,18 +576,18 @@
 					  EPL_C_DLL_MULTICAST_PRES);
 			// destination node ID
 			AmiSetByteToLe(&pTxFrame->m_le_bDstNodeId,
-				       (BYTE) EPL_C_ADR_BROADCAST);
+				       (u8) EPL_C_ADR_BROADCAST);
 			// reset Flags
-			//AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag1, (BYTE) 0);
-			//AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag2, (BYTE) 0);
+			//AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag1, (u8) 0);
+			//AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag2, (u8) 0);
 			// PDO size
 			//AmiSetWordToLe(&pTxFrame->m_Data.m_Pres.m_le_wSize, 0);
 			break;
 
 		case kEplMsgTypePreq:
 			// reset Flags
-			//AmiSetByteToLe(&pTxFrame->m_Data.m_Preq.m_le_bFlag1, (BYTE) 0);
-			//AmiSetByteToLe(&pTxFrame->m_Data.m_Preq.m_le_bFlag2, (BYTE) 0);
+			//AmiSetByteToLe(&pTxFrame->m_Data.m_Preq.m_le_bFlag1, (u8) 0);
+			//AmiSetByteToLe(&pTxFrame->m_Data.m_Preq.m_le_bFlag2, (u8) 0);
 			// PDO size
 			//AmiSetWordToLe(&pTxFrame->m_Data.m_Preq.m_le_wSize, 0);
 			break;
@@ -597,7 +596,7 @@
 			break;
 		}
 		// EPL message type
-		AmiSetByteToLe(&pTxFrame->m_le_bMessageType, (BYTE) MsgType_p);
+		AmiSetByteToLe(&pTxFrame->m_le_bMessageType, (u8) MsgType_p);
 	}
 
 	*ppFrame_p = pTxFrame;
@@ -673,7 +672,7 @@
 	tEdrvTxBuffer *pTxBuffer;
 	unsigned int uiHandle;
 	unsigned int uiFrameSize;
-	BYTE abMulticastMac[6];
+	u8 abMulticastMac[6];
 	tEplDllAsyncReqPriority AsyncReqPriority;
 	unsigned int uiFrameCount;
 	tEplNmtState NmtState;
@@ -712,7 +711,7 @@
 			// EPL profile version
 			AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
 				       m_IdentResponse.m_le_bEplProfileVersion,
-				       (BYTE) EPL_SPEC_VERSION);
+				       (u8) EPL_SPEC_VERSION);
 			// FeatureFlags
 			AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
 					m_IdentResponse.m_le_dwFeatureFlags,
@@ -721,18 +720,18 @@
 			// MTU
 			AmiSetWordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
 				       m_IdentResponse.m_le_wMtu,
-				       (WORD) EplDllkInstance_g.
+				       (u16) EplDllkInstance_g.
 				       m_DllConfigParam.m_uiAsyncMtu);
 			// PollInSize
 			AmiSetWordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
 				       m_IdentResponse.m_le_wPollInSize,
-				       (WORD) EplDllkInstance_g.
+				       (u16) EplDllkInstance_g.
 				       m_DllConfigParam.
 				       m_uiPreqActPayloadLimit);
 			// PollOutSize
 			AmiSetWordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
 				       m_IdentResponse.m_le_wPollOutSize,
-				       (WORD) EplDllkInstance_g.
+				       (u16) EplDllkInstance_g.
 				       m_DllConfigParam.
 				       m_uiPresActPayloadLimit);
 			// ResponseTime / PresMaxLatency
@@ -936,7 +935,7 @@
 //                    EplDllkInstance_g.m_aNodeInfo[uiIndex].m_uiNodeId = uiIndex + 1;
 					EplDllkInstance_g.m_aNodeInfo[uiIndex].
 					    m_wPresPayloadLimit =
-					    (WORD) EplDllkInstance_g.
+					    (u16) EplDllkInstance_g.
 					    m_DllConfigParam.
 					    m_uiIsochrRxMaxPayload;
 				}
@@ -1233,7 +1232,7 @@
 				}
 				if (uiFrameCount > 0) {
 					EplDllkInstance_g.m_bFlag2 =
-					    (BYTE) (((AsyncReqPriority <<
+					    (u8) (((AsyncReqPriority <<
 						      EPL_FRAME_FLAG2_PR_SHIFT)
 						     & EPL_FRAME_FLAG2_PR)
 						    | (uiFrameCount &
@@ -1307,7 +1306,7 @@
 					}
 					AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
 						       m_le_bNmtStatus,
-						       (BYTE) NmtState);
+						       (u8) NmtState);
 					AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
 						       m_le_bFlag2,
 						       EplDllkInstance_g.
@@ -1533,7 +1532,7 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel EplDllkSetFlag1OfNode(unsigned int uiNodeId_p, BYTE bSoaFlag1_p)
+tEplKernel EplDllkSetFlag1OfNode(unsigned int uiNodeId_p, u8 bSoaFlag1_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 	tEplDllkNodeInfo *pNodeInfo;
@@ -1664,7 +1663,7 @@
 		pIntNodeInfo->m_pPreqTxBuffer =
 		    &EplDllkInstance_g.m_pTxBuffer[uiHandle];
 		AmiSetByteToLe(&pFrame->m_le_bDstNodeId,
-			       (BYTE) pNodeInfo_p->m_uiNodeId);
+			       (u8) pNodeInfo_p->m_uiNodeId);
 
 		// set up destination MAC address
 		EPL_MEMCPY(pFrame->m_be_abDstMac, pIntNodeInfo->m_be_abMacAddr,
@@ -2431,7 +2430,7 @@
 	tEplDllReqServiceId ReqServiceId;
 	unsigned int uiAsndServiceId;
 	unsigned int uiNodeId;
-	BYTE bFlag1;
+	u8 bFlag1;
 
 	BENCHMARK_MOD_02_SET(3);
 	NmtState = EplNmtkGetNmtState();
@@ -2466,7 +2465,7 @@
 					// update frame (NMT state, RD, RS, PR, MS, EN flags)
 					AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
 						       m_le_bNmtStatus,
-						       (BYTE) NmtState);
+						       (u8) NmtState);
 					AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
 						       m_le_bFlag2,
 						       EplDllkInstance_g.
@@ -2541,7 +2540,7 @@
 					// update frame (NMT state, RD, RS, PR, MS, EN flags)
 					AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
 						       m_le_bNmtStatus,
-						       (BYTE) NmtState);
+						       (u8) NmtState);
 					AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
 						       m_le_bFlag2,
 						       EplDllkInstance_g.
@@ -2803,7 +2802,7 @@
 				}
 				AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
 					       m_le_bNmtStatus,
-					       (BYTE) NmtState);
+					       (u8) NmtState);
 				AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
 					       m_le_bFlag2,
 					       EplDllkInstance_g.m_bFlag2);
@@ -2888,7 +2887,7 @@
 							       m_Payload.
 							       m_StatusResponse.
 							       m_le_bNmtStatus,
-							       (BYTE) NmtState);
+							       (u8) NmtState);
 						AmiSetByteToLe(&pTxFrame->
 							       m_Data.m_Asnd.
 							       m_Payload.
@@ -2954,7 +2953,7 @@
 							       m_Payload.
 							       m_IdentResponse.
 							       m_le_bNmtStatus,
-							       (BYTE) NmtState);
+							       (u8) NmtState);
 						AmiSetByteToLe(&pTxFrame->
 							       m_Data.m_Asnd.
 							       m_Payload.
@@ -3155,7 +3154,7 @@
 
       Exit:
 	if (Ret != kEplSuccessful) {
-		DWORD dwArg;
+		u32 dwArg;
 
 		BENCHMARK_MOD_02_TOGGLE(9);
 
@@ -3286,7 +3285,7 @@
 						       m_Payload.
 						       m_StatusResponse.
 						       m_le_bNmtStatus,
-						       (BYTE) NmtState);
+						       (u8) NmtState);
 					AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.
 						       m_Payload.
 						       m_StatusResponse.
@@ -3322,7 +3321,7 @@
 						       m_Payload.
 						       m_IdentResponse.
 						       m_le_bNmtStatus,
-						       (BYTE) NmtState);
+						       (u8) NmtState);
 					AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.
 						       m_Payload.
 						       m_IdentResponse.
@@ -3362,12 +3361,12 @@
 						if ((AmiGetByteFromLe
 						     (&pTxFrame->
 						      m_le_bMessageType)
-						     == (BYTE) kEplMsgTypeAsnd)
+						     == (u8) kEplMsgTypeAsnd)
 						    &&
 						    (AmiGetByteFromLe
 						     (&pTxFrame->m_Data.m_Asnd.
 						      m_le_bServiceId)
-						     == (BYTE) kEplDllAsndNmtCommand)) {	// post event directly to NmtMnu module
+						     == (u8) kEplDllAsndNmtCommand)) {	// post event directly to NmtMnu module
 							Event.m_EventSink =
 							    kEplEventSinkNmtMnu;
 							Event.m_EventType =
@@ -3449,7 +3448,7 @@
 
       Exit:
 	if (Ret != kEplSuccessful) {
-		DWORD dwArg;
+		u32 dwArg;
 
 		BENCHMARK_MOD_02_TOGGLE(9);
 
@@ -3485,7 +3484,7 @@
 				    unsigned int uiFrameSize_p)
 {
 	tEplMsgType MsgType;
-	WORD wEtherType;
+	u16 wEtherType;
 
 	// check frame
 	if (pFrame_p != NULL) {
@@ -3506,7 +3505,7 @@
 		if (wEtherType == EPL_C_DLL_ETHERTYPE_EPL) {
 			// source node ID
 			AmiSetByteToLe(&pFrame_p->m_le_bSrcNodeId,
-				       (BYTE) EplDllkInstance_g.
+				       (u8) EplDllkInstance_g.
 				       m_DllConfigParam.m_uiNodeId);
 
 			// check message type
@@ -3515,7 +3514,7 @@
 			if (MsgType == 0) {
 				MsgType = kEplMsgTypeAsnd;
 				AmiSetByteToLe(&pFrame_p->m_le_bMessageType,
-					       (BYTE) MsgType);
+					       (u8) MsgType);
 			}
 
 			if (MsgType == kEplMsgTypeAsnd) {
@@ -3546,7 +3545,7 @@
 //---------------------------------------------------------------------------
 
 #if EPL_TIMER_USE_HIGHRES != FALSE
-static tEplKernel PUBLIC EplDllkCbCnTimer(tEplTimerEventArg * pEventArg_p)
+static tEplKernel EplDllkCbCnTimer(tEplTimerEventArg *pEventArg_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 	tEplNmtState NmtState;
@@ -3583,7 +3582,7 @@
 
       Exit:
 	if (Ret != kEplSuccessful) {
-		DWORD dwArg;
+		u32 dwArg;
 
 		BENCHMARK_MOD_02_TOGGLE(9);
 
@@ -3617,7 +3616,7 @@
 //
 //---------------------------------------------------------------------------
 
-static tEplKernel PUBLIC EplDllkCbMnTimerCycle(tEplTimerEventArg * pEventArg_p)
+static tEplKernel EplDllkCbMnTimerCycle(tEplTimerEventArg *pEventArg_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 	tEplNmtState NmtState;
@@ -3639,7 +3638,7 @@
 
       Exit:
 	if (Ret != kEplSuccessful) {
-		DWORD dwArg;
+		u32 dwArg;
 
 		BENCHMARK_MOD_02_TOGGLE(9);
 
@@ -3670,8 +3669,7 @@
 //
 //---------------------------------------------------------------------------
 
-static tEplKernel PUBLIC EplDllkCbMnTimerResponse(tEplTimerEventArg *
-						  pEventArg_p)
+static tEplKernel EplDllkCbMnTimerResponse(tEplTimerEventArg *pEventArg_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 	tEplNmtState NmtState;
@@ -3693,7 +3691,7 @@
 
       Exit:
 	if (Ret != kEplSuccessful) {
-		DWORD dwArg;
+		u32 dwArg;
 
 		BENCHMARK_MOD_02_TOGGLE(9);
 
@@ -3827,24 +3825,24 @@
 			// update frame (target)
 			AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.
 				       m_le_bReqServiceId,
-				       (BYTE) EplDllkInstance_g.
+				       (u8) EplDllkInstance_g.
 				       m_LastReqServiceId);
 			AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.
 				       m_le_bReqServiceTarget,
-				       (BYTE) EplDllkInstance_g.
+				       (u8) EplDllkInstance_g.
 				       m_uiLastTargetNodeId);
 
 		} else {	// invite nobody
 			// update frame (target)
 			AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.
-				       m_le_bReqServiceId, (BYTE) 0);
+				       m_le_bReqServiceId, (u8) 0);
 			AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.
-				       m_le_bReqServiceTarget, (BYTE) 0);
+				       m_le_bReqServiceTarget, (u8) 0);
 		}
 
 		// update frame (NMT state)
 		AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bNmtStatus,
-			       (BYTE) NmtState_p);
+			       (u8) NmtState_p);
 
 		// send SoA frame
 		Ret = EdrvSendTxMsg(pTxBuffer);
@@ -3921,7 +3919,7 @@
 	tEplKernel Ret = kEplSuccessful;
 	tEdrvTxBuffer *pTxBuffer = NULL;
 	tEplFrame *pTxFrame;
-	BYTE bFlag1 = 0;
+	u8 bFlag1 = 0;
 
 	if (EplDllkInstance_g.m_pCurNodeInfo == NULL) {	// start with first isochronous CN
 		EplDllkInstance_g.m_pCurNodeInfo =
@@ -3972,7 +3970,7 @@
 		if (pTxBuffer == &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES]) {	// PRes of MN will be sent
 			// update NMT state
 			AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bNmtStatus,
-				       (BYTE) NmtState_p);
+				       (u8) NmtState_p);
 			*pDllStateProposed_p = kEplDllMsWaitSoaTrig;
 		}
 		// $$$ d.k. set EPL_FRAME_FLAG1_MS if necessary
@@ -4015,7 +4013,7 @@
 					       unsigned int uiNodeId_p)
 {
 	tEplKernel Ret = kEplSuccessful;
-	BYTE abBuffer[18];
+	u8 abBuffer[18];
 	tEplFrame *pFrame = (tEplFrame *) abBuffer;
 	tEplFrameInfo FrameInfo;
 
@@ -4026,13 +4024,13 @@
 		// ASnd service registered?
 		if (EplDllkInstance_g.m_aAsndFilter[ReqServiceId_p] == kEplDllAsndFilterAny) {	// ASnd service ID is registered
 			AmiSetByteToLe(&pFrame->m_le_bSrcNodeId,
-				       (BYTE) uiNodeId_p);
+				       (u8) uiNodeId_p);
 			// EPL MsgType ASnd
 			AmiSetByteToLe(&pFrame->m_le_bMessageType,
-				       (BYTE) kEplMsgTypeAsnd);
+				       (u8) kEplMsgTypeAsnd);
 			// ASnd Service ID
 			AmiSetByteToLe(&pFrame->m_Data.m_Asnd.m_le_bServiceId,
-				       (BYTE) ReqServiceId_p);
+				       (u8) ReqServiceId_p);
 			// create frame info structure
 			FrameInfo.m_pFrame = pFrame;
 			FrameInfo.m_uiFrameSize = 18;	// empty non existing ASnd frame
diff --git a/drivers/staging/epl/EplDllkCal.c b/drivers/staging/epl/EplDllkCal.c
index 359083e..0e283d5 100644
--- a/drivers/staging/epl/EplDllkCal.c
+++ b/drivers/staging/epl/EplDllkCal.c
@@ -142,9 +142,9 @@
 	tShbInstance m_ShbInstanceTxGen;	// FIFO for Tx frames with generic priority
 #else
 	unsigned int m_uiFrameSizeNmt;
-	BYTE m_abFrameNmt[1500];
+	u8 m_abFrameNmt[1500];
 	unsigned int m_uiFrameSizeGen;
-	BYTE m_abFrameGen[1500];
+	u8 m_abFrameGen[1500];
 #endif
 
 	tEplDllkCalStatistics m_Statistics;
@@ -202,7 +202,7 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel EplDllkCalAddInstance()
+tEplKernel EplDllkCalAddInstance(void)
 {
 	tEplKernel Ret = kEplSuccessful;
 #ifndef EPL_NO_FIFO
@@ -279,7 +279,7 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel EplDllkCalDelInstance()
+tEplKernel EplDllkCalDelInstance(void)
 {
 	tEplKernel Ret = kEplSuccessful;
 #ifndef EPL_NO_FIFO
@@ -536,7 +536,7 @@
 	case kEplDllAsyncReqPrioNmt:	// NMT request priority
 		ShbError =
 		    ShbCirReadDataBlock(EplDllkCalInstance_g.m_ShbInstanceTxNmt,
-					(BYTE *) pFrame_p, *puiFrameSize_p,
+					(u8 *) pFrame_p, *puiFrameSize_p,
 					&ulFrameSize);
 		// returns kShbOk, kShbDataTruncated, kShbInvalidArg, kShbNoReadableData
 		break;
@@ -544,7 +544,7 @@
 	default:		// generic priority
 		ShbError =
 		    ShbCirReadDataBlock(EplDllkCalInstance_g.m_ShbInstanceTxGen,
-					(BYTE *) pFrame_p, *puiFrameSize_p,
+					(u8 *) pFrame_p, *puiFrameSize_p,
 					&ulFrameSize);
 		// returns kShbOk, kShbDataTruncated, kShbInvalidArg, kShbNoReadableData
 		break;
@@ -876,7 +876,7 @@
 //---------------------------------------------------------------------------
 
 tEplKernel EplDllkCalIssueRequest(tEplDllReqServiceId Service_p,
-				  unsigned int uiNodeId_p, BYTE bSoaFlag1_p)
+				  unsigned int uiNodeId_p, u8 bSoaFlag1_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 
diff --git a/drivers/staging/epl/EplDlluCal.c b/drivers/staging/epl/EplDlluCal.c
index 7f4a174..f96fe84 100644
--- a/drivers/staging/epl/EplDlluCal.c
+++ b/drivers/staging/epl/EplDlluCal.c
@@ -173,7 +173,7 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel EplDlluCalAddInstance()
+tEplKernel EplDlluCalAddInstance(void)
 {
 	tEplKernel Ret = kEplSuccessful;
 
@@ -198,7 +198,7 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel EplDlluCalDelInstance()
+tEplKernel EplDlluCalDelInstance(void)
 {
 	tEplKernel Ret = kEplSuccessful;
 
@@ -355,7 +355,7 @@
 //---------------------------------------------------------------------------
 
 tEplKernel EplDlluCalIssueRequest(tEplDllReqServiceId Service_p,
-				  unsigned int uiNodeId_p, BYTE bSoaFlag1_p)
+				  unsigned int uiNodeId_p, u8 bSoaFlag1_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 
diff --git a/drivers/staging/epl/EplErrorHandlerk.c b/drivers/staging/epl/EplErrorHandlerk.c
index d12521f..6baed04 100644
--- a/drivers/staging/epl/EplErrorHandlerk.c
+++ b/drivers/staging/epl/EplErrorHandlerk.c
@@ -97,9 +97,9 @@
 //---------------------------------------------------------------------------
 
 typedef struct {
-	DWORD m_dwCumulativeCnt;	// subindex 1
-	DWORD m_dwThresholdCnt;	// subindex 2
-	DWORD m_dwThreshold;	// subindex 3
+	u32 m_dwCumulativeCnt;	// subindex 1
+	u32 m_dwThresholdCnt;	// subindex 2
+	u32 m_dwThreshold;	// subindex 3
 
 } tEplErrorHandlerkErrorCounter;
 
@@ -112,9 +112,9 @@
 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
 	tEplErrorHandlerkErrorCounter m_MnCrcErr;	// object 0x1C00
 	tEplErrorHandlerkErrorCounter m_MnCycTimeExceed;	// object 0x1C02
-	DWORD m_adwMnCnLossPresCumCnt[254];	// object 0x1C07
-	DWORD m_adwMnCnLossPresThrCnt[254];	// object 0x1C08
-	DWORD m_adwMnCnLossPresThreshold[254];	// object 0x1C09
+	u32 m_adwMnCnLossPresCumCnt[254];	// object 0x1C07
+	u32 m_adwMnCnLossPresThrCnt[254];	// object 0x1C08
+	u32 m_adwMnCnLossPresThreshold[254];	// object 0x1C09
 	BOOL m_afMnCnLossPresEvent[254];
 #endif
 
@@ -135,7 +135,7 @@
 						   unsigned int uiIndex_p);
 
 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-static tEplKernel EplErrorHandlerkLinkArray(DWORD * pdwValue_p,
+static tEplKernel EplErrorHandlerkLinkArray(u32 * pdwValue_p,
 					    unsigned int uiValueCount_p,
 					    unsigned int uiIndex_p);
 #endif
@@ -176,7 +176,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplErrorHandlerkInit(void)
+tEplKernel EplErrorHandlerkInit(void)
 {
 	tEplKernel Ret;
 
@@ -203,7 +203,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplErrorHandlerkAddInstance(void)
+tEplKernel EplErrorHandlerkAddInstance(void)
 {
 	tEplKernel Ret;
 
@@ -306,7 +306,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplErrorHandlerkDelInstance()
+tEplKernel EplErrorHandlerkDelInstance(void)
 {
 	tEplKernel Ret;
 
@@ -333,7 +333,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplErrorHandlerkProcess(tEplEvent * pEvent_p)
+tEplKernel EplErrorHandlerkProcess(tEplEvent *pEvent_p)
 {
 	tEplKernel Ret;
 	unsigned long ulDllErrorEvents;
@@ -713,7 +713,7 @@
 	tEplVarParam VarParam;
 
 	VarParam.m_pData = &pErrorCounter_p->m_dwCumulativeCnt;
-	VarParam.m_Size = sizeof(DWORD);
+	VarParam.m_Size = sizeof(u32);
 	VarParam.m_uiIndex = uiIndex_p;
 	VarParam.m_uiSubindex = 0x01;
 	VarParam.m_ValidFlag = kVarValidAll;
@@ -723,7 +723,7 @@
 	}
 
 	VarParam.m_pData = &pErrorCounter_p->m_dwThresholdCnt;
-	VarParam.m_Size = sizeof(DWORD);
+	VarParam.m_Size = sizeof(u32);
 	VarParam.m_uiIndex = uiIndex_p;
 	VarParam.m_uiSubindex = 0x02;
 	VarParam.m_ValidFlag = kVarValidAll;
@@ -733,7 +733,7 @@
 	}
 
 	VarParam.m_pData = &pErrorCounter_p->m_dwThreshold;
-	VarParam.m_Size = sizeof(DWORD);
+	VarParam.m_Size = sizeof(u32);
 	VarParam.m_uiIndex = uiIndex_p;
 	VarParam.m_uiSubindex = 0x03;
 	VarParam.m_ValidFlag = kVarValidAll;
@@ -763,18 +763,18 @@
 //---------------------------------------------------------------------------
 
 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-static tEplKernel EplErrorHandlerkLinkArray(DWORD * pdwValue_p,
+static tEplKernel EplErrorHandlerkLinkArray(u32 * pdwValue_p,
 					    unsigned int uiValueCount_p,
 					    unsigned int uiIndex_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 	tEplVarParam VarParam;
 	tEplObdSize EntrySize;
-	BYTE bIndexEntries;
+	u8 bIndexEntries;
 
 	EntrySize = (tEplObdSize) sizeof(bIndexEntries);
 	Ret = EplObdReadEntry(uiIndex_p,
-			      0x00, (void GENERIC *)&bIndexEntries, &EntrySize);
+			      0x00, (void *)&bIndexEntries, &EntrySize);
 
 	if ((Ret != kEplSuccessful) || (bIndexEntries == 0x00)) {
 		// Object doesn't exist or invalid entry number
@@ -786,7 +786,7 @@
 		uiValueCount_p = bIndexEntries;
 	}
 
-	VarParam.m_Size = sizeof(DWORD);
+	VarParam.m_Size = sizeof(u32);
 	VarParam.m_uiIndex = uiIndex_p;
 	VarParam.m_ValidFlag = kVarValidAll;
 
diff --git a/drivers/staging/epl/EplEvent.h b/drivers/staging/epl/EplEvent.h
index b6dc1b9..910bd69 100644
--- a/drivers/staging/epl/EplEvent.h
+++ b/drivers/staging/epl/EplEvent.h
@@ -248,8 +248,8 @@
 	tEplEventSource m_EventSource;	// module which posted this error event
 	tEplKernel m_EplError;	// EPL error which occured
 	union {
-		BYTE m_bArg;
-		DWORD m_dwArg;
+		u8 m_bArg;
+		u32 m_dwArg;
 		tEplEventSource m_EventSource;	// from Eventk/u module (originating error source)
 		tEplEventObdError m_ObdError;	// from Obd module
 //        tEplErrHistoryEntry     m_HistoryEntry; // from Nmtk/u module
@@ -267,10 +267,10 @@
 } tEplErrorHandlerkEvent;
 
 // callback function to get informed about sync event
-typedef tEplKernel(PUBLIC * tEplSyncCb) (void);
+typedef tEplKernel(*tEplSyncCb) (void);
 
 // callback function for generic events
-typedef tEplKernel(PUBLIC * tEplProcessEventCb) (tEplEvent * pEplEvent_p);
+typedef tEplKernel(*tEplProcessEventCb) (tEplEvent *pEplEvent_p);
 
 //---------------------------------------------------------------------------
 // function prototypes
diff --git a/drivers/staging/epl/EplEventk.c b/drivers/staging/epl/EplEventk.c
index 8068a6c..ef36815 100644
--- a/drivers/staging/epl/EplEventk.c
+++ b/drivers/staging/epl/EplEventk.c
@@ -100,8 +100,8 @@
 
 // TracePoint support for realtime-debugging
 #ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
+void TgtDbgPostTraceValue(u32 dwTraceValue_p);
 #define TGT_DBG_SIGNAL_TRACE_POINT(p)   TgtDbgSignalTracePoint(p)
 #define TGT_DBG_POST_TRACE_VALUE(v)     TgtDbgPostTraceValue(v)
 #else
@@ -172,7 +172,7 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplEventkInit(tEplSyncCb pfnCbSync_p)
+tEplKernel EplEventkInit(tEplSyncCb pfnCbSync_p)
 {
 	tEplKernel Ret;
 
@@ -196,7 +196,7 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplEventkAddInstance(tEplSyncCb pfnCbSync_p)
+tEplKernel EplEventkAddInstance(tEplSyncCb pfnCbSync_p)
 {
 	tEplKernel Ret;
 #ifndef EPL_NO_FIFO
@@ -275,7 +275,7 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplEventkDelInstance()
+tEplKernel EplEventkDelInstance(void)
 {
 	tEplKernel Ret;
 #ifndef EPL_NO_FIFO
@@ -339,7 +339,7 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplEventkProcess(tEplEvent * pEvent_p)
+tEplKernel EplEventkProcess(tEplEvent *pEvent_p)
 {
 	tEplKernel Ret;
 	tEplEventSource EventSource;
@@ -562,7 +562,7 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplEventkPost(tEplEvent * pEvent_p)
+tEplKernel EplEventkPost(tEplEvent *pEvent_p)
 {
 	tEplKernel Ret;
 #ifndef EPL_NO_FIFO
@@ -755,12 +755,12 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplEventkPostError(tEplEventSource EventSource_p,
-				     tEplKernel EplError_p,
-				     unsigned int uiArgSize_p, void *pArg_p)
+tEplKernel EplEventkPostError(tEplEventSource EventSource_p,
+			      tEplKernel EplError_p,
+			      unsigned int uiArgSize_p, void *pArg_p)
 {
 	tEplKernel Ret;
-	BYTE abBuffer[EPL_MAX_EVENT_ARG_SIZE];
+	u8 abBuffer[EPL_MAX_EVENT_ARG_SIZE];
 	tEplEventError *pEventError = (tEplEventError *) abBuffer;
 	tEplEvent EplEvent;
 
@@ -814,7 +814,7 @@
 	tShbError ShbError;
 //unsigned long   ulBlockCount;
 //unsigned long   ulDataSize;
-	BYTE abDataBuffer[sizeof(tEplEvent) + EPL_MAX_EVENT_ARG_SIZE];
+	u8 abDataBuffer[sizeof(tEplEvent) + EPL_MAX_EVENT_ARG_SIZE];
 	// d.k.: abDataBuffer contains the complete tEplEvent structure
 	//       and behind this the argument
 
diff --git a/drivers/staging/epl/EplEventu.c b/drivers/staging/epl/EplEventu.c
index 815f9a8..3ae2841 100644
--- a/drivers/staging/epl/EplEventu.c
+++ b/drivers/staging/epl/EplEventu.c
@@ -96,8 +96,8 @@
 
 // TracePoint support for realtime-debugging
 #ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
+void TgtDbgPostTraceValue(u32 dwTraceValue_p);
 #define TGT_DBG_SIGNAL_TRACE_POINT(p)   TgtDbgSignalTracePoint(p)
 #define TGT_DBG_POST_TRACE_VALUE(v)     TgtDbgPostTraceValue(v)
 #else
@@ -172,7 +172,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventuInit(tEplProcessEventCb pfnApiProcessEventCb_p)
+tEplKernel EplEventuInit(tEplProcessEventCb pfnApiProcessEventCb_p)
 {
 	tEplKernel Ret;
 
@@ -199,8 +199,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventuAddInstance(tEplProcessEventCb
-				       pfnApiProcessEventCb_p)
+tEplKernel EplEventuAddInstance(tEplProcessEventCb pfnApiProcessEventCb_p)
 {
 	tEplKernel Ret;
 #ifndef EPL_NO_FIFO
@@ -280,7 +279,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventuDelInstance()
+tEplKernel EplEventuDelInstance(void)
 {
 	tEplKernel Ret;
 #ifndef EPL_NO_FIFO
@@ -348,7 +347,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventuProcess(tEplEvent * pEvent_p)
+tEplKernel EplEventuProcess(tEplEvent *pEvent_p)
 {
 	tEplKernel Ret;
 	tEplEventSource EventSource;
@@ -515,7 +514,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventuPost(tEplEvent * pEvent_p)
+tEplKernel EplEventuPost(tEplEvent *pEvent_p)
 {
 	tEplKernel Ret;
 #ifndef EPL_NO_FIFO
@@ -689,12 +688,12 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventuPostError(tEplEventSource EventSource_p,
-				     tEplKernel EplError_p,
-				     unsigned int uiArgSize_p, void *pArg_p)
+tEplKernel EplEventuPostError(tEplEventSource EventSource_p,
+			      tEplKernel EplError_p,
+			      unsigned int uiArgSize_p, void *pArg_p)
 {
 	tEplKernel Ret;
-	BYTE abBuffer[EPL_MAX_EVENT_ARG_SIZE];
+	u8 abBuffer[EPL_MAX_EVENT_ARG_SIZE];
 	tEplEventError *pEventError = (tEplEventError *) abBuffer;
 	tEplEvent EplEvent;
 
@@ -751,7 +750,7 @@
 	tShbError ShbError;
 //unsigned long   ulBlockCount;
 //unsigned long   ulDataSize;
-	BYTE abDataBuffer[sizeof(tEplEvent) + EPL_MAX_EVENT_ARG_SIZE];
+	u8 abDataBuffer[sizeof(tEplEvent) + EPL_MAX_EVENT_ARG_SIZE];
 	// d.k.: abDataBuffer contains the complete tEplEvent structure
 	//       and behind this the argument
 
diff --git a/drivers/staging/epl/EplFrame.h b/drivers/staging/epl/EplFrame.h
index 9a7f8b9..ba1ae9e 100644
--- a/drivers/staging/epl/EplFrame.h
+++ b/drivers/staging/epl/EplFrame.h
@@ -122,155 +122,155 @@
 
 typedef struct {
 	// Offset 17
-	BYTE m_le_bRes1;	// reserved
+	u8 m_le_bRes1;	// reserved
 	// Offset 18
-	BYTE m_le_bFlag1;	// Flags: MC, PS
+	u8 m_le_bFlag1;	// Flags: MC, PS
 	// Offset 19
-	BYTE m_le_bFlag2;	// Flags: res
+	u8 m_le_bFlag2;	// Flags: res
 	// Offset 20
 	tEplNetTime m_le_NetTime;	// supported if D_NMT_NetTimeIsRealTime_BOOL is set
 	// Offset 28
-	QWORD m_le_RelativeTime;	// in us (supported if D_NMT_RelativeTime_BOOL is set)
+	u64 m_le_RelativeTime;	// in us (supported if D_NMT_RelativeTime_BOOL is set)
 
 } PACK_STRUCT tEplSocFrame;
 
 typedef struct {
 	// Offset 17
-	BYTE m_le_bRes1;	// reserved
+	u8 m_le_bRes1;	// reserved
 	// Offset 18
-	BYTE m_le_bFlag1;	// Flags: MS, EA, RD
+	u8 m_le_bFlag1;	// Flags: MS, EA, RD
 	// Offset 19
-	BYTE m_le_bFlag2;	// Flags: res
+	u8 m_le_bFlag2;	// Flags: res
 	// Offset 20
-	BYTE m_le_bPdoVersion;
+	u8 m_le_bPdoVersion;
 	// Offset 21
-	BYTE m_le_bRes2;	// reserved
+	u8 m_le_bRes2;	// reserved
 	// Offset 22
-	WORD m_le_wSize;
+	u16 m_le_wSize;
 	// Offset 24
-	BYTE m_le_abPayload[256 /*D_NMT_IsochrRxMaxPayload_U16 */ ];
+	u8 m_le_abPayload[256 /*D_NMT_IsochrRxMaxPayload_U16 */ ];
 
 } PACK_STRUCT tEplPreqFrame;
 
 typedef struct {
 	// Offset 17
-	BYTE m_le_bNmtStatus;	// NMT state
+	u8 m_le_bNmtStatus;	// NMT state
 	// Offset 18
-	BYTE m_le_bFlag1;	// Flags: MS, EN, RD
+	u8 m_le_bFlag1;	// Flags: MS, EN, RD
 	// Offset 19
-	BYTE m_le_bFlag2;	// Flags: PR, RS
+	u8 m_le_bFlag2;	// Flags: PR, RS
 	// Offset 20
-	BYTE m_le_bPdoVersion;
+	u8 m_le_bPdoVersion;
 	// Offset 21
-	BYTE m_le_bRes2;	// reserved
+	u8 m_le_bRes2;	// reserved
 	// Offset 22
-	WORD m_le_wSize;
+	u16 m_le_wSize;
 	// Offset 24
-	BYTE m_le_abPayload[256	/*D_NMT_IsochrRxMaxPayload_U16
+	u8 m_le_abPayload[256	/*D_NMT_IsochrRxMaxPayload_U16
 				   / D_NMT_IsochrTxMaxPayload_U16 */ ];
 
 } PACK_STRUCT tEplPresFrame;
 
 typedef struct {
 	// Offset 17
-	BYTE m_le_bNmtStatus;	// NMT state
+	u8 m_le_bNmtStatus;	// NMT state
 	// Offset 18
-	BYTE m_le_bFlag1;	// Flags: EA, ER
+	u8 m_le_bFlag1;	// Flags: EA, ER
 	// Offset 19
-	BYTE m_le_bFlag2;	// Flags: res
+	u8 m_le_bFlag2;	// Flags: res
 	// Offset 20
-	BYTE m_le_bReqServiceId;
+	u8 m_le_bReqServiceId;
 	// Offset 21
-	BYTE m_le_bReqServiceTarget;
+	u8 m_le_bReqServiceTarget;
 	// Offset 22
-	BYTE m_le_bEplVersion;
+	u8 m_le_bEplVersion;
 
 } PACK_STRUCT tEplSoaFrame;
 
 typedef struct {
-	WORD m_wEntryType;
-	WORD m_wErrorCode;
+	u16 m_wEntryType;
+	u16 m_wErrorCode;
 	tEplNetTime m_TimeStamp;
-	BYTE m_abAddInfo[8];
+	u8 m_abAddInfo[8];
 
 } PACK_STRUCT tEplErrHistoryEntry;
 
 typedef struct {
 	// Offset 18
-	BYTE m_le_bFlag1;	// Flags: EN, EC
-	BYTE m_le_bFlag2;	// Flags: PR, RS
-	BYTE m_le_bNmtStatus;	// NMT state
-	BYTE m_le_bRes1[3];
-	QWORD m_le_qwStaticError;	// static error bit field
+	u8 m_le_bFlag1;	// Flags: EN, EC
+	u8 m_le_bFlag2;	// Flags: PR, RS
+	u8 m_le_bNmtStatus;	// NMT state
+	u8 m_le_bRes1[3];
+	u64 m_le_qwStaticError;	// static error bit field
 	tEplErrHistoryEntry m_le_aErrHistoryEntry[14];
 
 } PACK_STRUCT tEplStatusResponse;
 
 typedef struct {
 	// Offset 18
-	BYTE m_le_bFlag1;	// Flags: res
-	BYTE m_le_bFlag2;	// Flags: PR, RS
-	BYTE m_le_bNmtStatus;	// NMT state
-	BYTE m_le_bIdentRespFlags;	// Flags: FW
-	BYTE m_le_bEplProfileVersion;
-	BYTE m_le_bRes1;
-	DWORD m_le_dwFeatureFlags;	// NMT_FeatureFlags_U32
-	WORD m_le_wMtu;		// NMT_CycleTiming_REC.AsyncMTU_U16: C_IP_MIN_MTU - C_IP_MAX_MTU
-	WORD m_le_wPollInSize;	// NMT_CycleTiming_REC.PReqActPayload_U16
-	WORD m_le_wPollOutSize;	// NMT_CycleTiming_REC.PResActPayload_U16
-	DWORD m_le_dwResponseTime;	// NMT_CycleTiming_REC.PResMaxLatency_U32
-	WORD m_le_wRes2;
-	DWORD m_le_dwDeviceType;	// NMT_DeviceType_U32
-	DWORD m_le_dwVendorId;	// NMT_IdentityObject_REC.VendorId_U32
-	DWORD m_le_dwProductCode;	// NMT_IdentityObject_REC.ProductCode_U32
-	DWORD m_le_dwRevisionNumber;	// NMT_IdentityObject_REC.RevisionNo_U32
-	DWORD m_le_dwSerialNumber;	// NMT_IdentityObject_REC.SerialNo_U32
-	QWORD m_le_qwVendorSpecificExt1;
-	DWORD m_le_dwVerifyConfigurationDate;	// CFM_VerifyConfiguration_REC.ConfDate_U32
-	DWORD m_le_dwVerifyConfigurationTime;	// CFM_VerifyConfiguration_REC.ConfTime_U32
-	DWORD m_le_dwApplicationSwDate;	// PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device
-	DWORD m_le_dwApplicationSwTime;	// PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device
-	DWORD m_le_dwIpAddress;
-	DWORD m_le_dwSubnetMask;
-	DWORD m_le_dwDefaultGateway;
-	BYTE m_le_sHostname[32];
-	BYTE m_le_abVendorSpecificExt2[48];
+	u8 m_le_bFlag1;	// Flags: res
+	u8 m_le_bFlag2;	// Flags: PR, RS
+	u8 m_le_bNmtStatus;	// NMT state
+	u8 m_le_bIdentRespFlags;	// Flags: FW
+	u8 m_le_bEplProfileVersion;
+	u8 m_le_bRes1;
+	u32 m_le_dwFeatureFlags;	// NMT_FeatureFlags_U32
+	u16 m_le_wMtu;		// NMT_CycleTiming_REC.AsyncMTU_U16: C_IP_MIN_MTU - C_IP_MAX_MTU
+	u16 m_le_wPollInSize;	// NMT_CycleTiming_REC.PReqActPayload_U16
+	u16 m_le_wPollOutSize;	// NMT_CycleTiming_REC.PResActPayload_U16
+	u32 m_le_dwResponseTime;	// NMT_CycleTiming_REC.PResMaxLatency_U32
+	u16 m_le_wRes2;
+	u32 m_le_dwDeviceType;	// NMT_DeviceType_U32
+	u32 m_le_dwVendorId;	// NMT_IdentityObject_REC.VendorId_U32
+	u32 m_le_dwProductCode;	// NMT_IdentityObject_REC.ProductCode_U32
+	u32 m_le_dwRevisionNumber;	// NMT_IdentityObject_REC.RevisionNo_U32
+	u32 m_le_dwSerialNumber;	// NMT_IdentityObject_REC.SerialNo_U32
+	u64 m_le_qwVendorSpecificExt1;
+	u32 m_le_dwVerifyConfigurationDate;	// CFM_VerifyConfiguration_REC.ConfDate_U32
+	u32 m_le_dwVerifyConfigurationTime;	// CFM_VerifyConfiguration_REC.ConfTime_U32
+	u32 m_le_dwApplicationSwDate;	// PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device
+	u32 m_le_dwApplicationSwTime;	// PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device
+	u32 m_le_dwIpAddress;
+	u32 m_le_dwSubnetMask;
+	u32 m_le_dwDefaultGateway;
+	u8 m_le_sHostname[32];
+	u8 m_le_abVendorSpecificExt2[48];
 
 } PACK_STRUCT tEplIdentResponse;
 
 typedef struct {
 	// Offset 18
-	BYTE m_le_bNmtCommandId;
-	BYTE m_le_bRes1;
-	BYTE m_le_abNmtCommandData[32];
+	u8 m_le_bNmtCommandId;
+	u8 m_le_bRes1;
+	u8 m_le_abNmtCommandData[32];
 
 } PACK_STRUCT tEplNmtCommandService;
 
 typedef struct {
-	BYTE m_le_bReserved;
-	BYTE m_le_bTransactionId;
-	BYTE m_le_bFlags;
-	BYTE m_le_bCommandId;
-	WORD m_le_wSegmentSize;
-	WORD m_le_wReserved;
-	BYTE m_le_abCommandData[8];	// just reserve a minimum number of bytes as a placeholder
+	u8 m_le_bReserved;
+	u8 m_le_bTransactionId;
+	u8 m_le_bFlags;
+	u8 m_le_bCommandId;
+	u16 m_le_wSegmentSize;
+	u16 m_le_wReserved;
+	u8 m_le_abCommandData[8];	// just reserve a minimum number of bytes as a placeholder
 
 } PACK_STRUCT tEplAsySdoCom;
 
 // asynchronous SDO Sequence Header
 typedef struct {
-	BYTE m_le_bRecSeqNumCon;
-	BYTE m_le_bSendSeqNumCon;
-	BYTE m_le_abReserved[2];
+	u8 m_le_bRecSeqNumCon;
+	u8 m_le_bSendSeqNumCon;
+	u8 m_le_abReserved[2];
 	tEplAsySdoCom m_le_abSdoSeqPayload;
 
 } PACK_STRUCT tEplAsySdoSeq;
 
 typedef struct {
 	// Offset 18
-	BYTE m_le_bNmtCommandId;
-	BYTE m_le_bTargetNodeId;
-	BYTE m_le_abNmtCommandData[32];
+	u8 m_le_bNmtCommandId;
+	u8 m_le_bTargetNodeId;
+	u8 m_le_abNmtCommandData[32];
 
 } PACK_STRUCT tEplNmtRequestService;
 
@@ -281,14 +281,14 @@
 	tEplNmtCommandService m_NmtCommandService;
 	tEplNmtRequestService m_NmtRequestService;
 	tEplAsySdoSeq m_SdoSequenceFrame;
-	BYTE m_le_abPayload[256	/*D_NMT_ASndTxMaxPayload_U16
+	u8 m_le_abPayload[256	/*D_NMT_ASndTxMaxPayload_U16
 				   / D_NMT_ASndRxMaxPayload_U16 */ ];
 
 } tEplAsndPayload;
 
 typedef struct {
 	// Offset 17
-	BYTE m_le_bServiceId;
+	u8 m_le_bServiceId;
 	// Offset 18
 	tEplAsndPayload m_Payload;
 
@@ -306,17 +306,17 @@
 
 typedef struct {
 	// Offset 0
-	BYTE m_be_abDstMac[6];	// MAC address of the addressed nodes
+	u8 m_be_abDstMac[6];	// MAC address of the addressed nodes
 	// Offset 6
-	BYTE m_be_abSrcMac[6];	// MAC address of the transmitting node
+	u8 m_be_abSrcMac[6];	// MAC address of the transmitting node
 	// Offset 12
-	WORD m_be_wEtherType;	// Ethernet message type (big endian)
+	u16 m_be_wEtherType;	// Ethernet message type (big endian)
 	// Offset 14
-	BYTE m_le_bMessageType;	// EPL message type
+	u8 m_le_bMessageType;	// EPL message type
 	// Offset 15
-	BYTE m_le_bDstNodeId;	// EPL node ID of the addressed nodes
+	u8 m_le_bDstNodeId;	// EPL node ID of the addressed nodes
 	// Offset 16
-	BYTE m_le_bSrcNodeId;	// EPL node ID of the transmitting node
+	u8 m_le_bSrcNodeId;	// EPL node ID of the transmitting node
 	// Offset 17
 	tEplFrameData m_Data;
 
diff --git a/drivers/staging/epl/EplIdentu.c b/drivers/staging/epl/EplIdentu.c
index ce59ef0..93d5a40 100644
--- a/drivers/staging/epl/EplIdentu.c
+++ b/drivers/staging/epl/EplIdentu.c
@@ -138,7 +138,7 @@
 // local function prototypes
 //---------------------------------------------------------------------------
 
-static tEplKernel PUBLIC EplIdentuCbIdentResponse(tEplFrameInfo * pFrameInfo_p);
+static tEplKernel EplIdentuCbIdentResponse(tEplFrameInfo *pFrameInfo_p);
 
 //=========================================================================//
 //                                                                         //
@@ -164,7 +164,7 @@
 //
 //---------------------------------------------------------------------------
 
-EPLDLLEXPORT tEplKernel PUBLIC EplIdentuInit()
+tEplKernel EplIdentuInit(void)
 {
 	tEplKernel Ret;
 
@@ -191,7 +191,7 @@
 //
 //---------------------------------------------------------------------------
 
-EPLDLLEXPORT tEplKernel PUBLIC EplIdentuAddInstance()
+tEplKernel EplIdentuAddInstance(void)
 {
 	tEplKernel Ret;
 
@@ -228,7 +228,7 @@
 //
 //---------------------------------------------------------------------------
 
-EPLDLLEXPORT tEplKernel PUBLIC EplIdentuDelInstance()
+tEplKernel EplIdentuDelInstance(void)
 {
 	tEplKernel Ret;
 
@@ -263,7 +263,7 @@
 //
 //---------------------------------------------------------------------------
 
-EPLDLLEXPORT tEplKernel PUBLIC EplIdentuReset()
+tEplKernel EplIdentuReset(void)
 {
 	tEplKernel Ret;
 	int iIndex;
@@ -300,9 +300,8 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplIdentuGetIdentResponse(unsigned int uiNodeId_p,
-					    tEplIdentResponse **
-					    ppIdentResponse_p)
+tEplKernel EplIdentuGetIdentResponse(unsigned int uiNodeId_p,
+				     tEplIdentResponse **ppIdentResponse_p)
 {
 	tEplKernel Ret;
 
@@ -338,9 +337,8 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplIdentuRequestIdentResponse(unsigned int uiNodeId_p,
-						tEplIdentuCbResponse
-						pfnCbResponse_p)
+tEplKernel EplIdentuRequestIdentResponse(unsigned int uiNodeId_p,
+					 tEplIdentuCbResponse pfnCbResponse_p)
 {
 	tEplKernel Ret;
 
@@ -388,9 +386,9 @@
 //
 //---------------------------------------------------------------------------
 
-EPLDLLEXPORT DWORD PUBLIC EplIdentuGetRunningRequests(void)
+u32 EplIdentuGetRunningRequests(void)
 {
-	DWORD dwReqs = 0;
+	u32 dwReqs = 0;
 	unsigned int uiIndex;
 
 	for (uiIndex = 0; uiIndex < 32; uiIndex++) {
@@ -426,7 +424,7 @@
 //
 //---------------------------------------------------------------------------
 
-static tEplKernel PUBLIC EplIdentuCbIdentResponse(tEplFrameInfo * pFrameInfo_p)
+static tEplKernel EplIdentuCbIdentResponse(tEplFrameInfo *pFrameInfo_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 	unsigned int uiNodeId;
diff --git a/drivers/staging/epl/EplInc.h b/drivers/staging/epl/EplInc.h
index 77f93d1..f91797a 100644
--- a/drivers/staging/epl/EplInc.h
+++ b/drivers/staging/epl/EplInc.h
@@ -140,8 +140,8 @@
 
 // IEEE 1588 conformant net time structure
 typedef struct {
-	DWORD m_dwSec;
-	DWORD m_dwNanoSec;
+	u32 m_dwSec;
+	u32 m_dwNanoSec;
 
 } tEplNetTime;
 
@@ -154,8 +154,8 @@
 // -------------------------------------------------------------------------
 
 #define EPL_SPEC_VERSION                    0x20	// ETHERNET Powerlink V. 2.0
-#define EPL_STACK_VERSION(ver,rev,rel)      ((((DWORD)(ver)) & 0xFF)|((((DWORD)(rev))&0xFF)<<8)|(((DWORD)(rel))<<16))
-#define EPL_OBJ1018_VERSION(ver,rev,rel)    ((((DWORD)(ver))<<16) |(((DWORD)(rev))&0xFFFF))
+#define EPL_STACK_VERSION(ver,rev,rel)      ((((u32)(ver)) & 0xFF)|((((u32)(rev))&0xFF)<<8)|(((u32)(rel))<<16))
+#define EPL_OBJ1018_VERSION(ver,rev,rel)    ((((u32)(ver))<<16) |(((u32)(rev))&0xFFFF))
 #define EPL_STRING_VERSION(ver,rev,rel)     "V" #ver "." #rev " r" #rel
 
 #include "EplVersion.h"
@@ -236,21 +236,6 @@
 #define tabentries(a)   (sizeof(a)/sizeof(*(a)))
 #endif
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-// definitions for DLL export
-#if ((DEV_SYSTEM == _DEV_WIN32_) || (DEV_SYSTEM == _DEV_WIN_CE_)) && defined (COP_LIB)
-
-#define EPLDLLEXPORT    __declspec (dllexport)
-
-#else
-
-#define EPLDLLEXPORT
-
-#endif
-
 // ============================================================================
 // common debug macros
 // ============================================================================
diff --git a/drivers/staging/epl/EplInstDef.h b/drivers/staging/epl/EplInstDef.h
index 89efbf2..29ab7fb 100644
--- a/drivers/staging/epl/EplInstDef.h
+++ b/drivers/staging/epl/EplInstDef.h
@@ -71,6 +71,8 @@
 #ifndef _EPLINSTDEF_H_
 #define _EPLINSTDEF_H_
 
+#include <linux/kernel.h>
+
 // =========================================================================
 // types and macros for generating instances
 // =========================================================================
@@ -83,8 +85,8 @@
 
 //------------------------------------------------------------------------------------------
 
-typedef void MEM *tEplPtrInstance;
-typedef BYTE tEplInstanceHdl;
+typedef void *tEplPtrInstance;
+typedef u8 tEplInstanceHdl;
 
 // define const for illegale values
 #define CCM_ILLINSTANCE      NULL
@@ -99,8 +101,6 @@
     //--------------------------------------------------------------------------------------
 
     // memory attributes for instance table
-#define INST_NEAR		// faster access to variables
-#define INST_FAR		// variables wich have to located in xdata
 #define STATIC			// prevent warnings for variables with same name
 
 #define INSTANCE_TYPE_BEGIN     typedef struct {
@@ -117,12 +117,12 @@
 #define CCM_DECL_INSTANCE_HDL_                  tEplInstanceHdl InstanceHandle,
 
     // macros for declaration of pointer to instance handle within function header or prototype of API functions
-#define CCM_DECL_PTR_INSTANCE_HDL               tEplInstanceHdl MEM* pInstanceHandle
-#define CCM_DECL_PTR_INSTANCE_HDL_              tEplInstanceHdl MEM* pInstanceHandle,
+#define CCM_DECL_PTR_INSTANCE_HDL               tEplInstanceHdl *pInstanceHandle
+#define CCM_DECL_PTR_INSTANCE_HDL_              tEplInstanceHdl *pInstanceHandle,
 
     // macros for declaration instance as lokacl variable within functions
-#define CCM_DECL_INSTANCE_PTR_LOCAL             tCcmInstanceInfo MEM* pInstance;
-#define CCM_DECL_PTR_INSTANCE_HDL_LOCAL         tEplInstanceHdl  MEM* pInstanceHandle;
+#define CCM_DECL_INSTANCE_PTR_LOCAL             tCcmInstanceInfo *pInstance;
+#define CCM_DECL_PTR_INSTANCE_HDL_LOCAL         tEplInstanceHdl  *pInstanceHandle;
 
     // reference:
 
@@ -163,10 +163,10 @@
     //--------------------------------------------------------------------------------------
 
     // macros for declaration within the function header, prototype or local var list
-    // Declaration of pointers within function paramater list must defined as void MEM*
+    // Declaration of pointers within function paramater list must defined as void *
     // pointer.
-#define EPL_MCO_DECL_INSTANCE_PTR                   void MEM* pInstance
-#define EPL_MCO_DECL_INSTANCE_PTR_                  void MEM* pInstance,
+#define EPL_MCO_DECL_INSTANCE_PTR                   void *pInstance
+#define EPL_MCO_DECL_INSTANCE_PTR_                  void *pInstance,
 #define EPL_MCO_DECL_INSTANCE_PTR_LOCAL             tEplPtrInstance  pInstance;
 
     // macros for reference of pointer to instance
@@ -191,8 +191,8 @@
                                                     ASSERT (((tEplPtrInstance)pInstance)->m_InstState == kStateUsed);
 
     // macros for declaration of pointer to instance pointer
-#define EPL_MCO_DECL_PTR_INSTANCE_PTR               void MEM*  MEM* pInstancePtr
-#define EPL_MCO_DECL_PTR_INSTANCE_PTR_              void MEM*  MEM* pInstancePtr,
+#define EPL_MCO_DECL_PTR_INSTANCE_PTR               void **pInstancePtr
+#define EPL_MCO_DECL_PTR_INSTANCE_PTR_              void **pInstancePtr,
 
     // macros for reference of pointer to instance pointer
     // These macros are used for parameter passing to called function.
@@ -212,12 +212,12 @@
     // this macro deletes all instance entries as unused
 #define EPL_MCO_DELETE_INSTANCE_TABLE()                                    \
     {                                                                      \
-        tEplInstanceInfo MEM*   pInstance       = &aEplInstanceTable_g[0]; \
-        tFastByte               InstNumber      = 0;                       \
-        tFastByte               i               = EPL_MAX_INSTANCES;       \
+        tEplInstanceInfo *   pInstance       = &aEplInstanceTable_g[0];    \
+        tFastByte            InstNumber      = 0;                          \
+        tFastByte            i               = EPL_MAX_INSTANCES;          \
         do {                                                               \
-            pInstance->m_InstState = (BYTE) kStateUnused;                  \
-            pInstance->m_bInstIndex = (BYTE) InstNumber;                   \
+            pInstance->m_InstState = (u8) kStateUnused;                  \
+            pInstance->m_bInstIndex = (u8) InstNumber;                   \
             pInstance++; InstNumber++; i--;                                \
         } while (i != 0);                                                  \
     }
@@ -230,8 +230,8 @@
         static tEplPtrInstance GetInstancePtr (tEplInstanceHdl InstHandle_p) { \
             return &aEplInstanceTable_g[InstHandle_p]; }                       \
         static tEplPtrInstance GetFreeInstance (void) {                        \
-            tEplInstanceInfo MEM*   pInstance   = &aEplInstanceTable_g[0];     \
-            tFastByte               i           = EPL_MAX_INSTANCES;           \
+            tEplInstanceInfo *pInstance   = &aEplInstanceTable_g[0];           \
+            tFastByte         i           = EPL_MAX_INSTANCES;                 \
             do { if (pInstance->m_InstState != kStateUsed) {                   \
                     return (tEplPtrInstance) pInstance; }                      \
                 pInstance++; i--; }                                            \
@@ -240,13 +240,13 @@
 
     // this macro defines the instance table. Each entry is reserved for an instance of CANopen.
 #define EPL_MCO_DECL_INSTANCE_VAR() \
-        static tEplInstanceInfo MEM aEplInstanceTable_g [EPL_MAX_INSTANCES];
+        static tEplInstanceInfo aEplInstanceTable_g [EPL_MAX_INSTANCES];
 
     // this macro defines member variables in instance table which are needed in
     // all modules of Epl stack
 #define EPL_MCO_DECL_INSTANCE_MEMBER() \
-        STATIC  BYTE                            m_InstState; \
-        STATIC  BYTE                            m_bInstIndex;
+        STATIC  u8                            m_InstState; \
+        STATIC  u8                            m_bInstIndex;
 
 #define EPL_MCO_INSTANCE_PARAM_IDX_()           EPL_MCO_INSTANCE_PARAM_ (EPL_MCO_GLB_VAR (m_bInstIndex))
 #define EPL_MCO_INSTANCE_PARAM_IDX()            EPL_MCO_INSTANCE_PARAM (EPL_MCO_GLB_VAR (m_bInstIndex))
@@ -254,8 +254,6 @@
 #else // only one instance is used
 
     // Memory attributes for instance table.
-#define INST_NEAR   NEAR	// faster access to variables
-#define INST_FAR    MEM		// variables wich have to located in xdata
 #define STATIC      static	// prevent warnings for variables with same name
 
 #define INSTANCE_TYPE_BEGIN
@@ -359,18 +357,6 @@
 
 #endif
 
-/*
-#if (CDRV_MAX_INSTANCES > 1)
-
-    #define CDRV_REENTRANT                          REENTRANT
-
-#else
-
-    #define CDRV_REENTRANT
-
-#endif
-*/
-
 #endif // _EPLINSTDEF_H_
 
 // Die letzte Zeile muß unbedingt eine leere Zeile sein, weil manche Compiler
diff --git a/drivers/staging/epl/EplNmt.h b/drivers/staging/epl/EplNmt.h
index 4c11e5b..e351b55 100644
--- a/drivers/staging/epl/EplNmt.h
+++ b/drivers/staging/epl/EplNmt.h
@@ -185,7 +185,7 @@
 typedef struct {
 	unsigned int m_uiNodeId;	// NodeId
 	tEplNmtState m_NmtState;	// NMT state (remember distinguish between MN / CN)
-	WORD m_wErrorCode;	// EPL error code in case of NMT state NotActive
+	u16 m_wErrorCode;	// EPL error code in case of NMT state NotActive
 
 } tEplHeartbeatEvent;
 
diff --git a/drivers/staging/epl/EplNmtCnu.c b/drivers/staging/epl/EplNmtCnu.c
index f2f46da..c27ca8f 100644
--- a/drivers/staging/epl/EplNmtCnu.c
+++ b/drivers/staging/epl/EplNmtCnu.c
@@ -108,9 +108,9 @@
 
 static tEplNmtCommand EplNmtCnuGetNmtCommand(tEplFrameInfo * pFrameInfo_p);
 
-static BOOL EplNmtCnuNodeIdList(BYTE * pbNmtCommandDate_p);
+static BOOL EplNmtCnuNodeIdList(u8 * pbNmtCommandDate_p);
 
-static tEplKernel PUBLIC EplNmtCnuCommandCb(tEplFrameInfo * pFrameInfo_p);
+static tEplKernel EplNmtCnuCommandCb(tEplFrameInfo *pFrameInfo_p);
 
 //=========================================================================//
 //                                                                         //
@@ -135,7 +135,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuInit(unsigned int uiNodeId_p)
+tEplKernel EplNmtCnuInit(unsigned int uiNodeId_p)
 {
 	tEplKernel Ret;
 
@@ -161,7 +161,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuAddInstance(unsigned int uiNodeId_p)
+tEplKernel EplNmtCnuAddInstance(unsigned int uiNodeId_p)
 {
 	tEplKernel Ret;
 
@@ -201,7 +201,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuDelInstance()
+tEplKernel EplNmtCnuDelInstance(void)
 {
 	tEplKernel Ret;
 
@@ -234,9 +234,8 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuSendNmtRequest(unsigned int uiNodeId_p,
-						       tEplNmtCommand
-						       NmtCommand_p)
+tEplKernel EplNmtCnuSendNmtRequest(unsigned int uiNodeId_p,
+				   tEplNmtCommand NmtCommand_p)
 {
 	tEplKernel Ret;
 	tEplFrameInfo NmtRequestFrameInfo;
@@ -249,15 +248,15 @@
 	EPL_MEMSET(&NmtRequestFrame.m_be_abSrcMac[0], 0x00, sizeof(NmtRequestFrame.m_be_abSrcMac));	// set by DLL
 	AmiSetWordToBe(&NmtRequestFrame.m_be_wEtherType,
 		       EPL_C_DLL_ETHERTYPE_EPL);
-	AmiSetByteToLe(&NmtRequestFrame.m_le_bDstNodeId, (BYTE) EPL_C_ADR_MN_DEF_NODE_ID);	// node id of the MN
+	AmiSetByteToLe(&NmtRequestFrame.m_le_bDstNodeId, (u8) EPL_C_ADR_MN_DEF_NODE_ID);	// node id of the MN
 	AmiSetByteToLe(&NmtRequestFrame.m_le_bMessageType,
-		       (BYTE) kEplMsgTypeAsnd);
+		       (u8) kEplMsgTypeAsnd);
 	AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_le_bServiceId,
-		       (BYTE) kEplDllAsndNmtRequest);
+		       (u8) kEplDllAsndNmtRequest);
 	AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.
 		       m_NmtRequestService.m_le_bNmtCommandId,
-		       (BYTE) NmtCommand_p);
-	AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.m_NmtRequestService.m_le_bTargetNodeId, (BYTE) uiNodeId_p);	// target for the nmt command
+		       (u8) NmtCommand_p);
+	AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.m_NmtRequestService.m_le_bTargetNodeId, (u8) uiNodeId_p);	// target for the nmt command
 	EPL_MEMSET(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.m_NmtRequestService.
 		   m_le_abNmtCommandData[0], 0x00,
 		   sizeof(NmtRequestFrame.m_Data.m_Asnd.m_Payload.
@@ -297,9 +296,7 @@
 //
 //---------------------------------------------------------------------------
 
-EPLDLLEXPORT tEplKernel PUBLIC
-EplNmtCnuRegisterCheckEventCb(tEplNmtuCheckEventCallback
-			      pfnEplNmtCheckEventCb_p)
+tEplKernel EplNmtCnuRegisterCheckEventCb(tEplNmtuCheckEventCallback pfnEplNmtCheckEventCb_p)
 {
 	tEplKernel Ret;
 
@@ -335,7 +332,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplNmtCnuCommandCb(tEplFrameInfo * pFrameInfo_p)
+static tEplKernel EplNmtCnuCommandCb(tEplFrameInfo *pFrameInfo_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 	tEplNmtCommand NmtCommand;
@@ -676,18 +673,18 @@
 // State:
 //
 //---------------------------------------------------------------------------
-static BOOL EplNmtCnuNodeIdList(BYTE * pbNmtCommandDate_p)
+static BOOL EplNmtCnuNodeIdList(u8 * pbNmtCommandDate_p)
 {
 	BOOL fNodeIdInList;
 	unsigned int uiByteOffset;
-	BYTE bBitOffset;
-	BYTE bNodeListByte;
+	u8 bBitOffset;
+	u8 bNodeListByte;
 
 	// get byte-offset of the own nodeid in NodeIdList
 	// devide though 8
 	uiByteOffset = (unsigned int)(EplNmtCnuInstance_g.m_uiNodeId >> 3);
 	// get bitoffset
-	bBitOffset = (BYTE) EplNmtCnuInstance_g.m_uiNodeId % 8;
+	bBitOffset = (u8) EplNmtCnuInstance_g.m_uiNodeId % 8;
 
 	bNodeListByte = AmiGetByteFromLe(&pbNmtCommandDate_p[uiByteOffset]);
 	if ((bNodeListByte & bBitOffset) == 0) {
diff --git a/drivers/staging/epl/EplNmtMnu.c b/drivers/staging/epl/EplNmtMnu.c
index 4ed0b6c..d19434f 100644
--- a/drivers/staging/epl/EplNmtMnu.c
+++ b/drivers/staging/epl/EplNmtMnu.c
@@ -94,8 +94,8 @@
 
 // TracePoint support for realtime-debugging
 #ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
+void TgtDbgPostTraceValue(u32 dwTraceValue_p);
 #define TGT_DBG_SIGNAL_TRACE_POINT(p)   TgtDbgSignalTracePoint(p)
 #define TGT_DBG_POST_TRACE_VALUE(v)     TgtDbgPostTraceValue(v)
 #else
@@ -211,8 +211,8 @@
 	tEplTimerHdl m_TimerHdlStatReq;	// timer to delay StatusRequests and IdentRequests
 	tEplTimerHdl m_TimerHdlLonger;	// 2nd timer for NMT command EnableReadyToOp and CheckCommunication
 	tEplNmtMnuNodeState m_NodeState;	// internal node state (kind of sub state of NMT state)
-	DWORD m_dwNodeCfg;	// subindex from 0x1F81
-	WORD m_wFlags;		// flags: CN is being accessed isochronously
+	u32 m_dwNodeCfg;	// subindex from 0x1F81
+	u16 m_wFlags;		// flags: CN is being accessed isochronously
 
 } tEplNmtMnuNodeInfo;
 
@@ -224,8 +224,8 @@
 	unsigned long m_ulStatusRequestDelay;	// in [ms] (object 0x1006 * EPL_C_NMT_STATREQ_CYCLE)
 	unsigned long m_ulTimeoutReadyToOp;	// in [ms] (object 0x1F89/5)
 	unsigned long m_ulTimeoutCheckCom;	// in [ms] (object 0x1006 * MultiplexedCycleCount)
-	WORD m_wFlags;		// global flags
-	DWORD m_dwNmtStartup;	// object 0x1F80 NMT_StartUp_U32
+	u16 m_wFlags;		// global flags
+	u32 m_dwNmtStartup;	// object 0x1F80 NMT_StartUp_U32
 	tEplNmtMnuCbNodeEvent m_pfnCbNodeEvent;
 	tEplNmtMnuCbBootEvent m_pfnCbBootEvent;
 
@@ -241,20 +241,18 @@
 // local function prototypes
 //---------------------------------------------------------------------------
 
-static tEplKernel PUBLIC EplNmtMnuCbNmtRequest(tEplFrameInfo * pFrameInfo_p);
+static tEplKernel EplNmtMnuCbNmtRequest(tEplFrameInfo *pFrameInfo_p);
 
-static tEplKernel PUBLIC EplNmtMnuCbIdentResponse(unsigned int uiNodeId_p,
-						  tEplIdentResponse *
-						  pIdentResponse_p);
+static tEplKernel EplNmtMnuCbIdentResponse(unsigned int uiNodeId_p,
+					   tEplIdentResponse *pIdentResponse_p);
 
-static tEplKernel PUBLIC EplNmtMnuCbStatusResponse(unsigned int uiNodeId_p,
-						   tEplStatusResponse *
-						   pStatusResponse_p);
+static tEplKernel EplNmtMnuCbStatusResponse(unsigned int uiNodeId_p,
+					    tEplStatusResponse *pStatusResponse_p);
 
 static tEplKernel EplNmtMnuCheckNmtState(unsigned int uiNodeId_p,
 					 tEplNmtMnuNodeInfo * pNodeInfo_p,
 					 tEplNmtState NodeNmtState_p,
-					 WORD wErrorCode_p,
+					 u16 wErrorCode_p,
 					 tEplNmtState LocalNmtState_p);
 
 static tEplKernel EplNmtMnuStartBootStep1(void);
@@ -273,7 +271,7 @@
 
 static tEplKernel EplNmtMnuProcessInternalEvent(unsigned int uiNodeId_p,
 						tEplNmtState NodeNmtState_p,
-						WORD wErrorCode_p,
+						u16 wErrorCode_p,
 						tEplNmtMnuIntNodeEvent
 						NodeEvent_p);
 
@@ -380,7 +378,7 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel EplNmtMnuDelInstance()
+tEplKernel EplNmtMnuDelInstance(void)
 {
 	tEplKernel Ret;
 
@@ -419,7 +417,7 @@
 {
 	tEplKernel Ret = kEplSuccessful;
 	tEplFrameInfo FrameInfo;
-	BYTE abBuffer[EPL_C_DLL_MINSIZE_NMTCMDEXT];
+	u8 abBuffer[EPL_C_DLL_MINSIZE_NMTCMDEXT];
 	tEplFrame *pFrame = (tEplFrame *) abBuffer;
 	BOOL fSoftDeleteNode = FALSE;
 
@@ -439,11 +437,11 @@
 
 	// build frame
 	EPL_MEMSET(pFrame, 0x00, sizeof(abBuffer));
-	AmiSetByteToLe(&pFrame->m_le_bDstNodeId, (BYTE) uiNodeId_p);
+	AmiSetByteToLe(&pFrame->m_le_bDstNodeId, (u8) uiNodeId_p);
 	AmiSetByteToLe(&pFrame->m_Data.m_Asnd.m_le_bServiceId,
-		       (BYTE) kEplDllAsndNmtCommand);
+		       (u8) kEplDllAsndNmtCommand);
 	AmiSetByteToLe(&pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.
-		       m_le_bNmtCommandId, (BYTE) NmtCommand_p);
+		       m_le_bNmtCommandId, (u8) NmtCommand_p);
 	if ((pNmtCommandData_p != NULL) && (uiDataSize_p > 0)) {	// copy command data to frame
 		EPL_MEMCPY(&pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.
 			   m_le_abNmtCommandData[0], pNmtCommandData_p,
@@ -574,8 +572,8 @@
 	tEplKernel Ret = kEplSuccessful;
 	tEplNmtMnuIntNodeEvent NodeEvent;
 	tEplObdSize ObdSize;
-	BYTE bNmtState;
-	WORD wErrorCode = EPL_E_NO_ERROR;
+	u8 bNmtState;
+	u16 wErrorCode = EPL_E_NO_ERROR;
 
 	if ((uiNodeId_p == 0) || (uiNodeId_p >= EPL_C_ADR_BROADCAST)) {
 		Ret = kEplInvalidNodeId;
@@ -645,8 +643,7 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplNmtMnuCbNmtStateChange(tEplEventNmtStateChange
-					    NmtStateChange_p)
+tEplKernel EplNmtMnuCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 
@@ -676,7 +673,7 @@
 		// build the configuration with infos from OD
 	case kEplNmtGsResetConfiguration:
 		{
-			DWORD dwTimeout;
+			u32 dwTimeout;
 			tEplObdSize ObdSize;
 
 			// read object 0x1F80 NMT_StartUp_U32
@@ -788,7 +785,7 @@
 		// node processes only async frames
 	case kEplNmtMsPreOperational1:
 		{
-			DWORD dwTimeout;
+			u32 dwTimeout;
 			tEplTimerArg TimerArg;
 			tEplObdSize ObdSize;
 			tEplEvent Event;
@@ -928,7 +925,7 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplNmtMnuCbCheckEvent(tEplNmtEvent NmtEvent_p)
+tEplKernel EplNmtMnuCbCheckEvent(tEplNmtEvent NmtEvent_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 
@@ -949,7 +946,7 @@
 //
 //---------------------------------------------------------------------------
 
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtMnuProcessEvent(tEplEvent * pEvent_p)
+tEplKernel EplNmtMnuProcessEvent(tEplEvent *pEvent_p)
 {
 	tEplKernel Ret;
 
@@ -970,7 +967,7 @@
 					   EPL_NMTMNU_TIMERARG_NODE_MASK);
 			if (uiNodeId != 0) {
 				tEplObdSize ObdSize;
-				BYTE bNmtState;
+				u8 bNmtState;
 				tEplNmtMnuNodeInfo *pNodeInfo;
 
 				pNodeInfo = EPL_NMTMNU_GET_NODEINFO(uiNodeId);
@@ -1150,7 +1147,7 @@
 			tEplFrame *pFrame = (tEplFrame *) pEvent_p->m_pArg;
 			unsigned int uiNodeId;
 			tEplNmtCommand NmtCommand;
-			BYTE bNmtState;
+			u8 bNmtState;
 
 			uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bDstNodeId);
 			NmtCommand =
@@ -1162,30 +1159,30 @@
 			switch (NmtCommand) {
 			case kEplNmtCmdStartNode:
 				bNmtState =
-				    (BYTE) (kEplNmtCsOperational & 0xFF);
+				    (u8) (kEplNmtCsOperational & 0xFF);
 				break;
 
 			case kEplNmtCmdStopNode:
-				bNmtState = (BYTE) (kEplNmtCsStopped & 0xFF);
+				bNmtState = (u8) (kEplNmtCsStopped & 0xFF);
 				break;
 
 			case kEplNmtCmdEnterPreOperational2:
 				bNmtState =
-				    (BYTE) (kEplNmtCsPreOperational2 & 0xFF);
+				    (u8) (kEplNmtCsPreOperational2 & 0xFF);
 				break;
 
 			case kEplNmtCmdEnableReadyToOperate:
 				// d.k. do not change expected node state, because of DS 1.0.0 7.3.1.2.1 Plain NMT State Command
 				//      and because node may not change NMT state within EPL_C_NMT_STATE_TOLERANCE
 				bNmtState =
-				    (BYTE) (kEplNmtCsPreOperational2 & 0xFF);
+				    (u8) (kEplNmtCsPreOperational2 & 0xFF);
 				break;
 
 			case kEplNmtCmdResetNode:
 			case kEplNmtCmdResetCommunication:
 			case kEplNmtCmdResetConfiguration:
 			case kEplNmtCmdSwReset:
-				bNmtState = (BYTE) (kEplNmtCsNotActive & 0xFF);
+				bNmtState = (u8) (kEplNmtCsNotActive & 0xFF);
 				// EplNmtMnuProcessInternalEvent() sets internal node state to kEplNmtMnuNodeStateUnknown
 				// after next unresponded IdentRequest/StatusRequest
 				break;
@@ -1258,11 +1255,9 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplNmtMnuGetDiagnosticInfo(unsigned int
-					     *puiMandatorySlaveCount_p,
-					     unsigned int
-					     *puiSignalSlaveCount_p,
-					     WORD * pwFlags_p)
+tEplKernel EplNmtMnuGetDiagnosticInfo(unsigned int *puiMandatorySlaveCount_p,
+				      unsigned int *puiSignalSlaveCount_p,
+				      u16 *pwFlags_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 
@@ -1296,7 +1291,7 @@
 //
 //---------------------------------------------------------------------------
 /*
-DWORD EplNmtMnuGetRunningTimerStatReq(void)
+u32 EplNmtMnuGetRunningTimerStatReq(void)
 {
 tEplKernel      Ret = kEplSuccessful;
 unsigned int    uiIndex;
@@ -1347,7 +1342,7 @@
 //
 //---------------------------------------------------------------------------
 
-static tEplKernel PUBLIC EplNmtMnuCbNmtRequest(tEplFrameInfo * pFrameInfo_p)
+static tEplKernel EplNmtMnuCbNmtRequest(tEplFrameInfo *pFrameInfo_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 
@@ -1371,9 +1366,8 @@
 //
 //---------------------------------------------------------------------------
 
-static tEplKernel PUBLIC EplNmtMnuCbIdentResponse(unsigned int uiNodeId_p,
-						  tEplIdentResponse *
-						  pIdentResponse_p)
+static tEplKernel EplNmtMnuCbIdentResponse(unsigned int uiNodeId_p,
+					   tEplIdentResponse *pIdentResponse_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 
@@ -1382,8 +1376,8 @@
 						    kEplNmtMnuIntNodeEventNoIdentResponse);
 	} else {		// node answered IdentRequest
 		tEplObdSize ObdSize;
-		DWORD dwDevType;
-		WORD wErrorCode = EPL_E_NO_ERROR;
+		u32 dwDevType;
+		u16 wErrorCode = EPL_E_NO_ERROR;
 		tEplNmtState NmtState =
 		    (tEplNmtState) (AmiGetByteFromLe
 				    (&pIdentResponse_p->
@@ -1431,9 +1425,8 @@
 //
 //---------------------------------------------------------------------------
 
-static tEplKernel PUBLIC EplNmtMnuCbStatusResponse(unsigned int uiNodeId_p,
-						   tEplStatusResponse *
-						   pStatusResponse_p)
+static tEplKernel EplNmtMnuCbStatusResponse(unsigned int uiNodeId_p,
+					    tEplStatusResponse *pStatusResponse_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 
@@ -1473,7 +1466,7 @@
 	tEplKernel Ret = kEplSuccessful;
 	unsigned int uiSubIndex;
 	unsigned int uiLocalNodeId;
-	DWORD dwNodeCfg;
+	u32 dwNodeCfg;
 	tEplObdSize ObdSize;
 
 	// $$$ d.k.: save current time for 0x1F89/2 MNTimeoutPreOp1_U32
@@ -1633,7 +1626,7 @@
 {
 	tEplKernel Ret = kEplSuccessful;
 	tEplDllNodeInfo DllNodeInfo;
-	DWORD dwNodeCfg;
+	u32 dwNodeCfg;
 	tEplObdSize ObdSize;
 	tEplTimerArg TimerArg;
 
@@ -1782,7 +1775,7 @@
 					tEplNmtMnuNodeInfo * pNodeInfo_p)
 {
 	tEplKernel Ret = kEplSuccessful;
-	DWORD dwNodeCfg;
+	u32 dwNodeCfg;
 	tEplTimerArg TimerArg;
 
 	dwNodeCfg = pNodeInfo_p->m_dwNodeCfg;
@@ -1916,7 +1909,7 @@
 
 static tEplKernel EplNmtMnuProcessInternalEvent(unsigned int uiNodeId_p,
 						tEplNmtState NodeNmtState_p,
-						WORD wErrorCode_p,
+						u16 wErrorCode_p,
 						tEplNmtMnuIntNodeEvent
 						NodeEvent_p)
 {
@@ -1934,7 +1927,7 @@
 	switch (NodeEvent_p) {
 	case kEplNmtMnuIntNodeEventIdentResponse:
 		{
-			BYTE bNmtState;
+			u8 bNmtState;
 
 			EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
 							uiNodeId_p,
@@ -1961,7 +1954,7 @@
 				    ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
 			}
 			// update object 0x1F8F NMT_MNNodeExpState_AU8 to PreOp1 (even if local state >= PreOp2)
-			bNmtState = (BYTE) (kEplNmtCsPreOperational1 & 0xFF);
+			bNmtState = (u8) (kEplNmtCsPreOperational1 & 0xFF);
 			Ret =
 			    EplObduWriteEntry(0x1F8F, uiNodeId_p, &bNmtState,
 					      1);
@@ -2441,11 +2434,11 @@
 
 	case kEplNmtMnuIntNodeEventNmtCmdSent:
 		{
-			BYTE bNmtState;
+			u8 bNmtState;
 
 			// update expected NMT state with the one that results
 			// from the sent NMT command
-			bNmtState = (BYTE) (NodeNmtState_p & 0xFF);
+			bNmtState = (u8) (NodeNmtState_p & 0xFF);
 
 			// write object 0x1F8F NMT_MNNodeExpState_AU8
 			Ret =
@@ -2630,13 +2623,13 @@
 static tEplKernel EplNmtMnuCheckNmtState(unsigned int uiNodeId_p,
 					 tEplNmtMnuNodeInfo * pNodeInfo_p,
 					 tEplNmtState NodeNmtState_p,
-					 WORD wErrorCode_p,
+					 u16 wErrorCode_p,
 					 tEplNmtState LocalNmtState_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 	tEplObdSize ObdSize;
-	BYTE bNmtState;
-	BYTE bNmtStatePrev;
+	u8 bNmtState;
+	u8 bNmtStatePrev;
 	tEplNmtState ExpNmtState;
 
 	ObdSize = 1;
@@ -2647,8 +2640,8 @@
 	}
 	// compute expected NMT state
 	ExpNmtState = (tEplNmtState) (bNmtState | EPL_NMT_TYPE_CS);
-	// compute BYTE of current NMT state
-	bNmtState = ((BYTE) NodeNmtState_p & 0xFF);
+	// compute u8 of current NMT state
+	bNmtState = ((u8) NodeNmtState_p & 0xFF);
 
 	if (ExpNmtState == kEplNmtCsNotActive) {	// ignore the current state, because the CN shall be not active
 		Ret = kEplReject;
@@ -2706,7 +2699,7 @@
 	} else if ((ExpNmtState != NodeNmtState_p)
 		   && !((ExpNmtState == kEplNmtCsPreOperational1)
 			&& (NodeNmtState_p == kEplNmtCsPreOperational2))) {	// CN is not in expected NMT state (without the exceptions above)
-		WORD wbeErrorCode;
+		u16 wbeErrorCode;
 
 		if ((pNodeInfo_p->
 		     m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) != 0) {
diff --git a/drivers/staging/epl/EplNmtk.c b/drivers/staging/epl/EplNmtk.c
index 4e2d0e1..609d5c0 100644
--- a/drivers/staging/epl/EplNmtk.c
+++ b/drivers/staging/epl/EplNmtk.c
@@ -88,8 +88,8 @@
 
 // TracePoint support for realtime-debugging
 #ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
+void TgtDbgPostTraceValue(u32 dwTraceValue_p);
 #define TGT_DBG_SIGNAL_TRACE_POINT(p)   TgtDbgSignalTracePoint(p)
 #define TGT_DBG_POST_TRACE_VALUE(v)     TgtDbgPostTraceValue(v)
 #else
@@ -107,12 +107,12 @@
 // struct for instance table
 INSTANCE_TYPE_BEGIN EPL_MCO_DECL_INSTANCE_MEMBER()
 
-STATIC volatile tEplNmtState INST_FAR m_NmtState;
-STATIC volatile BOOL INST_FAR m_fEnableReadyToOperate;
-STATIC volatile BOOL INST_FAR m_fAppReadyToOperate;
-STATIC volatile BOOL INST_FAR m_fTimerMsPreOp2;
-STATIC volatile BOOL INST_FAR m_fAllMandatoryCNIdent;
-STATIC volatile BOOL INST_FAR m_fFrozen;
+STATIC volatile tEplNmtState m_NmtState;
+STATIC volatile BOOL m_fEnableReadyToOperate;
+STATIC volatile BOOL m_fAppReadyToOperate;
+STATIC volatile BOOL m_fTimerMsPreOp2;
+STATIC volatile BOOL m_fAllMandatoryCNIdent;
+STATIC volatile BOOL m_fFrozen;
 
 INSTANCE_TYPE_END
 //---------------------------------------------------------------------------
@@ -121,7 +121,7 @@
 // This macro replace the unspecific pointer to an instance through
 // the modul specific type for the local instance table. This macro
 // must defined in each modul.
-//#define tEplPtrInstance             tEplInstanceInfo MEM*
+//#define tEplPtrInstance             tEplInstanceInfo*
 EPL_MCO_DECL_INSTANCE_VAR()
 //---------------------------------------------------------------------------
 // local function prototypes
@@ -163,7 +163,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtkInit(EPL_MCO_DECL_PTR_INSTANCE_PTR)
+tEplKernel EplNmtkInit(EPL_MCO_DECL_PTR_INSTANCE_PTR)
 {
 	tEplKernel Ret;
 
@@ -189,7 +189,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtkAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR)
+tEplKernel EplNmtkAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR)
 {
 	EPL_MCO_DECL_INSTANCE_PTR_LOCAL tEplKernel Ret;
 //tEplEvent               Event;
@@ -258,7 +258,7 @@
 //
 //---------------------------------------------------------------------------
 #if (EPL_USE_DELETEINST_FUNC != FALSE)
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtkDelInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR)
+tEplKernel EplNmtkDelInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR)
 {
 	tEplKernel Ret = kEplSuccessful;
 	// check for all API function if instance is valid
@@ -296,8 +296,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtkProcess(EPL_MCO_DECL_PTR_INSTANCE_PTR_
-					      tEplEvent * pEvent_p)
+tEplKernel EplNmtkProcess(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplEvent *pEvent_p)
 {
 	tEplKernel Ret;
 	tEplNmtState OldNmtState;
@@ -1804,8 +1803,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplNmtState PUBLIC
-EplNmtkGetNmtState(EPL_MCO_DECL_PTR_INSTANCE_PTR)
+tEplNmtState EplNmtkGetNmtState(EPL_MCO_DECL_PTR_INSTANCE_PTR)
 {
 	tEplNmtState NmtState;
 
diff --git a/drivers/staging/epl/EplNmtkCal.c b/drivers/staging/epl/EplNmtkCal.c
index 4ad71a7..4453c09 100644
--- a/drivers/staging/epl/EplNmtkCal.c
+++ b/drivers/staging/epl/EplNmtkCal.c
@@ -69,8 +69,6 @@
 
 ****************************************************************************/
 
-#include "kernel/EplNmtkCal.h"
-
 // TODO: init function needed to prepare EplNmtkGetNmtState for
 //       io-controll-call from EplNmtuCal-Modul
 
diff --git a/drivers/staging/epl/EplNmtu.c b/drivers/staging/epl/EplNmtu.c
index 3de16a1..9ac2e8e 100644
--- a/drivers/staging/epl/EplNmtu.c
+++ b/drivers/staging/epl/EplNmtu.c
@@ -132,7 +132,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuInit()
+tEplKernel EplNmtuInit(void)
 {
 	tEplKernel Ret;
 
@@ -158,7 +158,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuAddInstance()
+tEplKernel EplNmtuAddInstance(void)
 {
 	tEplKernel Ret;
 
@@ -187,7 +187,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuDelInstance()
+tEplKernel EplNmtuDelInstance(void)
 {
 	tEplKernel Ret;
 
@@ -219,7 +219,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuNmtEvent(tEplNmtEvent NmtEvent_p)
+tEplKernel EplNmtuNmtEvent(tEplNmtEvent NmtEvent_p)
 {
 	tEplKernel Ret;
 	tEplEvent Event;
@@ -253,7 +253,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplNmtState PUBLIC EplNmtuGetNmtState()
+tEplNmtState EplNmtuGetNmtState(void)
 {
 	tEplNmtState NmtState;
 
@@ -284,7 +284,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuProcessEvent(tEplEvent * pEplEvent_p)
+tEplKernel EplNmtuProcessEvent(tEplEvent *pEplEvent_p)
 {
 	tEplKernel Ret;
 
@@ -382,7 +382,7 @@
 					// node listens for EPL-Frames and check timeout
 				case kEplNmtCsNotActive:
 					{
-						DWORD dwBuffer;
+						u32 dwBuffer;
 						tEplObdSize ObdSize;
 						tEplTimerArg TimerArg;
 
@@ -475,7 +475,7 @@
 					// node listens for EPL-Frames and check timeout
 				case kEplNmtMsNotActive:
 					{
-						DWORD dwBuffer;
+						u32 dwBuffer;
 						tEplObdSize ObdSize;
 						tEplTimerArg TimerArg;
 
@@ -544,7 +544,7 @@
 					// node processes only async frames
 				case kEplNmtMsPreOperational1:
 					{
-						DWORD dwBuffer = 0;
+						u32 dwBuffer = 0;
 						tEplObdSize ObdSize;
 						tEplTimerArg TimerArg;
 
@@ -664,9 +664,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC
-EplNmtuRegisterStateChangeCb(tEplNmtuStateChangeCallback
-			     pfnEplNmtStateChangeCb_p)
+tEplKernel EplNmtuRegisterStateChangeCb(tEplNmtuStateChangeCallback pfnEplNmtStateChangeCb_p)
 {
 	tEplKernel Ret;
 
diff --git a/drivers/staging/epl/EplNmtuCal.c b/drivers/staging/epl/EplNmtuCal.c
index 4a29ef5..92164c57 100644
--- a/drivers/staging/epl/EplNmtuCal.c
+++ b/drivers/staging/epl/EplNmtuCal.c
@@ -119,7 +119,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplNmtState PUBLIC EplNmtkCalGetNmtState()
+tEplNmtState EplNmtkCalGetNmtState(void)
 {
 	tEplNmtState NmtState;
 	// for test direkt call for EplNmtkGetNmtState()
diff --git a/drivers/staging/epl/EplObd.c b/drivers/staging/epl/EplObd.c
index efbb196..1e46323 100644
--- a/drivers/staging/epl/EplObd.c
+++ b/drivers/staging/epl/EplObd.c
@@ -101,8 +101,8 @@
 // struct for instance table
 INSTANCE_TYPE_BEGIN EPL_MCO_DECL_INSTANCE_MEMBER()
 
-STATIC tEplObdInitParam INST_FAR m_ObdInitParam;
-STATIC tEplObdStoreLoadObjCallback INST_NEAR m_fpStoreLoadObjCallback;
+STATIC tEplObdInitParam m_ObdInitParam;
+STATIC tEplObdStoreLoadObjCallback m_fpStoreLoadObjCallback;
 
 INSTANCE_TYPE_END
 // decomposition of float
@@ -119,11 +119,11 @@
 // This macro replace the unspecific pointer to an instance through
 // the modul specific type for the local instance table. This macro
 // must defined in each modul.
-//#define tEplPtrInstance             tEplInstanceInfo MEM*
+//#define tEplPtrInstance             tEplInstanceInfo *
 
 EPL_MCO_DECL_INSTANCE_VAR()
 
-BYTE MEM abEplObdTrashObject_g[8];
+u8 abEplObdTrashObject_g[8];
 
 //---------------------------------------------------------------------------
 // local function prototypes
@@ -133,7 +133,7 @@
 
 static tEplKernel EplObdCallObjectCallback(EPL_MCO_DECL_INSTANCE_PTR_
 					   tEplObdCallback fpCallback_p,
-					   tEplObdCbParam MEM * pCbParam_p);
+					   tEplObdCbParam *pCbParam_p);
 
 static tEplObdSize EplObdGetDataSizeIntern(tEplObdSubEntryPtr pSubIndexEntry_p);
 
@@ -146,7 +146,7 @@
 #endif
 
 static tEplKernel EplObdGetVarEntry(tEplObdSubEntryPtr pSubindexEntry_p,
-				    tEplObdVarEntry MEM ** ppVarEntry_p);
+				    tEplObdVarEntry **ppVarEntry_p);
 
 static tEplKernel EplObdGetEntry(EPL_MCO_DECL_INSTANCE_PTR_
 				 unsigned int uiIndex_p,
@@ -156,7 +156,7 @@
 
 static tEplObdSize EplObdGetObjectSize(tEplObdSubEntryPtr pSubIndexEntry_p);
 
-static tEplKernel EplObdGetIndexIntern(tEplObdInitParam MEM * pInitParam_p,
+static tEplKernel EplObdGetIndexIntern(tEplObdInitParam *pInitParam_p,
 				       unsigned int uiIndex_p,
 				       tEplObdEntryPtr * ppObdEntry_p);
 
@@ -170,17 +170,15 @@
 					   tEplObdDir Direction_p);
 
 static void *EplObdGetObjectDefaultPtr(tEplObdSubEntryPtr pSubIndexEntry_p);
-static void MEM *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p);
+static void *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p);
 
 #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
 
-static tEplKernel EplObdCallStoreCallback(EPL_MCO_DECL_INSTANCE_PTR_
-					  tEplObdCbStoreParam MEM *
-					  pCbStoreParam_p);
+static tEplKernel EplObdCallStoreCallback(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdCbStoreParam *pCbStoreParam_p);
 
 #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
 
-static void EplObdCopyObjectData(void MEM * pDstData_p,
+static void EplObdCopyObjectData(void *pDstData_p,
 				 void *pSrcData_p,
 				 tEplObdSize ObjSize_p, tEplObdType ObjType_p);
 
@@ -189,24 +187,22 @@
 static tEplKernel EplObdIsNumericalIntern(tEplObdSubEntryPtr pObdSubEntry_p,
 					  BOOL * pfEntryNumerical_p);
 
-static tEplKernel PUBLIC EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_
-					     unsigned int uiIndex_p,
-					     unsigned int uiSubIndex_p,
-					     void *pSrcData_p,
-					     void **ppDstData_p,
-					     tEplObdSize Size_p,
-					     tEplObdEntryPtr * ppObdEntry_p,
-					     tEplObdSubEntryPtr * ppSubEntry_p,
-					     tEplObdCbParam MEM * pCbParam_p,
-					     tEplObdSize * pObdSize_p);
+static tEplKernel EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+				      unsigned int uiSubIndex_p,
+				      void *pSrcData_p,
+				      void **ppDstData_p,
+				      tEplObdSize Size_p,
+				      tEplObdEntryPtr *ppObdEntry_p,
+				      tEplObdSubEntryPtr *ppSubEntry_p,
+				      tEplObdCbParam *pCbParam_p,
+				      tEplObdSize *pObdSize_p);
 
-static tEplKernel PUBLIC EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_
-					      tEplObdEntryPtr pObdEntry_p,
-					      tEplObdSubEntryPtr pSubEntry_p,
-					      tEplObdCbParam MEM * pCbParam_p,
-					      void *pSrcData_p,
-					      void *pDstData_p,
-					      tEplObdSize ObdSize_p);
+static tEplKernel EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pObdEntry_p,
+				       tEplObdSubEntryPtr pSubEntry_p,
+				       tEplObdCbParam *pCbParam_p,
+				       void *pSrcData_p,
+				       void *pDstData_p,
+				       tEplObdSize ObdSize_p);
 
 //=========================================================================//
 //                                                                         //
@@ -228,8 +224,7 @@
 //
 //---------------------------------------------------------------------------
 
-EPLDLLEXPORT tEplKernel PUBLIC EplObdInit(EPL_MCO_DECL_PTR_INSTANCE_PTR_
-					  tEplObdInitParam MEM * pInitParam_p)
+tEplKernel EplObdInit(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam *pInitParam_p)
 {
 
 	tEplKernel Ret;
@@ -261,9 +256,7 @@
 //
 //---------------------------------------------------------------------------
 
-EPLDLLEXPORT tEplKernel PUBLIC EplObdAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR_
-						 tEplObdInitParam MEM *
-						 pInitParam_p)
+tEplKernel EplObdAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam *pInitParam_p)
 {
 
 	EPL_MCO_DECL_INSTANCE_PTR_LOCAL tEplKernel Ret;
@@ -308,7 +301,7 @@
 //
 //---------------------------------------------------------------------------
 #if (EPL_USE_DELETEINST_FUNC != FALSE)
-EPLDLLEXPORT tEplKernel PUBLIC EplObdDeleteInstance(EPL_MCO_DECL_INSTANCE_PTR)
+tEplKernel EplObdDeleteInstance(EPL_MCO_DECL_INSTANCE_PTR)
 {
 	// check for all API function if instance is valid
 	EPL_MCO_CHECK_INSTANCE_STATE();
@@ -341,18 +334,16 @@
 //
 //---------------------------------------------------------------------------
 
-EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntry(EPL_MCO_DECL_INSTANCE_PTR_
-						unsigned int uiIndex_p,
-						unsigned int uiSubIndex_p,
-						void *pSrcData_p,
-						tEplObdSize Size_p)
+tEplKernel EplObdWriteEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+			    unsigned int uiSubIndex_p,
+			    void *pSrcData_p, tEplObdSize Size_p)
 {
 
 	tEplKernel Ret;
 	tEplObdEntryPtr pObdEntry;
 	tEplObdSubEntryPtr pSubEntry;
-	tEplObdCbParam MEM CbParam;
-	void MEM *pDstData;
+	tEplObdCbParam CbParam;
+	void *pDstData;
 	tEplObdSize ObdSize;
 
 	Ret = EplObdWriteEntryPre(EPL_MCO_INSTANCE_PTR_
@@ -402,17 +393,15 @@
 //
 //---------------------------------------------------------------------------
 
-EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntry(EPL_MCO_DECL_INSTANCE_PTR_
-					       unsigned int uiIndex_p,
-					       unsigned int uiSubIndex_p,
-					       void *pDstData_p,
-					       tEplObdSize * pSize_p)
+tEplKernel EplObdReadEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+			   unsigned int uiSubIndex_p,
+			   void *pDstData_p, tEplObdSize *pSize_p)
 {
 
 	tEplKernel Ret;
 	tEplObdEntryPtr pObdEntry;
 	tEplObdSubEntryPtr pSubEntry;
-	tEplObdCbParam MEM CbParam;
+	tEplObdCbParam CbParam;
 	void *pSrcData;
 	tEplObdSize ObdSize;
 
@@ -487,9 +476,8 @@
 //
 //---------------------------------------------------------------------------
 
-EPLDLLEXPORT tEplKernel PUBLIC EplObdAccessOdPart(EPL_MCO_DECL_INSTANCE_PTR_
-						  tEplObdPart ObdPart_p,
-						  tEplObdDir Direction_p)
+tEplKernel EplObdAccessOdPart(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdPart ObdPart_p,
+			      tEplObdDir Direction_p)
 {
 
 	tEplKernel Ret = kEplSuccessful;
@@ -587,12 +575,11 @@
 //
 //---------------------------------------------------------------------------
 
-EPLDLLEXPORT tEplKernel PUBLIC EplObdDefineVar(EPL_MCO_DECL_INSTANCE_PTR_
-					       tEplVarParam MEM * pVarParam_p)
+tEplKernel EplObdDefineVar(EPL_MCO_DECL_INSTANCE_PTR_ tEplVarParam *pVarParam_p)
 {
 
 	tEplKernel Ret;
-	tEplObdVarEntry MEM *pVarEntry;
+	tEplObdVarEntry *pVarEntry;
 	tEplVarParamValid VarValid;
 	tEplObdSubEntryPtr pSubindexEntry;
 
@@ -674,9 +661,8 @@
 //
 //---------------------------------------------------------------------------
 
-EPLDLLEXPORT void *PUBLIC EplObdGetObjectDataPtr(EPL_MCO_DECL_INSTANCE_PTR_
-						 unsigned int uiIndex_p,
-						 unsigned int uiSubIndex_p)
+void *EplObdGetObjectDataPtr(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+			     unsigned int uiSubIndex_p)
 {
 	tEplKernel Ret;
 	void *pData;
@@ -719,8 +705,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdRegisterUserOd(EPL_MCO_DECL_INSTANCE_PTR_
-						    tEplObdEntryPtr pUserOd_p)
+tEplKernel EplObdRegisterUserOd(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pUserOd_p)
 {
 
 	EPL_MCO_CHECK_INSTANCE_STATE();
@@ -749,10 +734,8 @@
 //
 //---------------------------------------------------------------------------
 
-EPLDLLEXPORT void PUBLIC EplObdInitVarEntry(EPL_MCO_DECL_INSTANCE_PTR_
-					    tEplObdVarEntry MEM * pVarEntry_p,
-					    tEplObdType Type_p,
-					    tEplObdSize ObdSize_p)
+void EplObdInitVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdVarEntry *pVarEntry_p,
+			tEplObdType Type_p, tEplObdSize ObdSize_p)
 {
 /*
     #if (EPL_PDO_USE_STATIC_MAPPING == FALSE)
@@ -803,9 +786,8 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplObdSize PUBLIC EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_
-						  unsigned int uiIndex_p,
-						  unsigned int uiSubIndex_p)
+tEplObdSize EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+			      unsigned int uiSubIndex_p)
 {
 	tEplKernel Ret;
 	tEplObdSize ObdSize;
@@ -845,11 +827,11 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT unsigned int PUBLIC EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR)
+unsigned int EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR)
 {
 	tEplKernel Ret;
 	tEplObdSize ObdSize;
-	BYTE bNodeId;
+	u8 bNodeId;
 
 	bNodeId = 0;
 	ObdSize = sizeof(bNodeId);
@@ -882,22 +864,21 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdSetNodeId(EPL_MCO_DECL_PTR_INSTANCE_PTR_
-					       unsigned int uiNodeId_p,
-					       tEplObdNodeIdType NodeIdType_p)
+tEplKernel EplObdSetNodeId(EPL_MCO_DECL_PTR_INSTANCE_PTR_ unsigned int uiNodeId_p,
+			   tEplObdNodeIdType NodeIdType_p)
 {
 	tEplKernel Ret;
 	tEplObdSize ObdSize;
-	BYTE fHwBool;
-	BYTE bNodeId;
+	u8 fHwBool;
+	u8 bNodeId;
 
 	// check Node Id
 	if (uiNodeId_p == EPL_C_ADR_INVALID) {
 		Ret = kEplInvalidNodeId;
 		goto Exit;
 	}
-	bNodeId = (BYTE) uiNodeId_p;
-	ObdSize = sizeof(BYTE);
+	bNodeId = (u8) uiNodeId_p;
+	ObdSize = sizeof(u8);
 	// write NodeId to OD entry
 	Ret = EplObdWriteEntry(EPL_MCO_PTR_INSTANCE_PTR_
 			       EPL_OBD_NODE_ID_INDEX,
@@ -966,10 +947,9 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_
-						 unsigned int uiIndex_p,
-						 unsigned int uiSubIndex_p,
-						 BOOL * pfEntryNumerical_p)
+tEplKernel EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+			     unsigned int uiSubIndex_p,
+			     BOOL *pfEntryNumerical_p)
 {
 	tEplKernel Ret;
 	tEplObdEntryPtr pObdEntry;
@@ -1018,16 +998,14 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_
-						   unsigned int uiIndex_p,
-						   unsigned int uiSubIndex_p,
-						   void *pDstData_p,
-						   tEplObdSize * pSize_p)
+tEplKernel EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+			       unsigned int uiSubIndex_p,
+			       void *pDstData_p, tEplObdSize *pSize_p)
 {
 	tEplKernel Ret;
 	tEplObdEntryPtr pObdEntry;
 	tEplObdSubEntryPtr pSubEntry;
-	tEplObdCbParam MEM CbParam;
+	tEplObdCbParam CbParam;
 	void *pSrcData;
 	tEplObdSize ObdSize;
 
@@ -1091,7 +1069,7 @@
 	case kEplObdTypInt8:
 	case kEplObdTypUInt8:
 		{
-			AmiSetByteToLe(pDstData_p, *((BYTE *) pSrcData));
+			AmiSetByteToLe(pDstData_p, *((u8 *) pSrcData));
 			break;
 		}
 
@@ -1099,7 +1077,7 @@
 	case kEplObdTypInt16:
 	case kEplObdTypUInt16:
 		{
-			AmiSetWordToLe(pDstData_p, *((WORD *) pSrcData));
+			AmiSetWordToLe(pDstData_p, *((u16 *) pSrcData));
 			break;
 		}
 
@@ -1107,7 +1085,7 @@
 	case kEplObdTypInt24:
 	case kEplObdTypUInt24:
 		{
-			AmiSetDword24ToLe(pDstData_p, *((DWORD *) pSrcData));
+			AmiSetDword24ToLe(pDstData_p, *((u32 *) pSrcData));
 			break;
 		}
 
@@ -1116,7 +1094,7 @@
 	case kEplObdTypUInt32:
 	case kEplObdTypReal32:
 		{
-			AmiSetDwordToLe(pDstData_p, *((DWORD *) pSrcData));
+			AmiSetDwordToLe(pDstData_p, *((u32 *) pSrcData));
 			break;
 		}
 
@@ -1124,7 +1102,7 @@
 	case kEplObdTypInt40:
 	case kEplObdTypUInt40:
 		{
-			AmiSetQword40ToLe(pDstData_p, *((QWORD *) pSrcData));
+			AmiSetQword40ToLe(pDstData_p, *((u64 *) pSrcData));
 			break;
 		}
 
@@ -1132,7 +1110,7 @@
 	case kEplObdTypInt48:
 	case kEplObdTypUInt48:
 		{
-			AmiSetQword48ToLe(pDstData_p, *((QWORD *) pSrcData));
+			AmiSetQword48ToLe(pDstData_p, *((u64 *) pSrcData));
 			break;
 		}
 
@@ -1140,7 +1118,7 @@
 	case kEplObdTypInt56:
 	case kEplObdTypUInt56:
 		{
-			AmiSetQword56ToLe(pDstData_p, *((QWORD *) pSrcData));
+			AmiSetQword56ToLe(pDstData_p, *((u64 *) pSrcData));
 			break;
 		}
 
@@ -1149,7 +1127,7 @@
 	case kEplObdTypUInt64:
 	case kEplObdTypReal64:
 		{
-			AmiSetQword64ToLe(pDstData_p, *((QWORD *) pSrcData));
+			AmiSetQword64ToLe(pDstData_p, *((u64 *) pSrcData));
 			break;
 		}
 
@@ -1199,19 +1177,17 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_
-						      unsigned int uiIndex_p,
-						      unsigned int uiSubIndex_p,
-						      void *pSrcData_p,
-						      tEplObdSize Size_p)
+tEplKernel EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+				  unsigned int uiSubIndex_p,
+				  void *pSrcData_p, tEplObdSize Size_p)
 {
 	tEplKernel Ret;
 	tEplObdEntryPtr pObdEntry;
 	tEplObdSubEntryPtr pSubEntry;
-	tEplObdCbParam MEM CbParam;
-	void MEM *pDstData;
+	tEplObdCbParam CbParam;
+	void *pDstData;
 	tEplObdSize ObdSize;
-	QWORD qwBuffer;
+	u64 qwBuffer;
 	void *pBuffer = &qwBuffer;
 
 	Ret = EplObdWriteEntryPre(EPL_MCO_INSTANCE_PTR_
@@ -1242,7 +1218,7 @@
 	case kEplObdTypInt8:
 	case kEplObdTypUInt8:
 		{
-			*((BYTE *) pBuffer) = AmiGetByteFromLe(pSrcData_p);
+			*((u8 *) pBuffer) = AmiGetByteFromLe(pSrcData_p);
 			break;
 		}
 
@@ -1250,7 +1226,7 @@
 	case kEplObdTypInt16:
 	case kEplObdTypUInt16:
 		{
-			*((WORD *) pBuffer) = AmiGetWordFromLe(pSrcData_p);
+			*((u16 *) pBuffer) = AmiGetWordFromLe(pSrcData_p);
 			break;
 		}
 
@@ -1258,7 +1234,7 @@
 	case kEplObdTypInt24:
 	case kEplObdTypUInt24:
 		{
-			*((DWORD *) pBuffer) = AmiGetDword24FromLe(pSrcData_p);
+			*((u32 *) pBuffer) = AmiGetDword24FromLe(pSrcData_p);
 			break;
 		}
 
@@ -1267,7 +1243,7 @@
 	case kEplObdTypUInt32:
 	case kEplObdTypReal32:
 		{
-			*((DWORD *) pBuffer) = AmiGetDwordFromLe(pSrcData_p);
+			*((u32 *) pBuffer) = AmiGetDwordFromLe(pSrcData_p);
 			break;
 		}
 
@@ -1275,7 +1251,7 @@
 	case kEplObdTypInt40:
 	case kEplObdTypUInt40:
 		{
-			*((QWORD *) pBuffer) = AmiGetQword40FromLe(pSrcData_p);
+			*((u64 *) pBuffer) = AmiGetQword40FromLe(pSrcData_p);
 			break;
 		}
 
@@ -1283,7 +1259,7 @@
 	case kEplObdTypInt48:
 	case kEplObdTypUInt48:
 		{
-			*((QWORD *) pBuffer) = AmiGetQword48FromLe(pSrcData_p);
+			*((u64 *) pBuffer) = AmiGetQword48FromLe(pSrcData_p);
 			break;
 		}
 
@@ -1291,7 +1267,7 @@
 	case kEplObdTypInt56:
 	case kEplObdTypUInt56:
 		{
-			*((QWORD *) pBuffer) = AmiGetQword56FromLe(pSrcData_p);
+			*((u64 *) pBuffer) = AmiGetQword56FromLe(pSrcData_p);
 			break;
 		}
 
@@ -1300,7 +1276,7 @@
 	case kEplObdTypUInt64:
 	case kEplObdTypReal64:
 		{
-			*((QWORD *) pBuffer) = AmiGetQword64FromLe(pSrcData_p);
+			*((u64 *) pBuffer) = AmiGetQword64FromLe(pSrcData_p);
 			break;
 		}
 
@@ -1345,10 +1321,9 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_
-						   unsigned int uiIndex_p,
-						   unsigned int uiSubIndex_p,
-						   tEplObdAccess * pAccessTyp_p)
+tEplKernel EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+			       unsigned int uiSubIndex_p,
+			       tEplObdAccess *pAccessTyp_p)
 {
 	tEplKernel Ret;
 	tEplObdEntryPtr pObdEntry;
@@ -1388,10 +1363,9 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplObdSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_
-				       unsigned int uiIndex_p,
-				       unsigned int uiSubindex_p,
-				       tEplObdVarEntry MEM ** ppVarEntry_p)
+tEplKernel EplObdSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+				unsigned int uiSubindex_p,
+				tEplObdVarEntry **ppVarEntry_p)
 {
 
 	tEplKernel Ret;
@@ -1435,11 +1409,11 @@
 //---------------------------------------------------------------------------
 static tEplKernel EplObdCallObjectCallback(EPL_MCO_DECL_INSTANCE_PTR_
 					   tEplObdCallback fpCallback_p,
-					   tEplObdCbParam MEM * pCbParam_p)
+					   tEplObdCbParam *pCbParam_p)
 {
 
 	tEplKernel Ret;
-	tEplObdCallback MEM fpCallback;
+	tEplObdCallback fpCallback;
 
 	// check for all API function if instance is valid
 	EPL_MCO_CHECK_INSTANCE_STATE();
@@ -1481,7 +1455,7 @@
 {
 
 	tEplObdSize DataSize;
-	void MEM *pData;
+	void *pData;
 
 	// If OD entry is defined by macro EPL_OBD_SUBINDEX_ROM_VSTRING
 	// then the current pointer is always NULL. The function
@@ -1490,8 +1464,7 @@
 
 	if (pSubIndexEntry_p->m_Type == kEplObdTypVString) {
 		// The pointer to current value can be received from EplObdGetObjectCurrentPtr()
-		pData =
-		    ((void MEM *)EplObdGetObjectCurrentPtr(pSubIndexEntry_p));
+		pData = ((void *)EplObdGetObjectCurrentPtr(pSubIndexEntry_p));
 		if (pData != NULL) {
 			DataSize =
 			    EplObdGetStrLen((void *)pData, DataSize,
@@ -1526,7 +1499,7 @@
 {
 
 	tEplObdSize StrLen = 0;
-	BYTE *pbString;
+	u8 *pbString;
 
 	if (pObjData_p == NULL) {
 		goto Exit;
@@ -1763,18 +1736,18 @@
 	case kEplObdTypInt64:
 
 		// switch to lower limit
-		pRangeData = ((signed QWORD *)pRangeData) + 1;
+		pRangeData = ((signed u64 *)pRangeData) + 1;
 
 		// check if value is to low
-		if (*((signed QWORD *)pData_p) < *((signed QWORD *)pRangeData)) {
+		if (*((signed u64 *)pData_p) < *((signed u64 *)pRangeData)) {
 			Ret = kEplObdValueTooLow;
 			break;
 		}
 		// switch to higher limit
-		pRangeData = ((signed QWORD *)pRangeData) + 1;
+		pRangeData = ((signed u64 *)pRangeData) + 1;
 
 		// check if value is to high
-		if (*((signed QWORD *)pData_p) > *((signed QWORD *)pRangeData)) {
+		if (*((signed u64 *)pData_p) > *((signed u64 *)pRangeData)) {
 			Ret = kEplObdValueTooHigh;
 		}
 
@@ -1787,20 +1760,20 @@
 	case kEplObdTypUInt64:
 
 		// switch to lower limit
-		pRangeData = ((unsigned QWORD *)pRangeData) + 1;
+		pRangeData = ((unsigned u64 *)pRangeData) + 1;
 
 		// check if value is to low
-		if (*((unsigned QWORD *)pData_p) <
-		    *((unsigned QWORD *)pRangeData)) {
+		if (*((unsigned u64 *)pData_p) <
+		    *((unsigned u64 *)pRangeData)) {
 			Ret = kEplObdValueTooLow;
 			break;
 		}
 		// switch to higher limit
-		pRangeData = ((unsigned QWORD *)pRangeData) + 1;
+		pRangeData = ((unsigned u64 *)pRangeData) + 1;
 
 		// check if value is to high
-		if (*((unsigned QWORD *)pData_p) >
-		    *((unsigned QWORD *)pRangeData)) {
+		if (*((unsigned u64 *)pData_p) >
+		    *((unsigned u64 *)pRangeData)) {
 			Ret = kEplObdValueTooHigh;
 		}
 
@@ -1870,29 +1843,28 @@
 //
 //---------------------------------------------------------------------------
 
-static tEplKernel PUBLIC EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_
-					     unsigned int uiIndex_p,
-					     unsigned int uiSubIndex_p,
-					     void *pSrcData_p,
-					     void **ppDstData_p,
-					     tEplObdSize Size_p,
-					     tEplObdEntryPtr * ppObdEntry_p,
-					     tEplObdSubEntryPtr * ppSubEntry_p,
-					     tEplObdCbParam MEM * pCbParam_p,
-					     tEplObdSize * pObdSize_p)
+static tEplKernel EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+				      unsigned int uiSubIndex_p,
+				      void *pSrcData_p,
+				      void **ppDstData_p,
+				      tEplObdSize Size_p,
+				      tEplObdEntryPtr *ppObdEntry_p,
+				      tEplObdSubEntryPtr *ppSubEntry_p,
+				      tEplObdCbParam *pCbParam_p,
+				      tEplObdSize *pObdSize_p)
 {
 
 	tEplKernel Ret;
 	tEplObdEntryPtr pObdEntry;
 	tEplObdSubEntryPtr pSubEntry;
 	tEplObdAccess Access;
-	void MEM *pDstData;
+	void *pDstData;
 	tEplObdSize ObdSize;
 	BOOL fEntryNumerical;
 
 #if (EPL_OBD_USE_STRING_DOMAIN_IN_RAM != FALSE)
-	tEplObdVStringDomain MEM MemVStringDomain;
-	void MEM *pCurrData;
+	tEplObdVStringDomain MemVStringDomain;
+	void *pCurrData;
 #endif
 
 	// check for all API function if instance is valid
@@ -1908,7 +1880,7 @@
 		goto Exit;
 	}
 	// get pointer to object data
-	pDstData = (void MEM *)EplObdGetObjectDataPtrIntern(pSubEntry);
+	pDstData = (void *)EplObdGetObjectDataPtrIntern(pSubEntry);
 
 	Access = (tEplObdAccess) pSubEntry->m_Access;
 
@@ -1933,7 +1905,7 @@
 	// adapted by user callback function, re-read
 	// this values.
 	ObdSize = EplObdGetObjectSize(pSubEntry);
-	pDstData = (void MEM *)EplObdGetObjectDataPtrIntern(pSubEntry);
+	pDstData = (void *)EplObdGetObjectDataPtrIntern(pSubEntry);
 
 	// 09-dec-2004 r.d.:
 	//      Function EplObdWriteEntry() calls new event kEplObdEvWrStringDomain
@@ -1967,23 +1939,19 @@
 		pCurrData = pSubEntry->m_pCurrent;
 		if ((pSubEntry->m_Type == kEplObdTypVString)
 		    || (pSubEntry->m_Type == kEplObdTypOString)) {
-			((tEplObdVString MEM *) pCurrData)->m_Size =
-			    MemVStringDomain.m_ObjSize;
-			((tEplObdVString MEM *) pCurrData)->m_pString =
-			    MemVStringDomain.m_pData;
+			((tEplObdVString *)pCurrData)->m_Size = MemVStringDomain.m_ObjSize;
+			((tEplObdVString *)pCurrData)->m_pString = MemVStringDomain.m_pData;
 		} else		// if (pSdosTableEntry_p->m_bObjType == kEplObdTypDomain)
 		{
-			((tEplObdVarEntry MEM *) pCurrData)->m_Size =
-			    MemVStringDomain.m_ObjSize;
-			((tEplObdVarEntry MEM *) pCurrData)->m_pData =
-			    (void MEM *)MemVStringDomain.m_pData;
+			((tEplObdVarEntry *)pCurrData)->m_Size = MemVStringDomain.m_ObjSize;
+			((tEplObdVarEntry *)pCurrData)->m_pData = (void *)MemVStringDomain.m_pData;
 		}
 
 		// Because object size and object pointer are
 		// adapted by user callback function, re-read
 		// this values.
 		ObdSize = MemVStringDomain.m_ObjSize;
-		pDstData = (void MEM *)MemVStringDomain.m_pData;
+		pDstData = (void *)MemVStringDomain.m_pData;
 	}
 #endif //#if (OBD_USE_STRING_DOMAIN_IN_RAM != FALSE)
 
@@ -2004,7 +1972,7 @@
 	}
 
 	if (pSubEntry->m_Type == kEplObdTypVString) {
-		if (((char MEM *)pSrcData_p)[Size_p - 1] == '\0') {	// last byte of source string contains null character
+		if (((char *)pSrcData_p)[Size_p - 1] == '\0') {	// last byte of source string contains null character
 
 			// reserve one byte in destination for 0-termination
 			Size_p -= 1;
@@ -2064,13 +2032,12 @@
 //
 //---------------------------------------------------------------------------
 
-static tEplKernel PUBLIC EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_
-					      tEplObdEntryPtr pObdEntry_p,
-					      tEplObdSubEntryPtr pSubEntry_p,
-					      tEplObdCbParam MEM * pCbParam_p,
-					      void *pSrcData_p,
-					      void *pDstData_p,
-					      tEplObdSize ObdSize_p)
+static tEplKernel EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pObdEntry_p,
+				       tEplObdSubEntryPtr pSubEntry_p,
+				       tEplObdCbParam *pCbParam_p,
+				       void *pSrcData_p,
+				       void *pDstData_p,
+				       tEplObdSize ObdSize_p)
 {
 
 	tEplKernel Ret;
@@ -2103,7 +2070,7 @@
 
 	// terminate string with 0
 	if (pSubEntry_p->m_Type == kEplObdTypVString) {
-		((char MEM *)pDstData_p)[ObdSize_p] = '\0';
+		((char *)pDstData_p)[ObdSize_p] = '\0';
 	}
 	// write address of destination to structure of callback parameters
 	// so callback function can change data subsequently
@@ -2123,7 +2090,7 @@
 // Function:    EplObdGetObjectSize()
 //
 // Description: function to get size of object
-//              The function determines if an object type an fixed data type (BYTE, WORD, ...)
+//              The function determines if an object type an fixed data type (u8, u16, ...)
 //              or non fixed object (string, domain). This information is used to decide
 //              if download data are stored temporary or not. For objects with fixed data length
 //              and types a value range checking can process.
@@ -2192,8 +2159,8 @@
 	case kEplObdTypDomain:
 
 		pData = (void *)pSubIndexEntry_p->m_pCurrent;
-		if ((void MEM *)pData != (void MEM *)NULL) {
-			DataSize = ((tEplObdVarEntry MEM *) pData)->m_Size;
+		if ((void *)pData != (void *)NULL) {
+			DataSize = ((tEplObdVarEntry *) pData)->m_Size;
 		}
 		break;
 
@@ -2205,21 +2172,19 @@
 		// then the current pointer is always NULL. The function
 		// returns the length of default string.
 		pData = (void *)pSubIndexEntry_p->m_pCurrent;
-		if ((void MEM *)pData != (void MEM *)NULL) {
+		if ((void *)pData != (void *)NULL) {
 			// The max. size of strings defined by STRING-Macro is stored in
 			// tEplObdVString of current value.
 			// (types tEplObdVString, tEplObdOString and tEplObdUString has the same members)
-			DataSize = ((tEplObdVString MEM *) pData)->m_Size;
+			DataSize = ((tEplObdVString *) pData)->m_Size;
 		} else {
 			// The current position is not decleared. The string
 			// is located in ROM, therefor use default pointer.
 			pData = (void *)pSubIndexEntry_p->m_pDefault;
-			if ((CONST void ROM *)pData != (CONST void ROM *)NULL) {
+			if ((const void *)pData != (const void *)NULL) {
 				// The max. size of strings defined by STRING-Macro is stored in
 				// tEplObdVString of default value.
-				DataSize =
-				    ((CONST tEplObdVString ROM *) pData)->
-				    m_Size;
+				DataSize = ((const tEplObdVString *)pData)->m_Size;
 			}
 		}
 
@@ -2229,21 +2194,19 @@
 	case kEplObdTypOString:
 
 		pData = (void *)pSubIndexEntry_p->m_pCurrent;
-		if ((void MEM *)pData != (void MEM *)NULL) {
+		if ((void *)pData != (void *)NULL) {
 			// The max. size of strings defined by STRING-Macro is stored in
 			// tEplObdVString of current value.
 			// (types tEplObdVString, tEplObdOString and tEplObdUString has the same members)
-			DataSize = ((tEplObdOString MEM *) pData)->m_Size;
+			DataSize = ((tEplObdOString *) pData)->m_Size;
 		} else {
 			// The current position is not decleared. The string
 			// is located in ROM, therefor use default pointer.
 			pData = (void *)pSubIndexEntry_p->m_pDefault;
-			if ((CONST void ROM *)pData != (CONST void ROM *)NULL) {
+			if ((const void *)pData != (const void *)NULL) {
 				// The max. size of strings defined by STRING-Macro is stored in
 				// tEplObdVString of default value.
-				DataSize =
-				    ((CONST tEplObdOString ROM *) pData)->
-				    m_Size;
+				DataSize = ((const tEplObdOString *)pData)->m_Size;
 			}
 		}
 		break;
@@ -2366,7 +2329,7 @@
 //---------------------------------------------------------------------------
 
 static tEplKernel EplObdGetVarEntry(tEplObdSubEntryPtr pSubindexEntry_p,
-				    tEplObdVarEntry MEM ** ppVarEntry_p)
+				    tEplObdVarEntry **ppVarEntry_p)
 {
 
 	tEplKernel Ret = kEplObdVarEntryNotExist;
@@ -2378,13 +2341,9 @@
 	if ((pSubindexEntry_p->m_Access & kEplObdAccVar) != 0) {
 		// check if object is an array
 		if ((pSubindexEntry_p->m_Access & kEplObdAccArray) != 0) {
-			*ppVarEntry_p =
-			    &((tEplObdVarEntry MEM *) pSubindexEntry_p->
-			      m_pCurrent)[pSubindexEntry_p->m_uiSubIndex - 1];
+			*ppVarEntry_p = &((tEplObdVarEntry *)pSubindexEntry_p->m_pCurrent)[pSubindexEntry_p->m_uiSubIndex - 1];
 		} else {
-			*ppVarEntry_p =
-			    (tEplObdVarEntry MEM *) pSubindexEntry_p->
-			    m_pCurrent;
+			*ppVarEntry_p = (tEplObdVarEntry *)pSubindexEntry_p->m_pCurrent;
 		}
 
 		Ret = kEplSuccessful;
@@ -2420,7 +2379,7 @@
 {
 
 	tEplObdEntryPtr pObdEntry;
-	tEplObdCbParam MEM CbParam;
+	tEplObdCbParam CbParam;
 	tEplKernel Ret;
 
 	// check for all API function if instance is valid
@@ -2474,16 +2433,16 @@
 //
 // Parameters:  pSubIndexEntry_p
 //
-// Return:      void MEM*
+// Return:      void *
 //
 // State:
 //
 //---------------------------------------------------------------------------
 
-static void MEM *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p)
+static void *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p)
 {
 
-	void MEM *pData;
+	void *pData;
 	unsigned int uiArrayIndex;
 	tEplObdSize Size;
 
@@ -2500,24 +2459,21 @@
 			} else {
 				Size = EplObdGetObjectSize(pSubIndexEntry_p);
 			}
-			pData = ((BYTE MEM *) pData) + (Size * uiArrayIndex);
+			pData = ((u8 *) pData) + (Size * uiArrayIndex);
 		}
 		// check if VarEntry
 		if ((pSubIndexEntry_p->m_Access & kEplObdAccVar) != 0) {
 			// The data pointer is stored in VarEntry->pData
-			pData = ((tEplObdVarEntry MEM *) pData)->m_pData;
+			pData = ((tEplObdVarEntry *) pData)->m_pData;
 		}
 		// the default pointer is stored for strings in tEplObdVString
 		else if ((pSubIndexEntry_p->m_Type == kEplObdTypVString)	/* ||
 										   (pSubIndexEntry_p->m_Type == kEplObdTypUString)    */
 			 ) {
-			pData =
-			    (void MEM *)((tEplObdVString MEM *) pData)->
-			    m_pString;
+			pData = (void *)((tEplObdVString *)pData)->m_pString;
 		} else if (pSubIndexEntry_p->m_Type == kEplObdTypOString) {
 			pData =
-			    (void MEM *)((tEplObdOString MEM *) pData)->
-			    m_pString;
+			    (void *)((tEplObdOString *)pData)->m_pString;
 		}
 	}
 
@@ -2541,7 +2497,7 @@
 //
 //---------------------------------------------------------------------------
 
-static tEplKernel EplObdGetIndexIntern(tEplObdInitParam MEM * pInitParam_p,
+static tEplKernel EplObdGetIndexIntern(tEplObdInitParam *pInitParam_p,
 				       unsigned int uiIndex_p,
 				       tEplObdEntryPtr * ppObdEntry_p)
 {
@@ -2762,9 +2718,7 @@
 //
 //---------------------------------------------------------------------------
 #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
-EPLDLLEXPORT tEplKernel PUBLIC
-EplObdSetStoreLoadObjCallback(EPL_MCO_DECL_INSTANCE_PTR_
-			      tEplObdStoreLoadObjCallback fpCallback_p)
+tEplKernel EplObdSetStoreLoadObjCallback(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdStoreLoadObjCallback fpCallback_p)
 {
 
 	EPL_MCO_CHECK_INSTANCE_STATE();
@@ -2802,26 +2756,26 @@
 	tEplObdSubEntryPtr pSubIndex;
 	unsigned int nSubIndexCount;
 	tEplObdAccess Access;
-	void MEM *pDstData;
+	void *pDstData;
 	void *pDefault;
 	tEplObdSize ObjSize;
 	tEplKernel Ret;
-	tEplObdCbStoreParam MEM CbStore;
-	tEplObdVarEntry MEM *pVarEntry;
+	tEplObdCbStoreParam CbStore;
+	tEplObdVarEntry *pVarEntry;
 
 	ASSERT(pObdEnty_p != NULL);
 
 	Ret = kEplSuccessful;
 
 	// prepare structure for STORE RESTORE callback function
-	CbStore.m_bCurrentOdPart = (BYTE) CurrentOdPart_p;
+	CbStore.m_bCurrentOdPart = (u8) CurrentOdPart_p;
 	CbStore.m_pData = NULL;
 	CbStore.m_ObjSize = 0;
 
 	// command of first action depends on direction to access
 #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
 	if (Direction_p == kEplObdDirLoad) {
-		CbStore.m_bCommand = (BYTE) kEplObdCommOpenRead;
+		CbStore.m_bCommand = (u8) kEplObdCommOpenRead;
 
 		// call callback function for previous command
 		Ret = EplObdCallStoreCallback(EPL_MCO_INSTANCE_PTR_ & CbStore);
@@ -2829,9 +2783,9 @@
 			goto Exit;
 		}
 		// set command for index and subindex loop
-		CbStore.m_bCommand = (BYTE) kEplObdCommReadObj;
+		CbStore.m_bCommand = (u8) kEplObdCommReadObj;
 	} else if (Direction_p == kEplObdDirStore) {
-		CbStore.m_bCommand = (BYTE) kEplObdCommOpenWrite;
+		CbStore.m_bCommand = (u8) kEplObdCommOpenWrite;
 
 		// call callback function for previous command
 		Ret = EplObdCallStoreCallback(EPL_MCO_INSTANCE_PTR_ & CbStore);
@@ -2839,7 +2793,7 @@
 			goto Exit;
 		}
 		// set command for index and subindex loop
-		CbStore.m_bCommand = (BYTE) kEplObdCommWriteObj;
+		CbStore.m_bCommand = (u8) kEplObdCommWriteObj;
 	}
 #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
 
@@ -2890,7 +2844,7 @@
                             }
                             else
                             {
-                                EplObdInitVarEntry ((tEplObdVarEntry MEM*) (((BYTE MEM*) pSubIndex->m_pCurrent) + (sizeof (tEplObdVarEntry) * pSubIndex->m_uiSubIndex)),
+                                EplObdInitVarEntry ((tEplObdVarEntry *) (((u8 *) pSubIndex->m_pCurrent) + (sizeof (tEplObdVarEntry) * pSubIndex->m_uiSubIndex)),
                                     pSubIndex->m_Type, ObjSize);
                             }
 */
@@ -2911,29 +2865,17 @@
 						    pSubIndex->m_pCurrent;
 						if (pDstData != NULL) {
 							// 08-dec-2004: code optimization !!!
-							//              entries ((tEplObdVStringDef ROM*) pSubIndex->m_pDefault)->m_pString
-							//              and ((tEplObdVStringDef ROM*) pSubIndex->m_pDefault)->m_Size were read
+							//              entries ((tEplObdVStringDef*) pSubIndex->m_pDefault)->m_pString
+							//              and ((tEplObdVStringDef*) pSubIndex->m_pDefault)->m_Size were read
 							//              twice. thats not necessary!
 
 							// For copying data we have to set the destination pointer to the real RAM string. This
 							// pointer to RAM string is located in default string info structure. (translated r.d.)
-							pDstData =
-							    (void MEM
-							     *)((tEplObdVStringDef ROM *) pSubIndex->m_pDefault)->m_pString;
-							ObjSize =
-							    ((tEplObdVStringDef
-							      ROM *) pSubIndex->
-							     m_pDefault)->
-							    m_Size;
+							pDstData = (void *)((tEplObdVStringDef*) pSubIndex->m_pDefault)->m_pString;
+							ObjSize = ((tEplObdVStringDef *)pSubIndex->m_pDefault)->m_Size;
 
-							((tEplObdVString MEM *)
-							 pSubIndex->
-							 m_pCurrent)->
-				     m_pString = pDstData;
-							((tEplObdVString MEM *)
-							 pSubIndex->
-							 m_pCurrent)->m_Size =
-				     ObjSize;
+							((tEplObdVString *)pSubIndex->m_pCurrent)->m_pString = pDstData;
+							((tEplObdVString *)pSubIndex->m_pCurrent)->m_Size = ObjSize;
 						}
 
 					} else if (pSubIndex->m_Type ==
@@ -2942,29 +2884,17 @@
 						    pSubIndex->m_pCurrent;
 						if (pDstData != NULL) {
 							// 08-dec-2004: code optimization !!!
-							//              entries ((tEplObdOStringDef ROM*) pSubIndex->m_pDefault)->m_pString
-							//              and ((tEplObdOStringDef ROM*) pSubIndex->m_pDefault)->m_Size were read
+							//              entries ((tEplObdOStringDef*) pSubIndex->m_pDefault)->m_pString
+							//              and ((tEplObdOStringDef*) pSubIndex->m_pDefault)->m_Size were read
 							//              twice. thats not necessary!
 
 							// For copying data we have to set the destination pointer to the real RAM string. This
 							// pointer to RAM string is located in default string info structure. (translated r.d.)
-							pDstData =
-							    (void MEM
-							     *)((tEplObdOStringDef ROM *) pSubIndex->m_pDefault)->m_pString;
-							ObjSize =
-							    ((tEplObdOStringDef
-							      ROM *) pSubIndex->
-							     m_pDefault)->
-							    m_Size;
+							pDstData = (void *)((tEplObdOStringDef *) pSubIndex->m_pDefault)->m_pString;
+							ObjSize = ((tEplObdOStringDef *)pSubIndex->m_pDefault)->m_Size;
 
-							((tEplObdOString MEM *)
-							 pSubIndex->
-							 m_pCurrent)->
-				     m_pString = pDstData;
-							((tEplObdOString MEM *)
-							 pSubIndex->
-							 m_pCurrent)->m_Size =
-				     ObjSize;
+							((tEplObdOString *)pSubIndex->m_pCurrent)->m_pString = pDstData;
+							((tEplObdOString *)pSubIndex->m_pCurrent)->m_Size = ObjSize;
 						}
 
 					}
@@ -3069,11 +2999,11 @@
 #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
 	else {
 		if (Direction_p == kEplObdDirLoad) {
-			CbStore.m_bCommand = (BYTE) kEplObdCommCloseRead;
+			CbStore.m_bCommand = (u8) kEplObdCommCloseRead;
 		} else if (Direction_p == kEplObdDirStore) {
-			CbStore.m_bCommand = (BYTE) kEplObdCommCloseWrite;
+			CbStore.m_bCommand = (u8) kEplObdCommCloseWrite;
 		} else if (Direction_p == kEplObdDirRestore) {
-			CbStore.m_bCommand = (BYTE) kEplObdCommClear;
+			CbStore.m_bCommand = (u8) kEplObdCommClear;
 		} else {
 			goto Exit;
 		}
@@ -3104,7 +3034,7 @@
 // Returns:     tEplKernel              = error code
 // ----------------------------------------------------------------------------
 
-static void EplObdCopyObjectData(void MEM * pDstData_p,
+static void EplObdCopyObjectData(void *pDstData_p,
 				 void *pSrcData_p,
 				 tEplObdSize ObjSize_p, tEplObdType ObjType_p)
 {
@@ -3135,7 +3065,7 @@
 			EPL_MEMCPY(pDstData_p, pSrcData_p, ObjSize_p);
 
 			if (ObjType_p == kEplObdTypVString) {
-				((char MEM *)pDstData_p)[StrSize] = '\0';
+				((char *)pDstData_p)[StrSize] = '\0';
 			}
 		}
 	}
@@ -3196,7 +3126,7 @@
 // ----------------------------------------------------------------------------
 #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
 static tEplKernel EplObdCallStoreCallback(EPL_MCO_DECL_INSTANCE_PTR_
-					  tEplObdCbStoreParam MEM *
+					  tEplObdCbStoreParam *
 					  pCbStoreParam_p)
 {
 
diff --git a/drivers/staging/epl/EplObd.h b/drivers/staging/epl/EplObd.h
index 88cc11e..6bb5a27 100644
--- a/drivers/staging/epl/EplObd.h
+++ b/drivers/staging/epl/EplObd.h
@@ -68,11 +68,11 @@
 
 ****************************************************************************/
 
-#include "EplInc.h"
-
 #ifndef _EPLOBD_H_
 #define _EPLOBD_H_
 
+#include "EplInc.h"
+
 // ============================================================================
 // defines
 // ============================================================================
@@ -206,7 +206,7 @@
 // -------------------------------------------------------------------------
 
 // types of objects in object dictionary
-// DS-301 defines these types as WORD
+// DS-301 defines these types as u16
 typedef enum {
 // types which are always supported
 	kEplObdTypBool = 0x0001,
@@ -255,15 +255,15 @@
 typedef signed long tEplObdInteger24;	// 0010
 typedef unsigned long tEplObdUnsigned24;	// 0016
 
-typedef signed QWORD tEplObdInteger40;	// 0012
-typedef signed QWORD tEplObdInteger48;	// 0013
-typedef signed QWORD tEplObdInteger56;	// 0014
-typedef signed QWORD tEplObdInteger64;	// 0015
+typedef s64 tEplObdInteger40;	// 0012
+typedef s64 tEplObdInteger48;	// 0013
+typedef s64 tEplObdInteger56;	// 0014
+typedef s64 tEplObdInteger64;	// 0015
 
-typedef unsigned QWORD tEplObdUnsigned40;	// 0018
-typedef unsigned QWORD tEplObdUnsigned48;	// 0019
-typedef unsigned QWORD tEplObdUnsigned56;	// 001A
-typedef unsigned QWORD tEplObdUnsigned64;	// 001B
+typedef u64 tEplObdUnsigned40;	// 0018
+typedef u64 tEplObdUnsigned48;	// 0019
+typedef u64 tEplObdUnsigned56;	// 001A
+typedef u64 tEplObdUnsigned64;	// 001B
 
 typedef double tEplObdReal64;	// 0011
 
@@ -283,22 +283,21 @@
 	kVarValidAll = 0x03	// currently only size and data are implemented and used
 } tEplVarParamValid;
 
-typedef tEplKernel(PUBLIC ROM * tEplVarCallback) (CCM_DECL_INSTANCE_HDL_
-						  void *pParam_p);
+typedef tEplKernel(*tEplVarCallback) (CCM_DECL_INSTANCE_HDL_ void *pParam_p);
 
 typedef struct {
 	tEplVarParamValid m_ValidFlag;
 	unsigned int m_uiIndex;
 	unsigned int m_uiSubindex;
 	tEplObdSize m_Size;
-	void MEM *m_pData;
+	void *m_pData;
 //    tEplVarCallback     m_fpCallback;
 //    void *       m_pArg;
 
 } tEplVarParam;
 
 typedef struct {
-	void MEM *m_pData;
+	void *m_pData;
 	tEplObdSize m_Size;
 /*
     #if (EPL_PDO_USE_STATIC_MAPPING == FALSE)
@@ -310,7 +309,7 @@
 
 typedef struct {
 	tEplObdSize m_Size;
-	BYTE *m_pString;
+	u8 *m_pString;
 
 } tEplObdOString;		// 000C
 
@@ -328,8 +327,8 @@
 
 typedef struct {
 	tEplObdSize m_Size;
-	BYTE *m_pDefString;	// $$$ d.k. it is unused, so we could delete it
-	BYTE *m_pString;
+	u8 *m_pDefString;	// $$$ d.k. it is unused, so we could delete it
+	u8 *m_pString;
 
 } tEplObdOStringDef;
 
@@ -354,7 +353,7 @@
 	tEplObdType m_Type;
 	tEplObdAccess m_Access;
 	void *m_pDefault;
-	void MEM *m_pCurrent;	// points always to RAM
+	void *m_pCurrent;	// points always to RAM
 
 } tEplObdSubEntry;
 
@@ -371,14 +370,12 @@
 	unsigned int m_uiIndex;
 	unsigned int m_uiSubIndex;
 	void *m_pArg;
-	DWORD m_dwAbortCode;
+	u32 m_dwAbortCode;
 
 } tEplObdCbParam;
 
 // define type for callback function: pParam_p points to tEplObdCbParam
-typedef tEplKernel(PUBLIC ROM * tEplObdCallback) (CCM_DECL_INSTANCE_HDL_
-						  tEplObdCbParam MEM *
-						  pParam_p);
+typedef tEplKernel(*tEplObdCallback) (CCM_DECL_INSTANCE_HDL_ tEplObdCbParam *pParam_p);
 
 // do not change the order for this struct!!!
 
@@ -417,19 +414,14 @@
 typedef struct {
 	tEplObdCommand m_bCommand;
 	tEplObdPart m_bCurrentOdPart;
-	void MEM *m_pData;
+	void *m_pData;
 	tEplObdSize m_ObjSize;
 
 } tEplObdCbStoreParam;
 
-typedef tEplKernel(PUBLIC ROM * tInitTabEntryCallback) (void MEM * pTabEntry_p,
-							unsigned int
-							uiObjIndex_p);
+typedef tEplKernel(*tInitTabEntryCallback) (void *pTabEntry_p, unsigned int uiObjIndex_p);
 
-typedef tEplKernel(PUBLIC ROM *
-		   tEplObdStoreLoadObjCallback) (CCM_DECL_INSTANCE_HDL_
-						 tEplObdCbStoreParam MEM *
-						 pCbStoreParam_p);
+typedef tEplKernel(*tEplObdStoreLoadObjCallback) (CCM_DECL_INSTANCE_HDL_ tEplObdCbStoreParam *pCbStoreParam_p);
 
 // -------------------------------------------------------------------------
 // this stucture is used for parameters for function ObdInitModuleTab()
@@ -438,8 +430,8 @@
 	unsigned int m_uiLowerObjIndex;	// lower limit of ObjIndex
 	unsigned int m_uiUpperObjIndex;	// upper limit of ObjIndex
 	tInitTabEntryCallback m_fpInitTabEntry;	// will be called if ObjIndex was found
-	void MEM *m_pTabBase;	// base address of table
-	unsigned int m_uiEntrySize;	// size of table entry      // 25-feb-2005 r.d.: expansion from BYTE to WORD necessary for PDO bit mapping
+	void *m_pTabBase;	// base address of table
+	unsigned int m_uiEntrySize;	// size of table entry      // 25-feb-2005 r.d.: expansion from u8 to u16 necessary for PDO bit mapping
 	unsigned int m_uiMaxEntries;	// max. tabel entries
 
 } tEplObdModulTabParam;
diff --git a/drivers/staging/epl/EplObdMacro.h b/drivers/staging/epl/EplObdMacro.h
index 23f2ad8..fc325bf 100644
--- a/drivers/staging/epl/EplObdMacro.h
+++ b/drivers/staging/epl/EplObdMacro.h
@@ -80,7 +80,7 @@
 
 //        #pragma message ("EPL_OBD_CREATE_ROM_DATA")
 
-#define EPL_OBD_BEGIN()                                                         static  DWORD  dwObd_OBK_g = 0x0000;
+#define EPL_OBD_BEGIN()                                                         static  u32  dwObd_OBK_g = 0x0000;
 #define EPL_OBD_END()
 
 	//---------------------------------------------------------------------------------------
@@ -102,11 +102,11 @@
 #define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val)                 static  dtyp  xDef##ind##_##sub##_g        = val;
 #define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high)     static  dtyp  xDef##ind##_##sub##_g[3]     = {val,low,high};
 #define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name)
-#define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val)                 static char  MEM szCur##ind##_##sub##_g[size+1]; \
+#define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val)                 static char  szCur##ind##_##sub##_g[size+1]; \
                                                                                         static  tEplObdVStringDef  xDef##ind##_##sub##_g = {size, val, szCur##ind##_##sub##_g};
 
-#define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size)                     static  BYTE  MEM bCur##ind##_##sub##_g[size]; \
-                                                                                        static  tEplObdOStringDef  xDef##ind##_##sub##_g = {size, ((BYTE*)""), bCur##ind##_##sub##_g};
+#define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size)                     static  u8  bCur##ind##_##sub##_g[size]; \
+                                                                                        static  tEplObdOStringDef  xDef##ind##_##sub##_g = {size, ((u8*)""), bCur##ind##_##sub##_g};
 #define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name)
 #define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val)             static  dtyp  xDef##ind##_##sub##_g        = val;
 #define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high) static  dtyp  xDef##ind##_##sub##_g[3]     = {val,low,high};
@@ -129,20 +129,20 @@
 	//---------------------------------------------------------------------------------------
 #define EPL_OBD_BEGIN_INDEX_RAM(ind,cnt,call)
 #define EPL_OBD_END_INDEX(ind)
-#define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def)         static dtyp         MEM axCur##ind##_g[cnt];
-#define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def)      static tEplObdVarEntry MEM aVarEntry##ind##_g[cnt];
-#define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name)   static tEplObdVarEntry MEM aVarEntry##ind##_g[cnt];
+#define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def)         static dtyp         axCur##ind##_g[cnt];
+#define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def)      static tEplObdVarEntry aVarEntry##ind##_g[cnt];
+#define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name)   static tEplObdVarEntry aVarEntry##ind##_g[cnt];
 
 	//---------------------------------------------------------------------------------------
-#define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val)                 static dtyp         MEM xCur##ind##_##sub##_g;
-#define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high)     static dtyp         MEM xCur##ind##_##sub##_g;
-#define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val)                 static tEplObdVString  MEM xCur##ind##_##sub##_g;
-#define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size)                     static tEplObdOString  MEM xCur##ind##_##sub##_g;
-#define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name)              static dtyp         MEM xCur##ind##_##sub##_g;
-#define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name)                           static tEplObdVarEntry MEM VarEntry##ind##_##sub##_g;
-#define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val)             static tEplObdVarEntry MEM VarEntry##ind##_##sub##_g;
-#define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high) static tEplObdVarEntry MEM VarEntry##ind##_##sub##_g;
-#define EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT(ind,sub,typ,acc,dtyp,name)          static tEplObdVarEntry MEM VarEntry##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val)                 static dtyp         xCur##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high)     static dtyp         xCur##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val)                 static tEplObdVString  xCur##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size)                     static tEplObdOString  xCur##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name)              static dtyp         xCur##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name)                           static tEplObdVarEntry VarEntry##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val)             static tEplObdVarEntry VarEntry##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high) static tEplObdVarEntry VarEntry##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT(ind,sub,typ,acc,dtyp,name)          static tEplObdVarEntry VarEntry##ind##_##sub##_g;
 
     //-------------------------------------------------------------------------------------------
 #elif defined (EPL_OBD_CREATE_SUBINDEX_TAB)
@@ -159,17 +159,17 @@
 #define EPL_OBD_END_PART()
 
 	//---------------------------------------------------------------------------------------
-#define EPL_OBD_BEGIN_INDEX_RAM(ind,cnt,call)                                   static tEplObdSubEntry MEM aObdSubEntry##ind##Ram_g[cnt]= {
+#define EPL_OBD_BEGIN_INDEX_RAM(ind,cnt,call)                                   static tEplObdSubEntry aObdSubEntry##ind##Ram_g[cnt]= {
 #define EPL_OBD_END_INDEX(ind)                                                  EPL_OBD_END_SUBINDEX()};
-#define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def)         static tEplObdSubEntry MEM aObdSubEntry##ind##Ram_g[]= { \
+#define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def)         static tEplObdSubEntry aObdSubEntry##ind##Ram_g[]= { \
                                                                                         {0, kEplObdTypUInt8, kEplObdAccCR,          &xDef##ind##_0x00_g,   NULL}, \
                                                                                         {1, typ,          (acc)|kEplObdAccArray, &xDef##ind##_0x01_g,   &axCur##ind##_g[0]}, \
                                                                                         EPL_OBD_END_SUBINDEX()};
-#define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def)      static tEplObdSubEntry MEM aObdSubEntry##ind##Ram_g[]= { \
+#define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def)      static tEplObdSubEntry aObdSubEntry##ind##Ram_g[]= { \
                                                                                         {0, kEplObdTypUInt8, kEplObdAccCR,                     &xDef##ind##_0x00_g,   NULL}, \
                                                                                         {1, typ,          (acc)|kEplObdAccArray|kEplObdAccVar, &xDef##ind##_0x01_g,   &aVarEntry##ind##_g[0]}, \
                                                                                         EPL_OBD_END_SUBINDEX()};
-#define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name)   static tEplObdSubEntry MEM aObdSubEntry##ind##Ram_g[]= { \
+#define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name)   static tEplObdSubEntry aObdSubEntry##ind##Ram_g[]= { \
                                                                                         {0, kEplObdTypUInt8, kEplObdAccCR,                     &xDef##ind##_0x00_g,   NULL}, \
                                                                                         {1, typ,          (acc)|kEplObdAccArray|kEplObdAccVar, NULL,                  &aVarEntry##ind##_g[0]}, \
                                                                                         EPL_OBD_END_SUBINDEX()};
diff --git a/drivers/staging/epl/EplObdkCal.c b/drivers/staging/epl/EplObdkCal.c
index 4c9af89..02bd722 100644
--- a/drivers/staging/epl/EplObdkCal.c
+++ b/drivers/staging/epl/EplObdkCal.c
@@ -70,7 +70,6 @@
 ****************************************************************************/
 
 #include "EplInc.h"
-#include "kernel/EplObdkCal.h"
 
 /***************************************************************************/
 /*                                                                         */
diff --git a/drivers/staging/epl/EplObdu.c b/drivers/staging/epl/EplObdu.c
index 218d152..5f1d998 100644
--- a/drivers/staging/epl/EplObdu.c
+++ b/drivers/staging/epl/EplObdu.c
@@ -121,10 +121,9 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduWriteEntry(unsigned int uiIndex_p,
-						 unsigned int uiSubIndex_p,
-						 void *pSrcData_p,
-						 tEplObdSize Size_p)
+tEplKernel EplObduWriteEntry(unsigned int uiIndex_p,
+			     unsigned int uiSubIndex_p,
+			     void *pSrcData_p, tEplObdSize Size_p)
 {
 	tEplKernel Ret;
 
@@ -153,10 +152,10 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduReadEntry(unsigned int uiIndex_p,
-						unsigned int uiSubIndex_p,
-						void *pDstData_p,
-						tEplObdSize * pSize_p)
+tEplKernel EplObduReadEntry(unsigned int uiIndex_p,
+			    unsigned int uiSubIndex_p,
+			    void *pDstData_p,
+			    tEplObdSize *pSize_p)
 {
 	tEplKernel Ret;
 
@@ -179,8 +178,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduAccessOdPart(tEplObdPart ObdPart_p,
-						   tEplObdDir Direction_p)
+tEplKernel EplObduAccessOdPart(tEplObdPart ObdPart_p, tEplObdDir Direction_p)
 {
 	tEplKernel Ret;
 
@@ -202,7 +200,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduDefineVar(tEplVarParam MEM * pVarParam_p)
+tEplKernel EplObduDefineVar(tEplVarParam *pVarParam_p)
 {
 	tEplKernel Ret;
 
@@ -226,8 +224,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT void *PUBLIC EplObduGetObjectDataPtr(unsigned int uiIndex_p,
-						  unsigned int uiSubIndex_p)
+void *EplObduGetObjectDataPtr(unsigned int uiIndex_p, unsigned int uiSubIndex_p)
 {
 	void *pData;
 
@@ -250,7 +247,7 @@
 //
 //---------------------------------------------------------------------------
 #if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
-EPLDLLEXPORT tEplKernel PUBLIC EplObduRegisterUserOd(tEplObdEntryPtr pUserOd_p)
+tEplKernel EplObduRegisterUserOd(tEplObdEntryPtr pUserOd_p)
 {
 	tEplKernel Ret;
 
@@ -275,9 +272,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT void PUBLIC EplObduInitVarEntry(tEplObdVarEntry MEM * pVarEntry_p,
-					     BYTE bType_p,
-					     tEplObdSize ObdSize_p)
+void EplObduInitVarEntry(tEplObdVarEntry *pVarEntry_p, u8 bType_p, tEplObdSize ObdSize_p)
 {
 	EplObduCalInitVarEntry(pVarEntry_p, bType_p, ObdSize_p);
 }
@@ -299,8 +294,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplObdSize PUBLIC EplObduGetDataSize(unsigned int uiIndex_p,
-						   unsigned int uiSubIndex_p)
+tEplObdSize EplObduGetDataSize(unsigned int uiIndex_p, unsigned int uiSubIndex_p)
 {
 	tEplObdSize Size;
 
@@ -323,7 +317,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT unsigned int PUBLIC EplObduGetNodeId()
+unsigned int EplObduGetNodeId(void)
 {
 	unsigned int uiNodeId;
 
@@ -347,8 +341,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduSetNodeId(unsigned int uiNodeId_p,
-						tEplObdNodeIdType NodeIdType_p)
+tEplKernel EplObduSetNodeId(unsigned int uiNodeId_p, tEplObdNodeIdType NodeIdType_p)
 {
 	tEplKernel Ret;
 
@@ -373,10 +366,9 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduGetAccessType(unsigned int uiIndex_p,
-						    unsigned int uiSubIndex_p,
-						    tEplObdAccess *
-						    pAccessTyp_p)
+tEplKernel EplObduGetAccessType(unsigned int uiIndex_p,
+				unsigned int uiSubIndex_p,
+				tEplObdAccess *pAccessTyp_p)
 {
 	tEplObdAccess AccessType;
 
@@ -410,10 +402,10 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduReadEntryToLe(unsigned int uiIndex_p,
-						    unsigned int uiSubIndex_p,
-						    void *pDstData_p,
-						    tEplObdSize * pSize_p)
+tEplKernel EplObduReadEntryToLe(unsigned int uiIndex_p,
+				unsigned int uiSubIndex_p,
+				void *pDstData_p,
+				tEplObdSize *pSize_p)
 {
 	tEplKernel Ret;
 
@@ -445,11 +437,10 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduWriteEntryFromLe(unsigned int uiIndex_p,
-						       unsigned int
-						       uiSubIndex_p,
-						       void *pSrcData_p,
-						       tEplObdSize Size_p)
+tEplKernel EplObduWriteEntryFromLe(unsigned int uiIndex_p,
+				   unsigned int uiSubIndex_p,
+				   void *pSrcData_p,
+				   tEplObdSize Size_p)
 {
 	tEplKernel Ret;
 
@@ -475,11 +466,9 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_
-						     unsigned int uiIndex_p,
-						     unsigned int uiSubindex_p,
-						     tEplObdVarEntry MEM **
-						     ppVarEntry_p)
+tEplKernel EplObduSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+				 unsigned int uiSubindex_p,
+				 tEplObdVarEntry **ppVarEntry_p)
 {
 	tEplKernel Ret;
 
diff --git a/drivers/staging/epl/EplObduCal.c b/drivers/staging/epl/EplObduCal.c
index 85b3df0..55612cf 100644
--- a/drivers/staging/epl/EplObduCal.c
+++ b/drivers/staging/epl/EplObduCal.c
@@ -121,10 +121,9 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalWriteEntry(unsigned int uiIndex_p,
-						    unsigned int uiSubIndex_p,
-						    void *pSrcData_p,
-						    tEplObdSize Size_p)
+tEplKernel EplObduCalWriteEntry(unsigned int uiIndex_p,
+				unsigned int uiSubIndex_p,
+				void *pSrcData_p, tEplObdSize Size_p)
 {
 	tEplKernel Ret;
 
@@ -155,10 +154,9 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalReadEntry(unsigned int uiIndex_p,
-						   unsigned int uiSubIndex_p,
-						   void *pDstData_p,
-						   tEplObdSize * pSize_p)
+tEplKernel EplObduCalReadEntry(unsigned int uiIndex_p,
+			       unsigned int uiSubIndex_p,
+			       void *pDstData_p, tEplObdSize *pSize_p)
 {
 	tEplKernel Ret;
 
@@ -185,8 +183,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalAccessOdPart(tEplObdPart ObdPart_p,
-						      tEplObdDir Direction_p)
+tEplKernel EplObduCalAccessOdPart(tEplObdPart ObdPart_p, tEplObdDir Direction_p)
 {
 	tEplKernel Ret;
 
@@ -212,8 +209,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalDefineVar(tEplVarParam MEM *
-						   pVarParam_p)
+tEplKernel EplObduCalDefineVar(tEplVarParam *pVarParam_p)
 {
 	tEplKernel Ret;
 
@@ -240,8 +236,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT void *PUBLIC EplObduCalGetObjectDataPtr(unsigned int uiIndex_p,
-						     unsigned int uiSubIndex_p)
+void *EplObduCalGetObjectDataPtr(unsigned int uiIndex_p, unsigned int uiSubIndex_p)
 {
 	void *pData;
 
@@ -268,8 +263,7 @@
 //
 //---------------------------------------------------------------------------
 #if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalRegisterUserOd(tEplObdEntryPtr
-							pUserOd_p)
+tEplKernel EplObduCalRegisterUserOd(tEplObdEntryPtr pUserOd_p)
 {
 	tEplKernel Ret;
 
@@ -298,9 +292,8 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT void PUBLIC EplObduCalInitVarEntry(tEplObdVarEntry MEM *
-						pVarEntry_p, BYTE bType_p,
-						tEplObdSize ObdSize_p)
+void EplObduCalInitVarEntry(tEplObdVarEntry *pVarEntry_p, u8 bType_p,
+			    tEplObdSize ObdSize_p)
 {
 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
 	EplObdInitVarEntry(pVarEntry_p, bType_p, ObdSize_p);
@@ -324,8 +317,8 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplObdSize PUBLIC EplObduCalGetDataSize(unsigned int uiIndex_p,
-						      unsigned int uiSubIndex_p)
+tEplObdSize EplObduCalGetDataSize(unsigned int uiIndex_p,
+				  unsigned int uiSubIndex_p)
 {
 	tEplObdSize Size;
 
@@ -352,7 +345,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT unsigned int PUBLIC EplObduCalGetNodeId()
+unsigned int EplObduCalGetNodeId(void)
 {
 	unsigned int uiNodeId;
 
@@ -380,9 +373,8 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalSetNodeId(unsigned int uiNodeId_p,
-						   tEplObdNodeIdType
-						   NodeIdType_p)
+tEplKernel EplObduCalSetNodeId(unsigned int uiNodeId_p,
+			       tEplObdNodeIdType NodeIdType_p)
 {
 	tEplKernel Ret;
 
@@ -411,11 +403,9 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalGetAccessType(unsigned int uiIndex_p,
-						       unsigned int
-						       uiSubIndex_p,
-						       tEplObdAccess *
-						       pAccessTyp_p)
+tEplKernel EplObduCalGetAccessType(unsigned int uiIndex_p,
+				   unsigned int uiSubIndex_p,
+				   tEplObdAccess *pAccessTyp_p)
 {
 	tEplObdAccess AccesType;
 
@@ -447,11 +437,10 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalReadEntryToLe(unsigned int uiIndex_p,
-						       unsigned int
-						       uiSubIndex_p,
-						       void *pDstData_p,
-						       tEplObdSize * pSize_p)
+tEplKernel EplObduCalReadEntryToLe(unsigned int uiIndex_p,
+				   unsigned int uiSubIndex_p,
+				   void *pDstData_p,
+				   tEplObdSize *pSize_p)
 {
 	tEplKernel Ret;
 
@@ -481,12 +470,9 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalWriteEntryFromLe(unsigned int
-							  uiIndex_p,
-							  unsigned int
-							  uiSubIndex_p,
-							  void *pSrcData_p,
-							  tEplObdSize Size_p)
+tEplKernel EplObduCalWriteEntryFromLe(unsigned int uiIndex_p,
+				      unsigned int uiSubIndex_p,
+				      void *pSrcData_p, tEplObdSize Size_p)
 {
 	tEplKernel Ret;
 
@@ -514,10 +500,9 @@
 // State:
 //
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC
-EplObduCalSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
-			 unsigned int uiSubindex_p,
-			 tEplObdVarEntry MEM ** ppVarEntry_p)
+tEplKernel EplObduCalSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+				    unsigned int uiSubindex_p,
+				    tEplObdVarEntry **ppVarEntry_p)
 {
 	tEplKernel Ret;
 
diff --git a/drivers/staging/epl/EplObjDef.h b/drivers/staging/epl/EplObjDef.h
deleted file mode 100644
index 7713125..0000000
--- a/drivers/staging/epl/EplObjDef.h
+++ /dev/null
@@ -1,208 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  defines objdict dictionary
-
-  License:
-
-    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 SYSTEC electronic GmbH nor the names of its
-       contributors may be used to endorse or promote products derived
-       from this software without prior written permission. For written
-       permission, please contact info@systec-electronic.com.
-
-    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 HOLDERS 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.
-
-    Severability Clause:
-
-        If a provision of this License is or becomes illegal, invalid or
-        unenforceable in any jurisdiction, that shall not affect:
-        1. the validity or enforceability in that jurisdiction of any other
-           provision of this License; or
-        2. the validity or enforceability in other jurisdictions of that or
-           any other provision of this License.
-
-  -------------------------------------------------------------------------
-
-                $RCSfile: EplObjDef.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.4 $  $Date: 2008/04/17 21:36:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/06    k.t.:   take ObjDef.h from CANopen and modify for EPL
-
-****************************************************************************/
-
-#ifndef _EPLOBJDEF_H_
-#define _EPLOBJDEF_H_
-
-//---------------------------------------------------------------------------
-// security checks
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// macros to help building OD
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-#if (defined (EPL_OBD_USE_VARIABLE_SUBINDEX_TAB) && (EPL_OBD_USE_VARIABLE_SUBINDEX_TAB != FALSE))
-
-#define CCM_SUBINDEX_RAM_ONLY(a)    a;
-#define CCM_SUBINDEX_RAM_ONEOF(a,b) a
-
-#else
-
-#define CCM_SUBINDEX_RAM_ONLY(a)
-#define CCM_SUBINDEX_RAM_ONEOF(a,b) b
-
-#endif
-
-//---------------------------------------------------------------------------
-// To prevent unused memory in subindex tables we need this macro.
-// But not all compilers support to preset the last struct value followed by a comma.
-// Compilers which does not support a comma after last struct value has to place in a dummy subindex.
-#if ((DEV_SYSTEM & _DEV_COMMA_EXT_) != 0)
-
-#define EPL_OBD_END_SUBINDEX()
-#define EPL_OBD_MAX_ARRAY_SUBENTRIES    2
-
-#else
-
-#define EPL_OBD_END_SUBINDEX()          {0,0,0,NULL,NULL}
-#define EPL_OBD_MAX_ARRAY_SUBENTRIES    3
-
-#endif
-
-//---------------------------------------------------------------------------
-//---------------------------------------------------------------------------
-// globale vars
-//---------------------------------------------------------------------------
-//---------------------------------------------------------------------------
-
-// -------------------------------------------------------------------------
-// creation of data in ROM memory
-// -------------------------------------------------------------------------
-#define EPL_OBD_CREATE_ROM_DATA
-#include "objdict.h"
-#undef EPL_OBD_CREATE_ROM_DATA
-
-// -------------------------------------------------------------------------
-// creation of data in RAM memory
-// -------------------------------------------------------------------------
-
-#define EPL_OBD_CREATE_RAM_DATA
-#include "objdict.h"
-#undef EPL_OBD_CREATE_RAM_DATA
-
-// -------------------------------------------------------------------------
-// creation of subindex tables in ROM and RAM
-// -------------------------------------------------------------------------
-
-#define EPL_OBD_CREATE_SUBINDEX_TAB
-#include "objdict.h"
-#undef EPL_OBD_CREATE_SUBINDEX_TAB
-
-// -------------------------------------------------------------------------
-// creation of index tables for generic, manufacturer and device part
-// -------------------------------------------------------------------------
-
-#define EPL_OBD_CREATE_INDEX_TAB
-#include "objdict.h"
-#undef EPL_OBD_CREATE_INDEX_TAB
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-// ----------------------------------------------------------------------------
-//
-// Function:    EPL_OBD_INIT_RAM_NAME()
-//
-// Description: function to initialize object dictionary
-//
-// Parameters:  pInitParam_p    = pointer to init param struct of Epl
-//
-// Returns:     tEplKernel      = error code
-//
-// State:
-//
-// ----------------------------------------------------------------------------
-
-EPLDLLEXPORT tEplKernel PUBLIC EPL_OBD_INIT_RAM_NAME(tEplObdInitParam MEM *
-						     pInitParam_p)
-{
-
-	tEplObdInitParam MEM *pInitParam = pInitParam_p;
-
-	// check if pointer to parameter structure is valid
-	// if not then only copy subindex tables below
-	if (pInitParam != NULL) {
-		// at first delete all parameters (all pointers will be set zu NULL)
-		EPL_MEMSET(pInitParam, 0, sizeof(tEplObdInitParam));
-
-#define EPL_OBD_CREATE_INIT_FUNCTION
-		{
-			// inserts code to init pointer to index tables
-#include "objdict.h"
-		}
-#undef EPL_OBD_CREATE_INIT_FUNCTION
-
-#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
-		{
-			// to begin no user OD is defined
-			pInitParam_p->m_pUserPart = NULL;
-		}
-#endif
-	}
-#define EPL_OBD_CREATE_INIT_SUBINDEX
-	{
-		// inserts code to copy subindex tables
-#include "objdict.h"
-	}
-#undef EPL_OBD_CREATE_INIT_SUBINDEX
-
-	return kEplSuccessful;
-
-}
-
-#endif // _EPLOBJDEF_H_
-
-// Die letzte Zeile muß unbedingt eine leere Zeile sein, weil manche Compiler
-// damit ein Problem haben, wenn das nicht so ist (z.B. GNU oder Borland C++ Builder).
diff --git a/drivers/staging/epl/EplPdo.h b/drivers/staging/epl/EplPdo.h
index d22ac86..0b3ad5b 100644
--- a/drivers/staging/epl/EplPdo.h
+++ b/drivers/staging/epl/EplPdo.h
@@ -90,8 +90,8 @@
 
 typedef struct {
 	void *m_pVar;
-	WORD m_wOffset;		// in Bits
-	WORD m_wSize;		// in Bits
+	u16 m_wOffset;		// in Bits
+	u16 m_wSize;		// in Bits
 	BOOL m_fNumeric;	// numeric value -> use AMI functions
 
 } tEplPdoMapping;
@@ -104,7 +104,7 @@
 	//               TPDO: 0x00=PRes, MN: CnNodeId=PReq
 
 	BOOL m_fTxRx;
-	BYTE m_bMappingVersion;
+	u8 m_bMappingVersion;
 	unsigned int m_uiMaxMappingEntries;	// maximum number of mapping entries, i.e. size of m_aPdoMapping
 	tEplPdoMapping m_aPdoMapping[1];
 
diff --git a/drivers/staging/epl/EplPdok.c b/drivers/staging/epl/EplPdok.c
index 15999b4..db9b3f0 100644
--- a/drivers/staging/epl/EplPdok.c
+++ b/drivers/staging/epl/EplPdok.c
@@ -73,11 +73,6 @@
 #include "kernel/EplEventk.h"
 #include "kernel/EplObdk.h"
 
-#if (DEV_SYSTEM == _DEV_GNU_CF548X_)
-#include "plccore.h"
-#define PDO_LED 0x08
-#endif
-
 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
 
 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) == 0)
@@ -226,11 +221,6 @@
 	tEplKernel Ret = kEplSuccessful;
 	tEplEvent Event;
 
-#if (DEV_SYSTEM == _DEV_GNU_CF548X_)
-	// reset LED
-//    MCF_GPIO_PODR_PCIBG &= ~PDO_LED;  // Level
-#endif
-
 	Event.m_EventSink = kEplEventSinkPdok;
 	Event.m_EventType = kEplEventTypePdoRx;
 	// limit copied data to size of PDO (because from some CNs the frame is larger than necessary)
@@ -238,11 +228,6 @@
 	Event.m_pArg = pFrameInfo_p->m_pFrame;
 	Ret = EplEventkPost(&Event);
 
-#if (DEV_SYSTEM == _DEV_GNU_CF548X_)
-	// set LED
-//    MCF_GPIO_PODR_PCIBG |= PDO_LED;  // Level
-#endif
-
 	return Ret;
 }
 
@@ -269,22 +254,12 @@
 	tEplKernel Ret = kEplSuccessful;
 	tEplEvent Event;
 
-#if (DEV_SYSTEM == _DEV_GNU_CF548X_)
-	// reset LED
-	MCF_GPIO_PODR_PCIBG &= ~PDO_LED;	// Level
-#endif
-
 	Event.m_EventSink = kEplEventSinkPdok;
 	Event.m_EventType = kEplEventTypePdoTx;
 	Event.m_uiSize = sizeof(tEplFrameInfo);
 	Event.m_pArg = pFrameInfo_p;
 	Ret = EplEventkPost(&Event);
 
-#if (DEV_SYSTEM == _DEV_GNU_CF548X_)
-	// set LED
-	MCF_GPIO_PODR_PCIBG |= PDO_LED;	// Level
-#endif
-
 	return Ret;
 }
 
@@ -339,19 +314,19 @@
 tEplKernel EplPdokProcess(tEplEvent * pEvent_p)
 {
 	tEplKernel Ret = kEplSuccessful;
-	WORD wPdoSize;
-	WORD wBitOffset;
-	WORD wBitSize;
-	WORD wVarSize;
-	QWORD qwObjectMapping;
-	BYTE bMappSubindex;
-	BYTE bObdSubindex;
-	WORD wObdMappIndex;
-	WORD wObdCommIndex;
-	WORD wPdoId;
-	BYTE bObdData;
-	BYTE bObjectCount;
-	BYTE bFrameData;
+	u16 wPdoSize;
+	u16 wBitOffset;
+	u16 wBitSize;
+	u16 wVarSize;
+	u64 qwObjectMapping;
+	u8 bMappSubindex;
+	u8 bObdSubindex;
+	u16 wObdMappIndex;
+	u16 wObdCommIndex;
+	u16 wPdoId;
+	u8 bObdData;
+	u8 bObjectCount;
+	u8 bFrameData;
 	BOOL fValid;
 	tEplObdSize ObdSize;
 	tEplFrame *pFrame;
@@ -448,7 +423,7 @@
 			// process mapping
 			for (bMappSubindex = 1; bMappSubindex <= bObjectCount;
 			     bMappSubindex++) {
-				ObdSize = 8;	// QWORD
+				ObdSize = 8;	// u64
 				// read object mapping from OD
 				Ret =
 				    EplObdReadEntry(wObdMappIndex,
@@ -463,16 +438,16 @@
 				}
 				// decode object mapping
 				wObdCommIndex =
-				    (WORD) (qwObjectMapping &
+				    (u16) (qwObjectMapping &
 					    0x000000000000FFFFLL);
 				bObdSubindex =
-				    (BYTE) ((qwObjectMapping &
+				    (u8) ((qwObjectMapping &
 					     0x0000000000FF0000LL) >> 16);
 				wBitOffset =
-				    (WORD) ((qwObjectMapping &
+				    (u16) ((qwObjectMapping &
 					     0x0000FFFF00000000LL) >> 32);
 				wBitSize =
-				    (WORD) ((qwObjectMapping &
+				    (u16) ((qwObjectMapping &
 					     0xFFFF000000000000LL) >> 48);
 
 				// check if object exceeds PDO size
@@ -578,7 +553,7 @@
 			// process mapping
 			for (bMappSubindex = 1; bMappSubindex <= bObjectCount;
 			     bMappSubindex++) {
-				ObdSize = 8;	// QWORD
+				ObdSize = 8;	// u64
 				// read object mapping from OD
 				Ret =
 				    EplObdReadEntry(wObdMappIndex,
@@ -593,21 +568,21 @@
 				}
 				// decode object mapping
 				wObdCommIndex =
-				    (WORD) (qwObjectMapping &
+				    (u16) (qwObjectMapping &
 					    0x000000000000FFFFLL);
 				bObdSubindex =
-				    (BYTE) ((qwObjectMapping &
+				    (u8) ((qwObjectMapping &
 					     0x0000000000FF0000LL) >> 16);
 				wBitOffset =
-				    (WORD) ((qwObjectMapping &
+				    (u16) ((qwObjectMapping &
 					     0x0000FFFF00000000LL) >> 32);
 				wBitSize =
-				    (WORD) ((qwObjectMapping &
+				    (u16) ((qwObjectMapping &
 					     0xFFFF000000000000LL) >> 48);
 
 				// calculate max PDO size
 				ObdSize = wBitSize >> 3;
-				wVarSize = (wBitOffset >> 3) + (WORD) ObdSize;
+				wVarSize = (wBitOffset >> 3) + (u16) ObdSize;
 				if ((unsigned int)(wVarSize + 24) > pFrameInfo->m_uiFrameSize) {	// TPDO is too short
 					// $$$ raise PDO error, set Ret
 					goto Exit;
diff --git a/drivers/staging/epl/EplPdou.c b/drivers/staging/epl/EplPdou.c
index e7b1065..d6d0624 100644
--- a/drivers/staging/epl/EplPdou.c
+++ b/drivers/staging/epl/EplPdou.c
@@ -149,18 +149,18 @@
 // local function prototypes
 //---------------------------------------------------------------------------
 
-static tEplKernel EplPdouCheckPdoValidity(tEplObdCbParam MEM * pParam_p,
+static tEplKernel EplPdouCheckPdoValidity(tEplObdCbParam *pParam_p,
 					  unsigned int uiIndex_p);
 
-static void EplPdouDecodeObjectMapping(QWORD qwObjectMapping_p,
+static void EplPdouDecodeObjectMapping(u64 qwObjectMapping_p,
 				       unsigned int *puiIndex_p,
 				       unsigned int *puiSubIndex_p,
 				       unsigned int *puiBitOffset_p,
 				       unsigned int *puiBitSize_p);
 
-static tEplKernel EplPdouCheckObjectMapping(QWORD qwObjectMapping_p,
+static tEplKernel EplPdouCheckObjectMapping(u64 qwObjectMapping_p,
 					    tEplObdAccess AccessType_p,
-					    DWORD * pdwAbortCode_p,
+					    u32 * pdwAbortCode_p,
 					    unsigned int *puiPdoSize_p);
 
 //=========================================================================//
@@ -226,18 +226,18 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplPdouCbObdAccess(tEplObdCbParam MEM * pParam_p)
+tEplKernel EplPdouCbObdAccess(tEplObdCbParam *pParam_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 	unsigned int uiPdoId;
 	unsigned int uiIndexType;
 	tEplObdSize ObdSize;
-	BYTE bObjectCount;
-	QWORD qwObjectMapping;
+	u8 bObjectCount;
+	u64 qwObjectMapping;
 	tEplObdAccess AccessType;
-	BYTE bMappSubindex;
+	u8 bMappSubindex;
 	unsigned int uiCurPdoSize;
-	WORD wMaxPdoSize;
+	u16 wMaxPdoSize;
 	unsigned int uiSubIndex;
 
 	// fetch PDO ID
@@ -293,7 +293,7 @@
 	if (pParam_p->m_uiSubIndex == 0) {	// object mapping count accessed
 
 		// PDO is enabled or disabled
-		bObjectCount = *((BYTE *) pParam_p->m_pArg);
+		bObjectCount = *((u8 *) pParam_p->m_pArg);
 
 		if (bObjectCount == 0) {	// PDO shall be disabled
 
@@ -326,7 +326,7 @@
 		for (bMappSubindex = 1; bMappSubindex <= bObjectCount;
 		     bMappSubindex++) {
 			// read object mapping from OD
-			ObdSize = sizeof(qwObjectMapping);	// QWORD
+			ObdSize = sizeof(qwObjectMapping);	// u64
 			Ret = EplObduReadEntry(pParam_p->m_uiIndex,
 					       bMappSubindex, &qwObjectMapping,
 					       &ObdSize);
@@ -360,7 +360,7 @@
 		}
 		// check existence of object and validity of object length
 
-		qwObjectMapping = *((QWORD *) pParam_p->m_pArg);
+		qwObjectMapping = *((u64 *) pParam_p->m_pArg);
 
 		Ret = EplPdouCheckObjectMapping(qwObjectMapping,
 						AccessType,
@@ -394,12 +394,12 @@
 //
 //---------------------------------------------------------------------------
 
-static tEplKernel EplPdouCheckPdoValidity(tEplObdCbParam MEM * pParam_p,
+static tEplKernel EplPdouCheckPdoValidity(tEplObdCbParam *pParam_p,
 					  unsigned int uiIndex_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 	tEplObdSize ObdSize;
-	BYTE bObjectCount;
+	u8 bObjectCount;
 
 	ObdSize = 1;
 	// read number of mapped objects from OD; this indicates if the PDO is valid
@@ -439,7 +439,7 @@
 //
 //---------------------------------------------------------------------------
 
-static void EplPdouDecodeObjectMapping(QWORD qwObjectMapping_p,
+static void EplPdouDecodeObjectMapping(u64 qwObjectMapping_p,
 				       unsigned int *puiIndex_p,
 				       unsigned int *puiSubIndex_p,
 				       unsigned int *puiBitOffset_p,
@@ -480,9 +480,9 @@
 //
 //---------------------------------------------------------------------------
 
-static tEplKernel EplPdouCheckObjectMapping(QWORD qwObjectMapping_p,
+static tEplKernel EplPdouCheckObjectMapping(u64 qwObjectMapping_p,
 					    tEplObdAccess AccessType_p,
-					    DWORD * pdwAbortCode_p,
+					    u32 * pdwAbortCode_p,
 					    unsigned int *puiPdoSize_p)
 {
 	tEplKernel Ret = kEplSuccessful;
diff --git a/drivers/staging/epl/EplSdo.h b/drivers/staging/epl/EplSdo.h
index 1cb3f2d..8002e0c 100644
--- a/drivers/staging/epl/EplSdo.h
+++ b/drivers/staging/epl/EplSdo.h
@@ -116,20 +116,18 @@
 
 // callback function pointer for Protocol Abstraction Layer to call
 // asynchronuus SDO Sequence Layer
-typedef tEplKernel(PUBLIC * tEplSequLayerReceiveCb) (tEplSdoConHdl ConHdl_p,
-						     tEplAsySdoSeq *
-						     pSdoSeqData_p,
-						     unsigned int uiDataSize_p);
+typedef tEplKernel(*tEplSequLayerReceiveCb) (tEplSdoConHdl ConHdl_p,
+					     tEplAsySdoSeq *pSdoSeqData_p,
+					     unsigned int uiDataSize_p);
 
 // handle between asynchronuus SDO Sequence Layer and SDO Command layer
 typedef unsigned int tEplSdoSeqConHdl;
 
 // callback function pointer for asynchronuus SDO Sequence Layer to call
 // SDO Command layer for received data
-typedef tEplKernel(PUBLIC *
-		   tEplSdoComReceiveCb) (tEplSdoSeqConHdl SdoSeqConHdl_p,
-					 tEplAsySdoCom * pAsySdoCom_p,
-					 unsigned int uiDataSize_p);
+typedef tEplKernel(* tEplSdoComReceiveCb) (tEplSdoSeqConHdl SdoSeqConHdl_p,
+					   tEplAsySdoCom *pAsySdoCom_p,
+					   unsigned int uiDataSize_p);
 
 // status of connection
 typedef enum {
@@ -143,9 +141,8 @@
 
 // callback function pointer for asynchronuus SDO Sequence Layer to call
 // SDO Command layer for connection status
-typedef tEplKernel(PUBLIC * tEplSdoComConCb) (tEplSdoSeqConHdl SdoSeqConHdl_p,
-					      tEplAsySdoConState
-					      AsySdoConState_p);
+typedef tEplKernel(* tEplSdoComConCb) (tEplSdoSeqConHdl SdoSeqConHdl_p,
+				       tEplAsySdoConState AsySdoConState_p);
 
 // handle between  SDO Command layer and application
 typedef unsigned int tEplSdoComConHdl;
@@ -210,7 +207,7 @@
 typedef struct {
 	tEplSdoComConHdl m_SdoComConHdl;
 	tEplSdoComConState m_SdoComConState;
-	DWORD m_dwAbortCode;
+	u32 m_dwAbortCode;
 	tEplSdoAccessType m_SdoAccessType;
 	unsigned int m_uiNodeId;	// NodeId of the target
 	unsigned int m_uiTargetIndex;	// index which was accessed
@@ -221,8 +218,7 @@
 } tEplSdoComFinished;
 
 // callback function pointer to inform application about connection
-typedef tEplKernel(PUBLIC * tEplSdoFinishedCb) (tEplSdoComFinished *
-						pSdoComFinished_p);
+typedef tEplKernel(* tEplSdoFinishedCb) (tEplSdoComFinished *pSdoComFinished_p);
 
 // structure to init SDO transfer to Read or Write by Index
 typedef struct {
diff --git a/drivers/staging/epl/EplSdoAsndu.c b/drivers/staging/epl/EplSdoAsndu.c
index 05a00c9..aa8bdef 100644
--- a/drivers/staging/epl/EplSdoAsndu.c
+++ b/drivers/staging/epl/EplSdoAsndu.c
@@ -110,7 +110,7 @@
 // local function prototypes
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplSdoAsnduCb(tEplFrameInfo * pFrameInfo_p);
+tEplKernel EplSdoAsnduCb(tEplFrameInfo *pFrameInfo_p);
 
 /***************************************************************************/
 /*                                                                         */
@@ -149,7 +149,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsnduInit(tEplSequLayerReceiveCb fpReceiveCb_p)
+tEplKernel EplSdoAsnduInit(tEplSequLayerReceiveCb fpReceiveCb_p)
 {
 	tEplKernel Ret;
 
@@ -176,7 +176,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsnduAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
+tEplKernel EplSdoAsnduAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
 {
 	tEplKernel Ret;
 
@@ -218,7 +218,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsnduDelInstance()
+tEplKernel EplSdoAsnduDelInstance(void)
 {
 	tEplKernel Ret;
 
@@ -251,8 +251,8 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsnduInitCon(tEplSdoConHdl * pSdoConHandle_p,
-				     unsigned int uiTargetNodeId_p)
+tEplKernel EplSdoAsnduInitCon(tEplSdoConHdl *pSdoConHandle_p,
+			      unsigned int uiTargetNodeId_p)
 {
 	tEplKernel Ret;
 	unsigned int uiCount;
@@ -319,9 +319,9 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsnduSendData(tEplSdoConHdl SdoConHandle_p,
-				      tEplFrame * pSrcData_p,
-				      DWORD dwDataSize_p)
+tEplKernel EplSdoAsnduSendData(tEplSdoConHdl SdoConHandle_p,
+			       tEplFrame *pSrcData_p,
+			       u32 dwDataSize_p)
 {
 	tEplKernel Ret;
 	unsigned int uiArray;
@@ -339,10 +339,10 @@
 	// own node id not needed -> filled by DLL
 
 	// set message type
-	AmiSetByteToLe(&pSrcData_p->m_le_bMessageType, (BYTE) kEplMsgTypeAsnd);	// ASnd == 0x06
+	AmiSetByteToLe(&pSrcData_p->m_le_bMessageType, (u8) kEplMsgTypeAsnd);	// ASnd == 0x06
 	// target node id
 	AmiSetByteToLe(&pSrcData_p->m_le_bDstNodeId,
-		       (BYTE) SdoAsndInstance_g.
+		       (u8) SdoAsndInstance_g.
 		       m_auiSdoAsndConnection[uiArray]);
 	// set source-nodeid (filled by DLL 0)
 	AmiSetByteToLe(&pSrcData_p->m_le_bSrcNodeId, 0x00);
@@ -379,7 +379,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsnduDelCon(tEplSdoConHdl SdoConHandle_p)
+tEplKernel EplSdoAsnduDelCon(tEplSdoConHdl SdoConHandle_p)
 {
 	tEplKernel Ret;
 	unsigned int uiArray;
@@ -422,7 +422,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsnduCb(tEplFrameInfo * pFrameInfo_p)
+tEplKernel EplSdoAsnduCb(tEplFrameInfo *pFrameInfo_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 	unsigned int uiCount;
diff --git a/drivers/staging/epl/EplSdoAsySequ.c b/drivers/staging/epl/EplSdoAsySequ.c
index 6b6a997..256d708 100644
--- a/drivers/staging/epl/EplSdoAsySequ.c
+++ b/drivers/staging/epl/EplSdoAsySequ.c
@@ -128,11 +128,11 @@
 
 // structure for History-Buffer
 typedef struct {
-	BYTE m_bFreeEntries;
-	BYTE m_bWrite;		// index of the next free buffer entry
-	BYTE m_bAck;		// index of the next message which should become acknowledged
-	BYTE m_bRead;		// index between m_bAck and m_bWrite to the next message for retransmission
-	BYTE m_aabHistoryFrame[EPL_SDO_HISTORY_SIZE]
+	u8 m_bFreeEntries;
+	u8 m_bWrite;		// index of the next free buffer entry
+	u8 m_bAck;		// index of the next message which should become acknowledged
+	u8 m_bRead;		// index between m_bAck and m_bWrite to the next message for retransmission
+	u8 m_aabHistoryFrame[EPL_SDO_HISTORY_SIZE]
 	    [EPL_SEQ_HISTROY_FRAME_SIZE];
 	unsigned int m_auiFrameSize[EPL_SDO_HISTORY_SIZE];
 
@@ -152,8 +152,8 @@
 typedef struct {
 	tEplSdoConHdl m_ConHandle;
 	tEplAsySdoState m_SdoState;
-	BYTE m_bRecSeqNum;	// name from view of the communication partner
-	BYTE m_bSendSeqNum;	// name from view of the communication partner
+	u8 m_bRecSeqNum;	// name from view of the communication partner
+	u8 m_bSendSeqNum;	// name from view of the communication partner
 	tEplAsySdoConHistory m_SdoConHistory;
 	tEplTimerHdl m_EplTimerHdl;
 	unsigned int m_uiRetryCount;	// retry counter
@@ -203,9 +203,9 @@
 					     unsigned int uiDataSize_p,
 					     tEplFrame * pEplFrame_p);
 
-tEplKernel PUBLIC EplSdoAsyReceiveCb(tEplSdoConHdl ConHdl_p,
-				     tEplAsySdoSeq * pSdoSeqData_p,
-				     unsigned int uiDataSize_p);
+tEplKernel EplSdoAsyReceiveCb(tEplSdoConHdl ConHdl_p,
+			      tEplAsySdoSeq *pSdoSeqData_p,
+			      unsigned int uiDataSize_p);
 
 static tEplKernel EplSdoAsyInitHistory(void);
 
@@ -214,7 +214,7 @@
 					     unsigned int uiSize_p);
 
 static tEplKernel EplSdoAsyAckFrameToHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
-					     BYTE bRecSeqNumber_p);
+					     u8 bRecSeqNumber_p);
 
 static tEplKernel EplSdoAsyReadFromHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
 					   tEplFrame ** ppFrame_p,
@@ -267,8 +267,8 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsySeqInit(tEplSdoComReceiveCb fpSdoComCb_p,
-				   tEplSdoComConCb fpSdoComConCb_p)
+tEplKernel EplSdoAsySeqInit(tEplSdoComReceiveCb fpSdoComCb_p,
+			    tEplSdoComConCb fpSdoComConCb_p)
 {
 	tEplKernel Ret;
 
@@ -297,8 +297,8 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsySeqAddInstance(tEplSdoComReceiveCb fpSdoComCb_p,
-					  tEplSdoComConCb fpSdoComConCb_p)
+tEplKernel EplSdoAsySeqAddInstance(tEplSdoComReceiveCb fpSdoComCb_p,
+				   tEplSdoComConCb fpSdoComConCb_p)
 {
 	tEplKernel Ret;
 
@@ -380,7 +380,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsySeqDelInstance()
+tEplKernel EplSdoAsySeqDelInstance(void)
 {
 	tEplKernel Ret;
 	unsigned int uiCount;
@@ -439,9 +439,9 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsySeqInitCon(tEplSdoSeqConHdl * pSdoSeqConHdl_p,
-				      unsigned int uiNodeId_p,
-				      tEplSdoType SdoType)
+tEplKernel EplSdoAsySeqInitCon(tEplSdoSeqConHdl *pSdoSeqConHdl_p,
+			       unsigned int uiNodeId_p,
+			       tEplSdoType SdoType)
 {
 	tEplKernel Ret;
 	unsigned int uiCount;
@@ -594,9 +594,9 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsySeqSendData(tEplSdoSeqConHdl SdoSeqConHdl_p,
-				       unsigned int uiDataSize_p,
-				       tEplFrame * pabData_p)
+tEplKernel EplSdoAsySeqSendData(tEplSdoSeqConHdl SdoSeqConHdl_p,
+				unsigned int uiDataSize_p,
+				tEplFrame *pabData_p)
 {
 	tEplKernel Ret;
 	unsigned int uiHandle;
@@ -640,7 +640,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsySeqProcessEvent(tEplEvent * pEvent_p)
+tEplKernel EplSdoAsySeqProcessEvent(tEplEvent *pEvent_p)
 {
 	tEplKernel Ret;
 	tEplTimerEventArg *pTimerEventArg;
@@ -714,7 +714,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsySeqDelCon(tEplSdoSeqConHdl SdoSeqConHdl_p)
+tEplKernel EplSdoAsySeqDelCon(tEplSdoSeqConHdl SdoSeqConHdl_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 	unsigned int uiHandle;
@@ -1498,7 +1498,7 @@
 				// frame received
 			case kAsySdoSeqEventFrameRec:
 				{
-					BYTE bSendSeqNumCon =
+					u8 bSendSeqNumCon =
 					    AmiGetByteFromLe(&pRecFrame_p->
 							     m_le_bSendSeqNumCon);
 
@@ -2016,7 +2016,7 @@
 					 BOOL fFrameInHistory_p)
 {
 	tEplKernel Ret;
-	BYTE abFrame[EPL_SEQ_FRAME_SIZE];
+	u8 abFrame[EPL_SEQ_FRAME_SIZE];
 	tEplFrame *pEplFrame;
 	unsigned int uiFreeEntries;
 
@@ -2139,9 +2139,9 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsyReceiveCb(tEplSdoConHdl ConHdl_p,
-				     tEplAsySdoSeq * pSdoSeqData_p,
-				     unsigned int uiDataSize_p)
+tEplKernel EplSdoAsyReceiveCb(tEplSdoConHdl ConHdl_p,
+			      tEplAsySdoSeq *pSdoSeqData_p,
+			      unsigned int uiDataSize_p)
 {
 	tEplKernel Ret;
 	unsigned int uiCount = 0;
@@ -2154,7 +2154,7 @@
 #endif
 
 	EPL_DBGLVL_SDO_TRACE2("Handle: 0x%x , First Databyte 0x%x\n", ConHdl_p,
-			      ((BYTE *) pSdoSeqData_p)[0]);
+			      ((u8 *) pSdoSeqData_p)[0]);
 
 	// search controll structure for this connection
 	pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[uiCount];
@@ -2328,12 +2328,12 @@
 //
 //---------------------------------------------------------------------------
 static tEplKernel EplSdoAsyAckFrameToHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
-					     BYTE bRecSeqNumber_p)
+					     u8 bRecSeqNumber_p)
 {
 	tEplKernel Ret;
 	tEplAsySdoConHistory *pHistory;
-	BYTE bAckIndex;
-	BYTE bCurrentSeqNum;
+	u8 bAckIndex;
+	u8 bCurrentSeqNum;
 
 	Ret = kEplSuccessful;
 
@@ -2422,8 +2422,8 @@
 	// check if entries are available for reading
 	if ((pHistory->m_bFreeEntries < EPL_SDO_HISTORY_SIZE)
 	    && (pHistory->m_bWrite != pHistory->m_bRead)) {
-//        PRINTF4("EplSdoAsyReadFromHistory(): init = %d, read = %u, write = %u, ack = %u", (int) fInitRead_p, (WORD)pHistory->m_bRead, (WORD)pHistory->m_bWrite, (WORD)pHistory->m_bAck);
-//        PRINTF2(", free entries = %u, next frame size = %u\n", (WORD)pHistory->m_bFreeEntries, pHistory->m_auiFrameSize[pHistory->m_bRead]);
+//        PRINTF4("EplSdoAsyReadFromHistory(): init = %d, read = %u, write = %u, ack = %u", (int) fInitRead_p, (u16)pHistory->m_bRead, (u16)pHistory->m_bWrite, (u16)pHistory->m_bAck);
+//        PRINTF2(", free entries = %u, next frame size = %u\n", (u16)pHistory->m_bFreeEntries, pHistory->m_auiFrameSize[pHistory->m_bRead]);
 
 		// return pointer to stored frame
 		*ppFrame_p =
@@ -2439,7 +2439,7 @@
 		}
 
 	} else {
-//        PRINTF3("EplSdoAsyReadFromHistory(): read = %u, ack = %u, free entries = %u, no frame\n", (WORD)pHistory->m_bRead, (WORD)pHistory->m_bAck, (WORD)pHistory->m_bFreeEntries);
+//        PRINTF3("EplSdoAsyReadFromHistory(): read = %u, ack = %u, free entries = %u, no frame\n", (u16)pHistory->m_bRead, (u16)pHistory->m_bAck, (u16)pHistory->m_bFreeEntries);
 
 		// no more frames to send
 		// return null pointer
diff --git a/drivers/staging/epl/EplSdoComu.c b/drivers/staging/epl/EplSdoComu.c
index ce0eb33..bf35afab 100644
--- a/drivers/staging/epl/EplSdoComu.c
+++ b/drivers/staging/epl/EplSdoComu.c
@@ -156,14 +156,14 @@
 typedef struct {
 	tEplSdoSeqConHdl m_SdoSeqConHdl;	// if != 0 -> entry used
 	tEplSdoComState m_SdoComState;
-	BYTE m_bTransactionId;
+	u8 m_bTransactionId;
 	unsigned int m_uiNodeId;	// NodeId of the target
 	// -> needed to reinit connection
 	//    after timeout
 	tEplSdoTransType m_SdoTransType;	// Auto, Expedited, Segmented
 	tEplSdoServiceType m_SdoServiceType;	// WriteByIndex, ReadByIndex
 	tEplSdoType m_SdoProtType;	// protocol layer: Auto, Udp, Asnd, Pdo
-	BYTE *m_pData;		// pointer to data
+	u8 *m_pData;		// pointer to data
 	unsigned int m_uiTransSize;	// number of bytes
 	// to transfer
 	unsigned int m_uiTransferredByte;	// number of bytes
@@ -174,7 +174,7 @@
 	//    the SDO transfer
 	void *m_pUserArg;	// user definable argument pointer
 
-	DWORD m_dwLastAbortCode;	// save the last abort code
+	u32 m_dwLastAbortCode;	// save the last abort code
 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
 	// only for client
 	unsigned int m_uiTargetIndex;	// index to access
@@ -205,12 +205,12 @@
 //---------------------------------------------------------------------------
 // local function prototypes
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
-				     tEplAsySdoCom * pAsySdoCom_p,
-				     unsigned int uiDataSize_p);
+tEplKernel EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
+			      tEplAsySdoCom *pAsySdoCom_p,
+			      unsigned int uiDataSize_p);
 
-tEplKernel PUBLIC EplSdoComConCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
-				 tEplAsySdoConState AsySdoConState_p);
+tEplKernel EplSdoComConCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
+			  tEplAsySdoConState AsySdoConState_p);
 
 static tEplKernel EplSdoComSearchConIntern(tEplSdoSeqConHdl SdoSeqConHdl_p,
 					   tEplSdoComConEvent SdoComConEvent_p,
@@ -246,7 +246,7 @@
 					      tEplAsySdoCom * pAsySdoCom_p);
 
 static tEplKernel EplSdoComClientSendAbort(tEplSdoComCon * pSdoComCon_p,
-					   DWORD dwAbortCode_p);
+					   u32 dwAbortCode_p);
 #endif
 
 /***************************************************************************/
@@ -285,7 +285,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoComInit(void)
+tEplKernel EplSdoComInit(void)
 {
 	tEplKernel Ret;
 
@@ -312,7 +312,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoComAddInstance(void)
+tEplKernel EplSdoComAddInstance(void)
 {
 	tEplKernel Ret;
 
@@ -354,7 +354,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoComDelInstance(void)
+tEplKernel EplSdoComDelInstance(void)
 {
 	tEplKernel Ret;
 
@@ -398,9 +398,9 @@
 //
 //---------------------------------------------------------------------------
 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-tEplKernel PUBLIC EplSdoComDefineCon(tEplSdoComConHdl * pSdoComConHdl_p,
-				     unsigned int uiTargetNodeId_p,
-				     tEplSdoType ProtType_p)
+tEplKernel EplSdoComDefineCon(tEplSdoComConHdl *pSdoComConHdl_p,
+			      unsigned int uiTargetNodeId_p,
+			      tEplSdoType ProtType_p)
 {
 	tEplKernel Ret;
 	unsigned int uiCount;
@@ -511,8 +511,7 @@
 //
 //---------------------------------------------------------------------------
 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-tEplKernel PUBLIC EplSdoComInitTransferByIndex(tEplSdoComTransParamByIndex *
-					       pSdoComTransParam_p)
+tEplKernel EplSdoComInitTransferByIndex(tEplSdoComTransParamByIndex *pSdoComTransParam_p)
 {
 	tEplKernel Ret;
 	tEplSdoComCon *pSdoComCon;
@@ -603,7 +602,7 @@
 //
 //---------------------------------------------------------------------------
 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-tEplKernel PUBLIC EplSdoComUndefineCon(tEplSdoComConHdl SdoComConHdl_p)
+tEplKernel EplSdoComUndefineCon(tEplSdoComConHdl SdoComConHdl_p)
 {
 	tEplKernel Ret;
 	tEplSdoComCon *pSdoComCon;
@@ -669,8 +668,8 @@
 //
 //---------------------------------------------------------------------------
 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-tEplKernel PUBLIC EplSdoComGetState(tEplSdoComConHdl SdoComConHdl_p,
-				    tEplSdoComFinished * pSdoComFinished_p)
+tEplKernel EplSdoComGetState(tEplSdoComConHdl SdoComConHdl_p,
+			     tEplSdoComFinished *pSdoComFinished_p)
 {
 	tEplKernel Ret;
 	tEplSdoComCon *pSdoComCon;
@@ -747,8 +746,8 @@
 //
 //---------------------------------------------------------------------------
 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-tEplKernel PUBLIC EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p,
-				    DWORD dwAbortCode_p)
+tEplKernel EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p,
+			     u32 dwAbortCode_p)
 {
 	tEplKernel Ret;
 	tEplSdoComCon *pSdoComCon;
@@ -766,7 +765,7 @@
 		goto Exit;
 	}
 	// save pointer to abort code
-	pSdoComCon->m_pData = (BYTE *) & dwAbortCode_p;
+	pSdoComCon->m_pData = (u8 *) & dwAbortCode_p;
 
 	Ret = EplSdoComProcessIntern(SdoComConHdl_p,
 				     kEplSdoComConEventAbort,
@@ -803,9 +802,9 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
-				     tEplAsySdoCom * pAsySdoCom_p,
-				     unsigned int uiDataSize_p)
+tEplKernel EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
+			      tEplAsySdoCom *pAsySdoCom_p,
+			      unsigned int uiDataSize_p)
 {
 	tEplKernel Ret;
 
@@ -815,7 +814,7 @@
 
 	EPL_DBGLVL_SDO_TRACE3
 	    ("EplSdoComReceiveCb SdoSeqConHdl: 0x%X, First Byte of pAsySdoCom_p: 0x%02X, uiDataSize_p: 0x%04X\n",
-	     SdoSeqConHdl_p, (WORD) pAsySdoCom_p->m_le_abCommandData[0],
+	     SdoSeqConHdl_p, (u16) pAsySdoCom_p->m_le_abCommandData[0],
 	     uiDataSize_p);
 
 	return Ret;
@@ -840,8 +839,8 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoComConCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
-				 tEplAsySdoConState AsySdoConState_p)
+tEplKernel EplSdoComConCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
+			  tEplAsySdoConState AsySdoConState_p)
 {
 	tEplKernel Ret;
 	tEplSdoComConEvent SdoComConEvent = kEplSdoComConEventSendFirst;
@@ -999,10 +998,10 @@
 {
 	tEplKernel Ret;
 	tEplSdoComCon *pSdoComCon;
-	BYTE bFlag;
+	u8 bFlag;
 
 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
-	DWORD dwAbortCode;
+	u32 dwAbortCode;
 	unsigned int uiSize;
 #endif
 
@@ -1138,7 +1137,7 @@
 									pSdoComCon->
 									    m_pData
 									    =
-									    (BYTE
+									    (u8
 									     *)
 									    &
 									    dwAbortCode;
@@ -1283,7 +1282,7 @@
 							if (pSdoComCon->
 							    m_dwLastAbortCode ==
 							    0) {
-								( /*(BYTE*) */
+								( /*(u8*) */
 								 pSdoComCon->
 								 m_pData) +=
 						      uiSize;
@@ -1321,7 +1320,7 @@
 									pSdoComCon->
 									    m_pData
 									    =
-									    (BYTE
+									    (u8
 									     *)
 									    &
 									    pSdoComCon->
@@ -1667,7 +1666,7 @@
 			case kEplSdoComConEventAbort:
 				{
 					EplSdoComClientSendAbort(pSdoComCon,
-								 *((DWORD *)
+								 *((u32 *)
 								   pSdoComCon->
 								   m_pData));
 
@@ -1675,7 +1674,7 @@
 					pSdoComCon->m_bTransactionId++;
 					// call callback of application
 					pSdoComCon->m_dwLastAbortCode =
-					    *((DWORD *) pSdoComCon->m_pData);
+					    *((u32 *) pSdoComCon->m_pData);
 					Ret =
 					    EplSdoComTransferFinished
 					    (SdoComCon_p, pSdoComCon,
@@ -1869,7 +1868,7 @@
 			case kEplSdoComConEventAbort:
 				{
 					EplSdoComClientSendAbort(pSdoComCon,
-								 *((DWORD *)
+								 *((u32 *)
 								   pSdoComCon->
 								   m_pData));
 
@@ -1880,7 +1879,7 @@
 					    kEplSdoComStateClientConnected;
 					// call callback of application
 					pSdoComCon->m_dwLastAbortCode =
-					    *((DWORD *) pSdoComCon->m_pData);
+					    *((u32 *) pSdoComCon->m_pData);
 					Ret =
 					    EplSdoComTransferFinished
 					    (SdoComCon_p, pSdoComCon,
@@ -1965,7 +1964,7 @@
 	unsigned int uiSubindex;
 	tEplObdSize EntrySize;
 	tEplObdAccess AccessType;
-	DWORD dwAbortCode;
+	u32 dwAbortCode;
 
 	dwAbortCode = 0;
 
@@ -1987,7 +1986,7 @@
 	if (Ret == kEplObdSubindexNotExist) {	// subentry doesn't exist
 		dwAbortCode = EPL_SDOAC_SUB_INDEX_NOT_EXIST;
 		// send abort
-		pSdoComCon_p->m_pData = (BYTE *) & dwAbortCode;
+		pSdoComCon_p->m_pData = (u8 *) & dwAbortCode;
 		Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
 						     uiIndex,
 						     uiSubindex,
@@ -1996,7 +1995,7 @@
 	} else if (Ret != kEplSuccessful) {	// entry doesn't exist
 		dwAbortCode = EPL_SDOAC_OBJECT_NOT_EXIST;
 		// send abort
-		pSdoComCon_p->m_pData = (BYTE *) & dwAbortCode;
+		pSdoComCon_p->m_pData = (u8 *) & dwAbortCode;
 		Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
 						     uiIndex,
 						     uiSubindex,
@@ -2014,7 +2013,7 @@
 			dwAbortCode = EPL_SDOAC_UNSUPPORTED_ACCESS;
 		}
 		// send abort
-		pSdoComCon_p->m_pData = (BYTE *) & dwAbortCode;
+		pSdoComCon_p->m_pData = (u8 *) & dwAbortCode;
 		Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
 						     uiIndex,
 						     uiSubindex,
@@ -2051,7 +2050,7 @@
 		// error -> abort
 		dwAbortCode = EPL_SDOAC_GENERAL_ERROR;
 		// send abort
-		pSdoComCon_p->m_pData = (BYTE *) & dwAbortCode;
+		pSdoComCon_p->m_pData = (u8 *) & dwAbortCode;
 		Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
 						     uiIndex,
 						     uiSubindex,
@@ -2090,11 +2089,11 @@
 						 tEplSdoComSendType SendType_p)
 {
 	tEplKernel Ret;
-	BYTE abFrame[EPL_MAX_SDO_FRAME_SIZE];
+	u8 abFrame[EPL_MAX_SDO_FRAME_SIZE];
 	tEplFrame *pFrame;
 	tEplAsySdoCom *pCommandFrame;
 	unsigned int uiSizeOfFrame;
-	BYTE bFlag;
+	u8 bFlag;
 
 	Ret = kEplSuccessful;
 
@@ -2167,7 +2166,7 @@
 				// set size of frame
 				AmiSetWordToLe(&pCommandFrame->
 					       m_le_wSegmentSize,
-					       (WORD) pSdoComCon_p->
+					       (u16) pSdoComCon_p->
 					       m_uiTransSize);
 
 				// correct byte-counter
@@ -2297,7 +2296,7 @@
 					// set segment size
 					AmiSetWordToLe(&pCommandFrame->
 						       m_le_wSegmentSize,
-						       (WORD) pSdoComCon_p->
+						       (u16) pSdoComCon_p->
 						       m_uiTransSize);
 
 					// send frame
@@ -2324,18 +2323,18 @@
 
 			// copy abortcode to frame
 			AmiSetDwordToLe(&pCommandFrame->m_le_abCommandData[0],
-					*((DWORD *) pSdoComCon_p->m_pData));
+					*((u32 *) pSdoComCon_p->m_pData));
 
 			// set size of segment
 			AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize,
-				       sizeof(DWORD));
+				       sizeof(u32));
 
 			// update counter
-			pSdoComCon_p->m_uiTransferredByte = sizeof(DWORD);
+			pSdoComCon_p->m_uiTransferredByte = sizeof(u32);
 			pSdoComCon_p->m_uiTransSize = 0;
 
 			// calc framesize
-			uiSizeOfFrame += sizeof(DWORD);
+			uiSizeOfFrame += sizeof(u32);
 			Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
 						   uiSizeOfFrame, pFrame);
 			break;
@@ -2373,8 +2372,8 @@
 	unsigned int uiBytesToTransfer;
 	tEplObdSize EntrySize;
 	tEplObdAccess AccessType;
-	DWORD dwAbortCode;
-	BYTE *pbSrcData;
+	u32 dwAbortCode;
+	u8 *pbSrcData;
 
 	dwAbortCode = 0;
 
@@ -2427,7 +2426,7 @@
 		pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_SUB_INDEX_NOT_EXIST;
 		// send abort
 		// d.k. This is wrong: k.t. not needed send abort on end of write
-		/*pSdoComCon_p->m_pData = (BYTE*)pSdoComCon_p->m_dwLastAbortCode;
+		/*pSdoComCon_p->m_pData = (u8*)pSdoComCon_p->m_dwLastAbortCode;
 		   Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
 		   uiIndex,
 		   uiSubindex,
@@ -2438,7 +2437,7 @@
 		// send abort
 		// d.k. This is wrong: k.t. not needed send abort on end of write
 		/*
-		   pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
+		   pSdoComCon_p->m_pData = (u8*)&dwAbortCode;
 		   Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
 		   uiIndex,
 		   uiSubindex,
@@ -2458,7 +2457,7 @@
 		}
 		// send abort
 		// d.k. This is wrong: k.t. not needed send abort on end of write
-		/*pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
+		/*pSdoComCon_p->m_pData = (u8*)&dwAbortCode;
 		   Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
 		   uiIndex,
 		   uiSubindex,
@@ -2549,7 +2548,7 @@
 			    EPL_SDOAC_DATA_TYPE_LENGTH_TOO_HIGH;
 			// send abort
 			// d.k. This is wrong: k.t. not needed send abort on end of write
-			/*pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
+			/*pSdoComCon_p->m_pData = (u8*)&dwAbortCode;
 			   Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
 			   uiIndex,
 			   uiSubindex,
@@ -2571,7 +2570,7 @@
 			    EPL_SDOAC_GENERAL_ERROR;
 			// send abort
 			// d.k. This is wrong: k.t. not needed send abort on end of write
-/*            pSdoComCon_p->m_pData = (BYTE*)&pSdoComCon_p->m_dwLastAbortCode;
+/*            pSdoComCon_p->m_pData = (u8*)&pSdoComCon_p->m_dwLastAbortCode;
             Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
                                         uiIndex,
                                         uiSubindex,
@@ -2586,7 +2585,7 @@
 		pSdoComCon_p->m_uiTransSize -= uiBytesToTransfer;
 
 		// update target pointer
-		( /*(BYTE*) */ pSdoComCon_p->m_pData) += uiBytesToTransfer;
+		( /*(u8*) */ pSdoComCon_p->m_pData) += uiBytesToTransfer;
 
 		// send acknowledge without any Command layer data
 		Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
@@ -2598,7 +2597,7 @@
 	if (pSdoComCon_p->m_dwLastAbortCode != 0) {
 		// send abort
 		pSdoComCon_p->m_pData =
-		    (BYTE *) & pSdoComCon_p->m_dwLastAbortCode;
+		    (u8 *) & pSdoComCon_p->m_dwLastAbortCode;
 		Ret =
 		    EplSdoComServerSendFrameIntern(pSdoComCon_p, uiIndex,
 						   uiSubindex,
@@ -2635,12 +2634,12 @@
 static tEplKernel EplSdoComClientSend(tEplSdoComCon * pSdoComCon_p)
 {
 	tEplKernel Ret;
-	BYTE abFrame[EPL_MAX_SDO_FRAME_SIZE];
+	u8 abFrame[EPL_MAX_SDO_FRAME_SIZE];
 	tEplFrame *pFrame;
 	tEplAsySdoCom *pCommandFrame;
 	unsigned int uiSizeOfFrame;
-	BYTE bFlags;
-	BYTE *pbPayload;
+	u8 bFlags;
+	u8 *pbPayload;
 
 	Ret = kEplSuccessful;
 
@@ -2680,11 +2679,11 @@
 
 					// create command header
 					AmiSetWordToLe(pbPayload,
-						       (WORD) pSdoComCon_p->
+						       (u16) pSdoComCon_p->
 						       m_uiTargetIndex);
 					pbPayload += 2;
 					AmiSetByteToLe(pbPayload,
-						       (BYTE) pSdoComCon_p->
+						       (u8) pSdoComCon_p->
 						       m_uiTargetSubIndex);
 					// calc size
 					uiSizeOfFrame += 4;
@@ -2721,12 +2720,12 @@
 							       bFlags);
 						// create command header
 						AmiSetWordToLe(pbPayload,
-							       (WORD)
+							       (u16)
 							       pSdoComCon_p->
 							       m_uiTargetIndex);
 						pbPayload += 2;
 						AmiSetByteToLe(pbPayload,
-							       (BYTE)
+							       (u8)
 							       pSdoComCon_p->
 							       m_uiTargetSubIndex);
 						// on byte for reserved
@@ -2760,12 +2759,12 @@
 
 						// create command header
 						AmiSetWordToLe(pbPayload,
-							       (WORD)
+							       (u16)
 							       pSdoComCon_p->
 							       m_uiTargetIndex);
 						pbPayload += 2;
 						AmiSetByteToLe(pbPayload,
-							       (BYTE)
+							       (u8)
 							       pSdoComCon_p->
 							       m_uiTargetSubIndex);
 						// + 2 -> one byte for subindex and one byte reserved
@@ -2784,7 +2783,7 @@
 						// fill rest of header
 						AmiSetWordToLe(&pCommandFrame->
 							       m_le_wSegmentSize,
-							       (WORD) (4 +
+							       (u16) (4 +
 								       pSdoComCon_p->
 								       m_uiTransSize));
 
@@ -2855,7 +2854,7 @@
 							AmiSetWordToLe
 							    (&pCommandFrame->
 							     m_le_wSegmentSize,
-							     (WORD)
+							     (u16)
 							     pSdoComCon_p->
 							     m_uiTransSize);
 							bFlags = 0x30;
@@ -2944,7 +2943,7 @@
 					      tEplAsySdoCom * pAsySdoCom_p)
 {
 	tEplKernel Ret;
-	BYTE bBuffer;
+	u8 bBuffer;
 	unsigned int uiBuffer;
 	unsigned int uiDataSize;
 	unsigned long ulBuffer;
@@ -3217,10 +3216,10 @@
 //---------------------------------------------------------------------------
 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
 static tEplKernel EplSdoComClientSendAbort(tEplSdoComCon * pSdoComCon_p,
-					   DWORD dwAbortCode_p)
+					   u32 dwAbortCode_p)
 {
 	tEplKernel Ret;
-	BYTE abFrame[EPL_MAX_SDO_FRAME_SIZE];
+	u8 abFrame[EPL_MAX_SDO_FRAME_SIZE];
 	tEplFrame *pFrame;
 	tEplAsySdoCom *pCommandFrame;
 	unsigned int uiSizeOfFrame;
@@ -3250,14 +3249,14 @@
 	AmiSetDwordToLe(&pCommandFrame->m_le_abCommandData[0], dwAbortCode_p);
 
 	// set size of segment
-	AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize, sizeof(DWORD));
+	AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize, sizeof(u32));
 
 	// update counter
-	pSdoComCon_p->m_uiTransferredByte = sizeof(DWORD);
+	pSdoComCon_p->m_uiTransferredByte = sizeof(u32);
 	pSdoComCon_p->m_uiTransSize = 0;
 
 	// calc framesize
-	uiSizeOfFrame += sizeof(DWORD);
+	uiSizeOfFrame += sizeof(u32);
 
 	// save abort code
 	pSdoComCon_p->m_dwLastAbortCode = dwAbortCode_p;
diff --git a/drivers/staging/epl/EplSdoUdpu.c b/drivers/staging/epl/EplSdoUdpu.c
index be52233..b409c9b 100644
--- a/drivers/staging/epl/EplSdoUdpu.c
+++ b/drivers/staging/epl/EplSdoUdpu.c
@@ -72,11 +72,9 @@
 
 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
 
-#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
 #include "SocketLinuxKernel.h"
 #include <linux/completion.h>
 #include <linux/sched.h>
-#endif
 
 /***************************************************************************/
 /*                                                                         */
@@ -110,17 +108,9 @@
 	tEplSequLayerReceiveCb m_fpSdoAsySeqCb;
 	SOCKET m_UdpSocket;
 
-#if (TARGET_SYSTEM == _WIN32_)
-	HANDLE m_ThreadHandle;
-	LPCRITICAL_SECTION m_pCriticalSection;
-	CRITICAL_SECTION m_CriticalSection;
-
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
 	struct completion m_CompletionUdpThread;
 	int m_ThreadHandle;
 	int m_iTerminateThread;
-#endif
-
 } tEplSdoUdpInstance;
 
 //---------------------------------------------------------------------------
@@ -133,12 +123,7 @@
 // local function prototypes
 //---------------------------------------------------------------------------
 
-#if (TARGET_SYSTEM == _WIN32_)
-static DWORD PUBLIC EplSdoUdpThread(LPVOID lpParameter);
-
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
 static int EplSdoUdpThread(void *pArg_p);
-#endif
 
 /***************************************************************************/
 /*                                                                         */
@@ -177,7 +162,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoUdpuInit(tEplSequLayerReceiveCb fpReceiveCb_p)
+tEplKernel EplSdoUdpuInit(tEplSequLayerReceiveCb fpReceiveCb_p)
 {
 	tEplKernel Ret;
 
@@ -205,16 +190,10 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
+tEplKernel EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
 {
 	tEplKernel Ret;
 
-#if (TARGET_SYSTEM == _WIN32_)
-	int iError;
-	WSADATA Wsa;
-
-#endif
-
 	// set instance variables to 0
 	EPL_MEMSET(&SdoUdpInstance_g, 0x00, sizeof(SdoUdpInstance_g));
 
@@ -228,24 +207,8 @@
 		goto Exit;
 	}
 
-#if (TARGET_SYSTEM == _WIN32_)
-	// start winsock2 for win32
-	// windows specific start of socket
-	iError = WSAStartup(MAKEWORD(2, 0), &Wsa);
-	if (iError != 0) {
-		Ret = kEplSdoUdpNoSocket;
-		goto Exit;
-	}
-	// create critical section for acccess of instnace variables
-	SdoUdpInstance_g.m_pCriticalSection =
-	    &SdoUdpInstance_g.m_CriticalSection;
-	InitializeCriticalSection(SdoUdpInstance_g.m_pCriticalSection);
-
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
 	init_completion(&SdoUdpInstance_g.m_CompletionUdpThread);
 	SdoUdpInstance_g.m_iTerminateThread = 0;
-#endif
-
 	SdoUdpInstance_g.m_ThreadHandle = 0;
 	SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET;
 
@@ -273,32 +236,18 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoUdpuDelInstance()
+tEplKernel EplSdoUdpuDelInstance(void)
 {
 	tEplKernel Ret;
 
-#if (TARGET_SYSTEM == _WIN32_)
-	BOOL fTermError;
-#endif
-
 	Ret = kEplSuccessful;
 
 	if (SdoUdpInstance_g.m_ThreadHandle != 0) {	// listen thread was started
 		// close thread
-#if (TARGET_SYSTEM == _WIN32_)
-		fTermError =
-		    TerminateThread(SdoUdpInstance_g.m_ThreadHandle, 0);
-		if (fTermError == FALSE) {
-			Ret = kEplSdoUdpThreadError;
-			goto Exit;
-		}
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
 		SdoUdpInstance_g.m_iTerminateThread = 1;
 		/* kill_proc(SdoUdpInstance_g.m_ThreadHandle, SIGTERM, 1 ); */
 		send_sig(SIGTERM, SdoUdpInstance_g.m_ThreadHandle, 1);
 		wait_for_completion(&SdoUdpInstance_g.m_CompletionUdpThread);
-#endif
-
 		SdoUdpInstance_g.m_ThreadHandle = 0;
 	}
 
@@ -307,19 +256,6 @@
 		closesocket(SdoUdpInstance_g.m_UdpSocket);
 		SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET;
 	}
-#if (TARGET_SYSTEM == _WIN32_)
-	// delete critical section
-	DeleteCriticalSection(SdoUdpInstance_g.m_pCriticalSection);
-#endif
-
-#if (TARGET_SYSTEM == _WIN32_)
-	// for win 32
-	WSACleanup();
-#endif
-
-#if (TARGET_SYSTEM == _WIN32_)
-      Exit:
-#endif
 	return Ret;
 }
 
@@ -340,18 +276,12 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoUdpuConfig(unsigned long ulIpAddr_p,
-				   unsigned int uiPort_p)
+tEplKernel EplSdoUdpuConfig(unsigned long ulIpAddr_p, unsigned int uiPort_p)
 {
 	tEplKernel Ret;
 	struct sockaddr_in Addr;
 	int iError;
 
-#if (TARGET_SYSTEM == _WIN32_)
-	BOOL fTermError;
-	unsigned long ulThreadId;
-#endif
-
 	Ret = kEplSuccessful;
 
 	if (uiPort_p == 0) {	// set UDP port to default port number
@@ -364,21 +294,11 @@
 	if (SdoUdpInstance_g.m_ThreadHandle != 0) {	// listen thread was started
 
 		// close old thread
-#if (TARGET_SYSTEM == _WIN32_)
-		fTermError =
-		    TerminateThread(SdoUdpInstance_g.m_ThreadHandle, 0);
-		if (fTermError == FALSE) {
-			Ret = kEplSdoUdpThreadError;
-			goto Exit;
-		}
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
 		SdoUdpInstance_g.m_iTerminateThread = 1;
 		/* kill_proc(SdoUdpInstance_g.m_ThreadHandle, SIGTERM, 1 ); */
 		send_sig(SIGTERM, SdoUdpInstance_g.m_ThreadHandle, 1);
 		wait_for_completion(&SdoUdpInstance_g.m_CompletionUdpThread);
 		SdoUdpInstance_g.m_iTerminateThread = 0;
-#endif
-
 		SdoUdpInstance_g.m_ThreadHandle = 0;
 	}
 
@@ -413,28 +333,12 @@
 		goto Exit;
 	}
 	// create Listen-Thread
-#if (TARGET_SYSTEM == _WIN32_)
-	// for win32
-
-	// create thread
-	SdoUdpInstance_g.m_ThreadHandle = CreateThread(NULL,
-						       0,
-						       EplSdoUdpThread,
-						       &SdoUdpInstance_g,
-						       0, &ulThreadId);
-	if (SdoUdpInstance_g.m_ThreadHandle == NULL) {
-		Ret = kEplSdoUdpThreadError;
-		goto Exit;
-	}
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
-
 	SdoUdpInstance_g.m_ThreadHandle =
 	    kernel_thread(EplSdoUdpThread, &SdoUdpInstance_g, CLONE_KERNEL);
 	if (SdoUdpInstance_g.m_ThreadHandle == 0) {
 		Ret = kEplSdoUdpThreadError;
 		goto Exit;
 	}
-#endif
 
       Exit:
 	return Ret;
@@ -459,8 +363,8 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoUdpuInitCon(tEplSdoConHdl * pSdoConHandle_p,
-				    unsigned int uiTargetNodeId_p)
+tEplKernel EplSdoUdpuInitCon(tEplSdoConHdl *pSdoConHandle_p,
+			     unsigned int uiTargetNodeId_p)
 {
 	tEplKernel Ret;
 	unsigned int uiCount;
@@ -526,8 +430,8 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoUdpuSendData(tEplSdoConHdl SdoConHandle_p,
-				     tEplFrame * pSrcData_p, DWORD dwDataSize_p)
+tEplKernel EplSdoUdpuSendData(tEplSdoConHdl SdoConHandle_p,
+			      tEplFrame *pSrcData_p, u32 dwDataSize_p)
 {
 	tEplKernel Ret;
 	int iError;
@@ -553,22 +457,12 @@
 
 	// call sendto
 	Addr.sin_family = AF_INET;
-#if (TARGET_SYSTEM == _WIN32_)
-	// enter  critical section for process function
-	EnterCriticalSection(SdoUdpInstance_g.m_pCriticalSection);
-#endif
-
 	Addr.sin_port =
 	    (unsigned short)SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].
 	    m_uiPort;
 	Addr.sin_addr.s_addr =
 	    SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_ulIpAddr;
 
-#if (TARGET_SYSTEM == _WIN32_)
-	// leave critical section for process function
-	LeaveCriticalSection(SdoUdpInstance_g.m_pCriticalSection);
-#endif
-
 	iError = sendto(SdoUdpInstance_g.m_UdpSocket,	// sockethandle
 			(const char *)&pSrcData_p->m_le_bMessageType,	// data to send
 			dwDataSize_p,	// number of bytes to send
@@ -603,7 +497,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoUdpuDelCon(tEplSdoConHdl SdoConHandle_p)
+tEplKernel EplSdoUdpuDelCon(tEplSdoConHdl SdoConHandle_p)
 {
 	tEplKernel Ret;
 	unsigned int uiArray;
@@ -642,17 +536,13 @@
 // Parameters:      lpParameter = pointer to parameter type tEplSdoUdpThreadPara
 //
 //
-// Returns:         DWORD   =   errorcode
+// Returns:         u32   =   errorcode
 //
 //
 // State:
 //
 //---------------------------------------------------------------------------
-#if (TARGET_SYSTEM == _WIN32_)
-static DWORD PUBLIC EplSdoUdpThread(LPVOID lpParameter)
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
 static int EplSdoUdpThread(void *pArg_p)
-#endif
 {
 
 	tEplSdoUdpInstance *pInstance;
@@ -660,21 +550,15 @@
 	int iError;
 	int iCount;
 	int iFreeEntry;
-	BYTE abBuffer[EPL_MAX_SDO_REC_FRAME_SIZE];
+	u8 abBuffer[EPL_MAX_SDO_REC_FRAME_SIZE];
 	unsigned int uiSize;
 	tEplSdoConHdl SdoConHdl;
 
-#if (TARGET_SYSTEM == _WIN32_)
-	pInstance = (tEplSdoUdpInstance *) lpParameter;
-
-	for (;;)
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
 	pInstance = (tEplSdoUdpInstance *) pArg_p;
 	daemonize("EplSdoUdpThread");
 	allow_signal(SIGTERM);
 
 	for (; pInstance->m_iTerminateThread == 0;)
-#endif
 
 	{
 		// wait for data
@@ -685,20 +569,13 @@
 				  0,	// flags
 				  (struct sockaddr *)&RemoteAddr,
 				  (int *)&uiSize);
-#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
 		if (iError == -ERESTARTSYS) {
 			break;
 		}
-#endif
 		if (iError > 0) {
 			// get handle for higher layer
 			iCount = 0;
 			iFreeEntry = 0xFFFF;
-#if (TARGET_SYSTEM == _WIN32_)
-			// enter  critical section for process function
-			EnterCriticalSection(SdoUdpInstance_g.
-					     m_pCriticalSection);
-#endif
 			while (iCount < EPL_SDO_MAX_CONNECTION_UDP) {
 				// check if this connection is already known
 				if ((pInstance->m_aSdoAbsUdpConnection[iCount].
@@ -734,11 +611,6 @@
 					pInstance->
 					    m_aSdoAbsUdpConnection[iFreeEntry].
 					    m_uiPort = RemoteAddr.sin_port;
-#if (TARGET_SYSTEM == _WIN32_)
-					// leave critical section for process function
-					LeaveCriticalSection(SdoUdpInstance_g.
-							     m_pCriticalSection);
-#endif
 					// call callback
 					SdoConHdl = iFreeEntry;
 					SdoConHdl |= EPL_SDO_UDP_HANDLE;
@@ -752,11 +624,6 @@
 				} else {
 					EPL_DBGLVL_SDO_TRACE0
 					    ("Error in EplSdoUdpThread() no free handle\n");
-#if (TARGET_SYSTEM == _WIN32_)
-					// leave critical section for process function
-					LeaveCriticalSection(SdoUdpInstance_g.
-							     m_pCriticalSection);
-#endif
 				}
 
 			} else {
@@ -764,11 +631,6 @@
 				// call callback with correct handle
 				SdoConHdl = iCount;
 				SdoConHdl |= EPL_SDO_UDP_HANDLE;
-#if (TARGET_SYSTEM == _WIN32_)
-				// leave critical section for process function
-				LeaveCriticalSection(SdoUdpInstance_g.
-						     m_pCriticalSection);
-#endif
 				// offset 4 -> start of SDO Sequence header
 				pInstance->m_fpSdoAsySeqCb(SdoConHdl,
 							   (tEplAsySdoSeq *) &
@@ -778,10 +640,7 @@
 		}		// end of  if(iError!=SOCKET_ERROR)
 	}			// end of for(;;)
 
-#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
 	complete_and_exit(&SdoUdpInstance_g.m_CompletionUdpThread, 0);
-#endif
-
 	return 0;
 }
 
diff --git a/drivers/staging/epl/EplStatusu.c b/drivers/staging/epl/EplStatusu.c
index 689f912..b291399 100644
--- a/drivers/staging/epl/EplStatusu.c
+++ b/drivers/staging/epl/EplStatusu.c
@@ -137,8 +137,7 @@
 // local function prototypes
 //---------------------------------------------------------------------------
 
-static tEplKernel PUBLIC EplStatusuCbStatusResponse(tEplFrameInfo *
-						    pFrameInfo_p);
+static tEplKernel EplStatusuCbStatusResponse(tEplFrameInfo *pFrameInfo_p);
 
 //=========================================================================//
 //                                                                         //
@@ -164,7 +163,7 @@
 //
 //---------------------------------------------------------------------------
 
-EPLDLLEXPORT tEplKernel PUBLIC EplStatusuInit()
+tEplKernel EplStatusuInit(void)
 {
 	tEplKernel Ret;
 
@@ -191,7 +190,7 @@
 //
 //---------------------------------------------------------------------------
 
-EPLDLLEXPORT tEplKernel PUBLIC EplStatusuAddInstance()
+tEplKernel EplStatusuAddInstance(void)
 {
 	tEplKernel Ret;
 
@@ -228,7 +227,7 @@
 //
 //---------------------------------------------------------------------------
 
-EPLDLLEXPORT tEplKernel PUBLIC EplStatusuDelInstance()
+tEplKernel EplStatusuDelInstance(void)
 {
 	tEplKernel Ret;
 
@@ -258,7 +257,7 @@
 //
 //---------------------------------------------------------------------------
 
-EPLDLLEXPORT tEplKernel PUBLIC EplStatusuReset()
+tEplKernel EplStatusuReset(void)
 {
 	tEplKernel Ret;
 
@@ -287,9 +286,8 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplStatusuRequestStatusResponse(unsigned int uiNodeId_p,
-						  tEplStatusuCbResponse
-						  pfnCbResponse_p)
+tEplKernel EplStatusuRequestStatusResponse(unsigned int uiNodeId_p,
+					   tEplStatusuCbResponse pfnCbResponse_p)
 {
 	tEplKernel Ret;
 
@@ -342,8 +340,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplStatusuCbStatusResponse(tEplFrameInfo *
-						    pFrameInfo_p)
+static tEplKernel EplStatusuCbStatusResponse(tEplFrameInfo *pFrameInfo_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 	unsigned int uiNodeId;
diff --git a/drivers/staging/epl/EplTarget.h b/drivers/staging/epl/EplTarget.h
index b2b66f8..e76d21f 100644
--- a/drivers/staging/epl/EplTarget.h
+++ b/drivers/staging/epl/EplTarget.h
@@ -83,95 +83,11 @@
 // applications needs to use one common library function (e.g. memcpy()). So
 // you can set (or change) it here.
 
-#if (TARGET_SYSTEM == _WIN32_)
-
-#define _WIN32_WINDOWS 0x0401
-#define _WIN32_WINNT   0x0400
-
-#include <stdlib.h>
-#include <stdio.h>
-
-    //29.11.2004 f.j. sonst ist memcpy und memset unbekannt
-#include <string.h>
-
-#define EPL_MEMCPY(dst,src,siz)     memcpy((void*)(dst),(const void*)(src),(size_t)(siz));
-#define EPL_MEMSET(dst,val,siz)     memset((void*)(dst),(int)(val),(size_t)(siz));
-
-    // f.j.: die Funktionen für <MemAlloc> und <MemFree> sind in WinMem.c definiert
-    //definition der Prototypen
-void FAR *MemAlloc(DWORD dwMemSize_p);
-void MemFree(void FAR * pMem_p);
-
-#define EPL_MALLOC(siz)             malloc((size_t)(siz))
-#define EPL_FREE(ptr)               free((void *)ptr)
-
-#ifndef PRINTF0
-void trace(const char *fmt, ...);
-#define PRINTF                      TRACE
-#define PRINTF0(arg)                TRACE0(arg)
-#define PRINTF1(arg,p1)             TRACE1(arg,p1)
-#define PRINTF2(arg,p1,p2)          TRACE2(arg,p1,p2)
-#define PRINTF3(arg,p1,p2,p3)       TRACE3(arg,p1,p2,p3)
-#define PRINTF4(arg,p1,p2,p3,p4)    TRACE4(arg,p1,p2,p3,p4)
-	//#define PRINTF                      printf
-	//#define PRINTF0(arg)                PRINTF(arg)
-	//#define PRINTF1(arg,p1)             PRINTF(arg,p1)
-	//#define PRINTF2(arg,p1,p2)          PRINTF(arg,p1,p2)
-	//#define PRINTF3(arg,p1,p2,p3)       PRINTF(arg,p1,p2,p3)
-	//#define PRINTF4(arg,p1,p2,p3,p4)    PRINTF(arg,p1,p2,p3,p4)
-#endif
-
-#ifdef ASSERTMSG
-#undef ASSERTMSG
-#endif
-
-#define ASSERTMSG(expr,string)  if (!(expr)) { \
-                                        MessageBox (NULL, string, "Assertion failed", MB_OK | MB_ICONERROR); \
-                                        exit (-1);}
-
-#elif (TARGET_SYSTEM == _NO_OS_)
-
-#include <stdlib.h>
-#include <stdio.h>
-
-    //29.11.2004 f.j. sonst ist memcpy und memset unbekannt
-//    #include <string.h>
-
-#define EPL_MEMCPY(dst,src,siz)     memcpy((void*)(dst),(const void*)(src),(size_t)(siz));
-#define EPL_MEMSET(dst,val,siz)     memset((void*)(dst),(int)(val),(size_t)(siz));
-
-#define EPL_MALLOC(siz)             malloc((size_t)(siz))
-#define EPL_FREE(ptr)               free((void *)ptr)
-
-#ifndef PRINTF0
-#define PRINTF                      TRACE
-#define PRINTF0(arg)                TRACE0(arg)
-#define PRINTF1(arg,p1)             TRACE1(arg,p1)
-#define PRINTF2(arg,p1,p2)          TRACE2(arg,p1,p2)
-#define PRINTF3(arg,p1,p2,p3)       TRACE3(arg,p1,p2,p3)
-#define PRINTF4(arg,p1,p2,p3,p4)    TRACE4(arg,p1,p2,p3,p4)
-	//#define PRINTF                      printf
-	//#define PRINTF0(arg)                PRINTF(arg)
-	//#define PRINTF1(arg,p1)             PRINTF(arg,p1)
-	//#define PRINTF2(arg,p1,p2)          PRINTF(arg,p1,p2)
-	//#define PRINTF3(arg,p1,p2,p3)       PRINTF(arg,p1,p2,p3)
-	//#define PRINTF4(arg,p1,p2,p3,p4)    PRINTF(arg,p1,p2,p3,p4)
-#endif
-
-#elif (TARGET_SYSTEM == _LINUX_)
-
-#ifndef __KERNEL__
-#include <stdlib.h>
-#include <stdio.h>
-#else
-//        #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/major.h>
-#include <linux/version.h>
-#endif
 
     //29.11.2004 f.j. sonst ist memcpy und memset unbekannt
 //    #include <string.h>
@@ -179,13 +95,8 @@
 #define EPL_MEMCPY(dst,src,siz)     memcpy((void*)(dst),(const void*)(src),(size_t)(siz));
 #define EPL_MEMSET(dst,val,siz)     memset((void*)(dst),(int)(val),(size_t)(siz));
 
-#ifndef __KERNEL__
-#define EPL_MALLOC(siz)             malloc((size_t)(siz))
-#define EPL_FREE(ptr)               free((void *)ptr)
-#else
 #define EPL_MALLOC(siz)             kmalloc((size_t)(siz), GFP_KERNEL)
 #define EPL_FREE(ptr)               kfree((void *)ptr)
-#endif
 
 #ifndef PRINTF0
 #define PRINTF                      TRACE
@@ -202,8 +113,6 @@
 	//#define PRINTF4(arg,p1,p2,p3,p4)    PRINTF(arg,p1,p2,p3,p4)
 #endif
 
-#endif
-
 #define EPL_TGT_INTMASK_ETH     0x0001	// ethernet interrupt
 #define EPL_TGT_INTMASK_DMA     0x0002	// DMA interrupt
 
@@ -217,17 +126,15 @@
 
 // currently no Timer functions are needed by EPL stack
 // so they are not implemented yet
-//void  PUBLIC TgtTimerInit(void);
-//DWORD PUBLIC TgtGetTickCount(void);
-//void PUBLIC TgtGetNetTime(tEplNetTime * pNetTime_p);
+//void  TgtTimerInit(void);
+//u32 TgtGetTickCount(void);
+//void TgtGetNetTime(tEplNetTime * pNetTime_p);
 
 // functions for ethernet driver
-tEplKernel PUBLIC TgtInitEthIsr(void);
-void PUBLIC TgtFreeEthIsr(void);
-void PUBLIC TgtEnableGlobalInterrupt(BYTE fEnable_p);
-void PUBLIC TgtEnableEthInterrupt0(BYTE fEnable_p,
-				   unsigned int uiInterruptMask_p);
-void PUBLIC TgtEnableEthInterrupt1(BYTE fEnable_p,
-				   unsigned int uiInterruptMask_p);
+tEplKernel TgtInitEthIsr(void);
+void TgtFreeEthIsr(void);
+void TgtEnableGlobalInterrupt(u8 fEnable_p);
+void TgtEnableEthInterrupt0(u8 fEnable_p, unsigned int uiInterruptMask_p);
+void TgtEnableEthInterrupt1(u8 fEnable_p, unsigned int uiInterruptMask_p);
 
 #endif // #ifndef _EPLTARGET_H_
diff --git a/drivers/staging/epl/EplTimer.h b/drivers/staging/epl/EplTimer.h
index facbfd8..d1a73ea 100644
--- a/drivers/staging/epl/EplTimer.h
+++ b/drivers/staging/epl/EplTimer.h
@@ -107,8 +107,7 @@
 
 } tEplTimerEventArg;
 
-typedef tEplKernel(PUBLIC * tEplTimerkCallback) (tEplTimerEventArg *
-						 pEventArg_p);
+typedef tEplKernel(* tEplTimerkCallback) (tEplTimerEventArg *pEventArg_p);
 
 //---------------------------------------------------------------------------
 // function prototypes
diff --git a/drivers/staging/epl/EplTimeruLinuxKernel.c b/drivers/staging/epl/EplTimeruLinuxKernel.c
index 08820d1..ff80fc8 100644
--- a/drivers/staging/epl/EplTimeruLinuxKernel.c
+++ b/drivers/staging/epl/EplTimeruLinuxKernel.c
@@ -99,7 +99,7 @@
 //---------------------------------------------------------------------------
 // local function prototypes
 //---------------------------------------------------------------------------
-static void PUBLIC EplTimeruCbMs(unsigned long ulParameter_p);
+static void EplTimeruCbMs(unsigned long ulParameter_p);
 
 /***************************************************************************/
 /*                                                                         */
@@ -134,7 +134,7 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplTimeruInit()
+tEplKernel EplTimeruInit(void)
 {
 	tEplKernel Ret;
 
@@ -157,7 +157,7 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplTimeruAddInstance()
+tEplKernel EplTimeruAddInstance(void)
 {
 	tEplKernel Ret;
 
@@ -182,7 +182,7 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplTimeruDelInstance()
+tEplKernel EplTimeruDelInstance(void)
 {
 	tEplKernel Ret;
 
@@ -207,9 +207,9 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplTimeruSetTimerMs(tEplTimerHdl * pTimerHdl_p,
-				      unsigned long ulTime_p,
-				      tEplTimerArg Argument_p)
+tEplKernel EplTimeruSetTimerMs(tEplTimerHdl *pTimerHdl_p,
+			       unsigned long ulTime_p,
+			       tEplTimerArg Argument_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 	tEplTimeruData *pData;
@@ -257,9 +257,9 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl * pTimerHdl_p,
-					 unsigned long ulTime_p,
-					 tEplTimerArg Argument_p)
+tEplKernel EplTimeruModifyTimerMs(tEplTimerHdl *pTimerHdl_p,
+				  unsigned long ulTime_p,
+				  tEplTimerArg Argument_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 	tEplTimeruData *pData;
@@ -315,7 +315,7 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplTimeruDeleteTimer(tEplTimerHdl * pTimerHdl_p)
+tEplKernel EplTimeruDeleteTimer(tEplTimerHdl *pTimerHdl_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 	tEplTimeruData *pData;
@@ -370,7 +370,7 @@
 //
 //---------------------------------------------------------------------------
 
-BOOL PUBLIC EplTimeruIsTimerActive(tEplTimerHdl TimerHdl_p)
+BOOL EplTimeruIsTimerActive(tEplTimerHdl TimerHdl_p)
 {
 	BOOL fActive = FALSE;
 	tEplTimeruData *pData;
@@ -417,7 +417,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
-static void PUBLIC EplTimeruCbMs(unsigned long ulParameter_p)
+static void EplTimeruCbMs(unsigned long ulParameter_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 	tEplTimeruData *pData;
diff --git a/drivers/staging/epl/EplTimeruNull.c b/drivers/staging/epl/EplTimeruNull.c
deleted file mode 100644
index 40ce403..0000000
--- a/drivers/staging/epl/EplTimeruNull.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for Epl Userspace-Timermodule NULL-Implementation
-
-  License:
-
-    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 SYSTEC electronic GmbH nor the names of its
-       contributors may be used to endorse or promote products derived
-       from this software without prior written permission. For written
-       permission, please contact info@systec-electronic.com.
-
-    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 HOLDERS 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.
-
-    Severability Clause:
-
-        If a provision of this License is or becomes illegal, invalid or
-        unenforceable in any jurisdiction, that shall not affect:
-        1. the validity or enforceability in that jurisdiction of any other
-           provision of this License; or
-        2. the validity or enforceability in other jurisdictions of that or
-           any other provision of this License.
-
-  -------------------------------------------------------------------------
-
-                $RCSfile: EplTimeruNull.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.3 $  $Date: 2008/04/17 21:36:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                KEIL uVision 2
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/07/06 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#include "user/EplTimeru.h"
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// modul globale vars
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          C L A S S  <Epl Userspace-Timermodule NULL-Implementation>     */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-//
-// Description: Epl Userspace-Timermodule NULL-Implementation
-//
-//
-/***************************************************************************/
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplTimeruInit
-//
-// Description: function init first instance
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruInit()
-{
-	tEplKernel Ret;
-
-	Ret = EplTimeruAddInstance();
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplTimeruAddInstance
-//
-// Description: function init additional instance
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruAddInstance()
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplTimeruDelInstance
-//
-// Description: function delte instance
-//              -> under Win32 nothing to do
-//              -> no instnace table needed
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruDelInstance()
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplTimeruSetTimerMs
-//
-// Description: function create a timer and return a handle to the pointer
-//
-//
-//
-// Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
-//              ulTime_p    = time for timer in ms
-//              Argument_p  = argument for timer
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruSetTimerMs(tEplTimerHdl * pTimerHdl_p,
-				      unsigned long ulTime_p,
-				      tEplTimerArg Argument_p)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	// check handle
-	if (pTimerHdl_p == NULL) {
-		Ret = kEplTimerInvalidHandle;
-		goto Exit;
-	}
-
-      Exit:
-	return Ret;
-}
-
- //---------------------------------------------------------------------------
-//
-// Function:    EplTimeruModifyTimerMs
-//
-// Description: function change a timer and return a handle to the pointer
-//
-//
-//
-// Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
-//              ulTime_p    = time for timer in ms
-//              Argument_p  = argument for timer
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl * pTimerHdl_p,
-					 unsigned long ulTime_p,
-					 tEplTimerArg Argument_p)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	// check parameter
-	if (pTimerHdl_p == NULL) {
-		Ret = kEplTimerInvalidHandle;
-		goto Exit;
-	}
-
-      Exit:
-	return Ret;
-}
-
- //---------------------------------------------------------------------------
-//
-// Function:    EplTimeruDeleteTimer
-//
-// Description: function delte a timer
-//
-//
-//
-// Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruDeleteTimer(tEplTimerHdl * pTimerHdl_p)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	// check parameter
-	if (pTimerHdl_p == NULL) {
-		Ret = kEplTimerInvalidHandle;
-		goto Exit;
-	}
-	// set handle invalide
-	*pTimerHdl_p = 0;
-
-      Exit:
-	return Ret;
-
-}
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-// EOF
diff --git a/drivers/staging/epl/EplTimeruWin32.c b/drivers/staging/epl/EplTimeruWin32.c
deleted file mode 100644
index a967b4e..0000000
--- a/drivers/staging/epl/EplTimeruWin32.c
+++ /dev/null
@@ -1,513 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for Epl Userspace-Timermodule for Win32
-
-  License:
-
-    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 SYSTEC electronic GmbH nor the names of its
-       contributors may be used to endorse or promote products derived
-       from this software without prior written permission. For written
-       permission, please contact info@systec-electronic.com.
-
-    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 HOLDERS 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.
-
-    Severability Clause:
-
-        If a provision of this License is or becomes illegal, invalid or
-        unenforceable in any jurisdiction, that shall not affect:
-        1. the validity or enforceability in that jurisdiction of any other
-           provision of this License; or
-        2. the validity or enforceability in other jurisdictions of that or
-           any other provision of this License.
-
-  -------------------------------------------------------------------------
-
-                $RCSfile: EplTimeruWin32.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.4 $  $Date: 2008/04/17 21:36:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/07/06 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#include "user/EplTimeru.h"
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-typedef struct {
-	tEplTimerArg TimerArgument;
-	HANDLE DelteHandle;
-	unsigned long ulTimeout;
-
-} tEplTimeruThread;
-
-typedef struct {
-	LPCRITICAL_SECTION m_pCriticalSection;
-	CRITICAL_SECTION m_CriticalSection;
-} tEplTimeruInstance;
-//---------------------------------------------------------------------------
-// modul globale vars
-//---------------------------------------------------------------------------
-static tEplTimeruInstance EplTimeruInstance_g;
-static tEplTimeruThread ThreadData_l;
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-DWORD PUBLIC EplSdoTimeruThreadms(LPVOID lpParameter);
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          C L A S S  <Epl Userspace-Timermodule for Win32>               */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-//
-// Description: Epl Userspace-Timermodule for Win32
-//
-//
-/***************************************************************************/
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplTimeruInit
-//
-// Description: function init first instance
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruInit()
-{
-	tEplKernel Ret;
-
-	Ret = EplTimeruAddInstance();
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplTimeruAddInstance
-//
-// Description: function init additional instance
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruAddInstance()
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	// create critical section
-	EplTimeruInstance_g.m_pCriticalSection =
-	    &EplTimeruInstance_g.m_CriticalSection;
-	InitializeCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplTimeruDelInstance
-//
-// Description: function delte instance
-//              -> under Win32 nothing to do
-//              -> no instnace table needed
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruDelInstance()
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplTimeruSetTimerMs
-//
-// Description: function create a timer and return a handle to the pointer
-//
-//
-//
-// Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
-//              ulTime_p    = time for timer in ms
-//              Argument_p  = argument for timer
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruSetTimerMs(tEplTimerHdl * pTimerHdl_p,
-				      unsigned long ulTime_p,
-				      tEplTimerArg Argument_p)
-{
-	tEplKernel Ret;
-	HANDLE DeleteHandle;
-	HANDLE ThreadHandle;
-	DWORD ThreadId;
-
-	Ret = kEplSuccessful;
-
-	// check handle
-	if (pTimerHdl_p == NULL) {
-		Ret = kEplTimerInvalidHandle;
-		goto Exit;
-	}
-	// enter  critical section
-	EnterCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
-
-	// first create event to delete timer
-	DeleteHandle = CreateEvent(NULL, FALSE, FALSE, NULL);
-	if (DeleteHandle == NULL) {
-		Ret = kEplTimerNoTimerCreated;
-		goto Exit;
-	}
-	// set handle for caller
-	*pTimerHdl_p = (tEplTimerHdl) DeleteHandle;
-
-	// fill data for thread
-	ThreadData_l.DelteHandle = DeleteHandle;
-	EPL_MEMCPY(&ThreadData_l.TimerArgument, &Argument_p,
-		   sizeof(tEplTimerArg));
-	ThreadData_l.ulTimeout = ulTime_p;
-
-	// create thread to create waitable timer and wait for timer
-	ThreadHandle = CreateThread(NULL,
-				    0,
-				    EplSdoTimeruThreadms,
-				    &ThreadData_l, 0, &ThreadId);
-	if (ThreadHandle == NULL) {
-		// leave critical section
-		LeaveCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
-
-		// delte handle
-		CloseHandle(DeleteHandle);
-
-		Ret = kEplTimerNoTimerCreated;
-		goto Exit;
-	}
-
-      Exit:
-	return Ret;
-}
-
- //---------------------------------------------------------------------------
-//
-// Function:    EplTimeruModifyTimerMs
-//
-// Description: function change a timer and return a handle to the pointer
-//
-//
-//
-// Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
-//              ulTime_p    = time for timer in ms
-//              Argument_p  = argument for timer
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl * pTimerHdl_p,
-					 unsigned long ulTime_p,
-					 tEplTimerArg Argument_p)
-{
-	tEplKernel Ret;
-	HANDLE DeleteHandle;
-	HANDLE ThreadHandle;
-	DWORD ThreadId;
-
-	Ret = kEplSuccessful;
-
-	// check parameter
-	if (pTimerHdl_p == NULL) {
-		Ret = kEplTimerInvalidHandle;
-		goto Exit;
-	}
-
-	DeleteHandle = (HANDLE) (*pTimerHdl_p);
-
-	// set event to end timer task for this timer
-	SetEvent(DeleteHandle);
-
-	// create new timer
-	// first create event to delete timer
-	DeleteHandle = CreateEvent(NULL, FALSE, FALSE, NULL);
-	if (DeleteHandle == NULL) {
-		Ret = kEplTimerNoTimerCreated;
-		goto Exit;
-	}
-	// set handle for caller
-	*pTimerHdl_p = (tEplTimerHdl) DeleteHandle;
-
-	// enter  critical section
-	EnterCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
-
-	// fill data for thread
-	ThreadData_l.DelteHandle = DeleteHandle;
-	EPL_MEMCPY(&ThreadData_l.TimerArgument, &Argument_p,
-		   sizeof(tEplTimerArg));
-	ThreadData_l.ulTimeout = ulTime_p;
-
-	// create thread to create waitable timer and wait for timer
-	ThreadHandle = CreateThread(NULL,
-				    0,
-				    EplSdoTimeruThreadms,
-				    &ThreadData_l, 0, &ThreadId);
-	if (ThreadHandle == NULL) {
-		// leave critical section
-		LeaveCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
-
-		// delte handle
-
-		Ret = kEplTimerNoTimerCreated;
-		goto Exit;
-	}
-
-      Exit:
-	return Ret;
-}
-
- //---------------------------------------------------------------------------
-//
-// Function:    EplTimeruDeleteTimer
-//
-// Description: function delte a timer
-//
-//
-//
-// Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruDeleteTimer(tEplTimerHdl * pTimerHdl_p)
-{
-	tEplKernel Ret;
-	HANDLE DeleteHandle;
-
-	Ret = kEplSuccessful;
-
-	// check parameter
-	if (pTimerHdl_p == NULL) {
-		Ret = kEplTimerInvalidHandle;
-		goto Exit;
-	}
-
-	DeleteHandle = (HANDLE) (*pTimerHdl_p);
-
-	// set event to end timer task for this timer
-	SetEvent(DeleteHandle);
-
-	// set handle invalide
-	*pTimerHdl_p = 0;
-
-      Exit:
-	return Ret;
-
-}
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoTimeruThreadms
-//
-// Description: function to process timer as thread
-//
-//
-//
-// Parameters:  lpParameter = pointer to structur of type tEplTimeruThread
-//
-//
-// Returns:     DWORD = Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-DWORD PUBLIC EplSdoTimeruThreadms(LPVOID lpParameter)
-{
-	tEplKernel Ret;
-	tEplTimeruThread *pThreadData;
-	HANDLE aHandles[2];
-	BOOL fReturn;
-	LARGE_INTEGER TimeoutTime;
-	unsigned long ulEvent;
-	tEplEvent EplEvent;
-	tEplTimeruThread ThreadData;
-	tEplTimerEventArg TimerEventArg;
-
-	Ret = kEplSuccessful;
-
-	// get pointer to data
-	pThreadData = (tEplTimeruThread *) lpParameter;
-	// copy thread data
-	EPL_MEMCPY(&ThreadData, pThreadData, sizeof(ThreadData));
-	pThreadData = &ThreadData;
-
-	// leave critical section
-	LeaveCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
-
-	// create waitable timer
-	aHandles[1] = CreateWaitableTimer(NULL, FALSE, NULL);
-	if (aHandles[1] == NULL) {
-		Ret = kEplTimerNoTimerCreated;
-		goto Exit;
-	}
-	// set timer
-	// set timeout interval -> needed to be negativ
-	// -> because relative timeout
-	// -> multiply by 10000 for 100 ns timebase of function
-	TimeoutTime.QuadPart = (((long long)pThreadData->ulTimeout) * -10000);
-	fReturn = SetWaitableTimer(aHandles[1],
-				   &TimeoutTime, 0, NULL, NULL, FALSE);
-	if (fReturn == 0) {
-		Ret = kEplTimerNoTimerCreated;
-		goto Exit;
-	}
-	// save delte event handle in handle array
-	aHandles[0] = pThreadData->DelteHandle;
-
-	// wait for one of the events
-	ulEvent = WaitForMultipleObjects(2, &aHandles[0], FALSE, INFINITE);
-	if (ulEvent == WAIT_OBJECT_0) {	// delte event
-
-		// close handels
-		CloseHandle(aHandles[1]);
-		// terminate thread
-		goto Exit;
-	} else if (ulEvent == (WAIT_OBJECT_0 + 1)) {	// timer event
-		// call event function
-		TimerEventArg.m_TimerHdl =
-		    (tEplTimerHdl) pThreadData->DelteHandle;
-		TimerEventArg.m_ulArg = pThreadData->TimerArgument.m_ulArg;
-
-		EplEvent.m_EventSink = pThreadData->TimerArgument.m_EventSink;
-		EplEvent.m_EventType = kEplEventTypeTimer;
-		EPL_MEMSET(&EplEvent.m_NetTime, 0x00, sizeof(tEplNetTime));
-		EplEvent.m_pArg = &TimerEventArg;
-		EplEvent.m_uiSize = sizeof(TimerEventArg);
-
-		Ret = EplEventuPost(&EplEvent);
-
-		// close handels
-		CloseHandle(aHandles[1]);
-		// terminate thread
-		goto Exit;
-
-	} else {		// error
-		ulEvent = GetLastError();
-		TRACE1("Error in WaitForMultipleObjects Errorcode: 0x%x\n",
-		       ulEvent);
-		// terminate thread
-		goto Exit;
-	}
-
-      Exit:
-	return Ret;
-}
-
-// EOF
diff --git a/drivers/staging/epl/SharedBuff.c b/drivers/staging/epl/SharedBuff.c
index 9fb09d6..2b10c375 100644
--- a/drivers/staging/epl/SharedBuff.c
+++ b/drivers/staging/epl/SharedBuff.c
@@ -85,14 +85,8 @@
 #include "SharedBuff.h"
 #include "ShbIpc.h"
 
-// d.k. Linux kernel modules needs other header files for memcpy()
-#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
 #include <linux/string.h>
-#else
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#endif
+#include <linux/kernel.h>
 
 /***************************************************************************/
 /*                                                                         */
@@ -102,8 +96,6 @@
 /*                                                                         */
 /***************************************************************************/
 
-#if (!defined(SHAREDBUFF_INLINED)) || defined(INLINE_ENABLED)
-
 //---------------------------------------------------------------------------
 //  Configuration
 //---------------------------------------------------------------------------
@@ -177,7 +169,7 @@
 //  Get pointer to Circular Shared Buffer
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION tShbCirBuff *ShbCirGetBuffer(tShbInstance pShbInstance_p)
+tShbCirBuff *ShbCirGetBuffer(tShbInstance pShbInstance_p)
 {
 
 	tShbCirBuff *pShbCirBuff;
@@ -193,7 +185,7 @@
 //  Get pointer to Linear Shared Buffer
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION tShbLinBuff *ShbLinGetBuffer(tShbInstance pShbInstance_p)
+tShbLinBuff *ShbLinGetBuffer(tShbInstance pShbInstance_p)
 {
 
 	tShbLinBuff *pShbLinBuff;
@@ -210,7 +202,6 @@
 void ShbCirSignalHandlerReset(tShbInstance pShbInstance_p,
 			      unsigned int fTimeOut_p);
 
-#endif
 
 //=========================================================================//
 //                                                                         //
@@ -218,7 +209,6 @@
 //                                                                         //
 //=========================================================================//
 
-#if !defined(INLINE_ENABLED)
 // not inlined external functions
 
 //---------------------------------------------------------------------------
@@ -363,18 +353,13 @@
 
 }
 
-#endif // !defined(INLINE_ENABLED)
-
-#if (!defined(SHAREDBUFF_INLINED)) || defined(INLINE_ENABLED)
-
 //---------------------------------------------------------------------------
 //  Reset Circular Shared Buffer
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION tShbError ShbCirResetBuffer(tShbInstance pShbInstance_p,
-					    unsigned long ulTimeOut_p,
-					    tShbCirSigHndlrReset
-					    pfnSignalHandlerReset_p)
+tShbError ShbCirResetBuffer(tShbInstance pShbInstance_p,
+			    unsigned long ulTimeOut_p,
+			    tShbCirSigHndlrReset pfnSignalHandlerReset_p)
 {
 
 	tShbCirBuff *pShbCirBuff;
@@ -440,9 +425,9 @@
 //  Write data block to Circular Shared Buffer
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION tShbError ShbCirWriteDataBlock(tShbInstance pShbInstance_p,
-					       const void *pSrcDataBlock_p,
-					       unsigned long ulDataBlockSize_p)
+tShbError ShbCirWriteDataBlock(tShbInstance pShbInstance_p,
+			       const void *pSrcDataBlock_p,
+			       unsigned long ulDataBlockSize_p)
 {
 
 	tShbCirBuff *pShbCirBuff;
@@ -608,9 +593,9 @@
 //  Allocate block within the Circular Shared Buffer for chunk writing
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION tShbError ShbCirAllocDataBlock(tShbInstance pShbInstance_p,
-					       tShbCirChunk * pShbCirChunk_p,
-					       unsigned long ulDataBufferSize_p)
+tShbError ShbCirAllocDataBlock(tShbInstance pShbInstance_p,
+			       tShbCirChunk * pShbCirChunk_p,
+			       unsigned long ulDataBufferSize_p)
 {
 
 	tShbCirBuff *pShbCirBuff;
@@ -717,12 +702,11 @@
 //  Write data chunk into an allocated buffer of the Circular Shared Buffer
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION tShbError ShbCirWriteDataChunk(tShbInstance pShbInstance_p,
-					       tShbCirChunk * pShbCirChunk_p,
-					       const void *pSrcDataChunk_p,
-					       unsigned long ulDataChunkSize_p,
-					       unsigned int
-					       *pfBufferCompleted_p)
+tShbError ShbCirWriteDataChunk(tShbInstance pShbInstance_p,
+			       tShbCirChunk *pShbCirChunk_p,
+			       const void *pSrcDataChunk_p,
+			       unsigned long ulDataChunkSize_p,
+			       unsigned int *pfBufferCompleted_p)
 {
 
 	tShbCirBuff *pShbCirBuff;
@@ -857,10 +841,10 @@
 //  Read data block from Circular Shared Buffer
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION tShbError ShbCirReadDataBlock(tShbInstance pShbInstance_p,
-					      void *pDstDataBlock_p,
-					      unsigned long ulRdBuffSize_p,
-					      unsigned long *pulDataBlockSize_p)
+tShbError ShbCirReadDataBlock(tShbInstance pShbInstance_p,
+			      void *pDstDataBlock_p,
+			      unsigned long ulRdBuffSize_p,
+			      unsigned long *pulDataBlockSize_p)
 {
 
 	tShbCirBuff *pShbCirBuff;
@@ -1009,9 +993,8 @@
 //  Get data size of next readable block from Circular Shared Buffer
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION tShbError ShbCirGetReadDataSize(tShbInstance pShbInstance_p,
-						unsigned long
-						*pulDataBlockSize_p)
+tShbError ShbCirGetReadDataSize(tShbInstance pShbInstance_p,
+				unsigned long *pulDataBlockSize_p)
 {
 
 	tShbCirBuff *pShbCirBuff;
@@ -1070,9 +1053,8 @@
 //  Get number of readable blocks from Circular Shared Buffer
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION tShbError ShbCirGetReadBlockCount(tShbInstance pShbInstance_p,
-						  unsigned long
-						  *pulDataBlockCount_p)
+tShbError ShbCirGetReadBlockCount(tShbInstance pShbInstance_p,
+				  unsigned long *pulDataBlockCount_p)
 {
 
 	tShbCirBuff *pShbCirBuff;
@@ -1113,12 +1095,9 @@
 //  d.k.: new parameter priority as enum
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION tShbError ShbCirSetSignalHandlerNewData(tShbInstance
-							pShbInstance_p,
-							tShbCirSigHndlrNewData
-							pfnSignalHandlerNewData_p,
-							tShbPriority
-							ShbPriority_p)
+tShbError ShbCirSetSignalHandlerNewData(tShbInstance pShbInstance_p,
+					tShbCirSigHndlrNewData pfnSignalHandlerNewData_p,
+					tShbPriority ShbPriority_p)
 {
 
 	tShbCirBuff *pShbCirBuff;
@@ -1165,10 +1144,6 @@
 
 }
 
-#endif
-
-#if !defined(INLINE_ENABLED)
-
 //---------------------------------------------------------------------------
 //  DEBUG: Trace Circular Shared Buffer
 //---------------------------------------------------------------------------
@@ -1413,18 +1388,13 @@
 
 }
 
-#endif // !defined(INLINE_ENABLED)
-
-#if (!defined(SHAREDBUFF_INLINED)) || defined(INLINE_ENABLED)
-
 //---------------------------------------------------------------------------
 //  Write data block to Linear Shared Buffer
 //---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbLinWriteDataBlock(tShbInstance pShbInstance_p,
-					       unsigned long ulDstBufferOffs_p,
-					       const void *pSrcDataBlock_p,
-					       unsigned long ulDataBlockSize_p)
+tShbError ShbLinWriteDataBlock(tShbInstance pShbInstance_p,
+			       unsigned long ulDstBufferOffs_p,
+			       const void *pSrcDataBlock_p,
+			       unsigned long ulDataBlockSize_p)
 {
 
 	tShbLinBuff *pShbLinBuff;
@@ -1489,11 +1459,10 @@
 //---------------------------------------------------------------------------
 //  Read data block from Linear Shared Buffer
 //---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbLinReadDataBlock(tShbInstance pShbInstance_p,
-					      void *pDstDataBlock_p,
-					      unsigned long ulSrcBufferOffs_p,
-					      unsigned long ulDataBlockSize_p)
+tShbError ShbLinReadDataBlock(tShbInstance pShbInstance_p,
+			      void *pDstDataBlock_p,
+			      unsigned long ulSrcBufferOffs_p,
+			      unsigned long ulDataBlockSize_p)
 {
 
 	tShbLinBuff *pShbLinBuff;
@@ -1555,10 +1524,6 @@
 
 }
 
-#endif
-
-#if !defined(INLINE_ENABLED)
-
 //---------------------------------------------------------------------------
 //  DEBUG: Trace Linear Shared Buffer
 //---------------------------------------------------------------------------
@@ -1639,7 +1604,7 @@
 	ulBuffSize = ulDataSize_p;
 
 	if (pszInfoText_p != NULL) {
-		TRACE0(pszInfoText_p);
+		TRACE1("%s", pszInfoText_p);
 	}
 	// dump buffer contents
 	for (nRow = 0;; nRow++) {
@@ -1794,6 +1759,4 @@
 
 }
 
-#endif
-
 // EOF
diff --git a/drivers/staging/epl/SharedBuff.h b/drivers/staging/epl/SharedBuff.h
index 0ec1b4b..4edbd0b 100644
--- a/drivers/staging/epl/SharedBuff.h
+++ b/drivers/staging/epl/SharedBuff.h
@@ -110,15 +110,6 @@
 extern "C" {
 #endif
 
-/*#if defined(INLINE_FUNCTION_DEF)
-    #undef  INLINE_FUNCTION
-    #define INLINE_FUNCTION     INLINE_FUNCTION_DEF
-    #define INLINE_ENABLED      TRUE
-    #define SHAREDBUFF_INLINED
-    #include "SharedBuff.c"
-#endif
-*/
-
 	tShbError ShbInit(void);
 	tShbError ShbExit(void);
 
@@ -129,7 +120,6 @@
 				    unsigned int *pfShbNewCreated_p);
 	tShbError ShbCirReleaseBuffer(tShbInstance pShbInstance_p);
 
-#if !defined(INLINE_ENABLED)
 
 	tShbError ShbCirResetBuffer(tShbInstance pShbInstance_p,
 				    unsigned long ulTimeOut_p,
@@ -159,7 +149,6 @@
 						pfnShbSignalHandlerNewData_p,
 						tShbPriority ShbPriority_p);
 
-#endif
 
 // Linear Shared Buffer
 	tShbError ShbLinAllocBuffer(unsigned long ulBufferSize_p,
@@ -168,7 +157,6 @@
 				    unsigned int *pfShbNewCreated_p);
 	tShbError ShbLinReleaseBuffer(tShbInstance pShbInstance_p);
 
-#if !defined(INLINE_ENABLED)
 
 	tShbError ShbLinWriteDataBlock(tShbInstance pShbInstance_p,
 				       unsigned long ulDstBufferOffs_p,
@@ -179,7 +167,6 @@
 				      unsigned long ulSrcBufferOffs_p,
 				      unsigned long ulDataBlockSize_p);
 
-#endif
 
 #ifndef NDEBUG
 	tShbError ShbCirTraceBuffer(tShbInstance pShbInstance_p);
@@ -194,10 +181,6 @@
 #define ShbTraceDump(p0, p1, p2, p3)
 #endif
 
-#undef  INLINE_ENABLED		// disable actual inlining of functions
-#undef  INLINE_FUNCTION
-#define INLINE_FUNCTION		// define INLINE_FUNCTION to nothing
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/drivers/staging/epl/ShbIpc-LinuxKernel.c b/drivers/staging/epl/ShbIpc-LinuxKernel.c
index 1d3cb3f..497938b 100644
--- a/drivers/staging/epl/ShbIpc-LinuxKernel.c
+++ b/drivers/staging/epl/ShbIpc-LinuxKernel.c
@@ -79,8 +79,6 @@
 /*                                                                         */
 /***************************************************************************/
 
-#if (!defined(SHBIPC_INLINED)) || defined(SHBIPC_INLINE_ENABLED)
-
 //---------------------------------------------------------------------------
 //  Configuration
 //---------------------------------------------------------------------------
@@ -211,13 +209,11 @@
 // not inlined internal functions
 int ShbIpcThreadSignalNewData(void *pvThreadParam_p);
 int ShbIpcThreadSignalJobReady(void *pvThreadParam_p);
-#endif
 
 //---------------------------------------------------------------------------
 // modul globale vars
 //---------------------------------------------------------------------------
 
-#if !defined(SHBIPC_INLINE_ENABLED)
 struct sShbMemTable *psMemTableElementFirst_g;
 
 static void *ShbIpcAllocPrivateMem(unsigned long ulMemSize_p);
@@ -230,7 +226,6 @@
 static unsigned long ShbIpcCrc32GetCrc(const char *pcString,
 				       unsigned long aulCrcTable[256]);
 
-#endif
 
 //=========================================================================//
 //                                                                         //
@@ -238,7 +233,6 @@
 //                                                                         //
 //=========================================================================//
 
-#if !defined(SHBIPC_INLINE_ENABLED)
 // not inlined external functions
 
 //---------------------------------------------------------------------------
@@ -433,15 +427,11 @@
 	return (ShbError);
 }
 
-#endif // !defined(SHBIPC_INLINE_ENABLED)
-
-#if (!defined(SHBIPC_INLINED)) || defined(SHBIPC_INLINE_ENABLED)
-
 //---------------------------------------------------------------------------
 //  Enter atomic section for Shared Buffer access
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION tShbError ShbIpcEnterAtomicSection(tShbInstance pShbInstance_p)
+tShbError ShbIpcEnterAtomicSection(tShbInstance pShbInstance_p)
 {
 
 	tShbMemInst *pShbMemInst;
@@ -469,7 +459,7 @@
 //  Leave atomic section for Shared Buffer access
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION tShbError ShbIpcLeaveAtomicSection(tShbInstance pShbInstance_p)
+tShbError ShbIpcLeaveAtomicSection(tShbInstance pShbInstance_p)
 {
 
 	tShbMemInst *pShbMemInst;
@@ -496,12 +486,9 @@
 //  Start signaling of new data (called from reading process)
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION tShbError ShbIpcStartSignalingNewData(tShbInstance
-						      pShbInstance_p,
-						      tSigHndlrNewData
-						      pfnSignalHandlerNewData_p,
-						      tShbPriority
-						      ShbPriority_p)
+tShbError ShbIpcStartSignalingNewData(tShbInstance pShbInstance_p,
+				      tSigHndlrNewData pfnSignalHandlerNewData_p,
+				      tShbPriority ShbPriority_p)
 {
 	tShbMemInst *pShbMemInst;
 	tShbMemHeader *pShbMemHeader;
@@ -557,8 +544,7 @@
 //  Stop signaling of new data (called from reading process)
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION tShbError ShbIpcStopSignalingNewData(tShbInstance
-						     pShbInstance_p)
+tShbError ShbIpcStopSignalingNewData(tShbInstance pShbInstance_p)
 {
 	tShbMemInst *pShbMemInst;
 	tShbMemHeader *pShbMemHeader;
@@ -604,7 +590,7 @@
 //  Signal new data (called from writing process)
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION tShbError ShbIpcSignalNewData(tShbInstance pShbInstance_p)
+tShbError ShbIpcSignalNewData(tShbInstance pShbInstance_p)
 {
 	tShbMemHeader *pShbMemHeader;
 
@@ -625,12 +611,9 @@
 //  Start signaling for job ready (called from waiting process)
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION tShbError ShbIpcStartSignalingJobReady(tShbInstance
-						       pShbInstance_p,
-						       unsigned long
-						       ulTimeOut_p,
-						       tSigHndlrJobReady
-						       pfnSignalHandlerJobReady_p)
+tShbError ShbIpcStartSignalingJobReady(tShbInstance pShbInstance_p,
+				       unsigned long ulTimeOut_p,
+				       tSigHndlrJobReady pfnSignalHandlerJobReady_p)
 {
 	tShbMemInst *pShbMemInst;
 	tShbMemHeader *pShbMemHeader;
@@ -663,7 +646,7 @@
 //  Signal job ready (called from executing process)
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION tShbError ShbIpcSignalJobReady(tShbInstance pShbInstance_p)
+tShbError ShbIpcSignalJobReady(tShbInstance pShbInstance_p)
 {
 	tShbMemHeader *pShbMemHeader;
 
@@ -685,7 +668,7 @@
 //  Get pointer to common used share memory area
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION void *ShbIpcGetShMemPtr(tShbInstance pShbInstance_p)
+void *ShbIpcGetShMemPtr(tShbInstance pShbInstance_p)
 {
 
 	tShbMemHeader *pShbMemHeader;
@@ -694,7 +677,7 @@
 	pShbMemHeader =
 	    ShbIpcGetShbMemHeader(ShbIpcGetShbMemInst(pShbInstance_p));
 	if (pShbMemHeader != NULL) {
-		pShbShMemPtr = (BYTE *) pShbMemHeader + sizeof(tShbMemHeader);
+		pShbShMemPtr = (u8 *) pShbMemHeader + sizeof(tShbMemHeader);
 	} else {
 		pShbShMemPtr = NULL;
 	}
@@ -703,16 +686,12 @@
 
 }
 
-#endif
-
 //=========================================================================//
 //                                                                         //
 //          P R I V A T E   F U N C T I O N S                              //
 //                                                                         //
 //=========================================================================//
 
-#if !defined(SHBIPC_INLINE_ENABLED)
-
 //---------------------------------------------------------------------------
 //  Get pointer to process local information structure
 //---------------------------------------------------------------------------
@@ -963,4 +942,3 @@
 
 }
 
-#endif
diff --git a/drivers/staging/epl/ShbIpc-Win32.c b/drivers/staging/epl/ShbIpc-Win32.c
deleted file mode 100644
index b918147..0000000
--- a/drivers/staging/epl/ShbIpc-Win32.c
+++ /dev/null
@@ -1,1202 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      Project independend shared buffer (linear + circular)
-
-  Description:  Implementation of platform specific part for the
-                shared buffer
-                (Implementation for Win32)
-
-  License:
-
-    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 SYSTEC electronic GmbH nor the names of its
-       contributors may be used to endorse or promote products derived
-       from this software without prior written permission. For written
-       permission, please contact info@systec-electronic.com.
-
-    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 HOLDERS 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.
-
-    Severability Clause:
-
-        If a provision of this License is or becomes illegal, invalid or
-        unenforceable in any jurisdiction, that shall not affect:
-        1. the validity or enforceability in that jurisdiction of any other
-           provision of this License; or
-        2. the validity or enforceability in other jurisdictions of that or
-           any other provision of this License.
-
-  -------------------------------------------------------------------------
-
-  2006/06/27 -rs:   V 1.00 (initial version)
-
-****************************************************************************/
-
-#define WINVER       0x0400	// #defines necessary for usage of
-#define _WIN32_WINNT 0x0400	// function <SignalObjectAndWait>
-
-#include <windows.h>
-#include <stdio.h>
-#include "global.h"
-#include "sharedbuff.h"
-#include "shbipc.h"
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-#if (!defined(SHBIPC_INLINED)) || defined(SHBIPC_INLINE_ENABLED)
-
-//---------------------------------------------------------------------------
-//  Configuration
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-//  Constant definitions
-//---------------------------------------------------------------------------
-
-#define MAX_LEN_BUFFER_ID       MAX_PATH
-
-#define IDX_EVENT_NEW_DATA      0
-#define IDX_EVENT_TERM_REQU     1
-#define IDX_EVENT_TERM_RESP     2
-
-#define NAME_MUTEX_BUFF_ACCESS  "BuffAccess"
-#define NAME_EVENT_NEW_DATA     "NewData"
-#define NAME_EVENT_TERM_REQU    "TermRequ"
-#define NAME_EVENT_TERM_RESP    "TermResp"
-#define NAME_EVENT_JOB_READY    "JobReady"
-
-#define TIMEOUT_ENTER_ATOMIC    1000	// for debgging: INFINITE
-#define TIMEOUT_TERM_THREAD     2000
-
-#define SBI_MAGIC_ID            0x5342492B	// magic ID ("SBI+")
-#define SBH_MAGIC_ID            0x5342482A	// magic ID ("SBH*")
-
-//---------------------------------------------------------------------------
-//  Local types
-//---------------------------------------------------------------------------
-
-// This structure is the common header for the shared memory region used
-// by all processes attached this shared memory. It includes common
-// information to administrate/manage the shared buffer from a couple of
-// separated processes (e.g. the refernce counter). This structure is
-// located at the start of the shared memory region itself and exists
-// consequently only one times per shared memory instance.
-typedef struct {
-	unsigned long m_SbhMagicID;	// magic ID ("SBH*")
-	unsigned long m_ulShMemSize;
-	unsigned long m_ulRefCount;
-	char m_szBufferID[MAX_LEN_BUFFER_ID];
-
-#ifndef NDEBUG
-	unsigned long m_ulOwnerProcID;
-#endif
-
-} tShbMemHeader;
-
-// This structure is the "external entry point" from a separate process
-// to get access to a shared buffer. This structure includes all platform
-// resp. target specific information to administrate/manage the shared
-// buffer from a separate process. Every process attached to the shared
-// buffer has its own runtime instance of this structure with its individual
-// runtime data (e.g. the scope of an event handle is limitted to the
-// owner process only). The structure member <m_pShbMemHeader> points
-// to the (process specific) start address of the shared memory region
-// itself.
-typedef struct {
-	unsigned long m_SbiMagicID;	// magic ID ("SBI+")
-	HANDLE m_hSharedMem;
-	HANDLE m_hMutexBuffAccess;
-	HANDLE m_hThreadNewData;	// thraed to signal that new data are available
-	HANDLE m_ahEventNewData[3];	// IDX_EVENT_NEW_DATA + IDX_EVENT_TERM_REQU + ID_EVENT_TERM_RESP
-	tSigHndlrNewData m_pfnSigHndlrNewData;
-	HANDLE m_hThreadJobReady;	// thread to signal that a job/operation is ready now (e.g. reset buffer)
-	HANDLE m_hEventJobReady;
-	unsigned long m_ulTimeOutJobReady;
-	tSigHndlrJobReady m_pfnSigHndlrJobReady;
-	tShbMemHeader *m_pShbMemHeader;
-
-#ifndef NDEBUG
-	unsigned long m_ulThreadIDNewData;
-	unsigned long m_ulThreadIDJobReady;
-#endif
-
-} tShbMemInst;
-
-//---------------------------------------------------------------------------
-//  Global variables
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-//  Local variables
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-//  Prototypes of internal functions
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-//  Get pointer to process local information structure
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbMemInst *ShbIpcGetShbMemInst(tShbInstance pShbInstance_p)
-{
-
-	tShbMemInst *pShbMemInst;
-
-	pShbMemInst = (tShbMemInst *) pShbInstance_p;
-	ASSERT(pShbMemInst->m_SbiMagicID == SBI_MAGIC_ID);
-
-	return (pShbMemInst);
-
-}
-
-//---------------------------------------------------------------------------
-//  Get pointer to shared memory header
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbMemHeader *ShbIpcGetShbMemHeader(tShbInstance
-						     pShbInstance_p)
-{
-
-	tShbMemInst *pShbMemInst;
-	tShbMemHeader *pShbMemHeader;
-
-	pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
-	pShbMemHeader = pShbMemInst->m_pShbMemHeader;
-	ASSERT(pShbMemHeader->m_SbhMagicID == SBH_MAGIC_ID);
-
-	return (pShbMemHeader);
-
-}
-
-// not inlined internal functions
-DWORD WINAPI ShbIpcThreadSignalNewData(LPVOID pvThreadParam_p);
-DWORD WINAPI ShbIpcThreadSignalJobReady(LPVOID pvThreadParam_p);
-const char *ShbIpcGetUniformObjectName(const char *pszEventJobName_p,
-				       const char *pszBufferID_p,
-				       BOOL fGlobalObject_p);
-
-#endif
-
-#if !defined(SHBIPC_INLINE_ENABLED)
-// true internal functions (not inlined)
-static void *ShbIpcAllocPrivateMem(unsigned long ulMemSize_p);
-static void ShbIpcReleasePrivateMem(void *pMem_p);
-#endif
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-#if !defined(SHBIPC_INLINE_ENABLED)
-// not inlined external functions
-
-//---------------------------------------------------------------------------
-//  Initialize IPC for Shared Buffer Module
-//---------------------------------------------------------------------------
-
-tShbError ShbIpcInit(void)
-{
-
-	return (kShbOk);
-
-}
-
-//---------------------------------------------------------------------------
-//  Deinitialize IPC for Shared Buffer Module
-//---------------------------------------------------------------------------
-
-tShbError ShbIpcExit(void)
-{
-
-	return (kShbOk);
-
-}
-
-//---------------------------------------------------------------------------
-//  Allocate Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbIpcAllocBuffer(unsigned long ulBufferSize_p,
-			    const char *pszBufferID_p,
-			    tShbInstance * ppShbInstance_p,
-			    unsigned int *pfShbNewCreated_p)
-{
-
-	HANDLE hSharedMem;
-	LPVOID pSharedMem;
-	unsigned long ulShMemSize;
-	tShbMemInst *pShbMemInst;
-	tShbMemHeader *pShbMemHeader;
-	tShbInstance pShbInstance;
-	unsigned int fShMemNewCreated;
-	const char *pszObjectName;
-	HANDLE hMutexBuffAccess;
-	HANDLE hEventNewData;
-	HANDLE hEventJobReady;
-	tShbError ShbError;
-
-	ulShMemSize = ulBufferSize_p + sizeof(tShbMemHeader);
-	pSharedMem = NULL;
-	pShbInstance = NULL;
-	fShMemNewCreated = FALSE;
-	ShbError = kShbOk;
-
-	//---------------------------------------------------------------
-	// (1) open an existing or create a new shared memory
-	//---------------------------------------------------------------
-	// try to open an already existing shared memory
-	// (created by an another process)
-	hSharedMem = OpenFileMapping(FILE_MAP_ALL_ACCESS,	// DWORD dwDesiredAccess
-				     FALSE,	// BOOL bInheritHandle
-				     pszBufferID_p);	// LPCTSTR lpName
-	if (hSharedMem != NULL) {
-		// a shared memory already exists
-		fShMemNewCreated = FALSE;
-	} else {
-		// it seams that this process is the first who wants to use the
-		// shared memory, so it has to create a new shared memory
-		hSharedMem = CreateFileMapping(INVALID_HANDLE_VALUE,	// HANDLE hFile
-					       NULL,	// LPSECURITY_ATTRIBUTES lpAttributes
-					       PAGE_READWRITE,	// DWORD flProtect
-					       0,	// DWORD dwMaximumSizeHigh
-					       ulShMemSize,	// DWORD dwMaximumSizeLow
-					       pszBufferID_p);	// LPCTSTR lpName
-
-		fShMemNewCreated = TRUE;
-	}
-
-	if (hSharedMem == NULL) {
-		ShbError = kShbOutOfMem;
-		goto Exit;
-	}
-
-	//---------------------------------------------------------------
-	// (2) get the pointer to the shared memory
-	//---------------------------------------------------------------
-	pSharedMem = MapViewOfFile(hSharedMem,	// HANDLE hFileMappingObject
-				   FILE_MAP_ALL_ACCESS,	// DWORD dwDesiredAccess,
-				   0,	// DWORD dwFileOffsetHigh,
-				   0,	// DWORD dwFileOffsetLow,
-				   ulShMemSize);	// SIZE_T dwNumberOfBytesToMap
-
-	if (pSharedMem == NULL) {
-		ShbError = kShbOutOfMem;
-		goto Exit;
-	}
-
-	//---------------------------------------------------------------
-	// (3) setup or update header and management information
-	//---------------------------------------------------------------
-	pShbMemHeader = (tShbMemHeader *) pSharedMem;
-
-	// allocate a memory block from process specific mempool to save
-	// process local information to administrate/manage the shared buffer
-	pShbMemInst =
-	    (tShbMemInst *) ShbIpcAllocPrivateMem(sizeof(tShbMemInst));
-	if (pShbMemInst == NULL) {
-		ShbError = kShbOutOfMem;
-		goto Exit;
-	}
-	// reset complete header to default values
-	pShbMemInst->m_SbiMagicID = SBI_MAGIC_ID;
-	pShbMemInst->m_hSharedMem = hSharedMem;
-	pShbMemInst->m_hMutexBuffAccess = INVALID_HANDLE_VALUE;
-	pShbMemInst->m_hThreadNewData = INVALID_HANDLE_VALUE;
-	pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA] =
-	    INVALID_HANDLE_VALUE;
-	pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] =
-	    INVALID_HANDLE_VALUE;
-	pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] =
-	    INVALID_HANDLE_VALUE;
-	pShbMemInst->m_pfnSigHndlrNewData = NULL;
-	pShbMemInst->m_hThreadJobReady = INVALID_HANDLE_VALUE;
-	pShbMemInst->m_hEventJobReady = INVALID_HANDLE_VALUE;
-	pShbMemInst->m_ulTimeOutJobReady = 0;
-	pShbMemInst->m_pfnSigHndlrJobReady = NULL;
-	pShbMemInst->m_pShbMemHeader = pShbMemHeader;
-
-#ifndef NDEBUG
-	{
-		pShbMemInst->m_ulThreadIDNewData = 0;
-		pShbMemInst->m_ulThreadIDJobReady = 0;
-	}
-#endif
-
-	// create mutex for buffer access
-	pszObjectName =
-	    ShbIpcGetUniformObjectName(NAME_MUTEX_BUFF_ACCESS, pszBufferID_p,
-				       TRUE);
-	hMutexBuffAccess = CreateMutex(NULL,	// LPSECURITY_ATTRIBUTES lpMutexAttributes
-				       FALSE,	// BOOL bInitialOwner
-				       pszObjectName);	// LPCTSTR lpName
-	pShbMemInst->m_hMutexBuffAccess = hMutexBuffAccess;
-	ASSERT(pShbMemInst->m_hMutexBuffAccess != NULL);
-
-	// The EventNewData is used for signaling of new data after a write
-	// operation (SetEvent) as well as for waiting for new data on the
-	// reader side (WaitForMultipleObjects). Because it's not known if
-	// this process will be read or write data, the event will be
-	// always created here.
-	pszObjectName =
-	    ShbIpcGetUniformObjectName(NAME_EVENT_NEW_DATA, pszBufferID_p,
-				       TRUE);
-	hEventNewData = CreateEvent(NULL,	// LPSECURITY_ATTRIBUTES lpEventAttributes
-				    FALSE,	// BOOL bManualReset
-				    FALSE,	// BOOL bInitialState
-				    pszObjectName);	// LPCTSTR lpName
-	pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA] = hEventNewData;
-	ASSERT(pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA] != NULL);
-
-	// The EventJobReady is used for signaling that a job is done (SetEvent)
-	// as well as for waiting for finishing of a job (WaitForMultipleObjects).
-	// Because it's not known if this process will signal or wait, the event
-	// will be always created here.
-	pszObjectName =
-	    ShbIpcGetUniformObjectName(NAME_EVENT_JOB_READY, pszBufferID_p,
-				       TRUE);
-	hEventJobReady = CreateEvent(NULL,	// LPSECURITY_ATTRIBUTES lpEventAttributes
-				     FALSE,	// BOOL bManualReset
-				     FALSE,	// BOOL bInitialState
-				     pszObjectName);	// LPCTSTR lpName
-	pShbMemInst->m_hEventJobReady = hEventJobReady;
-	ASSERT(pShbMemInst->m_hEventJobReady != NULL);
-
-	if (fShMemNewCreated) {
-		// this process was the first who wanted to use the shared memory,
-		// so a new shared memory was created
-		// -> setup new header information inside the shared memory region
-		//    itself
-		pShbMemHeader->m_SbhMagicID = SBH_MAGIC_ID;
-		pShbMemHeader->m_ulShMemSize = ulShMemSize;
-		pShbMemHeader->m_ulRefCount = 1;
-		strncpy(pShbMemHeader->m_szBufferID, pszBufferID_p,
-			sizeof(pShbMemHeader->m_szBufferID) - 1);
-
-#ifndef NDEBUG
-		{
-			pShbMemHeader->m_ulOwnerProcID = GetCurrentProcessId();
-		}
-#endif
-	} else {
-		// any other process has created the shared memory and this
-		// process has only attached to it
-		// -> check and update existing header information inside the
-		//    shared memory region itself
-		if (pShbMemHeader->m_ulShMemSize != ulShMemSize) {
-			ShbError = kShbOpenMismatch;
-			goto Exit;
-		}
-#ifndef NDEBUG
-		{
-			if (strncmp
-			    (pShbMemHeader->m_szBufferID, pszBufferID_p,
-			     sizeof(pShbMemHeader->m_szBufferID) - 1)) {
-				ShbError = kShbOpenMismatch;
-				goto Exit;
-			}
-		}
-#endif
-
-		pShbMemHeader->m_ulRefCount++;
-	}
-
-	// set abstarct "handle" for returning to application
-	pShbInstance = (tShbInstance *) pShbMemInst;
-
-      Exit:
-
-	if (ShbError != kShbOk) {
-		if (pShbMemInst != NULL) {
-			ShbIpcReleasePrivateMem(pShbMemInst);
-		}
-		if (pSharedMem != NULL) {
-			UnmapViewOfFile(pSharedMem);
-		}
-		if (hSharedMem != NULL) {
-			CloseHandle(hSharedMem);
-		}
-	}
-
-	*pfShbNewCreated_p = fShMemNewCreated;
-	*ppShbInstance_p = pShbInstance;
-
-	return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-//  Release Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbIpcReleaseBuffer(tShbInstance pShbInstance_p)
-{
-
-	tShbMemInst *pShbMemInst;
-	tShbMemHeader *pShbMemHeader;
-	HANDLE hEventNewData;
-	HANDLE hMutexBuffAccess;
-	tShbError ShbError;
-	tShbError ShbError2;
-
-	if (pShbInstance_p == NULL) {
-		return (kShbOk);
-	}
-
-	pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
-	pShbMemHeader = ShbIpcGetShbMemHeader(pShbInstance_p);
-
-	if (!--pShbMemHeader->m_ulRefCount) {
-		ShbError = kShbOk;
-	} else {
-		ShbError = kShbMemUsedByOtherProcs;
-	}
-
-	ShbError2 = ShbIpcStopSignalingNewData(pShbInstance_p);
-	hEventNewData = pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA];
-	if (hEventNewData != INVALID_HANDLE_VALUE) {
-		CloseHandle(hEventNewData);
-		pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA] =
-		    INVALID_HANDLE_VALUE;
-	}
-
-	hMutexBuffAccess = pShbMemInst->m_hMutexBuffAccess;
-	if (hMutexBuffAccess != INVALID_HANDLE_VALUE) {
-		CloseHandle(hMutexBuffAccess);
-		pShbMemInst->m_hMutexBuffAccess = INVALID_HANDLE_VALUE;
-	}
-
-	UnmapViewOfFile(pShbMemHeader);
-	if (pShbMemInst->m_hSharedMem != INVALID_HANDLE_VALUE) {
-		CloseHandle(pShbMemInst->m_hSharedMem);
-		pShbMemInst->m_hSharedMem = INVALID_HANDLE_VALUE;
-	}
-
-	ShbIpcReleasePrivateMem(pShbMemInst);
-
-	if (ShbError == kShbOk) {
-		ShbError = ShbError2;
-	}
-
-	return (ShbError);
-
-}
-
-#endif // !defined(SHBIPC_INLINE_ENABLED)
-
-#if (!defined(SHBIPC_INLINED)) || defined(SHBIPC_INLINE_ENABLED)
-
-//---------------------------------------------------------------------------
-//  Enter atomic section for Shared Buffer access
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbIpcEnterAtomicSection(tShbInstance pShbInstance_p)
-{
-
-	tShbMemInst *pShbMemInst;
-	HANDLE hMutexBuffAccess;
-	DWORD dwWaitResult;
-	tShbError ShbError;
-
-	if (pShbInstance_p == NULL) {
-		return (kShbInvalidArg);
-	}
-
-	pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
-	ShbError = kShbOk;
-
-	hMutexBuffAccess = pShbMemInst->m_hMutexBuffAccess;
-	if (hMutexBuffAccess != INVALID_HANDLE_VALUE) {
-		dwWaitResult =
-		    WaitForSingleObject(hMutexBuffAccess, TIMEOUT_ENTER_ATOMIC);
-		switch (dwWaitResult) {
-		case WAIT_OBJECT_0 + 0:
-			{
-				break;
-			}
-
-		case WAIT_TIMEOUT:
-			{
-				TRACE0
-				    ("\nShbIpcEnterAtomicSection(): WAIT_TIMEOUT");
-				ASSERT(0);
-				ShbError = kShbBufferInvalid;
-				break;
-			}
-
-		case WAIT_ABANDONED:
-			{
-				TRACE0
-				    ("\nShbIpcEnterAtomicSection(): WAIT_ABANDONED");
-				ASSERT(0);
-				ShbError = kShbBufferInvalid;
-				break;
-			}
-
-		case WAIT_FAILED:
-			{
-				TRACE1
-				    ("\nShbIpcEnterAtomicSection(): WAIT_FAILED -> LastError=%ld",
-				     GetLastError());
-				ASSERT(0);
-				ShbError = kShbBufferInvalid;
-				break;
-			}
-
-		default:
-			{
-				TRACE1
-				    ("\nShbIpcEnterAtomicSection(): unknown error -> LastError=%ld",
-				     GetLastError());
-				ASSERT(0);
-				ShbError = kShbBufferInvalid;
-				break;
-			}
-		}
-	} else {
-		ShbError = kShbBufferInvalid;
-	}
-
-	return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-//  Leave atomic section for Shared Buffer access
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbIpcLeaveAtomicSection(tShbInstance pShbInstance_p)
-{
-
-	tShbMemInst *pShbMemInst;
-	HANDLE hMutexBuffAccess;
-	BOOL fRes;
-	tShbError ShbError;
-
-	if (pShbInstance_p == NULL) {
-		return (kShbInvalidArg);
-	}
-
-	pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
-	ShbError = kShbOk;
-
-	hMutexBuffAccess = pShbMemInst->m_hMutexBuffAccess;
-	if (hMutexBuffAccess != INVALID_HANDLE_VALUE) {
-		fRes = ReleaseMutex(hMutexBuffAccess);
-		ASSERT(fRes);
-	} else {
-		ShbError = kShbBufferInvalid;
-	}
-
-	return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-//  Start signaling of new data (called from reading process)
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbIpcStartSignalingNewData(tShbInstance
-						      pShbInstance_p,
-						      tSigHndlrNewData
-						      pfnSignalHandlerNewData_p,
-						      tShbPriority
-						      ShbPriority_p)
-{
-
-	tShbMemInst *pShbMemInst;
-	tShbMemHeader *pShbMemHeader;
-	const char *pszObjectName;
-	HANDLE hEventTermRequ;
-	HANDLE hEventTermResp;
-	HANDLE hThreadNewData;
-	unsigned long ulThreadIDNewData;
-	tShbError ShbError;
-	int iPriority;
-
-	if ((pShbInstance_p == NULL) || (pfnSignalHandlerNewData_p == NULL)) {
-		return (kShbInvalidArg);
-	}
-
-	pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
-	pShbMemHeader = ShbIpcGetShbMemHeader(pShbInstance_p);
-	ShbError = kShbOk;
-
-	if ((pShbMemInst->m_hThreadNewData != INVALID_HANDLE_VALUE) ||
-	    (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] !=
-	     INVALID_HANDLE_VALUE)
-	    || (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] !=
-		INVALID_HANDLE_VALUE)
-	    || (pShbMemInst->m_pfnSigHndlrNewData != NULL)) {
-		ShbError = kShbAlreadySignaling;
-		goto Exit;
-	}
-
-	pShbMemInst->m_pfnSigHndlrNewData = pfnSignalHandlerNewData_p;
-
-	// Because the event <pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA]>
-	// is used for signaling of new data after a write operation too (using
-	// SetEvent), it is always created here (see <ShbIpcAllocBuffer>).
-
-	pszObjectName =
-	    ShbIpcGetUniformObjectName(NAME_EVENT_TERM_REQU,
-				       pShbMemHeader->m_szBufferID, FALSE);
-	hEventTermRequ = CreateEvent(NULL,	// LPSECURITY_ATTRIBUTES lpEventAttributes
-				     FALSE,	// BOOL bManualReset
-				     FALSE,	// BOOL bInitialState
-				     pszObjectName);	// LPCTSTR lpName
-	pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] = hEventTermRequ;
-	ASSERT(pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] != NULL);
-
-	pszObjectName =
-	    ShbIpcGetUniformObjectName(NAME_EVENT_TERM_RESP,
-				       pShbMemHeader->m_szBufferID, FALSE);
-	hEventTermResp = CreateEvent(NULL,	// LPSECURITY_ATTRIBUTES lpEventAttributes
-				     FALSE,	// BOOL bManualReset
-				     FALSE,	// BOOL bInitialState
-				     pszObjectName);	// LPCTSTR lpName
-	pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] = hEventTermResp;
-	ASSERT(pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] != NULL);
-
-	hThreadNewData = CreateThread(NULL,	// LPSECURITY_ATTRIBUTES lpThreadAttributes
-				      0,	// SIZE_T dwStackSize
-				      ShbIpcThreadSignalNewData,	// LPTHREAD_START_ROUTINE lpStartAddress
-				      pShbInstance_p,	// LPVOID lpParameter
-				      0,	// DWORD dwCreationFlags
-				      &ulThreadIDNewData);	// LPDWORD lpThreadId
-
-	switch (ShbPriority_p) {
-	case kShbPriorityLow:
-		iPriority = THREAD_PRIORITY_BELOW_NORMAL;
-		break;
-
-	case kShbPriorityNormal:
-		iPriority = THREAD_PRIORITY_NORMAL;
-		break;
-
-	case kshbPriorityHigh:
-		iPriority = THREAD_PRIORITY_ABOVE_NORMAL;
-		break;
-
-	}
-
-	ASSERT(pShbMemInst->m_hThreadNewData != NULL);
-
-	SetThreadPriority(hThreadNewData, iPriority);
-
-	pShbMemInst->m_hThreadNewData = hThreadNewData;
-
-#ifndef NDEBUG
-	{
-		pShbMemInst->m_ulThreadIDNewData = ulThreadIDNewData;
-	}
-#endif
-
-      Exit:
-
-	return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-//  Stop signaling of new data (called from reading process)
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbIpcStopSignalingNewData(tShbInstance
-						     pShbInstance_p)
-{
-
-	tShbMemInst *pShbMemInst;
-	HANDLE hEventTermRequ;
-	HANDLE hEventTermResp;
-	DWORD dwWaitResult;
-
-	if (pShbInstance_p == NULL) {
-		return (kShbInvalidArg);
-	}
-
-	pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
-
-	// terminate new data signaling thread
-	// (set event <hEventTermRequ> to wakeup the thread and dispose it
-	// to exit, then wait for confirmation using event <hEventTermResp>)
-	hEventTermRequ = pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU];
-	hEventTermResp = pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP];
-	if ((hEventTermRequ != INVALID_HANDLE_VALUE) &&
-	    (hEventTermResp != INVALID_HANDLE_VALUE)) {
-		TRACE0("\nShbIpcStopSignalingNewData(): enter wait state");
-		dwWaitResult = SignalObjectAndWait(hEventTermRequ,	// HANDLE hObjectToSignal
-						   hEventTermResp,	// HANDLE hObjectToWaitOn
-						   TIMEOUT_TERM_THREAD,	// DWORD dwMilliseconds
-						   FALSE);	// BOOL bAlertable
-		TRACE0
-		    ("\nShbIpcStopSignalingNewData(): wait state leaved: ---> ");
-		switch (dwWaitResult) {
-		case WAIT_OBJECT_0 + 0:	// event "new data signaling thread terminated"
-			{
-				TRACE0("Event = WAIT_OBJECT_0+0");
-				break;
-			}
-
-		default:
-			{
-				TRACE0("Unhandled Event");
-				ASSERT(0);
-				break;
-			}
-		}
-	}
-
-	if (pShbMemInst->m_hThreadNewData != INVALID_HANDLE_VALUE) {
-		CloseHandle(pShbMemInst->m_hThreadNewData);
-		pShbMemInst->m_hThreadNewData = INVALID_HANDLE_VALUE;
-	}
-
-	if (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] !=
-	    INVALID_HANDLE_VALUE) {
-		CloseHandle(pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU]);
-		pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] =
-		    INVALID_HANDLE_VALUE;
-	}
-
-	if (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] !=
-	    INVALID_HANDLE_VALUE) {
-		CloseHandle(pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP]);
-		pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] =
-		    INVALID_HANDLE_VALUE;
-	}
-
-	pShbMemInst->m_pfnSigHndlrNewData = NULL;
-
-	return (kShbOk);
-
-}
-
-//---------------------------------------------------------------------------
-//  Signal new data (called from writing process)
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbIpcSignalNewData(tShbInstance pShbInstance_p)
-{
-
-	tShbMemInst *pShbMemInst;
-	HANDLE hEventNewData;
-	BOOL fRes;
-
-	// TRACE0("\nShbIpcSignalNewData(): enter\n");
-
-	if (pShbInstance_p == NULL) {
-		return (kShbInvalidArg);
-	}
-
-	pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
-
-	ASSERT(pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA] !=
-	       INVALID_HANDLE_VALUE);
-	hEventNewData = pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA];
-	if (hEventNewData != INVALID_HANDLE_VALUE) {
-		fRes = SetEvent(hEventNewData);
-		// TRACE1("\nShbIpcSignalNewData(): EventNewData set (Result=%d)\n", (int)fRes);
-		ASSERT(fRes);
-	}
-	// TRACE0("\nShbIpcSignalNewData(): leave\n");
-	return (kShbOk);
-
-}
-
-//---------------------------------------------------------------------------
-//  Start signaling for job ready (called from waiting process)
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbIpcStartSignalingJobReady(tShbInstance
-						       pShbInstance_p,
-						       unsigned long
-						       ulTimeOut_p,
-						       tSigHndlrJobReady
-						       pfnSignalHandlerJobReady_p)
-{
-
-	tShbMemInst *pShbMemInst;
-	tShbMemHeader *pShbMemHeader;
-	HANDLE hThreadJobReady;
-	unsigned long ulThreadIDJobReady;
-	tShbError ShbError;
-
-	if ((pShbInstance_p == NULL) || (pfnSignalHandlerJobReady_p == NULL)) {
-		return (kShbInvalidArg);
-	}
-
-	pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
-	pShbMemHeader = ShbIpcGetShbMemHeader(pShbInstance_p);
-	ShbError = kShbOk;
-
-	if ((pShbMemInst->m_hThreadJobReady != INVALID_HANDLE_VALUE) ||
-	    (pShbMemInst->m_pfnSigHndlrJobReady != NULL)) {
-		ShbError = kShbAlreadySignaling;
-		goto Exit;
-	}
-
-	pShbMemInst->m_ulTimeOutJobReady = ulTimeOut_p;
-	pShbMemInst->m_pfnSigHndlrJobReady = pfnSignalHandlerJobReady_p;
-
-	// Because the event <pShbMemInst->m_ahEventJobReady> is used for
-	// signaling of a finished job too (using SetEvent), it is always
-	// created here (see <ShbIpcAllocBuffer>).
-
-	hThreadJobReady = CreateThread(NULL,	// LPSECURITY_ATTRIBUTES lpThreadAttributes
-				       0,	// SIZE_T dwStackSize
-				       ShbIpcThreadSignalJobReady,	// LPTHREAD_START_ROUTINE lpStartAddress
-				       pShbInstance_p,	// LPVOID lpParameter
-				       0,	// DWORD dwCreationFlags
-				       &ulThreadIDJobReady);	// LPDWORD lpThreadId
-
-	pShbMemInst->m_hThreadJobReady = hThreadJobReady;
-	ASSERT(pShbMemInst->m_hThreadJobReady != NULL);
-
-#ifndef NDEBUG
-	{
-		pShbMemInst->m_ulThreadIDJobReady = ulThreadIDJobReady;
-	}
-#endif
-
-      Exit:
-
-	return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-//  Signal job ready (called from executing process)
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbIpcSignalJobReady(tShbInstance pShbInstance_p)
-{
-
-	tShbMemInst *pShbMemInst;
-	HANDLE hEventJobReady;
-	BOOL fRes;
-
-	// TRACE0("\nShbIpcSignalJobReady(): enter\n");
-
-	if (pShbInstance_p == NULL) {
-		return (kShbInvalidArg);
-	}
-
-	pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
-
-	ASSERT(pShbMemInst->m_hEventJobReady != INVALID_HANDLE_VALUE);
-	hEventJobReady = pShbMemInst->m_hEventJobReady;
-	if (hEventJobReady != INVALID_HANDLE_VALUE) {
-		fRes = SetEvent(hEventJobReady);
-		// TRACE1("\nShbIpcSignalJobReady(): EventJobReady set (Result=%d)\n", (int)fRes);
-		ASSERT(fRes);
-	}
-	// TRACE0("\nShbIpcSignalJobReady(): leave\n");
-	return (kShbOk);
-
-}
-
-//---------------------------------------------------------------------------
-//  Get pointer to common used share memory area
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION void *ShbIpcGetShMemPtr(tShbInstance pShbInstance_p)
-{
-
-	tShbMemHeader *pShbMemHeader;
-	void *pShbShMemPtr;
-
-	pShbMemHeader = ShbIpcGetShbMemHeader(pShbInstance_p);
-	if (pShbMemHeader != NULL) {
-		pShbShMemPtr = (BYTE *) pShbMemHeader + sizeof(tShbMemHeader);
-	} else {
-		pShbShMemPtr = NULL;
-	}
-
-	return (pShbShMemPtr);
-
-}
-
-#endif
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-#if !defined(SHBIPC_INLINE_ENABLED)
-
-//---------------------------------------------------------------------------
-//  Allocate a memory block from process specific mempool
-//---------------------------------------------------------------------------
-
-static void *ShbIpcAllocPrivateMem(unsigned long ulMemSize_p)
-{
-
-	HGLOBAL hMem;
-	void *pMem;
-
-	hMem = GlobalAlloc(GMEM_FIXED, ulMemSize_p + sizeof(HGLOBAL));
-	pMem = GlobalLock(hMem);
-	if (pMem != NULL) {
-		*(HGLOBAL *) pMem = hMem;
-		(BYTE *) pMem += sizeof(HGLOBAL);
-	}
-
-#ifndef NDEBUG
-	{
-		memset(pMem, 0xaa, ulMemSize_p);
-	}
-#endif
-
-	return (pMem);
-
-}
-
-//---------------------------------------------------------------------------
-//  Release a memory block from process specific mempool
-//---------------------------------------------------------------------------
-
-static void ShbIpcReleasePrivateMem(void *pMem_p)
-{
-
-	HGLOBAL hMem;
-
-	if (pMem_p == NULL) {
-		return;
-	}
-
-	(BYTE *) pMem_p -= sizeof(HGLOBAL);
-	hMem = *(HGLOBAL *) pMem_p;
-
-	GlobalUnlock(hMem);
-	GlobalFree(hMem);
-
-	return;
-
-}
-
-//---------------------------------------------------------------------------
-//  Create uniform object name (needed for inter-process communication)
-//---------------------------------------------------------------------------
-
-const char *ShbIpcGetUniformObjectName(const char *pszObjectJobName_p,
-				       const char *pszBufferID_p,
-				       BOOL fGlobalObject_p)
-{
-
-	static char szObjectName[MAX_PATH];
-	char szObjectPrefix[MAX_PATH];
-
-	if (fGlobalObject_p) {
-		strncpy(szObjectPrefix, "Global\\", sizeof(szObjectPrefix));
-	} else {
-		_snprintf(szObjectPrefix, sizeof(szObjectPrefix), "PID%08lX_",
-			  (unsigned long)GetCurrentProcessId());
-	}
-
-	_snprintf(szObjectName, sizeof(szObjectName), "%s%s#%s",
-		  szObjectPrefix, pszBufferID_p, pszObjectJobName_p);
-
-	return (szObjectName);
-
-}
-
-//---------------------------------------------------------------------------
-//  Thread for new data signaling
-//---------------------------------------------------------------------------
-
-DWORD WINAPI ShbIpcThreadSignalNewData(LPVOID pvThreadParam_p)
-{
-
-	tShbInstance pShbInstance;
-	tShbMemInst *pShbMemInst;
-	DWORD dwWaitResult;
-	BOOL fTermRequ;
-	int fCallAgain;
-
-	TRACE1
-	    ("\nShbIpcThreadSignalNewData(): SignalThread started (pShbInstance=0x%08lX)\n",
-	     (DWORD) pvThreadParam_p);
-
-	pShbInstance = (tShbMemInst *) pvThreadParam_p;
-	pShbMemInst = ShbIpcGetShbMemInst(pShbInstance);
-	fTermRequ = FALSE;
-
-	do {
-		ASSERT((pShbMemInst->m_ahEventNewData[0] !=
-			INVALID_HANDLE_VALUE)
-		       && (pShbMemInst->m_ahEventNewData[0] != NULL));
-		ASSERT((pShbMemInst->m_ahEventNewData[1] !=
-			INVALID_HANDLE_VALUE)
-		       && (pShbMemInst->m_ahEventNewData[1] != NULL));
-
-		TRACE0("\nShbIpcThreadSignalNewData(): enter wait state");
-		dwWaitResult = WaitForMultipleObjects(2,	// DWORD nCount
-						      pShbMemInst->m_ahEventNewData,	// const HANDLE* lpHandles
-						      FALSE,	// BOOL bWaitAll
-						      INFINITE);	// DWORD dwMilliseconds
-		TRACE0
-		    ("\nShbIpcThreadSignalNewData(): wait state leaved: ---> ");
-		switch (dwWaitResult) {
-		case WAIT_OBJECT_0 + 0:	// event "new data"
-			{
-				TRACE0("Event = WAIT_OBJECT_0+0");
-				if (pShbMemInst->m_pfnSigHndlrNewData != NULL) {
-					TRACE0
-					    ("\nShbIpcThreadSignalNewData(): calling SignalHandlerNewData");
-					do {
-						fCallAgain =
-						    pShbMemInst->
-						    m_pfnSigHndlrNewData
-						    (pShbInstance);
-						// d.k.: try to run any shared buffer which has higher priority.
-						//           under Windows this is not really necessary because the Windows scheduler
-						//           already preempts tasks with lower priority.
-					} while (fCallAgain != FALSE);
-				}
-				break;
-			}
-
-		case WAIT_OBJECT_0 + 1:	// event "terminate"
-			{
-				TRACE0("Event = WAIT_OBJECT_0+1");
-				fTermRequ = TRUE;
-				break;
-			}
-
-		default:
-			{
-				TRACE0("Unhandled Event");
-				ASSERT(0);
-				fTermRequ = TRUE;
-				break;
-			}
-		}
-	}
-	while (!fTermRequ);
-
-	if (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] !=
-	    INVALID_HANDLE_VALUE) {
-		SetEvent(pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP]);
-	}
-
-	TRACE1
-	    ("\nShbIpcThreadSignalNewData(): SignalThread terminated (pShbInstance=0x%08lX)\n",
-	     (DWORD) pShbInstance);
-
-	ExitThread(0);
-
-}
-
-//---------------------------------------------------------------------------
-//  Thread for new data signaling
-//---------------------------------------------------------------------------
-
-DWORD WINAPI ShbIpcThreadSignalJobReady(LPVOID pvThreadParam_p)
-{
-
-	tShbInstance *pShbInstance;
-	tShbMemInst *pShbMemInst;
-	DWORD ulTimeOut;
-	DWORD dwWaitResult;
-	unsigned int fTimeOut;
-
-	TRACE1
-	    ("\nShbIpcThreadSignalJobReady(): SignalThread started (pShbInstance=0x%08lX)\n",
-	     (DWORD) pvThreadParam_p);
-
-	pShbInstance = (tShbInstance *) pvThreadParam_p;
-	pShbMemInst = ShbIpcGetShbMemInst(pShbInstance);
-	fTimeOut = FALSE;
-
-	if (pShbMemInst->m_ulTimeOutJobReady != 0) {
-		ulTimeOut = pShbMemInst->m_ulTimeOutJobReady;
-	} else {
-		ulTimeOut = INFINITE;
-	}
-
-	ASSERT((pShbMemInst->m_hEventJobReady != INVALID_HANDLE_VALUE)
-	       && (pShbMemInst->m_hEventJobReady != NULL));
-
-	TRACE0("\nShbIpcThreadSignalJobReady(): enter wait state");
-	dwWaitResult = WaitForSingleObject(pShbMemInst->m_hEventJobReady,	// HANDLE hHandle
-					   ulTimeOut);	// DWORD dwMilliseconds
-	TRACE0("\nShbIpcThreadSignalJobReady(): wait state leaved: ---> ");
-	switch (dwWaitResult) {
-	case WAIT_OBJECT_0 + 0:	// event "new data"
-		{
-			TRACE0("Event = WAIT_OBJECT_0+0");
-			fTimeOut = FALSE;
-			break;
-		}
-
-	case WAIT_TIMEOUT:
-		{
-			TRACE0("\nEvent = WAIT_TIMEOUT");
-			fTimeOut = TRUE;
-			// ASSERT(0);
-			break;
-		}
-
-	default:
-		{
-			TRACE0("Unhandled Event");
-			fTimeOut = TRUE;
-			ASSERT(0);
-			break;
-		}
-	}
-
-	if (pShbMemInst->m_pfnSigHndlrJobReady != NULL) {
-		TRACE0
-		    ("\nShbIpcThreadSignalJobReady(): calling SignalHandlerJobReady");
-		pShbMemInst->m_pfnSigHndlrJobReady(pShbInstance, fTimeOut);
-	}
-
-	pShbMemInst->m_hThreadJobReady = INVALID_HANDLE_VALUE;
-	pShbMemInst->m_pfnSigHndlrJobReady = NULL;
-
-	TRACE1
-	    ("\nShbIpcThreadSignalJobReady(): SignalThread terminated (pShbInstance=0x%08lX)\n",
-	     (DWORD) pShbInstance);
-
-	ExitThread(0);
-
-}
-
-#endif
-
-// EOF
diff --git a/drivers/staging/epl/ShbIpc.h b/drivers/staging/epl/ShbIpc.h
index cad8846..285f096 100644
--- a/drivers/staging/epl/ShbIpc.h
+++ b/drivers/staging/epl/ShbIpc.h
@@ -65,25 +65,6 @@
 typedef void (*tSigHndlrJobReady) (tShbInstance pShbInstance_p,
 				   unsigned int fTimeOut_p);
 
-#if (TARGET_SYSTEM == _WIN32_)
-#if defined(INLINE_FUNCTION_DEF)
-#undef  INLINE_FUNCTION
-#define INLINE_FUNCTION     INLINE_FUNCTION_DEF
-#define SHBIPC_INLINE_ENABLED      TRUE
-#define SHBIPC_INLINED
-#include "ShbIpc-Win32.c"
-#endif
-
-#elif (TARGET_SYSTEM == _LINUX_)
-#if defined(INLINE_FUNCTION_DEF)
-#undef  INLINE_FUNCTION
-#define INLINE_FUNCTION     INLINE_FUNCTION_DEF
-#define SHBIPC_INLINE_ENABLED      TRUE
-#define SHBIPC_INLINED
-#include "ShbIpc-LinuxKernel.c"
-#endif
-#endif
-
 //---------------------------------------------------------------------------
 //  Prototypes
 //---------------------------------------------------------------------------
@@ -97,8 +78,6 @@
 			    unsigned int *pfShbNewCreated_p);
 tShbError ShbIpcReleaseBuffer(tShbInstance pShbInstance_p);
 
-#if !defined(SHBIPC_INLINE_ENABLED)
-
 tShbError ShbIpcEnterAtomicSection(tShbInstance pShbInstance_p);
 tShbError ShbIpcLeaveAtomicSection(tShbInstance pShbInstance_p);
 
@@ -116,10 +95,5 @@
 tShbError ShbIpcSignalJobReady(tShbInstance pShbInstance_p);
 
 void *ShbIpcGetShMemPtr(tShbInstance pShbInstance_p);
-#endif
-
-#undef  SHBIPC_INLINE_ENABLED	// disable actual inlining of functions
-#undef  INLINE_FUNCTION
-#define INLINE_FUNCTION		// define INLINE_FUNCTION to nothing
 
 #endif // #ifndef _SHBIPC_H_
diff --git a/drivers/staging/epl/TimerHighReskX86.c b/drivers/staging/epl/TimerHighReskX86.c
index 82eee47..d6897de 100644
--- a/drivers/staging/epl/TimerHighReskX86.c
+++ b/drivers/staging/epl/TimerHighReskX86.c
@@ -97,14 +97,10 @@
 
 #define PROVE_OVERRUN
 
-#ifndef CONFIG_HIGH_RES_TIMERS
-#error "Kernel symbol CONFIG_HIGH_RES_TIMERS is required."
-#endif
-
 // TracePoint support for realtime-debugging
 #ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
+void TgtDbgPostTraceValue(u32 dwTraceValue_p);
 #define TGT_DBG_SIGNAL_TRACE_POINT(p)   TgtDbgSignalTracePoint(p)
 #define TGT_DBG_POST_TRACE_VALUE(v)     TgtDbgPostTraceValue(v)
 #else
@@ -172,7 +168,7 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplTimerHighReskInit(void)
+tEplKernel EplTimerHighReskInit(void)
 {
 	tEplKernel Ret;
 
@@ -196,7 +192,7 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplTimerHighReskAddInstance(void)
+tEplKernel EplTimerHighReskAddInstance(void)
 {
 	tEplKernel Ret;
 	unsigned int uiIndex;
@@ -206,13 +202,6 @@
 	EPL_MEMSET(&EplTimerHighReskInstance_l, 0,
 		   sizeof(EplTimerHighReskInstance_l));
 
-#ifndef CONFIG_HIGH_RES_TIMERS
-	printk
-	    ("EplTimerHighResk: Kernel symbol CONFIG_HIGH_RES_TIMERS is required.\n");
-	Ret = kEplNoResource;
-	return Ret;
-#endif
-
 	/*
 	 * Initialize hrtimer structures for all usable timers.
 	 */
@@ -244,7 +233,7 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplTimerHighReskDelInstance(void)
+tEplKernel EplTimerHighReskDelInstance(void)
 {
 	tEplTimerHighReskTimerInfo *pTimerInfo;
 	tEplKernel Ret;
@@ -298,12 +287,11 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplTimerHighReskModifyTimerNs(tEplTimerHdl * pTimerHdl_p,
-						unsigned long long ullTimeNs_p,
-						tEplTimerkCallback
-						pfnCallback_p,
-						unsigned long ulArgument_p,
-						BOOL fContinuously_p)
+tEplKernel EplTimerHighReskModifyTimerNs(tEplTimerHdl *pTimerHdl_p,
+					 unsigned long long ullTimeNs_p,
+					 tEplTimerkCallback pfnCallback_p,
+					 unsigned long ulArgument_p,
+					 BOOL fContinuously_p)
 {
 	tEplKernel Ret;
 	unsigned int uiIndex;
@@ -396,7 +384,7 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC EplTimerHighReskDeleteTimer(tEplTimerHdl * pTimerHdl_p)
+tEplKernel EplTimerHighReskDeleteTimer(tEplTimerHdl *pTimerHdl_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 	unsigned int uiIndex;
diff --git a/drivers/staging/epl/VirtualEthernetLinux.c b/drivers/staging/epl/VirtualEthernetLinux.c
index 5d838db..21206c4 100644
--- a/drivers/staging/epl/VirtualEthernetLinux.c
+++ b/drivers/staging/epl/VirtualEthernetLinux.c
@@ -74,7 +74,6 @@
 
 ****************************************************************************/
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -285,7 +284,7 @@
 	return Ret;
 }
 
-tEplKernel PUBLIC VEthAddInstance(tEplDllkInitParam * pInitParam_p)
+tEplKernel VEthAddInstance(tEplDllkInitParam *pInitParam_p)
 {
 	tEplKernel Ret = kEplSuccessful;
 
@@ -324,7 +323,7 @@
 	return Ret;
 }
 
-tEplKernel PUBLIC VEthDelInstance(void)
+tEplKernel VEthDelInstance(void)
 {
 	tEplKernel Ret = kEplSuccessful;
 
diff --git a/drivers/staging/epl/amix86.c b/drivers/staging/epl/amix86.c
index 9f74238..d40ad91 100644
--- a/drivers/staging/epl/amix86.c
+++ b/drivers/staging/epl/amix86.c
@@ -74,24 +74,22 @@
 //#include "EplAmi.h"
 #include "EplInc.h"
 
-#if (!defined(EPL_AMI_INLINED)) || defined(INLINE_ENABLED)
-
 //---------------------------------------------------------------------------
 // typedef
 //---------------------------------------------------------------------------
 
 typedef struct {
-	WORD m_wWord;
+	u16 m_wWord;
 
 } twStruct;
 
 typedef struct {
-	DWORD m_dwDword;
+	u32 m_dwDword;
 
 } tdwStruct;
 
 typedef struct {
-	QWORD m_qwQword;
+	u64 m_qwQword;
 
 } tqwStruct;
 
@@ -117,37 +115,36 @@
 //
 //---------------------------------------------------------------------------
 
-//------------< write BYTE in big endian >--------------------------
+//------------< write u8 in big endian >--------------------------
 /*
-void  PUBLIC  AmiSetByteToBe (void FAR* pAddr_p, BYTE bByteVal_p)
+void AmiSetByteToBe (void *pAddr_p, u8 bByteVal_p)
 {
 
-   *(BYTE FAR*)pAddr_p = bByteVal_p;
+	*(u8 *)pAddr_p = bByteVal_p;
 
 }
 */
 
-//------------< write WORD in big endian >--------------------------
+//------------< write u16 in big endian >--------------------------
 
-INLINE_FUNCTION void PUBLIC AmiSetWordToBe(void FAR * pAddr_p, WORD wWordVal_p)
+void AmiSetWordToBe(void * pAddr_p, u16 wWordVal_p)
 {
-	twStruct FAR *pwStruct;
+	twStruct *pwStruct;
 	twStruct wValue;
 
-	wValue.m_wWord = (WORD) ((wWordVal_p & 0x00FF) << 8);	//LSB to MSB
-	wValue.m_wWord |= (WORD) ((wWordVal_p & 0xFF00) >> 8);	//MSB to LSB
+	wValue.m_wWord = (u16) ((wWordVal_p & 0x00FF) << 8);	//LSB to MSB
+	wValue.m_wWord |= (u16) ((wWordVal_p & 0xFF00) >> 8);	//MSB to LSB
 
-	pwStruct = (twStruct FAR *) pAddr_p;
+	pwStruct = (twStruct *) pAddr_p;
 	pwStruct->m_wWord = wValue.m_wWord;
 
 }
 
-//------------< write DWORD in big endian >-------------------------
+//------------< write u32 in big endian >-------------------------
 
-INLINE_FUNCTION void PUBLIC AmiSetDwordToBe(void FAR * pAddr_p,
-					    DWORD dwDwordVal_p)
+void AmiSetDwordToBe(void *pAddr_p, u32 dwDwordVal_p)
 {
-	tdwStruct FAR *pdwStruct;
+	tdwStruct *pdwStruct;
 	tdwStruct dwValue;
 
 	dwValue.m_dwDword = ((dwDwordVal_p & 0x000000FF) << 24);	//LSB to MSB
@@ -155,7 +152,7 @@
 	dwValue.m_dwDword |= ((dwDwordVal_p & 0x00FF0000) >> 8);
 	dwValue.m_dwDword |= ((dwDwordVal_p & 0xFF000000) >> 24);	//MSB to LSB
 
-	pdwStruct = (tdwStruct FAR *) pAddr_p;
+	pdwStruct = (tdwStruct *) pAddr_p;
 	pdwStruct->m_dwDword = dwValue.m_dwDword;
 
 }
@@ -176,35 +173,34 @@
 //
 //---------------------------------------------------------------------------
 
-//------------< write BYTE in little endian >--------------------------
+//------------< write u8 in little endian >--------------------------
 /*
-void  PUBLIC  AmiSetByteToLe (void FAR* pAddr_p, BYTE bByteVal_p)
+void AmiSetByteToLe (void *pAddr_p, u8 bByteVal_p)
 {
 
-   *(BYTE FAR*)pAddr_p = bByteVal_p;
+	*(u8 *)pAddr_p = bByteVal_p;
 
 }
 */
 
-//------------< write WORD in little endian >--------------------------
+//------------< write u16 in little endian >--------------------------
 
-INLINE_FUNCTION void PUBLIC AmiSetWordToLe(void FAR * pAddr_p, WORD wWordVal_p)
+void AmiSetWordToLe(void *pAddr_p, u16 wWordVal_p)
 {
-	twStruct FAR *pwStruct;
+	twStruct *pwStruct;
 
-	pwStruct = (twStruct FAR *) pAddr_p;
+	pwStruct = (twStruct *) pAddr_p;
 	pwStruct->m_wWord = wWordVal_p;
 
 }
 
-//------------< write DWORD in little endian >-------------------------
+//------------< write u32 in little endian >-------------------------
 
-INLINE_FUNCTION void PUBLIC AmiSetDwordToLe(void FAR * pAddr_p,
-					    DWORD dwDwordVal_p)
+void AmiSetDwordToLe(void *pAddr_p, u32 dwDwordVal_p)
 {
-	tdwStruct FAR *pdwStruct;
+	tdwStruct *pdwStruct;
 
-	pdwStruct = (tdwStruct FAR *) pAddr_p;
+	pdwStruct = (tdwStruct *) pAddr_p;
 	pdwStruct->m_dwDword = dwDwordVal_p;
 
 }
@@ -224,40 +220,40 @@
 //
 //---------------------------------------------------------------------------
 
-//------------< read BYTE in big endian >---------------------------
+//------------< read u8 in big endian >---------------------------
 /*
-BYTE  PUBLIC  AmiGetByteFromBe (void FAR* pAddr_p)
+u8 AmiGetByteFromBe (void *pAddr_p)
 {
 
-   return ( *(BYTE FAR*)pAddr_p );
+	return ( *(u8 *)pAddr_p );
 
 }
 */
 
-//------------< read WORD in big endian >---------------------------
+//------------< read u16 in big endian >---------------------------
 
-INLINE_FUNCTION WORD PUBLIC AmiGetWordFromBe(void FAR * pAddr_p)
+u16 AmiGetWordFromBe(void *pAddr_p)
 {
-	twStruct FAR *pwStruct;
+	twStruct *pwStruct;
 	twStruct wValue;
 
-	pwStruct = (twStruct FAR *) pAddr_p;
+	pwStruct = (twStruct *) pAddr_p;
 
-	wValue.m_wWord = (WORD) ((pwStruct->m_wWord & 0x00FF) << 8);	//LSB to MSB
-	wValue.m_wWord |= (WORD) ((pwStruct->m_wWord & 0xFF00) >> 8);	//MSB to LSB
+	wValue.m_wWord = (u16) ((pwStruct->m_wWord & 0x00FF) << 8);	//LSB to MSB
+	wValue.m_wWord |= (u16) ((pwStruct->m_wWord & 0xFF00) >> 8);	//MSB to LSB
 
 	return (wValue.m_wWord);
 
 }
 
-//------------< read DWORD in big endian >--------------------------
+//------------< read u32 in big endian >--------------------------
 
-INLINE_FUNCTION DWORD PUBLIC AmiGetDwordFromBe(void FAR * pAddr_p)
+u32 AmiGetDwordFromBe(void *pAddr_p)
 {
-	tdwStruct FAR *pdwStruct;
+	tdwStruct *pdwStruct;
 	tdwStruct dwValue;
 
-	pdwStruct = (tdwStruct FAR *) pAddr_p;
+	pdwStruct = (tdwStruct *) pAddr_p;
 
 	dwValue.m_dwDword = ((pdwStruct->m_dwDword & 0x000000FF) << 24);	//LSB to MSB
 	dwValue.m_dwDword |= ((pdwStruct->m_dwDword & 0x0000FF00) << 8);
@@ -283,36 +279,34 @@
 //
 //---------------------------------------------------------------------------
 
-//------------< read BYTE in little endian >---------------------------
+//------------< read u8 in little endian >---------------------------
 /*
-BYTE  PUBLIC  AmiGetByteFromLe (void FAR* pAddr_p)
+u8 AmiGetByteFromLe (void *pAddr_p)
 {
 
-   return ( *(BYTE FAR*)pAddr_p );
+	return ( *(u8 *)pAddr_p );
 
 }
 */
 
-//------------< read WORD in little endian >---------------------------
+//------------< read u16 in little endian >---------------------------
 
-INLINE_FUNCTION WORD PUBLIC AmiGetWordFromLe(void FAR * pAddr_p)
+u16 AmiGetWordFromLe(void *pAddr_p)
 {
-	twStruct FAR *pwStruct;
+	twStruct *pwStruct;
 
-	pwStruct = (twStruct FAR *) pAddr_p;
+	pwStruct = (twStruct *) pAddr_p;
 	return (pwStruct->m_wWord);
-
 }
 
-//------------< read DWORD in little endian >--------------------------
+//------------< read u32 in little endian >--------------------------
 
-INLINE_FUNCTION DWORD PUBLIC AmiGetDwordFromLe(void FAR * pAddr_p)
+u32 AmiGetDwordFromLe(void *pAddr_p)
 {
-	tdwStruct FAR *pdwStruct;
+	tdwStruct *pdwStruct;
 
-	pdwStruct = (tdwStruct FAR *) pAddr_p;
+	pdwStruct = (tdwStruct *) pAddr_p;
 	return (pdwStruct->m_dwDword);
-
 }
 
 //---------------------------------------------------------------------------
@@ -330,14 +324,11 @@
 //
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION void PUBLIC AmiSetDword24ToBe(void FAR * pAddr_p,
-					      DWORD dwDwordVal_p)
+void AmiSetDword24ToBe(void *pAddr_p, u32 dwDwordVal_p)
 {
-
-	((BYTE FAR *) pAddr_p)[0] = ((BYTE FAR *) & dwDwordVal_p)[2];
-	((BYTE FAR *) pAddr_p)[1] = ((BYTE FAR *) & dwDwordVal_p)[1];
-	((BYTE FAR *) pAddr_p)[2] = ((BYTE FAR *) & dwDwordVal_p)[0];
-
+	((u8 *) pAddr_p)[0] = ((u8 *) & dwDwordVal_p)[2];
+	((u8 *) pAddr_p)[1] = ((u8 *) & dwDwordVal_p)[1];
+	((u8 *) pAddr_p)[2] = ((u8 *) & dwDwordVal_p)[0];
 }
 
 //---------------------------------------------------------------------------
@@ -355,14 +346,11 @@
 //
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION void PUBLIC AmiSetDword24ToLe(void FAR * pAddr_p,
-					      DWORD dwDwordVal_p)
+void AmiSetDword24ToLe(void *pAddr_p, u32 dwDwordVal_p)
 {
-
-	((BYTE FAR *) pAddr_p)[0] = ((BYTE FAR *) & dwDwordVal_p)[0];
-	((BYTE FAR *) pAddr_p)[1] = ((BYTE FAR *) & dwDwordVal_p)[1];
-	((BYTE FAR *) pAddr_p)[2] = ((BYTE FAR *) & dwDwordVal_p)[2];
-
+	((u8 *) pAddr_p)[0] = ((u8 *) & dwDwordVal_p)[0];
+	((u8 *) pAddr_p)[1] = ((u8 *) & dwDwordVal_p)[1];
+	((u8 *) pAddr_p)[2] = ((u8 *) & dwDwordVal_p)[2];
 }
 
 //---------------------------------------------------------------------------
@@ -373,22 +361,19 @@
 //
 // Parameters:  pAddr_p         = pointer to source buffer
 //
-// Return:      DWORD           = read value
+// Return:      u32           = read value
 //
 // State:       not tested
 //
 //---------------------------------------------------------------------------
-
-INLINE_FUNCTION DWORD PUBLIC AmiGetDword24FromBe(void FAR * pAddr_p)
+u32 AmiGetDword24FromBe(void *pAddr_p)
 {
-
 	tdwStruct dwStruct;
 
 	dwStruct.m_dwDword = AmiGetDwordFromBe(pAddr_p);
 	dwStruct.m_dwDword >>= 8;
 
 	return (dwStruct.m_dwDword);
-
 }
 
 //---------------------------------------------------------------------------
@@ -399,22 +384,19 @@
 //
 // Parameters:  pAddr_p         = pointer to source buffer
 //
-// Return:      DWORD           = read value
+// Return:      u32           = read value
 //
 // State:       not tested
 //
 //---------------------------------------------------------------------------
-
-INLINE_FUNCTION DWORD PUBLIC AmiGetDword24FromLe(void FAR * pAddr_p)
+u32 AmiGetDword24FromLe(void *pAddr_p)
 {
-
 	tdwStruct dwStruct;
 
 	dwStruct.m_dwDword = AmiGetDwordFromLe(pAddr_p);
 	dwStruct.m_dwDword &= 0x00FFFFFF;
 
 	return (dwStruct.m_dwDword);
-
 }
 
 //#ifdef USE_VAR64
@@ -433,20 +415,16 @@
 // State:       not tested
 //
 //---------------------------------------------------------------------------
-
-INLINE_FUNCTION void PUBLIC AmiSetQword64ToBe(void FAR * pAddr_p,
-					      QWORD qwQwordVal_p)
+void AmiSetQword64ToBe(void *pAddr_p, u64 qwQwordVal_p)
 {
-
-	((BYTE FAR *) pAddr_p)[0] = ((BYTE FAR *) & qwQwordVal_p)[7];
-	((BYTE FAR *) pAddr_p)[1] = ((BYTE FAR *) & qwQwordVal_p)[6];
-	((BYTE FAR *) pAddr_p)[2] = ((BYTE FAR *) & qwQwordVal_p)[5];
-	((BYTE FAR *) pAddr_p)[3] = ((BYTE FAR *) & qwQwordVal_p)[4];
-	((BYTE FAR *) pAddr_p)[4] = ((BYTE FAR *) & qwQwordVal_p)[3];
-	((BYTE FAR *) pAddr_p)[5] = ((BYTE FAR *) & qwQwordVal_p)[2];
-	((BYTE FAR *) pAddr_p)[6] = ((BYTE FAR *) & qwQwordVal_p)[1];
-	((BYTE FAR *) pAddr_p)[7] = ((BYTE FAR *) & qwQwordVal_p)[0];
-
+	((u8 *) pAddr_p)[0] = ((u8 *) & qwQwordVal_p)[7];
+	((u8 *) pAddr_p)[1] = ((u8 *) & qwQwordVal_p)[6];
+	((u8 *) pAddr_p)[2] = ((u8 *) & qwQwordVal_p)[5];
+	((u8 *) pAddr_p)[3] = ((u8 *) & qwQwordVal_p)[4];
+	((u8 *) pAddr_p)[4] = ((u8 *) & qwQwordVal_p)[3];
+	((u8 *) pAddr_p)[5] = ((u8 *) & qwQwordVal_p)[2];
+	((u8 *) pAddr_p)[6] = ((u8 *) & qwQwordVal_p)[1];
+	((u8 *) pAddr_p)[7] = ((u8 *) & qwQwordVal_p)[0];
 }
 
 //---------------------------------------------------------------------------
@@ -463,16 +441,12 @@
 // State:       not tested
 //
 //---------------------------------------------------------------------------
-
-INLINE_FUNCTION void PUBLIC AmiSetQword64ToLe(void FAR * pAddr_p,
-					      QWORD qwQwordVal_p)
+void AmiSetQword64ToLe(void *pAddr_p, u64 qwQwordVal_p)
 {
+	u64 *pqwDst;
 
-	QWORD FAR *pqwDst;
-
-	pqwDst = (QWORD FAR *) pAddr_p;
+	pqwDst = (u64 *) pAddr_p;
 	*pqwDst = qwQwordVal_p;
-
 }
 
 //---------------------------------------------------------------------------
@@ -488,23 +462,20 @@
 // State:       not tested
 //
 //---------------------------------------------------------------------------
-
-INLINE_FUNCTION QWORD PUBLIC AmiGetQword64FromBe(void FAR * pAddr_p)
+u64 AmiGetQword64FromBe(void *pAddr_p)
 {
-
 	tqwStruct qwStruct;
 
-	((BYTE FAR *) & qwStruct.m_qwQword)[0] = ((BYTE FAR *) pAddr_p)[7];
-	((BYTE FAR *) & qwStruct.m_qwQword)[1] = ((BYTE FAR *) pAddr_p)[6];
-	((BYTE FAR *) & qwStruct.m_qwQword)[2] = ((BYTE FAR *) pAddr_p)[5];
-	((BYTE FAR *) & qwStruct.m_qwQword)[3] = ((BYTE FAR *) pAddr_p)[4];
-	((BYTE FAR *) & qwStruct.m_qwQword)[4] = ((BYTE FAR *) pAddr_p)[3];
-	((BYTE FAR *) & qwStruct.m_qwQword)[5] = ((BYTE FAR *) pAddr_p)[2];
-	((BYTE FAR *) & qwStruct.m_qwQword)[6] = ((BYTE FAR *) pAddr_p)[1];
-	((BYTE FAR *) & qwStruct.m_qwQword)[7] = ((BYTE FAR *) pAddr_p)[0];
+	((u8 *) & qwStruct.m_qwQword)[0] = ((u8 *) pAddr_p)[7];
+	((u8 *) & qwStruct.m_qwQword)[1] = ((u8 *) pAddr_p)[6];
+	((u8 *) & qwStruct.m_qwQword)[2] = ((u8 *) pAddr_p)[5];
+	((u8 *) & qwStruct.m_qwQword)[3] = ((u8 *) pAddr_p)[4];
+	((u8 *) & qwStruct.m_qwQword)[4] = ((u8 *) pAddr_p)[3];
+	((u8 *) & qwStruct.m_qwQword)[5] = ((u8 *) pAddr_p)[2];
+	((u8 *) & qwStruct.m_qwQword)[6] = ((u8 *) pAddr_p)[1];
+	((u8 *) & qwStruct.m_qwQword)[7] = ((u8 *) pAddr_p)[0];
 
 	return (qwStruct.m_qwQword);
-
 }
 
 //---------------------------------------------------------------------------
@@ -520,18 +491,15 @@
 // State:       not tested
 //
 //---------------------------------------------------------------------------
-
-INLINE_FUNCTION QWORD PUBLIC AmiGetQword64FromLe(void FAR * pAddr_p)
+u64 AmiGetQword64FromLe(void *pAddr_p)
 {
-
-	tqwStruct FAR *pqwStruct;
+	tqwStruct *pqwStruct;
 	tqwStruct qwStruct;
 
-	pqwStruct = (tqwStruct FAR *) pAddr_p;
+	pqwStruct = (tqwStruct *) pAddr_p;
 	qwStruct.m_qwQword = pqwStruct->m_qwQword;
 
 	return (qwStruct.m_qwQword);
-
 }
 
 //---------------------------------------------------------------------------
@@ -549,15 +517,14 @@
 //
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION void PUBLIC AmiSetQword40ToBe(void FAR * pAddr_p,
-					      QWORD qwQwordVal_p)
+void AmiSetQword40ToBe(void *pAddr_p, u64 qwQwordVal_p)
 {
 
-	((BYTE FAR *) pAddr_p)[0] = ((BYTE FAR *) & qwQwordVal_p)[4];
-	((BYTE FAR *) pAddr_p)[1] = ((BYTE FAR *) & qwQwordVal_p)[3];
-	((BYTE FAR *) pAddr_p)[2] = ((BYTE FAR *) & qwQwordVal_p)[2];
-	((BYTE FAR *) pAddr_p)[3] = ((BYTE FAR *) & qwQwordVal_p)[1];
-	((BYTE FAR *) pAddr_p)[4] = ((BYTE FAR *) & qwQwordVal_p)[0];
+	((u8 *) pAddr_p)[0] = ((u8 *) & qwQwordVal_p)[4];
+	((u8 *) pAddr_p)[1] = ((u8 *) & qwQwordVal_p)[3];
+	((u8 *) pAddr_p)[2] = ((u8 *) & qwQwordVal_p)[2];
+	((u8 *) pAddr_p)[3] = ((u8 *) & qwQwordVal_p)[1];
+	((u8 *) pAddr_p)[4] = ((u8 *) & qwQwordVal_p)[0];
 
 }
 
@@ -576,12 +543,11 @@
 //
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION void PUBLIC AmiSetQword40ToLe(void FAR * pAddr_p,
-					      QWORD qwQwordVal_p)
+void AmiSetQword40ToLe(void *pAddr_p, u64 qwQwordVal_p)
 {
 
-	((DWORD FAR *) pAddr_p)[0] = ((DWORD FAR *) & qwQwordVal_p)[0];
-	((BYTE FAR *) pAddr_p)[4] = ((BYTE FAR *) & qwQwordVal_p)[4];
+	((u32 *) pAddr_p)[0] = ((u32 *) & qwQwordVal_p)[0];
+	((u8 *) pAddr_p)[4] = ((u8 *) & qwQwordVal_p)[4];
 
 }
 
@@ -593,13 +559,13 @@
 //
 // Parameters:  pAddr_p         = pointer to source buffer
 //
-// Return:      QWORD
+// Return:      u64
 //
 // State:       not tested
 //
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION QWORD PUBLIC AmiGetQword40FromBe(void FAR * pAddr_p)
+u64 AmiGetQword40FromBe(void *pAddr_p)
 {
 
 	tqwStruct qwStruct;
@@ -619,13 +585,13 @@
 //
 // Parameters:  pAddr_p         = pointer to source buffer
 //
-// Return:      QWORD
+// Return:      u64
 //
 // State:       not tested
 //
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION QWORD PUBLIC AmiGetQword40FromLe(void FAR * pAddr_p)
+u64 AmiGetQword40FromLe(void *pAddr_p)
 {
 
 	tqwStruct qwStruct;
@@ -652,16 +618,15 @@
 //
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION void PUBLIC AmiSetQword48ToBe(void FAR * pAddr_p,
-					      QWORD qwQwordVal_p)
+void AmiSetQword48ToBe(void *pAddr_p, u64 qwQwordVal_p)
 {
 
-	((BYTE FAR *) pAddr_p)[0] = ((BYTE FAR *) & qwQwordVal_p)[5];
-	((BYTE FAR *) pAddr_p)[1] = ((BYTE FAR *) & qwQwordVal_p)[4];
-	((BYTE FAR *) pAddr_p)[2] = ((BYTE FAR *) & qwQwordVal_p)[3];
-	((BYTE FAR *) pAddr_p)[3] = ((BYTE FAR *) & qwQwordVal_p)[2];
-	((BYTE FAR *) pAddr_p)[4] = ((BYTE FAR *) & qwQwordVal_p)[1];
-	((BYTE FAR *) pAddr_p)[5] = ((BYTE FAR *) & qwQwordVal_p)[0];
+	((u8 *) pAddr_p)[0] = ((u8 *) & qwQwordVal_p)[5];
+	((u8 *) pAddr_p)[1] = ((u8 *) & qwQwordVal_p)[4];
+	((u8 *) pAddr_p)[2] = ((u8 *) & qwQwordVal_p)[3];
+	((u8 *) pAddr_p)[3] = ((u8 *) & qwQwordVal_p)[2];
+	((u8 *) pAddr_p)[4] = ((u8 *) & qwQwordVal_p)[1];
+	((u8 *) pAddr_p)[5] = ((u8 *) & qwQwordVal_p)[0];
 
 }
 
@@ -680,12 +645,11 @@
 //
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION void PUBLIC AmiSetQword48ToLe(void FAR * pAddr_p,
-					      QWORD qwQwordVal_p)
+void AmiSetQword48ToLe(void *pAddr_p, u64 qwQwordVal_p)
 {
 
-	((DWORD FAR *) pAddr_p)[0] = ((DWORD FAR *) & qwQwordVal_p)[0];
-	((WORD FAR *) pAddr_p)[2] = ((WORD FAR *) & qwQwordVal_p)[2];
+	((u32 *) pAddr_p)[0] = ((u32 *) & qwQwordVal_p)[0];
+	((u16 *) pAddr_p)[2] = ((u16 *) & qwQwordVal_p)[2];
 
 }
 
@@ -697,13 +661,13 @@
 //
 // Parameters:  pAddr_p         = pointer to source buffer
 //
-// Return:      QWORD
+// Return:      u64
 //
 // State:       not tested
 //
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION QWORD PUBLIC AmiGetQword48FromBe(void FAR * pAddr_p)
+u64 AmiGetQword48FromBe(void *pAddr_p)
 {
 
 	tqwStruct qwStruct;
@@ -723,13 +687,13 @@
 //
 // Parameters:  pAddr_p         = pointer to source buffer
 //
-// Return:      QWORD
+// Return:      u64
 //
 // State:       not tested
 //
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION QWORD PUBLIC AmiGetQword48FromLe(void FAR * pAddr_p)
+u64 AmiGetQword48FromLe(void *pAddr_p)
 {
 
 	tqwStruct qwStruct;
@@ -756,17 +720,16 @@
 //
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION void PUBLIC AmiSetQword56ToBe(void FAR * pAddr_p,
-					      QWORD qwQwordVal_p)
+void AmiSetQword56ToBe(void *pAddr_p, u64 qwQwordVal_p)
 {
 
-	((BYTE FAR *) pAddr_p)[0] = ((BYTE FAR *) & qwQwordVal_p)[6];
-	((BYTE FAR *) pAddr_p)[1] = ((BYTE FAR *) & qwQwordVal_p)[5];
-	((BYTE FAR *) pAddr_p)[2] = ((BYTE FAR *) & qwQwordVal_p)[4];
-	((BYTE FAR *) pAddr_p)[3] = ((BYTE FAR *) & qwQwordVal_p)[3];
-	((BYTE FAR *) pAddr_p)[4] = ((BYTE FAR *) & qwQwordVal_p)[2];
-	((BYTE FAR *) pAddr_p)[5] = ((BYTE FAR *) & qwQwordVal_p)[1];
-	((BYTE FAR *) pAddr_p)[6] = ((BYTE FAR *) & qwQwordVal_p)[0];
+	((u8 *) pAddr_p)[0] = ((u8 *) & qwQwordVal_p)[6];
+	((u8 *) pAddr_p)[1] = ((u8 *) & qwQwordVal_p)[5];
+	((u8 *) pAddr_p)[2] = ((u8 *) & qwQwordVal_p)[4];
+	((u8 *) pAddr_p)[3] = ((u8 *) & qwQwordVal_p)[3];
+	((u8 *) pAddr_p)[4] = ((u8 *) & qwQwordVal_p)[2];
+	((u8 *) pAddr_p)[5] = ((u8 *) & qwQwordVal_p)[1];
+	((u8 *) pAddr_p)[6] = ((u8 *) & qwQwordVal_p)[0];
 
 }
 
@@ -785,13 +748,12 @@
 //
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION void PUBLIC AmiSetQword56ToLe(void FAR * pAddr_p,
-					      QWORD qwQwordVal_p)
+void AmiSetQword56ToLe(void *pAddr_p, u64 qwQwordVal_p)
 {
 
-	((DWORD FAR *) pAddr_p)[0] = ((DWORD FAR *) & qwQwordVal_p)[0];
-	((WORD FAR *) pAddr_p)[2] = ((WORD FAR *) & qwQwordVal_p)[2];
-	((BYTE FAR *) pAddr_p)[6] = ((BYTE FAR *) & qwQwordVal_p)[6];
+	((u32 *) pAddr_p)[0] = ((u32 *) & qwQwordVal_p)[0];
+	((u16 *) pAddr_p)[2] = ((u16 *) & qwQwordVal_p)[2];
+	((u8 *) pAddr_p)[6] = ((u8 *) & qwQwordVal_p)[6];
 
 }
 
@@ -803,13 +765,13 @@
 //
 // Parameters:  pAddr_p         = pointer to source buffer
 //
-// Return:      QWORD
+// Return:      u64
 //
 // State:       not tested
 //
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION QWORD PUBLIC AmiGetQword56FromBe(void FAR * pAddr_p)
+u64 AmiGetQword56FromBe(void *pAddr_p)
 {
 
 	tqwStruct qwStruct;
@@ -829,13 +791,13 @@
 //
 // Parameters:  pAddr_p         = pointer to source buffer
 //
-// Return:      QWORD
+// Return:      u64
 //
 // State:       not tested
 //
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION QWORD PUBLIC AmiGetQword56FromLe(void FAR * pAddr_p)
+u64 AmiGetQword56FromLe(void *pAddr_p)
 {
 
 	tqwStruct qwStruct;
@@ -862,13 +824,11 @@
 //
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION void PUBLIC AmiSetTimeOfDay(void FAR * pAddr_p,
-					    tTimeOfDay FAR * pTimeOfDay_p)
+void AmiSetTimeOfDay(void *pAddr_p, tTimeOfDay *pTimeOfDay_p)
 {
 
-	AmiSetDwordToLe(((BYTE FAR *) pAddr_p),
-			pTimeOfDay_p->m_dwMs & 0x0FFFFFFF);
-	AmiSetWordToLe(((BYTE FAR *) pAddr_p) + 4, pTimeOfDay_p->m_wDays);
+	AmiSetDwordToLe(((u8 *) pAddr_p), pTimeOfDay_p->m_dwMs & 0x0FFFFFFF);
+	AmiSetWordToLe(((u8 *) pAddr_p) + 4, pTimeOfDay_p->m_wDays);
 
 }
 
@@ -887,18 +847,14 @@
 //
 //---------------------------------------------------------------------------
 
-INLINE_FUNCTION void PUBLIC AmiGetTimeOfDay(void FAR * pAddr_p,
-					    tTimeOfDay FAR * pTimeOfDay_p)
+void AmiGetTimeOfDay(void *pAddr_p, tTimeOfDay *pTimeOfDay_p)
 {
 
-	pTimeOfDay_p->m_dwMs =
-	    AmiGetDwordFromLe(((BYTE FAR *) pAddr_p)) & 0x0FFFFFFF;
-	pTimeOfDay_p->m_wDays = AmiGetWordFromLe(((BYTE FAR *) pAddr_p) + 4);
+	pTimeOfDay_p->m_dwMs = AmiGetDwordFromLe(((u8 *) pAddr_p)) & 0x0FFFFFFF;
+	pTimeOfDay_p->m_wDays = AmiGetWordFromLe(((u8 *) pAddr_p) + 4);
 
 }
 
-#endif
-
 // EOF
 
 // Die letzte Zeile muß unbedingt eine leere Zeile sein, weil manche Compiler
diff --git a/drivers/staging/epl/demo_main.c b/drivers/staging/epl/demo_main.c
index 263fa04..7ad10fc 100644
--- a/drivers/staging/epl/demo_main.c
+++ b/drivers/staging/epl/demo_main.c
@@ -74,7 +74,6 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/major.h>
-#include <linux/version.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/atomic.h>
@@ -87,16 +86,6 @@
 #include "Epl.h"
 #include "proc_fs.h"
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-    // remove ("make invisible") obsolete symbols for kernel versions 2.6
-    // and higher
-#define MOD_INC_USE_COUNT
-#define MOD_DEC_USE_COUNT
-#define EXPORT_NO_SYMBOLS
-#else
-#error "This driver needs a 2.6.x kernel or higher"
-#endif
-
 /***************************************************************************/
 /*                                                                         */
 /*                                                                         */
@@ -118,7 +107,7 @@
 
 // TracePoint support for realtime-debugging
 #ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
 #define TGT_DBG_SIGNAL_TRACE_POINT(p)   TgtDbgSignalTracePoint(p)
 #else
 #define TGT_DBG_SIGNAL_TRACE_POINT(p)
@@ -148,30 +137,30 @@
 // modul globale vars
 //---------------------------------------------------------------------------
 
-CONST BYTE abMacAddr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const u8 abMacAddr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
 
-BYTE bVarIn1_l;
-BYTE bVarOut1_l;
-BYTE bVarOut1Old_l;
-BYTE bModeSelect_l;		// state of the pushbuttons to select the mode
-BYTE bSpeedSelect_l;		// state of the pushbuttons to increase/decrease the speed
-BYTE bSpeedSelectOld_l;		// old state of the pushbuttons
-DWORD dwLeds_l;			// current state of all LEDs
-BYTE bLedsRow1_l;		// current state of the LEDs in row 1
-BYTE bLedsRow2_l;		// current state of the LEDs in row 2
-BYTE abSelect_l[3];		// pushbuttons from CNs
+static u8 bVarIn1_l;
+static u8 bVarOut1_l;
+static u8 bVarOut1Old_l;
+static u8 bModeSelect_l;		// state of the pushbuttons to select the mode
+static u8 bSpeedSelect_l;		// state of the pushbuttons to increase/decrease the speed
+static u8 bSpeedSelectOld_l;		// old state of the pushbuttons
+static u32 dwLeds_l;			// current state of all LEDs
+static u8 bLedsRow1_l;		// current state of the LEDs in row 1
+static u8 bLedsRow2_l;		// current state of the LEDs in row 2
+static u8 abSelect_l[3];		// pushbuttons from CNs
 
-DWORD dwMode_l;			// current mode
-int iCurCycleCount_l;		// current cycle count
-int iMaxCycleCount_l;		// maximum cycle count (i.e. number of cycles until next light movement step)
-int iToggle;			// indicates the light movement direction
+static u32 dwMode_l;			// current mode
+static int iCurCycleCount_l;		// current cycle count
+static int iMaxCycleCount_l;		// maximum cycle count (i.e. number of cycles until next light movement step)
+static int iToggle;			// indicates the light movement direction
 
-BYTE abDomain_l[3000];
+//static u8 abDomain_l[3000];
 
 static wait_queue_head_t WaitQueueShutdown_g;	// wait queue for tEplNmtEventSwitchOff
 static atomic_t AtomicShutdown_g = ATOMIC_INIT(FALSE);
 
-static DWORD dw_le_CycleLen_g;
+static u32 dw_le_CycleLen_g;
 
 static uint uiNodeId_g = EPL_C_ADR_INVALID;
 module_param_named(nodeid, uiNodeId_g, uint, 0);
@@ -188,23 +177,19 @@
 // this function prototype here. If you want to use more than one Epl
 // instances then the function name of each object dictionary has to differ.
 
-tEplKernel PUBLIC EplObdInitRam(tEplObdInitParam MEM * pInitParam_p);
+tEplKernel EplObdInitRam(tEplObdInitParam *pInitParam_p);
 
-tEplKernel PUBLIC AppCbEvent(tEplApiEventType EventType_p,	// IN: event type (enum)
-			     tEplApiEventArg * pEventArg_p,	// IN: event argument (union)
-			     void GENERIC * pUserArg_p);
+tEplKernel AppCbEvent(tEplApiEventType EventType_p,	// IN: event type (enum)
+		      tEplApiEventArg *pEventArg_p,	// IN: event argument (union)
+		      void *pUserArg_p);
 
-tEplKernel PUBLIC AppCbSync(void);
+tEplKernel AppCbSync(void);
 
-static int __init EplLinInit(void);
-static void __exit EplLinExit(void);
 
 //---------------------------------------------------------------------------
 //  Kernel Module specific Data Structures
 //---------------------------------------------------------------------------
 
-EXPORT_NO_SYMBOLS;
-
 //module_init(EplLinInit);
 //module_exit(EplLinExit);
 
@@ -231,6 +216,7 @@
 // State:
 //
 //---------------------------------------------------------------------------
+#if 0
 static int __init EplLinInit(void)
 {
 	tEplKernel EplRet;
@@ -263,7 +249,7 @@
 	EplApiInitParam.m_uiSizeOfStruct = sizeof(EplApiInitParam);
 	EPL_MEMCPY(EplApiInitParam.m_abMacAddress, abMacAddr,
 		   sizeof(EplApiInitParam.m_abMacAddress));
-//    EplApiInitParam.m_abMacAddress[5] = (BYTE) EplApiInitParam.m_uiNodeId;
+//	EplApiInitParam.m_abMacAddress[5] = (u8) EplApiInitParam.m_uiNodeId;
 	EplApiInitParam.m_dwFeatureFlags = -1;
 	EplApiInitParam.m_dwCycleLen = uiCycleLen_g;	// required for error detection
 	EplApiInitParam.m_uiIsochrTxMaxPayload = 100;	// const
@@ -401,7 +387,7 @@
 
 	// configure IP address of virtual network interface
 	// for TCP/IP communication over the POWERLINK network
-	sprintf(sBuffer, "%lu.%lu.%lu.%lu",
+	sprintf(sBuffer, "%u.%u.%u.%u",
 		(EplApiInitParam.m_dwIpAddress >> 24),
 		((EplApiInitParam.m_dwIpAddress >> 16) & 0xFF),
 		((EplApiInitParam.m_dwIpAddress >> 8) & 0xFF),
@@ -456,7 +442,7 @@
 	printk("EplLinProcFree():        0x%X\n", EplRet);
 
 }
-
+#endif
 //=========================================================================//
 //                                                                         //
 //          P R I V A T E   F U N C T I O N S                              //
@@ -484,9 +470,9 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC AppCbEvent(tEplApiEventType EventType_p,	// IN: event type (enum)
-			     tEplApiEventArg * pEventArg_p,	// IN: event argument (union)
-			     void GENERIC * pUserArg_p)
+tEplKernel AppCbEvent(tEplApiEventType EventType_p,	// IN: event type (enum)
+		      tEplApiEventArg *pEventArg_p,	// IN: event argument (union)
+		      void *pUserArg_p)
 {
 	tEplKernel EplRet = kEplSuccessful;
 
@@ -515,7 +501,7 @@
 
 			case kEplNmtGsResetCommunication:
 				{
-					DWORD dwBuffer;
+					u32 dwBuffer;
 
 					// configure OD for MN in state ResetComm after reseting the OD
 					// TODO: setup your own network configuration here
@@ -677,8 +663,8 @@
 
 			case kEplEventSourceDllk:
 				{	// error occured within the data link layer (e.g. interrupt processing)
-					// the DWORD argument contains the DLL state and the NMT event
-					printk(" val=%lX\n",
+					// the u32 argument contains the DLL state and the NMT event
+					printk(" val=%X\n",
 					       pEventArg_p->m_InternalError.
 					       m_Arg.m_dwArg);
 					break;
@@ -802,7 +788,7 @@
 //
 //---------------------------------------------------------------------------
 
-tEplKernel PUBLIC AppCbSync(void)
+tEplKernel AppCbSync(void)
 {
 	tEplKernel EplRet = kEplSuccessful;
 
@@ -810,7 +796,7 @@
 		bVarOut1Old_l = bVarOut1_l;
 		// set LEDs
 
-//        printk("bVarIn = 0x%02X bVarOut = 0x%02X\n", (WORD) bVarIn_l, (WORD) bVarOut_l);
+//        printk("bVarIn = 0x%02X bVarOut = 0x%02X\n", (u16) bVarIn_l, (u16) bVarOut_l);
 	}
 	if (uiNodeId_g != EPL_C_ADR_MN_DEF_NODE_ID) {
 		bVarIn1_l++;
diff --git a/drivers/staging/epl/edrv.h b/drivers/staging/epl/edrv.h
index a45984d..62b4e77e 100644
--- a/drivers/staging/epl/edrv.h
+++ b/drivers/staging/epl/edrv.h
@@ -104,7 +104,7 @@
 	unsigned int m_uiTxMsgLen;	// IN: length of message to be send (set for each transmit call)
 	// ----------------------
 	unsigned int m_uiBufferNumber;	// OUT: number of the buffer, set by ethernetdriver
-	BYTE *m_pbBuffer;	// OUT: pointer to the buffer, set by ethernetdriver
+	u8 *m_pbBuffer;	// OUT: pointer to the buffer, set by ethernetdriver
 	tEplNetTime m_NetTime;	// OUT: Timestamp of end of transmission, set by ethernetdriver
 	// ----------------------
 	unsigned int m_uiMaxBufferLen;	// IN/OUT: maximum length of the buffer
@@ -114,23 +114,23 @@
 typedef struct _tEdrvRxBuffer {
 	tEdrvBufferInFrame m_BufferInFrame;	// OUT position of received buffer in an ethernet-frame
 	unsigned int m_uiRxMsgLen;	// OUT: length of received buffer (without CRC)
-	BYTE *m_pbBuffer;	// OUT: pointer to the buffer, set by ethernetdriver
+	u8 *m_pbBuffer;	// OUT: pointer to the buffer, set by ethernetdriver
 	tEplNetTime m_NetTime;	// OUT: Timestamp of end of receiption
 
 } tEdrvRxBuffer;
 
-//typedef void (*tEdrvRxHandler) (BYTE bBufferInFrame_p, tBufferDescr * pbBuffer_p);
-//typedef void (*tEdrvRxHandler) (BYTE bBufferInFrame_p, BYTE * pbEthernetData_p, WORD wDataLen_p);
+//typedef void (*tEdrvRxHandler) (u8 bBufferInFrame_p, tBufferDescr * pbBuffer_p);
+//typedef void (*tEdrvRxHandler) (u8 bBufferInFrame_p, u8 * pbEthernetData_p, u16 wDataLen_p);
 typedef void (*tEdrvRxHandler) (tEdrvRxBuffer * pRxBuffer_p);
 typedef void (*tEdrvTxHandler) (tEdrvTxBuffer * pTxBuffer_p);
 
 // format of init structure
 typedef struct {
-	BYTE m_abMyMacAddr[6];	// the own MAC address
+	u8 m_abMyMacAddr[6];	// the own MAC address
 
-//    BYTE            m_bNoOfRxBuffDescr;     // number of entries in rx bufferdescriptor table
+//    u8            m_bNoOfRxBuffDescr;     // number of entries in rx bufferdescriptor table
 //    tBufferDescr *  m_pRxBuffDescrTable;    // rx bufferdescriptor table
-//    WORD            m_wRxBufferSize;        // size of the whole rx buffer
+//    u16            m_wRxBufferSize;        // size of the whole rx buffer
 
 	tEdrvRxHandler m_pfnRxHandler;
 	tEdrvTxHandler m_pfnTxHandler;
@@ -145,11 +145,11 @@
 
 tEplKernel EdrvShutdown(void);
 
-tEplKernel EdrvDefineRxMacAddrEntry(BYTE * pbMacAddr_p);
-tEplKernel EdrvUndefineRxMacAddrEntry(BYTE * pbMacAddr_p);
+tEplKernel EdrvDefineRxMacAddrEntry(u8 * pbMacAddr_p);
+tEplKernel EdrvUndefineRxMacAddrEntry(u8 * pbMacAddr_p);
 
-//tEplKernel EdrvDefineUnicastEntry     (BYTE * pbUCEntry_p);
-//tEplKernel EdrvUndfineUnicastEntry    (BYTE * pbUCEntry_p);
+//tEplKernel EdrvDefineUnicastEntry     (u8 * pbUCEntry_p);
+//tEplKernel EdrvUndfineUnicastEntry    (u8 * pbUCEntry_p);
 
 tEplKernel EdrvAllocTxMsgBuffer(tEdrvTxBuffer * pBuffer_p);
 tEplKernel EdrvReleaseTxMsgBuffer(tEdrvTxBuffer * pBuffer_p);
diff --git a/drivers/staging/epl/global.h b/drivers/staging/epl/global.h
index fe16716..8c52d97 100644
--- a/drivers/staging/epl/global.h
+++ b/drivers/staging/epl/global.h
@@ -22,1261 +22,21 @@
 #ifndef _GLOBAL_H_
 #define _GLOBAL_H_
 
-//---------------------------------------------------------------------------
-//  elements of defines for development system
-//---------------------------------------------------------------------------
-
-// these defines are necessary to check some of characteristics of the development system
-#define _DEV_BIGEND_            0x80000000L	// big endian (motorolla format)
-#define _DEV_ALIGNMENT_4_       0x00400000L	//                  the CPU needs alignment of 4 bytes
-#define _DEV_ONLY_INT_MAIN_     0x00004000L	//                  the compiler needs "int main(int)" instead of "void main(void)"
-#define _DEV_COMMA_EXT_         0x00002000L	//                  support of last comma in struct predefinition
-#define _DEV_64BIT_SUPPORT_     0x00001000L	//                  support of 64 bit operations
-#define _DEV_BIT64_             0x00000400L	// count of bits:   64 bit
-#define _DEV_BIT32_             0x00000300L	//                  32 bit
-#define _DEV_BIT16_             0x00000200L	//                  16 bit
-#define _DEV_BIT8_              0x00000100L	//                  8 bit
-#define _DEV_RVCT_ARM_          0x0000001CL	//                  RealView ARM
-#define _DEV_RENESASM32C        0x0000001BL	// compiler from:   Renesas
-#define _DEV_GNUC_MIPS2_        0x0000001AL	//                  GNU for MIPS2
-#define _DEV_MPLAB_C30_         0x00000019L	//                  MPLAB C30 for Microchip dsPIC33F series
-#define _DEV_GNUC_TC_           0x00000018L	//                  GNU for Infineon TriCore
-#define _DEV_GNUC_X86_          0x00000017L	//                  GNU for I386
-#define _DEV_IAR_ARM_           0x00000016L	//                  ARM IAR C/C++ Compiler
-#define _DEV_PARADGM_X86        0x00000015L	//                  Paradigm C/C++ for Beck 1x3
-#define _DEV_GNUC_CF_           0x00000014L	//                  GNU for Coldfire
-#define _DEV_KEIL_ARM_          0x00000013L	//                  Keil ARM
-#define _DEV_MSEVC_             0x00000012L	//                  Microsoft embedded Visual C/C++
-#define _DEV_HIGHTEC_GNUC_X86_  0x00000011L	//                  Hightec elf386 gcc
-#define _DEV_MSVC_RTX_          0x00000010L	//                  VC600 + RTX
-#define _DEV_MSVC_V1_5_         0x0000000FL	//                  Microsoft Visual C/C++ V1.5
-#define _DEV_GNUC_ARM7_         0x0000000EL	//                  GNU Compiler gcc for ARM7
-#define _DEV_METROWERKS_CW_     0x0000000DL	//                  Metrowerks Code Warrior
-#define _DEV_MITSUBISHIM16C_    0x0000000CL	//compiler from:    Mitsubishi
-#define _DEV_GNUC_C16X_         0x0000000BL	//                  GNU Compiler gcc166 for Infineon C16x
-#define _DEV_LINUX_GCC_         0x0000000AL	//                  Linux GNU Compiler gcc
-#define _DEV_GNUC_MPC5X5        0x00000009L	//                  GNU for Motorola PPC5x5
-#define _DEV_TASKINGM16C_       0x00000008L	//                  Tasking for Mitsubishi M16C
-#define _DEV_FUJITSU_           0x00000007L	//                  Fujitsu
-#define _DEV_TASKING8_          0x00000006L	//                  Tasking 8051
-#define _DEV_TASKING16_         0x00000005L	//                  Tasking 166
-#define _DEV_KEIL8_             0x00000004L	//                  Keil C51
-#define _DEV_KEIL16_            0x00000003L	//                  Keil C166
-#define _DEV_BORLANDC_          0x00000002L	//                  Borland C/C++
-#define _DEV_MSVC16_            0x00000001L	//                  Microsoft Visual C/C++
-#define _DEV_MSVC32_            0x00000000L	//                  Microsoft Visual C/C++
-
-// these defines can be used to mask previous elements
-#define _DEV_MASK_COMPILER      0x000000FFL
-#define _DEV_MASK_BITCOUNT      0x00000F00L
-#define _DEV_MASK_ADDSUPPORT    0x0000F000L
-#define _DEV_MASK_ALIGNMENT     0x00F00000L
-
-//---------------------------------------------------------------------------
-//  defines for development system (DEV_SYSTEM) including previous elements
-//---------------------------------------------------------------------------
-
-#define _DEV_WIN16_             (_DEV_BIT16_ | _DEV_MSVC16_                  )
-#define _DEV_WIN32_             (_DEV_BIT32_ | _DEV_MSVC32_                   | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_MSVC_DOS_          (_DEV_BIT32_ | _DEV_MSVC_V1_5_               )
-#define _DEV_BORLAND_DOS_       (_DEV_BIT32_ | _DEV_BORLANDC_                )	//| _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_KEIL_C51X_         (_DEV_BIT8_  | _DEV_KEIL8_     | _DEV_BIGEND_ | _DEV_COMMA_EXT_)	// at least C51 version 7.05 supports comma extension
-#define _DEV_KEIL_C16X_         (_DEV_BIT16_ | _DEV_KEIL16_                   | _DEV_COMMA_EXT_)	// at least C166 version 5.03 supports comma extension
-#define _DEV_TASKING_C51X_      (_DEV_BIT8_  | _DEV_TASKING8_  | _DEV_BIGEND_)
-#define _DEV_TASKING_C16X_      (_DEV_BIT16_ | _DEV_TASKING16_               )
-#define _DEV_FUJITSU_F590_      (_DEV_BIT8_  | _DEV_FUJITSU_                  | _DEV_COMMA_EXT_)	// softune is not able to support 64 bit variables QWORD !!!
-//f.j.29.04.03 M16C kann effektiv mit Bytes umgehen
-//#define _DEV_TASKING_M16C_      (_DEV_BIT16_ | _DEV_TASKINGM16C_             )
-#define _DEV_TASKING_M16C_      (_DEV_BIT8_  | _DEV_TASKINGM16C_             )
-#define _DEV_MITSUBISHI_M16C_   (_DEV_BIT8_  | _DEV_MITSUBISHIM16C_          )
-#define _DEV_GNU_MPC5X5_        (_DEV_BIT32_ | _DEV_GNUC_MPC5X5| _DEV_BIGEND_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_LINUX_             (_DEV_BIT32_ | _DEV_LINUX_GCC_                | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_GNU_C16X_          (_DEV_BIT16_ | _DEV_GNUC_C16X_               )	//| _DEV_COMMA_EXT_)
-#define _DEV_MCW_MPC5X5_        (_DEV_BIT32_ | _DEV_METROWERKS_CW_           )	//| _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_GNU_ARM7_          (_DEV_BIT32_ | _DEV_GNUC_ARM7_                | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_ | _DEV_ONLY_INT_MAIN_)
-#define _DEV_WIN32_RTX_         (_DEV_BIT32_ | _DEV_MSVC_RTX_                )	//| _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_HIGHTEC_X86_       (_DEV_BIT32_ | _DEV_HIGHTEC_GNUC_X86_        )	//| _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_WIN_CE_            (_DEV_BIT32_ | _DEV_MSEVC_                   )	//| _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_KEIL_CARM_         (_DEV_BIT32_ | _DEV_KEIL_ARM_                 | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_IAR_CARM_          (_DEV_BIT32_ | _DEV_IAR_ARM_                  | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_RVCT_CARM_         (_DEV_BIT32_ | _DEV_RVCT_ARM_                 | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_ | _DEV_ONLY_INT_MAIN_)
-#define _DEV_MCW_MCF5XXX_       (_DEV_BIT32_ | _DEV_METROWERKS_CW_           )	//| _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_GNU_CF5282_        (_DEV_BIT32_ | _DEV_GNUC_CF_   | _DEV_BIGEND_)
-#define _DEV_PAR_BECK1X3_       (_DEV_BIT16_ | _DEV_PARADGM_X86)
-#define _DEV_GNU_CF548X_        (_DEV_BIT32_ | _DEV_GNUC_CF_   | _DEV_BIGEND_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_GNU_I386_          (_DEV_BIT32_ | _DEV_GNUC_X86_                 | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_ | _DEV_ONLY_INT_MAIN_)
-#define _DEV_GNU_TRICORE_       (_DEV_BIT32_ | _DEV_GNUC_TC_                  | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_ | _DEV_ONLY_INT_MAIN_ | _DEV_ALIGNMENT_4_)
-#define _DEV_MPLAB_DSPIC33F_    (_DEV_BIT16_ | _DEV_MPLAB_C30_               )	//| _DEV_COMMA_EXT_)
-#define _DEV_GNU_MIPSEL_        (_DEV_BIT32_ | _DEV_GNUC_MIPS2_     | _DEV_BIGEND_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_ | _DEV_ONLY_INT_MAIN_)
-
-#define _DEV_RENESAS_M32C_      (_DEV_BIT32_ | _DEV_RENESASM32C)
-
-//---------------------------------------------------------------------------
-//  usefull macros
-//---------------------------------------------------------------------------
-
-#define CHECK_IF_ONLY_INT_MAIN()    (DEV_SYSTEM & _DEV_ONLY_INT_MAIN_)
-#define CHECK_MEMORY_ALINMENT()     (DEV_SYSTEM & _DEV_MASK_ALIGNMENT)
-
-//---------------------------------------------------------------------------
-//  defines for target system (TARGET_SYSTEM)
-//---------------------------------------------------------------------------
-
-#define _DOS_              (16 + 0x10000)
-#define _WIN16_             16
-#define _WIN32_             32
-#define _WINCE_            (32 + 0x20000)
-#define _NO_OS_              0
-#define _LINUX_              1
-#define _PXROS_              2
-#define _ECOSPRO_            3
-
-//---------------------------------------------------------------------------
-//  definitions for function inlining
-//---------------------------------------------------------------------------
-
-#define INLINE_FUNCTION		// empty define
-#undef  INLINE_ENABLED		// disable actual inlining of functions
-#undef  INLINE_FUNCTION_DEF	// disable inlining for all compilers per default
-
-//---------------------------------------------------------------------------
-//  definitions for Keil C51
-//---------------------------------------------------------------------------
-
-#ifdef  __C51__
-
-#define TARGET_SYSTEM   _NO_OS_
-#define DEV_SYSTEM      _DEV_KEIL_C51X_
-
-#pragma DEBUG OBJECTEXTEND
-#pragma WARNINGLEVEL(2)		// maximum warning level
-
-#define NEAR            idata	// variables mapped to internal data storage location
-#define FAR             xdata	// variables mapped to external data storage location
-#define CONST           const	// variables mapped to ROM (i.e. flash)
-#define ROM             code	// code or variables mapped to ROM (i.e. flash)
-					// usage: CONST BYTE ROM foo = 0x00;
-#define HWACC           xdata	// hardware access through external memory (i.e. CAN)
-#define LARGE           large	// functions set parameters to external data storage location
-
-    // These types can be adjusted by users to match application requirements. The goal is to
-    // minimize code memory and maximize speed.
-#define GENERIC			// generic pointer to point to application data
-					// Variables with this attribute can be located in external
-					// or internal data memory.
-#define MEM             xdata	// Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT       reentrant
-#define PUBLIC
-
-#ifndef NDEBUG
-#include <stdio.h>		// prototype printf() (for TRACE)
-#define TRACE  printf
-#endif
-
-//---------------------------------------------------------------------------
-//  definitions for GNU Compiler for Infineon C16x
-//  - it have to be befor Keil (it has __C166__ too)
-//---------------------------------------------------------------------------
-#elif  defined (__GNUC__) && defined (__C166__)
-
-#define TARGET_SYSTEM   _NO_OS_
-#define DEV_SYSTEM      _DEV_GNU_C16X_
-
-//    #define NEAR            idata       // variables mapped to internal data storage location
-#define NEAR            near	// variables mapped to internal data storage location
-//    #define FAR             xhuge       // variables mapped to external data storage location
-#define FAR             huge	// variables mapped to external data storage location
-#define CONST           const	// variables mapped to ROM (i.e. flash)
-#define ROM			// code or variables mapped to ROM (i.e. flash)
-					// usage: CONST BYTE ROM foo = 0x00;
-//    #define HWACC           sdata       // hardware access through external memory (i.e. CAN)
-#define HWACC           huge	// hardware access through external memory (i.e. CAN)
-#define LARGE			// functions set parameters to external data storage location
-
-    // These types can be adjusted by users to match application requirements. The goal is to
-    // minimize code memory and maximize speed.
-//    #define GENERIC         xhuge       // generic pointer to point to application data
-#define GENERIC         huge	// generic pointer to point to application data
-					// Variables with this attribute can be located in external
-					// or internal data memory.
-#define MEM			// Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#include <stdio.h>		// prototype printf() (for TRACE)
-#define TRACE  printf
-
-#define ASSERT(p)  \
-            if (p)         \
-            {              \
-                ;          \
-            }              \
-            else           \
-            {              \
-                PRINTF0("Assert failed: " #p " (file %s line %d)\n", __FILE__, (int) __LINE__ ); \
-                while (1); \
-            }
-#else
-#define ASSERT(p)
-#endif
-
-//---------------------------------------------------------------------------
-//  definitions for Keil C166
-//---------------------------------------------------------------------------
-#elif  defined (__C166__)	// 24.01.2005 r.d.: Keil ARM7 needs directive 'defined'
-
-#define TARGET_SYSTEM   _NO_OS_
-#define DEV_SYSTEM      _DEV_KEIL_C16X_
-
-#pragma CODE
-#pragma MOD167
-#pragma NOINIT
-#pragma DEBUG
-#pragma WARNINGLEVEL(3)		// maximum warning level
-#pragma WARNING DISABLE = 47	// warning <unreferenced parameter> = OFF
-#pragma WARNING DISABLE = 38	// warning <empty translation unit> = OFF
-//  #pragma WARNING DISABLE = 102       // warning <different const/volatile qualifiers> = OFF
-#pragma WARNING DISABLE = 174	// warning <unreferenced 'static' function> = OFF
-#pragma WARNING DISABLE = 183	// warning <dead assignement eliminated> = OFF
-
-#define NEAR            idata	// variables mapped to internal data storage location
-#define FAR             xhuge	// variables mapped to external data storage location
-#define CONST           const	// variables mapped to ROM (i.e. flash)
-#define ROM			// code or variables mapped to ROM (i.e. flash)
-					// usage: CONST BYTE ROM foo = 0x00;
-//    #define HWACC           sdata       // hardware access through external memory (i.e. CAN)
-#define HWACC           huge	// hardware access through external memory (i.e. CAN)
-#define LARGE			// functions set parameters to external data storage location
-
-    // These types can be adjusted by users to match application requirements. The goal is to
-    // minimize code memory and maximize speed.
-#define GENERIC         xhuge	// generic pointer to point to application data
-					// Variables with this attribute can be located in external
-					// or internal data memory.
-#define MEM			// Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#include <stdio.h>		// prototype printf() (for TRACE)
-#define TRACE  printf
-#endif
-
-//---------------------------------------------------------------------------
-//  definitions for MPLAB C30 for dsPIC33F series
-//---------------------------------------------------------------------------
-#elif  defined (__C30__)
-
-#define TARGET_SYSTEM   _NO_OS_
-#define DEV_SYSTEM      _DEV_MPLAB_DSPIC33F_
-
-#define NEAR			// variables mapped to internal data storage location
-#define FAR			// variables mapped to external data storage location
-#define CONST        const	// variables mapped to ROM (i.e. flash)
-#define ROM			// code or variables mapped to ROM (i.e. flash)
-					// usage: CONST BYTE ROM foo = 0x00;
-#define HWACC			// hardware access through external memory (i.e. CAN)
-#define LARGE			// functions set parameters to external data storage location
-
-    // These types can be adjusted by users to match application requirements. The goal is to
-    // minimize code memory and maximize speed.
-#define GENERIC			// generic pointer to point to application data
-					// Variables with this attribute can be located in external
-					// or internal data memory.
-#define MEM			// Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
-//    #ifndef QWORD
-//        #define QWORD long long
-//    #endif
-
-#ifndef NDEBUG
-#include <stdio.h>		// prototype printf() (for TRACE)
-#define TRACE  printf
-#endif
-
-//---------------------------------------------------------------------------
-//  definitions for Keil ARM
-//---------------------------------------------------------------------------
-#elif  defined (__CA__)
-
-#define TARGET_SYSTEM   _NO_OS_
-#define DEV_SYSTEM      _DEV_KEIL_CARM_
-
-#define NEAR			// variables mapped to internal data storage location
-#define FAR			// variables mapped to external data storage location
-#define CONST        const	// variables mapped to ROM (i.e. flash)
-#define ROM			// code or variables mapped to ROM (i.e. flash)
-					// usage: CONST BYTE ROM foo = 0x00;
-#define HWACC			// hardware access through external memory (i.e. CAN)
-#define LARGE			// functions set parameters to external data storage location
-
-    // These types can be adjusted by users to match application requirements. The goal is to
-    // minimize code memory and maximize speed.
-#define GENERIC			// generic pointer to point to application data
-					// Variables with this attribute can be located in external
-					// or internal data memory.
-#define MEM			// Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef QWORD
-#define QWORD long long
-#endif
-
-#ifndef NDEBUG
-#include <stdio.h>		// prototype printf() (for TRACE)
-#define TRACE  printf
-#endif
-
-//---------------------------------------------------------------------------
-//  definitions for RealView ARM compilation tools (provided by recent Keil Microcontroller Development Kits)
-//---------------------------------------------------------------------------
-#elif  defined (__ARMCC_VERSION)
-
-#define TARGET_SYSTEM   _NO_OS_
-#define DEV_SYSTEM      _DEV_RVCT_CARM_
-
-#define NEAR			// variables mapped to internal data storage location
-#define FAR			// variables mapped to external data storage location
-#define CONST        const	// variables mapped to ROM (i.e. flash)
-#define ROM			// code or variables mapped to ROM (i.e. flash)
-					// usage: CONST BYTE ROM foo = 0x00;
-#define HWACC			// hardware access through external memory (i.e. CAN)
-#define LARGE			// functions set parameters to external data storage location
-
-    // These types can be adjusted by users to match application requirements. The goal is to
-    // minimize code memory and maximize speed.
-#define GENERIC			// generic pointer to point to application data
-					// Variables with this attribute can be located in external
-					// or internal data memory.
-#define MEM			// Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef QWORD
-#define QWORD long long
-#endif
-
-#ifndef NDEBUG
-#define ASSERT(expr)    if (!(expr)) {\
-                                   TRACE0 ("Assertion failed: " #expr );\
-                                   while (1);}
-#else
-#define ASSERT(expr)
-#endif
-
-#ifndef NDEBUG
-#include <stdio.h>		// prototype printf() (for TRACE)
-#define TRACE  printf
-#endif
-
-//---------------------------------------------------------------------------
-//  definitions for ARM IAR C Compiler
-//---------------------------------------------------------------------------
-#elif  defined (__ICCARM__)
-
-#define TARGET_SYSTEM   _NO_OS_
-#define DEV_SYSTEM      _DEV_IAR_CARM_
-
-#define NEAR			// variables mapped to internal data storage location
-#define FAR			// variables mapped to external data storage location
-#define CONST        const	// variables mapped to ROM (i.e. flash)
-#define ROM			// code or variables mapped to ROM (i.e. flash)
-					// usage: CONST BYTE ROM foo = 0x00;
-#define HWACC			// hardware access through external memory (i.e. CAN)
-#define LARGE			// functions set parameters to external data storage location
-
-    // These types can be adjusted by users to match application requirements. The goal is to
-    // minimize code memory and maximize speed.
-#define GENERIC			// generic pointer to point to application data
-					// Variables with this attribute can be located in external
-					// or internal data memory.
-#define MEM			// Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef QWORD
-#define QWORD long long
-#endif
-
-    // Workaround:
-    // If we use IAR and want to debug but don't want to use C-Spy Debugger
-    // assert() doesn't work in debug mode because it needs support for FILE descriptors
-    // (_DLIB_FILE_DESCRIPTOR == 1).
-#ifndef NDEBUG
-#define ASSERT(expr)    if (!(expr)) {\
-                                   TRACE0 ("Assertion failed: " #expr );\
-                                   while (1);}
-#else
-#define ASSERT(expr)
-#endif
-
-#ifndef NDEBUG
-#include <stdio.h>		// prototype printf() (for TRACE)
-#define TRACE  printf
-//        #define TRACE  PRINTF4
-#endif
-
-//---------------------------------------------------------------------------
-//  definitions for Tasking 8051
-//---------------------------------------------------------------------------
-
-#elif defined (_CC51)
-
-#include <cc51.h>
-
-#define TARGET_SYSTEM   _NO_OS_
-#define DEV_SYSTEM      _DEV_TASKING_C51X_
-
-#define NEAR            _data	// variables mapped to internal data storage location
-#define FAR             _xdat	// variables mapped to external data storage location
-#define CONST           const	// variables mapped to ROM (i.e. flash)
-#define ROM			// code or variables mapped to ROM (i.e. flash)
-					// usage: CONST BYTE ROM foo = 0x00;
-#define HWACC           _xdat	// hardware access through external memory (i.e. CAN)
-#define LARGE			// functions set parameters to external data storage location
-
-    // These types can be adjusted by users to match application requirements. The goal is to
-    // minimize code memory and maximize speed.
-#define GENERIC			// generic pointer to point to application data
-					// Variables with this attribute can be located in external
-					// or internal data memory.
-#define MEM             _xdat	// Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT       _reentrant
-#define PUBLIC
-
-#ifndef NDEBUG
-#include <stdio.h>		// prototype printf() (for TRACE)
-#define TRACE  printf
-#endif
-
-//---------------------------------------------------------------------------
-//  definitions for Tasking C167CR and C164CI
-//---------------------------------------------------------------------------
-
-#elif defined (_C166)
-
-#define TARGET_SYSTEM   _NO_OS_
-#define DEV_SYSTEM      _DEV_TASKING_C16X_
-
-#define NEAR            near	// variables mapped to internal data storage location
-#define FAR             far	// variables mapped to external data storage location
-#define CONST           const	// variables mapped to ROM (i.e. flash)
-#define ROM			// code or variables mapped to ROM (i.e. flash)
-					// usage: CONST BYTE ROM foo = 0x00;
-#define HWACC   /* to be defined */	// hardware access through external memory (i.e. CAN)
-#define LARGE			// functions set parameters to external data storage location
-
-    // These types can be adjusted by users to match application requirements. The goal is to
-    // minimize code memory and maximize speed.
-#define GENERIC			// generic pointer to point to application data
-					// Variables with this attribute can be located in external
-					// or internal data memory.
-#define MEM			// Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
-    // Stdio.h has to be alway included here. If printf() is used stdio.h defines NULL
-    // without checking if it is already included. So an error occurs while compiling.
-    // (r.d.)
-#include <stdio.h>		// prototype printf() (for TRACE)
-#ifndef NDEBUG
-#define TRACE  printf
-#endif
-
-//---------------------------------------------------------------------------
-//  definitions for FUJITSU FFMC-16LX MB90590
-//---------------------------------------------------------------------------
-
-//#elif (defined (F590) || defined (F543) || defined (F598) || defined (F495) || defined (F350))
-#elif defined(__COMPILER_FCC907__)
-
-#define TARGET_SYSTEM   _NO_OS_
-#define DEV_SYSTEM      _DEV_FUJITSU_F590_
-
-#define NEAR    /* to be defined */	// variables mapped to internal data storage location
-#define FAR     /* to be defined */	// variables mapped to external data storage location
-#define CONST           const	// variables mapped to ROM (i.e. flash)
-#define ROM     /* to be defined */	// code or variables mapped to ROM (i.e. flash)
-					// usage: CONST BYTE ROM foo = 0x00;
-#define HWACC   /* to be defined */	// hardware access through external memory (i.e. CAN)
-#define LARGE			// functions set parameters to external data storage location
-
-    // These types can be adjusted by users to match application requirements. The goal is to
-    // minimize code memory and maximize speed.
-#define GENERIC			// generic pointer to point to application data
-					// Variables with this attribute can be located in external
-					// or internal data memory.
-#define MEM			// Memory attribute to optimize speed and code of pointer access.
-
-    // softune is not able to support 64 bit variables QWORD !!!
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#include <stdio.h>		// prototype printf() (for TRACE)
-#define TRACE  printf
-#endif
-
-//---------------------------------------------------------------------------
-//  definitions for Mitsubishi M16C family for TASKING Compiler CM16
-//---------------------------------------------------------------------------
-
-#elif defined (_CM16C)
-
-#define TARGET_SYSTEM   _NO_OS_
-#define DEV_SYSTEM      _DEV_TASKING_M16C_
-
-#define NEAR            _near	// variables mapped to internal data storage location
-#define FAR             _far	// variables mapped to external data storage location
-#define CONST           _farrom	// variables mapped to ROM (i.e. flash)
-#define ROM			// code or variables mapped to ROM (i.e. flash)
-					// usage: CONST BYTE ROM foo = 0x00;
-#define HWACC           _near	// hardware access through external memory (i.e. CAN)
-#define LARGE			// functions set parameters to external data storage location
-
-    // These types can be adjusted by users to match application requirements. The goal is to
-    // minimize code memory and maximize speed.
-#define GENERIC         _far	// generic pointer to point to application data
-					// Variables with this attribute can be located in external
-					// or internal data memory.
-					// do you use memory model SMALL, than you have to set _far
-#define MEM			// Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
-    // Stdio.h has to be alway included here. If printf() is used stdio.h defines NULL
-    // without checking if it is already included. So an error occurs while compiling.
-    // (r.d.)
-#include <stdio.h>		// prototype printf() (for TRACE)
-#ifndef NDEBUG
-#define TRACE  printf
-#endif
-
-//---------------------------------------------------------------------------
-//  definitions for Mitsubishi M16C family for Mitsubishi Compiler NC30
-//---------------------------------------------------------------------------
-// name NC30, andere Form will der Compiler nicht !!
-#elif defined (NC30)
-
-#define TARGET_SYSTEM   _NO_OS_
-#define DEV_SYSTEM      _DEV_MITSUBISHI_M16C_
-
-#define NEAR            near	// variables mapped to internal data storage location
-#define FAR             far	// variables mapped to external data storage location
-#define CONST           const	// variables mapped to ROM (i.e. flash)
-#define ROM			// code or variables mapped to ROM (i.e. flash)
-					// usage: CONST BYTE ROM foo = 0x00;
-#define HWACC           near	// hardware access through external memory (i.e. CAN)
-#define LARGE			// functions set parameters to external data storage location
-
-    // These types can be adjusted by users to match application requirements. The goal is to
-    // minimize code memory and maximize speed.
-#define GENERIC         far	// generic pointer to point to application data
-					// Variables with this attribute can be located in external
-					// or internal data memory.
-#define MEM			// Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#include <stdio.h>		// prototype printf() (for TRACE)
-#define TRACE  printf
-#endif
-
-//---------------------------------------------------------------------------
-//  definitions for Renesas M32C family for Renesas Compiler
-//---------------------------------------------------------------------------
-#elif defined (NC308)
-
-#define TARGET_SYSTEM   _NO_OS_
-#define DEV_SYSTEM      _DEV_RENESAS_M32C_
-
-#define NEAR             near	// variables mapped to internal data storage location
-#define FAR              far	// variables mapped to external data storage location
-#define CONST            const	// variables mapped to ROM (i.e. flash)
-#define ROM			// code or variables mapped to ROM (i.e. flash)
-#define HWACC			// hardware access through external memory (i.e. CAN)
-#define LARGE			// functions set parameters to external data storage location
-
-    // These types can be adjusted by users to match application requirements. The goal is to
-    // minimize code memory and maximize speed.
-#define GENERIC			// generic pointer to point to application data
-					// Variables with this attribute can be located in external
-					// or internal data memory.
-#define MEM              far	// Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#include <stdio.h>		// prototype printf() (for TRACE)
-#define TRACE  printf
-#endif
-
-//    #error ("RENESAS o.k.")
-
-//---------------------------------------------------------------------------
-//  definitions for ARM7 family with GNU compiler
-//---------------------------------------------------------------------------
-
-#elif defined(__GNUC__) && defined(__arm__) && !defined(__LINUX_ARM_ARCH__)
-
-#define TARGET_SYSTEM   _NO_OS_
-#define DEV_SYSTEM      _DEV_GNU_ARM7_
-
-#define NEAR			// variables mapped to internal data storage location
-#define FAR			// variables mapped to external data storage location
-#define CONST           const	// variables mapped to ROM (i.e. flash)
-#define ROM			// code or variables mapped to ROM (i.e. flash)
-					// usage: CONST BYTE ROM foo = 0x00;
-#define HWACC			// hardware access through external memory (i.e. CAN)
-#define LARGE			// functions set parameters to external data storage location
-
-    // These types can be adjusted by users to match application requirements. The goal is to
-    // minimize code memory and maximize speed.
-#define GENERIC			// generic pointer to point to application data
-					// Variables with this attribute can be located in external
-					// or internal data memory.
-#define MEM			// Memory attribute to optimize speed and code of pointer access.
-#define HWACC			// hardware access through external memory (i.e. CAN)
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef QWORD
-#define QWORD long long		// i.A. durch Herr Kuschel
-#endif
-
-#ifndef NDEBUG
-#include <stdio.h>		// prototype printf() (for TRACE)
-#define TRACE  printf
-#endif
-
-//---------------------------------------------------------------------------
-//  definitions for Motorola PowerPC family 5x5 (555/565)
-//  definitions Linux-PC
-//---------------------------------------------------------------------------
-
-#elif defined (__GNUC__)
-
-#if defined (LINUX) || defined (linux) || defined (__linux__)
-#define LINUX_SYSTEM		// define 'LINUX_SYSTEM' uniform for all Linux based systems
-	// r.d.: We will need an other solution here! There are two sections here which do check the preproc-definitions:
-	//     LINUX and __linux__ . The first one was Linux for PC, the second one is this section for embedded Linux (MCF5xxx).
-	//     But Linux for PC does not need the definitions for embedded Linux.
-#endif
-
-    // GNU C compiler supports function inlining
-#define INLINE_FUNCTION_DEF extern inline
-
-    // to actually enable inlining just include the following three lines
-    // #undef INLINE_FUNCTION
-    // #define INLINE_FUNCTION     INLINE_FUNCTION_DEF
-    // #define INLINE_ENABLED      TRUE
-
-#ifdef PXROS
-#define TARGET_SYSTEM       _PXROS_
-#ifdef __i386__
-#undef LINUX			// this define seems to be set from compiler
-#define DEV_SYSTEM      _DEV_HIGHTEC_X86_
-#elif defined (__tricore__)
-#define DEV_SYSTEM      _DEV_GNU_TRICORE_
-#else // MPC5x5
-#define DEV_SYSTEM      _DEV_GNU_MPC5X5_
-#endif
-
-#elif defined (LINUX) || defined (__linux__)
-#define TARGET_SYSTEM       _LINUX_	// Linux definition
-#define DEV_SYSTEM          _DEV_LINUX_
-
-#elif defined (GNU_CF5282)
-#define TARGET_SYSTEM       _NO_OS_
-#define DEV_SYSTEM          _DEV_GNU_CF5282_
-
-#elif defined (ECOSPRO_I386_PEAK_PCI)
-#define TARGET_SYSTEM       _ECOSPRO_
-#define DEV_SYSTEM          _DEV_GNU_I386_
-
-#elif defined (GNU_CF548X)
-#define TARGET_SYSTEM       _NO_OS_
-#define DEV_SYSTEM          _DEV_GNU_CF548X_
-#else
-#error 'ERROR: DEV_SYSTEM not found!'
-#endif
-
-#ifndef QWORD
-#define QWORD long long int
-#endif
-
-#if (TARGET_SYSTEM == _PXROS_)
-
-#ifndef __KERNEL__
-#include <string.h>
-#endif
-
-#define NEAR			// variables mapped to internal data storage location
-#define FAR			// variables mapped to external data storage location
-#define CONST           const	// variables mapped to ROM (i.e. flash)
-#define ROM     /* to be defined */	// code or variables mapped to ROM (i.e. flash)
-					    // usage: CONST BYTE ROM foo = 0x00;
-#define LARGE			// functions set parameters to external data storage location
-
-	// These types can be adjusted by users to match application requirements. The goal is to
-	// minimize code memory and maximize speed.
-#define GENERIC			// generic pointer to point to application data
-					    // Variables with this attribute can be located in external
-					    // or internal data memory.
-#define MEM			// Memory attribute to optimize speed and code of pointer access.
-
-#define HWACC			// hardware access through external memory (i.e. CAN)
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef QWORD
-#define QWORD long long int
-#endif
-
-#ifndef NDEBUG
-#include <stdio.h>		// prototype printf() (for TRACE)
-#define TRACE  printf
-#endif
-
-#endif
-
-    // ------------------ GNUC for I386 ---------------------------------------------
-
-#if (TARGET_SYSTEM == _LINUX_) || (TARGET_SYSTEM == _ECOSPRO_)
-
-#ifndef __KERNEL__
-#include <string.h>
-#endif
-
-#define ROM			// code or variables mapped to ROM (i.e. flash)
-					// usage: CONST BYTE ROM foo = 0x00;
-#define HWACC			// hardware access through external memory (i.e. CAN)
-
-	// These types can be adjusted by users to match application requirements. The goal is to
-	// minimize code memory and maximize speed.
-#define GENERIC			// generic pointer to point to application data
-					// Variables with this attribute can be located in external
-					// or internal data memory.
-#define MEM			// Memory attribute to optimize speed and code of pointer access.
-
-#ifndef NEAR
-#define NEAR			// variables mapped to internal data storage location
-#endif
-
-#ifndef FAR
-#define FAR			// variables mapped to external data storage location
-#endif
-
-#ifndef CONST
-#define CONST const		// variables mapped to ROM (i.e. flash)
-#endif
-
-#define LARGE
-
-#define REENTRANT
-#define PUBLIC
 
-#ifndef NDEBUG
-#ifndef __KERNEL__
-#include <stdio.h>		// prototype printf() (for TRACE)
-#define TRACE  printf
-#else
 #define TRACE  printk
-#endif
-#endif
-#endif
 
-    // ------------------ GNU without OS ---------------------------------------------
-
-#if (TARGET_SYSTEM == _NO_OS_)
-
-#define ROM			// code or variables mapped to ROM (i.e. flash)
-					// usage: CONST BYTE ROM foo = 0x00;
-#define HWACC			// hardware access through external memory (i.e. CAN)
-
-	// These types can be adjusted by users to match application requirements. The goal is to
-	// minimize code memory and maximize speed.
-#define GENERIC			// generic pointer to point to application data
-					// Variables with this attribute can be located in external
-					// or internal data memory.
-#define MEM			// Memory attribute to optimize speed and code of pointer access.
-
-#ifndef NEAR
-#define NEAR			// variables mapped to internal data storage location
-#endif
-
-#ifndef FAR
-#define FAR			// variables mapped to external data storage location
-#endif
-
-#ifndef CONST
-#define CONST const		// variables mapped to ROM (i.e. flash)
-#endif
-
-#define LARGE
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-//            #include "xuartdrv.h"
-//            #include <stdio.h>              // prototype printf() (for TRACE)
-#define TRACE  printf
-//            #define TRACE  mprintf
-//            #ifndef TRACE
-//                #define TRACE trace
-//                void trace (char *fmt, ...);
-//            #endif
-#endif
-
-#endif
-
-//---------------------------------------------------------------------------
-//  definitions for MPC565
-//---------------------------------------------------------------------------
-#elif __MWERKS__
-
-#ifdef __MC68K__
-
-#define TARGET_SYSTEM = _MCF548X_
-#define DEV_SYSTEM      _DEV_MCW_MCF5XXX_
-
-#else
-#define TARGET_SYSTEM = _MPC565_
-#define DEV_SYSTEM      _DEV_MCW_MPC5X5_
-#endif
-
-#define NEAR			// variables mapped to internal data storage location
-#define FAR			// variables mapped to external data storage location
-#define CONST           const	// variables mapped to ROM (i.e. flash)
-#define ROM			// code or variables mapped to ROM (i.e. flash)
-					// usage: CONST BYTE ROM foo = 0x00;
-#define LARGE			// functions set parameters to external data storage location
-
-    // These types can be adjusted by users to match application requirements. The goal is to
-    // minimize code memory and maximize speed.
-#define GENERIC			// generic pointer to point to application data
-					// Variables with this attribute can be located in external
-					// or internal data memory.
-#define MEM			// Memory attribute to optimize speed and code of pointer access.
-
-#define HWACC			// hardware access through external memory (i.e. CAN)
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#include <stdio.h>		// prototype printf() (for TRACE)
-#define TRACE  printf
-#endif
-
-//---------------------------------------------------------------------------
-//  definitions for BECK 1x3
-//---------------------------------------------------------------------------
-#elif defined (__BORLANDC__) && defined (__PARADIGM__)
-
-#define TARGET_SYSTEM      _NO_OS_
-#define DEV_SYSTEM         _DEV_PAR_BECK1X3_
-
-#define ROM			// code or variables mapped to ROM (i.e. flash)
-				     // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC			// hardware access through external memory (i.e. CAN)
-
-     // These types can be adjusted by users to match application requirements. The goal is to
-     // minimize code memory and maximize speed.
-#define GENERIC			// generic pointer to point to application data
-				     // Variables with this attribute can be located in external
-				     // or internal data memory.
-#define MEM			// Memory attribute to optimize speed and code of pointer access.
-#define NEAR __near		// variables mapped to internal data storage location
-#define FAR  __far		// variables mapped to external data storage location
-#define CONST const		// variables mapped to ROM (i.e. flash)
-#define LARGE
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#ifndef TRACE
-#include <stdio.h>
-#define TRACE printf
-#endif
-#endif
-
-//---------------------------------------------------------------------------
-//  definitions for PC
-//---------------------------------------------------------------------------
-
-#elif defined (__BORLANDC__)
-
-    // ------------------ definition target system --------------------------
-
-#ifdef _WIN32
-#define TARGET_SYSTEM   _WIN32_	// WIN32 definition
-#define DEV_SYSTEM      _DEV_WIN32_
-#else
-#define TARGET_SYSTEM   _DOS_
-#define DEV_SYSTEM      _DEV_BORLAND_DOS_
-#endif
-
-    // ------------------ WIN32 ---------------------------------------------
-
-#if (TARGET_SYSTEM == _WIN32_)
-
-#define ROM			// code or variables mapped to ROM (i.e. flash)
-					// usage: CONST BYTE ROM foo = 0x00;
-#define HWACC			// hardware access through external memory (i.e. CAN)
-
-	// These types can be adjusted by users to match application requirements. The goal is to
-	// minimize code memory and maximize speed.
-#define GENERIC			// generic pointer to point to application data
-					// Variables with this attribute can be located in external
-					// or internal data memory.
-#define MEM			// Memory attribute to optimize speed and code of pointer access.
-
-#ifndef NEAR
-#define NEAR			// variables mapped to internal data storage location
-#endif
-
-#ifndef FAR
-#define FAR			// variables mapped to external data storage location
-#endif
-
-#ifndef CONST
-#define CONST const		// variables mapped to ROM (i.e. flash)
-#endif
-
-#define LARGE
-
-#define REENTRANT
-#define PUBLIC __stdcall
-
-#ifndef NDEBUG
-#ifndef TRACE
-#include <stdio.h>
-#define TRACE printf
-#endif
-#endif
-
-#elif (TARGET_SYSTEM == _DOS_)
-
-#define ROM			// code or variables mapped to ROM (i.e. flash)
-					// usage: CONST BYTE ROM foo = 0x00;
-#define HWACC			// hardware access through external memory (i.e. CAN)
-
-	// These types can be adjusted by users to match application requirements. The goal is to
-	// minimize code memory and maximize speed.
-#define GENERIC			// generic pointer to point to application data
-					// Variables with this attribute can be located in external
-					// or internal data memory.
-#define MEM			// Memory attribute to optimize speed and code of pointer access.
-#define NEAR near		// variables mapped to internal data storage location
-#define FAR  far		// variables mapped to external data storage location
-#define CONST const		// variables mapped to ROM (i.e. flash)
-#define LARGE
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#ifndef TRACE
-#include <stdio.h>
-#define TRACE printf
-#endif
-#endif
-
-#endif
-
-#elif (_MSC_VER == 800)		// PC MS Visual C/C++ for DOS applications
-
-#define TARGET_SYSTEM   _DOS_
-#define DEV_SYSTEM      _DEV_MSVC_DOS_
-
-#define ROM			// code or variables mapped to ROM (i.e. flash)
-				    // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC near		// hardware access through external memory (i.e. CAN)
-
-    // These types can be adjusted by users to match application requirements. The goal is to
-    // minimize code memory and maximize speed.
-#define GENERIC			// generic pointer to point to application data
-				    // Variables with this attribute can be located in external
-				    // or internal data memory.
-#define MEM			// Memory attribute to optimize speed and code of pointer access.
-#define NEAR near		// variables mapped to internal data storage location
-#define FAR  far		// variables mapped to external data storage location
-#define CONST const		// variables mapped to ROM (i.e. flash)
-#define LARGE
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#ifndef TRACE
-#include <stdio.h>
-#define TRACE printf
-#endif
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for RTX under WIN32
-//---------------------------------------------------------------------------
-#elif (defined (UNDER_RTSS) && defined (WIN32))
-
-    // ------------------ definition target system --------------------------
-#define TARGET_SYSTEM   _WIN32_RTX_
-#define DEV_SYSTEM      _DEV_WIN32_RTX_
-
-#define ROM			// code or variables mapped to ROM (i.e. flash)
-				    // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC			// hardware access through external memory (i.e. CAN)
-
-    // These types can be adjusted by users to match application requirements. The goal is to
-    // minimize code memory and maximize speed.
-#define GENERIC			// generic pointer to point to application data
-				    // Variables with this attribute can be located in external
-				    // or internal data memory.
-#define MEM			// Memory attribute to optimize speed and code of pointer access.
-
-#ifndef NEAR
-#define NEAR			// variables mapped to internal data storage location
-#endif
-
-#ifndef FAR
-#define FAR			// variables mapped to external data storage location
-#endif
-
-#ifndef CONST
-#define CONST const		// variables mapped to ROM (i.e. flash)
-#endif
-
-#define LARGE
-
-#define REENTRANT
-#define PUBLIC __stdcall
-
-#ifndef NDEBUG
-#ifndef TRACE
-#define TRACE RtPrintf
-#endif
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for WinCE
-//---------------------------------------------------------------------------
-#elif defined (_WIN32_WCE)
-
-    // ------------------ definition target system --------------------------
-#define TARGET_SYSTEM           _WINCE_
-#define DEV_SYSTEM              _DEV_WIN_CE_
-
-#define ROM			// code or variables mapped to ROM (i.e. flash)
-				    // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC			// hardware access through external memory (i.e. CAN)
-
-    // These types can be adjusted by users to match application requirements. The goal is to
-    // minimize code memory and maximize speed.
-#define GENERIC			// generic pointer to point to application data
-				    // Variables with this attribute can be located in external
-				    // or internal data memory.
-#define MEM			// Memory attribute to optimize speed and code of pointer access.
-
-#ifndef NEAR
-#define NEAR			// variables mapped to internal data storage location
-#endif
-
-#ifndef FAR
-#define FAR			// variables mapped to external data storage location
-#endif
-
-#ifndef CONST
-#define CONST const		// variables mapped to ROM (i.e. flash)
-#endif
-
-#define LARGE
-
-#ifndef QWORD
-      //#define QWORD long long int // MSVC .NET can use "long long int" too (like GNU)
-#define QWORD __int64
-#endif
-
-#define REENTRANT
-#define PUBLIC __cdecl
-
-#ifdef ASSERTMSG
-#undef ASSERTMSG
-#endif
-
-#ifndef NDEBUG
-#ifndef TRACE
-#define TRACE printf
-//            void trace (char *fmt, ...);
-#endif
-#endif
-
-#else // ===> PC MS Visual C/C++
-
-    // ------------------ definition target system --------------------------
-
-#ifdef _WIN32
-#define TARGET_SYSTEM   _WIN32_	// WIN32 definition
-#define DEV_SYSTEM      _DEV_WIN32_
-#else
-#define TARGET_SYSTEM   _WIN16_	// WIN16 definition
-#define DEV_SYSTEM      _DEV_WIN16_
-#endif
-
-    // ------------------ WIN16 ---------------------------------------------
-
-#if (TARGET_SYSTEM == _WIN16_)
-
-#define ROM			// code or variables mapped to ROM (i.e. flash)
-					// usage: CONST BYTE ROM foo = 0x00;
-#define HWACC			// hardware access through external memory (i.e. CAN)
-
-	// These types can be adjusted by users to match application requirements. The goal is to
-	// minimize code memory and maximize speed.
-#define GENERIC			// generic pointer to point to application data
-					// Variables with this attribute can be located in external
-					// or internal data memory.
-#define MEM			// Memory attribute to optimize speed and code of pointer access.
-
-#ifndef NEAR
-#define NEAR			// variables mapped to internal data storage location
-#endif
-
-#ifndef FAR
-#define FAR far			// variables mapped to external data storage location
-#endif
-
-#ifndef CONST
-#define CONST const		// variables mapped to ROM (i.e. flash)
-#endif
-
-#define LARGE
-
-#define REENTRANT
-#define PUBLIC _far _pascal _export
-
-#ifndef NDEBUG
-#ifndef TRACE
-#define TRACE trace
-#ifdef __cplusplus
-extern "C" {
-#endif
-	void trace(const char *fmt, ...);
-#ifdef __cplusplus
-}
-#endif
-#endif
-#endif
-#endif
-    // ------------------ WIN32 ---------------------------------------------
-#if (TARGET_SYSTEM == _WIN32_)
-#define ROM			// code or variables mapped to ROM (i.e. flash)
-					// usage: CONST BYTE ROM foo = 0x00;
-#define HWACC			// hardware access through external memory (i.e. CAN)
-	// These types can be adjusted by users to match application requirements. The goal is to// minimize code memory and maximize speed.
-#define GENERIC			// generic pointer to point to application data
-					// Variables with this attribute can be located in external// or internal data memory.
-#define MEM			// Memory attribute to optimize speed and code of pointer access.
-#ifndef NEAR
-#define NEAR			// variables mapped to internal data storage location
-#endif
-#ifndef FAR
-#define FAR			// variables mapped to external data storage location
-#endif
-#ifndef CONST
-#define CONST const		// variables mapped to ROM (i.e. flash)
-#endif
-#define LARGE
-#define REENTRANT
-#define PUBLIC __stdcall
-#ifndef QWORD
-	  //#define QWORD long long int // MSVC .NET can use "long long int" too (like GNU)
-#define QWORD __int64
-#endif
-#ifndef NDEBUG
-#ifndef TRACE
-#define TRACE trace
-#ifdef __cplusplus
-extern "C" {
-#endif
-	void trace(const char *fmt, ...);
-#ifdef __cplusplus
-}
-#endif
-#endif
-#endif
-	// MS Visual C++ compiler supports function inlining
-#define INLINE_FUNCTION_DEF __forceinline
-	// to actually enable inlining just include the following two lines// #define INLINE_FUNCTION     INLINE_FUNCTION_DEF// #define INLINE_ENABLED      TRUE
-#endif
-#endif				// ===> PC
-//---------------------------------------------------------------------------//  definitions of basic types//---------------------------------------------------------------------------
-#ifndef _WINDEF_		// defined in WINDEF.H, included by <windows.h>
-    // --- arithmetic types ---
-#ifndef SHORT
-#define SHORT short int
-#endif
-#ifndef USHORT
-#define USHORT unsigned short int
-#endif
-#ifndef INT
-#define INT int
-#endif
-#ifndef UINT
-#define UINT unsigned int
-#endif
-#ifndef LONG
-#define LONG long int
-#endif
-#ifndef ULONG
-#define ULONG unsigned long int
-#endif
-    // --- logic types ---
-#ifndef BYTE
-#define BYTE unsigned char
-#endif
-#ifndef WORD
-#define WORD unsigned short int
-#endif
-#ifndef DWORD
-#define DWORD unsigned long int
-#endif
+// --- logic types ---
 #ifndef BOOL
 #define BOOL unsigned char
 #endif
-    // --- alias types ---
+
+// --- alias types ---
 #ifndef TRUE
 #define TRUE  0xFF
 #endif
 #ifndef FALSE
 #define FALSE 0x00
 #endif
-#ifndef NULL
-#define NULL ((void *) 0)
-#endif
-#endif
 #ifndef _TIME_OF_DAY_DEFINED_
 typedef struct {
 	unsigned long int m_dwMs;
@@ -1359,15 +119,8 @@
 //---------------------------------------------------------------------------
 
 #ifndef ASSERT
-#if !defined (__linux__) && !defined (__KERNEL__)
-#include <assert.h>
-#ifndef ASSERT
-#define ASSERT(p)    assert(p)
-#endif
-#else
 #define ASSERT(p)
 #endif
-#endif
 
 //---------------------------------------------------------------------------
 //  SYS TEC extensions
diff --git a/drivers/staging/epl/kernel/EplDllk.h b/drivers/staging/epl/kernel/EplDllk.h
index 588e871..a97920a 100644
--- a/drivers/staging/epl/kernel/EplDllk.h
+++ b/drivers/staging/epl/kernel/EplDllk.h
@@ -74,18 +74,10 @@
 #include "../EplDll.h"
 #include "../EplEvent.h"
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
 typedef tEplKernel(*tEplDllkCbAsync) (tEplFrameInfo * pFrameInfo_p);
 
 typedef struct {
-	BYTE m_be_abSrcMac[6];
+	u8 m_be_abSrcMac[6];
 
 } tEplDllkInitParam;
 
@@ -96,22 +88,18 @@
 	struct _tEplDllkNodeInfo *m_pNextNodeInfo;
 	struct _tEdrvTxBuffer *m_pPreqTxBuffer;
 	unsigned int m_uiNodeId;
-	DWORD m_dwPresTimeout;
+	u32 m_dwPresTimeout;
 	unsigned long m_ulDllErrorEvents;
 	tEplNmtState m_NmtState;
-	WORD m_wPresPayloadLimit;
-	BYTE m_be_abMacAddr[6];
-	BYTE m_bSoaFlag1;
+	u16 m_wPresPayloadLimit;
+	u8 m_be_abMacAddr[6];
+	u8 m_bSoaFlag1;
 	BOOL m_fSoftDelete;	// delete node after error and ignore error
 
 };
 
 typedef struct _tEplDllkNodeInfo tEplDllkNodeInfo;
 
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
 
 tEplKernel EplDllkAddInstance(tEplDllkInitParam * pInitParam_p);
@@ -154,7 +142,7 @@
 
 tEplKernel EplDllkSoftDeleteNode(unsigned int uiNodeId_p);
 
-tEplKernel EplDllkSetFlag1OfNode(unsigned int uiNodeId_p, BYTE bSoaFlag1_p);
+tEplKernel EplDllkSetFlag1OfNode(unsigned int uiNodeId_p, u8 bSoaFlag1_p);
 
 tEplKernel EplDllkGetFirstNodeInfo(tEplDllkNodeInfo ** ppNodeInfo_p);
 
diff --git a/drivers/staging/epl/kernel/EplDllkCal.h b/drivers/staging/epl/kernel/EplDllkCal.h
index 6c4dc7e..ddec1d5 100644
--- a/drivers/staging/epl/kernel/EplDllkCal.h
+++ b/drivers/staging/epl/kernel/EplDllkCal.h
@@ -74,14 +74,6 @@
 #include "../EplDll.h"
 #include "../EplEvent.h"
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
 typedef struct {
 	unsigned long m_ulCurTxFrameCountGen;
 	unsigned long m_ulCurTxFrameCountNmt;
@@ -92,10 +84,6 @@
 
 } tEplDllkCalStatistics;
 
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
 
 tEplKernel EplDllkCalAddInstance(void);
@@ -124,7 +112,7 @@
 tEplKernel EplDllkCalAsyncClearQueues(void);
 
 tEplKernel EplDllkCalIssueRequest(tEplDllReqServiceId Service_p,
-				  unsigned int uiNodeId_p, BYTE bSoaFlag1_p);
+				  unsigned int uiNodeId_p, u8 bSoaFlag1_p);
 
 tEplKernel EplDllkCalAsyncGetSoaRequest(tEplDllReqServiceId * pReqServiceId_p,
 					unsigned int *puiNodeId_p);
diff --git a/drivers/staging/epl/kernel/EplErrorHandlerk.h b/drivers/staging/epl/kernel/EplErrorHandlerk.h
index 4a67ef8..185b597 100644
--- a/drivers/staging/epl/kernel/EplErrorHandlerk.h
+++ b/drivers/staging/epl/kernel/EplErrorHandlerk.h
@@ -73,28 +73,16 @@
 
 #include "../EplEvent.h"
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
 // init function
-tEplKernel PUBLIC EplErrorHandlerkInit(void);
+tEplKernel EplErrorHandlerkInit(void);
 
 // add instance
-tEplKernel PUBLIC EplErrorHandlerkAddInstance(void);
+tEplKernel EplErrorHandlerkAddInstance(void);
 
 // delete instance
-tEplKernel PUBLIC EplErrorHandlerkDelInstance(void);
+tEplKernel EplErrorHandlerkDelInstance(void);
 
 // processes error events
-tEplKernel PUBLIC EplErrorHandlerkProcess(tEplEvent * pEvent_p);
+tEplKernel EplErrorHandlerkProcess(tEplEvent *pEvent_p);
 
 #endif // #ifndef _EPL_ERRORHANDLERK_H_
diff --git a/drivers/staging/epl/kernel/EplEventk.h b/drivers/staging/epl/kernel/EplEventk.h
index 1d25aaa..0c2a60f 100644
--- a/drivers/staging/epl/kernel/EplEventk.h
+++ b/drivers/staging/epl/kernel/EplEventk.h
@@ -73,36 +73,24 @@
 
 #include "../EplEvent.h"
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
 // init function
-tEplKernel PUBLIC EplEventkInit(tEplSyncCb fpSyncCb);
+tEplKernel EplEventkInit(tEplSyncCb fpSyncCb);
 
 // add instance
-tEplKernel PUBLIC EplEventkAddInstance(tEplSyncCb fpSyncCb);
+tEplKernel EplEventkAddInstance(tEplSyncCb fpSyncCb);
 
 // delete instance
-tEplKernel PUBLIC EplEventkDelInstance(void);
+tEplKernel EplEventkDelInstance(void);
 
 // Kernelthread that dispatches events in kernelspace
-tEplKernel PUBLIC EplEventkProcess(tEplEvent * pEvent_p);
+tEplKernel EplEventkProcess(tEplEvent *pEvent_p);
 
 // post events from kernelspace
-tEplKernel PUBLIC EplEventkPost(tEplEvent * pEvent_p);
+tEplKernel EplEventkPost(tEplEvent *pEvent_p);
 
 // post errorevents from kernelspace
-tEplKernel PUBLIC EplEventkPostError(tEplEventSource EventSource_p,
-				     tEplKernel EplError_p,
-				     unsigned int uiArgSize_p, void *pArg_p);
+tEplKernel EplEventkPostError(tEplEventSource EventSource_p,
+			      tEplKernel EplError_p,
+			      unsigned int uiArgSize_p, void *pArg_p);
 
 #endif // #ifndef _EPL_EVENTK_H_
diff --git a/drivers/staging/epl/kernel/EplNmtk.h b/drivers/staging/epl/kernel/EplNmtk.h
index 53409cc..5dc8a37 100644
--- a/drivers/staging/epl/kernel/EplNmtk.h
+++ b/drivers/staging/epl/kernel/EplNmtk.h
@@ -74,31 +74,16 @@
 #include "../EplNmt.h"
 #include "EplEventk.h"
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtkInit(EPL_MCO_DECL_PTR_INSTANCE_PTR);
+tEplKernel EplNmtkInit(EPL_MCO_DECL_PTR_INSTANCE_PTR);
 
-EPLDLLEXPORT tEplKernel PUBLIC
-EplNmtkAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR);
+tEplKernel EplNmtkAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR);
 
-EPLDLLEXPORT tEplKernel PUBLIC
-EplNmtkDelInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR);
+tEplKernel EplNmtkDelInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR);
 
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtkProcess(EPL_MCO_DECL_PTR_INSTANCE_PTR_
-					      tEplEvent * pEvent_p);
+tEplKernel EplNmtkProcess(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplEvent *pEvent_p);
 
-EPLDLLEXPORT tEplNmtState PUBLIC
-EplNmtkGetNmtState(EPL_MCO_DECL_PTR_INSTANCE_PTR);
+tEplNmtState EplNmtkGetNmtState(EPL_MCO_DECL_PTR_INSTANCE_PTR);
 
 #endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
 
diff --git a/drivers/staging/epl/kernel/EplNmtkCal.h b/drivers/staging/epl/kernel/EplNmtkCal.h
deleted file mode 100644
index 9edeafc..0000000
--- a/drivers/staging/epl/kernel/EplNmtkCal.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for communication abstraction layer of the
-                NMT-Kernel-Module
-
-  License:
-
-    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 SYSTEC electronic GmbH nor the names of its
-       contributors may be used to endorse or promote products derived
-       from this software without prior written permission. For written
-       permission, please contact info@systec-electronic.com.
-
-    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 HOLDERS 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.
-
-    Severability Clause:
-
-        If a provision of this License is or becomes illegal, invalid or
-        unenforceable in any jurisdiction, that shall not affect:
-        1. the validity or enforceability in that jurisdiction of any other
-           provision of this License; or
-        2. the validity or enforceability in other jurisdictions of that or
-           any other provision of this License.
-
-  -------------------------------------------------------------------------
-
-                $RCSfile: EplNmtkCal.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.3 $  $Date: 2008/04/17 21:36:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                KEIL uVision 2
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/16 -k.t.:   start of the implementation
-
-****************************************************************************/
-
-#include "EplNmtk.h"
-
-#ifndef _EPLNMTKCAL_H_
-#define _EPLNMTKCAL_H_
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-#endif // #ifndef _EPLNMTKCAL_H_
diff --git a/drivers/staging/epl/kernel/EplObdk.h b/drivers/staging/epl/kernel/EplObdk.h
index cf9f583..78c4d96 100644
--- a/drivers/staging/epl/kernel/EplObdk.h
+++ b/drivers/staging/epl/kernel/EplObdk.h
@@ -68,128 +68,88 @@
 
 ****************************************************************************/
 
-#include "../EplObd.h"
-
 #ifndef _EPLOBDK_H_
 #define _EPLOBDK_H_
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
+#include "../EplObd.h"
 
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
+extern u8 abEplObdTrashObject_g[8];
 
-//---------------------------------------------------------------------------
-// global variables
-//---------------------------------------------------------------------------
-
-extern BYTE MEM abEplObdTrashObject_g[8];
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
 // ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdInit(EPL_MCO_DECL_PTR_INSTANCE_PTR_
-					  tEplObdInitParam MEM * pInitParam_p);
+tEplKernel EplObdInit(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam *pInitParam_p);
 
 // ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR_
-						 tEplObdInitParam MEM *
-						 pInitParam_p);
+tEplKernel EplObdAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam *pInitParam_p);
 
 // ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdDeleteInstance(EPL_MCO_DECL_INSTANCE_PTR);
+tEplKernel EplObdDeleteInstance(EPL_MCO_DECL_INSTANCE_PTR);
 
 // ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntry(EPL_MCO_DECL_INSTANCE_PTR_
-						unsigned int uiIndex_p,
-						unsigned int uiSubIndex_p,
-						void *pSrcData_p,
-						tEplObdSize Size_p);
+tEplKernel EplObdWriteEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+			    unsigned int uiSubIndex_p,
+			    void *pSrcData_p, tEplObdSize Size_p);
 
 // ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntry(EPL_MCO_DECL_INSTANCE_PTR_
-					       unsigned int uiIndex_p,
-					       unsigned int uiSubIndex_p,
-					       void *pDstData_p,
-					       tEplObdSize * pSize_p);
+tEplKernel EplObdReadEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+			   unsigned int uiSubIndex_p,
+			   void *pDstData_p, tEplObdSize *pSize_p);
 
 // ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC
-EplObdSetStoreLoadObjCallback(EPL_MCO_DECL_INSTANCE_PTR_
-			      tEplObdStoreLoadObjCallback fpCallback_p);
+tEplKernel EplObdSetStoreLoadObjCallback(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdStoreLoadObjCallback fpCallback_p);
 
 // ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdAccessOdPart(EPL_MCO_DECL_INSTANCE_PTR_
-						  tEplObdPart ObdPart_p,
-						  tEplObdDir Direction_p);
+tEplKernel EplObdAccessOdPart(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdPart ObdPart_p,
+			      tEplObdDir Direction_p);
 
 // ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdDefineVar(EPL_MCO_DECL_INSTANCE_PTR_
-					       tEplVarParam MEM * pVarParam_p);
+tEplKernel EplObdDefineVar(EPL_MCO_DECL_INSTANCE_PTR_ tEplVarParam *pVarParam_p);
 
 // ---------------------------------------------------------------------
-EPLDLLEXPORT void *PUBLIC EplObdGetObjectDataPtr(EPL_MCO_DECL_INSTANCE_PTR_
-						 unsigned int uiIndex_p,
-						 unsigned int uiSubIndex_p);
+void *EplObdGetObjectDataPtr(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+			     unsigned int uiSubIndex_p);
 // ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdRegisterUserOd(EPL_MCO_DECL_INSTANCE_PTR_
-						    tEplObdEntryPtr pUserOd_p);
+tEplKernel EplObdRegisterUserOd(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pUserOd_p);
 
 // ---------------------------------------------------------------------
-EPLDLLEXPORT void PUBLIC EplObdInitVarEntry(EPL_MCO_DECL_INSTANCE_PTR_
-					    tEplObdVarEntry MEM * pVarEntry_p,
-					    tEplObdType Type_p,
-					    tEplObdSize ObdSize_p);
+void EplObdInitVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdVarEntry *pVarEntry_p,
+			tEplObdType Type_p, tEplObdSize ObdSize_p);
 
 // ---------------------------------------------------------------------
-EPLDLLEXPORT tEplObdSize PUBLIC EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_
-						  unsigned int uiIndex_p,
-						  unsigned int uiSubIndex_p);
+tEplObdSize EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+			      unsigned int uiSubIndex_p);
 
 // ---------------------------------------------------------------------
-EPLDLLEXPORT unsigned int PUBLIC EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR);
+unsigned int EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR);
 
 // ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdSetNodeId(EPL_MCO_DECL_INSTANCE_PTR_
-					       unsigned int uiNodeId_p,
-					       tEplObdNodeIdType NodeIdType_p);
+tEplKernel EplObdSetNodeId(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiNodeId_p,
+			   tEplObdNodeIdType NodeIdType_p);
 
 // ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_
-						 unsigned int uiIndex_p,
-						 unsigned int uiSubIndex_p,
-						 BOOL * pfEntryNumerical);
+tEplKernel EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+			     unsigned int uiSubIndex_p, BOOL *pfEntryNumerical);
 // ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_
-						      unsigned int uiIndex_p,
-						      unsigned int uiSubIndex_p,
-						      void *pSrcData_p,
-						      tEplObdSize Size_p);
+tEplKernel EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+				  unsigned int uiSubIndex_p,
+				  void *pSrcData_p,
+				  tEplObdSize Size_p);
 
 // ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_
-						   unsigned int uiIndex_p,
-						   unsigned int uiSubIndex_p,
-						   void *pDstData_p,
-						   tEplObdSize * pSize_p);
+tEplKernel EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+			       unsigned int uiSubIndex_p,
+			       void *pDstData_p,
+			       tEplObdSize *pSize_p);
 
 // ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_
-						   unsigned int uiIndex_p,
-						   unsigned int uiSubIndex_p,
-						   tEplObdAccess *
-						   pAccessTyp_p);
+tEplKernel EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+			       unsigned int uiSubIndex_p,
+			       tEplObdAccess *pAccessTyp_p);
 
 // ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_
-						    unsigned int uiIndex_p,
-						    unsigned int uiSubindex_p,
-						    tEplObdVarEntry MEM **
-						    ppVarEntry_p);
+tEplKernel EplObdSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+				unsigned int uiSubindex_p,
+				tEplObdVarEntry **ppVarEntry_p);
 
 #endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
 
diff --git a/drivers/staging/epl/kernel/EplObdkCal.h b/drivers/staging/epl/kernel/EplObdkCal.h
deleted file mode 100644
index c173a95..0000000
--- a/drivers/staging/epl/kernel/EplObdkCal.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for communication abstraction layer
-                for the Epl-Obd-Kernelspace-Modul
-
-  License:
-
-    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 SYSTEC electronic GmbH nor the names of its
-       contributors may be used to endorse or promote products derived
-       from this software without prior written permission. For written
-       permission, please contact info@systec-electronic.com.
-
-    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 HOLDERS 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.
-
-    Severability Clause:
-
-        If a provision of this License is or becomes illegal, invalid or
-        unenforceable in any jurisdiction, that shall not affect:
-        1. the validity or enforceability in that jurisdiction of any other
-           provision of this License; or
-        2. the validity or enforceability in other jurisdictions of that or
-           any other provision of this License.
-
-  -------------------------------------------------------------------------
-
-                $RCSfile: EplObdkCal.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.4 $  $Date: 2008/04/17 21:36:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/19 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#include "../EplObd.h"
-
-#ifndef _EPLOBDKCAL_H_
-#define _EPLOBDKCAL_H_
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-#endif // #ifndef _EPLOBDKCAL_H_
diff --git a/drivers/staging/epl/kernel/EplPdok.h b/drivers/staging/epl/kernel/EplPdok.h
index b5b18f4..24bfc3f7 100644
--- a/drivers/staging/epl/kernel/EplPdok.h
+++ b/drivers/staging/epl/kernel/EplPdok.h
@@ -75,18 +75,6 @@
 #include "../EplEvent.h"
 #include "../EplDll.h"
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
 // process events from queue (PDOs/frames and SoA for synchronization)
 tEplKernel EplPdokProcess(tEplEvent * pEvent_p);
 
diff --git a/drivers/staging/epl/kernel/EplPdokCal.h b/drivers/staging/epl/kernel/EplPdokCal.h
index 6a183eb..8a31edf 100644
--- a/drivers/staging/epl/kernel/EplPdokCal.h
+++ b/drivers/staging/epl/kernel/EplPdokCal.h
@@ -72,19 +72,6 @@
 #define _EPL_PDOKCAL_H_
 
 #include "../EplInc.h"
-//#include "EplPdo.h"
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
 
 tEplKernel EplPdokCalAddInstance(void);
 
diff --git a/drivers/staging/epl/kernel/EplTimerHighResk.h b/drivers/staging/epl/kernel/EplTimerHighResk.h
index d5d046d..a2124ee 100644
--- a/drivers/staging/epl/kernel/EplTimerHighResk.h
+++ b/drivers/staging/epl/kernel/EplTimerHighResk.h
@@ -68,42 +68,29 @@
 
 ****************************************************************************/
 
-#include "../EplTimer.h"
-
 #ifndef _EPLTIMERHIGHRESK_H_
 #define _EPLTIMERHIGHRESK_H_
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
+#include "../EplTimer.h"
 
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
+tEplKernel EplTimerHighReskInit(void);
 
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+tEplKernel EplTimerHighReskAddInstance(void);
 
-tEplKernel PUBLIC EplTimerHighReskInit(void);
+tEplKernel EplTimerHighReskDelInstance(void);
 
-tEplKernel PUBLIC EplTimerHighReskAddInstance(void);
+tEplKernel EplTimerHighReskSetTimerNs(tEplTimerHdl *pTimerHdl_p,
+				      unsigned long long ullTimeNs_p,
+				      tEplTimerkCallback pfnCallback_p,
+				      unsigned long ulArgument_p,
+				      BOOL fContinuously_p);
 
-tEplKernel PUBLIC EplTimerHighReskDelInstance(void);
+tEplKernel EplTimerHighReskModifyTimerNs(tEplTimerHdl *pTimerHdl_p,
+					 unsigned long long ullTimeNs_p,
+					 tEplTimerkCallback pfnCallback_p,
+					 unsigned long ulArgument_p,
+					 BOOL fContinuously_p);
 
-tEplKernel PUBLIC EplTimerHighReskSetTimerNs(tEplTimerHdl * pTimerHdl_p,
-					     unsigned long long ullTimeNs_p,
-					     tEplTimerkCallback pfnCallback_p,
-					     unsigned long ulArgument_p,
-					     BOOL fContinuously_p);
-
-tEplKernel PUBLIC EplTimerHighReskModifyTimerNs(tEplTimerHdl * pTimerHdl_p,
-						unsigned long long ullTimeNs_p,
-						tEplTimerkCallback
-						pfnCallback_p,
-						unsigned long ulArgument_p,
-						BOOL fContinuously_p);
-
-tEplKernel PUBLIC EplTimerHighReskDeleteTimer(tEplTimerHdl * pTimerHdl_p);
+tEplKernel EplTimerHighReskDeleteTimer(tEplTimerHdl *pTimerHdl_p);
 
 #endif // #ifndef _EPLTIMERHIGHRESK_H_
diff --git a/drivers/staging/epl/kernel/EplTimerk.h b/drivers/staging/epl/kernel/EplTimerk.h
index 9160e72..47c5f47 100644
--- a/drivers/staging/epl/kernel/EplTimerk.h
+++ b/drivers/staging/epl/kernel/EplTimerk.h
@@ -68,19 +68,16 @@
 
 ****************************************************************************/
 
-#include "../EplTimer.h"
-#include "../user/EplEventu.h"
-
 #ifndef _EPLTIMERK_H_
 #define _EPLTIMERK_H_
 
+#include "../EplTimer.h"
+#include "../user/EplEventu.h"
+
 #if EPL_TIMER_USE_USER != FALSE
 #include "../user/EplTimeru.h"
 #endif
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
 
 #if EPL_TIMER_USE_USER != FALSE
 #define EplTimerkInit           EplTimeruInit
@@ -91,28 +88,21 @@
 #define EplTimerkDeleteTimer    EplTimeruDeleteTimer
 #endif
 
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
 #if EPL_TIMER_USE_USER == FALSE
-tEplKernel PUBLIC EplTimerkInit(void);
+tEplKernel EplTimerkInit(void);
 
-tEplKernel PUBLIC EplTimerkAddInstance(void);
+tEplKernel EplTimerkAddInstance(void);
 
-tEplKernel PUBLIC EplTimerkDelInstance(void);
+tEplKernel EplTimerkDelInstance(void);
 
-tEplKernel PUBLIC EplTimerkSetTimerMs(tEplTimerHdl * pTimerHdl_p,
-				      unsigned long ulTime_p,
-				      tEplTimerArg Argument_p);
+tEplKernel EplTimerkSetTimerMs(tEplTimerHdl *pTimerHdl_p,
+			       unsigned long ulTime_p,
+			       tEplTimerArg Argument_p);
 
-tEplKernel PUBLIC EplTimerkModifyTimerMs(tEplTimerHdl * pTimerHdl_p,
-					 unsigned long ulTime_p,
-					 tEplTimerArg Argument_p);
+tEplKernel EplTimerkModifyTimerMs(tEplTimerHdl *pTimerHdl_p,
+				  unsigned long ulTime_p,
+				  tEplTimerArg Argument_p);
 
-tEplKernel PUBLIC EplTimerkDeleteTimer(tEplTimerHdl * pTimerHdl_p);
+tEplKernel EplTimerkDeleteTimer(tEplTimerHdl *pTimerHdl_p);
 #endif
 #endif // #ifndef _EPLTIMERK_H_
diff --git a/drivers/staging/epl/kernel/VirtualEthernet.h b/drivers/staging/epl/kernel/VirtualEthernet.h
index deff872..4a42cce 100644
--- a/drivers/staging/epl/kernel/VirtualEthernet.h
+++ b/drivers/staging/epl/kernel/VirtualEthernet.h
@@ -73,23 +73,11 @@
 
 #include "EplDllk.h"
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0)
 
-tEplKernel PUBLIC VEthAddInstance(tEplDllkInitParam * pInitParam_p);
+tEplKernel VEthAddInstance(tEplDllkInitParam *pInitParam_p);
 
-tEplKernel PUBLIC VEthDelInstance(void);
+tEplKernel VEthDelInstance(void);
 
 #endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0)
 
diff --git a/drivers/staging/epl/proc_fs.c b/drivers/staging/epl/proc_fs.c
index f491033..9ccf079 100644
--- a/drivers/staging/epl/proc_fs.c
+++ b/drivers/staging/epl/proc_fs.c
@@ -83,7 +83,6 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/major.h>
-#include <linux/version.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/atomic.h>
@@ -95,6 +94,8 @@
 #include "fec.h"
 #endif
 
+#include "proc_fs.h"
+
 /***************************************************************************/
 /*                                                                         */
 /*                                                                         */
@@ -129,8 +130,8 @@
 
 #ifdef _DBG_TRACE_POINTS_
 atomic_t aatmDbgTracePoint_l[DBG_TRACE_POINTS];
-DWORD adwDbgTraceValue_l[DBG_TRACE_VALUES];
-DWORD dwDbgTraceValueOld_l;
+u32 adwDbgTraceValue_l[DBG_TRACE_VALUES];
+u32 dwDbgTraceValueOld_l;
 unsigned int uiDbgTraceValuePos_l;
 spinlock_t spinlockDbgTraceValue_l;
 unsigned long ulDbTraceValueFlags_l;
@@ -145,10 +146,10 @@
 static int EplLinProcWrite(struct file *file, const char __user * buffer,
 			   unsigned long count, void *data);
 
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
+void TgtDbgPostTraceValue(u32 dwTraceValue_p);
 
-EPLDLLEXPORT DWORD PUBLIC EplIdentuGetRunningRequests(void);
+extern u32 EplIdentuGetRunningRequests(void);
 
 //=========================================================================//
 //                                                                         //
@@ -191,7 +192,7 @@
 //---------------------------------------------------------------------------
 
 #ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p)
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p)
 {
 
 	if (bTracePointNumber_p >=
@@ -207,7 +208,7 @@
 
 }
 
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p)
+void TgtDbgPostTraceValue(u32 dwTraceValue_p)
 {
 
 	spin_lock_irqsave(&spinlockDbgTraceValue_l, ulDbTraceValueFlags_l);
@@ -263,7 +264,7 @@
 	// ---- EPL state ----
 	nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize,
 			  "NMT state:                  0x%04X\n",
-			  (WORD) EplNmtkGetNmtState());
+			  (u16) EplNmtkGetNmtState());
 
 	EplDllkCalGetStatistics(&pDllkCalStats);
 
@@ -279,14 +280,14 @@
 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
 	// fetch running IdentRequests
 	nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize,
-			  "running IdentRequests:      0x%08lX\n",
+			  "running IdentRequests:      0x%08X\n",
 			  EplIdentuGetRunningRequests());
 
 	// fetch state of NmtMnu module
 	{
 		unsigned int uiMandatorySlaveCount;
 		unsigned int uiSignalSlaveCount;
-		WORD wFlags;
+		u16 wFlags;
 
 		EplNmtMnuGetDiagnosticInfo(&uiMandatorySlaveCount,
 					   &uiSignalSlaveCount, &wFlags);
diff --git a/drivers/staging/epl/user/EplCfgMau.h b/drivers/staging/epl/user/EplCfgMau.h
index d25a1e9..4ac770f 100644
--- a/drivers/staging/epl/user/EplCfgMau.h
+++ b/drivers/staging/epl/user/EplCfgMau.h
@@ -69,25 +69,22 @@
 
 ****************************************************************************/
 
-#include "../EplInc.h"
-
 #ifndef _EPLCFGMA_H_
 #define _EPLCFGMA_H_
 
+#include "../EplInc.h"
+
 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_CFGMA)) != 0)
 
 #include "EplObdu.h"
 #include "EplSdoComu.h"
 
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
 //define max number of timeouts for configuration of 1 device
 #define EPL_CFGMA_MAX_TIMEOUT   3
 
 //callbackfunction, called if configuration is finished
-typedef void (PUBLIC * tfpEplCfgMaCb) (unsigned int uiNodeId_p,
-				       tEplKernel Errorstate_p);
+typedef void (* tfpEplCfgMaCb)(unsigned int uiNodeId_p,
+			       tEplKernel Errorstate_p);
 
 //State for configuartion manager Statemachine
 typedef enum {
@@ -131,33 +128,29 @@
 typedef struct {
 	tEplCfgState m_CfgState;	// state of the configuration state maschine
 	tEplSdoComConHdl m_SdoComConHdl;	// handle for sdo connection
-	DWORD m_dwLastAbortCode;
+	u32 m_dwLastAbortCode;
 	unsigned int m_uiLastIndex;	// last index of configuration, to compair with actual index
-	BYTE *m_pbConcise;	// Ptr to concise DCF
-	BYTE *m_pbActualIndex;	// Ptr to actual index in the DCF segment
+	u8 *m_pbConcise;	// Ptr to concise DCF
+	u8 *m_pbActualIndex;	// Ptr to actual index in the DCF segment
 	tfpEplCfgMaCb m_pfnCfgMaCb;	// Ptr to CfgMa Callback, is call if configuration finished
 	tEplKernel m_EplKernelError;	// errorcode
-	DWORD m_dwNumValueCopy;	// numeric values are copied in this variable
+	u32 m_dwNumValueCopy;	// numeric values are copied in this variable
 	unsigned int m_uiPdoNodeId;	// buffer for PDO node id
-	BYTE m_bNrOfMappedObject;	// number of mapped objects
+	u8 m_bNrOfMappedObject;	// number of mapped objects
 	unsigned int m_uiNodeId;	// Epl node addresse
 	tEplSdocState m_SdocState;	// bitcoded state of the SDO transfer
 	unsigned int m_uiLastSubIndex;	// last subindex of configuration
 	BOOL m_fOneTranferOk;	// atleased one transfer was successful
-	BYTE m_bEventFlag;	// for Eventsignaling to the State Maschine
-	DWORD m_dwCntObjectInDcf;	// number of Objects in DCF
+	u8 m_bEventFlag;	// for Eventsignaling to the State Maschine
+	u32 m_dwCntObjectInDcf;	// number of Objects in DCF
 	tEplCfgMaIndexType m_SkipCfg;	// TRUE if a adsitional Configurationprocess
 	// have to insert e.g. PDO-mapping
-	WORD m_wTimeOutCnt;	// Timeout Counter, break configuration is
+	u16 m_wTimeOutCnt;	// Timeout Counter, break configuration is
 	// m_wTimeOutCnt == CFGMA_MAX_TIMEOUT
 
 } tEplCfgMaNode;
 
 //---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
 // Function:    EplCfgMaInit()
 //
 // Description: Function creates first instance of Configuration Manager
@@ -166,7 +159,7 @@
 //
 // Returns:     tEplKernel              = error code
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplCfgMaInit();
+tEplKernel EplCfgMaInit(void);
 
 //---------------------------------------------------------------------------
 // Function:    EplCfgMaAddInstance()
@@ -177,7 +170,7 @@
 //
 // Returns:     tEplKernel              = error code
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplCfgMaAddInstance();
+tEplKernel EplCfgMaAddInstance(void);
 
 //---------------------------------------------------------------------------
 // Function:    EplCfgMaDelInstance()
@@ -188,7 +181,7 @@
 //
 // Returns:     tEplKernel              = error code
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplCfgMaDelInstance();
+tEplKernel plCfgMaDelInstance(void);
 
 //---------------------------------------------------------------------------
 // Function:    EplCfgMaStartConfig()
@@ -199,16 +192,16 @@
 // Parameters:  uiNodeId_p              = NodeId of the node to configure
 //              pbConcise_p             = pointer to DCF
 //              fpCfgMaCb_p             = pointer to callback function (should not be NULL)
-//              SizeOfConcise_p         = size of DCF in BYTE -> for future use
+//              SizeOfConcise_p         = size of DCF in u8 -> for future use
 //              DcfType_p               = type of the DCF
 //
 // Returns:     tCopKernel              = error code
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplCfgMaStartConfig(unsigned int uiNodeId_p,
-				      BYTE * pbConcise_p,
-				      tfpEplCfgMaCb fpCfgMaCb_p,
-				      tEplObdSize SizeOfConcise_p,
-				      tEplCfgMaDcfTyp DcfType_p);
+tEplKernel EplCfgMaStartConfig(unsigned int uiNodeId_p,
+			       u8 * pbConcise_p,
+			       tfpEplCfgMaCb fpCfgMaCb_p,
+			       tEplObdSize SizeOfConcise_p,
+			       tEplCfgMaDcfTyp DcfType_p);
 
 //---------------------------------------------------------------------------
 // Function:    CfgMaStartConfigurationNode()
@@ -222,9 +215,9 @@
 //
 // Returns:     tCopKernel              = error code
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplCfgMaStartConfigNode(unsigned int uiNodeId_p,
-					  tfpEplCfgMaCb fpCfgMaCb_p,
-					  tEplCfgMaDcfTyp DcfType_p);
+tEplKernel EplCfgMaStartConfigNode(unsigned int uiNodeId_p,
+				   tfpEplCfgMaCb fpCfgMaCb_p,
+				   tEplCfgMaDcfTyp DcfType_p);
 
 //---------------------------------------------------------------------------
 // Function:    EplCfgMaStartConfigNodeDcf()
@@ -235,16 +228,16 @@
 // Parameters:  uiNodeId_p              = NodeId of the node to configure
 //              pbConcise_p             = pointer to DCF
 //              fpCfgMaCb_p             = pointer to callback function (should not be NULL)
-//              SizeOfConcise_p         = size of DCF in BYTE -> for future use
+//              SizeOfConcise_p         = size of DCF in u8 -> for future use
 //              DcfType_p               = type of the DCF
 //
 // Returns:     tCopKernel              = error code
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplCfgMaStartConfigNodeDcf(unsigned int uiNodeId_p,
-					     BYTE * pbConcise_p,
-					     tfpEplCfgMaCb fpCfgMaCb_p,
-					     tEplObdSize SizeOfConcise_p,
-					     tEplCfgMaDcfTyp DcfType_p);
+tEplKernel EplCfgMaStartConfigNodeDcf(unsigned int uiNodeId_p,
+				      u8 * pbConcise_p,
+				      tfpEplCfgMaCb fpCfgMaCb_p,
+				      tEplObdSize SizeOfConcise_p,
+				      tEplCfgMaDcfTyp DcfType_p);
 
 //---------------------------------------------------------------------------
 // Function:    EplCfgMaLinkDcf()
@@ -253,15 +246,15 @@
 //
 // Parameters:  uiNodeId_p              = NodeId of the node to configure
 //              pbConcise_p             = pointer to DCF
-//              SizeOfConcise_p        = size of DCF in BYTE -> for future use
+//              SizeOfConcise_p        = size of DCF in u8 -> for future use
 //              DcfType_p               = type of the DCF
 //
 // Returns:     tCopKernel              = error code
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplCfgMaLinkDcf(unsigned int uiNodeId_p,
-				  BYTE * pbConcise_p,
-				  tEplObdSize SizeOfConcise_p,
-				  tEplCfgMaDcfTyp DcfType_p);
+tEplKernel EplCfgMaLinkDcf(unsigned int uiNodeId_p,
+			   u8 * pbConcise_p,
+			   tEplObdSize SizeOfConcise_p,
+			   tEplCfgMaDcfTyp DcfType_p);
 
 //---------------------------------------------------------------------------
 // Function:    EplCfgMaCheckDcf()
@@ -274,8 +267,7 @@
 //
 // Returns:     tCopKernel              = error code
 //---------------------------------------------------------------------------
-tEplKernel PUBLIC EplCfgMaCheckDcf(unsigned int uiNodeId_p,
-				   tEplCfgMaDcfTyp DcfType_p);
+tEplKernel EplCfgMaCheckDcf(unsigned int uiNodeId_p, tEplCfgMaDcfTyp DcfType_p);
 
 #endif // #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_CFGMA)) != 0)
 
diff --git a/drivers/staging/epl/user/EplDllu.h b/drivers/staging/epl/user/EplDllu.h
index 36f8bb7..890f837 100644
--- a/drivers/staging/epl/user/EplDllu.h
+++ b/drivers/staging/epl/user/EplDllu.h
@@ -73,19 +73,7 @@
 
 #include "../EplDll.h"
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-typedef tEplKernel(PUBLIC * tEplDlluCbAsnd) (tEplFrameInfo * pFrameInfo_p);
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+typedef tEplKernel(* tEplDlluCbAsnd) (tEplFrameInfo * pFrameInfo_p);
 
 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
 
diff --git a/drivers/staging/epl/user/EplDlluCal.h b/drivers/staging/epl/user/EplDlluCal.h
index b1dcd06..bc9126b 100644
--- a/drivers/staging/epl/user/EplDlluCal.h
+++ b/drivers/staging/epl/user/EplDlluCal.h
@@ -74,19 +74,8 @@
 #include "../EplDll.h"
 #include "../EplEvent.h"
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
 
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-typedef tEplKernel(PUBLIC * tEplDlluCbAsnd) (tEplFrameInfo * pFrameInfo_p);
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+typedef tEplKernel(* tEplDlluCbAsnd) (tEplFrameInfo * pFrameInfo_p);
 
 tEplKernel EplDlluCalAddInstance(void);
 
@@ -110,7 +99,7 @@
 tEplKernel EplDlluCalSoftDeleteNode(unsigned int uiNodeId_p);
 
 tEplKernel EplDlluCalIssueRequest(tEplDllReqServiceId Service_p,
-				  unsigned int uiNodeId_p, BYTE bSoaFlag1_p);
+				  unsigned int uiNodeId_p, u8 bSoaFlag1_p);
 
 #endif
 
diff --git a/drivers/staging/epl/user/EplEventu.h b/drivers/staging/epl/user/EplEventu.h
index 322cffd..ab85205 100644
--- a/drivers/staging/epl/user/EplEventu.h
+++ b/drivers/staging/epl/user/EplEventu.h
@@ -73,36 +73,24 @@
 
 #include "../EplEvent.h"
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
 // init function
-tEplKernel PUBLIC EplEventuInit(tEplProcessEventCb pfnApiProcessEventCb_p);
+tEplKernel EplEventuInit(tEplProcessEventCb pfnApiProcessEventCb_p);
 
 // add instance
-tEplKernel PUBLIC EplEventuAddInstance(tEplProcessEventCb
-				       pfnApiProcessEventCb_p);
+tEplKernel EplEventuAddInstance(tEplProcessEventCb pfnApiProcessEventCb_p);
 
 // delete instance
-tEplKernel PUBLIC EplEventuDelInstance(void);
+tEplKernel EplEventuDelInstance(void);
 
 // Task that dispatches events in userspace
-tEplKernel PUBLIC EplEventuProcess(tEplEvent * pEvent_p);
+tEplKernel EplEventuProcess(tEplEvent * pEvent_p);
 
 // post events from userspace
-tEplKernel PUBLIC EplEventuPost(tEplEvent * pEvent_p);
+tEplKernel EplEventuPost(tEplEvent * pEvent_p);
 
 // post errorevents from userspace
-tEplKernel PUBLIC EplEventuPostError(tEplEventSource EventSource_p,
-				     tEplKernel EplError_p,
-				     unsigned int uiArgSize_p, void *pArg_p);
+tEplKernel EplEventuPostError(tEplEventSource EventSource_p,
+			      tEplKernel EplError_p,
+			      unsigned int uiArgSize_p, void *pArg_p);
 
 #endif // #ifndef _EPL_EVENTU_H_
diff --git a/drivers/staging/epl/user/EplIdentu.h b/drivers/staging/epl/user/EplIdentu.h
index e730210..057c902 100644
--- a/drivers/staging/epl/user/EplIdentu.h
+++ b/drivers/staging/epl/user/EplIdentu.h
@@ -68,41 +68,27 @@
 
 ****************************************************************************/
 
-#include "../EplDll.h"
-
 #ifndef _EPLIDENTU_H_
 #define _EPLIDENTU_H_
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
+#include "../EplDll.h"
 
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-typedef tEplKernel(PUBLIC * tEplIdentuCbResponse) (unsigned int uiNodeId_p,
+typedef tEplKernel(* tEplIdentuCbResponse) (unsigned int uiNodeId_p,
 						   tEplIdentResponse *
 						   pIdentResponse_p);
 
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+tEplKernel EplIdentuInit(void);
 
-tEplKernel PUBLIC EplIdentuInit(void);
+tEplKernel EplIdentuAddInstance(void);
 
-tEplKernel PUBLIC EplIdentuAddInstance(void);
+tEplKernel EplIdentuDelInstance(void);
 
-tEplKernel PUBLIC EplIdentuDelInstance(void);
+tEplKernel EplIdentuReset(void);
 
-tEplKernel PUBLIC EplIdentuReset(void);
+tEplKernel EplIdentuGetIdentResponse(unsigned int uiNodeId_p,
+				     tEplIdentResponse **ppIdentResponse_p);
 
-tEplKernel PUBLIC EplIdentuGetIdentResponse(unsigned int uiNodeId_p,
-					    tEplIdentResponse **
-					    ppIdentResponse_p);
-
-tEplKernel PUBLIC EplIdentuRequestIdentResponse(unsigned int uiNodeId_p,
-						tEplIdentuCbResponse
-						pfnCbResponse_p);
+tEplKernel EplIdentuRequestIdentResponse(unsigned int uiNodeId_p,
+					 tEplIdentuCbResponse pfnCbResponse_p);
 
 #endif // #ifndef _EPLIDENTU_H_
diff --git a/drivers/staging/epl/user/EplLedu.h b/drivers/staging/epl/user/EplLedu.h
index 78e70d0..ca9eb43 100644
--- a/drivers/staging/epl/user/EplLedu.h
+++ b/drivers/staging/epl/user/EplLedu.h
@@ -68,41 +68,27 @@
 
 ****************************************************************************/
 
+#ifndef _EPLLEDU_H_
+#define _EPLLEDU_H_
+
 #include "../EplLed.h"
 #include "../EplNmt.h"
 #include "EplEventu.h"
 
-#ifndef _EPLLEDU_H_
-#define _EPLLEDU_H_
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-typedef tEplKernel(PUBLIC * tEplLeduStateChangeCallback) (tEplLedType LedType_p,
+typedef tEplKernel(* tEplLeduStateChangeCallback) (tEplLedType LedType_p,
 							  BOOL fOn_p);
 
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
 
-tEplKernel PUBLIC EplLeduInit(tEplLeduStateChangeCallback pfnCbStateChange_p);
+tEplKernel EplLeduInit(tEplLeduStateChangeCallback pfnCbStateChange_p);
 
-tEplKernel PUBLIC EplLeduAddInstance(tEplLeduStateChangeCallback
-				     pfnCbStateChange_p);
+tEplKernel EplLeduAddInstance(tEplLeduStateChangeCallback pfnCbStateChange_p);
 
-tEplKernel PUBLIC EplLeduDelInstance(void);
+tEplKernel EplLeduDelInstance(void);
 
-tEplKernel PUBLIC EplLeduCbNmtStateChange(tEplEventNmtStateChange
-					  NmtStateChange_p);
+tEplKernel EplLeduCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p);
 
-tEplKernel PUBLIC EplLeduProcessEvent(tEplEvent * pEplEvent_p);
+tEplKernel EplLeduProcessEvent(tEplEvent * pEplEvent_p);
 
 #endif // #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
 
diff --git a/drivers/staging/epl/user/EplNmtCnu.h b/drivers/staging/epl/user/EplNmtCnu.h
index e508055..7d23029 100644
--- a/drivers/staging/epl/user/EplNmtCnu.h
+++ b/drivers/staging/epl/user/EplNmtCnu.h
@@ -68,40 +68,24 @@
 
 ****************************************************************************/
 
+#ifndef _EPLNMTCNU_H_
+#define _EPLNMTCNU_H_
+
 #include "EplNmtu.h"
 #include "../EplDll.h"
 #include "../EplFrame.h"
 
-#ifndef _EPLNMTCNU_H_
-#define _EPLNMTCNU_H_
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
 
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuInit(unsigned int uiNodeId_p);
+tEplKernel EplNmtCnuInit(unsigned int uiNodeId_p);
 
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuAddInstance(unsigned int uiNodeId_p);
+tEplKernel EplNmtCnuAddInstance(unsigned int uiNodeId_p);
 
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuDelInstance(void);
+tEplKernel EplNmtCnuDelInstance(void);
 
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuSendNmtRequest(unsigned int uiNodeId_p,
-						       tEplNmtCommand
-						       NmtCommand_p);
+tEplKernel EplNmtCnuSendNmtRequest(unsigned int uiNodeId_p, tEplNmtCommand NmtCommand_p);
 
-EPLDLLEXPORT tEplKernel PUBLIC
-EplNmtCnuRegisterCheckEventCb(tEplNmtuCheckEventCallback
-			      pfnEplNmtCheckEventCb_p);
+tEplKernel EplNmtCnuRegisterCheckEventCb(tEplNmtuCheckEventCallback pfnEplNmtCheckEventCb_p);
 
 #endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
 
diff --git a/drivers/staging/epl/user/EplNmtMnu.h b/drivers/staging/epl/user/EplNmtMnu.h
index c54efeb..5e5e0cd 100644
--- a/drivers/staging/epl/user/EplNmtMnu.h
+++ b/drivers/staging/epl/user/EplNmtMnu.h
@@ -68,34 +68,20 @@
 
 ****************************************************************************/
 
-#include "EplNmtu.h"
-
 #ifndef _EPLNMTMNU_H_
 #define _EPLNMTMNU_H_
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
+#include "EplNmtu.h"
 
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
+typedef tEplKernel(* tEplNmtMnuCbNodeEvent) (unsigned int uiNodeId_p,
+					     tEplNmtNodeEvent NodeEvent_p,
+					     tEplNmtState NmtState_p,
+					     u16 wErrorCode_p,
+					     BOOL fMandatory_p);
 
-typedef tEplKernel(PUBLIC * tEplNmtMnuCbNodeEvent) (unsigned int uiNodeId_p,
-						    tEplNmtNodeEvent
-						    NodeEvent_p,
-						    tEplNmtState NmtState_p,
-						    WORD wErrorCode_p,
-						    BOOL fMandatory_p);
-
-typedef tEplKernel(PUBLIC *
-		   tEplNmtMnuCbBootEvent) (tEplNmtBootEvent BootEvent_p,
-					   tEplNmtState NmtState_p,
-					   WORD wErrorCode_p);
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+typedef tEplKernel(* tEplNmtMnuCbBootEvent) (tEplNmtBootEvent BootEvent_p,
+					     tEplNmtState NmtState_p,
+					     u16 wErrorCode_p);
 
 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
 
@@ -107,7 +93,7 @@
 
 tEplKernel EplNmtMnuDelInstance(void);
 
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtMnuProcessEvent(tEplEvent * pEvent_p);
+tEplKernel EplNmtMnuProcessEvent(tEplEvent *pEvent_p);
 
 tEplKernel EplNmtMnuSendNmtCommand(unsigned int uiNodeId_p,
 				   tEplNmtCommand NmtCommand_p);
@@ -115,16 +101,16 @@
 tEplKernel EplNmtMnuTriggerStateChange(unsigned int uiNodeId_p,
 				       tEplNmtNodeCommand NodeCommand_p);
 
-tEplKernel PUBLIC EplNmtMnuCbNmtStateChange(tEplEventNmtStateChange
+tEplKernel EplNmtMnuCbNmtStateChange(tEplEventNmtStateChange
 					    NmtStateChange_p);
 
-tEplKernel PUBLIC EplNmtMnuCbCheckEvent(tEplNmtEvent NmtEvent_p);
+tEplKernel EplNmtMnuCbCheckEvent(tEplNmtEvent NmtEvent_p);
 
-tEplKernel PUBLIC EplNmtMnuGetDiagnosticInfo(unsigned int
+tEplKernel EplNmtMnuGetDiagnosticInfo(unsigned int
 					     *puiMandatorySlaveCount_p,
 					     unsigned int
 					     *puiSignalSlaveCount_p,
-					     WORD * pwFlags_p);
+					     u16 * pwFlags_p);
 
 #endif
 
diff --git a/drivers/staging/epl/user/EplNmtu.h b/drivers/staging/epl/user/EplNmtu.h
index 5a56c58..c1fca80 100644
--- a/drivers/staging/epl/user/EplNmtu.h
+++ b/drivers/staging/epl/user/EplNmtu.h
@@ -68,19 +68,12 @@
 
 ****************************************************************************/
 
-#include "../EplNmt.h"
-#include "EplEventu.h"
-
 #ifndef _EPLNMTU_H_
 #define _EPLNMTU_H_
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
+#include "../EplNmt.h"
+#include "EplEventu.h"
 
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
 // nmt commands
 typedef enum {
 	// requestable ASnd ServiceIds    0x01..0x1F
@@ -121,34 +114,25 @@
 	kEplNmtCmdInvalidService = 0xFF
 } tEplNmtCommand;
 
-typedef tEplKernel(PUBLIC *
-		   tEplNmtuStateChangeCallback) (tEplEventNmtStateChange
-						 NmtStateChange_p);
+typedef tEplKernel(* tEplNmtuStateChangeCallback) (tEplEventNmtStateChange NmtStateChange_p);
 
-typedef tEplKernel(PUBLIC *
-		   tEplNmtuCheckEventCallback) (tEplNmtEvent NmtEvent_p);
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+typedef tEplKernel(* tEplNmtuCheckEventCallback) (tEplNmtEvent NmtEvent_p);
 
 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
 
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuInit(void);
+tEplKernel EplNmtuInit(void);
 
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuAddInstance(void);
+tEplKernel EplNmtuAddInstance(void);
 
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuDelInstance(void);
+tEplKernel EplNmtuDelInstance(void);
 
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuNmtEvent(tEplNmtEvent NmtEvent_p);
+tEplKernel EplNmtuNmtEvent(tEplNmtEvent NmtEvent_p);
 
-EPLDLLEXPORT tEplNmtState PUBLIC EplNmtuGetNmtState(void);
+tEplNmtState EplNmtuGetNmtState(void);
 
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuProcessEvent(tEplEvent * pEplEvent_p);
+tEplKernel EplNmtuProcessEvent(tEplEvent *pEplEvent_p);
 
-EPLDLLEXPORT tEplKernel PUBLIC
-EplNmtuRegisterStateChangeCb(tEplNmtuStateChangeCallback
-			     pfnEplNmtStateChangeCb_p);
+tEplKernel EplNmtuRegisterStateChangeCb(tEplNmtuStateChangeCallback pfnEplNmtStateChangeCb_p);
 
 #endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
 
diff --git a/drivers/staging/epl/user/EplNmtuCal.h b/drivers/staging/epl/user/EplNmtuCal.h
index c881582..b985037 100644
--- a/drivers/staging/epl/user/EplNmtuCal.h
+++ b/drivers/staging/epl/user/EplNmtuCal.h
@@ -69,23 +69,12 @@
 
 ****************************************************************************/
 
-#include "EplNmtu.h"
-#include "../kernel/EplNmtk.h"
-
 #ifndef _EPLNMTUCAL_H_
 #define _EPLNMTUCAL_H_
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
+#include "EplNmtu.h"
+#include "../kernel/EplNmtk.h"
 
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplNmtState PUBLIC EplNmtkCalGetNmtState(void);
+tEplNmtState EplNmtkCalGetNmtState(void);
 
 #endif // #ifndef _EPLNMTUCAL_H_
diff --git a/drivers/staging/epl/user/EplObdu.h b/drivers/staging/epl/user/EplObdu.h
index bc1e173..0863712 100644
--- a/drivers/staging/epl/user/EplObdu.h
+++ b/drivers/staging/epl/user/EplObdu.h
@@ -68,22 +68,10 @@
 
 ****************************************************************************/
 
-#include "../EplObd.h"
-
 #ifndef _EPLOBDU_H_
 #define _EPLOBDU_H_
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+#include "../EplObd.h"
 
 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
 
@@ -91,68 +79,57 @@
 #error "EPL OBDu module enabled, but OBD_USE_KERNEL == TRUE"
 #endif
 
-EPLDLLEXPORT tEplKernel PUBLIC EplObduWriteEntry(unsigned int uiIndex_p,
-						 unsigned int uiSubIndex_p,
-						 void *pSrcData_p,
-						 tEplObdSize Size_p);
+tEplKernel EplObduWriteEntry(unsigned int uiIndex_p, unsigned int uiSubIndex_p,
+			     void *pSrcData_p, tEplObdSize Size_p);
 
 // ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduReadEntry(unsigned int uiIndex_p,
-						unsigned int uiSubIndex_p,
-						void *pDstData_p,
-						tEplObdSize * pSize_p);
+tEplKernel EplObduReadEntry(unsigned int uiIndex_p, unsigned int uiSubIndex_p,
+			    void *pDstData_p, tEplObdSize *pSize_p);
 
 // ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduAccessOdPart(tEplObdPart ObdPart_p,
-						   tEplObdDir Direction_p);
+tEplKernel EplObduAccessOdPart(tEplObdPart ObdPart_p, tEplObdDir Direction_p);
 
 // ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduDefineVar(tEplVarParam MEM * pVarParam_p);
+tEplKernel EplObduDefineVar(tEplVarParam *pVarParam_p);
 
 // ---------------------------------------------------------------------
-EPLDLLEXPORT void *PUBLIC EplObduGetObjectDataPtr(unsigned int uiIndex_p,
-						  unsigned int uiSubIndex_p);
-// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduRegisterUserOd(tEplObdEntryPtr pUserOd_p);
+void *EplObduGetObjectDataPtr(unsigned int uiIndex_p, unsigned int uiSubIndex_p);
 
 // ---------------------------------------------------------------------
-EPLDLLEXPORT void PUBLIC EplObduInitVarEntry(tEplObdVarEntry MEM * pVarEntry_p,
-					     BYTE bType_p,
-					     tEplObdSize ObdSize_p);
+tEplKernel EplObduRegisterUserOd(tEplObdEntryPtr pUserOd_p);
 
 // ---------------------------------------------------------------------
-EPLDLLEXPORT tEplObdSize PUBLIC EplObduGetDataSize(unsigned int uiIndex_p,
-						   unsigned int uiSubIndex_p);
+void EplObduInitVarEntry(tEplObdVarEntry *pVarEntry_p, u8 bType_p,
+			 tEplObdSize ObdSize_p);
 
 // ---------------------------------------------------------------------
-EPLDLLEXPORT unsigned int PUBLIC EplObduGetNodeId(void);
+tEplObdSize EplObduGetDataSize(unsigned int uiIndex_p,
+			       unsigned int uiSubIndex_p);
 
 // ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduSetNodeId(unsigned int uiNodeId_p,
-						tEplObdNodeIdType NodeIdType_p);
-// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduGetAccessType(unsigned int uiIndex_p,
-						    unsigned int uiSubIndex_p,
-						    tEplObdAccess *
-						    pAccessTyp_p);
-// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduReadEntryToLe(unsigned int uiIndex_p,
-						    unsigned int uiSubIndex_p,
-						    void *pDstData_p,
-						    tEplObdSize * pSize_p);
-// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduWriteEntryFromLe(unsigned int uiIndex_p,
-						       unsigned int
-						       uiSubIndex_p,
-						       void *pSrcData_p,
-						       tEplObdSize Size_p);
+unsigned int EplObduGetNodeId(void);
 
 // ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_
-						     unsigned int uiIndex_p,
-						     unsigned int uiSubindex_p,
-						     tEplObdVarEntry MEM **
-						     ppVarEntry_p);
+tEplKernel EplObduSetNodeId(unsigned int uiNodeId_p,
+			    tEplObdNodeIdType NodeIdType_p);
+
+// ---------------------------------------------------------------------
+tEplKernel EplObduGetAccessType(unsigned int uiIndex_p,
+				unsigned int uiSubIndex_p,
+				tEplObdAccess *pAccessTyp_p);
+// ---------------------------------------------------------------------
+tEplKernel EplObduReadEntryToLe(unsigned int uiIndex_p,
+				unsigned int uiSubIndex_p,
+				void *pDstData_p, tEplObdSize *pSize_p);
+// ---------------------------------------------------------------------
+tEplKernel EplObduWriteEntryFromLe(unsigned int uiIndex_p,
+				   unsigned int uiSubIndex_p,
+				   void *pSrcData_p, tEplObdSize Size_p);
+
+// ---------------------------------------------------------------------
+tEplKernel EplObduSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+				 unsigned int uiSubindex_p,
+				 tEplObdVarEntry **ppVarEntry_p);
 
 #elif EPL_OBD_USE_KERNEL != FALSE
 #include "../kernel/EplObdk.h"
diff --git a/drivers/staging/epl/user/EplObduCal.h b/drivers/staging/epl/user/EplObduCal.h
index 498e011..0727777 100644
--- a/drivers/staging/epl/user/EplObduCal.h
+++ b/drivers/staging/epl/user/EplObduCal.h
@@ -69,80 +69,58 @@
 
 ****************************************************************************/
 
-#include "../EplObd.h"
-
 #ifndef _EPLOBDUCAL_H_
 #define _EPLOBDUCAL_H_
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
+#include "../EplObd.h"
 
+tEplKernel EplObduCalWriteEntry(unsigned int uiIndex_p,
+				unsigned int uiSubIndex_p,
+				void *pSrcData_p,
+				tEplObdSize Size_p);
 //---------------------------------------------------------------------------
-// typedef
+tEplKernel EplObduCalReadEntry(unsigned int uiIndex_p,
+			       unsigned int uiSubIndex_p,
+			       void *pDstData_p,
+			       tEplObdSize *pSize_p);
 //---------------------------------------------------------------------------
-
+tEplKernel EplObduCalAccessOdPart(tEplObdPart ObdPart_p,
+				  tEplObdDir Direction_p);
 //---------------------------------------------------------------------------
-// function prototypes
+tEplKernel EplObduCalDefineVar(tEplVarParam *pVarParam_p);
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalWriteEntry(unsigned int uiIndex_p,
-						    unsigned int uiSubIndex_p,
-						    void *pSrcData_p,
-						    tEplObdSize Size_p);
+void *EplObduCalGetObjectDataPtr(unsigned int uiIndex_p,
+				 unsigned int uiSubIndex_p);
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalReadEntry(unsigned int uiIndex_p,
-						   unsigned int uiSubIndex_p,
-						   void *pDstData_p,
-						   tEplObdSize * pSize_p);
+tEplKernel EplObduCalRegisterUserOd(tEplObdEntryPtr pUserOd_p);
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalAccessOdPart(tEplObdPart ObdPart_p,
-						      tEplObdDir Direction_p);
+void EplObduCalInitVarEntry(tEplObdVarEntry *pVarEntry_p,
+			    u8 bType_p, tEplObdSize ObdSize_p);
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalDefineVar(tEplVarParam MEM *
-						   pVarParam_p);
+tEplObdSize EplObduCalGetDataSize(unsigned int uiIndex_p,
+				  unsigned int uiSubIndex_p);
 //---------------------------------------------------------------------------
-EPLDLLEXPORT void *PUBLIC EplObduCalGetObjectDataPtr(unsigned int uiIndex_p,
-						     unsigned int uiSubIndex_p);
+unsigned int EplObduCalGetNodeId(void);
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalRegisterUserOd(tEplObdEntryPtr
-							pUserOd_p);
+tEplKernel EplObduCalSetNodeId(unsigned int uiNodeId_p,
+			       tEplObdNodeIdType NodeIdType_p);
 //---------------------------------------------------------------------------
-EPLDLLEXPORT void PUBLIC EplObduCalInitVarEntry(tEplObdVarEntry MEM *
-						pVarEntry_p, BYTE bType_p,
-						tEplObdSize ObdSize_p);
+tEplKernel EplObduCalGetAccessType(unsigned int uiIndex_p,
+				   unsigned int uiSubIndex_p,
+				   tEplObdAccess *pAccessTyp_p);
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplObdSize PUBLIC EplObduCalGetDataSize(unsigned int uiIndex_p,
-						      unsigned int
-						      uiSubIndex_p);
+tEplKernel EplObduCalReadEntryToLe(unsigned int uiIndex_p,
+				   unsigned int uiSubIndex_p,
+				   void *pDstData_p,
+				   tEplObdSize *pSize_p);
 //---------------------------------------------------------------------------
-EPLDLLEXPORT unsigned int PUBLIC EplObduCalGetNodeId(void);
+tEplKernel EplObduCalWriteEntryFromLe(unsigned int uiIndex_p,
+				      unsigned int uiSubIndex_p,
+				      void *pSrcData_p,
+				      tEplObdSize Size_p);
 //---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalSetNodeId(unsigned int uiNodeId_p,
-						   tEplObdNodeIdType
-						   NodeIdType_p);
-//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalGetAccessType(unsigned int uiIndex_p,
-						       unsigned int
-						       uiSubIndex_p,
-						       tEplObdAccess *
-						       pAccessTyp_p);
-//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalReadEntryToLe(unsigned int uiIndex_p,
-						       unsigned int
-						       uiSubIndex_p,
-						       void *pDstData_p,
-						       tEplObdSize * pSize_p);
-//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalWriteEntryFromLe(unsigned int
-							  uiIndex_p,
-							  unsigned int
-							  uiSubIndex_p,
-							  void *pSrcData_p,
-							  tEplObdSize Size_p);
-//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC
-EplObduCalSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
-			 unsigned int uiSubindex_p,
-			 tEplObdVarEntry MEM ** ppVarEntry_p);
+tEplKernel EplObduCalSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+				    unsigned int uiSubindex_p,
+				    tEplObdVarEntry **ppVarEntry_p);
 
 #endif // #ifndef _EPLOBDUCAL_H_
diff --git a/drivers/staging/epl/user/EplPdou.h b/drivers/staging/epl/user/EplPdou.h
index 11de486..b8c832b 100644
--- a/drivers/staging/epl/user/EplPdou.h
+++ b/drivers/staging/epl/user/EplPdou.h
@@ -72,24 +72,12 @@
 
 #include "../EplPdo.h"
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
 tEplKernel EplPdouAddInstance(void);
 
 tEplKernel EplPdouDelInstance(void);
 
 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOU)) != 0)
-tEplKernel PUBLIC EplPdouCbObdAccess(tEplObdCbParam MEM * pParam_p);
+tEplKernel EplPdouCbObdAccess(tEplObdCbParam *pParam_p);
 #else
 #define EplPdouCbObdAccess		NULL
 #endif
@@ -97,12 +85,12 @@
 // returns error if bPdoId_p is already valid
 /*
 tEplKernel EplPdouSetMapping(
-    BYTE bPdoId_p, BOOL fTxRx_p, BYTE bNodeId, BYTE bMappingVersion,
-    tEplPdoMapping * pMapping_p, BYTE bMaxEntries_p);
+    u8 bPdoId_p, BOOL fTxRx_p, u8 bNodeId, u8 bMappingVersion,
+    tEplPdoMapping * pMapping_p, u8 bMaxEntries_p);
 
 tEplKernel EplPdouGetMapping(
-    BYTE bPdoId_p, BOOL fTxRx_p, BYTE * pbNodeId, BYTE * pbMappingVersion,
-    tEplPdoMapping * pMapping_p, BYTE * pbMaxEntries_p);
+    u8 bPdoId_p, BOOL fTxRx_p, u8 * pbNodeId, u8 * pbMappingVersion,
+    tEplPdoMapping * pMapping_p, u8 * pbMaxEntries_p);
 */
 
 #endif // #ifndef _EPL_PDOU_H_
diff --git a/drivers/staging/epl/user/EplSdoAsndu.h b/drivers/staging/epl/user/EplSdoAsndu.h
index e34959f..a62d4c9 100644
--- a/drivers/staging/epl/user/EplSdoAsndu.h
+++ b/drivers/staging/epl/user/EplSdoAsndu.h
@@ -68,39 +68,28 @@
 
 ****************************************************************************/
 
-#include "../EplSdo.h"
-#include "../EplDll.h"
-
 #ifndef _EPLSDOASNDU_H_
 #define _EPLSDOASNDU_H_
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
+#include "../EplSdo.h"
+#include "../EplDll.h"
 
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
 
-tEplKernel PUBLIC EplSdoAsnduInit(tEplSequLayerReceiveCb fpReceiveCb_p);
+tEplKernel EplSdoAsnduInit(tEplSequLayerReceiveCb fpReceiveCb_p);
 
-tEplKernel PUBLIC EplSdoAsnduAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p);
+tEplKernel EplSdoAsnduAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p);
 
-tEplKernel PUBLIC EplSdoAsnduDelInstance(void);
+tEplKernel EplSdoAsnduDelInstance(void);
 
-tEplKernel PUBLIC EplSdoAsnduInitCon(tEplSdoConHdl * pSdoConHandle_p,
-				     unsigned int uiTargetNodeId_p);
+tEplKernel EplSdoAsnduInitCon(tEplSdoConHdl *pSdoConHandle_p,
+			      unsigned int uiTargetNodeId_p);
 
-tEplKernel PUBLIC EplSdoAsnduSendData(tEplSdoConHdl SdoConHandle_p,
-				      tEplFrame * pSrcData_p,
-				      DWORD dwDataSize_p);
+tEplKernel EplSdoAsnduSendData(tEplSdoConHdl SdoConHandle_p,
+			       tEplFrame *pSrcData_p,
+			       u32 dwDataSize_p);
 
-tEplKernel PUBLIC EplSdoAsnduDelCon(tEplSdoConHdl SdoConHandle_p);
+tEplKernel EplSdoAsnduDelCon(tEplSdoConHdl SdoConHandle_p);
 
 #endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
 
diff --git a/drivers/staging/epl/user/EplSdoAsySequ.h b/drivers/staging/epl/user/EplSdoAsySequ.h
index 4658b5f..cc862de 100644
--- a/drivers/staging/epl/user/EplSdoAsySequ.h
+++ b/drivers/staging/epl/user/EplSdoAsySequ.h
@@ -68,44 +68,33 @@
 
 ****************************************************************************/
 
+#ifndef _EPLSDOASYSEQU_H_
+#define _EPLSDOASYSEQU_H_
+
 #include "../EplSdo.h"
 #include "EplSdoUdpu.h"
 #include "EplSdoAsndu.h"
 #include "../EplEvent.h"
 #include "EplTimeru.h"
 
-#ifndef _EPLSDOASYSEQU_H_
-#define _EPLSDOASYSEQU_H_
+tEplKernel EplSdoAsySeqInit(tEplSdoComReceiveCb fpSdoComCb_p,
+			    tEplSdoComConCb fpSdoComConCb_p);
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsySeqInit(tEplSdoComReceiveCb fpSdoComCb_p,
+tEplKernel EplSdoAsySeqAddInstance(tEplSdoComReceiveCb fpSdoComCb_p,
 				   tEplSdoComConCb fpSdoComConCb_p);
 
-tEplKernel PUBLIC EplSdoAsySeqAddInstance(tEplSdoComReceiveCb fpSdoComCb_p,
-					  tEplSdoComConCb fpSdoComConCb_p);
+tEplKernel EplSdoAsySeqDelInstance(void);
 
-tEplKernel PUBLIC EplSdoAsySeqDelInstance(void);
+tEplKernel EplSdoAsySeqInitCon(tEplSdoSeqConHdl *pSdoSeqConHdl_p,
+			       unsigned int uiNodeId_p,
+			       tEplSdoType SdoType);
 
-tEplKernel PUBLIC EplSdoAsySeqInitCon(tEplSdoSeqConHdl * pSdoSeqConHdl_p,
-				      unsigned int uiNodeId_p,
-				      tEplSdoType SdoType);
+tEplKernel EplSdoAsySeqSendData(tEplSdoSeqConHdl SdoSeqConHdl_p,
+				unsigned int uiDataSize_p,
+				tEplFrame *pData_p);
 
-tEplKernel PUBLIC EplSdoAsySeqSendData(tEplSdoSeqConHdl SdoSeqConHdl_p,
-				       unsigned int uiDataSize_p,
-				       tEplFrame * pData_p);
+tEplKernel EplSdoAsySeqProcessEvent(tEplEvent *pEvent_p);
 
-tEplKernel PUBLIC EplSdoAsySeqProcessEvent(tEplEvent * pEvent_p);
-
-tEplKernel PUBLIC EplSdoAsySeqDelCon(tEplSdoSeqConHdl SdoSeqConHdl_p);
+tEplKernel EplSdoAsySeqDelCon(tEplSdoSeqConHdl SdoSeqConHdl_p);
 
 #endif // #ifndef _EPLSDOASYSEQU_H_
diff --git a/drivers/staging/epl/user/EplSdoComu.h b/drivers/staging/epl/user/EplSdoComu.h
index 3e454c7..4eee6fa 100644
--- a/drivers/staging/epl/user/EplSdoComu.h
+++ b/drivers/staging/epl/user/EplSdoComu.h
@@ -68,58 +68,46 @@
 
 ****************************************************************************/
 
+#ifndef _EPLSDOCOMU_H_
+#define _EPLSDOCOMU_H_
+
 #include "../EplSdo.h"
 #include "../EplObd.h"
 #include "../EplSdoAc.h"
 #include "EplObdu.h"
 #include "EplSdoAsySequ.h"
 
-#ifndef _EPLSDOCOMU_H_
-#define _EPLSDOCOMU_H_
+tEplKernel EplSdoComInit(void);
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
+tEplKernel EplSdoComAddInstance(void);
 
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoComInit(void);
-
-tEplKernel PUBLIC EplSdoComAddInstance(void);
-
-tEplKernel PUBLIC EplSdoComDelInstance(void);
+tEplKernel EplSdoComDelInstance(void);
 
 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
 
-tEplKernel PUBLIC EplSdoComDefineCon(tEplSdoComConHdl * pSdoComConHdl_p,
-				     unsigned int uiTargetNodeId_p,
-				     tEplSdoType ProtType_p);
+tEplKernel EplSdoComDefineCon(tEplSdoComConHdl *pSdoComConHdl_p,
+			      unsigned int uiTargetNodeId_p,
+			      tEplSdoType ProtType_p);
 
-tEplKernel PUBLIC EplSdoComInitTransferByIndex(tEplSdoComTransParamByIndex *
-					       pSdoComTransParam_p);
+tEplKernel EplSdoComInitTransferByIndex(tEplSdoComTransParamByIndex *pSdoComTransParam_p);
 
-tEplKernel PUBLIC EplSdoComUndefineCon(tEplSdoComConHdl SdoComConHdl_p);
+tEplKernel EplSdoComUndefineCon(tEplSdoComConHdl SdoComConHdl_p);
 
-tEplKernel PUBLIC EplSdoComGetState(tEplSdoComConHdl SdoComConHdl_p,
-				    tEplSdoComFinished * pSdoComFinished_p);
+tEplKernel EplSdoComGetState(tEplSdoComConHdl SdoComConHdl_p,
+			     tEplSdoComFinished *pSdoComFinished_p);
 
-tEplKernel PUBLIC EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p,
-				    DWORD dwAbortCode_p);
+tEplKernel EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p,
+			     u32 dwAbortCode_p);
 
 #endif
 
 // for future extention
 /*
-tEplKernel PUBLIC EplSdoComInitTransferAllByIndex(tEplSdoComTransParamAllByIndex* pSdoComTransParam_p);
+tEplKernel EplSdoComInitTransferAllByIndex(tEplSdoComTransParamAllByIndex* pSdoComTransParam_p);
 
-tEplKernel PUBLIC EplSdoComInitTransferByName(tEplSdoComTransParamByName* pSdoComTransParam_p);
+tEplKernel EplSdoComInitTransferByName(tEplSdoComTransParamByName* pSdoComTransParam_p);
 
-tEplKernel PUBLIC EplSdoComInitTransferFile(tEplSdoComTransParamFile* pSdoComTransParam_p);
+tEplKernel EplSdoComInitTransferFile(tEplSdoComTransParamFile* pSdoComTransParam_p);
 
 */
 
diff --git a/drivers/staging/epl/user/EplSdoUdpu.h b/drivers/staging/epl/user/EplSdoUdpu.h
index 2d77b6f..13e2a27 100644
--- a/drivers/staging/epl/user/EplSdoUdpu.h
+++ b/drivers/staging/epl/user/EplSdoUdpu.h
@@ -68,41 +68,29 @@
 
 ****************************************************************************/
 
-#include "../EplSdo.h"
-
 #ifndef _EPLSDOUDPU_H_
 #define _EPLSDOUDPU_H_
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
+#include "../EplSdo.h"
 
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
 
-tEplKernel PUBLIC EplSdoUdpuInit(tEplSequLayerReceiveCb fpReceiveCb_p);
+tEplKernel EplSdoUdpuInit(tEplSequLayerReceiveCb fpReceiveCb_p);
 
-tEplKernel PUBLIC EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p);
+tEplKernel EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p);
 
-tEplKernel PUBLIC EplSdoUdpuDelInstance(void);
+tEplKernel EplSdoUdpuDelInstance(void);
 
-tEplKernel PUBLIC EplSdoUdpuConfig(unsigned long ulIpAddr_p,
-				   unsigned int uiPort_p);
+tEplKernel EplSdoUdpuConfig(unsigned long ulIpAddr_p,
+			    unsigned int uiPort_p);
 
-tEplKernel PUBLIC EplSdoUdpuInitCon(tEplSdoConHdl * pSdoConHandle_p,
-				    unsigned int uiTargetNodeId_p);
+tEplKernel EplSdoUdpuInitCon(tEplSdoConHdl *pSdoConHandle_p,
+			     unsigned int uiTargetNodeId_p);
 
-tEplKernel PUBLIC EplSdoUdpuSendData(tEplSdoConHdl SdoConHandle_p,
-				     tEplFrame * pSrcData_p,
-				     DWORD dwDataSize_p);
+tEplKernel EplSdoUdpuSendData(tEplSdoConHdl SdoConHandle_p,
+			      tEplFrame *pSrcData_p, u32 dwDataSize_p);
 
-tEplKernel PUBLIC EplSdoUdpuDelCon(tEplSdoConHdl SdoConHandle_p);
+tEplKernel EplSdoUdpuDelCon(tEplSdoConHdl SdoConHandle_p);
 
 #endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
 
diff --git a/drivers/staging/epl/user/EplStatusu.h b/drivers/staging/epl/user/EplStatusu.h
index d211935..0fd3ebb 100644
--- a/drivers/staging/epl/user/EplStatusu.h
+++ b/drivers/staging/epl/user/EplStatusu.h
@@ -68,37 +68,23 @@
 
 ****************************************************************************/
 
-#include "../EplDll.h"
-
 #ifndef _EPLSTATUSU_H_
 #define _EPLSTATUSU_H_
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
+#include "../EplDll.h"
 
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
+typedef tEplKernel(* tEplStatusuCbResponse) (unsigned int uiNodeId_p,
+					     tEplStatusResponse *pStatusResponse_p);
 
-typedef tEplKernel(PUBLIC * tEplStatusuCbResponse) (unsigned int uiNodeId_p,
-						    tEplStatusResponse *
-						    pStatusResponse_p);
+tEplKernel EplStatusuInit(void);
 
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+tEplKernel EplStatusuAddInstance(void);
 
-tEplKernel PUBLIC EplStatusuInit(void);
+tEplKernel EplStatusuDelInstance(void);
 
-tEplKernel PUBLIC EplStatusuAddInstance(void);
+tEplKernel EplStatusuReset(void);
 
-tEplKernel PUBLIC EplStatusuDelInstance(void);
-
-tEplKernel PUBLIC EplStatusuReset(void);
-
-tEplKernel PUBLIC EplStatusuRequestStatusResponse(unsigned int uiNodeId_p,
-						  tEplStatusuCbResponse
-						  pfnCbResponse_p);
+tEplKernel EplStatusuRequestStatusResponse(unsigned int uiNodeId_p,
+					   tEplStatusuCbResponse pfnCbResponse_p);
 
 #endif // #ifndef _EPLSTATUSU_H_
diff --git a/drivers/staging/epl/user/EplTimeru.h b/drivers/staging/epl/user/EplTimeru.h
index 4044955..5c44748 100644
--- a/drivers/staging/epl/user/EplTimeru.h
+++ b/drivers/staging/epl/user/EplTimeru.h
@@ -68,40 +68,28 @@
 
 ****************************************************************************/
 
-#include "../EplTimer.h"
-#include "EplEventu.h"
-
 #ifndef _EPLTIMERU_H_
 #define _EPLTIMERU_H_
 
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
+#include "../EplTimer.h"
+#include "EplEventu.h"
 
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
+tEplKernel EplTimeruInit(void);
 
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+tEplKernel EplTimeruAddInstance(void);
 
-tEplKernel PUBLIC EplTimeruInit(void);
+tEplKernel EplTimeruDelInstance(void);
 
-tEplKernel PUBLIC EplTimeruAddInstance(void);
+tEplKernel EplTimeruSetTimerMs(tEplTimerHdl *pTimerHdl_p,
+			       unsigned long ulTime_p,
+			       tEplTimerArg Argument_p);
 
-tEplKernel PUBLIC EplTimeruDelInstance(void);
+tEplKernel EplTimeruModifyTimerMs(tEplTimerHdl *pTimerHdl_p,
+				  unsigned long ulTime_p,
+				  tEplTimerArg Argument_p);
 
-tEplKernel PUBLIC EplTimeruSetTimerMs(tEplTimerHdl * pTimerHdl_p,
-				      unsigned long ulTime_p,
-				      tEplTimerArg Argument_p);
+tEplKernel EplTimeruDeleteTimer(tEplTimerHdl *pTimerHdl_p);
 
-tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl * pTimerHdl_p,
-					 unsigned long ulTime_p,
-					 tEplTimerArg Argument_p);
-
-tEplKernel PUBLIC EplTimeruDeleteTimer(tEplTimerHdl * pTimerHdl_p);
-
-BOOL PUBLIC EplTimeruIsTimerActive(tEplTimerHdl TimerHdl_p);
+BOOL EplTimeruIsTimerActive(tEplTimerHdl TimerHdl_p);
 
 #endif // #ifndef _EPLTIMERU_H_
diff --git a/drivers/staging/et131x/et1310_rx.c b/drivers/staging/et131x/et1310_rx.c
index ec98da5..8dc559a 100644
--- a/drivers/staging/et131x/et1310_rx.c
+++ b/drivers/staging/et131x/et1310_rx.c
@@ -1203,8 +1203,7 @@
 
 		pMpRfd = (PMP_RFD) list_entry(element, MP_RFD, list_node);
 
-		list_del(&pMpRfd->list_node);
-		list_add_tail(&pMpRfd->list_node, &pAdapter->RxRing.RecvList);
+		list_move_tail(&pMpRfd->list_node, &pAdapter->RxRing.RecvList);
 	}
 
 	DBG_LEAVE(et131x_dbginfo);
diff --git a/drivers/staging/frontier/README b/drivers/staging/frontier/README
index 07c9ef9..cd07af2 100644
--- a/drivers/staging/frontier/README
+++ b/drivers/staging/frontier/README
@@ -1,28 +1,47 @@
-This directory contains the USB Tranzport and Alphatrack Kernel drivers for Linux.
+This directory contains the Linux USB Tranzport and Alphatrack Kernel drivers.
 
-At present the tranzport does reads/writes of 8 byte cmds to /dev/tranzport0 to control
-the lights and screen and wheel
+See http://www.frontierdesign.com for details on these devices.
 
-At present the alphatrack accepts reads/writes of 12 byte cmds to /dev/tranzport0 to control
-the lights and screen and fader.
+Userspace test code is available from
 
-Both drivers also have some sysfs hooks that are non-functional at the moment.
+git://toutatis.isc.org/home/d/src/git/frontier.git
 
-The API is currently closely tied to the ardour revision and WILL change.
+At present the tranzport does reads/writes of 8 byte cmds to
+/dev/tranzport0 to control the lights, screen, and wheel.
 
-A sysfs interface is PERFECT for simple userspace apps to do fun things with the
-lights and screen. It's fairly lousy for handling input events and very lousy
-for watching the state of the shuttle wheel.
+At present the alphatrack accepts reads/writes of 12 byte cmds to
+/dev/tranzport0 to control the lights, screen, fader and touchpad.
 
-A linux input events interface is great for the input events and shuttle wheel. It's
-theoretically OK on LEDs. A Fader can be mapped to an absolute mouse device.
-But there is no LCD support at all.
+The tranzport driver provides a rudimentary sysfs interface for the status of
+the device and a writable parameter for turning wheel compression on and off.
 
-In the end this is going to be driven by a midi layer, which handles all those
-cases via a defined API, but - among other things - is slow, doesn't do
-flow control, and is a LOT of extra work. Frankly, I'd like to keep the
+The API is nothing more than the USB commands issued to the device. Why?
+
+The control wheel/fader can generate events far too quickly for
+a typical userspace application to keep up with them via libusb. Input
+needs to be 100% accurate and fast in order for the alphatrack or tranzport
+to be useful.
+
+UIO would be useful except that usb disconnect events need
+to be handled correctly.
+
+A sysfs interface is perfect for simple userspace apps to do fun things with
+the lights and screen. But it's fairly lousy for handling input events and
+very lousy for watching the state of the shuttle wheel.
+
+A linux input events interface is great for the input events and shuttle wheel.
+* It's theoretically OK on LEDs.
+* A fader can be mapped to an absolute mouse device.
+* But there is no LCD support at all, or fader feedback support in that API
+
+So, thus, these stubby drivers exist.
+
+In the end this could be driven by a midi layer, which handles all those
+cases via a well defined API, but - among other things - is slow, doesn't do
+flow control, and is a LOT of extra work, none of which is required at
+the kernel level (probably). Frankly, I'd like to keep the
 core driver simple because the only realtime work really required is
 the bottom half interrupt handler and the output overlapping.
 
-Exposing some sort of clean aio api to userspace would be perfect. What that
+Exposing some sort of clean api to userspace would be perfect. What that
 API looks like? Gah. beats me.
diff --git a/drivers/staging/frontier/alphatrack.c b/drivers/staging/frontier/alphatrack.c
index 6136e3f..bcba17e 100644
--- a/drivers/staging/frontier/alphatrack.c
+++ b/drivers/staging/frontier/alphatrack.c
@@ -41,19 +41,11 @@
 #include <linux/mutex.h>
 #include <linux/version.h>
 
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/input.h>
 #include <linux/usb.h>
 #include <linux/poll.h>
 
-#include "surface_sysfs.h"
-
-/* make this work on older kernel versions */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
-#include "frontier_compat.h"
-#endif /* older kernel versions */
-
 #include "alphatrack.h"
 
 #define VENDOR_ID	0x165b
@@ -62,19 +54,18 @@
 #ifdef CONFIG_USB_DYNAMIC_MINORS
 #define USB_ALPHATRACK_MINOR_BASE	0
 #else
-// FIXME 176 - is another driver's minor - apply for that
-// #define USB_ALPHATRACK_MINOR_BASE	177
+/* FIXME 176 - is another driver's minor - apply for that */
 #define USB_ALPHATRACK_MINOR_BASE	176
 #endif
 
 /* table of devices that work with this driver */
-static struct usb_device_id usb_alphatrack_table [] = {
-	{ USB_DEVICE(VENDOR_ID, PRODUCT_ID) },
-	{ }					/* Terminating entry */
+static struct usb_device_id usb_alphatrack_table[] = {
+	{USB_DEVICE(VENDOR_ID, PRODUCT_ID)},
+	{}			/* Terminating entry */
 };
 
 MODULE_DEVICE_TABLE(usb, usb_alphatrack_table);
-MODULE_VERSION("0.40");
+MODULE_VERSION("0.41");
 MODULE_AUTHOR("Mike Taht <m@taht.net>");
 MODULE_DESCRIPTION("Alphatrack USB Driver");
 MODULE_LICENSE("GPL");
@@ -93,18 +84,18 @@
 #define ALPHATRACK_USB_TIMEOUT 10
 #define OUTPUT_CMD_SIZE 8
 #define INPUT_CMD_SIZE 12
+#define ALPHATRACK_DEBUG 0
 
-
-static int debug = 0;
+static int debug = ALPHATRACK_DEBUG;
 
 /* Use our own dbg macro */
-#define dbg_info(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0)
+#define dbg_info(dev, format, arg...) do \
+    { if (debug) dev_info(dev , format , ## arg); } while (0)
 
 #define alphatrack_ocmd_info(dev, cmd, format, arg...)
 
 #define alphatrack_icmd_info(dev, cmd, format, arg...)
 
-
 /* Module parameters */
 
 module_param(debug, int, S_IRUGO | S_IWUSR);
@@ -116,14 +107,14 @@
 
 static int ring_buffer_size = RING_BUFFER_SIZE;
 
-module_param(ring_buffer_size, int,  S_IRUGO);
+module_param(ring_buffer_size, int, S_IRUGO);
 MODULE_PARM_DESC(ring_buffer_size, "Read ring buffer size");
 
 /* The write_buffer can one day contain more than one interrupt out transfer.
  */
 
 static int write_buffer_size = WRITE_BUFFER_SIZE;
-module_param(write_buffer_size, int,  S_IRUGO);
+module_param(write_buffer_size, int, S_IRUGO);
 MODULE_PARM_DESC(write_buffer_size, "Write buffer size");
 
 /*
@@ -133,55 +124,56 @@
 
 static int min_interrupt_in_interval = ALPHATRACK_USB_TIMEOUT;
 module_param(min_interrupt_in_interval, int, 0);
-MODULE_PARM_DESC(min_interrupt_in_interval, "Minimum interrupt in interval in ms");
+MODULE_PARM_DESC(min_interrupt_in_interval,
+		 "Minimum interrupt in interval in ms");
 
 static int min_interrupt_out_interval = ALPHATRACK_USB_TIMEOUT;
 module_param(min_interrupt_out_interval, int, 0);
-MODULE_PARM_DESC(min_interrupt_out_interval, "Minimum interrupt out interval in ms");
-
-
+MODULE_PARM_DESC(min_interrupt_out_interval,
+		 "Minimum interrupt out interval in ms");
 
 /* Structure to hold all of our device specific stuff */
 
 struct usb_alphatrack {
-	struct semaphore	sem;		/* locks this structure */
-	struct usb_interface*	intf;		/* save off the usb interface pointer */
-	int			open_count;	/* number of times this port has been opened */
+	struct semaphore sem;	/* locks this structure */
+	struct usb_interface *intf;	/* save off the usb interface pointer */
+	int open_count;		/* number of times this port has been opened */
 
-	struct alphatrack_icmd	(*ring_buffer)[RING_BUFFER_SIZE]; /* just make c happy */
-	struct alphatrack_ocmd	(*write_buffer)[WRITE_BUFFER_SIZE]; /* just make c happy */
-	unsigned int		ring_head;
-	unsigned int		ring_tail;
+	/* make gcc happy */
+	struct alphatrack_icmd (*ring_buffer)[RING_BUFFER_SIZE];
+	struct alphatrack_ocmd (*write_buffer)[WRITE_BUFFER_SIZE];
+	unsigned int ring_head;
+	unsigned int ring_tail;
 
-	wait_queue_head_t	read_wait;
-	wait_queue_head_t	write_wait;
+	wait_queue_head_t read_wait;
+	wait_queue_head_t write_wait;
 
-	unsigned char*		interrupt_in_buffer;
-	unsigned char*		oldi_buffer;
-	struct usb_endpoint_descriptor* interrupt_in_endpoint;
-	struct urb*		interrupt_in_urb;
-	int			interrupt_in_interval;
-	size_t			interrupt_in_endpoint_size;
-	int			interrupt_in_running;
-	int			interrupt_in_done;
+	unsigned char *interrupt_in_buffer;
+	unsigned char *oldi_buffer;
+	struct usb_endpoint_descriptor *interrupt_in_endpoint;
+	struct urb *interrupt_in_urb;
+	int interrupt_in_interval;
+	size_t interrupt_in_endpoint_size;
+	int interrupt_in_running;
+	int interrupt_in_done;
 
-	char*			interrupt_out_buffer;
-	struct usb_endpoint_descriptor* interrupt_out_endpoint;
-	struct urb*		interrupt_out_urb;
-	int			interrupt_out_interval;
-	size_t			interrupt_out_endpoint_size;
-	int			interrupt_out_busy;
+	char *interrupt_out_buffer;
+	struct usb_endpoint_descriptor *interrupt_out_endpoint;
+	struct urb *interrupt_out_urb;
+	int interrupt_out_interval;
+	size_t interrupt_out_endpoint_size;
+	int interrupt_out_busy;
 
 	atomic_t writes_pending;
-	int event; /* alternate interface to events */
-	int fader; /* 10 bits */
-	int lights; /* 23 bits */
-	unsigned char dump_state; /* 0 if disabled 1 if enabled */
-	unsigned char enable; /* 0 if disabled 1 if enabled */
-	unsigned char offline; /* if the device is out of range or asleep */
-	unsigned char verbose; /* be verbose in error reporting */
-	unsigned char  last_cmd[OUTPUT_CMD_SIZE];
-	unsigned char  screen[32];
+	int event;		/* alternate interface to events */
+	int fader;		/* 10 bits */
+	int lights;		/* 23 bits */
+	unsigned char dump_state;	/* 0 if disabled 1 if enabled */
+	unsigned char enable;	/* 0 if disabled 1 if enabled */
+	unsigned char offline;	/* if the device is out of range or asleep */
+	unsigned char verbose;	/* be verbose in error reporting */
+	unsigned char last_cmd[OUTPUT_CMD_SIZE];
+	unsigned char screen[32];
 };
 
 /* prevent races between open() and disconnect() */
@@ -219,7 +211,7 @@
 	kfree(dev->ring_buffer);
 	kfree(dev->interrupt_in_buffer);
 	kfree(dev->interrupt_out_buffer);
-	kfree(dev); // fixme oldi_buffer
+	kfree(dev);		/* fixme oldi_buffer */
 }
 
 /**
@@ -234,39 +226,52 @@
 
 	if (urb->status) {
 		if (urb->status == -ENOENT ||
-		    urb->status == -ECONNRESET ||
-		    urb->status == -ESHUTDOWN) {
+		    urb->status == -ECONNRESET || urb->status == -ESHUTDOWN) {
 			goto exit;
 		} else {
-			dbg_info(&dev->intf->dev, "%s: nonzero status received: %d\n",
-				 __func__, urb->status);
-			goto resubmit; /* maybe we can recover */
+			dbg_info(&dev->intf->dev,
+				 "%s: nonzero status received: %d\n", __func__,
+				 urb->status);
+			goto resubmit;	/* maybe we can recover */
 		}
 	}
 
 	if (urb->actual_length != INPUT_CMD_SIZE) {
 		dev_warn(&dev->intf->dev,
-			 "Urb length was %d bytes!! Do something intelligent \n", urb->actual_length);
+			 "Urb length was %d bytes!!"
+			 "Do something intelligent \n", urb->actual_length);
 	} else {
-		 alphatrack_ocmd_info(&dev->intf->dev,&(*dev->ring_buffer)[dev->ring_tail].cmd,"%s", "bla");
-		 if(memcmp(dev->interrupt_in_buffer,dev->oldi_buffer,INPUT_CMD_SIZE)==0) {
-						goto resubmit;
+		alphatrack_ocmd_info(&dev->intf->dev,
+				     &(*dev->ring_buffer)[dev->ring_tail].cmd,
+				     "%s", "bla");
+		if (memcmp
+		    (dev->interrupt_in_buffer, dev->oldi_buffer,
+		     INPUT_CMD_SIZE) == 0) {
+			goto resubmit;
 		}
-		memcpy(dev->oldi_buffer,dev->interrupt_in_buffer,INPUT_CMD_SIZE);
+		memcpy(dev->oldi_buffer, dev->interrupt_in_buffer,
+		       INPUT_CMD_SIZE);
 
 #if SUPPRESS_EXTRA_OFFLINE_EVENTS
-	if(dev->offline == 2 && dev->interrupt_in_buffer[1] == 0xff) { goto resubmit; }
-		if(dev->offline == 1 && dev->interrupt_in_buffer[1] == 0xff) { dev->offline = 2; goto resubmit; }
+		if (dev->offline == 2 && dev->interrupt_in_buffer[1] == 0xff)
+			goto resubmit;
+		if (dev->offline == 1 && dev->interrupt_in_buffer[1] == 0xff) {
+			dev->offline = 2;
+			goto resubmit;
+		}
 /* Always pass one offline event up the stack */
-		if(dev->offline > 0 && dev->interrupt_in_buffer[1] != 0xff) { dev->offline = 0; }
-		if(dev->offline == 0 && dev->interrupt_in_buffer[1] == 0xff) { dev->offline = 1; }
+		if (dev->offline > 0 && dev->interrupt_in_buffer[1] != 0xff)
+			dev->offline = 0;
+		if (dev->offline == 0 && dev->interrupt_in_buffer[1] == 0xff)
+			dev->offline = 1;
 #endif
-		dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n", __func__,dev->ring_head,dev->ring_tail);
-		next_ring_head = (dev->ring_head+1) % ring_buffer_size;
+		dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n",
+			 __func__, dev->ring_head, dev->ring_tail);
+		next_ring_head = (dev->ring_head + 1) % ring_buffer_size;
 
 		if (next_ring_head != dev->ring_tail) {
 			memcpy(&((*dev->ring_buffer)[dev->ring_head]),
-						 dev->interrupt_in_buffer, urb->actual_length);
+			       dev->interrupt_in_buffer, urb->actual_length);
 			dev->ring_head = next_ring_head;
 			retval = 0;
 			memset(dev->interrupt_in_buffer, 0, urb->actual_length);
@@ -330,7 +335,7 @@
 
 	if (!interface) {
 		err("%s - error, can't find device for minor %d\n",
-		     __func__, subminor);
+		    __func__, subminor);
 		retval = -ENODEV;
 		goto unlock_disconnect_exit;
 	}
@@ -361,11 +366,11 @@
 	usb_fill_int_urb(dev->interrupt_in_urb,
 			 interface_to_usbdev(interface),
 			 usb_rcvintpipe(interface_to_usbdev(interface),
-					dev->interrupt_in_endpoint->bEndpointAddress),
+					dev->interrupt_in_endpoint->
+					bEndpointAddress),
 			 dev->interrupt_in_buffer,
 			 dev->interrupt_in_endpoint_size,
-			 usb_alphatrack_interrupt_in_callback,
-			 dev,
+			 usb_alphatrack_interrupt_in_callback, dev,
 			 dev->interrupt_in_interval);
 
 	dev->interrupt_in_running = 1;
@@ -375,7 +380,8 @@
 
 	retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
 	if (retval) {
-		dev_err(&interface->dev, "Couldn't submit interrupt_in_urb %d\n", retval);
+		dev_err(&interface->dev,
+			"Couldn't submit interrupt_in_urb %d\n", retval);
 		dev->interrupt_in_running = 0;
 		dev->open_count = 0;
 		goto unlock_exit;
@@ -384,7 +390,6 @@
 	/* save device in the file's private structure */
 	file->private_data = dev;
 
-
 unlock_exit:
 	up(&dev->sem);
 
@@ -430,7 +435,9 @@
 
 	/* wait until write transfer is finished */
 	if (dev->interrupt_out_busy)
-		wait_event_interruptible_timeout(dev->write_wait, !dev->interrupt_out_busy, 2 * HZ);
+		wait_event_interruptible_timeout(dev->write_wait,
+						 !dev->interrupt_out_busy,
+						 2 * HZ);
 	usb_alphatrack_abort_transfers(dev);
 	dev->open_count = 0;
 
@@ -444,7 +451,7 @@
 /**
  *	usb_alphatrack_poll
  */
-static unsigned int usb_alphatrack_poll(struct file *file, poll_table *wait)
+static unsigned int usb_alphatrack_poll(struct file *file, poll_table * wait)
 {
 	struct usb_alphatrack *dev;
 	unsigned int mask = 0;
@@ -465,8 +472,8 @@
 /**
  *	usb_alphatrack_read
  */
-static ssize_t usb_alphatrack_read(struct file *file, char __user *buffer, size_t count,
-			   loff_t *ppos)
+static ssize_t usb_alphatrack_read(struct file *file, char __user *buffer,
+				   size_t count, loff_t *ppos)
 {
 	struct usb_alphatrack *dev;
 	int retval = 0;
@@ -493,30 +500,36 @@
 	}
 
 	while (dev->ring_head == dev->ring_tail) {
-					if (file->f_flags & O_NONBLOCK) {
-									retval = -EAGAIN;
-									goto unlock_exit;
-					}
-					dev->interrupt_in_done = 0 ;
-					retval = wait_event_interruptible(dev->read_wait, dev->interrupt_in_done);
-					if (retval < 0) {
-									goto unlock_exit;
-					}
+		if (file->f_flags & O_NONBLOCK) {
+			retval = -EAGAIN;
+			goto unlock_exit;
+		}
+		dev->interrupt_in_done = 0;
+		retval =
+		    wait_event_interruptible(dev->read_wait,
+					     dev->interrupt_in_done);
+		if (retval < 0)
+			goto unlock_exit;
 	}
 
-	alphatrack_ocmd_info(&dev->intf->dev, &(*dev->ring_buffer)[dev->ring_tail].cmd, "%s", ": copying to userspace");
+	alphatrack_ocmd_info(&dev->intf->dev,
+			     &(*dev->ring_buffer)[dev->ring_tail].cmd, "%s",
+			     ": copying to userspace");
 
-	   c = 0;
-	   while((c < count) && (dev->ring_tail != dev->ring_head)) {
-						 if (copy_to_user(&buffer[c], &(*dev->ring_buffer)[dev->ring_tail], INPUT_CMD_SIZE)) {
-										 retval = -EFAULT;
-										 goto unlock_exit;
-						 }
-						 dev->ring_tail = (dev->ring_tail+1) % ring_buffer_size;
-						 c+=INPUT_CMD_SIZE;
-						 dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n", __func__,dev->ring_head,dev->ring_tail);
-	   }
-	   retval = c;
+	c = 0;
+	while ((c < count) && (dev->ring_tail != dev->ring_head)) {
+		if (copy_to_user
+		    (&buffer[c], &(*dev->ring_buffer)[dev->ring_tail],
+		     INPUT_CMD_SIZE)) {
+			retval = -EFAULT;
+			goto unlock_exit;
+		}
+		dev->ring_tail = (dev->ring_tail + 1) % ring_buffer_size;
+		c += INPUT_CMD_SIZE;
+		dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n",
+			 __func__, dev->ring_head, dev->ring_tail);
+	}
+	retval = c;
 
 unlock_exit:
 	/* unlock the device */
@@ -529,8 +542,9 @@
 /**
  *	usb_alphatrack_write
  */
-static ssize_t usb_alphatrack_write(struct file *file, const char __user *buffer,
-			    size_t count, loff_t *ppos)
+static ssize_t usb_alphatrack_write(struct file *file,
+				    const char __user *buffer, size_t count,
+				    loff_t *ppos)
 {
 	struct usb_alphatrack *dev;
 	size_t bytes_to_write;
@@ -561,19 +575,24 @@
 			retval = -EAGAIN;
 			goto unlock_exit;
 		}
-		retval = wait_event_interruptible(dev->write_wait, !dev->interrupt_out_busy);
-		if (retval < 0) {
+		retval =
+		    wait_event_interruptible(dev->write_wait,
+					     !dev->interrupt_out_busy);
+		if (retval < 0)
 			goto unlock_exit;
-		}
 	}
 
 	/* write the data into interrupt_out_buffer from userspace */
-  /* FIXME - if you write more than 12 bytes this breaks */
-	bytes_to_write = min(count, write_buffer_size*dev->interrupt_out_endpoint_size);
+	/* FIXME - if you write more than 12 bytes this breaks */
+	bytes_to_write =
+	    min(count, write_buffer_size * dev->interrupt_out_endpoint_size);
 	if (bytes_to_write < count)
-		dev_warn(&dev->intf->dev, "Write buffer overflow, %zd bytes dropped\n",count-bytes_to_write);
+		dev_warn(&dev->intf->dev,
+			 "Write buffer overflow, %zd bytes dropped\n",
+			 count - bytes_to_write);
 
-	dbg_info(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n", __func__, count, bytes_to_write);
+	dbg_info(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n",
+		 __func__, count, bytes_to_write);
 
 	if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) {
 		retval = -EFAULT;
@@ -589,11 +608,10 @@
 	usb_fill_int_urb(dev->interrupt_out_urb,
 			 interface_to_usbdev(dev->intf),
 			 usb_sndintpipe(interface_to_usbdev(dev->intf),
-					dev->interrupt_out_endpoint->bEndpointAddress),
-			 dev->interrupt_out_buffer,
-			 bytes_to_write,
-			 usb_alphatrack_interrupt_out_callback,
-			 dev,
+					dev->interrupt_out_endpoint->
+					bEndpointAddress),
+			 dev->interrupt_out_buffer, bytes_to_write,
+			 usb_alphatrack_interrupt_out_callback, dev,
 			 dev->interrupt_out_interval);
 	dev->interrupt_out_busy = 1;
 	atomic_inc(&dev->writes_pending);
@@ -618,12 +636,12 @@
 
 /* file operations needed when we register this driver */
 static const struct file_operations usb_alphatrack_fops = {
-	.owner =	THIS_MODULE,
-	.read  =	usb_alphatrack_read,
-	.write =	usb_alphatrack_write,
-	.open =		usb_alphatrack_open,
-	.release =	usb_alphatrack_release,
-	.poll =		usb_alphatrack_poll,
+	.owner = THIS_MODULE,
+	.read = usb_alphatrack_read,
+	.write = usb_alphatrack_write,
+	.open = usb_alphatrack_open,
+	.release = usb_alphatrack_release,
+	.poll = usb_alphatrack_poll,
 };
 
 /*
@@ -632,19 +650,19 @@
  */
 
 static struct usb_class_driver usb_alphatrack_class = {
-	.name =		"alphatrack%d",
-	.fops =		&usb_alphatrack_fops,
-	.minor_base =	USB_ALPHATRACK_MINOR_BASE,
+	.name = "alphatrack%d",
+	.fops = &usb_alphatrack_fops,
+	.minor_base = USB_ALPHATRACK_MINOR_BASE,
 };
 
-
 /**
  *	usb_alphatrack_probe
  *
  *	Called by the usb core when a new device is connected that it thinks
  *	this driver might be interested in.
  */
-static int usb_alphatrack_probe(struct usb_interface *intf, const struct usb_device_id *id)
+static int usb_alphatrack_probe(struct usb_interface *intf,
+				const struct usb_device_id *id)
 {
 	struct usb_device *udev = interface_to_usbdev(intf);
 	struct usb_alphatrack *dev = NULL;
@@ -683,28 +701,35 @@
 		goto error;
 	}
 	if (dev->interrupt_out_endpoint == NULL)
-		dev_warn(&intf->dev, "Interrupt out endpoint not found (using control endpoint instead)\n");
+		dev_warn(&intf->dev,
+			 "Interrupt out endpoint not found"
+			 "(using control endpoint instead)\n");
 
-	dev->interrupt_in_endpoint_size = le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize);
+	dev->interrupt_in_endpoint_size =
+	    le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize);
 
 	if (dev->interrupt_in_endpoint_size != 64)
-	    dev_warn(&intf->dev, "Interrupt in endpoint size is not 64!\n");
+		dev_warn(&intf->dev, "Interrupt in endpoint size is not 64!\n");
 
-	if(ring_buffer_size == 0) { ring_buffer_size = RING_BUFFER_SIZE; }
+	if (ring_buffer_size == 0)
+		ring_buffer_size = RING_BUFFER_SIZE;
 
-	true_size = min(ring_buffer_size,RING_BUFFER_SIZE);
+	true_size = min(ring_buffer_size, RING_BUFFER_SIZE);
 
-	/* FIXME - there are more usb_alloc routines for dma correctness. Needed? */
-
-//	dev->ring_buffer = kmalloc((true_size*sizeof(struct alphatrack_icmd))+12, GFP_KERNEL);
-	dev->ring_buffer = kmalloc((true_size*sizeof(struct alphatrack_icmd)), GFP_KERNEL);
+	/* FIXME - there are more usb_alloc routines for dma correctness.
+	   Needed? */
+	dev->ring_buffer =
+	    kmalloc((true_size * sizeof(struct alphatrack_icmd)), GFP_KERNEL);
 
 	if (!dev->ring_buffer) {
-		dev_err(&intf->dev, "Couldn't allocate input ring_buffer of size %d\n",true_size);
+		dev_err(&intf->dev,
+			"Couldn't allocate input ring_buffer of size %d\n",
+			true_size);
 		goto error;
 	}
 
-	dev->interrupt_in_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL);
+	dev->interrupt_in_buffer =
+	    kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL);
 
 	if (!dev->interrupt_in_buffer) {
 		dev_err(&intf->dev, "Couldn't allocate interrupt_in_buffer\n");
@@ -721,23 +746,30 @@
 		goto error;
 	}
 
-	dev->interrupt_out_endpoint_size = dev->interrupt_out_endpoint ? le16_to_cpu(dev->interrupt_out_endpoint->wMaxPacketSize) :
-									 udev->descriptor.bMaxPacketSize0;
+	dev->interrupt_out_endpoint_size =
+	    dev->interrupt_out_endpoint ? le16_to_cpu(dev->
+						      interrupt_out_endpoint->
+						      wMaxPacketSize) : udev->
+	    descriptor.bMaxPacketSize0;
 
-	if (dev->interrupt_out_endpoint_size !=64)
-		dev_warn(&intf->dev, "Interrupt out endpoint size is not 64!)\n");
+	if (dev->interrupt_out_endpoint_size != 64)
+		dev_warn(&intf->dev,
+			 "Interrupt out endpoint size is not 64!)\n");
 
-	if(write_buffer_size == 0) { write_buffer_size = WRITE_BUFFER_SIZE; }
-	true_size = min(write_buffer_size,WRITE_BUFFER_SIZE);
+	if (write_buffer_size == 0)
+		write_buffer_size = WRITE_BUFFER_SIZE;
+	true_size = min(write_buffer_size, WRITE_BUFFER_SIZE);
 
-	dev->interrupt_out_buffer = kmalloc(true_size*dev->interrupt_out_endpoint_size, GFP_KERNEL);
+	dev->interrupt_out_buffer =
+	    kmalloc(true_size * dev->interrupt_out_endpoint_size, GFP_KERNEL);
 
 	if (!dev->interrupt_out_buffer) {
 		dev_err(&intf->dev, "Couldn't allocate interrupt_out_buffer\n");
 		goto error;
 	}
 
-	dev->write_buffer = kmalloc(sizeof(struct alphatrack_ocmd)*true_size, GFP_KERNEL);
+	dev->write_buffer =
+	    kmalloc(sizeof(struct alphatrack_ocmd) * true_size, GFP_KERNEL);
 
 	if (!dev->write_buffer) {
 		dev_err(&intf->dev, "Couldn't allocate write_buffer \n");
@@ -749,25 +781,36 @@
 		dev_err(&intf->dev, "Couldn't allocate interrupt_out_urb\n");
 		goto error;
 	}
-	dev->interrupt_in_interval = min_interrupt_in_interval > dev->interrupt_in_endpoint->bInterval ? min_interrupt_in_interval : dev->interrupt_in_endpoint->bInterval;
+	dev->interrupt_in_interval =
+	    min_interrupt_in_interval >
+	    dev->interrupt_in_endpoint->
+	    bInterval ? min_interrupt_in_interval : dev->interrupt_in_endpoint->
+	    bInterval;
 	if (dev->interrupt_out_endpoint)
-		dev->interrupt_out_interval = min_interrupt_out_interval > dev->interrupt_out_endpoint->bInterval ? min_interrupt_out_interval : dev->interrupt_out_endpoint->bInterval;
+		dev->interrupt_out_interval =
+		    min_interrupt_out_interval >
+		    dev->interrupt_out_endpoint->
+		    bInterval ? min_interrupt_out_interval : dev->
+		    interrupt_out_endpoint->bInterval;
 
 	/* we can register the device now, as it is ready */
 	usb_set_intfdata(intf, dev);
 
-	atomic_set(&dev->writes_pending,0);
+	atomic_set(&dev->writes_pending, 0);
 	retval = usb_register_dev(intf, &usb_alphatrack_class);
 	if (retval) {
 		/* something prevented us from registering this driver */
-		dev_err(&intf->dev, "Not able to get a minor for this device.\n");
+		dev_err(&intf->dev,
+			"Not able to get a minor for this device.\n");
 		usb_set_intfdata(intf, NULL);
 		goto error;
 	}
 
 	/* let the user know what node this device is now attached to */
-	dev_info(&intf->dev, "Alphatrack Device #%d now attached to major %d minor %d\n",
-		(intf->minor - USB_ALPHATRACK_MINOR_BASE), USB_MAJOR, intf->minor);
+	dev_info(&intf->dev,
+		 "Alphatrack Device #%d now attached to major %d minor %d\n",
+		 (intf->minor - USB_ALPHATRACK_MINOR_BASE), USB_MAJOR,
+		 intf->minor);
 
 exit:
 	return retval;
@@ -809,7 +852,7 @@
 		up(&dev->sem);
 	}
 
-	atomic_set(&dev->writes_pending,0);
+	atomic_set(&dev->writes_pending, 0);
 	mutex_unlock(&disconnect_mutex);
 
 	dev_info(&intf->dev, "Alphatrack Surface #%d now disconnected\n",
@@ -818,10 +861,10 @@
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver usb_alphatrack_driver = {
-	.name =		"alphatrack",
-	.probe =	usb_alphatrack_probe,
-	.disconnect =	usb_alphatrack_disconnect,
-	.id_table =	usb_alphatrack_table,
+	.name = "alphatrack",
+	.probe = usb_alphatrack_probe,
+	.disconnect = usb_alphatrack_disconnect,
+	.id_table = usb_alphatrack_table,
 };
 
 /**
@@ -834,7 +877,8 @@
 	/* register this driver with the USB subsystem */
 	retval = usb_register(&usb_alphatrack_driver);
 	if (retval)
-		err("usb_register failed for the "__FILE__" driver. Error number %d\n", retval);
+		err("usb_register failed for the " __FILE__
+		    " driver. Error number %d\n", retval);
 
 	return retval;
 }
@@ -850,4 +894,3 @@
 
 module_init(usb_alphatrack_init);
 module_exit(usb_alphatrack_exit);
-
diff --git a/drivers/staging/frontier/alphatrack.h b/drivers/staging/frontier/alphatrack.h
index 35c90a9..10a7972 100644
--- a/drivers/staging/frontier/alphatrack.h
+++ b/drivers/staging/frontier/alphatrack.h
@@ -1,42 +1,38 @@
-#define show_set_bit(a) show_set_mbit(alphatrack,a)
-#define show_set_cmd(a) show_set_mcmd(alphatrack,a)
-#define show_set_int(a) show_set_mint(alphatrack,a)
-#define show_set_char(a) show_set_mchar(alphatrack,a)
-#define show_set_light(a) show_set_ebit(alphatrack,LightID,lights,a)
-#define show_set_button(a) show_set_ebit(alphatrack,ButtonID,button,a)
-
 struct alphatrack_icmd {
-    unsigned char cmd[12];
+	unsigned char cmd[12];
 };
 
 struct alphatrack_ocmd {
-    unsigned char cmd[8];
+	unsigned char cmd[8];
 };
 
+/* These are unused by the present driver but provide documentation for the
+ * userspace API.
+ */
 enum LightID {
-        LIGHT_EQ = 0,
-        LIGHT_OUT,
-        LIGHT_F2,
-        LIGHT_SEND,
-        LIGHT_IN,
-        LIGHT_F1,
-        LIGHT_PAN,
-        LIGHT_UNDEF1,
-        LIGHT_UNDEF2,
-        LIGHT_SHIFT,
-        LIGHT_TRACKMUTE,
-        LIGHT_TRACKSOLO,
-        LIGHT_TRACKREC,
-        LIGHT_READ,
-        LIGHT_WRITE,
-        LIGHT_ANYSOLO,
-        LIGHT_AUTO,
-        LIGHT_F4,
-        LIGHT_RECORD,
-        LIGHT_WINDOW,
-        LIGHT_PLUGIN,
-        LIGHT_F3,
-        LIGHT_LOOP
+	LIGHT_EQ = 0,
+	LIGHT_OUT,
+	LIGHT_F2,
+	LIGHT_SEND,
+	LIGHT_IN,
+	LIGHT_F1,
+	LIGHT_PAN,
+	LIGHT_UNDEF1,
+	LIGHT_UNDEF2,
+	LIGHT_SHIFT,
+	LIGHT_TRACKMUTE,
+	LIGHT_TRACKSOLO,
+	LIGHT_TRACKREC,
+	LIGHT_READ,
+	LIGHT_WRITE,
+	LIGHT_ANYSOLO,
+	LIGHT_AUTO,
+	LIGHT_F4,
+	LIGHT_RECORD,
+	LIGHT_WINDOW,
+	LIGHT_PLUGIN,
+	LIGHT_F3,
+	LIGHT_LOOP
 };
 
 #define BUTTONMASK_BATTERY     0x00004000
@@ -62,8 +58,9 @@
 #define BUTTONMASK_PRESS2      0x00008010
 #define BUTTONMASK_PRESS3      0x00002020
 
-// last 3 bytes are the slider position
-// 40 is the actual slider moving, the most sig bits, and 3 lsb
+/* last 3 bytes are the slider position
+ * 40 is the actual slider moving, the most sig bits, and 3 lsb
+ */
 
 #define BUTTONMASK_FLIP         0x40000000
 #define BUTTONMASK_F1           0x00100000
@@ -76,17 +73,4 @@
 #define BUTTONMASK_PLUGIN       0x00000400
 #define BUTTONMASK_AUTO         0x00000100
 
-
-// #define BUTTONMASK_FOOTSWITCH FIXME
-
-// Lookup. name. midi out. midi in.
-
-struct buttonmap_t {
-	u32 mask;
-	short midi_in;
-	short midi_out;
-	char *name;
-//  	void (*function) (buttonmap_t *);
-  	void (*function) (void);
-};
-
+/* #define BUTTONMASK_FOOTSWITCH FIXME */
diff --git a/drivers/staging/frontier/frontier_compat.h b/drivers/staging/frontier/frontier_compat.h
deleted file mode 100644
index 00450e6..0000000
--- a/drivers/staging/frontier/frontier_compat.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* USB defines for older kernels */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
-
-/**
- * usb_endpoint_dir_out - check if the endpoint has OUT direction
- * @epd: endpoint to be checked
- *
- * Returns true if the endpoint is of type OUT, otherwise it returns false.
- */
-
-static inline int usb_endpoint_dir_out(const struct usb_endpoint_descriptor *epd)
-{
-       return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT);
-}
-
-static inline int usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd)
-{
-       return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN);
-}
-
-
-/**
- * usb_endpoint_xfer_int - check if the endpoint has interrupt transfer type
- * @epd: endpoint to be checked
- *
- * Returns true if the endpoint is of type interrupt, otherwise it returns
- * false.
- */
-static inline int usb_endpoint_xfer_int(const struct usb_endpoint_descriptor *epd)
-{
-       return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
-               USB_ENDPOINT_XFER_INT);
-}
-
-
-/**
- * usb_endpoint_is_int_in - check if the endpoint is interrupt IN
- * @epd: endpoint to be checked
- *
- * Returns true if the endpoint has interrupt transfer type and IN direction,
- * otherwise it returns false.
- */
-
-static inline int usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd)
-{
-       return (usb_endpoint_xfer_int(epd) && usb_endpoint_dir_in(epd));
-}
-
-/**
- * usb_endpoint_is_int_out - check if the endpoint is interrupt OUT
- * @epd: endpoint to be checked
- *
- * Returns true if the endpoint has interrupt transfer type and OUT direction,
- * otherwise it returns false.
- */
-
-static inline int usb_endpoint_is_int_out(const struct usb_endpoint_descriptor *epd)
-{
-       return (usb_endpoint_xfer_int(epd) && usb_endpoint_dir_out(epd));
-}
-
-#endif /* older kernel versions */
diff --git a/drivers/staging/frontier/surface_sysfs.h b/drivers/staging/frontier/surface_sysfs.h
deleted file mode 100644
index d50a562d..0000000
--- a/drivers/staging/frontier/surface_sysfs.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* If you are going to abuse the preprocessor, why not ABUSE the preprocessor?
-   I stuck this header in a separate file so I don't have to look at it */
-
-// FIXME Need locking or atomic ops
-
-#define show_set_mbit(dname,value,bit)																			\
-static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf)		\
-{									\
-	struct usb_interface *intf = to_usb_interface(dev);		\
-	struct usb_##dname *t = usb_get_intfdata(intf);			\
-	int temp = (1 && (t->value & (1 << bit)));					\
-	return sprintf(buf, "%d\n", temp);			\
-}									\
-static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)	\
-{									\
-	struct usb_interface *intf = to_usb_interface(dev);		\
-	struct usb_##dname *t = usb_get_intfdata(intf);			\
-	int temp = simple_strtoul(buf, NULL, 10);			\
-	if(temp > 0) { long b = 1 << bit; t->value |= b; } \
-	else { long b = ~(1 << bit); t->value &= b ;				 \
-	return count;							\
-}									\
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
-
-#define show_set_ebit(dname,enumname,value,bit)																			\
-static ssize_t show_##bit(struct device *dev, struct device_attribute *attr, char *buf)		\
-{									\
-	struct usb_interface *intf = to_usb_interface(dev);		\
-	struct usb_##dname *t = usb_get_intfdata(intf);			\
-  enum enumname l = bit; \
-  int temp = t->value & (1 << l);						\
-	return sprintf(buf, "%d\n", temp);			\
-}									\
-static ssize_t set_##bit(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)	\
-{									\
-	struct usb_interface *intf = to_usb_interface(dev);		\
-	struct usb_##dname *t = usb_get_intfdata(intf);			\
-	int temp = simple_strtoul(buf, NULL, 10);			\
-  enum enumname l = bit;\
-	long b  = 1 << l; \
-	if(temp > 0) { t->value |= b; }	\
-	else { t->value &= ~b ;				\
-	return count;							\
-}									\
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
-
-// FIXME FOR CORRECTLY SETTING HEX from a string
-#define show_set_mcmd(dname,value)																			\
-static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf)		\
-{									\
-	struct usb_interface *intf = to_usb_interface(dev);		\
-	struct usb_##dname *t = usb_get_intfdata(intf);			\
-  int count = 0;\
-	int i; \
-	for (i = 0,i<sizeof(dname); i++) count += snprintf(buf, "%02x",t->dname[i]); \
-  return(count);\
-}									\
-static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)	\
-{									\
-	struct usb_interface *intf = to_usb_interface(dev);		\
-	struct usb_##dname *t = usb_get_intfdata(intf);			\
-	int temp = simple_strtoul(buf, NULL, 10);			\
-	t->value = temp;						\
-	return count;							\
-}									\
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
-
-#define show_set_mint(dname,value)				\
-static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf)		\
-{									\
-	struct usb_interface *intf = to_usb_interface(dev);		\
-	struct usb_##dname *t = usb_get_intfdata(intf);			\
-	return sprintf(buf, "%d\n", t->value);			\
-}									\
-static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)	\
-{									\
-	struct usb_interface *intf = to_usb_interface(dev);		\
-	struct usb_##dname *t = usb_get_intfdata(intf);			\
-	int temp = simple_strtoul(buf, NULL, 10);			\
-	t->value = temp;						\
-	return count;							\
-}									\
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
-
-#define show_set_mchar(dname,value)																				\
-static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf)		\
-{									\
-	struct usb_interface *intf = to_usb_interface(dev);		\
-	struct usb_##dname *t = usb_get_intfdata(intf);			\
-	return sprintf(buf, "%c\n", t->value);			\
-}									\
-static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)	\
-{									\
-	struct usb_interface *intf = to_usb_interface(dev);		\
-	struct usb_##dname *t = usb_get_intfdata(intf);			\
-	int temp = simple_strtoul(buf, NULL, 10);			\
-	t->value = temp;						\
-	return count;							\
-}									\
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
diff --git a/drivers/staging/frontier/tranzport.c b/drivers/staging/frontier/tranzport.c
index 79abb6b..274b82b 100644
--- a/drivers/staging/frontier/tranzport.c
+++ b/drivers/staging/frontier/tranzport.c
@@ -18,7 +18,7 @@
  *
  */
 
-/**
+/*
  * This driver uses a ring buffer for time critical reading of
  * interrupt in reports and provides read and write methods for
  * raw interrupt reports.
@@ -30,7 +30,7 @@
  * as we only have 17 commands for the tranzport. In particular this is
  * key for getting lights to flash in time as otherwise many commands
  * can be buffered up before the light change makes it to the interface.
-*/
+ */
 
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -40,56 +40,47 @@
 #include <linux/mutex.h>
 #include <linux/version.h>
 
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/input.h>
 #include <linux/usb.h>
 #include <linux/poll.h>
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
-#include frontier_compat.h
-#endif
-
 /* Define these values to match your devices */
 #define VENDOR_ID   0x165b
-#define PRODUCT_ID	0x8101
+#define PRODUCT_ID  0x8101
 
 #ifdef CONFIG_USB_DYNAMIC_MINORS
 #define USB_TRANZPORT_MINOR_BASE	0
-#else
-// FIXME 176 - is the ldusb driver's minor - apply for a minor soon
+#else  /* FIXME 177- is the another driver's minor - apply for a minor soon */
 #define USB_TRANZPORT_MINOR_BASE	177
 #endif
 
 /* table of devices that work with this driver */
-static struct usb_device_id usb_tranzport_table [] = {
-	{ USB_DEVICE(VENDOR_ID, PRODUCT_ID) },
-	{ }					/* Terminating entry */
+static struct usb_device_id usb_tranzport_table[] = {
+	{USB_DEVICE(VENDOR_ID, PRODUCT_ID)},
+	{}			/* Terminating entry */
 };
 
 MODULE_DEVICE_TABLE(usb, usb_tranzport_table);
-MODULE_VERSION("0.33");
+MODULE_VERSION("0.35");
 MODULE_AUTHOR("Mike Taht <m@taht.net>");
 MODULE_DESCRIPTION("Tranzport USB Driver");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("Frontier Designs Tranzport Control Surface");
 
-/* These two aren't done yet */
-
-#define SUPPRESS_EXTRA_ONLINE_EVENTS 0
-#define BUFFERED_WRITES 0
-
 #define SUPPRESS_EXTRA_OFFLINE_EVENTS 1
 #define COMPRESS_WHEEL_EVENTS 1
 #define BUFFERED_READS 1
 #define RING_BUFFER_SIZE 1000
 #define WRITE_BUFFER_SIZE 34
 #define TRANZPORT_USB_TIMEOUT 10
+#define TRANZPORT_DEBUG 0
 
-
-static int debug = 0;
+static int debug = TRANZPORT_DEBUG;
 
 /* Use our own dbg macro */
-#define dbg_info(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0)
+#define dbg_info(dev, format, arg...) do			\
+	{ if (debug) dev_info(dev , format , ## arg); } while (0)
 
 /* Module parameters */
 
@@ -102,13 +93,13 @@
 
 static int ring_buffer_size = RING_BUFFER_SIZE;
 
-module_param(ring_buffer_size, int,  S_IRUGO);
+module_param(ring_buffer_size, int, S_IRUGO);
 MODULE_PARM_DESC(ring_buffer_size, "Read ring buffer size in reports");
 
 /* The write_buffer can one day contain more than one interrupt out transfer.
  */
 static int write_buffer_size = WRITE_BUFFER_SIZE;
-module_param(write_buffer_size, int,  S_IRUGO);
+module_param(write_buffer_size, int, S_IRUGO);
 MODULE_PARM_DESC(write_buffer_size, "Write buffer size");
 
 /*
@@ -118,69 +109,48 @@
 
 static int min_interrupt_in_interval = TRANZPORT_USB_TIMEOUT;
 module_param(min_interrupt_in_interval, int, 0);
-MODULE_PARM_DESC(min_interrupt_in_interval, "Minimum interrupt in interval in ms");
+MODULE_PARM_DESC(min_interrupt_in_interval,
+		"Minimum interrupt in interval in ms");
 
 static int min_interrupt_out_interval = TRANZPORT_USB_TIMEOUT;
 module_param(min_interrupt_out_interval, int, 0);
-MODULE_PARM_DESC(min_interrupt_out_interval, "Minimum interrupt out interval in ms");
+MODULE_PARM_DESC(min_interrupt_out_interval,
+		"Minimum interrupt out interval in ms");
 
 struct tranzport_cmd {
-    unsigned char cmd[8];
+	unsigned char cmd[8];
 };
 
-enum LightID {
-	LightRecord = 0,
-	LightTrackrec,
-	LightTrackmute,
-	LightTracksolo,
-	LightAnysolo,
-	LightLoop,
-	LightPunch
-	};
-
 /* Structure to hold all of our device specific stuff */
 
 struct usb_tranzport {
-	struct semaphore	sem;		/* locks this structure */
-	struct usb_interface*	intf;		/* save off the usb interface pointer */
+	struct semaphore sem;	/* locks this structure */
+	struct usb_interface *intf;	/* save off the usb interface pointer */
+	int open_count;		/* number of times this port opened */
+	struct tranzport_cmd (*ring_buffer)[RING_BUFFER_SIZE];
+	unsigned int ring_head;
+	unsigned int ring_tail;
+	wait_queue_head_t read_wait;
+	wait_queue_head_t write_wait;
+	unsigned char *interrupt_in_buffer;
+	struct usb_endpoint_descriptor *interrupt_in_endpoint;
+	struct urb *interrupt_in_urb;
+	int interrupt_in_interval;
+	size_t interrupt_in_endpoint_size;
+	int interrupt_in_running;
+	int interrupt_in_done;
+	char *interrupt_out_buffer;
+	struct usb_endpoint_descriptor *interrupt_out_endpoint;
+	struct urb *interrupt_out_urb;
+	int interrupt_out_interval;
+	size_t interrupt_out_endpoint_size;
+	int interrupt_out_busy;
 
-	int			open_count;	/* number of times this port has been opened */
+	/* Sysfs support */
 
-	struct tranzport_cmd	(*ring_buffer)[RING_BUFFER_SIZE]; /* just make c happy */
-	unsigned int		ring_head;
-	unsigned int		ring_tail;
-
-	wait_queue_head_t	read_wait;
-	wait_queue_head_t	write_wait;
-
-	unsigned char*		interrupt_in_buffer;
-	struct usb_endpoint_descriptor* interrupt_in_endpoint;
-	struct urb*		interrupt_in_urb;
-	int			interrupt_in_interval;
-	size_t	interrupt_in_endpoint_size;
-	int			interrupt_in_running;
-	int			interrupt_in_done;
-
-	char*			interrupt_out_buffer;
-	struct usb_endpoint_descriptor* interrupt_out_endpoint;
-	struct urb*		interrupt_out_urb;
-	int			interrupt_out_interval;
-	size_t	interrupt_out_endpoint_size;
-	int			interrupt_out_busy;
-
-	/* Sysfs and translation support */
-
-	int event; /* alternate interface to events */
-	int wheel; /* - for negative, 0 for none, + for positive */
-	unsigned char dump_state; /* 0 if disabled 1 if enabled */
-	unsigned char enable; /* 0 if disabled 1 if enabled */
-	unsigned char offline; /* if the device is out of range or asleep */
-	unsigned char compress_wheel; /* flag to compress wheel events */
-	unsigned char light; /* 7 bits used */
-	unsigned char last_cmd[8];
-	unsigned char last_input[8];
-	unsigned char screen[40]; // We'll also have cells
-
+	unsigned char enable;	/* 0 if disabled 1 if enabled */
+	unsigned char offline;	/* if the device is out of range or asleep */
+	unsigned char compress_wheel;	/* flag to compress wheel events */
 };
 
 /* prevent races between open() and disconnect() */
@@ -205,84 +175,39 @@
 			usb_kill_urb(dev->interrupt_out_urb);
 }
 
-// FIXME ~light not good enough or correct - need atomic set_bit
+#define show_int(value)							\
+  static ssize_t show_##value(struct device *dev,			\
+			      struct device_attribute *attr, char *buf)	\
+  {									\
+    struct usb_interface *intf = to_usb_interface(dev);			\
+    struct usb_tranzport *t = usb_get_intfdata(intf);			\
+    return sprintf(buf, "%d\n", t->value);			        \
+  }									\
+  static DEVICE_ATTR(value, S_IRUGO, show_##value, NULL);
 
-#define show_set_light(value)	\
-static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf)		\
-{									\
-	struct usb_interface *intf = to_usb_interface(dev);		\
-	struct usb_tranzport *t = usb_get_intfdata(intf);		\
-	enum LightID light = value;					\
-	int temp = (1 && (t->light & (1 << light)));			\
-	return sprintf(buf, "%d\n", temp );				\
-}									\
-static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)	\
-{									\
-	struct usb_interface *intf = to_usb_interface(dev);		\
-	struct usb_tranzport *t = usb_get_intfdata(intf);		\
-	int temp = simple_strtoul(buf, NULL, 10);			\
-	enum LightID light = (temp << value) & (t->light << value);	\
-	t->light = (t->light & ~light) ;				\
-	return count;							\
-}									\
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
+#define show_set_int(value)						\
+  static ssize_t show_##value(struct device *dev,			\
+			      struct device_attribute *attr, char *buf)	\
+  {									\
+    struct usb_interface *intf = to_usb_interface(dev);			\
+    struct usb_tranzport *t = usb_get_intfdata(intf);			\
+    return sprintf(buf, "%d\n", t->value);			        \
+  }									\
+  static ssize_t set_##value(struct device *dev,			\
+			     struct device_attribute *attr,		\
+			     const char *buf, size_t count)		\
+  {									\
+    struct usb_interface *intf = to_usb_interface(dev);			\
+    struct usb_tranzport *t = usb_get_intfdata(intf);			\
+    int temp = simple_strtoul(buf, NULL, 10);				\
+    t->value = temp;							\
+    return count;							\
+  }									\
+  static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
 
-show_set_light(LightRecord);
-show_set_light(LightTrackrec);
-show_set_light(LightTrackmute);
-show_set_light(LightTracksolo);
-show_set_light(LightAnysolo);
-show_set_light(LightLoop);
-show_set_light(LightPunch);
-
-
-#define show_set_int(value)	\
-static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf)		\
-{									\
-	struct usb_interface *intf = to_usb_interface(dev);		\
-	struct usb_tranzport *t = usb_get_intfdata(intf);			\
-									\
-	return sprintf(buf, "%d\n", t->value);			\
-}									\
-static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)	\
-{									\
-	struct usb_interface *intf = to_usb_interface(dev);		\
-	struct usb_tranzport *t = usb_get_intfdata(intf);			\
-	int temp = simple_strtoul(buf, NULL, 10);			\
-									\
-	t->value = temp;						\
-	return count;							\
-}									\
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
-
-show_set_int(enable);
-show_set_int(offline);
+show_int(enable);
+show_int(offline);
 show_set_int(compress_wheel);
-show_set_int(dump_state);
-show_set_int(wheel);
-show_set_int(event);
-
-#define show_set_cmd(value)	\
-static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf)		\
-{									\
-	struct usb_interface *intf = to_usb_interface(dev);		\
-	struct usb_tranzport *t = usb_get_intfdata(intf);			\
-									\
-	return sprintf(buf, "%d\n", t->value);			\
-}									\
-static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)	\
-{									\
-	struct usb_interface *intf = to_usb_interface(dev);		\
-	struct usb_tranzport *t = usb_get_intfdata(intf);			\
-	int temp = simple_strtoul(buf, NULL, 10);			\
-									\
-	t->value = temp;						\
-	return count;							\
-}									\
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
-
-
-
 
 /**
  *	usb_tranzport_delete
@@ -290,23 +215,10 @@
 static void usb_tranzport_delete(struct usb_tranzport *dev)
 {
 	usb_tranzport_abort_transfers(dev);
-	/*  This is just too twisted to be correct */
-	if(dev->intf != NULL) {
-	device_remove_file(&dev->intf->dev, &dev_attr_LightRecord);
-	device_remove_file(&dev->intf->dev, &dev_attr_LightTrackrec);
-	device_remove_file(&dev->intf->dev, &dev_attr_LightTrackmute);
-	device_remove_file(&dev->intf->dev, &dev_attr_LightTracksolo);
-	device_remove_file(&dev->intf->dev, &dev_attr_LightTrackmute);
-	device_remove_file(&dev->intf->dev, &dev_attr_LightAnysolo);
-	device_remove_file(&dev->intf->dev, &dev_attr_LightLoop);
-	device_remove_file(&dev->intf->dev, &dev_attr_LightPunch);
-	device_remove_file(&dev->intf->dev, &dev_attr_wheel);
-	device_remove_file(&dev->intf->dev, &dev_attr_enable);
-	device_remove_file(&dev->intf->dev, &dev_attr_event);
-	device_remove_file(&dev->intf->dev, &dev_attr_offline);
-	device_remove_file(&dev->intf->dev, &dev_attr_compress_wheel);
-
-	device_remove_file(&dev->intf->dev, &dev_attr_dump_state);
+	if (dev->intf != NULL) {
+		device_remove_file(&dev->intf->dev, &dev_attr_enable);
+		device_remove_file(&dev->intf->dev, &dev_attr_offline);
+		device_remove_file(&dev->intf->dev, &dev_attr_compress_wheel);
 	}
 
 	/* free data structures */
@@ -330,37 +242,56 @@
 
 	if (urb->status) {
 		if (urb->status == -ENOENT ||
-		    urb->status == -ECONNRESET ||
-		    urb->status == -ESHUTDOWN) {
+			urb->status == -ECONNRESET ||
+			urb->status == -ESHUTDOWN) {
 			goto exit;
 		} else {
-			dbg_info(&dev->intf->dev, "%s: nonzero status received: %d\n",
+			dbg_info(&dev->intf->dev,
+				 "%s: nonzero status received: %d\n",
 				 __func__, urb->status);
-			goto resubmit; /* maybe we can recover */
+			goto resubmit;	/* maybe we can recover */
 		}
 	}
 
 	if (urb->actual_length != 8) {
 		dev_warn(&dev->intf->dev,
-			 "Urb length was %d bytes!! Do something intelligent \n", urb->actual_length);
+			"Urb length was %d bytes!!"
+			"Do something intelligent \n",
+			 urb->actual_length);
 	} else {
-		dbg_info(&dev->intf->dev, "%s: received: %02x%02x%02x%02x%02x%02x%02x%02x\n",
-			 __func__, dev->interrupt_in_buffer[0],dev->interrupt_in_buffer[1],dev->interrupt_in_buffer[2],dev->interrupt_in_buffer[3],dev->interrupt_in_buffer[4],dev->interrupt_in_buffer[5],dev->interrupt_in_buffer[6],dev->interrupt_in_buffer[7]);
+		dbg_info(&dev->intf->dev,
+			 "%s: received: %02x%02x%02x%02x%02x%02x%02x%02x\n",
+			 __func__, dev->interrupt_in_buffer[0],
+			 dev->interrupt_in_buffer[1],
+			 dev->interrupt_in_buffer[2],
+			 dev->interrupt_in_buffer[3],
+			 dev->interrupt_in_buffer[4],
+			 dev->interrupt_in_buffer[5],
+			 dev->interrupt_in_buffer[6],
+			 dev->interrupt_in_buffer[7]);
 #if SUPPRESS_EXTRA_OFFLINE_EVENTS
-		if(dev->offline == 2 && dev->interrupt_in_buffer[1] == 0xff) { goto resubmit; }
-		if(dev->offline == 1 && dev->interrupt_in_buffer[1] == 0xff) { dev->offline = 2; goto resubmit; }
+	if (dev->offline == 2 && dev->interrupt_in_buffer[1] == 0xff)
+		goto resubmit;
+		if (dev->offline == 1 && dev->interrupt_in_buffer[1] == 0xff) {
+			dev->offline = 2;
+			goto resubmit;
+		}
 
-/* Always pass one offline event up the stack */
-		if(dev->offline > 0 && dev->interrupt_in_buffer[1] != 0xff) { dev->offline = 0; }
-		if(dev->offline == 0 && dev->interrupt_in_buffer[1] == 0xff) { dev->offline = 1; }
+		/* Always pass one offline event up the stack */
+		if (dev->offline > 0 && dev->interrupt_in_buffer[1] != 0xff)
+			dev->offline = 0;
+		if (dev->offline == 0 && dev->interrupt_in_buffer[1] == 0xff)
+			dev->offline = 1;
 
-#endif
-		dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n", __func__,dev->ring_head,dev->ring_tail);
+#endif	/* SUPPRESS_EXTRA_OFFLINE_EVENTS */
+	   dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n",
+		__func__, dev->ring_head, dev->ring_tail);
 
-		next_ring_head = (dev->ring_head+1) % ring_buffer_size;
+		next_ring_head = (dev->ring_head + 1) % ring_buffer_size;
 
 		if (next_ring_head != dev->ring_tail) {
-			memcpy(&((*dev->ring_buffer)[dev->ring_head]), dev->interrupt_in_buffer, urb->actual_length);
+			memcpy(&((*dev->ring_buffer)[dev->ring_head]),
+			       dev->interrupt_in_buffer, urb->actual_length);
 			dev->ring_head = next_ring_head;
 			retval = 0;
 			memset(dev->interrupt_in_buffer, 0, urb->actual_length);
@@ -373,7 +304,7 @@
 	}
 
 resubmit:
-	/* resubmit if we're still running */
+/* resubmit if we're still running */
 	if (dev->interrupt_in_running && dev->intf) {
 		retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC);
 		if (retval)
@@ -392,19 +323,17 @@
 static void usb_tranzport_interrupt_out_callback(struct urb *urb)
 {
 	struct usb_tranzport *dev = urb->context;
-
 	/* sync/async unlink faults aren't errors */
 	if (urb->status && !(urb->status == -ENOENT ||
-			     urb->status == -ECONNRESET ||
-			     urb->status == -ESHUTDOWN))
+				urb->status == -ECONNRESET ||
+				urb->status == -ESHUTDOWN))
 		dbg_info(&dev->intf->dev,
-			 "%s - nonzero write interrupt status received: %d\n",
-			 __func__, urb->status);
+			"%s - nonzero write interrupt status received: %d\n",
+			__func__, urb->status);
 
 	dev->interrupt_out_busy = 0;
 	wake_up_interruptible(&dev->write_wait);
 }
-
 /**
  *	usb_tranzport_open
  */
@@ -424,7 +353,7 @@
 
 	if (!interface) {
 		err("%s - error, can't find device for minor %d\n",
-		     __func__, subminor);
+			__func__, subminor);
 		retval = -ENODEV;
 		goto unlock_disconnect_exit;
 	}
@@ -453,14 +382,14 @@
 	dev->ring_head = 0;
 	dev->ring_tail = 0;
 	usb_fill_int_urb(dev->interrupt_in_urb,
-			 interface_to_usbdev(interface),
-			 usb_rcvintpipe(interface_to_usbdev(interface),
-					dev->interrupt_in_endpoint->bEndpointAddress),
-			 dev->interrupt_in_buffer,
-			 dev->interrupt_in_endpoint_size,
-			 usb_tranzport_interrupt_in_callback,
-			 dev,
-			 dev->interrupt_in_interval);
+			interface_to_usbdev(interface),
+			usb_rcvintpipe(interface_to_usbdev(interface),
+				dev->interrupt_in_endpoint->
+				bEndpointAddress),
+			dev->interrupt_in_buffer,
+			dev->interrupt_in_endpoint_size,
+			usb_tranzport_interrupt_in_callback, dev,
+			dev->interrupt_in_interval);
 
 	dev->interrupt_in_running = 1;
 	dev->interrupt_in_done = 0;
@@ -470,7 +399,8 @@
 
 	retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
 	if (retval) {
-		dev_err(&interface->dev, "Couldn't submit interrupt_in_urb %d\n", retval);
+		dev_err(&interface->dev,
+			"Couldn't submit interrupt_in_urb %d\n", retval);
 		dev->interrupt_in_running = 0;
 		dev->open_count = 0;
 		goto unlock_exit;
@@ -479,7 +409,6 @@
 	/* save device in the file's private structure */
 	file->private_data = dev;
 
-
 unlock_exit:
 	up(&dev->sem);
 
@@ -525,7 +454,9 @@
 
 	/* wait until write transfer is finished */
 	if (dev->interrupt_out_busy)
-		wait_event_interruptible_timeout(dev->write_wait, !dev->interrupt_out_busy, 2 * HZ);
+		wait_event_interruptible_timeout(dev->write_wait,
+						!dev->interrupt_out_busy,
+						2 * HZ);
 	usb_tranzport_abort_transfers(dev);
 	dev->open_count = 0;
 
@@ -539,37 +470,31 @@
 /**
  *	usb_tranzport_poll
  */
-static unsigned int usb_tranzport_poll(struct file *file, poll_table *wait)
+static unsigned int usb_tranzport_poll(struct file *file, poll_table * wait)
 {
 	struct usb_tranzport *dev;
 	unsigned int mask = 0;
-
 	dev = file->private_data;
-
 	poll_wait(file, &dev->read_wait, wait);
 	poll_wait(file, &dev->write_wait, wait);
-
 	if (dev->ring_head != dev->ring_tail)
 		mask |= POLLIN | POLLRDNORM;
 	if (!dev->interrupt_out_busy)
 		mask |= POLLOUT | POLLWRNORM;
-
 	return mask;
 }
-
 /**
  *	usb_tranzport_read
  */
-static ssize_t usb_tranzport_read(struct file *file, char __user *buffer, size_t count,
-			   loff_t *ppos)
+
+static ssize_t usb_tranzport_read(struct file *file, char __user *buffer,
+				size_t count, loff_t *ppos)
 {
 	struct usb_tranzport *dev;
 	int retval = 0;
-
 #if BUFFERED_READS
 	int c = 0;
 #endif
-
 #if COMPRESS_WHEEL_EVENTS
 	signed char oldwheel;
 	signed char newwheel;
@@ -577,7 +502,7 @@
 	int next_tail;
 #endif
 
-/* do I have such a thing as a null event? */
+	/* do I have such a thing as a null event? */
 
 	dev = file->private_data;
 
@@ -591,8 +516,7 @@
 		goto exit;
 	}
 
-	/* verify that the device wasn't unplugged */
-	if (dev->intf == NULL) {
+	/* verify that the device wasn't unplugged */ if (dev->intf == NULL) {
 		retval = -ENODEV;
 		err("No device or device unplugged %d\n", retval);
 		goto unlock_exit;
@@ -604,104 +528,149 @@
 			retval = -EAGAIN;
 			goto unlock_exit;
 		}
-		// atomic_cmp_exchange(&dev->interrupt_in_done,0,0);
-		dev->interrupt_in_done = 0 ; /* tiny race - FIXME: make atomic? */
-		retval = wait_event_interruptible(dev->read_wait, dev->interrupt_in_done);
-		if (retval < 0) {
+		/* tiny race - FIXME: make atomic? */
+		/* atomic_cmp_exchange(&dev->interrupt_in_done,0,0); */
+		dev->interrupt_in_done = 0;
+		retval = wait_event_interruptible(dev->read_wait,
+						  dev->interrupt_in_done);
+		if (retval < 0)
 			goto unlock_exit;
-		}
 	}
 
-	dbg_info(&dev->intf->dev, "%s: copying to userspace: %02x%02x%02x%02x%02x%02x%02x%02x\n",
-			 __func__, (*dev->ring_buffer)[dev->ring_tail].cmd[0],(*dev->ring_buffer)[dev->ring_tail].cmd[1],(*dev->ring_buffer)[dev->ring_tail].cmd[2],(*dev->ring_buffer)[dev->ring_tail].cmd[3],(*dev->ring_buffer)[dev->ring_tail].cmd[4],(*dev->ring_buffer)[dev->ring_tail].cmd[5],(*dev->ring_buffer)[dev->ring_tail].cmd[6],(*dev->ring_buffer)[dev->ring_tail].cmd[7]);
+	dbg_info(&dev->intf->dev,
+		"%s: copying to userspace: "
+		"%02x%02x%02x%02x%02x%02x%02x%02x\n",
+		 __func__,
+		 (*dev->ring_buffer)[dev->ring_tail].cmd[0],
+		 (*dev->ring_buffer)[dev->ring_tail].cmd[1],
+		 (*dev->ring_buffer)[dev->ring_tail].cmd[2],
+		 (*dev->ring_buffer)[dev->ring_tail].cmd[3],
+		 (*dev->ring_buffer)[dev->ring_tail].cmd[4],
+		 (*dev->ring_buffer)[dev->ring_tail].cmd[5],
+		 (*dev->ring_buffer)[dev->ring_tail].cmd[6],
+		 (*dev->ring_buffer)[dev->ring_tail].cmd[7]);
 
 #if BUFFERED_READS
-	   c = 0;
-	   while((c < count) && (dev->ring_tail != dev->ring_head)) {
+	c = 0;
+	while ((c < count) && (dev->ring_tail != dev->ring_head)) {
 
-/* This started off in the lower level service routine, and I moved it here. Then my brain died. Not done yet. */
 #if COMPRESS_WHEEL_EVENTS
 		next_tail = (dev->ring_tail+1) % ring_buffer_size;
-		if(dev->compress_wheel) cancompress = 1;
-		while(dev->ring_head != next_tail && cancompress == 1 ) {
+		if (dev->compress_wheel)
+			cancompress = 1;
+		while (dev->ring_head != next_tail && cancompress == 1) {
 			newwheel = (*dev->ring_buffer)[next_tail].cmd[6];
 			oldwheel = (*dev->ring_buffer)[dev->ring_tail].cmd[6];
-			// if both are wheel events, and no buttons have changes (FIXME, do I have to check?),
-			// and we are the same sign, we can compress +- 7F
-			// FIXME: saner check for overflow! - max of +- 7F
-			// FIXME the math is wrong for going in reverse, actually, as the midi spec doesn't allow signed chars
+			/* if both are wheel events, and
+			   no buttons have changes (FIXME, do I have to check?),
+			   and we are the same sign, we can compress +- 7F
+			*/
+			dbg_info(&dev->intf->dev,
+				"%s: trying to compress: "
+				"%02x%02x%02x%02x%02x%02x%02x%02x\n",
+				__func__,
+				(*dev->ring_buffer)[dev->ring_tail].cmd[0],
+				(*dev->ring_buffer)[dev->ring_tail].cmd[1],
+				(*dev->ring_buffer)[dev->ring_tail].cmd[2],
+				(*dev->ring_buffer)[dev->ring_tail].cmd[3],
+				(*dev->ring_buffer)[dev->ring_tail].cmd[4],
+				(*dev->ring_buffer)[dev->ring_tail].cmd[5],
+				(*dev->ring_buffer)[dev->ring_tail].cmd[6],
+				(*dev->ring_buffer)[dev->ring_tail].cmd[7]);
 
-	dbg_info(&dev->intf->dev, "%s: trying to compress: %02x%02x%02x%02x%02x %02x %02x %02x\n",
-			 __func__, (*dev->ring_buffer)[dev->ring_tail].cmd[0],(*dev->ring_buffer)[dev->ring_tail].cmd[1],(*dev->ring_buffer)[dev->ring_tail].cmd[2],(*dev->ring_buffer)[dev->ring_tail].cmd[3],(*dev->ring_buffer)[dev->ring_tail].cmd[4],(*dev->ring_buffer)[dev->ring_tail].cmd[5],(*dev->ring_buffer)[dev->ring_tail].cmd[6],(*dev->ring_buffer)[dev->ring_tail].cmd[7]);
-
-
-			if(((*dev->ring_buffer)[dev->ring_tail].cmd[6] != 0 &&
-			    (*dev->ring_buffer)[next_tail].cmd[6] != 0 ) &&
+			if (((*dev->ring_buffer)[dev->ring_tail].cmd[6] != 0 &&
+				(*dev->ring_buffer)[next_tail].cmd[6] != 0) &&
 				((newwheel > 0 && oldwheel > 0) ||
-				(newwheel < 0 && oldwheel < 0)) &&
-				((*dev->ring_buffer)[dev->ring_tail].cmd[2] == (*dev->ring_buffer)[next_tail].cmd[2]) &&
-				((*dev->ring_buffer)[dev->ring_tail].cmd[3] == (*dev->ring_buffer)[next_tail].cmd[3]) &&
-				((*dev->ring_buffer)[dev->ring_tail].cmd[4] == (*dev->ring_buffer)[next_tail].cmd[4]) &&
-				((*dev->ring_buffer)[dev->ring_tail].cmd[5] == (*dev->ring_buffer)[next_tail].cmd[5]))
- {
-	dbg_info(&dev->intf->dev, "%s: should compress: %02x%02x%02x%02x%02x%02x%02x%02x\n",
-			 __func__, (*dev->ring_buffer)[dev->ring_tail].cmd[0],(*dev->ring_buffer)[dev->ring_tail].cmd[1],(*dev->ring_buffer)[dev->ring_tail].cmd[2],(*dev->ring_buffer)[dev->ring_tail].cmd[3],(*dev->ring_buffer)[dev->ring_tail].cmd[4],(*dev->ring_buffer)[dev->ring_tail].cmd[5],(*dev->ring_buffer)[dev->ring_tail].cmd[6],(*dev->ring_buffer)[dev->ring_tail].cmd[7]);
-
+					(newwheel < 0 && oldwheel < 0)) &&
+				((*dev->ring_buffer)[dev->ring_tail].cmd[2] ==
+				(*dev->ring_buffer)[next_tail].cmd[2]) &&
+				((*dev->ring_buffer)[dev->ring_tail].cmd[3] ==
+				(*dev->ring_buffer)[next_tail].cmd[3]) &&
+				((*dev->ring_buffer)[dev->ring_tail].cmd[4] ==
+				(*dev->ring_buffer)[next_tail].cmd[4]) &&
+				((*dev->ring_buffer)[dev->ring_tail].cmd[5] ==
+				(*dev->ring_buffer)[next_tail].cmd[5])) {
+				dbg_info(&dev->intf->dev,
+					"%s: should compress: "
+					"%02x%02x%02x%02x%02x%02x%02x%02x\n",
+					__func__,
+					(*dev->ring_buffer)[dev->ring_tail].
+					cmd[0],
+					(*dev->ring_buffer)[dev->ring_tail].
+					cmd[1],
+					(*dev->ring_buffer)[dev->ring_tail].
+					cmd[2],
+					(*dev->ring_buffer)[dev->ring_tail].
+					cmd[3],
+					(*dev->ring_buffer)[dev->ring_tail].
+					cmd[4],
+					(*dev->ring_buffer)[dev->ring_tail].
+					cmd[5],
+					(*dev->ring_buffer)[dev->ring_tail].
+					cmd[6],
+					(*dev->ring_buffer)[dev->ring_tail].
+					cmd[7]);
 				newwheel += oldwheel;
-				if(oldwheel > 0 && !(newwheel > 0)) {
+				if (oldwheel > 0 && !(newwheel > 0)) {
 					newwheel = 0x7f;
 					cancompress = 0;
 				}
-				if(oldwheel < 0 && !(newwheel < 0)) {
+				if (oldwheel < 0 && !(newwheel < 0)) {
 					newwheel = 0x80;
 					cancompress = 0;
 				}
 
-				(*dev->ring_buffer)[next_tail].cmd[6] = newwheel;
+				(*dev->ring_buffer)[next_tail].cmd[6] =
+					newwheel;
 				dev->ring_tail = next_tail;
-				next_tail = (dev->ring_tail+1) % ring_buffer_size;
+				next_tail =
+					(dev->ring_tail + 1) % ring_buffer_size;
 			} else {
 				cancompress = 0;
 			}
 		}
 #endif /* COMPRESS_WHEEL_EVENTS */
-
-		if (copy_to_user(&buffer[c], &(*dev->ring_buffer)[dev->ring_tail], 8)) {
+		if (copy_to_user(
+				&buffer[c],
+				&(*dev->ring_buffer)[dev->ring_tail], 8)) {
 			retval = -EFAULT;
 			goto unlock_exit;
 		}
-
-		dev->ring_tail = (dev->ring_tail+1) % ring_buffer_size;
-		c+=8;
-		dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n", __func__,dev->ring_head,dev->ring_tail);
-	   }
-	   retval = c;
+		dev->ring_tail = (dev->ring_tail + 1) % ring_buffer_size;
+		c += 8;
+		dbg_info(&dev->intf->dev,
+			 "%s: head, tail are %x, %x\n",
+			 __func__, dev->ring_head, dev->ring_tail);
+	}
+	retval = c;
 
 #else
-	if (copy_to_user(buffer, &(*dev->ring_buffer)[dev->ring_tail], 8)) {
-		retval = -EFAULT;
-		goto unlock_exit;
-	}
+/*  if (copy_to_user(buffer, &(*dev->ring_buffer)[dev->ring_tail], 8)) { */
+	retval = -EFAULT;
+	goto unlock_exit;
+}
 
-	dev->ring_tail = (dev->ring_tail+1) % ring_buffer_size;
-	dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n", __func__,dev->ring_head,dev->ring_tail);
+dev->ring_tail = (dev->ring_tail + 1) % ring_buffer_size;
+dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n",
+	 __func__, dev->ring_head, dev->ring_tail);
 
-	retval = 8;
+retval = 8;
 #endif /* BUFFERED_READS */
 
 unlock_exit:
-	/* unlock the device */
-	up(&dev->sem);
+/* unlock the device */
+up(&dev->sem);
 
 exit:
-	return retval;
+return retval;
 }
 
 /**
  *	usb_tranzport_write
  */
-static ssize_t usb_tranzport_write(struct file *file, const char __user *buffer,
-			    size_t count, loff_t *ppos)
+static ssize_t usb_tranzport_write(struct file *file,
+				const char __user *buffer, size_t count,
+				loff_t *ppos)
 {
 	struct usb_tranzport *dev;
 	size_t bytes_to_write;
@@ -718,7 +687,6 @@
 		retval = -ERESTARTSYS;
 		goto exit;
 	}
-
 	/* verify that the device wasn't unplugged */
 	if (dev->intf == NULL) {
 		retval = -ENODEV;
@@ -732,18 +700,24 @@
 			retval = -EAGAIN;
 			goto unlock_exit;
 		}
-		retval = wait_event_interruptible(dev->write_wait, !dev->interrupt_out_busy);
-		if (retval < 0) {
+		retval = wait_event_interruptible(dev->write_wait,
+						!dev->interrupt_out_busy);
+		if (retval < 0)
 			goto unlock_exit;
-		}
 	}
 
 	/* write the data into interrupt_out_buffer from userspace */
-	bytes_to_write = min(count, write_buffer_size*dev->interrupt_out_endpoint_size);
+	bytes_to_write = min(count,
+			write_buffer_size *
+			dev->interrupt_out_endpoint_size);
 	if (bytes_to_write < count)
-		dev_warn(&dev->intf->dev, "Write buffer overflow, %zd bytes dropped\n",count-bytes_to_write);
+		dev_warn(&dev->intf->dev,
+			"Write buffer overflow, %zd bytes dropped\n",
+			count - bytes_to_write);
 
-	dbg_info(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n", __func__, count, bytes_to_write);
+	dbg_info(&dev->intf->dev,
+		"%s: count = %zd, bytes_to_write = %zd\n", __func__,
+		count, bytes_to_write);
 
 	if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) {
 		retval = -EFAULT;
@@ -757,14 +731,13 @@
 
 	/* send off the urb */
 	usb_fill_int_urb(dev->interrupt_out_urb,
-			 interface_to_usbdev(dev->intf),
-			 usb_sndintpipe(interface_to_usbdev(dev->intf),
-					dev->interrupt_out_endpoint->bEndpointAddress),
-			 dev->interrupt_out_buffer,
-			 bytes_to_write,
-			 usb_tranzport_interrupt_out_callback,
-			 dev,
-			 dev->interrupt_out_interval);
+			interface_to_usbdev(dev->intf),
+			usb_sndintpipe(interface_to_usbdev(dev->intf),
+				dev->interrupt_out_endpoint->
+				bEndpointAddress),
+			dev->interrupt_out_buffer, bytes_to_write,
+			usb_tranzport_interrupt_out_callback, dev,
+			dev->interrupt_out_interval);
 
 	dev->interrupt_out_busy = 1;
 	wmb();
@@ -787,12 +760,12 @@
 
 /* file operations needed when we register this driver */
 static const struct file_operations usb_tranzport_fops = {
-	.owner =	THIS_MODULE,
-	.read  =	usb_tranzport_read,
-	.write =	usb_tranzport_write,
-	.open =		usb_tranzport_open,
-	.release =	usb_tranzport_release,
-	.poll =		usb_tranzport_poll,
+	.owner = THIS_MODULE,
+	.read = usb_tranzport_read,
+	.write = usb_tranzport_write,
+	.open = usb_tranzport_open,
+	.release = usb_tranzport_release,
+	.poll = usb_tranzport_poll,
 };
 
 /*
@@ -800,20 +773,19 @@
  * and to have the device registered with the driver core
  */
 static struct usb_class_driver usb_tranzport_class = {
-	.name =		"tranzport%d",
-	.fops =		&usb_tranzport_fops,
-	.minor_base =	USB_TRANZPORT_MINOR_BASE,
+	.name = "tranzport%d",
+	.fops = &usb_tranzport_fops,
+	.minor_base = USB_TRANZPORT_MINOR_BASE,
 };
 
-
 /**
  *	usb_tranzport_probe
  *
  *	Called by the usb core when a new device is connected that it thinks
  *	this driver might be interested in.
  */
-static int usb_tranzport_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
+static int usb_tranzport_probe(struct usb_interface *intf,
+			       const struct usb_device_id *id) {
 	struct usb_device *udev = interface_to_usbdev(intf);
 	struct usb_tranzport *dev = NULL;
 	struct usb_host_interface *iface_desc;
@@ -824,7 +796,7 @@
 
 	/* allocate memory for our device state and intialize it */
 
-	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (dev == NULL) {
 		dev_err(&intf->dev, "Out of memory\n");
 		goto exit;
@@ -851,25 +823,33 @@
 		goto error;
 	}
 	if (dev->interrupt_out_endpoint == NULL)
-		dev_warn(&intf->dev, "Interrupt out endpoint not found (using control endpoint instead)\n");
+		dev_warn(&intf->dev,
+			"Interrupt out endpoint not found"
+			"(using control endpoint instead)\n");
 
-
-	dev->interrupt_in_endpoint_size = le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize);
+	dev->interrupt_in_endpoint_size =
+	    le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize);
 
 	if (dev->interrupt_in_endpoint_size != 8)
-	    dev_warn(&intf->dev, "Interrupt in endpoint size is not 8!\n");
+		dev_warn(&intf->dev, "Interrupt in endpoint size is not 8!\n");
 
-	if(ring_buffer_size == 0) { ring_buffer_size = RING_BUFFER_SIZE; }
-	true_size = min(ring_buffer_size,RING_BUFFER_SIZE);
-	/* FIXME - there are more usb_alloc routines for dma correctness. Needed? */
+	if (ring_buffer_size == 0)
+		ring_buffer_size = RING_BUFFER_SIZE;
+	true_size = min(ring_buffer_size, RING_BUFFER_SIZE);
 
-	dev->ring_buffer = kmalloc((true_size*sizeof(struct tranzport_cmd))+8, GFP_KERNEL);
+	/* FIXME - there are more usb_alloc routines for dma correctness.
+	   Needed? */
+
+	dev->ring_buffer =
+	    kmalloc((true_size * sizeof(struct tranzport_cmd)) + 8, GFP_KERNEL);
 
 	if (!dev->ring_buffer) {
-		dev_err(&intf->dev, "Couldn't allocate ring_buffer of size %d\n",true_size);
+		dev_err(&intf->dev,
+			"Couldn't allocate ring_buffer size %d\n", true_size);
 		goto error;
 	}
-	dev->interrupt_in_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL);
+	dev->interrupt_in_buffer =
+	    kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL);
 	if (!dev->interrupt_in_buffer) {
 		dev_err(&intf->dev, "Couldn't allocate interrupt_in_buffer\n");
 		goto error;
@@ -879,13 +859,18 @@
 		dev_err(&intf->dev, "Couldn't allocate interrupt_in_urb\n");
 		goto error;
 	}
-	dev->interrupt_out_endpoint_size = dev->interrupt_out_endpoint ? le16_to_cpu(dev->interrupt_out_endpoint->wMaxPacketSize) :
-									 udev->descriptor.bMaxPacketSize0;
+	dev->interrupt_out_endpoint_size =
+	    dev->interrupt_out_endpoint ?
+	    le16_to_cpu(dev->interrupt_out_endpoint->wMaxPacketSize) :
+	    udev->descriptor.bMaxPacketSize0;
 
-	if (dev->interrupt_out_endpoint_size !=8)
-		dev_warn(&intf->dev, "Interrupt out endpoint size is not 8!)\n");
+	if (dev->interrupt_out_endpoint_size != 8)
+		dev_warn(&intf->dev,
+			 "Interrupt out endpoint size is not 8!)\n");
 
-	dev->interrupt_out_buffer = kmalloc(write_buffer_size*dev->interrupt_out_endpoint_size, GFP_KERNEL);
+	dev->interrupt_out_buffer =
+	    kmalloc(write_buffer_size * dev->interrupt_out_endpoint_size,
+		    GFP_KERNEL);
 	if (!dev->interrupt_out_buffer) {
 		dev_err(&intf->dev, "Couldn't allocate interrupt_out_buffer\n");
 		goto error;
@@ -895,9 +880,18 @@
 		dev_err(&intf->dev, "Couldn't allocate interrupt_out_urb\n");
 		goto error;
 	}
-	dev->interrupt_in_interval = min_interrupt_in_interval > dev->interrupt_in_endpoint->bInterval ? min_interrupt_in_interval : dev->interrupt_in_endpoint->bInterval;
-	if (dev->interrupt_out_endpoint)
-		dev->interrupt_out_interval = min_interrupt_out_interval > dev->interrupt_out_endpoint->bInterval ? min_interrupt_out_interval : dev->interrupt_out_endpoint->bInterval;
+	dev->interrupt_in_interval =
+	    min_interrupt_in_interval >
+	    dev->interrupt_in_endpoint->bInterval ? min_interrupt_in_interval
+	    : dev->interrupt_in_endpoint->bInterval;
+
+	if (dev->interrupt_out_endpoint) {
+		dev->interrupt_out_interval =
+		    min_interrupt_out_interval >
+		    dev->interrupt_out_endpoint->bInterval ?
+		    min_interrupt_out_interval :
+		    dev->interrupt_out_endpoint->bInterval;
+	}
 
 	/* we can register the device now, as it is ready */
 	usb_set_intfdata(intf, dev);
@@ -905,35 +899,33 @@
 	retval = usb_register_dev(intf, &usb_tranzport_class);
 	if (retval) {
 		/* something prevented us from registering this driver */
-		dev_err(&intf->dev, "Not able to get a minor for this device.\n");
+		dev_err(&intf->dev,
+			"Not able to get a minor for this device.\n");
 		usb_set_intfdata(intf, NULL);
 		goto error;
 	}
 
-	if((retval = device_create_file(&intf->dev, &dev_attr_LightRecord))) goto error;
-	if((retval = device_create_file(&intf->dev, &dev_attr_LightTrackrec))) goto error;
-	if((retval = device_create_file(&intf->dev, &dev_attr_LightTrackmute))) goto error;
-	if((retval = device_create_file(&intf->dev, &dev_attr_LightTracksolo))) goto error;
-	if((retval = device_create_file(&intf->dev, &dev_attr_LightAnysolo))) goto error;
-	if((retval = device_create_file(&intf->dev, &dev_attr_LightLoop))) goto error;
-	if((retval = device_create_file(&intf->dev, &dev_attr_LightPunch))) goto error;
-	if((retval = device_create_file(&intf->dev, &dev_attr_wheel))) goto error;
-	if((retval = device_create_file(&intf->dev, &dev_attr_event))) goto error;
-	if((retval = device_create_file(&intf->dev, &dev_attr_dump_state))) goto error;
-	if((retval = device_create_file(&intf->dev, &dev_attr_compress_wheel))) goto error;
-	if((retval = device_create_file(&intf->dev, &dev_attr_enable))) goto error;
-	if((retval = device_create_file(&intf->dev, &dev_attr_offline))) goto error;
+	retval = device_create_file(&intf->dev, &dev_attr_compress_wheel);
+	if (retval)
+		goto error;
+	retval = device_create_file(&intf->dev, &dev_attr_enable);
+	if (retval)
+		goto error;
+	retval = device_create_file(&intf->dev, &dev_attr_offline);
+	if (retval)
+		goto error;
 
 	/* let the user know what node this device is now attached to */
-	dev_info(&intf->dev, "Tranzport Device #%d now attached to major %d minor %d\n",
-		(intf->minor - USB_TRANZPORT_MINOR_BASE), USB_MAJOR, intf->minor);
+	dev_info(&intf->dev,
+		"Tranzport Device #%d now attached to major %d minor %d\n",
+		(intf->minor - USB_TRANZPORT_MINOR_BASE), USB_MAJOR,
+		intf->minor);
 
 exit:
 	return retval;
 
 error:
 	usb_tranzport_delete(dev);
-
 	return retval;
 }
 
@@ -966,15 +958,15 @@
 	mutex_unlock(&disconnect_mutex);
 
 	dev_info(&intf->dev, "Tranzport Surface #%d now disconnected\n",
-		 (minor - USB_TRANZPORT_MINOR_BASE));
+		(minor - USB_TRANZPORT_MINOR_BASE));
 }
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver usb_tranzport_driver = {
-	.name =		"tranzport",
-	.probe =	usb_tranzport_probe,
-	.disconnect =	usb_tranzport_disconnect,
-	.id_table =	usb_tranzport_table,
+	.name = "tranzport",
+	.probe = usb_tranzport_probe,
+	.disconnect = usb_tranzport_disconnect,
+	.id_table = usb_tranzport_table,
 };
 
 /**
@@ -987,14 +979,14 @@
 	/* register this driver with the USB subsystem */
 	retval = usb_register(&usb_tranzport_driver);
 	if (retval)
-		err("usb_register failed for the "__FILE__" driver. Error number %d\n", retval);
-
+		err("usb_register failed for the " __FILE__
+			" driver. Error number %d\n", retval);
 	return retval;
 }
-
 /**
  *	usb_tranzport_exit
  */
+
 static void __exit usb_tranzport_exit(void)
 {
 	/* deregister this driver with the USB subsystem */
@@ -1003,4 +995,3 @@
 
 module_init(usb_tranzport_init);
 module_exit(usb_tranzport_exit);
-
diff --git a/drivers/staging/go7007/Kconfig b/drivers/staging/go7007/Kconfig
index f2cf7f6..ca6ade6 100644
--- a/drivers/staging/go7007/Kconfig
+++ b/drivers/staging/go7007/Kconfig
@@ -10,7 +10,7 @@
 	select CRC32
 	default N
 	---help---
-	  This is a video4linux driver for some wierd device...
+	  This is a video4linux driver for some weird device...
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called go7007
@@ -20,7 +20,7 @@
 	depends on VIDEO_GO7007 && USB
 	default N
 	---help---
-	  This is a video4linux driver for some wierd device...
+	  This is a video4linux driver for some weird device...
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called go7007-usb
diff --git a/drivers/staging/go7007/go7007-v4l2.c b/drivers/staging/go7007/go7007-v4l2.c
index 868edb6..06cacd3 100644
--- a/drivers/staging/go7007/go7007-v4l2.c
+++ b/drivers/staging/go7007/go7007-v4l2.c
@@ -1827,7 +1827,6 @@
 
 static struct video_device go7007_template = {
 	.name		= "go7007",
-	.vfl_type	= VID_TYPE_CAPTURE,
 	.fops		= &go7007_fops,
 	.minor		= -1,
 	.release	= go7007_vfl_release,
diff --git a/drivers/staging/go7007/s2250-board.c b/drivers/staging/go7007/s2250-board.c
index fb6845e..d333ea2 100644
--- a/drivers/staging/go7007/s2250-board.c
+++ b/drivers/staging/go7007/s2250-board.c
@@ -149,7 +149,7 @@
 static int write_reg(struct i2c_client *client, u8 reg, u8 value)
 {
 	struct go7007 *go = i2c_get_adapdata(client->adapter);
-	struct go7007_usb *usb = go->hpi_context;
+	struct go7007_usb *usb;
 	int rc;
 	int dev_addr = client->addr;
 	u8 *buf;
@@ -164,8 +164,10 @@
 	if (buf == NULL)
 		return -ENOMEM;
 
+	usb = go->hpi_context;
 	if (down_interruptible(&usb->i2c_lock) != 0) {
 		printk(KERN_INFO "i2c lock failed\n");
+		kfree(buf);
 		return -EINTR;
 	}
 	rc = go7007_usb_vendor_request(go, 0x55, dev_addr,
@@ -181,7 +183,7 @@
 static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val)
 {
 	struct go7007 *go = i2c_get_adapdata(client->adapter);
-	struct go7007_usb *usb = go->hpi_context;
+	struct go7007_usb *usb;
 	u8 *buf;
 	struct s2250 *dec = i2c_get_clientdata(client);
 
@@ -200,6 +202,7 @@
 
 	memset(buf, 0xcd, 6);
 
+	usb = go->hpi_context;
 	if (down_interruptible(&usb->i2c_lock) != 0) {
 		printk(KERN_INFO "i2c lock failed\n");
 		return -EINTR;
diff --git a/drivers/staging/heci/Kconfig b/drivers/staging/heci/Kconfig
new file mode 100644
index 0000000..ae8d588
--- /dev/null
+++ b/drivers/staging/heci/Kconfig
@@ -0,0 +1,6 @@
+config HECI
+	tristate "Intel Management Engine Interface (MEI) Support"
+	---help---
+	  The Intel Management Engine Interface (Intel MEI) driver allows
+	  applications to access the Active Management Technology
+	  firmware and other Management Engine sub-systems.
diff --git a/drivers/staging/heci/Makefile b/drivers/staging/heci/Makefile
new file mode 100644
index 0000000..0524856
--- /dev/null
+++ b/drivers/staging/heci/Makefile
@@ -0,0 +1,9 @@
+obj-$(CONFIG_HECI)	+= heci.o
+
+heci-objs :=				\
+		heci_init.o		\
+		interrupt.o		\
+		heci_interface.o	\
+		io_heci.o		\
+		heci_main.o
+
diff --git a/drivers/staging/heci/TODO b/drivers/staging/heci/TODO
new file mode 100644
index 0000000..f86715d
--- /dev/null
+++ b/drivers/staging/heci/TODO
@@ -0,0 +1,6 @@
+TODO:
+	- fix user/kernel pointer mess in the ioctl handlers as pointed
+	  out by sparse.
+	- resolve the ioctls and see if most of them can just be simple
+	  sysfs files
+	- fix locking issues that sparse points out at the least.
diff --git a/drivers/staging/heci/heci.h b/drivers/staging/heci/heci.h
new file mode 100644
index 0000000..14192e0
--- /dev/null
+++ b/drivers/staging/heci/heci.h
@@ -0,0 +1,176 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * 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,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * 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 MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ *
+ */
+
+#ifndef _HECI_H_
+#define _HECI_H_
+
+#include <linux/version.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/module.h>
+#include <linux/aio.h>
+#include <linux/types.h>
+#include "heci_data_structures.h"
+
+extern const struct guid heci_pthi_guid;
+extern const struct guid heci_wd_guid;
+extern const __u8 heci_start_wd_params[];
+extern const __u8 heci_stop_wd_params[];
+extern const __u8 heci_wd_state_independence_msg[3][4];
+
+/*
+ * heci device ID
+ */
+#define    HECI_DEV_ID_82946GZ    0x2974  /* 82946GZ/GL */
+#define    HECI_DEV_ID_82G35      0x2984  /* 82G35 Express */
+#define    HECI_DEV_ID_82Q965     0x2994  /* 82Q963/Q965 */
+#define    HECI_DEV_ID_82G965     0x29A4  /* 82P965/G965 */
+
+#define    HECI_DEV_ID_82GM965    0x2A04  /* Mobile PM965/GM965 */
+#define    HECI_DEV_ID_82GME965   0x2A14  /* Mobile GME965/GLE960 */
+
+#define    HECI_DEV_ID_ICH9_82Q35 0x29B4  /* 82Q35 Express */
+#define    HECI_DEV_ID_ICH9_82G33 0x29C4  /* 82G33/G31/P35/P31 Express */
+#define    HECI_DEV_ID_ICH9_82Q33 0x29D4  /* 82Q33 Express */
+#define    HECI_DEV_ID_ICH9_82X38 0x29E4  /* 82X38/X48 Express */
+#define    HECI_DEV_ID_ICH9_3200  0x29F4  /* 3200/3210 Server */
+
+#define    HECI_DEV_ID_ICH9_6     0x28B4  /* Bearlake */
+#define    HECI_DEV_ID_ICH9_7     0x28C4  /* Bearlake */
+#define    HECI_DEV_ID_ICH9_8     0x28D4  /* Bearlake */
+#define    HECI_DEV_ID_ICH9_9     0x28E4  /* Bearlake */
+#define    HECI_DEV_ID_ICH9_10    0x28F4  /* Bearlake */
+
+#define    HECI_DEV_ID_ICH9M_1    0x2A44  /* Cantiga */
+#define    HECI_DEV_ID_ICH9M_2    0x2A54  /* Cantiga */
+#define    HECI_DEV_ID_ICH9M_3    0x2A64  /* Cantiga */
+#define    HECI_DEV_ID_ICH9M_4    0x2A74  /* Cantiga */
+
+#define    HECI_DEV_ID_ICH10_1    0x2E04  /* Eaglelake */
+#define    HECI_DEV_ID_ICH10_2    0x2E14  /* Eaglelake */
+#define    HECI_DEV_ID_ICH10_3    0x2E24  /* Eaglelake */
+#define    HECI_DEV_ID_ICH10_4    0x2E34  /* Eaglelake */
+
+/*
+ * heci init function prototypes
+ */
+struct iamt_heci_device *init_heci_device(struct pci_dev *pdev);
+void heci_reset(struct iamt_heci_device *dev, int interrupts);
+int heci_hw_init(struct iamt_heci_device *dev);
+int heci_task_initialize_clients(void *data);
+int heci_initialize_clients(struct iamt_heci_device *dev);
+struct heci_file_private *heci_alloc_file_private(struct file *file);
+int heci_disconnect_host_client(struct iamt_heci_device *dev,
+				struct heci_file_private *file_ext);
+void heci_initialize_list(struct io_heci_list *list,
+			  struct iamt_heci_device *dev);
+void heci_flush_list(struct io_heci_list *list,
+		     struct heci_file_private *file_ext);
+void heci_flush_queues(struct iamt_heci_device *dev,
+		       struct heci_file_private *file_ext);
+
+void heci_remove_client_from_file_list(struct iamt_heci_device *dev,
+				       __u8 host_client_id);
+
+/*
+ *  interrupt function prototype
+ */
+irqreturn_t heci_isr_interrupt(int irq, void *dev_id);
+
+void heci_wd_timer(unsigned long data);
+
+/*
+ *  input output function prototype
+ */
+int heci_ioctl_get_version(struct iamt_heci_device *dev, int if_num,
+			   struct heci_message_data __user *u_msg,
+			   struct heci_message_data k_msg,
+			   struct heci_file_private *file_ext);
+
+int heci_ioctl_connect_client(struct iamt_heci_device *dev, int if_num,
+			      struct heci_message_data __user *u_msg,
+			      struct heci_message_data k_msg,
+			      struct file *file);
+
+int heci_ioctl_wd(struct iamt_heci_device *dev, int if_num,
+		  struct heci_message_data k_msg,
+		  struct heci_file_private *file_ext);
+
+int heci_ioctl_bypass_wd(struct iamt_heci_device *dev, int if_num,
+		  struct heci_message_data k_msg,
+		  struct heci_file_private *file_ext);
+
+int heci_start_read(struct iamt_heci_device *dev, int if_num,
+		    struct heci_file_private *file_ext);
+
+int pthi_write(struct iamt_heci_device *dev,
+	       struct heci_cb_private *priv_cb);
+
+int pthi_read(struct iamt_heci_device *dev, int if_num, struct file *file,
+	      char __user *ubuf, size_t length, loff_t *offset);
+
+struct heci_cb_private *find_pthi_read_list_entry(
+			struct iamt_heci_device *dev,
+			struct file *file);
+
+void run_next_iamthif_cmd(struct iamt_heci_device *dev);
+
+void heci_free_cb_private(struct heci_cb_private *priv_cb);
+
+/**
+ * heci_fe_same_id - tell if file private data have same id
+ *
+ * @fe1: private data of 1. file object
+ * @fe2: private data of 2. file object
+ *
+ * returns  !=0 - if ids are the same, 0 - if differ.
+ */
+static inline int heci_fe_same_id(const struct heci_file_private *fe1,
+				  const struct heci_file_private *fe2)
+{
+	return ((fe1->host_client_id == fe2->host_client_id)
+		&& (fe1->me_client_id == fe2->me_client_id));
+}
+
+#endif /* _HECI_H_ */
diff --git a/drivers/staging/heci/heci_data_structures.h b/drivers/staging/heci/heci_data_structures.h
new file mode 100644
index 0000000..575e8f8
--- /dev/null
+++ b/drivers/staging/heci/heci_data_structures.h
@@ -0,0 +1,530 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * 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,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * 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 MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ *
+ */
+
+#ifndef _HECI_DATA_STRUCTURES_H_
+#define _HECI_DATA_STRUCTURES_H_
+
+#include <linux/version.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/module.h>
+#include <linux/aio.h>
+#include <linux/types.h>
+
+/*
+ * error code definition
+ */
+#define     ESLOTS_OVERFLOW              1
+#define     ECORRUPTED_MESSAGE_HEADER    1000
+#define     ECOMPLETE_MESSAGE            1001
+
+#define     HECI_FC_MESSAGE_RESERVED_LENGTH           5
+
+/*
+ * Number of queue lists used by this driver
+ */
+#define HECI_IO_LISTS_NUMBER        7
+
+/*
+ * Maximum transmission unit (MTU) of heci messages
+ */
+#define IAMTHIF_MTU 4160
+
+
+/*
+ * HECI HW Section
+ */
+
+/* HECI registers */
+/* H_CB_WW - Host Circular Buffer (CB) Write Window register */
+#define H_CB_WW    0
+/* H_CSR - Host Control Status register */
+#define H_CSR      4
+/* ME_CB_RW - ME Circular Buffer Read Window register (read only) */
+#define ME_CB_RW   8
+/* ME_CSR_HA - ME Control Status Host Access register (read only) */
+#define ME_CSR_HA  0xC
+
+
+/* register bits of H_CSR (Host Control Status register) */
+/* Host Circular Buffer Depth - maximum number of 32-bit entries in CB */
+#define H_CBD             0xFF000000
+/* Host Circular Buffer Write Pointer */
+#define H_CBWP            0x00FF0000
+/* Host Circular Buffer Read Pointer */
+#define H_CBRP            0x0000FF00
+/* Host Reset */
+#define H_RST             0x00000010
+/* Host Ready */
+#define H_RDY             0x00000008
+/* Host Interrupt Generate */
+#define H_IG              0x00000004
+/* Host Interrupt Status */
+#define H_IS              0x00000002
+/* Host Interrupt Enable */
+#define H_IE              0x00000001
+
+
+/* register bits of ME_CSR_HA (ME Control Status Host Access register) */
+/* ME CB (Circular Buffer) Depth HRA (Host Read Access)
+ *  - host read only access to ME_CBD */
+#define ME_CBD_HRA        0xFF000000
+/* ME CB Write Pointer HRA - host read only access to ME_CBWP */
+#define ME_CBWP_HRA       0x00FF0000
+/* ME CB Read Pointer HRA - host read only access to ME_CBRP */
+#define ME_CBRP_HRA       0x0000FF00
+/* ME Reset HRA - host read only access to ME_RST */
+#define ME_RST_HRA        0x00000010
+/* ME Ready HRA - host read only access to ME_RDY */
+#define ME_RDY_HRA        0x00000008
+/* ME Interrupt Generate HRA - host read only access to ME_IG */
+#define ME_IG_HRA         0x00000004
+/* ME Interrupt Status HRA - host read only access to ME_IS */
+#define ME_IS_HRA         0x00000002
+/* ME Interrupt Enable HRA - host read only access to ME_IE */
+#define ME_IE_HRA         0x00000001
+
+#define HECI_MINORS_BASE	1
+#define HECI_MINORS_COUNT	1
+
+#define  HECI_MINOR_NUMBER	1
+#define  HECI_MAX_OPEN_HANDLE_COUNT	253
+
+/*
+ * debug kernel print macro define
+ */
+extern int heci_debug;
+
+#define DBG(format, arg...) do { \
+	if (heci_debug) \
+		printk(KERN_INFO "heci: %s: " format, __func__, ## arg); \
+} while (0)
+
+
+/*
+ * time to wait HECI become ready after init
+ */
+#define HECI_INTEROP_TIMEOUT    (HZ * 7)
+
+/*
+ * watch dog definition
+ */
+#define HECI_WATCHDOG_DATA_SIZE         16
+#define HECI_START_WD_DATA_SIZE         20
+#define HECI_WD_PARAMS_SIZE             4
+#define HECI_WD_STATE_INDEPENDENCE_MSG_SENT       (1 << 0)
+
+#define HECI_WD_HOST_CLIENT_ID          1
+#define HECI_IAMTHIF_HOST_CLIENT_ID     2
+
+struct guid {
+	__u32 data1;
+	__u16 data2;
+	__u16 data3;
+	__u8 data4[8];
+};
+
+/* File state */
+enum file_state {
+	HECI_FILE_INITIALIZING = 0,
+	HECI_FILE_CONNECTING,
+	HECI_FILE_CONNECTED,
+	HECI_FILE_DISCONNECTING,
+	HECI_FILE_DISCONNECTED
+};
+
+/* HECI device states */
+enum heci_states {
+	HECI_INITIALIZING = 0,
+	HECI_ENABLED,
+	HECI_RESETING,
+	HECI_DISABLED,
+	HECI_RECOVERING_FROM_RESET,
+	HECI_POWER_DOWN,
+	HECI_POWER_UP
+};
+
+enum iamthif_states {
+	HECI_IAMTHIF_IDLE,
+	HECI_IAMTHIF_WRITING,
+	HECI_IAMTHIF_FLOW_CONTROL,
+	HECI_IAMTHIF_READING,
+	HECI_IAMTHIF_READ_COMPLETE
+};
+
+enum heci_file_transaction_states {
+	HECI_IDLE,
+	HECI_WRITING,
+	HECI_WRITE_COMPLETE,
+	HECI_FLOW_CONTROL,
+	HECI_READING,
+	HECI_READ_COMPLETE
+};
+
+/* HECI CB */
+enum heci_cb_major_types {
+	HECI_READ = 0,
+	HECI_WRITE,
+	HECI_IOCTL,
+	HECI_OPEN,
+	HECI_CLOSE
+};
+
+/* HECI user data struct */
+struct heci_message_data {
+	__u32 size;
+	char *data;
+} __attribute__((packed));
+
+#define HECI_CONNECT_TIMEOUT             3	/* at least 2 seconds */
+
+#define IAMTHIF_STALL_TIMER              12	/* seconds */
+#define IAMTHIF_READ_TIMER               15	/* seconds */
+
+struct heci_cb_private {
+	struct list_head cb_list;
+	enum heci_cb_major_types major_file_operations;
+	void *file_private;
+	struct heci_message_data request_buffer;
+	struct heci_message_data response_buffer;
+	unsigned long information;
+	unsigned long read_time;
+	struct file *file_object;
+};
+
+/* Private file struct */
+struct heci_file_private {
+	struct list_head link;
+	struct file *file;
+	enum file_state state;
+	wait_queue_head_t tx_wait;
+	wait_queue_head_t rx_wait;
+	wait_queue_head_t wait;
+	spinlock_t file_lock; /* file lock */
+	spinlock_t read_io_lock; /* read lock */
+	spinlock_t write_io_lock; /* write lock */
+	int read_pending;
+	int status;
+	/* ID of client connected */
+	__u8 host_client_id;
+	__u8 me_client_id;
+	__u8 flow_ctrl_creds;
+	__u8 timer_count;
+	enum heci_file_transaction_states reading_state;
+	enum heci_file_transaction_states writing_state;
+	int sm_state;
+	struct heci_cb_private *read_cb;
+};
+
+struct io_heci_list {
+	struct heci_cb_private heci_cb;
+	int status;
+	struct iamt_heci_device *device_extension;
+};
+
+struct heci_driver_version {
+	__u8 major;
+	__u8 minor;
+	__u8 hotfix;
+	__u16 build;
+} __attribute__((packed));
+
+
+struct heci_client {
+	__u32 max_msg_length;
+	__u8 protocol_version;
+} __attribute__((packed));
+
+/*
+ *  HECI BUS Interface Section
+ */
+struct heci_msg_hdr {
+	__u32 me_addr:8;
+	__u32 host_addr:8;
+	__u32 length:9;
+	__u32 reserved:6;
+	__u32 msg_complete:1;
+} __attribute__((packed));
+
+
+struct hbm_cmd {
+	__u8 cmd:7;
+	__u8 is_response:1;
+} __attribute__((packed));
+
+
+struct heci_bus_message {
+	struct hbm_cmd cmd;
+	__u8 command_specific_data[];
+} __attribute__((packed));
+
+struct hbm_version {
+	__u8 minor_version;
+	__u8 major_version;
+} __attribute__((packed));
+
+struct hbm_host_version_request {
+	struct hbm_cmd cmd;
+	__u8 reserved;
+	struct hbm_version host_version;
+} __attribute__((packed));
+
+struct hbm_host_version_response {
+	struct hbm_cmd cmd;
+	int host_version_supported;
+	struct hbm_version me_max_version;
+} __attribute__((packed));
+
+struct hbm_host_stop_request {
+	struct hbm_cmd cmd;
+	__u8 reason;
+	__u8 reserved[2];
+} __attribute__((packed));
+
+struct hbm_host_stop_response {
+	struct hbm_cmd cmd;
+	__u8 reserved[3];
+} __attribute__((packed));
+
+struct hbm_me_stop_request {
+	struct hbm_cmd cmd;
+	__u8 reason;
+	__u8 reserved[2];
+} __attribute__((packed));
+
+struct hbm_host_enum_request {
+	struct hbm_cmd cmd;
+	__u8 reserved[3];
+} __attribute__((packed));
+
+struct hbm_host_enum_response {
+	struct hbm_cmd cmd;
+	__u8 reserved[3];
+	__u8 valid_addresses[32];
+} __attribute__((packed));
+
+struct heci_client_properties {
+	struct guid protocol_name;
+	__u8 protocol_version;
+	__u8 max_number_of_connections;
+	__u8 fixed_address;
+	__u8 single_recv_buf;
+	__u32 max_msg_length;
+} __attribute__((packed));
+
+struct hbm_props_request {
+	struct hbm_cmd cmd;
+	__u8 address;
+	__u8 reserved[2];
+} __attribute__((packed));
+
+
+struct hbm_props_response {
+	struct hbm_cmd cmd;
+	__u8 address;
+	__u8 status;
+	__u8 reserved[1];
+	struct heci_client_properties client_properties;
+} __attribute__((packed));
+
+struct hbm_client_connect_request {
+	struct hbm_cmd cmd;
+	__u8 me_addr;
+	__u8 host_addr;
+	__u8 reserved;
+} __attribute__((packed));
+
+struct hbm_client_connect_response {
+	struct hbm_cmd cmd;
+	__u8 me_addr;
+	__u8 host_addr;
+	__u8 status;
+} __attribute__((packed));
+
+struct hbm_client_disconnect_request {
+	struct hbm_cmd cmd;
+	__u8 me_addr;
+	__u8 host_addr;
+	__u8 reserved[1];
+} __attribute__((packed));
+
+struct hbm_flow_control {
+	struct hbm_cmd cmd;
+	__u8 me_addr;
+	__u8 host_addr;
+	__u8 reserved[HECI_FC_MESSAGE_RESERVED_LENGTH];
+} __attribute__((packed));
+
+struct heci_me_client {
+	struct heci_client_properties props;
+	__u8 client_id;
+	__u8 flow_ctrl_creds;
+} __attribute__((packed));
+
+/* private device struct */
+struct iamt_heci_device {
+	struct pci_dev *pdev;	/* pointer to pci device struct */
+	/*
+	 * lists of queues
+	 */
+	 /* array of pointers to  aio lists */
+	struct io_heci_list *io_list_array[HECI_IO_LISTS_NUMBER];
+	struct io_heci_list read_list;	/* driver read queue */
+	struct io_heci_list write_list;	/* driver write queue */
+	struct io_heci_list write_waiting_list;	/* write waiting queue */
+	struct io_heci_list ctrl_wr_list;	/* managed write IOCTL list */
+	struct io_heci_list ctrl_rd_list;	/* managed read IOCTL list */
+	struct io_heci_list pthi_cmd_list;	/* PTHI list for cmd waiting */
+
+	/* driver managed PTHI list for reading completed pthi cmd data */
+	struct io_heci_list pthi_read_complete_list;
+	/*
+	 * list of files
+	 */
+	struct list_head file_list;
+	/*
+	 * memory of device
+	 */
+	unsigned int mem_base;
+	unsigned int mem_length;
+	void __iomem *mem_addr;
+	/*
+	 * lock for the device
+	 */
+	spinlock_t device_lock; /* device lock*/
+	struct work_struct work;
+	int recvd_msg;
+
+	struct task_struct *reinit_tsk;
+
+	struct timer_list wd_timer;
+	/*
+	 * hw states of host and fw(ME)
+	 */
+	__u32 host_hw_state;
+	__u32 me_hw_state;
+	/*
+	 * waiting queue for receive message from FW
+	 */
+	wait_queue_head_t wait_recvd_msg;
+	wait_queue_head_t wait_stop_wd;
+	/*
+	 * heci device  states
+	 */
+	enum heci_states heci_state;
+	int stop;
+
+	__u32 extra_write_index;
+	__u32 rd_msg_buf[128];	/* used for control messages */
+	__u32 wr_msg_buf[128];	/* used for control messages */
+	__u32 ext_msg_buf[8];	/* for control responses    */
+	__u32 rd_msg_hdr;
+
+	struct hbm_version version;
+
+	int host_buffer_is_empty;
+	struct heci_file_private wd_file_ext;
+	struct heci_me_client *me_clients; /* Note: memory has to be allocated*/
+	__u8 heci_me_clients[32];	/* list of existing clients */
+	__u8 num_heci_me_clients;
+	__u8 heci_host_clients[32];	/* list of existing clients */
+	__u8 current_host_client_id;
+
+	int wd_pending;
+	int wd_stoped;
+	__u16 wd_timeout;	/* seconds ((wd_data[1] << 8) + wd_data[0]) */
+	unsigned char wd_data[HECI_START_WD_DATA_SIZE];
+
+
+	__u16 wd_due_counter;
+	int asf_mode;
+	int wd_bypass;	/* if 1, don't refresh watchdog ME client */
+
+	struct file *iamthif_file_object;
+	struct heci_file_private iamthif_file_ext;
+	int iamthif_ioctl;
+	int iamthif_canceled;
+	__u32 iamthif_timer;
+	__u32 iamthif_stall_timer;
+	unsigned char iamthif_msg_buf[IAMTHIF_MTU];
+	__u32 iamthif_msg_buf_size;
+	__u32 iamthif_msg_buf_index;
+	int iamthif_flow_control_pending;
+	enum iamthif_states iamthif_state;
+
+	struct heci_cb_private *iamthif_current_cb;
+	__u8 write_hang;
+	int need_reset;
+	long open_handle_count;
+
+};
+
+/**
+ * read_heci_register - Read a byte from the heci device
+ *
+ * @dev: the device structure
+ * @offset: offset from which to read the data
+ *
+ * returns  the byte read.
+ */
+static inline __u32 read_heci_register(struct iamt_heci_device *dev,
+					unsigned long offset)
+{
+	return readl(dev->mem_addr + offset);
+}
+
+/**
+ * write_heci_register - Write  4 bytes to the heci device
+ *
+ * @dev: the device structure
+ * @offset: offset from which to write the data
+ * @value: the byte to write
+ */
+static inline void write_heci_register(struct iamt_heci_device *dev,
+					unsigned long offset,  __u32 value)
+{
+	writel(value, dev->mem_addr + offset);
+}
+
+#endif /* _HECI_DATA_STRUCTURES_H_ */
diff --git a/drivers/staging/heci/heci_init.c b/drivers/staging/heci/heci_init.c
new file mode 100644
index 0000000..a8a0da9
--- /dev/null
+++ b/drivers/staging/heci/heci_init.c
@@ -0,0 +1,1077 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * 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,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * 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 MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/reboot.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/kdev_t.h>
+#include <linux/moduleparam.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+#include <linux/kthread.h>
+
+#include "heci_data_structures.h"
+#include "heci_interface.h"
+#include "heci.h"
+
+
+const __u8 heci_start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 };
+const __u8 heci_stop_wd_params[] = { 0x02, 0x02, 0x14, 0x10 };
+
+const __u8 heci_wd_state_independence_msg[3][4] = {
+	{0x05, 0x02, 0x51, 0x10},
+	{0x05, 0x02, 0x52, 0x10},
+	{0x07, 0x02, 0x01, 0x10}
+};
+
+static const struct guid heci_asf_guid = {
+	0x75B30CD6, 0xA29E, 0x4AF7,
+	{0xA7, 0x12, 0xE6, 0x17, 0x43, 0x93, 0xC8, 0xA6}
+};
+const struct guid heci_wd_guid = {
+	0x05B79A6F, 0x4628, 0x4D7F,
+	{0x89, 0x9D, 0xA9, 0x15, 0x14, 0xCB, 0x32, 0xAB}
+};
+const struct guid heci_pthi_guid = {
+	0x12f80028, 0xb4b7, 0x4b2d,
+	{0xac, 0xa8, 0x46, 0xe0, 0xff, 0x65, 0x81, 0x4c}
+};
+
+
+/*
+ *  heci init function prototypes
+ */
+static void heci_check_asf_mode(struct iamt_heci_device *dev);
+static int host_start_message(struct iamt_heci_device *dev);
+static int host_enum_clients_message(struct iamt_heci_device *dev);
+static int allocate_me_clients_storage(struct iamt_heci_device *dev);
+static void host_init_wd(struct iamt_heci_device *dev);
+static void host_init_iamthif(struct iamt_heci_device *dev);
+static int heci_wait_event_int_timeout(struct iamt_heci_device *dev,
+				       long timeout);
+
+
+/**
+ * heci_initialize_list - Sets up a queue list.
+ *
+ * @list: An instance of our list structure
+ * @dev: Device object for our driver
+ */
+void heci_initialize_list(struct io_heci_list *list,
+			  struct iamt_heci_device *dev)
+{
+	/* initialize our queue list */
+	INIT_LIST_HEAD(&list->heci_cb.cb_list);
+	list->status = 0;
+	list->device_extension = dev;
+}
+
+/**
+ * heci_flush_queues - flush our queues list belong to file_ext.
+ *
+ * @dev: Device object for our driver
+ * @file_ext: private data of the file object
+ */
+void heci_flush_queues(struct iamt_heci_device *dev,
+		       struct heci_file_private *file_ext)
+{
+	int i;
+
+	if (!dev || !file_ext)
+		return;
+
+	/* flush our queue list belong to file_ext */
+	for (i = 0; i < HECI_IO_LISTS_NUMBER; i++) {
+		DBG("remove list entry belong to file_ext\n");
+		heci_flush_list(dev->io_list_array[i], file_ext);
+	}
+}
+
+
+/**
+ * heci_flush_list - remove list entry belong to file_ext.
+ *
+ * @list:  An instance of our list structure
+ * @file_ext: private data of the file object
+ */
+void heci_flush_list(struct io_heci_list *list,
+		struct heci_file_private *file_ext)
+{
+	struct heci_file_private *file_ext_tmp;
+	struct heci_cb_private *priv_cb_pos = NULL;
+	struct heci_cb_private *priv_cb_next = NULL;
+
+	if (!list || !file_ext)
+		return;
+
+	if (list->status != 0)
+		return;
+
+	if (list_empty(&list->heci_cb.cb_list))
+		return;
+
+	list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+				 &list->heci_cb.cb_list, cb_list) {
+		if (priv_cb_pos) {
+			file_ext_tmp = (struct heci_file_private *)
+				priv_cb_pos->file_private;
+			if (file_ext_tmp) {
+				if (heci_fe_same_id(file_ext, file_ext_tmp))
+					list_del(&priv_cb_pos->cb_list);
+			}
+		}
+	}
+}
+
+/**
+ * heci_reset_iamthif_params - initializes heci device iamthif
+ *
+ * @dev: The heci device structure
+ */
+static void heci_reset_iamthif_params(struct iamt_heci_device *dev)
+{
+	/* reset iamthif parameters. */
+	dev->iamthif_current_cb = NULL;
+	dev->iamthif_msg_buf_size = 0;
+	dev->iamthif_msg_buf_index = 0;
+	dev->iamthif_canceled = 0;
+	dev->iamthif_file_ext.file = NULL;
+	dev->iamthif_ioctl = 0;
+	dev->iamthif_state = HECI_IAMTHIF_IDLE;
+	dev->iamthif_timer = 0;
+}
+
+/**
+ * init_heci_device - allocates and initializes the heci device structure
+ *
+ * @pdev: The pci device structure
+ *
+ * returns The heci_device_device pointer on success, NULL on failure.
+ */
+struct iamt_heci_device *init_heci_device(struct pci_dev *pdev)
+{
+	int i;
+	struct iamt_heci_device *dev;
+
+	dev = kzalloc(sizeof(struct iamt_heci_device), GFP_KERNEL);
+	if (!dev)
+		return NULL;
+
+	/* setup our list array */
+	dev->io_list_array[0] = &dev->read_list;
+	dev->io_list_array[1] = &dev->write_list;
+	dev->io_list_array[2] = &dev->write_waiting_list;
+	dev->io_list_array[3] = &dev->ctrl_wr_list;
+	dev->io_list_array[4] = &dev->ctrl_rd_list;
+	dev->io_list_array[5] = &dev->pthi_cmd_list;
+	dev->io_list_array[6] = &dev->pthi_read_complete_list;
+	INIT_LIST_HEAD(&dev->file_list);
+	INIT_LIST_HEAD(&dev->wd_file_ext.link);
+	INIT_LIST_HEAD(&dev->iamthif_file_ext.link);
+	spin_lock_init(&dev->device_lock);
+	init_waitqueue_head(&dev->wait_recvd_msg);
+	init_waitqueue_head(&dev->wait_stop_wd);
+	dev->heci_state = HECI_INITIALIZING;
+	dev->iamthif_state = HECI_IAMTHIF_IDLE;
+
+	/* init work for schedule work */
+	INIT_WORK(&dev->work, NULL);
+	for (i = 0; i < HECI_IO_LISTS_NUMBER; i++)
+		heci_initialize_list(dev->io_list_array[i], dev);
+	dev->pdev = pdev;
+	return dev;
+}
+
+
+
+
+static int heci_wait_event_int_timeout(struct iamt_heci_device *dev,
+		long timeout)
+{
+	return wait_event_interruptible_timeout(dev->wait_recvd_msg,
+			(dev->recvd_msg), timeout);
+}
+
+/**
+ * heci_hw_init  - init host and fw to start work.
+ *
+ * @dev: Device object for our driver
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int heci_hw_init(struct iamt_heci_device *dev)
+{
+	int err = 0;
+
+	dev->host_hw_state = read_heci_register(dev, H_CSR);
+	dev->me_hw_state = read_heci_register(dev, ME_CSR_HA);
+	DBG("host_hw_state = 0x%08x, mestate = 0x%08x.\n",
+	    dev->host_hw_state, dev->me_hw_state);
+
+	if ((dev->host_hw_state & H_IS) == H_IS) {
+		/* acknowledge interrupt and stop interupts */
+		heci_set_csr_register(dev);
+	}
+	dev->recvd_msg = 0;
+	DBG("reset in start the heci device.\n");
+
+	heci_reset(dev, 1);
+
+	DBG("host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
+	    dev->host_hw_state, dev->me_hw_state);
+
+	/* wait for ME to turn on ME_RDY */
+	if (!dev->recvd_msg)
+		err = heci_wait_event_int_timeout(dev, HECI_INTEROP_TIMEOUT);
+
+	if (!err && !dev->recvd_msg) {
+		dev->heci_state = HECI_DISABLED;
+		DBG("wait_event_interruptible_timeout failed"
+		    "on wait for ME to turn on ME_RDY.\n");
+		return -ENODEV;
+	} else {
+		if (!(((dev->host_hw_state & H_RDY) == H_RDY)
+		      && ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA))) {
+			dev->heci_state = HECI_DISABLED;
+			DBG("host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
+			    dev->host_hw_state,
+			    dev->me_hw_state);
+
+			if (!(dev->host_hw_state & H_RDY) != H_RDY)
+				DBG("host turn off H_RDY.\n");
+
+			if (!(dev->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA)
+				DBG("ME turn off ME_RDY.\n");
+
+			printk(KERN_ERR
+			       "heci: link layer initialization failed.\n");
+			return -ENODEV;
+		}
+	}
+	dev->recvd_msg = 0;
+	DBG("host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
+	    dev->host_hw_state, dev->me_hw_state);
+	DBG("ME turn on ME_RDY and host turn on H_RDY.\n");
+	printk(KERN_INFO "heci: link layer has been established.\n");
+	return 0;
+}
+
+/**
+ * heci_hw_reset - reset fw via heci csr register.
+ *
+ * @dev: Device object for our driver
+ * @interrupts: if interrupt should be enable after reset.
+ */
+static void heci_hw_reset(struct iamt_heci_device *dev, int interrupts)
+{
+	dev->host_hw_state |= (H_RST | H_IG);
+
+	if (interrupts)
+		heci_csr_enable_interrupts(dev);
+	else
+		heci_csr_disable_interrupts(dev);
+
+	BUG_ON((dev->host_hw_state & H_RST) != H_RST);
+	BUG_ON((dev->host_hw_state & H_RDY) != 0);
+}
+
+/**
+ * heci_reset - reset host and fw.
+ *
+ * @dev: Device object for our driver
+ * @interrupts: if interrupt should be enable after reset.
+ */
+void heci_reset(struct iamt_heci_device *dev, int interrupts)
+{
+	struct heci_file_private *file_pos = NULL;
+	struct heci_file_private *file_next = NULL;
+	struct heci_cb_private *priv_cb_pos = NULL;
+	struct heci_cb_private *priv_cb_next = NULL;
+	int unexpected = 0;
+
+	if (dev->heci_state == HECI_RECOVERING_FROM_RESET) {
+		dev->need_reset = 1;
+		return;
+	}
+
+	if (dev->heci_state != HECI_INITIALIZING &&
+	    dev->heci_state != HECI_DISABLED &&
+	    dev->heci_state != HECI_POWER_DOWN &&
+	    dev->heci_state != HECI_POWER_UP)
+		unexpected = 1;
+
+	if (dev->reinit_tsk != NULL) {
+		kthread_stop(dev->reinit_tsk);
+		dev->reinit_tsk = NULL;
+	}
+
+	dev->host_hw_state = read_heci_register(dev, H_CSR);
+
+	DBG("before reset host_hw_state = 0x%08x.\n",
+	    dev->host_hw_state);
+
+	heci_hw_reset(dev, interrupts);
+
+	dev->host_hw_state &= ~H_RST;
+	dev->host_hw_state |= H_IG;
+
+	write_heci_register(dev, H_CSR, dev->host_hw_state);
+
+	DBG("currently saved host_hw_state = 0x%08x.\n",
+	    dev->host_hw_state);
+
+	dev->need_reset = 0;
+
+	if (dev->heci_state != HECI_INITIALIZING) {
+		if ((dev->heci_state != HECI_DISABLED) &&
+		    (dev->heci_state != HECI_POWER_DOWN))
+			dev->heci_state = HECI_RESETING;
+
+		list_for_each_entry_safe(file_pos,
+				file_next, &dev->file_list, link) {
+			file_pos->state = HECI_FILE_DISCONNECTED;
+			file_pos->flow_ctrl_creds = 0;
+			file_pos->read_cb = NULL;
+			file_pos->timer_count = 0;
+		}
+		/* remove entry if already in list */
+		DBG("list del iamthif and wd file list.\n");
+		heci_remove_client_from_file_list(dev,
+				dev->wd_file_ext.host_client_id);
+
+		heci_remove_client_from_file_list(dev,
+				dev->iamthif_file_ext.host_client_id);
+
+		heci_reset_iamthif_params(dev);
+		dev->wd_due_counter = 0;
+		dev->extra_write_index = 0;
+	}
+
+	dev->num_heci_me_clients = 0;
+	dev->rd_msg_hdr = 0;
+	dev->stop = 0;
+	dev->wd_pending = 0;
+
+	/* update the state of the registers after reset */
+	dev->host_hw_state =  read_heci_register(dev, H_CSR);
+	dev->me_hw_state =  read_heci_register(dev, ME_CSR_HA);
+
+	DBG("after reset host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
+	    dev->host_hw_state, dev->me_hw_state);
+
+	if (unexpected)
+		printk(KERN_WARNING "heci: unexpected reset.\n");
+
+	/* Wake up all readings so they can be interrupted */
+	list_for_each_entry_safe(file_pos, file_next, &dev->file_list, link) {
+		if (&file_pos->rx_wait &&
+		    waitqueue_active(&file_pos->rx_wait)) {
+			printk(KERN_INFO "heci: Waking up client!\n");
+			wake_up_interruptible(&file_pos->rx_wait);
+		}
+	}
+	/* remove all waiting requests */
+	if (dev->write_list.status == 0 &&
+		!list_empty(&dev->write_list.heci_cb.cb_list)) {
+		list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+				&dev->write_list.heci_cb.cb_list, cb_list) {
+			if (priv_cb_pos) {
+				list_del(&priv_cb_pos->cb_list);
+				heci_free_cb_private(priv_cb_pos);
+			}
+		}
+	}
+}
+
+/**
+ * heci_initialize_clients - heci communication initialization.
+ *
+ * @dev: Device object for our driver
+ */
+int heci_initialize_clients(struct iamt_heci_device *dev)
+{
+	int status;
+
+	msleep(100); /* FW needs time to be ready to talk with us */
+	DBG("link is established start sending messages.\n");
+	/* link is established start sending messages. */
+	status = host_start_message(dev);
+	if (status != 0) {
+		spin_lock_bh(&dev->device_lock);
+		dev->heci_state = HECI_DISABLED;
+		spin_unlock_bh(&dev->device_lock);
+		DBG("start sending messages failed.\n");
+		return status;
+	}
+
+	/* enumerate clients */
+	status = host_enum_clients_message(dev);
+	if (status != 0) {
+		spin_lock_bh(&dev->device_lock);
+		dev->heci_state = HECI_DISABLED;
+		spin_unlock_bh(&dev->device_lock);
+		DBG("enum clients failed.\n");
+		return status;
+	}
+	/* allocate storage for ME clients representation */
+	status = allocate_me_clients_storage(dev);
+	if (status != 0) {
+		spin_lock_bh(&dev->device_lock);
+		dev->num_heci_me_clients = 0;
+		dev->heci_state = HECI_DISABLED;
+		spin_unlock_bh(&dev->device_lock);
+		DBG("allocate clients failed.\n");
+		return status;
+	}
+
+	heci_check_asf_mode(dev);
+	/*heci initialization wd */
+	host_init_wd(dev);
+	/*heci initialization iamthif client */
+	host_init_iamthif(dev);
+
+	spin_lock_bh(&dev->device_lock);
+	if (dev->need_reset) {
+		dev->need_reset = 0;
+		dev->heci_state = HECI_DISABLED;
+		spin_unlock_bh(&dev->device_lock);
+		return -ENODEV;
+	}
+
+	memset(dev->heci_host_clients, 0, sizeof(dev->heci_host_clients));
+	dev->open_handle_count = 0;
+	dev->heci_host_clients[0] |= 7;
+	dev->current_host_client_id = 3;
+	dev->heci_state = HECI_ENABLED;
+	spin_unlock_bh(&dev->device_lock);
+	DBG("initialization heci clients successful.\n");
+	return 0;
+}
+
+/**
+ * heci_task_initialize_clients - heci reinitialization task
+ *
+ * @data: Device object for our driver
+ */
+int heci_task_initialize_clients(void *data)
+{
+	int ret;
+	struct iamt_heci_device *dev = (struct iamt_heci_device *) data;
+
+	spin_lock_bh(&dev->device_lock);
+	if (dev->reinit_tsk != NULL) {
+		spin_unlock_bh(&dev->device_lock);
+		DBG("reinit task already started.\n");
+		return 0;
+	}
+	dev->reinit_tsk = current;
+	current->flags |= PF_NOFREEZE;
+	spin_unlock_bh(&dev->device_lock);
+
+	ret = heci_initialize_clients(dev);
+
+	spin_lock_bh(&dev->device_lock);
+	dev->reinit_tsk = NULL;
+	spin_unlock_bh(&dev->device_lock);
+
+	return ret;
+}
+
+/**
+ * host_start_message - heci host send start message.
+ *
+ * @dev: Device object for our driver
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int host_start_message(struct iamt_heci_device *dev)
+{
+	long timeout = 60;	/* 60 second */
+
+	struct heci_msg_hdr *heci_hdr;
+	struct hbm_host_version_request *host_start_req;
+	struct hbm_host_stop_request *host_stop_req;
+	int err = 0;
+
+	/* host start message */
+	heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+	heci_hdr->host_addr = 0;
+	heci_hdr->me_addr = 0;
+	heci_hdr->length = sizeof(struct hbm_host_version_request);
+	heci_hdr->msg_complete = 1;
+	heci_hdr->reserved = 0;
+
+	host_start_req =
+	    (struct hbm_host_version_request *) &dev->wr_msg_buf[1];
+	memset(host_start_req, 0, sizeof(struct hbm_host_version_request));
+	host_start_req->cmd.cmd = HOST_START_REQ_CMD;
+	host_start_req->host_version.major_version = HBM_MAJOR_VERSION;
+	host_start_req->host_version.minor_version = HBM_MINOR_VERSION;
+	dev->recvd_msg = 0;
+	if (!heci_write_message(dev, heci_hdr,
+				       (unsigned char *) (host_start_req),
+				       heci_hdr->length)) {
+		DBG("send version to fw fail.\n");
+		return -ENODEV;
+	}
+	DBG("call wait_event_interruptible_timeout for response message.\n");
+	/* wait for response */
+	err = heci_wait_event_int_timeout(dev, timeout * HZ);
+	if (!err && !dev->recvd_msg) {
+		DBG("wait_timeout failed on host start response message.\n");
+		return -ENODEV;
+	}
+	dev->recvd_msg = 0;
+	DBG("wait_timeout successful on host start response message.\n");
+	if ((dev->version.major_version != HBM_MAJOR_VERSION) ||
+	    (dev->version.minor_version != HBM_MINOR_VERSION)) {
+		/* send stop message */
+		heci_hdr->host_addr = 0;
+		heci_hdr->me_addr = 0;
+		heci_hdr->length = sizeof(struct hbm_host_stop_request);
+		heci_hdr->msg_complete = 1;
+		heci_hdr->reserved = 0;
+
+		host_stop_req =
+		    (struct hbm_host_stop_request *) &dev->wr_msg_buf[1];
+
+		memset(host_stop_req, 0, sizeof(struct hbm_host_stop_request));
+		host_stop_req->cmd.cmd = HOST_STOP_REQ_CMD;
+		host_stop_req->reason = DRIVER_STOP_REQUEST;
+		heci_write_message(dev, heci_hdr,
+				   (unsigned char *) (host_stop_req),
+				   heci_hdr->length);
+		DBG("version mismatch.\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+/**
+ * host_enum_clients_message - host send enumeration client request message.
+ *
+ * @dev: Device object for our driver
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int host_enum_clients_message(struct iamt_heci_device *dev)
+{
+	long timeout = 5;	/*5 second */
+	struct heci_msg_hdr *heci_hdr;
+	struct hbm_host_enum_request *host_enum_req;
+	int err = 0;
+	int i, j;
+
+	heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+	/* enumerate clients */
+	heci_hdr->host_addr = 0;
+	heci_hdr->me_addr = 0;
+	heci_hdr->length = sizeof(struct hbm_host_enum_request);
+	heci_hdr->msg_complete = 1;
+	heci_hdr->reserved = 0;
+
+	host_enum_req = (struct hbm_host_enum_request *) &dev->wr_msg_buf[1];
+	memset(host_enum_req, 0, sizeof(struct hbm_host_enum_request));
+	host_enum_req->cmd.cmd = HOST_ENUM_REQ_CMD;
+	if (!heci_write_message(dev, heci_hdr,
+			       (unsigned char *) (host_enum_req),
+			       heci_hdr->length)) {
+		DBG("send enumeration request failed.\n");
+		return -ENODEV;
+	}
+	/* wait for response */
+	dev->recvd_msg = 0;
+	err = heci_wait_event_int_timeout(dev, timeout * HZ);
+	if (!err && !dev->recvd_msg) {
+		DBG("wait_event_interruptible_timeout failed "
+				"on enumeration clients response message.\n");
+		return -ENODEV;
+	}
+	dev->recvd_msg = 0;
+
+	spin_lock_bh(&dev->device_lock);
+	/* count how many ME clients we have */
+	for (i = 0; i < sizeof(dev->heci_me_clients); i++) {
+		for (j = 0; j < 8; j++) {
+			if ((dev->heci_me_clients[i] & (1 << j)) != 0)
+				dev->num_heci_me_clients++;
+
+		}
+	}
+	spin_unlock_bh(&dev->device_lock);
+
+	return 0;
+}
+
+/**
+ * host_client_properties - reads properties for client
+ *
+ * @dev: Device object for our driver
+ * @idx: client index in me client array
+ * @client_id: id of the client
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int host_client_properties(struct iamt_heci_device *dev,
+				  struct heci_me_client *client)
+{
+	struct heci_msg_hdr *heci_hdr;
+	struct hbm_props_request *host_cli_req;
+	int err;
+
+	heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+	heci_hdr->host_addr = 0;
+	heci_hdr->me_addr = 0;
+	heci_hdr->length = sizeof(struct hbm_props_request);
+	heci_hdr->msg_complete = 1;
+	heci_hdr->reserved = 0;
+
+	host_cli_req = (struct hbm_props_request *) &dev->wr_msg_buf[1];
+	memset(host_cli_req, 0, sizeof(struct hbm_props_request));
+	host_cli_req->cmd.cmd = HOST_CLIENT_PROPERTEIS_REQ_CMD;
+	host_cli_req->address = client->client_id;
+	if (!heci_write_message(dev, heci_hdr,
+				(unsigned char *) (host_cli_req),
+				heci_hdr->length)) {
+		DBG("send props request failed.\n");
+		return -ENODEV;
+	}
+	/* wait for response */
+	dev->recvd_msg = 0;
+	err = heci_wait_event_int_timeout(dev, 10 * HZ);
+	if (!err && !dev->recvd_msg) {
+		DBG("wait failed on props resp msg.\n");
+		return -ENODEV;
+	}
+	dev->recvd_msg = 0;
+	return 0;
+}
+
+/**
+ * allocate_me_clients_storage - allocate storage for me clients
+ *
+ * @dev: Device object for our driver
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int allocate_me_clients_storage(struct iamt_heci_device *dev)
+{
+	struct heci_me_client *clients;
+	struct heci_me_client *client;
+	__u8 num, i, j;
+	int err;
+
+	if (dev->num_heci_me_clients <= 0)
+		return 0;
+
+	spin_lock_bh(&dev->device_lock);
+	kfree(dev->me_clients);
+	dev->me_clients = NULL;
+	spin_unlock_bh(&dev->device_lock);
+
+	/* allocate storage for ME clients representation */
+	clients = kcalloc(dev->num_heci_me_clients,
+			sizeof(struct heci_me_client), GFP_KERNEL);
+	if (!clients) {
+		DBG("memory allocation for ME clients failed.\n");
+		return -ENOMEM;
+	}
+
+	spin_lock_bh(&dev->device_lock);
+	dev->me_clients = clients;
+	spin_unlock_bh(&dev->device_lock);
+
+	num = 0;
+	for (i = 0; i < sizeof(dev->heci_me_clients); i++) {
+		for (j = 0; j < 8; j++) {
+			if ((dev->heci_me_clients[i] & (1 << j)) != 0) {
+				client = &dev->me_clients[num];
+				client->client_id = (i * 8) + j;
+				client->flow_ctrl_creds = 0;
+				err = host_client_properties(dev, client);
+				if (err != 0) {
+					spin_lock_bh(&dev->device_lock);
+					kfree(dev->me_clients);
+					dev->me_clients = NULL;
+					spin_unlock_bh(&dev->device_lock);
+					return err;
+				}
+				num++;
+			}
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * heci_init_file_private - initializes private file structure.
+ *
+ * @priv: private file structure to be initialized
+ * @file: the file structure
+ */
+static void heci_init_file_private(struct heci_file_private *priv,
+				   struct file *file)
+{
+	memset(priv, 0, sizeof(struct heci_file_private));
+	spin_lock_init(&priv->file_lock);
+	spin_lock_init(&priv->read_io_lock);
+	spin_lock_init(&priv->write_io_lock);
+	init_waitqueue_head(&priv->wait);
+	init_waitqueue_head(&priv->rx_wait);
+	DBG("priv->rx_wait =%p\n", &priv->rx_wait);
+	init_waitqueue_head(&priv->tx_wait);
+	INIT_LIST_HEAD(&priv->link);
+	priv->reading_state = HECI_IDLE;
+	priv->writing_state = HECI_IDLE;
+}
+
+/**
+ * heci_find_me_client - search for ME client guid
+ *                       sets client_id in heci_file_private if found
+ * @dev: Device object for our driver
+ * @priv: private file structure to set client_id in
+ * @cguid: searched guid of ME client
+ * @client_id: id of host client to be set in file private structure
+ *
+ * returns ME client index
+ */
+static __u8 heci_find_me_client(struct iamt_heci_device *dev,
+				struct heci_file_private *priv,
+				const struct guid *cguid, __u8 client_id)
+{
+	__u8 i;
+
+	if ((dev == NULL) || (priv == NULL) || (cguid == NULL))
+		return 0;
+
+	for (i = 0; i < dev->num_heci_me_clients; i++) {
+		if (memcmp(cguid,
+			   &dev->me_clients[i].props.protocol_name,
+			   sizeof(struct guid)) == 0) {
+			priv->me_client_id = dev->me_clients[i].client_id;
+			priv->state = HECI_FILE_CONNECTING;
+			priv->host_client_id = client_id;
+
+			list_add_tail(&priv->link, &dev->file_list);
+			return i;
+		}
+	}
+	return 0;
+}
+
+/**
+ * heci_check_asf_mode - check for ASF client
+ *
+ * @dev: Device object for our driver
+ */
+static void heci_check_asf_mode(struct iamt_heci_device *dev)
+{
+	__u8 i;
+
+	spin_lock_bh(&dev->device_lock);
+	dev->asf_mode = 0;
+	/* find ME ASF client - otherwise assume AMT mode */
+	DBG("find ME ASF client - otherwise assume AMT mode.\n");
+	for (i = 0; i < dev->num_heci_me_clients; i++) {
+		if (memcmp(&heci_asf_guid,
+				&dev->me_clients[i].props.protocol_name,
+				sizeof(struct guid)) == 0) {
+			dev->asf_mode = 1;
+			spin_unlock_bh(&dev->device_lock);
+			DBG("found ME ASF client.\n");
+			return;
+		}
+	}
+	spin_unlock_bh(&dev->device_lock);
+	DBG("assume AMT mode.\n");
+}
+
+/**
+ * heci_connect_me_client - connect ME client
+ * @dev: Device object for our driver
+ * @priv: private file structure
+ * @timeout: connect timeout in seconds
+ *
+ * returns 1 - if connected, 0 - if not
+ */
+static __u8 heci_connect_me_client(struct iamt_heci_device *dev,
+				   struct heci_file_private *priv,
+				   long timeout)
+{
+	int err = 0;
+
+	if ((dev == NULL) || (priv == NULL))
+		return 0;
+
+	if (!heci_connect(dev, priv)) {
+		DBG("failed to call heci_connect for client_id=%d.\n",
+		    priv->host_client_id);
+		spin_lock_bh(&dev->device_lock);
+		heci_remove_client_from_file_list(dev, priv->host_client_id);
+		priv->state = HECI_FILE_DISCONNECTED;
+		spin_unlock_bh(&dev->device_lock);
+		return 0;
+	}
+
+	err = wait_event_timeout(dev->wait_recvd_msg,
+	    (HECI_FILE_CONNECTED == priv->state ||
+	     HECI_FILE_DISCONNECTED == priv->state),
+	    timeout * HZ);
+	if (HECI_FILE_CONNECTED != priv->state) {
+		spin_lock_bh(&dev->device_lock);
+		heci_remove_client_from_file_list(dev, priv->host_client_id);
+		DBG("failed to connect client_id=%d state=%d.\n",
+		    priv->host_client_id, priv->state);
+		if (err)
+			DBG("failed connect err=%08x\n", err);
+		priv->state = HECI_FILE_DISCONNECTED;
+		spin_unlock_bh(&dev->device_lock);
+		return 0;
+	}
+	DBG("successfully connected client_id=%d.\n",
+	    priv->host_client_id);
+	return 1;
+}
+
+/**
+ * host_init_wd - heci initialization wd.
+ *
+ * @dev: Device object for our driver
+ */
+static void host_init_wd(struct iamt_heci_device *dev)
+{
+	spin_lock_bh(&dev->device_lock);
+
+	heci_init_file_private(&dev->wd_file_ext, NULL);
+
+	/* look for WD client and connect to it */
+	dev->wd_file_ext.state = HECI_FILE_DISCONNECTED;
+	dev->wd_timeout = 0;
+
+	if (dev->asf_mode) {
+		memcpy(dev->wd_data, heci_stop_wd_params, HECI_WD_PARAMS_SIZE);
+	} else {
+		/* AMT mode */
+		dev->wd_timeout = AMT_WD_VALUE;
+		DBG("dev->wd_timeout=%d.\n", dev->wd_timeout);
+		memcpy(dev->wd_data, heci_start_wd_params, HECI_WD_PARAMS_SIZE);
+		memcpy(dev->wd_data + HECI_WD_PARAMS_SIZE,
+		       &dev->wd_timeout, sizeof(__u16));
+	}
+
+	/* find ME WD client */
+	heci_find_me_client(dev, &dev->wd_file_ext,
+			    &heci_wd_guid, HECI_WD_HOST_CLIENT_ID);
+	spin_unlock_bh(&dev->device_lock);
+
+	DBG("check wd_file_ext\n");
+	if (HECI_FILE_CONNECTING == dev->wd_file_ext.state) {
+		if (heci_connect_me_client(dev, &dev->wd_file_ext, 15) == 1) {
+			DBG("dev->wd_timeout=%d.\n", dev->wd_timeout);
+			if (dev->wd_timeout != 0)
+				dev->wd_due_counter = 1;
+			else
+				dev->wd_due_counter = 0;
+			DBG("successfully connected to WD client.\n");
+		}
+	} else
+		DBG("failed to find WD client.\n");
+
+
+	spin_lock_bh(&dev->device_lock);
+	dev->wd_timer.function = &heci_wd_timer;
+	dev->wd_timer.data = (unsigned long) dev;
+	spin_unlock_bh(&dev->device_lock);
+}
+
+
+/**
+ * host_init_iamthif - heci initialization iamthif client.
+ *
+ * @dev: Device object for our driver
+ *
+ */
+static void host_init_iamthif(struct iamt_heci_device *dev)
+{
+	__u8 i;
+
+	spin_lock_bh(&dev->device_lock);
+
+	heci_init_file_private(&dev->iamthif_file_ext, NULL);
+	dev->iamthif_file_ext.state = HECI_FILE_DISCONNECTED;
+
+	/* find ME PTHI client */
+	i = heci_find_me_client(dev, &dev->iamthif_file_ext,
+			    &heci_pthi_guid, HECI_IAMTHIF_HOST_CLIENT_ID);
+	if (dev->iamthif_file_ext.state != HECI_FILE_CONNECTING) {
+		DBG("failed to find iamthif client.\n");
+		spin_unlock_bh(&dev->device_lock);
+		return;
+	}
+
+	BUG_ON(dev->me_clients[i].props.max_msg_length != IAMTHIF_MTU);
+
+	spin_unlock_bh(&dev->device_lock);
+	if (heci_connect_me_client(dev, &dev->iamthif_file_ext, 15) == 1) {
+		DBG("connected to iamthif client.\n");
+		dev->iamthif_state = HECI_IAMTHIF_IDLE;
+	}
+}
+
+/**
+ * heci_alloc_file_private - allocates a private file structure and set it up.
+ * @file: the file structure
+ *
+ * returns  The allocated file or NULL on failure
+ */
+struct heci_file_private *heci_alloc_file_private(struct file *file)
+{
+	struct heci_file_private *priv;
+
+	priv = kmalloc(sizeof(struct heci_file_private), GFP_KERNEL);
+	if (!priv)
+		return NULL;
+
+	heci_init_file_private(priv, file);
+
+	return priv;
+}
+
+
+
+/**
+ * heci_disconnect_host_client - send disconnect message  to fw from host client.
+ *
+ * @dev: Device object for our driver
+ * @file_ext: private data of the file object
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int heci_disconnect_host_client(struct iamt_heci_device *dev,
+		struct heci_file_private *file_ext)
+{
+	int rets, err;
+	long timeout = 15;	/* 15 seconds */
+	struct heci_cb_private *priv_cb;
+
+	if ((!dev) || (!file_ext))
+		return -ENODEV;
+
+	if (file_ext->state != HECI_FILE_DISCONNECTING)
+		return 0;
+
+	priv_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL);
+	if (!priv_cb)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&priv_cb->cb_list);
+	priv_cb->file_private = file_ext;
+	priv_cb->major_file_operations = HECI_CLOSE;
+	spin_lock_bh(&dev->device_lock);
+	if (dev->host_buffer_is_empty) {
+		dev->host_buffer_is_empty = 0;
+		if (heci_disconnect(dev, file_ext)) {
+			list_add_tail(&priv_cb->cb_list,
+				&dev->ctrl_rd_list.heci_cb.cb_list);
+		} else {
+			spin_unlock_bh(&dev->device_lock);
+			rets = -ENODEV;
+			DBG("failed to call heci_disconnect.\n");
+			goto free;
+		}
+	} else {
+		DBG("add disconnect cb to control write list\n");
+		list_add_tail(&priv_cb->cb_list,
+				&dev->ctrl_wr_list.heci_cb.cb_list);
+	}
+	spin_unlock_bh(&dev->device_lock);
+
+	err = wait_event_timeout(dev->wait_recvd_msg,
+		 (HECI_FILE_DISCONNECTED == file_ext->state),
+		 timeout * HZ);
+	if (HECI_FILE_DISCONNECTED == file_ext->state) {
+		rets = 0;
+		DBG("successfully disconnected from fw client.\n");
+	} else {
+		rets = -ENODEV;
+		if (HECI_FILE_DISCONNECTED != file_ext->state)
+			DBG("wrong status client disconnect.\n");
+
+		if (err)
+			DBG("wait failed disconnect err=%08x\n", err);
+
+		DBG("failed to disconnect from fw client.\n");
+	}
+
+	spin_lock_bh(&dev->device_lock);
+	heci_flush_list(&dev->ctrl_rd_list, file_ext);
+	heci_flush_list(&dev->ctrl_wr_list, file_ext);
+	spin_unlock_bh(&dev->device_lock);
+free:
+	heci_free_cb_private(priv_cb);
+	return rets;
+}
+
+/**
+ * heci_remove_client_from_file_list -
+ *	remove file private data from device file list
+ *
+ * @dev: Device object for our driver
+ * @host_client_id: host client id to be removed
+ */
+void heci_remove_client_from_file_list(struct iamt_heci_device *dev,
+				       __u8 host_client_id)
+{
+	struct heci_file_private *file_pos = NULL;
+	struct heci_file_private *file_next = NULL;
+	list_for_each_entry_safe(file_pos, file_next, &dev->file_list, link) {
+		if (host_client_id == file_pos->host_client_id) {
+			DBG("remove host client = %d, ME client = %d\n",
+					file_pos->host_client_id,
+					file_pos->me_client_id);
+			list_del_init(&file_pos->link);
+			break;
+		}
+	}
+}
diff --git a/drivers/staging/heci/heci_interface.c b/drivers/staging/heci/heci_interface.c
new file mode 100644
index 0000000..c5f51a7
--- /dev/null
+++ b/drivers/staging/heci/heci_interface.c
@@ -0,0 +1,485 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * 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,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * 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 MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ *
+ */
+
+
+#include "heci.h"
+#include "heci_interface.h"
+
+
+/**
+ * heci_set_csr_register - write H_CSR register to the heci device
+ *
+ * @dev: device object for our driver
+ */
+void heci_set_csr_register(struct iamt_heci_device *dev)
+{
+	write_heci_register(dev, H_CSR, dev->host_hw_state);
+	dev->host_hw_state = read_heci_register(dev, H_CSR);
+}
+
+/**
+ * heci_csr_enable_interrupts - enable heci device interrupts
+ *
+ * @dev: device object for our driver
+ */
+void heci_csr_enable_interrupts(struct iamt_heci_device *dev)
+{
+	dev->host_hw_state |= H_IE;
+	heci_set_csr_register(dev);
+}
+
+/**
+ * heci_csr_disable_interrupts - disable heci device interrupts
+ *
+ * @dev: device object for our driver
+ */
+void heci_csr_disable_interrupts(struct iamt_heci_device *dev)
+{
+	dev->host_hw_state &= ~H_IE;
+	heci_set_csr_register(dev);
+}
+
+
+/**
+ * _host_get_filled_slots - get number of device filled buffer slots
+ *
+ * @device: the device structure
+ *
+ * returns numer of filled slots
+ */
+static unsigned char _host_get_filled_slots(const struct iamt_heci_device *dev)
+{
+	char read_ptr, write_ptr;
+
+	read_ptr = (char) ((dev->host_hw_state & H_CBRP) >> 8);
+	write_ptr = (char) ((dev->host_hw_state & H_CBWP) >> 16);
+
+	return (unsigned char) (write_ptr - read_ptr);
+}
+
+/**
+ * host_buffer_is_empty  - check if host buffer is empty.
+ *
+ * @dev: device object for our driver
+ *
+ * returns  1 if empty, 0 - otherwise.
+ */
+int host_buffer_is_empty(struct iamt_heci_device *dev)
+{
+	unsigned char filled_slots;
+
+	dev->host_hw_state = read_heci_register(dev, H_CSR);
+	filled_slots = _host_get_filled_slots(dev);
+
+	if (filled_slots > 0)
+		return 0;
+
+	return 1;
+}
+
+/**
+ * count_empty_write_slots  - count write empty slots.
+ *
+ * @dev: device object for our driver
+ *
+ * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise empty slots count
+ */
+__s32 count_empty_write_slots(const struct iamt_heci_device *dev)
+{
+	unsigned char buffer_depth, filled_slots, empty_slots;
+
+	buffer_depth = (unsigned char) ((dev->host_hw_state & H_CBD) >> 24);
+	filled_slots = _host_get_filled_slots(dev);
+	empty_slots = buffer_depth - filled_slots;
+
+	if (filled_slots > buffer_depth) {
+		/* overflow */
+		return -ESLOTS_OVERFLOW;
+	}
+
+	return (__s32) empty_slots;
+}
+
+/**
+ * heci_write_message  - write a message to heci device.
+ *
+ * @dev: device object for our driver
+ * @heci_hdr: header of  message
+ * @write_buffer: message buffer will be write
+ * @write_length: message size will be write
+ *
+ * returns 1 if success, 0 - otherwise.
+ */
+int heci_write_message(struct iamt_heci_device *dev,
+			     struct heci_msg_hdr *header,
+			     unsigned char *write_buffer,
+			     unsigned long write_length)
+{
+	__u32 temp_msg = 0;
+	unsigned long bytes_written = 0;
+	unsigned char buffer_depth, filled_slots, empty_slots;
+	unsigned long dw_to_write;
+
+	dev->host_hw_state = read_heci_register(dev, H_CSR);
+	DBG("host_hw_state = 0x%08x.\n", dev->host_hw_state);
+	DBG("heci_write_message header=%08x.\n", *((__u32 *) header));
+	buffer_depth = (unsigned char) ((dev->host_hw_state & H_CBD) >> 24);
+	filled_slots = _host_get_filled_slots(dev);
+	empty_slots = buffer_depth - filled_slots;
+	DBG("filled = %hu, empty = %hu.\n", filled_slots, empty_slots);
+
+	dw_to_write = ((write_length + 3) / 4);
+
+	if (dw_to_write > empty_slots)
+		return 0;
+
+	write_heci_register(dev, H_CB_WW, *((__u32 *) header));
+
+	while (write_length >= 4) {
+		write_heci_register(dev, H_CB_WW,
+				*(__u32 *) (write_buffer + bytes_written));
+		bytes_written += 4;
+		write_length -= 4;
+	}
+
+	if (write_length > 0) {
+		memcpy(&temp_msg, &write_buffer[bytes_written], write_length);
+		write_heci_register(dev, H_CB_WW, temp_msg);
+	}
+
+	dev->host_hw_state |= H_IG;
+	write_heci_register(dev, H_CSR, dev->host_hw_state);
+	dev->me_hw_state = read_heci_register(dev, ME_CSR_HA);
+	if ((dev->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA)
+		return 0;
+
+	dev->write_hang = 0;
+	return 1;
+}
+
+/**
+ * count_full_read_slots  - count read full slots.
+ *
+ * @dev: device object for our driver
+ *
+ * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise filled slots count
+ */
+__s32 count_full_read_slots(struct iamt_heci_device *dev)
+{
+	char read_ptr, write_ptr;
+	unsigned char buffer_depth, filled_slots;
+
+	dev->me_hw_state = read_heci_register(dev, ME_CSR_HA);
+	buffer_depth = (unsigned char)((dev->me_hw_state & ME_CBD_HRA) >> 24);
+	read_ptr = (char) ((dev->me_hw_state & ME_CBRP_HRA) >> 8);
+	write_ptr = (char) ((dev->me_hw_state & ME_CBWP_HRA) >> 16);
+	filled_slots = (unsigned char) (write_ptr - read_ptr);
+
+	if (filled_slots > buffer_depth) {
+		/* overflow */
+		return -ESLOTS_OVERFLOW;
+	}
+
+	DBG("filled_slots =%08x  \n", filled_slots);
+	return (__s32) filled_slots;
+}
+
+/**
+ * heci_read_slots  - read a message from heci device.
+ *
+ * @dev: device object for our driver
+ * @buffer: message buffer will be write
+ * @buffer_length: message size will be read
+ */
+void heci_read_slots(struct iamt_heci_device *dev,
+		     unsigned char *buffer, unsigned long buffer_length)
+{
+	__u32 i = 0;
+	unsigned char temp_buf[sizeof(__u32)];
+
+	while (buffer_length >= sizeof(__u32)) {
+		((__u32 *) buffer)[i] = read_heci_register(dev, ME_CB_RW);
+		DBG("buffer[%d]= %d\n", i, ((__u32 *) buffer)[i]);
+		i++;
+		buffer_length -= sizeof(__u32);
+	}
+
+	if (buffer_length > 0) {
+		*((__u32 *) &temp_buf) = read_heci_register(dev, ME_CB_RW);
+		memcpy(&buffer[i * 4], temp_buf, buffer_length);
+	}
+
+	dev->host_hw_state |= H_IG;
+	heci_set_csr_register(dev);
+}
+
+/**
+ * flow_ctrl_creds  - check flow_control credentials.
+ *
+ * @dev: device object for our driver
+ * @file_ext: private data of the file object
+ *
+ * returns 1 if flow_ctrl_creds >0, 0 - otherwise.
+ */
+int flow_ctrl_creds(struct iamt_heci_device *dev,
+				   struct heci_file_private *file_ext)
+{
+	__u8 i;
+
+	if (!dev->num_heci_me_clients)
+		return 0;
+
+	if (file_ext == NULL)
+		return 0;
+
+	if (file_ext->flow_ctrl_creds > 0)
+		return 1;
+
+	for (i = 0; i < dev->num_heci_me_clients; i++) {
+		if (dev->me_clients[i].client_id == file_ext->me_client_id) {
+			if (dev->me_clients[i].flow_ctrl_creds > 0) {
+				BUG_ON(dev->me_clients[i].props.single_recv_buf
+					 == 0);
+				return 1;
+			}
+			return 0;
+		}
+	}
+	BUG();
+	return 0;
+}
+
+/**
+ * flow_ctrl_reduce  - reduce flow_control.
+ *
+ * @dev: device object for our driver
+ * @file_ext: private data of the file object
+ */
+void flow_ctrl_reduce(struct iamt_heci_device *dev,
+			 struct heci_file_private *file_ext)
+{
+	__u8 i;
+
+	if (!dev->num_heci_me_clients)
+		return;
+
+	for (i = 0; i < dev->num_heci_me_clients; i++) {
+		if (dev->me_clients[i].client_id == file_ext->me_client_id) {
+			if (dev->me_clients[i].props.single_recv_buf != 0) {
+				BUG_ON(dev->me_clients[i].flow_ctrl_creds <= 0);
+				dev->me_clients[i].flow_ctrl_creds--;
+			} else {
+				BUG_ON(file_ext->flow_ctrl_creds <= 0);
+				file_ext->flow_ctrl_creds--;
+			}
+			return;
+		}
+	}
+	BUG();
+}
+
+/**
+ * heci_send_flow_control - send flow control to fw.
+ *
+ * @dev: device object for our driver
+ * @file_ext: private data of the file object
+ *
+ * returns 1 if success, 0 - otherwise.
+ */
+int heci_send_flow_control(struct iamt_heci_device *dev,
+				 struct heci_file_private *file_ext)
+{
+	struct heci_msg_hdr *heci_hdr;
+	struct hbm_flow_control *heci_flow_control;
+
+	heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+	heci_hdr->host_addr = 0;
+	heci_hdr->me_addr = 0;
+	heci_hdr->length = sizeof(struct hbm_flow_control);
+	heci_hdr->msg_complete = 1;
+	heci_hdr->reserved = 0;
+
+	heci_flow_control = (struct hbm_flow_control *) &dev->wr_msg_buf[1];
+	memset(heci_flow_control, 0, sizeof(heci_flow_control));
+	heci_flow_control->host_addr = file_ext->host_client_id;
+	heci_flow_control->me_addr = file_ext->me_client_id;
+	heci_flow_control->cmd.cmd = HECI_FLOW_CONTROL_CMD;
+	memset(heci_flow_control->reserved, 0,
+			sizeof(heci_flow_control->reserved));
+	DBG("sending flow control host client = %d, me client = %d\n",
+	    file_ext->host_client_id, file_ext->me_client_id);
+	if (!heci_write_message(dev, heci_hdr,
+				(unsigned char *) heci_flow_control,
+				sizeof(struct hbm_flow_control)))
+		return 0;
+
+	return 1;
+
+}
+
+/**
+ * other_client_is_connecting  - check if other
+ *    client with the same client id is connected.
+ *
+ * @dev: device object for our driver
+ * @file_ext: private data of the file object
+ *
+ * returns 1 if other client is connected, 0 - otherwise.
+ */
+int other_client_is_connecting(struct iamt_heci_device *dev,
+		struct heci_file_private *file_ext)
+{
+	struct heci_file_private *file_pos = NULL;
+	struct heci_file_private *file_next = NULL;
+
+	list_for_each_entry_safe(file_pos, file_next, &dev->file_list, link) {
+		if ((file_pos->state == HECI_FILE_CONNECTING)
+			&& (file_pos != file_ext)
+			&& file_ext->me_client_id == file_pos->me_client_id)
+			return 1;
+
+	}
+	return 0;
+}
+
+/**
+ * heci_send_wd  - send watch dog message to fw.
+ *
+ * @dev: device object for our driver
+ *
+ * returns 1 if success, 0 - otherwise.
+ */
+int heci_send_wd(struct iamt_heci_device *dev)
+{
+	struct heci_msg_hdr *heci_hdr;
+
+	heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+	heci_hdr->host_addr = dev->wd_file_ext.host_client_id;
+	heci_hdr->me_addr = dev->wd_file_ext.me_client_id;
+	heci_hdr->msg_complete = 1;
+	heci_hdr->reserved = 0;
+
+	if (!memcmp(dev->wd_data, heci_start_wd_params,
+			HECI_WD_PARAMS_SIZE)) {
+		heci_hdr->length = HECI_START_WD_DATA_SIZE;
+	} else {
+		BUG_ON(memcmp(dev->wd_data, heci_stop_wd_params,
+			HECI_WD_PARAMS_SIZE));
+		heci_hdr->length = HECI_WD_PARAMS_SIZE;
+	}
+
+	if (!heci_write_message(dev, heci_hdr, dev->wd_data, heci_hdr->length))
+		return 0;
+
+	return 1;
+}
+
+/**
+ * heci_disconnect  - send disconnect message to fw.
+ *
+ * @dev: device object for our driver
+ * @file_ext: private data of the file object
+ *
+ * returns 1 if success, 0 - otherwise.
+ */
+int heci_disconnect(struct iamt_heci_device *dev,
+			  struct heci_file_private *file_ext)
+{
+	struct heci_msg_hdr *heci_hdr;
+	struct hbm_client_disconnect_request *heci_cli_disconnect;
+
+	heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+	heci_hdr->host_addr = 0;
+	heci_hdr->me_addr = 0;
+	heci_hdr->length = sizeof(struct hbm_client_disconnect_request);
+	heci_hdr->msg_complete = 1;
+	heci_hdr->reserved = 0;
+
+	heci_cli_disconnect =
+	    (struct hbm_client_disconnect_request *) &dev->wr_msg_buf[1];
+	memset(heci_cli_disconnect, 0, sizeof(heci_cli_disconnect));
+	heci_cli_disconnect->host_addr = file_ext->host_client_id;
+	heci_cli_disconnect->me_addr = file_ext->me_client_id;
+	heci_cli_disconnect->cmd.cmd = CLIENT_DISCONNECT_REQ_CMD;
+	heci_cli_disconnect->reserved[0] = 0;
+
+	if (!heci_write_message(dev, heci_hdr,
+				(unsigned char *) heci_cli_disconnect,
+				sizeof(struct hbm_client_disconnect_request)))
+		return 0;
+
+	return 1;
+}
+
+/**
+ * heci_connect - send connect message to fw.
+ *
+ * @dev: device object for our driver
+ * @file_ext: private data of the file object
+ *
+ * returns 1 if success, 0 - otherwise.
+ */
+int heci_connect(struct iamt_heci_device *dev,
+		       struct heci_file_private *file_ext)
+{
+	struct heci_msg_hdr *heci_hdr;
+	struct hbm_client_connect_request *heci_cli_connect;
+
+	heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+	heci_hdr->host_addr = 0;
+	heci_hdr->me_addr = 0;
+	heci_hdr->length = sizeof(struct hbm_client_connect_request);
+	heci_hdr->msg_complete = 1;
+	heci_hdr->reserved = 0;
+
+	heci_cli_connect =
+	    (struct hbm_client_connect_request *) &dev->wr_msg_buf[1];
+	heci_cli_connect->host_addr = file_ext->host_client_id;
+	heci_cli_connect->me_addr = file_ext->me_client_id;
+	heci_cli_connect->cmd.cmd = CLIENT_CONNECT_REQ_CMD;
+	heci_cli_connect->reserved = 0;
+
+	if (!heci_write_message(dev, heci_hdr,
+				(unsigned char *) heci_cli_connect,
+				sizeof(struct hbm_client_connect_request)))
+		return 0;
+
+	return 1;
+}
diff --git a/drivers/staging/heci/heci_interface.h b/drivers/staging/heci/heci_interface.h
new file mode 100644
index 0000000..37336eb
--- /dev/null
+++ b/drivers/staging/heci/heci_interface.h
@@ -0,0 +1,170 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * 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,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * 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 MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ *
+ */
+
+
+#ifndef _HECI_INTERFACE_H_
+#define _HECI_INTERFACE_H_
+
+#include <linux/version.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/module.h>
+#include <linux/aio.h>
+#include <linux/types.h>
+#include "heci_data_structures.h"
+
+
+#define HBM_MINOR_VERSION                   0
+#define HBM_MAJOR_VERSION                   1
+#define HBM_TIMEOUT                         1	/* 1 second */
+
+
+#define HOST_START_REQ_CMD                  0x01
+#define HOST_START_RES_CMD                  0x81
+
+#define HOST_STOP_REQ_CMD                   0x02
+#define HOST_STOP_RES_CMD                   0x82
+
+#define ME_STOP_REQ_CMD                     0x03
+
+#define HOST_ENUM_REQ_CMD                   0x04
+#define HOST_ENUM_RES_CMD                   0x84
+
+#define HOST_CLIENT_PROPERTEIS_REQ_CMD      0x05
+#define HOST_CLIENT_PROPERTEIS_RES_CMD      0x85
+
+#define CLIENT_CONNECT_REQ_CMD              0x06
+#define CLIENT_CONNECT_RES_CMD              0x86
+
+#define CLIENT_DISCONNECT_REQ_CMD           0x07
+#define CLIENT_DISCONNECT_RES_CMD           0x87
+
+#define HECI_FLOW_CONTROL_CMD               0x08
+
+
+#define AMT_WD_VALUE 120	/* seconds */
+
+#define HECI_WATCHDOG_DATA_SIZE         16
+#define HECI_START_WD_DATA_SIZE         20
+#define HECI_WD_PARAMS_SIZE             4
+
+/* IOCTL commands */
+#define IOCTL_HECI_GET_VERSION \
+    _IOWR('H' , 0x0, struct heci_message_data)
+#define IOCTL_HECI_CONNECT_CLIENT \
+    _IOWR('H' , 0x01, struct heci_message_data)
+#define IOCTL_HECI_WD \
+    _IOWR('H' , 0x02, struct heci_message_data)
+#define IOCTL_HECI_BYPASS_WD \
+    _IOWR('H' , 0x10, struct heci_message_data)
+
+enum heci_stop_reason_types{
+	DRIVER_STOP_REQUEST = 0x00,
+	DEVICE_D1_ENTRY = 0x01,
+	DEVICE_D2_ENTRY = 0x02,
+	DEVICE_D3_ENTRY = 0x03,
+	SYSTEM_S1_ENTRY = 0x04,
+	SYSTEM_S2_ENTRY = 0x05,
+	SYSTEM_S3_ENTRY = 0x06,
+	SYSTEM_S4_ENTRY = 0x07,
+	SYSTEM_S5_ENTRY = 0x08
+};
+
+enum me_stop_reason_types{
+	FW_UPDATE = 0x00
+};
+
+enum client_connect_status_types{
+	CCS_SUCCESS = 0x00,
+	CCS_NOT_FOUND = 0x01,
+	CCS_ALREADY_STARTED = 0x02,
+	CCS_OUT_OF_RESOURCES = 0x03,
+	CCS_MESSAGE_SMALL = 0x04
+};
+
+enum client_disconnect_status_types{
+	CDS_SUCCESS = 0x00
+};
+
+
+/*
+ * heci interface function prototypes
+ */
+void heci_set_csr_register(struct iamt_heci_device *dev);
+void heci_csr_enable_interrupts(struct iamt_heci_device *dev);
+void heci_csr_disable_interrupts(struct iamt_heci_device *dev);
+
+void heci_read_slots(struct iamt_heci_device *dev,
+		     unsigned char *buffer, unsigned long buffer_length);
+
+int heci_write_message(struct iamt_heci_device *dev,
+			     struct heci_msg_hdr *header,
+			     unsigned char *write_buffer,
+			     unsigned long write_length);
+
+int host_buffer_is_empty(struct iamt_heci_device *dev);
+
+__s32 count_full_read_slots(struct iamt_heci_device *dev);
+
+__s32 count_empty_write_slots(const struct iamt_heci_device *dev);
+
+int flow_ctrl_creds(struct iamt_heci_device *dev,
+				   struct heci_file_private *file_ext);
+
+int heci_send_wd(struct iamt_heci_device *dev);
+
+void flow_ctrl_reduce(struct iamt_heci_device *dev,
+			 struct heci_file_private *file_ext);
+
+int heci_send_flow_control(struct iamt_heci_device *dev,
+				 struct heci_file_private *file_ext);
+
+int heci_disconnect(struct iamt_heci_device *dev,
+			  struct heci_file_private *file_ext);
+int other_client_is_connecting(struct iamt_heci_device *dev,
+				     struct heci_file_private *file_ext);
+int heci_connect(struct iamt_heci_device *dev,
+		       struct heci_file_private *file_ext);
+
+#endif /* _HECI_INTERFACE_H_ */
diff --git a/drivers/staging/heci/heci_main.c b/drivers/staging/heci/heci_main.c
new file mode 100644
index 0000000..00e44c7
--- /dev/null
+++ b/drivers/staging/heci/heci_main.c
@@ -0,0 +1,1564 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * 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,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * 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 MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ *
+ */
+
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/aio.h>
+#include <linux/pci.h>
+#include <linux/reboot.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/kdev_t.h>
+#include <linux/ioctl.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/unistd.h>
+#include <linux/kthread.h>
+
+#include "heci.h"
+#include "heci_interface.h"
+#include "heci_version.h"
+
+
+#define HECI_READ_TIMEOUT	45
+
+#define HECI_DRIVER_NAME	"heci"
+
+/*
+ *  heci driver strings
+ */
+static char heci_driver_name[] = HECI_DRIVER_NAME;
+static char heci_driver_string[] = "Intel(R) Management Engine Interface";
+static char heci_driver_version[] = HECI_DRIVER_VERSION;
+static char heci_copyright[] = "Copyright (c) 2003 - 2008 Intel Corporation.";
+
+
+#ifdef HECI_DEBUG
+int heci_debug = 1;
+#else
+int heci_debug;
+#endif
+MODULE_PARM_DESC(heci_debug,  "Debug enabled or not");
+module_param(heci_debug, int, 0644);
+
+
+#define HECI_DEV_NAME	"heci"
+
+/* heci char device for registration */
+static struct cdev heci_cdev;
+
+/* major number for device */
+static int heci_major;
+/* The device pointer */
+static struct pci_dev *heci_device;
+
+static struct class *heci_class;
+
+
+/* heci_pci_tbl - PCI Device ID Table */
+static struct pci_device_id heci_pci_tbl[] = {
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_82946GZ)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_82G35)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_82Q965)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_82G965)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_82GM965)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_82GME965)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_82Q35)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_82G33)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_82Q33)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_82X38)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_3200)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_6)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_7)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_8)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_9)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_10)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9M_1)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9M_2)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9M_3)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9M_4)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH10_1)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH10_2)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH10_3)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH10_4)},
+	/* required last entry */
+	{0, }
+};
+
+MODULE_DEVICE_TABLE(pci, heci_pci_tbl);
+
+/*
+ * Local Function Prototypes
+ */
+static int __init heci_init_module(void);
+static void __exit heci_exit_module(void);
+static int __devinit heci_probe(struct pci_dev *pdev,
+				const struct pci_device_id *ent);
+static void __devexit heci_remove(struct pci_dev *pdev);
+static int heci_open(struct inode *inode, struct file *file);
+static int heci_release(struct inode *inode, struct file *file);
+static ssize_t heci_read(struct file *file, char __user *ubuf,
+			 size_t length, loff_t *offset);
+static int heci_ioctl(struct inode *inode, struct file *file,
+		      unsigned int cmd, unsigned long data);
+static ssize_t heci_write(struct file *file, const char __user *ubuf,
+			  size_t length, loff_t *offset);
+static unsigned int heci_poll(struct file *file, poll_table *wait);
+static struct heci_cb_private *find_read_list_entry(
+		struct iamt_heci_device *dev,
+		struct heci_file_private *file_ext);
+#ifdef CONFIG_PM
+static int heci_suspend(struct pci_dev *pdev, pm_message_t state);
+static int heci_resume(struct pci_dev *pdev);
+static __u16 g_sus_wd_timeout;
+#else
+#define heci_suspend NULL
+#define heci_resume NULL
+#endif
+/*
+ *  PCI driver structure
+ */
+static struct pci_driver heci_driver = {
+	.name = heci_driver_name,
+	.id_table = heci_pci_tbl,
+	.probe = heci_probe,
+	.remove = __devexit_p(heci_remove),
+	.shutdown = __devexit_p(heci_remove),
+	.suspend = heci_suspend,
+	.resume = heci_resume
+};
+
+/*
+ * file operations structure will be use heci char device.
+ */
+static const struct file_operations heci_fops = {
+	.owner = THIS_MODULE,
+	.read = heci_read,
+	.ioctl = heci_ioctl,
+	.open = heci_open,
+	.release = heci_release,
+	.write = heci_write,
+	.poll = heci_poll,
+};
+
+/**
+ * heci_registration_cdev - set up the cdev structure for heci device.
+ *
+ * @dev: char device struct
+ * @hminor: minor number for registration char device
+ * @fops: file operations structure
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int heci_registration_cdev(struct cdev *dev, int hminor,
+				  const struct file_operations *fops)
+{
+	int ret, devno = MKDEV(heci_major, hminor);
+
+	cdev_init(dev, fops);
+	dev->owner = THIS_MODULE;
+	ret = cdev_add(dev, devno, 1);
+	/* Fail gracefully if need be */
+	if (ret) {
+		printk(KERN_ERR "heci: Error %d registering heci device %d\n",
+		       ret, hminor);
+	}
+	return ret;
+}
+
+/* Display the version of heci driver. */
+static ssize_t version_show(struct class *dev, char *buf)
+{
+	return sprintf(buf, "%s %s.\n",
+		       heci_driver_string, heci_driver_version);
+}
+
+static CLASS_ATTR(version, S_IRUGO, version_show, NULL);
+
+/**
+ * heci_register_cdev - registers heci char device
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int heci_register_cdev(void)
+{
+	int ret;
+	dev_t dev;
+
+	/* registration of char devices */
+	ret = alloc_chrdev_region(&dev, HECI_MINORS_BASE, HECI_MINORS_COUNT,
+				  HECI_DRIVER_NAME);
+	if (ret) {
+		printk(KERN_ERR "heci: Error allocating char device region.\n");
+		return ret;
+	}
+
+	heci_major = MAJOR(dev);
+
+	ret = heci_registration_cdev(&heci_cdev, HECI_MINOR_NUMBER,
+				     &heci_fops);
+	if (ret)
+		unregister_chrdev_region(MKDEV(heci_major, HECI_MINORS_BASE),
+					 HECI_MINORS_COUNT);
+
+	return ret;
+}
+
+/**
+ * heci_unregister_cdev - unregisters heci char device
+ */
+static void heci_unregister_cdev(void)
+{
+	cdev_del(&heci_cdev);
+	unregister_chrdev_region(MKDEV(heci_major, HECI_MINORS_BASE),
+				 HECI_MINORS_COUNT);
+}
+
+#ifndef HECI_DEVICE_CREATE
+#define HECI_DEVICE_CREATE device_create
+#endif
+/**
+ * heci_sysfs_device_create - adds device entry to sysfs
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int heci_sysfs_device_create(void)
+{
+	struct class *class;
+	void *tmphdev;
+	int err = 0;
+
+	class = class_create(THIS_MODULE, HECI_DRIVER_NAME);
+	if (IS_ERR(class)) {
+		err = PTR_ERR(class);
+		printk(KERN_ERR "heci: Error creating heci class.\n");
+		goto err_out;
+	}
+
+	err = class_create_file(class, &class_attr_version);
+	if (err) {
+		class_destroy(class);
+		printk(KERN_ERR "heci: Error creating heci class file.\n");
+		goto err_out;
+	}
+
+	tmphdev = HECI_DEVICE_CREATE(class, NULL, heci_cdev.dev, NULL,
+					HECI_DEV_NAME);
+	if (IS_ERR(tmphdev)) {
+		err = PTR_ERR(tmphdev);
+		class_remove_file(class, &class_attr_version);
+		class_destroy(class);
+		goto err_out;
+	}
+
+	heci_class = class;
+err_out:
+	return err;
+}
+
+/**
+ * heci_sysfs_device_remove - unregisters the device entry on sysfs
+ */
+static void heci_sysfs_device_remove(void)
+{
+	if ((heci_class == NULL) || (IS_ERR(heci_class)))
+		return;
+
+	device_destroy(heci_class, heci_cdev.dev);
+	class_remove_file(heci_class, &class_attr_version);
+	class_destroy(heci_class);
+}
+
+/**
+ * heci_init_module - Driver Registration Routine
+ *
+ * heci_init_module is the first routine called when the driver is
+ * loaded. All it does is register with the PCI subsystem.
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int __init heci_init_module(void)
+{
+	int ret = 0;
+
+	printk(KERN_INFO "heci: %s - version %s\n", heci_driver_string,
+			heci_driver_version);
+	printk(KERN_INFO "heci: %s\n", heci_copyright);
+
+	/* init pci module */
+	ret = pci_register_driver(&heci_driver);
+	if (ret < 0) {
+		printk(KERN_ERR "heci: Error registering driver.\n");
+		goto end;
+	}
+
+	ret = heci_register_cdev();
+	if (ret)
+		goto unregister_pci;
+
+	ret = heci_sysfs_device_create();
+	if (ret)
+		goto unregister_cdev;
+
+	return ret;
+
+unregister_cdev:
+	heci_unregister_cdev();
+unregister_pci:
+	pci_unregister_driver(&heci_driver);
+end:
+	return ret;
+}
+
+module_init(heci_init_module);
+
+
+/**
+ * heci_exit_module - Driver Exit Cleanup Routine
+ *
+ * heci_exit_module is called just before the driver is removed
+ * from memory.
+ */
+static void __exit heci_exit_module(void)
+{
+	pci_unregister_driver(&heci_driver);
+	heci_sysfs_device_remove();
+	heci_unregister_cdev();
+}
+
+module_exit(heci_exit_module);
+
+
+/**
+ * heci_probe - Device Initialization Routine
+ *
+ * @pdev: PCI device information struct
+ * @ent: entry in kcs_pci_tbl
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int __devinit heci_probe(struct pci_dev *pdev,
+				const struct pci_device_id *ent)
+{
+	struct iamt_heci_device *dev = NULL;
+	int i, err = 0;
+
+	if (heci_device) {
+		err = -EEXIST;
+		goto end;
+	}
+	/* enable pci dev */
+	err = pci_enable_device(pdev);
+	if (err) {
+		printk(KERN_ERR "heci: Failed to enable pci device.\n");
+		goto end;
+	}
+	/* set PCI host mastering  */
+	pci_set_master(pdev);
+	/* pci request regions for heci driver */
+	err = pci_request_regions(pdev, heci_driver_name);
+	if (err) {
+		printk(KERN_ERR "heci: Failed to get pci regions.\n");
+		goto disable_device;
+	}
+	/* allocates and initializes the heci dev structure */
+	dev = init_heci_device(pdev);
+	if (!dev) {
+		err = -ENOMEM;
+		goto release_regions;
+	}
+	/* mapping  IO device memory */
+	for (i = 0; i <= 5; i++) {
+		if (pci_resource_len(pdev, i) == 0)
+			continue;
+		if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
+			printk(KERN_ERR "heci: heci has IO ports.\n");
+			goto free_device;
+		} else if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) {
+			if (dev->mem_base) {
+				printk(KERN_ERR
+					"heci: Too many mem addresses.\n");
+				goto free_device;
+			}
+			dev->mem_base = pci_resource_start(pdev, i);
+			dev->mem_length = pci_resource_len(pdev, i);
+		}
+	}
+	if (!dev->mem_base) {
+		printk(KERN_ERR "heci: No address to use.\n");
+		err = -ENODEV;
+		goto free_device;
+	}
+	dev->mem_addr = ioremap_nocache(dev->mem_base,
+			dev->mem_length);
+	if (!dev->mem_addr) {
+		printk(KERN_ERR "heci: Remap IO device memory failure.\n");
+		err = -ENOMEM;
+		goto free_device;
+	}
+	/* request and enable interrupt   */
+	err = request_irq(pdev->irq, heci_isr_interrupt, IRQF_SHARED,
+			heci_driver_name, dev);
+	if (err) {
+		printk(KERN_ERR "heci: Request_irq failure. irq = %d \n",
+		       pdev->irq);
+		goto unmap_memory;
+	}
+
+	if (heci_hw_init(dev)) {
+		printk(KERN_ERR "heci: Init hw failure.\n");
+		err = -ENODEV;
+		goto release_irq;
+	}
+	init_timer(&dev->wd_timer);
+
+	heci_initialize_clients(dev);
+	if (dev->heci_state != HECI_ENABLED) {
+		err = -ENODEV;
+		goto release_hw;
+	}
+
+	spin_lock_bh(&dev->device_lock);
+	heci_device = pdev;
+	pci_set_drvdata(pdev, dev);
+	spin_unlock_bh(&dev->device_lock);
+
+	if (dev->wd_timeout)
+		mod_timer(&dev->wd_timer, jiffies);
+
+#ifdef CONFIG_PM
+	g_sus_wd_timeout = 0;
+#endif
+	printk(KERN_INFO "heci driver initialization successful.\n");
+	return 0;
+
+release_hw:
+	/* disable interrupts */
+	dev->host_hw_state = read_heci_register(dev, H_CSR);
+	heci_csr_disable_interrupts(dev);
+
+	del_timer_sync(&dev->wd_timer);
+
+	flush_scheduled_work();
+
+release_irq:
+	free_irq(pdev->irq, dev);
+unmap_memory:
+	if (dev->mem_addr)
+		iounmap(dev->mem_addr);
+free_device:
+	kfree(dev);
+release_regions:
+	pci_release_regions(pdev);
+disable_device:
+	pci_disable_device(pdev);
+end:
+	printk(KERN_ERR "heci driver initialization failed.\n");
+	return err;
+}
+
+/**
+ * heci_remove - Device Removal Routine
+ *
+ * @pdev: PCI device information struct
+ *
+ * heci_remove is called by the PCI subsystem to alert the driver
+ * that it should release a PCI device.
+ */
+static void __devexit heci_remove(struct pci_dev *pdev)
+{
+	struct iamt_heci_device *dev = pci_get_drvdata(pdev);
+
+	if (heci_device != pdev)
+		return;
+
+	if (dev == NULL)
+		return;
+
+	spin_lock_bh(&dev->device_lock);
+	if (heci_device != pdev) {
+		spin_unlock_bh(&dev->device_lock);
+		return;
+	}
+
+	if (dev->reinit_tsk != NULL) {
+		kthread_stop(dev->reinit_tsk);
+		dev->reinit_tsk = NULL;
+	}
+
+	del_timer_sync(&dev->wd_timer);
+	if (dev->wd_file_ext.state == HECI_FILE_CONNECTED
+	    && dev->wd_timeout) {
+		dev->wd_timeout = 0;
+		dev->wd_due_counter = 0;
+		memcpy(dev->wd_data, heci_stop_wd_params, HECI_WD_PARAMS_SIZE);
+		dev->stop = 1;
+		if (dev->host_buffer_is_empty &&
+		    flow_ctrl_creds(dev, &dev->wd_file_ext)) {
+			dev->host_buffer_is_empty = 0;
+
+			if (!heci_send_wd(dev))
+				DBG("send stop WD failed\n");
+			else
+				flow_ctrl_reduce(dev, &dev->wd_file_ext);
+
+			dev->wd_pending = 0;
+		} else {
+			dev->wd_pending = 1;
+		}
+		dev->wd_stoped = 0;
+		spin_unlock_bh(&dev->device_lock);
+
+		wait_event_interruptible_timeout(dev->wait_stop_wd,
+				(dev->wd_stoped), 10 * HZ);
+		spin_lock_bh(&dev->device_lock);
+		if (!dev->wd_stoped)
+			DBG("stop wd failed to complete.\n");
+		else
+			DBG("stop wd complete.\n");
+
+	}
+
+	heci_device = NULL;
+	spin_unlock_bh(&dev->device_lock);
+
+	if (dev->iamthif_file_ext.state == HECI_FILE_CONNECTED) {
+		dev->iamthif_file_ext.state = HECI_FILE_DISCONNECTING;
+		heci_disconnect_host_client(dev,
+					    &dev->iamthif_file_ext);
+	}
+	if (dev->wd_file_ext.state == HECI_FILE_CONNECTED) {
+		dev->wd_file_ext.state = HECI_FILE_DISCONNECTING;
+		heci_disconnect_host_client(dev,
+					    &dev->wd_file_ext);
+	}
+
+	spin_lock_bh(&dev->device_lock);
+
+	/* remove entry if already in list */
+	DBG("list del iamthif and wd file list.\n");
+	heci_remove_client_from_file_list(dev, dev->wd_file_ext.
+					  host_client_id);
+	heci_remove_client_from_file_list(dev,
+			dev->iamthif_file_ext.host_client_id);
+
+	dev->iamthif_current_cb = NULL;
+	dev->iamthif_file_ext.file = NULL;
+	dev->num_heci_me_clients = 0;
+
+	spin_unlock_bh(&dev->device_lock);
+
+	flush_scheduled_work();
+
+	/* disable interrupts */
+	heci_csr_disable_interrupts(dev);
+
+	free_irq(pdev->irq, dev);
+	pci_set_drvdata(pdev, NULL);
+
+	if (dev->mem_addr)
+		iounmap(dev->mem_addr);
+
+	kfree(dev);
+
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+}
+
+/**
+ * heci_clear_list - remove all callbacks associated with file
+ * 		from heci_cb_list
+ *
+ * @file: file information struct
+ * @heci_cb_list: callbacks list
+ *
+ * heci_clear_list is called to clear resources associated with file
+ * when application calls close function or Ctrl-C was pressed
+ *
+ * returns 1 if callback removed from the list, 0 otherwise
+ */
+static int heci_clear_list(struct iamt_heci_device *dev,
+		struct file *file, struct list_head *heci_cb_list)
+{
+	struct heci_cb_private *priv_cb_pos = NULL;
+	struct heci_cb_private *priv_cb_next = NULL;
+	struct file *file_temp;
+	int rets = 0;
+
+	/* list all list member */
+	list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+				 heci_cb_list, cb_list) {
+		file_temp = (struct file *)priv_cb_pos->file_object;
+		/* check if list member associated with a file */
+		if (file_temp == file) {
+			/* remove member from the list */
+			list_del(&priv_cb_pos->cb_list);
+			/* check if cb equal to current iamthif cb */
+			if (dev->iamthif_current_cb == priv_cb_pos) {
+				dev->iamthif_current_cb = NULL;
+				/* send flow control to iamthif client */
+				heci_send_flow_control(dev,
+						       &dev->iamthif_file_ext);
+			}
+			/* free all allocated buffers */
+			heci_free_cb_private(priv_cb_pos);
+			rets = 1;
+		}
+	}
+	return rets;
+}
+
+/**
+ * heci_clear_lists - remove all callbacks associated with file
+ *
+ * @dev: device information struct
+ * @file: file information struct
+ *
+ * heci_clear_lists is called to clear resources associated with file
+ * when application calls close function or Ctrl-C was pressed
+ *
+ * returns 1 if callback removed from the list, 0 otherwise
+ */
+static int heci_clear_lists(struct iamt_heci_device *dev, struct file *file)
+{
+	int rets = 0;
+
+	/* remove callbacks associated with a file */
+	heci_clear_list(dev, file, &dev->pthi_cmd_list.heci_cb.cb_list);
+	if (heci_clear_list(dev, file,
+			    &dev->pthi_read_complete_list.heci_cb.cb_list))
+		rets = 1;
+
+	heci_clear_list(dev, file, &dev->ctrl_rd_list.heci_cb.cb_list);
+
+	if (heci_clear_list(dev, file, &dev->ctrl_wr_list.heci_cb.cb_list))
+		rets = 1;
+
+	if (heci_clear_list(dev, file,
+			    &dev->write_waiting_list.heci_cb.cb_list))
+		rets = 1;
+
+	if (heci_clear_list(dev, file, &dev->write_list.heci_cb.cb_list))
+		rets = 1;
+
+	/* check if iamthif_current_cb not NULL */
+	if (dev->iamthif_current_cb && (!rets)) {
+		/* check file and iamthif current cb association */
+		if (dev->iamthif_current_cb->file_object == file) {
+			/* remove cb */
+			heci_free_cb_private(dev->iamthif_current_cb);
+			dev->iamthif_current_cb = NULL;
+			rets = 1;
+		}
+	}
+	return rets;
+}
+
+/**
+ * heci_open - the open function
+ *
+ * @inode: pointer to inode structure
+ * @file: pointer to file structure
+ *
+ * returns 0 on success, <0 on error
+ */
+static int heci_open(struct inode *inode, struct file *file)
+{
+	struct heci_file_private *file_ext;
+	int if_num = iminor(inode);
+	struct iamt_heci_device *dev;
+
+	if (!heci_device)
+		return -ENODEV;
+
+	dev = pci_get_drvdata(heci_device);
+	if ((if_num != HECI_MINOR_NUMBER) || (!dev))
+		return -ENODEV;
+
+	file_ext = heci_alloc_file_private(file);
+	if (file_ext == NULL)
+		return -ENOMEM;
+
+	spin_lock_bh(&dev->device_lock);
+	if (dev->heci_state != HECI_ENABLED) {
+		spin_unlock_bh(&dev->device_lock);
+		kfree(file_ext);
+		return -ENODEV;
+	}
+	if (dev->open_handle_count >= HECI_MAX_OPEN_HANDLE_COUNT) {
+		spin_unlock_bh(&dev->device_lock);
+		kfree(file_ext);
+		return -ENFILE;
+	};
+	dev->open_handle_count++;
+	list_add_tail(&file_ext->link, &dev->file_list);
+	while ((dev->heci_host_clients[dev->current_host_client_id / 8]
+		& (1 << (dev->current_host_client_id % 8))) != 0) {
+
+		dev->current_host_client_id++; /* allow overflow */
+		DBG("current_host_client_id = %d\n",
+		    dev->current_host_client_id);
+		DBG("dev->open_handle_count = %lu\n",
+		    dev->open_handle_count);
+	}
+	DBG("current_host_client_id = %d\n", dev->current_host_client_id);
+	file_ext->host_client_id = dev->current_host_client_id;
+	dev->heci_host_clients[file_ext->host_client_id / 8] |=
+		(1 << (file_ext->host_client_id % 8));
+	spin_unlock_bh(&dev->device_lock);
+	spin_lock(&file_ext->file_lock);
+	file_ext->state = HECI_FILE_INITIALIZING;
+	file_ext->sm_state = 0;
+
+	file->private_data = file_ext;
+	spin_unlock(&file_ext->file_lock);
+
+	return 0;
+}
+
+/**
+ * heci_release - the release function
+ *
+ * @inode: pointer to inode structure
+ * @file: pointer to file structure
+ *
+ * returns 0 on success, <0 on error
+ */
+static int heci_release(struct inode *inode, struct file *file)
+{
+	int rets = 0;
+	int if_num = iminor(inode);
+	struct heci_file_private *file_ext = file->private_data;
+	struct heci_cb_private *priv_cb = NULL;
+	struct iamt_heci_device *dev;
+
+	if (!heci_device)
+		return -ENODEV;
+
+	dev = pci_get_drvdata(heci_device);
+	if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext))
+		return -ENODEV;
+
+	if (file_ext != &dev->iamthif_file_ext) {
+		spin_lock(&file_ext->file_lock);
+		if (file_ext->state == HECI_FILE_CONNECTED) {
+			file_ext->state = HECI_FILE_DISCONNECTING;
+			spin_unlock(&file_ext->file_lock);
+			DBG("disconnecting client host client = %d, "
+			    "ME client = %d\n",
+			    file_ext->host_client_id,
+			    file_ext->me_client_id);
+			rets = heci_disconnect_host_client(dev, file_ext);
+			spin_lock(&file_ext->file_lock);
+		}
+		spin_lock_bh(&dev->device_lock);
+		heci_flush_queues(dev, file_ext);
+		DBG("remove client host client = %d, ME client = %d\n",
+		    file_ext->host_client_id,
+		    file_ext->me_client_id);
+
+		if (dev->open_handle_count > 0) {
+			dev->heci_host_clients[file_ext->host_client_id / 8] &=
+			~(1 << (file_ext->host_client_id % 8));
+			dev->open_handle_count--;
+		}
+		heci_remove_client_from_file_list(dev,
+				file_ext->host_client_id);
+
+		/* free read cb */
+		if (file_ext->read_cb != NULL) {
+			priv_cb = find_read_list_entry(dev, file_ext);
+			/* Remove entry from read list */
+			if (priv_cb != NULL)
+				list_del(&priv_cb->cb_list);
+
+			priv_cb = file_ext->read_cb;
+			file_ext->read_cb = NULL;
+		}
+
+		spin_unlock_bh(&dev->device_lock);
+		file->private_data = NULL;
+		spin_unlock(&file_ext->file_lock);
+
+		if (priv_cb != NULL)
+			heci_free_cb_private(priv_cb);
+
+		kfree(file_ext);
+	} else {
+		spin_lock_bh(&dev->device_lock);
+
+		if (dev->open_handle_count > 0)
+			dev->open_handle_count--;
+
+		if (dev->iamthif_file_object == file
+		    && dev->iamthif_state != HECI_IAMTHIF_IDLE) {
+			DBG("pthi canceled iamthif state %d\n",
+			    dev->iamthif_state);
+			dev->iamthif_canceled = 1;
+			if (dev->iamthif_state == HECI_IAMTHIF_READ_COMPLETE) {
+				DBG("run next pthi iamthif cb\n");
+				run_next_iamthif_cmd(dev);
+			}
+		}
+
+		if (heci_clear_lists(dev, file))
+			dev->iamthif_state = HECI_IAMTHIF_IDLE;
+
+		spin_unlock_bh(&dev->device_lock);
+	}
+	return rets;
+}
+
+static struct heci_cb_private *find_read_list_entry(
+		struct iamt_heci_device *dev,
+		struct heci_file_private *file_ext)
+{
+	struct heci_cb_private *priv_cb_pos = NULL;
+	struct heci_cb_private *priv_cb_next = NULL;
+	struct heci_file_private *file_ext_list_temp;
+
+	if (dev->read_list.status == 0
+	    && !list_empty(&dev->read_list.heci_cb.cb_list)) {
+		DBG("remove read_list CB \n");
+		list_for_each_entry_safe(priv_cb_pos,
+				priv_cb_next,
+				&dev->read_list.heci_cb.cb_list, cb_list) {
+
+			file_ext_list_temp = (struct heci_file_private *)
+				priv_cb_pos->file_private;
+
+			if ((file_ext_list_temp != NULL) &&
+			    heci_fe_same_id(file_ext, file_ext_list_temp))
+				return priv_cb_pos;
+
+		}
+	}
+	return NULL;
+}
+
+/**
+ * heci_read - the read client message function.
+ *
+ * @file: pointer to file structure
+ * @ubuf: pointer to user buffer
+ * @length: buffer length
+ * @offset: data offset in buffer
+ *
+ * returns >=0 data length on success , <0 on error
+ */
+static ssize_t heci_read(struct file *file, char __user *ubuf,
+			 size_t length, loff_t *offset)
+{
+	int i;
+	int rets = 0, err = 0;
+	int if_num = iminor(file->f_dentry->d_inode);
+	struct heci_file_private *file_ext = file->private_data;
+	struct heci_cb_private *priv_cb_pos = NULL;
+	struct heci_cb_private *priv_cb = NULL;
+	struct iamt_heci_device *dev;
+
+	if (!heci_device)
+		return -ENODEV;
+
+	dev = pci_get_drvdata(heci_device);
+	if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext))
+		return -ENODEV;
+
+	spin_lock_bh(&dev->device_lock);
+	if (dev->heci_state != HECI_ENABLED) {
+		spin_unlock_bh(&dev->device_lock);
+		return -ENODEV;
+	}
+	spin_unlock_bh(&dev->device_lock);
+
+	spin_lock(&file_ext->file_lock);
+	if ((file_ext->sm_state & HECI_WD_STATE_INDEPENDENCE_MSG_SENT) == 0) {
+		spin_unlock(&file_ext->file_lock);
+		/* Do not allow to read watchdog client */
+		for (i = 0; i < dev->num_heci_me_clients; i++) {
+			if (memcmp(&heci_wd_guid,
+				   &dev->me_clients[i].props.protocol_name,
+				   sizeof(struct guid)) == 0) {
+				if (file_ext->me_client_id ==
+				    dev->me_clients[i].client_id)
+					return -EBADF;
+			}
+		}
+	} else {
+		file_ext->sm_state &= ~HECI_WD_STATE_INDEPENDENCE_MSG_SENT;
+		spin_unlock(&file_ext->file_lock);
+	}
+
+	if (file_ext == &dev->iamthif_file_ext) {
+		rets = pthi_read(dev, if_num, file, ubuf, length, offset);
+		goto out;
+	}
+
+	if (file_ext->read_cb && file_ext->read_cb->information > *offset) {
+		priv_cb = file_ext->read_cb;
+		goto copy_buffer;
+	} else if (file_ext->read_cb && file_ext->read_cb->information > 0 &&
+		   file_ext->read_cb->information <= *offset) {
+		priv_cb = file_ext->read_cb;
+		rets = 0;
+		goto free;
+	} else if ((!file_ext->read_cb || file_ext->read_cb->information == 0)
+		    && *offset > 0) {
+		/*Offset needs to be cleaned for contingous reads*/
+		*offset = 0;
+		rets = 0;
+		goto out;
+	}
+
+	spin_lock(&file_ext->read_io_lock);
+	err = heci_start_read(dev, if_num, file_ext);
+	if (err != 0 && err != -EBUSY) {
+		DBG("heci start read failure with status = %d\n", err);
+		spin_unlock(&file_ext->read_io_lock);
+		rets = err;
+		goto out;
+	}
+	if (HECI_READ_COMPLETE != file_ext->reading_state
+			&& !waitqueue_active(&file_ext->rx_wait)) {
+		if (file->f_flags & O_NONBLOCK) {
+			rets = -EAGAIN;
+			spin_unlock(&file_ext->read_io_lock);
+			goto out;
+		}
+		spin_unlock(&file_ext->read_io_lock);
+
+		if (wait_event_interruptible(file_ext->rx_wait,
+			(HECI_READ_COMPLETE == file_ext->reading_state
+			 || HECI_FILE_INITIALIZING == file_ext->state
+			 || HECI_FILE_DISCONNECTED == file_ext->state
+			 || HECI_FILE_DISCONNECTING == file_ext->state))) {
+			if (signal_pending(current)) {
+				rets = -EINTR;
+				goto out;
+			}
+			return -ERESTARTSYS;
+		}
+
+		if (HECI_FILE_INITIALIZING == file_ext->state ||
+		    HECI_FILE_DISCONNECTED == file_ext->state ||
+		    HECI_FILE_DISCONNECTING == file_ext->state) {
+			rets = -EBUSY;
+			goto out;
+		}
+		spin_lock(&file_ext->read_io_lock);
+	}
+
+	priv_cb = file_ext->read_cb;
+
+	if (!priv_cb) {
+		spin_unlock(&file_ext->read_io_lock);
+		return -ENODEV;
+	}
+	if (file_ext->reading_state != HECI_READ_COMPLETE) {
+		spin_unlock(&file_ext->read_io_lock);
+		return 0;
+	}
+	spin_unlock(&file_ext->read_io_lock);
+	/* now copy the data to user space */
+copy_buffer:
+	DBG("priv_cb->response_buffer size - %d\n",
+	    priv_cb->response_buffer.size);
+	DBG("priv_cb->information - %lu\n",
+	    priv_cb->information);
+	if (length == 0 || ubuf == NULL ||
+	    *offset > priv_cb->information) {
+		rets = -EMSGSIZE;
+		goto free;
+	}
+
+	/* length is being turncated to PAGE_SIZE, however, */
+	/* information size may be longer */
+	length = (length < (priv_cb->information - *offset) ?
+			length : (priv_cb->information - *offset));
+
+	if (copy_to_user(ubuf,
+			 priv_cb->response_buffer.data + *offset,
+			 length)) {
+		rets = -EFAULT;
+		goto free;
+	}
+
+	rets = length;
+	*offset += length;
+	if ((unsigned long)*offset < priv_cb->information)
+		goto out;
+
+free:
+	spin_lock_bh(&dev->device_lock);
+	priv_cb_pos = find_read_list_entry(dev, file_ext);
+	/* Remove entry from read list */
+	if (priv_cb_pos != NULL)
+		list_del(&priv_cb_pos->cb_list);
+	spin_unlock_bh(&dev->device_lock);
+	heci_free_cb_private(priv_cb);
+	spin_lock(&file_ext->read_io_lock);
+	file_ext->reading_state = HECI_IDLE;
+	file_ext->read_cb = NULL;
+	file_ext->read_pending = 0;
+	spin_unlock(&file_ext->read_io_lock);
+out:	DBG("end heci read rets= %d\n", rets);
+	return rets;
+}
+
+/**
+ * heci_write - the write function.
+ *
+ * @file: pointer to file structure
+ * @ubuf: pointer to user buffer
+ * @length: buffer length
+ * @offset: data offset in buffer
+ *
+ * returns >=0 data length on success , <0 on error
+ */
+static ssize_t heci_write(struct file *file, const char __user *ubuf,
+			  size_t length, loff_t *offset)
+{
+	int rets = 0;
+	__u8 i;
+	int if_num = iminor(file->f_dentry->d_inode);
+	struct heci_file_private *file_ext = file->private_data;
+	struct heci_cb_private *priv_write_cb = NULL;
+	struct heci_msg_hdr heci_hdr;
+	struct iamt_heci_device *dev;
+	unsigned long currtime = get_seconds();
+
+	if (!heci_device)
+		return -ENODEV;
+
+	dev = pci_get_drvdata(heci_device);
+
+	if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext))
+		return -ENODEV;
+
+	spin_lock_bh(&dev->device_lock);
+
+	if (dev->heci_state != HECI_ENABLED) {
+		spin_unlock_bh(&dev->device_lock);
+		return -ENODEV;
+	}
+	if (file_ext == &dev->iamthif_file_ext) {
+		priv_write_cb = find_pthi_read_list_entry(dev, file);
+		if ((priv_write_cb != NULL) &&
+		     (((currtime - priv_write_cb->read_time) >
+			    IAMTHIF_READ_TIMER) ||
+		      (file_ext->reading_state == HECI_READ_COMPLETE))) {
+			(*offset) = 0;
+			list_del(&priv_write_cb->cb_list);
+			heci_free_cb_private(priv_write_cb);
+			priv_write_cb = NULL;
+		}
+	}
+
+	/* free entry used in read */
+	if (file_ext->reading_state == HECI_READ_COMPLETE) {
+		*offset = 0;
+		priv_write_cb = find_read_list_entry(dev, file_ext);
+		if (priv_write_cb != NULL) {
+			list_del(&priv_write_cb->cb_list);
+			heci_free_cb_private(priv_write_cb);
+			priv_write_cb = NULL;
+			spin_lock(&file_ext->read_io_lock);
+			file_ext->reading_state = HECI_IDLE;
+			file_ext->read_cb = NULL;
+			file_ext->read_pending = 0;
+			spin_unlock(&file_ext->read_io_lock);
+		}
+	} else if (file_ext->reading_state == HECI_IDLE &&
+			file_ext->read_pending == 0)
+		(*offset) = 0;
+
+	spin_unlock_bh(&dev->device_lock);
+
+	priv_write_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL);
+	if (!priv_write_cb)
+		return -ENOMEM;
+
+	priv_write_cb->file_object = file;
+	priv_write_cb->file_private = file_ext;
+	priv_write_cb->request_buffer.data = kmalloc(length, GFP_KERNEL);
+	if (!priv_write_cb->request_buffer.data) {
+		kfree(priv_write_cb);
+		return -ENOMEM;
+	}
+	DBG("length =%d\n", (int) length);
+
+	if (copy_from_user(priv_write_cb->request_buffer.data,
+		ubuf, length)) {
+		rets = -EFAULT;
+		goto fail;
+	}
+
+	spin_lock(&file_ext->file_lock);
+	file_ext->sm_state = 0;
+	if ((length == 4) &&
+	    ((memcmp(heci_wd_state_independence_msg[0], ubuf, 4) == 0) ||
+	     (memcmp(heci_wd_state_independence_msg[1], ubuf, 4) == 0) ||
+	     (memcmp(heci_wd_state_independence_msg[2], ubuf, 4) == 0)))
+		file_ext->sm_state |= HECI_WD_STATE_INDEPENDENCE_MSG_SENT;
+	spin_unlock(&file_ext->file_lock);
+
+	INIT_LIST_HEAD(&priv_write_cb->cb_list);
+	if (file_ext == &dev->iamthif_file_ext) {
+		priv_write_cb->response_buffer.data =
+		    kmalloc(IAMTHIF_MTU, GFP_KERNEL);
+		if (!priv_write_cb->response_buffer.data) {
+			rets = -ENOMEM;
+			goto fail;
+		}
+		spin_lock_bh(&dev->device_lock);
+		if (dev->heci_state != HECI_ENABLED) {
+			spin_unlock_bh(&dev->device_lock);
+			rets = -ENODEV;
+			goto fail;
+		}
+		for (i = 0; i < dev->num_heci_me_clients; i++) {
+			if (dev->me_clients[i].client_id ==
+				dev->iamthif_file_ext.me_client_id)
+				break;
+		}
+
+		BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id);
+		if ((i == dev->num_heci_me_clients) ||
+		    (dev->me_clients[i].client_id !=
+		      dev->iamthif_file_ext.me_client_id)) {
+
+			spin_unlock_bh(&dev->device_lock);
+			rets = -ENODEV;
+			goto fail;
+		} else if ((length > dev->me_clients[i].props.max_msg_length)
+			    || (length <= 0)) {
+			spin_unlock_bh(&dev->device_lock);
+			rets = -EMSGSIZE;
+			goto fail;
+		}
+
+
+		priv_write_cb->response_buffer.size = IAMTHIF_MTU;
+		priv_write_cb->major_file_operations = HECI_IOCTL;
+		priv_write_cb->information = 0;
+		priv_write_cb->request_buffer.size = length;
+		if (dev->iamthif_file_ext.state != HECI_FILE_CONNECTED) {
+			spin_unlock_bh(&dev->device_lock);
+			rets = -ENODEV;
+			goto fail;
+		}
+
+		if (!list_empty(&dev->pthi_cmd_list.heci_cb.cb_list)
+				|| dev->iamthif_state != HECI_IAMTHIF_IDLE) {
+			DBG("pthi_state = %d\n", (int) dev->iamthif_state);
+			DBG("add PTHI cb to pthi cmd waiting list\n");
+			list_add_tail(&priv_write_cb->cb_list,
+					&dev->pthi_cmd_list.heci_cb.cb_list);
+			rets = length;
+		} else {
+			DBG("call pthi write\n");
+			rets = pthi_write(dev, priv_write_cb);
+
+			if (rets != 0) {
+				DBG("pthi write failed with status = %d\n",
+				    rets);
+				spin_unlock_bh(&dev->device_lock);
+				goto fail;
+			}
+			rets = length;
+		}
+		spin_unlock_bh(&dev->device_lock);
+		return rets;
+	}
+
+	priv_write_cb->major_file_operations = HECI_WRITE;
+	/* make sure information is zero before we start */
+
+	priv_write_cb->information = 0;
+	priv_write_cb->request_buffer.size = length;
+
+	spin_lock(&file_ext->write_io_lock);
+	DBG("host client = %d, ME client = %d\n",
+	    file_ext->host_client_id, file_ext->me_client_id);
+	if (file_ext->state != HECI_FILE_CONNECTED) {
+		rets = -ENODEV;
+		DBG("host client = %d,  is not connected to ME client = %d",
+		    file_ext->host_client_id,
+		    file_ext->me_client_id);
+
+		goto unlock;
+	}
+	for (i = 0; i < dev->num_heci_me_clients; i++) {
+		if (dev->me_clients[i].client_id ==
+		    file_ext->me_client_id)
+			break;
+	}
+	BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id);
+	if (i == dev->num_heci_me_clients) {
+		rets = -ENODEV;
+		goto unlock;
+	}
+	if (length > dev->me_clients[i].props.max_msg_length || length <= 0) {
+		rets = -EINVAL;
+		goto unlock;
+	}
+	priv_write_cb->file_private = file_ext;
+
+	spin_lock_bh(&dev->device_lock);
+	if (flow_ctrl_creds(dev, file_ext) &&
+		dev->host_buffer_is_empty) {
+		spin_unlock_bh(&dev->device_lock);
+		dev->host_buffer_is_empty = 0;
+		if (length > ((((dev->host_hw_state & H_CBD) >> 24) *
+			sizeof(__u32)) - sizeof(struct heci_msg_hdr))) {
+
+			heci_hdr.length =
+				(((dev->host_hw_state & H_CBD) >> 24) *
+				sizeof(__u32)) -
+				sizeof(struct heci_msg_hdr);
+			heci_hdr.msg_complete = 0;
+		} else {
+			heci_hdr.length = length;
+			heci_hdr.msg_complete = 1;
+		}
+		heci_hdr.host_addr = file_ext->host_client_id;
+		heci_hdr.me_addr = file_ext->me_client_id;
+		heci_hdr.reserved = 0;
+		DBG("call heci_write_message header=%08x.\n",
+		    *((__u32 *) &heci_hdr));
+		spin_unlock(&file_ext->write_io_lock);
+		/*  protect heci low level write */
+		spin_lock_bh(&dev->device_lock);
+		if (!heci_write_message(dev, &heci_hdr,
+			(unsigned char *) (priv_write_cb->request_buffer.data),
+			heci_hdr.length)) {
+
+			spin_unlock_bh(&dev->device_lock);
+			heci_free_cb_private(priv_write_cb);
+			rets = -ENODEV;
+			priv_write_cb->information = 0;
+			return rets;
+		}
+		file_ext->writing_state = HECI_WRITING;
+		priv_write_cb->information = heci_hdr.length;
+		if (heci_hdr.msg_complete) {
+			flow_ctrl_reduce(dev, file_ext);
+			list_add_tail(&priv_write_cb->cb_list,
+				      &dev->write_waiting_list.heci_cb.cb_list);
+		} else {
+			list_add_tail(&priv_write_cb->cb_list,
+				      &dev->write_list.heci_cb.cb_list);
+		}
+		spin_unlock_bh(&dev->device_lock);
+
+	} else {
+
+		spin_unlock_bh(&dev->device_lock);
+		priv_write_cb->information = 0;
+		file_ext->writing_state = HECI_WRITING;
+		spin_unlock(&file_ext->write_io_lock);
+		list_add_tail(&priv_write_cb->cb_list,
+			      &dev->write_list.heci_cb.cb_list);
+	}
+	return length;
+
+unlock:
+	spin_unlock(&file_ext->write_io_lock);
+fail:
+	heci_free_cb_private(priv_write_cb);
+	return rets;
+
+}
+
+/**
+ * heci_ioctl - the IOCTL function
+ *
+ * @inode: pointer to inode structure
+ * @file: pointer to file structure
+ * @cmd: ioctl command
+ * @data: pointer to heci message structure
+ *
+ * returns 0 on success , <0 on error
+ */
+static int heci_ioctl(struct inode *inode, struct file *file,
+		      unsigned int cmd, unsigned long data)
+{
+	int rets = 0;
+	int if_num = iminor(inode);
+	struct heci_file_private *file_ext = file->private_data;
+	/* in user space */
+	struct heci_message_data __user *u_msg;
+	struct heci_message_data k_msg;	/* all in kernel on the stack */
+	struct iamt_heci_device *dev;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (!heci_device)
+		return -ENODEV;
+
+	dev = pci_get_drvdata(heci_device);
+	if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext))
+		return -ENODEV;
+
+	spin_lock_bh(&dev->device_lock);
+	if (dev->heci_state != HECI_ENABLED) {
+		spin_unlock_bh(&dev->device_lock);
+		return -ENODEV;
+	}
+	spin_unlock_bh(&dev->device_lock);
+
+	/* first copy from user all data needed */
+	u_msg = (struct heci_message_data __user *)data;
+	if (copy_from_user(&k_msg, u_msg, sizeof(k_msg))) {
+		DBG("first copy from user all data needed filled\n");
+		return -EFAULT;
+	}
+	DBG("user message size is %d\n", k_msg.size);
+
+	switch (cmd) {
+	case IOCTL_HECI_GET_VERSION:
+		DBG(": IOCTL_HECI_GET_VERSION\n");
+		rets = heci_ioctl_get_version(dev, if_num, u_msg, k_msg,
+					      file_ext);
+		break;
+
+	case IOCTL_HECI_CONNECT_CLIENT:
+		DBG(": IOCTL_HECI_CONNECT_CLIENT.\n");
+		rets = heci_ioctl_connect_client(dev, if_num, u_msg, k_msg,
+						 file);
+		break;
+
+	case IOCTL_HECI_WD:
+		DBG(": IOCTL_HECI_WD.\n");
+		rets = heci_ioctl_wd(dev, if_num, k_msg, file_ext);
+		break;
+
+	case IOCTL_HECI_BYPASS_WD:
+		DBG(": IOCTL_HECI_BYPASS_WD.\n");
+		rets = heci_ioctl_bypass_wd(dev, if_num, k_msg, file_ext);
+		break;
+
+	default:
+		rets = -EINVAL;
+		break;
+	}
+	return rets;
+}
+
+/**
+ * heci_poll - the poll function
+ *
+ * @file: pointer to file structure
+ * @wait: pointer to poll_table structure
+ *
+ * returns poll mask
+ */
+static unsigned int heci_poll(struct file *file, poll_table *wait)
+{
+	int if_num = iminor(file->f_dentry->d_inode);
+	unsigned int mask = 0;
+	struct heci_file_private *file_ext = file->private_data;
+	struct iamt_heci_device *dev;
+
+	if (!heci_device)
+		return mask;
+
+	dev = pci_get_drvdata(heci_device);
+
+	if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext))
+		return mask;
+
+	spin_lock_bh(&dev->device_lock);
+	if (dev->heci_state != HECI_ENABLED) {
+		spin_unlock_bh(&dev->device_lock);
+		return mask;
+	}
+	spin_unlock_bh(&dev->device_lock);
+
+	if (file_ext == &dev->iamthif_file_ext) {
+		poll_wait(file, &dev->iamthif_file_ext.wait, wait);
+		spin_lock(&dev->iamthif_file_ext.file_lock);
+		if (dev->iamthif_state == HECI_IAMTHIF_READ_COMPLETE
+		    && dev->iamthif_file_object == file) {
+			mask |= (POLLIN | POLLRDNORM);
+			spin_lock_bh(&dev->device_lock);
+			DBG("run next pthi cb\n");
+			run_next_iamthif_cmd(dev);
+			spin_unlock_bh(&dev->device_lock);
+		}
+		spin_unlock(&dev->iamthif_file_ext.file_lock);
+
+	} else{
+		poll_wait(file, &file_ext->tx_wait, wait);
+		spin_lock(&file_ext->write_io_lock);
+		if (HECI_WRITE_COMPLETE == file_ext->writing_state)
+			mask |= (POLLIN | POLLRDNORM);
+
+		spin_unlock(&file_ext->write_io_lock);
+	}
+
+	return mask;
+}
+
+#ifdef CONFIG_PM
+static int heci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	struct iamt_heci_device *dev = pci_get_drvdata(pdev);
+	int err = 0;
+
+	spin_lock_bh(&dev->device_lock);
+	if (dev->reinit_tsk != NULL) {
+		kthread_stop(dev->reinit_tsk);
+		dev->reinit_tsk = NULL;
+	}
+	spin_unlock_bh(&dev->device_lock);
+
+	/* Stop watchdog if exists */
+	del_timer_sync(&dev->wd_timer);
+	if (dev->wd_file_ext.state == HECI_FILE_CONNECTED
+	    && dev->wd_timeout) {
+		spin_lock_bh(&dev->device_lock);
+		g_sus_wd_timeout = dev->wd_timeout;
+		dev->wd_timeout = 0;
+		dev->wd_due_counter = 0;
+		memcpy(dev->wd_data, heci_stop_wd_params,
+					HECI_WD_PARAMS_SIZE);
+		dev->stop = 1;
+		if (dev->host_buffer_is_empty &&
+		    flow_ctrl_creds(dev, &dev->wd_file_ext)) {
+			dev->host_buffer_is_empty = 0;
+			if (!heci_send_wd(dev))
+				DBG("send stop WD failed\n");
+			else
+				flow_ctrl_reduce(dev, &dev->wd_file_ext);
+
+			dev->wd_pending = 0;
+		} else {
+			dev->wd_pending = 1;
+		}
+		spin_unlock_bh(&dev->device_lock);
+		dev->wd_stoped = 0;
+
+		err = wait_event_interruptible_timeout(dev->wait_stop_wd,
+						       (dev->wd_stoped),
+						       10 * HZ);
+		if (!dev->wd_stoped)
+			DBG("stop wd failed to complete.\n");
+		else {
+			DBG("stop wd complete %d.\n", err);
+			err = 0;
+		}
+	}
+	/* Set new heci state */
+	spin_lock_bh(&dev->device_lock);
+	if (dev->heci_state == HECI_ENABLED ||
+	    dev->heci_state == HECI_RECOVERING_FROM_RESET) {
+		dev->heci_state = HECI_POWER_DOWN;
+		heci_reset(dev, 0);
+	}
+	spin_unlock_bh(&dev->device_lock);
+
+	pci_save_state(pdev);
+
+	pci_disable_device(pdev);
+	free_irq(pdev->irq, dev);
+
+	pci_set_power_state(pdev, PCI_D3hot);
+
+	return err;
+}
+
+static int heci_resume(struct pci_dev *pdev)
+{
+	struct iamt_heci_device *dev;
+	int err = 0;
+
+	pci_set_power_state(pdev, PCI_D0);
+	pci_restore_state(pdev);
+
+	dev = pci_get_drvdata(pdev);
+	if (!dev)
+		return -ENODEV;
+
+	/* request and enable interrupt   */
+	err = request_irq(pdev->irq, heci_isr_interrupt, IRQF_SHARED,
+			heci_driver_name, dev);
+	if (err) {
+		printk(KERN_ERR "heci: Request_irq failure. irq = %d \n",
+		       pdev->irq);
+		return err;
+	}
+
+	spin_lock_bh(&dev->device_lock);
+	dev->heci_state = HECI_POWER_UP;
+	heci_reset(dev, 1);
+	spin_unlock_bh(&dev->device_lock);
+
+	/* Start watchdog if stopped in suspend */
+	if (g_sus_wd_timeout != 0) {
+		dev->wd_timeout = g_sus_wd_timeout;
+
+		memcpy(dev->wd_data, heci_start_wd_params,
+					HECI_WD_PARAMS_SIZE);
+		memcpy(dev->wd_data + HECI_WD_PARAMS_SIZE,
+		       &dev->wd_timeout, sizeof(__u16));
+		dev->wd_due_counter = 1;
+
+		if (dev->wd_timeout)
+			mod_timer(&dev->wd_timer, jiffies);
+
+		g_sus_wd_timeout = 0;
+	}
+	return err;
+}
+#endif
+
+MODULE_AUTHOR("Intel Corporation");
+MODULE_DESCRIPTION("Intel(R) Management Engine Interface");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_VERSION(HECI_DRIVER_VERSION);
diff --git a/drivers/staging/heci/heci_version.h b/drivers/staging/heci/heci_version.h
new file mode 100644
index 0000000..3007aa6
--- /dev/null
+++ b/drivers/staging/heci/heci_version.h
@@ -0,0 +1,54 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * 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,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * 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 MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ *
+ */
+
+#ifndef HECI_VERSION_H
+#define HECI_VERSION_H
+
+#define MAJOR_VERSION              5
+#define MINOR_VERSION              0
+#define QUICK_FIX_NUMBER        0
+#define VER_BUILD               31
+
+#define HECI_DRV_VER1 __stringify(MAJOR_VERSION) "." __stringify(MINOR_VERSION)
+#define HECI_DRV_VER2 __stringify(QUICK_FIX_NUMBER) "." __stringify(VER_BUILD)
+
+#define HECI_DRIVER_VERSION	HECI_DRV_VER1 "." HECI_DRV_VER2
+
+#endif
diff --git a/drivers/staging/heci/interrupt.c b/drivers/staging/heci/interrupt.c
new file mode 100644
index 0000000..aacd262
--- /dev/null
+++ b/drivers/staging/heci/interrupt.c
@@ -0,0 +1,1553 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * 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,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * 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 MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ *
+ */
+
+#include <linux/kthread.h>
+
+#include "heci.h"
+#include "heci_interface.h"
+
+/*
+ *  interrupt function prototypes
+ */
+static void heci_bh_handler(struct work_struct *work);
+static int heci_bh_read_handler(struct io_heci_list *complete_list,
+		struct iamt_heci_device *dev,
+		__s32 *slots);
+static int heci_bh_write_handler(struct io_heci_list *complete_list,
+		struct iamt_heci_device *dev,
+		__s32 *slots);
+static void heci_bh_read_bus_message(struct iamt_heci_device *dev,
+		struct heci_msg_hdr *heci_hdr);
+static int heci_bh_read_pthi_message(struct io_heci_list *complete_list,
+		struct iamt_heci_device *dev,
+		struct heci_msg_hdr *heci_hdr);
+static int heci_bh_read_client_message(struct io_heci_list *complete_list,
+		struct iamt_heci_device *dev,
+		struct heci_msg_hdr *heci_hdr);
+static void heci_client_connect_response(struct iamt_heci_device *dev,
+		struct hbm_client_connect_response *connect_res);
+static void heci_client_disconnect_response(struct iamt_heci_device *dev,
+		struct hbm_client_connect_response *disconnect_res);
+static void heci_client_flow_control_response(struct iamt_heci_device *dev,
+		struct hbm_flow_control *flow_control);
+static void heci_client_disconnect_request(struct iamt_heci_device *dev,
+		struct hbm_client_disconnect_request *disconnect_req);
+
+
+/**
+ * heci_isr_interrupt - The ISR of the HECI device
+ *
+ * @irq: The irq number
+ * @dev_id: pointer to the device structure
+ *
+ * returns irqreturn_t
+ */
+irqreturn_t heci_isr_interrupt(int irq, void *dev_id)
+{
+	int err;
+	struct iamt_heci_device *dev = (struct iamt_heci_device *) dev_id;
+
+	dev->host_hw_state = read_heci_register(dev, H_CSR);
+
+	if ((dev->host_hw_state & H_IS) != H_IS)
+		return IRQ_NONE;
+
+	/* disable interrupts */
+	heci_csr_disable_interrupts(dev);
+
+	/*
+	 * Our device interrupted, schedule work the heci_bh_handler
+	 * to handle the interrupt processing. This needs to be a
+	 * workqueue item since the handler can sleep.
+	 */
+	PREPARE_WORK(&dev->work, heci_bh_handler);
+	DBG("schedule work the heci_bh_handler.\n");
+	err = schedule_work(&dev->work);
+	if (!err) {
+		printk(KERN_ERR "heci: schedule the heci_bh_handler"
+		       " failed error=%x\n", err);
+	}
+	return IRQ_HANDLED;
+}
+
+/**
+ * _heci_cmpl - process completed operation.
+ *
+ * @file_ext: private data of the file object.
+ * @priv_cb_pos: callback block.
+ */
+static void _heci_cmpl(struct heci_file_private *file_ext,
+				struct heci_cb_private *priv_cb_pos)
+{
+	if (priv_cb_pos->major_file_operations == HECI_WRITE) {
+		heci_free_cb_private(priv_cb_pos);
+		DBG("completing write call back.\n");
+		file_ext->writing_state = HECI_WRITE_COMPLETE;
+		if ((&file_ext->tx_wait) &&
+		    waitqueue_active(&file_ext->tx_wait))
+			wake_up_interruptible(&file_ext->tx_wait);
+
+	} else if (priv_cb_pos->major_file_operations == HECI_READ
+				&& HECI_READING == file_ext->reading_state) {
+		DBG("completing read call back information= %lu\n",
+				priv_cb_pos->information);
+		file_ext->reading_state = HECI_READ_COMPLETE;
+		if ((&file_ext->rx_wait) &&
+		    waitqueue_active(&file_ext->rx_wait))
+			wake_up_interruptible(&file_ext->rx_wait);
+
+	}
+}
+
+/**
+ * _heci_cmpl_iamthif - process completed iamthif operation.
+ *
+ * @dev: Device object for our driver.
+ * @priv_cb_pos: callback block.
+ */
+static void _heci_cmpl_iamthif(struct iamt_heci_device *dev,
+				struct heci_cb_private *priv_cb_pos)
+{
+	if (dev->iamthif_canceled != 1) {
+		dev->iamthif_state = HECI_IAMTHIF_READ_COMPLETE;
+		dev->iamthif_stall_timer = 0;
+		memcpy(priv_cb_pos->response_buffer.data,
+				dev->iamthif_msg_buf,
+				dev->iamthif_msg_buf_index);
+		list_add_tail(&priv_cb_pos->cb_list,
+				&dev->pthi_read_complete_list.heci_cb.cb_list);
+		DBG("pthi read completed.\n");
+	} else {
+		run_next_iamthif_cmd(dev);
+	}
+	if (&dev->iamthif_file_ext.wait) {
+		DBG("completing pthi call back.\n");
+		wake_up_interruptible(&dev->iamthif_file_ext.wait);
+	}
+}
+/**
+ * heci_bh_handler - function called after ISR to handle the interrupt
+ * processing.
+ *
+ * @work: pointer to the work structure
+ *
+ * NOTE: This function is called by schedule work
+ */
+static void heci_bh_handler(struct work_struct *work)
+{
+	struct iamt_heci_device *dev =
+		container_of(work, struct iamt_heci_device, work);
+	struct io_heci_list complete_list;
+	__s32 slots;
+	int rets;
+	struct heci_cb_private *cb_pos = NULL, *cb_next = NULL;
+	struct heci_file_private *file_ext;
+	int bus_message_received = 0;
+	struct task_struct *tsk;
+
+	DBG("function called after ISR to handle the interrupt processing.\n");
+	/* initialize our complete list */
+	spin_lock_bh(&dev->device_lock);
+	heci_initialize_list(&complete_list, dev);
+	dev->host_hw_state = read_heci_register(dev, H_CSR);
+	dev->me_hw_state = read_heci_register(dev, ME_CSR_HA);
+
+	/* check if ME wants a reset */
+	if (((dev->me_hw_state & ME_RDY_HRA) == 0)
+	    && (dev->heci_state != HECI_RESETING)
+	    && (dev->heci_state != HECI_INITIALIZING)) {
+		DBG("FW not ready.\n");
+		heci_reset(dev, 1);
+		spin_unlock_bh(&dev->device_lock);
+		return;
+	}
+
+	/*  check if we need to start the dev */
+	if ((dev->host_hw_state & H_RDY) == 0) {
+		if ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA) {
+			DBG("we need to start the dev.\n");
+			dev->host_hw_state |= (H_IE | H_IG | H_RDY);
+			heci_set_csr_register(dev);
+			if (dev->heci_state == HECI_INITIALIZING) {
+				dev->recvd_msg = 1;
+				spin_unlock_bh(&dev->device_lock);
+				wake_up_interruptible(&dev->wait_recvd_msg);
+				return;
+
+			} else {
+				spin_unlock_bh(&dev->device_lock);
+				tsk = kthread_run(heci_task_initialize_clients,
+						  dev, "heci_reinit");
+				if (IS_ERR(tsk)) {
+					int rc = PTR_ERR(tsk);
+					printk(KERN_WARNING "heci: Unable to"
+					"start the heci thread: %d\n", rc);
+				}
+				return;
+			}
+		} else {
+			DBG("enable interrupt FW not ready.\n");
+			heci_csr_enable_interrupts(dev);
+			spin_unlock_bh(&dev->device_lock);
+			return;
+		}
+	}
+	/* check slots avalable for reading */
+	slots = count_full_read_slots(dev);
+	DBG("slots =%08x  extra_write_index =%08x.\n",
+		slots, dev->extra_write_index);
+	while ((slots > 0) && (!dev->extra_write_index)) {
+		DBG("slots =%08x  extra_write_index =%08x.\n", slots,
+				dev->extra_write_index);
+		DBG("call heci_bh_read_handler.\n");
+		rets = heci_bh_read_handler(&complete_list, dev, &slots);
+		if (rets != 0)
+			goto end;
+	}
+	rets = heci_bh_write_handler(&complete_list, dev, &slots);
+end:
+	DBG("end of bottom half function.\n");
+	dev->host_hw_state = read_heci_register(dev, H_CSR);
+	dev->host_buffer_is_empty = host_buffer_is_empty(dev);
+
+	if ((dev->host_hw_state & H_IS) == H_IS) {
+		/* acknowledge interrupt and disable interrupts */
+		heci_csr_disable_interrupts(dev);
+
+		PREPARE_WORK(&dev->work, heci_bh_handler);
+		DBG("schedule work the heci_bh_handler.\n");
+		rets = schedule_work(&dev->work);
+		if (!rets) {
+			printk(KERN_ERR "heci: schedule the heci_bh_handler"
+			       " failed error=%x\n", rets);
+		}
+	} else {
+		heci_csr_enable_interrupts(dev);
+	}
+
+	if (dev->recvd_msg && waitqueue_active(&dev->wait_recvd_msg)) {
+		DBG("received waiting bus message\n");
+		bus_message_received = 1;
+	}
+	spin_unlock_bh(&dev->device_lock);
+	if (bus_message_received) {
+		DBG("wake up dev->wait_recvd_msg\n");
+		wake_up_interruptible(&dev->wait_recvd_msg);
+		bus_message_received = 0;
+	}
+	if ((complete_list.status != 0)
+	    || list_empty(&complete_list.heci_cb.cb_list))
+		return;
+
+
+	list_for_each_entry_safe(cb_pos, cb_next,
+			&complete_list.heci_cb.cb_list, cb_list) {
+		file_ext = (struct heci_file_private *)cb_pos->file_private;
+		list_del(&cb_pos->cb_list);
+		if (file_ext != NULL) {
+			if (file_ext != &dev->iamthif_file_ext) {
+				DBG("completing call back.\n");
+				_heci_cmpl(file_ext, cb_pos);
+				cb_pos = NULL;
+			} else if (file_ext == &dev->iamthif_file_ext) {
+				_heci_cmpl_iamthif(dev, cb_pos);
+			}
+		}
+	}
+}
+
+
+/**
+ * heci_bh_read_handler - bottom half read routine after ISR to
+ * handle the read processing.
+ *
+ * @cmpl_list: An instance of our list structure
+ * @dev: Device object for our driver
+ * @slots: slots to read.
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int heci_bh_read_handler(struct io_heci_list *cmpl_list,
+		struct iamt_heci_device *dev,
+		__s32 *slots)
+{
+	struct heci_msg_hdr *heci_hdr;
+	int ret = 0;
+	struct heci_file_private *file_pos = NULL;
+	struct heci_file_private *file_next = NULL;
+
+	if (!dev->rd_msg_hdr) {
+		dev->rd_msg_hdr = read_heci_register(dev, ME_CB_RW);
+		DBG("slots=%08x.\n", *slots);
+		(*slots)--;
+		DBG("slots=%08x.\n", *slots);
+	}
+	heci_hdr = (struct heci_msg_hdr *) &dev->rd_msg_hdr;
+	DBG("heci_hdr->length =%d\n", heci_hdr->length);
+
+	if ((heci_hdr->reserved) || !(dev->rd_msg_hdr)) {
+		DBG("corrupted message header.\n");
+		ret = -ECORRUPTED_MESSAGE_HEADER;
+		goto end;
+	}
+
+	if ((heci_hdr->host_addr) || (heci_hdr->me_addr)) {
+		list_for_each_entry_safe(file_pos, file_next,
+				&dev->file_list, link) {
+			DBG("list_for_each_entry_safe read host"
+					" client = %d, ME client = %d\n",
+					file_pos->host_client_id,
+					file_pos->me_client_id);
+			if ((file_pos->host_client_id == heci_hdr->host_addr)
+			    && (file_pos->me_client_id == heci_hdr->me_addr))
+				break;
+		}
+
+		if (&file_pos->link == &dev->file_list) {
+			DBG("corrupted message header\n");
+			ret = -ECORRUPTED_MESSAGE_HEADER;
+			goto end;
+		}
+	}
+	if (((*slots) * sizeof(__u32)) < heci_hdr->length) {
+		DBG("we can't read the message slots=%08x.\n", *slots);
+		/* we can't read the message */
+		ret = -ERANGE;
+		goto end;
+	}
+
+	/* decide where to read the message too */
+	if (!heci_hdr->host_addr) {
+		DBG("call heci_bh_read_bus_message.\n");
+		heci_bh_read_bus_message(dev, heci_hdr);
+		DBG("end heci_bh_read_bus_message.\n");
+	} else if ((heci_hdr->host_addr == dev->iamthif_file_ext.host_client_id)
+		   && (HECI_FILE_CONNECTED == dev->iamthif_file_ext.state)
+		   && (dev->iamthif_state == HECI_IAMTHIF_READING)) {
+		DBG("call heci_bh_read_iamthif_message.\n");
+		DBG("heci_hdr->length =%d\n", heci_hdr->length);
+		ret = heci_bh_read_pthi_message(cmpl_list, dev, heci_hdr);
+		if (ret != 0)
+			goto end;
+
+	} else {
+		DBG("call heci_bh_read_client_message.\n");
+		ret = heci_bh_read_client_message(cmpl_list, dev, heci_hdr);
+		if (ret != 0)
+			goto end;
+
+	}
+
+	/* reset the number of slots and header */
+	*slots = count_full_read_slots(dev);
+	dev->rd_msg_hdr = 0;
+
+	if (*slots == -ESLOTS_OVERFLOW) {
+		/* overflow - reset */
+		DBG("reseting due to slots overflow.\n");
+		/* set the event since message has been read */
+		ret = -ERANGE;
+		goto end;
+	}
+end:
+	return ret;
+}
+
+
+/**
+ * heci_bh_read_bus_message - bottom half read routine after ISR to
+ * handle the read bus message cmd  processing.
+ *
+ * @dev: Device object for our driver
+ * @heci_hdr: header of bus message
+ */
+static void heci_bh_read_bus_message(struct iamt_heci_device *dev,
+		struct heci_msg_hdr *heci_hdr)
+{
+	struct heci_bus_message *heci_msg;
+	struct hbm_host_version_response *version_res;
+	struct hbm_client_connect_response *connect_res;
+	struct hbm_client_connect_response *disconnect_res;
+	struct hbm_flow_control *flow_control;
+	struct hbm_props_response *props_res;
+	struct hbm_host_enum_response *enum_res;
+	struct hbm_client_disconnect_request *disconnect_req;
+	struct hbm_host_stop_request *h_stop_req;
+	int i;
+	unsigned char *buffer;
+
+	/*  read the message to our buffer */
+	buffer = (unsigned char *) dev->rd_msg_buf;
+	BUG_ON(heci_hdr->length >= sizeof(dev->rd_msg_buf));
+	heci_read_slots(dev, buffer, heci_hdr->length);
+	heci_msg = (struct heci_bus_message *) buffer;
+
+	switch (*(__u8 *) heci_msg) {
+	case HOST_START_RES_CMD:
+		version_res = (struct hbm_host_version_response *) heci_msg;
+		if (version_res->host_version_supported) {
+			dev->version.major_version = HBM_MAJOR_VERSION;
+			dev->version.minor_version = HBM_MINOR_VERSION;
+		} else {
+			dev->version = version_res->me_max_version;
+		}
+		dev->recvd_msg = 1;
+		DBG("host start response message received.\n");
+		break;
+
+	case CLIENT_CONNECT_RES_CMD:
+		connect_res =
+			(struct hbm_client_connect_response *) heci_msg;
+		heci_client_connect_response(dev, connect_res);
+		DBG("client connect response message received.\n");
+		wake_up(&dev->wait_recvd_msg);
+		break;
+
+	case CLIENT_DISCONNECT_RES_CMD:
+		disconnect_res =
+			(struct hbm_client_connect_response *) heci_msg;
+		heci_client_disconnect_response(dev,	 disconnect_res);
+		DBG("client disconnect response message received.\n");
+		wake_up(&dev->wait_recvd_msg);
+		break;
+
+	case HECI_FLOW_CONTROL_CMD:
+		flow_control = (struct hbm_flow_control *) heci_msg;
+		heci_client_flow_control_response(dev, flow_control);
+		DBG("client flow control response message received.\n");
+		break;
+
+	case HOST_CLIENT_PROPERTEIS_RES_CMD:
+		props_res = (struct hbm_props_response *) heci_msg;
+		if (props_res->status != 0) {
+			BUG();
+			break;
+		}
+		for (i = 0; i < dev->num_heci_me_clients; i++) {
+			if (dev->me_clients[i].client_id ==
+					props_res->address) {
+				dev->me_clients[i].props =
+					props_res->client_properties;
+				break;
+			}
+
+		}
+		dev->recvd_msg = 1;
+		break;
+
+	case HOST_ENUM_RES_CMD:
+		enum_res = (struct hbm_host_enum_response *) heci_msg;
+		memcpy(dev->heci_me_clients, enum_res->valid_addresses, 32);
+		dev->recvd_msg = 1;
+		break;
+
+	case HOST_STOP_RES_CMD:
+		dev->heci_state = HECI_DISABLED;
+		DBG("reseting because of FW stop response.\n");
+		heci_reset(dev, 1);
+		break;
+
+	case CLIENT_DISCONNECT_REQ_CMD:
+		/* search for client */
+		disconnect_req =
+			(struct hbm_client_disconnect_request *) heci_msg;
+		heci_client_disconnect_request(dev, disconnect_req);
+		break;
+
+	case ME_STOP_REQ_CMD:
+		/* prepare stop request */
+		heci_hdr = (struct heci_msg_hdr *) &dev->ext_msg_buf[0];
+		heci_hdr->host_addr = 0;
+		heci_hdr->me_addr = 0;
+		heci_hdr->length = sizeof(struct hbm_host_stop_request);
+		heci_hdr->msg_complete = 1;
+		heci_hdr->reserved = 0;
+		h_stop_req =
+			(struct hbm_host_stop_request *) &dev->ext_msg_buf[1];
+		memset(h_stop_req, 0, sizeof(struct hbm_host_stop_request));
+		h_stop_req->cmd.cmd = HOST_STOP_REQ_CMD;
+		h_stop_req->reason = DRIVER_STOP_REQUEST;
+		h_stop_req->reserved[0] = 0;
+		h_stop_req->reserved[1] = 0;
+		dev->extra_write_index = 2;
+		break;
+
+	default:
+		BUG();
+		break;
+
+	}
+}
+
+/**
+ * heci_bh_read_pthi_message - bottom half read routine after ISR to
+ * handle the read pthi message data processing.
+ *
+ * @complete_list: An instance of our list structure
+ * @dev: Device object for our driver
+ * @heci_hdr: header of pthi message
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int heci_bh_read_pthi_message(struct io_heci_list *complete_list,
+		struct iamt_heci_device *dev,
+		struct heci_msg_hdr *heci_hdr)
+{
+	struct heci_file_private *file_ext;
+	struct heci_cb_private *priv_cb;
+	unsigned char *buffer;
+
+	BUG_ON(heci_hdr->me_addr != dev->iamthif_file_ext.me_client_id);
+	BUG_ON(dev->iamthif_state != HECI_IAMTHIF_READING);
+
+	buffer = (unsigned char *) (dev->iamthif_msg_buf +
+			dev->iamthif_msg_buf_index);
+	BUG_ON(sizeof(dev->iamthif_msg_buf) <
+			(dev->iamthif_msg_buf_index + heci_hdr->length));
+
+	heci_read_slots(dev, buffer, heci_hdr->length);
+
+	dev->iamthif_msg_buf_index += heci_hdr->length;
+
+	if (!(heci_hdr->msg_complete))
+		return 0;
+
+	DBG("pthi_message_buffer_index=%d\n", heci_hdr->length);
+	DBG("completed pthi read.\n ");
+	if (!dev->iamthif_current_cb)
+		return -ENODEV;
+
+	priv_cb = dev->iamthif_current_cb;
+	dev->iamthif_current_cb = NULL;
+
+	file_ext = (struct heci_file_private *)priv_cb->file_private;
+	if (!file_ext)
+		return -ENODEV;
+
+	dev->iamthif_stall_timer = 0;
+	priv_cb->information =	dev->iamthif_msg_buf_index;
+	priv_cb->read_time = get_seconds();
+	if ((dev->iamthif_ioctl) && (file_ext == &dev->iamthif_file_ext)) {
+		/* found the iamthif cb */
+		DBG("complete the pthi read cb.\n ");
+		if (&dev->iamthif_file_ext) {
+			DBG("add the pthi read cb to complete.\n ");
+			list_add_tail(&priv_cb->cb_list,
+				      &complete_list->heci_cb.cb_list);
+		}
+	}
+	return 0;
+}
+
+/**
+ * _heci_bh_state_ok - check if heci header matches file private data
+ *
+ * @file_ext: private data of the file object
+ * @heci_hdr: header of heci client message
+ *
+ * returns  !=0 if matches, 0 if no match.
+ */
+static int _heci_bh_state_ok(struct heci_file_private *file_ext,
+					struct heci_msg_hdr *heci_hdr)
+{
+	return ((file_ext->host_client_id == heci_hdr->host_addr)
+		&& (file_ext->me_client_id == heci_hdr->me_addr)
+		&& (file_ext->state == HECI_FILE_CONNECTED)
+		&& (HECI_READ_COMPLETE != file_ext->reading_state));
+}
+
+/**
+ * heci_bh_read_client_message - bottom half read routine after ISR to
+ * handle the read heci client message data  processing.
+ *
+ * @complete_list: An instance of our list structure
+ * @dev: Device object for our driver
+ * @heci_hdr: header of heci client message
+ *
+ * returns  0 on success, <0 on failure.
+ */
+static int heci_bh_read_client_message(struct io_heci_list *complete_list,
+		struct iamt_heci_device *dev,
+		struct heci_msg_hdr *heci_hdr)
+{
+	struct heci_file_private *file_ext;
+	struct heci_cb_private *priv_cb_pos = NULL, *priv_cb_next = NULL;
+	unsigned char *buffer = NULL;
+
+	DBG("start client msg\n");
+	if (!((dev->read_list.status == 0) &&
+	      !list_empty(&dev->read_list.heci_cb.cb_list)))
+		goto quit;
+
+	list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+			&dev->read_list.heci_cb.cb_list, cb_list) {
+		file_ext = (struct heci_file_private *)
+				priv_cb_pos->file_private;
+		if ((file_ext != NULL) &&
+		    (_heci_bh_state_ok(file_ext, heci_hdr))) {
+			spin_lock(&file_ext->read_io_lock);
+			file_ext->reading_state = HECI_READING;
+			buffer = (unsigned char *)
+				(priv_cb_pos->response_buffer.data +
+				priv_cb_pos->information);
+			BUG_ON(priv_cb_pos->response_buffer.size <
+					heci_hdr->length +
+					priv_cb_pos->information);
+
+			if (priv_cb_pos->response_buffer.size <
+					heci_hdr->length +
+					priv_cb_pos->information) {
+				DBG("message overflow.\n");
+				list_del(&priv_cb_pos->cb_list);
+				spin_unlock(&file_ext->read_io_lock);
+				return -ENOMEM;
+			}
+			if (buffer) {
+				heci_read_slots(dev, buffer,
+						heci_hdr->length);
+			}
+			priv_cb_pos->information += heci_hdr->length;
+			if (heci_hdr->msg_complete) {
+				file_ext->status = 0;
+				list_del(&priv_cb_pos->cb_list);
+				spin_unlock(&file_ext->read_io_lock);
+				DBG("completed read host client = %d,"
+					"ME client = %d, "
+					"data length = %lu\n",
+					file_ext->host_client_id,
+					file_ext->me_client_id,
+					priv_cb_pos->information);
+
+				*(priv_cb_pos->response_buffer.data +
+					priv_cb_pos->information) = '\0';
+				DBG("priv_cb_pos->res_buffer - %s\n",
+					priv_cb_pos->response_buffer.data);
+				list_add_tail(&priv_cb_pos->cb_list,
+					&complete_list->heci_cb.cb_list);
+			} else {
+				spin_unlock(&file_ext->read_io_lock);
+			}
+
+			break;
+		}
+
+	}
+
+quit:
+	DBG("message read\n");
+	if (!buffer) {
+		heci_read_slots(dev, (unsigned char *) dev->rd_msg_buf,
+						heci_hdr->length);
+		DBG("discarding message, header=%08x.\n",
+				*(__u32 *) dev->rd_msg_buf);
+	}
+
+	return 0;
+}
+
+/**
+ * _heci_bh_iamthif_read - prepare to read iamthif data.
+ *
+ * @dev: Device object for our driver.
+ * @slots: free slots.
+ *
+ * returns  0, OK; otherwise, error.
+ */
+static int _heci_bh_iamthif_read(struct iamt_heci_device *dev,	__s32 *slots)
+{
+
+	if (((*slots) * sizeof(__u32)) >= (sizeof(struct heci_msg_hdr)
+			+ sizeof(struct hbm_flow_control))) {
+		*slots -= (sizeof(struct heci_msg_hdr) +
+				sizeof(struct hbm_flow_control) + 3) / 4;
+		if (!heci_send_flow_control(dev, &dev->iamthif_file_ext)) {
+			DBG("iamthif flow control failed\n");
+		} else {
+			DBG("iamthif flow control success\n");
+			dev->iamthif_state = HECI_IAMTHIF_READING;
+			dev->iamthif_flow_control_pending = 0;
+			dev->iamthif_msg_buf_index = 0;
+			dev->iamthif_msg_buf_size = 0;
+			dev->iamthif_stall_timer = IAMTHIF_STALL_TIMER;
+			dev->host_buffer_is_empty = host_buffer_is_empty(dev);
+		}
+		return 0;
+	} else {
+		return -ECOMPLETE_MESSAGE;
+	}
+}
+
+/**
+ * _heci_bh_close - process close related operation.
+ *
+ * @dev: Device object for our driver.
+ * @slots: free slots.
+ * @priv_cb_pos: callback block.
+ * @file_ext: private data of the file object.
+ * @cmpl_list: complete list.
+ *
+ * returns  0, OK; otherwise, error.
+ */
+static int _heci_bh_close(struct iamt_heci_device *dev,	__s32 *slots,
+			struct heci_cb_private *priv_cb_pos,
+			struct heci_file_private *file_ext,
+			struct io_heci_list *cmpl_list)
+{
+	if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_msg_hdr) +
+			sizeof(struct hbm_client_disconnect_request))) {
+		*slots -= (sizeof(struct heci_msg_hdr) +
+			sizeof(struct hbm_client_disconnect_request) + 3) / 4;
+
+		if (!heci_disconnect(dev, file_ext)) {
+			file_ext->status = 0;
+			priv_cb_pos->information = 0;
+			list_move_tail(&priv_cb_pos->cb_list,
+					&cmpl_list->heci_cb.cb_list);
+			return -ECOMPLETE_MESSAGE;
+		} else {
+			file_ext->state = HECI_FILE_DISCONNECTING;
+			file_ext->status = 0;
+			priv_cb_pos->information = 0;
+			list_move_tail(&priv_cb_pos->cb_list,
+					&dev->ctrl_rd_list.heci_cb.cb_list);
+			file_ext->timer_count = HECI_CONNECT_TIMEOUT;
+		}
+	} else {
+		/* return the cancel routine */
+		return -ECORRUPTED_MESSAGE_HEADER;
+	}
+
+	return 0;
+}
+
+/**
+ * _heci_hb_close - process read related operation.
+ *
+ * @dev: Device object for our driver.
+ * @slots: free slots.
+ * @priv_cb_pos: callback block.
+ * @file_ext: private data of the file object.
+ * @cmpl_list: complete list.
+ *
+ * returns 0, OK; otherwise, error.
+ */
+static int _heci_bh_read(struct iamt_heci_device *dev,	__s32 *slots,
+			struct heci_cb_private *priv_cb_pos,
+			struct heci_file_private *file_ext,
+			struct io_heci_list *cmpl_list)
+{
+	if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_msg_hdr) +
+			sizeof(struct hbm_flow_control))) {
+		*slots -= (sizeof(struct heci_msg_hdr) +
+			sizeof(struct hbm_flow_control) + 3) / 4;
+		if (!heci_send_flow_control(dev, file_ext)) {
+			file_ext->status = -ENODEV;
+			priv_cb_pos->information = 0;
+			list_move_tail(&priv_cb_pos->cb_list,
+					&cmpl_list->heci_cb.cb_list);
+			return -ENODEV;
+		} else {
+			list_move_tail(&priv_cb_pos->cb_list,
+					&dev->read_list.heci_cb.cb_list);
+		}
+	} else {
+		/* return the cancel routine */
+		list_del(&priv_cb_pos->cb_list);
+		return -ECORRUPTED_MESSAGE_HEADER;
+	}
+
+	return 0;
+}
+
+
+/**
+ * _heci_bh_ioctl - process ioctl related operation.
+ *
+ * @dev: Device object for our driver.
+ * @slots: free slots.
+ * @priv_cb_pos: callback block.
+ * @file_ext: private data of the file object.
+ * @cmpl_list: complete list.
+ *
+ * returns  0, OK; otherwise, error.
+ */
+static int _heci_bh_ioctl(struct iamt_heci_device *dev,	__s32 *slots,
+			struct heci_cb_private *priv_cb_pos,
+			struct heci_file_private *file_ext,
+			struct io_heci_list *cmpl_list)
+{
+	if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_msg_hdr) +
+			sizeof(struct hbm_client_connect_request))) {
+		file_ext->state = HECI_FILE_CONNECTING;
+		*slots -= (sizeof(struct heci_msg_hdr) +
+			sizeof(struct hbm_client_connect_request) + 3) / 4;
+		if (!heci_connect(dev, file_ext)) {
+			file_ext->status = -ENODEV;
+			priv_cb_pos->information = 0;
+			list_del(&priv_cb_pos->cb_list);
+			return -ENODEV;
+		} else {
+			list_move_tail(&priv_cb_pos->cb_list,
+				&dev->ctrl_rd_list.heci_cb.cb_list);
+			file_ext->timer_count = HECI_CONNECT_TIMEOUT;
+		}
+	} else {
+		/* return the cancel routine */
+		list_del(&priv_cb_pos->cb_list);
+		return -ECORRUPTED_MESSAGE_HEADER;
+	}
+
+	return 0;
+}
+
+/**
+ * _heci_bh_cmpl - process completed and no-iamthif operation.
+ *
+ * @dev: Device object for our driver.
+ * @slots: free slots.
+ * @priv_cb_pos: callback block.
+ * @file_ext: private data of the file object.
+ * @cmpl_list: complete list.
+ *
+ * returns  0, OK; otherwise, error.
+ */
+static int _heci_bh_cmpl(struct iamt_heci_device *dev,	__s32 *slots,
+			struct heci_cb_private *priv_cb_pos,
+			struct heci_file_private *file_ext,
+			struct io_heci_list *cmpl_list)
+{
+	struct heci_msg_hdr *heci_hdr;
+
+	if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_msg_hdr) +
+			(priv_cb_pos->request_buffer.size -
+			priv_cb_pos->information))) {
+		heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+		heci_hdr->host_addr = file_ext->host_client_id;
+		heci_hdr->me_addr = file_ext->me_client_id;
+		heci_hdr->length = ((priv_cb_pos->request_buffer.size) -
+				(priv_cb_pos->information));
+		heci_hdr->msg_complete = 1;
+		heci_hdr->reserved = 0;
+		DBG("priv_cb_pos->request_buffer.size =%d"
+			"heci_hdr->msg_complete= %d\n",
+				priv_cb_pos->request_buffer.size,
+				heci_hdr->msg_complete);
+		DBG("priv_cb_pos->information  =%lu\n",
+				priv_cb_pos->information);
+		DBG("heci_hdr->length  =%d\n",
+				heci_hdr->length);
+		*slots -= (sizeof(struct heci_msg_hdr) +
+				heci_hdr->length + 3) / 4;
+		if (!heci_write_message(dev, heci_hdr,
+				(unsigned char *)
+				(priv_cb_pos->request_buffer.data +
+				priv_cb_pos->information),
+				heci_hdr->length)) {
+			file_ext->status = -ENODEV;
+			list_move_tail(&priv_cb_pos->cb_list,
+				&cmpl_list->heci_cb.cb_list);
+			return -ENODEV;
+		} else {
+			flow_ctrl_reduce(dev, file_ext);
+			file_ext->status = 0;
+			priv_cb_pos->information += heci_hdr->length;
+			list_move_tail(&priv_cb_pos->cb_list,
+				&dev->write_waiting_list.heci_cb.cb_list);
+		}
+	} else if (*slots == ((dev->host_hw_state & H_CBD) >> 24)) {
+		/* buffer is still empty */
+		heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+		heci_hdr->host_addr = file_ext->host_client_id;
+		heci_hdr->me_addr = file_ext->me_client_id;
+		heci_hdr->length =
+			(*slots * sizeof(__u32)) - sizeof(struct heci_msg_hdr);
+		heci_hdr->msg_complete = 0;
+		heci_hdr->reserved = 0;
+
+		(*slots) -= (sizeof(struct heci_msg_hdr) +
+				heci_hdr->length + 3) / 4;
+		if (!heci_write_message(dev, heci_hdr,
+					(unsigned char *)
+					(priv_cb_pos->request_buffer.data +
+					priv_cb_pos->information),
+					heci_hdr->length)) {
+			file_ext->status = -ENODEV;
+			list_move_tail(&priv_cb_pos->cb_list,
+				&cmpl_list->heci_cb.cb_list);
+			return -ENODEV;
+		} else {
+			priv_cb_pos->information += heci_hdr->length;
+			DBG("priv_cb_pos->request_buffer.size =%d"
+					" heci_hdr->msg_complete= %d\n",
+					priv_cb_pos->request_buffer.size,
+					heci_hdr->msg_complete);
+			DBG("priv_cb_pos->information  =%lu\n",
+					priv_cb_pos->information);
+			DBG("heci_hdr->length  =%d\n", heci_hdr->length);
+		}
+		return -ECOMPLETE_MESSAGE;
+	} else {
+		return -ECORRUPTED_MESSAGE_HEADER;
+	}
+
+	return 0;
+}
+
+/**
+ * _heci_bh_cmpl_iamthif - process completed iamthif operation.
+ *
+ * @dev: Device object for our driver.
+ * @slots: free slots.
+ * @priv_cb_pos: callback block.
+ * @file_ext: private data of the file object.
+ * @cmpl_list: complete list.
+ *
+ * returns  0, OK; otherwise, error.
+ */
+static int _heci_bh_cmpl_iamthif(struct iamt_heci_device *dev, __s32 *slots,
+			struct heci_cb_private *priv_cb_pos,
+			struct heci_file_private *file_ext,
+			struct io_heci_list *cmpl_list)
+{
+	struct heci_msg_hdr *heci_hdr;
+
+	if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_msg_hdr) +
+			dev->iamthif_msg_buf_size -
+			dev->iamthif_msg_buf_index)) {
+		heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+		heci_hdr->host_addr = file_ext->host_client_id;
+		heci_hdr->me_addr = file_ext->me_client_id;
+		heci_hdr->length = dev->iamthif_msg_buf_size -
+			dev->iamthif_msg_buf_index;
+		heci_hdr->msg_complete = 1;
+		heci_hdr->reserved = 0;
+
+		*slots -= (sizeof(struct heci_msg_hdr) +
+				heci_hdr->length + 3) / 4;
+
+		if (!heci_write_message(dev, heci_hdr,
+					(dev->iamthif_msg_buf +
+					dev->iamthif_msg_buf_index),
+					heci_hdr->length)) {
+			dev->iamthif_state = HECI_IAMTHIF_IDLE;
+			file_ext->status = -ENODEV;
+			list_del(&priv_cb_pos->cb_list);
+			return -ENODEV;
+		} else {
+			flow_ctrl_reduce(dev, file_ext);
+			dev->iamthif_msg_buf_index += heci_hdr->length;
+			priv_cb_pos->information = dev->iamthif_msg_buf_index;
+			file_ext->status = 0;
+			dev->iamthif_state = HECI_IAMTHIF_FLOW_CONTROL;
+			dev->iamthif_flow_control_pending = 1;
+			/* save iamthif cb sent to pthi client */
+			dev->iamthif_current_cb = priv_cb_pos;
+			list_move_tail(&priv_cb_pos->cb_list,
+				&dev->write_waiting_list.heci_cb.cb_list);
+
+		}
+	} else if (*slots == ((dev->host_hw_state & H_CBD) >> 24)) {
+			/* buffer is still empty */
+		heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+		heci_hdr->host_addr = file_ext->host_client_id;
+		heci_hdr->me_addr = file_ext->me_client_id;
+		heci_hdr->length =
+			(*slots * sizeof(__u32)) - sizeof(struct heci_msg_hdr);
+		heci_hdr->msg_complete = 0;
+		heci_hdr->reserved = 0;
+
+		*slots -= (sizeof(struct heci_msg_hdr) +
+				heci_hdr->length + 3) / 4;
+
+		if (!heci_write_message(dev, heci_hdr,
+					(dev->iamthif_msg_buf +
+					dev->iamthif_msg_buf_index),
+					heci_hdr->length)) {
+			file_ext->status = -ENODEV;
+			list_del(&priv_cb_pos->cb_list);
+		} else {
+			dev->iamthif_msg_buf_index += heci_hdr->length;
+		}
+		return -ECOMPLETE_MESSAGE;
+	} else {
+		return -ECORRUPTED_MESSAGE_HEADER;
+	}
+
+	return 0;
+}
+
+/**
+ * heci_bh_write_handler - bottom half write routine after
+ * ISR to handle the write processing.
+ *
+ * @cmpl_list: An instance of our list structure
+ * @dev: Device object for our driver
+ * @slots: slots to write.
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int heci_bh_write_handler(struct io_heci_list *cmpl_list,
+		struct iamt_heci_device *dev,
+		__s32 *slots)
+{
+
+	struct heci_file_private *file_ext;
+	struct heci_cb_private *priv_cb_pos = NULL, *priv_cb_next = NULL;
+	struct io_heci_list *list;
+	int ret;
+
+	if (!host_buffer_is_empty(dev)) {
+		DBG("host buffer is not empty.\n");
+		return 0;
+	}
+	dev->write_hang = -1;
+	*slots = count_empty_write_slots(dev);
+	/* complete all waiting for write CB */
+	DBG("complete all waiting for write cb.\n");
+
+	list = &dev->write_waiting_list;
+	if ((list->status == 0)
+	    && !list_empty(&list->heci_cb.cb_list)) {
+		list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+				&list->heci_cb.cb_list, cb_list) {
+			file_ext = (struct heci_file_private *)
+					priv_cb_pos->file_private;
+			if (file_ext != NULL) {
+				file_ext->status = 0;
+				list_del(&priv_cb_pos->cb_list);
+				if ((HECI_WRITING == file_ext->writing_state) &&
+					(priv_cb_pos->major_file_operations ==
+						HECI_WRITING) &&
+					(file_ext != &dev->iamthif_file_ext)) {
+					DBG("HECI WRITE COMPLETE\n");
+					file_ext->writing_state =
+						HECI_WRITE_COMPLETE;
+					list_add_tail(&priv_cb_pos->cb_list,
+						&cmpl_list->heci_cb.cb_list);
+				}
+				if (file_ext == &dev->iamthif_file_ext) {
+					DBG("check iamthif flow control.\n");
+					if (dev->iamthif_flow_control_pending) {
+						ret = _heci_bh_iamthif_read(dev,
+									slots);
+						if (ret != 0)
+							return ret;
+					}
+				}
+			}
+
+		}
+	}
+
+	if ((dev->stop) && (!dev->wd_pending)) {
+		dev->wd_stoped = 1;
+		wake_up_interruptible(&dev->wait_stop_wd);
+		return 0;
+	}
+
+	if (dev->extra_write_index != 0) {
+		DBG("extra_write_index =%d.\n",	dev->extra_write_index);
+		heci_write_message(dev,
+				(struct heci_msg_hdr *) &dev->ext_msg_buf[0],
+				(unsigned char *) &dev->ext_msg_buf[1],
+				(dev->extra_write_index - 1) * sizeof(__u32));
+		*slots -= dev->extra_write_index;
+		dev->extra_write_index = 0;
+	}
+	if (dev->heci_state == HECI_ENABLED) {
+		if ((dev->wd_pending)
+		    && flow_ctrl_creds(dev, &dev->wd_file_ext)) {
+			if (!heci_send_wd(dev))
+				DBG("wd send failed.\n");
+			else
+				flow_ctrl_reduce(dev, &dev->wd_file_ext);
+
+			dev->wd_pending = 0;
+
+			if (dev->wd_timeout != 0) {
+				*slots -= (sizeof(struct heci_msg_hdr) +
+					 HECI_START_WD_DATA_SIZE + 3) / 4;
+				dev->wd_due_counter = 2;
+			} else {
+				*slots -= (sizeof(struct heci_msg_hdr) +
+					 HECI_WD_PARAMS_SIZE + 3) / 4;
+				dev->wd_due_counter = 0;
+			}
+
+		}
+	}
+	if (dev->stop)
+		return ~ENODEV;
+
+	/* complete control write list CB */
+	if (dev->ctrl_wr_list.status == 0) {
+		/* complete control write list CB */
+		DBG("complete control write list cb.\n");
+		list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+				&dev->ctrl_wr_list.heci_cb.cb_list, cb_list) {
+			file_ext = (struct heci_file_private *)
+				priv_cb_pos->file_private;
+			if (file_ext == NULL) {
+				list_del(&priv_cb_pos->cb_list);
+				return -ENODEV;
+			}
+			switch (priv_cb_pos->major_file_operations) {
+			case HECI_CLOSE:
+				/* send disconnect message */
+				ret = _heci_bh_close(dev, slots,
+						     priv_cb_pos,
+						     file_ext, cmpl_list);
+				if (ret != 0)
+					return ret;
+
+				break;
+			case HECI_READ:
+				/* send flow control message */
+				ret = _heci_bh_read(dev, slots,
+						    priv_cb_pos,
+						    file_ext, cmpl_list);
+				if (ret != 0)
+					return ret;
+
+				break;
+			case HECI_IOCTL:
+				/* connect message */
+				if (!other_client_is_connecting(dev, file_ext))
+					continue;
+				ret = _heci_bh_ioctl(dev, slots,
+						     priv_cb_pos,
+						     file_ext, cmpl_list);
+				if (ret != 0)
+					return ret;
+
+				break;
+
+			default:
+				BUG();
+			}
+
+		}
+	}
+	/* complete  write list CB */
+	if ((dev->write_list.status == 0)
+	    && !list_empty(&dev->write_list.heci_cb.cb_list)) {
+		DBG("complete write list cb.\n");
+		list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+				&dev->write_list.heci_cb.cb_list, cb_list) {
+			file_ext = (struct heci_file_private *)
+					priv_cb_pos->file_private;
+
+			if (file_ext != NULL) {
+				if (file_ext != &dev->iamthif_file_ext) {
+					if (!flow_ctrl_creds(dev, file_ext)) {
+						DBG("No flow control"
+						    " credentials for client"
+						    " %d, not sending.\n",
+						    file_ext->host_client_id);
+						continue;
+					}
+					ret = _heci_bh_cmpl(dev, slots,
+							    priv_cb_pos,
+							    file_ext,
+							    cmpl_list);
+					if (ret != 0)
+						return ret;
+
+				} else if (file_ext == &dev->iamthif_file_ext) {
+					/* IAMTHIF IOCTL */
+					DBG("complete pthi write cb.\n");
+					if (!flow_ctrl_creds(dev, file_ext)) {
+						DBG("No flow control"
+						    " credentials for pthi"
+						    " client %d.\n",
+						    file_ext->host_client_id);
+						continue;
+					}
+					ret = _heci_bh_cmpl_iamthif(dev, slots,
+								   priv_cb_pos,
+								   file_ext,
+								   cmpl_list);
+					if (ret != 0)
+						return ret;
+
+				}
+			}
+
+		}
+	}
+	return 0;
+}
+
+
+/**
+ * is_treat_specially_client  - check if the message belong
+ * to the file private data.
+ *
+ * @file_ext: private data of the file object
+ * @rs: connect response bus message
+ * @dev: Device object for our driver
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int is_treat_specially_client(struct heci_file_private *file_ext,
+		struct hbm_client_connect_response *rs)
+{
+	int ret = 0;
+
+	if ((file_ext->host_client_id == rs->host_addr) &&
+	    (file_ext->me_client_id == rs->me_addr)) {
+		if (rs->status == 0) {
+			DBG("client connect status = 0x%08x.\n", rs->status);
+			file_ext->state = HECI_FILE_CONNECTED;
+			file_ext->status = 0;
+		} else {
+			DBG("client connect status = 0x%08x.\n", rs->status);
+			file_ext->state = HECI_FILE_DISCONNECTED;
+			file_ext->status = -ENODEV;
+		}
+		ret = 1;
+	}
+	DBG("client state = %d.\n", file_ext->state);
+	return ret;
+}
+
+/**
+ * heci_client_connect_response  - connect response bh routine
+ *
+ * @dev: Device object for our driver
+ * @rs: connect response bus message
+ */
+static void heci_client_connect_response(struct iamt_heci_device *dev,
+		struct hbm_client_connect_response *rs)
+{
+
+	struct heci_file_private *file_ext;
+	struct heci_cb_private *priv_cb_pos = NULL, *priv_cb_next = NULL;
+
+	/* if WD or iamthif client treat specially */
+
+	if ((is_treat_specially_client(&(dev->wd_file_ext), rs)) ||
+	    (is_treat_specially_client(&(dev->iamthif_file_ext), rs)))
+		return;
+
+	if (dev->ctrl_rd_list.status == 0
+	    && !list_empty(&dev->ctrl_rd_list.heci_cb.cb_list)) {
+		list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+			&dev->ctrl_rd_list.heci_cb.cb_list, cb_list) {
+			file_ext = (struct heci_file_private *)
+					priv_cb_pos->file_private;
+			if (file_ext == NULL) {
+				list_del(&priv_cb_pos->cb_list);
+				return;
+			}
+			if (HECI_IOCTL == priv_cb_pos->major_file_operations) {
+				if (is_treat_specially_client(file_ext, rs)) {
+					list_del(&priv_cb_pos->cb_list);
+					file_ext->status = 0;
+					file_ext->timer_count = 0;
+					break;
+				}
+			}
+		}
+	}
+}
+
+/**
+ * heci_client_disconnect_response  - disconnect response bh routine
+ *
+ * @dev: Device object for our driver
+ * @rs: disconnect response bus message
+ */
+static void heci_client_disconnect_response(struct iamt_heci_device *dev,
+					struct hbm_client_connect_response *rs)
+{
+	struct heci_file_private *file_ext;
+	struct heci_cb_private *priv_cb_pos = NULL, *priv_cb_next = NULL;
+
+	if (dev->ctrl_rd_list.status == 0
+	    && !list_empty(&dev->ctrl_rd_list.heci_cb.cb_list)) {
+		list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+				&dev->ctrl_rd_list.heci_cb.cb_list, cb_list) {
+			file_ext = (struct heci_file_private *)
+				priv_cb_pos->file_private;
+
+			if (file_ext == NULL) {
+				list_del(&priv_cb_pos->cb_list);
+				return;
+			}
+
+			DBG("list_for_each_entry_safe in ctrl_rd_list.\n");
+			if ((file_ext->host_client_id == rs->host_addr) &&
+				(file_ext->me_client_id == rs->me_addr)) {
+
+				list_del(&priv_cb_pos->cb_list);
+				if (rs->status == 0) {
+					file_ext->state =
+					    HECI_FILE_DISCONNECTED;
+				}
+
+				file_ext->status = 0;
+				file_ext->timer_count = 0;
+				break;
+			}
+		}
+	}
+}
+
+/**
+ * same_flow_addr - tell they have same address.
+ *
+ * @file: private data of the file object.
+ * @flow: flow control.
+ *
+ * returns  !=0, same; 0,not.
+ */
+static int same_flow_addr(struct heci_file_private *file,
+					struct hbm_flow_control *flow)
+{
+	return ((file->host_client_id == flow->host_addr)
+		&& (file->me_client_id == flow->me_addr));
+}
+
+/**
+ * add_single_flow_creds - add single buffer credentials.
+ *
+ * @file: private data ot the file object.
+ * @flow: flow control.
+ */
+static void add_single_flow_creds(struct iamt_heci_device *dev,
+				  struct hbm_flow_control *flow)
+{
+	struct heci_me_client *client;
+	int i;
+
+	for (i = 0; i < dev->num_heci_me_clients; i++) {
+		client = &dev->me_clients[i];
+		if ((client != NULL) &&
+		    (flow->me_addr == client->client_id)) {
+			if (client->props.single_recv_buf != 0) {
+				client->flow_ctrl_creds++;
+				DBG("recv flow ctrl msg ME %d (single).\n",
+				    flow->me_addr);
+				DBG("flow control credentials=%d.\n",
+				    client->flow_ctrl_creds);
+			} else {
+				BUG();	/* error in flow control */
+			}
+		}
+	}
+}
+
+/**
+ * heci_client_flow_control_response  - flow control response bh routine
+ *
+ * @dev: Device object for our driver
+ * @flow_control: flow control response bus message
+ */
+static void heci_client_flow_control_response(struct iamt_heci_device *dev,
+		struct hbm_flow_control *flow_control)
+{
+	struct heci_file_private *file_pos = NULL;
+	struct heci_file_private *file_next = NULL;
+
+	if (flow_control->host_addr == 0) {
+		/* single receive buffer */
+		add_single_flow_creds(dev, flow_control);
+	} else {
+		/* normal connection */
+		list_for_each_entry_safe(file_pos, file_next,
+				&dev->file_list, link) {
+			DBG("list_for_each_entry_safe in file_list\n");
+
+			DBG("file_ext of host client %d ME client %d.\n",
+			    file_pos->host_client_id,
+			    file_pos->me_client_id);
+			DBG("flow ctrl msg for host %d ME %d.\n",
+			    flow_control->host_addr,
+			    flow_control->me_addr);
+			if (same_flow_addr(file_pos, flow_control)) {
+				DBG("recv ctrl msg for host  %d ME %d.\n",
+				    flow_control->host_addr,
+				    flow_control->me_addr);
+				file_pos->flow_ctrl_creds++;
+				DBG("flow control credentials=%d.\n",
+				    file_pos->flow_ctrl_creds);
+				break;
+			}
+		}
+	}
+}
+
+/**
+ * same_disconn_addr - tell they have same address
+ *
+ * @file: private data of the file object.
+ * @disconn: disconnection request.
+ *
+ * returns !=0, same; 0,not.
+ */
+static int same_disconn_addr(struct heci_file_private *file,
+			     struct hbm_client_disconnect_request *disconn)
+{
+	return ((file->host_client_id == disconn->host_addr)
+		&& (file->me_client_id == disconn->me_addr));
+}
+
+/**
+ * heci_client_disconnect_request  - disconnect request bh routine
+ *
+ * @dev: Device object for our driver.
+ * @disconnect_req: disconnect request bus message.
+ */
+static void heci_client_disconnect_request(struct iamt_heci_device *dev,
+		struct hbm_client_disconnect_request *disconnect_req)
+{
+	struct heci_msg_hdr *heci_hdr;
+	struct hbm_client_connect_response *disconnect_res;
+	struct heci_file_private *file_pos = NULL;
+	struct heci_file_private *file_next = NULL;
+
+	list_for_each_entry_safe(file_pos, file_next, &dev->file_list, link) {
+		if (same_disconn_addr(file_pos, disconnect_req)) {
+			DBG("disconnect request host client %d ME client %d.\n",
+					disconnect_req->host_addr,
+					disconnect_req->me_addr);
+			file_pos->state = HECI_FILE_DISCONNECTED;
+			file_pos->timer_count = 0;
+			if (file_pos == &dev->wd_file_ext) {
+				dev->wd_due_counter = 0;
+				dev->wd_pending = 0;
+			} else if (file_pos == &dev->iamthif_file_ext)
+				dev->iamthif_timer = 0;
+
+			/* prepare disconnect response */
+			heci_hdr =
+				(struct heci_msg_hdr *) &dev->ext_msg_buf[0];
+			heci_hdr->host_addr = 0;
+			heci_hdr->me_addr = 0;
+			heci_hdr->length =
+				sizeof(struct hbm_client_connect_response);
+			heci_hdr->msg_complete = 1;
+			heci_hdr->reserved = 0;
+
+			disconnect_res =
+				(struct hbm_client_connect_response *)
+				&dev->ext_msg_buf[1];
+			disconnect_res->host_addr = file_pos->host_client_id;
+			disconnect_res->me_addr = file_pos->me_client_id;
+			*(__u8 *) (&disconnect_res->cmd) =
+				CLIENT_DISCONNECT_RES_CMD;
+			disconnect_res->status = 0;
+			dev->extra_write_index = 2;
+			break;
+		}
+	}
+}
+
+/**
+ * heci_timer - timer function.
+ *
+ * @data: pointer to the device structure
+ *
+ * NOTE: This function is called by timer interrupt work
+ */
+void heci_wd_timer(unsigned long data)
+{
+	struct iamt_heci_device *dev = (struct iamt_heci_device *) data;
+
+	DBG("send watchdog.\n");
+	spin_lock_bh(&dev->device_lock);
+	if (dev->heci_state != HECI_ENABLED) {
+		mod_timer(&dev->wd_timer, round_jiffies(jiffies + 2 * HZ));
+		spin_unlock_bh(&dev->device_lock);
+		return;
+	}
+	if (dev->wd_file_ext.state != HECI_FILE_CONNECTED) {
+		mod_timer(&dev->wd_timer, round_jiffies(jiffies + 2 * HZ));
+		spin_unlock_bh(&dev->device_lock);
+		return;
+	}
+	/* Watchdog */
+	if ((dev->wd_due_counter != 0) && (dev->wd_bypass == 0)) {
+		if (--dev->wd_due_counter == 0) {
+			if (dev->host_buffer_is_empty &&
+			    flow_ctrl_creds(dev, &dev->wd_file_ext)) {
+				dev->host_buffer_is_empty = 0;
+				if (!heci_send_wd(dev)) {
+					DBG("wd send failed.\n");
+				} else {
+					flow_ctrl_reduce(dev,
+							 &dev->wd_file_ext);
+				}
+
+				if (dev->wd_timeout != 0)
+					dev->wd_due_counter = 2;
+				else
+					dev->wd_due_counter = 0;
+
+			} else
+				dev->wd_pending = 1;
+
+		}
+	}
+	if (dev->iamthif_stall_timer != 0) {
+		if (--dev->iamthif_stall_timer == 0) {
+			DBG("reseting because of hang to PTHI.\n");
+			heci_reset(dev, 1);
+			dev->iamthif_msg_buf_size = 0;
+			dev->iamthif_msg_buf_index = 0;
+			dev->iamthif_canceled = 0;
+			dev->iamthif_ioctl = 1;
+			dev->iamthif_state = HECI_IAMTHIF_IDLE;
+			dev->iamthif_timer = 0;
+			spin_unlock_bh(&dev->device_lock);
+
+			if (dev->iamthif_current_cb)
+				heci_free_cb_private(dev->iamthif_current_cb);
+
+			spin_lock_bh(&dev->device_lock);
+			dev->iamthif_file_object = NULL;
+			dev->iamthif_current_cb = NULL;
+			run_next_iamthif_cmd(dev);
+		}
+	}
+	mod_timer(&dev->wd_timer, round_jiffies(jiffies + 2 * HZ));
+	spin_unlock_bh(&dev->device_lock);
+}
diff --git a/drivers/staging/heci/io_heci.c b/drivers/staging/heci/io_heci.c
new file mode 100644
index 0000000..f7544a7
--- /dev/null
+++ b/drivers/staging/heci/io_heci.c
@@ -0,0 +1,847 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * 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,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * 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 MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/aio.h>
+#include <linux/pci.h>
+#include <linux/reboot.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/kdev_t.h>
+#include <linux/ioctl.h>
+#include <linux/cdev.h>
+#include <linux/list.h>
+#include <linux/unistd.h>
+#include <linux/delay.h>
+
+#include "heci_data_structures.h"
+#include "heci.h"
+#include "heci_interface.h"
+#include "heci_version.h"
+
+
+/**
+ * heci_ioctl_get_version - the get driver version IOCTL function
+ *
+ * @dev: Device object for our driver
+ * @if_num:  minor number
+ * @*u_msg: pointer to user data struct in user space
+ * @k_msg: data in kernel on the stack
+ * @file_ext: private data of the file object
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int heci_ioctl_get_version(struct iamt_heci_device *dev, int if_num,
+			   struct heci_message_data __user *u_msg,
+			   struct heci_message_data k_msg,
+			   struct heci_file_private *file_ext)
+{
+	int rets = 0;
+	struct heci_driver_version *version;
+	struct heci_message_data res_msg;
+
+	if ((if_num != HECI_MINOR_NUMBER) || (!dev)
+	    || (!file_ext))
+		return -ENODEV;
+
+	if (k_msg.size < (sizeof(struct heci_driver_version) - 2)) {
+		DBG("user buffer less than heci_driver_version.\n");
+		return -EMSGSIZE;
+	}
+
+	res_msg.data = kmalloc(sizeof(struct heci_driver_version), GFP_KERNEL);
+	if (!res_msg.data) {
+		DBG("failed allocation response buffer size = %d.\n",
+		    (int) sizeof(struct heci_driver_version));
+		return -ENOMEM;
+	}
+
+	version = (struct heci_driver_version *) res_msg.data;
+	version->major = MAJOR_VERSION;
+	version->minor = MINOR_VERSION;
+	version->hotfix = QUICK_FIX_NUMBER;
+	version->build = VER_BUILD;
+	res_msg.size = sizeof(struct heci_driver_version);
+	if (k_msg.size < sizeof(struct heci_driver_version))
+		res_msg.size -= 2;
+
+	rets = file_ext->status;
+	/* now copy the data to user space */
+	if (copy_to_user(k_msg.data, res_msg.data, res_msg.size)) {
+		rets = -EFAULT;
+		goto end;
+	}
+	if (put_user(res_msg.size, &u_msg->size)) {
+		rets = -EFAULT;
+		goto end;
+	}
+end:
+	kfree(res_msg.data);
+	return rets;
+}
+
+/**
+ * heci_ioctl_connect_client - the connect to fw client IOCTL function
+ *
+ * @dev: Device object for our driver
+ * @if_num:  minor number
+ * @*u_msg: pointer to user data struct in user space
+ * @k_msg: data in kernel on the stack
+ * @file_ext: private data of the file object
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int heci_ioctl_connect_client(struct iamt_heci_device *dev, int if_num,
+			      struct heci_message_data __user *u_msg,
+			      struct heci_message_data k_msg,
+			      struct file *file)
+{
+	int rets = 0;
+	struct heci_message_data req_msg, res_msg;
+	struct heci_cb_private *priv_cb = NULL;
+	struct heci_client *client;
+	struct heci_file_private *file_ext;
+	struct heci_file_private *file_pos = NULL;
+	struct heci_file_private *file_next = NULL;
+	long timeout = 15;	/*15 second */
+	__u8 i;
+	int err = 0;
+
+	if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file))
+		return -ENODEV;
+
+	file_ext = file->private_data;
+	if (!file_ext)
+		return -ENODEV;
+
+	if (k_msg.size != sizeof(struct guid)) {
+		DBG("user buffer size is not equal to size of struct "
+				"guid(16).\n");
+		return -EMSGSIZE;
+	}
+
+	if (!k_msg.data)
+		return -EIO;
+
+	req_msg.data = kmalloc(sizeof(struct guid), GFP_KERNEL);
+	res_msg.data = kmalloc(sizeof(struct heci_client), GFP_KERNEL);
+
+	if (!res_msg.data) {
+		DBG("failed allocation response buffer size = %d.\n",
+		    (int) sizeof(struct heci_client));
+		kfree(req_msg.data);
+		return -ENOMEM;
+	}
+	if (!req_msg.data) {
+		DBG("failed allocation request buffer size = %d.\n",
+		    (int) sizeof(struct guid));
+		kfree(res_msg.data);
+		return -ENOMEM;
+	}
+	req_msg.size = sizeof(struct guid);
+	res_msg.size = sizeof(struct heci_client);
+
+	/* copy the message to kernel space -
+	 * use a pointer already copied into kernel space
+	 */
+	if (copy_from_user(req_msg.data, k_msg.data, k_msg.size)) {
+		rets = -EFAULT;
+		goto end;
+	}
+	/* buffered ioctl cb */
+	priv_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL);
+	if (!priv_cb) {
+		rets = -ENOMEM;
+		goto end;
+	}
+	INIT_LIST_HEAD(&priv_cb->cb_list);
+	priv_cb->response_buffer.data = res_msg.data;
+	priv_cb->response_buffer.size = res_msg.size;
+	priv_cb->request_buffer.data = req_msg.data;
+	priv_cb->request_buffer.size = req_msg.size;
+	priv_cb->major_file_operations = HECI_IOCTL;
+	spin_lock_bh(&dev->device_lock);
+	if (dev->heci_state != HECI_ENABLED) {
+		rets = -ENODEV;
+		spin_unlock_bh(&dev->device_lock);
+		goto end;
+	}
+	if ((file_ext->state != HECI_FILE_INITIALIZING) &&
+	    (file_ext->state != HECI_FILE_DISCONNECTED)) {
+		rets = -EBUSY;
+		spin_unlock_bh(&dev->device_lock);
+		goto end;
+	}
+
+	/* find ME client we're trying to connect to */
+	for (i = 0; i < dev->num_heci_me_clients; i++) {
+		if (memcmp((struct guid *)req_msg.data,
+			    &dev->me_clients[i].props.protocol_name,
+			    sizeof(struct guid)) == 0) {
+			if (dev->me_clients[i].props.fixed_address == 0) {
+				file_ext->me_client_id =
+				    dev->me_clients[i].client_id;
+				file_ext->state = HECI_FILE_CONNECTING;
+			}
+			break;
+		}
+	}
+	/* if we're connecting to PTHI client so we will use the exist
+	 * connection
+	 */
+	if (memcmp((struct guid *)req_msg.data, &heci_pthi_guid,
+				sizeof(struct guid)) == 0) {
+		if (dev->iamthif_file_ext.state != HECI_FILE_CONNECTED) {
+			rets = -ENODEV;
+			spin_unlock_bh(&dev->device_lock);
+			goto end;
+		}
+		dev->heci_host_clients[file_ext->host_client_id / 8] &=
+			~(1 << (file_ext->host_client_id % 8));
+		list_for_each_entry_safe(file_pos,
+		    file_next, &dev->file_list, link) {
+			if (heci_fe_same_id(file_ext, file_pos)) {
+				DBG("remove file private data node host"
+				    " client = %d, ME client = %d.\n",
+				    file_pos->host_client_id,
+				    file_pos->me_client_id);
+				list_del(&file_pos->link);
+			}
+
+		}
+		DBG("free file private data memory.\n");
+		kfree(file_ext);
+		file_ext = NULL;
+		file->private_data = &dev->iamthif_file_ext;
+		client = (struct heci_client *) res_msg.data;
+		client->max_msg_length =
+			dev->me_clients[i].props.max_msg_length;
+		client->protocol_version =
+			dev->me_clients[i].props.protocol_version;
+		rets = dev->iamthif_file_ext.status;
+		spin_unlock_bh(&dev->device_lock);
+
+		/* now copy the data to user space */
+		if (copy_to_user(k_msg.data, res_msg.data, res_msg.size)) {
+			rets = -EFAULT;
+			goto end;
+		}
+		if (put_user(res_msg.size, &u_msg->size)) {
+			rets = -EFAULT;
+			goto end;
+		}
+		goto end;
+	}
+	spin_lock(&file_ext->file_lock);
+	if (file_ext->state != HECI_FILE_CONNECTING) {
+		rets = -ENODEV;
+		spin_unlock(&file_ext->file_lock);
+		spin_unlock_bh(&dev->device_lock);
+		goto end;
+	}
+	spin_unlock(&file_ext->file_lock);
+	/* prepare the output buffer */
+	client = (struct heci_client *) res_msg.data;
+	client->max_msg_length = dev->me_clients[i].props.max_msg_length;
+	client->protocol_version = dev->me_clients[i].props.protocol_version;
+	if (dev->host_buffer_is_empty
+	    && !other_client_is_connecting(dev, file_ext)) {
+		dev->host_buffer_is_empty = 0;
+		if (!heci_connect(dev, file_ext)) {
+			rets = -ENODEV;
+			spin_unlock_bh(&dev->device_lock);
+			goto end;
+		} else {
+			file_ext->timer_count = HECI_CONNECT_TIMEOUT;
+			priv_cb->file_private = file_ext;
+			list_add_tail(&priv_cb->cb_list,
+				      &dev->ctrl_rd_list.heci_cb.
+				      cb_list);
+		}
+
+
+	} else {
+		priv_cb->file_private = file_ext;
+		DBG("add connect cb to control write list.\n");
+		list_add_tail(&priv_cb->cb_list,
+			      &dev->ctrl_wr_list.heci_cb.cb_list);
+	}
+	spin_unlock_bh(&dev->device_lock);
+	err = wait_event_timeout(dev->wait_recvd_msg,
+			(HECI_FILE_CONNECTED == file_ext->state
+			 || HECI_FILE_DISCONNECTED == file_ext->state),
+			timeout * HZ);
+
+	if (HECI_FILE_CONNECTED == file_ext->state) {
+		DBG("successfully connected to FW client.\n");
+		rets = file_ext->status;
+		/* now copy the data to user space */
+		if (copy_to_user(k_msg.data, res_msg.data, res_msg.size)) {
+			rets = -EFAULT;
+			goto end;
+		}
+		if (put_user(res_msg.size, &u_msg->size)) {
+			rets = -EFAULT;
+			goto end;
+		}
+		goto end;
+	} else {
+		DBG("failed to connect to FW client.file_ext->state = %d.\n",
+		    file_ext->state);
+		if (!err) {
+			DBG("wait_event_interruptible_timeout failed on client"
+			    " connect message fw response message.\n");
+		}
+		rets = -EFAULT;
+		goto remove_list;
+	}
+
+remove_list:
+	if (priv_cb) {
+		spin_lock_bh(&dev->device_lock);
+		heci_flush_list(&dev->ctrl_rd_list, file_ext);
+		heci_flush_list(&dev->ctrl_wr_list, file_ext);
+		spin_unlock_bh(&dev->device_lock);
+	}
+end:
+	DBG("free connect cb memory.");
+	kfree(req_msg.data);
+	kfree(res_msg.data);
+	kfree(priv_cb);
+	return rets;
+}
+
+/**
+ * heci_ioctl_wd  - the wd IOCTL function
+ *
+ * @dev: Device object for our driver
+ * @if_num:  minor number
+ * @k_msg: data in kernel on the stack
+ * @file_ext: private data of the file object
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int heci_ioctl_wd(struct iamt_heci_device *dev, int if_num,
+		  struct heci_message_data k_msg,
+		  struct heci_file_private *file_ext)
+{
+	int rets = 0;
+	struct heci_message_data req_msg;	/*in kernel on the stack */
+
+	if (if_num != HECI_MINOR_NUMBER)
+		return -ENODEV;
+
+	spin_lock(&file_ext->file_lock);
+	if (k_msg.size != HECI_WATCHDOG_DATA_SIZE) {
+		DBG("user buffer has invalid size.\n");
+		spin_unlock(&file_ext->file_lock);
+		return -EMSGSIZE;
+	}
+	spin_unlock(&file_ext->file_lock);
+
+	req_msg.data = kmalloc(HECI_WATCHDOG_DATA_SIZE, GFP_KERNEL);
+	if (!req_msg.data) {
+		DBG("failed allocation request buffer size = %d.\n",
+		    HECI_WATCHDOG_DATA_SIZE);
+		return -ENOMEM;
+	}
+	req_msg.size = HECI_WATCHDOG_DATA_SIZE;
+
+	/* copy the message to kernel space - use a pointer already
+	 * copied into kernel space
+	 */
+	if (copy_from_user(req_msg.data, k_msg.data, req_msg.size)) {
+		rets = -EFAULT;
+		goto end;
+	}
+	spin_lock_bh(&dev->device_lock);
+	if (dev->heci_state != HECI_ENABLED) {
+		rets = -ENODEV;
+		spin_unlock_bh(&dev->device_lock);
+		goto end;
+	}
+
+	if (dev->wd_file_ext.state != HECI_FILE_CONNECTED) {
+		rets = -ENODEV;
+		spin_unlock_bh(&dev->device_lock);
+		goto end;
+	}
+	if (!dev->asf_mode) {
+		rets = -EIO;
+		spin_unlock_bh(&dev->device_lock);
+		goto end;
+	}
+
+	memcpy(&dev->wd_data[HECI_WD_PARAMS_SIZE], req_msg.data,
+	       HECI_WATCHDOG_DATA_SIZE);
+
+	dev->wd_timeout = (req_msg.data[1] << 8) + req_msg.data[0];
+	dev->wd_pending = 0;
+	dev->wd_due_counter = 1;	/* next timer */
+	if (dev->wd_timeout == 0) {
+		memcpy(dev->wd_data, heci_stop_wd_params,
+		       HECI_WD_PARAMS_SIZE);
+	} else {
+		memcpy(dev->wd_data, heci_start_wd_params,
+		       HECI_WD_PARAMS_SIZE);
+		mod_timer(&dev->wd_timer, jiffies);
+	}
+	spin_unlock_bh(&dev->device_lock);
+end:
+	kfree(req_msg.data);
+	return rets;
+}
+
+
+/**
+ * heci_ioctl_bypass_wd  - the bypass_wd IOCTL function
+ *
+ * @dev: Device object for our driver
+ * @if_num:  minor number
+ * @k_msg: data in kernel on the stack
+ * @file_ext: private data of the file object
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int heci_ioctl_bypass_wd(struct iamt_heci_device *dev, int if_num,
+		  struct heci_message_data k_msg,
+		  struct heci_file_private *file_ext)
+{
+	__u8 flag = 0;
+	int rets = 0;
+
+	if (if_num != HECI_MINOR_NUMBER)
+		return -ENODEV;
+
+	spin_lock(&file_ext->file_lock);
+	if (k_msg.size < 1) {
+		DBG("user buffer less than HECI_WATCHDOG_DATA_SIZE.\n");
+		spin_unlock(&file_ext->file_lock);
+		return -EMSGSIZE;
+	}
+	spin_unlock(&file_ext->file_lock);
+	if (copy_from_user(&flag, k_msg.data, 1)) {
+		rets = -EFAULT;
+		goto end;
+	}
+
+	spin_lock_bh(&dev->device_lock);
+	flag = flag ? (1) : (0);
+	dev->wd_bypass = flag;
+	spin_unlock_bh(&dev->device_lock);
+end:
+	return rets;
+}
+
+/**
+ * find_pthi_read_list_entry - finds a PTHIlist entry for current file
+ *
+ * @dev: Device object for our driver
+ * @file: pointer to file object
+ *
+ * returns   returned a list entry on success, NULL on failure.
+ */
+struct heci_cb_private *find_pthi_read_list_entry(
+		struct iamt_heci_device *dev,
+		struct file *file)
+{
+	struct heci_file_private *file_ext_temp;
+	struct heci_cb_private *priv_cb_pos = NULL;
+	struct heci_cb_private *priv_cb_next = NULL;
+
+	if ((dev->pthi_read_complete_list.status == 0) &&
+	    !list_empty(&dev->pthi_read_complete_list.heci_cb.cb_list)) {
+		list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+		    &dev->pthi_read_complete_list.heci_cb.cb_list, cb_list) {
+			file_ext_temp = (struct heci_file_private *)
+					priv_cb_pos->file_private;
+			if ((file_ext_temp != NULL) &&
+			    (file_ext_temp == &dev->iamthif_file_ext) &&
+			    (priv_cb_pos->file_object == file))
+				return priv_cb_pos;
+		}
+	}
+	return NULL;
+}
+
+/**
+ * pthi_read - read data from pthi client
+ *
+ * @dev: Device object for our driver
+ * @if_num:  minor number
+ * @file: pointer to file object
+ * @*ubuf: pointer to user data in user space
+ * @length: data length to read
+ * @offset: data read offset
+ *
+ * returns
+ *  returned data length on success,
+ *  zero if no data to read,
+ *  negative on failure.
+ */
+int pthi_read(struct iamt_heci_device *dev, int if_num, struct file *file,
+	      char __user *ubuf, size_t length, loff_t *offset)
+{
+	int rets = 0;
+	struct heci_cb_private *priv_cb = NULL;
+	struct heci_file_private *file_ext = file->private_data;
+	__u8 i;
+	unsigned long currtime = get_seconds();
+
+	if ((if_num != HECI_MINOR_NUMBER) || (!dev))
+		return -ENODEV;
+
+	if ((file_ext == NULL) || (file_ext != &dev->iamthif_file_ext))
+		return -ENODEV;
+
+	spin_lock_bh(&dev->device_lock);
+	for (i = 0; i < dev->num_heci_me_clients; i++) {
+		if (dev->me_clients[i].client_id ==
+		    dev->iamthif_file_ext.me_client_id)
+			break;
+	}
+	BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id);
+	if ((i == dev->num_heci_me_clients)
+	    || (dev->me_clients[i].client_id !=
+		dev->iamthif_file_ext.me_client_id)) {
+		DBG("PTHI client not found.\n");
+		spin_unlock_bh(&dev->device_lock);
+		return -ENODEV;
+	}
+	priv_cb = find_pthi_read_list_entry(dev, file);
+	if (!priv_cb) {
+		spin_unlock_bh(&dev->device_lock);
+		return 0; /* No more data to read */
+	} else {
+		if (priv_cb &&
+		    (currtime - priv_cb->read_time > IAMTHIF_READ_TIMER)) {
+			/* 15 sec for the message has expired */
+			list_del(&priv_cb->cb_list);
+			spin_unlock_bh(&dev->device_lock);
+			rets = -ETIMEDOUT;
+			goto free;
+		}
+		/* if the whole message will fit remove it from the list */
+		if ((priv_cb->information >= *offset)  &&
+		    (length >= (priv_cb->information - *offset)))
+			list_del(&priv_cb->cb_list);
+		else if ((priv_cb->information > 0) &&
+		    (priv_cb->information <= *offset)) {
+			/* end of the message has been reached */
+			list_del(&priv_cb->cb_list);
+			rets = 0;
+			spin_unlock_bh(&dev->device_lock);
+			goto free;
+		}
+		/* else means that not full buffer will be read and do not
+		 * remove message from deletion list
+		 */
+	}
+	DBG("pthi priv_cb->response_buffer size - %d\n",
+	    priv_cb->response_buffer.size);
+	DBG("pthi priv_cb->information - %lu\n",
+	    priv_cb->information);
+	spin_unlock_bh(&dev->device_lock);
+
+	/* length is being turncated to PAGE_SIZE, however,
+	 * the information may be longer */
+	length = length < (priv_cb->information - *offset) ?
+			length : (priv_cb->information - *offset);
+
+	if (copy_to_user(ubuf,
+			 priv_cb->response_buffer.data + *offset,
+			 length))
+		rets = -EFAULT;
+	else {
+		rets = length;
+		if ((*offset + length) < priv_cb->information) {
+			*offset += length;
+			goto out;
+		}
+	}
+free:
+	DBG("free pthi cb memory.\n");
+	*offset = 0;
+	heci_free_cb_private(priv_cb);
+out:
+	return rets;
+}
+
+/**
+ * heci_start_read  - the start read client message function.
+ *
+ * @dev: Device object for our driver
+ * @if_num:  minor number
+ * @file_ext: private data of the file object
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int heci_start_read(struct iamt_heci_device *dev, int if_num,
+		    struct heci_file_private *file_ext)
+{
+	int rets = 0;
+	__u8 i;
+	struct heci_cb_private *priv_cb = NULL;
+
+	if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext)) {
+		DBG("received wrong function input param.\n");
+		return -ENODEV;
+	}
+	if (file_ext->state != HECI_FILE_CONNECTED)
+		return -ENODEV;
+
+	spin_lock_bh(&dev->device_lock);
+	if (dev->heci_state != HECI_ENABLED) {
+		spin_unlock_bh(&dev->device_lock);
+		return -ENODEV;
+	}
+	spin_unlock_bh(&dev->device_lock);
+	DBG("check if read is pending.\n");
+	if ((file_ext->read_pending) || (file_ext->read_cb != NULL)) {
+		DBG("read is pending.\n");
+		return -EBUSY;
+	}
+	priv_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL);
+	if (!priv_cb)
+		return -ENOMEM;
+
+	DBG("allocation call back success\n"
+	    "host client = %d, ME client = %d\n",
+	    file_ext->host_client_id, file_ext->me_client_id);
+	spin_lock_bh(&dev->device_lock);
+	for (i = 0; i < dev->num_heci_me_clients; i++) {
+		if (dev->me_clients[i].client_id == file_ext->me_client_id)
+			break;
+
+	}
+
+	BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id);
+	if (i == dev->num_heci_me_clients) {
+		rets = -ENODEV;
+		goto unlock;
+	}
+
+	priv_cb->response_buffer.size = dev->me_clients[i].props.max_msg_length;
+	spin_unlock_bh(&dev->device_lock);
+	priv_cb->response_buffer.data =
+	    kmalloc(priv_cb->response_buffer.size, GFP_KERNEL);
+	if (!priv_cb->response_buffer.data) {
+		rets = -ENOMEM;
+		goto fail;
+	}
+	DBG("allocation call back data success.\n");
+	priv_cb->major_file_operations = HECI_READ;
+	/* make sure information is zero before we start */
+	priv_cb->information = 0;
+	priv_cb->file_private = (void *) file_ext;
+	file_ext->read_cb = priv_cb;
+	spin_lock_bh(&dev->device_lock);
+	if (dev->host_buffer_is_empty) {
+		dev->host_buffer_is_empty = 0;
+		if (!heci_send_flow_control(dev, file_ext)) {
+			rets = -ENODEV;
+			goto unlock;
+		} else {
+			list_add_tail(&priv_cb->cb_list,
+				      &dev->read_list.heci_cb.cb_list);
+		}
+	} else {
+		list_add_tail(&priv_cb->cb_list,
+			      &dev->ctrl_wr_list.heci_cb.cb_list);
+	}
+	spin_unlock_bh(&dev->device_lock);
+	return rets;
+unlock:
+	spin_unlock_bh(&dev->device_lock);
+fail:
+	heci_free_cb_private(priv_cb);
+	return rets;
+}
+
+/**
+ * pthi_write - write iamthif data to pthi client
+ *
+ * @dev: Device object for our driver
+ * @priv_cb: heci call back struct
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int pthi_write(struct iamt_heci_device *dev,
+	       struct heci_cb_private *priv_cb)
+{
+	int rets = 0;
+	struct heci_msg_hdr heci_hdr;
+
+	if ((!dev) || (!priv_cb))
+		return -ENODEV;
+
+	DBG("write data to pthi client.\n");
+
+	dev->iamthif_state = HECI_IAMTHIF_WRITING;
+	dev->iamthif_current_cb = priv_cb;
+	dev->iamthif_file_object = priv_cb->file_object;
+	dev->iamthif_canceled = 0;
+	dev->iamthif_ioctl = 1;
+	dev->iamthif_msg_buf_size = priv_cb->request_buffer.size;
+	memcpy(dev->iamthif_msg_buf, priv_cb->request_buffer.data,
+	    priv_cb->request_buffer.size);
+
+	if (flow_ctrl_creds(dev, &dev->iamthif_file_ext) &&
+	    dev->host_buffer_is_empty) {
+		dev->host_buffer_is_empty = 0;
+		if (priv_cb->request_buffer.size >
+		    (((dev->host_hw_state & H_CBD) >> 24) *
+		    sizeof(__u32)) - sizeof(struct heci_msg_hdr)) {
+			heci_hdr.length =
+			    (((dev->host_hw_state & H_CBD) >> 24) *
+			    sizeof(__u32)) - sizeof(struct heci_msg_hdr);
+			heci_hdr.msg_complete = 0;
+		} else {
+			heci_hdr.length = priv_cb->request_buffer.size;
+			heci_hdr.msg_complete = 1;
+		}
+
+		heci_hdr.host_addr = dev->iamthif_file_ext.host_client_id;
+		heci_hdr.me_addr = dev->iamthif_file_ext.me_client_id;
+		heci_hdr.reserved = 0;
+		dev->iamthif_msg_buf_index += heci_hdr.length;
+		if (!heci_write_message(dev, &heci_hdr,
+					(unsigned char *)(dev->iamthif_msg_buf),
+					heci_hdr.length))
+			return -ENODEV;
+
+		if (heci_hdr.msg_complete) {
+			flow_ctrl_reduce(dev, &dev->iamthif_file_ext);
+			dev->iamthif_flow_control_pending = 1;
+			dev->iamthif_state = HECI_IAMTHIF_FLOW_CONTROL;
+			DBG("add pthi cb to write waiting list\n");
+			dev->iamthif_current_cb = priv_cb;
+			dev->iamthif_file_object = priv_cb->file_object;
+			list_add_tail(&priv_cb->cb_list,
+				      &dev->write_waiting_list.heci_cb.cb_list);
+		} else {
+			DBG("message does not complete, "
+					"so add pthi cb to write list.\n");
+			list_add_tail(&priv_cb->cb_list,
+				      &dev->write_list.heci_cb.cb_list);
+		}
+	} else {
+		if (!(dev->host_buffer_is_empty))
+			DBG("host buffer is not empty");
+
+		DBG("No flow control credentials, "
+				"so add iamthif cb to write list.\n");
+		list_add_tail(&priv_cb->cb_list,
+			      &dev->write_list.heci_cb.cb_list);
+	}
+	return rets;
+}
+
+/**
+ * iamthif_ioctl_send_msg - send cmd data to pthi client
+ *
+ * @dev: Device object for our driver
+ *
+ * returns 0 on success, <0 on failure.
+ */
+void run_next_iamthif_cmd(struct iamt_heci_device *dev)
+{
+	struct heci_file_private *file_ext_tmp;
+	struct heci_cb_private *priv_cb_pos = NULL;
+	struct heci_cb_private *priv_cb_next = NULL;
+	int status = 0;
+
+	if (!dev)
+		return;
+
+	dev->iamthif_msg_buf_size = 0;
+	dev->iamthif_msg_buf_index = 0;
+	dev->iamthif_canceled = 0;
+	dev->iamthif_ioctl = 1;
+	dev->iamthif_state = HECI_IAMTHIF_IDLE;
+	dev->iamthif_timer = 0;
+	dev->iamthif_file_object = NULL;
+
+	if (dev->pthi_cmd_list.status == 0 &&
+	    !list_empty(&dev->pthi_cmd_list.heci_cb.cb_list)) {
+		DBG("complete pthi cmd_list cb.\n");
+
+		list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+		    &dev->pthi_cmd_list.heci_cb.cb_list, cb_list) {
+			list_del(&priv_cb_pos->cb_list);
+			file_ext_tmp = (struct heci_file_private *)
+					priv_cb_pos->file_private;
+
+			if ((file_ext_tmp != NULL) &&
+			    (file_ext_tmp == &dev->iamthif_file_ext)) {
+				status = pthi_write(dev, priv_cb_pos);
+				if (status != 0) {
+					DBG("pthi write failed status = %d\n",
+							status);
+					return;
+				}
+				break;
+			}
+		}
+	}
+}
+
+/**
+ * heci_free_cb_private - free heci_cb_private related memory
+ *
+ * @priv_cb: heci callback struct
+ */
+void heci_free_cb_private(struct heci_cb_private *priv_cb)
+{
+	if (priv_cb == NULL)
+		return;
+
+	kfree(priv_cb->request_buffer.data);
+	kfree(priv_cb->response_buffer.data);
+	kfree(priv_cb);
+}
+
diff --git a/drivers/staging/line6/Kconfig b/drivers/staging/line6/Kconfig
new file mode 100644
index 0000000..7852d4a
--- /dev/null
+++ b/drivers/staging/line6/Kconfig
@@ -0,0 +1,21 @@
+config LINE6_USB
+	tristate "Line6 USB support"
+	depends on USB && SND
+	select SND_RAWMIDI
+	help
+	  This is a driver for the guitar amp, cab, and effects modeller
+	  PODxt Pro by Line6 (and similar devices), supporting the
+	  following features:
+	    * Reading/writing individual parameters
+	    * Reading/writing complete channel, effects setup, and amp
+	      setup data
+	    * Channel switching
+	    * Virtual MIDI interface
+	    * Tuner access
+	    * Playback/capture/mixer device for any ALSA-compatible PCM
+	      audio application
+	    * Signal routing (record clean/processed guitar signal,
+	      re-amping)
+
+	  Preliminary support for the Variax Workbench is included.
+
diff --git a/drivers/staging/line6/Makefile b/drivers/staging/line6/Makefile
new file mode 100644
index 0000000..a1c93ed
--- /dev/null
+++ b/drivers/staging/line6/Makefile
@@ -0,0 +1,15 @@
+obj-$(CONFIG_LINE6_USB)		+= line6usb.o
+
+line6usb-objs := 		\
+		audio.o		\
+		capture.o	\
+		control.o	\
+		driver.o	\
+		dumprequest.o	\
+		midi.o		\
+		midibuf.o	\
+		pcm.o		\
+		playback.o	\
+		pod.o		\
+		toneport.o	\
+		variax.o
diff --git a/drivers/staging/line6/audio.c b/drivers/staging/line6/audio.c
new file mode 100644
index 0000000..3aa9468
--- /dev/null
+++ b/drivers/staging/line6/audio.c
@@ -0,0 +1,72 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *	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.
+ *
+ */
+
+#include "driver.h"
+#include "audio.h"
+
+#include <sound/core.h>
+#include <sound/initval.h>
+
+
+static int line6_index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
+static char *line6_id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
+
+
+/*
+	Initialize the Line6 USB audio system.
+*/
+int line6_init_audio(struct usb_line6 *line6)
+{
+	static int dev;
+	struct snd_card *card;
+
+	card = snd_card_new(line6_index[dev], line6_id[dev], THIS_MODULE, 0);
+
+	if (card == NULL)
+		return -ENOMEM;
+
+	line6->card = card;
+
+	strcpy(card->driver, DRIVER_NAME);
+	strcpy(card->shortname, "Line6-USB");
+	sprintf(card->longname, "Line6 %s at USB %s", line6->properties->name,
+		dev_name(line6->ifcdev));  /* 80 chars - see asound.h */
+	return 0;
+}
+
+/*
+	Register the Line6 USB audio system.
+*/
+int line6_register_audio(struct usb_line6 *line6)
+{
+	int err;
+
+	err = snd_card_register(line6->card);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+/*
+	Cleanup the Line6 USB audio system.
+*/
+void line6_cleanup_audio(struct usb_line6 *line6)
+{
+	struct snd_card *card = line6->card;
+
+	if (card == NULL)
+		return;
+
+	snd_card_disconnect(card);
+	snd_card_free(card);
+	line6->card = NULL;
+}
diff --git a/drivers/staging/line6/audio.h b/drivers/staging/line6/audio.h
new file mode 100644
index 0000000..cc0245a
--- /dev/null
+++ b/drivers/staging/line6/audio.h
@@ -0,0 +1,24 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *	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.
+ *
+ */
+
+#ifndef AUDIO_H
+#define AUDIO_H
+
+
+#include "driver.h"
+
+
+extern void line6_cleanup_audio(struct usb_line6 *);
+extern int line6_init_audio(struct usb_line6 *);
+extern int line6_register_audio(struct usb_line6 *);
+
+
+#endif
diff --git a/drivers/staging/line6/capture.c b/drivers/staging/line6/capture.c
new file mode 100644
index 0000000..8393e25
--- /dev/null
+++ b/drivers/staging/line6/capture.c
@@ -0,0 +1,372 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *	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.
+ *
+ */
+
+#include "driver.h"
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+
+#include "audio.h"
+#include "pcm.h"
+#include "pod.h"
+#include "capture.h"
+
+
+/*
+	Find a free URB and submit it.
+*/
+static int submit_audio_in_urb(struct snd_pcm_substream *substream)
+{
+	int index;
+	unsigned long flags;
+	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+	int i, urb_size;
+	struct urb *urb_in;
+
+	spin_lock_irqsave(&line6pcm->lock_audio_in, flags);
+	index = find_first_zero_bit(&line6pcm->active_urb_in, LINE6_ISO_BUFFERS);
+
+	if (index < 0 || index >= LINE6_ISO_BUFFERS) {
+		spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
+		dev_err(s2m(substream), "no free URB found\n");
+		return -EINVAL;
+	}
+
+	urb_in = line6pcm->urb_audio_in[index];
+	urb_size = 0;
+
+	for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
+		struct usb_iso_packet_descriptor *fin = &urb_in->iso_frame_desc[i];
+		fin->offset = urb_size;
+		fin->length = line6pcm->max_packet_size;
+		urb_size += line6pcm->max_packet_size;
+	}
+
+	urb_in->transfer_buffer = line6pcm->buffer_in + index * LINE6_ISO_PACKETS * line6pcm->max_packet_size;
+	urb_in->transfer_buffer_length = urb_size;
+	urb_in->context = substream;
+
+	if (usb_submit_urb(urb_in, GFP_ATOMIC) == 0)
+		set_bit(index, &line6pcm->active_urb_in);
+	else
+		dev_err(s2m(substream), "URB in #%d submission failed\n", index);
+
+	spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
+	return 0;
+}
+
+/*
+	Submit all currently available capture URBs.
+*/
+static int submit_audio_in_all_urbs(struct snd_pcm_substream *substream)
+{
+	int ret, i;
+
+	for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
+		ret = submit_audio_in_urb(substream);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+/*
+	Unlink all currently active capture URBs.
+*/
+static void unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm)
+{
+	unsigned int i;
+
+	for (i = LINE6_ISO_BUFFERS; i--;) {
+		if (test_bit(i, &line6pcm->active_urb_in)) {
+			if (!test_and_set_bit(i, &line6pcm->unlink_urb_in)) {
+				struct urb *u = line6pcm->urb_audio_in[i];
+				usb_unlink_urb(u);
+			}
+		}
+	}
+}
+
+/*
+	Wait until unlinking of all currently active capture URBs has been
+	finished.
+*/
+static void wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
+{
+	int timeout = HZ;
+	unsigned int i;
+	int alive;
+
+	do {
+		alive = 0;
+		for (i = LINE6_ISO_BUFFERS; i--;) {
+			if (test_bit(i, &line6pcm->active_urb_in))
+				alive++;
+		}
+		if (!alive)
+			break;
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(1);
+	} while (--timeout > 0);
+	if (alive)
+		snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
+
+	line6pcm->active_urb_in = 0;
+	line6pcm->unlink_urb_in = 0;
+}
+
+/*
+	Unlink all currently active capture URBs, and wait for finishing.
+*/
+void unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
+{
+	unlink_audio_in_urbs(line6pcm);
+	wait_clear_audio_in_urbs(line6pcm);
+}
+
+/*
+	Callback for completed capture URB.
+*/
+static void audio_in_callback(struct urb *urb)
+{
+	int i, index, length = 0, shutdown = 0;
+	int frames;
+	unsigned long flags;
+
+	struct snd_pcm_substream *substream = (struct snd_pcm_substream *)urb->context;
+	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+	const int bytes_per_frame = line6pcm->properties->bytes_per_frame;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+
+	/* find index of URB */
+	for (index = 0; index < LINE6_ISO_BUFFERS; ++index)
+		if (urb == line6pcm->urb_audio_in[index])
+			break;
+
+#if DO_DUMP_PCM_RECEIVE
+	for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
+		struct usb_iso_packet_descriptor *fout = &urb->iso_frame_desc[i];
+		line6_write_hexdump(line6pcm->line6, 'C', urb->transfer_buffer + fout->offset, fout->length);
+	}
+#endif
+
+	spin_lock_irqsave(&line6pcm->lock_audio_in, flags);
+
+	for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
+		char *fbuf;
+		int fsize;
+		struct usb_iso_packet_descriptor *fin = &urb->iso_frame_desc[i];
+
+		if (fin->status == -18) {
+			shutdown = 1;
+			break;
+		}
+
+		fbuf = urb->transfer_buffer + fin->offset;
+		fsize = fin->actual_length;
+		length += fsize;
+
+		if (fsize > 0) {
+			frames = fsize / bytes_per_frame;
+
+			if (line6pcm->pos_in_done + frames > runtime->buffer_size) {
+				/*
+					The transferred area goes over buffer boundary,
+					copy two separate chunks.
+				*/
+				int len;
+				len = runtime->buffer_size - line6pcm->pos_in_done;
+
+				if (len > 0) {
+					memcpy(runtime->dma_area + line6pcm->pos_in_done * bytes_per_frame, fbuf, len * bytes_per_frame);
+					memcpy(runtime->dma_area, fbuf + len * bytes_per_frame, (frames - len) * bytes_per_frame);
+				} else
+					dev_err(s2m(substream), "driver bug: len = %d\n", len);  /* this is somewhat paranoid */
+			} else {
+				/* copy single chunk */
+				memcpy(runtime->dma_area + line6pcm->pos_in_done * bytes_per_frame, fbuf, fsize * bytes_per_frame);
+			}
+
+			if ((line6pcm->pos_in_done += frames) >= runtime->buffer_size)
+				line6pcm->pos_in_done -= runtime->buffer_size;
+		}
+	}
+
+	clear_bit(index, &line6pcm->active_urb_in);
+
+	if (test_bit(index, &line6pcm->unlink_urb_in))
+		shutdown = 1;
+
+	spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
+
+	if (!shutdown) {
+		submit_audio_in_urb(substream);
+
+		if ((line6pcm->bytes_in += length) >= line6pcm->period_in) {
+			line6pcm->bytes_in -= line6pcm->period_in;
+			snd_pcm_period_elapsed(substream);
+		}
+	}
+}
+
+/* open capture callback */
+static int snd_line6_capture_open(struct snd_pcm_substream *substream)
+{
+	int err;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+
+	err = snd_pcm_hw_constraint_ratdens(runtime, 0,
+					    SNDRV_PCM_HW_PARAM_RATE,
+					    (&line6pcm->properties->snd_line6_rates));
+	if (err < 0)
+		return err;
+
+	runtime->hw = line6pcm->properties->snd_line6_capture_hw;
+	return 0;
+}
+
+/* close capture callback */
+static int snd_line6_capture_close(struct snd_pcm_substream *substream)
+{
+	return 0;
+}
+
+/* hw_params capture callback */
+static int snd_line6_capture_hw_params(struct snd_pcm_substream *substream,
+				       struct snd_pcm_hw_params *hw_params)
+{
+	int ret;
+	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+
+	/* -- Florian Demski [FD] */
+	/* don't ask me why, but this fixes the bug on my machine */
+	if (line6pcm == NULL) {
+		if (substream->pcm == NULL)
+			return -ENOMEM;
+		if (substream->pcm->private_data == NULL)
+			return -ENOMEM;
+		substream->private_data = substream->pcm->private_data;
+		line6pcm = snd_pcm_substream_chip(substream);
+	}
+	/* -- [FD] end */
+
+	ret = snd_pcm_lib_malloc_pages(substream,
+				       params_buffer_bytes(hw_params));
+	if (ret < 0)
+		return ret;
+
+	line6pcm->period_in = params_period_bytes(hw_params);
+	line6pcm->buffer_in = kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * LINE6_ISO_PACKET_SIZE_MAX, GFP_KERNEL);
+
+	if (!line6pcm->buffer_in) {
+		dev_err(s2m(substream), "cannot malloc buffer_in\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+/* hw_free capture callback */
+static int snd_line6_capture_hw_free(struct snd_pcm_substream *substream)
+{
+	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+	unlink_wait_clear_audio_in_urbs(line6pcm);
+
+	kfree(line6pcm->buffer_in);
+	line6pcm->buffer_in = NULL;
+
+	return snd_pcm_lib_free_pages(substream);
+}
+
+/* trigger callback */
+int snd_line6_capture_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+	int err;
+	line6pcm->count_in = 0;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		if (!test_and_set_bit(BIT_RUNNING_CAPTURE, &line6pcm->flags)) {
+			err = submit_audio_in_all_urbs(substream);
+
+			if (err < 0) {
+				clear_bit(BIT_RUNNING_CAPTURE, &line6pcm->flags);
+				return err;
+			}
+		}
+
+		break;
+
+	case SNDRV_PCM_TRIGGER_STOP:
+		if (test_and_clear_bit(BIT_RUNNING_CAPTURE, &line6pcm->flags))
+			unlink_audio_in_urbs(line6pcm);
+
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* capture pointer callback */
+static snd_pcm_uframes_t
+snd_line6_capture_pointer(struct snd_pcm_substream *substream)
+{
+	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+	return line6pcm->pos_in_done;
+}
+
+/* capture operators */
+struct snd_pcm_ops snd_line6_capture_ops = {
+	.open =        snd_line6_capture_open,
+	.close =       snd_line6_capture_close,
+	.ioctl =       snd_pcm_lib_ioctl,
+	.hw_params =   snd_line6_capture_hw_params,
+	.hw_free =     snd_line6_capture_hw_free,
+	.prepare =     snd_line6_prepare,
+	.trigger =     snd_line6_trigger,
+	.pointer =     snd_line6_capture_pointer,
+};
+
+int create_audio_in_urbs(struct snd_line6_pcm *line6pcm)
+{
+	int i;
+
+	/* create audio URBs and fill in constant values: */
+	for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
+		struct urb *urb;
+
+		/* URB for audio in: */
+		urb = line6pcm->urb_audio_in[i] = usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL);
+
+		if (urb == NULL) {
+			dev_err(line6pcm->line6->ifcdev, "Out of memory\n");
+			return -ENOMEM;
+		}
+
+		urb->dev = line6pcm->line6->usbdev;
+		urb->pipe = usb_rcvisocpipe(line6pcm->line6->usbdev, line6pcm->ep_audio_read & USB_ENDPOINT_NUMBER_MASK);
+		urb->transfer_flags = URB_ISO_ASAP;
+		urb->start_frame = -1;
+		urb->number_of_packets = LINE6_ISO_PACKETS;
+		urb->interval = LINE6_ISO_INTERVAL;
+		urb->error_count = 0;
+		urb->complete = audio_in_callback;
+	}
+
+	return 0;
+}
diff --git a/drivers/staging/line6/capture.h b/drivers/staging/line6/capture.h
new file mode 100644
index 0000000..5c44464
--- /dev/null
+++ b/drivers/staging/line6/capture.h
@@ -0,0 +1,32 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *	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.
+ *
+ */
+
+#ifndef CAPTURE_H
+#define CAPTURE_H
+
+
+#include "driver.h"
+
+#include <sound/pcm.h>
+
+#include "pcm.h"
+
+
+extern struct snd_pcm_ops snd_line6_capture_ops;
+
+
+extern int create_audio_in_urbs(struct snd_line6_pcm *line6pcm);
+extern int snd_line6_capture_trigger(struct snd_pcm_substream *substream,
+				     int cmd);
+extern void unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm);
+
+
+#endif
diff --git a/drivers/staging/line6/config.h b/drivers/staging/line6/config.h
new file mode 100644
index 0000000..adad130
--- /dev/null
+++ b/drivers/staging/line6/config.h
@@ -0,0 +1,48 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *	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.
+ *
+ */
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+
+#ifdef CONFIG_USB_DEBUG
+#define DEBUG 1
+#endif
+
+
+/**
+   Development tools.
+*/
+#define DO_DEBUG_MESSAGES    0
+#define DO_DUMP_URB_SEND     DO_DEBUG_MESSAGES
+#define DO_DUMP_URB_RECEIVE  DO_DEBUG_MESSAGES
+#define DO_DUMP_PCM_SEND     0
+#define DO_DUMP_PCM_RECEIVE  0
+#define DO_DUMP_MIDI_SEND    DO_DEBUG_MESSAGES
+#define DO_DUMP_MIDI_RECEIVE DO_DEBUG_MESSAGES
+#define DO_DUMP_ANY          (DO_DUMP_URB_SEND || DO_DUMP_URB_RECEIVE || \
+			      DO_DUMP_PCM_SEND || DO_DUMP_PCM_RECEIVE || \
+			      DO_DUMP_MIDI_SEND || DO_DUMP_MIDI_RECEIVE)
+#define CREATE_RAW_FILE      0
+
+#if DO_DEBUG_MESSAGES
+#define CHECKPOINT printk(KERN_INFO "line6usb: %s (%s:%d)\n", \
+			  __func__, __FILE__, __LINE__)
+#endif
+
+#if DO_DEBUG_MESSAGES
+#define DEBUG_MESSAGES(x) (x)
+#else
+#define DEBUG_MESSAGES(x)
+#endif
+
+
+#endif
diff --git a/drivers/staging/line6/control.c b/drivers/staging/line6/control.c
new file mode 100644
index 0000000..23ad08e
--- /dev/null
+++ b/drivers/staging/line6/control.c
@@ -0,0 +1,840 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *	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.
+ *
+ */
+
+#include "driver.h"
+
+#include <linux/usb.h>
+
+#include "control.h"
+#include "pod.h"
+#include "usbdefs.h"
+#include "variax.h"
+
+#define DEVICE_ATTR2(_name1, _name2, _mode, _show, _store) \
+struct device_attribute dev_attr_##_name1 = __ATTR(_name2, _mode, _show, _store)
+
+#define LINE6_PARAM_R(PREFIX, prefix, type, param) \
+static ssize_t prefix ## _get_ ## param(struct device *dev, \
+			struct device_attribute *attr, char *buf) \
+{ \
+	return prefix ## _get_param_ ## type(dev, buf, PREFIX ## _ ## param); \
+}
+
+#define LINE6_PARAM_RW(PREFIX, prefix, type, param) \
+LINE6_PARAM_R(PREFIX, prefix, type, param); \
+static ssize_t prefix ## _set_ ## param(struct device *dev, \
+		struct device_attribute *attr, const char *buf, size_t count) \
+{ \
+	return prefix ## _set_param_ ## type(dev, buf, count, PREFIX ## _ ## param); \
+}
+
+#define POD_PARAM_R(type, param) LINE6_PARAM_R(POD, pod, type, param)
+#define POD_PARAM_RW(type, param) LINE6_PARAM_RW(POD, pod, type, param)
+#define VARIAX_PARAM_R(type, param) LINE6_PARAM_R(VARIAX, variax, type, param)
+#define VARIAX_PARAM_RW(type, param) LINE6_PARAM_RW(VARIAX, variax, type, param)
+
+
+static ssize_t pod_get_param_int(struct device *dev, char *buf, int param)
+{
+	struct usb_interface *interface = to_usb_interface(dev);
+	struct usb_line6_pod *pod = usb_get_intfdata(interface);
+	int retval = line6_wait_dump(&pod->dumpreq, 0);
+	if (retval < 0)
+		return retval;
+	return sprintf(buf, "%d\n", pod->prog_data.control[param]);
+}
+
+static ssize_t pod_set_param_int(struct device *dev, const char *buf, size_t count, int param)
+{
+	struct usb_interface *interface = to_usb_interface(dev);
+	struct usb_line6_pod *pod = usb_get_intfdata(interface);
+	int value = simple_strtoul(buf, NULL, 10);
+	pod_transmit_parameter(pod, param, value);
+	return count;
+}
+
+static ssize_t variax_get_param_int(struct device *dev, char *buf, int param)
+{
+	struct usb_interface *interface = to_usb_interface(dev);
+	struct usb_line6_variax *variax = usb_get_intfdata(interface);
+	int retval = line6_wait_dump(&variax->dumpreq, 0);
+	if (retval < 0)
+		return retval;
+	return sprintf(buf, "%d\n", variax->model_data.control[param]);
+}
+
+static ssize_t variax_get_param_float(struct device *dev, char *buf, int param)
+{
+	/*
+		We do our own floating point handling here since floats in the
+		kernel are problematic for at least two reasons: - many distros
+		are still shipped with binary kernels optimized for the ancient
+		80386 without FPU
+		- there isn't a printf("%f")
+		  (see http://www.kernelthread.com/publications/faq/335.html)
+	*/
+
+	static const int BIAS = 0x7f;
+	static const int OFFSET = 0xf;
+	static const int PRECISION = 1000;
+
+	int len = 0;
+	unsigned part_int, part_frac;
+	struct usb_interface *interface = to_usb_interface(dev);
+	struct usb_line6_variax *variax = usb_get_intfdata(interface);
+	const unsigned char *p = variax->model_data.control + param;
+	int retval = line6_wait_dump(&variax->dumpreq, 0);
+	if (retval < 0)
+		return retval;
+
+	if ((p[0] == 0) && (p[1] == 0) && (p[2] == 0))
+		part_int = part_frac = 0;
+	else {
+		int exponent = (((p[0] & 0x7f) << 1) | (p[1] >> 7)) - BIAS;
+		unsigned mantissa = (p[1] << 8) | p[2] | 0x8000;
+		exponent -= OFFSET;
+
+		if (exponent >= 0) {
+			part_int = mantissa << exponent;
+			part_frac = 0;
+		} else {
+			part_int = mantissa >> -exponent;
+			part_frac = (mantissa << (32 + exponent)) & 0xffffffff;
+		}
+
+		part_frac = (part_frac / ((1UL << 31) / (PRECISION / 2 * 10)) + 5) / 10;
+	}
+
+	len += sprintf(buf + len, "%s%d.%03d\n", ((p[0] & 0x80) ? "-" : ""), part_int, part_frac);
+	return len;
+}
+
+POD_PARAM_RW(int, tweak);
+POD_PARAM_RW(int, wah_position);
+POD_PARAM_RW(int, compression_gain);
+POD_PARAM_RW(int, vol_pedal_position);
+POD_PARAM_RW(int, compression_threshold);
+POD_PARAM_RW(int, pan);
+POD_PARAM_RW(int, amp_model_setup);
+POD_PARAM_RW(int, amp_model);
+POD_PARAM_RW(int, drive);
+POD_PARAM_RW(int, bass);
+POD_PARAM_RW(int, mid);
+POD_PARAM_RW(int, lowmid);
+POD_PARAM_RW(int, treble);
+POD_PARAM_RW(int, highmid);
+POD_PARAM_RW(int, chan_vol);
+POD_PARAM_RW(int, reverb_mix);
+POD_PARAM_RW(int, effect_setup);
+POD_PARAM_RW(int, band_1_frequency);
+POD_PARAM_RW(int, presence);
+POD_PARAM_RW(int, treble__bass);
+POD_PARAM_RW(int, noise_gate_enable);
+POD_PARAM_RW(int, gate_threshold);
+POD_PARAM_RW(int, gate_decay_time);
+POD_PARAM_RW(int, stomp_enable);
+POD_PARAM_RW(int, comp_enable);
+POD_PARAM_RW(int, stomp_time);
+POD_PARAM_RW(int, delay_enable);
+POD_PARAM_RW(int, mod_param_1);
+POD_PARAM_RW(int, delay_param_1);
+POD_PARAM_RW(int, delay_param_1_note_value);
+POD_PARAM_RW(int, band_2_frequency__bass);
+POD_PARAM_RW(int, delay_param_2);
+POD_PARAM_RW(int, delay_volume_mix);
+POD_PARAM_RW(int, delay_param_3);
+POD_PARAM_RW(int, reverb_enable);
+POD_PARAM_RW(int, reverb_type);
+POD_PARAM_RW(int, reverb_decay);
+POD_PARAM_RW(int, reverb_tone);
+POD_PARAM_RW(int, reverb_pre_delay);
+POD_PARAM_RW(int, reverb_pre_post);
+POD_PARAM_RW(int, band_2_frequency);
+POD_PARAM_RW(int, band_3_frequency__bass);
+POD_PARAM_RW(int, wah_enable);
+POD_PARAM_RW(int, modulation_lo_cut);
+POD_PARAM_RW(int, delay_reverb_lo_cut);
+POD_PARAM_RW(int, volume_pedal_minimum);
+POD_PARAM_RW(int, eq_pre_post);
+POD_PARAM_RW(int, volume_pre_post);
+POD_PARAM_RW(int, di_model);
+POD_PARAM_RW(int, di_delay);
+POD_PARAM_RW(int, mod_enable);
+POD_PARAM_RW(int, mod_param_1_note_value);
+POD_PARAM_RW(int, mod_param_2);
+POD_PARAM_RW(int, mod_param_3);
+POD_PARAM_RW(int, mod_param_4);
+POD_PARAM_RW(int, mod_param_5);
+POD_PARAM_RW(int, mod_volume_mix);
+POD_PARAM_RW(int, mod_pre_post);
+POD_PARAM_RW(int, modulation_model);
+POD_PARAM_RW(int, band_3_frequency);
+POD_PARAM_RW(int, band_4_frequency__bass);
+POD_PARAM_RW(int, mod_param_1_double_precision);
+POD_PARAM_RW(int, delay_param_1_double_precision);
+POD_PARAM_RW(int, eq_enable);
+POD_PARAM_RW(int, tap);
+POD_PARAM_RW(int, volume_tweak_pedal_assign);
+POD_PARAM_RW(int, band_5_frequency);
+POD_PARAM_RW(int, tuner);
+POD_PARAM_RW(int, mic_selection);
+POD_PARAM_RW(int, cabinet_model);
+POD_PARAM_RW(int, stomp_model);
+POD_PARAM_RW(int, roomlevel);
+POD_PARAM_RW(int, band_4_frequency);
+POD_PARAM_RW(int, band_6_frequency);
+POD_PARAM_RW(int, stomp_param_1_note_value);
+POD_PARAM_RW(int, stomp_param_2);
+POD_PARAM_RW(int, stomp_param_3);
+POD_PARAM_RW(int, stomp_param_4);
+POD_PARAM_RW(int, stomp_param_5);
+POD_PARAM_RW(int, stomp_param_6);
+POD_PARAM_RW(int, amp_switch_select);
+POD_PARAM_RW(int, delay_param_4);
+POD_PARAM_RW(int, delay_param_5);
+POD_PARAM_RW(int, delay_pre_post);
+POD_PARAM_RW(int, delay_model);
+POD_PARAM_RW(int, delay_verb_model);
+POD_PARAM_RW(int, tempo_msb);
+POD_PARAM_RW(int, tempo_lsb);
+POD_PARAM_RW(int, wah_model);
+POD_PARAM_RW(int, bypass_volume);
+POD_PARAM_RW(int, fx_loop_on_off);
+POD_PARAM_RW(int, tweak_param_select);
+POD_PARAM_RW(int, amp1_engage);
+POD_PARAM_RW(int, band_1_gain);
+POD_PARAM_RW(int, band_2_gain__bass);
+POD_PARAM_RW(int, band_2_gain);
+POD_PARAM_RW(int, band_3_gain__bass);
+POD_PARAM_RW(int, band_3_gain);
+POD_PARAM_RW(int, band_4_gain__bass);
+POD_PARAM_RW(int, band_5_gain__bass);
+POD_PARAM_RW(int, band_4_gain);
+POD_PARAM_RW(int, band_6_gain__bass);
+VARIAX_PARAM_R(int, body);
+VARIAX_PARAM_R(int, pickup1_enable);
+VARIAX_PARAM_R(int, pickup1_type);
+VARIAX_PARAM_R(float, pickup1_position);
+VARIAX_PARAM_R(float, pickup1_angle);
+VARIAX_PARAM_R(float, pickup1_level);
+VARIAX_PARAM_R(int, pickup2_enable);
+VARIAX_PARAM_R(int, pickup2_type);
+VARIAX_PARAM_R(float, pickup2_position);
+VARIAX_PARAM_R(float, pickup2_angle);
+VARIAX_PARAM_R(float, pickup2_level);
+VARIAX_PARAM_R(int, pickup_phase);
+VARIAX_PARAM_R(float, capacitance);
+VARIAX_PARAM_R(float, tone_resistance);
+VARIAX_PARAM_R(float, volume_resistance);
+VARIAX_PARAM_R(int, taper);
+VARIAX_PARAM_R(float, tone_dump);
+VARIAX_PARAM_R(int, save_tone);
+VARIAX_PARAM_R(float, volume_dump);
+VARIAX_PARAM_R(int, tuning_enable);
+VARIAX_PARAM_R(int, tuning6);
+VARIAX_PARAM_R(int, tuning5);
+VARIAX_PARAM_R(int, tuning4);
+VARIAX_PARAM_R(int, tuning3);
+VARIAX_PARAM_R(int, tuning2);
+VARIAX_PARAM_R(int, tuning1);
+VARIAX_PARAM_R(float, detune6);
+VARIAX_PARAM_R(float, detune5);
+VARIAX_PARAM_R(float, detune4);
+VARIAX_PARAM_R(float, detune3);
+VARIAX_PARAM_R(float, detune2);
+VARIAX_PARAM_R(float, detune1);
+VARIAX_PARAM_R(float, mix6);
+VARIAX_PARAM_R(float, mix5);
+VARIAX_PARAM_R(float, mix4);
+VARIAX_PARAM_R(float, mix3);
+VARIAX_PARAM_R(float, mix2);
+VARIAX_PARAM_R(float, mix1);
+VARIAX_PARAM_R(int, pickup_wiring);
+
+static DEVICE_ATTR(tweak, S_IWUGO | S_IRUGO, pod_get_tweak, pod_set_tweak);
+static DEVICE_ATTR(wah_position, S_IWUGO | S_IRUGO, pod_get_wah_position, pod_set_wah_position);
+static DEVICE_ATTR(compression_gain, S_IWUGO | S_IRUGO, pod_get_compression_gain, pod_set_compression_gain);
+static DEVICE_ATTR(vol_pedal_position, S_IWUGO | S_IRUGO, pod_get_vol_pedal_position, pod_set_vol_pedal_position);
+static DEVICE_ATTR(compression_threshold, S_IWUGO | S_IRUGO, pod_get_compression_threshold, pod_set_compression_threshold);
+static DEVICE_ATTR(pan, S_IWUGO | S_IRUGO, pod_get_pan, pod_set_pan);
+static DEVICE_ATTR(amp_model_setup, S_IWUGO | S_IRUGO, pod_get_amp_model_setup, pod_set_amp_model_setup);
+static DEVICE_ATTR(amp_model, S_IWUGO | S_IRUGO, pod_get_amp_model, pod_set_amp_model);
+static DEVICE_ATTR(drive, S_IWUGO | S_IRUGO, pod_get_drive, pod_set_drive);
+static DEVICE_ATTR(bass, S_IWUGO | S_IRUGO, pod_get_bass, pod_set_bass);
+static DEVICE_ATTR(mid, S_IWUGO | S_IRUGO, pod_get_mid, pod_set_mid);
+static DEVICE_ATTR(lowmid, S_IWUGO | S_IRUGO, pod_get_lowmid, pod_set_lowmid);
+static DEVICE_ATTR(treble, S_IWUGO | S_IRUGO, pod_get_treble, pod_set_treble);
+static DEVICE_ATTR(highmid, S_IWUGO | S_IRUGO, pod_get_highmid, pod_set_highmid);
+static DEVICE_ATTR(chan_vol, S_IWUGO | S_IRUGO, pod_get_chan_vol, pod_set_chan_vol);
+static DEVICE_ATTR(reverb_mix, S_IWUGO | S_IRUGO, pod_get_reverb_mix, pod_set_reverb_mix);
+static DEVICE_ATTR(effect_setup, S_IWUGO | S_IRUGO, pod_get_effect_setup, pod_set_effect_setup);
+static DEVICE_ATTR(band_1_frequency, S_IWUGO | S_IRUGO, pod_get_band_1_frequency, pod_set_band_1_frequency);
+static DEVICE_ATTR(presence, S_IWUGO | S_IRUGO, pod_get_presence, pod_set_presence);
+static DEVICE_ATTR2(treble__bass, treble, S_IWUGO | S_IRUGO, pod_get_treble__bass, pod_set_treble__bass);
+static DEVICE_ATTR(noise_gate_enable, S_IWUGO | S_IRUGO, pod_get_noise_gate_enable, pod_set_noise_gate_enable);
+static DEVICE_ATTR(gate_threshold, S_IWUGO | S_IRUGO, pod_get_gate_threshold, pod_set_gate_threshold);
+static DEVICE_ATTR(gate_decay_time, S_IWUGO | S_IRUGO, pod_get_gate_decay_time, pod_set_gate_decay_time);
+static DEVICE_ATTR(stomp_enable, S_IWUGO | S_IRUGO, pod_get_stomp_enable, pod_set_stomp_enable);
+static DEVICE_ATTR(comp_enable, S_IWUGO | S_IRUGO, pod_get_comp_enable, pod_set_comp_enable);
+static DEVICE_ATTR(stomp_time, S_IWUGO | S_IRUGO, pod_get_stomp_time, pod_set_stomp_time);
+static DEVICE_ATTR(delay_enable, S_IWUGO | S_IRUGO, pod_get_delay_enable, pod_set_delay_enable);
+static DEVICE_ATTR(mod_param_1, S_IWUGO | S_IRUGO, pod_get_mod_param_1, pod_set_mod_param_1);
+static DEVICE_ATTR(delay_param_1, S_IWUGO | S_IRUGO, pod_get_delay_param_1, pod_set_delay_param_1);
+static DEVICE_ATTR(delay_param_1_note_value, S_IWUGO | S_IRUGO, pod_get_delay_param_1_note_value, pod_set_delay_param_1_note_value);
+static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IWUGO | S_IRUGO, pod_get_band_2_frequency__bass, pod_set_band_2_frequency__bass);
+static DEVICE_ATTR(delay_param_2, S_IWUGO | S_IRUGO, pod_get_delay_param_2, pod_set_delay_param_2);
+static DEVICE_ATTR(delay_volume_mix, S_IWUGO | S_IRUGO, pod_get_delay_volume_mix, pod_set_delay_volume_mix);
+static DEVICE_ATTR(delay_param_3, S_IWUGO | S_IRUGO, pod_get_delay_param_3, pod_set_delay_param_3);
+static DEVICE_ATTR(reverb_enable, S_IWUGO | S_IRUGO, pod_get_reverb_enable, pod_set_reverb_enable);
+static DEVICE_ATTR(reverb_type, S_IWUGO | S_IRUGO, pod_get_reverb_type, pod_set_reverb_type);
+static DEVICE_ATTR(reverb_decay, S_IWUGO | S_IRUGO, pod_get_reverb_decay, pod_set_reverb_decay);
+static DEVICE_ATTR(reverb_tone, S_IWUGO | S_IRUGO, pod_get_reverb_tone, pod_set_reverb_tone);
+static DEVICE_ATTR(reverb_pre_delay, S_IWUGO | S_IRUGO, pod_get_reverb_pre_delay, pod_set_reverb_pre_delay);
+static DEVICE_ATTR(reverb_pre_post, S_IWUGO | S_IRUGO, pod_get_reverb_pre_post, pod_set_reverb_pre_post);
+static DEVICE_ATTR(band_2_frequency, S_IWUGO | S_IRUGO, pod_get_band_2_frequency, pod_set_band_2_frequency);
+static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IWUGO | S_IRUGO, pod_get_band_3_frequency__bass, pod_set_band_3_frequency__bass);
+static DEVICE_ATTR(wah_enable, S_IWUGO | S_IRUGO, pod_get_wah_enable, pod_set_wah_enable);
+static DEVICE_ATTR(modulation_lo_cut, S_IWUGO | S_IRUGO, pod_get_modulation_lo_cut, pod_set_modulation_lo_cut);
+static DEVICE_ATTR(delay_reverb_lo_cut, S_IWUGO | S_IRUGO, pod_get_delay_reverb_lo_cut, pod_set_delay_reverb_lo_cut);
+static DEVICE_ATTR(volume_pedal_minimum, S_IWUGO | S_IRUGO, pod_get_volume_pedal_minimum, pod_set_volume_pedal_minimum);
+static DEVICE_ATTR(eq_pre_post, S_IWUGO | S_IRUGO, pod_get_eq_pre_post, pod_set_eq_pre_post);
+static DEVICE_ATTR(volume_pre_post, S_IWUGO | S_IRUGO, pod_get_volume_pre_post, pod_set_volume_pre_post);
+static DEVICE_ATTR(di_model, S_IWUGO | S_IRUGO, pod_get_di_model, pod_set_di_model);
+static DEVICE_ATTR(di_delay, S_IWUGO | S_IRUGO, pod_get_di_delay, pod_set_di_delay);
+static DEVICE_ATTR(mod_enable, S_IWUGO | S_IRUGO, pod_get_mod_enable, pod_set_mod_enable);
+static DEVICE_ATTR(mod_param_1_note_value, S_IWUGO | S_IRUGO, pod_get_mod_param_1_note_value, pod_set_mod_param_1_note_value);
+static DEVICE_ATTR(mod_param_2, S_IWUGO | S_IRUGO, pod_get_mod_param_2, pod_set_mod_param_2);
+static DEVICE_ATTR(mod_param_3, S_IWUGO | S_IRUGO, pod_get_mod_param_3, pod_set_mod_param_3);
+static DEVICE_ATTR(mod_param_4, S_IWUGO | S_IRUGO, pod_get_mod_param_4, pod_set_mod_param_4);
+static DEVICE_ATTR(mod_param_5, S_IWUGO | S_IRUGO, pod_get_mod_param_5, pod_set_mod_param_5);
+static DEVICE_ATTR(mod_volume_mix, S_IWUGO | S_IRUGO, pod_get_mod_volume_mix, pod_set_mod_volume_mix);
+static DEVICE_ATTR(mod_pre_post, S_IWUGO | S_IRUGO, pod_get_mod_pre_post, pod_set_mod_pre_post);
+static DEVICE_ATTR(modulation_model, S_IWUGO | S_IRUGO, pod_get_modulation_model, pod_set_modulation_model);
+static DEVICE_ATTR(band_3_frequency, S_IWUGO | S_IRUGO, pod_get_band_3_frequency, pod_set_band_3_frequency);
+static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IWUGO | S_IRUGO, pod_get_band_4_frequency__bass, pod_set_band_4_frequency__bass);
+static DEVICE_ATTR(mod_param_1_double_precision, S_IWUGO | S_IRUGO, pod_get_mod_param_1_double_precision, pod_set_mod_param_1_double_precision);
+static DEVICE_ATTR(delay_param_1_double_precision, S_IWUGO | S_IRUGO, pod_get_delay_param_1_double_precision, pod_set_delay_param_1_double_precision);
+static DEVICE_ATTR(eq_enable, S_IWUGO | S_IRUGO, pod_get_eq_enable, pod_set_eq_enable);
+static DEVICE_ATTR(tap, S_IWUGO | S_IRUGO, pod_get_tap, pod_set_tap);
+static DEVICE_ATTR(volume_tweak_pedal_assign, S_IWUGO | S_IRUGO, pod_get_volume_tweak_pedal_assign, pod_set_volume_tweak_pedal_assign);
+static DEVICE_ATTR(band_5_frequency, S_IWUGO | S_IRUGO, pod_get_band_5_frequency, pod_set_band_5_frequency);
+static DEVICE_ATTR(tuner, S_IWUGO | S_IRUGO, pod_get_tuner, pod_set_tuner);
+static DEVICE_ATTR(mic_selection, S_IWUGO | S_IRUGO, pod_get_mic_selection, pod_set_mic_selection);
+static DEVICE_ATTR(cabinet_model, S_IWUGO | S_IRUGO, pod_get_cabinet_model, pod_set_cabinet_model);
+static DEVICE_ATTR(stomp_model, S_IWUGO | S_IRUGO, pod_get_stomp_model, pod_set_stomp_model);
+static DEVICE_ATTR(roomlevel, S_IWUGO | S_IRUGO, pod_get_roomlevel, pod_set_roomlevel);
+static DEVICE_ATTR(band_4_frequency, S_IWUGO | S_IRUGO, pod_get_band_4_frequency, pod_set_band_4_frequency);
+static DEVICE_ATTR(band_6_frequency, S_IWUGO | S_IRUGO, pod_get_band_6_frequency, pod_set_band_6_frequency);
+static DEVICE_ATTR(stomp_param_1_note_value, S_IWUGO | S_IRUGO, pod_get_stomp_param_1_note_value, pod_set_stomp_param_1_note_value);
+static DEVICE_ATTR(stomp_param_2, S_IWUGO | S_IRUGO, pod_get_stomp_param_2, pod_set_stomp_param_2);
+static DEVICE_ATTR(stomp_param_3, S_IWUGO | S_IRUGO, pod_get_stomp_param_3, pod_set_stomp_param_3);
+static DEVICE_ATTR(stomp_param_4, S_IWUGO | S_IRUGO, pod_get_stomp_param_4, pod_set_stomp_param_4);
+static DEVICE_ATTR(stomp_param_5, S_IWUGO | S_IRUGO, pod_get_stomp_param_5, pod_set_stomp_param_5);
+static DEVICE_ATTR(stomp_param_6, S_IWUGO | S_IRUGO, pod_get_stomp_param_6, pod_set_stomp_param_6);
+static DEVICE_ATTR(amp_switch_select, S_IWUGO | S_IRUGO, pod_get_amp_switch_select, pod_set_amp_switch_select);
+static DEVICE_ATTR(delay_param_4, S_IWUGO | S_IRUGO, pod_get_delay_param_4, pod_set_delay_param_4);
+static DEVICE_ATTR(delay_param_5, S_IWUGO | S_IRUGO, pod_get_delay_param_5, pod_set_delay_param_5);
+static DEVICE_ATTR(delay_pre_post, S_IWUGO | S_IRUGO, pod_get_delay_pre_post, pod_set_delay_pre_post);
+static DEVICE_ATTR(delay_model, S_IWUGO | S_IRUGO, pod_get_delay_model, pod_set_delay_model);
+static DEVICE_ATTR(delay_verb_model, S_IWUGO | S_IRUGO, pod_get_delay_verb_model, pod_set_delay_verb_model);
+static DEVICE_ATTR(tempo_msb, S_IWUGO | S_IRUGO, pod_get_tempo_msb, pod_set_tempo_msb);
+static DEVICE_ATTR(tempo_lsb, S_IWUGO | S_IRUGO, pod_get_tempo_lsb, pod_set_tempo_lsb);
+static DEVICE_ATTR(wah_model, S_IWUGO | S_IRUGO, pod_get_wah_model, pod_set_wah_model);
+static DEVICE_ATTR(bypass_volume, S_IWUGO | S_IRUGO, pod_get_bypass_volume, pod_set_bypass_volume);
+static DEVICE_ATTR(fx_loop_on_off, S_IWUGO | S_IRUGO, pod_get_fx_loop_on_off, pod_set_fx_loop_on_off);
+static DEVICE_ATTR(tweak_param_select, S_IWUGO | S_IRUGO, pod_get_tweak_param_select, pod_set_tweak_param_select);
+static DEVICE_ATTR(amp1_engage, S_IWUGO | S_IRUGO, pod_get_amp1_engage, pod_set_amp1_engage);
+static DEVICE_ATTR(band_1_gain, S_IWUGO | S_IRUGO, pod_get_band_1_gain, pod_set_band_1_gain);
+static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IWUGO | S_IRUGO, pod_get_band_2_gain__bass, pod_set_band_2_gain__bass);
+static DEVICE_ATTR(band_2_gain, S_IWUGO | S_IRUGO, pod_get_band_2_gain, pod_set_band_2_gain);
+static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IWUGO | S_IRUGO, pod_get_band_3_gain__bass, pod_set_band_3_gain__bass);
+static DEVICE_ATTR(band_3_gain, S_IWUGO | S_IRUGO, pod_get_band_3_gain, pod_set_band_3_gain);
+static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IWUGO | S_IRUGO, pod_get_band_4_gain__bass, pod_set_band_4_gain__bass);
+static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IWUGO | S_IRUGO, pod_get_band_5_gain__bass, pod_set_band_5_gain__bass);
+static DEVICE_ATTR(band_4_gain, S_IWUGO | S_IRUGO, pod_get_band_4_gain, pod_set_band_4_gain);
+static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IWUGO | S_IRUGO, pod_get_band_6_gain__bass, pod_set_band_6_gain__bass);
+static DEVICE_ATTR(body, S_IRUGO, variax_get_body, line6_nop_write);
+static DEVICE_ATTR(pickup1_enable, S_IRUGO, variax_get_pickup1_enable, line6_nop_write);
+static DEVICE_ATTR(pickup1_type, S_IRUGO, variax_get_pickup1_type, line6_nop_write);
+static DEVICE_ATTR(pickup1_position, S_IRUGO, variax_get_pickup1_position, line6_nop_write);
+static DEVICE_ATTR(pickup1_angle, S_IRUGO, variax_get_pickup1_angle, line6_nop_write);
+static DEVICE_ATTR(pickup1_level, S_IRUGO, variax_get_pickup1_level, line6_nop_write);
+static DEVICE_ATTR(pickup2_enable, S_IRUGO, variax_get_pickup2_enable, line6_nop_write);
+static DEVICE_ATTR(pickup2_type, S_IRUGO, variax_get_pickup2_type, line6_nop_write);
+static DEVICE_ATTR(pickup2_position, S_IRUGO, variax_get_pickup2_position, line6_nop_write);
+static DEVICE_ATTR(pickup2_angle, S_IRUGO, variax_get_pickup2_angle, line6_nop_write);
+static DEVICE_ATTR(pickup2_level, S_IRUGO, variax_get_pickup2_level, line6_nop_write);
+static DEVICE_ATTR(pickup_phase, S_IRUGO, variax_get_pickup_phase, line6_nop_write);
+static DEVICE_ATTR(capacitance, S_IRUGO, variax_get_capacitance, line6_nop_write);
+static DEVICE_ATTR(tone_resistance, S_IRUGO, variax_get_tone_resistance, line6_nop_write);
+static DEVICE_ATTR(volume_resistance, S_IRUGO, variax_get_volume_resistance, line6_nop_write);
+static DEVICE_ATTR(taper, S_IRUGO, variax_get_taper, line6_nop_write);
+static DEVICE_ATTR(tone_dump, S_IRUGO, variax_get_tone_dump, line6_nop_write);
+static DEVICE_ATTR(save_tone, S_IRUGO, variax_get_save_tone, line6_nop_write);
+static DEVICE_ATTR(volume_dump, S_IRUGO, variax_get_volume_dump, line6_nop_write);
+static DEVICE_ATTR(tuning_enable, S_IRUGO, variax_get_tuning_enable, line6_nop_write);
+static DEVICE_ATTR(tuning6, S_IRUGO, variax_get_tuning6, line6_nop_write);
+static DEVICE_ATTR(tuning5, S_IRUGO, variax_get_tuning5, line6_nop_write);
+static DEVICE_ATTR(tuning4, S_IRUGO, variax_get_tuning4, line6_nop_write);
+static DEVICE_ATTR(tuning3, S_IRUGO, variax_get_tuning3, line6_nop_write);
+static DEVICE_ATTR(tuning2, S_IRUGO, variax_get_tuning2, line6_nop_write);
+static DEVICE_ATTR(tuning1, S_IRUGO, variax_get_tuning1, line6_nop_write);
+static DEVICE_ATTR(detune6, S_IRUGO, variax_get_detune6, line6_nop_write);
+static DEVICE_ATTR(detune5, S_IRUGO, variax_get_detune5, line6_nop_write);
+static DEVICE_ATTR(detune4, S_IRUGO, variax_get_detune4, line6_nop_write);
+static DEVICE_ATTR(detune3, S_IRUGO, variax_get_detune3, line6_nop_write);
+static DEVICE_ATTR(detune2, S_IRUGO, variax_get_detune2, line6_nop_write);
+static DEVICE_ATTR(detune1, S_IRUGO, variax_get_detune1, line6_nop_write);
+static DEVICE_ATTR(mix6, S_IRUGO, variax_get_mix6, line6_nop_write);
+static DEVICE_ATTR(mix5, S_IRUGO, variax_get_mix5, line6_nop_write);
+static DEVICE_ATTR(mix4, S_IRUGO, variax_get_mix4, line6_nop_write);
+static DEVICE_ATTR(mix3, S_IRUGO, variax_get_mix3, line6_nop_write);
+static DEVICE_ATTR(mix2, S_IRUGO, variax_get_mix2, line6_nop_write);
+static DEVICE_ATTR(mix1, S_IRUGO, variax_get_mix1, line6_nop_write);
+static DEVICE_ATTR(pickup_wiring, S_IRUGO, variax_get_pickup_wiring, line6_nop_write);
+
+int pod_create_files(int firmware, int type, struct device *dev)
+{
+	int err;
+	CHECK_RETURN(device_create_file(dev, &dev_attr_tweak));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_wah_position));
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_compression_gain));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_vol_pedal_position));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_compression_threshold));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_pan));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_amp_model_setup));
+	if (firmware >= 200)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_amp_model));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_drive));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_bass));
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_mid));
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_lowmid));
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_treble));
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_highmid));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_chan_vol));
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_mix));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_effect_setup));
+	if (firmware >= 200)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_band_1_frequency));
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_presence));
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_treble__bass));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_noise_gate_enable));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_gate_threshold));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_gate_decay_time));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_enable));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_comp_enable));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_time));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_enable));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_1));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_1));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_1_note_value));
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		if (firmware >= 200)
+			CHECK_RETURN(device_create_file(dev, &dev_attr_band_2_frequency__bass));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_2));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_volume_mix));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_3));
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_enable));
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_type));
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_decay));
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_tone));
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_pre_delay));
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_pre_post));
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		if (firmware >= 200)
+			CHECK_RETURN(device_create_file(dev, &dev_attr_band_2_frequency));
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		if (firmware >= 200)
+			CHECK_RETURN(device_create_file(dev, &dev_attr_band_3_frequency__bass));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_wah_enable));
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_modulation_lo_cut));
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_delay_reverb_lo_cut));
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		if (firmware >= 200)
+			CHECK_RETURN(device_create_file(dev, &dev_attr_volume_pedal_minimum));
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		if (firmware >= 200)
+			CHECK_RETURN(device_create_file(dev, &dev_attr_eq_pre_post));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_volume_pre_post));
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_di_model));
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_di_delay));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_mod_enable));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_1_note_value));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_2));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_3));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_4));
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_5));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_mod_volume_mix));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_mod_pre_post));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_modulation_model));
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		if (firmware >= 200)
+			CHECK_RETURN(device_create_file(dev, &dev_attr_band_3_frequency));
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		if (firmware >= 200)
+			CHECK_RETURN(device_create_file(dev, &dev_attr_band_4_frequency__bass));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_1_double_precision));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_1_double_precision));
+	if (firmware >= 200)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_eq_enable));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_tap));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_volume_tweak_pedal_assign));
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		if (firmware >= 200)
+			CHECK_RETURN(device_create_file(dev, &dev_attr_band_5_frequency));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_tuner));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_mic_selection));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_cabinet_model));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_model));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_roomlevel));
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		if (firmware >= 200)
+			CHECK_RETURN(device_create_file(dev, &dev_attr_band_4_frequency));
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		if (firmware >= 200)
+			CHECK_RETURN(device_create_file(dev, &dev_attr_band_6_frequency));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_1_note_value));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_2));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_3));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_4));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_5));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_6));
+	if ((type & (LINE6_BITS_LIVE)) != 0)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_amp_switch_select));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_4));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_5));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_delay_pre_post));
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_delay_model));
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_delay_verb_model));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_tempo_msb));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_tempo_lsb));
+	if (firmware >= 300)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_wah_model));
+	if (firmware >= 214)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_bypass_volume));
+	if ((type & (LINE6_BITS_PRO)) != 0)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_fx_loop_on_off));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_tweak_param_select));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_amp1_engage));
+	if (firmware >= 200)
+		CHECK_RETURN(device_create_file(dev, &dev_attr_band_1_gain));
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		if (firmware >= 200)
+			CHECK_RETURN(device_create_file(dev, &dev_attr_band_2_gain__bass));
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		if (firmware >= 200)
+			CHECK_RETURN(device_create_file(dev, &dev_attr_band_2_gain));
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		if (firmware >= 200)
+			CHECK_RETURN(device_create_file(dev, &dev_attr_band_3_gain__bass));
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		if (firmware >= 200)
+			CHECK_RETURN(device_create_file(dev, &dev_attr_band_3_gain));
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		if (firmware >= 200)
+			CHECK_RETURN(device_create_file(dev, &dev_attr_band_4_gain__bass));
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		if (firmware >= 200)
+			CHECK_RETURN(device_create_file(dev, &dev_attr_band_5_gain__bass));
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		if (firmware >= 200)
+			CHECK_RETURN(device_create_file(dev, &dev_attr_band_4_gain));
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		if (firmware >= 200)
+			CHECK_RETURN(device_create_file(dev, &dev_attr_band_6_gain__bass));
+  return 0;
+}
+
+void pod_remove_files(int firmware, int type, struct device *dev)
+{
+	device_remove_file(dev, &dev_attr_tweak);
+	device_remove_file(dev, &dev_attr_wah_position);
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		device_remove_file(dev, &dev_attr_compression_gain);
+	device_remove_file(dev, &dev_attr_vol_pedal_position);
+	device_remove_file(dev, &dev_attr_compression_threshold);
+	device_remove_file(dev, &dev_attr_pan);
+	device_remove_file(dev, &dev_attr_amp_model_setup);
+	if (firmware >= 200)
+		device_remove_file(dev, &dev_attr_amp_model);
+	device_remove_file(dev, &dev_attr_drive);
+	device_remove_file(dev, &dev_attr_bass);
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		device_remove_file(dev, &dev_attr_mid);
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		device_remove_file(dev, &dev_attr_lowmid);
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		device_remove_file(dev, &dev_attr_treble);
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		device_remove_file(dev, &dev_attr_highmid);
+	device_remove_file(dev, &dev_attr_chan_vol);
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		device_remove_file(dev, &dev_attr_reverb_mix);
+	device_remove_file(dev, &dev_attr_effect_setup);
+	if (firmware >= 200)
+		device_remove_file(dev, &dev_attr_band_1_frequency);
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		device_remove_file(dev, &dev_attr_presence);
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		device_remove_file(dev, &dev_attr_treble__bass);
+	device_remove_file(dev, &dev_attr_noise_gate_enable);
+	device_remove_file(dev, &dev_attr_gate_threshold);
+	device_remove_file(dev, &dev_attr_gate_decay_time);
+	device_remove_file(dev, &dev_attr_stomp_enable);
+	device_remove_file(dev, &dev_attr_comp_enable);
+	device_remove_file(dev, &dev_attr_stomp_time);
+	device_remove_file(dev, &dev_attr_delay_enable);
+	device_remove_file(dev, &dev_attr_mod_param_1);
+	device_remove_file(dev, &dev_attr_delay_param_1);
+	device_remove_file(dev, &dev_attr_delay_param_1_note_value);
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		if (firmware >= 200)
+			device_remove_file(dev, &dev_attr_band_2_frequency__bass);
+	device_remove_file(dev, &dev_attr_delay_param_2);
+	device_remove_file(dev, &dev_attr_delay_volume_mix);
+	device_remove_file(dev, &dev_attr_delay_param_3);
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		device_remove_file(dev, &dev_attr_reverb_enable);
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		device_remove_file(dev, &dev_attr_reverb_type);
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		device_remove_file(dev, &dev_attr_reverb_decay);
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		device_remove_file(dev, &dev_attr_reverb_tone);
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		device_remove_file(dev, &dev_attr_reverb_pre_delay);
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		device_remove_file(dev, &dev_attr_reverb_pre_post);
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		if (firmware >= 200)
+			device_remove_file(dev, &dev_attr_band_2_frequency);
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		if (firmware >= 200)
+			device_remove_file(dev, &dev_attr_band_3_frequency__bass);
+	device_remove_file(dev, &dev_attr_wah_enable);
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		device_remove_file(dev, &dev_attr_modulation_lo_cut);
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		device_remove_file(dev, &dev_attr_delay_reverb_lo_cut);
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		if (firmware >= 200)
+			device_remove_file(dev, &dev_attr_volume_pedal_minimum);
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		if (firmware >= 200)
+			device_remove_file(dev, &dev_attr_eq_pre_post);
+	device_remove_file(dev, &dev_attr_volume_pre_post);
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		device_remove_file(dev, &dev_attr_di_model);
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		device_remove_file(dev, &dev_attr_di_delay);
+	device_remove_file(dev, &dev_attr_mod_enable);
+	device_remove_file(dev, &dev_attr_mod_param_1_note_value);
+	device_remove_file(dev, &dev_attr_mod_param_2);
+	device_remove_file(dev, &dev_attr_mod_param_3);
+	device_remove_file(dev, &dev_attr_mod_param_4);
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		device_remove_file(dev, &dev_attr_mod_param_5);
+	device_remove_file(dev, &dev_attr_mod_volume_mix);
+	device_remove_file(dev, &dev_attr_mod_pre_post);
+	device_remove_file(dev, &dev_attr_modulation_model);
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		if (firmware >= 200)
+			device_remove_file(dev, &dev_attr_band_3_frequency);
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		if (firmware >= 200)
+			device_remove_file(dev, &dev_attr_band_4_frequency__bass);
+	device_remove_file(dev, &dev_attr_mod_param_1_double_precision);
+	device_remove_file(dev, &dev_attr_delay_param_1_double_precision);
+	if (firmware >= 200)
+		device_remove_file(dev, &dev_attr_eq_enable);
+	device_remove_file(dev, &dev_attr_tap);
+	device_remove_file(dev, &dev_attr_volume_tweak_pedal_assign);
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		if (firmware >= 200)
+			device_remove_file(dev, &dev_attr_band_5_frequency);
+	device_remove_file(dev, &dev_attr_tuner);
+	device_remove_file(dev, &dev_attr_mic_selection);
+	device_remove_file(dev, &dev_attr_cabinet_model);
+	device_remove_file(dev, &dev_attr_stomp_model);
+	device_remove_file(dev, &dev_attr_roomlevel);
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		if (firmware >= 200)
+			device_remove_file(dev, &dev_attr_band_4_frequency);
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		if (firmware >= 200)
+			device_remove_file(dev, &dev_attr_band_6_frequency);
+	device_remove_file(dev, &dev_attr_stomp_param_1_note_value);
+	device_remove_file(dev, &dev_attr_stomp_param_2);
+	device_remove_file(dev, &dev_attr_stomp_param_3);
+	device_remove_file(dev, &dev_attr_stomp_param_4);
+	device_remove_file(dev, &dev_attr_stomp_param_5);
+	device_remove_file(dev, &dev_attr_stomp_param_6);
+	if ((type & (LINE6_BITS_LIVE)) != 0)
+		device_remove_file(dev, &dev_attr_amp_switch_select);
+	device_remove_file(dev, &dev_attr_delay_param_4);
+	device_remove_file(dev, &dev_attr_delay_param_5);
+	device_remove_file(dev, &dev_attr_delay_pre_post);
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		device_remove_file(dev, &dev_attr_delay_model);
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		device_remove_file(dev, &dev_attr_delay_verb_model);
+	device_remove_file(dev, &dev_attr_tempo_msb);
+	device_remove_file(dev, &dev_attr_tempo_lsb);
+	if (firmware >= 300)
+		device_remove_file(dev, &dev_attr_wah_model);
+	if (firmware >= 214)
+		device_remove_file(dev, &dev_attr_bypass_volume);
+	if ((type & (LINE6_BITS_PRO)) != 0)
+		device_remove_file(dev, &dev_attr_fx_loop_on_off);
+	device_remove_file(dev, &dev_attr_tweak_param_select);
+	device_remove_file(dev, &dev_attr_amp1_engage);
+	if (firmware >= 200)
+		device_remove_file(dev, &dev_attr_band_1_gain);
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		if (firmware >= 200)
+			device_remove_file(dev, &dev_attr_band_2_gain__bass);
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		if (firmware >= 200)
+			device_remove_file(dev, &dev_attr_band_2_gain);
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		if (firmware >= 200)
+			device_remove_file(dev, &dev_attr_band_3_gain__bass);
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		if (firmware >= 200)
+			device_remove_file(dev, &dev_attr_band_3_gain);
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		if (firmware >= 200)
+			device_remove_file(dev, &dev_attr_band_4_gain__bass);
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		if (firmware >= 200)
+			device_remove_file(dev, &dev_attr_band_5_gain__bass);
+	if ((type & (LINE6_BITS_PODXTALL)) != 0)
+		if (firmware >= 200)
+			device_remove_file(dev, &dev_attr_band_4_gain);
+	if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+		if (firmware >= 200)
+			device_remove_file(dev, &dev_attr_band_6_gain__bass);
+}
+
+EXPORT_SYMBOL(pod_create_files);
+EXPORT_SYMBOL(pod_remove_files);
+
+int variax_create_files(int firmware, int type, struct device *dev)
+{
+	int err;
+	CHECK_RETURN(device_create_file(dev, &dev_attr_body));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_enable));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_type));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_position));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_angle));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_level));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_enable));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_type));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_position));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_angle));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_level));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_pickup_phase));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_capacitance));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_tone_resistance));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_volume_resistance));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_taper));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_tone_dump));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_save_tone));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_volume_dump));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_tuning_enable));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_tuning6));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_tuning5));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_tuning4));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_tuning3));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_tuning2));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_tuning1));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_detune6));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_detune5));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_detune4));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_detune3));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_detune2));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_detune1));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_mix6));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_mix5));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_mix4));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_mix3));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_mix2));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_mix1));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_pickup_wiring));
+  return 0;
+}
+
+void variax_remove_files(int firmware, int type, struct device *dev)
+{
+	device_remove_file(dev, &dev_attr_body);
+	device_remove_file(dev, &dev_attr_pickup1_enable);
+	device_remove_file(dev, &dev_attr_pickup1_type);
+	device_remove_file(dev, &dev_attr_pickup1_position);
+	device_remove_file(dev, &dev_attr_pickup1_angle);
+	device_remove_file(dev, &dev_attr_pickup1_level);
+	device_remove_file(dev, &dev_attr_pickup2_enable);
+	device_remove_file(dev, &dev_attr_pickup2_type);
+	device_remove_file(dev, &dev_attr_pickup2_position);
+	device_remove_file(dev, &dev_attr_pickup2_angle);
+	device_remove_file(dev, &dev_attr_pickup2_level);
+	device_remove_file(dev, &dev_attr_pickup_phase);
+	device_remove_file(dev, &dev_attr_capacitance);
+	device_remove_file(dev, &dev_attr_tone_resistance);
+	device_remove_file(dev, &dev_attr_volume_resistance);
+	device_remove_file(dev, &dev_attr_taper);
+	device_remove_file(dev, &dev_attr_tone_dump);
+	device_remove_file(dev, &dev_attr_save_tone);
+	device_remove_file(dev, &dev_attr_volume_dump);
+	device_remove_file(dev, &dev_attr_tuning_enable);
+	device_remove_file(dev, &dev_attr_tuning6);
+	device_remove_file(dev, &dev_attr_tuning5);
+	device_remove_file(dev, &dev_attr_tuning4);
+	device_remove_file(dev, &dev_attr_tuning3);
+	device_remove_file(dev, &dev_attr_tuning2);
+	device_remove_file(dev, &dev_attr_tuning1);
+	device_remove_file(dev, &dev_attr_detune6);
+	device_remove_file(dev, &dev_attr_detune5);
+	device_remove_file(dev, &dev_attr_detune4);
+	device_remove_file(dev, &dev_attr_detune3);
+	device_remove_file(dev, &dev_attr_detune2);
+	device_remove_file(dev, &dev_attr_detune1);
+	device_remove_file(dev, &dev_attr_mix6);
+	device_remove_file(dev, &dev_attr_mix5);
+	device_remove_file(dev, &dev_attr_mix4);
+	device_remove_file(dev, &dev_attr_mix3);
+	device_remove_file(dev, &dev_attr_mix2);
+	device_remove_file(dev, &dev_attr_mix1);
+	device_remove_file(dev, &dev_attr_pickup_wiring);
+}
+
+EXPORT_SYMBOL(variax_create_files);
+EXPORT_SYMBOL(variax_remove_files);
diff --git a/drivers/staging/line6/control.h b/drivers/staging/line6/control.h
new file mode 100644
index 0000000..2f19665
--- /dev/null
+++ b/drivers/staging/line6/control.h
@@ -0,0 +1,187 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *	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.
+ *
+ */
+
+#ifndef LINE6_CONTROL_H
+#define LINE6_CONTROL_H
+
+
+/**
+   List of PODxt Pro controls.
+   See Appendix C of the "PODxt (Pro) Pilot's Handbook" by Line6.
+   Comments after the number refer to the PODxt Pro firmware version required
+   for this feature.
+*/
+enum {
+	POD_tweak                          =   1,
+	POD_wah_position                   =   4,
+	POD_compression_gain               =   5,  /* device: LINE6_BITS_PODXTALL */
+	POD_vol_pedal_position             =   7,
+	POD_compression_threshold          =   9,
+	POD_pan                            =  10,
+	POD_amp_model_setup                =  11,
+	POD_amp_model                      =  12,  /* firmware: 2.0 */
+	POD_drive                          =  13,
+	POD_bass                           =  14,
+	POD_mid                            =  15,  /* device: LINE6_BITS_PODXTALL */
+	POD_lowmid                         =  15,  /* device: LINE6_BITS_BASSPODXTALL */
+	POD_treble                         =  16,  /* device: LINE6_BITS_PODXTALL */
+	POD_highmid                        =  16,  /* device: LINE6_BITS_BASSPODXTALL */
+	POD_chan_vol                       =  17,
+	POD_reverb_mix                     =  18,  /* device: LINE6_BITS_PODXTALL */
+	POD_effect_setup                   =  19,
+	POD_band_1_frequency               =  20,  /* firmware: 2.0 */
+	POD_presence                       =  21,  /* device: LINE6_BITS_PODXTALL */
+	POD_treble__bass                   =  21,  /* device: LINE6_BITS_BASSPODXTALL */
+	POD_noise_gate_enable              =  22,
+	POD_gate_threshold                 =  23,
+	POD_gate_decay_time                =  24,
+	POD_stomp_enable                   =  25,
+	POD_comp_enable                    =  26,
+	POD_stomp_time                     =  27,
+	POD_delay_enable                   =  28,
+	POD_mod_param_1                    =  29,
+	POD_delay_param_1                  =  30,
+	POD_delay_param_1_note_value       =  31,
+	POD_band_2_frequency__bass         =  32,  /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+	POD_delay_param_2                  =  33,
+	POD_delay_volume_mix               =  34,
+	POD_delay_param_3                  =  35,
+	POD_reverb_enable                  =  36,  /* device: LINE6_BITS_PODXTALL */
+	POD_reverb_type                    =  37,  /* device: LINE6_BITS_PODXTALL */
+	POD_reverb_decay                   =  38,  /* device: LINE6_BITS_PODXTALL */
+	POD_reverb_tone                    =  39,  /* device: LINE6_BITS_PODXTALL */
+	POD_reverb_pre_delay               =  40,  /* device: LINE6_BITS_PODXTALL */
+	POD_reverb_pre_post                =  41,  /* device: LINE6_BITS_PODXTALL */
+	POD_band_2_frequency               =  42,  /* device: LINE6_BITS_PODXTALL */     /* firmware: 2.0 */
+	POD_band_3_frequency__bass         =  42,  /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+	POD_wah_enable                     =  43,
+	POD_modulation_lo_cut              =  44,  /* device: LINE6_BITS_BASSPODXTALL */
+	POD_delay_reverb_lo_cut            =  45,  /* device: LINE6_BITS_BASSPODXTALL */
+	POD_volume_pedal_minimum           =  46,  /* device: LINE6_BITS_PODXTALL */     /* firmware: 2.0 */
+	POD_eq_pre_post                    =  46,  /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+	POD_volume_pre_post                =  47,
+	POD_di_model                       =  48,  /* device: LINE6_BITS_BASSPODXTALL */
+	POD_di_delay                       =  49,  /* device: LINE6_BITS_BASSPODXTALL */
+	POD_mod_enable                     =  50,
+	POD_mod_param_1_note_value         =  51,
+	POD_mod_param_2                    =  52,
+	POD_mod_param_3                    =  53,
+	POD_mod_param_4                    =  54,
+	POD_mod_param_5                    =  55,  /* device: LINE6_BITS_BASSPODXTALL */
+	POD_mod_volume_mix                 =  56,
+	POD_mod_pre_post                   =  57,
+	POD_modulation_model               =  58,
+	POD_band_3_frequency               =  60,  /* device: LINE6_BITS_PODXTALL */     /* firmware: 2.0 */
+	POD_band_4_frequency__bass         =  60,  /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+	POD_mod_param_1_double_precision   =  61,
+	POD_delay_param_1_double_precision =  62,
+	POD_eq_enable                      =  63,  /* firmware: 2.0 */
+	POD_tap                            =  64,
+	POD_volume_tweak_pedal_assign      =  65,
+	POD_band_5_frequency               =  68,  /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+	POD_tuner                          =  69,
+	POD_mic_selection                  =  70,
+	POD_cabinet_model                  =  71,
+	POD_stomp_model                    =  75,
+	POD_roomlevel                      =  76,
+	POD_band_4_frequency               =  77,  /* device: LINE6_BITS_PODXTALL */     /* firmware: 2.0 */
+	POD_band_6_frequency               =  77,  /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+	POD_stomp_param_1_note_value       =  78,
+	POD_stomp_param_2                  =  79,
+	POD_stomp_param_3                  =  80,
+	POD_stomp_param_4                  =  81,
+	POD_stomp_param_5                  =  82,
+	POD_stomp_param_6                  =  83,
+	POD_amp_switch_select              =  84,  /* device: LINE6_BITS_LIVE */
+	POD_delay_param_4                  =  85,
+	POD_delay_param_5                  =  86,
+	POD_delay_pre_post                 =  87,
+	POD_delay_model                    =  88,  /* device: LINE6_BITS_PODXTALL */
+	POD_delay_verb_model               =  88,  /* device: LINE6_BITS_BASSPODXTALL */
+	POD_tempo_msb                      =  89,
+	POD_tempo_lsb                      =  90,
+	POD_wah_model                      =  91,  /* firmware: 3.0 */
+	POD_bypass_volume                  = 105,  /* firmware: 2.14 */
+	POD_fx_loop_on_off                 = 107,  /* device: LINE6_BITS_PRO */
+	POD_tweak_param_select             = 108,
+	POD_amp1_engage                    = 111,
+	POD_band_1_gain                    = 114,  /* firmware: 2.0 */
+	POD_band_2_gain__bass              = 115,  /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+	POD_band_2_gain                    = 116,  /* device: LINE6_BITS_PODXTALL */     /* firmware: 2.0 */
+	POD_band_3_gain__bass              = 116,  /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+	POD_band_3_gain                    = 117,  /* device: LINE6_BITS_PODXTALL */     /* firmware: 2.0 */
+	POD_band_4_gain__bass              = 117,  /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+	POD_band_5_gain__bass              = 118,  /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+	POD_band_4_gain                    = 119,  /* device: LINE6_BITS_PODXTALL */     /* firmware: 2.0 */
+	POD_band_6_gain__bass              = 119   /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+};
+
+/**
+   List of Variax workbench controls (dump).
+*/
+enum {
+	VARIAX_body                        =   3,
+	VARIAX_pickup1_enable              =   4,  /* 0: enabled, 1: disabled */
+	VARIAX_pickup1_type                =   8,
+	VARIAX_pickup1_position            =   9,  /* type: 24 bit float */
+	VARIAX_pickup1_angle               =  12,  /* type: 24 bit float */
+	VARIAX_pickup1_level               =  15,  /* type: 24 bit float */
+	VARIAX_pickup2_enable              =  18,  /* 0: enabled, 1: disabled */
+	VARIAX_pickup2_type                =  22,
+	VARIAX_pickup2_position            =  23,  /* type: 24 bit float */
+	VARIAX_pickup2_angle               =  26,  /* type: 24 bit float */
+	VARIAX_pickup2_level               =  29,  /* type: 24 bit float */
+	VARIAX_pickup_phase                =  32,  /* 0: in phase, 1: out of phase */
+	VARIAX_capacitance                 =  33,  /* type: 24 bit float */
+	VARIAX_tone_resistance             =  36,  /* type: 24 bit float */
+	VARIAX_volume_resistance           =  39,  /* type: 24 bit float */
+	VARIAX_taper                       =  42,  /* 0: Linear, 1: Audio */
+	VARIAX_tone_dump                   =  43,  /* type: 24 bit float */
+	VARIAX_save_tone                   =  46,
+	VARIAX_volume_dump                 =  47,  /* type: 24 bit float */
+	VARIAX_tuning_enable               =  50,
+	VARIAX_tuning6                     =  51,
+	VARIAX_tuning5                     =  52,
+	VARIAX_tuning4                     =  53,
+	VARIAX_tuning3                     =  54,
+	VARIAX_tuning2                     =  55,
+	VARIAX_tuning1                     =  56,
+	VARIAX_detune6                     =  57,  /* type: 24 bit float */
+	VARIAX_detune5                     =  60,  /* type: 24 bit float */
+	VARIAX_detune4                     =  63,  /* type: 24 bit float */
+	VARIAX_detune3                     =  66,  /* type: 24 bit float */
+	VARIAX_detune2                     =  69,  /* type: 24 bit float */
+	VARIAX_detune1                     =  72,  /* type: 24 bit float */
+	VARIAX_mix6                        =  75,  /* type: 24 bit float */
+	VARIAX_mix5                        =  78,  /* type: 24 bit float */
+	VARIAX_mix4                        =  81,  /* type: 24 bit float */
+	VARIAX_mix3                        =  84,  /* type: 24 bit float */
+	VARIAX_mix2                        =  87,  /* type: 24 bit float */
+	VARIAX_mix1                        =  90,  /* type: 24 bit float */
+	VARIAX_pickup_wiring               =  96   /* 0: parallel, 1: series */
+};
+
+/**
+   List of Variax workbench controls (MIDI).
+*/
+enum {
+	VARIAXMIDI_volume                  =   7,
+	VARIAXMIDI_tone                    =  79,
+};
+
+
+extern int pod_create_files(int firmware, int type, struct device *dev);
+extern void pod_remove_files(int firmware, int type, struct device *dev);
+extern int variax_create_files(int firmware, int type, struct device *dev);
+extern void variax_remove_files(int firmware, int type, struct device *dev);
+
+
+#endif
diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c
new file mode 100644
index 0000000..85a20d0
--- /dev/null
+++ b/drivers/staging/line6/driver.c
@@ -0,0 +1,1102 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *	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.
+ *
+ */
+
+#include "driver.h"
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+
+#include "audio.h"
+#include "capture.h"
+#include "control.h"
+#include "midi.h"
+#include "playback.h"
+#include "pod.h"
+#include "revision.h"
+#include "toneport.h"
+#include "usbdefs.h"
+#include "variax.h"
+
+
+#define DRIVER_AUTHOR  "Markus Grabner <grabner@icg.tugraz.at>"
+#define DRIVER_DESC    "Line6 USB Driver"
+#define DRIVER_VERSION "0.8.0"
+
+
+/* table of devices that work with this driver */
+static struct usb_device_id line6_id_table[] = {
+	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXT) },
+	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTLIVE) },
+	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTPRO) },
+	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_GUITARPORT) },
+	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_POCKETPOD) },
+	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3) },
+	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3LIVE) },
+	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXT) },
+	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTLIVE) },
+	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTPRO) },
+	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_GX) },
+	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_UX1) },
+	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_UX2) },
+	{ USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_VARIAX) },
+	{ },
+};
+MODULE_DEVICE_TABLE(usb, line6_id_table);
+
+static struct line6_properties line6_properties_table[] = {
+	{ "BassPODxt",        LINE6_BIT_BASSPODXT,     LINE6_BIT_CONTROL_PCM },
+	{ "BassPODxt Live",   LINE6_BIT_BASSPODXTLIVE, LINE6_BIT_CONTROL_PCM },
+	{ "BassPODxt Pro",    LINE6_BIT_BASSPODXTPRO,  LINE6_BIT_CONTROL_PCM },
+	{ "GuitarPort",       LINE6_BIT_GUITARPORT,    LINE6_BIT_PCM         },
+	{ "Pocket POD",       LINE6_BIT_POCKETPOD,     LINE6_BIT_CONTROL_PCM },
+	{ "POD X3",           LINE6_BIT_PODX3,         LINE6_BIT_PCM         },
+	{ "POD X3 Live",      LINE6_BIT_PODX3LIVE,     LINE6_BIT_PCM         },
+	{ "PODxt",            LINE6_BIT_PODXT,         LINE6_BIT_CONTROL_PCM },
+	{ "PODxt Live",       LINE6_BIT_PODXTLIVE,     LINE6_BIT_CONTROL_PCM },
+	{ "PODxt Pro",        LINE6_BIT_PODXTPRO,      LINE6_BIT_CONTROL_PCM },
+	{ "TonePort GX",      LINE6_BIT_TONEPORT_GX,   LINE6_BIT_PCM         },
+	{ "TonePort UX1",     LINE6_BIT_TONEPORT_UX1,  LINE6_BIT_PCM         },
+	{ "TonePort UX2",     LINE6_BIT_TONEPORT_UX2,  LINE6_BIT_PCM         },
+	{ "Variax Workbench", LINE6_BIT_VARIAX,        LINE6_BIT_CONTROL     }
+};
+
+
+/*
+	This is Line6's MIDI manufacturer ID.
+*/
+const unsigned char line6_midi_id[] = { 0x00, 0x01, 0x0c };
+
+struct usb_line6 *line6_devices[LINE6_MAX_DEVICES];
+struct workqueue_struct *line6_workqueue;
+
+
+/**
+	 Class for asynchronous messages.
+*/
+struct message {
+	struct usb_line6 *line6;
+	const char *buffer;
+	int size;
+	int done;
+};
+
+
+/*
+	Forward declarations.
+*/
+static void line6_data_received(struct urb *urb);
+static int line6_send_raw_message_async_part(struct message *msg,
+					     struct urb *urb);
+
+
+/*
+	Start to listen on endpoint.
+*/
+static int line6_start_listen(struct usb_line6 *line6)
+{
+	usb_fill_int_urb(line6->urb_listen, line6->usbdev,
+			 usb_rcvintpipe(line6->usbdev, line6->ep_control_read),
+			 line6->buffer_listen, LINE6_BUFSIZE_LISTEN,
+			 line6_data_received, line6, line6->interval);
+	line6->urb_listen->actual_length = 0;
+	return usb_submit_urb(line6->urb_listen, GFP_KERNEL);
+}
+
+#if DO_DUMP_ANY
+/*
+	Write hexdump to syslog.
+*/
+void line6_write_hexdump(struct usb_line6 *line6, char dir,
+			 const unsigned char *buffer, int size)
+{
+	static const int BYTES_PER_LINE = 8;
+	char hexdump[100];
+	char asc[BYTES_PER_LINE + 1];
+	int i, j;
+
+	for (i = 0; i < size; i += BYTES_PER_LINE) {
+		int hexdumpsize = sizeof(hexdump);
+		char *p = hexdump;
+		int n = min(size - i, BYTES_PER_LINE);
+		asc[n] = 0;
+
+		for (j = 0; j < BYTES_PER_LINE; ++j) {
+			int bytes;
+
+			if (j < n) {
+				unsigned char val = buffer[i + j];
+				bytes = snprintf(p, hexdumpsize, " %02X", val);
+				asc[j] = ((val >= 0x20) && (val < 0x7f)) ? val : '.';
+			} else
+				bytes = snprintf(p, hexdumpsize, "   ");
+
+			if (bytes > hexdumpsize)
+				break;  /* buffer overflow */
+
+			p += bytes;
+			hexdumpsize -= bytes;
+		}
+
+		dev_info(line6->ifcdev, "%c%04X:%s %s\n", dir, i, hexdump, asc);
+	}
+}
+#endif
+
+#if DO_DUMP_URB_RECEIVE
+/*
+	Dump URB data to syslog.
+*/
+static void line6_dump_urb(struct urb *urb)
+{
+	struct usb_line6 *line6 = (struct usb_line6 *)urb->context;
+
+	if (urb->status < 0)
+		return;
+
+	line6_write_hexdump(line6, 'R', (unsigned char *)urb->transfer_buffer,
+			    urb->actual_length);
+}
+#endif
+
+/*
+	Send raw message in pieces of wMaxPacketSize bytes.
+*/
+int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,
+			   int size)
+{
+	int i, done = 0;
+
+#if DO_DUMP_URB_SEND
+	line6_write_hexdump(line6, 'S', buffer, size);
+#endif
+
+	for (i = 0; i < size; i += line6->max_packet_size) {
+		int partial;
+		const char *frag_buf = buffer + i;
+		int frag_size = min(line6->max_packet_size, size - i);
+		int retval;
+
+		retval = usb_interrupt_msg(line6->usbdev,
+					   usb_sndintpipe(line6->usbdev,
+							  line6->ep_control_write),
+					   (char *)frag_buf, frag_size,
+					   &partial, LINE6_TIMEOUT * HZ);
+
+		if (retval) {
+			dev_err(line6->ifcdev,
+				"usb_interrupt_msg failed (%d)\n", retval);
+			break;
+		}
+
+		done += frag_size;
+	}
+
+	return done;
+}
+
+/*
+	Notification of completion of asynchronous request transmission.
+*/
+static void line6_async_request_sent(struct urb *urb)
+{
+	struct message *msg = (struct message *)urb->context;
+
+	if (msg->done >= msg->size) {
+		usb_free_urb(urb);
+		kfree(msg);
+	} else
+		line6_send_raw_message_async_part(msg, urb);
+}
+
+/*
+	Asynchronously send part of a raw message.
+*/
+static int line6_send_raw_message_async_part(struct message *msg,
+					     struct urb *urb)
+{
+	int retval;
+	struct usb_line6 *line6 = msg->line6;
+	int done = msg->done;
+	int bytes = min(msg->size - done, line6->max_packet_size);
+
+	usb_fill_int_urb(urb, line6->usbdev,
+			 usb_sndintpipe(line6->usbdev, line6->ep_control_write),
+			 (char *)msg->buffer + done, bytes,
+			 line6_async_request_sent, msg, line6->interval);
+
+#if DO_DUMP_URB_SEND
+	line6_write_hexdump(line6, 'S', (char *)msg->buffer + done, bytes);
+#endif
+
+	msg->done += bytes;
+	retval = usb_submit_urb(urb, GFP_ATOMIC);
+
+	if (retval < 0) {
+		dev_err(line6->ifcdev, "%s: usb_submit_urb failed (%d)\n",
+			__func__, retval);
+		usb_free_urb(urb);
+		kfree(msg);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/*
+	Asynchronously send raw message.
+*/
+int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer,
+				 int size)
+{
+	struct message *msg;
+	struct urb *urb;
+
+	/* create message: */
+	msg = kmalloc(sizeof(struct message), GFP_ATOMIC);
+
+	if (msg == NULL) {
+		dev_err(line6->ifcdev, "Out of memory\n");
+		return -ENOMEM;
+	}
+
+	/* create URB: */
+	urb = usb_alloc_urb(0, GFP_ATOMIC);
+
+	if (urb == NULL) {
+		kfree(msg);
+		dev_err(line6->ifcdev, "Out of memory\n");
+		return -ENOMEM;
+	}
+
+	/* set message data: */
+	msg->line6 = line6;
+	msg->buffer = buffer;
+	msg->size = size;
+	msg->done = 0;
+
+	/* start sending: */
+	return line6_send_raw_message_async_part(msg, urb);
+}
+
+/*
+	Send sysex message in pieces of wMaxPacketSize bytes.
+*/
+int line6_send_sysex_message(struct usb_line6 *line6, const char *buffer,
+			     int size)
+{
+	return line6_send_raw_message(line6, buffer, size + SYSEX_EXTRA_SIZE) - SYSEX_EXTRA_SIZE;
+}
+
+/*
+	Allocate buffer for sysex message and prepare header.
+	@param code sysex message code
+	@param size number of bytes between code and sysex end
+*/
+char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, int code2,
+			       int size)
+{
+	char *buffer = kmalloc(size + SYSEX_EXTRA_SIZE, GFP_KERNEL);
+
+	if (!buffer) {
+		dev_err(line6->ifcdev, "out of memory\n");
+		return NULL;
+	}
+
+	buffer[0] = LINE6_SYSEX_BEGIN;
+	memcpy(buffer + 1, line6_midi_id, sizeof(line6_midi_id));
+	buffer[sizeof(line6_midi_id) + 1] = code1;
+	buffer[sizeof(line6_midi_id) + 2] = code2;
+	buffer[sizeof(line6_midi_id) + 3 + size] = LINE6_SYSEX_END;
+	return buffer;
+}
+
+/*
+	Notification of data received from the Line6 device.
+*/
+static void line6_data_received(struct urb *urb)
+{
+	struct usb_line6 *line6 = (struct usb_line6 *)urb->context;
+	struct MidiBuffer *mb = &line6->line6midi->midibuf_in;
+	int done;
+
+	if (urb->status == -ESHUTDOWN)
+		return;
+
+#if DO_DUMP_URB_RECEIVE
+	line6_dump_urb(urb);
+#endif
+
+	done = midibuf_write(mb, urb->transfer_buffer, urb->actual_length);
+
+	if (done < urb->actual_length) {
+		midibuf_ignore(mb, done);
+		DEBUG_MESSAGES(dev_err(line6->ifcdev, "%d %d buffer overflow - message skipped\n", done, urb->actual_length));
+	}
+
+	for (;;) {
+		done = midibuf_read(mb, line6->buffer_message, LINE6_MESSAGE_MAXLEN);
+
+		if (done == 0)
+			break;
+
+		/* MIDI input filter */
+		if (midibuf_skip_message(mb, line6->line6midi->midi_mask_receive))
+			continue;
+
+		line6->message_length = done;
+#if DO_DUMP_MIDI_RECEIVE
+		line6_write_hexdump(line6, 'r', line6->buffer_message, done);
+#endif
+		line6_midi_receive(line6, line6->buffer_message, done);
+
+		switch (line6->usbdev->descriptor.idProduct) {
+		case LINE6_DEVID_BASSPODXT:
+		case LINE6_DEVID_BASSPODXTLIVE:
+		case LINE6_DEVID_BASSPODXTPRO:
+		case LINE6_DEVID_PODXT:
+		case LINE6_DEVID_PODXTPRO:
+		case LINE6_DEVID_POCKETPOD:
+			pod_process_message((struct usb_line6_pod *)line6);
+			break;
+
+		case LINE6_DEVID_PODXTLIVE:
+			switch (line6->interface_number) {
+			case PODXTLIVE_INTERFACE_POD:
+				pod_process_message((struct usb_line6_pod *)line6);
+				break;
+
+			case PODXTLIVE_INTERFACE_VARIAX:
+				variax_process_message((struct usb_line6_variax *)line6);
+				break;
+
+			default:
+				dev_err(line6->ifcdev, "PODxt Live interface %d not supported\n", line6->interface_number);
+			}
+			break;
+
+		case LINE6_DEVID_VARIAX:
+			variax_process_message((struct usb_line6_variax *)line6);
+			break;
+
+		default:
+			MISSING_CASE;
+		}
+	}
+
+	line6_start_listen(line6);
+}
+
+/*
+	Send channel number (i.e., switch to a different sound).
+*/
+int line6_send_program(struct usb_line6 *line6, int value)
+{
+	int retval;
+	unsigned char *buffer;
+	unsigned int partial;
+
+	buffer = kmalloc(2, GFP_KERNEL);
+
+	if (!buffer) {
+		dev_err(line6->ifcdev, "out of memory\n");
+		return -ENOMEM;
+	}
+
+	buffer[0] = LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST;
+	buffer[1] = value;
+
+#if DO_DUMP_URB_SEND
+	line6_write_hexdump(line6, 'S', buffer, 2);
+#endif
+
+	retval = usb_interrupt_msg(line6->usbdev,
+				   usb_sndintpipe(line6->usbdev,
+						  line6->ep_control_write),
+				   buffer, 2, &partial, LINE6_TIMEOUT * HZ);
+
+	if (retval)
+		dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n", retval);
+
+	kfree(buffer);
+	return retval;
+}
+
+/*
+	Transmit Line6 control parameter.
+*/
+int line6_transmit_parameter(struct usb_line6 *line6, int param, int value)
+{
+	int retval;
+	unsigned char *buffer;
+	unsigned int partial;
+
+	buffer = kmalloc(3, GFP_KERNEL);
+
+	if (!buffer) {
+		dev_err(line6->ifcdev, "out of memory\n");
+		return -ENOMEM;
+	}
+
+	buffer[0] = LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST;
+	buffer[1] = param;
+	buffer[2] = value;
+
+#if DO_DUMP_URB_SEND
+	line6_write_hexdump(line6, 'S', buffer, 3);
+#endif
+
+	retval = usb_interrupt_msg(line6->usbdev,
+														 usb_sndintpipe(line6->usbdev, line6->ep_control_write),
+														 buffer, 3, &partial, LINE6_TIMEOUT * HZ);
+
+	if (retval)
+		dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n", retval);
+
+	kfree(buffer);
+	return retval;
+}
+
+/*
+	Read data from device.
+*/
+int line6_read_data(struct usb_line6 *line6, int address, void *data, size_t datalen)
+{
+	struct usb_device *usbdev = line6->usbdev;
+	int ret;
+	unsigned char len;
+
+	/* query the serial number: */
+	ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
+												USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+												(datalen << 8) | 0x21, address, NULL, 0, LINE6_TIMEOUT * HZ);
+
+	if (ret < 0) {
+		dev_err(line6->ifcdev, "read request failed (error %d)\n", ret);
+		return ret;
+	}
+
+	/* Wait for data length. We'll get a couple of 0xff until length arrives. */
+	do {
+		ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67,
+				      USB_TYPE_VENDOR | USB_RECIP_DEVICE |
+				      USB_DIR_IN,
+				      0x0012, 0x0000, &len, 1,
+				      LINE6_TIMEOUT * HZ);
+		if (ret < 0) {
+			dev_err(line6->ifcdev,
+				"receive length failed (error %d)\n", ret);
+			return ret;
+		}
+	}
+	while (len == 0xff)
+		;
+
+	if (len != datalen) {
+		/* should be equal or something went wrong */
+		dev_err(line6->ifcdev,
+			"length mismatch (expected %d, got %d)\n",
+			(int)datalen, (int)len);
+		return -EINVAL;
+	}
+
+	/* receive the result: */
+	ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67,
+			      USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+			      0x0013, 0x0000, data, datalen,
+			      LINE6_TIMEOUT * HZ);
+
+	if (ret < 0) {
+		dev_err(line6->ifcdev, "read failed (error %d)\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+/*
+	Write data to device.
+*/
+int line6_write_data(struct usb_line6 *line6, int address, void *data,
+		     size_t datalen)
+{
+	struct usb_device *usbdev = line6->usbdev;
+	int ret;
+	unsigned char status;
+
+	ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
+			      USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+			      0x0022, address, data, datalen,
+			      LINE6_TIMEOUT * HZ);
+
+	if (ret < 0) {
+		dev_err(line6->ifcdev,
+			"write request failed (error %d)\n", ret);
+		return ret;
+	}
+
+	do {
+		ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0),
+				      0x67,
+				      USB_TYPE_VENDOR | USB_RECIP_DEVICE |
+				      USB_DIR_IN,
+				      0x0012, 0x0000,
+				      &status, 1, LINE6_TIMEOUT * HZ);
+
+		if (ret < 0) {
+			dev_err(line6->ifcdev,
+				"receiving status failed (error %d)\n", ret);
+			return ret;
+		}
+	}
+	while (status == 0xff)
+		;
+
+	if (status != 0) {
+		dev_err(line6->ifcdev, "write failed (error %d)\n", ret);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/*
+	Read Line6 device serial number.
+	(POD, TonePort, GuitarPort)
+*/
+int line6_read_serial_number(struct usb_line6 *line6, int *serial_number)
+{
+	return line6_read_data(line6, 0x80d0, serial_number, sizeof(*serial_number));
+}
+
+/*
+	No operation (i.e., unsupported).
+*/
+ssize_t line6_nop_read(struct device *dev, struct device_attribute *attr,
+		       char *buf)
+{
+	return 0;
+}
+
+/*
+	No operation (i.e., unsupported).
+*/
+ssize_t line6_nop_write(struct device *dev, struct device_attribute *attr,
+			const char *buf, size_t count)
+{
+	return count;
+}
+
+/*
+	"write" request on "raw" special file.
+*/
+#if CREATE_RAW_FILE
+ssize_t line6_set_raw(struct device *dev, struct device_attribute *attr,
+		      const char *buf, size_t count)
+{
+	struct usb_interface *interface = to_usb_interface(dev);
+	struct usb_line6 *line6 = usb_get_intfdata(interface);
+	line6_send_raw_message(line6, buf, count);
+	return count;
+}
+#endif
+
+/*
+	Generic destructor.
+*/
+static void line6_destruct(struct usb_interface *interface)
+{
+	struct usb_line6 *line6;
+
+	if (interface == NULL)
+		return;
+	line6 = usb_get_intfdata(interface);
+	if (line6 == NULL)
+		return;
+
+	/* free buffer memory first: */
+	kfree(line6->buffer_message);
+	kfree(line6->buffer_listen);
+
+	/* then free URBs: */
+	usb_free_urb(line6->urb_listen);
+
+	/* make sure the device isn't destructed twice: */
+	usb_set_intfdata(interface, NULL);
+
+	/* free interface data: */
+	kfree(line6);
+}
+
+static void line6_list_devices(void)
+{
+	int i;
+
+	for (i = 0; i < LINE6_MAX_DEVICES; ++i) {
+		struct usb_line6 *dev = line6_devices[i];
+		printk(KERN_INFO "Line6 device %d: ", i);
+
+		if (dev == NULL)
+			printk("(not used)\n");
+		else
+			printk("%s:%d\n", dev->properties->name, dev->interface_number);
+	}
+}
+
+/*
+	Probe USB device.
+*/
+static int line6_probe(struct usb_interface *interface, const struct usb_device_id *id)
+{
+	int devtype;
+	struct usb_device *usbdev = NULL;
+	struct usb_line6 *line6 = NULL;
+	const struct line6_properties *properties;
+	int devnum;
+	int interface_number, alternate = 0;
+	int product;
+	int size = 0;
+	int ep_read = 0, ep_write = 0;
+	int ret;
+
+	if (interface == NULL)
+		return -ENODEV;
+	usbdev = interface_to_usbdev(interface);
+	if (usbdev == NULL)
+		return -ENODEV;
+
+	/* increment reference counters: */
+	usb_get_intf(interface);
+	usb_get_dev(usbdev);
+
+	/* we don't handle multiple configurations */
+	if (usbdev->descriptor.bNumConfigurations != 1)
+		return -ENODEV;
+
+	/* check vendor and product id */
+	for (devtype = sizeof(line6_id_table) / sizeof(line6_id_table[0]) - 1; devtype--;)
+		if ((le16_to_cpu(usbdev->descriptor.idVendor) == line6_id_table[devtype].idVendor) &&
+			 (le16_to_cpu(usbdev->descriptor.idProduct) == line6_id_table[devtype].idProduct))
+			break;
+
+	if (devtype < 0)
+		return -ENODEV;
+
+	/* find free slot in device table: */
+	for (devnum = 0; devnum < LINE6_MAX_DEVICES; ++devnum)
+		if (line6_devices[devnum] == NULL)
+			break;
+
+	if (devnum == LINE6_MAX_DEVICES)
+		return -ENODEV;
+
+	/* initialize device info: */
+	properties = &line6_properties_table[devtype];
+	dev_info(&interface->dev, "Line6 %s found\n", properties->name);
+	product = le16_to_cpu(usbdev->descriptor.idProduct);
+
+	/* query interface number */
+	interface_number = interface->cur_altsetting->desc.bInterfaceNumber;
+
+	switch (product) {
+	case LINE6_DEVID_BASSPODXTLIVE:
+	case LINE6_DEVID_POCKETPOD:
+	case LINE6_DEVID_PODXTLIVE:
+	case LINE6_DEVID_VARIAX:
+		alternate = 1;
+		break;
+
+	case LINE6_DEVID_PODX3:
+	case LINE6_DEVID_PODX3LIVE:
+		switch (interface_number) {
+		case 0:
+			alternate = 1;
+			break;
+		case 1:
+			alternate = 0;
+			break;
+		default:
+			MISSING_CASE;
+		}
+		break;
+
+	case LINE6_DEVID_BASSPODXT:
+	case LINE6_DEVID_BASSPODXTPRO:
+	case LINE6_DEVID_PODXT:
+	case LINE6_DEVID_PODXTPRO:
+		alternate = 5;
+		break;
+
+	case LINE6_DEVID_TONEPORT_GX:
+	case LINE6_DEVID_GUITARPORT:
+		alternate = 2;  /* 1..4 seem to be ok */
+		break;
+
+	case LINE6_DEVID_TONEPORT_UX1:
+	case LINE6_DEVID_TONEPORT_UX2:
+		switch (interface_number) {
+		case 0:
+			/* defaults to 44.1kHz, 16-bit */
+			alternate = 2;
+			break;
+		case 1:
+			alternate = 0;
+			break;
+		default:
+			MISSING_CASE;
+		}
+		break;
+
+	default:
+		MISSING_CASE;
+		return -ENODEV;
+	}
+
+	ret = usb_set_interface(usbdev, interface_number, alternate);
+	if (ret < 0) {
+		dev_err(&interface->dev, "set_interface failed\n");
+		return ret;
+	}
+
+	/* initialize device data based on product id: */
+	switch (product) {
+	case LINE6_DEVID_BASSPODXT:
+	case LINE6_DEVID_BASSPODXTLIVE:
+	case LINE6_DEVID_BASSPODXTPRO:
+	case LINE6_DEVID_POCKETPOD:
+	case LINE6_DEVID_PODXT:
+	case LINE6_DEVID_PODXTPRO:
+		size = sizeof(struct usb_line6_pod);
+		ep_read  = 0x84;
+		ep_write = 0x03;
+		break;
+
+	case LINE6_DEVID_PODX3:
+	case LINE6_DEVID_PODX3LIVE:
+		/* currently unused! */
+		size = sizeof(struct usb_line6_pod);
+		ep_read  = 0x81;
+		ep_write = 0x01;
+		break;
+
+	case LINE6_DEVID_TONEPORT_GX:
+	case LINE6_DEVID_TONEPORT_UX1:
+	case LINE6_DEVID_TONEPORT_UX2:
+	case LINE6_DEVID_GUITARPORT:
+		size = sizeof(struct usb_line6_toneport);
+		/* these don't have a control channel */
+		break;
+
+	case LINE6_DEVID_PODXTLIVE:
+		switch (interface_number) {
+		case PODXTLIVE_INTERFACE_POD:
+			size = sizeof(struct usb_line6_pod);
+			ep_read  = 0x84;
+			ep_write = 0x03;
+			break;
+
+		case PODXTLIVE_INTERFACE_VARIAX:
+			size = sizeof(struct usb_line6_variax);
+			ep_read  = 0x86;
+			ep_write = 0x05;
+			break;
+
+		default:
+			return -ENODEV;
+		}
+		break;
+
+	case LINE6_DEVID_VARIAX:
+		size = sizeof(struct usb_line6_variax);
+		ep_read  = 0x82;
+		ep_write = 0x01;
+		break;
+
+	default:
+		MISSING_CASE;
+		return -ENODEV;
+	}
+
+	if (size == 0) {
+		dev_err(line6->ifcdev, "driver bug: interface data size not set\n");
+		return -ENODEV;
+	}
+
+	line6 = kzalloc(size, GFP_KERNEL);
+
+	if (line6 == NULL) {
+		dev_err(&interface->dev, "Out of memory\n");
+		return -ENOMEM;
+	}
+
+	/* store basic data: */
+	line6->interface_number = interface_number;
+	line6->properties = properties;
+	line6->usbdev = usbdev;
+	line6->ifcdev = &interface->dev;
+	line6->ep_control_read = ep_read;
+	line6->ep_control_write = ep_write;
+	line6->product = product;
+
+	/* get data from endpoint descriptor (see usb_maxpacket): */
+	{
+		struct usb_host_endpoint *ep;
+		unsigned epnum = usb_pipeendpoint(usb_rcvintpipe(usbdev, ep_read));
+		ep = usbdev->ep_in[epnum];
+
+		if (ep != NULL) {
+			line6->interval = ep->desc.bInterval;
+			line6->max_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);
+		} else {
+			line6->interval = LINE6_FALLBACK_INTERVAL;
+			line6->max_packet_size = LINE6_FALLBACK_MAXPACKETSIZE;
+			dev_err(line6->ifcdev, "endpoint not available, using fallback values");
+		}
+	}
+
+	usb_set_intfdata(interface, line6);
+
+	if (properties->capabilities & LINE6_BIT_CONTROL) {
+		/* initialize USB buffers: */
+		line6->buffer_listen = kmalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL);
+
+		if (line6->buffer_listen == NULL) {
+			dev_err(&interface->dev, "Out of memory\n");
+			line6_destruct(interface);
+			return -ENOMEM;
+		}
+
+		line6->buffer_message = kmalloc(LINE6_MESSAGE_MAXLEN, GFP_KERNEL);
+
+		if (line6->buffer_message == NULL) {
+			dev_err(&interface->dev, "Out of memory\n");
+			line6_destruct(interface);
+			return -ENOMEM;
+		}
+
+		line6->urb_listen = usb_alloc_urb(0, GFP_KERNEL);
+
+		if (line6->urb_listen == NULL) {
+			dev_err(&interface->dev, "Out of memory\n");
+			line6_destruct(interface);
+			return -ENOMEM;
+		}
+
+		ret = line6_start_listen(line6);
+		if (ret < 0) {
+			dev_err(&interface->dev, "%s: usb_submit_urb failed\n",
+				__func__);
+			line6_destruct(interface);
+			return ret;
+		}
+	}
+
+	/* initialize device data based on product id: */
+	switch (product) {
+	case LINE6_DEVID_BASSPODXT:
+	case LINE6_DEVID_BASSPODXTLIVE:
+	case LINE6_DEVID_BASSPODXTPRO:
+	case LINE6_DEVID_POCKETPOD:
+	case LINE6_DEVID_PODX3:
+	case LINE6_DEVID_PODX3LIVE:
+	case LINE6_DEVID_PODXT:
+	case LINE6_DEVID_PODXTPRO:
+		ret = pod_init(interface, (struct usb_line6_pod *)line6);
+		break;
+
+	case LINE6_DEVID_PODXTLIVE:
+		switch (interface_number) {
+		case PODXTLIVE_INTERFACE_POD:
+			ret = pod_init(interface, (struct usb_line6_pod *)line6);
+			break;
+
+		case PODXTLIVE_INTERFACE_VARIAX:
+			ret = variax_init(interface, (struct usb_line6_variax *)line6);
+			break;
+
+		default:
+			dev_err(&interface->dev,
+				"PODxt Live interface %d not supported\n",
+				interface_number);
+			ret = -ENODEV;
+		}
+
+		break;
+
+	case LINE6_DEVID_VARIAX:
+		ret = variax_init(interface, (struct usb_line6_variax *)line6);
+		break;
+
+	case LINE6_DEVID_TONEPORT_GX:
+	case LINE6_DEVID_TONEPORT_UX1:
+	case LINE6_DEVID_TONEPORT_UX2:
+	case LINE6_DEVID_GUITARPORT:
+		ret = toneport_init(interface, (struct usb_line6_toneport *)line6);
+		break;
+
+	default:
+		MISSING_CASE;
+		ret = -ENODEV;
+	}
+
+	if (ret < 0) {
+		line6_destruct(interface);
+		return ret;
+	}
+
+	ret = sysfs_create_link(&interface->dev.kobj, &usbdev->dev.kobj,
+				"usb_device");
+	if (ret < 0) {
+		line6_destruct(interface);
+		return ret;
+	}
+
+	dev_info(&interface->dev, "Line6 %s now attached\n",
+		 line6->properties->name);
+	line6_devices[devnum] = line6;
+	line6_list_devices();
+	return ret;
+}
+
+/*
+	Line6 device disconnected.
+*/
+static void line6_disconnect(struct usb_interface *interface)
+{
+	struct usb_line6 *line6;
+	struct usb_device *usbdev;
+	int interface_number, i;
+
+	if (interface == NULL)
+		return;
+	usbdev = interface_to_usbdev(interface);
+	if (usbdev == NULL)
+		return;
+
+	sysfs_remove_link(&interface->dev.kobj, "usb_device");
+
+	interface_number = interface->cur_altsetting->desc.bInterfaceNumber;
+	line6 = usb_get_intfdata(interface);
+
+	if (line6 != NULL) {
+		if (line6->urb_listen != NULL)
+			usb_kill_urb(line6->urb_listen);
+
+		if (usbdev != line6->usbdev)
+			dev_err(line6->ifcdev,
+				"driver bug: inconsistent usb device\n");
+
+		switch (line6->usbdev->descriptor.idProduct) {
+		case LINE6_DEVID_BASSPODXT:
+		case LINE6_DEVID_BASSPODXTLIVE:
+		case LINE6_DEVID_BASSPODXTPRO:
+		case LINE6_DEVID_POCKETPOD:
+		case LINE6_DEVID_PODX3:
+		case LINE6_DEVID_PODX3LIVE:
+		case LINE6_DEVID_PODXT:
+		case LINE6_DEVID_PODXTPRO:
+			pod_disconnect(interface);
+			break;
+
+		case LINE6_DEVID_PODXTLIVE:
+			switch (interface_number) {
+			case PODXTLIVE_INTERFACE_POD:
+				pod_disconnect(interface);
+				break;
+
+			case PODXTLIVE_INTERFACE_VARIAX:
+				variax_disconnect(interface);
+				break;
+			}
+
+			break;
+
+		case LINE6_DEVID_VARIAX:
+			variax_disconnect(interface);
+			break;
+
+		case LINE6_DEVID_TONEPORT_GX:
+		case LINE6_DEVID_TONEPORT_UX1:
+		case LINE6_DEVID_TONEPORT_UX2:
+		case LINE6_DEVID_GUITARPORT:
+			toneport_disconnect(interface);
+			break;
+
+		default:
+			MISSING_CASE;
+		}
+
+		dev_info(&interface->dev, "Line6 %s now disconnected\n", line6->properties->name);
+
+		for (i = LINE6_MAX_DEVICES; i--;)
+			if (line6_devices[i] == line6)
+				line6_devices[i] = NULL;
+	}
+
+	line6_destruct(interface);
+
+	/* decrement reference counters: */
+	usb_put_intf(interface);
+	usb_put_dev(usbdev);
+
+	line6_list_devices();
+}
+
+static struct usb_driver line6_driver = {
+	.name = DRIVER_NAME,
+	.probe = line6_probe,
+	.disconnect = line6_disconnect,
+	.id_table = line6_id_table,
+};
+
+/*
+	Module initialization.
+*/
+static int __init line6_init(void)
+{
+	int i, retval;
+
+	printk(KERN_INFO "%s driver version %s%s\n",
+	       DRIVER_NAME, DRIVER_VERSION, DRIVER_REVISION);
+	line6_workqueue = create_workqueue(DRIVER_NAME);
+
+	if (line6_workqueue == NULL) {
+		err("couldn't create workqueue");
+		return -EINVAL;
+	}
+
+	for (i = LINE6_MAX_DEVICES; i--;)
+		line6_devices[i] = NULL;
+
+	retval = usb_register(&line6_driver);
+
+	if (retval)
+		err("usb_register failed. Error number %d", retval);
+
+	return retval;
+}
+
+/*
+	Module cleanup.
+*/
+static void __exit line6_exit(void)
+{
+	destroy_workqueue(line6_workqueue);
+	usb_deregister(&line6_driver);
+}
+
+module_init(line6_init);
+module_exit(line6_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRIVER_VERSION);
diff --git a/drivers/staging/line6/driver.h b/drivers/staging/line6/driver.h
new file mode 100644
index 0000000..9908bfa
--- /dev/null
+++ b/drivers/staging/line6/driver.h
@@ -0,0 +1,204 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *	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.
+ *
+ */
+
+#ifndef DRIVER_H
+#define DRIVER_H
+
+
+#include "config.h"
+
+#include <linux/spinlock.h>
+#include <linux/usb.h>
+#include <linux/wait.h>
+#include <sound/core.h>
+
+#include "midi.h"
+
+#define DRIVER_NAME "line6usb"
+
+#define LINE6_TIMEOUT 1
+#define LINE6_MAX_DEVICES 8
+#define LINE6_BUFSIZE_LISTEN 32
+#define LINE6_MESSAGE_MAXLEN 256
+
+
+/*
+	Line6 MIDI control commands
+*/
+#define LINE6_PARAM_CHANGE   0xb0
+#define LINE6_PROGRAM_CHANGE 0xc0
+#define LINE6_SYSEX_BEGIN    0xf0
+#define LINE6_SYSEX_END      0xf7
+#define LINE6_RESET          0xff
+
+/*
+	MIDI channel for messages initiated by the host
+	(and eventually echoed back by the device)
+*/
+#define LINE6_CHANNEL_HOST   0x00
+
+/*
+	MIDI channel for messages initiated by the device
+*/
+#define LINE6_CHANNEL_DEVICE 0x02
+
+#define LINE6_CHANNEL_UNKNOWN 5  /* don't know yet what this is good for */
+
+#define LINE6_CHANNEL_MASK 0x0f
+
+
+#define MISSING_CASE	\
+	printk(KERN_ERR "line6usb driver bug: missing case in %s:%d\n", \
+		__FILE__, __LINE__)
+
+
+#define CHECK_RETURN(x)		\
+do {				\
+	err = x;		\
+	if (err < 0)		\
+		return err;	\
+} while (0)
+
+
+extern const unsigned char line6_midi_id[3];
+extern struct usb_line6 *line6_devices[LINE6_MAX_DEVICES];
+extern struct workqueue_struct *line6_workqueue;
+
+static const int SYSEX_DATA_OFS = sizeof(line6_midi_id) + 3;
+static const int SYSEX_EXTRA_SIZE = sizeof(line6_midi_id) + 4;
+
+
+/**
+	 Common properties of Line6 devices.
+*/
+struct line6_properties {
+	const char *name;
+	int device_bit;
+	int capabilities;
+};
+
+/**
+	 Common data shared by all Line6 devices.
+	 Corresponds to a pair of USB endpoints.
+*/
+struct usb_line6 {
+	/**
+		 USB device.
+	*/
+	struct usb_device *usbdev;
+
+	/**
+		 Product id.
+	*/
+	int product;
+
+	/**
+		 Properties.
+	*/
+	const struct line6_properties *properties;
+
+	/**
+		 Interface number.
+	*/
+	int interface_number;
+
+	/**
+		 Interval (ms).
+	*/
+	int interval;
+
+	/**
+		 Maximum size of USB packet.
+	*/
+	int max_packet_size;
+
+	/**
+		 Device representing the USB interface.
+	*/
+	struct device *ifcdev;
+
+	/**
+		 Line6 sound card data structure.
+		 Each device has at least MIDI or PCM.
+	*/
+	struct snd_card *card;
+
+	/**
+		 Line6 PCM device data structure.
+	*/
+	struct snd_line6_pcm *line6pcm;
+
+	/**
+		 Line6 MIDI device data structure.
+	*/
+	struct snd_line6_midi *line6midi;
+
+	/**
+		 USB endpoint for listening to control commands.
+	*/
+	int ep_control_read;
+
+	/**
+		 USB endpoint for writing control commands.
+	*/
+	int ep_control_write;
+
+	/**
+		 URB for listening to PODxt Pro control endpoint.
+	*/
+	struct urb *urb_listen;
+
+	/**
+		 Buffer for listening to PODxt Pro control endpoint.
+	*/
+	unsigned char *buffer_listen;
+
+	/**
+		 Buffer for message to be processed.
+	*/
+	unsigned char *buffer_message;
+
+	/**
+		 Length of message to be processed.
+	*/
+	int message_length;
+};
+
+
+extern char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1,
+				      int code2, int size);
+extern ssize_t line6_nop_read(struct device *dev,
+			      struct device_attribute *attr, char *buf);
+extern ssize_t line6_nop_write(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t count);
+extern int line6_read_data(struct usb_line6 *line6, int address, void *data,
+			   size_t datalen);
+extern int line6_read_serial_number(struct usb_line6 *line6,
+				    int *serial_number);
+extern int line6_send_program(struct usb_line6 *line6, int value);
+extern int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,
+				  int size);
+extern int line6_send_raw_message_async(struct usb_line6 *line6,
+					const char *buffer, int size);
+extern int line6_send_sysex_message(struct usb_line6 *line6,
+				    const char *buffer, int size);
+extern ssize_t line6_set_raw(struct device *dev, struct device_attribute *attr,
+			     const char *buf, size_t count);
+extern int line6_transmit_parameter(struct usb_line6 *line6, int param,
+				    int value);
+extern int line6_write_data(struct usb_line6 *line6, int address, void *data,
+			    size_t datalen);
+extern void line6_write_hexdump(struct usb_line6 *line6, char dir,
+				const unsigned char *buffer, int size);
+
+
+#endif
diff --git a/drivers/staging/line6/dumprequest.c b/drivers/staging/line6/dumprequest.c
new file mode 100644
index 0000000..decbaa9
--- /dev/null
+++ b/drivers/staging/line6/dumprequest.c
@@ -0,0 +1,151 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *	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.
+ *
+ */
+
+#include "driver.h"
+#include "dumprequest.h"
+
+
+/*
+	Set "dump in progress" flag.
+*/
+void line6_dump_started(struct line6_dump_request *l6dr, int dest)
+{
+	l6dr->in_progress = dest;
+}
+
+/*
+	Invalidate current channel, i.e., set "dump in progress" flag.
+	Reading from the "dump" special file blocks until dump is completed.
+*/
+void line6_invalidate_current(struct line6_dump_request *l6dr)
+{
+	line6_dump_started(l6dr, LINE6_DUMP_CURRENT);
+}
+
+/*
+	Clear "dump in progress" flag and notify waiting processes.
+*/
+void line6_dump_finished(struct line6_dump_request *l6dr)
+{
+	l6dr->in_progress = LINE6_DUMP_NONE;
+	wake_up_interruptible(&l6dr->wait);
+}
+
+/*
+	Send an asynchronous channel dump request.
+*/
+int line6_dump_request_async(struct line6_dump_request *l6dr,
+			     struct usb_line6 *line6, int num)
+{
+	int ret;
+	line6_invalidate_current(l6dr);
+	ret = line6_send_raw_message_async(line6, l6dr->reqbufs[num].buffer,
+					   l6dr->reqbufs[num].length);
+
+	if (ret < 0)
+		line6_dump_finished(l6dr);
+
+	return ret;
+}
+
+/*
+	Send an asynchronous dump request after a given interval.
+*/
+void line6_startup_delayed(struct line6_dump_request *l6dr, int seconds,
+			   void (*function)(unsigned long), void *data)
+{
+	l6dr->timer.expires = jiffies + seconds * HZ;
+	l6dr->timer.function = function;
+	l6dr->timer.data = (unsigned long)data;
+	add_timer(&l6dr->timer);
+}
+
+/*
+	Wait for completion.
+*/
+int line6_wait_dump(struct line6_dump_request *l6dr, int nonblock)
+{
+	int retval = 0;
+	DECLARE_WAITQUEUE(wait, current);
+	add_wait_queue(&l6dr->wait, &wait);
+	current->state = TASK_INTERRUPTIBLE;
+
+	while (l6dr->in_progress) {
+		if (nonblock) {
+			retval = -EAGAIN;
+			break;
+		}
+
+		if (signal_pending(current)) {
+			retval = -ERESTARTSYS;
+			break;
+		} else
+			schedule();
+	}
+
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&l6dr->wait, &wait);
+	return retval;
+}
+
+/*
+	Initialize dump request buffer.
+*/
+int line6_dumpreq_initbuf(struct line6_dump_request *l6dr, const void *buf,
+			  size_t len, int num)
+{
+	l6dr->reqbufs[num].buffer = kmalloc(len, GFP_KERNEL);
+	if (l6dr->reqbufs[num].buffer == NULL)
+		return -ENOMEM;
+	memcpy(l6dr->reqbufs[num].buffer, buf, len);
+	l6dr->reqbufs[num].length = len;
+	return 0;
+}
+
+/*
+	Initialize dump request data structure (including one buffer).
+*/
+int line6_dumpreq_init(struct line6_dump_request *l6dr, const void *buf,
+		       size_t len)
+{
+	int ret;
+	ret = line6_dumpreq_initbuf(l6dr, buf, len, 0);
+	if (ret < 0)
+		return ret;
+	init_waitqueue_head(&l6dr->wait);
+	init_timer(&l6dr->timer);
+	return 0;
+}
+
+/*
+	Destruct dump request data structure.
+*/
+void line6_dumpreq_destructbuf(struct line6_dump_request *l6dr, int num)
+{
+	if (l6dr == NULL)
+		return;
+	if (l6dr->reqbufs[num].buffer == NULL)
+		return;
+	kfree(l6dr->reqbufs[num].buffer);
+	l6dr->reqbufs[num].buffer = NULL;
+}
+
+/*
+	Destruct dump request data structure.
+*/
+void line6_dumpreq_destruct(struct line6_dump_request *l6dr)
+{
+	if (l6dr->reqbufs[0].buffer == NULL)
+		return;
+	line6_dumpreq_destructbuf(l6dr, 0);
+	l6dr->ok = 1;
+	del_timer_sync(&l6dr->timer);
+}
diff --git a/drivers/staging/line6/dumprequest.h b/drivers/staging/line6/dumprequest.h
new file mode 100644
index 0000000..1975d54
--- /dev/null
+++ b/drivers/staging/line6/dumprequest.h
@@ -0,0 +1,90 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *	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.
+ *
+ */
+
+#ifndef DUMPREQUEST_H
+#define DUMPREQUEST_H
+
+
+#include <linux/usb.h>
+#include <linux/wait.h>
+
+#include <sound/core.h>
+
+
+enum {
+	LINE6_DUMP_NONE,
+	LINE6_DUMP_CURRENT
+};
+
+
+struct line6_dump_reqbuf {
+	/**
+		 Buffer for dump requests.
+	*/
+	unsigned char *buffer;
+
+	/**
+		 Size of dump request.
+	*/
+	size_t length;
+};
+
+/**
+	 Provides the functionality to request channel/model/... dump data from a
+	 Line6 device.
+*/
+struct line6_dump_request {
+	/**
+		 Wait queue for access to program dump data.
+	*/
+	wait_queue_head_t wait;
+
+	/**
+		 Indicates an unfinished program dump request.
+		 0: no dump
+		 1: dump current settings
+		 Other device-specific values are also allowed.
+	*/
+	int in_progress;
+
+	/**
+		 Timer for delayed dump request.
+	*/
+	struct timer_list timer;
+
+	/**
+		 Flag if initial dump request has been successful.
+	*/
+	char ok;
+
+	/**
+		 Dump request buffers
+	*/
+	struct line6_dump_reqbuf reqbufs[1];
+};
+
+extern void line6_dump_finished(struct line6_dump_request *l6dr);
+extern int line6_dump_request_async(struct line6_dump_request *l6dr,
+				    struct usb_line6 *line6, int num);
+extern void line6_dump_started(struct line6_dump_request *l6dr, int dest);
+extern void line6_dumpreq_destruct(struct line6_dump_request *l6dr);
+extern void line6_dumpreq_destructbuf(struct line6_dump_request *l6dr, int num);
+extern int line6_dumpreq_init(struct line6_dump_request *l6dr, const void *buf,
+			      size_t len);
+extern int line6_dumpreq_initbuf(struct line6_dump_request *l6dr,
+				 const void *buf, size_t len, int num);
+extern void line6_invalidate_current(struct line6_dump_request *l6dr);
+extern void line6_startup_delayed(struct line6_dump_request *l6dr, int seconds,
+				  void (*function)(unsigned long), void *data);
+extern int line6_wait_dump(struct line6_dump_request *l6dr, int nonblock);
+
+
+#endif
diff --git a/drivers/staging/line6/midi.c b/drivers/staging/line6/midi.c
new file mode 100644
index 0000000..89a2b17
--- /dev/null
+++ b/drivers/staging/line6/midi.c
@@ -0,0 +1,422 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *	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.
+ *
+ */
+
+#include "driver.h"
+
+#include <linux/usb.h>
+
+#include <sound/core.h>
+#include <sound/rawmidi.h>
+
+#include "audio.h"
+#include "midi.h"
+#include "pod.h"
+#include "usbdefs.h"
+
+
+#define USE_MIDIBUF      1
+#define OUTPUT_DUMP_ONLY 0
+
+
+#define line6_rawmidi_substream_midi(substream) \
+	((struct snd_line6_midi *)((substream)->rmidi->private_data))
+
+
+static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
+			   int length);
+
+
+/*
+	Pass data received via USB to MIDI.
+*/
+void line6_midi_receive(struct usb_line6 *line6, unsigned char *data,
+			int length)
+{
+	if (line6->line6midi->substream_receive)
+		snd_rawmidi_receive(line6->line6midi->substream_receive,
+				    data, length);
+}
+
+/*
+	Read data from MIDI buffer and transmit them via USB.
+*/
+static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
+{
+	struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6;
+	struct snd_line6_midi *line6midi = line6->line6midi;
+	struct MidiBuffer *mb = &line6midi->midibuf_out;
+	unsigned long flags;
+	unsigned char chunk[line6->max_packet_size];
+	int req, done;
+
+	spin_lock_irqsave(&line6->line6midi->midi_transmit_lock, flags);
+
+	for (;;) {
+		req = min(midibuf_bytes_free(mb), line6->max_packet_size);
+		done = snd_rawmidi_transmit_peek(substream, chunk, req);
+
+		if (done == 0)
+			break;
+
+#if DO_DUMP_MIDI_SEND
+		line6_write_hexdump(line6, 's', chunk, done);
+#endif
+		midibuf_write(mb, chunk, done);
+		snd_rawmidi_transmit_ack(substream, done);
+	}
+
+	for (;;) {
+		done = midibuf_read(mb, chunk, line6->max_packet_size);
+
+		if (done == 0)
+			break;
+
+		if (midibuf_skip_message(mb, line6midi->midi_mask_transmit))
+			continue;
+
+		send_midi_async(line6, chunk, done);
+	}
+
+	spin_unlock_irqrestore(&line6->line6midi->midi_transmit_lock, flags);
+}
+
+/*
+	Notification of completion of MIDI transmission.
+*/
+static void midi_sent(struct urb *urb)
+{
+	unsigned long flags;
+	int status;
+	int num;
+	struct usb_line6 *line6 = (struct usb_line6 *)urb->context;
+
+	status = urb->status;
+	kfree(urb->transfer_buffer);
+	usb_free_urb(urb);
+
+	if (status == -ESHUTDOWN)
+		return;
+
+	spin_lock_irqsave(&line6->line6midi->send_urb_lock, flags);
+	num = --line6->line6midi->num_active_send_urbs;
+
+	if (num == 0) {
+		line6_midi_transmit(line6->line6midi->substream_transmit);
+		num = line6->line6midi->num_active_send_urbs;
+	}
+
+	if (num == 0)
+		wake_up_interruptible(&line6->line6midi->send_wait);
+
+	spin_unlock_irqrestore(&line6->line6midi->send_urb_lock, flags);
+}
+
+/*
+	Send an asynchronous MIDI message.
+	Assumes that line6->line6midi->send_urb_lock is held
+	(i.e., this function is serialized).
+*/
+static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
+			   int length)
+{
+	struct urb *urb;
+	int retval;
+	unsigned char *transfer_buffer;
+
+	urb = usb_alloc_urb(0, GFP_ATOMIC);
+
+	if (urb == 0) {
+		dev_err(line6->ifcdev, "Out of memory\n");
+		return -ENOMEM;
+	}
+
+#if DO_DUMP_URB_SEND
+	line6_write_hexdump(line6, 'S', data, length);
+#endif
+
+	transfer_buffer = kmalloc(length, GFP_ATOMIC);
+
+	if (transfer_buffer == 0) {
+		usb_free_urb(urb);
+		dev_err(line6->ifcdev, "Out of memory\n");
+		return -ENOMEM;
+	}
+
+	memcpy(transfer_buffer, data, length);
+	usb_fill_int_urb(urb, line6->usbdev,
+			 usb_sndbulkpipe(line6->usbdev,
+					 line6->ep_control_write),
+			 transfer_buffer, length, midi_sent, line6,
+			 line6->interval);
+	urb->actual_length = 0;
+	retval = usb_submit_urb(urb, GFP_ATOMIC);
+
+	if (retval < 0) {
+		dev_err(line6->ifcdev, "usb_submit_urb failed\n");
+		usb_free_urb(urb);
+		return -EINVAL;
+	}
+
+	++line6->line6midi->num_active_send_urbs;
+
+	switch (line6->usbdev->descriptor.idProduct) {
+	case LINE6_DEVID_BASSPODXT:
+	case LINE6_DEVID_BASSPODXTLIVE:
+	case LINE6_DEVID_BASSPODXTPRO:
+	case LINE6_DEVID_PODXT:
+	case LINE6_DEVID_PODXTLIVE:
+	case LINE6_DEVID_PODXTPRO:
+	case LINE6_DEVID_POCKETPOD:
+		pod_midi_postprocess((struct usb_line6_pod *)line6, data,
+				     length);
+		break;
+
+	default:
+		MISSING_CASE;
+	}
+
+	return 0;
+}
+
+static int line6_midi_output_open(struct snd_rawmidi_substream *substream)
+{
+	return 0;
+}
+
+static int line6_midi_output_close(struct snd_rawmidi_substream *substream)
+{
+	return 0;
+}
+
+static void line6_midi_output_trigger(struct snd_rawmidi_substream *substream,
+				      int up)
+{
+	unsigned long flags;
+	struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6;
+
+	line6->line6midi->substream_transmit = substream;
+	spin_lock_irqsave(&line6->line6midi->send_urb_lock, flags);
+
+	if (line6->line6midi->num_active_send_urbs == 0)
+		line6_midi_transmit(substream);
+
+	spin_unlock_irqrestore(&line6->line6midi->send_urb_lock, flags);
+}
+
+static void line6_midi_output_drain(struct snd_rawmidi_substream *substream)
+{
+	struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6;
+	wait_queue_head_t *head = &line6->line6midi->send_wait;
+	DECLARE_WAITQUEUE(wait, current);
+	add_wait_queue(head, &wait);
+	current->state = TASK_INTERRUPTIBLE;
+
+	while (line6->line6midi->num_active_send_urbs > 0)
+		if (signal_pending(current))
+			break;
+		else
+			schedule();
+
+	current->state = TASK_RUNNING;
+	remove_wait_queue(head, &wait);
+}
+
+static int line6_midi_input_open(struct snd_rawmidi_substream *substream)
+{
+	return 0;
+}
+
+static int line6_midi_input_close(struct snd_rawmidi_substream *substream)
+{
+	return 0;
+}
+
+static void line6_midi_input_trigger(struct snd_rawmidi_substream *substream,
+				     int up)
+{
+	struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6;
+
+	if (up)
+		line6->line6midi->substream_receive = substream;
+	else
+		line6->line6midi->substream_receive = 0;
+}
+
+static struct snd_rawmidi_ops line6_midi_output_ops = {
+	.open = line6_midi_output_open,
+	.close = line6_midi_output_close,
+	.trigger = line6_midi_output_trigger,
+	.drain = line6_midi_output_drain,
+};
+
+static struct snd_rawmidi_ops line6_midi_input_ops = {
+	.open = line6_midi_input_open,
+	.close = line6_midi_input_close,
+	.trigger = line6_midi_input_trigger,
+};
+
+/*
+	Cleanup the Line6 MIDI device.
+*/
+static void line6_cleanup_midi(struct snd_rawmidi *rmidi)
+{
+}
+
+/* Create a MIDI device */
+static int snd_line6_new_midi(struct snd_line6_midi *line6midi)
+{
+	struct snd_rawmidi *rmidi;
+	int err;
+
+	err = snd_rawmidi_new(line6midi->line6->card, "Line6 MIDI", 0, 1, 1,
+			      &rmidi);
+	if (err < 0)
+		return err;
+
+	rmidi->private_data = line6midi;
+	rmidi->private_free = line6_cleanup_midi;
+	strcpy(rmidi->name, line6midi->line6->properties->name);
+
+	rmidi->info_flags =
+		SNDRV_RAWMIDI_INFO_OUTPUT |
+		SNDRV_RAWMIDI_INFO_INPUT |
+		SNDRV_RAWMIDI_INFO_DUPLEX;
+
+	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
+			    &line6_midi_output_ops);
+	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
+			    &line6_midi_input_ops);
+	return 0;
+}
+
+/*
+	"read" request on "midi_mask_transmit" special file.
+*/
+static ssize_t midi_get_midi_mask_transmit(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
+{
+	struct usb_interface *interface = to_usb_interface(dev);
+	struct usb_line6 *line6 = usb_get_intfdata(interface);
+	return sprintf(buf, "%d\n", line6->line6midi->midi_mask_transmit);
+}
+
+/*
+	"write" request on "midi_mask" special file.
+*/
+static ssize_t midi_set_midi_mask_transmit(struct device *dev,
+					   struct device_attribute *attr,
+					   const char *buf, size_t count)
+{
+	struct usb_interface *interface = to_usb_interface(dev);
+	struct usb_line6 *line6 = usb_get_intfdata(interface);
+	int value = simple_strtoul(buf, NULL, 10);
+	line6->line6midi->midi_mask_transmit = value;
+	return count;
+}
+
+/*
+	"read" request on "midi_mask_receive" special file.
+*/
+static ssize_t midi_get_midi_mask_receive(struct device *dev,
+					  struct device_attribute *attr,
+					  char *buf)
+{
+	struct usb_interface *interface = to_usb_interface(dev);
+	struct usb_line6 *line6 = usb_get_intfdata(interface);
+	return sprintf(buf, "%d\n", line6->line6midi->midi_mask_receive);
+}
+
+/*
+	"write" request on "midi_mask" special file.
+*/
+static ssize_t midi_set_midi_mask_receive(struct device *dev,
+					  struct device_attribute *attr,
+					  const char *buf, size_t count)
+{
+	struct usb_interface *interface = to_usb_interface(dev);
+	struct usb_line6 *line6 = usb_get_intfdata(interface);
+	int value = simple_strtoul(buf, NULL, 10);
+	line6->line6midi->midi_mask_receive = value;
+	return count;
+}
+
+static DEVICE_ATTR(midi_mask_transmit, S_IWUGO | S_IRUGO, midi_get_midi_mask_transmit, midi_set_midi_mask_transmit);
+static DEVICE_ATTR(midi_mask_receive, S_IWUGO | S_IRUGO, midi_get_midi_mask_receive, midi_set_midi_mask_receive);
+
+/* MIDI device destructor */
+static int snd_line6_midi_free(struct snd_device *device)
+{
+	struct snd_line6_midi *line6midi = device->device_data;
+	device_remove_file(line6midi->line6->ifcdev, &dev_attr_midi_mask_transmit);
+	device_remove_file(line6midi->line6->ifcdev, &dev_attr_midi_mask_receive);
+	midibuf_destroy(&line6midi->midibuf_in);
+	midibuf_destroy(&line6midi->midibuf_out);
+	return 0;
+}
+
+/*
+	Initialize the Line6 MIDI subsystem.
+*/
+int line6_init_midi(struct usb_line6 *line6)
+{
+	static struct snd_device_ops midi_ops = {
+		.dev_free = snd_line6_midi_free,
+	};
+
+	int err;
+	struct snd_line6_midi *line6midi;
+
+	if (!(line6->properties->capabilities & LINE6_BIT_CONTROL))
+		return 0;  /* skip MIDI initialization and report success */
+
+	line6midi = kzalloc(sizeof(struct snd_line6_midi), GFP_KERNEL);
+
+	if (line6midi == NULL)
+		return -ENOMEM;
+
+	err = midibuf_init(&line6midi->midibuf_in, MIDI_BUFFER_SIZE, 0);
+	if (err < 0)
+		return err;
+
+	err = midibuf_init(&line6midi->midibuf_out, MIDI_BUFFER_SIZE, 1);
+	if (err < 0)
+		return err;
+
+	line6midi->line6 = line6;
+	line6midi->midi_mask_transmit = 1;
+	line6midi->midi_mask_receive = 4;
+	line6->line6midi = line6midi;
+
+	err = snd_device_new(line6->card, SNDRV_DEV_RAWMIDI, line6midi,
+			     &midi_ops);
+	if (err < 0)
+		return err;
+
+	snd_card_set_dev(line6->card, line6->ifcdev);
+
+	err = snd_line6_new_midi(line6midi);
+	if (err < 0)
+		return err;
+
+	err = device_create_file(line6->ifcdev, &dev_attr_midi_mask_transmit);
+	if (err < 0)
+		return err;
+
+	err = device_create_file(line6->ifcdev, &dev_attr_midi_mask_receive);
+	if (err < 0)
+		return err;
+
+	init_waitqueue_head(&line6midi->send_wait);
+	spin_lock_init(&line6midi->send_urb_lock);
+	spin_lock_init(&line6midi->midi_transmit_lock);
+	return 0;
+}
diff --git a/drivers/staging/line6/midi.h b/drivers/staging/line6/midi.h
new file mode 100644
index 0000000..c69fd11
--- /dev/null
+++ b/drivers/staging/line6/midi.h
@@ -0,0 +1,87 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *	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.
+ *
+ */
+
+#ifndef MIDI_H
+#define MIDI_H
+
+
+#include <sound/rawmidi.h>
+
+#include "midibuf.h"
+
+
+#define MIDI_BUFFER_SIZE 1024
+
+
+struct snd_line6_midi {
+	/**
+		 Pointer back to the Line6 driver data structure.
+	*/
+	struct usb_line6 *line6;
+
+	/**
+		 MIDI substream for receiving (or NULL if not active).
+	*/
+	struct snd_rawmidi_substream *substream_receive;
+
+	/**
+		 MIDI substream for transmitting (or NULL if not active).
+	*/
+	struct snd_rawmidi_substream *substream_transmit;
+
+	/**
+		 Number of currently active MIDI send URBs.
+	*/
+	int num_active_send_urbs;
+
+	/**
+		 Spin lock to protect updates of send_urb.
+	*/
+	spinlock_t send_urb_lock;
+
+	/**
+		 Spin lock to protect MIDI buffer handling.
+	*/
+	spinlock_t midi_transmit_lock;
+
+	/**
+		 Wait queue for MIDI transmission.
+	*/
+	wait_queue_head_t send_wait;
+
+	/**
+		 Bit mask for output MIDI channels.
+	*/
+	int midi_mask_transmit;
+
+	/**
+		 Bit mask for input MIDI channels.
+	*/
+	int midi_mask_receive;
+
+	/**
+		 Buffer for incoming MIDI stream.
+	*/
+	struct MidiBuffer midibuf_in;
+
+	/**
+		 Buffer for outgoing MIDI stream.
+	*/
+	struct MidiBuffer midibuf_out;
+};
+
+
+extern int line6_init_midi(struct usb_line6 *line6);
+extern void line6_midi_receive(struct usb_line6 *line6, unsigned char *data,
+			       int length);
+
+
+#endif
diff --git a/drivers/staging/line6/midibuf.c b/drivers/staging/line6/midibuf.c
new file mode 100644
index 0000000..ab0a5f3
--- /dev/null
+++ b/drivers/staging/line6/midibuf.c
@@ -0,0 +1,262 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *	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.
+ *
+ */
+
+#include "config.h"
+
+#include <linux/slab.h>
+
+#include "midibuf.h"
+
+
+static int midibuf_message_length(unsigned char code)
+{
+	if (code < 0x80)
+		return -1;
+	else if (code < 0xf0) {
+		static const int length[] = { 3, 3, 3, 3, 2, 2, 3 };
+		return length[(code >> 4) - 8];
+	} else {
+		/*
+			Note that according to the MIDI specification 0xf2 is
+			the "Song Position Pointer", but this is used by Line6
+			to send sysex messages to the host.
+		*/
+		static const int length[] = { -1, 2, -1, 2, -1, -1, 1, 1, 1, 1,
+					       1, 1, 1, -1, 1, 1 };
+		return length[code & 0x0f];
+	}
+}
+
+void midibuf_reset(struct MidiBuffer *this)
+{
+	this->pos_read = this->pos_write = this->full = 0;
+	this->command_prev = -1;
+}
+
+int midibuf_init(struct MidiBuffer *this, int size, int split)
+{
+	this->buf = kmalloc(size, GFP_KERNEL);
+
+	if (this->buf == NULL)
+		return -ENOMEM;
+
+	this->size = size;
+	this->split = split;
+	midibuf_reset(this);
+	return 0;
+}
+
+void midibuf_status(struct MidiBuffer *this)
+{
+	printk(KERN_DEBUG "midibuf size=%d split=%d pos_read=%d pos_write=%d "
+	       "full=%d command_prev=%02x\n", this->size, this->split,
+	       this->pos_read, this->pos_write, this->full, this->command_prev);
+}
+
+static int midibuf_is_empty(struct MidiBuffer *this)
+{
+	return (this->pos_read == this->pos_write) && !this->full;
+}
+
+static int midibuf_is_full(struct MidiBuffer *this)
+{
+	return this->full;
+}
+
+int midibuf_bytes_free(struct MidiBuffer *this)
+{
+	return
+		midibuf_is_full(this) ?
+		0 :
+		(this->pos_read - this->pos_write + this->size - 1) % this->size + 1;
+}
+
+int midibuf_bytes_used(struct MidiBuffer *this)
+{
+	return
+		midibuf_is_empty(this) ?
+		0 :
+		(this->pos_write - this->pos_read + this->size - 1) % this->size + 1;
+}
+
+int midibuf_write(struct MidiBuffer *this, unsigned char *data, int length)
+{
+	int bytes_free;
+	int length1, length2;
+	int skip_active_sense = 0;
+
+	if (midibuf_is_full(this) || (length <= 0))
+		return 0;
+
+	/* skip trailing active sense */
+	if (data[length - 1] == 0xfe) {
+		--length;
+		skip_active_sense = 1;
+	}
+
+	bytes_free = midibuf_bytes_free(this);
+
+	if (length > bytes_free)
+		length = bytes_free;
+
+	if (length > 0) {
+		length1 = this->size - this->pos_write;
+
+		if (length < length1) {
+			/* no buffer wraparound */
+			memcpy(this->buf + this->pos_write, data, length);
+			this->pos_write += length;
+		} else {
+			/* buffer wraparound */
+			length2 = length - length1;
+			memcpy(this->buf + this->pos_write, data, length1);
+			memcpy(this->buf, data + length1, length2);
+			this->pos_write = length2;
+		}
+
+		if (this->pos_write == this->pos_read)
+			this->full = 1;
+	}
+
+	return length + skip_active_sense;
+}
+
+int midibuf_read(struct MidiBuffer *this, unsigned char *data, int length)
+{
+	int bytes_used;
+	int length1, length2;
+	int command;
+	int midi_length;
+	int repeat = 0;
+	int i;
+
+	/* we need to be able to store at least a 3 byte MIDI message */
+	if (length < 3)
+		return -EINVAL;
+
+	if (midibuf_is_empty(this))
+		return 0;
+
+	bytes_used = midibuf_bytes_used(this);
+
+	if (length > bytes_used)
+		length = bytes_used;
+
+	length1 = this->size - this->pos_read;
+
+	/* check MIDI command length */
+	command = this->buf[this->pos_read];
+
+	if (command & 0x80) {
+		midi_length = midibuf_message_length(command);
+		this->command_prev = command;
+	} else {
+		if (this->command_prev > 0) {
+			int midi_length_prev = midibuf_message_length(this->command_prev);
+
+			if (midi_length_prev > 0) {
+				midi_length = midi_length_prev - 1;
+				repeat = 1;
+			} else
+				midi_length = -1;
+		} else
+			midi_length = -1;
+	}
+
+	if (midi_length < 0) {
+		/* search for end of message */
+		if (length < length1) {
+			/* no buffer wraparound */
+			for (i = 1; i < length; ++i)
+				if (this->buf[this->pos_read + i] & 0x80)
+					break;
+
+			midi_length = i;
+		} else {
+			/* buffer wraparound */
+			length2 = length - length1;
+
+			for (i = 1; i < length1; ++i)
+				if (this->buf[this->pos_read + i] & 0x80)
+					break;
+
+			if (i < length1)
+				midi_length = i;
+			else {
+				for (i = 0; i < length2; ++i)
+					if (this->buf[i] & 0x80)
+						break;
+
+				midi_length = length1 + i;
+			}
+		}
+
+		if (midi_length == length)
+			midi_length = -1;  /* end of message not found */
+	}
+
+	if (midi_length < 0) {
+		if (!this->split)
+			return 0;  /* command is not yet complete */
+	} else {
+		if (length < midi_length)
+			return 0;  /* command is not yet complete */
+
+		length = midi_length;
+	}
+
+	if (length < length1) {
+		/* no buffer wraparound */
+		memcpy(data + repeat, this->buf + this->pos_read, length);
+		this->pos_read += length;
+	} else {
+		/* buffer wraparound */
+		length2 = length - length1;
+		memcpy(data + repeat, this->buf + this->pos_read, length1);
+		memcpy(data + repeat + length1, this->buf, length2);
+		this->pos_read = length2;
+	}
+
+	if (repeat)
+		data[0] = this->command_prev;
+
+	this->full = 0;
+	return length + repeat;
+}
+
+int midibuf_ignore(struct MidiBuffer *this, int length)
+{
+	int bytes_used = midibuf_bytes_used(this);
+
+	if (length > bytes_used)
+		length = bytes_used;
+
+	this->pos_read = (this->pos_read + length) % this->size;
+	this->full = 0;
+	return length;
+}
+
+int midibuf_skip_message(struct MidiBuffer *this, unsigned short mask)
+{
+	int cmd = this->command_prev;
+
+	if ((cmd >= 0x80) && (cmd < 0xf0))
+		if ((mask & (1 << (cmd & 0x0f))) == 0)
+			return 1;
+
+	return 0;
+}
+
+void midibuf_destroy(struct MidiBuffer *this)
+{
+	kfree(this->buf);
+	this->buf = NULL;
+}
diff --git a/drivers/staging/line6/midibuf.h b/drivers/staging/line6/midibuf.h
new file mode 100644
index 0000000..9877581
--- /dev/null
+++ b/drivers/staging/line6/midibuf.h
@@ -0,0 +1,39 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *	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.
+ *
+ */
+
+#ifndef MIDIBUF_H
+#define MIDIBUF_H
+
+
+struct MidiBuffer {
+	unsigned char *buf;
+	int size;
+	int split;
+	int pos_read, pos_write;
+	int full;
+	int command_prev;
+};
+
+
+extern int midibuf_bytes_used(struct MidiBuffer *mb);
+extern int midibuf_bytes_free(struct MidiBuffer *mb);
+extern void midibuf_destroy(struct MidiBuffer *mb);
+extern int midibuf_ignore(struct MidiBuffer *mb, int length);
+extern int midibuf_init(struct MidiBuffer *mb, int size, int split);
+extern int midibuf_read(struct MidiBuffer *mb, unsigned char *data, int length);
+extern void midibuf_reset(struct MidiBuffer *mb);
+extern int midibuf_skip_message(struct MidiBuffer *mb, unsigned short mask);
+extern void midibuf_status(struct MidiBuffer *mb);
+extern int midibuf_write(struct MidiBuffer *mb, unsigned char *data,
+			 int length);
+
+
+#endif
diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c
new file mode 100644
index 0000000..fc4113f
--- /dev/null
+++ b/drivers/staging/line6/pcm.c
@@ -0,0 +1,301 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *	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.
+ *
+ */
+
+#include "driver.h"
+
+#include <sound/core.h>
+#include <sound/control.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+
+#include "audio.h"
+#include "capture.h"
+#include "playback.h"
+#include "pod.h"
+
+
+/* trigger callback */
+int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+	struct snd_pcm_substream *s;
+	int err;
+	unsigned long flags;
+
+	spin_lock_irqsave(&line6pcm->lock_trigger, flags);
+	clear_bit(BIT_PREPARED, &line6pcm->flags);
+
+	snd_pcm_group_for_each_entry(s, substream) {
+		switch (s->stream) {
+		case SNDRV_PCM_STREAM_PLAYBACK:
+			err = snd_line6_playback_trigger(s, cmd);
+
+			if (err < 0) {
+				spin_unlock_irqrestore(&line6pcm->lock_trigger,
+						       flags);
+				return err;
+			}
+
+			break;
+
+		case SNDRV_PCM_STREAM_CAPTURE:
+			err = snd_line6_capture_trigger(s, cmd);
+
+			if (err < 0) {
+				spin_unlock_irqrestore(&line6pcm->lock_trigger,
+						       flags);
+				return err;
+			}
+
+			break;
+
+		default:
+			dev_err(s2m(substream), "Unknown stream direction %d\n",
+				s->stream);
+		}
+	}
+
+	spin_unlock_irqrestore(&line6pcm->lock_trigger, flags);
+	return 0;
+}
+
+/* control info callback */
+static int snd_line6_control_info(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 2;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 256;
+	return 0;
+}
+
+/* control get callback */
+static int snd_line6_control_get(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	int i;
+	struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+
+	for (i = 2; i--;)
+		ucontrol->value.integer.value[i] = line6pcm->volume[i];
+
+	return 0;
+}
+
+/* control put callback */
+static int snd_line6_control_put(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	int i, changed = 0;
+	struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+
+	for (i = 2; i--;)
+		if (line6pcm->volume[i] != ucontrol->value.integer.value[i]) {
+			line6pcm->volume[i] = ucontrol->value.integer.value[i];
+			changed = 1;
+		}
+
+	return changed;
+}
+
+/* control definition */
+static struct snd_kcontrol_new line6_control = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "PCM Playback Volume",
+	.index = 0,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.info = snd_line6_control_info,
+	.get = snd_line6_control_get,
+	.put = snd_line6_control_put
+};
+
+/*
+	Cleanup the PCM device.
+*/
+static void line6_cleanup_pcm(struct snd_pcm *pcm)
+{
+	int i;
+	struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm);
+
+	for (i = LINE6_ISO_BUFFERS; i--;) {
+		if (line6pcm->urb_audio_out[i]) {
+			usb_kill_urb(line6pcm->urb_audio_out[i]);
+			usb_free_urb(line6pcm->urb_audio_out[i]);
+		}
+		if (line6pcm->urb_audio_in[i]) {
+			usb_kill_urb(line6pcm->urb_audio_in[i]);
+			usb_free_urb(line6pcm->urb_audio_in[i]);
+		}
+	}
+}
+
+/* create a PCM device */
+static int snd_line6_new_pcm(struct snd_line6_pcm *line6pcm)
+{
+	struct snd_pcm *pcm;
+	int err;
+
+	err = snd_pcm_new(line6pcm->line6->card,
+			 (char *)line6pcm->line6->properties->name,
+			 0, 1, 1, &pcm);
+	if (err < 0)
+		return err;
+
+	pcm->private_data = line6pcm;
+	pcm->private_free = line6_cleanup_pcm;
+	line6pcm->pcm = pcm;
+	strcpy(pcm->name, line6pcm->line6->properties->name);
+
+	/* set operators */
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_line6_playback_ops);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_line6_capture_ops);
+
+	/* pre-allocation of buffers */
+	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
+					snd_dma_continuous_data(GFP_KERNEL),
+					64 * 1024, 128 * 1024);
+
+	return 0;
+}
+
+/* PCM device destructor */
+static int snd_line6_pcm_free(struct snd_device *device)
+{
+	return 0;
+}
+
+/*
+	Create and register the PCM device and mixer entries.
+	Create URBs for playback and capture.
+*/
+int line6_init_pcm(struct usb_line6 *line6,
+		   struct line6_pcm_properties *properties)
+{
+	static struct snd_device_ops pcm_ops = {
+		.dev_free = snd_line6_pcm_free,
+	};
+
+	int err;
+	int ep_read = 0, ep_write = 0;
+	struct snd_line6_pcm *line6pcm;
+
+	if (!(line6->properties->capabilities & LINE6_BIT_PCM))
+		return 0;  /* skip PCM initialization and report success */
+
+	/* initialize PCM subsystem based on product id: */
+	switch (line6->product) {
+	case LINE6_DEVID_BASSPODXT:
+	case LINE6_DEVID_BASSPODXTLIVE:
+	case LINE6_DEVID_BASSPODXTPRO:
+	case LINE6_DEVID_PODXT:
+	case LINE6_DEVID_PODXTLIVE:
+	case LINE6_DEVID_PODXTPRO:
+		ep_read  = 0x82;
+		ep_write = 0x01;
+		break;
+
+	case LINE6_DEVID_PODX3:
+	case LINE6_DEVID_PODX3LIVE:
+		ep_read  = 0x86;
+		ep_write = 0x02;
+		break;
+
+	case LINE6_DEVID_POCKETPOD:
+		ep_read  = 0x82;
+		ep_write = 0x02;
+		break;
+
+	case LINE6_DEVID_GUITARPORT:
+	case LINE6_DEVID_TONEPORT_GX:
+		ep_read  = 0x82;
+		ep_write = 0x01;
+		break;
+
+	case LINE6_DEVID_TONEPORT_UX1:
+		ep_read  = 0x00;
+		ep_write = 0x00;
+		break;
+
+	case LINE6_DEVID_TONEPORT_UX2:
+		ep_read  = 0x87;
+		ep_write = 0x00;
+		break;
+
+	default:
+		MISSING_CASE;
+	}
+
+	line6pcm = kzalloc(sizeof(struct snd_line6_pcm), GFP_KERNEL);
+
+	if (line6pcm == NULL)
+		return -ENOMEM;
+
+	line6pcm->volume[0] = line6pcm->volume[1] = 128;
+	line6pcm->line6 = line6;
+	line6pcm->ep_audio_read = ep_read;
+	line6pcm->ep_audio_write = ep_write;
+	line6pcm->max_packet_size = usb_maxpacket(line6->usbdev,
+						 usb_rcvintpipe(line6->usbdev,
+								ep_read),
+						  0);
+	line6pcm->properties = properties;
+	line6->line6pcm = line6pcm;
+
+	/* PCM device: */
+	err = snd_device_new(line6->card, SNDRV_DEV_PCM, line6, &pcm_ops);
+	if (err < 0)
+		return err;
+
+	snd_card_set_dev(line6->card, line6->ifcdev);
+
+	err = snd_line6_new_pcm(line6pcm);
+	if (err < 0)
+		return err;
+
+	spin_lock_init(&line6pcm->lock_audio_out);
+	spin_lock_init(&line6pcm->lock_audio_in);
+	spin_lock_init(&line6pcm->lock_trigger);
+
+	err = create_audio_out_urbs(line6pcm);
+	if (err < 0)
+		return err;
+
+	err = create_audio_in_urbs(line6pcm);
+	if (err < 0)
+		return err;
+
+	/* mixer: */
+	err = snd_ctl_add(line6->card, snd_ctl_new1(&line6_control, line6pcm));
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+/* prepare pcm callback */
+int snd_line6_prepare(struct snd_pcm_substream *substream)
+{
+	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+
+	if (!test_and_set_bit(BIT_PREPARED, &line6pcm->flags)) {
+		unlink_wait_clear_audio_out_urbs(line6pcm);
+		line6pcm->pos_out = 0;
+		line6pcm->pos_out_done = 0;
+
+		unlink_wait_clear_audio_in_urbs(line6pcm);
+		line6pcm->bytes_out = 0;
+		line6pcm->pos_in_done = 0;
+		line6pcm->bytes_in = 0;
+	}
+
+	return 0;
+}
diff --git a/drivers/staging/line6/pcm.h b/drivers/staging/line6/pcm.h
new file mode 100644
index 0000000..53db217
--- /dev/null
+++ b/drivers/staging/line6/pcm.h
@@ -0,0 +1,222 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *	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.
+ *
+ */
+
+/*
+	PCM interface to POD series devices.
+*/
+
+#ifndef PCM_H
+#define PCM_H
+
+
+#include <sound/pcm.h>
+
+#include "driver.h"
+#include "usbdefs.h"
+
+
+/* number of URBs */
+#define LINE6_ISO_BUFFERS	8
+
+/* number of USB frames per URB */
+#define LINE6_ISO_PACKETS	2
+
+/* in a "full speed" device (such as the PODxt Pro) this means 1ms */
+#define LINE6_ISO_INTERVAL	1
+
+/* this should be queried dynamically from the USB interface! */
+#define LINE6_ISO_PACKET_SIZE_MAX	252
+
+
+/*
+	Extract the messaging device from the substream instance
+*/
+#define s2m(s)	(((struct snd_line6_pcm *) \
+		   snd_pcm_substream_chip(s))->line6->ifcdev)
+
+
+enum {
+	BIT_RUNNING_PLAYBACK,
+	BIT_RUNNING_CAPTURE,
+	BIT_PAUSE_PLAYBACK,
+	BIT_PREPARED
+};
+
+struct line6_pcm_properties {
+	struct snd_pcm_hardware snd_line6_playback_hw, snd_line6_capture_hw;
+	struct snd_pcm_hw_constraint_ratdens snd_line6_rates;
+	int bytes_per_frame;
+};
+
+struct snd_line6_pcm {
+	/**
+		 Pointer back to the Line6 driver data structure.
+	*/
+	struct usb_line6 *line6;
+
+	/**
+		 Properties.
+	*/
+	struct line6_pcm_properties *properties;
+
+	/**
+		 ALSA pcm stream
+	*/
+	struct snd_pcm *pcm;
+
+	/**
+		 URBs for audio playback.
+	*/
+	struct urb *urb_audio_out[LINE6_ISO_BUFFERS];
+
+	/**
+		 URBs for audio capture.
+	*/
+	struct urb *urb_audio_in[LINE6_ISO_BUFFERS];
+
+	/**
+		 Temporary buffer to hold data when playback buffer wraps.
+	*/
+	unsigned char *wrap_out;
+
+	/**
+		 Temporary buffer for capture.
+		 Since the packet size is not known in advance, this buffer is
+		 large enough to store maximum size packets.
+	*/
+	unsigned char *buffer_in;
+
+	/**
+		 Free frame position in the playback buffer.
+	*/
+	snd_pcm_uframes_t pos_out;
+
+	/**
+		 Count processed bytes for playback.
+		 This is modulo period size (to determine when a period is
+		 finished).
+	*/
+	unsigned bytes_out;
+
+	/**
+		 Counter to create desired playback sample rate.
+	*/
+	unsigned count_out;
+
+	/**
+		 Playback period size in bytes
+	*/
+	unsigned period_out;
+
+	/**
+		 Processed frame position in the playback buffer.
+		 The contents of the output ring buffer have been consumed by
+		 the USB subsystem (i.e., sent to the USB device) up to this
+		 position.
+	*/
+	snd_pcm_uframes_t pos_out_done;
+
+	/**
+		 Count processed bytes for capture.
+		 This is modulo period size (to determine when a period is
+		 finished).
+	*/
+	unsigned bytes_in;
+
+	/**
+		 Counter to create desired capture sample rate.
+	*/
+	unsigned count_in;
+
+	/**
+		 Capture period size in bytes
+	*/
+	unsigned period_in;
+
+	/**
+		 Processed frame position in the capture buffer.
+		 The contents of the output ring buffer have been consumed by
+		 the USB subsystem (i.e., sent to the USB device) up to this
+		 position.
+	*/
+	snd_pcm_uframes_t pos_in_done;
+
+	/**
+		 Bit mask of active playback URBs.
+	*/
+	unsigned long active_urb_out;
+
+	/**
+		 Maximum size of USB packet.
+	*/
+	int max_packet_size;
+
+	/**
+		 USB endpoint for listening to audio data.
+	*/
+	int ep_audio_read;
+
+	/**
+		 USB endpoint for writing audio data.
+	*/
+	int ep_audio_write;
+
+	/**
+		 Bit mask of active capture URBs.
+	*/
+	unsigned long active_urb_in;
+
+	/**
+		 Bit mask of playback URBs currently being unlinked.
+	*/
+	unsigned long unlink_urb_out;
+
+	/**
+		 Bit mask of capture URBs currently being unlinked.
+	*/
+	unsigned long unlink_urb_in;
+
+	/**
+		 Spin lock to protect updates of the playback buffer positions (not
+		 contents!)
+	*/
+	spinlock_t lock_audio_out;
+
+	/**
+		 Spin lock to protect updates of the capture buffer positions (not
+		 contents!)
+	*/
+	spinlock_t lock_audio_in;
+
+	/**
+		 Spin lock to protect trigger.
+	*/
+	spinlock_t lock_trigger;
+
+	/**
+		 PCM playback volume (left and right).
+	*/
+	int volume[2];
+
+	/**
+		 Several status bits (see BIT_*).
+	*/
+	unsigned long flags;
+};
+
+
+extern int line6_init_pcm(struct usb_line6 *line6,
+			  struct line6_pcm_properties *properties);
+extern int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd);
+extern int snd_line6_prepare(struct snd_pcm_substream *substream);
+
+
+#endif
diff --git a/drivers/staging/line6/playback.c b/drivers/staging/line6/playback.c
new file mode 100644
index 0000000..acb0612
--- /dev/null
+++ b/drivers/staging/line6/playback.c
@@ -0,0 +1,427 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *	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.
+ *
+ */
+
+#include "driver.h"
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+
+#include "audio.h"
+#include "pcm.h"
+#include "pod.h"
+#include "playback.h"
+
+
+/*
+	Software stereo volume control.
+*/
+static void change_volume(struct urb *urb_out, int volume[],
+			  int bytes_per_frame)
+{
+	int chn = 0;
+
+	if (volume[0] == 256 && volume[1] == 256)
+		return;  /* maximum volume - no change */
+
+	if (bytes_per_frame == 4) {
+		short *p, *buf_end;
+		p = (short *)urb_out->transfer_buffer;
+		buf_end = p + urb_out->transfer_buffer_length / sizeof(*p);
+
+		for (; p < buf_end; ++p) {
+			*p = (*p * volume[chn & 1]) >> 8;
+			++chn;
+		}
+	} else if (bytes_per_frame == 6) {
+		unsigned char *p, *buf_end;
+		p = (unsigned char *)urb_out->transfer_buffer;
+		buf_end = p + urb_out->transfer_buffer_length;
+
+		for (; p < buf_end; p += 3) {
+			int val;
+			val = p[0] + (p[1] << 8) + ((signed char)p[2] << 16);
+			val = (val * volume[chn & 1]) >> 8;
+			p[0] = val;
+			p[1] = val >> 8;
+			p[2] = val >> 16;
+			++chn;
+		}
+	}
+}
+
+/*
+	Find a free URB, prepare audio data, and submit URB.
+*/
+static int submit_audio_out_urb(struct snd_pcm_substream *substream)
+{
+	int index;
+	unsigned long flags;
+	int i, urb_size, urb_frames;
+	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+	const int bytes_per_frame = line6pcm->properties->bytes_per_frame;
+	const int frame_increment = line6pcm->properties->snd_line6_rates.rats[0].num_min;
+	const int frame_factor = line6pcm->properties->snd_line6_rates.rats[0].den * (USB_INTERVALS_PER_SECOND / LINE6_ISO_INTERVAL);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct urb *urb_out;
+
+	spin_lock_irqsave(&line6pcm->lock_audio_out, flags);
+	index = find_first_zero_bit(&line6pcm->active_urb_out, LINE6_ISO_BUFFERS);
+
+	if (index < 0 || index >= LINE6_ISO_BUFFERS) {
+		spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
+		dev_err(s2m(substream), "no free URB found\n");
+		return -EINVAL;
+	}
+
+	urb_out = line6pcm->urb_audio_out[index];
+	urb_size = 0;
+
+	for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
+		/* compute frame size for given sampling rate */
+		int n, fs;
+		struct usb_iso_packet_descriptor *fout = &urb_out->iso_frame_desc[i];
+		line6pcm->count_out += frame_increment;
+		n = line6pcm->count_out / frame_factor;
+		line6pcm->count_out -= n * frame_factor;
+		fs = n * bytes_per_frame;
+		fout->offset = urb_size;
+		fout->length = fs;
+		urb_size += fs;
+	}
+
+	urb_frames = urb_size / bytes_per_frame;
+
+	if (test_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags)) {
+		urb_out->transfer_buffer = line6pcm->wrap_out;
+		memset(line6pcm->wrap_out, 0, urb_size);
+	} else {
+		if (line6pcm->pos_out + urb_frames > runtime->buffer_size) {
+			/*
+				The transferred area goes over buffer boundary,
+				copy the data to the temp buffer.
+			*/
+			int len;
+			len = runtime->buffer_size - line6pcm->pos_out;
+			urb_out->transfer_buffer = line6pcm->wrap_out;
+
+			if (len > 0) {
+				memcpy(line6pcm->wrap_out, runtime->dma_area + line6pcm->pos_out * bytes_per_frame, len * bytes_per_frame);
+				memcpy(line6pcm->wrap_out + len * bytes_per_frame, runtime->dma_area, (urb_frames - len) * bytes_per_frame);
+			} else
+				dev_err(s2m(substream), "driver bug: len = %d\n", len);  /* this is somewhat paranoid */
+		} else {
+			/* set the buffer pointer */
+			urb_out->transfer_buffer = runtime->dma_area + line6pcm->pos_out * bytes_per_frame;
+		}
+	}
+
+	if ((line6pcm->pos_out += urb_frames) >= runtime->buffer_size)
+		line6pcm->pos_out -= runtime->buffer_size;
+
+	urb_out->transfer_buffer_length = urb_size;
+	urb_out->context = substream;
+	change_volume(urb_out, line6pcm->volume, bytes_per_frame);
+
+#if DO_DUMP_PCM_SEND
+	for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
+		struct usb_iso_packet_descriptor *fout = &urb_out->iso_frame_desc[i];
+		line6_write_hexdump(line6pcm->line6, 'P', urb_out->transfer_buffer + fout->offset, fout->length);
+	}
+#endif
+
+	if (usb_submit_urb(urb_out, GFP_ATOMIC) == 0)
+		set_bit(index, &line6pcm->active_urb_out);
+	else
+		dev_err(s2m(substream), "URB out #%d submission failed\n", index);
+
+	spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
+	return 0;
+}
+
+/*
+	Submit all currently available playback URBs.
+*/
+static int submit_audio_out_all_urbs(struct snd_pcm_substream *substream)
+{
+	int ret, i;
+
+	for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
+		ret = submit_audio_out_urb(substream);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+/*
+	Unlink all currently active playback URBs.
+*/
+static void unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm)
+{
+	unsigned int i;
+
+	for (i = LINE6_ISO_BUFFERS; i--;) {
+		if (test_bit(i, &line6pcm->active_urb_out)) {
+			if (!test_and_set_bit(i, &line6pcm->unlink_urb_out)) {
+				struct urb *u = line6pcm->urb_audio_out[i];
+				usb_unlink_urb(u);
+			}
+		}
+	}
+}
+
+/*
+	Wait until unlinking of all currently active playback URBs has been finished.
+*/
+static void wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)
+{
+	int timeout = HZ;
+	unsigned int i;
+	int alive;
+
+	do {
+		alive = 0;
+		for (i = LINE6_ISO_BUFFERS; i--;) {
+			if (test_bit(i, &line6pcm->active_urb_out))
+				alive++;
+		}
+		if (!alive)
+			break;
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(1);
+	} while (--timeout > 0);
+	if (alive)
+		snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
+
+	line6pcm->active_urb_out = 0;
+	line6pcm->unlink_urb_out = 0;
+}
+
+/*
+	Unlink all currently active playback URBs, and wait for finishing.
+*/
+void unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)
+{
+	unlink_audio_out_urbs(line6pcm);
+	wait_clear_audio_out_urbs(line6pcm);
+}
+
+/*
+	Callback for completed playback URB.
+*/
+static void audio_out_callback(struct urb *urb)
+{
+	int i, index, length = 0, shutdown = 0;
+	unsigned long flags;
+
+	struct snd_pcm_substream *substream = (struct snd_pcm_substream *)urb->context;
+	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+
+	/* find index of URB */
+	for (index = LINE6_ISO_BUFFERS; index--;)
+		if (urb == line6pcm->urb_audio_out[index])
+			break;
+
+	if (index < 0)
+		return;  /* URB has been unlinked asynchronously */
+
+	for (i = LINE6_ISO_PACKETS; i--;)
+		length += urb->iso_frame_desc[i].length;
+
+	spin_lock_irqsave(&line6pcm->lock_audio_out, flags);
+	line6pcm->pos_out_done += length / line6pcm->properties->bytes_per_frame;
+
+	if (line6pcm->pos_out_done >= runtime->buffer_size)
+		line6pcm->pos_out_done -= runtime->buffer_size;
+
+	clear_bit(index, &line6pcm->active_urb_out);
+
+	for (i = LINE6_ISO_PACKETS; i--;)
+		if (urb->iso_frame_desc[i].status == -ESHUTDOWN) {
+			shutdown = 1;
+			break;
+		}
+
+	if (test_bit(index, &line6pcm->unlink_urb_out))
+		shutdown = 1;
+
+	spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
+
+	if (!shutdown) {
+		submit_audio_out_urb(substream);
+
+		if ((line6pcm->bytes_out += length) >= line6pcm->period_out) {
+			line6pcm->bytes_out -= line6pcm->period_out;
+			snd_pcm_period_elapsed(substream);
+		}
+	}
+}
+
+/* open playback callback */
+static int snd_line6_playback_open(struct snd_pcm_substream *substream)
+{
+	int err;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+
+	err = snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+					    (&line6pcm->properties->snd_line6_rates));
+	if (err < 0)
+		return err;
+
+	runtime->hw = line6pcm->properties->snd_line6_playback_hw;
+	return 0;
+}
+
+/* close playback callback */
+static int snd_line6_playback_close(struct snd_pcm_substream *substream)
+{
+	return 0;
+}
+
+/* hw_params playback callback */
+static int snd_line6_playback_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params)
+{
+	int ret;
+	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+
+	/* -- Florian Demski [FD] */
+	/* don't ask me why, but this fixes the bug on my machine */
+	if (line6pcm == NULL) {
+		if (substream->pcm == NULL)
+			return -ENOMEM;
+		if (substream->pcm->private_data == NULL)
+			return -ENOMEM;
+		substream->private_data = substream->pcm->private_data;
+		line6pcm = snd_pcm_substream_chip(substream);
+	}
+	/* -- [FD] end */
+
+	ret = snd_pcm_lib_malloc_pages(substream,
+				       params_buffer_bytes(hw_params));
+	if (ret < 0)
+		return ret;
+
+	line6pcm->period_out = params_period_bytes(hw_params);
+	line6pcm->wrap_out = kmalloc(2 * LINE6_ISO_PACKET_SIZE_MAX, GFP_KERNEL);
+
+	if (!line6pcm->wrap_out) {
+		dev_err(s2m(substream), "cannot malloc wrap_out\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+/* hw_free playback callback */
+static int snd_line6_playback_hw_free(struct snd_pcm_substream *substream)
+{
+	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+	unlink_wait_clear_audio_out_urbs(line6pcm);
+
+	kfree(line6pcm->wrap_out);
+	line6pcm->wrap_out = NULL;
+
+	return snd_pcm_lib_free_pages(substream);
+}
+
+/* trigger playback callback */
+int snd_line6_playback_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+	int err;
+	line6pcm->count_out = 0;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		if (!test_and_set_bit(BIT_RUNNING_PLAYBACK, &line6pcm->flags)) {
+			err = submit_audio_out_all_urbs(substream);
+
+			if (err < 0) {
+				clear_bit(BIT_RUNNING_PLAYBACK, &line6pcm->flags);
+				return err;
+			}
+		}
+
+		break;
+
+	case SNDRV_PCM_TRIGGER_STOP:
+		if (test_and_clear_bit(BIT_RUNNING_PLAYBACK, &line6pcm->flags))
+			unlink_audio_out_urbs(line6pcm);
+
+		break;
+
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		set_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags);
+		break;
+
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		clear_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* playback pointer callback */
+static snd_pcm_uframes_t
+snd_line6_playback_pointer(struct snd_pcm_substream *substream)
+{
+	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+	return line6pcm->pos_out_done;
+}
+
+/* playback operators */
+struct snd_pcm_ops snd_line6_playback_ops = {
+	.open =        snd_line6_playback_open,
+	.close =       snd_line6_playback_close,
+	.ioctl =       snd_pcm_lib_ioctl,
+	.hw_params =   snd_line6_playback_hw_params,
+	.hw_free =     snd_line6_playback_hw_free,
+	.prepare =     snd_line6_prepare,
+	.trigger =     snd_line6_trigger,
+	.pointer =     snd_line6_playback_pointer,
+};
+
+int create_audio_out_urbs(struct snd_line6_pcm *line6pcm)
+{
+	int i;
+
+	/* create audio URBs and fill in constant values: */
+	for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
+		struct urb *urb;
+
+		/* URB for audio out: */
+		urb = line6pcm->urb_audio_out[i] = usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL);
+
+		if (urb == NULL) {
+			dev_err(line6pcm->line6->ifcdev, "Out of memory\n");
+			return -ENOMEM;
+		}
+
+		urb->dev = line6pcm->line6->usbdev;
+		urb->pipe = usb_sndisocpipe(line6pcm->line6->usbdev, line6pcm->ep_audio_write & USB_ENDPOINT_NUMBER_MASK);
+		urb->transfer_flags = URB_ISO_ASAP;
+		urb->start_frame = -1;
+		urb->number_of_packets = LINE6_ISO_PACKETS;
+		urb->interval = LINE6_ISO_INTERVAL;
+		urb->error_count = 0;
+		urb->complete = audio_out_callback;
+	}
+
+	return 0;
+}
diff --git a/drivers/staging/line6/playback.h b/drivers/staging/line6/playback.h
new file mode 100644
index 0000000..db1e48b
--- /dev/null
+++ b/drivers/staging/line6/playback.h
@@ -0,0 +1,30 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *	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.
+ *
+ */
+
+#ifndef PLAYBACK_H
+#define PLAYBACK_H
+
+
+#include "driver.h"
+
+#include <sound/pcm.h>
+
+
+extern struct snd_pcm_ops snd_line6_playback_ops;
+
+
+extern int create_audio_out_urbs(struct snd_line6_pcm *line6pcm);
+extern int snd_line6_playback_trigger(struct snd_pcm_substream *substream,
+				      int cmd);
+extern void unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm);
+
+
+#endif
diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c
new file mode 100644
index 0000000..fa5caa24
--- /dev/null
+++ b/drivers/staging/line6/pod.c
@@ -0,0 +1,1151 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *	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.
+ *
+ */
+
+#include "driver.h"
+
+#include "audio.h"
+#include "capture.h"
+#include "control.h"
+#include "playback.h"
+#include "pod.h"
+
+
+#define POD_SYSEX_CODE 3
+#define POD_BYTES_PER_FRAME 6  /* 24bit audio (stereo) */
+
+
+enum {
+	POD_SYSEX_CLIP      = 0x0f,
+	POD_SYSEX_SAVE      = 0x24,
+	POD_SYSEX_SYSTEM    = 0x56,
+	POD_SYSEX_SYSTEMREQ = 0x57,
+	/* POD_SYSEX_UPDATE    = 0x6c, */  /* software update! */
+	POD_SYSEX_STORE     = 0x71,
+	POD_SYSEX_FINISH    = 0x72,
+	POD_SYSEX_DUMPMEM   = 0x73,
+	POD_SYSEX_DUMP      = 0x74,
+	POD_SYSEX_DUMPREQ   = 0x75
+	/* POD_SYSEX_DUMPMEM2  = 0x76 */   /* dumps entire internal memory of PODxt Pro */
+};
+
+enum {
+	POD_monitor_level  = 0x04,
+	POD_routing        = 0x05,
+	POD_tuner_mute     = 0x13,
+	POD_tuner_freq     = 0x15,
+	POD_tuner_note     = 0x16,
+	POD_tuner_pitch    = 0x17,
+	POD_system_invalid = 0x7fff
+};
+
+enum {
+	POD_DUMP_MEMORY = 2
+};
+
+enum {
+	POD_BUSY_READ,
+	POD_BUSY_WRITE,
+	POD_CHANNEL_DIRTY,
+	POD_SAVE_PRESSED,
+	POD_BUSY_MIDISEND
+};
+
+
+static struct snd_ratden pod_ratden = {
+	.num_min = 78125,
+	.num_max = 78125,
+	.num_step = 1,
+	.den = 2
+};
+
+static struct line6_pcm_properties pod_pcm_properties = {
+  .snd_line6_playback_hw = {
+		.info = (SNDRV_PCM_INFO_MMAP |
+						 SNDRV_PCM_INFO_INTERLEAVED |
+						 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+						 SNDRV_PCM_INFO_MMAP_VALID |
+						 SNDRV_PCM_INFO_PAUSE |
+						 SNDRV_PCM_INFO_SYNC_START),
+		.formats =          SNDRV_PCM_FMTBIT_S24_3LE,
+		.rates =            SNDRV_PCM_RATE_KNOT,
+		.rate_min =         39062,
+		.rate_max =         39063,
+		.channels_min =     2,
+		.channels_max =     2,
+		.buffer_bytes_max = 60000,
+		.period_bytes_min = LINE6_ISO_PACKET_SIZE_MAX * POD_BYTES_PER_FRAME,  /* at least one URB must fit into one period */
+		.period_bytes_max = 8192,
+		.periods_min =      1,
+		.periods_max =      1024
+	},
+  .snd_line6_capture_hw = {
+		.info = (SNDRV_PCM_INFO_MMAP |
+						 SNDRV_PCM_INFO_INTERLEAVED |
+						 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+						 SNDRV_PCM_INFO_MMAP_VALID |
+						 SNDRV_PCM_INFO_SYNC_START),
+		.formats =          SNDRV_PCM_FMTBIT_S24_3LE,
+		.rates =            SNDRV_PCM_RATE_KNOT,
+		.rate_min =         39062,
+		.rate_max =         39063,
+		.channels_min =     2,
+		.channels_max =     2,
+		.buffer_bytes_max = 60000,
+		.period_bytes_min = LINE6_ISO_PACKET_SIZE_MAX * POD_BYTES_PER_FRAME,  /* at least one URB must fit into one period */
+		.period_bytes_max = 8192,
+		.periods_min =      1,
+		.periods_max =      1024
+	},
+	.snd_line6_rates = {
+		.nrats = 1,
+		.rats = &pod_ratden
+	},
+	.bytes_per_frame = POD_BYTES_PER_FRAME
+};
+
+static const char pod_request_version[] = { 0xf0, 0x7e, 0x7f, 0x06, 0x01, 0xf7 };
+static const char pod_request_channel[] = { 0xf0, 0x00, 0x01, 0x0c, 0x03, 0x75, 0xf7 };
+static const char pod_version_header[]  = { 0xf2, 0x7e, 0x7f, 0x06, 0x02 };
+
+
+/*
+	Mark all parameters as dirty and notify waiting processes.
+*/
+static void pod_mark_batch_all_dirty(struct usb_line6_pod *pod)
+{
+	int i;
+
+	for (i = POD_CONTROL_SIZE; i--;)
+		set_bit(i, pod->param_dirty);
+}
+
+/*
+	Send an asynchronous request for the POD firmware version and device ID.
+*/
+static int pod_version_request_async(struct usb_line6_pod *pod)
+{
+	return line6_send_raw_message_async(&pod->line6, pod->buffer_versionreq, sizeof(pod_request_version));
+}
+
+static void pod_create_files_work(struct work_struct *work)
+{
+	struct usb_line6_pod *pod = container_of(work, struct usb_line6_pod, create_files_work);
+
+	pod_create_files(pod->firmware_version, pod->line6.properties->device_bit, pod->line6.ifcdev);
+}
+
+static void pod_startup_timeout(unsigned long arg)
+{
+	enum {
+		REQUEST_NONE,
+		REQUEST_DUMP,
+		REQUEST_VERSION
+	};
+
+	int request = REQUEST_NONE;
+	struct usb_line6_pod *pod = (struct usb_line6_pod *)arg;
+
+	if (pod->dumpreq.ok) {
+		if (!pod->versionreq_ok)
+			request = REQUEST_VERSION;
+	} else {
+		if (pod->versionreq_ok)
+			request = REQUEST_DUMP;
+		else if (pod->startup_count++ & 1)
+			request = REQUEST_DUMP;
+		else
+			request = REQUEST_VERSION;
+	}
+
+	switch (request) {
+	case REQUEST_DUMP:
+		line6_dump_request_async(&pod->dumpreq, &pod->line6, 0);
+		break;
+
+	case REQUEST_VERSION:
+		pod_version_request_async(pod);
+		break;
+
+	default:
+		return;
+	}
+
+	line6_startup_delayed(&pod->dumpreq, 1, pod_startup_timeout, pod);
+}
+
+static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code, int size)
+{
+	return line6_alloc_sysex_buffer(&pod->line6, POD_SYSEX_CODE, code, size);
+}
+
+/*
+	Send channel dump data to the PODxt Pro.
+*/
+static void pod_dump(struct usb_line6_pod *pod, const unsigned char *data)
+{
+	int size = 1 + sizeof(pod->prog_data);
+	char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_DUMP, size);
+	if (!sysex)
+		return;
+	/* Don't know what this is good for, but PODxt Pro transmits it, so we
+	 * also do... */
+	sysex[SYSEX_DATA_OFS] = 5;
+	memcpy(sysex + SYSEX_DATA_OFS + 1, data, sizeof(pod->prog_data));
+	line6_send_sysex_message(&pod->line6, sysex, size);
+	memcpy(&pod->prog_data, data, sizeof(pod->prog_data));
+	pod_mark_batch_all_dirty(pod);
+	kfree(sysex);
+}
+
+/*
+	Store parameter value in driver memory and mark it as dirty.
+*/
+static void pod_store_parameter(struct usb_line6_pod *pod, int param, int value)
+{
+	pod->prog_data.control[param] = value;
+	set_bit(param, pod->param_dirty);
+	pod->dirty = 1;
+}
+
+/*
+	Handle SAVE button
+*/
+static void pod_save_button_pressed(struct usb_line6_pod *pod, int type, int index)
+{
+	pod->dirty = 0;
+	set_bit(POD_SAVE_PRESSED, &pod->atomic_flags);
+}
+
+/*
+	Process a completely received message.
+*/
+void pod_process_message(struct usb_line6_pod *pod)
+{
+	const unsigned char *buf = pod->line6.buffer_message;
+
+	/* filter messages by type */
+	switch (buf[0] & 0xf0) {
+	case LINE6_PARAM_CHANGE:
+	case LINE6_PROGRAM_CHANGE:
+	case LINE6_SYSEX_BEGIN:
+		break;  /* handle these further down */
+
+	default:
+		return;  /* ignore all others */
+	}
+
+	/* process all remaining messages */
+	switch (buf[0]) {
+	case LINE6_PARAM_CHANGE | LINE6_CHANNEL_DEVICE:
+		pod_store_parameter(pod, buf[1], buf[2]);
+		/* intentionally no break here! */
+
+	case LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST:
+		if ((buf[1] == POD_amp_model_setup) ||
+		    (buf[1] == POD_effect_setup))
+			/* these also affect other settings */
+			line6_dump_request_async(&pod->dumpreq, &pod->line6, 0);
+
+		break;
+
+	case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_DEVICE:
+	case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST:
+		pod->channel_num = buf[1];
+		pod->dirty = 0;
+		set_bit(POD_CHANNEL_DIRTY, &pod->atomic_flags);
+		line6_dump_request_async(&pod->dumpreq, &pod->line6, 0);
+		break;
+
+	case LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE:
+	case LINE6_SYSEX_BEGIN | LINE6_CHANNEL_UNKNOWN:
+		if (memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) == 0) {
+			switch (buf[5]) {
+			case POD_SYSEX_DUMP:
+				if (pod->line6.message_length == sizeof(pod->prog_data) + 7) {
+					switch (pod->dumpreq.in_progress) {
+					case LINE6_DUMP_CURRENT:
+						memcpy(&pod->prog_data, buf + 7, sizeof(pod->prog_data));
+						pod_mark_batch_all_dirty(pod);
+						pod->dumpreq.ok = 1;
+						break;
+
+					case POD_DUMP_MEMORY:
+						memcpy(&pod->prog_data_buf, buf + 7, sizeof(pod->prog_data_buf));
+						break;
+
+					default:
+						DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown dump code %02X\n", pod->dumpreq.in_progress));
+					}
+
+					line6_dump_finished(&pod->dumpreq);
+				} else
+					DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "wrong size of channel dump message (%d instead of %d)\n",
+																 pod->line6.message_length, (int)sizeof(pod->prog_data) + 7));
+
+				break;
+
+			case POD_SYSEX_SYSTEM: {
+				short value = ((int)buf[7] << 12) | ((int)buf[8] << 8) | ((int)buf[9] << 4) | (int)buf[10];
+
+#define PROCESS_SYSTEM_PARAM(x) \
+					case POD_ ## x: \
+						pod->x.value = value; \
+						wake_up_interruptible(&pod->x.wait); \
+						break;
+
+				switch (buf[6]) {
+					PROCESS_SYSTEM_PARAM(monitor_level);
+					PROCESS_SYSTEM_PARAM(routing);
+					PROCESS_SYSTEM_PARAM(tuner_mute);
+					PROCESS_SYSTEM_PARAM(tuner_freq);
+					PROCESS_SYSTEM_PARAM(tuner_note);
+					PROCESS_SYSTEM_PARAM(tuner_pitch);
+
+#undef PROCESS_SYSTEM_PARAM
+
+				default:
+					DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown tuner/system response %02X\n", buf[6]));
+				}
+
+				break;
+			}
+
+			case POD_SYSEX_FINISH:
+				/* do we need to respond to this? */
+				break;
+
+			case POD_SYSEX_SAVE:
+				pod_save_button_pressed(pod, buf[6], buf[7]);
+				break;
+
+			case POD_SYSEX_CLIP:
+				DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "audio clipped\n"));
+				pod->clipping.value = 1;
+				wake_up_interruptible(&pod->clipping.wait);
+				break;
+
+			case POD_SYSEX_STORE:
+				DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "message %02X not yet implemented\n", buf[5]));
+				break;
+
+			default:
+				DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown sysex message %02X\n", buf[5]));
+			}
+		} else if (memcmp(buf, pod_version_header, sizeof(pod_version_header)) == 0) {
+			if (pod->versionreq_ok == 0) {
+				pod->firmware_version = buf[13] * 100 + buf[14] * 10 + buf[15];
+				pod->device_id = ((int)buf[8] << 16) | ((int)buf[9] << 8) | (int)buf[10];
+				pod->versionreq_ok = 1;
+
+				/* Now we know the firmware version, so we schedule a bottom half
+					 handler to create the special files: */
+				INIT_WORK(&pod->create_files_work, pod_create_files_work);
+				queue_work(line6_workqueue, &pod->create_files_work);
+			} else
+				DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "multiple firmware version message\n"));
+		} else
+			DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown sysex header\n"));
+
+		break;
+
+	case LINE6_SYSEX_END:
+		break;
+
+	default:
+		DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "POD: unknown message %02X\n", buf[0]));
+	}
+}
+
+/*
+	Detect some cases that require a channel dump after sending a command to the
+	device. Important notes:
+	*) The actual dump request can not be sent here since we are not allowed to
+	wait for the completion of the first message in this context, and sending
+	the dump request before completion of the previous message leaves the POD
+	in an undefined state. The dump request will be sent when the echoed
+	commands are received.
+	*) This method fails if a param change message is "chopped" after the first
+	byte.
+*/
+void pod_midi_postprocess(struct usb_line6_pod *pod, unsigned char *data, int length)
+{
+	int i;
+
+	if (!pod->midi_postprocess)
+		return;
+
+	for (i = 0; i < length; ++i) {
+		if (data[i] == (LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST)) {
+			line6_invalidate_current(&pod->dumpreq);
+			break;
+		} else if ((data[i] == (LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST)) && (i < length - 1))
+			if ((data[i + 1] == POD_amp_model_setup) || (data[i + 1] == POD_effect_setup)) {
+				line6_invalidate_current(&pod->dumpreq);
+				break;
+			}
+	}
+}
+
+/*
+	Send channel number (i.e., switch to a different sound).
+*/
+static void pod_send_channel(struct usb_line6_pod *pod, int value)
+{
+	line6_invalidate_current(&pod->dumpreq);
+
+	if (line6_send_program(&pod->line6, value) == 0)
+		pod->channel_num = value;
+	else
+		line6_dump_finished(&pod->dumpreq);
+}
+
+/*
+	Transmit PODxt Pro control parameter.
+*/
+void pod_transmit_parameter(struct usb_line6_pod *pod, int param, int value)
+{
+	if (line6_transmit_parameter(&pod->line6, param, value) == 0)
+		pod_store_parameter(pod, param, value);
+
+	if ((param == POD_amp_model_setup) || (param == POD_effect_setup))  /* these also affect other settings */
+		line6_invalidate_current(&pod->dumpreq);
+}
+
+/*
+	Resolve value to memory location.
+*/
+static void pod_resolve(const char *buf, short block0, short block1, unsigned char *location)
+{
+	int value = simple_strtoul(buf, NULL, 10);
+	short block = (value < 0x40) ? block0 : block1;
+	value &= 0x3f;
+	location[0] = block >> 7;
+	location[1] = value | (block & 0x7f);
+}
+
+/*
+	Send command to store channel/effects setup/amp setup to PODxt Pro.
+*/
+static ssize_t pod_send_store_command(struct device *dev, const char *buf, size_t count, short block0, short block1)
+{
+	struct usb_interface *interface = to_usb_interface(dev);
+	struct usb_line6_pod *pod = usb_get_intfdata(interface);
+
+	int size = 3 + sizeof(pod->prog_data_buf);
+	char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_STORE, size);
+	if (!sysex)
+		return 0;
+
+	sysex[SYSEX_DATA_OFS] = 5;  /* see pod_dump() */
+	pod_resolve(buf, block0, block1, sysex + SYSEX_DATA_OFS + 1);
+	memcpy(sysex + SYSEX_DATA_OFS + 3, &pod->prog_data_buf, sizeof(pod->prog_data_buf));
+
+	line6_send_sysex_message(&pod->line6, sysex, size);
+	kfree(sysex);
+	/* needs some delay here on AMD64 platform */
+	return count;
+}
+
+/*
+	Send command to retrieve channel/effects setup/amp setup to PODxt Pro.
+*/
+static ssize_t pod_send_retrieve_command(struct device *dev, const char *buf, size_t count, short block0, short block1)
+{
+	struct usb_interface *interface = to_usb_interface(dev);
+	struct usb_line6_pod *pod = usb_get_intfdata(interface);
+	int size = 4;
+	char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_DUMPMEM, size);
+
+	if (!sysex)
+		return 0;
+
+	pod_resolve(buf, block0, block1, sysex + SYSEX_DATA_OFS);
+	sysex[SYSEX_DATA_OFS + 2] = 0;
+	sysex[SYSEX_DATA_OFS + 3] = 0;
+	line6_dump_started(&pod->dumpreq, POD_DUMP_MEMORY);
+
+	if (line6_send_sysex_message(&pod->line6, sysex, size) < size)
+		line6_dump_finished(&pod->dumpreq);
+
+	kfree(sysex);
+	/* needs some delay here on AMD64 platform */
+	return count;
+}
+
+/*
+	Generic get name function.
+*/
+static ssize_t get_name_generic(struct usb_line6_pod *pod, const char *str, char *buf)
+{
+	int length = 0;
+	const char *p1;
+	char *p2;
+	char *last_non_space = buf;
+
+	int retval = line6_wait_dump(&pod->dumpreq, 0);
+	if (retval < 0)
+		return retval;
+
+	for (p1 = str, p2 = buf; *p1; ++p1, ++p2) {
+		*p2 = *p1;
+		if (*p2 != ' ')
+			last_non_space = p2;
+		if (++length == POD_NAME_LENGTH)
+			break;
+	}
+
+	*(last_non_space + 1) = '\n';
+	return last_non_space - buf + 2;
+}
+
+/*
+	"read" request on "channel" special file.
+*/
+static ssize_t pod_get_channel(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);
+	return sprintf(buf, "%d\n", pod->channel_num);
+}
+
+/*
+	"write" request on "channel" special file.
+*/
+static ssize_t pod_set_channel(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t count)
+{
+	struct usb_interface *interface = to_usb_interface(dev);
+	struct usb_line6_pod *pod = usb_get_intfdata(interface);
+	int value = simple_strtoul(buf, NULL, 10);
+	pod_send_channel(pod, value);
+	return count;
+}
+
+/*
+	"read" request on "name" special file.
+*/
+static ssize_t pod_get_name(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);
+	return get_name_generic(pod, pod->prog_data.header + POD_NAME_OFFSET, buf);
+}
+
+/*
+	"read" request on "name" special file.
+*/
+static ssize_t pod_get_name_buf(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);
+	return get_name_generic(pod, pod->prog_data_buf.header + POD_NAME_OFFSET, buf);
+}
+
+/*
+	"read" request on "dump" special file.
+*/
+static ssize_t pod_get_dump(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);
+	int retval = line6_wait_dump(&pod->dumpreq, 0);
+	if (retval < 0)
+		return retval;
+	memcpy(buf, &pod->prog_data, sizeof(pod->prog_data));
+	return sizeof(pod->prog_data);
+}
+
+/*
+	"write" request on "dump" special file.
+*/
+static ssize_t pod_set_dump(struct device *dev, struct device_attribute *attr,
+			    const char *buf, size_t count)
+{
+	struct usb_interface *interface = to_usb_interface(dev);
+	struct usb_line6_pod *pod = usb_get_intfdata(interface);
+
+	if (count != sizeof(pod->prog_data)) {
+		dev_err(pod->line6.ifcdev,
+						"data block must be exactly %d bytes\n",
+						(int)sizeof(pod->prog_data));
+		return -EINVAL;
+	}
+
+	pod_dump(pod, buf);
+	return sizeof(pod->prog_data);
+}
+
+/*
+	Request system parameter.
+	@param tuner non-zero, if code refers to a tuner parameter
+*/
+static ssize_t pod_get_system_param(struct usb_line6_pod *pod, char *buf, int code, struct ValueWait *param, int tuner, int sign)
+{
+	char *sysex;
+	int value;
+	static const int size = 1;
+	int retval = 0;
+	DECLARE_WAITQUEUE(wait, current);
+
+	if (((pod->prog_data.control[POD_tuner] & 0x40) == 0) && tuner)
+		return -ENODEV;
+
+	/* send value request to tuner: */
+	param->value = POD_system_invalid;
+	sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEMREQ, size);
+	if (!sysex)
+		return 0;
+	sysex[SYSEX_DATA_OFS] = code;
+	line6_send_sysex_message(&pod->line6, sysex, size);
+	kfree(sysex);
+
+	/* wait for tuner to respond: */
+	add_wait_queue(&param->wait, &wait);
+	current->state = TASK_INTERRUPTIBLE;
+
+	while (param->value == POD_system_invalid) {
+		if (signal_pending(current)) {
+			retval = -ERESTARTSYS;
+			break;
+		} else
+			schedule();
+	}
+
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&param->wait, &wait);
+
+	if (retval < 0)
+		return retval;
+
+	value = sign ? (int)(signed short)param->value : (int)(unsigned short)param->value;
+	return sprintf(buf, "%d\n", value);
+}
+
+/*
+	Send system parameter.
+	@param tuner non-zero, if code refers to a tuner parameter
+*/
+static ssize_t pod_set_system_param(struct usb_line6_pod *pod, const char *buf,
+				    int count, int code, unsigned short mask,
+				    int tuner)
+{
+	char *sysex;
+	static const int size = 5;
+	unsigned short value;
+
+	if (((pod->prog_data.control[POD_tuner] & 0x40) == 0) && tuner)
+		return -EINVAL;
+
+	/* send value to tuner: */
+	sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size);
+	if (!sysex)
+		return 0;
+	value = simple_strtoul(buf, NULL, 10) & mask;
+	sysex[SYSEX_DATA_OFS] = code;
+	sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f;
+	sysex[SYSEX_DATA_OFS + 2] = (value >>  8) & 0x0f;
+	sysex[SYSEX_DATA_OFS + 3] = (value >>  4) & 0x0f;
+	sysex[SYSEX_DATA_OFS + 4] = (value      ) & 0x0f;
+	line6_send_sysex_message(&pod->line6, sysex, size);
+	kfree(sysex);
+	return count;
+}
+
+/*
+	"read" request on "dump_buf" special file.
+*/
+static ssize_t pod_get_dump_buf(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);
+	int retval = line6_wait_dump(&pod->dumpreq, 0);
+	if (retval < 0)
+		return retval;
+	memcpy(buf, &pod->prog_data_buf, sizeof(pod->prog_data_buf));
+	return sizeof(pod->prog_data_buf);
+}
+
+/*
+	"write" request on "dump_buf" special file.
+*/
+static ssize_t pod_set_dump_buf(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	struct usb_interface *interface = to_usb_interface(dev);
+	struct usb_line6_pod *pod = usb_get_intfdata(interface);
+
+	if (count != sizeof(pod->prog_data)) {
+		dev_err(pod->line6.ifcdev,
+						"data block must be exactly %d bytes\n",
+						(int)sizeof(pod->prog_data));
+		return -EINVAL;
+	}
+
+	memcpy(&pod->prog_data_buf, buf, sizeof(pod->prog_data));
+	return sizeof(pod->prog_data);
+}
+
+/*
+	"write" request on "finish" special file.
+*/
+static ssize_t pod_set_finish(struct device *dev,
+			      struct device_attribute *attr,
+			      const char *buf, size_t count)
+{
+	struct usb_interface *interface = to_usb_interface(dev);
+	struct usb_line6_pod *pod = usb_get_intfdata(interface);
+	int size = 0;
+	char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_FINISH, size);
+	if (!sysex)
+		return 0;
+	line6_send_sysex_message(&pod->line6, sysex, size);
+	kfree(sysex);
+	return count;
+}
+
+/*
+	"write" request on "store_channel" special file.
+*/
+static ssize_t pod_set_store_channel(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	return pod_send_store_command(dev, buf, count, 0x0000, 0x00c0);
+}
+
+/*
+	"write" request on "store_effects_setup" special file.
+*/
+static ssize_t pod_set_store_effects_setup(struct device *dev,
+					   struct device_attribute *attr,
+					   const char *buf, size_t count)
+{
+	return pod_send_store_command(dev, buf, count, 0x0080, 0x0080);
+}
+
+/*
+	"write" request on "store_amp_setup" special file.
+*/
+static ssize_t pod_set_store_amp_setup(struct device *dev,
+				       struct device_attribute *attr,
+				       const char *buf, size_t count)
+{
+	return pod_send_store_command(dev, buf, count, 0x0040, 0x0100);
+}
+
+/*
+	"write" request on "retrieve_channel" special file.
+*/
+static ssize_t pod_set_retrieve_channel(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf, size_t count)
+{
+	return pod_send_retrieve_command(dev, buf, count, 0x0000, 0x00c0);
+}
+
+/*
+	"write" request on "retrieve_effects_setup" special file.
+*/
+static ssize_t pod_set_retrieve_effects_setup(struct device *dev,
+					      struct device_attribute *attr,
+					      const char *buf, size_t count)
+{
+	return pod_send_retrieve_command(dev, buf, count, 0x0080, 0x0080);
+}
+
+/*
+	"write" request on "retrieve_amp_setup" special file.
+*/
+static ssize_t pod_set_retrieve_amp_setup(struct device *dev,
+					  struct device_attribute *attr,
+					  const char *buf, size_t count)
+{
+	return pod_send_retrieve_command(dev, buf, count, 0x0040, 0x0100);
+}
+
+/*
+	"read" request on "dirty" special file.
+*/
+static ssize_t pod_get_dirty(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);
+	buf[0] = pod->dirty ? '1' : '0';
+	buf[1] = '\n';
+	return 2;
+}
+
+/*
+	"read" request on "midi_postprocess" special file.
+*/
+static ssize_t pod_get_midi_postprocess(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);
+	return sprintf(buf, "%d\n", pod->midi_postprocess);
+}
+
+/*
+	"write" request on "midi_postprocess" special file.
+*/
+static ssize_t pod_set_midi_postprocess(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf, size_t count)
+{
+	struct usb_interface *interface = to_usb_interface(dev);
+	struct usb_line6_pod *pod = usb_get_intfdata(interface);
+	int value = simple_strtoul(buf, NULL, 10);
+	pod->midi_postprocess = value ? 1 : 0;
+	return count;
+}
+
+/*
+	"read" request on "serial_number" special file.
+*/
+static ssize_t pod_get_serial_number(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);
+	return sprintf(buf, "%d\n", pod->serial_number);
+}
+
+/*
+	"read" request on "firmware_version" special file.
+*/
+static ssize_t pod_get_firmware_version(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);
+	return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100,
+		       pod->firmware_version % 100);
+}
+
+/*
+	"read" request on "device_id" special file.
+*/
+static ssize_t pod_get_device_id(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);
+	return sprintf(buf, "%d\n", pod->device_id);
+}
+
+/*
+	"read" request on "clip" special file.
+*/
+static ssize_t pod_wait_for_clip(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);
+	int err = 0;
+	DECLARE_WAITQUEUE(wait, current);
+	pod->clipping.value = 0;
+	add_wait_queue(&pod->clipping.wait, &wait);
+	current->state = TASK_INTERRUPTIBLE;
+
+	while (pod->clipping.value == 0) {
+		if (signal_pending(current)) {
+			err = -ERESTARTSYS;
+			break;
+		} else
+			schedule();
+	}
+
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&pod->clipping.wait, &wait);
+	return err;
+}
+
+#define POD_GET_SYSTEM_PARAM(code, tuner, sign) \
+static ssize_t pod_get_ ## code(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); \
+	return pod_get_system_param(pod, buf, POD_ ## code, &pod->code, \
+				    tuner, sign); \
+}
+
+#define POD_GET_SET_SYSTEM_PARAM(code, mask, tuner, sign) \
+POD_GET_SYSTEM_PARAM(code, tuner, sign) \
+static ssize_t pod_set_ ## code(struct device *dev, \
+				struct device_attribute *attr, \
+				const char *buf, size_t count) \
+{ \
+	struct usb_interface *interface = to_usb_interface(dev); \
+	struct usb_line6_pod *pod = usb_get_intfdata(interface); \
+	return pod_set_system_param(pod, buf, count, POD_ ## code, mask, \
+				    tuner); \
+}
+
+POD_GET_SET_SYSTEM_PARAM(monitor_level, 0xffff, 0, 0);
+POD_GET_SET_SYSTEM_PARAM(routing, 0x0003, 0, 0);
+POD_GET_SET_SYSTEM_PARAM(tuner_mute, 0x0001, 1, 0);
+POD_GET_SET_SYSTEM_PARAM(tuner_freq, 0xffff, 1, 0);
+POD_GET_SYSTEM_PARAM(tuner_note, 1, 1);
+POD_GET_SYSTEM_PARAM(tuner_pitch, 1, 1);
+
+#undef GET_SET_SYSTEM_PARAM
+#undef GET_SYSTEM_PARAM
+
+/* POD special files: */
+static DEVICE_ATTR(channel, S_IWUGO | S_IRUGO, pod_get_channel, pod_set_channel);
+static DEVICE_ATTR(clip, S_IRUGO, pod_wait_for_clip, line6_nop_write);
+static DEVICE_ATTR(device_id, S_IRUGO, pod_get_device_id, line6_nop_write);
+static DEVICE_ATTR(dirty, S_IRUGO, pod_get_dirty, line6_nop_write);
+static DEVICE_ATTR(dump, S_IWUGO | S_IRUGO, pod_get_dump, pod_set_dump);
+static DEVICE_ATTR(dump_buf, S_IWUGO | S_IRUGO, pod_get_dump_buf, pod_set_dump_buf);
+static DEVICE_ATTR(finish, S_IWUGO, line6_nop_read, pod_set_finish);
+static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version, line6_nop_write);
+static DEVICE_ATTR(midi_postprocess, S_IWUGO | S_IRUGO, pod_get_midi_postprocess, pod_set_midi_postprocess);
+static DEVICE_ATTR(monitor_level, S_IWUGO | S_IRUGO, pod_get_monitor_level, pod_set_monitor_level);
+static DEVICE_ATTR(name, S_IRUGO, pod_get_name, line6_nop_write);
+static DEVICE_ATTR(name_buf, S_IRUGO, pod_get_name_buf, line6_nop_write);
+static DEVICE_ATTR(retrieve_amp_setup, S_IWUGO, line6_nop_read, pod_set_retrieve_amp_setup);
+static DEVICE_ATTR(retrieve_channel, S_IWUGO, line6_nop_read, pod_set_retrieve_channel);
+static DEVICE_ATTR(retrieve_effects_setup, S_IWUGO, line6_nop_read, pod_set_retrieve_effects_setup);
+static DEVICE_ATTR(routing, S_IWUGO | S_IRUGO, pod_get_routing, pod_set_routing);
+static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number, line6_nop_write);
+static DEVICE_ATTR(store_amp_setup, S_IWUGO, line6_nop_read, pod_set_store_amp_setup);
+static DEVICE_ATTR(store_channel, S_IWUGO, line6_nop_read, pod_set_store_channel);
+static DEVICE_ATTR(store_effects_setup, S_IWUGO, line6_nop_read, pod_set_store_effects_setup);
+static DEVICE_ATTR(tuner_freq, S_IWUGO | S_IRUGO, pod_get_tuner_freq, pod_set_tuner_freq);
+static DEVICE_ATTR(tuner_mute, S_IWUGO | S_IRUGO, pod_get_tuner_mute, pod_set_tuner_mute);
+static DEVICE_ATTR(tuner_note, S_IRUGO, pod_get_tuner_note, line6_nop_write);
+static DEVICE_ATTR(tuner_pitch, S_IRUGO, pod_get_tuner_pitch, line6_nop_write);
+
+#if CREATE_RAW_FILE
+static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw);
+#endif
+
+/*
+	POD destructor.
+*/
+static void pod_destruct(struct usb_interface *interface)
+{
+	struct usb_line6_pod *pod = usb_get_intfdata(interface);
+	struct usb_line6 *line6;
+
+	if (pod == NULL)
+		return;
+	line6 = &pod->line6;
+	if (line6 == NULL)
+		return;
+	line6_cleanup_audio(line6);
+
+	/* free dump request data: */
+	line6_dumpreq_destruct(&pod->dumpreq);
+
+	kfree(pod->buffer_versionreq);
+}
+
+/*
+	Create sysfs entries.
+*/
+static int pod_create_files2(struct device *dev)
+{
+	int err;
+
+	CHECK_RETURN(device_create_file(dev, &dev_attr_channel));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_clip));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_device_id));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_dirty));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_dump));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_dump_buf));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_finish));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_firmware_version));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_midi_postprocess));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_monitor_level));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_name));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_name_buf));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_retrieve_amp_setup));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_retrieve_channel));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_retrieve_effects_setup));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_routing));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_serial_number));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_store_amp_setup));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_store_channel));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_store_effects_setup));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_freq));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_mute));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_note));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_pitch));
+
+#if CREATE_RAW_FILE
+	CHECK_RETURN(device_create_file(dev, &dev_attr_raw));
+#endif
+
+	return 0;
+}
+
+/*
+	 Init POD device.
+*/
+int pod_init(struct usb_interface *interface, struct usb_line6_pod *pod)
+{
+	int err;
+	struct usb_line6 *line6 = &pod->line6;
+
+	if ((interface == NULL) || (pod == NULL))
+		return -ENODEV;
+
+	pod->channel_num = 255;
+
+	/* initialize wait queues: */
+	init_waitqueue_head(&pod->monitor_level.wait);
+	init_waitqueue_head(&pod->routing.wait);
+	init_waitqueue_head(&pod->tuner_mute.wait);
+	init_waitqueue_head(&pod->tuner_freq.wait);
+	init_waitqueue_head(&pod->tuner_note.wait);
+	init_waitqueue_head(&pod->tuner_pitch.wait);
+	init_waitqueue_head(&pod->clipping.wait);
+
+	memset(pod->param_dirty, 0xff, sizeof(pod->param_dirty));
+
+	/* initialize USB buffers: */
+	err = line6_dumpreq_init(&pod->dumpreq, pod_request_channel,
+				 sizeof(pod_request_channel));
+	if (err < 0) {
+		dev_err(&interface->dev, "Out of memory\n");
+		pod_destruct(interface);
+		return -ENOMEM;
+	}
+
+	pod->buffer_versionreq = kmalloc(sizeof(pod_request_version),
+					 GFP_KERNEL);
+
+	if (pod->buffer_versionreq == NULL) {
+		dev_err(&interface->dev, "Out of memory\n");
+		pod_destruct(interface);
+		return -ENOMEM;
+	}
+
+	memcpy(pod->buffer_versionreq, pod_request_version,
+	       sizeof(pod_request_version));
+
+	/* create sysfs entries: */
+	err = pod_create_files2(&interface->dev);
+	if (err < 0) {
+		pod_destruct(interface);
+		return err;
+	}
+
+	/* initialize audio system: */
+	err = line6_init_audio(line6);
+	if (err < 0) {
+		pod_destruct(interface);
+		return err;
+	}
+
+	/* initialize MIDI subsystem: */
+	err = line6_init_midi(line6);
+	if (err < 0) {
+		pod_destruct(interface);
+		return err;
+	}
+
+	/* initialize PCM subsystem: */
+	err = line6_init_pcm(line6, &pod_pcm_properties);
+	if (err < 0) {
+		pod_destruct(interface);
+		return err;
+	}
+
+	/* register audio system: */
+	err = line6_register_audio(line6);
+	if (err < 0) {
+		pod_destruct(interface);
+		return err;
+	}
+
+	if (pod->line6.properties->capabilities & LINE6_BIT_CONTROL) {
+		/* query some data: */
+		line6_startup_delayed(&pod->dumpreq, POD_STARTUP_DELAY,
+				      pod_startup_timeout, pod);
+		line6_read_serial_number(&pod->line6, &pod->serial_number);
+	}
+
+	return 0;
+}
+
+/*
+	POD device disconnected.
+*/
+void pod_disconnect(struct usb_interface *interface)
+{
+	struct usb_line6_pod *pod;
+
+	if (interface == NULL)
+		return;
+	pod = usb_get_intfdata(interface);
+
+	if (pod != NULL) {
+		struct snd_line6_pcm *line6pcm = pod->line6.line6pcm;
+		struct device *dev = &interface->dev;
+
+		if (line6pcm != NULL) {
+			unlink_wait_clear_audio_out_urbs(line6pcm);
+			unlink_wait_clear_audio_in_urbs(line6pcm);
+		}
+
+		if (dev != NULL) {
+			/* remove sysfs entries: */
+			if (pod->versionreq_ok)
+				pod_remove_files(pod->firmware_version, pod->line6.properties->device_bit, dev);
+
+			device_remove_file(dev, &dev_attr_channel);
+			device_remove_file(dev, &dev_attr_clip);
+			device_remove_file(dev, &dev_attr_device_id);
+			device_remove_file(dev, &dev_attr_dirty);
+			device_remove_file(dev, &dev_attr_dump);
+			device_remove_file(dev, &dev_attr_dump_buf);
+			device_remove_file(dev, &dev_attr_finish);
+			device_remove_file(dev, &dev_attr_firmware_version);
+			device_remove_file(dev, &dev_attr_midi_postprocess);
+			device_remove_file(dev, &dev_attr_monitor_level);
+			device_remove_file(dev, &dev_attr_name);
+			device_remove_file(dev, &dev_attr_name_buf);
+			device_remove_file(dev, &dev_attr_retrieve_amp_setup);
+			device_remove_file(dev, &dev_attr_retrieve_channel);
+			device_remove_file(dev, &dev_attr_retrieve_effects_setup);
+			device_remove_file(dev, &dev_attr_routing);
+			device_remove_file(dev, &dev_attr_serial_number);
+			device_remove_file(dev, &dev_attr_store_amp_setup);
+			device_remove_file(dev, &dev_attr_store_channel);
+			device_remove_file(dev, &dev_attr_store_effects_setup);
+			device_remove_file(dev, &dev_attr_tuner_freq);
+			device_remove_file(dev, &dev_attr_tuner_mute);
+			device_remove_file(dev, &dev_attr_tuner_note);
+			device_remove_file(dev, &dev_attr_tuner_pitch);
+
+#if CREATE_RAW_FILE
+			device_remove_file(dev, &dev_attr_raw);
+#endif
+		}
+	}
+
+	pod_destruct(interface);
+}
diff --git a/drivers/staging/line6/pod.h b/drivers/staging/line6/pod.h
new file mode 100644
index 0000000..7051ca6
--- /dev/null
+++ b/drivers/staging/line6/pod.h
@@ -0,0 +1,204 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *	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.
+ *
+ */
+
+#ifndef POD_H
+#define POD_H
+
+
+#include "driver.h"
+
+#include <linux/spinlock.h>
+#include <linux/usb.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+
+#include <sound/core.h>
+
+#include "dumprequest.h"
+
+
+/*
+	PODxt Live interfaces
+*/
+#define PODXTLIVE_INTERFACE_POD    0
+#define PODXTLIVE_INTERFACE_VARIAX 1
+
+/*
+	Locate name in binary program dump
+*/
+#define	POD_NAME_OFFSET 0
+#define	POD_NAME_LENGTH 16
+
+/*
+	Other constants
+*/
+#define POD_CONTROL_SIZE 0x80
+#define POD_BUFSIZE_DUMPREQ 7
+#define POD_STARTUP_DELAY 3
+
+
+/**
+	 Data structure for values that need to be requested explicitly.
+	 This is the case for system and tuner settings.
+*/
+struct ValueWait {
+	unsigned short value;
+	wait_queue_head_t wait;
+};
+
+/**
+	 Binary PodXT Pro program dump
+*/
+struct pod_program {
+	/**
+		 Header information (including program name).
+	*/
+	unsigned char header[0x20];
+
+	/**
+		 Program parameters.
+	*/
+	unsigned char control[POD_CONTROL_SIZE];
+};
+
+struct usb_line6_pod {
+	/**
+		 Generic Line6 USB data.
+	*/
+	struct usb_line6 line6;
+
+	/**
+		 Dump request structure.
+	*/
+	struct line6_dump_request dumpreq;
+
+	/**
+		 Current program number.
+	*/
+	unsigned char channel_num;
+
+	/**
+		 Current program settings.
+	*/
+	struct pod_program prog_data;
+
+	/**
+		 Buffer for data retrieved from or to be stored on PODxt Pro.
+	*/
+	struct pod_program prog_data_buf;
+
+	/**
+		 Buffer for requesting version number.
+	*/
+	unsigned char *buffer_versionreq;
+
+	/**
+		 Tuner mute mode.
+	*/
+	struct ValueWait tuner_mute;
+
+	/**
+		 Tuner base frequency (typically 440Hz).
+	*/
+	struct ValueWait tuner_freq;
+
+	/**
+		 Note received from tuner.
+	*/
+	struct ValueWait tuner_note;
+
+	/**
+		 Pitch value received from tuner.
+	*/
+	struct ValueWait tuner_pitch;
+
+	/**
+		 Instrument monitor level.
+	*/
+	struct ValueWait monitor_level;
+
+	/**
+		 Audio routing mode.
+		 0: send processed guitar
+		 1: send clean guitar
+		 2: send clean guitar re-amp playback
+		 3: send re-amp playback
+	*/
+	struct ValueWait routing;
+
+	/**
+		 Wait for audio clipping event.
+	*/
+	struct ValueWait clipping;
+
+	/**
+		 Bottom-half for creation of sysfs special files.
+	*/
+	struct work_struct create_files_work;
+
+	/**
+		 Dirty flags for access to parameter data.
+	*/
+	unsigned long param_dirty[POD_CONTROL_SIZE / sizeof(unsigned long)];
+
+	/**
+		 Some atomic flags.
+	*/
+	unsigned long atomic_flags;
+
+	/**
+		 Counter for startup process.
+	*/
+	int startup_count;
+
+	/**
+		 Serial number of device.
+	*/
+	int serial_number;
+
+	/**
+		 Firmware version (x 100).
+	*/
+	int firmware_version;
+
+	/**
+		 Device ID.
+	*/
+	int device_id;
+
+	/**
+		 Flag to indicate modification of current program settings.
+	*/
+	char dirty;
+
+	/**
+		 Flag if initial firmware version request has been successful.
+	*/
+	char versionreq_ok;
+
+	/**
+		 Flag to enable MIDI postprocessing.
+	*/
+	char midi_postprocess;
+};
+
+
+extern void pod_disconnect(struct usb_interface *interface);
+extern int pod_init(struct usb_interface *interface, struct usb_line6_pod *pod);
+extern void pod_midi_postprocess(struct usb_line6_pod *pod,
+				 unsigned char *data, int length);
+extern void pod_process_message(struct usb_line6_pod *pod);
+extern void pod_receive_parameter(struct usb_line6_pod *pod, int param);
+extern void pod_transmit_parameter(struct usb_line6_pod *pod, int param,
+				   int value);
+
+
+#endif
diff --git a/drivers/staging/line6/revision.h b/drivers/staging/line6/revision.h
new file mode 100644
index 0000000..b2a0a85
--- /dev/null
+++ b/drivers/staging/line6/revision.h
@@ -0,0 +1,4 @@
+#ifndef DRIVER_REVISION
+/* current subversion revision */
+#define DRIVER_REVISION " (revision 529)"
+#endif
diff --git a/drivers/staging/line6/toneport.c b/drivers/staging/line6/toneport.c
new file mode 100644
index 0000000..eaa1229
--- /dev/null
+++ b/drivers/staging/line6/toneport.c
@@ -0,0 +1,241 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *                         Emil Myhrman (emil.myhrman@gmail.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.
+ *
+ */
+
+#include "driver.h"
+
+#include "audio.h"
+#include "capture.h"
+#include "playback.h"
+#include "toneport.h"
+
+
+static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2);
+
+
+static struct snd_ratden toneport_ratden = {
+	.num_min = 44100,
+	.num_max = 44100,
+	.num_step = 1,
+	.den = 1
+};
+
+static struct line6_pcm_properties toneport_pcm_properties = {
+  .snd_line6_playback_hw = {
+		.info = (SNDRV_PCM_INFO_MMAP |
+						 SNDRV_PCM_INFO_INTERLEAVED |
+						 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+						 SNDRV_PCM_INFO_MMAP_VALID |
+						 SNDRV_PCM_INFO_PAUSE |
+						 SNDRV_PCM_INFO_SYNC_START),
+		.formats =          SNDRV_PCM_FMTBIT_S16_LE,
+		.rates =            SNDRV_PCM_RATE_KNOT,
+		.rate_min =         44100,
+		.rate_max =         44100,
+		.channels_min =     2,
+		.channels_max =     2,
+		.buffer_bytes_max = 60000,
+		.period_bytes_min = 180 * 4,
+		.period_bytes_max = 8192,
+		.periods_min =      1,
+		.periods_max =      1024
+	},
+  .snd_line6_capture_hw = {
+		.info = (SNDRV_PCM_INFO_MMAP |
+						 SNDRV_PCM_INFO_INTERLEAVED |
+						 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+						 SNDRV_PCM_INFO_MMAP_VALID |
+						 SNDRV_PCM_INFO_SYNC_START),
+		.formats =          SNDRV_PCM_FMTBIT_S16_LE,
+		.rates =            SNDRV_PCM_RATE_KNOT,
+		.rate_min =         44100,
+		.rate_max =         44100,
+		.channels_min =     2,
+		.channels_max =     2,
+		.buffer_bytes_max = 60000,
+		.period_bytes_min = 188 * 4,
+		.period_bytes_max = 8192,
+		.periods_min =      1,
+		.periods_max =      1024
+	},
+	.snd_line6_rates = {
+		.nrats = 1,
+		.rats = &toneport_ratden
+	},
+	.bytes_per_frame = 4
+};
+
+/*
+	For the led on Guitarport.
+	Brightness goes from 0x00 to 0x26. Set a value above this to have led
+	blink.
+	(void cmd_0x02(byte red, byte green)
+*/
+static int led_red = 0x00;
+static int led_green = 0x26;
+
+static void toneport_update_led(struct device *dev)
+{
+	struct usb_interface *interface = to_usb_interface(dev);
+	struct usb_line6_toneport *tp = usb_get_intfdata(interface);
+	struct usb_line6 *line6;
+
+	if (!tp)
+		return;
+
+	line6 = &tp->line6;
+	if (line6)
+		toneport_send_cmd(line6->usbdev, (led_red << 8) | 0x0002,
+				  led_green);
+}
+
+static ssize_t toneport_set_led_red(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t count)
+{
+	char *c;
+	led_red = simple_strtol(buf, &c, 10);
+	toneport_update_led(dev);
+	return count;
+}
+
+static ssize_t toneport_set_led_green(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t count)
+{
+	char *c;
+	led_green = simple_strtol(buf, &c, 10);
+	toneport_update_led(dev);
+	return count;
+}
+
+static DEVICE_ATTR(led_red, S_IWUGO | S_IRUGO, line6_nop_read, toneport_set_led_red);
+static DEVICE_ATTR(led_green, S_IWUGO | S_IRUGO, line6_nop_read, toneport_set_led_green);
+
+
+static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2)
+{
+	int ret;
+
+	ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
+			      USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+			      cmd1, cmd2, NULL, 0, LINE6_TIMEOUT * HZ);
+
+	if (ret < 0) {
+		err("send failed (error %d)\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+/*
+	Toneport destructor.
+*/
+static void toneport_destruct(struct usb_interface *interface)
+{
+	struct usb_line6_toneport *toneport = usb_get_intfdata(interface);
+	struct usb_line6 *line6;
+
+	if (toneport == NULL)
+		return;
+	line6 = &toneport->line6;
+	if (line6 == NULL)
+		return;
+	line6_cleanup_audio(line6);
+}
+
+/*
+	 Init Toneport device.
+*/
+int toneport_init(struct usb_interface *interface,
+		  struct usb_line6_toneport *toneport)
+{
+	int err, ticks;
+	struct usb_line6 *line6 = &toneport->line6;
+	struct usb_device *usbdev;
+
+	if ((interface == NULL) || (toneport == NULL))
+		return -ENODEV;
+
+	/* initialize audio system: */
+	err = line6_init_audio(line6);
+	if (err < 0) {
+		toneport_destruct(interface);
+		return err;
+	}
+
+	/* initialize PCM subsystem: */
+	err = line6_init_pcm(line6, &toneport_pcm_properties);
+	if (err < 0) {
+		toneport_destruct(interface);
+		return err;
+	}
+
+	/* register audio system: */
+	err = line6_register_audio(line6);
+	if (err < 0) {
+		toneport_destruct(interface);
+		return err;
+	}
+
+	usbdev = line6->usbdev;
+	line6_read_serial_number(line6, &toneport->serial_number);
+	line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1);
+
+	/* sync time on device with host: */
+	ticks = (int)get_seconds();
+	line6_write_data(line6, 0x80c6, &ticks, 4);
+
+	/*
+	seems to work without the first two...
+	*/
+	/* toneport_send_cmd(usbdev, 0x0201, 0x0002); */
+	/* toneport_send_cmd(usbdev, 0x0801, 0x0000); */
+	/* only one that works for me; on GP, TP might be different? */
+	toneport_send_cmd(usbdev, 0x0301, 0x0000);
+
+	if (usbdev->descriptor.idProduct != LINE6_DEVID_GUITARPORT) {
+		CHECK_RETURN(device_create_file(&interface->dev, &dev_attr_led_red));
+		CHECK_RETURN(device_create_file(&interface->dev, &dev_attr_led_green));
+		toneport_update_led(&usbdev->dev);
+	}
+
+	return 0;
+}
+
+/*
+	Toneport device disconnected.
+*/
+void toneport_disconnect(struct usb_interface *interface)
+{
+	struct usb_line6_toneport *toneport;
+
+	if (interface == NULL)
+		return;
+	toneport = usb_get_intfdata(interface);
+
+	if (toneport->line6.usbdev->descriptor.idProduct != LINE6_DEVID_GUITARPORT) {
+		device_remove_file(&interface->dev, &dev_attr_led_red);
+		device_remove_file(&interface->dev, &dev_attr_led_green);
+	}
+
+	if (toneport != NULL) {
+		struct snd_line6_pcm *line6pcm = toneport->line6.line6pcm;
+
+		if (line6pcm != NULL) {
+			unlink_wait_clear_audio_out_urbs(line6pcm);
+			unlink_wait_clear_audio_in_urbs(line6pcm);
+		}
+	}
+
+	toneport_destruct(interface);
+}
diff --git a/drivers/staging/line6/toneport.h b/drivers/staging/line6/toneport.h
new file mode 100644
index 0000000..bddc58d
--- /dev/null
+++ b/drivers/staging/line6/toneport.h
@@ -0,0 +1,45 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *	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.
+ *
+ */
+
+#ifndef TONEPORT_H
+#define TONEPORT_H
+
+
+#include "driver.h"
+
+#include <linux/usb.h>
+#include <sound/core.h>
+
+
+struct usb_line6_toneport {
+	/**
+		 Generic Line6 USB data.
+	*/
+	struct usb_line6 line6;
+
+	/**
+		 Serial number of device.
+	*/
+	int serial_number;
+
+	/**
+		 Firmware version (x 100).
+	*/
+	int firmware_version;
+};
+
+
+extern void toneport_disconnect(struct usb_interface *interface);
+extern int toneport_init(struct usb_interface *interface,
+			 struct usb_line6_toneport *toneport);
+
+
+#endif
diff --git a/drivers/staging/line6/usbdefs.h b/drivers/staging/line6/usbdefs.h
new file mode 100644
index 0000000..c38f31f
--- /dev/null
+++ b/drivers/staging/line6/usbdefs.h
@@ -0,0 +1,74 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2005-2008 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *	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.
+ *
+ */
+
+#ifndef USBDEFS_H
+#define USBDEFS_H
+
+
+#define LINE6_VENDOR_ID  0x0e41
+
+#define USB_INTERVALS_PER_SECOND 1000
+
+/*
+	Device ids.
+*/
+#define LINE6_DEVID_BASSPODXT     0x4250
+#define LINE6_DEVID_BASSPODXTLIVE 0x4642
+#define LINE6_DEVID_BASSPODXTPRO  0x4252
+#define LINE6_DEVID_GUITARPORT    0x4750
+#define LINE6_DEVID_POCKETPOD     0x5051
+#define LINE6_DEVID_PODX3         0x414a
+#define LINE6_DEVID_PODX3LIVE     0x414b
+#define LINE6_DEVID_PODXT         0x5044
+#define LINE6_DEVID_PODXTLIVE     0x4650
+#define LINE6_DEVID_PODXTPRO      0x5050
+#define LINE6_DEVID_TONEPORT_GX   0x4147
+#define LINE6_DEVID_TONEPORT_UX1  0x4141
+#define LINE6_DEVID_TONEPORT_UX2  0x4142
+#define LINE6_DEVID_VARIAX        0x534d
+
+#define LINE6_BIT_BASSPODXT       (1 << 0)
+#define LINE6_BIT_BASSPODXTLIVE   (1 << 1)
+#define LINE6_BIT_BASSPODXTPRO    (1 << 2)
+#define LINE6_BIT_GUITARPORT      (1 << 3)
+#define LINE6_BIT_POCKETPOD       (1 << 4)
+#define LINE6_BIT_PODX3           (1 << 5)
+#define LINE6_BIT_PODX3LIVE       (1 << 6)
+#define LINE6_BIT_PODXT           (1 << 7)
+#define LINE6_BIT_PODXTLIVE       (1 << 8)
+#define LINE6_BIT_PODXTPRO        (1 << 9)
+#define LINE6_BIT_TONEPORT_GX     (1 << 10)
+#define LINE6_BIT_TONEPORT_UX1    (1 << 11)
+#define LINE6_BIT_TONEPORT_UX2    (1 << 12)
+#define LINE6_BIT_VARIAX          (1 << 13)
+
+#define LINE6_BITS_PRO		(LINE6_BIT_BASSPODXTPRO | \
+				 LINE6_BIT_PODXTPRO)
+#define LINE6_BITS_LIVE		(LINE6_BIT_BASSPODXTLIVE | \
+				 LINE6_BIT_PODXTLIVE | \
+				 LINE6_BIT_PODX3LIVE)
+#define LINE6_BITS_PODXTALL	(LINE6_BIT_PODXT | \
+				 LINE6_BIT_PODXTLIVE | \
+				 LINE6_BIT_PODXTPRO)
+#define LINE6_BITS_BASSPODXTALL	(LINE6_BIT_BASSPODXT | \
+				 LINE6_BIT_BASSPODXTLIVE | \
+				 LINE6_BIT_BASSPODXTPRO)
+
+/* device supports settings parameter via USB */
+#define LINE6_BIT_CONTROL	(1 << 0)
+/* device supports PCM input/output via USB */
+#define LINE6_BIT_PCM		(1 << 1)
+#define LINE6_BIT_CONTROL_PCM	(LINE6_BIT_CONTROL | LINE6_BIT_PCM)
+
+#define LINE6_FALLBACK_INTERVAL		10
+#define LINE6_FALLBACK_MAXPACKETSIZE	16
+
+#endif
diff --git a/drivers/staging/line6/variax.c b/drivers/staging/line6/variax.c
new file mode 100644
index 0000000..f9d9698
--- /dev/null
+++ b/drivers/staging/line6/variax.c
@@ -0,0 +1,546 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *	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.
+ *
+ */
+
+#include "driver.h"
+
+#include "audio.h"
+#include "control.h"
+#include "variax.h"
+
+
+#define VARIAX_SYSEX_CODE 7
+#define VARIAX_SYSEX_PARAM 0x3b
+#define VARIAX_SYSEX_ACTIVATE 0x2a
+#define VARIAX_MODEL_HEADER_LENGTH 7
+#define VARIAX_MODEL_MESSAGE_LENGTH 199
+#define VARIAX_OFFSET_ACTIVATE 7
+
+
+static const char variax_activate[] = {
+	0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x2a, 0x01,
+	0xf7
+};
+static const char variax_request_bank[] = {
+	0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6d, 0xf7
+};
+static const char variax_request_model1[] = {
+	0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x3c, 0x00,
+	0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x05, 0x03,
+	0x00, 0x00, 0x00, 0xf7
+};
+static const char variax_request_model2[] = {
+	0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x3c, 0x00,
+	0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x03,
+	0x00, 0x00, 0x00, 0xf7
+};
+
+
+/*
+	Decode data transmitted by workbench.
+*/
+static void variax_decode(const unsigned char *raw_data, unsigned char *data,
+			  int raw_size)
+{
+	for (; raw_size > 0; raw_size -= 6) {
+		data[2] = raw_data[0] | (raw_data[1] << 4);
+		data[1] = raw_data[2] | (raw_data[3] << 4);
+		data[0] = raw_data[4] | (raw_data[5] << 4);
+		raw_data += 6;
+		data += 3;
+	}
+}
+
+static void variax_activate_timeout(unsigned long arg)
+{
+	struct usb_line6_variax *variax = (struct usb_line6_variax *)arg;
+	variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = 1;
+	line6_send_raw_message_async(&variax->line6, variax->buffer_activate,
+				     sizeof(variax_activate));
+}
+
+/*
+	Send an asynchronous activation request after a given interval.
+*/
+static void variax_activate_delayed(struct usb_line6_variax *variax,
+				    int seconds)
+{
+	variax->activate_timer.expires = jiffies + seconds * HZ;
+	variax->activate_timer.function = variax_activate_timeout;
+	variax->activate_timer.data = (unsigned long)variax;
+	add_timer(&variax->activate_timer);
+}
+
+static void variax_startup_timeout(unsigned long arg)
+{
+	struct usb_line6_variax *variax = (struct usb_line6_variax *)arg;
+
+	if (variax->dumpreq.ok)
+		return;
+
+	line6_dump_request_async(&variax->dumpreq, &variax->line6, 0);
+	line6_startup_delayed(&variax->dumpreq, 1, variax_startup_timeout,
+			      variax);
+}
+
+/*
+	Process a completely received message.
+*/
+void variax_process_message(struct usb_line6_variax *variax)
+{
+	const unsigned char *buf = variax->line6.buffer_message;
+
+	switch (buf[0]) {
+	case LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST:
+		switch (buf[1]) {
+		case VARIAXMIDI_volume:
+			variax->volume = buf[2];
+			break;
+
+		case VARIAXMIDI_tone:
+			variax->tone = buf[2];
+		}
+
+		break;
+
+	case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_DEVICE:
+	case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST:
+		variax->model = buf[1];
+		line6_dump_request_async(&variax->dumpreq, &variax->line6, 0);
+		break;
+
+	case LINE6_RESET:
+		dev_info(variax->line6.ifcdev, "VARIAX reset\n");
+		variax_activate_delayed(variax, VARIAX_ACTIVATE_DELAY);
+		break;
+
+	case LINE6_SYSEX_BEGIN:
+		if (memcmp(buf + 1, variax_request_model1 + 1,
+			   VARIAX_MODEL_HEADER_LENGTH - 1) == 0) {
+			if (variax->line6.message_length ==
+			    VARIAX_MODEL_MESSAGE_LENGTH) {
+				switch (variax->dumpreq.in_progress) {
+				case VARIAX_DUMP_PASS1:
+					variax_decode(buf + VARIAX_MODEL_HEADER_LENGTH, (unsigned char *)&variax->model_data,
+												(sizeof(variax->model_data.name) + sizeof(variax->model_data.control) / 2) * 2);
+					line6_dump_request_async(&variax->dumpreq, &variax->line6, 1);
+					line6_dump_started(&variax->dumpreq, VARIAX_DUMP_PASS2);
+					break;
+
+				case VARIAX_DUMP_PASS2:
+					/* model name is transmitted twice, so skip it here: */
+					variax_decode(buf + VARIAX_MODEL_HEADER_LENGTH,
+						      (unsigned char *)&variax->model_data.control + sizeof(variax->model_data.control) / 2,
+						      sizeof(variax->model_data.control) / 2 * 2);
+					variax->dumpreq.ok = 1;
+					line6_dump_request_async(&variax->dumpreq, &variax->line6, 2);
+					line6_dump_started(&variax->dumpreq, VARIAX_DUMP_PASS3);
+				}
+			} else {
+				DEBUG_MESSAGES(dev_err(variax->line6.ifcdev, "illegal length %d of model data\n", variax->line6.message_length));
+				line6_dump_finished(&variax->dumpreq);
+			}
+		} else if (memcmp(buf + 1, variax_request_bank + 1,
+				sizeof(variax_request_bank) - 2) == 0) {
+			memcpy(variax->bank,
+			       buf + sizeof(variax_request_bank) - 1,
+			       sizeof(variax->bank));
+			variax->dumpreq.ok = 1;
+			line6_dump_finished(&variax->dumpreq);
+		}
+
+		break;
+
+	case LINE6_SYSEX_END:
+		break;
+
+	default:
+		DEBUG_MESSAGES(dev_err(variax->line6.ifcdev, "Variax: unknown message %02X\n", buf[0]));
+	}
+}
+
+/*
+	"read" request on "volume" special file.
+*/
+static ssize_t variax_get_volume(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+	return sprintf(buf, "%d\n", variax->volume);
+}
+
+/*
+	"write" request on "volume" special file.
+*/
+static ssize_t variax_set_volume(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf, size_t count)
+{
+	struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+	int value = simple_strtoul(buf, NULL, 10);
+
+	if (line6_transmit_parameter(&variax->line6, VARIAXMIDI_volume,
+				     value) == 0)
+		variax->volume = value;
+
+	return count;
+}
+
+/*
+	"read" request on "model" special file.
+*/
+static ssize_t variax_get_model(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+	return sprintf(buf, "%d\n", variax->model);
+}
+
+/*
+	"write" request on "model" special file.
+*/
+static ssize_t variax_set_model(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+	int value = simple_strtoul(buf, NULL, 10);
+
+	if (line6_send_program(&variax->line6, value) == 0)
+		variax->model = value;
+
+	return count;
+}
+
+/*
+	"read" request on "active" special file.
+*/
+static ssize_t variax_get_active(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+	return sprintf(buf, "%d\n", variax->buffer_activate[VARIAX_OFFSET_ACTIVATE]);
+}
+
+/*
+	"write" request on "active" special file.
+*/
+static ssize_t variax_set_active(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf, size_t count)
+{
+	struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+	int value = simple_strtoul(buf, NULL, 10) ? 1 : 0;
+	variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = value;
+	line6_send_raw_message_async(&variax->line6, variax->buffer_activate,
+				     sizeof(variax_activate));
+	return count;
+}
+
+/*
+	"read" request on "tone" special file.
+*/
+static ssize_t variax_get_tone(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+	return sprintf(buf, "%d\n", variax->tone);
+}
+
+/*
+	"write" request on "tone" special file.
+*/
+static ssize_t variax_set_tone(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t count)
+{
+	struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+	int value = simple_strtoul(buf, NULL, 10);
+
+	if (line6_transmit_parameter(&variax->line6, VARIAXMIDI_tone,
+				     value) == 0)
+		variax->tone = value;
+
+	return count;
+}
+
+static ssize_t get_string(char *buf, const char *data, int length)
+{
+	int i;
+	memcpy(buf, data, length);
+
+	for (i = length; i--;) {
+		char c = buf[i];
+
+		if ((c != 0) && (c != ' '))
+			break;
+	}
+
+	buf[i + 1] = '\n';
+	return i + 2;
+}
+
+/*
+	"read" request on "name" special file.
+*/
+static ssize_t variax_get_name(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+	line6_wait_dump(&variax->dumpreq, 0);
+	return get_string(buf, variax->model_data.name,
+			  sizeof(variax->model_data.name));
+}
+
+/*
+	"read" request on "bank" special file.
+*/
+static ssize_t variax_get_bank(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+	line6_wait_dump(&variax->dumpreq, 0);
+	return get_string(buf, variax->bank, sizeof(variax->bank));
+}
+
+/*
+	"read" request on "dump" special file.
+*/
+static ssize_t variax_get_dump(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+	int retval;
+	retval = line6_wait_dump(&variax->dumpreq, 0);
+	if (retval < 0)
+		return retval;
+	memcpy(buf, &variax->model_data.control,
+	       sizeof(variax->model_data.control));
+	return sizeof(variax->model_data.control);
+}
+
+#if CREATE_RAW_FILE
+
+/*
+	"write" request on "raw" special file.
+*/
+static ssize_t variax_set_raw2(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t count)
+{
+	struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+	int size;
+	int i;
+	char *sysex;
+
+	count -= count % 3;
+	size = count * 2;
+	sysex = variax_alloc_sysex_buffer(variax, VARIAX_SYSEX_PARAM, size);
+
+	if (!sysex)
+		return 0;
+
+	for (i = 0; i < count; i += 3) {
+		const unsigned char *p1 = buf + i;
+		char *p2 = sysex + SYSEX_DATA_OFS + i * 2;
+		p2[0] = p1[2] & 0x0f;
+		p2[1] = p1[2] >> 4;
+		p2[2] = p1[1] & 0x0f;
+		p2[3] = p1[1] >> 4;
+		p2[4] = p1[0] & 0x0f;
+		p2[5] = p1[0] >> 4;
+	}
+
+	line6_send_sysex_message(&variax->line6, sysex, size);
+	kfree(sysex);
+	return count;
+}
+
+#endif
+
+/* Variax workbench special files: */
+static DEVICE_ATTR(model, S_IWUGO | S_IRUGO, variax_get_model, variax_set_model);
+static DEVICE_ATTR(volume, S_IWUGO | S_IRUGO, variax_get_volume, variax_set_volume);
+static DEVICE_ATTR(tone, S_IWUGO | S_IRUGO, variax_get_tone, variax_set_tone);
+static DEVICE_ATTR(name, S_IRUGO, variax_get_name, line6_nop_write);
+static DEVICE_ATTR(bank, S_IRUGO, variax_get_bank, line6_nop_write);
+static DEVICE_ATTR(dump, S_IRUGO, variax_get_dump, line6_nop_write);
+static DEVICE_ATTR(active, S_IWUGO | S_IRUGO, variax_get_active, variax_set_active);
+
+#if CREATE_RAW_FILE
+static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw);
+static DEVICE_ATTR(raw2, S_IWUGO, line6_nop_read, variax_set_raw2);
+#endif
+
+
+/*
+	Variax destructor.
+*/
+static void variax_destruct(struct usb_interface *interface)
+{
+	struct usb_line6_variax *variax = usb_get_intfdata(interface);
+	struct usb_line6 *line6;
+
+	if (variax == NULL)
+		return;
+	line6 = &variax->line6;
+	if (line6 == NULL)
+		return;
+	line6_cleanup_audio(line6);
+
+	/* free dump request data: */
+	line6_dumpreq_destructbuf(&variax->dumpreq, 2);
+	line6_dumpreq_destructbuf(&variax->dumpreq, 1);
+	line6_dumpreq_destruct(&variax->dumpreq);
+
+	kfree(variax->buffer_activate);
+	del_timer_sync(&variax->activate_timer);
+}
+
+/*
+	Create sysfs entries.
+*/
+static int variax_create_files2(struct device *dev)
+{
+	int err;
+	CHECK_RETURN(device_create_file(dev, &dev_attr_model));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_volume));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_tone));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_name));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_bank));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_dump));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_active));
+#if CREATE_RAW_FILE
+	CHECK_RETURN(device_create_file(dev, &dev_attr_raw));
+	CHECK_RETURN(device_create_file(dev, &dev_attr_raw2));
+#endif
+	return 0;
+}
+
+/*
+	 Init workbench device.
+*/
+int variax_init(struct usb_interface *interface,
+		struct usb_line6_variax *variax)
+{
+	int err;
+
+	if ((interface == NULL) || (variax == NULL))
+		return -ENODEV;
+
+	/* initialize USB buffers: */
+	err = line6_dumpreq_init(&variax->dumpreq, variax_request_model1,
+				 sizeof(variax_request_model1));
+
+	if (err < 0) {
+		dev_err(&interface->dev, "Out of memory\n");
+		variax_destruct(interface);
+		return err;
+	}
+
+	err = line6_dumpreq_initbuf(&variax->dumpreq, variax_request_model2,
+				    sizeof(variax_request_model2), 1);
+
+	if (err < 0) {
+		dev_err(&interface->dev, "Out of memory\n");
+		variax_destruct(interface);
+		return err;
+	}
+
+	err = line6_dumpreq_initbuf(&variax->dumpreq, variax_request_bank,
+				    sizeof(variax_request_bank), 2);
+
+	if (err < 0) {
+		dev_err(&interface->dev, "Out of memory\n");
+		variax_destruct(interface);
+		return err;
+	}
+
+	variax->buffer_activate = kmalloc(sizeof(variax_activate), GFP_KERNEL);
+
+	if (variax->buffer_activate == NULL) {
+		dev_err(&interface->dev, "Out of memory\n");
+		variax_destruct(interface);
+		return -ENOMEM;
+	}
+
+	memcpy(variax->buffer_activate, variax_activate,
+	       sizeof(variax_activate));
+	init_timer(&variax->activate_timer);
+
+	/* create sysfs entries: */
+	err = variax_create_files(0, 0, &interface->dev);
+	if (err < 0) {
+		variax_destruct(interface);
+		return err;
+	}
+
+	err = variax_create_files2(&interface->dev);
+	if (err < 0) {
+		variax_destruct(interface);
+		return err;
+	}
+
+	/* initialize audio system: */
+	err = line6_init_audio(&variax->line6);
+	if (err < 0) {
+		variax_destruct(interface);
+		return err;
+	}
+
+	/* initialize MIDI subsystem: */
+	err = line6_init_midi(&variax->line6);
+	if (err < 0) {
+		variax_destruct(interface);
+		return err;
+	}
+
+	/* register audio system: */
+	err = line6_register_audio(&variax->line6);
+	if (err < 0) {
+		variax_destruct(interface);
+		return err;
+	}
+
+	variax_activate_delayed(variax, VARIAX_ACTIVATE_DELAY);
+	line6_startup_delayed(&variax->dumpreq, VARIAX_STARTUP_DELAY,
+			      variax_startup_timeout, variax);
+	return 0;
+}
+
+/*
+	Workbench device disconnected.
+*/
+void variax_disconnect(struct usb_interface *interface)
+{
+	struct device *dev;
+
+	if (interface == NULL)
+		return;
+	dev = &interface->dev;
+
+	if (dev != NULL) {
+		/* remove sysfs entries: */
+		variax_remove_files(0, 0, dev);
+		device_remove_file(dev, &dev_attr_model);
+		device_remove_file(dev, &dev_attr_volume);
+		device_remove_file(dev, &dev_attr_tone);
+		device_remove_file(dev, &dev_attr_name);
+		device_remove_file(dev, &dev_attr_bank);
+		device_remove_file(dev, &dev_attr_dump);
+		device_remove_file(dev, &dev_attr_active);
+#if CREATE_RAW_FILE
+		device_remove_file(dev, &dev_attr_raw);
+		device_remove_file(dev, &dev_attr_raw2);
+#endif
+	}
+
+	variax_destruct(interface);
+}
diff --git a/drivers/staging/line6/variax.h b/drivers/staging/line6/variax.h
new file mode 100644
index 0000000..ee330ba
--- /dev/null
+++ b/drivers/staging/line6/variax.h
@@ -0,0 +1,108 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ *	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.
+ *
+ */
+
+#ifndef VARIAX_H
+#define VARIAX_H
+
+
+#include "driver.h"
+
+#include <linux/spinlock.h>
+#include <linux/usb.h>
+#include <linux/wait.h>
+
+#include <sound/core.h>
+
+#include "dumprequest.h"
+
+
+#define VARIAX_ACTIVATE_DELAY 10
+#define VARIAX_STARTUP_DELAY 3
+
+
+enum {
+	VARIAX_DUMP_PASS1 = LINE6_DUMP_CURRENT,
+	VARIAX_DUMP_PASS2,
+	VARIAX_DUMP_PASS3
+};
+
+
+/**
+	 Binary Variax model dump
+*/
+struct variax_model {
+	/**
+		 Header information (including program name).
+	*/
+	unsigned char name[18];
+
+	/**
+		 Model parameters.
+	*/
+	unsigned char control[78 * 2];
+};
+
+struct usb_line6_variax {
+	/**
+		 Generic Line6 USB data.
+	*/
+	struct usb_line6 line6;
+
+	/**
+		 Dump request structure.
+		 Append two extra buffers for 3-pass data query.
+	*/
+	struct line6_dump_request dumpreq; struct line6_dump_reqbuf extrabuf[2];
+
+	/**
+		 Buffer for activation code.
+	*/
+	unsigned char *buffer_activate;
+
+	/**
+		 Model number.
+	*/
+	int model;
+
+	/**
+		 Current model settings.
+	*/
+	struct variax_model model_data;
+
+	/**
+		 Name of current model bank.
+	*/
+	unsigned char bank[18];
+
+	/**
+		 Position of volume dial.
+	*/
+	int volume;
+
+	/**
+		 Position of tone control dial.
+	*/
+	int tone;
+
+	/**
+		 Timer for delayed activation request.
+	*/
+	struct timer_list activate_timer;
+};
+
+
+extern void variax_disconnect(struct usb_interface *interface);
+extern int variax_init(struct usb_interface *interface,
+		       struct usb_line6_variax *variax);
+extern void variax_process_message(struct usb_line6_variax *variax);
+
+
+#endif
diff --git a/drivers/staging/me4000/me4000.c b/drivers/staging/me4000/me4000.c
index e1c4a80..01017b7 100644
--- a/drivers/staging/me4000/me4000.c
+++ b/drivers/staging/me4000/me4000.c
@@ -36,8 +36,8 @@
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
 #include <asm/pgtable.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
 #include <asm/system.h>
 
 /* Include-File for the Meilhaus ME-4000 I/O board */
@@ -246,17 +246,17 @@
   Inline functions
   ---------------------------------------------------------------------------*/
 
-static int inline me4000_buf_count(struct me4000_circ_buf buf, int size)
+static inline int me4000_buf_count(struct me4000_circ_buf buf, int size)
 {
-	return ((buf.head - buf.tail) & (size - 1));
+	return (buf.head - buf.tail) & (size - 1);
 }
 
-static int inline me4000_buf_space(struct me4000_circ_buf buf, int size)
+static inline int me4000_buf_space(struct me4000_circ_buf buf, int size)
 {
-	return ((buf.tail - (buf.head + 1)) & (size - 1));
+	return (buf.tail - (buf.head + 1)) & (size - 1);
 }
 
-static int inline me4000_values_to_end(struct me4000_circ_buf buf, int size)
+static inline int me4000_values_to_end(struct me4000_circ_buf buf, int size)
 {
 	int end;
 	int n;
@@ -265,7 +265,7 @@
 	return (n < end) ? n : end;
 }
 
-static int inline me4000_space_to_end(struct me4000_circ_buf buf, int size)
+static inline int me4000_space_to_end(struct me4000_circ_buf buf, int size)
 {
 	int end;
 	int n;
@@ -275,19 +275,19 @@
 	return (n <= end) ? n : (end + 1);
 }
 
-static void inline me4000_outb(unsigned char value, unsigned long port)
+static inline void me4000_outb(unsigned char value, unsigned long port)
 {
 	PORT_PDEBUG("--> 0x%02X port 0x%04lX\n", value, port);
 	outb(value, port);
 }
 
-static void inline me4000_outl(unsigned long value, unsigned long port)
+static inline void me4000_outl(unsigned long value, unsigned long port)
 {
 	PORT_PDEBUG("--> 0x%08lX port 0x%04lX\n", value, port);
 	outl(value, port);
 }
 
-static unsigned long inline me4000_inl(unsigned long port)
+static inline unsigned long me4000_inl(unsigned long port)
 {
 	unsigned long value;
 	value = inl(port);
@@ -295,7 +295,7 @@
 	return value;
 }
 
-static unsigned char inline me4000_inb(unsigned long port)
+static inline unsigned char me4000_inb(unsigned long port)
 {
 	unsigned char value;
 	value = inb(port);
@@ -309,7 +309,7 @@
 	.probe = me4000_probe
 };
 
-static struct file_operations me4000_ao_fops_sing = {
+static const struct file_operations me4000_ao_fops_sing = {
       .owner = THIS_MODULE,
       .write = me4000_ao_write_sing,
       .ioctl = me4000_ao_ioctl_sing,
@@ -317,7 +317,7 @@
       .release = me4000_release,
 };
 
-static struct file_operations me4000_ao_fops_wrap = {
+static const struct file_operations me4000_ao_fops_wrap = {
       .owner = THIS_MODULE,
       .write = me4000_ao_write_wrap,
       .ioctl = me4000_ao_ioctl_wrap,
@@ -325,7 +325,7 @@
       .release = me4000_release,
 };
 
-static struct file_operations me4000_ao_fops_cont = {
+static const struct file_operations me4000_ao_fops_cont = {
       .owner = THIS_MODULE,
       .write = me4000_ao_write_cont,
       .poll = me4000_ao_poll_cont,
@@ -335,14 +335,14 @@
       .fsync = me4000_ao_fsync_cont,
 };
 
-static struct file_operations me4000_ai_fops_sing = {
+static const struct file_operations me4000_ai_fops_sing = {
       .owner = THIS_MODULE,
       .ioctl = me4000_ai_ioctl_sing,
       .open = me4000_open,
       .release = me4000_release,
 };
 
-static struct file_operations me4000_ai_fops_cont_sw = {
+static const struct file_operations me4000_ai_fops_cont_sw = {
       .owner = THIS_MODULE,
       .read = me4000_ai_read,
       .poll = me4000_ai_poll,
@@ -352,7 +352,7 @@
       .fasync = me4000_ai_fasync,
 };
 
-static struct file_operations me4000_ai_fops_cont_et = {
+static const struct file_operations me4000_ai_fops_cont_et = {
       .owner = THIS_MODULE,
       .read = me4000_ai_read,
       .poll = me4000_ai_poll,
@@ -361,7 +361,7 @@
       .release = me4000_release,
 };
 
-static struct file_operations me4000_ai_fops_cont_et_value = {
+static const struct file_operations me4000_ai_fops_cont_et_value = {
       .owner = THIS_MODULE,
       .read = me4000_ai_read,
       .poll = me4000_ai_poll,
@@ -370,7 +370,7 @@
       .release = me4000_release,
 };
 
-static struct file_operations me4000_ai_fops_cont_et_chanlist = {
+static const struct file_operations me4000_ai_fops_cont_et_chanlist = {
       .owner = THIS_MODULE,
       .read = me4000_ai_read,
       .poll = me4000_ai_poll,
@@ -379,21 +379,21 @@
       .release = me4000_release,
 };
 
-static struct file_operations me4000_dio_fops = {
+static const struct file_operations me4000_dio_fops = {
       .owner = THIS_MODULE,
       .ioctl = me4000_dio_ioctl,
       .open = me4000_open,
       .release = me4000_release,
 };
 
-static struct file_operations me4000_cnt_fops = {
+static const struct file_operations me4000_cnt_fops = {
       .owner = THIS_MODULE,
       .ioctl = me4000_cnt_ioctl,
       .open = me4000_open,
       .release = me4000_release,
 };
 
-static struct file_operations me4000_ext_int_fops = {
+static const struct file_operations me4000_ext_int_fops = {
       .owner = THIS_MODULE,
       .ioctl = me4000_ext_int_ioctl,
       .open = me4000_open,
@@ -401,18 +401,26 @@
       .fasync = me4000_ext_int_fasync,
 };
 
-static struct file_operations *me4000_ao_fops_array[] = {
-	&me4000_ao_fops_sing,	// single operations
-	&me4000_ao_fops_wrap,	// wraparound operations
-	&me4000_ao_fops_cont,	// continous operations
+static const struct file_operations *me4000_ao_fops_array[] = {
+	/* single operations */
+	&me4000_ao_fops_sing,
+	/* wraparound operations */
+	&me4000_ao_fops_wrap,
+	/* continuous operations */
+	&me4000_ao_fops_cont,
 };
 
-static struct file_operations *me4000_ai_fops_array[] = {
-	&me4000_ai_fops_sing,	// single operations
-	&me4000_ai_fops_cont_sw,	// continuous operations with software start
-	&me4000_ai_fops_cont_et,	// continous operations with external trigger
-	&me4000_ai_fops_cont_et_value,	// sample values by external trigger
-	&me4000_ai_fops_cont_et_chanlist,	// work through one channel list by external trigger
+static const struct file_operations *me4000_ai_fops_array[] = {
+	/* single operations */
+	&me4000_ai_fops_sing,
+	/* continuous operations with software start */
+	&me4000_ai_fops_cont_sw,
+	/* continuous operations with external trigger */
+	&me4000_ai_fops_cont_et,
+	/* sample values by external trigger */
+	&me4000_ai_fops_cont_et_value,
+	/* work through one channel list by external trigger */
+	&me4000_ai_fops_cont_et_chanlist,
 };
 
 static int __init me4000_init_module(void)
@@ -546,15 +554,13 @@
 				&board_info->ao_context_list, list) {
 			me4000_ao_reset(ao_context);
 			free_irq(ao_context->irq, ao_context);
-			if (ao_context->circ_buf.buf)
-				kfree(ao_context->circ_buf.buf);
+			kfree(ao_context->circ_buf.buf);
 			list_del(&ao_context->list);
 			kfree(ao_context);
 		}
 
 		/* Clear analog input context */
-		if (board_info->ai_context->circ_buf.buf)
-			kfree(board_info->ai_context->circ_buf.buf);
+		kfree(board_info->ai_context->circ_buf.buf);
 		kfree(board_info->ai_context);
 
 		/* Clear digital I/O context */
@@ -1263,9 +1269,8 @@
 		    info->me4000_regbase + ME4000_AO_DEMUX_ADJUST_REG);
 
 	/* Set digital I/O direction for port 0 to output on isolated versions */
-	if (!(me4000_inl(info->me4000_regbase + ME4000_DIO_DIR_REG) & 0x1)) {
+	if (!(me4000_inl(info->me4000_regbase + ME4000_DIO_DIR_REG) & 0x1))
 		me4000_outl(0x1, info->me4000_regbase + ME4000_DIO_CTRL_REG);
-	}
 
 	return 0;
 }
@@ -1463,7 +1468,7 @@
 		/* Set file operations pointer to single functions */
 		file_p->f_op = &me4000_dio_fops;
 
-		//me4000_dio_reset(dio_context);
+		/* me4000_dio_reset(dio_context); */
 	}
 	/* Counters */
 	else if (MAJOR(inode_p->i_rdev) == me4000_cnt_major_driver_no) {
@@ -2058,7 +2063,7 @@
 						ME4000_AO_BUFFER_COUNT);
 
 			if (c == 0)
-				return (2 * ret);
+				return 2 * ret;
 
 			/* Only able to write size of free buffer or size of count */
 			if (count < c)
@@ -2104,9 +2109,8 @@
 		}
 	}
 
-	if (filep->f_flags & O_NONBLOCK) {
+	if (filep->f_flags & O_NONBLOCK)
 		return (ret == 0) ? -EAGAIN : 2 * ret;
-	}
 
 	return 2 * ret;
 }
@@ -2201,7 +2205,7 @@
 	case ME4000_AO_SIMULTANEOUS_UPDATE:
 		return
 		    me4000_ao_simultaneous_update(
-		    		(struct me4000_ao_channel_list *)arg,
+				(struct me4000_ao_channel_list *)arg,
 				ao_context);
 	case ME4000_AO_EX_TRIG_TIMEOUT:
 		return me4000_ao_ex_trig_timeout((unsigned long *)arg,
@@ -2361,7 +2365,9 @@
 					       "ME4000:me4000_ao_start():Wait on start of state machine interrupted\n");
 					return -EINTR;
 				}
-				if (((jiffies - ref) > (timeout * HZ / USER_HZ))) {	// 2.6 has diffrent definitions for HZ in user and kernel space
+				/* kernel 2.6 has different definitions for HZ
+				 * in user and kernel space */
+				if ((jiffies - ref) > (timeout * HZ / USER_HZ)) {
 					printk(KERN_ERR
 					       "ME4000:me4000_ao_start():Timeout reached\n");
 					return -EIO;
@@ -2402,8 +2408,8 @@
 	}
 
 	/* Clear the stop bit */
-	//tmp &= ~ME4000_AO_CTRL_BIT_STOP;
-	//me4000_outl(tmp, ao_context->ctrl_reg);
+	/* tmp &= ~ME4000_AO_CTRL_BIT_STOP; */
+	/* me4000_outl(tmp, ao_context->ctrl_reg); */
 
 	return 0;
 }
@@ -2434,8 +2440,8 @@
 	}
 
 	/* Clear the stop bits */
-	//tmp &= ~(ME4000_AO_CTRL_BIT_STOP | ME4000_AO_CTRL_BIT_IMMEDIATE_STOP);
-	//me4000_outl(tmp, ao_context->ctrl_reg);
+	/* tmp &= ~(ME4000_AO_CTRL_BIT_STOP | ME4000_AO_CTRL_BIT_IMMEDIATE_STOP); */
+	/* me4000_outl(tmp, ao_context->ctrl_reg); */
 
 	return 0;
 }
@@ -2598,8 +2604,10 @@
 
 	spin_lock(&ao_context->board_info->preload_lock);
 	tmp = me4000_inl(ao_context->preload_reg);
-	tmp &= ~(0x1 << ao_context->index);	// Disable preload bit
-	tmp &= ~(0x1 << (ao_context->index + 16));	// Disable hw simultaneous bit
+	/* Disable preload bit */
+	tmp &= ~(0x1 << ao_context->index);
+	/* Disable hw simultaneous bit */
+	tmp &= ~(0x1 << (ao_context->index + 16));
 	me4000_outl(tmp, ao_context->preload_reg);
 	spin_unlock(&ao_context->board_info->preload_lock);
 
@@ -2614,8 +2622,10 @@
 
 	spin_lock(&ao_context->board_info->preload_lock);
 	tmp = me4000_inl(ao_context->preload_reg);
-	tmp |= (0x1 << ao_context->index);	// Enable preload bit
-	tmp |= (0x1 << (ao_context->index + 16));	// Enable hw simultaneous bit
+	/* Enable preload bit */
+	tmp |= (0x1 << ao_context->index);
+	/* Enable hw simulatenous bit */
+	tmp |= (0x1 << (ao_context->index + 16));
 	me4000_outl(tmp, ao_context->preload_reg);
 	spin_unlock(&ao_context->board_info->preload_lock);
 
@@ -2630,8 +2640,10 @@
 
 	spin_lock(&ao_context->board_info->preload_lock);
 	tmp = me4000_inl(ao_context->preload_reg);
-	tmp |= (0x1 << ao_context->index);	// Enable preload bit
-	tmp &= ~(0x1 << (ao_context->index + 16));	// Disable hw simultaneous bit
+	/* Enable preload bit */
+	tmp |= (0x1 << ao_context->index);
+	/* Enable hw simulatenous bit */
+	tmp &= ~(0x1 << (ao_context->index + 16));
 	me4000_outl(tmp, ao_context->preload_reg);
 	spin_unlock(&ao_context->board_info->preload_lock);
 
@@ -2669,11 +2681,11 @@
 			    (tmp &
 			     (0x1 <<
 			      (((struct me4000_ao_context *)entry)->index
-			      					      + 16)))) {
+								      + 16)))) {
 				tmp &=
 				    ~(0x1 <<
 				      (((struct me4000_ao_context *)entry)->
-				      					index));
+									index));
 			}
 		}
 	}
@@ -2732,8 +2744,10 @@
 			       "ME4000:me4000_ao_simultaneous_update():Invalid board number specified\n");
 			return -EFAULT;
 		}
-		tmp &= ~(0x1 << channels.list[i]);	// Clear the preload bit
-		tmp &= ~(0x1 << (channels.list[i] + 16));	// Clear the hw simultaneous bit
+		/* Clear the preload bit */
+		tmp &= ~(0x1 << channels.list[i]);
+		/* Clear the hw simultaneous bit */
+		tmp &= ~(0x1 << (channels.list[i] + 16));
 	}
 	me4000_outl(tmp, ao_context->preload_reg);
 	spin_unlock(&ao_context->board_info->preload_lock);
@@ -2759,8 +2773,10 @@
 
 	spin_lock(&ao_context->board_info->preload_lock);
 	tmp = me4000_inl(ao_context->preload_reg);
-	tmp &= ~(0x1 << ao_context->index);	// Disable synchronous sw bit
-	tmp |= 0x1 << (ao_context->index + 16);	// Enable synchronous hw bit
+	/* Disable synchronous sw bit */
+	tmp &= ~(0x1 << ao_context->index);
+	/* Enable synchronous hw bit */
+	tmp |= 0x1 << (ao_context->index + 16);
 	me4000_outl(tmp, ao_context->preload_reg);
 	spin_unlock(&ao_context->board_info->preload_lock);
 
@@ -2794,8 +2810,10 @@
 
 	spin_lock(&ao_context->board_info->preload_lock);
 	tmp = me4000_inl(ao_context->preload_reg);
-	tmp |= 0x1 << ao_context->index;	// Enable synchronous sw bit
-	tmp &= ~(0x1 << (ao_context->index + 16));	// Disable synchronous hw bit
+	/* Enable synchronous sw bit */
+	tmp |= 0x1 << ao_context->index;
+	/* Disable synchronous hw bit */
+	tmp &= ~(0x1 << (ao_context->index + 16));
 	me4000_outl(tmp, ao_context->preload_reg);
 	spin_unlock(&ao_context->board_info->preload_lock);
 
@@ -2867,7 +2885,9 @@
 					       "ME4000:me4000_ao_ex_trig_timeout():Wait on start of state machine interrupted\n");
 					return -EINTR;
 				}
-				if (((jiffies - ref) > (timeout * HZ / USER_HZ))) {	// 2.6 has diffrent definitions for HZ in user and kernel space
+				/* kernel 2.6 has different definitions for HZ
+				 * in user and kernel space */
+				if ((jiffies - ref) > (timeout * HZ / USER_HZ)) {
 					printk(KERN_ERR
 					       "ME4000:me4000_ao_ex_trig_timeout():Timeout reached\n");
 					return -EIO;
@@ -3243,7 +3263,8 @@
 				       "ME4000:me4000_ai_single():Wait on start of state machine interrupted\n");
 				return -EINTR;
 			}
-			if (((jiffies - jiffy) > (cmd.timeout * HZ / USER_HZ)) && cmd.timeout) {	// 2.6 has diffrent definitions for HZ in user and kernel space
+			/* 2.6 has different definitions for HZ in user and kernel space */
+			if (((jiffies - jiffy) > (cmd.timeout * HZ / USER_HZ)) && cmd.timeout) {
 				printk(KERN_ERR
 				       "ME4000:me4000_ai_single():Timeout reached\n");
 				return -EIO;
@@ -3622,9 +3643,8 @@
 	me4000_outl(tmp, ai_context->ctrl_reg);
 
 	/* Write the channel list */
-	for (i = 0; i < cmd.channel_list.count; i++) {
+	for (i = 0; i < cmd.channel_list.count; i++)
 		me4000_outl(list[i], ai_context->channel_list_reg);
-	}
 
 	/* Setup sample and hold */
 	if (cmd.sh) {
@@ -3663,8 +3683,7 @@
 	tmp &=
 	    ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_SAMPLE_HOLD);
 
-	if (list)
-		kfree(list);
+	kfree(list);
 
 	return err;
 
@@ -3774,25 +3793,22 @@
 
 	if (timeout) {
 		ref = jiffies;
-		while (!
-		       (inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM))
-		{
+		while (!(inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM)) {
 			interruptible_sleep_on_timeout(&queue, 1);
 			if (signal_pending(current)) {
 				printk(KERN_ERR
 				       "ME4000:me4000_ai_start_ex():Wait on start of state machine interrupted\n");
 				return -EINTR;
 			}
-			if (((jiffies - ref) > (timeout * HZ / USER_HZ))) {	// 2.6 has diffrent definitions for HZ in user and kernel space
+			/* 2.6 has different definitions for HZ in user and kernel space */
+			if ((jiffies - ref) > (timeout * HZ / USER_HZ)) {
 				printk(KERN_ERR
 				       "ME4000:me4000_ai_start_ex():Timeout reached\n");
 				return -EIO;
 			}
 		}
 	} else {
-		while (!
-		       (inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM))
-		{
+		while (!(inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM)) {
 			interruptible_sleep_on_timeout(&queue, 1);
 			if (signal_pending(current)) {
 				printk(KERN_ERR
@@ -4113,9 +4129,8 @@
 		return -EPIPE;
 	}
 
-	if (filep->f_flags & O_NONBLOCK) {
+	if (filep->f_flags & O_NONBLOCK)
 		return (k == 0) ? -EAGAIN : 2 * ret;
-	}
 
 	CALL_PDEBUG("me4000_ai_read() is leaved\n");
 	return ret * 2;
@@ -4254,11 +4269,10 @@
 	udelay(EEPROM_DELAY);
 
 	for (i = 0; i < length; i++) {
-		if (cmd & ((0x1 << (length - 1)) >> i)) {
+		if (cmd & ((0x1 << (length - 1)) >> i))
 			value |= PLX_ICR_BIT_EEPROM_WRITE;
-		} else {
+		else
 			value &= ~PLX_ICR_BIT_EEPROM_WRITE;
-		}
 
 		/* Write to EEPROM */
 		me4000_outl(value,
@@ -4314,11 +4328,11 @@
 
 	/* Write the read command to the eeprom */
 	for (i = 0; i < length; i++) {
-		if (cmd & ((0x1 << (length - 1)) >> i)) {
+		if (cmd & ((0x1 << (length - 1)) >> i))
 			value |= PLX_ICR_BIT_EEPROM_WRITE;
-		} else {
+		else
 			value &= ~PLX_ICR_BIT_EEPROM_WRITE;
-		}
+
 		me4000_outl(value,
 			    ai_context->board_info->plx_regbase + PLX_ICR);
 		udelay(EEPROM_DELAY);
@@ -5440,8 +5454,6 @@
 	int i;
 	int c = 0;
 	int c1 = 0;
-	//unsigned long before;
-	//unsigned long after;
 
 	ISR_PDEBUG("me4000_ao_isr() is executed\n");
 
@@ -5493,7 +5505,6 @@
 			    ("me4000_ao_isr():Work done or buffer empty\n");
 			break;
 		}
-		//rdtscl(before);
 		if (((ao_context->fifo_reg & 0xFF) == ME4000_AO_01_FIFO_REG) ||
 		    ((ao_context->fifo_reg & 0xFF) == ME4000_AO_03_FIFO_REG)) {
 			for (i = 0; i < c1; i++) {
@@ -5509,8 +5520,6 @@
 			      ao_context->circ_buf.buf +
 			      ao_context->circ_buf.tail, c1);
 
-		//rdtscl(after);
-		//printk(KERN_ERR"ME4000:me4000_ao_isr():Time lapse = %lu\n", after - before);
 
 		ao_context->circ_buf.tail =
 		    (ao_context->circ_buf.tail + c1) & (ME4000_AO_BUFFER_COUNT -
@@ -5542,8 +5551,10 @@
 	/* If state machine is stopped, flow was interrupted */
 	if (!(me4000_inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM)) {
 		printk(KERN_ERR "ME4000:me4000_ao_isr():Broken pipe\n");
-		ao_context->pipe_flag = 1;	// Set flag in order to inform write routine
-		tmp &= ~ME4000_AO_CTRL_BIT_ENABLE_IRQ;	// Disable interrupt
+		/* Set flag in order to inform write routine */
+		ao_context->pipe_flag = 1;
+		/* Disable interrupt */
+		tmp &= ~ME4000_AO_CTRL_BIT_ENABLE_IRQ;
 	}
 	me4000_outl(tmp, ao_context->ctrl_reg);
 	spin_unlock(&ao_context->int_lock);
diff --git a/drivers/staging/meilhaus/me0600_device.c b/drivers/staging/meilhaus/me0600_device.c
index 8950e47..bae17d26 100644
--- a/drivers/staging/meilhaus/me0600_device.c
+++ b/drivers/staging/meilhaus/me0600_device.c
@@ -186,6 +186,7 @@
 
 	return (me_device_t *) me0600_device;
 }
+EXPORT_SYMBOL(me0600_pci_constructor);
 
 // Init and exit of module.
 
@@ -210,6 +211,3 @@
 MODULE_DESCRIPTION("Device Driver Module for ME-6xx Device");
 MODULE_SUPPORTED_DEVICE("Meilhaus ME-6xx Devices");
 MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me0600_pci_constructor);
diff --git a/drivers/staging/meilhaus/me0600_dio.c b/drivers/staging/meilhaus/me0600_dio.c
index 3a27757..d293035 100644
--- a/drivers/staging/meilhaus/me0600_dio.c
+++ b/drivers/staging/meilhaus/me0600_dio.c
@@ -36,7 +36,7 @@
 
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/types.h>
 
 #include "medefines.h"
@@ -91,7 +91,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me0600_dio_io_single_config(me_subdevice_t * subdevice,
+static int me0600_dio_io_single_config(me_subdevice_t *subdevice,
 				       struct file *filep,
 				       int channel,
 				       int single_config,
@@ -162,7 +162,7 @@
 	return err;
 }
 
-static int me0600_dio_io_single_read(me_subdevice_t * subdevice,
+static int me0600_dio_io_single_read(me_subdevice_t *subdevice,
 				     struct file *filep,
 				     int channel,
 				     int *value, int time_out, int flags)
@@ -242,7 +242,7 @@
 	return err;
 }
 
-static int me0600_dio_io_single_write(me_subdevice_t * subdevice,
+static int me0600_dio_io_single_write(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int channel,
 				      int value, int time_out, int flags)
@@ -329,7 +329,7 @@
 	return err;
 }
 
-static int me0600_dio_query_number_channels(me_subdevice_t * subdevice,
+static int me0600_dio_query_number_channels(me_subdevice_t *subdevice,
 					    int *number)
 {
 	PDEBUG("executed.\n");
@@ -337,7 +337,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me0600_dio_query_subdevice_type(me_subdevice_t * subdevice,
+static int me0600_dio_query_subdevice_type(me_subdevice_t *subdevice,
 					   int *type, int *subtype)
 {
 	PDEBUG("executed.\n");
@@ -346,7 +346,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me0600_dio_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me0600_dio_query_subdevice_caps(me_subdevice_t *subdevice,
 					   int *caps)
 {
 	PDEBUG("executed.\n");
@@ -356,7 +356,7 @@
 
 me0600_dio_subdevice_t *me0600_dio_constructor(uint32_t reg_base,
 					       unsigned int dio_idx,
-					       spinlock_t * ctrl_reg_lock)
+					       spinlock_t *ctrl_reg_lock)
 {
 	me0600_dio_subdevice_t *subdevice;
 	int err;
@@ -381,7 +381,7 @@
 		kfree(subdevice);
 		return NULL;
 	}
-	// Initialize spin locks.
+	/* Initialize spin locks. */
 	spin_lock_init(&subdevice->subdevice_lock);
 
 	subdevice->ctrl_reg_lock = ctrl_reg_lock;
diff --git a/drivers/staging/meilhaus/me0600_ext_irq.c b/drivers/staging/meilhaus/me0600_ext_irq.c
index eba18ad..2f6fedc 100644
--- a/drivers/staging/meilhaus/me0600_ext_irq.c
+++ b/drivers/staging/meilhaus/me0600_ext_irq.c
@@ -37,7 +37,7 @@
 
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
 
@@ -337,11 +337,7 @@
 	kfree(instance);
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
 static irqreturn_t me0600_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me0600_isr(int irq, void *dev_id, struct pt_regs *regs)
-#endif
 {
 	me0600_ext_irq_subdevice_t *instance;
 	uint32_t status;
@@ -397,7 +393,7 @@
 
 me0600_ext_irq_subdevice_t *me0600_ext_irq_constructor(uint32_t plx_reg_base,
 						       uint32_t me0600_reg_base,
-						       spinlock_t * intcsr_lock,
+						       spinlock_t *intcsr_lock,
 						       unsigned ext_irq_idx,
 						       int irq)
 {
diff --git a/drivers/staging/meilhaus/me0600_optoi.c b/drivers/staging/meilhaus/me0600_optoi.c
index b6d977f..43f710f 100644
--- a/drivers/staging/meilhaus/me0600_optoi.c
+++ b/drivers/staging/meilhaus/me0600_optoi.c
@@ -36,7 +36,7 @@
 
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/types.h>
 
 #include "medefines.h"
@@ -68,7 +68,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me0600_optoi_io_single_config(me_subdevice_t * subdevice,
+static int me0600_optoi_io_single_config(me_subdevice_t *subdevice,
 					 struct file *filep,
 					 int channel,
 					 int single_config,
@@ -118,7 +118,7 @@
 	return err;
 }
 
-static int me0600_optoi_io_single_read(me_subdevice_t * subdevice,
+static int me0600_optoi_io_single_read(me_subdevice_t *subdevice,
 				       struct file *filep,
 				       int channel,
 				       int *value, int time_out, int flags)
@@ -169,7 +169,7 @@
 	return err;
 }
 
-static int me0600_optoi_query_number_channels(me_subdevice_t * subdevice,
+static int me0600_optoi_query_number_channels(me_subdevice_t *subdevice,
 					      int *number)
 {
 	PDEBUG("executed.\n");
@@ -177,7 +177,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me0600_optoi_query_subdevice_type(me_subdevice_t * subdevice,
+static int me0600_optoi_query_subdevice_type(me_subdevice_t *subdevice,
 					     int *type, int *subtype)
 {
 	PDEBUG("executed.\n");
@@ -186,7 +186,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me0600_optoi_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me0600_optoi_query_subdevice_caps(me_subdevice_t *subdevice,
 					     int *caps)
 {
 	PDEBUG("executed.\n");
@@ -219,7 +219,7 @@
 		kfree(subdevice);
 		return NULL;
 	}
-	// Initialize spin locks.
+	/* Initialize spin locks. */
 	spin_lock_init(&subdevice->subdevice_lock);
 
 	/* Save the subdevice index */
diff --git a/drivers/staging/meilhaus/me0600_relay.c b/drivers/staging/meilhaus/me0600_relay.c
index 2665c69..03835e3 100644
--- a/drivers/staging/meilhaus/me0600_relay.c
+++ b/drivers/staging/meilhaus/me0600_relay.c
@@ -36,7 +36,7 @@
 
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/types.h>
 
 #include "medefines.h"
@@ -85,7 +85,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me0600_relay_io_single_config(me_subdevice_t * subdevice,
+static int me0600_relay_io_single_config(me_subdevice_t *subdevice,
 					 struct file *filep,
 					 int channel,
 					 int single_config,
@@ -135,7 +135,7 @@
 	return err;
 }
 
-static int me0600_relay_io_single_read(me_subdevice_t * subdevice,
+static int me0600_relay_io_single_read(me_subdevice_t *subdevice,
 				       struct file *filep,
 				       int channel,
 				       int *value, int time_out, int flags)
@@ -203,7 +203,7 @@
 	return err;
 }
 
-static int me0600_relay_io_single_write(me_subdevice_t * subdevice,
+static int me0600_relay_io_single_write(me_subdevice_t *subdevice,
 					struct file *filep,
 					int channel,
 					int value, int time_out, int flags)
@@ -279,7 +279,7 @@
 	return err;
 }
 
-static int me0600_relay_query_number_channels(me_subdevice_t * subdevice,
+static int me0600_relay_query_number_channels(me_subdevice_t *subdevice,
 					      int *number)
 {
 	PDEBUG("executed.\n");
@@ -287,7 +287,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me0600_relay_query_subdevice_type(me_subdevice_t * subdevice,
+static int me0600_relay_query_subdevice_type(me_subdevice_t *subdevice,
 					     int *type, int *subtype)
 {
 	PDEBUG("executed.\n");
@@ -296,7 +296,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me0600_relay_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me0600_relay_query_subdevice_caps(me_subdevice_t *subdevice,
 					     int *caps)
 {
 	PDEBUG("executed.\n");
diff --git a/drivers/staging/meilhaus/me0600_ttli.c b/drivers/staging/meilhaus/me0600_ttli.c
index ab8e13b..7d970f5 100644
--- a/drivers/staging/meilhaus/me0600_ttli.c
+++ b/drivers/staging/meilhaus/me0600_ttli.c
@@ -36,7 +36,7 @@
 
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/types.h>
 
 #include "medefines.h"
@@ -67,7 +67,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me0600_ttli_io_single_config(me_subdevice_t * subdevice,
+static int me0600_ttli_io_single_config(me_subdevice_t *subdevice,
 					struct file *filep,
 					int channel,
 					int single_config,
@@ -116,7 +116,7 @@
 	return err;
 }
 
-static int me0600_ttli_io_single_read(me_subdevice_t * subdevice,
+static int me0600_ttli_io_single_read(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int channel,
 				      int *value, int time_out, int flags)
@@ -164,7 +164,7 @@
 	return err;
 }
 
-static int me0600_ttli_query_number_channels(me_subdevice_t * subdevice,
+static int me0600_ttli_query_number_channels(me_subdevice_t *subdevice,
 					     int *number)
 {
 	PDEBUG("executed.\n");
@@ -172,7 +172,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me0600_ttli_query_subdevice_type(me_subdevice_t * subdevice,
+static int me0600_ttli_query_subdevice_type(me_subdevice_t *subdevice,
 					    int *type, int *subtype)
 {
 	PDEBUG("executed.\n");
@@ -181,7 +181,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me0600_ttli_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me0600_ttli_query_subdevice_caps(me_subdevice_t *subdevice,
 					    int *caps)
 {
 	PDEBUG("executed.\n");
diff --git a/drivers/staging/meilhaus/me0900_device.c b/drivers/staging/meilhaus/me0900_device.c
index 764d5d3..e9c6884 100644
--- a/drivers/staging/meilhaus/me0900_device.c
+++ b/drivers/staging/meilhaus/me0900_device.c
@@ -152,6 +152,7 @@
 
 	return (me_device_t *) me0900_device;
 }
+EXPORT_SYMBOL(me0900_pci_constructor);
 
 // Init and exit of module.
 
@@ -175,6 +176,3 @@
 MODULE_DESCRIPTION("Device Driver Module for ME-9x Device");
 MODULE_SUPPORTED_DEVICE("Meilhaus ME-9x Devices");
 MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me0900_pci_constructor);
diff --git a/drivers/staging/meilhaus/me0900_di.c b/drivers/staging/meilhaus/me0900_di.c
index d7d7394..4665b2a 100644
--- a/drivers/staging/meilhaus/me0900_di.c
+++ b/drivers/staging/meilhaus/me0900_di.c
@@ -35,7 +35,7 @@
 
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/version.h>
@@ -71,7 +71,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me0900_di_io_single_config(me_subdevice_t * subdevice,
+static int me0900_di_io_single_config(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int channel,
 				      int single_config,
@@ -115,7 +115,7 @@
 	return err;
 }
 
-static int me0900_di_io_single_read(me_subdevice_t * subdevice,
+static int me0900_di_io_single_read(me_subdevice_t *subdevice,
 				    struct file *filep,
 				    int channel,
 				    int *value, int time_out, int flags)
@@ -161,7 +161,7 @@
 	return err;
 }
 
-static int me0900_di_query_number_channels(me_subdevice_t * subdevice,
+static int me0900_di_query_number_channels(me_subdevice_t *subdevice,
 					   int *number)
 {
 	PDEBUG("executed.\n");
@@ -169,7 +169,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me0900_di_query_subdevice_type(me_subdevice_t * subdevice,
+static int me0900_di_query_subdevice_type(me_subdevice_t *subdevice,
 					  int *type, int *subtype)
 {
 	PDEBUG("executed.\n");
@@ -178,7 +178,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me0900_di_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me0900_di_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
 {
 	PDEBUG("executed.\n");
 	*caps = 0;
diff --git a/drivers/staging/meilhaus/me0900_do.c b/drivers/staging/meilhaus/me0900_do.c
index b5b9c3a..a2275fa 100644
--- a/drivers/staging/meilhaus/me0900_do.c
+++ b/drivers/staging/meilhaus/me0900_do.c
@@ -35,7 +35,7 @@
 
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/types.h>
 
 #include "medefines.h"
@@ -81,7 +81,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me0900_do_io_single_config(me_subdevice_t * subdevice,
+static int me0900_do_io_single_config(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int channel,
 				      int single_config,
@@ -125,7 +125,7 @@
 	return err;
 }
 
-static int me0900_do_io_single_read(me_subdevice_t * subdevice,
+static int me0900_do_io_single_read(me_subdevice_t *subdevice,
 				    struct file *filep,
 				    int channel,
 				    int *value, int time_out, int flags)
@@ -171,7 +171,7 @@
 	return err;
 }
 
-static int me0900_do_io_single_write(me_subdevice_t * subdevice,
+static int me0900_do_io_single_write(me_subdevice_t *subdevice,
 				     struct file *filep,
 				     int channel,
 				     int value, int time_out, int flags)
@@ -223,7 +223,7 @@
 	return err;
 }
 
-static int me0900_do_query_number_channels(me_subdevice_t * subdevice,
+static int me0900_do_query_number_channels(me_subdevice_t *subdevice,
 					   int *number)
 {
 	PDEBUG("executed.\n");
@@ -231,7 +231,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me0900_do_query_subdevice_type(me_subdevice_t * subdevice,
+static int me0900_do_query_subdevice_type(me_subdevice_t *subdevice,
 					  int *type, int *subtype)
 {
 	PDEBUG("executed.\n");
@@ -240,7 +240,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me0900_do_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me0900_do_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
 {
 	PDEBUG("executed.\n");
 	*caps = 0;
diff --git a/drivers/staging/meilhaus/me1000_device.c b/drivers/staging/meilhaus/me1000_device.c
index c44e214..cf0fb92 100644
--- a/drivers/staging/meilhaus/me1000_device.c
+++ b/drivers/staging/meilhaus/me1000_device.c
@@ -49,8 +49,8 @@
 #include "mesubdevice.h"
 #include "me1000_dio.h"
 
-static int me1000_config_load(me_device_t * me_device, struct file *filep,
-			      me_cfg_device_entry_t * config)
+static int me1000_config_load(me_device_t *me_device, struct file *filep,
+			      me_cfg_device_entry_t *config)
 {
 	me1000_device_t *me1000_device;
 	me1000_dio_subdevice_t *dio;
@@ -181,6 +181,7 @@
 
 	return (me_device_t *) me1000_device;
 }
+EXPORT_SYMBOL(me1000_pci_constructor);
 
 // Init and exit of module.
 static int __init me1000_init(void)
@@ -203,6 +204,3 @@
 MODULE_DESCRIPTION("Device Driver Module for Meilhaus ME-1000 Devices");
 MODULE_SUPPORTED_DEVICE("Meilhaus ME-1000 Digital I/O Devices");
 MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me1000_pci_constructor);
diff --git a/drivers/staging/meilhaus/me1000_dio.c b/drivers/staging/meilhaus/me1000_dio.c
index 87605a9..2d7ed07 100644
--- a/drivers/staging/meilhaus/me1000_dio.c
+++ b/drivers/staging/meilhaus/me1000_dio.c
@@ -36,7 +36,7 @@
 
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/types.h>
 
 #include "medefines.h"
@@ -371,7 +371,7 @@
 
 me1000_dio_subdevice_t *me1000_dio_constructor(uint32_t reg_base,
 					       unsigned int dio_idx,
-					       spinlock_t * ctrl_reg_lock)
+					       spinlock_t *ctrl_reg_lock)
 {
 	me1000_dio_subdevice_t *subdevice;
 	int err;
diff --git a/drivers/staging/meilhaus/me1400_device.c b/drivers/staging/meilhaus/me1400_device.c
index b95bb4f..ca7498b 100644
--- a/drivers/staging/meilhaus/me1400_device.c
+++ b/drivers/staging/meilhaus/me1400_device.c
@@ -228,6 +228,7 @@
 
 	return (me_device_t *) me1400_device;
 }
+EXPORT_SYMBOL(me1400_pci_constructor);
 
 // Init and exit of module.
 
@@ -251,6 +252,3 @@
 MODULE_DESCRIPTION("Device Driver Module for Meilhaus ME-14xx devices");
 MODULE_SUPPORTED_DEVICE("Meilhaus ME-14xx MIO devices");
 MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me1400_pci_constructor);
diff --git a/drivers/staging/meilhaus/me1400_ext_irq.c b/drivers/staging/meilhaus/me1400_ext_irq.c
index b4df7cc..0dc6b45 100644
--- a/drivers/staging/meilhaus/me1400_ext_irq.c
+++ b/drivers/staging/meilhaus/me1400_ext_irq.c
@@ -37,7 +37,7 @@
 
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
 
@@ -323,12 +323,7 @@
 	return ME_ERRNO_NOT_SUPPORTED;
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
 static irqreturn_t me1400_ext_irq_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me1400_ext_irq_isr(int irq, void *dev_id,
-				      struct pt_regs *regs)
-#endif
 {
 	me1400_ext_irq_subdevice_t *instance;
 	uint32_t status;
diff --git a/drivers/staging/meilhaus/me1600_ao.c b/drivers/staging/meilhaus/me1600_ao.c
index d127c6b..12e3c70 100644
--- a/drivers/staging/meilhaus/me1600_ao.c
+++ b/drivers/staging/meilhaus/me1600_ao.c
@@ -36,7 +36,7 @@
 
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/types.h>
 #include <linux/sched.h>
 
@@ -55,36 +55,32 @@
 
 static void me1600_ao_destructor(struct me_subdevice *subdevice);
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-static void me1600_ao_work_control_task(void *subdevice);
-#else
 static void me1600_ao_work_control_task(struct work_struct *work);
-#endif
 
-static int me1600_ao_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me1600_ao_io_reset_subdevice(me_subdevice_t *subdevice,
 					struct file *filep, int flags);
-static int me1600_ao_io_single_config(me_subdevice_t * subdevice,
+static int me1600_ao_io_single_config(me_subdevice_t *subdevice,
 				      struct file *filep, int channel,
 				      int single_config, int ref, int trig_chan,
 				      int trig_type, int trig_edge, int flags);
-static int me1600_ao_io_single_read(me_subdevice_t * subdevice,
+static int me1600_ao_io_single_read(me_subdevice_t *subdevice,
 				    struct file *filep, int channel, int *value,
 				    int time_out, int flags);
-static int me1600_ao_io_single_write(me_subdevice_t * subdevice,
+static int me1600_ao_io_single_write(me_subdevice_t *subdevice,
 				     struct file *filep, int channel, int value,
 				     int time_out, int flags);
-static int me1600_ao_query_number_channels(me_subdevice_t * subdevice,
+static int me1600_ao_query_number_channels(me_subdevice_t *subdevice,
 					   int *number);
-static int me1600_ao_query_subdevice_type(me_subdevice_t * subdevice, int *type,
+static int me1600_ao_query_subdevice_type(me_subdevice_t *subdevice, int *type,
 					  int *subtype);
-static int me1600_ao_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me1600_ao_query_subdevice_caps(me_subdevice_t *subdevice,
 					  int *caps);
-static int me1600_ao_query_range_by_min_max(me_subdevice_t * subdevice,
+static int me1600_ao_query_range_by_min_max(me_subdevice_t *subdevice,
 					    int unit, int *min, int *max,
 					    int *maxdata, int *range);
-static int me1600_ao_query_number_ranges(me_subdevice_t * subdevice, int unit,
+static int me1600_ao_query_number_ranges(me_subdevice_t *subdevice, int unit,
 					 int *count);
-static int me1600_ao_query_range_info(me_subdevice_t * subdevice, int range,
+static int me1600_ao_query_range_info(me_subdevice_t *subdevice, int range,
 				      int *unit, int *min, int *max,
 				      int *maxdata);
 
@@ -94,10 +90,9 @@
 me1600_ao_subdevice_t *me1600_ao_constructor(uint32_t reg_base,
 					     unsigned int ao_idx,
 					     int curr,
-					     spinlock_t * config_regs_lock,
-					     spinlock_t * ao_shadows_lock,
-					     me1600_ao_shadow_t *
-					     ao_regs_shadows,
+					     spinlock_t *config_regs_lock,
+					     spinlock_t *ao_shadows_lock,
+					     me1600_ao_shadow_t *ao_regs_shadows,
 					     struct workqueue_struct *me1600_wq)
 {
 	me1600_ao_subdevice_t *subdevice;
@@ -200,13 +195,8 @@
 	subdevice->me1600_workqueue = me1600_wq;
 
 /* workqueue API changed in kernel 2.6.20 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) )
-	INIT_WORK(&subdevice->ao_control_task, me1600_ao_work_control_task,
-		  (void *)subdevice);
-#else
 	INIT_DELAYED_WORK(&subdevice->ao_control_task,
 			  me1600_ao_work_control_task);
-#endif
 	return subdevice;
 }
 
@@ -231,7 +221,7 @@
 	}
 }
 
-static int me1600_ao_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me1600_ao_io_reset_subdevice(me_subdevice_t *subdevice,
 					struct file *filep, int flags)
 {
 	me1600_ao_subdevice_t *instance;
@@ -313,7 +303,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me1600_ao_io_single_config(me_subdevice_t * subdevice,
+static int me1600_ao_io_single_config(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int channel,
 				      int single_config,
@@ -545,7 +535,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me1600_ao_io_single_read(me_subdevice_t * subdevice,
+static int me1600_ao_io_single_read(me_subdevice_t *subdevice,
 				    struct file *filep,
 				    int channel,
 				    int *value, int time_out, int flags)
@@ -612,7 +602,7 @@
 	return err;
 }
 
-static int me1600_ao_io_single_write(me_subdevice_t * subdevice,
+static int me1600_ao_io_single_write(me_subdevice_t *subdevice,
 				     struct file *filep,
 				     int channel,
 				     int value, int time_out, int flags)
@@ -756,7 +746,9 @@
 	queue_delayed_work(instance->me1600_workqueue,
 			   &instance->ao_control_task, 1);
 
-	if ((!flags & ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING) && ((instance->ao_regs_shadows)->trigger & instance->ao_idx)) {	//Blocking mode. Wait for software trigger.
+	if ((!(flags & ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) &&
+	    ((instance->ao_regs_shadows)->trigger & instance->ao_idx)) {
+		/* Blocking mode. Wait for software trigger. */
 		if (time_out) {
 			delay = (time_out * HZ) / 1000;
 			if (delay == 0)
@@ -793,7 +785,7 @@
 	return err;
 }
 
-static int me1600_ao_query_number_channels(me_subdevice_t * subdevice,
+static int me1600_ao_query_number_channels(me_subdevice_t *subdevice,
 					   int *number)
 {
 	me1600_ao_subdevice_t *instance;
@@ -805,7 +797,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me1600_ao_query_subdevice_type(me_subdevice_t * subdevice, int *type,
+static int me1600_ao_query_subdevice_type(me_subdevice_t *subdevice, int *type,
 					  int *subtype)
 {
 	me1600_ao_subdevice_t *instance;
@@ -818,14 +810,14 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me1600_ao_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me1600_ao_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
 {
 	PDEBUG("executed.\n");
 	*caps = ME_CAPS_AO_TRIG_SYNCHRONOUS;
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me1600_ao_query_range_by_min_max(me_subdevice_t * subdevice,
+static int me1600_ao_query_range_by_min_max(me_subdevice_t *subdevice,
 					    int unit,
 					    int *min,
 					    int *max, int *maxdata, int *range)
@@ -903,7 +895,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me1600_ao_query_number_ranges(me_subdevice_t * subdevice,
+static int me1600_ao_query_number_ranges(me_subdevice_t *subdevice,
 					 int unit, int *count)
 {
 	me1600_ao_subdevice_t *instance;
@@ -928,7 +920,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me1600_ao_query_range_info(me_subdevice_t * subdevice,
+static int me1600_ao_query_range_info(me_subdevice_t *subdevice,
 				      int range,
 				      int *unit,
 				      int *min, int *max, int *maxdata)
@@ -960,22 +952,14 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-static void me1600_ao_work_control_task(void *subdevice)
-#else
 static void me1600_ao_work_control_task(struct work_struct *work)
-#endif
 {
 	me1600_ao_subdevice_t *instance;
 	int reschedule = 1;
 	int signaling = 0;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-	instance = (me1600_ao_subdevice_t *) subdevice;
-#else
 	instance =
 	    container_of((void *)work, me1600_ao_subdevice_t, ao_control_task);
-#endif
 
 	PINFO("<%s: %ld> executed. idx=%d\n", __func__, jiffies,
 	      instance->ao_idx);
diff --git a/drivers/staging/meilhaus/me1600_ao.h b/drivers/staging/meilhaus/me1600_ao.h
index b82bf5a..4827dcb 100644
--- a/drivers/staging/meilhaus/me1600_ao.h
+++ b/drivers/staging/meilhaus/me1600_ao.h
@@ -98,11 +98,7 @@
 	wait_queue_head_t wait_queue;							/**< Wait queue to put on tasks waiting for data to arrive. */
 	me1600_ao_timeout_t timeout;							/**< The timeout for start in blocking and non-blocking mode. */
 	struct workqueue_struct *me1600_workqueue;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-	struct work_struct ao_control_task;
-#else
 	struct delayed_work ao_control_task;
-#endif
 
 	volatile int ao_control_task_flag;						/**< Flag controling reexecuting of control task */
 } me1600_ao_subdevice_t;
diff --git a/drivers/staging/meilhaus/me1600_device.c b/drivers/staging/meilhaus/me1600_device.c
index 3bc2cb1..c244e98 100644
--- a/drivers/staging/meilhaus/me1600_device.c
+++ b/drivers/staging/meilhaus/me1600_device.c
@@ -48,7 +48,7 @@
 #include "mesubdevice.h"
 #include "me1600_device.h"
 
-static void me1600_set_registry(me1600_device_t * subdevice, uint32_t reg_base);
+static void me1600_set_registry(me1600_device_t *subdevice, uint32_t reg_base);
 static void me1600_destructor(struct me_device *device);
 
 /**
@@ -142,6 +142,7 @@
 
 	return (me_device_t *) me1600_device;
 }
+EXPORT_SYMBOL(me1600_pci_constructor);
 
 static void me1600_destructor(struct me_device *device)
 {
@@ -157,7 +158,7 @@
 	kfree(me1600_device);
 }
 
-static void me1600_set_registry(me1600_device_t * subdevice, uint32_t reg_base)
+static void me1600_set_registry(me1600_device_t *subdevice, uint32_t reg_base)
 {				// Create shadow structure.
 	if (subdevice->ao_regs_shadows.count >= 1) {
 		subdevice->ao_regs_shadows.registry[0] =
@@ -256,6 +257,3 @@
 MODULE_DESCRIPTION("Device Driver Module for ME-1600 Device");
 MODULE_SUPPORTED_DEVICE("Meilhaus ME-1600 Devices");
 MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me1600_pci_constructor);
diff --git a/drivers/staging/meilhaus/me4600_ai.c b/drivers/staging/meilhaus/me4600_ai.c
index 0a8c9d7..a3cfef0 100644
--- a/drivers/staging/meilhaus/me4600_ai.c
+++ b/drivers/staging/meilhaus/me4600_ai.c
@@ -36,8 +36,8 @@
 
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
@@ -57,10 +57,10 @@
  */
 
 static void me4600_ai_destructor(struct me_subdevice *subdevice);
-static int me4600_ai_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me4600_ai_io_reset_subdevice(me_subdevice_t *subdevice,
 					struct file *filep, int flags);
 
-static int me4600_ai_io_single_config(me_subdevice_t * subdevice,
+static int me4600_ai_io_single_config(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int channel,
 				      int single_config,
@@ -68,120 +68,112 @@
 				      int trig_chan,
 				      int trig_type, int trig_edge, int flags);
 
-static int me4600_ai_io_single_read(me_subdevice_t * subdevice,
+static int me4600_ai_io_single_read(me_subdevice_t *subdevice,
 				    struct file *filep,
 				    int channel,
 				    int *value, int time_out, int flags);
 
-static int me4600_ai_io_stream_config(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_config(me_subdevice_t *subdevice,
 				      struct file *filep,
-				      meIOStreamConfig_t * config_list,
+				      meIOStreamConfig_t *config_list,
 				      int count,
-				      meIOStreamTrigger_t * trigger,
+				      meIOStreamTrigger_t *trigger,
 				      int fifo_irq_threshold, int flags);
-static int me4600_ai_io_stream_read(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_read(me_subdevice_t *subdevice,
 				    struct file *filep,
 				    int read_mode,
 				    int *values, int *count, int flags);
-static int me4600_ai_io_stream_new_values(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_new_values(me_subdevice_t *subdevice,
 					  struct file *filep,
 					  int time_out, int *count, int flags);
-static int inline me4600_ai_io_stream_read_get_value(me4600_ai_subdevice_t *
+static inline int me4600_ai_io_stream_read_get_value(me4600_ai_subdevice_t *
 						     instance, int *values,
 						     const int count,
 						     const int flags);
 
-static int me4600_ai_io_stream_start(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_start(me_subdevice_t *subdevice,
 				     struct file *filep,
 				     int start_mode, int time_out, int flags);
-static int me4600_ai_io_stream_stop(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_stop(me_subdevice_t *subdevice,
 				    struct file *filep,
 				    int stop_mode, int flags);
-static int me4600_ai_io_stream_status(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_status(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int wait,
 				      int *status, int *values, int flags);
 
-static int me4600_ai_query_range_by_min_max(me_subdevice_t * subdevice,
+static int me4600_ai_query_range_by_min_max(me_subdevice_t *subdevice,
 					    int unit,
 					    int *min,
 					    int *max, int *maxdata, int *range);
-static int me4600_ai_query_number_ranges(me_subdevice_t * subdevice,
+static int me4600_ai_query_number_ranges(me_subdevice_t *subdevice,
 					 int unit, int *count);
-static int me4600_ai_query_range_info(me_subdevice_t * subdevice,
+static int me4600_ai_query_range_info(me_subdevice_t *subdevice,
 				      int range,
 				      int *unit,
 				      int *min, int *max, int *maxdata);
-static int me4600_ai_query_timer(me_subdevice_t * subdevice,
+static int me4600_ai_query_timer(me_subdevice_t *subdevice,
 				 int timer,
 				 int *base_frequency,
 				 long long *min_ticks, long long *max_ticks);
-static int me4600_ai_query_number_channels(me_subdevice_t * subdevice,
+static int me4600_ai_query_number_channels(me_subdevice_t *subdevice,
 					   int *number);
-static int me4600_ai_query_subdevice_type(me_subdevice_t * subdevice,
+static int me4600_ai_query_subdevice_type(me_subdevice_t *subdevice,
 					  int *type, int *subtype);
-static int me4600_ai_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me4600_ai_query_subdevice_caps(me_subdevice_t *subdevice,
 					  int *caps);
 static int me4600_ai_query_subdevice_caps_args(struct me_subdevice *subdevice,
 					       int cap, int *args, int count);
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
 static irqreturn_t me4600_ai_isr(int irq, void *dev_id);
-#else
-static irqreturn_t me4600_ai_isr(int irq, void *dev_id, struct pt_regs *regs);
-#endif
 
-static int ai_mux_toggler(me4600_ai_subdevice_t * subdevice);
+static int ai_mux_toggler(me4600_ai_subdevice_t *subdevice);
 
 /** Immidiate stop.
 * Reset all IRQ's sources. (block laches)
 * Preserve FIFO
 */
-static int ai_stop_immediately(me4600_ai_subdevice_t * instance);
+static int ai_stop_immediately(me4600_ai_subdevice_t *instance);
 
 /** Immidiate stop.
 * Reset all IRQ's sources. (block laches)
 * Reset data FIFO
 */
-void inline ai_stop_isr(me4600_ai_subdevice_t * instance);
+inline void ai_stop_isr(me4600_ai_subdevice_t *instance);
 
 /** Interrupt logics.
 * Read datas
 * Reset latches
 */
-void ai_limited_isr(me4600_ai_subdevice_t * instance, const uint32_t irq_status,
+void ai_limited_isr(me4600_ai_subdevice_t *instance, const uint32_t irq_status,
 		    const uint32_t ctrl_status);
-void ai_infinite_isr(me4600_ai_subdevice_t * instance,
+void ai_infinite_isr(me4600_ai_subdevice_t *instance,
 		     const uint32_t irq_status, const uint32_t ctrl_status);
 
 /** Last chunck of datas. We must reschedule sample counter.
 * Leaving SC_RELOAD doesn't do any harm, but in some bad case can make extra interrupts.
 * When threshold is wrongly set some IRQ are lost.(!!!)
 */
-void inline ai_reschedule_SC(me4600_ai_subdevice_t * instance);
+inline void ai_reschedule_SC(me4600_ai_subdevice_t *instance);
 
 /** Read datas from FIFO and copy them to buffer */
-static int inline ai_read_data(me4600_ai_subdevice_t * instance,
+static inline int ai_read_data(me4600_ai_subdevice_t *instance,
 			       const int count);
 
 /** Copy rest of data from fifo to circular buffer.*/
-static int inline ai_read_data_pooling(me4600_ai_subdevice_t * instance);
+static inline int ai_read_data_pooling(me4600_ai_subdevice_t *instance);
 
 /** Set ISM to next state for infinite data aqusation mode*/
-void inline ai_infinite_ISM(me4600_ai_subdevice_t * instance);
+inline void ai_infinite_ISM(me4600_ai_subdevice_t *instance);
 
 /** Set ISM to next state for define amount of data aqusation mode*/
-void inline ai_limited_ISM(me4600_ai_subdevice_t * instance,
+inline void ai_limited_ISM(me4600_ai_subdevice_t *instance,
 			   uint32_t irq_status);
 
 /** Set ISM to next stage for limited mode */
-void inline ai_data_acquisition_logic(me4600_ai_subdevice_t * instance);
+inline void ai_data_acquisition_logic(me4600_ai_subdevice_t *instance);
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-static void me4600_ai_work_control_task(void *subdevice);
-#else
 static void me4600_ai_work_control_task(struct work_struct *work);
-#endif
 
 /* Definitions
  */
@@ -192,7 +184,7 @@
 					     int isolated,
 					     int sh,
 					     int irq,
-					     spinlock_t * ctrl_reg_lock,
+					     spinlock_t *ctrl_reg_lock,
 					     struct workqueue_struct *me4600_wq)
 {
 	me4600_ai_subdevice_t *subdevice;
@@ -360,13 +352,8 @@
 	subdevice->me4600_workqueue = me4600_wq;
 
 /* workqueue API changed in kernel 2.6.20 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) )
-	INIT_WORK(&subdevice->ai_control_task, me4600_ai_work_control_task,
-		  (void *)subdevice);
-#else
 	INIT_DELAYED_WORK(&subdevice->ai_control_task,
 			  me4600_ai_work_control_task);
-#endif
 
 	return subdevice;
 }
@@ -397,7 +384,7 @@
 	kfree(instance);
 }
 
-static int me4600_ai_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me4600_ai_io_reset_subdevice(me_subdevice_t *subdevice,
 					struct file *filep, int flags)
 {
 	me4600_ai_subdevice_t *instance;
@@ -519,7 +506,7 @@
 	return err;
 }
 
-static int me4600_ai_io_single_config(me_subdevice_t * subdevice,
+static int me4600_ai_io_single_config(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int channel,
 				      int single_config,
@@ -709,7 +696,7 @@
 	return err;
 }
 
-static int me4600_ai_io_single_read(me_subdevice_t * subdevice,
+static int me4600_ai_io_single_read(me_subdevice_t *subdevice,
 				    struct file *filep,
 				    int channel,
 				    int *value, int time_out, int flags)
@@ -915,11 +902,11 @@
 	return err;
 }
 
-static int me4600_ai_io_stream_config(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_config(me_subdevice_t *subdevice,
 				      struct file *filep,
-				      meIOStreamConfig_t * config_list,
+				      meIOStreamConfig_t *config_list,
 				      int count,
-				      meIOStreamTrigger_t * trigger,
+				      meIOStreamTrigger_t *trigger,
 				      int fifo_irq_threshold, int flags)
 {
 	me4600_ai_subdevice_t *instance;
@@ -1586,15 +1573,15 @@
 		    ME_SINGLE_CHANNEL_NOT_CONFIGURED;
 	}
 
-      VERIFY_ERROR:		// Error in code. Wrong setting check. This should never ever happend!
+VERIFY_ERROR:		// Error in code. Wrong setting check. This should never ever happend!
 	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-      ERROR:			// Error in settings.
+ERROR:			// Error in settings.
 	ME_SUBDEVICE_EXIT;
 
 	return err;
 }
 
-static int me4600_ai_io_stream_new_values(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_new_values(me_subdevice_t *subdevice,
 					  struct file *filep,
 					  int time_out, int *count, int flags)
 {
@@ -1677,7 +1664,7 @@
 	return err;
 }
 
-static int inline me4600_ai_io_stream_read_get_value(me4600_ai_subdevice_t *
+static inline int me4600_ai_io_stream_read_get_value(me4600_ai_subdevice_t *
 						     instance, int *values,
 						     const int count,
 						     const int flags)
@@ -1712,7 +1699,7 @@
 	return n;
 }
 
-static int me4600_ai_io_stream_read(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_read(me_subdevice_t *subdevice,
 				    struct file *filep,
 				    int read_mode,
 				    int *values, int *count, int flags)
@@ -1838,7 +1825,7 @@
 * @param instance The subdevice instance (pointer).
 */
 
-static int ai_stop_immediately(me4600_ai_subdevice_t * instance)
+static int ai_stop_immediately(me4600_ai_subdevice_t *instance)
 {
 	unsigned long cpu_flags = 0;
 	volatile uint32_t ctrl;
@@ -1877,7 +1864,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me4600_ai_io_stream_start(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_start(me_subdevice_t *subdevice,
 				     struct file *filep,
 				     int start_mode, int time_out, int flags)
 {
@@ -2055,13 +2042,13 @@
 	      (tmp & ME4600_AI_CTRL_BIT_SC_IRQ_RESET) ? "reset" : "work");
 #endif
 
-      ERROR:
+ERROR:
 	ME_SUBDEVICE_EXIT;
 
 	return err;
 }
 
-static int me4600_ai_io_stream_status(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_status(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int wait,
 				      int *status, int *values, int flags)
@@ -2139,7 +2126,7 @@
 	return err;
 }
 
-static int me4600_ai_io_stream_stop(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_stop(me_subdevice_t *subdevice,
 				    struct file *filep,
 				    int stop_mode, int flags)
 {
@@ -2236,7 +2223,7 @@
 	return ret;
 }
 
-static int me4600_ai_query_range_by_min_max(me_subdevice_t * subdevice,
+static int me4600_ai_query_range_by_min_max(me_subdevice_t *subdevice,
 					    int unit,
 					    int *min,
 					    int *max, int *maxdata, int *range)
@@ -2288,7 +2275,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me4600_ai_query_number_ranges(me_subdevice_t * subdevice,
+static int me4600_ai_query_number_ranges(me_subdevice_t *subdevice,
 					 int unit, int *count)
 {
 	me4600_ai_subdevice_t *instance;
@@ -2306,7 +2293,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me4600_ai_query_range_info(me_subdevice_t * subdevice,
+static int me4600_ai_query_range_info(me_subdevice_t *subdevice,
 				      int range,
 				      int *unit,
 				      int *min, int *max, int *maxdata)
@@ -2330,7 +2317,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me4600_ai_query_timer(me_subdevice_t * subdevice,
+static int me4600_ai_query_timer(me_subdevice_t *subdevice,
 				 int timer,
 				 int *base_frequency,
 				 long long *min_ticks, long long *max_ticks)
@@ -2370,7 +2357,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me4600_ai_query_number_channels(me_subdevice_t * subdevice,
+static int me4600_ai_query_number_channels(me_subdevice_t *subdevice,
 					   int *number)
 {
 	me4600_ai_subdevice_t *instance;
@@ -2383,7 +2370,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me4600_ai_query_subdevice_type(me_subdevice_t * subdevice,
+static int me4600_ai_query_subdevice_type(me_subdevice_t *subdevice,
 					  int *type, int *subtype)
 {
 	PDEBUG("executed. idx=0\n");
@@ -2394,7 +2381,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me4600_ai_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me4600_ai_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
 {
 	PDEBUG("executed. idx=0\n");
 
@@ -2439,7 +2426,7 @@
 	return err;
 }
 
-void ai_limited_isr(me4600_ai_subdevice_t * instance, const uint32_t irq_status,
+void ai_limited_isr(me4600_ai_subdevice_t *instance, const uint32_t irq_status,
 		    const uint32_t ctrl_status)
 {
 	int to_read;
@@ -2547,7 +2534,7 @@
 	}
 }
 
-void ai_infinite_isr(me4600_ai_subdevice_t * instance,
+void ai_infinite_isr(me4600_ai_subdevice_t *instance,
 		     const uint32_t irq_status, const uint32_t ctrl_status)
 {
 	int to_read;
@@ -2603,11 +2590,7 @@
 	}
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
 static irqreturn_t me4600_ai_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me4600_ai_isr(int irq, void *dev_id, struct pt_regs *regs)
-#endif
 {				/// @note This is time critical function!
 	uint32_t irq_status;
 	uint32_t ctrl_status;
@@ -2803,7 +2786,7 @@
 *
 * @param instance The subdevice instance (pointer).
 */
-void inline ai_stop_isr(me4600_ai_subdevice_t * instance)
+inline void ai_stop_isr(me4600_ai_subdevice_t *instance)
 {				/// @note This is soft time critical function!
 	register uint32_t tmp;
 
@@ -2829,7 +2812,7 @@
 * @return On success: Number of copied values.
 * @return On error: -ME_ERRNO_RING_BUFFER_OVERFLOW.
 */
-static int inline ai_read_data(me4600_ai_subdevice_t * instance,
+static inline int ai_read_data(me4600_ai_subdevice_t *instance,
 			       const int count)
 {				/// @note This is time critical function!
 	int c = count;
@@ -2875,7 +2858,7 @@
 	return copied;
 }
 
-void inline ai_infinite_ISM(me4600_ai_subdevice_t * instance)
+inline void ai_infinite_ISM(me4600_ai_subdevice_t *instance)
 {				/// @note This is time critical function!
 	register volatile uint32_t ctrl_set, ctrl_reset, tmp;
 
@@ -2925,7 +2908,7 @@
 
 }
 
-void inline ai_limited_ISM(me4600_ai_subdevice_t * instance,
+inline void ai_limited_ISM(me4600_ai_subdevice_t *instance,
 			   uint32_t irq_status)
 {				/// @note This is time critical function!
 	register volatile uint32_t ctrl_set, ctrl_reset = 0xFFFFFFFF, tmp;
@@ -2986,7 +2969,7 @@
 *	Leaving SC_RELOAD doesn't do any harm, but in some bad case can make extra interrupts.
 *	@warning When threshold is wrongly set some IRQ are lost.(!!!)
 */
-void inline ai_reschedule_SC(me4600_ai_subdevice_t * instance)
+inline void ai_reschedule_SC(me4600_ai_subdevice_t *instance)
 {
 	register uint32_t rest;
 
@@ -3018,7 +3001,7 @@
 }
 
 /** Start the ISM. All must be reseted before enter to this function. */
-void inline ai_data_acquisition_logic(me4600_ai_subdevice_t * instance)
+inline void ai_data_acquisition_logic(me4600_ai_subdevice_t *instance)
 {
 	register uint32_t tmp;
 
@@ -3166,7 +3149,7 @@
 	}
 }
 
-static int ai_mux_toggler(me4600_ai_subdevice_t * instance)
+static int ai_mux_toggler(me4600_ai_subdevice_t *instance)
 {
 	uint32_t tmp;
 
@@ -3276,7 +3259,7 @@
 * @return On success: Number of copied values.
 * @return On error: Negative error code -ME_ERRNO_RING_BUFFER_OVERFLOW.
 */
-static int inline ai_read_data_pooling(me4600_ai_subdevice_t * instance)
+static inline int ai_read_data_pooling(me4600_ai_subdevice_t *instance)
 {				/// @note This is time critical function!
 	int empty_space;
 	int copied = 0;
@@ -3310,11 +3293,7 @@
 	return (!status) ? copied : -ME_ERRNO_RING_BUFFER_OVERFLOW;
 }
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-static void me4600_ai_work_control_task(void *subdevice)
-#else
 static void me4600_ai_work_control_task(struct work_struct *work)
-#endif
 {
 	me4600_ai_subdevice_t *instance;
 	uint32_t status;
@@ -3323,12 +3302,8 @@
 	int reschedule = 0;
 	int signaling = 0;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-	instance = (me4600_ai_subdevice_t *) subdevice;
-#else
 	instance =
 	    container_of((void *)work, me4600_ai_subdevice_t, ai_control_task);
-#endif
 	PINFO("<%s: %ld> executed.\n", __func__, jiffies);
 
 	status = inl(instance->status_reg);
diff --git a/drivers/staging/meilhaus/me4600_ai.h b/drivers/staging/meilhaus/me4600_ai.h
index 1d5a1b9..106e195 100644
--- a/drivers/staging/meilhaus/me4600_ai.h
+++ b/drivers/staging/meilhaus/me4600_ai.h
@@ -139,11 +139,7 @@
 	wait_queue_head_t wait_queue;					/**< Wait queue to put on tasks waiting for data to arrive. */
 
 	struct workqueue_struct *me4600_workqueue;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-	struct work_struct ai_control_task;
-#else
 	struct delayed_work ai_control_task;
-#endif
 
 	volatile int ai_control_task_flag;				/**< Flag controling reexecuting of control task */
 
diff --git a/drivers/staging/meilhaus/me4600_ao.c b/drivers/staging/meilhaus/me4600_ao.c
index e2bec82..eb47269 100644
--- a/drivers/staging/meilhaus/me4600_ao.c
+++ b/drivers/staging/meilhaus/me4600_ao.c
@@ -38,8 +38,8 @@
 
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
 #include <linux/types.h>
 #include <linux/version.h>
 #include <linux/interrupt.h>
@@ -58,31 +58,31 @@
 /* Defines
  */
 
-static int me4600_ao_query_range_by_min_max(me_subdevice_t * subdevice,
+static int me4600_ao_query_range_by_min_max(me_subdevice_t *subdevice,
 					    int unit,
 					    int *min,
 					    int *max, int *maxdata, int *range);
 
-static int me4600_ao_query_number_ranges(me_subdevice_t * subdevice,
+static int me4600_ao_query_number_ranges(me_subdevice_t *subdevice,
 					 int unit, int *count);
 
-static int me4600_ao_query_range_info(me_subdevice_t * subdevice,
+static int me4600_ao_query_range_info(me_subdevice_t *subdevice,
 				      int range,
 				      int *unit,
 				      int *min, int *max, int *maxdata);
 
-static int me4600_ao_query_timer(me_subdevice_t * subdevice,
+static int me4600_ao_query_timer(me_subdevice_t *subdevice,
 				 int timer,
 				 int *base_frequency,
 				 long long *min_ticks, long long *max_ticks);
 
-static int me4600_ao_query_number_channels(me_subdevice_t * subdevice,
+static int me4600_ao_query_number_channels(me_subdevice_t *subdevice,
 					   int *number);
 
-static int me4600_ao_query_subdevice_type(me_subdevice_t * subdevice,
+static int me4600_ao_query_subdevice_type(me_subdevice_t *subdevice,
 					  int *type, int *subtype);
 
-static int me4600_ao_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me4600_ao_query_subdevice_caps(me_subdevice_t *subdevice,
 					  int *caps);
 
 static int me4600_ao_query_subdevice_caps_args(struct me_subdevice *subdevice,
@@ -105,12 +105,12 @@
 
 /** Reset subdevice. Stop all actions. Reset registry. Disable FIFO. Set output to 0V and status to 'none'.
 */
-static int me4600_ao_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me4600_ao_io_reset_subdevice(me_subdevice_t *subdevice,
 					struct file *filep, int flags);
 
 /** Set output as single
 */
-static int me4600_ao_io_single_config(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_config(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int channel,
 				      int single_config,
@@ -120,103 +120,93 @@
 
 /** Pass to user actual value of output.
 */
-static int me4600_ao_io_single_read(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_read(me_subdevice_t *subdevice,
 				    struct file *filep,
 				    int channel,
 				    int *value, int time_out, int flags);
 
 /** Write to output requed value.
 */
-static int me4600_ao_io_single_write(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_write(me_subdevice_t *subdevice,
 				     struct file *filep,
 				     int channel,
 				     int value, int time_out, int flags);
 
 /** Set output as streamed device.
 */
-static int me4600_ao_io_stream_config(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_config(me_subdevice_t *subdevice,
 				      struct file *filep,
-				      meIOStreamConfig_t * config_list,
+				      meIOStreamConfig_t *config_list,
 				      int count,
-				      meIOStreamTrigger_t * trigger,
+				      meIOStreamTrigger_t *trigger,
 				      int fifo_irq_threshold, int flags);
 
 /** Wait for / Check empty space in buffer.
 */
-static int me4600_ao_io_stream_new_values(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_new_values(me_subdevice_t *subdevice,
 					  struct file *filep,
 					  int time_out, int *count, int flags);
 
 /** Start streaming.
 */
-static int me4600_ao_io_stream_start(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_start(me_subdevice_t *subdevice,
 				     struct file *filep,
 				     int start_mode, int time_out, int flags);
 
 /** Check actual state. / Wait for end.
 */
-static int me4600_ao_io_stream_status(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_status(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int wait,
 				      int *status, int *values, int flags);
 
 /** Stop streaming.
 */
-static int me4600_ao_io_stream_stop(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_stop(me_subdevice_t *subdevice,
 				    struct file *filep,
 				    int stop_mode, int flags);
 
 /** Write datas to buffor.
 */
-static int me4600_ao_io_stream_write(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_write(me_subdevice_t *subdevice,
 				     struct file *filep,
 				     int write_mode,
 				     int *values, int *count, int flags);
 
 /** Interrupt handler. Copy from buffer to FIFO.
 */
-static irqreturn_t me4600_ao_isr(int irq, void *dev_id
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
-				 , struct pt_regs *regs
-#endif
-    );
+static irqreturn_t me4600_ao_isr(int irq, void *dev_id);
 /** Copy data from circular buffer to fifo (fast) in wraparound mode.
 */
-int inline ao_write_data_wraparound(me4600_ao_subdevice_t * instance, int count,
+inline int ao_write_data_wraparound(me4600_ao_subdevice_t *instance, int count,
 				    int start_pos);
 
 /** Copy data from circular buffer to fifo (fast).
 */
-int inline ao_write_data(me4600_ao_subdevice_t * instance, int count,
+inline int ao_write_data(me4600_ao_subdevice_t *instance, int count,
 			 int start_pos);
 
 /** Copy data from circular buffer to fifo (slow).
 */
-int inline ao_write_data_pooling(me4600_ao_subdevice_t * instance, int count,
+inline int ao_write_data_pooling(me4600_ao_subdevice_t *instance, int count,
 				 int start_pos);
 
 /** Copy data from user space to circular buffer.
 */
-int inline ao_get_data_from_user(me4600_ao_subdevice_t * instance, int count,
+inline int ao_get_data_from_user(me4600_ao_subdevice_t *instance, int count,
 				 int *user_values);
 
 /** Stop presentation. Preserve FIFOs.
 */
-int inline ao_stop_immediately(me4600_ao_subdevice_t * instance);
+inline int ao_stop_immediately(me4600_ao_subdevice_t *instance);
 
 /** Task for asynchronical state verifying.
 */
-static void me4600_ao_work_control_task(
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-					       void *subdevice
-#else
-					       struct work_struct *work
-#endif
-    );
+static void me4600_ao_work_control_task(struct work_struct *work);
 /* Functions
  */
 
-static int me4600_ao_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me4600_ao_io_reset_subdevice(me_subdevice_t *subdevice,
 					struct file *filep, int flags)
 {
 	me4600_ao_subdevice_t *instance;
@@ -290,7 +280,7 @@
 	return err;
 }
 
-static int me4600_ao_io_single_config(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_config(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int channel,
 				      int single_config,
@@ -463,7 +453,7 @@
 	return err;
 }
 
-static int me4600_ao_io_single_read(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_read(me_subdevice_t *subdevice,
 				    struct file *filep,
 				    int channel,
 				    int *value, int time_out, int flags)
@@ -547,7 +537,7 @@
 	return err;
 }
 
-static int me4600_ao_io_single_write(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_write(me_subdevice_t *subdevice,
 				     struct file *filep,
 				     int channel,
 				     int value, int time_out, int flags)
@@ -989,11 +979,11 @@
 	return err;
 }
 
-static int me4600_ao_io_stream_config(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_config(me_subdevice_t *subdevice,
 				      struct file *filep,
-				      meIOStreamConfig_t * config_list,
+				      meIOStreamConfig_t *config_list,
 				      int count,
-				      meIOStreamTrigger_t * trigger,
+				      meIOStreamTrigger_t *trigger,
 				      int fifo_irq_threshold, int flags)
 {
 	me4600_ao_subdevice_t *instance;
@@ -1025,7 +1015,7 @@
 	}
 
 	if (flags & ME_IO_STREAM_CONFIG_HARDWARE_ONLY) {
-		if (!flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
+		if (!(flags & ME_IO_STREAM_CONFIG_WRAPAROUND)) {
 			PERROR
 			    ("Hardware ME_IO_STREAM_CONFIG_HARDWARE_ONLY has to be with ME_IO_STREAM_CONFIG_WRAPAROUND.\n");
 			return ME_ERRNO_INVALID_FLAGS;
@@ -1327,7 +1317,7 @@
 	return err;
 }
 
-static int me4600_ao_io_stream_new_values(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_new_values(me_subdevice_t *subdevice,
 					  struct file *filep,
 					  int time_out, int *count, int flags)
 {
@@ -1408,7 +1398,7 @@
 	return err;
 }
 
-static int me4600_ao_io_stream_start(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_start(me_subdevice_t *subdevice,
 				     struct file *filep,
 				     int start_mode, int time_out, int flags)
 {
@@ -1845,7 +1835,7 @@
 	return err;
 }
 
-static int me4600_ao_io_stream_status(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_status(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int wait,
 				      int *status, int *values, int flags)
@@ -1943,7 +1933,7 @@
 	return err;
 }
 
-static int me4600_ao_io_stream_stop(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_stop(me_subdevice_t *subdevice,
 				    struct file *filep,
 				    int stop_mode, int flags)
 {				// Stop work and empty buffer and FIFO
@@ -2048,7 +2038,7 @@
 	return err;
 }
 
-static int me4600_ao_io_stream_write(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_write(me_subdevice_t *subdevice,
 				     struct file *filep,
 				     int write_mode,
 				     int *values, int *count, int flags)
@@ -2272,11 +2262,7 @@
 
 	return err;
 }
-static irqreturn_t me4600_ao_isr(int irq, void *dev_id
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
-				 , struct pt_regs *regs
-#endif
-    )
+static irqreturn_t me4600_ao_isr(int irq, void *dev_id)
 {
 	me4600_ao_subdevice_t *instance = dev_id;
 	uint32_t irq_status;
@@ -2498,8 +2484,8 @@
 }
 
 me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base,
-					     spinlock_t * preload_reg_lock,
-					     uint32_t * preload_flags,
+					     spinlock_t *preload_reg_lock,
+					     uint32_t *preload_flags,
 					     int ao_idx,
 					     int fifo,
 					     int irq,
@@ -2689,13 +2675,8 @@
 	subdevice->me4600_workqueue = me4600_wq;
 
 /* workqueue API changed in kernel 2.6.20 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) )
-	INIT_WORK(&subdevice->ao_control_task, me4600_ao_work_control_task,
-		  (void *)subdevice);
-#else
 	INIT_DELAYED_WORK(&subdevice->ao_control_task,
 			  me4600_ao_work_control_task);
-#endif
 
 	if (subdevice->fifo) {	// Set speed for single operations.
 		outl(ME4600_AO_MIN_CHAN_TICKS - 1, subdevice->timer_reg);
@@ -2709,7 +2690,7 @@
 *
 * @param instance The subdevice instance (pointer).
 */
-int inline ao_stop_immediately(me4600_ao_subdevice_t * instance)
+inline int ao_stop_immediately(me4600_ao_subdevice_t *instance)
 {
 	unsigned long cpu_flags;
 	uint32_t ctrl;
@@ -2762,7 +2743,7 @@
 * @return On error/success: 0.	No datas were copied => no data in buffer.
 * @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW.
 */
-int inline ao_write_data_wraparound(me4600_ao_subdevice_t * instance, int count,
+inline int ao_write_data_wraparound(me4600_ao_subdevice_t *instance, int count,
 				    int start_pos)
 {				/// @note This is time critical function!
 	uint32_t status;
@@ -2827,7 +2808,7 @@
 * @return On error/success: 0.	No datas were copied => no data in buffer.
 * @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW.
 */
-int inline ao_write_data(me4600_ao_subdevice_t * instance, int count,
+inline int ao_write_data(me4600_ao_subdevice_t *instance, int count,
 			 int start_pos)
 {				/// @note This is time critical function!
 	uint32_t status;
@@ -2897,7 +2878,7 @@
 * @return On error/success: 0.	FIFO was full at begining.
 * @return On error: -ME_ERRNO_RING_BUFFER_UNDEFFLOW.
 */
-int inline ao_write_data_pooling(me4600_ao_subdevice_t * instance, int count,
+inline int ao_write_data_pooling(me4600_ao_subdevice_t *instance, int count,
 				 int start_pos)
 {				/// @note This is slow function!
 	uint32_t status;
@@ -2955,7 +2936,7 @@
 * @return On success: Number of copied values.
 * @return On error: -ME_ERRNO_INTERNAL.
 */
-int inline ao_get_data_from_user(me4600_ao_subdevice_t * instance, int count,
+inline int ao_get_data_from_user(me4600_ao_subdevice_t *instance, int count,
 				 int *user_values)
 {
 	int i, err;
@@ -2987,13 +2968,7 @@
 /** @brief Checking actual hardware and logical state.
 * @param instance The subdevice instance (pointer).
 */
-static void me4600_ao_work_control_task(
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-					       void *subdevice
-#else
-					       struct work_struct *work
-#endif
-    )
+static void me4600_ao_work_control_task(struct work_struct *work)
 {
 	me4600_ao_subdevice_t *instance;
 	unsigned long cpu_flags = 0;
@@ -3003,12 +2978,8 @@
 	int reschedule = 0;
 	int signaling = 0;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-	instance = (me4600_ao_subdevice_t *) subdevice;
-#else
 	instance =
 	    container_of((void *)work, me4600_ao_subdevice_t, ao_control_task);
-#endif
 	PINFO("<%s: %ld> executed. idx=%d\n", __func__, jiffies,
 	      instance->ao_idx);
 
@@ -3323,7 +3294,7 @@
 #else
 /// @note SPECIAL BUILD FOR BOSCH
 /// @author Guenter Gebhardt
-static int me4600_ao_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me4600_ao_io_reset_subdevice(me_subdevice_t *subdevice,
 					struct file *filep, int flags)
 {
 	me4600_ao_subdevice_t *instance;
@@ -3365,7 +3336,7 @@
 	return err;
 }
 
-static int me4600_ao_io_single_config(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_config(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int channel,
 				      int single_config,
@@ -3636,7 +3607,7 @@
 		goto ERROR;
 	}
 
-      ERROR:
+ERROR:
 
 	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
 
@@ -3645,7 +3616,7 @@
 	return err;
 }
 
-static int me4600_ao_io_single_read(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_read(me_subdevice_t *subdevice,
 				    struct file *filep,
 				    int channel,
 				    int *value, int time_out, int flags)
@@ -3682,7 +3653,7 @@
 	return err;
 }
 
-static int me4600_ao_io_single_write(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_write(me_subdevice_t *subdevice,
 				     struct file *filep,
 				     int channel,
 				     int value, int time_out, int flags)
@@ -3830,18 +3801,18 @@
 		spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
 	}
 
-      ERROR:
+ERROR:
 
 	ME_SUBDEVICE_EXIT;
 
 	return err;
 }
 
-static int me4600_ao_io_stream_config(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_config(me_subdevice_t *subdevice,
 				      struct file *filep,
-				      meIOStreamConfig_t * config_list,
+				      meIOStreamConfig_t *config_list,
 				      int count,
-				      meIOStreamTrigger_t * trigger,
+				      meIOStreamTrigger_t *trigger,
 				      int fifo_irq_threshold, int flags)
 {
 	me4600_ao_subdevice_t *instance;
@@ -4150,7 +4121,7 @@
 	PDEBUG("Ctrl word = 0x%lX.\n", ctrl);
 	outl(ctrl, instance->ctrl_reg);	// Write the control word
 
-      ERROR:
+ERROR:
 
 	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
 
@@ -4159,7 +4130,7 @@
 	return err;
 }
 
-static int me4600_ao_io_stream_new_values(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_new_values(me_subdevice_t *subdevice,
 					  struct file *filep,
 					  int time_out, int *count, int flags)
 {
@@ -4238,7 +4209,7 @@
 	return err;
 }
 
-static void stop_immediately(me4600_ao_subdevice_t * instance)
+static void stop_immediately(me4600_ao_subdevice_t *instance)
 {
 	unsigned long cpu_flags;
 	uint32_t tmp;
@@ -4253,7 +4224,7 @@
 	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
 }
 
-static int me4600_ao_io_stream_start(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_start(me_subdevice_t *subdevice,
 				     struct file *filep,
 				     int start_mode, int time_out, int flags)
 {
@@ -4778,14 +4749,14 @@
 		goto ERROR;
 	}
 
-      ERROR:
+ERROR:
 
 	ME_SUBDEVICE_EXIT;
 
 	return err;
 }
 
-static int me4600_ao_io_stream_status(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_status(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int wait,
 				      int *status, int *values, int flags)
@@ -4842,14 +4813,14 @@
 		goto ERROR;
 	}
 
-      ERROR:
+ERROR:
 
 	ME_SUBDEVICE_EXIT;
 
 	return err;
 }
 
-static int me4600_ao_io_stream_stop(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_stop(me_subdevice_t *subdevice,
 				    struct file *filep,
 				    int stop_mode, int flags)
 {
@@ -4891,14 +4862,14 @@
 		goto ERROR;
 	}
 
-      ERROR:
+ERROR:
 
 	ME_SUBDEVICE_EXIT;
 
 	return err;
 }
 
-static int me4600_ao_io_stream_write(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_write(me_subdevice_t *subdevice,
 				     struct file *filep,
 				     int write_mode,
 				     int *values, int *count, int flags)
@@ -5432,18 +5403,14 @@
 		goto ERROR;
 	}
 
-      ERROR:
+ERROR:
 
 	ME_SUBDEVICE_EXIT;
 
 	return err;
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
 static irqreturn_t me4600_ao_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me4600_ao_isr(int irq, void *dev_id, struct pt_regs *regs)
-#endif
 {
 	unsigned long tmp;
 	int value;
@@ -5660,8 +5627,8 @@
 }
 
 me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base,
-					     spinlock_t * preload_reg_lock,
-					     uint32_t * preload_flags,
+					     spinlock_t *preload_reg_lock,
+					     uint32_t *preload_flags,
 					     int ao_idx, int fifo, int irq)
 {
 	me4600_ao_subdevice_t *subdevice;
@@ -5823,7 +5790,7 @@
 /* Common functions
 */
 
-static int me4600_ao_query_range_by_min_max(me_subdevice_t * subdevice,
+static int me4600_ao_query_range_by_min_max(me_subdevice_t *subdevice,
 					    int unit,
 					    int *min,
 					    int *max, int *maxdata, int *range)
@@ -5858,7 +5825,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me4600_ao_query_number_ranges(me_subdevice_t * subdevice,
+static int me4600_ao_query_number_ranges(me_subdevice_t *subdevice,
 					 int unit, int *count)
 {
 	me4600_ao_subdevice_t *instance;
@@ -5876,7 +5843,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me4600_ao_query_range_info(me_subdevice_t * subdevice,
+static int me4600_ao_query_range_info(me_subdevice_t *subdevice,
 				      int range,
 				      int *unit,
 				      int *min, int *max, int *maxdata)
@@ -5900,7 +5867,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me4600_ao_query_timer(me_subdevice_t * subdevice,
+static int me4600_ao_query_timer(me_subdevice_t *subdevice,
 				 int timer,
 				 int *base_frequency,
 				 long long *min_ticks, long long *max_ticks)
@@ -5934,7 +5901,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me4600_ao_query_number_channels(me_subdevice_t * subdevice,
+static int me4600_ao_query_number_channels(me_subdevice_t *subdevice,
 					   int *number)
 {
 	me4600_ao_subdevice_t *instance;
@@ -5947,7 +5914,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me4600_ao_query_subdevice_type(me_subdevice_t * subdevice,
+static int me4600_ao_query_subdevice_type(me_subdevice_t *subdevice,
 					  int *type, int *subtype)
 {
 	me4600_ao_subdevice_t *instance;
@@ -5962,7 +5929,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me4600_ao_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me4600_ao_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
 {
 	me4600_ao_subdevice_t *instance;
 	instance = (me4600_ao_subdevice_t *) subdevice;
diff --git a/drivers/staging/meilhaus/me4600_ao.h b/drivers/staging/meilhaus/me4600_ao.h
index 6fbc4a2..7579435 100644
--- a/drivers/staging/meilhaus/me4600_ao.h
+++ b/drivers/staging/meilhaus/me4600_ao.h
@@ -225,11 +225,7 @@
 	wait_queue_head_t wait_queue;				/**< Wait queue to put on tasks waiting for data to arrive. */
 
 	struct workqueue_struct *me4600_workqueue;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-	struct work_struct ao_control_task;
-#else
 	struct delayed_work ao_control_task;
-#endif
 
 	volatile int ao_control_task_flag;			/**< Flag controling reexecuting of control task */
 
diff --git a/drivers/staging/meilhaus/me4600_device.c b/drivers/staging/meilhaus/me4600_device.c
index fa45584..457666e 100644
--- a/drivers/staging/meilhaus/me4600_device.c
+++ b/drivers/staging/meilhaus/me4600_device.c
@@ -336,6 +336,7 @@
 
 	return (me_device_t *) me4600_device;
 }
+EXPORT_SYMBOL(me4600_pci_constructor);
 
 // Init and exit of module.
 
@@ -368,6 +369,3 @@
 MODULE_DESCRIPTION("Device Driver Module for ME-46xx Devices");
 MODULE_SUPPORTED_DEVICE("Meilhaus ME-46xx Devices");
 MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me4600_pci_constructor);
diff --git a/drivers/staging/meilhaus/me4600_di.c b/drivers/staging/meilhaus/me4600_di.c
index 7e3c9f4..e107e50 100644
--- a/drivers/staging/meilhaus/me4600_di.c
+++ b/drivers/staging/meilhaus/me4600_di.c
@@ -36,7 +36,7 @@
 
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/types.h>
 
 #include "medefines.h"
@@ -91,7 +91,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me4600_di_io_single_config(me_subdevice_t * subdevice,
+static int me4600_di_io_single_config(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int channel,
 				      int single_config,
@@ -133,7 +133,7 @@
 	return err;
 }
 
-static int me4600_di_io_single_read(me_subdevice_t * subdevice,
+static int me4600_di_io_single_read(me_subdevice_t *subdevice,
 				    struct file *filep,
 				    int channel,
 				    int *value, int time_out, int flags)
@@ -177,7 +177,7 @@
 	return err;
 }
 
-static int me4600_di_query_number_channels(me_subdevice_t * subdevice,
+static int me4600_di_query_number_channels(me_subdevice_t *subdevice,
 					   int *number)
 {
 	PDEBUG("executed.\n");
@@ -185,7 +185,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me4600_di_query_subdevice_type(me_subdevice_t * subdevice,
+static int me4600_di_query_subdevice_type(me_subdevice_t *subdevice,
 					  int *type, int *subtype)
 {
 	PDEBUG("executed.\n");
@@ -194,7 +194,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me4600_di_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me4600_di_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
 {
 	PDEBUG("executed.\n");
 	*caps = 0;
@@ -202,7 +202,7 @@
 }
 
 me4600_di_subdevice_t *me4600_di_constructor(uint32_t reg_base,
-					     spinlock_t * ctrl_reg_lock)
+					     spinlock_t *ctrl_reg_lock)
 {
 	me4600_di_subdevice_t *subdevice;
 	int err;
diff --git a/drivers/staging/meilhaus/me4600_dio.c b/drivers/staging/meilhaus/me4600_dio.c
index 0af95d1..baa28ff 100644
--- a/drivers/staging/meilhaus/me4600_dio.c
+++ b/drivers/staging/meilhaus/me4600_dio.c
@@ -36,7 +36,7 @@
 
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/types.h>
 
 #include "medefines.h"
@@ -94,7 +94,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me4600_dio_io_single_config(me_subdevice_t * subdevice,
+static int me4600_dio_io_single_config(me_subdevice_t *subdevice,
 				       struct file *filep,
 				       int channel,
 				       int single_config,
@@ -268,7 +268,7 @@
 	return err;
 }
 
-static int me4600_dio_io_single_read(me_subdevice_t * subdevice,
+static int me4600_dio_io_single_read(me_subdevice_t *subdevice,
 				     struct file *filep,
 				     int channel,
 				     int *value, int time_out, int flags)
@@ -342,7 +342,7 @@
 	return err;
 }
 
-static int me4600_dio_io_single_write(me_subdevice_t * subdevice,
+static int me4600_dio_io_single_write(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int channel,
 				      int value, int time_out, int flags)
@@ -425,7 +425,7 @@
 	return err;
 }
 
-static int me4600_dio_query_number_channels(me_subdevice_t * subdevice,
+static int me4600_dio_query_number_channels(me_subdevice_t *subdevice,
 					    int *number)
 {
 	PDEBUG("executed.\n");
@@ -433,7 +433,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me4600_dio_query_subdevice_type(me_subdevice_t * subdevice,
+static int me4600_dio_query_subdevice_type(me_subdevice_t *subdevice,
 					   int *type, int *subtype)
 {
 	PDEBUG("executed.\n");
@@ -442,7 +442,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me4600_dio_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me4600_dio_query_subdevice_caps(me_subdevice_t *subdevice,
 					   int *caps)
 {
 	PDEBUG("executed.\n");
@@ -452,7 +452,7 @@
 
 me4600_dio_subdevice_t *me4600_dio_constructor(uint32_t reg_base,
 					       unsigned int dio_idx,
-					       spinlock_t * ctrl_reg_lock)
+					       spinlock_t *ctrl_reg_lock)
 {
 	me4600_dio_subdevice_t *subdevice;
 	int err;
diff --git a/drivers/staging/meilhaus/me4600_do.c b/drivers/staging/meilhaus/me4600_do.c
index ee591bc..39510f3 100644
--- a/drivers/staging/meilhaus/me4600_do.c
+++ b/drivers/staging/meilhaus/me4600_do.c
@@ -36,7 +36,7 @@
 
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/types.h>
 
 #include "medefines.h"
@@ -93,7 +93,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me4600_do_io_single_config(me_subdevice_t * subdevice,
+static int me4600_do_io_single_config(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int channel,
 				      int single_config,
@@ -224,7 +224,7 @@
 	return err;
 }
 
-static int me4600_do_io_single_read(me_subdevice_t * subdevice,
+static int me4600_do_io_single_read(me_subdevice_t *subdevice,
 				    struct file *filep,
 				    int channel,
 				    int *value, int time_out, int flags)
@@ -284,7 +284,7 @@
 	return err;
 }
 
-static int me4600_do_io_single_write(me_subdevice_t * subdevice,
+static int me4600_do_io_single_write(me_subdevice_t *subdevice,
 				     struct file *filep,
 				     int channel,
 				     int value, int time_out, int flags)
@@ -352,7 +352,7 @@
 	return err;
 }
 
-static int me4600_do_query_number_channels(me_subdevice_t * subdevice,
+static int me4600_do_query_number_channels(me_subdevice_t *subdevice,
 					   int *number)
 {
 	PDEBUG("executed.\n");
@@ -360,7 +360,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me4600_do_query_subdevice_type(me_subdevice_t * subdevice,
+static int me4600_do_query_subdevice_type(me_subdevice_t *subdevice,
 					  int *type, int *subtype)
 {
 	PDEBUG("executed.\n");
@@ -369,7 +369,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me4600_do_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me4600_do_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
 {
 	PDEBUG("executed.\n");
 	*caps = 0;
@@ -377,7 +377,7 @@
 }
 
 me4600_do_subdevice_t *me4600_do_constructor(uint32_t reg_base,
-					     spinlock_t * ctrl_reg_lock)
+					     spinlock_t *ctrl_reg_lock)
 {
 	me4600_do_subdevice_t *subdevice;
 	int err;
diff --git a/drivers/staging/meilhaus/me4600_ext_irq.c b/drivers/staging/meilhaus/me4600_ext_irq.c
index adc1e1ba..6b33cba 100644
--- a/drivers/staging/meilhaus/me4600_ext_irq.c
+++ b/drivers/staging/meilhaus/me4600_ext_irq.c
@@ -37,7 +37,7 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/types.h>
 #include <linux/version.h>
 
@@ -60,7 +60,7 @@
  * Functions
  */
 
-static int me4600_ext_irq_io_irq_start(me_subdevice_t * subdevice,
+static int me4600_ext_irq_io_irq_start(me_subdevice_t *subdevice,
 				       struct file *filep,
 				       int channel,
 				       int irq_source,
@@ -135,7 +135,7 @@
 	return err;
 }
 
-static int me4600_ext_irq_io_irq_wait(me_subdevice_t * subdevice,
+static int me4600_ext_irq_io_irq_wait(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int channel,
 				      int *irq_count,
@@ -214,7 +214,7 @@
 	return err;
 }
 
-static int me4600_ext_irq_io_irq_stop(me_subdevice_t * subdevice,
+static int me4600_ext_irq_io_irq_stop(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int channel, int flags)
 {
@@ -256,7 +256,7 @@
 	return err;
 }
 
-static int me4600_ext_irq_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me4600_ext_irq_io_reset_subdevice(me_subdevice_t *subdevice,
 					     struct file *filep, int flags)
 {
 	me4600_ext_irq_subdevice_t *instance;
@@ -308,7 +308,7 @@
 	kfree(instance);
 }
 
-static int me4600_ext_irq_query_number_channels(me_subdevice_t * subdevice,
+static int me4600_ext_irq_query_number_channels(me_subdevice_t *subdevice,
 						int *number)
 {
 	PDEBUG("executed.\n");
@@ -316,7 +316,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me4600_ext_irq_query_subdevice_type(me_subdevice_t * subdevice,
+static int me4600_ext_irq_query_subdevice_type(me_subdevice_t *subdevice,
 					       int *type, int *subtype)
 {
 	PDEBUG("executed.\n");
@@ -325,7 +325,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me4600_ext_irq_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me4600_ext_irq_query_subdevice_caps(me_subdevice_t *subdevice,
 					       int *caps)
 {
 	PDEBUG("executed.\n");
@@ -335,12 +335,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
 static irqreturn_t me4600_ext_irq_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me4600_ext_irq_isr(int irq, void *dev_id,
-				      struct pt_regs *regs)
-#endif
 {
 	me4600_ext_irq_subdevice_t *instance;
 	uint32_t ctrl;
diff --git a/drivers/staging/meilhaus/me6000_ao.c b/drivers/staging/meilhaus/me6000_ao.c
index 94f0123..f7abdbd 100644
--- a/drivers/staging/meilhaus/me6000_ao.c
+++ b/drivers/staging/meilhaus/me6000_ao.c
@@ -36,8 +36,8 @@
 
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
@@ -57,31 +57,31 @@
 /* Defines
  */
 
-static int me6000_ao_query_range_by_min_max(me_subdevice_t * subdevice,
+static int me6000_ao_query_range_by_min_max(me_subdevice_t *subdevice,
 					    int unit,
 					    int *min,
 					    int *max, int *maxdata, int *range);
 
-static int me6000_ao_query_number_ranges(me_subdevice_t * subdevice,
+static int me6000_ao_query_number_ranges(me_subdevice_t *subdevice,
 					 int unit, int *count);
 
-static int me6000_ao_query_range_info(me_subdevice_t * subdevice,
+static int me6000_ao_query_range_info(me_subdevice_t *subdevice,
 				      int range,
 				      int *unit,
 				      int *min, int *max, int *maxdata);
 
-static int me6000_ao_query_timer(me_subdevice_t * subdevice,
+static int me6000_ao_query_timer(me_subdevice_t *subdevice,
 				 int timer,
 				 int *base_frequency,
 				 long long *min_ticks, long long *max_ticks);
 
-static int me6000_ao_query_number_channels(me_subdevice_t * subdevice,
+static int me6000_ao_query_number_channels(me_subdevice_t *subdevice,
 					   int *number);
 
-static int me6000_ao_query_subdevice_type(me_subdevice_t * subdevice,
+static int me6000_ao_query_subdevice_type(me_subdevice_t *subdevice,
 					  int *type, int *subtype);
 
-static int me6000_ao_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me6000_ao_query_subdevice_caps(me_subdevice_t *subdevice,
 					  int *caps);
 
 static int me6000_ao_query_subdevice_caps_args(struct me_subdevice *subdevice,
@@ -91,11 +91,11 @@
 static void me6000_ao_destructor(struct me_subdevice *subdevice);
 
 /** Reset subdevice. Stop all actions. Reset registry. Disable FIFO. Set output to 0V and status to 'none'. */
-static int me6000_ao_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me6000_ao_io_reset_subdevice(me_subdevice_t *subdevice,
 					struct file *filep, int flags);
 
 /** Set output as single */
-static int me6000_ao_io_single_config(me_subdevice_t * subdevice,
+static int me6000_ao_io_single_config(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int channel,
 				      int single_config,
@@ -104,89 +104,81 @@
 				      int trig_type, int trig_edge, int flags);
 
 /** Pass to user actual value of output. */
-static int me6000_ao_io_single_read(me_subdevice_t * subdevice,
+static int me6000_ao_io_single_read(me_subdevice_t *subdevice,
 				    struct file *filep,
 				    int channel,
 				    int *value, int time_out, int flags);
 
 /** Write to output requed value. */
-static int me6000_ao_io_single_write(me_subdevice_t * subdevice,
+static int me6000_ao_io_single_write(me_subdevice_t *subdevice,
 				     struct file *filep,
 				     int channel,
 				     int value, int time_out, int flags);
 
 /** Set output as streamed device. */
-static int me6000_ao_io_stream_config(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_config(me_subdevice_t *subdevice,
 				      struct file *filep,
-				      meIOStreamConfig_t * config_list,
+				      meIOStreamConfig_t *config_list,
 				      int count,
-				      meIOStreamTrigger_t * trigger,
+				      meIOStreamTrigger_t *trigger,
 				      int fifo_irq_threshold, int flags);
 
 /** Wait for / Check empty space in buffer. */
-static int me6000_ao_io_stream_new_values(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_new_values(me_subdevice_t *subdevice,
 					  struct file *filep,
 					  int time_out, int *count, int flags);
 
 /** Start streaming. */
-static int me6000_ao_io_stream_start(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_start(me_subdevice_t *subdevice,
 				     struct file *filep,
 				     int start_mode, int time_out, int flags);
 
 /** Check actual state. / Wait for end. */
-static int me6000_ao_io_stream_status(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_status(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int wait,
 				      int *status, int *values, int flags);
 
 /** Stop streaming. */
-static int me6000_ao_io_stream_stop(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_stop(me_subdevice_t *subdevice,
 				    struct file *filep,
 				    int stop_mode, int flags);
 
 /** Write datas to buffor. */
-static int me6000_ao_io_stream_write(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_write(me_subdevice_t *subdevice,
 				     struct file *filep,
 				     int write_mode,
 				     int *values, int *count, int flags);
 
 /** Interrupt handler. Copy from buffer to FIFO. */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
 static irqreturn_t me6000_ao_isr(int irq, void *dev_id);
-#else
-static irqreturn_t me6000_ao_isr(int irq, void *dev_id, struct pt_regs *regs);
-#endif
 
 /** Copy data from circular buffer to fifo (fast) in wraparound mode. */
-int inline ao_write_data_wraparound(me6000_ao_subdevice_t * instance, int count,
+inline int ao_write_data_wraparound(me6000_ao_subdevice_t *instance, int count,
 				    int start_pos);
 
 /** Copy data from circular buffer to fifo (fast).*/
-int inline ao_write_data(me6000_ao_subdevice_t * instance, int count,
+inline int ao_write_data(me6000_ao_subdevice_t *instance, int count,
 			 int start_pos);
 
 /** Copy data from circular buffer to fifo (slow).*/
-int inline ao_write_data_pooling(me6000_ao_subdevice_t * instance, int count,
+inline int ao_write_data_pooling(me6000_ao_subdevice_t *instance, int count,
 				 int start_pos);
 
 /** Copy data from user space to circular buffer. */
-int inline ao_get_data_from_user(me6000_ao_subdevice_t * instance, int count,
+inline int ao_get_data_from_user(me6000_ao_subdevice_t *instance, int count,
 				 int *user_values);
 
 /** Stop presentation. Preserve FIFOs. */
-int inline ao_stop_immediately(me6000_ao_subdevice_t * instance);
+inline int ao_stop_immediately(me6000_ao_subdevice_t *instance);
 
 /** Function for checking timeout in non-blocking mode. */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-static void me6000_ao_work_control_task(void *subdevice);
-#else
 static void me6000_ao_work_control_task(struct work_struct *work);
-#endif
 
 /* Functions
  */
 
-static int me6000_ao_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me6000_ao_io_reset_subdevice(me_subdevice_t *subdevice,
 					struct file *filep, int flags)
 {
 	me6000_ao_subdevice_t *instance;
@@ -274,7 +266,7 @@
 	return err;
 }
 
-static int me6000_ao_io_single_config(me_subdevice_t * subdevice,
+static int me6000_ao_io_single_config(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int channel,
 				      int single_config,
@@ -473,7 +465,7 @@
 	return err;
 }
 
-static int me6000_ao_io_single_read(me_subdevice_t * subdevice,
+static int me6000_ao_io_single_read(me_subdevice_t *subdevice,
 				    struct file *filep,
 				    int channel,
 				    int *value, int time_out, int flags)
@@ -555,7 +547,7 @@
 	return err;
 }
 
-static int me6000_ao_io_single_write(me_subdevice_t * subdevice,
+static int me6000_ao_io_single_write(me_subdevice_t *subdevice,
 				     struct file *filep,
 				     int channel,
 				     int value, int time_out, int flags)
@@ -1027,11 +1019,11 @@
 	return err;
 }
 
-static int me6000_ao_io_stream_config(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_config(me_subdevice_t *subdevice,
 				      struct file *filep,
-				      meIOStreamConfig_t * config_list,
+				      meIOStreamConfig_t *config_list,
 				      int count,
-				      meIOStreamTrigger_t * trigger,
+				      meIOStreamTrigger_t *trigger,
 				      int fifo_irq_threshold, int flags)
 {
 	me6000_ao_subdevice_t *instance;
@@ -1063,7 +1055,7 @@
 	}
 
 	if (flags & ME_IO_STREAM_CONFIG_HARDWARE_ONLY) {
-		if (!flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
+		if (!(flags & ME_IO_STREAM_CONFIG_WRAPAROUND)) {
 			PERROR
 			    ("Hardware ME_IO_STREAM_CONFIG_HARDWARE_ONLY has to be with ME_IO_STREAM_CONFIG_WRAPAROUND.\n");
 			return ME_ERRNO_INVALID_FLAGS;
@@ -1359,7 +1351,7 @@
 	return err;
 }
 
-static int me6000_ao_io_stream_new_values(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_new_values(me_subdevice_t *subdevice,
 					  struct file *filep,
 					  int time_out, int *count, int flags)
 {
@@ -1440,7 +1432,7 @@
 	return err;
 }
 
-static int me6000_ao_io_stream_start(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_start(me_subdevice_t *subdevice,
 				     struct file *filep,
 				     int start_mode, int time_out, int flags)
 {
@@ -1889,7 +1881,7 @@
 	return err;
 }
 
-static int me6000_ao_io_stream_status(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_status(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int wait,
 				      int *status, int *values, int flags)
@@ -1987,7 +1979,7 @@
 	return err;
 }
 
-static int me6000_ao_io_stream_stop(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_stop(me_subdevice_t *subdevice,
 				    struct file *filep,
 				    int stop_mode, int flags)
 {				/// @note Stop work and empty buffer and FIFO
@@ -2094,7 +2086,7 @@
 	return err;
 }
 
-static int me6000_ao_io_stream_write(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_write(me_subdevice_t *subdevice,
 				     struct file *filep,
 				     int write_mode,
 				     int *values, int *count, int flags)
@@ -2324,11 +2316,7 @@
 	return err;
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
 static irqreturn_t me6000_ao_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me6000_ao_isr(int irq, void *dev_id, struct pt_regs *regs)
-#endif
 {
 	me6000_ao_subdevice_t *instance = dev_id;
 	uint32_t irq_status;
@@ -2544,9 +2532,9 @@
 }
 
 me6000_ao_subdevice_t *me6000_ao_constructor(uint32_t reg_base,
-					     spinlock_t * preload_reg_lock,
-					     uint32_t * preload_flags,
-					     uint32_t * triggering_flags,
+					     spinlock_t *preload_reg_lock,
+					     uint32_t *preload_flags,
+					     uint32_t *triggering_flags,
 					     int ao_idx,
 					     int fifo,
 					     int irq,
@@ -2797,13 +2785,8 @@
 	subdevice->me6000_workqueue = me6000_wq;
 
 /* workqueue API changed in kernel 2.6.20 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) )
-	INIT_WORK(&subdevice->ao_control_task, me6000_ao_work_control_task,
-		  (void *)subdevice);
-#else
 	INIT_DELAYED_WORK(&subdevice->ao_control_task,
 			  me6000_ao_work_control_task);
-#endif
 
 	if (subdevice->fifo) {	//Set speed
 		outl(ME6000_AO_MIN_CHAN_TICKS - 1, subdevice->timer_reg);
@@ -2817,7 +2800,7 @@
 *
 * @param instance The subdevice instance (pointer).
 */
-int inline ao_stop_immediately(me6000_ao_subdevice_t * instance)
+inline int ao_stop_immediately(me6000_ao_subdevice_t *instance)
 {
 	unsigned long cpu_flags;
 	uint32_t ctrl;
@@ -2825,10 +2808,11 @@
 	int i;
 	uint32_t single_mask;
 
-	single_mask =
-	    (instance->ao_idx - ME6000_AO_SINGLE_STATUS_OFFSET <
-	     0) ? 0x0000 : (0x0001 << (instance->ao_idx -
-				       ME6000_AO_SINGLE_STATUS_OFFSET));
+	if (instance->ao_idx < ME6000_AO_SINGLE_STATUS_OFFSET)
+		single_mask = 0x0000;
+	else
+		single_mask = 0x0001 << (instance->ao_idx -
+				ME6000_AO_SINGLE_STATUS_OFFSET);
 
 	timeout =
 	    (instance->hardware_stop_delay >
@@ -2887,7 +2871,7 @@
 * @return On error/success: 0.	No datas were copied => no data in buffer.
 * @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW.
 */
-int inline ao_write_data_wraparound(me6000_ao_subdevice_t * instance, int count,
+inline int ao_write_data_wraparound(me6000_ao_subdevice_t *instance, int count,
 				    int start_pos)
 {				/// @note This is time critical function!
 	uint32_t status;
@@ -2952,7 +2936,7 @@
 * @return On error/success: 0.	No datas were copied => no data in buffer.
 * @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW.
 */
-int inline ao_write_data(me6000_ao_subdevice_t * instance, int count,
+inline int ao_write_data(me6000_ao_subdevice_t *instance, int count,
 			 int start_pos)
 {				/// @note This is time critical function!
 	uint32_t status;
@@ -3022,7 +3006,7 @@
 * @return On error/success: 0.	FIFO was full at begining.
 * @return On error: -ME_ERRNO_RING_BUFFER_UNDEFFLOW.
 */
-int inline ao_write_data_pooling(me6000_ao_subdevice_t * instance, int count,
+inline int ao_write_data_pooling(me6000_ao_subdevice_t *instance, int count,
 				 int start_pos)
 {				/// @note This is slow function!
 	uint32_t status;
@@ -3080,7 +3064,7 @@
 * @return On success: Number of copied values.
 * @return On error: -ME_ERRNO_INTERNAL.
 */
-int inline ao_get_data_from_user(me6000_ao_subdevice_t * instance, int count,
+inline int ao_get_data_from_user(me6000_ao_subdevice_t *instance, int count,
 				 int *user_values)
 {
 	int i, err;
@@ -3109,13 +3093,7 @@
 	return copied;
 }
 
-static void me6000_ao_work_control_task(
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-					       void *subdevice
-#else
-					       struct work_struct *work
-#endif
-    )
+static void me6000_ao_work_control_task(struct work_struct *work)
 {
 	me6000_ao_subdevice_t *instance;
 	unsigned long cpu_flags = 0;
@@ -3126,12 +3104,8 @@
 	int signaling = 0;
 	uint32_t single_mask;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-	instance = (me6000_ao_subdevice_t *) subdevice;
-#else
 	instance =
 	    container_of((void *)work, me6000_ao_subdevice_t, ao_control_task);
-#endif
 	PINFO("<%s: %ld> executed. idx=%d\n", __func__, jiffies,
 	      instance->ao_idx);
 
@@ -3555,7 +3529,7 @@
 
 }
 
-static int me6000_ao_query_range_by_min_max(me_subdevice_t * subdevice,
+static int me6000_ao_query_range_by_min_max(me_subdevice_t *subdevice,
 					    int unit,
 					    int *min,
 					    int *max, int *maxdata, int *range)
@@ -3589,7 +3563,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me6000_ao_query_number_ranges(me_subdevice_t * subdevice,
+static int me6000_ao_query_number_ranges(me_subdevice_t *subdevice,
 					 int unit, int *count)
 {
 	me6000_ao_subdevice_t *instance;
@@ -3607,7 +3581,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me6000_ao_query_range_info(me_subdevice_t * subdevice,
+static int me6000_ao_query_range_info(me_subdevice_t *subdevice,
 				      int range,
 				      int *unit,
 				      int *min, int *max, int *maxdata)
@@ -3631,7 +3605,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me6000_ao_query_timer(me_subdevice_t * subdevice,
+static int me6000_ao_query_timer(me_subdevice_t *subdevice,
 				 int timer,
 				 int *base_frequency,
 				 long long *min_ticks, long long *max_ticks)
@@ -3660,7 +3634,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me6000_ao_query_number_channels(me_subdevice_t * subdevice,
+static int me6000_ao_query_number_channels(me_subdevice_t *subdevice,
 					   int *number)
 {
 	me6000_ao_subdevice_t *instance;
@@ -3672,7 +3646,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me6000_ao_query_subdevice_type(me_subdevice_t * subdevice,
+static int me6000_ao_query_subdevice_type(me_subdevice_t *subdevice,
 					  int *type, int *subtype)
 {
 	me6000_ao_subdevice_t *instance;
@@ -3690,7 +3664,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me6000_ao_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me6000_ao_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
 {
 	me6000_ao_subdevice_t *instance;
 	instance = (me6000_ao_subdevice_t *) subdevice;
diff --git a/drivers/staging/meilhaus/me6000_ao.h b/drivers/staging/meilhaus/me6000_ao.h
index 9629649..ef4d018 100644
--- a/drivers/staging/meilhaus/me6000_ao.h
+++ b/drivers/staging/meilhaus/me6000_ao.h
@@ -160,11 +160,7 @@
 	wait_queue_head_t wait_queue;			/**< Wait queue to put on tasks waiting for data to arrive. */
 
 	struct workqueue_struct *me6000_workqueue;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-	struct work_struct ao_control_task;
-#else
 	struct delayed_work ao_control_task;
-#endif
 
 	volatile int ao_control_task_flag;		/**< Flag controling reexecuting of control task */
 
diff --git a/drivers/staging/meilhaus/me6000_device.c b/drivers/staging/meilhaus/me6000_device.c
index fee4c58..1a6cf7f 100644
--- a/drivers/staging/meilhaus/me6000_device.c
+++ b/drivers/staging/meilhaus/me6000_device.c
@@ -178,6 +178,7 @@
 
 	return (me_device_t *) me6000_device;
 }
+EXPORT_SYMBOL(me6000_pci_constructor);
 
 // Init and exit of module.
 
@@ -206,6 +207,3 @@
 MODULE_DESCRIPTION("Device Driver Module for ME-6000 Device");
 MODULE_SUPPORTED_DEVICE("Meilhaus ME-6000 Devices");
 MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me6000_pci_constructor);
diff --git a/drivers/staging/meilhaus/me6000_dio.c b/drivers/staging/meilhaus/me6000_dio.c
index 07f1069..c90686e 100644
--- a/drivers/staging/meilhaus/me6000_dio.c
+++ b/drivers/staging/meilhaus/me6000_dio.c
@@ -36,7 +36,7 @@
 
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/types.h>
 
 #include "medefines.h"
@@ -91,7 +91,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me6000_dio_io_single_config(me_subdevice_t * subdevice,
+static int me6000_dio_io_single_config(me_subdevice_t *subdevice,
 				       struct file *filep,
 				       int channel,
 				       int single_config,
@@ -161,7 +161,7 @@
 	return err;
 }
 
-static int me6000_dio_io_single_read(me_subdevice_t * subdevice,
+static int me6000_dio_io_single_read(me_subdevice_t *subdevice,
 				     struct file *filep,
 				     int channel,
 				     int *value, int time_out, int flags)
@@ -233,7 +233,7 @@
 	return err;
 }
 
-static int me6000_dio_io_single_write(me_subdevice_t * subdevice,
+static int me6000_dio_io_single_write(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int channel,
 				      int value, int time_out, int flags)
@@ -314,7 +314,7 @@
 	return err;
 }
 
-static int me6000_dio_query_number_channels(me_subdevice_t * subdevice,
+static int me6000_dio_query_number_channels(me_subdevice_t *subdevice,
 					    int *number)
 {
 	PDEBUG("executed.\n");
@@ -322,7 +322,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me6000_dio_query_subdevice_type(me_subdevice_t * subdevice,
+static int me6000_dio_query_subdevice_type(me_subdevice_t *subdevice,
 					   int *type, int *subtype)
 {
 	PDEBUG("executed.\n");
@@ -331,7 +331,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me6000_dio_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me6000_dio_query_subdevice_caps(me_subdevice_t *subdevice,
 					   int *caps)
 {
 	PDEBUG("executed.\n");
@@ -341,7 +341,7 @@
 
 me6000_dio_subdevice_t *me6000_dio_constructor(uint32_t reg_base,
 					       unsigned int dio_idx,
-					       spinlock_t * ctrl_reg_lock)
+					       spinlock_t *ctrl_reg_lock)
 {
 	me6000_dio_subdevice_t *subdevice;
 	int err;
diff --git a/drivers/staging/meilhaus/me8100_device.c b/drivers/staging/meilhaus/me8100_device.c
index 1fb79e4..41a9345 100644
--- a/drivers/staging/meilhaus/me8100_device.c
+++ b/drivers/staging/meilhaus/me8100_device.c
@@ -159,6 +159,7 @@
 
 	return (me_device_t *) me8100_device;
 }
+EXPORT_SYMBOL(me8100_pci_constructor);
 
 // Init and exit of module.
 
@@ -182,6 +183,3 @@
 MODULE_DESCRIPTION("Device Driver Module for Template Device");
 MODULE_SUPPORTED_DEVICE("Meilhaus Template Devices");
 MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me8100_pci_constructor);
diff --git a/drivers/staging/meilhaus/me8100_di.c b/drivers/staging/meilhaus/me8100_di.c
index 971727c..301dbd8 100644
--- a/drivers/staging/meilhaus/me8100_di.c
+++ b/drivers/staging/meilhaus/me8100_di.c
@@ -36,7 +36,7 @@
 
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/version.h>
@@ -114,7 +114,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me8100_di_io_irq_start(me_subdevice_t * subdevice,
+static int me8100_di_io_irq_start(me_subdevice_t *subdevice,
 				  struct file *filep,
 				  int channel,
 				  int irq_source,
@@ -208,7 +208,7 @@
 	return err;
 }
 
-static int me8100_di_io_irq_wait(me_subdevice_t * subdevice,
+static int me8100_di_io_irq_wait(me_subdevice_t *subdevice,
 				 struct file *filep,
 				 int channel,
 				 int *irq_count,
@@ -315,7 +315,7 @@
 	return err;
 }
 
-static int me8100_di_io_irq_stop(me_subdevice_t * subdevice,
+static int me8100_di_io_irq_stop(me_subdevice_t *subdevice,
 				 struct file *filep, int channel, int flags)
 {
 	me8100_di_subdevice_t *instance;
@@ -358,7 +358,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me8100_di_io_single_config(me_subdevice_t * subdevice,
+static int me8100_di_io_single_config(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int channel,
 				      int single_config,
@@ -405,7 +405,7 @@
 	return err;
 }
 
-static int me8100_di_io_single_read(me_subdevice_t * subdevice,
+static int me8100_di_io_single_read(me_subdevice_t *subdevice,
 				    struct file *filep,
 				    int channel,
 				    int *value, int time_out, int flags)
@@ -466,7 +466,7 @@
 	return err;
 }
 
-static int me8100_di_query_number_channels(me_subdevice_t * subdevice,
+static int me8100_di_query_number_channels(me_subdevice_t *subdevice,
 					   int *number)
 {
 	PDEBUG("executed.\n");
@@ -474,7 +474,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me8100_di_query_subdevice_type(me_subdevice_t * subdevice,
+static int me8100_di_query_subdevice_type(me_subdevice_t *subdevice,
 					  int *type, int *subtype)
 {
 	PDEBUG("executed.\n");
@@ -483,7 +483,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me8100_di_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me8100_di_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
 {
 	PDEBUG("executed.\n");
 	*caps = ME_CAPS_DIO_BIT_PATTERN_IRQ | ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_ANY;
@@ -503,11 +503,7 @@
 	kfree(instance);
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
 static irqreturn_t me8100_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me8100_isr(int irq, void *dev_id, struct pt_regs *regs)
-#endif
 {
 	me8100_di_subdevice_t *instance;
 	uint32_t icsr;
@@ -598,7 +594,7 @@
 					     uint32_t plx_reg_base,
 					     unsigned int di_idx,
 					     int irq,
-					     spinlock_t * ctrl_reg_lock)
+					     spinlock_t *ctrl_reg_lock)
 {
 	me8100_di_subdevice_t *subdevice;
 	int err;
diff --git a/drivers/staging/meilhaus/me8100_do.c b/drivers/staging/meilhaus/me8100_do.c
index 957b9f9..81651a9 100644
--- a/drivers/staging/meilhaus/me8100_do.c
+++ b/drivers/staging/meilhaus/me8100_do.c
@@ -36,7 +36,7 @@
 
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/types.h>
 
 #include "medefines.h"
@@ -92,7 +92,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me8100_do_io_single_config(me_subdevice_t * subdevice,
+static int me8100_do_io_single_config(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int channel,
 				      int single_config,
@@ -158,7 +158,7 @@
 	return err;
 }
 
-static int me8100_do_io_single_read(me_subdevice_t * subdevice,
+static int me8100_do_io_single_read(me_subdevice_t *subdevice,
 				    struct file *filep,
 				    int channel,
 				    int *value, int time_out, int flags)
@@ -215,7 +215,7 @@
 	return err;
 }
 
-static int me8100_do_io_single_write(me_subdevice_t * subdevice,
+static int me8100_do_io_single_write(me_subdevice_t *subdevice,
 				     struct file *filep,
 				     int channel,
 				     int value, int time_out, int flags)
@@ -297,7 +297,7 @@
 	return err;
 }
 
-static int me8100_do_query_number_channels(me_subdevice_t * subdevice,
+static int me8100_do_query_number_channels(me_subdevice_t *subdevice,
 					   int *number)
 {
 	PDEBUG("executed.\n");
@@ -305,7 +305,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me8100_do_query_subdevice_type(me_subdevice_t * subdevice,
+static int me8100_do_query_subdevice_type(me_subdevice_t *subdevice,
 					  int *type, int *subtype)
 {
 	PDEBUG("executed.\n");
@@ -314,7 +314,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me8100_do_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me8100_do_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
 {
 	PDEBUG("executed.\n");
 	*caps = ME_CAPS_DIO_SINK_SOURCE;
@@ -323,7 +323,7 @@
 
 me8100_do_subdevice_t *me8100_do_constructor(uint32_t reg_base,
 					     unsigned int do_idx,
-					     spinlock_t * ctrl_reg_lock)
+					     spinlock_t *ctrl_reg_lock)
 {
 	me8100_do_subdevice_t *subdevice;
 	int err;
diff --git a/drivers/staging/meilhaus/me8200_device.c b/drivers/staging/meilhaus/me8200_device.c
index 261c0cb..b313679 100644
--- a/drivers/staging/meilhaus/me8200_device.c
+++ b/drivers/staging/meilhaus/me8200_device.c
@@ -166,6 +166,7 @@
 
 	return (me_device_t *) me8200_device;
 }
+EXPORT_SYMBOL(me8200_pci_constructor);
 
 // Init and exit of module.
 
@@ -189,6 +190,3 @@
 MODULE_DESCRIPTION("Device Driver Module for Template Device");
 MODULE_SUPPORTED_DEVICE("Meilhaus Template Devices");
 MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me8200_pci_constructor);
diff --git a/drivers/staging/meilhaus/me8200_di.c b/drivers/staging/meilhaus/me8200_di.c
index 27525bc..a931fb8 100644
--- a/drivers/staging/meilhaus/me8200_di.c
+++ b/drivers/staging/meilhaus/me8200_di.c
@@ -34,7 +34,7 @@
 
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/version.h>
@@ -50,52 +50,44 @@
 
 /// Defines
 static void me8200_di_destructor(struct me_subdevice *subdevice);
-static int me8200_di_io_irq_start(me_subdevice_t * subdevice,
+static int me8200_di_io_irq_start(me_subdevice_t *subdevice,
 				  struct file *filep,
 				  int channel,
 				  int irq_source,
 				  int irq_edge, int irq_arg, int flags);
-static int me8200_di_io_irq_wait(me_subdevice_t * subdevice,
+static int me8200_di_io_irq_wait(me_subdevice_t *subdevice,
 				 struct file *filep,
 				 int channel,
 				 int *irq_count,
 				 int *value, int time_out, int flags);
-static int me8200_di_io_irq_stop(me_subdevice_t * subdevice,
+static int me8200_di_io_irq_stop(me_subdevice_t *subdevice,
 				 struct file *filep, int channel, int flags);
-static int me8200_di_io_single_config(me_subdevice_t * subdevice,
+static int me8200_di_io_single_config(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int channel,
 				      int single_config,
 				      int ref,
 				      int trig_chan,
 				      int trig_type, int trig_edge, int flags);
-static int me8200_di_io_single_read(me_subdevice_t * subdevice,
+static int me8200_di_io_single_read(me_subdevice_t *subdevice,
 				    struct file *filep,
 				    int channel,
 				    int *value, int time_out, int flags);
 static int me8200_di_io_reset_subdevice(struct me_subdevice *subdevice,
 					struct file *filep, int flags);
-static int me8200_di_query_number_channels(me_subdevice_t * subdevice,
+static int me8200_di_query_number_channels(me_subdevice_t *subdevice,
 					   int *number);
-static int me8200_di_query_subdevice_type(me_subdevice_t * subdevice,
+static int me8200_di_query_subdevice_type(me_subdevice_t *subdevice,
 					  int *type, int *subtype);
-static int me8200_di_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me8200_di_query_subdevice_caps(me_subdevice_t *subdevice,
 					  int *caps);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
 static irqreturn_t me8200_isr(int irq, void *dev_id);
-#else
-static irqreturn_t me8200_isr(int irq, void *dev_id, struct pt_regs *regs);
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
 static irqreturn_t me8200_isr_EX(int irq, void *dev_id);
-#else
-static irqreturn_t me8200_isr_EX(int irq, void *dev_id, struct pt_regs *regs);
-#endif
-static void me8200_di_check_version(me8200_di_subdevice_t * instance,
+static void me8200_di_check_version(me8200_di_subdevice_t *instance,
 				    unsigned long addr);
 
 ///Functions
-static int me8200_di_io_irq_start(me_subdevice_t * subdevice,
+static int me8200_di_io_irq_start(me_subdevice_t *subdevice,
 				  struct file *filep,
 				  int channel,
 				  int irq_source,
@@ -246,7 +238,7 @@
 	return err;
 }
 
-static int me8200_di_io_irq_wait(me_subdevice_t * subdevice,
+static int me8200_di_io_irq_wait(me_subdevice_t *subdevice,
 				 struct file *filep,
 				 int channel,
 				 int *irq_count,
@@ -352,7 +344,7 @@
 	return err;
 }
 
-static int me8200_di_io_irq_stop(me_subdevice_t * subdevice,
+static int me8200_di_io_irq_stop(me_subdevice_t *subdevice,
 				 struct file *filep, int channel, int flags)
 {
 	me8200_di_subdevice_t *instance;
@@ -406,7 +398,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me8200_di_io_single_config(me_subdevice_t * subdevice,
+static int me8200_di_io_single_config(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int channel,
 				      int single_config,
@@ -453,7 +445,7 @@
 	return err;
 }
 
-static int me8200_di_io_single_read(me_subdevice_t * subdevice,
+static int me8200_di_io_single_read(me_subdevice_t *subdevice,
 				    struct file *filep,
 				    int channel,
 				    int *value, int time_out, int flags)
@@ -518,7 +510,7 @@
 	return me8200_di_io_irq_stop(subdevice, filep, 0, 0);
 }
 
-static int me8200_di_query_number_channels(me_subdevice_t * subdevice,
+static int me8200_di_query_number_channels(me_subdevice_t *subdevice,
 					   int *number)
 {
 	PDEBUG("executed.\n");
@@ -526,7 +518,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me8200_di_query_subdevice_type(me_subdevice_t * subdevice,
+static int me8200_di_query_subdevice_type(me_subdevice_t *subdevice,
 					  int *type, int *subtype)
 {
 	PDEBUG("executed.\n");
@@ -535,7 +527,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me8200_di_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me8200_di_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
 {
 	PDEBUG("executed.\n");
 	*caps =
@@ -546,11 +538,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
 static irqreturn_t me8200_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me8200_isr(int irq, void *dev_id, struct pt_regs *regs)
-#endif
 {
 	me8200_di_subdevice_t *instance;
 	uint8_t ctrl;
@@ -629,11 +617,7 @@
 	return IRQ_HANDLED;
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
 static irqreturn_t me8200_isr_EX(int irq, void *dev_id)
-#else
-static irqreturn_t me8200_isr_EX(int irq, void *dev_id, struct pt_regs *regs)
-#endif
 {
 	me8200_di_subdevice_t *instance;
 	uint8_t irq_status = 0;
@@ -715,8 +699,8 @@
 me8200_di_subdevice_t *me8200_di_constructor(uint32_t me8200_regbase,
 					     unsigned int di_idx,
 					     int irq,
-					     spinlock_t * irq_ctrl_lock,
-					     spinlock_t * irq_mode_lock)
+					     spinlock_t *irq_ctrl_lock,
+					     spinlock_t *irq_mode_lock)
 {
 	me8200_di_subdevice_t *subdevice;
 	int err;
@@ -843,7 +827,7 @@
 	return subdevice;
 }
 
-static void me8200_di_check_version(me8200_di_subdevice_t * instance,
+static void me8200_di_check_version(me8200_di_subdevice_t *instance,
 				    unsigned long addr)
 {
 
diff --git a/drivers/staging/meilhaus/me8200_dio.c b/drivers/staging/meilhaus/me8200_dio.c
index ff8ca1b..c7f43f0 100644
--- a/drivers/staging/meilhaus/me8200_dio.c
+++ b/drivers/staging/meilhaus/me8200_dio.c
@@ -36,7 +36,7 @@
 
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/types.h>
 
 #include "medefines.h"
@@ -90,7 +90,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me8200_dio_io_single_config(me_subdevice_t * subdevice,
+static int me8200_dio_io_single_config(me_subdevice_t *subdevice,
 				       struct file *filep,
 				       int channel,
 				       int single_config,
@@ -164,7 +164,7 @@
 	return err;
 }
 
-static int me8200_dio_io_single_read(me_subdevice_t * subdevice,
+static int me8200_dio_io_single_read(me_subdevice_t *subdevice,
 				     struct file *filep,
 				     int channel,
 				     int *value, int time_out, int flags)
@@ -241,7 +241,7 @@
 	return err;
 }
 
-static int me8200_dio_io_single_write(me_subdevice_t * subdevice,
+static int me8200_dio_io_single_write(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int channel,
 				      int value, int time_out, int flags)
@@ -332,7 +332,7 @@
 	return err;
 }
 
-static int me8200_dio_query_number_channels(me_subdevice_t * subdevice,
+static int me8200_dio_query_number_channels(me_subdevice_t *subdevice,
 					    int *number)
 {
 	PDEBUG("executed.\n");
@@ -340,7 +340,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me8200_dio_query_subdevice_type(me_subdevice_t * subdevice,
+static int me8200_dio_query_subdevice_type(me_subdevice_t *subdevice,
 					   int *type, int *subtype)
 {
 	PDEBUG("executed.\n");
@@ -349,7 +349,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me8200_dio_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me8200_dio_query_subdevice_caps(me_subdevice_t *subdevice,
 					   int *caps)
 {
 	PDEBUG("executed.\n");
@@ -359,7 +359,7 @@
 
 me8200_dio_subdevice_t *me8200_dio_constructor(uint32_t reg_base,
 					       unsigned int dio_idx,
-					       spinlock_t * ctrl_reg_lock)
+					       spinlock_t *ctrl_reg_lock)
 {
 	me8200_dio_subdevice_t *subdevice;
 	int err;
diff --git a/drivers/staging/meilhaus/me8200_do.c b/drivers/staging/meilhaus/me8200_do.c
index d2bebd1..40d536c 100644
--- a/drivers/staging/meilhaus/me8200_do.c
+++ b/drivers/staging/meilhaus/me8200_do.c
@@ -37,7 +37,7 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/types.h>
 #include <linux/version.h>
 
@@ -59,7 +59,7 @@
  * Functions
  */
 
-static int me8200_do_io_irq_start(me_subdevice_t * subdevice,
+static int me8200_do_io_irq_start(me_subdevice_t *subdevice,
 				  struct file *filep,
 				  int channel,
 				  int irq_source,
@@ -109,7 +109,7 @@
 	return err;
 }
 
-static int me8200_do_io_irq_wait(me_subdevice_t * subdevice,
+static int me8200_do_io_irq_wait(me_subdevice_t *subdevice,
 				 struct file *filep,
 				 int channel,
 				 int *irq_count,
@@ -184,7 +184,7 @@
 	return err;
 }
 
-static int me8200_do_io_irq_stop(me_subdevice_t * subdevice,
+static int me8200_do_io_irq_stop(me_subdevice_t *subdevice,
 				 struct file *filep, int channel, int flags)
 {
 	me8200_do_subdevice_t *instance;
@@ -262,7 +262,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me8200_do_io_single_config(me_subdevice_t * subdevice,
+static int me8200_do_io_single_config(me_subdevice_t *subdevice,
 				      struct file *filep,
 				      int channel,
 				      int single_config,
@@ -307,7 +307,7 @@
 	return err;
 }
 
-static int me8200_do_io_single_read(me_subdevice_t * subdevice,
+static int me8200_do_io_single_read(me_subdevice_t *subdevice,
 				    struct file *filep,
 				    int channel,
 				    int *value, int time_out, int flags)
@@ -354,7 +354,7 @@
 	return err;
 }
 
-static int me8200_do_io_single_write(me_subdevice_t * subdevice,
+static int me8200_do_io_single_write(me_subdevice_t *subdevice,
 				     struct file *filep,
 				     int channel,
 				     int value, int time_out, int flags)
@@ -415,7 +415,7 @@
 	return err;
 }
 
-static int me8200_do_query_number_channels(me_subdevice_t * subdevice,
+static int me8200_do_query_number_channels(me_subdevice_t *subdevice,
 					   int *number)
 {
 	PDEBUG("executed.\n");
@@ -423,7 +423,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me8200_do_query_subdevice_type(me_subdevice_t * subdevice,
+static int me8200_do_query_subdevice_type(me_subdevice_t *subdevice,
 					  int *type, int *subtype)
 {
 	PDEBUG("executed.\n");
@@ -432,7 +432,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me8200_do_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me8200_do_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
 {
 	PDEBUG("executed.\n");
 	*caps = ME_CAPS_DIO_OVER_TEMP_IRQ;
@@ -452,11 +452,7 @@
 	kfree(instance);
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
 static irqreturn_t me8200_do_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me8200_do_isr(int irq, void *dev_id, struct pt_regs *regs)
-#endif
 {
 	me8200_do_subdevice_t *instance;
 	uint16_t ctrl;
@@ -505,7 +501,7 @@
 me8200_do_subdevice_t *me8200_do_constructor(uint32_t reg_base,
 					     unsigned int do_idx,
 					     int irq,
-					     spinlock_t * irq_mode_lock)
+					     spinlock_t *irq_mode_lock)
 {
 	me8200_do_subdevice_t *subdevice;
 	int err;
diff --git a/drivers/staging/meilhaus/me8254.c b/drivers/staging/meilhaus/me8254.c
index 6e44c3d..d8f742a 100644
--- a/drivers/staging/meilhaus/me8254.c
+++ b/drivers/staging/meilhaus/me8254.c
@@ -35,7 +35,7 @@
 
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/types.h>
 
 #include "medefines.h"
@@ -183,7 +183,7 @@
 	return err;
 }
 
-static int me1400_ab_ref_config(me8254_subdevice_t * instance, int ref)
+static int me1400_ab_ref_config(me8254_subdevice_t *instance, int ref)
 {
 	uint8_t clk_src;
 
@@ -291,7 +291,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me1400_cd_ref_config(me8254_subdevice_t * instance, int ref)
+static int me1400_cd_ref_config(me8254_subdevice_t *instance, int ref)
 {
 	uint8_t clk_src;
 
@@ -436,7 +436,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me4600_ref_config(me8254_subdevice_t * instance, int ref)
+static int me4600_ref_config(me8254_subdevice_t *instance, int ref)
 {
 	switch (ref) {
 
@@ -453,7 +453,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int me8100_ref_config(me8254_subdevice_t * instance, int ref)
+static int me8100_ref_config(me8254_subdevice_t *instance, int ref)
 {
 	switch (ref) {
 
@@ -962,8 +962,8 @@
 				       uint32_t reg_base,
 				       unsigned int me8254_idx,
 				       unsigned int ctr_idx,
-				       spinlock_t * ctrl_reg_lock,
-				       spinlock_t * clk_src_reg_lock)
+				       spinlock_t *ctrl_reg_lock,
+				       spinlock_t *clk_src_reg_lock)
 {
 	me8254_subdevice_t *subdevice;
 	int err;
diff --git a/drivers/staging/meilhaus/me8255.c b/drivers/staging/meilhaus/me8255.c
index 180e7f8..ec9c638 100644
--- a/drivers/staging/meilhaus/me8255.c
+++ b/drivers/staging/meilhaus/me8255.c
@@ -35,7 +35,7 @@
 
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/types.h>
 
 #include "medefines.h"
@@ -318,7 +318,7 @@
 				       unsigned int me8255_idx,
 				       unsigned int dio_idx,
 				       int *ctrl_reg_mirror,
-				       spinlock_t * ctrl_reg_lock)
+				       spinlock_t *ctrl_reg_lock)
 {
 	me8255_subdevice_t *subdevice;
 	int err;
diff --git a/drivers/staging/meilhaus/mecirc_buf.h b/drivers/staging/meilhaus/mecirc_buf.h
index e9b591e..5166585 100644
--- a/drivers/staging/meilhaus/mecirc_buf.h
+++ b/drivers/staging/meilhaus/mecirc_buf.h
@@ -40,19 +40,19 @@
 	int volatile tail;
 } me_circ_buf_t;
 
-static int inline me_circ_buf_values(me_circ_buf_t * buf)
+static inline int me_circ_buf_values(me_circ_buf_t * buf)
 {
 //      return ((buf->head - buf->tail) & (buf->count - 1));
 	return ((buf->head - buf->tail) & (buf->mask));
 }
 
-static int inline me_circ_buf_space(me_circ_buf_t * buf)
+static inline int me_circ_buf_space(me_circ_buf_t * buf)
 {
 //      return ((buf->tail - (buf->head + 1)) & (buf->count - 1));
 	return ((buf->tail - (buf->head + 1)) & (buf->mask));
 }
 
-static int inline me_circ_buf_values_to_end(me_circ_buf_t * buf)
+static inline int me_circ_buf_values_to_end(me_circ_buf_t * buf)
 {
 	int end;
 	int n;
@@ -63,7 +63,7 @@
 	return (n < end) ? n : end;
 }
 
-static int inline me_circ_buf_space_to_end(me_circ_buf_t * buf)
+static inline int me_circ_buf_space_to_end(me_circ_buf_t * buf)
 {
 	int end;
 	int n;
@@ -99,19 +99,19 @@
 #   endif //_CBUFF_32b_t
 
 /** How many values is in buffer */
-static int inline me_circ_buf_values(me_circ_buf_t * buf)
+static inline int me_circ_buf_values(me_circ_buf_t * buf)
 {
 	return ((buf->head - buf->tail) & (buf->mask));
 }
 
 /** How many space left */
-static int inline me_circ_buf_space(me_circ_buf_t * buf)
+static inline int me_circ_buf_space(me_circ_buf_t * buf)
 {
 	return ((buf->tail - (buf->head + 1)) & (buf->mask));
 }
 
 /** How many values can be read from buffor in one chunck. */
-static int inline me_circ_buf_values_to_end(me_circ_buf_t * buf)
+static inline int me_circ_buf_values_to_end(me_circ_buf_t * buf)
 {
 	return (buf->tail <=
 		buf->head) ? (buf->head - buf->tail) : (buf->mask - buf->tail +
@@ -119,7 +119,7 @@
 }
 
 /** How many values can be write to buffer in one chunck. */
-static int inline me_circ_buf_space_to_end(me_circ_buf_t * buf)
+static inline int me_circ_buf_space_to_end(me_circ_buf_t * buf)
 {
 	return (buf->tail <=
 		buf->head) ? (buf->mask - buf->head + 1) : (buf->tail -
diff --git a/drivers/staging/meilhaus/medevice.c b/drivers/staging/meilhaus/medevice.c
index 8f62e16..75aaec0 100644
--- a/drivers/staging/meilhaus/medevice.c
+++ b/drivers/staging/meilhaus/medevice.c
@@ -390,9 +390,9 @@
 static int me_device_io_stream_config(struct me_device *device,
 				      struct file *filep,
 				      int subdevice,
-				      meIOStreamConfig_t * config_list,
+				      meIOStreamConfig_t *config_list,
 				      int count,
-				      meIOStreamTrigger_t * trigger,
+				      meIOStreamTrigger_t *trigger,
 				      int fifo_irq_threshold, int flags)
 {
 	int err = ME_ERRNO_SUCCESS;
@@ -1040,7 +1040,7 @@
 				 int subdevice,
 				 int timer,
 				 int *base_frequency,
-				 uint64_t * min_ticks, uint64_t * max_ticks)
+				 uint64_t *min_ticks, uint64_t *max_ticks)
 {
 	int err = ME_ERRNO_SUCCESS;
 	me_subdevice_t *s;
@@ -1082,14 +1082,14 @@
 }
 
 static int me_device_config_load(struct me_device *device, struct file *filep,
-				 me_cfg_device_entry_t * config)
+				 me_cfg_device_entry_t *config)
 {
 	PDEBUG("executed.\n");
 	return ME_ERRNO_SUCCESS;	//If no need for config return success.
 //      return ME_ERRNO_NOT_SUPPORTED;
 }
 
-static void me_device_destructor(me_device_t * me_device)
+static void me_device_destructor(me_device_t *me_device)
 {
 	PDEBUG("executed.\n");
 	me_device_deinit(me_device);
@@ -1581,7 +1581,7 @@
 	return 0;
 }
 
-int me_device_pci_init(me_device_t * me_device, struct pci_dev *pci_device)
+int me_device_pci_init(me_device_t *me_device, struct pci_dev *pci_device)
 {
 	int err;
 	int i;
@@ -1720,7 +1720,7 @@
 	return 1;
 }
 
-void me_device_deinit(me_device_t * me_device)
+void me_device_deinit(me_device_t *me_device)
 {
 	PDEBUG("executed.\n");
 
diff --git a/drivers/staging/meilhaus/medlist.c b/drivers/staging/meilhaus/medlist.c
index ef4e369..b6a4065 100644
--- a/drivers/staging/meilhaus/medlist.c
+++ b/drivers/staging/meilhaus/medlist.c
@@ -69,7 +69,7 @@
 	return device;
 }
 
-void me_dlist_add_device_tail(struct me_dlist *dlist, me_device_t * device)
+void me_dlist_add_device_tail(struct me_dlist *dlist, me_device_t *device)
 {
 	PDEBUG_LOCKS("called.\n");
 
@@ -99,7 +99,7 @@
 	return device;
 }
 
-int me_dlist_init(me_dlist_t * dlist)
+int me_dlist_init(me_dlist_t *dlist)
 {
 	PDEBUG_LOCKS("called.\n");
 
@@ -108,7 +108,7 @@
 	return 0;
 }
 
-void me_dlist_deinit(me_dlist_t * dlist)
+void me_dlist_deinit(me_dlist_t *dlist)
 {
 
 	struct list_head *s;
diff --git a/drivers/staging/meilhaus/medlock.c b/drivers/staging/meilhaus/medlock.c
index f649e3d..8ded397 100644
--- a/drivers/staging/meilhaus/medlock.c
+++ b/drivers/staging/meilhaus/medlock.c
@@ -65,7 +65,7 @@
 }
 
 int me_dlock_lock(struct me_dlock *dlock,
-		  struct file *filep, int lock, int flags, me_slist_t * slist)
+		  struct file *filep, int lock, int flags, me_slist_t *slist)
 {
 	int err = ME_ERRNO_SUCCESS;
 	int i;
@@ -183,7 +183,7 @@
 	PDEBUG_LOCKS("executed.\n");
 }
 
-int me_dlock_init(me_dlock_t * dlock)
+int me_dlock_init(me_dlock_t *dlock)
 {
 	PDEBUG_LOCKS("executed.\n");
 
diff --git a/drivers/staging/meilhaus/medummy.c b/drivers/staging/meilhaus/medummy.c
index 6a9f08d..2423745 100644
--- a/drivers/staging/meilhaus/medummy.c
+++ b/drivers/staging/meilhaus/medummy.c
@@ -47,7 +47,7 @@
 
 #include "medummy.h"
 
-static int medummy_io_irq_start(me_device_t * device,
+static int medummy_io_irq_start(me_device_t *device,
 				struct file *filep,
 				int subdevice,
 				int channel,
@@ -58,7 +58,7 @@
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-static int medummy_io_irq_wait(me_device_t * device,
+static int medummy_io_irq_wait(me_device_t *device,
 			       struct file *filep,
 			       int subdevice,
 			       int channel,
@@ -69,7 +69,7 @@
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-static int medummy_io_irq_stop(me_device_t * device,
+static int medummy_io_irq_stop(me_device_t *device,
 			       struct file *filep,
 			       int subdevice, int channel, int flags)
 {
@@ -77,14 +77,14 @@
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-static int medummy_io_reset_device(me_device_t * device,
+static int medummy_io_reset_device(me_device_t *device,
 				   struct file *filep, int flags)
 {
 	PDEBUG("executed.\n");
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-static int medummy_io_reset_subdevice(me_device_t * device,
+static int medummy_io_reset_subdevice(me_device_t *device,
 				      struct file *filep,
 				      int subdevice, int flags)
 {
@@ -92,7 +92,7 @@
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-static int medummy_io_single_config(me_device_t * device,
+static int medummy_io_single_config(me_device_t *device,
 				    struct file *filep,
 				    int subdevice,
 				    int channel,
@@ -105,7 +105,7 @@
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-static int medummy_io_single_read(me_device_t * device,
+static int medummy_io_single_read(me_device_t *device,
 				  struct file *filep,
 				  int subdevice,
 				  int channel,
@@ -115,7 +115,7 @@
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-static int medummy_io_single_write(me_device_t * device,
+static int medummy_io_single_write(me_device_t *device,
 				   struct file *filep,
 				   int subdevice,
 				   int channel,
@@ -125,19 +125,19 @@
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-static int medummy_io_stream_config(me_device_t * device,
+static int medummy_io_stream_config(me_device_t *device,
 				    struct file *filep,
 				    int subdevice,
-				    meIOStreamConfig_t * config_list,
+				    meIOStreamConfig_t *config_list,
 				    int count,
-				    meIOStreamTrigger_t * trigger,
+				    meIOStreamTrigger_t *trigger,
 				    int fifo_irq_threshold, int flags)
 {
 	PDEBUG("executed.\n");
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-static int medummy_io_stream_new_values(me_device_t * device,
+static int medummy_io_stream_new_values(me_device_t *device,
 					struct file *filep,
 					int subdevice,
 					int timeout, int *count, int flags)
@@ -146,7 +146,7 @@
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-static int medummy_io_stream_read(me_device_t * device,
+static int medummy_io_stream_read(me_device_t *device,
 				  struct file *filep,
 				  int subdevice,
 				  int read_mode,
@@ -156,7 +156,7 @@
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-static int medummy_io_stream_start(me_device_t * device,
+static int medummy_io_stream_start(me_device_t *device,
 				   struct file *filep,
 				   int subdevice,
 				   int start_mode, int time_out, int flags)
@@ -165,7 +165,7 @@
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-static int medummy_io_stream_status(me_device_t * device,
+static int medummy_io_stream_status(me_device_t *device,
 				    struct file *filep,
 				    int subdevice,
 				    int wait,
@@ -175,7 +175,7 @@
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-static int medummy_io_stream_stop(me_device_t * device,
+static int medummy_io_stream_stop(me_device_t *device,
 				  struct file *filep,
 				  int subdevice, int stop_mode, int flags)
 {
@@ -183,7 +183,7 @@
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-static int medummy_io_stream_write(me_device_t * device,
+static int medummy_io_stream_write(me_device_t *device,
 				   struct file *filep,
 				   int subdevice,
 				   int write_mode,
@@ -193,14 +193,14 @@
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-static int medummy_lock_device(me_device_t * device,
+static int medummy_lock_device(me_device_t *device,
 			       struct file *filep, int lock, int flags)
 {
 	PDEBUG("executed.\n");
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-static int medummy_lock_subdevice(me_device_t * device,
+static int medummy_lock_subdevice(me_device_t *device,
 				  struct file *filep,
 				  int subdevice, int lock, int flags)
 {
@@ -208,7 +208,7 @@
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-static int medummy_query_description_device(me_device_t * device,
+static int medummy_query_description_device(me_device_t *device,
 					    char **description)
 {
 	medummy_device_t *instance = (medummy_device_t *) device;
@@ -602,7 +602,7 @@
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-static int medummy_query_info_device(me_device_t * device,
+static int medummy_query_info_device(me_device_t *device,
 				     int *vendor_id,
 				     int *device_id,
 				     int *serial_no,
@@ -632,14 +632,14 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int medummy_query_name_device_driver(me_device_t * device, char **name)
+static int medummy_query_name_device_driver(me_device_t *device, char **name)
 {
 	PDEBUG("executed.\n");
 	*name = MEDUMMY_NAME_DRIVER;
 	return ME_ERRNO_SUCCESS;
 }
 
-static int medummy_query_name_device(me_device_t * device, char **name)
+static int medummy_query_name_device(me_device_t *device, char **name)
 {
 	medummy_device_t *instance = (medummy_device_t *) device;
 
@@ -1012,41 +1012,41 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int medummy_query_number_subdevices(me_device_t * device, int *number)
+static int medummy_query_number_subdevices(me_device_t *device, int *number)
 {
 	PDEBUG("executed.\n");
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-static int medummy_query_number_channels(me_device_t * device,
+static int medummy_query_number_channels(me_device_t *device,
 					 int subdevice, int *number)
 {
 	PDEBUG("executed.\n");
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-static int medummy_query_number_ranges(me_device_t * device,
+static int medummy_query_number_ranges(me_device_t *device,
 				       int subdevice, int unit, int *count)
 {
 	PDEBUG("executed.\n");
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-static int medummy_query_subdevice_type(me_device_t * device,
+static int medummy_query_subdevice_type(me_device_t *device,
 					int subdevice, int *type, int *subtype)
 {
 	PDEBUG("executed.\n");
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-static int medummy_query_subdevice_caps(me_device_t * device,
+static int medummy_query_subdevice_caps(me_device_t *device,
 					int subdevice, int *caps)
 {
 	PDEBUG("executed.\n");
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-static int medummy_query_subdevice_caps_args(me_device_t * device,
+static int medummy_query_subdevice_caps_args(me_device_t *device,
 					     int subdevice,
 					     int cap, int *args, int count)
 {
@@ -1054,7 +1054,7 @@
 	return ME_ERRNO_NOT_SUPPORTED;
 }
 
-static int medummy_query_subdevice_by_type(me_device_t * device,
+static int medummy_query_subdevice_by_type(me_device_t *device,
 					   int start_subdevice,
 					   int type,
 					   int subtype, int *subdevice)
@@ -1063,7 +1063,7 @@
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-static int medummy_query_range_by_min_max(me_device_t * device,
+static int medummy_query_range_by_min_max(me_device_t *device,
 					  int subdevice,
 					  int unit,
 					  int *min,
@@ -1073,7 +1073,7 @@
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-static int medummy_query_range_info(me_device_t * device,
+static int medummy_query_range_info(me_device_t *device,
 				    int subdevice,
 				    int range,
 				    int *unit, int *min, int *max, int *maxdata)
@@ -1082,17 +1082,17 @@
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-int medummy_query_timer(me_device_t * device,
+int medummy_query_timer(me_device_t *device,
 			int subdevice,
 			int timer,
 			int *base_frequency,
-			uint64_t * min_ticks, uint64_t * max_ticks)
+			uint64_t *min_ticks, uint64_t *max_ticks)
 {
 	PDEBUG("executed.\n");
 	return ME_ERRNO_DEVICE_UNPLUGGED;
 }
 
-static int medummy_query_version_device_driver(me_device_t * device,
+static int medummy_query_version_device_driver(me_device_t *device,
 					       int *version)
 {
 	PDEBUG("executed.\n");
@@ -1101,7 +1101,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static void medummy_destructor(me_device_t * device)
+static void medummy_destructor(me_device_t *device)
 {
 	PDEBUG("executed.\n");
 	kfree(device);
@@ -1113,7 +1113,7 @@
 			    int bus_type,
 			    int bus_no,
 			    int dev_no,
-			    int func_no, medummy_device_t * instance)
+			    int func_no, medummy_device_t *instance)
 {
 	PDEBUG("executed.\n");
 
@@ -1129,14 +1129,14 @@
 	return 0;
 }
 
-static int medummy_config_load(me_device_t * device, struct file *filep,
-			       me_cfg_device_entry_t * config)
+static int medummy_config_load(me_device_t *device, struct file *filep,
+			       me_cfg_device_entry_t *config)
 {
 	PDEBUG("executed.\n");
 	return ME_ERRNO_SUCCESS;
 }
 
-static int init_device_instance(me_device_t * device)
+static int init_device_instance(me_device_t *device)
 {
 	PDEBUG("executed.\n");
 
@@ -1238,6 +1238,7 @@
 
 	return (me_device_t *) instance;
 }
+EXPORT_SYMBOL(medummy_constructor);
 
 // Init and exit of module.
 
@@ -1261,6 +1262,3 @@
 MODULE_DESCRIPTION("Device Driver Module for Meilhaus ME-DUMMY Devices");
 MODULE_SUPPORTED_DEVICE("Meilhaus ME-DUMMY Devices");
 MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(medummy_constructor);
diff --git a/drivers/staging/meilhaus/memain.c b/drivers/staging/meilhaus/memain.c
index b09d1a6..fd9f079 100644
--- a/drivers/staging/meilhaus/memain.c
+++ b/drivers/staging/meilhaus/memain.c
@@ -37,7 +37,7 @@
 #include <linux/pci.h>
 //#include <linux/usb.h>
 #include <linux/errno.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/cdev.h>
 #include <linux/rwsem.h>
 
@@ -56,6 +56,7 @@
 
 #ifdef BOSCH
 static unsigned int me_bosch_fw = 0;
+EXPORT_SYMBOL(me_bosch_fw);
 
 # ifdef module_param
 module_param(me_bosch_fw, int, S_IRUGO);
@@ -79,7 +80,7 @@
 
 static struct file *me_filep = NULL;
 static int me_count = 0;
-static spinlock_t me_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(me_lock);
 static DECLARE_RWSEM(me_rwsem);
 
 /* Board instances are kept in a global list */
@@ -90,7 +91,7 @@
 
 static int me_probe_pci(struct pci_dev *dev, const struct pci_device_id *id);
 static void me_remove_pci(struct pci_dev *dev);
-static int insert_to_device_list(me_device_t * n_device);
+static int insert_to_device_list(me_device_t *n_device);
 static int replace_with_dummy(int vendor_id, int device_id, int serial_no);
 static void clear_device_list(void);
 static int me_open(struct inode *inode_ptr, struct file *filep);
@@ -472,7 +473,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static void release_instance(me_device_t * device)
+static void release_instance(me_device_t *device)
 {
 	int vendor_id;
 	int device_id;
@@ -517,7 +518,7 @@
 	}
 }
 
-static int insert_to_device_list(me_device_t * n_device)
+static int insert_to_device_list(me_device_t *n_device)
 {
 	me_device_t *o_device = NULL;
 
@@ -762,7 +763,7 @@
 	return err;
 }
 
-static int me_lock_driver(struct file *filep, me_lock_driver_t * arg)
+static int me_lock_driver(struct file *filep, me_lock_driver_t *arg)
 {
 	int err = 0;
 
@@ -807,7 +808,7 @@
 }
 
 static int me_query_version_main_driver(struct file *filep,
-					me_query_version_main_driver_t * arg)
+					me_query_version_main_driver_t *arg)
 {
 	int err;
 	me_query_version_main_driver_t karg;
@@ -828,7 +829,7 @@
 }
 
 static int me_config_load_device(struct file *filep,
-				 me_cfg_device_entry_t * karg, int device_no)
+				 me_cfg_device_entry_t *karg, int device_no)
 {
 
 	int err = ME_ERRNO_SUCCESS;
@@ -874,7 +875,7 @@
 	return err;
 }
 
-static int me_config_load(struct file *filep, me_config_load_t * arg)
+static int me_config_load(struct file *filep, me_config_load_t *arg)
 {
 	int err;
 	int i;
@@ -1170,7 +1171,7 @@
 	return 0;
 }
 
-static int me_io_stream_start(struct file *filep, me_io_stream_start_t * arg)
+static int me_io_stream_start(struct file *filep, me_io_stream_start_t *arg)
 {
 	int err;
 	int i, k;
@@ -1292,7 +1293,7 @@
 	return err;
 }
 
-static int me_io_single(struct file *filep, me_io_single_t * arg)
+static int me_io_single(struct file *filep, me_io_single_t *arg)
 {
 	int err;
 	int i, k;
@@ -1448,7 +1449,7 @@
 	return err;
 }
 
-static int me_io_stream_config(struct file *filep, me_io_stream_config_t * arg)
+static int me_io_stream_config(struct file *filep, me_io_stream_config_t *arg)
 {
 	int err;
 	int k = 0;
@@ -1540,7 +1541,7 @@
 }
 
 static int me_query_number_devices(struct file *filep,
-				   me_query_number_devices_t * arg)
+				   me_query_number_devices_t *arg)
 {
 	int err;
 	me_query_number_devices_t karg;
@@ -1569,7 +1570,7 @@
 	return 0;
 }
 
-static int me_io_stream_stop(struct file *filep, me_io_stream_stop_t * arg)
+static int me_io_stream_stop(struct file *filep, me_io_stream_stop_t *arg)
 {
 	int err;
 	int i, k;
@@ -2015,8 +2016,3 @@
 MODULE_DESCRIPTION("Central module for Meilhaus Driver System.");
 MODULE_SUPPORTED_DEVICE("Meilhaus PCI/cPCI boards.");
 MODULE_LICENSE("GPL");
-
-#ifdef BOSCH
-// Export the flag for the BOSCH firmware.
-EXPORT_SYMBOL(me_bosch_fw);
-#endif // BOSCH
diff --git a/drivers/staging/meilhaus/meslist.c b/drivers/staging/meilhaus/meslist.c
index 7e8b66c..ce49114 100644
--- a/drivers/staging/meilhaus/meslist.c
+++ b/drivers/staging/meilhaus/meslist.c
@@ -115,7 +115,7 @@
 }
 
 void me_slist_add_subdevice_tail(struct me_slist *slist,
-				 me_subdevice_t * subdevice)
+				 me_subdevice_t *subdevice)
 {
 	PDEBUG_LOCKS("called.\n");
 
@@ -145,7 +145,7 @@
 	return subdevice;
 }
 
-int me_slist_init(me_slist_t * slist)
+int me_slist_init(me_slist_t *slist)
 {
 	PDEBUG_LOCKS("called.\n");
 
@@ -154,7 +154,7 @@
 	return 0;
 }
 
-void me_slist_deinit(me_slist_t * slist)
+void me_slist_deinit(me_slist_t *slist)
 {
 
 	struct list_head *s;
diff --git a/drivers/staging/meilhaus/meslock.c b/drivers/staging/meilhaus/meslock.c
index 5230b89..abcdb4a 100644
--- a/drivers/staging/meilhaus/meslock.c
+++ b/drivers/staging/meilhaus/meslock.c
@@ -124,7 +124,7 @@
 	PDEBUG_LOCKS("executed.\n");
 }
 
-int me_slock_init(me_slock_t * slock)
+int me_slock_init(me_slock_t *slock)
 {
 	PDEBUG_LOCKS("executed.\n");
 
diff --git a/drivers/staging/meilhaus/mesubdevice.c b/drivers/staging/meilhaus/mesubdevice.c
index 98d4f1f..b2e9567 100644
--- a/drivers/staging/meilhaus/mesubdevice.c
+++ b/drivers/staging/meilhaus/mesubdevice.c
@@ -101,9 +101,9 @@
 
 static int me_subdevice_io_stream_config(struct me_subdevice *subdevice,
 					 struct file *filep,
-					 meIOStreamConfig_t * config_list,
+					 meIOStreamConfig_t *config_list,
 					 int count,
-					 meIOStreamTrigger_t * trigger,
+					 meIOStreamTrigger_t *trigger,
 					 int fifo_irq_threshold, int flags)
 {
 	PDEBUG("executed.\n");
@@ -162,7 +162,7 @@
 	return ME_ERRNO_NOT_SUPPORTED;
 }
 
-static int me_subdevice_lock_subdevice(me_subdevice_t * subdevice,
+static int me_subdevice_lock_subdevice(me_subdevice_t *subdevice,
 				       struct file *filep, int lock, int flags)
 {
 	PDEBUG("executed.\n");
@@ -235,7 +235,7 @@
 }
 
 static int me_subdevice_config_load(struct me_subdevice *subdevice,
-				    me_cfg_device_entry_t * config)
+				    me_cfg_device_entry_t *config)
 {
 	PDEBUG("executed.\n");
 	return ME_ERRNO_SUCCESS;
@@ -248,7 +248,7 @@
 	kfree(subdevice);
 }
 
-int me_subdevice_init(me_subdevice_t * subdevice)
+int me_subdevice_init(me_subdevice_t *subdevice)
 {
 	int err;
 
@@ -308,7 +308,7 @@
 	return 0;
 }
 
-void me_subdevice_deinit(me_subdevice_t * subdevice)
+void me_subdevice_deinit(me_subdevice_t *subdevice)
 {
 	PDEBUG("executed.\n");
 	me_subdevice_io_reset_subdevice(subdevice, NULL,
diff --git a/drivers/staging/meilhaus/metempl_device.c b/drivers/staging/meilhaus/metempl_device.c
index e48632d..bdaf6df 100644
--- a/drivers/staging/meilhaus/metempl_device.c
+++ b/drivers/staging/meilhaus/metempl_device.c
@@ -109,6 +109,7 @@
 
 	return (me_device_t *) metempl_device;
 }
+EXPORT_SYMBOL(metempl_pci_constructor);
 
 // Init and exit of module.
 
@@ -132,6 +133,3 @@
 MODULE_DESCRIPTION("Device Driver Module for Template Device");
 MODULE_SUPPORTED_DEVICE("Meilhaus Template Devices");
 MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(metempl_pci_constructor);
diff --git a/drivers/staging/meilhaus/metempl_sub.c b/drivers/staging/meilhaus/metempl_sub.c
index f1d65d8..b5a6a97 100644
--- a/drivers/staging/meilhaus/metempl_sub.c
+++ b/drivers/staging/meilhaus/metempl_sub.c
@@ -35,7 +35,7 @@
 
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/types.h>
 
 #include "medefines.h"
@@ -68,7 +68,7 @@
 	kfree(instance);
 }
 
-static int metempl_sub_query_number_channels(me_subdevice_t * subdevice,
+static int metempl_sub_query_number_channels(me_subdevice_t *subdevice,
 					     int *number)
 {
 	PDEBUG("executed.\n");
@@ -76,7 +76,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int metempl_sub_query_subdevice_type(me_subdevice_t * subdevice,
+static int metempl_sub_query_subdevice_type(me_subdevice_t *subdevice,
 					    int *type, int *subtype)
 {
 	PDEBUG("executed.\n");
@@ -85,7 +85,7 @@
 	return ME_ERRNO_SUCCESS;
 }
 
-static int metempl_sub_query_subdevice_caps(me_subdevice_t * subdevice,
+static int metempl_sub_query_subdevice_caps(me_subdevice_t *subdevice,
 					    int *caps)
 {
 	PDEBUG("executed.\n");
@@ -95,7 +95,7 @@
 
 metempl_sub_subdevice_t *metempl_sub_constructor(uint32_t reg_base,
 						 unsigned int sub_idx,
-						 spinlock_t * ctrl_reg_lock)
+						 spinlock_t *ctrl_reg_lock)
 {
 	metempl_sub_subdevice_t *subdevice;
 	int err;
diff --git a/drivers/staging/mimio/Kconfig b/drivers/staging/mimio/Kconfig
index c0ba4c8..505dcb2 100644
--- a/drivers/staging/mimio/Kconfig
+++ b/drivers/staging/mimio/Kconfig
@@ -1,6 +1,6 @@
 config INPUT_MIMIO
 	tristate "Mimio Xi interactive whiteboard support"
-	depends on USB
+	depends on USB && INPUT
 	default N
 	help
 	  Say Y here if you want to use a Mimio Xi interactive
diff --git a/drivers/staging/otus/80211core/amsdu.c b/drivers/staging/otus/80211core/amsdu.c
index c9123d5..0321288 100644
--- a/drivers/staging/otus/80211core/amsdu.c
+++ b/drivers/staging/otus/80211core/amsdu.c
@@ -34,53 +34,53 @@
 /*      Stephen Chen        Atheros Communications, INC.    2007.2      */
 /*                                                                      */
 /************************************************************************/
-zbuf_t* zfGetAmsduSubFrame(zdev_t* dev, zbuf_t* buf, u16_t* offset)
+zbuf_t *zfGetAmsduSubFrame(zdev_t *dev, zbuf_t *buf, u16_t *offset)
 {
-    u16_t subframeLen;
-    u16_t amsduLen = zfwBufGetSize(dev, buf);
-    zbuf_t* newBuf;
+	u16_t subframeLen;
+	u16_t amsduLen = zfwBufGetSize(dev, buf);
+	zbuf_t *newBuf;
 
-    ZM_PERFORMANCE_RX_AMSDU(dev, buf, amsduLen);
+	ZM_PERFORMANCE_RX_AMSDU(dev, buf, amsduLen);
 
-    /* Verify A-MSDU length */
-    if (amsduLen < (*offset + 14))
-    {
-        return NULL;
-    }
+	/* Verify A-MSDU length */
+	if (amsduLen < (*offset + 14))
+		return NULL;
 
-    /* Locate A-MSDU subframe by offset and verify subframe length */
-    subframeLen = (zmw_buf_readb(dev, buf, *offset + 12) << 8) +
-                  zmw_buf_readb(dev, buf, *offset + 13);
-    if (subframeLen == 0)
-    {
-        return NULL;
-    }
+	/* Locate A-MSDU subframe by offset and verify subframe length */
+	subframeLen = (zmw_buf_readb(dev, buf, *offset + 12) << 8) +
+		zmw_buf_readb(dev, buf, *offset + 13);
 
-    /* Verify A-MSDU subframe length */
-    if ((*offset+14+subframeLen) <= amsduLen)
-    {
-        /* Allocate a new buffer */
-        if ((newBuf = zfwBufAllocate(dev, 24+2+subframeLen)) != NULL)
-        {
-#ifdef ZM_ENABLE_NATIVE_WIFI
-            /* Copy and convert subframe to wlan frame format */
-            /* SHALL NOT INCLUDE QOS and AMSDU header. Ray 20070807 For Vista */
-            zfRxBufferCopy(dev, newBuf, buf, 0, 0, 24);
-            zfRxBufferCopy(dev, newBuf, buf, 24, *offset+14, subframeLen);
-            zfwBufSetSize(dev, newBuf, 24+subframeLen);
-#else
-            /* Copy subframe to new buffer */
-            zfRxBufferCopy(dev, newBuf, buf, 0, *offset, 14+subframeLen);
-            zfwBufSetSize(dev, newBuf, 14+subframeLen);
-#endif
-            /* Update offset */
-            *offset += (((14+subframeLen)+3) & 0xfffc);
+	if (subframeLen == 0)
+		return NULL;
 
-            /* Return buffer pointer */
-            return newBuf;
-        }
-    }
-    return NULL;
+	/* Verify A-MSDU subframe length */
+	if ((*offset+14+subframeLen) <= amsduLen) {
+		/* Allocate a new buffer */
+		newBuf = zfwBufAllocate(dev, 24+2+subframeLen);
+		if (newBuf != NULL) {
+			#ifdef ZM_ENABLE_NATIVE_WIFI
+			/* Copy and convert subframe to wlan frame format
+			* SHALL NOT INCLUDE QOS and AMSDU header.
+			* Ray 20070807 For Vista
+			*/
+			zfRxBufferCopy(dev, newBuf, buf, 0, 0, 24);
+			zfRxBufferCopy(dev, newBuf, buf, 24, *offset+14,
+					subframeLen);
+			zfwBufSetSize(dev, newBuf, 24+subframeLen);
+			#else
+			/* Copy subframe to new buffer */
+			zfRxBufferCopy(dev, newBuf, buf, 0, *offset,
+					14+subframeLen);
+			zfwBufSetSize(dev, newBuf, 14+subframeLen);
+			#endif
+			/* Update offset */
+			*offset += (((14+subframeLen)+3) & 0xfffc);
+
+			/* Return buffer pointer */
+			return newBuf;
+		}
+	}
+	return NULL;
 }
 
 
@@ -101,34 +101,29 @@
 /*      Stephen Chen        Atheros Communications, INC.    2007.2      */
 /*                                                                      */
 /************************************************************************/
-void zfDeAmsdu(zdev_t* dev, zbuf_t* buf, u16_t vap, u8_t encryMode)
+void zfDeAmsdu(zdev_t *dev, zbuf_t *buf, u16_t vap, u8_t encryMode)
 {
-    u16_t offset = ZM_SIZE_OF_WLAN_DATA_HEADER+ZM_SIZE_OF_QOS_CTRL;
-    zbuf_t* subframeBuf;
-    zmw_get_wlan_dev(dev);
+	u16_t offset = ZM_SIZE_OF_WLAN_DATA_HEADER+ZM_SIZE_OF_QOS_CTRL;
+	zbuf_t *subframeBuf;
+	zmw_get_wlan_dev(dev);
 
-    ZM_BUFFER_TRACE(dev, buf)
+	ZM_BUFFER_TRACE(dev, buf)
 
-    if (encryMode == ZM_AES || encryMode == ZM_TKIP)
-    {
-        offset += (ZM_SIZE_OF_IV + ZM_SIZE_OF_EXT_IV);
-    }
-    else if (encryMode == ZM_WEP64 || encryMode == ZM_WEP128)
-    {
-        offset += ZM_SIZE_OF_IV;
-    }
+	if (encryMode == ZM_AES || encryMode == ZM_TKIP)
+		offset += (ZM_SIZE_OF_IV + ZM_SIZE_OF_EXT_IV);
+	else if (encryMode == ZM_WEP64 || encryMode == ZM_WEP128)
+		offset += ZM_SIZE_OF_IV;
 
-    /* Repeatly calling zfGetAmsduSubFrame() until NULL returned */
-    while ((subframeBuf = zfGetAmsduSubFrame(dev, buf, &offset)) != NULL)
-    {
-        wd->commTally.NotifyNDISRxFrmCnt++;
-        if (wd->zfcbRecvEth != NULL)
-    	{
-            wd->zfcbRecvEth(dev, subframeBuf, (u8_t)vap);
-            ZM_PERFORMANCE_RX_MSDU(dev, wd->tick);
-        }
-    }
-    zfwBufFree(dev, buf, 0);
 
-    return;
+	/* Repeatly calling zfGetAmsduSubFrame() until NULL returned */
+	while ((subframeBuf = zfGetAmsduSubFrame(dev, buf, &offset)) != NULL) {
+		wd->commTally.NotifyNDISRxFrmCnt++;
+		if (wd->zfcbRecvEth != NULL) {
+			wd->zfcbRecvEth(dev, subframeBuf, (u8_t)vap);
+			ZM_PERFORMANCE_RX_MSDU(dev, wd->tick);
+		}
+	}
+	zfwBufFree(dev, buf, 0);
+
+	return;
 }
diff --git a/drivers/staging/otus/80211core/cmmsta.c b/drivers/staging/otus/80211core/cmmsta.c
index c75ba11..b28a4e2 100644
--- a/drivers/staging/otus/80211core/cmmsta.c
+++ b/drivers/staging/otus/80211core/cmmsta.c
@@ -724,6 +724,9 @@
 /* process 802.11h Dynamic Frequency Selection */
 void zfStaUpdateDot11HDFS(zdev_t* dev, zbuf_t* buf)
 {
+    //u8_t    length, channel, is5G;
+    u16_t   offset;
+
     zmw_get_wlan_dev(dev);
 
     /*
@@ -736,8 +739,6 @@
     |Value |   37     |  3   |       0 or 1      |unsigned integer  |unsigned integer    |
     +------+----------+------+-------------------+------------------+--------------------+
     */
-    //u8_t    length, channel, is5G;
-    u16_t   offset;
 
     /* get EID(Channel Switch Announcement) */
     if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_CHANNEL_SWITCH_ANNOUNCE)) == 0xffff )
diff --git a/drivers/staging/otus/80211core/coid.c b/drivers/staging/otus/80211core/coid.c
index 6007f31..88f8d349 100644
--- a/drivers/staging/otus/80211core/coid.c
+++ b/drivers/staging/otus/80211core/coid.c
@@ -214,10 +214,10 @@
 
 u32_t zfiWlanQueryTransmitPower(zdev_t* dev)
 {
-    zmw_get_wlan_dev(dev);
-
     u32_t ret = 0;
 
+    zmw_get_wlan_dev(dev);
+
     if (zfStaIsConnected(dev)) {
         ret = wd->sta.connPowerInHalfDbm;
     } else {
@@ -1432,12 +1432,12 @@
 
 u32_t zfiWlanQueryFrequencyAttribute(zdev_t* dev, u32_t freq)
 {
-    zmw_get_wlan_dev(dev);
-
     u8_t  i;
     u16_t frequency = (u16_t) (freq/1000);
     u32_t ret = 0;
 
+    zmw_get_wlan_dev(dev);
+
     for (i = 0; i < wd->regulationTable.allowChannelCnt; i++)
     {
         if ( wd->regulationTable.allowChannel[i].channel == frequency )
diff --git a/drivers/staging/otus/80211core/cwm.c b/drivers/staging/otus/80211core/cwm.c
index 80f1141..1bd0b1f 100644
--- a/drivers/staging/otus/80211core/cwm.c
+++ b/drivers/staging/otus/80211core/cwm.c
@@ -75,9 +75,9 @@
 
     if((wd->wlanMode == ZM_MODE_INFRASTRUCTURE || wd->wlanMode == ZM_MODE_PSEUDO ||
         wd->wlanMode == ZM_MODE_IBSS)) {
-        if (wd->sta.ie.HtCap.HtCapInfo && HTCAP_SupChannelWidthSet != 0 &&
-            wd->sta.ie.HtInfo.ChannelInfo && ExtHtCap_RecomTxWidthSet != 0 &&
-            (wd->sta.ie.HtInfo.ChannelInfo && ExtHtCap_ExtChannelOffsetAbove) == 1) {
+        if ((wd->sta.ie.HtCap.HtCapInfo & HTCAP_SupChannelWidthSet) &&
+            (wd->sta.ie.HtInfo.ChannelInfo & ExtHtCap_RecomTxWidthSet) &&
+            (wd->sta.ie.HtInfo.ChannelInfo & ExtHtCap_ExtChannelOffsetAbove)) {
 
             wd->cwm.cw_width = CWM_WIDTH40;
         }
diff --git a/drivers/staging/otus/TODO b/drivers/staging/otus/TODO
index e912293..4caf026 100644
--- a/drivers/staging/otus/TODO
+++ b/drivers/staging/otus/TODO
@@ -1,8 +1,15 @@
+I'm hesitant to add a TODO file here, as the wireless developers would
+really have people help them out on the "clean" ar9170 driver that can
+be found at the linux-wireless developer site.
+
+But, if you wish to clean up this driver instead, here's a short list of
+things that need to be done to get it into a more mergable shape:
+
 TODO:
 	- checkpatch.pl cleanups
 	- sparse cleanups
 	- port to in-kernel 80211 stack
-	- proper network developer maintainer
+	- review by the wireless developer community
 
 Please send any patches to Greg Kroah-Hartman <greg@kroah.com> and
 Luis Rodriguez <Luis.Rodriguez@Atheros.com> and the
diff --git a/drivers/staging/otus/hal/hpani.c b/drivers/staging/otus/hal/hpani.c
index ba95b5d01..0afecd8 100644
--- a/drivers/staging/otus/hal/hpani.c
+++ b/drivers/staging/otus/hal/hpani.c
@@ -55,10 +55,10 @@
 s32_t BEACON_RSSI(zdev_t* dev)
 {
     s32_t rssi;
+    struct zsHpPriv *HpPriv;
 
     zmw_get_wlan_dev(dev);
-
-    struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
+    HpPriv = (struct zsHpPriv*)wd->hpPrivate;
 
     rssi = ZM_HAL_EP_RND(HpPriv->stats.ast_nodestats.ns_avgbrssi, ZM_HAL_RSSI_EP_MULTIPLIER);
 
@@ -74,16 +74,16 @@
 {
 #define N(a)     (sizeof(a) / sizeof(a[0]))
     u32_t i;
-
-    zmw_get_wlan_dev(dev);
-
-    struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
+    struct zsHpPriv *HpPriv;
 
     const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
     const int coarseHigh[]       = { -14, -14, -14, -14, -12 };
     const int coarseLow[]        = { -64, -64, -64, -64, -70 };
     const int firpwr[]           = { -78, -78, -78, -78, -80 };
 
+    zmw_get_wlan_dev(dev);
+    HpPriv = (struct zsHpPriv*)wd->hpPrivate;
+
     for (i = 0; i < 5; i++)
     {
         HpPriv->totalSizeDesired[i] = totalSizeDesired[i];
@@ -139,12 +139,12 @@
 {
 #define N(a) (sizeof(a)/sizeof(a[0]))
     typedef s32_t TABLE[];
+    struct zsHpPriv *HpPriv;
+    struct zsAniState *aniState;
 
     zmw_get_wlan_dev(dev);
-
-    struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
-
-    struct zsAniState *aniState = HpPriv->curani;
+    HpPriv = (struct zsHpPriv*)wd->hpPrivate;
+    aniState = HpPriv->curani;
 
     switch (cmd)
     {
@@ -346,11 +346,10 @@
 void zfHpAniRestart(zdev_t* dev)
 {
     struct zsAniState *aniState;
+    struct zsHpPriv *HpPriv;
 
     zmw_get_wlan_dev(dev);
-
-    struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
-
+    HpPriv = (struct zsHpPriv*)wd->hpPrivate;
     aniState = HpPriv->curani;
 
     aniState->listenTime = 0;
@@ -387,10 +386,10 @@
 {
     struct zsAniState *aniState;
     s32_t rssi;
+    struct zsHpPriv *HpPriv;
 
     zmw_get_wlan_dev(dev);
-
-    struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
+    HpPriv = (struct zsHpPriv*)wd->hpPrivate;
 
     //HALASSERT(chan != NULL);
 
@@ -466,10 +465,10 @@
 {
     struct zsAniState *aniState;
     s32_t rssi;
+    struct zsHpPriv *HpPriv;
 
     zmw_get_wlan_dev(dev);
-
-    struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
+    HpPriv = (struct zsHpPriv*)wd->hpPrivate;
 
     //HALASSERT(chan != NULL);
 
@@ -511,11 +510,10 @@
 {
     struct zsAniState *aniState;
     s32_t rssi;
+    struct zsHpPriv *HpPriv;
 
     zmw_get_wlan_dev(dev);
-
-    struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
-
+    HpPriv = (struct zsHpPriv*)wd->hpPrivate;
     aniState = HpPriv->curani;
 
     rssi = BEACON_RSSI(dev);
@@ -586,10 +584,10 @@
     struct zsAniState *aniState;
     u32_t txFrameCount, rxFrameCount, cycleCount;
     s32_t listenTime;
+    struct zsHpPriv *HpPriv;
 
     zmw_get_wlan_dev(dev);
-
-    struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
+    HpPriv = (struct zsHpPriv*)wd->hpPrivate;
 
     txFrameCount = 0;//OS_REG_READ(ah, AR_TFCNT);
     rxFrameCount = 0;//OS_REG_READ(ah, AR_RFCNT);
@@ -627,10 +625,10 @@
 {
     struct zsAniState *aniState;
     //s32_t listenTime;
+    struct zsHpPriv *HpPriv;
 
     zmw_get_wlan_dev(dev);
-
-    struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
+    HpPriv = (struct zsHpPriv*)wd->hpPrivate;
 
     /*
      * Since we're called from end of rx tasklet, we also check for
diff --git a/drivers/staging/otus/hal/hpmain.c b/drivers/staging/otus/hal/hpmain.c
index 2e65c46..322585b 100644
--- a/drivers/staging/otus/hal/hpmain.c
+++ b/drivers/staging/otus/hal/hpmain.c
@@ -152,7 +152,7 @@
     else
     {
     #ifndef ZM_OTUS_LINUX_PHASE_2
-        /* donwload the normal frimware */
+        /* download the normal firmware */
         if ((ret = zfFirmwareDownload(dev, (u32_t*)zcFwImage,
                 (u32_t)zcFwImageSize, ZM_FIRMWARE_WLAN_ADDR)) != ZM_SUCCESS)
         {
@@ -328,8 +328,8 @@
     u16_t modesIndex = 0;
     u16_t freqIndex = 0;
     u32_t tmp, tmp1;
-    zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv=wd->hpPrivate;
+    struct zsHpPriv* hpPriv;
+
     u32_t eepromBoardData[15][6] = {
     /* Register   A-20        A-20/40     G-20/40     G-20        G-Turbo    */
         {0x9964,    0,      0,      0,      0,      0},
@@ -349,6 +349,9 @@
         {0xa258,    0,      0,      0,      0,      0},
     };
 
+    zmw_get_wlan_dev(dev);
+    hpPriv=wd->hpPrivate;
+
     /* #1 Save the initial value of the related RIFS register settings */
     //((struct zsHpPriv*)wd->hpPrivate)->isInitialPhy++;
 
@@ -1324,9 +1327,10 @@
     int delta_slope_coeff_man;
     int delta_slope_coeff_exp_shgi;
     int delta_slope_coeff_man_shgi;
+    struct zsHpPriv* hpPriv;
 
     zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv = wd->hpPrivate;
+    hpPriv = wd->hpPrivate;
 
     zm_msg1_scan(ZM_LV_1, "Frequency = ", frequency);
     zm_msg1_scan(ZM_LV_1, "bw40 = ", bw40);
@@ -1560,9 +1564,10 @@
 {
     u8_t i;
     u32_t key[4] = {0, 0, 0, 0};
+    struct zsHpPriv* hpPriv;
 
     zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv=wd->hpPrivate;
+    hpPriv=wd->hpPrivate;
 
     for(i=0;i<4;i++)
     {
@@ -1601,9 +1606,10 @@
     u32_t cmd[(ZM_MAX_CMD_SIZE/4)];
     u16_t ret;
     u16_t i;
+    struct zsHpPriv* hpPriv;
 
     zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv=wd->hpPrivate;
+    hpPriv=wd->hpPrivate;
 
 #if 0   /* remove to zfCoreSetKey() */
     zmw_declare_for_critical_section();
@@ -1670,8 +1676,10 @@
     u16_t macAddr[3] = {0, 0, 0};
 
     #ifdef ZM_ENABLE_IBSS_WPA2PSK
+    struct zsHpPriv* hpPriv;
+
     zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv = wd->hpPrivate;
+    hpPriv = wd->hpPrivate;
 
     if ( hpPriv->dot11Mode == ZM_HAL_80211_MODE_IBSS_WPA2PSK )
     { /* If not wpa2psk , use traditional */
@@ -1702,8 +1710,10 @@
 u32_t zfHpSetPerUserKey(zdev_t* dev, u8_t user, u8_t keyId, u8_t* mac, u8_t type, u32_t* key, u32_t* micKey)
 {
 #ifdef ZM_ENABLE_IBSS_WPA2PSK
+    struct zsHpPriv* hpPriv;
+
     zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv = wd->hpPrivate;
+    hpPriv = wd->hpPrivate;
 
     if ( hpPriv->dot11Mode == ZM_HAL_80211_MODE_IBSS_WPA2PSK )
     { /* If not wpa2psk , use traditional */
@@ -1918,9 +1928,10 @@
 
 u16_t zfHpSetApStaMode(zdev_t* dev, u8_t mode)
 {
-    zmw_get_wlan_dev(dev);
+    struct zsHpPriv* hpPriv;
 
-    struct zsHpPriv* hpPriv = wd->hpPrivate;
+    zmw_get_wlan_dev(dev);
+    hpPriv = wd->hpPrivate;
     hpPriv->dot11Mode = mode;
 
     switch(mode)
@@ -1993,8 +2004,10 @@
 u8_t zfHpUpdateQosParameter(zdev_t* dev, u16_t* cwminTbl, u16_t* cwmaxTbl,
         u16_t* aifsTbl, u16_t* txopTbl)
 {
+    struct zsHpPriv* hpPriv;
+
     zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv = wd->hpPrivate;
+    hpPriv = wd->hpPrivate;
 
     zm_msg0_mm(ZM_LV_0, "zfHalUpdateQosParameter()");
 
@@ -2259,9 +2272,11 @@
     //
     //ret = zfIssueCmd(dev, cmd, 12, ZM_CWM_READ, 0);
     //return ret;
-    zmw_get_wlan_dev(dev);
 
-    struct zsHpPriv* hpPriv=wd->hpPrivate;
+    struct zsHpPriv* hpPriv;
+
+    zmw_get_wlan_dev(dev);
+    hpPriv=wd->hpPrivate;
 
     zfCoreCwmBusy(dev, zfCwmIsExtChanBusy(hpPriv->ctlBusy, hpPriv->extBusy));
 
@@ -2291,9 +2306,10 @@
  */
 u32_t zfHpAniUpdateRssi(zdev_t* dev, u8_t rssi)
 {
-    zmw_get_wlan_dev(dev);
+    struct zsHpPriv* hpPriv;
 
-    struct zsHpPriv* hpPriv=wd->hpPrivate;
+    zmw_get_wlan_dev(dev);
+    hpPriv=wd->hpPrivate;
 
     hpPriv->stats.ast_nodestats.ns_avgbrssi = rssi;
 
@@ -2325,11 +2341,12 @@
 
 u32_t zfHpGetTransmitPower(zdev_t* dev)
 {
-    zmw_get_wlan_dev(dev);
-
-    struct zsHpPriv*    hpPriv  = wd->hpPrivate;
+    struct zsHpPriv*    hpPriv;
     u16_t               tpc     = 0;
 
+    zmw_get_wlan_dev(dev);
+    hpPriv  = wd->hpPrivate;
+
     if (hpPriv->hwFrequency < 3000) {
         tpc = hpPriv->tPow2x2g[0] & 0x3f;
         wd->maxTxPower2 &= 0x3f;
@@ -2345,11 +2362,12 @@
 
 u8_t zfHpGetMinTxPower(zdev_t* dev)
 {
-    zmw_get_wlan_dev(dev);
-
-    struct zsHpPriv*    hpPriv  = wd->hpPrivate;
+    struct zsHpPriv*    hpPriv;
     u8_t               tpc     = 0;
 
+    zmw_get_wlan_dev(dev);
+    hpPriv  = wd->hpPrivate;
+
     if (hpPriv->hwFrequency < 3000)
     {
         if(wd->BandWidth40)
@@ -2382,11 +2400,12 @@
 
 u8_t zfHpGetMaxTxPower(zdev_t* dev)
 {
-    zmw_get_wlan_dev(dev);
-
-    struct zsHpPriv*    hpPriv  = wd->hpPrivate;
+    struct zsHpPriv*    hpPriv;
     u8_t               tpc     = 0;
 
+    zmw_get_wlan_dev(dev);
+    hpPriv  = wd->hpPrivate;
+
     if (hpPriv->hwFrequency < 3000)
     {
         tpc = (hpPriv->tPow2xCck[0]&0x3f);
@@ -2421,11 +2440,13 @@
 
 void zfHpHeartBeat(zdev_t* dev)
 {
-    zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv=wd->hpPrivate;
+    struct zsHpPriv* hpPriv;
     u8_t polluted = 0;
     u8_t ackTpc;
 
+    zmw_get_wlan_dev(dev);
+    hpPriv=wd->hpPrivate;
+
     /* Workaround : Make OTUS fire more beacon in ad hoc mode in 2.4GHz */
     if (hpPriv->ibssBcnEnabled != 0)
     {
@@ -4219,8 +4240,10 @@
 
 void zfHpPowerSaveSetState(zdev_t* dev, u8_t psState)
 {
+    struct zsHpPriv* hpPriv;
+
     zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv = wd->hpPrivate;
+    hpPriv = wd->hpPrivate;
 
 	//DbgPrint("INTO zfHpPowerSaveSetState");
 
@@ -4279,8 +4302,10 @@
 
 void zfHpSetAggPktNum(zdev_t* dev, u32_t num)
 {
+    struct zsHpPriv* hpPriv;
+
     zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv = wd->hpPrivate;
+    hpPriv = wd->hpPrivate;
 
     num = (num << 16) | (0xa);
 
@@ -4310,8 +4335,10 @@
 
 void zfHpSetSlotTime(zdev_t* dev, u8_t type)
 {
+    struct zsHpPriv* hpPriv;
+
     zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv = wd->hpPrivate;
+    hpPriv = wd->hpPrivate;
 
     if (type == 0)
     {
@@ -4376,8 +4403,10 @@
 
 void zfHpBeginSiteSurvey(zdev_t* dev, u8_t status)
 {
+    struct zsHpPriv* hpPriv;
+
     zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv=wd->hpPrivate;
+    hpPriv=wd->hpPrivate;
 
     if ( status == 1 )
     { // Connected
@@ -4421,8 +4450,10 @@
 
 void zfHpFinishSiteSurvey(zdev_t* dev, u8_t status)
 {
+    struct zsHpPriv* hpPriv;
+
     zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv=wd->hpPrivate;
+    hpPriv=wd->hpPrivate;
 
     zmw_declare_for_critical_section();
 
@@ -4527,16 +4558,20 @@
 
 u32_t zfHpCapability(zdev_t* dev)
 {
+    struct zsHpPriv* hpPriv;
+
     zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv=wd->hpPrivate;
+    hpPriv=wd->hpPrivate;
 
     return hpPriv->halCapability;
 }
 
 void zfHpSetRollCallTable(zdev_t* dev)
 {
+    struct zsHpPriv* hpPriv;
+
     zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv=wd->hpPrivate;
+    hpPriv=wd->hpPrivate;
 
     if (hpPriv->camRollCallTable != (u64_t) 0)
     {
diff --git a/drivers/staging/otus/hal/hpreg.c b/drivers/staging/otus/hal/hpreg.c
index 3cfeba8..d9894fe 100644
--- a/drivers/staging/otus/hal/hpreg.c
+++ b/drivers/staging/otus/hal/hpreg.c
@@ -1770,8 +1770,10 @@
 	REG_DOMAIN rd5GHz, rd2GHz;
 	const struct cmode *cm;
 	s16_t next=0,b;
+	struct zsHpPriv* hpPriv;
+
     zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv=wd->hpPrivate;
+    hpPriv=wd->hpPrivate;
 
     zmw_declare_for_critical_section();
 
@@ -2473,9 +2475,10 @@
 
 void zfHpDisableDfsChannel(zdev_t* dev, u8_t disableFlag)
 {
-    zmw_get_wlan_dev(dev);
+    struct zsHpPriv* hpPriv;
 
-    struct zsHpPriv* hpPriv=wd->hpPrivate;
+    zmw_get_wlan_dev(dev);
+    hpPriv=wd->hpPrivate;
     hpPriv->disableDfsCh = disableFlag;
     return;
 }
diff --git a/drivers/staging/otus/hal/hprw.c b/drivers/staging/otus/hal/hprw.c
index db7d495..d9fad47 100644
--- a/drivers/staging/otus/hal/hprw.c
+++ b/drivers/staging/otus/hal/hprw.c
@@ -29,8 +29,10 @@
 
 void zfInitCmdQueue(zdev_t* dev)
 {
+    struct zsHpPriv* hpPriv;
+
     zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv = (struct zsHpPriv*)(wd->hpPrivate);
+    hpPriv = (struct zsHpPriv*)(wd->hpPrivate);
 
     zmw_declare_for_critical_section();
 
@@ -48,9 +50,10 @@
 u16_t zfPutCmd(zdev_t* dev, u32_t* cmd, u16_t cmdLen, u16_t src, u8_t* buf)
 {
     u16_t i;
+    struct zsHpPriv* hpPriv;
 
     zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv=wd->hpPrivate;
+    hpPriv=wd->hpPrivate;
 
     /* Make sure command length < ZM_MAX_CMD_SIZE */
     zm_assert(cmdLen <= ZM_MAX_CMD_SIZE);
@@ -77,9 +80,10 @@
 u16_t zfGetCmd(zdev_t* dev, u32_t* cmd, u16_t* cmdLen, u16_t* src, u8_t** buf)
 {
     u16_t i;
+    struct zsHpPriv* hpPriv;
 
     zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv=wd->hpPrivate;
+    hpPriv=wd->hpPrivate;
 
     if (hpPriv->cmdTail == hpPriv->cmdHead)
     {
@@ -106,9 +110,10 @@
     u16_t ncmdLen = 0;
     u16_t cmdFlag = 0;
     u16_t i;
+    struct zsHpPriv* hpPriv;
 
     zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv=wd->hpPrivate;
+    hpPriv=wd->hpPrivate;
 
     zmw_declare_for_critical_section();
 
@@ -141,8 +146,10 @@
 
 void zfiSendCmdComp(zdev_t* dev)
 {
+    struct zsHpPriv* hpPriv;
+
     zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv=wd->hpPrivate;
+    hpPriv=wd->hpPrivate;
 
     zmw_declare_for_critical_section();
 
@@ -158,9 +165,10 @@
 {
     u16_t cmdFlag = 0;
     u16_t ret;
+    struct zsHpPriv* hpPriv;
 
     zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv=wd->hpPrivate;
+    hpPriv=wd->hpPrivate;
 
     zmw_declare_for_critical_section();
 
@@ -214,9 +222,10 @@
     u16_t i;
     s32_t nf;
     s32_t noisefloor[4];
+    struct zsHpPriv* hpPriv;
 
     zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv=wd->hpPrivate;
+    hpPriv=wd->hpPrivate;
 
 
     zmw_declare_for_critical_section();
@@ -826,9 +835,10 @@
     u32_t cmd[(ZM_MAX_CMD_SIZE/4)];
     u16_t i;
     u16_t ret;
+    struct zsHpPriv* hpPriv;
 
     zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv=wd->hpPrivate;
+    hpPriv=wd->hpPrivate;
 
     zmw_declare_for_critical_section();
 
@@ -892,8 +902,10 @@
     u32_t cmd[(ZM_MAX_CMD_SIZE/4)];
     u16_t i;
     u16_t ret;
+    struct zsHpPriv* hpPriv;
+
     zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv=wd->hpPrivate;
+    hpPriv=wd->hpPrivate;
 
     zmw_declare_for_critical_section();
 
diff --git a/drivers/staging/otus/hal/hpusb.c b/drivers/staging/otus/hal/hpusb.c
index 4b76de9..ee93900 100644
--- a/drivers/staging/otus/hal/hpusb.c
+++ b/drivers/staging/otus/hal/hpusb.c
@@ -64,9 +64,10 @@
     u32_t oldPhyCtrl;
 
     u16_t tpc = 0;
+    struct zsHpPriv* hpPriv;
 
     zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv=wd->hpPrivate;
+    hpPriv=wd->hpPrivate;
 
    /* mm */
     if (header == NULL)
@@ -330,8 +331,10 @@
     u16_t i;
    	u16_t swlpOffset;
 #endif /* #if ZM_SW_LOOP_BACK == 1 */
+    struct zsHpPriv* hpPriv;
+
     zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv=wd->hpPrivate;
+    hpPriv=wd->hpPrivate;
 
     zm_msg1_tx(ZM_LV_1, "zfHpSend(), len = ", 12 + headerLen-8 + snapLen + zfwBufGetSize(dev, buf) + 4 + 8);
 
@@ -576,8 +579,10 @@
     u32_t               rxMCS;
     u32_t               rxBW;
     u32_t               rxSG;
+    struct zsHpPriv* hpPriv;
+
     zmw_get_wlan_dev(dev);
-    struct zsHpPriv* hpPriv=wd->hpPrivate;
+    hpPriv=wd->hpPrivate;
 
     //zm_msg0_rx(ZM_LV_0, "zfiUsbRecv()");
 
diff --git a/drivers/staging/otus/ioctl.c b/drivers/staging/otus/ioctl.c
index 7a5c1e8..ce04218 100644
--- a/drivers/staging/otus/ioctl.c
+++ b/drivers/staging/otus/ioctl.c
@@ -25,7 +25,7 @@
 /************************************************************************/
 #include <linux/module.h>
 #include <linux/if_arp.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 
 #include "usbdrv.h"
 
@@ -34,7 +34,7 @@
 #define ZD_IOCTL_GETWPAIE		    (SIOCDEVPRIVATE + 3)
 #ifdef ZM_ENABLE_CENC
 #define ZM_IOCTL_CENC               (SIOCDEVPRIVATE + 4)
-#endif //ZM_ENABLE_CENC
+#endif  /* ZM_ENABLE_CENC */
 #define ZD_PARAM_ROAMING		    0x0001
 #define ZD_PARAM_PRIVACY		    0x0002
 #define ZD_PARAM_WPA			    0x0003
@@ -45,7 +45,7 @@
 
 #ifdef ZM_ENABLE_CENC
 #define P80211_PACKET_CENCFLAG		0x0001
-#endif //ZM_ENABLE_CENC
+#endif  /* ZM_ENABLE_CENC */
 #define P80211_PACKET_SETKEY     	0x0003
 
 #define ZD_CMD_SET_ENCRYPT_KEY		0x0001
@@ -62,204 +62,190 @@
 #include <net/iw_handler.h>
 #endif
 
-extern u16_t zfLnxGetVapId(zdev_t* dev);
+extern u16_t zfLnxGetVapId(zdev_t *dev);
 
 static const u32_t channel_frequency_11A[] =
 {
-//Even element for Channel Number, Odd for Frequency
-    36,5180,
-    40,5200,
-    44,5220,
-    48,5240,
-    52,5260,
-    56,5280,
-    60,5300,
-    64,5320,
-    100,5500,
-    104,5520,
-    108,5540,
-    112,5560,
-    116,5580,
-    120,5600,
-    124,5620,
-    128,5640,
-    132,5660,
-    136,5680,
-    140,5700,
-//
-    184,4920,
-    188,4940,
-    192,4960,
-    196,4980,
-    8,5040,
-    12,5060,
-    16,5080,
-    34,5170,
-    38,5190,
-    42,5210,
-    46,5230,
-//
-    149,5745,
-    153,5765,
-    157,5785,
-    161,5805,
-    165,5825
-//
+	/* Even element for Channel Number, Odd for Frequency */
+	36, 5180,
+	40, 5200,
+	44, 5220,
+	48, 5240,
+	52, 5260,
+	56, 5280,
+	60, 5300,
+	64, 5320,
+	100, 5500,
+	104, 5520,
+	108, 5540,
+	112, 5560,
+	116, 5580,
+	120, 5600,
+	124, 5620,
+	128, 5640,
+	132, 5660,
+	136, 5680,
+	140, 5700,
+	/**/
+	184, 4920,
+	188, 4940,
+	192, 4960,
+	196, 4980,
+	8, 5040,
+	12, 5060,
+	16, 5080,
+	34, 5170,
+	38, 5190,
+	42, 5210,
+	46, 5230,
+	/**/
+	149, 5745,
+	153, 5765,
+	157, 5785,
+	161, 5805,
+	165, 5825
+	/**/
 };
 
 int usbdrv_freq2chan(u32_t freq)
 {
-    /* 2.4G Hz */
-    if (freq > 2400 && freq < 3000)
-    {
-        return ((freq-2412)/5) + 1;
-    }
-    else
-    {
-        u16_t ii;
-        u16_t num_chan = sizeof(channel_frequency_11A)/sizeof(u32_t);
+	/* 2.4G Hz */
+	if (freq > 2400 && freq < 3000) {
+		return ((freq-2412)/5) + 1;
+	} else {
+		u16_t ii;
+		u16_t num_chan = sizeof(channel_frequency_11A)/sizeof(u32_t);
 
-        for(ii = 1; ii < num_chan; ii += 2)
-        {
-            if (channel_frequency_11A[ii] == freq)
-                return channel_frequency_11A[ii-1];
-        }
-    }
+		for (ii = 1; ii < num_chan; ii += 2) {
+			if (channel_frequency_11A[ii] == freq)
+				return channel_frequency_11A[ii-1];
+		}
+	}
 
-    return 0;
+	return 0;
 }
 
 int usbdrv_chan2freq(int chan)
 {
-    int freq;
+	int freq;
 
-    /* If channel number is out of range */
-    if (chan > 165 || chan <= 0)
-        return -1;
+	/* If channel number is out of range */
+	if (chan > 165 || chan <= 0)
+		return -1;
 
-    /* 2.4G band */
-    if (chan >= 1 && chan <= 13)
-    {
-        freq = (2412 + (chan - 1) * 5);
-        return freq;
-    }
-    else if (chan >= 36 && chan <= 165)
-    {
-        u16_t ii;
-        u16_t num_chan = sizeof(channel_frequency_11A)/sizeof(u32_t);
+	/* 2.4G band */
+	if (chan >= 1 && chan <= 13) {
+		freq = (2412 + (chan - 1) * 5);
+			return freq;
+	} else if (chan >= 36 && chan <= 165) {
+		u16_t ii;
+		u16_t num_chan = sizeof(channel_frequency_11A)/sizeof(u32_t);
 
-        for(ii = 0; ii < num_chan; ii += 2)
-        {
-            if (channel_frequency_11A[ii] == chan)
-                return channel_frequency_11A[ii+1];
-        }
+		for (ii = 0; ii < num_chan; ii += 2) {
+			if (channel_frequency_11A[ii] == chan)
+				return channel_frequency_11A[ii+1];
+		}
 
-        /* Can't find desired frequency */
-        if (ii == num_chan)
-           return -1;
-    }
+	/* Can't find desired frequency */
+	if (ii == num_chan)
+		return -1;
+	}
 
-    /* Can't find deisred frequency */
-    return -1;
+	/* Can't find deisred frequency */
+	return -1;
 }
 
 int usbdrv_ioctl_setessid(struct net_device *dev, struct iw_point *erq)
 {
-#ifdef ZM_HOSTAPD_SUPPORT
-    //struct usbdrv_private *macp = dev->ml_priv;
-    char essidbuf[IW_ESSID_MAX_SIZE+1];
-    int i;
+	#ifdef ZM_HOSTAPD_SUPPORT
+	/* struct usbdrv_private *macp = dev->ml_priv; */
+	char essidbuf[IW_ESSID_MAX_SIZE+1];
+	int i;
 
-    if(!netif_running(dev))
-        return -EINVAL;
+	if (!netif_running(dev))
+		return -EINVAL;
 
-    memset(essidbuf, 0, sizeof(essidbuf));
+	memset(essidbuf, 0, sizeof(essidbuf));
 
-    printk(KERN_ERR "usbdrv_ioctl_setessid\n");
+	printk(KERN_ERR "usbdrv_ioctl_setessid\n");
 
-    //printk("ssidlen=%d\n", erq->length); //for any, it is 1.
-    if (erq->flags) {
-        if (erq->length > (IW_ESSID_MAX_SIZE+1))
-            return -E2BIG;
+	/* printk("ssidlen=%d\n", erq->length); //for any, it is 1. */
+	if (erq->flags) {
+		if (erq->length > (IW_ESSID_MAX_SIZE+1))
+			return -E2BIG;
 
-        if (copy_from_user(essidbuf, erq->pointer, erq->length))
-            return -EFAULT;
-    }
+		if (copy_from_user(essidbuf, erq->pointer, erq->length))
+			return -EFAULT;
+	}
 
-    //zd_DisasocAll(2);
-    //wait_ms(100);
+	/* zd_DisasocAll(2); */
+	/* wait_ms(100); */
 
-    printk(KERN_ERR "essidbuf: ");
+	printk(KERN_ERR "essidbuf: ");
 
-    for(i = 0; i < erq->length; i++)
-    {
-        printk(KERN_ERR "%02x ", essidbuf[i]);
-    }
+	for (i = 0; i < erq->length; i++)
+		printk(KERN_ERR "%02x ", essidbuf[i]);
 
-    printk(KERN_ERR "\n");
+	printk(KERN_ERR "\n");
 
-    essidbuf[erq->length] = '\0';
-    //memcpy(macp->wd.ws.ssid, essidbuf, erq->length);
-    //macp->wd.ws.ssidLen = strlen(essidbuf)+2;
-    //macp->wd.ws.ssid[1] = strlen(essidbuf); // Update ssid length
+	essidbuf[erq->length] = '\0';
+	/* memcpy(macp->wd.ws.ssid, essidbuf, erq->length); */
+	/* macp->wd.ws.ssidLen = strlen(essidbuf)+2; */
+	/* macp->wd.ws.ssid[1] = strlen(essidbuf); Update ssid length */
 
-    zfiWlanSetSSID(dev, essidbuf, erq->length);
-#if 0
-    printk(KERN_ERR "macp->wd.ws.ssid: ");
+	zfiWlanSetSSID(dev, essidbuf, erq->length);
+	#if 0
+		printk(KERN_ERR "macp->wd.ws.ssid: ");
 
-    for(i = 0; i < macp->wd.ws.ssidLen; i++)
-    {
-        printk(KERN_ERR "%02x ", macp->wd.ws.ssid[i]);
-    }
+		for (i = 0; i < macp->wd.ws.ssidLen; i++)
+			printk(KERN_ERR "%02x ", macp->wd.ws.ssid[i]);
 
-    printk(KERN_ERR "\n");
-#endif
-    zfiWlanDisable(dev, 0);
-    zfiWlanEnable(dev);
+		printk(KERN_ERR "\n");
+	#endif
 
-#endif
+	zfiWlanDisable(dev, 0);
+	zfiWlanEnable(dev);
 
-    return 0;
+	#endif
+
+	return 0;
 }
 
 int usbdrv_ioctl_getessid(struct net_device *dev, struct iw_point *erq)
 {
-     //struct usbdrv_private *macp = dev->ml_priv;
-     u8_t essidbuf[IW_ESSID_MAX_SIZE+1];
-     u8_t len;
-     u8_t i;
+	/* struct usbdrv_private *macp = dev->ml_priv; */
+	u8_t essidbuf[IW_ESSID_MAX_SIZE+1];
+	u8_t len;
+	u8_t i;
 
 
-     //len = macp->wd.ws.ssidLen;
-     //memcpy(essidbuf, macp->wd.ws.ssid, macp->wd.ws.ssidLen);
-     zfiWlanQuerySSID(dev, essidbuf, &len);
+	/* len = macp->wd.ws.ssidLen; */
+	/* memcpy(essidbuf, macp->wd.ws.ssid, macp->wd.ws.ssidLen); */
+	zfiWlanQuerySSID(dev, essidbuf, &len);
 
-     essidbuf[len] = 0;
+	essidbuf[len] = 0;
 
-     printk(KERN_ERR "ESSID: ");
+	printk(KERN_ERR "ESSID: ");
 
-     for(i = 0; i < len; i++)
-     {
-         printk(KERN_ERR "%c", essidbuf[i]);
-     }
+	for (i = 0; i < len; i++)
+		printk(KERN_ERR "%c", essidbuf[i]);
 
-     printk(KERN_ERR "\n");
+	printk(KERN_ERR "\n");
 
-     erq->flags= 1;
-     erq->length = strlen(essidbuf) + 1;
+	erq->flags = 1;
+	erq->length = strlen(essidbuf) + 1;
 
-     if (erq->pointer)
-         if (copy_to_user(erq->pointer, essidbuf, erq->length))
-             return -EFAULT;
+	if (erq->pointer) {
+		if (copy_to_user(erq->pointer, essidbuf, erq->length))
+			return -EFAULT;
+	}
 
-     return 0;
+	return 0;
 }
 
-
 int usbdrv_ioctl_setrts(struct net_device *dev, struct iw_param *rrq)
 {
-
-    return 0;
+	return 0;
 }
 
 #if WIRELESS_EXT > 14
@@ -267,462 +253,418 @@
  * Encode a WPA or RSN information element as a custom
  * element using the hostap format.
  */
-u32 encode_ie(void *buf, u32 bufsize, const u8 *ie, u32 ielen, const u8 *leader, u32 leader_len)
+u32 encode_ie(void *buf, u32 bufsize, const u8 *ie, u32 ielen,
+		const u8 *leader, u32 leader_len)
 {
-    u8 *p;
-    u32 i;
+	u8 *p;
+	u32 i;
 
-    if (bufsize < leader_len)
-        return 0;
-    p = buf;
-    memcpy(p, leader, leader_len);
-    bufsize -= leader_len;
-    p += leader_len;
-    for (i = 0; i < ielen && bufsize > 2; i++)
-        p += sprintf(p, "%02x", ie[i]);
-    return (i == ielen ? p - (u8 *)buf : 0);
+	if (bufsize < leader_len)
+		return 0;
+	p = buf;
+	memcpy(p, leader, leader_len);
+	bufsize -= leader_len;
+	p += leader_len;
+	for (i = 0; i < ielen && bufsize > 2; i++)
+		p += sprintf(p, "%02x", ie[i]);
+	return (i == ielen ? p - (u8 *)buf:0);
 }
-#endif                                            /* WIRELESS_EXT > 14 */
+#endif  /* WIRELESS_EXT > 14 */
 
-/*------------------------------------------------------------------*/
 /*
  * Translate scan data returned from the card to a card independent
  * format that the Wireless Tools will understand
  */
 char *usbdrv_translate_scan(struct net_device *dev,
 	struct iw_request_info *info, char *current_ev,
-        char *end_buf, struct zsBssInfo *list)
+	char *end_buf, struct zsBssInfo *list)
 {
-    struct iw_event iwe;                          /* Temporary buffer */
-    u16_t capabilities;
-    char *current_val;                            /* For rates */
-    char *last_ev;
-    int i;
-#if WIRELESS_EXT > 14
-    char    buf[64*2 + 30];
-#endif
+	struct iw_event iwe;   /* Temporary buffer */
+	u16_t capabilities;
+	char *current_val;     /* For rates */
+	char *last_ev;
+	int i;
+	#if WIRELESS_EXT > 14
+		char    buf[64*2 + 30];
+	#endif
 
-    last_ev = current_ev;
+	last_ev = current_ev;
 
-/* First entry *MUST* be the AP MAC address */
-    iwe.cmd = SIOCGIWAP;
-    iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
-    memcpy(iwe.u.ap_addr.sa_data, list->bssid, ETH_ALEN);
-    current_ev = iwe_stream_add_event(
-	info,
-	current_ev,
-	end_buf, &iwe, IW_EV_ADDR_LEN);
+	/* First entry *MUST* be the AP MAC address */
+	iwe.cmd = SIOCGIWAP;
+	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+	memcpy(iwe.u.ap_addr.sa_data, list->bssid, ETH_ALEN);
+	current_ev = iwe_stream_add_event(info,	current_ev,
+					end_buf, &iwe, IW_EV_ADDR_LEN);
 
-    /* Ran out of buffer */
-    if (last_ev == current_ev)
-    {
-        return end_buf;
-    }
+	/* Ran out of buffer */
+	if (last_ev == current_ev)
+		return end_buf;
 
-    last_ev = current_ev;
+	last_ev = current_ev;
 
-/* Other entries will be displayed in the order we give them */
+	/* Other entries will be displayed in the order we give them */
 
-/* Add the ESSID */
-    iwe.u.data.length = list->ssid[1];
-    if(iwe.u.data.length > 32)
-        iwe.u.data.length = 32;
-    iwe.cmd = SIOCGIWESSID;
-    iwe.u.data.flags = 1;
-    current_ev = iwe_stream_add_point(
-	info,
-	current_ev, end_buf, &iwe, &list->ssid[2]);
+	/* Add the ESSID */
+	iwe.u.data.length = list->ssid[1];
+	if (iwe.u.data.length > 32)
+		iwe.u.data.length = 32;
+	iwe.cmd = SIOCGIWESSID;
+	iwe.u.data.flags = 1;
+	current_ev = iwe_stream_add_point(info,	current_ev,
+					end_buf, &iwe, &list->ssid[2]);
 
-    /* Ran out of buffer */
-    if (last_ev == current_ev)
-    {
-        return end_buf;
-    }
+	/* Ran out of buffer */
+	if (last_ev == current_ev)
+		return end_buf;
 
-    last_ev = current_ev;
+	last_ev = current_ev;
 
-/* Add mode */
-    iwe.cmd = SIOCGIWMODE;
-    capabilities = (list->capability[1] << 8) + list->capability[0];
-    if(capabilities & (0x01 | 0x02))
-    {
-        if(capabilities & 0x01)
-            iwe.u.mode = IW_MODE_MASTER;
-        else
-            iwe.u.mode = IW_MODE_ADHOC;
-        current_ev = iwe_stream_add_event(
-		info,
-		current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
-    }
+	/* Add mode */
+	iwe.cmd = SIOCGIWMODE;
+	capabilities = (list->capability[1] << 8) + list->capability[0];
+	if (capabilities & (0x01 | 0x02)) {
+		if (capabilities & 0x01)
+			iwe.u.mode = IW_MODE_MASTER;
+		else
+			iwe.u.mode = IW_MODE_ADHOC;
+			current_ev = iwe_stream_add_event(info,	current_ev,
+						end_buf, &iwe, IW_EV_UINT_LEN);
+	}
 
-    /* Ran out of buffer */
-    if (last_ev == current_ev)
-    {
-        return end_buf;
-    }
+	/* Ran out of buffer */
+	if (last_ev == current_ev)
+		return end_buf;
 
-    last_ev = current_ev;
+	last_ev = current_ev;
 
-/* Add frequency */
-    iwe.cmd = SIOCGIWFREQ;
-    iwe.u.freq.m = list->channel;
-/* Channel frequency in KHz */
-    if (iwe.u.freq.m > 14)
-    {
-        if ((184 <= iwe.u.freq.m) && (iwe.u.freq.m<=196))
-              iwe.u.freq.m = 4000 + iwe.u.freq.m * 5;
-        else
-              iwe.u.freq.m = 5000 + iwe.u.freq.m * 5;
-    }
-    else
-    {
-        if (iwe.u.freq.m == 14)
-              iwe.u.freq.m = 2484;
-        else
-              iwe.u.freq.m = 2412 + (iwe.u.freq.m - 1) * 5;
-    }
-    iwe.u.freq.e = 6;
-    current_ev = iwe_stream_add_event(
-	info,
-    	current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
+	/* Add frequency */
+	iwe.cmd = SIOCGIWFREQ;
+	iwe.u.freq.m = list->channel;
+	/* Channel frequency in KHz */
+	if (iwe.u.freq.m > 14) {
+		if ((184 <= iwe.u.freq.m) && (iwe.u.freq.m <= 196))
+			iwe.u.freq.m = 4000 + iwe.u.freq.m * 5;
+		else
+			iwe.u.freq.m = 5000 + iwe.u.freq.m * 5;
+	} else {
+		if (iwe.u.freq.m == 14)
+			iwe.u.freq.m = 2484;
+		else
+			iwe.u.freq.m = 2412 + (iwe.u.freq.m - 1) * 5;
+	}
+	iwe.u.freq.e = 6;
+	current_ev = iwe_stream_add_event(info, current_ev,
+					end_buf, &iwe, IW_EV_FREQ_LEN);
 
-    /* Ran out of buffer */
-    if (last_ev == current_ev)
-    {
-        return end_buf;
-    }
+	/* Ran out of buffer */
+	if (last_ev == current_ev)
+		return end_buf;
 
-    last_ev = current_ev;
+	last_ev = current_ev;
 
-/* Add quality statistics */
-    iwe.cmd = IWEVQUAL;
-#if WIRELESS_EXT > 18
-    iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED
-                        |IW_QUAL_NOISE_UPDATED;
-#endif
-    iwe.u.qual.level = list->signalStrength;
-    iwe.u.qual.noise = 0;
-    iwe.u.qual.qual = list->signalQuality;
-    current_ev = iwe_stream_add_event(
-	info,
-	current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+	/* Add quality statistics */
+	iwe.cmd = IWEVQUAL;
+	#if WIRELESS_EXT > 18
+	iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED
+				| IW_QUAL_NOISE_UPDATED;
+	#endif
+	iwe.u.qual.level = list->signalStrength;
+	iwe.u.qual.noise = 0;
+	iwe.u.qual.qual = list->signalQuality;
+	current_ev = iwe_stream_add_event(info,	current_ev,
+					end_buf, &iwe, IW_EV_QUAL_LEN);
 
-    /* Ran out of buffer */
-    if (last_ev == current_ev)
-    {
-        return end_buf;
-    }
+	/* Ran out of buffer */
+	if (last_ev == current_ev)
+		return end_buf;
 
-    last_ev = current_ev;
+	last_ev = current_ev;
 
-/* Add encryption capability */
+	/* Add encryption capability */
 
-    iwe.cmd = SIOCGIWENCODE;
-    if(capabilities & 0x10)
-        iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
-    else
-        iwe.u.data.flags = IW_ENCODE_DISABLED;
+	iwe.cmd = SIOCGIWENCODE;
+	if (capabilities & 0x10)
+		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+	else
+		iwe.u.data.flags = IW_ENCODE_DISABLED;
 
-    iwe.u.data.length = 0;
-    current_ev = iwe_stream_add_point(
-	info,
-	current_ev, end_buf, &iwe, list->ssid);
+	iwe.u.data.length = 0;
+	current_ev = iwe_stream_add_point(info,	current_ev,
+					end_buf, &iwe, list->ssid);
 
-    /* Ran out of buffer */
-    if (last_ev == current_ev)
-    {
-        return end_buf;
-    }
+	/* Ran out of buffer */
+	if (last_ev == current_ev)
+		return end_buf;
 
-    last_ev = current_ev;
+	last_ev = current_ev;
 
-/* Rate : stuffing multiple values in a single event require a bit
- * more of magic */
-    current_val = current_ev + IW_EV_LCP_LEN;
+	/* Rate : stuffing multiple values in a single event require a bit
+	* more of magic
+	*/
+	current_val = current_ev + IW_EV_LCP_LEN;
 
-    iwe.cmd = SIOCGIWRATE;
-/* Those two flags are ignored... */
-    iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+	iwe.cmd = SIOCGIWRATE;
+	/* Those two flags are ignored... */
+	iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
 
-    for(i = 0 ; i < list->supportedRates[1] ; i++)
-    {
-/* Bit rate given in 500 kb/s units (+ 0x80) */
-        iwe.u.bitrate.value = ((list->supportedRates[i+2] & 0x7f) * 500000);
-/* Add new value to event */
-        current_val = iwe_stream_add_value(
-		info,
-		current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
+	for (i = 0 ; i < list->supportedRates[1] ; i++) {
+		/* Bit rate given in 500 kb/s units (+ 0x80) */
+		iwe.u.bitrate.value = ((list->supportedRates[i+2] & 0x7f)
+					* 500000);
+		/* Add new value to event */
+		current_val = iwe_stream_add_value(info, current_ev,
+				current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
 
-        /* Ran out of buffer */
-        if (last_ev == current_val)
-        {
-            return end_buf;
-        }
+		/* Ran out of buffer */
+		if (last_ev == current_val)
+			return end_buf;
 
-        last_ev = current_val;
-    }
+		last_ev = current_val;
+	}
 
-    for (i = 0 ; i < list->extSupportedRates[1] ; i++)
-    {
-/* Bit rate given in 500 kb/s units (+ 0x80) */
-        iwe.u.bitrate.value = ((list->extSupportedRates[i+2] & 0x7f) * 500000);
-/* Add new value to event */
-        current_val = iwe_stream_add_value(
-		info,
-		current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
+	for (i = 0 ; i < list->extSupportedRates[1] ; i++) {
+		/* Bit rate given in 500 kb/s units (+ 0x80) */
+		iwe.u.bitrate.value = ((list->extSupportedRates[i+2] & 0x7f)
+					* 500000);
+		/* Add new value to event */
+		current_val = iwe_stream_add_value(info, current_ev,
+				current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
 
-        /* Ran out of buffer */
-        if (last_ev == current_val)
-        {
-            return end_buf;
-        }
+		/* Ran out of buffer */
+		if (last_ev == current_val)
+			return end_buf;
 
-        last_ev = current_ev;
-    }
+		last_ev = current_ev;
+	}
 
-/* Check if we added any event */
-    if((current_val - current_ev) > IW_EV_LCP_LEN)
-        current_ev = current_val;
-#if WIRELESS_EXT > 14
-#define IEEE80211_ELEMID_RSN 0x30
-    memset(&iwe, 0, sizeof(iwe));
-    iwe.cmd = IWEVCUSTOM;
-    snprintf(buf, sizeof(buf), "bcn_int=%d", (list->beaconInterval[1] << 8) + list->beaconInterval[0]);
-    iwe.u.data.length = strlen(buf);
-    current_ev = iwe_stream_add_point(
-		info,
-		current_ev, end_buf, &iwe, buf);
+	/* Check if we added any event */
+	if ((current_val - current_ev) > IW_EV_LCP_LEN)
+		current_ev = current_val;
+	#if WIRELESS_EXT > 14
+		#define IEEE80211_ELEMID_RSN 0x30
+	memset(&iwe, 0, sizeof(iwe));
+	iwe.cmd = IWEVCUSTOM;
+	snprintf(buf, sizeof(buf), "bcn_int=%d", (list->beaconInterval[1] << 8)
+						+ list->beaconInterval[0]);
+	iwe.u.data.length = strlen(buf);
+	current_ev = iwe_stream_add_point(info, current_ev,
+						end_buf, &iwe, buf);
 
-    /* Ran out of buffer */
-    if (last_ev == current_ev)
-    {
-        return end_buf;
-    }
+	/* Ran out of buffer */
+	if (last_ev == current_ev)
+		return end_buf;
 
-    last_ev = current_ev;
+	last_ev = current_ev;
 
-    if (list->wpaIe[1] != 0)
-    {
-        static const char rsn_leader[] = "rsn_ie=";
-        static const char wpa_leader[] = "wpa_ie=";
+	if (list->wpaIe[1] != 0) {
+		static const char rsn_leader[] = "rsn_ie=";
+		static const char wpa_leader[] = "wpa_ie=";
 
-        memset(&iwe, 0, sizeof(iwe));
-        iwe.cmd = IWEVCUSTOM;
-        if (list->wpaIe[0] == IEEE80211_ELEMID_RSN)
-            iwe.u.data.length = encode_ie(buf, sizeof(buf),
-                list->wpaIe, list->wpaIe[1]+2,
-                rsn_leader, sizeof(rsn_leader)-1);
-        else
-            iwe.u.data.length = encode_ie(buf, sizeof(buf),
-                list->wpaIe, list->wpaIe[1]+2,
-                wpa_leader, sizeof(wpa_leader)-1);
+		memset(&iwe, 0, sizeof(iwe));
+		iwe.cmd = IWEVCUSTOM;
+		if (list->wpaIe[0] == IEEE80211_ELEMID_RSN)
+			iwe.u.data.length = encode_ie(buf, sizeof(buf),
+					list->wpaIe, list->wpaIe[1]+2,
+					rsn_leader, sizeof(rsn_leader)-1);
+		else
+			iwe.u.data.length = encode_ie(buf, sizeof(buf),
+					list->wpaIe, list->wpaIe[1]+2,
+					wpa_leader, sizeof(wpa_leader)-1);
 
-        if (iwe.u.data.length != 0)
-            current_ev = iwe_stream_add_point(
-		info,
-		current_ev, end_buf, &iwe, buf);
+		if (iwe.u.data.length != 0)
+			current_ev = iwe_stream_add_point(info, current_ev,
+							end_buf, &iwe, buf);
 
-        /* Ran out of buffer */
-        if (last_ev == current_ev)
-        {
-            return end_buf;
-        }
+		/* Ran out of buffer */
+		if (last_ev == current_ev)
+			return end_buf;
 
-        last_ev = current_ev;
-    }
-    if (list->rsnIe[1] != 0)
-    {
-        static const char rsn_leader[] = "rsn_ie=";
-        memset(&iwe, 0, sizeof(iwe));
-        iwe.cmd = IWEVCUSTOM;
+		last_ev = current_ev;
+	}
 
-        if (list->rsnIe[0] == IEEE80211_ELEMID_RSN)
-        {
-            iwe.u.data.length = encode_ie(buf, sizeof(buf),
-                list->rsnIe, list->rsnIe[1]+2,
-                rsn_leader, sizeof(rsn_leader)-1);
-            if (iwe.u.data.length != 0)
-                current_ev = iwe_stream_add_point(
-			info,
-			current_ev, end_buf,  &iwe, buf);
+	if (list->rsnIe[1] != 0) {
+		static const char rsn_leader[] = "rsn_ie=";
+		memset(&iwe, 0, sizeof(iwe));
+		iwe.cmd = IWEVCUSTOM;
 
-            /* Ran out of buffer */
-            if (last_ev == current_ev)
-            {
-                return end_buf;
-            }
+		if (list->rsnIe[0] == IEEE80211_ELEMID_RSN) {
+			iwe.u.data.length = encode_ie(buf, sizeof(buf),
+			list->rsnIe, list->rsnIe[1]+2,
+			rsn_leader, sizeof(rsn_leader)-1);
+			if (iwe.u.data.length != 0)
+				current_ev = iwe_stream_add_point(info,
+					current_ev, end_buf,  &iwe, buf);
 
-            last_ev = current_ev;
-        }
-    }
-#endif
-/* The other data in the scan result are not really
- * interesting, so for now drop it */
-    return current_ev;
+			/* Ran out of buffer */
+			if (last_ev == current_ev)
+				return end_buf;
+
+			last_ev = current_ev;
+		}
+	}
+	#endif
+	/* The other data in the scan result are not really
+	* interesting, so for now drop it
+	*/
+	return current_ev;
 }
 
 int usbdrvwext_giwname(struct net_device *dev,
-            struct iw_request_info *info,
-            union iwreq_data *wrq, char *extra)
+		struct iw_request_info *info,
+		union iwreq_data *wrq, char *extra)
 {
-    //struct usbdrv_private *macp = dev->ml_priv;
+	/* struct usbdrv_private *macp = dev->ml_priv; */
 
-    strcpy(wrq->name, "IEEE 802.11-MIMO");
+	strcpy(wrq->name, "IEEE 802.11-MIMO");
 
-    return 0;
+	return 0;
 }
 
 int usbdrvwext_siwfreq(struct net_device *dev,
-            struct iw_request_info *info,
-            struct iw_freq *freq, char *extra)
+		struct iw_request_info *info,
+		struct iw_freq *freq, char *extra)
 {
-    u32_t FreqKHz;
-    struct usbdrv_private *macp = dev->ml_priv;
+	u32_t FreqKHz;
+	struct usbdrv_private *macp = dev->ml_priv;
 
-    if(!netif_running(dev))
-        return -EINVAL;
+	if (!netif_running(dev))
+		return -EINVAL;
 
-    if (freq->e > 1)
-        return -EINVAL;
+	if (freq->e > 1)
+		return -EINVAL;
 
-    if (freq->e == 1)
-    {
-        FreqKHz = (freq->m / 100000);
+	if (freq->e == 1) {
+		FreqKHz = (freq->m / 100000);
 
-        if (FreqKHz > 4000000)
-        {
-            if (FreqKHz > 5825000)
-                FreqKHz = 5825000;
-            else if (FreqKHz < 4920000)
-                FreqKHz = 4920000;
-            else if (FreqKHz < 5000000)
-                FreqKHz = (((FreqKHz - 4000000) / 5000) * 5000) + 4000000;
-            else
-                FreqKHz = (((FreqKHz - 5000000) / 5000) * 5000) + 5000000;
-        }
-        else
-        {
-            if (FreqKHz > 2484000)
-                FreqKHz = 2484000;
-            else if (FreqKHz < 2412000)
-                FreqKHz = 2412000;
-            else
-                FreqKHz = (((FreqKHz - 2412000) / 5000) * 5000) + 2412000;
-        }
+		if (FreqKHz > 4000000) {
+			if (FreqKHz > 5825000)
+				FreqKHz = 5825000;
+			else if (FreqKHz < 4920000)
+				FreqKHz = 4920000;
+			else if (FreqKHz < 5000000)
+				FreqKHz = (((FreqKHz - 4000000) / 5000) * 5000)
+						+ 4000000;
+			else
+				FreqKHz = (((FreqKHz - 5000000) / 5000) * 5000)
+						+ 5000000;
+		} else {
+			if (FreqKHz > 2484000)
+				FreqKHz = 2484000;
+			else if (FreqKHz < 2412000)
+				FreqKHz = 2412000;
+			else
+				FreqKHz = (((FreqKHz - 2412000) / 5000) * 5000)
+						+ 2412000;
+		}
+	} else {
+		FreqKHz = usbdrv_chan2freq(freq->m);
 
-    }
-    else
-    {
-        FreqKHz = usbdrv_chan2freq(freq->m);
+		if (FreqKHz != -1)
+			FreqKHz *= 1000;
+		else
+			FreqKHz = 2412000;
+	}
 
-        if (FreqKHz != -1)
-            FreqKHz *= 1000;
-        else
-            FreqKHz = 2412000;
-    }
+	/* printk("freq->m: %d, freq->e: %d\n", freq->m, freq->e); */
+	/* printk("FreqKHz: %d\n", FreqKHz); */
 
-    //printk("freq->m: %d, freq->e: %d\n", freq->m, freq->e);
-    //printk("FreqKHz: %d\n", FreqKHz);
+	if (macp->DeviceOpened == 1) {
+		zfiWlanSetFrequency(dev, FreqKHz, 0); /* Immediate */
+		/* u8_t wpaieLen,wpaie[50]; */
+		/* zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen); */
+		zfiWlanDisable(dev, 0);
+		zfiWlanEnable(dev);
+		/* if (wpaieLen > 2) */
+		/* zfiWlanSetWpaIe(dev, wpaie, wpaieLen); */
+	}
 
-    if (macp->DeviceOpened == 1)
-    {
-        zfiWlanSetFrequency(dev, FreqKHz, 0); // Immediate
-        //u8_t wpaieLen,wpaie[50];
-        //zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen);
-        zfiWlanDisable(dev, 0);
-        zfiWlanEnable(dev);
-        //if (wpaieLen > 2)
-        //    zfiWlanSetWpaIe(dev, wpaie, wpaieLen);
-    }
-
-    return 0;
+	return 0;
 }
 
 int usbdrvwext_giwfreq(struct net_device *dev,
-            struct iw_request_info *info,
-            struct iw_freq *freq, char *extra)
+		struct iw_request_info *info,
+		struct iw_freq *freq, char *extra)
 {
-    struct usbdrv_private *macp = dev->ml_priv;
+	struct usbdrv_private *macp = dev->ml_priv;
 
-    if (macp->DeviceOpened != 1)
-        return 0;
+	if (macp->DeviceOpened != 1)
+		return 0;
 
-    freq->m = zfiWlanQueryFrequency(dev);
-    freq->e = 3;
+	freq->m = zfiWlanQueryFrequency(dev);
+	freq->e = 3;
 
-    return 0;
+	return 0;
 }
 
 int usbdrvwext_siwmode(struct net_device *dev,
-            struct iw_request_info *info,
-            union iwreq_data *wrq, char *extra)
+		struct iw_request_info *info,
+		union iwreq_data *wrq, char *extra)
 {
-    struct usbdrv_private *macp = dev->ml_priv;
-    u8_t WlanMode;
+	struct usbdrv_private *macp = dev->ml_priv;
+	u8_t WlanMode;
 
-    if(!netif_running(dev))
-        return -EINVAL;
+	if (!netif_running(dev))
+		return -EINVAL;
 
-    if (macp->DeviceOpened != 1)
-        return 0;
+	if (macp->DeviceOpened != 1)
+		return 0;
 
-    switch(wrq->mode)
-    {
-        case IW_MODE_MASTER:
-            WlanMode = ZM_MODE_AP;
-            break;
-        case IW_MODE_INFRA:
-            WlanMode = ZM_MODE_INFRASTRUCTURE;
-            break;
-        case IW_MODE_ADHOC:
-            WlanMode = ZM_MODE_IBSS;
-            break;
-        default:
-            WlanMode = ZM_MODE_IBSS;
-            break;
-    }
+	switch (wrq->mode) {
+	case IW_MODE_MASTER:
+		WlanMode = ZM_MODE_AP;
+		break;
+	case IW_MODE_INFRA:
+		WlanMode = ZM_MODE_INFRASTRUCTURE;
+		break;
+	case IW_MODE_ADHOC:
+		WlanMode = ZM_MODE_IBSS;
+		break;
+	default:
+		WlanMode = ZM_MODE_IBSS;
+		break;
+	}
 
-    zfiWlanSetWlanMode(dev,WlanMode);
-    zfiWlanDisable(dev, 1);
-    zfiWlanEnable(dev);
+	zfiWlanSetWlanMode(dev, WlanMode);
+	zfiWlanDisable(dev, 1);
+	zfiWlanEnable(dev);
 
-    return 0;
+	return 0;
 }
 
 int usbdrvwext_giwmode(struct net_device *dev,
-            struct iw_request_info *info,
-            __u32 *mode, char *extra)
+	struct iw_request_info *info,
+	__u32 *mode, char *extra)
 {
-    unsigned long irqFlag;
-    struct usbdrv_private *macp = dev->ml_priv;
+	unsigned long irqFlag;
+	struct usbdrv_private *macp = dev->ml_priv;
 
-    if(!netif_running(dev))
-        return -EINVAL;
+	if (!netif_running(dev))
+		return -EINVAL;
 
-    if (macp->DeviceOpened != 1)
-        return 0;
+	if (macp->DeviceOpened != 1)
+		return 0;
 
-    spin_lock_irqsave(&macp->cs_lock, irqFlag);
+	spin_lock_irqsave(&macp->cs_lock, irqFlag);
 
-    switch(zfiWlanQueryWlanMode(dev))
-    {
-        case ZM_MODE_AP:
-            *mode = IW_MODE_MASTER;
-            break;
-        case ZM_MODE_INFRASTRUCTURE:
-            *mode = IW_MODE_INFRA;
-            break;
-        case ZM_MODE_IBSS:
-            *mode = IW_MODE_ADHOC;
-            break;
-        default:
-            *mode = IW_MODE_ADHOC;
-            break;
-    }
+	switch (zfiWlanQueryWlanMode(dev)) {
+	case ZM_MODE_AP:
+		*mode = IW_MODE_MASTER;
+		break;
+	case ZM_MODE_INFRASTRUCTURE:
+		*mode = IW_MODE_INFRA;
+		break;
+	case ZM_MODE_IBSS:
+		*mode = IW_MODE_ADHOC;
+		break;
+	default:
+		*mode = IW_MODE_ADHOC;
+		break;
+	}
 
-    spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
+	spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
 
-    return 0;
+	return 0;
 }
 
 int usbdrvwext_siwsens(struct net_device *dev,
@@ -743,338 +685,341 @@
 }
 
 int usbdrvwext_giwrange(struct net_device *dev,
-            struct iw_request_info *info,
-            struct iw_point *data, char *extra)
+		struct iw_request_info *info,
+		struct iw_point *data, char *extra)
 {
-    struct iw_range *range = (struct iw_range *) extra;
-    int i, val;
-    //int num_band_a;
-    u16_t channels[60];
-    u16_t channel_num;
+	struct iw_range *range = (struct iw_range *) extra;
+	int i, val;
+	/* int num_band_a; */
+	u16_t channels[60];
+	u16_t channel_num;
 
-    if(!netif_running(dev))
-        return -EINVAL;
+	if (!netif_running(dev))
+		return -EINVAL;
 
-#if WIRELESS_EXT > 9
-    range->txpower_capa = IW_TXPOW_DBM;
-// XXX what about min/max_pmp, min/max_pmt, etc.
-#endif
+	#if WIRELESS_EXT > 9
+	range->txpower_capa = IW_TXPOW_DBM;
+	/* XXX what about min/max_pmp, min/max_pmt, etc. */
+	#endif
 
-#if WIRELESS_EXT > 10
-    range->we_version_compiled = WIRELESS_EXT;
-    range->we_version_source = 13;
+	#if WIRELESS_EXT > 10
+	range->we_version_compiled = WIRELESS_EXT;
+	range->we_version_source = 13;
 
-    range->retry_capa = IW_RETRY_LIMIT;
-    range->retry_flags = IW_RETRY_LIMIT;
-    range->min_retry = 0;
-    range->max_retry = 255;
-#endif                                        /* WIRELESS_EXT > 10 */
+	range->retry_capa = IW_RETRY_LIMIT;
+	range->retry_flags = IW_RETRY_LIMIT;
+	range->min_retry = 0;
+	range->max_retry = 255;
+	#endif  /* WIRELESS_EXT > 10 */
 
-    channel_num = zfiWlanQueryAllowChannels(dev, channels);
+	channel_num = zfiWlanQueryAllowChannels(dev, channels);
 
-    /* Gurantee reported channel numbers is less or equal to IW_MAX_FREQUENCIES */
-    if (channel_num > IW_MAX_FREQUENCIES)
-        channel_num = IW_MAX_FREQUENCIES;
+	/* Gurantee reported channel numbers is less
+	* or equal to IW_MAX_FREQUENCIES
+	*/
+	if (channel_num > IW_MAX_FREQUENCIES)
+		channel_num = IW_MAX_FREQUENCIES;
 
-    val = 0;
+	val = 0;
 
-    for (i = 0; i < channel_num; i++)
-    {
-        range->freq[val].i = usbdrv_freq2chan(channels[i]);
-        range->freq[val].m = channels[i];
-        range->freq[val].e = 6;
-        val++;
-    }
+	for (i = 0; i < channel_num; i++) {
+		range->freq[val].i = usbdrv_freq2chan(channels[i]);
+		range->freq[val].m = channels[i];
+		range->freq[val].e = 6;
+		val++;
+	}
 
-    range->num_channels = channel_num;
-    range->num_frequency = channel_num;
+	range->num_channels = channel_num;
+	range->num_frequency = channel_num;
 
-#if 0
-    range->num_channels = 14; // Only 2.4G
+	#if 0
+	range->num_channels = 14; /* Only 2.4G */
 
-/* XXX need to filter against the regulatory domain &| active set */
-    val = 0;
-    for (i = 1; i <= 14; i++) // B,G Bands
-    {
-        range->freq[val].i = i;
-        if (i == 14)
-              range->freq[val].m = 2484000;
-        else
-              range->freq[val].m = (2412+(i-1)*5)*1000;
-        range->freq[val].e = 3;
-        val++;
-    }
+	/* XXX need to filter against the regulatory domain &| active set */
+	val = 0;
+	/* B,G Bands */
+	for (i = 1; i <= 14; i++) {
+		range->freq[val].i = i;
+		if (i == 14)
+			range->freq[val].m = 2484000;
+		else
+			range->freq[val].m = (2412+(i-1)*5)*1000;
+		range->freq[val].e = 3;
+		val++;
+	}
 
-    num_band_a = (IW_MAX_FREQUENCIES - val);
+	num_band_a = (IW_MAX_FREQUENCIES - val);
+	/* A Bands */
+	for (i = 0; i < num_band_a; i++) {
+		range->freq[val].i = channel_frequency_11A[2 * i];
+		range->freq[val].m = channel_frequency_11A[2 * i + 1] * 1000;
+		range->freq[val].e = 3;
+		val++;
+	}
+	/* MIMO Rate Not Defined Now
+	* For 802.11a, there are too more frequency.
+	* We can't return them all.
+	*/
+	range->num_frequency = val;
+	#endif
 
-    for (i = 0; i < num_band_a; i++) // A Bands
-    {
-        range->freq[val].i = channel_frequency_11A[2 * i];
-        range->freq[val].m = channel_frequency_11A[2 * i + 1] * 1000;
-        range->freq[val].e = 3;
-        val++;
-    }
-    // MIMO Rate Not Defined Now
-    //For 802.11a, there are too more frequency. We can't return them all
-    range->num_frequency = val;
-#endif
+	/* Max of /proc/net/wireless */
+	range->max_qual.qual = 100;  /* ??  92; */
+	range->max_qual.level = 154; /* ?? */
+	range->max_qual.noise = 154; /* ?? */
+	range->sensitivity = 3;      /* ?? */
 
-/* Max of /proc/net/wireless */
-    range->max_qual.qual = 100; //??                  //92;
-    range->max_qual.level = 154; //??
-    range->max_qual.noise = 154; //??
-    range->sensitivity = 3; //??
+	/* XXX these need to be nsd-specific! */
+	range->min_rts = 0;
+	range->max_rts = 2347;
+	range->min_frag = 256;
+	range->max_frag = 2346;
+	range->max_encoding_tokens = 4 /* NUM_WEPKEYS ?? */;
+	range->num_encoding_sizes = 2; /* ?? */
 
-// XXX these need to be nsd-specific!
-    range->min_rts = 0;
-    range->max_rts = 2347;
-    range->min_frag = 256;
-    range->max_frag = 2346;
-    range->max_encoding_tokens = 4/*NUM_WEPKEYS*/; //??
-    range->num_encoding_sizes = 2; //??
+	range->encoding_size[0] = 5; /* ?? WEP Key Encoding Size */
+	range->encoding_size[1] = 13; /* ?? */
 
-    range->encoding_size[0] = 5; //??               //WEP Key Encoding Size
-    range->encoding_size[1] = 13;//??
+	/* XXX what about num_bitrates/throughput? */
+	range->num_bitrates = 0; /* ?? */
 
-// XXX what about num_bitrates/throughput?
-    range->num_bitrates = 0; //??
+	/* estimated max throughput
+	* XXX need to cap it if we're running at ~2Mbps..
+	*/
 
-/* estimated max throughput */
-// XXX need to cap it if we're running at ~2Mbps..
+	range->throughput = 300000000;
 
-    range->throughput = 300000000;
-
-    return 0;
+	return 0;
 }
 
 int usbdrvwext_siwap(struct net_device *dev, struct iw_request_info *info,
-        struct sockaddr *MacAddr, char *extra)
+		struct sockaddr *MacAddr, char *extra)
 {
-    struct usbdrv_private *macp = dev->ml_priv;
+	struct usbdrv_private *macp = dev->ml_priv;
 
-    if(!netif_running(dev))
-        return -EINVAL;
+	if (!netif_running(dev))
+		return -EINVAL;
 
-    if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) // AP Mode
-        zfiWlanSetMacAddress(dev,(u16_t *)&MacAddr->sa_data[0]);
-    else                                 //STA Mode
-        zfiWlanSetBssid(dev,&MacAddr->sa_data[0]);
+	if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) {
+		/* AP Mode */
+		zfiWlanSetMacAddress(dev, (u16_t *)&MacAddr->sa_data[0]);
+	} else {
+		/* STA Mode */
+		zfiWlanSetBssid(dev, &MacAddr->sa_data[0]);
+	}
 
-    if (macp->DeviceOpened == 1)
-    {
-        //u8_t wpaieLen,wpaie[80];
-        //zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen);
-        zfiWlanDisable(dev, 0);
-        zfiWlanEnable(dev);
-        //if (wpaieLen > 2)
-        //    zfiWlanSetWpaIe(dev, wpaie, wpaieLen);
-    }
+	if (macp->DeviceOpened == 1) {
+		/* u8_t wpaieLen,wpaie[80]; */
+		/* zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen); */
+		zfiWlanDisable(dev, 0);
+		zfiWlanEnable(dev);
+		/* if (wpaieLen > 2) */
+		/* zfiWlanSetWpaIe(dev, wpaie, wpaieLen); */
+	}
 
-    return 0;
+	return 0;
 }
 
 int usbdrvwext_giwap(struct net_device *dev,
-            struct iw_request_info *info,
-            struct sockaddr *MacAddr, char *extra)
+		struct iw_request_info *info,
+		struct sockaddr *MacAddr, char *extra)
 {
-    struct usbdrv_private *macp = dev->ml_priv;
+	struct usbdrv_private *macp = dev->ml_priv;
 
-    if (macp->DeviceOpened != 1)
-        return 0;
+	if (macp->DeviceOpened != 1)
+		return 0;
 
-    if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) // AP Mode
-        zfiWlanQueryMacAddress(dev, &MacAddr->sa_data[0]);
-    else                                 //STA Mode
-    {
-        if (macp->adapterState == ZM_STATUS_MEDIA_CONNECT)
-        {
-            zfiWlanQueryBssid(dev, &MacAddr->sa_data[0]);
-        }
-        else
-        {
-            u8_t zero_addr[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-            memcpy(&MacAddr->sa_data[0], zero_addr, sizeof(zero_addr));
-        }
-    }
+	if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) {
+		/* AP Mode */
+		zfiWlanQueryMacAddress(dev, &MacAddr->sa_data[0]);
+	} else {
+		/* STA Mode */
+		if (macp->adapterState == ZM_STATUS_MEDIA_CONNECT) {
+			zfiWlanQueryBssid(dev, &MacAddr->sa_data[0]);
+		} else {
+			u8_t zero_addr[6] = { 0x00, 0x00, 0x00, 0x00,
+								0x00, 0x00 };
+			memcpy(&MacAddr->sa_data[0], zero_addr,
+							sizeof(zero_addr));
+		}
+	}
 
-    return 0;
+	return 0;
 }
 
 int usbdrvwext_iwaplist(struct net_device *dev,
 			struct iw_request_info *info,
 			struct iw_point *data, char *extra)
 {
-    //Don't know how to do yet--CWYang(+)
-    return 0;
+	/* Don't know how to do yet--CWYang(+) */
+	return 0;
 
 }
 
 int usbdrvwext_siwscan(struct net_device *dev, struct iw_request_info *info,
-        struct iw_point *data, char *extra)
+	struct iw_point *data, char *extra)
 {
-    struct usbdrv_private *macp = dev->ml_priv;
+	struct usbdrv_private *macp = dev->ml_priv;
 
-    if (macp->DeviceOpened != 1)
-        return 0;
+	if (macp->DeviceOpened != 1)
+		return 0;
 
-    printk("CWY - usbdrvwext_siwscan\n");
+	printk(KERN_WARNING "CWY - usbdrvwext_siwscan\n");
 
-    zfiWlanScan(dev);
+	zfiWlanScan(dev);
 
-    return 0;
+	return 0;
 }
 
 int usbdrvwext_giwscan(struct net_device *dev,
-            struct iw_request_info *info,
-            struct iw_point *data, char *extra)
+		struct iw_request_info *info,
+		struct iw_point *data, char *extra)
 {
-    struct usbdrv_private *macp = dev->ml_priv;
-    //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev);
-    char *current_ev = extra;
-    char *end_buf;
-    int i;
-    //struct zsBssList BssList;
-    struct zsBssListV1 *pBssList = kmalloc(sizeof(struct zsBssListV1), GFP_KERNEL);
-    //BssList = wd->sta.pBssList;
-    //zmw_get_wlan_dev(dev);
+	struct usbdrv_private *macp = dev->ml_priv;
+	/* struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev); */
+	char *current_ev = extra;
+	char *end_buf;
+	int i;
+	/* struct zsBssList BssList; */
+	struct zsBssListV1 *pBssList = kmalloc(sizeof(struct zsBssListV1),
+								GFP_KERNEL);
+	/* BssList = wd->sta.pBssList; */
+	/* zmw_get_wlan_dev(dev); */
 
-    if (macp->DeviceOpened != 1)
-        return 0;
+	if (macp->DeviceOpened != 1)
+		return 0;
 
-    if (data->length == 0)
-    {
-       end_buf = extra + IW_SCAN_MAX_DATA;
-    }
-    else
-    {
-        end_buf = extra + data->length;
-    }
+	if (data->length == 0)
+		end_buf = extra + IW_SCAN_MAX_DATA;
+	else
+		end_buf = extra + data->length;
 
-    printk("giwscan - Report Scan Results\n");
-    //printk("giwscan - BssList Sreucture Len : %d\n", sizeof(BssList));
-    //printk("giwscan - BssList Count : %d\n", wd->sta.pBssList->bssCount);
-    //printk("giwscan - UpdateBssList Count : %d\n", wd->sta.pUpdateBssList->bssCount);
-    zfiWlanQueryBssListV1(dev, pBssList);
-    //zfiWlanQueryBssList(dev, &BssList);
+	printk(KERN_WARNING "giwscan - Report Scan Results\n");
+	/* printk("giwscan - BssList Sreucture Len : %d\n", sizeof(BssList));
+	* printk("giwscan - BssList Count : %d\n",
+	* wd->sta.pBssList->bssCount);
+	* printk("giwscan - UpdateBssList Count : %d\n",
+	* wd->sta.pUpdateBssList->bssCount);
+	*/
+	zfiWlanQueryBssListV1(dev, pBssList);
+	/* zfiWlanQueryBssList(dev, &BssList); */
 
-/* Read and parse all entries */
-    printk("giwscan - pBssList->bssCount : %d\n", pBssList->bssCount);
-    //printk("giwscan - BssList.bssCount : %d\n", BssList.bssCount);
+	/* Read and parse all entries */
+	printk(KERN_WARNING "giwscan - pBssList->bssCount : %d\n",
+						pBssList->bssCount);
+	/* printk("giwscan - BssList.bssCount : %d\n", BssList.bssCount); */
 
-    for (i = 0; i < pBssList->bssCount; i++)
-    {
-/* Translate to WE format this entry */
-        //current_ev = usbdrv_translate_scan(dev, info, current_ev,
-        //    extra + IW_SCAN_MAX_DATA, &pBssList->bssInfo[i]);
-        current_ev = usbdrv_translate_scan(dev, info, current_ev,
-            end_buf, &pBssList->bssInfo[i]);
+	for (i = 0; i < pBssList->bssCount; i++) {
+		/* Translate to WE format this entry
+		* current_ev = usbdrv_translate_scan(dev, info, current_ev,
+		* extra + IW_SCAN_MAX_DATA, &pBssList->bssInfo[i]);
+		*/
+		current_ev = usbdrv_translate_scan(dev, info, current_ev,
+					end_buf, &pBssList->bssInfo[i]);
 
-#if WIRELESS_EXT > 16
-        if (current_ev == end_buf)
-        {
-            kfree(pBssList);
-            data->length = current_ev - extra;
-            return -E2BIG;
-        }
-#endif
-    }
+		#if WIRELESS_EXT > 16
+		if (current_ev == end_buf) {
+			kfree(pBssList);
+			data->length = current_ev - extra;
+			return -E2BIG;
+		}
+		#endif
+	}
 
-/* Length of data */
-    data->length = (current_ev - extra);
-    data->flags = 0;                              /* todo */
+	/* Length of data */
+	data->length = (current_ev - extra);
+	data->flags = 0;   /* todo */
 
-    kfree(pBssList);
+	kfree(pBssList);
 
-    return 0;
+	return 0;
 }
 
 int usbdrvwext_siwessid(struct net_device *dev,
-            struct iw_request_info *info,
-            struct iw_point *essid, char *extra)
+		struct iw_request_info *info,
+		struct iw_point *essid, char *extra)
 {
-    char EssidBuf[IW_ESSID_MAX_SIZE+1];
-    struct usbdrv_private *macp = dev->ml_priv;
+	char EssidBuf[IW_ESSID_MAX_SIZE + 1];
+	struct usbdrv_private *macp = dev->ml_priv;
 
-    if(!netif_running(dev))
-        return -EINVAL;
+	if (!netif_running(dev))
+		return -EINVAL;
 
-    if (essid->flags == 1)
-    {
-        if (essid->length > (IW_ESSID_MAX_SIZE+1))
-            return -E2BIG;
+	if (essid->flags == 1) {
+		if (essid->length > (IW_ESSID_MAX_SIZE + 1))
+			return -E2BIG;
 
-        if (copy_from_user(&EssidBuf, essid->pointer, essid->length))
-            return -EFAULT;
+		if (copy_from_user(&EssidBuf, essid->pointer, essid->length))
+			return -EFAULT;
 
-        EssidBuf[essid->length] = '\0';
-        //printk("siwessid - Set Essid : %s\n",EssidBuf);
-        //printk("siwessid - Essid Len : %d\n",essid->length);
-        //printk("siwessid - Essid Flag : %x\n",essid->flags);
-        if (macp->DeviceOpened == 1)
-        {
-            zfiWlanSetSSID(dev, EssidBuf, strlen(EssidBuf));
-            zfiWlanSetFrequency(dev, zfiWlanQueryFrequency(dev), FALSE);
-            zfiWlanSetEncryMode(dev, zfiWlanQueryEncryMode(dev));
-            //u8_t wpaieLen,wpaie[50];
-            //zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen);
-            zfiWlanDisable(dev, 0);
-            zfiWlanEnable(dev);
-            //if (wpaieLen > 2)
-            //    zfiWlanSetWpaIe(dev, wpaie, wpaieLen);
-        }
-    }
+		EssidBuf[essid->length] = '\0';
+		/* printk("siwessid - Set Essid : %s\n",EssidBuf); */
+		/* printk("siwessid - Essid Len : %d\n",essid->length); */
+		/* printk("siwessid - Essid Flag : %x\n",essid->flags); */
+		if (macp->DeviceOpened == 1) {
+			zfiWlanSetSSID(dev, EssidBuf, strlen(EssidBuf));
+			zfiWlanSetFrequency(dev, zfiWlanQueryFrequency(dev),
+						FALSE);
+			zfiWlanSetEncryMode(dev, zfiWlanQueryEncryMode(dev));
+			/* u8_t wpaieLen,wpaie[50]; */
+			/* zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen); */
+			zfiWlanDisable(dev, 0);
+			zfiWlanEnable(dev);
+			/* if (wpaieLen > 2) */
+			/* zfiWlanSetWpaIe(dev, wpaie, wpaieLen); */
+		}
+	}
 
-    return 0;
+	return 0;
 }
 
 int usbdrvwext_giwessid(struct net_device *dev,
-            struct iw_request_info *info,
-            struct iw_point *essid, char *extra)
+		struct iw_request_info *info,
+		struct iw_point *essid, char *extra)
 {
-    struct usbdrv_private *macp = dev->ml_priv;
-    u8_t EssidLen;
-    char EssidBuf[IW_ESSID_MAX_SIZE+1];
-    int ssid_len;
+	struct usbdrv_private *macp = dev->ml_priv;
+	u8_t EssidLen;
+	char EssidBuf[IW_ESSID_MAX_SIZE + 1];
+	int ssid_len;
 
-    if(!netif_running(dev))
-        return -EINVAL;
+	if (!netif_running(dev))
+		return -EINVAL;
 
-    if (macp->DeviceOpened != 1)
-        return 0;
+	if (macp->DeviceOpened != 1)
+		return 0;
 
-    zfiWlanQuerySSID(dev, &EssidBuf[0], &EssidLen);
+	zfiWlanQuerySSID(dev, &EssidBuf[0], &EssidLen);
 
-    /* Convert type from unsigned char to char */
-    ssid_len = (int)EssidLen;
+	/* Convert type from unsigned char to char */
+	ssid_len = (int)EssidLen;
 
-    /* Make sure the essid length is not greater than IW_ESSID_MAX_SIZE */
-    if (ssid_len > IW_ESSID_MAX_SIZE)
-        ssid_len = IW_ESSID_MAX_SIZE;
+	/* Make sure the essid length is not greater than IW_ESSID_MAX_SIZE */
+	if (ssid_len > IW_ESSID_MAX_SIZE)
+		ssid_len = IW_ESSID_MAX_SIZE;
 
-    EssidBuf[ssid_len] = '\0';
+	EssidBuf[ssid_len] = '\0';
 
-    essid->flags = 1;
-    essid->length = strlen(EssidBuf);
+	essid->flags = 1;
+	essid->length = strlen(EssidBuf);
 
-    memcpy(extra, EssidBuf, essid->length);
-    // wireless.c in Kernel would handle copy_to_user -- line 679
-    /*if (essid->pointer)
-    {
-        if ( copy_to_user(essid->pointer, EssidBuf, essid->length) )
-        {
-            printk("giwessid - copy_to_user Fail\n");
-            return -EFAULT;
-        }
-    }*/
+	memcpy(extra, EssidBuf, essid->length);
+	/* wireless.c in Kernel would handle copy_to_user -- line 679 */
+	/* if (essid->pointer) {
+	* if (copy_to_user(essid->pointer, EssidBuf, essid->length)) {
+	* printk("giwessid - copy_to_user Fail\n");
+	* return -EFAULT;
+	* }
+	* }
+	*/
 
-    return 0;
+	return 0;
 }
 
 int usbdrvwext_siwnickn(struct net_device *dev,
 			struct iw_request_info *info,
 			struct iw_point *data, char *nickname)
 {
-    //Exist but junk--CWYang(+)
+	/* Exist but junk--CWYang(+) */
 	return 0;
 }
 
@@ -1082,182 +1027,180 @@
 			struct iw_request_info *info,
 			struct iw_point *data, char *nickname)
 {
-    struct usbdrv_private *macp = dev->ml_priv;
-    u8_t EssidLen;
-    char EssidBuf[IW_ESSID_MAX_SIZE+1];
+	struct usbdrv_private *macp = dev->ml_priv;
+	u8_t EssidLen;
+	char EssidBuf[IW_ESSID_MAX_SIZE + 1];
 
-    if (macp->DeviceOpened != 1)
-        return 0;
+	if (macp->DeviceOpened != 1)
+		return 0;
 
-    zfiWlanQuerySSID(dev, &EssidBuf[0], &EssidLen);
-    EssidBuf[EssidLen] = 0;
+	zfiWlanQuerySSID(dev, &EssidBuf[0], &EssidLen);
+	EssidBuf[EssidLen] = 0;
 
-    data->flags = 1;
-    data->length = strlen(EssidBuf);
+	data->flags = 1;
+	data->length = strlen(EssidBuf);
 
-    memcpy(nickname, EssidBuf, data->length);
+	memcpy(nickname, EssidBuf, data->length);
 
 	return 0;
 }
 
 int usbdrvwext_siwrate(struct net_device *dev,
-            struct iw_request_info *info,
-            struct iw_param *frq, char *extra)
+		struct iw_request_info *info,
+		struct iw_param *frq, char *extra)
 {
 	struct usbdrv_private *macp = dev->ml_priv;
-    //Array to Define Rate Number that Send to Driver
-    u16_t zcIndextoRateBG[16] = {1000, 2000, 5500, 11000, 0, 0, 0, 0, 48000,
-                               24000, 12000, 6000, 54000, 36000, 18000, 9000};
-    u16_t zcRateToMCS[] = {0xff, 0, 1, 2, 3, 0xb, 0xf, 0xa, 0xe, 0x9, 0xd,
-                           0x8, 0xc};
-    u8_t i,RateIndex = 4;
-    u16_t RateKbps;
+	/* Array to Define Rate Number that Send to Driver */
+	u16_t zcIndextoRateBG[16] = {1000, 2000, 5500, 11000, 0, 0, 0, 0,
+			48000, 24000, 12000, 6000, 54000, 36000, 18000, 9000};
+	u16_t zcRateToMCS[] = {0xff, 0, 1, 2, 3, 0xb, 0xf, 0xa, 0xe, 0x9, 0xd,
+				0x8, 0xc};
+	u8_t i, RateIndex = 4;
+	u16_t RateKbps;
 
-    //printk("frq->disabled : 0x%x\n",frq->disabled);
-    //printk("frq->value : 0x%x\n",frq->value);
+	/* printk("frq->disabled : 0x%x\n",frq->disabled); */
+	/* printk("frq->value : 0x%x\n",frq->value); */
 
-    RateKbps = frq->value / 1000;
-    //printk("RateKbps : %d\n", RateKbps);
-    for (i = 0; i < 16; i++)
-    {
-        if (RateKbps == zcIndextoRateBG[i])
-            RateIndex = i;
-    }
-    if (zcIndextoRateBG[RateIndex] == 0)
-        RateIndex = 0xff;
-    //printk("RateIndex : %x\n", RateIndex);
-    for (i = 0; i < 13; i++)
-        if (RateIndex == zcRateToMCS[i])
-            break;
-    //printk("Index : %x\n", i);
-    if (RateKbps == 65000)
-    {
-        RateIndex = 20;
-        printk("RateIndex : %d\n", RateIndex);
-    }
-    if (macp->DeviceOpened == 1)
-    {
-        zfiWlanSetTxRate(dev, i);
-        //zfiWlanDisable(dev);
-        //zfiWlanEnable(dev);
-    }
+	RateKbps = frq->value / 1000;
+	/* printk("RateKbps : %d\n", RateKbps); */
+	for (i = 0; i < 16; i++) {
+		if (RateKbps == zcIndextoRateBG[i])
+			RateIndex = i;
+	}
 
-    return 0;
+	if (zcIndextoRateBG[RateIndex] == 0)
+		RateIndex = 0xff;
+	/* printk("RateIndex : %x\n", RateIndex); */
+	for (i = 0; i < 13; i++)
+		if (RateIndex == zcRateToMCS[i])
+			break;
+	/* printk("Index : %x\n", i); */
+	if (RateKbps == 65000) {
+		RateIndex = 20;
+		printk(KERN_WARNING "RateIndex : %d\n", RateIndex);
+	}
+
+	if (macp->DeviceOpened == 1) {
+		zfiWlanSetTxRate(dev, i);
+		/* zfiWlanDisable(dev); */
+		/* zfiWlanEnable(dev); */
+	}
+
+	return 0;
 }
 
 int usbdrvwext_giwrate(struct net_device *dev,
-            struct iw_request_info *info,
-            struct iw_param *frq, char *extra)
+		struct iw_request_info *info,
+		struct iw_param *frq, char *extra)
 {
-    struct usbdrv_private *macp = dev->ml_priv;
+	struct usbdrv_private *macp = dev->ml_priv;
 
-    if(!netif_running(dev))
-        return -EINVAL;
+	if (!netif_running(dev))
+		return -EINVAL;
 
-    if (macp->DeviceOpened != 1)
-        return 0;
+	if (macp->DeviceOpened != 1)
+		return 0;
 
-    frq->fixed = 0;
-    frq->disabled = 0;
-    frq->value = zfiWlanQueryRxRate(dev) * 1000;
+	frq->fixed = 0;
+	frq->disabled = 0;
+	frq->value = zfiWlanQueryRxRate(dev) * 1000;
 
-    return 0;
+	return 0;
 }
 
 int usbdrvwext_siwrts(struct net_device *dev,
-            struct iw_request_info *info,
-            struct iw_param *rts, char *extra)
+		struct iw_request_info *info,
+		struct iw_param *rts, char *extra)
 {
-    struct usbdrv_private *macp = dev->ml_priv;
-    int val = rts->value;
+	struct usbdrv_private *macp = dev->ml_priv;
+	int val = rts->value;
 
-    if (macp->DeviceOpened != 1)
-        return 0;
+	if (macp->DeviceOpened != 1)
+		return 0;
 
-    if (rts->disabled)
-        val = 2347;
+	if (rts->disabled)
+		val = 2347;
 
-    if ((val < 0) || (val > 2347))
-        return -EINVAL;
+	if ((val < 0) || (val > 2347))
+		return -EINVAL;
 
-    zfiWlanSetRtsThreshold(dev,val);
+	zfiWlanSetRtsThreshold(dev, val);
 
-    return 0;
+	return 0;
 }
 
 int usbdrvwext_giwrts(struct net_device *dev,
-            struct iw_request_info *info,
-            struct iw_param *rts, char *extra)
+		struct iw_request_info *info,
+		struct iw_param *rts, char *extra)
 {
-    struct usbdrv_private *macp = dev->ml_priv;
+	struct usbdrv_private *macp = dev->ml_priv;
 
-    if(!netif_running(dev))
-        return -EINVAL;
+	if (!netif_running(dev))
+		return -EINVAL;
 
-    if (macp->DeviceOpened != 1)
-        return 0;
+	if (macp->DeviceOpened != 1)
+		return 0;
 
-    rts->value = zfiWlanQueryRtsThreshold(dev);
-    rts->disabled = (rts->value >= 2347);
-    rts->fixed = 1;
+	rts->value = zfiWlanQueryRtsThreshold(dev);
+	rts->disabled = (rts->value >= 2347);
+	rts->fixed = 1;
 
-    return 0;
-
+	return 0;
 }
 
 int usbdrvwext_siwfrag(struct net_device *dev,
-            struct iw_request_info *info,
-            struct iw_param *frag, char *extra)
+		struct iw_request_info *info,
+		struct iw_param *frag, char *extra)
 {
-    struct usbdrv_private *macp = dev->ml_priv;
-    u16_t fragThreshold;
+	struct usbdrv_private *macp = dev->ml_priv;
+	u16_t fragThreshold;
 
-    if (macp->DeviceOpened != 1)
-        return 0;
+	if (macp->DeviceOpened != 1)
+		return 0;
 
-    if (frag->disabled)
-        fragThreshold = 0;
-    else
-        fragThreshold = frag->value;
+	if (frag->disabled)
+		fragThreshold = 0;
+	else
+		fragThreshold = frag->value;
 
-    zfiWlanSetFragThreshold(dev,fragThreshold);
+	zfiWlanSetFragThreshold(dev, fragThreshold);
 
-    return 0;
+	return 0;
 }
 
 int usbdrvwext_giwfrag(struct net_device *dev,
-            struct iw_request_info *info,
-            struct iw_param *frag, char *extra)
+		struct iw_request_info *info,
+		struct iw_param *frag, char *extra)
 {
-    struct usbdrv_private *macp = dev->ml_priv;
-    u16 val;
-    unsigned long irqFlag;
+	struct usbdrv_private *macp = dev->ml_priv;
+	u16 val;
+	unsigned long irqFlag;
 
-    if(!netif_running(dev))
-        return -EINVAL;
+	if (!netif_running(dev))
+		return -EINVAL;
 
-    if (macp->DeviceOpened != 1)
-        return 0;
+	if (macp->DeviceOpened != 1)
+		return 0;
 
-    spin_lock_irqsave(&macp->cs_lock, irqFlag);
+	spin_lock_irqsave(&macp->cs_lock, irqFlag);
 
-    val = zfiWlanQueryFragThreshold(dev);
+	val = zfiWlanQueryFragThreshold(dev);
 
-    frag->value = val;
+	frag->value = val;
 
-    frag->disabled = (val >= 2346);
-    frag->fixed = 1;
+	frag->disabled = (val >= 2346);
+	frag->fixed = 1;
 
-    spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
+	spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
 
-    return 0;
+	return 0;
 }
 
 int usbdrvwext_siwtxpow(struct net_device *dev,
 			struct iw_request_info *info,
 			struct iw_param *rrq, char *extra)
 {
-    //Not support yet--CWYng(+)
+	/* Not support yet--CWYng(+) */
 	return 0;
 }
 
@@ -1265,7 +1208,7 @@
 			struct iw_request_info *info,
 			struct iw_param *rrq, char *extra)
 {
-    //Not support yet--CWYng(+)
+	/* Not support yet--CWYng(+) */
 	return 0;
 }
 
@@ -1273,7 +1216,7 @@
 			struct iw_request_info *info,
 			struct iw_param *rrq, char *extra)
 {
-    //Do nothing--CWYang(+)
+	/* Do nothing--CWYang(+) */
 	return 0;
 }
 
@@ -1281,665 +1224,662 @@
 			struct iw_request_info *info,
 			struct iw_param *rrq, char *extra)
 {
-    //Do nothing--CWYang(+)
+	/* Do nothing--CWYang(+) */
 	return 0;
 }
 
 int usbdrvwext_siwencode(struct net_device *dev,
-            struct iw_request_info *info,
-            struct iw_point *erq, char *key)
+		struct iw_request_info *info,
+		struct iw_point *erq, char *key)
 {
-    struct zsKeyInfo keyInfo;
-    int i, WepState = ZM_ENCRYPTION_WEP_DISABLED;
-    struct usbdrv_private *macp = dev->ml_priv;
+	struct zsKeyInfo keyInfo;
+	int i;
+	int WepState = ZM_ENCRYPTION_WEP_DISABLED;
+	struct usbdrv_private *macp = dev->ml_priv;
 
-    if(!netif_running(dev))
-        return -EINVAL;
+	if (!netif_running(dev))
+		return -EINVAL;
 
-    if ((erq->flags & IW_ENCODE_DISABLED) == 0)
-    {
-        keyInfo.key = key;
-        keyInfo.keyLength = erq->length;
-        keyInfo.keyIndex = (erq->flags & IW_ENCODE_INDEX) - 1;
-        if (keyInfo.keyIndex >= 4)
-            keyInfo.keyIndex = 0;
-        keyInfo.flag = ZM_KEY_FLAG_DEFAULT_KEY;
+	if ((erq->flags & IW_ENCODE_DISABLED) == 0) {
+		keyInfo.key = key;
+		keyInfo.keyLength = erq->length;
+		keyInfo.keyIndex = (erq->flags & IW_ENCODE_INDEX) - 1;
+		if (keyInfo.keyIndex >= 4)
+			keyInfo.keyIndex = 0;
+		keyInfo.flag = ZM_KEY_FLAG_DEFAULT_KEY;
 
-        zfiWlanSetKey(dev, keyInfo);
-        WepState = ZM_ENCRYPTION_WEP_ENABLED;
-    }
-    else
-    {
-        for (i = 1; i < 4; i++)
-            zfiWlanRemoveKey(dev, 0, i);
-        WepState = ZM_ENCRYPTION_WEP_DISABLED;
-        //zfiWlanSetEncryMode(dev, ZM_NO_WEP);
-    }
+		zfiWlanSetKey(dev, keyInfo);
+		WepState = ZM_ENCRYPTION_WEP_ENABLED;
+	} else {
+		for (i = 1; i < 4; i++)
+			zfiWlanRemoveKey(dev, 0, i);
+		WepState = ZM_ENCRYPTION_WEP_DISABLED;
+		/* zfiWlanSetEncryMode(dev, ZM_NO_WEP); */
+	}
 
-    if (macp->DeviceOpened == 1)
-    {
-        zfiWlanSetWepStatus(dev, WepState);
-        zfiWlanSetFrequency(dev, zfiWlanQueryFrequency(dev), FALSE);
-        //zfiWlanSetEncryMode(dev, zfiWlanQueryEncryMode(dev));
-        //u8_t wpaieLen,wpaie[50];
-        //zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen);
-        zfiWlanDisable(dev, 0);
-        zfiWlanEnable(dev);
-        //if (wpaieLen > 2)
-        //    zfiWlanSetWpaIe(dev, wpaie, wpaieLen);
-    }
+	if (macp->DeviceOpened == 1) {
+		zfiWlanSetWepStatus(dev, WepState);
+		zfiWlanSetFrequency(dev, zfiWlanQueryFrequency(dev), FALSE);
+		/* zfiWlanSetEncryMode(dev, zfiWlanQueryEncryMode(dev)); */
+		/* u8_t wpaieLen,wpaie[50]; */
+		/* zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen); */
+		zfiWlanDisable(dev, 0);
+		zfiWlanEnable(dev);
+		/* if (wpaieLen > 2) */
+		/* zfiWlanSetWpaIe(dev, wpaie, wpaieLen); */
+	}
 
-    return 0;
+	return 0;
 }
 
 int usbdrvwext_giwencode(struct net_device *dev,
-            struct iw_request_info *info,
-            struct iw_point *erq, char *key)
+		struct iw_request_info *info,
+		struct iw_point *erq, char *key)
 {
-    struct usbdrv_private *macp = dev->ml_priv;
-    u8_t EncryptionMode;
-    u8_t keyLen = 0;
+	struct usbdrv_private *macp = dev->ml_priv;
+	u8_t EncryptionMode;
+	u8_t keyLen = 0;
 
-    if (macp->DeviceOpened != 1)
-        return 0;
+	if (macp->DeviceOpened != 1)
+		return 0;
 
-    EncryptionMode = zfiWlanQueryEncryMode(dev);
+	EncryptionMode = zfiWlanQueryEncryMode(dev);
 
-    if (EncryptionMode)
-    {
-        erq->flags = IW_ENCODE_ENABLED;
-    }
-    else
-    {
-        erq->flags = IW_ENCODE_DISABLED;
-    }
+	if (EncryptionMode)
+		erq->flags = IW_ENCODE_ENABLED;
+	else
+		erq->flags = IW_ENCODE_DISABLED;
 
-/* We can't return the key, so set the proper flag and return zero */
-    erq->flags |= IW_ENCODE_NOKEY;
-    memset(key, 0, 16);
+	/* We can't return the key, so set the proper flag and return zero */
+	erq->flags |= IW_ENCODE_NOKEY;
+	memset(key, 0, 16);
 
-/* Copy the key to the user buffer */
-    switch(EncryptionMode)
-    {
-        case ZM_WEP64:
-            keyLen = 5;
-            break;
-        case ZM_WEP128:
-            keyLen = 13;
-            break;
-        case ZM_WEP256:
-            keyLen = 29;
-            break;
-        case ZM_AES:
-            keyLen = 16;
-            break;
-        case ZM_TKIP:
-            keyLen = 32;
-            break;
-#ifdef ZM_ENABLE_CENC
-        case ZM_CENC:
-            keyLen = 32;
-            break;
-#endif //ZM_ENABLE_CENC
-        case ZM_NO_WEP:
-            keyLen = 0;
-            break;
-        default :
-            keyLen = 0;
-            printk("Unknown EncryMode\n");
-            break;
+	/* Copy the key to the user buffer */
+	switch (EncryptionMode) {
+	case ZM_WEP64:
+		keyLen = 5;
+		break;
+	case ZM_WEP128:
+		keyLen = 13;
+		break;
+	case ZM_WEP256:
+		keyLen = 29;
+		break;
+	case ZM_AES:
+		keyLen = 16;
+		break;
+	case ZM_TKIP:
+		keyLen = 32;
+		break;
+	#ifdef ZM_ENABLE_CENC
+	case ZM_CENC:
+		/* ZM_ENABLE_CENC */
+		keyLen = 32;
+		break;
+	#endif
+	case ZM_NO_WEP:
+		keyLen = 0;
+		break;
+	default:
+		keyLen = 0;
+		printk(KERN_ERR "Unknown EncryMode\n");
+		break;
+	}
+	erq->length = keyLen;
 
-    }
-    erq->length = keyLen;
-
-    return 0;
+	return 0;
 }
 
 int usbdrvwext_siwpower(struct net_device *dev,
-            struct iw_request_info *info,
-            struct iw_param *frq, char *extra)
+		struct iw_request_info *info,
+		struct iw_param *frq, char *extra)
 {
-    struct usbdrv_private *macp = dev->ml_priv;
-    u8_t PSMode;
+	struct usbdrv_private *macp = dev->ml_priv;
+	u8_t PSMode;
 
-    if (macp->DeviceOpened != 1)
-        return 0;
+	if (macp->DeviceOpened != 1)
+		return 0;
 
-    if (frq->disabled)
-        PSMode = ZM_STA_PS_NONE;
-    else
-        PSMode = ZM_STA_PS_MAX;
+	if (frq->disabled)
+		PSMode = ZM_STA_PS_NONE;
+	else
+		PSMode = ZM_STA_PS_MAX;
 
-    zfiWlanSetPowerSaveMode(dev,PSMode);
+	zfiWlanSetPowerSaveMode(dev, PSMode);
 
-    return 0;
+	return 0;
 }
 
 int usbdrvwext_giwpower(struct net_device *dev,
-            struct iw_request_info *info,
-            struct iw_param *frq, char *extra)
+		struct iw_request_info *info,
+		struct iw_param *frq, char *extra)
 {
-    unsigned long irqFlag;
-    struct usbdrv_private *macp = dev->ml_priv;
+	unsigned long irqFlag;
+	struct usbdrv_private *macp = dev->ml_priv;
 
-    if (macp->DeviceOpened != 1)
-        return 0;
+	if (macp->DeviceOpened != 1)
+		return 0;
 
-    spin_lock_irqsave(&macp->cs_lock, irqFlag);
+	spin_lock_irqsave(&macp->cs_lock, irqFlag);
 
-    if (zfiWlanQueryPowerSaveMode(dev) == ZM_STA_PS_NONE)
-        frq->disabled = 1;
-    else
-        frq->disabled = 0;
+	if (zfiWlanQueryPowerSaveMode(dev) == ZM_STA_PS_NONE)
+		frq->disabled = 1;
+	else
+		frq->disabled = 0;
 
-    spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
+	spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
 
-    return 0;
+	return 0;
 }
 
-//int usbdrvwext_setparam(struct net_device *dev, struct iw_request_info *info,
-//		   	 void *w, char *extra)
-//{
-//	struct ieee80211vap *vap = dev->ml_priv;
-//	struct ieee80211com *ic = vap->iv_ic;
-//	struct ieee80211_rsnparms *rsn = &vap->iv_bss->ni_rsn;
-//	int *i = (int *) extra;
-//	int param = i[0];		/* parameter id is 1st */
-//	int value = i[1];		/* NB: most values are TYPE_INT */
-//	int retv = 0;
-//	int j, caps;
-//	const struct ieee80211_authenticator *auth;
-//	const struct ieee80211_aclator *acl;
-//
-//	switch (param) {
-//	case IEEE80211_PARAM_AUTHMODE:
-//		switch (value) {
-//		case IEEE80211_AUTH_WPA:	/* WPA */
-//		case IEEE80211_AUTH_8021X:	/* 802.1x */
-//		case IEEE80211_AUTH_OPEN:	/* open */
-//		case IEEE80211_AUTH_SHARED:	/* shared-key */
-//		case IEEE80211_AUTH_AUTO:	/* auto */
-//			auth = ieee80211_authenticator_get(value);
-//			if (auth == NULL)
-//				return -EINVAL;
-//			break;
-//		default:
-//			return -EINVAL;
-//		}
-//		switch (value) {
-//		case IEEE80211_AUTH_WPA:	/* WPA w/ 802.1x */
-//			vap->iv_flags |= IEEE80211_F_PRIVACY;
-//			value = IEEE80211_AUTH_8021X;
-//			break;
-//		case IEEE80211_AUTH_OPEN:	/* open */
-//			vap->iv_flags &= ~(IEEE80211_F_WPA|IEEE80211_F_PRIVACY);
-//			break;
-//		case IEEE80211_AUTH_SHARED:	/* shared-key */
-//		case IEEE80211_AUTH_AUTO:	/* auto */
-//		case IEEE80211_AUTH_8021X:	/* 802.1x */
-//			vap->iv_flags &= ~IEEE80211_F_WPA;
-//			/* both require a key so mark the PRIVACY capability */
-//			vap->iv_flags |= IEEE80211_F_PRIVACY;
-//			break;
-//		}
-//		/* NB: authenticator attach/detach happens on state change */
-//		vap->iv_bss->ni_authmode = value;
-//		/* XXX mixed/mode/usage? */
-//		vap->iv_auth = auth;
-//		retv = ENETRESET;
-//		break;
-//	case IEEE80211_PARAM_PROTMODE:
-//		if (value > IEEE80211_PROT_RTSCTS)
-//			return -EINVAL;
-//		ic->ic_protmode = value;
-//		/* NB: if not operating in 11g this can wait */
-//		if (ic->ic_bsschan != IEEE80211_CHAN_ANYC &&
-//		    IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan))
-//			retv = ENETRESET;
-//		break;
-//	case IEEE80211_PARAM_MCASTCIPHER:
-//		if ((vap->iv_caps & cipher2cap(value)) == 0 &&
-//		    !ieee80211_crypto_available(value))
-//			return -EINVAL;
-//		rsn->rsn_mcastcipher = value;
-//		if (vap->iv_flags & IEEE80211_F_WPA)
-//			retv = ENETRESET;
-//		break;
-//	case IEEE80211_PARAM_MCASTKEYLEN:
-//		if (!(0 < value && value < IEEE80211_KEYBUF_SIZE))
-//			return -EINVAL;
-//		/* XXX no way to verify driver capability */
-//		rsn->rsn_mcastkeylen = value;
-//		if (vap->iv_flags & IEEE80211_F_WPA)
-//			retv = ENETRESET;
-//		break;
-//	case IEEE80211_PARAM_UCASTCIPHERS:
-//		/*
-//		 * Convert cipher set to equivalent capabilities.
-//		 * NB: this logic intentionally ignores unknown and
-//		 * unsupported ciphers so folks can specify 0xff or
-//		 * similar and get all available ciphers.
-//		 */
-//		caps = 0;
-//		for (j = 1; j < 32; j++)	/* NB: skip WEP */
-//			if ((value & (1<<j)) &&
-//			    ((vap->iv_caps & cipher2cap(j)) ||
-//			     ieee80211_crypto_available(j)))
-//				caps |= 1<<j;
-//		if (caps == 0)			/* nothing available */
-//			return -EINVAL;
-//		/* XXX verify ciphers ok for unicast use? */
-//		/* XXX disallow if running as it'll have no effect */
-//		rsn->rsn_ucastcipherset = caps;
-//		if (vap->iv_flags & IEEE80211_F_WPA)
-//			retv = ENETRESET;
-//		break;
-//	case IEEE80211_PARAM_UCASTCIPHER:
-//		if ((rsn->rsn_ucastcipherset & cipher2cap(value)) == 0)
-//			return -EINVAL;
-//		rsn->rsn_ucastcipher = value;
-//		break;
-//	case IEEE80211_PARAM_UCASTKEYLEN:
-//		if (!(0 < value && value < IEEE80211_KEYBUF_SIZE))
-//			return -EINVAL;
-//		/* XXX no way to verify driver capability */
-//		rsn->rsn_ucastkeylen = value;
-//		break;
-//	case IEEE80211_PARAM_KEYMGTALGS:
-//		/* XXX check */
-//		rsn->rsn_keymgmtset = value;
-//		if (vap->iv_flags & IEEE80211_F_WPA)
-//			retv = ENETRESET;
-//		break;
-//	case IEEE80211_PARAM_RSNCAPS:
-//		/* XXX check */
-//		rsn->rsn_caps = value;
-//		if (vap->iv_flags & IEEE80211_F_WPA)
-//			retv = ENETRESET;
-//		break;
-//	case IEEE80211_PARAM_WPA:
-//		if (value > 3)
-//			return -EINVAL;
-//		/* XXX verify ciphers available */
-//		vap->iv_flags &= ~IEEE80211_F_WPA;
-//		switch (value) {
-//		case 1:
-//			vap->iv_flags |= IEEE80211_F_WPA1;
-//			break;
-//		case 2:
-//			vap->iv_flags |= IEEE80211_F_WPA2;
-//			break;
-//		case 3:
-//			vap->iv_flags |= IEEE80211_F_WPA1 | IEEE80211_F_WPA2;
-//			break;
-//		}
-//		retv = ENETRESET;		/* XXX? */
-//		break;
-//	case IEEE80211_PARAM_ROAMING:
-//		if (!(IEEE80211_ROAMING_DEVICE <= value &&
-//		    value <= IEEE80211_ROAMING_MANUAL))
-//			return -EINVAL;
-//		ic->ic_roaming = value;
-//		break;
-//	case IEEE80211_PARAM_PRIVACY:
-//		if (value) {
-//			/* XXX check for key state? */
-//			vap->iv_flags |= IEEE80211_F_PRIVACY;
-//		} else
-//			vap->iv_flags &= ~IEEE80211_F_PRIVACY;
-//		break;
-//	case IEEE80211_PARAM_DROPUNENCRYPTED:
-//		if (value)
-//			vap->iv_flags |= IEEE80211_F_DROPUNENC;
-//		else
-//			vap->iv_flags &= ~IEEE80211_F_DROPUNENC;
-//		break;
-//	case IEEE80211_PARAM_COUNTERMEASURES:
-//		if (value) {
-//			if ((vap->iv_flags & IEEE80211_F_WPA) == 0)
-//				return -EINVAL;
-//			vap->iv_flags |= IEEE80211_F_COUNTERM;
-//		} else
-//			vap->iv_flags &= ~IEEE80211_F_COUNTERM;
-//		break;
-//	case IEEE80211_PARAM_DRIVER_CAPS:
-//		vap->iv_caps = value;		/* NB: for testing */
-//		break;
-//	case IEEE80211_PARAM_MACCMD:
-//		acl = vap->iv_acl;
-//		switch (value) {
-//		case IEEE80211_MACCMD_POLICY_OPEN:
-//		case IEEE80211_MACCMD_POLICY_ALLOW:
-//		case IEEE80211_MACCMD_POLICY_DENY:
-//			if (acl == NULL) {
-//				acl = ieee80211_aclator_get("mac");
-//				if (acl == NULL || !acl->iac_attach(vap))
-//					return -EINVAL;
-//				vap->iv_acl = acl;
-//			}
-//			acl->iac_setpolicy(vap, value);
-//			break;
-//		case IEEE80211_MACCMD_FLUSH:
-//			if (acl != NULL)
-//				acl->iac_flush(vap);
-//			/* NB: silently ignore when not in use */
-//			break;
-//		case IEEE80211_MACCMD_DETACH:
-//			if (acl != NULL) {
-//				vap->iv_acl = NULL;
-//				acl->iac_detach(vap);
-//			}
-//			break;
-//		}
-//		break;
-//	case IEEE80211_PARAM_WMM:
-//		if (ic->ic_caps & IEEE80211_C_WME){
-//			if (value) {
-//				vap->iv_flags |= IEEE80211_F_WME;
-//				vap->iv_ic->ic_flags |= IEEE80211_F_WME; /* XXX needed by ic_reset */
-//			}
-//			else {
-//				vap->iv_flags &= ~IEEE80211_F_WME;
-//				vap->iv_ic->ic_flags &= ~IEEE80211_F_WME; /* XXX needed by ic_reset */
-//			}
-//			retv = ENETRESET;	/* Renegotiate for capabilities */
-//		}
-//		break;
-//	case IEEE80211_PARAM_HIDESSID:
-//		if (value)
-//			vap->iv_flags |= IEEE80211_F_HIDESSID;
-//		else
-//			vap->iv_flags &= ~IEEE80211_F_HIDESSID;
-//		retv = ENETRESET;
-//		break;
-//	case IEEE80211_PARAM_APBRIDGE:
-//		if (value == 0)
-//			vap->iv_flags |= IEEE80211_F_NOBRIDGE;
-//		else
-//			vap->iv_flags &= ~IEEE80211_F_NOBRIDGE;
-//		break;
-//	case IEEE80211_PARAM_INACT:
-//		vap->iv_inact_run = value / IEEE80211_INACT_WAIT;
-//		break;
-//	case IEEE80211_PARAM_INACT_AUTH:
-//		vap->iv_inact_auth = value / IEEE80211_INACT_WAIT;
-//		break;
-//	case IEEE80211_PARAM_INACT_INIT:
-//		vap->iv_inact_init = value / IEEE80211_INACT_WAIT;
-//		break;
-//	case IEEE80211_PARAM_ABOLT:
-//		caps = 0;
-//		/*
-//		 * Map abolt settings to capability bits;
-//		 * this also strips unknown/unwanted bits.
-//		 */
-//		if (value & IEEE80211_ABOLT_TURBO_PRIME)
-//			caps |= IEEE80211_ATHC_TURBOP;
-//		if (value & IEEE80211_ABOLT_COMPRESSION)
-//			caps |= IEEE80211_ATHC_COMP;
-//		if (value & IEEE80211_ABOLT_FAST_FRAME)
-//			caps |= IEEE80211_ATHC_FF;
-//		if (value & IEEE80211_ABOLT_XR)
-//			caps |= IEEE80211_ATHC_XR;
-//		if (value & IEEE80211_ABOLT_AR)
-//			caps |= IEEE80211_ATHC_AR;
-//		if (value & IEEE80211_ABOLT_BURST)
-//			caps |= IEEE80211_ATHC_BURST;
-//        if (value & IEEE80211_ABOLT_WME_ELE)
-//            caps |= IEEE80211_ATHC_WME;
-//		/* verify requested capabilities are supported */
-//		if ((caps & ic->ic_ath_cap) != caps)
-//			return -EINVAL;
-//		if (vap->iv_ath_cap != caps) {
-//			if ((vap->iv_ath_cap ^ caps) & IEEE80211_ATHC_TURBOP) {
-//				if (ieee80211_set_turbo(dev,  caps & IEEE80211_ATHC_TURBOP))
-//					return -EINVAL;
-//				ieee80211_scan_flush(ic);
-//			}
-//			vap->iv_ath_cap = caps;
-//			ic->ic_athcapsetup(vap->iv_ic, vap->iv_ath_cap);
-//			retv = ENETRESET;
-//		}
-//		break;
-//	case IEEE80211_PARAM_DTIM_PERIOD:
-//		if (vap->iv_opmode != IEEE80211_M_HOSTAP &&
-//		    vap->iv_opmode != IEEE80211_M_IBSS)
-//			return -EINVAL;
-//		if (IEEE80211_DTIM_MIN <= value &&
-//		    value <= IEEE80211_DTIM_MAX) {
-//			vap->iv_dtim_period = value;
-//			retv = ENETRESET;		/* requires restart */
-//		} else
-//			retv = EINVAL;
-//		break;
-//	case IEEE80211_PARAM_BEACON_INTERVAL:
-//		if (vap->iv_opmode != IEEE80211_M_HOSTAP &&
-//		    vap->iv_opmode != IEEE80211_M_IBSS)
-//			return -EINVAL;
-//		if (IEEE80211_BINTVAL_MIN <= value &&
-//		    value <= IEEE80211_BINTVAL_MAX) {
-//			ic->ic_lintval = value;		/* XXX multi-bss */
-//			retv = ENETRESET;		/* requires restart */
-//		} else
-//			retv = EINVAL;
-//		break;
-//	case IEEE80211_PARAM_DOTH:
-//		if (value) {
-//			ic->ic_flags |= IEEE80211_F_DOTH;
-//		}
-//		else
-//			ic->ic_flags &= ~IEEE80211_F_DOTH;
-//		retv = ENETRESET;	/* XXX: need something this drastic? */
-//		break;
-//	case IEEE80211_PARAM_PWRTARGET:
-//		ic->ic_curchanmaxpwr = value;
-//		break;
-//	case IEEE80211_PARAM_GENREASSOC:
-//		IEEE80211_SEND_MGMT(vap->iv_bss, IEEE80211_FC0_SUBTYPE_REASSOC_REQ, 0);
-//		break;
-//	case IEEE80211_PARAM_COMPRESSION:
-//		retv = ieee80211_setathcap(vap, IEEE80211_ATHC_COMP, value);
-//		break;
-//    case IEEE80211_PARAM_WMM_AGGRMODE:
-//        retv = ieee80211_setathcap(vap, IEEE80211_ATHC_WME, value);
-//        break;
-//	case IEEE80211_PARAM_FF:
-//		retv = ieee80211_setathcap(vap, IEEE80211_ATHC_FF, value);
-//		break;
-//	case IEEE80211_PARAM_TURBO:
-//		retv = ieee80211_setathcap(vap, IEEE80211_ATHC_TURBOP, value);
-//		if (retv == ENETRESET) {
-//			if(ieee80211_set_turbo(dev,value))
-//					return -EINVAL;
-//			ieee80211_scan_flush(ic);
-//		}
-//		break;
-//	case IEEE80211_PARAM_XR:
-//		retv = ieee80211_setathcap(vap, IEEE80211_ATHC_XR, value);
-//		break;
-//	case IEEE80211_PARAM_BURST:
-//		retv = ieee80211_setathcap(vap, IEEE80211_ATHC_BURST, value);
-//		break;
-//	case IEEE80211_PARAM_AR:
-//		retv = ieee80211_setathcap(vap, IEEE80211_ATHC_AR, value);
-//		break;
-//	case IEEE80211_PARAM_PUREG:
-//		if (value)
-//			vap->iv_flags |= IEEE80211_F_PUREG;
-//		else
-//			vap->iv_flags &= ~IEEE80211_F_PUREG;
-//		/* NB: reset only if we're operating on an 11g channel */
-//		if (ic->ic_bsschan != IEEE80211_CHAN_ANYC &&
-//		    IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan))
-//			retv = ENETRESET;
-//		break;
-//	case IEEE80211_PARAM_WDS:
-//		if (value)
-//			vap->iv_flags_ext |= IEEE80211_FEXT_WDS;
-//		else
-//			vap->iv_flags_ext &= ~IEEE80211_FEXT_WDS;
-//		break;
-//	case IEEE80211_PARAM_BGSCAN:
-//		if (value) {
-//			if ((vap->iv_caps & IEEE80211_C_BGSCAN) == 0)
-//				return -EINVAL;
-//			vap->iv_flags |= IEEE80211_F_BGSCAN;
-//		} else {
-//			/* XXX racey? */
-//			vap->iv_flags &= ~IEEE80211_F_BGSCAN;
-//			ieee80211_cancel_scan(vap);	/* anything current */
-//		}
-//		break;
-//	case IEEE80211_PARAM_BGSCAN_IDLE:
-//		if (value >= IEEE80211_BGSCAN_IDLE_MIN)
-//			vap->iv_bgscanidle = value*HZ/1000;
-//		else
-//			retv = EINVAL;
-//		break;
-//	case IEEE80211_PARAM_BGSCAN_INTERVAL:
-//		if (value >= IEEE80211_BGSCAN_INTVAL_MIN)
-//			vap->iv_bgscanintvl = value*HZ;
-//		else
-//			retv = EINVAL;
-//		break;
-//	case IEEE80211_PARAM_MCAST_RATE:
-//		/* units are in KILObits per second */
-//		if (value >= 256 && value <= 54000)
-//			vap->iv_mcast_rate = value;
-//		else
-//			retv = EINVAL;
-//		break;
-//	case IEEE80211_PARAM_COVERAGE_CLASS:
-//		if (value >= 0 && value <= IEEE80211_COVERAGE_CLASS_MAX) {
-//			ic->ic_coverageclass = value;
-//			if (IS_UP_AUTO(vap))
-//				ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
-//			retv = 0;
-//		}
-//		else
-//			retv = EINVAL;
-//		break;
-//	case IEEE80211_PARAM_COUNTRY_IE:
-//		if (value)
-//			ic->ic_flags_ext |= IEEE80211_FEXT_COUNTRYIE;
-//		else
-//			ic->ic_flags_ext &= ~IEEE80211_FEXT_COUNTRYIE;
-//		retv = ENETRESET;
-//		break;
-//	case IEEE80211_PARAM_REGCLASS:
-//		if (value)
-//			ic->ic_flags_ext |= IEEE80211_FEXT_REGCLASS;
-//		else
-//			ic->ic_flags_ext &= ~IEEE80211_FEXT_REGCLASS;
-//		retv = ENETRESET;
-//		break;
-//	case IEEE80211_PARAM_SCANVALID:
-//		vap->iv_scanvalid = value*HZ;
-//		break;
-//	case IEEE80211_PARAM_ROAM_RSSI_11A:
-//		vap->iv_roam.rssi11a = value;
-//		break;
-//	case IEEE80211_PARAM_ROAM_RSSI_11B:
-//		vap->iv_roam.rssi11bOnly = value;
-//		break;
-//	case IEEE80211_PARAM_ROAM_RSSI_11G:
-//		vap->iv_roam.rssi11b = value;
-//		break;
-//	case IEEE80211_PARAM_ROAM_RATE_11A:
-//		vap->iv_roam.rate11a = value;
-//		break;
-//	case IEEE80211_PARAM_ROAM_RATE_11B:
-//		vap->iv_roam.rate11bOnly = value;
-//		break;
-//	case IEEE80211_PARAM_ROAM_RATE_11G:
-//		vap->iv_roam.rate11b = value;
-//		break;
-//	case IEEE80211_PARAM_UAPSDINFO:
-//		if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
-//			if (ic->ic_caps & IEEE80211_C_UAPSD) {
-//				if (value)
-//					IEEE80211_VAP_UAPSD_ENABLE(vap);
-//				else
-//					IEEE80211_VAP_UAPSD_DISABLE(vap);
-//				retv = ENETRESET;
-//			}
-//		}
-//		else if (vap->iv_opmode == IEEE80211_M_STA) {
-//			vap->iv_uapsdinfo = value;
-//			IEEE80211_VAP_UAPSD_ENABLE(vap);
-//			retv = ENETRESET;
-//		}
-//		break;
-//	case IEEE80211_PARAM_SLEEP:
-//		/* XXX: Forced sleep for testing. Does not actually place the
-//		 *      HW in sleep mode yet. this only makes sense for STAs.
-//		 */
-//		if (value) {
-//			/* goto sleep */
-//			IEEE80211_VAP_GOTOSLEEP(vap);
-//		}
-//		else {
-//			/* wakeup */
-//			IEEE80211_VAP_WAKEUP(vap);
-//		}
-//		ieee80211_send_nulldata(ieee80211_ref_node(vap->iv_bss));
-//		break;
-//	case IEEE80211_PARAM_QOSNULL:
-//		/* Force a QoS Null for testing. */
-//		ieee80211_send_qosnulldata(vap->iv_bss, value);
-//		break;
-//	case IEEE80211_PARAM_PSPOLL:
-//		/* Force a PS-POLL for testing. */
-//		ieee80211_send_pspoll(vap->iv_bss);
-//		break;
-//	case IEEE80211_PARAM_EOSPDROP:
-//		if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
-//			if (value) IEEE80211_VAP_EOSPDROP_ENABLE(vap);
-//			else IEEE80211_VAP_EOSPDROP_DISABLE(vap);
-//		}
-//		break;
-//	case IEEE80211_PARAM_MARKDFS:
-//		if (value)
-//			ic->ic_flags_ext |= IEEE80211_FEXT_MARKDFS;
-//		else
-//			ic->ic_flags_ext &= ~IEEE80211_FEXT_MARKDFS;
-//		break;
-//	case IEEE80211_PARAM_CHANBW:
-//		switch (value) {
-//			case 0:
-//				ic->ic_chanbwflag = 0;
-//				break;
-//			case 1:
-//				ic->ic_chanbwflag = IEEE80211_CHAN_HALF;
-//				break;
-//			case 2:
-//				ic->ic_chanbwflag = IEEE80211_CHAN_QUARTER;
-//				break;
-//			default:
-//				retv = EINVAL;
-//				break;
-//		}
-//		break;
-//	case IEEE80211_PARAM_SHORTPREAMBLE:
-//		if (value) {
-//			ic->ic_caps |= IEEE80211_C_SHPREAMBLE;
-//		} else {
-//			ic->ic_caps &= ~IEEE80211_C_SHPREAMBLE;
-//		}
-//		retv = ENETRESET;
-//		break;
-//	default:
-//		retv = EOPNOTSUPP;
-//		break;
-//	}
-//	/* XXX should any of these cause a rescan? */
-//	if (retv == ENETRESET)
-//		retv = IS_UP_AUTO(vap) ? ieee80211_open(vap->iv_dev) : 0;
-//	return -retv;
-//}
+/*int usbdrvwext_setparam(struct net_device *dev, struct iw_request_info *info,
+*		   	 void *w, char *extra)
+*{
+*	struct ieee80211vap *vap = dev->ml_priv;
+*	struct ieee80211com *ic = vap->iv_ic;
+*	struct ieee80211_rsnparms *rsn = &vap->iv_bss->ni_rsn;
+*	int *i = (int *) extra;
+*	int param = i[0];		// parameter id is 1st
+*	int value = i[1];		// NB: most values are TYPE_INT
+*	int retv = 0;
+*	int j, caps;
+*	const struct ieee80211_authenticator *auth;
+*	const struct ieee80211_aclator *acl;
+*
+*	switch (param) {
+*	case IEEE80211_PARAM_AUTHMODE:
+*		switch (value) {
+*		case IEEE80211_AUTH_WPA:	// WPA
+*		case IEEE80211_AUTH_8021X:	// 802.1x
+*		case IEEE80211_AUTH_OPEN:	// open
+*		case IEEE80211_AUTH_SHARED:	// shared-key
+*		case IEEE80211_AUTH_AUTO:	// auto
+*			auth = ieee80211_authenticator_get(value);
+*			if (auth == NULL)
+*				return -EINVAL;
+*			break;
+*		default:
+*			return -EINVAL;
+*		}
+*		switch (value) {
+*		case IEEE80211_AUTH_WPA:	// WPA w/ 802.1x
+*			vap->iv_flags |= IEEE80211_F_PRIVACY;
+*			value = IEEE80211_AUTH_8021X;
+*			break;
+*		case IEEE80211_AUTH_OPEN:	// open
+*		vap->iv_flags &= ~(IEEE80211_F_WPA | IEEE80211_F_PRIVACY);
+*			break;
+*		case IEEE80211_AUTH_SHARED:	// shared-key
+*		case IEEE80211_AUTH_AUTO:	// auto
+*		case IEEE80211_AUTH_8021X:	// 802.1x
+*			vap->iv_flags &= ~IEEE80211_F_WPA;
+*			// both require a key so mark the PRIVACY capability
+*			vap->iv_flags |= IEEE80211_F_PRIVACY;
+*			break;
+*		}
+*		// NB: authenticator attach/detach happens on state change
+*		vap->iv_bss->ni_authmode = value;
+*		// XXX mixed/mode/usage?
+*		vap->iv_auth = auth;
+*		retv = ENETRESET;
+*		break;
+*	case IEEE80211_PARAM_PROTMODE:
+*		if (value > IEEE80211_PROT_RTSCTS)
+*			return -EINVAL;
+*		ic->ic_protmode = value;
+*		// NB: if not operating in 11g this can wait
+*		if (ic->ic_bsschan != IEEE80211_CHAN_ANYC &&
+*		    IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan))
+*			retv = ENETRESET;
+*		break;
+*	case IEEE80211_PARAM_MCASTCIPHER:
+*		if ((vap->iv_caps & cipher2cap(value)) == 0 &&
+*		    !ieee80211_crypto_available(value))
+*			return -EINVAL;
+*		rsn->rsn_mcastcipher = value;
+*		if (vap->iv_flags & IEEE80211_F_WPA)
+*			retv = ENETRESET;
+*		break;
+*	case IEEE80211_PARAM_MCASTKEYLEN:
+*		if (!(0 < value && value < IEEE80211_KEYBUF_SIZE))
+*			return -EINVAL;
+*		// XXX no way to verify driver capability
+*		rsn->rsn_mcastkeylen = value;
+*		if (vap->iv_flags & IEEE80211_F_WPA)
+*			retv = ENETRESET;
+*		break;
+*	case IEEE80211_PARAM_UCASTCIPHERS:
+*
+*		 // Convert cipher set to equivalent capabilities.
+*		 // NB: this logic intentionally ignores unknown and
+*		 // unsupported ciphers so folks can specify 0xff or
+*		 // similar and get all available ciphers.
+*
+*		caps = 0;
+*		for (j = 1; j < 32; j++)	// NB: skip WEP
+*			if ((value & (1<<j)) &&
+*			    ((vap->iv_caps & cipher2cap(j)) ||
+*			     ieee80211_crypto_available(j)))
+*				caps |= 1<<j;
+*		if (caps == 0)			// nothing available
+*			return -EINVAL;
+*		// XXX verify ciphers ok for unicast use?
+*		// XXX disallow if running as it'll have no effect
+*		rsn->rsn_ucastcipherset = caps;
+*		if (vap->iv_flags & IEEE80211_F_WPA)
+*			retv = ENETRESET;
+*		break;
+*	case IEEE80211_PARAM_UCASTCIPHER:
+*		if ((rsn->rsn_ucastcipherset & cipher2cap(value)) == 0)
+*			return -EINVAL;
+*		rsn->rsn_ucastcipher = value;
+*		break;
+*	case IEEE80211_PARAM_UCASTKEYLEN:
+*		if (!(0 < value && value < IEEE80211_KEYBUF_SIZE))
+*			return -EINVAL;
+*		// XXX no way to verify driver capability
+*		rsn->rsn_ucastkeylen = value;
+*		break;
+*	case IEEE80211_PARAM_KEYMGTALGS:
+*		// XXX check
+*		rsn->rsn_keymgmtset = value;
+*		if (vap->iv_flags & IEEE80211_F_WPA)
+*			retv = ENETRESET;
+*		break;
+*	case IEEE80211_PARAM_RSNCAPS:
+*		// XXX check
+*		rsn->rsn_caps = value;
+*		if (vap->iv_flags & IEEE80211_F_WPA)
+*			retv = ENETRESET;
+*		break;
+*	case IEEE80211_PARAM_WPA:
+*		if (value > 3)
+*			return -EINVAL;
+*		// XXX verify ciphers available
+*		vap->iv_flags &= ~IEEE80211_F_WPA;
+*		switch (value) {
+*		case 1:
+*			vap->iv_flags |= IEEE80211_F_WPA1;
+*			break;
+*		case 2:
+*			vap->iv_flags |= IEEE80211_F_WPA2;
+*			break;
+*		case 3:
+*			vap->iv_flags |= IEEE80211_F_WPA1 | IEEE80211_F_WPA2;
+*			break;
+*		}
+*		retv = ENETRESET;		// XXX?
+*		break;
+*	case IEEE80211_PARAM_ROAMING:
+*		if (!(IEEE80211_ROAMING_DEVICE <= value &&
+*		    value <= IEEE80211_ROAMING_MANUAL))
+*			return -EINVAL;
+*		ic->ic_roaming = value;
+*		break;
+*	case IEEE80211_PARAM_PRIVACY:
+*		if (value) {
+*			// XXX check for key state?
+*			vap->iv_flags |= IEEE80211_F_PRIVACY;
+*		} else
+*			vap->iv_flags &= ~IEEE80211_F_PRIVACY;
+*		break;
+*	case IEEE80211_PARAM_DROPUNENCRYPTED:
+*		if (value)
+*			vap->iv_flags |= IEEE80211_F_DROPUNENC;
+*		else
+*			vap->iv_flags &= ~IEEE80211_F_DROPUNENC;
+*		break;
+*	case IEEE80211_PARAM_COUNTERMEASURES:
+*		if (value) {
+*			if ((vap->iv_flags & IEEE80211_F_WPA) == 0)
+*				return -EINVAL;
+*			vap->iv_flags |= IEEE80211_F_COUNTERM;
+*		} else
+*			vap->iv_flags &= ~IEEE80211_F_COUNTERM;
+*		break;
+*	case IEEE80211_PARAM_DRIVER_CAPS:
+*		vap->iv_caps = value;		// NB: for testing
+*		break;
+*	case IEEE80211_PARAM_MACCMD:
+*		acl = vap->iv_acl;
+*		switch (value) {
+*		case IEEE80211_MACCMD_POLICY_OPEN:
+*		case IEEE80211_MACCMD_POLICY_ALLOW:
+*		case IEEE80211_MACCMD_POLICY_DENY:
+*			if (acl == NULL) {
+*				acl = ieee80211_aclator_get("mac");
+*				if (acl == NULL || !acl->iac_attach(vap))
+*					return -EINVAL;
+*				vap->iv_acl = acl;
+*			}
+*			acl->iac_setpolicy(vap, value);
+*			break;
+*		case IEEE80211_MACCMD_FLUSH:
+*			if (acl != NULL)
+*				acl->iac_flush(vap);
+*			// NB: silently ignore when not in use
+*			break;
+*		case IEEE80211_MACCMD_DETACH:
+*			if (acl != NULL) {
+*				vap->iv_acl = NULL;
+*				acl->iac_detach(vap);
+*			}
+*			break;
+*		}
+*		break;
+*	case IEEE80211_PARAM_WMM:
+*		if (ic->ic_caps & IEEE80211_C_WME){
+*			if (value) {
+*				vap->iv_flags |= IEEE80211_F_WME;
+*				 *//* XXX needed by ic_reset *//*
+*				vap->iv_ic->ic_flags |= IEEE80211_F_WME;
+*			}
+*			else {
+*				*//* XXX needed by ic_reset *//*
+*				vap->iv_flags &= ~IEEE80211_F_WME;
+*				vap->iv_ic->ic_flags &= ~IEEE80211_F_WME;
+*			}
+*			retv = ENETRESET;	// Renegotiate for capabilities
+*		}
+*		break;
+*	case IEEE80211_PARAM_HIDESSID:
+*		if (value)
+*			vap->iv_flags |= IEEE80211_F_HIDESSID;
+*		else
+*			vap->iv_flags &= ~IEEE80211_F_HIDESSID;
+*		retv = ENETRESET;
+*		break;
+*	case IEEE80211_PARAM_APBRIDGE:
+*		if (value == 0)
+*			vap->iv_flags |= IEEE80211_F_NOBRIDGE;
+*		else
+*			vap->iv_flags &= ~IEEE80211_F_NOBRIDGE;
+*		break;
+*	case IEEE80211_PARAM_INACT:
+*		vap->iv_inact_run = value / IEEE80211_INACT_WAIT;
+*		break;
+*	case IEEE80211_PARAM_INACT_AUTH:
+*		vap->iv_inact_auth = value / IEEE80211_INACT_WAIT;
+*		break;
+*	case IEEE80211_PARAM_INACT_INIT:
+*		vap->iv_inact_init = value / IEEE80211_INACT_WAIT;
+*		break;
+*	case IEEE80211_PARAM_ABOLT:
+*		caps = 0;
+*
+*		 // Map abolt settings to capability bits;
+*		 // this also strips unknown/unwanted bits.
+*
+*		if (value & IEEE80211_ABOLT_TURBO_PRIME)
+*			caps |= IEEE80211_ATHC_TURBOP;
+*		if (value & IEEE80211_ABOLT_COMPRESSION)
+*			caps |= IEEE80211_ATHC_COMP;
+*		if (value & IEEE80211_ABOLT_FAST_FRAME)
+*			caps |= IEEE80211_ATHC_FF;
+*		if (value & IEEE80211_ABOLT_XR)
+*			caps |= IEEE80211_ATHC_XR;
+*		if (value & IEEE80211_ABOLT_AR)
+*			caps |= IEEE80211_ATHC_AR;
+*		if (value & IEEE80211_ABOLT_BURST)
+*			caps |= IEEE80211_ATHC_BURST;
+*        if (value & IEEE80211_ABOLT_WME_ELE)
+*            caps |= IEEE80211_ATHC_WME;
+*		// verify requested capabilities are supported
+*		if ((caps & ic->ic_ath_cap) != caps)
+*			return -EINVAL;
+*		if (vap->iv_ath_cap != caps) {
+*			if ((vap->iv_ath_cap ^ caps) & IEEE80211_ATHC_TURBOP) {
+*				if (ieee80211_set_turbo(dev,
+*						caps & IEEE80211_ATHC_TURBOP))
+*					return -EINVAL;
+*				ieee80211_scan_flush(ic);
+*			}
+*			vap->iv_ath_cap = caps;
+*			ic->ic_athcapsetup(vap->iv_ic, vap->iv_ath_cap);
+*			retv = ENETRESET;
+*		}
+*		break;
+*	case IEEE80211_PARAM_DTIM_PERIOD:
+*		if (vap->iv_opmode != IEEE80211_M_HOSTAP &&
+*		    vap->iv_opmode != IEEE80211_M_IBSS)
+*			return -EINVAL;
+*		if (IEEE80211_DTIM_MIN <= value &&
+*		    value <= IEEE80211_DTIM_MAX) {
+*			vap->iv_dtim_period = value;
+*			retv = ENETRESET;		// requires restart
+*		} else
+*			retv = EINVAL;
+*		break;
+*	case IEEE80211_PARAM_BEACON_INTERVAL:
+*		if (vap->iv_opmode != IEEE80211_M_HOSTAP &&
+*		    vap->iv_opmode != IEEE80211_M_IBSS)
+*			return -EINVAL;
+*		if (IEEE80211_BINTVAL_MIN <= value &&
+*		    value <= IEEE80211_BINTVAL_MAX) {
+*			ic->ic_lintval = value;		// XXX multi-bss
+*			retv = ENETRESET;		// requires restart
+*		} else
+*			retv = EINVAL;
+*		break;
+*	case IEEE80211_PARAM_DOTH:
+*		if (value) {
+*			ic->ic_flags |= IEEE80211_F_DOTH;
+*		}
+*		else
+*			ic->ic_flags &= ~IEEE80211_F_DOTH;
+*		retv = ENETRESET;	// XXX: need something this drastic?
+*		break;
+*	case IEEE80211_PARAM_PWRTARGET:
+*		ic->ic_curchanmaxpwr = value;
+*		break;
+*	case IEEE80211_PARAM_GENREASSOC:
+*		IEEE80211_SEND_MGMT(vap->iv_bss,
+*					IEEE80211_FC0_SUBTYPE_REASSOC_REQ, 0);
+*		break;
+*	case IEEE80211_PARAM_COMPRESSION:
+*		retv = ieee80211_setathcap(vap, IEEE80211_ATHC_COMP, value);
+*		break;
+*    case IEEE80211_PARAM_WMM_AGGRMODE:
+*        retv = ieee80211_setathcap(vap, IEEE80211_ATHC_WME, value);
+*        break;
+*	case IEEE80211_PARAM_FF:
+*		retv = ieee80211_setathcap(vap, IEEE80211_ATHC_FF, value);
+*		break;
+*	case IEEE80211_PARAM_TURBO:
+*		retv = ieee80211_setathcap(vap, IEEE80211_ATHC_TURBOP, value);
+*		if (retv == ENETRESET) {
+*			if(ieee80211_set_turbo(dev,value))
+*					return -EINVAL;
+*			ieee80211_scan_flush(ic);
+*		}
+*		break;
+*	case IEEE80211_PARAM_XR:
+*		retv = ieee80211_setathcap(vap, IEEE80211_ATHC_XR, value);
+*		break;
+*	case IEEE80211_PARAM_BURST:
+*		retv = ieee80211_setathcap(vap, IEEE80211_ATHC_BURST, value);
+*		break;
+*	case IEEE80211_PARAM_AR:
+*		retv = ieee80211_setathcap(vap, IEEE80211_ATHC_AR, value);
+*		break;
+*	case IEEE80211_PARAM_PUREG:
+*		if (value)
+*			vap->iv_flags |= IEEE80211_F_PUREG;
+*		else
+*			vap->iv_flags &= ~IEEE80211_F_PUREG;
+*		// NB: reset only if we're operating on an 11g channel
+*		if (ic->ic_bsschan != IEEE80211_CHAN_ANYC &&
+*		    IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan))
+*			retv = ENETRESET;
+*		break;
+*	case IEEE80211_PARAM_WDS:
+*		if (value)
+*			vap->iv_flags_ext |= IEEE80211_FEXT_WDS;
+*		else
+*			vap->iv_flags_ext &= ~IEEE80211_FEXT_WDS;
+*		break;
+*	case IEEE80211_PARAM_BGSCAN:
+*		if (value) {
+*			if ((vap->iv_caps & IEEE80211_C_BGSCAN) == 0)
+*				return -EINVAL;
+*			vap->iv_flags |= IEEE80211_F_BGSCAN;
+*		} else {
+*			// XXX racey?
+*			vap->iv_flags &= ~IEEE80211_F_BGSCAN;
+*			ieee80211_cancel_scan(vap);	// anything current
+*		}
+*		break;
+*	case IEEE80211_PARAM_BGSCAN_IDLE:
+*		if (value >= IEEE80211_BGSCAN_IDLE_MIN)
+*			vap->iv_bgscanidle = value*HZ/1000;
+*		else
+*			retv = EINVAL;
+*		break;
+*	case IEEE80211_PARAM_BGSCAN_INTERVAL:
+*		if (value >= IEEE80211_BGSCAN_INTVAL_MIN)
+*			vap->iv_bgscanintvl = value*HZ;
+*		else
+*			retv = EINVAL;
+*		break;
+*	case IEEE80211_PARAM_MCAST_RATE:
+*		// units are in KILObits per second
+*		if (value >= 256 && value <= 54000)
+*			vap->iv_mcast_rate = value;
+*		else
+*			retv = EINVAL;
+*		break;
+*	case IEEE80211_PARAM_COVERAGE_CLASS:
+*		if (value >= 0 && value <= IEEE80211_COVERAGE_CLASS_MAX) {
+*			ic->ic_coverageclass = value;
+*			if (IS_UP_AUTO(vap))
+*				ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
+*			retv = 0;
+*		}
+*		else
+*			retv = EINVAL;
+*		break;
+*	case IEEE80211_PARAM_COUNTRY_IE:
+*		if (value)
+*			ic->ic_flags_ext |= IEEE80211_FEXT_COUNTRYIE;
+*		else
+*			ic->ic_flags_ext &= ~IEEE80211_FEXT_COUNTRYIE;
+*		retv = ENETRESET;
+*		break;
+*	case IEEE80211_PARAM_REGCLASS:
+*		if (value)
+*			ic->ic_flags_ext |= IEEE80211_FEXT_REGCLASS;
+*		else
+*			ic->ic_flags_ext &= ~IEEE80211_FEXT_REGCLASS;
+*		retv = ENETRESET;
+*		break;
+*	case IEEE80211_PARAM_SCANVALID:
+*		vap->iv_scanvalid = value*HZ;
+*		break;
+*	case IEEE80211_PARAM_ROAM_RSSI_11A:
+*		vap->iv_roam.rssi11a = value;
+*		break;
+*	case IEEE80211_PARAM_ROAM_RSSI_11B:
+*		vap->iv_roam.rssi11bOnly = value;
+*		break;
+*	case IEEE80211_PARAM_ROAM_RSSI_11G:
+*		vap->iv_roam.rssi11b = value;
+*		break;
+*	case IEEE80211_PARAM_ROAM_RATE_11A:
+*		vap->iv_roam.rate11a = value;
+*		break;
+*	case IEEE80211_PARAM_ROAM_RATE_11B:
+*		vap->iv_roam.rate11bOnly = value;
+*		break;
+*	case IEEE80211_PARAM_ROAM_RATE_11G:
+*		vap->iv_roam.rate11b = value;
+*		break;
+*	case IEEE80211_PARAM_UAPSDINFO:
+*		if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
+*			if (ic->ic_caps & IEEE80211_C_UAPSD) {
+*				if (value)
+*					IEEE80211_VAP_UAPSD_ENABLE(vap);
+*				else
+*					IEEE80211_VAP_UAPSD_DISABLE(vap);
+*				retv = ENETRESET;
+*			}
+*		}
+*		else if (vap->iv_opmode == IEEE80211_M_STA) {
+*			vap->iv_uapsdinfo = value;
+*			IEEE80211_VAP_UAPSD_ENABLE(vap);
+*			retv = ENETRESET;
+*		}
+*		break;
+*	case IEEE80211_PARAM_SLEEP:
+*		// XXX: Forced sleep for testing. Does not actually place the
+*		//      HW in sleep mode yet. this only makes sense for STAs.
+*
+*		if (value) {
+*			// goto sleep
+*			IEEE80211_VAP_GOTOSLEEP(vap);
+*		}
+*		else {
+*			// wakeup
+*			IEEE80211_VAP_WAKEUP(vap);
+*		}
+*		ieee80211_send_nulldata(ieee80211_ref_node(vap->iv_bss));
+*		break;
+*	case IEEE80211_PARAM_QOSNULL:
+*		// Force a QoS Null for testing.
+*		ieee80211_send_qosnulldata(vap->iv_bss, value);
+*		break;
+*	case IEEE80211_PARAM_PSPOLL:
+*		// Force a PS-POLL for testing.
+*		ieee80211_send_pspoll(vap->iv_bss);
+*		break;
+*	case IEEE80211_PARAM_EOSPDROP:
+*		if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
+*			if (value) IEEE80211_VAP_EOSPDROP_ENABLE(vap);
+*			else IEEE80211_VAP_EOSPDROP_DISABLE(vap);
+*		}
+*		break;
+*	case IEEE80211_PARAM_MARKDFS:
+*		if (value)
+*			ic->ic_flags_ext |= IEEE80211_FEXT_MARKDFS;
+*		else
+*			ic->ic_flags_ext &= ~IEEE80211_FEXT_MARKDFS;
+*		break;
+*	case IEEE80211_PARAM_CHANBW:
+*		switch (value) {
+*			case 0:
+*				ic->ic_chanbwflag = 0;
+*				break;
+*			case 1:
+*				ic->ic_chanbwflag = IEEE80211_CHAN_HALF;
+*				break;
+*			case 2:
+*				ic->ic_chanbwflag = IEEE80211_CHAN_QUARTER;
+*				break;
+*			default:
+*				retv = EINVAL;
+*				break;
+*		}
+*		break;
+*	case IEEE80211_PARAM_SHORTPREAMBLE:
+*		if (value) {
+*			ic->ic_caps |= IEEE80211_C_SHPREAMBLE;
+*		} else {
+*			ic->ic_caps &= ~IEEE80211_C_SHPREAMBLE;
+*		}
+*		retv = ENETRESET;
+*		break;
+*	default:
+*		retv = EOPNOTSUPP;
+*		break;
+*	}
+*	// XXX should any of these cause a rescan?
+*	if (retv == ENETRESET)
+*		retv = IS_UP_AUTO(vap) ? ieee80211_open(vap->iv_dev) : 0;
+*	return -retv;
+*}
+*/
 
 int usbdrvwext_setmode(struct net_device *dev, struct iw_request_info *info,
-		   	 void *w, char *extra)
+			void *w, char *extra)
 {
 	return 0;
 }
@@ -1947,158 +1887,138 @@
 int usbdrvwext_getmode(struct net_device *dev, struct iw_request_info *info,
 			void *w, char *extra)
 {
-	//struct usbdrv_private *macp = dev->ml_priv;
+	/* struct usbdrv_private *macp = dev->ml_priv; */
 	struct iw_point *wri = (struct iw_point *)extra;
 	char mode[8];
 
-    strcpy(mode,"11g");
-	return (copy_to_user(wri->pointer, mode, 6) ? -EFAULT : 0);
+	strcpy(mode, "11g");
+	return copy_to_user(wri->pointer, mode, 6) ? -EFAULT : 0;
 }
 
 int zfLnxPrivateIoctl(struct net_device *dev, struct zdap_ioctl* zdreq)
 {
-	//void* regp = macp->regp;
+	/* void* regp = macp->regp; */
 	u16_t cmd;
-	//u32_t temp;
-	u32_t* p;
+	/* u32_t temp; */
+	u32_t *p;
 	u32_t i;
 
 	cmd = zdreq->cmd;
-	switch(cmd)
-	{
+	switch (cmd) {
 	case ZM_IOCTL_REG_READ:
 		zfiDbgReadReg(dev, zdreq->addr);
 		break;
-
 	case ZM_IOCTL_REG_WRITE:
 		zfiDbgWriteReg(dev, zdreq->addr, zdreq->value);
 		break;
-
 	case ZM_IOCTL_MEM_READ:
 		p = (u32_t *) bus_to_virt(zdreq->addr);
-		printk(KERN_DEBUG "usbdrv: read memory addr: 0x%08x value: 0x%08x\n", zdreq->addr, *p);
+		printk(KERN_WARNING
+				"usbdrv: read memory addr: 0x%08x value:"
+				" 0x%08x\n", zdreq->addr, *p);
 		break;
-
 	case ZM_IOCTL_MEM_WRITE:
 		p = (u32_t *) bus_to_virt(zdreq->addr);
 		*p = zdreq->value;
-		printk(KERN_DEBUG "usbdrv: write value: 0x%08x to memory addr: 0x%08x\n", zdreq->value, zdreq->addr);
+		printk(KERN_WARNING
+			"usbdrv : write value : 0x%08x to memory addr :"
+			" 0x%08x\n", zdreq->value, zdreq->addr);
 		break;
-
-	case ZM_IOCTL_TALLY :
+	case ZM_IOCTL_TALLY:
 		zfiWlanShowTally(dev);
 		if (zdreq->addr)
 			zfiWlanResetTally(dev);
 		break;
+	case ZM_IOCTL_TEST:
+		printk(KERN_WARNING
+				"ZM_IOCTL_TEST:len=%d\n", zdreq->addr);
+		/* zfiWlanReadReg(dev, 0x10f400); */
+		/* zfiWlanReadReg(dev, 0x10f404); */
+		printk(KERN_WARNING "IOCTL TEST\n");
+		#if 1
+		/* print packet */
+		for (i = 0; i < zdreq->addr; i++) {
+			if ((i&0x7) == 0)
+				printk(KERN_WARNING "\n");
+			printk(KERN_WARNING "%02X ",
+					(unsigned char)zdreq->data[i]);
+		}
+		printk(KERN_WARNING "\n");
+		#endif
 
-	case ZM_IOCTL_TEST :
-            printk(KERN_DEBUG "ZM_IOCTL_TEST:len=%d\n", zdreq->addr);
-            //zfiWlanReadReg(dev, 0x10f400);
-            //zfiWlanReadReg(dev, 0x10f404);
-            printk("IOCTL TEST\n");
-            #if 1
-            //print packet
-            for (i=0; i<zdreq->addr; i++)
-            {
-                if ((i&0x7) == 0)
-                {
-                    printk("\n");
-                }
-                printk("%02X ", (unsigned char)zdreq->data[i]);
-            }
-            printk("\n");
-            #endif
+		/* For Test?? 1 to 0 by CWYang(-) */
+		#if 0
+			struct sk_buff *s;
 
+			/* Allocate a skb */
+			s = alloc_skb(2000, GFP_ATOMIC);
 
-            #if 0 //For Test?? 1 to 0 by CWYang(-)
-            {
-            struct sk_buff* s;
+			/* Copy data to skb */
+			for (i = 0; i < zdreq->addr; i++)
+				s->data[i] = zdreq->data[i];
+			s->len = zdreq->addr;
 
-            /* Allocate a skb */
-            s = alloc_skb(2000, GFP_ATOMIC);
+			/* Call zfIdlRecv() */
+			zfiRecv80211(dev, s, NULL);
+		#endif
+		break;
+	/************************* ZDCONFIG ***************************/
+	case ZM_IOCTL_FRAG:
+		zfiWlanSetFragThreshold(dev, zdreq->addr);
+		break;
+	case ZM_IOCTL_RTS:
+		zfiWlanSetRtsThreshold(dev, zdreq->addr);
+		break;
+	case ZM_IOCTL_SCAN:
+		zfiWlanScan(dev);
+		break;
+	case ZM_IOCTL_KEY: {
+		u8_t key[29];
+		struct zsKeyInfo keyInfo;
+		u32_t i;
 
-            /* Copy data to skb */
-            for (i=0; i<zdreq->addr; i++)
-            {
-                s->data[i] = zdreq->data[i];
-            }
-            s->len = zdreq->addr;
+		for (i = 0; i < 29; i++)
+			key[i] = 0;
 
-            /* Call zfIdlRecv() */
-            zfiRecv80211(dev, s, NULL);
-            }
-            #endif
+		for (i = 0; i < zdreq->addr; i++)
+			key[i] = zdreq->data[i];
 
-            break;
+		printk(KERN_WARNING
+			"key len=%d, key=%02x%02x%02x%02x%02x...\n",
+			zdreq->addr, key[0], key[1], key[2], key[3], key[4]);
 
+		keyInfo.keyLength = zdreq->addr;
+		keyInfo.keyIndex = 0;
+		keyInfo.flag = 0;
+		keyInfo.key = key;
+		zfiWlanSetKey(dev, keyInfo);
+	}
+		break;
+	case ZM_IOCTL_RATE:
+		zfiWlanSetTxRate(dev, zdreq->addr);
+		break;
+	case ZM_IOCTL_ENCRYPTION_MODE:
+		zfiWlanSetEncryMode(dev, zdreq->addr);
 
-/****************************** ZDCONFIG ******************************/
-        case ZM_IOCTL_FRAG :
-            zfiWlanSetFragThreshold(dev, zdreq->addr);
-            break;
-
-        case ZM_IOCTL_RTS :
-            zfiWlanSetRtsThreshold(dev, zdreq->addr);
-            break;
-
-        case ZM_IOCTL_SCAN :
-            zfiWlanScan(dev);
-            break;
-
-        case ZM_IOCTL_KEY :
-            {
-                u8_t key[29];
-                struct zsKeyInfo keyInfo;
-                u32_t i;
-
-                for (i=0; i<29; i++)
-                {
-                    key[i] = 0;
-                }
-
-                for (i=0; i<zdreq->addr; i++)
-                {
-                    key[i] = zdreq->data[i];
-                }
-
-                printk("key len=%d, key=%02x%02x%02x%02x%02x...\n",
-                        zdreq->addr, key[0], key[1], key[2], key[3], key[4]);
-
-                keyInfo.keyLength = zdreq->addr;
-                keyInfo.keyIndex = 0;
-                keyInfo.flag = 0;
-                keyInfo.key = key;
-                zfiWlanSetKey(dev, keyInfo);
-            }
-            break;
-
-        case ZM_IOCTL_RATE :
-            zfiWlanSetTxRate(dev, zdreq->addr);
-            break;
-
-        case ZM_IOCTL_ENCRYPTION_MODE :
-            zfiWlanSetEncryMode(dev, zdreq->addr);
-
-            zfiWlanDisable(dev, 0);
-            zfiWlanEnable(dev);
-            break;
-        //CWYang(+)
-        case ZM_IOCTL_SIGNAL_STRENGTH :
-            {
-                u8_t buffer[2];
-                zfiWlanQuerySignalInfo(dev, &buffer[0]);
-                printk("Current Signal Strength : %02d\n", buffer[0]);
-            }
-            break;
-        //CWYang(+)
-        case ZM_IOCTL_SIGNAL_QUALITY :
-            {
-                u8_t buffer[2];
-                zfiWlanQuerySignalInfo(dev, &buffer[0]);
-                printk("Current Signal Quality : %02d\n", buffer[1]);
-            }
-            break;
-
+		zfiWlanDisable(dev, 0);
+		zfiWlanEnable(dev);
+		break;
+		/* CWYang(+) */
+	case ZM_IOCTL_SIGNAL_STRENGTH: {
+		u8_t buffer[2];
+		zfiWlanQuerySignalInfo(dev, &buffer[0]);
+		printk(KERN_WARNING
+			"Current Signal Strength : %02d\n", buffer[0]);
+	}
+		break;
+		/* CWYang(+) */
+	case ZM_IOCTL_SIGNAL_QUALITY: {
+		u8_t buffer[2];
+		zfiWlanQuerySignalInfo(dev, &buffer[0]);
+		printk(KERN_WARNING
+			"Current Signal Quality : %02d\n", buffer[1]);
+	}
+		break;
 	case ZM_IOCTL_SET_PIBSS_MODE:
 		if (zdreq->addr == 1)
 			zfiWlanSetWlanMode(dev, ZM_MODE_PSEUDO);
@@ -2107,11 +2027,9 @@
 
 		zfiWlanDisable(dev, 0);
 		zfiWlanEnable(dev);
-
 		break;
-/****************************** ZDCONFIG ******************************/
-
-	default :
+	/********************* ZDCONFIG ***********************/
+	default:
 		printk(KERN_ERR "usbdrv: error command = %x\n", cmd);
 		break;
 	}
@@ -2121,793 +2039,736 @@
 
 int usbdrv_wpa_ioctl(struct net_device *dev, struct athr_wlan_param *zdparm)
 {
-    int ret = 0;
-    u8_t bc_addr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-    u8_t mac_addr[80];
-    struct zsKeyInfo keyInfo;
-    struct usbdrv_private *macp = dev->ml_priv;
-    u16_t vapId = 0;
+	int ret = 0;
+	u8_t bc_addr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+	u8_t mac_addr[80];
+	struct zsKeyInfo keyInfo;
+	struct usbdrv_private *macp = dev->ml_priv;
+	u16_t vapId = 0;
 
-    //zmw_get_wlan_dev(dev);
+	/* zmw_get_wlan_dev(dev); */
 
-    switch(zdparm->cmd)
-    {
-        case ZD_CMD_SET_ENCRYPT_KEY:
+	switch (zdparm->cmd) {
+	case ZD_CMD_SET_ENCRYPT_KEY:
+		/* Set up key information */
+		keyInfo.keyLength = zdparm->u.crypt.key_len;
+		keyInfo.keyIndex = zdparm->u.crypt.idx;
+		if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) {
+			/* AP Mode */
+			keyInfo.flag = ZM_KEY_FLAG_AUTHENTICATOR;
+		} else
+			keyInfo.flag = 0;
+		keyInfo.key = zdparm->u.crypt.key;
+		keyInfo.initIv = zdparm->u.crypt.seq;
+		keyInfo.macAddr = (u16_t *)zdparm->sta_addr;
 
-            /* Set up key information */
-            keyInfo.keyLength = zdparm->u.crypt.key_len;
-            keyInfo.keyIndex = zdparm->u.crypt.idx;
-            if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) // AP Mode
-                keyInfo.flag = ZM_KEY_FLAG_AUTHENTICATOR;
-            else
-                keyInfo.flag = 0;
-            keyInfo.key = zdparm->u.crypt.key;
-            keyInfo.initIv = zdparm->u.crypt.seq;
-            keyInfo.macAddr = (u16_t *)zdparm->sta_addr;
+		/* Identify the MAC address information */
+		if (memcmp(zdparm->sta_addr, bc_addr, sizeof(bc_addr)) == 0)
+			keyInfo.flag |= ZM_KEY_FLAG_GK;
+		else
+			keyInfo.flag |= ZM_KEY_FLAG_PK;
 
-            /* Identify the MAC address information */
-            if (memcmp(zdparm->sta_addr, bc_addr, sizeof(bc_addr)) == 0)
-            {
-                keyInfo.flag |= ZM_KEY_FLAG_GK;
-            }
-            else
-            {
-                keyInfo.flag |= ZM_KEY_FLAG_PK;
-            }
+		if (!strcmp(zdparm->u.crypt.alg, "NONE")) {
+			/* u8_t zero_mac[]={0,0,0,0,0,0}; */
 
-            if (!strcmp(zdparm->u.crypt.alg, "NONE"))
-            {
-                //u8_t zero_mac[]={0,0,0,0,0,0};
+			/* Set key length to zero */
+			keyInfo.keyLength = 0;
 
-                /* Set key length to zero */
-                keyInfo.keyLength = 0;
+			/* del group key */
+			if (zdparm->sta_addr[0] & 1) {
+				/* if (macp->cardSetting.WPAIeLen==0)
+				* { 802.1x dynamic WEP
+				*    mDynKeyMode = 0;
+				*    mKeyFormat[0] = 0;
+				*    mPrivacyInvoked[0]=FALSE;
+				*    mCap[0] &= ~CAP_PRIVACY;
+				*    macp->cardSetting.EncryOnOff[0]=0;
+				* }
+				* mWpaBcKeyLen = mGkInstalled = 0;
+				*/
+			} else {
+				/* if (memcmp(zero_mac,zdparm->sta_addr, 6)==0)
+				* {
+				*     mDynKeyMode=0;
+				*    mKeyFormat[0]=0;
+				*    pSetting->DynKeyMode=0;
+				*    pSetting->EncryMode[0]=0;
+				*    mDynKeyMode=0;
+				* }
+				*/
+			}
 
-                if (zdparm->sta_addr[0] & 1)//del group key
-                {
-                    //if (macp->cardSetting.WPAIeLen==0)
-                    //{//802.1x dynamic WEP
-                    //    mDynKeyMode = 0;
-                    //    mKeyFormat[0] = 0;
-                    //    mPrivacyInvoked[0]=FALSE;
-                    //    mCap[0] &= ~CAP_PRIVACY;
-                    //    macp->cardSetting.EncryOnOff[0]=0;
-                    //}
-                    //mWpaBcKeyLen = mGkInstalled = 0;
-                }
-                else
-                {
-                    //if (memcmp(zero_mac,zdparm->sta_addr, 6)==0)
-                    //{
-                    //    mDynKeyMode=0;
-                    //    mKeyFormat[0]=0;
-                    //    pSetting->DynKeyMode=0;
-                    //    pSetting->EncryMode[0]=0;
-                    //    mDynKeyMode=0;
-                    //}
-                }
+			printk(KERN_ERR "Set Encryption Type NONE\n");
+			return ret;
+		} else if (!strcmp(zdparm->u.crypt.alg, "TKIP")) {
+			zfiWlanSetEncryMode(dev, ZM_TKIP);
+			/* //Linux Supplicant will inverse Tx/Rx key
+			* //So we inverse it back, CWYang(+)
+			* zfMemoryCopy(&temp[0], &keyInfo.key[16], 8);
+			* zfMemoryCopy(&keyInfo.key[16], keyInfo.key[24], 8);
+			* zfMemoryCopy(&keyInfo.key[24], &temp[0], 8);
+			* u8_t temp;
+			* int k;
+			* for (k = 0; k < 8; k++)
+			* {
+			*     temp = keyInfo.key[16 + k];
+			*     keyInfo.key[16 + k] = keyInfo.key[24 + k];
+			*     keyInfo.key[24 + k] = temp;
+			* }
+			* CamEncryType = ZM_TKIP;
+			* if (idx == 0)
+			* {   // Pairwise key
+			*     mKeyFormat[0] = CamEncryType;
+			*     mDynKeyMode = pSetting->DynKeyMode = DYN_KEY_TKIP;
+			* }
+			*/
+		} else if (!strcmp(zdparm->u.crypt.alg, "CCMP")) {
+			zfiWlanSetEncryMode(dev, ZM_AES);
+			/* CamEncryType = ZM_AES;
+			* if (idx == 0)
+			* {  // Pairwise key
+			*    mKeyFormat[0] = CamEncryType;
+			*    mDynKeyMode = pSetting->DynKeyMode = DYN_KEY_AES;
+			* }
+			*/
+		} else if (!strcmp(zdparm->u.crypt.alg, "WEP")) {
+			if (keyInfo.keyLength == 5) {
+				/* WEP 64 */
+				zfiWlanSetEncryMode(dev, ZM_WEP64);
+				/* CamEncryType = ZM_WEP64; */
+				/* tmpDynKeyMode=DYN_KEY_WEP64; */
+			} else if (keyInfo.keyLength == 13) {
+				/* keylen=13, WEP 128 */
+				zfiWlanSetEncryMode(dev, ZM_WEP128);
+				/* CamEncryType = ZM_WEP128; */
+				/* tmpDynKeyMode=DYN_KEY_WEP128; */
+			} else {
+				zfiWlanSetEncryMode(dev, ZM_WEP256);
+			}
 
-                printk(KERN_ERR "Set Encryption Type NONE\n");
-                return ret;
-            }
-            else if (!strcmp(zdparm->u.crypt.alg, "TKIP"))
-            {
-                zfiWlanSetEncryMode(dev, ZM_TKIP);
-                //Linux Supplicant will inverse Tx/Rx key
-                //So we inverse it back //CWYang(+)
-                //zfMemoryCopy(&temp[0], &keyInfo.key[16], 8);
-                //zfMemoryCopy(&keyInfo.key[16], keyInfo.key[24], 8);
-                //zfMemoryCopy(&keyInfo.key[24], &temp[0], 8);
-                //u8_t temp;
-                //int k;
-                //for (k = 0; k < 8; k++)
-                //{
-                //    temp = keyInfo.key[16 + k];
-                //    keyInfo.key[16 + k] = keyInfo.key[24 + k];
-                //    keyInfo.key[24 + k] = temp;
-                //}
-                //CamEncryType = ZM_TKIP;
-                ////if (idx == 0)
-                //{// Pairwise key
-                //    mKeyFormat[0] = CamEncryType;
-                //    mDynKeyMode = pSetting->DynKeyMode = DYN_KEY_TKIP;
-                //}
-            }
-            else if (!strcmp(zdparm->u.crypt.alg, "CCMP"))
-            {
-                zfiWlanSetEncryMode(dev, ZM_AES);
-                //CamEncryType = ZM_AES;
-                ////if (idx == 0)
-                //{// Pairwise key
-                //    mKeyFormat[0] = CamEncryType;
-                //    mDynKeyMode = pSetting->DynKeyMode = DYN_KEY_AES;
-                //}
-            }
-            else if (!strcmp(zdparm->u.crypt.alg, "WEP"))
-            {
-                if (keyInfo.keyLength == 5)
-                { // WEP 64
-                    zfiWlanSetEncryMode(dev, ZM_WEP64);
-                //    CamEncryType = ZM_WEP64;
-                //    tmpDynKeyMode=DYN_KEY_WEP64;
-                }
-                else if (keyInfo.keyLength == 13)
-                {//keylen=13, WEP 128
-                    zfiWlanSetEncryMode(dev, ZM_WEP128);
-                //    CamEncryType = ZM_WEP128;
-                //    tmpDynKeyMode=DYN_KEY_WEP128;
-                }
-                else
-                {
-                    zfiWlanSetEncryMode(dev, ZM_WEP256);
-                }
+	/* For Dynamic WEP key (Non-WPA Radius), the key ID range: 0-3
+	* In WPA/RSN mode, the key ID range: 1-3, usually, a broadcast key.
+	* For WEP key setting: we set mDynKeyMode and mKeyFormat in following
+	* case:
+	*   1. For 802.1x dynamically generated WEP key method.
+	*   2. For WPA/RSN mode, but key id == 0.
+	*	(But this is an impossible case)
+	* So, only check case 1.
+	* if (macp->cardSetting.WPAIeLen==0)
+	* {
+	*    mKeyFormat[0] = CamEncryType;
+	*    mDynKeyMode = pSetting->DynKeyMode = tmpDynKeyMode;
+	*    mPrivacyInvoked[0]=TRUE;
+	*    mCap[0] |= CAP_PRIVACY;
+	*    macp->cardSetting.EncryOnOff[0]=1;
+	* }
+	*/
+		}
 
-                // For Dynamic WEP key (Non-WPA Radius), the key ID range: 0-3
-                // In WPA/RSN mode, the key ID range: 1-3, usually, a broadcast key.
-                // For WEP key setting: we set mDynKeyMode and mKeyFormat in following case:
-                //   1. For 802.1x dynamically generated WEP key method.
-                //   2. For WPA/RSN mode, but key id == 0. (But this is an impossible case)
-                // So, only check case 1.
-                //if (macp->cardSetting.WPAIeLen==0)
-                //{
-                //    mKeyFormat[0] = CamEncryType;
-                //    mDynKeyMode = pSetting->DynKeyMode = tmpDynKeyMode;
-                //    mPrivacyInvoked[0]=TRUE;
-                //    mCap[0] |= CAP_PRIVACY;
-                //    macp->cardSetting.EncryOnOff[0]=1;
-                //}
-            }
+		/* DUMP key context */
+		/* #ifdef WPA_DEBUG */
+		if (keyInfo.keyLength > 0) {
+			int ii;
+			printk(KERN_WARNING
+						"Otus: Key Context:\n");
+			for (ii = 0; ii < keyInfo.keyLength; ) {
+				printk(KERN_WARNING
+						"0x%02x ", keyInfo.key[ii]);
+				if ((++ii % 16) == 0)
+					printk(KERN_WARNING "\n");
+			}
+			printk(KERN_WARNING "\n");
+		}
+		/* #endif */
 
-            /* DUMP key context */
-//#ifdef WPA_DEBUG
-            if (keyInfo.keyLength > 0)
-            {
-                int ii;
-                printk("Otus: Key Context:\n");
-                for(ii = 0; ii < keyInfo.keyLength;)
-                {
-                    printk("0x%02x ", keyInfo.key[ii]);
-                    if((++ii % 16) == 0)
-                        printk("\n");
-                }
-                printk("\n");
-            }
-//#endif
+		/* Set encrypt mode */
+		/* zfiWlanSetEncryMode(dev, CamEncryType); */
+		vapId = zfLnxGetVapId(dev);
+		if (vapId == 0xffff)
+			keyInfo.vapId = 0;
+		else
+			keyInfo.vapId = vapId + 1;
+		keyInfo.vapAddr[0] = keyInfo.macAddr[0];
+		keyInfo.vapAddr[1] = keyInfo.macAddr[1];
+		keyInfo.vapAddr[2] = keyInfo.macAddr[2];
 
-            /* Set encrypt mode */
-            //zfiWlanSetEncryMode(dev, CamEncryType);
-            vapId = zfLnxGetVapId(dev);
-            if (vapId == 0xffff)
-                keyInfo.vapId = 0;
-            else
-                keyInfo.vapId = vapId + 1;
-            keyInfo.vapAddr[0] = keyInfo.macAddr[0];
-            keyInfo.vapAddr[1] = keyInfo.macAddr[1];
-            keyInfo.vapAddr[2] = keyInfo.macAddr[2];
+		zfiWlanSetKey(dev, keyInfo);
 
-            zfiWlanSetKey(dev, keyInfo);
+		/* zfiWlanDisable(dev); */
+		/* zfiWlanEnable(dev); */
+		break;
+	case ZD_CMD_SET_MLME:
+		printk(KERN_ERR "usbdrv_wpa_ioctl: ZD_CMD_SET_MLME\n");
 
-            //zfiWlanDisable(dev);
-            //zfiWlanEnable(dev);
-            break;
+		/* Translate STA's address */
+		sprintf(mac_addr, "%02x:%02x:%02x:%02x:%02x:%02x",
+			zdparm->sta_addr[0], zdparm->sta_addr[1],
+			zdparm->sta_addr[2], zdparm->sta_addr[3],
+			zdparm->sta_addr[4], zdparm->sta_addr[5]);
 
-        case ZD_CMD_SET_MLME:
-            printk(KERN_ERR "usbdrv_wpa_ioctl: ZD_CMD_SET_MLME\n");
+		switch (zdparm->u.mlme.cmd) {
+		case MLME_STA_DEAUTH:
+			printk(KERN_WARNING
+				" -------Call zfiWlanDeauth, reason:%d\n",
+				zdparm->u.mlme.reason_code);
+			if (zfiWlanDeauth(dev, (u16_t *) zdparm->sta_addr,
+				zdparm->u.mlme.reason_code) != 0)
+				printk(KERN_ERR "Can't deauthencate STA: %s\n",
+					mac_addr);
+			else
+				printk(KERN_ERR "Deauthenticate STA: %s"
+					"with reason code: %d\n",
+					mac_addr, zdparm->u.mlme.reason_code);
+			break;
+		case MLME_STA_DISASSOC:
+			printk(KERN_WARNING
+				" -------Call zfiWlanDeauth, reason:%d\n",
+				zdparm->u.mlme.reason_code);
+			if (zfiWlanDeauth(dev, (u16_t *) zdparm->sta_addr,
+				zdparm->u.mlme.reason_code) != 0)
+				printk(KERN_ERR "Can't disassociate STA: %s\n",
+					mac_addr);
+			else
+				printk(KERN_ERR "Disassociate STA: %s"
+					"with reason code: %d\n",
+					mac_addr, zdparm->u.mlme.reason_code);
+			break;
+		default:
+			printk(KERN_ERR "MLME command: 0x%04x not support\n",
+				zdparm->u.mlme.cmd);
+			break;
+		}
 
-            /* Translate STA's address */
-            sprintf(mac_addr, "%02x:%02x:%02x:%02x:%02x:%02x", zdparm->sta_addr[0], zdparm->sta_addr[1],
-                zdparm->sta_addr[2], zdparm->sta_addr[3], zdparm->sta_addr[4], zdparm->sta_addr[5]);
+		break;
+	case ZD_CMD_SCAN_REQ:
+		printk(KERN_ERR "usbdrv_wpa_ioctl: ZD_CMD_SCAN_REQ\n");
+		break;
+	case ZD_CMD_SET_GENERIC_ELEMENT:
+		printk(KERN_ERR "usbdrv_wpa_ioctl:"
+					" ZD_CMD_SET_GENERIC_ELEMENT\n");
 
-            switch(zdparm->u.mlme.cmd)
-            {
-                case MLME_STA_DEAUTH:
-                    printk(" -------Call zfiWlanDeauth, reason:%d\n",zdparm->u.mlme.reason_code);
-                    if(zfiWlanDeauth(dev, (u16_t*) zdparm->sta_addr, zdparm->u.mlme.reason_code) != 0)
-                        printk(KERN_ERR "Can't deauthencate STA: %s\n", mac_addr);
-                    else
-                        printk(KERN_ERR "Deauthenticate STA: %s with reason code: %d\n", mac_addr, zdparm->u.mlme.reason_code);
-                    break;
+		/* Copy the WPA IE
+		* zm_msg1_mm(ZM_LV_0, "CWY - wpaie Length : ",
+		* zdparm->u.generic_elem.len);
+		*/
+		printk(KERN_ERR "wpaie Length : % d\n",
+						zdparm->u.generic_elem.len);
+		if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) {
+			/* AP Mode */
+			zfiWlanSetWpaIe(dev, zdparm->u.generic_elem.data,
+					zdparm->u.generic_elem.len);
+		} else {
+			macp->supLen = zdparm->u.generic_elem.len;
+			memcpy(macp->supIe, zdparm->u.generic_elem.data,
+				zdparm->u.generic_elem.len);
+		}
+		zfiWlanSetWpaSupport(dev, 1);
+		/* zfiWlanSetWpaIe(dev, zdparm->u.generic_elem.data,
+		* zdparm->u.generic_elem.len);
+		*/
+		int ii;
+		u8_t len = zdparm->u.generic_elem.len;
+		u8_t *wpaie = (u8_t *)zdparm->u.generic_elem.data;
 
-                case MLME_STA_DISASSOC:
-                    printk(" -------Call zfiWlanDeauth, reason:%d\n",zdparm->u.mlme.reason_code);
-                    if(zfiWlanDeauth(dev, (u16_t*) zdparm->sta_addr, zdparm->u.mlme.reason_code) != 0)
-                        printk(KERN_ERR "Can't disassociate STA: %s\n", mac_addr);
-                    else
-                        printk(KERN_ERR "Disassociate STA: %s with reason code: %d\n", mac_addr, zdparm->u.mlme.reason_code);
-                    break;
+		printk(KERN_ERR "wd->ap.wpaLen : % d\n", len);
 
-                default:
-                    printk(KERN_ERR "MLME command: 0x%04x not support\n", zdparm->u.mlme.cmd);
-                    break;
-            }
+		/* DUMP WPA IE */
+		for(ii = 0; ii < len;) {
+			printk(KERN_ERR "0x%02x ", wpaie[ii]);
 
-            break;
+			if((++ii % 16) == 0)
+				printk(KERN_ERR "\n");
+		}
+		printk(KERN_ERR "\n");
 
-        case ZD_CMD_SCAN_REQ:
-            printk(KERN_ERR "usbdrv_wpa_ioctl: ZD_CMD_SCAN_REQ\n");
-            break;
+		/* #ifdef ZM_HOSTAPD_SUPPORT
+		* if (wd->wlanMode == ZM_MODE_AP)
+		* {// Update Beacon FIFO in the next TBTT.
+		*     memcpy(&mWPAIe, pSetting->WPAIe, pSetting->WPAIeLen);
+		*     printk(KERN_ERR "Copy WPA IE into mWPAIe\n");
+		* }
+		* #endif
+		*/
+		break;
 
-        case ZD_CMD_SET_GENERIC_ELEMENT:
-            printk(KERN_ERR "usbdrv_wpa_ioctl: ZD_CMD_SET_GENERIC_ELEMENT\n");
+	/* #ifdef ZM_HOSTAPD_SUPPORT */
+	case ZD_CMD_GET_TSC:
+		printk(KERN_ERR "usbdrv_wpa_ioctl : ZD_CMD_GET_TSC\n");
+		break;
+	/* #endif */
 
-            /* Copy the WPA IE */
-            //zm_msg1_mm(ZM_LV_0, "CWY - wpaie Length : ", zdparm->u.generic_elem.len);
-            printk(KERN_ERR "wpaie Length : %d\n", zdparm->u.generic_elem.len);
-            if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) // AP Mode
-            {
-                zfiWlanSetWpaIe(dev, zdparm->u.generic_elem.data, zdparm->u.generic_elem.len);
-            }
-            else
-            {
-                macp->supLen = zdparm->u.generic_elem.len;
-                memcpy(macp->supIe, zdparm->u.generic_elem.data, zdparm->u.generic_elem.len);
-            }
-            zfiWlanSetWpaSupport(dev, 1);
-            //zfiWlanSetWpaIe(dev, zdparm->u.generic_elem.data, zdparm->u.generic_elem.len);
-            {
-                int ii;
-                u8_t len = zdparm->u.generic_elem.len;
-                u8_t *wpaie = (u8_t *)zdparm->u.generic_elem.data;
+	default:
+		printk(KERN_ERR "usbdrv_wpa_ioctl default : 0x%04x\n",
+			zdparm->cmd);
+		ret = -EINVAL;
+		break;
+	}
 
-                printk(KERN_ERR "wd->ap.wpaLen: %d\n", len);
-
-                /* DUMP WPA IE */
-                for(ii = 0; ii < len;)
-                {
-                    printk(KERN_ERR "0x%02x ", wpaie[ii]);
-
-                    if((++ii % 16) == 0)
-                        printk(KERN_ERR "\n");
-                }
-                printk(KERN_ERR "\n");
-            }
-
-//            #ifdef ZM_HOSTAPD_SUPPORT
-            //if (wd->wlanMode == ZM_MODE_AP)
-            //{// Update Beacon FIFO in the next TBTT.
-            //    memcpy(&mWPAIe, pSetting->WPAIe, pSetting->WPAIeLen);
-            //    printk(KERN_ERR "Copy WPA IE into mWPAIe\n");
-            //}
-//            #endif
-            break;
-
-//        #ifdef ZM_HOSTAPD_SUPPORT
-        case ZD_CMD_GET_TSC:
-            printk(KERN_ERR "usbdrv_wpa_ioctl: ZD_CMD_GET_TSC\n");
-            break;
-//        #endif
-
-        default:
-            printk(KERN_ERR "usbdrv_wpa_ioctl default: 0x%04x\n", zdparm->cmd);
-            ret = -EINVAL;
-            break;
-    }
-
-    return ret;
+	return ret;
 }
 
 #ifdef ZM_ENABLE_CENC
 int usbdrv_cenc_ioctl(struct net_device *dev, struct zydas_cenc_param *zdparm)
 {
-    //struct usbdrv_private *macp = dev->ml_priv;
-    struct zsKeyInfo keyInfo;
-    u16_t apId;
-    u8_t bc_addr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-    int ret = 0;
-    int ii;
+	/* struct usbdrv_private *macp = dev->ml_priv; */
+	struct zsKeyInfo keyInfo;
+	u16_t apId;
+	u8_t bc_addr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+	int ret = 0;
+	int ii;
 
-    /* Get the AP Id */
-    apId = zfLnxGetVapId(dev);
+	/* Get the AP Id */
+	apId = zfLnxGetVapId(dev);
 
-    if (apId == 0xffff)
-    {
-        apId = 0;
-    }
-    else
-    {
-        apId = apId+1;
-    }
+	if (apId == 0xffff) {
+		apId = 0;
+	} else {
+		apId = apId + 1;
+	}
 
-    switch (zdparm->cmd)
-    {
-        case ZM_CMD_CENC_SETCENC:
-            printk(KERN_ERR "ZM_CMD_CENC_SETCENC\n");
-            printk(KERN_ERR "length: %d\n", zdparm->len);
-            printk(KERN_ERR "policy: %d\n", zdparm->u.info.cenc_policy);
-            break;
-        case ZM_CMD_CENC_SETKEY:
-            //ret = wai_ioctl_setkey(vap, ioctl_msg);
-            printk(KERN_ERR "ZM_CMD_CENC_SETKEY\n");
+	switch (zdparm->cmd) {
+	case ZM_CMD_CENC_SETCENC:
+		printk(KERN_ERR "ZM_CMD_CENC_SETCENC\n");
+		printk(KERN_ERR "length : % d\n", zdparm->len);
+		printk(KERN_ERR "policy : % d\n", zdparm->u.info.cenc_policy);
+		break;
+	case ZM_CMD_CENC_SETKEY:
+		/* ret = wai_ioctl_setkey(vap, ioctl_msg); */
+		printk(KERN_ERR "ZM_CMD_CENC_SETKEY\n");
 
-            printk(KERN_ERR "MAC address= ");
-            for(ii = 0; ii < 6; ii++)
-            {
-                printk(KERN_ERR "0x%02x ", zdparm->u.crypt.sta_addr[ii]);
-            }
-            printk(KERN_ERR "\n");
+		printk(KERN_ERR "MAC address = ");
+		for (ii = 0; ii < 6; ii++) {
+			printk(KERN_ERR "0x%02x ",
+				zdparm->u.crypt.sta_addr[ii]);
+		}
+		printk(KERN_ERR "\n");
 
-            printk(KERN_ERR "Key Index: %d\n", zdparm->u.crypt.keyid);
-            printk(KERN_ERR "Encryption key= ");
-            for(ii = 0; ii < 16; ii++)
-            {
-                printk(KERN_ERR "0x%02x ", zdparm->u.crypt.key[ii]);
-            }
-            printk(KERN_ERR "\n");
+		printk(KERN_ERR "Key Index : % d\n", zdparm->u.crypt.keyid);
+		printk(KERN_ERR "Encryption key = ");
+		for (ii = 0; ii < 16; ii++) {
+			printk(KERN_ERR "0x%02x ", zdparm->u.crypt.key[ii]);
+		}
+		printk(KERN_ERR "\n");
 
-            printk(KERN_ERR "MIC key= ");
-            for(ii = 16; ii < ZM_CENC_KEY_SIZE; ii++)
-            {
-                printk(KERN_ERR "0x%02x ", zdparm->u.crypt.key[ii]);
-            }
-            printk(KERN_ERR "\n");
+		printk(KERN_ERR "MIC key = ");
+		for(ii = 16; ii < ZM_CENC_KEY_SIZE; ii++) {
+			printk(KERN_ERR "0x%02x ", zdparm->u.crypt.key[ii]);
+		}
+		printk(KERN_ERR "\n");
 
-            /* Set up key information */
-            keyInfo.keyLength = ZM_CENC_KEY_SIZE;
-            keyInfo.keyIndex = zdparm->u.crypt.keyid;
-            keyInfo.flag = ZM_KEY_FLAG_AUTHENTICATOR | ZM_KEY_FLAG_CENC;
-            keyInfo.key = zdparm->u.crypt.key;
-            keyInfo.macAddr = (u16_t *)zdparm->u.crypt.sta_addr;
+		/* Set up key information */
+		keyInfo.keyLength = ZM_CENC_KEY_SIZE;
+		keyInfo.keyIndex = zdparm->u.crypt.keyid;
+		keyInfo.flag = ZM_KEY_FLAG_AUTHENTICATOR | ZM_KEY_FLAG_CENC;
+		keyInfo.key = zdparm->u.crypt.key;
+		keyInfo.macAddr = (u16_t *)zdparm->u.crypt.sta_addr;
 
-            /* Identify the MAC address information */
-            if (memcmp(zdparm->u.crypt.sta_addr, bc_addr, sizeof(bc_addr)) == 0)
-            {
-                keyInfo.flag |= ZM_KEY_FLAG_GK;
-                keyInfo.vapId = apId;
-                memcpy(keyInfo.vapAddr, dev->dev_addr, ETH_ALEN);
-            }
-            else
-            {
-                keyInfo.flag |= ZM_KEY_FLAG_PK;
-            }
+		/* Identify the MAC address information */
+		if (memcmp(zdparm->u.crypt.sta_addr, bc_addr,
+				sizeof(bc_addr)) == 0) {
+			keyInfo.flag |= ZM_KEY_FLAG_GK;
+			keyInfo.vapId = apId;
+			memcpy(keyInfo.vapAddr, dev->dev_addr, ETH_ALEN);
+		} else {
+			keyInfo.flag |= ZM_KEY_FLAG_PK;
+		}
 
-            zfiWlanSetKey(dev, keyInfo);
+		zfiWlanSetKey(dev, keyInfo);
 
-            break;
-        case ZM_CMD_CENC_REKEY:
-            //ret = wai_ioctl_rekey(vap, ioctl_msg);
-            printk(KERN_ERR "ZM_CMD_CENC_REKEY\n");
-            break;
-        default:
-            ret = -EOPNOTSUPP;
-            break;
+		break;
+	case ZM_CMD_CENC_REKEY:
+		/* ret = wai_ioctl_rekey(vap, ioctl_msg); */
+		printk(KERN_ERR "ZM_CMD_CENC_REKEY\n");
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+		break;
+	}
 
-    }
+	/* if (retv == ENETRESET) */
+	/* retv = IS_UP_AUTO(vap) ? ieee80211_open(vap->iv_dev) : 0; */
 
-    //if (retv == ENETRESET)
-    //    retv = IS_UP_AUTO(vap) ? ieee80211_open(vap->iv_dev) : 0;
-
-    return ret;
+	return ret;
 }
-#endif //ZM_ENABLE_CENC
-/////////////////////////////////////////
+#endif /* ZM_ENABLE_CENC */
+
 int usbdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
-//    struct usbdrv_private *macp;
-//    void *regp;
-    struct zdap_ioctl zdreq;
-    struct iwreq *wrq = (struct iwreq *)ifr;
-    struct athr_wlan_param zdparm;
-    struct usbdrv_private *macp = dev->ml_priv;
+	/* struct usbdrv_private *macp; */
+	/* void *regp; */
+	struct zdap_ioctl zdreq;
+	struct iwreq *wrq = (struct iwreq *)ifr;
+	struct athr_wlan_param zdparm;
+	struct usbdrv_private *macp = dev->ml_priv;
 
-    int err = 0;
-    int changed = 0;
+	int err = 0;
+	int changed = 0;
 
-//    regp = macp->regp;
+	/* regp = macp->regp; */
 
-    if(!netif_running(dev))
-        return -EINVAL;
+	if (!netif_running(dev))
+		return -EINVAL;
 
-    switch (cmd)
-    {
-            case SIOCGIWNAME:
-            strcpy(wrq->u.name, "IEEE 802.11-DS");
-            break;
+	switch (cmd) {
+	case SIOCGIWNAME:
+		strcpy(wrq->u.name, "IEEE 802.11-DS");
+		break;
+	case SIOCGIWAP:
+		err = usbdrvwext_giwap(dev, NULL, &wrq->u.ap_addr, NULL);
+		break;
+	case SIOCSIWAP:
+		err = usbdrvwext_siwap(dev, NULL, &wrq->u.ap_addr, NULL);
+		break;
+	case SIOCGIWMODE:
+		err = usbdrvwext_giwmode(dev, NULL, &wrq->u.mode, NULL);
+		break;
+	case SIOCSIWESSID:
+		printk(KERN_ERR "CWY - usbdrvwext_siwessid\n");
+		/* err = usbdrv_ioctl_setessid(dev, &wrq->u.essid); */
+		err = usbdrvwext_siwessid(dev, NULL, &wrq->u.essid, NULL);
 
-        case SIOCGIWAP:
-            err = usbdrvwext_giwap(dev, NULL, &wrq->u.ap_addr, NULL);
-            break;
+		if (!err)
+			changed = 1;
+		break;
+	case SIOCGIWESSID:
+		err = usbdrvwext_giwessid(dev, NULL, &wrq->u.essid, NULL);
+		break;
+	case SIOCSIWRTS:
+		err = usbdrv_ioctl_setrts(dev, &wrq->u.rts);
+		if (! err)
+			changed = 1;
+		break;
+	/* set_auth */
+	case SIOCIWFIRSTPRIV + 0x2: {
+		/* printk("CWY - SIOCIWFIRSTPRIV + 0x2(set_auth)\n"); */
+		if (!capable(CAP_NET_ADMIN)) {
+			err = -EPERM;
+			break;
+		}
+		int val = *((int *) wrq->u.name);
+		if ((val < 0) || (val > 2)) {
+			err = -EINVAL;
+			break;
+		} else {
+			zfiWlanSetAuthenticationMode(dev, val);
 
+			if (macp->DeviceOpened == 1) {
+				zfiWlanDisable(dev, 0);
+				zfiWlanEnable(dev);
+			}
 
-        case SIOCSIWAP:
-            err = usbdrvwext_siwap(dev, NULL, &wrq->u.ap_addr, NULL);
-            break;
+			err = 0;
+			changed = 1;
+		}
+	}
+		break;
+	/* get_auth */
+	case SIOCIWFIRSTPRIV + 0x3: {
+		int AuthMode = ZM_AUTH_MODE_OPEN;
 
+		/* printk("CWY - SIOCIWFIRSTPRIV + 0x3(get_auth)\n"); */
 
-        case SIOCGIWMODE:
-            err = usbdrvwext_giwmode(dev, NULL, &wrq->u.mode, NULL);
-            break;
+		if (wrq->u.data.pointer) {
+			wrq->u.data.flags = 1;
 
+			AuthMode = zfiWlanQueryAuthenticationMode(dev, 0);
+			if (AuthMode == ZM_AUTH_MODE_OPEN) {
+				wrq->u.data.length = 12;
 
-        case SIOCSIWESSID:
-            printk(KERN_ERR "CWY - usbdrvwext_siwessid\n");
-            //err = usbdrv_ioctl_setessid(dev, &wrq->u.essid);
-            err = usbdrvwext_siwessid(dev, NULL, &wrq->u.essid, NULL);
+				if (copy_to_user(wrq->u.data.pointer,
+					"open system", 12)) {
+						return -EFAULT;
+				}
+			} else if (AuthMode == ZM_AUTH_MODE_SHARED_KEY)	{
+				wrq->u.data.length = 11;
 
-            if (! err)
-                changed = 1;
-            break;
+				if (copy_to_user(wrq->u.data.pointer,
+					"shared key", 11)) {
+							return -EFAULT;
+				}
+			} else if (AuthMode == ZM_AUTH_MODE_AUTO) {
+				wrq->u.data.length = 10;
 
+				if (copy_to_user(wrq->u.data.pointer,
+					"auto mode", 10)) {
+							return -EFAULT;
+				}
+			} else {
+				return -EFAULT;
+			}
+		}
+	}
+		break;
+	/* debug command */
+	case ZDAPIOCTL:
+		if (copy_from_user(&zdreq, ifr->ifr_data, sizeof(zdreq))) {
+			printk(KERN_ERR "usbdrv : copy_from_user error\n");
+			return -EFAULT;
+		}
 
-        case SIOCGIWESSID:
-            err = usbdrvwext_giwessid(dev, NULL, &wrq->u.essid, NULL);
-            break;
+		/* printk(KERN_WARNING
+		* "usbdrv : cmd = % 2x, reg = 0x%04lx,
+		*value = 0x%08lx\n",
+		* zdreq.cmd, zdreq.addr, zdreq.value);
+		*/
+		zfLnxPrivateIoctl(dev, &zdreq);
 
+		err = 0;
+		break;
+	case ZD_IOCTL_WPA:
+		if (copy_from_user(&zdparm, ifr->ifr_data,
+			sizeof(struct athr_wlan_param))) {
+			printk(KERN_ERR "usbdrv : copy_from_user error\n");
+			return -EFAULT;
+		}
 
-        case SIOCSIWRTS:
+		usbdrv_wpa_ioctl(dev, &zdparm);
+		err = 0;
+		break;
+	case ZD_IOCTL_PARAM: {
+		int *p;
+		int op;
+		int arg;
 
-            err = usbdrv_ioctl_setrts(dev, &wrq->u.rts);
-            if (! err)
-                changed = 1;
-            break;
+		/* Point to the name field and retrieve the
+		* op and arg elements.
+		*/
+		p = (int *)wrq->u.name;
+		op = *p++;
+		arg = *p;
 
+		if (op == ZD_PARAM_ROAMING) {
+			printk(KERN_ERR
+			"*************ZD_PARAM_ROAMING : % d\n", arg);
+			/* macp->cardSetting.ap_scan=(U8)arg; */
+		}
+		if (op == ZD_PARAM_PRIVACY) {
+			printk(KERN_ERR "ZD_IOCTL_PRIVACY : ");
 
-		case SIOCIWFIRSTPRIV + 0x2: /* set_auth */
-		{
-			//printk("CWY - SIOCIWFIRSTPRIV + 0x2 (set_auth)\n");
-			if (! capable(CAP_NET_ADMIN))
-			{
-				err = -EPERM;
+			/* Turn on the privacy invoke flag */
+			if (arg) {
+				/* mCap[0] |= CAP_PRIVACY; */
+				/* macp->cardSetting.EncryOnOff[0] = 1; */
+				printk(KERN_ERR "enable\n");
+
+			} else {
+				/* mCap[0] &= ~CAP_PRIVACY; */
+				/* macp->cardSetting.EncryOnOff[0] = 0; */
+				printk(KERN_ERR "disable\n");
+			}
+			/* changed=1; */
+		}
+		if (op == ZD_PARAM_WPA) {
+
+		printk(KERN_ERR "ZD_PARAM_WPA : ");
+
+		if (arg) {
+			printk(KERN_ERR "enable\n");
+
+			if (zfiWlanQueryWlanMode(dev) != ZM_MODE_AP) {
+				printk(KERN_ERR "Station Mode\n");
+				/* zfiWlanQueryWpaIe(dev, (u8_t *)
+					&wpaIe, &wpalen); */
+				/* printk("wpaIe : % 2x, % 2x, % 2x\n",
+					wpaIe[21], wpaIe[22], wpaIe[23]); */
+				/* printk("rsnIe : % 2x, % 2x, % 2x\n",
+					wpaIe[17], wpaIe[18], wpaIe[19]); */
+				if ((macp->supIe[21] == 0x50) &&
+					(macp->supIe[22] == 0xf2) &&
+					(macp->supIe[23] == 0x2)) {
+					printk(KERN_ERR
+				"wd->sta.authMode = ZM_AUTH_MODE_WPAPSK\n");
+				/* wd->sta.authMode = ZM_AUTH_MODE_WPAPSK; */
+				/* wd->ws.authMode = ZM_AUTH_MODE_WPAPSK; */
+				zfiWlanSetAuthenticationMode(dev,
+							ZM_AUTH_MODE_WPAPSK);
+				} else if ((macp->supIe[21] == 0x50) &&
+					(macp->supIe[22] == 0xf2) &&
+					(macp->supIe[23] == 0x1)) {
+					printk(KERN_ERR
+				"wd->sta.authMode = ZM_AUTH_MODE_WPA\n");
+				/* wd->sta.authMode = ZM_AUTH_MODE_WPA; */
+				/* wd->ws.authMode = ZM_AUTH_MODE_WPA; */
+				zfiWlanSetAuthenticationMode(dev,
+							ZM_AUTH_MODE_WPA);
+					} else if ((macp->supIe[17] == 0xf) &&
+						(macp->supIe[18] == 0xac) &&
+						(macp->supIe[19] == 0x2))
+					{
+						printk(KERN_ERR
+				"wd->sta.authMode = ZM_AUTH_MODE_WPA2PSK\n");
+				/* wd->sta.authMode = ZM_AUTH_MODE_WPA2PSK; */
+				/* wd->ws.authMode = ZM_AUTH_MODE_WPA2PSK; */
+				zfiWlanSetAuthenticationMode(dev,
+				ZM_AUTH_MODE_WPA2PSK);
+			} else if ((macp->supIe[17] == 0xf) &&
+				(macp->supIe[18] == 0xac) &&
+				(macp->supIe[19] == 0x1))
+				{
+					printk(KERN_ERR
+				"wd->sta.authMode = ZM_AUTH_MODE_WPA2\n");
+				/* wd->sta.authMode = ZM_AUTH_MODE_WPA2; */
+				/* wd->ws.authMode = ZM_AUTH_MODE_WPA2; */
+				zfiWlanSetAuthenticationMode(dev,
+							ZM_AUTH_MODE_WPA2);
+			}
+			/* WPA or WPAPSK */
+			if ((macp->supIe[21] == 0x50) ||
+				(macp->supIe[22] == 0xf2)) {
+				if (macp->supIe[11] == 0x2) {
+					printk(KERN_ERR
+				"wd->sta.wepStatus = ZM_ENCRYPTION_TKIP\n");
+				/* wd->sta.wepStatus = ZM_ENCRYPTION_TKIP; */
+				/* wd->ws.wepStatus = ZM_ENCRYPTION_TKIP; */
+				zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_TKIP);
+			} else {
+				printk(KERN_ERR
+				"wd->sta.wepStatus = ZM_ENCRYPTION_AES\n");
+				/* wd->sta.wepStatus = ZM_ENCRYPTION_AES; */
+				/* wd->ws.wepStatus = ZM_ENCRYPTION_AES; */
+				zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_AES);
+				}
+			}
+			//WPA2 or WPA2PSK
+			if ((macp->supIe[17] == 0xf) ||
+				(macp->supIe[18] == 0xac)) {
+				if (macp->supIe[13] == 0x2) {
+					printk(KERN_ERR
+				"wd->sta.wepStatus = ZM_ENCRYPTION_TKIP\n");
+				/* wd->sta.wepStatus = ZM_ENCRYPTION_TKIP; */
+				/* wd->ws.wepStatus = ZM_ENCRYPTION_TKIP; */
+				zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_TKIP);
+				} else {
+					printk(KERN_ERR
+				"wd->sta.wepStatus = ZM_ENCRYPTION_AES\n");
+				/* wd->sta.wepStatus = ZM_ENCRYPTION_AES; */
+				/* wd->ws.wepStatus = ZM_ENCRYPTION_AES; */
+				zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_AES);
+					}
+				}
+			}
+			zfiWlanSetWpaSupport(dev, 1);
+		} else {
+			/* Reset the WPA related variables */
+			printk(KERN_ERR "disable\n");
+
+			zfiWlanSetWpaSupport(dev, 0);
+			zfiWlanSetAuthenticationMode(dev, ZM_AUTH_MODE_OPEN);
+			zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_WEP_DISABLED);
+
+			/* Now we only set the length in the WPA IE
+			* field to zero.
+			*macp->cardSetting.WPAIe[1] = 0;
+			*/
+			}
+		}
+
+		if (op == ZD_PARAM_COUNTERMEASURES) {
+			printk(KERN_ERR
+				"****************ZD_PARAM_COUNTERMEASURES : ");
+
+			if(arg) {
+				/*    mCounterMeasureState=1; */
+				printk(KERN_ERR "enable\n");
+			} else {
+				/*    mCounterMeasureState=0; */
+				printk(KERN_ERR "disable\n");
+			}
+		}
+		if (op == ZD_PARAM_DROPUNENCRYPTED) {
+			printk(KERN_ERR "ZD_PARAM_DROPUNENCRYPTED : ");
+
+			if(arg) {
+				printk(KERN_ERR "enable\n");
+			} else {
+				printk(KERN_ERR "disable\n");
+			}
+		}
+		if (op == ZD_PARAM_AUTH_ALGS) {
+			printk(KERN_ERR "ZD_PARAM_AUTH_ALGS : ");
+
+			if (arg == 0) {
+				printk(KERN_ERR "OPEN_SYSTEM\n");
+			} else {
+				printk(KERN_ERR "SHARED_KEY\n");
+			}
+		}
+		if (op == ZD_PARAM_WPS_FILTER) {
+			printk(KERN_ERR "ZD_PARAM_WPS_FILTER : ");
+
+			if (arg) {
+				/*    mCounterMeasureState=1; */
+				macp->forwardMgmt = 1;
+				printk(KERN_ERR "enable\n");
+			} else {
+				/*    mCounterMeasureState=0; */
+				macp->forwardMgmt = 0;
+				printk(KERN_ERR "disable\n");
+			}
+		}
+	}
+		err = 0;
+		break;
+	case ZD_IOCTL_GETWPAIE: {
+		struct ieee80211req_wpaie req_wpaie;
+		u16_t apId, i, j;
+
+		/* Get the AP Id */
+		apId = zfLnxGetVapId(dev);
+
+		if (apId == 0xffff) {
+			apId = 0;
+		} else {
+			apId = apId + 1;
+		}
+
+		if (copy_from_user(&req_wpaie, ifr->ifr_data,
+					sizeof(struct ieee80211req_wpaie))) {
+			printk(KERN_ERR "usbdrv : copy_from_user error\n");
+			return -EFAULT;
+		}
+
+		for (i = 0; i < ZM_OAL_MAX_STA_SUPPORT; i++) {
+			for (j = 0; j < IEEE80211_ADDR_LEN; j++) {
+				if (macp->stawpaie[i].wpa_macaddr[j] !=
+						req_wpaie.wpa_macaddr[j])
 				break;
 			}
-			{
-				int val = *( (int *) wrq->u.name );
-				if ((val < 0) || (val > 2))
-				{
-					err = -EINVAL;
-					break;
-				}
-				else
-				{
-					zfiWlanSetAuthenticationMode(dev, val);
-
-                    if (macp->DeviceOpened == 1)
-                    {
-                        zfiWlanDisable(dev, 0);
-                        zfiWlanEnable(dev);
-                    }
-
-					err = 0;
-					changed = 1;
-				}
-			}
-		}
+			if (j == 6)
 			break;
-
-		case SIOCIWFIRSTPRIV + 0x3: /* get_auth */
-		{
-		    int AuthMode = ZM_AUTH_MODE_OPEN;
-
-			//printk("CWY - SIOCIWFIRSTPRIV + 0x3 (get_auth)\n");
-
-			if (wrq->u.data.pointer)
-			{
-				wrq->u.data.flags = 1;
-
-				AuthMode = zfiWlanQueryAuthenticationMode(dev, 0);
-				if (AuthMode == ZM_AUTH_MODE_OPEN)
-				{
-					wrq->u.data.length = 12;
-
-					if (copy_to_user(wrq->u.data.pointer, "open system", 12))
-					{
-						return -EFAULT;
-					}
-				}
-				else if (AuthMode == ZM_AUTH_MODE_SHARED_KEY)
-				{
-					wrq->u.data.length = 11;
-
-					if (copy_to_user(wrq->u.data.pointer, "shared key", 11))
-					{
-						return -EFAULT;
-					}
-				}
-				else if (AuthMode == ZM_AUTH_MODE_AUTO)
-				{
-					wrq->u.data.length = 10;
-
-					if (copy_to_user(wrq->u.data.pointer, "auto mode", 10))
-					{
-						return -EFAULT;
-					}
-				}
-				else
-				{
-					return -EFAULT;
-				}
-			}
 		}
-			break;
 
+		if (i < ZM_OAL_MAX_STA_SUPPORT) {
+		/* printk("ZD_IOCTL_GETWPAIE - sta index = % d\n", i); */
+		memcpy(req_wpaie.wpa_ie, macp->stawpaie[i].wpa_ie,
+							IEEE80211_MAX_IE_SIZE);
+		}
 
-        case ZDAPIOCTL:    //debug command
-            if (copy_from_user(&zdreq, ifr->ifr_data, sizeof (zdreq)))
-            {
-                printk(KERN_ERR "usbdrv: copy_from_user error\n");
-                return -EFAULT;
-            }
+		if (copy_to_user(wrq->u.data.pointer, &req_wpaie,
+				sizeof(struct ieee80211req_wpaie))) {
+			return -EFAULT;
+		}
+	}
 
-            //printk(KERN_DEBUG "usbdrv: cmd=%2x, reg=0x%04lx, value=0x%08lx\n",
-            //        zdreq.cmd, zdreq.addr, zdreq.value);
+		err = 0;
+		break;
+	#ifdef ZM_ENABLE_CENC
+	case ZM_IOCTL_CENC:
+		if (copy_from_user(&macp->zd_wpa_req, ifr->ifr_data,
+			sizeof(struct athr_wlan_param))) {
+			printk(KERN_ERR "usbdrv : copy_from_user error\n");
+			return -EFAULT;
+		}
 
-			zfLnxPrivateIoctl(dev, &zdreq);
+		usbdrv_cenc_ioctl(dev,
+				(struct zydas_cenc_param *)&macp->zd_wpa_req);
+		err = 0;
+		break;
+	#endif /* ZM_ENABLE_CENC */
+	default:
+		err = -EOPNOTSUPP;
+		break;
+	}
 
-            err = 0;
-            break;
-
-        case ZD_IOCTL_WPA:
-            if (copy_from_user(&zdparm, ifr->ifr_data, sizeof(struct athr_wlan_param)))
-            {
-                printk(KERN_ERR "usbdrv: copy_from_user error\n");
-                return -EFAULT;
-            }
-
-            usbdrv_wpa_ioctl(dev, &zdparm);
-            err = 0;
-            break;
-
-        case ZD_IOCTL_PARAM:
-        {
-            int *p;
-            int op;
-            int arg;
-
-            /* Point to the name field and retrieve the
-             * op and arg elements.          */
-            p = (int *)wrq->u.name;
-            op = *p++;
-            arg = *p;
-
-            if(op == ZD_PARAM_ROAMING)
-            {
-                printk(KERN_ERR "************* ZD_PARAM_ROAMING: %d\n", arg);
-                //macp->cardSetting.ap_scan=(U8)arg;
-            }
-            if(op == ZD_PARAM_PRIVACY)
-            {
-                printk(KERN_ERR "ZD_IOCTL_PRIVACY: ");
-
-                /* Turn on the privacy invoke flag */
-                if(arg)
-                {
-                //    mCap[0] |= CAP_PRIVACY;
-                //    macp->cardSetting.EncryOnOff[0] = 1;
-                    printk(KERN_ERR "enable\n");
-
-                }
-                else
-                {
-                //    mCap[0] &= ~CAP_PRIVACY;
-                //    macp->cardSetting.EncryOnOff[0] = 0;
-                    printk(KERN_ERR "disable\n");
-                }
-                                //changed=1;
-            }
-            if(op == ZD_PARAM_WPA)
-            {
-                printk(KERN_ERR "ZD_PARAM_WPA: ");
-
-                if(arg)
-                {
-                    printk(KERN_ERR "enable\n");
-
-                    if (zfiWlanQueryWlanMode(dev) != ZM_MODE_AP)
-                    {
-                        printk(KERN_ERR "Station Mode\n");
-                        //zfiWlanQueryWpaIe(dev, (u8_t *)&wpaIe, &wpalen);
-                        //printk("wpaIe : %2x,%2x,%2x\n", wpaIe[21], wpaIe[22], wpaIe[23]);
-                        //printk("rsnIe : %2x,%2x,%2x\n", wpaIe[17], wpaIe[18], wpaIe[19]);
-                        if ((macp->supIe[21] == 0x50) &&
-                            (macp->supIe[22] == 0xf2) &&
-                            (macp->supIe[23] == 0x2))
-                        {
-                            printk(KERN_ERR "wd->sta.authMode = ZM_AUTH_MODE_WPAPSK\n");
-                            //wd->sta.authMode = ZM_AUTH_MODE_WPAPSK;
-                            //wd->ws.authMode = ZM_AUTH_MODE_WPAPSK;
-                            zfiWlanSetAuthenticationMode(dev, ZM_AUTH_MODE_WPAPSK);
-                        }
-                        else if ((macp->supIe[21] == 0x50) &&
-                                 (macp->supIe[22] == 0xf2) &&
-                                 (macp->supIe[23] == 0x1))
-                        {
-                            printk(KERN_ERR "wd->sta.authMode = ZM_AUTH_MODE_WPA\n");
-                            //wd->sta.authMode = ZM_AUTH_MODE_WPA;
-                            //wd->ws.authMode = ZM_AUTH_MODE_WPA;
-                            zfiWlanSetAuthenticationMode(dev, ZM_AUTH_MODE_WPA);
-                        }
-                        else if ((macp->supIe[17] == 0xf) &&
-                                 (macp->supIe[18] == 0xac) &&
-                                 (macp->supIe[19] == 0x2))
-                        {
-                            printk(KERN_ERR "wd->sta.authMode = ZM_AUTH_MODE_WPA2PSK\n");
-                            //wd->sta.authMode = ZM_AUTH_MODE_WPA2PSK;
-                            //wd->ws.authMode = ZM_AUTH_MODE_WPA2PSK;
-                            zfiWlanSetAuthenticationMode(dev, ZM_AUTH_MODE_WPA2PSK);
-                        }
-                        else if ((macp->supIe[17] == 0xf) &&
-                                 (macp->supIe[18] == 0xac) &&
-                                 (macp->supIe[19] == 0x1))
-                        {
-                            printk(KERN_ERR "wd->sta.authMode = ZM_AUTH_MODE_WPA2\n");
-                            //wd->sta.authMode = ZM_AUTH_MODE_WPA2;
-                            //wd->ws.authMode = ZM_AUTH_MODE_WPA2;
-                            zfiWlanSetAuthenticationMode(dev, ZM_AUTH_MODE_WPA2);
-                        }
-                        if ((macp->supIe[21] == 0x50) || (macp->supIe[22] == 0xf2))//WPA or WPAPSK
-                        {
-                            if (macp->supIe[11] == 0x2)
-                            {
-                                printk(KERN_ERR "wd->sta.wepStatus = ZM_ENCRYPTION_TKIP\n");
-                                //wd->sta.wepStatus = ZM_ENCRYPTION_TKIP;
-                                //wd->ws.wepStatus = ZM_ENCRYPTION_TKIP;
-                                zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_TKIP);
-                            }
-                            else
-                            {
-                                printk(KERN_ERR "wd->sta.wepStatus = ZM_ENCRYPTION_AES\n");
-                                //wd->sta.wepStatus = ZM_ENCRYPTION_AES;
-                                //wd->ws.wepStatus = ZM_ENCRYPTION_AES;
-                                zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_AES);
-                            }
-                        }
-                        if ((macp->supIe[17] == 0xf) || (macp->supIe[18] == 0xac)) //WPA2 or WPA2PSK
-                        {
-                            if (macp->supIe[13] == 0x2)
-                            {
-                                printk(KERN_ERR "wd->sta.wepStatus = ZM_ENCRYPTION_TKIP\n");
-                                //wd->sta.wepStatus = ZM_ENCRYPTION_TKIP;
-                                //wd->ws.wepStatus = ZM_ENCRYPTION_TKIP;
-                                zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_TKIP);
-                            }
-                            else
-                            {
-                                printk(KERN_ERR "wd->sta.wepStatus = ZM_ENCRYPTION_AES\n");
-                                //wd->sta.wepStatus = ZM_ENCRYPTION_AES;
-                                //wd->ws.wepStatus = ZM_ENCRYPTION_AES;
-                                zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_AES);
-                            }
-                        }
-                    }
-                    zfiWlanSetWpaSupport(dev, 1);
-                }
-                else
-                {
-                    /* Reset the WPA related variables */
-                    printk(KERN_ERR "disable\n");
-
-                    zfiWlanSetWpaSupport(dev, 0);
-                    zfiWlanSetAuthenticationMode(dev, ZM_AUTH_MODE_OPEN);
-                    zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_WEP_DISABLED);
-
-                    /* Now we only set the length in the WPA IE
-                     * field to zero.                         */
-                    //macp->cardSetting.WPAIe[1] = 0;
-                }
-            }
-            if(op == ZD_PARAM_COUNTERMEASURES)
-            {
-                printk(KERN_ERR "================ZD_PARAM_COUNTERMEASURES: ");
-
-                if(arg)
-                {
-                //    mCounterMeasureState=1;
-                    printk(KERN_ERR "enable\n");
-                }
-                else
-                {
-                //    mCounterMeasureState=0;
-                    printk(KERN_ERR "disable\n");
-                }
-            }
-            if(op == ZD_PARAM_DROPUNENCRYPTED)
-            {
-                printk(KERN_ERR "ZD_PARAM_DROPUNENCRYPTED: ");
-
-                if(arg)
-                {
-                    printk(KERN_ERR "enable\n");
-                }
-                else
-                {
-                    printk(KERN_ERR "disable\n");
-                }
-            }
-            if(op == ZD_PARAM_AUTH_ALGS)
-            {
-                printk(KERN_ERR "ZD_PARAM_AUTH_ALGS: ");
-
-                if(arg == 0)
-                {
-                    printk(KERN_ERR "OPEN_SYSTEM\n");
-                }
-                else
-                {
-                    printk(KERN_ERR "SHARED_KEY\n");
-                }
-            }
-            if(op == ZD_PARAM_WPS_FILTER)
-            {
-                printk(KERN_ERR "ZD_PARAM_WPS_FILTER: ");
-
-                if(arg)
-                {
-                //    mCounterMeasureState=1;
-                    macp->forwardMgmt = 1;
-                    printk(KERN_ERR "enable\n");
-                }
-                else
-                {
-                //    mCounterMeasureState=0;
-                    macp->forwardMgmt = 0;
-                    printk(KERN_ERR "disable\n");
-                }
-            }
-        }
-            err = 0;
-            break;
-
-        case ZD_IOCTL_GETWPAIE:
-        {
-            struct ieee80211req_wpaie req_wpaie;
-            u16_t apId, i, j;
-
-            /* Get the AP Id */
-            apId = zfLnxGetVapId(dev);
-
-            if (apId == 0xffff)
-            {
-                apId = 0;
-            }
-            else
-            {
-                apId = apId+1;
-            }
-
-            if (copy_from_user(&req_wpaie, ifr->ifr_data, sizeof(struct ieee80211req_wpaie))){
-                printk(KERN_ERR "usbdrv: copy_from_user error\n");
-                return -EFAULT;
-            }
-
-            for(i = 0; i < ZM_OAL_MAX_STA_SUPPORT; i++)
-            {
-                for(j = 0; j < IEEE80211_ADDR_LEN; j++)
-                {
-                    if (macp->stawpaie[i].wpa_macaddr[j] != req_wpaie.wpa_macaddr[j])
-                        break;
-                }
-                if (j == 6)
-                    break;
-            }
-            if (i < ZM_OAL_MAX_STA_SUPPORT)
-            {
-                //printk("ZD_IOCTL_GETWPAIE - sta index = %d\n", i);
-                memcpy(req_wpaie.wpa_ie, macp->stawpaie[i].wpa_ie, IEEE80211_MAX_IE_SIZE);
-            }
-
-            if (copy_to_user(wrq->u.data.pointer, &req_wpaie, sizeof(struct ieee80211req_wpaie)))
-            {
-                    return -EFAULT;
-            }
-        }
-
-            err = 0;
-            break;
-#ifdef ZM_ENABLE_CENC
-        case ZM_IOCTL_CENC:
-            if (copy_from_user(&macp->zd_wpa_req, ifr->ifr_data, sizeof(struct athr_wlan_param)))
-            {
-                printk(KERN_ERR "usbdrv: copy_from_user error\n");
-                return -EFAULT;
-            }
-
-            usbdrv_cenc_ioctl(dev, (struct zydas_cenc_param *)&macp->zd_wpa_req);
-            err = 0;
-            break;
-#endif //ZM_ENABLE_CENC
-        default:
-            err = -EOPNOTSUPP;
-            break;
-    }
-
-
-    return err;
+	return err;
 }
diff --git a/drivers/staging/otus/usbdrv.c b/drivers/staging/otus/usbdrv.c
index dfe0707..565a839 100644
--- a/drivers/staging/otus/usbdrv.c
+++ b/drivers/staging/otus/usbdrv.c
@@ -936,30 +936,26 @@
     for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i)
     {
         endpoint = &iface_desc->endpoint[i].desc;
-        if ((endpoint->bEndpointAddress & 0x80) &&
-            ((endpoint->bmAttributes & 3) == 0x02))
+	 if (usb_endpoint_is_bulk_in(endpoint))
         {
             /* we found a bulk in endpoint */
             printk(KERN_ERR "bulk in: wMaxPacketSize = %x\n", le16_to_cpu(endpoint->wMaxPacketSize));
         }
 
-        if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
-            ((endpoint->bmAttributes & 3) == 0x02))
+	 if (usb_endpoint_is_bulk_out(endpoint))
         {
             /* we found a bulk out endpoint */
             printk(KERN_ERR "bulk out: wMaxPacketSize = %x\n", le16_to_cpu(endpoint->wMaxPacketSize));
         }
 
-        if ((endpoint->bEndpointAddress & 0x80) &&
-            ((endpoint->bmAttributes & 3) == 0x03))
+	 if (usb_endpoint_is_int_in(endpoint))
         {
             /* we found a interrupt in endpoint */
             printk(KERN_ERR "interrupt in: wMaxPacketSize = %x\n", le16_to_cpu(endpoint->wMaxPacketSize));
             printk(KERN_ERR "interrupt in: int_interval = %d\n", endpoint->bInterval);
         }
 
-        if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
-            ((endpoint->bmAttributes & 3) == 0x03))
+	 if (usb_endpoint_is_int_out(endpoint))
         {
             /* we found a interrupt out endpoint */
             printk(KERN_ERR "interrupt out: wMaxPacketSize = %x\n", le16_to_cpu(endpoint->wMaxPacketSize));
diff --git a/drivers/staging/otus/wwrap.c b/drivers/staging/otus/wwrap.c
index 1bb5f59..4db8f6e 100644
--- a/drivers/staging/otus/wwrap.c
+++ b/drivers/staging/otus/wwrap.c
@@ -350,8 +350,7 @@
     buf->len = 0;
 #endif
 
-    if ((buf->tail + urb->actual_length) > buf->end)
-        BUG();
+    BUG_ON((buf->tail + urb->actual_length) > buf->end);
 
     skb_put(buf, urb->actual_length);
 
@@ -971,8 +970,7 @@
 out:
 	return ret;
 nlmsg_failure: /*NLMSG_PUT ʧ°Ü£¬Ôò³·ÏúÌ×½Ó×Ö»º´æ*/
-  	if(skb)
-    		kfree_skb(skb);
+	kfree_skb(skb);
 	goto out;
 
 #undef COMMTYPE_GROUP
diff --git a/drivers/staging/otus/zdcompat.h b/drivers/staging/otus/zdcompat.h
index 8acf400..d9a3b2d 100644
--- a/drivers/staging/otus/zdcompat.h
+++ b/drivers/staging/otus/zdcompat.h
@@ -45,13 +45,6 @@
 #endif
 #endif
 
-#ifndef IRQ_NONE
-typedef void irqreturn_t;
-#define IRQ_NONE
-#define IRQ_HANDLED
-#define IRQ_RETVAL(x)
-#endif
-
 #ifndef in_atomic
 #define in_atomic()  0
 #endif
diff --git a/drivers/staging/p9auth/Kconfig b/drivers/staging/p9auth/Kconfig
new file mode 100644
index 0000000..d1c66d2
--- /dev/null
+++ b/drivers/staging/p9auth/Kconfig
@@ -0,0 +1,9 @@
+config PLAN9AUTH
+	tristate "Plan 9 style capability device implementation"
+	default n
+	depends on CRYPTO
+	help
+	  This module implements the Plan 9 style capability device.
+
+	  To compile this driver as a module, choose
+	  M here: the module will be called p9auth.
diff --git a/drivers/staging/p9auth/Makefile b/drivers/staging/p9auth/Makefile
new file mode 100644
index 0000000..3ebf6ff
--- /dev/null
+++ b/drivers/staging/p9auth/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_PLAN9AUTH)	+= p9auth.o
diff --git a/drivers/staging/p9auth/p9auth.c b/drivers/staging/p9auth/p9auth.c
new file mode 100644
index 0000000..3cac89b
--- /dev/null
+++ b/drivers/staging/p9auth/p9auth.c
@@ -0,0 +1,383 @@
+/*
+ * Plan 9 style capability device implementation for the Linux Kernel
+ *
+ * Copyright 2008, 2009 Ashwin Ganti <ashwin.ganti@gmail.com>
+ *
+ * Released under the GPLv2
+ *
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/moduleparam.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/fcntl.h>
+#include <linux/cdev.h>
+#include <linux/uaccess.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/crypto.h>
+#include <linux/highmem.h>
+#include <linux/scatterlist.h>
+#include <linux/sched.h>
+#include <linux/cred.h>
+
+#ifndef CAP_MAJOR
+#define CAP_MAJOR 0
+#endif
+
+#ifndef CAP_NR_DEVS
+#define CAP_NR_DEVS 2		/* caphash and capuse */
+#endif
+
+#ifndef CAP_NODE_SIZE
+#define CAP_NODE_SIZE 20
+#endif
+
+#define MAX_DIGEST_SIZE  20
+
+struct cap_node {
+	char data[CAP_NODE_SIZE];
+	struct list_head list;
+};
+
+struct cap_dev {
+	struct cap_node *head;
+	int node_size;
+	unsigned long size;
+	struct semaphore sem;
+	struct cdev cdev;
+};
+
+static int cap_major = CAP_MAJOR;
+static int cap_minor;
+static int cap_nr_devs = CAP_NR_DEVS;
+static int cap_node_size = CAP_NODE_SIZE;
+
+module_param(cap_major, int, S_IRUGO);
+module_param(cap_minor, int, S_IRUGO);
+module_param(cap_nr_devs, int, S_IRUGO);
+
+MODULE_AUTHOR("Ashwin Ganti");
+MODULE_LICENSE("GPL");
+
+static struct cap_dev *cap_devices;
+
+static void hexdump(unsigned char *buf, unsigned int len)
+{
+	while (len--)
+		printk("%02x", *buf++);
+	printk("\n");
+}
+
+static char *cap_hash(char *plain_text, unsigned int plain_text_size,
+		      char *key, unsigned int key_size)
+{
+	struct scatterlist sg;
+	char *result;
+	struct crypto_hash *tfm;
+	struct hash_desc desc;
+	int ret;
+
+	tfm = crypto_alloc_hash("hmac(sha1)", 0, CRYPTO_ALG_ASYNC);
+	if (IS_ERR(tfm)) {
+		printk(KERN_ERR
+		       "failed to load transform for hmac(sha1): %ld\n",
+		       PTR_ERR(tfm));
+		return NULL;
+	}
+
+	desc.tfm = tfm;
+	desc.flags = 0;
+
+	result = kzalloc(MAX_DIGEST_SIZE, GFP_KERNEL);
+	if (!result) {
+		printk(KERN_ERR "out of memory!\n");
+		goto out;
+	}
+
+	sg_set_buf(&sg, plain_text, plain_text_size);
+
+	ret = crypto_hash_setkey(tfm, key, key_size);
+	if (ret) {
+		printk(KERN_ERR "setkey() failed ret=%d\n", ret);
+		kfree(result);
+		result = NULL;
+		goto out;
+	}
+
+	ret = crypto_hash_digest(&desc, &sg, plain_text_size, result);
+	if (ret) {
+		printk(KERN_ERR "digest () failed ret=%d\n", ret);
+		kfree(result);
+		result = NULL;
+		goto out;
+	}
+
+	printk(KERN_DEBUG "crypto hash digest size %d\n",
+	       crypto_hash_digestsize(tfm));
+	hexdump(result, MAX_DIGEST_SIZE);
+
+out:
+	crypto_free_hash(tfm);
+	return result;
+}
+
+static int cap_trim(struct cap_dev *dev)
+{
+	struct cap_node *tmp;
+	struct list_head *pos, *q;
+	if (dev->head != NULL) {
+		list_for_each_safe(pos, q, &(dev->head->list)) {
+			tmp = list_entry(pos, struct cap_node, list);
+			list_del(pos);
+			kfree(tmp);
+		}
+	}
+	return 0;
+}
+
+static int cap_open(struct inode *inode, struct file *filp)
+{
+	struct cap_dev *dev;
+	dev = container_of(inode->i_cdev, struct cap_dev, cdev);
+	filp->private_data = dev;
+
+	/* trim to 0 the length of the device if open was write-only */
+	if ((filp->f_flags & O_ACCMODE) == O_WRONLY) {
+		if (down_interruptible(&dev->sem))
+			return -ERESTARTSYS;
+		cap_trim(dev);
+		up(&dev->sem);
+	}
+	/* initialise the head if it is NULL */
+	if (dev->head == NULL) {
+		dev->head = kmalloc(sizeof(struct cap_node), GFP_KERNEL);
+		INIT_LIST_HEAD(&(dev->head->list));
+	}
+	return 0;
+}
+
+static int cap_release(struct inode *inode, struct file *filp)
+{
+	return 0;
+}
+
+static ssize_t cap_write(struct file *filp, const char __user *buf,
+			 size_t count, loff_t *f_pos)
+{
+	struct cap_node *node_ptr, *tmp;
+	struct list_head *pos;
+	struct cap_dev *dev = filp->private_data;
+	ssize_t retval = -ENOMEM;
+	struct cred *new;
+	int len, target_int, source_int, flag = 0;
+	char *user_buf, *user_buf_running, *source_user, *target_user,
+	    *rand_str, *hash_str, *result;
+
+	if (down_interruptible(&dev->sem))
+		return -ERESTARTSYS;
+
+	node_ptr = kmalloc(sizeof(struct cap_node), GFP_KERNEL);
+	user_buf = kzalloc(count, GFP_KERNEL);
+
+	if (copy_from_user(user_buf, buf, count)) {
+		retval = -EFAULT;
+		goto out;
+	}
+
+	/*
+	 * If the minor number is 0 ( /dev/caphash ) then simply add the
+	 * hashed capability supplied by the user to the list of hashes
+	 */
+	if (0 == iminor(filp->f_dentry->d_inode)) {
+		printk(KERN_INFO "Capability being written to /dev/caphash : \n");
+		hexdump(user_buf, count);
+		memcpy(node_ptr->data, user_buf, count);
+		list_add(&(node_ptr->list), &(dev->head->list));
+	} else {
+		/*
+		 * break the supplied string into tokens with @ as the
+		 * delimiter If the string is "user1@user2@randomstring" we
+		 * need to split it and hash 'user1@user2' using 'randomstring'
+		 * as the key.
+		 */
+		user_buf_running = kstrdup(user_buf, GFP_KERNEL);
+		source_user = strsep(&user_buf_running, "@");
+		target_user = strsep(&user_buf_running, "@");
+		rand_str = strsep(&user_buf_running, "@");
+
+		/* hash the string user1@user2 with rand_str as the key */
+		len = strlen(source_user) + strlen(target_user) + 1;
+		hash_str = kzalloc(len, GFP_KERNEL);
+		strcat(hash_str, source_user);
+		strcat(hash_str, "@");
+		strcat(hash_str, target_user);
+
+		printk(KERN_ALERT "the source user is %s \n", source_user);
+		printk(KERN_ALERT "the target user is %s \n", target_user);
+
+		result = cap_hash(hash_str, len, rand_str, strlen(rand_str));
+		if (NULL == result) {
+			retval = -EFAULT;
+			goto out;
+		}
+		memcpy(node_ptr->data, result, CAP_NODE_SIZE);
+		/* Change the process's uid if the hash is present in the
+		 * list of hashes
+		 */
+		list_for_each(pos, &(cap_devices->head->list)) {
+			/*
+			 * Change the user id of the process if the hashes
+			 * match
+			 */
+			if (0 ==
+			    memcmp(result,
+				   list_entry(pos, struct cap_node,
+					      list)->data,
+				   CAP_NODE_SIZE)) {
+				target_int = (unsigned int)
+				    simple_strtol(target_user, NULL, 0);
+				source_int = (unsigned int)
+				    simple_strtol(source_user, NULL, 0);
+				flag = 1;
+
+				/*
+				 * Check whether the process writing to capuse
+				 * is actually owned by the source owner
+				 */
+				if (source_int != current_uid()) {
+					printk(KERN_ALERT
+					       "Process is not owned by the source user of the capability.\n");
+					retval = -EFAULT;
+					goto out;
+				}
+				/*
+				 * What all id's need to be changed here? uid,
+				 * euid, fsid, savedids ??  Currently I am
+				 * changing the effective user id since most of
+				 * the authorisation decisions are based on it
+				 */
+				new = prepare_creds();
+				if (!new) {
+					retval = -ENOMEM;
+					goto out;
+				}
+				new->uid = (uid_t) target_int;
+				new->euid = (uid_t) target_int;
+				retval = commit_creds(new);
+				if (retval)
+					goto out;
+
+				/*
+				 * Remove the capability from the list and
+				 * break
+				 */
+				tmp = list_entry(pos, struct cap_node, list);
+				list_del(pos);
+				kfree(tmp);
+				break;
+			}
+		}
+		if (0 == flag) {
+			/*
+			 * The capability is not present in the list of the
+			 * hashes stored, hence return failure
+			 */
+			printk(KERN_ALERT
+			       "Invalid capabiliy written to /dev/capuse \n");
+			retval = -EFAULT;
+			goto out;
+		}
+	}
+	*f_pos += count;
+	retval = count;
+	/* update the size */
+	if (dev->size < *f_pos)
+		dev->size = *f_pos;
+
+out:
+	up(&dev->sem);
+	return retval;
+}
+
+static const struct file_operations cap_fops = {
+	.owner = THIS_MODULE,
+	.write = cap_write,
+	.open = cap_open,
+	.release = cap_release,
+};
+
+static void cap_cleanup_module(void)
+{
+	int i;
+	dev_t devno = MKDEV(cap_major, cap_minor);
+	if (cap_devices) {
+		for (i = 0; i < cap_nr_devs; i++) {
+			cap_trim(cap_devices + i);
+			cdev_del(&cap_devices[i].cdev);
+		}
+		kfree(cap_devices);
+	}
+	unregister_chrdev_region(devno, cap_nr_devs);
+
+}
+
+static void cap_setup_cdev(struct cap_dev *dev, int index)
+{
+	int err, devno = MKDEV(cap_major, cap_minor + index);
+	cdev_init(&dev->cdev, &cap_fops);
+	dev->cdev.owner = THIS_MODULE;
+	dev->cdev.ops = &cap_fops;
+	err = cdev_add(&dev->cdev, devno, 1);
+	if (err)
+		printk(KERN_NOTICE "Error %d adding cap%d", err, index);
+}
+
+static int cap_init_module(void)
+{
+	int result, i;
+	dev_t dev = 0;
+
+	if (cap_major) {
+		dev = MKDEV(cap_major, cap_minor);
+		result = register_chrdev_region(dev, cap_nr_devs, "cap");
+	} else {
+		result = alloc_chrdev_region(&dev, cap_minor, cap_nr_devs,
+					     "cap");
+		cap_major = MAJOR(dev);
+	}
+
+	if (result < 0) {
+		printk(KERN_WARNING "cap: can't get major %d\n",
+		       cap_major);
+		return result;
+	}
+
+	cap_devices = kzalloc(cap_nr_devs * sizeof(struct cap_dev),
+			      GFP_KERNEL);
+	if (!cap_devices) {
+		result = -ENOMEM;
+		goto fail;
+	}
+
+	/* Initialize each device. */
+	for (i = 0; i < cap_nr_devs; i++) {
+		cap_devices[i].node_size = cap_node_size;
+		init_MUTEX(&cap_devices[i].sem);
+		cap_setup_cdev(&cap_devices[i], i);
+	}
+
+	return 0;
+
+fail:
+	cap_cleanup_module();
+	return result;
+}
+
+module_init(cap_init_module);
+module_exit(cap_cleanup_module);
+
+
diff --git a/drivers/staging/panel/Kconfig b/drivers/staging/panel/Kconfig
index c4b30f2..3abe7c9 100644
--- a/drivers/staging/panel/Kconfig
+++ b/drivers/staging/panel/Kconfig
@@ -110,7 +110,7 @@
 	---help---
 	  Most LCDs use a standard controller which supports hardware lines of 40
 	  characters, although sometimes only 16, 20 or 24 of them are really wired
-	  to the terminal. This results in some non-visible but adressable characters,
+	  to the terminal. This results in some non-visible but addressable characters,
 	  and is the case for most parallel LCDs. Other LCDs, and some serial ones,
 	  however, use the same line width internally as what is visible. The KS0074
 	  for example, uses 16 characters per line for 16 visible characters per line.
diff --git a/drivers/staging/phison/Kconfig b/drivers/staging/phison/Kconfig
new file mode 100644
index 0000000..d3c65d3
--- /dev/null
+++ b/drivers/staging/phison/Kconfig
@@ -0,0 +1,5 @@
+config IDE_PHISON
+	tristate "PCIE ATA PS5000 IDE support"
+	depends on PCI && ATA && ATA_SFF
+	---help---
+	  This is an experimental driver for PS5000 IDE driver.
diff --git a/drivers/staging/phison/Makefile b/drivers/staging/phison/Makefile
new file mode 100644
index 0000000..7642a21
--- /dev/null
+++ b/drivers/staging/phison/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_IDE_PHISON)	+= phison.o
diff --git a/drivers/staging/phison/phison.c b/drivers/staging/phison/phison.c
new file mode 100644
index 0000000..270ebcb
--- /dev/null
+++ b/drivers/staging/phison/phison.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2006		Red Hat <evan_ko@phison.com>
+ *
+ *  May be copied or modified under the terms of the GNU General Public License
+ *
+ *  [Modify History]
+ *   #0001, Evan, 2008.10.22, V0.00, New release.
+ *   #0002, Evan, 2008.11.01, V0.90, Test Work In Ubuntu Linux 8.04.
+ *   #0003, Evan, 2008.01.08, V0.91, Change Name "PCIE-SSD" to "E-BOX".
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <scsi/scsi_host.h>
+#include <linux/libata.h>
+#include <linux/ata.h>
+
+#define PHISON_DEBUG
+
+#define DRV_NAME		"phison_e-box"	/* #0003 */
+#define DRV_VERSION 		"0.91"		/* #0003 */
+
+#define PCI_VENDOR_ID_PHISON	0x1987
+#define PCI_DEVICE_ID_PS5000	0x5000
+
+static int phison_pre_reset(struct ata_link *link, unsigned long deadline)
+{
+	int ret;
+	struct ata_port *ap = link->ap;
+
+	ap->cbl = ATA_CBL_NONE;
+	ret = ata_std_prereset(link, deadline);
+	dev_dbg(ap->dev, "phison_pre_reset(), ret = %x\n", ret);
+	return ret;
+}
+
+static struct scsi_host_template phison_sht = {
+	ATA_BMDMA_SHT(DRV_NAME),
+};
+
+static struct ata_port_operations phison_ops = {
+	.inherits		= &ata_bmdma_port_ops,
+	.prereset		= phison_pre_reset,
+};
+
+static int phison_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	int ret;
+	struct ata_port_info info = {
+		.flags		= ATA_FLAG_NO_ATAPI,
+
+		.pio_mask	= 0x1f,
+		.mwdma_mask	= 0x07,
+		.udma_mask 	= ATA_UDMA5,
+
+		.port_ops	= &phison_ops,
+	};
+	const struct ata_port_info *ppi[] = { &info, NULL };
+
+	ret = ata_pci_sff_init_one(pdev, ppi, &phison_sht, NULL);
+
+	dev_dbg(&pdev->dev, "phison_init_one(), ret = %x\n", ret);
+
+	return ret;
+}
+
+static struct pci_device_id phison_pci_tbl[] = {
+	{ PCI_VENDOR_ID_PHISON, PCI_DEVICE_ID_PS5000, PCI_ANY_ID, PCI_ANY_ID,
+	  PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 0 },
+	{ 0, },
+};
+MODULE_DEVICE_TABLE(pci, phison_pci_tbl);
+
+static struct pci_driver phison_pci_driver = {
+	.name		= DRV_NAME,
+	.id_table	= phison_pci_tbl,
+	.probe		= phison_init_one,
+	.remove		= ata_pci_remove_one,
+#ifdef CONFIG_PM	/* haven't tested it. */
+	.suspend	= ata_pci_device_suspend,
+	.resume		= ata_pci_device_resume,
+#endif
+};
+
+static int phison_ide_init(void)
+{
+	return pci_register_driver(&phison_pci_driver);
+}
+
+static void phison_ide_exit(void)
+{
+	pci_unregister_driver(&phison_pci_driver);
+}
+
+module_init(phison_ide_init);
+module_exit(phison_ide_exit);
+
+MODULE_AUTHOR("Evan Ko");
+MODULE_DESCRIPTION("PCIE driver module for PHISON PS5000 E-BOX");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/staging/pohmelfs/Kconfig b/drivers/staging/pohmelfs/Kconfig
new file mode 100644
index 0000000..58158b8
--- /dev/null
+++ b/drivers/staging/pohmelfs/Kconfig
@@ -0,0 +1,28 @@
+config POHMELFS
+	tristate "POHMELFS filesystem support"
+	depends on NET
+	select CONNECTOR
+	select CRYPTO
+	select CRYPTO_BLKCIPHER
+	select CRYPTO_HMAC
+	help
+	  POHMELFS stands for Parallel Optimized Host Message Exchange Layered
+	  File System.  This is a network filesystem which supports coherent
+	  caching of data and metadata on clients.
+
+config POHMELFS_DEBUG
+	bool "POHMELFS debugging"
+	depends on POHMELFS
+	default n
+	help
+	  Turns on excessive POHMELFS debugging facilities.
+	  You usually do not want to slow things down noticeably and get really
+	  lots of kernel messages in syslog.
+
+config POHMELFS_CRYPTO
+	bool "POHMELFS crypto support"
+	depends on POHMELFS
+	help
+	  This option allows to encrypt and/or protect with strong
+	  cryptographic hash all dataflow between server and clients.
+	  Each config group can have its own keys.
diff --git a/drivers/staging/pohmelfs/Makefile b/drivers/staging/pohmelfs/Makefile
new file mode 100644
index 0000000..196561c
--- /dev/null
+++ b/drivers/staging/pohmelfs/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_POHMELFS)	+= pohmelfs.o
+
+pohmelfs-y := inode.o config.o dir.o net.o path_entry.o trans.o crypto.o lock.o mcache.o
diff --git a/drivers/staging/pohmelfs/config.c b/drivers/staging/pohmelfs/config.c
new file mode 100644
index 0000000..3e67da9
--- /dev/null
+++ b/drivers/staging/pohmelfs/config.c
@@ -0,0 +1,478 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * 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.
+ *
+ * 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/connector.h>
+#include <linux/crypto.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/string.h>
+#include <linux/in.h>
+
+#include "netfs.h"
+
+/*
+ * Global configuration list.
+ * Each client can be asked to get one of them.
+ *
+ * Allows to provide remote server address (ipv4/v6/whatever), port
+ * and so on via kernel connector.
+ */
+
+static struct cb_id pohmelfs_cn_id = {.idx = POHMELFS_CN_IDX, .val = POHMELFS_CN_VAL};
+static LIST_HEAD(pohmelfs_config_list);
+static DEFINE_MUTEX(pohmelfs_config_lock);
+
+static inline int pohmelfs_config_eql(struct pohmelfs_ctl *sc, struct pohmelfs_ctl *ctl)
+{
+	if (sc->idx == ctl->idx && sc->type == ctl->type &&
+			sc->proto == ctl->proto &&
+			sc->addrlen == ctl->addrlen &&
+			!memcmp(&sc->addr, &ctl->addr, ctl->addrlen))
+		return 1;
+
+	return 0;
+}
+
+static struct pohmelfs_config_group *pohmelfs_find_config_group(unsigned int idx)
+{
+	struct pohmelfs_config_group *g, *group = NULL;
+
+	list_for_each_entry(g, &pohmelfs_config_list, group_entry) {
+		if (g->idx == idx) {
+			group = g;
+			break;
+		}
+	}
+
+	return group;
+}
+
+static struct pohmelfs_config_group *pohmelfs_find_create_config_group(unsigned int idx)
+{
+	struct pohmelfs_config_group *g;
+
+	g = pohmelfs_find_config_group(idx);
+	if (g)
+		return g;
+
+	g = kzalloc(sizeof(struct pohmelfs_config_group), GFP_KERNEL);
+	if (!g)
+		return NULL;
+
+	INIT_LIST_HEAD(&g->config_list);
+	g->idx = idx;
+	g->num_entry = 0;
+
+	list_add_tail(&g->group_entry, &pohmelfs_config_list);
+
+	return g;
+}
+
+int pohmelfs_copy_config(struct pohmelfs_sb *psb)
+{
+	struct pohmelfs_config_group *g;
+	struct pohmelfs_config *c, *dst;
+	int err = -ENODEV;
+
+	mutex_lock(&pohmelfs_config_lock);
+
+	g = pohmelfs_find_config_group(psb->idx);
+	if (!g)
+		goto out_unlock;
+
+	/*
+	 * Run over all entries in given config group and try to crate and
+	 * initialize those, which do not exist in superblock list.
+	 * Skip all existing entries.
+	 */
+
+	list_for_each_entry(c, &g->config_list, config_entry) {
+		err = 0;
+		list_for_each_entry(dst, &psb->state_list, config_entry) {
+			if (pohmelfs_config_eql(&dst->state.ctl, &c->state.ctl)) {
+				err = -EEXIST;
+				break;
+			}
+		}
+
+		if (err)
+			continue;
+
+		dst = kzalloc(sizeof(struct pohmelfs_config), GFP_KERNEL);
+		if (!dst) {
+			err = -ENOMEM;
+			break;
+		}
+
+		memcpy(&dst->state.ctl, &c->state.ctl, sizeof(struct pohmelfs_ctl));
+
+		list_add_tail(&dst->config_entry, &psb->state_list);
+
+		err = pohmelfs_state_init_one(psb, dst);
+		if (err) {
+			list_del(&dst->config_entry);
+			kfree(dst);
+		}
+
+		err = 0;
+	}
+
+out_unlock:
+	mutex_unlock(&pohmelfs_config_lock);
+
+	return err;
+}
+
+int pohmelfs_copy_crypto(struct pohmelfs_sb *psb)
+{
+	struct pohmelfs_config_group *g;
+	int err = -ENOENT;
+
+	mutex_lock(&pohmelfs_config_lock);
+	g = pohmelfs_find_config_group(psb->idx);
+	if (!g)
+		goto err_out_exit;
+
+	if (g->hash_string) {
+		err = -ENOMEM;
+		psb->hash_string = kstrdup(g->hash_string, GFP_KERNEL);
+		if (!psb->hash_string)
+			goto err_out_exit;
+		psb->hash_strlen = g->hash_strlen;
+	}
+
+	if (g->cipher_string) {
+		psb->cipher_string = kstrdup(g->cipher_string, GFP_KERNEL);
+		if (!psb->cipher_string)
+			goto err_out_free_hash_string;
+		psb->cipher_strlen = g->cipher_strlen;
+	}
+
+	if (g->hash_keysize) {
+		psb->hash_key = kmalloc(g->hash_keysize, GFP_KERNEL);
+		if (!psb->hash_key)
+			goto err_out_free_cipher_string;
+		memcpy(psb->hash_key, g->hash_key, g->hash_keysize);
+		psb->hash_keysize = g->hash_keysize;
+	}
+
+	if (g->cipher_keysize) {
+		psb->cipher_key = kmalloc(g->cipher_keysize, GFP_KERNEL);
+		if (!psb->cipher_key)
+			goto err_out_free_hash;
+		memcpy(psb->cipher_key, g->cipher_key, g->cipher_keysize);
+		psb->cipher_keysize = g->cipher_keysize;
+	}
+
+	mutex_unlock(&pohmelfs_config_lock);
+
+	return 0;
+
+err_out_free_hash:
+	kfree(psb->hash_key);
+err_out_free_cipher_string:
+	kfree(psb->cipher_string);
+err_out_free_hash_string:
+	kfree(psb->hash_string);
+err_out_exit:
+	mutex_unlock(&pohmelfs_config_lock);
+	return err;
+}
+
+static int pohmelfs_send_reply(int err, int msg_num, int action, struct cn_msg *msg, struct pohmelfs_ctl *ctl)
+{
+	struct pohmelfs_cn_ack *ack;
+
+	ack = kmalloc(sizeof(struct pohmelfs_cn_ack), GFP_KERNEL);
+	if (!ack)
+		return -ENOMEM;
+
+	memset(ack, 0, sizeof(struct pohmelfs_cn_ack));
+	memcpy(&ack->msg, msg, sizeof(struct cn_msg));
+
+	if (action == POHMELFS_CTLINFO_ACK)
+		memcpy(&ack->ctl, ctl, sizeof(struct pohmelfs_ctl));
+
+	ack->msg.len = sizeof(struct pohmelfs_cn_ack) - sizeof(struct cn_msg);
+	ack->msg.ack = msg->ack + 1;
+	ack->error = err;
+	ack->msg_num = msg_num;
+
+	cn_netlink_send(&ack->msg, 0, GFP_KERNEL);
+	kfree(ack);
+	return 0;
+}
+
+static int pohmelfs_cn_disp(struct cn_msg *msg)
+{
+	struct pohmelfs_config_group *g;
+	struct pohmelfs_ctl *ctl = (struct pohmelfs_ctl *)msg->data;
+	struct pohmelfs_config *c, *tmp;
+	int err = 0, i = 1;
+
+	if (msg->len != sizeof(struct pohmelfs_ctl))
+		return -EBADMSG;
+
+	mutex_lock(&pohmelfs_config_lock);
+
+	g = pohmelfs_find_config_group(ctl->idx);
+	if (!g) {
+		pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL);
+		goto out_unlock;
+	}
+
+	list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
+		struct pohmelfs_ctl *sc = &c->state.ctl;
+		if (pohmelfs_send_reply(err, g->num_entry - i, POHMELFS_CTLINFO_ACK, msg, sc)) {
+			err = -ENOMEM;
+			goto out_unlock;
+		}
+		i += 1;
+	}
+
+out_unlock:
+        mutex_unlock(&pohmelfs_config_lock);
+        return err;
+}
+
+static int pohmelfs_cn_ctl(struct cn_msg *msg, int action)
+{
+	struct pohmelfs_config_group *g;
+	struct pohmelfs_ctl *ctl = (struct pohmelfs_ctl *)msg->data;
+	struct pohmelfs_config *c, *tmp;
+	int err = 0;
+
+	if (msg->len != sizeof(struct pohmelfs_ctl))
+		return -EBADMSG;
+
+	mutex_lock(&pohmelfs_config_lock);
+
+	g = pohmelfs_find_create_config_group(ctl->idx);
+	if (!g) {
+		err = -ENOMEM;
+		goto out_unlock;
+	}
+
+	list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
+		struct pohmelfs_ctl *sc = &c->state.ctl;
+
+		if (pohmelfs_config_eql(sc, ctl)) {
+			if (action == POHMELFS_FLAGS_ADD) {
+				err = -EEXIST;
+				goto out_unlock;
+			} else if (action == POHMELFS_FLAGS_DEL) {
+				list_del(&c->config_entry);
+				g->num_entry--;
+				kfree(c);
+				goto out_unlock;
+			} else {
+				err = -EEXIST;
+				goto out_unlock;
+			}
+		}
+	}
+	if (action == POHMELFS_FLAGS_DEL) {
+		err = -EBADMSG;
+		goto out_unlock;
+	}
+
+	c = kzalloc(sizeof(struct pohmelfs_config), GFP_KERNEL);
+	if (!c) {
+		err = -ENOMEM;
+		goto out_unlock;
+	}
+	memcpy(&c->state.ctl, ctl, sizeof(struct pohmelfs_ctl));
+	g->num_entry++;
+	list_add_tail(&c->config_entry, &g->config_list);
+
+out_unlock:
+	mutex_unlock(&pohmelfs_config_lock);
+	if (pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL))
+		err = -ENOMEM;
+
+	return err;
+}
+
+static int pohmelfs_crypto_hash_init(struct pohmelfs_config_group *g, struct pohmelfs_crypto *c)
+{
+	char *algo = (char *)c->data;
+	u8 *key = (u8 *)(algo + c->strlen);
+
+	if (g->hash_string)
+		return -EEXIST;
+
+	g->hash_string = kstrdup(algo, GFP_KERNEL);
+	if (!g->hash_string)
+		return -ENOMEM;
+	g->hash_strlen = c->strlen;
+	g->hash_keysize = c->keysize;
+
+	g->hash_key = kmalloc(c->keysize, GFP_KERNEL);
+	if (!g->hash_key) {
+		kfree(g->hash_string);
+		return -ENOMEM;
+	}
+
+	memcpy(g->hash_key, key, c->keysize);
+
+	return 0;
+}
+
+static int pohmelfs_crypto_cipher_init(struct pohmelfs_config_group *g, struct pohmelfs_crypto *c)
+{
+	char *algo = (char *)c->data;
+	u8 *key = (u8 *)(algo + c->strlen);
+
+	if (g->cipher_string)
+		return -EEXIST;
+
+	g->cipher_string = kstrdup(algo, GFP_KERNEL);
+	if (!g->cipher_string)
+		return -ENOMEM;
+	g->cipher_strlen = c->strlen;
+	g->cipher_keysize = c->keysize;
+
+	g->cipher_key = kmalloc(c->keysize, GFP_KERNEL);
+	if (!g->cipher_key) {
+		kfree(g->cipher_string);
+		return -ENOMEM;
+	}
+
+	memcpy(g->cipher_key, key, c->keysize);
+
+	return 0;
+}
+
+
+static int pohmelfs_cn_crypto(struct cn_msg *msg)
+{
+	struct pohmelfs_crypto *crypto = (struct pohmelfs_crypto *)msg->data;
+	struct pohmelfs_config_group *g;
+	int err = 0;
+
+	dprintk("%s: idx: %u, strlen: %u, type: %u, keysize: %u, algo: %s.\n",
+			__func__, crypto->idx, crypto->strlen, crypto->type,
+			crypto->keysize, (char *)crypto->data);
+
+	mutex_lock(&pohmelfs_config_lock);
+	g = pohmelfs_find_create_config_group(crypto->idx);
+	if (!g) {
+		err = -ENOMEM;
+		goto out_unlock;
+	}
+
+	switch (crypto->type) {
+		case POHMELFS_CRYPTO_HASH:
+			err = pohmelfs_crypto_hash_init(g, crypto);
+			break;
+		case POHMELFS_CRYPTO_CIPHER:
+			err = pohmelfs_crypto_cipher_init(g, crypto);
+			break;
+		default:
+			err = -ENOTSUPP;
+			break;
+	}
+
+out_unlock:
+	mutex_unlock(&pohmelfs_config_lock);
+	if (pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL))
+		err = -ENOMEM;
+
+	return err;
+}
+
+static void pohmelfs_cn_callback(void *data)
+{
+	struct cn_msg *msg = data;
+	int err;
+
+	switch (msg->flags) {
+		case POHMELFS_FLAGS_ADD:
+			err = pohmelfs_cn_ctl(msg, POHMELFS_FLAGS_ADD);
+			break;
+		case POHMELFS_FLAGS_DEL:
+			err = pohmelfs_cn_ctl(msg, POHMELFS_FLAGS_DEL);
+			break;
+		case POHMELFS_FLAGS_SHOW:
+			err = pohmelfs_cn_disp(msg);
+			break;
+		case POHMELFS_FLAGS_CRYPTO:
+			err = pohmelfs_cn_crypto(msg);
+			break;
+		default:
+			err = -ENOSYS;
+			break;
+	}
+}
+
+int pohmelfs_config_check(struct pohmelfs_config *config, int idx)
+{
+	struct pohmelfs_ctl *ctl = &config->state.ctl;
+	struct pohmelfs_config *tmp;
+	int err = -ENOENT;
+	struct pohmelfs_ctl *sc;
+	struct pohmelfs_config_group *g;
+
+	mutex_lock(&pohmelfs_config_lock);
+
+	g = pohmelfs_find_config_group(ctl->idx);
+	if (g) {
+		list_for_each_entry(tmp, &g->config_list, config_entry) {
+			sc = &tmp->state.ctl;
+
+			if (pohmelfs_config_eql(sc, ctl)) {
+				err = 0;
+				break;
+			}
+		}
+	}
+
+	mutex_unlock(&pohmelfs_config_lock);
+
+	return err;
+}
+
+int __init pohmelfs_config_init(void)
+{
+	return cn_add_callback(&pohmelfs_cn_id, "pohmelfs", pohmelfs_cn_callback);
+}
+
+void pohmelfs_config_exit(void)
+{
+	struct pohmelfs_config *c, *tmp;
+	struct pohmelfs_config_group *g, *gtmp;
+
+	cn_del_callback(&pohmelfs_cn_id);
+
+	mutex_lock(&pohmelfs_config_lock);
+	list_for_each_entry_safe(g, gtmp, &pohmelfs_config_list, group_entry) {
+		list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
+			list_del(&c->config_entry);
+			kfree(c);
+		}
+
+		list_del(&g->group_entry);
+
+		if (g->hash_string)
+			kfree(g->hash_string);
+
+		if (g->cipher_string)
+			kfree(g->cipher_string);
+
+		kfree(g);
+	}
+	mutex_unlock(&pohmelfs_config_lock);
+}
diff --git a/drivers/staging/pohmelfs/crypto.c b/drivers/staging/pohmelfs/crypto.c
new file mode 100644
index 0000000..31d765d
--- /dev/null
+++ b/drivers/staging/pohmelfs/crypto.c
@@ -0,0 +1,880 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * 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.
+ *
+ * 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/crypto.h>
+#include <linux/highmem.h>
+#include <linux/kthread.h>
+#include <linux/pagemap.h>
+#include <linux/slab.h>
+
+#include "netfs.h"
+
+static struct crypto_hash *pohmelfs_init_hash(struct pohmelfs_sb *psb)
+{
+	int err;
+	struct crypto_hash *hash;
+
+	hash = crypto_alloc_hash(psb->hash_string, 0, CRYPTO_ALG_ASYNC);
+	if (IS_ERR(hash)) {
+		err = PTR_ERR(hash);
+		dprintk("%s: idx: %u: failed to allocate hash '%s', err: %d.\n",
+				__func__, psb->idx, psb->hash_string, err);
+		goto err_out_exit;
+	}
+
+	psb->crypto_attached_size = crypto_hash_digestsize(hash);
+
+	if (!psb->hash_keysize)
+		return hash;
+
+	err = crypto_hash_setkey(hash, psb->hash_key, psb->hash_keysize);
+	if (err) {
+		dprintk("%s: idx: %u: failed to set key for hash '%s', err: %d.\n",
+				__func__, psb->idx, psb->hash_string, err);
+		goto err_out_free;
+	}
+
+	return hash;
+
+err_out_free:
+	crypto_free_hash(hash);
+err_out_exit:
+	return ERR_PTR(err);
+}
+
+static struct crypto_ablkcipher *pohmelfs_init_cipher(struct pohmelfs_sb *psb)
+{
+	int err = -EINVAL;
+	struct crypto_ablkcipher *cipher;
+
+	if (!psb->cipher_keysize)
+		goto err_out_exit;
+
+	cipher = crypto_alloc_ablkcipher(psb->cipher_string, 0, 0);
+	if (IS_ERR(cipher)) {
+		err = PTR_ERR(cipher);
+		dprintk("%s: idx: %u: failed to allocate cipher '%s', err: %d.\n",
+				__func__, psb->idx, psb->cipher_string, err);
+		goto err_out_exit;
+	}
+
+	crypto_ablkcipher_clear_flags(cipher, ~0);
+
+	err = crypto_ablkcipher_setkey(cipher, psb->cipher_key, psb->cipher_keysize);
+	if (err) {
+		dprintk("%s: idx: %u: failed to set key for cipher '%s', err: %d.\n",
+				__func__, psb->idx, psb->cipher_string, err);
+		goto err_out_free;
+	}
+
+	return cipher;
+
+err_out_free:
+	crypto_free_ablkcipher(cipher);
+err_out_exit:
+	return ERR_PTR(err);
+}
+
+int pohmelfs_crypto_engine_init(struct pohmelfs_crypto_engine *e, struct pohmelfs_sb *psb)
+{
+	int err;
+
+	e->page_num = 0;
+
+	e->size = PAGE_SIZE;
+	e->data = kmalloc(e->size, GFP_KERNEL);
+	if (!e->data) {
+		err = -ENOMEM;
+		goto err_out_exit;
+	}
+
+	if (psb->hash_string) {
+		e->hash = pohmelfs_init_hash(psb);
+		if (IS_ERR(e->hash)) {
+			err = PTR_ERR(e->hash);
+			e->hash = NULL;
+			goto err_out_free;
+		}
+	}
+
+	if (psb->cipher_string) {
+		e->cipher = pohmelfs_init_cipher(psb);
+		if (IS_ERR(e->cipher)) {
+			err = PTR_ERR(e->cipher);
+			e->cipher = NULL;
+			goto err_out_free_hash;
+		}
+	}
+
+	return 0;
+
+err_out_free_hash:
+	crypto_free_hash(e->hash);
+err_out_free:
+	kfree(e->data);
+err_out_exit:
+	return err;
+}
+
+void pohmelfs_crypto_engine_exit(struct pohmelfs_crypto_engine *e)
+{
+	if (e->hash)
+		crypto_free_hash(e->hash);
+	if (e->cipher)
+		crypto_free_ablkcipher(e->cipher);
+	kfree(e->data);
+}
+
+static void pohmelfs_crypto_complete(struct crypto_async_request *req, int err)
+{
+	struct pohmelfs_crypto_completion *c = req->data;
+
+	if (err == -EINPROGRESS)
+		return;
+
+	dprintk("%s: req: %p, err: %d.\n", __func__, req, err);
+	c->error = err;
+	complete(&c->complete);
+}
+
+static int pohmelfs_crypto_process(struct ablkcipher_request *req,
+		struct scatterlist *sg_dst, struct scatterlist *sg_src,
+		void *iv, int enc, unsigned long timeout)
+{
+	struct pohmelfs_crypto_completion complete;
+	int err;
+
+	init_completion(&complete.complete);
+	complete.error = -EINPROGRESS;
+
+	ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+					pohmelfs_crypto_complete, &complete);
+
+	ablkcipher_request_set_crypt(req, sg_src, sg_dst, sg_src->length, iv);
+
+	if (enc)
+		err = crypto_ablkcipher_encrypt(req);
+	else
+		err = crypto_ablkcipher_decrypt(req);
+
+	switch (err) {
+		case -EINPROGRESS:
+		case -EBUSY:
+			err = wait_for_completion_interruptible_timeout(&complete.complete,
+					timeout);
+			if (!err)
+				err = -ETIMEDOUT;
+			else
+				err = complete.error;
+			break;
+		default:
+			break;
+	}
+
+	return err;
+}
+
+int pohmelfs_crypto_process_input_data(struct pohmelfs_crypto_engine *e, u64 cmd_iv,
+		void *data, struct page *page, unsigned int size)
+{
+	int err;
+	struct scatterlist sg;
+
+	if (!e->cipher && !e->hash)
+		return 0;
+
+	dprintk("%s: eng: %p, iv: %llx, data: %p, page: %p/%lu, size: %u.\n",
+		__func__, e, cmd_iv, data, page, (page)?page->index:0, size);
+
+	if (data) {
+		sg_init_one(&sg, data, size);
+	} else {
+		sg_init_table(&sg, 1);
+		sg_set_page(&sg, page, size, 0);
+	}
+
+	if (e->cipher) {
+		struct ablkcipher_request *req = e->data + crypto_hash_digestsize(e->hash);
+		u8 iv[32];
+
+		memset(iv, 0, sizeof(iv));
+		memcpy(iv, &cmd_iv, sizeof(cmd_iv));
+
+		ablkcipher_request_set_tfm(req, e->cipher);
+
+		err = pohmelfs_crypto_process(req, &sg, &sg, iv, 0, e->timeout);
+		if (err)
+			goto err_out_exit;
+	}
+
+	if (e->hash) {
+		struct hash_desc desc;
+		void *dst = e->data + e->size/2;
+
+		desc.tfm = e->hash;
+		desc.flags = 0;
+
+		err = crypto_hash_init(&desc);
+		if (err)
+			goto err_out_exit;
+
+		err = crypto_hash_update(&desc, &sg, size);
+		if (err)
+			goto err_out_exit;
+
+		err = crypto_hash_final(&desc, dst);
+		if (err)
+			goto err_out_exit;
+
+		err = !!memcmp(dst, e->data, crypto_hash_digestsize(e->hash));
+
+		if (err) {
+#ifdef CONFIG_POHMELFS_DEBUG
+			unsigned int i;
+			unsigned char *recv = e->data, *calc = dst;
+
+			dprintk("%s: eng: %p, hash: %p, cipher: %p: iv : %llx, hash mismatch (recv/calc): ",
+					__func__, e, e->hash, e->cipher, cmd_iv);
+			for (i=0; i<crypto_hash_digestsize(e->hash); ++i) {
+#if 0
+				dprintka("%02x ", recv[i]);
+				if (recv[i] != calc[i]) {
+					dprintka("| calc byte: %02x.\n", calc[i]);
+					break;
+				}
+#else
+				dprintka("%02x/%02x ", recv[i], calc[i]);
+#endif
+			}
+			dprintk("\n");
+#endif
+			goto err_out_exit;
+		} else {
+			dprintk("%s: eng: %p, hash: %p, cipher: %p: hashes matched.\n",
+					__func__, e, e->hash, e->cipher);
+		}
+	}
+
+	dprintk("%s: eng: %p, size: %u, hash: %p, cipher: %p: completed.\n",
+			__func__, e, e->size, e->hash, e->cipher);
+
+	return 0;
+
+err_out_exit:
+	dprintk("%s: eng: %p, hash: %p, cipher: %p: err: %d.\n",
+			__func__, e, e->hash, e->cipher, err);
+	return err;
+}
+
+static int pohmelfs_trans_iter(struct netfs_trans *t, struct pohmelfs_crypto_engine *e,
+		int (* iterator) (struct pohmelfs_crypto_engine *e,
+				  struct scatterlist *dst,
+				  struct scatterlist *src))
+{
+	void *data = t->iovec.iov_base + sizeof(struct netfs_cmd) + t->psb->crypto_attached_size;
+	unsigned int size = t->iovec.iov_len - sizeof(struct netfs_cmd) - t->psb->crypto_attached_size;
+	struct netfs_cmd *cmd = data;
+	unsigned int sz, pages = t->attached_pages, i, csize, cmd_cmd, dpage_idx;
+	struct scatterlist sg_src, sg_dst;
+	int err;
+
+	while (size) {
+		cmd = data;
+		cmd_cmd = __be16_to_cpu(cmd->cmd);
+		csize = __be32_to_cpu(cmd->size);
+		cmd->iv = __cpu_to_be64(e->iv);
+
+		if (cmd_cmd == NETFS_READ_PAGES || cmd_cmd == NETFS_READ_PAGE)
+			csize = __be16_to_cpu(cmd->ext);
+
+		sz = csize + __be16_to_cpu(cmd->cpad) + sizeof(struct netfs_cmd);
+
+		dprintk("%s: size: %u, sz: %u, cmd_size: %u, cmd_cpad: %u.\n",
+				__func__, size, sz, __be32_to_cpu(cmd->size), __be16_to_cpu(cmd->cpad));
+
+		data += sz;
+		size -= sz;
+
+		sg_init_one(&sg_src, cmd->data, sz - sizeof(struct netfs_cmd));
+		sg_init_one(&sg_dst, cmd->data, sz - sizeof(struct netfs_cmd));
+
+		err = iterator(e, &sg_dst, &sg_src);
+		if (err)
+			return err;
+	}
+
+	if (!pages)
+		return 0;
+
+	dpage_idx = 0;
+	for (i=0; i<t->page_num; ++i) {
+		struct page *page = t->pages[i];
+		struct page *dpage = e->pages[dpage_idx];
+
+		if (!page)
+			continue;
+
+		sg_init_table(&sg_src, 1);
+		sg_init_table(&sg_dst, 1);
+		sg_set_page(&sg_src, page, page_private(page), 0);
+		sg_set_page(&sg_dst, dpage, page_private(page), 0);
+
+		err = iterator(e, &sg_dst, &sg_src);
+		if (err)
+			return err;
+
+		pages--;
+		if (!pages)
+			break;
+		dpage_idx++;
+	}
+
+	return 0;
+}
+
+static int pohmelfs_encrypt_iterator(struct pohmelfs_crypto_engine *e,
+		struct scatterlist *sg_dst, struct scatterlist *sg_src)
+{
+	struct ablkcipher_request *req = e->data;
+	u8 iv[32];
+
+	memset(iv, 0, sizeof(iv));
+
+	memcpy(iv, &e->iv, sizeof(e->iv));
+
+	return pohmelfs_crypto_process(req, sg_dst, sg_src, iv, 1, e->timeout);
+}
+
+static int pohmelfs_encrypt(struct pohmelfs_crypto_thread *tc)
+{
+	struct netfs_trans *t = tc->trans;
+	struct pohmelfs_crypto_engine *e = &tc->eng;
+	struct ablkcipher_request *req = e->data;
+
+	memset(req, 0, sizeof(struct ablkcipher_request));
+	ablkcipher_request_set_tfm(req, e->cipher);
+
+	e->iv = pohmelfs_gen_iv(t);
+
+	return pohmelfs_trans_iter(t, e, pohmelfs_encrypt_iterator);
+}
+
+static int pohmelfs_hash_iterator(struct pohmelfs_crypto_engine *e,
+		struct scatterlist *sg_dst, struct scatterlist *sg_src)
+{
+	return crypto_hash_update(e->data, sg_src, sg_src->length);
+}
+
+static int pohmelfs_hash(struct pohmelfs_crypto_thread *tc)
+{
+	struct pohmelfs_crypto_engine *e = &tc->eng;
+	struct hash_desc *desc = e->data;
+	unsigned char *dst = tc->trans->iovec.iov_base + sizeof(struct netfs_cmd);
+	int err;
+
+	desc->tfm = e->hash;
+	desc->flags = 0;
+
+	err = crypto_hash_init(desc);
+	if (err)
+		return err;
+
+	err = pohmelfs_trans_iter(tc->trans, e, pohmelfs_hash_iterator);
+	if (err)
+		return err;
+
+	err = crypto_hash_final(desc, dst);
+	if (err)
+		return err;
+
+	{
+		unsigned int i;
+		dprintk("%s: ", __func__);
+		for (i=0; i<tc->psb->crypto_attached_size; ++i)
+			dprintka("%02x ", dst[i]);
+		dprintka("\n");
+	}
+
+	return 0;
+}
+
+static void pohmelfs_crypto_pages_free(struct pohmelfs_crypto_engine *e)
+{
+	unsigned int i;
+
+	for (i=0; i<e->page_num; ++i)
+		__free_page(e->pages[i]);
+	kfree(e->pages);
+}
+
+static int pohmelfs_crypto_pages_alloc(struct pohmelfs_crypto_engine *e, struct pohmelfs_sb *psb)
+{
+	unsigned int i;
+
+	e->pages = kmalloc(psb->trans_max_pages * sizeof(struct page *), GFP_KERNEL);
+	if (!e->pages)
+		return -ENOMEM;
+
+	for (i=0; i<psb->trans_max_pages; ++i) {
+		e->pages[i] = alloc_page(GFP_KERNEL);
+		if (!e->pages[i])
+			break;
+	}
+
+	e->page_num = i;
+	if (!e->page_num)
+		goto err_out_free;
+
+	return 0;
+
+err_out_free:
+	kfree(e->pages);
+	return -ENOMEM;
+}
+
+static void pohmelfs_sys_crypto_exit_one(struct pohmelfs_crypto_thread *t)
+{
+	struct pohmelfs_sb *psb = t->psb;
+
+	if (t->thread)
+		kthread_stop(t->thread);
+
+	mutex_lock(&psb->crypto_thread_lock);
+	list_del(&t->thread_entry);
+	psb->crypto_thread_num--;
+	mutex_unlock(&psb->crypto_thread_lock);
+
+	pohmelfs_crypto_engine_exit(&t->eng);
+	pohmelfs_crypto_pages_free(&t->eng);
+	kfree(t);
+}
+
+static int pohmelfs_crypto_finish(struct netfs_trans *t, struct pohmelfs_sb *psb, int err)
+{
+	struct netfs_cmd *cmd = t->iovec.iov_base;
+	netfs_convert_cmd(cmd);
+
+	if (likely(!err))
+		err = netfs_trans_finish_send(t, psb);
+
+	t->result = err;
+	netfs_trans_put(t);
+
+	return err;
+}
+
+void pohmelfs_crypto_thread_make_ready(struct pohmelfs_crypto_thread *th)
+{
+	struct pohmelfs_sb *psb = th->psb;
+
+	th->page = NULL;
+	th->trans = NULL;
+
+	mutex_lock(&psb->crypto_thread_lock);
+	list_move_tail(&th->thread_entry, &psb->crypto_ready_list);
+	mutex_unlock(&psb->crypto_thread_lock);
+	wake_up(&psb->wait);
+}
+
+static int pohmelfs_crypto_thread_trans(struct pohmelfs_crypto_thread *t)
+{
+	struct netfs_trans *trans;
+	int err = 0;
+
+	trans = t->trans;
+	trans->eng = NULL;
+
+	if (t->eng.hash) {
+		err = pohmelfs_hash(t);
+		if (err)
+			goto out_complete;
+	}
+
+	if (t->eng.cipher) {
+		err = pohmelfs_encrypt(t);
+		if (err)
+			goto out_complete;
+		trans->eng = &t->eng;
+	}
+
+out_complete:
+	t->page = NULL;
+	t->trans = NULL;
+
+	if (!trans->eng)
+		pohmelfs_crypto_thread_make_ready(t);
+
+	pohmelfs_crypto_finish(trans, t->psb, err);
+	return err;
+}
+
+static int pohmelfs_crypto_thread_page(struct pohmelfs_crypto_thread *t)
+{
+	struct pohmelfs_crypto_engine *e = &t->eng;
+	struct page *page = t->page;
+	int err;
+
+	WARN_ON(!PageChecked(page));
+
+	err = pohmelfs_crypto_process_input_data(e, e->iv, NULL, page, t->size);
+	if (!err)
+		SetPageUptodate(page);
+	else
+		SetPageError(page);
+	unlock_page(page);
+	page_cache_release(page);
+
+	pohmelfs_crypto_thread_make_ready(t);
+
+	return err;
+}
+
+static int pohmelfs_crypto_thread_func(void *data)
+{
+	struct pohmelfs_crypto_thread *t = data;
+
+	while (!kthread_should_stop()) {
+		wait_event_interruptible(t->wait, kthread_should_stop() ||
+				t->trans || t->page);
+
+		if (kthread_should_stop())
+			break;
+
+		if (!t->trans && !t->page)
+			continue;
+
+		dprintk("%s: thread: %p, trans: %p, page: %p.\n",
+				__func__, t, t->trans, t->page);
+
+		if (t->trans)
+			pohmelfs_crypto_thread_trans(t);
+		else if (t->page)
+			pohmelfs_crypto_thread_page(t);
+	}
+
+	return 0;
+}
+
+static void pohmelfs_crypto_flush(struct pohmelfs_sb *psb, struct list_head *head)
+{
+	while (!list_empty(head)) {
+		struct pohmelfs_crypto_thread *t = NULL;
+
+		mutex_lock(&psb->crypto_thread_lock);
+		if (!list_empty(head)) {
+			t = list_first_entry(head, struct pohmelfs_crypto_thread, thread_entry);
+			list_del_init(&t->thread_entry);
+		}
+		mutex_unlock(&psb->crypto_thread_lock);
+
+		if (t)
+			pohmelfs_sys_crypto_exit_one(t);
+	}
+}
+
+static void pohmelfs_sys_crypto_exit(struct pohmelfs_sb *psb)
+{
+	while (!list_empty(&psb->crypto_active_list) || !list_empty(&psb->crypto_ready_list)) {
+		dprintk("%s: crypto_thread_num: %u.\n", __func__, psb->crypto_thread_num);
+		pohmelfs_crypto_flush(psb, &psb->crypto_active_list);
+		pohmelfs_crypto_flush(psb, &psb->crypto_ready_list);
+	}
+}
+
+static int pohmelfs_sys_crypto_init(struct pohmelfs_sb *psb)
+{
+	unsigned int i;
+	struct pohmelfs_crypto_thread *t;
+	struct pohmelfs_config *c;
+	struct netfs_state *st;
+	int err;
+
+	list_for_each_entry(c, &psb->state_list, config_entry) {
+		st = &c->state;
+
+		err = pohmelfs_crypto_engine_init(&st->eng, psb);
+		if (err)
+			goto err_out_exit;
+
+		dprintk("%s: st: %p, eng: %p, hash: %p, cipher: %p.\n",
+				__func__, st, &st->eng, &st->eng.hash, &st->eng.cipher);
+	}
+
+	for (i=0; i<psb->crypto_thread_num; ++i) {
+		err = -ENOMEM;
+		t = kzalloc(sizeof(struct pohmelfs_crypto_thread), GFP_KERNEL);
+		if (!t)
+			goto err_out_free_state_engines;
+
+		init_waitqueue_head(&t->wait);
+
+		t->psb = psb;
+		t->trans = NULL;
+		t->eng.thread = t;
+
+		err = pohmelfs_crypto_engine_init(&t->eng, psb);
+		if (err)
+			goto err_out_free_state_engines;
+
+		err = pohmelfs_crypto_pages_alloc(&t->eng, psb);
+		if (err)
+			goto err_out_free;
+
+		t->thread = kthread_run(pohmelfs_crypto_thread_func, t,
+				"pohmelfs-crypto-%d-%d", psb->idx, i);
+		if (IS_ERR(t->thread)) {
+			err = PTR_ERR(t->thread);
+			t->thread = NULL;
+			goto err_out_free;
+		}
+
+		if (t->eng.cipher)
+			psb->crypto_align_size = crypto_ablkcipher_blocksize(t->eng.cipher);
+
+		mutex_lock(&psb->crypto_thread_lock);
+		list_add_tail(&t->thread_entry, &psb->crypto_ready_list);
+		mutex_unlock(&psb->crypto_thread_lock);
+	}
+
+	psb->crypto_thread_num = i;
+	return 0;
+
+err_out_free:
+	pohmelfs_sys_crypto_exit_one(t);
+err_out_free_state_engines:
+	list_for_each_entry(c, &psb->state_list, config_entry) {
+		st = &c->state;
+		pohmelfs_crypto_engine_exit(&st->eng);
+	}
+err_out_exit:
+	pohmelfs_sys_crypto_exit(psb);
+	return err;
+}
+
+void pohmelfs_crypto_exit(struct pohmelfs_sb *psb)
+{
+	pohmelfs_sys_crypto_exit(psb);
+
+	kfree(psb->hash_string);
+	kfree(psb->cipher_string);
+}
+
+static int pohmelfs_crypt_init_complete(struct page **pages, unsigned int page_num,
+		void *private, int err)
+{
+	struct pohmelfs_sb *psb = private;
+
+	psb->flags = -err;
+	dprintk("%s: err: %d.\n", __func__, err);
+
+	wake_up(&psb->wait);
+
+	return err;
+}
+
+static int pohmelfs_crypto_init_handshake(struct pohmelfs_sb *psb)
+{
+	struct netfs_trans *t;
+	struct netfs_crypto_capabilities *cap;
+	struct netfs_cmd *cmd;
+	char *str;
+	int err = -ENOMEM, size;
+
+	size = sizeof(struct netfs_crypto_capabilities) +
+		psb->cipher_strlen + psb->hash_strlen + 2; /* 0 bytes */
+
+	t = netfs_trans_alloc(psb, size, 0, 0);
+	if (!t)
+		goto err_out_exit;
+
+	t->complete = pohmelfs_crypt_init_complete;
+	t->private = psb;
+
+	cmd = netfs_trans_current(t);
+	cap = (struct netfs_crypto_capabilities *)(cmd + 1);
+	str = (char *)(cap + 1);
+
+	cmd->cmd = NETFS_CAPABILITIES;
+	cmd->id = POHMELFS_CRYPTO_CAPABILITIES;
+	cmd->size = size;
+	cmd->start = 0;
+	cmd->ext = 0;
+	cmd->csize = 0;
+
+	netfs_convert_cmd(cmd);
+	netfs_trans_update(cmd, t, size);
+
+	cap->hash_strlen = psb->hash_strlen;
+	if (cap->hash_strlen) {
+		sprintf(str, "%s", psb->hash_string);
+		str += cap->hash_strlen;
+	}
+
+	cap->cipher_strlen = psb->cipher_strlen;
+	cap->cipher_keysize = psb->cipher_keysize;
+	if (cap->cipher_strlen)
+		sprintf(str, "%s", psb->cipher_string);
+
+	netfs_convert_crypto_capabilities(cap);
+
+	psb->flags = ~0;
+	err = netfs_trans_finish(t, psb);
+	if (err)
+		goto err_out_exit;
+
+	err = wait_event_interruptible_timeout(psb->wait, (psb->flags != ~0),
+			psb->wait_on_page_timeout);
+	if (!err)
+		err = -ETIMEDOUT;
+	else
+		err = -psb->flags;
+
+	if (!err)
+		psb->perform_crypto = 1;
+	psb->flags = 0;
+
+	/*
+	 * At this point NETFS_CAPABILITIES response command
+	 * should setup superblock in a way, which is acceptible
+	 * for both client and server, so if server refuses connection,
+	 * it will send error in transaction response.
+	 */
+
+	if (err)
+		goto err_out_exit;
+
+	return 0;
+
+err_out_exit:
+	return err;
+}
+
+int pohmelfs_crypto_init(struct pohmelfs_sb *psb)
+{
+	int err;
+
+	if (!psb->cipher_string && !psb->hash_string)
+		return 0;
+
+	err = pohmelfs_crypto_init_handshake(psb);
+	if (err)
+		return err;
+
+	err = pohmelfs_sys_crypto_init(psb);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static int pohmelfs_crypto_thread_get(struct pohmelfs_sb *psb,
+		int (* action)(struct pohmelfs_crypto_thread *t, void *data), void *data)
+{
+	struct pohmelfs_crypto_thread *t = NULL;
+	int err;
+
+	while (!t) {
+		err = wait_event_interruptible_timeout(psb->wait,
+				!list_empty(&psb->crypto_ready_list),
+				psb->wait_on_page_timeout);
+
+		t = NULL;
+		err = 0;
+		mutex_lock(&psb->crypto_thread_lock);
+		if (!list_empty(&psb->crypto_ready_list)) {
+			t = list_entry(psb->crypto_ready_list.prev,
+					struct pohmelfs_crypto_thread,
+					thread_entry);
+
+			list_move_tail(&t->thread_entry,
+					&psb->crypto_active_list);
+
+			action(t, data);
+			wake_up(&t->wait);
+
+		}
+		mutex_unlock(&psb->crypto_thread_lock);
+	}
+
+	return err;
+}
+
+static int pohmelfs_trans_crypt_action(struct pohmelfs_crypto_thread *t, void *data)
+{
+	struct netfs_trans *trans = data;
+
+	netfs_trans_get(trans);
+	t->trans = trans;
+
+	dprintk("%s: t: %p, gen: %u, thread: %p.\n", __func__, trans, trans->gen, t);
+	return 0;
+}
+
+int pohmelfs_trans_crypt(struct netfs_trans *trans, struct pohmelfs_sb *psb)
+{
+	if ((!psb->hash_string && !psb->cipher_string) || !psb->perform_crypto) {
+		netfs_trans_get(trans);
+		return pohmelfs_crypto_finish(trans, psb, 0);
+	}
+
+	return pohmelfs_crypto_thread_get(psb, pohmelfs_trans_crypt_action, trans);
+}
+
+struct pohmelfs_crypto_input_action_data
+{
+	struct page			*page;
+	struct pohmelfs_crypto_engine	*e;
+	u64				iv;
+	unsigned int			size;
+};
+
+static int pohmelfs_crypt_input_page_action(struct pohmelfs_crypto_thread *t, void *data)
+{
+	struct pohmelfs_crypto_input_action_data *act = data;
+
+	memcpy(t->eng.data, act->e->data, t->psb->crypto_attached_size);
+
+	t->size = act->size;
+	t->eng.iv = act->iv;
+
+	t->page = act->page;
+	return 0;
+}
+
+int pohmelfs_crypto_process_input_page(struct pohmelfs_crypto_engine *e,
+		struct page *page, unsigned int size, u64 iv)
+{
+	struct inode *inode = page->mapping->host;
+	struct pohmelfs_crypto_input_action_data act;
+	int err = -ENOENT;
+
+	act.page = page;
+	act.e = e;
+	act.size = size;
+	act.iv = iv;
+
+	err = pohmelfs_crypto_thread_get(POHMELFS_SB(inode->i_sb),
+			pohmelfs_crypt_input_page_action, &act);
+	if (err)
+		goto err_out_exit;
+
+	return 0;
+
+err_out_exit:
+	SetPageUptodate(page);
+	page_cache_release(page);
+
+	return err;
+}
diff --git a/drivers/staging/pohmelfs/dir.c b/drivers/staging/pohmelfs/dir.c
new file mode 100644
index 0000000..7a41183
--- /dev/null
+++ b/drivers/staging/pohmelfs/dir.c
@@ -0,0 +1,1093 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * 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.
+ *
+ * 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/fs.h>
+#include <linux/jhash.h>
+#include <linux/namei.h>
+#include <linux/pagemap.h>
+
+#include "netfs.h"
+
+static int pohmelfs_cmp_hash(struct pohmelfs_name *n, u32 hash)
+{
+	if (n->hash > hash)
+		return -1;
+	if (n->hash < hash)
+		return 1;
+
+	return 0;
+}
+
+static struct pohmelfs_name *pohmelfs_search_hash_unprecise(struct pohmelfs_inode *pi, u32 hash)
+{
+	struct rb_node *n = pi->hash_root.rb_node;
+	struct pohmelfs_name *tmp = NULL;
+	int cmp;
+
+	while (n) {
+		tmp = rb_entry(n, struct pohmelfs_name, hash_node);
+
+		cmp = pohmelfs_cmp_hash(tmp, hash);
+		if (cmp < 0)
+			n = n->rb_left;
+		else if (cmp > 0)
+			n = n->rb_right;
+		else
+			break;
+
+	}
+
+	return tmp;
+}
+
+struct pohmelfs_name *pohmelfs_search_hash(struct pohmelfs_inode *pi, u32 hash)
+{
+	struct pohmelfs_name *tmp;
+
+	tmp = pohmelfs_search_hash_unprecise(pi, hash);
+	if (tmp && (tmp->hash == hash))
+		return tmp;
+
+	return NULL;
+}
+
+static void __pohmelfs_name_del(struct pohmelfs_inode *parent, struct pohmelfs_name *node)
+{
+	rb_erase(&node->hash_node, &parent->hash_root);
+}
+
+/*
+ * Remove name cache entry from its caches and free it.
+ */
+static void pohmelfs_name_free(struct pohmelfs_inode *parent, struct pohmelfs_name *node)
+{
+	__pohmelfs_name_del(parent, node);
+	list_del(&node->sync_create_entry);
+	kfree(node);
+}
+
+static struct pohmelfs_name *pohmelfs_insert_hash(struct pohmelfs_inode *pi,
+		struct pohmelfs_name *new)
+{
+	struct rb_node **n = &pi->hash_root.rb_node, *parent = NULL;
+	struct pohmelfs_name *ret = NULL, *tmp;
+	int cmp;
+
+	while (*n) {
+		parent = *n;
+
+		tmp = rb_entry(parent, struct pohmelfs_name, hash_node);
+
+		cmp = pohmelfs_cmp_hash(tmp, new->hash);
+		if (cmp < 0)
+			n = &parent->rb_left;
+		else if (cmp > 0)
+			n = &parent->rb_right;
+		else {
+			ret = tmp;
+			break;
+		}
+	}
+
+	if (ret) {
+		printk("%s: exist: parent: %llu, ino: %llu, hash: %x, len: %u, data: '%s', "
+				           "new: ino: %llu, hash: %x, len: %u, data: '%s'.\n",
+				__func__, pi->ino,
+				ret->ino, ret->hash, ret->len, ret->data,
+				new->ino, new->hash, new->len, new->data);
+		ret->ino = new->ino;
+		return ret;
+	}
+
+	rb_link_node(&new->hash_node, parent, n);
+	rb_insert_color(&new->hash_node, &pi->hash_root);
+
+	return NULL;
+}
+
+/*
+ * Free name cache for given inode.
+ */
+void pohmelfs_free_names(struct pohmelfs_inode *parent)
+{
+	struct rb_node *rb_node;
+	struct pohmelfs_name *n;
+
+	for (rb_node = rb_first(&parent->hash_root); rb_node;) {
+		n = rb_entry(rb_node, struct pohmelfs_name, hash_node);
+		rb_node = rb_next(rb_node);
+
+		pohmelfs_name_free(parent, n);
+	}
+}
+
+static void pohmelfs_fix_offset(struct pohmelfs_inode *parent, struct pohmelfs_name *node)
+{
+	parent->total_len -= node->len;
+}
+
+/*
+ * Free name cache entry helper.
+ */
+void pohmelfs_name_del(struct pohmelfs_inode *parent, struct pohmelfs_name *node)
+{
+	pohmelfs_fix_offset(parent, node);
+	pohmelfs_name_free(parent, node);
+}
+
+/*
+ * Insert new name cache entry into all hash cache.
+ */
+static int pohmelfs_insert_name(struct pohmelfs_inode *parent, struct pohmelfs_name *n)
+{
+	struct pohmelfs_name *name;
+
+	name = pohmelfs_insert_hash(parent, n);
+	if (name)
+		return -EEXIST;
+
+	parent->total_len += n->len;
+	list_add_tail(&n->sync_create_entry, &parent->sync_create_list);
+
+	return 0;
+}
+
+/*
+ * Allocate new name cache entry.
+ */
+static struct pohmelfs_name *pohmelfs_name_alloc(unsigned int len)
+{
+	struct pohmelfs_name *n;
+
+	n = kzalloc(sizeof(struct pohmelfs_name) + len, GFP_KERNEL);
+	if (!n)
+		return NULL;
+
+	INIT_LIST_HEAD(&n->sync_create_entry);
+
+	n->data = (char *)(n+1);
+
+	return n;
+}
+
+/*
+ * Add new name entry into directory's cache.
+ */
+static int pohmelfs_add_dir(struct pohmelfs_sb *psb, struct pohmelfs_inode *parent,
+		struct pohmelfs_inode *npi, struct qstr *str, unsigned int mode, int link)
+{
+	int err = -ENOMEM;
+	struct pohmelfs_name *n;
+
+	n = pohmelfs_name_alloc(str->len + 1);
+	if (!n)
+		goto err_out_exit;
+
+	n->ino = npi->ino;
+	n->mode = mode;
+	n->len = str->len;
+	n->hash = str->hash;
+	sprintf(n->data, "%s", str->name);
+
+	mutex_lock(&parent->offset_lock);
+	err = pohmelfs_insert_name(parent, n);
+	mutex_unlock(&parent->offset_lock);
+
+	if (err) {
+		if (err != -EEXIST)
+			goto err_out_free;
+		kfree(n);
+	}
+
+	return 0;
+
+err_out_free:
+	kfree(n);
+err_out_exit:
+	return err;
+}
+
+/*
+ * Create new inode for given parameters (name, inode info, parent).
+ * This does not create object on the server, it will be synced there during writeback.
+ */
+struct pohmelfs_inode *pohmelfs_new_inode(struct pohmelfs_sb *psb,
+		struct pohmelfs_inode *parent, struct qstr *str,
+		struct netfs_inode_info *info, int link)
+{
+	struct inode *new = NULL;
+	struct pohmelfs_inode *npi;
+	int err = -EEXIST;
+
+	dprintk("%s: creating inode: parent: %llu, ino: %llu, str: %p.\n",
+			__func__, (parent)?parent->ino:0, info->ino, str);
+
+	err = -ENOMEM;
+	new = iget_locked(psb->sb, info->ino);
+	if (!new)
+		goto err_out_exit;
+
+	npi = POHMELFS_I(new);
+	npi->ino = info->ino;
+	err = 0;
+
+	if (new->i_state & I_NEW) {
+		dprintk("%s: filling VFS inode: %lu/%llu.\n",
+				__func__, new->i_ino, info->ino);
+		pohmelfs_fill_inode(new, info);
+
+		if (S_ISDIR(info->mode)) {
+			struct qstr s;
+
+			s.name = ".";
+			s.len = 1;
+			s.hash = jhash(s.name, s.len, 0);
+
+			err = pohmelfs_add_dir(psb, npi, npi, &s, info->mode, 0);
+			if (err)
+				goto err_out_put;
+
+			s.name = "..";
+			s.len = 2;
+			s.hash = jhash(s.name, s.len, 0);
+
+			err = pohmelfs_add_dir(psb, npi, (parent)?parent:npi, &s,
+					(parent)?parent->vfs_inode.i_mode:npi->vfs_inode.i_mode, 0);
+			if (err)
+				goto err_out_put;
+		}
+	}
+
+	if (str) {
+		if (parent) {
+			err = pohmelfs_add_dir(psb, parent, npi, str, info->mode, link);
+
+			dprintk("%s: %s inserted name: '%s', new_offset: %llu, ino: %llu, parent: %llu.\n",
+					__func__, (err)?"unsuccessfully":"successfully",
+					str->name, parent->total_len, info->ino, parent->ino);
+
+			if (err && err != -EEXIST)
+				goto err_out_put;
+		}
+	}
+
+	if (new->i_state & I_NEW) {
+		if (parent)
+			mark_inode_dirty(&parent->vfs_inode);
+		mark_inode_dirty(new);
+	}
+
+	set_bit(NETFS_INODE_OWNED, &npi->state);
+	npi->lock_type = POHMELFS_WRITE_LOCK;
+	unlock_new_inode(new);
+
+	return npi;
+
+err_out_put:
+	printk("%s: putting inode: %p, npi: %p, error: %d.\n", __func__, new, npi, err);
+	iput(new);
+err_out_exit:
+	return ERR_PTR(err);
+}
+
+static int pohmelfs_remote_sync_complete(struct page **pages, unsigned int page_num,
+		void *private, int err)
+{
+	struct pohmelfs_inode *pi = private;
+	struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
+
+	dprintk("%s: ino: %llu, err: %d.\n", __func__, pi->ino, err);
+
+	if (err)
+		pi->error = err;
+	wake_up(&psb->wait);
+	pohmelfs_put_inode(pi);
+
+	return err;
+}
+
+/*
+ * Receive directory content from the server.
+ * This should be only done for objects, which were not created locally,
+ * and which were not synced previously.
+ */
+static int pohmelfs_sync_remote_dir(struct pohmelfs_inode *pi)
+{
+	struct inode *inode = &pi->vfs_inode;
+	struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+	long ret = msecs_to_jiffies(25000);
+	int err;
+
+	dprintk("%s: dir: %llu, state: %lx: remote_synced: %d.\n",
+		__func__, pi->ino, pi->state, test_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state));
+
+	if (test_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &pi->state))
+		return 0;
+
+	if (!igrab(inode)) {
+		err = -ENOENT;
+		goto err_out_exit;
+	}
+
+	err = pohmelfs_meta_command(pi, NETFS_READDIR, NETFS_TRANS_SINGLE_DST,
+			pohmelfs_remote_sync_complete, pi, 0);
+	if (err)
+		goto err_out_exit;
+
+	pi->error = 0;
+	ret = wait_event_interruptible_timeout(psb->wait,
+			test_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &pi->state) || pi->error, ret);
+	dprintk("%s: awake dir: %llu, ret: %ld, err: %d.\n", __func__, pi->ino, ret, pi->error);
+	if (ret <= 0) {
+		err = -ETIMEDOUT;
+		goto err_out_exit;
+	}
+
+	if (pi->error)
+		return pi->error;
+
+	return 0;
+
+err_out_exit:
+	clear_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);
+
+	return err;
+}
+
+static int pohmelfs_dir_open(struct inode *inode, struct file *file)
+{
+	file->private_data = NULL;
+	return 0;
+}
+
+/*
+ * VFS readdir callback. Syncs directory content from server if needed,
+ * and provides direntry info to the userspace.
+ */
+static int pohmelfs_readdir(struct file *file, void *dirent, filldir_t filldir)
+{
+	struct inode *inode = file->f_path.dentry->d_inode;
+	struct pohmelfs_inode *pi = POHMELFS_I(inode);
+	struct pohmelfs_name *n;
+	struct rb_node *rb_node;
+	int err = 0, mode;
+	u64 len;
+
+	dprintk("%s: parent: %llu, fpos: %llu, hash: %08lx.\n",
+			__func__, pi->ino, (u64)file->f_pos,
+			(unsigned long)file->private_data);
+
+	err = pohmelfs_data_lock(pi, 0, ~0, POHMELFS_READ_LOCK);
+	if (err)
+		return err;
+
+	err = pohmelfs_sync_remote_dir(pi);
+	if (err)
+		return err;
+
+	if (file->private_data && (file->private_data == (void *)(unsigned long)file->f_pos))
+		return 0;
+
+	mutex_lock(&pi->offset_lock);
+	n = pohmelfs_search_hash_unprecise(pi, (unsigned long)file->private_data);
+
+	while (n) {
+		mode = (n->mode >> 12) & 15;
+
+		dprintk("%s: offset: %llu, parent ino: %llu, name: '%s', len: %u, ino: %llu, "
+				"mode: %o/%o, fpos: %llu, hash: %08x.\n",
+				__func__, file->f_pos, pi->ino, n->data, n->len,
+				n->ino, n->mode, mode, file->f_pos, n->hash);
+
+		file->private_data = (void *)n->hash;
+
+		len = n->len;
+		err = filldir(dirent, n->data, n->len, file->f_pos, n->ino, mode);
+
+		if (err < 0) {
+			dprintk("%s: err: %d.\n", __func__, err);
+			err = 0;
+			break;
+		}
+
+		file->f_pos += len;
+
+		rb_node = rb_next(&n->hash_node);
+
+		if (!rb_node || (rb_node == &n->hash_node)) {
+			file->private_data = (void *)(unsigned long)file->f_pos;
+			break;
+		}
+
+		n = rb_entry(rb_node, struct pohmelfs_name, hash_node);
+	}
+	mutex_unlock(&pi->offset_lock);
+
+	return err;
+}
+
+static loff_t pohmelfs_dir_lseek(struct file *file, loff_t offset, int origin)
+{
+	file->f_pos = offset;
+	file->private_data = NULL;
+	return offset;
+}
+
+const struct file_operations pohmelfs_dir_fops = {
+	.open = pohmelfs_dir_open,
+	.read = generic_read_dir,
+	.llseek = pohmelfs_dir_lseek,
+	.readdir = pohmelfs_readdir,
+};
+
+/*
+ * Lookup single object on server.
+ */
+static int pohmelfs_lookup_single(struct pohmelfs_inode *parent,
+		struct qstr *str, u64 ino)
+{
+	struct pohmelfs_sb *psb = POHMELFS_SB(parent->vfs_inode.i_sb);
+	long ret = msecs_to_jiffies(5000);
+	int err;
+
+	set_bit(NETFS_COMMAND_PENDING, &parent->state);
+	err = pohmelfs_meta_command_data(parent, parent->ino, NETFS_LOOKUP,
+			(char *)str->name, NETFS_TRANS_SINGLE_DST, NULL, NULL, ino);
+	if (err)
+		goto err_out_exit;
+
+	err = 0;
+	ret = wait_event_interruptible_timeout(psb->wait,
+			!test_bit(NETFS_COMMAND_PENDING, &parent->state), ret);
+	if (ret == 0)
+		err = -ETIMEDOUT;
+	else if (signal_pending(current))
+		err = -EINTR;
+
+	if (err)
+		goto err_out_exit;
+
+	return 0;
+
+err_out_exit:
+	clear_bit(NETFS_COMMAND_PENDING, &parent->state);
+
+	printk("%s: failed: parent: %llu, ino: %llu, name: '%s', err: %d.\n",
+			__func__, parent->ino, ino, str->name, err);
+
+	return err;
+}
+
+/*
+ * VFS lookup callback.
+ * We first try to get inode number from local name cache, if we have one,
+ * then inode can be found in inode cache. If there is no inode or no object in
+ * local cache, try to lookup it on server. This only should be done for directories,
+ * which were not created locally, otherwise remote server does not know about dir at all,
+ * so no need to try to know that.
+ */
+struct dentry *pohmelfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+{
+	struct pohmelfs_inode *parent = POHMELFS_I(dir);
+	struct pohmelfs_name *n;
+	struct inode *inode = NULL;
+	unsigned long ino = 0;
+	int err, lock_type = POHMELFS_READ_LOCK, need_lock;
+	struct qstr str = dentry->d_name;
+
+	if ((nd->intent.open.flags & O_ACCMODE) > 1)
+		lock_type = POHMELFS_WRITE_LOCK;
+
+	need_lock = pohmelfs_need_lock(parent, lock_type);
+
+	err = pohmelfs_data_lock(parent, 0, ~0, lock_type);
+	if (err)
+		goto out;
+
+	str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
+
+	mutex_lock(&parent->offset_lock);
+	n = pohmelfs_search_hash(parent, str.hash);
+	if (n)
+		ino = n->ino;
+	mutex_unlock(&parent->offset_lock);
+
+	dprintk("%s: 1 ino: %lu, inode: %p, name: '%s', hash: %x, parent_state: %lx.\n",
+			__func__, ino, inode, str.name, str.hash, parent->state);
+
+	if (ino) {
+		inode = ilookup(dir->i_sb, ino);
+		if (inode)
+			goto out;
+	}
+
+	dprintk("%s: dir: %p, dir_ino: %llu, name: '%s', len: %u, dir_state: %lx, ino: %lu.\n",
+			__func__, dir, parent->ino,
+			str.name, str.len, parent->state, ino);
+
+	if (!ino) {
+		if (!need_lock)
+			goto out;
+	}
+
+	err = pohmelfs_lookup_single(parent, &str, ino);
+	if (err)
+		goto out;
+
+	if (!ino) {
+		mutex_lock(&parent->offset_lock);
+		n = pohmelfs_search_hash(parent, str.hash);
+		if (n)
+			ino = n->ino;
+		mutex_unlock(&parent->offset_lock);
+	}
+
+	if (ino) {
+		inode = ilookup(dir->i_sb, ino);
+		printk("%s: second lookup ino: %lu, inode: %p, name: '%s', hash: %x.\n",
+				__func__, ino, inode, str.name, str.hash);
+		if (!inode) {
+			printk("%s: No inode for ino: %lu, name: '%s', hash: %x.\n",
+				__func__, ino, str.name, str.hash);
+			//return NULL;
+			return ERR_PTR(-EACCES);
+		}
+	} else {
+		printk("%s: No inode number : name: '%s', hash: %x.\n",
+			__func__, str.name, str.hash);
+	}
+out:
+	return d_splice_alias(inode, dentry);
+}
+
+/*
+ * Create new object in local cache. Object will be synced to server
+ * during writeback for given inode.
+ */
+struct pohmelfs_inode *pohmelfs_create_entry_local(struct pohmelfs_sb *psb,
+	struct pohmelfs_inode *parent, struct qstr *str, u64 start, int mode)
+{
+	struct pohmelfs_inode *npi;
+	int err = -ENOMEM;
+	struct netfs_inode_info info;
+
+	dprintk("%s: name: '%s', mode: %o, start: %llu.\n",
+			__func__, str->name, mode, start);
+
+	info.mode = mode;
+	info.ino = start;
+
+	if (!start)
+		info.ino = pohmelfs_new_ino(psb);
+
+	info.nlink = S_ISDIR(mode)?2:1;
+	info.uid = current_fsuid();
+	info.gid = current_fsgid();
+	info.size = 0;
+	info.blocksize = 512;
+	info.blocks = 0;
+	info.rdev = 0;
+	info.version = 0;
+
+	npi = pohmelfs_new_inode(psb, parent, str, &info, !!start);
+	if (IS_ERR(npi)) {
+		err = PTR_ERR(npi);
+		goto err_out_unlock;
+	}
+
+	return npi;
+
+err_out_unlock:
+	dprintk("%s: err: %d.\n", __func__, err);
+	return ERR_PTR(err);
+}
+
+/*
+ * Create local object and bind it to dentry.
+ */
+static int pohmelfs_create_entry(struct inode *dir, struct dentry *dentry, u64 start, int mode)
+{
+	struct pohmelfs_sb *psb = POHMELFS_SB(dir->i_sb);
+	struct pohmelfs_inode *npi, *parent;
+	struct qstr str = dentry->d_name;
+	int err;
+
+	parent = POHMELFS_I(dir);
+
+	err = pohmelfs_data_lock(parent, 0, ~0, POHMELFS_WRITE_LOCK);
+	if (err)
+		return err;
+
+	str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
+
+	npi = pohmelfs_create_entry_local(psb, parent, &str, start, mode);
+	if (IS_ERR(npi))
+		return PTR_ERR(npi);
+
+	d_instantiate(dentry, &npi->vfs_inode);
+
+	dprintk("%s: parent: %llu, inode: %llu, name: '%s', parent_nlink: %d, nlink: %d.\n",
+			__func__, parent->ino, npi->ino, dentry->d_name.name,
+			(signed)dir->i_nlink, (signed)npi->vfs_inode.i_nlink);
+
+	return 0;
+}
+
+/*
+ * VFS create and mkdir callbacks.
+ */
+static int pohmelfs_create(struct inode *dir, struct dentry *dentry, int mode,
+		struct nameidata *nd)
+{
+	return pohmelfs_create_entry(dir, dentry, 0, mode);
+}
+
+static int pohmelfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+	int err;
+
+	inode_inc_link_count(dir);
+	err = pohmelfs_create_entry(dir, dentry, 0, mode | S_IFDIR);
+	if (err)
+		inode_dec_link_count(dir);
+
+	return err;
+}
+
+static int pohmelfs_remove_entry(struct inode *dir, struct dentry *dentry)
+{
+	struct pohmelfs_sb *psb = POHMELFS_SB(dir->i_sb);
+	struct inode *inode = dentry->d_inode;
+	struct pohmelfs_inode *parent = POHMELFS_I(dir), *pi = POHMELFS_I(inode);
+	struct pohmelfs_name *n;
+	int err = -ENOENT;
+	struct qstr str = dentry->d_name;
+
+	err = pohmelfs_data_lock(parent, 0, ~0, POHMELFS_WRITE_LOCK);
+	if (err)
+		return err;
+
+	str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
+
+	dprintk("%s: dir_ino: %llu, inode: %llu, name: '%s', nlink: %d.\n",
+			__func__, parent->ino, pi->ino,
+			str.name, (signed)inode->i_nlink);
+
+	BUG_ON(!inode);
+
+	mutex_lock(&parent->offset_lock);
+	n = pohmelfs_search_hash(parent, str.hash);
+	if (n) {
+		pohmelfs_fix_offset(parent, n);
+		if (test_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state)) {
+			pohmelfs_remove_child(pi, n);
+		}
+		pohmelfs_name_free(parent, n);
+		err = 0;
+	}
+	mutex_unlock(&parent->offset_lock);
+
+	if (!err) {
+		psb->avail_size += inode->i_size;
+
+		pohmelfs_inode_del_inode(psb, pi);
+
+		mark_inode_dirty(dir);
+
+		inode->i_ctime = dir->i_ctime;
+		if (inode->i_nlink)
+			inode_dec_link_count(inode);
+	}
+	dprintk("%s: inode: %p, lock: %ld, unhashed: %d.\n",
+		__func__, pi, inode->i_state & I_LOCK, hlist_unhashed(&inode->i_hash));
+
+	return err;
+}
+
+/*
+ * Unlink and rmdir VFS callbacks.
+ */
+static int pohmelfs_unlink(struct inode *dir, struct dentry *dentry)
+{
+	return pohmelfs_remove_entry(dir, dentry);
+}
+
+static int pohmelfs_rmdir(struct inode *dir, struct dentry *dentry)
+{
+	int err;
+	struct inode *inode = dentry->d_inode;
+
+	dprintk("%s: parent: %llu, inode: %llu, name: '%s', parent_nlink: %d, nlink: %d.\n",
+			__func__, POHMELFS_I(dir)->ino, POHMELFS_I(inode)->ino,
+			dentry->d_name.name, (signed)dir->i_nlink, (signed)inode->i_nlink);
+
+	err = pohmelfs_remove_entry(dir, dentry);
+	if (!err) {
+		inode_dec_link_count(dir);
+		inode_dec_link_count(inode);
+	}
+
+	return err;
+}
+
+/*
+ * Link creation is synchronous.
+ * I'm lazy.
+ * Earth is somewhat round.
+ */
+static int pohmelfs_create_link(struct pohmelfs_inode *parent, struct qstr *obj,
+		struct pohmelfs_inode *target, struct qstr *tstr)
+{
+	struct super_block *sb = parent->vfs_inode.i_sb;
+	struct pohmelfs_sb *psb = POHMELFS_SB(sb);
+	struct netfs_cmd *cmd;
+	struct netfs_trans *t;
+	void *data;
+	int err, parent_len, target_len = 0, cur_len, path_size = 0;
+
+	err = pohmelfs_data_lock(parent, 0, ~0, POHMELFS_WRITE_LOCK);
+	if (err)
+		return err;
+
+	err = sb->s_op->write_inode(&parent->vfs_inode, 0);
+	if (err)
+		goto err_out_exit;
+
+	if (tstr)
+		target_len = tstr->len;
+
+	parent_len = pohmelfs_path_length(parent);
+	if (target)
+		target_len += pohmelfs_path_length(target);
+
+	if (parent_len < 0) {
+		err = parent_len;
+		goto err_out_exit;
+	}
+
+	if (target_len < 0) {
+		err = target_len;
+		goto err_out_exit;
+	}
+
+	t = netfs_trans_alloc(psb, parent_len + target_len + obj->len + 2, 0, 0);
+	if (!t) {
+		err = -ENOMEM;
+		goto err_out_exit;
+	}
+	cur_len = netfs_trans_cur_len(t);
+
+	cmd = netfs_trans_current(t);
+	if (IS_ERR(cmd)) {
+		err = PTR_ERR(cmd);
+		goto err_out_free;
+	}
+
+	data = (void *)(cmd + 1);
+	cur_len -= sizeof(struct netfs_cmd);
+
+	err = pohmelfs_construct_path_string(parent, data, parent_len);
+	if (err > 0) {
+		/* Do not place null-byte before the slash */
+		path_size = err - 1;
+		cur_len -= path_size;
+
+		err = snprintf(data + path_size, cur_len, "/%s|", obj->name);
+
+		path_size += err;
+		cur_len -= err;
+
+		cmd->ext = path_size - 1; /* No | symbol */
+
+		if (target) {
+			err = pohmelfs_construct_path_string(target, data + path_size, target_len);
+			if (err > 0) {
+				path_size += err;
+				cur_len -= err;
+			}
+		}
+	}
+
+	if (err < 0)
+		goto err_out_free;
+
+	cmd->start = 0;
+
+	if (!target && tstr) {
+		if (tstr->len > cur_len - 1) {
+			err = -ENAMETOOLONG;
+			goto err_out_free;
+		}
+
+		err = snprintf(data + path_size, cur_len, "%s", tstr->name) + 1; /* 0-byte */
+		path_size += err;
+		cur_len -= err;
+		cmd->start = 1;
+	}
+
+	dprintk("%s: parent: %llu, obj: '%s', target_inode: %llu, target_str: '%s', full: '%s'.\n",
+			__func__, parent->ino, obj->name, (target)?target->ino:0, (tstr)?tstr->name:NULL,
+			(char *)data);
+
+	cmd->cmd = NETFS_LINK;
+	cmd->size = path_size;
+	cmd->id = parent->ino;
+
+	netfs_convert_cmd(cmd);
+
+	netfs_trans_update(cmd, t, path_size);
+
+	err = netfs_trans_finish(t, psb);
+	if (err)
+		goto err_out_exit;
+
+	return 0;
+
+err_out_free:
+	t->result = err;
+	netfs_trans_put(t);
+err_out_exit:
+	return err;
+}
+
+/*
+ *  VFS hard and soft link callbacks.
+ */
+static int pohmelfs_link(struct dentry *old_dentry, struct inode *dir,
+	struct dentry *dentry)
+{
+	struct inode *inode = old_dentry->d_inode;
+	struct pohmelfs_inode *pi = POHMELFS_I(inode);
+	int err;
+	struct qstr str = dentry->d_name;
+
+	str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
+
+	err = inode->i_sb->s_op->write_inode(inode, 0);
+	if (err)
+		return err;
+
+	err = pohmelfs_create_link(POHMELFS_I(dir), &str, pi, NULL);
+	if (err)
+		return err;
+
+	return pohmelfs_create_entry(dir, dentry, pi->ino, inode->i_mode);
+}
+
+static int pohmelfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
+{
+	struct qstr sym_str;
+	struct qstr str = dentry->d_name;
+	struct inode *inode;
+	int err;
+
+	str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
+
+	sym_str.name = symname;
+	sym_str.len = strlen(symname);
+
+	err = pohmelfs_create_link(POHMELFS_I(dir), &str, NULL, &sym_str);
+	if (err)
+		goto err_out_exit;
+
+	err = pohmelfs_create_entry(dir, dentry, 0, S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO);
+	if (err)
+		goto err_out_exit;
+
+	inode = dentry->d_inode;
+
+	err = page_symlink(inode, symname, sym_str.len + 1);
+	if (err)
+		goto err_out_put;
+
+	return 0;
+
+err_out_put:
+	iput(inode);
+err_out_exit:
+	return err;
+}
+
+static int pohmelfs_send_rename(struct pohmelfs_inode *pi, struct pohmelfs_inode *parent,
+		struct qstr *str)
+{
+	int path_len, err, total_len = 0, inode_len, parent_len;
+	char *path;
+	struct netfs_trans *t;
+	struct netfs_cmd *cmd;
+	struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
+
+	parent_len = pohmelfs_path_length(parent);
+	inode_len = pohmelfs_path_length(pi);
+
+	if (parent_len < 0 || inode_len < 0)
+		return -EINVAL;
+
+	path_len = parent_len + inode_len + str->len + 3;
+
+	t = netfs_trans_alloc(psb, path_len, 0, 0);
+	if (!t)
+		return -ENOMEM;
+
+	cmd = netfs_trans_current(t);
+	path = (char *)(cmd + 1);
+
+	err = pohmelfs_construct_path_string(pi, path, inode_len);
+	if (err < 0)
+		goto err_out_unlock;
+
+	cmd->ext = err;
+
+	path += err;
+	total_len += err;
+	path_len -= err;
+
+	*path = '|';
+	path++;
+	total_len++;
+	path_len--;
+
+	err = pohmelfs_construct_path_string(parent, path, parent_len);
+	if (err < 0)
+		goto err_out_unlock;
+
+	/*
+	 * Do not place a null-byte before the final slash and the name.
+	 */
+	err--;
+	path += err;
+	total_len += err;
+	path_len -= err;
+
+	err = snprintf(path, path_len - 1, "/%s", str->name);
+
+	total_len += err + 1; /* 0 symbol */
+	path_len -= err + 1;
+
+	cmd->cmd = NETFS_RENAME;
+	cmd->id = pi->ino;
+	cmd->start = parent->ino;
+	cmd->size = total_len;
+
+	netfs_convert_cmd(cmd);
+
+	netfs_trans_update(cmd, t, total_len);
+
+	return netfs_trans_finish(t, psb);
+
+err_out_unlock:
+	netfs_trans_free(t);
+	return err;
+}
+
+static int pohmelfs_rename(struct inode *old_dir, struct dentry *old_dentry,
+			struct inode *new_dir, struct dentry *new_dentry)
+{
+	struct inode *inode = old_dentry->d_inode;
+	struct pohmelfs_inode *old_parent, *pi, *new_parent;
+	struct qstr str = new_dentry->d_name;
+	struct pohmelfs_name *n;
+	unsigned int old_hash;
+	int err = -ENOENT;
+
+	pi = POHMELFS_I(inode);
+	old_parent = POHMELFS_I(old_dir);
+
+	if (new_dir) {
+		new_dir->i_sb->s_op->write_inode(new_dir, 0);
+	}
+
+	old_hash = jhash(old_dentry->d_name.name, old_dentry->d_name.len, 0);
+	str.hash = jhash(new_dentry->d_name.name, new_dentry->d_name.len, 0);
+
+	str.len = new_dentry->d_name.len;
+	str.name = new_dentry->d_name.name;
+	str.hash = jhash(new_dentry->d_name.name, new_dentry->d_name.len, 0);
+
+	if (new_dir) {
+		new_parent = POHMELFS_I(new_dir);
+		err = -ENOTEMPTY;
+
+		if (S_ISDIR(inode->i_mode) &&
+				new_parent->total_len <= 3)
+			goto err_out_exit;
+	} else {
+		new_parent = old_parent;
+	}
+
+	dprintk("%s: ino: %llu, parent: %llu, name: '%s' -> parent: %llu, name: '%s', i_size: %llu.\n",
+			__func__, pi->ino, old_parent->ino, old_dentry->d_name.name,
+			new_parent->ino, new_dentry->d_name.name, inode->i_size);
+
+	if (test_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state) &&
+			test_bit(NETFS_INODE_OWNED, &pi->state)) {
+		err = pohmelfs_send_rename(pi, new_parent, &str);
+		if (err)
+			goto err_out_exit;
+	}
+
+	n = pohmelfs_name_alloc(str.len + 1);
+	if (!n)
+		goto err_out_exit;
+
+	mutex_lock(&new_parent->offset_lock);
+	n->ino = pi->ino;
+	n->mode = inode->i_mode;
+	n->len = str.len;
+	n->hash = str.hash;
+	sprintf(n->data, "%s", str.name);
+
+	err = pohmelfs_insert_name(new_parent, n);
+	mutex_unlock(&new_parent->offset_lock);
+
+	if (err)
+		goto err_out_exit;
+
+	mutex_lock(&old_parent->offset_lock);
+	n = pohmelfs_search_hash(old_parent, old_hash);
+	if (n)
+		pohmelfs_name_del(old_parent, n);
+	mutex_unlock(&old_parent->offset_lock);
+
+	mark_inode_dirty(inode);
+	mark_inode_dirty(&new_parent->vfs_inode);
+
+	WARN_ON_ONCE(list_empty(&inode->i_dentry));
+
+	return 0;
+
+err_out_exit:
+
+	clear_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);
+
+	mutex_unlock(&inode->i_mutex);
+	return err;
+}
+
+/*
+ * POHMELFS directory inode operations.
+ */
+const struct inode_operations pohmelfs_dir_inode_ops = {
+	.link		= pohmelfs_link,
+	.symlink	= pohmelfs_symlink,
+	.unlink		= pohmelfs_unlink,
+	.mkdir		= pohmelfs_mkdir,
+	.rmdir		= pohmelfs_rmdir,
+	.create		= pohmelfs_create,
+	.lookup 	= pohmelfs_lookup,
+	.setattr	= pohmelfs_setattr,
+	.rename		= pohmelfs_rename,
+};
diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c
new file mode 100644
index 0000000..5bf1650
--- /dev/null
+++ b/drivers/staging/pohmelfs/inode.c
@@ -0,0 +1,1976 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * 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.
+ *
+ * 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/module.h>
+#include <linux/backing-dev.h>
+#include <linux/crypto.h>
+#include <linux/fs.h>
+#include <linux/jhash.h>
+#include <linux/hash.h>
+#include <linux/ktime.h>
+#include <linux/mm.h>
+#include <linux/mount.h>
+#include <linux/pagemap.h>
+#include <linux/pagevec.h>
+#include <linux/parser.h>
+#include <linux/swap.h>
+#include <linux/slab.h>
+#include <linux/statfs.h>
+#include <linux/writeback.h>
+#include <linux/quotaops.h>
+
+#include "netfs.h"
+
+#define POHMELFS_MAGIC_NUM	0x504f482e
+
+static struct kmem_cache *pohmelfs_inode_cache;
+
+/*
+ * Removes inode from all trees, drops local name cache and removes all queued
+ * requests for object removal.
+ */
+void pohmelfs_inode_del_inode(struct pohmelfs_sb *psb, struct pohmelfs_inode *pi)
+{
+	mutex_lock(&pi->offset_lock);
+	pohmelfs_free_names(pi);
+	mutex_unlock(&pi->offset_lock);
+
+	dprintk("%s: deleted stuff in ino: %llu.\n", __func__, pi->ino);
+}
+
+/*
+ * Sync inode to server.
+ * Returns zero in success and negative error value otherwise.
+ * It will gather path to root directory into structures containing
+ * creation mode, permissions and names, so that the whole path
+ * to given inode could be created using only single network command.
+ */
+int pohmelfs_write_inode_create(struct inode *inode, struct netfs_trans *trans)
+{
+	struct pohmelfs_inode *pi = POHMELFS_I(inode);
+	int err = -ENOMEM, size;
+	struct netfs_cmd *cmd;
+	void *data;
+	int cur_len = netfs_trans_cur_len(trans);
+
+	if (unlikely(cur_len < 0))
+		return -ETOOSMALL;
+
+	cmd = netfs_trans_current(trans);
+	cur_len -= sizeof(struct netfs_cmd);
+
+	data = (void *)(cmd + 1);
+
+	err = pohmelfs_construct_path_string(pi, data, cur_len);
+	if (err < 0)
+		goto err_out_exit;
+
+	size = err;
+
+	cmd->start = i_size_read(inode);
+	cmd->cmd = NETFS_CREATE;
+	cmd->size = size;
+	cmd->id = pi->ino;
+	cmd->ext = inode->i_mode;
+
+	netfs_convert_cmd(cmd);
+
+	netfs_trans_update(cmd, trans, size);
+
+	return 0;
+
+err_out_exit:
+	printk("%s: completed ino: %llu, err: %d.\n", __func__, pi->ino, err);
+	return err;
+}
+
+static int pohmelfs_write_trans_complete(struct page **pages, unsigned int page_num,
+		void *private, int err)
+{
+	unsigned i;
+
+	dprintk("%s: pages: %lu-%lu, page_num: %u, err: %d.\n",
+			__func__, pages[0]->index, pages[page_num-1]->index,
+			page_num, err);
+
+	for (i = 0; i < page_num; i++) {
+		struct page *page = pages[i];
+
+		if (!page)
+			continue;
+
+		end_page_writeback(page);
+
+		if (err < 0) {
+			SetPageError(page);
+			set_page_dirty(page);
+		}
+
+		unlock_page(page);
+		page_cache_release(page);
+
+		/* dprintk("%s: %3u/%u: page: %p.\n", __func__, i, page_num, page); */
+	}
+	return err;
+}
+
+static int pohmelfs_inode_has_dirty_pages(struct address_space *mapping, pgoff_t index)
+{
+	int ret;
+	struct page *page;
+
+	rcu_read_lock();
+	ret = radix_tree_gang_lookup_tag(&mapping->page_tree,
+				(void **)&page, index, 1, PAGECACHE_TAG_DIRTY);
+	rcu_read_unlock();
+	return ret;
+}
+
+static int pohmelfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
+{
+	struct inode *inode = mapping->host;
+	struct pohmelfs_inode *pi = POHMELFS_I(inode);
+	struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+	struct backing_dev_info *bdi = mapping->backing_dev_info;
+	int err = 0;
+	int done = 0;
+	int nr_pages;
+	pgoff_t index;
+	pgoff_t end;		/* Inclusive */
+	int scanned = 0;
+	int range_whole = 0;
+
+	if (wbc->nonblocking && bdi_write_congested(bdi)) {
+		wbc->encountered_congestion = 1;
+		return 0;
+	}
+
+	if (wbc->range_cyclic) {
+		index = mapping->writeback_index; /* Start from prev offset */
+		end = -1;
+	} else {
+		index = wbc->range_start >> PAGE_CACHE_SHIFT;
+		end = wbc->range_end >> PAGE_CACHE_SHIFT;
+		if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
+			range_whole = 1;
+		scanned = 1;
+	}
+retry:
+	while (!done && (index <= end)) {
+		unsigned int i = min(end - index, (pgoff_t)psb->trans_max_pages);
+		int path_len;
+		struct netfs_trans *trans;
+
+		err = pohmelfs_inode_has_dirty_pages(mapping, index);
+		if (!err)
+			break;
+
+		err = pohmelfs_path_length(pi);
+		if (err < 0)
+			break;
+
+		path_len = err;
+
+		if (path_len <= 2) {
+			err = -ENOENT;
+			break;
+		}
+
+		trans = netfs_trans_alloc(psb, path_len, 0, i);
+		if (!trans) {
+			err = -ENOMEM;
+			break;
+		}
+		trans->complete = &pohmelfs_write_trans_complete;
+
+		trans->page_num = nr_pages = find_get_pages_tag(mapping, &index,
+				PAGECACHE_TAG_DIRTY, trans->page_num,
+				trans->pages);
+
+		dprintk("%s: t: %p, nr_pages: %u, end: %lu, index: %lu, max: %u.\n",
+				__func__, trans, nr_pages, end, index, trans->page_num);
+
+		if (!nr_pages)
+			goto err_out_reset;
+
+		err = pohmelfs_write_inode_create(inode, trans);
+		if (err)
+			goto err_out_reset;
+
+		err = 0;
+		scanned = 1;
+
+		for (i = 0; i < trans->page_num; i++) {
+			struct page *page = trans->pages[i];
+
+			lock_page(page);
+
+			if (unlikely(page->mapping != mapping))
+				goto out_continue;
+
+			if (!wbc->range_cyclic && page->index > end) {
+				done = 1;
+				goto out_continue;
+			}
+
+			if (wbc->sync_mode != WB_SYNC_NONE)
+				wait_on_page_writeback(page);
+
+			if (PageWriteback(page) ||
+			    !clear_page_dirty_for_io(page)) {
+				dprintk("%s: not clear for io page: %p, writeback: %d.\n",
+						__func__, page, PageWriteback(page));
+				goto out_continue;
+			}
+
+			set_page_writeback(page);
+
+			trans->attached_size += page_private(page);
+			trans->attached_pages++;
+#if 0
+			dprintk("%s: %u/%u added trans: %p, gen: %u, page: %p, [High: %d], size: %lu, idx: %lu.\n",
+					__func__, i, trans->page_num, trans, trans->gen, page,
+					!!PageHighMem(page), page_private(page), page->index);
+#endif
+			wbc->nr_to_write--;
+
+			if (wbc->nr_to_write <= 0)
+				done = 1;
+			if (wbc->nonblocking && bdi_write_congested(bdi)) {
+				wbc->encountered_congestion = 1;
+				done = 1;
+			}
+
+			continue;
+out_continue:
+			unlock_page(page);
+			trans->pages[i] = NULL;
+		}
+
+		err = netfs_trans_finish(trans, psb);
+		if (err)
+			break;
+
+		continue;
+
+err_out_reset:
+		trans->result = err;
+		netfs_trans_reset(trans);
+		netfs_trans_put(trans);
+		break;
+	}
+
+	if (!scanned && !done) {
+		/*
+		 * We hit the last page and there is more work to be done: wrap
+		 * back to the start of the file
+		 */
+		scanned = 1;
+		index = 0;
+		goto retry;
+	}
+
+	if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
+		mapping->writeback_index = index;
+
+	return err;
+}
+
+/*
+ * Inode writeback creation completion callback.
+ * Only invoked for just created inodes, which do not have pages attached,
+ * like dirs and empty files.
+ */
+static int pohmelfs_write_inode_complete(struct page **pages, unsigned int page_num,
+		void *private, int err)
+{
+	struct inode *inode = private;
+	struct pohmelfs_inode *pi = POHMELFS_I(inode);
+
+	if (inode) {
+		if (err) {
+			mark_inode_dirty(inode);
+			clear_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);
+		} else {
+			set_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);
+		}
+
+		pohmelfs_put_inode(pi);
+	}
+
+	return err;
+}
+
+int pohmelfs_write_create_inode(struct pohmelfs_inode *pi)
+{
+	struct netfs_trans *t;
+	struct inode *inode = &pi->vfs_inode;
+	struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+	int err;
+
+	if (test_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state))
+		return 0;
+
+	dprintk("%s: started ino: %llu.\n", __func__, pi->ino);
+
+	err = pohmelfs_path_length(pi);
+	if (err < 0)
+		goto err_out_exit;
+
+	t = netfs_trans_alloc(psb, err + 1, 0, 0);
+	if (!t) {
+		err = -ENOMEM;
+		goto err_out_put;
+	}
+	t->complete = pohmelfs_write_inode_complete;
+	t->private = igrab(inode);
+	if (!t->private) {
+		err = -ENOENT;
+		goto err_out_put;
+	}
+
+	err = pohmelfs_write_inode_create(inode, t);
+	if (err)
+		goto err_out_put;
+
+	netfs_trans_finish(t, POHMELFS_SB(inode->i_sb));
+
+	return 0;
+
+err_out_put:
+	t->result = err;
+	netfs_trans_put(t);
+err_out_exit:
+	return err;
+}
+
+/*
+ * Sync all not-yet-created children in given directory to the server.
+ */
+static int pohmelfs_write_inode_create_children(struct inode *inode)
+{
+	struct pohmelfs_inode *parent = POHMELFS_I(inode);
+	struct super_block *sb = inode->i_sb;
+	struct pohmelfs_name *n;
+
+	while (!list_empty(&parent->sync_create_list)) {
+		n = NULL;
+		mutex_lock(&parent->offset_lock);
+		if (!list_empty(&parent->sync_create_list)) {
+			n = list_first_entry(&parent->sync_create_list,
+				struct pohmelfs_name, sync_create_entry);
+			list_del_init(&n->sync_create_entry);
+		}
+		mutex_unlock(&parent->offset_lock);
+
+		if (!n)
+			break;
+
+		inode = ilookup(sb, n->ino);
+
+		dprintk("%s: parent: %llu, ino: %llu, inode: %p.\n",
+				__func__, parent->ino, n->ino, inode);
+
+		if (inode && (inode->i_state & I_DIRTY)) {
+			struct pohmelfs_inode *pi = POHMELFS_I(inode);
+			pohmelfs_write_create_inode(pi);
+			//pohmelfs_meta_command(pi, NETFS_INODE_INFO, 0, NULL, NULL, 0);
+			iput(inode);
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * Removes given child from given inode on server.
+ */
+int pohmelfs_remove_child(struct pohmelfs_inode *pi, struct pohmelfs_name *n)
+{
+	return pohmelfs_meta_command_data(pi, pi->ino, NETFS_REMOVE, NULL, 0, NULL, NULL, 0);
+}
+
+/*
+ * Writeback for given inode.
+ */
+static int pohmelfs_write_inode(struct inode *inode, int sync)
+{
+	struct pohmelfs_inode *pi = POHMELFS_I(inode);
+
+	pohmelfs_write_create_inode(pi);
+	pohmelfs_write_inode_create_children(inode);
+
+	return 0;
+}
+
+/*
+ * It is not exported, sorry...
+ */
+static inline wait_queue_head_t *page_waitqueue(struct page *page)
+{
+	const struct zone *zone = page_zone(page);
+
+	return &zone->wait_table[hash_ptr(page, zone->wait_table_bits)];
+}
+
+static int pohmelfs_wait_on_page_locked(struct page *page)
+{
+	struct pohmelfs_sb *psb = POHMELFS_SB(page->mapping->host->i_sb);
+	long ret = psb->wait_on_page_timeout;
+	DEFINE_WAIT_BIT(wait, &page->flags, PG_locked);
+	int err = 0;
+
+	if (!PageLocked(page))
+		return 0;
+
+	for (;;) {
+		prepare_to_wait(page_waitqueue(page),
+				&wait.wait, TASK_INTERRUPTIBLE);
+
+		dprintk("%s: page: %p, locked: %d, uptodate: %d, error: %d, flags: %lx.\n",
+				__func__, page, PageLocked(page), PageUptodate(page),
+				PageError(page), page->flags);
+
+		if (!PageLocked(page))
+			break;
+
+		if (!signal_pending(current)) {
+			ret = schedule_timeout(ret);
+			if (!ret)
+				break;
+			continue;
+		}
+		ret = -ERESTARTSYS;
+		break;
+	}
+	finish_wait(page_waitqueue(page), &wait.wait);
+
+	if (!ret)
+		err = -ETIMEDOUT;
+
+
+	if (!err)
+		SetPageUptodate(page);
+
+	if (err)
+		printk("%s: page: %p, uptodate: %d, locked: %d, err: %d.\n",
+			__func__, page, PageUptodate(page), PageLocked(page), err);
+
+	return err;
+}
+
+static int pohmelfs_read_page_complete(struct page **pages, unsigned int page_num,
+		void *private, int err)
+{
+	struct page *page = private;
+
+	if (PageChecked(page))
+		return err;
+
+	if (err < 0) {
+		dprintk("%s: page: %p, err: %d.\n", __func__, page, err);
+		SetPageError(page);
+	}
+
+	unlock_page(page);
+
+	return err;
+}
+
+/*
+ * Read a page from remote server.
+ * Function will wait until page is unlocked.
+ */
+static int pohmelfs_readpage(struct file *file, struct page *page)
+{
+	struct inode *inode = page->mapping->host;
+	struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+	struct pohmelfs_inode *pi = POHMELFS_I(inode);
+	struct netfs_trans *t;
+	struct netfs_cmd *cmd;
+	int err, path_len;
+	void *data;
+	u64 isize;
+
+	err = pohmelfs_data_lock(pi, page->index << PAGE_CACHE_SHIFT,
+			PAGE_SIZE, POHMELFS_READ_LOCK);
+	if (err)
+		goto err_out_exit;
+
+	isize = i_size_read(inode);
+	if (isize <= page->index << PAGE_CACHE_SHIFT) {
+		SetPageUptodate(page);
+		unlock_page(page);
+		return 0;
+	}
+
+	path_len = pohmelfs_path_length(pi);
+	if (path_len < 0) {
+		err = path_len;
+		goto err_out_exit;
+	}
+
+	t = netfs_trans_alloc(psb, path_len, NETFS_TRANS_SINGLE_DST, 0);
+	if (!t) {
+		err = -ENOMEM;
+		goto err_out_exit;
+	}
+
+	t->complete = pohmelfs_read_page_complete;
+	t->private = page;
+
+	cmd = netfs_trans_current(t);
+	data = (void *)(cmd + 1);
+
+	err = pohmelfs_construct_path_string(pi, data, path_len);
+	if (err < 0)
+		goto err_out_free;
+
+	path_len = err;
+
+	cmd->id = pi->ino;
+	cmd->start = page->index;
+	cmd->start <<= PAGE_CACHE_SHIFT;
+	cmd->size = PAGE_CACHE_SIZE + path_len;
+	cmd->cmd = NETFS_READ_PAGE;
+	cmd->ext = path_len;
+
+	dprintk("%s: path: '%s', page: %p, ino: %llu, start: %llu, size: %lu.\n",
+			__func__, (char *)data, page, pi->ino, cmd->start, PAGE_CACHE_SIZE);
+
+	netfs_convert_cmd(cmd);
+	netfs_trans_update(cmd, t, path_len);
+
+	err = netfs_trans_finish(t, psb);
+	if (err)
+		goto err_out_return;
+
+	return pohmelfs_wait_on_page_locked(page);
+
+err_out_free:
+	t->result = err;
+	netfs_trans_put(t);
+err_out_exit:
+	SetPageError(page);
+	if (PageLocked(page))
+		unlock_page(page);
+err_out_return:
+	printk("%s: page: %p, start: %lu, size: %lu, err: %d.\n",
+		__func__, page, page->index << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE, err);
+
+	return err;
+}
+
+/*
+ * Write begin/end magic.
+ * Allocates a page and writes inode if it was not synced to server before.
+ */
+static int pohmelfs_write_begin(struct file *file, struct address_space *mapping,
+		loff_t pos, unsigned len, unsigned flags,
+		struct page **pagep, void **fsdata)
+{
+	struct inode *inode = mapping->host;
+	struct page *page;
+	pgoff_t index;
+	unsigned start, end;
+	int err;
+
+	*pagep = NULL;
+
+	index = pos >> PAGE_CACHE_SHIFT;
+	start = pos & (PAGE_CACHE_SIZE - 1);
+	end = start + len;
+
+	page = grab_cache_page(mapping, index);
+#if 0
+	dprintk("%s: page: %p pos: %llu, len: %u, index: %lu, start: %u, end: %u, uptodate: %d.\n",
+			__func__, page,	pos, len, index, start, end, PageUptodate(page));
+#endif
+	if (!page) {
+		err = -ENOMEM;
+		goto err_out_exit;
+	}
+
+	while (!PageUptodate(page)) {
+		if (start && test_bit(NETFS_INODE_REMOTE_SYNCED, &POHMELFS_I(inode)->state)) {
+			err = pohmelfs_readpage(file, page);
+			if (err)
+				goto err_out_exit;
+
+			lock_page(page);
+			continue;
+		}
+
+		if (len != PAGE_CACHE_SIZE) {
+			void *kaddr = kmap_atomic(page, KM_USER0);
+
+			memset(kaddr + start, 0, PAGE_CACHE_SIZE - start);
+			flush_dcache_page(page);
+			kunmap_atomic(kaddr, KM_USER0);
+		}
+		SetPageUptodate(page);
+	}
+
+	set_page_private(page, end);
+
+	*pagep = page;
+
+	return 0;
+
+err_out_exit:
+	page_cache_release(page);
+	*pagep = NULL;
+
+	return err;
+}
+
+static int pohmelfs_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;
+
+	if (copied != len) {
+		unsigned from = pos & (PAGE_CACHE_SIZE - 1);
+		void *kaddr = kmap_atomic(page, KM_USER0);
+
+		memset(kaddr + from + copied, 0, len - copied);
+		flush_dcache_page(page);
+		kunmap_atomic(kaddr, KM_USER0);
+	}
+
+	SetPageUptodate(page);
+	set_page_dirty(page);
+#if 0
+	dprintk("%s: page: %p [U: %d, D: %d, L: %d], pos: %llu, len: %u, copied: %u.\n",
+			__func__, page,
+			PageUptodate(page), PageDirty(page), PageLocked(page),
+			pos, len, copied);
+#endif
+	flush_dcache_page(page);
+
+	unlock_page(page);
+	page_cache_release(page);
+
+	if (pos + copied > inode->i_size) {
+		struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+
+		psb->avail_size -= pos + copied - inode->i_size;
+
+		i_size_write(inode, pos + copied);
+	}
+
+	return copied;
+}
+
+static int pohmelfs_readpages_trans_complete(struct page **__pages, unsigned int page_num,
+		void *private, int err)
+{
+	struct pohmelfs_inode *pi = private;
+	unsigned int i, num;
+	struct page **pages, *page = (struct page *)__pages;
+	loff_t index = page->index;
+
+	pages = kzalloc(sizeof(void *) * page_num, GFP_NOIO);
+	if (!pages)
+		return -ENOMEM;
+
+	num = find_get_pages_contig(pi->vfs_inode.i_mapping, index, page_num, pages);
+	if (num <= 0) {
+		err = num;
+		goto err_out_free;
+	}
+
+	for (i=0; i<num; ++i) {
+		page = pages[i];
+
+		if (err)
+			printk("%s: %u/%u: page: %p, index: %lu, uptodate: %d, locked: %d, err: %d.\n",
+				__func__, i, num, page, page->index,
+				PageUptodate(page), PageLocked(page), err);
+
+		if (!PageChecked(page)) {
+			if (err < 0)
+				SetPageError(page);
+			unlock_page(page);
+		}
+		page_cache_release(page);
+		page_cache_release(page);
+	}
+
+err_out_free:
+	kfree(pages);
+	return err;
+}
+
+static int pohmelfs_send_readpages(struct pohmelfs_inode *pi, struct page *first, unsigned int num)
+{
+	struct netfs_trans *t;
+	struct netfs_cmd *cmd;
+	struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
+	int err, path_len;
+	void *data;
+
+	err = pohmelfs_data_lock(pi, first->index << PAGE_CACHE_SHIFT,
+			num * PAGE_SIZE, POHMELFS_READ_LOCK);
+	if (err)
+		goto err_out_exit;
+
+	path_len = pohmelfs_path_length(pi);
+	if (path_len < 0) {
+		err = path_len;
+		goto err_out_exit;
+	}
+
+	t = netfs_trans_alloc(psb, path_len, NETFS_TRANS_SINGLE_DST, 0);
+	if (!t) {
+		err = -ENOMEM;
+		goto err_out_exit;
+	}
+
+	cmd = netfs_trans_current(t);
+	data = (void *)(cmd + 1);
+
+	t->complete = pohmelfs_readpages_trans_complete;
+	t->private = pi;
+	t->page_num = num;
+	t->pages = (struct page **)first;
+
+	err = pohmelfs_construct_path_string(pi, data, path_len);
+	if (err < 0)
+		goto err_out_put;
+
+	path_len = err;
+
+	cmd->cmd = NETFS_READ_PAGES;
+	cmd->start = first->index;
+	cmd->start <<= PAGE_CACHE_SHIFT;
+	cmd->size = (num << 8 | PAGE_CACHE_SHIFT);
+	cmd->id = pi->ino;
+	cmd->ext = path_len;
+
+	dprintk("%s: t: %p, gen: %u, path: '%s', path_len: %u, "
+			"start: %lu, num: %u.\n",
+			__func__, t, t->gen, (char *)data, path_len,
+			first->index, num);
+
+	netfs_convert_cmd(cmd);
+	netfs_trans_update(cmd, t, path_len);
+
+	return netfs_trans_finish(t, psb);
+
+err_out_put:
+	netfs_trans_free(t);
+err_out_exit:
+	pohmelfs_readpages_trans_complete((struct page **)first, num, pi, err);
+	return err;
+}
+
+#define list_to_page(head) (list_entry((head)->prev, struct page, lru))
+
+static int pohmelfs_readpages(struct file *file, struct address_space *mapping,
+			struct list_head *pages, unsigned nr_pages)
+{
+	unsigned int page_idx, num = 0;
+	struct page *page = NULL, *first = NULL;
+
+	for (page_idx = 0; page_idx < nr_pages; page_idx++) {
+		page = list_to_page(pages);
+
+		prefetchw(&page->flags);
+		list_del(&page->lru);
+
+		if (!add_to_page_cache_lru(page, mapping,
+					page->index, GFP_KERNEL)) {
+
+			if (!num) {
+				num = 1;
+				first = page;
+				continue;
+			}
+
+			dprintk("%s: added to lru page: %p, page_index: %lu, first_index: %lu.\n",
+					__func__, page, page->index, first->index);
+
+			if (unlikely(first->index + num != page->index) || (num > 500)) {
+				pohmelfs_send_readpages(POHMELFS_I(mapping->host),
+						first, num);
+				first = page;
+				num = 0;
+			}
+
+			num++;
+		}
+	}
+	pohmelfs_send_readpages(POHMELFS_I(mapping->host), first, num);
+
+	/*
+	 * This will be sync read, so when last page is processed,
+	 * all previous are alerady unlocked and ready to be used.
+	 */
+	return 0;
+}
+
+/*
+ * Small addres space operations for POHMELFS.
+ */
+const struct address_space_operations pohmelfs_aops = {
+	.readpage		= pohmelfs_readpage,
+	.readpages		= pohmelfs_readpages,
+	.writepages		= pohmelfs_writepages,
+	.write_begin		= pohmelfs_write_begin,
+	.write_end		= pohmelfs_write_end,
+	.set_page_dirty 	= __set_page_dirty_nobuffers,
+};
+
+/*
+ * ->detroy_inode() callback. Deletes inode from the caches
+ *  and frees private data.
+ */
+static void pohmelfs_destroy_inode(struct inode *inode)
+{
+	struct super_block *sb = inode->i_sb;
+	struct pohmelfs_sb *psb = POHMELFS_SB(sb);
+	struct pohmelfs_inode *pi = POHMELFS_I(inode);
+
+	//pohmelfs_data_unlock(pi, 0, inode->i_size, POHMELFS_READ_LOCK);
+
+	pohmelfs_inode_del_inode(psb, pi);
+
+	dprintk("%s: pi: %p, inode: %p, ino: %llu.\n",
+		__func__, pi, &pi->vfs_inode, pi->ino);
+	kmem_cache_free(pohmelfs_inode_cache, pi);
+	atomic_long_dec(&psb->total_inodes);
+}
+
+/*
+ * ->alloc_inode() callback. Allocates inode and initilizes private data.
+ */
+static struct inode *pohmelfs_alloc_inode(struct super_block *sb)
+{
+	struct pohmelfs_inode *pi;
+
+	pi = kmem_cache_alloc(pohmelfs_inode_cache, GFP_NOIO);
+	if (!pi)
+		return NULL;
+
+	pi->hash_root = RB_ROOT;
+	mutex_init(&pi->offset_lock);
+
+	INIT_LIST_HEAD(&pi->sync_create_list);
+
+	INIT_LIST_HEAD(&pi->inode_entry);
+
+	pi->lock_type = 0;
+	pi->state = 0;
+	pi->total_len = 0;
+	pi->drop_count = 0;
+
+	dprintk("%s: pi: %p, inode: %p.\n", __func__, pi, &pi->vfs_inode);
+
+	atomic_long_inc(&POHMELFS_SB(sb)->total_inodes);
+
+	return &pi->vfs_inode;
+}
+
+/*
+ * We want fsync() to work on POHMELFS.
+ */
+static int pohmelfs_fsync(struct file *file, struct dentry *dentry, int datasync)
+{
+	struct inode *inode = file->f_mapping->host;
+	struct writeback_control wbc = {
+		.sync_mode = WB_SYNC_ALL,
+		.nr_to_write = 0,	/* sys_fsync did this */
+	};
+
+	return sync_inode(inode, &wbc);
+}
+
+ssize_t pohmelfs_write(struct file *file, const char __user *buf,
+		size_t len, loff_t *ppos)
+{
+	struct address_space *mapping = file->f_mapping;
+	struct inode *inode = mapping->host;
+	struct pohmelfs_inode *pi = POHMELFS_I(inode);
+	struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len };
+	struct kiocb kiocb;
+	ssize_t ret;
+	loff_t pos = *ppos;
+
+	init_sync_kiocb(&kiocb, file);
+	kiocb.ki_pos = pos;
+	kiocb.ki_left = len;
+
+	dprintk("%s: len: %zu, pos: %llu.\n", __func__, len, pos);
+
+	mutex_lock(&inode->i_mutex);
+	ret = pohmelfs_data_lock(pi, pos, len, POHMELFS_WRITE_LOCK);
+	if (ret)
+		goto err_out_unlock;
+
+	ret = generic_file_aio_write_nolock(&kiocb, &iov, 1, pos);
+	*ppos = kiocb.ki_pos;
+
+	mutex_unlock(&inode->i_mutex);
+	WARN_ON(ret < 0);
+
+	if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
+		ssize_t err;
+
+		err = sync_page_range(inode, mapping, pos, ret);
+		if (err < 0)
+			ret = err;
+		WARN_ON(ret < 0);
+	}
+
+	return ret;
+
+err_out_unlock:
+	mutex_unlock(&inode->i_mutex);
+	return ret;
+}
+
+const static struct file_operations pohmelfs_file_ops = {
+	.open		= generic_file_open,
+	.fsync		= pohmelfs_fsync,
+
+	.llseek		= generic_file_llseek,
+
+	.read		= do_sync_read,
+	.aio_read	= generic_file_aio_read,
+
+	.mmap		= generic_file_mmap,
+
+	.splice_read	= generic_file_splice_read,
+	.splice_write	= generic_file_splice_write,
+
+	.write		= pohmelfs_write,
+	.aio_write	= generic_file_aio_write,
+};
+
+const struct inode_operations pohmelfs_symlink_inode_operations = {
+	.readlink	= generic_readlink,
+	.follow_link	= page_follow_link_light,
+	.put_link	= page_put_link,
+};
+
+int pohmelfs_setattr_raw(struct inode *inode, struct iattr *attr)
+{
+	int err;
+
+	err = inode_change_ok(inode, attr);
+	if (err) {
+		dprintk("%s: ino: %llu, inode changes are not allowed.\n", __func__, POHMELFS_I(inode)->ino);
+		goto err_out_exit;
+	}
+
+	if ((attr->ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
+	    (attr->ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
+		err = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0;
+		if (err)
+			goto err_out_exit;
+	}
+
+	err = inode_setattr(inode, attr);
+	if (err) {
+		dprintk("%s: ino: %llu, failed to set the attributes.\n", __func__, POHMELFS_I(inode)->ino);
+		goto err_out_exit;
+	}
+
+	dprintk("%s: ino: %llu, mode: %o -> %o, uid: %u -> %u, gid: %u -> %u, size: %llu -> %llu.\n",
+			__func__, POHMELFS_I(inode)->ino, inode->i_mode, attr->ia_mode,
+			inode->i_uid, attr->ia_uid, inode->i_gid, attr->ia_gid, inode->i_size, attr->ia_size);
+
+	return 0;
+
+err_out_exit:
+	return err;
+}
+
+int pohmelfs_setattr(struct dentry *dentry, struct iattr *attr)
+{
+	struct inode *inode = dentry->d_inode;
+	struct pohmelfs_inode *pi = POHMELFS_I(inode);
+	int err;
+
+	err = pohmelfs_data_lock(pi, 0, ~0, POHMELFS_WRITE_LOCK);
+	if (err)
+		goto err_out_exit;
+
+	err = security_inode_setattr(dentry, attr);
+	if (err)
+		goto err_out_exit;
+
+	err = pohmelfs_setattr_raw(inode, attr);
+	if (err)
+		goto err_out_exit;
+
+	return 0;
+
+err_out_exit:
+	return err;
+}
+
+static int pohmelfs_send_xattr_req(struct pohmelfs_inode *pi, u64 id, u64 start,
+		const char *name, const void *value, size_t attrsize, int command)
+{
+	struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
+	int err, path_len, namelen = strlen(name) + 1; /* 0-byte */
+	struct netfs_trans *t;
+	struct netfs_cmd *cmd;
+	void *data;
+
+	dprintk("%s: id: %llu, start: %llu, name: '%s', attrsize: %zu, cmd: %d.\n",
+			__func__, id, start, name, attrsize, command);
+
+	path_len = pohmelfs_path_length(pi);
+	if (path_len < 0) {
+		err = path_len;
+		goto err_out_exit;
+	}
+
+	t = netfs_trans_alloc(psb, namelen + path_len + attrsize, 0, 0);
+	if (!t) {
+		err = -ENOMEM;
+		goto err_out_exit;
+	}
+
+	cmd = netfs_trans_current(t);
+	data = cmd + 1;
+
+	path_len = pohmelfs_construct_path_string(pi, data, path_len);
+	if (path_len < 0) {
+		err = path_len;
+		goto err_out_put;
+	}
+	data += path_len;
+
+	/*
+	 * 'name' is a NUL-terminated string already and
+	 * 'namelen' includes 0-byte.
+	 */
+	memcpy(data, name, namelen);
+	data += namelen;
+
+	memcpy(data, value, attrsize);
+
+	cmd->cmd = command;
+	cmd->id = id;
+	cmd->start = start;
+	cmd->size = attrsize + namelen + path_len;
+	cmd->ext = path_len;
+	cmd->csize = 0;
+	cmd->cpad = 0;
+
+	netfs_convert_cmd(cmd);
+	netfs_trans_update(cmd, t, namelen + path_len + attrsize);
+
+	return netfs_trans_finish(t, psb);
+
+err_out_put:
+	t->result = err;
+	netfs_trans_put(t);
+err_out_exit:
+	return err;
+}
+
+static int pohmelfs_setxattr(struct dentry *dentry, const char *name,
+		const void *value, size_t attrsize, int flags)
+{
+	struct inode *inode = dentry->d_inode;
+	struct pohmelfs_inode *pi = POHMELFS_I(inode);
+	struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+
+	if (!(psb->state_flags & POHMELFS_FLAGS_XATTR))
+		return -EOPNOTSUPP;
+
+	return pohmelfs_send_xattr_req(pi, flags, attrsize, name,
+			value, attrsize, NETFS_XATTR_SET);
+}
+
+static ssize_t pohmelfs_getxattr(struct dentry *dentry, const char *name,
+		void *value, size_t attrsize)
+{
+	struct inode *inode = dentry->d_inode;
+	struct pohmelfs_inode *pi = POHMELFS_I(inode);
+	struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+	struct pohmelfs_mcache *m;
+	int err;
+	long timeout = psb->mcache_timeout;
+
+	if (!(psb->state_flags & POHMELFS_FLAGS_XATTR))
+		return -EOPNOTSUPP;
+
+	m = pohmelfs_mcache_alloc(psb, 0, attrsize, value);
+	if (IS_ERR(m))
+		return PTR_ERR(m);
+
+	dprintk("%s: ino: %llu, name: '%s', size: %zu.\n",
+			__func__, pi->ino, name, attrsize);
+
+	err = pohmelfs_send_xattr_req(pi, m->gen, attrsize, name, value, 0, NETFS_XATTR_GET);
+	if (err)
+		goto err_out_put;
+
+	do {
+		err = wait_for_completion_timeout(&m->complete, timeout);
+		if (err) {
+			err = m->err;
+			break;
+		}
+
+		/*
+		 * This loop is a bit ugly, since it waits until reference counter
+		 * hits 1 and then put object here. Main goal is to prevent race with
+		 * network thread, when it can start processing given request, i.e.
+		 * increase its reference counter but yet not complete it, while
+		 * we will exit from ->getxattr() with timeout, and although request
+		 * will not be freed (its reference counter was increased by network
+		 * thread), data pointer provided by user may be released, so we will
+		 * overwrite already freed area in network thread.
+		 *
+		 * Now after timeout we remove request from the cache, so it can not be
+		 * found by network thread, and wait for its reference counter to hit 1,
+		 * i.e. if network thread already started to process this request, we wait
+		 * it to finish, and then free object locally. If reference counter is
+		 * already 1, i.e. request is not used by anyone else, we can free it without
+		 * problem.
+		 */
+		err = -ETIMEDOUT;
+		timeout = HZ;
+
+		pohmelfs_mcache_remove_locked(psb, m);
+	} while (atomic_read(&m->refcnt) != 1);
+
+	pohmelfs_mcache_put(psb, m);
+
+	dprintk("%s: ino: %llu, err: %d.\n", __func__, pi->ino, err);
+
+	return err;
+
+err_out_put:
+	pohmelfs_mcache_put(psb, m);
+	return err;
+}
+
+static int pohmelfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+{
+	struct inode *inode = dentry->d_inode;
+	struct pohmelfs_inode *pi = POHMELFS_I(inode);
+	int err;
+
+	err = pohmelfs_data_lock(pi, 0, ~0, POHMELFS_READ_LOCK);
+	if (err)
+		return err;
+
+	dprintk("%s: ino: %llu, mode: %o, uid: %u, gid: %u, size: %llu.\n",
+			__func__, pi->ino, inode->i_mode, inode->i_uid,
+			inode->i_gid, inode->i_size);
+
+	generic_fillattr(inode, stat);
+	return 0;
+}
+
+const struct inode_operations pohmelfs_file_inode_operations = {
+	.setattr	= pohmelfs_setattr,
+	.getattr	= pohmelfs_getattr,
+	.setxattr	= pohmelfs_setxattr,
+	.getxattr	= pohmelfs_getxattr,
+};
+
+/*
+ * Fill inode data: mode, size, operation callbacks and so on...
+ */
+void pohmelfs_fill_inode(struct inode *inode, struct netfs_inode_info *info)
+{
+	inode->i_mode = info->mode;
+	inode->i_nlink = info->nlink;
+	inode->i_uid = info->uid;
+	inode->i_gid = info->gid;
+	inode->i_blocks = info->blocks;
+	inode->i_rdev = info->rdev;
+	inode->i_size = info->size;
+	inode->i_version = info->version;
+	inode->i_blkbits = ffs(info->blocksize);
+
+	dprintk("%s: inode: %p, num: %lu/%llu inode is regular: %d, dir: %d, link: %d, mode: %o, size: %llu.\n",
+			__func__, inode, inode->i_ino, info->ino,
+			S_ISREG(inode->i_mode), S_ISDIR(inode->i_mode),
+			S_ISLNK(inode->i_mode), inode->i_mode, inode->i_size);
+
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
+
+	/*
+	 * i_mapping is a pointer to i_data during inode initialization.
+	 */
+	inode->i_data.a_ops = &pohmelfs_aops;
+
+	if (S_ISREG(inode->i_mode)) {
+		inode->i_fop = &pohmelfs_file_ops;
+		inode->i_op = &pohmelfs_file_inode_operations;
+	} else if (S_ISDIR(inode->i_mode)) {
+		inode->i_fop = &pohmelfs_dir_fops;
+		inode->i_op = &pohmelfs_dir_inode_ops;
+	} else if (S_ISLNK(inode->i_mode)) {
+		inode->i_op = &pohmelfs_symlink_inode_operations;
+		inode->i_fop = &pohmelfs_file_ops;
+	} else {
+		inode->i_fop = &generic_ro_fops;
+	}
+}
+
+static void pohmelfs_drop_inode(struct inode *inode)
+{
+	struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+	struct pohmelfs_inode *pi = POHMELFS_I(inode);
+
+	spin_lock(&psb->ino_lock);
+	list_del_init(&pi->inode_entry);
+	spin_unlock(&psb->ino_lock);
+
+	generic_drop_inode(inode);
+}
+
+static struct pohmelfs_inode *pohmelfs_get_inode_from_list(struct pohmelfs_sb *psb,
+		struct list_head *head, unsigned int *count)
+{
+	struct pohmelfs_inode *pi = NULL;
+
+	spin_lock(&psb->ino_lock);
+	if (!list_empty(head)) {
+		pi = list_entry(head->next, struct pohmelfs_inode,
+					inode_entry);
+		list_del_init(&pi->inode_entry);
+		*count = pi->drop_count;
+		pi->drop_count = 0;
+	}
+	spin_unlock(&psb->ino_lock);
+
+	return pi;
+}
+
+static void pohmelfs_flush_transactions(struct pohmelfs_sb *psb)
+{
+	struct pohmelfs_config *c;
+
+	mutex_lock(&psb->state_lock);
+	list_for_each_entry(c, &psb->state_list, config_entry) {
+		pohmelfs_state_flush_transactions(&c->state);
+	}
+	mutex_unlock(&psb->state_lock);
+}
+
+/*
+ * ->put_super() callback. Invoked before superblock is destroyed,
+ *  so it has to clean all private data.
+ */
+static void pohmelfs_put_super(struct super_block *sb)
+{
+	struct pohmelfs_sb *psb = POHMELFS_SB(sb);
+	struct pohmelfs_inode *pi;
+	unsigned int count;
+	unsigned int in_drop_list = 0;
+	struct inode *inode, *tmp;
+
+	dprintk("%s.\n", __func__);
+
+	/*
+	 * Kill pending transactions, which could affect inodes in-flight.
+	 */
+	pohmelfs_flush_transactions(psb);
+
+	while ((pi = pohmelfs_get_inode_from_list(psb, &psb->drop_list, &count))) {
+		inode = &pi->vfs_inode;
+
+		dprintk("%s: ino: %llu, pi: %p, inode: %p, count: %u.\n",
+				__func__, pi->ino, pi, inode, count);
+
+		if (atomic_read(&inode->i_count) != count) {
+			printk("%s: ino: %llu, pi: %p, inode: %p, count: %u, i_count: %d.\n",
+					__func__, pi->ino, pi, inode, count,
+					atomic_read(&inode->i_count));
+			count = atomic_read(&inode->i_count);
+			in_drop_list++;
+		}
+
+		while (count--)
+			iput(&pi->vfs_inode);
+	}
+
+	list_for_each_entry_safe(inode, tmp, &sb->s_inodes, i_sb_list) {
+		pi = POHMELFS_I(inode);
+
+		dprintk("%s: ino: %llu, pi: %p, inode: %p, i_count: %u.\n",
+				__func__, pi->ino, pi, inode, atomic_read(&inode->i_count));
+
+		/*
+		 * These are special inodes, they were created during
+		 * directory reading or lookup, and were not bound to dentry,
+		 * so they live here with reference counter being 1 and prevent
+		 * umount from succeed since it believes that they are busy.
+		 */
+		count = atomic_read(&inode->i_count);
+		if (count) {
+			list_del_init(&inode->i_sb_list);
+			while (count--)
+				iput(&pi->vfs_inode);
+		}
+	}
+
+	psb->trans_scan_timeout = psb->drop_scan_timeout = 0;
+	cancel_rearming_delayed_work(&psb->dwork);
+	cancel_rearming_delayed_work(&psb->drop_dwork);
+	flush_scheduled_work();
+
+	dprintk("%s: stopped workqueues.\n", __func__);
+
+	pohmelfs_crypto_exit(psb);
+	pohmelfs_state_exit(psb);
+
+	kfree(psb);
+	sb->s_fs_info = NULL;
+
+	pohmelfs_ftrans_exit();
+}
+
+static int pohmelfs_remount(struct super_block *sb, int *flags, char *data)
+{
+	*flags |= MS_RDONLY;
+	return 0;
+}
+
+static int pohmelfs_statfs(struct dentry *dentry, struct kstatfs *buf)
+{
+	struct super_block *sb = dentry->d_sb;
+	struct pohmelfs_sb *psb = POHMELFS_SB(sb);
+
+	/*
+	 * There are no filesystem size limits yet.
+	 */
+	memset(buf, 0, sizeof(struct kstatfs));
+
+	buf->f_type = POHMELFS_MAGIC_NUM; /* 'POH.' */
+	buf->f_bsize = sb->s_blocksize;
+	buf->f_files = psb->ino;
+	buf->f_namelen = 255;
+	buf->f_files = atomic_long_read(&psb->total_inodes);
+	buf->f_bfree = buf->f_bavail = psb->avail_size >> PAGE_SHIFT;
+	buf->f_blocks = psb->total_size >> PAGE_SHIFT;
+
+	dprintk("%s: total: %llu, avail: %llu, inodes: %llu, bsize: %lu.\n",
+		__func__, psb->total_size, psb->avail_size, buf->f_files, sb->s_blocksize);
+
+	return 0;
+}
+
+static int pohmelfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
+{
+	struct pohmelfs_sb *psb = POHMELFS_SB(vfs->mnt_sb);
+
+	seq_printf(seq, ",idx=%u", psb->idx);
+	seq_printf(seq, ",trans_scan_timeout=%u", jiffies_to_msecs(psb->trans_scan_timeout));
+	seq_printf(seq, ",drop_scan_timeout=%u", jiffies_to_msecs(psb->drop_scan_timeout));
+	seq_printf(seq, ",wait_on_page_timeout=%u", jiffies_to_msecs(psb->wait_on_page_timeout));
+	seq_printf(seq, ",trans_retries=%u", psb->trans_retries);
+	seq_printf(seq, ",crypto_thread_num=%u", psb->crypto_thread_num);
+	seq_printf(seq, ",trans_max_pages=%u", psb->trans_max_pages);
+	seq_printf(seq, ",mcache_timeout=%u", jiffies_to_msecs(psb->mcache_timeout));
+	if (psb->crypto_fail_unsupported)
+		seq_printf(seq, ",crypto_fail_unsupported");
+
+	return 0;
+}
+
+static const struct super_operations pohmelfs_sb_ops = {
+	.alloc_inode	= pohmelfs_alloc_inode,
+	.destroy_inode	= pohmelfs_destroy_inode,
+	.drop_inode	= pohmelfs_drop_inode,
+	.write_inode	= pohmelfs_write_inode,
+	.put_super	= pohmelfs_put_super,
+	.remount_fs	= pohmelfs_remount,
+	.statfs		= pohmelfs_statfs,
+	.show_options	= pohmelfs_show_options,
+};
+
+enum {
+	pohmelfs_opt_idx,
+	pohmelfs_opt_trans_scan_timeout,
+	pohmelfs_opt_drop_scan_timeout,
+	pohmelfs_opt_wait_on_page_timeout,
+	pohmelfs_opt_trans_retries,
+	pohmelfs_opt_crypto_thread_num,
+	pohmelfs_opt_trans_max_pages,
+	pohmelfs_opt_crypto_fail_unsupported,
+	pohmelfs_opt_mcache_timeout,
+};
+
+static struct match_token pohmelfs_tokens[] = {
+	{pohmelfs_opt_idx, "idx=%u"},
+	{pohmelfs_opt_trans_scan_timeout, "trans_scan_timeout=%u"},
+	{pohmelfs_opt_drop_scan_timeout, "drop_scan_timeout=%u"},
+	{pohmelfs_opt_wait_on_page_timeout, "wait_on_page_timeout=%u"},
+	{pohmelfs_opt_trans_retries, "trans_retries=%u"},
+	{pohmelfs_opt_crypto_thread_num, "crypto_thread_num=%u"},
+	{pohmelfs_opt_trans_max_pages, "trans_max_pages=%u"},
+	{pohmelfs_opt_crypto_fail_unsupported, "crypto_fail_unsupported"},
+	{pohmelfs_opt_mcache_timeout, "mcache_timeout=%u"},
+};
+
+static int pohmelfs_parse_options(char *options, struct pohmelfs_sb *psb)
+{
+	char *p;
+	substring_t args[MAX_OPT_ARGS];
+	int option, err;
+
+	if (!options)
+		return 0;
+
+	while ((p = strsep(&options, ",")) != NULL) {
+		int token;
+		if (!*p)
+			continue;
+
+		token = match_token(p, pohmelfs_tokens, args);
+
+		err = match_int(&args[0], &option);
+		if (err)
+			return err;
+
+		switch (token) {
+			case pohmelfs_opt_idx:
+				psb->idx = option;
+				break;
+			case pohmelfs_opt_trans_scan_timeout:
+				psb->trans_scan_timeout = msecs_to_jiffies(option);
+				break;
+			case pohmelfs_opt_drop_scan_timeout:
+				psb->drop_scan_timeout = msecs_to_jiffies(option);
+				break;
+			case pohmelfs_opt_wait_on_page_timeout:
+				psb->wait_on_page_timeout = msecs_to_jiffies(option);
+				break;
+			case pohmelfs_opt_mcache_timeout:
+				psb->mcache_timeout = msecs_to_jiffies(option);
+				break;
+			case pohmelfs_opt_trans_retries:
+				psb->trans_retries = option;
+				break;
+			case pohmelfs_opt_crypto_thread_num:
+				psb->crypto_thread_num = option;
+				break;
+			case pohmelfs_opt_trans_max_pages:
+				psb->trans_max_pages = option;
+				break;
+			case pohmelfs_opt_crypto_fail_unsupported:
+				psb->crypto_fail_unsupported = 1;
+				break;
+			default:
+				return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static void pohmelfs_flush_inode(struct pohmelfs_inode *pi, unsigned int count)
+{
+	struct inode *inode = &pi->vfs_inode;
+
+	dprintk("%s: %p: ino: %llu, owned: %d.\n",
+		__func__, inode, pi->ino, test_bit(NETFS_INODE_OWNED, &pi->state));
+
+	mutex_lock(&inode->i_mutex);
+	if (test_and_clear_bit(NETFS_INODE_OWNED, &pi->state)) {
+		filemap_fdatawrite(inode->i_mapping);
+		inode->i_sb->s_op->write_inode(inode, 0);
+	}
+
+	truncate_inode_pages(inode->i_mapping, 0);
+
+	pohmelfs_data_unlock(pi, 0, ~0, POHMELFS_WRITE_LOCK);
+	mutex_unlock(&inode->i_mutex);
+}
+
+static void pohmelfs_put_inode_count(struct pohmelfs_inode *pi, unsigned int count)
+{
+	dprintk("%s: ino: %llu, pi: %p, inode: %p, count: %u.\n",
+			__func__, pi->ino, pi, &pi->vfs_inode, count);
+
+	if (test_and_clear_bit(NETFS_INODE_NEED_FLUSH, &pi->state))
+		pohmelfs_flush_inode(pi, count);
+
+	while (count--)
+		iput(&pi->vfs_inode);
+}
+
+static void pohmelfs_drop_scan(struct work_struct *work)
+{
+	struct pohmelfs_sb *psb =
+		container_of(work, struct pohmelfs_sb, drop_dwork.work);
+	struct pohmelfs_inode *pi;
+	unsigned int count = 0;
+
+	while ((pi = pohmelfs_get_inode_from_list(psb, &psb->drop_list, &count))) {
+		pohmelfs_put_inode_count(pi, count);
+	}
+	pohmelfs_check_states(psb);
+
+	if (psb->drop_scan_timeout)
+		schedule_delayed_work(&psb->drop_dwork, psb->drop_scan_timeout);
+}
+
+/*
+ * Run through all transactions starting from the oldest,
+ * drop transaction from current state and try to send it
+ * to all remote nodes, which are currently installed.
+ */
+static void pohmelfs_trans_scan_state(struct netfs_state *st)
+{
+	struct rb_node *rb_node;
+	struct netfs_trans_dst *dst;
+	struct pohmelfs_sb *psb = st->psb;
+	unsigned int timeout = psb->trans_scan_timeout;
+	struct netfs_trans *t;
+	int err;
+
+	mutex_lock(&st->trans_lock);
+	for (rb_node = rb_first(&st->trans_root); rb_node; ) {
+		dst = rb_entry(rb_node, struct netfs_trans_dst, state_entry);
+		t = dst->trans;
+
+		if (timeout && time_after(dst->send_time + timeout, jiffies)
+				&& dst->retries == 0)
+			break;
+
+		dprintk("%s: t: %p, gen: %u, st: %p, retries: %u, max: %u.\n",
+			__func__, t, t->gen, st, dst->retries, psb->trans_retries);
+		netfs_trans_get(t);
+
+		rb_node = rb_next(rb_node);
+
+		err = -ETIMEDOUT;
+		if (timeout && (++dst->retries < psb->trans_retries)) {
+			err = netfs_trans_resend(t, psb);
+		}
+
+		if (err || (t->flags & NETFS_TRANS_SINGLE_DST)) {
+			if (netfs_trans_remove_nolock(dst, st))
+				netfs_trans_drop_dst_nostate(dst);
+		}
+
+		t->result = err;
+		netfs_trans_put(t);
+	}
+	mutex_unlock(&st->trans_lock);
+}
+
+/*
+ * Walk through all installed network states and resend all
+ * transactions, which are old enough.
+ */
+static void pohmelfs_trans_scan(struct work_struct *work)
+{
+	struct pohmelfs_sb *psb =
+		container_of(work, struct pohmelfs_sb, dwork.work);
+	struct netfs_state *st;
+	struct pohmelfs_config *c;
+
+	mutex_lock(&psb->state_lock);
+	list_for_each_entry(c, &psb->state_list, config_entry) {
+		st = &c->state;
+
+		pohmelfs_trans_scan_state(st);
+	}
+	mutex_unlock(&psb->state_lock);
+
+	/*
+	 * If no timeout specified then system is in the middle of umount process,
+	 * so no need to reschedule scanning process again.
+	 */
+	if (psb->trans_scan_timeout)
+		schedule_delayed_work(&psb->dwork, psb->trans_scan_timeout);
+}
+
+int pohmelfs_meta_command_data(struct pohmelfs_inode *pi, u64 id, unsigned int cmd_op, char *addon,
+		unsigned int flags, netfs_trans_complete_t complete, void *priv, u64 start)
+{
+	struct inode *inode = &pi->vfs_inode;
+	struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+	int err = 0, sz;
+	struct netfs_trans *t;
+	int path_len, addon_len = 0;
+	void *data;
+	struct netfs_inode_info *info;
+	struct netfs_cmd *cmd;
+
+	dprintk("%s: ino: %llu, cmd: %u, addon: %p.\n", __func__, pi->ino, cmd_op, addon);
+
+	path_len = pohmelfs_path_length(pi);
+	if (path_len < 0) {
+		err = path_len;
+		goto err_out_exit;
+	}
+
+	if (addon)
+		addon_len = strlen(addon) + 1; /* 0-byte */
+	sz = addon_len;
+
+	if (cmd_op == NETFS_INODE_INFO)
+		sz += sizeof(struct netfs_inode_info);
+
+	t = netfs_trans_alloc(psb, sz + path_len, flags, 0);
+	if (!t) {
+		err = -ENOMEM;
+		goto err_out_exit;
+	}
+	t->complete = complete;
+	t->private = priv;
+
+	cmd = netfs_trans_current(t);
+	data = (void *)(cmd + 1);
+
+	if (cmd_op == NETFS_INODE_INFO) {
+		info = (struct netfs_inode_info *)(cmd + 1);
+		data = (void *)(info + 1);
+
+		/*
+		 * We are under i_mutex, can read and change whatever we want...
+		 */
+		info->mode = inode->i_mode;
+		info->nlink = inode->i_nlink;
+		info->uid = inode->i_uid;
+		info->gid = inode->i_gid;
+		info->blocks = inode->i_blocks;
+		info->rdev = inode->i_rdev;
+		info->size = inode->i_size;
+		info->version = inode->i_version;
+
+		netfs_convert_inode_info(info);
+	}
+
+	path_len = pohmelfs_construct_path_string(pi, data, path_len);
+	if (path_len < 0)
+		goto err_out_free;
+
+	dprintk("%s: path_len: %d.\n", __func__, path_len);
+
+	if (addon) {
+		path_len--; /* Do not place null-byte before the addon */
+		path_len += sprintf(data + path_len, "/%s", addon) + 1; /* 0 - byte */
+	}
+
+	sz += path_len;
+
+	cmd->cmd = cmd_op;
+	cmd->ext = path_len;
+	cmd->size = sz;
+	cmd->id = id;
+	cmd->start = start;
+
+	netfs_convert_cmd(cmd);
+	netfs_trans_update(cmd, t, sz);
+
+	/*
+	 * Note, that it is possible to leak error here: transaction callback will not
+	 * be invoked for allocation path failure.
+	 */
+	return netfs_trans_finish(t, psb);
+
+err_out_free:
+	netfs_trans_free(t);
+err_out_exit:
+	if (complete)
+		complete(NULL, 0, priv, err);
+	return err;
+}
+
+int pohmelfs_meta_command(struct pohmelfs_inode *pi, unsigned int cmd_op, unsigned int flags,
+		netfs_trans_complete_t complete, void *priv, u64 start)
+{
+	return pohmelfs_meta_command_data(pi, pi->ino, cmd_op, NULL, flags, complete, priv, start);
+}
+
+/*
+ * Send request and wait for POHMELFS root capabilities response,
+ * which will update server's informaion about size of the export,
+ * permissions, number of objects, available size and so on.
+ */
+static int pohmelfs_root_handshake(struct pohmelfs_sb *psb)
+{
+	struct netfs_trans *t;
+	struct netfs_cmd *cmd;
+	int err = -ENOMEM;
+
+	t = netfs_trans_alloc(psb, 0, 0, 0);
+	if (!t)
+		goto err_out_exit;
+
+	cmd = netfs_trans_current(t);
+
+	cmd->cmd = NETFS_CAPABILITIES;
+	cmd->id = POHMELFS_ROOT_CAPABILITIES;
+	cmd->size = 0;
+	cmd->start = 0;
+	cmd->ext = 0;
+	cmd->csize = 0;
+
+	netfs_convert_cmd(cmd);
+	netfs_trans_update(cmd, t, 0);
+
+	err = netfs_trans_finish(t, psb);
+	if (err)
+		goto err_out_exit;
+
+	psb->flags = ~0;
+	err = wait_event_interruptible_timeout(psb->wait,
+			(psb->flags != ~0),
+			psb->wait_on_page_timeout);
+	if (!err) {
+		err = -ETIMEDOUT;
+	} else {
+		err = -psb->flags;
+	}
+
+	if (err)
+		goto err_out_exit;
+
+	return 0;
+
+err_out_exit:
+	return err;
+}
+
+/*
+ * Allocate private superblock and create root dir.
+ */
+static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent)
+{
+	struct pohmelfs_sb *psb;
+	int err = -ENOMEM;
+	struct inode *root;
+	struct pohmelfs_inode *npi;
+	struct qstr str;
+
+	pohmelfs_ftrans_init();
+
+	psb = kzalloc(sizeof(struct pohmelfs_sb), GFP_KERNEL);
+	if (!psb)
+		goto err_out_exit;
+
+	sb->s_fs_info = psb;
+	sb->s_op = &pohmelfs_sb_ops;
+	sb->s_magic = POHMELFS_MAGIC_NUM;
+	sb->s_maxbytes = MAX_LFS_FILESIZE;
+	sb->s_blocksize = PAGE_SIZE;
+
+	psb->sb = sb;
+
+	psb->ino = 2;
+	psb->idx = 0;
+	psb->active_state = NULL;
+	psb->trans_retries = 5;
+	psb->trans_data_size = PAGE_SIZE;
+	psb->drop_scan_timeout = msecs_to_jiffies(1000);
+	psb->trans_scan_timeout = msecs_to_jiffies(5000);
+	psb->wait_on_page_timeout = msecs_to_jiffies(5000);
+	init_waitqueue_head(&psb->wait);
+
+	spin_lock_init(&psb->ino_lock);
+
+	INIT_LIST_HEAD(&psb->drop_list);
+
+	mutex_init(&psb->mcache_lock);
+	psb->mcache_root = RB_ROOT;
+	psb->mcache_timeout = msecs_to_jiffies(5000);
+	atomic_long_set(&psb->mcache_gen, 0);
+
+	psb->trans_max_pages = 100;
+
+	psb->crypto_align_size = 16;
+	psb->crypto_attached_size = 0;
+	psb->hash_strlen = 0;
+	psb->cipher_strlen = 0;
+	psb->perform_crypto = 0;
+	psb->crypto_thread_num = 2;
+	psb->crypto_fail_unsupported = 0;
+	mutex_init(&psb->crypto_thread_lock);
+	INIT_LIST_HEAD(&psb->crypto_ready_list);
+	INIT_LIST_HEAD(&psb->crypto_active_list);
+
+	atomic_set(&psb->trans_gen, 1);
+	atomic_set(&psb->total_inodes, 0);
+
+	mutex_init(&psb->state_lock);
+	INIT_LIST_HEAD(&psb->state_list);
+
+	err = pohmelfs_parse_options((char *) data, psb);
+	if (err)
+		goto err_out_free_sb;
+
+	err = pohmelfs_copy_crypto(psb);
+	if (err)
+		goto err_out_free_sb;
+
+	err = pohmelfs_state_init(psb);
+	if (err)
+		goto err_out_free_strings;
+
+	err = pohmelfs_crypto_init(psb);
+	if (err)
+		goto err_out_state_exit;
+
+	err = pohmelfs_root_handshake(psb);
+	if (err)
+		goto err_out_crypto_exit;
+
+	str.name = "/";
+	str.hash = jhash("/", 1, 0);
+	str.len = 1;
+
+	npi = pohmelfs_create_entry_local(psb, NULL, &str, 0, 0755|S_IFDIR);
+	if (IS_ERR(npi)) {
+		err = PTR_ERR(npi);
+		goto err_out_crypto_exit;
+	}
+
+	root = &npi->vfs_inode;
+
+	sb->s_root = d_alloc_root(root);
+	if (!sb->s_root)
+		goto err_out_put_root;
+
+	INIT_DELAYED_WORK(&psb->drop_dwork, pohmelfs_drop_scan);
+	schedule_delayed_work(&psb->drop_dwork, psb->drop_scan_timeout);
+
+	INIT_DELAYED_WORK(&psb->dwork, pohmelfs_trans_scan);
+	schedule_delayed_work(&psb->dwork, psb->trans_scan_timeout);
+
+	return 0;
+
+err_out_put_root:
+	iput(root);
+err_out_crypto_exit:
+	pohmelfs_crypto_exit(psb);
+err_out_state_exit:
+	pohmelfs_state_exit(psb);
+err_out_free_strings:
+	kfree(psb->cipher_string);
+	kfree(psb->hash_string);
+err_out_free_sb:
+	kfree(psb);
+err_out_exit:
+
+	dprintk("%s: err: %d.\n", __func__, err);
+	return err;
+}
+
+/*
+ * Some VFS magic here...
+ */
+static int pohmelfs_get_sb(struct file_system_type *fs_type,
+	int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+{
+	return get_sb_nodev(fs_type, flags, data, pohmelfs_fill_super,
+				mnt);
+}
+
+static struct file_system_type pohmel_fs_type = {
+	.owner		= THIS_MODULE,
+	.name		= "pohmel",
+	.get_sb		= pohmelfs_get_sb,
+	.kill_sb 	= kill_anon_super,
+};
+
+/*
+ * Cache and module initializations and freeing routings.
+ */
+static void pohmelfs_init_once(void *data)
+{
+	struct pohmelfs_inode *pi = data;
+
+	inode_init_once(&pi->vfs_inode);
+}
+
+static int __init pohmelfs_init_inodecache(void)
+{
+	pohmelfs_inode_cache = kmem_cache_create("pohmelfs_inode_cache",
+				sizeof(struct pohmelfs_inode),
+				0, (SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD),
+				pohmelfs_init_once);
+	if (!pohmelfs_inode_cache)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static void pohmelfs_destroy_inodecache(void)
+{
+	kmem_cache_destroy(pohmelfs_inode_cache);
+}
+
+static int __init init_pohmel_fs(void)
+{
+	int err;
+
+	err = pohmelfs_config_init();
+	if (err)
+		goto err_out_exit;
+
+	err = pohmelfs_init_inodecache();
+	if (err)
+		goto err_out_config_exit;
+
+	err = pohmelfs_mcache_init();
+	if (err)
+		goto err_out_destroy;
+
+	err = netfs_trans_init();
+	if (err)
+		goto err_out_mcache_exit;
+
+	err = register_filesystem(&pohmel_fs_type);
+	if (err)
+		goto err_out_trans;
+
+	return 0;
+
+err_out_trans:
+	netfs_trans_exit();
+err_out_mcache_exit:
+	pohmelfs_mcache_exit();
+err_out_destroy:
+	pohmelfs_destroy_inodecache();
+err_out_config_exit:
+	pohmelfs_config_exit();
+err_out_exit:
+	return err;
+}
+
+static void __exit exit_pohmel_fs(void)
+{
+        unregister_filesystem(&pohmel_fs_type);
+	pohmelfs_destroy_inodecache();
+	pohmelfs_mcache_exit();
+	pohmelfs_config_exit();
+	netfs_trans_exit();
+}
+
+module_init(init_pohmel_fs);
+module_exit(exit_pohmel_fs);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>");
+MODULE_DESCRIPTION("Pohmel filesystem");
diff --git a/drivers/staging/pohmelfs/lock.c b/drivers/staging/pohmelfs/lock.c
new file mode 100644
index 0000000..ad4a185
--- /dev/null
+++ b/drivers/staging/pohmelfs/lock.c
@@ -0,0 +1,182 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * 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.
+ *
+ * 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/module.h>
+#include <linux/backing-dev.h>
+#include <linux/fs.h>
+#include <linux/fsnotify.h>
+#include <linux/slab.h>
+#include <linux/mempool.h>
+
+#include "netfs.h"
+
+static int pohmelfs_send_lock_trans(struct pohmelfs_inode *pi,
+		u64 id, u64 start, u32 size, int type)
+{
+	struct inode *inode = &pi->vfs_inode;
+	struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+	struct netfs_trans *t;
+	struct netfs_cmd *cmd;
+	int path_len, err;
+	void *data;
+	struct netfs_lock *l;
+	int isize = (type & POHMELFS_LOCK_GRAB) ? 0 : sizeof(struct netfs_inode_info);
+
+	err = pohmelfs_path_length(pi);
+	if (err < 0)
+		goto err_out_exit;
+
+	path_len = err;
+
+	err = -ENOMEM;
+	t = netfs_trans_alloc(psb, path_len + sizeof(struct netfs_lock) + isize, 0, 0);
+	if (!t)
+		goto err_out_exit;
+
+	cmd = netfs_trans_current(t);
+	data = cmd + 1;
+
+	err = pohmelfs_construct_path_string(pi, data, path_len);
+	if (err < 0)
+		goto err_out_free;
+	path_len = err;
+
+	l = data + path_len;
+
+	l->start = start;
+	l->size = size;
+	l->type = type;
+	l->ino = pi->ino;
+
+	cmd->cmd = NETFS_LOCK;
+	cmd->start = 0;
+	cmd->id = id;
+	cmd->size = sizeof(struct netfs_lock) + path_len + isize;
+	cmd->ext = path_len;
+	cmd->csize = 0;
+
+	netfs_convert_cmd(cmd);
+	netfs_convert_lock(l);
+
+	if (isize) {
+		struct netfs_inode_info *info = (struct netfs_inode_info *)(l + 1);
+
+		info->mode = inode->i_mode;
+		info->nlink = inode->i_nlink;
+		info->uid = inode->i_uid;
+		info->gid = inode->i_gid;
+		info->blocks = inode->i_blocks;
+		info->rdev = inode->i_rdev;
+		info->size = inode->i_size;
+		info->version = inode->i_version;
+
+		netfs_convert_inode_info(info);
+	}
+
+	netfs_trans_update(cmd, t, path_len + sizeof(struct netfs_lock) + isize);
+
+	return netfs_trans_finish(t, psb);
+
+err_out_free:
+	netfs_trans_free(t);
+err_out_exit:
+	printk("%s: err: %d.\n", __func__, err);
+	return err;
+}
+
+int pohmelfs_data_lock(struct pohmelfs_inode *pi, u64 start, u32 size, int type)
+{
+	struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
+	struct pohmelfs_mcache *m;
+	int err = -ENOMEM;
+	struct iattr iattr;
+	struct inode *inode = &pi->vfs_inode;
+
+	dprintk("%s: %p: ino: %llu, start: %llu, size: %u, "
+			"type: %d, locked as: %d, owned: %d.\n",
+			__func__, &pi->vfs_inode, pi->ino,
+			start, size, type, pi->lock_type,
+			!!test_bit(NETFS_INODE_OWNED, &pi->state));
+
+	if (!pohmelfs_need_lock(pi, type))
+		return 0;
+
+	m = pohmelfs_mcache_alloc(psb, start, size, NULL);
+	if (IS_ERR(m))
+		return PTR_ERR(m);
+
+	err = pohmelfs_send_lock_trans(pi, m->gen, start, size,
+			type | POHMELFS_LOCK_GRAB);
+	if (err)
+		goto err_out_put;
+
+	err = wait_for_completion_timeout(&m->complete, psb->mcache_timeout);
+	if (err)
+		err = m->err;
+	else
+		err = -ETIMEDOUT;
+
+	if (err) {
+		printk("%s: %p: ino: %llu, mgen: %llu, start: %llu, size: %u, err: %d.\n",
+			__func__, &pi->vfs_inode, pi->ino, m->gen, start, size, err);
+	}
+
+	if (err && (err != -ENOENT))
+		goto err_out_put;
+
+	if (!err) {
+		netfs_convert_inode_info(&m->info);
+
+		iattr.ia_valid = ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_SIZE | ATTR_ATIME;
+		iattr.ia_mode = m->info.mode;
+		iattr.ia_uid = m->info.uid;
+		iattr.ia_gid = m->info.gid;
+		iattr.ia_size = m->info.size;
+		iattr.ia_atime = CURRENT_TIME;
+
+		dprintk("%s: %p: ino: %llu, mgen: %llu, start: %llu, isize: %llu -> %llu.\n",
+			__func__, &pi->vfs_inode, pi->ino, m->gen, start, inode->i_size, m->info.size);
+
+		err = pohmelfs_setattr_raw(inode, &iattr);
+		if (!err) {
+			struct dentry *dentry = d_find_alias(inode);
+			if (dentry) {
+				fsnotify_change(dentry, iattr.ia_valid);
+				dput(dentry);
+			}
+		}
+	}
+
+	pi->lock_type = type;
+	set_bit(NETFS_INODE_OWNED, &pi->state);
+
+	pohmelfs_mcache_put(psb, m);
+
+	return 0;
+
+err_out_put:
+	pohmelfs_mcache_put(psb, m);
+	return err;
+}
+
+int pohmelfs_data_unlock(struct pohmelfs_inode *pi, u64 start, u32 size, int type)
+{
+	dprintk("%s: %p: ino: %llu, start: %llu, size: %u, type: %d.\n",
+			__func__, &pi->vfs_inode, pi->ino, start, size, type);
+	pi->lock_type = 0;
+	clear_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &pi->state);
+	clear_bit(NETFS_INODE_OWNED, &pi->state);
+	return pohmelfs_send_lock_trans(pi, pi->ino, start, size, type);
+}
diff --git a/drivers/staging/pohmelfs/mcache.c b/drivers/staging/pohmelfs/mcache.c
new file mode 100644
index 0000000..e22665c
--- /dev/null
+++ b/drivers/staging/pohmelfs/mcache.c
@@ -0,0 +1,171 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * 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.
+ *
+ * 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/module.h>
+#include <linux/slab.h>
+#include <linux/mempool.h>
+
+#include "netfs.h"
+
+static struct kmem_cache *pohmelfs_mcache_cache;
+static mempool_t *pohmelfs_mcache_pool;
+
+static inline int pohmelfs_mcache_cmp(u64 gen, u64 new)
+{
+	if (gen < new)
+		return 1;
+	if (gen > new)
+		return -1;
+	return 0;
+}
+
+struct pohmelfs_mcache *pohmelfs_mcache_search(struct pohmelfs_sb *psb, u64 gen)
+{
+	struct rb_root *root = &psb->mcache_root;
+	struct rb_node *n = root->rb_node;
+	struct pohmelfs_mcache *tmp, *ret = NULL;
+	int cmp;
+
+	while (n) {
+		tmp = rb_entry(n, struct pohmelfs_mcache, mcache_entry);
+
+		cmp = pohmelfs_mcache_cmp(tmp->gen, gen);
+		if (cmp < 0)
+			n = n->rb_left;
+		else if (cmp > 0)
+			n = n->rb_right;
+		else {
+			ret = tmp;
+			pohmelfs_mcache_get(ret);
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static int pohmelfs_mcache_insert(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m)
+{
+	struct rb_root *root = &psb->mcache_root;
+	struct rb_node **n = &root->rb_node, *parent = NULL;
+	struct pohmelfs_mcache *ret = NULL, *tmp;
+	int cmp;
+
+	while (*n) {
+		parent = *n;
+
+		tmp = rb_entry(parent, struct pohmelfs_mcache, mcache_entry);
+
+		cmp = pohmelfs_mcache_cmp(tmp->gen, m->gen);
+		if (cmp < 0)
+			n = &parent->rb_left;
+		else if (cmp > 0)
+			n = &parent->rb_right;
+		else {
+			ret = tmp;
+			break;
+		}
+	}
+
+	if (ret)
+		return -EEXIST;
+
+	rb_link_node(&m->mcache_entry, parent, n);
+	rb_insert_color(&m->mcache_entry, root);
+
+	return 0;
+}
+
+static int pohmelfs_mcache_remove(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m)
+{
+	if (m && m->mcache_entry.rb_parent_color) {
+		rb_erase(&m->mcache_entry, &psb->mcache_root);
+		m->mcache_entry.rb_parent_color = 0;
+		return 1;
+	}
+	return 0;
+}
+
+void pohmelfs_mcache_remove_locked(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m)
+{
+	mutex_lock(&psb->mcache_lock);
+	pohmelfs_mcache_remove(psb, m);
+	mutex_unlock(&psb->mcache_lock);
+}
+
+struct pohmelfs_mcache *pohmelfs_mcache_alloc(struct pohmelfs_sb *psb, u64 start,
+		unsigned int size, void *data)
+{
+	struct pohmelfs_mcache *m;
+	int err = -ENOMEM;
+
+	m = mempool_alloc(pohmelfs_mcache_pool, GFP_KERNEL);
+	if (!m)
+		goto err_out_exit;
+
+	init_completion(&m->complete);
+	m->err = 0;
+	atomic_set(&m->refcnt, 1);
+	m->data = data;
+	m->start = start;
+	m->size = size;
+	m->gen = atomic_long_inc_return(&psb->mcache_gen);
+
+	mutex_lock(&psb->mcache_lock);
+	err = pohmelfs_mcache_insert(psb, m);
+	mutex_unlock(&psb->mcache_lock);
+	if (err)
+		goto err_out_free;
+
+	return m;
+
+err_out_free:
+	mempool_free(m, pohmelfs_mcache_pool);
+err_out_exit:
+	return ERR_PTR(err);
+}
+
+void pohmelfs_mcache_free(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m)
+{
+	pohmelfs_mcache_remove_locked(psb, m);
+
+	mempool_free(m, pohmelfs_mcache_pool);
+}
+
+int __init pohmelfs_mcache_init(void)
+{
+	pohmelfs_mcache_cache = kmem_cache_create("pohmelfs_mcache_cache",
+				sizeof(struct pohmelfs_mcache),
+				0, (SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD), NULL);
+	if (!pohmelfs_mcache_cache)
+		goto err_out_exit;
+
+	pohmelfs_mcache_pool = mempool_create_slab_pool(256, pohmelfs_mcache_cache);
+	if (!pohmelfs_mcache_pool)
+		goto err_out_free;
+
+	return 0;
+
+err_out_free:
+	kmem_cache_destroy(pohmelfs_mcache_cache);
+err_out_exit:
+	return -ENOMEM;
+}
+
+void pohmelfs_mcache_exit(void)
+{
+	mempool_destroy(pohmelfs_mcache_pool);
+	kmem_cache_destroy(pohmelfs_mcache_cache);
+}
diff --git a/drivers/staging/pohmelfs/net.c b/drivers/staging/pohmelfs/net.c
new file mode 100644
index 0000000..c9b8540
--- /dev/null
+++ b/drivers/staging/pohmelfs/net.c
@@ -0,0 +1,1247 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * 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.
+ *
+ * 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/fsnotify.h>
+#include <linux/jhash.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/kthread.h>
+#include <linux/pagemap.h>
+#include <linux/poll.h>
+#include <linux/swap.h>
+#include <linux/syscalls.h>
+#include <linux/vmalloc.h>
+
+#include "netfs.h"
+
+static int pohmelfs_ftrans_size = 10240;
+static u32 *pohmelfs_ftrans;
+
+int pohmelfs_ftrans_init(void)
+{
+	pohmelfs_ftrans = vmalloc(pohmelfs_ftrans_size * 4);
+	if (!pohmelfs_ftrans)
+		return -ENOMEM;
+
+	return 0;
+}
+
+void pohmelfs_ftrans_exit(void)
+{
+	vfree(pohmelfs_ftrans);
+}
+
+void pohmelfs_ftrans_clean(u64 id)
+{
+	if (pohmelfs_ftrans) {
+		u32 i = id & 0xffffffff;
+		int idx = i % pohmelfs_ftrans_size;
+
+		pohmelfs_ftrans[idx] = 0;
+	}
+}
+
+void pohmelfs_ftrans_update(u64 id)
+{
+	if (pohmelfs_ftrans) {
+		u32 i = id & 0xffffffff;
+		int idx = i % pohmelfs_ftrans_size;
+
+		pohmelfs_ftrans[idx] = i;
+	}
+}
+
+int pohmelfs_ftrans_check(u64 id)
+{
+	if (pohmelfs_ftrans) {
+		u32 i = id & 0xffffffff;
+		int idx = i % pohmelfs_ftrans_size;
+
+		return (pohmelfs_ftrans[idx] == i);
+	}
+
+	return -1;
+}
+
+/*
+ * Async machinery lives here.
+ * All commands being sent to server do _not_ require sync reply,
+ * instead, if it is really needed, like readdir or readpage, caller
+ * sleeps waiting for data, which will be placed into provided buffer
+ * and caller will be awakened.
+ *
+ * Every command response can come without some listener. For example
+ * readdir response will add new objects into cache without appropriate
+ * request from userspace. This is used in cache coherency.
+ *
+ * If object is not found for given data, it is discarded.
+ *
+ * All requests are received by dedicated kernel thread.
+ */
+
+/*
+ * Basic network sending/receiving functions.
+ * Blocked mode is used.
+ */
+static int netfs_data_recv(struct netfs_state *st, void *buf, u64 size)
+{
+	struct msghdr msg;
+	struct kvec iov;
+	int err;
+
+	BUG_ON(!size);
+
+	iov.iov_base = buf;
+	iov.iov_len = size;
+
+	msg.msg_iov = (struct iovec *)&iov;
+	msg.msg_iovlen = 1;
+	msg.msg_name = NULL;
+	msg.msg_namelen = 0;
+	msg.msg_control = NULL;
+	msg.msg_controllen = 0;
+	msg.msg_flags = MSG_DONTWAIT;
+
+	err = kernel_recvmsg(st->socket, &msg, &iov, 1, iov.iov_len,
+			msg.msg_flags);
+	if (err <= 0) {
+		printk("%s: failed to recv data: size: %llu, err: %d.\n", __func__, size, err);
+		if (err == 0)
+			err = -ECONNRESET;
+	}
+
+	return err;
+}
+
+static int pohmelfs_data_recv(struct netfs_state *st, void *data, unsigned int size)
+{
+	unsigned int revents = 0;
+	unsigned int err_mask = POLLERR | POLLHUP | POLLRDHUP;
+	unsigned int mask = err_mask | POLLIN;
+	int err = 0;
+
+	while (size && !err) {
+		revents = netfs_state_poll(st);
+
+		if (!(revents & mask)) {
+			DEFINE_WAIT(wait);
+
+			for (;;) {
+				prepare_to_wait(&st->thread_wait, &wait, TASK_INTERRUPTIBLE);
+				if (kthread_should_stop())
+					break;
+
+				revents = netfs_state_poll(st);
+
+				if (revents & mask)
+					break;
+
+				if (signal_pending(current))
+					break;
+
+				schedule();
+				continue;
+			}
+			finish_wait(&st->thread_wait, &wait);
+		}
+
+		err = 0;
+		netfs_state_lock(st);
+		if (st->socket && (st->read_socket == st->socket) && (revents & POLLIN)) {
+			err = netfs_data_recv(st, data, size);
+			if (err > 0) {
+				data += err;
+				size -= err;
+				err = 0;
+			} else if (err == 0)
+				err = -ECONNRESET;
+		}
+
+		if (revents & err_mask) {
+			printk("%s: revents: %x, socket: %p, size: %u, err: %d.\n",
+					__func__, revents, st->socket, size, err);
+			err = -ECONNRESET;
+		}
+		netfs_state_unlock(st);
+
+		if (err < 0) {
+			if (netfs_state_trylock_send(st)) {
+				netfs_state_exit(st);
+				err = netfs_state_init(st);
+				if (!err)
+					err = -EAGAIN;
+				netfs_state_unlock_send(st);
+			} else {
+				st->need_reset = 1;
+			}
+		}
+
+		if (kthread_should_stop())
+			err = -ENODEV;
+
+		if (err)
+			printk("%s: socket: %p, read_socket: %p, revents: %x, rev_error: %d, "
+					"should_stop: %d, size: %u, err: %d.\n",
+				__func__, st->socket, st->read_socket,
+				revents, revents & err_mask, kthread_should_stop(), size, err);
+	}
+
+	return err;
+}
+
+int pohmelfs_data_recv_and_check(struct netfs_state *st, void *data, unsigned int size)
+{
+	struct netfs_cmd *cmd = &st->cmd;
+	int err;
+
+	err = pohmelfs_data_recv(st, data, size);
+	if (err)
+		return err;
+
+	return pohmelfs_crypto_process_input_data(&st->eng, cmd->iv, data, NULL, size);
+}
+
+/*
+ * Polling machinery.
+ */
+
+struct netfs_poll_helper
+{
+	poll_table 		pt;
+	struct netfs_state	*st;
+};
+
+static int netfs_queue_wake(wait_queue_t *wait, unsigned mode, int sync, void *key)
+{
+	struct netfs_state *st = container_of(wait, struct netfs_state, wait);
+
+	wake_up(&st->thread_wait);
+	return 1;
+}
+
+static void netfs_queue_func(struct file *file, wait_queue_head_t *whead,
+				 poll_table *pt)
+{
+	struct netfs_state *st = container_of(pt, struct netfs_poll_helper, pt)->st;
+
+	st->whead = whead;
+	init_waitqueue_func_entry(&st->wait, netfs_queue_wake);
+	add_wait_queue(whead, &st->wait);
+}
+
+static void netfs_poll_exit(struct netfs_state *st)
+{
+	if (st->whead) {
+		remove_wait_queue(st->whead, &st->wait);
+		st->whead = NULL;
+	}
+}
+
+static int netfs_poll_init(struct netfs_state *st)
+{
+	struct netfs_poll_helper ph;
+
+	ph.st = st;
+	init_poll_funcptr(&ph.pt, &netfs_queue_func);
+
+	st->socket->ops->poll(NULL, st->socket, &ph.pt);
+	return 0;
+}
+
+/*
+ * Get response for readpage command. We search inode and page in its mapping
+ * and copy data into. If it was async request, then we queue page into shared
+ * data and wakeup listener, who will copy it to userspace.
+ *
+ * There is a work in progress of allowing to call copy_to_user() directly from
+ * async receiving kernel thread.
+ */
+static int pohmelfs_read_page_response(struct netfs_state *st)
+{
+	struct pohmelfs_sb *psb = st->psb;
+	struct netfs_cmd *cmd = &st->cmd;
+	struct inode *inode;
+	struct page *page;
+	int err = 0;
+
+	if (cmd->size > PAGE_CACHE_SIZE) {
+		err = -EINVAL;
+		goto err_out_exit;
+	}
+
+	inode = ilookup(st->psb->sb, cmd->id);
+	if (!inode) {
+		printk("%s: failed to find inode: id: %llu.\n", __func__, cmd->id);
+		err = -ENOENT;
+		goto err_out_exit;
+	}
+
+	page = find_get_page(inode->i_mapping, cmd->start >> PAGE_CACHE_SHIFT);
+	if (!page || !PageLocked(page)) {
+		printk("%s: failed to find/lock page: page: %p, id: %llu, start: %llu, index: %llu.\n",
+				__func__, page, cmd->id, cmd->start, cmd->start >> PAGE_CACHE_SHIFT);
+
+		while (cmd->size) {
+			unsigned int sz = min(cmd->size, st->size);
+
+			err = pohmelfs_data_recv(st, st->data, sz);
+			if (err)
+				break;
+
+			cmd->size -= sz;
+		}
+
+		err = -ENODEV;
+		if (page)
+			goto err_out_page_put;
+		goto err_out_put;
+	}
+
+	if (cmd->size) {
+		void *addr;
+
+		addr = kmap(page);
+		err = pohmelfs_data_recv(st, addr, cmd->size);
+		kunmap(page);
+
+		if (err)
+			goto err_out_page_unlock;
+	}
+
+	dprintk("%s: page: %p, start: %llu, size: %u, locked: %d.\n",
+		__func__, page, cmd->start, cmd->size, PageLocked(page));
+
+	SetPageChecked(page);
+	if ((psb->hash_string || psb->cipher_string) && psb->perform_crypto && cmd->size) {
+		err = pohmelfs_crypto_process_input_page(&st->eng, page, cmd->size, cmd->iv);
+		if (err < 0)
+			goto err_out_page_unlock;
+	} else {
+		SetPageUptodate(page);
+		unlock_page(page);
+		page_cache_release(page);
+	}
+
+	pohmelfs_put_inode(POHMELFS_I(inode));
+	wake_up(&st->psb->wait);
+
+	return 0;
+
+err_out_page_unlock:
+	SetPageError(page);
+	unlock_page(page);
+err_out_page_put:
+	page_cache_release(page);
+err_out_put:
+	pohmelfs_put_inode(POHMELFS_I(inode));
+err_out_exit:
+	wake_up(&st->psb->wait);
+	return err;
+}
+
+static int pohmelfs_check_name(struct pohmelfs_inode *parent, struct qstr *str,
+		struct netfs_inode_info *info)
+{
+	struct inode *inode;
+	struct pohmelfs_name *n;
+	int err = 0;
+	u64 ino = 0;
+
+	mutex_lock(&parent->offset_lock);
+	n = pohmelfs_search_hash(parent, str->hash);
+	if (n)
+		ino = n->ino;
+	mutex_unlock(&parent->offset_lock);
+
+	if (!ino)
+		goto out;
+
+	inode = ilookup(parent->vfs_inode.i_sb, ino);
+	if (!inode)
+		goto out;
+
+	dprintk("%s: parent: %llu, inode: %llu.\n", __func__, parent->ino, ino);
+
+	pohmelfs_fill_inode(inode, info);
+	pohmelfs_put_inode(POHMELFS_I(inode));
+	err = -EEXIST;
+out:
+	return err;
+}
+
+/*
+ * Readdir response from server. If special field is set, we wakeup
+ * listener (readdir() call), which will copy data to userspace.
+ */
+static int pohmelfs_readdir_response(struct netfs_state *st)
+{
+	struct inode *inode;
+	struct netfs_cmd *cmd = &st->cmd;
+	struct netfs_inode_info *info;
+	struct pohmelfs_inode *parent = NULL, *npi;
+	int err = 0, last = cmd->ext;
+	struct qstr str;
+
+	if (cmd->size > st->size)
+		return -EINVAL;
+
+	inode = ilookup(st->psb->sb, cmd->id);
+	if (!inode) {
+		printk("%s: failed to find inode: id: %llu.\n", __func__, cmd->id);
+		return -ENOENT;
+	}
+	parent = POHMELFS_I(inode);
+
+	if (!cmd->size && cmd->start) {
+		err = -cmd->start;
+		goto out;
+	}
+
+	if (cmd->size) {
+		char *name;
+
+		err = pohmelfs_data_recv_and_check(st, st->data, cmd->size);
+		if (err)
+			goto err_out_put;
+
+		info = (struct netfs_inode_info *)(st->data);
+
+		name = (char *)(info + 1);
+		str.len = cmd->size - sizeof(struct netfs_inode_info) - 1 - cmd->cpad;
+		name[str.len] = 0;
+		str.name = name;
+		str.hash = jhash(str.name, str.len, 0);
+
+		netfs_convert_inode_info(info);
+
+		if (parent) {
+			err = pohmelfs_check_name(parent, &str, info);
+			if (err) {
+				if (err == -EEXIST)
+					err = 0;
+				goto out;
+			}
+		}
+
+		info->ino = cmd->start;
+		if (!info->ino)
+			info->ino = pohmelfs_new_ino(st->psb);
+
+		dprintk("%s: parent: %llu, ino: %llu, name: '%s', hash: %x, len: %u, mode: %o.\n",
+				__func__, parent->ino, info->ino, str.name, str.hash, str.len,
+				info->mode);
+
+		npi = pohmelfs_new_inode(st->psb, parent, &str, info, 0);
+		if (IS_ERR(npi)) {
+			err = PTR_ERR(npi);
+
+			if (err != -EEXIST)
+				goto err_out_put;
+		} else {
+			set_bit(NETFS_INODE_REMOTE_SYNCED, &npi->state);
+			clear_bit(NETFS_INODE_OWNED, &npi->state);
+		}
+	}
+out:
+	if (last) {
+		set_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &parent->state);
+		set_bit(NETFS_INODE_REMOTE_SYNCED, &parent->state);
+		wake_up(&st->psb->wait);
+	}
+	pohmelfs_put_inode(parent);
+
+	return err;
+
+err_out_put:
+	clear_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &parent->state);
+	printk("%s: parent: %llu, ino: %llu, cmd_id: %llu.\n", __func__, parent->ino, cmd->start, cmd->id);
+	pohmelfs_put_inode(parent);
+	wake_up(&st->psb->wait);
+	return err;
+}
+
+/*
+ * Lookup command response.
+ * It searches for inode to be looked at (if it exists) and substitutes
+ * its inode information (size, permission, mode and so on), if inode does
+ * not exist, new one will be created and inserted into caches.
+ */
+static int pohmelfs_lookup_response(struct netfs_state *st)
+{
+	struct inode *inode = NULL;
+	struct netfs_cmd *cmd = &st->cmd;
+	struct netfs_inode_info *info;
+	struct pohmelfs_inode *parent = NULL, *npi;
+	int err = -EINVAL;
+	char *name;
+
+	inode = ilookup(st->psb->sb, cmd->id);
+	if (!inode) {
+		printk("%s: lookup response: id: %llu, start: %llu, size: %u.\n",
+				__func__, cmd->id, cmd->start, cmd->size);
+		err = -ENOENT;
+		goto err_out_exit;
+	}
+	parent = POHMELFS_I(inode);
+
+	if (!cmd->size) {
+		err = -cmd->start;
+		goto err_out_put;
+	}
+
+	if (cmd->size < sizeof(struct netfs_inode_info)) {
+		printk("%s: broken lookup response: id: %llu, start: %llu, size: %u.\n",
+				__func__, cmd->id, cmd->start, cmd->size);
+		err = -EINVAL;
+		goto err_out_put;
+	}
+
+	err = pohmelfs_data_recv_and_check(st, st->data, cmd->size);
+	if (err)
+		goto err_out_put;
+
+	info = (struct netfs_inode_info *)(st->data);
+	name = (char *)(info + 1);
+
+	netfs_convert_inode_info(info);
+
+	info->ino = cmd->start;
+	if (!info->ino)
+		info->ino = pohmelfs_new_ino(st->psb);
+
+	dprintk("%s: parent: %llu, ino: %llu, name: '%s', start: %llu.\n",
+			__func__, parent->ino, info->ino, name, cmd->start);
+
+	if (cmd->start)
+		npi = pohmelfs_new_inode(st->psb, parent, NULL, info, 0);
+	else {
+		struct qstr str;
+
+		str.name = name;
+		str.len = cmd->size - sizeof(struct netfs_inode_info) - 1 - cmd->cpad;
+		str.hash = jhash(name, str.len, 0);
+
+		npi = pohmelfs_new_inode(st->psb, parent, &str, info, 0);
+	}
+	if (IS_ERR(npi)) {
+		err = PTR_ERR(npi);
+
+		if (err != -EEXIST)
+			goto err_out_put;
+	} else {
+		set_bit(NETFS_INODE_REMOTE_SYNCED, &npi->state);
+		clear_bit(NETFS_INODE_OWNED, &npi->state);
+	}
+
+	clear_bit(NETFS_COMMAND_PENDING, &parent->state);
+	pohmelfs_put_inode(parent);
+
+	wake_up(&st->psb->wait);
+
+	return 0;
+
+err_out_put:
+	pohmelfs_put_inode(parent);
+err_out_exit:
+	clear_bit(NETFS_COMMAND_PENDING, &parent->state);
+	wake_up(&st->psb->wait);
+	printk("%s: inode: %p, id: %llu, start: %llu, size: %u, err: %d.\n",
+			__func__, inode, cmd->id, cmd->start, cmd->size, err);
+	return err;
+}
+
+/*
+ * Create response, just marks local inode as 'created', so that writeback
+ * for any of its children (or own) would not try to sync it again.
+ */
+static int pohmelfs_create_response(struct netfs_state *st)
+{
+	struct inode *inode;
+	struct netfs_cmd *cmd = &st->cmd;
+	struct pohmelfs_inode *pi;
+
+	inode = ilookup(st->psb->sb, cmd->id);
+	if (!inode) {
+		printk("%s: failed to find inode: id: %llu, start: %llu.\n",
+				__func__, cmd->id, cmd->start);
+		goto err_out_exit;
+	}
+
+	pi = POHMELFS_I(inode);
+
+	/*
+	 * To lock or not to lock?
+	 * We actually do not care if it races...
+	 */
+	if (cmd->start)
+		make_bad_inode(inode);
+	set_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);
+
+	pohmelfs_put_inode(pi);
+
+	wake_up(&st->psb->wait);
+	return 0;
+
+err_out_exit:
+	wake_up(&st->psb->wait);
+	return -ENOENT;
+}
+
+/*
+ * Object remove response. Just says that remove request has been received.
+ * Used in cache coherency protocol.
+ */
+static int pohmelfs_remove_response(struct netfs_state *st)
+{
+	struct netfs_cmd *cmd = &st->cmd;
+	int err;
+
+	err = pohmelfs_data_recv_and_check(st, st->data, cmd->size);
+	if (err)
+		return err;
+
+	dprintk("%s: parent: %llu, path: '%s'.\n", __func__, cmd->id, (char *)st->data);
+
+	return 0;
+}
+
+/*
+ * Transaction reply processing.
+ *
+ * Find transaction based on its generation number, bump its reference counter,
+ * so that none could free it under us, drop from the trees and lists and
+ * drop reference counter. When it hits zero (when all destinations replied
+ * and all timeout handled by async scanning code), completion will be called
+ * and transaction will be freed.
+ */
+static int pohmelfs_transaction_response(struct netfs_state *st)
+{
+	struct netfs_trans_dst *dst;
+	struct netfs_trans *t = NULL;
+	struct netfs_cmd *cmd = &st->cmd;
+	short err = (signed)cmd->ext;
+
+	mutex_lock(&st->trans_lock);
+	dst = netfs_trans_search(st, cmd->start);
+	if (dst) {
+		netfs_trans_remove_nolock(dst, st);
+		t = dst->trans;
+
+		pohmelfs_ftrans_update(cmd->start);
+	}
+	mutex_unlock(&st->trans_lock);
+
+	if (!t) {
+		int check = pohmelfs_ftrans_check(cmd->start);
+		printk("%s: failed to find transaction: start: %llu: id: %llu, size: %u, ext: %u, double: %d.\n",
+				__func__, cmd->start, cmd->id, cmd->size, cmd->ext, check);
+		err = -EINVAL;
+		goto out;
+	}
+
+	t->result = err;
+	netfs_trans_drop_dst_nostate(dst);
+
+out:
+	wake_up(&st->psb->wait);
+	return err;
+}
+
+/*
+ * Inode metadata cache coherency message.
+ */
+static int pohmelfs_page_cache_response(struct netfs_state *st)
+{
+	struct netfs_cmd *cmd = &st->cmd;
+	struct inode *inode;
+
+	dprintk("%s: st: %p, id: %llu, start: %llu, size: %u.\n", __func__, st, cmd->id, cmd->start, cmd->size);
+
+	inode = ilookup(st->psb->sb, cmd->id);
+	if (!inode) {
+		printk("%s: failed to find inode: id: %llu.\n", __func__, cmd->id);
+		return -ENOENT;
+	}
+
+	set_bit(NETFS_INODE_NEED_FLUSH, &POHMELFS_I(inode)->state);
+	pohmelfs_put_inode(POHMELFS_I(inode));
+
+	return 0;
+}
+
+/*
+ * Root capabilities response: export statistics
+ * like used and available size, number of files and dirs,
+ * permissions.
+ */
+static int pohmelfs_root_cap_response(struct netfs_state *st)
+{
+	struct netfs_cmd *cmd = &st->cmd;
+	struct netfs_root_capabilities *cap;
+	struct pohmelfs_sb *psb = st->psb;
+
+	if (cmd->size != sizeof(struct netfs_root_capabilities)) {
+		psb->flags = EPROTO;
+		wake_up(&psb->wait);
+		return -EPROTO;
+	}
+
+	cap = st->data;
+
+	netfs_convert_root_capabilities(cap);
+
+	if (psb->total_size < cap->used + cap->avail)
+		psb->total_size = cap->used + cap->avail;
+	if (cap->avail)
+		psb->avail_size = cap->avail;
+	psb->state_flags = cap->flags;
+
+	if (psb->state_flags & POHMELFS_FLAGS_RO) {
+		psb->sb->s_flags |= MS_RDONLY;
+		printk(KERN_INFO "Mounting POHMELFS (%d) read-only.\n", psb->idx);
+	}
+
+	if (psb->state_flags & POHMELFS_FLAGS_XATTR)
+		printk(KERN_INFO "Mounting POHMELFS (%d) "
+			"with extended attributes support.\n", psb->idx);
+
+	if (atomic_read(&psb->total_inodes) <= 1)
+		atomic_long_set(&psb->total_inodes, cap->nr_files);
+
+	dprintk("%s: total: %llu, avail: %llu, flags: %llx, inodes: %llu.\n",
+		__func__, psb->total_size, psb->avail_size, psb->state_flags, cap->nr_files);
+
+	psb->flags = 0;
+	wake_up(&psb->wait);
+	return 0;
+}
+
+/*
+ * Crypto capabilities of the server, where it says that
+ * it supports or does not requested hash/cipher algorithms.
+ */
+static int pohmelfs_crypto_cap_response(struct netfs_state *st)
+{
+	struct netfs_cmd *cmd = &st->cmd;
+	struct netfs_crypto_capabilities *cap;
+	struct pohmelfs_sb *psb = st->psb;
+	int err = 0;
+
+	if (cmd->size != sizeof(struct netfs_crypto_capabilities)) {
+		psb->flags = EPROTO;
+		wake_up(&psb->wait);
+		return -EPROTO;
+	}
+
+	cap = st->data;
+
+	dprintk("%s: cipher '%s': %s, hash: '%s': %s.\n",
+			__func__,
+			psb->cipher_string, (cap->cipher_strlen)?"SUPPORTED":"NOT SUPPORTED",
+			psb->hash_string, (cap->hash_strlen)?"SUPPORTED":"NOT SUPPORTED");
+
+	if (!cap->hash_strlen) {
+		if (psb->hash_strlen && psb->crypto_fail_unsupported)
+			err = -ENOTSUPP;
+		psb->hash_strlen = 0;
+		kfree(psb->hash_string);
+		psb->hash_string = NULL;
+	}
+
+	if (!cap->cipher_strlen) {
+		if (psb->cipher_strlen && psb->crypto_fail_unsupported)
+			err = -ENOTSUPP;
+		psb->cipher_strlen = 0;
+		kfree(psb->cipher_string);
+		psb->cipher_string = NULL;
+	}
+
+	return err;
+}
+
+/*
+ * Capabilities handshake response.
+ */
+static int pohmelfs_capabilities_response(struct netfs_state *st)
+{
+	struct netfs_cmd *cmd = &st->cmd;
+	int err = 0;
+
+	err = pohmelfs_data_recv(st, st->data, cmd->size);
+	if (err)
+		return err;
+
+	switch (cmd->id) {
+		case POHMELFS_CRYPTO_CAPABILITIES:
+			return pohmelfs_crypto_cap_response(st);
+		case POHMELFS_ROOT_CAPABILITIES:
+			return pohmelfs_root_cap_response(st);
+		default:
+			break;
+	}
+	return -EINVAL;
+}
+
+/*
+ * Receiving extended attribute.
+ * Does not work properly if received size is more than requested one,
+ * it should not happen with current request/reply model though.
+ */
+static int pohmelfs_getxattr_response(struct netfs_state *st)
+{
+	struct pohmelfs_sb *psb = st->psb;
+	struct netfs_cmd *cmd = &st->cmd;
+	struct pohmelfs_mcache *m;
+	short error = (signed short)cmd->ext, err;
+	unsigned int sz, total_size;
+
+	m = pohmelfs_mcache_search(psb, cmd->id);
+
+	dprintk("%s: id: %llu, gen: %llu, err: %d.\n",
+		__func__, cmd->id, (m)?m->gen:0, error);
+
+	if (!m) {
+		printk("%s: failed to find getxattr cache entry: id: %llu.\n", __func__, cmd->id);
+		return -ENOENT;
+	}
+
+	if (cmd->size) {
+		sz = min_t(unsigned int, cmd->size, m->size);
+		err = pohmelfs_data_recv_and_check(st, m->data, sz);
+		if (err) {
+			error = err;
+			goto out;
+		}
+
+		m->size = sz;
+		total_size = cmd->size - sz;
+
+		while (total_size) {
+			sz = min(total_size, st->size);
+
+			err = pohmelfs_data_recv_and_check(st, st->data, sz);
+			if (err) {
+				error = err;
+				break;
+			}
+
+			total_size -= sz;
+		}
+	}
+
+out:
+	m->err = error;
+	complete(&m->complete);
+	pohmelfs_mcache_put(psb, m);
+
+	return error;
+}
+
+int pohmelfs_data_lock_response(struct netfs_state *st)
+{
+	struct pohmelfs_sb *psb = st->psb;
+	struct netfs_cmd *cmd = &st->cmd;
+	struct pohmelfs_mcache *m;
+	short err = (signed short)cmd->ext;
+	u64 id = cmd->id;
+
+	m = pohmelfs_mcache_search(psb, id);
+
+	dprintk("%s: id: %llu, gen: %llu, err: %d.\n",
+		__func__, cmd->id, (m)?m->gen:0, err);
+
+	if (!m) {
+		pohmelfs_data_recv(st, st->data, cmd->size);
+		printk("%s: failed to find data lock response: id: %llu.\n", __func__, cmd->id);
+		return -ENOENT;
+	}
+
+	if (cmd->size)
+		err = pohmelfs_data_recv_and_check(st, &m->info, cmd->size);
+
+	m->err = err;
+	complete(&m->complete);
+	pohmelfs_mcache_put(psb, m);
+
+	return err;
+}
+
+static void __inline__ netfs_state_reset(struct netfs_state *st)
+{
+	netfs_state_lock_send(st);
+	netfs_state_exit(st);
+	netfs_state_init(st);
+	netfs_state_unlock_send(st);
+}
+
+/*
+ * Main receiving function, called from dedicated kernel thread.
+ */
+static int pohmelfs_recv(void *data)
+{
+	int err = -EINTR;
+	struct netfs_state *st = data;
+	struct netfs_cmd *cmd = &st->cmd;
+
+	while (!kthread_should_stop()) {
+		/*
+		 * If socket will be reset after this statement, then
+		 * pohmelfs_data_recv() will just fail and loop will
+		 * start again, so it can be done without any locks.
+		 *
+		 * st->read_socket is needed to prevents state machine
+		 * breaking between this data reading and subsequent one
+		 * in protocol specific functions during connection reset.
+		 * In case of reset we have to read next command and do
+		 * not expect data for old command to magically appear in
+		 * new connection.
+		 */
+		st->read_socket = st->socket;
+		err = pohmelfs_data_recv(st, cmd, sizeof(struct netfs_cmd));
+		if (err) {
+			msleep(1000);
+			continue;
+		}
+
+		netfs_convert_cmd(cmd);
+
+		dprintk("%s: cmd: %u, id: %llu, start: %llu, size: %u, "
+				"ext: %u, csize: %u, cpad: %u.\n",
+				__func__, cmd->cmd, cmd->id, cmd->start,
+				cmd->size, cmd->ext, cmd->csize, cmd->cpad);
+
+		if (cmd->csize) {
+			struct pohmelfs_crypto_engine *e = &st->eng;
+
+			if (unlikely(cmd->csize > e->size/2)) {
+				netfs_state_reset(st);
+				continue;
+			}
+
+			if (e->hash && unlikely(cmd->csize != st->psb->crypto_attached_size)) {
+				dprintk("%s: cmd: cmd: %u, id: %llu, start: %llu, size: %u, "
+						"csize: %u != digest size %u.\n",
+						__func__, cmd->cmd, cmd->id, cmd->start, cmd->size,
+						cmd->csize, st->psb->crypto_attached_size);
+				netfs_state_reset(st);
+				continue;
+			}
+
+			err = pohmelfs_data_recv(st, e->data, cmd->csize);
+			if (err) {
+				netfs_state_reset(st);
+				continue;
+			}
+
+#ifdef CONFIG_POHMELFS_DEBUG
+			{
+				unsigned int i;
+				unsigned char *hash = e->data;
+
+				dprintk("%s: received hash: ", __func__);
+				for (i=0; i<cmd->csize; ++i) {
+					printk("%02x ", hash[i]);
+				}
+				printk("\n");
+			}
+#endif
+			cmd->size -= cmd->csize;
+		}
+
+		/*
+		 * This should catch protocol breakage and random garbage instead of commands.
+		 */
+		if (unlikely((cmd->size > st->size) && (cmd->cmd != NETFS_XATTR_GET))) {
+			netfs_state_reset(st);
+			continue;
+		}
+
+		switch (cmd->cmd) {
+			case NETFS_READ_PAGE:
+				err = pohmelfs_read_page_response(st);
+				break;
+			case NETFS_READDIR:
+				err = pohmelfs_readdir_response(st);
+				break;
+			case NETFS_LOOKUP:
+				err = pohmelfs_lookup_response(st);
+				break;
+			case NETFS_CREATE:
+				err = pohmelfs_create_response(st);
+				break;
+			case NETFS_REMOVE:
+				err = pohmelfs_remove_response(st);
+				break;
+			case NETFS_TRANS:
+				err = pohmelfs_transaction_response(st);
+				break;
+			case NETFS_PAGE_CACHE:
+				err = pohmelfs_page_cache_response(st);
+				break;
+			case NETFS_CAPABILITIES:
+				err = pohmelfs_capabilities_response(st);
+				break;
+			case NETFS_LOCK:
+				err = pohmelfs_data_lock_response(st);
+				break;
+			case NETFS_XATTR_GET:
+				err = pohmelfs_getxattr_response(st);
+				break;
+			default:
+				printk("%s: wrong cmd: %u, id: %llu, start: %llu, size: %u, ext: %u.\n",
+					__func__, cmd->cmd, cmd->id, cmd->start, cmd->size, cmd->ext);
+				netfs_state_reset(st);
+				break;
+		}
+	}
+
+	while (!kthread_should_stop())
+		schedule_timeout_uninterruptible(msecs_to_jiffies(10));
+
+	return err;
+}
+
+int netfs_state_init(struct netfs_state *st)
+{
+	int err;
+	struct pohmelfs_ctl *ctl = &st->ctl;
+
+	err = sock_create(ctl->addr.sa_family, ctl->type, ctl->proto, &st->socket);
+	if (err) {
+		printk("%s: failed to create a socket: family: %d, type: %d, proto: %d, err: %d.\n",
+				__func__, ctl->addr.sa_family, ctl->type, ctl->proto, err);
+		goto err_out_exit;
+	}
+
+	st->socket->sk->sk_allocation = GFP_NOIO;
+	st->socket->sk->sk_sndtimeo = st->socket->sk->sk_rcvtimeo = msecs_to_jiffies(60000);
+
+	err = kernel_connect(st->socket, (struct sockaddr *)&ctl->addr, ctl->addrlen, 0);
+	if (err) {
+		printk("%s: failed to connect to server: idx: %u, err: %d.\n",
+				__func__, st->psb->idx, err);
+		goto err_out_release;
+	}
+	st->socket->sk->sk_sndtimeo = st->socket->sk->sk_rcvtimeo = msecs_to_jiffies(60000);
+
+	err = netfs_poll_init(st);
+	if (err)
+		goto err_out_release;
+
+	if (st->socket->ops->family == AF_INET) {
+		struct sockaddr_in *sin = (struct sockaddr_in *)&ctl->addr;
+		printk(KERN_INFO "%s: (re)connected to peer %u.%u.%u.%u:%d.\n", __func__,
+			NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
+	} else if (st->socket->ops->family == AF_INET6) {
+		struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&ctl->addr;
+		printk(KERN_INFO "%s: (re)connected to peer "
+			"%pi6:%d",
+			__func__, &sin->sin6_addr, ntohs(sin->sin6_port));
+	}
+
+	return 0;
+
+err_out_release:
+	sock_release(st->socket);
+err_out_exit:
+	st->socket = NULL;
+	return err;
+}
+
+void netfs_state_exit(struct netfs_state *st)
+{
+	if (st->socket) {
+		netfs_poll_exit(st);
+		st->socket->ops->shutdown(st->socket, 2);
+
+		if (st->socket->ops->family == AF_INET) {
+			struct sockaddr_in *sin = (struct sockaddr_in *)&st->ctl.addr;
+			printk("%s: disconnected from peer %u.%u.%u.%u:%d.\n", __func__,
+				NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
+		} else if (st->socket->ops->family == AF_INET6) {
+			struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&st->ctl.addr;
+			printk("%s: disconnected from peer "
+				"%pi6:%d",
+				__func__, &sin->sin6_addr, ntohs(sin->sin6_port));
+		}
+
+		sock_release(st->socket);
+		st->socket = NULL;
+		st->read_socket = NULL;
+		st->need_reset = 0;
+	}
+}
+
+int pohmelfs_state_init_one(struct pohmelfs_sb *psb, struct pohmelfs_config *conf)
+{
+	struct netfs_state *st = &conf->state;
+	int err = -ENOMEM;
+
+	mutex_init(&st->__state_lock);
+	mutex_init(&st->__state_send_lock);
+	init_waitqueue_head(&st->thread_wait);
+
+	st->psb = psb;
+	st->trans_root = RB_ROOT;
+	mutex_init(&st->trans_lock);
+
+	st->size = psb->trans_data_size;
+	st->data = kmalloc(st->size, GFP_KERNEL);
+	if (!st->data)
+		goto err_out_exit;
+
+	if (psb->perform_crypto) {
+		err = pohmelfs_crypto_engine_init(&st->eng, psb);
+		if (err)
+			goto err_out_free_data;
+	}
+
+	err = netfs_state_init(st);
+	if (err)
+		goto err_out_free_engine;
+
+	st->thread = kthread_run(pohmelfs_recv, st, "pohmelfs/%u", psb->idx);
+	if (IS_ERR(st->thread)) {
+		err = PTR_ERR(st->thread);
+		goto err_out_netfs_exit;
+	}
+
+	if (!psb->active_state)
+		psb->active_state = conf;
+
+	dprintk("%s: conf: %p, st: %p, socket: %p.\n",
+			__func__, conf, st, st->socket);
+	return 0;
+
+err_out_netfs_exit:
+	netfs_state_exit(st);
+err_out_free_engine:
+	pohmelfs_crypto_engine_exit(&st->eng);
+err_out_free_data:
+	kfree(st->data);
+err_out_exit:
+	return err;
+
+}
+
+void pohmelfs_state_flush_transactions(struct netfs_state *st)
+{
+	struct rb_node *rb_node;
+	struct netfs_trans_dst *dst;
+
+	mutex_lock(&st->trans_lock);
+	for (rb_node = rb_first(&st->trans_root); rb_node; ) {
+		dst = rb_entry(rb_node, struct netfs_trans_dst, state_entry);
+		rb_node = rb_next(rb_node);
+
+		dst->trans->result = -EINVAL;
+		netfs_trans_remove_nolock(dst, st);
+		netfs_trans_drop_dst_nostate(dst);
+	}
+	mutex_unlock(&st->trans_lock);
+}
+
+static void pohmelfs_state_exit_one(struct pohmelfs_config *c)
+{
+	struct netfs_state *st = &c->state;
+
+	dprintk("%s: exiting, st: %p.\n", __func__, st);
+	if (st->thread) {
+		kthread_stop(st->thread);
+		st->thread = NULL;
+	}
+
+	netfs_state_lock_send(st);
+	netfs_state_exit(st);
+	netfs_state_unlock_send(st);
+
+	pohmelfs_state_flush_transactions(st);
+
+	pohmelfs_crypto_engine_exit(&st->eng);
+	kfree(st->data);
+
+	kfree(c);
+}
+
+/*
+ * Initialize network stack. It searches for given ID in global
+ * configuration table, this contains information of the remote server
+ * (address (any supported by socket interface) and port, protocol and so on).
+ */
+int pohmelfs_state_init(struct pohmelfs_sb *psb)
+{
+	int err = -ENOMEM;
+
+	err = pohmelfs_copy_config(psb);
+	if (err) {
+		pohmelfs_state_exit(psb);
+		return err;
+	}
+
+	return 0;
+}
+
+void pohmelfs_state_exit(struct pohmelfs_sb *psb)
+{
+	struct pohmelfs_config *c, *tmp;
+
+	list_for_each_entry_safe(c, tmp, &psb->state_list, config_entry) {
+		list_del(&c->config_entry);
+		pohmelfs_state_exit_one(c);
+	}
+}
+
+void pohmelfs_switch_active(struct pohmelfs_sb *psb)
+{
+	struct pohmelfs_config *c = psb->active_state;
+
+	if (!list_empty(&psb->state_list)) {
+		if (c->config_entry.next != &psb->state_list) {
+			psb->active_state = list_entry(c->config_entry.next,
+				struct pohmelfs_config, config_entry);
+		} else {
+			psb->active_state = list_entry(psb->state_list.next,
+				struct pohmelfs_config, config_entry);
+		}
+
+		dprintk("%s: empty: %d, active %p -> %p.\n",
+			__func__, list_empty(&psb->state_list), c,
+			psb->active_state);
+	} else
+		psb->active_state = NULL;
+}
+
+void pohmelfs_check_states(struct pohmelfs_sb *psb)
+{
+	struct pohmelfs_config *c, *tmp;
+	LIST_HEAD(delete_list);
+
+	mutex_lock(&psb->state_lock);
+	list_for_each_entry_safe(c, tmp, &psb->state_list, config_entry) {
+		if (pohmelfs_config_check(c, psb->idx)) {
+
+			if (psb->active_state == c)
+				pohmelfs_switch_active(psb);
+			list_move(&c->config_entry, &delete_list);
+		}
+	}
+	pohmelfs_copy_config(psb);
+	mutex_unlock(&psb->state_lock);
+
+	list_for_each_entry_safe(c, tmp, &delete_list, config_entry) {
+		list_del(&c->config_entry);
+		pohmelfs_state_exit_one(c);
+	}
+}
diff --git a/drivers/staging/pohmelfs/netfs.h b/drivers/staging/pohmelfs/netfs.h
new file mode 100644
index 0000000..2ff21ae
--- /dev/null
+++ b/drivers/staging/pohmelfs/netfs.h
@@ -0,0 +1,932 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * 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.
+ *
+ * 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 __NETFS_H
+#define __NETFS_H
+
+#include <linux/types.h>
+#include <linux/connector.h>
+
+#define POHMELFS_CN_IDX			5
+#define POHMELFS_CN_VAL			0
+
+#define POHMELFS_CTLINFO_ACK		1
+#define POHMELFS_NOINFO_ACK		2
+
+
+/*
+ * Network command structure.
+ * Will be extended.
+ */
+struct netfs_cmd
+{
+	__u16			cmd;	/* Command number */
+	__u16			csize;	/* Attached crypto information size */
+	__u16			cpad;	/* Attached padding size */
+	__u16			ext;	/* External flags */
+	__u32			size;	/* Size of the attached data */
+	__u32			trans;	/* Transaction id */
+	__u64			id;	/* Object ID to operate on. Used for feedback.*/
+	__u64			start;	/* Start of the object. */
+	__u64			iv;	/* IV sequence */
+	__u8			data[0];
+};
+
+static inline void netfs_convert_cmd(struct netfs_cmd *cmd)
+{
+	cmd->id = __be64_to_cpu(cmd->id);
+	cmd->start = __be64_to_cpu(cmd->start);
+	cmd->iv = __be64_to_cpu(cmd->iv);
+	cmd->cmd = __be16_to_cpu(cmd->cmd);
+	cmd->ext = __be16_to_cpu(cmd->ext);
+	cmd->csize = __be16_to_cpu(cmd->csize);
+	cmd->cpad = __be16_to_cpu(cmd->cpad);
+	cmd->size = __be32_to_cpu(cmd->size);
+}
+
+#define NETFS_TRANS_SINGLE_DST		(1<<0)
+
+enum {
+	NETFS_READDIR	= 1,	/* Read directory for given inode number */
+	NETFS_READ_PAGE,	/* Read data page from the server */
+	NETFS_WRITE_PAGE,	/* Write data page to the server */
+	NETFS_CREATE,		/* Create directory entry */
+	NETFS_REMOVE,		/* Remove directory entry */
+
+	NETFS_LOOKUP,		/* Lookup single object */
+	NETFS_LINK,		/* Create a link */
+	NETFS_TRANS,		/* Transaction */
+	NETFS_OPEN,		/* Open intent */
+	NETFS_INODE_INFO,	/* Metadata cache coherency synchronization message */
+
+	NETFS_PAGE_CACHE,	/* Page cache invalidation message */
+	NETFS_READ_PAGES,	/* Read multiple contiguous pages in one go */
+	NETFS_RENAME,		/* Rename object */
+	NETFS_CAPABILITIES,	/* Capabilities of the client, for example supported crypto */
+	NETFS_LOCK,		/* Distributed lock message */
+
+	NETFS_XATTR_SET,	/* Set extended attribute */
+	NETFS_XATTR_GET,	/* Get extended attribute */
+	NETFS_CMD_MAX
+};
+
+enum {
+	POHMELFS_FLAGS_ADD = 0, /* Network state control message for ADD */
+	POHMELFS_FLAGS_DEL,     /* Network state control message for DEL */
+	POHMELFS_FLAGS_SHOW,    /* Network state control message for SHOW */
+	POHMELFS_FLAGS_CRYPTO,	/* Crypto data control message */
+};
+
+/*
+ * Always wanted to copy it from socket headers into public one,
+ * since they are __KERNEL__ protected there.
+ */
+#define _K_SS_MAXSIZE	128
+
+struct saddr
+{
+	unsigned short		sa_family;
+	char			addr[_K_SS_MAXSIZE];
+};
+
+enum {
+	POHMELFS_CRYPTO_HASH = 0,
+	POHMELFS_CRYPTO_CIPHER,
+};
+
+struct pohmelfs_crypto
+{
+	unsigned int		idx;		/* Config index */
+	unsigned short		strlen;		/* Size of the attached crypto string including 0-byte
+						 * "cbc(aes)" for example */
+	unsigned short		type;		/* HMAC, cipher, both */
+	unsigned int		keysize;	/* Key size */
+	unsigned char		data[0];	/* Algorithm string, key and IV */
+};
+
+/*
+ * Configuration command used to create table of different remote servers.
+ */
+struct pohmelfs_ctl
+{
+	unsigned int		idx;		/* Config index */
+	unsigned int		type;		/* Socket type */
+	unsigned int		proto;		/* Socket protocol */
+	unsigned int		addrlen;	/* Size of the address */
+	unsigned short		unused;		/* Align structure by 4 bytes */
+	struct saddr		addr;		/* Remote server address */
+};
+
+/*
+ * Ack for userspace about requested command.
+ */
+struct pohmelfs_cn_ack
+{
+	struct cn_msg		msg;
+	int			error;
+	int			msg_num;
+	int			unused[3];
+	struct pohmelfs_ctl	ctl;
+};
+
+/*
+ * Inode info structure used to sync with server.
+ * Check what stat() returns.
+ */
+struct netfs_inode_info
+{
+	unsigned int		mode;
+	unsigned int		nlink;
+	unsigned int		uid;
+	unsigned int		gid;
+	unsigned int		blocksize;
+	unsigned int		padding;
+	__u64			ino;
+	__u64			blocks;
+	__u64			rdev;
+	__u64			size;
+	__u64			version;
+};
+
+static inline void netfs_convert_inode_info(struct netfs_inode_info *info)
+{
+	info->mode = __cpu_to_be32(info->mode);
+	info->nlink = __cpu_to_be32(info->nlink);
+	info->uid = __cpu_to_be32(info->uid);
+	info->gid = __cpu_to_be32(info->gid);
+	info->blocksize = __cpu_to_be32(info->blocksize);
+	info->blocks = __cpu_to_be64(info->blocks);
+	info->rdev = __cpu_to_be64(info->rdev);
+	info->size = __cpu_to_be64(info->size);
+	info->version = __cpu_to_be64(info->version);
+	info->ino = __cpu_to_be64(info->ino);
+}
+
+/*
+ * Cache state machine.
+ */
+enum {
+	NETFS_COMMAND_PENDING = 0,	/* Command is being executed */
+	NETFS_INODE_REMOTE_SYNCED,	/* Inode was synced to server */
+	NETFS_INODE_REMOTE_DIR_SYNCED,	/* Inode (directory) was synced from the server */
+	NETFS_INODE_OWNED,		/* Inode is owned by given host */
+	NETFS_INODE_NEED_FLUSH,		/* Inode has to be flushed to the server */
+};
+
+/*
+ * POHMELFS capabilities: information about supported
+ * crypto operations (hash/cipher, modes, key sizes and so on),
+ * root informaion (used/available size, number of objects, permissions)
+ */
+enum pohmelfs_capabilities {
+	POHMELFS_CRYPTO_CAPABILITIES = 0,
+	POHMELFS_ROOT_CAPABILITIES,
+};
+
+/* Read-only mount */
+#define POHMELFS_FLAGS_RO		(1<<0)
+/* Extended attributes support on/off */
+#define POHMELFS_FLAGS_XATTR		(1<<1)
+
+struct netfs_root_capabilities
+{
+	__u64			nr_files;
+	__u64			used, avail;
+	__u64			flags;
+};
+
+static inline void netfs_convert_root_capabilities(struct netfs_root_capabilities *cap)
+{
+	cap->nr_files = __cpu_to_be64(cap->nr_files);
+	cap->used = __cpu_to_be64(cap->used);
+	cap->avail = __cpu_to_be64(cap->avail);
+	cap->flags = __cpu_to_be64(cap->flags);
+}
+
+struct netfs_crypto_capabilities
+{
+	unsigned short		hash_strlen;	/* Hash string length, like "hmac(sha1) including 0 byte "*/
+	unsigned short		cipher_strlen;	/* Cipher string length with the same format */
+	unsigned int		cipher_keysize;	/* Cipher key size */
+};
+
+static inline void netfs_convert_crypto_capabilities(struct netfs_crypto_capabilities *cap)
+{
+	cap->hash_strlen = __cpu_to_be16(cap->hash_strlen);
+	cap->cipher_strlen = __cpu_to_be16(cap->cipher_strlen);
+	cap->cipher_keysize = __cpu_to_be32(cap->cipher_keysize);
+}
+
+enum pohmelfs_lock_type {
+	POHMELFS_LOCK_GRAB	= (1<<15),
+
+	POHMELFS_READ_LOCK	= 0,
+	POHMELFS_WRITE_LOCK,
+};
+
+struct netfs_lock
+{
+	__u64			start;
+	__u64			ino;
+	__u32			size;
+	__u32			type;
+};
+
+static inline void netfs_convert_lock(struct netfs_lock *lock)
+{
+	lock->start = __cpu_to_be64(lock->start);
+	lock->ino = __cpu_to_be64(lock->ino);
+	lock->size = __cpu_to_be32(lock->size);
+	lock->type = __cpu_to_be32(lock->type);
+}
+
+#ifdef __KERNEL__
+
+#include <linux/kernel.h>
+#include <linux/completion.h>
+#include <linux/rbtree.h>
+#include <linux/net.h>
+#include <linux/poll.h>
+
+/*
+ * Private POHMELFS cache of objects in directory.
+ */
+struct pohmelfs_name
+{
+	struct rb_node		hash_node;
+
+	struct list_head	sync_create_entry;
+
+	u64			ino;
+
+	u32			hash;
+	u32			mode;
+	u32			len;
+
+	char			*data;
+};
+
+/*
+ * POHMELFS inode. Main object.
+ */
+struct pohmelfs_inode
+{
+	struct list_head	inode_entry;		/* Entry in superblock list.
+							 * Objects which are not bound to dentry require to be dropped
+							 * in ->put_super()
+							 */
+	struct rb_root		hash_root;		/* The same, but indexed by name hash and len */
+	struct mutex		offset_lock;		/* Protect both above trees */
+
+	struct list_head	sync_create_list;	/* List of created but not yet synced to the server children */
+
+	unsigned int		drop_count;
+
+	int			lock_type;		/* How this inode is locked: read or write */
+
+	int			error;			/* Transaction error for given inode */
+
+	long			state;			/* State machine above */
+
+	u64			ino;			/* Inode number */
+	u64			total_len;		/* Total length of all children names, used to create offsets */
+
+	struct inode		vfs_inode;
+};
+
+struct netfs_trans;
+typedef int (* netfs_trans_complete_t)(struct page **pages, unsigned int page_num,
+		void *private, int err);
+
+struct netfs_state;
+struct pohmelfs_sb;
+
+struct netfs_trans
+{
+	/*
+	 * Transaction header and attached contiguous data live here.
+	 */
+	struct iovec			iovec;
+
+	/*
+	 * Pages attached to transaction.
+	 */
+	struct page			**pages;
+
+	/*
+	 * List and protecting lock for transaction destination
+	 * network states.
+	 */
+	spinlock_t			dst_lock;
+	struct list_head		dst_list;
+
+	/*
+	 * Number of users for given transaction.
+	 * For example each network state attached to transaction
+	 * via dst_list increases it.
+	 */
+	atomic_t			refcnt;
+
+	/*
+	 * Number of pages attached to given transaction.
+	 * Some slots in above page array can be NULL, since
+	 * for example page can be under writeback already,
+	 * so we skip it in this transaction.
+	 */
+	unsigned int			page_num;
+
+	/*
+	 * Transaction flags: single dst or broadcast and so on.
+	 */
+	unsigned int			flags;
+
+	/*
+	 * Size of the data, which can be placed into
+	 * iovec.iov_base area.
+	 */
+	unsigned int			total_size;
+
+	/*
+	 * Number of pages to be sent to remote server.
+	 * Usually equal to above page_num, but in case of partial
+	 * writeback it can accumulate only pages already completed
+	 * previous writeback.
+	 */
+	unsigned int			attached_pages;
+
+	/*
+	 * Attached number of bytes in all above pages.
+	 */
+	unsigned int			attached_size;
+
+	/*
+	 * Unique transacton generation number.
+	 * Used as identity in the network state tree of transactions.
+	 */
+	unsigned int			gen;
+
+	/*
+	 * Transaction completion status.
+	 */
+	int				result;
+
+	/*
+	 * Superblock this transaction belongs to
+	 */
+	struct pohmelfs_sb		*psb;
+
+	/*
+	 * Crypto engine, which processed this transaction.
+	 * Can be not NULL only if crypto engine holds encrypted pages.
+	 */
+	struct pohmelfs_crypto_engine	*eng;
+
+	/* Private data */
+	void				*private;
+
+	/* Completion callback, invoked just before transaction is destroyed */
+	netfs_trans_complete_t		complete;
+};
+
+static inline int netfs_trans_cur_len(struct netfs_trans *t)
+{
+	return (signed)(t->total_size - t->iovec.iov_len);
+}
+
+static inline void *netfs_trans_current(struct netfs_trans *t)
+{
+	return t->iovec.iov_base + t->iovec.iov_len;
+}
+
+struct netfs_trans *netfs_trans_alloc(struct pohmelfs_sb *psb, unsigned int size,
+		unsigned int flags, unsigned int nr);
+void netfs_trans_free(struct netfs_trans *t);
+int netfs_trans_finish(struct netfs_trans *t, struct pohmelfs_sb *psb);
+int netfs_trans_finish_send(struct netfs_trans *t, struct pohmelfs_sb *psb);
+
+static inline void netfs_trans_reset(struct netfs_trans *t)
+{
+	t->complete = NULL;
+}
+
+struct netfs_trans_dst
+{
+	struct list_head		trans_entry;
+	struct rb_node			state_entry;
+
+	unsigned long			send_time;
+
+	/*
+	 * Times this transaction was resent to its old or new,
+	 * depending on flags, destinations. When it reaches maximum
+	 * allowed number, specified in superblock->trans_retries,
+	 * transaction will be freed with ETIMEDOUT error.
+	 */
+	unsigned int			retries;
+
+	struct netfs_trans		*trans;
+	struct netfs_state		*state;
+};
+
+struct netfs_trans_dst *netfs_trans_search(struct netfs_state *st, unsigned int gen);
+void netfs_trans_drop_dst(struct netfs_trans_dst *dst);
+void netfs_trans_drop_dst_nostate(struct netfs_trans_dst *dst);
+void netfs_trans_drop_trans(struct netfs_trans *t, struct netfs_state *st);
+void netfs_trans_drop_last(struct netfs_trans *t, struct netfs_state *st);
+int netfs_trans_resend(struct netfs_trans *t, struct pohmelfs_sb *psb);
+int netfs_trans_remove_nolock(struct netfs_trans_dst *dst, struct netfs_state *st);
+
+int netfs_trans_init(void);
+void netfs_trans_exit(void);
+
+struct pohmelfs_crypto_engine
+{
+	u64				iv;		/* Crypto IV for current operation */
+	unsigned long			timeout;	/* Crypto waiting timeout */
+	unsigned int			size;		/* Size of crypto scratchpad */
+	void				*data;		/* Temporal crypto scratchpad */
+	/*
+	 * Crypto operations performed on objects.
+	 */
+	struct crypto_hash		*hash;
+	struct crypto_ablkcipher	*cipher;
+
+	struct pohmelfs_crypto_thread	*thread;	/* Crypto thread which hosts this engine */
+
+	struct page			**pages;
+	unsigned int			page_num;
+};
+
+struct pohmelfs_crypto_thread
+{
+	struct list_head		thread_entry;
+
+	struct task_struct		*thread;
+	struct pohmelfs_sb		*psb;
+
+	struct pohmelfs_crypto_engine	eng;
+
+	struct netfs_trans		*trans;
+
+	wait_queue_head_t		wait;
+	int				error;
+
+	unsigned int			size;
+	struct page			*page;
+};
+
+void pohmelfs_crypto_thread_make_ready(struct pohmelfs_crypto_thread *th);
+
+/*
+ * Network state, attached to one server.
+ */
+struct netfs_state
+{
+	struct mutex		__state_lock;		/* Can not allow to use the same socket simultaneously */
+	struct mutex		__state_send_lock;
+	struct netfs_cmd 	cmd;			/* Cached command */
+	struct netfs_inode_info	info;			/* Cached inode info */
+
+	void			*data;			/* Cached some data */
+	unsigned int		size;			/* Size of that data */
+
+	struct pohmelfs_sb	*psb;			/* Superblock */
+
+	struct task_struct	*thread;		/* Async receiving thread */
+
+	/* Waiting/polling machinery */
+	wait_queue_t 		wait;
+	wait_queue_head_t 	*whead;
+	wait_queue_head_t 	thread_wait;
+
+	struct mutex		trans_lock;
+	struct rb_root		trans_root;
+
+	struct pohmelfs_ctl	ctl;			/* Remote peer */
+
+	struct socket		*socket;		/* Socket object */
+	struct socket		*read_socket;		/* Cached pointer to socket object.
+							 * Used to determine if between lock drops socket was changed.
+							 * Never used to read data or any kind of access.
+							 */
+	/*
+	 * Crypto engines to process incoming data.
+	 */
+	struct pohmelfs_crypto_engine	eng;
+
+	int			need_reset;
+};
+
+int netfs_state_init(struct netfs_state *st);
+void netfs_state_exit(struct netfs_state *st);
+
+static inline void netfs_state_lock_send(struct netfs_state *st)
+{
+	mutex_lock(&st->__state_send_lock);
+}
+
+static inline int netfs_state_trylock_send(struct netfs_state *st)
+{
+	return mutex_trylock(&st->__state_send_lock);
+}
+
+static inline void netfs_state_unlock_send(struct netfs_state *st)
+{
+	BUG_ON(!mutex_is_locked(&st->__state_send_lock));
+
+	mutex_unlock(&st->__state_send_lock);
+}
+
+static inline void netfs_state_lock(struct netfs_state *st)
+{
+	mutex_lock(&st->__state_lock);
+}
+
+static inline void netfs_state_unlock(struct netfs_state *st)
+{
+	BUG_ON(!mutex_is_locked(&st->__state_lock));
+
+	mutex_unlock(&st->__state_lock);
+}
+
+static inline unsigned int netfs_state_poll(struct netfs_state *st)
+{
+	unsigned int revents = POLLHUP | POLLERR;
+
+	netfs_state_lock(st);
+	if (st->socket)
+		revents = st->socket->ops->poll(NULL, st->socket, NULL);
+	netfs_state_unlock(st);
+
+	return revents;
+}
+
+struct pohmelfs_config;
+
+struct pohmelfs_sb
+{
+	struct rb_root		mcache_root;
+	struct mutex		mcache_lock;
+	atomic_long_t		mcache_gen;
+	unsigned long		mcache_timeout;
+
+	unsigned int		idx;
+
+	unsigned int		trans_retries;
+
+	atomic_t		trans_gen;
+
+	unsigned int		crypto_attached_size;
+	unsigned int		crypto_align_size;
+
+	unsigned int		crypto_fail_unsupported;
+
+	unsigned int		crypto_thread_num;
+	struct list_head	crypto_active_list, crypto_ready_list;
+	struct mutex		crypto_thread_lock;
+
+	unsigned int		trans_max_pages;
+	unsigned long		trans_data_size;
+	unsigned long		trans_timeout;
+
+	unsigned long		drop_scan_timeout;
+	unsigned long		trans_scan_timeout;
+
+	unsigned long		wait_on_page_timeout;
+
+	struct list_head	flush_list;
+	struct list_head	drop_list;
+	spinlock_t		ino_lock;
+	u64			ino;
+
+	/*
+	 * Remote nodes POHMELFS connected to.
+	 */
+	struct list_head	state_list;
+	struct mutex		state_lock;
+
+	/*
+	 * Currently active state to request data from.
+	 */
+	struct pohmelfs_config	*active_state;
+
+
+	wait_queue_head_t	wait;
+
+	/*
+	 * Timed checks: stale transactions, inodes to be freed and so on.
+	 */
+	struct delayed_work 	dwork;
+	struct delayed_work 	drop_dwork;
+
+	struct super_block	*sb;
+
+	/*
+	 * Algorithm strings.
+	 */
+	char			*hash_string;
+	char			*cipher_string;
+
+	u8			*hash_key;
+	u8			*cipher_key;
+
+	/*
+	 * Algorithm string lengths.
+	 */
+	unsigned int		hash_strlen;
+	unsigned int		cipher_strlen;
+	unsigned int		hash_keysize;
+	unsigned int		cipher_keysize;
+
+	/*
+	 * Controls whether to perfrom crypto processing or not.
+	 */
+	int			perform_crypto;
+
+	/*
+	 * POHMELFS statistics.
+	 */
+	u64			total_size;
+	u64			avail_size;
+	atomic_long_t		total_inodes;
+
+	/*
+	 * Xattr support, read-only and so on.
+	 */
+	u64			state_flags;
+
+	/*
+	 * Temporary storage to detect changes in the wait queue.
+	 */
+	long			flags;
+};
+
+static inline void netfs_trans_update(struct netfs_cmd *cmd,
+		struct netfs_trans *t, unsigned int size)
+{
+	unsigned int sz = ALIGN(size, t->psb->crypto_align_size);
+
+	t->iovec.iov_len += sizeof(struct netfs_cmd) + sz;
+	cmd->cpad = __cpu_to_be16(sz - size);
+}
+
+static inline struct pohmelfs_sb *POHMELFS_SB(struct super_block *sb)
+{
+	return sb->s_fs_info;
+}
+
+static inline struct pohmelfs_inode *POHMELFS_I(struct inode *inode)
+{
+	return container_of(inode, struct pohmelfs_inode, vfs_inode);
+}
+
+static inline u64 pohmelfs_new_ino(struct pohmelfs_sb *psb)
+{
+	u64 ino;
+
+	spin_lock(&psb->ino_lock);
+	ino = psb->ino++;
+	spin_unlock(&psb->ino_lock);
+
+	return ino;
+}
+
+static inline void pohmelfs_put_inode(struct pohmelfs_inode *pi)
+{
+	struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
+
+	spin_lock(&psb->ino_lock);
+	list_move_tail(&pi->inode_entry, &psb->drop_list);
+	pi->drop_count++;
+	spin_unlock(&psb->ino_lock);
+}
+
+struct pohmelfs_config
+{
+	struct list_head	config_entry;
+
+	struct netfs_state	state;
+};
+
+struct pohmelfs_config_group
+{
+	/*
+	 * Entry in the global config group list.
+	 */
+	struct list_head	group_entry;
+
+	/*
+	 * Index of the current group.
+	 */
+	unsigned int		idx;
+	/*
+	 * Number of config_list entries in this group entry.
+	 */
+	unsigned int		num_entry;
+	/*
+	 * Algorithm strings.
+	 */
+	char			*hash_string;
+	char			*cipher_string;
+
+	/*
+	 * Algorithm string lengths.
+	 */
+	unsigned int		hash_strlen;
+	unsigned int		cipher_strlen;
+
+	/*
+	 * Key and its size.
+	 */
+	unsigned int		hash_keysize;
+	unsigned int		cipher_keysize;
+	u8			*hash_key;
+	u8			*cipher_key;
+
+	/*
+	 * List of config entries (network state info) for given idx.
+	 */
+	struct list_head	config_list;
+};
+
+int __init pohmelfs_config_init(void);
+void pohmelfs_config_exit(void);
+int pohmelfs_copy_config(struct pohmelfs_sb *psb);
+int pohmelfs_copy_crypto(struct pohmelfs_sb *psb);
+int pohmelfs_config_check(struct pohmelfs_config *config, int idx);
+int pohmelfs_state_init_one(struct pohmelfs_sb *psb, struct pohmelfs_config *conf);
+
+extern const struct file_operations pohmelfs_dir_fops;
+extern const struct inode_operations pohmelfs_dir_inode_ops;
+
+int pohmelfs_state_init(struct pohmelfs_sb *psb);
+void pohmelfs_state_exit(struct pohmelfs_sb *psb);
+void pohmelfs_state_flush_transactions(struct netfs_state *st);
+
+void pohmelfs_fill_inode(struct inode *inode, struct netfs_inode_info *info);
+
+void pohmelfs_name_del(struct pohmelfs_inode *parent, struct pohmelfs_name *n);
+void pohmelfs_free_names(struct pohmelfs_inode *parent);
+struct pohmelfs_name *pohmelfs_search_hash(struct pohmelfs_inode *pi, u32 hash);
+
+void pohmelfs_inode_del_inode(struct pohmelfs_sb *psb, struct pohmelfs_inode *pi);
+
+struct pohmelfs_inode *pohmelfs_create_entry_local(struct pohmelfs_sb *psb,
+	struct pohmelfs_inode *parent, struct qstr *str, u64 start, int mode);
+
+int pohmelfs_write_create_inode(struct pohmelfs_inode *pi);
+
+int pohmelfs_write_inode_create(struct inode *inode, struct netfs_trans *trans);
+int pohmelfs_remove_child(struct pohmelfs_inode *parent, struct pohmelfs_name *n);
+
+struct pohmelfs_inode *pohmelfs_new_inode(struct pohmelfs_sb *psb,
+		struct pohmelfs_inode *parent, struct qstr *str,
+		struct netfs_inode_info *info, int link);
+
+int pohmelfs_setattr(struct dentry *dentry, struct iattr *attr);
+int pohmelfs_setattr_raw(struct inode *inode, struct iattr *attr);
+
+int pohmelfs_meta_command(struct pohmelfs_inode *pi, unsigned int cmd_op, unsigned int flags,
+		netfs_trans_complete_t complete, void *priv, u64 start);
+int pohmelfs_meta_command_data(struct pohmelfs_inode *pi, u64 id, unsigned int cmd_op, char *addon,
+		unsigned int flags, netfs_trans_complete_t complete, void *priv, u64 start);
+
+void pohmelfs_check_states(struct pohmelfs_sb *psb);
+void pohmelfs_switch_active(struct pohmelfs_sb *psb);
+
+int pohmelfs_construct_path_string(struct pohmelfs_inode *pi, void *data, int len);
+int pohmelfs_path_length(struct pohmelfs_inode *pi);
+
+struct pohmelfs_crypto_completion
+{
+	struct completion	complete;
+	int			error;
+};
+
+int pohmelfs_trans_crypt(struct netfs_trans *t, struct pohmelfs_sb *psb);
+void pohmelfs_crypto_exit(struct pohmelfs_sb *psb);
+int pohmelfs_crypto_init(struct pohmelfs_sb *psb);
+
+int pohmelfs_crypto_engine_init(struct pohmelfs_crypto_engine *e, struct pohmelfs_sb *psb);
+void pohmelfs_crypto_engine_exit(struct pohmelfs_crypto_engine *e);
+
+int pohmelfs_crypto_process_input_data(struct pohmelfs_crypto_engine *e, u64 iv,
+		void *data, struct page *page, unsigned int size);
+int pohmelfs_crypto_process_input_page(struct pohmelfs_crypto_engine *e,
+		struct page *page, unsigned int size, u64 iv);
+
+static inline u64 pohmelfs_gen_iv(struct netfs_trans *t)
+{
+	u64 iv = t->gen;
+
+	iv <<= 32;
+	iv |= ((unsigned long)t) & 0xffffffff;
+
+	return iv;
+}
+
+int pohmelfs_data_lock(struct pohmelfs_inode *pi, u64 start, u32 size, int type);
+int pohmelfs_data_unlock(struct pohmelfs_inode *pi, u64 start, u32 size, int type);
+int pohmelfs_data_lock_response(struct netfs_state *st);
+
+static inline int pohmelfs_need_lock(struct pohmelfs_inode *pi, int type)
+{
+	if (test_bit(NETFS_INODE_OWNED, &pi->state)) {
+		if (type == pi->lock_type)
+			return 0;
+		if ((type == POHMELFS_READ_LOCK) && (pi->lock_type == POHMELFS_WRITE_LOCK))
+			return 0;
+	}
+
+	if (!test_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state))
+		return 0;
+
+	return 1;
+}
+
+int __init pohmelfs_mcache_init(void);
+void pohmelfs_mcache_exit(void);
+
+//#define CONFIG_POHMELFS_DEBUG
+
+#ifdef CONFIG_POHMELFS_DEBUG
+#define dprintka(f, a...) printk(f, ##a)
+#define dprintk(f, a...) printk("%d: " f, task_pid_vnr(current), ##a)
+#else
+#define dprintka(f, a...) do {} while (0)
+#define dprintk(f, a...) do {} while (0)
+#endif
+
+static inline void netfs_trans_get(struct netfs_trans *t)
+{
+	atomic_inc(&t->refcnt);
+}
+
+static inline void netfs_trans_put(struct netfs_trans *t)
+{
+	if (atomic_dec_and_test(&t->refcnt)) {
+		dprintk("%s: t: %p, gen: %u, err: %d.\n",
+			__func__, t, t->gen, t->result);
+		if (t->complete)
+			t->complete(t->pages, t->page_num,
+				t->private, t->result);
+		netfs_trans_free(t);
+	}
+}
+
+struct pohmelfs_mcache
+{
+	struct rb_node			mcache_entry;
+	struct completion		complete;
+
+	atomic_t			refcnt;
+
+	u64				gen;
+
+	void				*data;
+	u64				start;
+	u32				size;
+	int				err;
+
+	struct netfs_inode_info		info;
+};
+
+struct pohmelfs_mcache *pohmelfs_mcache_alloc(struct pohmelfs_sb *psb, u64 start,
+		unsigned int size, void *data);
+void pohmelfs_mcache_free(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m);
+struct pohmelfs_mcache *pohmelfs_mcache_search(struct pohmelfs_sb *psb, u64 gen);
+void pohmelfs_mcache_remove_locked(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m);
+
+static inline void pohmelfs_mcache_get(struct pohmelfs_mcache *m)
+{
+	atomic_inc(&m->refcnt);
+}
+
+static inline void pohmelfs_mcache_put(struct pohmelfs_sb *psb,
+		struct pohmelfs_mcache *m)
+{
+	if (atomic_dec_and_test(&m->refcnt))
+		pohmelfs_mcache_free(psb, m);
+}
+
+int pohmelfs_ftrans_init(void);
+void pohmelfs_ftrans_exit(void);
+void pohmelfs_ftrans_update(u64 id);
+int pohmelfs_ftrans_check(u64 id);
+void pohmelfs_ftrans_clean(u64 id);
+
+#endif /* __KERNEL__*/
+
+#endif /* __NETFS_H */
diff --git a/drivers/staging/pohmelfs/path_entry.c b/drivers/staging/pohmelfs/path_entry.c
new file mode 100644
index 0000000..3bad888
--- /dev/null
+++ b/drivers/staging/pohmelfs/path_entry.c
@@ -0,0 +1,114 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * 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.
+ *
+ * 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/module.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/ktime.h>
+#include <linux/fs_struct.h>
+#include <linux/pagemap.h>
+#include <linux/writeback.h>
+#include <linux/mount.h>
+#include <linux/mm.h>
+
+#include "netfs.h"
+
+#define UNHASHED_OBSCURE_STRING_SIZE		sizeof(" (deleted)")
+
+/*
+ * Create path from root for given inode.
+ * Path is formed as set of stuctures, containing name of the object
+ * and its inode data (mode, permissions and so on).
+ */
+int pohmelfs_construct_path_string(struct pohmelfs_inode *pi, void *data, int len)
+{
+	struct path path;
+	struct dentry *d;
+	char *ptr;
+	int err = 0, strlen, reduce = 0;
+
+	d = d_find_alias(&pi->vfs_inode);
+	if (!d) {
+		printk("%s: no alias, list_empty: %d.\n", __func__, list_empty(&pi->vfs_inode.i_dentry));
+		return -ENOENT;
+	}
+
+	read_lock(&current->fs->lock);
+	path.mnt = mntget(current->fs->root.mnt);
+	read_unlock(&current->fs->lock);
+
+	path.dentry = d;
+
+	if (!IS_ROOT(d) && d_unhashed(d))
+		reduce = 1;
+
+	ptr = d_path(&path, data, len);
+	if (IS_ERR(ptr)) {
+		err = PTR_ERR(ptr);
+		goto out;
+	}
+
+	if (reduce && len >= UNHASHED_OBSCURE_STRING_SIZE) {
+		char *end = data + len - UNHASHED_OBSCURE_STRING_SIZE;
+		*end = '\0';
+	}
+
+	strlen = len - (ptr - (char *)data);
+	memmove(data, ptr, strlen);
+	ptr = data;
+
+	err = strlen;
+
+	dprintk("%s: dname: '%s', len: %u, maxlen: %u, name: '%s', strlen: %d.\n",
+			__func__, d->d_name.name, d->d_name.len, len, ptr, strlen);
+
+out:
+	dput(d);
+	mntput(path.mnt);
+
+	return err;
+}
+
+int pohmelfs_path_length(struct pohmelfs_inode *pi)
+{
+	struct dentry *d, *root, *first;
+	int len = 1; /* Root slash */
+
+	first = d = d_find_alias(&pi->vfs_inode);
+	if (!d) {
+		dprintk("%s: ino: %llu, mode: %o.\n", __func__, pi->ino, pi->vfs_inode.i_mode);
+		return -ENOENT;
+	}
+
+	read_lock(&current->fs->lock);
+	root = dget(current->fs->root.dentry);
+	read_unlock(&current->fs->lock);
+
+	spin_lock(&dcache_lock);
+
+	if (!IS_ROOT(d) && d_unhashed(d))
+		len += UNHASHED_OBSCURE_STRING_SIZE; /* Obscure " (deleted)" string */
+
+	while (d && d != root && !IS_ROOT(d)) {
+		len += d->d_name.len + 1; /* Plus slash */
+		d = d->d_parent;
+	}
+	spin_unlock(&dcache_lock);
+
+	dput(root);
+	dput(first);
+
+	return len + 1; /* Including zero-byte */
+}
diff --git a/drivers/staging/pohmelfs/trans.c b/drivers/staging/pohmelfs/trans.c
new file mode 100644
index 0000000..bcb5942
--- /dev/null
+++ b/drivers/staging/pohmelfs/trans.c
@@ -0,0 +1,715 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * 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.
+ *
+ * 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/module.h>
+#include <linux/crypto.h>
+#include <linux/fs.h>
+#include <linux/jhash.h>
+#include <linux/hash.h>
+#include <linux/ktime.h>
+#include <linux/mempool.h>
+#include <linux/mm.h>
+#include <linux/mount.h>
+#include <linux/pagemap.h>
+#include <linux/parser.h>
+#include <linux/poll.h>
+#include <linux/swap.h>
+#include <linux/slab.h>
+#include <linux/statfs.h>
+#include <linux/writeback.h>
+
+#include "netfs.h"
+
+static struct kmem_cache *netfs_trans_dst;
+static mempool_t *netfs_trans_dst_pool;
+
+static void netfs_trans_init_static(struct netfs_trans *t, int num, int size)
+{
+	t->page_num = num;
+	t->total_size = size;
+	atomic_set(&t->refcnt, 1);
+
+	spin_lock_init(&t->dst_lock);
+	INIT_LIST_HEAD(&t->dst_list);
+}
+
+static int netfs_trans_send_pages(struct netfs_trans *t, struct netfs_state *st)
+{
+	int err = 0;
+	unsigned int i, attached_pages = t->attached_pages, ci;
+	struct msghdr msg;
+	struct page **pages = (t->eng)?t->eng->pages:t->pages;
+	struct page *p;
+	unsigned int size;
+
+	msg.msg_name = NULL;
+	msg.msg_namelen = 0;
+	msg.msg_control = NULL;
+	msg.msg_controllen = 0;
+	msg.msg_flags = MSG_WAITALL | MSG_MORE;
+
+	ci = 0;
+	for (i=0; i<t->page_num; ++i) {
+		struct page *page = pages[ci];
+		struct netfs_cmd cmd;
+		struct iovec io;
+
+		p = t->pages[i];
+
+		if (!p)
+			continue;
+
+		size = page_private(p);
+
+		io.iov_base = &cmd;
+		io.iov_len = sizeof(struct netfs_cmd);
+
+		cmd.cmd = NETFS_WRITE_PAGE;
+		cmd.ext = 0;
+		cmd.id = 0;
+		cmd.size = size;
+		cmd.start = p->index;
+		cmd.start <<= PAGE_CACHE_SHIFT;
+		cmd.csize = 0;
+		cmd.cpad = 0;
+		cmd.iv = pohmelfs_gen_iv(t);
+
+		netfs_convert_cmd(&cmd);
+
+		msg.msg_iov = &io;
+		msg.msg_iovlen = 1;
+		msg.msg_flags = MSG_WAITALL | MSG_MORE;
+
+		err = kernel_sendmsg(st->socket, &msg, (struct kvec *)msg.msg_iov, 1, sizeof(struct netfs_cmd));
+		if (err <= 0) {
+			printk("%s: %d/%d failed to send transaction header: t: %p, gen: %u, err: %d.\n",
+					__func__, i, t->page_num, t, t->gen, err);
+			if (err == 0)
+				err = -ECONNRESET;
+			goto err_out;
+		}
+
+		msg.msg_flags = MSG_WAITALL|(attached_pages == 1)?0:MSG_MORE;
+
+		err = kernel_sendpage(st->socket, page, 0, size, msg.msg_flags);
+		if (err <= 0) {
+			printk("%s: %d/%d failed to send transaction page: t: %p, gen: %u, size: %u, err: %d.\n",
+					__func__, i, t->page_num, t, t->gen, size, err);
+			if (err == 0)
+				err = -ECONNRESET;
+			goto err_out;
+		}
+
+		dprintk("%s: %d/%d sent t: %p, gen: %u, page: %p/%p, size: %u.\n",
+			__func__, i, t->page_num, t, t->gen, page, p, size);
+
+		err = 0;
+		attached_pages--;
+		if (!attached_pages)
+			break;
+		ci++;
+
+		continue;
+
+err_out:
+		printk("%s: t: %p, gen: %u, err: %d.\n", __func__, t, t->gen, err);
+		netfs_state_exit(st);
+		break;
+	}
+
+	return err;
+}
+
+int netfs_trans_send(struct netfs_trans *t, struct netfs_state *st)
+{
+	int err;
+	struct msghdr msg;
+
+	BUG_ON(!t->iovec.iov_len);
+	BUG_ON(t->iovec.iov_len > 1024*1024*1024);
+
+	netfs_state_lock_send(st);
+	if (!st->socket) {
+		err = netfs_state_init(st);
+		if (err)
+			goto err_out_unlock_return;
+	}
+
+	msg.msg_iov = &t->iovec;
+	msg.msg_iovlen = 1;
+	msg.msg_name = NULL;
+	msg.msg_namelen = 0;
+	msg.msg_control = NULL;
+	msg.msg_controllen = 0;
+	msg.msg_flags = MSG_WAITALL;
+
+	if (t->attached_pages)
+		msg.msg_flags |= MSG_MORE;
+
+	err = kernel_sendmsg(st->socket, &msg, (struct kvec *)msg.msg_iov, 1, t->iovec.iov_len);
+	if (err <= 0) {
+		printk("%s: failed to send contig transaction: t: %p, gen: %u, size: %zu, err: %d.\n",
+				__func__, t, t->gen, t->iovec.iov_len, err);
+		if (err == 0)
+			err = -ECONNRESET;
+		goto err_out_unlock_return;
+	}
+
+	dprintk("%s: sent %s transaction: t: %p, gen: %u, size: %zu, page_num: %u.\n",
+			__func__, (t->page_num)?"partial":"full",
+			t, t->gen, t->iovec.iov_len, t->page_num);
+
+	err = 0;
+	if (t->attached_pages)
+		err = netfs_trans_send_pages(t, st);
+
+err_out_unlock_return:
+
+	if (st->need_reset) {
+		netfs_state_exit(st);
+	}
+	netfs_state_unlock_send(st);
+
+	dprintk("%s: t: %p, gen: %u, err: %d.\n",
+		__func__, t, t->gen, err);
+
+	t->result = err;
+	return err;
+}
+
+static inline int netfs_trans_cmp(unsigned int gen, unsigned int new)
+{
+	if (gen < new)
+		return 1;
+	if (gen > new)
+		return -1;
+	return 0;
+}
+
+struct netfs_trans_dst *netfs_trans_search(struct netfs_state *st, unsigned int gen)
+{
+	struct rb_root *root = &st->trans_root;
+	struct rb_node *n = root->rb_node;
+	struct netfs_trans_dst *tmp, *ret = NULL;
+	struct netfs_trans *t;
+	int cmp;
+
+	while (n) {
+		tmp = rb_entry(n, struct netfs_trans_dst, state_entry);
+		t = tmp->trans;
+
+		cmp = netfs_trans_cmp(t->gen, gen);
+		if (cmp < 0)
+			n = n->rb_left;
+		else if (cmp > 0)
+			n = n->rb_right;
+		else {
+			ret = tmp;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static int netfs_trans_insert(struct netfs_trans_dst *ndst, struct netfs_state *st)
+{
+	struct rb_root *root = &st->trans_root;
+	struct rb_node **n = &root->rb_node, *parent = NULL;
+	struct netfs_trans_dst *ret = NULL, *tmp;
+	struct netfs_trans *t = NULL, *new = ndst->trans;
+	int cmp;
+
+	while (*n) {
+		parent = *n;
+
+		tmp = rb_entry(parent, struct netfs_trans_dst, state_entry);
+		t = tmp->trans;
+
+		cmp = netfs_trans_cmp(t->gen, new->gen);
+		if (cmp < 0)
+			n = &parent->rb_left;
+		else if (cmp > 0)
+			n = &parent->rb_right;
+		else {
+			ret = tmp;
+			break;
+		}
+	}
+
+	if (ret) {
+		printk("%s: exist: old: gen: %u, flags: %x, send_time: %lu, "
+				"new: gen: %u, flags: %x, send_time: %lu.\n",
+			__func__, t->gen, t->flags, ret->send_time,
+			new->gen, new->flags, ndst->send_time);
+		return -EEXIST;
+	}
+
+	rb_link_node(&ndst->state_entry, parent, n);
+	rb_insert_color(&ndst->state_entry, root);
+	ndst->send_time = jiffies;
+
+	return 0;
+}
+
+int netfs_trans_remove_nolock(struct netfs_trans_dst *dst, struct netfs_state *st)
+{
+	if (dst && dst->state_entry.rb_parent_color) {
+		rb_erase(&dst->state_entry, &st->trans_root);
+		dst->state_entry.rb_parent_color = 0;
+		return 1;
+	}
+	return 0;
+}
+
+static int netfs_trans_remove_state(struct netfs_trans_dst *dst)
+{
+	int ret;
+	struct netfs_state *st = dst->state;
+
+	mutex_lock(&st->trans_lock);
+	ret = netfs_trans_remove_nolock(dst, st);
+	mutex_unlock(&st->trans_lock);
+
+	return ret;
+}
+
+/*
+ * Create new destination for given transaction associated with given network state.
+ * Transaction's reference counter is bumped and will be dropped when either
+ * reply is received or when async timeout detection task will fail resending
+ * and drop transaction.
+ */
+static int netfs_trans_push_dst(struct netfs_trans *t, struct netfs_state *st)
+{
+	struct netfs_trans_dst *dst;
+	int err;
+
+	dst = mempool_alloc(netfs_trans_dst_pool, GFP_KERNEL);
+	if (!dst)
+		return -ENOMEM;
+
+	dst->retries = 0;
+	dst->send_time = 0;
+	dst->state = st;
+	dst->trans = t;
+	netfs_trans_get(t);
+
+	mutex_lock(&st->trans_lock);
+	err = netfs_trans_insert(dst, st);
+	mutex_unlock(&st->trans_lock);
+
+	if (err)
+		goto err_out_free;
+
+	spin_lock(&t->dst_lock);
+	list_add_tail(&dst->trans_entry, &t->dst_list);
+	spin_unlock(&t->dst_lock);
+
+	return 0;
+
+err_out_free:
+	t->result = err;
+	netfs_trans_put(t);
+	mempool_free(dst, netfs_trans_dst_pool);
+	return err;
+}
+
+static void netfs_trans_free_dst(struct netfs_trans_dst *dst)
+{
+	netfs_trans_put(dst->trans);
+	mempool_free(dst, netfs_trans_dst_pool);
+}
+
+static void netfs_trans_remove_dst(struct netfs_trans_dst *dst)
+{
+	if (netfs_trans_remove_state(dst))
+		netfs_trans_free_dst(dst);
+}
+
+/*
+ * Drop destination transaction entry when we know it.
+ */
+void netfs_trans_drop_dst(struct netfs_trans_dst *dst)
+{
+	struct netfs_trans *t = dst->trans;
+
+	spin_lock(&t->dst_lock);
+	list_del_init(&dst->trans_entry);
+	spin_unlock(&t->dst_lock);
+
+	netfs_trans_remove_dst(dst);
+}
+
+/*
+ * Drop destination transaction entry when we know it and when we
+ * already removed dst from state tree.
+ */
+void netfs_trans_drop_dst_nostate(struct netfs_trans_dst *dst)
+{
+	struct netfs_trans *t = dst->trans;
+
+	spin_lock(&t->dst_lock);
+	list_del_init(&dst->trans_entry);
+	spin_unlock(&t->dst_lock);
+
+	netfs_trans_free_dst(dst);
+}
+
+/*
+ * This drops destination transaction entry from appropriate network state
+ * tree and drops related reference counter. It is possible that transaction
+ * will be freed here if its reference counter hits zero.
+ * Destination transaction entry will be freed.
+ */
+void netfs_trans_drop_trans(struct netfs_trans *t, struct netfs_state *st)
+{
+	struct netfs_trans_dst *dst, *tmp, *ret = NULL;
+
+	spin_lock(&t->dst_lock);
+	list_for_each_entry_safe(dst, tmp, &t->dst_list, trans_entry) {
+		if (dst->state == st) {
+			ret = dst;
+			list_del(&dst->trans_entry);
+			break;
+		}
+	}
+	spin_unlock(&t->dst_lock);
+
+	if (ret)
+		netfs_trans_remove_dst(ret);
+}
+
+/*
+ * This drops destination transaction entry from appropriate network state
+ * tree and drops related reference counter. It is possible that transaction
+ * will be freed here if its reference counter hits zero.
+ * Destination transaction entry will be freed.
+ */
+void netfs_trans_drop_last(struct netfs_trans *t, struct netfs_state *st)
+{
+	struct netfs_trans_dst *dst, *tmp, *ret;
+
+	spin_lock(&t->dst_lock);
+	ret = list_entry(t->dst_list.prev, struct netfs_trans_dst, trans_entry);
+	if (ret->state != st) {
+		ret = NULL;
+		list_for_each_entry_safe(dst, tmp, &t->dst_list, trans_entry) {
+			if (dst->state == st) {
+				ret = dst;
+				list_del_init(&dst->trans_entry);
+				break;
+			}
+		}
+	} else {
+		list_del(&ret->trans_entry);
+	}
+	spin_unlock(&t->dst_lock);
+
+	if (ret)
+		netfs_trans_remove_dst(ret);
+}
+
+static int netfs_trans_push(struct netfs_trans *t, struct netfs_state *st)
+{
+	int err;
+
+	err = netfs_trans_push_dst(t, st);
+	if (err)
+		return err;
+
+	err = netfs_trans_send(t, st);
+	if (err)
+		goto err_out_free;
+
+	if (t->flags & NETFS_TRANS_SINGLE_DST)
+		pohmelfs_switch_active(st->psb);
+
+	return 0;
+
+err_out_free:
+	t->result = err;
+	netfs_trans_drop_last(t, st);
+
+	return err;
+}
+
+int netfs_trans_finish_send(struct netfs_trans *t, struct pohmelfs_sb *psb)
+{
+	struct pohmelfs_config *c;
+	int err = -ENODEV;
+	struct netfs_state *st;
+#if 0
+	dprintk("%s: t: %p, gen: %u, size: %u, page_num: %u, active: %p.\n",
+		__func__, t, t->gen, t->iovec.iov_len, t->page_num, psb->active_state);
+#endif
+	mutex_lock(&psb->state_lock);
+
+	if ((t->flags & NETFS_TRANS_SINGLE_DST) && psb->active_state) {
+		st = &psb->active_state->state;
+
+		err = -EPIPE;
+		if (netfs_state_poll(st) & POLLOUT) {
+			err = netfs_trans_push_dst(t, st);
+			if (!err) {
+				err = netfs_trans_send(t, st);
+				if (err) {
+					netfs_trans_drop_last(t, st);
+				} else {
+					pohmelfs_switch_active(psb);
+					goto out;
+				}
+			}
+		}
+		pohmelfs_switch_active(psb);
+	}
+
+	list_for_each_entry(c, &psb->state_list, config_entry) {
+		st = &c->state;
+
+		err = netfs_trans_push(t, st);
+		if (!err && (t->flags & NETFS_TRANS_SINGLE_DST))
+			break;
+	}
+out:
+	mutex_unlock(&psb->state_lock);
+#if 0
+	dprintk("%s: fully sent t: %p, gen: %u, size: %u, page_num: %u, err: %d.\n",
+		__func__, t, t->gen, t->iovec.iov_len, t->page_num, err);
+#endif
+	if (err)
+		t->result = err;
+	return err;
+}
+
+int netfs_trans_finish(struct netfs_trans *t, struct pohmelfs_sb *psb)
+{
+	int err;
+	struct netfs_cmd *cmd = t->iovec.iov_base;
+
+	t->gen = atomic_inc_return(&psb->trans_gen);
+
+	pohmelfs_ftrans_clean(t->gen);
+
+	cmd->size = t->iovec.iov_len - sizeof(struct netfs_cmd) +
+		t->attached_size + t->attached_pages * sizeof(struct netfs_cmd);
+	cmd->cmd = NETFS_TRANS;
+	cmd->start = t->gen;
+	cmd->id = 0;
+
+	if (psb->perform_crypto) {
+		cmd->ext = psb->crypto_attached_size;
+		cmd->csize = psb->crypto_attached_size;
+	}
+
+	dprintk("%s: t: %u, size: %u, iov_len: %zu, attached_size: %u, attached_pages: %u.\n",
+			__func__, t->gen, cmd->size, t->iovec.iov_len, t->attached_size, t->attached_pages);
+	err = pohmelfs_trans_crypt(t, psb);
+	if (err) {
+		t->result = err;
+		netfs_convert_cmd(cmd);
+		dprintk("%s: trans: %llu, crypto_attached_size: %u, attached_size: %u, attached_pages: %d, trans_size: %u, err: %d.\n",
+			__func__, cmd->start, psb->crypto_attached_size, t->attached_size, t->attached_pages, cmd->size, err);
+	}
+	netfs_trans_put(t);
+	return err;
+}
+
+/*
+ * Resend transaction to remote server(s).
+ * If new servers were added into superblock, we can try to send data
+ * to them too.
+ *
+ * It is called under superblock's state_lock, so we can safely
+ * dereference psb->state_list. Also, transaction's reference counter is
+ * bumped, so it can not go away under us, thus we can safely access all
+ * its members. State is locked.
+ *
+ * This function returns 0 if transaction was successfully sent to at
+ * least one destination target.
+ */
+int netfs_trans_resend(struct netfs_trans *t, struct pohmelfs_sb *psb)
+{
+	struct netfs_trans_dst *dst;
+	struct netfs_state *st;
+	struct pohmelfs_config *c;
+	int err, exist, error = -ENODEV;
+
+	list_for_each_entry(c, &psb->state_list, config_entry) {
+		st = &c->state;
+
+		exist = 0;
+		spin_lock(&t->dst_lock);
+		list_for_each_entry(dst, &t->dst_list, trans_entry) {
+			if (st == dst->state) {
+				exist = 1;
+				break;
+			}
+		}
+		spin_unlock(&t->dst_lock);
+
+		if (exist) {
+			if (!(t->flags & NETFS_TRANS_SINGLE_DST) ||
+					(c->config_entry.next == &psb->state_list)) {
+				dprintk("%s: resending st: %p, t: %p, gen: %u.\n",
+						__func__, st, t, t->gen);
+				err = netfs_trans_send(t, st);
+				if (!err)
+					error = 0;
+			}
+			continue;
+		}
+
+		dprintk("%s: pushing/resending st: %p, t: %p, gen: %u.\n",
+				__func__, st, t, t->gen);
+		err = netfs_trans_push(t, st);
+		if (err)
+			continue;
+		error = 0;
+		if (t->flags & NETFS_TRANS_SINGLE_DST)
+			break;
+	}
+
+	t->result = error;
+	return error;
+}
+
+void *netfs_trans_add(struct netfs_trans *t, unsigned int size)
+{
+	struct iovec *io = &t->iovec;
+	void *ptr;
+
+	if (size > t->total_size) {
+		ptr = ERR_PTR(-EINVAL);
+		goto out;
+	}
+
+	if (io->iov_len + size > t->total_size) {
+		dprintk("%s: too big size t: %p, gen: %u, iov_len: %zu, size: %u, total: %u.\n",
+				__func__, t, t->gen, io->iov_len, size, t->total_size);
+		ptr = ERR_PTR(-E2BIG);
+		goto out;
+	}
+
+	ptr = io->iov_base + io->iov_len;
+	io->iov_len += size;
+
+out:
+	dprintk("%s: t: %p, gen: %u, size: %u, total: %zu.\n",
+		__func__, t, t->gen, size, io->iov_len);
+	return ptr;
+}
+
+void netfs_trans_free(struct netfs_trans *t)
+{
+	if (t->eng)
+		pohmelfs_crypto_thread_make_ready(t->eng->thread);
+	kfree(t);
+}
+
+struct netfs_trans *netfs_trans_alloc(struct pohmelfs_sb *psb, unsigned int size,
+		unsigned int flags, unsigned int nr)
+{
+	struct netfs_trans *t;
+	unsigned int num, cont, pad, size_no_trans;
+	unsigned int crypto_added = 0;
+	struct netfs_cmd *cmd;
+
+	if (psb->perform_crypto)
+		crypto_added = psb->crypto_attached_size;
+
+	/*
+	 * |sizeof(struct netfs_trans)|
+	 * |sizeof(struct netfs_cmd)| - transaction header
+	 * |size| - buffer with requested size
+	 * |padding| - crypto padding, zero bytes
+	 * |nr * sizeof(struct page *)| - array of page pointers
+	 *
+	 * Overall size should be less than PAGE_SIZE for guaranteed allocation.
+	 */
+
+	cont = size;
+	size = ALIGN(size, psb->crypto_align_size);
+	pad = size - cont;
+
+	size_no_trans = size + sizeof(struct netfs_cmd) * 2 + crypto_added;
+
+	cont = sizeof(struct netfs_trans) + size_no_trans;
+
+	num = (PAGE_SIZE - cont)/sizeof(struct page *);
+
+	if (nr > num)
+		nr = num;
+
+	t = kzalloc(cont + nr*sizeof(struct page *), GFP_NOIO);
+	if (!t)
+		goto err_out_exit;
+
+	t->iovec.iov_base = (void *)(t + 1);
+	t->pages = (struct page **)(t->iovec.iov_base + size_no_trans);
+
+	/*
+	 * Reserving space for transaction header.
+	 */
+	t->iovec.iov_len = sizeof(struct netfs_cmd) + crypto_added;
+
+	netfs_trans_init_static(t, nr, size_no_trans);
+
+	t->flags = flags;
+	t->psb = psb;
+
+	cmd = (struct netfs_cmd *)t->iovec.iov_base;
+
+	cmd->size = size;
+	cmd->cpad = pad;
+	cmd->csize = crypto_added;
+
+	dprintk("%s: t: %p, gen: %u, size: %u, padding: %u, align_size: %u, flags: %x, "
+			"page_num: %u, base: %p, pages: %p.\n",
+			__func__, t, t->gen, size, pad, psb->crypto_align_size, flags, nr,
+			t->iovec.iov_base, t->pages);
+
+	return t;
+
+err_out_exit:
+	return NULL;
+}
+
+int netfs_trans_init(void)
+{
+	int err = -ENOMEM;
+
+	netfs_trans_dst = kmem_cache_create("netfs_trans_dst", sizeof(struct netfs_trans_dst),
+			0, 0, NULL);
+	if (!netfs_trans_dst)
+		goto err_out_exit;
+
+	netfs_trans_dst_pool = mempool_create_slab_pool(256, netfs_trans_dst);
+	if (!netfs_trans_dst_pool)
+		goto err_out_free;
+
+	return 0;
+
+err_out_free:
+	kmem_cache_destroy(netfs_trans_dst);
+err_out_exit:
+	return err;
+}
+
+void netfs_trans_exit(void)
+{
+	mempool_destroy(netfs_trans_dst_pool);
+	kmem_cache_destroy(netfs_trans_dst);
+}
diff --git a/drivers/staging/rspiusb/rspiusb.c b/drivers/staging/rspiusb/rspiusb.c
index ca281d6..ecaffb5 100644
--- a/drivers/staging/rspiusb/rspiusb.c
+++ b/drivers/staging/rspiusb/rspiusb.c
@@ -781,9 +781,8 @@
 			dbg("Endpoint[%d]->MaxPacketSize = %d\n", i,
 			    endpoint->wMaxPacketSize);
 		}
-		if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
-		    USB_ENDPOINT_XFER_BULK) {
-			if (endpoint->bEndpointAddress & USB_DIR_IN)
+		if (usb_endpoint_xfer_bulk(endpoint)) {
+			if (usb_endpoint_dir_in(endpoint))
 				pdx->hEP[i] =
 				    usb_rcvbulkpipe(pdx->udev,
 						    endpoint->bEndpointAddress);
diff --git a/drivers/staging/rt2860/2860_main_dev.c b/drivers/staging/rt2860/2860_main_dev.c
index 08ca81f..ff7f833 100644
--- a/drivers/staging/rt2860/2860_main_dev.c
+++ b/drivers/staging/rt2860/2860_main_dev.c
@@ -90,12 +90,10 @@
 static void __exit rt2860_cleanup_module(void);
 static int __init rt2860_init_module(void);
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 #ifdef CONFIG_PM
 static int rt2860_suspend(struct pci_dev *pci_dev, pm_message_t state);
 static int rt2860_resume(struct pci_dev *pci_dev);
 #endif // CONFIG_PM //
-#endif
 
 
 //
@@ -128,22 +126,15 @@
     name:       "rt2860",
     id_table:   rt2860_pci_tbl,
     probe:      rt2860_init_one,
-#if LINUX_VERSION_CODE >= 0x20412
     remove:     __devexit_p(rt2860_remove_one),
-#else
-    remove:     __devexit(rt2860_remove_one),
-#endif
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 #ifdef CONFIG_PM
 	suspend:	rt2860_suspend,
 	resume:		rt2860_resume,
 #endif
-#endif
 };
 
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 #ifdef CONFIG_PM
 
 VOID RT2860RejectPendingPackets(
@@ -284,16 +275,11 @@
 	return 0;
 }
 #endif // CONFIG_PM //
-#endif
 
 
 static INT __init rt2860_init_module(VOID)
 {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 	return pci_register_driver(&rt2860_driver);
-#else
-    return pci_module_init(&rt2860_driver);
-#endif
 }
 
 
@@ -374,11 +360,7 @@
 	}
 
 	// Free pre-allocated net_device memory
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 	free_netdev(net_dev);
-#else
-	kfree(net_dev);
-#endif
 }
 
 //
@@ -758,16 +740,13 @@
 int print_int_count;
 
 IRQ_HANDLE_TYPE
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19))
 rt2860_interrupt(int irq, void *dev_instance)
-#else
-rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
-#endif
 {
 	struct net_device *net_dev = (struct net_device *) dev_instance;
 	PRTMP_ADAPTER pAd = net_dev->ml_priv;
 	INT_SOURCE_CSR_STRUC	IntSource;
 	POS_COOKIE pObj;
+	BOOLEAN	bOldValue;
 
 	pObj = (POS_COOKIE) pAd->OS_Cookie;
 
@@ -800,20 +779,19 @@
 	// RT2661 => when ASIC is sleeping, MAC register cannot be read and written.
 	// RT2860 => when ASIC is sleeping, MAC register can be read and written.
 
+	bOldValue = pAd->bPCIclkOff;
+	pAd->bPCIclkOff = FALSE;
 	{
 		RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
 		RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word); // write 1 to clear
 	}
+	pAd->bPCIclkOff = bOldValue;
 
 	// Do nothing if Reset in progress
 	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
 		RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
 	{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-        return  IRQ_HANDLED;
-#else
-        return;
-#endif
+		return IRQ_HANDLED;
 	}
 
 	//
@@ -822,8 +800,6 @@
 	// The priority can be adjust by altering processing if statement
 	//
 
-    pAd->bPCIclkOff = FALSE;
-
 	// If required spinlock, each interrupt service routine has to acquire
 	// and release itself.
 	//
@@ -832,11 +808,8 @@
 	if (IntSource.word == 0xffffffff)
 	{
 		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-        return  IRQ_HANDLED;
-#else
-        return;
-#endif
+		printk("snowpin - IntSource.word == 0xffffffff\n");
+		return IRQ_HANDLED;
 	}
 
 	if (IntSource.word & TxCoherent)
@@ -970,10 +943,7 @@
 	}
 #endif // CONFIG_STA_SUPPORT //
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
     return  IRQ_HANDLED;
-#endif
-
 }
 
 /*
@@ -1026,11 +996,7 @@
     ULONG	csr_addr;
 
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-    print_name = pci_dev ? pci_name(pci_dev) : "rt2860";
-#else
-    print_name = pci_dev ? pci_dev->slot_name : "rt2860";
-#endif // LINUX_VERSION_CODE //
+	print_name = pci_dev ? pci_name(pci_dev) : "rt2860";
 
 	net_dev->base_addr = 0;
 	net_dev->irq = 0;
diff --git a/drivers/staging/rt2860/Makefile b/drivers/staging/rt2860/Makefile
index 6162212..b956364 100644
--- a/drivers/staging/rt2860/Makefile
+++ b/drivers/staging/rt2860/Makefile
@@ -2,7 +2,6 @@
 
 # TODO: all of these should be removed
 EXTRA_CFLAGS += -DLINUX -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT
-EXTRA_CFLAGS += -DRT2860
 EXTRA_CFLAGS += -DCONFIG_STA_SUPPORT
 EXTRA_CFLAGS += -DDBG
 EXTRA_CFLAGS += -DDOT11_N_SUPPORT
diff --git a/drivers/staging/rt2860/TODO b/drivers/staging/rt2860/TODO
index 2f70b0f..6158dc2 100644
--- a/drivers/staging/rt2860/TODO
+++ b/drivers/staging/rt2860/TODO
@@ -1,6 +1,6 @@
 I'm hesitant to add a TODO file here, as the wireless developers would
 really have people help them out on the "clean" rt2860 driver that can
-be found at the rt2860.sf.net site.
+be found at the http://rt2x00.serialmonkey.com/ site.
 
 But, if you wish to clean up this driver instead, here's a short list of
 things that need to be done to get it into a more mergable shape:
@@ -8,7 +8,7 @@
 TODO:
 	- checkpatch.pl clean
 	- sparse clean
-	- port to in-kernel 80211 stack
+	- port to in-kernel 80211 stack and common rt2x00 infrastructure
 	- remove reading from /etc/ config files
 	- review by the wireless developer community
 
diff --git a/drivers/staging/rt2860/common/cmm_data.c b/drivers/staging/rt2860/common/cmm_data.c
index b67b9eb..b3f88f5 100644
--- a/drivers/staging/rt2860/common/cmm_data.c
+++ b/drivers/staging/rt2860/common/cmm_data.c
@@ -105,9 +105,7 @@
 	PNDIS_PACKET	pPacket;
 	NDIS_STATUS  	Status = NDIS_STATUS_SUCCESS;
 	ULONG	 		FreeNum;
-#ifdef RT2860
 	unsigned long	IrqFlags = 0;
-#endif // RT2860 //
 	UCHAR			IrqState;
 	UCHAR			rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
 
@@ -118,10 +116,9 @@
 	// 2860C use Tx Ring
 
 	IrqState = pAd->irq_disabled;
-#ifdef RT2860
+
 	if ((pAd->MACVersion == 0x28600100) && (!IrqState))
 		RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-#endif // RT2860 //
 
 	do
 	{
@@ -175,17 +172,14 @@
 
 	} while (FALSE);
 
-#ifdef RT2860
 	// 2860C use Tx Ring
 	if ((pAd->MACVersion == 0x28600100) && (!IrqState))
 		RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-#endif // RT2860 //
 
 	return Status;
 }
 
 
-#ifdef RT2860
 NDIS_STATUS MiniportMMRequestUnlock(
 	IN	PRTMP_ADAPTER	pAd,
 	IN	UCHAR			QueIdx,
@@ -253,7 +247,6 @@
 
 	return Status;
 }
-#endif // RT2860 //
 
 
 /*
@@ -290,17 +283,14 @@
 		return NDIS_STATUS_FAILURE;
 	}
 
-#ifdef RT2860
 	if ( pAd->MACVersion == 0x28600100 )
 		return MlmeHardTransmitTxRing(pAd,QueIdx,pPacket);
 	else
-#endif // RT2860 //
 		return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
 
 }
 
 
-#ifdef RT2860
 NDIS_STATUS MlmeHardTransmitTxRing(
 	IN	PRTMP_ADAPTER	pAd,
 	IN	UCHAR	QueIdx,
@@ -366,7 +356,7 @@
 	{
 		// outgoing frame always wakeup PHY to prevent frame lost
 		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-			AsicForceWakeup(pAd, TRUE);
+			AsicForceWakeup(pAd, FROM_TX);
 	}
 #endif // CONFIG_STA_SUPPORT //
 	pFirstTxWI	=(PTXWI_STRUC)pSrcBufVA;
@@ -509,7 +499,6 @@
 
 	return NDIS_STATUS_SUCCESS;
 }
-#endif // RT2860 //
 
 
 NDIS_STATUS MlmeHardTransmitMgmtRing(
@@ -541,7 +530,7 @@
 	{
 		// outgoing frame always wakeup PHY to prevent frame lost
 		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-			AsicForceWakeup(pAd, TRUE);
+			AsicForceWakeup(pAd, FROM_TX);
 	}
 #endif // CONFIG_STA_SUPPORT //
 
@@ -1076,7 +1065,6 @@
 				break;
 			}
 
-#ifdef RT2860
 			FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
 
 #ifdef DBG_DIAGNOSE
@@ -1101,7 +1089,6 @@
 				RTMPFreeTXDUponTxDmaDone(pAd, QueIdx);
 				FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
 			}
-#endif // RT2860 //
 
 			// probe the Queue Head
 			pQueue = &pAd->TxSwQueue[QueIdx];
@@ -1180,12 +1167,10 @@
 				Status = STAHardTransmit(pAd, pTxBlk, QueIdx);
 #endif // CONFIG_STA_SUPPORT //
 
-#ifdef RT2860
 			DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
 			// static rate also need NICUpdateFifoStaCounters() function.
 			//if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
 				NICUpdateFifoStaCounters(pAd);
-#endif // RT2860 //
 		}
 
 		RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
@@ -1764,7 +1749,6 @@
 }
 
 
-#ifdef RT2860
 BOOLEAN  RTMPFreeTXDUponTxDmaDone(
 	IN PRTMP_ADAPTER	pAd,
 	IN UCHAR			QueIdx)
@@ -2309,7 +2293,6 @@
 	DBGPRINT_RAW(RT_DEBUG_TRACE,(" 	RxSwReadIdx [%d]=", AC0freeIdx));
 	DBGPRINT_RAW(RT_DEBUG_TRACE,("	pending-NDIS=%ld\n", pAd->RalinkCounters.PendingNdisPacketCount));
 }
-#endif // RT2860 //
 
 /*
 	========================================================================
@@ -2634,9 +2617,7 @@
 					pEntry->AuthMode = pAd->StaCfg.AuthMode;
 					pEntry->WepStatus = pAd->StaCfg.WepStatus;
 					pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
-#ifdef RT2860
 					AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)i);
-#endif // RT2860 //
 				}
 #endif // CONFIG_STA_SUPPORT //
 			}
@@ -2823,9 +2804,7 @@
 
 	for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
 	{
-#ifdef RT2860
 		RT28XX_STA_ENTRY_MAC_RESET(pAd, i);
-#endif // RT2860 //
 		if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
 	   {
 
diff --git a/drivers/staging/rt2860/common/cmm_data_2860.c b/drivers/staging/rt2860/common/cmm_data_2860.c
index 419e50c..fae741e 100644
--- a/drivers/staging/rt2860/common/cmm_data_2860.c
+++ b/drivers/staging/rt2860/common/cmm_data_2860.c
@@ -634,7 +634,7 @@
 	}
 
     // Once go into this function, disable tx because don't want too many packets in queue to prevent HW stops.
-	pAd->bPCIclkOffDisableTx = TRUE;
+	RTMP_SET_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
 
 	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
 	{
@@ -651,7 +651,7 @@
 			{
 				DBGPRINT(RT_DEBUG_TRACE, ("TbTTTime = 0x%x , give up this sleep. \n", TbTTTime));
 	            OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
-	            pAd->bPCIclkOffDisableTx = FALSE;
+				RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
 				return;
 			}
 			else
@@ -688,18 +688,25 @@
 	if (i >= 50)
 	{
 		DBGPRINT(RT_DEBUG_TRACE, ("DMA keeps busy.  return on RT28xxPciAsicRadioOff ()\n"));
-		pAd->bPCIclkOffDisableTx = FALSE;
 		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
 		DmaCfg.field.EnableTxDMA = 1;
 		RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word);
+		pAd->CheckDmaBusyCount++;
 		return;
 	}
+	else
+	{
+		pAd->CheckDmaBusyCount = 0;
+	}
 
     RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
 
     // Set to 1R.
-    tempBBP_R3 = (pAd->StaCfg.BBPR3 & 0xE7);
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, tempBBP_R3);
+	if (pAd->Antenna.field.RxPath > 1)
+	{
+		tempBBP_R3 = (pAd->StaCfg.BBPR3 & 0xE7);
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, tempBBP_R3);
+	}
 
 	// In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
 	if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
@@ -714,8 +721,15 @@
 		AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
 	}
 
-    // When PCI clock is off, don't want to service interrupt.
-	RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt);
+	if (Level != RTMP_HALT)
+	{
+		// Change Interrupt bitmask.
+		RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt);
+	}
+	else
+	{
+		NICDisableInterrupt(pAd);
+	}
 
     RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
 	// Disable MAC Rx
@@ -726,7 +740,8 @@
 	//  2. Send Sleep command
 	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
 	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
-	AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x00);   // send POWER-SAVE command to MCU. Timeout unit:40us.
+	// send POWER-SAVE command to MCU. high-byte = 1 save power as much as possible. high byte = 0 save less power
+	AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x1);
 	//  2-1. Wait command success
 	// Status = 1 : success, Status = 2, already sleep, Status = 3, Maybe MAC is busy so can't finish this task.
 	brc = AsicCheckCommanOk(pAd, PowerSafeCID);
@@ -734,7 +749,7 @@
     if (brc == FALSE)
     {
         // try again
-    	AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x00);   // send POWER-SAVE command to MCU. Timeout unit:40us.
+    	AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x01);   // send POWER-SAVE command to MCU. Timeout unit:40us.
     	//RTMPusecDelay(200);
     	brc = AsicCheckCommanOk(pAd, PowerSafeCID);
     }
@@ -759,7 +774,7 @@
 	do
 	{
 		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
-		if (DmaCfg.field.RxDMABusy == 0)
+		if ((DmaCfg.field.RxDMABusy == 0) && (DmaCfg.field.TxDMABusy == 0))
 			break;
 		RTMPusecDelay(20);
 		i++;
@@ -767,13 +782,12 @@
 
 	if (i >= 50)
 	{
+		pAd->CheckDmaBusyCount++;
 		DBGPRINT(RT_DEBUG_TRACE, ("DMA Rx keeps busy.  on RT28xxPciAsicRadioOff ()\n"));
 	}
-	// disable DMA Rx.
+	else
 	{
-		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
-		DmaCfg.field.EnableRxDMA = 0;
-		RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word);
+		pAd->CheckDmaBusyCount = 0;
 	}
 
 	if (Level == DOT11POWERSAVE)
@@ -799,7 +813,7 @@
 	if (Level == RTMP_HALT)
 	{
 		if ((brc == TRUE) && (i < 50))
-			RTMPPCIeLinkCtrlSetting(pAd, 1);
+			RTMPPCIeLinkCtrlSetting(pAd, 0);
 	}
 	//  4. Set PCI configuration Space Link Comtrol fields.  Only Radio Off needs to call this function
 	else
@@ -808,7 +822,7 @@
 			RTMPPCIeLinkCtrlSetting(pAd, 3);
 	}
 
-    pAd->bPCIclkOffDisableTx = FALSE;
+	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
 }
 
 
@@ -835,7 +849,8 @@
 	{
 	    pAd->Mlme.bPsPollTimerRunning = FALSE;
 		RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
-		if ((Level == GUIRADIO_OFF) || (Level == GUI_IDLE_POWER_SAVE))
+		if ((Level == GUIRADIO_OFF) || (Level == GUI_IDLE_POWER_SAVE)
+		|| (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND)))
 		{
 			DBGPRINT(RT_DEBUG_TRACE, ("RT28xxPciAsicRadioOn ()\n"));
 			// 1. Set PCI Link Control in Configuration Space.
@@ -845,15 +860,14 @@
 	}
 
     pAd->bPCIclkOff = FALSE;
-
+	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x3a80);
 	// 2. Send wake up command.
-	AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x00);
+	AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02);
 
 	// 2-1. wait command ok.
 	brv = AsicCheckCommanOk(pAd, PowerWakeCID);
     if (brv)
     {
-    	//RTMP_IO_WRITE32(pAd, INT_MASK_CSR, (DELAYINTMASK|RxINT));
     	NICEnableInterrupt(pAd);
 
     	// 3. Enable Tx DMA.
@@ -893,13 +907,10 @@
 
 VOID RT28xxPciStaAsicForceWakeup(
 	IN PRTMP_ADAPTER pAd,
-	IN BOOLEAN       bFromTx)
+	IN UCHAR    	 Level)
 {
     AUTO_WAKEUP_STRUC	AutoWakeupCfg;
 
-    if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-        return;
-
     if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW))
     {
         DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n"));
@@ -907,38 +918,48 @@
     }
 
     OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
+	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
 
     if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
     {
         // Support PCIe Advance Power Save
-    	if (bFromTx == TRUE)
+    	if (((Level == FROM_TX) && (pAd->Mlme.bPsPollTimerRunning == TRUE)) ||
+			(Level == RTMP_HALT))
     	{
             pAd->Mlme.bPsPollTimerRunning = FALSE;
     		RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
-    		RTMPusecDelay(3000);
+    		RTMPusecDelay(5000);
             DBGPRINT(RT_DEBUG_TRACE, ("=======AsicForceWakeup===bFromTx\n"));
     	}
 
 		AutoWakeupCfg.word = 0;
 		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
 
-        if (RT28xxPciAsicRadioOn(pAd, DOT11POWERSAVE))
-        {
-            // In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
-        	if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
-        		&& (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
-        	{
-        		// Must using 40MHz.
-        		AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
-        		AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
-        	}
-        	else
-        	{
-        		// Must using 20MHz.
-        		AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-        		AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-        	}
-        }
+		// If this is called from Halt. ALWAYS force wakeup!!!
+		if (Level == RTMP_HALT)
+		{
+			RT28xxPciAsicRadioOn(pAd, RTMP_HALT);
+		}
+		else
+		{
+			if (RT28xxPciAsicRadioOn(pAd, DOT11POWERSAVE))
+			{
+				// In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
+				if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
+					&& (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
+				{
+					// Must using 40MHz.
+					AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+					AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+				}
+				else
+				{
+					// Must using 20MHz.
+					AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+					AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+				}
+			}
+		}
     }
     else
     {
@@ -1122,6 +1143,7 @@
     {
     	NICResetFromError(pAd);
 
+    	/*
     	RTMPRingCleanUp(pAd, QID_AC_BK);
     	RTMPRingCleanUp(pAd, QID_AC_BE);
     	RTMPRingCleanUp(pAd, QID_AC_VI);
@@ -1129,6 +1151,7 @@
     	RTMPRingCleanUp(pAd, QID_HCCA);
     	RTMPRingCleanUp(pAd, QID_MGMT);
     	RTMPRingCleanUp(pAd, QID_RX);
+		*/
 
     	// Enable Tx/Rx
     	RTMPEnableRxTx(pAd);
@@ -1162,6 +1185,12 @@
     WPDMA_GLO_CFG_STRUC	GloCfg;
 	UINT32	i;
 
+	if (pAd->StaCfg.bRadio == TRUE)
+	{
+		DBGPRINT(RT_DEBUG_TRACE,("-->MlmeRadioOff() return on bRadio == TRUE; \n"));
+		return;
+	}
+
     if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
     	return;
 
@@ -1169,13 +1198,12 @@
 
 	// Set LED
 	RTMPSetLED(pAd, LED_RADIO_OFF);
-	// Set Radio off flag
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
 
 #ifdef CONFIG_STA_SUPPORT
 	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
     {
     	BOOLEAN		Cancelled;
+
     	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
     	{
 			RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
@@ -1185,6 +1213,15 @@
 		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
         {
             BOOLEAN Cancelled;
+
+			// Always radio on since the NIC needs to set the MCU command (LED_RADIO_OFF).

+			if ((pAd->OpMode == OPMODE_STA) && 

+			     (IDLE_ON(pAd)) && 

+			     (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))

+			{

+				RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);

+			}
+
             pAd->Mlme.bPsPollTimerRunning = FALSE;
             RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
 	        RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer,	&Cancelled);
@@ -1197,9 +1234,26 @@
         //==========================================
         // Clean up old bss table
         BssTableInit(&pAd->ScanTab);
+
+		RTMPRingCleanUp(pAd, QID_AC_BK);
+    	RTMPRingCleanUp(pAd, QID_AC_BE);
+    	RTMPRingCleanUp(pAd, QID_AC_VI);
+    	RTMPRingCleanUp(pAd, QID_AC_VO);
+    	RTMPRingCleanUp(pAd, QID_HCCA);
+    	RTMPRingCleanUp(pAd, QID_MGMT);
+    	RTMPRingCleanUp(pAd, QID_RX);
+
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
+		{
+			RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 500);
+			return;
+		}
     }
 #endif // CONFIG_STA_SUPPORT //
 
+	// Set Radio off flag
+	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+
 	// Disable Tx/Rx DMA
 	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);	   // disable DMA
 	GloCfg.field.EnableTxDMA = 0;
diff --git a/drivers/staging/rt2860/common/cmm_info.c b/drivers/staging/rt2860/common/cmm_info.c
index dd92ac6..c3e1319 100644
--- a/drivers/staging/rt2860/common/cmm_info.c
+++ b/drivers/staging/rt2860/common/cmm_info.c
@@ -814,7 +814,6 @@
 	IN	PRTMP_ADAPTER	pAd,
 	IN	PUCHAR			arg)
 {
-#ifdef RT2860
 	INT i, QueIdx=0;
 	PRT28XX_RXD_STRUC pRxD;
     PTXD_STRUC pTxD;
@@ -845,7 +844,6 @@
 	    hex_dump("Rx Descriptor", (char *)pRxD, 16);
 		printk("pRxD->DDONE = %x\n", pRxD->DDONE);
 	}
-#endif // RT2860 //
 
 	return TRUE;
 }
@@ -1803,9 +1801,7 @@
 	}
 
 	// For key index and ext IV bit, so only need to update the position(offset+3).
-#ifdef RT2860
 	RTMP_IO_WRITE8(pAd, offset+3, IVEIV);
-#endif // RT2860 //
 
 	DBGPRINT(RT_DEBUG_TRACE,("RTMPAddWcidAttributeEntry: WCID #%d, KeyIndex #%d, Alg=%s\n",Wcid, KeyIdx, CipherName[CipherAlg]));
 	DBGPRINT(RT_DEBUG_TRACE,("	WCIDAttri = 0x%x \n",  WCIDAttri));
@@ -2827,9 +2823,7 @@
 
 	Value = simple_strtol(arg, 0, 10);
 
-#ifdef RT2860
 	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-#endif // RT2860 //
 	{
 		DBGPRINT(RT_DEBUG_ERROR, ("Can not switch operate mode on interface up !! \n"));
 		return FALSE;
diff --git a/drivers/staging/rt2860/common/cmm_sync.c b/drivers/staging/rt2860/common/cmm_sync.c
index 40e4109..d29e0b6 100644
--- a/drivers/staging/rt2860/common/cmm_sync.c
+++ b/drivers/staging/rt2860/common/cmm_sync.c
@@ -470,7 +470,7 @@
 		{
 		// BBP and RF are not accessible in PS mode, we has to wake them up first
 		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-			AsicForceWakeup(pAd, TRUE);
+				AsicForceWakeup(pAd, FROM_TX);
 
 			// leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON
 			if (pAd->StaCfg.Psm == PWR_SAVE)
diff --git a/drivers/staging/rt2860/common/cmm_wpa.c b/drivers/staging/rt2860/common/cmm_wpa.c
index 81c332a..69baf52 100644
--- a/drivers/staging/rt2860/common/cmm_wpa.c
+++ b/drivers/staging/rt2860/common/cmm_wpa.c
@@ -39,8 +39,10 @@
 // WPA OUI
 UCHAR		OUI_WPA_NONE_AKM[4]		= {0x00, 0x50, 0xF2, 0x00};
 UCHAR       OUI_WPA_VERSION[4]      = {0x00, 0x50, 0xF2, 0x01};
+UCHAR       OUI_WPA_WEP40[4]      = {0x00, 0x50, 0xF2, 0x01};
 UCHAR       OUI_WPA_TKIP[4]     = {0x00, 0x50, 0xF2, 0x02};
 UCHAR       OUI_WPA_CCMP[4]     = {0x00, 0x50, 0xF2, 0x04};
+UCHAR       OUI_WPA_WEP104[4]      = {0x00, 0x50, 0xF2, 0x05};
 UCHAR       OUI_WPA_8021X_AKM[4]	= {0x00, 0x50, 0xF2, 0x01};
 UCHAR       OUI_WPA_PSK_AKM[4]      = {0x00, 0x50, 0xF2, 0x02};
 // WPA2 OUI
@@ -49,6 +51,7 @@
 UCHAR       OUI_WPA2_CCMP[4]        = {0x00, 0x0F, 0xAC, 0x04};
 UCHAR       OUI_WPA2_8021X_AKM[4]   = {0x00, 0x0F, 0xAC, 0x01};
 UCHAR       OUI_WPA2_PSK_AKM[4]   	= {0x00, 0x0F, 0xAC, 0x02};
+UCHAR       OUI_WPA2_WEP104[4]   = {0x00, 0x0F, 0xAC, 0x05};
 // MSA OUI
 UCHAR   	OUI_MSA_8021X_AKM[4]    = {0x00, 0x0F, 0xAC, 0x05};		// Not yet final - IEEE 802.11s-D1.06
 UCHAR   	OUI_MSA_PSK_AKM[4]   	= {0x00, 0x0F, 0xAC, 0x06};		// Not yet final - IEEE 802.11s-D1.06
@@ -367,6 +370,24 @@
                 break;
         }
 
+#ifdef CONFIG_STA_SUPPORT
+		if ((pAd->OpMode == OPMODE_STA) &&
+			(pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
+			(pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled))
+		{
+			UINT GroupCipher = pAd->StaCfg.GroupCipher;
+			switch(GroupCipher)
+			{
+				case Ndis802_11GroupWEP40Enabled:
+					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_WEP40, 4);
+					break;
+				case Ndis802_11GroupWEP104Enabled:
+					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_WEP104, 4);
+					break;
+			}
+		}
+#endif // CONFIG_STA_SUPPORT //
+
 		// swap for big-endian platform
 		pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
 	    pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
@@ -427,11 +448,28 @@
                 break;
         }
 
+#ifdef CONFIG_STA_SUPPORT
+		if ((pAd->OpMode == OPMODE_STA) &&
+			(pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
+			(pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled))
+		{
+			UINT GroupCipher = pAd->StaCfg.GroupCipher;
+			switch(GroupCipher)
+			{
+				case Ndis802_11GroupWEP40Enabled:
+					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_WEP40, 4);
+					break;
+				case Ndis802_11GroupWEP104Enabled:
+					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_WEP104, 4);
+					break;
+			}
+		}
+#endif // CONFIG_STA_SUPPORT //
+
 		// swap for big-endian platform
 		pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
 	    pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
 	}
-
 }
 
 /*
diff --git a/drivers/staging/rt2860/common/mlme.c b/drivers/staging/rt2860/common/mlme.c
index 2297470..c00f9ab 100644
--- a/drivers/staging/rt2860/common/mlme.c
+++ b/drivers/staging/rt2860/common/mlme.c
@@ -527,7 +527,6 @@
 
 
 #ifdef CONFIG_STA_SUPPORT
-#ifdef RT2860
 		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
 		{
 	        if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
@@ -537,7 +536,6 @@
 	    		RTMPInitTimer(pAd, &pAd->Mlme.RadioOnOffTimer, GET_TIMER_FUNCTION(RadioOnExec), pAd, FALSE);
 	        }
 		}
-#endif // RT2860 //
 #endif // CONFIG_STA_SUPPORT //
 
 	} while (FALSE);
@@ -711,13 +709,11 @@
 		RTMPCancelTimer(&pAd->MlmeAux.AuthTimer,		&Cancelled);
 		RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer,		&Cancelled);
 		RTMPCancelTimer(&pAd->MlmeAux.ScanTimer,		&Cancelled);
-#ifdef RT2860
 	    if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
 	    {
 	   	    RTMPCancelTimer(&pAd->Mlme.PsPollTimer,		&Cancelled);
 		    RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer,		&Cancelled);
 		}
-#endif // RT2860 //
 
 #ifdef QOS_DLS_SUPPORT
 		for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
@@ -808,21 +804,34 @@
 	ULONG			TxTotalCnt;
 	PRTMP_ADAPTER	pAd = (RTMP_ADAPTER *)FunctionContext;
 
+	//Baron 2008/07/10
+	//printk("Baron_Test:\t%s", RTMPGetRalinkEncryModeStr(pAd->StaCfg.WepStatus));
+	//If the STA security setting is OPEN or WEP, pAd->StaCfg.WpaSupplicantUP = 0.
+	//If the STA security setting is WPAPSK or WPA2PSK, pAd->StaCfg.WpaSupplicantUP = 1.
+	if(pAd->StaCfg.WepStatus<2)
+	{
+		pAd->StaCfg.WpaSupplicantUP = 0;
+	}
+	else
+	{
+		pAd->StaCfg.WpaSupplicantUP = 1;
+	}
+
 #ifdef CONFIG_STA_SUPPORT
-#ifdef RT2860
 	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
 	{
 	    // If Hardware controlled Radio enabled, we have to check GPIO pin2 every 2 second.
 		// Move code to here, because following code will return when radio is off
-		if ((pAd->Mlme.PeriodicRound % (MLME_TASK_EXEC_MULTIPLE * 2) == 0) && (pAd->StaCfg.bHardwareRadio == TRUE) &&
+		if ((pAd->Mlme.PeriodicRound % (MLME_TASK_EXEC_MULTIPLE * 2) == 0) &&
+			(pAd->StaCfg.bHardwareRadio == TRUE) &&
+			(RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP)) &&
 			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
-			(pAd->bPCIclkOff == FALSE))
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
 		{
 			UINT32				data = 0;
 
 			// Read GPIO pin2 as Hardware controlled radio state
-			RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data);
+			RTMP_IO_FORCE_READ32(pAd, GPIO_CTRL_CFG, &data);
 			if (data & 0x04)
 			{
 				pAd->StaCfg.bHwRadio = TRUE;
@@ -849,7 +858,6 @@
 			}
 		}
 	}
-#endif // RT2860 //
 #endif // CONFIG_STA_SUPPORT //
 
 	// Do nothing if the driver is starting halt state.
@@ -860,6 +868,45 @@
 								fRTMP_ADAPTER_RESET_IN_PROGRESS))))
 		return;
 
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		if ((pAd->RalinkCounters.LastReceivedByteCount == pAd->RalinkCounters.ReceivedByteCount) && (pAd->StaCfg.bRadio == TRUE))
+		{
+			// If ReceiveByteCount doesn't change,  increase SameRxByteCount by 1.
+			pAd->SameRxByteCount++;
+		}
+		else
+			pAd->SameRxByteCount = 0;
+
+		// If after BBP, still not work...need to check to reset PBF&MAC.
+		if (pAd->SameRxByteCount == 702)
+		{
+			pAd->SameRxByteCount = 0;
+			AsicResetPBF(pAd);
+			AsicResetMAC(pAd);
+		}
+
+		// If SameRxByteCount keeps happens for 2 second in infra mode, or for 60 seconds in idle mode.
+		if (((INFRA_ON(pAd)) && (pAd->SameRxByteCount > 20)) || ((IDLE_ON(pAd)) && (pAd->SameRxByteCount > 600)))
+		{
+			if ((pAd->StaCfg.bRadio == TRUE) && (pAd->SameRxByteCount < 700))
+			{
+				DBGPRINT(RT_DEBUG_TRACE, ("--->  SameRxByteCount = %lu !!!!!!!!!!!!!!! \n", pAd->SameRxByteCount));
+				pAd->SameRxByteCount = 700;
+				AsicResetBBP(pAd);
+			}
+		}
+
+		// Update lastReceiveByteCount.
+		pAd->RalinkCounters.LastReceivedByteCount = pAd->RalinkCounters.ReceivedByteCount;
+
+		if ((pAd->CheckDmaBusyCount > 3) && (IDLE_ON(pAd)))
+		{
+			pAd->CheckDmaBusyCount = 0;
+			AsicResetFromDMABusy(pAd);
+		}
+	}
+
 	RT28XX_MLME_PRE_SANITY_CHECK(pAd);
 
 #ifdef RALINK_ATE
@@ -1022,9 +1069,7 @@
 #ifdef CONFIG_STA_SUPPORT
 		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
 		{
-#ifdef RT2860
 			if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->bPCIclkOff == FALSE))
-#endif // RT2860 //
 			{
 				// When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock
 				// and sending CTS-to-self over and over.
@@ -1081,6 +1126,19 @@
     		pAd->StaCfg.bBlockAssoc = FALSE;
     }
 
+	//Baron 2008/07/10
+	//printk("Baron_Test:\t%s", RTMPGetRalinkEncryModeStr(pAd->StaCfg.WepStatus));
+	//If the STA security setting is OPEN or WEP, pAd->StaCfg.WpaSupplicantUP = 0.
+	//If the STA security setting is WPAPSK or WPA2PSK, pAd->StaCfg.WpaSupplicantUP = 1.
+	if(pAd->StaCfg.WepStatus<2)
+	{
+		pAd->StaCfg.WpaSupplicantUP = 0;
+	}
+	else
+	{
+		pAd->StaCfg.WpaSupplicantUP = 1;
+	}
+
     if ((pAd->PreMediaState != pAd->IndicateMediaState) && (pAd->CommonCfg.bWirelessEvent))
 	{
 		if (pAd->IndicateMediaState == NdisMediaStateConnected)
@@ -1090,6 +1148,15 @@
 		pAd->PreMediaState = pAd->IndicateMediaState;
 	}
 
+	if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd)) &&
+        (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) &&
+		(pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE) &&
+		(pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
+		(RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP)) &&
+		(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
+	{
+		RT28xxPciAsicRadioOff(pAd, GUI_IDLE_POWER_SAVE, 0);
+	}
 
 
 
@@ -2781,7 +2848,7 @@
 	if (INFRA_ON(pAd) &&
 		(PowerMode != Ndis802_11PowerModeCAM) &&
 		(pAd->StaCfg.Psm == PWR_ACTIVE) &&
-		(pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE))
+		RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP))
 	{
 		NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime);
 		pAd->RalinkCounters.RxCountSinceLastNULL = 0;
@@ -4065,7 +4132,9 @@
 							continue;
 
 					// check group cipher
-					if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
+					if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) &&
+						(pInBss->WPA.GroupCipher != Ndis802_11GroupWEP40Enabled) &&
+						(pInBss->WPA.GroupCipher != Ndis802_11GroupWEP104Enabled))
 						continue;
 
 					// check pairwise cipher, skip if none matched
@@ -4084,7 +4153,9 @@
 							continue;
 
 					// check group cipher
-					if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
+					if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) &&
+						(pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP40Enabled) &&
+						(pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP104Enabled))
 						continue;
 
 					// check pairwise cipher, skip if none matched
@@ -4371,8 +4442,10 @@
 				switch (*pTmp)
 				{
 					case 1:
-					case 5:	// Although WEP is not allowed in WPA related auth mode, we parse it anyway
-						pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
+						pBss->WPA.GroupCipher = Ndis802_11GroupWEP40Enabled;
+						break;
+					case 5:
+						pBss->WPA.GroupCipher = Ndis802_11GroupWEP104Enabled;
 						break;
 					case 2:
 						pBss->WPA.GroupCipher = Ndis802_11Encryption2Enabled;
@@ -4489,8 +4562,10 @@
 				switch (pCipher->Type)
 				{
 					case 1:
-					case 5:	// Although WEP is not allowed in WPA related auth mode, we parse it anyway
-						pBss->WPA2.GroupCipher = Ndis802_11Encryption1Enabled;
+						pBss->WPA2.GroupCipher = Ndis802_11GroupWEP40Enabled;
+						break;
+					case 5:
+						pBss->WPA2.GroupCipher = Ndis802_11GroupWEP104Enabled;
 						break;
 					case 2:
 						pBss->WPA2.GroupCipher = Ndis802_11Encryption2Enabled;
@@ -4953,16 +5028,13 @@
 VOID	MlmeRestartStateMachine(
 	IN	PRTMP_ADAPTER	pAd)
 {
-#ifdef RT2860
 	MLME_QUEUE_ELEM		*Elem = NULL;
-#endif // RT2860 //
 #ifdef CONFIG_STA_SUPPORT
 	BOOLEAN				Cancelled;
 #endif // CONFIG_STA_SUPPORT //
 
 	DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n"));
 
-#ifdef RT2860
 	NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
 	if(pAd->Mlme.bRunning)
 	{
@@ -4990,7 +5062,6 @@
 			DBGPRINT_ERR(("MlmeRestartStateMachine: MlmeQueue empty\n"));
 		}
 	}
-#endif // RT2860 //
 
 #ifdef CONFIG_STA_SUPPORT
 	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
@@ -5039,12 +5110,10 @@
 	}
 #endif // CONFIG_STA_SUPPORT //
 
-#ifdef RT2860
 	// Remove running state
 	NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
 	pAd->Mlme.bRunning = FALSE;
 	NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
-#endif // RT2860 //
 }
 
 /*! \brief	test if the MLME Queue is empty
@@ -6149,6 +6218,12 @@
 	ULONG		TxPwr[5];
 	CHAR		Value;
 
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
+		|| (pAd->bPCIclkOff == TRUE)
+		|| RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)
+		|| RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+		return;
+
 	if (pAd->CommonCfg.BBPCurrentBW == BW_40)
 	{
 		if (pAd->CommonCfg.CentralChannel > 14)
@@ -6493,10 +6568,10 @@
  */
 VOID AsicForceWakeup(
 	IN PRTMP_ADAPTER pAd,
-	IN BOOLEAN    bFromTx)
+	IN UCHAR    	 Level)
 {
     DBGPRINT(RT_DEBUG_TRACE, ("--> AsicForceWakeup \n"));
-    RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx);
+    RT28XX_STA_FORCE_WAKEUP(pAd, Level);
 }
 #endif // CONFIG_STA_SUPPORT //
 /*
@@ -6710,7 +6785,6 @@
 	csr9.field.bTsfTicking = 0;
 	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
 
-#ifdef RT2860
 	// move BEACON TXD and frame content to on-chip memory
 	ptr = (PUCHAR)&pAd->BeaconTxWI;
 	for (i=0; i<TXWI_SIZE; i+=4)  // 16-byte TXWI field
@@ -6728,7 +6802,6 @@
 		RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
 		ptr +=4;
 	}
-#endif // RT2860 //
 
 	// start sending BEACON
 	csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
@@ -7097,9 +7170,7 @@
 {
 	ULONG offset; //, csr0;
 	SHAREDKEY_MODE_STRUC csr1;
-#ifdef RT2860
 	INT   i;
-#endif // RT2860 //
 
 	DBGPRINT(RT_DEBUG_TRACE, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,KeyIdx));
 //============================================================================================
@@ -7121,7 +7192,6 @@
 	//
 	// fill key material - key + TX MIC + RX MIC
 	//
-#ifdef RT2860
 	offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE;
 	for (i=0; i<MAX_LEN_OF_SHARE_KEY; i++)
 	{
@@ -7145,7 +7215,6 @@
 			RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
 		}
 	}
-#endif // RT2860 //
 
 
 	//
@@ -7320,9 +7389,7 @@
 	PUCHAR		pTxtsc = pCipherKey->TxTsc;
 	UCHAR		CipherAlg = pCipherKey->CipherAlg;
 	SHAREDKEY_MODE_STRUC csr1;
-#ifdef RT2860
 	UCHAR		i;
-#endif // RT2860 //
 
 	DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n"));
 	//
@@ -7337,7 +7404,6 @@
 	// 2.) Set Key to Asic
 	//
 	//for (i = 0; i < KeyLen; i++)
-#ifdef RT2860
 	for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++)
 	{
 		RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
@@ -7363,7 +7429,6 @@
 			RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
 		}
 	}
-#endif // RT2860 //
 
 
 	//
@@ -7372,7 +7437,6 @@
 	//
 	if (bTxKey)
 	{
-#ifdef RT2860
 		offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
 		//
 		// Write IV
@@ -7395,7 +7459,6 @@
 		{
 			RTMP_IO_WRITE8(pAd, offset + i, pTxtsc[i + 2]);
 		}
-#endif // RT2860 //
 
 		AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg, bUsePairewiseKeyTable);
 	}
@@ -7461,12 +7524,10 @@
 
 	// EKEY
 	offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
-#ifdef RT2860
 	for (i=0; i<MAX_LEN_OF_PEER_KEY; i++)
 	{
 		RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
 	}
-#endif // RT2860 //
 	for (i=0; i<MAX_LEN_OF_PEER_KEY; i+=4)
 	{
 		UINT32 Value;
@@ -7478,22 +7539,18 @@
 	//  MIC KEY
 	if (pTxMic)
 	{
-#ifdef RT2860
 		for (i=0; i<8; i++)
 		{
 			RTMP_IO_WRITE8(pAd, offset+i, pTxMic[i]);
 		}
-#endif // RT2860 //
 	}
 	offset += 8;
 	if (pRxMic)
 	{
-#ifdef RT2860
 		for (i=0; i<8; i++)
 		{
 			RTMP_IO_WRITE8(pAd, offset+i, pRxMic[i]);
 		}
-#endif // RT2860 //
 	}
 
 	DBGPRINT(RT_DEBUG_TRACE,("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n",WCID, CipherName[CipherAlg]));
@@ -7542,11 +7599,9 @@
 	HOST_CMD_CSR_STRUC	H2MCmd;
 	H2M_MAILBOX_STRUC	H2MMailbox;
 	ULONG				i = 0;
-#ifdef RT2860
 #ifdef RALINK_ATE
 	static UINT32 j = 0;
 #endif // RALINK_ATE //
-#endif // RT2860 //
 	do
 	{
 		RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
@@ -7558,7 +7613,6 @@
 
 	if (i >= 100)
 	{
-#ifdef RT2860
 #ifdef RALINK_ATE
 		if (pAd->ate.bFWLoading == TRUE)
 		{
@@ -7583,14 +7637,33 @@
 		}
 		else
 #endif // RALINK_ATE //
-#endif // RT2860 //
 		{
+			UINT32 Data;
+
+			// Reset DMA
+			RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
+			Data |= 0x2;
+			RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
+
+			// After Reset DMA, DMA index will become Zero. So Driver need to reset all ring indexs too.
+			// Reset DMA/CPU ring index
+			RTMPRingCleanUp(pAd, QID_AC_BK);
+			RTMPRingCleanUp(pAd, QID_AC_BE);
+			RTMPRingCleanUp(pAd, QID_AC_VI);
+			RTMPRingCleanUp(pAd, QID_AC_VO);
+			RTMPRingCleanUp(pAd, QID_HCCA);
+			RTMPRingCleanUp(pAd, QID_MGMT);
+			RTMPRingCleanUp(pAd, QID_RX);
+
+			// Clear Reset
+			RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
+			Data &= 0xfffffffd;
+			RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
 		DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
 		}
-		return FALSE;
+		//return FALSE;
 	}
 
-#ifdef RT2860
 #ifdef RALINK_ATE
 	else if (pAd->ate.bFWLoading == TRUE)
 	{
@@ -7600,7 +7673,6 @@
 		j = 0;
 	}
 #endif // RALINK_ATE //
-#endif // RT2860 //
 
 	H2MMailbox.field.Owner	  = 1;	   // pass ownership to MCU
 	H2MMailbox.field.CmdToken = Token;
@@ -7619,7 +7691,6 @@
 	return TRUE;
 }
 
-#ifdef RT2860
 BOOLEAN AsicCheckCommanOk(
 	IN PRTMP_ADAPTER pAd,
 	IN UCHAR		 Command)
@@ -7684,7 +7755,6 @@
 
 	return FALSE;
 }
-#endif // RT2860 //
 
 /*
 	========================================================================
@@ -8096,10 +8166,8 @@
 	}
 	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
 #ifdef CONFIG_STA_SUPPORT
-#ifdef RT2860
 	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
     	pAd->StaCfg.BBPR3 = BBPR3;
-#endif // RT2860 //
 #endif // CONFIG_STA_SUPPORT //
 	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
 		)
@@ -8211,9 +8279,7 @@
 			BBPR3 |= (0x0);
 		}
 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
-#ifdef RT2860
-    pAd->StaCfg.BBPR3 = BBPR3;
-#endif // RT2860 //
+		pAd->StaCfg.BBPR3 = BBPR3;
 	}
 
 #endif // CONFIG_STA_SUPPORT //
@@ -8439,10 +8505,7 @@
 		&& (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
 			)
 		&& !(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-#ifdef RT2860
-		&& (pAd->bPCIclkOff == FALSE)
-#endif // RT2860 //
-		)
+		&& (pAd->bPCIclkOff == FALSE))
 	{
 		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &OrigR66Value);
 		R66 = OrigR66Value;
@@ -8518,6 +8581,106 @@
 
 	}
 }
+
+VOID AsicResetFromDMABusy(
+	IN PRTMP_ADAPTER pAd)
+{
+	UINT32		Data;
+	BOOLEAN		bCtrl = FALSE;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--->  AsicResetFromDMABusy  !!!!!!!!!!!!!!!!!!!!!!! \n"));
+
+	// Be sure restore link control value so we can write register.
+	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+	if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
+	{
+		DBGPRINT(RT_DEBUG_TRACE,("AsicResetFromDMABusy==>\n"));
+		RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
+		RTMPusecDelay(6000);
+		pAd->bPCIclkOff = FALSE;
+		bCtrl = TRUE;
+	}
+	// Reset DMA
+	RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
+	Data |= 0x2;
+	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
+
+	// After Reset DMA, DMA index will become Zero. So Driver need to reset all ring indexs too.
+	// Reset DMA/CPU ring index
+	RTMPRingCleanUp(pAd, QID_AC_BK);
+	RTMPRingCleanUp(pAd, QID_AC_BE);
+	RTMPRingCleanUp(pAd, QID_AC_VI);
+	RTMPRingCleanUp(pAd, QID_AC_VO);
+	RTMPRingCleanUp(pAd, QID_HCCA);
+	RTMPRingCleanUp(pAd, QID_MGMT);
+	RTMPRingCleanUp(pAd, QID_RX);
+
+	// Clear Reset
+	RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
+	Data &= 0xfffffffd;
+	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
+
+	// If in Radio off, should call RTMPPCIePowerLinkCtrl again.
+	if ((bCtrl == TRUE) && (pAd->StaCfg.bRadio == FALSE))
+		RTMPPCIeLinkCtrlSetting(pAd, 3);
+
+	RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS);
+	DBGPRINT(RT_DEBUG_TRACE, ("<---  AsicResetFromDMABusy !!!!!!!!!!!!!!!!!!!!!!!  \n"));
+}
+
+VOID AsicResetBBP(
+	IN PRTMP_ADAPTER pAd)
+{
+	DBGPRINT(RT_DEBUG_TRACE, ("--->  Asic HardReset BBP  !!!!!!!!!!!!!!!!!!!!!!! \n"));
+
+	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
+	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x2);
+	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc);
+
+	// After hard-reset BBP, initialize all BBP values.
+	NICRestoreBBPValue(pAd);
+	DBGPRINT(RT_DEBUG_TRACE, ("<---  Asic HardReset BBP !!!!!!!!!!!!!!!!!!!!!!!  \n"));
+}
+
+VOID AsicResetMAC(
+	IN PRTMP_ADAPTER pAd)
+{
+	ULONG		Data;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--->  AsicResetMAC   !!!! \n"));
+	RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
+	Data |= 0x4;
+	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
+	Data &= 0xfffffffb;
+	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<---  AsicResetMAC   !!!! \n"));
+}
+
+VOID AsicResetPBF(
+	IN PRTMP_ADAPTER pAd)
+{
+	ULONG		Value1, Value2;
+	ULONG		Data;
+
+	RTMP_IO_READ32(pAd, TXRXQ_PCNT, &Value1);
+	RTMP_IO_READ32(pAd, PBF_DBG, &Value2);
+
+	Value2 &= 0xff;
+	// sum should be equals to 0xff, which is the total buffer size.
+	if ((Value1 + Value2) < 0xff)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("--->  Asic HardReset PBF !!!! \n"));
+		RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
+		Data |= 0x8;
+		RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
+		Data &= 0xfffffff7;
+		RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
+
+		DBGPRINT(RT_DEBUG_TRACE, ("<---  Asic HardReset PBF !!!! \n"));
+	}
+}
 #endif // CONFIG_STA_SUPPORT //
 
 VOID RTMPSetAGCInitValue(
diff --git a/drivers/staging/rt2860/common/rtmp_init.c b/drivers/staging/rt2860/common/rtmp_init.c
index 563f2c5..8a00cee3 100644
--- a/drivers/staging/rt2860/common/rtmp_init.c
+++ b/drivers/staging/rt2860/common/rtmp_init.c
@@ -149,9 +149,7 @@
 	{GF20_PROT_CFG,			0x01744004},    // set 19:18 --> Short NAV for MIMO PS
 	{GF40_PROT_CFG,			0x03F44084},
 	{MM20_PROT_CFG,			0x01744004},
-#ifdef RT2860
 	{MM40_PROT_CFG,			0x03F54084},
-#endif // RT2860 //
 	{TXOP_CTRL_CFG,			0x0000583f, /*0x0000243f*/ /*0x000024bf*/},	//Extension channel backoff.
 	{TX_RTS_CFG,			0x00092b20},
 	{EXP_ACK_TIME,			0x002400ca},	// default value
@@ -188,9 +186,7 @@
 #define FIRMWAREIMAGEV1_LENGTH	0x1000
 #define FIRMWAREIMAGEV2_LENGTH	0x1000
 
-#ifdef RT2860
 #define FIRMWARE_MINOR_VERSION	2
-#endif // RT2860 //
 
 
 /*
@@ -248,9 +244,7 @@
 
 		// Init spin locks
 		NdisAllocateSpinLock(&pAd->MgmtRingLock);
-#ifdef RT2860
 		NdisAllocateSpinLock(&pAd->RxRingLock);
-#endif // RT2860 //
 
 		for (index =0 ; index < NUM_OF_TX_RING; index++)
 		{
@@ -1555,10 +1549,7 @@
 		pAd->LedCntl.word = 0x01;
 		pAd->Led1 = 0x5555;
 		pAd->Led2 = 0x2221;
-
-#ifdef RT2860
 		pAd->Led3 = 0xA9F8;
-#endif // RT2860 //
 	}
 
 	AsicSendCommandToMcu(pAd, 0x52, 0xff, (UCHAR)pAd->Led1, (UCHAR)(pAd->Led1 >> 8));
@@ -1594,12 +1585,10 @@
 		else
 		{
 			RTMPSetLED(pAd, LED_RADIO_ON);
-#ifdef RT2860
 			AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
 			AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x00);
 			// 2-1. wait command ok.
 			AsicCheckCommanOk(pAd, PowerWakeCID);
-#endif // RT2860 //
 		}
 	}
 #endif // CONFIG_STA_SUPPORT //
@@ -1677,10 +1666,8 @@
 {
 	NDIS_STATUS     Status = NDIS_STATUS_SUCCESS;
 	WPDMA_GLO_CFG_STRUC	GloCfg;
-#ifdef RT2860
 	UINT32			Value;
 	DELAY_INT_CFG_STRUC	IntCfg;
-#endif // RT2860 //
 	ULONG	i =0, j=0;
 	AC_TXOP_CSR0_STRUC	csr0;
 
@@ -1719,11 +1706,9 @@
 
 	// asic simulation sequence put this ahead before loading firmware.
 	// pbf hardware reset
-#ifdef RT2860
 	RTMP_IO_WRITE32(pAd, WPDMA_RST_IDX, 0x1003f);	// 0x10000 for reset rx, 0x3f resets all 6 tx rings.
 	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe1f);
 	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe00);
-#endif // RT2860 //
 
 	// Initialze ASIC for TX & Rx operation
 	if (NICInitializeAsic(pAd , bHardReset) != NDIS_STATUS_SUCCESS)
@@ -1737,7 +1722,6 @@
 	}
 
 
-#ifdef RT2860
 	// Write AC_BK base address register
 	Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_BK].Cell[0].AllocPa);
 	RTMP_IO_WRITE32(pAd, TX_BASE_PTR1, Value);
@@ -1810,7 +1794,6 @@
 	// Write RX_RING_CSR register
 	Value = RX_RING_SIZE;
 	RTMP_IO_WRITE32(pAd, RX_MAX_CNT, Value);
-#endif // RT2860 //
 
 
 	// WMM parameter
@@ -1829,7 +1812,6 @@
 	RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr0.word);
 
 
-#ifdef RT2860
 	// 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits:
 	i = 0;
 	do
@@ -1848,7 +1830,6 @@
 
 	IntCfg.word = 0;
 	RTMP_IO_WRITE32(pAd, DELAY_INT_CFG, IntCfg.word);
-#endif // RT2860 //
 
 
 	// reset action
@@ -1889,7 +1870,6 @@
 
 	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAsic\n"));
 
-#ifdef RT2860
 	if (bHardReset == TRUE)
 	{
 		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3);
@@ -1914,7 +1894,6 @@
 		}
 	}
 #endif // CONFIG_STA_SUPPORT //
-#endif // RT2860 //
 
 
 	//
@@ -2041,6 +2020,131 @@
 	return NDIS_STATUS_SUCCESS;
 }
 
+
+VOID NICRestoreBBPValue(
+	IN PRTMP_ADAPTER pAd)
+{
+	UCHAR		index;
+	UCHAR		Value = 0;
+	ULONG		Data;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--->  NICRestoreBBPValue !!!!!!!!!!!!!!!!!!!!!!!  \n"));
+	// Initialize BBP register to default value (rtmp_init.c)
+	for (index = 0; index < NUM_BBP_REG_PARMS; index++)
+	{
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[index].Register, BBPRegTable[index].Value);
+	}
+	// copy from (rtmp_init.c)
+	if (pAd->MACVersion == 0x28600100)
+	{
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x12);
+	}
+
+	// copy from (connect.c LinkUp function)
+	if (INFRA_ON(pAd))
+	{
+		// Change to AP channel
+		if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
+		{
+			// Must using 40MHz.
+			pAd->CommonCfg.BBPCurrentBW = BW_40;
+			AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+			AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
+			Value &= (~0x18);
+			Value |= 0x10;
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
+
+			//  RX : control channel at lower
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
+			Value &= (~0x20);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
+			// Record BBPR3 setting, But don't keep R Antenna # information.
+			pAd->StaCfg.BBPR3 = Value;
+
+			RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
+			Data &= 0xfffffffe;
+			RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
+
+			if (pAd->MACVersion == 0x28600100)
+			{
+				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
+				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
+				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
+				DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
+			}
+
+			DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
+		}
+		else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
+		{
+			// Must using 40MHz.
+			pAd->CommonCfg.BBPCurrentBW = BW_40;
+			AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+			AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
+			Value &= (~0x18);
+			Value |= 0x10;
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
+
+			RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
+			Data |= 0x1;
+			RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
+
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
+			Value |= (0x20);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
+			// Record BBPR3 setting, But don't keep R Antenna # information.
+			pAd->StaCfg.BBPR3 = Value;
+
+			if (pAd->MACVersion == 0x28600100)
+			{
+				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
+				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
+				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
+				DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
+			}
+
+			DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
+		}
+		else
+		{
+			pAd->CommonCfg.BBPCurrentBW = BW_20;
+			AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+			AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
+			Value &= (~0x18);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
+
+			RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
+			Data &= 0xfffffffe;
+			RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
+
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
+			Value &= (~0x20);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
+			// Record BBPR3 setting, But don't keep R Antenna # information.
+			pAd->StaCfg.BBPR3 = Value;
+
+			if (pAd->MACVersion == 0x28600100)
+			{
+				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
+				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
+				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
+				DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
+			}
+
+			DBGPRINT(RT_DEBUG_TRACE, ("!!!20MHz LINK UP !!! \n" ));
+		}
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<---  NICRestoreBBPValue !!!!!!!!!!!!!!!!!!!!!!!  \n"));
+}
+
 /*
 	========================================================================
 
@@ -3028,11 +3132,10 @@
 	pAd->CommonCfg.BBPCurrentBW = BW_20;
 
 	pAd->LedCntl.word = 0;
-#ifdef RT2860
 	pAd->LedIndicatorStregth = 0;
 	pAd->RLnkCtrlOffset = 0;
 	pAd->HostLnkCtrlOffset = 0;
-#endif // RT2860 //
+	pAd->CheckDmaBusyCount = 0;
 
 	pAd->bAutoTxAgcA = FALSE;			// Default is OFF
 	pAd->bAutoTxAgcG = FALSE;			// Default is OFF
@@ -3292,9 +3395,7 @@
 	pAd->ate.bRxFer = 0;
 	pAd->ate.bQATxStart = FALSE;
 	pAd->ate.bQARxStart = FALSE;
-#ifdef RT2860
 	pAd->ate.bFWLoading = FALSE;
-#endif // RT2860 //
 #ifdef RALINK_28xx_QA
 	//pAd->ate.Repeat = 0;
 	pAd->ate.TxStatus = 0;
@@ -3304,11 +3405,9 @@
 
 
 	pAd->CommonCfg.bWiFiTest = FALSE;
-#ifdef RT2860
-    pAd->bPCIclkOff = FALSE;
-#endif // RT2860 //
+	pAd->bPCIclkOff = FALSE;
 
-
+	RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
 	DBGPRINT(RT_DEBUG_TRACE, ("<-- UserCfgInit\n"));
 }
 
diff --git a/drivers/staging/rt2860/common/spectrum.c b/drivers/staging/rt2860/common/spectrum.c
index 0265a6d..b3650ec 100644
--- a/drivers/staging/rt2860/common/spectrum.c
+++ b/drivers/staging/rt2860/common/spectrum.c
@@ -1596,7 +1596,7 @@
 
 	if ((pMeasureReportInfo = kmalloc(sizeof(MEASURE_RPI_REPORT), GFP_ATOMIC)) == NULL)
 	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%d).\n", __func__, sizeof(MEASURE_RPI_REPORT)));
+		DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%zu).\n", __func__, sizeof(MEASURE_RPI_REPORT)));
 		return;
 	}
 
diff --git a/drivers/staging/rt2860/config.mk b/drivers/staging/rt2860/config.mk
index f57d7bb..25bd55a 100644
--- a/drivers/staging/rt2860/config.mk
+++ b/drivers/staging/rt2860/config.mk
@@ -108,10 +108,6 @@
 WFLAGS += -DEXT_BUILD_CHANNEL_LIST
 endif
 
-ifeq ($(CHIPSET),2860)
-WFLAGS +=-DRT2860
-endif
-
 ifeq ($(CHIPSET),2870)
 WFLAGS +=-DRT2870
 endif
diff --git a/drivers/staging/rt2860/oid.h b/drivers/staging/rt2860/oid.h
index f2f91b6..5e6ed9f 100644
--- a/drivers/staging/rt2860/oid.h
+++ b/drivers/staging/rt2860/oid.h
@@ -544,6 +544,8 @@
     Ndis802_11Encryption3KeyAbsent,
     Ndis802_11Encryption4Enabled,	// TKIP or AES mix
     Ndis802_11Encryption4KeyAbsent,
+    Ndis802_11GroupWEP40Enabled,
+	Ndis802_11GroupWEP104Enabled,
 } NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS,
   NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS;
 
diff --git a/drivers/staging/rt2860/rt2860.h b/drivers/staging/rt2860/rt2860.h
index 0172019..4fbec90 100644
--- a/drivers/staging/rt2860/rt2860.h
+++ b/drivers/staging/rt2860/rt2860.h
@@ -46,18 +46,10 @@
 	Status = NDIS_STATUS_SUCCESS;
 
 /* function declarations */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 #define IRQ_HANDLE_TYPE  irqreturn_t
-#else
-#define IRQ_HANDLE_TYPE  void
-#endif
 
 IRQ_HANDLE_TYPE
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19))
 rt2860_interrupt(int irq, void *dev_instance);
-#else
-rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
-#endif
 
 /* ----------------- Frimware Related MACRO ----------------- */
 #define RT28XX_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen)				\
@@ -237,9 +229,7 @@
 #define RTMP_MSI_DISABLE(_pAd)
 #endif // PCI_MSI_SUPPORT //
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
 #define SA_SHIRQ IRQF_SHARED
-#endif
 
 #define RT28XX_IRQ_REQUEST(net_dev)							\
 {	PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)((net_dev)->ml_priv);	\
@@ -251,20 +241,12 @@
 		printk("RT2860: request_irq  ERROR(%d)\n", retval);	\
 	return retval; } }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 #define RT28XX_IRQ_RELEASE(net_dev)								\
 {	PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)((net_dev)->ml_priv);		\
 	POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie);			\
 	synchronize_irq(_pObj->pci_dev->irq);						\
 	free_irq(_pObj->pci_dev->irq, (net_dev));					\
 	RTMP_MSI_DISABLE(_pAd); }
-#else
-#define RT28XX_IRQ_RELEASE(net_dev)								\
-{	PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)((net_dev)->priv);		\
-	POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie);			\
-	free_irq(_pObj->pci_dev->irq, (net_dev));					\
-	RTMP_MSI_DISABLE(_pAd); }
-#endif
 
 #define RT28XX_IRQ_INIT(pAd)										\
 	{	pAd->int_enable_reg = ((DELAYINTMASK) |						\
@@ -333,8 +315,8 @@
     reg16 = cpu2le16(Configuration);                        \
     pci_write_config_word(pci_dev, offset, reg16);          \
 
-#define RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx) \
-    RT28xxPciStaAsicForceWakeup(pAd, bFromTx);
+#define RT28XX_STA_FORCE_WAKEUP(pAd, Level) \
+    RT28xxPciStaAsicForceWakeup(pAd, Level);
 
 #define RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \
     RT28xxPciStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
diff --git a/drivers/staging/rt2860/rt28xx.h b/drivers/staging/rt2860/rt28xx.h
index ff23043..e5e6f0a 100644
--- a/drivers/staging/rt2860/rt28xx.h
+++ b/drivers/staging/rt2860/rt28xx.h
@@ -1670,11 +1670,9 @@
 #define E2PROM_CSR          0x0004
 #define IO_CNTL_CSR         0x77d0
 
-#ifdef RT2860
 // 8051 firmware image for RT2860 - base address = 0x4000
 #define FIRMWARE_IMAGE_BASE     0x2000
 #define MAX_FIRMWARE_IMAGE_SIZE 0x2000    // 8kbyte
-#endif // RT2860 //
 
 
 // ================================================================
@@ -2029,7 +2027,6 @@
 //
 // Rx descriptor format, Rx	Ring
 //
-#ifdef RT2860
 #ifdef RT_BIG_ENDIAN
 typedef	struct	PACKED _RXD_STRUC	{
 	// Word 0
@@ -2098,7 +2095,6 @@
 	UINT32		Rsv1:13;
 }	RXD_STRUC, *PRXD_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
 #endif
-#endif // RT2860 //
 //
 // RXWI wireless information format, in PBF. invisible in driver.
 //
diff --git a/drivers/staging/rt2860/rt_ate.c b/drivers/staging/rt2860/rt_ate.c
index f3316ec..1ed73c9 100644
--- a/drivers/staging/rt2860/rt_ate.c
+++ b/drivers/staging/rt2860/rt_ate.c
@@ -68,7 +68,6 @@
 	IN UCHAR Mode,
 	IN UCHAR Mcs);
 
-#ifdef RT2860
 static VOID ATEWriteTxWI(
 	IN	PRTMP_ADAPTER	pAd,
 	IN	PTXWI_STRUC 	pOutTxWI,
@@ -87,7 +86,6 @@
 	IN	UCHAR			Txopmode,
 	IN	BOOLEAN			CfAck,
 	IN	HTTRANSMIT_SETTING	*pTransmit);
-#endif // RT2860 //
 
 
 static VOID SetJapanFilter(
@@ -95,7 +93,6 @@
 
 /*=========================end of prototype=========================*/
 
-#ifdef RT2860
 static INT TxDmaBusy(
 	IN PRTMP_ADAPTER pAd)
 {
@@ -153,7 +150,6 @@
 
 	return;
 }
-#endif // RT2860 //
 
 
 static VOID BbpSoftReset(
@@ -488,7 +484,6 @@
         TRUE if all parameters are OK, FALSE otherwise
     ==========================================================================
 */
-#ifdef RT2860
 static INT	ATECmdHandler(
 	IN	PRTMP_ADAPTER	pAd,
 	IN	PUCHAR			arg)
@@ -1297,7 +1292,6 @@
 
 	return TRUE;
 }
-#endif // RT2860 //
 /*                                                           */
 /*                                                           */
 /*=======================End of RT2860=======================*/
@@ -2907,7 +2901,6 @@
 		None
 	========================================================================
 */
-#ifdef RT2860
 static VOID ATEWriteTxWI(
 	IN	PRTMP_ADAPTER	pAd,
 	IN	PTXWI_STRUC 	pOutTxWI,
@@ -2972,7 +2965,6 @@
 
         return;
 }
-#endif // RT2860 //
 
 /*
 	========================================================================
@@ -3249,13 +3241,11 @@
     IN  PRTMP_ADAPTER   pAd)
 {
     ATEDBGPRINT(RT_DEBUG_TRACE, ("==> RTMPStationStart\n"));
-#ifdef RT2860
-	pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+epAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
 	//
 	// We did not cancel this timer when entering ATE mode.
 	//
 //	RTMPSetTimer(&pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
-#endif // RT2860 //
 	ATEDBGPRINT(RT_DEBUG_TRACE, ("<== RTMPStationStart\n"));
 }
 #endif // CONFIG_STA_SUPPORT //
@@ -3268,7 +3258,6 @@
 		This routine should only be used in ATE mode.
 	==========================================================================
  */
-#ifdef RT2860
 static INT ATESetUpFrame(
 	IN PRTMP_ADAPTER pAd,
 	IN UINT32 TxIdx)
@@ -3455,7 +3444,6 @@
 /*                                                           */
 /*                                                           */
 /*=======================End of RT2860=======================*/
-#endif // RT2860 //
 
 
 VOID rt_ee_read_all(PRTMP_ADAPTER pAd, USHORT *Data)
@@ -4578,9 +4566,7 @@
 						{
 							if (pAdapter->ate.TxCount == 0)
 							{
-#ifdef RT2860
 								pAdapter->ate.TxCount = 0xFFFFFFFF;
-#endif // RT2860 //
 							}
 							ATEDBGPRINT(RT_DEBUG_TRACE,("START TXFRAME\n"));
 							pAdapter->ate.bQATxStart = TRUE;
@@ -5375,7 +5361,6 @@
 
 				memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
 				value = ntohs(value);
-#ifdef RT2860
 				/* TX_FRAME_COUNT == 0 means tx infinitely */
 				if (value == 0)
 				{
@@ -5387,7 +5372,6 @@
 
 				}
 				else
-#endif // RT2860 //
 				{
 					sprintf((PCHAR)str, "%d", value);
 					Set_ATE_TX_COUNT_Proc(pAdapter, str);
diff --git a/drivers/staging/rt2860/rt_ate.h b/drivers/staging/rt2860/rt_ate.h
index 48aa70d..38f5c4a 100644
--- a/drivers/staging/rt2860/rt_ate.h
+++ b/drivers/staging/rt2860/rt_ate.h
@@ -31,12 +31,10 @@
 #ifndef UCOS
 #define ate_print printk
 #define ATEDBGPRINT DBGPRINT
-#ifdef RT2860
 #define EEPROM_SIZE								0x200
 #ifdef CONFIG_STA_SUPPORT
 #define EEPROM_BIN_FILE_NAME  "/etc/Wireless/RT2860STA/e2p.bin"
 #endif // CONFIG_STA_SUPPORT //
-#endif // RT2860 //
 
 #else // !UCOS //
 #define fATE_LOAD_EEPROM						0x0C43
@@ -69,7 +67,6 @@
 #define ATE_ON(_p)              (((_p)->ate.Mode) != ATE_STOP)
 
 /* RT2880_iNIC will define "RT2860". */
-#ifdef RT2860
 #define ATE_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)        \
 {                                                       \
     BBP_CSR_CFG_STRUC  BbpCsr;                             \
@@ -131,10 +128,8 @@
         ATEDBGPRINT(RT_DEBUG_ERROR, ("BBP write R%d fail\n", _I));     \
     }                                                   \
 }
-#endif // RT2860 //
 
 /* RT2880_iNIC will define RT2860. */
-#ifdef RT2860
 #define EEPROM_SIZE								0x200
 /* iNIC has its own EEPROM_BIN_FILE_NAME */
 #ifndef UCOS
@@ -142,7 +137,6 @@
 #define EEPROM_BIN_FILE_NAME  "/etc/Wireless/RT2860STA/e2p.bin"
 #endif // CONFIG_STA_SUPPORT //
 #endif // !UCOS //
-#endif // RT2860 //
 
 
 
diff --git a/drivers/staging/rt2860/rt_config.h b/drivers/staging/rt2860/rt_config.h
index 7ee7a40..a67024f 100644
--- a/drivers/staging/rt2860/rt_config.h
+++ b/drivers/staging/rt2860/rt_config.h
@@ -53,9 +53,7 @@
 #include    "rtmp_def.h"
 #include    "rt28xx.h"
 
-#ifdef RT2860
 #include	"rt2860.h"
-#endif // RT2860 //
 
 
 #include    "oid.h"
diff --git a/drivers/staging/rt2860/rt_linux.c b/drivers/staging/rt2860/rt_linux.c
index f1450093..f3c128c 100644
--- a/drivers/staging/rt2860/rt_linux.c
+++ b/drivers/staging/rt2860/rt_linux.c
@@ -48,10 +48,8 @@
 #endif
 BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
 BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
-#ifdef RT2860
 BUILD_TIMER_FUNCTION(PsPollWakeExec);
 BUILD_TIMER_FUNCTION(RadioOnExec);
-#endif // RT2860 //
 #ifdef QOS_DLS_SUPPORT
 BUILD_TIMER_FUNCTION(DlsTimeoutAction);
 #endif // QOS_DLS_SUPPORT //
@@ -293,9 +291,7 @@
 
 	NdisFreeSpinLock(&pAd->MgmtRingLock);
 
-#ifdef RT2860
 	NdisFreeSpinLock(&pAd->RxRingLock);
-#endif // RT2860 //
 
 	for (index =0 ; index < NUM_OF_TX_RING; index++)
 	{
@@ -854,7 +850,7 @@
 
     if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
     {
-        DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%d)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
+        DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%zu)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
 		goto err_free_sk_buff;
     }
 
@@ -1005,35 +1001,14 @@
 
 void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
 {
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 	daemonize(pThreadName /*"%s",pAd->net_dev->name*/);
 
 	allow_signal(SIGTERM);
 	allow_signal(SIGKILL);
 	current->flags |= PF_NOFREEZE;
-#else
-	unsigned long flags;
 
-	daemonize();
-	reparent_to_init();
-	strcpy(current->comm, pThreadName);
-
-	siginitsetinv(&current->blocked, sigmask(SIGTERM) | sigmask(SIGKILL));
-
-	/* Allow interception of SIGKILL only
-	 * Don't allow other signals to interrupt the transmission */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22)
-	spin_lock_irqsave(&current->sigmask_lock, flags);
-	flush_signals(current);
-	recalc_sigpending(current);
-	spin_unlock_irqrestore(&current->sigmask_lock, flags);
-#endif
-#endif
-
-    /* signal that we've started the thread */
+	/* signal that we've started the thread */
 	complete(pNotify);
-
 }
 
 void RTMP_IndicateMediaState(
diff --git a/drivers/staging/rt2860/rt_linux.h b/drivers/staging/rt2860/rt_linux.h
index 0fd58f5..708923c 100644
--- a/drivers/staging/rt2860/rt_linux.h
+++ b/drivers/staging/rt2860/rt_linux.h
@@ -65,7 +65,6 @@
 #include <linux/vmalloc.h>
 
 
-#include <linux/wireless.h>
 #include <net/iw_handler.h>
 
 // load firmware
@@ -90,28 +89,22 @@
 // add by kathy
 
 #ifdef CONFIG_STA_SUPPORT
-#ifdef RT2860
 #define STA_PROFILE_PATH			"/etc/Wireless/RT2860STA/RT2860STA.dat"
 #define STA_RTMP_FIRMWARE_FILE_NAME "/etc/Wireless/RT2860STA/RT2860STA.bin"
 #define STA_NIC_DEVICE_NAME			"RT2860STA"
-#define STA_DRIVER_VERSION			"1.8.0.0"
+#define STA_DRIVER_VERSION			"1.8.1.1"
 #ifdef MULTIPLE_CARD_SUPPORT
 #define CARD_INFO_PATH			"/etc/Wireless/RT2860STA/RT2860STACard.dat"
 #endif // MULTIPLE_CARD_SUPPORT //
-#endif // RT2860 //
 
 
 #endif // CONFIG_STA_SUPPORT //
 
-#ifdef RT2860
 #ifndef PCI_DEVICE
 #define PCI_DEVICE(vend,dev) \
 	.vendor = (vend), .device = (dev), \
 	.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
 #endif // PCI_DEVICE //
-#endif // RT2860 //
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 
 #define RTMP_TIME_AFTER(a,b)		\
 	(typecheck(unsigned long, (unsigned long)a) && \
@@ -123,11 +116,7 @@
 	 typecheck(unsigned long, (unsigned long)b) && \
 	 ((long)(a) - (long)(b) >= 0))
 #define RTMP_TIME_BEFORE(a,b)	RTMP_TIME_AFTER_EQ(b,a)
-#else
-#define RTMP_TIME_AFTER(a,b) time_after(a, b)
-#endif
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 #define RT_MOD_INC_USE_COUNT() \
 	if (!try_module_get(THIS_MODULE)) \
 	{ \
@@ -136,10 +125,6 @@
 	}
 
 #define RT_MOD_DEC_USE_COUNT() module_put(THIS_MODULE);
-#else
-#define RT_MOD_INC_USE_COUNT()	MOD_INC_USE_COUNT;
-#define RT_MOD_DEC_USE_COUNT() MOD_DEC_USE_COUNT;
-#endif
 
 #define OS_HZ			HZ
 
@@ -171,21 +156,12 @@
 #define NDIS_PACKET_TYPE_ALL_MULTICAST	3
 #endif // CONFIG_STA_SUPPORT //
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
 typedef	struct pid *	THREAD_PID;
 #define	THREAD_PID_INIT_VALUE	NULL
 #define	GET_PID(_v)	find_get_pid(_v)
 #define	GET_PID_NUMBER(_v)	pid_nr(_v)
 #define CHECK_PID_LEGALITY(_pid)	if (pid_nr(_pid) >= 0)
 #define KILL_THREAD_PID(_A, _B, _C)	kill_pid(_A, _B, _C)
-#else
-typedef	pid_t	THREAD_PID;
-#define	THREAD_PID_INIT_VALUE	-1
-#define	GET_PID(_v)	_v
-#define	GET_PID_NUMBER(_v)	_v
-#define CHECK_PID_LEGALITY(_pid)	if (_pid >= 0)
-#define KILL_THREAD_PID(_A, _B, _C)	kill_proc(_A, _B, _C)
-#endif
 
 struct os_lock  {
 	spinlock_t		lock;
@@ -194,11 +170,9 @@
 
 
 struct os_cookie {
-#ifdef RT2860
 	struct pci_dev 			*pci_dev;
 	struct pci_dev 			*parent_pci_dev;
 	dma_addr_t		  		pAd_pa;
-#endif // RT2860 //
 
 
 	struct tasklet_struct 	rx_done_task;
@@ -209,9 +183,7 @@
 	struct tasklet_struct 	ac3_dma_done_task;
 	struct tasklet_struct 	hcca_dma_done_task;
 	struct tasklet_struct	tbtt_task;
-#ifdef RT2860
 	struct tasklet_struct	fifo_statistic_full_task;
-#endif // RT2860 //
 
 
 	unsigned long			apd_pid; //802.1x daemon pid
@@ -266,7 +238,6 @@
 
 #define RT2860_PCI_DEVICE_ID		0x0601
 
-#ifdef RT2860
 #define PCI_MAP_SINGLE(_handle, _ptr, _size, _sd_idx, _dir) \
 	linux_pci_map_single(_handle, _ptr, _size, _sd_idx, _dir)
 
@@ -281,7 +252,6 @@
 
 #define DEV_ALLOC_SKB(_length) \
 	dev_alloc_skb(_length)
-#endif // RT2860 //
 
 
 
@@ -401,7 +371,6 @@
 	spin_unlock_irqrestore((spinlock_t *)(__lock), ((unsigned long)__irqflag));	\
 }
 
-#ifdef RT2860
 #if defined(INF_TWINPASS) || defined(INF_DANUBE) || defined(IKANOS_VX_1X0)
 //Patch for ASIC turst read/write bug, needs to remove after metel fix
 #define RTMP_IO_READ32(_A, _R, _pV)									\
@@ -413,6 +382,12 @@
 	(*_pV = SWAP32(*((UINT32 *)(_pV))));                           \
     }                                                                   \
 }
+#define RTMP_IO_FORCE_READ32(_A, _R, _pV)							\
+{																	\
+	(*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)));		\
+	(*_pV = readl((void *)((_A)->CSRBaseAddress + (_R))));			\
+	(*_pV = SWAP32(*((UINT32 *)(_pV))));                           \
+}
 #define RTMP_IO_READ8(_A, _R, _pV)									\
 {																	\
 	(*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)));		\
@@ -452,6 +427,11 @@
     else															\
 		*_pV = 0;													\
 }
+#define RTMP_IO_FORCE_READ32(_A, _R, _pV)							\
+{																	\
+	(*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)));		\
+	(*_pV = readl((void *)((_A)->CSRBaseAddress + (_R))));			\
+}
 #define RTMP_IO_READ8(_A, _R, _pV)								\
 {																\
 	(*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)));			\
@@ -492,7 +472,6 @@
 	writew((_V), (PUSHORT)((_A)->CSRBaseAddress + (_R)));	\
 }
 #endif
-#endif // RT2860 //
 
 
 #ifndef wait_event_interruptible_timeout
@@ -544,7 +523,6 @@
 #define MlmeAllocateMemory(_pAd, _ppVA) os_alloc_mem(_pAd, _ppVA, MGMT_DMA_BUFFER_SIZE)
 #define MlmeFreeMemory(_pAd, _pVA)     os_free_mem(_pAd, _pVA)
 
-#ifdef RT2860
 #define BUILD_TIMER_FUNCTION(_func)												\
 void linux_##_func(unsigned long data)											\
 {																				\
@@ -554,7 +532,6 @@
 	if (pTimer->Repeat)															\
 		RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue);				\
 }
-#endif // RT2860 //
 
 
 
@@ -907,7 +884,6 @@
 
 void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify);
 
-#ifdef RT2860
 #if !defined(PCI_CAP_ID_EXP)
 #define PCI_CAP_ID_EXP			    0x10
 #endif
@@ -921,6 +897,5 @@
 #endif
 
 #define PCIBUS_INTEL_VENDOR         0x8086
-#endif // RT2860 //
 
 
diff --git a/drivers/staging/rt2860/rt_main_dev.c b/drivers/staging/rt2860/rt_main_dev.c
index 3873c47..cf17bcd 100644
--- a/drivers/staging/rt2860/rt_main_dev.c
+++ b/drivers/staging/rt2860/rt_main_dev.c
@@ -58,11 +58,7 @@
 
 char *mac = "";		   // default 00:00:00:00:00:00
 char *hostname = "";		   // default CMPC
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12)
-MODULE_PARM (mac, "s");
-#else
 module_param (mac, charp, 0);
-#endif
 MODULE_PARM_DESC (mac, "rt28xx: wireless mac addr");
 
 
@@ -75,9 +71,7 @@
 #endif // DOT11_N_SUPPORT //
 extern NDIS_STATUS NICLoadRateSwitchingParams(IN PRTMP_ADAPTER pAd);
 
-#ifdef RT2860
 extern void init_thread_task(PRTMP_ADAPTER pAd);
-#endif // RT2860 //
 
 // public function prototype
 INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
@@ -87,13 +81,6 @@
 static int rt28xx_init(IN struct net_device *net_dev);
 INT rt28xx_send_packets(IN struct sk_buff *skb_p, IN struct net_device *net_dev);
 
-#if LINUX_VERSION_CODE <= 0x20402	// Red Hat 7.1
-struct net_device *alloc_netdev(
-	int sizeof_priv,
-	const char *mask,
-	void (*setup)(struct net_device *));
-#endif // LINUX_VERSION_CODE //
-
 static void CfgInitHook(PRTMP_ADAPTER pAd);
 
 #ifdef CONFIG_STA_SUPPORT
@@ -235,15 +222,13 @@
 #ifdef CONFIG_STA_SUPPORT
 	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
 	{
-#ifdef RT2860
-		RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_CLOSE);
-#endif // RT2860 //
-
 		// If dirver doesn't wake up firmware here,
 		// NICLoadFirmware will hang forever when interface is up again.
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
+			RTMP_SET_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND) ||
+			RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
         {
-		    AsicForceWakeup(pAd, TRUE);
+		    AsicForceWakeup(pAd, RTMP_HALT);
         }
 
 #ifdef QOS_DLS_SUPPORT
@@ -323,9 +308,7 @@
 #endif // WPA_SUPPLICANT_SUPPORT //
 
 		MlmeRadioOff(pAd);
-#ifdef RT2860
 		pAd->bPCIclkOff = FALSE;
-#endif // RT2860 //
 	}
 #endif // CONFIG_STA_SUPPORT //
 
@@ -359,7 +342,6 @@
 	TpcReqTabExit(pAd);
 
 
-#ifdef RT2860
 	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
 	{
 		NICDisableInterrupt(pAd);
@@ -375,7 +357,6 @@
 		RT28XX_IRQ_RELEASE(net_dev)
 		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
 	}
-#endif // RT2860 //
 
 
 	// Free Ring or USB buffers
@@ -439,12 +420,10 @@
 
 	// Disable interrupts here which is as soon as possible
 	// This statement should never be true. We might consider to remove it later
-#ifdef RT2860
 	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
 	{
 		NICDisableInterrupt(pAd);
 	}
-#endif // RT2860 //
 
 	Status = RTMPAllocTxRxRingMemory(pAd);
 	if (Status != NDIS_STATUS_SUCCESS)
@@ -667,26 +646,6 @@
 #endif // WIRELESS_EXT >= 12 //
 #endif // CONFIG_APSTA_MIXED_SUPPORT //
 
-#ifdef CONFIG_STA_SUPPORT
-#ifdef RT2860
-	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
-	{
-    	// If dirver doesn't wake up firmware here,
-    	// NICLoadFirmware will hang forever when interface is up again.
-    	// RT2860 PCI
-    	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) &&
-        	OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
-    	{
-        	AUTO_WAKEUP_STRUC AutoWakeupCfg;
-			AsicForceWakeup(pAd, TRUE);
-        	AutoWakeupCfg.word = 0;
-	    	RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
-        	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
-    	}
-	}
-#endif // RT2860 //
-#endif // CONFIG_STA_SUPPORT //
-
 	// Init
  	pObj = (POS_COOKIE)pAd->OS_Cookie;
 
@@ -753,10 +712,8 @@
 	}
 
 #ifdef CONFIG_STA_SUPPORT
-#ifdef RT2860
 	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
         RTMPInitPCIeLinkCtrlValue(pAd);
-#endif // RT2860 //
 #endif // CONFIG_STA_SUPPORT //
 
 	return (retval);
@@ -808,9 +765,7 @@
 	dev->stop = MainVirtualIF_close; //rt28xx_close;
 	dev->priv_flags = INT_MAIN;
 	dev->do_ioctl = rt28xx_ioctl;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-    dev->validate_addr = NULL;
-#endif
+	dev->validate_addr = NULL;
 	// find available device name
 	for (i = 0; i < 8; i++)
 	{
@@ -821,25 +776,11 @@
 #endif // MULTIPLE_CARD_SUPPORT //
 		sprintf(slot_name, "ra%d", i);
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
-        device = dev_get_by_name(dev_net(dev), slot_name);
-#else
-        device = dev_get_by_name(dev->nd_net, slot_name);
-#endif
-#else
-		device = dev_get_by_name(slot_name);
-#endif
-		if (device != NULL) dev_put(device);
-#else
-		for (device = dev_base; device != NULL; device = device->next)
-		{
-			if (strncmp(device->name, slot_name, 4) == 0)
-				break;
-		}
-#endif
-		if(device == NULL)
+		device = dev_get_by_name(dev_net(dev), slot_name);
+		if (device != NULL)
+			dev_put(device);
+
+		if (device == NULL)
 			break;
 	}
 
@@ -1252,47 +1193,28 @@
     PRTMP_ADAPTER       pAd = (PRTMP_ADAPTER) NULL;
     INT                 status;
 	PVOID				handle;
-#ifdef RT2860
 	struct pci_dev *dev_p = (struct pci_dev *)_dev_p;
-#endif // RT2860 //
 
 
 #ifdef CONFIG_STA_SUPPORT
     DBGPRINT(RT_DEBUG_TRACE, ("STA Driver version-%s\n", STA_DRIVER_VERSION));
 #endif // CONFIG_STA_SUPPORT //
 
-#if LINUX_VERSION_CODE <= 0x20402       // Red Hat 7.1
-    net_dev = alloc_netdev(sizeof(PRTMP_ADAPTER), "eth%d", ether_setup);
-#else
     net_dev = alloc_etherdev(sizeof(PRTMP_ADAPTER));
-#endif
     if (net_dev == NULL)
     {
         printk("alloc_netdev failed\n");
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
-		module_put(THIS_MODULE);
-#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
-#else
-		MOD_DEC_USE_COUNT;
-#endif
         goto err_out;
     }
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
-    SET_MODULE_OWNER(net_dev);
-#endif
-
 	netif_stop_queue(net_dev);
 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
 /* for supporting Network Manager */
 /* Set the sysfs physical device reference for the network logical device
  * if set prior to registration will cause a symlink during initialization.
  */
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
     SET_NETDEV_DEV(net_dev, &(dev_p->dev));
-#endif
 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
 
 	// Allocate RTMP_ADAPTER miniport adapter structure
@@ -1313,13 +1235,8 @@
 #endif // CONFIG_STA_SUPPORT //
 
 	// Post config
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	if (RT28XXProbePostConfig(_dev_p, pAd, argc) == FALSE)
-		goto err_out_unmap;
-#else
 	if (RT28XXProbePostConfig(_dev_p, pAd, 0) == FALSE)
 		goto err_out_unmap;
-#endif // LINUX_VERSION_CODE //
 
 #ifdef CONFIG_STA_SUPPORT
 	pAd->OpMode = OPMODE_STA;
@@ -1362,20 +1279,12 @@
 	RT28XX_UNMAP();
 
 err_out_free_netdev:
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-    free_netdev(net_dev);
-#else
-	kfree(net_dev);
-#endif
+	free_netdev(net_dev);
 
 err_out:
 	RT28XX_PUT_DEVICE(dev_p);
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	return (LONG)NULL;
-#else
-    return -ENODEV; /* probe fail */
-#endif // LINUX_VERSION_CODE //
+	return -ENODEV; /* probe fail */
 } /* End of rt28xx_probe */
 
 
@@ -1495,40 +1404,6 @@
 
 
 
-#if LINUX_VERSION_CODE <= 0x20402	// Red Hat 7.1
-struct net_device *alloc_netdev(
-	int sizeof_priv,
-	const char *mask,
-	void (*setup)(struct net_device *))
-{
-    struct net_device	*dev;
-    INT					alloc_size;
-
-
-    /* ensure 32-byte alignment of the private area */
-    alloc_size = sizeof (*dev) + sizeof_priv + 31;
-
-    dev = (struct net_device *) kmalloc(alloc_size, GFP_KERNEL);
-    if (dev == NULL)
-    {
-        DBGPRINT(RT_DEBUG_ERROR,
-				("alloc_netdev: Unable to allocate device memory.\n"));
-        return NULL;
-    }
-
-    memset(dev, 0, alloc_size);
-
-    if (sizeof_priv)
-        dev->priv = (void *) (((long)(dev + 1) + 31) & ~31);
-
-    setup(dev);
-    strcpy(dev->name, mask);
-
-    return dev;
-}
-#endif // LINUX_VERSION_CODE //
-
-
 void CfgInitHook(PRTMP_ADAPTER pAd)
 {
 	pAd->bBroadComHT = TRUE;
diff --git a/drivers/staging/rt2860/rt_profile.c b/drivers/staging/rt2860/rt_profile.c
index 326a3cb..62141f3 100644
--- a/drivers/staging/rt2860/rt_profile.c
+++ b/drivers/staging/rt2860/rt_profile.c
@@ -1451,7 +1451,7 @@
 					IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
 					{
 						//PSMode
-						if (RTMPGetKeyParameter("PSMode", tmpbuf, 10, buffer))
+						if (RTMPGetKeyParameter("PSMode", tmpbuf, 32, buffer))
 						{
 							if (pAd->StaCfg.BssType == BSS_INFRA)
 							{
diff --git a/drivers/staging/rt2860/rtmp.h b/drivers/staging/rt2860/rtmp.h
index 4119542..b904b78 100644
--- a/drivers/staging/rt2860/rtmp.h
+++ b/drivers/staging/rt2860/rtmp.h
@@ -203,9 +203,7 @@
 	BOOLEAN	bRxFer;
 	BOOLEAN	bQATxStart; // Have compiled QA in and use it to ATE tx.
 	BOOLEAN	bQARxStart;	// Have compiled QA in and use it to ATE rx.
-#ifdef RT2860
 	BOOLEAN	bFWLoading;	// Reload firmware when ATE is done.
-#endif // RT2860 //
 	UINT32	RxTotalCnt;
 	UINT32	RxCntPerSec;
 
@@ -366,6 +364,13 @@
 #define RTMP_TEST_FLAG(_M, _F)      (((_M)->Flags & (_F)) != 0)
 #define RTMP_TEST_FLAGS(_M, _F)     (((_M)->Flags & (_F)) == (_F))
 
+// Macro for power save flag.
+#define RTMP_SET_PSFLAG(_M, _F)       ((_M)->PSFlags |= (_F))
+#define RTMP_CLEAR_PSFLAG(_M, _F)     ((_M)->PSFlags &= ~(_F))
+#define RTMP_CLEAR_PSFLAGS(_M)        ((_M)->PSFlags = 0)
+#define RTMP_TEST_PSFLAG(_M, _F)      (((_M)->PSFlags & (_F)) != 0)
+#define RTMP_TEST_PSFLAGS(_M, _F)     (((_M)->PSFlags & (_F)) == (_F))
+
 #define OPSTATUS_SET_FLAG(_pAd, _F)     ((_pAd)->CommonCfg.OpStatusFlags |= (_F))
 #define OPSTATUS_CLEAR_FLAG(_pAd, _F)   ((_pAd)->CommonCfg.OpStatusFlags &= ~(_F))
 #define OPSTATUS_TEST_FLAG(_pAd, _F)    (((_pAd)->CommonCfg.OpStatusFlags & (_F)) != 0)
@@ -478,7 +483,6 @@
 //
 #define MAX_BUSY_COUNT  100         // Number of retry before failing access BBP & RF indirect register
 //
-#ifdef RT2860
 #define RTMP_RF_IO_WRITE32(_A, _V)                  \
 {                                                   \
     PHY_CSR4_STRUC  Value;                          \
@@ -642,7 +646,6 @@
     }                                                   \
     }                                                   \
 }
-#endif // RT2860 //
 
 
 #define     MAP_CHANNEL_ID_TO_KHZ(ch, khz)  {               \
@@ -894,7 +897,6 @@
 // Enqueue this frame to MLME engine
 // We need to enqueue the whole frame because MLME need to pass data type
 // information from 802.11 header
-#ifdef RT2860
 #define REPORT_MGMT_FRAME_TO_MLME(_pAd, Wcid, _pFrame, _FrameSize, _Rssi0, _Rssi1, _Rssi2, _PlcpSignal)        \
 {                                                                                       \
     UINT32 High32TSF, Low32TSF;                                                          \
@@ -902,7 +904,6 @@
     RTMP_IO_READ32(_pAd, TSF_TIMER_DW0, &Low32TSF);                                        \
     MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (UCHAR)_Rssi0, (UCHAR)_Rssi1,(UCHAR)_Rssi2,_FrameSize, _pFrame, (UCHAR)_PlcpSignal);   \
 }
-#endif // RT2860 //
 
 #define NDIS_QUERY_BUFFER(_NdisBuf, _ppVA, _pBufLen)                    \
     NdisQueryBuffer(_NdisBuf, _ppVA, _pBufLen)
@@ -919,9 +920,10 @@
 #define STA_PORT_SECURED(_pAd) \
 { \
 	_pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; \
-	NdisAcquireSpinLock(&_pAd->MacTabLock); \
+	RTMP_SET_PSFLAG(_pAd, fRTMP_PS_CAN_GO_SLEEP); \
+	NdisAcquireSpinLock(&(_pAd)->MacTabLock); \
 	_pAd->MacTab.Content[BSSID_WCID].PortSecured = _pAd->StaCfg.PortSecured; \
-	NdisReleaseSpinLock(&_pAd->MacTabLock); \
+	NdisReleaseSpinLock(&(_pAd)->MacTabLock); \
 }
 #endif // CONFIG_STA_SUPPORT //
 
@@ -1000,9 +1002,7 @@
 	UCHAR 		DataOffset;
 	USHORT 		Datasize;
 	ULONG                   AllocSize;
-#ifdef RT2860
 	NDIS_PHYSICAL_ADDRESS   AllocPa;            // TxBuf physical address
-#endif // RT2860 //
 }   RTMP_REORDERBUF, *PRTMP_REORDERBUF;
 
 //
@@ -1101,6 +1101,7 @@
 
 typedef struct _COUNTER_RALINK {
 	ULONG           TransmittedByteCount;   // both successful and failure, used to calculate TX throughput
+	ULONG           LastReceivedByteCount;
 	ULONG           ReceivedByteCount;      // both CRC okay and CRC error, used to calculate RX throughput
 	ULONG           BeenDisassociatedCount;
 	ULONG           BadCQIAutoRecoveryCount;
@@ -1436,11 +1437,9 @@
 	RALINK_TIMER_STRUCT     APSDPeriodicTimer;
 	RALINK_TIMER_STRUCT     LinkDownTimer;
 	RALINK_TIMER_STRUCT     LinkUpTimer;
-#ifdef RT2860
     UCHAR                   bPsPollTimerRunning;
     RALINK_TIMER_STRUCT     PsPollTimer;
 	RALINK_TIMER_STRUCT     RadioOnOffTimer;
-#endif // RT2860 //
 	ULONG                   PeriodicRound;
 	ULONG                   OneSecPeriodicRound;
 
@@ -2228,9 +2227,7 @@
 	RT_HT_PHY_INFO					DesiredHtPhyInfo;
 	BOOLEAN							bAutoTxRateSwitch;
 
-#ifdef RT2860
     UCHAR       BBPR3;
-#endif // RT2860 //
 
 #ifdef EXT_BUILD_CHANNEL_LIST
 	UCHAR				IEEE80211dClientMode;
@@ -2663,7 +2660,6 @@
 	PNET_DEV				net_dev;
 	ULONG					VirtualIfCnt;
 
-#ifdef RT2860
     USHORT		            LnkCtrlBitMask;
     USHORT		            RLnkCtrlConfiguration;
     USHORT                  RLnkCtrlOffset;
@@ -2671,7 +2667,9 @@
     USHORT                  HostLnkCtrlOffset;
 	USHORT		            PCIePowerSaveLevel;
    	BOOLEAN					bPCIclkOff;						// flag that indicate if the PICE power status in Configuration SPace..
-	BOOLEAN					bPCIclkOffDisableTx;			//
+   	ULONG					CheckDmaBusyCount;  // Check Interrupt Status Register Count.
+   	USHORT					ThisTbttNumToNextWakeUp;
+	ULONG					SameRxByteCount;
 
 
 /*****************************************************************************************/
@@ -2688,7 +2686,6 @@
 	RTMP_DMABUF             RxDescRing;                 // Shared memory for RX descriptors
 	RTMP_DMABUF             TxDescRing[NUM_OF_TX_RING]; 	// Shared memory for Tx descriptors
 	RTMP_TX_RING            TxRing[NUM_OF_TX_RING];     	// AC0~4 + HCCA
-#endif // RT2860 //
 
 
 	NDIS_SPIN_LOCK          irq_lock;
@@ -2721,10 +2718,8 @@
 /*      Rx related parameters                                                           */
 /*****************************************************************************************/
 
-#ifdef RT2860
 	RTMP_RX_RING            RxRing;
 	NDIS_SPIN_LOCK          RxRingLock;                 // Rx Ring spinlock
-#endif // RT2860 //
 
 
 
@@ -2895,6 +2890,7 @@
 
 	// flags, see fRTMP_ADAPTER_xxx flags
 	ULONG                   Flags;                      // Represent current device status
+	ULONG                   PSFlags;                    // Power Save operation flag.
 
 	// current TX sequence #
 	USHORT                  Sequence;
@@ -3181,7 +3177,6 @@
 //------------------------------------------------------------------------------------------
 
 
-#ifdef RT2860
 //
 // Enable & Disable NIC interrupt via writing interrupt mask register
 // Since it use ADAPTER structure, it have to be put after structure definition.
@@ -3214,7 +3209,6 @@
 	//RTMP_IO_WRITE32(pAd, PBF_INT_ENA, 0x00000030); // 1 : enable
 	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
 }
-#endif // RT2860 //
 
 #ifdef RT_BIG_ENDIAN
 static inline VOID	WriteBackToDescriptor(
@@ -3291,7 +3285,6 @@
 		Call this function when read or update descriptor
 	========================================================================
 */
-#ifdef RT2860
 static inline VOID	RTMPDescriptorEndianChange(
 	IN	PUCHAR			pData,
 	IN	ULONG			DescriptorType)
@@ -3301,7 +3294,6 @@
 	*((UINT32 *)(pData +12)) = SWAP32(*((UINT32 *)(pData + 12)));	// Byte 12~15
 	*((UINT32 *)(pData + 4)) = SWAP32(*((UINT32 *)(pData + 4)));				// Byte 4~7, this must be swapped last
 }
-#endif // RT2860 //
 
 /*
 	========================================================================
@@ -3550,6 +3542,9 @@
 	IN  PRTMP_ADAPTER   pAd,
 	IN  BOOLEAN		bHardReset);
 
+VOID NICRestoreBBPValue(
+	IN PRTMP_ADAPTER pAd);
+
 VOID NICIssueReset(
 	IN  PRTMP_ADAPTER   pAd);
 
@@ -4208,7 +4203,7 @@
 
 VOID AsicForceWakeup(
 	IN PRTMP_ADAPTER pAd,
-	IN BOOLEAN    bFromTx);
+	IN UCHAR    	 Level);
 #endif // CONFIG_STA_SUPPORT //
 
 VOID AsicSetBssid(
@@ -4304,11 +4299,9 @@
 	IN UCHAR         Arg0,
 	IN UCHAR         Arg1);
 
-#ifdef RT2860
 BOOLEAN AsicCheckCommanOk(
 	IN PRTMP_ADAPTER pAd,
 	IN UCHAR		 Command);
-#endif // RT2860 //
 
 VOID MacAddrRandomBssid(
 	IN  PRTMP_ADAPTER   pAd,
@@ -6978,7 +6971,6 @@
 
 void tbtt_tasklet(unsigned long data);
 
-#ifdef RT2860
 //
 // Function Prototype in cmm_data_2860.c
 //
@@ -7069,7 +7061,7 @@
 
 VOID RT28xxPciStaAsicForceWakeup(
 	IN PRTMP_ADAPTER pAd,
-	IN BOOLEAN       bFromTx);
+	IN UCHAR    	 Level);
 
 VOID RT28xxPciStaAsicSleepThenAutoWakeup(
 	IN PRTMP_ADAPTER pAd,
@@ -7093,7 +7085,6 @@
 
 VOID RT28xxPciMlmeRadioOFF(
 	IN PRTMP_ADAPTER pAd);
-#endif // RT2860 //
 
 VOID AsicTurnOffRFClk(
 	IN PRTMP_ADAPTER    pAd,
@@ -7132,6 +7123,18 @@
 #ifdef CONFIG_STA_SUPPORT
 VOID AsicStaBbpTuning(
 	IN PRTMP_ADAPTER pAd);
+
+VOID AsicResetFromDMABusy(
+	IN PRTMP_ADAPTER pAd);
+
+VOID AsicResetBBP(
+	IN PRTMP_ADAPTER pAd);
+
+VOID AsicResetMAC(
+	IN PRTMP_ADAPTER pAd);
+
+VOID AsicResetPBF(
+	IN PRTMP_ADAPTER pAd);
 #endif // CONFIG_STA_SUPPORT //
 
 void RTMP_IndicateMediaState(
diff --git a/drivers/staging/rt2860/rtmp_def.h b/drivers/staging/rt2860/rtmp_def.h
index be98214..25a53d8 100644
--- a/drivers/staging/rt2860/rtmp_def.h
+++ b/drivers/staging/rt2860/rtmp_def.h
@@ -111,7 +111,6 @@
 // Entry number for each DMA descriptor ring
 //
 
-#ifdef RT2860
 #define TX_RING_SIZE            64 //64
 #define MGMT_RING_SIZE          128
 #define RX_RING_SIZE            128 //64
@@ -119,7 +118,6 @@
 #define MAX_DMA_DONE_PROCESS    TX_RING_SIZE
 #define MAX_TX_DONE_PROCESS     TX_RING_SIZE //8
 #define LOCAL_TXBUF_SIZE        2
-#endif // RT2860 //
 
 
 #ifdef MULTIPLE_CARD_SUPPORT
@@ -212,6 +210,19 @@
 #define fOP_STATUS_WAKEUP_NOW               0x00008000
 #define fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE       0x00020000
 
+//
+//  RTMP_ADAPTER PSFlags : related to advanced power save.
+//
+// Indicate whether driver can go to sleep mode from now. This flag is useful AFTER link up
+#define fRTMP_PS_CAN_GO_SLEEP          0x00000001
+// Indicate whether driver has issue a LinkControl command to PCIe L1
+#define fRTMP_PS_SET_PCI_CLK_OFF_COMMAND          0x00000002
+// Indicate driver should disable kick off hardware to send packets from now.
+#define fRTMP_PS_DISABLE_TX         0x00000004
+// Indicate driver should IMMEDIATELY fo to sleep after receiving AP's beacon in which  doesn't indicate unicate nor multicast packets for me
+//. This flag is used ONLY in RTMPHandleRxDoneInterrupt routine.
+#define fRTMP_PS_GO_TO_SLEEP_NOW         0x00000008
+
 #ifdef DOT11N_DRAFT3
 #define fOP_STATUS_SCAN_2040               	    0x00040000
 #endif // DOT11N_DRAFT3 //
@@ -1514,12 +1525,14 @@
 #define MCAST_HTMIX		3
 #endif // MCAST_RATE_SPECIFIC //
 
-// For AsicRadioOff/AsicRadioOn function
-#define DOT11POWERSAVE		0
-#define GUIRADIO_OFF		1
-#define RTMP_HALT		    2
-#define GUI_IDLE_POWER_SAVE		3
-// --
+// For AsicRadioOff/AsicRadioOn/AsicForceWakeup function
+// This is to indicate from where to call this function.
+#define DOT11POWERSAVE		0	// TO do .11 power save sleep
+#define GUIRADIO_OFF		1	// To perform Radio OFf command from GUI
+#define RTMP_HALT			2	// Called from Halt handler.
+#define GUI_IDLE_POWER_SAVE	3	// Call to sleep before link up with AP
+#define FROM_TX				4	// Force wake up from Tx packet.
+
 
 
 // definition for WpaSupport flag
diff --git a/drivers/staging/rt2860/sta/assoc.c b/drivers/staging/rt2860/sta/assoc.c
index 42db753..34f1c14 100644
--- a/drivers/staging/rt2860/sta/assoc.c
+++ b/drivers/staging/rt2860/sta/assoc.c
@@ -473,12 +473,7 @@
 				RSNIe = IE_WPA2;
 			}
 
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-#ifdef SIOCSIWGENIE
-			if (pAd->StaCfg.WpaSupplicantUP != 1)
-#endif // SIOCSIWGENIE //
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
-            	RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
+            RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
 
             // Check for WPA PMK cache list
 			if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
@@ -504,17 +499,6 @@
 				}
 			}
 
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-#ifdef SIOCSIWGENIE
-			if (pAd->StaCfg.WpaSupplicantUP == 1)
-			{
-				MakeOutgoingFrame(pOutBuffer + FrameLen,    		&tmp,
-		                        	pAd->StaCfg.RSNIE_Len,			pAd->StaCfg.RSN_IE,
-		                        	END_OF_ARGS);
-			}
-			else
-#endif
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
 			{
 				MakeOutgoingFrame(pOutBuffer + FrameLen,    		&tmp,
 				              		1,                              &RSNIe,
@@ -525,11 +509,6 @@
 
 			FrameLen += tmp;
 
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-#ifdef SIOCSIWGENIE
-			if (pAd->StaCfg.WpaSupplicantUP != 1)
-#endif
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
 			{
 	            // Append Variable IE
 	            NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &RSNIe, 1);
diff --git a/drivers/staging/rt2860/sta/connect.c b/drivers/staging/rt2860/sta/connect.c
index 36f28f8..d8bcc766 100644
--- a/drivers/staging/rt2860/sta/connect.c
+++ b/drivers/staging/rt2860/sta/connect.c
@@ -337,6 +337,10 @@
 	MLME_DISASSOC_REQ_STRUCT   DisassocReq;
 	ULONG					   Now;
 
+	// BBP and RF are not accessible in PS mode, we has to wake them up first
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+		AsicForceWakeup(pAd, RTMP_HALT);
+
 	// Step 1. record the desired user settings to MlmeAux
 	NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
 	NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
@@ -1240,6 +1244,13 @@
 	UCHAR	Value = 0, idx;
 	MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
 
+	if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
+	{
+		RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
+		RTMPusecDelay(6000);
+		pAd->bPCIclkOff = FALSE;
+	}
+
 	pEntry = &pAd->MacTab.Content[BSSID_WCID];
 
 	//
@@ -1264,7 +1275,6 @@
 	//rt2860b. Don't know why need this
 	SwitchBetweenWepAndCkip(pAd);
 
-#ifdef RT2860
 	// Before power save before link up function, We will force use 1R.
 	// So after link up, check Rx antenna # again.
 	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
@@ -1282,7 +1292,6 @@
 	}
 	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
 	pAd->StaCfg.BBPR3 = Value;
-#endif // RT2860 //
 
 	if (BssType == BSS_ADHOC)
 	{
@@ -1330,9 +1339,7 @@
 		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
 		Value &= (~0x20);
 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
-#ifdef RT2860
         pAd->StaCfg.BBPR3 = Value;
-#endif // RT2860 //
 
 		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
 		Data &= 0xfffffffe;
@@ -1367,9 +1374,7 @@
 		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
 	    Value |= (0x20);
 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
-#ifdef RT2860
         pAd->StaCfg.BBPR3 = Value;
-#endif // RT2860 //
 
 		if (pAd->MACVersion == 0x28600100)
 		{
@@ -1400,9 +1405,7 @@
 		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
 		Value &= (~0x20);
 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
-#ifdef RT2860
         pAd->StaCfg.BBPR3 = Value;
-#endif // RT2860 //
 
 		if (pAd->MACVersion == 0x28600100)
 		{
@@ -1598,6 +1601,8 @@
 			IV = 0;
 			IV |= (pAd->StaCfg.DefaultKeyId << 30);
 			AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
+
+			RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
 		}
 		// NOTE:
 		// the decision of using "short slot time" or not may change dynamically due to
@@ -1919,6 +1924,7 @@
 	}
 
 	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
 
 #ifdef DOT11_N_SUPPORT
 #ifdef DOT11N_DRAFT3
@@ -1961,6 +1967,7 @@
 	IN  BOOLEAN      IsReqFromAP)
 {
 	UCHAR			    i, ByteValue = 0;
+	BOOLEAN		Cancelled;
 
 	// Do nothing if monitor mode is on
 	if (MONITOR_ON(pAd))
@@ -1972,6 +1979,12 @@
 		return;
 #endif // RALINK_ATE //
 
+	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
+	RTMPCancelTimer(&pAd->Mlme.PsPollTimer,		&Cancelled);
+
+	// Not allow go to sleep within linkdown function.
+	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+
     if (pAd->CommonCfg.bWirelessEvent)
 	{
 		RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
@@ -1980,7 +1993,6 @@
 	DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
 	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
 
-#ifdef RT2860
     if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
     {
 	    BOOLEAN Cancelled;
@@ -1988,17 +2000,15 @@
         RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
     }
 
-    if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+    if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
+		RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND) ||
+		RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
     {
-        AUTO_WAKEUP_STRUC AutoWakeupCfg;
-		AsicForceWakeup(pAd, TRUE);
-        AutoWakeupCfg.word = 0;
-	    RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+		AsicForceWakeup(pAd, RTMP_HALT);
         OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
     }
 
     pAd->bPCIclkOff = FALSE;
-#endif // RT2860 //
 	if (ADHOC_ON(pAd))		// Adhoc mode link down
 	{
 		DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
@@ -2266,6 +2276,9 @@
 	RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
 	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
 
+	// Allow go to sleep after linkdown steps.
+	RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+
 #ifdef WPA_SUPPLICANT_SUPPORT
 #ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
 	if (pAd->StaCfg.WpaSupplicantUP) {
@@ -2510,7 +2523,6 @@
 
 	==========================================================================
  */
-#ifdef RT2860
 VOID ComposePsPoll(
 	IN PRTMP_ADAPTER pAd)
 {
@@ -2534,7 +2546,6 @@
 	COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
 	COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
 }
-#endif // RT2860 //
 
 
 
diff --git a/drivers/staging/rt2860/sta/dls.c b/drivers/staging/rt2860/sta/dls.c
index 78fb289..873cf7f 100644
--- a/drivers/staging/rt2860/sta/dls.c
+++ b/drivers/staging/rt2860/sta/dls.c
@@ -1419,7 +1419,6 @@
 				//AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE);	// reserve 0 for multicast, 1 for unicast
 				//AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
 				// Add Pair-wise key to Asic
-#ifdef RT2860
             	AsicAddPairwiseKeyEntry(pAd,
 										pAd->StaCfg.DLSEntry[i].MacAddr,
 										(UCHAR)pAd->StaCfg.DLSEntry[i].MacTabMatchWCID,
@@ -1431,7 +1430,6 @@
 										  PairwiseKey.CipherAlg,
 										  pEntry);
 
-#endif // RT2860 //
 				NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
 				DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Peer STA MAC Address STAKey) \n"));
 
@@ -1477,7 +1475,6 @@
 				//AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE);	// reserve 0 for multicast, 1 for unicast
 				//AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
 				// Add Pair-wise key to Asic
-#ifdef RT2860
             	AsicAddPairwiseKeyEntry(pAd,
 										pAd->StaCfg.DLSEntry[i].MacAddr,
 										(UCHAR)pAd->StaCfg.DLSEntry[i].MacTabMatchWCID,
@@ -1488,7 +1485,6 @@
 										  0,
 										  PairwiseKey.CipherAlg,
 										  pEntry);
-#endif // RT2860 //
 				NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
 				DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Initiator STA MAC Address STAKey)\n"));
 
diff --git a/drivers/staging/rt2860/sta/rtmp_data.c b/drivers/staging/rt2860/sta/rtmp_data.c
index 36aff24..c5e76a2 100644
--- a/drivers/staging/rt2860/sta/rtmp_data.c
+++ b/drivers/staging/rt2860/sta/rtmp_data.c
@@ -75,7 +75,6 @@
 
                     if (pAd->StaCfg.DesireSharedKey[idx].KeyLen > 0)
     				{
-#ifdef RT2860
 						MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[BSSID_WCID];
 
 						// Set key material and cipherAlg to Asic
@@ -89,7 +88,6 @@
 
                         pAd->IndicateMediaState = NdisMediaStateConnected;
                         pAd->ExtraInfo = GENERAL_LINK_UP;
-#endif // RT2860 //
 						// For Preventing ShardKey Table is cleared by remove key procedure.
     					pAd->SharedKey[BSS0][idx].CipherAlg = CipherAlg;
 						pAd->SharedKey[BSS0][idx].KeyLen = pAd->StaCfg.DesireSharedKey[idx].KeyLen;
@@ -693,14 +691,12 @@
 			break;
 		}
 
-#ifdef RT2860
 		if (RxProcessed++ > MAX_RX_PROCESS_CNT)
 		{
 			// need to reschedule rx handle
 			bReschedule = TRUE;
 			break;
 		}
-#endif // RT2860 //
 
 		RxProcessed ++; // test
 
@@ -811,6 +807,13 @@
 		}
 	}
 
+	// fRTMP_PS_GO_TO_SLEEP_NOW is set if receiving beacon.
+	if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW) && (INFRA_ON(pAd)))
+	{
+		RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
+		AsicSleepThenAutoWakeup(pAd, pAd->ThisTbttNumToNextWakeUp);
+		bReschedule = FALSE;
+	}
 	return bReschedule;
 }
 
@@ -828,7 +831,7 @@
 VOID	RTMPHandleTwakeupInterrupt(
 	IN PRTMP_ADAPTER pAd)
 {
-	AsicForceWakeup(pAd, FALSE);
+	AsicForceWakeup(pAd, DOT11POWERSAVE);
 }
 
 /*
@@ -1220,7 +1223,6 @@
 
 	========================================================================
 */
-#ifdef RT2860
 NDIS_STATUS RTMPFreeTXDRequest(
 	IN		PRTMP_ADAPTER	pAd,
 	IN		UCHAR			QueIdx,
@@ -1264,7 +1266,6 @@
 
 	return (Status);
 }
-#endif // RT2860 //
 
 
 
@@ -1889,7 +1890,8 @@
 		//
 		// Kick out Tx
 		//
-		HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+		if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
+			HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
 
 		pAd->RalinkCounters.KickTxCount++;
 		pAd->RalinkCounters.OneSecTxDoneCount++;
@@ -2019,7 +2021,8 @@
 	//
 	// Kick out Tx
 	//
-	HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
+		HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
 }
 #endif // DOT11_N_SUPPORT //
 
@@ -2139,7 +2142,8 @@
 	//
 	// Kick out Tx
 	//
-	HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
+		HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
 }
 
 
@@ -2249,7 +2253,8 @@
 	//
 	// Kick out Tx
 	//
-	HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
+		HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
 
 }
 
@@ -2526,7 +2531,7 @@
 	if ((pAd->StaCfg.Psm == PWR_SAVE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
 	{
 	    DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicForceWakeup At HardTx\n"));
-		AsicForceWakeup(pAd, TRUE);
+		AsicForceWakeup(pAd, FROM_TX);
 	}
 
 	// It should not change PSM bit, when APSD turn on.
diff --git a/drivers/staging/rt2860/sta/sync.c b/drivers/staging/rt2860/sta/sync.c
index d196f85..148037a 100644
--- a/drivers/staging/rt2860/sta/sync.c
+++ b/drivers/staging/rt2860/sta/sync.c
@@ -228,7 +228,6 @@
 	// Increase the scan retry counters.
 	pAd->StaCfg.ScanCnt++;
 
-#ifdef RT2860
     if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) &&
         (IDLE_ON(pAd)) &&
 		(pAd->StaCfg.bRadio == TRUE) &&
@@ -236,7 +235,6 @@
 	{
 		RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
 	}
-#endif // RT2860 //
 
 	// first check the parameter sanity
 	if (MlmeScanReqSanity(pAd,
@@ -349,7 +347,6 @@
 
 	DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo->BssIdx));
 
-#ifdef RT2860
     if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) &&
         (IDLE_ON(pAd)) &&
 		(pAd->StaCfg.bRadio == TRUE) &&
@@ -357,7 +354,6 @@
 	{
 		RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
 	}
-#endif // RT2860 //
 
 	// reset all the timers
 	RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
@@ -1532,13 +1528,10 @@
 				//  5. otherwise, put PHY back to sleep to save battery.
 				if (MessageToMe)
 				{
-#ifdef RT2860
 					if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
 					{
 						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
-						// Turn clk to 80Mhz.
 					}
-#endif // RT2860 //
 					if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable &&
 						pAd->CommonCfg.bAPSDAC_BE && pAd->CommonCfg.bAPSDAC_BK && pAd->CommonCfg.bAPSDAC_VI && pAd->CommonCfg.bAPSDAC_VO)
 					{
@@ -1549,12 +1542,10 @@
 				}
 				else if (BcastFlag && (DtimCount == 0) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM))
 				{
-#ifdef RT2860
 					if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
 					{
 						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
 					}
-#endif // RT2860 //
 				}
 				else if ((pAd->TxSwQueue[QID_AC_BK].Number != 0)													||
 						(pAd->TxSwQueue[QID_AC_BE].Number != 0)														||
@@ -1568,12 +1559,10 @@
 				{
 					// TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme
 					// can we cheat here (i.e. just check MGMT & AC_BE) for better performance?
-#ifdef RT2860
 					if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
 					{
 						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
 					}
-#endif // RT2860 //
 				}
 				else
 				{
@@ -1588,7 +1577,10 @@
 
 					if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
 					{
-						AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
+						// Set a flag to go to sleep . Then after parse this RxDoneInterrupt, will go to sleep mode.
+						RTMP_SET_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
+						pAd->ThisTbttNumToNextWakeUp = TbttNumToNextWakeUp;
+						//AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
 					}
 				}
 			}
diff --git a/drivers/staging/rt2860/sta/wpa.c b/drivers/staging/rt2860/sta/wpa.c
index 774c656..2609d84 100644
--- a/drivers/staging/rt2860/sta/wpa.c
+++ b/drivers/staging/rt2860/sta/wpa.c
@@ -1384,6 +1384,10 @@
 			pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
 		else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
 			pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
+		else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled)
+			pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP64;
+		else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
+			pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP128;
 
     	//hex_dump("Group Key :", pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, LEN_TKIP_EK);
 	}
@@ -1760,7 +1764,7 @@
 	// Get GTK length - refer to IEEE 802.11i-2004 p.82
 	GTKLEN = pKDE->Len -6;
 
-	if (GTKLEN < LEN_AES_KEY)
+	if (GTKLEN < MIN_LEN_OF_GTK)
 	{
 		DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN));
         return FALSE;
@@ -1786,6 +1790,10 @@
 		pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
 	else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
 		pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
+	else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled)
+		pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP64;
+	else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
+		pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP128;
 
 	return TRUE;
 
diff --git a/drivers/staging/rt2860/sta_ioctl.c b/drivers/staging/rt2860/sta_ioctl.c
index 3ea2b2c..c5452f1 100644
--- a/drivers/staging/rt2860/sta_ioctl.c
+++ b/drivers/staging/rt2860/sta_ioctl.c
@@ -49,15 +49,9 @@
 
 #define GROUP_KEY_NO                4
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
 #define IWE_STREAM_ADD_EVENT(_A, _B, _C, _D, _E)		iwe_stream_add_event(_A, _B, _C, _D, _E)
 #define IWE_STREAM_ADD_POINT(_A, _B, _C, _D, _E)		iwe_stream_add_point(_A, _B, _C, _D, _E)
 #define IWE_STREAM_ADD_VALUE(_A, _B, _C, _D, _E, _F)	iwe_stream_add_value(_A, _B, _C, _D, _E, _F)
-#else
-#define IWE_STREAM_ADD_EVENT(_A, _B, _C, _D, _E)		iwe_stream_add_event(_B, _C, _D, _E)
-#define IWE_STREAM_ADD_POINT(_A, _B, _C, _D, _E)		iwe_stream_add_point(_B, _C, _D, _E)
-#define IWE_STREAM_ADD_VALUE(_A, _B, _C, _D, _E, _F)	iwe_stream_add_value(_B, _C, _D, _E, _F)
-#endif
 
 extern UCHAR    CipherWpa2Template[];
 extern UCHAR    CipherWpaPskTkip[];
@@ -358,6 +352,20 @@
 
     DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey ------>\n"));
 
+	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+	if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
+	{
+		if (pAd->StaCfg.bRadio == FALSE)
+		{
+			RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+			return;
+		}
+		DBGPRINT(RT_DEBUG_TRACE,("RTMPWPAAddKeyProc1==>\n"));
+		RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
+		RTMPusecDelay(6000);
+		pAd->bPCIclkOff = FALSE;
+	}
+
 	if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
 	{
 		if (pKey->KeyIndex & 0x80000000)
@@ -551,6 +559,8 @@
 		}
 	}
 end:
+	RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+    DBGPRINT(RT_DEBUG_INFO, ("<------ RTMPAddKey\n"));
 	return;
 }
 
@@ -573,9 +583,7 @@
 {
 //	PRTMP_ADAPTER pAdapter = dev->ml_priv;
 
-#ifdef RT2860
     strncpy(name, "RT2860 Wireless", IFNAMSIZ);
-#endif // RT2860 //
 	return 0;
 }
 
@@ -670,11 +678,9 @@
 		case IW_MODE_INFRA:
 			Set_NetworkType_Proc(pAdapter, "Infra");
 			break;
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
         case IW_MODE_MONITOR:
 			Set_NetworkType_Proc(pAdapter, "Monitor");
 			break;
-#endif
 		default:
 			DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_siwmode::SIOCSIWMODE (unknown %d)\n", *mode));
 			return -EINVAL;
@@ -715,12 +721,10 @@
 		*mode = IW_MODE_ADHOC;
     else if (INFRA_ON(pAdapter))
 		*mode = IW_MODE_INFRA;
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
     else if (MONITOR_ON(pAdapter))
     {
         *mode = IW_MODE_MONITOR;
     }
-#endif
     else
         *mode = IW_MODE_AUTO;
 
@@ -1038,6 +1042,15 @@
         return -EINVAL;
     }
 
+	if ((pAdapter->OpMode == OPMODE_STA) && (IDLE_ON(pAdapter))
+		&& (pAdapter->StaCfg.bRadio == TRUE)
+		&& (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
+	{
+		RT28xxPciAsicRadioOn(pAdapter, GUI_IDLE_POWER_SAVE);
+	}
+	// Check if still radio off.
+	else if (pAdapter->bPCIclkOff == TRUE)
+		return 0;
 
 #ifdef WPA_SUPPLICANT_SUPPORT
 	if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
@@ -1756,7 +1769,7 @@
             }
         else
 			/* Don't complain if only change the mode */
-			if(!erq->flags & IW_ENCODE_MODE) {
+			if (!(erq->flags & IW_ENCODE_MODE)) {
 				return -EINVAL;
 		}
 	}
@@ -2161,12 +2174,6 @@
             wrq->length = strlen(extra) + 1; // 1: size of '\0'
             break;
         case RAIO_ON:
-            if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-            {
-                sprintf(extra, "Scanning\n");
-                wrq->length = strlen(extra) + 1; // 1: size of '\0'
-                break;
-            }
             pAd->StaCfg.bSwRadio = TRUE;
             //if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
             {
@@ -2450,6 +2457,20 @@
     IN  BOOLEAN         bGTK,
     IN  struct iw_encode_ext *ext)
 {
+	RTMP_CLEAR_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP);
+	if (RTMP_TEST_PSFLAG(pAdapter, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
+	{
+		if (pAdapter->StaCfg.bRadio == FALSE)
+		{
+			RTMP_SET_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP);
+			return;
+		}
+		DBGPRINT(RT_DEBUG_TRACE,("RTMPWPAAddKeyProc1==>\n"));
+		RTMPPCIeLinkCtrlValueRestore(pAdapter, RESTORE_HALT);
+		RTMPusecDelay(6000);
+		pAdapter->bPCIclkOff = FALSE;
+	}
+
     NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
     pAdapter->SharedKey[BSS0][keyIdx].KeyLen = LEN_TKIP_EK;
     NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, LEN_TKIP_EK);
@@ -2480,6 +2501,8 @@
     							  keyIdx,
     							  pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
     							  &pAdapter->MacTab.Content[BSSID_WCID]);
+
+	RTMP_SET_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP);
 }
 
 int rt_ioctl_siwencodeext(struct net_device *dev,
@@ -2544,6 +2567,21 @@
 
                 NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,  16);
 			    NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, ext->key_len);
+
+				if (pAdapter->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled ||
+					pAdapter->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
+				{
+					// Set Group key material to Asic
+					AsicAddSharedKeyEntry(pAdapter, BSS0, keyIdx, pAdapter->SharedKey[BSS0][keyIdx].CipherAlg, pAdapter->SharedKey[BSS0][keyIdx].Key, NULL, NULL);
+
+					// Update WCID attribute table and IVEIV table for this group key table
+					RTMPAddWcidAttributeEntry(pAdapter, BSS0, keyIdx, pAdapter->SharedKey[BSS0][keyIdx].CipherAlg, NULL);
+
+					STA_PORT_SECURED(pAdapter);
+
+    				// Indicate Connected for GUI
+    				pAdapter->IndicateMediaState = NdisMediaStateConnected;
+				}
     			break;
             case IW_ENCODE_ALG_TKIP:
                 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_TKIP - keyIdx = %d, ext->key_len = %d\n", __func__, keyIdx, ext->key_len));
@@ -4259,7 +4297,23 @@
                     }
 
 #ifdef WPA_SUPPLICANT_SUPPORT
-                    if (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)
+					if ((pAdapter->StaCfg.WpaSupplicantUP != 0) &&
+						(pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
+					{
+						Key = pWepKey->KeyMaterial;
+
+						// Set Group key material to Asic
+    					AsicAddSharedKeyEntry(pAdapter, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
+
+						// Update WCID attribute table and IVEIV table for this group key table
+						RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, NULL);
+
+						STA_PORT_SECURED(pAdapter);
+
+        				// Indicate Connected for GUI
+        				pAdapter->IndicateMediaState = NdisMediaStateConnected;
+					}
+                    else if (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)
 #endif // WPA_SUPPLICANT_SUPPORT
                     {
                         Key = pAdapter->SharedKey[BSS0][KeyIdx].Key;
@@ -5265,7 +5319,6 @@
 		case RT_OID_802_11_PRODUCTID:
 			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRODUCTID \n"));
 
-#ifdef RT2860
 			{
 
 				USHORT  device_id;
@@ -5275,7 +5328,6 @@
 					DBGPRINT(RT_DEBUG_TRACE, (" pci_dev = NULL\n"));
 				sprintf(tmp, "%04x %04x\n", NIC_PCI_VENDOR_ID, device_id);
 			}
-#endif // RT2860 //
 			wrq->u.data.length = strlen(tmp);
 			Status = copy_to_user(wrq->u.data.pointer, tmp, wrq->u.data.length);
 			break;
diff --git a/drivers/staging/rt2860/wpa.h b/drivers/staging/rt2860/wpa.h
index 88c7c8b..0134ae6 100644
--- a/drivers/staging/rt2860/wpa.h
+++ b/drivers/staging/rt2860/wpa.h
@@ -90,6 +90,7 @@
 #define TKIP_AP_RXMICK_OFFSET		(TKIP_AP_TXMICK_OFFSET+LEN_TKIP_TXMICK)
 #define TKIP_GTK_LENGTH				((LEN_TKIP_EK)+(LEN_TKIP_RXMICK)+(LEN_TKIP_TXMICK))
 #define LEN_PTK						((LEN_EAP_KEY)+(LEN_TKIP_KEY))
+#define MIN_LEN_OF_GTK				5
 
 // RSN IE Length definition
 #define MAX_LEN_OF_RSNIE         	90
diff --git a/drivers/staging/rt2870/2870_main_dev.c b/drivers/staging/rt2870/2870_main_dev.c
index 04c764d..9d59e31 100644
--- a/drivers/staging/rt2870/2870_main_dev.c
+++ b/drivers/staging/rt2870/2870_main_dev.c
@@ -265,7 +265,7 @@
 	 */
 	DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__));
 
-	pObj->MLMEThr_pid = THREAD_PID_INIT_VALUE;
+	pObj->MLMEThr_task = NULL;
 
 	complete_and_exit (&pAd->mlmeComplete, 0);
 	return 0;
@@ -373,7 +373,7 @@
 	 */
 	DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n"));
 
-	pObj->RTUSBCmdThr_pid = THREAD_PID_INIT_VALUE;
+	pObj->RTUSBCmdThr_task = NULL;
 
 	complete_and_exit (&pAd->CmdQComplete, 0);
 	return 0;
@@ -467,7 +467,7 @@
 	 */
 	DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__));
 
-	pObj->TimerQThr_pid = THREAD_PID_INIT_VALUE;
+	pObj->TimerQThr_task = NULL;
 
 	complete_and_exit(&pAd->TimerQComplete, 0);
 	return 0;
@@ -944,69 +944,46 @@
 	RTUSBCancelPendingIRPs(pAd);
 
 	// Terminate Threads
-	CHECK_PID_LEGALITY(pObj->TimerQThr_pid)
+	BUG_ON(pObj->TimerQThr_task == NULL);
+	CHECK_PID_LEGALITY(task_pid(pObj->TimerQThr_task))
 	{
 		POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
 
-		printk("Terminate the TimerQThr_pid=%d!\n", GET_PID_NUMBER(pObj->TimerQThr_pid));
+		printk(KERN_DEBUG "Terminate the TimerQThr pid=%d!\n",
+			pid_nr(task_pid(pObj->TimerQThr_task)));
 		mb();
 		pAd->TimerFunc_kill = 1;
 		mb();
-		ret = KILL_THREAD_PID(pObj->TimerQThr_pid, SIGTERM, 1);
-		if (ret)
-		{
-			printk(KERN_WARNING "%s: unable to stop TimerQThread, pid=%d, ret=%d!\n",
-					pAd->net_dev->name, GET_PID_NUMBER(pObj->TimerQThr_pid), ret);
-		}
-		else
-		{
-			wait_for_completion(&pAd->TimerQComplete);
-			pObj->TimerQThr_pid = THREAD_PID_INIT_VALUE;
-		}
+		kthread_stop(pObj->TimerQThr_task);
+		pObj->TimerQThr_task = NULL;
 	}
 
-	CHECK_PID_LEGALITY(pObj->MLMEThr_pid)
+	BUG_ON(pObj->MLMEThr_task == NULL);
+	CHECK_PID_LEGALITY(task_pid(pObj->MLMEThr_task))
 	{
-		printk("Terminate the MLMEThr_pid=%d!\n", GET_PID_NUMBER(pObj->MLMEThr_pid));
+		printk(KERN_DEBUG "Terminate the MLMEThr pid=%d!\n",
+			pid_nr(task_pid(pObj->MLMEThr_task)));
 		mb();
 		pAd->mlme_kill = 1;
 		//RT28XX_MLME_HANDLER(pAd);
 		mb();
-		ret = KILL_THREAD_PID(pObj->MLMEThr_pid, SIGTERM, 1);
-		if (ret)
-		{
-			printk (KERN_WARNING "%s: unable to Mlme thread, pid=%d, ret=%d!\n",
-					pAd->net_dev->name, GET_PID_NUMBER(pObj->MLMEThr_pid), ret);
-		}
-		else
-		{
-			//wait_for_completion (&pAd->notify);
-			wait_for_completion (&pAd->mlmeComplete);
-			pObj->MLMEThr_pid = THREAD_PID_INIT_VALUE;
-		}
+		kthread_stop(pObj->MLMEThr_task);
+		pObj->MLMEThr_task = NULL;
 	}
 
-	CHECK_PID_LEGALITY(pObj->RTUSBCmdThr_pid)
+	BUG_ON(pObj->RTUSBCmdThr_task == NULL);
+	CHECK_PID_LEGALITY(task_pid(pObj->RTUSBCmdThr_task))
 	{
-		printk("Terminate the RTUSBCmdThr_pid=%d!\n", GET_PID_NUMBER(pObj->RTUSBCmdThr_pid));
+		printk(KERN_DEBUG "Terminate the RTUSBCmdThr pid=%d!\n",
+			pid_nr(task_pid(pObj->RTUSBCmdThr_task)));
 		mb();
 		NdisAcquireSpinLock(&pAd->CmdQLock);
 		pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
 		NdisReleaseSpinLock(&pAd->CmdQLock);
 		mb();
 		//RTUSBCMDUp(pAd);
-		ret = KILL_THREAD_PID(pObj->RTUSBCmdThr_pid, SIGTERM, 1);
-		if (ret)
-		{
-			printk(KERN_WARNING "%s: unable to RTUSBCmd thread, pid=%d, ret=%d!\n",
-					pAd->net_dev->name, GET_PID_NUMBER(pObj->RTUSBCmdThr_pid), ret);
-		}
-		else
-		{
-			//wait_for_completion (&pAd->notify);
-			wait_for_completion (&pAd->CmdQComplete);
-			pObj->RTUSBCmdThr_pid = THREAD_PID_INIT_VALUE;
-	}
+		kthread_stop(pObj->RTUSBCmdThr_task);
+		pObj->RTUSBCmdThr_task = NULL;
 	}
 
 
@@ -1067,7 +1044,7 @@
 		if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor &&
 			dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct)
 		{
-			printk("rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
+			printk(KERN_DEBUG "rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
 					dev_p->descriptor.idVendor, dev_p->descriptor.idProduct);
 			break;
 		}
diff --git a/drivers/staging/rt2870/TODO b/drivers/staging/rt2870/TODO
index eae1ac4..2df1bfe 100644
--- a/drivers/staging/rt2870/TODO
+++ b/drivers/staging/rt2870/TODO
@@ -1,7 +1,14 @@
+I'm hesitant to add a TODO file here, as the wireless developers would
+really have people help them out on the "clean" rt2870 driver that can
+be found at the http://rt2x00.serialmonkey.com/ site.
+
+But, if you wish to clean up this driver instead, here's a short list of
+things that need to be done to get it into a more mergable shape:
+
 TODO:
 	- checkpatch.pl clean
 	- sparse clean
-	- port to in-kernel 80211 stack
+	- port to in-kernel 80211 stack and common rt2x00 infrastructure
 	- remove reading from /etc/ config files
 	- review by the wireless developer community
 
diff --git a/drivers/staging/rt2870/common/2870_rtmp_init.c b/drivers/staging/rt2870/common/2870_rtmp_init.c
index 9f5143b..cb16d2f 100644
--- a/drivers/staging/rt2870/common/2870_rtmp_init.c
+++ b/drivers/staging/rt2870/common/2870_rtmp_init.c
@@ -727,8 +727,8 @@
 
 	usb_dev = pObj->pUsb_Dev;
 
-	pObj->MLMEThr_pid		= THREAD_PID_INIT_VALUE;
-	pObj->RTUSBCmdThr_pid	= THREAD_PID_INIT_VALUE;
+	pObj->MLMEThr_task		= NULL;
+	pObj->RTUSBCmdThr_task	= NULL;
 
 	*ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER));
 
@@ -765,7 +765,7 @@
 {
 	PRTMP_ADAPTER pAd = net_dev->ml_priv;
 	POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
-	pid_t pid_number = -1;
+	struct task_struct *tsk;
 
 	//init_MUTEX(&(pAd->usbdev_semaphore));
 
@@ -779,36 +779,39 @@
 	init_completion (&pAd->TimerQComplete);
 
 	// Creat MLME Thread
-	pObj->MLMEThr_pid= THREAD_PID_INIT_VALUE;
-	pid_number = kernel_thread(MlmeThread, pAd, CLONE_VM);
-	if (pid_number < 0)
-	{
+	pObj->MLMEThr_task = NULL;
+	tsk = kthread_run(MlmeThread, pAd, pAd->net_dev->name);
+
+	if (IS_ERR(tsk)) {
 		printk (KERN_WARNING "%s: unable to start Mlme thread\n",pAd->net_dev->name);
 		return NDIS_STATUS_FAILURE;
 	}
-	pObj->MLMEThr_pid = GET_PID(pid_number);
+
+	pObj->MLMEThr_task = tsk;
 	// Wait for the thread to start
 	wait_for_completion(&(pAd->mlmeComplete));
 
 	// Creat Command Thread
-	pObj->RTUSBCmdThr_pid= THREAD_PID_INIT_VALUE;
-	pid_number = kernel_thread(RTUSBCmdThread, pAd, CLONE_VM);
-	if (pid_number < 0)
+	pObj->RTUSBCmdThr_task = NULL;
+	tsk = kthread_run(RTUSBCmdThread, pAd, pAd->net_dev->name);
+
+	if (IS_ERR(tsk) < 0)
 	{
 		printk (KERN_WARNING "%s: unable to start RTUSBCmd thread\n",pAd->net_dev->name);
 		return NDIS_STATUS_FAILURE;
 	}
-	pObj->RTUSBCmdThr_pid = GET_PID(pid_number);
+
+	pObj->RTUSBCmdThr_task = tsk;
 	wait_for_completion(&(pAd->CmdQComplete));
 
-	pObj->TimerQThr_pid= THREAD_PID_INIT_VALUE;
-	pid_number = kernel_thread(TimerQThread, pAd, CLONE_VM);
-	if (pid_number < 0)
+	pObj->TimerQThr_task = NULL;
+	tsk = kthread_run(TimerQThread, pAd, pAd->net_dev->name);
+	if (IS_ERR(tsk) < 0)
 	{
 		printk (KERN_WARNING "%s: unable to start TimerQThread\n",pAd->net_dev->name);
 		return NDIS_STATUS_FAILURE;
 	}
-	pObj->TimerQThr_pid = GET_PID(pid_number);
+	pObj->TimerQThr_task = tsk;
 	// Wait for the thread to start
 	wait_for_completion(&(pAd->TimerQComplete));
 
diff --git a/drivers/staging/rt2870/common/cmm_data.c b/drivers/staging/rt2870/common/cmm_data.c
index fd809ab..f8e0ebd 100644
--- a/drivers/staging/rt2870/common/cmm_data.c
+++ b/drivers/staging/rt2870/common/cmm_data.c
@@ -709,9 +709,6 @@
 	}
 
 	return TRUE;
-
-FillTxBlkErr:
-	return FALSE;
 }
 
 
diff --git a/drivers/staging/rt2870/common/rtmp_init.c b/drivers/staging/rt2870/common/rtmp_init.c
index 870a00da..099b6a8 100644
--- a/drivers/staging/rt2870/common/rtmp_init.c
+++ b/drivers/staging/rt2870/common/rtmp_init.c
@@ -3655,7 +3655,7 @@
 #ifdef RALINK_28xx_QA
 	//pAd->ate.Repeat = 0;
 	pAd->ate.TxStatus = 0;
-	pAd->ate.AtePid = THREAD_PID_INIT_VALUE;
+	pAd->ate.AtePid = NULL;
 #endif // RALINK_28xx_QA //
 #endif // RALINK_ATE //
 
diff --git a/drivers/staging/rt2870/common/rtusb_io.c b/drivers/staging/rt2870/common/rtusb_io.c
index 6db443e..afde136 100644
--- a/drivers/staging/rt2870/common/rtusb_io.c
+++ b/drivers/staging/rt2870/common/rtusb_io.c
@@ -958,7 +958,8 @@
 	POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
 
 
-	CHECK_PID_LEGALITY(pObj->RTUSBCmdThr_pid)
+	BUG_ON(pObj->RTUSBCmdThr_task == NULL);
+	CHECK_PID_LEGALITY(task_pid(pObj->RTUSBCmdThr_task))
 		return (NDIS_STATUS_RESOURCES);
 
 	status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt));
diff --git a/drivers/staging/rt2870/common/spectrum.c b/drivers/staging/rt2870/common/spectrum.c
index 43782ce..7438095 100644
--- a/drivers/staging/rt2870/common/spectrum.c
+++ b/drivers/staging/rt2870/common/spectrum.c
@@ -1595,7 +1595,7 @@
 
 	if ((pMeasureReportInfo = kmalloc(sizeof(MEASURE_RPI_REPORT), GFP_ATOMIC)) == NULL)
 	{
-		DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%d).\n", __func__, sizeof(MEASURE_RPI_REPORT)));
+		DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%zu).\n", __func__, sizeof(MEASURE_RPI_REPORT)));
 		return;
 	}
 
diff --git a/drivers/staging/rt2870/rt2870.h b/drivers/staging/rt2870/rt2870.h
index 30af4b5..5dd15aa 100644
--- a/drivers/staging/rt2870/rt2870.h
+++ b/drivers/staging/rt2870/rt2870.h
@@ -86,6 +86,7 @@
 #define RT2870_USB_DEVICES	\
 {	\
 	{USB_DEVICE(0x148F,0x2770)}, /* Ralink */		\
+	{USB_DEVICE(0x1737,0x0071)}, /* Linksys WUSB600N */	\
 	{USB_DEVICE(0x148F,0x2870)}, /* Ralink */		\
 	{USB_DEVICE(0x148F,0x3070)}, /* Ralink */		\
 	{USB_DEVICE(0x0B05,0x1731)}, /* Asus */			\
@@ -576,14 +577,16 @@
 #define RTUSBMlmeUp(pAd)	        \
 {								    \
 	POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;	\
-	CHECK_PID_LEGALITY(pObj->MLMEThr_pid)		    \
+	BUG_ON(pObj->MLMEThr_task == NULL);		    \
+	CHECK_PID_LEGALITY(task_pid(pObj->MLMEThr_task))		    \
         up(&(pAd->mlme_semaphore)); \
 }
 
 #define RTUSBCMDUp(pAd)	                \
 {									    \
 	POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;	\
-	CHECK_PID_LEGALITY(pObj->RTUSBCmdThr_pid)	    \
+	BUG_ON(pObj->RTUSBCmdThr_task == NULL);	    \
+	CHECK_PID_LEGALITY(task_pid(pObj->RTUSBCmdThr_task))	    \
 	    up(&(pAd->RTUSBCmd_semaphore)); \
 }
 
diff --git a/drivers/staging/rt2870/rt_linux.c b/drivers/staging/rt2870/rt_linux.c
index 992e3d1..e38552c 100644
--- a/drivers/staging/rt2870/rt_linux.c
+++ b/drivers/staging/rt2870/rt_linux.c
@@ -895,7 +895,7 @@
 
     if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
     {
-        DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%d)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
+        DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%zu)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
 		goto err_free_sk_buff;
     }
 
diff --git a/drivers/staging/rt2870/rt_linux.h b/drivers/staging/rt2870/rt_linux.h
index 859f9ce..5a6ee6a 100644
--- a/drivers/staging/rt2870/rt_linux.h
+++ b/drivers/staging/rt2870/rt_linux.h
@@ -44,6 +44,7 @@
 #include <linux/module.h>
 #include <linux/version.h>
 #include <linux/kernel.h>
+#include <linux/kthread.h>
 
 #include <linux/spinlock.h>
 #include <linux/init.h>
@@ -65,7 +66,6 @@
 #include <linux/vmalloc.h>
 
 
-#include <linux/wireless.h>
 #include <net/iw_handler.h>
 
 // load firmware
@@ -166,14 +166,12 @@
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
 typedef	struct pid *	THREAD_PID;
-#define	THREAD_PID_INIT_VALUE	NULL
 #define	GET_PID(_v)	find_get_pid(_v)
 #define	GET_PID_NUMBER(_v)	pid_nr(_v)
 #define CHECK_PID_LEGALITY(_pid)	if (pid_nr(_pid) >= 0)
 #define KILL_THREAD_PID(_A, _B, _C)	kill_pid(_A, _B, _C)
 #else
 typedef	pid_t	THREAD_PID;
-#define	THREAD_PID_INIT_VALUE	-1
 #define	GET_PID(_v)	_v
 #define	GET_PID_NUMBER(_v)	_v
 #define CHECK_PID_LEGALITY(_pid)	if (_pid >= 0)
@@ -189,11 +187,11 @@
 struct os_cookie {
 
 #ifdef RT2870
-	struct usb_device		*pUsb_Dev;
+	struct usb_device	*pUsb_Dev;
 
-	THREAD_PID				MLMEThr_pid;
-	THREAD_PID				RTUSBCmdThr_pid;
-	THREAD_PID				TimerQThr_pid;
+	struct task_struct	*MLMEThr_task;
+	struct task_struct	*RTUSBCmdThr_task;
+	struct task_struct	*TimerQThr_task;
 #endif // RT2870 //
 
 	struct tasklet_struct 	rx_done_task;
diff --git a/drivers/staging/rt2870/sta_ioctl.c b/drivers/staging/rt2870/sta_ioctl.c
index 91f0fab..4b432ce 100644
--- a/drivers/staging/rt2870/sta_ioctl.c
+++ b/drivers/staging/rt2870/sta_ioctl.c
@@ -1776,7 +1776,7 @@
             }
         else
 			/* Don't complain if only change the mode */
-			if(!erq->flags & IW_ENCODE_MODE) {
+			if (!(erq->flags & IW_ENCODE_MODE)) {
 				return -EINVAL;
 		}
 	}
diff --git a/drivers/staging/rt3070/2870_main_dev.c b/drivers/staging/rt3070/2870_main_dev.c
new file mode 100644
index 0000000..401ddb0
--- /dev/null
+++ b/drivers/staging/rt3070/2870_main_dev.c
@@ -0,0 +1,1627 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+    rtmp_main.c
+
+    Abstract:
+    main initialization routines
+
+    Revision History:
+    Who         When            What
+    --------    ----------      ----------------------------------------------
+    Name        Date            Modification logs
+    Jan Lee		01-10-2005	    modified
+	Sample		Jun/01/07		Merge RT2870 and RT2860 drivers.
+*/
+
+#include "rt_config.h"
+
+
+// Following information will be show when you run 'modinfo'
+// *** If you have a solution for the bug in current version of driver, please mail to me.
+// Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. ***
+MODULE_AUTHOR("Paul Lin <paul_lin@ralinktech.com>");
+MODULE_DESCRIPTION("RT2870 Wireless Lan Linux Driver");
+#ifdef CONFIG_STA_SUPPORT
+MODULE_LICENSE("GPL");
+#ifdef MODULE_VERSION
+MODULE_VERSION(STA_DRIVER_VERSION);
+#endif
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef MULTIPLE_CARD_SUPPORT
+// record whether the card in the card list is used in the card file
+extern UINT8  MC_CardUsed[];
+#endif // MULTIPLE_CARD_SUPPORT //
+
+/* Kernel thread and vars, which handles packets that are completed. Only
+ * packets that have a "complete" function are sent here. This way, the
+ * completion is run out of kernel context, and doesn't block the rest of
+ * the stack. */
+//static int mlme_kill = 0;		// Mlme kernel thread
+//static int RTUSBCmd_kill = 0;	// Command kernel thread
+//static int TimerFunc_kill = 0;	// TimerQ kernel thread
+
+//static wait_queue_head_t 	timerWaitQ;
+//static wait_queue_t 		waitQ;
+
+extern INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
+									IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
+
+
+/* module table */
+struct usb_device_id    rtusb_usb_id[] = RT2870_USB_DEVICES;
+INT const               rtusb_usb_id_len = sizeof(rtusb_usb_id) / sizeof(struct usb_device_id);
+MODULE_DEVICE_TABLE(usb, rtusb_usb_id);
+
+#ifndef PF_NOFREEZE
+#define PF_NOFREEZE  0
+#endif
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+
+/**************************************************************************/
+/**************************************************************************/
+//tested for kernel 2.4 series
+/**************************************************************************/
+/**************************************************************************/
+static void *rtusb_probe(struct usb_device *dev, UINT interface,
+						const struct usb_device_id *id_table);
+static void rtusb_disconnect(struct usb_device *dev, void *ptr);
+
+struct usb_driver rtusb_driver = {
+		name:"rt2870",
+		probe:rtusb_probe,
+		disconnect:rtusb_disconnect,
+		id_table:rtusb_usb_id,
+	};
+
+#else
+
+#ifdef CONFIG_PM
+static int rt2870_suspend(struct usb_interface *intf, pm_message_t state);
+static int rt2870_resume(struct usb_interface *intf);
+#endif // CONFIG_PM //
+
+/**************************************************************************/
+/**************************************************************************/
+//tested for kernel 2.6series
+/**************************************************************************/
+/**************************************************************************/
+static int rtusb_probe (struct usb_interface *intf,
+						const struct usb_device_id *id);
+static void rtusb_disconnect(struct usb_interface *intf);
+
+struct usb_driver rtusb_driver = {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
+	.owner = THIS_MODULE,
+#endif
+	.name="rt2870",
+	.probe=rtusb_probe,
+	.disconnect=rtusb_disconnect,
+	.id_table=rtusb_usb_id,
+
+#ifdef CONFIG_PM
+	suspend:	rt2870_suspend,
+	resume:		rt2870_resume,
+#endif
+	};
+
+#ifdef CONFIG_PM
+
+VOID RT2860RejectPendingPackets(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	// clear PS packets
+	// clear TxSw packets
+}
+
+static int rt2870_suspend(
+	struct usb_interface *intf,
+	pm_message_t state)
+{
+	struct net_device *net_dev;
+	PRTMP_ADAPTER pAd = usb_get_intfdata(intf);
+
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_suspend()\n"));
+	net_dev = pAd->net_dev;
+			netif_device_detach(net_dev);
+
+	pAd->PM_FlgSuspend = 1;
+	if (netif_running(net_dev)) {
+		RTUSBCancelPendingBulkInIRP(pAd);
+		RTUSBCancelPendingBulkOutIRP(pAd);
+	}
+	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_suspend()\n"));
+	return 0;
+}
+
+static int rt2870_resume(
+	struct usb_interface *intf)
+{
+	struct net_device *net_dev;
+	PRTMP_ADAPTER pAd = usb_get_intfdata(intf);
+
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_resume()\n"));
+
+	pAd->PM_FlgSuspend = 0;
+	net_dev = pAd->net_dev;
+			netif_device_attach(net_dev);
+			netif_start_queue(net_dev);
+			netif_carrier_on(net_dev);
+			netif_wake_queue(net_dev);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_resume()\n"));
+	return 0;
+}
+#endif // CONFIG_PM //
+#endif // LINUX_VERSION_CODE //
+
+
+// Init driver module
+INT __init rtusb_init(void)
+{
+	printk("rtusb init --->\n");
+	return usb_register(&rtusb_driver);
+}
+
+// Deinit driver module
+VOID __exit rtusb_exit(void)
+{
+	usb_deregister(&rtusb_driver);
+	printk("<--- rtusb exit\n");
+}
+
+module_init(rtusb_init);
+module_exit(rtusb_exit);
+
+
+
+
+/*---------------------------------------------------------------------	*/
+/* function declarations												*/
+/*---------------------------------------------------------------------	*/
+
+/*
+========================================================================
+Routine Description:
+    MLME kernel thread.
+
+Arguments:
+	*Context			the pAd, driver control block pointer
+
+Return Value:
+    0					close the thread
+
+Note:
+========================================================================
+*/
+INT MlmeThread(
+	IN void *Context)
+{
+	PRTMP_ADAPTER	pAd = (PRTMP_ADAPTER)Context;
+	POS_COOKIE	pObj;
+	int status;
+
+	pObj = (POS_COOKIE)pAd->OS_Cookie;
+
+	rtmp_os_thread_init("rt2870MlmeThread", (PVOID)&(pAd->mlmeComplete));
+
+	while (pAd->mlme_kill == 0)
+	{
+		/* lock the device pointers */
+		//down(&(pAd->mlme_semaphore));
+		status = down_interruptible(&(pAd->mlme_semaphore));
+
+		/* lock the device pointers , need to check if required*/
+		//down(&(pAd->usbdev_semaphore));
+
+		if (!pAd->PM_FlgSuspend)
+		MlmeHandler(pAd);
+
+		/* unlock the device pointers */
+		//up(&(pAd->usbdev_semaphore));
+		if (status != 0)
+		{
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+			break;
+		}
+	}
+
+	/* notify the exit routine that we're actually exiting now
+	 *
+	 * complete()/wait_for_completion() is similar to up()/down(),
+	 * except that complete() is safe in the case where the structure
+	 * is getting deleted in a parallel mode of execution (i.e. just
+	 * after the down() -- that's necessary for the thread-shutdown
+	 * case.
+	 *
+	 * complete_and_exit() goes even further than this -- it is safe in
+	 * the case that the thread of the caller is going away (not just
+	 * the structure) -- this is necessary for the module-remove case.
+	 * This is important in preemption kernels, which transfer the flow
+	 * of execution immediately upon a complete().
+	 */
+	DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__));
+
+	pObj->MLMEThr_pid = NULL;
+
+	complete_and_exit (&pAd->mlmeComplete, 0);
+	return 0;
+
+}
+
+
+/*
+========================================================================
+Routine Description:
+    USB command kernel thread.
+
+Arguments:
+	*Context			the pAd, driver control block pointer
+
+Return Value:
+    0					close the thread
+
+Note:
+========================================================================
+*/
+INT RTUSBCmdThread(
+	IN void * Context)
+{
+	PRTMP_ADAPTER	pAd = (PRTMP_ADAPTER)Context;
+	POS_COOKIE		pObj;
+	int status;
+
+	pObj = (POS_COOKIE)pAd->OS_Cookie;
+
+	rtmp_os_thread_init("rt2870CmdThread", (PVOID)&(pAd->CmdQComplete));
+
+	NdisAcquireSpinLock(&pAd->CmdQLock);
+	pAd->CmdQ.CmdQState = RT2870_THREAD_RUNNING;
+	NdisReleaseSpinLock(&pAd->CmdQLock);
+
+	while (pAd->CmdQ.CmdQState == RT2870_THREAD_RUNNING)
+	{
+		/* lock the device pointers */
+		//down(&(pAd->RTUSBCmd_semaphore));
+		status = down_interruptible(&(pAd->RTUSBCmd_semaphore));
+
+		if (pAd->CmdQ.CmdQState == RT2870_THREAD_STOPED)
+			break;
+
+		if (status != 0)
+		{
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+			break;
+		}
+		/* lock the device pointers , need to check if required*/
+		//down(&(pAd->usbdev_semaphore));
+
+		if (!pAd->PM_FlgSuspend)
+		CMDHandler(pAd);
+
+		/* unlock the device pointers */
+		//up(&(pAd->usbdev_semaphore));
+	}
+
+	if (!pAd->PM_FlgSuspend)
+	{	// Clear the CmdQElements.
+		CmdQElmt	*pCmdQElmt = NULL;
+
+		NdisAcquireSpinLock(&pAd->CmdQLock);
+		pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
+		while(pAd->CmdQ.size)
+		{
+			RTUSBDequeueCmd(&pAd->CmdQ, &pCmdQElmt);
+			if (pCmdQElmt)
+			{
+				if (pCmdQElmt->CmdFromNdis == TRUE)
+				{
+					if (pCmdQElmt->buffer != NULL)
+						NdisFreeMemory(pCmdQElmt->buffer, pCmdQElmt->bufferlength, 0);
+
+					NdisFreeMemory(pCmdQElmt, sizeof(CmdQElmt), 0);
+				}
+				else
+				{
+					if ((pCmdQElmt->buffer != NULL) && (pCmdQElmt->bufferlength != 0))
+						NdisFreeMemory(pCmdQElmt->buffer, pCmdQElmt->bufferlength, 0);
+		            {
+						NdisFreeMemory(pCmdQElmt, sizeof(CmdQElmt), 0);
+					}
+				}
+			}
+		}
+
+		NdisReleaseSpinLock(&pAd->CmdQLock);
+	}
+	/* notify the exit routine that we're actually exiting now
+	 *
+	 * complete()/wait_for_completion() is similar to up()/down(),
+	 * except that complete() is safe in the case where the structure
+	 * is getting deleted in a parallel mode of execution (i.e. just
+	 * after the down() -- that's necessary for the thread-shutdown
+	 * case.
+	 *
+	 * complete_and_exit() goes even further than this -- it is safe in
+	 * the case that the thread of the caller is going away (not just
+	 * the structure) -- this is necessary for the module-remove case.
+	 * This is important in preemption kernels, which transfer the flow
+	 * of execution immediately upon a complete().
+	 */
+	DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n"));
+
+	pObj->RTUSBCmdThr_pid = NULL;
+
+	complete_and_exit (&pAd->CmdQComplete, 0);
+	return 0;
+
+}
+
+
+static void RT2870_TimerQ_Handle(RTMP_ADAPTER *pAd)
+{
+	int status;
+	RALINK_TIMER_STRUCT	*pTimer;
+	RT2870_TIMER_ENTRY	*pEntry;
+	unsigned long	irqFlag;
+
+	while(!pAd->TimerFunc_kill)
+	{
+//		printk("waiting for event!\n");
+		pTimer = NULL;
+
+		status = down_interruptible(&(pAd->RTUSBTimer_semaphore));
+
+		if (pAd->TimerQ.status == RT2870_THREAD_STOPED)
+			break;
+
+		// event happened.
+		while(pAd->TimerQ.pQHead)
+		{
+			RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlag);
+			pEntry = pAd->TimerQ.pQHead;
+			if (pEntry)
+			{
+				pTimer = pEntry->pRaTimer;
+
+				// update pQHead
+				pAd->TimerQ.pQHead = pEntry->pNext;
+				if (pEntry == pAd->TimerQ.pQTail)
+					pAd->TimerQ.pQTail = NULL;
+
+				// return this queue entry to timerQFreeList.
+				pEntry->pNext = pAd->TimerQ.pQPollFreeList;
+				pAd->TimerQ.pQPollFreeList = pEntry;
+			}
+			RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlag);
+
+			if (pTimer)
+			{
+				if (pTimer->handle != NULL)
+				if (!pAd->PM_FlgSuspend)
+					pTimer->handle(NULL, (PVOID) pTimer->cookie, NULL, pTimer);
+				if ((pTimer->Repeat) && (pTimer->State == FALSE))
+					RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue);
+			}
+		}
+
+		if (status != 0)
+		{
+			pAd->TimerQ.status = RT2870_THREAD_STOPED;
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+			break;
+		}
+	}
+}
+
+
+INT TimerQThread(
+	IN OUT PVOID Context)
+{
+	PRTMP_ADAPTER	pAd;
+	POS_COOKIE	pObj;
+
+	pAd = (PRTMP_ADAPTER)Context;
+	pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+	rtmp_os_thread_init("rt2870TimerQHandle", (PVOID)&(pAd->TimerQComplete));
+
+	RT2870_TimerQ_Handle(pAd);
+
+	/* notify the exit routine that we're actually exiting now
+	 *
+	 * complete()/wait_for_completion() is similar to up()/down(),
+	 * except that complete() is safe in the case where the structure
+	 * is getting deleted in a parallel mode of execution (i.e. just
+	 * after the down() -- that's necessary for the thread-shutdown
+	 * case.
+	 *
+	 * complete_and_exit() goes even further than this -- it is safe in
+	 * the case that the thread of the caller is going away (not just
+	 * the structure) -- this is necessary for the module-remove case.
+	 * This is important in preemption kernels, which transfer the flow
+	 * of execution immediately upon a complete().
+	 */
+	DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__));
+
+	pObj->TimerQThr_pid = NULL;
+
+	complete_and_exit(&pAd->TimerQComplete, 0);
+	return 0;
+
+}
+
+
+RT2870_TIMER_ENTRY *RT2870_TimerQ_Insert(
+	IN RTMP_ADAPTER *pAd,
+	IN RALINK_TIMER_STRUCT *pTimer)
+{
+	RT2870_TIMER_ENTRY *pQNode = NULL, *pQTail;
+	unsigned long irqFlags;
+
+
+	RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
+	if (pAd->TimerQ.status & RT2870_THREAD_CAN_DO_INSERT)
+	{
+		if(pAd->TimerQ.pQPollFreeList)
+		{
+			pQNode = pAd->TimerQ.pQPollFreeList;
+			pAd->TimerQ.pQPollFreeList = pQNode->pNext;
+
+			pQNode->pRaTimer = pTimer;
+			pQNode->pNext = NULL;
+
+			pQTail = pAd->TimerQ.pQTail;
+			if (pAd->TimerQ.pQTail != NULL)
+				pQTail->pNext = pQNode;
+			pAd->TimerQ.pQTail = pQNode;
+			if (pAd->TimerQ.pQHead == NULL)
+				pAd->TimerQ.pQHead = pQNode;
+		}
+		RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
+
+		if (pQNode)
+			up(&pAd->RTUSBTimer_semaphore);
+			//wake_up(&timerWaitQ);
+	}
+	else
+	{
+		RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
+	}
+	return pQNode;
+}
+
+
+BOOLEAN RT2870_TimerQ_Remove(
+	IN RTMP_ADAPTER *pAd,
+	IN RALINK_TIMER_STRUCT *pTimer)
+{
+	RT2870_TIMER_ENTRY *pNode, *pPrev = NULL;
+	unsigned long irqFlags;
+
+	RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
+	if (pAd->TimerQ.status >= RT2870_THREAD_INITED)
+	{
+		pNode = pAd->TimerQ.pQHead;
+		while (pNode)
+		{
+			if (pNode->pRaTimer == pTimer)
+				break;
+			pPrev = pNode;
+			pNode = pNode->pNext;
+		}
+
+		// Now move it to freeList queue.
+		if (pNode)
+		{
+			if (pNode == pAd->TimerQ.pQHead)
+				pAd->TimerQ.pQHead = pNode->pNext;
+			if (pNode == pAd->TimerQ.pQTail)
+				pAd->TimerQ.pQTail = pPrev;
+			if (pPrev != NULL)
+				pPrev->pNext = pNode->pNext;
+
+			// return this queue entry to timerQFreeList.
+			pNode->pNext = pAd->TimerQ.pQPollFreeList;
+			pAd->TimerQ.pQPollFreeList = pNode;
+		}
+	}
+	RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
+
+	return TRUE;
+}
+
+
+void RT2870_TimerQ_Exit(RTMP_ADAPTER *pAd)
+{
+	RT2870_TIMER_ENTRY *pTimerQ;
+	unsigned long irqFlags;
+
+	RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
+	while (pAd->TimerQ.pQHead)
+	{
+		pTimerQ = pAd->TimerQ.pQHead;
+		pAd->TimerQ.pQHead = pTimerQ->pNext;
+		// remove the timeQ
+	}
+	pAd->TimerQ.pQPollFreeList = NULL;
+	os_free_mem(pAd, pAd->TimerQ.pTimerQPoll);
+	pAd->TimerQ.pQTail = NULL;
+	pAd->TimerQ.pQHead = NULL;
+	pAd->TimerQ.status = RT2870_THREAD_STOPED;
+	RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
+
+}
+
+
+void RT2870_TimerQ_Init(RTMP_ADAPTER *pAd)
+{
+	int 	i;
+	RT2870_TIMER_ENTRY *pQNode, *pEntry;
+	unsigned long irqFlags;
+
+	NdisAllocateSpinLock(&pAd->TimerQLock);
+
+	RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
+	NdisZeroMemory(&pAd->TimerQ, sizeof(pAd->TimerQ));
+	//InterlockedExchange(&pAd->TimerQ.count, 0);
+
+	/* Initialise the wait q head */
+	//init_waitqueue_head(&timerWaitQ);
+
+	os_alloc_mem(pAd, &pAd->TimerQ.pTimerQPoll, sizeof(RT2870_TIMER_ENTRY) * TIMER_QUEUE_SIZE_MAX);
+	if (pAd->TimerQ.pTimerQPoll)
+	{
+		pEntry = NULL;
+		pQNode = (RT2870_TIMER_ENTRY *)pAd->TimerQ.pTimerQPoll;
+		for (i = 0 ;i <TIMER_QUEUE_SIZE_MAX; i++)
+		{
+			pQNode->pNext = pEntry;
+			pEntry = pQNode;
+			pQNode++;
+		}
+		pAd->TimerQ.pQPollFreeList = pEntry;
+		pAd->TimerQ.pQHead = NULL;
+		pAd->TimerQ.pQTail = NULL;
+		pAd->TimerQ.status = RT2870_THREAD_INITED;
+	}
+	RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
+}
+
+
+VOID RT2870_WatchDog(IN RTMP_ADAPTER *pAd)
+{
+	PHT_TX_CONTEXT		pHTTXContext;
+	int 					idx;
+	ULONG				irqFlags;
+	PURB		   		pUrb;
+	BOOLEAN				needDumpSeq = FALSE;
+	UINT32          	MACValue;
+
+
+	idx = 0;
+	RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
+	if ((MACValue & 0xff) !=0 )
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 0 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
+		RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012);
+		while((MACValue &0xff) != 0 && (idx++ < 10))
+		{
+		        RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
+		        NdisMSleep(1);
+		}
+		RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
+	}
+
+//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		idx = 0;
+		if ((MACValue & 0xff00) !=0 )
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 1 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
+			RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf4000a);
+			while((MACValue &0xff00) != 0 && (idx++ < 10))
+			{
+				RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
+				NdisMSleep(1);
+			}
+			RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
+		}
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	if (pAd->watchDogRxOverFlowCnt >= 2)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n"));
+		if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+									fRTMP_ADAPTER_BULKIN_RESET |
+									fRTMP_ADAPTER_HALT_IN_PROGRESS |
+									fRTMP_ADAPTER_NIC_NOT_EXIST))))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n"));
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
+			needDumpSeq = TRUE;
+		}
+		pAd->watchDogRxOverFlowCnt = 0;
+	}
+
+
+	for (idx = 0; idx < NUM_OF_TX_RING; idx++)
+	{
+		pUrb = NULL;
+
+		RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags);
+		if ((pAd->BulkOutPending[idx] == TRUE) && pAd->watchDogTxPendingCnt)
+		{
+			pAd->watchDogTxPendingCnt[idx]++;
+
+			if ((pAd->watchDogTxPendingCnt[idx] > 2) &&
+				 (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_BULKOUT_RESET)))
+				)
+			{
+				// FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it!
+				pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[idx]);
+				if (pHTTXContext->IRPPending)
+				{	// Check TxContext.
+					pUrb = pHTTXContext->pUrb;
+				}
+				else if (idx == MGMTPIPEIDX)
+				{
+					PTX_CONTEXT pMLMEContext, pNULLContext, pPsPollContext;
+
+					//Check MgmtContext.
+					pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
+					pPsPollContext = (PTX_CONTEXT)(&pAd->PsPollContext);
+					pNULLContext = (PTX_CONTEXT)(&pAd->NullContext);
+
+					if (pMLMEContext->IRPPending)
+					{
+						ASSERT(pMLMEContext->IRPPending);
+						pUrb = pMLMEContext->pUrb;
+					}
+					else if (pNULLContext->IRPPending)
+					{
+						ASSERT(pNULLContext->IRPPending);
+						pUrb = pNULLContext->pUrb;
+					}
+					else if (pPsPollContext->IRPPending)
+					{
+						ASSERT(pPsPollContext->IRPPending);
+						pUrb = pPsPollContext->pUrb;
+					}
+				}
+
+				RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
+
+				DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n", idx));
+				if (pUrb)
+				{
+					DBGPRINT(RT_DEBUG_TRACE, ("Unlink the pending URB!\n"));
+					// unlink it now
+					RTUSB_UNLINK_URB(pUrb);
+					// Sleep 200 microseconds to give cancellation time to work
+					RTMPusecDelay(200);
+					needDumpSeq = TRUE;
+				}
+				else
+				{
+					DBGPRINT(RT_DEBUG_ERROR, ("Unkonw bulkOut URB maybe hanged!!!!!!!!!!!!\n"));
+				}
+			}
+			else
+			{
+				RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
+			}
+		}
+		else
+		{
+			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
+		}
+	}
+
+#ifdef DOT11_N_SUPPORT
+	// For Sigma debug, dump the ba_reordering sequence.
+	if((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0))
+	{
+		USHORT				Idx;
+		PBA_REC_ENTRY		pBAEntry = NULL;
+		UCHAR				count = 0;
+		struct reordering_mpdu *mpdu_blk;
+
+		Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0];
+
+		pBAEntry = &pAd->BATable.BARecEntry[Idx];
+		if((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n"));
+			NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
+			mpdu_blk = pBAEntry->list.next;
+			while (mpdu_blk)
+			{
+				DBGPRINT(RT_DEBUG_TRACE, ("\t%d:Seq-%d, bAMSDU-%d!\n", count, mpdu_blk->Sequence, mpdu_blk->bAMSDU));
+				mpdu_blk = mpdu_blk->next;
+				count++;
+			}
+
+			DBGPRINT(RT_DEBUG_TRACE, ("\npBAEntry->LastIndSeq=%d!\n", pBAEntry->LastIndSeq));
+			NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
+		}
+	}
+#endif // DOT11_N_SUPPORT //
+}
+
+/*
+========================================================================
+Routine Description:
+    Release allocated resources.
+
+Arguments:
+    *dev				Point to the PCI or USB device
+	pAd					driver control block pointer
+
+Return Value:
+    None
+
+Note:
+========================================================================
+*/
+static void _rtusb_disconnect(struct usb_device *dev, PRTMP_ADAPTER pAd)
+{
+	struct net_device	*net_dev = NULL;
+
+
+	DBGPRINT(RT_DEBUG_ERROR, ("rtusb_disconnect: unregister usbnet usb-%s-%s\n",
+				dev->bus->bus_name, dev->devpath));
+	if (!pAd)
+	{
+#ifdef MULTIPLE_CARD_SUPPORT
+		if ((pAd->MC_RowID >= 0) && (pAd->MC_RowID <= MAX_NUM_OF_MULTIPLE_CARD))
+			MC_CardUsed[pAd->MC_RowID] = 0; // not clear MAC address
+#endif // MULTIPLE_CARD_SUPPORT //
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	/* kernel 2.4 series */
+		while(MOD_IN_USE > 0)
+		{
+			MOD_DEC_USE_COUNT;
+		}
+#else
+		usb_put_dev(dev);
+#endif // LINUX_VERSION_CODE //
+
+		printk("rtusb_disconnect: pAd == NULL!\n");
+		return;
+	}
+	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
+
+
+
+	// for debug, wait to show some messages to /proc system
+	udelay(1);
+
+
+
+
+	net_dev = pAd->net_dev;
+	if (pAd->net_dev != NULL)
+	{
+		printk("rtusb_disconnect: unregister_netdev(), dev->name=%s!\n", net_dev->name);
+		unregister_netdev (pAd->net_dev);
+	}
+	udelay(1);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	/* kernel 2.4 series */
+#else
+	flush_scheduled_work();
+#endif // LINUX_VERSION_CODE //
+	udelay(1);
+
+	// free net_device memory
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	/* kernel 2.4 series */
+	kfree(net_dev);
+#else
+	free_netdev(net_dev);
+#endif // LINUX_VERSION_CODE //
+
+	// free adapter memory
+	RTMPFreeAdapter(pAd);
+
+	// release a use of the usb device structure
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	/* kernel 2.4 series */
+	while(MOD_IN_USE > 0)
+	{
+		MOD_DEC_USE_COUNT;
+	}
+#else
+	usb_put_dev(dev);
+#endif // LINUX_VERSION_CODE //
+	udelay(1);
+
+	DBGPRINT(RT_DEBUG_ERROR, (" RTUSB disconnect successfully\n"));
+}
+
+
+/*
+========================================================================
+Routine Description:
+    Probe RT28XX chipset.
+
+Arguments:
+    *dev				Point to the PCI or USB device
+	interface
+	*id_table			Point to the PCI or USB device ID
+
+Return Value:
+    None
+
+Note:
+========================================================================
+*/
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	/* kernel 2.4 series */
+static void *rtusb_probe(struct usb_device *dev, UINT interface,
+						const struct usb_device_id *id)
+{
+	PRTMP_ADAPTER pAd;
+	rt28xx_probe((void *)dev, (void *)id, interface, &pAd);
+	return (void *)pAd;
+}
+
+//Disconnect function is called within exit routine
+static void rtusb_disconnect(struct usb_device *dev, void *ptr)
+{
+	_rtusb_disconnect(dev, ((PRTMP_ADAPTER)ptr));
+}
+
+#else	/* kernel 2.6 series */
+static int rtusb_probe (struct usb_interface *intf,
+						const struct usb_device_id *id)
+{
+	PRTMP_ADAPTER pAd;
+	return (int)rt28xx_probe((void *)intf, (void *)id, 0, &pAd);
+}
+
+
+static void rtusb_disconnect(struct usb_interface *intf)
+{
+	struct usb_device   *dev = interface_to_usbdev(intf);
+	PRTMP_ADAPTER       pAd;
+
+
+	pAd = usb_get_intfdata(intf);
+	usb_set_intfdata(intf, NULL);
+
+	_rtusb_disconnect(dev, pAd);
+}
+#endif // LINUX_VERSION_CODE //
+
+
+/*
+========================================================================
+Routine Description:
+    Close kernel threads.
+
+Arguments:
+	*pAd				the raxx interface data pointer
+
+Return Value:
+    NONE
+
+Note:
+========================================================================
+*/
+VOID RT28xxThreadTerminate(
+	IN RTMP_ADAPTER *pAd)
+{
+	POS_COOKIE	pObj = (POS_COOKIE) pAd->OS_Cookie;
+	INT			ret;
+
+
+	// Sleep 50 milliseconds so pending io might finish normally
+	RTMPusecDelay(50000);
+
+	// We want to wait until all pending receives and sends to the
+	// device object. We cancel any
+	// irps. Wait until sends and receives have stopped.
+	RTUSBCancelPendingIRPs(pAd);
+
+	// Terminate Threads
+	if (pObj->MLMEThr_pid)
+	{
+		printk("Terminate the MLMEThr_pid=%d!\n", pid_nr(pObj->MLMEThr_pid));
+		mb();
+		pAd->mlme_kill = 1;
+		//RT28XX_MLME_HANDLER(pAd);
+		mb();
+		ret = kill_pid(pObj->MLMEThr_pid, SIGTERM, 1);
+		if (ret)
+		{
+			printk (KERN_WARNING "%s: unable to Mlme thread, pid=%d, ret=%d!\n",
+					pAd->net_dev->name, pid_nr(pObj->MLMEThr_pid), ret);
+		}
+		else
+		{
+			//wait_for_completion (&pAd->notify);
+			wait_for_completion (&pAd->mlmeComplete);
+			pObj->MLMEThr_pid = NULL;
+		}
+	}
+
+	if (pObj->RTUSBCmdThr_pid >= 0)
+	{
+		printk("Terminate the RTUSBCmdThr_pid=%d!\n", pid_nr(pObj->RTUSBCmdThr_pid));
+		mb();
+		NdisAcquireSpinLock(&pAd->CmdQLock);
+		pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
+		NdisReleaseSpinLock(&pAd->CmdQLock);
+		mb();
+		//RTUSBCMDUp(pAd);
+		ret = kill_pid(pObj->RTUSBCmdThr_pid, SIGTERM, 1);
+		if (ret)
+		{
+			printk(KERN_WARNING "%s: unable to RTUSBCmd thread, pid=%d, ret=%d!\n",
+					pAd->net_dev->name, pid_nr(pObj->RTUSBCmdThr_pid), ret);
+		}
+		else
+		{
+			//wait_for_completion (&pAd->notify);
+			wait_for_completion (&pAd->CmdQComplete);
+			pObj->RTUSBCmdThr_pid = NULL;
+		}
+	}
+	if (pObj->TimerQThr_pid >= 0)
+	{
+		POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
+
+		printk("Terminate the TimerQThr_pid=%d!\n", pid_nr(pObj->TimerQThr_pid));
+		mb();
+		pAd->TimerFunc_kill = 1;
+		mb();
+		ret = kill_pid(pObj->TimerQThr_pid, SIGTERM, 1);
+		if (ret)
+		{
+			printk(KERN_WARNING "%s: unable to stop TimerQThread, pid=%d, ret=%d!\n",
+					pAd->net_dev->name, pid_nr(pObj->TimerQThr_pid), ret);
+		}
+		else
+		{
+			printk("wait_for_completion TimerQThr\n");
+			wait_for_completion(&pAd->TimerQComplete);
+			pObj->TimerQThr_pid = NULL;
+		}
+	}
+	// Kill tasklets
+	pAd->mlme_kill = 0;
+	pAd->CmdQ.CmdQState = RT2870_THREAD_UNKNOWN;
+	pAd->TimerFunc_kill = 0;
+}
+
+
+void kill_thread_task(IN PRTMP_ADAPTER pAd)
+{
+	POS_COOKIE pObj;
+
+	pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+	tasklet_kill(&pObj->rx_done_task);
+	tasklet_kill(&pObj->mgmt_dma_done_task);
+	tasklet_kill(&pObj->ac0_dma_done_task);
+	tasklet_kill(&pObj->ac1_dma_done_task);
+	tasklet_kill(&pObj->ac2_dma_done_task);
+	tasklet_kill(&pObj->ac3_dma_done_task);
+	tasklet_kill(&pObj->hcca_dma_done_task);
+	tasklet_kill(&pObj->tbtt_task);
+
+}
+
+
+/*
+========================================================================
+Routine Description:
+    Check the chipset vendor/product ID.
+
+Arguments:
+    _dev_p				Point to the PCI or USB device
+
+Return Value:
+    TRUE				Check ok
+	FALSE				Check fail
+
+Note:
+========================================================================
+*/
+BOOLEAN RT28XXChipsetCheck(
+	IN void *_dev_p)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	/* kernel 2.4 series */
+	struct usb_device *dev_p = (struct usb_device *)_dev_p;
+#else
+	struct usb_interface *intf = (struct usb_interface *)_dev_p;
+	struct usb_device *dev_p = interface_to_usbdev(intf);
+#endif // LINUX_VERSION_CODE //
+	UINT32 i;
+
+
+	for(i=0; i<rtusb_usb_id_len; i++)
+	{
+		if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor &&
+			dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct)
+		{
+			printk("rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
+					dev_p->descriptor.idVendor, dev_p->descriptor.idProduct);
+			break;
+		}
+	}
+
+	if (i == rtusb_usb_id_len)
+	{
+		printk("rt2870: Error! Device Descriptor not matching!\n");
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+
+/*
+========================================================================
+Routine Description:
+    Init net device structure.
+
+Arguments:
+    _dev_p				Point to the PCI or USB device
+    *net_dev			Point to the net device
+	*pAd				the raxx interface data pointer
+
+Return Value:
+    TRUE				Init ok
+	FALSE				Init fail
+
+Note:
+========================================================================
+*/
+BOOLEAN RT28XXNetDevInit(
+	IN void 				*_dev_p,
+	IN struct  net_device	*net_dev,
+	IN RTMP_ADAPTER 		*pAd)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	/* kernel 2.4 series */
+	struct usb_device *dev_p = (struct usb_device *)_dev_p;
+#else
+	struct usb_interface *intf = (struct usb_interface *)_dev_p;
+	struct usb_device *dev_p = interface_to_usbdev(intf);
+#endif // LINUX_VERSION_CODE //
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	/* kernel 2.4 series */
+	pAd->config = dev_p->config;
+#else
+	pAd->config = &dev_p->config->desc;
+#endif // LINUX_VERSION_CODE //
+	return TRUE;
+}
+
+
+/*
+========================================================================
+Routine Description:
+    Init net device structure.
+
+Arguments:
+    _dev_p				Point to the PCI or USB device
+	*pAd				the raxx interface data pointer
+
+Return Value:
+    TRUE				Config ok
+	FALSE				Config fail
+
+Note:
+========================================================================
+*/
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+BOOLEAN RT28XXProbePostConfig(
+	IN void 				*_dev_p,
+	IN RTMP_ADAPTER 		*pAd,
+	IN INT32				interface)
+{
+	struct usb_device *dev_p = (struct usb_device *)_dev_p;
+	struct usb_interface *intf;
+	struct usb_interface_descriptor *iface_desc;
+	struct usb_endpoint_descriptor *endpoint;
+	ULONG BulkOutIdx;
+	UINT32 i;
+
+
+	/* get the active interface descriptor */
+	intf = &dev_p->actconfig->interface[interface];
+	iface_desc = &intf->altsetting[0];
+
+	/* get # of enpoints */
+	pAd->NumberOfPipes = iface_desc->bNumEndpoints;
+	DBGPRINT(RT_DEBUG_TRACE, ("NumEndpoints=%d\n", iface_desc->bNumEndpoints));
+
+	/* Configure Pipes */
+	endpoint = &iface_desc->endpoint[0];
+	BulkOutIdx = 0;
+
+	for(i=0; i<pAd->NumberOfPipes; i++)
+	{
+		if ((endpoint[i].bmAttributes == USB_ENDPOINT_XFER_BULK) &&
+			((endpoint[i].bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN))
+		{
+			pAd->BulkInEpAddr = endpoint[i].bEndpointAddress;
+			pAd->BulkInMaxPacketSize = endpoint[i].wMaxPacketSize;
+
+			DBGPRINT_RAW(RT_DEBUG_TRACE,
+				("BULK IN MaximumPacketSize = %d\n", pAd->BulkInMaxPacketSize));
+			DBGPRINT_RAW(RT_DEBUG_TRACE,
+				("EP address = 0x%2x  \n", endpoint[i].bEndpointAddress));
+		}
+		else if ((endpoint[i].bmAttributes == USB_ENDPOINT_XFER_BULK) &&
+				((endpoint[i].bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT))
+		{
+			// There are 6 bulk out EP. EP6 highest priority.
+			// EP1-4 is EDCA.  EP5 is HCCA.
+			pAd->BulkOutEpAddr[BulkOutIdx++] = endpoint[i].bEndpointAddress;
+			pAd->BulkOutMaxPacketSize = endpoint[i].wMaxPacketSize;
+
+			DBGPRINT_RAW(RT_DEBUG_TRACE,
+				("BULK OUT MaximumPacketSize = %d\n", pAd->BulkOutMaxPacketSize));
+			DBGPRINT_RAW(RT_DEBUG_TRACE,
+				("EP address = 0x%2x  \n", endpoint[i].bEndpointAddress));
+		}
+	}
+
+	if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0]))
+	{
+		printk("Could not find both bulk-in and bulk-out endpoints\n");
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+#else
+BOOLEAN RT28XXProbePostConfig(
+	IN void 				*_dev_p,
+	IN RTMP_ADAPTER 		*pAd,
+	IN INT32				interface)
+{
+	struct usb_interface *intf = (struct usb_interface *)_dev_p;
+	struct usb_host_interface *iface_desc;
+	ULONG BulkOutIdx;
+	UINT32 i;
+
+
+	/* get the active interface descriptor */
+	iface_desc = intf->cur_altsetting;
+
+	/* get # of enpoints  */
+	pAd->NumberOfPipes = iface_desc->desc.bNumEndpoints;
+	DBGPRINT(RT_DEBUG_TRACE,
+			("NumEndpoints=%d\n", iface_desc->desc.bNumEndpoints));
+
+	/* Configure Pipes */
+	BulkOutIdx = 0;
+
+	for(i=0; i<pAd->NumberOfPipes; i++)
+	{
+		if ((iface_desc->endpoint[i].desc.bmAttributes ==
+				USB_ENDPOINT_XFER_BULK) &&
+			((iface_desc->endpoint[i].desc.bEndpointAddress &
+				USB_ENDPOINT_DIR_MASK) == USB_DIR_IN))
+		{
+			pAd->BulkInEpAddr = iface_desc->endpoint[i].desc.bEndpointAddress;
+			pAd->BulkInMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize;
+
+			DBGPRINT_RAW(RT_DEBUG_TRACE,
+				("BULK IN MaximumPacketSize = %d\n", pAd->BulkInMaxPacketSize));
+			DBGPRINT_RAW(RT_DEBUG_TRACE,
+				("EP address = 0x%2x\n", iface_desc->endpoint[i].desc.bEndpointAddress));
+		}
+		else if ((iface_desc->endpoint[i].desc.bmAttributes ==
+					USB_ENDPOINT_XFER_BULK) &&
+				((iface_desc->endpoint[i].desc.bEndpointAddress &
+					USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT))
+		{
+			// there are 6 bulk out EP. EP6 highest priority.
+			// EP1-4 is EDCA.  EP5 is HCCA.
+			pAd->BulkOutEpAddr[BulkOutIdx++] = iface_desc->endpoint[i].desc.bEndpointAddress;
+			pAd->BulkOutMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize;
+
+			DBGPRINT_RAW(RT_DEBUG_TRACE,
+				("BULK OUT MaximumPacketSize = %d\n", pAd->BulkOutMaxPacketSize));
+			DBGPRINT_RAW(RT_DEBUG_TRACE,
+				("EP address = 0x%2x  \n", iface_desc->endpoint[i].desc.bEndpointAddress));
+		}
+	}
+
+	if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0]))
+	{
+		printk("%s: Could not find both bulk-in and bulk-out endpoints\n", __FUNCTION__);
+		return FALSE;
+	}
+
+	return TRUE;
+}
+#endif // LINUX_VERSION_CODE //
+
+
+/*
+========================================================================
+Routine Description:
+    Disable DMA.
+
+Arguments:
+	*pAd				the raxx interface data pointer
+
+Return Value:
+	None
+
+Note:
+========================================================================
+*/
+VOID RT28XXDMADisable(
+	IN RTMP_ADAPTER 		*pAd)
+{
+	// no use
+}
+
+
+
+/*
+========================================================================
+Routine Description:
+    Enable DMA.
+
+Arguments:
+	*pAd				the raxx interface data pointer
+
+Return Value:
+	None
+
+Note:
+========================================================================
+*/
+VOID RT28XXDMAEnable(
+	IN RTMP_ADAPTER 		*pAd)
+{
+	WPDMA_GLO_CFG_STRUC	GloCfg;
+	USB_DMA_CFG_STRUC	UsbCfg;
+	int					i = 0;
+
+
+	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
+	do
+	{
+		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
+		if ((GloCfg.field.TxDMABusy == 0)  && (GloCfg.field.RxDMABusy == 0))
+			break;
+
+		DBGPRINT(RT_DEBUG_TRACE, ("==>  DMABusy\n"));
+		RTMPusecDelay(1000);
+		i++;
+	}while ( i <200);
+
+
+	RTMPusecDelay(50);
+	GloCfg.field.EnTXWriteBackDDONE = 1;
+	GloCfg.field.EnableRxDMA = 1;
+	GloCfg.field.EnableTxDMA = 1;
+	DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
+	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
+
+	UsbCfg.word = 0;
+	UsbCfg.field.phyclear = 0;
+	/* usb version is 1.1,do not use bulk in aggregation */
+	if (pAd->BulkInMaxPacketSize == 512)
+			UsbCfg.field.RxBulkAggEn = 1;
+	/* for last packet, PBF might use more than limited, so minus 2 to prevent from error */
+	UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE /1024)-3;
+	UsbCfg.field.RxBulkAggTOut = 0x80; /* 2006-10-18 */
+	UsbCfg.field.RxBulkEn = 1;
+	UsbCfg.field.TxBulkEn = 1;
+
+	RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word);
+
+}
+
+/*
+========================================================================
+Routine Description:
+    Write Beacon buffer to Asic.
+
+Arguments:
+	*pAd				the raxx interface data pointer
+
+Return Value:
+	None
+
+Note:
+========================================================================
+*/
+VOID RT28xx_UpdateBeaconToAsic(
+	IN RTMP_ADAPTER		*pAd,
+	IN INT				apidx,
+	IN ULONG			FrameLen,
+	IN ULONG			UpdatePos)
+{
+	PUCHAR        	pBeaconFrame = NULL;
+	UCHAR  			*ptr;
+	UINT  			i, padding;
+	BEACON_SYNC_STRUCT	*pBeaconSync = pAd->CommonCfg.pBeaconSync;
+	UINT32			longValue;
+//	USHORT			shortValue;
+	BOOLEAN			bBcnReq = FALSE;
+	UCHAR			bcn_idx = 0;
+
+
+	if (pBeaconFrame == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("pBeaconFrame is NULL!\n"));
+		return;
+	}
+
+	if (pBeaconSync == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("pBeaconSync is NULL!\n"));
+		return;
+	}
+
+	//if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) ||
+	//	((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP))
+	//	)
+	if (bBcnReq == FALSE)
+	{
+		/* when the ra interface is down, do not send its beacon frame */
+		/* clear all zero */
+		for(i=0; i<TXWI_SIZE; i+=4) {
+			RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, 0x00);
+		}
+		pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
+		NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE);
+	}
+	else
+	{
+		ptr = (PUCHAR)&pAd->BeaconTxWI;
+#ifdef RT_BIG_ENDIAN
+		RTMPWIEndianChange(ptr, TYPE_TXWI);
+#endif
+		if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE)
+		{	// If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames.
+			pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
+			NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE);
+		}
+
+		if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) != (1 << bcn_idx))
+		{
+			for (i=0; i<TXWI_SIZE; i+=4)  // 16-byte TXWI field
+			{
+				longValue =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
+				RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, longValue);
+				ptr += 4;
+			}
+		}
+
+		ptr = pBeaconSync->BeaconBuf[bcn_idx];
+		padding = (FrameLen & 0x01);
+		NdisZeroMemory((PUCHAR)(pBeaconFrame + FrameLen), padding);
+		FrameLen += padding;
+		for (i = 0 ; i < FrameLen /*HW_BEACON_OFFSET*/; i += 2)
+		{
+			if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE)
+			{
+				NdisMoveMemory(ptr, pBeaconFrame, 2);
+				//shortValue = *ptr + (*(ptr+1)<<8);
+				//RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue);
+				RTUSBMultiWrite(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, ptr, 2);
+			}
+			ptr +=2;
+			pBeaconFrame += 2;
+		}
+
+		pBeaconSync->BeaconBitMap |= (1 << bcn_idx);
+
+		// For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame.
+	}
+
+}
+
+
+VOID RT2870_BssBeaconStop(
+	IN RTMP_ADAPTER *pAd)
+{
+	BEACON_SYNC_STRUCT	*pBeaconSync;
+	int i, offset;
+	BOOLEAN	Cancelled = TRUE;
+
+	pBeaconSync = pAd->CommonCfg.pBeaconSync;
+	if (pBeaconSync && pBeaconSync->EnableBeacon)
+	{
+		INT NumOfBcn;
+
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+			NumOfBcn = MAX_MESH_NUM;
+		}
+#endif // CONFIG_STA_SUPPORT //
+
+		RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
+
+		for(i=0; i<NumOfBcn; i++)
+		{
+			NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
+			NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
+
+			for (offset=0; offset<HW_BEACON_OFFSET; offset+=4)
+				RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[i] + offset, 0x00);
+
+			pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
+			pBeaconSync->TimIELocationInBeacon[i] = 0;
+		}
+		pBeaconSync->BeaconBitMap = 0;
+		pBeaconSync->DtimBitOn = 0;
+	}
+}
+
+
+VOID RT2870_BssBeaconStart(
+	IN RTMP_ADAPTER *pAd)
+{
+	int apidx;
+	BEACON_SYNC_STRUCT	*pBeaconSync;
+//	LARGE_INTEGER 	tsfTime, deltaTime;
+
+	pBeaconSync = pAd->CommonCfg.pBeaconSync;
+	if (pBeaconSync && pBeaconSync->EnableBeacon)
+	{
+		INT NumOfBcn;
+
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+			NumOfBcn = MAX_MESH_NUM;
+		}
+#endif // CONFIG_STA_SUPPORT //
+
+		for(apidx=0; apidx<NumOfBcn; apidx++)
+		{
+			UCHAR CapabilityInfoLocationInBeacon = 0;
+			UCHAR TimIELocationInBeacon = 0;
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+			NdisZeroMemory(pBeaconSync->BeaconBuf[apidx], HW_BEACON_OFFSET);
+			pBeaconSync->CapabilityInfoLocationInBeacon[apidx] = CapabilityInfoLocationInBeacon;
+			pBeaconSync->TimIELocationInBeacon[apidx] = TimIELocationInBeacon;
+			NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx], TXWI_SIZE);
+		}
+		pBeaconSync->BeaconBitMap = 0;
+		pBeaconSync->DtimBitOn = 0;
+		pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE;
+
+		pAd->CommonCfg.BeaconAdjust = 0;
+		pAd->CommonCfg.BeaconFactor = 0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10);
+		pAd->CommonCfg.BeaconRemain = (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1;
+		printk("RT2870_BssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n", pAd->CommonCfg.BeaconFactor, pAd->CommonCfg.BeaconRemain);
+		RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer, pAd->CommonCfg.BeaconPeriod);
+
+	}
+}
+
+
+VOID RT2870_BssBeaconInit(
+	IN RTMP_ADAPTER *pAd)
+{
+	BEACON_SYNC_STRUCT	*pBeaconSync;
+	int i;
+
+	NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(BEACON_SYNC_STRUCT), MEM_ALLOC_FLAG);
+	if (pAd->CommonCfg.pBeaconSync)
+	{
+		pBeaconSync = pAd->CommonCfg.pBeaconSync;
+		NdisZeroMemory(pBeaconSync, sizeof(BEACON_SYNC_STRUCT));
+		for(i=0; i < HW_BEACON_MAX_COUNT; i++)
+		{
+			NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
+			pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
+			pBeaconSync->TimIELocationInBeacon[i] = 0;
+			NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
+		}
+		pBeaconSync->BeaconBitMap = 0;
+
+		//RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE);
+		pBeaconSync->EnableBeacon = TRUE;
+	}
+}
+
+
+VOID RT2870_BssBeaconExit(
+	IN RTMP_ADAPTER *pAd)
+{
+	BEACON_SYNC_STRUCT	*pBeaconSync;
+	BOOLEAN	Cancelled = TRUE;
+	int i;
+
+	if (pAd->CommonCfg.pBeaconSync)
+	{
+		pBeaconSync = pAd->CommonCfg.pBeaconSync;
+		pBeaconSync->EnableBeacon = FALSE;
+		RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
+		pBeaconSync->BeaconBitMap = 0;
+
+		for(i=0; i<HW_BEACON_MAX_COUNT; i++)
+		{
+			NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
+			pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
+			pBeaconSync->TimIELocationInBeacon[i] = 0;
+			NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
+		}
+
+		NdisFreeMemory(pAd->CommonCfg.pBeaconSync, HW_BEACON_OFFSET * HW_BEACON_MAX_COUNT, 0);
+		pAd->CommonCfg.pBeaconSync = NULL;
+	}
+}
+
+VOID BeaconUpdateExec(
+    IN PVOID SystemSpecific1,
+    IN PVOID FunctionContext,
+    IN PVOID SystemSpecific2,
+    IN PVOID SystemSpecific3)
+{
+	PRTMP_ADAPTER	pAd = (PRTMP_ADAPTER)FunctionContext;
+	LARGE_INTEGER	tsfTime_a;//, tsfTime_b, deltaTime_exp, deltaTime_ab;
+	UINT32			delta, remain, remain_low, remain_high;
+//	BOOLEAN			positive;
+
+	ReSyncBeaconTime(pAd);
+
+
+
+	RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart);
+	RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart);
+
+
+	//positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp);
+	remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart;
+	remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10);
+	remain = (remain_high + remain_low)%(pAd->CommonCfg.BeaconPeriod << 10);
+	delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain;
+
+	pAd->CommonCfg.BeaconUpdateTimer.TimerValue = (delta >> 10) + 10;
+
+}
+
diff --git a/drivers/staging/rt3070/Kconfig b/drivers/staging/rt3070/Kconfig
new file mode 100644
index 0000000..b37fb5d
--- /dev/null
+++ b/drivers/staging/rt3070/Kconfig
@@ -0,0 +1,6 @@
+config RT3070
+	tristate "Ralink 3070 wireless support"
+	depends on USB && X86 && WLAN_80211
+	---help---
+	  This is an experimental driver for the Ralink 3070 wireless chip.
+
diff --git a/drivers/staging/rt3070/Makefile b/drivers/staging/rt3070/Makefile
new file mode 100644
index 0000000..55980c9
--- /dev/null
+++ b/drivers/staging/rt3070/Makefile
@@ -0,0 +1,47 @@
+obj-$(CONFIG_RT3070)	+= rt3070sta.o
+
+# TODO: all of these should be removed
+EXTRA_CFLAGS += -DLINUX -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT
+EXTRA_CFLAGS += -DRT2870 -DRT30xx -DRT3070
+EXTRA_CFLAGS += -DCONFIG_STA_SUPPORT
+EXTRA_CFLAGS += -DDBG
+EXTRA_CFLAGS += -DDOT11_N_SUPPORT
+EXTRA_CFLAGS += -DWPA_SUPPLICANT_SUPPORT
+EXTRA_CFLAGS += -DNATIVE_WPA_SUPPLICANT_SUPPORT
+
+rt3070sta-objs :=		\
+	common/md5.o		\
+	common/mlme.o		\
+	common/rtmp_wep.o	\
+	common/action.o		\
+	common/cmm_data.o	\
+	common/rtmp_init.o	\
+	common/rtmp_tkip.o	\
+	common/cmm_sync.o	\
+	common/eeprom.o		\
+	common/cmm_sanity.o	\
+	common/cmm_info.o	\
+	common/cmm_wpa.o	\
+	common/dfs.o		\
+	common/spectrum.o	\
+	sta/assoc.o		\
+	sta/aironet.o		\
+	sta/auth.o		\
+	sta/auth_rsp.o		\
+	sta/sync.o		\
+	sta/sanity.o		\
+	sta/rtmp_data.o		\
+	sta/connect.o		\
+	sta/wpa.o		\
+	rt_linux.o		\
+	rt_profile.o		\
+	rt_main_dev.o		\
+	sta_ioctl.o		\
+	common/ba_action.o	\
+	2870_main_dev.o		\
+	common/2870_rtmp_init.o	\
+	common/rtusb_io.o	\
+	common/rtusb_bulk.o	\
+	common/rtusb_data.o	\
+	common/cmm_data_2870.o
+
diff --git a/drivers/staging/rt3070/action.h b/drivers/staging/rt3070/action.h
new file mode 100644
index 0000000..ce3877d
--- /dev/null
+++ b/drivers/staging/rt3070/action.h
@@ -0,0 +1,68 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	aironet.h
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	Name		Date			Modification logs
+	Paul Lin	04-06-15		Initial
+*/
+
+#ifndef	__ACTION_H__
+#define	__ACTION_H__
+
+typedef struct PACKED __HT_INFO_OCTET
+{
+#ifdef RT_BIG_ENDIAN
+	UCHAR	Reserved:5;
+	UCHAR 	STA_Channel_Width:1;
+	UCHAR	Forty_MHz_Intolerant:1;
+	UCHAR	Request:1;
+#else
+	UCHAR	Request:1;
+	UCHAR	Forty_MHz_Intolerant:1;
+	UCHAR 	STA_Channel_Width:1;
+	UCHAR	Reserved:5;
+#endif
+} HT_INFORMATION_OCTET;
+
+
+typedef struct PACKED __FRAME_HT_INFO
+{
+	HEADER_802_11   		Hdr;
+	UCHAR					Category;
+	UCHAR					Action;
+	HT_INFORMATION_OCTET	HT_Info;
+}   FRAME_HT_INFO, *PFRAME_HT_INFO;
+
+#endif /* __ACTION_H__ */
+
+
diff --git a/drivers/staging/rt3070/aironet.h b/drivers/staging/rt3070/aironet.h
new file mode 100644
index 0000000..1e07b19
--- /dev/null
+++ b/drivers/staging/rt3070/aironet.h
@@ -0,0 +1,210 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	aironet.h
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	Name		Date			Modification logs
+	Paul Lin	04-06-15		Initial
+*/
+
+#ifndef	__AIRONET_H__
+#define	__AIRONET_H__
+
+// Measurement Type definition
+#define	MSRN_TYPE_UNUSED				0
+#define	MSRN_TYPE_CHANNEL_LOAD_REQ		1
+#define	MSRN_TYPE_NOISE_HIST_REQ		2
+#define	MSRN_TYPE_BEACON_REQ			3
+#define	MSRN_TYPE_FRAME_REQ				4
+
+// Scan Mode in Beacon Request
+#define	MSRN_SCAN_MODE_PASSIVE			0
+#define	MSRN_SCAN_MODE_ACTIVE			1
+#define	MSRN_SCAN_MODE_BEACON_TABLE		2
+
+// PHY type definition for Aironet beacon report, CCX 2 table 36-9
+#define	PHY_FH							1
+#define	PHY_DSS							2
+#define	PHY_UNUSED						3
+#define	PHY_OFDM						4
+#define	PHY_HR_DSS						5
+#define	PHY_ERP							6
+
+// RPI table in dBm
+#define	RPI_0			0			//	Power <= -87
+#define	RPI_1			1			//	-87 < Power <= -82
+#define	RPI_2			2			//	-82 < Power <= -77
+#define	RPI_3			3			//	-77 < Power <= -72
+#define	RPI_4			4			//	-72 < Power <= -67
+#define	RPI_5			5			//	-67 < Power <= -62
+#define	RPI_6			6			//	-62 < Power <= -57
+#define	RPI_7			7			//	-57 < Power
+
+// Cisco Aironet IAPP definetions
+#define	AIRONET_IAPP_TYPE					0x32
+#define	AIRONET_IAPP_SUBTYPE_REQUEST		0x01
+#define	AIRONET_IAPP_SUBTYPE_REPORT			0x81
+
+// Measurement Request detail format
+typedef	struct	_MEASUREMENT_REQUEST	{
+	UCHAR	Channel;
+	UCHAR	ScanMode;			// Use only in beacon request, other requests did not use this field
+	USHORT	Duration;
+}	MEASUREMENT_REQUEST, *PMEASUREMENT_REQUEST;
+
+// Beacon Measurement Report
+// All these field might change to UCHAR, because we didn't do anything to these report.
+// We copy all these beacons and report to CCX 2 AP.
+typedef	struct	_BEACON_REPORT	{
+	UCHAR	Channel;
+	UCHAR	Spare;
+	USHORT	Duration;
+	UCHAR	PhyType;			// Definiation is listed above table 36-9
+	UCHAR	RxPower;
+	UCHAR	BSSID[6];
+	UCHAR	ParentTSF[4];
+	UCHAR	TargetTSF[8];
+	USHORT	BeaconInterval;
+	USHORT	CapabilityInfo;
+}	BEACON_REPORT, *PBEACON_REPORT;
+
+// Frame Measurement Report (Optional)
+typedef	struct	_FRAME_REPORT	{
+	UCHAR	Channel;
+	UCHAR	Spare;
+	USHORT	Duration;
+	UCHAR	TA;
+	UCHAR	BSSID[6];
+	UCHAR	RSSI;
+	UCHAR	Count;
+}	FRAME_REPORT, *PFRAME_REPORT;
+
+#pragma pack(1)
+// Channel Load Report
+typedef	struct	_CHANNEL_LOAD_REPORT	{
+	UCHAR	Channel;
+	UCHAR	Spare;
+	USHORT	Duration;
+	UCHAR	CCABusy;
+}	CHANNEL_LOAD_REPORT, *PCHANNEL_LOAD_REPORT;
+#pragma pack()
+
+// Nosie Histogram Report
+typedef	struct	_NOISE_HIST_REPORT	{
+	UCHAR	Channel;
+	UCHAR	Spare;
+	USHORT	Duration;
+	UCHAR	Density[8];
+}	NOISE_HIST_REPORT, *PNOISE_HIST_REPORT;
+
+// Radio Management Capability element
+typedef	struct	_RADIO_MANAGEMENT_CAPABILITY	{
+	UCHAR	Eid;				// TODO: Why the Eid is 1 byte, not normal 2 bytes???
+	UCHAR	Length;
+	UCHAR	AironetOui[3];		// AIronet OUI (00 40 96)
+	UCHAR	Type;				// Type / Version
+	USHORT	Status;				// swap16 required
+}	RADIO_MANAGEMENT_CAPABILITY, *PRADIO_MANAGEMENT_CAPABILITY;
+
+// Measurement Mode Bit definition
+typedef	struct	_MEASUREMENT_MODE	{
+	UCHAR	Rsvd:4;
+	UCHAR	Report:1;
+	UCHAR	NotUsed:1;
+	UCHAR	Enable:1;
+	UCHAR	Parallel:1;
+}	MEASUREMENT_MODE, *PMEASUREMENT_MODE;
+
+// Measurement Request element, This is little endian mode
+typedef	struct	_MEASUREMENT_REQUEST_ELEMENT	{
+	USHORT				Eid;
+	USHORT				Length;				// swap16 required
+	USHORT				Token;				// non-zero unique token
+	UCHAR				Mode;				// Measurement Mode
+	UCHAR				Type;				// Measurement type
+}	MEASUREMENT_REQUEST_ELEMENT, *PMEASUREMENT_REQUEST_ELEMENT;
+
+// Measurement Report element, This is little endian mode
+typedef	struct	_MEASUREMENT_REPORT_ELEMENT	{
+	USHORT				Eid;
+	USHORT				Length;				// swap16 required
+	USHORT				Token;				// non-zero unique token
+	UCHAR				Mode;				// Measurement Mode
+	UCHAR				Type;				// Measurement type
+}	MEASUREMENT_REPORT_ELEMENT, *PMEASUREMENT_REPORT_ELEMENT;
+
+// Cisco Aironet IAPP Frame Header, Network byte order used
+typedef	struct	_AIRONET_IAPP_HEADER {
+	UCHAR	CiscoSnapHeader[8];	// 8 bytes Cisco snap header
+	USHORT	Length;				// IAPP ID & length, remember to swap16 in LE system
+	UCHAR	Type;				// IAPP type
+	UCHAR	SubType;			// IAPP subtype
+	UCHAR	DA[6];				// Destination MAC address
+	UCHAR	SA[6];				// Source MAC address
+	USHORT	Token;				// Dialog token, no need to swap16 since it is for yoken usage only
+}	AIRONET_IAPP_HEADER, *PAIRONET_IAPP_HEADER;
+
+// Radio Measurement Request frame
+typedef	struct	_AIRONET_RM_REQUEST_FRAME	{
+    AIRONET_IAPP_HEADER	IAPP;			// Common header
+	UCHAR				Delay;			// Activation Delay
+	UCHAR				Offset;			// Measurement offset
+}	AIRONET_RM_REQUEST_FRAME, *PAIRONET_RM_REQUEST_FRAME;
+
+// Radio Measurement Report frame
+typedef	struct	_AIRONET_RM_REPORT_FRAME	{
+    AIRONET_IAPP_HEADER	IAPP;			// Common header
+}	AIRONET_RM_REPORT_FRAME, *PAIRONET_RM_REPORT_FRAME;
+
+// Saved element request actions which will saved in StaCfg.
+typedef	struct	_RM_REQUEST_ACTION	{
+	MEASUREMENT_REQUEST_ELEMENT	ReqElem;		// Saved request element
+	MEASUREMENT_REQUEST			Measurement;	// Saved measurement within the request element
+}	RM_REQUEST_ACTION, *PRM_REQUEST_ACTION;
+
+// CCX administration control
+typedef	union	_CCX_CONTROL	{
+	struct	{
+		UINT32		Enable:1;			// Enable CCX2
+		UINT32		LeapEnable:1;		// Enable LEAP at CCX2
+		UINT32		RMEnable:1;			// Radio Measurement Enable
+		UINT32		DCRMEnable:1;		// Non serving channel Radio Measurement enable
+		UINT32		QOSEnable:1;		// Enable QOS for CCX 2.0 support
+		UINT32		FastRoamEnable:1;	// Enable fast roaming
+		UINT32		Rsvd:2;				// Not used
+		UINT32		dBmToRoam:8;		// the condition to roam when receiving Rssi less than this value. It's negative value.
+		UINT32		TuLimit:16;			// Limit for different channel scan
+	}	field;
+	UINT32			word;
+}	CCX_CONTROL, *PCCX_CONTROL;
+
+#endif	// __AIRONET_H__
diff --git a/drivers/staging/rt3070/ap.h b/drivers/staging/rt3070/ap.h
new file mode 100644
index 0000000..f5ba042
--- /dev/null
+++ b/drivers/staging/rt3070/ap.h
@@ -0,0 +1,557 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+    ap.h
+
+    Abstract:
+    Miniport generic portion header file
+
+    Revision History:
+    Who         When          What
+    --------    ----------    ----------------------------------------------
+    Paul Lin    08-01-2002    created
+    James Tan   09-06-2002    modified (Revise NTCRegTable)
+    John Chang  12-22-2004    modified for RT2561/2661. merge with STA driver
+*/
+#ifndef __AP_H__
+#define __AP_H__
+
+
+
+// ========================= AP RTMP.h ================================
+
+
+
+// =============================================================
+//      Function Prototypes
+// =============================================================
+
+// ap_data.c
+
+BOOLEAN APBridgeToWirelessSta(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  PUCHAR          pHeader,
+    IN  UINT            HdrLen,
+    IN  PUCHAR          pData,
+    IN  UINT            DataLen,
+    IN  ULONG           fromwdsidx);
+
+BOOLEAN APHandleRxDoneInterrupt(
+    IN  PRTMP_ADAPTER   pAd);
+
+VOID	APSendPackets(
+	IN	NDIS_HANDLE		MiniportAdapterContext,
+	IN	PPNDIS_PACKET	ppPacketArray,
+	IN	UINT			NumberOfPackets);
+
+NDIS_STATUS APSendPacket(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  PNDIS_PACKET    pPacket);
+
+
+NDIS_STATUS APHardTransmit(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	UCHAR			QueIdx);
+
+VOID APRxEAPOLFrameIndicate(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	MAC_TABLE_ENTRY	*pEntry,
+	IN	RX_BLK			*pRxBlk,
+	IN	UCHAR			FromWhichBSSID);
+
+NDIS_STATUS APCheckRxError(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PRT28XX_RXD_STRUC		pRxD,
+	IN	UCHAR			Wcid);
+
+BOOLEAN APCheckClass2Class3Error(
+    IN  PRTMP_ADAPTER   pAd,
+	IN ULONG Wcid,
+	IN  PHEADER_802_11  pHeader);
+
+VOID APHandleRxPsPoll(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pAddr,
+	IN	USHORT			Aid,
+    IN	BOOLEAN			isActive);
+
+VOID    RTMPDescriptorEndianChange(
+    IN  PUCHAR          pData,
+    IN  ULONG           DescriptorType);
+
+VOID    RTMPFrameEndianChange(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  PUCHAR          pData,
+    IN  ULONG           Dir,
+    IN  BOOLEAN         FromRxDoneInt);
+
+// ap_assoc.c
+
+VOID APAssocStateMachineInit(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  STATE_MACHINE *S,
+    OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID  APPeerAssocReqAction(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  MLME_QUEUE_ELEM *Elem);
+
+VOID  APPeerReassocReqAction(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  MLME_QUEUE_ELEM *Elem);
+
+VOID  APPeerDisassocReqAction(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  MLME_QUEUE_ELEM *Elem);
+
+VOID MbssKickOutStas(
+	IN PRTMP_ADAPTER pAd,
+	IN INT apidx,
+	IN USHORT Reason);
+
+VOID APMlmeKickOutSta(
+    IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pStaAddr,
+	IN UCHAR Wcid,
+	IN USHORT Reason);
+
+VOID APMlmeDisassocReqAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem);
+
+VOID  APCls3errAction(
+    IN  PRTMP_ADAPTER   pAd,
+	IN 	ULONG Wcid,
+    IN	PHEADER_802_11	pHeader);
+
+
+USHORT APBuildAssociation(
+    IN PRTMP_ADAPTER pAd,
+    IN MAC_TABLE_ENTRY *pEntry,
+    IN USHORT CapabilityInfo,
+    IN UCHAR  MaxSupportedRateIn500Kbps,
+    IN UCHAR  *RSN,
+    IN UCHAR  *pRSNLen,
+    IN BOOLEAN bWmmCapable,
+    IN ULONG  RalinkIe,
+#ifdef DOT11N_DRAFT3
+    IN EXT_CAP_INFO_ELEMENT ExtCapInfo,
+#endif // DOT11N_DRAFT3 //
+	IN HT_CAPABILITY_IE		*pHtCapability,
+	IN UCHAR		 HtCapabilityLen,
+    OUT USHORT *pAid);
+
+/*
+VOID	RTMPAddClientSec(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR	BssIdx,
+	IN UCHAR		 KeyIdx,
+	IN UCHAR		 CipherAlg,
+	IN PUCHAR		 pKey,
+	IN PUCHAR		 pTxMic,
+	IN PUCHAR		 pRxMic,
+	IN MAC_TABLE_ENTRY *pEntry);
+*/
+
+// ap_auth.c
+
+void APAuthStateMachineInit(
+    IN PRTMP_ADAPTER pAd,
+    IN STATE_MACHINE *Sm,
+    OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID APMlmeDeauthReqAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem);
+
+VOID APCls2errAction(
+    IN PRTMP_ADAPTER pAd,
+	IN 	ULONG Wcid,
+    IN	PHEADER_802_11	pHeader);
+
+// ap_authrsp.c
+
+VOID APAuthRspStateMachineInit(
+    IN PRTMP_ADAPTER pAd,
+    IN PSTATE_MACHINE Sm,
+    IN STATE_MACHINE_FUNC Trans[]);
+
+VOID APPeerAuthAtAuthRspIdleAction(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  MLME_QUEUE_ELEM *Elem);
+
+VOID APPeerDeauthReqAction(
+    IN PRTMP_ADAPTER	pAd,
+    IN MLME_QUEUE_ELEM *Elem);
+
+VOID APPeerAuthSimpleRspGenAndSend(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  PHEADER_802_11 pHdr80211,
+    IN  USHORT Alg,
+    IN  USHORT Seq,
+    IN  USHORT StatusCode);
+
+// ap_connect.c
+
+BOOLEAN BeaconTransmitRequired(
+	IN PRTMP_ADAPTER	pAd,
+	IN INT				apidx);
+
+VOID APMakeBssBeacon(
+    IN  PRTMP_ADAPTER   pAd,
+	IN	INT				apidx);
+
+VOID  APUpdateBeaconFrame(
+    IN  PRTMP_ADAPTER   pAd,
+	IN	INT				apidx);
+
+VOID APMakeAllBssBeacon(
+    IN  PRTMP_ADAPTER   pAd);
+
+VOID  APUpdateAllBeaconFrame(
+    IN  PRTMP_ADAPTER   pAd);
+
+
+// ap_sync.c
+
+VOID APSyncStateMachineInit(
+    IN PRTMP_ADAPTER pAd,
+    IN STATE_MACHINE *Sm,
+    OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID APScanTimeout(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3);
+
+VOID APInvalidStateWhenScan(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem);
+
+VOID APScanTimeoutAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem);
+
+VOID APPeerProbeReqAction(
+    IN  PRTMP_ADAPTER pAd,
+    IN  MLME_QUEUE_ELEM *Elem);
+
+VOID APPeerBeaconAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem);
+
+VOID APMlmeScanReqAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem);
+
+VOID APPeerBeaconAtScanAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem);
+
+VOID APScanCnclAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem);
+
+VOID ApSiteSurvey(
+	IN PRTMP_ADAPTER pAd);
+
+VOID SupportRate(
+	IN PUCHAR SupRate,
+	IN UCHAR SupRateLen,
+	IN PUCHAR ExtRate,
+	IN UCHAR ExtRateLen,
+	OUT PUCHAR *Rates,
+	OUT PUCHAR RatesLen,
+	OUT PUCHAR pMaxSupportRate);
+
+
+BOOLEAN ApScanRunning(
+	IN PRTMP_ADAPTER pAd);
+
+#ifdef DOT11N_DRAFT3
+VOID APOverlappingBSSScan(
+	IN RTMP_ADAPTER *pAd);
+#endif // DOT11N_DRAFT3 //
+
+// ap_wpa.c
+
+VOID APWpaStateMachineInit(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  STATE_MACHINE *Sm,
+    OUT STATE_MACHINE_FUNC Trans[]);
+
+// ap_mlme.c
+
+VOID APMlmePeriodicExec(
+    IN  PRTMP_ADAPTER   pAd);
+
+VOID APMlmeSelectTxRateTable(
+	IN PRTMP_ADAPTER		pAd,
+	IN PMAC_TABLE_ENTRY		pEntry,
+	IN PUCHAR				*ppTable,
+	IN PUCHAR				pTableSize,
+	IN PUCHAR				pInitTxRateIdx);
+
+VOID APMlmeSetTxRate(
+	IN PRTMP_ADAPTER		pAd,
+	IN PMAC_TABLE_ENTRY		pEntry,
+	IN PRTMP_TX_RATE_SWITCH	pTxRate);
+
+VOID APMlmeDynamicTxRateSwitching(
+    IN PRTMP_ADAPTER pAd);
+
+VOID APQuickResponeForRateUpExec(
+    IN PVOID SystemSpecific1,
+    IN PVOID FunctionContext,
+    IN PVOID SystemSpecific2,
+    IN PVOID SystemSpecific3);
+
+BOOLEAN APMsgTypeSubst(
+    IN PRTMP_ADAPTER pAd,
+    IN PFRAME_802_11 pFrame,
+    OUT INT *Machine,
+    OUT INT *MsgType);
+
+VOID APQuickResponeForRateUpExec(
+    IN PVOID SystemSpecific1,
+    IN PVOID FunctionContext,
+    IN PVOID SystemSpecific2,
+    IN PVOID SystemSpecific3);
+
+#ifdef RT2870
+VOID BeaconUpdateExec(
+    IN PVOID SystemSpecific1,
+    IN PVOID FunctionContext,
+    IN PVOID SystemSpecific2,
+    IN PVOID SystemSpecific3);
+#endif // RT2870 //
+
+VOID RTMPSetPiggyBack(
+	IN PRTMP_ADAPTER	pAd,
+	IN BOOLEAN			bPiggyBack);
+
+VOID APAsicEvaluateRxAnt(
+	IN PRTMP_ADAPTER	pAd);
+
+VOID APAsicRxAntEvalTimeout(
+	IN PRTMP_ADAPTER	pAd);
+
+// ap.c
+
+VOID APSwitchChannel(
+	IN PRTMP_ADAPTER pAd,
+	IN INT Channel);
+
+NDIS_STATUS APInitialize(
+    IN  PRTMP_ADAPTER   pAd);
+
+VOID APShutdown(
+    IN PRTMP_ADAPTER    pAd);
+
+VOID APStartUp(
+    IN  PRTMP_ADAPTER   pAd);
+
+VOID APStop(
+    IN  PRTMP_ADAPTER   pAd);
+
+VOID APCleanupPsQueue(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  PQUEUE_HEADER   pQueue);
+
+VOID MacTableReset(
+    IN  PRTMP_ADAPTER   pAd);
+
+MAC_TABLE_ENTRY *MacTableInsertEntry(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  PUCHAR          pAddr,
+	IN	UCHAR			apidx,
+	IN BOOLEAN	CleanAll);
+
+BOOLEAN MacTableDeleteEntry(
+    IN  PRTMP_ADAPTER   pAd,
+	IN USHORT wcid,
+    IN  PUCHAR          pAddr);
+
+MAC_TABLE_ENTRY *MacTableLookup(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  PUCHAR          pAddr);
+
+VOID MacTableMaintenance(
+    IN PRTMP_ADAPTER pAd);
+
+UINT32 MacTableAssocStaNumGet(
+	IN PRTMP_ADAPTER pAd);
+
+MAC_TABLE_ENTRY *APSsPsInquiry(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  PUCHAR          pAddr,
+    OUT SST             *Sst,
+    OUT USHORT          *Aid,
+    OUT UCHAR           *PsMode,
+    OUT UCHAR           *Rate);
+
+BOOLEAN APPsIndicate(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  PUCHAR          pAddr,
+	IN ULONG Wcid,
+    IN  UCHAR           Psm);
+
+VOID ApLogEvent(
+    IN PRTMP_ADAPTER    pAd,
+    IN PUCHAR           pAddr,
+    IN USHORT           Event);
+
+#ifdef DOT11_N_SUPPORT
+VOID APUpdateOperationMode(
+    IN PRTMP_ADAPTER pAd);
+#endif // DOT11_N_SUPPORT //
+
+VOID APUpdateCapabilityAndErpIe(
+	IN PRTMP_ADAPTER pAd);
+
+BOOLEAN ApCheckAccessControlList(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR        pAddr,
+	IN UCHAR         Apidx);
+
+VOID ApUpdateAccessControlList(
+    IN PRTMP_ADAPTER pAd,
+    IN UCHAR         Apidx);
+
+VOID ApEnqueueNullFrame(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR        pAddr,
+	IN UCHAR         TxRate,
+	IN UCHAR         PID,
+	IN UCHAR         apidx,
+    IN BOOLEAN       bQosNull,
+    IN BOOLEAN       bEOSP,
+    IN UCHAR         OldUP);
+
+VOID ApSendFrame(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  PVOID           pBuffer,
+    IN  ULONG           Length,
+    IN  UCHAR           TxRate,
+    IN  UCHAR           PID);
+
+VOID ApEnqueueAckFrame(
+    IN PRTMP_ADAPTER pAd,
+    IN PUCHAR        pAddr,
+    IN UCHAR         TxRate,
+	IN UCHAR         apidx);
+
+UCHAR APAutoSelectChannel(
+	IN PRTMP_ADAPTER pAd,
+	IN BOOLEAN Optimal);
+
+// ap_sanity.c
+
+
+BOOLEAN PeerAssocReqCmmSanity(
+    IN PRTMP_ADAPTER pAd,
+	IN BOOLEAN isRessoc,
+    IN VOID *Msg,
+    IN ULONG MsgLen,
+    OUT PUCHAR pAddr2,
+    OUT USHORT *pCapabilityInfo,
+    OUT USHORT *pListenInterval,
+    OUT PUCHAR pApAddr,
+    OUT UCHAR *pSsidLen,
+    OUT char *Ssid,
+    OUT UCHAR *pRatesLen,
+    OUT UCHAR Rates[],
+    OUT UCHAR *RSN,
+    OUT UCHAR *pRSNLen,
+    OUT BOOLEAN *pbWmmCapable,
+    OUT ULONG  *pRalinkIe,
+#ifdef DOT11N_DRAFT3
+    OUT EXT_CAP_INFO_ELEMENT	*pExtCapInfo,
+#endif // DOT11N_DRAFT3 //
+    OUT UCHAR		 *pHtCapabilityLen,
+    OUT HT_CAPABILITY_IE *pHtCapability);
+
+
+BOOLEAN PeerDisassocReqSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *Msg,
+    IN ULONG MsgLen,
+    OUT PUCHAR pAddr2,
+    OUT USHORT *Reason);
+
+BOOLEAN PeerDeauthReqSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *Msg,
+    IN ULONG MsgLen,
+    OUT PUCHAR pAddr2,
+    OUT USHORT *Reason);
+
+BOOLEAN APPeerAuthSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *Msg,
+    IN ULONG MsgLen,
+	OUT PUCHAR pAddr1,
+    OUT PUCHAR pAddr2,
+    OUT USHORT *Alg,
+    OUT USHORT *Seq,
+    OUT USHORT *Status,
+    CHAR *ChlgText);
+
+BOOLEAN APPeerProbeReqSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *Msg,
+    IN ULONG MsgLen,
+    OUT PUCHAR pAddr2,
+    OUT CHAR Ssid[],
+    OUT UCHAR *SsidLen);
+
+BOOLEAN APPeerBeaconAndProbeRspSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *Msg,
+    IN ULONG MsgLen,
+    OUT PUCHAR pAddr2,
+    OUT PUCHAR pBssid,
+    OUT CHAR Ssid[],
+    OUT UCHAR *SsidLen,
+    OUT UCHAR *BssType,
+    OUT USHORT *BeaconPeriod,
+    OUT UCHAR *Channel,
+    OUT LARGE_INTEGER *Timestamp,
+    OUT USHORT *CapabilityInfo,
+    OUT UCHAR Rate[],
+    OUT UCHAR *RateLen,
+    OUT BOOLEAN *ExtendedRateIeExist,
+    OUT UCHAR *Erp);
+
+
+// ================== end of AP RTMP.h ========================
+
+
+#endif  // __AP_H__
+
diff --git a/drivers/staging/rt3070/chlist.h b/drivers/staging/rt3070/chlist.h
new file mode 100644
index 0000000..7151e86
--- /dev/null
+++ b/drivers/staging/rt3070/chlist.h
@@ -0,0 +1,1253 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	chlist.c
+
+	Abstract:
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+	Fonchi Wu   2007-12-19    created
+*/
+
+#ifndef __CHLIST_H__
+#define __CHLIST_H__
+
+#include "rtmp_type.h"
+#include "rtmp_def.h"
+
+
+#define ODOR			0
+#define IDOR			1
+#define BOTH			2
+
+#define BAND_5G         0
+#define BAND_24G        1
+#define BAND_BOTH       2
+
+typedef struct _CH_DESP {
+	UCHAR FirstChannel;
+	UCHAR NumOfCh;
+	CHAR MaxTxPwr;			// dBm
+	UCHAR Geography;			// 0:out door, 1:in door, 2:both
+	BOOLEAN DfsReq;			// Dfs require, 0: No, 1: yes.
+} CH_DESP, *PCH_DESP;
+
+typedef struct _CH_REGION {
+	UCHAR CountReg[3];
+	UCHAR DfsType;			// 0: CE, 1: FCC, 2: JAP, 3:JAP_W53, JAP_W56
+	CH_DESP ChDesp[10];
+} CH_REGION, *PCH_REGION;
+
+static CH_REGION ChRegion[] =
+{
+		{	// Antigua and Berbuda
+			"AG",
+			CE,
+			{
+				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
+				{ 52,  4,  23, BOTH, FALSE},	// 5G, ch 52~64
+				{ 100, 11, 30, BOTH, FALSE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// Argentina
+			"AR",
+			CE,
+			{
+				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
+				{ 149, 4,  30, BOTH, FALSE},	// 5G, ch 149~161
+				{ 0},							// end
+			}
+		},
+
+		{	// Aruba
+			"AW",
+			CE,
+			{
+				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
+				{ 52,  4,  23, BOTH, FALSE},	// 5G, ch 52~64
+				{ 100, 11, 30, BOTH, FALSE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// Australia
+			"AU",
+			CE,
+			{
+				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
+				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
+				{ 149, 5,  30, BOTH, FALSE},	// 5G, ch 149~165
+				{ 0},							// end
+			}
+		},
+
+		{	// Austria
+			"AT",
+			CE,
+			{
+				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,  4,  23, IDOR, TRUE},		// 5G, ch 36~48
+				{ 52,  4,  23, IDOR, TRUE},		// 5G, ch 52~64
+				{ 100, 11, 30, BOTH, TRUE},		// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// Bahamas
+			"BS",
+			CE,
+			{
+				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
+				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
+				{ 149, 5,  30, BOTH, FALSE},	// 5G, ch 149~165
+				{ 0},							// end
+			}
+		},
+
+		{	// Barbados
+			"BB",
+			CE,
+			{
+				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
+				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
+				{ 100, 11, 30, BOTH, FALSE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// Bermuda
+			"BM",
+			CE,
+			{
+				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
+				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
+				{ 100, 11, 30, BOTH, FALSE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// Brazil
+			"BR",
+			CE,
+			{
+				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
+				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
+				{ 100, 11, 24, BOTH, FALSE},	// 5G, ch 100~140
+				{ 149, 5,  30, BOTH, FALSE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// Belgium
+			"BE",
+			CE,
+			{
+				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,  4,  18, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52,  4,  18, IDOR, FALSE},	// 5G, ch 52~64
+				{ 0},							// end
+			}
+		},
+
+		{	// Bulgaria
+			"BG",
+			CE,
+			{
+				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,  4,  23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52,  4,  23, IDOR, TRUE},	// 5G, ch 52~64
+				{ 100, 11, 30, ODOR, TRUE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// Canada
+			"CA",
+			CE,
+			{
+				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
+				{ 52,  4,  23, BOTH, FALSE},	// 5G, ch 52~64
+				{ 149, 5,  30, BOTH, FALSE},	// 5G, ch 149~165
+				{ 0},							// end
+			}
+		},
+
+		{	// Cayman IsLands
+			"KY",
+			CE,
+			{
+				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,  4,  23, BOTH, FALSE},	// 5G, ch 36~48
+				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
+				{ 100, 11, 30, BOTH, FALSE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// Chile
+			"CL",
+			CE,
+			{
+				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,  4,  20, BOTH, FALSE},	// 5G, ch 36~48
+				{ 52,  4,  20, BOTH, FALSE},	// 5G, ch 52~64
+				{ 149, 5,  20, BOTH, FALSE},	// 5G, ch 149~165
+				{ 0},							// end
+			}
+		},
+
+		{	// China
+			"CN",
+			CE,
+			{
+				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 149, 4,  27, BOTH, FALSE},	// 5G, ch 149~161
+				{ 0},							// end
+			}
+		},
+
+		{	// Colombia
+			"CO",
+			CE,
+			{
+				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,  4,  17, BOTH, FALSE},	// 5G, ch 36~48
+				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
+				{ 100, 11, 30, BOTH, FALSE},	// 5G, ch 100~140
+				{ 149, 5,  30, BOTH, FALSE},	// 5G, ch 149~165
+				{ 0},							// end
+			}
+		},
+
+		{	// Costa Rica
+			"CR",
+			CE,
+			{
+				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,  4,  17, BOTH, FALSE},	// 5G, ch 36~48
+				{ 52,  4,  24, BOTH, FALSE},	// 5G, ch 52~64
+				{ 149, 4,  30, BOTH, FALSE},	// 5G, ch 149~161
+				{ 0},							// end
+			}
+		},
+
+		{	// Cyprus
+			"CY",
+			CE,
+			{
+				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,  4,  23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52,  4,  24, IDOR, TRUE},		// 5G, ch 52~64
+				{ 100, 11, 30, BOTH, TRUE},		// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// Czech_Republic
+			"CZ",
+			CE,
+			{
+				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,  4,  23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52,  4,  23, IDOR, TRUE},		// 5G, ch 52~64
+				{ 0},							// end
+			}
+		},
+
+		{	// Denmark
+			"DK",
+			CE,
+			{
+				{ 1,   13, 20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,  4,  23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52,  4,  23, IDOR, TRUE},		// 5G, ch 52~64
+				{ 100, 11, 30, BOTH, TRUE},		// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// Dominican Republic
+			"DO",
+			CE,
+			{
+				{ 1,   0,  20, BOTH, FALSE},	// 2.4 G, ch 0
+				{ 149, 4,  20, BOTH, FALSE},	// 5G, ch 149~161
+				{ 0},							// end
+			}
+		},
+
+		{	// Equador
+			"EC",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 100, 11,  27, BOTH, FALSE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// El Salvador
+			"SV",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,  4,   23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52,  4,   30, BOTH, TRUE},	// 5G, ch 52~64
+				{ 149, 4,   36, BOTH, TRUE},	// 5G, ch 149~165
+				{ 0},							// end
+			}
+		},
+
+		{	// Finland
+			"FI",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,  4,   23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52,  4,   23, IDOR, TRUE},	// 5G, ch 52~64
+				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// France
+			"FR",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,  4,   23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52,  4,   23, IDOR, TRUE},	// 5G, ch 52~64
+				{ 0},							// end
+			}
+		},
+
+		{	// Germany
+			"DE",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,  4,   23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52,  4,   23, IDOR, TRUE},	// 5G, ch 52~64
+				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// Greece
+			"GR",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,  4,   23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52,  4,   23, IDOR, TRUE},	// 5G, ch 52~64
+				{ 100, 11,  30, ODOR, TRUE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// Guam
+			"GU",
+			CE,
+			{
+				{ 1,   11,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
+				{ 36,  4,   17, BOTH, FALSE},	// 5G, ch 36~48
+				{ 52,  4,   24, BOTH, FALSE},	// 5G, ch 52~64
+				{ 100, 11,  30, BOTH, FALSE},	// 5G, ch 100~140
+				{ 149,  5,  30, BOTH, FALSE},	// 5G, ch 149~165
+				{ 0},							// end
+			}
+		},
+
+		{	// Guatemala
+			"GT",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,  4,   17, BOTH, FALSE},	// 5G, ch 36~48
+				{ 52,  4,   24, BOTH, FALSE},	// 5G, ch 52~64
+				{ 149,  4,  30, BOTH, FALSE},	// 5G, ch 149~161
+				{ 0},							// end
+			}
+		},
+
+		{	// Haiti
+			"HT",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,  4,   17, BOTH, FALSE},	// 5G, ch 36~48
+				{ 52,  4,   24, BOTH, FALSE},	// 5G, ch 52~64
+				{ 149,  4,  30, BOTH, FALSE},	// 5G, ch 149~161
+				{ 0},							// end
+			}
+		},
+
+		{	// Honduras
+			"HN",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 149,  4,  27, BOTH, FALSE},	// 5G, ch 149~161
+				{ 0},							// end
+			}
+		},
+
+		{	// Hong Kong
+			"HK",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52,   4,  23, IDOR, FALSE},	// 5G, ch 52~64
+				{ 149,  4,  30, BOTH, FALSE},	// 5G, ch 149~161
+				{ 0},							// end
+			}
+		},
+
+		{	// Hungary
+			"HU",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
+				{ 0},							// end
+			}
+		},
+
+		{	// Iceland
+			"IS",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
+				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// India
+			"IN",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 149, 	4,  24, IDOR, FALSE},	// 5G, ch 149~161
+				{ 0},							// end
+			}
+		},
+
+		{	// Indonesia
+			"ID",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 149, 	4,  27, BOTH, FALSE},	// 5G, ch 149~161
+				{ 0},							// end
+			}
+		},
+
+		{	// Ireland
+			"IE",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52, 	4,  23, IDOR, TRUE},	// 5G, ch 52~64
+				{ 100, 11,  30, ODOR, TRUE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// Israel
+			"IL",
+			CE,
+			{
+				{ 1,    3,  20, IDOR, FALSE},	// 2.4 G, ch 1~3
+				{ 4, 	6,  20, BOTH, FALSE},	// 2.4 G, ch 4~9
+				{ 10, 	4,  20, IDOR, FALSE},	// 2.4 G, ch 10~13
+				{ 0},							// end
+			}
+		},
+
+		{	// Italy
+			"IT",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52, 	4,  23, IDOR, TRUE},	// 5G, ch 52~64
+				{ 100, 11,  30, ODOR, TRUE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// Japan
+			"JP",
+			JAP,
+			{
+				{ 1,   14,  20, BOTH, FALSE},	// 2.4 G, ch 1~14
+				{ 34, 	4,  23, IDOR, FALSE},	// 5G, ch 34~46
+				{ 0},							// end
+			}
+		},
+
+		{	// Jordan
+			"JO",
+			CE,
+			{
+				{ 1,   13,  20, IDOR, FALSE},	// 2.4 G, ch 1~13
+				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 149, 	4,  23, IDOR, FALSE},	// 5G, ch 149~161
+				{ 0},							// end
+			}
+		},
+
+		{	// Latvia
+			"LV",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52, 	4,  23, IDOR, TRUE},	// 5G, ch 52~64
+				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// Liechtenstein
+			"LI",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 52, 	4,  23, IDOR, TRUE},	// 5G, ch 52~64
+				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// Lithuania
+			"LT",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52, 	4,  23, IDOR, TRUE},	// 5G, ch 52~64
+				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// Luxemburg
+			"LU",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52, 	4,  23, IDOR, TRUE},	// 5G, ch 52~64
+				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// Malaysia
+			"MY",
+			CE,
+			{
+				{ 36, 	4,  23, BOTH, FALSE},	// 5G, ch 36~48
+				{ 52, 	4,  23, BOTH, FALSE},	// 5G, ch 52~64
+				{ 149,  5,  20, BOTH, FALSE},	// 5G, ch 149~165
+				{ 0},							// end
+			}
+		},
+
+		{	// Malta
+			"MT",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52, 	4,  23, IDOR, TRUE},	// 5G, ch 52~64
+				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// Marocco
+			"MA",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36, 	4,  24, IDOR, FALSE},	// 5G, ch 36~48
+				{ 0},							// end
+			}
+		},
+
+		{	// Mexico
+			"MX",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36, 	4,  23, BOTH, FALSE},	// 5G, ch 36~48
+				{ 52, 	4,  24, BOTH, FALSE},	// 5G, ch 52~64
+				{ 149,  5,  30, IDOR, FALSE},	// 5G, ch 149~165
+				{ 0},							// end
+			}
+		},
+
+		{	// Netherlands
+			"NL",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52, 	4,  24, IDOR, TRUE},	// 5G, ch 52~64
+				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// New Zealand
+			"NZ",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36, 	4,  24, BOTH, FALSE},	// 5G, ch 36~48
+				{ 52, 	4,  24, BOTH, FALSE},	// 5G, ch 52~64
+				{ 149,  4,  30, BOTH, FALSE},	// 5G, ch 149~161
+				{ 0},							// end
+			}
+		},
+
+		{	// Norway
+			"NO",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36, 	4,  24, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52, 	4,  24, IDOR, TRUE},	// 5G, ch 52~64
+				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 149~161
+				{ 0},							// end
+			}
+		},
+
+		{	// Peru
+			"PE",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 149,  4,  27, BOTH, FALSE},	// 5G, ch 149~161
+				{ 0},							// end
+			}
+		},
+
+		{	// Portugal
+			"PT",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
+				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// Poland
+			"PL",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
+				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// Romania
+			"RO",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
+				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// Russia
+			"RU",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 149,  4,  20, IDOR, FALSE},	// 5G, ch 149~161
+				{ 0},							// end
+			}
+		},
+
+		{	// Saudi Arabia
+			"SA",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,   4,  23, BOTH, FALSE},	// 5G, ch 36~48
+				{ 52,   4,  23, BOTH, FALSE},	// 5G, ch 52~64
+				{ 149,  4,  23, BOTH, FALSE},	// 5G, ch 149~161
+				{ 0},							// end
+			}
+		},
+
+		{	// Serbia_and_Montenegro
+			"CS",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 0},							// end
+			}
+		},
+
+		{	// Singapore
+			"SG",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,   4,  23, BOTH, FALSE},	// 5G, ch 36~48
+				{ 52,   4,  23, BOTH, FALSE},	// 5G, ch 52~64
+				{ 149,  4,  20, BOTH, FALSE},	// 5G, ch 149~161
+				{ 0},							// end
+			}
+		},
+
+		{	// Slovakia
+			"SK",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
+				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// Slovenia
+			"SI",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
+				{ 0},							// end
+			}
+		},
+
+		{	// South Africa
+			"ZA",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,   4,  23, BOTH, FALSE},	// 5G, ch 36~48
+				{ 52,   4,  23, IDOR, FALSE},	// 5G, ch 52~64
+				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
+				{ 149,  4,  30, BOTH, FALSE},	// 5G, ch 149~161
+				{ 0},							// end
+			}
+		},
+
+		{	// South Korea
+			"KR",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,   4,  20, BOTH, FALSE},	// 5G, ch 36~48
+				{ 52,   4,  20, BOTH, FALSE},	// 5G, ch 52~64
+				{ 100,  8,  20, BOTH, FALSE},	// 5G, ch 100~128
+				{ 149,  4,  20, BOTH, FALSE},	// 5G, ch 149~161
+				{ 0},							// end
+			}
+		},
+
+		{	// Spain
+			"ES",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,   4,  17, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
+				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// Sweden
+			"SE",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
+				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// Switzerland
+			"CH",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~13
+				{ 36,   4,  23, IDOR, TRUE},	// 5G, ch 36~48
+				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
+				{ 0},							// end
+			}
+		},
+
+		{	// Taiwan
+			"TW",
+			CE,
+			{
+				{ 1,   11,  30, BOTH, FALSE},	// 2.4 G, ch 1~11
+				{ 52,   4,  23, IDOR, FALSE},	// 5G, ch 52~64
+				{ 0},							// end
+			}
+		},
+
+		{	// Turkey
+			"TR",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
+				{ 36,   4,  23, BOTH, FALSE},	// 5G, ch 36~48
+				{ 52,   4,  23, BOTH, FALSE},	// 5G, ch 52~64
+				{ 0},							// end
+			}
+		},
+
+		{	// UK
+			"GB",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
+				{ 36,   4,  23, IDOR, FALSE},	// 5G, ch 52~64
+				{ 52,   4,  23, IDOR, TRUE},	// 5G, ch 52~64
+				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
+				{ 0},							// end
+			}
+		},
+
+		{	// Ukraine
+			"UA",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
+				{ 0},							// end
+			}
+		},
+
+		{	// United_Arab_Emirates
+			"AE",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
+				{ 0},							// end
+			}
+		},
+
+		{	// United_States
+			"US",
+			CE,
+			{
+				{ 1,   11,  30, BOTH, FALSE},	// 2.4 G, ch 1~11
+				{ 36,   4,  17, IDOR, FALSE},	// 5G, ch 52~64
+				{ 52,   4,  24, BOTH, TRUE},	// 5G, ch 52~64
+				{ 100, 11,  30, BOTH, TRUE},	// 5G, ch 100~140
+				{ 149,  5,  30, BOTH, FALSE},	// 5G, ch 149~165
+				{ 0},							// end
+			}
+		},
+
+		{	// Venezuela
+			"VE",
+			CE,
+			{
+				{ 1,   13,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
+				{ 149,  4,  27, BOTH, FALSE},	// 5G, ch 149~161
+				{ 0},							// end
+			}
+		},
+
+		{	// Default
+			"",
+			CE,
+			{
+				{ 1,   11,  20, BOTH, FALSE},	// 2.4 G, ch 1~11
+				{ 36,   4,  20, BOTH, FALSE},	// 5G, ch 52~64
+				{ 52,   4,  20, BOTH, FALSE},	// 5G, ch 52~64
+				{ 100, 11,  20, BOTH, FALSE},	// 5G, ch 100~140
+				{ 149,  5,  20, BOTH, FALSE},	// 5G, ch 149~165
+				{ 0},							// end
+			}
+		},
+};
+
+static inline PCH_REGION GetChRegion(
+	IN PUCHAR CntryCode)
+{
+	INT loop = 0;
+	PCH_REGION pChRegion = NULL;
+
+	while (strcmp(ChRegion[loop].CountReg, "") != 0)
+	{
+		if (strncmp(ChRegion[loop].CountReg, CntryCode, 2) == 0)
+		{
+			pChRegion = &ChRegion[loop];
+			break;
+		}
+		loop++;
+	}
+
+	if (pChRegion == NULL)
+		pChRegion = &ChRegion[loop];
+	return pChRegion;
+}
+
+static inline VOID ChBandCheck(
+	IN UCHAR PhyMode,
+	OUT PUCHAR pChType)
+{
+	switch(PhyMode)
+	{
+		case PHY_11A:
+#ifdef DOT11_N_SUPPORT
+		case PHY_11AN_MIXED:
+#endif // DOT11_N_SUPPORT //
+			*pChType = BAND_5G;
+			break;
+		case PHY_11ABG_MIXED:
+#ifdef DOT11_N_SUPPORT
+		case PHY_11AGN_MIXED:
+		case PHY_11ABGN_MIXED:
+#endif // DOT11_N_SUPPORT //
+			*pChType = BAND_BOTH;
+			break;
+
+		default:
+			*pChType = BAND_24G;
+			break;
+	}
+}
+
+static inline UCHAR FillChList(
+	IN PRTMP_ADAPTER pAd,
+	IN PCH_DESP pChDesp,
+	IN UCHAR Offset,
+	IN UCHAR increment)
+{
+	INT i, j, l;
+	UCHAR channel;
+
+	j = Offset;
+	for (i = 0; i < pChDesp->NumOfCh; i++)
+	{
+		channel = pChDesp->FirstChannel + i * increment;
+		for (l=0; l<MAX_NUM_OF_CHANNELS; l++)
+		{
+			if (channel == pAd->TxPower[l].Channel)
+			{
+				pAd->ChannelList[j].Power = pAd->TxPower[l].Power;
+				pAd->ChannelList[j].Power2 = pAd->TxPower[l].Power2;
+				break;
+			}
+		}
+		if (l == MAX_NUM_OF_CHANNELS)
+			continue;
+
+		pAd->ChannelList[j].Channel = pChDesp->FirstChannel + i * increment;
+		pAd->ChannelList[j].MaxTxPwr = pChDesp->MaxTxPwr;
+		pAd->ChannelList[j].DfsReq = pChDesp->DfsReq;
+		j++;
+	}
+	pAd->ChannelListNum = j;
+
+	return j;
+}
+
+static inline VOID CreateChList(
+	IN PRTMP_ADAPTER pAd,
+	IN PCH_REGION pChRegion,
+	IN UCHAR Geography)
+{
+	INT i;
+	UCHAR offset = 0;
+	PCH_DESP pChDesp;
+	UCHAR ChType;
+	UCHAR increment;
+
+	if (pChRegion == NULL)
+		return;
+
+	ChBandCheck(pAd->CommonCfg.PhyMode, &ChType);
+
+	for (i=0; i<10; i++)
+	{
+		pChDesp = &pChRegion->ChDesp[i];
+		if (pChDesp->FirstChannel == 0)
+			break;
+
+		if (ChType == BAND_5G)
+		{
+			if (pChDesp->FirstChannel <= 14)
+				continue;
+		}
+		else if (ChType == BAND_24G)
+		{
+			if (pChDesp->FirstChannel > 14)
+				continue;
+		}
+
+		if ((pChDesp->Geography == BOTH)
+			|| (pChDesp->Geography == Geography))
+        {
+			if (pChDesp->FirstChannel > 14)
+                increment = 4;
+            else
+                increment = 1;
+			offset = FillChList(pAd, pChDesp, offset, increment);
+        }
+	}
+}
+
+static inline VOID BuildChannelListEx(
+	IN PRTMP_ADAPTER pAd)
+{
+	PCH_REGION pChReg;
+
+	pChReg = GetChRegion(pAd->CommonCfg.CountryCode);
+	CreateChList(pAd, pChReg, pAd->CommonCfg.Geography);
+}
+
+static inline VOID BuildBeaconChList(
+	IN PRTMP_ADAPTER pAd,
+	OUT PUCHAR pBuf,
+	OUT	PULONG pBufLen)
+{
+	INT i;
+	ULONG TmpLen;
+	PCH_REGION pChRegion;
+	PCH_DESP pChDesp;
+	UCHAR ChType;
+
+	pChRegion = GetChRegion(pAd->CommonCfg.CountryCode);
+
+	if (pChRegion == NULL)
+		return;
+
+	ChBandCheck(pAd->CommonCfg.PhyMode, &ChType);
+	*pBufLen = 0;
+
+	for (i=0; i<10; i++)
+	{
+		pChDesp = &pChRegion->ChDesp[i];
+		if (pChDesp->FirstChannel == 0)
+			break;
+
+		if (ChType == BAND_5G)
+		{
+			if (pChDesp->FirstChannel <= 14)
+				continue;
+		}
+		else if (ChType == BAND_24G)
+		{
+			if (pChDesp->FirstChannel > 14)
+				continue;
+		}
+
+		if ((pChDesp->Geography == BOTH)
+			|| (pChDesp->Geography == pAd->CommonCfg.Geography))
+		{
+			MakeOutgoingFrame(pBuf + *pBufLen,		&TmpLen,
+								1,                 	&pChDesp->FirstChannel,
+								1,                 	&pChDesp->NumOfCh,
+								1,                 	&pChDesp->MaxTxPwr,
+								END_OF_ARGS);
+			*pBufLen += TmpLen;
+		}
+	}
+}
+
+
+#ifdef DOT11_N_SUPPORT
+static inline BOOLEAN IsValidChannel(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR channel)
+
+{
+	INT i;
+
+	for (i = 0; i < pAd->ChannelListNum; i++)
+	{
+		if (pAd->ChannelList[i].Channel == channel)
+			break;
+	}
+
+	if (i == pAd->ChannelListNum)
+		return FALSE;
+	else
+		return TRUE;
+}
+
+
+static inline UCHAR GetExtCh(
+	IN UCHAR Channel,
+	IN UCHAR Direction)
+{
+	CHAR ExtCh;
+
+	if (Direction == EXTCHA_ABOVE)
+		ExtCh = Channel + 4;
+	else
+		ExtCh = (Channel - 4) > 0 ? (Channel - 4) : 0;
+
+	return ExtCh;
+}
+
+
+static inline VOID N_ChannelCheck(
+	IN PRTMP_ADAPTER pAd)
+{
+	//UCHAR ChannelNum = pAd->ChannelListNum;
+	UCHAR Channel = pAd->CommonCfg.Channel;
+
+	if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pAd->CommonCfg.RegTransmitSetting.field.BW  == BW_40))
+	{
+		if (Channel > 14)
+		{
+			if ((Channel == 36) || (Channel == 44) || (Channel == 52) || (Channel == 60) || (Channel == 100) || (Channel == 108) ||
+			    (Channel == 116) || (Channel == 124) || (Channel == 132) || (Channel == 149) || (Channel == 157))
+			{
+				pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
+			}
+			else if ((Channel == 40) || (Channel == 48) || (Channel == 56) || (Channel == 64) || (Channel == 104) || (Channel == 112) ||
+					(Channel == 120) || (Channel == 128) || (Channel == 136) || (Channel == 153) || (Channel == 161))
+			{
+				pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW;
+			}
+			else
+			{
+				pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_20;
+			}
+		}
+		else
+		{
+			do
+			{
+				UCHAR ExtCh;
+				UCHAR Dir = pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
+				ExtCh = GetExtCh(Channel, Dir);
+				if (IsValidChannel(pAd, ExtCh))
+					break;
+
+				Dir = (Dir == EXTCHA_ABOVE) ? EXTCHA_BELOW : EXTCHA_ABOVE;
+				ExtCh = GetExtCh(Channel, Dir);
+				if (IsValidChannel(pAd, ExtCh))
+				{
+					pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = Dir;
+					break;
+				}
+				pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_20;
+			} while(FALSE);
+
+			if (Channel == 14)
+			{
+				pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_20;
+				//pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_NONE;	// We didn't set the ExtCh as NONE due to it'll set in RTMPSetHT()
+			}
+		}
+	}
+
+
+}
+
+
+static inline VOID N_SetCenCh(
+	IN PRTMP_ADAPTER pAd)
+{
+	if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
+	{
+		if (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
+		{
+			pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
+		}
+		else
+		{
+			if (pAd->CommonCfg.Channel == 14)
+				pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 1;
+			else
+				pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
+		}
+	}
+	else
+	{
+		pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
+	}
+}
+#endif // DOT11_N_SUPPORT //
+
+
+static inline UINT8 GetCuntryMaxTxPwr(
+	IN PRTMP_ADAPTER pAd,
+	IN UINT8 channel)
+{
+	int i;
+	for (i = 0; i < pAd->ChannelListNum; i++)
+	{
+		if (pAd->ChannelList[i].Channel == channel)
+			break;
+	}
+
+	if (i == pAd->ChannelListNum)
+		return 0xff;
+	else
+		return pAd->ChannelList[i].MaxTxPwr;
+}
+#endif // __CHLIST_H__
+
diff --git a/drivers/staging/rt3070/common/2870_rtmp_init.c b/drivers/staging/rt3070/common/2870_rtmp_init.c
new file mode 100644
index 0000000..fdf8dc1
--- /dev/null
+++ b/drivers/staging/rt3070/common/2870_rtmp_init.c
@@ -0,0 +1,1762 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	2870_rtmp_init.c
+
+	Abstract:
+	Miniport generic portion header file
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+	Paul Lin    2002-08-01    created
+    John Chang  2004-08-20    RT2561/2661 use scatter-gather scheme
+    Jan Lee  	2006-09-15    RT2860. Change for 802.11n , EEPROM, Led, BA, HT.
+	Sample Lin	2007-05-31    Merge RT2860 and RT2870 drivers.
+*/
+
+#include	"../rt_config.h"
+
+
+static void rx_done_tasklet(unsigned long data);
+static void rt2870_hcca_dma_done_tasklet(unsigned long data);
+static void rt2870_ac3_dma_done_tasklet(unsigned long data);
+static void rt2870_ac2_dma_done_tasklet(unsigned long data);
+static void rt2870_ac1_dma_done_tasklet(unsigned long data);
+static void rt2870_ac0_dma_done_tasklet(unsigned long data);
+static void rt2870_mgmt_dma_done_tasklet(unsigned long data);
+static void rt2870_null_frame_complete_tasklet(unsigned long data);
+static void rt2870_rts_frame_complete_tasklet(unsigned long data);
+static void rt2870_pspoll_frame_complete_tasklet(unsigned long data);
+static void rt2870_dataout_complete_tasklet(unsigned long data);
+
+
+/*
+========================================================================
+Routine Description:
+    Initialize receive data structures.
+
+Arguments:
+    pAd					Pointer to our adapter
+
+Return Value:
+	NDIS_STATUS_SUCCESS
+	NDIS_STATUS_RESOURCES
+
+Note:
+	Initialize all receive releated private buffer, include those define
+	in RTMP_ADAPTER structure and all private data structures. The mahor
+	work is to allocate buffer for each packet and chain buffer to
+	NDIS packet descriptor.
+========================================================================
+*/
+NDIS_STATUS	NICInitRecv(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	UCHAR				i;
+	NDIS_STATUS			Status = NDIS_STATUS_SUCCESS;
+	POS_COOKIE			pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitRecv\n"));
+	pObj = pObj;
+
+	//InterlockedExchange(&pAd->PendingRx, 0);
+	pAd->PendingRx = 0;
+	pAd->NextRxBulkInReadIndex 	= 0;	// Next Rx Read index
+	pAd->NextRxBulkInIndex		= 0 ; //RX_RING_SIZE -1; // Rx Bulk pointer
+	pAd->NextRxBulkInPosition 	= 0;
+
+	for (i = 0; i < (RX_RING_SIZE); i++)
+	{
+		PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
+
+		//Allocate URB
+		pRxContext->pUrb = RTUSB_ALLOC_URB(0);
+		if (pRxContext->pUrb == NULL)
+		{
+			Status = NDIS_STATUS_RESOURCES;
+			goto out1;
+		}
+
+		// Allocate transfer buffer
+		pRxContext->TransferBuffer = RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE, &pRxContext->data_dma);
+		if (pRxContext->TransferBuffer == NULL)
+		{
+			Status = NDIS_STATUS_RESOURCES;
+			goto out1;
+		}
+
+		NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE);
+
+		pRxContext->pAd	= pAd;
+		pRxContext->pIrp = NULL;
+		pRxContext->InUse		= FALSE;
+		pRxContext->IRPPending	= FALSE;
+		pRxContext->Readable	= FALSE;
+		//pRxContext->ReorderInUse = FALSE;
+		pRxContext->bRxHandling = FALSE;
+		pRxContext->BulkInOffset = 0;
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitRecv\n"));
+	return Status;
+
+out1:
+	for (i = 0; i < (RX_RING_SIZE); i++)
+	{
+		PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
+
+		if (NULL != pRxContext->TransferBuffer)
+		{
+			RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE,
+								pRxContext->TransferBuffer, pRxContext->data_dma);
+			pRxContext->TransferBuffer = NULL;
+		}
+
+		if (NULL != pRxContext->pUrb)
+		{
+			RTUSB_UNLINK_URB(pRxContext->pUrb);
+			RTUSB_FREE_URB(pRxContext->pUrb);
+			pRxContext->pUrb = NULL;
+		}
+	}
+
+	return Status;
+}
+
+
+/*
+========================================================================
+Routine Description:
+    Initialize transmit data structures.
+
+Arguments:
+    pAd					Pointer to our adapter
+
+Return Value:
+	NDIS_STATUS_SUCCESS
+	NDIS_STATUS_RESOURCES
+
+Note:
+========================================================================
+*/
+NDIS_STATUS	NICInitTransmit(
+	IN	PRTMP_ADAPTER	pAd)
+{
+#define LM_USB_ALLOC(pObj, Context, TB_Type, BufferSize, Status, msg1, err1, msg2, err2)	\
+	Context->pUrb = RTUSB_ALLOC_URB(0);		\
+	if (Context->pUrb == NULL) {			\
+		DBGPRINT(RT_DEBUG_ERROR, msg1);		\
+		Status = NDIS_STATUS_RESOURCES;		\
+		goto err1; }						\
+											\
+	Context->TransferBuffer = 				\
+		(TB_Type)RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, BufferSize, &Context->data_dma);	\
+	if (Context->TransferBuffer == NULL) {	\
+		DBGPRINT(RT_DEBUG_ERROR, msg2);		\
+		Status = NDIS_STATUS_RESOURCES;		\
+		goto err2; }
+
+#define LM_URB_FREE(pObj, Context, BufferSize)				\
+	if (NULL != Context->pUrb) {							\
+		RTUSB_UNLINK_URB(Context->pUrb);					\
+		RTUSB_FREE_URB(Context->pUrb);						\
+		Context->pUrb = NULL; }								\
+	if (NULL != Context->TransferBuffer) {				\
+		RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize,	\
+								Context->TransferBuffer,	\
+								Context->data_dma);			\
+		Context->TransferBuffer = NULL; }
+
+	UCHAR			i, acidx;
+	NDIS_STATUS     Status = NDIS_STATUS_SUCCESS;
+	PTX_CONTEXT		pNullContext   = &(pAd->NullContext);
+	PTX_CONTEXT		pPsPollContext = &(pAd->PsPollContext);
+	PTX_CONTEXT		pRTSContext    = &(pAd->RTSContext);
+	PTX_CONTEXT		pMLMEContext = NULL;
+//	PHT_TX_CONTEXT	pHTTXContext = NULL;
+	POS_COOKIE		pObj = (POS_COOKIE) pAd->OS_Cookie;
+	PVOID			RingBaseVa;
+//	RTMP_TX_RING	*pTxRing;
+	RTMP_MGMT_RING  *pMgmtRing;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTransmit\n"));
+	pObj = pObj;
+
+	// Init 4 set of Tx parameters
+	for(acidx = 0; acidx < NUM_OF_TX_RING; acidx++)
+	{
+		// Initialize all Transmit releated queues
+		InitializeQueueHeader(&pAd->TxSwQueue[acidx]);
+
+		// Next Local tx ring pointer waiting for buck out
+		pAd->NextBulkOutIndex[acidx] = acidx;
+		pAd->BulkOutPending[acidx] = FALSE; // Buck Out control flag
+		//pAd->DataBulkDoneIdx[acidx] = 0;
+	}
+
+	//pAd->NextMLMEIndex	= 0;
+	//pAd->PushMgmtIndex	= 0;
+	//pAd->PopMgmtIndex	= 0;
+	//InterlockedExchange(&pAd->MgmtQueueSize, 0);
+	//InterlockedExchange(&pAd->TxCount, 0);
+
+	//pAd->PrioRingFirstIndex	= 0;
+	//pAd->PrioRingTxCnt		= 0;
+
+	do
+	{
+		//
+		// TX_RING_SIZE, 4 ACs
+		//
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		for(acidx=0; acidx<4; acidx++)
+#endif // CONFIG_STA_SUPPORT //
+		{
+#if 1 //def DOT11_N_SUPPORT
+			PHT_TX_CONTEXT	pHTTXContext = &(pAd->TxContext[acidx]);
+
+			NdisZeroMemory(pHTTXContext, sizeof(HT_TX_CONTEXT));
+			//Allocate URB
+			LM_USB_ALLOC(pObj, pHTTXContext, PHTTX_BUFFER, sizeof(HTTX_BUFFER), Status,
+							("<-- ERROR in Alloc TX TxContext[%d] urb!! \n", acidx),
+							done,
+							("<-- ERROR in Alloc TX TxContext[%d] HTTX_BUFFER !! \n", acidx),
+							out1);
+
+			NdisZeroMemory(pHTTXContext->TransferBuffer->Aggregation, 4);
+			pHTTXContext->pAd = pAd;
+			pHTTXContext->pIrp = NULL;
+			pHTTXContext->IRPPending = FALSE;
+			pHTTXContext->NextBulkOutPosition = 0;
+			pHTTXContext->ENextBulkOutPosition = 0;
+			pHTTXContext->CurWritePosition = 0;
+			pHTTXContext->CurWriteRealPos = 0;
+			pHTTXContext->BulkOutSize = 0;
+			pHTTXContext->BulkOutPipeId = acidx;
+			pHTTXContext->bRingEmpty = TRUE;
+			pHTTXContext->bCopySavePad = FALSE;
+#endif // DOT11_N_SUPPORT //
+			pAd->BulkOutPending[acidx] = FALSE;
+		}
+
+
+		//
+		// MGMT_RING_SIZE
+		//
+		// Allocate MGMT ring descriptor's memory
+		pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * sizeof(TX_CONTEXT);
+		RTMPAllocateMemory(&pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
+		if (pAd->MgmtDescRing.AllocVa == NULL)
+		{
+			DBGPRINT_ERR(("Failed to allocate a big buffer for MgmtDescRing!\n"));
+			Status = NDIS_STATUS_RESOURCES;
+			goto out1;
+		}
+		NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
+		RingBaseVa     = pAd->MgmtDescRing.AllocVa;
+
+		// Initialize MGMT Ring and associated buffer memory
+		pMgmtRing = &pAd->MgmtRing;
+		for (i = 0; i < MGMT_RING_SIZE; i++)
+		{
+			// link the pre-allocated Mgmt buffer to MgmtRing.Cell
+			pMgmtRing->Cell[i].AllocSize = sizeof(TX_CONTEXT);
+			pMgmtRing->Cell[i].AllocVa = RingBaseVa;
+			pMgmtRing->Cell[i].pNdisPacket = NULL;
+			pMgmtRing->Cell[i].pNextNdisPacket = NULL;
+
+			//Allocate URB for MLMEContext
+			pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
+			pMLMEContext->pUrb = RTUSB_ALLOC_URB(0);
+			if (pMLMEContext->pUrb == NULL)
+			{
+				DBGPRINT(RT_DEBUG_ERROR, ("<-- ERROR in Alloc TX MLMEContext[%d] urb!! \n", i));
+				Status = NDIS_STATUS_RESOURCES;
+				goto out2;
+			}
+			pMLMEContext->pAd = pAd;
+			pMLMEContext->pIrp = NULL;
+			pMLMEContext->TransferBuffer = NULL;
+			pMLMEContext->InUse = FALSE;
+			pMLMEContext->IRPPending = FALSE;
+			pMLMEContext->bWaitingBulkOut = FALSE;
+			pMLMEContext->BulkOutSize = 0;
+			pMLMEContext->SelfIdx = i;
+
+			// Offset to next ring descriptor address
+			RingBaseVa = (PUCHAR) RingBaseVa + sizeof(TX_CONTEXT);
+		}
+		DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", i));
+
+		//pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1);
+		pAd->MgmtRing.TxSwFreeIdx = MGMT_RING_SIZE;
+		pAd->MgmtRing.TxCpuIdx = 0;
+		pAd->MgmtRing.TxDmaIdx = 0;
+
+		//
+		// BEACON_RING_SIZE
+		//
+		for(i=0; i<BEACON_RING_SIZE; i++) // 2
+		{
+			PTX_CONTEXT	pBeaconContext = &(pAd->BeaconContext[i]);
+
+
+			NdisZeroMemory(pBeaconContext, sizeof(TX_CONTEXT));
+
+			//Allocate URB
+			LM_USB_ALLOC(pObj, pBeaconContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
+							("<-- ERROR in Alloc TX BeaconContext[%d] urb!! \n", i),
+							out2,
+							("<-- ERROR in Alloc TX BeaconContext[%d] TX_BUFFER !! \n", i),
+							out3);
+
+			pBeaconContext->pAd = pAd;
+			pBeaconContext->pIrp = NULL;
+			pBeaconContext->InUse = FALSE;
+			pBeaconContext->IRPPending = FALSE;
+		}
+
+		//
+		// NullContext
+		//
+		NdisZeroMemory(pNullContext, sizeof(TX_CONTEXT));
+
+		//Allocate URB
+		LM_USB_ALLOC(pObj, pNullContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
+						("<-- ERROR in Alloc TX NullContext urb!! \n"),
+						out3,
+						("<-- ERROR in Alloc TX NullContext TX_BUFFER !! \n"),
+						out4);
+
+		pNullContext->pAd = pAd;
+		pNullContext->pIrp = NULL;
+		pNullContext->InUse = FALSE;
+		pNullContext->IRPPending = FALSE;
+
+		//
+		// RTSContext
+		//
+		NdisZeroMemory(pRTSContext, sizeof(TX_CONTEXT));
+
+		//Allocate URB
+		LM_USB_ALLOC(pObj, pRTSContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
+						("<-- ERROR in Alloc TX RTSContext urb!! \n"),
+						out4,
+						("<-- ERROR in Alloc TX RTSContext TX_BUFFER !! \n"),
+						out5);
+
+		pRTSContext->pAd = pAd;
+		pRTSContext->pIrp = NULL;
+		pRTSContext->InUse = FALSE;
+		pRTSContext->IRPPending = FALSE;
+
+		//
+		// PsPollContext
+		//
+		//NdisZeroMemory(pPsPollContext, sizeof(TX_CONTEXT));
+		//Allocate URB
+		LM_USB_ALLOC(pObj, pPsPollContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
+						("<-- ERROR in Alloc TX PsPollContext urb!! \n"),
+						out5,
+						("<-- ERROR in Alloc TX PsPollContext TX_BUFFER !! \n"),
+						out6);
+
+		pPsPollContext->pAd = pAd;
+		pPsPollContext->pIrp = NULL;
+		pPsPollContext->InUse = FALSE;
+		pPsPollContext->IRPPending = FALSE;
+		pPsPollContext->bAggregatible = FALSE;
+		pPsPollContext->LastOne = TRUE;
+
+	}   while (FALSE);
+
+
+done:
+	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit\n"));
+
+	return Status;
+
+	/* --------------------------- ERROR HANDLE --------------------------- */
+out6:
+	LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
+
+out5:
+	LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
+
+out4:
+	LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
+
+out3:
+	for(i=0; i<BEACON_RING_SIZE; i++)
+	{
+		PTX_CONTEXT	pBeaconContext = &(pAd->BeaconContext[i]);
+		if (pBeaconContext)
+			LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
+	}
+
+out2:
+	if (pAd->MgmtDescRing.AllocVa)
+	{
+		pMgmtRing = &pAd->MgmtRing;
+	for(i=0; i<MGMT_RING_SIZE; i++)
+	{
+		pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
+		if (pMLMEContext)
+			LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
+	}
+		NdisFreeMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize, 0);
+		pAd->MgmtDescRing.AllocVa = NULL;
+	}
+
+out1:
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	for(acidx=0; acidx<4; acidx++)
+#endif // CONFIG_STA_SUPPORT //
+	{
+		PHT_TX_CONTEXT pTxContext = &(pAd->TxContext[acidx]);
+		if (pTxContext)
+			LM_URB_FREE(pObj, pTxContext, sizeof(HTTX_BUFFER));
+	}
+
+	// Here we didn't have any pre-allocated memory need to free.
+
+	return Status;
+}
+
+
+/*
+========================================================================
+Routine Description:
+    Allocate DMA memory blocks for send, receive.
+
+Arguments:
+    pAd					Pointer to our adapter
+
+Return Value:
+	NDIS_STATUS_SUCCESS
+	NDIS_STATUS_FAILURE
+	NDIS_STATUS_RESOURCES
+
+Note:
+========================================================================
+*/
+NDIS_STATUS	RTMPAllocTxRxRingMemory(
+	IN	PRTMP_ADAPTER	pAd)
+{
+//	COUNTER_802_11	pCounter = &pAd->WlanCounters;
+	NDIS_STATUS		Status;
+	INT				num;
+
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
+
+
+	do
+	{
+		// Init the CmdQ and CmdQLock
+		NdisAllocateSpinLock(&pAd->CmdQLock);
+		NdisAcquireSpinLock(&pAd->CmdQLock);
+		RTUSBInitializeCmdQ(&pAd->CmdQ);
+		NdisReleaseSpinLock(&pAd->CmdQLock);
+
+
+		NdisAllocateSpinLock(&pAd->MLMEBulkOutLock);
+		//NdisAllocateSpinLock(&pAd->MLMEWaitQueueLock);
+		NdisAllocateSpinLock(&pAd->BulkOutLock[0]);
+		NdisAllocateSpinLock(&pAd->BulkOutLock[1]);
+		NdisAllocateSpinLock(&pAd->BulkOutLock[2]);
+		NdisAllocateSpinLock(&pAd->BulkOutLock[3]);
+		NdisAllocateSpinLock(&pAd->BulkOutLock[4]);
+		NdisAllocateSpinLock(&pAd->BulkOutLock[5]);
+		NdisAllocateSpinLock(&pAd->BulkInLock);
+
+		for (num = 0; num < NUM_OF_TX_RING; num++)
+		{
+			NdisAllocateSpinLock(&pAd->TxContextQueueLock[num]);
+		}
+
+#ifdef RALINK_ATE
+		NdisAllocateSpinLock(&pAd->GenericLock);
+#endif // RALINK_ATE //
+
+//		NdisAllocateSpinLock(&pAd->MemLock);	// Not used in RT28XX
+
+//		NdisAllocateSpinLock(&pAd->MacTabLock); // init it in UserCfgInit()
+//		NdisAllocateSpinLock(&pAd->BATabLock); // init it in BATableInit()
+
+//		for(num=0; num<MAX_LEN_OF_BA_REC_TABLE; num++)
+//		{
+//			NdisAllocateSpinLock(&pAd->BATable.BARecEntry[num].RxReRingLock);
+//		}
+
+		//
+		// Init Mac Table
+		//
+//		MacTableInitialize(pAd);
+
+		//
+		// Init send data structures and related parameters
+		//
+		Status = NICInitTransmit(pAd);
+		if (Status != NDIS_STATUS_SUCCESS)
+			break;
+
+		//
+		// Init receive data structures and related parameters
+		//
+		Status = NICInitRecv(pAd);
+		if (Status != NDIS_STATUS_SUCCESS)
+			break;
+
+		pAd->PendingIoCount = 1;
+
+	} while (FALSE);
+
+	NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME));
+	pAd->FragFrame.pFragPacket =  RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
+
+	if (pAd->FragFrame.pFragPacket == NULL)
+	{
+		Status = NDIS_STATUS_RESOURCES;
+	}
+
+	DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
+	return Status;
+}
+
+
+/*
+========================================================================
+Routine Description:
+	Calls USB_InterfaceStop and frees memory allocated for the URBs
+    calls NdisMDeregisterDevice and frees the memory
+    allocated in VNetInitialize for the Adapter Object
+
+Arguments:
+	*pAd				the raxx interface data pointer
+
+Return Value:
+	None
+
+Note:
+========================================================================
+*/
+VOID	RTMPFreeTxRxRingMemory(
+	IN	PRTMP_ADAPTER	pAd)
+{
+#define LM_URB_FREE(pObj, Context, BufferSize)				\
+	if (NULL != Context->pUrb) {							\
+		RTUSB_UNLINK_URB(Context->pUrb);					\
+		RTUSB_FREE_URB(Context->pUrb);						\
+		Context->pUrb = NULL; }								\
+	if (NULL != Context->TransferBuffer) {					\
+		RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize,	\
+								Context->TransferBuffer,	\
+								Context->data_dma);			\
+		Context->TransferBuffer = NULL; }
+
+
+	UINT                i, acidx;
+	PTX_CONTEXT			pNullContext   = &pAd->NullContext;
+	PTX_CONTEXT			pPsPollContext = &pAd->PsPollContext;
+	PTX_CONTEXT			pRTSContext    = &pAd->RTSContext;
+//	PHT_TX_CONTEXT 		pHTTXContext;
+	//PRTMP_REORDERBUF	pReorderBuf;
+	POS_COOKIE			pObj = (POS_COOKIE) pAd->OS_Cookie;
+//	RTMP_TX_RING		*pTxRing;
+
+	DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n"));
+	pObj = pObj;
+
+	// Free all resources for the RECEIVE buffer queue.
+	for(i=0; i<(RX_RING_SIZE); i++)
+	{
+		PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
+		if (pRxContext)
+			LM_URB_FREE(pObj, pRxContext, MAX_RXBULK_SIZE);
+	}
+
+	// Free PsPoll frame resource
+	LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
+
+	// Free NULL frame resource
+	LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
+
+	// Free RTS frame resource
+	LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
+
+
+	// Free beacon frame resource
+	for(i=0; i<BEACON_RING_SIZE; i++)
+	{
+		PTX_CONTEXT	pBeaconContext = &(pAd->BeaconContext[i]);
+		if (pBeaconContext)
+			LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
+	}
+
+
+	// Free mgmt frame resource
+	for(i = 0; i < MGMT_RING_SIZE; i++)
+	{
+		PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
+		//LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
+		if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket)
+		{
+			RTMPFreeNdisPacket(pAd, pAd->MgmtRing.Cell[i].pNdisPacket);
+			pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
+			pMLMEContext->TransferBuffer = NULL;
+		}
+
+		if (pMLMEContext)
+		{
+			if (NULL != pMLMEContext->pUrb)
+			{
+				RTUSB_UNLINK_URB(pMLMEContext->pUrb);
+				RTUSB_FREE_URB(pMLMEContext->pUrb);
+				pMLMEContext->pUrb = NULL;
+			}
+		}
+	}
+	if (pAd->MgmtDescRing.AllocVa)
+		NdisFreeMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize, 0);
+
+
+	// Free Tx frame resource
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		for(acidx=0; acidx<4; acidx++)
+#endif // CONFIG_STA_SUPPORT //
+		{
+		PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
+			if (pHTTXContext)
+				LM_URB_FREE(pObj, pHTTXContext, sizeof(HTTX_BUFFER));
+		}
+
+	if (pAd->FragFrame.pFragPacket)
+		RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS);
+
+	for(i=0; i<6; i++)
+	{
+		NdisFreeSpinLock(&pAd->BulkOutLock[i]);
+	}
+
+	NdisFreeSpinLock(&pAd->BulkInLock);
+	NdisFreeSpinLock(&pAd->MLMEBulkOutLock);
+
+	NdisFreeSpinLock(&pAd->CmdQLock);
+#ifdef RALINK_ATE
+	NdisFreeSpinLock(&pAd->GenericLock);
+#endif // RALINK_ATE //
+	// Clear all pending bulk-out request flags.
+	RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff);
+
+//	NdisFreeSpinLock(&pAd->MacTabLock);
+
+//	for(i=0; i<MAX_LEN_OF_BA_REC_TABLE; i++)
+//	{
+//		NdisFreeSpinLock(&pAd->BATable.BARecEntry[i].RxReRingLock);
+//	}
+
+	DBGPRINT(RT_DEBUG_ERROR, ("<--- ReleaseAdapter\n"));
+}
+
+
+/*
+========================================================================
+Routine Description:
+    Allocate memory for adapter control block.
+
+Arguments:
+    pAd					Pointer to our adapter
+
+Return Value:
+	NDIS_STATUS_SUCCESS
+	NDIS_STATUS_FAILURE
+	NDIS_STATUS_RESOURCES
+
+Note:
+========================================================================
+*/
+NDIS_STATUS AdapterBlockAllocateMemory(
+	IN PVOID	handle,
+	OUT	PVOID	*ppAd)
+{
+	PUSB_DEV	usb_dev;
+	POS_COOKIE	pObj = (POS_COOKIE) handle;
+
+
+	usb_dev = pObj->pUsb_Dev;
+
+	pObj->MLMEThr_pid	= NULL;
+	pObj->RTUSBCmdThr_pid	= NULL;
+
+	*ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER));
+
+	if (*ppAd)
+	{
+		NdisZeroMemory(*ppAd, sizeof(RTMP_ADAPTER));
+		((PRTMP_ADAPTER)*ppAd)->OS_Cookie = handle;
+		return (NDIS_STATUS_SUCCESS);
+	}
+	else
+	{
+		return (NDIS_STATUS_FAILURE);
+	}
+}
+
+
+/*
+========================================================================
+Routine Description:
+    Create kernel threads & tasklets.
+
+Arguments:
+    *net_dev			Pointer to wireless net device interface
+
+Return Value:
+	NDIS_STATUS_SUCCESS
+	NDIS_STATUS_FAILURE
+
+Note:
+========================================================================
+*/
+NDIS_STATUS	 CreateThreads(
+	IN	struct net_device *net_dev)
+{
+	PRTMP_ADAPTER pAd = net_dev->ml_priv;
+	POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+	pid_t pid_number;
+
+	//init_MUTEX(&(pAd->usbdev_semaphore));
+
+	init_MUTEX_LOCKED(&(pAd->mlme_semaphore));
+	init_completion (&pAd->mlmeComplete);
+
+	init_MUTEX_LOCKED(&(pAd->RTUSBCmd_semaphore));
+	init_completion (&pAd->CmdQComplete);
+
+	init_MUTEX_LOCKED(&(pAd->RTUSBTimer_semaphore));
+	init_completion (&pAd->TimerQComplete);
+
+	// Creat MLME Thread
+	pObj->MLMEThr_pid = NULL;
+	pid_number = kernel_thread(MlmeThread, pAd, CLONE_VM);
+	if (pid_number < 0)
+	{
+		printk (KERN_WARNING "%s: unable to start Mlme thread\n",pAd->net_dev->name);
+		return NDIS_STATUS_FAILURE;
+	}
+	pObj->MLMEThr_pid = find_get_pid(pid_number);
+	// Wait for the thread to start
+	wait_for_completion(&(pAd->mlmeComplete));
+
+	// Creat Command Thread
+	pObj->RTUSBCmdThr_pid = NULL;
+	pid_number = kernel_thread(RTUSBCmdThread, pAd, CLONE_VM);
+	if (pid_number < 0)
+	{
+		printk (KERN_WARNING "%s: unable to start RTUSBCmd thread\n",pAd->net_dev->name);
+		return NDIS_STATUS_FAILURE;
+	}
+	pObj->RTUSBCmdThr_pid = find_get_pid(pid_number);
+	wait_for_completion(&(pAd->CmdQComplete));
+
+	pObj->TimerQThr_pid = NULL;
+	pid_number = kernel_thread(TimerQThread, pAd, CLONE_VM);
+	if (pid_number < 0)
+	{
+		printk (KERN_WARNING "%s: unable to start TimerQThread\n",pAd->net_dev->name);
+		return NDIS_STATUS_FAILURE;
+	}
+	pObj->TimerQThr_pid = find_get_pid(pid_number);
+	// Wait for the thread to start
+	wait_for_completion(&(pAd->TimerQComplete));
+
+	// Create receive tasklet
+	tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (ULONG)pAd);
+	tasklet_init(&pObj->mgmt_dma_done_task, rt2870_mgmt_dma_done_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->ac0_dma_done_task, rt2870_ac0_dma_done_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->ac1_dma_done_task, rt2870_ac1_dma_done_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->ac2_dma_done_task, rt2870_ac2_dma_done_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->ac3_dma_done_task, rt2870_ac3_dma_done_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->hcca_dma_done_task, rt2870_hcca_dma_done_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->null_frame_complete_task, rt2870_null_frame_complete_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->rts_frame_complete_task, rt2870_rts_frame_complete_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->pspoll_frame_complete_task, rt2870_pspoll_frame_complete_tasklet, (unsigned long)pAd);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+#ifdef CONFIG_STA_SUPPORT
+/*
+========================================================================
+Routine Description:
+ 	As STA's BSSID is a WC too, it uses shared key table.
+ 	This function write correct unicast TX key to ASIC WCID.
+ 	And we still make a copy in our MacTab.Content[BSSID_WCID].PairwiseKey.
+	Caller guarantee TKIP/AES always has keyidx = 0. (pairwise key)
+	Caller guarantee WEP calls this function when set Txkey,  default key index=0~3.
+
+Arguments:
+	pAd 					Pointer to our adapter
+	pKey					Pointer to the where the key stored
+
+Return Value:
+	NDIS_SUCCESS			Add key successfully
+
+Note:
+========================================================================
+*/
+VOID	RTMPAddBSSIDCipher(
+	IN	PRTMP_ADAPTER		pAd,
+	IN	UCHAR				Aid,
+	IN	PNDIS_802_11_KEY	pKey,
+	IN  UCHAR   			CipherAlg)
+{
+	PUCHAR		pTxMic, pRxMic;
+	BOOLEAN 	bKeyRSC, bAuthenticator; // indicate the receive SC set by KeyRSC value
+//	UCHAR		CipherAlg;
+	UCHAR		i;
+	ULONG		WCIDAttri;
+	USHORT	 	offset;
+	UCHAR		KeyIdx, IVEIV[8];
+	UINT32		Value;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddBSSIDCipher==> Aid = %d\n",Aid));
+
+	// Bit 29 of Add-key KeyRSC
+	bKeyRSC 	   = (pKey->KeyIndex & 0x20000000) ? TRUE : FALSE;
+
+	// Bit 28 of Add-key Authenticator
+	bAuthenticator = (pKey->KeyIndex & 0x10000000) ? TRUE : FALSE;
+	KeyIdx = (UCHAR)pKey->KeyIndex&0xff;
+
+	if (KeyIdx > 4)
+		return;
+
+
+	if (pAd->MacTab.Content[Aid].PairwiseKey.CipherAlg == CIPHER_TKIP)
+	{	if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+		{
+			// for WPA-None Tx, Rx MIC is the same
+			pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
+			pRxMic = pTxMic;
+		}
+		else if (bAuthenticator == TRUE)
+		{
+			pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
+			pRxMic = (PUCHAR) (&pKey->KeyMaterial) + 24;
+		}
+		else
+		{
+			pRxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
+			pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 24;
+		}
+
+		offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE) + 0x10;
+		for (i=0; i<8; )
+		{
+			Value = *(pTxMic+i);
+			Value += (*(pTxMic+i+1)<<8);
+			Value += (*(pTxMic+i+2)<<16);
+			Value += (*(pTxMic+i+3)<<24);
+			RTUSBWriteMACRegister(pAd, offset+i, Value);
+			i+=4;
+		}
+
+		offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE) + 0x18;
+		for (i=0; i<8; )
+		{
+			Value = *(pRxMic+i);
+			Value += (*(pRxMic+i+1)<<8);
+			Value += (*(pRxMic+i+2)<<16);
+			Value += (*(pRxMic+i+3)<<24);
+			RTUSBWriteMACRegister(pAd, offset+i, Value);
+			i+=4;
+		}
+
+		// Only Key lenth equal to TKIP key have these
+		NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxMic, pRxMic, 8);
+		NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.TxMic, pTxMic, 8);
+
+		DBGPRINT(RT_DEBUG_TRACE,
+				("	TxMIC  = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n",
+				pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],
+				pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
+		DBGPRINT(RT_DEBUG_TRACE,
+				("	RxMIC  = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n",
+				pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],
+				pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
+	}
+
+	// 2. Record Security Key.
+	pAd->MacTab.Content[BSSID_WCID].PairwiseKey.KeyLen= (UCHAR)pKey->KeyLength;
+	NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.Key, &pKey->KeyMaterial, pKey->KeyLength);
+
+	// 3. Check RxTsc. And used to init to ASIC IV.
+	if (bKeyRSC == TRUE)
+		NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxTsc, &pKey->KeyRSC, 6);
+	else
+		NdisZeroMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxTsc, 6);
+
+	// 4. Init TxTsc to one based on WiFi WPA specs
+	pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[0] = 1;
+	pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[1] = 0;
+	pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[2] = 0;
+	pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[3] = 0;
+	pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[4] = 0;
+	pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[5] = 0;
+
+	CipherAlg = pAd->MacTab.Content[Aid].PairwiseKey.CipherAlg;
+
+	offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE);
+	RTUSBMultiWrite(pAd, (USHORT) offset, pKey->KeyMaterial,
+				((pKey->KeyLength == LEN_TKIP_KEY) ? 16 : (USHORT)pKey->KeyLength));
+
+	offset = SHARED_KEY_TABLE_BASE + (KeyIdx * HW_KEY_ENTRY_SIZE);
+	RTUSBMultiWrite(pAd, (USHORT) offset, pKey->KeyMaterial, (USHORT)pKey->KeyLength);
+
+	offset = PAIRWISE_IVEIV_TABLE_BASE + (Aid * HW_IVEIV_ENTRY_SIZE);
+	NdisZeroMemory(IVEIV, 8);
+
+	// IV/EIV
+	if ((CipherAlg == CIPHER_TKIP) ||
+		(CipherAlg == CIPHER_TKIP_NO_MIC) ||
+		(CipherAlg == CIPHER_AES))
+	{
+		IVEIV[3] = 0x20; // Eiv bit on. keyid always 0 for pairwise key
+	}
+	// default key idx needs to set.
+	// in TKIP/AES KeyIdx = 0 , WEP KeyIdx is default tx key.
+	else
+	{
+		IVEIV[3] |= (KeyIdx<< 6);
+	}
+	RTUSBMultiWrite(pAd, (USHORT) offset, IVEIV, 8);
+
+	// WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0
+	if ((CipherAlg == CIPHER_TKIP) ||
+		(CipherAlg == CIPHER_TKIP_NO_MIC) ||
+		(CipherAlg == CIPHER_AES))
+	{
+		WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
+	}
+	else
+		WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
+
+	offset = MAC_WCID_ATTRIBUTE_BASE + (Aid* HW_WCID_ATTRI_SIZE);
+	RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
+	RTUSBReadMACRegister(pAd, offset, &Value);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("BSSID_WCID : offset = %x, WCIDAttri = %lx\n",
+			offset, WCIDAttri));
+
+	// pAddr
+	// Add Bssid mac address at linkup. not here.  check!
+	/*offset = MAC_WCID_BASE + (BSSID_WCID * HW_WCID_ENTRY_SIZE);
+	*for (i=0; i<MAC_ADDR_LEN; i++)
+	{
+		RTMP_IO_WRITE8(pAd, offset+i, pKey->BSSID[i]);
+	}
+	*/
+
+	DBGPRINT(RT_DEBUG_ERROR, ("AddBSSIDasWCIDEntry: Alg=%s, KeyLength = %d\n",
+			CipherName[CipherAlg], pKey->KeyLength));
+	DBGPRINT(RT_DEBUG_TRACE, ("Key [idx=%x] [KeyLen = %d]\n",
+			pKey->KeyIndex, pKey->KeyLength));
+	for(i=0; i<pKey->KeyLength; i++)
+		DBGPRINT_RAW(RT_DEBUG_TRACE,(" %x:", pKey->KeyMaterial[i]));
+	DBGPRINT(RT_DEBUG_TRACE,("	 \n"));
+}
+#endif // CONFIG_STA_SUPPORT //
+
+/*
+========================================================================
+Routine Description:
+    Get a received packet.
+
+Arguments:
+	pAd					device control block
+	pSaveRxD			receive descriptor information
+	*pbReschedule		need reschedule flag
+	*pRxPending			pending received packet flag
+
+Return Value:
+    the recieved packet
+
+Note:
+========================================================================
+*/
+#define RT2870_RXDMALEN_FIELD_SIZE			4
+PNDIS_PACKET GetPacketFromRxRing(
+	IN		PRTMP_ADAPTER		pAd,
+	OUT		PRT28XX_RXD_STRUC	pSaveRxD,
+	OUT		BOOLEAN				*pbReschedule,
+	IN OUT	UINT32				*pRxPending)
+{
+	PRX_CONTEXT		pRxContext;
+	PNDIS_PACKET	pSkb;
+	PUCHAR			pData;
+	ULONG			ThisFrameLen;
+	ULONG			RxBufferLength;
+	PRXWI_STRUC		pRxWI;
+
+	pRxContext = &pAd->RxContext[pAd->NextRxBulkInReadIndex];
+	if ((pRxContext->Readable == FALSE) || (pRxContext->InUse == TRUE))
+		return NULL;
+
+	RxBufferLength = pRxContext->BulkInOffset - pAd->ReadPosition;
+	if (RxBufferLength < (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXWI_STRUC) + sizeof(RXINFO_STRUC)))
+	{
+		goto label_null;
+	}
+
+	pData = &pRxContext->TransferBuffer[pAd->ReadPosition]; /* 4KB */
+	// The RXDMA field is 4 bytes, now just use the first 2 bytes. The Length including the (RXWI + MSDU + Padding)
+	ThisFrameLen = *pData + (*(pData+1)<<8);
+    if (ThisFrameLen == 0)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("BIRIdx(%d): RXDMALen is zero.[%ld], BulkInBufLen = %ld)\n",
+								pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset));
+		goto label_null;
+	}
+	if ((ThisFrameLen&0x3) != 0)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("BIRIdx(%d): RXDMALen not multiple of 4.[%ld], BulkInBufLen = %ld)\n",
+								pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset));
+		goto label_null;
+	}
+
+	if ((ThisFrameLen + 8)> RxBufferLength)	// 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))
+	{
+		DBGPRINT(RT_DEBUG_TRACE,("BIRIdx(%d):FrameLen(0x%lx) outranges. BulkInLen=0x%lx, remaining RxBufLen=0x%lx, ReadPos=0x%lx\n",
+						pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset, RxBufferLength, pAd->ReadPosition));
+
+		// error frame. finish this loop
+		goto label_null;
+	}
+
+	// skip USB frame length field
+	pData += RT2870_RXDMALEN_FIELD_SIZE;
+	pRxWI = (PRXWI_STRUC)pData;
+#ifdef RT_BIG_ENDIAN
+	RTMPWIEndianChange(pData, TYPE_RXWI);
+#endif // RT_BIG_ENDIAN //
+	if (pRxWI->MPDUtotalByteCount > ThisFrameLen)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n",
+									__FUNCTION__, pRxWI->MPDUtotalByteCount, ThisFrameLen));
+		goto label_null;
+	}
+#ifdef RT_BIG_ENDIAN
+	RTMPWIEndianChange(pData, TYPE_RXWI);
+#endif // RT_BIG_ENDIAN //
+
+	// allocate a rx packet
+	pSkb = dev_alloc_skb(ThisFrameLen);
+	if (pSkb == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("%s():Cannot Allocate sk buffer for this Bulk-In buffer!\n", __FUNCTION__));
+		goto label_null;
+	}
+
+	// copy the rx packet
+	memcpy(skb_put(pSkb, ThisFrameLen), pData, ThisFrameLen);
+	RTPKT_TO_OSPKT(pSkb)->dev = get_netdev_from_bssid(pAd, BSS0);
+	RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pSkb), PKTSRC_NDIS);
+
+	// copy RxD
+	*pSaveRxD = *(PRXINFO_STRUC)(pData + ThisFrameLen);
+#ifdef RT_BIG_ENDIAN
+	RTMPDescriptorEndianChange((PUCHAR)pSaveRxD, TYPE_RXINFO);
+#endif // RT_BIG_ENDIAN //
+
+	// update next packet read position.
+	pAd->ReadPosition += (ThisFrameLen + RT2870_RXDMALEN_FIELD_SIZE + RXINFO_SIZE);	// 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))
+
+	return pSkb;
+
+label_null:
+
+	return NULL;
+}
+
+
+/*
+========================================================================
+Routine Description:
+    Handle received packets.
+
+Arguments:
+	data				- URB information pointer
+
+Return Value:
+    None
+
+Note:
+========================================================================
+*/
+static void rx_done_tasklet(unsigned long data)
+{
+	purbb_t 			pUrb;
+	PRX_CONTEXT			pRxContext;
+	PRTMP_ADAPTER		pAd;
+	NTSTATUS			Status;
+	unsigned int		IrqFlags;
+
+	pUrb		= (purbb_t)data;
+	pRxContext	= (PRX_CONTEXT)pUrb->context;
+	pAd 		= pRxContext->pAd;
+	Status = pUrb->status;
+
+
+	RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
+	pRxContext->InUse = FALSE;
+	pRxContext->IRPPending = FALSE;
+	pRxContext->BulkInOffset += pUrb->actual_length;
+	//NdisInterlockedDecrement(&pAd->PendingRx);
+	pAd->PendingRx--;
+
+	if (Status == USB_ST_NOERROR)
+	{
+		pAd->BulkInComplete++;
+		pAd->NextRxBulkInPosition = 0;
+		if (pRxContext->BulkInOffset)	// As jan's comment, it may bulk-in success but size is zero.
+		{
+			pRxContext->Readable = TRUE;
+			INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE);
+		}
+		RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+	}
+	else	 // STATUS_OTHER
+	{
+		pAd->BulkInCompleteFail++;
+		// Still read this packet although it may comtain wrong bytes.
+		pRxContext->Readable = FALSE;
+		RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+
+		// Parsing all packets. because after reset, the index will reset to all zero.
+		if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+									fRTMP_ADAPTER_BULKIN_RESET |
+									fRTMP_ADAPTER_HALT_IN_PROGRESS |
+									fRTMP_ADAPTER_NIC_NOT_EXIST))))
+		{
+
+			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk In Failed. Status=%d, BIIdx=0x%x, BIRIdx=0x%x, actual_length= 0x%x\n",
+							Status, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, pRxContext->pUrb->actual_length));
+
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
+		}
+	}
+
+	ASSERT((pRxContext->InUse == pRxContext->IRPPending));
+
+#ifdef RALINK_ATE
+	if (ATE_ON(pAd))
+    {
+		// If the driver is in ATE mode and Rx frame is set into here.
+		if (pAd->ContinBulkIn == TRUE)
+		{
+			RTUSBBulkReceive(pAd);
+		}
+	}
+	else
+#endif // RALINK_ATE //
+	RTUSBBulkReceive(pAd);
+
+	return;
+
+}
+
+
+static void rt2870_mgmt_dma_done_tasklet(unsigned long data)
+{
+	PRTMP_ADAPTER 	pAd;
+	PTX_CONTEXT		pMLMEContext;
+	int				index;
+	PNDIS_PACKET	pPacket;
+	purbb_t			pUrb;
+	NTSTATUS		Status;
+	unsigned long	IrqFlags;
+
+
+	pUrb			= (purbb_t)data;
+	pMLMEContext	= (PTX_CONTEXT)pUrb->context;
+	pAd 			= pMLMEContext->pAd;
+	Status			= pUrb->status;
+	index 			= pMLMEContext->SelfIdx;
+
+	ASSERT((pAd->MgmtRing.TxDmaIdx == index));
+
+	RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
+
+
+	if (Status != USB_ST_NOERROR)
+	{
+		//Bulk-Out fail status handle
+		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
+		{
+			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out MLME Failed, Status=%d!\n", Status));
+			// TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt?
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+			pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
+		}
+	}
+
+	pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
+	RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
+
+	RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
+	// Reset MLME context flags
+	pMLMEContext->IRPPending = FALSE;
+	pMLMEContext->InUse = FALSE;
+	pMLMEContext->bWaitingBulkOut = FALSE;
+	pMLMEContext->BulkOutSize = 0;
+
+	pPacket = pAd->MgmtRing.Cell[index].pNdisPacket;
+	pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
+
+	// Increase MgmtRing Index
+	INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE);
+	pAd->MgmtRing.TxSwFreeIdx++;
+	RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
+
+	// No-matter success or fail, we free the mgmt packet.
+	if (pPacket)
+		RTMPFreeNdisPacket(pAd, pPacket);
+
+	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+								fRTMP_ADAPTER_HALT_IN_PROGRESS |
+								fRTMP_ADAPTER_NIC_NOT_EXIST))))
+	{
+		// do nothing and return directly.
+	}
+	else
+	{
+		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET) &&
+			((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG))
+		{	// For Mgmt Bulk-Out failed, ignore it now.
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+		}
+		else
+		{
+
+			// Always call Bulk routine, even reset bulk.
+			// The protectioon of rest bulk should be in BulkOut routine
+			if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */)
+			{
+				RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
+			}
+				RTUSBKickBulkOut(pAd);
+			}
+		}
+
+}
+
+
+static void rt2870_hcca_dma_done_tasklet(unsigned long data)
+{
+	PRTMP_ADAPTER		pAd;
+	PHT_TX_CONTEXT		pHTTXContext;
+	UCHAR				BulkOutPipeId = 4;
+	purbb_t				pUrb;
+
+
+	pUrb			= (purbb_t)data;
+	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
+	pAd				= pHTTXContext->pAd;
+
+	rt2870_dataout_complete_tasklet((unsigned long)pUrb);
+
+	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+								fRTMP_ADAPTER_HALT_IN_PROGRESS |
+								fRTMP_ADAPTER_NIC_NOT_EXIST))))
+	{
+		// do nothing and return directly.
+	}
+	else
+	{
+		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
+		{
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+		}
+		else
+		{	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
+				/*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
+				(pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
+				(pHTTXContext->bCurWriting == FALSE))
+			{
+				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
+			}
+
+			RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<4);
+			RTUSBKickBulkOut(pAd);
+		}
+	}
+
+
+		return;
+}
+
+
+static void rt2870_ac3_dma_done_tasklet(unsigned long data)
+{
+	PRTMP_ADAPTER		pAd;
+	PHT_TX_CONTEXT		pHTTXContext;
+	UCHAR				BulkOutPipeId = 3;
+	purbb_t				pUrb;
+
+
+	pUrb			= (purbb_t)data;
+	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
+	pAd				= pHTTXContext->pAd;
+
+	rt2870_dataout_complete_tasklet((unsigned long)pUrb);
+
+	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+								fRTMP_ADAPTER_HALT_IN_PROGRESS |
+								fRTMP_ADAPTER_NIC_NOT_EXIST))))
+	{
+		// do nothing and return directly.
+	}
+	else
+	{
+		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
+		{
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+		}
+		else
+		{	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
+				/*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
+				(pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
+				(pHTTXContext->bCurWriting == FALSE))
+			{
+				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
+			}
+
+			RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<3);
+			RTUSBKickBulkOut(pAd);
+		}
+	}
+
+
+		return;
+}
+
+
+static void rt2870_ac2_dma_done_tasklet(unsigned long data)
+{
+	PRTMP_ADAPTER		pAd;
+	PHT_TX_CONTEXT		pHTTXContext;
+	UCHAR				BulkOutPipeId = 2;
+	purbb_t				pUrb;
+
+
+	pUrb			= (purbb_t)data;
+	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
+	pAd				= pHTTXContext->pAd;
+
+	rt2870_dataout_complete_tasklet((unsigned long)pUrb);
+
+	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+								fRTMP_ADAPTER_HALT_IN_PROGRESS |
+								fRTMP_ADAPTER_NIC_NOT_EXIST))))
+	{
+		// do nothing and return directly.
+	}
+	else
+	{
+		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
+		{
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+		}
+		else
+		{	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
+				/*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
+				(pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
+				(pHTTXContext->bCurWriting == FALSE))
+			{
+				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
+			}
+
+			RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<2);
+			RTUSBKickBulkOut(pAd);
+		}
+	}
+
+		return;
+}
+
+
+static void rt2870_ac1_dma_done_tasklet(unsigned long data)
+{
+	PRTMP_ADAPTER		pAd;
+	PHT_TX_CONTEXT		pHTTXContext;
+	UCHAR				BulkOutPipeId = 1;
+	purbb_t				pUrb;
+
+
+	pUrb			= (purbb_t)data;
+	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
+	pAd				= pHTTXContext->pAd;
+
+	rt2870_dataout_complete_tasklet((unsigned long)pUrb);
+
+	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+								fRTMP_ADAPTER_HALT_IN_PROGRESS |
+								fRTMP_ADAPTER_NIC_NOT_EXIST))))
+	{
+		// do nothing and return directly.
+	}
+	else
+	{
+		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
+		{
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+		}
+		else
+		{	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
+				/*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
+				(pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
+				(pHTTXContext->bCurWriting == FALSE))
+			{
+				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
+			}
+
+			RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<1);
+			RTUSBKickBulkOut(pAd);
+		}
+	}
+
+
+	return;
+}
+
+
+static void rt2870_ac0_dma_done_tasklet(unsigned long data)
+{
+	PRTMP_ADAPTER		pAd;
+	PHT_TX_CONTEXT		pHTTXContext;
+	UCHAR				BulkOutPipeId = 0;
+	purbb_t				pUrb;
+
+
+	pUrb			= (purbb_t)data;
+	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
+	pAd				= pHTTXContext->pAd;
+
+	rt2870_dataout_complete_tasklet((unsigned long)pUrb);
+
+	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+								fRTMP_ADAPTER_HALT_IN_PROGRESS |
+								fRTMP_ADAPTER_NIC_NOT_EXIST))))
+	{
+		// do nothing and return directly.
+	}
+	else
+	{
+		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
+		{
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+		}
+		else
+		{	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
+				/*  ((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
+				(pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
+				(pHTTXContext->bCurWriting == FALSE))
+			{
+				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
+			}
+
+			RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL);
+			RTUSBKickBulkOut(pAd);
+		}
+	}
+
+
+	return;
+
+}
+
+
+static void rt2870_null_frame_complete_tasklet(unsigned long data)
+{
+	PRTMP_ADAPTER	pAd;
+	PTX_CONTEXT		pNullContext;
+	purbb_t			pUrb;
+	NTSTATUS		Status;
+	unsigned long	irqFlag;
+
+
+	pUrb			= (purbb_t)data;
+	pNullContext	= (PTX_CONTEXT)pUrb->context;
+	pAd 			= pNullContext->pAd;
+	Status 			= pUrb->status;
+
+	// Reset Null frame context flags
+	RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
+	pNullContext->IRPPending 	= FALSE;
+	pNullContext->InUse 		= FALSE;
+	pAd->BulkOutPending[0] = FALSE;
+	pAd->watchDogTxPendingCnt[0] = 0;
+
+	if (Status == USB_ST_NOERROR)
+	{
+		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+
+		RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+	}
+	else	// STATUS_OTHER
+	{
+		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
+		{
+			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out Null Frame Failed, ReasonCode=%d!\n", Status));
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+			pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
+			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+		}
+		else
+		{
+			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+		}
+	}
+
+	// Always call Bulk routine, even reset bulk.
+	// The protectioon of rest bulk should be in BulkOut routine
+	RTUSBKickBulkOut(pAd);
+
+}
+
+
+static void rt2870_rts_frame_complete_tasklet(unsigned long data)
+{
+	PRTMP_ADAPTER	pAd;
+	PTX_CONTEXT		pRTSContext;
+	purbb_t			pUrb;
+	NTSTATUS		Status;
+	unsigned long	irqFlag;
+
+
+	pUrb		= (purbb_t)data;
+	pRTSContext	= (PTX_CONTEXT)pUrb->context;
+	pAd			= pRTSContext->pAd;
+	Status		= pUrb->status;
+
+	// Reset RTS frame context flags
+	RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
+	pRTSContext->IRPPending = FALSE;
+	pRTSContext->InUse		= FALSE;
+
+	if (Status == USB_ST_NOERROR)
+	{
+		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+		RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+	}
+	else	// STATUS_OTHER
+	{
+		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
+		{
+			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out RTS Frame Failed\n"));
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+			pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
+			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+		}
+		else
+		{
+			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+		}
+	}
+
+	RTMP_SEM_LOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
+	pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE;
+	RTMP_SEM_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
+
+	// Always call Bulk routine, even reset bulk.
+	// The protectioon of rest bulk should be in BulkOut routine
+	RTUSBKickBulkOut(pAd);
+
+}
+
+
+static void rt2870_pspoll_frame_complete_tasklet(unsigned long data)
+{
+	PRTMP_ADAPTER	pAd;
+	PTX_CONTEXT		pPsPollContext;
+	purbb_t			pUrb;
+	NTSTATUS		Status;
+
+
+	pUrb			= (purbb_t)data;
+	pPsPollContext	= (PTX_CONTEXT)pUrb->context;
+	pAd				= pPsPollContext->pAd;
+	Status			= pUrb->status;
+
+	// Reset PsPoll context flags
+	pPsPollContext->IRPPending	= FALSE;
+	pPsPollContext->InUse		= FALSE;
+	pAd->watchDogTxPendingCnt[0] = 0;
+
+	if (Status == USB_ST_NOERROR)
+	{
+		RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+	}
+	else // STATUS_OTHER
+	{
+		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
+		{
+			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out PSPoll Failed\n"));
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+			pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+		}
+	}
+
+	RTMP_SEM_LOCK(&pAd->BulkOutLock[0]);
+	pAd->BulkOutPending[0] = FALSE;
+	RTMP_SEM_UNLOCK(&pAd->BulkOutLock[0]);
+
+	// Always call Bulk routine, even reset bulk.
+	// The protectioon of rest bulk should be in BulkOut routine
+	RTUSBKickBulkOut(pAd);
+
+}
+
+
+static void rt2870_dataout_complete_tasklet(unsigned long data)
+{
+	PRTMP_ADAPTER		pAd;
+	purbb_t				pUrb;
+	POS_COOKIE			pObj;
+	PHT_TX_CONTEXT		pHTTXContext;
+	UCHAR				BulkOutPipeId;
+	NTSTATUS			Status;
+	unsigned long		IrqFlags;
+
+
+	pUrb			= (purbb_t)data;
+	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
+	pAd				= pHTTXContext->pAd;
+	pObj 			= (POS_COOKIE) pAd->OS_Cookie;
+	Status			= pUrb->status;
+
+	// Store BulkOut PipeId
+	BulkOutPipeId = pHTTXContext->BulkOutPipeId;
+	pAd->BulkOutDataOneSecCount++;
+
+	//DBGPRINT(RT_DEBUG_LOUD, ("Done-B(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", BulkOutPipeId, in_interrupt(), pHTTXContext->CurWritePosition,
+	//		pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
+
+	RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+	pAd->BulkOutPending[BulkOutPipeId] = FALSE;
+	pHTTXContext->IRPPending = FALSE;
+	pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
+
+	if (Status == USB_ST_NOERROR)
+	{
+		pAd->BulkOutComplete++;
+
+		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+		pAd->Counters8023.GoodTransmits++;
+		//RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+		FREE_HTTX_RING(pAd, BulkOutPipeId, pHTTXContext);
+		//RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+
+
+	}
+	else	// STATUS_OTHER
+	{
+		PUCHAR	pBuf;
+
+		pAd->BulkOutCompleteOther++;
+
+		pBuf = &pHTTXContext->TransferBuffer->field.WirelessPacket[pHTTXContext->NextBulkOutPosition];
+
+		if (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+									fRTMP_ADAPTER_HALT_IN_PROGRESS |
+									fRTMP_ADAPTER_NIC_NOT_EXIST |
+									fRTMP_ADAPTER_BULKOUT_RESET)))
+		{
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+			pAd->bulkResetPipeid = BulkOutPipeId;
+			pAd->bulkResetReq[BulkOutPipeId] = pAd->BulkOutReq;
+		}
+		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+		DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkOutDataPacket failed: ReasonCode=%d!\n", Status));
+		DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
+		DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Header:%x %x %x %x %x %x %x %x\n", pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], pBuf[5], pBuf[6], pBuf[7]));
+		//DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOutCompleteCancel=0x%x, BulkOutCompleteOther=0x%x\n", pAd->BulkOutCompleteCancel, pAd->BulkOutCompleteOther));
+
+	}
+
+	//
+	// bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut
+	// bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out.
+	//
+	//RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+	if ((pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition) &&
+		(pHTTXContext->ENextBulkOutPosition != (pHTTXContext->CurWritePosition+8)) &&
+		!RTUSB_TEST_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)))
+	{
+		// Indicate There is data avaliable
+		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
+	}
+	//RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+
+	// Always call Bulk routine, even reset bulk.
+	// The protection of rest bulk should be in BulkOut routine
+	RTUSBKickBulkOut(pAd);
+}
+
+/* End of 2870_rtmp_init.c */
diff --git a/drivers/staging/rt3070/common/action.c b/drivers/staging/rt3070/common/action.c
new file mode 100644
index 0000000..b8ae536
--- /dev/null
+++ b/drivers/staging/rt3070/common/action.c
@@ -0,0 +1,1038 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+	action.c
+
+    Abstract:
+    Handle association related requests either from WSTA or from local MLME
+
+    Revision History:
+    Who         When          What
+    --------    ----------    ----------------------------------------------
+	Jan Lee		2006	  	created for rt2860
+ */
+
+#include "../rt_config.h"
+#include "../action.h"
+
+
+static VOID ReservedAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem);
+
+/*
+    ==========================================================================
+    Description:
+        association state machine init, including state transition and timer init
+    Parameters:
+        S - pointer to the association state machine
+    Note:
+        The state machine looks like the following
+
+                                    ASSOC_IDLE
+        MT2_MLME_DISASSOC_REQ    mlme_disassoc_req_action
+        MT2_PEER_DISASSOC_REQ    peer_disassoc_action
+        MT2_PEER_ASSOC_REQ       drop
+        MT2_PEER_REASSOC_REQ     drop
+        MT2_CLS3ERR              cls3err_action
+    ==========================================================================
+ */
+VOID ActionStateMachineInit(
+    IN	PRTMP_ADAPTER	pAd,
+    IN  STATE_MACHINE *S,
+    OUT STATE_MACHINE_FUNC Trans[])
+{
+	StateMachineInit(S, (STATE_MACHINE_FUNC *)Trans, MAX_ACT_STATE, MAX_ACT_MSG, (STATE_MACHINE_FUNC)Drop, ACT_IDLE, ACT_MACHINE_BASE);
+
+	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_SPECTRUM_CATE, (STATE_MACHINE_FUNC)PeerSpectrumAction);
+	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_QOS_CATE, (STATE_MACHINE_FUNC)PeerQOSAction);
+
+	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE, (STATE_MACHINE_FUNC)ReservedAction);
+#ifdef QOS_DLS_SUPPORT
+		StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE, (STATE_MACHINE_FUNC)PeerDLSAction);
+#endif // QOS_DLS_SUPPORT //
+
+#ifdef DOT11_N_SUPPORT
+	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_BA_CATE, (STATE_MACHINE_FUNC)PeerBAAction);
+	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_HT_CATE, (STATE_MACHINE_FUNC)PeerHTAction);
+	StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ADD_BA_CATE, (STATE_MACHINE_FUNC)MlmeADDBAAction);
+	StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ORI_DELBA_CATE, (STATE_MACHINE_FUNC)MlmeDELBAAction);
+	StateMachineSetAction(S, ACT_IDLE, MT2_MLME_REC_DELBA_CATE, (STATE_MACHINE_FUNC)MlmeDELBAAction);
+#endif // DOT11_N_SUPPORT //
+
+	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_PUBLIC_CATE, (STATE_MACHINE_FUNC)PeerPublicAction);
+	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_RM_CATE, (STATE_MACHINE_FUNC)PeerRMAction);
+
+	StateMachineSetAction(S, ACT_IDLE, MT2_MLME_QOS_CATE, (STATE_MACHINE_FUNC)MlmeQOSAction);
+	StateMachineSetAction(S, ACT_IDLE, MT2_MLME_DLS_CATE, (STATE_MACHINE_FUNC)MlmeDLSAction);
+	StateMachineSetAction(S, ACT_IDLE, MT2_ACT_INVALID, (STATE_MACHINE_FUNC)MlmeInvalidAction);
+}
+
+#ifdef DOT11_N_SUPPORT
+VOID MlmeADDBAAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem)
+
+{
+	MLME_ADDBA_REQ_STRUCT *pInfo;
+	UCHAR           Addr[6];
+	PUCHAR         pOutBuffer = NULL;
+	NDIS_STATUS     NStatus;
+	ULONG		Idx;
+	FRAME_ADDBA_REQ  Frame;
+	ULONG		FrameLen;
+	BA_ORI_ENTRY			*pBAEntry = NULL;
+
+	pInfo = (MLME_ADDBA_REQ_STRUCT *)Elem->Msg;
+	NdisZeroMemory(&Frame, sizeof(FRAME_ADDBA_REQ));
+
+	if(MlmeAddBAReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr))
+	{
+		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
+		if(NStatus != NDIS_STATUS_SUCCESS)
+		{
+			DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeADDBAAction() allocate memory failed \n"));
+			return;
+		}
+		// 1. find entry
+		Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
+		if (Idx == 0)
+		{
+			MlmeFreeMemory(pAd, pOutBuffer);
+			DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() can't find BAOriEntry \n"));
+			return;
+		}
+		else
+		{
+			pBAEntry =&pAd->BATable.BAOriEntry[Idx];
+		}
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+			if (ADHOC_ON(pAd))
+				ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+			else
+				ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pInfo->pAddr);
+
+		}
+#endif // CONFIG_STA_SUPPORT //
+
+		Frame.Category = CATEGORY_BA;
+		Frame.Action = ADDBA_REQ;
+		Frame.BaParm.AMSDUSupported = 0;
+		Frame.BaParm.BAPolicy = IMMED_BA;
+		Frame.BaParm.TID = pInfo->TID;
+		Frame.BaParm.BufSize = pInfo->BaBufSize;
+		Frame.Token = pInfo->Token;
+		Frame.TimeOutValue = pInfo->TimeOutValue;
+		Frame.BaStartSeq.field.FragNum = 0;
+		Frame.BaStartSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID];
+
+		*(USHORT *)(&Frame.BaParm) = cpu2le16(*(USHORT *)(&Frame.BaParm));
+		Frame.TimeOutValue = cpu2le16(Frame.TimeOutValue);
+		Frame.BaStartSeq.word = cpu2le16(Frame.BaStartSeq.word);
+
+		MakeOutgoingFrame(pOutBuffer,		   &FrameLen,
+		              sizeof(FRAME_ADDBA_REQ), &Frame,
+		              END_OF_ARGS);
+		MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+		//MiniportDataMMRequest(pAd, MapUserPriorityToAccessCategory[pInfo->TID], pOutBuffer, FrameLen);
+		MlmeFreeMemory(pAd, pOutBuffer);
+
+		DBGPRINT(RT_DEBUG_TRACE, ("BA - Send ADDBA request. StartSeq = %x,  FrameLen = %ld. BufSize = %d\n", Frame.BaStartSeq.field.StartSeq, FrameLen, Frame.BaParm.BufSize));
+    }
+}
+
+/*
+    ==========================================================================
+    Description:
+        send DELBA and delete BaEntry if any
+    Parametrs:
+        Elem - MLME message MLME_DELBA_REQ_STRUCT
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+VOID MlmeDELBAAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem)
+{
+	MLME_DELBA_REQ_STRUCT *pInfo;
+	PUCHAR         pOutBuffer = NULL;
+	PUCHAR		   pOutBuffer2 = NULL;
+	NDIS_STATUS     NStatus;
+	ULONG		Idx;
+	FRAME_DELBA_REQ  Frame;
+	ULONG		FrameLen;
+	FRAME_BAR	FrameBar;
+
+	pInfo = (MLME_DELBA_REQ_STRUCT *)Elem->Msg;
+	// must send back DELBA
+	NdisZeroMemory(&Frame, sizeof(FRAME_DELBA_REQ));
+	DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeDELBAAction(), Initiator(%d) \n", pInfo->Initiator));
+
+	if(MlmeDelBAReqSanity(pAd, Elem->Msg, Elem->MsgLen))
+	{
+		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
+		if(NStatus != NDIS_STATUS_SUCCESS)
+		{
+			DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeDELBAAction() allocate memory failed 1. \n"));
+			return;
+		}
+
+		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2);  //Get an unused nonpaged memory
+		if(NStatus != NDIS_STATUS_SUCCESS)
+		{
+			MlmeFreeMemory(pAd, pOutBuffer);
+			DBGPRINT(RT_DEBUG_ERROR, ("BA - MlmeDELBAAction() allocate memory failed 2. \n"));
+			return;
+		}
+
+		// SEND BAR (Send BAR to refresh peer reordering buffer.)
+		Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+			BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress);
+#endif // CONFIG_STA_SUPPORT //
+
+		FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL funciton.
+		FrameBar.StartingSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID]; // make sure sequence not clear in DEL funciton.
+		FrameBar.BarControl.TID = pInfo->TID; // make sure sequence not clear in DEL funciton.
+		FrameBar.BarControl.ACKPolicy = IMMED_BA; // make sure sequence not clear in DEL funciton.
+		FrameBar.BarControl.Compressed = 1; // make sure sequence not clear in DEL funciton.
+		FrameBar.BarControl.MTID = 0; // make sure sequence not clear in DEL funciton.
+
+		MakeOutgoingFrame(pOutBuffer2,				&FrameLen,
+					  sizeof(FRAME_BAR),	  &FrameBar,
+					  END_OF_ARGS);
+		MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen);
+		MlmeFreeMemory(pAd, pOutBuffer2);
+		DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n"));
+
+		// SEND DELBA FRAME
+		FrameLen = 0;
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+			if (ADHOC_ON(pAd))
+				ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+			else
+				ActHeaderInit(pAd, &Frame.Hdr,  pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[pInfo->Wcid].Addr);
+		}
+#endif // CONFIG_STA_SUPPORT //
+		Frame.Category = CATEGORY_BA;
+		Frame.Action = DELBA;
+		Frame.DelbaParm.Initiator = pInfo->Initiator;
+		Frame.DelbaParm.TID = pInfo->TID;
+		Frame.ReasonCode = 39; // Time Out
+		*(USHORT *)(&Frame.DelbaParm) = cpu2le16(*(USHORT *)(&Frame.DelbaParm));
+		Frame.ReasonCode = cpu2le16(Frame.ReasonCode);
+
+		MakeOutgoingFrame(pOutBuffer,               &FrameLen,
+		              sizeof(FRAME_DELBA_REQ),    &Frame,
+		              END_OF_ARGS);
+		MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+		MlmeFreeMemory(pAd, pOutBuffer);
+		DBGPRINT(RT_DEBUG_TRACE, ("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n", pInfo->Initiator));
+    	}
+}
+#endif // DOT11_N_SUPPORT //
+
+VOID MlmeQOSAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem)
+{
+}
+
+VOID MlmeDLSAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem)
+{
+}
+
+VOID MlmeInvalidAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem)
+{
+	//PUCHAR		   pOutBuffer = NULL;
+	//Return the receiving frame except the MSB of category filed set to 1.  7.3.1.11
+}
+
+VOID PeerQOSAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+}
+
+#ifdef QOS_DLS_SUPPORT
+VOID PeerDLSAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	UCHAR	Action = Elem->Msg[LENGTH_802_11+1];
+
+	switch(Action)
+	{
+		case ACTION_DLS_REQUEST:
+#ifdef CONFIG_STA_SUPPORT
+			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+			PeerDlsReqAction(pAd, Elem);
+#endif // CONFIG_STA_SUPPORT //
+			break;
+
+		case ACTION_DLS_RESPONSE:
+#ifdef CONFIG_STA_SUPPORT
+			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+			PeerDlsRspAction(pAd, Elem);
+#endif // CONFIG_STA_SUPPORT //
+			break;
+
+		case ACTION_DLS_TEARDOWN:
+#ifdef CONFIG_STA_SUPPORT
+			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+			PeerDlsTearDownAction(pAd, Elem);
+#endif // CONFIG_STA_SUPPORT //
+			break;
+	}
+}
+#endif // QOS_DLS_SUPPORT //
+
+#ifdef DOT11_N_SUPPORT
+VOID PeerBAAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	UCHAR	Action = Elem->Msg[LENGTH_802_11+1];
+
+	switch(Action)
+	{
+		case ADDBA_REQ:
+			PeerAddBAReqAction(pAd,Elem);
+			break;
+		case ADDBA_RESP:
+			PeerAddBARspAction(pAd,Elem);
+			break;
+		case DELBA:
+			PeerDelBAAction(pAd,Elem);
+			break;
+	}
+}
+
+
+#ifdef DOT11N_DRAFT3
+
+#ifdef CONFIG_STA_SUPPORT
+VOID StaPublicAction(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR Bss2040Coexist)
+{
+	BSS_2040_COEXIST_IE		BssCoexist;
+	MLME_SCAN_REQ_STRUCT			ScanReq;
+
+	BssCoexist.word = Bss2040Coexist;
+	// AP asks Station to return a 20/40 BSS Coexistence mgmt frame.  So we first starts a scan, then send back 20/40 BSS Coexistence mgmt frame
+	if ((BssCoexist.field.InfoReq == 1) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SCAN_2040)))
+	{
+		// Clear record first.  After scan , will update those bit and send back to transmiter.
+		pAd->CommonCfg.BSSCoexist2040.field.InfoReq = 1;
+		pAd->CommonCfg.BSSCoexist2040.field.Intolerant40 = 0;
+		pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq = 0;
+		// Fill out stuff for scan request
+		ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_2040_BSS_COEXIST);
+		MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
+		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
+	}
+}
+
+
+/*
+Description : Build Intolerant Channel Rerpot from Trigger event table.
+return : how many bytes copied.
+*/
+ULONG BuildIntolerantChannelRep(
+	IN	PRTMP_ADAPTER	pAd,
+	IN    PUCHAR  pDest)
+{
+	ULONG			FrameLen = 0;
+	ULONG			ReadOffset = 0;
+	UCHAR			i;
+	UCHAR			LastRegClass = 0xff;
+	PUCHAR			pLen;
+
+	for ( i = 0;i < MAX_TRIGGER_EVENT;i++)
+	{
+		if (pAd->CommonCfg.TriggerEventTab.EventA[i].bValid == TRUE)
+		{
+			if (pAd->CommonCfg.TriggerEventTab.EventA[i].RegClass == LastRegClass)
+			{
+				*(pDest + ReadOffset) = (UCHAR)pAd->CommonCfg.TriggerEventTab.EventA[i].Channel;
+				*pLen++;
+				ReadOffset++;
+				FrameLen++;
+			}
+			else
+			{
+				*(pDest + ReadOffset) = IE_2040_BSS_INTOLERANT_REPORT;  // IE
+				*(pDest + ReadOffset + 1) = 2;	// Len = RegClass byte + channel byte.
+				pLen = pDest + ReadOffset + 1;
+				LastRegClass = pAd->CommonCfg.TriggerEventTab.EventA[i].RegClass;
+				*(pDest + ReadOffset + 2) = LastRegClass;	// Len = RegClass byte + channel byte.
+				*(pDest + ReadOffset + 3) = (UCHAR)pAd->CommonCfg.TriggerEventTab.EventA[i].Channel;
+				FrameLen += 4;
+				ReadOffset += 4;
+			}
+
+		}
+	}
+	return FrameLen;
+}
+
+
+/*
+Description : Send 20/40 BSS Coexistence Action frame If one trigger event is triggered.
+*/
+VOID Send2040CoexistAction(
+	IN	PRTMP_ADAPTER	pAd,
+	IN    UCHAR  Wcid,
+	IN	BOOLEAN	bAddIntolerantCha)
+{
+	PUCHAR			pOutBuffer = NULL;
+	NDIS_STATUS 	NStatus;
+	FRAME_ACTION_HDR	Frame;
+	ULONG			FrameLen;
+	ULONG			IntolerantChaRepLen;
+
+	IntolerantChaRepLen = 0;
+	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
+	if(NStatus != NDIS_STATUS_SUCCESS)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("ACT - Send2040CoexistAction() allocate memory failed \n"));
+		return;
+	}
+	ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[Wcid].Addr, pAd->CommonCfg.Bssid);
+	Frame.Category = CATEGORY_PUBLIC;
+	Frame.Action = ACTION_BSS_2040_COEXIST;
+
+	MakeOutgoingFrame(pOutBuffer,				&FrameLen,
+				  sizeof(FRAME_ACTION_HDR),	  &Frame,
+				  END_OF_ARGS);
+
+	*(pOutBuffer + FrameLen) = pAd->CommonCfg.BSSCoexist2040.word;
+	FrameLen++;
+
+	if (bAddIntolerantCha == TRUE)
+		IntolerantChaRepLen = BuildIntolerantChannelRep(pAd, pOutBuffer + FrameLen);
+
+	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen + IntolerantChaRepLen);
+	DBGPRINT(RT_DEBUG_ERROR,("ACT - Send2040CoexistAction( BSSCoexist2040 = 0x%x )  \n", pAd->CommonCfg.BSSCoexist2040.word));
+
+}
+
+
+/*
+	==========================================================================
+	Description:
+	After scan, Update 20/40 BSS Coexistence IE and send out.
+	According to 802.11n D3.03 11.14.10
+
+	Parameters:
+	==========================================================================
+ */
+VOID Update2040CoexistFrameAndNotify(
+	IN	PRTMP_ADAPTER	pAd,
+	IN    UCHAR  Wcid,
+	IN	BOOLEAN	bAddIntolerantCha)
+{
+	BSS_2040_COEXIST_IE	OldValue;
+
+	OldValue.word = pAd->CommonCfg.BSSCoexist2040.word;
+	if ((pAd->CommonCfg.TriggerEventTab.EventANo > 0) || (pAd->CommonCfg.TriggerEventTab.EventBCountDown > 0))
+		pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq = 1;
+
+	// Need to check !!!!
+	// How STA will set Intolerant40 if implementation dependent. Now we don't set this bit first.!!!!!
+	// So Only check BSS20WidthReq change.
+	if (OldValue.field.BSS20WidthReq != pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq)
+	{
+		Send2040CoexistAction(pAd, Wcid, bAddIntolerantCha);
+	}
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+BOOLEAN ChannelSwitchSanityCheck(
+	IN	PRTMP_ADAPTER	pAd,
+	IN    UCHAR  Wcid,
+	IN    UCHAR  NewChannel,
+	IN    UCHAR  Secondary)
+{
+	UCHAR		i;
+
+	if (Wcid >= MAX_LEN_OF_MAC_TABLE)
+		return FALSE;
+
+	if ((NewChannel > 7) && (Secondary == 1))
+		return FALSE;
+
+	if ((NewChannel < 5) && (Secondary == 3))
+		return FALSE;
+
+	// 0. Check if new channel is in the channellist.
+	for (i = 0;i < pAd->ChannelListNum;i++)
+	{
+		if (pAd->ChannelList[i].Channel == NewChannel)
+		{
+			break;
+		}
+	}
+
+	if (i == pAd->ChannelListNum)
+		return FALSE;
+
+	return TRUE;
+}
+
+
+VOID ChannelSwitchAction(
+	IN	PRTMP_ADAPTER	pAd,
+	IN    UCHAR  Wcid,
+	IN    UCHAR  NewChannel,
+	IN    UCHAR  Secondary)
+{
+	UCHAR		BBPValue = 0;
+	ULONG		MACValue;
+
+	DBGPRINT(RT_DEBUG_TRACE,("SPECTRUM - ChannelSwitchAction(NewChannel = %d , Secondary = %d)  \n", NewChannel, Secondary));
+
+	if (ChannelSwitchSanityCheck(pAd, Wcid, NewChannel, Secondary) == FALSE)
+		return;
+
+	// 1.  Switches to BW = 20.
+	if (Secondary == 0)
+	{
+		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+		BBPValue&= (~0x18);
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+		if (pAd->MACVersion == 0x28600100)
+		{
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
+			DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
+		}
+		pAd->CommonCfg.BBPCurrentBW = BW_20;
+		pAd->CommonCfg.Channel = NewChannel;
+		pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
+		AsicSwitchChannel(pAd, pAd->CommonCfg.Channel,FALSE);
+		AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+		pAd->MacTab.Content[Wcid].HTPhyMode.field.BW = 0;
+		DBGPRINT(RT_DEBUG_TRACE, ("!!!20MHz   !!! \n" ));
+	}
+	// 1.  Switches to BW = 40 And Station supports BW = 40.
+	else if (((Secondary == 1) || (Secondary == 3)) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == 1))
+	{
+		pAd->CommonCfg.Channel = NewChannel;
+
+		if (Secondary == 1)
+		{
+			// Secondary above.
+			pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
+			RTMP_IO_READ32(pAd, TX_BAND_CFG, &MACValue);
+			MACValue &= 0xfe;
+			RTMP_IO_WRITE32(pAd, TX_BAND_CFG, MACValue);
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+			BBPValue&= (~0x18);
+			BBPValue|= (0x10);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPValue);
+			BBPValue&= (~0x20);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPValue);
+			DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
+		}
+		else
+		{
+			// Secondary below.
+			pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
+			RTMP_IO_READ32(pAd, TX_BAND_CFG, &MACValue);
+			MACValue &= 0xfe;
+			MACValue |= 0x1;
+			RTMP_IO_WRITE32(pAd, TX_BAND_CFG, MACValue);
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+			BBPValue&= (~0x18);
+			BBPValue|= (0x10);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPValue);
+			BBPValue&= (~0x20);
+			BBPValue|= (0x20);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPValue);
+			DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
+		}
+		pAd->CommonCfg.BBPCurrentBW = BW_40;
+		AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+		AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+		pAd->MacTab.Content[Wcid].HTPhyMode.field.BW = 1;
+	}
+}
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+
+VOID PeerPublicAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+#ifdef DOT11N_DRAFT3
+	UCHAR	Action = Elem->Msg[LENGTH_802_11+1];
+#endif // DOT11N_DRAFT3 //
+
+	if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
+		return;
+
+#ifdef DOT11N_DRAFT3
+	switch(Action)
+	{
+		case ACTION_BSS_2040_COEXIST:	// Format defined in IEEE 7.4.7a.1 in 11n Draf3.03
+			{
+				//UCHAR	BssCoexist;
+				BSS_2040_COEXIST_ELEMENT		*pCoexistInfo;
+				BSS_2040_COEXIST_IE 			*pBssCoexistIe;
+				BSS_2040_INTOLERANT_CH_REPORT	*pIntolerantReport = NULL;
+
+				if (Elem->MsgLen <= (LENGTH_802_11 + sizeof(BSS_2040_COEXIST_ELEMENT)) )
+				{
+					DBGPRINT(RT_DEBUG_ERROR, ("ACTION - 20/40 BSS Coexistence Management Frame length too short! len = %ld!\n", Elem->MsgLen));
+					break;
+				}
+				DBGPRINT(RT_DEBUG_TRACE, ("ACTION - 20/40 BSS Coexistence Management action----> \n"));
+				hex_dump("CoexistenceMgmtFrame", Elem->Msg, Elem->MsgLen);
+
+
+				pCoexistInfo = (BSS_2040_COEXIST_ELEMENT *) &Elem->Msg[LENGTH_802_11+2];
+				//hex_dump("CoexistInfo", (PUCHAR)pCoexistInfo, sizeof(BSS_2040_COEXIST_ELEMENT));
+				if (Elem->MsgLen >= (LENGTH_802_11 + sizeof(BSS_2040_COEXIST_ELEMENT) + sizeof(BSS_2040_INTOLERANT_CH_REPORT)))
+				{
+					pIntolerantReport = (BSS_2040_INTOLERANT_CH_REPORT *)((PUCHAR)pCoexistInfo + sizeof(BSS_2040_COEXIST_ELEMENT));
+				}
+				//hex_dump("IntolerantReport ", (PUCHAR)pIntolerantReport, sizeof(BSS_2040_INTOLERANT_CH_REPORT));
+
+				pBssCoexistIe = (BSS_2040_COEXIST_IE *)(&pCoexistInfo->BssCoexistIe);
+
+#ifdef CONFIG_STA_SUPPORT
+				IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+				{
+					if (INFRA_ON(pAd))
+					{
+						StaPublicAction(pAd, pCoexistInfo);
+					}
+				}
+#endif // CONFIG_STA_SUPPORT //
+
+			}
+			break;
+	}
+
+#endif // DOT11N_DRAFT3 //
+
+}
+
+
+static VOID ReservedAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	UCHAR Category;
+
+	if (Elem->MsgLen <= LENGTH_802_11)
+	{
+		return;
+	}
+
+	Category = Elem->Msg[LENGTH_802_11];
+	DBGPRINT(RT_DEBUG_TRACE,("Rcv reserved category(%d) Action Frame\n", Category));
+	hex_dump("Reserved Action Frame", &Elem->Msg[0], Elem->MsgLen);
+}
+
+VOID PeerRMAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+
+{
+	return;
+}
+
+#ifdef DOT11_N_SUPPORT
+static VOID respond_ht_information_exchange_action(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	PUCHAR			pOutBuffer = NULL;
+	NDIS_STATUS		NStatus;
+	ULONG			FrameLen;
+	FRAME_HT_INFO	HTINFOframe, *pFrame;
+	UCHAR   		*pAddr;
+
+
+	// 2. Always send back ADDBA Response
+	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	 //Get an unused nonpaged memory
+
+	if (NStatus != NDIS_STATUS_SUCCESS)
+	{
+		DBGPRINT(RT_DEBUG_TRACE,("ACTION - respond_ht_information_exchange_action() allocate memory failed \n"));
+		return;
+	}
+
+	// get RA
+	pFrame = (FRAME_HT_INFO *) &Elem->Msg[0];
+	pAddr = pFrame->Hdr.Addr2;
+
+	NdisZeroMemory(&HTINFOframe, sizeof(FRAME_HT_INFO));
+	// 2-1. Prepare ADDBA Response frame.
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		if (ADHOC_ON(pAd))
+			ActHeaderInit(pAd, &HTINFOframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+		else
+			ActHeaderInit(pAd, &HTINFOframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr);
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	HTINFOframe.Category = CATEGORY_HT;
+	HTINFOframe.Action = HT_INFO_EXCHANGE;
+	HTINFOframe.HT_Info.Request = 0;
+	HTINFOframe.HT_Info.Forty_MHz_Intolerant = pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant;
+	HTINFOframe.HT_Info.STA_Channel_Width	 = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
+
+	MakeOutgoingFrame(pOutBuffer,					&FrameLen,
+					  sizeof(FRAME_HT_INFO),	&HTINFOframe,
+					  END_OF_ARGS);
+
+	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+	MlmeFreeMemory(pAd, pOutBuffer);
+}
+
+
+#ifdef DOT11N_DRAFT3
+VOID SendNotifyBWActionFrame(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR  Wcid,
+	IN UCHAR apidx)
+{
+	PUCHAR			pOutBuffer = NULL;
+	NDIS_STATUS 	NStatus;
+	FRAME_ACTION_HDR	Frame;
+	ULONG			FrameLen;
+	PUCHAR			pAddr1;
+
+
+	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
+	if(NStatus != NDIS_STATUS_SUCCESS)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("ACT - SendNotifyBWAction() allocate memory failed \n"));
+		return;
+	}
+
+	if (Wcid == MCAST_WCID)
+		pAddr1 = &BROADCAST_ADDR[0];
+	else
+		pAddr1 = pAd->MacTab.Content[Wcid].Addr;
+	ActHeaderInit(pAd, &Frame.Hdr, pAddr1, pAd->ApCfg.MBSSID[apidx].Bssid, pAd->ApCfg.MBSSID[apidx].Bssid);
+
+	Frame.Category = CATEGORY_HT;
+	Frame.Action = NOTIFY_BW_ACTION;
+
+	MakeOutgoingFrame(pOutBuffer,				&FrameLen,
+				  sizeof(FRAME_ACTION_HDR),	  &Frame,
+				  END_OF_ARGS);
+
+	*(pOutBuffer + FrameLen) = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
+	FrameLen++;
+
+
+	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+	DBGPRINT(RT_DEBUG_TRACE,("ACT - SendNotifyBWAction(NotifyBW= %d)!\n", pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth));
+
+}
+#endif // DOT11N_DRAFT3 //
+
+
+VOID PeerHTAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	UCHAR	Action = Elem->Msg[LENGTH_802_11+1];
+
+	if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
+		return;
+
+	switch(Action)
+	{
+		case NOTIFY_BW_ACTION:
+			DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Notify Channel bandwidth action----> \n"));
+#ifdef CONFIG_STA_SUPPORT
+			if(pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
+			{
+				// Note, this is to patch DIR-1353 AP. When the AP set to Wep, it will use legacy mode. But AP still keeps
+				// sending BW_Notify Action frame, and cause us to linkup and linkdown.
+				// In legacy mode, don't need to parse HT action frame.
+				DBGPRINT(RT_DEBUG_TRACE,("ACTION -Ignore HT Notify Channel BW when link as legacy mode. BW = %d---> \n",
+								Elem->Msg[LENGTH_802_11+2] ));
+				break;
+			}
+#endif // CONFIG_STA_SUPPORT //
+
+			if (Elem->Msg[LENGTH_802_11+2] == 0)	// 7.4.8.2. if value is 1, keep the same as supported channel bandwidth.
+				pAd->MacTab.Content[Elem->Wcid].HTPhyMode.field.BW = 0;
+
+			break;
+
+		case SMPS_ACTION:
+			// 7.3.1.25
+ 			DBGPRINT(RT_DEBUG_TRACE,("ACTION - SMPS action----> \n"));
+			if (((Elem->Msg[LENGTH_802_11+2]&0x1) == 0))
+			{
+				pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_ENABLE;
+			}
+			else if (((Elem->Msg[LENGTH_802_11+2]&0x2) == 0))
+			{
+				pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_STATIC;
+			}
+			else
+			{
+				pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_DYNAMIC;
+			}
+
+			DBGPRINT(RT_DEBUG_TRACE,("Aid(%d) MIMO PS = %d\n", Elem->Wcid, pAd->MacTab.Content[Elem->Wcid].MmpsMode));
+			// rt2860c : add something for smps change.
+			break;
+
+		case SETPCO_ACTION:
+			break;
+
+		case MIMO_CHA_MEASURE_ACTION:
+			break;
+
+		case HT_INFO_EXCHANGE:
+			{
+				HT_INFORMATION_OCTET	*pHT_info;
+
+				pHT_info = (HT_INFORMATION_OCTET *) &Elem->Msg[LENGTH_802_11+2];
+    				// 7.4.8.10
+    				DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Information Exchange action----> \n"));
+    				if (pHT_info->Request)
+    				{
+    					respond_ht_information_exchange_action(pAd, Elem);
+    				}
+			}
+    			break;
+	}
+}
+
+
+/*
+	==========================================================================
+	Description:
+		Retry sending ADDBA Reqest.
+
+	IRQL = DISPATCH_LEVEL
+
+	Parametrs:
+	p8023Header: if this is already 802.3 format, p8023Header is NULL
+
+	Return	: TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
+				FALSE , then continue indicaterx at this moment.
+	==========================================================================
+ */
+VOID ORIBATimerTimeout(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	MAC_TABLE_ENTRY	*pEntry;
+	INT			i, total;
+//	FRAME_BAR			FrameBar;
+//	ULONG			FrameLen;
+//	NDIS_STATUS 	NStatus;
+//	PUCHAR			pOutBuffer = NULL;
+//	USHORT			Sequence;
+	UCHAR			TID;
+
+#ifdef RALINK_ATE
+	if (ATE_ON(pAd))
+		return;
+#endif // RALINK_ATE //
+
+	total = pAd->MacTab.Size * NUM_OF_TID;
+
+	for (i = 1; ((i <MAX_LEN_OF_BA_ORI_TABLE) && (total > 0)) ; i++)
+	{
+		if  (pAd->BATable.BAOriEntry[i].ORI_BA_Status == Originator_Done)
+		{
+			pEntry = &pAd->MacTab.Content[pAd->BATable.BAOriEntry[i].Wcid];
+			TID = pAd->BATable.BAOriEntry[i].TID;
+
+			ASSERT(pAd->BATable.BAOriEntry[i].Wcid < MAX_LEN_OF_MAC_TABLE);
+		}
+		total --;
+	}
+}
+
+
+VOID SendRefreshBAR(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	MAC_TABLE_ENTRY	*pEntry)
+{
+	FRAME_BAR		FrameBar;
+	ULONG			FrameLen;
+	NDIS_STATUS 	NStatus;
+	PUCHAR			pOutBuffer = NULL;
+	USHORT			Sequence;
+	UCHAR			i, TID;
+	USHORT			idx;
+	BA_ORI_ENTRY	*pBAEntry;
+
+	for (i = 0; i <NUM_OF_TID; i++)
+	{
+		idx = pEntry->BAOriWcidArray[i];
+		if (idx == 0)
+		{
+			continue;
+		}
+		pBAEntry = &pAd->BATable.BAOriEntry[idx];
+
+		if  (pBAEntry->ORI_BA_Status == Originator_Done)
+		{
+			TID = pBAEntry->TID;
+
+			ASSERT(pBAEntry->Wcid < MAX_LEN_OF_MAC_TABLE);
+
+			NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
+			if(NStatus != NDIS_STATUS_SUCCESS)
+			{
+				DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n"));
+				return;
+			}
+
+			Sequence = pEntry->TxSeq[TID];
+
+
+#ifdef CONFIG_STA_SUPPORT
+			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+				BarHeaderInit(pAd, &FrameBar, pEntry->Addr, pAd->CurrentAddress);
+#endif // CONFIG_STA_SUPPORT //
+
+			FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL function.
+			FrameBar.StartingSeq.field.StartSeq = Sequence; // make sure sequence not clear in DEL funciton.
+			FrameBar.BarControl.TID = TID; // make sure sequence not clear in DEL funciton.
+
+			MakeOutgoingFrame(pOutBuffer,				&FrameLen,
+							  sizeof(FRAME_BAR),	  &FrameBar,
+							  END_OF_ARGS);
+			//if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET)))
+			if (1)	// Now we always send BAR.
+			{
+				//MiniportMMRequestUnlock(pAd, 0, pOutBuffer, FrameLen);
+				MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+				//MiniportDataMMRequest(pAd, MapUserPriorityToAccessCategory[TID], pOutBuffer, FrameLen);
+			}
+			MlmeFreeMemory(pAd, pOutBuffer);
+		}
+	}
+}
+#endif // DOT11_N_SUPPORT //
+
+VOID ActHeaderInit(
+    IN	PRTMP_ADAPTER	pAd,
+    IN OUT PHEADER_802_11 pHdr80211,
+    IN PUCHAR Addr1,
+    IN PUCHAR Addr2,
+    IN PUCHAR Addr3)
+{
+    NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
+    pHdr80211->FC.Type = BTYPE_MGMT;
+    pHdr80211->FC.SubType = SUBTYPE_ACTION;
+
+    COPY_MAC_ADDR(pHdr80211->Addr1, Addr1);
+	COPY_MAC_ADDR(pHdr80211->Addr2, Addr2);
+    COPY_MAC_ADDR(pHdr80211->Addr3, Addr3);
+}
+
+VOID BarHeaderInit(
+	IN	PRTMP_ADAPTER	pAd,
+	IN OUT PFRAME_BAR pCntlBar,
+	IN PUCHAR pDA,
+	IN PUCHAR pSA)
+{
+//	USHORT	Duration;
+
+	NdisZeroMemory(pCntlBar, sizeof(FRAME_BAR));
+	pCntlBar->FC.Type = BTYPE_CNTL;
+	pCntlBar->FC.SubType = SUBTYPE_BLOCK_ACK_REQ;
+   	pCntlBar->BarControl.MTID = 0;
+	pCntlBar->BarControl.Compressed = 1;
+	pCntlBar->BarControl.ACKPolicy = 0;
+
+
+	pCntlBar->Duration = 16 + RTMPCalcDuration(pAd, RATE_1, sizeof(FRAME_BA));
+
+	COPY_MAC_ADDR(pCntlBar->Addr1, pDA);
+	COPY_MAC_ADDR(pCntlBar->Addr2, pSA);
+}
+
+
+/*
+	==========================================================================
+	Description:
+		Insert Category and action code into the action frame.
+
+	Parametrs:
+		1. frame buffer pointer.
+		2. frame length.
+		3. category code of the frame.
+		4. action code of the frame.
+
+	Return	: None.
+	==========================================================================
+ */
+VOID InsertActField(
+	IN PRTMP_ADAPTER pAd,
+	OUT PUCHAR pFrameBuf,
+	OUT PULONG pFrameLen,
+	IN UINT8 Category,
+	IN UINT8 ActCode)
+{
+	ULONG TempLen;
+
+	MakeOutgoingFrame(	pFrameBuf,		&TempLen,
+						1,				&Category,
+						1,				&ActCode,
+						END_OF_ARGS);
+
+	*pFrameLen = *pFrameLen + TempLen;
+
+	return;
+}
diff --git a/drivers/staging/rt3070/common/ba_action.c b/drivers/staging/rt3070/common/ba_action.c
new file mode 100644
index 0000000..17e1f87
--- /dev/null
+++ b/drivers/staging/rt3070/common/ba_action.c
@@ -0,0 +1,1810 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+ */
+
+
+#ifdef DOT11_N_SUPPORT
+
+#include "../rt_config.h"
+
+
+
+#define BA_ORI_INIT_SEQ		(pEntry->TxSeq[TID]) //1			// inital sequence number of BA session
+
+#define ORI_SESSION_MAX_RETRY	8
+#define ORI_BA_SESSION_TIMEOUT	(2000)	// ms
+#define REC_BA_SESSION_IDLE_TIMEOUT	(1000)	// ms
+
+#define REORDERING_PACKET_TIMEOUT		((100 * HZ)/1000)	// system ticks -- 100 ms
+#define MAX_REORDERING_PACKET_TIMEOUT	((3000 * HZ)/1000)	// system ticks -- 100 ms
+
+#define RESET_RCV_SEQ		(0xFFFF)
+
+static void ba_mpdu_blk_free(PRTMP_ADAPTER pAd, struct reordering_mpdu *mpdu_blk);
+
+
+BA_ORI_ENTRY *BATableAllocOriEntry(
+								  IN  PRTMP_ADAPTER   pAd,
+								  OUT USHORT          *Idx);
+
+BA_REC_ENTRY *BATableAllocRecEntry(
+								  IN  PRTMP_ADAPTER   pAd,
+								  OUT USHORT          *Idx);
+
+VOID BAOriSessionSetupTimeout(
+    IN PVOID SystemSpecific1,
+    IN PVOID FunctionContext,
+    IN PVOID SystemSpecific2,
+    IN PVOID SystemSpecific3);
+
+VOID BARecSessionIdleTimeout(
+    IN PVOID SystemSpecific1,
+    IN PVOID FunctionContext,
+    IN PVOID SystemSpecific2,
+    IN PVOID SystemSpecific3);
+
+
+BUILD_TIMER_FUNCTION(BAOriSessionSetupTimeout);
+BUILD_TIMER_FUNCTION(BARecSessionIdleTimeout);
+
+#define ANNOUNCE_REORDERING_PACKET(_pAd, _mpdu_blk)	\
+			Announce_Reordering_Packet(_pAd, _mpdu_blk);
+
+VOID BA_MaxWinSizeReasign(
+	IN PRTMP_ADAPTER	pAd,
+	IN MAC_TABLE_ENTRY  *pEntryPeer,
+	OUT UCHAR			*pWinSize)
+{
+	UCHAR MaxSize;
+
+
+	if (pAd->MACVersion >= RALINK_2883_VERSION) // 3*3
+	{
+		if (pAd->MACVersion >= RALINK_3070_VERSION)
+		{
+			if (pEntryPeer->WepStatus != Ndis802_11EncryptionDisabled)
+				MaxSize = 7; // for non-open mode
+			else
+				MaxSize = 13;
+		}
+		else
+			MaxSize = 31;
+	}
+	else if (pAd->MACVersion >= RALINK_2880E_VERSION) // 2880 e
+	{
+		if (pEntryPeer->WepStatus != Ndis802_11EncryptionDisabled)
+			MaxSize = 7; // for non-open mode
+		else
+			MaxSize = 13;
+	}
+	else
+		MaxSize = 7;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("ba> Win Size = %d, Max Size = %d\n",
+			*pWinSize, MaxSize));
+
+	if ((*pWinSize) > MaxSize)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("ba> reassign max win size from %d to %d\n",
+				*pWinSize, MaxSize));
+
+		*pWinSize = MaxSize;
+	}
+}
+
+void Announce_Reordering_Packet(IN PRTMP_ADAPTER			pAd,
+								IN struct reordering_mpdu	*mpdu)
+{
+	PNDIS_PACKET    pPacket;
+
+	pPacket = mpdu->pPacket;
+
+	if (mpdu->bAMSDU)
+	{
+		ASSERT(0);
+		BA_Reorder_AMSDU_Annnounce(pAd, pPacket);
+	}
+	else
+	{
+		//
+		// pass this 802.3 packet to upper layer or forward this packet to WM directly
+		//
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+			ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket, RTMP_GET_PACKET_IF(pPacket));
+#endif // CONFIG_STA_SUPPORT //
+	}
+}
+
+/*
+ * Insert a reordering mpdu into sorted linked list by sequence no.
+ */
+BOOLEAN ba_reordering_mpdu_insertsorted(struct reordering_list *list, struct reordering_mpdu *mpdu)
+{
+
+	struct reordering_mpdu **ppScan = &list->next;
+
+	while (*ppScan != NULL)
+	{
+		if (SEQ_SMALLER((*ppScan)->Sequence, mpdu->Sequence, MAXSEQ))
+		{
+			ppScan = &(*ppScan)->next;
+		}
+		else if ((*ppScan)->Sequence == mpdu->Sequence)
+		{
+			/* give up this duplicated frame */
+			return(FALSE);
+		}
+		else
+		{
+			/* find position */
+			break;
+		}
+	}
+
+	mpdu->next = *ppScan;
+	*ppScan = mpdu;
+	list->qlen++;
+	return TRUE;
+}
+
+
+/*
+ * caller lock critical section if necessary
+ */
+static inline void ba_enqueue(struct reordering_list *list, struct reordering_mpdu *mpdu_blk)
+{
+	list->qlen++;
+	mpdu_blk->next = list->next;
+	list->next = mpdu_blk;
+}
+
+/*
+ * caller lock critical section if necessary
+ */
+static inline struct reordering_mpdu * ba_dequeue(struct reordering_list *list)
+{
+	struct reordering_mpdu *mpdu_blk = NULL;
+
+	ASSERT(list);
+
+		if (list->qlen)
+		{
+			list->qlen--;
+			mpdu_blk = list->next;
+			if (mpdu_blk)
+			{
+				list->next = mpdu_blk->next;
+				mpdu_blk->next = NULL;
+			}
+		}
+	return mpdu_blk;
+}
+
+
+static inline struct reordering_mpdu  *ba_reordering_mpdu_dequeue(struct reordering_list *list)
+{
+	return(ba_dequeue(list));
+}
+
+
+static inline struct reordering_mpdu  *ba_reordering_mpdu_probe(struct reordering_list *list)
+	{
+	ASSERT(list);
+
+		return(list->next);
+	}
+
+
+/*
+ * free all resource for reordering mechanism
+ */
+void ba_reordering_resource_release(PRTMP_ADAPTER pAd)
+{
+	BA_TABLE        *Tab;
+	PBA_REC_ENTRY   pBAEntry;
+	struct reordering_mpdu *mpdu_blk;
+	int i;
+
+	Tab = &pAd->BATable;
+
+	/* I.  release all pending reordering packet */
+	NdisAcquireSpinLock(&pAd->BATabLock);
+	for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++)
+	{
+		pBAEntry = &Tab->BARecEntry[i];
+		if (pBAEntry->REC_BA_Status != Recipient_NONE)
+		{
+			while ((mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list)))
+			{
+				ASSERT(mpdu_blk->pPacket);
+				RELEASE_NDIS_PACKET(pAd, mpdu_blk->pPacket, NDIS_STATUS_FAILURE);
+				ba_mpdu_blk_free(pAd, mpdu_blk);
+			}
+		}
+	}
+	NdisReleaseSpinLock(&pAd->BATabLock);
+
+	ASSERT(pBAEntry->list.qlen == 0);
+	/* II. free memory of reordering mpdu table */
+	NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
+	os_free_mem(pAd, pAd->mpdu_blk_pool.mem);
+	NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
+}
+
+
+
+/*
+ * Allocate all resource for reordering mechanism
+ */
+BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num)
+{
+	int     i;
+	PUCHAR  mem;
+	struct reordering_mpdu *mpdu_blk;
+	struct reordering_list *freelist;
+
+	/* allocate spinlock */
+	NdisAllocateSpinLock(&pAd->mpdu_blk_pool.lock);
+
+	/* initialize freelist */
+	freelist = &pAd->mpdu_blk_pool.freelist;
+	freelist->next = NULL;
+	freelist->qlen = 0;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Allocate %d memory for BA reordering\n", (UINT32)(num*sizeof(struct reordering_mpdu))));
+
+	/* allocate number of mpdu_blk memory */
+	os_alloc_mem(pAd, (PUCHAR *)&mem, (num*sizeof(struct reordering_mpdu)));
+
+	pAd->mpdu_blk_pool.mem = mem;
+
+	if (mem == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("Can't Allocate Memory for BA Reordering\n"));
+		return(FALSE);
+	}
+
+	/* build mpdu_blk free list */
+	for (i=0; i<num; i++)
+	{
+		/* get mpdu_blk */
+		mpdu_blk = (struct reordering_mpdu *) mem;
+		/* initial mpdu_blk */
+		NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu));
+		/* next mpdu_blk */
+		mem += sizeof(struct reordering_mpdu);
+		/* insert mpdu_blk into freelist */
+		ba_enqueue(freelist, mpdu_blk);
+	}
+
+	return(TRUE);
+}
+
+//static int blk_count=0; // sample take off, no use
+
+static struct reordering_mpdu *ba_mpdu_blk_alloc(PRTMP_ADAPTER pAd)
+{
+	struct reordering_mpdu *mpdu_blk;
+
+	NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
+	mpdu_blk = ba_dequeue(&pAd->mpdu_blk_pool.freelist);
+	if (mpdu_blk)
+	{
+//		blk_count++;
+		/* reset mpdu_blk */
+		NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu));
+	}
+	NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
+	return mpdu_blk;
+}
+
+static void ba_mpdu_blk_free(PRTMP_ADAPTER pAd, struct reordering_mpdu *mpdu_blk)
+{
+	ASSERT(mpdu_blk);
+
+	NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
+//	blk_count--;
+	ba_enqueue(&pAd->mpdu_blk_pool.freelist, mpdu_blk);
+	NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
+}
+
+
+static USHORT ba_indicate_reordering_mpdus_in_order(
+												   IN PRTMP_ADAPTER    pAd,
+												   IN PBA_REC_ENTRY    pBAEntry,
+												   IN USHORT           StartSeq)
+{
+	struct reordering_mpdu *mpdu_blk;
+	USHORT  LastIndSeq = RESET_RCV_SEQ;
+
+	NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
+
+	while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list)))
+		{
+			/* find in-order frame */
+		if (!SEQ_STEPONE(mpdu_blk->Sequence, StartSeq, MAXSEQ))
+			{
+				break;
+			}
+			/* dequeue in-order frame from reodering list */
+			mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list);
+			/* pass this frame up */
+		ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
+		/* move to next sequence */
+			StartSeq = mpdu_blk->Sequence;
+		LastIndSeq = StartSeq;
+		/* free mpdu_blk */
+			ba_mpdu_blk_free(pAd, mpdu_blk);
+	}
+
+	NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
+
+	/* update last indicated sequence */
+	return LastIndSeq;
+}
+
+static void ba_indicate_reordering_mpdus_le_seq(
+											   IN PRTMP_ADAPTER    pAd,
+											   IN PBA_REC_ENTRY    pBAEntry,
+											   IN USHORT           Sequence)
+{
+	struct reordering_mpdu *mpdu_blk;
+
+	NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
+	while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list)))
+		{
+			/* find in-order frame */
+		if ((mpdu_blk->Sequence == Sequence) || SEQ_SMALLER(mpdu_blk->Sequence, Sequence, MAXSEQ))
+		{
+			/* dequeue in-order frame from reodering list */
+			mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list);
+			/* pass this frame up */
+			ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
+			/* free mpdu_blk */
+			ba_mpdu_blk_free(pAd, mpdu_blk);
+		}
+		else
+			{
+				break;
+			}
+	}
+	NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
+}
+
+
+static void ba_refresh_reordering_mpdus(
+									   IN PRTMP_ADAPTER    pAd,
+									   PBA_REC_ENTRY       pBAEntry)
+{
+	struct reordering_mpdu *mpdu_blk;
+
+	NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
+
+			/* dequeue in-order frame from reodering list */
+	while ((mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list)))
+	{
+			/* pass this frame up */
+		ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
+
+		pBAEntry->LastIndSeq = mpdu_blk->Sequence;
+			ba_mpdu_blk_free(pAd, mpdu_blk);
+
+		/* update last indicated sequence */
+	}
+	ASSERT(pBAEntry->list.qlen == 0);
+	pBAEntry->LastIndSeq = RESET_RCV_SEQ;
+	NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
+}
+
+
+//static
+void ba_flush_reordering_timeout_mpdus(
+									IN PRTMP_ADAPTER    pAd,
+									IN PBA_REC_ENTRY    pBAEntry,
+									IN ULONG            Now32)
+
+{
+	USHORT Sequence;
+
+//	if ((RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+REORDERING_PACKET_TIMEOUT)) &&
+//		 (pBAEntry->list.qlen > ((pBAEntry->BAWinSize*7)/8))) //||
+//		(RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(10*REORDERING_PACKET_TIMEOUT))) &&
+//		 (pBAEntry->list.qlen > (pBAEntry->BAWinSize/8)))
+	if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(MAX_REORDERING_PACKET_TIMEOUT/6)))
+		 &&(pBAEntry->list.qlen > 1)
+		)
+	{
+		DBGPRINT(RT_DEBUG_TRACE,("timeout[%d] (%08lx-%08lx = %d > %d): %x, flush all!\n ", pBAEntry->list.qlen, Now32, (pBAEntry->LastIndSeqAtTimer),
+			   (int)((long) Now32 - (long)(pBAEntry->LastIndSeqAtTimer)), MAX_REORDERING_PACKET_TIMEOUT,
+			   pBAEntry->LastIndSeq));
+		ba_refresh_reordering_mpdus(pAd, pBAEntry);
+		pBAEntry->LastIndSeqAtTimer = Now32;
+	}
+	else
+	if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT)))
+		&& (pBAEntry->list.qlen > 0)
+	   )
+		{
+//		printk("timeout[%d] (%lx-%lx = %d > %d): %x, ", pBAEntry->list.qlen, Now32, (pBAEntry->LastIndSeqAtTimer),
+//			   (int)((long) Now32 - (long)(pBAEntry->LastIndSeqAtTimer)), REORDERING_PACKET_TIMEOUT,
+//			   pBAEntry->LastIndSeq);
+    		//
+		// force LastIndSeq to shift to LastIndSeq+1
+    		//
+    		Sequence = (pBAEntry->LastIndSeq+1) & MAXSEQ;
+    		ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
+    		pBAEntry->LastIndSeqAtTimer = Now32;
+			pBAEntry->LastIndSeq = Sequence;
+    		//
+    		// indicate in-order mpdus
+    		//
+    		Sequence = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, Sequence);
+    		if (Sequence != RESET_RCV_SEQ)
+    		{
+    			pBAEntry->LastIndSeq = Sequence;
+    		}
+
+		//printk("%x, flush one!\n", pBAEntry->LastIndSeq);
+
+	}
+}
+
+
+/*
+ * generate ADDBA request to
+ * set up BA agreement
+ */
+VOID BAOriSessionSetUp(
+					  IN PRTMP_ADAPTER    pAd,
+					  IN MAC_TABLE_ENTRY  *pEntry,
+					  IN UCHAR            TID,
+					  IN USHORT           TimeOut,
+					  IN ULONG            DelayTime,
+					  IN BOOLEAN          isForced)
+
+{
+	//MLME_ADDBA_REQ_STRUCT	AddbaReq;
+	BA_ORI_ENTRY            *pBAEntry = NULL;
+	USHORT                  Idx;
+	BOOLEAN                 Cancelled;
+
+	if ((pAd->CommonCfg.BACapability.field.AutoBA != TRUE)  &&  (isForced == FALSE))
+		return;
+
+	// if this entry is limited to use legacy tx mode, it doesn't generate BA.
+	if (RTMPStaFixedTxMode(pAd, pEntry) != FIXED_TXMODE_HT)
+		return;
+
+	if ((pEntry->BADeclineBitmap & (1<<TID)) && (isForced == FALSE))
+	{
+		// try again after 3 secs
+		DelayTime = 3000;
+//		printk("DeCline BA from Peer\n");
+//		return;
+	}
+
+
+	Idx = pEntry->BAOriWcidArray[TID];
+	if (Idx == 0)
+	{
+		// allocate a BA session
+		pBAEntry = BATableAllocOriEntry(pAd, &Idx);
+		if (pBAEntry == NULL)
+		{
+			DBGPRINT(RT_DEBUG_TRACE,("ADDBA - MlmeADDBAAction() allocate BA session failed \n"));
+			return;
+		}
+	}
+	else
+	{
+		pBAEntry =&pAd->BATable.BAOriEntry[Idx];
+	}
+
+	if (pBAEntry->ORI_BA_Status >= Originator_WaitRes)
+	{
+		return;
+	}
+
+	pEntry->BAOriWcidArray[TID] = Idx;
+
+	// Initialize BA session
+	pBAEntry->ORI_BA_Status = Originator_WaitRes;
+	pBAEntry->Wcid = pEntry->Aid;
+	pBAEntry->BAWinSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit;
+	pBAEntry->Sequence = BA_ORI_INIT_SEQ;
+	pBAEntry->Token = 1;	// (2008-01-21) Jan Lee recommends it - this token can't be 0
+	pBAEntry->TID = TID;
+	pBAEntry->TimeOutValue = TimeOut;
+	pBAEntry->pAdapter = pAd;
+
+	DBGPRINT(RT_DEBUG_TRACE,("Send AddBA to %02x:%02x:%02x:%02x:%02x:%02x Tid:%d isForced:%d Wcid:%d\n"
+		,pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2]
+		,pEntry->Addr[3],pEntry->Addr[4],pEntry->Addr[5]
+		,TID,isForced,pEntry->Aid));
+
+	if (!(pEntry->TXBAbitmap & (1<<TID)))
+	{
+		RTMPInitTimer(pAd, &pBAEntry->ORIBATimer, GET_TIMER_FUNCTION(BAOriSessionSetupTimeout), pBAEntry, FALSE);
+	}
+	else
+		RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
+
+	// set timer to send ADDBA request
+	RTMPSetTimer(&pBAEntry->ORIBATimer, DelayTime);
+}
+
+VOID BAOriSessionAdd(
+			IN PRTMP_ADAPTER    pAd,
+					IN MAC_TABLE_ENTRY  *pEntry,
+			IN PFRAME_ADDBA_RSP pFrame)
+{
+	BA_ORI_ENTRY  *pBAEntry = NULL;
+	BOOLEAN       Cancelled;
+	UCHAR         TID;
+	USHORT        Idx;
+	PUCHAR          pOutBuffer2 = NULL;
+	NDIS_STATUS     NStatus;
+	ULONG           FrameLen;
+	FRAME_BAR       FrameBar;
+
+	TID = pFrame->BaParm.TID;
+	Idx = pEntry->BAOriWcidArray[TID];
+	pBAEntry =&pAd->BATable.BAOriEntry[Idx];
+
+	// Start fill in parameters.
+	if ((Idx !=0) && (pBAEntry->TID == TID) && (pBAEntry->ORI_BA_Status == Originator_WaitRes))
+	{
+		pBAEntry->BAWinSize = min(pBAEntry->BAWinSize, ((UCHAR)pFrame->BaParm.BufSize));
+		BA_MaxWinSizeReasign(pAd, pEntry, &pBAEntry->BAWinSize);
+
+		pBAEntry->TimeOutValue = pFrame->TimeOutValue;
+		pBAEntry->ORI_BA_Status = Originator_Done;
+		// reset sequence number
+		pBAEntry->Sequence = BA_ORI_INIT_SEQ;
+		// Set Bitmap flag.
+		pEntry->TXBAbitmap |= (1<<TID);
+				RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
+
+		pBAEntry->ORIBATimer.TimerValue = 0;	//pFrame->TimeOutValue;
+
+		DBGPRINT(RT_DEBUG_TRACE,("%s : TXBAbitmap = %x, BAWinSize = %d, TimeOut = %ld\n", __FUNCTION__, pEntry->TXBAbitmap,
+								 pBAEntry->BAWinSize, pBAEntry->ORIBATimer.TimerValue));
+
+		// SEND BAR ;
+		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2);  //Get an unused nonpaged memory
+		if (NStatus != NDIS_STATUS_SUCCESS)
+		{
+			DBGPRINT(RT_DEBUG_TRACE,("BA - BAOriSessionAdd() allocate memory failed \n"));
+			return;
+		}
+
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+			BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pBAEntry->Wcid].Addr, pAd->CurrentAddress);
+#endif // CONFIG_STA_SUPPORT //
+
+		FrameBar.StartingSeq.field.FragNum = 0;	// make sure sequence not clear in DEL function.
+		FrameBar.StartingSeq.field.StartSeq = pBAEntry->Sequence; // make sure sequence not clear in DEL funciton.
+		FrameBar.BarControl.TID = pBAEntry->TID; // make sure sequence not clear in DEL funciton.
+		MakeOutgoingFrame(pOutBuffer2,              &FrameLen,
+						  sizeof(FRAME_BAR),      &FrameBar,
+					  END_OF_ARGS);
+		MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen);
+		MlmeFreeMemory(pAd, pOutBuffer2);
+
+
+		if (pBAEntry->ORIBATimer.TimerValue)
+			RTMPSetTimer(&pBAEntry->ORIBATimer, pBAEntry->ORIBATimer.TimerValue); // in mSec
+	}
+}
+
+BOOLEAN BARecSessionAdd(
+					   IN PRTMP_ADAPTER    pAd,
+					   IN MAC_TABLE_ENTRY  *pEntry,
+					   IN PFRAME_ADDBA_REQ pFrame)
+{
+	BA_REC_ENTRY            *pBAEntry = NULL;
+	BOOLEAN                 Status = TRUE;
+	BOOLEAN                 Cancelled;
+	USHORT                  Idx;
+	UCHAR                   TID;
+	UCHAR                   BAWinSize;
+	//UINT32                  Value;
+	//UINT                    offset;
+
+
+	ASSERT(pEntry);
+
+	// find TID
+	TID = pFrame->BaParm.TID;
+
+	BAWinSize = min(((UCHAR)pFrame->BaParm.BufSize), (UCHAR)pAd->CommonCfg.BACapability.field.RxBAWinLimit);
+
+	// Intel patch
+	if (BAWinSize == 0)
+	{
+		BAWinSize = 64;
+	}
+
+	Idx = pEntry->BARecWcidArray[TID];
+
+
+	if (Idx == 0)
+	{
+		pBAEntry = BATableAllocRecEntry(pAd, &Idx);
+	}
+	else
+	{
+		pBAEntry = &pAd->BATable.BARecEntry[Idx];
+		// flush all pending reordering mpdus
+		ba_refresh_reordering_mpdus(pAd, pBAEntry);
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE,("%s(%ld): Idx = %d, BAWinSize(req %d) = %d\n", __FUNCTION__, pAd->BATable.numAsRecipient, Idx,
+							 pFrame->BaParm.BufSize, BAWinSize));
+
+	// Start fill in parameters.
+	if (pBAEntry != NULL)
+	{
+		ASSERT(pBAEntry->list.qlen == 0);
+
+		pBAEntry->REC_BA_Status = Recipient_HandleRes;
+		pBAEntry->BAWinSize = BAWinSize;
+		pBAEntry->Wcid = pEntry->Aid;
+		pBAEntry->TID = TID;
+		pBAEntry->TimeOutValue = pFrame->TimeOutValue;
+		pBAEntry->REC_BA_Status = Recipient_Accept;
+		// initial sequence number
+		pBAEntry->LastIndSeq = RESET_RCV_SEQ; //pFrame->BaStartSeq.field.StartSeq;
+
+		printk("Start Seq = %08x\n",  pFrame->BaStartSeq.field.StartSeq);
+
+		if (pEntry->RXBAbitmap & (1<<TID))
+		{
+			RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
+		}
+		else
+		{
+			RTMPInitTimer(pAd, &pBAEntry->RECBATimer, GET_TIMER_FUNCTION(BARecSessionIdleTimeout), pBAEntry, TRUE);
+		}
+
+		// Set Bitmap flag.
+		pEntry->RXBAbitmap |= (1<<TID);
+		pEntry->BARecWcidArray[TID] = Idx;
+
+		pEntry->BADeclineBitmap &= ~(1<<TID);
+
+		// Set BA session mask in WCID table.
+		RT28XX_ADD_BA_SESSION_TO_ASIC(pAd, pEntry->Aid, TID);
+
+		DBGPRINT(RT_DEBUG_TRACE,("MACEntry[%d]RXBAbitmap = 0x%x. BARecWcidArray=%d\n",
+				pEntry->Aid, pEntry->RXBAbitmap, pEntry->BARecWcidArray[TID]));
+	}
+	else
+	{
+		Status = FALSE;
+		DBGPRINT(RT_DEBUG_TRACE,("Can't Accept ADDBA for %02x:%02x:%02x:%02x:%02x:%02x TID = %d\n",
+				PRINT_MAC(pEntry->Addr), TID));
+	}
+	return(Status);
+}
+
+
+BA_REC_ENTRY *BATableAllocRecEntry(
+								  IN  PRTMP_ADAPTER   pAd,
+								  OUT USHORT          *Idx)
+{
+	int             i;
+	BA_REC_ENTRY    *pBAEntry = NULL;
+
+
+	NdisAcquireSpinLock(&pAd->BATabLock);
+
+	if (pAd->BATable.numAsRecipient >= MAX_BARECI_SESSION)
+	{
+		printk("BA Recipeint Session (%ld) > %d\n", pAd->BATable.numAsRecipient,
+			MAX_BARECI_SESSION);
+		goto done;
+	}
+
+	// reserve idx 0 to identify BAWcidArray[TID] as empty
+	for (i=1; i < MAX_LEN_OF_BA_REC_TABLE; i++)
+	{
+		pBAEntry =&pAd->BATable.BARecEntry[i];
+		if ((pBAEntry->REC_BA_Status == Recipient_NONE))
+		{
+			// get one
+			pAd->BATable.numAsRecipient++;
+			pBAEntry->REC_BA_Status = Recipient_USED;
+			*Idx = i;
+			break;
+		}
+	}
+
+done:
+	NdisReleaseSpinLock(&pAd->BATabLock);
+	return pBAEntry;
+}
+
+BA_ORI_ENTRY *BATableAllocOriEntry(
+								  IN  PRTMP_ADAPTER   pAd,
+								  OUT USHORT          *Idx)
+{
+	int             i;
+	BA_ORI_ENTRY    *pBAEntry = NULL;
+
+	NdisAcquireSpinLock(&pAd->BATabLock);
+
+	if (pAd->BATable.numAsOriginator >= (MAX_LEN_OF_BA_ORI_TABLE))
+	{
+		goto done;
+	}
+
+	// reserve idx 0 to identify BAWcidArray[TID] as empty
+	for (i=1; i<MAX_LEN_OF_BA_ORI_TABLE; i++)
+	{
+		pBAEntry =&pAd->BATable.BAOriEntry[i];
+		if ((pBAEntry->ORI_BA_Status == Originator_NONE))
+		{
+			// get one
+			pAd->BATable.numAsOriginator++;
+			pBAEntry->ORI_BA_Status = Originator_USED;
+			pBAEntry->pAdapter = pAd;
+			*Idx = i;
+			break;
+		}
+	}
+
+done:
+	NdisReleaseSpinLock(&pAd->BATabLock);
+	return pBAEntry;
+}
+
+
+VOID BATableFreeOriEntry(
+						IN  PRTMP_ADAPTER   pAd,
+						IN  ULONG           Idx)
+{
+	BA_ORI_ENTRY    *pBAEntry = NULL;
+	MAC_TABLE_ENTRY *pEntry;
+
+
+	if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE))
+		return;
+
+	pBAEntry =&pAd->BATable.BAOriEntry[Idx];
+
+	if (pBAEntry->ORI_BA_Status != Originator_NONE)
+	{
+		pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
+		pEntry->BAOriWcidArray[pBAEntry->TID] = 0;
+
+
+		NdisAcquireSpinLock(&pAd->BATabLock);
+		if (pBAEntry->ORI_BA_Status == Originator_Done)
+		{
+		 	pEntry->TXBAbitmap &= (~(1<<(pBAEntry->TID) ));
+			DBGPRINT(RT_DEBUG_TRACE, ("BATableFreeOriEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient));
+			// Erase Bitmap flag.
+		}
+
+		ASSERT(pAd->BATable.numAsOriginator != 0);
+
+		pAd->BATable.numAsOriginator -= 1;
+
+		pBAEntry->ORI_BA_Status = Originator_NONE;
+		pBAEntry->Token = 0;
+		NdisReleaseSpinLock(&pAd->BATabLock);
+	}
+}
+
+
+VOID BATableFreeRecEntry(
+						IN  PRTMP_ADAPTER   pAd,
+						IN  ULONG           Idx)
+{
+	BA_REC_ENTRY    *pBAEntry = NULL;
+	MAC_TABLE_ENTRY *pEntry;
+
+
+	if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_REC_TABLE))
+		return;
+
+	pBAEntry =&pAd->BATable.BARecEntry[Idx];
+
+	if (pBAEntry->REC_BA_Status != Recipient_NONE)
+	{
+		pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
+		pEntry->BARecWcidArray[pBAEntry->TID] = 0;
+
+		NdisAcquireSpinLock(&pAd->BATabLock);
+
+		ASSERT(pAd->BATable.numAsRecipient != 0);
+
+		pAd->BATable.numAsRecipient -= 1;
+
+		pBAEntry->REC_BA_Status = Recipient_NONE;
+		NdisReleaseSpinLock(&pAd->BATabLock);
+	}
+}
+
+
+VOID BAOriSessionTearDown(
+						 IN OUT  PRTMP_ADAPTER   pAd,
+						 IN      UCHAR           Wcid,
+						 IN      UCHAR           TID,
+						 IN      BOOLEAN         bPassive,
+						 IN      BOOLEAN         bForceSend)
+{
+	ULONG           Idx = 0;
+	BA_ORI_ENTRY    *pBAEntry;
+	BOOLEAN         Cancelled;
+
+	if (Wcid >= MAX_LEN_OF_MAC_TABLE)
+	{
+		return;
+	}
+
+	//
+	// Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID).
+	//
+	Idx = pAd->MacTab.Content[Wcid].BAOriWcidArray[TID];
+	if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE))
+	{
+		if (bForceSend == TRUE)
+		{
+			// force send specified TID DelBA
+			MLME_DELBA_REQ_STRUCT   DelbaReq;
+			MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
+
+			NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
+			NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
+
+			COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
+			DelbaReq.Wcid = Wcid;
+			DelbaReq.TID = TID;
+			DelbaReq.Initiator = ORIGINATOR;
+#if 1
+			Elem->MsgLen  = sizeof(DelbaReq);
+			NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
+			MlmeDELBAAction(pAd, Elem);
+			kfree(Elem);
+#else
+			MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
+			RT28XX_MLME_HANDLER(pAd);
+#endif
+		}
+
+		return;
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID));
+
+	pBAEntry = &pAd->BATable.BAOriEntry[Idx];
+	DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, ORI_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->ORI_BA_Status));
+	//
+	// Prepare DelBA action frame and send to the peer.
+	//
+	if ((bPassive == FALSE) && (TID == pBAEntry->TID) && (pBAEntry->ORI_BA_Status == Originator_Done))
+	{
+		MLME_DELBA_REQ_STRUCT   DelbaReq;
+		MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
+
+		NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
+		NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
+
+		COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
+		DelbaReq.Wcid = Wcid;
+		DelbaReq.TID = pBAEntry->TID;
+		DelbaReq.Initiator = ORIGINATOR;
+#if 1
+		Elem->MsgLen  = sizeof(DelbaReq);
+		NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
+		MlmeDELBAAction(pAd, Elem);
+		kfree(Elem);
+#else
+		MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
+		RT28XX_MLME_HANDLER(pAd);
+#endif
+	}
+	RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
+	BATableFreeOriEntry(pAd, Idx);
+
+	if (bPassive)
+	{
+		//BAOriSessionSetUp(pAd, &pAd->MacTab.Content[Wcid], TID, 0, 10000, TRUE);
+	}
+}
+
+VOID BARecSessionTearDown(
+						 IN OUT  PRTMP_ADAPTER   pAd,
+						 IN      UCHAR           Wcid,
+						 IN      UCHAR           TID,
+						 IN      BOOLEAN         bPassive)
+{
+	ULONG           Idx = 0;
+	BA_REC_ENTRY    *pBAEntry;
+
+	if (Wcid >= MAX_LEN_OF_MAC_TABLE)
+	{
+		return;
+	}
+
+	//
+	//  Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID).
+	//
+	Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
+	if (Idx == 0)
+		return;
+
+	DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID));
+
+
+	pBAEntry = &pAd->BATable.BARecEntry[Idx];
+	DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, REC_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->REC_BA_Status));
+	//
+	// Prepare DelBA action frame and send to the peer.
+	//
+	if ((TID == pBAEntry->TID) && (pBAEntry->REC_BA_Status == Recipient_Accept))
+	{
+		MLME_DELBA_REQ_STRUCT   DelbaReq;
+		BOOLEAN 				Cancelled;
+		MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
+		//ULONG   offset;
+		//UINT32  VALUE;
+
+		RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
+
+		//
+		// 1. Send DELBA Action Frame
+		//
+		if (bPassive == FALSE)
+		{
+			NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
+			NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
+
+			COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
+			DelbaReq.Wcid = Wcid;
+			DelbaReq.TID = TID;
+			DelbaReq.Initiator = RECIPIENT;
+#if 1
+			Elem->MsgLen  = sizeof(DelbaReq);
+			NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
+			MlmeDELBAAction(pAd, Elem);
+			kfree(Elem);
+#else
+			MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
+			RT28XX_MLME_HANDLER(pAd);
+#endif
+		}
+
+
+		//
+		// 2. Free resource of BA session
+		//
+		// flush all pending reordering mpdus
+		ba_refresh_reordering_mpdus(pAd, pBAEntry);
+
+		NdisAcquireSpinLock(&pAd->BATabLock);
+
+		// Erase Bitmap flag.
+		pBAEntry->LastIndSeq = RESET_RCV_SEQ;
+		pBAEntry->BAWinSize = 0;
+		// Erase Bitmap flag at software mactable
+		pAd->MacTab.Content[Wcid].RXBAbitmap &= (~(1<<(pBAEntry->TID)));
+		pAd->MacTab.Content[Wcid].BARecWcidArray[TID] = 0;
+
+		RT28XX_DEL_BA_SESSION_FROM_ASIC(pAd, Wcid, TID);
+
+		NdisReleaseSpinLock(&pAd->BATabLock);
+
+	}
+
+	BATableFreeRecEntry(pAd, Idx);
+}
+
+VOID BASessionTearDownALL(
+						 IN OUT  PRTMP_ADAPTER pAd,
+						 IN      UCHAR Wcid)
+{
+	int i;
+
+	for (i=0; i<NUM_OF_TID; i++)
+	{
+		BAOriSessionTearDown(pAd, Wcid, i, FALSE, FALSE);
+		BARecSessionTearDown(pAd, Wcid, i, FALSE);
+	}
+}
+
+
+/*
+	==========================================================================
+	Description:
+		Retry sending ADDBA Reqest.
+
+	IRQL = DISPATCH_LEVEL
+
+	Parametrs:
+	p8023Header: if this is already 802.3 format, p8023Header is NULL
+
+	Return	: TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
+				FALSE , then continue indicaterx at this moment.
+	==========================================================================
+ */
+VOID BAOriSessionSetupTimeout(
+    IN PVOID SystemSpecific1,
+    IN PVOID FunctionContext,
+    IN PVOID SystemSpecific2,
+    IN PVOID SystemSpecific3)
+{
+	BA_ORI_ENTRY    *pBAEntry = (BA_ORI_ENTRY *)FunctionContext;
+	MAC_TABLE_ENTRY *pEntry;
+	PRTMP_ADAPTER   pAd;
+
+	if (pBAEntry == NULL)
+		return;
+
+	pAd = pBAEntry->pAdapter;
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		// Do nothing if monitor mode is on
+		if (MONITOR_ON(pAd))
+			return;
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef RALINK_ATE
+	// Nothing to do in ATE mode.
+	if (ATE_ON(pAd))
+		return;
+#endif // RALINK_ATE //
+
+	pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
+
+	if ((pBAEntry->ORI_BA_Status == Originator_WaitRes) && (pBAEntry->Token < ORI_SESSION_MAX_RETRY))
+	{
+		MLME_ADDBA_REQ_STRUCT    AddbaReq;
+
+		NdisZeroMemory(&AddbaReq, sizeof(AddbaReq));
+		COPY_MAC_ADDR(AddbaReq.pAddr, pEntry->Addr);
+		AddbaReq.Wcid = (UCHAR)(pEntry->Aid);
+		AddbaReq.TID = pBAEntry->TID;
+		AddbaReq.BaBufSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit;
+		AddbaReq.TimeOutValue = 0;
+		AddbaReq.Token = pBAEntry->Token;
+		MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ADD_BA_CATE, sizeof(MLME_ADDBA_REQ_STRUCT), (PVOID)&AddbaReq);
+		RT28XX_MLME_HANDLER(pAd);
+		//DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) : Send ADD BA again\n", pBAEntry->Token));
+
+		DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) to %02x:%02x:%02x:%02x:%02x:%02x Tid:%d Wcid:%d\n"
+		,pBAEntry->Token
+		,pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2]
+		,pEntry->Addr[3],pEntry->Addr[4],pEntry->Addr[5]
+		,pBAEntry->TID,pEntry->Aid));
+
+		pBAEntry->Token++;
+		RTMPSetTimer(&pBAEntry->ORIBATimer, ORI_BA_SESSION_TIMEOUT);
+	}
+	else
+	{
+		BATableFreeOriEntry(pAd, pEntry->BAOriWcidArray[pBAEntry->TID]);
+	}
+}
+
+/*
+	==========================================================================
+	Description:
+		Retry sending ADDBA Reqest.
+
+	IRQL = DISPATCH_LEVEL
+
+	Parametrs:
+	p8023Header: if this is already 802.3 format, p8023Header is NULL
+
+	Return	: TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
+				FALSE , then continue indicaterx at this moment.
+	==========================================================================
+ */
+VOID BARecSessionIdleTimeout(
+    IN PVOID SystemSpecific1,
+    IN PVOID FunctionContext,
+    IN PVOID SystemSpecific2,
+    IN PVOID SystemSpecific3)
+{
+
+	BA_REC_ENTRY    *pBAEntry = (BA_REC_ENTRY *)FunctionContext;
+	PRTMP_ADAPTER   pAd;
+	ULONG           Now32;
+
+	if (pBAEntry == NULL)
+		return;
+
+	if ((pBAEntry->REC_BA_Status == Recipient_Accept))
+	{
+		NdisGetSystemUpTime(&Now32);
+
+		if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer + REC_BA_SESSION_IDLE_TIMEOUT)))
+		{
+			pAd = pBAEntry->pAdapter;
+			// flush all pending reordering mpdus
+			ba_refresh_reordering_mpdus(pAd, pBAEntry);
+			printk("%ld: REC BA session Timeout\n", Now32);
+		}
+	}
+}
+
+
+VOID PeerAddBAReqAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+
+{
+	//	7.4.4.1
+	//ULONG	Idx;
+	UCHAR   Status = 1;
+	UCHAR   pAddr[6];
+	FRAME_ADDBA_RSP ADDframe;
+	PUCHAR         pOutBuffer = NULL;
+	NDIS_STATUS     NStatus;
+	PFRAME_ADDBA_REQ  pAddreqFrame = NULL;
+	//UCHAR		BufSize;
+	ULONG       FrameLen;
+	PULONG      ptemp;
+	PMAC_TABLE_ENTRY	pMacEntry;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("%s ==> (Wcid = %d)\n", __FUNCTION__, Elem->Wcid));
+
+	//hex_dump("AddBAReq", Elem->Msg, Elem->MsgLen);
+
+	//ADDBA Request from unknown peer, ignore this.
+	if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
+		return;
+
+	pMacEntry = &pAd->MacTab.Content[Elem->Wcid];
+	DBGPRINT(RT_DEBUG_TRACE,("BA - PeerAddBAReqAction----> \n"));
+	ptemp = (PULONG)Elem->Msg;
+	//DBGPRINT_RAW(RT_DEBUG_EMU, ("%08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x\n", *(ptemp), *(ptemp+1), *(ptemp+2), *(ptemp+3), *(ptemp+4), *(ptemp+5), *(ptemp+6), *(ptemp+7), *(ptemp+8)));
+
+	if (PeerAddBAReqActionSanity(pAd, Elem->Msg, Elem->MsgLen, pAddr))
+	{
+
+		if ((pAd->CommonCfg.bBADecline == FALSE) && IS_HT_STA(pMacEntry))
+		{
+			pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]);
+			printk("Rcv Wcid(%d) AddBAReq\n", Elem->Wcid);
+			if (BARecSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pAddreqFrame))
+				Status = 0;
+			else
+				Status = 38; // more parameters have invalid values
+		}
+		else
+		{
+			Status = 37; // the request has been declined.
+		}
+	}
+
+	if (pAd->MacTab.Content[Elem->Wcid].ValidAsCLI)
+		ASSERT(pAd->MacTab.Content[Elem->Wcid].Sst == SST_ASSOC);
+
+	pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]);
+	// 2. Always send back ADDBA Response
+	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	 //Get an unused nonpaged memory
+	if (NStatus != NDIS_STATUS_SUCCESS)
+	{
+		DBGPRINT(RT_DEBUG_TRACE,("ACTION - PeerBAAction() allocate memory failed \n"));
+		return;
+	}
+
+	NdisZeroMemory(&ADDframe, sizeof(FRAME_ADDBA_RSP));
+	// 2-1. Prepare ADDBA Response frame.
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		if (ADHOC_ON(pAd))
+			ActHeaderInit(pAd, &ADDframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+		else
+			ActHeaderInit(pAd, &ADDframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr);
+	}
+#endif // CONFIG_STA_SUPPORT //
+	ADDframe.Category = CATEGORY_BA;
+	ADDframe.Action = ADDBA_RESP;
+	ADDframe.Token = pAddreqFrame->Token;
+	// What is the Status code??  need to check.
+	ADDframe.StatusCode = Status;
+	ADDframe.BaParm.BAPolicy = IMMED_BA;
+	ADDframe.BaParm.AMSDUSupported = 0;
+	ADDframe.BaParm.TID = pAddreqFrame->BaParm.TID;
+	ADDframe.BaParm.BufSize = min(((UCHAR)pAddreqFrame->BaParm.BufSize), (UCHAR)pAd->CommonCfg.BACapability.field.RxBAWinLimit);
+	if (ADDframe.BaParm.BufSize == 0)
+	{
+		ADDframe.BaParm.BufSize = 64;
+	}
+	ADDframe.TimeOutValue = 0; //pAddreqFrame->TimeOutValue;
+
+	*(USHORT *)(&ADDframe.BaParm) = cpu2le16(*(USHORT *)(&ADDframe.BaParm));
+	ADDframe.StatusCode = cpu2le16(ADDframe.StatusCode);
+	ADDframe.TimeOutValue = cpu2le16(ADDframe.TimeOutValue);
+
+	MakeOutgoingFrame(pOutBuffer,               &FrameLen,
+					  sizeof(FRAME_ADDBA_RSP),  &ADDframe,
+			  END_OF_ARGS);
+	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+	MlmeFreeMemory(pAd, pOutBuffer);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("%s(%d): TID(%d), BufSize(%d) <== \n", __FUNCTION__, Elem->Wcid, ADDframe.BaParm.TID,
+							  ADDframe.BaParm.BufSize));
+}
+
+
+VOID PeerAddBARspAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+
+{
+	//UCHAR		Idx, i;
+	//PUCHAR		   pOutBuffer = NULL;
+	PFRAME_ADDBA_RSP    pFrame = NULL;
+	//PBA_ORI_ENTRY		pBAEntry;
+
+	//ADDBA Response from unknown peer, ignore this.
+	if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
+		return;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("%s ==> Wcid(%d)\n", __FUNCTION__, Elem->Wcid));
+
+	//hex_dump("PeerAddBARspAction()", Elem->Msg, Elem->MsgLen);
+
+	if (PeerAddBARspActionSanity(pAd, Elem->Msg, Elem->MsgLen))
+	{
+		pFrame = (PFRAME_ADDBA_RSP)(&Elem->Msg[0]);
+
+		DBGPRINT(RT_DEBUG_TRACE, ("\t\t StatusCode = %d\n", pFrame->StatusCode));
+		switch (pFrame->StatusCode)
+		{
+			case 0:
+				// I want a BAsession with this peer as an originator.
+				BAOriSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pFrame);
+				break;
+			default:
+				// check status == USED ???
+				BAOriSessionTearDown(pAd, Elem->Wcid, pFrame->BaParm.TID, TRUE, FALSE);
+				break;
+		}
+		// Rcv Decline StatusCode
+		if ((pFrame->StatusCode == 37)
+#ifdef CONFIG_STA_SUPPORT
+            || ((pAd->OpMode == OPMODE_STA) && STA_TGN_WIFI_ON(pAd) && (pFrame->StatusCode != 0))
+#endif // CONFIG_STA_SUPPORT //
+            )
+		{
+			pAd->MacTab.Content[Elem->Wcid].BADeclineBitmap |= 1<<pFrame->BaParm.TID;
+		}
+	}
+}
+
+VOID PeerDelBAAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+
+{
+	//UCHAR				Idx;
+	//PUCHAR				pOutBuffer = NULL;
+	PFRAME_DELBA_REQ    pDelFrame = NULL;
+
+	DBGPRINT(RT_DEBUG_TRACE,("%s ==>\n", __FUNCTION__));
+	//DELBA Request from unknown peer, ignore this.
+	if (PeerDelBAActionSanity(pAd, Elem->Wcid, Elem->Msg, Elem->MsgLen))
+	{
+		pDelFrame = (PFRAME_DELBA_REQ)(&Elem->Msg[0]);
+		if (pDelFrame->DelbaParm.Initiator == ORIGINATOR)
+		{
+			DBGPRINT(RT_DEBUG_TRACE,("BA - PeerDelBAAction----> ORIGINATOR\n"));
+			BARecSessionTearDown(pAd, Elem->Wcid, pDelFrame->DelbaParm.TID, TRUE);
+		}
+		else
+		{
+			DBGPRINT(RT_DEBUG_TRACE,("BA - PeerDelBAAction----> RECIPIENT, Reason = %d\n",  pDelFrame->ReasonCode));
+			//hex_dump("DelBA Frame", pDelFrame, Elem->MsgLen);
+			BAOriSessionTearDown(pAd, Elem->Wcid, pDelFrame->DelbaParm.TID, TRUE, FALSE);
+		}
+	}
+}
+
+
+BOOLEAN CntlEnqueueForRecv(
+						  IN PRTMP_ADAPTER		pAd,
+						  IN ULONG				Wcid,
+						  IN ULONG				MsgLen,
+						  IN PFRAME_BA_REQ		pMsg)
+{
+	PFRAME_BA_REQ   pFrame = pMsg;
+	//PRTMP_REORDERBUF	pBuffer;
+	//PRTMP_REORDERBUF	pDmaBuf;
+	PBA_REC_ENTRY pBAEntry;
+	//BOOLEAN 	Result;
+	ULONG   Idx;
+	//UCHAR	NumRxPkt;
+	UCHAR	TID;//, i;
+
+	TID = (UCHAR)pFrame->BARControl.TID;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("%s(): BAR-Wcid(%ld), Tid (%d)\n", __FUNCTION__, Wcid, TID));
+	//hex_dump("BAR", (PCHAR) pFrame, MsgLen);
+	// Do nothing if the driver is starting halt state.
+	// This might happen when timer already been fired before cancel timer with mlmehalt
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+		return FALSE;
+
+	// First check the size, it MUST not exceed the mlme queue size
+	if (MsgLen > MGMT_DMA_BUFFER_SIZE)
+	{
+		DBGPRINT_ERR(("CntlEnqueueForRecv: frame too large, size = %ld \n", MsgLen));
+		return FALSE;
+	}
+	else if (MsgLen != sizeof(FRAME_BA_REQ))
+	{
+		DBGPRINT_ERR(("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen));
+		return FALSE;
+	}
+	else if (MsgLen != sizeof(FRAME_BA_REQ))
+	{
+		DBGPRINT_ERR(("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen));
+		return FALSE;
+	}
+
+	if ((Wcid < MAX_LEN_OF_MAC_TABLE) && (TID < 8))
+		{
+		// if this receiving packet is from SA that is in our OriEntry. Since WCID <9 has direct mapping. no need search.
+		Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
+		pBAEntry = &pAd->BATable.BARecEntry[Idx];
+		}
+		else
+		{
+		return FALSE;
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("BAR(%ld) : Tid (%d) - %04x:%04x\n", Wcid, TID, pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq ));
+
+	if (SEQ_SMALLER(pBAEntry->LastIndSeq, pFrame->BAStartingSeq.field.StartSeq, MAXSEQ))
+	{
+		//printk("BAR Seq = %x, LastIndSeq = %x\n", pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq);
+		ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, pFrame->BAStartingSeq.field.StartSeq);
+		pBAEntry->LastIndSeq = (pFrame->BAStartingSeq.field.StartSeq == 0) ? MAXSEQ :(pFrame->BAStartingSeq.field.StartSeq -1);
+	}
+	//ba_refresh_reordering_mpdus(pAd, pBAEntry);
+	return TRUE;
+}
+
+/*
+Description : Send PSMP Action frame If PSMP mode switches.
+*/
+VOID SendPSMPAction(
+				   IN PRTMP_ADAPTER		pAd,
+				   IN UCHAR				Wcid,
+				   IN UCHAR				Psmp)
+{
+	PUCHAR          pOutBuffer = NULL;
+	NDIS_STATUS     NStatus;
+	//ULONG           Idx;
+	FRAME_PSMP_ACTION   Frame;
+	ULONG           FrameLen;
+#ifdef RT30xx
+	UCHAR			bbpdata=0;
+	UINT32			macdata;
+#endif // RT30xx //
+
+	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	 //Get an unused nonpaged memory
+	if (NStatus != NDIS_STATUS_SUCCESS)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n"));
+		return;
+	}
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[Wcid].Addr);
+#endif // CONFIG_STA_SUPPORT //
+
+	Frame.Category = CATEGORY_HT;
+	Frame.Action = SMPS_ACTION;
+	switch (Psmp)
+	{
+		case MMPS_ENABLE:
+#ifdef RT30xx
+			if (IS_RT3090(pAd))
+			{
+				// disable MMPS BBP control register
+				RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
+				bbpdata &= ~(0x04);	//bit 2
+				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
+
+				// disable MMPS MAC control register
+				RTMP_IO_READ32(pAd, 0x1210, &macdata);
+				macdata &= ~(0x09);	//bit 0, 3
+				RTMP_IO_WRITE32(pAd, 0x1210, macdata);
+			}
+#endif // RT30xx //
+			Frame.Psmp = 0;
+			break;
+		case MMPS_DYNAMIC:
+#ifdef RT30xx
+			if (IS_RT3090(pAd))
+			{
+				// enable MMPS BBP control register
+				RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
+				bbpdata |= 0x04;	//bit 2
+				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
+
+				// enable MMPS MAC control register
+				RTMP_IO_READ32(pAd, 0x1210, &macdata);
+				macdata |= 0x09;	//bit 0, 3
+				RTMP_IO_WRITE32(pAd, 0x1210, macdata);
+			}
+#endif // RT30xx //
+			Frame.Psmp = 3;
+			break;
+		case MMPS_STATIC:
+#ifdef RT30xx
+			if (IS_RT3090(pAd))
+			{
+				// enable MMPS BBP control register
+				RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
+				bbpdata |= 0x04;	//bit 2
+				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
+
+				// enable MMPS MAC control register
+				RTMP_IO_READ32(pAd, 0x1210, &macdata);
+				macdata |= 0x09;	//bit 0, 3
+				RTMP_IO_WRITE32(pAd, 0x1210, macdata);
+			}
+#endif // RT30xx //
+			Frame.Psmp = 1;
+			break;
+	}
+	MakeOutgoingFrame(pOutBuffer,               &FrameLen,
+					  sizeof(FRAME_PSMP_ACTION),      &Frame,
+					  END_OF_ARGS);
+	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+	MlmeFreeMemory(pAd, pOutBuffer);
+	DBGPRINT(RT_DEBUG_ERROR,("HT - SendPSMPAction( %d )  \n", Frame.Psmp));
+}
+
+
+#define RADIO_MEASUREMENT_REQUEST_ACTION	0
+
+typedef struct PACKED
+{
+	UCHAR	RegulatoryClass;
+	UCHAR	ChannelNumber;
+	USHORT	RandomInterval;
+	USHORT	MeasurementDuration;
+	UCHAR	MeasurementMode;
+	UCHAR   BSSID[MAC_ADDR_LEN];
+	UCHAR	ReportingCondition;
+	UCHAR	Threshold;
+	UCHAR   SSIDIE[2];			// 2 byte
+} BEACON_REQUEST;
+
+typedef struct PACKED
+{
+	UCHAR	ID;
+	UCHAR	Length;
+	UCHAR	Token;
+	UCHAR	RequestMode;
+	UCHAR	Type;
+} MEASUREMENT_REQ;
+
+
+
+
+void convert_reordering_packet_to_preAMSDU_or_802_3_packet(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	RX_BLK			*pRxBlk,
+	IN  UCHAR			FromWhichBSSID)
+{
+	PNDIS_PACKET	pRxPkt;
+	UCHAR			Header802_3[LENGTH_802_3];
+
+	// 1. get 802.3 Header
+	// 2. remove LLC
+	// 		a. pointer pRxBlk->pData to payload
+	//      b. modify pRxBlk->DataSize
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
+#endif // CONFIG_STA_SUPPORT //
+
+	ASSERT(pRxBlk->pRxPacket);
+	pRxPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
+
+	RTPKT_TO_OSPKT(pRxPkt)->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
+	RTPKT_TO_OSPKT(pRxPkt)->data = pRxBlk->pData;
+	RTPKT_TO_OSPKT(pRxPkt)->len = pRxBlk->DataSize;
+	RTPKT_TO_OSPKT(pRxPkt)->tail = RTPKT_TO_OSPKT(pRxPkt)->data + RTPKT_TO_OSPKT(pRxPkt)->len;
+
+	//
+	// copy 802.3 header, if necessary
+	//
+	if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
+	{
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+#ifdef LINUX
+			NdisMoveMemory(skb_push(pRxPkt, LENGTH_802_3), Header802_3, LENGTH_802_3);
+#endif
+#ifdef UCOS
+			NdisMoveMemory(net_pkt_push(pRxPkt, LENGTH_802_3), Header802_3, LENGTH_802_3);
+#endif
+		}
+#endif // CONFIG_STA_SUPPORT //
+	}
+}
+
+
+#define INDICATE_LEGACY_OR_AMSDU(_pAd, _pRxBlk, _fromWhichBSSID)		\
+	do																	\
+	{																	\
+    	if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_AMSDU))						\
+    	{																\
+    		Indicate_AMSDU_Packet(_pAd, _pRxBlk, _fromWhichBSSID);		\
+    	}																\
+		else if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_EAP))					\
+		{																\
+			Indicate_EAPOL_Packet(_pAd, _pRxBlk, _fromWhichBSSID);		\
+		}																\
+    	else															\
+    	{																\
+    		Indicate_Legacy_Packet(_pAd, _pRxBlk, _fromWhichBSSID);		\
+    	}																\
+	} while (0);
+
+
+
+static VOID ba_enqueue_reordering_packet(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PBA_REC_ENTRY	pBAEntry,
+	IN	RX_BLK			*pRxBlk,
+	IN	UCHAR			FromWhichBSSID)
+{
+	struct reordering_mpdu *mpdu_blk;
+	UINT16	Sequence = (UINT16) pRxBlk->pHeader->Sequence;
+
+	mpdu_blk = ba_mpdu_blk_alloc(pAd);
+	if (mpdu_blk != NULL)
+	{
+		// Write RxD buffer address & allocated buffer length
+		NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
+
+		mpdu_blk->Sequence = Sequence;
+
+		mpdu_blk->bAMSDU = RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU);
+
+		convert_reordering_packet_to_preAMSDU_or_802_3_packet(pAd, pRxBlk, FromWhichBSSID);
+
+		STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
+
+        //
+		// it is necessary for reordering packet to record
+		// which BSS it come from
+		//
+		RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
+
+		mpdu_blk->pPacket = pRxBlk->pRxPacket;
+
+		if (ba_reordering_mpdu_insertsorted(&pBAEntry->list, mpdu_blk) == FALSE)
+		{
+			// had been already within reordering list
+			// don't indicate
+			RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_SUCCESS);
+			ba_mpdu_blk_free(pAd, mpdu_blk);
+		}
+
+		ASSERT((0<= pBAEntry->list.qlen)  && (pBAEntry->list.qlen <= pBAEntry->BAWinSize));
+		NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_ERROR,  ("!!! (%d) Can't allocate reordering mpdu blk\n",
+								   pBAEntry->list.qlen));
+		/*
+		 * flush all pending reordering mpdus
+		 * and receving mpdu to upper layer
+		 * make tcp/ip to take care reordering mechanism
+		 */
+		//ba_refresh_reordering_mpdus(pAd, pBAEntry);
+		ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
+
+		pBAEntry->LastIndSeq = Sequence;
+		INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
+	}
+}
+
+
+/*
+	==========================================================================
+	Description:
+		Indicate this packet to upper layer or put it into reordering buffer
+
+	Parametrs:
+		pRxBlk         : carry necessary packet info 802.11 format
+		FromWhichBSSID : the packet received from which BSS
+
+	Return	:
+			  none
+
+	Note    :
+	          the packet queued into reordering buffer need to cover to 802.3 format
+			  or pre_AMSDU format
+	==========================================================================
+ */
+
+VOID Indicate_AMPDU_Packet(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	RX_BLK			*pRxBlk,
+	IN	UCHAR			FromWhichBSSID)
+{
+	USHORT				Idx;
+	PBA_REC_ENTRY		pBAEntry = NULL;
+	UINT16				Sequence = pRxBlk->pHeader->Sequence;
+	ULONG				Now32;
+	UCHAR				Wcid = pRxBlk->pRxWI->WirelessCliID;
+	UCHAR				TID = pRxBlk->pRxWI->TID;
+
+
+	if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU) &&  (pRxBlk->DataSize > MAX_RX_PKT_LEN))
+	{
+		// release packet
+		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+		return;
+	}
+
+	if (Wcid < MAX_LEN_OF_MAC_TABLE)
+	{
+		Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
+		if (Idx == 0)
+		{
+			/* Rec BA Session had been torn down */
+			INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
+			return;
+		}
+		pBAEntry = &pAd->BATable.BARecEntry[Idx];
+	}
+	else
+	{
+		// impossible !!!
+		ASSERT(0);
+		// release packet
+		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+		return;
+	}
+
+	ASSERT(pBAEntry);
+
+	// update last rx time
+	NdisGetSystemUpTime(&Now32);
+
+	pBAEntry->rcvSeq = Sequence;
+
+
+	ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
+	pBAEntry->LastIndSeqAtTimer = Now32;
+
+	//
+	// Reset Last Indicate Sequence
+	//
+	if (pBAEntry->LastIndSeq == RESET_RCV_SEQ)
+	{
+		ASSERT((pBAEntry->list.qlen == 0) && (pBAEntry->list.next == NULL));
+
+		// reset rcv sequence of BA session
+		pBAEntry->LastIndSeq = Sequence;
+		pBAEntry->LastIndSeqAtTimer = Now32;
+		INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
+		return;
+	}
+
+
+	//
+	// I. Check if in order.
+	//
+	if (SEQ_STEPONE(Sequence, pBAEntry->LastIndSeq, MAXSEQ))
+	{
+		USHORT  LastIndSeq;
+
+		pBAEntry->LastIndSeq = Sequence;
+		INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
+ 		LastIndSeq = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, pBAEntry->LastIndSeq);
+		if (LastIndSeq != RESET_RCV_SEQ)
+		{
+			pBAEntry->LastIndSeq = LastIndSeq;
+		}
+		pBAEntry->LastIndSeqAtTimer = Now32;
+	}
+	//
+	// II. Drop Duplicated Packet
+	//
+	else if (Sequence == pBAEntry->LastIndSeq)
+	{
+
+		// drop and release packet
+		pBAEntry->nDropPacket++;
+		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+	}
+	//
+	// III. Drop Old Received Packet
+	//
+	else if (SEQ_SMALLER(Sequence, pBAEntry->LastIndSeq, MAXSEQ))
+	{
+
+		// drop and release packet
+		pBAEntry->nDropPacket++;
+		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+	}
+	//
+	// IV. Receive Sequence within Window Size
+	//
+	else if (SEQ_SMALLER(Sequence, (((pBAEntry->LastIndSeq+pBAEntry->BAWinSize+1)) & MAXSEQ), MAXSEQ))
+	{
+		ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk, FromWhichBSSID);
+	}
+	//
+	// V. Receive seq surpasses Win(lastseq + nMSDU). So refresh all reorder buffer
+	//
+	else
+	{
+		LONG WinStartSeq, TmpSeq;
+
+
+		TmpSeq = Sequence - (pBAEntry->BAWinSize) -1;
+		if (TmpSeq < 0)
+		{
+			TmpSeq = (MAXSEQ+1) + TmpSeq;
+		}
+		WinStartSeq = (TmpSeq+1) & MAXSEQ;
+		ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, WinStartSeq);
+		pBAEntry->LastIndSeq = WinStartSeq; //TmpSeq;
+
+		pBAEntry->LastIndSeqAtTimer = Now32;
+
+		ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk, FromWhichBSSID);
+
+		TmpSeq = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, pBAEntry->LastIndSeq);
+		if (TmpSeq != RESET_RCV_SEQ)
+		{
+			pBAEntry->LastIndSeq = TmpSeq;
+		}
+	}
+}
+
+#endif // DOT11_N_SUPPORT //
+
diff --git a/drivers/staging/rt3070/common/cmm_data.c b/drivers/staging/rt3070/common/cmm_data.c
new file mode 100644
index 0000000..85f92b9
--- /dev/null
+++ b/drivers/staging/rt3070/common/cmm_data.c
@@ -0,0 +1,2827 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+*/
+
+#include "../rt_config.h"
+
+#define MAX_TX_IN_TBTT		(16)
+
+
+UCHAR	SNAP_802_1H[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
+UCHAR	SNAP_BRIDGE_TUNNEL[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8};
+// Add Cisco Aironet SNAP heade for CCX2 support
+UCHAR	SNAP_AIRONET[] = {0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x00};
+UCHAR	CKIP_LLC_SNAP[] = {0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02};
+UCHAR	EAPOL_LLC_SNAP[]= {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e};
+UCHAR	EAPOL[] = {0x88, 0x8e};
+UCHAR   TPID[] = {0x81, 0x00}; /* VLAN related */
+
+UCHAR	IPX[] = {0x81, 0x37};
+UCHAR	APPLE_TALK[] = {0x80, 0xf3};
+UCHAR	RateIdToPlcpSignal[12] = {
+	 0, /* RATE_1 */	1, /* RATE_2 */ 	2, /* RATE_5_5 */	3, /* RATE_11 */	// see BBP spec
+	11, /* RATE_6 */   15, /* RATE_9 */    10, /* RATE_12 */   14, /* RATE_18 */	// see IEEE802.11a-1999 p.14
+	 9, /* RATE_24 */  13, /* RATE_36 */	8, /* RATE_48 */   12  /* RATE_54 */ }; // see IEEE802.11a-1999 p.14
+
+UCHAR	 OfdmSignalToRateId[16] = {
+	RATE_54,  RATE_54,	RATE_54,  RATE_54,	// OFDM PLCP Signal = 0,  1,  2,  3 respectively
+	RATE_54,  RATE_54,	RATE_54,  RATE_54,	// OFDM PLCP Signal = 4,  5,  6,  7 respectively
+	RATE_48,  RATE_24,	RATE_12,  RATE_6,	// OFDM PLCP Signal = 8,  9,  10, 11 respectively
+	RATE_54,  RATE_36,	RATE_18,  RATE_9,	// OFDM PLCP Signal = 12, 13, 14, 15 respectively
+};
+
+UCHAR	 OfdmRateToRxwiMCS[12] = {
+	0,  0,	0,  0,
+	0,  1,	2,  3,	// OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3
+	4,  5,	6,  7,	// OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7
+};
+UCHAR	 RxwiMCSToOfdmRate[12] = {
+	RATE_6,  RATE_9,	RATE_12,  RATE_18,
+	RATE_24,  RATE_36,	RATE_48,  RATE_54,	// OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3
+	4,  5,	6,  7,	// OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7
+};
+
+char*   MCSToMbps[] = {"1Mbps","2Mbps","5.5Mbps","11Mbps","06Mbps","09Mbps","12Mbps","18Mbps","24Mbps","36Mbps","48Mbps","54Mbps","MM-0","MM-1","MM-2","MM-3","MM-4","MM-5","MM-6","MM-7","MM-8","MM-9","MM-10","MM-11","MM-12","MM-13","MM-14","MM-15","MM-32","ee1","ee2","ee3"};
+
+UCHAR default_cwmin[]={CW_MIN_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1, CW_MIN_IN_BITS-2};
+//UCHAR default_cwmax[]={CW_MAX_IN_BITS, CW_MAX_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1};
+UCHAR default_sta_aifsn[]={3,7,2,2};
+
+UCHAR MapUserPriorityToAccessCategory[8] = {QID_AC_BE, QID_AC_BK, QID_AC_BK, QID_AC_BE, QID_AC_VI, QID_AC_VI, QID_AC_VO, QID_AC_VO};
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		API for MLME to transmit management frame to AP (BSS Mode)
+	or station (IBSS Mode)
+
+	Arguments:
+		pAd Pointer to our adapter
+		pData		Pointer to the outgoing 802.11 frame
+		Length		Size of outgoing management frame
+
+	Return Value:
+		NDIS_STATUS_FAILURE
+		NDIS_STATUS_PENDING
+		NDIS_STATUS_SUCCESS
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+NDIS_STATUS MiniportMMRequest(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			QueIdx,
+	IN	PUCHAR			pData,
+	IN	UINT			Length)
+{
+	PNDIS_PACKET	pPacket;
+	NDIS_STATUS  	Status = NDIS_STATUS_SUCCESS;
+	ULONG	 		FreeNum;
+	UCHAR			IrqState;
+	UCHAR			rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
+
+	ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
+
+	QueIdx=3;
+
+	// 2860C use Tx Ring
+
+	IrqState = pAd->irq_disabled;
+
+	do
+	{
+		// Reset is in progress, stop immediately
+		if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
+			 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
+			 !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
+		{
+			Status = NDIS_STATUS_FAILURE;
+			break;
+		}
+
+		// Check Free priority queue
+		// Since we use PBF Queue2 for management frame.  Its corresponding DMA ring should be using TxRing.
+
+		// 2860C use Tx Ring
+		if (pAd->MACVersion == 0x28600100)
+		{
+			FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
+		}
+		else
+		{
+			FreeNum = GET_MGMTRING_FREENO(pAd);
+		}
+
+		if ((FreeNum > 0))
+		{
+			// We need to reserve space for rtmp hardware header. i.e., TxWI for RT2860 and TxInfo+TxWI for RT2870
+			NdisZeroMemory(&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE));
+			Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE), pData, Length);
+			if (Status != NDIS_STATUS_SUCCESS)
+			{
+				DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
+				break;
+			}
+
+			//pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
+			//pAd->CommonCfg.MlmeRate = RATE_2;
+
+
+			Status = MlmeHardTransmit(pAd, QueIdx, pPacket);
+			if (Status != NDIS_STATUS_SUCCESS)
+				RTMPFreeNdisPacket(pAd, pPacket);
+		}
+		else
+		{
+			pAd->RalinkCounters.MgmtRingFullCount++;
+			DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing, MgmtRingFullCount=%ld!\n",
+										QueIdx, pAd->RalinkCounters.MgmtRingFullCount));
+		}
+
+	} while (FALSE);
+
+
+	return Status;
+}
+
+
+
+NDIS_STATUS MlmeDataHardTransmit(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR	QueIdx,
+	IN	PNDIS_PACKET	pPacket);
+
+#define MAX_DATAMM_RETRY	3
+/*
+	========================================================================
+
+	Routine Description:
+		API for MLME to transmit management frame to AP (BSS Mode)
+	or station (IBSS Mode)
+
+	Arguments:
+		pAd Pointer to our adapter
+		pData		Pointer to the outgoing 802.11 frame
+		Length		Size of outgoing management frame
+
+	Return Value:
+		NDIS_STATUS_FAILURE
+		NDIS_STATUS_PENDING
+		NDIS_STATUS_SUCCESS
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+NDIS_STATUS MiniportDataMMRequest(
+							 IN  PRTMP_ADAPTER   pAd,
+							 IN  UCHAR           QueIdx,
+							 IN  PUCHAR          pData,
+							 IN  UINT            Length)
+{
+	PNDIS_PACKET    pPacket;
+	NDIS_STATUS  Status = NDIS_STATUS_SUCCESS;
+	ULONG    FreeNum;
+	int 	retry = 0;
+	UCHAR           IrqState;
+	UCHAR			rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
+
+	ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
+
+	// 2860C use Tx Ring
+	IrqState = pAd->irq_disabled;
+
+	do
+	{
+		// Reset is in progress, stop immediately
+		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
+			 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
+			!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
+		{
+			Status = NDIS_STATUS_FAILURE;
+			break;
+		}
+
+		// Check Free priority queue
+		// Since we use PBF Queue2 for management frame.  Its corresponding DMA ring should be using TxRing.
+
+		// 2860C use Tx Ring
+
+		// free Tx(QueIdx) resources
+		FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
+
+		if ((FreeNum > 0))
+		{
+			// We need to reserve space for rtmp hardware header. i.e., TxWI for RT2860 and TxInfo+TxWI for RT2870
+			NdisZeroMemory(&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE));
+			Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE), pData, Length);
+			if (Status != NDIS_STATUS_SUCCESS)
+			{
+				DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
+				break;
+			}
+
+			//pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
+			//pAd->CommonCfg.MlmeRate = RATE_2;
+
+
+			Status = MlmeDataHardTransmit(pAd, QueIdx, pPacket);
+			if (Status != NDIS_STATUS_SUCCESS)
+				RTMPFreeNdisPacket(pAd, pPacket);
+			retry = MAX_DATAMM_RETRY;
+		}
+		else
+		{
+			retry ++;
+
+			printk("retry %d\n", retry);
+			pAd->RalinkCounters.MgmtRingFullCount++;
+
+			if (retry >= MAX_DATAMM_RETRY)
+			{
+				DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in DataRing, MgmtRingFullCount=%ld!\n",
+											QueIdx, pAd->RalinkCounters.MgmtRingFullCount));
+			}
+		}
+
+	} while (retry < MAX_DATAMM_RETRY);
+
+
+	return Status;
+}
+
+
+
+
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Copy frame from waiting queue into relative ring buffer and set
+	appropriate ASIC register to kick hardware transmit function
+
+	Arguments:
+		pAd Pointer to our adapter
+		pBuffer 	Pointer to	memory of outgoing frame
+		Length		Size of outgoing management frame
+
+	Return Value:
+		NDIS_STATUS_FAILURE
+		NDIS_STATUS_PENDING
+		NDIS_STATUS_SUCCESS
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+NDIS_STATUS MlmeHardTransmit(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			QueIdx,
+	IN	PNDIS_PACKET	pPacket)
+{
+	if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
+#ifdef CARRIER_DETECTION_SUPPORT
+#endif // CARRIER_DETECTION_SUPPORT //
+		)
+	{
+		return NDIS_STATUS_FAILURE;
+	}
+
+		return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
+
+}
+
+NDIS_STATUS MlmeDataHardTransmit(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR	QueIdx,
+	IN	PNDIS_PACKET	pPacket)
+{
+	if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
+#ifdef CARRIER_DETECTION_SUPPORT
+#endif // CARRIER_DETECTION_SUPPORT //
+		)
+	{
+		return NDIS_STATUS_FAILURE;
+	}
+
+#ifdef RT2870
+	return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
+#endif // RT2870 //
+}
+
+
+
+
+
+NDIS_STATUS MlmeHardTransmitMgmtRing(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR	QueIdx,
+	IN	PNDIS_PACKET	pPacket)
+{
+	PACKET_INFO 	PacketInfo;
+	PUCHAR			pSrcBufVA;
+	UINT			SrcBufLen;
+	PHEADER_802_11	pHeader_802_11;
+	BOOLEAN 		bAckRequired, bInsertTimestamp;
+	UCHAR			MlmeRate;
+	PTXWI_STRUC 	pFirstTxWI;
+	MAC_TABLE_ENTRY	*pMacEntry = NULL;
+
+	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
+
+	// Make sure MGMT ring resource won't be used by other threads
+// sample, for IRQ LOCK -> SEM LOCK
+//	IrqState = pAd->irq_disabled;
+//	if (!IrqState)
+		RTMP_SEM_LOCK(&pAd->MgmtRingLock);
+
+
+	if (pSrcBufVA == NULL)
+	{
+		// The buffer shouldn't be NULL
+//		if (!IrqState)
+			RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
+		return NDIS_STATUS_FAILURE;
+	}
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		// outgoing frame always wakeup PHY to prevent frame lost
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+			AsicForceWakeup(pAd, TRUE);
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	pFirstTxWI = (PTXWI_STRUC)(pSrcBufVA +  TXINFO_SIZE);
+	pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); //TXWI_SIZE);
+
+	if (pHeader_802_11->Addr1[0] & 0x01)
+	{
+		MlmeRate = pAd->CommonCfg.BasicMlmeRate;
+	}
+	else
+	{
+		MlmeRate = pAd->CommonCfg.MlmeRate;
+	}
+
+	// Verify Mlme rate for a / g bands.
+	if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band
+		MlmeRate = RATE_6;
+
+	if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
+		(pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))
+	{
+		pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
+	}
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		// Fixed W52 with Activity scan issue in ABG_MIXED and ABGN_MIXED mode.
+		if (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED
+#ifdef DOT11_N_SUPPORT
+			|| pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED
+#endif // DOT11_N_SUPPORT //
+		)
+		{
+			if (pAd->LatchRfRegs.Channel > 14)
+				pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
+			else
+				pAd->CommonCfg.MlmeTransmit.field.MODE = 0;
+		}
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	//
+	// Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE)
+	// Snice it's been set to 0 while on MgtMacHeaderInit
+	// By the way this will cause frame to be send on PWR_SAVE failed.
+	//
+	// pHeader_802_11->FC.PwrMgmt = 0; // (pAd->StaCfg.Psm == PWR_SAVE);
+	//
+	// In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
+#ifdef CONFIG_STA_SUPPORT
+    // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD
+	if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL))
+	{
+		if ((pAd->StaCfg.Psm == PWR_SAVE) &&
+			(pHeader_802_11->FC.SubType == SUBTYPE_ACTION))
+			pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
+		else
+			pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	bInsertTimestamp = FALSE;
+	if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
+	{
+#ifdef CONFIG_STA_SUPPORT
+		//Set PM bit in ps-poll, to fix WLK 1.2  PowerSaveMode_ext failure issue.
+		if ((pAd->OpMode == OPMODE_STA) && (pHeader_802_11->FC.SubType == SUBTYPE_PS_POLL))
+		{
+			pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
+		}
+#endif // CONFIG_STA_SUPPORT //
+		bAckRequired = FALSE;
+	}
+	else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
+	{
+		//pAd->Sequence++;
+		//pHeader_802_11->Sequence = pAd->Sequence;
+
+		if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST
+		{
+			bAckRequired = FALSE;
+			pHeader_802_11->Duration = 0;
+		}
+		else
+		{
+			bAckRequired = TRUE;
+			pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);
+			if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
+			{
+				bInsertTimestamp = TRUE;
+			}
+		}
+	}
+
+	pHeader_802_11->Sequence = pAd->Sequence++;
+	if (pAd->Sequence >0xfff)
+		pAd->Sequence = 0;
+
+	// Before radar detection done, mgmt frame can not be sent but probe req
+	// Because we need to use probe req to trigger driver to send probe req in passive scan
+	if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
+		&& (pAd->CommonCfg.bIEEE80211H == 1)
+		&& (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));
+//		if (!IrqState)
+			RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
+		return (NDIS_STATUS_FAILURE);
+	}
+
+#ifdef RT_BIG_ENDIAN
+	RTMPFrameEndianChange(pAd, (PUCHAR)pHeader_802_11, DIR_WRITE, FALSE);
+#endif
+
+	//
+	// fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET
+	// should always has only one ohysical buffer, and the whole frame size equals
+	// to the first scatter buffer size
+	//
+
+	// Initialize TX Descriptor
+	// For inter-frame gap, the number is for this frame and next frame
+	// For MLME rate, we will fix as 2Mb to match other vendor's implement
+//	pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
+
+// management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.
+	if (pMacEntry == NULL)
+	{
+		RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
+		0, RESERVED_WCID, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID_MGMT, 0,  (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
+	}
+	else
+	{
+		RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
+					bInsertTimestamp, FALSE, bAckRequired, FALSE,
+					0, pMacEntry->Aid, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE),
+					pMacEntry->MaxHTPhyMode.field.MCS, 0,
+					(UCHAR)pMacEntry->MaxHTPhyMode.field.MCS,
+					IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
+	}
+
+#ifdef RT_BIG_ENDIAN
+	RTMPWIEndianChange((PUCHAR)pFirstTxWI, TYPE_TXWI);
+#endif
+
+	// Now do hardware-depened kick out.
+	HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen);
+
+	// Make sure to release MGMT ring resource
+//	if (!IrqState)
+		RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+/********************************************************************************
+
+	New DeQueue Procedures.
+
+ ********************************************************************************/
+
+#define DEQUEUE_LOCK(lock, bIntContext, IrqFlags) 				\
+			do{													\
+				if (bIntContext == FALSE)						\
+				RTMP_IRQ_LOCK((lock), IrqFlags);		\
+			}while(0)
+
+#define DEQUEUE_UNLOCK(lock, bIntContext, IrqFlags)				\
+			do{													\
+				if (bIntContext == FALSE)						\
+					RTMP_IRQ_UNLOCK((lock), IrqFlags);	\
+			}while(0)
+
+
+/*
+	========================================================================
+	Tx Path design algorithm:
+		Basically, we divide the packets into four types, Broadcast/Multicast, 11N Rate(AMPDU, AMSDU, Normal), B/G Rate(ARALINK, Normal),
+		Specific Packet Type. Following show the classification rule and policy for each kinds of packets.
+				Classification Rule=>
+					Multicast: (*addr1 & 0x01) == 0x01
+					Specific : bDHCPFrame, bARPFrame, bEAPOLFrame, etc.
+					11N Rate : If peer support HT
+								(1).AMPDU  -- If TXBA is negotiated.
+								(2).AMSDU  -- If AMSDU is capable for both peer and ourself.
+											*). AMSDU can embedded in a AMPDU, but now we didn't support it.
+								(3).Normal -- Other packets which send as 11n rate.
+
+					B/G Rate : If peer is b/g only.
+								(1).ARALINK-- If both of peer/us supprot Ralink proprietary Aggregation and the TxRate is large than RATE_6
+								(2).Normal -- Other packets which send as b/g rate.
+					Fragment:
+								The packet must be unicast, NOT A-RALINK, NOT A-MSDU, NOT 11n, then can consider about fragment.
+
+				Classified Packet Handle Rule=>
+					Multicast:
+								No ACK, 		//pTxBlk->bAckRequired = FALSE;
+								No WMM, 		//pTxBlk->bWMM = FALSE;
+								No piggyback,   //pTxBlk->bPiggyBack = FALSE;
+								Force LowRate,  //pTxBlk->bForceLowRate = TRUE;
+					Specific :	Basically, for specific packet, we should handle it specifically, but now all specific packets are use
+									the same policy to handle it.
+								Force LowRate,  //pTxBlk->bForceLowRate = TRUE;
+
+					11N Rate :
+								No piggyback,	//pTxBlk->bPiggyBack = FALSE;
+
+								(1).AMSDU
+									pTxBlk->bWMM = TRUE;
+								(2).AMPDU
+									pTxBlk->bWMM = TRUE;
+								(3).Normal
+
+					B/G Rate :
+								(1).ARALINK
+
+								(2).Normal
+	========================================================================
+*/
+static UCHAR TxPktClassification(
+	IN RTMP_ADAPTER *pAd,
+	IN PNDIS_PACKET  pPacket)
+{
+	UCHAR			TxFrameType = TX_UNKOWN_FRAME;
+	UCHAR			Wcid;
+	MAC_TABLE_ENTRY	*pMacEntry = NULL;
+#ifdef DOT11_N_SUPPORT
+	BOOLEAN			bHTRate = FALSE;
+#endif // DOT11_N_SUPPORT //
+
+	Wcid = RTMP_GET_PACKET_WCID(pPacket);
+	if (Wcid == MCAST_WCID)
+	{	// Handle for RA is Broadcast/Multicast Address.
+		return TX_MCAST_FRAME;
+	}
+
+	// Handle for unicast packets
+	pMacEntry = &pAd->MacTab.Content[Wcid];
+	if (RTMP_GET_PACKET_LOWRATE(pPacket))
+	{	// It's a specific packet need to force low rate, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame
+		TxFrameType = TX_LEGACY_FRAME;
+	}
+#ifdef DOT11_N_SUPPORT
+	else if (IS_HT_RATE(pMacEntry))
+	{	// it's a 11n capable packet
+
+		// Depends on HTPhyMode to check if the peer support the HTRate transmission.
+		// 	Currently didn't support A-MSDU embedded in A-MPDU
+		bHTRate = TRUE;
+		if (RTMP_GET_PACKET_MOREDATA(pPacket) || (pMacEntry->PsMode == PWR_SAVE))
+			TxFrameType = TX_LEGACY_FRAME;
+#ifdef UAPSD_AP_SUPPORT
+		else if (RTMP_GET_PACKET_EOSP(pPacket))
+			TxFrameType = TX_LEGACY_FRAME;
+#endif // UAPSD_AP_SUPPORT //
+		else if((pMacEntry->TXBAbitmap & (1<<(RTMP_GET_PACKET_UP(pPacket)))) != 0)
+			return TX_AMPDU_FRAME;
+		else if(CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AMSDU_INUSED))
+			return TX_AMSDU_FRAME;
+		else
+			TxFrameType = TX_LEGACY_FRAME;
+	}
+#endif // DOT11_N_SUPPORT //
+	else
+	{	// it's a legacy b/g packet.
+		if ((CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE) && pAd->CommonCfg.bAggregationCapable) &&
+			(RTMP_GET_PACKET_TXRATE(pPacket) >= RATE_6) &&
+			(!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
+		{	// if peer support Ralink Aggregation, we use it.
+			TxFrameType = TX_RALINK_FRAME;
+		}
+		else
+		{
+			TxFrameType = TX_LEGACY_FRAME;
+		}
+	}
+
+	// Currently, our fragment only support when a unicast packet send as NOT-ARALINK, NOT-AMSDU and NOT-AMPDU.
+	if ((RTMP_GET_PACKET_FRAGMENTS(pPacket) > 1) && (TxFrameType == TX_LEGACY_FRAME))
+		TxFrameType = TX_FRAG_FRAME;
+
+	return TxFrameType;
+}
+
+
+BOOLEAN RTMP_FillTxBlkInfo(
+	IN RTMP_ADAPTER *pAd,
+	IN TX_BLK *pTxBlk)
+{
+	PACKET_INFO			PacketInfo;
+	PNDIS_PACKET		pPacket;
+	PMAC_TABLE_ENTRY	pMacEntry = NULL;
+
+	pPacket = pTxBlk->pPacket;
+	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen);
+
+	pTxBlk->Wcid	 	 		= RTMP_GET_PACKET_WCID(pPacket);
+	pTxBlk->apidx		 		= RTMP_GET_PACKET_IF(pPacket);
+	pTxBlk->UserPriority 		= RTMP_GET_PACKET_UP(pPacket);
+	pTxBlk->FrameGap = IFS_HTTXOP;		// ASIC determine Frame Gap
+
+	if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pTxBlk->pPacket))
+		TX_BLK_SET_FLAG(pTxBlk, fTX_bClearEAPFrame);
+	else
+		TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bClearEAPFrame);
+
+	// Default to clear this flag
+	TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bForceNonQoS);
+
+
+	if (pTxBlk->Wcid == MCAST_WCID)
+	{
+		pTxBlk->pMacEntry = NULL;
+		{
+#ifdef MCAST_RATE_SPECIFIC
+			PUCHAR pDA = GET_OS_PKT_DATAPTR(pPacket);
+			if (((*pDA & 0x01) == 0x01) && (*pDA != 0xff))
+				pTxBlk->pTransmit = &pAd->CommonCfg.MCastPhyMode;
+			else
+#endif // MCAST_RATE_SPECIFIC //
+				pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
+		}
+
+		TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);	// AckRequired = FALSE, when broadcast packet in Adhoc mode.
+		//TX_BLK_SET_FLAG(pTxBlk, fTX_bForceLowRate);
+		TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAllowFrag);
+		TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
+		if (RTMP_GET_PACKET_MOREDATA(pPacket))
+		{
+			TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
+		}
+
+	}
+	else
+	{
+		pTxBlk->pMacEntry = &pAd->MacTab.Content[pTxBlk->Wcid];
+		pTxBlk->pTransmit = &pTxBlk->pMacEntry->HTPhyMode;
+
+		pMacEntry = pTxBlk->pMacEntry;
+
+
+		// For all unicast packets, need Ack unless the Ack Policy is not set as NORMAL_ACK.
+		if (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx] != NORMAL_ACK)
+			TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);
+		else
+			TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired);
+
+		{
+
+#ifdef CONFIG_STA_SUPPORT
+			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+			{
+
+				// If support WMM, enable it.
+				if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
+					CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))
+					TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM);
+
+//				if (pAd->StaCfg.bAutoTxRateSwitch)
+//					TX_BLK_SET_FLAG(pTxBlk, fTX_AutoRateSwitch);
+			}
+#endif // CONFIG_STA_SUPPORT //
+		}
+
+		if (pTxBlk->TxFrameType == TX_LEGACY_FRAME)
+		{
+			if ( (RTMP_GET_PACKET_LOWRATE(pPacket)) ||
+                ((pAd->OpMode == OPMODE_AP) && (pMacEntry->MaxHTPhyMode.field.MODE == MODE_CCK) && (pMacEntry->MaxHTPhyMode.field.MCS == RATE_1)))
+			{	// Specific packet, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame, need force low rate.
+				pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
+#ifdef DOT11_N_SUPPORT
+				// Modify the WMM bit for ICV issue. If we have a packet with EOSP field need to set as 1, how to handle it???
+				if (IS_HT_STA(pTxBlk->pMacEntry) &&
+					(CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RALINK_CHIPSET)) &&
+					((pAd->CommonCfg.bRdg == TRUE) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RDG_CAPABLE)))
+				{
+					TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
+					TX_BLK_SET_FLAG(pTxBlk, fTX_bForceNonQoS);
+				}
+#endif // DOT11_N_SUPPORT //
+			}
+
+#ifdef DOT11_N_SUPPORT
+			if ( (IS_HT_RATE(pMacEntry) == FALSE) &&
+				(CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE)))
+			{	// Currently piggy-back only support when peer is operate in b/g mode.
+				TX_BLK_SET_FLAG(pTxBlk, fTX_bPiggyBack);
+			}
+#endif // DOT11_N_SUPPORT //
+
+			if (RTMP_GET_PACKET_MOREDATA(pPacket))
+			{
+				TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
+			}
+#ifdef UAPSD_AP_SUPPORT
+			if (RTMP_GET_PACKET_EOSP(pPacket))
+			{
+				TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP);
+			}
+#endif // UAPSD_AP_SUPPORT //
+		}
+		else if (pTxBlk->TxFrameType == TX_FRAG_FRAME)
+		{
+			TX_BLK_SET_FLAG(pTxBlk, fTX_bAllowFrag);
+		}
+
+		pMacEntry->DebugTxCount++;
+	}
+
+	return TRUE;
+
+FillTxBlkErr:
+	return FALSE;
+}
+
+
+BOOLEAN CanDoAggregateTransmit(
+	IN RTMP_ADAPTER *pAd,
+	IN NDIS_PACKET *pPacket,
+	IN TX_BLK		*pTxBlk)
+{
+
+	//printk("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType);
+
+	if (RTMP_GET_PACKET_WCID(pPacket) == MCAST_WCID)
+		return FALSE;
+
+	if (RTMP_GET_PACKET_DHCP(pPacket) ||
+		RTMP_GET_PACKET_EAPOL(pPacket) ||
+		RTMP_GET_PACKET_WAI(pPacket))
+		return FALSE;
+
+	if ((pTxBlk->TxFrameType == TX_AMSDU_FRAME) &&
+		((pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))> (RX_BUFFER_AGGRESIZE - 100)))
+	{	// For AMSDU, allow the packets with total length < max-amsdu size
+		return FALSE;
+	}
+
+	if ((pTxBlk->TxFrameType == TX_RALINK_FRAME) &&
+		(pTxBlk->TxPacketList.Number == 2))
+	{	// For RALINK-Aggregation, allow two frames in one batch.
+		return FALSE;
+	}
+
+#ifdef CONFIG_STA_SUPPORT
+	if ((INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) // must be unicast to AP
+		return TRUE;
+	else
+#endif // CONFIG_STA_SUPPORT //
+		return FALSE;
+
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		To do the enqueue operation and extract the first item of waiting
+		list. If a number of available shared memory segments could meet
+		the request of extracted item, the extracted item will be fragmented
+		into shared memory segments.
+
+	Arguments:
+		pAd Pointer to our adapter
+		pQueue		Pointer to Waiting Queue
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+VOID RTMPDeQueuePacket(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  BOOLEAN         bIntContext,
+	IN  UCHAR			QIdx, /* BulkOutPipeId */
+	IN  UCHAR           Max_Tx_Packets)
+{
+	PQUEUE_ENTRY    pEntry = NULL;
+	PNDIS_PACKET 	pPacket;
+	NDIS_STATUS     Status = NDIS_STATUS_SUCCESS;
+	UCHAR           Count=0;
+	PQUEUE_HEADER   pQueue;
+	ULONG           FreeNumber[NUM_OF_TX_RING];
+	UCHAR			QueIdx, sQIdx, eQIdx;
+	unsigned long	IrqFlags = 0;
+	BOOLEAN			hasTxDesc = FALSE;
+	TX_BLK			TxBlk;
+	TX_BLK			*pTxBlk;
+
+#ifdef DBG_DIAGNOSE
+	BOOLEAN			firstRound;
+	RtmpDiagStruct	*pDiagStruct = &pAd->DiagStruct;
+#endif
+
+
+	if (QIdx == NUM_OF_TX_RING)
+	{
+		sQIdx = 0;
+//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		eQIdx = 3;	// 4 ACs, start from 0.
+#endif // CONFIG_STA_SUPPORT //
+	}
+	else
+	{
+		sQIdx = eQIdx = QIdx;
+	}
+
+	for (QueIdx=sQIdx; QueIdx <= eQIdx; QueIdx++)
+	{
+		Count=0;
+
+		RT28XX_START_DEQUEUE(pAd, QueIdx, IrqFlags);
+
+#ifdef DBG_DIAGNOSE
+		firstRound = ((QueIdx == 0) ? TRUE : FALSE);
+#endif // DBG_DIAGNOSE //
+
+		while (1)
+		{
+			if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS |
+										fRTMP_ADAPTER_RADIO_OFF |
+										fRTMP_ADAPTER_RESET_IN_PROGRESS |
+										fRTMP_ADAPTER_HALT_IN_PROGRESS |
+										fRTMP_ADAPTER_NIC_NOT_EXIST))))
+			{
+				RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
+				return;
+			}
+
+			if (Count >= Max_Tx_Packets)
+				break;
+
+			DEQUEUE_LOCK(&pAd->irq_lock, bIntContext, IrqFlags);
+			if (&pAd->TxSwQueue[QueIdx] == NULL)
+			{
+#ifdef DBG_DIAGNOSE
+				if (firstRound == TRUE)
+					pDiagStruct->TxSWQueCnt[pDiagStruct->ArrayCurIdx][0]++;
+#endif // DBG_DIAGNOSE //
+				DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
+				break;
+			}
+
+
+			// probe the Queue Head
+			pQueue = &pAd->TxSwQueue[QueIdx];
+			if ((pEntry = pQueue->Head) == NULL)
+			{
+				DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
+				break;
+			}
+
+			pTxBlk = &TxBlk;
+			NdisZeroMemory((PUCHAR)pTxBlk, sizeof(TX_BLK));
+			//InitializeQueueHeader(&pTxBlk->TxPacketList);		// Didn't need it because we already memzero it.
+			pTxBlk->QueIdx = QueIdx;
+
+			pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
+
+			// Early check to make sure we have enoguh Tx Resource.
+			hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
+			if (!hasTxDesc)
+			{
+				pAd->PrivateInfo.TxRingFullCnt++;
+
+				DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
+
+				break;
+			}
+
+			pTxBlk->TxFrameType = TxPktClassification(pAd, pPacket);
+			pEntry = RemoveHeadQueue(pQueue);
+			pTxBlk->TotalFrameNum++;
+			pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket);	// The real fragment number maybe vary
+			pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
+			pTxBlk->pPacket = pPacket;
+			InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
+
+			if (pTxBlk->TxFrameType == TX_RALINK_FRAME || pTxBlk->TxFrameType == TX_AMSDU_FRAME)
+			{
+				// Enhance SW Aggregation Mechanism
+				if (NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, FreeNumber[QueIdx], pTxBlk->TxFrameType))
+				{
+					InsertHeadQueue(pQueue, PACKET_TO_QUEUE_ENTRY(pPacket));
+					DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
+					break;
+				}
+
+				do{
+					if((pEntry = pQueue->Head) == NULL)
+						break;
+
+					// For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation.
+					pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
+					FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
+					hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
+					if ((hasTxDesc == FALSE) || (CanDoAggregateTransmit(pAd, pPacket, pTxBlk) == FALSE))
+						break;
+
+					//Remove the packet from the TxSwQueue and insert into pTxBlk
+					pEntry = RemoveHeadQueue(pQueue);
+					ASSERT(pEntry);
+					pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
+					pTxBlk->TotalFrameNum++;
+					pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket);	// The real fragment number maybe vary
+					pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
+					InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
+				}while(1);
+
+				if (pTxBlk->TxPacketList.Number == 1)
+					pTxBlk->TxFrameType = TX_LEGACY_FRAME;
+			}
+
+#ifdef RT2870
+			DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
+#endif // RT2870 //
+
+			Count += pTxBlk->TxPacketList.Number;
+
+				// Do HardTransmit now.
+#ifdef CONFIG_STA_SUPPORT
+			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+				Status = STAHardTransmit(pAd, pTxBlk, QueIdx);
+#endif // CONFIG_STA_SUPPORT //
+		}
+
+		RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
+
+#ifdef RT2870
+		if (!hasTxDesc)
+			RTUSBKickBulkOut(pAd);
+#endif // RT2870 //
+
+#ifdef BLOCK_NET_IF
+		if ((pAd->blockQueueTab[QueIdx].SwTxQueueBlockFlag == TRUE)
+			&& (pAd->TxSwQueue[QueIdx].Number < 1))
+		{
+			releaseNetIf(&pAd->blockQueueTab[QueIdx]);
+		}
+#endif // BLOCK_NET_IF //
+
+	}
+
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Calculates the duration which is required to transmit out frames
+	with given size and specified rate.
+
+	Arguments:
+		pAd 	Pointer to our adapter
+		Rate			Transmit rate
+		Size			Frame size in units of byte
+
+	Return Value:
+		Duration number in units of usec
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+USHORT	RTMPCalcDuration(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			Rate,
+	IN	ULONG			Size)
+{
+	ULONG	Duration = 0;
+
+	if (Rate < RATE_FIRST_OFDM_RATE) // CCK
+	{
+		if ((Rate > RATE_1) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED))
+			Duration = 96;	// 72+24 preamble+plcp
+		else
+			Duration = 192; // 144+48 preamble+plcp
+
+		Duration += (USHORT)((Size << 4) / RateIdTo500Kbps[Rate]);
+		if ((Size << 4) % RateIdTo500Kbps[Rate])
+			Duration ++;
+	}
+	else if (Rate <= RATE_LAST_OFDM_RATE)// OFDM rates
+	{
+		Duration = 20 + 6;		// 16+4 preamble+plcp + Signal Extension
+		Duration += 4 * (USHORT)((11 + Size * 4) / RateIdTo500Kbps[Rate]);
+		if ((11 + Size * 4) % RateIdTo500Kbps[Rate])
+			Duration += 4;
+	}
+	else	//mimo rate
+	{
+		Duration = 20 + 6;		// 16+4 preamble+plcp + Signal Extension
+	}
+
+	return (USHORT)Duration;
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Calculates the duration which is required to transmit out frames
+	with given size and specified rate.
+
+	Arguments:
+		pTxWI		Pointer to head of each MPDU to HW.
+		Ack 		Setting for Ack requirement bit
+		Fragment	Setting for Fragment bit
+		RetryMode	Setting for retry mode
+		Ifs 		Setting for IFS gap
+		Rate		Setting for transmit rate
+		Service 	Setting for service
+		Length		Frame length
+		TxPreamble	Short or Long preamble when using CCK rates
+		QueIdx - 0-3, according to 802.11e/d4.4 June/2003
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+    See also : BASmartHardTransmit()    !!!
+
+	========================================================================
+*/
+VOID RTMPWriteTxWI(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PTXWI_STRUC 	pOutTxWI,
+	IN	BOOLEAN			FRAG,
+	IN	BOOLEAN			CFACK,
+	IN	BOOLEAN			InsTimestamp,
+	IN	BOOLEAN 		AMPDU,
+	IN	BOOLEAN 		Ack,
+	IN	BOOLEAN 		NSeq,		// HW new a sequence.
+	IN	UCHAR			BASize,
+	IN	UCHAR			WCID,
+	IN	ULONG			Length,
+	IN	UCHAR 			PID,
+	IN	UCHAR			TID,
+	IN	UCHAR			TxRate,
+	IN	UCHAR			Txopmode,
+	IN	BOOLEAN			CfAck,
+	IN	HTTRANSMIT_SETTING	*pTransmit)
+{
+	PMAC_TABLE_ENTRY	pMac = NULL;
+	TXWI_STRUC 		TxWI;
+	PTXWI_STRUC 	pTxWI;
+
+	if (WCID < MAX_LEN_OF_MAC_TABLE)
+		pMac = &pAd->MacTab.Content[WCID];
+
+	//
+	// Always use Long preamble before verifiation short preamble functionality works well.
+	// Todo: remove the following line if short preamble functionality works
+	//
+	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
+	NdisZeroMemory(&TxWI, TXWI_SIZE);
+	pTxWI = &TxWI;
+
+	pTxWI->FRAG= FRAG;
+
+	pTxWI->CFACK = CFACK;
+	pTxWI->TS= InsTimestamp;
+	pTxWI->AMPDU = AMPDU;
+	pTxWI->ACK = Ack;
+	pTxWI->txop= Txopmode;
+
+	pTxWI->NSEQ = NSeq;
+	// John tune the performace with Intel Client in 20 MHz performance
+#ifdef DOT11_N_SUPPORT
+	BASize = pAd->CommonCfg.TxBASize;
+
+	if( BASize >7 )
+		BASize =7;
+	pTxWI->BAWinSize = BASize;
+	pTxWI->ShortGI = pTransmit->field.ShortGI;
+	pTxWI->STBC = pTransmit->field.STBC;
+#endif // DOT11_N_SUPPORT //
+
+	pTxWI->WirelessCliID = WCID;
+	pTxWI->MPDUtotalByteCount = Length;
+	pTxWI->PacketId = PID;
+
+	// If CCK or OFDM, BW must be 20
+	pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
+#ifdef DOT11N_DRAFT3
+	if (pTxWI->BW)
+		pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
+#endif // DOT11N_DRAFT3 //
+
+	pTxWI->MCS = pTransmit->field.MCS;
+	pTxWI->PHYMODE = pTransmit->field.MODE;
+	pTxWI->CFACK = CfAck;
+
+#ifdef DOT11_N_SUPPORT
+	if (pMac)
+	{
+		if (pAd->CommonCfg.bMIMOPSEnable)
+		{
+			if ((pMac->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
+			{
+				// Dynamic MIMO Power Save Mode
+				pTxWI->MIMOps = 1;
+			}
+			else if (pMac->MmpsMode == MMPS_STATIC)
+			{
+				// Static MIMO Power Save Mode
+				if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
+				{
+					pTxWI->MCS = 7;
+					pTxWI->MIMOps = 0;
+				}
+			}
+		}
+		//pTxWI->MIMOps = (pMac->PsMode == PWR_MMPS)? 1:0;
+		if (pMac->bIAmBadAtheros && (pMac->WepStatus != Ndis802_11WEPDisabled))
+		{
+			pTxWI->MpduDensity = 7;
+		}
+		else
+		{
+			pTxWI->MpduDensity = pMac->MpduDensity;
+		}
+	}
+#endif // DOT11_N_SUPPORT //
+
+	pTxWI->PacketId = pTxWI->MCS;
+	NdisMoveMemory(pOutTxWI, &TxWI, sizeof(TXWI_STRUC));
+}
+
+
+VOID RTMPWriteTxWI_Data(
+	IN	PRTMP_ADAPTER		pAd,
+	IN	OUT PTXWI_STRUC		pTxWI,
+	IN	TX_BLK				*pTxBlk)
+{
+	HTTRANSMIT_SETTING	*pTransmit;
+	PMAC_TABLE_ENTRY	pMacEntry;
+#ifdef DOT11_N_SUPPORT
+	UCHAR				BASize;
+#endif // DOT11_N_SUPPORT //
+
+
+	ASSERT(pTxWI);
+
+	pTransmit = pTxBlk->pTransmit;
+	pMacEntry = pTxBlk->pMacEntry;
+
+
+	//
+	// Always use Long preamble before verifiation short preamble functionality works well.
+	// Todo: remove the following line if short preamble functionality works
+	//
+	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
+	NdisZeroMemory(pTxWI, TXWI_SIZE);
+
+	pTxWI->FRAG		= TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag);
+	pTxWI->ACK		= TX_BLK_TEST_FLAG(pTxBlk, fTX_bAckRequired);
+	pTxWI->txop		= pTxBlk->FrameGap;
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+	if (pMacEntry &&
+		(pAd->StaCfg.BssType == BSS_INFRA) &&
+		(pMacEntry->ValidAsDls == TRUE))
+		pTxWI->WirelessCliID = BSSID_WCID;
+	else
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+		pTxWI->WirelessCliID		= pTxBlk->Wcid;
+
+	pTxWI->MPDUtotalByteCount	= pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
+	pTxWI->CFACK				= TX_BLK_TEST_FLAG(pTxBlk, fTX_bPiggyBack);
+
+	// If CCK or OFDM, BW must be 20
+	pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+	if (pTxWI->BW)
+		pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
+#endif // DOT11N_DRAFT3 //
+	pTxWI->AMPDU	= ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) ? TRUE : FALSE);
+
+	// John tune the performace with Intel Client in 20 MHz performance
+	BASize = pAd->CommonCfg.TxBASize;
+	if((pTxBlk->TxFrameType == TX_AMPDU_FRAME) && (pMacEntry))
+	{
+		UCHAR		RABAOriIdx = 0;	//The RA's BA Originator table index.
+
+		RABAOriIdx = pTxBlk->pMacEntry->BAOriWcidArray[pTxBlk->UserPriority];
+		BASize = pAd->BATable.BAOriEntry[RABAOriIdx].BAWinSize;
+	}
+
+	pTxWI->TxBF = pTransmit->field.TxBF;
+	pTxWI->BAWinSize = BASize;
+	pTxWI->ShortGI = pTransmit->field.ShortGI;
+	pTxWI->STBC = pTransmit->field.STBC;
+#endif // DOT11_N_SUPPORT //
+
+	pTxWI->MCS = pTransmit->field.MCS;
+	pTxWI->PHYMODE = pTransmit->field.MODE;
+
+#ifdef DOT11_N_SUPPORT
+	if (pMacEntry)
+	{
+		if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
+		{
+			// Dynamic MIMO Power Save Mode
+			pTxWI->MIMOps = 1;
+		}
+		else if (pMacEntry->MmpsMode == MMPS_STATIC)
+		{
+			// Static MIMO Power Save Mode
+			if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
+			{
+				pTxWI->MCS = 7;
+				pTxWI->MIMOps = 0;
+			}
+		}
+
+		if (pMacEntry->bIAmBadAtheros && (pMacEntry->WepStatus != Ndis802_11WEPDisabled))
+		{
+			pTxWI->MpduDensity = 7;
+		}
+		else
+		{
+			pTxWI->MpduDensity = pMacEntry->MpduDensity;
+		}
+	}
+#endif // DOT11_N_SUPPORT //
+
+#ifdef DBG_DIAGNOSE
+		if (pTxBlk->QueIdx== 0)
+		{
+			pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
+			pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
+		}
+#endif // DBG_DIAGNOSE //
+
+	// for rate adapation
+	pTxWI->PacketId = pTxWI->MCS;
+#ifdef INF_AMAZON_SE
+/*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate */
+	if( RTMP_GET_PACKET_NOBULKOUT(pTxBlk->pPacket))
+	{
+		if(pTxWI->PHYMODE == MODE_CCK)
+		{
+			pTxWI->PacketId = 6;
+		}
+	}
+#endif // INF_AMAZON_SE //
+}
+
+
+VOID RTMPWriteTxWI_Cache(
+	IN	PRTMP_ADAPTER		pAd,
+	IN	OUT PTXWI_STRUC		pTxWI,
+	IN	TX_BLK				*pTxBlk)
+{
+	PHTTRANSMIT_SETTING	/*pTxHTPhyMode,*/ pTransmit;
+	PMAC_TABLE_ENTRY	pMacEntry;
+
+	//
+	// update TXWI
+	//
+	pMacEntry = pTxBlk->pMacEntry;
+	pTransmit = pTxBlk->pTransmit;
+
+	//if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
+	//if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pMacEntry))
+	//if (TX_BLK_TEST_FLAG(pTxBlk, fTX_AutoRateSwitch))
+	if (pMacEntry->bAutoTxRateSwitch)
+	{
+		pTxWI->txop = IFS_HTTXOP;
+
+		// If CCK or OFDM, BW must be 20
+		pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
+		pTxWI->ShortGI = pTransmit->field.ShortGI;
+		pTxWI->STBC = pTransmit->field.STBC;
+
+		pTxWI->MCS = pTransmit->field.MCS;
+		pTxWI->PHYMODE = pTransmit->field.MODE;
+
+		// set PID for TxRateSwitching
+		pTxWI->PacketId = pTransmit->field.MCS;
+	}
+
+#ifdef DOT11_N_SUPPORT
+	pTxWI->AMPDU = ((pMacEntry->NoBADataCountDown == 0) ? TRUE: FALSE);
+	pTxWI->MIMOps = 0;
+
+#ifdef DOT11N_DRAFT3
+	if (pTxWI->BW)
+		pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
+#endif // DOT11N_DRAFT3 //
+
+	if (pAd->CommonCfg.bMIMOPSEnable)
+	{
+		// MIMO Power Save Mode
+		if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
+		{
+			// Dynamic MIMO Power Save Mode
+			pTxWI->MIMOps = 1;
+		}
+		else if (pMacEntry->MmpsMode == MMPS_STATIC)
+		{
+			// Static MIMO Power Save Mode
+			if ((pTransmit->field.MODE >= MODE_HTMIX) && (pTransmit->field.MCS > 7))
+			{
+				pTxWI->MCS = 7;
+				pTxWI->MIMOps = 0;
+			}
+		}
+	}
+#endif // DOT11_N_SUPPORT //
+
+#ifdef DBG_DIAGNOSE
+	if (pTxBlk->QueIdx== 0)
+	{
+		pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
+		pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
+	}
+#endif // DBG_DIAGNOSE //
+
+	pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
+
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Calculates the duration which is required to transmit out frames
+	with given size and specified rate.
+
+	Arguments:
+		pTxD		Pointer to transmit descriptor
+		Ack 		Setting for Ack requirement bit
+		Fragment	Setting for Fragment bit
+		RetryMode	Setting for retry mode
+		Ifs 		Setting for IFS gap
+		Rate		Setting for transmit rate
+		Service 	Setting for service
+		Length		Frame length
+		TxPreamble	Short or Long preamble when using CCK rates
+		QueIdx - 0-3, according to 802.11e/d4.4 June/2003
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	========================================================================
+*/
+VOID RTMPWriteTxDescriptor(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PTXD_STRUC		pTxD,
+	IN	BOOLEAN 		bWIV,
+	IN	UCHAR			QueueSEL)
+{
+	//
+	// Always use Long preamble before verifiation short preamble functionality works well.
+	// Todo: remove the following line if short preamble functionality works
+	//
+	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
+
+	pTxD->WIV	= (bWIV) ? 1: 0;
+	pTxD->QSEL= (QueueSEL);
+	if (pAd->bGenOneHCCA == TRUE)
+		pTxD->QSEL= FIFO_HCCA;
+	pTxD->DMADONE = 0;
+}
+
+
+// should be called only when -
+// 1. MEADIA_CONNECTED
+// 2. AGGREGATION_IN_USED
+// 3. Fragmentation not in used
+// 4. either no previous frame (pPrevAddr1=NULL) .OR. previoud frame is aggregatible
+BOOLEAN TxFrameIsAggregatible(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pPrevAddr1,
+	IN	PUCHAR			p8023hdr)
+{
+
+	// can't aggregate EAPOL (802.1x) frame
+	if ((p8023hdr[12] == 0x88) && (p8023hdr[13] == 0x8e))
+		return FALSE;
+
+	// can't aggregate multicast/broadcast frame
+	if (p8023hdr[0] & 0x01)
+		return FALSE;
+
+	if (INFRA_ON(pAd)) // must be unicast to AP
+		return TRUE;
+	else if ((pPrevAddr1 == NULL) || MAC_ADDR_EQUAL(pPrevAddr1, p8023hdr)) // unicast to same STA
+		return TRUE;
+	else
+		return FALSE;
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+	   Check the MSDU Aggregation policy
+	1.HT aggregation is A-MSDU
+	2.legaacy rate aggregation is software aggregation by Ralink.
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+	========================================================================
+*/
+BOOLEAN PeerIsAggreOn(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	ULONG		   TxRate,
+	IN	PMAC_TABLE_ENTRY pMacEntry)
+{
+	ULONG	AFlags = (fCLIENT_STATUS_AMSDU_INUSED | fCLIENT_STATUS_AGGREGATION_CAPABLE);
+
+	if (pMacEntry != NULL && CLIENT_STATUS_TEST_FLAG(pMacEntry, AFlags))
+	{
+#ifdef DOT11_N_SUPPORT
+		if (pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
+		{
+			return TRUE;
+		}
+#endif // DOT11_N_SUPPORT //
+
+#ifdef AGGREGATION_SUPPORT
+		if (TxRate >= RATE_6 && pAd->CommonCfg.bAggregationCapable && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
+		{	// legacy  Ralink Aggregation support
+			return TRUE;
+		}
+#endif // AGGREGATION_SUPPORT //
+	}
+
+	return FALSE;
+
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Check and fine the packet waiting in SW queue with highest priority
+
+	Arguments:
+		pAd Pointer to our adapter
+
+	Return Value:
+		pQueue		Pointer to Waiting Queue
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+PQUEUE_HEADER	RTMPCheckTxSwQueue(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT PUCHAR			pQueIdx)
+{
+
+	ULONG	Number;
+	// 2004-11-15 to be removed. test aggregation only
+//	if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)) && (*pNumber < 2))
+//		 return NULL;
+
+	Number = pAd->TxSwQueue[QID_AC_BK].Number
+			 + pAd->TxSwQueue[QID_AC_BE].Number
+			 + pAd->TxSwQueue[QID_AC_VI].Number
+			 + pAd->TxSwQueue[QID_AC_VO].Number
+			 + pAd->TxSwQueue[QID_HCCA].Number;
+
+	if (pAd->TxSwQueue[QID_AC_VO].Head != NULL)
+	{
+		*pQueIdx = QID_AC_VO;
+		return (&pAd->TxSwQueue[QID_AC_VO]);
+	}
+	else if (pAd->TxSwQueue[QID_AC_VI].Head != NULL)
+	{
+		*pQueIdx = QID_AC_VI;
+		return (&pAd->TxSwQueue[QID_AC_VI]);
+	}
+	else if (pAd->TxSwQueue[QID_AC_BE].Head != NULL)
+	{
+		*pQueIdx = QID_AC_BE;
+		return (&pAd->TxSwQueue[QID_AC_BE]);
+	}
+	else if (pAd->TxSwQueue[QID_AC_BK].Head != NULL)
+	{
+		*pQueIdx = QID_AC_BK;
+		return (&pAd->TxSwQueue[QID_AC_BK]);
+	}
+	else if (pAd->TxSwQueue[QID_HCCA].Head != NULL)
+	{
+		*pQueIdx = QID_HCCA;
+		return (&pAd->TxSwQueue[QID_HCCA]);
+	}
+
+	// No packet pending in Tx Sw queue
+	*pQueIdx = QID_AC_BK;
+
+	return (NULL);
+}
+
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Suspend MSDU transmission
+
+	Arguments:
+		pAd 	Pointer to our adapter
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTMPSuspendMsduTransmission(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	DBGPRINT(RT_DEBUG_TRACE,("SCANNING, suspend MSDU transmission ...\n"));
+
+
+	//
+	// Before BSS_SCAN_IN_PROGRESS, we need to keep Current R66 value and
+	// use Lowbound as R66 value on ScanNextChannel(...)
+	//
+	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
+
+	// set BBP_R66 to 0x30/0x40 when scanning (AsicSwitchChannel will set R66 according to channel when scanning)
+	//RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x26 + GET_LNA_GAIN(pAd)));
+	RTMPSetAGCInitValue(pAd, BW_20);
+
+	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+	//RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x000f0000);		// abort all TX rings
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Resume MSDU transmission
+
+	Arguments:
+		pAd 	Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+VOID RTMPResumeMsduTransmission(
+	IN	PRTMP_ADAPTER	pAd)
+{
+//    UCHAR			IrqState;
+
+	DBGPRINT(RT_DEBUG_TRACE,("SCAN done, resume MSDU transmission ...\n"));
+
+
+	// After finish BSS_SCAN_IN_PROGRESS, we need to restore Current R66 value
+	// R66 should not be 0
+	if (pAd->BbpTuning.R66CurrentValue == 0)
+	{
+		pAd->BbpTuning.R66CurrentValue = 0x38;
+		DBGPRINT_ERR(("RTMPResumeMsduTransmission, R66CurrentValue=0...\n"));
+	}
+	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, pAd->BbpTuning.R66CurrentValue);
+
+	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+// sample, for IRQ LOCK to SEM LOCK
+//    IrqState = pAd->irq_disabled;
+//	if (IrqState)
+//		RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+//    else
+	RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+}
+
+
+UINT deaggregate_AMSDU_announce(
+	IN	PRTMP_ADAPTER	pAd,
+	PNDIS_PACKET		pPacket,
+	IN	PUCHAR			pData,
+	IN	ULONG			DataSize)
+{
+	USHORT 			PayloadSize;
+	USHORT 			SubFrameSize;
+	PHEADER_802_3 	pAMSDUsubheader;
+	UINT			nMSDU;
+    UCHAR			Header802_3[14];
+
+	PUCHAR			pPayload, pDA, pSA, pRemovedLLCSNAP;
+	PNDIS_PACKET	pClonePacket;
+
+
+
+	nMSDU = 0;
+
+	while (DataSize > LENGTH_802_3)
+	{
+
+		nMSDU++;
+
+		//hex_dump("subheader", pData, 64);
+		pAMSDUsubheader = (PHEADER_802_3)pData;
+		//pData += LENGTH_802_3;
+		PayloadSize = pAMSDUsubheader->Octet[1] + (pAMSDUsubheader->Octet[0]<<8);
+		SubFrameSize = PayloadSize + LENGTH_802_3;
+
+
+		if ((DataSize < SubFrameSize) || (PayloadSize > 1518 ))
+		{
+			break;
+		}
+
+		//printk("%d subframe: Size = %d\n",  nMSDU, PayloadSize);
+
+		pPayload = pData + LENGTH_802_3;
+		pDA = pData;
+		pSA = pData + MAC_ADDR_LEN;
+
+		// convert to 802.3 header
+        CONVERT_TO_802_3(Header802_3, pDA, pSA, pPayload, PayloadSize, pRemovedLLCSNAP);
+
+#ifdef CONFIG_STA_SUPPORT
+		if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E) )
+		{
+		    // avoid local heap overflow, use dyanamic allocation
+		   MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
+		   memmove(Elem->Msg+(LENGTH_802_11 + LENGTH_802_1_H), pPayload, PayloadSize);
+		   Elem->MsgLen = LENGTH_802_11 + LENGTH_802_1_H + PayloadSize;
+		   WpaEAPOLKeyAction(pAd, Elem);
+		   kfree(Elem);
+		}
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+	        	if (pRemovedLLCSNAP)
+	        	{
+	    			pPayload -= LENGTH_802_3;
+	    			PayloadSize += LENGTH_802_3;
+	    			NdisMoveMemory(pPayload, &Header802_3[0], LENGTH_802_3);
+	        	}
+		}
+#endif // CONFIG_STA_SUPPORT //
+
+		pClonePacket = ClonePacket(pAd, pPacket, pPayload, PayloadSize);
+		if (pClonePacket)
+		{
+#ifdef CONFIG_STA_SUPPORT
+			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+				ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pClonePacket, RTMP_GET_PACKET_IF(pPacket));
+#endif // CONFIG_STA_SUPPORT //
+		}
+
+
+		// A-MSDU has padding to multiple of 4 including subframe header.
+		// align SubFrameSize up to multiple of 4
+		SubFrameSize = (SubFrameSize+3)&(~0x3);
+
+
+		if (SubFrameSize > 1528 || SubFrameSize < 32)
+		{
+			break;
+		}
+
+		if (DataSize > SubFrameSize)
+		{
+			pData += SubFrameSize;
+			DataSize -= SubFrameSize;
+		}
+		else
+		{
+			// end of A-MSDU
+			DataSize = 0;
+		}
+	}
+
+	// finally release original rx packet
+	RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+
+	return nMSDU;
+}
+
+
+UINT BA_Reorder_AMSDU_Annnounce(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PNDIS_PACKET	pPacket)
+{
+	PUCHAR			pData;
+	USHORT			DataSize;
+	UINT			nMSDU = 0;
+
+	pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
+	DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
+
+	nMSDU = deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
+
+	return nMSDU;
+}
+
+
+/*
+	==========================================================================
+	Description:
+		Look up the MAC address in the MAC table. Return NULL if not found.
+	Return:
+		pEntry - pointer to the MAC entry; NULL is not found
+	==========================================================================
+*/
+MAC_TABLE_ENTRY *MacTableLookup(
+	IN PRTMP_ADAPTER pAd,
+	PUCHAR pAddr)
+{
+	ULONG HashIdx;
+	MAC_TABLE_ENTRY *pEntry = NULL;
+
+	HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
+	pEntry = pAd->MacTab.Hash[HashIdx];
+
+	while (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsWDS || pEntry->ValidAsApCli || pEntry->ValidAsMesh))
+	{
+		if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
+		{
+			break;
+		}
+		else
+			pEntry = pEntry->pNext;
+	}
+
+	return pEntry;
+}
+
+MAC_TABLE_ENTRY *MacTableInsertEntry(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR			pAddr,
+	IN	UCHAR			apidx,
+	IN BOOLEAN	CleanAll)
+{
+	UCHAR HashIdx;
+	int i, FirstWcid;
+	MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
+//	USHORT	offset;
+//	ULONG	addr;
+
+	// if FULL, return
+	if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
+		return NULL;
+
+	FirstWcid = 1;
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	if (pAd->StaCfg.BssType == BSS_INFRA)
+		FirstWcid = 2;
+#endif // CONFIG_STA_SUPPORT //
+
+	// allocate one MAC entry
+	NdisAcquireSpinLock(&pAd->MacTabLock);
+	for (i = FirstWcid; i< MAX_LEN_OF_MAC_TABLE; i++)   // skip entry#0 so that "entry index == AID" for fast lookup
+	{
+		// pick up the first available vacancy
+		if ((pAd->MacTab.Content[i].ValidAsCLI == FALSE) &&
+			(pAd->MacTab.Content[i].ValidAsWDS == FALSE) &&
+			(pAd->MacTab.Content[i].ValidAsApCli== FALSE) &&
+			(pAd->MacTab.Content[i].ValidAsMesh == FALSE)
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+			&& (pAd->MacTab.Content[i].ValidAsDls == FALSE)
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+			)
+		{
+			pEntry = &pAd->MacTab.Content[i];
+			if (CleanAll == TRUE)
+			{
+				pEntry->MaxSupportedRate = RATE_11;
+				pEntry->CurrTxRate = RATE_11;
+				NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
+				pEntry->PairwiseKey.KeyLen = 0;
+				pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
+			}
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+			if (apidx >= MIN_NET_DEVICE_FOR_DLS)
+			{
+				pEntry->ValidAsCLI = FALSE;
+				pEntry->ValidAsWDS = FALSE;
+				pEntry->ValidAsApCli = FALSE;
+				pEntry->ValidAsMesh = FALSE;
+				pEntry->ValidAsDls = TRUE;
+				pEntry->isCached = FALSE;
+			}
+			else
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+			{
+
+#ifdef CONFIG_STA_SUPPORT
+				IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+				{
+					pEntry->ValidAsCLI = TRUE;
+					pEntry->ValidAsWDS = FALSE;
+					pEntry->ValidAsApCli = FALSE;
+					pEntry->ValidAsMesh = FALSE;
+					pEntry->ValidAsDls = FALSE;
+				}
+#endif // CONFIG_STA_SUPPORT //
+			}
+
+			pEntry->bIAmBadAtheros = FALSE;
+			pEntry->pAd = pAd;
+			pEntry->CMTimerRunning = FALSE;
+			pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
+			pEntry->RSNIE_Len = 0;
+			NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter));
+			pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
+
+			if (pEntry->ValidAsMesh)
+				pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_MESH);
+			else if (pEntry->ValidAsApCli)
+				pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_APCLI);
+			else if (pEntry->ValidAsWDS)
+				pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_WDS);
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+			else if (pEntry->ValidAsDls)
+				pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_DLS);
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+			else
+				pEntry->apidx = apidx;
+
+			{
+
+#ifdef CONFIG_STA_SUPPORT
+				IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+				{
+					pEntry->AuthMode = pAd->StaCfg.AuthMode;
+					pEntry->WepStatus = pAd->StaCfg.WepStatus;
+					pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
+				}
+#endif // CONFIG_STA_SUPPORT //
+			}
+
+			pEntry->GTKState = REKEY_NEGOTIATING;
+			pEntry->PairwiseKey.KeyLen = 0;
+			pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+			if (pEntry->ValidAsDls == TRUE)
+				pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+			else
+#endif //QOS_DLS_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+			pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+			pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
+			COPY_MAC_ADDR(pEntry->Addr, pAddr);
+			pEntry->Sst = SST_NOT_AUTH;
+			pEntry->AuthState = AS_NOT_AUTH;
+			pEntry->Aid = (USHORT)i;  //0;
+			pEntry->CapabilityInfo = 0;
+			pEntry->PsMode = PWR_ACTIVE;
+			pEntry->PsQIdleCount = 0;
+			pEntry->NoDataIdleCount = 0;
+			pEntry->ContinueTxFailCnt = 0;
+			InitializeQueueHeader(&pEntry->PsQueue);
+
+
+			pAd->MacTab.Size ++;
+
+			// Add this entry into ASIC RX WCID search table
+			RT28XX_STA_ENTRY_ADD(pAd, pEntry);
+
+
+
+			DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertEntry - allocate entry #%d, Total= %d\n",i, pAd->MacTab.Size));
+			break;
+		}
+	}
+
+	// add this MAC entry into HASH table
+	if (pEntry)
+	{
+		HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
+		if (pAd->MacTab.Hash[HashIdx] == NULL)
+		{
+			pAd->MacTab.Hash[HashIdx] = pEntry;
+		}
+		else
+		{
+			pCurrEntry = pAd->MacTab.Hash[HashIdx];
+			while (pCurrEntry->pNext != NULL)
+				pCurrEntry = pCurrEntry->pNext;
+			pCurrEntry->pNext = pEntry;
+		}
+	}
+
+	NdisReleaseSpinLock(&pAd->MacTabLock);
+	return pEntry;
+}
+
+/*
+	==========================================================================
+	Description:
+		Delete a specified client from MAC table
+	==========================================================================
+ */
+BOOLEAN MacTableDeleteEntry(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT wcid,
+	IN PUCHAR pAddr)
+{
+	USHORT HashIdx;
+	MAC_TABLE_ENTRY *pEntry, *pPrevEntry, *pProbeEntry;
+	BOOLEAN Cancelled;
+	//USHORT	offset;	// unused variable
+	//UCHAR	j;			// unused variable
+
+	if (wcid >= MAX_LEN_OF_MAC_TABLE)
+		return FALSE;
+
+	NdisAcquireSpinLock(&pAd->MacTabLock);
+
+	HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
+	//pEntry = pAd->MacTab.Hash[HashIdx];
+	pEntry = &pAd->MacTab.Content[wcid];
+
+	if (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsApCli || pEntry->ValidAsWDS || pEntry->ValidAsMesh
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+ 		|| pEntry->ValidAsDls
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+		))
+	{
+		if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
+		{
+
+			// Delete this entry from ASIC on-chip WCID Table
+			RT28XX_STA_ENTRY_MAC_RESET(pAd, wcid);
+
+#ifdef DOT11_N_SUPPORT
+			// free resources of BA
+			BASessionTearDownALL(pAd, pEntry->Aid);
+#endif // DOT11_N_SUPPORT //
+
+
+			pPrevEntry = NULL;
+			pProbeEntry = pAd->MacTab.Hash[HashIdx];
+			ASSERT(pProbeEntry);
+
+			// update Hash list
+			do
+			{
+				if (pProbeEntry == pEntry)
+				{
+					if (pPrevEntry == NULL)
+					{
+						pAd->MacTab.Hash[HashIdx] = pEntry->pNext;
+					}
+					else
+					{
+						pPrevEntry->pNext = pEntry->pNext;
+					}
+					break;
+				}
+
+				pPrevEntry = pProbeEntry;
+				pProbeEntry = pProbeEntry->pNext;
+			} while (pProbeEntry);
+
+			// not found !!!
+			ASSERT(pProbeEntry != NULL);
+
+			RT28XX_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid);
+
+
+		if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
+		{
+			RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
+			pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
+		}
+
+
+   			NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
+			pAd->MacTab.Size --;
+			DBGPRINT(RT_DEBUG_TRACE, ("MacTableDeleteEntry1 - Total= %d\n", pAd->MacTab.Size));
+		}
+		else
+		{
+			printk("\n%s: Impossible Wcid = %d !!!!!\n", __FUNCTION__, wcid);
+		}
+	}
+
+	NdisReleaseSpinLock(&pAd->MacTabLock);
+
+	//Reset operating mode when no Sta.
+	if (pAd->MacTab.Size == 0)
+	{
+#ifdef DOT11_N_SUPPORT
+		pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0;
+#endif // DOT11_N_SUPPORT //
+		//AsicUpdateProtect(pAd, 0 /*pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode*/, (ALLN_SETPROTECT), TRUE, 0 /*pAd->MacTab.fAnyStationNonGF*/);
+		RT28XX_UPDATE_PROTECT(pAd);  // edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
+	}
+
+	return TRUE;
+}
+
+
+/*
+	==========================================================================
+	Description:
+		This routine reset the entire MAC table. All packets pending in
+		the power-saving queues are freed here.
+	==========================================================================
+ */
+VOID MacTableReset(
+	IN  PRTMP_ADAPTER  pAd)
+{
+	int         i;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n"));
+	//NdisAcquireSpinLock(&pAd->MacTabLock);
+
+	for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
+	{
+		if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
+	   {
+
+#ifdef DOT11_N_SUPPORT
+			// free resources of BA
+			BASessionTearDownALL(pAd, i);
+#endif // DOT11_N_SUPPORT //
+
+			pAd->MacTab.Content[i].ValidAsCLI = FALSE;
+
+
+
+#ifdef RT2870
+			NdisZeroMemory(pAd->MacTab.Content[i].Addr, 6);
+			RT28XX_STA_ENTRY_MAC_RESET(pAd, i);
+#endif // RT2870 //
+
+			//AsicDelWcidTab(pAd, i);
+		}
+	}
+
+	return;
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+*/
+VOID AssocParmFill(
+	IN PRTMP_ADAPTER pAd,
+	IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq,
+	IN PUCHAR                     pAddr,
+	IN USHORT                     CapabilityInfo,
+	IN ULONG                      Timeout,
+	IN USHORT                     ListenIntv)
+{
+	COPY_MAC_ADDR(AssocReq->Addr, pAddr);
+	// Add mask to support 802.11b mode only
+	AssocReq->CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; // not cf-pollable, not cf-poll-request
+	AssocReq->Timeout = Timeout;
+	AssocReq->ListenIntv = ListenIntv;
+}
+
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+*/
+VOID DisassocParmFill(
+	IN PRTMP_ADAPTER pAd,
+	IN OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq,
+	IN PUCHAR pAddr,
+	IN USHORT Reason)
+{
+	COPY_MAC_ADDR(DisassocReq->Addr, pAddr);
+	DisassocReq->Reason = Reason;
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Check the out going frame, if this is an DHCP or ARP datagram
+	will be duplicate another frame at low data rate transmit.
+
+	Arguments:
+		pAd 		Pointer to our adapter
+		pPacket 	Pointer to outgoing Ndis frame
+
+	Return Value:
+		TRUE		To be duplicate at Low data rate transmit. (1mb)
+		FALSE		Do nothing.
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+		MAC header + IP Header + UDP Header
+		  14 Bytes	  20 Bytes
+
+		UDP Header
+		00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|
+						Source Port
+		16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|
+					Destination Port
+
+		port 0x43 means Bootstrap Protocol, server.
+		Port 0x44 means Bootstrap Protocol, client.
+
+	========================================================================
+*/
+
+BOOLEAN RTMPCheckDHCPFrame(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PNDIS_PACKET	pPacket)
+{
+	PACKET_INFO 	PacketInfo;
+	ULONG			NumberOfBytesRead = 0;
+	ULONG			CurrentOffset = 0;
+	PVOID			pVirtualAddress = NULL;
+	UINT			NdisBufferLength;
+	PUCHAR			pSrc;
+	USHORT			Protocol;
+	UCHAR			ByteOffset36 = 0;
+	UCHAR			ByteOffset38 = 0;
+	BOOLEAN 		ReadFirstParm = TRUE;
+
+	RTMP_QueryPacketInfo(pPacket, &PacketInfo, (PUCHAR *)&pVirtualAddress, &NdisBufferLength);
+
+	NumberOfBytesRead += NdisBufferLength;
+	pSrc = (PUCHAR) pVirtualAddress;
+	Protocol = *(pSrc + 12) * 256 + *(pSrc + 13);
+
+	//
+	// Check DHCP & BOOTP protocol
+	//
+	while (NumberOfBytesRead <= PacketInfo.TotalPacketLength)
+	{
+		if ((NumberOfBytesRead >= 35) && (ReadFirstParm == TRUE))
+		{
+			CurrentOffset = 35 - (NumberOfBytesRead - NdisBufferLength);
+			ByteOffset36 = *(pSrc + CurrentOffset);
+			ReadFirstParm = FALSE;
+		}
+
+		if (NumberOfBytesRead >= 37)
+		{
+			CurrentOffset = 37 - (NumberOfBytesRead - NdisBufferLength);
+			ByteOffset38 = *(pSrc + CurrentOffset);
+			//End of Read
+			break;
+		}
+		return FALSE;
+	}
+
+	// Check for DHCP & BOOTP protocol
+	if ((ByteOffset36 != 0x44) || (ByteOffset38 != 0x43))
+		{
+		//
+		// 2054 (hex 0806) for ARP datagrams
+		// if this packet is not ARP datagrams, then do nothing
+		// ARP datagrams will also be duplicate at 1mb broadcast frames
+		//
+		if (Protocol != 0x0806 )
+			return FALSE;
+		}
+
+	return TRUE;
+}
+
+
+BOOLEAN RTMPCheckEtherType(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PNDIS_PACKET	pPacket)
+{
+	USHORT	TypeLen;
+	UCHAR	Byte0, Byte1;
+	PUCHAR	pSrcBuf;
+	UINT32	pktLen;
+	UINT16 	srcPort, dstPort;
+	BOOLEAN	status = TRUE;
+
+
+	pSrcBuf = GET_OS_PKT_DATAPTR(pPacket);
+	pktLen = GET_OS_PKT_LEN(pPacket);
+
+	ASSERT(pSrcBuf);
+
+	RTMP_SET_PACKET_SPECIFIC(pPacket, 0);
+
+	// get Ethernet protocol field
+	TypeLen = (pSrcBuf[12] << 8) + pSrcBuf[13];
+
+	pSrcBuf += LENGTH_802_3;	// Skip the Ethernet Header.
+
+	if (TypeLen <= 1500)
+	{	// 802.3, 802.3 LLC
+		/*
+			DestMAC(6) + SrcMAC(6) + Lenght(2) +
+			DSAP(1) + SSAP(1) + Control(1) +
+			if the DSAP = 0xAA, SSAP=0xAA, Contorl = 0x03, it has a 5-bytes SNAP header.
+				=> + SNAP (5, OriginationID(3) + etherType(2))
+		*/
+		if (pSrcBuf[0] == 0xAA && pSrcBuf[1] == 0xAA && pSrcBuf[2] == 0x03)
+		{
+			Sniff2BytesFromNdisBuffer(pSrcBuf, 6, &Byte0, &Byte1);
+			RTMP_SET_PACKET_LLCSNAP(pPacket, 1);
+			TypeLen = (USHORT)((Byte0 << 8) + Byte1);
+			pSrcBuf += 8; // Skip this LLC/SNAP header
+		}
+		else
+		{
+			//It just has 3-byte LLC header, maybe a legacy ether type frame. we didn't handle it.
+		}
+	}
+
+	// If it's a VLAN packet, get the real Type/Length field.
+	if (TypeLen == 0x8100)
+	{
+		/* 0x8100 means VLAN packets */
+
+		/* Dest. MAC Address (6-bytes) +
+		   Source MAC Address (6-bytes) +
+		   Length/Type = 802.1Q Tag Type (2-byte) +
+		   Tag Control Information (2-bytes) +
+		   Length / Type (2-bytes) +
+		   data payload (0-n bytes) +
+		   Pad (0-p bytes) +
+		   Frame Check Sequence (4-bytes) */
+
+		RTMP_SET_PACKET_VLAN(pPacket, 1);
+		Sniff2BytesFromNdisBuffer(pSrcBuf, 2, &Byte0, &Byte1);
+		TypeLen = (USHORT)((Byte0 << 8) + Byte1);
+
+		pSrcBuf += 4; // Skip the VLAN Header.
+	}
+
+	switch (TypeLen)
+	{
+		case 0x0800:
+			{
+				ASSERT((pktLen > 34));
+				if (*(pSrcBuf + 9) == 0x11)
+				{	// udp packet
+					ASSERT((pktLen > 34));	// 14 for ethernet header, 20 for IP header
+
+					pSrcBuf += 20;	// Skip the IP header
+					srcPort = OS_NTOHS(*((UINT16 *)pSrcBuf));
+					dstPort = OS_NTOHS(*((UINT16 *)(pSrcBuf +2)));
+
+					if ((srcPort==0x44 && dstPort==0x43) || (srcPort==0x43 && dstPort==0x44))
+					{	//It's a BOOTP/DHCP packet
+						RTMP_SET_PACKET_DHCP(pPacket, 1);
+					}
+				}
+			}
+			break;
+		case 0x0806:
+			{
+				//ARP Packet.
+				RTMP_SET_PACKET_DHCP(pPacket, 1);
+			}
+			break;
+		case 0x888e:
+			{
+				// EAPOL Packet.
+				RTMP_SET_PACKET_EAPOL(pPacket, 1);
+			}
+			break;
+		default:
+			status = FALSE;
+			break;
+	}
+
+	return status;
+
+}
+
+
+
+VOID Update_Rssi_Sample(
+	IN PRTMP_ADAPTER	pAd,
+	IN RSSI_SAMPLE		*pRssi,
+	IN PRXWI_STRUC		pRxWI)
+		{
+	CHAR	rssi0 = pRxWI->RSSI0;
+	CHAR	rssi1 = pRxWI->RSSI1;
+	CHAR	rssi2 = pRxWI->RSSI2;
+
+	if (rssi0 != 0)
+	{
+		pRssi->LastRssi0	= ConvertToRssi(pAd, (CHAR)rssi0, RSSI_0);
+		pRssi->AvgRssi0X8	= (pRssi->AvgRssi0X8 - pRssi->AvgRssi0) + pRssi->LastRssi0;
+		pRssi->AvgRssi0	= pRssi->AvgRssi0X8 >> 3;
+	}
+
+	if (rssi1 != 0)
+	{
+		pRssi->LastRssi1	= ConvertToRssi(pAd, (CHAR)rssi1, RSSI_1);
+		pRssi->AvgRssi1X8	= (pRssi->AvgRssi1X8 - pRssi->AvgRssi1) + pRssi->LastRssi1;
+		pRssi->AvgRssi1	= pRssi->AvgRssi1X8 >> 3;
+	}
+
+	if (rssi2 != 0)
+	{
+		pRssi->LastRssi2	= ConvertToRssi(pAd, (CHAR)rssi2, RSSI_2);
+		pRssi->AvgRssi2X8  = (pRssi->AvgRssi2X8 - pRssi->AvgRssi2) + pRssi->LastRssi2;
+		pRssi->AvgRssi2 = pRssi->AvgRssi2X8 >> 3;
+	}
+}
+
+
+
+// Normal legacy Rx packet indication
+VOID Indicate_Legacy_Packet(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	RX_BLK			*pRxBlk,
+	IN	UCHAR			FromWhichBSSID)
+{
+	PNDIS_PACKET	pRxPacket = pRxBlk->pRxPacket;
+	UCHAR			Header802_3[LENGTH_802_3];
+
+	// 1. get 802.3 Header
+	// 2. remove LLC
+	// 		a. pointer pRxBlk->pData to payload
+	//      b. modify pRxBlk->DataSize
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
+#endif // CONFIG_STA_SUPPORT //
+
+	if (pRxBlk->DataSize > MAX_RX_PKT_LEN)
+	{
+		// release packet
+		RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+		return;
+	}
+
+
+	STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
+
+#ifdef RT2870
+#ifdef DOT11_N_SUPPORT
+	if (pAd->CommonCfg.bDisableReordering == 0)
+	{
+		PBA_REC_ENTRY		pBAEntry;
+		ULONG				Now32;
+		UCHAR				Wcid = pRxBlk->pRxWI->WirelessCliID;
+		UCHAR				TID = pRxBlk->pRxWI->TID;
+		USHORT				Idx;
+
+#define REORDERING_PACKET_TIMEOUT		((100 * HZ)/1000)	// system ticks -- 100 ms
+
+		if (Wcid < MAX_LEN_OF_MAC_TABLE)
+		{
+			Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
+			if (Idx != 0)
+			{
+				pBAEntry = &pAd->BATable.BARecEntry[Idx];
+				// update last rx time
+				NdisGetSystemUpTime(&Now32);
+				if ((pBAEntry->list.qlen > 0) &&
+					 RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT)))
+	   				)
+				{
+					printk("Indicate_Legacy_Packet():flush reordering_timeout_mpdus! RxWI->Flags=%d, pRxWI.TID=%d, RxD->AMPDU=%d!\n", pRxBlk->Flags, pRxBlk->pRxWI->TID, pRxBlk->RxD.AMPDU);
+					hex_dump("Dump the legacy Packet:", GET_OS_PKT_DATAPTR(pRxBlk->pRxPacket), 64);
+					ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
+				}
+			}
+		}
+	}
+#endif // DOT11_N_SUPPORT //
+#endif // RT2870 //
+
+	wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
+
+	//
+	// pass this 802.3 packet to upper layer or forward this packet to WM directly
+	//
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxPacket, FromWhichBSSID);
+#endif // CONFIG_STA_SUPPORT //
+
+}
+
+
+// Normal, AMPDU or AMSDU
+VOID CmmRxnonRalinkFrameIndicate(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	RX_BLK			*pRxBlk,
+	IN	UCHAR			FromWhichBSSID)
+{
+#ifdef DOT11_N_SUPPORT
+	if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0))
+	{
+		Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
+	}
+	else
+#endif // DOT11_N_SUPPORT //
+	{
+#ifdef DOT11_N_SUPPORT
+		if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
+		{
+			// handle A-MSDU
+			Indicate_AMSDU_Packet(pAd, pRxBlk, FromWhichBSSID);
+		}
+		else
+#endif // DOT11_N_SUPPORT //
+		{
+			Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
+		}
+	}
+}
+
+
+VOID CmmRxRalinkFrameIndicate(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	MAC_TABLE_ENTRY	*pEntry,
+	IN	RX_BLK			*pRxBlk,
+	IN	UCHAR			FromWhichBSSID)
+{
+	UCHAR			Header802_3[LENGTH_802_3];
+	UINT16			Msdu2Size;
+	UINT16 			Payload1Size, Payload2Size;
+	PUCHAR 			pData2;
+	PNDIS_PACKET	pPacket2 = NULL;
+
+
+
+	Msdu2Size = *(pRxBlk->pData) + (*(pRxBlk->pData+1) << 8);
+
+	if ((Msdu2Size <= 1536) && (Msdu2Size < pRxBlk->DataSize))
+	{
+		/* skip two byte MSDU2 len */
+		pRxBlk->pData += 2;
+		pRxBlk->DataSize -= 2;
+	}
+	else
+	{
+		// release packet
+		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+		return;
+	}
+
+	// get 802.3 Header and  remove LLC
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
+#endif // CONFIG_STA_SUPPORT //
+
+
+	ASSERT(pRxBlk->pRxPacket);
+
+	// Ralink Aggregation frame
+	pAd->RalinkCounters.OneSecRxAggregationCount ++;
+	Payload1Size = pRxBlk->DataSize - Msdu2Size;
+	Payload2Size = Msdu2Size - LENGTH_802_3;
+
+	pData2 = pRxBlk->pData + Payload1Size + LENGTH_802_3;
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		pPacket2 = duplicate_pkt(pAd, (pData2-LENGTH_802_3), LENGTH_802_3, pData2, Payload2Size, FromWhichBSSID);
+#endif // CONFIG_STA_SUPPORT //
+
+	if (!pPacket2)
+	{
+		// release packet
+		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+		return;
+	}
+
+	// update payload size of 1st packet
+	pRxBlk->DataSize = Payload1Size;
+	wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxBlk->pRxPacket, FromWhichBSSID);
+#endif // CONFIG_STA_SUPPORT //
+
+	if (pPacket2)
+	{
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+			ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket2, FromWhichBSSID);
+#endif // CONFIG_STA_SUPPORT //
+	}
+}
+
+
+#define RESET_FRAGFRAME(_fragFrame) \
+	{								\
+		_fragFrame.RxSize = 0;		\
+		_fragFrame.Sequence = 0;	\
+		_fragFrame.LastFrag = 0;	\
+		_fragFrame.Flags = 0;		\
+	}
+
+
+PNDIS_PACKET RTMPDeFragmentDataFrame(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	RX_BLK			*pRxBlk)
+{
+	PHEADER_802_11	pHeader = pRxBlk->pHeader;
+	PNDIS_PACKET	pRxPacket = pRxBlk->pRxPacket;
+	UCHAR			*pData = pRxBlk->pData;
+	USHORT			DataSize = pRxBlk->DataSize;
+	PNDIS_PACKET	pRetPacket = NULL;
+	UCHAR			*pFragBuffer = NULL;
+	BOOLEAN 		bReassDone = FALSE;
+	UCHAR			HeaderRoom = 0;
+
+
+	ASSERT(pHeader);
+
+	HeaderRoom = pData - (UCHAR *)pHeader;
+
+	// Re-assemble the fragmented packets
+	if (pHeader->Frag == 0)		// Frag. Number is 0 : First frag or only one pkt
+	{
+		// the first pkt of fragment, record it.
+		if (pHeader->FC.MoreFrag)
+		{
+			ASSERT(pAd->FragFrame.pFragPacket);
+			pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
+			pAd->FragFrame.RxSize   = DataSize + HeaderRoom;
+			NdisMoveMemory(pFragBuffer,	 pHeader, pAd->FragFrame.RxSize);
+			pAd->FragFrame.Sequence = pHeader->Sequence;
+			pAd->FragFrame.LastFrag = pHeader->Frag;	   // Should be 0
+			ASSERT(pAd->FragFrame.LastFrag == 0);
+			goto done;	// end of processing this frame
+		}
+	}
+	else	//Middle & End of fragment
+	{
+		if ((pHeader->Sequence != pAd->FragFrame.Sequence) ||
+			(pHeader->Frag != (pAd->FragFrame.LastFrag + 1)))
+		{
+			// Fragment is not the same sequence or out of fragment number order
+			// Reset Fragment control blk
+			RESET_FRAGFRAME(pAd->FragFrame);
+			DBGPRINT(RT_DEBUG_ERROR, ("Fragment is not the same sequence or out of fragment number order.\n"));
+			goto done; // give up this frame
+		}
+		else if ((pAd->FragFrame.RxSize + DataSize) > MAX_FRAME_SIZE)
+		{
+			// Fragment frame is too large, it exeeds the maximum frame size.
+			// Reset Fragment control blk
+			RESET_FRAGFRAME(pAd->FragFrame);
+			DBGPRINT(RT_DEBUG_ERROR, ("Fragment frame is too large, it exeeds the maximum frame size.\n"));
+			goto done; // give up this frame
+		}
+
+        //
+		// Broadcom AP(BCM94704AGR) will send out LLC in fragment's packet, LLC only can accpet at first fragment.
+		// In this case, we will dropt it.
+		//
+		if (NdisEqualMemory(pData, SNAP_802_1H, sizeof(SNAP_802_1H)))
+		{
+			DBGPRINT(RT_DEBUG_ERROR, ("Find another LLC at Middle or End fragment(SN=%d, Frag=%d)\n", pHeader->Sequence, pHeader->Frag));
+			goto done; // give up this frame
+		}
+
+		pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
+
+		// concatenate this fragment into the re-assembly buffer
+		NdisMoveMemory((pFragBuffer + pAd->FragFrame.RxSize), pData, DataSize);
+		pAd->FragFrame.RxSize  += DataSize;
+		pAd->FragFrame.LastFrag = pHeader->Frag;	   // Update fragment number
+
+		// Last fragment
+		if (pHeader->FC.MoreFrag == FALSE)
+		{
+			bReassDone = TRUE;
+		}
+	}
+
+done:
+	// always release rx fragmented packet
+	RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+
+	// return defragmented packet if packet is reassembled completely
+	// otherwise return NULL
+	if (bReassDone)
+	{
+		PNDIS_PACKET pNewFragPacket;
+
+		// allocate a new packet buffer for fragment
+		pNewFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
+		if (pNewFragPacket)
+		{
+			// update RxBlk
+			pRetPacket = pAd->FragFrame.pFragPacket;
+			pAd->FragFrame.pFragPacket = pNewFragPacket;
+			pRxBlk->pHeader = (PHEADER_802_11) GET_OS_PKT_DATAPTR(pRetPacket);
+			pRxBlk->pData = (UCHAR *)pRxBlk->pHeader + HeaderRoom;
+			pRxBlk->DataSize = pAd->FragFrame.RxSize - HeaderRoom;
+			pRxBlk->pRxPacket = pRetPacket;
+		}
+		else
+		{
+			RESET_FRAGFRAME(pAd->FragFrame);
+		}
+	}
+
+	return pRetPacket;
+}
+
+
+VOID Indicate_AMSDU_Packet(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	RX_BLK			*pRxBlk,
+	IN	UCHAR			FromWhichBSSID)
+{
+	UINT			nMSDU;
+
+	update_os_packet_info(pAd, pRxBlk, FromWhichBSSID);
+	RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
+	nMSDU = deaggregate_AMSDU_announce(pAd, pRxBlk->pRxPacket, pRxBlk->pData, pRxBlk->DataSize);
+}
+
+VOID Indicate_EAPOL_Packet(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	RX_BLK			*pRxBlk,
+	IN	UCHAR			FromWhichBSSID)
+{
+	MAC_TABLE_ENTRY *pEntry = NULL;
+
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		pEntry = &pAd->MacTab.Content[BSSID_WCID];
+		STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
+		return;
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	if (pEntry == NULL)
+	{
+		DBGPRINT(RT_DEBUG_WARN, ("Indicate_EAPOL_Packet: drop and release the invalid packet.\n"));
+		// release packet
+		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+		return;
+	}
+}
+
+#define BCN_TBTT_OFFSET		64	//defer 64 us
+VOID ReSyncBeaconTime(
+	IN  PRTMP_ADAPTER   pAd)
+{
+
+	UINT32  Offset;
+
+
+	Offset = (pAd->TbttTickCount) % (BCN_TBTT_OFFSET);
+
+	pAd->TbttTickCount++;
+
+	//
+	// The updated BeaconInterval Value will affect Beacon Interval after two TBTT
+	// beacasue the original BeaconInterval had been loaded into next TBTT_TIMER
+	//
+	if (Offset == (BCN_TBTT_OFFSET-2))
+	{
+		BCN_TIME_CFG_STRUC csr;
+		RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
+		csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod << 4) - 1 ;	// ASIC register in units of 1/16 TU = 64us
+		RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
+	}
+	else
+	{
+		if (Offset == (BCN_TBTT_OFFSET-1))
+		{
+			BCN_TIME_CFG_STRUC csr;
+
+			RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
+			csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod) << 4; // ASIC register in units of 1/16 TU
+			RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
+		}
+	}
+}
+
diff --git a/drivers/staging/rt3070/common/cmm_data_2870.c b/drivers/staging/rt3070/common/cmm_data_2870.c
new file mode 100644
index 0000000..b1066aa
--- /dev/null
+++ b/drivers/staging/rt3070/common/cmm_data_2870.c
@@ -0,0 +1,980 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+*/
+/*
+   All functions in this file must be USB-depended, or you should out your function
+	in other files.
+
+*/
+#include	"../rt_config.h"
+
+
+/*
+	We can do copy the frame into pTxContext when match following conditions.
+		=>
+		=>
+		=>
+*/
+static inline NDIS_STATUS RtmpUSBCanDoWrite(
+	IN RTMP_ADAPTER		*pAd,
+	IN UCHAR			QueIdx,
+	IN HT_TX_CONTEXT 	*pHTTXContext)
+{
+	NDIS_STATUS	canWrite = NDIS_STATUS_RESOURCES;
+
+	if (((pHTTXContext->CurWritePosition) < pHTTXContext->NextBulkOutPosition) && (pHTTXContext->CurWritePosition + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c1!\n"));
+		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
+	}
+	else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < LOCAL_TXBUF_SIZE))
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c2!\n"));
+		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
+	}
+	else if (pHTTXContext->bCurWriting == TRUE)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c3!\n"));
+	}
+	else
+	{
+		canWrite = NDIS_STATUS_SUCCESS;
+	}
+
+
+	return canWrite;
+}
+
+
+USHORT RtmpUSB_WriteSubTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	BOOLEAN			bIsLast,
+	OUT	USHORT			*FreeNumber)
+{
+
+	// Dummy function. Should be removed in the future.
+	return 0;
+
+}
+
+USHORT	RtmpUSB_WriteFragTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	UCHAR			fragNum,
+	OUT	USHORT			*FreeNumber)
+{
+	HT_TX_CONTEXT	*pHTTXContext;
+	USHORT			hwHdrLen;	// The hwHdrLen consist of 802.11 header length plus the header padding length.
+	UINT32			fillOffset;
+	TXINFO_STRUC	*pTxInfo;
+	TXWI_STRUC		*pTxWI;
+	PUCHAR			pWirelessPacket = NULL;
+	UCHAR			QueIdx;
+	NDIS_STATUS		Status;
+	unsigned long	IrqFlags;
+	UINT32			USBDMApktLen = 0, DMAHdrLen, padding;
+	BOOLEAN			TxQLastRound = FALSE;
+
+	//
+	// get Tx Ring Resource & Dma Buffer address
+	//
+	QueIdx = pTxBlk->QueIdx;
+	pHTTXContext  = &pAd->TxContext[QueIdx];
+
+	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+	pHTTXContext  = &pAd->TxContext[QueIdx];
+	fillOffset = pHTTXContext->CurWritePosition;
+
+	if(fragNum == 0)
+	{
+		// Check if we have enough space for this bulk-out batch.
+		Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
+		if (Status == NDIS_STATUS_SUCCESS)
+		{
+			pHTTXContext->bCurWriting = TRUE;
+
+			// Reserve space for 8 bytes padding.
+			if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
+			{
+				pHTTXContext->ENextBulkOutPosition += 8;
+				pHTTXContext->CurWritePosition += 8;
+				fillOffset += 8;
+			}
+			pTxBlk->Priv = 0;
+			pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+		}
+		else
+		{
+			RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+			return(Status);
+		}
+	}
+	else
+	{
+		// For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer.
+		Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
+		if (Status == NDIS_STATUS_SUCCESS)
+		{
+			fillOffset += pTxBlk->Priv;
+		}
+		else
+		{
+			RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+			return(Status);
+		}
+	}
+
+	NdisZeroMemory((PUCHAR)(&pTxBlk->HeaderBuf[0]), TXINFO_SIZE);
+	pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
+	pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
+
+	pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
+
+	// copy TXWI + WLAN Header + LLC into DMA Header Buffer
+	//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
+	hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+
+	// Build our URB for USBD
+	DMAHdrLen = TXWI_SIZE + hwHdrLen;
+	USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;
+	padding = (4 - (USBDMApktLen % 4)) & 0x03;	// round up to 4 byte alignment
+	USBDMApktLen += padding;
+
+	pTxBlk->Priv += (TXINFO_SIZE + USBDMApktLen);
+
+	// For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload
+	RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/,  FALSE);
+
+	if (fragNum == pTxBlk->TotalFragNum)
+	{
+		pTxInfo->USBDMATxburst = 0;
+		if ((pHTTXContext->CurWritePosition + pTxBlk->Priv + 3906)> MAX_TXBULK_LIMIT)
+		{
+			pTxInfo->SwUseLastRound = 1;
+			TxQLastRound = TRUE;
+		}
+	}
+	else
+	{
+		pTxInfo->USBDMATxburst = 1;
+	}
+
+	NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+#ifdef RT_BIG_ENDIAN
+	RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket + TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
+#endif // RT_BIG_ENDIAN //
+	pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+	pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+
+	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+	NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
+
+	//	Zero the last padding.
+	pWirelessPacket += pTxBlk->SrcBufLen;
+	NdisZeroMemory(pWirelessPacket, padding + 8);
+
+	if (fragNum == pTxBlk->TotalFragNum)
+	{
+		RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+		// Update the pHTTXContext->CurWritePosition. 3906 used to prevent the NextBulkOut is a A-RALINK/A-MSDU Frame.
+		pHTTXContext->CurWritePosition += pTxBlk->Priv;
+		if (TxQLastRound == TRUE)
+			pHTTXContext->CurWritePosition = 8;
+		pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+
+
+		// Finally, set bCurWriting as FALSE
+	pHTTXContext->bCurWriting = FALSE;
+
+		RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+		// succeed and release the skb buffer
+		RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
+	}
+
+
+	return(Status);
+
+}
+
+
+USHORT RtmpUSB_WriteSingleTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	BOOLEAN			bIsLast,
+	OUT	USHORT			*FreeNumber)
+{
+	HT_TX_CONTEXT	*pHTTXContext;
+	USHORT			hwHdrLen;
+	UINT32			fillOffset;
+	TXINFO_STRUC	*pTxInfo;
+	TXWI_STRUC		*pTxWI;
+	PUCHAR			pWirelessPacket;
+	UCHAR			QueIdx;
+	unsigned long	IrqFlags;
+	NDIS_STATUS		Status;
+	UINT32			USBDMApktLen = 0, DMAHdrLen, padding;
+	BOOLEAN			bTxQLastRound = FALSE;
+
+	// For USB, didn't need PCI_MAP_SINGLE()
+	//SrcBufPA = PCI_MAP_SINGLE(pAd, (char *) pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, PCI_DMA_TODEVICE);
+
+
+	//
+	// get Tx Ring Resource & Dma Buffer address
+	//
+	QueIdx = pTxBlk->QueIdx;
+
+	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+	pHTTXContext  = &pAd->TxContext[QueIdx];
+	fillOffset = pHTTXContext->CurWritePosition;
+
+
+
+	// Check ring full.
+	Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
+	if(Status == NDIS_STATUS_SUCCESS)
+	{
+		pHTTXContext->bCurWriting = TRUE;
+
+		pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
+		pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
+
+		// Reserve space for 8 bytes padding.
+		if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
+		{
+			pHTTXContext->ENextBulkOutPosition += 8;
+			pHTTXContext->CurWritePosition += 8;
+			fillOffset += 8;
+		}
+		pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+
+		pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
+
+		// copy TXWI + WLAN Header + LLC into DMA Header Buffer
+		//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
+		hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+
+		// Build our URB for USBD
+		DMAHdrLen = TXWI_SIZE + hwHdrLen;
+		USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;
+		padding = (4 - (USBDMApktLen % 4)) & 0x03;	// round up to 4 byte alignment
+		USBDMApktLen += padding;
+
+		pTxBlk->Priv = (TXINFO_SIZE + USBDMApktLen);
+
+		// For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload
+		//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/,  FALSE);
+#endif // CONFIG_STA_SUPPORT //
+
+		if ((pHTTXContext->CurWritePosition + 3906 + pTxBlk->Priv) > MAX_TXBULK_LIMIT)
+		{
+			pTxInfo->SwUseLastRound = 1;
+			bTxQLastRound = TRUE;
+		}
+		NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+#ifdef RT_BIG_ENDIAN
+		RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket + TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
+#endif // RT_BIG_ENDIAN //
+		pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+
+		// We unlock it here to prevent the first 8 bytes maybe over-writed issue.
+		//	1. First we got CurWritePosition but the first 8 bytes still not write to the pTxcontext.
+		//	2. An interrupt break our routine and handle bulk-out complete.
+		//	3. In the bulk-out compllete, it need to do another bulk-out,
+		//			if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition,
+		//			but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE.
+		//	4. Interrupt complete.
+		//  5. Our interrupted routine go back and fill the first 8 bytes to pTxContext.
+		//	6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition.
+		//		and the packet will wrong.
+		pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+		RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+		NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
+		pWirelessPacket += pTxBlk->SrcBufLen;
+		NdisZeroMemory(pWirelessPacket, padding + 8);
+
+		RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+		pHTTXContext->CurWritePosition += pTxBlk->Priv;
+		if (bTxQLastRound)
+			pHTTXContext->CurWritePosition = 8;
+		pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+
+	pHTTXContext->bCurWriting = FALSE;
+	}
+
+
+	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+
+	// succeed and release the skb buffer
+	RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
+
+	return(Status);
+
+}
+
+
+USHORT RtmpUSB_WriteMultiTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	UCHAR			frameNum,
+	OUT	USHORT			*FreeNumber)
+{
+	HT_TX_CONTEXT	*pHTTXContext;
+	USHORT			hwHdrLen;	// The hwHdrLen consist of 802.11 header length plus the header padding length.
+	UINT32			fillOffset;
+	TXINFO_STRUC	*pTxInfo;
+	TXWI_STRUC		*pTxWI;
+	PUCHAR			pWirelessPacket = NULL;
+	UCHAR			QueIdx;
+	NDIS_STATUS		Status;
+	unsigned long	IrqFlags;
+	//UINT32			USBDMApktLen = 0, DMAHdrLen, padding;
+
+	//
+	// get Tx Ring Resource & Dma Buffer address
+	//
+	QueIdx = pTxBlk->QueIdx;
+	pHTTXContext  = &pAd->TxContext[QueIdx];
+
+	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+	if(frameNum == 0)
+	{
+		// Check if we have enough space for this bulk-out batch.
+		Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
+		if (Status == NDIS_STATUS_SUCCESS)
+		{
+			pHTTXContext->bCurWriting = TRUE;
+
+			pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
+			pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
+
+
+			// Reserve space for 8 bytes padding.
+			if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
+			{
+
+				pHTTXContext->CurWritePosition += 8;
+				pHTTXContext->ENextBulkOutPosition += 8;
+			}
+			fillOffset = pHTTXContext->CurWritePosition;
+			pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+
+			pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
+
+			//
+			// Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
+			//
+			if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
+				//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD;
+				hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
+			else if (pTxBlk->TxFrameType == TX_RALINK_FRAME)
+				//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD;
+				hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen + LENGTH_ARALINK_HEADER_FIELD;
+			else
+				//hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
+				hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+
+			// Update the pTxBlk->Priv.
+			pTxBlk->Priv = TXINFO_SIZE + TXWI_SIZE + hwHdrLen;
+
+			//	pTxInfo->USBDMApktLen now just a temp value and will to correct latter.
+			RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(pTxBlk->Priv), FALSE, FIFO_EDCA, FALSE /*NextValid*/,  FALSE);
+
+			// Copy it.
+			NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->Priv);
+#ifdef RT_BIG_ENDIAN
+			RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket+ TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
+#endif // RT_BIG_ENDIAN //
+			pHTTXContext->CurWriteRealPos += pTxBlk->Priv;
+			pWirelessPacket += pTxBlk->Priv;
+		}
+	}
+	else
+	{	// For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer.
+
+		Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
+		if (Status == NDIS_STATUS_SUCCESS)
+		{
+			fillOffset =  (pHTTXContext->CurWritePosition + pTxBlk->Priv);
+			pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
+
+			//hwHdrLen = pTxBlk->MpduHeaderLen;
+			NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->MpduHeaderLen);
+			pWirelessPacket += (pTxBlk->MpduHeaderLen);
+			pTxBlk->Priv += pTxBlk->MpduHeaderLen;
+		}
+		else
+		{	// It should not happened now unless we are going to shutdown.
+			DBGPRINT(RT_DEBUG_ERROR, ("WriteMultiTxResource():bCurWriting is FALSE when handle sub-sequent frames.\n"));
+			Status = NDIS_STATUS_FAILURE;
+		}
+	}
+
+
+	// We unlock it here to prevent the first 8 bytes maybe over-write issue.
+	//	1. First we got CurWritePosition but the first 8 bytes still not write to the pTxContext.
+	//	2. An interrupt break our routine and handle bulk-out complete.
+	//	3. In the bulk-out compllete, it need to do another bulk-out,
+	//			if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition,
+	//			but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE.
+	//	4. Interrupt complete.
+	//  5. Our interrupted routine go back and fill the first 8 bytes to pTxContext.
+	//	6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition.
+	//		and the packet will wrong.
+	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+	if (Status != NDIS_STATUS_SUCCESS)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("WriteMultiTxResource: CWPos = %ld, NBOutPos = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition));
+		goto done;
+	}
+
+	// Copy the frame content into DMA buffer and update the pTxBlk->Priv
+	NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
+	pWirelessPacket += pTxBlk->SrcBufLen;
+	pTxBlk->Priv += pTxBlk->SrcBufLen;
+
+done:
+	// Release the skb buffer here
+	RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
+
+	return(Status);
+
+}
+
+
+VOID RtmpUSB_FinalWriteTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	USHORT			totalMPDUSize,
+	IN	USHORT			TxIdx)
+{
+	UCHAR			QueIdx;
+	HT_TX_CONTEXT	*pHTTXContext;
+	UINT32			fillOffset;
+	TXINFO_STRUC	*pTxInfo;
+	TXWI_STRUC		*pTxWI;
+	UINT32			USBDMApktLen, padding;
+	unsigned long	IrqFlags;
+	PUCHAR			pWirelessPacket;
+
+	QueIdx = pTxBlk->QueIdx;
+	pHTTXContext  = &pAd->TxContext[QueIdx];
+
+	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+	if (pHTTXContext->bCurWriting == TRUE)
+	{
+		fillOffset = pHTTXContext->CurWritePosition;
+		if (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition))
+			&& (pHTTXContext->bCopySavePad == TRUE))
+			pWirelessPacket = (PUCHAR)(&pHTTXContext->SavedPad[0]);
+		else
+			pWirelessPacket = (PUCHAR)(&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]);
+
+		//
+		// Update TxInfo->USBDMApktLen ,
+		//		the length = TXWI_SIZE + 802.11_hdr + 802.11_hdr_pad + payload_of_all_batch_frames + Bulk-Out-padding
+		//
+		pTxInfo = (PTXINFO_STRUC)(pWirelessPacket);
+
+		// Calculate the bulk-out padding
+		USBDMApktLen = pTxBlk->Priv - TXINFO_SIZE;
+		padding = (4 - (USBDMApktLen % 4)) & 0x03;	// round up to 4 byte alignment
+		USBDMApktLen += padding;
+
+		pTxInfo->USBDMATxPktLen = USBDMApktLen;
+
+		//
+		// Update TXWI->MPDUtotalByteCount ,
+		//		the length = 802.11 header + payload_of_all_batch_frames
+		pTxWI= (PTXWI_STRUC)(pWirelessPacket + TXINFO_SIZE);
+		pTxWI->MPDUtotalByteCount = totalMPDUSize;
+
+		//
+		// Update the pHTTXContext->CurWritePosition
+		//
+		pHTTXContext->CurWritePosition += (TXINFO_SIZE + USBDMApktLen);
+		if ((pHTTXContext->CurWritePosition + 3906)> MAX_TXBULK_LIMIT)
+		{	// Add 3906 for prevent the NextBulkOut packet size is a A-RALINK/A-MSDU Frame.
+			pHTTXContext->CurWritePosition = 8;
+			pTxInfo->SwUseLastRound = 1;
+		}
+		pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+
+
+		//
+		//	Zero the last padding.
+		//
+		pWirelessPacket = (&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset + pTxBlk->Priv]);
+		NdisZeroMemory(pWirelessPacket, padding + 8);
+
+		// Finally, set bCurWriting as FALSE
+		pHTTXContext->bCurWriting = FALSE;
+
+	}
+	else
+	{	// It should not happened now unless we are going to shutdown.
+		DBGPRINT(RT_DEBUG_ERROR, ("FinalWriteTxResource():bCurWriting is FALSE when handle last frames.\n"));
+	}
+
+	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+}
+
+
+VOID RtmpUSBDataLastTxIdx(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			QueIdx,
+	IN	USHORT			TxIdx)
+{
+	// DO nothing for USB.
+}
+
+
+/*
+	When can do bulk-out:
+		1. TxSwFreeIdx < TX_RING_SIZE;
+			It means has at least one Ring entity is ready for bulk-out, kick it out.
+		2. If TxSwFreeIdx == TX_RING_SIZE
+			Check if the CurWriting flag is FALSE, if it's FALSE, we can do kick out.
+
+*/
+VOID RtmpUSBDataKickOut(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	UCHAR			QueIdx)
+{
+	RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
+	RTUSBKickBulkOut(pAd);
+
+}
+
+
+/*
+	Must be run in Interrupt context
+	This function handle RT2870 specific TxDesc and cpu index update and kick the packet out.
+ */
+int RtmpUSBMgmtKickOut(
+	IN RTMP_ADAPTER 	*pAd,
+	IN UCHAR 			QueIdx,
+	IN PNDIS_PACKET		pPacket,
+	IN PUCHAR			pSrcBufVA,
+	IN UINT 			SrcBufLen)
+{
+	PTXINFO_STRUC	pTxInfo;
+	ULONG			BulkOutSize;
+	UCHAR			padLen;
+	PUCHAR			pDest;
+	ULONG			SwIdx = pAd->MgmtRing.TxCpuIdx;
+	PTX_CONTEXT		pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[SwIdx].AllocVa;
+	unsigned long	IrqFlags;
+
+
+	pTxInfo = (PTXINFO_STRUC)(pSrcBufVA);
+
+	// Build our URB for USBD
+	BulkOutSize = SrcBufLen;
+	BulkOutSize = (BulkOutSize + 3) & (~3);
+	RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(BulkOutSize - TXINFO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE,  FALSE);
+
+	BulkOutSize += 4; // Always add 4 extra bytes at every packet.
+
+	// If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again.
+	if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0)
+		BulkOutSize += 4;
+
+	padLen = BulkOutSize - SrcBufLen;
+	ASSERT((padLen <= RTMP_PKT_TAIL_PADDING));
+
+	// Now memzero all extra padding bytes.
+	pDest = (PUCHAR)(pSrcBufVA + SrcBufLen);
+	skb_put(GET_OS_PKT_TYPE(pPacket), padLen);
+	NdisZeroMemory(pDest, padLen);
+
+	RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
+
+	pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket;
+	pMLMEContext->TransferBuffer = (PTX_BUFFER)(GET_OS_PKT_DATAPTR(pPacket));
+
+	// Length in TxInfo should be 8 less than bulkout size.
+	pMLMEContext->BulkOutSize = BulkOutSize;
+	pMLMEContext->InUse = TRUE;
+	pMLMEContext->bWaitingBulkOut = TRUE;
+
+
+	//for debug
+	//hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize));
+
+	//pAd->RalinkCounters.KickTxCount++;
+	//pAd->RalinkCounters.OneSecTxDoneCount++;
+
+	//if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE)
+	//	needKickOut = TRUE;
+
+	// Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX
+	pAd->MgmtRing.TxSwFreeIdx--;
+	INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
+
+	RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
+
+	RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
+	//if (needKickOut)
+	RTUSBKickBulkOut(pAd);
+
+	return 0;
+}
+
+
+VOID RtmpUSBNullFrameKickOut(
+	IN RTMP_ADAPTER *pAd,
+	IN UCHAR		QueIdx,
+	IN UCHAR		*pNullFrame,
+	IN UINT32		frameLen)
+{
+	if (pAd->NullContext.InUse == FALSE)
+	{
+		PTX_CONTEXT		pNullContext;
+		PTXINFO_STRUC	pTxInfo;
+		PTXWI_STRUC		pTxWI;
+		PUCHAR			pWirelessPkt;
+
+		pNullContext = &(pAd->NullContext);
+
+		// Set the in use bit
+		pNullContext->InUse = TRUE;
+		pWirelessPkt = (PUCHAR)&pNullContext->TransferBuffer->field.WirelessPacket[0];
+
+		RTMPZeroMemory(&pWirelessPkt[0], 100);
+		pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[0];
+		RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE,  FALSE);
+		pTxInfo->QSEL = FIFO_EDCA;
+		pTxWI = (PTXWI_STRUC)&pWirelessPkt[TXINFO_SIZE];
+		RTMPWriteTxWI(pAd, pTxWI,  FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
+			0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
+#ifdef RT_BIG_ENDIAN
+		RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
+#endif // RT_BIG_ENDIAN //
+
+		RTMPMoveMemory(&pWirelessPkt[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
+#ifdef RT_BIG_ENDIAN
+		RTMPFrameEndianChange(pAd, (PUCHAR)&pWirelessPkt[TXINFO_SIZE + TXWI_SIZE], DIR_WRITE, FALSE);
+#endif // RT_BIG_ENDIAN //
+		pAd->NullContext.BulkOutSize =  TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
+
+		// Fill out frame length information for global Bulk out arbitor
+		//pNullContext->BulkOutSize = TransferBufferLength;
+		DBGPRINT(RT_DEBUG_TRACE, ("SYNC - send NULL Frame @%d Mbps...\n", RateIdToMbps[pAd->CommonCfg.TxRate]));
+		RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
+
+		// Kick bulk out
+		RTUSBKickBulkOut(pAd);
+	}
+
+}
+
+#ifdef CONFIG_STA_SUPPORT
+/*
+	========================================================================
+
+	Routine	Description:
+		Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
+
+	Arguments:
+		pRxD		Pointer	to the Rx descriptor
+
+	Return Value:
+		NDIS_STATUS_SUCCESS		No err
+		NDIS_STATUS_FAILURE		Error
+
+	Note:
+
+	========================================================================
+*/
+NDIS_STATUS	RTMPCheckRxError(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PHEADER_802_11	pHeader,
+	IN	PRXWI_STRUC	pRxWI,
+	IN	PRT28XX_RXD_STRUC	pRxINFO)
+{
+	PCIPHER_KEY pWpaKey;
+	INT	dBm;
+
+	if (pAd->bPromiscuous == TRUE)
+		return(NDIS_STATUS_SUCCESS);
+	if(pRxINFO == NULL)
+		return(NDIS_STATUS_FAILURE);
+
+	// Phy errors & CRC errors
+	if (pRxINFO->Crc)
+	{
+		// Check RSSI for Noise Hist statistic collection.
+		dBm = (INT) (pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta;
+		if (dBm <= -87)
+			pAd->StaCfg.RPIDensity[0] += 1;
+		else if (dBm <= -82)
+			pAd->StaCfg.RPIDensity[1] += 1;
+		else if (dBm <= -77)
+			pAd->StaCfg.RPIDensity[2] += 1;
+		else if (dBm <= -72)
+			pAd->StaCfg.RPIDensity[3] += 1;
+		else if (dBm <= -67)
+			pAd->StaCfg.RPIDensity[4] += 1;
+		else if (dBm <= -62)
+			pAd->StaCfg.RPIDensity[5] += 1;
+		else if (dBm <= -57)
+			pAd->StaCfg.RPIDensity[6] += 1;
+		else if (dBm > -57)
+			pAd->StaCfg.RPIDensity[7] += 1;
+
+		return(NDIS_STATUS_FAILURE);
+	}
+
+	// Add Rx size to channel load counter, we should ignore error counts
+	pAd->StaCfg.CLBusyBytes += (pRxWI->MPDUtotalByteCount+ 14);
+
+	// Drop ToDs promiscous frame, it is opened due to CCX 2 channel load statistics
+	if (pHeader->FC.ToDs)
+	{
+		DBGPRINT_RAW(RT_DEBUG_ERROR, ("Err;FC.ToDs\n"));
+		return NDIS_STATUS_FAILURE;
+	}
+
+	// Paul 04-03 for OFDM Rx length issue
+	if (pRxWI->MPDUtotalByteCount > MAX_AGGREGATION_SIZE)
+	{
+		DBGPRINT_RAW(RT_DEBUG_ERROR, ("received packet too long\n"));
+		return NDIS_STATUS_FAILURE;
+	}
+
+	// Drop not U2M frames, cant's drop here because we will drop beacon in this case
+	// I am kind of doubting the U2M bit operation
+	// if (pRxD->U2M == 0)
+	//	return(NDIS_STATUS_FAILURE);
+
+	// drop decyption fail frame
+	if (pRxINFO->Decrypted && pRxINFO->CipherErr)
+	{
+
+		//
+		// MIC Error
+		//
+		if ((pRxINFO->CipherErr == 2) && pRxINFO->MyBss)
+		{
+			pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex];
+			RTMPReportMicError(pAd, pWpaKey);
+			DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error\n"));
+		}
+
+		if (pRxINFO->Decrypted &&
+			(pAd->SharedKey[BSS0][pRxWI->KeyIndex].CipherAlg == CIPHER_AES) &&
+			(pHeader->Sequence == pAd->FragFrame.Sequence))
+		{
+			//
+			// Acceptable since the First FragFrame no CipherErr problem.
+			//
+			return(NDIS_STATUS_SUCCESS);
+		}
+
+		return(NDIS_STATUS_FAILURE);
+	}
+
+	return(NDIS_STATUS_SUCCESS);
+}
+
+VOID RT28xxUsbStaAsicForceWakeup(
+	IN PRTMP_ADAPTER pAd,
+	IN BOOLEAN       bFromTx)
+{
+    AUTO_WAKEUP_STRUC	AutoWakeupCfg;
+
+	AutoWakeupCfg.word = 0;
+	RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+
+	AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
+
+	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
+}
+
+VOID RT28xxUsbStaAsicSleepThenAutoWakeup(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT TbttNumToNextWakeUp)
+{
+	AUTO_WAKEUP_STRUC	AutoWakeupCfg;
+
+	// we have decided to SLEEP, so at least do it for a BEACON period.
+	if (TbttNumToNextWakeUp == 0)
+		TbttNumToNextWakeUp = 1;
+
+	AutoWakeupCfg.word = 0;
+	RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+
+	AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1;
+	AutoWakeupCfg.field.EnableAutoWakeup = 1;
+	AutoWakeupCfg.field.AutoLeadTime = 5;
+	RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+
+	AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);   // send POWER-SAVE command to MCU. Timeout 40us.
+
+	OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
+
+}
+#endif // CONFIG_STA_SUPPORT //
+
+VOID RT28xxUsbMlmeRadioOn(
+	IN PRTMP_ADAPTER pAd)
+{
+    DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOn()\n"));
+
+	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
+		return;
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+    	AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
+		RTMPusecDelay(10000);
+	}
+#endif // CONFIG_STA_SUPPORT //
+	NICResetFromError(pAd);
+
+	// Enable Tx/Rx
+	RTMPEnableRxTx(pAd);
+
+#ifdef RT3070
+	if (IS_RT3071(pAd))
+	{
+		RT30xxReverseRFSleepModeSetup(pAd);
+	}
+#endif // RT3070 //
+
+	// Clear Radio off flag
+	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		RTUSBBulkReceive(pAd);
+#endif // CONFIG_STA_SUPPORT //
+
+	// Set LED
+	RTMPSetLED(pAd, LED_RADIO_ON);
+}
+
+VOID RT28xxUsbMlmeRadioOFF(
+	IN PRTMP_ADAPTER pAd)
+{
+	WPDMA_GLO_CFG_STRUC	GloCfg;
+	UINT32	Value, i;
+
+	DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOFF()\n"));
+
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
+		return;
+
+	// Set LED
+	RTMPSetLED(pAd, LED_RADIO_OFF);
+	// Set Radio off flag
+	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		// Link down first if any association exists
+		if (INFRA_ON(pAd) || ADHOC_ON(pAd))
+			LinkDown(pAd, FALSE);
+		RTMPusecDelay(10000);
+
+		//==========================================
+		// Clean up old bss table
+		BssTableInit(&pAd->ScanTab);
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+
+	if (pAd->CommonCfg.BBPCurrentBW == BW_40)
+	{
+		// Must using 40MHz.
+		AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
+	}
+	else
+	{
+		// Must using 20MHz.
+		AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
+	}
+
+	// Disable Tx/Rx DMA
+	RTUSBReadMACRegister(pAd, WPDMA_GLO_CFG, &GloCfg.word);	   // disable DMA
+	GloCfg.field.EnableTxDMA = 0;
+	GloCfg.field.EnableRxDMA = 0;
+	RTUSBWriteMACRegister(pAd, WPDMA_GLO_CFG, GloCfg.word);	   // abort all TX rings
+
+	// Waiting for DMA idle
+	i = 0;
+	do
+	{
+		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
+		if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
+			break;
+
+		RTMPusecDelay(1000);
+	}while (i++ < 100);
+
+	// Disable MAC Tx/Rx
+	RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+	Value &= (0xfffffff3);
+	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+	// MAC_SYS_CTRL => value = 0x0 => 40mA
+	//RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0);
+
+	// PWR_PIN_CFG => value = 0x0 => 40mA
+	//RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0);
+
+	// TX_PIN_CFG => value = 0x0 => 20mA
+	//RTMP_IO_WRITE32(pAd, TX_PIN_CFG, 0);
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
+#endif // CONFIG_STA_SUPPORT //
+}
+
diff --git a/drivers/staging/rt3070/common/cmm_info.c b/drivers/staging/rt3070/common/cmm_info.c
new file mode 100644
index 0000000..54cb1a3
--- /dev/null
+++ b/drivers/staging/rt3070/common/cmm_info.c
@@ -0,0 +1,3395 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+*/
+
+#include	"../rt_config.h"
+
+INT	Show_SSID_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+INT	Show_WirelessMode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+INT	Show_TxBurst_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+INT	Show_TxPreamble_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+INT	Show_TxPower_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+INT	Show_Channel_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+INT	Show_BGProtection_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+INT	Show_RTSThreshold_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+INT	Show_FragThreshold_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+#ifdef DOT11_N_SUPPORT
+INT	Show_HtBw_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+INT	Show_HtMcs_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+INT	Show_HtGi_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+INT	Show_HtOpMode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+INT	Show_HtExtcha_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+INT	Show_HtMpduDensity_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+INT	Show_HtBaWinSize_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+INT	Show_HtRdg_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+INT	Show_HtAmsdu_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+INT	Show_HtAutoBa_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+#endif // DOT11_N_SUPPORT //
+
+INT	Show_CountryRegion_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+INT	Show_CountryRegionABand_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+INT	Show_CountryCode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+#ifdef AGGREGATION_SUPPORT
+INT	Show_PktAggregate_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+#endif // AGGREGATION_SUPPORT //
+
+#ifdef WMM_SUPPORT
+INT	Show_WmmCapable_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+#endif // WMM_SUPPORT //
+
+INT	Show_IEEE80211H_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+#ifdef CONFIG_STA_SUPPORT
+INT	Show_NetworkType_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+#endif // CONFIG_STA_SUPPORT //
+
+INT	Show_AuthMode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+INT	Show_EncrypType_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+INT	Show_DefaultKeyID_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+INT	Show_Key1_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+INT	Show_Key2_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+INT	Show_Key3_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+INT	Show_Key4_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+INT	Show_WPAPSK_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf);
+
+static struct {
+	CHAR *name;
+	INT (*show_proc)(PRTMP_ADAPTER pAdapter, PUCHAR arg);
+} *PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC, RTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC[] = {
+	{"SSID",					Show_SSID_Proc},
+	{"WirelessMode",			Show_WirelessMode_Proc},
+	{"TxBurst",					Show_TxBurst_Proc},
+	{"TxPreamble",				Show_TxPreamble_Proc},
+	{"TxPower",					Show_TxPower_Proc},
+	{"Channel",					Show_Channel_Proc},
+	{"BGProtection",			Show_BGProtection_Proc},
+	{"RTSThreshold",			Show_RTSThreshold_Proc},
+	{"FragThreshold",			Show_FragThreshold_Proc},
+#ifdef DOT11_N_SUPPORT
+	{"HtBw",					Show_HtBw_Proc},
+	{"HtMcs",					Show_HtMcs_Proc},
+	{"HtGi",					Show_HtGi_Proc},
+	{"HtOpMode",				Show_HtOpMode_Proc},
+	{"HtExtcha",				Show_HtExtcha_Proc},
+	{"HtMpduDensity",			Show_HtMpduDensity_Proc},
+	{"HtBaWinSize",		        Show_HtBaWinSize_Proc},
+	{"HtRdg",		        	Show_HtRdg_Proc},
+	{"HtAmsdu",		        	Show_HtAmsdu_Proc},
+	{"HtAutoBa",		        Show_HtAutoBa_Proc},
+#endif // DOT11_N_SUPPORT //
+	{"CountryRegion",			Show_CountryRegion_Proc},
+	{"CountryRegionABand",		Show_CountryRegionABand_Proc},
+	{"CountryCode",				Show_CountryCode_Proc},
+#ifdef AGGREGATION_SUPPORT
+	{"PktAggregate",			Show_PktAggregate_Proc},
+#endif
+
+#ifdef WMM_SUPPORT
+	{"WmmCapable",				Show_WmmCapable_Proc},
+#endif
+	{"IEEE80211H",				Show_IEEE80211H_Proc},
+#ifdef CONFIG_STA_SUPPORT
+    {"NetworkType",				Show_NetworkType_Proc},
+#endif // CONFIG_STA_SUPPORT //
+	{"AuthMode",				Show_AuthMode_Proc},
+	{"EncrypType",				Show_EncrypType_Proc},
+	{"DefaultKeyID",			Show_DefaultKeyID_Proc},
+	{"Key1",					Show_Key1_Proc},
+	{"Key2",					Show_Key2_Proc},
+	{"Key3",					Show_Key3_Proc},
+	{"Key4",					Show_Key4_Proc},
+	{"WPAPSK",					Show_WPAPSK_Proc},
+	{NULL, NULL}
+};
+
+/*
+    ==========================================================================
+    Description:
+        Get Driver version.
+
+    Return:
+    ==========================================================================
+*/
+INT Set_DriverVersion_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		DBGPRINT(RT_DEBUG_TRACE, ("Driver version-%s\n", STA_DRIVER_VERSION));
+#endif // CONFIG_STA_SUPPORT //
+
+    return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set Country Region.
+        This command will not work, if the field of CountryRegion in eeprom is programmed.
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT Set_CountryRegion_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ULONG region;
+
+	region = simple_strtol(arg, 0, 10);
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+	return -EOPNOTSUPP;
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+	// Country can be set only when EEPROM not programmed
+	if (pAd->CommonCfg.CountryRegion & 0x80)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegion_Proc::parameter of CountryRegion in eeprom is programmed \n"));
+		return FALSE;
+	}
+
+	if((region >= 0) && (region <= REGION_MAXIMUM_BG_BAND))
+	{
+		pAd->CommonCfg.CountryRegion = (UCHAR) region;
+	}
+	else if (region == REGION_31_BG_BAND)
+	{
+		pAd->CommonCfg.CountryRegion = (UCHAR) region;
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegion_Proc::parameters out of range\n"));
+		return FALSE;
+	}
+
+	// if set country region, driver needs to be reset
+	BuildChannelList(pAd);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_CountryRegion_Proc::(CountryRegion=%d)\n", pAd->CommonCfg.CountryRegion));
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set Country Region for A band.
+        This command will not work, if the field of CountryRegion in eeprom is programmed.
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT Set_CountryRegionABand_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ULONG region;
+
+	region = simple_strtol(arg, 0, 10);
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+	return -EOPNOTSUPP;
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+	// Country can be set only when EEPROM not programmed
+	if (pAd->CommonCfg.CountryRegionForABand & 0x80)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegionABand_Proc::parameter of CountryRegion in eeprom is programmed \n"));
+		return FALSE;
+	}
+
+	if((region >= 0) && (region <= REGION_MAXIMUM_A_BAND))
+	{
+		pAd->CommonCfg.CountryRegionForABand = (UCHAR) region;
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegionABand_Proc::parameters out of range\n"));
+		return FALSE;
+	}
+
+	// if set country region, driver needs to be reset
+	BuildChannelList(pAd);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_CountryRegionABand_Proc::(CountryRegion=%d)\n", pAd->CommonCfg.CountryRegionForABand));
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set Wireless Mode
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_WirelessMode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ULONG	WirelessMode;
+	INT		success = TRUE;
+
+	WirelessMode = simple_strtol(arg, 0, 10);
+
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		INT MaxPhyMode = PHY_11G;
+
+#ifdef DOT11_N_SUPPORT
+		MaxPhyMode = PHY_11N_5G;
+#endif // DOT11_N_SUPPORT //
+
+		if (WirelessMode <= MaxPhyMode)
+		{
+			RTMPSetPhyMode(pAd, WirelessMode);
+#ifdef DOT11_N_SUPPORT
+			if (WirelessMode >= PHY_11ABGN_MIXED)
+			{
+				pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
+				pAd->CommonCfg.REGBACapability.field.AutoBA = TRUE;
+			}
+			else
+			{
+				pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
+				pAd->CommonCfg.REGBACapability.field.AutoBA = FALSE;
+			}
+#endif // DOT11_N_SUPPORT //
+			// Set AdhocMode rates
+			if (pAd->StaCfg.BssType == BSS_ADHOC)
+			{
+				MlmeUpdateTxRates(pAd, FALSE, 0);
+				MakeIbssBeacon(pAd);           // re-build BEACON frame
+				AsicEnableIbssSync(pAd);       // copy to on-chip memory
+			}
+		}
+		else
+		{
+			success = FALSE;
+		}
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	// it is needed to set SSID to take effect
+	if (success == TRUE)
+	{
+#ifdef DOT11_N_SUPPORT
+		SetCommonHT(pAd);
+#endif // DOT11_N_SUPPORT //
+		DBGPRINT(RT_DEBUG_TRACE, ("Set_WirelessMode_Proc::(=%ld)\n", WirelessMode));
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("Set_WirelessMode_Proc::parameters out of range\n"));
+	}
+
+	return success;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set Channel
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_Channel_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+ 	INT		success = TRUE;
+	UCHAR	Channel;
+
+	Channel = (UCHAR) simple_strtol(arg, 0, 10);
+
+	// check if this channel is valid
+	if (ChannelSanity(pAd, Channel) == TRUE)
+	{
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+			pAd->CommonCfg.Channel = Channel;
+
+			if (MONITOR_ON(pAd))
+			{
+#ifdef DOT11_N_SUPPORT
+				N_ChannelCheck(pAd);
+				if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
+					pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
+				{
+					N_SetCenCh(pAd);
+					AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+					AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+					DBGPRINT(RT_DEBUG_TRACE, ("BW_40, control_channel(%d), CentralChannel(%d) \n",
+								pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
+				}
+				else
+#endif // DOT11_N_SUPPORT //
+				{
+					AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+					AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+					DBGPRINT(RT_DEBUG_TRACE, ("BW_20, Channel(%d)\n", pAd->CommonCfg.Channel));
+				}
+			}
+		}
+#endif // CONFIG_STA_SUPPORT //
+		success = TRUE;
+	}
+	else
+	{
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+			success = FALSE;
+#endif // CONFIG_STA_SUPPORT //
+	}
+
+
+	if (success == TRUE)
+		DBGPRINT(RT_DEBUG_TRACE, ("Set_Channel_Proc::(Channel=%d)\n", pAd->CommonCfg.Channel));
+
+	return success;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set Short Slot Time Enable or Disable
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_ShortSlot_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ULONG ShortSlot;
+
+	ShortSlot = simple_strtol(arg, 0, 10);
+
+	if (ShortSlot == 1)
+		pAd->CommonCfg.bUseShortSlotTime = TRUE;
+	else if (ShortSlot == 0)
+		pAd->CommonCfg.bUseShortSlotTime = FALSE;
+	else
+		return FALSE;  //Invalid argument
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_ShortSlot_Proc::(ShortSlot=%d)\n", pAd->CommonCfg.bUseShortSlotTime));
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set Tx power
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_TxPower_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ULONG TxPower;
+	INT   success = FALSE;
+
+	TxPower = (ULONG) simple_strtol(arg, 0, 10);
+	if (TxPower <= 100)
+	{
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+			pAd->CommonCfg.TxPowerDefault = TxPower;
+			pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
+		}
+#endif // CONFIG_STA_SUPPORT //
+		success = TRUE;
+	}
+	else
+		success = FALSE;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_TxPower_Proc::(TxPowerPercentage=%ld)\n", pAd->CommonCfg.TxPowerPercentage));
+
+	return success;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set 11B/11G Protection
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_BGProtection_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	switch (simple_strtol(arg, 0, 10))
+	{
+		case 0: //AUTO
+			pAd->CommonCfg.UseBGProtection = 0;
+			break;
+		case 1: //Always On
+			pAd->CommonCfg.UseBGProtection = 1;
+			break;
+		case 2: //Always OFF
+			pAd->CommonCfg.UseBGProtection = 2;
+			break;
+		default:  //Invalid argument
+			return FALSE;
+	}
+
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_BGProtection_Proc::(BGProtection=%ld)\n", pAd->CommonCfg.UseBGProtection));
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set TxPreamble
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_TxPreamble_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	RT_802_11_PREAMBLE	Preamble;
+
+	Preamble = simple_strtol(arg, 0, 10);
+
+
+	switch (Preamble)
+	{
+		case Rt802_11PreambleShort:
+			pAd->CommonCfg.TxPreamble = Preamble;
+#ifdef CONFIG_STA_SUPPORT
+			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+				MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
+#endif // CONFIG_STA_SUPPORT //
+			break;
+		case Rt802_11PreambleLong:
+#ifdef CONFIG_STA_SUPPORT
+		case Rt802_11PreambleAuto:
+			// if user wants AUTO, initialize to LONG here, then change according to AP's
+			// capability upon association.
+#endif // CONFIG_STA_SUPPORT //
+			pAd->CommonCfg.TxPreamble = Preamble;
+#ifdef CONFIG_STA_SUPPORT
+			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+				MlmeSetTxPreamble(pAd, Rt802_11PreambleLong);
+#endif // CONFIG_STA_SUPPORT //
+			break;
+		default: //Invalid argument
+			return FALSE;
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_TxPreamble_Proc::(TxPreamble=%ld)\n", pAd->CommonCfg.TxPreamble));
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set RTS Threshold
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_RTSThreshold_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	 NDIS_802_11_RTS_THRESHOLD           RtsThresh;
+
+	RtsThresh = simple_strtol(arg, 0, 10);
+
+	if((RtsThresh > 0) && (RtsThresh <= MAX_RTS_THRESHOLD))
+		pAd->CommonCfg.RtsThreshold  = (USHORT)RtsThresh;
+#ifdef CONFIG_STA_SUPPORT
+	else if (RtsThresh == 0)
+		pAd->CommonCfg.RtsThreshold = MAX_RTS_THRESHOLD;
+#endif // CONFIG_STA_SUPPORT //
+	else
+		return FALSE; //Invalid argument
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_RTSThreshold_Proc::(RTSThreshold=%d)\n", pAd->CommonCfg.RtsThreshold));
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set Fragment Threshold
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_FragThreshold_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	 NDIS_802_11_FRAGMENTATION_THRESHOLD     FragThresh;
+
+	FragThresh = simple_strtol(arg, 0, 10);
+
+	if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
+	{
+		//Illegal FragThresh so we set it to default
+		pAd->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
+	}
+	else if (FragThresh % 2 == 1)
+	{
+		// The length of each fragment shall always be an even number of octets, except for the last fragment
+		// of an MSDU or MMPDU, which may be either an even or an odd number of octets.
+		pAd->CommonCfg.FragmentThreshold = (USHORT)(FragThresh - 1);
+	}
+	else
+	{
+		pAd->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
+	}
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		if (pAd->CommonCfg.FragmentThreshold == MAX_FRAG_THRESHOLD)
+			pAd->CommonCfg.bUseZeroToDisableFragment = TRUE;
+		else
+			pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_FragThreshold_Proc::(FragThreshold=%d)\n", pAd->CommonCfg.FragmentThreshold));
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set TxBurst
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_TxBurst_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ULONG TxBurst;
+
+	TxBurst = simple_strtol(arg, 0, 10);
+	if (TxBurst == 1)
+		pAd->CommonCfg.bEnableTxBurst = TRUE;
+	else if (TxBurst == 0)
+		pAd->CommonCfg.bEnableTxBurst = FALSE;
+	else
+		return FALSE;  //Invalid argument
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_TxBurst_Proc::(TxBurst=%d)\n", pAd->CommonCfg.bEnableTxBurst));
+
+	return TRUE;
+}
+
+#ifdef AGGREGATION_SUPPORT
+/*
+    ==========================================================================
+    Description:
+        Set TxBurst
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_PktAggregate_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ULONG aggre;
+
+	aggre = simple_strtol(arg, 0, 10);
+
+	if (aggre == 1)
+		pAd->CommonCfg.bAggregationCapable = TRUE;
+	else if (aggre == 0)
+		pAd->CommonCfg.bAggregationCapable = FALSE;
+	else
+		return FALSE;  //Invalid argument
+
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_PktAggregate_Proc::(AGGRE=%d)\n", pAd->CommonCfg.bAggregationCapable));
+
+	return TRUE;
+}
+#endif
+
+/*
+    ==========================================================================
+    Description:
+        Set IEEE80211H.
+        This parameter is 1 when needs radar detection, otherwise 0
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_IEEE80211H_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+    ULONG ieee80211h;
+
+	ieee80211h = simple_strtol(arg, 0, 10);
+
+	if (ieee80211h == 1)
+		pAd->CommonCfg.bIEEE80211H = TRUE;
+	else if (ieee80211h == 0)
+		pAd->CommonCfg.bIEEE80211H = FALSE;
+	else
+		return FALSE;  //Invalid argument
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_IEEE80211H_Proc::(IEEE80211H=%d)\n", pAd->CommonCfg.bIEEE80211H));
+
+	return TRUE;
+}
+
+
+#ifdef DBG
+/*
+    ==========================================================================
+    Description:
+        For Debug information
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_Debug_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	DBGPRINT(RT_DEBUG_TRACE, ("==> Set_Debug_Proc *******************\n"));
+
+    if(simple_strtol(arg, 0, 10) <= RT_DEBUG_LOUD)
+        RTDebugLevel = simple_strtol(arg, 0, 10);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<== Set_Debug_Proc(RTDebugLevel = %ld)\n", RTDebugLevel));
+
+	return TRUE;
+}
+#endif
+
+INT	Show_DescInfo_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Reset statistics counter
+
+    Arguments:
+        pAdapter            Pointer to our adapter
+        arg
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_ResetStatCounter_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	//UCHAR           i;
+	//MAC_TABLE_ENTRY *pEntry;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("==>Set_ResetStatCounter_Proc\n"));
+
+	// add the most up-to-date h/w raw counters into software counters
+	NICUpdateRawCounters(pAd);
+
+	NdisZeroMemory(&pAd->WlanCounters, sizeof(COUNTER_802_11));
+	NdisZeroMemory(&pAd->Counters8023, sizeof(COUNTER_802_3));
+	NdisZeroMemory(&pAd->RalinkCounters, sizeof(COUNTER_RALINK));
+
+	return TRUE;
+}
+
+BOOLEAN RTMPCheckStrPrintAble(
+    IN  CHAR *pInPutStr,
+    IN  UCHAR strLen)
+{
+    UCHAR i=0;
+
+    for (i=0; i<strLen; i++)
+    {
+        if ((pInPutStr[i] < 0x21) ||
+            (pInPutStr[i] > 0x7E))
+            return FALSE;
+    }
+
+    return TRUE;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Remove WPA Key process
+
+	Arguments:
+		pAd 					Pointer to our adapter
+		pBuf							Pointer to the where the key stored
+
+	Return Value:
+		NDIS_SUCCESS					Add key successfully
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+#ifdef CONFIG_STA_SUPPORT
+VOID    RTMPSetDesiredRates(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  LONG            Rates)
+{
+    NDIS_802_11_RATES aryRates;
+
+    memset(&aryRates, 0x00, sizeof(NDIS_802_11_RATES));
+    switch (pAdapter->CommonCfg.PhyMode)
+    {
+        case PHY_11A: // A only
+            switch (Rates)
+            {
+                case 6000000: //6M
+                    aryRates[0] = 0x0c; // 6M
+                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
+                    break;
+                case 9000000: //9M
+                    aryRates[0] = 0x12; // 9M
+                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
+                    break;
+                case 12000000: //12M
+                    aryRates[0] = 0x18; // 12M
+                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
+                    break;
+                case 18000000: //18M
+                    aryRates[0] = 0x24; // 18M
+                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
+                    break;
+                case 24000000: //24M
+                    aryRates[0] = 0x30; // 24M
+                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_4;
+                    break;
+                case 36000000: //36M
+                    aryRates[0] = 0x48; // 36M
+                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_5;
+                    break;
+                case 48000000: //48M
+                    aryRates[0] = 0x60; // 48M
+                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_6;
+                    break;
+                case 54000000: //54M
+                    aryRates[0] = 0x6c; // 54M
+                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_7;
+                    break;
+                case -1: //Auto
+                default:
+                    aryRates[0] = 0x6c; // 54Mbps
+                    aryRates[1] = 0x60; // 48Mbps
+                    aryRates[2] = 0x48; // 36Mbps
+                    aryRates[3] = 0x30; // 24Mbps
+                    aryRates[4] = 0x24; // 18M
+                    aryRates[5] = 0x18; // 12M
+                    aryRates[6] = 0x12; // 9M
+                    aryRates[7] = 0x0c; // 6M
+                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
+                    break;
+            }
+            break;
+        case PHY_11BG_MIXED: // B/G Mixed
+        case PHY_11B: // B only
+        case PHY_11ABG_MIXED: // A/B/G Mixed
+        default:
+            switch (Rates)
+            {
+                case 1000000: //1M
+                    aryRates[0] = 0x02;
+                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
+                    break;
+                case 2000000: //2M
+                    aryRates[0] = 0x04;
+                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
+                    break;
+                case 5000000: //5.5M
+                    aryRates[0] = 0x0b; // 5.5M
+                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
+                    break;
+                case 11000000: //11M
+                    aryRates[0] = 0x16; // 11M
+                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
+                    break;
+                case 6000000: //6M
+                    aryRates[0] = 0x0c; // 6M
+                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
+                    break;
+                case 9000000: //9M
+                    aryRates[0] = 0x12; // 9M
+                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
+                    break;
+                case 12000000: //12M
+                    aryRates[0] = 0x18; // 12M
+                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
+                    break;
+                case 18000000: //18M
+                    aryRates[0] = 0x24; // 18M
+                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
+                    break;
+                case 24000000: //24M
+                    aryRates[0] = 0x30; // 24M
+                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_4;
+                    break;
+                case 36000000: //36M
+                    aryRates[0] = 0x48; // 36M
+                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_5;
+                    break;
+                case 48000000: //48M
+                    aryRates[0] = 0x60; // 48M
+                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_6;
+                    break;
+                case 54000000: //54M
+                    aryRates[0] = 0x6c; // 54M
+                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_7;
+                    break;
+                case -1: //Auto
+                default:
+                    if (pAdapter->CommonCfg.PhyMode == PHY_11B)
+                    { //B Only
+                        aryRates[0] = 0x16; // 11Mbps
+                        aryRates[1] = 0x0b; // 5.5Mbps
+                        aryRates[2] = 0x04; // 2Mbps
+                        aryRates[3] = 0x02; // 1Mbps
+                    }
+                    else
+                    { //(B/G) Mixed or (A/B/G) Mixed
+                        aryRates[0] = 0x6c; // 54Mbps
+                        aryRates[1] = 0x60; // 48Mbps
+                        aryRates[2] = 0x48; // 36Mbps
+                        aryRates[3] = 0x30; // 24Mbps
+                        aryRates[4] = 0x16; // 11Mbps
+                        aryRates[5] = 0x0b; // 5.5Mbps
+                        aryRates[6] = 0x04; // 2Mbps
+                        aryRates[7] = 0x02; // 1Mbps
+                    }
+                    pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
+                    break;
+            }
+            break;
+    }
+
+    NdisZeroMemory(pAdapter->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
+    NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates, sizeof(NDIS_802_11_RATES));
+    DBGPRINT(RT_DEBUG_TRACE, (" RTMPSetDesiredRates (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n",
+        pAdapter->CommonCfg.DesireRate[0],pAdapter->CommonCfg.DesireRate[1],
+        pAdapter->CommonCfg.DesireRate[2],pAdapter->CommonCfg.DesireRate[3],
+        pAdapter->CommonCfg.DesireRate[4],pAdapter->CommonCfg.DesireRate[5],
+        pAdapter->CommonCfg.DesireRate[6],pAdapter->CommonCfg.DesireRate[7] ));
+    // Changing DesiredRate may affect the MAX TX rate we used to TX frames out
+    MlmeUpdateTxRates(pAdapter, FALSE, 0);
+}
+
+NDIS_STATUS RTMPWPARemoveKeyProc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PVOID			pBuf)
+{
+	PNDIS_802_11_REMOVE_KEY pKey;
+	ULONG					KeyIdx;
+	NDIS_STATUS 			Status = NDIS_STATUS_FAILURE;
+	BOOLEAN 	bTxKey; 		// Set the key as transmit key
+	BOOLEAN 	bPairwise;		// Indicate the key is pairwise key
+	BOOLEAN 	bKeyRSC;		// indicate the receive  SC set by KeyRSC value.
+								// Otherwise, it will set by the NIC.
+	BOOLEAN 	bAuthenticator; // indicate key is set by authenticator.
+	INT 		i;
+
+	DBGPRINT(RT_DEBUG_TRACE,("---> RTMPWPARemoveKeyProc\n"));
+
+	pKey = (PNDIS_802_11_REMOVE_KEY) pBuf;
+	KeyIdx = pKey->KeyIndex & 0xff;
+	// Bit 31 of Add-key, Tx Key
+	bTxKey		   = (pKey->KeyIndex & 0x80000000) ? TRUE : FALSE;
+	// Bit 30 of Add-key PairwiseKey
+	bPairwise	   = (pKey->KeyIndex & 0x40000000) ? TRUE : FALSE;
+	// Bit 29 of Add-key KeyRSC
+	bKeyRSC 	   = (pKey->KeyIndex & 0x20000000) ? TRUE : FALSE;
+	// Bit 28 of Add-key Authenticator
+	bAuthenticator = (pKey->KeyIndex & 0x10000000) ? TRUE : FALSE;
+
+	// 1. If bTx is TRUE, return failure information
+	if (bTxKey == TRUE)
+		return(NDIS_STATUS_INVALID_DATA);
+
+	// 2. Check Pairwise Key
+	if (bPairwise)
+	{
+		// a. If BSSID is broadcast, remove all pairwise keys.
+		// b. If not broadcast, remove the pairwise specified by BSSID
+		for (i = 0; i < SHARE_KEY_NUM; i++)
+		{
+			if (MAC_ADDR_EQUAL(pAd->SharedKey[BSS0][i].BssId, pKey->BSSID))
+			{
+				DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveKeyProc(KeyIdx=%d)\n", i));
+				pAd->SharedKey[BSS0][i].KeyLen = 0;
+				pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_NONE;
+				AsicRemoveSharedKeyEntry(pAd, BSS0, (UCHAR)i);
+				Status = NDIS_STATUS_SUCCESS;
+				break;
+			}
+		}
+	}
+	// 3. Group Key
+	else
+	{
+		// a. If BSSID is broadcast, remove all group keys indexed
+		// b. If BSSID matched, delete the group key indexed.
+		DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveKeyProc(KeyIdx=%ld)\n", KeyIdx));
+		pAd->SharedKey[BSS0][KeyIdx].KeyLen = 0;
+		pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
+		AsicRemoveSharedKeyEntry(pAd, BSS0, (UCHAR)KeyIdx);
+		Status = NDIS_STATUS_SUCCESS;
+	}
+
+	return (Status);
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+#ifdef CONFIG_STA_SUPPORT
+/*
+	========================================================================
+
+	Routine Description:
+		Remove All WPA Keys
+
+	Arguments:
+		pAd 					Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTMPWPARemoveAllKeys(
+	IN	PRTMP_ADAPTER	pAd)
+{
+
+	UCHAR 	i;
+
+	DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveAllKeys(AuthMode=%d, WepStatus=%d)\n", pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus));
+
+	// For WEP/CKIP, there is no need to remove it, since WinXP won't set it again after
+	// Link up. And it will be replaced if user changed it.
+	if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
+		return;
+
+	// For WPA-None, there is no need to remove it, since WinXP won't set it again after
+	// Link up. And it will be replaced if user changed it.
+	if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+		return;
+
+	// set BSSID wcid entry of the Pair-wise Key table as no-security mode
+	AsicRemovePairwiseKeyEntry(pAd, BSS0, BSSID_WCID);
+
+	// set all shared key mode as no-security.
+	for (i = 0; i < SHARE_KEY_NUM; i++)
+    {
+		DBGPRINT(RT_DEBUG_TRACE,("remove %s key #%d\n", CipherName[pAd->SharedKey[BSS0][i].CipherAlg], i));
+		NdisZeroMemory(&pAd->SharedKey[BSS0][i], sizeof(CIPHER_KEY));
+
+		AsicRemoveSharedKeyEntry(pAd, BSS0, i);
+	}
+
+}
+#endif // CONFIG_STA_SUPPORT //
+
+/*
+	========================================================================
+	Routine Description:
+		Change NIC PHY mode. Re-association may be necessary. possible settings
+		include - PHY_11B, PHY_11BG_MIXED, PHY_11A, and PHY_11ABG_MIXED
+
+	Arguments:
+		pAd - Pointer to our adapter
+		phymode  -
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	========================================================================
+*/
+VOID	RTMPSetPhyMode(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	ULONG phymode)
+{
+	INT i;
+	// the selected phymode must be supported by the RF IC encoded in E2PROM
+
+	pAd->CommonCfg.PhyMode = (UCHAR)phymode;
+
+	DBGPRINT(RT_DEBUG_TRACE,("RTMPSetPhyMode : PhyMode=%d, channel=%d \n", pAd->CommonCfg.PhyMode, pAd->CommonCfg.Channel));
+#ifdef EXT_BUILD_CHANNEL_LIST
+	BuildChannelListEx(pAd);
+#else
+	BuildChannelList(pAd);
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+	// sanity check user setting
+	for (i = 0; i < pAd->ChannelListNum; i++)
+	{
+		if (pAd->CommonCfg.Channel == pAd->ChannelList[i].Channel)
+			break;
+	}
+
+	if (i == pAd->ChannelListNum)
+	{
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+			pAd->CommonCfg.Channel = FirstChannel(pAd);
+#endif // CONFIG_STA_SUPPORT //
+		DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetPhyMode: channel is out of range, use first channel=%d \n", pAd->CommonCfg.Channel));
+	}
+
+	NdisZeroMemory(pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
+	NdisZeroMemory(pAd->CommonCfg.ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
+	NdisZeroMemory(pAd->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
+	switch (phymode) {
+		case PHY_11B:
+			pAd->CommonCfg.SupRate[0]  = 0x82;	  // 1 mbps, in units of 0.5 Mbps, basic rate
+			pAd->CommonCfg.SupRate[1]  = 0x84;	  // 2 mbps, in units of 0.5 Mbps, basic rate
+			pAd->CommonCfg.SupRate[2]  = 0x8B;	  // 5.5 mbps, in units of 0.5 Mbps, basic rate
+			pAd->CommonCfg.SupRate[3]  = 0x96;	  // 11 mbps, in units of 0.5 Mbps, basic rate
+			pAd->CommonCfg.SupRateLen  = 4;
+			pAd->CommonCfg.ExtRateLen  = 0;
+			pAd->CommonCfg.DesireRate[0]  = 2;	   // 1 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.DesireRate[1]  = 4;	   // 2 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.DesireRate[2]  = 11;    // 5.5 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.DesireRate[3]  = 22;    // 11 mbps, in units of 0.5 Mbps
+			//pAd->CommonCfg.HTPhyMode.field.MODE = MODE_CCK; // This MODE is only FYI. not use
+			break;
+
+		case PHY_11G:
+		case PHY_11BG_MIXED:
+		case PHY_11ABG_MIXED:
+#ifdef DOT11_N_SUPPORT
+		case PHY_11N_2_4G:
+		case PHY_11ABGN_MIXED:
+		case PHY_11BGN_MIXED:
+		case PHY_11GN_MIXED:
+#endif // DOT11_N_SUPPORT //
+			pAd->CommonCfg.SupRate[0]  = 0x82;	  // 1 mbps, in units of 0.5 Mbps, basic rate
+			pAd->CommonCfg.SupRate[1]  = 0x84;	  // 2 mbps, in units of 0.5 Mbps, basic rate
+			pAd->CommonCfg.SupRate[2]  = 0x8B;	  // 5.5 mbps, in units of 0.5 Mbps, basic rate
+			pAd->CommonCfg.SupRate[3]  = 0x96;	  // 11 mbps, in units of 0.5 Mbps, basic rate
+			pAd->CommonCfg.SupRate[4]  = 0x12;	  // 9 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.SupRate[5]  = 0x24;	  // 18 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.SupRate[6]  = 0x48;	  // 36 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.SupRate[7]  = 0x6c;	  // 54 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.SupRateLen  = 8;
+			pAd->CommonCfg.ExtRate[0]  = 0x0C;	  // 6 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.ExtRate[1]  = 0x18;	  // 12 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.ExtRate[2]  = 0x30;	  // 24 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.ExtRate[3]  = 0x60;	  // 48 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.ExtRateLen  = 4;
+			pAd->CommonCfg.DesireRate[0]  = 2;	   // 1 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.DesireRate[1]  = 4;	   // 2 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.DesireRate[2]  = 11;    // 5.5 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.DesireRate[3]  = 22;    // 11 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.DesireRate[4]  = 12;    // 6 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.DesireRate[5]  = 18;    // 9 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.DesireRate[6]  = 24;    // 12 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.DesireRate[7]  = 36;    // 18 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.DesireRate[8]  = 48;    // 24 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.DesireRate[9]  = 72;    // 36 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.DesireRate[10] = 96;    // 48 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.DesireRate[11] = 108;   // 54 mbps, in units of 0.5 Mbps
+			break;
+
+		case PHY_11A:
+#ifdef DOT11_N_SUPPORT
+		case PHY_11AN_MIXED:
+		case PHY_11AGN_MIXED:
+		case PHY_11N_5G:
+#endif // DOT11_N_SUPPORT //
+			pAd->CommonCfg.SupRate[0]  = 0x8C;	  // 6 mbps, in units of 0.5 Mbps, basic rate
+			pAd->CommonCfg.SupRate[1]  = 0x12;	  // 9 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.SupRate[2]  = 0x98;	  // 12 mbps, in units of 0.5 Mbps, basic rate
+			pAd->CommonCfg.SupRate[3]  = 0x24;	  // 18 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.SupRate[4]  = 0xb0;	  // 24 mbps, in units of 0.5 Mbps, basic rate
+			pAd->CommonCfg.SupRate[5]  = 0x48;	  // 36 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.SupRate[6]  = 0x60;	  // 48 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.SupRate[7]  = 0x6c;	  // 54 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.SupRateLen  = 8;
+			pAd->CommonCfg.ExtRateLen  = 0;
+			pAd->CommonCfg.DesireRate[0]  = 12;    // 6 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.DesireRate[1]  = 18;    // 9 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.DesireRate[2]  = 24;    // 12 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.DesireRate[3]  = 36;    // 18 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.DesireRate[4]  = 48;    // 24 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.DesireRate[5]  = 72;    // 36 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.DesireRate[6]  = 96;    // 48 mbps, in units of 0.5 Mbps
+			pAd->CommonCfg.DesireRate[7]  = 108;   // 54 mbps, in units of 0.5 Mbps
+			//pAd->CommonCfg.HTPhyMode.field.MODE = MODE_OFDM; // This MODE is only FYI. not use
+			break;
+
+		default:
+			break;
+	}
+
+
+	pAd->CommonCfg.BandState = UNKNOWN_BAND;
+}
+
+
+#ifdef DOT11_N_SUPPORT
+/*
+	========================================================================
+	Routine Description:
+		Caller ensures we has 802.11n support.
+		Calls at setting HT from AP/STASetinformation
+
+	Arguments:
+		pAd - Pointer to our adapter
+		phymode  -
+
+	========================================================================
+*/
+VOID	RTMPSetHT(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	OID_SET_HT_PHYMODE *pHTPhyMode)
+{
+	//ULONG	*pmcs;
+	UINT32	Value = 0;
+	UCHAR	BBPValue = 0;
+	UCHAR	BBP3Value = 0;
+	UCHAR	RxStream = pAd->CommonCfg.RxStream;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : HT_mode(%d), ExtOffset(%d), MCS(%d), BW(%d), STBC(%d), SHORTGI(%d)\n",
+										pHTPhyMode->HtMode, pHTPhyMode->ExtOffset,
+										pHTPhyMode->MCS, pHTPhyMode->BW,
+										pHTPhyMode->STBC, pHTPhyMode->SHORTGI));
+
+	// Don't zero supportedHyPhy structure.
+	RTMPZeroMemory(&pAd->CommonCfg.HtCapability, sizeof(pAd->CommonCfg.HtCapability));
+	RTMPZeroMemory(&pAd->CommonCfg.AddHTInfo, sizeof(pAd->CommonCfg.AddHTInfo));
+	RTMPZeroMemory(&pAd->CommonCfg.NewExtChanOffset, sizeof(pAd->CommonCfg.NewExtChanOffset));
+	RTMPZeroMemory(&pAd->CommonCfg.DesiredHtPhy, sizeof(pAd->CommonCfg.DesiredHtPhy));
+
+   	if (pAd->CommonCfg.bRdg)
+	{
+		pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 1;
+		pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 1;
+	}
+	else
+	{
+		pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 0;
+		pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 0;
+	}
+
+	pAd->CommonCfg.HtCapability.HtCapParm.MaxRAmpduFactor = 3;
+	pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor = 3;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : RxBAWinLimit = %d\n", pAd->CommonCfg.BACapability.field.RxBAWinLimit));
+
+	// Mimo power save, A-MSDU size,
+	pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable;
+	pAd->CommonCfg.DesiredHtPhy.AmsduSize = (UCHAR)pAd->CommonCfg.BACapability.field.AmsduSize;
+	pAd->CommonCfg.DesiredHtPhy.MimoPs = (UCHAR)pAd->CommonCfg.BACapability.field.MMPSmode;
+	pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
+
+	pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
+	pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
+	pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : AMsduSize = %d, MimoPs = %d, MpduDensity = %d, MaxRAmpduFactor = %d\n",
+													pAd->CommonCfg.DesiredHtPhy.AmsduSize,
+													pAd->CommonCfg.DesiredHtPhy.MimoPs,
+													pAd->CommonCfg.DesiredHtPhy.MpduDensity,
+													pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor));
+
+	if(pHTPhyMode->HtMode == HTMODE_GF)
+	{
+		pAd->CommonCfg.HtCapability.HtCapInfo.GF = 1;
+		pAd->CommonCfg.DesiredHtPhy.GF = 1;
+	}
+	else
+		pAd->CommonCfg.DesiredHtPhy.GF = 0;
+
+	// Decide Rx MCSSet
+	switch (RxStream)
+	{
+		case 1:
+			pAd->CommonCfg.HtCapability.MCSSet[0] =  0xff;
+			pAd->CommonCfg.HtCapability.MCSSet[1] =  0x00;
+			break;
+
+		case 2:
+			pAd->CommonCfg.HtCapability.MCSSet[0] =  0xff;
+			pAd->CommonCfg.HtCapability.MCSSet[1] =  0xff;
+			break;
+
+		case 3: // 3*3
+			pAd->CommonCfg.HtCapability.MCSSet[0] =  0xff;
+			pAd->CommonCfg.HtCapability.MCSSet[1] =  0xff;
+			pAd->CommonCfg.HtCapability.MCSSet[2] =  0xff;
+			break;
+	}
+
+	if (pAd->CommonCfg.bForty_Mhz_Intolerant && (pAd->CommonCfg.Channel <= 14) && (pHTPhyMode->BW == BW_40) )
+	{
+		pHTPhyMode->BW = BW_20;
+		pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant = 1;
+	}
+
+	if(pHTPhyMode->BW == BW_40)
+	{
+		pAd->CommonCfg.HtCapability.MCSSet[4] = 0x1; // MCS 32
+		pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 1;
+		if (pAd->CommonCfg.Channel <= 14)
+			pAd->CommonCfg.HtCapability.HtCapInfo.CCKmodein40 = 1;
+
+		pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 1;
+		pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 1;
+		pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = (pHTPhyMode->ExtOffset == EXTCHA_BELOW)? (EXTCHA_BELOW): EXTCHA_ABOVE;
+		// Set Regsiter for extension channel position.
+		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
+		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBP3Value);
+		if ((pHTPhyMode->ExtOffset == EXTCHA_BELOW))
+		{
+			Value |= 0x1;
+			BBP3Value |= (0x20);
+			RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
+		}
+		else if ((pHTPhyMode->ExtOffset == EXTCHA_ABOVE))
+		{
+			Value &= 0xfe;
+			BBP3Value &= (~0x20);
+			RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
+		}
+
+		// Turn on BBP 40MHz mode now only as AP .
+		// Sta can turn on BBP 40MHz after connection with 40MHz AP. Sta only broadcast 40MHz capability before connection.
+		if ((pAd->OpMode == OPMODE_AP) || INFRA_ON(pAd) || ADHOC_ON(pAd)
+			)
+		{
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+			BBPValue &= (~0x18);
+			BBPValue |= 0x10;
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBP3Value);
+			pAd->CommonCfg.BBPCurrentBW = BW_40;
+		}
+	}
+	else
+	{
+		pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 0;
+		pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 0;
+		pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0;
+		pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = EXTCHA_NONE;
+		pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
+		// Turn on BBP 20MHz mode by request here.
+		{
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+			BBPValue &= (~0x18);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+			pAd->CommonCfg.BBPCurrentBW = BW_20;
+		}
+	}
+
+	if(pHTPhyMode->STBC == STBC_USE)
+	{
+		pAd->CommonCfg.HtCapability.HtCapInfo.TxSTBC = 1;
+		pAd->CommonCfg.DesiredHtPhy.TxSTBC = 1;
+		pAd->CommonCfg.HtCapability.HtCapInfo.RxSTBC = 1;
+		pAd->CommonCfg.DesiredHtPhy.RxSTBC = 1;
+	}
+	else
+	{
+		pAd->CommonCfg.DesiredHtPhy.TxSTBC = 0;
+		pAd->CommonCfg.DesiredHtPhy.RxSTBC = 0;
+	}
+
+	if(pHTPhyMode->SHORTGI == GI_400)
+	{
+		pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 1;
+		pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 1;
+		pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 1;
+		pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 1;
+	}
+	else
+	{
+		pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 0;
+		pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 0;
+		pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 0;
+		pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 0;
+	}
+
+	// We support link adaptation for unsolicit MCS feedback, set to 2.
+	pAd->CommonCfg.HtCapability.ExtHtCapInfo.MCSFeedback = MCSFBK_NONE; //MCSFBK_UNSOLICIT;
+	pAd->CommonCfg.AddHTInfo.ControlChan = pAd->CommonCfg.Channel;
+	// 1, the extension channel above the control channel.
+
+	// EDCA parameters used for AP's own transmission
+	if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
+	{
+		pAd->CommonCfg.APEdcaParm.bValid = TRUE;
+		pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
+		pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
+		pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
+		pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
+
+		pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
+		pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
+		pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
+		pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
+
+		pAd->CommonCfg.APEdcaParm.Cwmax[0] = 6;
+		pAd->CommonCfg.APEdcaParm.Cwmax[1] = 10;
+		pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
+		pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
+
+		pAd->CommonCfg.APEdcaParm.Txop[0]  = 0;
+		pAd->CommonCfg.APEdcaParm.Txop[1]  = 0;
+		pAd->CommonCfg.APEdcaParm.Txop[2]  = 94;
+		pAd->CommonCfg.APEdcaParm.Txop[3]  = 47;
+	}
+	AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
+
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		RTMPSetIndividualHT(pAd, 0);
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+}
+
+/*
+	========================================================================
+	Routine Description:
+		Caller ensures we has 802.11n support.
+		Calls at setting HT from AP/STASetinformation
+
+	Arguments:
+		pAd - Pointer to our adapter
+		phymode  -
+
+	========================================================================
+*/
+VOID	RTMPSetIndividualHT(
+	IN	PRTMP_ADAPTER		pAd,
+	IN	UCHAR				apidx)
+{
+	PRT_HT_PHY_INFO		pDesired_ht_phy = NULL;
+	UCHAR	TxStream = pAd->CommonCfg.TxStream;
+	UCHAR	DesiredMcs	= MCS_AUTO;
+
+	do
+	{
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+			pDesired_ht_phy = &pAd->StaCfg.DesiredHtPhyInfo;
+			DesiredMcs = pAd->StaCfg.DesiredTransmitSetting.field.MCS;
+			//pAd->StaCfg.bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE;
+				break;
+		}
+#endif // CONFIG_STA_SUPPORT //
+	} while (FALSE);
+
+	if (pDesired_ht_phy == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx));
+		return;
+	}
+	RTMPZeroMemory(pDesired_ht_phy, sizeof(RT_HT_PHY_INFO));
+
+	DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetIndividualHT : Desired MCS = %d\n", DesiredMcs));
+	// Check the validity of MCS
+	if ((TxStream == 1) && ((DesiredMcs >= MCS_8) && (DesiredMcs <= MCS_15)))
+	{
+		DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS(%d) is invalid in 1S, reset it as MCS_7\n", DesiredMcs));
+		DesiredMcs = MCS_7;
+	}
+
+	if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_20) && (DesiredMcs == MCS_32))
+	{
+		DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS_32 is only supported in 40-MHz, reset it as MCS_0\n"));
+		DesiredMcs = MCS_0;
+	}
+
+	pDesired_ht_phy->bHtEnable = TRUE;
+
+	// Decide desired Tx MCS
+	switch (TxStream)
+	{
+		case 1:
+			if (DesiredMcs == MCS_AUTO)
+			{
+				pDesired_ht_phy->MCSSet[0]= 0xff;
+				pDesired_ht_phy->MCSSet[1]= 0x00;
+			}
+			else if (DesiredMcs <= MCS_7)
+			{
+				pDesired_ht_phy->MCSSet[0]= 1<<DesiredMcs;
+				pDesired_ht_phy->MCSSet[1]= 0x00;
+			}
+			break;
+
+		case 2:
+			if (DesiredMcs == MCS_AUTO)
+			{
+				pDesired_ht_phy->MCSSet[0]= 0xff;
+				pDesired_ht_phy->MCSSet[1]= 0xff;
+			}
+			else if (DesiredMcs <= MCS_15)
+			{
+				ULONG mode;
+
+				mode = DesiredMcs / 8;
+				if (mode < 2)
+					pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8));
+			}
+			break;
+
+		case 3: // 3*3
+			if (DesiredMcs == MCS_AUTO)
+			{
+				/* MCS0 ~ MCS23, 3 bytes */
+				pDesired_ht_phy->MCSSet[0]= 0xff;
+				pDesired_ht_phy->MCSSet[1]= 0xff;
+				pDesired_ht_phy->MCSSet[2]= 0xff;
+			}
+			else if (DesiredMcs <= MCS_23)
+			{
+				ULONG mode;
+
+				mode = DesiredMcs / 8;
+				if (mode < 3)
+					pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8));
+			}
+			break;
+	}
+
+	if(pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_40)
+	{
+		if (DesiredMcs == MCS_AUTO || DesiredMcs == MCS_32)
+			pDesired_ht_phy->MCSSet[4] = 0x1;
+	}
+
+	// update HT Rate setting
+    if (pAd->OpMode == OPMODE_STA)
+        MlmeUpdateHtTxRates(pAd, BSS0);
+    else
+	    MlmeUpdateHtTxRates(pAd, apidx);
+}
+
+
+/*
+	========================================================================
+	Routine Description:
+		Update HT IE from our capability.
+
+	Arguments:
+		Send all HT IE in beacon/probe rsp/assoc rsp/action frame.
+
+
+	========================================================================
+*/
+VOID	RTMPUpdateHTIE(
+	IN	RT_HT_CAPABILITY	*pRtHt,
+	IN		UCHAR				*pMcsSet,
+	OUT		HT_CAPABILITY_IE *pHtCapability,
+	OUT		ADD_HT_INFO_IE		*pAddHtInfo)
+{
+	RTMPZeroMemory(pHtCapability, sizeof(HT_CAPABILITY_IE));
+	RTMPZeroMemory(pAddHtInfo, sizeof(ADD_HT_INFO_IE));
+
+		pHtCapability->HtCapInfo.ChannelWidth = pRtHt->ChannelWidth;
+		pHtCapability->HtCapInfo.MimoPs = pRtHt->MimoPs;
+		pHtCapability->HtCapInfo.GF = pRtHt->GF;
+		pHtCapability->HtCapInfo.ShortGIfor20 = pRtHt->ShortGIfor20;
+		pHtCapability->HtCapInfo.ShortGIfor40 = pRtHt->ShortGIfor40;
+		pHtCapability->HtCapInfo.TxSTBC = pRtHt->TxSTBC;
+		pHtCapability->HtCapInfo.RxSTBC = pRtHt->RxSTBC;
+		pHtCapability->HtCapInfo.AMsduSize = pRtHt->AmsduSize;
+		pHtCapability->HtCapParm.MaxRAmpduFactor = pRtHt->MaxRAmpduFactor;
+		pHtCapability->HtCapParm.MpduDensity = pRtHt->MpduDensity;
+
+		pAddHtInfo->AddHtInfo.ExtChanOffset = pRtHt->ExtChanOffset ;
+		pAddHtInfo->AddHtInfo.RecomWidth = pRtHt->RecomWidth;
+		pAddHtInfo->AddHtInfo2.OperaionMode = pRtHt->OperaionMode;
+		pAddHtInfo->AddHtInfo2.NonGfPresent = pRtHt->NonGfPresent;
+		RTMPMoveMemory(pAddHtInfo->MCSSet, /*pRtHt->MCSSet*/pMcsSet, 4); // rt2860 only support MCS max=32, no need to copy all 16 uchar.
+
+        DBGPRINT(RT_DEBUG_TRACE,("RTMPUpdateHTIE <== \n"));
+}
+#endif // DOT11_N_SUPPORT //
+
+/*
+	========================================================================
+	Description:
+		Add Client security information into ASIC WCID table and IVEIV table.
+    Return:
+	========================================================================
+*/
+VOID	RTMPAddWcidAttributeEntry(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			BssIdx,
+	IN 	UCHAR		 	KeyIdx,
+	IN 	UCHAR		 	CipherAlg,
+	IN 	MAC_TABLE_ENTRY *pEntry)
+{
+	UINT32		WCIDAttri = 0;
+	USHORT		offset;
+	UCHAR		IVEIV = 0;
+	USHORT		Wcid = 0;
+
+	{
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+			if (BssIdx > BSS0)
+			{
+				DBGPRINT(RT_DEBUG_ERROR, ("RTMPAddWcidAttributeEntry: The BSS-index(%d) is out of range for Infra link. \n", BssIdx));
+				return;
+			}
+
+			// 1.	In ADHOC mode, the AID is wcid number. And NO mesh link exists.
+			// 2.	In Infra mode, the AID:1 MUST be wcid of infra STA.
+			//					   the AID:2~ assign to mesh link entry.
+			if (pEntry && ADHOC_ON(pAd))
+				Wcid = pEntry->Aid;
+			else if (pEntry && INFRA_ON(pAd))
+			{
+#ifdef QOS_DLS_SUPPORT
+				if (pEntry->ValidAsDls == TRUE)
+					Wcid = pEntry->Aid;
+				else
+#endif // QOS_DLS_SUPPORT //
+				Wcid = BSSID_WCID;
+			}
+			else
+				Wcid = MCAST_WCID;
+		}
+#endif // CONFIG_STA_SUPPORT //
+	}
+
+	// Update WCID attribute table
+	offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		if (pEntry && pEntry->ValidAsMesh)
+			WCIDAttri = (CipherAlg<<1) | PAIRWISEKEYTABLE;
+#ifdef QOS_DLS_SUPPORT
+		else if ((pEntry) && (pEntry->ValidAsDls) &&
+					((CipherAlg == CIPHER_TKIP) ||
+				 	(CipherAlg == CIPHER_TKIP_NO_MIC) ||
+					(CipherAlg == CIPHER_AES) ||
+				 	(CipherAlg == CIPHER_NONE)))
+			WCIDAttri = (CipherAlg<<1) | PAIRWISEKEYTABLE;
+#endif // QOS_DLS_SUPPORT //
+		else
+			WCIDAttri = (CipherAlg<<1) | SHAREDKEYTABLE;
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
+
+
+	// Update IV/EIV table
+	offset = MAC_IVEIV_TABLE_BASE + (Wcid * HW_IVEIV_ENTRY_SIZE);
+
+	// WPA mode
+	if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) || (CipherAlg == CIPHER_AES))
+	{
+		// Eiv bit on. keyid always is 0 for pairwise key
+		IVEIV = (KeyIdx <<6) | 0x20;
+	}
+	else
+	{
+		// WEP KeyIdx is default tx key.
+		IVEIV = (KeyIdx << 6);
+	}
+
+	// For key index and ext IV bit, so only need to update the position(offset+3).
+#ifdef RT2870
+	RTUSBMultiWrite_OneByte(pAd, offset+3, &IVEIV);
+#endif // RT2870 //
+
+	DBGPRINT(RT_DEBUG_TRACE,("RTMPAddWcidAttributeEntry: WCID #%d, KeyIndex #%d, Alg=%s\n",Wcid, KeyIdx, CipherName[CipherAlg]));
+	DBGPRINT(RT_DEBUG_TRACE,("	WCIDAttri = 0x%x \n",  WCIDAttri));
+
+}
+
+/*
+    ==========================================================================
+    Description:
+        Parse encryption type
+Arguments:
+    pAdapter                    Pointer to our adapter
+    wrq                         Pointer to the ioctl argument
+
+    Return Value:
+        None
+
+    Note:
+    ==========================================================================
+*/
+CHAR *GetEncryptType(CHAR enc)
+{
+    if(enc == Ndis802_11WEPDisabled)
+        return "NONE";
+    if(enc == Ndis802_11WEPEnabled)
+    	return "WEP";
+    if(enc == Ndis802_11Encryption2Enabled)
+    	return "TKIP";
+    if(enc == Ndis802_11Encryption3Enabled)
+    	return "AES";
+	if(enc == Ndis802_11Encryption4Enabled)
+    	return "TKIPAES";
+    else
+    	return "UNKNOW";
+}
+
+CHAR *GetAuthMode(CHAR auth)
+{
+    if(auth == Ndis802_11AuthModeOpen)
+    	return "OPEN";
+    if(auth == Ndis802_11AuthModeShared)
+    	return "SHARED";
+	if(auth == Ndis802_11AuthModeAutoSwitch)
+    	return "AUTOWEP";
+    if(auth == Ndis802_11AuthModeWPA)
+    	return "WPA";
+    if(auth == Ndis802_11AuthModeWPAPSK)
+    	return "WPAPSK";
+    if(auth == Ndis802_11AuthModeWPANone)
+    	return "WPANONE";
+    if(auth == Ndis802_11AuthModeWPA2)
+    	return "WPA2";
+    if(auth == Ndis802_11AuthModeWPA2PSK)
+    	return "WPA2PSK";
+	if(auth == Ndis802_11AuthModeWPA1WPA2)
+    	return "WPA1WPA2";
+	if(auth == Ndis802_11AuthModeWPA1PSKWPA2PSK)
+    	return "WPA1PSKWPA2PSK";
+
+    	return "UNKNOW";
+}
+
+#if 1 //#ifndef UCOS
+/*
+    ==========================================================================
+    Description:
+        Get site survey results
+	Arguments:
+	    pAdapter                    Pointer to our adapter
+	    wrq                         Pointer to the ioctl argument
+
+    Return Value:
+        None
+
+    Note:
+        Usage:
+        		1.) UI needs to wait 4 seconds after issue a site survey command
+        		2.) iwpriv ra0 get_site_survey
+        		3.) UI needs to prepare at least 4096bytes to get the results
+    ==========================================================================
+*/
+#define	LINE_LEN	(4+33+20+8+10+9+7+3)	// Channel+SSID+Bssid+WepStatus+AuthMode+Signal+WiressMode+NetworkType
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+VOID RTMPIoctlGetSiteSurvey(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq)
+{
+	CHAR		*msg;
+	INT 		i=0;
+	INT			WaitCnt;
+	INT 		Status=0;
+	CHAR		Ssid[MAX_LEN_OF_SSID +1];
+    INT         Rssi = 0, max_len = LINE_LEN;
+	UINT        Rssi_Quality = 0;
+	NDIS_802_11_NETWORK_TYPE    wireless_mode;
+
+	os_alloc_mem(NULL, (PUCHAR *)&msg, sizeof(CHAR)*((MAX_LEN_OF_BSS_TABLE)*max_len));
+
+	if (msg == NULL)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlGetSiteSurvey - msg memory alloc fail.\n"));
+		return;
+	}
+
+	memset(msg, 0 ,(MAX_LEN_OF_BSS_TABLE)*max_len );
+	memset(Ssid, 0 ,(MAX_LEN_OF_SSID +1));
+	sprintf(msg,"%s","\n");
+	sprintf(msg+strlen(msg),"%-4s%-33s%-20s%-8s%-10s%-9s%-7s%-3s\n",
+	    "Ch", "SSID", "BSSID", "Enc", "Auth", "Siganl(%)", "W-Mode", " NT");
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+	WaitCnt = 0;
+#ifdef CONFIG_STA_SUPPORT
+	pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
+	while ((ScanRunning(pAdapter) == TRUE) && (WaitCnt++ < 200))
+		OS_WAIT(500);
+#endif // CONFIG_STA_SUPPORT //
+
+	for(i=0; i<pAdapter->ScanTab.BssNr ;i++)
+	{
+		if( pAdapter->ScanTab.BssEntry[i].Channel==0)
+			break;
+
+		if((strlen(msg)+max_len ) >= IW_SCAN_MAX_DATA)
+			break;
+
+		//Channel
+		sprintf(msg+strlen(msg),"%-4d", pAdapter->ScanTab.BssEntry[i].Channel);
+		//SSID
+		memcpy(Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
+		Ssid[pAdapter->ScanTab.BssEntry[i].SsidLen] = '\0';
+		sprintf(msg+strlen(msg),"%-33s", Ssid);
+		//BSSID
+		sprintf(msg+strlen(msg),"%02x:%02x:%02x:%02x:%02x:%02x   ",
+			pAdapter->ScanTab.BssEntry[i].Bssid[0],
+			pAdapter->ScanTab.BssEntry[i].Bssid[1],
+			pAdapter->ScanTab.BssEntry[i].Bssid[2],
+			pAdapter->ScanTab.BssEntry[i].Bssid[3],
+			pAdapter->ScanTab.BssEntry[i].Bssid[4],
+			pAdapter->ScanTab.BssEntry[i].Bssid[5]);
+		//Encryption Type
+		sprintf(msg+strlen(msg),"%-8s",GetEncryptType(pAdapter->ScanTab.BssEntry[i].WepStatus));
+		//Authentication Mode
+		if (pAdapter->ScanTab.BssEntry[i].WepStatus == Ndis802_11WEPEnabled)
+			sprintf(msg+strlen(msg),"%-10s", "UNKNOW");
+		else
+			sprintf(msg+strlen(msg),"%-10s",GetAuthMode(pAdapter->ScanTab.BssEntry[i].AuthMode));
+		// Rssi
+		Rssi = (INT)pAdapter->ScanTab.BssEntry[i].Rssi;
+		if (Rssi >= -50)
+			Rssi_Quality = 100;
+		else if (Rssi >= -80)    // between -50 ~ -80dbm
+			Rssi_Quality = (UINT)(24 + ((Rssi + 80) * 26)/10);
+		else if (Rssi >= -90)   // between -80 ~ -90dbm
+			Rssi_Quality = (UINT)(((Rssi + 90) * 26)/10);
+		else    // < -84 dbm
+			Rssi_Quality = 0;
+		sprintf(msg+strlen(msg),"%-9d", Rssi_Quality);
+		// Wireless Mode
+		wireless_mode = NetworkTypeInUseSanity(&pAdapter->ScanTab.BssEntry[i]);
+		if (wireless_mode == Ndis802_11FH ||
+			wireless_mode == Ndis802_11DS)
+			sprintf(msg+strlen(msg),"%-7s", "11b");
+		else if (wireless_mode == Ndis802_11OFDM5)
+			sprintf(msg+strlen(msg),"%-7s", "11a");
+		else if (wireless_mode == Ndis802_11OFDM5_N)
+			sprintf(msg+strlen(msg),"%-7s", "11a/n");
+		else if (wireless_mode == Ndis802_11OFDM24)
+			sprintf(msg+strlen(msg),"%-7s", "11b/g");
+		else if (wireless_mode == Ndis802_11OFDM24_N)
+			sprintf(msg+strlen(msg),"%-7s", "11b/g/n");
+		else
+			sprintf(msg+strlen(msg),"%-7s", "unknow");
+		//Network Type
+		if (pAdapter->ScanTab.BssEntry[i].BssType == BSS_ADHOC)
+			sprintf(msg+strlen(msg),"%-3s", " Ad");
+		else
+			sprintf(msg+strlen(msg),"%-3s", " In");
+
+        sprintf(msg+strlen(msg),"\n");
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+	}
+
+#ifdef CONFIG_STA_SUPPORT
+	pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
+#endif // CONFIG_STA_SUPPORT //
+	wrq->u.data.length = strlen(msg);
+	Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlGetSiteSurvey - wrq->u.data.length = %d\n", wrq->u.data.length));
+	os_free_mem(NULL, (PUCHAR)msg);
+}
+
+
+#define	MAC_LINE_LEN	(14+4+4+10+10+10+6+6)	// Addr+aid+psm+datatime+rxbyte+txbyte+current tx rate+last tx rate
+VOID RTMPIoctlGetMacTable(
+	IN PRTMP_ADAPTER pAd,
+	IN struct iwreq *wrq)
+{
+	INT i;
+	RT_802_11_MAC_TABLE MacTab;
+	char *msg;
+
+	MacTab.Num = 0;
+	for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+	{
+		if (pAd->MacTab.Content[i].ValidAsCLI && (pAd->MacTab.Content[i].Sst == SST_ASSOC))
+		{
+			COPY_MAC_ADDR(MacTab.Entry[MacTab.Num].Addr, &pAd->MacTab.Content[i].Addr);
+			MacTab.Entry[MacTab.Num].Aid = (UCHAR)pAd->MacTab.Content[i].Aid;
+			MacTab.Entry[MacTab.Num].Psm = pAd->MacTab.Content[i].PsMode;
+#ifdef DOT11_N_SUPPORT
+			MacTab.Entry[MacTab.Num].MimoPs = pAd->MacTab.Content[i].MmpsMode;
+#endif // DOT11_N_SUPPORT //
+
+			// Fill in RSSI per entry
+			MacTab.Entry[MacTab.Num].AvgRssi0 = pAd->MacTab.Content[i].RssiSample.AvgRssi0;
+			MacTab.Entry[MacTab.Num].AvgRssi1 = pAd->MacTab.Content[i].RssiSample.AvgRssi1;
+			MacTab.Entry[MacTab.Num].AvgRssi2 = pAd->MacTab.Content[i].RssiSample.AvgRssi2;
+
+			// the connected time per entry
+			MacTab.Entry[MacTab.Num].ConnectedTime = pAd->MacTab.Content[i].StaConnectTime;
+			MacTab.Entry[MacTab.Num].TxRate.field.MCS = pAd->MacTab.Content[i].HTPhyMode.field.MCS;
+			MacTab.Entry[MacTab.Num].TxRate.field.BW = pAd->MacTab.Content[i].HTPhyMode.field.BW;
+			MacTab.Entry[MacTab.Num].TxRate.field.ShortGI = pAd->MacTab.Content[i].HTPhyMode.field.ShortGI;
+			MacTab.Entry[MacTab.Num].TxRate.field.STBC = pAd->MacTab.Content[i].HTPhyMode.field.STBC;
+			MacTab.Entry[MacTab.Num].TxRate.field.rsv = pAd->MacTab.Content[i].HTPhyMode.field.rsv;
+			MacTab.Entry[MacTab.Num].TxRate.field.MODE = pAd->MacTab.Content[i].HTPhyMode.field.MODE;
+			MacTab.Entry[MacTab.Num].TxRate.word = pAd->MacTab.Content[i].HTPhyMode.word;
+
+			MacTab.Num += 1;
+		}
+	}
+	wrq->u.data.length = sizeof(RT_802_11_MAC_TABLE);
+	if (copy_to_user(wrq->u.data.pointer, &MacTab, wrq->u.data.length))
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("%s: copy_to_user() fail\n", __FUNCTION__));
+	}
+
+	msg = (CHAR *) kmalloc(sizeof(CHAR)*(MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN), MEM_ALLOC_FLAG);
+	memset(msg, 0 ,MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN );
+	sprintf(msg,"%s","\n");
+	sprintf(msg+strlen(msg),"%-14s%-4s%-4s%-10s%-10s%-10s%-6s%-6s\n",
+		"MAC", "AID", "PSM", "LDT", "RxB", "TxB","CTxR", "LTxR");
+
+	for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+	{
+		PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
+		if (pEntry->ValidAsCLI && (pEntry->Sst == SST_ASSOC))
+		{
+			if((strlen(msg)+MAC_LINE_LEN ) >= (MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN) )
+				break;
+			sprintf(msg+strlen(msg),"%02x%02x%02x%02x%02x%02x  ",
+				pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
+				pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
+			sprintf(msg+strlen(msg),"%-4d", (int)pEntry->Aid);
+			sprintf(msg+strlen(msg),"%-4d", (int)pEntry->PsMode);
+			sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.LastDataPacketTime*/); // ToDo
+			sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.TotalRxByteCount*/); // ToDo
+			sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.TotalTxByteCount*/); // ToDo
+			sprintf(msg+strlen(msg),"%-6d",RateIdToMbps[pAd->MacTab.Content[i].CurrTxRate]);
+			sprintf(msg+strlen(msg),"%-6d\n",0/*RateIdToMbps[pAd->MacTab.Content[i].LastTxRate]*/); // ToDo
+		}
+	}
+	// for compatible with old API just do the printk to console
+	//wrq->u.data.length = strlen(msg);
+	//if (copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length))
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("%s", msg));
+	}
+
+	kfree(msg);
+}
+#endif // UCOS //
+
+#ifdef DOT11_N_SUPPORT
+INT	Set_BASetup_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+    UCHAR mac[6], tid;
+	char *token, sepValue[] = ":", DASH = '-';
+	INT i;
+    MAC_TABLE_ENTRY *pEntry;
+
+/*
+	The BASetup inupt string format should be xx:xx:xx:xx:xx:xx-d,
+		=>The six 2 digit hex-decimal number previous are the Mac address,
+		=>The seventh decimal number is the tid value.
+*/
+	//printk("\n%s\n", arg);
+
+	if(strlen(arg) < 19)  //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
+		return FALSE;
+
+	token = strchr(arg, DASH);
+	if ((token != NULL) && (strlen(token)>1))
+	{
+		tid = simple_strtol((token+1), 0, 10);
+		if (tid > 15)
+			return FALSE;
+
+		*token = '\0';
+		for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
+		{
+			if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
+				return FALSE;
+			AtoH(token, (PUCHAR)(&mac[i]), 1);
+		}
+		if(i != 6)
+			return FALSE;
+
+		printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x\n", mac[0], mac[1],
+				mac[2], mac[3], mac[4], mac[5], tid);
+
+	    pEntry = MacTableLookup(pAd, mac);
+
+    	if (pEntry) {
+        	printk("\nSetup BA Session: Tid = %d\n", tid);
+	        BAOriSessionSetUp(pAd, pEntry, tid, 0, 100, TRUE);
+    	}
+
+		return TRUE;
+	}
+
+	return FALSE;
+
+}
+
+INT	Set_BADecline_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ULONG bBADecline;
+
+	bBADecline = simple_strtol(arg, 0, 10);
+
+	if (bBADecline == 0)
+	{
+		pAd->CommonCfg.bBADecline = FALSE;
+	}
+	else if (bBADecline == 1)
+	{
+		pAd->CommonCfg.bBADecline = TRUE;
+	}
+	else
+	{
+		return FALSE; //Invalid argument
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_BADecline_Proc::(BADecline=%d)\n", pAd->CommonCfg.bBADecline));
+
+	return TRUE;
+}
+
+INT	Set_BAOriTearDown_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+    UCHAR mac[6], tid;
+	char *token, sepValue[] = ":", DASH = '-';
+	INT i;
+    MAC_TABLE_ENTRY *pEntry;
+
+    //printk("\n%s\n", arg);
+/*
+	The BAOriTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
+		=>The six 2 digit hex-decimal number previous are the Mac address,
+		=>The seventh decimal number is the tid value.
+*/
+    if(strlen(arg) < 19)  //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
+		return FALSE;
+
+	token = strchr(arg, DASH);
+	if ((token != NULL) && (strlen(token)>1))
+	{
+		tid = simple_strtol((token+1), 0, 10);
+		if (tid > NUM_OF_TID)
+			return FALSE;
+
+		*token = '\0';
+		for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
+		{
+			if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
+				return FALSE;
+			AtoH(token, (PUCHAR)(&mac[i]), 1);
+		}
+		if(i != 6)
+			return FALSE;
+
+	    printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
+	           mac[2], mac[3], mac[4], mac[5], tid);
+
+	    pEntry = MacTableLookup(pAd, mac);
+
+	    if (pEntry) {
+	        printk("\nTear down Ori BA Session: Tid = %d\n", tid);
+        BAOriSessionTearDown(pAd, pEntry->Aid, tid, FALSE, TRUE);
+	    }
+
+		return TRUE;
+	}
+
+	return FALSE;
+
+}
+
+INT	Set_BARecTearDown_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+    UCHAR mac[6], tid;
+	char *token, sepValue[] = ":", DASH = '-';
+	INT i;
+    MAC_TABLE_ENTRY *pEntry;
+
+    //printk("\n%s\n", arg);
+/*
+	The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
+		=>The six 2 digit hex-decimal number previous are the Mac address,
+		=>The seventh decimal number is the tid value.
+*/
+    if(strlen(arg) < 19)  //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
+		return FALSE;
+
+	token = strchr(arg, DASH);
+	if ((token != NULL) && (strlen(token)>1))
+	{
+		tid = simple_strtol((token+1), 0, 10);
+		if (tid > NUM_OF_TID)
+			return FALSE;
+
+		*token = '\0';
+		for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
+		{
+			if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
+				return FALSE;
+			AtoH(token, (PUCHAR)(&mac[i]), 1);
+		}
+		if(i != 6)
+			return FALSE;
+
+		printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
+		       mac[2], mac[3], mac[4], mac[5], tid);
+
+		pEntry = MacTableLookup(pAd, mac);
+
+		if (pEntry) {
+		    printk("\nTear down Rec BA Session: Tid = %d\n", tid);
+		    BARecSessionTearDown(pAd, pEntry->Aid, tid, FALSE);
+		}
+
+		return TRUE;
+	}
+
+	return FALSE;
+
+}
+
+INT	Set_HtBw_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ULONG HtBw;
+
+	HtBw = simple_strtol(arg, 0, 10);
+	if (HtBw == BW_40)
+		pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_40;
+	else if (HtBw == BW_20)
+		pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_20;
+	else
+		return FALSE;  //Invalid argument
+
+	SetCommonHT(pAd);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtBw_Proc::(HtBw=%d)\n", pAd->CommonCfg.RegTransmitSetting.field.BW));
+
+	return TRUE;
+}
+
+INT	Set_HtMcs_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ULONG HtMcs, Mcs_tmp;
+#ifdef CONFIG_STA_SUPPORT
+    BOOLEAN bAutoRate = FALSE;
+#endif // CONFIG_STA_SUPPORT //
+
+	Mcs_tmp = simple_strtol(arg, 0, 10);
+
+	if (Mcs_tmp <= 15 || Mcs_tmp == 32)
+		HtMcs = Mcs_tmp;
+	else
+		HtMcs = MCS_AUTO;
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		pAd->StaCfg.DesiredTransmitSetting.field.MCS = HtMcs;
+		pAd->StaCfg.bAutoTxRateSwitch = (HtMcs == MCS_AUTO) ? TRUE:FALSE;
+		DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMcs_Proc::(HtMcs=%d, bAutoTxRateSwitch = %d)\n",
+						pAd->StaCfg.DesiredTransmitSetting.field.MCS, pAd->StaCfg.bAutoTxRateSwitch));
+
+		if ((pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED) ||
+			(pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE < MODE_HTMIX))
+		{
+	        if ((pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) &&
+				(HtMcs >= 0 && HtMcs <= 3) &&
+	            (pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode == FIXED_TXMODE_CCK))
+			{
+				RTMPSetDesiredRates(pAd, (LONG) (RateIdToMbps[HtMcs] * 1000000));
+			}
+	        else if ((pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) &&
+					(HtMcs >= 0 && HtMcs <= 7) &&
+	            	(pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode == FIXED_TXMODE_OFDM))
+			{
+				RTMPSetDesiredRates(pAd, (LONG) (RateIdToMbps[HtMcs+4] * 1000000));
+			}
+			else
+				bAutoRate = TRUE;
+
+			if (bAutoRate)
+			{
+	            pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
+				RTMPSetDesiredRates(pAd, -1);
+			}
+	        DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMcs_Proc::(FixedTxMode=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode));
+		}
+        if (ADHOC_ON(pAd))
+            return TRUE;
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	SetCommonHT(pAd);
+
+	return TRUE;
+}
+
+INT	Set_HtGi_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ULONG HtGi;
+
+	HtGi = simple_strtol(arg, 0, 10);
+
+	if ( HtGi == GI_400)
+		pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_400;
+	else if ( HtGi == GI_800 )
+		pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_800;
+	else
+		return FALSE; //Invalid argument
+
+	SetCommonHT(pAd);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtGi_Proc::(ShortGI=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.ShortGI));
+
+	return TRUE;
+}
+
+
+INT	Set_HtTxBASize_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	UCHAR Size;
+
+	Size = simple_strtol(arg, 0, 10);
+
+	if (Size <=0 || Size >=64)
+	{
+		Size = 8;
+	}
+	pAd->CommonCfg.TxBASize = Size-1;
+	DBGPRINT(RT_DEBUG_ERROR, ("Set_HtTxBASize ::(TxBASize= %d)\n", Size));
+
+	return TRUE;
+}
+
+
+INT	Set_HtOpMode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+
+	ULONG Value;
+
+	Value = simple_strtol(arg, 0, 10);
+
+	if (Value == HTMODE_GF)
+		pAd->CommonCfg.RegTransmitSetting.field.HTMODE  = HTMODE_GF;
+	else if ( Value == HTMODE_MM )
+		pAd->CommonCfg.RegTransmitSetting.field.HTMODE  = HTMODE_MM;
+	else
+		return FALSE; //Invalid argument
+
+	SetCommonHT(pAd);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtOpMode_Proc::(HtOpMode=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.HTMODE));
+
+	return TRUE;
+
+}
+
+INT	Set_HtStbc_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+
+	ULONG Value;
+
+	Value = simple_strtol(arg, 0, 10);
+
+	if (Value == STBC_USE)
+		pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_USE;
+	else if ( Value == STBC_NONE )
+		pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_NONE;
+	else
+		return FALSE; //Invalid argument
+
+	SetCommonHT(pAd);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_Stbc_Proc::(HtStbc=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.STBC));
+
+	return TRUE;
+}
+
+INT	Set_HtHtc_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+
+	ULONG Value;
+
+	Value = simple_strtol(arg, 0, 10);
+	if (Value == 0)
+		pAd->HTCEnable = FALSE;
+	else if ( Value ==1 )
+        	pAd->HTCEnable = TRUE;
+	else
+		return FALSE; //Invalid argument
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtHtc_Proc::(HtHtc=%d)\n",pAd->HTCEnable));
+
+	return TRUE;
+}
+
+INT	Set_HtExtcha_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+
+	ULONG Value;
+
+	Value = simple_strtol(arg, 0, 10);
+
+	if (Value == 0)
+		pAd->CommonCfg.RegTransmitSetting.field.EXTCHA  = EXTCHA_BELOW;
+	else if ( Value ==1 )
+        pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
+	else
+		return FALSE; //Invalid argument
+
+	SetCommonHT(pAd);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtExtcha_Proc::(HtExtcha=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.EXTCHA));
+
+	return TRUE;
+}
+
+INT	Set_HtMpduDensity_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ULONG Value;
+
+	Value = simple_strtol(arg, 0, 10);
+
+	if (Value <=7 && Value >= 0)
+		pAd->CommonCfg.BACapability.field.MpduDensity = Value;
+	else
+		pAd->CommonCfg.BACapability.field.MpduDensity = 4;
+
+	SetCommonHT(pAd);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMpduDensity_Proc::(HtMpduDensity=%d)\n",pAd->CommonCfg.BACapability.field.MpduDensity));
+
+	return TRUE;
+}
+
+INT	Set_HtBaWinSize_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ULONG Value;
+
+	Value = simple_strtol(arg, 0, 10);
+
+
+	if (Value >=1 && Value <= 64)
+	{
+		pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = Value;
+		pAd->CommonCfg.BACapability.field.RxBAWinLimit = Value;
+	}
+	else
+	{
+        pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = 64;
+		pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64;
+	}
+
+	SetCommonHT(pAd);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtBaWinSize_Proc::(HtBaWinSize=%d)\n",pAd->CommonCfg.BACapability.field.RxBAWinLimit));
+
+	return TRUE;
+}
+
+INT	Set_HtRdg_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ULONG Value;
+
+	Value = simple_strtol(arg, 0, 10);
+
+	if (Value == 0)
+		pAd->CommonCfg.bRdg = FALSE;
+	else if ( Value ==1 )
+	{
+		pAd->HTCEnable = TRUE;
+        	pAd->CommonCfg.bRdg = TRUE;
+	}
+	else
+		return FALSE; //Invalid argument
+
+	SetCommonHT(pAd);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtRdg_Proc::(HtRdg=%d)\n",pAd->CommonCfg.bRdg));
+
+	return TRUE;
+}
+
+INT	Set_HtLinkAdapt_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ULONG Value;
+
+	Value = simple_strtol(arg, 0, 10);
+	if (Value == 0)
+		pAd->bLinkAdapt = FALSE;
+	else if ( Value ==1 )
+	{
+			pAd->HTCEnable = TRUE;
+			pAd->bLinkAdapt = TRUE;
+	}
+	else
+		return FALSE; //Invalid argument
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtLinkAdapt_Proc::(HtLinkAdapt=%d)\n",pAd->bLinkAdapt));
+
+	return TRUE;
+}
+
+INT	Set_HtAmsdu_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ULONG Value;
+
+	Value = simple_strtol(arg, 0, 10);
+	if (Value == 0)
+		pAd->CommonCfg.BACapability.field.AmsduEnable = FALSE;
+	else if ( Value == 1 )
+        pAd->CommonCfg.BACapability.field.AmsduEnable = TRUE;
+	else
+		return FALSE; //Invalid argument
+
+	SetCommonHT(pAd);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtAmsdu_Proc::(HtAmsdu=%d)\n",pAd->CommonCfg.BACapability.field.AmsduEnable));
+
+	return TRUE;
+}
+
+INT	Set_HtAutoBa_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ULONG Value;
+
+	Value = simple_strtol(arg, 0, 10);
+	if (Value == 0)
+	{
+		pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
+		pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
+	}
+        else if (Value == 1)
+	{
+		pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
+		pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
+	}
+	else
+		return FALSE; //Invalid argument
+
+    pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA;
+    pAd->CommonCfg.REGBACapability.field.Policy = pAd->CommonCfg.BACapability.field.Policy;
+	SetCommonHT(pAd);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtAutoBa_Proc::(HtAutoBa=%d)\n",pAd->CommonCfg.BACapability.field.AutoBA));
+
+	return TRUE;
+
+}
+
+INT	Set_HtProtect_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ULONG Value;
+
+	Value = simple_strtol(arg, 0, 10);
+	if (Value == 0)
+		pAd->CommonCfg.bHTProtect = FALSE;
+    else if (Value == 1)
+		pAd->CommonCfg.bHTProtect = TRUE;
+	else
+		return FALSE; //Invalid argument
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtProtect_Proc::(HtProtect=%d)\n",pAd->CommonCfg.bHTProtect));
+
+	return TRUE;
+}
+
+INT	Set_SendPSMPAction_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+    UCHAR mac[6], mode;
+	char *token, sepValue[] = ":", DASH = '-';
+	INT i;
+    MAC_TABLE_ENTRY *pEntry;
+
+    //printk("\n%s\n", arg);
+/*
+	The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
+		=>The six 2 digit hex-decimal number previous are the Mac address,
+		=>The seventh decimal number is the mode value.
+*/
+    if(strlen(arg) < 19)  //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and mode value in decimal format.
+		return FALSE;
+
+   	token = strchr(arg, DASH);
+	if ((token != NULL) && (strlen(token)>1))
+	{
+		mode = simple_strtol((token+1), 0, 10);
+		if (mode > MMPS_ENABLE)
+			return FALSE;
+
+		*token = '\0';
+		for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
+		{
+			if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
+				return FALSE;
+			AtoH(token, (PUCHAR)(&mac[i]), 1);
+		}
+		if(i != 6)
+			return FALSE;
+
+		printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
+		       mac[2], mac[3], mac[4], mac[5], mode);
+
+		pEntry = MacTableLookup(pAd, mac);
+
+		if (pEntry) {
+		    printk("\nSendPSMPAction MIPS mode = %d\n", mode);
+		    SendPSMPAction(pAd, pEntry->Aid, mode);
+		}
+
+		return TRUE;
+	}
+
+	return FALSE;
+
+
+}
+
+INT	Set_HtMIMOPSmode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ULONG Value;
+
+	Value = simple_strtol(arg, 0, 10);
+
+	if (Value <=3 && Value >= 0)
+		pAd->CommonCfg.BACapability.field.MMPSmode = Value;
+	else
+		pAd->CommonCfg.BACapability.field.MMPSmode = 3;
+
+	SetCommonHT(pAd);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMIMOPSmode_Proc::(MIMOPS mode=%d)\n",pAd->CommonCfg.BACapability.field.MMPSmode));
+
+	return TRUE;
+}
+
+
+INT	Set_ForceShortGI_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ULONG Value;
+
+	Value = simple_strtol(arg, 0, 10);
+	if (Value == 0)
+		pAd->WIFItestbed.bShortGI = FALSE;
+	else if (Value == 1)
+		pAd->WIFItestbed.bShortGI = TRUE;
+	else
+		return FALSE; //Invalid argument
+
+	SetCommonHT(pAd);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_ForceShortGI_Proc::(ForceShortGI=%d)\n", pAd->WIFItestbed.bShortGI));
+
+	return TRUE;
+}
+
+
+
+INT	Set_ForceGF_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ULONG Value;
+
+	Value = simple_strtol(arg, 0, 10);
+	if (Value == 0)
+		pAd->WIFItestbed.bGreenField = FALSE;
+	else if (Value == 1)
+		pAd->WIFItestbed.bGreenField = TRUE;
+	else
+		return FALSE; //Invalid argument
+
+	SetCommonHT(pAd);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_ForceGF_Proc::(ForceGF=%d)\n", pAd->WIFItestbed.bGreenField));
+
+	return TRUE;
+}
+
+INT	Set_HtMimoPs_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ULONG Value;
+
+	Value = simple_strtol(arg, 0, 10);
+	if (Value == 0)
+		pAd->CommonCfg.bMIMOPSEnable = FALSE;
+	else if (Value == 1)
+		pAd->CommonCfg.bMIMOPSEnable = TRUE;
+	else
+		return FALSE; //Invalid argument
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMimoPs_Proc::(HtMimoPs=%d)\n",pAd->CommonCfg.bMIMOPSEnable));
+
+	return TRUE;
+}
+#endif // DOT11_N_SUPPORT //
+
+
+#ifdef DOT11_N_SUPPORT
+INT	SetCommonHT(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	OID_SET_HT_PHYMODE		SetHT;
+
+	if (pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED)
+		return FALSE;
+
+	SetHT.PhyMode = pAd->CommonCfg.PhyMode;
+	SetHT.TransmitNo = ((UCHAR)pAd->Antenna.field.TxPath);
+	SetHT.HtMode = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.HTMODE;
+	SetHT.ExtOffset = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
+	SetHT.MCS = MCS_AUTO;
+	SetHT.BW = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.BW;
+	SetHT.STBC = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.STBC;
+	SetHT.SHORTGI = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.ShortGI;
+
+	RTMPSetHT(pAd, &SetHT);
+
+	return TRUE;
+}
+#endif // DOT11_N_SUPPORT //
+
+INT	Set_FixedTxMode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	UCHAR	fix_tx_mode = FIXED_TXMODE_HT;
+
+	if (strcmp(arg, "OFDM") == 0 || strcmp(arg, "ofdm") == 0)
+	{
+		fix_tx_mode = FIXED_TXMODE_OFDM;
+	}
+	else if (strcmp(arg, "CCK") == 0 || strcmp(arg, "cck") == 0)
+	{
+        fix_tx_mode = FIXED_TXMODE_CCK;
+	}
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = fix_tx_mode;
+#endif // CONFIG_STA_SUPPORT //
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_FixedTxMode_Proc::(FixedTxMode=%d)\n", fix_tx_mode));
+
+	return TRUE;
+}
+
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+INT	Set_OpMode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ULONG Value;
+
+	Value = simple_strtol(arg, 0, 10);
+
+#ifdef RT2870
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
+#endif // RT2870 //
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("Can not switch operate mode on interface up !! \n"));
+		return FALSE;
+	}
+
+	if (Value == 0)
+		pAd->OpMode = OPMODE_STA;
+	else if (Value == 1)
+		pAd->OpMode = OPMODE_AP;
+	else
+		return FALSE; //Invalid argument
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_OpMode_Proc::(OpMode=%s)\n", pAd->OpMode == 1 ? "AP Mode" : "STA Mode"));
+
+	return TRUE;
+}
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+
+
+/////////////////////////////////////////////////////////////////////////
+PCHAR   RTMPGetRalinkAuthModeStr(
+    IN  NDIS_802_11_AUTHENTICATION_MODE authMode)
+{
+	switch(authMode)
+	{
+		case Ndis802_11AuthModeOpen:
+			return "OPEN";
+        default:
+		case Ndis802_11AuthModeWPAPSK:
+			return "WPAPSK";
+		case Ndis802_11AuthModeShared:
+			return "SHARED";
+		case Ndis802_11AuthModeWPA:
+			return "WPA";
+		case Ndis802_11AuthModeWPA2:
+			return "WPA2";
+		case Ndis802_11AuthModeWPA2PSK:
+			return "WPA2PSK";
+        case Ndis802_11AuthModeWPA1PSKWPA2PSK:
+			return "WPAPSKWPA2PSK";
+        case Ndis802_11AuthModeWPA1WPA2:
+			return "WPA1WPA2";
+	}
+}
+
+PCHAR   RTMPGetRalinkEncryModeStr(
+    IN  USHORT encryMode)
+{
+	switch(encryMode)
+	{
+	    default:
+		case Ndis802_11WEPDisabled:
+			return "NONE";
+		case Ndis802_11WEPEnabled:
+			return "WEP";
+		case Ndis802_11Encryption2Enabled:
+			return "TKIP";
+		case Ndis802_11Encryption3Enabled:
+			return "AES";
+        case Ndis802_11Encryption4Enabled:
+			return "TKIPAES";
+	}
+}
+
+INT RTMPShowCfgValue(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pName,
+	IN	PUCHAR			pBuf)
+{
+	INT	Status = 0;
+
+	for (PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC = RTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC++)
+	{
+		if (!strcmp(pName, PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name))
+		{
+			if(PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->show_proc(pAd, pBuf))
+				Status = -EINVAL;
+			break;  //Exit for loop.
+		}
+	}
+
+	if(PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name == NULL)
+	{
+		sprintf(pBuf, "\n");
+		for (PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC = RTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC++)
+			sprintf(pBuf, "%s%s\n", pBuf, PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name);
+	}
+
+	return Status;
+}
+
+INT	Show_SSID_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		sprintf(pBuf, "\t%s", pAd->CommonCfg.Ssid);
+#endif // CONFIG_STA_SUPPORT //
+	return 0;
+}
+
+INT	Show_WirelessMode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	switch(pAd->CommonCfg.PhyMode)
+	{
+		case PHY_11BG_MIXED:
+			sprintf(pBuf, "\t11B/G");
+			break;
+		case PHY_11B:
+			sprintf(pBuf, "\t11B");
+			break;
+		case PHY_11A:
+			sprintf(pBuf, "\t11A");
+			break;
+		case PHY_11ABG_MIXED:
+			sprintf(pBuf, "\t11A/B/G");
+			break;
+		case PHY_11G:
+			sprintf(pBuf, "\t11G");
+			break;
+#ifdef DOT11_N_SUPPORT
+		case PHY_11ABGN_MIXED:
+			sprintf(pBuf, "\t11A/B/G/N");
+			break;
+		case PHY_11N_2_4G:
+			sprintf(pBuf, "\t11N only with 2.4G");
+			break;
+		case PHY_11GN_MIXED:
+			sprintf(pBuf, "\t11G/N");
+			break;
+		case PHY_11AN_MIXED:
+			sprintf(pBuf, "\t11A/N");
+			break;
+		case PHY_11BGN_MIXED:
+			sprintf(pBuf, "\t11B/G/N");
+			break;
+		case PHY_11AGN_MIXED:
+			sprintf(pBuf, "\t11A/G/N");
+			break;
+		case PHY_11N_5G:
+			sprintf(pBuf, "\t11N only with 5G");
+			break;
+#endif // DOT11_N_SUPPORT //
+		default:
+			sprintf(pBuf, "\tUnknow Value(%d)", pAd->CommonCfg.PhyMode);
+			break;
+	}
+	return 0;
+}
+
+
+INT	Show_TxBurst_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	sprintf(pBuf, "\t%s", pAd->CommonCfg.bEnableTxBurst ? "TRUE":"FALSE");
+	return 0;
+}
+
+INT	Show_TxPreamble_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	switch(pAd->CommonCfg.TxPreamble)
+	{
+		case Rt802_11PreambleShort:
+			sprintf(pBuf, "\tShort");
+			break;
+		case Rt802_11PreambleLong:
+			sprintf(pBuf, "\tLong");
+			break;
+		case Rt802_11PreambleAuto:
+			sprintf(pBuf, "\tAuto");
+			break;
+		default:
+			sprintf(pBuf, "\tUnknow Value(%lu)", pAd->CommonCfg.TxPreamble);
+			break;
+	}
+
+	return 0;
+}
+
+INT	Show_TxPower_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	sprintf(pBuf, "\t%lu", pAd->CommonCfg.TxPowerPercentage);
+	return 0;
+}
+
+INT	Show_Channel_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	sprintf(pBuf, "\t%d", pAd->CommonCfg.Channel);
+	return 0;
+}
+
+INT	Show_BGProtection_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	switch(pAd->CommonCfg.UseBGProtection)
+	{
+		case 1: //Always On
+			sprintf(pBuf, "\tON");
+			break;
+		case 2: //Always OFF
+			sprintf(pBuf, "\tOFF");
+			break;
+		case 0: //AUTO
+			sprintf(pBuf, "\tAuto");
+			break;
+		default:
+			sprintf(pBuf, "\tUnknow Value(%lu)", pAd->CommonCfg.UseBGProtection);
+			break;
+	}
+	return 0;
+}
+
+INT	Show_RTSThreshold_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	sprintf(pBuf, "\t%u", pAd->CommonCfg.RtsThreshold);
+	return 0;
+}
+
+INT	Show_FragThreshold_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	sprintf(pBuf, "\t%u", pAd->CommonCfg.FragmentThreshold);
+	return 0;
+}
+
+#ifdef DOT11_N_SUPPORT
+INT	Show_HtBw_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
+	{
+		sprintf(pBuf, "\t40 MHz");
+	}
+	else
+	{
+        sprintf(pBuf, "\t20 MHz");
+	}
+	return 0;
+}
+
+INT	Show_HtMcs_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		sprintf(pBuf, "\t%u", pAd->StaCfg.DesiredTransmitSetting.field.MCS);
+#endif // CONFIG_STA_SUPPORT //
+	return 0;
+}
+
+INT	Show_HtGi_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	switch(pAd->CommonCfg.RegTransmitSetting.field.ShortGI)
+	{
+		case GI_400:
+			sprintf(pBuf, "\tGI_400");
+			break;
+		case GI_800:
+			sprintf(pBuf, "\tGI_800");
+			break;
+		default:
+			sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.ShortGI);
+			break;
+	}
+	return 0;
+}
+
+INT	Show_HtOpMode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	switch(pAd->CommonCfg.RegTransmitSetting.field.HTMODE)
+	{
+		case HTMODE_GF:
+			sprintf(pBuf, "\tGF");
+			break;
+		case HTMODE_MM:
+			sprintf(pBuf, "\tMM");
+			break;
+		default:
+			sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.HTMODE);
+			break;
+	}
+	return 0;
+}
+
+INT	Show_HtExtcha_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	switch(pAd->CommonCfg.RegTransmitSetting.field.EXTCHA)
+	{
+		case EXTCHA_BELOW:
+			sprintf(pBuf, "\tBelow");
+			break;
+		case EXTCHA_ABOVE:
+			sprintf(pBuf, "\tAbove");
+			break;
+		default:
+			sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.EXTCHA);
+			break;
+	}
+	return 0;
+}
+
+
+INT	Show_HtMpduDensity_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.MpduDensity);
+	return 0;
+}
+
+INT	Show_HtBaWinSize_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.RxBAWinLimit);
+	return 0;
+}
+
+INT	Show_HtRdg_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	sprintf(pBuf, "\t%s", pAd->CommonCfg.bRdg ? "TRUE":"FALSE");
+	return 0;
+}
+
+INT	Show_HtAmsdu_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AmsduEnable ? "TRUE":"FALSE");
+	return 0;
+}
+
+INT	Show_HtAutoBa_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AutoBA ? "TRUE":"FALSE");
+	return 0;
+}
+#endif // DOT11_N_SUPPORT //
+
+INT	Show_CountryRegion_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegion);
+	return 0;
+}
+
+INT	Show_CountryRegionABand_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegionForABand);
+	return 0;
+}
+
+INT	Show_CountryCode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	sprintf(pBuf, "\t%s", pAd->CommonCfg.CountryCode);
+	return 0;
+}
+
+#ifdef AGGREGATION_SUPPORT
+INT	Show_PktAggregate_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	sprintf(pBuf, "\t%s", pAd->CommonCfg.bAggregationCapable ? "TRUE":"FALSE");
+	return 0;
+}
+#endif // AGGREGATION_SUPPORT //
+
+#ifdef WMM_SUPPORT
+INT	Show_WmmCapable_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		sprintf(pBuf, "\t%s", pAd->CommonCfg.bWmmCapable ? "TRUE":"FALSE");
+#endif // CONFIG_STA_SUPPORT //
+
+	return 0;
+}
+#endif // WMM_SUPPORT //
+
+INT	Show_IEEE80211H_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	sprintf(pBuf, "\t%s", pAd->CommonCfg.bIEEE80211H ? "TRUE":"FALSE");
+	return 0;
+}
+
+#ifdef CONFIG_STA_SUPPORT
+INT	Show_NetworkType_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	switch(pAd->StaCfg.BssType)
+	{
+		case BSS_ADHOC:
+			sprintf(pBuf, "\tAdhoc");
+			break;
+		case BSS_INFRA:
+			sprintf(pBuf, "\tInfra");
+			break;
+		case BSS_ANY:
+			sprintf(pBuf, "\tAny");
+			break;
+		case BSS_MONITOR:
+			sprintf(pBuf, "\tMonitor");
+			break;
+		default:
+			sprintf(pBuf, "\tUnknow Value(%d)", pAd->StaCfg.BssType);
+			break;
+	}
+	return 0;
+}
+#endif // CONFIG_STA_SUPPORT //
+
+INT	Show_AuthMode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	NDIS_802_11_AUTHENTICATION_MODE	AuthMode = Ndis802_11AuthModeOpen;
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		AuthMode = pAd->StaCfg.AuthMode;
+#endif // CONFIG_STA_SUPPORT //
+
+	if ((AuthMode >= Ndis802_11AuthModeOpen) &&
+		(AuthMode <= Ndis802_11AuthModeWPA1PSKWPA2PSK))
+		sprintf(pBuf, "\t%s", RTMPGetRalinkAuthModeStr(AuthMode));
+	else
+		sprintf(pBuf, "\tUnknow Value(%d)", AuthMode);
+
+	return 0;
+}
+
+INT	Show_EncrypType_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	NDIS_802_11_WEP_STATUS	WepStatus = Ndis802_11WEPDisabled;
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		WepStatus = pAd->StaCfg.WepStatus;
+#endif // CONFIG_STA_SUPPORT //
+
+	if ((WepStatus >= Ndis802_11WEPEnabled) &&
+		(WepStatus <= Ndis802_11Encryption4KeyAbsent))
+		sprintf(pBuf, "\t%s", RTMPGetRalinkEncryModeStr(WepStatus));
+	else
+		sprintf(pBuf, "\tUnknow Value(%d)", WepStatus);
+
+	return 0;
+}
+
+INT	Show_DefaultKeyID_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	UCHAR DefaultKeyId = 0;
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		DefaultKeyId = pAd->StaCfg.DefaultKeyId;
+#endif // CONFIG_STA_SUPPORT //
+
+	sprintf(pBuf, "\t%d", DefaultKeyId);
+
+	return 0;
+}
+
+INT	Show_WepKey_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN  INT				KeyIdx,
+	OUT	PUCHAR			pBuf)
+{
+	UCHAR   Key[16] = {0}, KeyLength = 0;
+	INT		index = BSS0;
+
+	KeyLength = pAd->SharedKey[index][KeyIdx].KeyLen;
+	NdisMoveMemory(Key, pAd->SharedKey[index][KeyIdx].Key, KeyLength);
+
+	//check key string is ASCII or not
+    if (RTMPCheckStrPrintAble(Key, KeyLength))
+        sprintf(pBuf, "\t%s", Key);
+    else
+    {
+        int idx;
+        sprintf(pBuf, "\t");
+        for (idx = 0; idx < KeyLength; idx++)
+            sprintf(pBuf+strlen(pBuf), "%02X", Key[idx]);
+    }
+	return 0;
+}
+
+INT	Show_Key1_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	Show_WepKey_Proc(pAd, 0, pBuf);
+	return 0;
+}
+
+INT	Show_Key2_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	Show_WepKey_Proc(pAd, 1, pBuf);
+	return 0;
+}
+
+INT	Show_Key3_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	Show_WepKey_Proc(pAd, 2, pBuf);
+	return 0;
+}
+
+INT	Show_Key4_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	Show_WepKey_Proc(pAd, 3, pBuf);
+	return 0;
+}
+
+INT	Show_WPAPSK_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUCHAR			pBuf)
+{
+	INT 	idx;
+	UCHAR	PMK[32] = {0};
+
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		NdisMoveMemory(PMK, pAd->StaCfg.PMK, 32);
+#endif // CONFIG_STA_SUPPORT //
+
+    sprintf(pBuf, "\tPMK = ");
+    for (idx = 0; idx < 32; idx++)
+        sprintf(pBuf+strlen(pBuf), "%02X", PMK[idx]);
+
+	return 0;
+}
+
diff --git a/drivers/staging/rt3070/common/cmm_sanity.c b/drivers/staging/rt3070/common/cmm_sanity.c
new file mode 100644
index 0000000..6118df8
--- /dev/null
+++ b/drivers/staging/rt3070/common/cmm_sanity.c
@@ -0,0 +1,1669 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	sanity.c
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	John Chang  2004-09-01      add WMM support
+*/
+#include "../rt_config.h"
+
+
+extern UCHAR	CISCO_OUI[];
+
+extern UCHAR	WPA_OUI[];
+extern UCHAR	RSN_OUI[];
+extern UCHAR	WME_INFO_ELEM[];
+extern UCHAR	WME_PARM_ELEM[];
+extern UCHAR	Ccx2QosInfo[];
+extern UCHAR	RALINK_OUI[];
+extern UCHAR	BROADCOM_OUI[];
+extern UCHAR    WPS_OUI[];
+
+/*
+    ==========================================================================
+    Description:
+        MLME message sanity check
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+BOOLEAN MlmeAddBAReqSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *Msg,
+    IN ULONG MsgLen,
+    OUT PUCHAR pAddr2)
+{
+    PMLME_ADDBA_REQ_STRUCT   pInfo;
+
+    pInfo = (MLME_ADDBA_REQ_STRUCT *)Msg;
+
+    if ((MsgLen != sizeof(MLME_ADDBA_REQ_STRUCT)))
+    {
+        DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - message lenght not correct.\n"));
+        return FALSE;
+    }
+
+    if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE))
+    {
+        DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - The peer Mac is not associated yet.\n"));
+        return FALSE;
+    }
+
+	/*
+    if ((pInfo->BaBufSize > MAX_RX_REORDERBUF) || (pInfo->BaBufSize < 2))
+    {
+        DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - Rx Reordering buffer too big or too small\n"));
+        return FALSE;
+    }
+	*/
+
+    if ((pInfo->pAddr[0]&0x01) == 0x01)
+    {
+        DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - broadcast address not support BA\n"));
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        MLME message sanity check
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+BOOLEAN MlmeDelBAReqSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *Msg,
+    IN ULONG MsgLen)
+{
+	MLME_DELBA_REQ_STRUCT *pInfo;
+	pInfo = (MLME_DELBA_REQ_STRUCT *)Msg;
+
+    if ((MsgLen != sizeof(MLME_DELBA_REQ_STRUCT)))
+    {
+        DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - message lenght not correct.\n"));
+        return FALSE;
+    }
+
+    if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE))
+    {
+        DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer Mac is not associated yet.\n"));
+        return FALSE;
+    }
+
+    if ((pInfo->TID & 0xf0))
+    {
+        DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer TID is incorrect.\n"));
+        return FALSE;
+    }
+
+	if (NdisEqualMemory(pAd->MacTab.Content[pInfo->Wcid].Addr, pInfo->Addr, MAC_ADDR_LEN) == 0)
+    {
+        DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - the peer addr dosen't exist.\n"));
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+BOOLEAN PeerAddBAReqActionSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *pMsg,
+    IN ULONG MsgLen,
+	OUT PUCHAR pAddr2)
+{
+	PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
+	PFRAME_ADDBA_REQ pAddFrame;
+	pAddFrame = (PFRAME_ADDBA_REQ)(pMsg);
+	if (MsgLen < (sizeof(FRAME_ADDBA_REQ)))
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request frame length size = %ld incorrect\n", MsgLen));
+		return FALSE;
+	}
+	// we support immediate BA.
+	*(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm));
+	pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue);
+	pAddFrame->BaStartSeq.word = cpu2le16(pAddFrame->BaStartSeq.word);
+
+	if (pAddFrame->BaParm.BAPolicy != IMMED_BA)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request Ba Policy[%d] not support\n", pAddFrame->BaParm.BAPolicy));
+		DBGPRINT(RT_DEBUG_ERROR,("ADDBA Request. tid=%x, Bufsize=%x, AMSDUSupported=%x \n", pAddFrame->BaParm.TID, pAddFrame->BaParm.BufSize, pAddFrame->BaParm.AMSDUSupported));
+		return FALSE;
+	}
+
+	// we support immediate BA.
+	if (pAddFrame->BaParm.TID &0xfff0)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request incorrect TID = %d\n", pAddFrame->BaParm.TID));
+		return FALSE;
+	}
+	COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
+	return TRUE;
+}
+
+BOOLEAN PeerAddBARspActionSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *pMsg,
+    IN ULONG MsgLen)
+{
+	//PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
+	PFRAME_ADDBA_RSP pAddFrame;
+
+	pAddFrame = (PFRAME_ADDBA_RSP)(pMsg);
+	if (MsgLen < (sizeof(FRAME_ADDBA_RSP)))
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("PeerAddBARspActionSanity: ADDBA Response frame length size = %ld incorrect\n", MsgLen));
+		return FALSE;
+	}
+	// we support immediate BA.
+	*(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm));
+	pAddFrame->StatusCode = cpu2le16(pAddFrame->StatusCode);
+	pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue);
+
+	if (pAddFrame->BaParm.BAPolicy != IMMED_BA)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Response Ba Policy[%d] not support\n", pAddFrame->BaParm.BAPolicy));
+		return FALSE;
+	}
+
+	// we support immediate BA.
+	if (pAddFrame->BaParm.TID &0xfff0)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("PeerAddBARspActionSanity: ADDBA Response incorrect TID = %d\n", pAddFrame->BaParm.TID));
+		return FALSE;
+	}
+	return TRUE;
+
+}
+
+BOOLEAN PeerDelBAActionSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN UCHAR Wcid,
+    IN VOID *pMsg,
+    IN ULONG MsgLen )
+{
+	//PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
+	PFRAME_DELBA_REQ  pDelFrame;
+	if (MsgLen != (sizeof(FRAME_DELBA_REQ)))
+		return FALSE;
+
+	if (Wcid >= MAX_LEN_OF_MAC_TABLE)
+		return FALSE;
+
+	pDelFrame = (PFRAME_DELBA_REQ)(pMsg);
+
+	*(USHORT *)(&pDelFrame->DelbaParm) = cpu2le16(*(USHORT *)(&pDelFrame->DelbaParm));
+	pDelFrame->ReasonCode = cpu2le16(pDelFrame->ReasonCode);
+
+	if (pDelFrame->DelbaParm.TID &0xfff0)
+		return FALSE;
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        MLME message sanity check
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+BOOLEAN PeerBeaconAndProbeRspSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *Msg,
+    IN ULONG MsgLen,
+    IN UCHAR  MsgChannel,
+    OUT PUCHAR pAddr2,
+    OUT PUCHAR pBssid,
+    OUT CHAR Ssid[],
+    OUT UCHAR *pSsidLen,
+    OUT UCHAR *pBssType,
+    OUT USHORT *pBeaconPeriod,
+    OUT UCHAR *pChannel,
+    OUT UCHAR *pNewChannel,
+    OUT LARGE_INTEGER *pTimestamp,
+    OUT CF_PARM *pCfParm,
+    OUT USHORT *pAtimWin,
+    OUT USHORT *pCapabilityInfo,
+    OUT UCHAR *pErp,
+    OUT UCHAR *pDtimCount,
+    OUT UCHAR *pDtimPeriod,
+    OUT UCHAR *pBcastFlag,
+    OUT UCHAR *pMessageToMe,
+    OUT UCHAR SupRate[],
+    OUT UCHAR *pSupRateLen,
+    OUT UCHAR ExtRate[],
+    OUT UCHAR *pExtRateLen,
+    OUT	UCHAR *pCkipFlag,
+    OUT	UCHAR *pAironetCellPowerLimit,
+    OUT PEDCA_PARM       pEdcaParm,
+    OUT PQBSS_LOAD_PARM  pQbssLoad,
+    OUT PQOS_CAPABILITY_PARM pQosCapability,
+    OUT ULONG *pRalinkIe,
+    OUT UCHAR		 *pHtCapabilityLen,
+#ifdef CONFIG_STA_SUPPORT
+    OUT UCHAR		 *pPreNHtCapabilityLen,
+#endif // CONFIG_STA_SUPPORT //
+    OUT HT_CAPABILITY_IE *pHtCapability,
+	OUT UCHAR		 *AddHtInfoLen,
+	OUT ADD_HT_INFO_IE *AddHtInfo,
+	OUT UCHAR *NewExtChannelOffset,		// Ht extension channel offset(above or below)
+    OUT USHORT *LengthVIE,
+    OUT	PNDIS_802_11_VARIABLE_IEs pVIE)
+{
+    CHAR				*Ptr;
+#ifdef CONFIG_STA_SUPPORT
+	CHAR 				TimLen;
+#endif // CONFIG_STA_SUPPORT //
+    PFRAME_802_11		pFrame;
+    PEID_STRUCT         pEid;
+    UCHAR				SubType;
+    UCHAR				Sanity;
+    //UCHAR				ECWMin, ECWMax;
+    //MAC_CSR9_STRUC		Csr9;
+    ULONG				Length = 0;
+
+	// For some 11a AP which didn't have DS_IE, we use two conditions to decide the channel
+	//	1. If the AP is 11n enabled, then check the control channel.
+	//	2. If the AP didn't have any info about channel, use the channel we received this frame as the channel. (May inaccuracy!!)
+	UCHAR			CtrlChannel = 0;
+
+    // Add for 3 necessary EID field check
+    Sanity = 0;
+
+    *pAtimWin = 0;
+    *pErp = 0;
+    *pDtimCount = 0;
+    *pDtimPeriod = 0;
+    *pBcastFlag = 0;
+    *pMessageToMe = 0;
+    *pExtRateLen = 0;
+    *pCkipFlag = 0;			        // Default of CkipFlag is 0
+    *pAironetCellPowerLimit = 0xFF;  // Default of AironetCellPowerLimit is 0xFF
+    *LengthVIE = 0;					// Set the length of VIE to init value 0
+    *pHtCapabilityLen = 0;					// Set the length of VIE to init value 0
+#ifdef CONFIG_STA_SUPPORT
+	if (pAd->OpMode == OPMODE_STA)
+		*pPreNHtCapabilityLen = 0;					// Set the length of VIE to init value 0
+#endif // CONFIG_STA_SUPPORT //
+    *AddHtInfoLen = 0;					// Set the length of VIE to init value 0
+    *pRalinkIe = 0;
+    *pNewChannel = 0;
+    *NewExtChannelOffset = 0xff;	//Default 0xff means no such IE
+    pCfParm->bValid = FALSE;        // default: no IE_CF found
+    pQbssLoad->bValid = FALSE;      // default: no IE_QBSS_LOAD found
+    pEdcaParm->bValid = FALSE;      // default: no IE_EDCA_PARAMETER found
+    pQosCapability->bValid = FALSE; // default: no IE_QOS_CAPABILITY found
+
+    pFrame = (PFRAME_802_11)Msg;
+
+    // get subtype from header
+    SubType = (UCHAR)pFrame->Hdr.FC.SubType;
+
+    // get Addr2 and BSSID from header
+    COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
+    COPY_MAC_ADDR(pBssid, pFrame->Hdr.Addr3);
+
+//	hex_dump("Beacon", Msg, MsgLen);
+
+    Ptr = pFrame->Octet;
+    Length += LENGTH_802_11;
+
+    // get timestamp from payload and advance the pointer
+    NdisMoveMemory(pTimestamp, Ptr, TIMESTAMP_LEN);
+
+	pTimestamp->u.LowPart = cpu2le32(pTimestamp->u.LowPart);
+	pTimestamp->u.HighPart = cpu2le32(pTimestamp->u.HighPart);
+
+    Ptr += TIMESTAMP_LEN;
+    Length += TIMESTAMP_LEN;
+
+    // get beacon interval from payload and advance the pointer
+    NdisMoveMemory(pBeaconPeriod, Ptr, 2);
+    Ptr += 2;
+    Length += 2;
+
+    // get capability info from payload and advance the pointer
+    NdisMoveMemory(pCapabilityInfo, Ptr, 2);
+    Ptr += 2;
+    Length += 2;
+
+    if (CAP_IS_ESS_ON(*pCapabilityInfo))
+        *pBssType = BSS_INFRA;
+    else
+        *pBssType = BSS_ADHOC;
+
+    pEid = (PEID_STRUCT) Ptr;
+
+    // get variable fields from payload and advance the pointer
+    while ((Length + 2 + pEid->Len) <= MsgLen)
+    {
+        //
+        // Secure copy VIE to VarIE[MAX_VIE_LEN] didn't overflow.
+        //
+        if ((*LengthVIE + pEid->Len + 2) >= MAX_VIE_LEN)
+        {
+            DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - Variable IEs out of resource [len(=%d) > MAX_VIE_LEN(=%d)]\n",
+                    (*LengthVIE + pEid->Len + 2), MAX_VIE_LEN));
+            break;
+        }
+
+        switch(pEid->Eid)
+        {
+            case IE_SSID:
+                // Already has one SSID EID in this beacon, ignore the second one
+                if (Sanity & 0x1)
+                    break;
+                if(pEid->Len <= MAX_LEN_OF_SSID)
+                {
+                    NdisMoveMemory(Ssid, pEid->Octet, pEid->Len);
+                    *pSsidLen = pEid->Len;
+                    Sanity |= 0x1;
+                }
+                else
+                {
+                    DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n",pEid->Len));
+                    return FALSE;
+                }
+                break;
+
+            case IE_SUPP_RATES:
+                if(pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
+                {
+                    Sanity |= 0x2;
+                    NdisMoveMemory(SupRate, pEid->Octet, pEid->Len);
+                    *pSupRateLen = pEid->Len;
+
+                    // TODO: 2004-09-14 not a good design here, cause it exclude extra rates
+                    // from ScanTab. We should report as is. And filter out unsupported
+                    // rates in MlmeAux.
+                    // Check against the supported rates
+                    // RTMPCheckRates(pAd, SupRate, pSupRateLen);
+                }
+                else
+                {
+                    DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SUPP_RATES (len=%d)\n",pEid->Len));
+                    return FALSE;
+                }
+                break;
+
+            case IE_HT_CAP:
+			if (pEid->Len >= SIZE_HT_CAP_IE)  //Note: allow extension.!!
+			{
+				NdisMoveMemory(pHtCapability, pEid->Octet, sizeof(HT_CAPABILITY_IE));
+				*pHtCapabilityLen = SIZE_HT_CAP_IE;	// Nnow we only support 26 bytes.
+
+				*(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
+				*(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
+
+#ifdef CONFIG_STA_SUPPORT
+				IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+				{
+					*pPreNHtCapabilityLen = 0;	// Nnow we only support 26 bytes.
+
+					Ptr = (PUCHAR) pVIE;
+					NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
+					*LengthVIE += (pEid->Len + 2);
+				}
+#endif // CONFIG_STA_SUPPORT //
+			}
+			else
+			{
+				DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_HT_CAP. pEid->Len = %d\n", pEid->Len));
+			}
+
+		break;
+            case IE_ADD_HT:
+			if (pEid->Len >= sizeof(ADD_HT_INFO_IE))
+			{
+				// This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only
+				// copy first sizeof(ADD_HT_INFO_IE)
+				NdisMoveMemory(AddHtInfo, pEid->Octet, sizeof(ADD_HT_INFO_IE));
+				*AddHtInfoLen = SIZE_ADD_HT_INFO_IE;
+
+				CtrlChannel = AddHtInfo->ControlChan;
+
+				*(USHORT *)(&AddHtInfo->AddHtInfo2) = cpu2le16(*(USHORT *)(&AddHtInfo->AddHtInfo2));
+				*(USHORT *)(&AddHtInfo->AddHtInfo3) = cpu2le16(*(USHORT *)(&AddHtInfo->AddHtInfo3));
+
+#ifdef CONFIG_STA_SUPPORT
+				IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+				{
+			                Ptr = (PUCHAR) pVIE;
+			                NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
+			                *LengthVIE += (pEid->Len + 2);
+				}
+#endif // CONFIG_STA_SUPPORT //
+			}
+			else
+			{
+				DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_ADD_HT. \n"));
+			}
+
+		break;
+            case IE_SECONDARY_CH_OFFSET:
+			if (pEid->Len == 1)
+			{
+				*NewExtChannelOffset = pEid->Octet[0];
+			}
+			else
+			{
+				DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
+			}
+
+		break;
+            case IE_FH_PARM:
+                DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity(IE_FH_PARM) \n"));
+                break;
+
+            case IE_DS_PARM:
+                if(pEid->Len == 1)
+                {
+                    *pChannel = *pEid->Octet;
+#ifdef CONFIG_STA_SUPPORT
+					IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+					{
+						if (ChannelSanity(pAd, *pChannel) == 0)
+						{
+
+							return FALSE;
+						}
+					}
+#endif // CONFIG_STA_SUPPORT //
+                    Sanity |= 0x4;
+                }
+                else
+                {
+                    DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_DS_PARM (len=%d)\n",pEid->Len));
+                    return FALSE;
+                }
+                break;
+
+            case IE_CF_PARM:
+                if(pEid->Len == 6)
+                {
+                    pCfParm->bValid = TRUE;
+                    pCfParm->CfpCount = pEid->Octet[0];
+                    pCfParm->CfpPeriod = pEid->Octet[1];
+                    pCfParm->CfpMaxDuration = pEid->Octet[2] + 256 * pEid->Octet[3];
+                    pCfParm->CfpDurRemaining = pEid->Octet[4] + 256 * pEid->Octet[5];
+                }
+                else
+                {
+                    DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_CF_PARM\n"));
+                    return FALSE;
+                }
+                break;
+
+            case IE_IBSS_PARM:
+                if(pEid->Len == 2)
+                {
+                    NdisMoveMemory(pAtimWin, pEid->Octet, pEid->Len);
+                }
+                else
+                {
+                    DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_IBSS_PARM\n"));
+                    return FALSE;
+                }
+                break;
+
+#ifdef CONFIG_STA_SUPPORT
+            case IE_TIM:
+                if(INFRA_ON(pAd) && SubType == SUBTYPE_BEACON)
+                {
+                    GetTimBit((PUCHAR)pEid, pAd->StaActive.Aid, &TimLen, pBcastFlag, pDtimCount, pDtimPeriod, pMessageToMe);
+                }
+                break;
+#endif // CONFIG_STA_SUPPORT //
+            case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
+                if(pEid->Len == 3)
+                {
+                	*pNewChannel = pEid->Octet[1];	//extract new channel number
+                }
+                break;
+
+            // New for WPA
+            // CCX v2 has the same IE, we need to parse that too
+            // Wifi WMM use the same IE vale, need to parse that too
+            // case IE_WPA:
+            case IE_VENDOR_SPECIFIC:
+                // Check Broadcom/Atheros 802.11n OUI version, for HT Capability IE.
+                // This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan.
+                /*if (NdisEqualMemory(pEid->Octet, BROADCOM_OUI, 3) && (pEid->Len >= 4))
+                {
+                	if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 30))
+            		{
+				{
+					NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(HT_CAPABILITY_IE));
+					*pHtCapabilityLen = SIZE_HT_CAP_IE;	// Nnow we only support 26 bytes.
+				}
+         		}
+                	if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 26))
+            		{
+				{
+					NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(ADD_HT_INFO_IE));
+					*AddHtInfoLen = SIZE_ADD_HT_INFO_IE;	// Nnow we only support 26 bytes.
+				}
+         		}
+                }
+				*/
+                // Check the OUI version, filter out non-standard usage
+                if (NdisEqualMemory(pEid->Octet, RALINK_OUI, 3) && (pEid->Len == 7))
+                {
+                    //*pRalinkIe = pEid->Octet[3];
+                    if (pEid->Octet[3] != 0)
+        				*pRalinkIe = pEid->Octet[3];
+        			else
+        				*pRalinkIe = 0xf0000000; // Set to non-zero value (can't set bit0-2) to represent this is Ralink Chip. So at linkup, we will set ralinkchip flag.
+                }
+#ifdef CONFIG_STA_SUPPORT
+#ifdef DOT11_N_SUPPORT
+		// This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan.
+
+                // Other vendors had production before IE_HT_CAP value is assigned. To backward support those old-firmware AP,
+                // Check broadcom-defiend pre-802.11nD1.0 OUI for HT related IE, including HT Capatilities IE and HT Information IE
+                else if ((*pHtCapabilityLen == 0) && NdisEqualMemory(pEid->Octet, PRE_N_HT_OUI, 3) && (pEid->Len >= 4) && (pAd->OpMode == OPMODE_STA))
+                {
+                    if ((pEid->Octet[3] == OUI_PREN_HT_CAP) && (pEid->Len >= 30) && (*pHtCapabilityLen == 0))
+                    {
+                        NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(HT_CAPABILITY_IE));
+                        *pPreNHtCapabilityLen = SIZE_HT_CAP_IE;
+                    }
+
+                    if ((pEid->Octet[3] == OUI_PREN_ADD_HT) && (pEid->Len >= 26))
+                    {
+                        NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(ADD_HT_INFO_IE));
+                        *AddHtInfoLen = SIZE_ADD_HT_INFO_IE;
+                    }
+                }
+#endif // DOT11_N_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+                else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
+                {
+                    // Copy to pVIE which will report to microsoft bssid list.
+                    Ptr = (PUCHAR) pVIE;
+                    NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
+                    *LengthVIE += (pEid->Len + 2);
+                }
+                else if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) && (pEid->Len == 24))
+                {
+                    PUCHAR ptr;
+                    int i;
+
+                    // parsing EDCA parameters
+                    pEdcaParm->bValid          = TRUE;
+                    pEdcaParm->bQAck           = FALSE; // pEid->Octet[0] & 0x10;
+                    pEdcaParm->bQueueRequest   = FALSE; // pEid->Octet[0] & 0x20;
+                    pEdcaParm->bTxopRequest    = FALSE; // pEid->Octet[0] & 0x40;
+                    pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f;
+                    pEdcaParm->bAPSDCapable    = (pEid->Octet[6] & 0x80) ? 1 : 0;
+                    ptr = &pEid->Octet[8];
+                    for (i=0; i<4; i++)
+                    {
+                        UCHAR aci = (*ptr & 0x60) >> 5; // b5~6 is AC INDEX
+                        pEdcaParm->bACM[aci]  = (((*ptr) & 0x10) == 0x10);   // b5 is ACM
+                        pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f;               // b0~3 is AIFSN
+                        pEdcaParm->Cwmin[aci] = *(ptr+1) & 0x0f;             // b0~4 is Cwmin
+                        pEdcaParm->Cwmax[aci] = *(ptr+1) >> 4;               // b5~8 is Cwmax
+                        pEdcaParm->Txop[aci]  = *(ptr+2) + 256 * (*(ptr+3)); // in unit of 32-us
+                        ptr += 4; // point to next AC
+                    }
+                }
+                else if (NdisEqualMemory(pEid->Octet, WME_INFO_ELEM, 6) && (pEid->Len == 7))
+                {
+                    // parsing EDCA parameters
+                    pEdcaParm->bValid          = TRUE;
+                    pEdcaParm->bQAck           = FALSE; // pEid->Octet[0] & 0x10;
+                    pEdcaParm->bQueueRequest   = FALSE; // pEid->Octet[0] & 0x20;
+                    pEdcaParm->bTxopRequest    = FALSE; // pEid->Octet[0] & 0x40;
+                    pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f;
+                    pEdcaParm->bAPSDCapable    = (pEid->Octet[6] & 0x80) ? 1 : 0;
+
+                    // use default EDCA parameter
+                    pEdcaParm->bACM[QID_AC_BE]  = 0;
+                    pEdcaParm->Aifsn[QID_AC_BE] = 3;
+                    pEdcaParm->Cwmin[QID_AC_BE] = CW_MIN_IN_BITS;
+                    pEdcaParm->Cwmax[QID_AC_BE] = CW_MAX_IN_BITS;
+                    pEdcaParm->Txop[QID_AC_BE]  = 0;
+
+                    pEdcaParm->bACM[QID_AC_BK]  = 0;
+                    pEdcaParm->Aifsn[QID_AC_BK] = 7;
+                    pEdcaParm->Cwmin[QID_AC_BK] = CW_MIN_IN_BITS;
+                    pEdcaParm->Cwmax[QID_AC_BK] = CW_MAX_IN_BITS;
+                    pEdcaParm->Txop[QID_AC_BK]  = 0;
+
+                    pEdcaParm->bACM[QID_AC_VI]  = 0;
+                    pEdcaParm->Aifsn[QID_AC_VI] = 2;
+                    pEdcaParm->Cwmin[QID_AC_VI] = CW_MIN_IN_BITS-1;
+                    pEdcaParm->Cwmax[QID_AC_VI] = CW_MAX_IN_BITS;
+                    pEdcaParm->Txop[QID_AC_VI]  = 96;   // AC_VI: 96*32us ~= 3ms
+
+                    pEdcaParm->bACM[QID_AC_VO]  = 0;
+                    pEdcaParm->Aifsn[QID_AC_VO] = 2;
+                    pEdcaParm->Cwmin[QID_AC_VO] = CW_MIN_IN_BITS-2;
+                    pEdcaParm->Cwmax[QID_AC_VO] = CW_MAX_IN_BITS-1;
+                    pEdcaParm->Txop[QID_AC_VO]  = 48;   // AC_VO: 48*32us ~= 1.5ms
+                }
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+                else
+                {
+                }
+
+                break;
+
+            case IE_EXT_SUPP_RATES:
+                if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
+                {
+                    NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len);
+                    *pExtRateLen = pEid->Len;
+
+                    // TODO: 2004-09-14 not a good design here, cause it exclude extra rates
+                    // from ScanTab. We should report as is. And filter out unsupported
+                    // rates in MlmeAux.
+                    // Check against the supported rates
+                    // RTMPCheckRates(pAd, ExtRate, pExtRateLen);
+                }
+                break;
+
+            case IE_ERP:
+                if (pEid->Len == 1)
+                {
+                    *pErp = (UCHAR)pEid->Octet[0];
+                }
+                break;
+
+            case IE_AIRONET_CKIP:
+                // 0. Check Aironet IE length, it must be larger or equal to 28
+                // Cisco AP350 used length as 28
+                // Cisco AP12XX used length as 30
+                if (pEid->Len < (CKIP_NEGOTIATION_LENGTH - 2))
+                    break;
+
+                // 1. Copy CKIP flag byte to buffer for process
+                *pCkipFlag = *(pEid->Octet + 8);
+                break;
+
+            case IE_AP_TX_POWER:
+                // AP Control of Client Transmit Power
+                //0. Check Aironet IE length, it must be 6
+                if (pEid->Len != 0x06)
+                    break;
+
+                // Get cell power limit in dBm
+                if (NdisEqualMemory(pEid->Octet, CISCO_OUI, 3) == 1)
+                    *pAironetCellPowerLimit = *(pEid->Octet + 4);
+                break;
+
+            // WPA2 & 802.11i RSN
+            case IE_RSN:
+                // There is no OUI for version anymore, check the group cipher OUI before copying
+                if (RTMPEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
+                {
+                    // Copy to pVIE which will report to microsoft bssid list.
+                    Ptr = (PUCHAR) pVIE;
+                    NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
+                    *LengthVIE += (pEid->Len + 2);
+                }
+                break;
+#ifdef CONFIG_STA_SUPPORT
+#ifdef EXT_BUILD_CHANNEL_LIST
+			case IE_COUNTRY:
+				Ptr = (PUCHAR) pVIE;
+                NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
+                *LengthVIE += (pEid->Len + 2);
+				break;
+#endif // EXT_BUILD_CHANNEL_LIST //
+#endif // CONFIG_STA_SUPPORT //
+            default:
+                break;
+        }
+
+        Length = Length + 2 + pEid->Len;  // Eid[1] + Len[1]+ content[Len]
+        pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
+    }
+
+    // For some 11a AP. it did not have the channel EID, patch here
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		UCHAR LatchRfChannel = MsgChannel;
+		if ((pAd->LatchRfRegs.Channel > 14) && ((Sanity & 0x4) == 0))
+		{
+			if (CtrlChannel != 0)
+				*pChannel = CtrlChannel;
+			else
+				*pChannel = LatchRfChannel;
+			Sanity |= 0x4;
+		}
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	if (Sanity != 0x7)
+	{
+		DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n", Sanity));
+		return FALSE;
+	}
+	else
+	{
+		return TRUE;
+	}
+
+}
+
+#ifdef DOT11N_DRAFT3
+/*
+	==========================================================================
+	Description:
+		MLME message sanity check for some IE addressed  in 802.11n d3.03.
+	Return:
+		TRUE if all parameters are OK, FALSE otherwise
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+BOOLEAN PeerBeaconAndProbeRspSanity2(
+	IN PRTMP_ADAPTER pAd,
+	IN VOID *Msg,
+	IN ULONG MsgLen,
+	OUT UCHAR 	*RegClass)
+{
+	CHAR				*Ptr;
+	PFRAME_802_11		pFrame;
+	PEID_STRUCT			pEid;
+	ULONG				Length = 0;
+
+	pFrame = (PFRAME_802_11)Msg;
+
+	*RegClass = 0;
+	Ptr = pFrame->Octet;
+	Length += LENGTH_802_11;
+
+	// get timestamp from payload and advance the pointer
+	Ptr += TIMESTAMP_LEN;
+	Length += TIMESTAMP_LEN;
+
+	// get beacon interval from payload and advance the pointer
+	Ptr += 2;
+	Length += 2;
+
+	// get capability info from payload and advance the pointer
+	Ptr += 2;
+	Length += 2;
+
+	pEid = (PEID_STRUCT) Ptr;
+
+	// get variable fields from payload and advance the pointer
+	while ((Length + 2 + pEid->Len) <= MsgLen)
+	{
+		switch(pEid->Eid)
+		{
+			case IE_SUPP_REG_CLASS:
+				if(pEid->Len > 0)
+				{
+					*RegClass = *pEid->Octet;
+				}
+				else
+				{
+					DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n",pEid->Len));
+					return FALSE;
+				}
+				break;
+		}
+
+		Length = Length + 2 + pEid->Len;  // Eid[1] + Len[1]+ content[Len]
+		pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
+	}
+
+	return TRUE;
+
+}
+#endif // DOT11N_DRAFT3 //
+
+/*
+    ==========================================================================
+    Description:
+        MLME message sanity check
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+ */
+BOOLEAN MlmeScanReqSanity(
+	IN PRTMP_ADAPTER pAd,
+	IN VOID *Msg,
+	IN ULONG MsgLen,
+	OUT UCHAR *pBssType,
+	OUT CHAR Ssid[],
+	OUT UCHAR *pSsidLen,
+	OUT UCHAR *pScanType)
+{
+	MLME_SCAN_REQ_STRUCT *Info;
+
+	Info = (MLME_SCAN_REQ_STRUCT *)(Msg);
+	*pBssType = Info->BssType;
+	*pSsidLen = Info->SsidLen;
+	NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen);
+	*pScanType = Info->ScanType;
+
+	if ((*pBssType == BSS_INFRA || *pBssType == BSS_ADHOC || *pBssType == BSS_ANY)
+		&& (*pScanType == SCAN_ACTIVE || *pScanType == SCAN_PASSIVE
+#ifdef CONFIG_STA_SUPPORT
+		|| *pScanType == SCAN_CISCO_PASSIVE || *pScanType == SCAN_CISCO_ACTIVE
+		|| *pScanType == SCAN_CISCO_CHANNEL_LOAD || *pScanType == SCAN_CISCO_NOISE
+#endif // CONFIG_STA_SUPPORT //
+		))
+	{
+		return TRUE;
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqSanity fail - wrong BssType or ScanType\n"));
+		return FALSE;
+	}
+}
+
+// IRQL = DISPATCH_LEVEL
+UCHAR ChannelSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN UCHAR channel)
+{
+    int i;
+
+    for (i = 0; i < pAd->ChannelListNum; i ++)
+    {
+        if (channel == pAd->ChannelList[i].Channel)
+            return 1;
+    }
+    return 0;
+}
+
+/*
+    ==========================================================================
+    Description:
+        MLME message sanity check
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+BOOLEAN PeerDeauthSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *Msg,
+    IN ULONG MsgLen,
+    OUT PUCHAR pAddr2,
+    OUT USHORT *pReason)
+{
+    PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
+
+    COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
+    NdisMoveMemory(pReason, &pFrame->Octet[0], 2);
+
+    return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        MLME message sanity check
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+BOOLEAN PeerAuthSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *Msg,
+    IN ULONG MsgLen,
+    OUT PUCHAR pAddr,
+    OUT USHORT *pAlg,
+    OUT USHORT *pSeq,
+    OUT USHORT *pStatus,
+    CHAR *pChlgText)
+{
+    PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
+
+    COPY_MAC_ADDR(pAddr,   pFrame->Hdr.Addr2);
+    NdisMoveMemory(pAlg,    &pFrame->Octet[0], 2);
+    NdisMoveMemory(pSeq,    &pFrame->Octet[2], 2);
+    NdisMoveMemory(pStatus, &pFrame->Octet[4], 2);
+
+    if ((*pAlg == Ndis802_11AuthModeOpen)
+#ifdef LEAP_SUPPORT
+      || (*pAlg == CISCO_AuthModeLEAP)
+#endif // LEAP_SUPPORT //
+      )
+    {
+        if (*pSeq == 1 || *pSeq == 2)
+        {
+            return TRUE;
+        }
+        else
+        {
+            DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n"));
+            return FALSE;
+        }
+    }
+    else if (*pAlg == Ndis802_11AuthModeShared)
+    {
+        if (*pSeq == 1 || *pSeq == 4)
+        {
+            return TRUE;
+        }
+        else if (*pSeq == 2 || *pSeq == 3)
+        {
+            NdisMoveMemory(pChlgText, &pFrame->Octet[8], CIPHER_TEXT_LEN);
+            return TRUE;
+        }
+        else
+        {
+            DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n"));
+            return FALSE;
+        }
+    }
+    else
+    {
+        DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong algorithm\n"));
+        return FALSE;
+    }
+}
+
+/*
+    ==========================================================================
+    Description:
+        MLME message sanity check
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+ */
+BOOLEAN MlmeAuthReqSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *Msg,
+    IN ULONG MsgLen,
+    OUT PUCHAR pAddr,
+    OUT ULONG *pTimeout,
+    OUT USHORT *pAlg)
+{
+    MLME_AUTH_REQ_STRUCT *pInfo;
+
+    pInfo  = (MLME_AUTH_REQ_STRUCT *)Msg;
+    COPY_MAC_ADDR(pAddr, pInfo->Addr);
+    *pTimeout = pInfo->Timeout;
+    *pAlg = pInfo->Alg;
+
+    if (((*pAlg == Ndis802_11AuthModeShared) ||(*pAlg == Ndis802_11AuthModeOpen)
+#ifdef LEAP_SUPPORT
+     || (*pAlg == CISCO_AuthModeLEAP)
+#endif // LEAP_SUPPORT //
+     	) &&
+        ((*pAddr & 0x01) == 0))
+    {
+        return TRUE;
+    }
+    else
+    {
+        DBGPRINT(RT_DEBUG_TRACE, ("MlmeAuthReqSanity fail - wrong algorithm\n"));
+        return FALSE;
+    }
+}
+
+/*
+    ==========================================================================
+    Description:
+        MLME message sanity check
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+BOOLEAN MlmeAssocReqSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *Msg,
+    IN ULONG MsgLen,
+    OUT PUCHAR pApAddr,
+    OUT USHORT *pCapabilityInfo,
+    OUT ULONG *pTimeout,
+    OUT USHORT *pListenIntv)
+{
+    MLME_ASSOC_REQ_STRUCT *pInfo;
+
+    pInfo = (MLME_ASSOC_REQ_STRUCT *)Msg;
+    *pTimeout = pInfo->Timeout;                             // timeout
+    COPY_MAC_ADDR(pApAddr, pInfo->Addr);                   // AP address
+    *pCapabilityInfo = pInfo->CapabilityInfo;               // capability info
+    *pListenIntv = pInfo->ListenIntv;
+
+    return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        MLME message sanity check
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+BOOLEAN PeerDisassocSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *Msg,
+    IN ULONG MsgLen,
+    OUT PUCHAR pAddr2,
+    OUT USHORT *pReason)
+{
+    PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
+
+    COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
+    NdisMoveMemory(pReason, &pFrame->Octet[0], 2);
+
+    return TRUE;
+}
+
+/*
+	========================================================================
+	Routine Description:
+		Sanity check NetworkType (11b, 11g or 11a)
+
+	Arguments:
+		pBss - Pointer to BSS table.
+
+	Return Value:
+        Ndis802_11DS .......(11b)
+        Ndis802_11OFDM24....(11g)
+        Ndis802_11OFDM5.....(11a)
+
+	IRQL = DISPATCH_LEVEL
+
+	========================================================================
+*/
+NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(
+    IN PBSS_ENTRY pBss)
+{
+	NDIS_802_11_NETWORK_TYPE	NetWorkType;
+	UCHAR						rate, i;
+
+	NetWorkType = Ndis802_11DS;
+
+	if (pBss->Channel <= 14)
+	{
+		//
+		// First check support Rate.
+		//
+		for (i = 0; i < pBss->SupRateLen; i++)
+		{
+			rate = pBss->SupRate[i] & 0x7f; // Mask out basic rate set bit
+			if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22))
+			{
+				continue;
+			}
+			else
+			{
+				//
+				// Otherwise (even rate > 108) means Ndis802_11OFDM24
+				//
+				NetWorkType = Ndis802_11OFDM24;
+				break;
+			}
+		}
+
+		//
+		// Second check Extend Rate.
+		//
+		if (NetWorkType != Ndis802_11OFDM24)
+		{
+			for (i = 0; i < pBss->ExtRateLen; i++)
+			{
+				rate = pBss->SupRate[i] & 0x7f; // Mask out basic rate set bit
+				if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22))
+				{
+					continue;
+				}
+				else
+				{
+					//
+					// Otherwise (even rate > 108) means Ndis802_11OFDM24
+					//
+					NetWorkType = Ndis802_11OFDM24;
+					break;
+				}
+			}
+		}
+	}
+	else
+	{
+		NetWorkType = Ndis802_11OFDM5;
+	}
+
+    if (pBss->HtCapabilityLen != 0)
+    {
+        if (NetWorkType == Ndis802_11OFDM5)
+            NetWorkType = Ndis802_11OFDM5_N;
+        else
+            NetWorkType = Ndis802_11OFDM24_N;
+    }
+
+	return NetWorkType;
+}
+
+/*
+    ==========================================================================
+    Description:
+        WPA message sanity check
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+ */
+BOOLEAN PeerWpaMessageSanity(
+    IN 	PRTMP_ADAPTER 		pAd,
+    IN 	PEAPOL_PACKET 		pMsg,
+    IN 	ULONG 				MsgLen,
+    IN 	UCHAR				MsgType,
+    IN 	MAC_TABLE_ENTRY  	*pEntry)
+{
+	UCHAR			mic[LEN_KEY_DESC_MIC], digest[80], KEYDATA[MAX_LEN_OF_RSNIE];
+	BOOLEAN			bReplayDiff = FALSE;
+	BOOLEAN			bWPA2 = FALSE;
+	KEY_INFO		EapolKeyInfo;
+	UCHAR			GroupKeyIndex = 0;
+
+
+	NdisZeroMemory(mic, sizeof(mic));
+	NdisZeroMemory(digest, sizeof(digest));
+	NdisZeroMemory(KEYDATA, sizeof(KEYDATA));
+	NdisZeroMemory((PUCHAR)&EapolKeyInfo, sizeof(EapolKeyInfo));
+
+	NdisMoveMemory((PUCHAR)&EapolKeyInfo, (PUCHAR)&pMsg->KeyDesc.KeyInfo, sizeof(KEY_INFO));
+
+	*((USHORT *)&EapolKeyInfo) = cpu2le16(*((USHORT *)&EapolKeyInfo));
+
+	// Choose WPA2 or not
+	if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
+		bWPA2 = TRUE;
+
+	// 0. Check MsgType
+	if ((MsgType > EAPOL_GROUP_MSG_2) || (MsgType < EAPOL_PAIR_MSG_1))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("The message type is invalid(%d)! \n", MsgType));
+		return FALSE;
+	}
+
+	// 1. Replay counter check
+ 	if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1)	// For supplicant
+    {
+    	// First validate replay counter, only accept message with larger replay counter.
+		// Let equal pass, some AP start with all zero replay counter
+		UCHAR	ZeroReplay[LEN_KEY_DESC_REPLAY];
+
+        NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
+		if ((RTMPCompareMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY) != 1) &&
+			(RTMPCompareMemory(pMsg->KeyDesc.ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
+    	{
+			bReplayDiff = TRUE;
+    	}
+ 	}
+	else if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2)	// For authenticator
+	{
+		// check Replay Counter coresponds to MSG from authenticator, otherwise discard
+    	if (!NdisEqualMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY))
+    	{
+			bReplayDiff = TRUE;
+    	}
+	}
+
+	// Replay Counter different condition
+	if (bReplayDiff)
+	{
+		// send wireless event - for replay counter different
+		if (pAd->CommonCfg.bWirelessEvent)
+			RTMPSendWirelessEvent(pAd, IW_REPLAY_COUNTER_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
+
+		if (MsgType < EAPOL_GROUP_MSG_1)
+		{
+           	DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in pairwise msg %d of 4-way handshake!\n", MsgType));
+		}
+		else
+		{
+			DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in group msg %d of 2-way handshake!\n", (MsgType - EAPOL_PAIR_MSG_4)));
+		}
+
+		hex_dump("Receive replay counter ", pMsg->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+		hex_dump("Current replay counter ", pEntry->R_Counter, LEN_KEY_DESC_REPLAY);
+        return FALSE;
+	}
+
+	// 2. Verify MIC except Pairwise Msg1
+	if (MsgType != EAPOL_PAIR_MSG_1)
+	{
+		UCHAR			rcvd_mic[LEN_KEY_DESC_MIC];
+
+		// Record the received MIC for check later
+		NdisMoveMemory(rcvd_mic, pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+		NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+
+        if (pEntry->WepStatus == Ndis802_11Encryption2Enabled)	// TKIP
+        {
+            hmac_md5(pEntry->PTK, LEN_EAP_MICK, (PUCHAR)pMsg, MsgLen, mic);
+        }
+        else if (pEntry->WepStatus == Ndis802_11Encryption3Enabled)	// AES
+        {
+            HMAC_SHA1((PUCHAR)pMsg, MsgLen, pEntry->PTK, LEN_EAP_MICK, digest);
+            NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
+        }
+
+        if (!NdisEqualMemory(rcvd_mic, mic, LEN_KEY_DESC_MIC))
+        {
+			// send wireless event - for MIC different
+			if (pAd->CommonCfg.bWirelessEvent)
+				RTMPSendWirelessEvent(pAd, IW_MIC_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
+
+			if (MsgType < EAPOL_GROUP_MSG_1)
+			{
+            	DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in pairwise msg %d of 4-way handshake!\n", MsgType));
+			}
+			else
+			{
+				DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in group msg %d of 2-way handshake!\n", (MsgType - EAPOL_PAIR_MSG_4)));
+			}
+
+			hex_dump("Received MIC", rcvd_mic, LEN_KEY_DESC_MIC);
+			hex_dump("Desired  MIC", mic, LEN_KEY_DESC_MIC);
+
+			return FALSE;
+        }
+	}
+
+	// Extract the context of the Key Data field if it exist
+	// The field in pairwise_msg_2_WPA1(WPA2) & pairwise_msg_3_WPA1 is un-encrypted.
+	// The field in group_msg_1_WPA1(WPA2) & pairwise_msg_3_WPA2 is encrypted.
+	if (pMsg->KeyDesc.KeyDataLen[1] > 0)
+	{
+		// Decrypt this field
+		if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1))
+		{
+			if(pEntry->WepStatus == Ndis802_11Encryption3Enabled)
+			{
+				// AES
+				AES_GTK_KEY_UNWRAP(&pEntry->PTK[16], KEYDATA, pMsg->KeyDesc.KeyDataLen[1],pMsg->KeyDesc.KeyData);
+			}
+			else
+			{
+				INT 	i;
+				UCHAR   Key[32];
+				// Decrypt TKIP GTK
+				// Construct 32 bytes RC4 Key
+				NdisMoveMemory(Key, pMsg->KeyDesc.KeyIv, 16);
+				NdisMoveMemory(&Key[16], &pEntry->PTK[16], 16);
+				ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
+				//discard first 256 bytes
+				for(i = 0; i < 256; i++)
+					ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
+				// Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
+				ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, pMsg->KeyDesc.KeyData, pMsg->KeyDesc.KeyDataLen[1]);
+			}
+
+			if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))
+				GroupKeyIndex = EapolKeyInfo.KeyIndex;
+
+		}
+		else if ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3 && !bWPA2))
+		{
+			NdisMoveMemory(KEYDATA, pMsg->KeyDesc.KeyData, pMsg->KeyDesc.KeyDataLen[1]);
+		}
+		else
+		{
+
+			return TRUE;
+		}
+
+		// Parse Key Data field to
+		// 1. verify RSN IE for pairwise_msg_2_WPA1(WPA2) ,pairwise_msg_3_WPA1(WPA2)
+		// 2. verify KDE format for pairwise_msg_3_WPA2, group_msg_1_WPA2
+		// 3. update shared key for pairwise_msg_3_WPA2, group_msg_1_WPA1(WPA2)
+		if (!RTMPParseEapolKeyData(pAd, KEYDATA, pMsg->KeyDesc.KeyDataLen[1], GroupKeyIndex, MsgType, bWPA2, pEntry))
+		{
+			return FALSE;
+		}
+	}
+
+	return TRUE;
+
+}
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+BOOLEAN MlmeDlsReqSanity(
+	IN PRTMP_ADAPTER pAd,
+    IN VOID *Msg,
+    IN ULONG MsgLen,
+    OUT PRT_802_11_DLS *pDLS,
+    OUT PUSHORT pReason)
+{
+	MLME_DLS_REQ_STRUCT *pInfo;
+
+    pInfo = (MLME_DLS_REQ_STRUCT *)Msg;
+
+	*pDLS = pInfo->pDLS;
+	*pReason = pInfo->Reason;
+
+	return TRUE;
+}
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef QOS_DLS_SUPPORT
+BOOLEAN PeerDlsReqSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *Msg,
+    IN ULONG MsgLen,
+    OUT PUCHAR pDA,
+    OUT PUCHAR pSA,
+    OUT USHORT *pCapabilityInfo,
+    OUT USHORT *pDlsTimeout,
+    OUT UCHAR *pRatesLen,
+    OUT UCHAR Rates[],
+	OUT UCHAR *pHtCapabilityLen,
+    OUT HT_CAPABILITY_IE *pHtCapability)
+{
+	CHAR            *Ptr;
+    PFRAME_802_11	Fr = (PFRAME_802_11)Msg;
+	PEID_STRUCT  eid_ptr;
+
+    // to prevent caller from using garbage output value
+    *pCapabilityInfo	= 0;
+    *pDlsTimeout	= 0;
+	*pHtCapabilityLen = 0;
+
+    Ptr = Fr->Octet;
+
+	// offset to destination MAC address (Category and Action field)
+    Ptr += 2;
+
+    // get DA from payload and advance the pointer
+    NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN);
+    Ptr += MAC_ADDR_LEN;
+
+    // get SA from payload and advance the pointer
+    NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN);
+    Ptr += MAC_ADDR_LEN;
+
+    // get capability info from payload and advance the pointer
+    NdisMoveMemory(pCapabilityInfo, Ptr, 2);
+    Ptr += 2;
+
+    // get capability info from payload and advance the pointer
+    NdisMoveMemory(pDlsTimeout, Ptr, 2);
+    Ptr += 2;
+
+	// Category and Action field + DA + SA + capability + Timeout
+	eid_ptr = (PEID_STRUCT) &Fr->Octet[18];
+
+	while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((UCHAR*)Fr + MsgLen))
+	{
+		switch(eid_ptr->Eid)
+		{
+			case IE_SUPP_RATES:
+                if ((eid_ptr->Len <= MAX_LEN_OF_SUPPORTED_RATES) && (eid_ptr->Len > 0))
+                {
+                    NdisMoveMemory(Rates, eid_ptr->Octet, eid_ptr->Len);
+                    DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - IE_SUPP_RATES., Len=%d. Rates[0]=%x\n",eid_ptr->Len, Rates[0]));
+                    DBGPRINT(RT_DEBUG_TRACE, ("Rates[1]=%x %x %x %x %x %x %x\n", Rates[1], Rates[2], Rates[3], Rates[4], Rates[5], Rates[6], Rates[7]));
+                    *pRatesLen = eid_ptr->Len;
+                }
+                else
+                {
+                    *pRatesLen = 8;
+					Rates[0] = 0x82;
+					Rates[1] = 0x84;
+					Rates[2] = 0x8b;
+					Rates[3] = 0x96;
+					Rates[4] = 0x12;
+					Rates[5] = 0x24;
+					Rates[6] = 0x48;
+					Rates[7] = 0x6c;
+                    DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - wrong IE_SUPP_RATES., Len=%d\n",eid_ptr->Len));
+                }
+				break;
+
+			case IE_EXT_SUPP_RATES:
+                if (eid_ptr->Len + *pRatesLen <= MAX_LEN_OF_SUPPORTED_RATES)
+                {
+                    NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, eid_ptr->Len);
+                    *pRatesLen = (*pRatesLen) + eid_ptr->Len;
+                }
+                else
+                {
+                    NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, MAX_LEN_OF_SUPPORTED_RATES - (*pRatesLen));
+                    *pRatesLen = MAX_LEN_OF_SUPPORTED_RATES;
+                }
+				break;
+
+			case IE_HT_CAP:
+				if (eid_ptr->Len >= sizeof(HT_CAPABILITY_IE))
+				{
+					NdisMoveMemory(pHtCapability, eid_ptr->Octet, sizeof(HT_CAPABILITY_IE));
+
+					*(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
+					*(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
+					*pHtCapabilityLen = sizeof(HT_CAPABILITY_IE);
+
+					DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - IE_HT_CAP\n"));
+				}
+				else
+				{
+					DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - wrong IE_HT_CAP.eid_ptr->Len = %d\n", eid_ptr->Len));
+				}
+				break;
+
+			default:
+				break;
+		}
+
+		eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+	}
+
+    return TRUE;
+}
+
+BOOLEAN PeerDlsRspSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *Msg,
+    IN ULONG MsgLen,
+    OUT PUCHAR pDA,
+    OUT PUCHAR pSA,
+    OUT USHORT *pCapabilityInfo,
+    OUT USHORT *pStatus,
+    OUT UCHAR *pRatesLen,
+    OUT UCHAR Rates[],
+    OUT UCHAR *pHtCapabilityLen,
+    OUT HT_CAPABILITY_IE *pHtCapability)
+{
+    CHAR            *Ptr;
+    PFRAME_802_11	Fr = (PFRAME_802_11)Msg;
+	PEID_STRUCT  eid_ptr;
+
+    // to prevent caller from using garbage output value
+    *pStatus		= 0;
+    *pCapabilityInfo	= 0;
+	*pHtCapabilityLen = 0;
+
+    Ptr = Fr->Octet;
+
+	// offset to destination MAC address (Category and Action field)
+    Ptr += 2;
+
+	// get status code from payload and advance the pointer
+    NdisMoveMemory(pStatus, Ptr, 2);
+    Ptr += 2;
+
+    // get DA from payload and advance the pointer
+    NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN);
+    Ptr += MAC_ADDR_LEN;
+
+    // get SA from payload and advance the pointer
+    NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN);
+    Ptr += MAC_ADDR_LEN;
+
+	if (pStatus == 0)
+	{
+	    // get capability info from payload and advance the pointer
+	    NdisMoveMemory(pCapabilityInfo, Ptr, 2);
+	    Ptr += 2;
+	}
+
+	// Category and Action field + status code + DA + SA + capability
+	eid_ptr = (PEID_STRUCT) &Fr->Octet[18];
+
+	while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((UCHAR*)Fr + MsgLen))
+	{
+		switch(eid_ptr->Eid)
+		{
+			case IE_SUPP_RATES:
+                if ((eid_ptr->Len <= MAX_LEN_OF_SUPPORTED_RATES) && (eid_ptr->Len > 0))
+                {
+                    NdisMoveMemory(Rates, eid_ptr->Octet, eid_ptr->Len);
+                    DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - IE_SUPP_RATES., Len=%d. Rates[0]=%x\n",eid_ptr->Len, Rates[0]));
+                    DBGPRINT(RT_DEBUG_TRACE, ("Rates[1]=%x %x %x %x %x %x %x\n", Rates[1], Rates[2], Rates[3], Rates[4], Rates[5], Rates[6], Rates[7]));
+                    *pRatesLen = eid_ptr->Len;
+                }
+                else
+                {
+                    *pRatesLen = 8;
+					Rates[0] = 0x82;
+					Rates[1] = 0x84;
+					Rates[2] = 0x8b;
+					Rates[3] = 0x96;
+					Rates[4] = 0x12;
+					Rates[5] = 0x24;
+					Rates[6] = 0x48;
+					Rates[7] = 0x6c;
+                    DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - wrong IE_SUPP_RATES., Len=%d\n",eid_ptr->Len));
+                }
+				break;
+
+			case IE_EXT_SUPP_RATES:
+                if (eid_ptr->Len + *pRatesLen <= MAX_LEN_OF_SUPPORTED_RATES)
+                {
+                    NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, eid_ptr->Len);
+                    *pRatesLen = (*pRatesLen) + eid_ptr->Len;
+                }
+                else
+                {
+                    NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, MAX_LEN_OF_SUPPORTED_RATES - (*pRatesLen));
+                    *pRatesLen = MAX_LEN_OF_SUPPORTED_RATES;
+                }
+				break;
+
+			case IE_HT_CAP:
+				if (eid_ptr->Len >= sizeof(HT_CAPABILITY_IE))
+				{
+					NdisMoveMemory(pHtCapability, eid_ptr->Octet, sizeof(HT_CAPABILITY_IE));
+
+					*(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
+					*(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
+					*pHtCapabilityLen = sizeof(HT_CAPABILITY_IE);
+
+					DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - IE_HT_CAP\n"));
+				}
+				else
+				{
+					DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - wrong IE_HT_CAP.eid_ptr->Len = %d\n", eid_ptr->Len));
+				}
+				break;
+
+			default:
+				break;
+		}
+
+		eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+	}
+
+    return TRUE;
+}
+
+BOOLEAN PeerDlsTearDownSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *Msg,
+    IN ULONG MsgLen,
+    OUT PUCHAR pDA,
+    OUT PUCHAR pSA,
+    OUT USHORT *pReason)
+{
+    CHAR            *Ptr;
+    PFRAME_802_11	Fr = (PFRAME_802_11)Msg;
+
+    // to prevent caller from using garbage output value
+    *pReason	= 0;
+
+    Ptr = Fr->Octet;
+
+	// offset to destination MAC address (Category and Action field)
+    Ptr += 2;
+
+    // get DA from payload and advance the pointer
+    NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN);
+    Ptr += MAC_ADDR_LEN;
+
+    // get SA from payload and advance the pointer
+    NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN);
+    Ptr += MAC_ADDR_LEN;
+
+	// get reason code from payload and advance the pointer
+    NdisMoveMemory(pReason, Ptr, 2);
+    Ptr += 2;
+
+    return TRUE;
+}
+#endif // QOS_DLS_SUPPORT //
+
diff --git a/drivers/staging/rt3070/common/cmm_sync.c b/drivers/staging/rt3070/common/cmm_sync.c
new file mode 100644
index 0000000..2be7c77
--- /dev/null
+++ b/drivers/staging/rt3070/common/cmm_sync.c
@@ -0,0 +1,711 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	sync.c
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	John Chang	2004-09-01      modified for rt2561/2661
+*/
+#include "../rt_config.h"
+
+// 2.4 Ghz channel plan index in the TxPower arrays.
+#define	BG_BAND_REGION_0_START	0			// 1,2,3,4,5,6,7,8,9,10,11
+#define	BG_BAND_REGION_0_SIZE	11
+#define	BG_BAND_REGION_1_START	0			// 1,2,3,4,5,6,7,8,9,10,11,12,13
+#define	BG_BAND_REGION_1_SIZE	13
+#define	BG_BAND_REGION_2_START	9			// 10,11
+#define	BG_BAND_REGION_2_SIZE	2
+#define	BG_BAND_REGION_3_START	9			// 10,11,12,13
+#define	BG_BAND_REGION_3_SIZE	4
+#define	BG_BAND_REGION_4_START	13			// 14
+#define	BG_BAND_REGION_4_SIZE	1
+#define	BG_BAND_REGION_5_START	0			// 1,2,3,4,5,6,7,8,9,10,11,12,13,14
+#define	BG_BAND_REGION_5_SIZE	14
+#define	BG_BAND_REGION_6_START	2			// 3,4,5,6,7,8,9
+#define	BG_BAND_REGION_6_SIZE	7
+#define	BG_BAND_REGION_7_START	4			// 5,6,7,8,9,10,11,12,13
+#define	BG_BAND_REGION_7_SIZE	9
+#define	BG_BAND_REGION_31_START	0			// 1,2,3,4,5,6,7,8,9,10,11,12,13,14
+#define	BG_BAND_REGION_31_SIZE	14
+
+// 5 Ghz channel plan index in the TxPower arrays.
+UCHAR A_BAND_REGION_0_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165};
+UCHAR A_BAND_REGION_1_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
+UCHAR A_BAND_REGION_2_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64};
+UCHAR A_BAND_REGION_3_CHANNEL_LIST[]={52, 56, 60, 64, 149, 153, 157, 161};
+UCHAR A_BAND_REGION_4_CHANNEL_LIST[]={149, 153, 157, 161, 165};
+UCHAR A_BAND_REGION_5_CHANNEL_LIST[]={149, 153, 157, 161};
+UCHAR A_BAND_REGION_6_CHANNEL_LIST[]={36, 40, 44, 48};
+UCHAR A_BAND_REGION_7_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165};
+UCHAR A_BAND_REGION_8_CHANNEL_LIST[]={52, 56, 60, 64};
+UCHAR A_BAND_REGION_9_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165};
+UCHAR A_BAND_REGION_10_CHANNEL_LIST[]={36, 40, 44, 48, 149, 153, 157, 161, 165};
+UCHAR A_BAND_REGION_11_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161};
+
+//BaSizeArray follows the 802.11n definition as MaxRxFactor.  2^(13+factor) bytes. When factor =0, it's about Ba buffer size =8.
+UCHAR BaSizeArray[4] = {8,16,32,64};
+
+/*
+	==========================================================================
+	Description:
+		Update StaCfg->ChannelList[] according to 1) Country Region 2) RF IC type,
+		and 3) PHY-mode user selected.
+		The outcome is used by driver when doing site survey.
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID BuildChannelList(
+	IN PRTMP_ADAPTER pAd)
+{
+	UCHAR i, j, index=0, num=0;
+	PUCHAR	pChannelList = NULL;
+
+	NdisZeroMemory(pAd->ChannelList, MAX_NUM_OF_CHANNELS * sizeof(CHANNEL_TX_POWER));
+
+	// if not 11a-only mode, channel list starts from 2.4Ghz band
+	if ((pAd->CommonCfg.PhyMode != PHY_11A)
+#ifdef DOT11_N_SUPPORT
+		&& (pAd->CommonCfg.PhyMode != PHY_11AN_MIXED) && (pAd->CommonCfg.PhyMode != PHY_11N_5G)
+#endif // DOT11_N_SUPPORT //
+	)
+	{
+		switch (pAd->CommonCfg.CountryRegion  & 0x7f)
+		{
+			case REGION_0_BG_BAND:	// 1 -11
+				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_0_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_0_SIZE);
+				index += BG_BAND_REGION_0_SIZE;
+				break;
+			case REGION_1_BG_BAND:	// 1 - 13
+				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_1_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_1_SIZE);
+				index += BG_BAND_REGION_1_SIZE;
+				break;
+			case REGION_2_BG_BAND:	// 10 - 11
+				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_2_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_2_SIZE);
+				index += BG_BAND_REGION_2_SIZE;
+				break;
+			case REGION_3_BG_BAND:	// 10 - 13
+				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_3_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_3_SIZE);
+				index += BG_BAND_REGION_3_SIZE;
+				break;
+			case REGION_4_BG_BAND:	// 14
+				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_4_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_4_SIZE);
+				index += BG_BAND_REGION_4_SIZE;
+				break;
+			case REGION_5_BG_BAND:	// 1 - 14
+				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_5_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_5_SIZE);
+				index += BG_BAND_REGION_5_SIZE;
+				break;
+			case REGION_6_BG_BAND:	// 3 - 9
+				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_6_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_6_SIZE);
+				index += BG_BAND_REGION_6_SIZE;
+				break;
+			case REGION_7_BG_BAND:  // 5 - 13
+				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_7_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_7_SIZE);
+				index += BG_BAND_REGION_7_SIZE;
+				break;
+			case REGION_31_BG_BAND:	// 1 - 14
+				NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_31_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_31_SIZE);
+				index += BG_BAND_REGION_31_SIZE;
+				break;
+			default:            // Error. should never happen
+				break;
+		}
+		for (i=0; i<index; i++)
+			pAd->ChannelList[i].MaxTxPwr = 20;
+	}
+
+	if ((pAd->CommonCfg.PhyMode == PHY_11A) || (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
+#ifdef DOT11_N_SUPPORT
+		|| (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED)
+		|| (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)
+#endif // DOT11_N_SUPPORT //
+	)
+	{
+		switch (pAd->CommonCfg.CountryRegionForABand & 0x7f)
+		{
+			case REGION_0_A_BAND:
+				num = sizeof(A_BAND_REGION_0_CHANNEL_LIST)/sizeof(UCHAR);
+				pChannelList = A_BAND_REGION_0_CHANNEL_LIST;
+				break;
+			case REGION_1_A_BAND:
+				num = sizeof(A_BAND_REGION_1_CHANNEL_LIST)/sizeof(UCHAR);
+				pChannelList = A_BAND_REGION_1_CHANNEL_LIST;
+				break;
+			case REGION_2_A_BAND:
+				num = sizeof(A_BAND_REGION_2_CHANNEL_LIST)/sizeof(UCHAR);
+				pChannelList = A_BAND_REGION_2_CHANNEL_LIST;
+				break;
+			case REGION_3_A_BAND:
+				num = sizeof(A_BAND_REGION_3_CHANNEL_LIST)/sizeof(UCHAR);
+				pChannelList = A_BAND_REGION_3_CHANNEL_LIST;
+				break;
+			case REGION_4_A_BAND:
+				num = sizeof(A_BAND_REGION_4_CHANNEL_LIST)/sizeof(UCHAR);
+				pChannelList = A_BAND_REGION_4_CHANNEL_LIST;
+				break;
+			case REGION_5_A_BAND:
+				num = sizeof(A_BAND_REGION_5_CHANNEL_LIST)/sizeof(UCHAR);
+				pChannelList = A_BAND_REGION_5_CHANNEL_LIST;
+				break;
+			case REGION_6_A_BAND:
+				num = sizeof(A_BAND_REGION_6_CHANNEL_LIST)/sizeof(UCHAR);
+				pChannelList = A_BAND_REGION_6_CHANNEL_LIST;
+				break;
+			case REGION_7_A_BAND:
+				num = sizeof(A_BAND_REGION_7_CHANNEL_LIST)/sizeof(UCHAR);
+				pChannelList = A_BAND_REGION_7_CHANNEL_LIST;
+				break;
+			case REGION_8_A_BAND:
+				num = sizeof(A_BAND_REGION_8_CHANNEL_LIST)/sizeof(UCHAR);
+				pChannelList = A_BAND_REGION_8_CHANNEL_LIST;
+				break;
+			case REGION_9_A_BAND:
+				num = sizeof(A_BAND_REGION_9_CHANNEL_LIST)/sizeof(UCHAR);
+				pChannelList = A_BAND_REGION_9_CHANNEL_LIST;
+				break;
+
+			case REGION_10_A_BAND:
+				num = sizeof(A_BAND_REGION_10_CHANNEL_LIST)/sizeof(UCHAR);
+				pChannelList = A_BAND_REGION_10_CHANNEL_LIST;
+				break;
+
+			case REGION_11_A_BAND:
+				num = sizeof(A_BAND_REGION_11_CHANNEL_LIST)/sizeof(UCHAR);
+				pChannelList = A_BAND_REGION_11_CHANNEL_LIST;
+				break;
+
+			default:            // Error. should never happen
+				DBGPRINT(RT_DEBUG_WARN,("countryregion=%d not support", pAd->CommonCfg.CountryRegionForABand));
+				break;
+		}
+
+		if (num != 0)
+		{
+			UCHAR RadarCh[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
+			for (i=0; i<num; i++)
+			{
+				for (j=0; j<MAX_NUM_OF_CHANNELS; j++)
+				{
+					if (pChannelList[i] == pAd->TxPower[j].Channel)
+						NdisMoveMemory(&pAd->ChannelList[index+i], &pAd->TxPower[j], sizeof(CHANNEL_TX_POWER));
+					}
+				for (j=0; j<15; j++)
+				{
+					if (pChannelList[i] == RadarCh[j])
+						pAd->ChannelList[index+i].DfsReq = TRUE;
+				}
+				pAd->ChannelList[index+i].MaxTxPwr = 20;
+			}
+			index += num;
+		}
+	}
+
+	pAd->ChannelListNum = index;
+	DBGPRINT(RT_DEBUG_TRACE,("country code=%d/%d, RFIC=%d, PHY mode=%d, support %d channels\n",
+		pAd->CommonCfg.CountryRegion, pAd->CommonCfg.CountryRegionForABand, pAd->RfIcType, pAd->CommonCfg.PhyMode, pAd->ChannelListNum));
+#ifdef DBG
+	for (i=0;i<pAd->ChannelListNum;i++)
+	{
+		DBGPRINT_RAW(RT_DEBUG_TRACE,("BuildChannel # %d :: Pwr0 = %d, Pwr1 =%d, \n ", pAd->ChannelList[i].Channel, pAd->ChannelList[i].Power, pAd->ChannelList[i].Power2));
+	}
+#endif
+}
+
+/*
+	==========================================================================
+	Description:
+		This routine return the first channel number according to the country
+		code selection and RF IC selection (signal band or dual band). It is called
+		whenever driver need to start a site survey of all supported channels.
+	Return:
+		ch - the first channel number of current country code setting
+
+	IRQL = PASSIVE_LEVEL
+
+	==========================================================================
+ */
+UCHAR FirstChannel(
+	IN PRTMP_ADAPTER pAd)
+{
+	return pAd->ChannelList[0].Channel;
+}
+
+/*
+	==========================================================================
+	Description:
+		This routine returns the next channel number. This routine is called
+		during driver need to start a site survey of all supported channels.
+	Return:
+		next_channel - the next channel number valid in current country code setting.
+	Note:
+		return 0 if no more next channel
+	==========================================================================
+ */
+UCHAR NextChannel(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR channel)
+{
+	int i;
+	UCHAR next_channel = 0;
+
+	for (i = 0; i < (pAd->ChannelListNum - 1); i++)
+		if (channel == pAd->ChannelList[i].Channel)
+		{
+			next_channel = pAd->ChannelList[i+1].Channel;
+			break;
+	}
+	return next_channel;
+}
+
+/*
+	==========================================================================
+	Description:
+		This routine is for Cisco Compatible Extensions 2.X
+		Spec31. AP Control of Client Transmit Power
+	Return:
+		None
+	Note:
+	   Required by Aironet dBm(mW)
+		   0dBm(1mW),   1dBm(5mW), 13dBm(20mW), 15dBm(30mW),
+		  17dBm(50mw), 20dBm(100mW)
+
+	   We supported
+		   3dBm(Lowest), 6dBm(10%), 9dBm(25%), 12dBm(50%),
+		  14dBm(75%),   15dBm(100%)
+
+		The client station's actual transmit power shall be within +/- 5dB of
+		the minimum value or next lower value.
+	==========================================================================
+ */
+VOID ChangeToCellPowerLimit(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR         AironetCellPowerLimit)
+{
+	//valud 0xFF means that hasn't found power limit information
+	//from the AP's Beacon/Probe response.
+	if (AironetCellPowerLimit == 0xFF)
+		return;
+
+	if (AironetCellPowerLimit < 6) //Used Lowest Power Percentage.
+		pAd->CommonCfg.TxPowerPercentage = 6;
+	else if (AironetCellPowerLimit < 9)
+		pAd->CommonCfg.TxPowerPercentage = 10;
+	else if (AironetCellPowerLimit < 12)
+		pAd->CommonCfg.TxPowerPercentage = 25;
+	else if (AironetCellPowerLimit < 14)
+		pAd->CommonCfg.TxPowerPercentage = 50;
+	else if (AironetCellPowerLimit < 15)
+		pAd->CommonCfg.TxPowerPercentage = 75;
+	else
+		pAd->CommonCfg.TxPowerPercentage = 100; //else used maximum
+
+	if (pAd->CommonCfg.TxPowerPercentage > pAd->CommonCfg.TxPowerDefault)
+		pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
+
+}
+
+CHAR	ConvertToRssi(
+	IN PRTMP_ADAPTER pAd,
+	IN	CHAR			Rssi,
+	IN  UCHAR   RssiNumber)
+{
+	UCHAR	RssiOffset, LNAGain;
+
+	// Rssi equals to zero should be an invalid value
+	if (Rssi == 0)
+		return -99;
+
+	LNAGain = GET_LNA_GAIN(pAd);
+    if (pAd->LatchRfRegs.Channel > 14)
+    {
+        if (RssiNumber == 0)
+			RssiOffset = pAd->ARssiOffset0;
+		else if (RssiNumber == 1)
+			RssiOffset = pAd->ARssiOffset1;
+		else
+			RssiOffset = pAd->ARssiOffset2;
+    }
+    else
+    {
+        if (RssiNumber == 0)
+			RssiOffset = pAd->BGRssiOffset0;
+		else if (RssiNumber == 1)
+			RssiOffset = pAd->BGRssiOffset1;
+		else
+			RssiOffset = pAd->BGRssiOffset2;
+    }
+
+    return (-12 - RssiOffset - LNAGain - Rssi);
+}
+
+/*
+	==========================================================================
+	Description:
+		Scan next channel
+	==========================================================================
+ */
+VOID ScanNextChannel(
+	IN PRTMP_ADAPTER pAd)
+{
+	HEADER_802_11   Hdr80211;
+	PUCHAR          pOutBuffer = NULL;
+	NDIS_STATUS     NStatus;
+	ULONG           FrameLen = 0;
+	UCHAR           SsidLen = 0, ScanType = pAd->MlmeAux.ScanType, BBPValue = 0;
+#ifdef CONFIG_STA_SUPPORT
+	USHORT          Status;
+	PHEADER_802_11  pHdr80211;
+#endif // CONFIG_STA_SUPPORT //
+	UINT			ScanTimeIn5gChannel = SHORT_CHANNEL_TIME;
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		if (MONITOR_ON(pAd))
+			return;
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef RALINK_ATE
+	// Nothing to do in ATE mode.
+	if (ATE_ON(pAd))
+		return;
+#endif // RALINK_ATE //
+
+	if (pAd->MlmeAux.Channel == 0)
+	{
+		if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
+#ifdef CONFIG_STA_SUPPORT
+			&& (INFRA_ON(pAd)
+				|| (pAd->OpMode == OPMODE_AP))
+#endif // CONFIG_STA_SUPPORT //
+			)
+		{
+			AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+			AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+			BBPValue &= (~0x18);
+			BBPValue |= 0x10;
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+			DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr));
+		}
+		else
+		{
+			AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+			AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+			DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to channel %d, Total BSS[%02d]\n",pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
+		}
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+			//
+			// To prevent data lost.
+			// Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
+			// Now, we need to send an NULL data with turned PSM bit off to AP, when scan progress done
+			//
+			if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd)))
+			{
+				NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);
+				if (NStatus	== NDIS_STATUS_SUCCESS)
+				{
+					pHdr80211 = (PHEADER_802_11) pOutBuffer;
+					MgtMacHeaderInit(pAd, pHdr80211, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
+					pHdr80211->Duration = 0;
+					pHdr80211->FC.Type = BTYPE_DATA;
+					pHdr80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
+
+					// Send using priority queue
+					MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
+					DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqAction -- Send PSM Data frame\n"));
+					MlmeFreeMemory(pAd, pOutBuffer);
+					RTMPusecDelay(5000);
+				}
+			}
+
+			pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+			Status = MLME_SUCCESS;
+			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
+		}
+#endif // CONFIG_STA_SUPPORT //
+
+
+		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+	}
+#ifdef RT2870
+#ifdef CONFIG_STA_SUPPORT
+	else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->OpMode == OPMODE_STA))
+	{
+		pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+		MlmeCntlConfirm(pAd, MT2_SCAN_CONF, MLME_FAIL_NO_RESOURCE);
+	}
+#endif // CONFIG_STA_SUPPORT //
+#endif // RT2870 //
+	else
+	{
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+		// BBP and RF are not accessible in PS mode, we has to wake them up first
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+			AsicForceWakeup(pAd, TRUE);
+
+			// leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON
+			if (pAd->StaCfg.Psm == PWR_SAVE)
+				MlmeSetPsmBit(pAd, PWR_ACTIVE);
+		}
+#endif // CONFIG_STA_SUPPORT //
+
+		AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE);
+		AsicLockChannel(pAd, pAd->MlmeAux.Channel);
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+			if (pAd->MlmeAux.Channel > 14)
+			{
+				if ((pAd->CommonCfg.bIEEE80211H == 1) && RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
+				{
+					ScanType = SCAN_PASSIVE;
+					ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
+				}
+			}
+
+#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
+			// carrier detection
+			if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
+			{
+				ScanType = SCAN_PASSIVE;
+				ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
+			}
+#endif // CARRIER_DETECTION_SUPPORT //
+		}
+
+#endif // CONFIG_STA_SUPPORT //
+
+		//Global country domain(ch1-11:active scan, ch12-14 passive scan)
+		if ((pAd->MlmeAux.Channel <= 14) && (pAd->MlmeAux.Channel >= 12) && ((pAd->CommonCfg.CountryRegion & 0x7f) == REGION_31_BG_BAND))
+		{
+			ScanType = SCAN_PASSIVE;
+		}
+
+		// We need to shorten active scan time in order for WZC connect issue
+		// Chnage the channel scan time for CISCO stuff based on its IAPP announcement
+		if (ScanType == FAST_SCAN_ACTIVE)
+			RTMPSetTimer(&pAd->MlmeAux.ScanTimer, FAST_ACTIVE_SCAN_TIME);
+#ifdef CONFIG_STA_SUPPORT
+		else if (((ScanType == SCAN_CISCO_ACTIVE) ||
+				(ScanType == SCAN_CISCO_PASSIVE) ||
+				(ScanType == SCAN_CISCO_CHANNEL_LOAD) ||
+				(ScanType == SCAN_CISCO_NOISE)) && (pAd->OpMode == OPMODE_STA))
+		{
+			if (pAd->StaCfg.CCXScanTime < 25)
+				RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime * 2);
+			else
+				RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime);
+		}
+#endif // CONFIG_STA_SUPPORT //
+		else // must be SCAN_PASSIVE or SCAN_ACTIVE
+		{
+			if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
+#ifdef DOT11_N_SUPPORT
+				|| (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED)
+#endif // DOT11_N_SUPPORT //
+			)
+			{
+				if (pAd->MlmeAux.Channel > 14)
+					RTMPSetTimer(&pAd->MlmeAux.ScanTimer, ScanTimeIn5gChannel);
+				else
+				RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MIN_CHANNEL_TIME);
+			}
+			else
+				RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MAX_CHANNEL_TIME);
+		}
+
+		if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE) ||
+			(ScanType == SCAN_CISCO_ACTIVE))
+		{
+			NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
+			if (NStatus != NDIS_STATUS_SUCCESS)
+			{
+				DBGPRINT(RT_DEBUG_TRACE, ("SYNC - ScanNextChannel() allocate memory fail\n"));
+#ifdef CONFIG_STA_SUPPORT
+				IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+				{
+					pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+					Status = MLME_FAIL_NO_RESOURCE;
+					MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
+				}
+#endif // CONFIG_STA_SUPPORT //
+
+				return;
+			}
+
+			// There is no need to send broadcast probe request if active scan is in effect.
+			if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE)
+				)
+				SsidLen = pAd->MlmeAux.SsidLen;
+			else
+				SsidLen = 0;
+
+			MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
+			MakeOutgoingFrame(pOutBuffer,               &FrameLen,
+							  sizeof(HEADER_802_11),    &Hdr80211,
+							  1,                        &SsidIe,
+							  1,                        &SsidLen,
+							  SsidLen,			        pAd->MlmeAux.Ssid,
+							  1,                        &SupRateIe,
+							  1,                        &pAd->CommonCfg.SupRateLen,
+							  pAd->CommonCfg.SupRateLen,  pAd->CommonCfg.SupRate,
+							  END_OF_ARGS);
+
+			if (pAd->CommonCfg.ExtRateLen)
+			{
+				ULONG Tmp;
+				MakeOutgoingFrame(pOutBuffer + FrameLen,            &Tmp,
+								  1,                                &ExtRateIe,
+								  1,                                &pAd->CommonCfg.ExtRateLen,
+								  pAd->CommonCfg.ExtRateLen,          pAd->CommonCfg.ExtRate,
+								  END_OF_ARGS);
+				FrameLen += Tmp;
+			}
+
+#ifdef DOT11_N_SUPPORT
+			if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+			{
+				ULONG	Tmp;
+				UCHAR	HtLen;
+				UCHAR	BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
+#ifdef RT_BIG_ENDIAN
+				HT_CAPABILITY_IE HtCapabilityTmp;
+#endif
+				if (pAd->bBroadComHT == TRUE)
+				{
+					HtLen = pAd->MlmeAux.HtCapabilityLen + 4;
+#ifdef RT_BIG_ENDIAN
+					NdisMoveMemory(&HtCapabilityTmp, &pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
+					*(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
+					*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
+
+					MakeOutgoingFrame(pOutBuffer + FrameLen,          &Tmp,
+									1,                                &WpaIe,
+									1,                                &HtLen,
+									4,                                &BROADCOM[0],
+									pAd->MlmeAux.HtCapabilityLen,     &HtCapabilityTmp,
+									END_OF_ARGS);
+#else
+					MakeOutgoingFrame(pOutBuffer + FrameLen,          &Tmp,
+									1,                                &WpaIe,
+									1,                                &HtLen,
+									4,                                &BROADCOM[0],
+									pAd->MlmeAux.HtCapabilityLen,     &pAd->MlmeAux.HtCapability,
+									END_OF_ARGS);
+#endif // RT_BIG_ENDIAN //
+				}
+				else
+				{
+					HtLen = pAd->MlmeAux.HtCapabilityLen;
+#ifdef RT_BIG_ENDIAN
+					NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, SIZE_HT_CAP_IE);
+					*(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
+					*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
+
+					MakeOutgoingFrame(pOutBuffer + FrameLen,          &Tmp,
+									1,                                &HtCapIe,
+									1,                                &HtLen,
+									HtLen,                            &HtCapabilityTmp,
+									END_OF_ARGS);
+#else
+					MakeOutgoingFrame(pOutBuffer + FrameLen,          &Tmp,
+									1,                                &HtCapIe,
+									1,                                &HtLen,
+									HtLen,                            &pAd->CommonCfg.HtCapability,
+									END_OF_ARGS);
+#endif // RT_BIG_ENDIAN //
+				}
+				FrameLen += Tmp;
+
+#ifdef DOT11N_DRAFT3
+				if (pAd->CommonCfg.BACapability.field.b2040CoexistScanSup == 1)
+				{
+					ULONG		Tmp;
+					HtLen = 1;
+					MakeOutgoingFrame(pOutBuffer + FrameLen,            &Tmp,
+									  1,					&ExtHtCapIe,
+									  1,					&HtLen,
+									  1,          			&pAd->CommonCfg.BSSCoexist2040.word,
+									  END_OF_ARGS);
+
+					FrameLen += Tmp;
+				}
+#endif // DOT11N_DRAFT3 //
+			}
+#endif // DOT11_N_SUPPORT //
+
+
+			MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+			MlmeFreeMemory(pAd, pOutBuffer);
+		}
+
+		// For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe reponse
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+			pAd->Mlme.SyncMachine.CurrState = SCAN_LISTEN;
+#endif // CONFIG_STA_SUPPORT //
+
+	}
+}
+
+VOID MgtProbReqMacHeaderInit(
+	IN	PRTMP_ADAPTER	pAd,
+	IN OUT PHEADER_802_11 pHdr80211,
+	IN UCHAR SubType,
+	IN UCHAR ToDs,
+	IN PUCHAR pDA,
+	IN PUCHAR pBssid)
+{
+	NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
+
+	pHdr80211->FC.Type = BTYPE_MGMT;
+	pHdr80211->FC.SubType = SubType;
+	if (SubType == SUBTYPE_ACK)
+		pHdr80211->FC.Type = BTYPE_CNTL;
+	pHdr80211->FC.ToDs = ToDs;
+	COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
+	COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
+	COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
+}
+
+
diff --git a/drivers/staging/rt3070/common/cmm_wpa.c b/drivers/staging/rt3070/common/cmm_wpa.c
new file mode 100644
index 0000000..81c332a
--- /dev/null
+++ b/drivers/staging/rt3070/common/cmm_wpa.c
@@ -0,0 +1,1606 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	wpa.c
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	Jan	Lee		03-07-22		Initial
+	Paul Lin	03-11-28		Modify for supplicant
+*/
+#include "../rt_config.h"
+// WPA OUI
+UCHAR		OUI_WPA_NONE_AKM[4]		= {0x00, 0x50, 0xF2, 0x00};
+UCHAR       OUI_WPA_VERSION[4]      = {0x00, 0x50, 0xF2, 0x01};
+UCHAR       OUI_WPA_TKIP[4]     = {0x00, 0x50, 0xF2, 0x02};
+UCHAR       OUI_WPA_CCMP[4]     = {0x00, 0x50, 0xF2, 0x04};
+UCHAR       OUI_WPA_8021X_AKM[4]	= {0x00, 0x50, 0xF2, 0x01};
+UCHAR       OUI_WPA_PSK_AKM[4]      = {0x00, 0x50, 0xF2, 0x02};
+// WPA2 OUI
+UCHAR       OUI_WPA2_WEP40[4]   = {0x00, 0x0F, 0xAC, 0x01};
+UCHAR       OUI_WPA2_TKIP[4]        = {0x00, 0x0F, 0xAC, 0x02};
+UCHAR       OUI_WPA2_CCMP[4]        = {0x00, 0x0F, 0xAC, 0x04};
+UCHAR       OUI_WPA2_8021X_AKM[4]   = {0x00, 0x0F, 0xAC, 0x01};
+UCHAR       OUI_WPA2_PSK_AKM[4]   	= {0x00, 0x0F, 0xAC, 0x02};
+// MSA OUI
+UCHAR   	OUI_MSA_8021X_AKM[4]    = {0x00, 0x0F, 0xAC, 0x05};		// Not yet final - IEEE 802.11s-D1.06
+UCHAR   	OUI_MSA_PSK_AKM[4]   	= {0x00, 0x0F, 0xAC, 0x06};		// Not yet final - IEEE 802.11s-D1.06
+
+/*
+	========================================================================
+
+	Routine Description:
+		The pseudo-random function(PRF) that hashes various inputs to
+		derive a pseudo-random value. To add liveness to the pseudo-random
+		value, a nonce should be one of the inputs.
+
+		It is used to generate PTK, GTK or some specific random value.
+
+	Arguments:
+		UCHAR	*key,		-	the key material for HMAC_SHA1 use
+		INT		key_len		-	the length of key
+		UCHAR	*prefix		-	a prefix label
+		INT		prefix_len	-	the length of the label
+		UCHAR	*data		-	a specific data with variable length
+		INT		data_len	-	the length of a specific data
+		INT		len			-	the output lenght
+
+	Return Value:
+		UCHAR	*output		-	the calculated result
+
+	Note:
+		802.11i-2004	Annex H.3
+
+	========================================================================
+*/
+VOID	PRF(
+	IN	UCHAR	*key,
+	IN	INT		key_len,
+	IN	UCHAR	*prefix,
+	IN	INT		prefix_len,
+	IN	UCHAR	*data,
+	IN	INT		data_len,
+	OUT	UCHAR	*output,
+	IN	INT		len)
+{
+	INT		i;
+    UCHAR   *input;
+	INT		currentindex = 0;
+	INT		total_len;
+
+	// Allocate memory for input
+	os_alloc_mem(NULL, (PUCHAR *)&input, 1024);
+
+    if (input == NULL)
+    {
+        DBGPRINT(RT_DEBUG_ERROR, ("!!!PRF: no memory!!!\n"));
+        return;
+    }
+
+	// Generate concatenation input
+	NdisMoveMemory(input, prefix, prefix_len);
+
+	// Concatenate a single octet containing 0
+	input[prefix_len] =	0;
+
+	// Concatenate specific data
+	NdisMoveMemory(&input[prefix_len + 1], data, data_len);
+	total_len =	prefix_len + 1 + data_len;
+
+	// Concatenate a single octet containing 0
+	// This octet shall be update later
+	input[total_len] = 0;
+	total_len++;
+
+	// Iterate to calculate the result by hmac-sha-1
+	// Then concatenate to last result
+	for	(i = 0;	i <	(len + 19) / 20; i++)
+	{
+		HMAC_SHA1(input, total_len,	key, key_len, &output[currentindex]);
+		currentindex +=	20;
+
+		// update the last octet
+		input[total_len - 1]++;
+	}
+    os_free_mem(NULL, input);
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		It utilizes PRF-384 or PRF-512 to derive session-specific keys from a PMK.
+		It shall be called by 4-way handshake processing.
+
+	Arguments:
+		pAd 	-	pointer to our pAdapter context
+		PMK		-	pointer to PMK
+		ANonce	-	pointer to ANonce
+		AA		-	pointer to Authenticator Address
+		SNonce	-	pointer to SNonce
+		SA		-	pointer to Supplicant Address
+		len		-	indicate the length of PTK (octet)
+
+	Return Value:
+		Output		pointer to the PTK
+
+	Note:
+		Refer to IEEE 802.11i-2004 8.5.1.2
+
+	========================================================================
+*/
+VOID WpaCountPTK(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR	*PMK,
+	IN	UCHAR	*ANonce,
+	IN	UCHAR	*AA,
+	IN	UCHAR	*SNonce,
+	IN	UCHAR	*SA,
+	OUT	UCHAR	*output,
+	IN	UINT	len)
+{
+	UCHAR	concatenation[76];
+	UINT	CurrPos = 0;
+	UCHAR	temp[32];
+	UCHAR	Prefix[] = {'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ',
+						'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'};
+
+	// initiate the concatenation input
+	NdisZeroMemory(temp, sizeof(temp));
+	NdisZeroMemory(concatenation, 76);
+
+	// Get smaller address
+	if (RTMPCompareMemory(SA, AA, 6) == 1)
+		NdisMoveMemory(concatenation, AA, 6);
+	else
+		NdisMoveMemory(concatenation, SA, 6);
+	CurrPos += 6;
+
+	// Get larger address
+	if (RTMPCompareMemory(SA, AA, 6) == 1)
+		NdisMoveMemory(&concatenation[CurrPos], SA, 6);
+	else
+		NdisMoveMemory(&concatenation[CurrPos], AA, 6);
+
+	// store the larger mac address for backward compatible of
+	// ralink proprietary STA-key issue
+	NdisMoveMemory(temp, &concatenation[CurrPos], MAC_ADDR_LEN);
+	CurrPos += 6;
+
+	// Get smaller Nonce
+	if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
+		NdisMoveMemory(&concatenation[CurrPos], temp, 32);	// patch for ralink proprietary STA-key issue
+	else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
+		NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
+	else
+		NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
+	CurrPos += 32;
+
+	// Get larger Nonce
+	if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
+		NdisMoveMemory(&concatenation[CurrPos], temp, 32);	// patch for ralink proprietary STA-key issue
+	else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
+		NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
+	else
+		NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
+	CurrPos += 32;
+
+	hex_dump("concatenation=", concatenation, 76);
+
+	// Use PRF to generate PTK
+	PRF(PMK, LEN_MASTER_KEY, Prefix, 22, concatenation, 76, output, len);
+
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Generate random number by software.
+
+	Arguments:
+		pAd		-	pointer to our pAdapter context
+		macAddr	-	pointer to local MAC address
+
+	Return Value:
+
+	Note:
+		802.1ii-2004  Annex H.5
+
+	========================================================================
+*/
+VOID	GenRandom(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			*macAddr,
+	OUT	UCHAR			*random)
+{
+	INT		i, curr;
+	UCHAR	local[80], KeyCounter[32];
+	UCHAR	result[80];
+	ULONG	CurrentTime;
+	UCHAR	prefix[] = {'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r'};
+
+	// Zero the related information
+	NdisZeroMemory(result, 80);
+	NdisZeroMemory(local, 80);
+	NdisZeroMemory(KeyCounter, 32);
+
+	for	(i = 0;	i <	32;	i++)
+	{
+		// copy the local MAC address
+		COPY_MAC_ADDR(local, macAddr);
+		curr =	MAC_ADDR_LEN;
+
+		// concatenate the current time
+		NdisGetSystemUpTime(&CurrentTime);
+		NdisMoveMemory(&local[curr],  &CurrentTime,	sizeof(CurrentTime));
+		curr +=	sizeof(CurrentTime);
+
+		// concatenate the last result
+		NdisMoveMemory(&local[curr],  result, 32);
+		curr +=	32;
+
+		// concatenate a variable
+		NdisMoveMemory(&local[curr],  &i,  2);
+		curr +=	2;
+
+		// calculate the result
+		PRF(KeyCounter, 32, prefix,12, local, curr, result, 32);
+	}
+
+	NdisMoveMemory(random, result,	32);
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Build cipher suite in RSN-IE.
+		It only shall be called by RTMPMakeRSNIE.
+
+	Arguments:
+		pAd			-	pointer to our pAdapter context
+    	ElementID	-	indicate the WPA1 or WPA2
+    	WepStatus	-	indicate the encryption type
+		bMixCipher	-	a boolean to indicate the pairwise cipher and group
+						cipher are the same or not
+
+	Return Value:
+
+	Note:
+
+	========================================================================
+*/
+static VOID RTMPInsertRsnIeCipher(
+	IN  PRTMP_ADAPTER   pAd,
+	IN	UCHAR			ElementID,
+	IN	UINT			WepStatus,
+	IN	BOOLEAN			bMixCipher,
+	IN	UCHAR			FlexibleCipher,
+	OUT	PUCHAR			pRsnIe,
+	OUT	UCHAR			*rsn_len)
+{
+	UCHAR	PairwiseCnt;
+
+	*rsn_len = 0;
+
+	// decide WPA2 or WPA1
+	if (ElementID == Wpa2Ie)
+	{
+		RSNIE2	*pRsnie_cipher = (RSNIE2*)pRsnIe;
+
+		// Assign the verson as 1
+		pRsnie_cipher->version = 1;
+
+        switch (WepStatus)
+        {
+        	// TKIP mode
+            case Ndis802_11Encryption2Enabled:
+                NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
+                pRsnie_cipher->ucount = 1;
+                NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4);
+                *rsn_len = sizeof(RSNIE2);
+                break;
+
+			// AES mode
+            case Ndis802_11Encryption3Enabled:
+				if (bMixCipher)
+					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
+				else
+					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_CCMP, 4);
+                pRsnie_cipher->ucount = 1;
+                NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4);
+                *rsn_len = sizeof(RSNIE2);
+                break;
+
+			// TKIP-AES mix mode
+            case Ndis802_11Encryption4Enabled:
+                NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
+
+				PairwiseCnt = 1;
+				// Insert WPA2 TKIP as the first pairwise cipher
+				if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher))
+				{
+                	NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4);
+					// Insert WPA2 AES as the secondary pairwise cipher
+					if (MIX_CIPHER_WPA2_AES_ON(FlexibleCipher))
+					{
+                		NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA2_CCMP, 4);
+						PairwiseCnt = 2;
+					}
+				}
+				else
+				{
+					// Insert WPA2 AES as the first pairwise cipher
+					NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4);
+				}
+
+                pRsnie_cipher->ucount = PairwiseCnt;
+                *rsn_len = sizeof(RSNIE2) + (4 * (PairwiseCnt - 1));
+                break;
+        }
+
+		// swap for big-endian platform
+		pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
+	    pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
+	}
+	else
+	{
+		RSNIE	*pRsnie_cipher = (RSNIE*)pRsnIe;
+
+		// Assign OUI and version
+		NdisMoveMemory(pRsnie_cipher->oui, OUI_WPA_VERSION, 4);
+        pRsnie_cipher->version = 1;
+
+		switch (WepStatus)
+		{
+			// TKIP mode
+            case Ndis802_11Encryption2Enabled:
+                NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
+                pRsnie_cipher->ucount = 1;
+                NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4);
+                *rsn_len = sizeof(RSNIE);
+                break;
+
+			// AES mode
+            case Ndis802_11Encryption3Enabled:
+				if (bMixCipher)
+					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
+				else
+					NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_CCMP, 4);
+                pRsnie_cipher->ucount = 1;
+                NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4);
+                *rsn_len = sizeof(RSNIE);
+                break;
+
+			// TKIP-AES mix mode
+            case Ndis802_11Encryption4Enabled:
+                NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
+
+				PairwiseCnt = 1;
+				// Insert WPA TKIP as the first pairwise cipher
+				if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher))
+				{
+                	NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4);
+					// Insert WPA AES as the secondary pairwise cipher
+					if (MIX_CIPHER_WPA_AES_ON(FlexibleCipher))
+					{
+                		NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA_CCMP, 4);
+						PairwiseCnt = 2;
+					}
+				}
+				else
+				{
+					// Insert WPA AES as the first pairwise cipher
+					NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4);
+				}
+
+                pRsnie_cipher->ucount = PairwiseCnt;
+                *rsn_len = sizeof(RSNIE) + (4 * (PairwiseCnt - 1));
+                break;
+        }
+
+		// swap for big-endian platform
+		pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
+	    pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
+	}
+
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Build AKM suite in RSN-IE.
+		It only shall be called by RTMPMakeRSNIE.
+
+	Arguments:
+		pAd			-	pointer to our pAdapter context
+    	ElementID	-	indicate the WPA1 or WPA2
+    	AuthMode	-	indicate the authentication mode
+		apidx		-	indicate the interface index
+
+	Return Value:
+
+	Note:
+
+	========================================================================
+*/
+static VOID RTMPInsertRsnIeAKM(
+	IN  PRTMP_ADAPTER   pAd,
+	IN	UCHAR			ElementID,
+	IN	UINT			AuthMode,
+	IN	UCHAR			apidx,
+	OUT	PUCHAR			pRsnIe,
+	OUT	UCHAR			*rsn_len)
+{
+	RSNIE_AUTH		*pRsnie_auth;
+
+	pRsnie_auth = (RSNIE_AUTH*)(pRsnIe + (*rsn_len));
+
+	// decide WPA2 or WPA1
+	if (ElementID == Wpa2Ie)
+	{
+		switch (AuthMode)
+        {
+            case Ndis802_11AuthModeWPA2:
+            case Ndis802_11AuthModeWPA1WPA2:
+                pRsnie_auth->acount = 1;
+                	NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_8021X_AKM, 4);
+                break;
+
+            case Ndis802_11AuthModeWPA2PSK:
+            case Ndis802_11AuthModeWPA1PSKWPA2PSK:
+                pRsnie_auth->acount = 1;
+                	NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_PSK_AKM, 4);
+                break;
+        }
+	}
+	else
+	{
+		switch (AuthMode)
+        {
+            case Ndis802_11AuthModeWPA:
+            case Ndis802_11AuthModeWPA1WPA2:
+                pRsnie_auth->acount = 1;
+                NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_8021X_AKM, 4);
+                break;
+
+            case Ndis802_11AuthModeWPAPSK:
+            case Ndis802_11AuthModeWPA1PSKWPA2PSK:
+                pRsnie_auth->acount = 1;
+                NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_PSK_AKM, 4);
+                break;
+
+			case Ndis802_11AuthModeWPANone:
+                pRsnie_auth->acount = 1;
+                NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_NONE_AKM, 4);
+                break;
+        }
+	}
+
+	pRsnie_auth->acount = cpu2le16(pRsnie_auth->acount);
+
+	(*rsn_len) += sizeof(RSNIE_AUTH);	// update current RSNIE length
+
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Build capability in RSN-IE.
+		It only shall be called by RTMPMakeRSNIE.
+
+	Arguments:
+		pAd			-	pointer to our pAdapter context
+    	ElementID	-	indicate the WPA1 or WPA2
+		apidx		-	indicate the interface index
+
+	Return Value:
+
+	Note:
+
+	========================================================================
+*/
+static VOID RTMPInsertRsnIeCap(
+	IN  PRTMP_ADAPTER   pAd,
+	IN	UCHAR			ElementID,
+	IN	UCHAR			apidx,
+	OUT	PUCHAR			pRsnIe,
+	OUT	UCHAR			*rsn_len)
+{
+	RSN_CAPABILITIES    *pRSN_Cap;
+
+	// it could be ignored in WPA1 mode
+	if (ElementID == WpaIe)
+		return;
+
+	pRSN_Cap = (RSN_CAPABILITIES*)(pRsnIe + (*rsn_len));
+
+
+	pRSN_Cap->word = cpu2le16(pRSN_Cap->word);
+
+	(*rsn_len) += sizeof(RSN_CAPABILITIES);	// update current RSNIE length
+
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Build RSN IE context. It is not included element-ID and length.
+
+	Arguments:
+		pAd			-	pointer to our pAdapter context
+    	AuthMode	-	indicate the authentication mode
+    	WepStatus	-	indicate the encryption type
+		apidx		-	indicate the interface index
+
+	Return Value:
+
+	Note:
+
+	========================================================================
+*/
+VOID RTMPMakeRSNIE(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  UINT            AuthMode,
+    IN  UINT            WepStatus,
+	IN	UCHAR			apidx)
+{
+	PUCHAR		pRsnIe = NULL;			// primary RSNIE
+	UCHAR 		*rsnielen_cur_p = 0;	// the length of the primary RSNIE
+	UCHAR		*rsnielen_ex_cur_p = 0;	// the length of the secondary RSNIE
+	UCHAR		PrimaryRsnie;
+	BOOLEAN		bMixCipher = FALSE;	// indicate the pairwise and group cipher are different
+	UCHAR		p_offset;
+	WPA_MIX_PAIR_CIPHER		FlexibleCipher = MIX_CIPHER_NOTUSE;	// it provide the more flexible cipher combination in WPA-WPA2 and TKIPAES mode
+
+	rsnielen_cur_p = NULL;
+	rsnielen_ex_cur_p = NULL;
+
+	{
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+#ifdef WPA_SUPPLICANT_SUPPORT
+			if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
+			{
+				if (AuthMode < Ndis802_11AuthModeWPA)
+					return;
+			}
+			else
+#endif // WPA_SUPPLICANT_SUPPORT //
+			{
+				// Support WPAPSK or WPA2PSK in STA-Infra mode
+				// Support WPANone in STA-Adhoc mode
+				if ((AuthMode != Ndis802_11AuthModeWPAPSK) &&
+					(AuthMode != Ndis802_11AuthModeWPA2PSK) &&
+					(AuthMode != Ndis802_11AuthModeWPANone)
+					)
+					return;
+			}
+
+			DBGPRINT(RT_DEBUG_TRACE,("==> RTMPMakeRSNIE(STA)\n"));
+
+			// Zero RSNIE context
+			pAd->StaCfg.RSNIE_Len = 0;
+			NdisZeroMemory(pAd->StaCfg.RSN_IE, MAX_LEN_OF_RSNIE);
+
+			// Pointer to RSNIE
+			rsnielen_cur_p = &pAd->StaCfg.RSNIE_Len;
+			pRsnIe = pAd->StaCfg.RSN_IE;
+
+			bMixCipher = pAd->StaCfg.bMixCipher;
+		}
+#endif // CONFIG_STA_SUPPORT //
+	}
+
+	// indicate primary RSNIE as WPA or WPA2
+	if ((AuthMode == Ndis802_11AuthModeWPA) ||
+		(AuthMode == Ndis802_11AuthModeWPAPSK) ||
+		(AuthMode == Ndis802_11AuthModeWPANone) ||
+		(AuthMode == Ndis802_11AuthModeWPA1WPA2) ||
+		(AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))
+		PrimaryRsnie = WpaIe;
+	else
+		PrimaryRsnie = Wpa2Ie;
+
+	{
+		// Build the primary RSNIE
+		// 1. insert cipher suite
+		RTMPInsertRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher, FlexibleCipher, pRsnIe, &p_offset);
+
+		// 2. insert AKM
+		RTMPInsertRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe, &p_offset);
+
+		// 3. insert capability
+		RTMPInsertRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset);
+	}
+
+	// 4. update the RSNIE length
+	*rsnielen_cur_p = p_offset;
+
+	hex_dump("The primary RSNIE", pRsnIe, (*rsnielen_cur_p));
+
+
+}
+
+/*
+    ==========================================================================
+    Description:
+		Check whether the received frame is EAP frame.
+
+	Arguments:
+		pAd				-	pointer to our pAdapter context
+		pEntry			-	pointer to active entry
+		pData			-	the received frame
+		DataByteCount 	-	the received frame's length
+		FromWhichBSSID	-	indicate the interface index
+
+    Return:
+         TRUE 			-	This frame is EAP frame
+         FALSE 			-	otherwise
+    ==========================================================================
+*/
+BOOLEAN RTMPCheckWPAframe(
+    IN PRTMP_ADAPTER    pAd,
+    IN PMAC_TABLE_ENTRY	pEntry,
+    IN PUCHAR           pData,
+    IN ULONG            DataByteCount,
+	IN UCHAR			FromWhichBSSID)
+{
+	ULONG	Body_len;
+	BOOLEAN Cancelled;
+
+
+    if(DataByteCount < (LENGTH_802_1_H + LENGTH_EAPOL_H))
+        return FALSE;
+
+
+	// Skip LLC header
+    if (NdisEqualMemory(SNAP_802_1H, pData, 6) ||
+        // Cisco 1200 AP may send packet with SNAP_BRIDGE_TUNNEL
+        NdisEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6))
+    {
+        pData += 6;
+    }
+	// Skip 2-bytes EAPoL type
+    if (NdisEqualMemory(EAPOL, pData, 2))
+    {
+        pData += 2;
+    }
+    else
+        return FALSE;
+
+    switch (*(pData+1))
+    {
+        case EAPPacket:
+			Body_len = (*(pData+2)<<8) | (*(pData+3));
+            DBGPRINT(RT_DEBUG_TRACE, ("Receive EAP-Packet frame, TYPE = 0, Length = %ld\n", Body_len));
+            break;
+        case EAPOLStart:
+            DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Start frame, TYPE = 1 \n"));
+			if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
+            {
+            	DBGPRINT(RT_DEBUG_TRACE, ("Cancel the EnqueueEapolStartTimerRunning \n"));
+                RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
+                pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
+            }
+            break;
+        case EAPOLLogoff:
+            DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLLogoff frame, TYPE = 2 \n"));
+            break;
+        case EAPOLKey:
+			Body_len = (*(pData+2)<<8) | (*(pData+3));
+            DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Key frame, TYPE = 3, Length = %ld\n", Body_len));
+            break;
+        case EAPOLASFAlert:
+            DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLASFAlert frame, TYPE = 4 \n"));
+            break;
+        default:
+            return FALSE;
+
+    }
+    return TRUE;
+}
+
+
+/*
+    ==========================================================================
+    Description:
+        ENCRYPT AES GTK before sending in EAPOL frame.
+        AES GTK length = 128 bit,  so fix blocks for aes-key-wrap as 2 in this function.
+        This function references to RFC 3394 for aes key wrap algorithm.
+    Return:
+    ==========================================================================
+*/
+VOID AES_GTK_KEY_WRAP(
+    IN UCHAR    *key,
+    IN UCHAR    *plaintext,
+    IN UCHAR    p_len,
+    OUT UCHAR   *ciphertext)
+{
+    UCHAR       A[8], BIN[16], BOUT[16];
+    UCHAR       R[512];
+    INT         num_blocks = p_len/8;   // unit:64bits
+    INT         i, j;
+    aes_context aesctx;
+    UCHAR       xor;
+
+    rtmp_aes_set_key(&aesctx, key, 128);
+
+    // Init IA
+    for (i = 0; i < 8; i++)
+        A[i] = 0xa6;
+
+    //Input plaintext
+    for (i = 0; i < num_blocks; i++)
+    {
+        for (j = 0 ; j < 8; j++)
+            R[8 * (i + 1) + j] = plaintext[8 * i + j];
+    }
+
+    // Key Mix
+    for (j = 0; j < 6; j++)
+    {
+        for(i = 1; i <= num_blocks; i++)
+        {
+            //phase 1
+            NdisMoveMemory(BIN, A, 8);
+            NdisMoveMemory(&BIN[8], &R[8 * i], 8);
+            rtmp_aes_encrypt(&aesctx, BIN, BOUT);
+
+            NdisMoveMemory(A, &BOUT[0], 8);
+            xor = num_blocks * j + i;
+            A[7] = BOUT[7] ^ xor;
+            NdisMoveMemory(&R[8 * i], &BOUT[8], 8);
+        }
+    }
+
+    // Output ciphertext
+    NdisMoveMemory(ciphertext, A, 8);
+
+    for (i = 1; i <= num_blocks; i++)
+    {
+        for (j = 0 ; j < 8; j++)
+            ciphertext[8 * i + j] = R[8 * i + j];
+    }
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Misc function to decrypt AES body
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+		This function references to	RFC	3394 for aes key unwrap algorithm.
+
+	========================================================================
+*/
+VOID	AES_GTK_KEY_UNWRAP(
+	IN	UCHAR	*key,
+	OUT	UCHAR	*plaintext,
+	IN	UCHAR    c_len,
+	IN	UCHAR	*ciphertext)
+
+{
+	UCHAR       A[8], BIN[16], BOUT[16];
+	UCHAR       xor;
+	INT         i, j;
+	aes_context aesctx;
+	UCHAR       *R;
+	INT         num_blocks = c_len/8;	// unit:64bits
+
+
+	os_alloc_mem(NULL, (PUCHAR *)&R, 512);
+
+	if (R == NULL)
+    {
+        DBGPRINT(RT_DEBUG_ERROR, ("!!!AES_GTK_KEY_UNWRAP: no memory!!!\n"));
+        return;
+    } /* End of if */
+
+	// Initialize
+	NdisMoveMemory(A, ciphertext, 8);
+	//Input plaintext
+	for(i = 0; i < (c_len-8); i++)
+	{
+		R[ i] = ciphertext[i + 8];
+	}
+
+	rtmp_aes_set_key(&aesctx, key, 128);
+
+	for(j = 5; j >= 0; j--)
+	{
+		for(i = (num_blocks-1); i > 0; i--)
+		{
+			xor = (num_blocks -1 )* j + i;
+			NdisMoveMemory(BIN, A, 8);
+			BIN[7] = A[7] ^ xor;
+			NdisMoveMemory(&BIN[8], &R[(i-1)*8], 8);
+			rtmp_aes_decrypt(&aesctx, BIN, BOUT);
+			NdisMoveMemory(A, &BOUT[0], 8);
+			NdisMoveMemory(&R[(i-1)*8], &BOUT[8], 8);
+		}
+	}
+
+	// OUTPUT
+	for(i = 0; i < c_len; i++)
+	{
+		plaintext[i] = R[i];
+	}
+
+
+	os_free_mem(NULL, R);
+}
+
+/*
+    ==========================================================================
+    Description:
+		Report the EAP message type
+
+	Arguments:
+		msg		-	EAPOL_PAIR_MSG_1
+					EAPOL_PAIR_MSG_2
+					EAPOL_PAIR_MSG_3
+					EAPOL_PAIR_MSG_4
+					EAPOL_GROUP_MSG_1
+					EAPOL_GROUP_MSG_2
+
+    Return:
+         message type string
+
+    ==========================================================================
+*/
+CHAR *GetEapolMsgType(CHAR msg)
+{
+    if(msg == EAPOL_PAIR_MSG_1)
+        return "Pairwise Message 1";
+    else if(msg == EAPOL_PAIR_MSG_2)
+        return "Pairwise Message 2";
+	else if(msg == EAPOL_PAIR_MSG_3)
+        return "Pairwise Message 3";
+	else if(msg == EAPOL_PAIR_MSG_4)
+        return "Pairwise Message 4";
+	else if(msg == EAPOL_GROUP_MSG_1)
+        return "Group Message 1";
+	else if(msg == EAPOL_GROUP_MSG_2)
+        return "Group Message 2";
+    else
+    	return "Invalid Message";
+}
+
+
+/*
+    ========================================================================
+
+    Routine Description:
+    Check Sanity RSN IE of EAPoL message
+
+    Arguments:
+
+    Return Value:
+
+
+    ========================================================================
+*/
+BOOLEAN RTMPCheckRSNIE(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR          pData,
+	IN  UCHAR           DataLen,
+	IN  MAC_TABLE_ENTRY *pEntry,
+	OUT	UCHAR			*Offset)
+{
+	PUCHAR              pVIE;
+	UCHAR               len;
+	PEID_STRUCT         pEid;
+	BOOLEAN				result = FALSE;
+
+	pVIE = pData;
+	len	 = DataLen;
+	*Offset = 0;
+
+	while (len > sizeof(RSNIE2))
+	{
+		pEid = (PEID_STRUCT) pVIE;
+		// WPA RSN IE
+		if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)))
+		{
+			if ((pEntry->AuthMode == Ndis802_11AuthModeWPA || pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) &&
+				(NdisEqualMemory(pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len)) &&
+				(pEntry->RSNIE_Len == (pEid->Len + 2)))
+			{
+					result = TRUE;
+			}
+
+			*Offset += (pEid->Len + 2);
+		}
+		// WPA2 RSN IE
+		else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3)))
+		{
+			if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2 || pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) &&
+				(NdisEqualMemory(pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len)) &&
+				(pEntry->RSNIE_Len == (pEid->Len + 2))/* ToDo-AlbertY for mesh*/)
+			{
+					result = TRUE;
+			}
+
+			*Offset += (pEid->Len + 2);
+		}
+		else
+		{
+			break;
+		}
+
+		pVIE += (pEid->Len + 2);
+		len  -= (pEid->Len + 2);
+	}
+
+
+	return result;
+
+}
+
+
+/*
+    ========================================================================
+
+    Routine Description:
+    Parse KEYDATA field.  KEYDATA[] May contain 2 RSN IE and optionally GTK.
+    GTK  is encaptulated in KDE format at  p.83 802.11i D10
+
+    Arguments:
+
+    Return Value:
+
+    Note:
+        802.11i D10
+
+    ========================================================================
+*/
+BOOLEAN RTMPParseEapolKeyData(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR          pKeyData,
+	IN  UCHAR           KeyDataLen,
+	IN	UCHAR			GroupKeyIndex,
+	IN	UCHAR			MsgType,
+	IN	BOOLEAN			bWPA2,
+	IN  MAC_TABLE_ENTRY *pEntry)
+{
+    PKDE_ENCAP          pKDE = NULL;
+    PUCHAR              pMyKeyData = pKeyData;
+    UCHAR               KeyDataLength = KeyDataLen;
+    UCHAR               GTKLEN = 0;
+	UCHAR				DefaultIdx = 0;
+	UCHAR				skip_offset;
+
+	// Verify The RSN IE contained in pairewise_msg_2 && pairewise_msg_3 and skip it
+	if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_3)
+    {
+		// Check RSN IE whether it is WPA2/WPA2PSK
+		if (!RTMPCheckRSNIE(pAd, pKeyData, KeyDataLen, pEntry, &skip_offset))
+		{
+			// send wireless event - for RSN IE different
+			if (pAd->CommonCfg.bWirelessEvent)
+				RTMPSendWirelessEvent(pAd, IW_RSNIE_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
+
+        	DBGPRINT(RT_DEBUG_ERROR, ("RSN_IE Different in msg %d of 4-way handshake!\n", MsgType));
+			hex_dump("Receive RSN_IE ", pKeyData, KeyDataLen);
+			hex_dump("Desired RSN_IE ", pEntry->RSN_IE, pEntry->RSNIE_Len);
+
+			return FALSE;
+    	}
+    	else
+		{
+			if (bWPA2 && MsgType == EAPOL_PAIR_MSG_3)
+			{
+				// skip RSN IE
+				pMyKeyData += skip_offset;
+				KeyDataLength -= skip_offset;
+				DBGPRINT(RT_DEBUG_TRACE, ("RTMPParseEapolKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", skip_offset));
+			}
+			else
+				return TRUE;
+		}
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE,("RTMPParseEapolKeyData ==> KeyDataLength %d without RSN_IE \n", KeyDataLength));
+
+	// Parse EKD format in pairwise_msg_3_WPA2 && group_msg_1_WPA2
+	if (bWPA2 && (MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1))
+	{
+		if (KeyDataLength >= 8)	// KDE format exclude GTK length
+    	{
+        	pKDE = (PKDE_ENCAP) pMyKeyData;
+
+
+			DefaultIdx = pKDE->GTKEncap.Kid;
+
+			// Sanity check - KED length
+			if (KeyDataLength < (pKDE->Len + 2))
+    		{
+        		DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The len from KDE is too short \n"));
+        		return FALSE;
+    		}
+
+			// Get GTK length - refer to IEEE 802.11i-2004 p.82
+			GTKLEN = pKDE->Len -6;
+			if (GTKLEN < LEN_AES_KEY)
+			{
+				DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN));
+        		return FALSE;
+			}
+
+    	}
+		else
+    	{
+			DBGPRINT(RT_DEBUG_ERROR, ("ERROR: KDE format length is too short \n"));
+	        return FALSE;
+    	}
+
+		DBGPRINT(RT_DEBUG_TRACE, ("GTK in KDE format ,DefaultKeyID=%d, KeyLen=%d \n", DefaultIdx, GTKLEN));
+		// skip it
+		pMyKeyData += 8;
+		KeyDataLength -= 8;
+
+	}
+	else if (!bWPA2 && MsgType == EAPOL_GROUP_MSG_1)
+	{
+		DefaultIdx = GroupKeyIndex;
+		DBGPRINT(RT_DEBUG_TRACE, ("GTK DefaultKeyID=%d \n", DefaultIdx));
+	}
+
+	// Sanity check - shared key index must be 1 ~ 3
+	if (DefaultIdx < 1 || DefaultIdx > 3)
+    {
+     	DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key index(%d) is invalid in %s %s \n", DefaultIdx, ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
+        return FALSE;
+    }
+
+
+#ifdef CONFIG_STA_SUPPORT
+	// Todo
+#endif // CONFIG_STA_SUPPORT //
+
+	return TRUE;
+
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Construct EAPoL message for WPA handshaking
+		Its format is below,
+
+		+--------------------+
+		| Protocol Version	 |  1 octet
+		+--------------------+
+		| Protocol Type		 |	1 octet
+		+--------------------+
+		| Body Length		 |  2 octets
+		+--------------------+
+		| Descriptor Type	 |	1 octet
+		+--------------------+
+		| Key Information    |	2 octets
+		+--------------------+
+		| Key Length	     |  1 octet
+		+--------------------+
+		| Key Repaly Counter |	8 octets
+		+--------------------+
+		| Key Nonce		     |  32 octets
+		+--------------------+
+		| Key IV			 |  16 octets
+		+--------------------+
+		| Key RSC			 |  8 octets
+		+--------------------+
+		| Key ID or Reserved |	8 octets
+		+--------------------+
+		| Key MIC			 |	16 octets
+		+--------------------+
+		| Key Data Length	 |	2 octets
+		+--------------------+
+		| Key Data			 |	n octets
+		+--------------------+
+
+
+	Arguments:
+		pAd			Pointer	to our adapter
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+VOID	ConstructEapolMsg(
+	IN 	PRTMP_ADAPTER    	pAd,
+    IN 	UCHAR				AuthMode,
+    IN 	UCHAR				WepStatus,
+    IN 	UCHAR				GroupKeyWepStatus,
+    IN 	UCHAR				MsgType,
+    IN	UCHAR				DefaultKeyIdx,
+    IN 	UCHAR				*ReplayCounter,
+	IN 	UCHAR				*KeyNonce,
+	IN	UCHAR				*TxRSC,
+	IN	UCHAR				*PTK,
+	IN	UCHAR				*GTK,
+	IN	UCHAR				*RSNIE,
+	IN	UCHAR				RSNIE_Len,
+    OUT PEAPOL_PACKET       pMsg)
+{
+	BOOLEAN	bWPA2 = FALSE;
+
+	// Choose WPA2 or not
+	if ((AuthMode == Ndis802_11AuthModeWPA2) || (AuthMode == Ndis802_11AuthModeWPA2PSK))
+		bWPA2 = TRUE;
+
+    // Init Packet and Fill header
+    pMsg->ProVer = EAPOL_VER;
+    pMsg->ProType = EAPOLKey;
+
+	// Default 95 bytes, the EAPoL-Key descriptor exclude Key-data field
+	pMsg->Body_Len[1] = LEN_EAPOL_KEY_MSG;
+
+	// Fill in EAPoL descriptor
+	if (bWPA2)
+		pMsg->KeyDesc.Type = WPA2_KEY_DESC;
+	else
+		pMsg->KeyDesc.Type = WPA1_KEY_DESC;
+
+	// Fill in Key information, refer to IEEE Std 802.11i-2004 page 78
+	// When either the pairwise or the group cipher is AES, the DESC_TYPE_AES(2) shall be used.
+	pMsg->KeyDesc.KeyInfo.KeyDescVer =
+        	(((WepStatus == Ndis802_11Encryption3Enabled) || (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
+
+	// Specify Key Type as Group(0) or Pairwise(1)
+	if (MsgType >= EAPOL_GROUP_MSG_1)
+		pMsg->KeyDesc.KeyInfo.KeyType = GROUPKEY;
+	else
+		pMsg->KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
+
+	// Specify Key Index, only group_msg1_WPA1
+	if (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))
+		pMsg->KeyDesc.KeyInfo.KeyIndex = DefaultKeyIdx;
+
+	if (MsgType == EAPOL_PAIR_MSG_3)
+		pMsg->KeyDesc.KeyInfo.Install = 1;
+
+	if ((MsgType == EAPOL_PAIR_MSG_1) || (MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1))
+		pMsg->KeyDesc.KeyInfo.KeyAck = 1;
+
+	if (MsgType != EAPOL_PAIR_MSG_1)
+		pMsg->KeyDesc.KeyInfo.KeyMic = 1;
+
+	if ((bWPA2 && (MsgType >= EAPOL_PAIR_MSG_3)) || (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1)))
+    {
+       	pMsg->KeyDesc.KeyInfo.Secure = 1;
+    }
+
+	if (bWPA2 && ((MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1)))
+    {
+        pMsg->KeyDesc.KeyInfo.EKD_DL = 1;
+    }
+
+	// key Information element has done.
+	*(USHORT *)(&pMsg->KeyDesc.KeyInfo) = cpu2le16(*(USHORT *)(&pMsg->KeyDesc.KeyInfo));
+
+	// Fill in Key Length
+	{
+		if (MsgType >= EAPOL_GROUP_MSG_1)
+		{
+			// the length of group key cipher
+			pMsg->KeyDesc.KeyLength[1] = ((GroupKeyWepStatus == Ndis802_11Encryption2Enabled) ? TKIP_GTK_LENGTH : LEN_AES_KEY);
+		}
+		else
+		{
+			// the length of pairwise key cipher
+			pMsg->KeyDesc.KeyLength[1] = ((WepStatus == Ndis802_11Encryption2Enabled) ? LEN_TKIP_KEY : LEN_AES_KEY);
+		}
+	}
+
+ 	// Fill in replay counter
+    NdisMoveMemory(pMsg->KeyDesc.ReplayCounter, ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+	// Fill Key Nonce field
+	// ANonce : pairwise_msg1 & pairwise_msg3
+	// SNonce : pairwise_msg2
+	// GNonce : group_msg1_wpa1
+	if ((MsgType <= EAPOL_PAIR_MSG_3) || ((!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))))
+    	NdisMoveMemory(pMsg->KeyDesc.KeyNonce, KeyNonce, LEN_KEY_DESC_NONCE);
+
+	// Fill key IV - WPA2 as 0, WPA1 as random
+	if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))
+	{
+		// Suggest IV be random number plus some number,
+		NdisMoveMemory(pMsg->KeyDesc.KeyIv, &KeyNonce[16], LEN_KEY_DESC_IV);
+        pMsg->KeyDesc.KeyIv[15] += 2;
+	}
+
+    // Fill Key RSC field
+    // It contains the RSC for the GTK being installed.
+	if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1))
+	{
+        NdisMoveMemory(pMsg->KeyDesc.KeyRsc, TxRSC, 6);
+	}
+
+	// Clear Key MIC field for MIC calculation later
+    NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+
+	ConstructEapolKeyData(pAd,
+						  AuthMode,
+						  WepStatus,
+						  GroupKeyWepStatus,
+						  MsgType,
+						  DefaultKeyIdx,
+						  bWPA2,
+						  PTK,
+						  GTK,
+						  RSNIE,
+						  RSNIE_Len,
+						  pMsg);
+
+	// Calculate MIC and fill in KeyMic Field except Pairwise Msg 1.
+	if (MsgType != EAPOL_PAIR_MSG_1)
+	{
+		CalculateMIC(pAd, WepStatus, PTK, pMsg);
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> ConstructEapolMsg for %s %s\n", ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
+	DBGPRINT(RT_DEBUG_TRACE, ("	     Body length = %d \n", pMsg->Body_Len[1]));
+	DBGPRINT(RT_DEBUG_TRACE, ("	     Key length  = %d \n", pMsg->KeyDesc.KeyLength[1]));
+
+
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Construct the Key Data field of EAPoL message
+
+	Arguments:
+		pAd			Pointer	to our adapter
+		Elem		Message body
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+VOID	ConstructEapolKeyData(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			AuthMode,
+	IN	UCHAR			WepStatus,
+	IN	UCHAR			GroupKeyWepStatus,
+	IN 	UCHAR			MsgType,
+	IN	UCHAR			DefaultKeyIdx,
+	IN	BOOLEAN			bWPA2Capable,
+	IN	UCHAR			*PTK,
+	IN	UCHAR			*GTK,
+	IN	UCHAR			*RSNIE,
+	IN	UCHAR			RSNIE_LEN,
+	OUT PEAPOL_PACKET   pMsg)
+{
+	UCHAR		*mpool, *Key_Data, *Rc4GTK;
+	UCHAR       ekey[(LEN_KEY_DESC_IV+LEN_EAP_EK)];
+	UCHAR		data_offset;
+
+
+	if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2)
+		return;
+
+	// allocate memory pool
+	os_alloc_mem(pAd, (PUCHAR *)&mpool, 1500);
+
+    if (mpool == NULL)
+		return;
+
+	/* Rc4GTK Len = 512 */
+	Rc4GTK = (UCHAR *) ROUND_UP(mpool, 4);
+	/* Key_Data Len = 512 */
+	Key_Data = (UCHAR *) ROUND_UP(Rc4GTK + 512, 4);
+
+	NdisZeroMemory(Key_Data, 512);
+	pMsg->KeyDesc.KeyDataLen[1] = 0;
+	data_offset = 0;
+
+	// Encapsulate RSNIE in pairwise_msg2 & pairwise_msg3
+	if (RSNIE_LEN && ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3)))
+	{
+		if (bWPA2Capable)
+			Key_Data[data_offset + 0] = IE_WPA2;
+		else
+			Key_Data[data_offset + 0] = IE_WPA;
+
+        Key_Data[data_offset + 1] = RSNIE_LEN;
+		NdisMoveMemory(&Key_Data[data_offset + 2], RSNIE, RSNIE_LEN);
+		data_offset += (2 + RSNIE_LEN);
+	}
+
+	// Encapsulate KDE format in pairwise_msg3_WPA2 & group_msg1_WPA2
+	if (bWPA2Capable && ((MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1)))
+	{
+		// Key Data Encapsulation (KDE) format - 802.11i-2004  Figure-43w and Table-20h
+        Key_Data[data_offset + 0] = 0xDD;
+
+		if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
+		{
+			Key_Data[data_offset + 1] = 0x16;// 4+2+16(OUI+DataType+DataField)
+		}
+		else
+		{
+			Key_Data[data_offset + 1] = 0x26;// 4+2+32(OUI+DataType+DataField)
+		}
+
+        Key_Data[data_offset + 2] = 0x00;
+        Key_Data[data_offset + 3] = 0x0F;
+        Key_Data[data_offset + 4] = 0xAC;
+        Key_Data[data_offset + 5] = 0x01;
+
+		// GTK KDE format - 802.11i-2004  Figure-43x
+        Key_Data[data_offset + 6] = (DefaultKeyIdx & 0x03);
+        Key_Data[data_offset + 7] = 0x00;	// Reserved Byte
+
+		data_offset += 8;
+	}
+
+
+	// Encapsulate GTK and encrypt the key-data field with KEK.
+	// Only for pairwise_msg3_WPA2 and group_msg1
+	if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable) || (MsgType == EAPOL_GROUP_MSG_1))
+	{
+		// Fill in GTK
+		if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
+		{
+			NdisMoveMemory(&Key_Data[data_offset], GTK, LEN_AES_KEY);
+			data_offset += LEN_AES_KEY;
+		}
+		else
+		{
+			NdisMoveMemory(&Key_Data[data_offset], GTK, TKIP_GTK_LENGTH);
+			data_offset += TKIP_GTK_LENGTH;
+		}
+
+		// Still dont know why, but if not append will occur "GTK not include in MSG3"
+		// Patch for compatibility between zero config and funk
+		if (MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable)
+		{
+			if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
+			{
+				Key_Data[data_offset + 0] = 0xDD;
+				Key_Data[data_offset + 1] = 0;
+				data_offset += 2;
+			}
+			else
+			{
+				Key_Data[data_offset + 0] = 0xDD;
+				Key_Data[data_offset + 1] = 0;
+				Key_Data[data_offset + 2] = 0;
+				Key_Data[data_offset + 3] = 0;
+				Key_Data[data_offset + 4] = 0;
+				Key_Data[data_offset + 5] = 0;
+				data_offset += 6;
+			}
+		}
+
+		// Encrypt the data material in key data field
+		if (WepStatus == Ndis802_11Encryption3Enabled)
+		{
+			AES_GTK_KEY_WRAP(&PTK[16], Key_Data, data_offset, Rc4GTK);
+            // AES wrap function will grow 8 bytes in length
+            data_offset += 8;
+		}
+		else
+		{
+			// PREPARE Encrypted  "Key DATA" field.  (Encrypt GTK with RC4, usinf PTK[16]->[31] as Key, IV-field as IV)
+			// put TxTsc in Key RSC field
+			pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32;   //Init crc32.
+
+			// ekey is the contanetion of IV-field, and PTK[16]->PTK[31]
+			NdisMoveMemory(ekey, pMsg->KeyDesc.KeyIv, LEN_KEY_DESC_IV);
+			NdisMoveMemory(&ekey[LEN_KEY_DESC_IV], &PTK[16], LEN_EAP_EK);
+			ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, ekey, sizeof(ekey));  //INIT SBOX, KEYLEN+3(IV)
+			pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, Key_Data, data_offset);
+			WPAARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, Rc4GTK, Key_Data, data_offset);
+		}
+
+		NdisMoveMemory(pMsg->KeyDesc.KeyData, Rc4GTK, data_offset);
+	}
+	else
+	{
+		NdisMoveMemory(pMsg->KeyDesc.KeyData, Key_Data, data_offset);
+	}
+
+	// set key data length field and total length
+	pMsg->KeyDesc.KeyDataLen[1] = data_offset;
+    pMsg->Body_Len[1] += data_offset;
+
+	os_free_mem(pAd, mpool);
+
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Calcaulate MIC. It is used during 4-ways handsharking.
+
+	Arguments:
+		pAd				-	pointer to our pAdapter context
+    	PeerWepStatus	-	indicate the encryption type
+
+	Return Value:
+
+	Note:
+
+	========================================================================
+*/
+VOID	CalculateMIC(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			PeerWepStatus,
+	IN	UCHAR			*PTK,
+	OUT PEAPOL_PACKET   pMsg)
+{
+    UCHAR   *OutBuffer;
+	ULONG	FrameLen = 0;
+	UCHAR	mic[LEN_KEY_DESC_MIC];
+	UCHAR	digest[80];
+
+	// allocate memory for MIC calculation
+	os_alloc_mem(pAd, (PUCHAR *)&OutBuffer, 512);
+
+    if (OutBuffer == NULL)
+    {
+		DBGPRINT(RT_DEBUG_ERROR, ("!!!CalculateMIC: no memory!!!\n"));
+		return;
+    }
+
+	// make a frame for calculating MIC.
+    MakeOutgoingFrame(OutBuffer,            	&FrameLen,
+                      pMsg->Body_Len[1] + 4,  	pMsg,
+                      END_OF_ARGS);
+
+	NdisZeroMemory(mic, sizeof(mic));
+
+	// Calculate MIC
+    if (PeerWepStatus == Ndis802_11Encryption3Enabled)
+ 	{
+		HMAC_SHA1(OutBuffer,  FrameLen, PTK, LEN_EAP_MICK, digest);
+		NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
+	}
+	else
+	{
+		hmac_md5(PTK,  LEN_EAP_MICK, OutBuffer, FrameLen, mic);
+	}
+
+	// store the calculated MIC
+	NdisMoveMemory(pMsg->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC);
+
+	os_free_mem(pAd, OutBuffer);
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Some received frames can't decrypt by Asic, so decrypt them by software.
+
+	Arguments:
+		pAd				-	pointer to our pAdapter context
+    	PeerWepStatus	-	indicate the encryption type
+
+	Return Value:
+		NDIS_STATUS_SUCCESS		-	decryption successful
+		NDIS_STATUS_FAILURE		-	decryption failure
+
+	========================================================================
+*/
+NDIS_STATUS	RTMPSoftDecryptBroadCastData(
+	IN	PRTMP_ADAPTER					pAd,
+	IN	RX_BLK							*pRxBlk,
+	IN  NDIS_802_11_ENCRYPTION_STATUS 	GroupCipher,
+	IN  PCIPHER_KEY						pShard_key)
+{
+	PRXWI_STRUC			pRxWI = pRxBlk->pRxWI;
+
+
+
+	// handle WEP decryption
+	if (GroupCipher == Ndis802_11Encryption1Enabled)
+    {
+		if (RTMPSoftDecryptWEP(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, pShard_key))
+		{
+
+			//Minus IV[4] & ICV[4]
+			pRxWI->MPDUtotalByteCount -= 8;
+		}
+		else
+		{
+			DBGPRINT(RT_DEBUG_ERROR, ("ERROR : Software decrypt WEP data fails.\n"));
+			// give up this frame
+			return NDIS_STATUS_FAILURE;
+		}
+	}
+	// handle TKIP decryption
+	else if (GroupCipher == Ndis802_11Encryption2Enabled)
+	{
+		if (RTMPSoftDecryptTKIP(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, 0, pShard_key))
+		{
+
+			//Minus 8 bytes MIC, 8 bytes IV/EIV, 4 bytes ICV
+			pRxWI->MPDUtotalByteCount -= 20;
+		}
+        else
+		{
+			DBGPRINT(RT_DEBUG_ERROR, ("ERROR : RTMPSoftDecryptTKIP Failed\n"));
+			// give up this frame
+			return NDIS_STATUS_FAILURE;
+        }
+	}
+	// handle AES decryption
+	else if (GroupCipher == Ndis802_11Encryption3Enabled)
+	{
+		if (RTMPSoftDecryptAES(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount , pShard_key))
+		{
+
+			//8 bytes MIC, 8 bytes IV/EIV (CCMP Header)
+			pRxWI->MPDUtotalByteCount -= 16;
+		}
+		else
+		{
+			DBGPRINT(RT_DEBUG_ERROR, ("ERROR : RTMPSoftDecryptAES Failed\n"));
+			// give up this frame
+			return NDIS_STATUS_FAILURE;
+		}
+	}
+	else
+	{
+		// give up this frame
+		return NDIS_STATUS_FAILURE;
+	}
+
+	return NDIS_STATUS_SUCCESS;
+
+}
+
diff --git a/drivers/staging/rt3070/common/dfs.c b/drivers/staging/rt3070/common/dfs.c
new file mode 100644
index 0000000..28d6014
--- /dev/null
+++ b/drivers/staging/rt3070/common/dfs.c
@@ -0,0 +1,441 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+    ap_dfs.c
+
+    Abstract:
+    Support DFS function.
+
+    Revision History:
+    Who       When            What
+    --------  ----------      ----------------------------------------------
+    Fonchi    03-12-2007      created
+*/
+
+#include "../rt_config.h"
+
+typedef struct _RADAR_DURATION_TABLE
+{
+	ULONG RDDurRegion;
+	ULONG RadarSignalDuration;
+	ULONG Tolerance;
+} RADAR_DURATION_TABLE, *PRADAR_DURATION_TABLE;
+
+
+static UCHAR RdIdleTimeTable[MAX_RD_REGION][4] =
+{
+	{9, 250, 250, 250},		// CE
+	{4, 250, 250, 250},		// FCC
+	{4, 250, 250, 250},		// JAP
+	{15, 250, 250, 250},	// JAP_W53
+	{4, 250, 250, 250}		// JAP_W56
+};
+
+/*
+	========================================================================
+
+	Routine Description:
+		Bbp Radar detection routine
+
+	Arguments:
+		pAd 	Pointer to our adapter
+
+	Return Value:
+
+	========================================================================
+*/
+VOID BbpRadarDetectionStart(
+	IN PRTMP_ADAPTER pAd)
+{
+	UINT8 RadarPeriod;
+
+	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 114, 0x02);
+	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 121, 0x20);
+	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 122, 0x00);
+	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 123, 0x08/*0x80*/);
+	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 124, 0x28);
+	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 125, 0xff);
+
+	RadarPeriod = ((UINT)RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + (UINT)pAd->CommonCfg.RadarDetect.DfsSessionTime) < 250 ?
+			(RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + pAd->CommonCfg.RadarDetect.DfsSessionTime) : 250;
+
+	RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
+	RTMP_IO_WRITE8(pAd, 0x7021, 0x40);
+
+	RadarDetectionStart(pAd, 0, RadarPeriod);
+	return;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Bbp Radar detection routine
+
+	Arguments:
+		pAd 	Pointer to our adapter
+
+	Return Value:
+
+	========================================================================
+*/
+VOID BbpRadarDetectionStop(
+	IN PRTMP_ADAPTER pAd)
+{
+	RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
+	RTMP_IO_WRITE8(pAd, 0x7021, 0x60);
+
+	RadarDetectionStop(pAd);
+	return;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Radar detection routine
+
+	Arguments:
+		pAd 	Pointer to our adapter
+
+	Return Value:
+
+	========================================================================
+*/
+VOID RadarDetectionStart(
+	IN PRTMP_ADAPTER pAd,
+	IN BOOLEAN CTSProtect,
+	IN UINT8 CTSPeriod)
+{
+	UINT8 DfsActiveTime = (pAd->CommonCfg.RadarDetect.DfsSessionTime & 0x1f);
+	UINT8 CtsProtect = (CTSProtect == 1) ? 0x02 : 0x01; // CTS protect.
+
+	if (CTSProtect != 0)
+	{
+		switch(pAd->CommonCfg.RadarDetect.RDDurRegion)
+		{
+		case FCC:
+		case JAP_W56:
+			CtsProtect = 0x03;
+			break;
+
+		case CE:
+		case JAP_W53:
+		default:
+			CtsProtect = 0x02;
+			break;
+		}
+	}
+	else
+		CtsProtect = 0x01;
+
+
+	// send start-RD with CTS protection command to MCU
+	// highbyte [7]		reserve
+	// highbyte [6:5]	0x: stop Carrier/Radar detection
+	// highbyte [10]:	Start Carrier/Radar detection without CTS protection, 11: Start Carrier/Radar detection with CTS protection
+	// highbyte [4:0]	Radar/carrier detection duration. In 1ms.
+
+	// lowbyte [7:0]	Radar/carrier detection period, in 1ms.
+	AsicSendCommandToMcu(pAd, 0x60, 0xff, CTSPeriod, DfsActiveTime | (CtsProtect << 5));
+	//AsicSendCommandToMcu(pAd, 0x63, 0xff, 10, 0);
+
+	return;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Radar detection routine
+
+	Arguments:
+		pAd 	Pointer to our adapter
+
+	Return Value:
+		TRUE	Found radar signal
+		FALSE	Not found radar signal
+
+	========================================================================
+*/
+VOID RadarDetectionStop(
+	IN PRTMP_ADAPTER	pAd)
+{
+	DBGPRINT(RT_DEBUG_TRACE,("RadarDetectionStop.\n"));
+	AsicSendCommandToMcu(pAd, 0x60, 0xff, 0x00, 0x00);	// send start-RD with CTS protection command to MCU
+
+	return;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Radar channel check routine
+
+	Arguments:
+		pAd 	Pointer to our adapter
+
+	Return Value:
+		TRUE	need to do radar detect
+		FALSE	need not to do radar detect
+
+	========================================================================
+*/
+BOOLEAN RadarChannelCheck(
+	IN PRTMP_ADAPTER	pAd,
+	IN UCHAR			Ch)
+{
+#if 1
+	INT		i;
+	BOOLEAN result = FALSE;
+
+	for (i=0; i<pAd->ChannelListNum; i++)
+	{
+		if (Ch == pAd->ChannelList[i].Channel)
+		{
+			result = pAd->ChannelList[i].DfsReq;
+			break;
+		}
+	}
+
+	return result;
+#else
+	INT		i;
+	UCHAR	Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
+
+	for (i=0; i<15; i++)
+	{
+		if (Ch == Channel[i])
+		{
+			break;
+		}
+	}
+
+	if (i != 15)
+		return TRUE;
+	else
+		return FALSE;
+#endif
+}
+
+ULONG JapRadarType(
+	IN PRTMP_ADAPTER pAd)
+{
+	ULONG		i;
+	const UCHAR	Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
+
+	if (pAd->CommonCfg.RadarDetect.RDDurRegion != JAP)
+	{
+		return pAd->CommonCfg.RadarDetect.RDDurRegion;
+	}
+
+	for (i=0; i<15; i++)
+	{
+		if (pAd->CommonCfg.Channel == Channel[i])
+		{
+			break;
+		}
+	}
+
+	if (i < 4)
+		return JAP_W53;
+	else if (i < 15)
+		return JAP_W56;
+	else
+		return JAP; // W52
+
+}
+
+ULONG RTMPBbpReadRadarDuration(
+	IN PRTMP_ADAPTER	pAd)
+{
+	UINT8 byteValue = 0;
+	ULONG result;
+
+	BBP_IO_READ8_BY_REG_ID(pAd, BBP_R115, &byteValue);
+
+	result = 0;
+	switch (byteValue)
+	{
+	case 1: // radar signal detected by pulse mode.
+	case 2: // radar signal detected by width mode.
+		result = RTMPReadRadarDuration(pAd);
+		break;
+
+	case 0: // No radar signal.
+	default:
+
+		result = 0;
+		break;
+	}
+
+	return result;
+}
+
+ULONG RTMPReadRadarDuration(
+	IN PRTMP_ADAPTER	pAd)
+{
+	ULONG result = 0;
+
+#ifdef DFS_SUPPORT
+	UINT8 duration1 = 0, duration2 = 0, duration3 = 0;
+
+	BBP_IO_READ8_BY_REG_ID(pAd, BBP_R116, &duration1);
+	BBP_IO_READ8_BY_REG_ID(pAd, BBP_R117, &duration2);
+	BBP_IO_READ8_BY_REG_ID(pAd, BBP_R118, &duration3);
+	result = (duration1 << 16) + (duration2 << 8) + duration3;
+#endif // DFS_SUPPORT //
+
+	return result;
+
+}
+
+VOID RTMPCleanRadarDuration(
+	IN PRTMP_ADAPTER	pAd)
+{
+	return;
+}
+
+/*
+    ========================================================================
+    Routine Description:
+        Radar wave detection. The API should be invoke each second.
+
+    Arguments:
+        pAd         - Adapter pointer
+
+    Return Value:
+        None
+
+    ========================================================================
+*/
+VOID ApRadarDetectPeriodic(
+	IN PRTMP_ADAPTER pAd)
+{
+	INT	i;
+
+	pAd->CommonCfg.RadarDetect.InServiceMonitorCount++;
+
+	for (i=0; i<pAd->ChannelListNum; i++)
+	{
+		if (pAd->ChannelList[i].RemainingTimeForUse > 0)
+		{
+			pAd->ChannelList[i].RemainingTimeForUse --;
+			if ((pAd->Mlme.PeriodicRound%5) == 0)
+			{
+				DBGPRINT(RT_DEBUG_TRACE, ("RadarDetectPeriodic - ch=%d, RemainingTimeForUse=%d\n", pAd->ChannelList[i].Channel, pAd->ChannelList[i].RemainingTimeForUse));
+			}
+		}
+	}
+
+	//radar detect
+	if ((pAd->CommonCfg.Channel > 14)
+		&& (pAd->CommonCfg.bIEEE80211H == 1)
+		&& RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
+	{
+		RadarDetectPeriodic(pAd);
+	}
+
+	return;
+}
+
+// Periodic Radar detection, switch channel will occur in RTMPHandleTBTTInterrupt()
+// Before switch channel, driver needs doing channel switch announcement.
+VOID RadarDetectPeriodic(
+	IN PRTMP_ADAPTER	pAd)
+{
+	// need to check channel availability, after switch channel
+	if (pAd->CommonCfg.RadarDetect.RDMode != RD_SILENCE_MODE)
+			return;
+
+	// channel availability check time is 60sec, use 65 for assurance
+	if (pAd->CommonCfg.RadarDetect.RDCount++ > pAd->CommonCfg.RadarDetect.ChMovingTime)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("Not found radar signal, start send beacon and radar detection in service monitor\n\n"));
+			BbpRadarDetectionStop(pAd);
+		AsicEnableBssSync(pAd);
+		pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
+
+
+		return;
+	}
+
+	return;
+}
+
+
+/*
+    ==========================================================================
+    Description:
+		change channel moving time for DFS testing.
+
+	Arguments:
+	    pAdapter                    Pointer to our adapter
+	    wrq                         Pointer to the ioctl argument
+
+    Return Value:
+        None
+
+    Note:
+        Usage:
+               1.) iwpriv ra0 set ChMovTime=[value]
+    ==========================================================================
+*/
+INT Set_ChMovingTime_Proc(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR arg)
+{
+	UINT8 Value;
+
+	Value = simple_strtol(arg, 0, 10);
+
+	pAd->CommonCfg.RadarDetect.ChMovingTime = Value;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __FUNCTION__,
+		pAd->CommonCfg.RadarDetect.ChMovingTime));
+
+	return TRUE;
+}
+
+INT Set_LongPulseRadarTh_Proc(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR arg)
+{
+	UINT8 Value;
+
+	Value = simple_strtol(arg, 0, 10) > 10 ? 10 : simple_strtol(arg, 0, 10);
+
+	pAd->CommonCfg.RadarDetect.LongPulseRadarTh = Value;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __FUNCTION__,
+		pAd->CommonCfg.RadarDetect.LongPulseRadarTh));
+
+	return TRUE;
+}
+
+
diff --git a/drivers/staging/rt3070/common/eeprom.c b/drivers/staging/rt3070/common/eeprom.c
new file mode 100644
index 0000000..63e1dc1
--- /dev/null
+++ b/drivers/staging/rt3070/common/eeprom.c
@@ -0,0 +1,1498 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	eeprom.c
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	Name		Date			Modification logs
+*/
+#include	"../rt_config.h"
+
+// IRQL = PASSIVE_LEVEL
+VOID RaiseClock(
+    IN	PRTMP_ADAPTER	pAd,
+    IN  UINT32 *x)
+{
+    *x = *x | EESK;
+    RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
+    RTMPusecDelay(1);				// Max frequency = 1MHz in Spec. definition
+}
+
+// IRQL = PASSIVE_LEVEL
+VOID LowerClock(
+    IN	PRTMP_ADAPTER	pAd,
+    IN  UINT32 *x)
+{
+    *x = *x & ~EESK;
+    RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
+    RTMPusecDelay(1);
+}
+
+// IRQL = PASSIVE_LEVEL
+USHORT ShiftInBits(
+    IN	PRTMP_ADAPTER	pAd)
+{
+    UINT32		x,i;
+	USHORT      data=0;
+
+    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+
+    x &= ~( EEDO | EEDI);
+
+    for(i=0; i<16; i++)
+    {
+        data = data << 1;
+        RaiseClock(pAd, &x);
+
+        RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+		LowerClock(pAd, &x); //prevent read failed
+
+        x &= ~(EEDI);
+        if(x & EEDO)
+            data |= 1;
+    }
+
+    return data;
+}
+
+// IRQL = PASSIVE_LEVEL
+VOID ShiftOutBits(
+    IN	PRTMP_ADAPTER	pAd,
+    IN  USHORT data,
+    IN  USHORT count)
+{
+    UINT32       x,mask;
+
+    mask = 0x01 << (count - 1);
+    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+
+    x &= ~(EEDO | EEDI);
+
+    do
+    {
+        x &= ~EEDI;
+        if(data & mask)		x |= EEDI;
+
+        RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+        RaiseClock(pAd, &x);
+        LowerClock(pAd, &x);
+
+        mask = mask >> 1;
+    } while(mask);
+
+    x &= ~EEDI;
+    RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+}
+
+// IRQL = PASSIVE_LEVEL
+VOID EEpromCleanup(
+    IN	PRTMP_ADAPTER	pAd)
+{
+    UINT32 x;
+
+    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+
+    x &= ~(EECS | EEDI);
+    RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+    RaiseClock(pAd, &x);
+    LowerClock(pAd, &x);
+}
+
+VOID EWEN(
+	IN	PRTMP_ADAPTER	pAd)
+{
+    UINT32	x;
+
+    // reset bits and set EECS
+    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+    x &= ~(EEDI | EEDO | EESK);
+    x |= EECS;
+    RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+	// kick a pulse
+	RaiseClock(pAd, &x);
+	LowerClock(pAd, &x);
+
+    // output the read_opcode and six pulse in that order
+    ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5);
+    ShiftOutBits(pAd, 0, 6);
+
+    EEpromCleanup(pAd);
+}
+
+VOID EWDS(
+	IN	PRTMP_ADAPTER	pAd)
+{
+    UINT32	x;
+
+    // reset bits and set EECS
+    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+    x &= ~(EEDI | EEDO | EESK);
+    x |= EECS;
+    RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+	// kick a pulse
+	RaiseClock(pAd, &x);
+	LowerClock(pAd, &x);
+
+    // output the read_opcode and six pulse in that order
+    ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5);
+    ShiftOutBits(pAd, 0, 6);
+
+    EEpromCleanup(pAd);
+}
+
+// IRQL = PASSIVE_LEVEL
+USHORT RTMP_EEPROM_READ16(
+    IN	PRTMP_ADAPTER	pAd,
+    IN  USHORT Offset)
+{
+    UINT32		x;
+    USHORT		data;
+
+	if (pAd->NicConfig2.field.AntDiversity)
+    {
+    	pAd->EepromAccess = TRUE;
+    }
+//2008/09/11:KH add to support efuse<--
+//2008/09/11:KH add to support efuse-->
+{
+    Offset /= 2;
+    // reset bits and set EECS
+    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+    x &= ~(EEDI | EEDO | EESK);
+    x |= EECS;
+    RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+	// patch can not access e-Fuse issue
+    if (!IS_RT3090(pAd))
+    {
+	// kick a pulse
+	RaiseClock(pAd, &x);
+	LowerClock(pAd, &x);
+    }
+
+    // output the read_opcode and register number in that order
+    ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3);
+    ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
+
+    // Now read the data (16 bits) in from the selected EEPROM word
+    data = ShiftInBits(pAd);
+
+    EEpromCleanup(pAd);
+
+	// Antenna and EEPROM access are both using EESK pin,
+    // Therefor we should avoid accessing EESK at the same time
+    // Then restore antenna after EEPROM access
+	if ((pAd->NicConfig2.field.AntDiversity) || (pAd->RfIcType == RFIC_3020))
+    {
+	    pAd->EepromAccess = FALSE;
+	    AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
+    }
+}
+    return data;
+}	//ReadEEprom
+
+VOID RTMP_EEPROM_WRITE16(
+    IN	PRTMP_ADAPTER	pAd,
+    IN  USHORT Offset,
+    IN  USHORT Data)
+{
+    UINT32 x;
+
+	if (pAd->NicConfig2.field.AntDiversity)
+    {
+    	pAd->EepromAccess = TRUE;
+    }
+	//2008/09/11:KH add to support efuse<--
+//2008/09/11:KH add to support efuse-->
+	{
+	Offset /= 2;
+
+	EWEN(pAd);
+
+    // reset bits and set EECS
+    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+    x &= ~(EEDI | EEDO | EESK);
+    x |= EECS;
+    RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+	// patch can not access e-Fuse issue
+    if (!IS_RT3090(pAd))
+    {
+	// kick a pulse
+	RaiseClock(pAd, &x);
+	LowerClock(pAd, &x);
+    }
+
+    // output the read_opcode ,register number and data in that order
+    ShiftOutBits(pAd, EEPROM_WRITE_OPCODE, 3);
+    ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
+	ShiftOutBits(pAd, Data, 16);		// 16-bit access
+
+    // read DO status
+    RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+
+	EEpromCleanup(pAd);
+
+	RTMPusecDelay(10000);	//delay for twp(MAX)=10ms
+
+	EWDS(pAd);
+
+    EEpromCleanup(pAd);
+
+	// Antenna and EEPROM access are both using EESK pin,
+    // Therefor we should avoid accessing EESK at the same time
+    // Then restore antenna after EEPROM access
+	if ((pAd->NicConfig2.field.AntDiversity) || (pAd->RfIcType == RFIC_3020))
+    {
+	    pAd->EepromAccess = FALSE;
+	    AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
+    }
+}
+}
+
+//2008/09/11:KH add to support efuse<--
+#ifdef RT30xx
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+UCHAR eFuseReadRegisters(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT Offset,
+	IN	USHORT Length,
+	OUT	USHORT* pData)
+{
+	EFUSE_CTRL_STRUC		eFuseCtrlStruc;
+	int	i;
+	USHORT	efuseDataOffset;
+	UINT32	data;
+
+	RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+
+	//Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
+	//Use the eeprom logical address and covert to address to block number
+	eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
+
+	//Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 0.
+	eFuseCtrlStruc.field.EFSROM_MODE = 0;
+
+	//Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
+	eFuseCtrlStruc.field.EFSROM_KICK = 1;
+
+	NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
+	RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
+
+	//Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
+	i = 0;
+	while(i < 100)
+	{
+		//rtmp.HwMemoryReadDword(EFUSE_CTRL, (DWORD *) &eFuseCtrlStruc, 4);
+		RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+		if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+		{
+			break;
+		}
+		RTMPusecDelay(2);
+		i++;
+	}
+
+	//if EFSROM_AOUT is not found in physical address, write 0xffff
+	if (eFuseCtrlStruc.field.EFSROM_AOUT == 0x3f)
+	{
+		for(i=0; i<Length/2; i++)
+			*(pData+2*i) = 0xffff;
+	}
+	else
+	{
+		//Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x590-0x59C)
+		efuseDataOffset =  EFUSE_DATA3 - (Offset & 0xC)  ;
+		//data hold 4 bytes data.
+		//In RTMP_IO_READ32 will automatically execute 32-bytes swapping
+		RTMP_IO_READ32(pAd, efuseDataOffset, &data);
+		//Decide the upper 2 bytes or the bottom 2 bytes.
+		// Little-endian		S	|	S	Big-endian
+		// addr	3	2	1	0	|	0	1	2	3
+		// Ori-V	D	C	B	A	|	A	B	C	D
+		//After swapping
+		//		D	C	B	A	|	D	C	B	A
+		//Return 2-bytes
+		//The return byte statrs from S. Therefore, the little-endian will return BA, the Big-endian will return DC.
+		//For returning the bottom 2 bytes, the Big-endian should shift right 2-bytes.
+#ifdef RT_BIG_ENDIAN
+		data = data << (8*((Offset & 0x3)^0x2));
+#else
+		data = data >> (8*(Offset & 0x3));
+#endif
+
+		NdisMoveMemory(pData, &data, Length);
+	}
+
+	return (UCHAR) eFuseCtrlStruc.field.EFSROM_AOUT;
+
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+VOID eFusePhysicalReadRegisters(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT Offset,
+	IN	USHORT Length,
+	OUT	USHORT* pData)
+{
+	EFUSE_CTRL_STRUC		eFuseCtrlStruc;
+	int	i;
+	USHORT	efuseDataOffset;
+	UINT32	data;
+
+	RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+
+	//Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
+	eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
+
+	//Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
+	//Read in physical view
+	eFuseCtrlStruc.field.EFSROM_MODE = 1;
+
+	//Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
+	eFuseCtrlStruc.field.EFSROM_KICK = 1;
+
+	NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
+	RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
+
+	//Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
+	i = 0;
+	while(i < 100)
+	{
+		RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+		if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+			break;
+		RTMPusecDelay(2);
+		i++;
+	}
+
+	//Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
+	//Because the size of each EFUSE_DATA is 4 Bytes, the size of address of each is 2 bits.
+	//The previous 2 bits is the EFUSE_DATA number, the last 2 bits is used to decide which bytes
+	//Decide which EFUSE_DATA to read
+	//590:F E D C
+	//594:B A 9 8
+	//598:7 6 5 4
+	//59C:3 2 1 0
+	efuseDataOffset =  EFUSE_DATA3 - (Offset & 0xC)  ;
+
+	RTMP_IO_READ32(pAd, efuseDataOffset, &data);
+
+#ifdef RT_BIG_ENDIAN
+		data = data << (8*((Offset & 0x3)^0x2));
+#else
+	data = data >> (8*(Offset & 0x3));
+#endif
+
+	NdisMoveMemory(pData, &data, Length);
+
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+VOID eFuseReadPhysical(
+	IN	PRTMP_ADAPTER	pAd,
+  	IN	PUSHORT lpInBuffer,
+  	IN	ULONG nInBufferSize,
+  	OUT	PUSHORT lpOutBuffer,
+  	IN	ULONG nOutBufferSize
+)
+{
+	USHORT* pInBuf = (USHORT*)lpInBuffer;
+	USHORT* pOutBuf = (USHORT*)lpOutBuffer;
+
+	USHORT Offset = pInBuf[0];					//addr
+	USHORT Length = pInBuf[1];					//length
+	int 		i;
+
+	for(i=0; i<Length; i+=2)
+	{
+		eFusePhysicalReadRegisters(pAd,Offset+i, 2, &pOutBuf[i/2]);
+	}
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+NTSTATUS eFuseRead(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT			Offset,
+	OUT	PUCHAR			pData,
+	IN	USHORT			Length)
+{
+	USHORT* pOutBuf = (USHORT*)pData;
+	NTSTATUS	Status = STATUS_SUCCESS;
+	UCHAR	EFSROM_AOUT;
+	int	i;
+
+	for(i=0; i<Length; i+=2)
+	{
+		EFSROM_AOUT = eFuseReadRegisters(pAd, Offset+i, 2, &pOutBuf[i/2]);
+	}
+	return Status;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+VOID eFusePhysicalWriteRegisters(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT Offset,
+	IN	USHORT Length,
+	OUT	USHORT* pData)
+{
+	EFUSE_CTRL_STRUC		eFuseCtrlStruc;
+	int	i;
+	USHORT	efuseDataOffset;
+	UINT32	data, eFuseDataBuffer[4];
+
+	//Step0. Write 16-byte of data to EFUSE_DATA0-3 (0x590-0x59C), where EFUSE_DATA0 is the LSB DW, EFUSE_DATA3 is the MSB DW.
+
+	/////////////////////////////////////////////////////////////////
+	//read current values of 16-byte block
+	RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+
+	//Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
+	eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
+
+	//Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
+	eFuseCtrlStruc.field.EFSROM_MODE = 1;
+
+	//Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
+	eFuseCtrlStruc.field.EFSROM_KICK = 1;
+
+	NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
+	RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
+
+	//Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
+	i = 0;
+	while(i < 100)
+	{
+		RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+
+		if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+			break;
+		RTMPusecDelay(2);
+		i++;
+	}
+
+	//Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
+	efuseDataOffset =  EFUSE_DATA3;
+	for(i=0; i< 4; i++)
+	{
+		RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &eFuseDataBuffer[i]);
+		efuseDataOffset -=  4;
+	}
+
+	//Update the value, the offset is multiple of 2, length is 2
+	efuseDataOffset = (Offset & 0xc) >> 2;
+	data = pData[0] & 0xffff;
+	//The offset should be 0x***10 or 0x***00
+	if((Offset % 4) != 0)
+	{
+		eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff) | (data << 16);
+	}
+	else
+	{
+		eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff0000) | data;
+	}
+
+	efuseDataOffset =  EFUSE_DATA3;
+	for(i=0; i< 4; i++)
+	{
+		RTMP_IO_WRITE32(pAd, efuseDataOffset, eFuseDataBuffer[i]);
+		efuseDataOffset -= 4;
+	}
+	/////////////////////////////////////////////////////////////////
+
+	//Step1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
+	eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
+
+	//Step2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.
+	eFuseCtrlStruc.field.EFSROM_MODE = 3;
+
+	//Step3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.
+	eFuseCtrlStruc.field.EFSROM_KICK = 1;
+
+	NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
+	RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
+
+	//Step4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It¡¦s done.
+	i = 0;
+	while(i < 100)
+	{
+		RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+
+		if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+			break;
+
+		RTMPusecDelay(2);
+		i++;
+	}
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+NTSTATUS eFuseWriteRegisters(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT Offset,
+	IN	USHORT Length,
+	IN	USHORT* pData)
+{
+	USHORT	i;
+	USHORT	eFuseData;
+	USHORT	LogicalAddress, BlkNum = 0xffff;
+	UCHAR	EFSROM_AOUT;
+
+	USHORT addr,tmpaddr, InBuf[3], tmpOffset;
+	USHORT buffer[8];
+	BOOLEAN		bWriteSuccess = TRUE;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters Offset=%x, pData=%x\n", Offset, *pData));
+
+	//Step 0. find the entry in the mapping table
+	//The address of EEPROM is 2-bytes alignment.
+	//The last bit is used for alignment, so it must be 0.
+	tmpOffset = Offset & 0xfffe;
+	EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData);
+
+	if( EFSROM_AOUT == 0x3f)
+	{	//find available logical address pointer
+		//the logical address does not exist, find an empty one
+		//from the first address of block 45=16*45=0x2d0 to the last address of block 47
+		//==>48*16-3(reserved)=2FC
+		for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
+		{
+			//Retrive the logical block nubmer form each logical address pointer
+			//It will access two logical address pointer each time.
+			eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
+			if( (LogicalAddress & 0xff) == 0)
+			{//Not used logical address pointer
+				BlkNum = i-EFUSE_USAGE_MAP_START;
+				break;
+			}
+			else if(( (LogicalAddress >> 8) & 0xff) == 0)
+			{//Not used logical address pointer
+				if (i != EFUSE_USAGE_MAP_END)
+				{
+					BlkNum = i-EFUSE_USAGE_MAP_START+1;
+				}
+				break;
+			}
+		}
+	}
+	else
+	{
+		BlkNum = EFSROM_AOUT;
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum));
+
+	if(BlkNum == 0xffff)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
+		return FALSE;
+	}
+
+	//Step 1. Save data of this block	which is pointed by the avaible logical address pointer
+	// read and save the original block data
+	for(i =0; i<8; i++)
+	{
+		addr = BlkNum * 0x10 ;
+
+		InBuf[0] = addr+2*i;
+		InBuf[1] = 2;
+		InBuf[2] = 0x0;
+
+		eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
+
+		buffer[i] = InBuf[2];
+	}
+
+	//Step 2. Update the data in buffer, and write the data to Efuse
+	buffer[ (Offset >> 1) % 8] = pData[0];
+
+	do
+	{
+		//Step 3. Write the data to Efuse
+		if(!bWriteSuccess)
+		{
+			for(i =0; i<8; i++)
+			{
+				addr = BlkNum * 0x10 ;
+
+				InBuf[0] = addr+2*i;
+				InBuf[1] = 2;
+				InBuf[2] = buffer[i];
+
+				eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
+			}
+		}
+		else
+		{
+				addr = BlkNum * 0x10 ;
+
+				InBuf[0] = addr+(Offset % 16);
+				InBuf[1] = 2;
+				InBuf[2] = pData[0];
+
+				eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
+		}
+
+		//Step 4. Write mapping table
+		addr = EFUSE_USAGE_MAP_START+BlkNum;
+
+		tmpaddr = addr;
+
+		if(addr % 2 != 0)
+			addr = addr -1;
+		InBuf[0] = addr;
+		InBuf[1] = 2;
+
+		//convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry
+		tmpOffset = Offset;
+		tmpOffset >>= 4;
+		tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^  (tmpOffset >> 2 & 0x01) ^  (tmpOffset >> 3 & 0x01))) << 6) & 0x40;
+		tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80;
+
+		// write the logical address
+		if(tmpaddr%2 != 0)
+			InBuf[2] = tmpOffset<<8;
+		else
+			InBuf[2] = tmpOffset;
+
+		eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0);
+
+		//Step 5. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted
+		bWriteSuccess = TRUE;
+		for(i =0; i<8; i++)
+		{
+			addr = BlkNum * 0x10 ;
+
+			InBuf[0] = addr+2*i;
+			InBuf[1] = 2;
+			InBuf[2] = 0x0;
+
+			eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
+
+			if(buffer[i] != InBuf[2])
+			{
+				bWriteSuccess = FALSE;
+				break;
+			}
+		}
+
+		//Step 6. invlidate mapping entry and find a free mapping entry if not succeed
+		if (!bWriteSuccess)
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess BlkNum = %d\n", BlkNum));
+
+			// the offset of current mapping entry
+			addr = EFUSE_USAGE_MAP_START+BlkNum;
+
+			//find a new mapping entry
+			BlkNum = 0xffff;
+			for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
+			{
+				eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
+				if( (LogicalAddress & 0xff) == 0)
+				{
+					BlkNum = i-EFUSE_USAGE_MAP_START;
+					break;
+				}
+				else if(( (LogicalAddress >> 8) & 0xff) == 0)
+				{
+					if (i != EFUSE_USAGE_MAP_END)
+					{
+						BlkNum = i+1-EFUSE_USAGE_MAP_START;
+					}
+					break;
+				}
+			}
+			DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess new BlkNum = %d\n", BlkNum));
+			if(BlkNum == 0xffff)
+			{
+				DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
+				return FALSE;
+			}
+
+			//invalidate the original mapping entry if new entry is not found
+			tmpaddr = addr;
+
+			if(addr % 2 != 0)
+				addr = addr -1;
+			InBuf[0] = addr;
+			InBuf[1] = 2;
+
+			eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
+
+			// write the logical address
+			if(tmpaddr%2 != 0)
+			{
+				// Invalidate the high byte
+				for (i=8; i<15; i++)
+				{
+					if( ( (InBuf[2] >> i) & 0x01) == 0)
+					{
+						InBuf[2] |= (0x1 <<i);
+						break;
+					}
+				}
+			}
+			else
+			{
+				// invalidate the low byte
+				for (i=0; i<8; i++)
+				{
+					if( ( (InBuf[2] >> i) & 0x01) == 0)
+					{
+						InBuf[2] |= (0x1 <<i);
+						break;
+					}
+				}
+			}
+			eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 0);
+		}
+	}
+	while(!bWriteSuccess);
+
+	return TRUE;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+VOID eFuseWritePhysical(
+	IN	PRTMP_ADAPTER	pAd,
+  	PUSHORT lpInBuffer,
+	ULONG nInBufferSize,
+  	PUCHAR lpOutBuffer,
+  	ULONG nOutBufferSize
+)
+{
+	USHORT* pInBuf = (USHORT*)lpInBuffer;
+	int 		i;
+	//USHORT* pOutBuf = (USHORT*)ioBuffer;
+
+	USHORT Offset = pInBuf[0];					//addr
+	USHORT Length = pInBuf[1];					//length
+	USHORT* pValueX = &pInBuf[2];				//value ...
+		// Little-endian		S	|	S	Big-endian
+		// addr	3	2	1	0	|	0	1	2	3
+		// Ori-V	D	C	B	A	|	A	B	C	D
+		//After swapping
+		//		D	C	B	A	|	D	C	B	A
+		//Both the little and big-endian use the same sequence to write  data.
+		//Therefore, we only need swap data when read the data.
+	for(i=0; i<Length; i+=2)
+	{
+		eFusePhysicalWriteRegisters(pAd, Offset+i, 2, &pValueX[i/2]);
+	}
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+NTSTATUS eFuseWrite(
+   	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT			Offset,
+	IN	PUCHAR			pData,
+	IN	USHORT			length)
+{
+	int i;
+
+	USHORT* pValueX = (PUSHORT) pData;				//value ...
+		//The input value=3070 will be stored as following
+ 		// Little-endian		S	|	S	Big-endian
+		// addr			1	0	|	0	1
+		// Ori-V			30	70	|	30	70
+		//After swapping
+		//				30	70	|	70	30
+		//Casting
+		//				3070	|	7030 (x)
+		//The swapping should be removed for big-endian
+	for(i=0; i<length; i+=2)
+	{
+		eFuseWriteRegisters(pAd, Offset+i, 2, &pValueX[i/2]);
+	}
+
+	return TRUE;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+INT set_eFuseGetFreeBlockCount_Proc(
+   	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	USHORT i;
+	USHORT	LogicalAddress;
+	USHORT efusefreenum=0;
+	if(!pAd->bUseEfuse)
+		return FALSE;
+	for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i+=2)
+	{
+		eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
+		if( (LogicalAddress & 0xff) == 0)
+		{
+			efusefreenum= (UCHAR) (EFUSE_USAGE_MAP_END-i+1);
+			break;
+		}
+		else if(( (LogicalAddress >> 8) & 0xff) == 0)
+		{
+			efusefreenum = (UCHAR) (EFUSE_USAGE_MAP_END-i);
+			break;
+		}
+
+		if(i == EFUSE_USAGE_MAP_END)
+			efusefreenum = 0;
+	}
+	printk("efuseFreeNumber is %d\n",efusefreenum);
+	return TRUE;
+}
+INT set_eFusedump_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+USHORT InBuf[3];
+	INT i=0;
+	if(!pAd->bUseEfuse)
+		return FALSE;
+	for(i =0; i<EFUSE_USAGE_MAP_END/2; i++)
+	{
+		InBuf[0] = 2*i;
+		InBuf[1] = 2;
+		InBuf[2] = 0x0;
+
+		eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
+		if(i%4==0)
+		printk("\nBlock %x:",i/8);
+		printk("%04x ",InBuf[2]);
+	}
+	return TRUE;
+}
+INT	set_eFuseLoadFromBin_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	CHAR					*src;
+	struct file				*srcf;
+	INT 					retval, orgfsuid, orgfsgid;
+   	mm_segment_t			orgfs;
+	UCHAR					*buffer;
+	UCHAR					BinFileSize=0;
+	INT						i = 0,j=0,k=1;
+	USHORT					*PDATA;
+	USHORT					DATA;
+	BinFileSize=strlen("RT30xxEEPROM.bin");
+	src = kmalloc(128, MEM_ALLOC_FLAG);
+	NdisZeroMemory(src, 128);
+
+ 	if(strlen(arg)>0)
+	{
+
+		NdisMoveMemory(src, arg, strlen(arg));
+ 	}
+
+	else
+	{
+
+		NdisMoveMemory(src, "RT30xxEEPROM.bin", BinFileSize);
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src));
+	buffer = kmalloc(MAX_EEPROM_BIN_FILE_SIZE, MEM_ALLOC_FLAG);
+
+	if(buffer == NULL)
+	{
+		kfree(src);
+		 return FALSE;
+}
+	PDATA=kmalloc(sizeof(USHORT)*8,MEM_ALLOC_FLAG);
+
+	if(PDATA==NULL)
+	{
+		kfree(src);
+
+		kfree(buffer);
+		return FALSE;
+	}
+	/* Don't change to uid 0, let the file be opened as the "normal" user */
+#if 0
+	orgfsuid = current->fsuid;
+	orgfsgid = current->fsgid;
+	current->fsuid=current->fsgid = 0;
+#endif
+    	orgfs = get_fs();
+   	 set_fs(KERNEL_DS);
+
+	if (src && *src)
+	{
+		srcf = filp_open(src, O_RDONLY, 0);
+		if (IS_ERR(srcf))
+		{
+			DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src));
+			return FALSE;
+		}
+		else
+		{
+			// The object must have a read method
+			if (srcf->f_op && srcf->f_op->read)
+			{
+				memset(buffer, 0x00, MAX_EEPROM_BIN_FILE_SIZE);
+				while(srcf->f_op->read(srcf, &buffer[i], 1, &srcf->f_pos)==1)
+				{
+					DBGPRINT(RT_DEBUG_TRACE, ("%02X ",buffer[i]));
+					if((i+1)%8==0)
+						DBGPRINT(RT_DEBUG_TRACE, ("\n"));
+              			i++;
+						if(i>=MAX_EEPROM_BIN_FILE_SIZE)
+							{
+								DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld reading %s, The file is too large[1024]\n", -PTR_ERR(srcf),src));
+								kfree(PDATA);
+								kfree(buffer);
+								kfree(src);
+								return FALSE;
+							}
+			       }
+			}
+			else
+			{
+						DBGPRINT(RT_DEBUG_ERROR, ("--> Error!! System doest not support read function\n"));
+						kfree(PDATA);
+						kfree(buffer);
+						kfree(src);
+						return FALSE;
+			}
+      		}
+
+
+	}
+	else
+		{
+					DBGPRINT(RT_DEBUG_ERROR, ("--> Error src  or srcf is null\n"));
+					kfree(PDATA);
+					kfree(buffer);
+					return FALSE;
+
+		}
+
+
+	retval=filp_close(srcf,NULL);
+
+	if (retval)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
+	}
+	set_fs(orgfs);
+#if 0
+	current->fsuid = orgfsuid;
+	current->fsgid = orgfsgid;
+#endif
+	for(j=0;j<i;j++)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("%02X ",buffer[j]));
+		if((j+1)%2==0)
+			PDATA[j/2%8]=((buffer[j]<<8)&0xff00)|(buffer[j-1]&0xff);
+		if(j%16==0)
+		{
+			k=buffer[j];
+		}
+		else
+		{
+			k&=buffer[j];
+			if((j+1)%16==0)
+			{
+
+				DBGPRINT(RT_DEBUG_TRACE, (" result=%02X,blk=%02x\n",k,j/16));
+
+				if(k!=0xff)
+					eFuseWriteRegistersFromBin(pAd,(USHORT)j-15, 16, PDATA);
+				else
+					{
+						if(eFuseReadRegisters(pAd,j, 2,(PUSHORT)&DATA)!=0x3f)
+							eFuseWriteRegistersFromBin(pAd,(USHORT)j-15, 16, PDATA);
+					}
+				/*
+				for(l=0;l<8;l++)
+					printk("%04x ",PDATA[l]);
+				printk("\n");
+				*/
+				NdisZeroMemory(PDATA,16);
+
+
+			}
+		}
+
+
+	}
+
+
+	kfree(PDATA);
+	kfree(buffer);
+	kfree(src);
+	return TRUE;
+}
+NTSTATUS eFuseWriteRegistersFromBin(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT Offset,
+	IN	USHORT Length,
+	IN	USHORT* pData)
+{
+	USHORT	i;
+	USHORT	eFuseData;
+	USHORT	LogicalAddress, BlkNum = 0xffff;
+	UCHAR	EFSROM_AOUT,Loop=0;
+	EFUSE_CTRL_STRUC		eFuseCtrlStruc;
+	USHORT	efuseDataOffset;
+	UINT32	data,tempbuffer;
+	USHORT addr,tmpaddr, InBuf[3], tmpOffset;
+	UINT32 buffer[4];
+	BOOLEAN		bWriteSuccess = TRUE;
+	BOOLEAN		bNotWrite=TRUE;
+	BOOLEAN		bAllocateNewBlk=TRUE;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin Offset=%x, pData=%04x:%04x:%04x:%04x\n", Offset, *pData,*(pData+1),*(pData+2),*(pData+3)));
+
+	do
+	{
+	//Step 0. find the entry in the mapping table
+	//The address of EEPROM is 2-bytes alignment.
+	//The last bit is used for alignment, so it must be 0.
+	Loop++;
+	tmpOffset = Offset & 0xfffe;
+	EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData);
+
+	if( EFSROM_AOUT == 0x3f)
+	{	//find available logical address pointer
+		//the logical address does not exist, find an empty one
+		//from the first address of block 45=16*45=0x2d0 to the last address of block 47
+		//==>48*16-3(reserved)=2FC
+		bAllocateNewBlk=TRUE;
+		for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
+		{
+			//Retrive the logical block nubmer form each logical address pointer
+			//It will access two logical address pointer each time.
+			eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
+			if( (LogicalAddress & 0xff) == 0)
+			{//Not used logical address pointer
+				BlkNum = i-EFUSE_USAGE_MAP_START;
+				break;
+			}
+			else if(( (LogicalAddress >> 8) & 0xff) == 0)
+			{//Not used logical address pointer
+				if (i != EFUSE_USAGE_MAP_END)
+				{
+					BlkNum = i-EFUSE_USAGE_MAP_START+1;
+				}
+				break;
+			}
+		}
+	}
+	else
+	{
+		bAllocateNewBlk=FALSE;
+		BlkNum = EFSROM_AOUT;
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum));
+
+	if(BlkNum == 0xffff)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
+		return FALSE;
+	}
+	//Step 1.1.0
+	//If the block is not existing in mapping table, create one
+	//and write down the 16-bytes data to the new block
+	if(bAllocateNewBlk)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk\n"));
+		efuseDataOffset =  EFUSE_DATA3;
+		for(i=0; i< 4; i++)
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk, Data%d=%04x%04x\n",3-i,pData[2*i+1],pData[2*i]));
+			tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i];
+
+
+			RTMP_IO_WRITE32(pAd, efuseDataOffset,tempbuffer);
+			efuseDataOffset -= 4;
+
+		}
+		/////////////////////////////////////////////////////////////////
+
+		//Step1.1.1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
+		eFuseCtrlStruc.field.EFSROM_AIN = BlkNum* 0x10 ;
+
+		//Step1.1.2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.
+		eFuseCtrlStruc.field.EFSROM_MODE = 3;
+
+		//Step1.1.3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.
+		eFuseCtrlStruc.field.EFSROM_KICK = 1;
+
+		NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
+
+		RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
+
+		//Step1.1.4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It¡¦s done.
+		i = 0;
+		while(i < 100)
+		{
+			RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+
+			if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+				break;
+
+			RTMPusecDelay(2);
+			i++;
+		}
+
+	}
+	else
+	{	//Step1.2.
+		//If the same logical number is existing, check if the writting data and the data
+		//saving in this block are the same.
+		/////////////////////////////////////////////////////////////////
+		//read current values of 16-byte block
+		RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+
+		//Step1.2.0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
+		eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
+
+		//Step1.2.1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
+		eFuseCtrlStruc.field.EFSROM_MODE = 0;
+
+		//Step1.2.2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
+		eFuseCtrlStruc.field.EFSROM_KICK = 1;
+
+		NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
+		RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
+
+		//Step1.2.3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
+		i = 0;
+		while(i < 100)
+		{
+			RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+
+			if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+				break;
+			RTMPusecDelay(2);
+			i++;
+		}
+
+		//Step1.2.4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
+		efuseDataOffset =  EFUSE_DATA3;
+		for(i=0; i< 4; i++)
+		{
+			RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &buffer[i]);
+			efuseDataOffset -=  4;
+		}
+		//Step1.2.5. Check if the data of efuse and the writing data are the same.
+		for(i =0; i<4; i++)
+		{
+			tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i];
+			DBGPRINT(RT_DEBUG_TRACE, ("buffer[%d]=%x,pData[%d]=%x,pData[%d]=%x,tempbuffer=%x\n",i,buffer[i],2*i,pData[2*i],2*i+1,pData[2*i+1],tempbuffer));
+
+			if(((buffer[i]&0xffff0000)==(pData[2*i+1]<<16))&&((buffer[i]&0xffff)==pData[2*i]))
+				bNotWrite&=TRUE;
+			else
+			{
+				bNotWrite&=FALSE;
+				break;
+			}
+		}
+		if(!bNotWrite)
+		{
+		printk("The data is not the same\n");
+
+			for(i =0; i<8; i++)
+			{
+				addr = BlkNum * 0x10 ;
+
+				InBuf[0] = addr+2*i;
+				InBuf[1] = 2;
+				InBuf[2] = pData[i];
+
+				eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
+			}
+
+		}
+		else
+			return TRUE;
+	     }
+
+
+
+		//Step 2. Write mapping table
+		addr = EFUSE_USAGE_MAP_START+BlkNum;
+
+		tmpaddr = addr;
+
+		if(addr % 2 != 0)
+			addr = addr -1;
+		InBuf[0] = addr;
+		InBuf[1] = 2;
+
+		//convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry
+		tmpOffset = Offset;
+		tmpOffset >>= 4;
+		tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^  (tmpOffset >> 2 & 0x01) ^  (tmpOffset >> 3 & 0x01))) << 6) & 0x40;
+		tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80;
+
+		// write the logical address
+		if(tmpaddr%2 != 0)
+			InBuf[2] = tmpOffset<<8;
+		else
+			InBuf[2] = tmpOffset;
+
+		eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0);
+
+		//Step 3. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted
+		bWriteSuccess = TRUE;
+		for(i =0; i<8; i++)
+		{
+			addr = BlkNum * 0x10 ;
+
+			InBuf[0] = addr+2*i;
+			InBuf[1] = 2;
+			InBuf[2] = 0x0;
+
+			eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
+			DBGPRINT(RT_DEBUG_TRACE, ("addr=%x, buffer[i]=%x,InBuf[2]=%x\n",InBuf[0],pData[i],InBuf[2]));
+			if(pData[i] != InBuf[2])
+			{
+				bWriteSuccess = FALSE;
+				break;
+			}
+		}
+
+		//Step 4. invlidate mapping entry and find a free mapping entry if not succeed
+
+		if (!bWriteSuccess&&Loop<2)
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess BlkNum = %d\n", BlkNum));
+
+			// the offset of current mapping entry
+			addr = EFUSE_USAGE_MAP_START+BlkNum;
+
+			//find a new mapping entry
+			BlkNum = 0xffff;
+			for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
+			{
+				eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
+				if( (LogicalAddress & 0xff) == 0)
+				{
+					BlkNum = i-EFUSE_USAGE_MAP_START;
+					break;
+				}
+				else if(( (LogicalAddress >> 8) & 0xff) == 0)
+				{
+					if (i != EFUSE_USAGE_MAP_END)
+					{
+						BlkNum = i+1-EFUSE_USAGE_MAP_START;
+					}
+					break;
+				}
+			}
+			DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess new BlkNum = %d\n", BlkNum));
+			if(BlkNum == 0xffff)
+			{
+				DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin: out of free E-fuse space!!!\n"));
+				return FALSE;
+			}
+
+			//invalidate the original mapping entry if new entry is not found
+			tmpaddr = addr;
+
+			if(addr % 2 != 0)
+				addr = addr -1;
+			InBuf[0] = addr;
+			InBuf[1] = 2;
+
+			eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
+
+			// write the logical address
+			if(tmpaddr%2 != 0)
+			{
+				// Invalidate the high byte
+				for (i=8; i<15; i++)
+				{
+					if( ( (InBuf[2] >> i) & 0x01) == 0)
+					{
+						InBuf[2] |= (0x1 <<i);
+						break;
+					}
+				}
+			}
+			else
+			{
+				// invalidate the low byte
+				for (i=0; i<8; i++)
+				{
+					if( ( (InBuf[2] >> i) & 0x01) == 0)
+					{
+						InBuf[2] |= (0x1 <<i);
+						break;
+					}
+				}
+			}
+			eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 0);
+		}
+
+	}
+	while(!bWriteSuccess&&Loop<2);
+
+	return TRUE;
+}
+
+#endif // RT30xx //
+//2008/09/11:KH add to support efuse-->
+
diff --git a/drivers/staging/rt3070/common/md5.c b/drivers/staging/rt3070/common/md5.c
new file mode 100644
index 0000000..774776b
--- /dev/null
+++ b/drivers/staging/rt3070/common/md5.c
@@ -0,0 +1,1427 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+    md5.c
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	Name		Date			Modification logs
+	jan			10-28-03		Initial
+	Rita    	11-23-04		Modify MD5 and SHA-1
+	Rita		10-14-05		Modify SHA-1 in big-endian platform
+ */
+#include "../rt_config.h"
+
+/**
+ * md5_mac:
+ * @key: pointer to	the	key	used for MAC generation
+ * @key_len: length	of the key in bytes
+ * @data: pointer to the data area for which the MAC is	generated
+ * @data_len: length of	the	data in	bytes
+ * @mac: pointer to	the	buffer holding space for the MAC; the buffer should
+ * have	space for 128-bit (16 bytes) MD5 hash value
+ *
+ * md5_mac() determines	the	message	authentication code	by using secure	hash
+ * MD5(key | data |	key).
+ */
+void md5_mac(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac)
+{
+	MD5_CTX	context;
+
+	MD5Init(&context);
+	MD5Update(&context,	key, key_len);
+	MD5Update(&context,	data, data_len);
+	MD5Update(&context,	key, key_len);
+	MD5Final(mac, &context);
+}
+
+/**
+ * hmac_md5:
+ * @key: pointer to	the	key	used for MAC generation
+ * @key_len: length	of the key in bytes
+ * @data: pointer to the data area for which the MAC is	generated
+ * @data_len: length of	the	data in	bytes
+ * @mac: pointer to	the	buffer holding space for the MAC; the buffer should
+ * have	space for 128-bit (16 bytes) MD5 hash value
+ *
+ * hmac_md5() determines the message authentication	code using HMAC-MD5.
+ * This	implementation is based	on the sample code presented in	RFC	2104.
+ */
+void hmac_md5(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac)
+{
+	MD5_CTX	context;
+    u8 k_ipad[65]; /* inner padding - key XORd with ipad */
+    u8 k_opad[65]; /* outer padding - key XORd with opad */
+    u8 tk[16];
+	int	i;
+
+	//assert(key != NULL && data != NULL && mac != NULL);
+
+	/* if key is longer	than 64	bytes reset	it to key =	MD5(key) */
+	if (key_len	> 64) {
+		MD5_CTX	ttcontext;
+
+		MD5Init(&ttcontext);
+		MD5Update(&ttcontext, key, key_len);
+		MD5Final(tk, &ttcontext);
+		//key=(PUCHAR)ttcontext.buf;
+		key	= tk;
+		key_len	= 16;
+	}
+
+	/* the HMAC_MD5	transform looks	like:
+	 *
+	 * MD5(K XOR opad, MD5(K XOR ipad, text))
+	 *
+	 * where K is an n byte	key
+	 * ipad	is the byte	0x36 repeated 64 times
+	 * opad	is the byte	0x5c repeated 64 times
+	 * and text	is the data	being protected	*/
+
+	/* start out by	storing	key	in pads	*/
+	NdisZeroMemory(k_ipad, sizeof(k_ipad));
+	NdisZeroMemory(k_opad,	sizeof(k_opad));
+	//assert(key_len < sizeof(k_ipad));
+	NdisMoveMemory(k_ipad, key,	key_len);
+	NdisMoveMemory(k_opad, key,	key_len);
+
+	/* XOR key with	ipad and opad values */
+	for	(i = 0;	i <	64;	i++) {
+		k_ipad[i] ^= 0x36;
+		k_opad[i] ^= 0x5c;
+	}
+
+	/* perform inner MD5 */
+	MD5Init(&context);					 /*	init context for 1st pass */
+	MD5Update(&context,	k_ipad,	64);	 /*	start with inner pad */
+	MD5Update(&context,	data, data_len); /*	then text of datagram */
+	MD5Final(mac, &context);			 /*	finish up 1st pass */
+
+	/* perform outer MD5 */
+	MD5Init(&context);					 /*	init context for 2nd pass */
+	MD5Update(&context,	k_opad,	64);	 /*	start with outer pad */
+	MD5Update(&context,	mac, 16);		 /*	then results of	1st	hash */
+	MD5Final(mac, &context);			 /*	finish up 2nd pass */
+}
+
+#ifndef RT_BIG_ENDIAN
+#define byteReverse(buf, len)   /* Nothing */
+#else
+void byteReverse(unsigned char *buf, unsigned longs);
+void byteReverse(unsigned char *buf, unsigned longs)
+{
+    do {
+        *(UINT32 *)buf = SWAP32(*(UINT32 *)buf);
+        buf += 4;
+    } while (--longs);
+}
+#endif
+
+
+/* ==========================  MD5 implementation =========================== */
+// four base functions for MD5
+#define MD5_F1(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define MD5_F2(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define MD5_F3(x, y, z) ((x) ^ (y) ^ (z))
+#define MD5_F4(x, y, z) ((y) ^ ((x) | (~z)))
+#define CYCLIC_LEFT_SHIFT(w, s) (((w) << (s)) | ((w) >> (32-(s))))
+
+#define	MD5Step(f, w, x, y,	z, data, t, s)	\
+	( w	+= f(x,	y, z) +	data + t,  w = (CYCLIC_LEFT_SHIFT(w, s)) & 0xffffffff, w +=	x )
+
+
+/*
+ *  Function Description:
+ *      Initiate MD5 Context satisfied in RFC 1321
+ *
+ *  Arguments:
+ *      pCtx        Pointer	to MD5 context
+ *
+ *  Return Value:
+ *      None
+ */
+VOID MD5Init(MD5_CTX *pCtx)
+{
+    pCtx->Buf[0]=0x67452301;
+    pCtx->Buf[1]=0xefcdab89;
+    pCtx->Buf[2]=0x98badcfe;
+    pCtx->Buf[3]=0x10325476;
+
+    pCtx->LenInBitCount[0]=0;
+    pCtx->LenInBitCount[1]=0;
+}
+
+
+/*
+ *  Function Description:
+ *      Update MD5 Context, allow of an arrary of octets as the next portion
+ *      of the message
+ *
+ *  Arguments:
+ *      pCtx		Pointer	to MD5 context
+ * 	    pData       Pointer to input data
+ *      LenInBytes  The length of input data (unit: byte)
+ *
+ *  Return Value:
+ *      None
+ *
+ *  Note:
+ *      Called after MD5Init or MD5Update(itself)
+ */
+VOID MD5Update(MD5_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes)
+{
+
+    UINT32 TfTimes;
+    UINT32 temp;
+	unsigned int i;
+
+    temp = pCtx->LenInBitCount[0];
+
+    pCtx->LenInBitCount[0] = (UINT32) (pCtx->LenInBitCount[0] + (LenInBytes << 3));
+
+    if (pCtx->LenInBitCount[0] < temp)
+        pCtx->LenInBitCount[1]++;   //carry in
+
+    pCtx->LenInBitCount[1] += LenInBytes >> 29;
+
+    // mod 64 bytes
+    temp = (temp >> 3) & 0x3f;
+
+    // process lacks of 64-byte data
+    if (temp)
+    {
+        UCHAR *pAds = (UCHAR *) pCtx->Input + temp;
+
+        if ((temp+LenInBytes) < 64)
+        {
+            NdisMoveMemory(pAds, (UCHAR *)pData, LenInBytes);
+            return;
+        }
+
+        NdisMoveMemory(pAds, (UCHAR *)pData, 64-temp);
+        byteReverse(pCtx->Input, 16);
+        MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
+
+        pData += 64-temp;
+        LenInBytes -= 64-temp;
+    } // end of if (temp)
+
+
+    TfTimes = (LenInBytes >> 6);
+
+    for (i=TfTimes; i>0; i--)
+    {
+        NdisMoveMemory(pCtx->Input, (UCHAR *)pData, 64);
+        byteReverse(pCtx->Input, 16);
+        MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
+        pData += 64;
+        LenInBytes -= 64;
+    } // end of for
+
+    // buffering lacks of 64-byte data
+    if(LenInBytes)
+        NdisMoveMemory(pCtx->Input, (UCHAR *)pData, LenInBytes);
+
+}
+
+
+/*
+ *  Function Description:
+ *      Append padding bits and length of original message in the tail
+ *      The message digest has to be completed in the end
+ *
+ *  Arguments:
+ *      Digest		Output of Digest-Message for MD5
+ *  	pCtx        Pointer	to MD5 context
+ *
+ *  Return Value:
+ *      None
+ *
+ *  Note:
+ *      Called after MD5Update
+ */
+VOID MD5Final(UCHAR Digest[16], MD5_CTX *pCtx)
+{
+    UCHAR Remainder;
+    UCHAR PadLenInBytes;
+    UCHAR *pAppend=0;
+    unsigned int i;
+
+    Remainder = (UCHAR)((pCtx->LenInBitCount[0] >> 3) & 0x3f);
+
+    PadLenInBytes = (Remainder < 56) ? (56-Remainder) : (120-Remainder);
+
+    pAppend = (UCHAR *)pCtx->Input + Remainder;
+
+    // padding bits without crossing block(64-byte based) boundary
+    if (Remainder < 56)
+    {
+        *pAppend = 0x80;
+        PadLenInBytes --;
+
+        NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, PadLenInBytes);
+
+		// add data-length field, from low to high
+       	for (i=0; i<4; i++)
+        {
+        	pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[0] >> (i << 3)) & 0xff);
+        	pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[1] >> (i << 3)) & 0xff);
+      	}
+
+        byteReverse(pCtx->Input, 16);
+        MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
+    } // end of if
+
+    // padding bits with crossing block(64-byte based) boundary
+    else
+    {
+        // the first block ===
+        *pAppend = 0x80;
+        PadLenInBytes --;
+
+        NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, (64-Remainder-1));
+        PadLenInBytes -= (64 - Remainder - 1);
+
+        byteReverse(pCtx->Input, 16);
+        MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
+
+
+        // the second block ===
+        NdisZeroMemory((UCHAR *)pCtx->Input, PadLenInBytes);
+
+        // add data-length field
+        for (i=0; i<4; i++)
+        {
+        	pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[0] >> (i << 3)) & 0xff);
+        	pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[1] >> (i << 3)) & 0xff);
+      	}
+
+        byteReverse(pCtx->Input, 16);
+        MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
+    } // end of else
+
+
+    NdisMoveMemory((UCHAR *)Digest, (UINT32 *)pCtx->Buf, 16); // output
+    byteReverse((UCHAR *)Digest, 4);
+    NdisZeroMemory(pCtx, sizeof(pCtx)); // memory free
+}
+
+
+/*
+ *  Function Description:
+ *      The central algorithm of MD5, consists of four rounds and sixteen
+ *  	steps per round
+ *
+ *  Arguments:
+ *      Buf     Buffers of four states (output: 16 bytes)
+ * 	    Mes     Input data (input: 64 bytes)
+ *
+ *  Return Value:
+ *      None
+ *
+ *  Note:
+ *      Called by MD5Update or MD5Final
+ */
+VOID MD5Transform(UINT32 Buf[4], UINT32 Mes[16])
+{
+    UINT32 Reg[4], Temp;
+	unsigned int i;
+
+    static UCHAR LShiftVal[16] =
+    {
+        7, 12, 17, 22,
+		5, 9 , 14, 20,
+		4, 11, 16, 23,
+ 		6, 10, 15, 21,
+ 	};
+
+
+	// [equal to 4294967296*abs(sin(index))]
+    static UINT32 MD5Table[64] =
+	{
+		0xd76aa478,	0xe8c7b756,	0x242070db,	0xc1bdceee,
+		0xf57c0faf,	0x4787c62a,	0xa8304613, 0xfd469501,
+		0x698098d8,	0x8b44f7af,	0xffff5bb1,	0x895cd7be,
+    	0x6b901122,	0xfd987193,	0xa679438e,	0x49b40821,
+
+    	0xf61e2562,	0xc040b340,	0x265e5a51,	0xe9b6c7aa,
+    	0xd62f105d,	0x02441453,	0xd8a1e681,	0xe7d3fbc8,
+    	0x21e1cde6,	0xc33707d6,	0xf4d50d87,	0x455a14ed,
+    	0xa9e3e905,	0xfcefa3f8,	0x676f02d9,	0x8d2a4c8a,
+
+    	0xfffa3942,	0x8771f681,	0x6d9d6122,	0xfde5380c,
+    	0xa4beea44,	0x4bdecfa9,	0xf6bb4b60,	0xbebfbc70,
+    	0x289b7ec6,	0xeaa127fa,	0xd4ef3085,	0x04881d05,
+    	0xd9d4d039,	0xe6db99e5,	0x1fa27cf8,	0xc4ac5665,
+
+    	0xf4292244,	0x432aff97,	0xab9423a7,	0xfc93a039,
+   		0x655b59c3,	0x8f0ccc92,	0xffeff47d,	0x85845dd1,
+    	0x6fa87e4f,	0xfe2ce6e0,	0xa3014314,	0x4e0811a1,
+    	0xf7537e82,	0xbd3af235,	0x2ad7d2bb,	0xeb86d391
+	};
+
+
+    for (i=0; i<4; i++)
+        Reg[i]=Buf[i];
+
+
+    // 64 steps in MD5 algorithm
+    for (i=0; i<16; i++)
+    {
+        MD5Step(MD5_F1, Reg[0], Reg[1], Reg[2], Reg[3], Mes[i],
+                MD5Table[i], LShiftVal[i & 0x3]);
+
+        // one-word right shift
+        Temp   = Reg[3];
+        Reg[3] = Reg[2];
+        Reg[2] = Reg[1];
+        Reg[1] = Reg[0];
+        Reg[0] = Temp;
+    }
+    for (i=16; i<32; i++)
+    {
+        MD5Step(MD5_F2, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(5*(i & 0xf)+1) & 0xf],
+                MD5Table[i], LShiftVal[(0x1 << 2)+(i & 0x3)]);
+
+        // one-word right shift
+        Temp   = Reg[3];
+        Reg[3] = Reg[2];
+        Reg[2] = Reg[1];
+        Reg[1] = Reg[0];
+        Reg[0] = Temp;
+    }
+    for (i=32; i<48; i++)
+    {
+        MD5Step(MD5_F3, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(3*(i & 0xf)+5) & 0xf],
+                MD5Table[i], LShiftVal[(0x1 << 3)+(i & 0x3)]);
+
+        // one-word right shift
+        Temp   = Reg[3];
+        Reg[3] = Reg[2];
+        Reg[2] = Reg[1];
+        Reg[1] = Reg[0];
+        Reg[0] = Temp;
+    }
+    for (i=48; i<64; i++)
+    {
+        MD5Step(MD5_F4, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(7*(i & 0xf)) & 0xf],
+                MD5Table[i], LShiftVal[(0x3 << 2)+(i & 0x3)]);
+
+        // one-word right shift
+        Temp   = Reg[3];
+        Reg[3] = Reg[2];
+        Reg[2] = Reg[1];
+        Reg[1] = Reg[0];
+        Reg[0] = Temp;
+    }
+
+
+    // (temporary)output
+    for (i=0; i<4; i++)
+        Buf[i] += Reg[i];
+
+}
+
+
+
+/* =========================  SHA-1 implementation ========================== */
+// four base functions for SHA-1
+#define SHA1_F1(b, c, d)    (((b) & (c)) | ((~b) & (d)))
+#define SHA1_F2(b, c, d)    ((b) ^ (c) ^ (d))
+#define SHA1_F3(b, c, d)    (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
+
+
+#define SHA1Step(f, a, b, c, d, e, w, k)    \
+    ( e	+= ( f(b, c, d) + w + k + CYCLIC_LEFT_SHIFT(a, 5)) & 0xffffffff, \
+      b = CYCLIC_LEFT_SHIFT(b, 30) )
+
+//Initiate SHA-1 Context satisfied in RFC 3174
+VOID SHAInit(SHA_CTX *pCtx)
+{
+    pCtx->Buf[0]=0x67452301;
+    pCtx->Buf[1]=0xefcdab89;
+    pCtx->Buf[2]=0x98badcfe;
+    pCtx->Buf[3]=0x10325476;
+    pCtx->Buf[4]=0xc3d2e1f0;
+
+    pCtx->LenInBitCount[0]=0;
+    pCtx->LenInBitCount[1]=0;
+}
+
+/*
+ *  Function Description:
+ *      Update SHA-1 Context, allow of an arrary of octets as the next
+ *      portion of the message
+ *
+ *  Arguments:
+ *      pCtx		Pointer	to SHA-1 context
+ * 	    pData       Pointer to input data
+ *      LenInBytes  The length of input data (unit: byte)
+ *
+ *  Return Value:
+ *      error       indicate more than pow(2,64) bits of data
+ *
+ *  Note:
+ *      Called after SHAInit or SHAUpdate(itself)
+ */
+UCHAR SHAUpdate(SHA_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes)
+{
+    UINT32 TfTimes;
+    UINT32 temp1,temp2;
+	unsigned int i;
+	UCHAR err=1;
+
+    temp1 = pCtx->LenInBitCount[0];
+    temp2 = pCtx->LenInBitCount[1];
+
+    pCtx->LenInBitCount[0] = (UINT32) (pCtx->LenInBitCount[0] + (LenInBytes << 3));
+    if (pCtx->LenInBitCount[0] < temp1)
+        pCtx->LenInBitCount[1]++;   //carry in
+
+
+    pCtx->LenInBitCount[1] = (UINT32) (pCtx->LenInBitCount[1] +(LenInBytes >> 29));
+    if (pCtx->LenInBitCount[1] < temp2)
+        return (err);   //check total length of original data
+
+
+    // mod 64 bytes
+    temp1 = (temp1 >> 3) & 0x3f;
+
+    // process lacks of 64-byte data
+    if (temp1)
+    {
+        UCHAR *pAds = (UCHAR *) pCtx->Input + temp1;
+
+        if ((temp1+LenInBytes) < 64)
+        {
+            NdisMoveMemory(pAds, (UCHAR *)pData, LenInBytes);
+            return (0);
+        }
+
+        NdisMoveMemory(pAds, (UCHAR *)pData, 64-temp1);
+        byteReverse((UCHAR *)pCtx->Input, 16);
+
+        NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
+        SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
+
+        pData += 64-temp1;
+        LenInBytes -= 64-temp1;
+    } // end of if (temp1)
+
+
+    TfTimes = (LenInBytes >> 6);
+
+    for (i=TfTimes; i>0; i--)
+    {
+        NdisMoveMemory(pCtx->Input, (UCHAR *)pData, 64);
+        byteReverse((UCHAR *)pCtx->Input, 16);
+
+        NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
+        SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
+        pData += 64;
+        LenInBytes -= 64;
+    } // end of for
+
+    // buffering lacks of 64-byte data
+    if(LenInBytes)
+        NdisMoveMemory(pCtx->Input, (UCHAR *)pData, LenInBytes);
+
+	return (0);
+
+}
+
+// Append padding bits and length of original message in the tail
+// The message digest has to be completed in the end
+VOID SHAFinal(SHA_CTX *pCtx, UCHAR Digest[20])
+{
+    UCHAR Remainder;
+    UCHAR PadLenInBytes;
+    UCHAR *pAppend=0;
+    unsigned int i;
+
+    Remainder = (UCHAR)((pCtx->LenInBitCount[0] >> 3) & 0x3f);
+
+    pAppend = (UCHAR *)pCtx->Input + Remainder;
+
+    PadLenInBytes = (Remainder < 56) ? (56-Remainder) : (120-Remainder);
+
+    // padding bits without crossing block(64-byte based) boundary
+    if (Remainder < 56)
+    {
+        *pAppend = 0x80;
+        PadLenInBytes --;
+
+        NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, PadLenInBytes);
+
+		// add data-length field, from high to low
+        for (i=0; i<4; i++)
+        {
+        	pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[1] >> ((3-i) << 3)) & 0xff);
+        	pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[0] >> ((3-i) << 3)) & 0xff);
+      	}
+
+        byteReverse((UCHAR *)pCtx->Input, 16);
+        NdisZeroMemory((UCHAR *)pCtx->Input + 64, 14);
+        SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
+    } // end of if
+
+    // padding bits with crossing block(64-byte based) boundary
+    else
+    {
+        // the first block ===
+        *pAppend = 0x80;
+        PadLenInBytes --;
+
+        NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, (64-Remainder-1));
+        PadLenInBytes -= (64 - Remainder - 1);
+
+        byteReverse((UCHAR *)pCtx->Input, 16);
+        NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
+        SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
+
+
+        // the second block ===
+        NdisZeroMemory((UCHAR *)pCtx->Input, PadLenInBytes);
+
+		// add data-length field
+		for (i=0; i<4; i++)
+        {
+        	pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[1] >> ((3-i) << 3)) & 0xff);
+        	pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[0] >> ((3-i) << 3)) & 0xff);
+      	}
+
+        byteReverse((UCHAR *)pCtx->Input, 16);
+        NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
+        SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
+    } // end of else
+
+
+    //Output, bytereverse
+    for (i=0; i<20; i++)
+    {
+        Digest [i] = (UCHAR)(pCtx->Buf[i>>2] >> 8*(3-(i & 0x3)));
+    }
+
+    NdisZeroMemory(pCtx, sizeof(pCtx)); // memory free
+}
+
+
+// The central algorithm of SHA-1, consists of four rounds and
+// twenty steps per round
+VOID SHATransform(UINT32 Buf[5], UINT32 Mes[20])
+{
+    UINT32 Reg[5],Temp;
+	unsigned int i;
+    UINT32 W[80];
+
+    static UINT32 SHA1Table[4] = { 0x5a827999, 0x6ed9eba1,
+                                  0x8f1bbcdc, 0xca62c1d6 };
+
+    Reg[0]=Buf[0];
+	Reg[1]=Buf[1];
+	Reg[2]=Buf[2];
+	Reg[3]=Buf[3];
+	Reg[4]=Buf[4];
+
+    //the first octet of a word is stored in the 0th element, bytereverse
+	for(i = 0; i < 16; i++)
+    {
+    	W[i]  = (Mes[i] >> 24) & 0xff;
+        W[i] |= (Mes[i] >> 8 ) & 0xff00;
+        W[i] |= (Mes[i] << 8 ) & 0xff0000;
+        W[i] |= (Mes[i] << 24) & 0xff000000;
+    }
+
+
+    for	(i = 0; i < 64; i++)
+	    W[16+i] = CYCLIC_LEFT_SHIFT(W[i] ^ W[2+i] ^ W[8+i] ^ W[13+i], 1);
+
+
+    // 80 steps in SHA-1 algorithm
+    for (i=0; i<80; i++)
+    {
+        if (i<20)
+            SHA1Step(SHA1_F1, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4],
+                     W[i], SHA1Table[0]);
+
+        else if (i>=20 && i<40)
+            SHA1Step(SHA1_F2, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4],
+                     W[i], SHA1Table[1]);
+
+		else if (i>=40 && i<60)
+            SHA1Step(SHA1_F3, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4],
+                      W[i], SHA1Table[2]);
+
+        else
+            SHA1Step(SHA1_F2, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4],
+                     W[i], SHA1Table[3]);
+
+
+       // one-word right shift
+		Temp   = Reg[4];
+        Reg[4] = Reg[3];
+        Reg[3] = Reg[2];
+        Reg[2] = Reg[1];
+        Reg[1] = Reg[0];
+        Reg[0] = Temp;
+
+    } // end of for-loop
+
+
+    // (temporary)output
+    for (i=0; i<5; i++)
+        Buf[i] += Reg[i];
+
+}
+
+
+/* =========================  AES En/Decryption ========================== */
+
+/* forward S-box */
+static uint32 FSb[256] =
+{
+	0x63, 0x7C,	0x77, 0x7B,	0xF2, 0x6B,	0x6F, 0xC5,
+	0x30, 0x01,	0x67, 0x2B,	0xFE, 0xD7,	0xAB, 0x76,
+	0xCA, 0x82,	0xC9, 0x7D,	0xFA, 0x59,	0x47, 0xF0,
+	0xAD, 0xD4,	0xA2, 0xAF,	0x9C, 0xA4,	0x72, 0xC0,
+	0xB7, 0xFD,	0x93, 0x26,	0x36, 0x3F,	0xF7, 0xCC,
+	0x34, 0xA5,	0xE5, 0xF1,	0x71, 0xD8,	0x31, 0x15,
+	0x04, 0xC7,	0x23, 0xC3,	0x18, 0x96,	0x05, 0x9A,
+	0x07, 0x12,	0x80, 0xE2,	0xEB, 0x27,	0xB2, 0x75,
+	0x09, 0x83,	0x2C, 0x1A,	0x1B, 0x6E,	0x5A, 0xA0,
+	0x52, 0x3B,	0xD6, 0xB3,	0x29, 0xE3,	0x2F, 0x84,
+	0x53, 0xD1,	0x00, 0xED,	0x20, 0xFC,	0xB1, 0x5B,
+	0x6A, 0xCB,	0xBE, 0x39,	0x4A, 0x4C,	0x58, 0xCF,
+	0xD0, 0xEF,	0xAA, 0xFB,	0x43, 0x4D,	0x33, 0x85,
+	0x45, 0xF9,	0x02, 0x7F,	0x50, 0x3C,	0x9F, 0xA8,
+	0x51, 0xA3,	0x40, 0x8F,	0x92, 0x9D,	0x38, 0xF5,
+	0xBC, 0xB6,	0xDA, 0x21,	0x10, 0xFF,	0xF3, 0xD2,
+	0xCD, 0x0C,	0x13, 0xEC,	0x5F, 0x97,	0x44, 0x17,
+	0xC4, 0xA7,	0x7E, 0x3D,	0x64, 0x5D,	0x19, 0x73,
+	0x60, 0x81,	0x4F, 0xDC,	0x22, 0x2A,	0x90, 0x88,
+	0x46, 0xEE,	0xB8, 0x14,	0xDE, 0x5E,	0x0B, 0xDB,
+	0xE0, 0x32,	0x3A, 0x0A,	0x49, 0x06,	0x24, 0x5C,
+	0xC2, 0xD3,	0xAC, 0x62,	0x91, 0x95,	0xE4, 0x79,
+	0xE7, 0xC8,	0x37, 0x6D,	0x8D, 0xD5,	0x4E, 0xA9,
+	0x6C, 0x56,	0xF4, 0xEA,	0x65, 0x7A,	0xAE, 0x08,
+	0xBA, 0x78,	0x25, 0x2E,	0x1C, 0xA6,	0xB4, 0xC6,
+	0xE8, 0xDD,	0x74, 0x1F,	0x4B, 0xBD,	0x8B, 0x8A,
+	0x70, 0x3E,	0xB5, 0x66,	0x48, 0x03,	0xF6, 0x0E,
+	0x61, 0x35,	0x57, 0xB9,	0x86, 0xC1,	0x1D, 0x9E,
+	0xE1, 0xF8,	0x98, 0x11,	0x69, 0xD9,	0x8E, 0x94,
+	0x9B, 0x1E,	0x87, 0xE9,	0xCE, 0x55,	0x28, 0xDF,
+	0x8C, 0xA1,	0x89, 0x0D,	0xBF, 0xE6,	0x42, 0x68,
+	0x41, 0x99,	0x2D, 0x0F,	0xB0, 0x54,	0xBB, 0x16
+};
+
+/* forward table */
+#define	FT \
+\
+	V(C6,63,63,A5),	V(F8,7C,7C,84),	V(EE,77,77,99),	V(F6,7B,7B,8D),	\
+	V(FF,F2,F2,0D),	V(D6,6B,6B,BD),	V(DE,6F,6F,B1),	V(91,C5,C5,54),	\
+	V(60,30,30,50),	V(02,01,01,03),	V(CE,67,67,A9),	V(56,2B,2B,7D),	\
+	V(E7,FE,FE,19),	V(B5,D7,D7,62),	V(4D,AB,AB,E6),	V(EC,76,76,9A),	\
+	V(8F,CA,CA,45),	V(1F,82,82,9D),	V(89,C9,C9,40),	V(FA,7D,7D,87),	\
+	V(EF,FA,FA,15),	V(B2,59,59,EB),	V(8E,47,47,C9),	V(FB,F0,F0,0B),	\
+	V(41,AD,AD,EC),	V(B3,D4,D4,67),	V(5F,A2,A2,FD),	V(45,AF,AF,EA),	\
+	V(23,9C,9C,BF),	V(53,A4,A4,F7),	V(E4,72,72,96),	V(9B,C0,C0,5B),	\
+	V(75,B7,B7,C2),	V(E1,FD,FD,1C),	V(3D,93,93,AE),	V(4C,26,26,6A),	\
+	V(6C,36,36,5A),	V(7E,3F,3F,41),	V(F5,F7,F7,02),	V(83,CC,CC,4F),	\
+	V(68,34,34,5C),	V(51,A5,A5,F4),	V(D1,E5,E5,34),	V(F9,F1,F1,08),	\
+	V(E2,71,71,93),	V(AB,D8,D8,73),	V(62,31,31,53),	V(2A,15,15,3F),	\
+	V(08,04,04,0C),	V(95,C7,C7,52),	V(46,23,23,65),	V(9D,C3,C3,5E),	\
+	V(30,18,18,28),	V(37,96,96,A1),	V(0A,05,05,0F),	V(2F,9A,9A,B5),	\
+	V(0E,07,07,09),	V(24,12,12,36),	V(1B,80,80,9B),	V(DF,E2,E2,3D),	\
+	V(CD,EB,EB,26),	V(4E,27,27,69),	V(7F,B2,B2,CD),	V(EA,75,75,9F),	\
+	V(12,09,09,1B),	V(1D,83,83,9E),	V(58,2C,2C,74),	V(34,1A,1A,2E),	\
+	V(36,1B,1B,2D),	V(DC,6E,6E,B2),	V(B4,5A,5A,EE),	V(5B,A0,A0,FB),	\
+	V(A4,52,52,F6),	V(76,3B,3B,4D),	V(B7,D6,D6,61),	V(7D,B3,B3,CE),	\
+	V(52,29,29,7B),	V(DD,E3,E3,3E),	V(5E,2F,2F,71),	V(13,84,84,97),	\
+	V(A6,53,53,F5),	V(B9,D1,D1,68),	V(00,00,00,00),	V(C1,ED,ED,2C),	\
+	V(40,20,20,60),	V(E3,FC,FC,1F),	V(79,B1,B1,C8),	V(B6,5B,5B,ED),	\
+	V(D4,6A,6A,BE),	V(8D,CB,CB,46),	V(67,BE,BE,D9),	V(72,39,39,4B),	\
+	V(94,4A,4A,DE),	V(98,4C,4C,D4),	V(B0,58,58,E8),	V(85,CF,CF,4A),	\
+	V(BB,D0,D0,6B),	V(C5,EF,EF,2A),	V(4F,AA,AA,E5),	V(ED,FB,FB,16),	\
+	V(86,43,43,C5),	V(9A,4D,4D,D7),	V(66,33,33,55),	V(11,85,85,94),	\
+	V(8A,45,45,CF),	V(E9,F9,F9,10),	V(04,02,02,06),	V(FE,7F,7F,81),	\
+	V(A0,50,50,F0),	V(78,3C,3C,44),	V(25,9F,9F,BA),	V(4B,A8,A8,E3),	\
+	V(A2,51,51,F3),	V(5D,A3,A3,FE),	V(80,40,40,C0),	V(05,8F,8F,8A),	\
+	V(3F,92,92,AD),	V(21,9D,9D,BC),	V(70,38,38,48),	V(F1,F5,F5,04),	\
+	V(63,BC,BC,DF),	V(77,B6,B6,C1),	V(AF,DA,DA,75),	V(42,21,21,63),	\
+	V(20,10,10,30),	V(E5,FF,FF,1A),	V(FD,F3,F3,0E),	V(BF,D2,D2,6D),	\
+	V(81,CD,CD,4C),	V(18,0C,0C,14),	V(26,13,13,35),	V(C3,EC,EC,2F),	\
+	V(BE,5F,5F,E1),	V(35,97,97,A2),	V(88,44,44,CC),	V(2E,17,17,39),	\
+	V(93,C4,C4,57),	V(55,A7,A7,F2),	V(FC,7E,7E,82),	V(7A,3D,3D,47),	\
+	V(C8,64,64,AC),	V(BA,5D,5D,E7),	V(32,19,19,2B),	V(E6,73,73,95),	\
+	V(C0,60,60,A0),	V(19,81,81,98),	V(9E,4F,4F,D1),	V(A3,DC,DC,7F),	\
+	V(44,22,22,66),	V(54,2A,2A,7E),	V(3B,90,90,AB),	V(0B,88,88,83),	\
+	V(8C,46,46,CA),	V(C7,EE,EE,29),	V(6B,B8,B8,D3),	V(28,14,14,3C),	\
+	V(A7,DE,DE,79),	V(BC,5E,5E,E2),	V(16,0B,0B,1D),	V(AD,DB,DB,76),	\
+	V(DB,E0,E0,3B),	V(64,32,32,56),	V(74,3A,3A,4E),	V(14,0A,0A,1E),	\
+	V(92,49,49,DB),	V(0C,06,06,0A),	V(48,24,24,6C),	V(B8,5C,5C,E4),	\
+	V(9F,C2,C2,5D),	V(BD,D3,D3,6E),	V(43,AC,AC,EF),	V(C4,62,62,A6),	\
+	V(39,91,91,A8),	V(31,95,95,A4),	V(D3,E4,E4,37),	V(F2,79,79,8B),	\
+	V(D5,E7,E7,32),	V(8B,C8,C8,43),	V(6E,37,37,59),	V(DA,6D,6D,B7),	\
+	V(01,8D,8D,8C),	V(B1,D5,D5,64),	V(9C,4E,4E,D2),	V(49,A9,A9,E0),	\
+	V(D8,6C,6C,B4),	V(AC,56,56,FA),	V(F3,F4,F4,07),	V(CF,EA,EA,25),	\
+	V(CA,65,65,AF),	V(F4,7A,7A,8E),	V(47,AE,AE,E9),	V(10,08,08,18),	\
+	V(6F,BA,BA,D5),	V(F0,78,78,88),	V(4A,25,25,6F),	V(5C,2E,2E,72),	\
+	V(38,1C,1C,24),	V(57,A6,A6,F1),	V(73,B4,B4,C7),	V(97,C6,C6,51),	\
+	V(CB,E8,E8,23),	V(A1,DD,DD,7C),	V(E8,74,74,9C),	V(3E,1F,1F,21),	\
+	V(96,4B,4B,DD),	V(61,BD,BD,DC),	V(0D,8B,8B,86),	V(0F,8A,8A,85),	\
+	V(E0,70,70,90),	V(7C,3E,3E,42),	V(71,B5,B5,C4),	V(CC,66,66,AA),	\
+	V(90,48,48,D8),	V(06,03,03,05),	V(F7,F6,F6,01),	V(1C,0E,0E,12),	\
+	V(C2,61,61,A3),	V(6A,35,35,5F),	V(AE,57,57,F9),	V(69,B9,B9,D0),	\
+	V(17,86,86,91),	V(99,C1,C1,58),	V(3A,1D,1D,27),	V(27,9E,9E,B9),	\
+	V(D9,E1,E1,38),	V(EB,F8,F8,13),	V(2B,98,98,B3),	V(22,11,11,33),	\
+	V(D2,69,69,BB),	V(A9,D9,D9,70),	V(07,8E,8E,89),	V(33,94,94,A7),	\
+	V(2D,9B,9B,B6),	V(3C,1E,1E,22),	V(15,87,87,92),	V(C9,E9,E9,20),	\
+	V(87,CE,CE,49),	V(AA,55,55,FF),	V(50,28,28,78),	V(A5,DF,DF,7A),	\
+	V(03,8C,8C,8F),	V(59,A1,A1,F8),	V(09,89,89,80),	V(1A,0D,0D,17),	\
+	V(65,BF,BF,DA),	V(D7,E6,E6,31),	V(84,42,42,C6),	V(D0,68,68,B8),	\
+	V(82,41,41,C3),	V(29,99,99,B0),	V(5A,2D,2D,77),	V(1E,0F,0F,11),	\
+	V(7B,B0,B0,CB),	V(A8,54,54,FC),	V(6D,BB,BB,D6),	V(2C,16,16,3A)
+
+#define	V(a,b,c,d) 0x##a##b##c##d
+static uint32 FT0[256] = { FT };
+#undef V
+
+#define	V(a,b,c,d) 0x##d##a##b##c
+static uint32 FT1[256] = { FT };
+#undef V
+
+#define	V(a,b,c,d) 0x##c##d##a##b
+static uint32 FT2[256] = { FT };
+#undef V
+
+#define	V(a,b,c,d) 0x##b##c##d##a
+static uint32 FT3[256] = { FT };
+#undef V
+
+#undef FT
+
+/* reverse S-box */
+
+static uint32 RSb[256] =
+{
+	0x52, 0x09,	0x6A, 0xD5,	0x30, 0x36,	0xA5, 0x38,
+	0xBF, 0x40,	0xA3, 0x9E,	0x81, 0xF3,	0xD7, 0xFB,
+	0x7C, 0xE3,	0x39, 0x82,	0x9B, 0x2F,	0xFF, 0x87,
+	0x34, 0x8E,	0x43, 0x44,	0xC4, 0xDE,	0xE9, 0xCB,
+	0x54, 0x7B,	0x94, 0x32,	0xA6, 0xC2,	0x23, 0x3D,
+	0xEE, 0x4C,	0x95, 0x0B,	0x42, 0xFA,	0xC3, 0x4E,
+	0x08, 0x2E,	0xA1, 0x66,	0x28, 0xD9,	0x24, 0xB2,
+	0x76, 0x5B,	0xA2, 0x49,	0x6D, 0x8B,	0xD1, 0x25,
+	0x72, 0xF8,	0xF6, 0x64,	0x86, 0x68,	0x98, 0x16,
+	0xD4, 0xA4,	0x5C, 0xCC,	0x5D, 0x65,	0xB6, 0x92,
+	0x6C, 0x70,	0x48, 0x50,	0xFD, 0xED,	0xB9, 0xDA,
+	0x5E, 0x15,	0x46, 0x57,	0xA7, 0x8D,	0x9D, 0x84,
+	0x90, 0xD8,	0xAB, 0x00,	0x8C, 0xBC,	0xD3, 0x0A,
+	0xF7, 0xE4,	0x58, 0x05,	0xB8, 0xB3,	0x45, 0x06,
+	0xD0, 0x2C,	0x1E, 0x8F,	0xCA, 0x3F,	0x0F, 0x02,
+	0xC1, 0xAF,	0xBD, 0x03,	0x01, 0x13,	0x8A, 0x6B,
+	0x3A, 0x91,	0x11, 0x41,	0x4F, 0x67,	0xDC, 0xEA,
+	0x97, 0xF2,	0xCF, 0xCE,	0xF0, 0xB4,	0xE6, 0x73,
+	0x96, 0xAC,	0x74, 0x22,	0xE7, 0xAD,	0x35, 0x85,
+	0xE2, 0xF9,	0x37, 0xE8,	0x1C, 0x75,	0xDF, 0x6E,
+	0x47, 0xF1,	0x1A, 0x71,	0x1D, 0x29,	0xC5, 0x89,
+	0x6F, 0xB7,	0x62, 0x0E,	0xAA, 0x18,	0xBE, 0x1B,
+	0xFC, 0x56,	0x3E, 0x4B,	0xC6, 0xD2,	0x79, 0x20,
+	0x9A, 0xDB,	0xC0, 0xFE,	0x78, 0xCD,	0x5A, 0xF4,
+	0x1F, 0xDD,	0xA8, 0x33,	0x88, 0x07,	0xC7, 0x31,
+	0xB1, 0x12,	0x10, 0x59,	0x27, 0x80,	0xEC, 0x5F,
+	0x60, 0x51,	0x7F, 0xA9,	0x19, 0xB5,	0x4A, 0x0D,
+	0x2D, 0xE5,	0x7A, 0x9F,	0x93, 0xC9,	0x9C, 0xEF,
+	0xA0, 0xE0,	0x3B, 0x4D,	0xAE, 0x2A,	0xF5, 0xB0,
+	0xC8, 0xEB,	0xBB, 0x3C,	0x83, 0x53,	0x99, 0x61,
+	0x17, 0x2B,	0x04, 0x7E,	0xBA, 0x77,	0xD6, 0x26,
+	0xE1, 0x69,	0x14, 0x63,	0x55, 0x21,	0x0C, 0x7D
+};
+
+/* reverse table */
+
+#define	RT \
+\
+	V(51,F4,A7,50),	V(7E,41,65,53),	V(1A,17,A4,C3),	V(3A,27,5E,96),	\
+	V(3B,AB,6B,CB),	V(1F,9D,45,F1),	V(AC,FA,58,AB),	V(4B,E3,03,93),	\
+	V(20,30,FA,55),	V(AD,76,6D,F6),	V(88,CC,76,91),	V(F5,02,4C,25),	\
+	V(4F,E5,D7,FC),	V(C5,2A,CB,D7),	V(26,35,44,80),	V(B5,62,A3,8F),	\
+	V(DE,B1,5A,49),	V(25,BA,1B,67),	V(45,EA,0E,98),	V(5D,FE,C0,E1),	\
+	V(C3,2F,75,02),	V(81,4C,F0,12),	V(8D,46,97,A3),	V(6B,D3,F9,C6),	\
+	V(03,8F,5F,E7),	V(15,92,9C,95),	V(BF,6D,7A,EB),	V(95,52,59,DA),	\
+	V(D4,BE,83,2D),	V(58,74,21,D3),	V(49,E0,69,29),	V(8E,C9,C8,44),	\
+	V(75,C2,89,6A),	V(F4,8E,79,78),	V(99,58,3E,6B),	V(27,B9,71,DD),	\
+	V(BE,E1,4F,B6),	V(F0,88,AD,17),	V(C9,20,AC,66),	V(7D,CE,3A,B4),	\
+	V(63,DF,4A,18),	V(E5,1A,31,82),	V(97,51,33,60),	V(62,53,7F,45),	\
+	V(B1,64,77,E0),	V(BB,6B,AE,84),	V(FE,81,A0,1C),	V(F9,08,2B,94),	\
+	V(70,48,68,58),	V(8F,45,FD,19),	V(94,DE,6C,87),	V(52,7B,F8,B7),	\
+	V(AB,73,D3,23),	V(72,4B,02,E2),	V(E3,1F,8F,57),	V(66,55,AB,2A),	\
+	V(B2,EB,28,07),	V(2F,B5,C2,03),	V(86,C5,7B,9A),	V(D3,37,08,A5),	\
+	V(30,28,87,F2),	V(23,BF,A5,B2),	V(02,03,6A,BA),	V(ED,16,82,5C),	\
+	V(8A,CF,1C,2B),	V(A7,79,B4,92),	V(F3,07,F2,F0),	V(4E,69,E2,A1),	\
+	V(65,DA,F4,CD),	V(06,05,BE,D5),	V(D1,34,62,1F),	V(C4,A6,FE,8A),	\
+	V(34,2E,53,9D),	V(A2,F3,55,A0),	V(05,8A,E1,32),	V(A4,F6,EB,75),	\
+	V(0B,83,EC,39),	V(40,60,EF,AA),	V(5E,71,9F,06),	V(BD,6E,10,51),	\
+	V(3E,21,8A,F9),	V(96,DD,06,3D),	V(DD,3E,05,AE),	V(4D,E6,BD,46),	\
+	V(91,54,8D,B5),	V(71,C4,5D,05),	V(04,06,D4,6F),	V(60,50,15,FF),	\
+	V(19,98,FB,24),	V(D6,BD,E9,97),	V(89,40,43,CC),	V(67,D9,9E,77),	\
+	V(B0,E8,42,BD),	V(07,89,8B,88),	V(E7,19,5B,38),	V(79,C8,EE,DB),	\
+	V(A1,7C,0A,47),	V(7C,42,0F,E9),	V(F8,84,1E,C9),	V(00,00,00,00),	\
+	V(09,80,86,83),	V(32,2B,ED,48),	V(1E,11,70,AC),	V(6C,5A,72,4E),	\
+	V(FD,0E,FF,FB),	V(0F,85,38,56),	V(3D,AE,D5,1E),	V(36,2D,39,27),	\
+	V(0A,0F,D9,64),	V(68,5C,A6,21),	V(9B,5B,54,D1),	V(24,36,2E,3A),	\
+	V(0C,0A,67,B1),	V(93,57,E7,0F),	V(B4,EE,96,D2),	V(1B,9B,91,9E),	\
+	V(80,C0,C5,4F),	V(61,DC,20,A2),	V(5A,77,4B,69),	V(1C,12,1A,16),	\
+	V(E2,93,BA,0A),	V(C0,A0,2A,E5),	V(3C,22,E0,43),	V(12,1B,17,1D),	\
+	V(0E,09,0D,0B),	V(F2,8B,C7,AD),	V(2D,B6,A8,B9),	V(14,1E,A9,C8),	\
+	V(57,F1,19,85),	V(AF,75,07,4C),	V(EE,99,DD,BB),	V(A3,7F,60,FD),	\
+	V(F7,01,26,9F),	V(5C,72,F5,BC),	V(44,66,3B,C5),	V(5B,FB,7E,34),	\
+	V(8B,43,29,76),	V(CB,23,C6,DC),	V(B6,ED,FC,68),	V(B8,E4,F1,63),	\
+	V(D7,31,DC,CA),	V(42,63,85,10),	V(13,97,22,40),	V(84,C6,11,20),	\
+	V(85,4A,24,7D),	V(D2,BB,3D,F8),	V(AE,F9,32,11),	V(C7,29,A1,6D),	\
+	V(1D,9E,2F,4B),	V(DC,B2,30,F3),	V(0D,86,52,EC),	V(77,C1,E3,D0),	\
+	V(2B,B3,16,6C),	V(A9,70,B9,99),	V(11,94,48,FA),	V(47,E9,64,22),	\
+	V(A8,FC,8C,C4),	V(A0,F0,3F,1A),	V(56,7D,2C,D8),	V(22,33,90,EF),	\
+	V(87,49,4E,C7),	V(D9,38,D1,C1),	V(8C,CA,A2,FE),	V(98,D4,0B,36),	\
+	V(A6,F5,81,CF),	V(A5,7A,DE,28),	V(DA,B7,8E,26),	V(3F,AD,BF,A4),	\
+	V(2C,3A,9D,E4),	V(50,78,92,0D),	V(6A,5F,CC,9B),	V(54,7E,46,62),	\
+	V(F6,8D,13,C2),	V(90,D8,B8,E8),	V(2E,39,F7,5E),	V(82,C3,AF,F5),	\
+	V(9F,5D,80,BE),	V(69,D0,93,7C),	V(6F,D5,2D,A9),	V(CF,25,12,B3),	\
+	V(C8,AC,99,3B),	V(10,18,7D,A7),	V(E8,9C,63,6E),	V(DB,3B,BB,7B),	\
+	V(CD,26,78,09),	V(6E,59,18,F4),	V(EC,9A,B7,01),	V(83,4F,9A,A8),	\
+	V(E6,95,6E,65),	V(AA,FF,E6,7E),	V(21,BC,CF,08),	V(EF,15,E8,E6),	\
+	V(BA,E7,9B,D9),	V(4A,6F,36,CE),	V(EA,9F,09,D4),	V(29,B0,7C,D6),	\
+	V(31,A4,B2,AF),	V(2A,3F,23,31),	V(C6,A5,94,30),	V(35,A2,66,C0),	\
+	V(74,4E,BC,37),	V(FC,82,CA,A6),	V(E0,90,D0,B0),	V(33,A7,D8,15),	\
+	V(F1,04,98,4A),	V(41,EC,DA,F7),	V(7F,CD,50,0E),	V(17,91,F6,2F),	\
+	V(76,4D,D6,8D),	V(43,EF,B0,4D),	V(CC,AA,4D,54),	V(E4,96,04,DF),	\
+	V(9E,D1,B5,E3),	V(4C,6A,88,1B),	V(C1,2C,1F,B8),	V(46,65,51,7F),	\
+	V(9D,5E,EA,04),	V(01,8C,35,5D),	V(FA,87,74,73),	V(FB,0B,41,2E),	\
+	V(B3,67,1D,5A),	V(92,DB,D2,52),	V(E9,10,56,33),	V(6D,D6,47,13),	\
+	V(9A,D7,61,8C),	V(37,A1,0C,7A),	V(59,F8,14,8E),	V(EB,13,3C,89),	\
+	V(CE,A9,27,EE),	V(B7,61,C9,35),	V(E1,1C,E5,ED),	V(7A,47,B1,3C),	\
+	V(9C,D2,DF,59),	V(55,F2,73,3F),	V(18,14,CE,79),	V(73,C7,37,BF),	\
+	V(53,F7,CD,EA),	V(5F,FD,AA,5B),	V(DF,3D,6F,14),	V(78,44,DB,86),	\
+	V(CA,AF,F3,81),	V(B9,68,C4,3E),	V(38,24,34,2C),	V(C2,A3,40,5F),	\
+	V(16,1D,C3,72),	V(BC,E2,25,0C),	V(28,3C,49,8B),	V(FF,0D,95,41),	\
+	V(39,A8,01,71),	V(08,0C,B3,DE),	V(D8,B4,E4,9C),	V(64,56,C1,90),	\
+	V(7B,CB,84,61),	V(D5,32,B6,70),	V(48,6C,5C,74),	V(D0,B8,57,42)
+
+#define	V(a,b,c,d) 0x##a##b##c##d
+static uint32 RT0[256] = { RT };
+#undef V
+
+#define	V(a,b,c,d) 0x##d##a##b##c
+static uint32 RT1[256] = { RT };
+#undef V
+
+#define	V(a,b,c,d) 0x##c##d##a##b
+static uint32 RT2[256] = { RT };
+#undef V
+
+#define	V(a,b,c,d) 0x##b##c##d##a
+static uint32 RT3[256] = { RT };
+#undef V
+
+#undef RT
+
+/* round constants */
+
+static uint32 RCON[10] =
+{
+	0x01000000,	0x02000000,	0x04000000,	0x08000000,
+	0x10000000,	0x20000000,	0x40000000,	0x80000000,
+	0x1B000000,	0x36000000
+};
+
+/* key schedule	tables */
+
+static int KT_init = 1;
+
+static uint32 KT0[256];
+static uint32 KT1[256];
+static uint32 KT2[256];
+static uint32 KT3[256];
+
+/* platform-independant	32-bit integer manipulation	macros */
+
+#define	GET_UINT32(n,b,i)						\
+{												\
+	(n)	= (	(uint32) (b)[(i)	] << 24	)		\
+		| (	(uint32) (b)[(i) + 1] << 16	)		\
+		| (	(uint32) (b)[(i) + 2] <<  8	)		\
+		| (	(uint32) (b)[(i) + 3]		);		\
+}
+
+#define	PUT_UINT32(n,b,i)						\
+{												\
+	(b)[(i)	   ] = (uint8) ( (n) >>	24 );		\
+	(b)[(i)	+ 1] = (uint8) ( (n) >>	16 );		\
+	(b)[(i)	+ 2] = (uint8) ( (n) >>	 8 );		\
+	(b)[(i)	+ 3] = (uint8) ( (n)	   );		\
+}
+
+/* AES key scheduling routine */
+
+int	rtmp_aes_set_key( aes_context *ctx, uint8 *key, int nbits )
+{
+	int	i;
+	uint32 *RK,	*SK;
+
+	switch(	nbits )
+	{
+		case 128: ctx->nr =	10;	break;
+		case 192: ctx->nr =	12;	break;
+		case 256: ctx->nr =	14;	break;
+		default	: return( 1	);
+	}
+
+	RK = ctx->erk;
+
+	for( i = 0;	i <	(nbits >> 5); i++ )
+	{
+		GET_UINT32(	RK[i], key,	i *	4 );
+	}
+
+	/* setup encryption	round keys */
+
+	switch(	nbits )
+	{
+	case 128:
+
+		for( i = 0;	i <	10;	i++, RK	+= 4 )
+		{
+			RK[4]  = RK[0] ^ RCON[i] ^
+						( FSb[ (uint8) ( RK[3] >> 16 ) ] <<	24 ) ^
+						( FSb[ (uint8) ( RK[3] >>  8 ) ] <<	16 ) ^
+						( FSb[ (uint8) ( RK[3]		 ) ] <<	 8 ) ^
+						( FSb[ (uint8) ( RK[3] >> 24 ) ]	   );
+
+			RK[5]  = RK[1] ^ RK[4];
+			RK[6]  = RK[2] ^ RK[5];
+			RK[7]  = RK[3] ^ RK[6];
+		}
+		break;
+
+	case 192:
+
+		for( i = 0;	i <	8; i++,	RK += 6	)
+		{
+			RK[6]  = RK[0] ^ RCON[i] ^
+						( FSb[ (uint8) ( RK[5] >> 16 ) ] <<	24 ) ^
+						( FSb[ (uint8) ( RK[5] >>  8 ) ] <<	16 ) ^
+						( FSb[ (uint8) ( RK[5]		 ) ] <<	 8 ) ^
+						( FSb[ (uint8) ( RK[5] >> 24 ) ]	   );
+
+			RK[7]  = RK[1] ^ RK[6];
+			RK[8]  = RK[2] ^ RK[7];
+			RK[9]  = RK[3] ^ RK[8];
+			RK[10] = RK[4] ^ RK[9];
+			RK[11] = RK[5] ^ RK[10];
+		}
+		break;
+
+	case 256:
+
+		for( i = 0;	i <	7; i++,	RK += 8	)
+		{
+			RK[8]  = RK[0] ^ RCON[i] ^
+						( FSb[ (uint8) ( RK[7] >> 16 ) ] <<	24 ) ^
+						( FSb[ (uint8) ( RK[7] >>  8 ) ] <<	16 ) ^
+						( FSb[ (uint8) ( RK[7]		 ) ] <<	 8 ) ^
+						( FSb[ (uint8) ( RK[7] >> 24 ) ]	   );
+
+			RK[9]  = RK[1] ^ RK[8];
+			RK[10] = RK[2] ^ RK[9];
+			RK[11] = RK[3] ^ RK[10];
+
+			RK[12] = RK[4] ^
+						( FSb[ (uint8) ( RK[11]	>> 24 )	] << 24	) ^
+						( FSb[ (uint8) ( RK[11]	>> 16 )	] << 16	) ^
+						( FSb[ (uint8) ( RK[11]	>>	8 )	] <<  8	) ^
+						( FSb[ (uint8) ( RK[11]		  )	]		);
+
+			RK[13] = RK[5] ^ RK[12];
+			RK[14] = RK[6] ^ RK[13];
+			RK[15] = RK[7] ^ RK[14];
+		}
+		break;
+	}
+
+	/* setup decryption	round keys */
+
+	if(	KT_init	)
+	{
+		for( i = 0;	i <	256; i++ )
+		{
+			KT0[i] = RT0[ FSb[i] ];
+			KT1[i] = RT1[ FSb[i] ];
+			KT2[i] = RT2[ FSb[i] ];
+			KT3[i] = RT3[ FSb[i] ];
+		}
+
+		KT_init	= 0;
+	}
+
+	SK = ctx->drk;
+
+	*SK++ =	*RK++;
+	*SK++ =	*RK++;
+	*SK++ =	*RK++;
+	*SK++ =	*RK++;
+
+	for( i = 1;	i <	ctx->nr; i++ )
+	{
+		RK -= 8;
+
+		*SK++ =	KT0[ (uint8) ( *RK >> 24 ) ] ^
+				KT1[ (uint8) ( *RK >> 16 ) ] ^
+				KT2[ (uint8) ( *RK >>  8 ) ] ^
+				KT3[ (uint8) ( *RK		 ) ]; RK++;
+
+		*SK++ =	KT0[ (uint8) ( *RK >> 24 ) ] ^
+				KT1[ (uint8) ( *RK >> 16 ) ] ^
+				KT2[ (uint8) ( *RK >>  8 ) ] ^
+				KT3[ (uint8) ( *RK		 ) ]; RK++;
+
+		*SK++ =	KT0[ (uint8) ( *RK >> 24 ) ] ^
+				KT1[ (uint8) ( *RK >> 16 ) ] ^
+				KT2[ (uint8) ( *RK >>  8 ) ] ^
+				KT3[ (uint8) ( *RK		 ) ]; RK++;
+
+		*SK++ =	KT0[ (uint8) ( *RK >> 24 ) ] ^
+				KT1[ (uint8) ( *RK >> 16 ) ] ^
+				KT2[ (uint8) ( *RK >>  8 ) ] ^
+				KT3[ (uint8) ( *RK		 ) ]; RK++;
+	}
+
+	RK -= 8;
+
+	*SK++ =	*RK++;
+	*SK++ =	*RK++;
+	*SK++ =	*RK++;
+	*SK++ =	*RK++;
+
+	return(	0 );
+}
+
+/* AES 128-bit block encryption	routine	*/
+
+void rtmp_aes_encrypt(aes_context *ctx, uint8 input[16],	uint8 output[16] )
+{
+	uint32 *RK,	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3;
+
+	RK = ctx->erk;
+	GET_UINT32(	X0,	input,	0 ); X0	^= RK[0];
+	GET_UINT32(	X1,	input,	4 ); X1	^= RK[1];
+	GET_UINT32(	X2,	input,	8 ); X2	^= RK[2];
+	GET_UINT32(	X3,	input, 12 ); X3	^= RK[3];
+
+#define	AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)		\
+{												\
+	RK += 4;									\
+												\
+	X0 = RK[0] ^ FT0[ (uint8) (	Y0 >> 24 ) ] ^	\
+				 FT1[ (uint8) (	Y1 >> 16 ) ] ^	\
+				 FT2[ (uint8) (	Y2 >>  8 ) ] ^	\
+				 FT3[ (uint8) (	Y3		 ) ];	\
+												\
+	X1 = RK[1] ^ FT0[ (uint8) (	Y1 >> 24 ) ] ^	\
+				 FT1[ (uint8) (	Y2 >> 16 ) ] ^	\
+				 FT2[ (uint8) (	Y3 >>  8 ) ] ^	\
+				 FT3[ (uint8) (	Y0		 ) ];	\
+												\
+	X2 = RK[2] ^ FT0[ (uint8) (	Y2 >> 24 ) ] ^	\
+				 FT1[ (uint8) (	Y3 >> 16 ) ] ^	\
+				 FT2[ (uint8) (	Y0 >>  8 ) ] ^	\
+				 FT3[ (uint8) (	Y1		 ) ];	\
+												\
+	X3 = RK[3] ^ FT0[ (uint8) (	Y3 >> 24 ) ] ^	\
+				 FT1[ (uint8) (	Y0 >> 16 ) ] ^	\
+				 FT2[ (uint8) (	Y1 >>  8 ) ] ^	\
+				 FT3[ (uint8) (	Y2		 ) ];	\
+}
+
+	AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 1 */
+	AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 2 */
+	AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 3 */
+	AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 4 */
+	AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 5 */
+	AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 6 */
+	AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 7 */
+	AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 8 */
+	AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 9 */
+
+	if(	ctx->nr	> 10 )
+	{
+		AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );	/* round 10	*/
+		AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );	/* round 11	*/
+	}
+
+	if(	ctx->nr	> 12 )
+	{
+		AES_FROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );	/* round 12	*/
+		AES_FROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );	/* round 13	*/
+	}
+
+	/* last	round */
+
+	RK += 4;
+
+	X0 = RK[0] ^ ( FSb[	(uint8)	( Y0 >>	24 ) ] << 24 ) ^
+				 ( FSb[	(uint8)	( Y1 >>	16 ) ] << 16 ) ^
+				 ( FSb[	(uint8)	( Y2 >>	 8 ) ] <<  8 ) ^
+				 ( FSb[	(uint8)	( Y3	   ) ]		 );
+
+	X1 = RK[1] ^ ( FSb[	(uint8)	( Y1 >>	24 ) ] << 24 ) ^
+				 ( FSb[	(uint8)	( Y2 >>	16 ) ] << 16 ) ^
+				 ( FSb[	(uint8)	( Y3 >>	 8 ) ] <<  8 ) ^
+				 ( FSb[	(uint8)	( Y0	   ) ]		 );
+
+	X2 = RK[2] ^ ( FSb[	(uint8)	( Y2 >>	24 ) ] << 24 ) ^
+				 ( FSb[	(uint8)	( Y3 >>	16 ) ] << 16 ) ^
+				 ( FSb[	(uint8)	( Y0 >>	 8 ) ] <<  8 ) ^
+				 ( FSb[	(uint8)	( Y1	   ) ]		 );
+
+	X3 = RK[3] ^ ( FSb[	(uint8)	( Y3 >>	24 ) ] << 24 ) ^
+				 ( FSb[	(uint8)	( Y0 >>	16 ) ] << 16 ) ^
+				 ( FSb[	(uint8)	( Y1 >>	 8 ) ] <<  8 ) ^
+				 ( FSb[	(uint8)	( Y2	   ) ]		 );
+
+	PUT_UINT32(	X0,	output,	 0 );
+	PUT_UINT32(	X1,	output,	 4 );
+	PUT_UINT32(	X2,	output,	 8 );
+	PUT_UINT32(	X3,	output,	12 );
+}
+
+/* AES 128-bit block decryption	routine	*/
+
+void rtmp_aes_decrypt( aes_context *ctx,	uint8 input[16], uint8 output[16] )
+{
+	uint32 *RK,	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3;
+
+	RK = ctx->drk;
+
+	GET_UINT32(	X0,	input,	0 ); X0	^= RK[0];
+	GET_UINT32(	X1,	input,	4 ); X1	^= RK[1];
+	GET_UINT32(	X2,	input,	8 ); X2	^= RK[2];
+	GET_UINT32(	X3,	input, 12 ); X3	^= RK[3];
+
+#define	AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)		\
+{												\
+	RK += 4;									\
+												\
+	X0 = RK[0] ^ RT0[ (uint8) (	Y0 >> 24 ) ] ^	\
+				 RT1[ (uint8) (	Y3 >> 16 ) ] ^	\
+				 RT2[ (uint8) (	Y2 >>  8 ) ] ^	\
+				 RT3[ (uint8) (	Y1		 ) ];	\
+												\
+	X1 = RK[1] ^ RT0[ (uint8) (	Y1 >> 24 ) ] ^	\
+				 RT1[ (uint8) (	Y0 >> 16 ) ] ^	\
+				 RT2[ (uint8) (	Y3 >>  8 ) ] ^	\
+				 RT3[ (uint8) (	Y2		 ) ];	\
+												\
+	X2 = RK[2] ^ RT0[ (uint8) (	Y2 >> 24 ) ] ^	\
+				 RT1[ (uint8) (	Y1 >> 16 ) ] ^	\
+				 RT2[ (uint8) (	Y0 >>  8 ) ] ^	\
+				 RT3[ (uint8) (	Y3		 ) ];	\
+												\
+	X3 = RK[3] ^ RT0[ (uint8) (	Y3 >> 24 ) ] ^	\
+				 RT1[ (uint8) (	Y2 >> 16 ) ] ^	\
+				 RT2[ (uint8) (	Y1 >>  8 ) ] ^	\
+				 RT3[ (uint8) (	Y0		 ) ];	\
+}
+
+	AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 1 */
+	AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 2 */
+	AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 3 */
+	AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 4 */
+	AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 5 */
+	AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 6 */
+	AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 7 */
+	AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );		/* round 8 */
+	AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );		/* round 9 */
+
+	if(	ctx->nr	> 10 )
+	{
+		AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );	/* round 10	*/
+		AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );	/* round 11	*/
+	}
+
+	if(	ctx->nr	> 12 )
+	{
+		AES_RROUND(	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3 );	/* round 12	*/
+		AES_RROUND(	Y0,	Y1,	Y2,	Y3,	X0,	X1,	X2,	X3 );	/* round 13	*/
+	}
+
+	/* last	round */
+
+	RK += 4;
+
+	X0 = RK[0] ^ ( RSb[	(uint8)	( Y0 >>	24 ) ] << 24 ) ^
+				 ( RSb[	(uint8)	( Y3 >>	16 ) ] << 16 ) ^
+				 ( RSb[	(uint8)	( Y2 >>	 8 ) ] <<  8 ) ^
+				 ( RSb[	(uint8)	( Y1	   ) ]		 );
+
+	X1 = RK[1] ^ ( RSb[	(uint8)	( Y1 >>	24 ) ] << 24 ) ^
+				 ( RSb[	(uint8)	( Y0 >>	16 ) ] << 16 ) ^
+				 ( RSb[	(uint8)	( Y3 >>	 8 ) ] <<  8 ) ^
+				 ( RSb[	(uint8)	( Y2	   ) ]		 );
+
+	X2 = RK[2] ^ ( RSb[	(uint8)	( Y2 >>	24 ) ] << 24 ) ^
+				 ( RSb[	(uint8)	( Y1 >>	16 ) ] << 16 ) ^
+				 ( RSb[	(uint8)	( Y0 >>	 8 ) ] <<  8 ) ^
+				 ( RSb[	(uint8)	( Y3	   ) ]		 );
+
+	X3 = RK[3] ^ ( RSb[	(uint8)	( Y3 >>	24 ) ] << 24 ) ^
+				 ( RSb[	(uint8)	( Y2 >>	16 ) ] << 16 ) ^
+				 ( RSb[	(uint8)	( Y1 >>	 8 ) ] <<  8 ) ^
+				 ( RSb[	(uint8)	( Y0	   ) ]		 );
+
+	PUT_UINT32(	X0,	output,	 0 );
+	PUT_UINT32(	X1,	output,	 4 );
+	PUT_UINT32(	X2,	output,	 8 );
+	PUT_UINT32(	X3,	output,	12 );
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		SHA1 function
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+	========================================================================
+*/
+VOID	HMAC_SHA1(
+	IN	UCHAR	*text,
+	IN	UINT	text_len,
+	IN	UCHAR	*key,
+	IN	UINT	key_len,
+	IN	UCHAR	*digest)
+{
+	SHA_CTX	context;
+	UCHAR	k_ipad[65]; /* inner padding - key XORd with ipad	*/
+	UCHAR	k_opad[65]; /* outer padding - key XORd with opad	*/
+	INT		i;
+
+	// if key is longer	than 64	bytes reset	it to key=SHA1(key)
+	if (key_len	> 64)
+	{
+		SHA_CTX		 tctx;
+		SHAInit(&tctx);
+		SHAUpdate(&tctx, key, key_len);
+		SHAFinal(&tctx,	key);
+		key_len	= 20;
+	}
+	NdisZeroMemory(k_ipad, sizeof(k_ipad));
+	NdisZeroMemory(k_opad, sizeof(k_opad));
+	NdisMoveMemory(k_ipad, key,	key_len);
+	NdisMoveMemory(k_opad, key,	key_len);
+
+	// XOR key with	ipad and opad values
+	for	(i = 0;	i <	64;	i++)
+	{
+		k_ipad[i] ^= 0x36;
+		k_opad[i] ^= 0x5c;
+	}
+
+	// perform inner SHA1
+	SHAInit(&context); 						/* init context for 1st pass */
+	SHAUpdate(&context,	k_ipad,	64);		/*	start with inner pad */
+	SHAUpdate(&context,	text, text_len);	/*	then text of datagram */
+	SHAFinal(&context, digest);				/* finish up 1st pass */
+
+	//perform outer	SHA1
+	SHAInit(&context);					/* init context for 2nd pass */
+	SHAUpdate(&context,	k_opad,	64);	/*	start with outer pad */
+	SHAUpdate(&context,	digest,	20);	/*	then results of	1st	hash */
+	SHAFinal(&context, digest);			/* finish up 2nd pass */
+
+}
+
+/*
+* F(P, S, c, i) = U1 xor U2 xor ... Uc
+* U1 = PRF(P, S || Int(i))
+* U2 = PRF(P, U1)
+* Uc = PRF(P, Uc-1)
+*/
+
+void F(char *password, unsigned char *ssid, int ssidlength, int iterations, int count, unsigned char *output)
+{
+    unsigned char digest[36], digest1[SHA_DIGEST_LEN];
+    int i, j;
+
+    /* U1 = PRF(P, S || int(i)) */
+    memcpy(digest, ssid, ssidlength);
+    digest[ssidlength] = (unsigned char)((count>>24) & 0xff);
+    digest[ssidlength+1] = (unsigned char)((count>>16) & 0xff);
+    digest[ssidlength+2] = (unsigned char)((count>>8) & 0xff);
+    digest[ssidlength+3] = (unsigned char)(count & 0xff);
+    HMAC_SHA1(digest, ssidlength+4, (unsigned char*) password, (int) strlen(password), digest1); // for WPA update
+
+    /* output = U1 */
+    memcpy(output, digest1, SHA_DIGEST_LEN);
+
+    for (i = 1; i < iterations; i++)
+    {
+        /* Un = PRF(P, Un-1) */
+        HMAC_SHA1(digest1, SHA_DIGEST_LEN, (unsigned char*) password, (int) strlen(password), digest); // for WPA update
+        memcpy(digest1, digest, SHA_DIGEST_LEN);
+
+        /* output = output xor Un */
+        for (j = 0; j < SHA_DIGEST_LEN; j++)
+        {
+            output[j] ^= digest[j];
+        }
+    }
+}
+/*
+* password - ascii string up to 63 characters in length
+* ssid - octet string up to 32 octets
+* ssidlength - length of ssid in octets
+* output must be 40 octets in length and outputs 256 bits of key
+*/
+int PasswordHash(char *password, unsigned char *ssid, int ssidlength, unsigned char *output)
+{
+    if ((strlen(password) > 63) || (ssidlength > 32))
+        return 0;
+
+    F(password, ssid, ssidlength, 4096, 1, output);
+    F(password, ssid, ssidlength, 4096, 2, &output[SHA_DIGEST_LEN]);
+    return 1;
+}
+
+
diff --git a/drivers/staging/rt3070/common/mlme.c b/drivers/staging/rt3070/common/mlme.c
new file mode 100644
index 0000000..0ffbfa3
--- /dev/null
+++ b/drivers/staging/rt3070/common/mlme.c
@@ -0,0 +1,9136 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	mlme.c
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	John Chang	2004-08-25		Modify from RT2500 code base
+	John Chang	2004-09-06		modified for RT2600
+*/
+
+#include "../rt_config.h"
+#include <stdarg.h>
+
+UCHAR	CISCO_OUI[] = {0x00, 0x40, 0x96};
+
+UCHAR	WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
+UCHAR	RSN_OUI[] = {0x00, 0x0f, 0xac};
+UCHAR	WAPI_OUI[] = {0x00, 0x14, 0x72};
+UCHAR   WME_INFO_ELEM[]  = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
+UCHAR   WME_PARM_ELEM[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
+UCHAR	Ccx2QosInfo[] = {0x00, 0x40, 0x96, 0x04};
+UCHAR   RALINK_OUI[]  = {0x00, 0x0c, 0x43};
+UCHAR   BROADCOM_OUI[]  = {0x00, 0x90, 0x4c};
+UCHAR   WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
+#ifdef CONFIG_STA_SUPPORT
+#ifdef DOT11_N_SUPPORT
+UCHAR	PRE_N_HT_OUI[]	= {0x00, 0x90, 0x4c};
+#endif // DOT11_N_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+UCHAR RateSwitchTable[] = {
+// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+    0x11, 0x00,  0,  0,  0,						// Initial used item after association
+    0x00, 0x00,  0, 40, 101,
+    0x01, 0x00,  1, 40, 50,
+    0x02, 0x00,  2, 35, 45,
+    0x03, 0x00,  3, 20, 45,
+    0x04, 0x21,  0, 30, 50,
+    0x05, 0x21,  1, 20, 50,
+    0x06, 0x21,  2, 20, 50,
+    0x07, 0x21,  3, 15, 50,
+    0x08, 0x21,  4, 15, 30,
+    0x09, 0x21,  5, 10, 25,
+    0x0a, 0x21,  6,  8, 25,
+    0x0b, 0x21,  7,  8, 25,
+    0x0c, 0x20, 12,  15, 30,
+    0x0d, 0x20, 13,  8, 20,
+    0x0e, 0x20, 14,  8, 20,
+    0x0f, 0x20, 15,  8, 25,
+    0x10, 0x22, 15,  8, 25,
+    0x11, 0x00,  0,  0,  0,
+    0x12, 0x00,  0,  0,  0,
+    0x13, 0x00,  0,  0,  0,
+    0x14, 0x00,  0,  0,  0,
+    0x15, 0x00,  0,  0,  0,
+    0x16, 0x00,  0,  0,  0,
+    0x17, 0x00,  0,  0,  0,
+    0x18, 0x00,  0,  0,  0,
+    0x19, 0x00,  0,  0,  0,
+    0x1a, 0x00,  0,  0,  0,
+    0x1b, 0x00,  0,  0,  0,
+    0x1c, 0x00,  0,  0,  0,
+    0x1d, 0x00,  0,  0,  0,
+    0x1e, 0x00,  0,  0,  0,
+    0x1f, 0x00,  0,  0,  0,
+};
+
+UCHAR RateSwitchTable11B[] = {
+// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+    0x04, 0x03,  0,  0,  0,						// Initial used item after association
+    0x00, 0x00,  0, 40, 101,
+    0x01, 0x00,  1, 40, 50,
+    0x02, 0x00,  2, 35, 45,
+    0x03, 0x00,  3, 20, 45,
+};
+
+UCHAR RateSwitchTable11BG[] = {
+// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+    0x0a, 0x00,  0,  0,  0,						// Initial used item after association
+    0x00, 0x00,  0, 40, 101,
+    0x01, 0x00,  1, 40, 50,
+    0x02, 0x00,  2, 35, 45,
+    0x03, 0x00,  3, 20, 45,
+    0x04, 0x10,  2, 20, 35,
+    0x05, 0x10,  3, 16, 35,
+    0x06, 0x10,  4, 10, 25,
+    0x07, 0x10,  5, 16, 25,
+    0x08, 0x10,  6, 10, 25,
+    0x09, 0x10,  7, 10, 13,
+};
+
+UCHAR RateSwitchTable11G[] = {
+// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+    0x08, 0x00,  0,  0,  0,						// Initial used item after association
+    0x00, 0x10,  0, 20, 101,
+    0x01, 0x10,  1, 20, 35,
+    0x02, 0x10,  2, 20, 35,
+    0x03, 0x10,  3, 16, 35,
+    0x04, 0x10,  4, 10, 25,
+    0x05, 0x10,  5, 16, 25,
+    0x06, 0x10,  6, 10, 25,
+    0x07, 0x10,  7, 10, 13,
+};
+
+#ifdef DOT11_N_SUPPORT
+UCHAR RateSwitchTable11N1S[] = {
+// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+    0x09, 0x00,  0,  0,  0,						// Initial used item after association
+    0x00, 0x21,  0, 30, 101,
+    0x01, 0x21,  1, 20, 50,
+    0x02, 0x21,  2, 20, 50,
+    0x03, 0x21,  3, 15, 50,
+    0x04, 0x21,  4, 15, 30,
+    0x05, 0x21,  5, 10, 25,
+    0x06, 0x21,  6,  8, 14,
+    0x07, 0x21,  7,  8, 14,
+    0x08, 0x23,  7,  8, 14,
+};
+
+UCHAR RateSwitchTable11N2S[] = {
+// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+    0x0a, 0x00,  0,  0,  0,      // Initial used item after association
+    0x00, 0x21,  0, 30, 101,
+    0x01, 0x21,  1, 20, 50,
+    0x02, 0x21,  2, 20, 50,
+    0x03, 0x21,  3, 15, 50,
+    0x04, 0x21,  4, 15, 30,
+    0x05, 0x20, 12,  15, 30,
+    0x06, 0x20, 13,  8, 20,
+    0x07, 0x20, 14,  8, 20,
+    0x08, 0x20, 15,  8, 25,
+    0x09, 0x22, 15,  8, 25,
+};
+
+UCHAR RateSwitchTable11N3S[] = {
+// Item No.	Mode	Curr-MCS	TrainUp	TrainDown	// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+    0x0a, 0x00,  0,  0,  0,      // Initial used item after association
+    0x00, 0x21,  0, 30, 101,
+    0x01, 0x21,  1, 20, 50,
+    0x02, 0x21,  2, 20, 50,
+    0x03, 0x21,  3, 15, 50,
+    0x04, 0x21,  4, 15, 30,
+    0x05, 0x20, 12,  15, 30,
+    0x06, 0x20, 13,  8, 20,
+    0x07, 0x20, 14,  8, 20,
+    0x08, 0x20, 15,  8, 25,
+    0x09, 0x22, 15,  8, 25,
+};
+
+UCHAR RateSwitchTable11N2SForABand[] = {
+// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+    0x0b, 0x09,  0,  0,  0,						// Initial used item after association
+    0x00, 0x21,  0, 30, 101,
+    0x01, 0x21,  1, 20, 50,
+    0x02, 0x21,  2, 20, 50,
+    0x03, 0x21,  3, 15, 50,
+    0x04, 0x21,  4, 15, 30,
+    0x05, 0x21,  5, 15, 30,
+    0x06, 0x20, 12,  15, 30,
+    0x07, 0x20, 13,  8, 20,
+    0x08, 0x20, 14,  8, 20,
+    0x09, 0x20, 15,  8, 25,
+    0x0a, 0x22, 15,  8, 25,
+};
+
+UCHAR RateSwitchTable11N3SForABand[] = { // 3*3
+// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+    0x0b, 0x09,  0,  0,  0,						// Initial used item after association
+    0x00, 0x21,  0, 30, 101,
+    0x01, 0x21,  1, 20, 50,
+    0x02, 0x21,  2, 20, 50,
+    0x03, 0x21,  3, 15, 50,
+    0x04, 0x21,  4, 15, 30,
+    0x05, 0x21,  5, 15, 30,
+    0x06, 0x20, 12,  15, 30,
+    0x07, 0x20, 13,  8, 20,
+    0x08, 0x20, 14,  8, 20,
+    0x09, 0x20, 15,  8, 25,
+    0x0a, 0x22, 15,  8, 25,
+};
+
+UCHAR RateSwitchTable11BGN1S[] = {
+// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+    0x0d, 0x00,  0,  0,  0,						// Initial used item after association
+    0x00, 0x00,  0, 40, 101,
+    0x01, 0x00,  1, 40, 50,
+    0x02, 0x00,  2, 35, 45,
+    0x03, 0x00,  3, 20, 45,
+    0x04, 0x21,  0, 30,101,	//50
+    0x05, 0x21,  1, 20, 50,
+    0x06, 0x21,  2, 20, 50,
+    0x07, 0x21,  3, 15, 50,
+    0x08, 0x21,  4, 15, 30,
+    0x09, 0x21,  5, 10, 25,
+    0x0a, 0x21,  6,  8, 14,
+    0x0b, 0x21,  7,  8, 14,
+	0x0c, 0x23,  7,  8, 14,
+};
+
+UCHAR RateSwitchTable11BGN2S[] = {
+// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+    0x0a, 0x00,  0,  0,  0,						// Initial used item after association
+    0x00, 0x21,  0, 30,101,	//50
+    0x01, 0x21,  1, 20, 50,
+    0x02, 0x21,  2, 20, 50,
+    0x03, 0x21,  3, 15, 50,
+    0x04, 0x21,  4, 15, 30,
+    0x05, 0x20, 12, 15, 30,
+    0x06, 0x20, 13,  8, 20,
+    0x07, 0x20, 14,  8, 20,
+    0x08, 0x20, 15,  8, 25,
+    0x09, 0x22, 15,  8, 25,
+};
+
+UCHAR RateSwitchTable11BGN3S[] = { // 3*3
+// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+    0x0a, 0x00,  0,  0,  0,						// Initial used item after association
+    0x00, 0x21,  0, 30,101,	//50
+    0x01, 0x21,  1, 20, 50,
+    0x02, 0x21,  2, 20, 50,
+    0x03, 0x21,  3, 20, 50,
+    0x04, 0x21,  4, 15, 50,
+#if 1
+    0x05, 0x20, 20, 15, 30,
+    0x06, 0x20, 21,  8, 20,
+    0x07, 0x20, 22,  8, 20,
+    0x08, 0x20, 23,  8, 25,
+    0x09, 0x22, 23,  8, 25,
+#else // for RT2860 2*3 test
+    0x05, 0x20, 12, 15, 30,
+    0x06, 0x20, 13,  8, 20,
+    0x07, 0x20, 14,  8, 20,
+    0x08, 0x20, 15,  8, 25,
+    0x09, 0x22, 15,  8, 25,
+#endif
+};
+
+UCHAR RateSwitchTable11BGN2SForABand[] = {
+// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+    0x0b, 0x09,  0,  0,  0,						// Initial used item after association
+    0x00, 0x21,  0, 30,101,	//50
+    0x01, 0x21,  1, 20, 50,
+    0x02, 0x21,  2, 20, 50,
+    0x03, 0x21,  3, 15, 50,
+    0x04, 0x21,  4, 15, 30,
+    0x05, 0x21,  5, 15, 30,
+    0x06, 0x20, 12, 15, 30,
+    0x07, 0x20, 13,  8, 20,
+    0x08, 0x20, 14,  8, 20,
+    0x09, 0x20, 15,  8, 25,
+    0x0a, 0x22, 15,  8, 25,
+};
+
+UCHAR RateSwitchTable11BGN3SForABand[] = { // 3*3
+// Item No.   Mode   Curr-MCS   TrainUp   TrainDown		// Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+    0x0c, 0x09,  0,  0,  0,						// Initial used item after association
+    0x00, 0x21,  0, 30,101,	//50
+    0x01, 0x21,  1, 20, 50,
+    0x02, 0x21,  2, 20, 50,
+    0x03, 0x21,  3, 15, 50,
+    0x04, 0x21,  4, 15, 30,
+    0x05, 0x21,  5, 15, 30,
+    0x06, 0x21, 12, 15, 30,
+    0x07, 0x20, 20, 15, 30,
+    0x08, 0x20, 21,  8, 20,
+    0x09, 0x20, 22,  8, 20,
+    0x0a, 0x20, 23,  8, 25,
+    0x0b, 0x22, 23,  8, 25,
+};
+#endif // DOT11_N_SUPPORT //
+
+PUCHAR ReasonString[] = {
+	/* 0  */	 "Reserved",
+	/* 1  */	 "Unspecified Reason",
+	/* 2  */	 "Previous Auth no longer valid",
+	/* 3  */	 "STA is leaving / has left",
+	/* 4  */	 "DIS-ASSOC due to inactivity",
+	/* 5  */	 "AP unable to hanle all associations",
+	/* 6  */	 "class 2 error",
+	/* 7  */	 "class 3 error",
+	/* 8  */	 "STA is leaving / has left",
+	/* 9  */	 "require auth before assoc/re-assoc",
+	/* 10 */	 "Reserved",
+	/* 11 */	 "Reserved",
+	/* 12 */	 "Reserved",
+	/* 13 */	 "invalid IE",
+	/* 14 */	 "MIC error",
+	/* 15 */	 "4-way handshake timeout",
+	/* 16 */	 "2-way (group key) handshake timeout",
+	/* 17 */	 "4-way handshake IE diff among AssosReq/Rsp/Beacon",
+	/* 18 */
+};
+
+extern UCHAR	 OfdmRateToRxwiMCS[];
+// since RT61 has better RX sensibility, we have to limit TX ACK rate not to exceed our normal data TX rate.
+// otherwise the WLAN peer may not be able to receive the ACK thus downgrade its data TX rate
+ULONG BasicRateMask[12]				= {0xfffff001 /* 1-Mbps */, 0xfffff003 /* 2 Mbps */, 0xfffff007 /* 5.5 */, 0xfffff00f /* 11 */,
+									  0xfffff01f /* 6 */	 , 0xfffff03f /* 9 */	  , 0xfffff07f /* 12 */ , 0xfffff0ff /* 18 */,
+									  0xfffff1ff /* 24 */	 , 0xfffff3ff /* 36 */	  , 0xfffff7ff /* 48 */ , 0xffffffff /* 54 */};
+
+UCHAR MULTICAST_ADDR[MAC_ADDR_LEN] = {0x1,  0x00, 0x00, 0x00, 0x00, 0x00};
+UCHAR BROADCAST_ADDR[MAC_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN]  = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+// e.g. RssiSafeLevelForTxRate[RATE_36]" means if the current RSSI is greater than
+//		this value, then it's quaranteed capable of operating in 36 mbps TX rate in
+//		clean environment.
+//								  TxRate: 1   2   5.5	11	 6	  9    12	18	 24   36   48	54	 72  100
+CHAR RssiSafeLevelForTxRate[] ={  -92, -91, -90, -87, -88, -86, -85, -83, -81, -78, -72, -71, -40, -40 };
+
+UCHAR  RateIdToMbps[]	 = { 1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 72, 100};
+USHORT RateIdTo500Kbps[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 144, 200};
+
+UCHAR  SsidIe	 = IE_SSID;
+UCHAR  SupRateIe = IE_SUPP_RATES;
+UCHAR  ExtRateIe = IE_EXT_SUPP_RATES;
+#ifdef DOT11_N_SUPPORT
+UCHAR  HtCapIe = IE_HT_CAP;
+UCHAR  AddHtInfoIe = IE_ADD_HT;
+UCHAR  NewExtChanIe = IE_SECONDARY_CH_OFFSET;
+#ifdef DOT11N_DRAFT3
+UCHAR  ExtHtCapIe = IE_EXT_CAPABILITY;
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+UCHAR  ErpIe	 = IE_ERP;
+UCHAR  DsIe 	 = IE_DS_PARM;
+UCHAR  TimIe	 = IE_TIM;
+UCHAR  WpaIe	 = IE_WPA;
+UCHAR  Wpa2Ie	 = IE_WPA2;
+UCHAR  IbssIe	 = IE_IBSS_PARM;
+UCHAR  Ccx2Ie	 = IE_CCX_V2;
+UCHAR  WapiIe	 = IE_WAPI;
+
+extern UCHAR	WPA_OUI[];
+
+UCHAR	SES_OUI[] = {0x00, 0x90, 0x4c};
+
+UCHAR	ZeroSsid[32] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+
+// Reset the RFIC setting to new series
+RTMP_RF_REGS RF2850RegTable[] = {
+//		ch	 R1 		 R2 		 R3(TX0~4=0) R4
+		{1,  0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b},
+		{2,  0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f},
+		{3,  0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b},
+		{4,  0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f},
+		{5,  0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b},
+		{6,  0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f},
+		{7,  0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b},
+		{8,  0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f},
+		{9,  0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b},
+		{10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f},
+		{11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b},
+		{12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f},
+		{13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b},
+		{14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193},
+
+		// 802.11 UNI / HyperLan 2
+		{36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3},
+		{38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193},
+		{40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183},
+		{44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3},
+		{46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b},
+		{48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b},
+		{52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193},
+		{54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3},
+		{56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b},
+		{60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183},
+		{62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193},
+		{64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3}, // Plugfest#4, Day4, change RFR3 left4th 9->5.
+
+		// 802.11 HyperLan 2
+		{100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783},
+
+		// 2008.04.30 modified
+		// The system team has AN to improve the EVM value
+		// for channel 102 to 108 for the RT2850/RT2750 dual band solution.
+		{102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793},
+		{104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3},
+		{108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193},
+
+		{110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183},
+		{112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b},
+		{116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3},
+		{118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193},
+		{120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183},
+		{124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193},
+		{126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b}, // 0x980ed1bb->0x980ed15b required by Rory 20070927
+		{128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3},
+		{132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b},
+		{134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193},
+		{136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b},
+		{140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183},
+
+		// 802.11 UNII
+		{149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7},
+		{151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187},
+		{153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f},
+		{157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f},
+		{159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7},
+		{161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187},
+		{165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197},
+
+		// Japan
+		{184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b},
+		{188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13},
+		{192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b},
+		{196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23},
+		{208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13},
+		{212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b},
+		{216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23},
+
+		// still lack of MMAC(Japan) ch 34,38,42,46
+};
+UCHAR	NUM_OF_2850_CHNL = (sizeof(RF2850RegTable) / sizeof(RTMP_RF_REGS));
+
+FREQUENCY_ITEM FreqItems3020[] =
+{
+	/**************************************************/
+	// ISM : 2.4 to 2.483 GHz                         //
+	/**************************************************/
+	// 11g
+	/**************************************************/
+	//-CH---N-------R---K-----------
+	{1,    241,  2,  2},
+	{2,    241,	 2,  7},
+	{3,    242,	 2,  2},
+	{4,    242,	 2,  7},
+	{5,    243,	 2,  2},
+	{6,    243,	 2,  7},
+	{7,    244,	 2,  2},
+	{8,    244,	 2,  7},
+	{9,    245,	 2,  2},
+	{10,   245,	 2,  7},
+	{11,   246,	 2,  2},
+	{12,   246,	 2,  7},
+	{13,   247,	 2,  2},
+	{14,   248,	 2,  4},
+};
+//2008/07/10:KH Modified to share this variable
+UCHAR	NUM_OF_3020_CHNL=(sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM));
+
+/*
+	==========================================================================
+	Description:
+		initialize the MLME task and its data structure (queue, spinlock,
+		timer, state machines).
+
+	IRQL = PASSIVE_LEVEL
+
+	Return:
+		always return NDIS_STATUS_SUCCESS
+
+	==========================================================================
+*/
+NDIS_STATUS MlmeInit(
+	IN PRTMP_ADAPTER pAd)
+{
+	NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--> MLME Initialize\n"));
+
+	do
+	{
+		Status = MlmeQueueInit(&pAd->Mlme.Queue);
+		if(Status != NDIS_STATUS_SUCCESS)
+			break;
+
+		pAd->Mlme.bRunning = FALSE;
+		NdisAllocateSpinLock(&pAd->Mlme.TaskLock);
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+			BssTableInit(&pAd->ScanTab);
+
+			// init STA state machines
+			AssocStateMachineInit(pAd, &pAd->Mlme.AssocMachine, pAd->Mlme.AssocFunc);
+			AuthStateMachineInit(pAd, &pAd->Mlme.AuthMachine, pAd->Mlme.AuthFunc);
+			AuthRspStateMachineInit(pAd, &pAd->Mlme.AuthRspMachine, pAd->Mlme.AuthRspFunc);
+			SyncStateMachineInit(pAd, &pAd->Mlme.SyncMachine, pAd->Mlme.SyncFunc);
+			WpaPskStateMachineInit(pAd, &pAd->Mlme.WpaPskMachine, pAd->Mlme.WpaPskFunc);
+			AironetStateMachineInit(pAd, &pAd->Mlme.AironetMachine, pAd->Mlme.AironetFunc);
+
+#ifdef QOS_DLS_SUPPORT
+			DlsStateMachineInit(pAd, &pAd->Mlme.DlsMachine, pAd->Mlme.DlsFunc);
+#endif // QOS_DLS_SUPPORT //
+
+
+			// Since we are using switch/case to implement it, the init is different from the above
+			// state machine init
+			MlmeCntlInit(pAd, &pAd->Mlme.CntlMachine, NULL);
+		}
+#endif // CONFIG_STA_SUPPORT //
+
+
+
+		ActionStateMachineInit(pAd, &pAd->Mlme.ActMachine, pAd->Mlme.ActFunc);
+
+		// Init mlme periodic timer
+		RTMPInitTimer(pAd, &pAd->Mlme.PeriodicTimer, GET_TIMER_FUNCTION(MlmePeriodicExec), pAd, TRUE);
+
+		// Set mlme periodic timer
+		RTMPSetTimer(&pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
+
+		// software-based RX Antenna diversity
+		RTMPInitTimer(pAd, &pAd->Mlme.RxAntEvalTimer, GET_TIMER_FUNCTION(AsicRxAntEvalTimeout), pAd, FALSE);
+
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+	} while (FALSE);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<-- MLME Initialize\n"));
+
+	return Status;
+}
+
+/*
+	==========================================================================
+	Description:
+		main loop of the MLME
+	Pre:
+		Mlme has to be initialized, and there are something inside the queue
+	Note:
+		This function is invoked from MPSetInformation and MPReceive;
+		This task guarantee only one MlmeHandler will run.
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID MlmeHandler(
+	IN PRTMP_ADAPTER pAd)
+{
+	MLME_QUEUE_ELEM 	   *Elem = NULL;
+
+	// Only accept MLME and Frame from peer side, no other (control/data) frame should
+	// get into this state machine
+
+	NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
+	if(pAd->Mlme.bRunning)
+	{
+		NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
+		return;
+	}
+	else
+	{
+		pAd->Mlme.bRunning = TRUE;
+	}
+	NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
+
+	while (!MlmeQueueEmpty(&pAd->Mlme.Queue))
+	{
+		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS) ||
+			RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
+			RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("Device Halted or Removed or MlmeRest, exit MlmeHandler! (queue num = %ld)\n", pAd->Mlme.Queue.Num));
+			break;
+		}
+
+#ifdef RALINK_ATE
+		if(ATE_ON(pAd))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now in MlmeHandler\n"));
+			break;
+		}
+#endif // RALINK_ATE //
+
+		//From message type, determine which state machine I should drive
+		if (MlmeDequeue(&pAd->Mlme.Queue, &Elem))
+		{
+#ifdef RT2870
+			if (Elem->MsgType == MT2_RESET_CONF)
+			{
+				DBGPRINT_RAW(RT_DEBUG_TRACE, ("!!! reset MLME state machine !!!\n"));
+				MlmeRestartStateMachine(pAd);
+				Elem->Occupied = FALSE;
+				Elem->MsgLen = 0;
+				continue;
+			}
+#endif // RT2870 //
+
+			// if dequeue success
+			switch (Elem->Machine)
+			{
+				// STA state machines
+#ifdef	CONFIG_STA_SUPPORT
+				case ASSOC_STATE_MACHINE:
+					StateMachinePerformAction(pAd, &pAd->Mlme.AssocMachine, Elem);
+					break;
+				case AUTH_STATE_MACHINE:
+					StateMachinePerformAction(pAd, &pAd->Mlme.AuthMachine, Elem);
+					break;
+				case AUTH_RSP_STATE_MACHINE:
+					StateMachinePerformAction(pAd, &pAd->Mlme.AuthRspMachine, Elem);
+					break;
+				case SYNC_STATE_MACHINE:
+					StateMachinePerformAction(pAd, &pAd->Mlme.SyncMachine, Elem);
+					break;
+				case MLME_CNTL_STATE_MACHINE:
+					MlmeCntlMachinePerformAction(pAd, &pAd->Mlme.CntlMachine, Elem);
+					break;
+				case WPA_PSK_STATE_MACHINE:
+					StateMachinePerformAction(pAd, &pAd->Mlme.WpaPskMachine, Elem);
+					break;
+#ifdef LEAP_SUPPORT
+				case LEAP_STATE_MACHINE:
+					LeapMachinePerformAction(pAd, &pAd->Mlme.LeapMachine, Elem);
+					break;
+#endif
+				case AIRONET_STATE_MACHINE:
+					StateMachinePerformAction(pAd, &pAd->Mlme.AironetMachine, Elem);
+					break;
+
+#ifdef QOS_DLS_SUPPORT
+				case DLS_STATE_MACHINE:
+					StateMachinePerformAction(pAd, &pAd->Mlme.DlsMachine, Elem);
+					break;
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+				case ACTION_STATE_MACHINE:
+					StateMachinePerformAction(pAd, &pAd->Mlme.ActMachine, Elem);
+					break;
+
+
+
+
+				default:
+					DBGPRINT(RT_DEBUG_TRACE, ("ERROR: Illegal machine %ld in MlmeHandler()\n", Elem->Machine));
+					break;
+			} // end of switch
+
+			// free MLME element
+			Elem->Occupied = FALSE;
+			Elem->MsgLen = 0;
+
+		}
+		else {
+			DBGPRINT_ERR(("MlmeHandler: MlmeQueue empty\n"));
+		}
+	}
+
+	NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
+	pAd->Mlme.bRunning = FALSE;
+	NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
+}
+
+/*
+	==========================================================================
+	Description:
+		Destructor of MLME (Destroy queue, state machine, spin lock and timer)
+	Parameters:
+		Adapter - NIC Adapter pointer
+	Post:
+		The MLME task will no longer work properly
+
+	IRQL = PASSIVE_LEVEL
+
+	==========================================================================
+ */
+VOID MlmeHalt(
+	IN PRTMP_ADAPTER pAd)
+{
+	BOOLEAN		Cancelled;
+#ifdef RT3070
+	UINT32		TxPinCfg = 0x00050F0F;
+#endif // RT3070 //
+
+	DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeHalt\n"));
+
+	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+	{
+		// disable BEACON generation and other BEACON related hardware timers
+		AsicDisableSync(pAd);
+	}
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+#ifdef QOS_DLS_SUPPORT
+		UCHAR		i;
+#endif // QOS_DLS_SUPPORT //
+		// Cancel pending timers
+		RTMPCancelTimer(&pAd->MlmeAux.AssocTimer,		&Cancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer,		&Cancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer,	&Cancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.AuthTimer,		&Cancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer,		&Cancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.ScanTimer,		&Cancelled);
+
+#ifdef QOS_DLS_SUPPORT
+		for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
+		{
+			RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &Cancelled);
+		}
+#endif // QOS_DLS_SUPPORT //
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	RTMPCancelTimer(&pAd->Mlme.PeriodicTimer,		&Cancelled);
+	RTMPCancelTimer(&pAd->Mlme.RxAntEvalTimer,		&Cancelled);
+
+
+
+	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+	{
+		// Set LED
+		RTMPSetLED(pAd, LED_HALT);
+        RTMPSetSignalLED(pAd, -100);	// Force signal strength Led to be turned off, firmware is not done it.
+#ifdef RT2870
+        {
+            LED_CFG_STRUC LedCfg;
+            RTMP_IO_READ32(pAd, LED_CFG, &LedCfg.word);
+            LedCfg.field.LedPolar = 0;
+            LedCfg.field.RLedMode = 0;
+            LedCfg.field.GLedMode = 0;
+            LedCfg.field.YLedMode = 0;
+            RTMP_IO_WRITE32(pAd, LED_CFG, LedCfg.word);
+        }
+#endif // RT2870 //
+#ifdef RT3070
+		//
+		// Turn off LNA_PE
+		//
+		if (IS_RT3070(pAd) || IS_RT3071(pAd))
+		{
+			TxPinCfg &= 0xFFFFF0F0;
+			RTUSBWriteMACRegister(pAd, TX_PIN_CFG, TxPinCfg);
+		}
+#endif // RT3070 //
+	}
+
+	RTMPusecDelay(5000);    //  5 msec to gurantee Ant Diversity timer canceled
+
+	MlmeQueueDestroy(&pAd->Mlme.Queue);
+	NdisFreeSpinLock(&pAd->Mlme.TaskLock);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeHalt\n"));
+}
+
+VOID MlmeResetRalinkCounters(
+	IN  PRTMP_ADAPTER   pAd)
+{
+	pAd->RalinkCounters.LastOneSecRxOkDataCnt = pAd->RalinkCounters.OneSecRxOkDataCnt;
+	// clear all OneSecxxx counters.
+	pAd->RalinkCounters.OneSecBeaconSentCnt = 0;
+	pAd->RalinkCounters.OneSecFalseCCACnt = 0;
+	pAd->RalinkCounters.OneSecRxFcsErrCnt = 0;
+	pAd->RalinkCounters.OneSecRxOkCnt = 0;
+	pAd->RalinkCounters.OneSecTxFailCount = 0;
+	pAd->RalinkCounters.OneSecTxNoRetryOkCount = 0;
+	pAd->RalinkCounters.OneSecTxRetryOkCount = 0;
+	pAd->RalinkCounters.OneSecRxOkDataCnt = 0;
+
+	// TODO: for debug only. to be removed
+	pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BE] = 0;
+	pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BK] = 0;
+	pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VI] = 0;
+	pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VO] = 0;
+	pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BE] = 0;
+	pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BK] = 0;
+	pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VI] = 0;
+	pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VO] = 0;
+	pAd->RalinkCounters.OneSecTxDoneCount = 0;
+	pAd->RalinkCounters.OneSecRxCount = 0;
+	pAd->RalinkCounters.OneSecTxAggregationCount = 0;
+	pAd->RalinkCounters.OneSecRxAggregationCount = 0;
+
+	return;
+}
+
+unsigned long rx_AMSDU;
+unsigned long rx_Total;
+
+/*
+	==========================================================================
+	Description:
+		This routine is executed periodically to -
+		1. Decide if it's a right time to turn on PwrMgmt bit of all
+		   outgoiing frames
+		2. Calculate ChannelQuality based on statistics of the last
+		   period, so that TX rate won't toggling very frequently between a
+		   successful TX and a failed TX.
+		3. If the calculated ChannelQuality indicated current connection not
+		   healthy, then a ROAMing attempt is tried here.
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+#define ADHOC_BEACON_LOST_TIME		(8*OS_HZ)  // 8 sec
+VOID MlmePeriodicExec(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3)
+{
+	ULONG			TxTotalCnt;
+	PRTMP_ADAPTER	pAd = (RTMP_ADAPTER *)FunctionContext;
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+	// Do nothing if the driver is starting halt state.
+	// This might happen when timer already been fired before cancel timer with mlmehalt
+	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_HALT_IN_PROGRESS |
+								fRTMP_ADAPTER_RADIO_OFF |
+								fRTMP_ADAPTER_RADIO_MEASUREMENT |
+								fRTMP_ADAPTER_RESET_IN_PROGRESS))))
+		return;
+
+	RT28XX_MLME_PRE_SANITY_CHECK(pAd);
+
+#ifdef RALINK_ATE
+	/* Do not show RSSI until "Normal 1 second Mlme PeriodicExec". */
+	if (ATE_ON(pAd))
+	{
+		if (pAd->Mlme.PeriodicRound % MLME_TASK_EXEC_MULTIPLE != (MLME_TASK_EXEC_MULTIPLE - 1))
+	{
+			pAd->Mlme.PeriodicRound ++;
+			return;
+		}
+	}
+#endif // RALINK_ATE //
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		// Do nothing if monitor mode is on
+		if (MONITOR_ON(pAd))
+			return;
+
+		if (pAd->Mlme.PeriodicRound & 0x1)
+		{
+			// This is the fix for wifi 11n extension channel overlapping test case.  for 2860D
+			if (((pAd->MACVersion & 0xffff) == 0x0101) &&
+				(STA_TGN_WIFI_ON(pAd)) &&
+				(pAd->CommonCfg.IOTestParm.bToggle == FALSE))
+
+				{
+					RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x24Bf);
+					pAd->CommonCfg.IOTestParm.bToggle = TRUE;
+				}
+				else if ((STA_TGN_WIFI_ON(pAd)) &&
+						((pAd->MACVersion & 0xffff) == 0x0101))
+				{
+					RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x243f);
+					pAd->CommonCfg.IOTestParm.bToggle = FALSE;
+				}
+		}
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	pAd->bUpdateBcnCntDone = FALSE;
+
+//	RECBATimerTimeout(SystemSpecific1,FunctionContext,SystemSpecific2,SystemSpecific3);
+	pAd->Mlme.PeriodicRound ++;
+
+#ifdef RT2870
+	// execute every 100ms, update the Tx FIFO Cnt for update Tx Rate.
+	NICUpdateFifoStaCounters(pAd);
+#endif // RT2870 //
+	// execute every 500ms
+	if ((pAd->Mlme.PeriodicRound % 5 == 0) && RTMPAutoRateSwitchCheck(pAd)/*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))*/)
+	{
+#ifdef CONFIG_STA_SUPPORT
+		// perform dynamic tx rate switching based on past TX history
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+			if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
+					)
+				&& (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)))
+				MlmeDynamicTxRateSwitching(pAd);
+		}
+#endif // CONFIG_STA_SUPPORT //
+	}
+
+	// Normal 1 second Mlme PeriodicExec.
+	if (pAd->Mlme.PeriodicRound %MLME_TASK_EXEC_MULTIPLE == 0)
+	{
+                pAd->Mlme.OneSecPeriodicRound ++;
+
+#ifdef RALINK_ATE
+    	if (ATE_ON(pAd))
+    	{
+			/* request from Baron : move this routine from later to here */
+			/* for showing Rx error count in ATE RXFRAME */
+            NICUpdateRawCounters(pAd);
+			if (pAd->ate.bRxFer == 1)
+			{
+				pAd->ate.RxTotalCnt += pAd->ate.RxCntPerSec;
+			    ate_print(KERN_EMERG "MlmePeriodicExec: Rx packet cnt = %d/%d\n", pAd->ate.RxCntPerSec, pAd->ate.RxTotalCnt);
+				pAd->ate.RxCntPerSec = 0;
+
+				if (pAd->ate.RxAntennaSel == 0)
+					ate_print(KERN_EMERG "MlmePeriodicExec: Rx AvgRssi0=%d, AvgRssi1=%d, AvgRssi2=%d\n\n",
+						pAd->ate.AvgRssi0, pAd->ate.AvgRssi1, pAd->ate.AvgRssi2);
+				else
+					ate_print(KERN_EMERG "MlmePeriodicExec: Rx AvgRssi=%d\n\n", pAd->ate.AvgRssi0);
+			}
+			MlmeResetRalinkCounters(pAd);
+			return;
+    	}
+#endif // RALINK_ATE //
+
+
+		if (rx_Total)
+		{
+
+			// reset counters
+			rx_AMSDU = 0;
+			rx_Total = 0;
+		}
+
+		//ORIBATimerTimeout(pAd);
+
+		// Media status changed, report to NDIS
+		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE))
+		{
+			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
+			if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+			{
+				pAd->IndicateMediaState = NdisMediaStateConnected;
+				RTMP_IndicateMediaState(pAd);
+
+			}
+			else
+			{
+				pAd->IndicateMediaState = NdisMediaStateDisconnected;
+				RTMP_IndicateMediaState(pAd);
+			}
+		}
+
+		NdisGetSystemUpTime(&pAd->Mlme.Now32);
+
+		// add the most up-to-date h/w raw counters into software variable, so that
+		// the dynamic tuning mechanism below are based on most up-to-date information
+		NICUpdateRawCounters(pAd);
+
+#ifdef RT2870
+		RT2870_WatchDog(pAd);
+#endif // RT2870 //
+
+#ifdef DOT11_N_SUPPORT
+   		// Need statistics after read counter. So put after NICUpdateRawCounters
+		ORIBATimerTimeout(pAd);
+#endif // DOT11_N_SUPPORT //
+
+		// The time period for checking antenna is according to traffic
+		{
+			if (pAd->Mlme.bEnableAutoAntennaCheck)
+			{
+				TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
+								 pAd->RalinkCounters.OneSecTxRetryOkCount +
+								 pAd->RalinkCounters.OneSecTxFailCount;
+
+					// dynamic adjust antenna evaluation period according to the traffic
+				if (TxTotalCnt > 50)
+				{
+					if (pAd->Mlme.OneSecPeriodicRound % 10 == 0)
+					{
+						AsicEvaluateRxAnt(pAd);
+					}
+				}
+				else
+				{
+					if (pAd->Mlme.OneSecPeriodicRound % 3 == 0)
+					{
+						AsicEvaluateRxAnt(pAd);
+					}
+				}
+			}
+		}
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+			STAMlmePeriodicExec(pAd);
+#endif // CONFIG_STA_SUPPORT //
+
+		MlmeResetRalinkCounters(pAd);
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+			{
+				// When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock
+				// and sending CTS-to-self over and over.
+				// Software Patch Solution:
+				// 1. Polling debug state register 0x10F4 every one second.
+				// 2. If in 0x10F4 the ((bit29==1) && (bit7==1)) OR ((bit29==1) && (bit5==1)), it means the deadlock has occurred.
+				// 3. If the deadlock occurred, reset MAC/BBP by setting 0x1004 to 0x0001 for a while then setting it back to 0x000C again.
+
+				UINT32	MacReg = 0;
+
+				RTMP_IO_READ32(pAd, 0x10F4, &MacReg);
+				if (((MacReg & 0x20000000) && (MacReg & 0x80)) || ((MacReg & 0x20000000) && (MacReg & 0x20)))
+				{
+					RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
+					RTMPusecDelay(1);
+					RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xC);
+
+					DBGPRINT(RT_DEBUG_WARN,("Warning, MAC specific condition occurs \n"));
+				}
+			}
+		}
+#endif // CONFIG_STA_SUPPORT //
+
+		RT28XX_MLME_HANDLER(pAd);
+	}
+
+
+	pAd->bUpdateBcnCntDone = FALSE;
+}
+
+#ifdef CONFIG_STA_SUPPORT
+VOID STAMlmePeriodicExec(
+	PRTMP_ADAPTER pAd)
+{
+	ULONG			    TxTotalCnt;
+	int 	i;
+
+//
+// We return here in ATE mode, because the statistics
+// that ATE needs are not collected via this routine.
+//
+#ifdef RALINK_ATE
+	// It is supposed that we will never reach here in ATE mode.
+	ASSERT(!(ATE_ON(pAd)));
+	if (ATE_ON(pAd))
+		return;
+#endif // RALINK_ATE //
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+    if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)
+#endif // WPA_SUPPLICANT_SUPPORT //
+    {
+    	// WPA MIC error should block association attempt for 60 seconds
+    	if (pAd->StaCfg.bBlockAssoc && (pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ) < pAd->Mlme.Now32))
+    		pAd->StaCfg.bBlockAssoc = FALSE;
+    }
+
+    if ((pAd->PreMediaState != pAd->IndicateMediaState) && (pAd->CommonCfg.bWirelessEvent))
+	{
+		if (pAd->IndicateMediaState == NdisMediaStateConnected)
+		{
+			RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+		}
+		pAd->PreMediaState = pAd->IndicateMediaState;
+	}
+
+
+
+
+   	AsicStaBbpTuning(pAd);
+
+	TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
+					 pAd->RalinkCounters.OneSecTxRetryOkCount +
+					 pAd->RalinkCounters.OneSecTxFailCount;
+
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+	{
+		// update channel quality for Roaming and UI LinkQuality display
+		MlmeCalculateChannelQuality(pAd, pAd->Mlme.Now32);
+	}
+
+	// must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if
+	// Radio is currently in noisy environment
+	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+		AsicAdjustTxPower(pAd);
+
+	if (INFRA_ON(pAd))
+	{
+#ifdef QOS_DLS_SUPPORT
+		// Check DLS time out, then tear down those session
+		RTMPCheckDLSTimeOut(pAd);
+#endif // QOS_DLS_SUPPORT //
+
+		// Is PSM bit consistent with user power management policy?
+		// This is the only place that will set PSM bit ON.
+		if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+		MlmeCheckPsmChange(pAd, pAd->Mlme.Now32);
+
+		pAd->RalinkCounters.LastOneSecTotalTxCount = TxTotalCnt;
+
+		if ((pAd->StaCfg.LastBeaconRxTime + 1*OS_HZ < pAd->Mlme.Now32) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
+			((TxTotalCnt + pAd->RalinkCounters.OneSecRxOkCnt < 600)))
+		{
+			RTMPSetAGCInitValue(pAd, BW_20);
+			DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n", (0x2E + GET_LNA_GAIN(pAd))));
+		}
+
+        //if ((pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&
+        //    (pAd->RalinkCounters.OneSecTxRetryOkCount == 0))
+        {
+    		if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable)
+    		{
+    		    // When APSD is enabled, the period changes as 20 sec
+    			if ((pAd->Mlme.OneSecPeriodicRound % 20) == 8)
+    				RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
+    		}
+    		else
+    		{
+    		    // Send out a NULL frame every 10 sec to inform AP that STA is still alive (Avoid being age out)
+    			if ((pAd->Mlme.OneSecPeriodicRound % 10) == 8)
+                {
+                    if (pAd->CommonCfg.bWmmCapable)
+    					RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
+                    else
+						RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
+                }
+    		}
+        }
+
+		if (CQI_IS_DEAD(pAd->Mlme.ChannelQuality))
+			{
+			DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
+			pAd->StaCfg.CCXAdjacentAPReportFlag = TRUE;
+			pAd->StaCfg.CCXAdjacentAPLinkDownTime = pAd->StaCfg.LastBeaconRxTime;
+
+			// Lost AP, send disconnect & link down event
+			LinkDown(pAd, FALSE);
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+            if (pAd->StaCfg.WpaSupplicantUP)
+			{
+                union iwreq_data    wrqu;
+                //send disassociate event to wpa_supplicant
+                memset(&wrqu, 0, sizeof(wrqu));
+                wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
+                wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+            }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+            {
+                union iwreq_data    wrqu;
+                memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+                wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+            }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+			// RTMPPatchMacBbpBug(pAd);
+			MlmeAutoReconnectLastSSID(pAd);
+		}
+		else if (CQI_IS_BAD(pAd->Mlme.ChannelQuality))
+		{
+			pAd->RalinkCounters.BadCQIAutoRecoveryCount ++;
+			DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Bad CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
+			MlmeAutoReconnectLastSSID(pAd);
+		}
+
+		// Add auto seamless roaming
+		if (pAd->StaCfg.bFastRoaming)
+		{
+			SHORT	dBmToRoam = (SHORT)pAd->StaCfg.dBmToRoam;
+
+			DBGPRINT(RT_DEBUG_TRACE, ("Rssi=%d, dBmToRoam=%d\n", RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2), (CHAR)dBmToRoam));
+
+			if (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) <= (CHAR)dBmToRoam)
+			{
+				MlmeCheckForFastRoaming(pAd, pAd->Mlme.Now32);
+			}
+		}
+	}
+	else if (ADHOC_ON(pAd))
+	{
+		//radar detect
+		if ((pAd->CommonCfg.Channel > 14)
+			&& (pAd->CommonCfg.bIEEE80211H == 1)
+			&& RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
+		{
+			RadarDetectPeriodic(pAd);
+		}
+
+		// If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState
+		// to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can
+		// join later.
+		if ((pAd->StaCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32) &&
+			OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+		{
+			MLME_START_REQ_STRUCT     StartReq;
+
+			DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n"));
+			LinkDown(pAd, FALSE);
+
+			StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
+			MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
+			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
+		}
+
+		for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
+		{
+			MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[i];
+
+			if (pEntry->ValidAsCLI == FALSE)
+				continue;
+
+			if (pEntry->LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32)
+				MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
+		}
+	}
+	else // no INFRA nor ADHOC connection
+	{
+
+		if (pAd->StaCfg.bScanReqIsFromWebUI &&
+            ((pAd->StaCfg.LastScanTime + 30 * OS_HZ) > pAd->Mlme.Now32))
+			goto SKIP_AUTO_SCAN_CONN;
+        else
+            pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
+
+		if ((pAd->StaCfg.bAutoReconnect == TRUE)
+			&& RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)
+			&& (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
+		{
+			if ((pAd->ScanTab.BssNr==0) && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE))
+			{
+				MLME_SCAN_REQ_STRUCT	   ScanReq;
+
+				if ((pAd->StaCfg.LastScanTime + 10 * OS_HZ) < pAd->Mlme.Now32)
+				{
+					DBGPRINT(RT_DEBUG_TRACE, ("STAMlmePeriodicExec():CNTL - ScanTab.BssNr==0, start a new ACTIVE scan SSID[%s]\n", pAd->MlmeAux.AutoReconnectSsid));
+					ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen, BSS_ANY, SCAN_ACTIVE);
+					MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
+					pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
+					// Reset Missed scan number
+					pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
+				}
+				else if (pAd->StaCfg.BssType == BSS_ADHOC)	// Quit the forever scan when in a very clean room
+					MlmeAutoReconnectLastSSID(pAd);
+			}
+			else if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
+			{
+				if ((pAd->Mlme.OneSecPeriodicRound % 7) == 0)
+				{
+					MlmeAutoScan(pAd);
+					pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
+				}
+				else
+				{
+#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
+					if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
+					{
+						if ((pAd->Mlme.OneSecPeriodicRound % 5) == 1)
+							MlmeAutoReconnectLastSSID(pAd);
+					}
+					else
+#endif // CARRIER_DETECTION_SUPPORT //
+						MlmeAutoReconnectLastSSID(pAd);
+				}
+			}
+		}
+	}
+
+SKIP_AUTO_SCAN_CONN:
+
+#ifdef DOT11_N_SUPPORT
+    if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap !=0) && (pAd->MacTab.fAnyBASession == FALSE))
+	{
+		pAd->MacTab.fAnyBASession = TRUE;
+		AsicUpdateProtect(pAd, HT_FORCERTSCTS,  ALLN_SETPROTECT, FALSE, FALSE);
+	}
+	else if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap ==0) && (pAd->MacTab.fAnyBASession == TRUE))
+	{
+		pAd->MacTab.fAnyBASession = FALSE;
+		AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode,  ALLN_SETPROTECT, FALSE, FALSE);
+	}
+#endif // DOT11_N_SUPPORT //
+
+
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SCAN_2040))
+		TriEventCounterMaintenance(pAd);
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+
+	return;
+}
+
+// Link down report
+VOID LinkDownExec(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3)
+{
+
+	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+	pAd->IndicateMediaState = NdisMediaStateDisconnected;
+	RTMP_IndicateMediaState(pAd);
+    pAd->ExtraInfo = GENERAL_LINK_DOWN;
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID MlmeAutoScan(
+	IN PRTMP_ADAPTER pAd)
+{
+	// check CntlMachine.CurrState to avoid collision with NDIS SetOID request
+	if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Driver auto scan\n"));
+		MlmeEnqueue(pAd,
+					MLME_CNTL_STATE_MACHINE,
+					OID_802_11_BSSID_LIST_SCAN,
+					0,
+					NULL);
+		RT28XX_MLME_HANDLER(pAd);
+	}
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID MlmeAutoReconnectLastSSID(
+	IN PRTMP_ADAPTER pAd)
+{
+
+
+	// check CntlMachine.CurrState to avoid collision with NDIS SetOID request
+	if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
+		(MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
+	{
+		NDIS_802_11_SSID OidSsid;
+		OidSsid.SsidLength = pAd->MlmeAux.AutoReconnectSsidLen;
+		NdisMoveMemory(OidSsid.Ssid, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
+
+		DBGPRINT(RT_DEBUG_TRACE, ("Driver auto reconnect to last OID_802_11_SSID setting - %s, len - %d\n", pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen));
+		MlmeEnqueue(pAd,
+					MLME_CNTL_STATE_MACHINE,
+					OID_802_11_SSID,
+					sizeof(NDIS_802_11_SSID),
+					&OidSsid);
+		RT28XX_MLME_HANDLER(pAd);
+	}
+}
+#endif // CONFIG_STA_SUPPORT //
+
+/*
+	==========================================================================
+	Validate SSID for connection try and rescan purpose
+	Valid SSID will have visible chars only.
+	The valid length is from 0 to 32.
+	IRQL = DISPATCH_LEVEL
+	==========================================================================
+ */
+BOOLEAN MlmeValidateSSID(
+	IN PUCHAR	pSsid,
+	IN UCHAR	SsidLen)
+{
+	int	index;
+
+	if (SsidLen > MAX_LEN_OF_SSID)
+		return (FALSE);
+
+	// Check each character value
+	for (index = 0; index < SsidLen; index++)
+	{
+		if (pSsid[index] < 0x20)
+			return (FALSE);
+	}
+
+	// All checked
+	return (TRUE);
+}
+
+VOID MlmeSelectTxRateTable(
+	IN PRTMP_ADAPTER		pAd,
+	IN PMAC_TABLE_ENTRY		pEntry,
+	IN PUCHAR				*ppTable,
+	IN PUCHAR				pTableSize,
+	IN PUCHAR				pInitTxRateIdx)
+{
+	do
+	{
+		// decide the rate table for tuning
+		if (pAd->CommonCfg.TxRateTableSize > 0)
+		{
+			*ppTable = RateSwitchTable;
+			*pTableSize = RateSwitchTable[0];
+			*pInitTxRateIdx = RateSwitchTable[1];
+
+			break;
+		}
+
+#ifdef CONFIG_STA_SUPPORT
+		if ((pAd->OpMode == OPMODE_STA) && ADHOC_ON(pAd))
+		{
+#ifdef DOT11_N_SUPPORT
+			if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
+				(pEntry->HTCapability.MCSSet[0] == 0xff) &&
+				((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
+			{// 11N 1S Adhoc
+				*ppTable = RateSwitchTable11N1S;
+				*pTableSize = RateSwitchTable11N1S[0];
+				*pInitTxRateIdx = RateSwitchTable11N1S[1];
+
+			}
+			else if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
+					(pEntry->HTCapability.MCSSet[0] == 0xff) &&
+					(pEntry->HTCapability.MCSSet[1] == 0xff) &&
+					(pAd->Antenna.field.TxPath == 2))
+			{// 11N 2S Adhoc
+				if (pAd->LatchRfRegs.Channel <= 14)
+				{
+					*ppTable = RateSwitchTable11N2S;
+					*pTableSize = RateSwitchTable11N2S[0];
+					*pInitTxRateIdx = RateSwitchTable11N2S[1];
+				}
+				else
+				{
+					*ppTable = RateSwitchTable11N2SForABand;
+					*pTableSize = RateSwitchTable11N2SForABand[0];
+					*pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
+				}
+
+			}
+			else
+#endif // DOT11_N_SUPPORT //
+				if ((pEntry->RateLen == 4)
+#ifdef DOT11_N_SUPPORT
+					&& (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
+#endif // DOT11_N_SUPPORT //
+					)
+			{
+				*ppTable = RateSwitchTable11B;
+				*pTableSize = RateSwitchTable11B[0];
+				*pInitTxRateIdx = RateSwitchTable11B[1];
+
+			}
+			else if (pAd->LatchRfRegs.Channel <= 14)
+			{
+				*ppTable = RateSwitchTable11BG;
+				*pTableSize = RateSwitchTable11BG[0];
+				*pInitTxRateIdx = RateSwitchTable11BG[1];
+
+			}
+			else
+			{
+				*ppTable = RateSwitchTable11G;
+				*pTableSize = RateSwitchTable11G[0];
+				*pInitTxRateIdx = RateSwitchTable11G[1];
+
+			}
+			break;
+		}
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef DOT11_N_SUPPORT
+		//if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
+		//	((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
+		if ((pEntry->RateLen == 12) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
+			((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
+		{// 11BGN 1S AP
+			*ppTable = RateSwitchTable11BGN1S;
+			*pTableSize = RateSwitchTable11BGN1S[0];
+			*pInitTxRateIdx = RateSwitchTable11BGN1S[1];
+
+			break;
+		}
+
+		//else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
+		//	(pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2))
+		if ((pEntry->RateLen == 12) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
+			(pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
+		{// 11BGN 2S AP
+			if (pAd->LatchRfRegs.Channel <= 14)
+			{
+				*ppTable = RateSwitchTable11BGN2S;
+				*pTableSize = RateSwitchTable11BGN2S[0];
+				*pInitTxRateIdx = RateSwitchTable11BGN2S[1];
+
+			}
+			else
+			{
+				*ppTable = RateSwitchTable11BGN2SForABand;
+				*pTableSize = RateSwitchTable11BGN2SForABand[0];
+				*pInitTxRateIdx = RateSwitchTable11BGN2SForABand[1];
+
+			}
+			break;
+		}
+
+		//else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
+		if ((pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
+		{// 11N 1S AP
+			*ppTable = RateSwitchTable11N1S;
+			*pTableSize = RateSwitchTable11N1S[0];
+			*pInitTxRateIdx = RateSwitchTable11N1S[1];
+
+			break;
+		}
+
+		//else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2))
+		if ((pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
+		{// 11N 2S AP
+			if (pAd->LatchRfRegs.Channel <= 14)
+			{
+			*ppTable = RateSwitchTable11N2S;
+			*pTableSize = RateSwitchTable11N2S[0];
+			*pInitTxRateIdx = RateSwitchTable11N2S[1];
+            }
+			else
+			{
+				*ppTable = RateSwitchTable11N2SForABand;
+				*pTableSize = RateSwitchTable11N2SForABand[0];
+				*pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
+			}
+
+			break;
+		}
+#endif // DOT11_N_SUPPORT //
+		//else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
+		if ((pEntry->RateLen == 4)
+#ifdef DOT11_N_SUPPORT
+//Iverson mark for Adhoc b mode,sta will use rate 54  Mbps when connect with sta b/g/n mode
+//			&& (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
+#endif // DOT11_N_SUPPORT //
+			)
+		{// B only AP
+			*ppTable = RateSwitchTable11B;
+			*pTableSize = RateSwitchTable11B[0];
+			*pInitTxRateIdx = RateSwitchTable11B[1];
+
+			break;
+		}
+
+		//else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen > 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
+		if ((pEntry->RateLen > 8)
+#ifdef DOT11_N_SUPPORT
+			&& (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
+#endif // DOT11_N_SUPPORT //
+			)
+		{// B/G  mixed AP
+			*ppTable = RateSwitchTable11BG;
+			*pTableSize = RateSwitchTable11BG[0];
+			*pInitTxRateIdx = RateSwitchTable11BG[1];
+
+			break;
+		}
+
+		//else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
+		if ((pEntry->RateLen == 8)
+#ifdef DOT11_N_SUPPORT
+			&& (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
+#endif // DOT11_N_SUPPORT //
+			)
+		{// G only AP
+			*ppTable = RateSwitchTable11G;
+			*pTableSize = RateSwitchTable11G[0];
+			*pInitTxRateIdx = RateSwitchTable11G[1];
+
+			break;
+		}
+#ifdef DOT11_N_SUPPORT
+#endif // DOT11_N_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+#ifdef DOT11_N_SUPPORT
+			//else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
+			if ((pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0))
+#endif // DOT11_N_SUPPORT //
+			{	// Legacy mode
+				if (pAd->CommonCfg.MaxTxRate <= RATE_11)
+				{
+					*ppTable = RateSwitchTable11B;
+					*pTableSize = RateSwitchTable11B[0];
+					*pInitTxRateIdx = RateSwitchTable11B[1];
+				}
+				else if ((pAd->CommonCfg.MaxTxRate > RATE_11) && (pAd->CommonCfg.MinTxRate > RATE_11))
+				{
+					*ppTable = RateSwitchTable11G;
+					*pTableSize = RateSwitchTable11G[0];
+					*pInitTxRateIdx = RateSwitchTable11G[1];
+
+				}
+				else
+				{
+					*ppTable = RateSwitchTable11BG;
+					*pTableSize = RateSwitchTable11BG[0];
+					*pInitTxRateIdx = RateSwitchTable11BG[1];
+				}
+				break;
+			}
+#ifdef DOT11_N_SUPPORT
+			if (pAd->LatchRfRegs.Channel <= 14)
+			{
+				if (pAd->CommonCfg.TxStream == 1)
+				{
+					*ppTable = RateSwitchTable11N1S;
+					*pTableSize = RateSwitchTable11N1S[0];
+					*pInitTxRateIdx = RateSwitchTable11N1S[1];
+					DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));
+				}
+				else
+				{
+					*ppTable = RateSwitchTable11N2S;
+					*pTableSize = RateSwitchTable11N2S[0];
+					*pInitTxRateIdx = RateSwitchTable11N2S[1];
+					DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
+				}
+			}
+			else
+			{
+				if (pAd->CommonCfg.TxStream == 1)
+				{
+					*ppTable = RateSwitchTable11N1S;
+					*pTableSize = RateSwitchTable11N1S[0];
+					*pInitTxRateIdx = RateSwitchTable11N1S[1];
+					DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));
+				}
+				else
+				{
+					*ppTable = RateSwitchTable11N2SForABand;
+					*pTableSize = RateSwitchTable11N2SForABand[0];
+					*pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
+					DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
+				}
+			}
+#endif // DOT11_N_SUPPORT //
+			DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n",
+				pAd->StaActive.SupRateLen, pAd->StaActive.ExtRateLen, pAd->StaActive.SupportedPhyInfo.MCSSet[0], pAd->StaActive.SupportedPhyInfo.MCSSet[1]));
+		}
+#endif // CONFIG_STA_SUPPORT //
+	} while(FALSE);
+}
+
+#ifdef CONFIG_STA_SUPPORT
+/*
+	==========================================================================
+	Description:
+		This routine checks if there're other APs out there capable for
+		roaming. Caller should call this routine only when Link up in INFRA mode
+		and channel quality is below CQI_GOOD_THRESHOLD.
+
+	IRQL = DISPATCH_LEVEL
+
+	Output:
+	==========================================================================
+ */
+VOID MlmeCheckForRoaming(
+	IN PRTMP_ADAPTER pAd,
+	IN ULONG	Now32)
+{
+	USHORT	   i;
+	BSS_TABLE  *pRoamTab = &pAd->MlmeAux.RoamTab;
+	BSS_ENTRY  *pBss;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForRoaming\n"));
+	// put all roaming candidates into RoamTab, and sort in RSSI order
+	BssTableInit(pRoamTab);
+	for (i = 0; i < pAd->ScanTab.BssNr; i++)
+	{
+		pBss = &pAd->ScanTab.BssEntry[i];
+
+		if ((pBss->LastBeaconRxTime + BEACON_LOST_TIME) < Now32)
+			continue;	 // AP disappear
+		if (pBss->Rssi <= RSSI_THRESHOLD_FOR_ROAMING)
+			continue;	 // RSSI too weak. forget it.
+		if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
+			continue;	 // skip current AP
+		if (pBss->Rssi < (pAd->StaCfg.RssiSample.LastRssi0 + RSSI_DELTA))
+			continue;	 // only AP with stronger RSSI is eligible for roaming
+
+		// AP passing all above rules is put into roaming candidate table
+		NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
+		pRoamTab->BssNr += 1;
+	}
+
+	if (pRoamTab->BssNr > 0)
+	{
+		// check CntlMachine.CurrState to avoid collision with NDIS SetOID request
+		if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
+		{
+			pAd->RalinkCounters.PoorCQIRoamingCount ++;
+			DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
+			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
+			RT28XX_MLME_HANDLER(pAd);
+		}
+	}
+	DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForRoaming(# of candidate= %d)\n",pRoamTab->BssNr));
+}
+
+/*
+	==========================================================================
+	Description:
+		This routine checks if there're other APs out there capable for
+		roaming. Caller should call this routine only when link up in INFRA mode
+		and channel quality is below CQI_GOOD_THRESHOLD.
+
+	IRQL = DISPATCH_LEVEL
+
+	Output:
+	==========================================================================
+ */
+VOID MlmeCheckForFastRoaming(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	ULONG			Now)
+{
+	USHORT		i;
+	BSS_TABLE	*pRoamTab = &pAd->MlmeAux.RoamTab;
+	BSS_ENTRY	*pBss;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForFastRoaming\n"));
+	// put all roaming candidates into RoamTab, and sort in RSSI order
+	BssTableInit(pRoamTab);
+	for (i = 0; i < pAd->ScanTab.BssNr; i++)
+	{
+		pBss = &pAd->ScanTab.BssEntry[i];
+
+        if ((pBss->Rssi <= -50) && (pBss->Channel == pAd->CommonCfg.Channel))
+			continue;	 // RSSI too weak. forget it.
+		if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
+			continue;	 // skip current AP
+		if (!SSID_EQUAL(pBss->Ssid, pBss->SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen))
+			continue;	 // skip different SSID
+        if (pBss->Rssi < (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) + RSSI_DELTA))
+			continue;	 // skip AP without better RSSI
+
+        DBGPRINT(RT_DEBUG_TRACE, ("LastRssi0 = %d, pBss->Rssi = %d\n", RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2), pBss->Rssi));
+		// AP passing all above rules is put into roaming candidate table
+		NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
+		pRoamTab->BssNr += 1;
+	}
+
+	if (pRoamTab->BssNr > 0)
+	{
+		// check CntlMachine.CurrState to avoid collision with NDIS SetOID request
+		if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
+		{
+			pAd->RalinkCounters.PoorCQIRoamingCount ++;
+			DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
+			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
+			RT28XX_MLME_HANDLER(pAd);
+		}
+	}
+	// Maybe site survey required
+	else
+	{
+		if ((pAd->StaCfg.LastScanTime + 10 * 1000) < Now)
+		{
+			// check CntlMachine.CurrState to avoid collision with NDIS SetOID request
+			DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming, No eligable entry, try new scan!\n"));
+			pAd->StaCfg.ScanCnt = 2;
+			pAd->StaCfg.LastScanTime = Now;
+			MlmeAutoScan(pAd);
+		}
+	}
+
+    DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr));
+}
+
+/*
+	==========================================================================
+	Description:
+		This routine calculates TxPER, RxPER of the past N-sec period. And
+		according to the calculation result, ChannelQuality is calculated here
+		to decide if current AP is still doing the job.
+
+		If ChannelQuality is not good, a ROAMing attempt may be tried later.
+	Output:
+		StaCfg.ChannelQuality - 0..100
+
+	IRQL = DISPATCH_LEVEL
+
+	NOTE: This routine decide channle quality based on RX CRC error ratio.
+		Caller should make sure a function call to NICUpdateRawCounters(pAd)
+		is performed right before this routine, so that this routine can decide
+		channel quality based on the most up-to-date information
+	==========================================================================
+ */
+VOID MlmeCalculateChannelQuality(
+	IN PRTMP_ADAPTER pAd,
+	IN ULONG Now32)
+{
+	ULONG TxOkCnt, TxCnt, TxPER, TxPRR;
+	ULONG RxCnt, RxPER;
+	UCHAR NorRssi;
+	CHAR  MaxRssi;
+	ULONG BeaconLostTime = BEACON_LOST_TIME;
+
+#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
+	// longer beacon lost time when carrier detection enabled
+	if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
+	{
+		BeaconLostTime = BEACON_LOST_TIME + BEACON_LOST_TIME/2;
+	}
+#endif // CARRIER_DETECTION_SUPPORT //
+
+	MaxRssi = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2);
+
+	//
+	// calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics
+	//
+	TxOkCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + pAd->RalinkCounters.OneSecTxRetryOkCount;
+	TxCnt = TxOkCnt + pAd->RalinkCounters.OneSecTxFailCount;
+	if (TxCnt < 5)
+	{
+		TxPER = 0;
+		TxPRR = 0;
+	}
+	else
+	{
+		TxPER = (pAd->RalinkCounters.OneSecTxFailCount * 100) / TxCnt;
+		TxPRR = ((TxCnt - pAd->RalinkCounters.OneSecTxNoRetryOkCount) * 100) / TxCnt;
+	}
+
+	//
+	// calculate RX PER - don't take RxPER into consideration if too few sample
+	//
+	RxCnt = pAd->RalinkCounters.OneSecRxOkCnt + pAd->RalinkCounters.OneSecRxFcsErrCnt;
+	if (RxCnt < 5)
+		RxPER = 0;
+	else
+		RxPER = (pAd->RalinkCounters.OneSecRxFcsErrCnt * 100) / RxCnt;
+
+	//
+	// decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER
+	//
+	if (INFRA_ON(pAd) &&
+		(pAd->RalinkCounters.OneSecTxNoRetryOkCount < 2) && // no heavy traffic
+		(pAd->StaCfg.LastBeaconRxTime + BeaconLostTime < Now32))
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n", BeaconLostTime, TxOkCnt));
+		pAd->Mlme.ChannelQuality = 0;
+	}
+	else
+	{
+		// Normalize Rssi
+		if (MaxRssi > -40)
+			NorRssi = 100;
+		else if (MaxRssi < -90)
+			NorRssi = 0;
+		else
+			NorRssi = (MaxRssi + 90) * 2;
+
+		// ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER	 (RSSI 0..100), (TxPER 100..0), (RxPER 100..0)
+		pAd->Mlme.ChannelQuality = (RSSI_WEIGHTING * NorRssi +
+								   TX_WEIGHTING * (100 - TxPRR) +
+								   RX_WEIGHTING* (100 - RxPER)) / 100;
+		if (pAd->Mlme.ChannelQuality >= 100)
+			pAd->Mlme.ChannelQuality = 100;
+	}
+
+}
+
+VOID MlmeSetTxRate(
+	IN PRTMP_ADAPTER		pAd,
+	IN PMAC_TABLE_ENTRY		pEntry,
+	IN PRTMP_TX_RATE_SWITCH	pTxRate)
+{
+	UCHAR	MaxMode = MODE_OFDM;
+
+#ifdef DOT11_N_SUPPORT
+	MaxMode = MODE_HTGREENFIELD;
+
+	if (pTxRate->STBC && (pAd->StaCfg.MaxHTPhyMode.field.STBC) && (pAd->Antenna.field.TxPath == 2))
+		pAd->StaCfg.HTPhyMode.field.STBC = STBC_USE;
+	else
+#endif // DOT11_N_SUPPORT //
+		pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
+
+	if (pTxRate->CurrMCS < MCS_AUTO)
+		pAd->StaCfg.HTPhyMode.field.MCS = pTxRate->CurrMCS;
+
+	if (pAd->StaCfg.HTPhyMode.field.MCS > 7)
+		pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
+
+   	if (ADHOC_ON(pAd))
+	{
+		// If peer adhoc is b-only mode, we can't send 11g rate.
+		pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
+		pEntry->HTPhyMode.field.STBC	= STBC_NONE;
+
+		//
+		// For Adhoc MODE_CCK, driver will use AdhocBOnlyJoined flag to roll back to B only if necessary
+		//
+		pEntry->HTPhyMode.field.MODE	= pTxRate->Mode;
+		pEntry->HTPhyMode.field.ShortGI	= pAd->StaCfg.HTPhyMode.field.ShortGI;
+		pEntry->HTPhyMode.field.MCS		= pAd->StaCfg.HTPhyMode.field.MCS;
+
+		// Patch speed error in status page
+		pAd->StaCfg.HTPhyMode.field.MODE = pEntry->HTPhyMode.field.MODE;
+	}
+	else
+	{
+		if (pTxRate->Mode <= MaxMode)
+			pAd->StaCfg.HTPhyMode.field.MODE = pTxRate->Mode;
+
+#ifdef DOT11_N_SUPPORT
+		if (pTxRate->ShortGI && (pAd->StaCfg.MaxHTPhyMode.field.ShortGI))
+			pAd->StaCfg.HTPhyMode.field.ShortGI = GI_400;
+		else
+#endif // DOT11_N_SUPPORT //
+			pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
+
+#ifdef DOT11_N_SUPPORT
+		// Reexam each bandwidth's SGI support.
+		if (pAd->StaCfg.HTPhyMode.field.ShortGI == GI_400)
+		{
+			if ((pEntry->HTPhyMode.field.BW == BW_20) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE)))
+				pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
+			if ((pEntry->HTPhyMode.field.BW == BW_40) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE)))
+				pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
+		}
+
+		// Turn RTS/CTS rate to 6Mbps.
+		if ((pEntry->HTPhyMode.field.MCS == 0) && (pAd->StaCfg.HTPhyMode.field.MCS != 0))
+		{
+			pEntry->HTPhyMode.field.MCS		= pAd->StaCfg.HTPhyMode.field.MCS;
+			if (pAd->MacTab.fAnyBASession)
+			{
+				AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+			}
+			else
+			{
+				AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+			}
+		}
+		else if ((pEntry->HTPhyMode.field.MCS == 8) && (pAd->StaCfg.HTPhyMode.field.MCS != 8))
+		{
+			pEntry->HTPhyMode.field.MCS		= pAd->StaCfg.HTPhyMode.field.MCS;
+			if (pAd->MacTab.fAnyBASession)
+			{
+				AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+			}
+			else
+			{
+				AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+			}
+		}
+		else if ((pEntry->HTPhyMode.field.MCS != 0) && (pAd->StaCfg.HTPhyMode.field.MCS == 0))
+		{
+			AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+
+		}
+		else if ((pEntry->HTPhyMode.field.MCS != 8) && (pAd->StaCfg.HTPhyMode.field.MCS == 8))
+		{
+			AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+		}
+#endif // DOT11_N_SUPPORT //
+
+		pEntry->HTPhyMode.field.STBC	= pAd->StaCfg.HTPhyMode.field.STBC;
+		pEntry->HTPhyMode.field.ShortGI	= pAd->StaCfg.HTPhyMode.field.ShortGI;
+		pEntry->HTPhyMode.field.MCS		= pAd->StaCfg.HTPhyMode.field.MCS;
+		pEntry->HTPhyMode.field.MODE	= pAd->StaCfg.HTPhyMode.field.MODE;
+#ifdef DOT11_N_SUPPORT
+		if ((pAd->StaCfg.MaxHTPhyMode.field.MODE == MODE_HTGREENFIELD) &&
+		    pAd->WIFItestbed.bGreenField)
+		    pEntry->HTPhyMode.field.MODE = MODE_HTGREENFIELD;
+#endif // DOT11_N_SUPPORT //
+	}
+
+	pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
+}
+
+/*
+	==========================================================================
+	Description:
+		This routine calculates the acumulated TxPER of eaxh TxRate. And
+		according to the calculation result, change CommonCfg.TxRate which
+		is the stable TX Rate we expect the Radio situation could sustained.
+
+		CommonCfg.TxRate will change dynamically within {RATE_1/RATE_6, MaxTxRate}
+	Output:
+		CommonCfg.TxRate -
+
+	IRQL = DISPATCH_LEVEL
+
+	NOTE:
+		call this routine every second
+	==========================================================================
+ */
+VOID MlmeDynamicTxRateSwitching(
+	IN PRTMP_ADAPTER pAd)
+{
+	UCHAR					UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx;
+	ULONG					i, AccuTxTotalCnt = 0, TxTotalCnt;
+	ULONG					TxErrorRatio = 0;
+	BOOLEAN					bTxRateChanged, bUpgradeQuality = FALSE;
+	PRTMP_TX_RATE_SWITCH	pCurrTxRate, pNextTxRate = NULL;
+	PUCHAR					pTable;
+	UCHAR					TableSize = 0;
+	UCHAR					InitTxRateIdx = 0, TrainUp, TrainDown;
+	CHAR					Rssi, RssiOffset = 0;
+	TX_STA_CNT1_STRUC		StaTx1;
+	TX_STA_CNT0_STRUC		TxStaCnt0;
+	ULONG					TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
+	MAC_TABLE_ENTRY			*pEntry;
+
+#ifdef RALINK_ATE
+	if (ATE_ON(pAd))
+	{
+		return;
+	}
+#endif // RALINK_ATE //
+
+	//
+	// walk through MAC table, see if need to change AP's TX rate toward each entry
+	//
+   	for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
+	{
+		pEntry = &pAd->MacTab.Content[i];
+
+		// check if this entry need to switch rate automatically
+		if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
+			continue;
+
+		if ((pAd->MacTab.Size == 1) || (pEntry->ValidAsDls))
+		{
+			Rssi = RTMPMaxRssi(pAd,
+							   pAd->StaCfg.RssiSample.AvgRssi0,
+							   pAd->StaCfg.RssiSample.AvgRssi1,
+							   pAd->StaCfg.RssiSample.AvgRssi2);
+
+			// Update statistic counter
+			RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
+			RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
+			pAd->bUpdateBcnCntDone = TRUE;
+			TxRetransmit = StaTx1.field.TxRetransmit;
+			TxSuccess = StaTx1.field.TxSuccess;
+			TxFailCount = TxStaCnt0.field.TxFailCount;
+			TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
+
+			pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
+			pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
+			pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
+			pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
+			pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
+			pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
+
+			// if no traffic in the past 1-sec period, don't change TX rate,
+			// but clear all bad history. because the bad history may affect the next
+			// Chariot throughput test
+			AccuTxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
+						 pAd->RalinkCounters.OneSecTxRetryOkCount +
+						 pAd->RalinkCounters.OneSecTxFailCount;
+
+			if (TxTotalCnt)
+				TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
+		}
+		else
+		{
+			if (INFRA_ON(pAd) && (i == 1))
+				Rssi = RTMPMaxRssi(pAd,
+								   pAd->StaCfg.RssiSample.AvgRssi0,
+								   pAd->StaCfg.RssiSample.AvgRssi1,
+								   pAd->StaCfg.RssiSample.AvgRssi2);
+			else
+				Rssi = RTMPMaxRssi(pAd,
+								   pEntry->RssiSample.AvgRssi0,
+								   pEntry->RssiSample.AvgRssi1,
+								   pEntry->RssiSample.AvgRssi2);
+
+			TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
+				 pEntry->OneSecTxRetryOkCount +
+				 pEntry->OneSecTxFailCount;
+
+			if (TxTotalCnt)
+				TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
+		}
+
+		CurrRateIdx = pEntry->CurrTxRateIndex;
+
+		MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
+
+		if (CurrRateIdx >= TableSize)
+		{
+			CurrRateIdx = TableSize - 1;
+		}
+
+		// When switch from Fixed rate -> auto rate, the REAL TX rate might be different from pAd->CommonCfg.TxRateIndex.
+		// So need to sync here.
+		pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
+		if ((pEntry->HTPhyMode.field.MCS != pCurrTxRate->CurrMCS)
+			//&& (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
+			)
+		{
+
+			// Need to sync Real Tx rate and our record.
+			// Then return for next DRS.
+			pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(InitTxRateIdx+1)*5];
+			pEntry->CurrTxRateIndex = InitTxRateIdx;
+			MlmeSetTxRate(pAd, pEntry, pCurrTxRate);
+
+			// reset all OneSecTx counters
+			RESET_ONE_SEC_TX_CNT(pEntry);
+			continue;
+		}
+
+		// decide the next upgrade rate and downgrade rate, if any
+		if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
+		{
+			UpRateIdx = CurrRateIdx + 1;
+			DownRateIdx = CurrRateIdx -1;
+		}
+		else if (CurrRateIdx == 0)
+		{
+			UpRateIdx = CurrRateIdx + 1;
+			DownRateIdx = CurrRateIdx;
+		}
+		else if (CurrRateIdx == (TableSize - 1))
+		{
+			UpRateIdx = CurrRateIdx;
+			DownRateIdx = CurrRateIdx - 1;
+		}
+
+		pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
+
+#ifdef DOT11_N_SUPPORT
+		if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
+		{
+			TrainUp		= (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
+			TrainDown	= (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
+		}
+		else
+#endif // DOT11_N_SUPPORT //
+		{
+			TrainUp		= pCurrTxRate->TrainUp;
+			TrainDown	= pCurrTxRate->TrainDown;
+		}
+
+		//pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction;
+
+		//
+		// Keep the last time TxRateChangeAction status.
+		//
+		pEntry->LastTimeTxRateChangeAction = pEntry->LastSecTxRateChangeAction;
+
+
+
+		//
+		// CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
+		//         (criteria copied from RT2500 for Netopia case)
+		//
+		if (TxTotalCnt <= 15)
+		{
+			CHAR	idx = 0;
+			UCHAR	TxRateIdx;
+			//UCHAR	MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS7 = 0, MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
+			UCHAR	MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0,  MCS5 =0, MCS6 = 0, MCS7 = 0;
+	        UCHAR	MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
+			UCHAR	MCS20 = 0, MCS21 = 0, MCS22 = 0, MCS23 = 0; // 3*3
+
+			// check the existence and index of each needed MCS
+			while (idx < pTable[0])
+			{
+				pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(idx+1)*5];
+
+				if (pCurrTxRate->CurrMCS == MCS_0)
+				{
+					MCS0 = idx;
+				}
+				else if (pCurrTxRate->CurrMCS == MCS_1)
+				{
+					MCS1 = idx;
+				}
+				else if (pCurrTxRate->CurrMCS == MCS_2)
+				{
+					MCS2 = idx;
+				}
+				else if (pCurrTxRate->CurrMCS == MCS_3)
+				{
+					MCS3 = idx;
+				}
+				else if (pCurrTxRate->CurrMCS == MCS_4)
+				{
+					MCS4 = idx;
+				}
+	            else if (pCurrTxRate->CurrMCS == MCS_5)
+	            {
+	                MCS5 = idx;
+	            }
+	            else if (pCurrTxRate->CurrMCS == MCS_6)
+	            {
+	                MCS6 = idx;
+	            }
+				//else if (pCurrTxRate->CurrMCS == MCS_7)
+				else if ((pCurrTxRate->CurrMCS == MCS_7) && (pCurrTxRate->ShortGI == GI_800))	// prevent the highest MCS using short GI when 1T and low throughput
+				{
+					MCS7 = idx;
+				}
+				else if (pCurrTxRate->CurrMCS == MCS_12)
+				{
+					MCS12 = idx;
+				}
+				else if (pCurrTxRate->CurrMCS == MCS_13)
+				{
+					MCS13 = idx;
+				}
+				else if (pCurrTxRate->CurrMCS == MCS_14)
+				{
+					MCS14 = idx;
+				}
+				else if ((pCurrTxRate->CurrMCS == MCS_15) && (pCurrTxRate->ShortGI == GI_800))
+				{
+					MCS15 = idx;
+				}
+				else if (pCurrTxRate->CurrMCS == MCS_20) // 3*3
+				{
+					MCS20 = idx;
+				}
+				else if (pCurrTxRate->CurrMCS == MCS_21)
+				{
+					MCS21 = idx;
+				}
+				else if (pCurrTxRate->CurrMCS == MCS_22)
+				{
+					MCS22 = idx;
+				}
+				else if (pCurrTxRate->CurrMCS == MCS_23)
+				{
+					MCS23 = idx;
+				}
+				idx ++;
+			}
+
+			if (pAd->LatchRfRegs.Channel <= 14)
+			{
+				if (pAd->NicConfig2.field.ExternalLNAForG)
+				{
+					RssiOffset = 2;
+				}
+				else
+				{
+					RssiOffset = 5;
+				}
+			}
+			else
+			{
+				if (pAd->NicConfig2.field.ExternalLNAForA)
+				{
+					RssiOffset = 5;
+				}
+				else
+				{
+					RssiOffset = 8;
+				}
+			}
+#ifdef DOT11_N_SUPPORT
+			/*if (MCS15)*/
+			if ((pTable == RateSwitchTable11BGN3S) ||
+				(pTable == RateSwitchTable11N3S) ||
+				(pTable == RateSwitchTable))
+			{// N mode with 3 stream // 3*3
+				if (MCS23 && (Rssi >= -70))
+					TxRateIdx = MCS15;
+				else if (MCS22 && (Rssi >= -72))
+					TxRateIdx = MCS14;
+        	    else if (MCS21 && (Rssi >= -76))
+					TxRateIdx = MCS13;
+				else if (MCS20 && (Rssi >= -78))
+					TxRateIdx = MCS12;
+			else if (MCS4 && (Rssi >= -82))
+				TxRateIdx = MCS4;
+			else if (MCS3 && (Rssi >= -84))
+				TxRateIdx = MCS3;
+			else if (MCS2 && (Rssi >= -86))
+				TxRateIdx = MCS2;
+			else if (MCS1 && (Rssi >= -88))
+				TxRateIdx = MCS1;
+			else
+				TxRateIdx = MCS0;
+		}
+//		else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand) || (pTable == RateSwitchTable))
+		else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand)) // 3*3
+			{// N mode with 2 stream
+				if (MCS15 && (Rssi >= (-70+RssiOffset)))
+					TxRateIdx = MCS15;
+				else if (MCS14 && (Rssi >= (-72+RssiOffset)))
+					TxRateIdx = MCS14;
+				else if (MCS13 && (Rssi >= (-76+RssiOffset)))
+					TxRateIdx = MCS13;
+				else if (MCS12 && (Rssi >= (-78+RssiOffset)))
+					TxRateIdx = MCS12;
+				else if (MCS4 && (Rssi >= (-82+RssiOffset)))
+					TxRateIdx = MCS4;
+				else if (MCS3 && (Rssi >= (-84+RssiOffset)))
+					TxRateIdx = MCS3;
+				else if (MCS2 && (Rssi >= (-86+RssiOffset)))
+					TxRateIdx = MCS2;
+				else if (MCS1 && (Rssi >= (-88+RssiOffset)))
+					TxRateIdx = MCS1;
+				else
+					TxRateIdx = MCS0;
+			}
+			else if ((pTable == RateSwitchTable11BGN1S) || (pTable == RateSwitchTable11N1S))
+			{// N mode with 1 stream
+				if (MCS7 && (Rssi > (-72+RssiOffset)))
+					TxRateIdx = MCS7;
+				else if (MCS6 && (Rssi > (-74+RssiOffset)))
+					TxRateIdx = MCS6;
+				else if (MCS5 && (Rssi > (-77+RssiOffset)))
+					TxRateIdx = MCS5;
+				else if (MCS4 && (Rssi > (-79+RssiOffset)))
+					TxRateIdx = MCS4;
+				else if (MCS3 && (Rssi > (-81+RssiOffset)))
+					TxRateIdx = MCS3;
+				else if (MCS2 && (Rssi > (-83+RssiOffset)))
+					TxRateIdx = MCS2;
+				else if (MCS1 && (Rssi > (-86+RssiOffset)))
+					TxRateIdx = MCS1;
+				else
+					TxRateIdx = MCS0;
+			}
+			else
+#endif // DOT11_N_SUPPORT //
+			{// Legacy mode
+				if (MCS7 && (Rssi > -70))
+					TxRateIdx = MCS7;
+				else if (MCS6 && (Rssi > -74))
+					TxRateIdx = MCS6;
+				else if (MCS5 && (Rssi > -78))
+					TxRateIdx = MCS5;
+				else if (MCS4 && (Rssi > -82))
+					TxRateIdx = MCS4;
+				else if (MCS4 == 0)	// for B-only mode
+					TxRateIdx = MCS3;
+				else if (MCS3 && (Rssi > -85))
+					TxRateIdx = MCS3;
+				else if (MCS2 && (Rssi > -87))
+					TxRateIdx = MCS2;
+				else if (MCS1 && (Rssi > -90))
+					TxRateIdx = MCS1;
+				else
+					TxRateIdx = MCS0;
+			}
+
+	//		if (TxRateIdx != pAd->CommonCfg.TxRateIndex)
+			{
+				pEntry->CurrTxRateIndex = TxRateIdx;
+				pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
+				MlmeSetTxRate(pAd, pEntry, pNextTxRate);
+			}
+
+			NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
+			NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
+			pEntry->fLastSecAccordingRSSI = TRUE;
+			// reset all OneSecTx counters
+			RESET_ONE_SEC_TX_CNT(pEntry);
+
+			continue;
+		}
+
+		if (pEntry->fLastSecAccordingRSSI == TRUE)
+		{
+			pEntry->fLastSecAccordingRSSI = FALSE;
+			pEntry->LastSecTxRateChangeAction = 0;
+			// reset all OneSecTx counters
+			RESET_ONE_SEC_TX_CNT(pEntry);
+
+			continue;
+		}
+
+		do
+		{
+			BOOLEAN	bTrainUpDown = FALSE;
+
+			pEntry->CurrTxRateStableTime ++;
+
+			// downgrade TX quality if PER >= Rate-Down threshold
+			if (TxErrorRatio >= TrainDown)
+			{
+				bTrainUpDown = TRUE;
+				pEntry->TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
+			}
+			// upgrade TX quality if PER <= Rate-Up threshold
+			else if (TxErrorRatio <= TrainUp)
+			{
+				bTrainUpDown = TRUE;
+				bUpgradeQuality = TRUE;
+				if (pEntry->TxQuality[CurrRateIdx])
+					pEntry->TxQuality[CurrRateIdx] --;  // quality very good in CurrRate
+
+				if (pEntry->TxRateUpPenalty)
+					pEntry->TxRateUpPenalty --;
+				else if (pEntry->TxQuality[UpRateIdx])
+					pEntry->TxQuality[UpRateIdx] --;    // may improve next UP rate's quality
+			}
+
+			pEntry->PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
+
+			if (bTrainUpDown)
+			{
+				// perform DRS - consider TxRate Down first, then rate up.
+				if ((CurrRateIdx != DownRateIdx) && (pEntry->TxQuality[CurrRateIdx] >= DRS_TX_QUALITY_WORST_BOUND))
+				{
+					pEntry->CurrTxRateIndex = DownRateIdx;
+				}
+				else if ((CurrRateIdx != UpRateIdx) && (pEntry->TxQuality[UpRateIdx] <= 0))
+				{
+					pEntry->CurrTxRateIndex = UpRateIdx;
+				}
+			}
+		} while (FALSE);
+
+		// if rate-up happen, clear all bad history of all TX rates
+		if (pEntry->CurrTxRateIndex > CurrRateIdx)
+		{
+			pEntry->CurrTxRateStableTime = 0;
+			pEntry->TxRateUpPenalty = 0;
+			pEntry->LastSecTxRateChangeAction = 1; // rate UP
+			NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
+			NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
+
+			//
+			// For TxRate fast train up
+			//
+			if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning)
+			{
+				RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
+
+				pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE;
+			}
+			bTxRateChanged = TRUE;
+		}
+		// if rate-down happen, only clear DownRate's bad history
+		else if (pEntry->CurrTxRateIndex < CurrRateIdx)
+		{
+			pEntry->CurrTxRateStableTime = 0;
+			pEntry->TxRateUpPenalty = 0;           // no penalty
+			pEntry->LastSecTxRateChangeAction = 2; // rate DOWN
+			pEntry->TxQuality[pEntry->CurrTxRateIndex] = 0;
+			pEntry->PER[pEntry->CurrTxRateIndex] = 0;
+
+			//
+			// For TxRate fast train down
+			//
+			if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning)
+			{
+				RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
+
+				pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE;
+			}
+			bTxRateChanged = TRUE;
+		}
+		else
+		{
+			pEntry->LastSecTxRateChangeAction = 0; // rate no change
+			bTxRateChanged = FALSE;
+		}
+
+		pEntry->LastTxOkCount = TxSuccess;
+
+		// reset all OneSecTx counters
+		RESET_ONE_SEC_TX_CNT(pEntry);
+
+		pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
+		if (bTxRateChanged && pNextTxRate)
+		{
+			MlmeSetTxRate(pAd, pEntry, pNextTxRate);
+		}
+	}
+}
+
+/*
+	========================================================================
+	Routine Description:
+		Station side, Auto TxRate faster train up timer call back function.
+
+	Arguments:
+		SystemSpecific1			- Not used.
+		FunctionContext			- Pointer to our Adapter context.
+		SystemSpecific2			- Not used.
+		SystemSpecific3			- Not used.
+
+	Return Value:
+		None
+
+	========================================================================
+*/
+VOID StaQuickResponeForRateUpExec(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3)
+{
+	PRTMP_ADAPTER			pAd = (PRTMP_ADAPTER)FunctionContext;
+	UCHAR					UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0;
+	ULONG					TxTotalCnt;
+	ULONG					TxErrorRatio = 0;
+	BOOLEAN					bTxRateChanged; //, bUpgradeQuality = FALSE;
+	PRTMP_TX_RATE_SWITCH	pCurrTxRate, pNextTxRate = NULL;
+	PUCHAR					pTable;
+	UCHAR					TableSize = 0;
+	UCHAR					InitTxRateIdx = 0, TrainUp, TrainDown;
+	TX_STA_CNT1_STRUC		StaTx1;
+	TX_STA_CNT0_STRUC		TxStaCnt0;
+	CHAR					Rssi, ratio;
+	ULONG					TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
+	MAC_TABLE_ENTRY			*pEntry;
+	ULONG					i;
+
+	pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
+
+    //
+    // walk through MAC table, see if need to change AP's TX rate toward each entry
+    //
+	for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
+	{
+		pEntry = &pAd->MacTab.Content[i];
+
+		// check if this entry need to switch rate automatically
+		if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
+			continue;
+
+		if (INFRA_ON(pAd) && (i == 1))
+			Rssi = RTMPMaxRssi(pAd,
+							   pAd->StaCfg.RssiSample.AvgRssi0,
+							   pAd->StaCfg.RssiSample.AvgRssi1,
+							   pAd->StaCfg.RssiSample.AvgRssi2);
+		else
+			Rssi = RTMPMaxRssi(pAd,
+							   pEntry->RssiSample.AvgRssi0,
+							   pEntry->RssiSample.AvgRssi1,
+							   pEntry->RssiSample.AvgRssi2);
+
+		CurrRateIdx = pAd->CommonCfg.TxRateIndex;
+
+			MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
+
+		// decide the next upgrade rate and downgrade rate, if any
+		if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
+		{
+			UpRateIdx = CurrRateIdx + 1;
+			DownRateIdx = CurrRateIdx -1;
+		}
+		else if (CurrRateIdx == 0)
+		{
+			UpRateIdx = CurrRateIdx + 1;
+			DownRateIdx = CurrRateIdx;
+		}
+		else if (CurrRateIdx == (TableSize - 1))
+		{
+			UpRateIdx = CurrRateIdx;
+			DownRateIdx = CurrRateIdx - 1;
+		}
+
+		pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
+
+#ifdef DOT11_N_SUPPORT
+		if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
+		{
+			TrainUp		= (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
+			TrainDown	= (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
+		}
+		else
+#endif // DOT11_N_SUPPORT //
+		{
+			TrainUp		= pCurrTxRate->TrainUp;
+			TrainDown	= pCurrTxRate->TrainDown;
+		}
+
+		if (pAd->MacTab.Size == 1)
+		{
+			// Update statistic counter
+			RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
+			RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
+
+			TxRetransmit = StaTx1.field.TxRetransmit;
+			TxSuccess = StaTx1.field.TxSuccess;
+			TxFailCount = TxStaCnt0.field.TxFailCount;
+			TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
+
+			pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
+			pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
+			pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
+			pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
+			pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
+			pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
+
+			if (TxTotalCnt)
+				TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
+		}
+		else
+		{
+			TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
+				 pEntry->OneSecTxRetryOkCount +
+				 pEntry->OneSecTxFailCount;
+
+			if (TxTotalCnt)
+				TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
+		}
+
+
+		//
+		// CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
+		//         (criteria copied from RT2500 for Netopia case)
+		//
+		if (TxTotalCnt <= 12)
+		{
+			NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
+			NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
+
+			if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
+			{
+				pAd->CommonCfg.TxRateIndex = DownRateIdx;
+				pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
+			}
+			else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx))
+			{
+				pAd->CommonCfg.TxRateIndex = UpRateIdx;
+			}
+
+			DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: TxTotalCnt <= 15, train back to original rate \n"));
+			return;
+		}
+
+		do
+		{
+			ULONG OneSecTxNoRetryOKRationCount;
+
+			if (pAd->DrsCounters.LastTimeTxRateChangeAction == 0)
+				ratio = 5;
+			else
+				ratio = 4;
+
+			// downgrade TX quality if PER >= Rate-Down threshold
+			if (TxErrorRatio >= TrainDown)
+			{
+				pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
+			}
+
+			pAd->DrsCounters.PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
+
+			OneSecTxNoRetryOKRationCount = (TxSuccess * ratio);
+
+			// perform DRS - consider TxRate Down first, then rate up.
+			if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
+			{
+				if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
+				{
+					pAd->CommonCfg.TxRateIndex = DownRateIdx;
+					pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
+
+				}
+
+			}
+			else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx))
+			{
+				if ((TxErrorRatio >= 50) || (TxErrorRatio >= TrainDown))
+				{
+
+				}
+				else if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
+				{
+					pAd->CommonCfg.TxRateIndex = UpRateIdx;
+				}
+			}
+		}while (FALSE);
+
+		// if rate-up happen, clear all bad history of all TX rates
+		if (pAd->CommonCfg.TxRateIndex > CurrRateIdx)
+		{
+			pAd->DrsCounters.TxRateUpPenalty = 0;
+			NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
+			NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
+			bTxRateChanged = TRUE;
+		}
+		// if rate-down happen, only clear DownRate's bad history
+		else if (pAd->CommonCfg.TxRateIndex < CurrRateIdx)
+		{
+			DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: --TX rate from %d to %d \n", CurrRateIdx, pAd->CommonCfg.TxRateIndex));
+
+			pAd->DrsCounters.TxRateUpPenalty = 0;           // no penalty
+			pAd->DrsCounters.TxQuality[pAd->CommonCfg.TxRateIndex] = 0;
+			pAd->DrsCounters.PER[pAd->CommonCfg.TxRateIndex] = 0;
+			bTxRateChanged = TRUE;
+		}
+		else
+		{
+			bTxRateChanged = FALSE;
+		}
+
+		pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pAd->CommonCfg.TxRateIndex+1)*5];
+		if (bTxRateChanged && pNextTxRate)
+		{
+			MlmeSetTxRate(pAd, pEntry, pNextTxRate);
+		}
+	}
+}
+
+/*
+	==========================================================================
+	Description:
+		This routine is executed periodically inside MlmePeriodicExec() after
+		association with an AP.
+		It checks if StaCfg.Psm is consistent with user policy (recorded in
+		StaCfg.WindowsPowerMode). If not, enforce user policy. However,
+		there're some conditions to consider:
+		1. we don't support power-saving in ADHOC mode, so Psm=PWR_ACTIVE all
+		   the time when Mibss==TRUE
+		2. When link up in INFRA mode, Psm should not be switch to PWR_SAVE
+		   if outgoing traffic available in TxRing or MgmtRing.
+	Output:
+		1. change pAd->StaCfg.Psm to PWR_SAVE or leave it untouched
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID MlmeCheckPsmChange(
+	IN PRTMP_ADAPTER pAd,
+	IN ULONG	Now32)
+{
+	ULONG	PowerMode;
+
+	// condition -
+	// 1. Psm maybe ON only happen in INFRASTRUCTURE mode
+	// 2. user wants either MAX_PSP or FAST_PSP
+	// 3. but current psm is not in PWR_SAVE
+	// 4. CNTL state machine is not doing SCANning
+	// 5. no TX SUCCESS event for the past 1-sec period
+#ifdef NDIS51_MINIPORT
+	if (pAd->StaCfg.WindowsPowerProfile == NdisPowerProfileBattery)
+		PowerMode = pAd->StaCfg.WindowsBatteryPowerMode;
+	else
+#endif
+		PowerMode = pAd->StaCfg.WindowsPowerMode;
+
+	if (INFRA_ON(pAd) &&
+		(PowerMode != Ndis802_11PowerModeCAM) &&
+		(pAd->StaCfg.Psm == PWR_ACTIVE) &&
+//		(! RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+		(pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) /*&&
+		(pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&
+		(pAd->RalinkCounters.OneSecTxRetryOkCount == 0)*/)
+	{
+		// add by johnli, use Rx OK data count per second to calculate throughput
+		// If Ttraffic is too high ( > 400 Rx per second), don't go to sleep mode. If tx rate is low, use low criteria
+		// Mode=CCK/MCS=3 => 11 Mbps, Mode=OFDM/MCS=3 => 18 Mbps
+		if (((pAd->StaCfg.HTPhyMode.field.MCS <= 3) &&
+/* Iverson mark
+				(pAd->StaCfg.HTPhyMode.field.MODE <= MODE_OFDM) &&
+*/
+				(pAd->RalinkCounters.OneSecRxOkDataCnt < (ULONG)100)) ||
+			((pAd->StaCfg.HTPhyMode.field.MCS > 3) &&
+/* Iverson mark
+			(pAd->StaCfg.HTPhyMode.field.MODE > MODE_OFDM) &&
+*/
+			(pAd->RalinkCounters.OneSecRxOkDataCnt < (ULONG)400)))
+		{
+				// Get this time
+			NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime);
+			pAd->RalinkCounters.RxCountSinceLastNULL = 0;
+			MlmeSetPsmBit(pAd, PWR_SAVE);
+			if (!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
+			{
+				RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
+			}
+			else
+			{
+				RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
+			}
+		}
+	}
+}
+
+// IRQL = PASSIVE_LEVEL
+// IRQL = DISPATCH_LEVEL
+VOID MlmeSetPsmBit(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT psm)
+{
+	AUTO_RSP_CFG_STRUC csr4;
+
+	pAd->StaCfg.Psm = psm;
+	RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
+	csr4.field.AckCtsPsmBit = (psm == PWR_SAVE)? 1:0;
+	RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+// IRQL = DISPATCH_LEVEL
+VOID MlmeSetTxPreamble(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT TxPreamble)
+{
+	AUTO_RSP_CFG_STRUC csr4;
+
+	//
+	// Always use Long preamble before verifiation short preamble functionality works well.
+	// Todo: remove the following line if short preamble functionality works
+	//
+	//TxPreamble = Rt802_11PreambleLong;
+
+	RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
+	if (TxPreamble == Rt802_11PreambleLong)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= LONG PREAMBLE)\n"));
+		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
+		csr4.field.AutoResponderPreamble = 0;
+	}
+	else
+	{
+		// NOTE: 1Mbps should always use long preamble
+		DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= SHORT PREAMBLE)\n"));
+		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
+		csr4.field.AutoResponderPreamble = 1;
+	}
+
+	RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
+}
+
+/*
+    ==========================================================================
+    Description:
+        Update basic rate bitmap
+    ==========================================================================
+ */
+
+VOID UpdateBasicRateBitmap(
+    IN  PRTMP_ADAPTER   pAdapter)
+{
+    INT  i, j;
+                  /* 1  2  5.5, 11,  6,  9, 12, 18, 24, 36, 48,  54 */
+    UCHAR rate[] = { 2, 4,  11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
+    UCHAR *sup_p = pAdapter->CommonCfg.SupRate;
+    UCHAR *ext_p = pAdapter->CommonCfg.ExtRate;
+    ULONG bitmap = pAdapter->CommonCfg.BasicRateBitmap;
+
+
+    /* if A mode, always use fix BasicRateBitMap */
+    //if (pAdapter->CommonCfg.Channel == PHY_11A)
+	if (pAdapter->CommonCfg.Channel > 14)
+        pAdapter->CommonCfg.BasicRateBitmap = 0x150; /* 6, 12, 24M */
+    /* End of if */
+
+    if (pAdapter->CommonCfg.BasicRateBitmap > 4095)
+    {
+        /* (2 ^ MAX_LEN_OF_SUPPORTED_RATES) -1 */
+        return;
+    } /* End of if */
+
+    for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
+    {
+        sup_p[i] &= 0x7f;
+        ext_p[i] &= 0x7f;
+    } /* End of for */
+
+    for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
+    {
+        if (bitmap & (1 << i))
+        {
+            for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
+            {
+                if (sup_p[j] == rate[i])
+                    sup_p[j] |= 0x80;
+                /* End of if */
+            } /* End of for */
+
+            for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
+            {
+                if (ext_p[j] == rate[i])
+                    ext_p[j] |= 0x80;
+                /* End of if */
+            } /* End of for */
+        } /* End of if */
+    } /* End of for */
+} /* End of UpdateBasicRateBitmap */
+
+// IRQL = PASSIVE_LEVEL
+// IRQL = DISPATCH_LEVEL
+// bLinkUp is to identify the inital link speed.
+// TRUE indicates the rate update at linkup, we should not try to set the rate at 54Mbps.
+VOID MlmeUpdateTxRates(
+	IN PRTMP_ADAPTER 		pAd,
+	IN 	BOOLEAN		 		bLinkUp,
+	IN	UCHAR				apidx)
+{
+	int i, num;
+	UCHAR Rate = RATE_6, MaxDesire = RATE_1, MaxSupport = RATE_1;
+	UCHAR MinSupport = RATE_54;
+	ULONG BasicRateBitmap = 0;
+	UCHAR CurrBasicRate = RATE_1;
+	UCHAR *pSupRate, SupRateLen, *pExtRate, ExtRateLen;
+	PHTTRANSMIT_SETTING		pHtPhy = NULL;
+	PHTTRANSMIT_SETTING		pMaxHtPhy = NULL;
+	PHTTRANSMIT_SETTING		pMinHtPhy = NULL;
+	BOOLEAN 				*auto_rate_cur_p;
+	UCHAR					HtMcs = MCS_AUTO;
+
+	// find max desired rate
+	UpdateBasicRateBitmap(pAd);
+
+	num = 0;
+	auto_rate_cur_p = NULL;
+	for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
+	{
+		switch (pAd->CommonCfg.DesireRate[i] & 0x7f)
+		{
+			case 2:  Rate = RATE_1;   num++;   break;
+			case 4:  Rate = RATE_2;   num++;   break;
+			case 11: Rate = RATE_5_5; num++;   break;
+			case 22: Rate = RATE_11;  num++;   break;
+			case 12: Rate = RATE_6;   num++;   break;
+			case 18: Rate = RATE_9;   num++;   break;
+			case 24: Rate = RATE_12;  num++;   break;
+			case 36: Rate = RATE_18;  num++;   break;
+			case 48: Rate = RATE_24;  num++;   break;
+			case 72: Rate = RATE_36;  num++;   break;
+			case 96: Rate = RATE_48;  num++;   break;
+			case 108: Rate = RATE_54; num++;   break;
+			//default: Rate = RATE_1;   break;
+		}
+		if (MaxDesire < Rate)  MaxDesire = Rate;
+	}
+
+//===========================================================================
+//===========================================================================
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		pHtPhy 		= &pAd->StaCfg.HTPhyMode;
+		pMaxHtPhy	= &pAd->StaCfg.MaxHTPhyMode;
+		pMinHtPhy	= &pAd->StaCfg.MinHTPhyMode;
+
+		auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
+		HtMcs 		= pAd->StaCfg.DesiredTransmitSetting.field.MCS;
+
+		if ((pAd->StaCfg.BssType == BSS_ADHOC) &&
+			(pAd->CommonCfg.PhyMode == PHY_11B) &&
+			(MaxDesire > RATE_11))
+		{
+			MaxDesire = RATE_11;
+		}
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	pAd->CommonCfg.MaxDesiredRate = MaxDesire;
+	pMinHtPhy->word = 0;
+	pMaxHtPhy->word = 0;
+	pHtPhy->word = 0;
+
+	// Auto rate switching is enabled only if more than one DESIRED RATES are
+	// specified; otherwise disabled
+	if (num <= 1)
+	{
+		//OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
+		//pAd->CommonCfg.bAutoTxRateSwitch	= FALSE;
+		*auto_rate_cur_p = FALSE;
+	}
+	else
+	{
+		//OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
+		//pAd->CommonCfg.bAutoTxRateSwitch	= TRUE;
+		*auto_rate_cur_p = TRUE;
+	}
+
+#if 1
+	if (HtMcs != MCS_AUTO)
+	{
+		//OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
+		//pAd->CommonCfg.bAutoTxRateSwitch	= FALSE;
+		*auto_rate_cur_p = FALSE;
+	}
+	else
+	{
+		//OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
+		//pAd->CommonCfg.bAutoTxRateSwitch	= TRUE;
+		*auto_rate_cur_p = TRUE;
+	}
+#endif
+
+#ifdef CONFIG_STA_SUPPORT
+	if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
+	{
+		pSupRate = &pAd->StaActive.SupRate[0];
+		pExtRate = &pAd->StaActive.ExtRate[0];
+		SupRateLen = pAd->StaActive.SupRateLen;
+		ExtRateLen = pAd->StaActive.ExtRateLen;
+	}
+	else
+#endif // CONFIG_STA_SUPPORT //
+	{
+		pSupRate = &pAd->CommonCfg.SupRate[0];
+		pExtRate = &pAd->CommonCfg.ExtRate[0];
+		SupRateLen = pAd->CommonCfg.SupRateLen;
+		ExtRateLen = pAd->CommonCfg.ExtRateLen;
+	}
+
+	// find max supported rate
+	for (i=0; i<SupRateLen; i++)
+	{
+		switch (pSupRate[i] & 0x7f)
+		{
+			case 2:   Rate = RATE_1;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0001;	 break;
+			case 4:   Rate = RATE_2;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0002;	 break;
+			case 11:  Rate = RATE_5_5;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0004;	 break;
+			case 22:  Rate = RATE_11;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0008;	 break;
+			case 12:  Rate = RATE_6;	/*if (pSupRate[i] & 0x80)*/  BasicRateBitmap |= 0x0010;  break;
+			case 18:  Rate = RATE_9;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0020;	 break;
+			case 24:  Rate = RATE_12;	/*if (pSupRate[i] & 0x80)*/  BasicRateBitmap |= 0x0040;  break;
+			case 36:  Rate = RATE_18;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0080;	 break;
+			case 48:  Rate = RATE_24;	/*if (pSupRate[i] & 0x80)*/  BasicRateBitmap |= 0x0100;  break;
+			case 72:  Rate = RATE_36;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0200;	 break;
+			case 96:  Rate = RATE_48;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0400;	 break;
+			case 108: Rate = RATE_54;	if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0800;	 break;
+			default:  Rate = RATE_1;	break;
+		}
+		if (MaxSupport < Rate)	MaxSupport = Rate;
+
+		if (MinSupport > Rate) MinSupport = Rate;
+	}
+
+	for (i=0; i<ExtRateLen; i++)
+	{
+		switch (pExtRate[i] & 0x7f)
+		{
+			case 2:   Rate = RATE_1;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0001;	 break;
+			case 4:   Rate = RATE_2;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0002;	 break;
+			case 11:  Rate = RATE_5_5;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0004;	 break;
+			case 22:  Rate = RATE_11;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0008;	 break;
+			case 12:  Rate = RATE_6;	/*if (pExtRate[i] & 0x80)*/  BasicRateBitmap |= 0x0010;  break;
+			case 18:  Rate = RATE_9;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0020;	 break;
+			case 24:  Rate = RATE_12;	/*if (pExtRate[i] & 0x80)*/  BasicRateBitmap |= 0x0040;  break;
+			case 36:  Rate = RATE_18;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0080;	 break;
+			case 48:  Rate = RATE_24;	/*if (pExtRate[i] & 0x80)*/  BasicRateBitmap |= 0x0100;  break;
+			case 72:  Rate = RATE_36;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0200;	 break;
+			case 96:  Rate = RATE_48;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0400;	 break;
+			case 108: Rate = RATE_54;	if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0800;	 break;
+			default:  Rate = RATE_1;	break;
+		}
+		if (MaxSupport < Rate)	MaxSupport = Rate;
+
+		if (MinSupport > Rate) MinSupport = Rate;
+	}
+
+	RTMP_IO_WRITE32(pAd, LEGACY_BASIC_RATE, BasicRateBitmap);
+
+	// calculate the exptected ACK rate for each TX rate. This info is used to caculate
+	// the DURATION field of outgoing uniicast DATA/MGMT frame
+	for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
+	{
+		if (BasicRateBitmap & (0x01 << i))
+			CurrBasicRate = (UCHAR)i;
+		pAd->CommonCfg.ExpectedACKRate[i] = CurrBasicRate;
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateTxRates[MaxSupport = %d] = MaxDesire %d Mbps\n", RateIdToMbps[MaxSupport], RateIdToMbps[MaxDesire]));
+	// max tx rate = min {max desire rate, max supported rate}
+	if (MaxSupport < MaxDesire)
+		pAd->CommonCfg.MaxTxRate = MaxSupport;
+	else
+		pAd->CommonCfg.MaxTxRate = MaxDesire;
+
+	pAd->CommonCfg.MinTxRate = MinSupport;
+	// 2003-07-31 john - 2500 doesn't have good sensitivity at high OFDM rates. to increase the success
+	// ratio of initial DHCP packet exchange, TX rate starts from a lower rate depending
+	// on average RSSI
+	//	 1. RSSI >= -70db, start at 54 Mbps (short distance)
+	//	 2. -70 > RSSI >= -75, start at 24 Mbps (mid distance)
+	//	 3. -75 > RSSI, start at 11 Mbps (long distance)
+	//if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)/* &&
+	//	OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)*/)
+	if (*auto_rate_cur_p)
+	{
+		short dbm = 0;
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+			dbm = pAd->StaCfg.RssiSample.AvgRssi0 - pAd->BbpRssiToDbmDelta;
+#endif // CONFIG_STA_SUPPORT //
+		if (bLinkUp == TRUE)
+			pAd->CommonCfg.TxRate = RATE_24;
+		else
+			pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
+
+		if (dbm < -75)
+			pAd->CommonCfg.TxRate = RATE_11;
+		else if (dbm < -70)
+			pAd->CommonCfg.TxRate = RATE_24;
+
+		// should never exceed MaxTxRate (consider 11B-only mode)
+		if (pAd->CommonCfg.TxRate > pAd->CommonCfg.MaxTxRate)
+			pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
+
+		pAd->CommonCfg.TxRateIndex = 0;
+	}
+	else
+	{
+		pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
+		pHtPhy->field.MCS	= (pAd->CommonCfg.MaxTxRate > 3) ? (pAd->CommonCfg.MaxTxRate - 4) : pAd->CommonCfg.MaxTxRate;
+		pHtPhy->field.MODE	= (pAd->CommonCfg.MaxTxRate > 3) ? MODE_OFDM : MODE_CCK;
+
+		pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC	= pHtPhy->field.STBC;
+		pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI	= pHtPhy->field.ShortGI;
+		pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS		= pHtPhy->field.MCS;
+		pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE	= pHtPhy->field.MODE;
+	}
+
+	if (pAd->CommonCfg.TxRate <= RATE_11)
+	{
+		pMaxHtPhy->field.MODE = MODE_CCK;
+		pMaxHtPhy->field.MCS = pAd->CommonCfg.TxRate;
+		pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;
+	}
+	else
+	{
+		pMaxHtPhy->field.MODE = MODE_OFDM;
+		pMaxHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.TxRate];
+		if (pAd->CommonCfg.MinTxRate >= RATE_6 && (pAd->CommonCfg.MinTxRate <= RATE_54))
+			{pMinHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MinTxRate];}
+		else
+			{pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;}
+	}
+
+	pHtPhy->word = (pMaxHtPhy->word);
+	if (bLinkUp && (pAd->OpMode == OPMODE_STA))
+	{
+			pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word = pHtPhy->word;
+			pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word = pMaxHtPhy->word;
+			pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word = pMinHtPhy->word;
+	}
+	else
+	{
+		switch (pAd->CommonCfg.PhyMode)
+		{
+			case PHY_11BG_MIXED:
+			case PHY_11B:
+#ifdef DOT11_N_SUPPORT
+			case PHY_11BGN_MIXED:
+#endif // DOT11_N_SUPPORT //
+				pAd->CommonCfg.MlmeRate = RATE_1;
+				pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
+				pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
+
+//#ifdef	WIFI_TEST
+				pAd->CommonCfg.RtsRate = RATE_11;
+//#else
+//				pAd->CommonCfg.RtsRate = RATE_1;
+//#endif
+				break;
+			case PHY_11G:
+			case PHY_11A:
+#ifdef DOT11_N_SUPPORT
+			case PHY_11AGN_MIXED:
+			case PHY_11GN_MIXED:
+			case PHY_11N_2_4G:
+			case PHY_11AN_MIXED:
+			case PHY_11N_5G:
+#endif // DOT11_N_SUPPORT //
+				pAd->CommonCfg.MlmeRate = RATE_6;
+				pAd->CommonCfg.RtsRate = RATE_6;
+				pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
+				pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+				break;
+			case PHY_11ABG_MIXED:
+#ifdef DOT11_N_SUPPORT
+			case PHY_11ABGN_MIXED:
+#endif // DOT11_N_SUPPORT //
+				if (pAd->CommonCfg.Channel <= 14)
+				{
+					pAd->CommonCfg.MlmeRate = RATE_1;
+					pAd->CommonCfg.RtsRate = RATE_1;
+					pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
+					pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
+				}
+				else
+				{
+					pAd->CommonCfg.MlmeRate = RATE_6;
+					pAd->CommonCfg.RtsRate = RATE_6;
+					pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
+					pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+				}
+				break;
+			default: // error
+				pAd->CommonCfg.MlmeRate = RATE_6;
+                        	pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
+				pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+				pAd->CommonCfg.RtsRate = RATE_1;
+				break;
+		}
+		//
+		// Keep Basic Mlme Rate.
+		//
+		pAd->MacTab.Content[MCAST_WCID].HTPhyMode.word = pAd->CommonCfg.MlmeTransmit.word;
+		if (pAd->CommonCfg.MlmeTransmit.field.MODE == MODE_OFDM)
+			pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[RATE_24];
+		else
+			pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = RATE_1;
+		pAd->CommonCfg.BasicMlmeRate = pAd->CommonCfg.MlmeRate;
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (MaxDesire=%d, MaxSupport=%d, MaxTxRate=%d, MinRate=%d, Rate Switching =%d)\n",
+			 RateIdToMbps[MaxDesire], RateIdToMbps[MaxSupport], RateIdToMbps[pAd->CommonCfg.MaxTxRate], RateIdToMbps[pAd->CommonCfg.MinTxRate],
+			 /*OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)*/*auto_rate_cur_p));
+	DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (TxRate=%d, RtsRate=%d, BasicRateBitmap=0x%04lx)\n",
+			 RateIdToMbps[pAd->CommonCfg.TxRate], RateIdToMbps[pAd->CommonCfg.RtsRate], BasicRateBitmap));
+	DBGPRINT(RT_DEBUG_TRACE, ("MlmeUpdateTxRates (MlmeTransmit=0x%x, MinHTPhyMode=%x, MaxHTPhyMode=0x%x, HTPhyMode=0x%x)\n",
+			 pAd->CommonCfg.MlmeTransmit.word, pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word ,pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word ,pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word ));
+}
+
+#ifdef DOT11_N_SUPPORT
+/*
+	==========================================================================
+	Description:
+		This function update HT Rate setting.
+		Input Wcid value is valid for 2 case :
+		1. it's used for Station in infra mode that copy AP rate to Mactable.
+		2. OR Station 	in adhoc mode to copy peer's HT rate to Mactable.
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID MlmeUpdateHtTxRates(
+	IN PRTMP_ADAPTER 		pAd,
+	IN	UCHAR				apidx)
+{
+	UCHAR	StbcMcs; //j, StbcMcs, bitmask;
+	CHAR 	i; // 3*3
+	RT_HT_CAPABILITY 	*pRtHtCap = NULL;
+	RT_HT_PHY_INFO		*pActiveHtPhy = NULL;
+	ULONG		BasicMCS;
+	UCHAR j, bitmask;
+	PRT_HT_PHY_INFO			pDesireHtPhy = NULL;
+	PHTTRANSMIT_SETTING		pHtPhy = NULL;
+	PHTTRANSMIT_SETTING		pMaxHtPhy = NULL;
+	PHTTRANSMIT_SETTING		pMinHtPhy = NULL;
+	BOOLEAN 				*auto_rate_cur_p;
+
+	DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates===> \n"));
+
+	auto_rate_cur_p = NULL;
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		pDesireHtPhy	= &pAd->StaCfg.DesiredHtPhyInfo;
+		pActiveHtPhy	= &pAd->StaCfg.DesiredHtPhyInfo;
+		pHtPhy 		= &pAd->StaCfg.HTPhyMode;
+		pMaxHtPhy	= &pAd->StaCfg.MaxHTPhyMode;
+		pMinHtPhy	= &pAd->StaCfg.MinHTPhyMode;
+
+		auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+	if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
+	{
+		if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
+			return;
+
+		pRtHtCap = &pAd->StaActive.SupportedHtPhy;
+		pActiveHtPhy = &pAd->StaActive.SupportedPhyInfo;
+		StbcMcs = (UCHAR)pAd->MlmeAux.AddHtInfo.AddHtInfo3.StbcMcs;
+		BasicMCS =pAd->MlmeAux.AddHtInfo.MCSSet[0]+(pAd->MlmeAux.AddHtInfo.MCSSet[1]<<8)+(StbcMcs<<16);
+		if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2))
+			pMaxHtPhy->field.STBC = STBC_USE;
+		else
+			pMaxHtPhy->field.STBC = STBC_NONE;
+	}
+	else
+#endif // CONFIG_STA_SUPPORT //
+	{
+		if (pDesireHtPhy->bHtEnable == FALSE)
+			return;
+
+		pRtHtCap = &pAd->CommonCfg.DesiredHtPhy;
+		StbcMcs = (UCHAR)pAd->CommonCfg.AddHTInfo.AddHtInfo3.StbcMcs;
+		BasicMCS = pAd->CommonCfg.AddHTInfo.MCSSet[0]+(pAd->CommonCfg.AddHTInfo.MCSSet[1]<<8)+(StbcMcs<<16);
+		if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2))
+			pMaxHtPhy->field.STBC = STBC_USE;
+		else
+			pMaxHtPhy->field.STBC = STBC_NONE;
+	}
+
+	// Decide MAX ht rate.
+	if ((pRtHtCap->GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
+		pMaxHtPhy->field.MODE = MODE_HTGREENFIELD;
+	else
+		pMaxHtPhy->field.MODE = MODE_HTMIX;
+
+    if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth) && (pRtHtCap->ChannelWidth))
+		pMaxHtPhy->field.BW = BW_40;
+	else
+		pMaxHtPhy->field.BW = BW_20;
+
+    if (pMaxHtPhy->field.BW == BW_20)
+		pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 & pRtHtCap->ShortGIfor20);
+	else
+		pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 & pRtHtCap->ShortGIfor40);
+
+	for (i=23; i>=0; i--) // 3*3
+	{
+		j = i/8;
+		bitmask = (1<<(i-(j*8)));
+
+		if ((pActiveHtPhy->MCSSet[j] & bitmask) && (pDesireHtPhy->MCSSet[j] & bitmask))
+		{
+			pMaxHtPhy->field.MCS = i;
+			break;
+		}
+
+		if (i==0)
+			break;
+	}
+
+	// Copy MIN ht rate.  rt2860???
+	pMinHtPhy->field.BW = BW_20;
+	pMinHtPhy->field.MCS = 0;
+	pMinHtPhy->field.STBC = 0;
+	pMinHtPhy->field.ShortGI = 0;
+	//If STA assigns fixed rate. update to fixed here.
+#ifdef CONFIG_STA_SUPPORT
+	if ( (pAd->OpMode == OPMODE_STA) && (pDesireHtPhy->MCSSet[0] != 0xff))
+	{
+		if (pDesireHtPhy->MCSSet[4] != 0)
+		{
+			pMaxHtPhy->field.MCS = 32;
+			pMinHtPhy->field.MCS = 32;
+			DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== Use Fixed MCS = %d\n",pMinHtPhy->field.MCS));
+		}
+
+		for (i=23; (CHAR)i >= 0; i--) // 3*3
+		{
+			j = i/8;
+			bitmask = (1<<(i-(j*8)));
+			if ( (pDesireHtPhy->MCSSet[j] & bitmask) && (pActiveHtPhy->MCSSet[j] & bitmask))
+			{
+				pMaxHtPhy->field.MCS = i;
+				pMinHtPhy->field.MCS = i;
+				break;
+			}
+			if (i==0)
+				break;
+		}
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+
+	// Decide ht rate
+	pHtPhy->field.STBC = pMaxHtPhy->field.STBC;
+	pHtPhy->field.BW = pMaxHtPhy->field.BW;
+	pHtPhy->field.MODE = pMaxHtPhy->field.MODE;
+	pHtPhy->field.MCS = pMaxHtPhy->field.MCS;
+	pHtPhy->field.ShortGI = pMaxHtPhy->field.ShortGI;
+
+	// use default now. rt2860
+	if (pDesireHtPhy->MCSSet[0] != 0xff)
+		*auto_rate_cur_p = FALSE;
+	else
+		*auto_rate_cur_p = TRUE;
+
+	DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateHtTxRates<---.AMsduSize = %d  \n", pAd->CommonCfg.DesiredHtPhy.AmsduSize ));
+	DBGPRINT(RT_DEBUG_TRACE,("TX: MCS[0] = %x (choose %d), BW = %d, ShortGI = %d, MODE = %d,  \n", pActiveHtPhy->MCSSet[0],pHtPhy->field.MCS,
+		pHtPhy->field.BW, pHtPhy->field.ShortGI, pHtPhy->field.MODE));
+	DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== \n"));
+}
+#endif // DOT11_N_SUPPORT //
+
+// IRQL = DISPATCH_LEVEL
+VOID MlmeRadioOff(
+	IN PRTMP_ADAPTER pAd)
+{
+	RT28XX_MLME_RADIO_OFF(pAd);
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID MlmeRadioOn(
+	IN PRTMP_ADAPTER pAd)
+{
+	RT28XX_MLME_RADIO_ON(pAd);
+}
+
+// ===========================================================================================
+// bss_table.c
+// ===========================================================================================
+
+
+/*! \brief initialize BSS table
+ *	\param p_tab pointer to the table
+ *	\return none
+ *	\pre
+ *	\post
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ */
+VOID BssTableInit(
+	IN BSS_TABLE *Tab)
+{
+	int i;
+
+	Tab->BssNr = 0;
+    Tab->BssOverlapNr = 0;
+	for (i = 0; i < MAX_LEN_OF_BSS_TABLE; i++)
+	{
+		NdisZeroMemory(&Tab->BssEntry[i], sizeof(BSS_ENTRY));
+		Tab->BssEntry[i].Rssi = -127;	// initial the rssi as a minimum value
+	}
+}
+
+#ifdef DOT11_N_SUPPORT
+VOID BATableInit(
+	IN PRTMP_ADAPTER pAd,
+    IN BA_TABLE *Tab)
+{
+	int i;
+
+	Tab->numAsOriginator = 0;
+	Tab->numAsRecipient = 0;
+	NdisAllocateSpinLock(&pAd->BATabLock);
+	for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++)
+	{
+		Tab->BARecEntry[i].REC_BA_Status = Recipient_NONE;
+		NdisAllocateSpinLock(&(Tab->BARecEntry[i].RxReRingLock));
+	}
+	for (i = 0; i < MAX_LEN_OF_BA_ORI_TABLE; i++)
+	{
+		Tab->BAOriEntry[i].ORI_BA_Status = Originator_NONE;
+	}
+}
+#endif // DOT11_N_SUPPORT //
+
+/*! \brief search the BSS table by SSID
+ *	\param p_tab pointer to the bss table
+ *	\param ssid SSID string
+ *	\return index of the table, BSS_NOT_FOUND if not in the table
+ *	\pre
+ *	\post
+ *	\note search by sequential search
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+ULONG BssTableSearch(
+	IN BSS_TABLE *Tab,
+	IN PUCHAR	 pBssid,
+	IN UCHAR	 Channel)
+{
+	UCHAR i;
+
+	for (i = 0; i < Tab->BssNr; i++)
+	{
+		//
+		// Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
+		// We should distinguish this case.
+		//
+		if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
+			 ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
+			MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid))
+		{
+			return i;
+		}
+	}
+	return (ULONG)BSS_NOT_FOUND;
+}
+
+ULONG BssSsidTableSearch(
+	IN BSS_TABLE *Tab,
+	IN PUCHAR	 pBssid,
+	IN PUCHAR	 pSsid,
+	IN UCHAR	 SsidLen,
+	IN UCHAR	 Channel)
+{
+	UCHAR i;
+
+	for (i = 0; i < Tab->BssNr; i++)
+	{
+		//
+		// Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
+		// We should distinguish this case.
+		//
+		if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
+			 ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
+			MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid) &&
+			SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen))
+		{
+			return i;
+		}
+	}
+	return (ULONG)BSS_NOT_FOUND;
+}
+
+ULONG BssTableSearchWithSSID(
+	IN BSS_TABLE *Tab,
+	IN PUCHAR	 Bssid,
+	IN PUCHAR	 pSsid,
+	IN UCHAR	 SsidLen,
+	IN UCHAR	 Channel)
+{
+	UCHAR i;
+
+	for (i = 0; i < Tab->BssNr; i++)
+	{
+		if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
+			((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
+			MAC_ADDR_EQUAL(&(Tab->BssEntry[i].Bssid), Bssid) &&
+			(SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen) ||
+			(NdisEqualMemory(pSsid, ZeroSsid, SsidLen)) ||
+			(NdisEqualMemory(Tab->BssEntry[i].Ssid, ZeroSsid, Tab->BssEntry[i].SsidLen))))
+		{
+			return i;
+		}
+	}
+	return (ULONG)BSS_NOT_FOUND;
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID BssTableDeleteEntry(
+	IN OUT	BSS_TABLE *Tab,
+	IN		PUCHAR	  pBssid,
+	IN		UCHAR	  Channel)
+{
+	UCHAR i, j;
+
+	for (i = 0; i < Tab->BssNr; i++)
+	{
+		if ((Tab->BssEntry[i].Channel == Channel) &&
+			(MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid)))
+		{
+			for (j = i; j < Tab->BssNr - 1; j++)
+			{
+				NdisMoveMemory(&(Tab->BssEntry[j]), &(Tab->BssEntry[j + 1]), sizeof(BSS_ENTRY));
+			}
+			NdisZeroMemory(&(Tab->BssEntry[Tab->BssNr - 1]), sizeof(BSS_ENTRY));
+			Tab->BssNr -= 1;
+			return;
+		}
+	}
+}
+
+#ifdef DOT11_N_SUPPORT
+/*
+	========================================================================
+	Routine Description:
+		Delete the Originator Entry in BAtable. Or decrease numAs Originator by 1 if needed.
+
+	Arguments:
+	// IRQL = DISPATCH_LEVEL
+	========================================================================
+*/
+VOID BATableDeleteORIEntry(
+	IN OUT	PRTMP_ADAPTER pAd,
+	IN		BA_ORI_ENTRY	*pBAORIEntry)
+{
+
+	if (pBAORIEntry->ORI_BA_Status != Originator_NONE)
+	{
+		NdisAcquireSpinLock(&pAd->BATabLock);
+		if (pBAORIEntry->ORI_BA_Status == Originator_Done)
+		{
+			pAd->BATable.numAsOriginator -= 1;
+			DBGPRINT(RT_DEBUG_TRACE, ("BATableDeleteORIEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient));
+			// Erase Bitmap flag.
+		}
+		pAd->MacTab.Content[pBAORIEntry->Wcid].TXBAbitmap &= (~(1<<(pBAORIEntry->TID) ));	// If STA mode,  erase flag here
+		pAd->MacTab.Content[pBAORIEntry->Wcid].BAOriWcidArray[pBAORIEntry->TID] = 0;	// If STA mode,  erase flag here
+		pBAORIEntry->ORI_BA_Status = Originator_NONE;
+		pBAORIEntry->Token = 1;
+		// Not clear Sequence here.
+		NdisReleaseSpinLock(&pAd->BATabLock);
+	}
+}
+#endif // DOT11_N_SUPPORT //
+
+/*! \brief
+ *	\param
+ *	\return
+ *	\pre
+ *	\post
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+VOID BssEntrySet(
+	IN PRTMP_ADAPTER	pAd,
+	OUT BSS_ENTRY *pBss,
+	IN PUCHAR pBssid,
+	IN CHAR Ssid[],
+	IN UCHAR SsidLen,
+	IN UCHAR BssType,
+	IN USHORT BeaconPeriod,
+	IN PCF_PARM pCfParm,
+	IN USHORT AtimWin,
+	IN USHORT CapabilityInfo,
+	IN UCHAR SupRate[],
+	IN UCHAR SupRateLen,
+	IN UCHAR ExtRate[],
+	IN UCHAR ExtRateLen,
+	IN HT_CAPABILITY_IE *pHtCapability,
+	IN ADD_HT_INFO_IE *pAddHtInfo,	// AP might use this additional ht info IE
+	IN UCHAR			HtCapabilityLen,
+	IN UCHAR			AddHtInfoLen,
+	IN UCHAR			NewExtChanOffset,
+	IN UCHAR Channel,
+	IN CHAR Rssi,
+	IN LARGE_INTEGER TimeStamp,
+	IN UCHAR CkipFlag,
+	IN PEDCA_PARM pEdcaParm,
+	IN PQOS_CAPABILITY_PARM pQosCapability,
+	IN PQBSS_LOAD_PARM pQbssLoad,
+	IN USHORT LengthVIE,
+	IN PNDIS_802_11_VARIABLE_IEs pVIE)
+{
+	COPY_MAC_ADDR(pBss->Bssid, pBssid);
+	// Default Hidden SSID to be TRUE, it will be turned to FALSE after coping SSID
+	pBss->Hidden = 1;
+	if (SsidLen > 0)
+	{
+		// For hidden SSID AP, it might send beacon with SSID len equal to 0
+		// Or send beacon /probe response with SSID len matching real SSID length,
+		// but SSID is all zero. such as "00-00-00-00" with length 4.
+		// We have to prevent this case overwrite correct table
+		if (NdisEqualMemory(Ssid, ZeroSsid, SsidLen) == 0)
+		{
+		    NdisZeroMemory(pBss->Ssid, MAX_LEN_OF_SSID);
+			NdisMoveMemory(pBss->Ssid, Ssid, SsidLen);
+			pBss->SsidLen = SsidLen;
+			pBss->Hidden = 0;
+		}
+	}
+	else
+		pBss->SsidLen = 0;
+	pBss->BssType = BssType;
+	pBss->BeaconPeriod = BeaconPeriod;
+	if (BssType == BSS_INFRA)
+	{
+		if (pCfParm->bValid)
+		{
+			pBss->CfpCount = pCfParm->CfpCount;
+			pBss->CfpPeriod = pCfParm->CfpPeriod;
+			pBss->CfpMaxDuration = pCfParm->CfpMaxDuration;
+			pBss->CfpDurRemaining = pCfParm->CfpDurRemaining;
+		}
+	}
+	else
+	{
+		pBss->AtimWin = AtimWin;
+	}
+
+	pBss->CapabilityInfo = CapabilityInfo;
+	// The privacy bit indicate security is ON, it maight be WEP, TKIP or AES
+	// Combine with AuthMode, they will decide the connection methods.
+	pBss->Privacy = CAP_IS_PRIVACY_ON(pBss->CapabilityInfo);
+	ASSERT(SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
+	if (SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES)
+		NdisMoveMemory(pBss->SupRate, SupRate, SupRateLen);
+	else
+		NdisMoveMemory(pBss->SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES);
+	pBss->SupRateLen = SupRateLen;
+	ASSERT(ExtRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
+	NdisMoveMemory(pBss->ExtRate, ExtRate, ExtRateLen);
+	NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen);
+	NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen);
+	pBss->NewExtChanOffset = NewExtChanOffset;
+	pBss->ExtRateLen = ExtRateLen;
+	pBss->Channel = Channel;
+	pBss->CentralChannel = Channel;
+	pBss->Rssi = Rssi;
+	// Update CkipFlag. if not exists, the value is 0x0
+	pBss->CkipFlag = CkipFlag;
+
+	// New for microsoft Fixed IEs
+	NdisMoveMemory(pBss->FixIEs.Timestamp, &TimeStamp, 8);
+	pBss->FixIEs.BeaconInterval = BeaconPeriod;
+	pBss->FixIEs.Capabilities = CapabilityInfo;
+
+	// New for microsoft Variable IEs
+	if (LengthVIE != 0)
+	{
+		pBss->VarIELen = LengthVIE;
+		NdisMoveMemory(pBss->VarIEs, pVIE, pBss->VarIELen);
+	}
+	else
+	{
+		pBss->VarIELen = 0;
+	}
+
+	pBss->AddHtInfoLen = 0;
+	pBss->HtCapabilityLen = 0;
+#ifdef DOT11_N_SUPPORT
+	if (HtCapabilityLen> 0)
+	{
+		pBss->HtCapabilityLen = HtCapabilityLen;
+		NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen);
+		if (AddHtInfoLen > 0)
+		{
+			pBss->AddHtInfoLen = AddHtInfoLen;
+			NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen);
+
+	 			if ((pAddHtInfo->ControlChan > 2)&& (pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
+	 			{
+	 				pBss->CentralChannel = pAddHtInfo->ControlChan - 2;
+	 			}
+	 			else if ((pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
+				{
+		 				pBss->CentralChannel = pAddHtInfo->ControlChan + 2;
+				}
+		}
+	}
+#endif // DOT11_N_SUPPORT //
+
+	BssCipherParse(pBss);
+
+	// new for QOS
+	if (pEdcaParm)
+		NdisMoveMemory(&pBss->EdcaParm, pEdcaParm, sizeof(EDCA_PARM));
+	else
+		pBss->EdcaParm.bValid = FALSE;
+	if (pQosCapability)
+		NdisMoveMemory(&pBss->QosCapability, pQosCapability, sizeof(QOS_CAPABILITY_PARM));
+	else
+		pBss->QosCapability.bValid = FALSE;
+	if (pQbssLoad)
+		NdisMoveMemory(&pBss->QbssLoad, pQbssLoad, sizeof(QBSS_LOAD_PARM));
+	else
+		pBss->QbssLoad.bValid = FALSE;
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		PEID_STRUCT     pEid;
+		USHORT          Length = 0;
+
+
+		NdisZeroMemory(&pBss->WpaIE.IE[0], MAX_CUSTOM_LEN);
+		NdisZeroMemory(&pBss->RsnIE.IE[0], MAX_CUSTOM_LEN);
+#ifdef EXT_BUILD_CHANNEL_LIST
+		NdisZeroMemory(&pBss->CountryString[0], 3);
+		pBss->bHasCountryIE = FALSE;
+#endif // EXT_BUILD_CHANNEL_LIST //
+		pEid = (PEID_STRUCT) pVIE;
+		while ((Length + 2 + (USHORT)pEid->Len) <= LengthVIE)
+		{
+			switch(pEid->Eid)
+			{
+				case IE_WPA:
+					if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
+					{
+						if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
+						{
+							pBss->WpaIE.IELen = 0;
+							break;
+						}
+						pBss->WpaIE.IELen = pEid->Len + 2;
+						NdisMoveMemory(pBss->WpaIE.IE, pEid, pBss->WpaIE.IELen);
+					}
+					break;
+                case IE_RSN:
+                    if (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
+					{
+						if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
+						{
+							pBss->RsnIE.IELen = 0;
+							break;
+						}
+						pBss->RsnIE.IELen = pEid->Len + 2;
+						NdisMoveMemory(pBss->RsnIE.IE, pEid, pBss->RsnIE.IELen);
+			}
+				break;
+#ifdef EXT_BUILD_CHANNEL_LIST
+				case IE_COUNTRY:
+					NdisMoveMemory(&pBss->CountryString[0], pEid->Octet, 3);
+					pBss->bHasCountryIE = TRUE;
+					break;
+#endif // EXT_BUILD_CHANNEL_LIST //
+            }
+			Length = Length + 2 + (USHORT)pEid->Len;  // Eid[1] + Len[1]+ content[Len]
+			pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
+		}
+	}
+#endif // CONFIG_STA_SUPPORT //
+}
+
+/*!
+ *	\brief insert an entry into the bss table
+ *	\param p_tab The BSS table
+ *	\param Bssid BSSID
+ *	\param ssid SSID
+ *	\param ssid_len Length of SSID
+ *	\param bss_type
+ *	\param beacon_period
+ *	\param timestamp
+ *	\param p_cf
+ *	\param atim_win
+ *	\param cap
+ *	\param rates
+ *	\param rates_len
+ *	\param channel_idx
+ *	\return none
+ *	\pre
+ *	\post
+ *	\note If SSID is identical, the old entry will be replaced by the new one
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+ULONG BssTableSetEntry(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT BSS_TABLE *Tab,
+	IN PUCHAR pBssid,
+	IN CHAR Ssid[],
+	IN UCHAR SsidLen,
+	IN UCHAR BssType,
+	IN USHORT BeaconPeriod,
+	IN CF_PARM *CfParm,
+	IN USHORT AtimWin,
+	IN USHORT CapabilityInfo,
+	IN UCHAR SupRate[],
+	IN UCHAR SupRateLen,
+	IN UCHAR ExtRate[],
+	IN UCHAR ExtRateLen,
+	IN HT_CAPABILITY_IE *pHtCapability,
+	IN ADD_HT_INFO_IE *pAddHtInfo,	// AP might use this additional ht info IE
+	IN UCHAR			HtCapabilityLen,
+	IN UCHAR			AddHtInfoLen,
+	IN UCHAR			NewExtChanOffset,
+	IN UCHAR ChannelNo,
+	IN CHAR Rssi,
+	IN LARGE_INTEGER TimeStamp,
+	IN UCHAR CkipFlag,
+	IN PEDCA_PARM pEdcaParm,
+	IN PQOS_CAPABILITY_PARM pQosCapability,
+	IN PQBSS_LOAD_PARM pQbssLoad,
+	IN USHORT LengthVIE,
+	IN PNDIS_802_11_VARIABLE_IEs pVIE)
+{
+	ULONG	Idx;
+
+	Idx = BssTableSearchWithSSID(Tab, pBssid,  Ssid, SsidLen, ChannelNo);
+	if (Idx == BSS_NOT_FOUND)
+	{
+		if (Tab->BssNr >= MAX_LEN_OF_BSS_TABLE)
+	    {
+			//
+			// It may happen when BSS Table was full.
+			// The desired AP will not be added into BSS Table
+			// In this case, if we found the desired AP then overwrite BSS Table.
+			//
+			if(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+			{
+				if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, pBssid) ||
+					SSID_EQUAL(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Ssid, SsidLen))
+				{
+					Idx = Tab->BssOverlapNr;
+					BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
+						CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
+						NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
+                    Tab->BssOverlapNr = (Tab->BssOverlapNr++) % MAX_LEN_OF_BSS_TABLE;
+				}
+				return Idx;
+			}
+			else
+			{
+			return BSS_NOT_FOUND;
+			}
+		}
+		Idx = Tab->BssNr;
+		BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
+					CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
+					NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
+		Tab->BssNr++;
+	}
+	else
+	{
+		/* avoid  Hidden SSID form beacon to overwirite correct SSID from probe response */
+		if ((SSID_EQUAL(Ssid, SsidLen, Tab->BssEntry[Idx].Ssid, Tab->BssEntry[Idx].SsidLen)) ||
+			(NdisEqualMemory(Tab->BssEntry[Idx].Ssid, ZeroSsid, Tab->BssEntry[Idx].SsidLen)))
+		{
+			BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod,CfParm, AtimWin,
+						CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
+						NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
+		}
+	}
+
+	return Idx;
+}
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+VOID  TriEventInit(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	UCHAR		i;
+
+	for (i = 0;i < MAX_TRIGGER_EVENT;i++)
+		pAd->CommonCfg.TriggerEventTab.EventA[i].bValid = FALSE;
+
+	pAd->CommonCfg.TriggerEventTab.EventANo = 0;
+	pAd->CommonCfg.TriggerEventTab.EventBCountDown = 0;
+}
+
+ULONG TriEventTableSetEntry(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT TRIGGER_EVENT_TAB *Tab,
+	IN PUCHAR pBssid,
+	IN HT_CAPABILITY_IE *pHtCapability,
+	IN UCHAR			HtCapabilityLen,
+	IN UCHAR			RegClass,
+	IN UCHAR ChannelNo)
+{
+	// Event A
+	if (HtCapabilityLen == 0)
+	{
+		if (Tab->EventANo < MAX_TRIGGER_EVENT)
+		{
+			RTMPMoveMemory(Tab->EventA[Tab->EventANo].BSSID, pBssid, 6);
+			Tab->EventA[Tab->EventANo].bValid = TRUE;
+			Tab->EventA[Tab->EventANo].Channel = ChannelNo;
+			Tab->EventA[Tab->EventANo].CDCounter = pAd->CommonCfg.Dot11BssWidthChanTranDelay;
+			if (RegClass != 0)
+			{
+				// Beacon has Regulatory class IE. So use beacon's
+				Tab->EventA[Tab->EventANo].RegClass = RegClass;
+			}
+			else
+			{
+				// Use Station's Regulatory class instead.
+				if (pAd->StaActive.SupportedHtPhy.bHtEnable == TRUE)
+				{
+					if (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
+					{
+						Tab->EventA[Tab->EventANo].RegClass = 32;
+					}
+					else if (pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel)
+						Tab->EventA[Tab->EventANo].RegClass = 33;
+				}
+				else
+					Tab->EventA[Tab->EventANo].RegClass = ??;
+
+			}
+
+			Tab->EventANo ++;
+		}
+	}
+	else if (pHtCapability->HtCapInfo.Intolerant40)
+	{
+		Tab->EventBCountDown = pAd->CommonCfg.Dot11BssWidthChanTranDelay;
+	}
+
+}
+
+/*
+	========================================================================
+	Routine Description:
+		Trigger Event table Maintainence called once every second.
+
+	Arguments:
+	// IRQL = DISPATCH_LEVEL
+	========================================================================
+*/
+VOID TriEventCounterMaintenance(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	UCHAR		i;
+	BOOLEAN			bNotify = FALSE;
+	for (i = 0;i < MAX_TRIGGER_EVENT;i++)
+	{
+		if (pAd->CommonCfg.TriggerEventTab.EventA[i].bValid && (pAd->CommonCfg.TriggerEventTab.EventA[i].CDCounter > 0))
+		{
+			pAd->CommonCfg.TriggerEventTab.EventA[i].CDCounter--;
+			if (pAd->CommonCfg.TriggerEventTab.EventA[i].CDCounter == 0)
+			{
+				pAd->CommonCfg.TriggerEventTab.EventA[i].bValid = FALSE;
+				pAd->CommonCfg.TriggerEventTab.EventANo --;
+				// Need to send 20/40 Coexistence Notify frame if has status change.
+				bNotify = TRUE;
+			}
+		}
+	}
+	if (pAd->CommonCfg.TriggerEventTab.EventBCountDown > 0)
+	{
+		pAd->CommonCfg.TriggerEventTab.EventBCountDown--;
+		if (pAd->CommonCfg.TriggerEventTab.EventBCountDown == 0)
+			bNotify = TRUE;
+	}
+
+	if (bNotify == TRUE)
+		Update2040CoexistFrameAndNotify(pAd, BSSID_WCID, TRUE);
+}
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+
+// IRQL = DISPATCH_LEVEL
+VOID BssTableSsidSort(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT BSS_TABLE *OutTab,
+	IN	CHAR Ssid[],
+	IN	UCHAR SsidLen)
+{
+	INT i;
+	BssTableInit(OutTab);
+
+	for (i = 0; i < pAd->ScanTab.BssNr; i++)
+	{
+		BSS_ENTRY *pInBss = &pAd->ScanTab.BssEntry[i];
+		BOOLEAN	bIsHiddenApIncluded = FALSE;
+
+		if (((pAd->CommonCfg.bIEEE80211H == 1) &&
+            (pAd->MlmeAux.Channel > 14) &&
+             RadarChannelCheck(pAd, pInBss->Channel))
+#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
+             || (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
+#endif // CARRIER_DETECTION_SUPPORT //
+            )
+		{
+			if (pInBss->Hidden)
+				bIsHiddenApIncluded = TRUE;
+		}
+
+		if ((pInBss->BssType == pAd->StaCfg.BssType) &&
+			(SSID_EQUAL(Ssid, SsidLen, pInBss->Ssid, pInBss->SsidLen) || bIsHiddenApIncluded))
+		{
+			BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
+
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+			// If no Country IE exists no Connection will be established when IEEE80211dClientMode is strict.
+			if ((pAd->StaCfg.IEEE80211dClientMode == Rt802_11_D_Strict) &&
+				(pInBss->bHasCountryIE == FALSE))
+			{
+				DBGPRINT(RT_DEBUG_TRACE,("StaCfg.IEEE80211dClientMode == Rt802_11_D_Strict, but this AP doesn't have country IE.\n"));
+				continue;
+			}
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+#ifdef DOT11_N_SUPPORT
+			// 2.4G/5G N only mode
+			if ((pInBss->HtCapabilityLen == 0) &&
+				((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
+			{
+				DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
+				continue;
+			}
+#endif // DOT11_N_SUPPORT //
+
+			// New for WPA2
+			// Check the Authmode first
+			if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+			{
+				// Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
+				if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux))
+					// None matched
+					continue;
+
+				// Check cipher suite, AP must have more secured cipher than station setting
+				if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
+				{
+					// If it's not mixed mode, we should only let BSS pass with the same encryption
+					if (pInBss->WPA.bMixMode == FALSE)
+						if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher)
+							continue;
+
+					// check group cipher
+					if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
+						continue;
+
+					// check pairwise cipher, skip if none matched
+					// If profile set to AES, let it pass without question.
+					// If profile set to TKIP, we must find one mateched
+					if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
+						(pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) &&
+						(pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux))
+						continue;
+				}
+				else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+				{
+					// If it's not mixed mode, we should only let BSS pass with the same encryption
+					if (pInBss->WPA2.bMixMode == FALSE)
+						if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher)
+							continue;
+
+					// check group cipher
+					if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
+						continue;
+
+					// check pairwise cipher, skip if none matched
+					// If profile set to AES, let it pass without question.
+					// If profile set to TKIP, we must find one mateched
+					if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
+						(pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) &&
+						(pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux))
+						continue;
+				}
+			}
+			// Bss Type matched, SSID matched.
+			// We will check wepstatus for qualification Bss
+			else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
+			{
+				DBGPRINT(RT_DEBUG_TRACE,("StaCfg.WepStatus=%d, while pInBss->WepStatus=%d\n", pAd->StaCfg.WepStatus, pInBss->WepStatus));
+				//
+				// For the SESv2 case, we will not qualify WepStatus.
+				//
+				if (!pInBss->bSES)
+					continue;
+			}
+
+			// Since the AP is using hidden SSID, and we are trying to connect to ANY
+			// It definitely will fail. So, skip it.
+			// CCX also require not even try to connect it!!
+			if (SsidLen == 0)
+				continue;
+
+#ifdef DOT11_N_SUPPORT
+			// If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
+			// If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
+			if ((pInBss->CentralChannel != pInBss->Channel) &&
+				(pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
+			{
+				if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
+				{
+					pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
+					SetCommonHT(pAd);
+					pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
+				}
+				else
+				{
+					if (pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BAND_WIDTH_20)
+					{
+						SetCommonHT(pAd);
+					}
+				}
+			}
+#endif // DOT11_N_SUPPORT //
+
+			// copy matching BSS from InTab to OutTab
+			NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
+
+			OutTab->BssNr++;
+		}
+		else if ((pInBss->BssType == pAd->StaCfg.BssType) && (SsidLen == 0))
+		{
+			BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
+
+
+#ifdef DOT11_N_SUPPORT
+			// 2.4G/5G N only mode
+			if ((pInBss->HtCapabilityLen == 0) &&
+				((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
+			{
+				DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
+				continue;
+			}
+#endif // DOT11_N_SUPPORT //
+
+			// New for WPA2
+			// Check the Authmode first
+			if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+			{
+				// Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
+				if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux))
+					// None matched
+					continue;
+
+				// Check cipher suite, AP must have more secured cipher than station setting
+				if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
+				{
+					// If it's not mixed mode, we should only let BSS pass with the same encryption
+					if (pInBss->WPA.bMixMode == FALSE)
+						if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher)
+							continue;
+
+					// check group cipher
+					if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
+						continue;
+
+					// check pairwise cipher, skip if none matched
+					// If profile set to AES, let it pass without question.
+					// If profile set to TKIP, we must find one mateched
+					if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
+						(pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) &&
+						(pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux))
+						continue;
+				}
+				else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+				{
+					// If it's not mixed mode, we should only let BSS pass with the same encryption
+					if (pInBss->WPA2.bMixMode == FALSE)
+						if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher)
+							continue;
+
+					// check group cipher
+					if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
+						continue;
+
+					// check pairwise cipher, skip if none matched
+					// If profile set to AES, let it pass without question.
+					// If profile set to TKIP, we must find one mateched
+					if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
+						(pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) &&
+						(pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux))
+						continue;
+				}
+			}
+			// Bss Type matched, SSID matched.
+			// We will check wepstatus for qualification Bss
+			else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
+					continue;
+
+#ifdef DOT11_N_SUPPORT
+			// If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
+			// If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
+			if ((pInBss->CentralChannel != pInBss->Channel) &&
+				(pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
+			{
+				if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
+				{
+					pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
+					SetCommonHT(pAd);
+					pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
+				}
+			}
+#endif // DOT11_N_SUPPORT //
+
+			// copy matching BSS from InTab to OutTab
+			NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
+
+			OutTab->BssNr++;
+		}
+
+		if (OutTab->BssNr >= MAX_LEN_OF_BSS_TABLE)
+			break;
+	}
+
+	BssTableSortByRssi(OutTab);
+}
+
+
+// IRQL = DISPATCH_LEVEL
+VOID BssTableSortByRssi(
+	IN OUT BSS_TABLE *OutTab)
+{
+	INT 	  i, j;
+	BSS_ENTRY TmpBss;
+
+	for (i = 0; i < OutTab->BssNr - 1; i++)
+	{
+		for (j = i+1; j < OutTab->BssNr; j++)
+		{
+			if (OutTab->BssEntry[j].Rssi > OutTab->BssEntry[i].Rssi)
+			{
+				NdisMoveMemory(&TmpBss, &OutTab->BssEntry[j], sizeof(BSS_ENTRY));
+				NdisMoveMemory(&OutTab->BssEntry[j], &OutTab->BssEntry[i], sizeof(BSS_ENTRY));
+				NdisMoveMemory(&OutTab->BssEntry[i], &TmpBss, sizeof(BSS_ENTRY));
+			}
+		}
+	}
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+VOID BssCipherParse(
+	IN OUT	PBSS_ENTRY	pBss)
+{
+	PEID_STRUCT 		 pEid;
+	PUCHAR				pTmp;
+	PRSN_IE_HEADER_STRUCT			pRsnHeader;
+	PCIPHER_SUITE_STRUCT			pCipher;
+	PAKM_SUITE_STRUCT				pAKM;
+	USHORT							Count;
+	INT								Length;
+	NDIS_802_11_ENCRYPTION_STATUS	TmpCipher;
+
+	//
+	// WepStatus will be reset later, if AP announce TKIP or AES on the beacon frame.
+	//
+	if (pBss->Privacy)
+	{
+		pBss->WepStatus 	= Ndis802_11WEPEnabled;
+	}
+	else
+	{
+		pBss->WepStatus 	= Ndis802_11WEPDisabled;
+	}
+	// Set default to disable & open authentication before parsing variable IE
+	pBss->AuthMode		= Ndis802_11AuthModeOpen;
+	pBss->AuthModeAux	= Ndis802_11AuthModeOpen;
+
+	// Init WPA setting
+	pBss->WPA.PairCipher	= Ndis802_11WEPDisabled;
+	pBss->WPA.PairCipherAux = Ndis802_11WEPDisabled;
+	pBss->WPA.GroupCipher	= Ndis802_11WEPDisabled;
+	pBss->WPA.RsnCapability = 0;
+	pBss->WPA.bMixMode		= FALSE;
+
+	// Init WPA2 setting
+	pBss->WPA2.PairCipher	 = Ndis802_11WEPDisabled;
+	pBss->WPA2.PairCipherAux = Ndis802_11WEPDisabled;
+	pBss->WPA2.GroupCipher	 = Ndis802_11WEPDisabled;
+	pBss->WPA2.RsnCapability = 0;
+	pBss->WPA2.bMixMode 	 = FALSE;
+
+
+	Length = (INT) pBss->VarIELen;
+
+	while (Length > 0)
+	{
+		// Parse cipher suite base on WPA1 & WPA2, they should be parsed differently
+		pTmp = ((PUCHAR) pBss->VarIEs) + pBss->VarIELen - Length;
+		pEid = (PEID_STRUCT) pTmp;
+		switch (pEid->Eid)
+		{
+			case IE_WPA:
+				//Parse Cisco IE_WPA (LEAP, CCKM, etc.)
+				if ( NdisEqualMemory((pTmp+8), CISCO_OUI, 3))
+				{
+					pTmp   += 11;
+					switch (*pTmp)
+					{
+						case 1:
+						case 5:	// Although WEP is not allowed in WPA related auth mode, we parse it anyway
+							pBss->WepStatus = Ndis802_11Encryption1Enabled;
+							pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
+							pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
+							break;
+						case 2:
+							pBss->WepStatus = Ndis802_11Encryption2Enabled;
+							pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
+							pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
+							break;
+						case 4:
+							pBss->WepStatus = Ndis802_11Encryption3Enabled;
+							pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
+							pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
+							break;
+						default:
+							break;
+					}
+
+					// if Cisco IE_WPA, break
+					break;
+				}
+				else if (NdisEqualMemory(pEid->Octet, SES_OUI, 3) && (pEid->Len == 7))
+				{
+					pBss->bSES = TRUE;
+					break;
+				}
+				else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4) != 1)
+				{
+					// if unsupported vendor specific IE
+					break;
+				}
+				// Skip OUI, version, and multicast suite
+				// This part should be improved in the future when AP supported multiple cipher suite.
+				// For now, it's OK since almost all APs have fixed cipher suite supported.
+				// pTmp = (PUCHAR) pEid->Octet;
+				pTmp   += 11;
+
+				// Cipher Suite Selectors from Spec P802.11i/D3.2 P26.
+				//	Value	   Meaning
+				//	0			None
+				//	1			WEP-40
+				//	2			Tkip
+				//	3			WRAP
+				//	4			AES
+				//	5			WEP-104
+				// Parse group cipher
+				switch (*pTmp)
+				{
+					case 1:
+					case 5:	// Although WEP is not allowed in WPA related auth mode, we parse it anyway
+						pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
+						break;
+					case 2:
+						pBss->WPA.GroupCipher = Ndis802_11Encryption2Enabled;
+						break;
+					case 4:
+						pBss->WPA.GroupCipher = Ndis802_11Encryption3Enabled;
+						break;
+					default:
+						break;
+				}
+				// number of unicast suite
+				pTmp   += 1;
+
+				// skip all unicast cipher suites
+				//Count = *(PUSHORT) pTmp;
+				Count = (pTmp[1]<<8) + pTmp[0];
+				pTmp   += sizeof(USHORT);
+
+				// Parsing all unicast cipher suite
+				while (Count > 0)
+				{
+					// Skip OUI
+					pTmp += 3;
+					TmpCipher = Ndis802_11WEPDisabled;
+					switch (*pTmp)
+					{
+						case 1:
+						case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
+							TmpCipher = Ndis802_11Encryption1Enabled;
+							break;
+						case 2:
+							TmpCipher = Ndis802_11Encryption2Enabled;
+							break;
+						case 4:
+							TmpCipher = Ndis802_11Encryption3Enabled;
+							break;
+						default:
+							break;
+					}
+					if (TmpCipher > pBss->WPA.PairCipher)
+					{
+						// Move the lower cipher suite to PairCipherAux
+						pBss->WPA.PairCipherAux = pBss->WPA.PairCipher;
+						pBss->WPA.PairCipher	= TmpCipher;
+					}
+					else
+					{
+						pBss->WPA.PairCipherAux = TmpCipher;
+					}
+					pTmp++;
+					Count--;
+				}
+
+				// 4. get AKM suite counts
+				//Count	= *(PUSHORT) pTmp;
+				Count = (pTmp[1]<<8) + pTmp[0];
+				pTmp   += sizeof(USHORT);
+				pTmp   += 3;
+
+				switch (*pTmp)
+				{
+					case 1:
+						// Set AP support WPA mode
+						if (pBss->AuthMode == Ndis802_11AuthModeOpen)
+							pBss->AuthMode = Ndis802_11AuthModeWPA;
+						else
+							pBss->AuthModeAux = Ndis802_11AuthModeWPA;
+						break;
+					case 2:
+						// Set AP support WPA mode
+						if (pBss->AuthMode == Ndis802_11AuthModeOpen)
+							pBss->AuthMode = Ndis802_11AuthModeWPAPSK;
+						else
+							pBss->AuthModeAux = Ndis802_11AuthModeWPAPSK;
+						break;
+					default:
+						break;
+				}
+				pTmp   += 1;
+
+				// Fixed for WPA-None
+				if (pBss->BssType == BSS_ADHOC)
+				{
+					pBss->AuthMode	  = Ndis802_11AuthModeWPANone;
+					pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
+					pBss->WepStatus   = pBss->WPA.GroupCipher;
+					if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
+						pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
+				}
+				else
+					pBss->WepStatus   = pBss->WPA.PairCipher;
+
+				// Check the Pair & Group, if different, turn on mixed mode flag
+				if (pBss->WPA.GroupCipher != pBss->WPA.PairCipher)
+					pBss->WPA.bMixMode = TRUE;
+
+				break;
+
+			case IE_RSN:
+				pRsnHeader = (PRSN_IE_HEADER_STRUCT) pTmp;
+
+				// 0. Version must be 1
+				if (le2cpu16(pRsnHeader->Version) != 1)
+					break;
+				pTmp   += sizeof(RSN_IE_HEADER_STRUCT);
+
+				// 1. Check group cipher
+				pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
+				if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
+					break;
+
+				// Parse group cipher
+				switch (pCipher->Type)
+				{
+					case 1:
+					case 5:	// Although WEP is not allowed in WPA related auth mode, we parse it anyway
+						pBss->WPA2.GroupCipher = Ndis802_11Encryption1Enabled;
+						break;
+					case 2:
+						pBss->WPA2.GroupCipher = Ndis802_11Encryption2Enabled;
+						break;
+					case 4:
+						pBss->WPA2.GroupCipher = Ndis802_11Encryption3Enabled;
+						break;
+					default:
+						break;
+				}
+				// set to correct offset for next parsing
+				pTmp   += sizeof(CIPHER_SUITE_STRUCT);
+
+				// 2. Get pairwise cipher counts
+				//Count = *(PUSHORT) pTmp;
+				Count = (pTmp[1]<<8) + pTmp[0];
+				pTmp   += sizeof(USHORT);
+
+				// 3. Get pairwise cipher
+				// Parsing all unicast cipher suite
+				while (Count > 0)
+				{
+					// Skip OUI
+					pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
+					TmpCipher = Ndis802_11WEPDisabled;
+					switch (pCipher->Type)
+					{
+						case 1:
+						case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
+							TmpCipher = Ndis802_11Encryption1Enabled;
+							break;
+						case 2:
+							TmpCipher = Ndis802_11Encryption2Enabled;
+							break;
+						case 4:
+							TmpCipher = Ndis802_11Encryption3Enabled;
+							break;
+						default:
+							break;
+					}
+					if (TmpCipher > pBss->WPA2.PairCipher)
+					{
+						// Move the lower cipher suite to PairCipherAux
+						pBss->WPA2.PairCipherAux = pBss->WPA2.PairCipher;
+						pBss->WPA2.PairCipher	 = TmpCipher;
+					}
+					else
+					{
+						pBss->WPA2.PairCipherAux = TmpCipher;
+					}
+					pTmp += sizeof(CIPHER_SUITE_STRUCT);
+					Count--;
+				}
+
+				// 4. get AKM suite counts
+				//Count	= *(PUSHORT) pTmp;
+				Count = (pTmp[1]<<8) + pTmp[0];
+				pTmp   += sizeof(USHORT);
+
+				// 5. Get AKM ciphers
+				pAKM = (PAKM_SUITE_STRUCT) pTmp;
+				if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
+					break;
+
+				switch (pAKM->Type)
+				{
+					case 1:
+						// Set AP support WPA mode
+						if (pBss->AuthMode == Ndis802_11AuthModeOpen)
+							pBss->AuthMode = Ndis802_11AuthModeWPA2;
+						else
+							pBss->AuthModeAux = Ndis802_11AuthModeWPA2;
+						break;
+					case 2:
+						// Set AP support WPA mode
+						if (pBss->AuthMode == Ndis802_11AuthModeOpen)
+							pBss->AuthMode = Ndis802_11AuthModeWPA2PSK;
+						else
+							pBss->AuthModeAux = Ndis802_11AuthModeWPA2PSK;
+						break;
+					default:
+						break;
+				}
+				pTmp   += (Count * sizeof(AKM_SUITE_STRUCT));
+
+				// Fixed for WPA-None
+				if (pBss->BssType == BSS_ADHOC)
+				{
+					pBss->AuthMode = Ndis802_11AuthModeWPANone;
+					pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
+					pBss->WPA.PairCipherAux = pBss->WPA2.PairCipherAux;
+					pBss->WPA.GroupCipher	= pBss->WPA2.GroupCipher;
+					pBss->WepStatus 		= pBss->WPA.GroupCipher;
+					if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
+						pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
+				}
+				pBss->WepStatus   = pBss->WPA2.PairCipher;
+
+				// 6. Get RSN capability
+				//pBss->WPA2.RsnCapability = *(PUSHORT) pTmp;
+				pBss->WPA2.RsnCapability = (pTmp[1]<<8) + pTmp[0];
+				pTmp += sizeof(USHORT);
+
+				// Check the Pair & Group, if different, turn on mixed mode flag
+				if (pBss->WPA2.GroupCipher != pBss->WPA2.PairCipher)
+					pBss->WPA2.bMixMode = TRUE;
+
+				break;
+			default:
+				break;
+		}
+		Length -= (pEid->Len + 2);
+	}
+}
+
+// ===========================================================================================
+// mac_table.c
+// ===========================================================================================
+
+/*! \brief generates a random mac address value for IBSS BSSID
+ *	\param Addr the bssid location
+ *	\return none
+ *	\pre
+ *	\post
+ */
+VOID MacAddrRandomBssid(
+	IN PRTMP_ADAPTER pAd,
+	OUT PUCHAR pAddr)
+{
+	INT i;
+
+	for (i = 0; i < MAC_ADDR_LEN; i++)
+	{
+		pAddr[i] = RandomByte(pAd);
+	}
+
+	pAddr[0] = (pAddr[0] & 0xfe) | 0x02;  // the first 2 bits must be 01xxxxxxxx
+}
+
+/*! \brief init the management mac frame header
+ *	\param p_hdr mac header
+ *	\param subtype subtype of the frame
+ *	\param p_ds destination address, don't care if it is a broadcast address
+ *	\return none
+ *	\pre the station has the following information in the pAd->StaCfg
+ *	 - bssid
+ *	 - station address
+ *	\post
+ *	\note this function initializes the following field
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ */
+VOID MgtMacHeaderInit(
+	IN	PRTMP_ADAPTER	pAd,
+	IN OUT PHEADER_802_11 pHdr80211,
+	IN UCHAR SubType,
+	IN UCHAR ToDs,
+	IN PUCHAR pDA,
+	IN PUCHAR pBssid)
+{
+	NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
+
+	pHdr80211->FC.Type = BTYPE_MGMT;
+	pHdr80211->FC.SubType = SubType;
+//	if (SubType == SUBTYPE_ACK)	// sample, no use, it will conflict with ACTION frame sub type
+//		pHdr80211->FC.Type = BTYPE_CNTL;
+	pHdr80211->FC.ToDs = ToDs;
+	COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
+#endif // CONFIG_STA_SUPPORT //
+	COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
+}
+
+// ===========================================================================================
+// mem_mgmt.c
+// ===========================================================================================
+
+/*!***************************************************************************
+ * This routine build an outgoing frame, and fill all information specified
+ * in argument list to the frame body. The actual frame size is the summation
+ * of all arguments.
+ * input params:
+ *		Buffer - pointer to a pre-allocated memory segment
+ *		args - a list of <int arg_size, arg> pairs.
+ *		NOTE NOTE NOTE!!!! the last argument must be NULL, otherwise this
+ *						   function will FAIL!!!
+ * return:
+ *		Size of the buffer
+ * usage:
+ *		MakeOutgoingFrame(Buffer, output_length, 2, &fc, 2, &dur, 6, p_addr1, 6,p_addr2, END_OF_ARGS);
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ****************************************************************************/
+ULONG MakeOutgoingFrame(
+	OUT CHAR *Buffer,
+	OUT ULONG *FrameLen, ...)
+{
+	CHAR   *p;
+	int 	leng;
+	ULONG	TotLeng;
+	va_list Args;
+
+	// calculates the total length
+	TotLeng = 0;
+	va_start(Args, FrameLen);
+	do
+	{
+		leng = va_arg(Args, int);
+		if (leng == END_OF_ARGS)
+		{
+			break;
+		}
+		p = va_arg(Args, PVOID);
+		NdisMoveMemory(&Buffer[TotLeng], p, leng);
+		TotLeng = TotLeng + leng;
+	} while(TRUE);
+
+	va_end(Args); /* clean up */
+	*FrameLen = TotLeng;
+	return TotLeng;
+}
+
+// ===========================================================================================
+// mlme_queue.c
+// ===========================================================================================
+
+/*! \brief	Initialize The MLME Queue, used by MLME Functions
+ *	\param	*Queue	   The MLME Queue
+ *	\return Always	   Return NDIS_STATE_SUCCESS in this implementation
+ *	\pre
+ *	\post
+ *	\note	Because this is done only once (at the init stage), no need to be locked
+
+ IRQL = PASSIVE_LEVEL
+
+ */
+NDIS_STATUS MlmeQueueInit(
+	IN MLME_QUEUE *Queue)
+{
+	INT i;
+
+	NdisAllocateSpinLock(&Queue->Lock);
+
+	Queue->Num	= 0;
+	Queue->Head = 0;
+	Queue->Tail = 0;
+
+	for (i = 0; i < MAX_LEN_OF_MLME_QUEUE; i++)
+	{
+		Queue->Entry[i].Occupied = FALSE;
+		Queue->Entry[i].MsgLen = 0;
+		NdisZeroMemory(Queue->Entry[i].Msg, MGMT_DMA_BUFFER_SIZE);
+	}
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+/*! \brief	 Enqueue a message for other threads, if they want to send messages to MLME thread
+ *	\param	*Queue	  The MLME Queue
+ *	\param	 Machine  The State Machine Id
+ *	\param	 MsgType  The Message Type
+ *	\param	 MsgLen   The Message length
+ *	\param	*Msg	  The message pointer
+ *	\return  TRUE if enqueue is successful, FALSE if the queue is full
+ *	\pre
+ *	\post
+ *	\note	 The message has to be initialized
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ */
+BOOLEAN MlmeEnqueue(
+	IN	PRTMP_ADAPTER	pAd,
+	IN ULONG Machine,
+	IN ULONG MsgType,
+	IN ULONG MsgLen,
+	IN VOID *Msg)
+{
+	INT Tail;
+	MLME_QUEUE	*Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
+
+	// Do nothing if the driver is starting halt state.
+	// This might happen when timer already been fired before cancel timer with mlmehalt
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+		return FALSE;
+
+	// First check the size, it MUST not exceed the mlme queue size
+	if (MsgLen > MGMT_DMA_BUFFER_SIZE)
+	{
+		DBGPRINT_ERR(("MlmeEnqueue: msg too large, size = %ld \n", MsgLen));
+		return FALSE;
+	}
+
+	if (MlmeQueueFull(Queue))
+	{
+		return FALSE;
+	}
+
+	NdisAcquireSpinLock(&(Queue->Lock));
+	Tail = Queue->Tail;
+	Queue->Tail++;
+	Queue->Num++;
+	if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
+	{
+		Queue->Tail = 0;
+	}
+
+	Queue->Entry[Tail].Wcid = RESERVED_WCID;
+	Queue->Entry[Tail].Occupied = TRUE;
+	Queue->Entry[Tail].Machine = Machine;
+	Queue->Entry[Tail].MsgType = MsgType;
+	Queue->Entry[Tail].MsgLen  = MsgLen;
+
+	if (Msg != NULL)
+	{
+		NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
+	}
+
+	NdisReleaseSpinLock(&(Queue->Lock));
+	return TRUE;
+}
+
+/*! \brief	 This function is used when Recv gets a MLME message
+ *	\param	*Queue			 The MLME Queue
+ *	\param	 TimeStampHigh	 The upper 32 bit of timestamp
+ *	\param	 TimeStampLow	 The lower 32 bit of timestamp
+ *	\param	 Rssi			 The receiving RSSI strength
+ *	\param	 MsgLen 		 The length of the message
+ *	\param	*Msg			 The message pointer
+ *	\return  TRUE if everything ok, FALSE otherwise (like Queue Full)
+ *	\pre
+ *	\post
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+BOOLEAN MlmeEnqueueForRecv(
+	IN	PRTMP_ADAPTER	pAd,
+	IN ULONG Wcid,
+	IN ULONG TimeStampHigh,
+	IN ULONG TimeStampLow,
+	IN UCHAR Rssi0,
+	IN UCHAR Rssi1,
+	IN UCHAR Rssi2,
+	IN ULONG MsgLen,
+	IN VOID *Msg,
+	IN UCHAR Signal)
+{
+	INT 		 Tail, Machine;
+	PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
+	INT		 MsgType;
+	MLME_QUEUE	*Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
+
+#ifdef RALINK_ATE
+	/* Nothing to do in ATE mode */
+	if(ATE_ON(pAd))
+		return FALSE;
+#endif // RALINK_ATE //
+
+	// Do nothing if the driver is starting halt state.
+	// This might happen when timer already been fired before cancel timer with mlmehalt
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+	{
+		DBGPRINT_ERR(("MlmeEnqueueForRecv: fRTMP_ADAPTER_HALT_IN_PROGRESS\n"));
+		return FALSE;
+	}
+
+	// First check the size, it MUST not exceed the mlme queue size
+	if (MsgLen > MGMT_DMA_BUFFER_SIZE)
+	{
+		DBGPRINT_ERR(("MlmeEnqueueForRecv: frame too large, size = %ld \n", MsgLen));
+		return FALSE;
+	}
+
+	if (MlmeQueueFull(Queue))
+	{
+		return FALSE;
+	}
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		if (!MsgTypeSubst(pAd, pFrame, &Machine, &MsgType))
+		{
+			DBGPRINT_ERR(("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n",pFrame->Hdr.FC.SubType));
+			return FALSE;
+		}
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	// OK, we got all the informations, it is time to put things into queue
+	NdisAcquireSpinLock(&(Queue->Lock));
+	Tail = Queue->Tail;
+	Queue->Tail++;
+	Queue->Num++;
+	if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
+	{
+		Queue->Tail = 0;
+	}
+	Queue->Entry[Tail].Occupied = TRUE;
+	Queue->Entry[Tail].Machine = Machine;
+	Queue->Entry[Tail].MsgType = MsgType;
+	Queue->Entry[Tail].MsgLen  = MsgLen;
+	Queue->Entry[Tail].TimeStamp.u.LowPart = TimeStampLow;
+	Queue->Entry[Tail].TimeStamp.u.HighPart = TimeStampHigh;
+	Queue->Entry[Tail].Rssi0 = Rssi0;
+	Queue->Entry[Tail].Rssi1 = Rssi1;
+	Queue->Entry[Tail].Rssi2 = Rssi2;
+	Queue->Entry[Tail].Signal = Signal;
+	Queue->Entry[Tail].Wcid = (UCHAR)Wcid;
+
+	Queue->Entry[Tail].Channel = pAd->LatchRfRegs.Channel;
+
+	if (Msg != NULL)
+	{
+		NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
+	}
+
+	NdisReleaseSpinLock(&(Queue->Lock));
+
+	RT28XX_MLME_HANDLER(pAd);
+
+	return TRUE;
+}
+
+
+/*! \brief	 Dequeue a message from the MLME Queue
+ *	\param	*Queue	  The MLME Queue
+ *	\param	*Elem	  The message dequeued from MLME Queue
+ *	\return  TRUE if the Elem contains something, FALSE otherwise
+ *	\pre
+ *	\post
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+BOOLEAN MlmeDequeue(
+	IN MLME_QUEUE *Queue,
+	OUT MLME_QUEUE_ELEM **Elem)
+{
+	NdisAcquireSpinLock(&(Queue->Lock));
+	*Elem = &(Queue->Entry[Queue->Head]);
+	Queue->Num--;
+	Queue->Head++;
+	if (Queue->Head == MAX_LEN_OF_MLME_QUEUE)
+	{
+		Queue->Head = 0;
+	}
+	NdisReleaseSpinLock(&(Queue->Lock));
+	return TRUE;
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID	MlmeRestartStateMachine(
+	IN	PRTMP_ADAPTER	pAd)
+{
+#ifdef CONFIG_STA_SUPPORT
+	BOOLEAN				Cancelled;
+#endif // CONFIG_STA_SUPPORT //
+
+	DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n"));
+
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+#ifdef QOS_DLS_SUPPORT
+		UCHAR i;
+#endif // QOS_DLS_SUPPORT //
+		// Cancel all timer events
+		// Be careful to cancel new added timer
+		RTMPCancelTimer(&pAd->MlmeAux.AssocTimer,	  &Cancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer,   &Cancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer,  &Cancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.AuthTimer,	   &Cancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer,	   &Cancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.ScanTimer,	   &Cancelled);
+
+#ifdef QOS_DLS_SUPPORT
+		for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
+		{
+			RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &Cancelled);
+		}
+#endif // QOS_DLS_SUPPORT //
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	// Change back to original channel in case of doing scan
+	AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+	AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+
+	// Resume MSDU which is turned off durning scan
+	RTMPResumeMsduTransmission(pAd);
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		// Set all state machines back IDLE
+		pAd->Mlme.CntlMachine.CurrState    = CNTL_IDLE;
+		pAd->Mlme.AssocMachine.CurrState   = ASSOC_IDLE;
+		pAd->Mlme.AuthMachine.CurrState    = AUTH_REQ_IDLE;
+		pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE;
+		pAd->Mlme.SyncMachine.CurrState    = SYNC_IDLE;
+		pAd->Mlme.ActMachine.CurrState    = ACT_IDLE;
+#ifdef QOS_DLS_SUPPORT
+		pAd->Mlme.DlsMachine.CurrState    = DLS_IDLE;
+#endif // QOS_DLS_SUPPORT //
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+}
+
+/*! \brief	test if the MLME Queue is empty
+ *	\param	*Queue	  The MLME Queue
+ *	\return TRUE if the Queue is empty, FALSE otherwise
+ *	\pre
+ *	\post
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+BOOLEAN MlmeQueueEmpty(
+	IN MLME_QUEUE *Queue)
+{
+	BOOLEAN Ans;
+
+	NdisAcquireSpinLock(&(Queue->Lock));
+	Ans = (Queue->Num == 0);
+	NdisReleaseSpinLock(&(Queue->Lock));
+
+	return Ans;
+}
+
+/*! \brief	 test if the MLME Queue is full
+ *	\param	 *Queue 	 The MLME Queue
+ *	\return  TRUE if the Queue is empty, FALSE otherwise
+ *	\pre
+ *	\post
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ */
+BOOLEAN MlmeQueueFull(
+	IN MLME_QUEUE *Queue)
+{
+	BOOLEAN Ans;
+
+	NdisAcquireSpinLock(&(Queue->Lock));
+	Ans = (Queue->Num == MAX_LEN_OF_MLME_QUEUE || Queue->Entry[Queue->Tail].Occupied);
+	NdisReleaseSpinLock(&(Queue->Lock));
+
+	return Ans;
+}
+
+/*! \brief	 The destructor of MLME Queue
+ *	\param
+ *	\return
+ *	\pre
+ *	\post
+ *	\note	Clear Mlme Queue, Set Queue->Num to Zero.
+
+ IRQL = PASSIVE_LEVEL
+
+ */
+VOID MlmeQueueDestroy(
+	IN MLME_QUEUE *pQueue)
+{
+	NdisAcquireSpinLock(&(pQueue->Lock));
+	pQueue->Num  = 0;
+	pQueue->Head = 0;
+	pQueue->Tail = 0;
+	NdisReleaseSpinLock(&(pQueue->Lock));
+	NdisFreeSpinLock(&(pQueue->Lock));
+}
+
+/*! \brief	 To substitute the message type if the message is coming from external
+ *	\param	pFrame		   The frame received
+ *	\param	*Machine	   The state machine
+ *	\param	*MsgType	   the message type for the state machine
+ *	\return TRUE if the substitution is successful, FALSE otherwise
+ *	\pre
+ *	\post
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+#ifdef CONFIG_STA_SUPPORT
+BOOLEAN MsgTypeSubst(
+	IN PRTMP_ADAPTER  pAd,
+	IN PFRAME_802_11 pFrame,
+	OUT INT *Machine,
+	OUT INT *MsgType)
+{
+	USHORT	Seq;
+	UCHAR	EAPType;
+	PUCHAR	pData;
+
+	// Pointer to start of data frames including SNAP header
+	pData = (PUCHAR) pFrame + LENGTH_802_11;
+
+	// The only data type will pass to this function is EAPOL frame
+	if (pFrame->Hdr.FC.Type == BTYPE_DATA)
+	{
+		if (NdisEqualMemory(SNAP_AIRONET, pData, LENGTH_802_1_H))
+		{
+			// Cisco Aironet SNAP header
+			*Machine = AIRONET_STATE_MACHINE;
+			*MsgType = MT2_AIRONET_MSG;
+			return (TRUE);
+		}
+#ifdef LEAP_SUPPORT
+		if ( pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP ) //LEAP
+		{
+			// LEAP frames
+			*Machine = LEAP_STATE_MACHINE;
+			EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
+			return (LeapMsgTypeSubst(EAPType, MsgType));
+		}
+		else
+#endif // LEAP_SUPPORT //
+		{
+			*Machine = WPA_PSK_STATE_MACHINE;
+			EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
+			return(WpaMsgTypeSubst(EAPType, MsgType));
+		}
+	}
+
+	switch (pFrame->Hdr.FC.SubType)
+	{
+		case SUBTYPE_ASSOC_REQ:
+			*Machine = ASSOC_STATE_MACHINE;
+			*MsgType = MT2_PEER_ASSOC_REQ;
+			break;
+		case SUBTYPE_ASSOC_RSP:
+			*Machine = ASSOC_STATE_MACHINE;
+			*MsgType = MT2_PEER_ASSOC_RSP;
+			break;
+		case SUBTYPE_REASSOC_REQ:
+			*Machine = ASSOC_STATE_MACHINE;
+			*MsgType = MT2_PEER_REASSOC_REQ;
+			break;
+		case SUBTYPE_REASSOC_RSP:
+			*Machine = ASSOC_STATE_MACHINE;
+			*MsgType = MT2_PEER_REASSOC_RSP;
+			break;
+		case SUBTYPE_PROBE_REQ:
+			*Machine = SYNC_STATE_MACHINE;
+			*MsgType = MT2_PEER_PROBE_REQ;
+			break;
+		case SUBTYPE_PROBE_RSP:
+			*Machine = SYNC_STATE_MACHINE;
+			*MsgType = MT2_PEER_PROBE_RSP;
+			break;
+		case SUBTYPE_BEACON:
+			*Machine = SYNC_STATE_MACHINE;
+			*MsgType = MT2_PEER_BEACON;
+			break;
+		case SUBTYPE_ATIM:
+			*Machine = SYNC_STATE_MACHINE;
+			*MsgType = MT2_PEER_ATIM;
+			break;
+		case SUBTYPE_DISASSOC:
+			*Machine = ASSOC_STATE_MACHINE;
+			*MsgType = MT2_PEER_DISASSOC_REQ;
+			break;
+		case SUBTYPE_AUTH:
+			// get the sequence number from payload 24 Mac Header + 2 bytes algorithm
+			NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(USHORT));
+			if (Seq == 1 || Seq == 3)
+			{
+				*Machine = AUTH_RSP_STATE_MACHINE;
+				*MsgType = MT2_PEER_AUTH_ODD;
+			}
+			else if (Seq == 2 || Seq == 4)
+			{
+				*Machine = AUTH_STATE_MACHINE;
+				*MsgType = MT2_PEER_AUTH_EVEN;
+			}
+			else
+			{
+				return FALSE;
+			}
+			break;
+		case SUBTYPE_DEAUTH:
+			*Machine = AUTH_RSP_STATE_MACHINE;
+			*MsgType = MT2_PEER_DEAUTH;
+			break;
+		case SUBTYPE_ACTION:
+			*Machine = ACTION_STATE_MACHINE;
+			//  Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support
+			if ((pFrame->Octet[0]&0x7F) > MAX_PEER_CATE_MSG)
+			{
+				*MsgType = MT2_ACT_INVALID;
+			}
+			else
+			{
+				*MsgType = (pFrame->Octet[0]&0x7F);
+			}
+			break;
+		default:
+			return FALSE;
+			break;
+	}
+
+	return TRUE;
+}
+#endif // CONFIG_STA_SUPPORT //
+
+// ===========================================================================================
+// state_machine.c
+// ===========================================================================================
+
+/*! \brief Initialize the state machine.
+ *	\param *S			pointer to the state machine
+ *	\param	Trans		State machine transition function
+ *	\param	StNr		number of states
+ *	\param	MsgNr		number of messages
+ *	\param	DefFunc 	default function, when there is invalid state/message combination
+ *	\param	InitState	initial state of the state machine
+ *	\param	Base		StateMachine base, internal use only
+ *	\pre p_sm should be a legal pointer
+ *	\post
+
+ IRQL = PASSIVE_LEVEL
+
+ */
+VOID StateMachineInit(
+	IN STATE_MACHINE *S,
+	IN STATE_MACHINE_FUNC Trans[],
+	IN ULONG StNr,
+	IN ULONG MsgNr,
+	IN STATE_MACHINE_FUNC DefFunc,
+	IN ULONG InitState,
+	IN ULONG Base)
+{
+	ULONG i, j;
+
+	// set number of states and messages
+	S->NrState = StNr;
+	S->NrMsg   = MsgNr;
+	S->Base    = Base;
+
+	S->TransFunc  = Trans;
+
+	// init all state transition to default function
+	for (i = 0; i < StNr; i++)
+	{
+		for (j = 0; j < MsgNr; j++)
+		{
+			S->TransFunc[i * MsgNr + j] = DefFunc;
+		}
+	}
+
+	// set the starting state
+	S->CurrState = InitState;
+}
+
+/*! \brief This function fills in the function pointer into the cell in the state machine
+ *	\param *S	pointer to the state machine
+ *	\param St	state
+ *	\param Msg	incoming message
+ *	\param f	the function to be executed when (state, message) combination occurs at the state machine
+ *	\pre *S should be a legal pointer to the state machine, st, msg, should be all within the range, Base should be set in the initial state
+ *	\post
+
+ IRQL = PASSIVE_LEVEL
+
+ */
+VOID StateMachineSetAction(
+	IN STATE_MACHINE *S,
+	IN ULONG St,
+	IN ULONG Msg,
+	IN STATE_MACHINE_FUNC Func)
+{
+	ULONG MsgIdx;
+
+	MsgIdx = Msg - S->Base;
+
+	if (St < S->NrState && MsgIdx < S->NrMsg)
+	{
+		// boundary checking before setting the action
+		S->TransFunc[St * S->NrMsg + MsgIdx] = Func;
+	}
+}
+
+/*! \brief	 This function does the state transition
+ *	\param	 *Adapter the NIC adapter pointer
+ *	\param	 *S 	  the state machine
+ *	\param	 *Elem	  the message to be executed
+ *	\return   None
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+VOID StateMachinePerformAction(
+	IN	PRTMP_ADAPTER	pAd,
+	IN STATE_MACHINE *S,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	(*(S->TransFunc[S->CurrState * S->NrMsg + Elem->MsgType - S->Base]))(pAd, Elem);
+}
+
+/*
+	==========================================================================
+	Description:
+		The drop function, when machine executes this, the message is simply
+		ignored. This function does nothing, the message is freed in
+		StateMachinePerformAction()
+	==========================================================================
+ */
+VOID Drop(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+}
+
+// ===========================================================================================
+// lfsr.c
+// ===========================================================================================
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = PASSIVE_LEVEL
+
+	==========================================================================
+ */
+VOID LfsrInit(
+	IN PRTMP_ADAPTER pAd,
+	IN ULONG Seed)
+{
+	if (Seed == 0)
+		pAd->Mlme.ShiftReg = 1;
+	else
+		pAd->Mlme.ShiftReg = Seed;
+}
+
+/*
+	==========================================================================
+	Description:
+	==========================================================================
+ */
+UCHAR RandomByte(
+	IN PRTMP_ADAPTER pAd)
+{
+	ULONG i;
+	UCHAR R, Result;
+
+	R = 0;
+
+	if (pAd->Mlme.ShiftReg == 0)
+	NdisGetSystemUpTime((ULONG *)&pAd->Mlme.ShiftReg);
+
+	for (i = 0; i < 8; i++)
+	{
+		if (pAd->Mlme.ShiftReg & 0x00000001)
+		{
+			pAd->Mlme.ShiftReg = ((pAd->Mlme.ShiftReg ^ LFSR_MASK) >> 1) | 0x80000000;
+			Result = 1;
+		}
+		else
+		{
+			pAd->Mlme.ShiftReg = pAd->Mlme.ShiftReg >> 1;
+			Result = 0;
+		}
+		R = (R << 1) | Result;
+	}
+
+	return R;
+}
+
+VOID AsicUpdateAutoFallBackTable(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pRateTable)
+{
+	UCHAR					i;
+	HT_FBK_CFG0_STRUC		HtCfg0;
+	HT_FBK_CFG1_STRUC		HtCfg1;
+	LG_FBK_CFG0_STRUC		LgCfg0;
+	LG_FBK_CFG1_STRUC		LgCfg1;
+	PRTMP_TX_RATE_SWITCH	pCurrTxRate, pNextTxRate;
+
+	// set to initial value
+	HtCfg0.word = 0x65432100;
+	HtCfg1.word = 0xedcba988;
+	LgCfg0.word = 0xedcba988;
+	LgCfg1.word = 0x00002100;
+
+	pNextTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1;
+	for (i = 1; i < *((PUCHAR) pRateTable); i++)
+	{
+		pCurrTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1+i;
+		switch (pCurrTxRate->Mode)
+		{
+			case 0:		//CCK
+				break;
+			case 1:		//OFDM
+				{
+					switch(pCurrTxRate->CurrMCS)
+					{
+						case 0:
+							LgCfg0.field.OFDMMCS0FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+							break;
+						case 1:
+							LgCfg0.field.OFDMMCS1FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+							break;
+						case 2:
+							LgCfg0.field.OFDMMCS2FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+							break;
+						case 3:
+							LgCfg0.field.OFDMMCS3FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+							break;
+						case 4:
+							LgCfg0.field.OFDMMCS4FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+							break;
+						case 5:
+							LgCfg0.field.OFDMMCS5FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+							break;
+						case 6:
+							LgCfg0.field.OFDMMCS6FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+							break;
+						case 7:
+							LgCfg0.field.OFDMMCS7FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+							break;
+					}
+				}
+				break;
+#ifdef DOT11_N_SUPPORT
+			case 2:		//HT-MIX
+			case 3:		//HT-GF
+				{
+					if ((pNextTxRate->Mode >= MODE_HTMIX) && (pCurrTxRate->CurrMCS != pNextTxRate->CurrMCS))
+					{
+						switch(pCurrTxRate->CurrMCS)
+						{
+							case 0:
+								HtCfg0.field.HTMCS0FBK = pNextTxRate->CurrMCS;
+								break;
+							case 1:
+								HtCfg0.field.HTMCS1FBK = pNextTxRate->CurrMCS;
+								break;
+							case 2:
+								HtCfg0.field.HTMCS2FBK = pNextTxRate->CurrMCS;
+								break;
+							case 3:
+								HtCfg0.field.HTMCS3FBK = pNextTxRate->CurrMCS;
+								break;
+							case 4:
+								HtCfg0.field.HTMCS4FBK = pNextTxRate->CurrMCS;
+								break;
+							case 5:
+								HtCfg0.field.HTMCS5FBK = pNextTxRate->CurrMCS;
+								break;
+							case 6:
+								HtCfg0.field.HTMCS6FBK = pNextTxRate->CurrMCS;
+								break;
+							case 7:
+								HtCfg0.field.HTMCS7FBK = pNextTxRate->CurrMCS;
+								break;
+							case 8:
+								HtCfg1.field.HTMCS8FBK = pNextTxRate->CurrMCS;
+								break;
+							case 9:
+								HtCfg1.field.HTMCS9FBK = pNextTxRate->CurrMCS;
+								break;
+							case 10:
+								HtCfg1.field.HTMCS10FBK = pNextTxRate->CurrMCS;
+								break;
+							case 11:
+								HtCfg1.field.HTMCS11FBK = pNextTxRate->CurrMCS;
+								break;
+							case 12:
+								HtCfg1.field.HTMCS12FBK = pNextTxRate->CurrMCS;
+								break;
+							case 13:
+								HtCfg1.field.HTMCS13FBK = pNextTxRate->CurrMCS;
+								break;
+							case 14:
+								HtCfg1.field.HTMCS14FBK = pNextTxRate->CurrMCS;
+								break;
+							case 15:
+								HtCfg1.field.HTMCS15FBK = pNextTxRate->CurrMCS;
+								break;
+							default:
+								DBGPRINT(RT_DEBUG_ERROR, ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n", pCurrTxRate->CurrMCS));
+						}
+					}
+				}
+				break;
+#endif // DOT11_N_SUPPORT //
+		}
+
+		pNextTxRate = pCurrTxRate;
+	}
+
+	RTMP_IO_WRITE32(pAd, HT_FBK_CFG0, HtCfg0.word);
+	RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, HtCfg1.word);
+	RTMP_IO_WRITE32(pAd, LG_FBK_CFG0, LgCfg0.word);
+	RTMP_IO_WRITE32(pAd, LG_FBK_CFG1, LgCfg1.word);
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Set MAC register value according operation mode.
+		OperationMode AND bNonGFExist are for MM and GF Proteciton.
+		If MM or GF mask is not set, those passing argument doesn't not take effect.
+
+		Operation mode meaning:
+		= 0 : Pure HT, no preotection.
+		= 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS.
+		= 0x10: No Transmission in 40M is protected.
+		= 0x11: Transmission in both 40M and 20M shall be protected
+		if (bNonGFExist)
+			we should choose not to use GF. But still set correct ASIC registers.
+	========================================================================
+*/
+VOID 	AsicUpdateProtect(
+	IN		PRTMP_ADAPTER	pAd,
+	IN 		USHORT			OperationMode,
+	IN 		UCHAR			SetMask,
+	IN		BOOLEAN			bDisableBGProtect,
+	IN		BOOLEAN			bNonGFExist)
+{
+	PROT_CFG_STRUC	ProtCfg, ProtCfg4;
+	UINT32 Protect[6];
+	USHORT			offset;
+	UCHAR			i;
+	UINT32 MacReg = 0;
+
+#ifdef RALINK_ATE
+	if (ATE_ON(pAd))
+		return;
+#endif // RALINK_ATE //
+
+#ifdef DOT11_N_SUPPORT
+	if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8))
+	{
+		return;
+	}
+
+	if (pAd->BATable.numAsOriginator)
+	{
+		//
+		// enable the RTS/CTS to avoid channel collision
+		//
+		SetMask = ALLN_SETPROTECT;
+		OperationMode = 8;
+	}
+#endif // DOT11_N_SUPPORT //
+
+	// Config ASIC RTS threshold register
+	RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
+	MacReg &= 0xFF0000FF;
+
+	// If the user want disable RtsThreshold and enbale Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096
+    if ((
+#ifdef DOT11_N_SUPPORT
+		(pAd->CommonCfg.BACapability.field.AmsduEnable) ||
+#endif // DOT11_N_SUPPORT //
+		(pAd->CommonCfg.bAggregationCapable == TRUE))
+        && pAd->CommonCfg.RtsThreshold == MAX_RTS_THRESHOLD)
+    {
+		MacReg |= (0x1000 << 8);
+    }
+    else
+    {
+		MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
+    }
+
+	RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
+
+	// Initial common protection settings
+	RTMPZeroMemory(Protect, sizeof(Protect));
+	ProtCfg4.word = 0;
+	ProtCfg.word = 0;
+	ProtCfg.field.TxopAllowGF40 = 1;
+	ProtCfg.field.TxopAllowGF20 = 1;
+	ProtCfg.field.TxopAllowMM40 = 1;
+	ProtCfg.field.TxopAllowMM20 = 1;
+	ProtCfg.field.TxopAllowOfdm = 1;
+	ProtCfg.field.TxopAllowCck = 1;
+	ProtCfg.field.RTSThEn = 1;
+	ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+
+	// update PHY mode and rate
+	if (pAd->CommonCfg.Channel > 14)
+		ProtCfg.field.ProtectRate = 0x4000;
+	ProtCfg.field.ProtectRate |= pAd->CommonCfg.RtsRate;
+
+	// Handle legacy(B/G) protection
+	if (bDisableBGProtect)
+	{
+		//ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
+		ProtCfg.field.ProtectCtrl = 0;
+		Protect[0] = ProtCfg.word;
+		Protect[1] = ProtCfg.word;
+	}
+	else
+	{
+		//ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
+		ProtCfg.field.ProtectCtrl = 0;			// CCK do not need to be protected
+		Protect[0] = ProtCfg.word;
+		ProtCfg.field.ProtectCtrl = ASIC_CTS;	// OFDM needs using CCK to protect
+		Protect[1] = ProtCfg.word;
+	}
+
+#ifdef DOT11_N_SUPPORT
+	// Decide HT frame protection.
+	if ((SetMask & ALLN_SETPROTECT) != 0)
+	{
+		switch(OperationMode)
+		{
+			case 0x0:
+				// NO PROTECT
+				// 1.All STAs in the BSS are 20/40 MHz HT
+				// 2. in ai 20/40MHz BSS
+				// 3. all STAs are 20MHz in a 20MHz BSS
+				// Pure HT. no protection.
+
+				// MM20_PROT_CFG
+				//	Reserved (31:27)
+				// 	PROT_TXOP(25:20) -- 010111
+				//	PROT_NAV(19:18)  -- 01 (Short NAV protection)
+				//  PROT_CTRL(17:16) -- 00 (None)
+				// 	PROT_RATE(15:0)  -- 0x4004 (OFDM 24M)
+				Protect[2] = 0x01744004;
+
+				// MM40_PROT_CFG
+				//	Reserved (31:27)
+				// 	PROT_TXOP(25:20) -- 111111
+				//	PROT_NAV(19:18)  -- 01 (Short NAV protection)
+				//  PROT_CTRL(17:16) -- 00 (None)
+				// 	PROT_RATE(15:0)  -- 0x4084 (duplicate OFDM 24M)
+				Protect[3] = 0x03f44084;
+
+				// CF20_PROT_CFG
+				//	Reserved (31:27)
+				// 	PROT_TXOP(25:20) -- 010111
+				//	PROT_NAV(19:18)  -- 01 (Short NAV protection)
+				//  PROT_CTRL(17:16) -- 00 (None)
+				// 	PROT_RATE(15:0)  -- 0x4004 (OFDM 24M)
+				Protect[4] = 0x01744004;
+
+				// CF40_PROT_CFG
+				//	Reserved (31:27)
+				// 	PROT_TXOP(25:20) -- 111111
+				//	PROT_NAV(19:18)  -- 01 (Short NAV protection)
+				//  PROT_CTRL(17:16) -- 00 (None)
+				// 	PROT_RATE(15:0)  -- 0x4084 (duplicate OFDM 24M)
+				Protect[5] = 0x03f44084;
+
+				if (bNonGFExist)
+				{
+					// PROT_NAV(19:18)  -- 01 (Short NAV protectiion)
+					// PROT_CTRL(17:16) -- 01 (RTS/CTS)
+					Protect[4] = 0x01754004;
+					Protect[5] = 0x03f54084;
+				}
+				pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
+				break;
+
+ 			case 1:
+				// This is "HT non-member protection mode."
+				// If there may be non-HT STAs my BSS
+				ProtCfg.word = 0x01744004;	// PROT_CTRL(17:16) : 0 (None)
+				ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
+				if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
+				{
+					ProtCfg.word = 0x01740003;	//ERP use Protection bit is set, use protection rate at Clause 18..
+					ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083;
+				}
+				//Assign Protection method for 20&40 MHz packets
+				ProtCfg.field.ProtectCtrl = ASIC_RTS;
+				ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+				ProtCfg4.field.ProtectCtrl = ASIC_RTS;
+				ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
+				Protect[2] = ProtCfg.word;
+				Protect[3] = ProtCfg4.word;
+				Protect[4] = ProtCfg.word;
+				Protect[5] = ProtCfg4.word;
+				pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
+				break;
+
+			case 2:
+				// If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets
+				ProtCfg.word = 0x01744004;  // PROT_CTRL(17:16) : 0 (None)
+				ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
+
+				//Assign Protection method for 40MHz packets
+				ProtCfg4.field.ProtectCtrl = ASIC_RTS;
+				ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
+				Protect[2] = ProtCfg.word;
+				Protect[3] = ProtCfg4.word;
+				if (bNonGFExist)
+				{
+					ProtCfg.field.ProtectCtrl = ASIC_RTS;
+					ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+				}
+				Protect[4] = ProtCfg.word;
+				Protect[5] = ProtCfg4.word;
+
+				pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
+				break;
+
+			case 3:
+				// HT mixed mode.	 PROTECT ALL!
+				// Assign Rate
+				ProtCfg.word = 0x01744004;	//duplicaet legacy 24M. BW set 1.
+				ProtCfg4.word = 0x03f44084;
+				// both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the
+				if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
+				{
+					ProtCfg.word = 0x01740003;	//ERP use Protection bit is set, use protection rate at Clause 18..
+					ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083
+				}
+				//Assign Protection method for 20&40 MHz packets
+				ProtCfg.field.ProtectCtrl = ASIC_RTS;
+				ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+				ProtCfg4.field.ProtectCtrl = ASIC_RTS;
+				ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
+				Protect[2] = ProtCfg.word;
+				Protect[3] = ProtCfg4.word;
+				Protect[4] = ProtCfg.word;
+				Protect[5] = ProtCfg4.word;
+				pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
+				break;
+
+			case 8:
+				Protect[2] = 0x01754004;
+				Protect[3] = 0x03f54084;
+				Protect[4] = 0x01754004;
+				Protect[5] = 0x03f54084;
+				pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
+				break;
+		}
+	}
+#endif // DOT11_N_SUPPORT //
+
+	offset = CCK_PROT_CFG;
+	for (i = 0;i < 6;i++)
+	{
+		if ((SetMask & (1<< i)))
+		{
+			RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]);
+		}
+	}
+}
+
+
+#ifdef RT30xx
+/*
+	========================================================================
+
+	Routine Description: Write RT30xx RF register through MAC
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+NTSTATUS RT30xxWriteRFRegister(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			RegID,
+	IN	UCHAR			Value)
+{
+	RF_CSR_CFG_STRUC	rfcsr;
+	UINT				i = 0;
+
+	do
+	{
+		RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
+
+		if (!rfcsr.field.RF_CSR_KICK)
+			break;
+		i++;
+	}
+	while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
+
+	if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+	{
+		DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
+		return STATUS_UNSUCCESSFUL;
+	}
+
+	rfcsr.field.RF_CSR_WR = 1;
+	rfcsr.field.RF_CSR_KICK = 1;
+	rfcsr.field.TESTCSR_RFACC_REGNUM = RegID;
+	rfcsr.field.RF_CSR_DATA = Value;
+
+	RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
+
+	return STATUS_SUCCESS;
+}
+
+
+/*
+	========================================================================
+
+	Routine Description: Read RT30xx RF register through MAC
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+NTSTATUS RT30xxReadRFRegister(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			RegID,
+	IN	PUCHAR			pValue)
+{
+	RF_CSR_CFG_STRUC	rfcsr;
+	UINT				i=0, k=0;
+
+	for (i=0; i<MAX_BUSY_COUNT; i++)
+	{
+		RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
+
+		if (rfcsr.field.RF_CSR_KICK == BUSY)
+		{
+			continue;
+		}
+		rfcsr.word = 0;
+		rfcsr.field.RF_CSR_WR = 0;
+		rfcsr.field.RF_CSR_KICK = 1;
+		rfcsr.field.TESTCSR_RFACC_REGNUM = RegID;
+		RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
+		for (k=0; k<MAX_BUSY_COUNT; k++)
+		{
+			RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
+
+			if (rfcsr.field.RF_CSR_KICK == IDLE)
+				break;
+		}
+		if ((rfcsr.field.RF_CSR_KICK == IDLE) &&
+			(rfcsr.field.TESTCSR_RFACC_REGNUM == RegID))
+		{
+			*pValue = (UCHAR)rfcsr.field.RF_CSR_DATA;
+			break;
+		}
+	}
+	if (rfcsr.field.RF_CSR_KICK == BUSY)
+	{
+		DBGPRINT_ERR(("RF read R%d=0x%x fail, i[%d], k[%d]\n", RegID, rfcsr.word,i,k));
+		return STATUS_UNSUCCESSFUL;
+	}
+
+	return STATUS_SUCCESS;
+}
+#endif // RT30xx //
+
+#ifdef RT30xx
+// add by johnli, RF power sequence setup
+/*
+	==========================================================================
+	Description:
+
+	Load RF normal operation-mode setup
+
+	==========================================================================
+ */
+VOID RT30xxLoadRFNormalModeSetup(
+	IN PRTMP_ADAPTER 	pAd)
+{
+	UCHAR RFValue;
+
+	// RX0_PD & TX0_PD, RF R1 register Bit 2 & Bit 3 to 0 and RF_BLOCK_en,RX1_PD & TX1_PD, Bit0, Bit 4 & Bit5 to 1
+	RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
+	RFValue = (RFValue & (~0x0C)) | 0x31;
+	RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
+
+	// TX_LO2_en, RF R15 register Bit 3 to 0
+	RT30xxReadRFRegister(pAd, RF_R15, &RFValue);
+	RFValue &= (~0x08);
+	RT30xxWriteRFRegister(pAd, RF_R15, RFValue);
+
+	// TX_LO1_en, RF R17 register Bit 3 to 0
+	RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
+	RFValue &= (~0x08);
+	// to fix rx long range issue
+	if (((pAd->MACVersion & 0xffff) >= 0x0211) && (pAd->NicConfig2.field.ExternalLNAForG == 0))
+	{
+		RFValue |= 0x20;
+	}
+	RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
+
+	// RX_LO1_en, RF R20 register Bit 3 to 0
+	RT30xxReadRFRegister(pAd, RF_R20, &RFValue);
+	RFValue &= (~0x08);
+	RT30xxWriteRFRegister(pAd, RF_R20, RFValue);
+
+	// RX_LO2_en, RF R21 register Bit 3 to 0
+	RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
+	RFValue &= (~0x08);
+	RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
+
+	// LDORF_VC, RF R27 register Bit 2 to 0
+	RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
+	if ((pAd->MACVersion & 0xffff) < 0x0211)
+		RFValue = (RFValue & (~0x77)) | 0x3;
+	else
+		RFValue = (RFValue & (~0x77));
+	RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
+	/* end johnli */
+}
+
+/*
+	==========================================================================
+	Description:
+
+	Load RF sleep-mode setup
+
+	==========================================================================
+ */
+VOID RT30xxLoadRFSleepModeSetup(
+	IN PRTMP_ADAPTER 	pAd)
+{
+	UCHAR RFValue;
+	UINT32 MACValue;
+
+	// RF_BLOCK_en. RF R1 register Bit 0 to 0
+	RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
+	RFValue &= (~0x01);
+	RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
+
+	// VCO_IC, RF R7 register Bit 4 & Bit 5 to 0
+	RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
+	RFValue &= (~0x30);
+	RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
+
+	// Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 0
+	RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
+	RFValue &= (~0x0E);
+	RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
+
+	// RX_CTB_en, RF R21 register Bit 7 to 0
+	RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
+	RFValue &= (~0x80);
+	RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
+
+	// LDORF_VC, RF R27 register Bit 0, Bit 1 & Bit 2 to 1
+	RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
+	RFValue |= 0x77;
+	RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
+
+	RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
+	MACValue |= 0x1D000000;
+	RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
+}
+
+/*
+	==========================================================================
+	Description:
+
+	Reverse RF sleep-mode setup
+
+	==========================================================================
+ */
+VOID RT30xxReverseRFSleepModeSetup(
+	IN PRTMP_ADAPTER 	pAd)
+{
+	UCHAR RFValue;
+	UINT32 MACValue;
+
+	// RF_BLOCK_en, RF R1 register Bit 0 to 1
+	RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
+	RFValue |= 0x01;
+	RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
+
+	// VCO_IC, RF R7 register Bit 4 & Bit 5 to 1
+	RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
+	RFValue |= 0x30;
+	RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
+
+	// Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 1
+	RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
+	RFValue |= 0x0E;
+	RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
+
+	// RX_CTB_en, RF R21 register Bit 7 to 1
+	RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
+	RFValue |= 0x80;
+	RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
+
+	// LDORF_VC, RF R27 register Bit 2 to 0
+	RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
+	if ((pAd->MACVersion & 0xffff) < 0x0211)
+		RFValue = (RFValue & (~0x77)) | 0x3;
+	else
+		RFValue = (RFValue & (~0x77));
+	RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
+
+	// RT3071 version E has fixed this issue
+	if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211))
+	{
+		// patch tx EVM issue temporarily
+		RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
+		MACValue = ((MACValue & 0xE0FFFFFF) | 0x0D000000);
+		RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
+	}
+	else
+	{
+		RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
+		MACValue = ((MACValue & 0xE0FFFFFF) | 0x01000000);
+		RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
+	}
+}
+// end johnli
+#endif // RT30xx //
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID AsicSwitchChannel(
+					  IN PRTMP_ADAPTER pAd,
+	IN	UCHAR			Channel,
+	IN	BOOLEAN			bScan)
+{
+	ULONG			R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0;
+	CHAR    TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER; //Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER;
+	UCHAR	index;
+	UINT32 	Value = 0; //BbpReg, Value;
+	RTMP_RF_REGS *RFRegTable;
+
+	// Search Tx power value
+#if 1
+	// We can't use ChannelList to search channel, since some central channl's txpowr doesn't list
+	// in ChannelList, so use TxPower array instead.
+	//
+	for (index = 0; index < MAX_NUM_OF_CHANNELS; index++)
+	{
+		if (Channel == pAd->TxPower[index].Channel)
+		{
+			TxPwer = pAd->TxPower[index].Power;
+			TxPwer2 = pAd->TxPower[index].Power2;
+			break;
+		}
+	}
+#else
+	for (index = 0; index < pAd->ChannelListNum; index++)
+	{
+		if (Channel == pAd->ChannelList[index].Channel)
+		{
+			TxPwer = pAd->ChannelList[index].Power;
+			TxPwer2 = pAd->ChannelList[index].Power2;
+			break;
+		}
+	}
+#endif
+
+	if (index == MAX_NUM_OF_CHANNELS)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Can't find the Channel#%d \n", Channel));
+	}
+
+#ifdef RT30xx
+	// The RF programming sequence is difference between 3xxx and 2xxx
+	if ((IS_RT3070(pAd) || IS_RT3090(pAd)) && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020) ||
+		(pAd->RfIcType == RFIC_3021) || (pAd->RfIcType == RFIC_3022)))
+	{
+		/* modify by WY for Read RF Reg. error */
+		UCHAR RFValue;
+
+		for (index = 0; index < NUM_OF_3020_CHNL; index++)
+		{
+			if (Channel == FreqItems3020[index].Channel)
+			{
+				// Programming channel parameters
+				RT30xxWriteRFRegister(pAd, RF_R02, FreqItems3020[index].N);
+				RT30xxWriteRFRegister(pAd, RF_R03, FreqItems3020[index].K);
+				RT30xxReadRFRegister(pAd, RF_R06, &RFValue);
+				RFValue = (RFValue & 0xFC) | FreqItems3020[index].R;
+				RT30xxWriteRFRegister(pAd, RF_R06, RFValue);
+
+				// Set Tx0 Power
+				RT30xxReadRFRegister(pAd, RF_R12, &RFValue);
+				RFValue = (RFValue & 0xE0) | TxPwer;
+				RT30xxWriteRFRegister(pAd, RF_R12, RFValue);
+
+				// Set Tx1 Power
+				RT30xxReadRFRegister(pAd, RF_R13, &RFValue);
+				RFValue = (RFValue & 0xE0) | TxPwer2;
+				RT30xxWriteRFRegister(pAd, RF_R13, RFValue);
+
+				// Tx/Rx Stream setting
+				RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
+				//if (IS_RT3090(pAd))
+				//	RFValue |= 0x01; // Enable RF block.
+				RFValue &= 0x03;	//clear bit[7~2]
+				if (pAd->Antenna.field.TxPath == 1)
+					RFValue |= 0xA0;
+				else if (pAd->Antenna.field.TxPath == 2)
+					RFValue |= 0x80;
+				if (pAd->Antenna.field.RxPath == 1)
+					RFValue |= 0x50;
+				else if (pAd->Antenna.field.RxPath == 2)
+					RFValue |= 0x40;
+				RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
+
+				// Set RF offset
+				RT30xxReadRFRegister(pAd, RF_R23, &RFValue);
+				RFValue = (RFValue & 0x80) | pAd->RfFreqOffset;
+				RT30xxWriteRFRegister(pAd, RF_R23, RFValue);
+
+				// Set BW
+				if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
+				{
+					RFValue = pAd->Mlme.CaliBW40RfR24;
+					//DISABLE_11N_CHECK(pAd);
+				}
+				else
+				{
+					RFValue = pAd->Mlme.CaliBW20RfR24;
+				}
+				RT30xxWriteRFRegister(pAd, RF_R24, RFValue);
+				RT30xxWriteRFRegister(pAd, RF_R31, RFValue);
+
+				// Enable RF tuning
+				RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
+				RFValue = RFValue | 0x1;
+				RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
+
+				// latch channel for future usage.
+				pAd->LatchRfRegs.Channel = Channel;
+
+				DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
+					Channel,
+					pAd->RfIcType,
+					TxPwer,
+					TxPwer2,
+					pAd->Antenna.field.TxPath,
+					FreqItems3020[index].N,
+					FreqItems3020[index].K,
+					FreqItems3020[index].R));
+
+				break;
+			}
+		}
+	}
+	else
+#endif // RT30xx //
+
+	{
+		RFRegTable = RF2850RegTable;
+
+		switch (pAd->RfIcType)
+		{
+			case RFIC_2820:
+			case RFIC_2850:
+			case RFIC_2720:
+			case RFIC_2750:
+
+			for (index = 0; index < NUM_OF_2850_CHNL; index++)
+			{
+				if (Channel == RFRegTable[index].Channel)
+				{
+					R2 = RFRegTable[index].R2;
+					if (pAd->Antenna.field.TxPath == 1)
+					{
+						R2 |= 0x4000;	// If TXpath is 1, bit 14 = 1;
+					}
+
+					if (pAd->Antenna.field.RxPath == 2)
+					{
+						R2 |= 0x40;	// write 1 to off Rxpath.
+					}
+					else if (pAd->Antenna.field.RxPath == 1)
+					{
+						R2 |= 0x20040;	// write 1 to off RxPath
+					}
+
+					if (Channel > 14)
+					{
+						// initialize R3, R4
+						R3 = (RFRegTable[index].R3 & 0xffffc1ff);
+						R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15);
+
+						// 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB
+						// R3
+						if ((TxPwer >= -7) && (TxPwer < 0))
+						{
+							TxPwer = (7+TxPwer);
+							TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
+							R3 |= (TxPwer << 10);
+							DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer=%d \n", TxPwer));
+						}
+						else
+						{
+							TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
+							R3 |= (TxPwer << 10) | (1 << 9);
+						}
+
+						// R4
+						if ((TxPwer2 >= -7) && (TxPwer2 < 0))
+						{
+							TxPwer2 = (7+TxPwer2);
+							TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
+							R4 |= (TxPwer2 << 7);
+							DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer2=%d \n", TxPwer2));
+						}
+						else
+						{
+							TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
+							R4 |= (TxPwer2 << 7) | (1 << 6);
+						}
+					}
+					else
+					{
+						R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); // set TX power0
+					R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15) | (TxPwer2 <<6);// Set freq Offset & TxPwr1
+					}
+
+					// Based on BBP current mode before changing RF channel.
+					if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
+					{
+						R4 |=0x200000;
+					}
+
+					// Update variables
+					pAd->LatchRfRegs.Channel = Channel;
+					pAd->LatchRfRegs.R1 = RFRegTable[index].R1;
+					pAd->LatchRfRegs.R2 = R2;
+					pAd->LatchRfRegs.R3 = R3;
+					pAd->LatchRfRegs.R4 = R4;
+
+					// Set RF value 1's set R3[bit2] = [0]
+					RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
+					RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
+					RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
+					RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
+
+					RTMPusecDelay(200);
+
+					// Set RF value 2's set R3[bit2] = [1]
+					RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
+					RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
+					RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04));
+					RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
+
+					RTMPusecDelay(200);
+
+					// Set RF value 3's set R3[bit2] = [0]
+					RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
+					RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
+					RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
+					RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
+
+					break;
+				}
+			}
+			break;
+
+			default:
+			break;
+		}
+	}
+
+	// Change BBP setting during siwtch from a->g, g->a
+	if (Channel <= 14)
+	{
+	    ULONG	TxPinCfg = 0x00050F0A;//Gary 2007/08/09 0x050A0A
+
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);//(0x44 - GET_LNA_GAIN(pAd)));	// According the Rory's suggestion to solve the middle range issue.
+		//RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
+
+		// Rx High power VGA offset for LNA select
+	    if (pAd->NicConfig2.field.ExternalLNAForG)
+	    {
+	        RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
+	    }
+	    else
+	    {
+	        RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
+	    }
+
+		// 5G band selection PIN, bit1 and bit2 are complement
+		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
+		Value &= (~0x6);
+		Value |= (0x04);
+		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
+
+        // Turn off unused PA or LNA when only 1T or 1R
+		if (pAd->Antenna.field.TxPath == 1)
+		{
+			TxPinCfg &= 0xFFFFFFF3;
+		}
+		if (pAd->Antenna.field.RxPath == 1)
+		{
+			TxPinCfg &= 0xFFFFF3FF;
+		}
+
+		RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+	}
+	else
+	{
+	    ULONG	TxPinCfg = 0x00050F05;//Gary 2007/8/9 0x050505
+
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);//(0x44 - GET_LNA_GAIN(pAd)));   // According the Rory's suggestion to solve the middle range issue.
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
+
+		// Rx High power VGA offset for LNA select
+		if (pAd->NicConfig2.field.ExternalLNAForA)
+		{
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
+		}
+		else
+		{
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
+		}
+
+		// 5G band selection PIN, bit1 and bit2 are complement
+		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
+		Value &= (~0x6);
+		Value |= (0x02);
+		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
+
+        // Turn off unused PA or LNA when only 1T or 1R
+		if (pAd->Antenna.field.TxPath == 1)
+		{
+			TxPinCfg &= 0xFFFFFFF3;
+	}
+		if (pAd->Antenna.field.RxPath == 1)
+		{
+			TxPinCfg &= 0xFFFFF3FF;
+	}
+
+		RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+	}
+
+    // R66 should be set according to Channel and use 20MHz when scanning
+	//RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd)));
+	if (bScan)
+		RTMPSetAGCInitValue(pAd, BW_20);
+	else
+		RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
+
+	//
+	// On 11A, We should delay and wait RF/BBP to be stable
+	// and the appropriate time should be 1000 micro seconds
+	// 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.
+	//
+	RTMPusecDelay(1000);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%lu, Pwr1=%lu, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
+							  Channel,
+							  pAd->RfIcType,
+							  (R3 & 0x00003e00) >> 9,
+							  (R4 & 0x000007c0) >> 6,
+							  pAd->Antenna.field.TxPath,
+							  pAd->LatchRfRegs.R1,
+							  pAd->LatchRfRegs.R2,
+							  pAd->LatchRfRegs.R3,
+							  pAd->LatchRfRegs.R4));
+}
+
+/*
+	==========================================================================
+	Description:
+		This function is required for 2421 only, and should not be used during
+		site survey. It's only required after NIC decided to stay at a channel
+		for a longer period.
+		When this function is called, it's always after AsicSwitchChannel().
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID AsicLockChannel(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR Channel)
+{
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID	AsicAntennaSelect(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			Channel)
+{
+			if (pAd->Mlme.OneSecPeriodicRound % 2 == 1)
+			{
+				// patch for AsicSetRxAnt failed
+				pAd->RxAnt.EvaluatePeriod = 0;
+
+				// check every 2 second. If rcv-beacon less than 5 in the past 2 second, then AvgRSSI is no longer a
+				// valid indication of the distance between this AP and its clients.
+				if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+				{
+					SHORT	realavgrssi1;
+
+					// if no traffic then reset average rssi to trigger evaluation
+#ifdef CONFIG_STA_SUPPORT
+					if (pAd->StaCfg.NumOfAvgRssiSample < 5)
+					{
+						pAd->RxAnt.Pair1LastAvgRssi = (-99);
+						pAd->RxAnt.Pair2LastAvgRssi = (-99);
+						DBGPRINT(RT_DEBUG_TRACE, ("MlmePeriodicExec: no traffic/beacon, reset RSSI\n"));
+					}
+
+					pAd->StaCfg.NumOfAvgRssiSample = 0;
+#endif // CONFIG_STA_SUPPORT //
+					realavgrssi1 = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt] >> 3);
+
+					DBGPRINT(RT_DEBUG_TRACE,("Ant-realrssi0(%d), Lastrssi0(%d), EvaluateStableCnt=%d\n", realavgrssi1, pAd->RxAnt.Pair1LastAvgRssi, pAd->RxAnt.EvaluateStableCnt));
+
+					// if the difference between two rssi is larger or less than 5, then evaluate the other antenna
+					if ((pAd->RxAnt.EvaluateStableCnt < 2) || (realavgrssi1 > (pAd->RxAnt.Pair1LastAvgRssi + 5)) || (realavgrssi1 < (pAd->RxAnt.Pair1LastAvgRssi - 5)))
+					{
+						pAd->RxAnt.Pair1LastAvgRssi = realavgrssi1;
+						AsicEvaluateRxAnt(pAd);
+					}
+				}
+				else
+				{
+					// if not connected, always switch antenna to try to connect
+					UCHAR	temp;
+
+					temp = pAd->RxAnt.Pair1PrimaryRxAnt;
+					pAd->RxAnt.Pair1PrimaryRxAnt = pAd->RxAnt.Pair1SecondaryRxAnt;
+					pAd->RxAnt.Pair1SecondaryRxAnt = temp;
+
+					DBGPRINT(RT_DEBUG_TRACE, ("MlmePeriodicExec: no connect, switch to another one to try connection\n"));
+
+					AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
+				}
+			}
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Antenna miscellaneous setting.
+
+	Arguments:
+		pAd						Pointer to our adapter
+		BandState				Indicate current Band State.
+
+	Return Value:
+		None
+
+	IRQL <= DISPATCH_LEVEL
+
+	Note:
+		1.) Frame End type control
+			only valid for G only (RF_2527 & RF_2529)
+			0: means DPDT, set BBP R4 bit 5 to 1
+			1: means SPDT, set BBP R4 bit 5 to 0
+
+
+	========================================================================
+*/
+VOID	AsicAntennaSetting(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	ABGBAND_STATE	BandState)
+{
+}
+
+VOID AsicRfTuningExec(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3)
+{
+}
+
+/*
+	==========================================================================
+	Description:
+		Gives CCK TX rate 2 more dB TX power.
+		This routine works only in LINK UP in INFRASTRUCTURE mode.
+
+		calculate desired Tx power in RF R3.Tx0~5,	should consider -
+		0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
+		1. TxPowerPercentage
+		2. auto calibration based on TSSI feedback
+		3. extra 2 db for CCK
+		4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
+
+	NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
+		it should be called AFTER MlmeDynamicTxRatSwitching()
+	==========================================================================
+ */
+VOID AsicAdjustTxPower(
+	IN PRTMP_ADAPTER pAd)
+{
+	INT			i, j;
+	CHAR		DeltaPwr = 0;
+	BOOLEAN		bAutoTxAgc = FALSE;
+	UCHAR		TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
+	UCHAR		BbpR1 = 0, BbpR49 = 0, idx;
+	PCHAR		pTxAgcCompensate;
+	ULONG		TxPwr[5];
+	CHAR		Value;
+
+
+
+	if (pAd->CommonCfg.BBPCurrentBW == BW_40)
+	{
+		if (pAd->CommonCfg.CentralChannel > 14)
+		{
+			TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
+			TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
+			TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
+			TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
+			TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
+		}
+		else
+		{
+			TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
+			TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
+			TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
+			TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
+			TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
+		}
+	}
+	else
+	{
+		if (pAd->CommonCfg.Channel > 14)
+		{
+			TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
+			TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
+			TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
+			TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
+			TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
+		}
+		else
+		{
+			TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
+			TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
+			TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
+			TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
+			TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
+		}
+	}
+
+	// TX power compensation for temperature variation based on TSSI. try every 4 second
+	if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
+	{
+		if (pAd->CommonCfg.Channel <= 14)
+		{
+			/* bg channel */
+			bAutoTxAgc         = pAd->bAutoTxAgcG;
+			TssiRef            = pAd->TssiRefG;
+			pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
+			pTssiPlusBoundary  = &pAd->TssiPlusBoundaryG[0];
+			TxAgcStep          = pAd->TxAgcStepG;
+			pTxAgcCompensate   = &pAd->TxAgcCompensateG;
+		}
+		else
+		{
+			/* a channel */
+			bAutoTxAgc         = pAd->bAutoTxAgcA;
+			TssiRef            = pAd->TssiRefA;
+			pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
+			pTssiPlusBoundary  = &pAd->TssiPlusBoundaryA[0];
+			TxAgcStep          = pAd->TxAgcStepA;
+			pTxAgcCompensate   = &pAd->TxAgcCompensateA;
+		}
+
+		if (bAutoTxAgc)
+		{
+			/* BbpR1 is unsigned char */
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
+
+			/* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
+			/* compensate: +4     +3   +2   +1    0   -1   -2   -3   -4 * steps */
+			/* step value is defined in pAd->TxAgcStepG for tx power value */
+
+			/* [4]+1+[4]   p4     p3   p2   p1   o1   m1   m2   m3   m4 */
+			/* ex:         0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
+			   above value are examined in mass factory production */
+			/*             [4]    [3]  [2]  [1]  [0]  [1]  [2]  [3]  [4] */
+
+			/* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */
+			/* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
+			/* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */
+
+			if (BbpR49 > pTssiMinusBoundary[1])
+			{
+				// Reading is larger than the reference value
+				// check for how large we need to decrease the Tx power
+				for (idx = 1; idx < 5; idx++)
+				{
+					if (BbpR49 <= pTssiMinusBoundary[idx])  // Found the range
+						break;
+				}
+				// The index is the step we should decrease, idx = 0 means there is nothing to compensate
+//				if (R3 > (ULONG) (TxAgcStep * (idx-1)))
+					*pTxAgcCompensate = -(TxAgcStep * (idx-1));
+//				else
+//					*pTxAgcCompensate = -((UCHAR)R3);
+
+				DeltaPwr += (*pTxAgcCompensate);
+				DBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
+					BbpR49, TssiRef, TxAgcStep, idx-1));
+			}
+			else if (BbpR49 < pTssiPlusBoundary[1])
+			{
+				// Reading is smaller than the reference value
+				// check for how large we need to increase the Tx power
+				for (idx = 1; idx < 5; idx++)
+				{
+					if (BbpR49 >= pTssiPlusBoundary[idx])   // Found the range
+						break;
+				}
+				// The index is the step we should increase, idx = 0 means there is nothing to compensate
+				*pTxAgcCompensate = TxAgcStep * (idx-1);
+				DeltaPwr += (*pTxAgcCompensate);
+				DBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
+					BbpR49, TssiRef, TxAgcStep, idx-1));
+			}
+			else
+			{
+				*pTxAgcCompensate = 0;
+				DBGPRINT(RT_DEBUG_TRACE, ("   Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
+					BbpR49, TssiRef, TxAgcStep, 0));
+			}
+		}
+	}
+	else
+	{
+		if (pAd->CommonCfg.Channel <= 14)
+		{
+			bAutoTxAgc         = pAd->bAutoTxAgcG;
+			pTxAgcCompensate   = &pAd->TxAgcCompensateG;
+		}
+		else
+		{
+			bAutoTxAgc         = pAd->bAutoTxAgcA;
+			pTxAgcCompensate   = &pAd->TxAgcCompensateA;
+		}
+
+		if (bAutoTxAgc)
+			DeltaPwr += (*pTxAgcCompensate);
+	}
+
+	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1);
+	BbpR1 &= 0xFC;
+
+#ifdef SINGLE_SKU
+	// Handle regulatory max tx power constrain
+	do
+	{
+		UCHAR    TxPwrInEEPROM = 0xFF, CountryTxPwr = 0xFF, criterion;
+		UCHAR    AdjustMaxTxPwr[40];
+
+		if (pAd->CommonCfg.Channel > 14) // 5G band
+			TxPwrInEEPROM = ((pAd->CommonCfg.DefineMaxTxPwr & 0xFF00) >> 8);
+		else // 2.4G band
+			TxPwrInEEPROM = (pAd->CommonCfg.DefineMaxTxPwr & 0x00FF);
+		CountryTxPwr = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel);
+
+		// error handling, range check
+		if ((TxPwrInEEPROM > 0x50) || (CountryTxPwr > 0x50))
+		{
+			DBGPRINT(RT_DEBUG_ERROR,("AsicAdjustTxPower - Invalid max tx power (=0x%02x), CountryTxPwr=%d\n", TxPwrInEEPROM, CountryTxPwr));
+			break;
+		}
+
+		criterion = *((PUCHAR)TxPwr + 2) & 0xF;        // FAE use OFDM 6M as criterion
+
+		DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (criterion=%d, TxPwrInEEPROM=%d, CountryTxPwr=%d)\n", criterion, TxPwrInEEPROM, CountryTxPwr));
+
+		// Adjust max tx power according to the relationship of tx power in E2PROM
+		for (i=0; i<5; i++)
+		{
+			// CCK will have 4dBm larger than OFDM
+			// Therefore, we should separate to parse the tx power field
+			if (i == 0)
+			{
+				for (j=0; j<8; j++)
+				{
+					Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F);
+
+					if (j < 4)
+					{
+						// CCK will have 4dBm larger than OFDM
+						AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion) + 4;
+					}
+					else
+					{
+						AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion);
+					}
+					DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
+				}
+			}
+			else
+			{
+				for (j=0; j<8; j++)
+				{
+					Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F);
+
+					AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion);
+					DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
+				}
+			}
+		}
+
+		// Adjust tx power according to the relationship
+		for (i=0; i<5; i++)
+		{
+			if (TxPwr[i] != 0xffffffff)
+			{
+				for (j=0; j<8; j++)
+				{
+					Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F);
+
+					// The system tx power is larger than the regulatory, the power should be restrain
+					if (AdjustMaxTxPwr[i*8+j] > CountryTxPwr)
+					{
+						// decrease to zero and don't need to take care BBPR1
+						if ((Value - (AdjustMaxTxPwr[i*8+j] - CountryTxPwr)) > 0)
+							Value -= (AdjustMaxTxPwr[i*8+j] - CountryTxPwr);
+						else
+							Value = 0;
+
+						DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
+					}
+					else
+						DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d, no change)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
+
+						TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
+				}
+			}
+		}
+	} while (FALSE);
+#endif // SINGLE_SKU //
+
+	/* calculate delta power based on the percentage specified from UI */
+	// E2PROM setting is calibrated for maximum TX power (i.e. 100%)
+	// We lower TX power here according to the percentage specified from UI
+	if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff)       // AUTO TX POWER control
+		;
+	else if (pAd->CommonCfg.TxPowerPercentage > 90)  // 91 ~ 100% & AUTO, treat as 100% in terms of mW
+		;
+	else if (pAd->CommonCfg.TxPowerPercentage > 60)  // 61 ~ 90%, treat as 75% in terms of mW		// DeltaPwr -= 1;
+	{
+		DeltaPwr -= 1;
+	}
+	else if (pAd->CommonCfg.TxPowerPercentage > 30)  // 31 ~ 60%, treat as 50% in terms of mW		// DeltaPwr -= 3;
+	{
+		DeltaPwr -= 3;
+	}
+	else if (pAd->CommonCfg.TxPowerPercentage > 15)  // 16 ~ 30%, treat as 25% in terms of mW		// DeltaPwr -= 6;
+	{
+		BbpR1 |= 0x01;
+	}
+	else if (pAd->CommonCfg.TxPowerPercentage > 9)   // 10 ~ 15%, treat as 12.5% in terms of mW		// DeltaPwr -= 9;
+	{
+		BbpR1 |= 0x01;
+		DeltaPwr -= 3;
+	}
+	else                                           // 0 ~ 9 %, treat as MIN(~3%) in terms of mW		// DeltaPwr -= 12;
+	{
+		BbpR1 |= 0x02;
+	}
+
+	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
+
+	/* reset different new tx power for different TX rate */
+	for(i=0; i<5; i++)
+	{
+		if (TxPwr[i] != 0xffffffff)
+		{
+			for (j=0; j<8; j++)
+			{
+				Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */
+
+				if ((Value + DeltaPwr) < 0)
+				{
+					Value = 0; /* min */
+				}
+				else if ((Value + DeltaPwr) > 0xF)
+				{
+					Value = 0xF; /* max */
+				}
+				else
+				{
+					Value += DeltaPwr; /* temperature compensation */
+				}
+
+				/* fill new value to CSR offset */
+				TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
+			}
+
+			/* write tx power value to CSR */
+			/* TX_PWR_CFG_0 (8 tx rate) for	TX power for OFDM 12M/18M
+											TX power for OFDM 6M/9M
+											TX power for CCK5.5M/11M
+											TX power for CCK1M/2M */
+			/* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
+			RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]);
+		}
+	}
+
+
+}
+
+#ifdef CONFIG_STA_SUPPORT
+/*
+	==========================================================================
+	Description:
+		put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup
+		automatically. Instead, MCU will issue a TwakeUpInterrupt to host after
+		the wakeup timer timeout. Driver has to issue a separate command to wake
+		PHY up.
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID AsicSleepThenAutoWakeup(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT TbttNumToNextWakeUp)
+{
+    RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp);
+}
+
+/*
+	==========================================================================
+	Description:
+		AsicForceWakeup() is used whenever manual wakeup is required
+		AsicForceSleep() should only be used when not in INFRA BSS. When
+		in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead.
+	==========================================================================
+ */
+VOID AsicForceSleep(
+	IN PRTMP_ADAPTER pAd)
+{
+
+}
+
+/*
+	==========================================================================
+	Description:
+		AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup)
+		expired.
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+	==========================================================================
+ */
+VOID AsicForceWakeup(
+	IN PRTMP_ADAPTER pAd,
+	IN BOOLEAN    bFromTx)
+{
+    DBGPRINT(RT_DEBUG_TRACE, ("--> AsicForceWakeup \n"));
+    RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx);
+}
+#endif // CONFIG_STA_SUPPORT //
+/*
+	==========================================================================
+	Description:
+		Set My BSSID
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID AsicSetBssid(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pBssid)
+{
+	ULONG		  Addr4;
+	DBGPRINT(RT_DEBUG_TRACE, ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n",
+		pBssid[0],pBssid[1],pBssid[2],pBssid[3], pBssid[4],pBssid[5]));
+
+	Addr4 = (ULONG)(pBssid[0])		 |
+			(ULONG)(pBssid[1] << 8)  |
+			(ULONG)(pBssid[2] << 16) |
+			(ULONG)(pBssid[3] << 24);
+	RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
+
+	Addr4 = 0;
+	// always one BSSID in STA mode
+	Addr4 = (ULONG)(pBssid[4]) | (ULONG)(pBssid[5] << 8);
+
+	RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
+}
+
+VOID AsicSetMcastWC(
+	IN PRTMP_ADAPTER pAd)
+{
+	MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[MCAST_WCID];
+	USHORT		offset;
+
+	pEntry->Sst        = SST_ASSOC;
+	pEntry->Aid        = MCAST_WCID;	// Softap supports 1 BSSID and use WCID=0 as multicast Wcid index
+	pEntry->PsMode     = PWR_ACTIVE;
+	pEntry->CurrTxRate = pAd->CommonCfg.MlmeRate;
+	offset = MAC_WCID_BASE + BSS0Mcast_WCID * HW_WCID_ENTRY_SIZE;
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID AsicDelWcidTab(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR	Wcid)
+{
+	ULONG		  Addr0 = 0x0, Addr1 = 0x0;
+	ULONG 		offset;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("AsicDelWcidTab==>Wcid = 0x%x\n",Wcid));
+	offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE;
+	RTMP_IO_WRITE32(pAd, offset, Addr0);
+	offset += 4;
+	RTMP_IO_WRITE32(pAd, offset, Addr1);
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID AsicEnableRDG(
+	IN PRTMP_ADAPTER pAd)
+{
+	TX_LINK_CFG_STRUC	TxLinkCfg;
+	UINT32				Data = 0;
+
+	RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
+	TxLinkCfg.field.TxRDGEn = 1;
+	RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
+
+	RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
+	Data  &= 0xFFFFFF00;
+	Data  |= 0x80;
+	RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+
+	//OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID AsicDisableRDG(
+	IN PRTMP_ADAPTER pAd)
+{
+	TX_LINK_CFG_STRUC	TxLinkCfg;
+	UINT32				Data = 0;
+
+
+	RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
+	TxLinkCfg.field.TxRDGEn = 0;
+	RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
+
+	RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
+
+	Data  &= 0xFFFFFF00;
+	//Data  |= 0x20;
+#ifndef WIFI_TEST
+	//if ( pAd->CommonCfg.bEnableTxBurst )
+	//	Data |= 0x60; // for performance issue not set the TXOP to 0
+#endif
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE)
+#ifdef DOT11_N_SUPPORT
+		&& (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE)
+#endif // DOT11_N_SUPPORT //
+	)
+	{
+		// For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
+		if (pAd->CommonCfg.bEnableTxBurst)
+			Data |= 0x20;
+	}
+	RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID AsicDisableSync(
+	IN PRTMP_ADAPTER pAd)
+{
+	BCN_TIME_CFG_STRUC csr;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n"));
+
+	// 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect
+	//			  that NIC will never wakes up because TSF stops and no more
+	//			  TBTT interrupts
+	pAd->TbttTickCount = 0;
+	RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
+	csr.field.bBeaconGen = 0;
+	csr.field.bTBTTEnable = 0;
+	csr.field.TsfSyncMode = 0;
+	csr.field.bTsfTicking = 0;
+	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
+
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID AsicEnableBssSync(
+	IN PRTMP_ADAPTER pAd)
+{
+	BCN_TIME_CFG_STRUC csr;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n"));
+
+	RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
+//	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, 0x00000000);
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
+		csr.field.bTsfTicking = 1;
+		csr.field.TsfSyncMode = 1; // sync TSF in INFRASTRUCTURE mode
+		csr.field.bBeaconGen  = 0; // do NOT generate BEACON
+		csr.field.bTBTTEnable = 1;
+	}
+#endif // CONFIG_STA_SUPPORT //
+	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
+}
+
+/*
+	==========================================================================
+	Description:
+	Note:
+		BEACON frame in shared memory should be built ok before this routine
+		can be called. Otherwise, a garbage frame maybe transmitted out every
+		Beacon period.
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID AsicEnableIbssSync(
+	IN PRTMP_ADAPTER pAd)
+{
+	BCN_TIME_CFG_STRUC csr9;
+	PUCHAR			ptr;
+	UINT i;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n", pAd->BeaconTxWI.MPDUtotalByteCount));
+
+	RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word);
+	csr9.field.bBeaconGen = 0;
+	csr9.field.bTBTTEnable = 0;
+	csr9.field.bTsfTicking = 0;
+	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
+
+
+#ifdef RT2870
+	// move BEACON TXD and frame content to on-chip memory
+	ptr = (PUCHAR)&pAd->BeaconTxWI;
+	for (i=0; i<TXWI_SIZE; i+=2)  // 16-byte TXWI field
+	{
+		//UINT32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
+		//RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr);
+		RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + i, ptr, 2);
+		ptr += 2;
+	}
+
+	// start right after the 16-byte TXWI field
+	ptr = pAd->BeaconBuf;
+	for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=2)
+	{
+		//UINT32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
+		//RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
+		RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, ptr, 2);
+		ptr +=2;
+	}
+#endif // RT2870 //
+
+	//
+	// For Wi-Fi faily generated beacons between participating stations.
+	// Set TBTT phase adaptive adjustment step to 8us (default 16us)
+	// don't change settings 2006-5- by Jerry
+	//RTMP_IO_WRITE32(pAd, TBTT_SYNC_CFG, 0x00001010);
+
+	// start sending BEACON
+	csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
+	csr9.field.bTsfTicking = 1;
+	csr9.field.TsfSyncMode = 2; // sync TSF in IBSS mode
+	csr9.field.bTBTTEnable = 1;
+	csr9.field.bBeaconGen = 1;
+	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID AsicSetEdcaParm(
+	IN PRTMP_ADAPTER pAd,
+	IN PEDCA_PARM	 pEdcaParm)
+{
+	EDCA_AC_CFG_STRUC   Ac0Cfg, Ac1Cfg, Ac2Cfg, Ac3Cfg;
+	AC_TXOP_CSR0_STRUC csr0;
+	AC_TXOP_CSR1_STRUC csr1;
+	AIFSN_CSR_STRUC    AifsnCsr;
+	CWMIN_CSR_STRUC    CwminCsr;
+	CWMAX_CSR_STRUC    CwmaxCsr;
+	int i;
+
+	Ac0Cfg.word = 0;
+	Ac1Cfg.word = 0;
+	Ac2Cfg.word = 0;
+	Ac3Cfg.word = 0;
+	if ((pEdcaParm == NULL) || (pEdcaParm->bValid == FALSE))
+	{
+		DBGPRINT(RT_DEBUG_TRACE,("AsicSetEdcaParm\n"));
+		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WMM_INUSED);
+		for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+		{
+			if (pAd->MacTab.Content[i].ValidAsCLI || pAd->MacTab.Content[i].ValidAsApCli)
+				CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[i], fCLIENT_STATUS_WMM_CAPABLE);
+		}
+
+		//========================================================
+		//      MAC Register has a copy .
+		//========================================================
+//#ifndef WIFI_TEST
+		if( pAd->CommonCfg.bEnableTxBurst )
+		{
+			// For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
+			Ac0Cfg.field.AcTxop = 0x20; // Suggest by John for TxBurst in HT Mode
+		}
+		else
+			Ac0Cfg.field.AcTxop = 0;	// QID_AC_BE
+//#else
+//		Ac0Cfg.field.AcTxop = 0;	// QID_AC_BE
+//#endif
+		Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS;
+		Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS;
+		Ac0Cfg.field.Aifsn = 2;
+		RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
+
+		Ac1Cfg.field.AcTxop = 0;	// QID_AC_BK
+		Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS;
+		Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS;
+		Ac1Cfg.field.Aifsn = 2;
+		RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
+
+		if (pAd->CommonCfg.PhyMode == PHY_11B)
+		{
+			Ac2Cfg.field.AcTxop = 192;	// AC_VI: 192*32us ~= 6ms
+			Ac3Cfg.field.AcTxop = 96;	// AC_VO: 96*32us  ~= 3ms
+		}
+		else
+		{
+			Ac2Cfg.field.AcTxop = 96;	// AC_VI: 96*32us ~= 3ms
+			Ac3Cfg.field.AcTxop = 48;	// AC_VO: 48*32us ~= 1.5ms
+		}
+		Ac2Cfg.field.Cwmin = CW_MIN_IN_BITS;
+		Ac2Cfg.field.Cwmax = CW_MAX_IN_BITS;
+		Ac2Cfg.field.Aifsn = 2;
+		RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
+		Ac3Cfg.field.Cwmin = CW_MIN_IN_BITS;
+		Ac3Cfg.field.Cwmax = CW_MAX_IN_BITS;
+		Ac3Cfg.field.Aifsn = 2;
+		RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
+
+		//========================================================
+		//      DMA Register has a copy too.
+		//========================================================
+		csr0.field.Ac0Txop = 0;		// QID_AC_BE
+		csr0.field.Ac1Txop = 0;		// QID_AC_BK
+		RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
+		if (pAd->CommonCfg.PhyMode == PHY_11B)
+		{
+			csr1.field.Ac2Txop = 192;		// AC_VI: 192*32us ~= 6ms
+			csr1.field.Ac3Txop = 96;		// AC_VO: 96*32us  ~= 3ms
+		}
+		else
+		{
+			csr1.field.Ac2Txop = 96;		// AC_VI: 96*32us ~= 3ms
+			csr1.field.Ac3Txop = 48;		// AC_VO: 48*32us ~= 1.5ms
+		}
+		RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
+
+		CwminCsr.word = 0;
+		CwminCsr.field.Cwmin0 = CW_MIN_IN_BITS;
+		CwminCsr.field.Cwmin1 = CW_MIN_IN_BITS;
+		CwminCsr.field.Cwmin2 = CW_MIN_IN_BITS;
+		CwminCsr.field.Cwmin3 = CW_MIN_IN_BITS;
+		RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
+
+		CwmaxCsr.word = 0;
+		CwmaxCsr.field.Cwmax0 = CW_MAX_IN_BITS;
+		CwmaxCsr.field.Cwmax1 = CW_MAX_IN_BITS;
+		CwmaxCsr.field.Cwmax2 = CW_MAX_IN_BITS;
+		CwmaxCsr.field.Cwmax3 = CW_MAX_IN_BITS;
+		RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
+
+		RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, 0x00002222);
+
+		NdisZeroMemory(&pAd->CommonCfg.APEdcaParm, sizeof(EDCA_PARM));
+	}
+	else
+	{
+		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WMM_INUSED);
+		//========================================================
+		//      MAC Register has a copy.
+		//========================================================
+		//
+		// Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27
+		// To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue.
+		//
+		//pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this
+
+		Ac0Cfg.field.AcTxop =  pEdcaParm->Txop[QID_AC_BE];
+		Ac0Cfg.field.Cwmin= pEdcaParm->Cwmin[QID_AC_BE];
+		Ac0Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BE];
+		Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]; //+1;
+
+		Ac1Cfg.field.AcTxop =  pEdcaParm->Txop[QID_AC_BK];
+		Ac1Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BK]; //+2;
+		Ac1Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BK];
+		Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK]; //+1;
+
+		Ac2Cfg.field.AcTxop = (pEdcaParm->Txop[QID_AC_VI] * 6) / 10;
+		Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI];
+		Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI];
+		Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI];
+#ifdef INF_AMAZON_SE
+#endif // INF_AMAZON_SE //
+
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+			// Tuning for Wi-Fi WMM S06
+			if (pAd->CommonCfg.bWiFiTest &&
+				pEdcaParm->Aifsn[QID_AC_VI] == 10)
+				Ac2Cfg.field.Aifsn -= 1;
+
+			// Tuning for TGn Wi-Fi 5.2.32
+			// STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta
+			if (STA_TGN_WIFI_ON(pAd) &&
+				pEdcaParm->Aifsn[QID_AC_VI] == 10)
+			{
+				Ac0Cfg.field.Aifsn = 3;
+				Ac2Cfg.field.AcTxop = 5;
+			}
+
+#ifdef RT30xx
+			if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
+			{
+				// Tuning for WiFi WMM S3-T07: connexant legacy sta ==> broadcom 11n sta.
+				Ac2Cfg.field.Aifsn = 5;
+			}
+#endif // RT30xx //
+		}
+#endif // CONFIG_STA_SUPPORT //
+
+		Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO];
+		Ac3Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VO];
+		Ac3Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VO];
+		Ac3Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VO];
+
+//#ifdef WIFI_TEST
+		if (pAd->CommonCfg.bWiFiTest)
+		{
+			if (Ac3Cfg.field.AcTxop == 102)
+			{
+			Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE] ? pEdcaParm->Txop[QID_AC_BE] : 10;
+				Ac0Cfg.field.Aifsn  = pEdcaParm->Aifsn[QID_AC_BE]-1; /* AIFSN must >= 1 */
+			Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
+				Ac1Cfg.field.Aifsn  = pEdcaParm->Aifsn[QID_AC_BK];
+			Ac2Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VI];
+			} /* End of if */
+		}
+//#endif // WIFI_TEST //
+
+		RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
+		RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
+		RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
+		RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
+
+
+		//========================================================
+		//      DMA Register has a copy too.
+		//========================================================
+		csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop;
+		csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop;
+		RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
+
+		csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop;
+		csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop;
+		RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
+
+		CwminCsr.word = 0;
+		CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE];
+		CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK];
+		CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI];
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+			CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO] - 1; //for TGn wifi test
+#endif // CONFIG_STA_SUPPORT //
+		RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
+
+		CwmaxCsr.word = 0;
+		CwmaxCsr.field.Cwmax0 = pEdcaParm->Cwmax[QID_AC_BE];
+		CwmaxCsr.field.Cwmax1 = pEdcaParm->Cwmax[QID_AC_BK];
+		CwmaxCsr.field.Cwmax2 = pEdcaParm->Cwmax[QID_AC_VI];
+		CwmaxCsr.field.Cwmax3 = pEdcaParm->Cwmax[QID_AC_VO];
+		RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
+
+		AifsnCsr.word = 0;
+		AifsnCsr.field.Aifsn0 = Ac0Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BE];
+		AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BK];
+		AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_VI];
+#ifdef INF_AMAZON_SE
+#endif // INF_AMAZON_SE //
+
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+			// Tuning for Wi-Fi WMM S06
+			if (pAd->CommonCfg.bWiFiTest &&
+				pEdcaParm->Aifsn[QID_AC_VI] == 10)
+				AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4;
+
+			// Tuning for TGn Wi-Fi 5.2.32
+			// STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta
+			if (STA_TGN_WIFI_ON(pAd) &&
+				pEdcaParm->Aifsn[QID_AC_VI] == 10)
+			{
+				AifsnCsr.field.Aifsn0 = 3;
+				AifsnCsr.field.Aifsn2 = 7;
+			}
+
+			if (INFRA_ON(pAd))
+				CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_WMM_CAPABLE);
+		}
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+			AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1; //pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test
+#ifdef RT30xx
+		if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
+		{
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+			AifsnCsr.field.Aifsn2 = 0x2; //pEdcaParm->Aifsn[QID_AC_VI]; //for WiFi WMM S4-T04.
+		}
+#endif // RT30xx //
+#endif // CONFIG_STA_SUPPORT //
+		RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word);
+
+		NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
+		if (!ADHOC_ON(pAd))
+		{
+			DBGPRINT(RT_DEBUG_TRACE,("EDCA [#%d]: AIFSN CWmin CWmax  TXOP(us)  ACM\n", pEdcaParm->EdcaUpdateCount));
+			DBGPRINT(RT_DEBUG_TRACE,("     AC_BE      %2d     %2d     %2d      %4d     %d\n",
+									 pEdcaParm->Aifsn[0],
+									 pEdcaParm->Cwmin[0],
+									 pEdcaParm->Cwmax[0],
+									 pEdcaParm->Txop[0]<<5,
+									 pEdcaParm->bACM[0]));
+			DBGPRINT(RT_DEBUG_TRACE,("     AC_BK      %2d     %2d     %2d      %4d     %d\n",
+									 pEdcaParm->Aifsn[1],
+									 pEdcaParm->Cwmin[1],
+									 pEdcaParm->Cwmax[1],
+									 pEdcaParm->Txop[1]<<5,
+									 pEdcaParm->bACM[1]));
+			DBGPRINT(RT_DEBUG_TRACE,("     AC_VI      %2d     %2d     %2d      %4d     %d\n",
+									 pEdcaParm->Aifsn[2],
+									 pEdcaParm->Cwmin[2],
+									 pEdcaParm->Cwmax[2],
+									 pEdcaParm->Txop[2]<<5,
+									 pEdcaParm->bACM[2]));
+			DBGPRINT(RT_DEBUG_TRACE,("     AC_VO      %2d     %2d     %2d      %4d     %d\n",
+									 pEdcaParm->Aifsn[3],
+									 pEdcaParm->Cwmin[3],
+									 pEdcaParm->Cwmax[3],
+									 pEdcaParm->Txop[3]<<5,
+									 pEdcaParm->bACM[3]));
+		}
+	}
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID 	AsicSetSlotTime(
+	IN PRTMP_ADAPTER pAd,
+	IN BOOLEAN bUseShortSlotTime)
+{
+	ULONG	SlotTime;
+	UINT32	RegValue = 0;
+
+#ifdef CONFIG_STA_SUPPORT
+	if (pAd->CommonCfg.Channel > 14)
+		bUseShortSlotTime = TRUE;
+#endif // CONFIG_STA_SUPPORT //
+
+	if (bUseShortSlotTime)
+		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
+	else
+		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
+
+	SlotTime = (bUseShortSlotTime)? 9 : 20;
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		// force using short SLOT time for FAE to demo performance when TxBurst is ON
+		if (pAd->CommonCfg.bEnableTxBurst)
+			SlotTime = 9;
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	//
+	// For some reasons, always set it to short slot time.
+	//
+	// ToDo: Should consider capability with 11B
+	//
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		if (pAd->StaCfg.BssType == BSS_ADHOC)
+			SlotTime = 20;
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue);
+	RegValue = RegValue & 0xFFFFFF00;
+
+	RegValue |= SlotTime;
+
+	RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue);
+}
+
+/*
+	========================================================================
+	Description:
+		Add Shared key information into ASIC.
+		Update shared key, TxMic and RxMic to Asic Shared key table
+		Update its cipherAlg to Asic Shared key Mode.
+
+    Return:
+	========================================================================
+*/
+VOID AsicAddSharedKeyEntry(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR		 BssIndex,
+	IN UCHAR		 KeyIdx,
+	IN UCHAR		 CipherAlg,
+	IN PUCHAR		 pKey,
+	IN PUCHAR		 pTxMic,
+	IN PUCHAR		 pRxMic)
+{
+	ULONG offset; //, csr0;
+	SHAREDKEY_MODE_STRUC csr1;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,KeyIdx));
+//============================================================================================
+
+	DBGPRINT(RT_DEBUG_TRACE,("AsicAddSharedKeyEntry: %s key #%d\n", CipherName[CipherAlg], BssIndex*4 + KeyIdx));
+	DBGPRINT_RAW(RT_DEBUG_TRACE, (" 	Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+		pKey[0],pKey[1],pKey[2],pKey[3],pKey[4],pKey[5],pKey[6],pKey[7],pKey[8],pKey[9],pKey[10],pKey[11],pKey[12],pKey[13],pKey[14],pKey[15]));
+	if (pRxMic)
+	{
+		DBGPRINT_RAW(RT_DEBUG_TRACE, (" 	Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+			pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
+	}
+	if (pTxMic)
+	{
+		DBGPRINT_RAW(RT_DEBUG_TRACE, (" 	Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+			pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
+	}
+//============================================================================================
+	//
+	// fill key material - key + TX MIC + RX MIC
+	//
+
+#ifdef RT2870
+{
+	offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE;
+	RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_SHARE_KEY);
+
+	offset += MAX_LEN_OF_SHARE_KEY;
+	if (pTxMic)
+	{
+		RTUSBMultiWrite(pAd, offset, pTxMic, 8);
+	}
+
+	offset += 8;
+	if (pRxMic)
+	{
+		RTUSBMultiWrite(pAd, offset, pRxMic, 8);
+	}
+}
+#endif // RT2870 //
+
+	//
+	// Update cipher algorithm. WSTA always use BSS0
+	//
+	RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
+	DBGPRINT(RT_DEBUG_TRACE,("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n", BssIndex,KeyIdx, csr1.word));
+	if ((BssIndex%2) == 0)
+	{
+		if (KeyIdx == 0)
+			csr1.field.Bss0Key0CipherAlg = CipherAlg;
+		else if (KeyIdx == 1)
+			csr1.field.Bss0Key1CipherAlg = CipherAlg;
+		else if (KeyIdx == 2)
+			csr1.field.Bss0Key2CipherAlg = CipherAlg;
+		else
+			csr1.field.Bss0Key3CipherAlg = CipherAlg;
+	}
+	else
+	{
+		if (KeyIdx == 0)
+			csr1.field.Bss1Key0CipherAlg = CipherAlg;
+		else if (KeyIdx == 1)
+			csr1.field.Bss1Key1CipherAlg = CipherAlg;
+		else if (KeyIdx == 2)
+			csr1.field.Bss1Key2CipherAlg = CipherAlg;
+		else
+			csr1.field.Bss1Key3CipherAlg = CipherAlg;
+	}
+	DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
+	RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
+
+}
+
+//	IRQL = DISPATCH_LEVEL
+VOID AsicRemoveSharedKeyEntry(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR		 BssIndex,
+	IN UCHAR		 KeyIdx)
+{
+	//ULONG SecCsr0;
+	SHAREDKEY_MODE_STRUC csr1;
+
+	DBGPRINT(RT_DEBUG_TRACE,("AsicRemoveSharedKeyEntry: #%d \n", BssIndex*4 + KeyIdx));
+
+	RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
+	if ((BssIndex%2) == 0)
+	{
+		if (KeyIdx == 0)
+			csr1.field.Bss0Key0CipherAlg = 0;
+		else if (KeyIdx == 1)
+			csr1.field.Bss0Key1CipherAlg = 0;
+		else if (KeyIdx == 2)
+			csr1.field.Bss0Key2CipherAlg = 0;
+		else
+			csr1.field.Bss0Key3CipherAlg = 0;
+	}
+	else
+	{
+		if (KeyIdx == 0)
+			csr1.field.Bss1Key0CipherAlg = 0;
+		else if (KeyIdx == 1)
+			csr1.field.Bss1Key1CipherAlg = 0;
+		else if (KeyIdx == 2)
+			csr1.field.Bss1Key2CipherAlg = 0;
+		else
+			csr1.field.Bss1Key3CipherAlg = 0;
+	}
+	DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
+	RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
+	ASSERT(BssIndex < 4);
+	ASSERT(KeyIdx < 4);
+
+}
+
+
+VOID AsicUpdateWCIDAttribute(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT		WCID,
+	IN UCHAR		BssIndex,
+	IN UCHAR        CipherAlg,
+	IN BOOLEAN		bUsePairewiseKeyTable)
+{
+	ULONG   WCIDAttri = 0, offset;
+
+	//
+	// Update WCID attribute.
+	// Only TxKey could update WCID attribute.
+	//
+	offset = MAC_WCID_ATTRIBUTE_BASE + (WCID * HW_WCID_ATTRI_SIZE);
+	WCIDAttri = (BssIndex << 4) | (CipherAlg << 1) | (bUsePairewiseKeyTable);
+	RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
+}
+
+VOID AsicUpdateWCIDIVEIV(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT		WCID,
+	IN ULONG        uIV,
+	IN ULONG        uEIV)
+{
+	ULONG	offset;
+
+	offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
+
+	RTMP_IO_WRITE32(pAd, offset, uIV);
+	RTMP_IO_WRITE32(pAd, offset + 4, uEIV);
+}
+
+VOID AsicUpdateRxWCIDTable(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT		WCID,
+	IN PUCHAR        pAddr)
+{
+	ULONG offset;
+	ULONG Addr;
+
+	offset = MAC_WCID_BASE + (WCID * HW_WCID_ENTRY_SIZE);
+	Addr = pAddr[0] + (pAddr[1] << 8) +(pAddr[2] << 16) +(pAddr[3] << 24);
+	RTMP_IO_WRITE32(pAd, offset, Addr);
+	Addr = pAddr[4] + (pAddr[5] << 8);
+	RTMP_IO_WRITE32(pAd, offset + 4, Addr);
+}
+
+
+/*
+    ========================================================================
+
+    Routine Description:
+        Set Cipher Key, Cipher algorithm, IV/EIV to Asic
+
+    Arguments:
+        pAd                     Pointer to our adapter
+        WCID                    WCID Entry number.
+        BssIndex                BSSID index, station or none multiple BSSID support
+                                this value should be 0.
+        KeyIdx                  This KeyIdx will set to IV's KeyID if bTxKey enabled
+        pCipherKey              Pointer to Cipher Key.
+        bUsePairewiseKeyTable   TRUE means saved the key in SharedKey table,
+                                otherwise PairewiseKey table
+        bTxKey                  This is the transmit key if enabled.
+
+    Return Value:
+        None
+
+    Note:
+        This routine will set the relative key stuff to Asic including WCID attribute,
+        Cipher Key, Cipher algorithm and IV/EIV.
+
+        IV/EIV will be update if this CipherKey is the transmission key because
+        ASIC will base on IV's KeyID value to select Cipher Key.
+
+        If bTxKey sets to FALSE, this is not the TX key, but it could be
+        RX key
+
+    	For AP mode bTxKey must be always set to TRUE.
+    ========================================================================
+*/
+VOID AsicAddKeyEntry(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT		WCID,
+	IN UCHAR		BssIndex,
+	IN UCHAR		KeyIdx,
+	IN PCIPHER_KEY	pCipherKey,
+	IN BOOLEAN		bUsePairewiseKeyTable,
+	IN BOOLEAN		bTxKey)
+{
+	ULONG	offset;
+//	ULONG   WCIDAttri = 0;
+	UCHAR	IV4 = 0;
+	PUCHAR		pKey = pCipherKey->Key;
+//	ULONG		KeyLen = pCipherKey->KeyLen;
+	PUCHAR		pTxMic = pCipherKey->TxMic;
+	PUCHAR		pRxMic = pCipherKey->RxMic;
+	PUCHAR		pTxtsc = pCipherKey->TxTsc;
+	UCHAR		CipherAlg = pCipherKey->CipherAlg;
+	SHAREDKEY_MODE_STRUC csr1;
+
+//	ASSERT(KeyLen <= MAX_LEN_OF_PEER_KEY);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n"));
+	//
+	// 1.) decide key table offset
+	//
+	if (bUsePairewiseKeyTable)
+		offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
+	else
+		offset = SHARED_KEY_TABLE_BASE + (4 * BssIndex + KeyIdx) * HW_KEY_ENTRY_SIZE;
+
+	//
+	// 2.) Set Key to Asic
+	//
+	//for (i = 0; i < KeyLen; i++)
+
+#ifdef RT2870
+	RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_PEER_KEY);
+	offset += MAX_LEN_OF_PEER_KEY;
+
+	//
+	// 3.) Set MIC key if available
+	//
+	if (pTxMic)
+	{
+		RTUSBMultiWrite(pAd, offset, pTxMic, 8);
+	}
+	offset += LEN_TKIP_TXMICK;
+
+	if (pRxMic)
+	{
+		RTUSBMultiWrite(pAd, offset, pRxMic, 8);
+	}
+#endif // RT2870 //
+
+	//
+	// 4.) Modify IV/EIV if needs
+	//     This will force Asic to use this key ID by setting IV.
+	//
+	if (bTxKey)
+	{
+
+#ifdef RT2870
+		UINT32 tmpVal;
+
+		//
+		// Write IV
+		//
+		IV4 = (KeyIdx << 6);
+		if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES))
+			IV4 |= 0x20;  // turn on extension bit means EIV existence
+
+		tmpVal = pTxtsc[1] + (((pTxtsc[1] | 0x20) & 0x7f) << 8) + (pTxtsc[0] << 16) + (IV4 << 24);
+		RTMP_IO_WRITE32(pAd, offset, tmpVal);
+
+		//
+		// Write EIV
+		//
+		offset += 4;
+		RTMP_IO_WRITE32(pAd, offset, *(PUINT32)&pCipherKey->TxTsc[2]);
+#endif // RT2870 //
+		AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg, bUsePairewiseKeyTable);
+	}
+
+	if (!bUsePairewiseKeyTable)
+	{
+		//
+		// Only update the shared key security mode
+		//
+		RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), &csr1.word);
+		if ((BssIndex % 2) == 0)
+		{
+			if (KeyIdx == 0)
+				csr1.field.Bss0Key0CipherAlg = CipherAlg;
+			else if (KeyIdx == 1)
+				csr1.field.Bss0Key1CipherAlg = CipherAlg;
+			else if (KeyIdx == 2)
+				csr1.field.Bss0Key2CipherAlg = CipherAlg;
+			else
+				csr1.field.Bss0Key3CipherAlg = CipherAlg;
+		}
+		else
+		{
+			if (KeyIdx == 0)
+				csr1.field.Bss1Key0CipherAlg = CipherAlg;
+			else if (KeyIdx == 1)
+				csr1.field.Bss1Key1CipherAlg = CipherAlg;
+			else if (KeyIdx == 2)
+				csr1.field.Bss1Key2CipherAlg = CipherAlg;
+			else
+				csr1.field.Bss1Key3CipherAlg = CipherAlg;
+		}
+		RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), csr1.word);
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<== AsicAddKeyEntry\n"));
+}
+
+
+/*
+	========================================================================
+	Description:
+		Add Pair-wise key material into ASIC.
+		Update pairwise key, TxMic and RxMic to Asic Pair-wise key table
+
+    Return:
+	========================================================================
+*/
+VOID AsicAddPairwiseKeyEntry(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR        pAddr,
+	IN UCHAR		WCID,
+	IN CIPHER_KEY		 *pCipherKey)
+{
+	INT i;
+	ULONG 		offset;
+	PUCHAR		 pKey = pCipherKey->Key;
+	PUCHAR		 pTxMic = pCipherKey->TxMic;
+	PUCHAR		 pRxMic = pCipherKey->RxMic;
+#ifdef DBG
+	UCHAR		CipherAlg = pCipherKey->CipherAlg;
+#endif // DBG //
+
+	// EKEY
+	offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
+#ifdef RT2870
+	RTUSBMultiWrite(pAd, offset, &pCipherKey->Key[0], MAX_LEN_OF_PEER_KEY);
+#endif // RT2870 //
+	for (i=0; i<MAX_LEN_OF_PEER_KEY; i+=4)
+	{
+		UINT32 Value;
+		RTMP_IO_READ32(pAd, offset + i, &Value);
+	}
+
+	offset += MAX_LEN_OF_PEER_KEY;
+
+	//  MIC KEY
+	if (pTxMic)
+	{
+#ifdef RT2870
+		RTUSBMultiWrite(pAd, offset, &pCipherKey->TxMic[0], 8);
+#endif // RT2870 //
+	}
+	offset += 8;
+	if (pRxMic)
+	{
+#ifdef RT2870
+		RTUSBMultiWrite(pAd, offset, &pCipherKey->RxMic[0], 8);
+#endif // RT2870 //
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE,("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n",WCID, CipherName[CipherAlg]));
+	DBGPRINT(RT_DEBUG_TRACE,("	Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+		pKey[0],pKey[1],pKey[2],pKey[3],pKey[4],pKey[5],pKey[6],pKey[7],pKey[8],pKey[9],pKey[10],pKey[11],pKey[12],pKey[13],pKey[14],pKey[15]));
+	if (pRxMic)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("	Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+			pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
+	}
+	if (pTxMic)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("	Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+			pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
+	}
+}
+/*
+	========================================================================
+	Description:
+		Remove Pair-wise key material from ASIC.
+
+    Return:
+	========================================================================
+*/
+VOID AsicRemovePairwiseKeyEntry(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR		 BssIdx,
+	IN UCHAR		 Wcid)
+{
+	ULONG		WCIDAttri;
+	USHORT		offset;
+
+	// re-set the entry's WCID attribute as OPEN-NONE.
+	offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
+	WCIDAttri = (BssIdx<<4) | PAIRWISEKEYTABLE;
+	RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
+}
+
+BOOLEAN AsicSendCommandToMcu(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR		 Command,
+	IN UCHAR		 Token,
+	IN UCHAR		 Arg0,
+	IN UCHAR		 Arg1)
+{
+	HOST_CMD_CSR_STRUC	H2MCmd;
+	H2M_MAILBOX_STRUC	H2MMailbox;
+	ULONG				i = 0;
+	do
+	{
+		RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
+		if (H2MMailbox.field.Owner == 0)
+			break;
+
+		RTMPusecDelay(2);
+	} while(i++ < 100);
+
+	if (i >= 100)
+	{
+		{
+		DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
+		}
+		return FALSE;
+	}
+
+
+	H2MMailbox.field.Owner	  = 1;	   // pass ownership to MCU
+	H2MMailbox.field.CmdToken = Token;
+	H2MMailbox.field.HighByte = Arg1;
+	H2MMailbox.field.LowByte  = Arg0;
+	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
+
+	H2MCmd.word 			  = 0;
+	H2MCmd.field.HostCommand  = Command;
+	RTMP_IO_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
+
+	if (Command != 0x80)
+	{
+	}
+
+	return TRUE;
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Verify the support rate for different PHY type
+
+	Arguments:
+		pAd 				Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+
+	========================================================================
+*/
+VOID	RTMPCheckRates(
+	IN		PRTMP_ADAPTER	pAd,
+	IN OUT	UCHAR			SupRate[],
+	IN OUT	UCHAR			*SupRateLen)
+{
+	UCHAR	RateIdx, i, j;
+	UCHAR	NewRate[12], NewRateLen;
+
+	NewRateLen = 0;
+
+	if (pAd->CommonCfg.PhyMode == PHY_11B)
+		RateIdx = 4;
+	else
+		RateIdx = 12;
+
+	// Check for support rates exclude basic rate bit
+	for (i = 0; i < *SupRateLen; i++)
+		for (j = 0; j < RateIdx; j++)
+			if ((SupRate[i] & 0x7f) == RateIdTo500Kbps[j])
+				NewRate[NewRateLen++] = SupRate[i];
+
+	*SupRateLen = NewRateLen;
+	NdisMoveMemory(SupRate, NewRate, NewRateLen);
+}
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef DOT11_N_SUPPORT
+BOOLEAN RTMPCheckChannel(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR		CentralChannel,
+	IN UCHAR		Channel)
+{
+	UCHAR		k;
+	UCHAR		UpperChannel = 0, LowerChannel = 0;
+	UCHAR		NoEffectChannelinList = 0;
+
+	// Find upper and lower channel according to 40MHz current operation.
+	if (CentralChannel < Channel)
+	{
+		UpperChannel = Channel;
+		if (CentralChannel > 2)
+			LowerChannel = CentralChannel - 2;
+		else
+			return FALSE;
+	}
+	else if (CentralChannel > Channel)
+	{
+		UpperChannel = CentralChannel + 2;
+		LowerChannel = Channel;
+	}
+
+	for (k = 0;k < pAd->ChannelListNum;k++)
+	{
+		if (pAd->ChannelList[k].Channel == UpperChannel)
+		{
+			NoEffectChannelinList ++;
+		}
+		if (pAd->ChannelList[k].Channel == LowerChannel)
+		{
+			NoEffectChannelinList ++;
+		}
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE,("Total Channel in Channel List = [%d]\n", NoEffectChannelinList));
+	if (NoEffectChannelinList == 2)
+		return TRUE;
+	else
+		return FALSE;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Verify the support rate for HT phy type
+
+	Arguments:
+		pAd 				Pointer to our adapter
+
+	Return Value:
+		FALSE if pAd->CommonCfg.SupportedHtPhy doesn't accept the pHtCapability.  (AP Mode)
+
+	IRQL = PASSIVE_LEVEL
+
+	========================================================================
+*/
+BOOLEAN 	RTMPCheckHt(
+	IN	PRTMP_ADAPTER			pAd,
+	IN	UCHAR					Wcid,
+	IN 	HT_CAPABILITY_IE		*pHtCapability,
+	IN 	ADD_HT_INFO_IE			*pAddHtInfo)
+{
+	if (Wcid >= MAX_LEN_OF_MAC_TABLE)
+		return FALSE;
+
+	// If use AMSDU, set flag.
+	if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable)
+		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_AMSDU_INUSED);
+	// Save Peer Capability
+	if (pHtCapability->HtCapInfo.ShortGIfor20)
+		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_SGI20_CAPABLE);
+	if (pHtCapability->HtCapInfo.ShortGIfor40)
+		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_SGI40_CAPABLE);
+	if (pHtCapability->HtCapInfo.TxSTBC)
+		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_TxSTBC_CAPABLE);
+	if (pHtCapability->HtCapInfo.RxSTBC)
+		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_RxSTBC_CAPABLE);
+	if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport)
+	{
+		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_RDG_CAPABLE);
+	}
+
+	if (Wcid < MAX_LEN_OF_MAC_TABLE)
+	{
+		pAd->MacTab.Content[Wcid].MpduDensity = pHtCapability->HtCapParm.MpduDensity;
+	}
+
+	// Will check ChannelWidth for MCSSet[4] below
+	pAd->MlmeAux.HtCapability.MCSSet[4] = 0x1;
+    switch (pAd->CommonCfg.RxStream)
+	{
+		case 1:
+			pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
+			pAd->MlmeAux.HtCapability.MCSSet[1] = 0x00;
+            pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
+            pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
+			break;
+		case 2:
+			pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
+			pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
+            pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
+            pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
+			break;
+		case 3:
+			pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
+			pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
+            pAd->MlmeAux.HtCapability.MCSSet[2] = 0xff;
+            pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
+			break;
+	}
+
+	pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth = pAddHtInfo->AddHtInfo.RecomWidth & pAd->CommonCfg.DesiredHtPhy.ChannelWidth;
+
+    DBGPRINT(RT_DEBUG_TRACE, ("RTMPCheckHt:: HtCapInfo.ChannelWidth=%d, RecomWidth=%d, DesiredHtPhy.ChannelWidth=%d, BW40MAvailForA/G=%d/%d, PhyMode=%d \n",
+		pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth, pAddHtInfo->AddHtInfo.RecomWidth, pAd->CommonCfg.DesiredHtPhy.ChannelWidth,
+		pAd->NicConfig2.field.BW40MAvailForA, pAd->NicConfig2.field.BW40MAvailForG, pAd->CommonCfg.PhyMode));
+
+	pAd->MlmeAux.HtCapability.HtCapInfo.GF =  pHtCapability->HtCapInfo.GF &pAd->CommonCfg.DesiredHtPhy.GF;
+
+	// Send Assoc Req with my HT capability.
+	pAd->MlmeAux.HtCapability.HtCapInfo.AMsduSize =  pAd->CommonCfg.DesiredHtPhy.AmsduSize;
+	pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs =  pAd->CommonCfg.DesiredHtPhy.MimoPs;
+	pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20 =  (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20) & (pHtCapability->HtCapInfo.ShortGIfor20);
+	pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40 =  (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40) & (pHtCapability->HtCapInfo.ShortGIfor40);
+	pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC =  (pAd->CommonCfg.DesiredHtPhy.TxSTBC)&(pHtCapability->HtCapInfo.RxSTBC);
+	pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC =  (pAd->CommonCfg.DesiredHtPhy.RxSTBC)&(pHtCapability->HtCapInfo.TxSTBC);
+	pAd->MlmeAux.HtCapability.HtCapParm.MaxRAmpduFactor = pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor;
+    pAd->MlmeAux.HtCapability.HtCapParm.MpduDensity = pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity;
+	pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = pHtCapability->ExtHtCapInfo.PlusHTC;
+	pAd->MacTab.Content[Wcid].HTCapability.ExtHtCapInfo.PlusHTC = pHtCapability->ExtHtCapInfo.PlusHTC;
+	if (pAd->CommonCfg.bRdg)
+	{
+		pAd->MlmeAux.HtCapability.ExtHtCapInfo.RDGSupport = pHtCapability->ExtHtCapInfo.RDGSupport;
+        pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = 1;
+	}
+
+    if (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_20)
+        pAd->MlmeAux.HtCapability.MCSSet[4] = 0x0;  // BW20 can't transmit MCS32
+
+	COPY_AP_HTSETTINGS_FROM_BEACON(pAd, pHtCapability);
+	return TRUE;
+}
+#endif // DOT11_N_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+/*
+	========================================================================
+
+	Routine Description:
+		Verify the support rate for different PHY type
+
+	Arguments:
+		pAd 				Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+
+	========================================================================
+*/
+VOID RTMPUpdateMlmeRate(
+	IN PRTMP_ADAPTER	pAd)
+{
+	UCHAR	MinimumRate;
+	UCHAR	ProperMlmeRate; //= RATE_54;
+	UCHAR	i, j, RateIdx = 12; //1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
+	BOOLEAN	bMatch = FALSE;
+
+	switch (pAd->CommonCfg.PhyMode)
+	{
+		case PHY_11B:
+			ProperMlmeRate = RATE_11;
+			MinimumRate = RATE_1;
+			break;
+		case PHY_11BG_MIXED:
+#ifdef DOT11_N_SUPPORT
+		case PHY_11ABGN_MIXED:
+		case PHY_11BGN_MIXED:
+#endif // DOT11_N_SUPPORT //
+			if ((pAd->MlmeAux.SupRateLen == 4) &&
+				(pAd->MlmeAux.ExtRateLen == 0))
+				// B only AP
+				ProperMlmeRate = RATE_11;
+			else
+				ProperMlmeRate = RATE_24;
+
+			if (pAd->MlmeAux.Channel <= 14)
+				MinimumRate = RATE_1;
+			else
+				MinimumRate = RATE_6;
+			break;
+		case PHY_11A:
+#ifdef DOT11_N_SUPPORT
+		case PHY_11N_2_4G:	// rt2860 need to check mlmerate for 802.11n
+		case PHY_11GN_MIXED:
+		case PHY_11AGN_MIXED:
+		case PHY_11AN_MIXED:
+		case PHY_11N_5G:
+#endif // DOT11_N_SUPPORT //
+			ProperMlmeRate = RATE_24;
+			MinimumRate = RATE_6;
+			break;
+		case PHY_11ABG_MIXED:
+			ProperMlmeRate = RATE_24;
+			if (pAd->MlmeAux.Channel <= 14)
+			   MinimumRate = RATE_1;
+			else
+				MinimumRate = RATE_6;
+			break;
+		default: // error
+			ProperMlmeRate = RATE_1;
+			MinimumRate = RATE_1;
+			break;
+	}
+
+	for (i = 0; i < pAd->MlmeAux.SupRateLen; i++)
+	{
+		for (j = 0; j < RateIdx; j++)
+		{
+			if ((pAd->MlmeAux.SupRate[i] & 0x7f) == RateIdTo500Kbps[j])
+			{
+				if (j == ProperMlmeRate)
+				{
+					bMatch = TRUE;
+					break;
+				}
+			}
+		}
+
+		if (bMatch)
+			break;
+	}
+
+	if (bMatch == FALSE)
+	{
+		for (i = 0; i < pAd->MlmeAux.ExtRateLen; i++)
+		{
+			for (j = 0; j < RateIdx; j++)
+			{
+				if ((pAd->MlmeAux.ExtRate[i] & 0x7f) == RateIdTo500Kbps[j])
+				{
+					if (j == ProperMlmeRate)
+					{
+						bMatch = TRUE;
+						break;
+					}
+				}
+			}
+
+			if (bMatch)
+				break;
+		}
+	}
+
+	if (bMatch == FALSE)
+	{
+		ProperMlmeRate = MinimumRate;
+	}
+
+	pAd->CommonCfg.MlmeRate = MinimumRate;
+	pAd->CommonCfg.RtsRate = ProperMlmeRate;
+	if (pAd->CommonCfg.MlmeRate >= RATE_6)
+	{
+		pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
+		pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
+		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+	}
+	else
+	{
+		pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
+		pAd->CommonCfg.MlmeTransmit.field.MCS = pAd->CommonCfg.MlmeRate;
+		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_CCK;
+		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = pAd->CommonCfg.MlmeRate;
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateMlmeRate ==>   MlmeTransmit = 0x%x  \n" , pAd->CommonCfg.MlmeTransmit.word));
+}
+
+CHAR RTMPMaxRssi(
+	IN PRTMP_ADAPTER	pAd,
+	IN CHAR				Rssi0,
+	IN CHAR				Rssi1,
+	IN CHAR				Rssi2)
+{
+	CHAR	larger = -127;
+
+	if ((pAd->Antenna.field.RxPath == 1) && (Rssi0 != 0))
+	{
+		larger = Rssi0;
+	}
+
+	if ((pAd->Antenna.field.RxPath >= 2) && (Rssi1 != 0))
+	{
+		larger = max(Rssi0, Rssi1);
+	}
+
+	if ((pAd->Antenna.field.RxPath == 3) && (Rssi2 != 0))
+	{
+		larger = max(larger, Rssi2);
+	}
+
+	if (larger == -127)
+		larger = 0;
+
+	return larger;
+}
+
+
+// Antenna divesity use GPIO3 and EESK pin for control
+// Antenna and EEPROM access are both using EESK pin,
+// Therefor we should avoid accessing EESK at the same time
+// Then restore antenna after EEPROM access
+VOID AsicSetRxAnt(
+	IN PRTMP_ADAPTER	pAd,
+	IN UCHAR			Ant)
+{
+#ifdef RT30xx
+	UINT32	Value;
+	UINT32	x;
+
+	if ((pAd->EepromAccess)										||
+		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS))	||
+		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))	||
+		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))			||
+		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+	{
+		return;
+	}
+
+	// the antenna selection is through firmware and MAC register(GPIO3)
+	if (Ant == 0)
+	{
+		// Main antenna
+		RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+		x |= (EESK);
+		RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+		RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
+		Value &= ~(0x0808);
+		RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
+		DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to main antenna\n"));
+	}
+	else
+	{
+		// Aux antenna
+		RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+		x &= ~(EESK);
+		RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+		RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
+		Value &= ~(0x0808);
+		Value |= 0x08;
+		RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
+		DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to aux antenna\n"));
+	}
+#endif // RT30xx //
+}
+
+
+/*
+    ========================================================================
+    Routine Description:
+        Periodic evaluate antenna link status
+
+    Arguments:
+        pAd         - Adapter pointer
+
+    Return Value:
+        None
+
+    ========================================================================
+*/
+VOID AsicEvaluateRxAnt(
+	IN PRTMP_ADAPTER	pAd)
+{
+	UCHAR	BBPR3 = 0;
+
+#ifdef RALINK_ATE
+	if (ATE_ON(pAd))
+		return;
+#endif // RALINK_ATE //
+
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS	|
+							fRTMP_ADAPTER_HALT_IN_PROGRESS	|
+							fRTMP_ADAPTER_RADIO_OFF			|
+							fRTMP_ADAPTER_NIC_NOT_EXIST		|
+							fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) ||
+							OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
+#ifdef RT30xx
+							|| (pAd->EepromAccess)
+#endif // RT30xx //
+							)
+		return;
+
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		//if (pAd->StaCfg.Psm == PWR_SAVE)
+		//	return;
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	// two antenna selection mechanism- one is antenna diversity, the other is failed antenna remove
+	// one is antenna diversity:there is only one antenna can rx and tx
+	// the other is failed antenna remove:two physical antenna can rx and tx
+	if (pAd->NicConfig2.field.AntDiversity)
+	{
+		DBGPRINT(RT_DEBUG_TRACE,("AntDiv - before evaluate Pair1-Ant (%d,%d)\n",
+			pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt));
+
+		AsicSetRxAnt(pAd, pAd->RxAnt.Pair1SecondaryRxAnt);
+
+		pAd->RxAnt.EvaluatePeriod = 1; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt
+		pAd->RxAnt.FirstPktArrivedWhenEvaluate = FALSE;
+		pAd->RxAnt.RcvPktNumWhenEvaluate = 0;
+
+		// a one-shot timer to end the evalution
+		// dynamic adjust antenna evaluation period according to the traffic
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+			RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 100);
+		else
+			RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
+	}
+	else
+	{
+
+#ifdef CONFIG_STA_SUPPORT
+		if (pAd->StaCfg.Psm == PWR_SAVE)
+			return;
+#endif // CONFIG_STA_SUPPORT //
+
+		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
+		BBPR3 &= (~0x18);
+		if(pAd->Antenna.field.RxPath == 3)
+		{
+			BBPR3 |= (0x10);
+		}
+		else if(pAd->Antenna.field.RxPath == 2)
+		{
+			BBPR3 |= (0x8);
+		}
+		else if(pAd->Antenna.field.RxPath == 1)
+		{
+			BBPR3 |= (0x0);
+		}
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
+			)
+		{
+			ULONG	TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
+									pAd->RalinkCounters.OneSecTxRetryOkCount +
+									pAd->RalinkCounters.OneSecTxFailCount;
+
+			// dynamic adjust antenna evaluation period according to the traffic
+			if (TxTotalCnt > 50)
+			{
+				RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 20);
+				pAd->Mlme.bLowThroughput = FALSE;
+			}
+			else
+			{
+				RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
+				pAd->Mlme.bLowThroughput = TRUE;
+			}
+		}
+	}
+}
+
+/*
+    ========================================================================
+    Routine Description:
+        After evaluation, check antenna link status
+
+    Arguments:
+        pAd         - Adapter pointer
+
+    Return Value:
+        None
+
+    ========================================================================
+*/
+VOID AsicRxAntEvalTimeout(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3)
+{
+	RTMP_ADAPTER	*pAd = (RTMP_ADAPTER *)FunctionContext;
+#ifdef CONFIG_STA_SUPPORT
+	UCHAR			BBPR3 = 0;
+	CHAR			larger = -127, rssi0, rssi1, rssi2;
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef RALINK_ATE
+	if (ATE_ON(pAd))
+		return;
+#endif // RALINK_ATE //
+
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS	|
+							fRTMP_ADAPTER_HALT_IN_PROGRESS	|
+							fRTMP_ADAPTER_RADIO_OFF			|
+							fRTMP_ADAPTER_NIC_NOT_EXIST) ||
+							OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
+#ifdef RT30xx
+							|| (pAd->EepromAccess)
+#endif // RT30xx //
+							)
+		return;
+
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		//if (pAd->StaCfg.Psm == PWR_SAVE)
+		//	return;
+
+		if (pAd->NicConfig2.field.AntDiversity)
+		{
+			if ((pAd->RxAnt.RcvPktNumWhenEvaluate != 0) && (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >= pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt]))
+			{
+				UCHAR			temp;
+
+				//
+				// select PrimaryRxAntPair
+				//    Role change, Used Pair1SecondaryRxAnt as PrimaryRxAntPair.
+				//    Since Pair1SecondaryRxAnt Quality good than Pair1PrimaryRxAnt
+				//
+				temp = pAd->RxAnt.Pair1PrimaryRxAnt;
+				pAd->RxAnt.Pair1PrimaryRxAnt = pAd->RxAnt.Pair1SecondaryRxAnt;
+				pAd->RxAnt.Pair1SecondaryRxAnt = temp;
+
+				pAd->RxAnt.Pair1LastAvgRssi = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >> 3);
+				pAd->RxAnt.EvaluateStableCnt = 0;
+			}
+			else
+			{
+				// if the evaluated antenna is not better than original, switch back to original antenna
+				AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
+				pAd->RxAnt.EvaluateStableCnt ++;
+			}
+
+			pAd->RxAnt.EvaluatePeriod = 0; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt
+
+			DBGPRINT(RT_DEBUG_TRACE,("AsicRxAntEvalAction::After Eval(fix in #%d), <%d, %d>, RcvPktNumWhenEvaluate=%ld\n",
+					pAd->RxAnt.Pair1PrimaryRxAnt, (pAd->RxAnt.Pair1AvgRssi[0] >> 3), (pAd->RxAnt.Pair1AvgRssi[1] >> 3), pAd->RxAnt.RcvPktNumWhenEvaluate));
+		}
+		else
+		{
+			if (pAd->StaCfg.Psm == PWR_SAVE)
+				return;
+
+			// if the traffic is low, use average rssi as the criteria
+			if (pAd->Mlme.bLowThroughput == TRUE)
+			{
+				rssi0 = pAd->StaCfg.RssiSample.LastRssi0;
+				rssi1 = pAd->StaCfg.RssiSample.LastRssi1;
+				rssi2 = pAd->StaCfg.RssiSample.LastRssi2;
+			}
+			else
+			{
+				rssi0 = pAd->StaCfg.RssiSample.AvgRssi0;
+				rssi1 = pAd->StaCfg.RssiSample.AvgRssi1;
+				rssi2 = pAd->StaCfg.RssiSample.AvgRssi2;
+			}
+
+			if(pAd->Antenna.field.RxPath == 3)
+			{
+				larger = max(rssi0, rssi1);
+
+				if (larger > (rssi2 + 20))
+					pAd->Mlme.RealRxPath = 2;
+				else
+					pAd->Mlme.RealRxPath = 3;
+			}
+			else if(pAd->Antenna.field.RxPath == 2)
+			{
+				if (rssi0 > (rssi1 + 20))
+					pAd->Mlme.RealRxPath = 1;
+				else
+					pAd->Mlme.RealRxPath = 2;
+			}
+
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
+			BBPR3 &= (~0x18);
+			if(pAd->Mlme.RealRxPath == 3)
+			{
+				BBPR3 |= (0x10);
+			}
+			else if(pAd->Mlme.RealRxPath == 2)
+			{
+				BBPR3 |= (0x8);
+			}
+			else if(pAd->Mlme.RealRxPath == 1)
+			{
+				BBPR3 |= (0x0);
+			}
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
+		}
+	}
+
+#endif // CONFIG_STA_SUPPORT //
+
+}
+
+
+
+VOID APSDPeriodicExec(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3)
+{
+	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+		return;
+
+	pAd->CommonCfg.TriggerTimerCount++;
+
+// Driver should not send trigger frame, it should be send by application layer
+/*
+	if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable
+		&& (pAd->CommonCfg.bNeedSendTriggerFrame ||
+		(((pAd->CommonCfg.TriggerTimerCount%20) == 19) && (!pAd->CommonCfg.bAPSDAC_BE || !pAd->CommonCfg.bAPSDAC_BK || !pAd->CommonCfg.bAPSDAC_VI || !pAd->CommonCfg.bAPSDAC_VO))))
+	{
+		DBGPRINT(RT_DEBUG_TRACE,("Sending trigger frame and enter service period when support APSD\n"));
+		RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
+		pAd->CommonCfg.bNeedSendTriggerFrame = FALSE;
+		pAd->CommonCfg.TriggerTimerCount = 0;
+		pAd->CommonCfg.bInServicePeriod = TRUE;
+	}*/
+}
+
+/*
+    ========================================================================
+    Routine Description:
+        Set/reset MAC registers according to bPiggyBack parameter
+
+    Arguments:
+        pAd         - Adapter pointer
+        bPiggyBack  - Enable / Disable Piggy-Back
+
+    Return Value:
+        None
+
+    ========================================================================
+*/
+VOID RTMPSetPiggyBack(
+    IN PRTMP_ADAPTER    pAd,
+    IN BOOLEAN          bPiggyBack)
+{
+	TX_LINK_CFG_STRUC  TxLinkCfg;
+
+	RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
+
+	TxLinkCfg.field.TxCFAckEn = bPiggyBack;
+	RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
+}
+
+/*
+    ========================================================================
+    Routine Description:
+        check if this entry need to switch rate automatically
+
+    Arguments:
+        pAd
+        pEntry
+
+    Return Value:
+        TURE
+        FALSE
+
+    ========================================================================
+*/
+BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(
+	IN PRTMP_ADAPTER    pAd,
+	IN PMAC_TABLE_ENTRY	pEntry)
+{
+	BOOLEAN		result = TRUE;
+
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		// only associated STA counts
+		if (pEntry && (pEntry->ValidAsCLI) && (pEntry->Sst == SST_ASSOC))
+		{
+			result = pAd->StaCfg.bAutoTxRateSwitch;
+		}
+		else
+			result = FALSE;
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+
+
+	return result;
+}
+
+
+BOOLEAN RTMPAutoRateSwitchCheck(
+	IN PRTMP_ADAPTER    pAd)
+{
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		if (pAd->StaCfg.bAutoTxRateSwitch)
+			return TRUE;
+	}
+#endif // CONFIG_STA_SUPPORT //
+	return FALSE;
+}
+
+
+/*
+    ========================================================================
+    Routine Description:
+        check if this entry need to fix tx legacy rate
+
+    Arguments:
+        pAd
+        pEntry
+
+    Return Value:
+        TURE
+        FALSE
+
+    ========================================================================
+*/
+UCHAR RTMPStaFixedTxMode(
+	IN PRTMP_ADAPTER    pAd,
+	IN PMAC_TABLE_ENTRY	pEntry)
+{
+	UCHAR	tx_mode = FIXED_TXMODE_HT;
+
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		tx_mode = (UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode;
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	return tx_mode;
+}
+
+/*
+    ========================================================================
+    Routine Description:
+        Overwrite HT Tx Mode by Fixed Legency Tx Mode, if specified.
+
+    Arguments:
+        pAd
+        pEntry
+
+    Return Value:
+        TURE
+        FALSE
+
+    ========================================================================
+*/
+VOID RTMPUpdateLegacyTxSetting(
+		UCHAR				fixed_tx_mode,
+		PMAC_TABLE_ENTRY	pEntry)
+{
+	HTTRANSMIT_SETTING TransmitSetting;
+
+	if (fixed_tx_mode == FIXED_TXMODE_HT)
+		return;
+
+	TransmitSetting.word = 0;
+
+	TransmitSetting.field.MODE = pEntry->HTPhyMode.field.MODE;
+	TransmitSetting.field.MCS = pEntry->HTPhyMode.field.MCS;
+
+	if (fixed_tx_mode == FIXED_TXMODE_CCK)
+	{
+		TransmitSetting.field.MODE = MODE_CCK;
+		// CCK mode allow MCS 0~3
+		if (TransmitSetting.field.MCS > MCS_3)
+			TransmitSetting.field.MCS = MCS_3;
+	}
+	else
+	{
+		TransmitSetting.field.MODE = MODE_OFDM;
+		// OFDM mode allow MCS 0~7
+		if (TransmitSetting.field.MCS > MCS_7)
+			TransmitSetting.field.MCS = MCS_7;
+	}
+
+	if (pEntry->HTPhyMode.field.MODE >= TransmitSetting.field.MODE)
+	{
+		pEntry->HTPhyMode.word = TransmitSetting.word;
+		DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateLegacyTxSetting : wcid-%d, MODE=%s, MCS=%d \n",
+				pEntry->Aid, GetPhyMode(pEntry->HTPhyMode.field.MODE), pEntry->HTPhyMode.field.MCS));
+	}
+}
+
+#ifdef CONFIG_STA_SUPPORT
+/*
+	==========================================================================
+	Description:
+		dynamic tune BBP R66 to find a balance between sensibility and
+		noise isolation
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID AsicStaBbpTuning(
+	IN PRTMP_ADAPTER pAd)
+{
+	UCHAR	OrigR66Value = 0, R66;//, R66UpperBound = 0x30, R66LowerBound = 0x30;
+	CHAR	Rssi;
+
+	// 2860C did not support Fase CCA, therefore can't tune
+	if (pAd->MACVersion == 0x28600100)
+		return;
+
+	//
+	// work as a STA
+	//
+	if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)  // no R66 tuning when SCANNING
+		return;
+
+	if ((pAd->OpMode == OPMODE_STA)
+		&& (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
+			)
+		&& !(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+		)
+	{
+		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &OrigR66Value);
+		R66 = OrigR66Value;
+
+		if (pAd->Antenna.field.RxPath > 1)
+			Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1;
+		else
+			Rssi = pAd->StaCfg.RssiSample.AvgRssi0;
+
+		if (pAd->LatchRfRegs.Channel <= 14)
+		{	//BG band
+#ifdef RT30xx
+			// RT3070 is a no LNA solution, it should have different control regarding to AGC gain control
+			// Otherwise, it will have some throughput side effect when low RSSI
+			if (IS_RT30xx(pAd))
+			{
+				if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
+				{
+					R66 = 0x1C + 2*GET_LNA_GAIN(pAd) + 0x20;
+					if (OrigR66Value != R66)
+					{
+						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+					}
+				}
+				else
+				{
+					R66 = 0x1C + 2*GET_LNA_GAIN(pAd);
+					if (OrigR66Value != R66)
+					{
+						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+					}
+				}
+			}
+			else
+#endif // RT30xx //
+			{
+				if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
+				{
+					R66 = (0x2E + GET_LNA_GAIN(pAd)) + 0x10;
+					if (OrigR66Value != R66)
+					{
+						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+					}
+				}
+				else
+				{
+					R66 = 0x2E + GET_LNA_GAIN(pAd);
+					if (OrigR66Value != R66)
+					{
+						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+					}
+				}
+			}
+
+		}
+		else
+		{	//A band
+			if (pAd->CommonCfg.BBPCurrentBW == BW_20)
+			{
+				if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
+				{
+					R66 = 0x32 + (GET_LNA_GAIN(pAd)*5)/3 + 0x10;
+					if (OrigR66Value != R66)
+					{
+						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+					}
+				}
+				else
+				{
+					R66 = 0x32 + (GET_LNA_GAIN(pAd)*5)/3;
+					if (OrigR66Value != R66)
+					{
+						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+					}
+				}
+			}
+			else
+			{
+				if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
+				{
+					R66 = 0x3A + (GET_LNA_GAIN(pAd)*5)/3 + 0x10;
+					if (OrigR66Value != R66)
+					{
+						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+					}
+				}
+				else
+				{
+					R66 = 0x3A + (GET_LNA_GAIN(pAd)*5)/3;
+					if (OrigR66Value != R66)
+					{
+						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+					}
+				}
+			}
+		}
+
+
+	}
+}
+#endif // CONFIG_STA_SUPPORT //
+
+VOID RTMPSetAGCInitValue(
+	IN PRTMP_ADAPTER	pAd,
+	IN UCHAR			BandWidth)
+{
+	UCHAR	R66 = 0x30;
+
+	if (pAd->LatchRfRegs.Channel <= 14)
+	{	// BG band
+		R66 = 0x2E + GET_LNA_GAIN(pAd);
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+	}
+	else
+	{	//A band
+		if (BandWidth == BW_20)
+		{
+			R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+		}
+#ifdef DOT11_N_SUPPORT
+		else
+		{
+			R66 = (UCHAR)(0x3A + (GET_LNA_GAIN(pAd)*5)/3);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+		}
+#endif // DOT11_N_SUPPORT //
+	}
+
+}
+
+VOID AsicTurnOffRFClk(
+	IN PRTMP_ADAPTER pAd,
+	IN	UCHAR		Channel)
+{
+	// RF R2 bit 18 = 0
+	UINT32			R1 = 0, R2 = 0, R3 = 0;
+	UCHAR			index;
+	RTMP_RF_REGS	*RFRegTable;
+
+#ifdef RT30xx
+	// The RF programming sequence is difference between 3xxx and 2xxx
+	if (IS_RT3090(pAd))
+	{
+		RT30xxLoadRFSleepModeSetup(pAd);  // add by johnli,  RF power sequence setup, load RF sleep-mode setup
+	}
+	else
+	{
+#endif // RT30xx //
+	RFRegTable = RF2850RegTable;
+
+	switch (pAd->RfIcType)
+	{
+		case RFIC_2820:
+		case RFIC_2850:
+		case RFIC_2720:
+		case RFIC_2750:
+
+			for (index = 0; index < NUM_OF_2850_CHNL; index++)
+			{
+				if (Channel == RFRegTable[index].Channel)
+				{
+					R1 = RFRegTable[index].R1 & 0xffffdfff;
+					R2 = RFRegTable[index].R2 & 0xfffbffff;
+					R3 = RFRegTable[index].R3 & 0xfff3ffff;
+
+					RTMP_RF_IO_WRITE32(pAd, R1);
+					RTMP_RF_IO_WRITE32(pAd, R2);
+
+					// Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0.
+					// Set RF R2 bit18=0, R3 bit[18:19]=0
+					//if (pAd->StaCfg.bRadio == FALSE)
+					if (1)
+					{
+						RTMP_RF_IO_WRITE32(pAd, R3);
+
+						DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x,  R3 = 0x%08x \n",
+							Channel, pAd->RfIcType, R2, R3));
+					}
+					else
+						DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n",
+							Channel, pAd->RfIcType, R2));
+					break;
+				}
+			}
+			break;
+
+		default:
+			break;
+	}
+#ifdef RT30xx
+	}
+#endif // RT30xx //
+
+}
+
+
+VOID AsicTurnOnRFClk(
+	IN PRTMP_ADAPTER pAd,
+	IN	UCHAR			Channel)
+{
+	// RF R2 bit 18 = 0
+	UINT32			R1 = 0, R2 = 0, R3 = 0;
+	UCHAR			index;
+	RTMP_RF_REGS	*RFRegTable;
+
+#ifdef RT30xx
+	// The RF programming sequence is difference between 3xxx and 2xxx
+	if (IS_RT3090(pAd))
+	{
+	}
+	else
+	{
+#endif // RT30xx //
+	RFRegTable = RF2850RegTable;
+
+	switch (pAd->RfIcType)
+	{
+		case RFIC_2820:
+		case RFIC_2850:
+		case RFIC_2720:
+		case RFIC_2750:
+
+			for (index = 0; index < NUM_OF_2850_CHNL; index++)
+			{
+				if (Channel == RFRegTable[index].Channel)
+				{
+					R3 = pAd->LatchRfRegs.R3;
+					R3 &= 0xfff3ffff;
+					R3 |= 0x00080000;
+					RTMP_RF_IO_WRITE32(pAd, R3);
+
+					R1 = RFRegTable[index].R1;
+					RTMP_RF_IO_WRITE32(pAd, R1);
+
+					R2 = RFRegTable[index].R2;
+					if (pAd->Antenna.field.TxPath == 1)
+					{
+						R2 |= 0x4000;	// If TXpath is 1, bit 14 = 1;
+					}
+
+					if (pAd->Antenna.field.RxPath == 2)
+					{
+						R2 |= 0x40;	// write 1 to off Rxpath.
+					}
+					else if (pAd->Antenna.field.RxPath == 1)
+					{
+						R2 |= 0x20040;	// write 1 to off RxPath
+					}
+					RTMP_RF_IO_WRITE32(pAd, R2);
+
+					break;
+				}
+			}
+			break;
+
+		default:
+			break;
+	}
+
+#ifdef RT30xx
+	}
+#endif // RT30xx //
+
+}
+
diff --git a/drivers/staging/rt3070/common/netif_block.c b/drivers/staging/rt3070/common/netif_block.c
new file mode 100644
index 0000000..4773c11
--- /dev/null
+++ b/drivers/staging/rt3070/common/netif_block.c
@@ -0,0 +1,136 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+ */
+
+#include "../rt_config.h"
+#include "netif_block.h"
+
+static NETIF_ENTRY freeNetIfEntryPool[FREE_NETIF_POOL_SIZE];
+static LIST_HEADER freeNetIfEntryList;
+
+void initblockQueueTab(
+	IN PRTMP_ADAPTER pAd)
+{
+	int i;
+
+	initList(&freeNetIfEntryList);
+	for (i = 0; i < FREE_NETIF_POOL_SIZE; i++)
+		insertTailList(&freeNetIfEntryList, (PLIST_ENTRY)&freeNetIfEntryPool[i]);
+
+	for (i=0; i < NUM_OF_TX_RING; i++)
+		initList(&pAd->blockQueueTab[i].NetIfList);
+
+	return;
+}
+
+BOOLEAN blockNetIf(
+	IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry,
+	IN PNET_DEV pNetDev)
+{
+	PNETIF_ENTRY pNetIfEntry = NULL;
+
+	if ((pNetIfEntry = (PNETIF_ENTRY)removeHeadList(&freeNetIfEntryList)) != NULL)
+	{
+		netif_stop_queue(pNetDev);
+		pNetIfEntry->pNetDev = pNetDev;
+		insertTailList(&pBlockQueueEntry->NetIfList, (PLIST_ENTRY)pNetIfEntry);
+
+		pBlockQueueEntry->SwTxQueueBlockFlag = TRUE;
+		DBGPRINT(RT_DEBUG_TRACE, ("netif_stop_queue(%s)\n", pNetDev->name));
+	}
+	else
+		return FALSE;
+
+	return TRUE;
+}
+
+VOID releaseNetIf(
+	IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry)
+{
+	PNETIF_ENTRY pNetIfEntry = NULL;
+	PLIST_HEADER pNetIfList = &pBlockQueueEntry->NetIfList;
+
+	while((pNetIfEntry = (PNETIF_ENTRY)removeHeadList(pNetIfList)) !=  NULL)
+	{
+		PNET_DEV pNetDev = pNetIfEntry->pNetDev;
+		netif_wake_queue(pNetDev);
+		insertTailList(&freeNetIfEntryList, (PLIST_ENTRY)pNetIfEntry);
+
+		DBGPRINT(RT_DEBUG_TRACE, ("netif_wake_queue(%s)\n", pNetDev->name));
+	}
+	pBlockQueueEntry->SwTxQueueBlockFlag = FALSE;
+	return;
+}
+
+
+VOID StopNetIfQueue(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR QueIdx,
+	IN PNDIS_PACKET pPacket)
+{
+	PNET_DEV NetDev = NULL;
+	UCHAR IfIdx = 0;
+	BOOLEAN valid = FALSE;
+
+#ifdef WDS_SUPPORT
+	if (RTMP_GET_PACKET_NET_DEVICE(pPacket) >= MIN_NET_DEVICE_FOR_WDS)
+	{
+		IfIdx = (RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_WDS) % MAX_WDS_ENTRY;
+		NetDev = pAd->WdsTab.WdsEntry[IfIdx].dev;
+	}
+	else
+#endif // WDS_SUPPORT //
+	{
+#ifdef MBSS_SUPPORT
+		if (pAd->OpMode == OPMODE_AP)
+		{
+			IfIdx = (RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_MBSSID) % MAX_MBSSID_NUM;
+			NetDev = pAd->ApCfg.MBSSID[IfIdx].MSSIDDev;
+		}
+		else
+		{
+			IfIdx = MAIN_MBSSID;
+			NetDev = pAd->net_dev;
+		}
+#else
+		IfIdx = MAIN_MBSSID;
+		NetDev = pAd->net_dev;
+#endif
+	}
+
+	// WMM support 4 software queues.
+	// One software queue full doesn't mean device have no capbility to transmit packet.
+	// So disable block Net-If queue function while WMM enable.
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		valid = (pAd->CommonCfg.bWmmCapable == TRUE) ? FALSE : TRUE;
+#endif // CONFIG_STA_SUPPORT //
+
+	if (valid)
+		blockNetIf(&pAd->blockQueueTab[QueIdx], NetDev);
+	return;
+}
+
diff --git a/drivers/staging/rt3070/common/rtmp_init.c b/drivers/staging/rt3070/common/rtmp_init.c
new file mode 100644
index 0000000..4503f6c
--- /dev/null
+++ b/drivers/staging/rt3070/common/rtmp_init.c
@@ -0,0 +1,4197 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	rtmp_init.c
+
+	Abstract:
+	Miniport generic portion header file
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+	Paul Lin    2002-08-01    created
+    John Chang  2004-08-20    RT2561/2661 use scatter-gather scheme
+    Jan Lee  2006-09-15    RT2860. Change for 802.11n , EEPROM, Led, BA, HT.
+*/
+#include	"../rt_config.h"
+#include 	"../firmware.h"
+
+//#define BIN_IN_FILE /* use *.bin firmware */
+
+UCHAR    BIT8[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
+ULONG    BIT32[] = {0x00000001, 0x00000002, 0x00000004, 0x00000008,
+					0x00000010, 0x00000020, 0x00000040, 0x00000080,
+					0x00000100, 0x00000200, 0x00000400, 0x00000800,
+					0x00001000, 0x00002000, 0x00004000, 0x00008000,
+					0x00010000, 0x00020000, 0x00040000, 0x00080000,
+					0x00100000, 0x00200000, 0x00400000, 0x00800000,
+					0x01000000, 0x02000000, 0x04000000, 0x08000000,
+					0x10000000, 0x20000000, 0x40000000, 0x80000000};
+
+char*   CipherName[] = {"none","wep64","wep128","TKIP","AES","CKIP64","CKIP128"};
+
+const unsigned short ccitt_16Table[] = {
+	0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
+	0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
+	0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
+	0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
+	0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
+	0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
+	0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
+	0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
+	0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
+	0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
+	0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
+	0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
+	0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
+	0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
+	0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
+	0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
+	0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
+	0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
+	0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
+	0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
+	0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
+	0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+	0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
+	0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
+	0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
+	0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
+	0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
+	0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
+	0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
+	0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
+	0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
+	0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
+};
+#define ByteCRC16(v, crc) \
+	(unsigned short)((crc << 8) ^  ccitt_16Table[((crc >> 8) ^ (v)) & 255])
+
+unsigned char BitReverse(unsigned char x)
+{
+	int i;
+	unsigned char Temp=0;
+	for(i=0; ; i++)
+	{
+		if(x & 0x80)	Temp |= 0x80;
+		if(i==7)		break;
+		x	<<= 1;
+		Temp >>= 1;
+	}
+	return Temp;
+}
+
+//
+// BBP register initialization set
+//
+REG_PAIR   BBPRegTable[] = {
+	{BBP_R65,		0x2C},		// fix rssi issue
+	{BBP_R66,		0x38},	// Also set this default value to pAd->BbpTuning.R66CurrentValue at initial
+	{BBP_R69,		0x12},
+	{BBP_R70,		0xa},	// BBP_R70 will change to 0x8 in ApStartUp and LinkUp for rt2860C, otherwise value is 0xa
+	{BBP_R73,		0x10},
+	{BBP_R81,		0x37},
+	{BBP_R82,		0x62},
+	{BBP_R83,		0x6A},
+	{BBP_R84,		0x99},	// 0x19 is for rt2860E and after. This is for extension channel overlapping IOT. 0x99 is for rt2860D and before
+	{BBP_R86,		0x00},	// middle range issue, Rory @2008-01-28
+	{BBP_R91,		0x04},	// middle range issue, Rory @2008-01-28
+	{BBP_R92,		0x00},	// middle range issue, Rory @2008-01-28
+	{BBP_R103,  	0x00}, 	// near range high-power issue, requested from Gary @2008-0528
+	{BBP_R105,		0x05},	// 0x05 is for rt2860E to turn on FEQ control. It is safe for rt2860D and before, because Bit 7:2 are reserved in rt2860D and before.
+};
+#define	NUM_BBP_REG_PARMS	(sizeof(BBPRegTable) / sizeof(REG_PAIR))
+
+//
+// RF register initialization set
+//
+#ifdef RT30xx
+REG_PAIR   RT30xx_RFRegTable[] = {
+        {RF_R04,          0x40},
+        {RF_R05,          0x03},
+        {RF_R06,          0x02},
+        {RF_R07,          0x70},
+        {RF_R09,          0x0F},
+        {RF_R10,          0x41},
+        {RF_R11,          0x21},
+        {RF_R12,          0x7B},
+        {RF_R14,          0x90},
+        {RF_R15,          0x58},
+        {RF_R16,          0xB3},
+        {RF_R17,          0x92},
+        {RF_R18,          0x2C},
+        {RF_R19,          0x02},
+        {RF_R20,          0xBA},
+        {RF_R21,          0xDB},
+        {RF_R24,          0x16},
+        {RF_R25,          0x01},
+        {RF_R29,          0x1F},
+};
+#define	NUM_RF_REG_PARMS	(sizeof(RT30xx_RFRegTable) / sizeof(REG_PAIR))
+#endif // RT30xx //
+
+//
+// ASIC register initialization sets
+//
+
+RTMP_REG_PAIR	MACRegTable[] =	{
+#if defined(HW_BEACON_OFFSET) && (HW_BEACON_OFFSET == 0x200)
+	{BCN_OFFSET0,			0xf8f0e8e0}, /* 0x3800(e0), 0x3A00(e8), 0x3C00(f0), 0x3E00(f8), 512B for each beacon */
+	{BCN_OFFSET1,			0x6f77d0c8}, /* 0x3200(c8), 0x3400(d0), 0x1DC0(77), 0x1BC0(6f), 512B for each beacon */
+#elif defined(HW_BEACON_OFFSET) && (HW_BEACON_OFFSET == 0x100)
+	{BCN_OFFSET0,			0xece8e4e0}, /* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */
+	{BCN_OFFSET1,			0xfcf8f4f0}, /* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */
+#else
+    #error You must re-calculate new value for BCN_OFFSET0 & BCN_OFFSET1 in MACRegTable[]!!!
+#endif // HW_BEACON_OFFSET //
+
+	{LEGACY_BASIC_RATE,		0x0000013f}, //  Basic rate set bitmap
+	{HT_BASIC_RATE,		0x00008003}, // Basic HT rate set , 20M, MCS=3, MM. Format is the same as in TXWI.
+	{MAC_SYS_CTRL,		0x00}, // 0x1004, , default Disable RX
+	{RX_FILTR_CFG,		0x17f97}, //0x1400  , RX filter control,
+	{BKOFF_SLOT_CFG,	0x209}, // default set short slot time, CC_DELAY_TIME should be 2
+	//{TX_SW_CFG0,		0x40a06}, // Gary,2006-08-23
+	{TX_SW_CFG0,		0x0}, 		// Gary,2008-05-21 for CWC test
+	{TX_SW_CFG1,		0x80606}, // Gary,2006-08-23
+	{TX_LINK_CFG,		0x1020},		// Gary,2006-08-23
+	{TX_TIMEOUT_CFG,	0x000a2090},
+	{MAX_LEN_CFG,		MAX_AGGREGATION_SIZE | 0x00001000},	// 0x3018, MAX frame length. Max PSDU = 16kbytes.
+	{LED_CFG,		0x7f031e46}, // Gary, 2006-08-23
+
+//#ifdef CONFIG_STA_SUPPORT
+//	{WMM_AIFSN_CFG,		0x00002273},
+//	{WMM_CWMIN_CFG,		0x00002344},
+//	{WMM_CWMAX_CFG,		0x000034aa},
+//#endif // CONFIG_STA_SUPPORT //
+#ifdef INF_AMAZON_SE
+	{PBF_MAX_PCNT,			0x1F3F6F6F}, 	//iverson modify for usb issue, 2008/09/19
+											// 6F + 6F < total page count FE
+											// so that RX doesn't occupy TX's buffer space when WMM congestion.
+#else
+	{PBF_MAX_PCNT,			0x1F3FBF9F}, 	//0x1F3f7f9f},		//Jan, 2006/04/20
+#endif // INF_AMAZON_SE //
+	//{TX_RTY_CFG,			0x6bb80408},	// Jan, 2006/11/16
+	{TX_RTY_CFG,			0x47d01f0f},	// Jan, 2006/11/16, Set TxWI->ACK =0 in Probe Rsp Modify for 2860E ,2007-08-03
+	{AUTO_RSP_CFG,			0x00000013},	// Initial Auto_Responder, because QA will turn off Auto-Responder
+	{CCK_PROT_CFG,			0x05740003 /*0x01740003*/},	// Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled.
+	{OFDM_PROT_CFG,			0x05740003 /*0x01740003*/},	// Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled.
+//PS packets use Tx1Q (for HCCA) when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
+#ifdef RT2870
+#ifdef CONFIG_STA_SUPPORT
+	{PBF_CFG, 				0xf40006}, 		// Only enable Queue 2
+#endif // CONFIG_STA_SUPPORT //
+	{MM40_PROT_CFG,			0x3F44084},		// Initial Auto_Responder, because QA will turn off Auto-Responder
+	{WPDMA_GLO_CFG,			0x00000030},
+#endif // RT2870 //
+	{GF20_PROT_CFG,			0x01744004},    // set 19:18 --> Short NAV for MIMO PS
+	{GF40_PROT_CFG,			0x03F44084},
+	{MM20_PROT_CFG,			0x01744004},
+	{TXOP_CTRL_CFG,			0x0000583f, /*0x0000243f*/ /*0x000024bf*/},	//Extension channel backoff.
+	{TX_RTS_CFG,			0x00092b20},
+//#ifdef WIFI_TEST
+	{EXP_ACK_TIME,			0x002400ca},	// default value
+//#else
+//	{EXP_ACK_TIME,			0x005400ca},	// suggested by Gray @ 20070323 for 11n intel-sta throughput
+//#endif // end - WIFI_TEST //
+	{TXOP_HLDR_ET, 			0x00000002},
+
+	/* Jerry comments 2008/01/16: we use SIFS = 10us in CCK defaultly, but it seems that 10us
+		is too small for INTEL 2200bg card, so in MBSS mode, the delta time between beacon0
+		and beacon1 is SIFS (10us), so if INTEL 2200bg card connects to BSS0, the ping
+		will always lost. So we change the SIFS of CCK from 10us to 16us. */
+	{XIFS_TIME_CFG,			0x33a41010},
+	{PWR_PIN_CFG,			0x00000003},	// patch for 2880-E
+};
+
+
+#ifdef CONFIG_STA_SUPPORT
+RTMP_REG_PAIR	STAMACRegTable[] =	{
+	{WMM_AIFSN_CFG,		0x00002273},
+	{WMM_CWMIN_CFG,	0x00002344},
+	{WMM_CWMAX_CFG,	0x000034aa},
+};
+#endif // CONFIG_STA_SUPPORT //
+
+#define	NUM_MAC_REG_PARMS		(sizeof(MACRegTable) / sizeof(RTMP_REG_PAIR))
+#ifdef CONFIG_STA_SUPPORT
+#define	NUM_STA_MAC_REG_PARMS	(sizeof(STAMACRegTable) / sizeof(RTMP_REG_PAIR))
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef RT2870
+//
+// RT2870 Firmware Spec only used 1 oct for version expression
+//
+#define FIRMWARE_MINOR_VERSION	7
+
+#endif // RT2870 //
+
+// New 8k byte firmware size for RT3071/RT3072
+#define FIRMWAREIMAGE_MAX_LENGTH	0x2000
+#define FIRMWAREIMAGE_LENGTH		(sizeof (FirmwareImage) / sizeof(UCHAR))
+#define FIRMWARE_MAJOR_VERSION	0
+
+#define FIRMWAREIMAGEV1_LENGTH	0x1000
+#define FIRMWAREIMAGEV2_LENGTH	0x1000
+
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Allocate RTMP_ADAPTER data block and do some initialization
+
+	Arguments:
+		Adapter		Pointer to our adapter
+
+	Return Value:
+		NDIS_STATUS_SUCCESS
+		NDIS_STATUS_FAILURE
+
+	IRQL = PASSIVE_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+NDIS_STATUS	RTMPAllocAdapterBlock(
+	IN  PVOID	handle,
+	OUT	PRTMP_ADAPTER	*ppAdapter)
+{
+	PRTMP_ADAPTER	pAd;
+	NDIS_STATUS		Status;
+	INT 			index;
+	UCHAR			*pBeaconBuf = NULL;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocAdapterBlock\n"));
+
+	*ppAdapter = NULL;
+
+	do
+	{
+		// Allocate RTMP_ADAPTER memory block
+		pBeaconBuf = kmalloc(MAX_BEACON_SIZE, MEM_ALLOC_FLAG);
+		if (pBeaconBuf == NULL)
+		{
+			Status = NDIS_STATUS_FAILURE;
+			DBGPRINT_ERR(("Failed to allocate memory - BeaconBuf!\n"));
+			break;
+		}
+
+		Status = AdapterBlockAllocateMemory(handle, (PVOID *)&pAd);
+		if (Status != NDIS_STATUS_SUCCESS)
+		{
+			DBGPRINT_ERR(("Failed to allocate memory - ADAPTER\n"));
+			break;
+		}
+		pAd->BeaconBuf = pBeaconBuf;
+		printk("\n\n=== pAd = %p, size = %d ===\n\n", pAd, (UINT32)sizeof(RTMP_ADAPTER));
+
+
+		// Init spin locks
+		NdisAllocateSpinLock(&pAd->MgmtRingLock);
+
+		for (index =0 ; index < NUM_OF_TX_RING; index++)
+		{
+			NdisAllocateSpinLock(&pAd->TxSwQueueLock[index]);
+			NdisAllocateSpinLock(&pAd->DeQueueLock[index]);
+			pAd->DeQueueRunning[index] = FALSE;
+		}
+
+		NdisAllocateSpinLock(&pAd->irq_lock);
+
+	} while (FALSE);
+
+	if ((Status != NDIS_STATUS_SUCCESS) && (pBeaconBuf))
+		kfree(pBeaconBuf);
+
+	*ppAdapter = pAd;
+
+	DBGPRINT_S(Status, ("<-- RTMPAllocAdapterBlock, Status=%x\n", Status));
+	return Status;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Read initial Tx power per MCS and BW from EEPROM
+
+	Arguments:
+		Adapter						Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTMPReadTxPwrPerRate(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	ULONG		data, Adata, Gdata;
+	USHORT		i, value, value2;
+	INT			Apwrdelta, Gpwrdelta;
+	UCHAR		t1,t2,t3,t4;
+	BOOLEAN		bValid, bApwrdeltaMinus = TRUE, bGpwrdeltaMinus = TRUE;
+
+	//
+	// Get power delta for 20MHz and 40MHz.
+	//
+	DBGPRINT(RT_DEBUG_TRACE, ("Txpower per Rate\n"));
+	RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_DELTA, value2);
+	Apwrdelta = 0;
+	Gpwrdelta = 0;
+
+	if ((value2 & 0xff) != 0xff)
+	{
+		if ((value2 & 0x80))
+			Gpwrdelta = (value2&0xf);
+
+		if ((value2 & 0x40))
+			bGpwrdeltaMinus = FALSE;
+		else
+			bGpwrdeltaMinus = TRUE;
+	}
+	if ((value2 & 0xff00) != 0xff00)
+	{
+		if ((value2 & 0x8000))
+			Apwrdelta = ((value2&0xf00)>>8);
+
+		if ((value2 & 0x4000))
+			bApwrdeltaMinus = FALSE;
+		else
+			bApwrdeltaMinus = TRUE;
+	}
+	DBGPRINT(RT_DEBUG_TRACE, ("Gpwrdelta = %x, Apwrdelta = %x .\n", Gpwrdelta, Apwrdelta));
+
+	//
+	// Get Txpower per MCS for 20MHz in 2.4G.
+	//
+	for (i=0; i<5; i++)
+	{
+		RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i*4, value);
+		data = value;
+		if (bApwrdeltaMinus == FALSE)
+		{
+			t1 = (value&0xf)+(Apwrdelta);
+			if (t1 > 0xf)
+				t1 = 0xf;
+			t2 = ((value&0xf0)>>4)+(Apwrdelta);
+			if (t2 > 0xf)
+				t2 = 0xf;
+			t3 = ((value&0xf00)>>8)+(Apwrdelta);
+			if (t3 > 0xf)
+				t3 = 0xf;
+			t4 = ((value&0xf000)>>12)+(Apwrdelta);
+			if (t4 > 0xf)
+				t4 = 0xf;
+		}
+		else
+		{
+			if ((value&0xf) > Apwrdelta)
+				t1 = (value&0xf)-(Apwrdelta);
+			else
+				t1 = 0;
+			if (((value&0xf0)>>4) > Apwrdelta)
+				t2 = ((value&0xf0)>>4)-(Apwrdelta);
+			else
+				t2 = 0;
+			if (((value&0xf00)>>8) > Apwrdelta)
+				t3 = ((value&0xf00)>>8)-(Apwrdelta);
+			else
+				t3 = 0;
+			if (((value&0xf000)>>12) > Apwrdelta)
+				t4 = ((value&0xf000)>>12)-(Apwrdelta);
+			else
+				t4 = 0;
+		}
+		Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
+		if (bGpwrdeltaMinus == FALSE)
+		{
+			t1 = (value&0xf)+(Gpwrdelta);
+			if (t1 > 0xf)
+				t1 = 0xf;
+			t2 = ((value&0xf0)>>4)+(Gpwrdelta);
+			if (t2 > 0xf)
+				t2 = 0xf;
+			t3 = ((value&0xf00)>>8)+(Gpwrdelta);
+			if (t3 > 0xf)
+				t3 = 0xf;
+			t4 = ((value&0xf000)>>12)+(Gpwrdelta);
+			if (t4 > 0xf)
+				t4 = 0xf;
+		}
+		else
+		{
+			if ((value&0xf) > Gpwrdelta)
+				t1 = (value&0xf)-(Gpwrdelta);
+			else
+				t1 = 0;
+			if (((value&0xf0)>>4) > Gpwrdelta)
+				t2 = ((value&0xf0)>>4)-(Gpwrdelta);
+			else
+				t2 = 0;
+			if (((value&0xf00)>>8) > Gpwrdelta)
+				t3 = ((value&0xf00)>>8)-(Gpwrdelta);
+			else
+				t3 = 0;
+			if (((value&0xf000)>>12) > Gpwrdelta)
+				t4 = ((value&0xf000)>>12)-(Gpwrdelta);
+			else
+				t4 = 0;
+		}
+		Gdata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
+
+		RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i*4 + 2, value);
+		if (bApwrdeltaMinus == FALSE)
+		{
+			t1 = (value&0xf)+(Apwrdelta);
+			if (t1 > 0xf)
+				t1 = 0xf;
+			t2 = ((value&0xf0)>>4)+(Apwrdelta);
+			if (t2 > 0xf)
+				t2 = 0xf;
+			t3 = ((value&0xf00)>>8)+(Apwrdelta);
+			if (t3 > 0xf)
+				t3 = 0xf;
+			t4 = ((value&0xf000)>>12)+(Apwrdelta);
+			if (t4 > 0xf)
+				t4 = 0xf;
+		}
+		else
+		{
+			if ((value&0xf) > Apwrdelta)
+				t1 = (value&0xf)-(Apwrdelta);
+			else
+				t1 = 0;
+			if (((value&0xf0)>>4) > Apwrdelta)
+				t2 = ((value&0xf0)>>4)-(Apwrdelta);
+			else
+				t2 = 0;
+			if (((value&0xf00)>>8) > Apwrdelta)
+				t3 = ((value&0xf00)>>8)-(Apwrdelta);
+			else
+				t3 = 0;
+			if (((value&0xf000)>>12) > Apwrdelta)
+				t4 = ((value&0xf000)>>12)-(Apwrdelta);
+			else
+				t4 = 0;
+		}
+		Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
+		if (bGpwrdeltaMinus == FALSE)
+		{
+			t1 = (value&0xf)+(Gpwrdelta);
+			if (t1 > 0xf)
+				t1 = 0xf;
+			t2 = ((value&0xf0)>>4)+(Gpwrdelta);
+			if (t2 > 0xf)
+				t2 = 0xf;
+			t3 = ((value&0xf00)>>8)+(Gpwrdelta);
+			if (t3 > 0xf)
+				t3 = 0xf;
+			t4 = ((value&0xf000)>>12)+(Gpwrdelta);
+			if (t4 > 0xf)
+				t4 = 0xf;
+		}
+		else
+		{
+			if ((value&0xf) > Gpwrdelta)
+				t1 = (value&0xf)-(Gpwrdelta);
+			else
+				t1 = 0;
+			if (((value&0xf0)>>4) > Gpwrdelta)
+				t2 = ((value&0xf0)>>4)-(Gpwrdelta);
+			else
+				t2 = 0;
+			if (((value&0xf00)>>8) > Gpwrdelta)
+				t3 = ((value&0xf00)>>8)-(Gpwrdelta);
+			else
+				t3 = 0;
+			if (((value&0xf000)>>12) > Gpwrdelta)
+				t4 = ((value&0xf000)>>12)-(Gpwrdelta);
+			else
+				t4 = 0;
+		}
+		Gdata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
+		data |= (value<<16);
+
+		pAd->Tx20MPwrCfgABand[i] = pAd->Tx40MPwrCfgABand[i] = Adata;
+		pAd->Tx20MPwrCfgGBand[i] = pAd->Tx40MPwrCfgGBand[i] = Gdata;
+
+		if (data != 0xffffffff)
+			RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, data);
+		DBGPRINT_RAW(RT_DEBUG_TRACE, ("20MHz BW, 2.4G band-%lx,  Adata = %lx,  Gdata = %lx \n", data, Adata, Gdata));
+	}
+
+	//
+	// Check this block is valid for 40MHz in 2.4G. If invalid, use parameter for 20MHz in 2.4G
+	//
+	bValid = TRUE;
+	for (i=0; i<6; i++)
+	{
+		RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + 2 + i*2, value);
+		if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00))
+		{
+			bValid = FALSE;
+			break;
+		}
+	}
+
+	//
+	// Get Txpower per MCS for 40MHz in 2.4G.
+	//
+	if (bValid)
+	{
+		for (i=0; i<4; i++)
+		{
+			RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + i*4, value);
+			if (bGpwrdeltaMinus == FALSE)
+			{
+				t1 = (value&0xf)+(Gpwrdelta);
+				if (t1 > 0xf)
+					t1 = 0xf;
+				t2 = ((value&0xf0)>>4)+(Gpwrdelta);
+				if (t2 > 0xf)
+					t2 = 0xf;
+				t3 = ((value&0xf00)>>8)+(Gpwrdelta);
+				if (t3 > 0xf)
+					t3 = 0xf;
+				t4 = ((value&0xf000)>>12)+(Gpwrdelta);
+				if (t4 > 0xf)
+					t4 = 0xf;
+			}
+			else
+			{
+				if ((value&0xf) > Gpwrdelta)
+					t1 = (value&0xf)-(Gpwrdelta);
+				else
+					t1 = 0;
+				if (((value&0xf0)>>4) > Gpwrdelta)
+					t2 = ((value&0xf0)>>4)-(Gpwrdelta);
+				else
+					t2 = 0;
+				if (((value&0xf00)>>8) > Gpwrdelta)
+					t3 = ((value&0xf00)>>8)-(Gpwrdelta);
+				else
+					t3 = 0;
+				if (((value&0xf000)>>12) > Gpwrdelta)
+					t4 = ((value&0xf000)>>12)-(Gpwrdelta);
+				else
+					t4 = 0;
+			}
+			Gdata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
+
+			RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + i*4 + 2, value);
+			if (bGpwrdeltaMinus == FALSE)
+			{
+				t1 = (value&0xf)+(Gpwrdelta);
+				if (t1 > 0xf)
+					t1 = 0xf;
+				t2 = ((value&0xf0)>>4)+(Gpwrdelta);
+				if (t2 > 0xf)
+					t2 = 0xf;
+				t3 = ((value&0xf00)>>8)+(Gpwrdelta);
+				if (t3 > 0xf)
+					t3 = 0xf;
+				t4 = ((value&0xf000)>>12)+(Gpwrdelta);
+				if (t4 > 0xf)
+					t4 = 0xf;
+			}
+			else
+			{
+				if ((value&0xf) > Gpwrdelta)
+					t1 = (value&0xf)-(Gpwrdelta);
+				else
+					t1 = 0;
+				if (((value&0xf0)>>4) > Gpwrdelta)
+					t2 = ((value&0xf0)>>4)-(Gpwrdelta);
+				else
+					t2 = 0;
+				if (((value&0xf00)>>8) > Gpwrdelta)
+					t3 = ((value&0xf00)>>8)-(Gpwrdelta);
+				else
+					t3 = 0;
+				if (((value&0xf000)>>12) > Gpwrdelta)
+					t4 = ((value&0xf000)>>12)-(Gpwrdelta);
+				else
+					t4 = 0;
+			}
+			Gdata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
+
+			if (i == 0)
+				pAd->Tx40MPwrCfgGBand[i+1] = (pAd->Tx40MPwrCfgGBand[i+1] & 0x0000FFFF) | (Gdata & 0xFFFF0000);
+			else
+				pAd->Tx40MPwrCfgGBand[i+1] = Gdata;
+
+			DBGPRINT_RAW(RT_DEBUG_TRACE, ("40MHz BW, 2.4G band, Gdata = %lx \n", Gdata));
+		}
+	}
+
+	//
+	// Check this block is valid for 20MHz in 5G. If invalid, use parameter for 20MHz in 2.4G
+	//
+	bValid = TRUE;
+	for (i=0; i<8; i++)
+	{
+		RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + 2 + i*2, value);
+		if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00))
+		{
+			bValid = FALSE;
+			break;
+		}
+	}
+
+	//
+	// Get Txpower per MCS for 20MHz in 5G.
+	//
+	if (bValid)
+	{
+		for (i=0; i<5; i++)
+		{
+			RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + i*4, value);
+			if (bApwrdeltaMinus == FALSE)
+			{
+				t1 = (value&0xf)+(Apwrdelta);
+				if (t1 > 0xf)
+					t1 = 0xf;
+				t2 = ((value&0xf0)>>4)+(Apwrdelta);
+				if (t2 > 0xf)
+					t2 = 0xf;
+				t3 = ((value&0xf00)>>8)+(Apwrdelta);
+				if (t3 > 0xf)
+					t3 = 0xf;
+				t4 = ((value&0xf000)>>12)+(Apwrdelta);
+				if (t4 > 0xf)
+					t4 = 0xf;
+			}
+			else
+			{
+				if ((value&0xf) > Apwrdelta)
+					t1 = (value&0xf)-(Apwrdelta);
+				else
+					t1 = 0;
+				if (((value&0xf0)>>4) > Apwrdelta)
+					t2 = ((value&0xf0)>>4)-(Apwrdelta);
+				else
+					t2 = 0;
+				if (((value&0xf00)>>8) > Apwrdelta)
+					t3 = ((value&0xf00)>>8)-(Apwrdelta);
+				else
+					t3 = 0;
+				if (((value&0xf000)>>12) > Apwrdelta)
+					t4 = ((value&0xf000)>>12)-(Apwrdelta);
+				else
+					t4 = 0;
+			}
+			Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
+
+			RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + i*4 + 2, value);
+			if (bApwrdeltaMinus == FALSE)
+			{
+				t1 = (value&0xf)+(Apwrdelta);
+				if (t1 > 0xf)
+					t1 = 0xf;
+				t2 = ((value&0xf0)>>4)+(Apwrdelta);
+				if (t2 > 0xf)
+					t2 = 0xf;
+				t3 = ((value&0xf00)>>8)+(Apwrdelta);
+				if (t3 > 0xf)
+					t3 = 0xf;
+				t4 = ((value&0xf000)>>12)+(Apwrdelta);
+				if (t4 > 0xf)
+					t4 = 0xf;
+			}
+			else
+			{
+				if ((value&0xf) > Apwrdelta)
+					t1 = (value&0xf)-(Apwrdelta);
+				else
+					t1 = 0;
+				if (((value&0xf0)>>4) > Apwrdelta)
+					t2 = ((value&0xf0)>>4)-(Apwrdelta);
+				else
+					t2 = 0;
+				if (((value&0xf00)>>8) > Apwrdelta)
+					t3 = ((value&0xf00)>>8)-(Apwrdelta);
+				else
+					t3 = 0;
+				if (((value&0xf000)>>12) > Apwrdelta)
+					t4 = ((value&0xf000)>>12)-(Apwrdelta);
+				else
+					t4 = 0;
+			}
+			Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
+
+			if (i == 0)
+				pAd->Tx20MPwrCfgABand[i] = (pAd->Tx20MPwrCfgABand[i] & 0x0000FFFF) | (Adata & 0xFFFF0000);
+			else
+				pAd->Tx20MPwrCfgABand[i] = Adata;
+
+			DBGPRINT_RAW(RT_DEBUG_TRACE, ("20MHz BW, 5GHz band, Adata = %lx \n", Adata));
+		}
+	}
+
+	//
+	// Check this block is valid for 40MHz in 5G. If invalid, use parameter for 20MHz in 2.4G
+	//
+	bValid = TRUE;
+	for (i=0; i<6; i++)
+	{
+		RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + 2 + i*2, value);
+		if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00))
+		{
+			bValid = FALSE;
+			break;
+		}
+	}
+
+	//
+	// Get Txpower per MCS for 40MHz in 5G.
+	//
+	if (bValid)
+	{
+		for (i=0; i<4; i++)
+		{
+			RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + i*4, value);
+			if (bApwrdeltaMinus == FALSE)
+			{
+				t1 = (value&0xf)+(Apwrdelta);
+				if (t1 > 0xf)
+					t1 = 0xf;
+				t2 = ((value&0xf0)>>4)+(Apwrdelta);
+				if (t2 > 0xf)
+					t2 = 0xf;
+				t3 = ((value&0xf00)>>8)+(Apwrdelta);
+				if (t3 > 0xf)
+					t3 = 0xf;
+				t4 = ((value&0xf000)>>12)+(Apwrdelta);
+				if (t4 > 0xf)
+					t4 = 0xf;
+			}
+			else
+			{
+				if ((value&0xf) > Apwrdelta)
+					t1 = (value&0xf)-(Apwrdelta);
+				else
+					t1 = 0;
+				if (((value&0xf0)>>4) > Apwrdelta)
+					t2 = ((value&0xf0)>>4)-(Apwrdelta);
+				else
+					t2 = 0;
+				if (((value&0xf00)>>8) > Apwrdelta)
+					t3 = ((value&0xf00)>>8)-(Apwrdelta);
+				else
+					t3 = 0;
+				if (((value&0xf000)>>12) > Apwrdelta)
+					t4 = ((value&0xf000)>>12)-(Apwrdelta);
+				else
+					t4 = 0;
+			}
+			Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
+
+			RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + i*4 + 2, value);
+			if (bApwrdeltaMinus == FALSE)
+			{
+				t1 = (value&0xf)+(Apwrdelta);
+				if (t1 > 0xf)
+					t1 = 0xf;
+				t2 = ((value&0xf0)>>4)+(Apwrdelta);
+				if (t2 > 0xf)
+					t2 = 0xf;
+				t3 = ((value&0xf00)>>8)+(Apwrdelta);
+				if (t3 > 0xf)
+					t3 = 0xf;
+				t4 = ((value&0xf000)>>12)+(Apwrdelta);
+				if (t4 > 0xf)
+					t4 = 0xf;
+			}
+			else
+			{
+				if ((value&0xf) > Apwrdelta)
+					t1 = (value&0xf)-(Apwrdelta);
+				else
+					t1 = 0;
+				if (((value&0xf0)>>4) > Apwrdelta)
+					t2 = ((value&0xf0)>>4)-(Apwrdelta);
+				else
+					t2 = 0;
+				if (((value&0xf00)>>8) > Apwrdelta)
+					t3 = ((value&0xf00)>>8)-(Apwrdelta);
+				else
+					t3 = 0;
+				if (((value&0xf000)>>12) > Apwrdelta)
+					t4 = ((value&0xf000)>>12)-(Apwrdelta);
+				else
+					t4 = 0;
+			}
+			Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
+
+			if (i == 0)
+				pAd->Tx40MPwrCfgABand[i+1] = (pAd->Tx40MPwrCfgABand[i+1] & 0x0000FFFF) | (Adata & 0xFFFF0000);
+			else
+				pAd->Tx40MPwrCfgABand[i+1] = Adata;
+
+			DBGPRINT_RAW(RT_DEBUG_TRACE, ("40MHz BW, 5GHz band, Adata = %lx \n", Adata));
+		}
+	}
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Read initial channel power parameters from EEPROM
+
+	Arguments:
+		Adapter						Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTMPReadChannelPwr(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	UCHAR				i, choffset;
+	EEPROM_TX_PWR_STRUC	    Power;
+	EEPROM_TX_PWR_STRUC	    Power2;
+
+	// Read Tx power value for all channels
+	// Value from 1 - 0x7f. Default value is 24.
+	// Power value : 2.4G 0x00 (0) ~ 0x1F (31)
+	//             : 5.5G 0xF9 (-7) ~ 0x0F (15)
+
+	// 0. 11b/g, ch1 - ch 14
+	for (i = 0; i < 7; i++)
+	{
+//		Power.word = RTMP_EEPROM_READ16(pAd, EEPROM_G_TX_PWR_OFFSET + i * 2);
+//		Power2.word = RTMP_EEPROM_READ16(pAd, EEPROM_G_TX2_PWR_OFFSET + i * 2);
+		RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX_PWR_OFFSET + i * 2, Power.word);
+		RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX2_PWR_OFFSET + i * 2, Power2.word);
+		pAd->TxPower[i * 2].Channel = i * 2 + 1;
+		pAd->TxPower[i * 2 + 1].Channel = i * 2 + 2;
+
+		if ((Power.field.Byte0 > 31) || (Power.field.Byte0 < 0))
+			pAd->TxPower[i * 2].Power = DEFAULT_RF_TX_POWER;
+		else
+			pAd->TxPower[i * 2].Power = Power.field.Byte0;
+
+		if ((Power.field.Byte1 > 31) || (Power.field.Byte1 < 0))
+			pAd->TxPower[i * 2 + 1].Power = DEFAULT_RF_TX_POWER;
+		else
+			pAd->TxPower[i * 2 + 1].Power = Power.field.Byte1;
+
+		if ((Power2.field.Byte0 > 31) || (Power2.field.Byte0 < 0))
+			pAd->TxPower[i * 2].Power2 = DEFAULT_RF_TX_POWER;
+		else
+			pAd->TxPower[i * 2].Power2 = Power2.field.Byte0;
+
+		if ((Power2.field.Byte1 > 31) || (Power2.field.Byte1 < 0))
+			pAd->TxPower[i * 2 + 1].Power2 = DEFAULT_RF_TX_POWER;
+		else
+			pAd->TxPower[i * 2 + 1].Power2 = Power2.field.Byte1;
+	}
+
+	// 1. U-NII lower/middle band: 36, 38, 40; 44, 46, 48; 52, 54, 56; 60, 62, 64 (including central frequency in BW 40MHz)
+	// 1.1 Fill up channel
+	choffset = 14;
+	for (i = 0; i < 4; i++)
+	{
+		pAd->TxPower[3 * i + choffset + 0].Channel	= 36 + i * 8 + 0;
+		pAd->TxPower[3 * i + choffset + 0].Power	= DEFAULT_RF_TX_POWER;
+		pAd->TxPower[3 * i + choffset + 0].Power2	= DEFAULT_RF_TX_POWER;
+
+		pAd->TxPower[3 * i + choffset + 1].Channel	= 36 + i * 8 + 2;
+		pAd->TxPower[3 * i + choffset + 1].Power	= DEFAULT_RF_TX_POWER;
+		pAd->TxPower[3 * i + choffset + 1].Power2	= DEFAULT_RF_TX_POWER;
+
+		pAd->TxPower[3 * i + choffset + 2].Channel	= 36 + i * 8 + 4;
+		pAd->TxPower[3 * i + choffset + 2].Power	= DEFAULT_RF_TX_POWER;
+		pAd->TxPower[3 * i + choffset + 2].Power2	= DEFAULT_RF_TX_POWER;
+	}
+
+	// 1.2 Fill up power
+	for (i = 0; i < 6; i++)
+	{
+//		Power.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + i * 2);
+//		Power2.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + i * 2);
+		RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + i * 2, Power.word);
+		RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + i * 2, Power2.word);
+
+		if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
+			pAd->TxPower[i * 2 + choffset + 0].Power = Power.field.Byte0;
+
+		if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
+			pAd->TxPower[i * 2 + choffset + 1].Power = Power.field.Byte1;
+
+		if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
+			pAd->TxPower[i * 2 + choffset + 0].Power2 = Power2.field.Byte0;
+
+		if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
+			pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1;
+	}
+
+	// 2. HipperLAN 2 100, 102 ,104; 108, 110, 112; 116, 118, 120; 124, 126, 128; 132, 134, 136; 140 (including central frequency in BW 40MHz)
+	// 2.1 Fill up channel
+	choffset = 14 + 12;
+	for (i = 0; i < 5; i++)
+	{
+		pAd->TxPower[3 * i + choffset + 0].Channel	= 100 + i * 8 + 0;
+		pAd->TxPower[3 * i + choffset + 0].Power	= DEFAULT_RF_TX_POWER;
+		pAd->TxPower[3 * i + choffset + 0].Power2	= DEFAULT_RF_TX_POWER;
+
+		pAd->TxPower[3 * i + choffset + 1].Channel	= 100 + i * 8 + 2;
+		pAd->TxPower[3 * i + choffset + 1].Power	= DEFAULT_RF_TX_POWER;
+		pAd->TxPower[3 * i + choffset + 1].Power2	= DEFAULT_RF_TX_POWER;
+
+		pAd->TxPower[3 * i + choffset + 2].Channel	= 100 + i * 8 + 4;
+		pAd->TxPower[3 * i + choffset + 2].Power	= DEFAULT_RF_TX_POWER;
+		pAd->TxPower[3 * i + choffset + 2].Power2	= DEFAULT_RF_TX_POWER;
+	}
+	pAd->TxPower[3 * 5 + choffset + 0].Channel		= 140;
+	pAd->TxPower[3 * 5 + choffset + 0].Power		= DEFAULT_RF_TX_POWER;
+	pAd->TxPower[3 * 5 + choffset + 0].Power2		= DEFAULT_RF_TX_POWER;
+
+	// 2.2 Fill up power
+	for (i = 0; i < 8; i++)
+	{
+//		Power.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2);
+//		Power2.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2);
+		RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2, Power.word);
+		RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2, Power2.word);
+
+		if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
+			pAd->TxPower[i * 2 + choffset + 0].Power = Power.field.Byte0;
+
+		if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
+			pAd->TxPower[i * 2 + choffset + 1].Power = Power.field.Byte1;
+
+		if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
+			pAd->TxPower[i * 2 + choffset + 0].Power2 = Power2.field.Byte0;
+
+		if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
+			pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1;
+	}
+
+	// 3. U-NII upper band: 149, 151, 153; 157, 159, 161; 165 (including central frequency in BW 40MHz)
+	// 3.1 Fill up channel
+	choffset = 14 + 12 + 16;
+	for (i = 0; i < 2; i++)
+	{
+		pAd->TxPower[3 * i + choffset + 0].Channel	= 149 + i * 8 + 0;
+		pAd->TxPower[3 * i + choffset + 0].Power	= DEFAULT_RF_TX_POWER;
+		pAd->TxPower[3 * i + choffset + 0].Power2	= DEFAULT_RF_TX_POWER;
+
+		pAd->TxPower[3 * i + choffset + 1].Channel	= 149 + i * 8 + 2;
+		pAd->TxPower[3 * i + choffset + 1].Power	= DEFAULT_RF_TX_POWER;
+		pAd->TxPower[3 * i + choffset + 1].Power2	= DEFAULT_RF_TX_POWER;
+
+		pAd->TxPower[3 * i + choffset + 2].Channel	= 149 + i * 8 + 4;
+		pAd->TxPower[3 * i + choffset + 2].Power	= DEFAULT_RF_TX_POWER;
+		pAd->TxPower[3 * i + choffset + 2].Power2	= DEFAULT_RF_TX_POWER;
+	}
+	pAd->TxPower[3 * 2 + choffset + 0].Channel		= 165;
+	pAd->TxPower[3 * 2 + choffset + 0].Power		= DEFAULT_RF_TX_POWER;
+	pAd->TxPower[3 * 2 + choffset + 0].Power2		= DEFAULT_RF_TX_POWER;
+
+	// 3.2 Fill up power
+	for (i = 0; i < 4; i++)
+	{
+//		Power.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2);
+//		Power2.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2);
+		RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2, Power.word);
+		RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2, Power2.word);
+
+		if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
+			pAd->TxPower[i * 2 + choffset + 0].Power = Power.field.Byte0;
+
+		if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
+			pAd->TxPower[i * 2 + choffset + 1].Power = Power.field.Byte1;
+
+		if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
+			pAd->TxPower[i * 2 + choffset + 0].Power2 = Power2.field.Byte0;
+
+		if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
+			pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1;
+	}
+
+	// 4. Print and Debug
+	choffset = 14 + 12 + 16 + 7;
+
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Read the following from the registry
+		1. All the parameters
+		2. NetworkAddres
+
+	Arguments:
+		Adapter						Pointer to our adapter
+		WrapperConfigurationContext	For use by NdisOpenConfiguration
+
+	Return Value:
+		NDIS_STATUS_SUCCESS
+		NDIS_STATUS_FAILURE
+		NDIS_STATUS_RESOURCES
+
+	IRQL = PASSIVE_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+NDIS_STATUS	NICReadRegParameters(
+	IN	PRTMP_ADAPTER		pAd,
+	IN	NDIS_HANDLE			WrapperConfigurationContext
+	)
+{
+	NDIS_STATUS						Status = NDIS_STATUS_SUCCESS;
+	DBGPRINT_S(Status, ("<-- NICReadRegParameters, Status=%x\n", Status));
+	return Status;
+}
+
+
+#ifdef RT30xx
+/*
+	========================================================================
+
+	Routine Description:
+		For RF filter calibration purpose
+
+	Arguments:
+		pAd                          Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+
+	========================================================================
+*/
+VOID RTMPFilterCalibration(
+	IN PRTMP_ADAPTER pAd)
+{
+	UCHAR	R55x = 0, value, FilterTarget = 0x1E, BBPValue=0;
+	UINT	loop = 0, count = 0, loopcnt = 0, ReTry = 0;
+	UCHAR	RF_R24_Value = 0;
+
+	// Give bbp filter initial value
+	pAd->Mlme.CaliBW20RfR24 = 0x1F;
+	pAd->Mlme.CaliBW40RfR24 = 0x2F; //Bit[5] must be 1 for BW 40
+
+	do
+	{
+		if (loop == 1)	//BandWidth = 40 MHz
+		{
+			// Write 0x27 to RF_R24 to program filter
+			RF_R24_Value = 0x27;
+			RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
+			if (IS_RT3090(pAd))
+				FilterTarget = 0x15;
+			else
+				FilterTarget = 0x19;
+
+			// when calibrate BW40, BBP mask must set to BW40.
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+			BBPValue&= (~0x18);
+			BBPValue|= (0x10);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+
+			// set to BW40
+			RT30xxReadRFRegister(pAd, RF_R31, &value);
+			value |= 0x20;
+			RT30xxWriteRFRegister(pAd, RF_R31, value);
+		}
+		else			//BandWidth = 20 MHz
+		{
+			// Write 0x07 to RF_R24 to program filter
+			RF_R24_Value = 0x07;
+			RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
+			if (IS_RT3090(pAd))
+				FilterTarget = 0x13;
+			else
+				FilterTarget = 0x16;
+
+			// set to BW20
+			RT30xxReadRFRegister(pAd, RF_R31, &value);
+			value &= (~0x20);
+			RT30xxWriteRFRegister(pAd, RF_R31, value);
+		}
+
+		// Write 0x01 to RF_R22 to enable baseband loopback mode
+		RT30xxReadRFRegister(pAd, RF_R22, &value);
+		value |= 0x01;
+		RT30xxWriteRFRegister(pAd, RF_R22, value);
+
+		// Write 0x00 to BBP_R24 to set power & frequency of passband test tone
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
+
+		do
+		{
+			// Write 0x90 to BBP_R25 to transmit test tone
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
+
+			RTMPusecDelay(1000);
+			// Read BBP_R55[6:0] for received power, set R55x = BBP_R55[6:0]
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
+			R55x = value & 0xFF;
+
+		} while ((ReTry++ < 100) && (R55x == 0));
+
+		// Write 0x06 to BBP_R24 to set power & frequency of stopband test tone
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0x06);
+
+		while(TRUE)
+		{
+			// Write 0x90 to BBP_R25 to transmit test tone
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
+
+			//We need to wait for calibration
+			RTMPusecDelay(1000);
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
+			value &= 0xFF;
+			if ((R55x - value) < FilterTarget)
+			{
+				RF_R24_Value ++;
+			}
+			else if ((R55x - value) == FilterTarget)
+			{
+				RF_R24_Value ++;
+				count ++;
+			}
+			else
+			{
+				break;
+			}
+
+			// prevent infinite loop cause driver hang.
+			if (loopcnt++ > 100)
+			{
+				DBGPRINT(RT_DEBUG_ERROR, ("RTMPFilterCalibration - can't find a valid value, loopcnt=%d stop calibrating", loopcnt));
+				break;
+			}
+
+			// Write RF_R24 to program filter
+			RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
+		}
+
+		if (count > 0)
+		{
+			RF_R24_Value = RF_R24_Value - ((count) ? (1) : (0));
+		}
+
+		// Store for future usage
+		if (loopcnt < 100)
+		{
+			if (loop++ == 0)
+			{
+				//BandWidth = 20 MHz
+				pAd->Mlme.CaliBW20RfR24 = (UCHAR)RF_R24_Value;
+			}
+			else
+			{
+				//BandWidth = 40 MHz
+				pAd->Mlme.CaliBW40RfR24 = (UCHAR)RF_R24_Value;
+				break;
+			}
+		}
+		else
+			break;
+
+		RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
+
+		// reset count
+		count = 0;
+	} while(TRUE);
+
+	//
+	// Set back to initial state
+	//
+	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
+
+	RT30xxReadRFRegister(pAd, RF_R22, &value);
+	value &= ~(0x01);
+	RT30xxWriteRFRegister(pAd, RF_R22, value);
+
+	// set BBP back to BW20
+	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+	BBPValue&= (~0x18);
+	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("RTMPFilterCalibration - CaliBW20RfR24=0x%x, CaliBW40RfR24=0x%x\n", pAd->Mlme.CaliBW20RfR24, pAd->Mlme.CaliBW40RfR24));
+}
+#endif // RT30xx //
+
+
+#ifdef RT3070
+VOID NICInitRT30xxRFRegisters(IN PRTMP_ADAPTER pAd)
+{
+	INT i;
+	// Driver must read EEPROM to get RfIcType before initial RF registers
+	// Initialize RF register to default value
+	if (IS_RT3070(pAd) || IS_RT3071(pAd))
+	{
+		// Init RF calibration
+		// Driver should toggle RF R30 bit7 before init RF registers
+		UINT32 RfReg = 0;
+		UINT32 data;
+
+		RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RfReg);
+		RfReg |= 0x80;
+		RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
+		RTMPusecDelay(1000);
+		RfReg &= 0x7F;
+		RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
+
+		// Initialize RF register to default value
+		for (i = 0; i < NUM_RF_REG_PARMS; i++)
+		{
+			RT30xxWriteRFRegister(pAd, RT30xx_RFRegTable[i].Register, RT30xx_RFRegTable[i].Value);
+		}
+
+		// add by johnli
+		if (IS_RT3070(pAd))
+		{
+			//  Update MAC 0x05D4 from 01xxxxxx to 0Dxxxxxx (voltage 1.2V to 1.35V) for RT3070 to improve yield rate
+			RTUSBReadMACRegister(pAd, LDO_CFG0, &data);
+			data = ((data & 0xF0FFFFFF) | 0x0D000000);
+			RTUSBWriteMACRegister(pAd, LDO_CFG0, data);
+		}
+		else if (IS_RT3071(pAd))
+		{
+			// Driver should set RF R6 bit6 on before init RF registers
+			RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RfReg);
+			RfReg |= 0x40;
+			RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RfReg);
+
+			// init R31
+			RT30xxWriteRFRegister(pAd, RF_R31, 0x14);
+
+			// RT3071 version E has fixed this issue
+			if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211))
+			{
+				// patch tx EVM issue temporarily
+				RTUSBReadMACRegister(pAd, LDO_CFG0, &data);
+				data = ((data & 0xE0FFFFFF) | 0x0D000000);
+				RTUSBWriteMACRegister(pAd, LDO_CFG0, data);
+			}
+			else
+			{
+				RTMP_IO_READ32(pAd, LDO_CFG0, &data);
+				data = ((data & 0xE0FFFFFF) | 0x01000000);
+				RTMP_IO_WRITE32(pAd, LDO_CFG0, data);
+			}
+
+			// patch LNA_PE_G1 failed issue
+			RTUSBReadMACRegister(pAd, GPIO_SWITCH, &data);
+			data &= ~(0x20);
+			RTUSBWriteMACRegister(pAd, GPIO_SWITCH, data);
+		}
+
+		//For RF filter Calibration
+		RTMPFilterCalibration(pAd);
+
+		// Initialize RF R27 register, set RF R27 must be behind RTMPFilterCalibration()
+		if ((pAd->MACVersion & 0xffff) < 0x0211)
+			RT30xxWriteRFRegister(pAd, RF_R27, 0x3);
+
+		// set led open drain enable
+		RTUSBReadMACRegister(pAd, OPT_14, &data);
+		data |= 0x01;
+		RTUSBWriteMACRegister(pAd, OPT_14, data);
+
+		if (IS_RT3071(pAd))
+		{
+			// add by johnli, RF power sequence setup, load RF normal operation-mode setup
+			RT30xxLoadRFNormalModeSetup(pAd);
+		}
+	}
+
+}
+#endif // RT3070 //
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Read initial parameters from EEPROM
+
+	Arguments:
+		Adapter						Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+VOID	NICReadEEPROMParameters(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			mac_addr)
+{
+	UINT32			data = 0;
+	USHORT			i, value, value2;
+	UCHAR			TmpPhy;
+	EEPROM_TX_PWR_STRUC	    Power;
+	EEPROM_VERSION_STRUC    Version;
+	EEPROM_ANTENNA_STRUC	Antenna;
+	EEPROM_NIC_CONFIG2_STRUC    NicConfig2;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--> NICReadEEPROMParameters\n"));
+
+	// Init EEPROM Address Number, before access EEPROM; if 93c46, EEPROMAddressNum=6, else if 93c66, EEPROMAddressNum=8
+	RTMP_IO_READ32(pAd, E2PROM_CSR, &data);
+	DBGPRINT(RT_DEBUG_TRACE, ("--> E2PROM_CSR = 0x%x\n", data));
+
+	if((data & 0x30) == 0)
+		pAd->EEPROMAddressNum = 6;		// 93C46
+	else if((data & 0x30) == 0x10)
+		pAd->EEPROMAddressNum = 8;     // 93C66
+	else
+		pAd->EEPROMAddressNum = 8;     // 93C86
+	DBGPRINT(RT_DEBUG_TRACE, ("--> EEPROMAddressNum = %d\n", pAd->EEPROMAddressNum ));
+
+	// RT2860 MAC no longer auto load MAC address from E2PROM. Driver has to intialize
+	// MAC address registers according to E2PROM setting
+	if (mac_addr == NULL ||
+		strlen(mac_addr) != 17 ||
+		mac_addr[2] != ':'  || mac_addr[5] != ':'  || mac_addr[8] != ':' ||
+		mac_addr[11] != ':' || mac_addr[14] != ':')
+	{
+		USHORT  Addr01,Addr23,Addr45 ;
+
+		RT28xx_EEPROM_READ16(pAd, 0x04, Addr01);
+		RT28xx_EEPROM_READ16(pAd, 0x06, Addr23);
+		RT28xx_EEPROM_READ16(pAd, 0x08, Addr45);
+
+		pAd->PermanentAddress[0] = (UCHAR)(Addr01 & 0xff);
+		pAd->PermanentAddress[1] = (UCHAR)(Addr01 >> 8);
+		pAd->PermanentAddress[2] = (UCHAR)(Addr23 & 0xff);
+		pAd->PermanentAddress[3] = (UCHAR)(Addr23 >> 8);
+		pAd->PermanentAddress[4] = (UCHAR)(Addr45 & 0xff);
+		pAd->PermanentAddress[5] = (UCHAR)(Addr45 >> 8);
+
+		DBGPRINT(RT_DEBUG_TRACE, ("Initialize MAC Address from E2PROM \n"));
+	}
+	else
+	{
+		INT		j;
+		PUCHAR	macptr;
+
+		macptr = mac_addr;
+
+		for (j=0; j<MAC_ADDR_LEN; j++)
+		{
+			AtoH(macptr, &pAd->PermanentAddress[j], 1);
+			macptr=macptr+3;
+		}
+
+		DBGPRINT(RT_DEBUG_TRACE, ("Initialize MAC Address from module parameter \n"));
+	}
+
+
+	{
+		//more conveninet to test mbssid, so ap's bssid &0xf1
+		if (pAd->PermanentAddress[0] == 0xff)
+			pAd->PermanentAddress[0] = RandomByte(pAd)&0xf8;
+
+		//if (pAd->PermanentAddress[5] == 0xff)
+		//	pAd->PermanentAddress[5] = RandomByte(pAd)&0xf8;
+
+		DBGPRINT_RAW(RT_DEBUG_TRACE,("E2PROM MAC: =%02x:%02x:%02x:%02x:%02x:%02x\n",
+			pAd->PermanentAddress[0], pAd->PermanentAddress[1],
+			pAd->PermanentAddress[2], pAd->PermanentAddress[3],
+			pAd->PermanentAddress[4], pAd->PermanentAddress[5]));
+		if (pAd->bLocalAdminMAC == FALSE)
+		{
+			MAC_DW0_STRUC csr2;
+			MAC_DW1_STRUC csr3;
+			COPY_MAC_ADDR(pAd->CurrentAddress, pAd->PermanentAddress);
+			csr2.field.Byte0 = pAd->CurrentAddress[0];
+			csr2.field.Byte1 = pAd->CurrentAddress[1];
+			csr2.field.Byte2 = pAd->CurrentAddress[2];
+			csr2.field.Byte3 = pAd->CurrentAddress[3];
+			RTMP_IO_WRITE32(pAd, MAC_ADDR_DW0, csr2.word);
+			csr3.word = 0;
+			csr3.field.Byte4 = pAd->CurrentAddress[4];
+			csr3.field.Byte5 = pAd->CurrentAddress[5];
+			csr3.field.U2MeMask = 0xff;
+			RTMP_IO_WRITE32(pAd, MAC_ADDR_DW1, csr3.word);
+			DBGPRINT_RAW(RT_DEBUG_TRACE,("E2PROM MAC: =%02x:%02x:%02x:%02x:%02x:%02x\n",
+				pAd->PermanentAddress[0], pAd->PermanentAddress[1],
+				pAd->PermanentAddress[2], pAd->PermanentAddress[3],
+				pAd->PermanentAddress[4], pAd->PermanentAddress[5]));
+		}
+	}
+
+	// if not return early. cause fail at emulation.
+	// Init the channel number for TX channel power
+	RTMPReadChannelPwr(pAd);
+
+	// if E2PROM version mismatch with driver's expectation, then skip
+	// all subsequent E2RPOM retieval and set a system error bit to notify GUI
+	RT28xx_EEPROM_READ16(pAd, EEPROM_VERSION_OFFSET, Version.word);
+	pAd->EepromVersion = Version.field.Version + Version.field.FaeReleaseNumber * 256;
+	DBGPRINT(RT_DEBUG_TRACE, ("E2PROM: Version = %d, FAE release #%d\n", Version.field.Version, Version.field.FaeReleaseNumber));
+
+	if (Version.field.Version > VALID_EEPROM_VERSION)
+	{
+		DBGPRINT_ERR(("E2PROM: WRONG VERSION 0x%x, should be %d\n",Version.field.Version, VALID_EEPROM_VERSION));
+		/*pAd->SystemErrorBitmap |= 0x00000001;
+
+		// hard-code default value when no proper E2PROM installed
+		pAd->bAutoTxAgcA = FALSE;
+		pAd->bAutoTxAgcG = FALSE;
+
+		// Default the channel power
+		for (i = 0; i < MAX_NUM_OF_CHANNELS; i++)
+			pAd->TxPower[i].Power = DEFAULT_RF_TX_POWER;
+
+		// Default the channel power
+		for (i = 0; i < MAX_NUM_OF_11JCHANNELS; i++)
+			pAd->TxPower11J[i].Power = DEFAULT_RF_TX_POWER;
+
+		for(i = 0; i < NUM_EEPROM_BBP_PARMS; i++)
+			pAd->EEPROMDefaultValue[i] = 0xffff;
+		return;  */
+	}
+
+	// Read BBP default value from EEPROM and store to array(EEPROMDefaultValue) in pAd
+	RT28xx_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET, value);
+	pAd->EEPROMDefaultValue[0] = value;
+
+	RT28xx_EEPROM_READ16(pAd, EEPROM_NIC2_OFFSET, value);
+	pAd->EEPROMDefaultValue[1] = value;
+
+	RT28xx_EEPROM_READ16(pAd, 0x38, value);	// Country Region
+	pAd->EEPROMDefaultValue[2] = value;
+
+	for(i = 0; i < 8; i++)
+	{
+		RT28xx_EEPROM_READ16(pAd, EEPROM_BBP_BASE_OFFSET + i*2, value);
+		pAd->EEPROMDefaultValue[i+3] = value;
+	}
+
+	// We have to parse NIC configuration 0 at here.
+	// If TSSI did not have preloaded value, it should reset the TxAutoAgc to false
+	// Therefore, we have to read TxAutoAgc control beforehand.
+	// Read Tx AGC control bit
+	Antenna.word = pAd->EEPROMDefaultValue[0];
+	if (Antenna.word == 0xFFFF)
+	{
+#ifdef RT30xx
+		if(IS_RT3090(pAd))
+		{
+			Antenna.word = 0;
+			Antenna.field.RfIcType = RFIC_3020;
+			Antenna.field.TxPath = 1;
+			Antenna.field.RxPath = 1;
+		}
+		else
+		{
+#endif // RT30xx //
+			Antenna.word = 0;
+			Antenna.field.RfIcType = RFIC_2820;
+			Antenna.field.TxPath = 1;
+			Antenna.field.RxPath = 2;
+			DBGPRINT(RT_DEBUG_WARN, ("E2PROM error, hard code as 0x%04x\n", Antenna.word));
+#ifdef RT30xx
+		}
+#endif // RT30xx //
+	}
+
+	// Choose the desired Tx&Rx stream.
+	if ((pAd->CommonCfg.TxStream == 0) || (pAd->CommonCfg.TxStream > Antenna.field.TxPath))
+		pAd->CommonCfg.TxStream = Antenna.field.TxPath;
+
+	if ((pAd->CommonCfg.RxStream == 0) || (pAd->CommonCfg.RxStream > Antenna.field.RxPath))
+	{
+		pAd->CommonCfg.RxStream = Antenna.field.RxPath;
+
+		if ((pAd->MACVersion < RALINK_2883_VERSION) &&
+			(pAd->CommonCfg.RxStream > 2))
+		{
+			// only 2 Rx streams for RT2860 series
+			pAd->CommonCfg.RxStream = 2;
+		}
+	}
+
+	// 3*3
+	// read value from EEPROM and set them to CSR174 ~ 177 in chain0 ~ chain2
+	// yet implement
+	for(i=0; i<3; i++)
+	{
+	}
+
+	NicConfig2.word = pAd->EEPROMDefaultValue[1];
+
+
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		if ((NicConfig2.word & 0x00ff) == 0xff)
+		{
+			NicConfig2.word &= 0xff00;
+		}
+
+		if ((NicConfig2.word >> 8) == 0xff)
+		{
+			NicConfig2.word &= 0x00ff;
+		}
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	if (NicConfig2.field.DynamicTxAgcControl == 1)
+		pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE;
+	else
+		pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE;
+
+	DBGPRINT_RAW(RT_DEBUG_TRACE, ("NICReadEEPROMParameters: RxPath = %d, TxPath = %d\n", Antenna.field.RxPath, Antenna.field.TxPath));
+
+	// Save the antenna for future use
+	pAd->Antenna.word = Antenna.word;
+
+	//
+	// Reset PhyMode if we don't support 802.11a
+	// Only RFIC_2850 & RFIC_2750 support 802.11a
+	//
+	if ((Antenna.field.RfIcType != RFIC_2850) && (Antenna.field.RfIcType != RFIC_2750))
+	{
+		if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED) ||
+			(pAd->CommonCfg.PhyMode == PHY_11A))
+			pAd->CommonCfg.PhyMode = PHY_11BG_MIXED;
+#ifdef DOT11_N_SUPPORT
+		else if ((pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED)	||
+				 (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED) 	||
+				 (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) 	||
+				 (pAd->CommonCfg.PhyMode == PHY_11N_5G))
+			pAd->CommonCfg.PhyMode = PHY_11BGN_MIXED;
+#endif // DOT11_N_SUPPORT //
+	}
+
+	// Read TSSI reference and TSSI boundary for temperature compensation. This is ugly
+	// 0. 11b/g
+	{
+		/* these are tempature reference value (0x00 ~ 0xFE)
+		   ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
+		   TssiPlusBoundaryG [4] [3] [2] [1] [0] (smaller) +
+		   TssiMinusBoundaryG[0] [1] [2] [3] [4] (larger) */
+		RT28xx_EEPROM_READ16(pAd, 0x6E, Power.word);
+		pAd->TssiMinusBoundaryG[4] = Power.field.Byte0;
+		pAd->TssiMinusBoundaryG[3] = Power.field.Byte1;
+		RT28xx_EEPROM_READ16(pAd, 0x70, Power.word);
+		pAd->TssiMinusBoundaryG[2] = Power.field.Byte0;
+		pAd->TssiMinusBoundaryG[1] = Power.field.Byte1;
+		RT28xx_EEPROM_READ16(pAd, 0x72, Power.word);
+		pAd->TssiRefG   = Power.field.Byte0; /* reference value [0] */
+		pAd->TssiPlusBoundaryG[1] = Power.field.Byte1;
+		RT28xx_EEPROM_READ16(pAd, 0x74, Power.word);
+		pAd->TssiPlusBoundaryG[2] = Power.field.Byte0;
+		pAd->TssiPlusBoundaryG[3] = Power.field.Byte1;
+		RT28xx_EEPROM_READ16(pAd, 0x76, Power.word);
+		pAd->TssiPlusBoundaryG[4] = Power.field.Byte0;
+		pAd->TxAgcStepG = Power.field.Byte1;
+		pAd->TxAgcCompensateG = 0;
+		pAd->TssiMinusBoundaryG[0] = pAd->TssiRefG;
+		pAd->TssiPlusBoundaryG[0]  = pAd->TssiRefG;
+
+		// Disable TxAgc if the based value is not right
+		if (pAd->TssiRefG == 0xff)
+			pAd->bAutoTxAgcG = FALSE;
+
+		DBGPRINT(RT_DEBUG_TRACE,("E2PROM: G Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n",
+			pAd->TssiMinusBoundaryG[4], pAd->TssiMinusBoundaryG[3], pAd->TssiMinusBoundaryG[2], pAd->TssiMinusBoundaryG[1],
+			pAd->TssiRefG,
+			pAd->TssiPlusBoundaryG[1], pAd->TssiPlusBoundaryG[2], pAd->TssiPlusBoundaryG[3], pAd->TssiPlusBoundaryG[4],
+			pAd->TxAgcStepG, pAd->bAutoTxAgcG));
+	}
+	// 1. 11a
+	{
+		RT28xx_EEPROM_READ16(pAd, 0xD4, Power.word);
+		pAd->TssiMinusBoundaryA[4] = Power.field.Byte0;
+		pAd->TssiMinusBoundaryA[3] = Power.field.Byte1;
+		RT28xx_EEPROM_READ16(pAd, 0xD6, Power.word);
+		pAd->TssiMinusBoundaryA[2] = Power.field.Byte0;
+		pAd->TssiMinusBoundaryA[1] = Power.field.Byte1;
+		RT28xx_EEPROM_READ16(pAd, 0xD8, Power.word);
+		pAd->TssiRefA   = Power.field.Byte0;
+		pAd->TssiPlusBoundaryA[1] = Power.field.Byte1;
+		RT28xx_EEPROM_READ16(pAd, 0xDA, Power.word);
+		pAd->TssiPlusBoundaryA[2] = Power.field.Byte0;
+		pAd->TssiPlusBoundaryA[3] = Power.field.Byte1;
+		RT28xx_EEPROM_READ16(pAd, 0xDC, Power.word);
+		pAd->TssiPlusBoundaryA[4] = Power.field.Byte0;
+		pAd->TxAgcStepA = Power.field.Byte1;
+		pAd->TxAgcCompensateA = 0;
+		pAd->TssiMinusBoundaryA[0] = pAd->TssiRefA;
+		pAd->TssiPlusBoundaryA[0]  = pAd->TssiRefA;
+
+		// Disable TxAgc if the based value is not right
+		if (pAd->TssiRefA == 0xff)
+			pAd->bAutoTxAgcA = FALSE;
+
+		DBGPRINT(RT_DEBUG_TRACE,("E2PROM: A Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n",
+			pAd->TssiMinusBoundaryA[4], pAd->TssiMinusBoundaryA[3], pAd->TssiMinusBoundaryA[2], pAd->TssiMinusBoundaryA[1],
+			pAd->TssiRefA,
+			pAd->TssiPlusBoundaryA[1], pAd->TssiPlusBoundaryA[2], pAd->TssiPlusBoundaryA[3], pAd->TssiPlusBoundaryA[4],
+			pAd->TxAgcStepA, pAd->bAutoTxAgcA));
+	}
+	pAd->BbpRssiToDbmDelta = 0x0;
+
+	// Read frequency offset setting for RF
+	RT28xx_EEPROM_READ16(pAd, EEPROM_FREQ_OFFSET, value);
+	if ((value & 0x00FF) != 0x00FF)
+		pAd->RfFreqOffset = (ULONG) (value & 0x00FF);
+	else
+		pAd->RfFreqOffset = 0;
+	DBGPRINT(RT_DEBUG_TRACE, ("E2PROM: RF FreqOffset=0x%lx \n", pAd->RfFreqOffset));
+
+	//CountryRegion byte offset (38h)
+	value = pAd->EEPROMDefaultValue[2] >> 8;		// 2.4G band
+	value2 = pAd->EEPROMDefaultValue[2] & 0x00FF;	// 5G band
+
+	if ((value <= REGION_MAXIMUM_BG_BAND) && (value2 <= REGION_MAXIMUM_A_BAND))
+	{
+		pAd->CommonCfg.CountryRegion = ((UCHAR) value) | 0x80;
+		pAd->CommonCfg.CountryRegionForABand = ((UCHAR) value2) | 0x80;
+		TmpPhy = pAd->CommonCfg.PhyMode;
+		pAd->CommonCfg.PhyMode = 0xff;
+		RTMPSetPhyMode(pAd, TmpPhy);
+#ifdef DOT11_N_SUPPORT
+		SetCommonHT(pAd);
+#endif // DOT11_N_SUPPORT //
+	}
+
+	//
+	// Get RSSI Offset on EEPROM 0x9Ah & 0x9Ch.
+	// The valid value are (-10 ~ 10)
+	//
+	RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET, value);
+	pAd->BGRssiOffset0 = value & 0x00ff;
+	pAd->BGRssiOffset1 = (value >> 8);
+	RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET+2, value);
+	pAd->BGRssiOffset2 = value & 0x00ff;
+	pAd->ALNAGain1 = (value >> 8);
+	RT28xx_EEPROM_READ16(pAd, EEPROM_LNA_OFFSET, value);
+	pAd->BLNAGain = value & 0x00ff;
+	pAd->ALNAGain0 = (value >> 8);
+
+	// Validate 11b/g RSSI_0 offset.
+	if ((pAd->BGRssiOffset0 < -10) || (pAd->BGRssiOffset0 > 10))
+		pAd->BGRssiOffset0 = 0;
+
+	// Validate 11b/g RSSI_1 offset.
+	if ((pAd->BGRssiOffset1 < -10) || (pAd->BGRssiOffset1 > 10))
+		pAd->BGRssiOffset1 = 0;
+
+	// Validate 11b/g RSSI_2 offset.
+	if ((pAd->BGRssiOffset2 < -10) || (pAd->BGRssiOffset2 > 10))
+		pAd->BGRssiOffset2 = 0;
+
+	RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_A_OFFSET, value);
+	pAd->ARssiOffset0 = value & 0x00ff;
+	pAd->ARssiOffset1 = (value >> 8);
+	RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_A_OFFSET+2), value);
+	pAd->ARssiOffset2 = value & 0x00ff;
+	pAd->ALNAGain2 = (value >> 8);
+
+	if (((UCHAR)pAd->ALNAGain1 == 0xFF) || (pAd->ALNAGain1 == 0x00))
+		pAd->ALNAGain1 = pAd->ALNAGain0;
+	if (((UCHAR)pAd->ALNAGain2 == 0xFF) || (pAd->ALNAGain2 == 0x00))
+		pAd->ALNAGain2 = pAd->ALNAGain0;
+
+	// Validate 11a RSSI_0 offset.
+	if ((pAd->ARssiOffset0 < -10) || (pAd->ARssiOffset0 > 10))
+		pAd->ARssiOffset0 = 0;
+
+	// Validate 11a RSSI_1 offset.
+	if ((pAd->ARssiOffset1 < -10) || (pAd->ARssiOffset1 > 10))
+		pAd->ARssiOffset1 = 0;
+
+	//Validate 11a RSSI_2 offset.
+	if ((pAd->ARssiOffset2 < -10) || (pAd->ARssiOffset2 > 10))
+		pAd->ARssiOffset2 = 0;
+
+	//
+	// Get LED Setting.
+	//
+	RT28xx_EEPROM_READ16(pAd, 0x3a, value);
+	pAd->LedCntl.word = (value&0xff00) >> 8;
+	RT28xx_EEPROM_READ16(pAd, EEPROM_LED1_OFFSET, value);
+	pAd->Led1 = value;
+	RT28xx_EEPROM_READ16(pAd, EEPROM_LED2_OFFSET, value);
+	pAd->Led2 = value;
+	RT28xx_EEPROM_READ16(pAd, EEPROM_LED3_OFFSET, value);
+	pAd->Led3 = value;
+
+	RTMPReadTxPwrPerRate(pAd);
+
+#ifdef SINGLE_SKU
+	//pAd->CommonCfg.DefineMaxTxPwr = RTMP_EEPROM_READ16(pAd, EEPROM_DEFINE_MAX_TXPWR);
+	RT28xx_EEPROM_READ16(pAd, EEPROM_DEFINE_MAX_TXPWR, pAd->CommonCfg.DefineMaxTxPwr);
+#endif // SINGLE_SKU //
+#ifdef RT30xx
+	if (IS_RT30xx(pAd))
+	{
+		eFusePhysicalReadRegisters(pAd, EFUSE_TAG, 2, &value);
+		pAd->EFuseTag = (value & 0xff);
+	}
+#endif // RT30xx //
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICReadEEPROMParameters\n"));
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Set default value from EEPROM
+
+	Arguments:
+		Adapter						Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+VOID	NICInitAsicFromEEPROM(
+	IN	PRTMP_ADAPTER	pAd)
+{
+#ifdef CONFIG_STA_SUPPORT
+	UINT32					data = 0;
+	UCHAR	BBPR1 = 0;
+#endif // CONFIG_STA_SUPPORT //
+	USHORT					i;
+	EEPROM_ANTENNA_STRUC	Antenna;
+	EEPROM_NIC_CONFIG2_STRUC    NicConfig2;
+	UCHAR	BBPR3 = 0;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitAsicFromEEPROM\n"));
+	for(i = 3; i < NUM_EEPROM_BBP_PARMS; i++)
+	{
+		UCHAR BbpRegIdx, BbpValue;
+
+		if ((pAd->EEPROMDefaultValue[i] != 0xFFFF) && (pAd->EEPROMDefaultValue[i] != 0))
+		{
+			BbpRegIdx = (UCHAR)(pAd->EEPROMDefaultValue[i] >> 8);
+			BbpValue  = (UCHAR)(pAd->EEPROMDefaultValue[i] & 0xff);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BbpRegIdx, BbpValue);
+		}
+	}
+
+	Antenna.word = pAd->EEPROMDefaultValue[0];
+	if (Antenna.word == 0xFFFF)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("E2PROM error, hard code as 0x%04x\n", Antenna.word));
+		BUG_ON(Antenna.word == 0xFFFF);
+	}
+	pAd->Mlme.RealRxPath = (UCHAR) Antenna.field.RxPath;
+	pAd->RfIcType = (UCHAR) Antenna.field.RfIcType;
+
+	DBGPRINT(RT_DEBUG_WARN, ("pAd->RfIcType = %d, RealRxPath=%d, TxPath = %d\n", pAd->RfIcType, pAd->Mlme.RealRxPath,Antenna.field.TxPath));
+
+	// Save the antenna for future use
+	pAd->Antenna.word = Antenna.word;
+
+	NicConfig2.word = pAd->EEPROMDefaultValue[1];
+
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		if ((NicConfig2.word & 0x00ff) == 0xff)
+		{
+			NicConfig2.word &= 0xff00;
+		}
+
+		if ((NicConfig2.word >> 8) == 0xff)
+		{
+			NicConfig2.word &= 0x00ff;
+		}
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	// Save the antenna for future use
+	pAd->NicConfig2.word = NicConfig2.word;
+
+	// set default antenna as main
+	if (pAd->RfIcType == RFIC_3020)
+		AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
+
+	//
+	// Send LED Setting to MCU.
+	//
+	if (pAd->LedCntl.word == 0xFF)
+	{
+		pAd->LedCntl.word = 0x01;
+		pAd->Led1 = 0x5555;
+		pAd->Led2 = 0x2221;
+
+#ifdef RT2870
+		pAd->Led3 = 0x5627;
+#endif // RT2870 //
+	}
+
+	AsicSendCommandToMcu(pAd, 0x52, 0xff, (UCHAR)pAd->Led1, (UCHAR)(pAd->Led1 >> 8));
+	AsicSendCommandToMcu(pAd, 0x53, 0xff, (UCHAR)pAd->Led2, (UCHAR)(pAd->Led2 >> 8));
+	AsicSendCommandToMcu(pAd, 0x54, 0xff, (UCHAR)pAd->Led3, (UCHAR)(pAd->Led3 >> 8));
+    pAd->LedIndicatorStregth = 0xFF;
+    RTMPSetSignalLED(pAd, -100);	// Force signal strength Led to be turned off, before link up
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		// Read Hardware controlled Radio state enable bit
+		if (NicConfig2.field.HardwareRadioControl == 1)
+		{
+			pAd->StaCfg.bHardwareRadio = TRUE;
+
+			// Read GPIO pin2 as Hardware controlled radio state
+			RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data);
+			if ((data & 0x04) == 0)
+			{
+				pAd->StaCfg.bHwRadio = FALSE;
+				pAd->StaCfg.bRadio = FALSE;
+//				RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818);
+				RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+			}
+		}
+		else
+			pAd->StaCfg.bHardwareRadio = FALSE;
+
+		if (pAd->StaCfg.bRadio == FALSE)
+		{
+			RTMPSetLED(pAd, LED_RADIO_OFF);
+		}
+		else
+		{
+			RTMPSetLED(pAd, LED_RADIO_ON);
+		}
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	// Turn off patching for cardbus controller
+	if (NicConfig2.field.CardbusAcceleration == 1)
+	{
+//		pAd->bTest1 = TRUE;
+	}
+
+	if (NicConfig2.field.DynamicTxAgcControl == 1)
+		pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE;
+	else
+		pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE;
+	//
+	// Since BBP has been progamed, to make sure BBP setting will be
+	// upate inside of AsicAntennaSelect, so reset to UNKNOWN_BAND!!
+	//
+	pAd->CommonCfg.BandState = UNKNOWN_BAND;
+
+	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
+	BBPR3 &= (~0x18);
+	if(pAd->Antenna.field.RxPath == 3)
+	{
+		BBPR3 |= (0x10);
+	}
+	else if(pAd->Antenna.field.RxPath == 2)
+	{
+		BBPR3 |= (0x8);
+	}
+	else if(pAd->Antenna.field.RxPath == 1)
+	{
+		BBPR3 |= (0x0);
+	}
+	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		// Handle the difference when 1T
+		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BBPR1);
+		if(pAd->Antenna.field.TxPath == 1)
+		{
+		BBPR1 &= (~0x18);
+		}
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BBPR1);
+
+		DBGPRINT(RT_DEBUG_TRACE, ("Use Hw Radio Control Pin=%d; if used Pin=%d;\n", pAd->CommonCfg.bHardwareRadio, pAd->CommonCfg.bHardwareRadio));
+	}
+#endif // CONFIG_STA_SUPPORT //
+	DBGPRINT(RT_DEBUG_TRACE, ("TxPath = %d, RxPath = %d, RFIC=%d, Polar+LED mode=%x\n", pAd->Antenna.field.TxPath, pAd->Antenna.field.RxPath, pAd->RfIcType, pAd->LedCntl.word));
+	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitAsicFromEEPROM\n"));
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Initialize NIC hardware
+
+	Arguments:
+		Adapter						Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+NDIS_STATUS	NICInitializeAdapter(
+	IN	PRTMP_ADAPTER	pAd,
+	IN   BOOLEAN    bHardReset)
+{
+	NDIS_STATUS     Status = NDIS_STATUS_SUCCESS;
+	WPDMA_GLO_CFG_STRUC	GloCfg;
+//	INT_MASK_CSR_STRUC		IntMask;
+	ULONG	i =0, j=0;
+	AC_TXOP_CSR0_STRUC	csr0;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAdapter\n"));
+
+	// 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits:
+retry:
+	i = 0;
+	do
+	{
+		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
+		if ((GloCfg.field.TxDMABusy == 0)  && (GloCfg.field.RxDMABusy == 0))
+			break;
+
+		RTMPusecDelay(1000);
+		i++;
+	}while ( i<100);
+	DBGPRINT(RT_DEBUG_TRACE, ("<== DMA offset 0x208 = 0x%x\n", GloCfg.word));
+	GloCfg.word &= 0xff0;
+	GloCfg.field.EnTXWriteBackDDONE =1;
+	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
+
+	// Record HW Beacon offset
+	pAd->BeaconOffset[0] = HW_BEACON_BASE0;
+	pAd->BeaconOffset[1] = HW_BEACON_BASE1;
+	pAd->BeaconOffset[2] = HW_BEACON_BASE2;
+	pAd->BeaconOffset[3] = HW_BEACON_BASE3;
+	pAd->BeaconOffset[4] = HW_BEACON_BASE4;
+	pAd->BeaconOffset[5] = HW_BEACON_BASE5;
+	pAd->BeaconOffset[6] = HW_BEACON_BASE6;
+	pAd->BeaconOffset[7] = HW_BEACON_BASE7;
+
+	//
+	// write all shared Ring's base address into ASIC
+	//
+
+	// asic simulation sequence put this ahead before loading firmware.
+	// pbf hardware reset
+
+	// Initialze ASIC for TX & Rx operation
+	if (NICInitializeAsic(pAd , bHardReset) != NDIS_STATUS_SUCCESS)
+	{
+		if (j++ == 0)
+		{
+			NICLoadFirmware(pAd);
+			goto retry;
+		}
+		return NDIS_STATUS_FAILURE;
+	}
+
+
+
+
+	// WMM parameter
+	csr0.word = 0;
+	RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
+	if (pAd->CommonCfg.PhyMode == PHY_11B)
+	{
+		csr0.field.Ac0Txop = 192;	// AC_VI: 192*32us ~= 6ms
+		csr0.field.Ac1Txop = 96;	// AC_VO: 96*32us  ~= 3ms
+	}
+	else
+	{
+		csr0.field.Ac0Txop = 96;	// AC_VI: 96*32us ~= 3ms
+		csr0.field.Ac1Txop = 48;	// AC_VO: 48*32us ~= 1.5ms
+	}
+	RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr0.word);
+
+
+
+
+	// reset action
+	// Load firmware
+	//  Status = NICLoadFirmware(pAd);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitializeAdapter\n"));
+	return Status;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Initialize ASIC
+
+	Arguments:
+		Adapter						Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+NDIS_STATUS	NICInitializeAsic(
+	IN	PRTMP_ADAPTER	pAd,
+	IN  BOOLEAN		bHardReset)
+{
+	ULONG			Index = 0;
+	UCHAR			R0 = 0xff;
+	UINT32			MacCsr12 = 0, Counter = 0;
+#ifdef RT2870
+	UINT32			MacCsr0 = 0;
+	NTSTATUS		Status;
+	UCHAR			Value = 0xff;
+#endif // RT2870 //
+#ifdef RT30xx
+	UINT32			eFuseCtrl;
+#endif // RT30xx //
+	USHORT			KeyIdx;
+	INT				i,apidx;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAsic\n"));
+
+
+#ifdef RT2870
+	//
+	// Make sure MAC gets ready after NICLoadFirmware().
+	//
+	Index = 0;
+
+	//To avoid hang-on issue when interface up in kernel 2.4,
+	//we use a local variable "MacCsr0" instead of using "pAd->MACVersion" directly.
+	do
+	{
+		RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
+
+		if ((MacCsr0 != 0x00) && (MacCsr0 != 0xFFFFFFFF))
+			break;
+
+		RTMPusecDelay(10);
+	} while (Index++ < 100);
+
+	pAd->MACVersion = MacCsr0;
+	DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0  [ Ver:Rev=0x%08x]\n", pAd->MACVersion));
+	// turn on bit13 (set to zero) after rt2860D. This is to solve high-current issue.
+	RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacCsr12);
+	MacCsr12 &= (~0x2000);
+	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, MacCsr12);
+
+	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3);
+	RTMP_IO_WRITE32(pAd, USB_DMA_CFG, 0x0);
+	Status = RTUSBVenderReset(pAd);
+
+	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
+
+	// Initialize MAC register to default value
+	for(Index=0; Index<NUM_MAC_REG_PARMS; Index++)
+	{
+#ifdef RT3070
+		if ((MACRegTable[Index].Register == TX_SW_CFG0) && (IS_RT3070(pAd) || IS_RT3071(pAd)))
+		{
+			MACRegTable[Index].Value = 0x00000400;
+		}
+#endif // RT3070 //
+		RTMP_IO_WRITE32(pAd, (USHORT)MACRegTable[Index].Register, MACRegTable[Index].Value);
+	}
+
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		for (Index = 0; Index < NUM_STA_MAC_REG_PARMS; Index++)
+		{
+			RTMP_IO_WRITE32(pAd, (USHORT)STAMACRegTable[Index].Register, STAMACRegTable[Index].Value);
+		}
+	}
+#endif // CONFIG_STA_SUPPORT //
+#endif // RT2870 //
+
+#ifdef RT30xx
+	// Initialize RT3070 serial MAc registers which is different from RT2870 serial
+	if (IS_RT3090(pAd))
+	{
+		RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0);
+
+		// RT3071 version E has fixed this issue
+		if ((pAd->MACVersion & 0xffff) < 0x0211)
+		{
+			if (pAd->NicConfig2.field.DACTestBit == 1)
+			{
+				RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x1F);	// To fix throughput drop drastically
+			}
+			else
+			{
+				RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0F);	// To fix throughput drop drastically
+			}
+		}
+		else
+		{
+			RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0);
+		}
+	}
+	else if (IS_RT3070(pAd))
+	{
+		RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0);
+		RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x1F);	// To fix throughput drop drastically
+	}
+#endif // RT30xx //
+
+	//
+	// Before program BBP, we need to wait BBP/RF get wake up.
+	//
+	Index = 0;
+	do
+	{
+		RTMP_IO_READ32(pAd, MAC_STATUS_CFG, &MacCsr12);
+
+		if ((MacCsr12 & 0x03) == 0)	// if BB.RF is stable
+			break;
+
+		DBGPRINT(RT_DEBUG_TRACE, ("Check MAC_STATUS_CFG  = Busy = %x\n", MacCsr12));
+		RTMPusecDelay(1000);
+	} while (Index++ < 100);
+
+    // The commands to firmware should be after these commands, these commands will init firmware
+	// PCI and USB are not the same because PCI driver needs to wait for PCI bus ready
+	RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, 0);	// initialize BBP R/W access agent
+	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, 0);
+	RTMPusecDelay(1000);
+
+	// Read BBP register, make sure BBP is up and running before write new data
+	Index = 0;
+	do
+	{
+		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R0, &R0);
+		DBGPRINT(RT_DEBUG_TRACE, ("BBP version = %x\n", R0));
+	} while ((++Index < 20) && ((R0 == 0xff) || (R0 == 0x00)));
+	//ASSERT(Index < 20); //this will cause BSOD on Check-build driver
+
+	if ((R0 == 0xff) || (R0 == 0x00))
+		return NDIS_STATUS_FAILURE;
+
+	// Initialize BBP register to default value
+	for (Index = 0; Index < NUM_BBP_REG_PARMS; Index++)
+	{
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register, BBPRegTable[Index].Value);
+	}
+
+	// for rt2860E and after, init BBP_R84 with 0x19. This is for extension channel overlapping IOT.
+	// RT3090 should not program BBP R84 to 0x19, otherwise TX will block.
+	if (((pAd->MACVersion&0xffff) != 0x0101) && (!IS_RT30xx(pAd)))
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19);
+
+// add by johnli, RF power sequence setup
+#ifdef RT30xx
+	if (IS_RT30xx(pAd))
+	{	//update for RT3070/71/72/90/91/92.
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R79, 0x13);
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R80, 0x05);
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R81, 0x33);
+	}
+
+	if (IS_RT3090(pAd))
+	{
+		UCHAR		bbpreg=0;
+
+		// enable DC filter
+		if ((pAd->MACVersion & 0xffff) >= 0x0211)
+		{
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xc0);
+		}
+
+		// improve power consumption
+		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R138, &bbpreg);
+		if (pAd->Antenna.field.TxPath == 1)
+		{
+			// turn off tx DAC_1
+			bbpreg = (bbpreg | 0x20);
+		}
+
+		if (pAd->Antenna.field.RxPath == 1)
+		{
+			// turn off tx ADC_1
+			bbpreg &= (~0x2);
+		}
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R138, bbpreg);
+
+		// improve power consumption in RT3071 Ver.E
+		if ((pAd->MACVersion & 0xffff) >= 0x0211)
+		{
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R31, &bbpreg);
+			bbpreg &= (~0x3);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg);
+		}
+	}
+#endif // RT30xx //
+// end johnli
+
+	if (pAd->MACVersion == 0x28600100)
+	{
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x12);
+    }
+
+	if (pAd->MACVersion >= RALINK_2880E_VERSION && pAd->MACVersion < RALINK_3070_VERSION) // 3*3
+	{
+		// enlarge MAX_LEN_CFG
+		UINT32 csr;
+		RTMP_IO_READ32(pAd, MAX_LEN_CFG, &csr);
+		csr &= 0xFFF;
+		csr |= 0x2000;
+		RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, csr);
+	}
+
+#ifdef RT2870
+{
+	UCHAR	MAC_Value[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0,0};
+
+	//Initialize WCID table
+	Value = 0xff;
+	for(Index =0 ;Index < 254;Index++)
+	{
+		RTUSBMultiWrite(pAd, (USHORT)(MAC_WCID_BASE + Index * 8), MAC_Value, 8);
+	}
+}
+#endif // RT2870 //
+
+	// Add radio off control
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		if (pAd->StaCfg.bRadio == FALSE)
+		{
+//			RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818);
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+			DBGPRINT(RT_DEBUG_TRACE, ("Set Radio Off\n"));
+		}
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	// Clear raw counters
+	RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter);
+	RTMP_IO_READ32(pAd, RX_STA_CNT1, &Counter);
+	RTMP_IO_READ32(pAd, RX_STA_CNT2, &Counter);
+	RTMP_IO_READ32(pAd, TX_STA_CNT0, &Counter);
+	RTMP_IO_READ32(pAd, TX_STA_CNT1, &Counter);
+	RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter);
+
+	// ASIC will keep garbage value after boot
+	// Clear all seared key table when initial
+	// This routine can be ignored in radio-ON/OFF operation.
+	if (bHardReset)
+	{
+		for (KeyIdx = 0; KeyIdx < 4; KeyIdx++)
+		{
+			RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4*KeyIdx, 0);
+		}
+
+	// Clear all pairwise key table when initial
+	for (KeyIdx = 0; KeyIdx < 256; KeyIdx++)
+	{
+		RTMP_IO_WRITE32(pAd, MAC_WCID_ATTRIBUTE_BASE + (KeyIdx * HW_WCID_ATTRI_SIZE), 1);
+	}
+	}
+
+	// assert HOST ready bit
+//  RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x0); // 2004-09-14 asked by Mark
+//  RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x4);
+
+	// It isn't necessary to clear this space when not hard reset.
+	if (bHardReset == TRUE)
+	{
+		// clear all on-chip BEACON frame space
+		for (apidx = 0; apidx < HW_BEACON_MAX_COUNT; apidx++)
+		{
+			for (i = 0; i < HW_BEACON_OFFSET>>2; i+=4)
+				RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[apidx] + i, 0x00);
+		}
+	}
+#ifdef RT2870
+	AsicDisableSync(pAd);
+	// Clear raw counters
+	RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter);
+	RTMP_IO_READ32(pAd, RX_STA_CNT1, &Counter);
+	RTMP_IO_READ32(pAd, RX_STA_CNT2, &Counter);
+	RTMP_IO_READ32(pAd, TX_STA_CNT0, &Counter);
+	RTMP_IO_READ32(pAd, TX_STA_CNT1, &Counter);
+	RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter);
+	// Default PCI clock cycle per ms is different as default setting, which is based on PCI.
+	RTMP_IO_READ32(pAd, USB_CYC_CFG, &Counter);
+	Counter&=0xffffff00;
+	Counter|=0x000001e;
+	RTMP_IO_WRITE32(pAd, USB_CYC_CFG, Counter);
+#endif // RT2870 //
+#ifdef RT30xx
+	pAd->bUseEfuse=FALSE;
+	RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrl);
+	pAd->bUseEfuse = ( (eFuseCtrl & 0x80000000) == 0x80000000) ? 1 : 0;
+	if(pAd->bUseEfuse)
+	{
+			DBGPRINT(RT_DEBUG_TRACE, ("NVM is Efuse\n"));
+	}
+	else
+	{
+			DBGPRINT(RT_DEBUG_TRACE, ("NVM is EEPROM\n"));
+
+	}
+#endif // RT30xx //
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		// for rt2860E and after, init TXOP_CTRL_CFG with 0x583f. This is for extension channel overlapping IOT.
+		if ((pAd->MACVersion&0xffff) != 0x0101)
+			RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x583f);
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitializeAsic\n"));
+	return NDIS_STATUS_SUCCESS;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Reset NIC Asics
+
+	Arguments:
+		Adapter						Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+
+	Note:
+		Reset NIC to initial state AS IS system boot up time.
+
+	========================================================================
+*/
+VOID	NICIssueReset(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	UINT32	Value = 0;
+	DBGPRINT(RT_DEBUG_TRACE, ("--> NICIssueReset\n"));
+
+	// Abort Tx, prevent ASIC from writing to Host memory
+	//RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x001f0000);
+
+	// Disable Rx, register value supposed will remain after reset
+	RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+	Value &= (0xfffffff3);
+	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+	// Issue reset and clear from reset state
+	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x03); // 2004-09-17 change from 0x01
+	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x00);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICIssueReset\n"));
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Check ASIC registers and find any reason the system might hang
+
+	Arguments:
+		Adapter						Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	========================================================================
+*/
+BOOLEAN	NICCheckForHang(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	return (FALSE);
+}
+
+VOID NICUpdateFifoStaCounters(
+	IN PRTMP_ADAPTER pAd)
+{
+	TX_STA_FIFO_STRUC	StaFifo;
+	MAC_TABLE_ENTRY		*pEntry;
+	UCHAR				i = 0;
+	UCHAR			pid = 0, wcid = 0;
+	CHAR				reTry;
+	UCHAR				succMCS;
+
+#ifdef RALINK_ATE
+	/* Nothing to do in ATE mode */
+	if (ATE_ON(pAd))
+		return;
+#endif // RALINK_ATE //
+
+		do
+		{
+			RTMP_IO_READ32(pAd, TX_STA_FIFO, &StaFifo.word);
+
+			if (StaFifo.field.bValid == 0)
+				break;
+
+			wcid = (UCHAR)StaFifo.field.wcid;
+
+
+		/* ignore NoACK and MGMT frame use 0xFF as WCID */
+			if ((StaFifo.field.TxAckRequired == 0) || (wcid >= MAX_LEN_OF_MAC_TABLE))
+			{
+				i++;
+				continue;
+			}
+
+			/* PID store Tx MCS Rate */
+			pid = (UCHAR)StaFifo.field.PidType;
+
+			pEntry = &pAd->MacTab.Content[wcid];
+
+			pEntry->DebugFIFOCount++;
+
+#ifdef DOT11_N_SUPPORT
+			if (StaFifo.field.TxBF) // 3*3
+				pEntry->TxBFCount++;
+#endif // DOT11_N_SUPPORT //
+
+#ifdef UAPSD_AP_SUPPORT
+			UAPSD_SP_AUE_Handle(pAd, pEntry, StaFifo.field.TxSuccess);
+#endif // UAPSD_AP_SUPPORT //
+
+			if (!StaFifo.field.TxSuccess)
+			{
+				pEntry->FIFOCount++;
+				pEntry->OneSecTxFailCount++;
+
+				if (pEntry->FIFOCount >= 1)
+				{
+					DBGPRINT(RT_DEBUG_TRACE, ("#"));
+#ifdef DOT11_N_SUPPORT
+					pEntry->NoBADataCountDown = 64;
+#endif // DOT11_N_SUPPORT //
+
+					if(pEntry->PsMode == PWR_ACTIVE)
+					{
+#ifdef DOT11_N_SUPPORT
+						int tid;
+						for (tid=0; tid<NUM_OF_TID; tid++)
+						{
+							BAOriSessionTearDown(pAd, pEntry->Aid,  tid, FALSE, FALSE);
+						}
+#endif // DOT11_N_SUPPORT //
+
+						// Update the continuous transmission counter except PS mode
+						pEntry->ContinueTxFailCnt++;
+					}
+					else
+					{
+						// Clear the FIFOCount when sta in Power Save mode. Basically we assume
+						//     this tx error happened due to sta just go to sleep.
+						pEntry->FIFOCount = 0;
+						pEntry->ContinueTxFailCnt = 0;
+					}
+					//pEntry->FIFOCount = 0;
+				}
+				//pEntry->bSendBAR = TRUE;
+			}
+			else
+			{
+#ifdef DOT11_N_SUPPORT
+				if ((pEntry->PsMode != PWR_SAVE) && (pEntry->NoBADataCountDown > 0))
+				{
+					pEntry->NoBADataCountDown--;
+					if (pEntry->NoBADataCountDown==0)
+					{
+						DBGPRINT(RT_DEBUG_TRACE, ("@\n"));
+					}
+				}
+#endif // DOT11_N_SUPPORT //
+				pEntry->FIFOCount = 0;
+				pEntry->OneSecTxNoRetryOkCount++;
+				// update NoDataIdleCount when sucessful send packet to STA.
+				pEntry->NoDataIdleCount = 0;
+				pEntry->ContinueTxFailCnt = 0;
+			}
+
+			succMCS = StaFifo.field.SuccessRate & 0x7F;
+
+			reTry = pid - succMCS;
+
+			if (StaFifo.field.TxSuccess)
+			{
+				pEntry->TXMCSExpected[pid]++;
+				if (pid == succMCS)
+				{
+					pEntry->TXMCSSuccessful[pid]++;
+				}
+				else
+				{
+					pEntry->TXMCSAutoFallBack[pid][succMCS]++;
+				}
+			}
+			else
+			{
+				pEntry->TXMCSFailed[pid]++;
+			}
+
+			if (reTry > 0)
+			{
+				if ((pid >= 12) && succMCS <=7)
+				{
+					reTry -= 4;
+				}
+				pEntry->OneSecTxRetryOkCount += reTry;
+			}
+
+			i++;
+			// ASIC store 16 stack
+		} while ( i < (2*TX_RING_SIZE) );
+
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Read statistical counters from hardware registers and record them
+		in software variables for later on query
+
+	Arguments:
+		pAd					Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	========================================================================
+*/
+VOID NICUpdateRawCounters(
+	IN PRTMP_ADAPTER pAd)
+{
+	UINT32	OldValue;//, Value2;
+	//ULONG	PageSum, OneSecTransmitCount;
+	//ULONG	TxErrorRatio, Retry, Fail;
+	RX_STA_CNT0_STRUC	 RxStaCnt0;
+	RX_STA_CNT1_STRUC   RxStaCnt1;
+	RX_STA_CNT2_STRUC   RxStaCnt2;
+	TX_STA_CNT0_STRUC 	 TxStaCnt0;
+	TX_STA_CNT1_STRUC	 StaTx1;
+	TX_STA_CNT2_STRUC	 StaTx2;
+	TX_AGG_CNT_STRUC	TxAggCnt;
+	TX_AGG_CNT0_STRUC	TxAggCnt0;
+	TX_AGG_CNT1_STRUC	TxAggCnt1;
+	TX_AGG_CNT2_STRUC	TxAggCnt2;
+	TX_AGG_CNT3_STRUC	TxAggCnt3;
+	TX_AGG_CNT4_STRUC	TxAggCnt4;
+	TX_AGG_CNT5_STRUC	TxAggCnt5;
+	TX_AGG_CNT6_STRUC	TxAggCnt6;
+	TX_AGG_CNT7_STRUC	TxAggCnt7;
+
+	RTMP_IO_READ32(pAd, RX_STA_CNT0, &RxStaCnt0.word);
+	RTMP_IO_READ32(pAd, RX_STA_CNT2, &RxStaCnt2.word);
+
+	{
+		RTMP_IO_READ32(pAd, RX_STA_CNT1, &RxStaCnt1.word);
+	    // Update RX PLCP error counter
+	    pAd->PrivateInfo.PhyRxErrCnt += RxStaCnt1.field.PlcpErr;
+		// Update False CCA counter
+		pAd->RalinkCounters.OneSecFalseCCACnt += RxStaCnt1.field.FalseCca;
+	}
+
+	// Update FCS counters
+	OldValue= pAd->WlanCounters.FCSErrorCount.u.LowPart;
+	pAd->WlanCounters.FCSErrorCount.u.LowPart += (RxStaCnt0.field.CrcErr); // >> 7);
+	if (pAd->WlanCounters.FCSErrorCount.u.LowPart < OldValue)
+		pAd->WlanCounters.FCSErrorCount.u.HighPart++;
+
+	// Add FCS error count to private counters
+	pAd->RalinkCounters.OneSecRxFcsErrCnt += RxStaCnt0.field.CrcErr;
+	OldValue = pAd->RalinkCounters.RealFcsErrCount.u.LowPart;
+	pAd->RalinkCounters.RealFcsErrCount.u.LowPart += RxStaCnt0.field.CrcErr;
+	if (pAd->RalinkCounters.RealFcsErrCount.u.LowPart < OldValue)
+		pAd->RalinkCounters.RealFcsErrCount.u.HighPart++;
+
+	// Update Duplicate Rcv check
+	pAd->RalinkCounters.DuplicateRcv += RxStaCnt2.field.RxDupliCount;
+	pAd->WlanCounters.FrameDuplicateCount.u.LowPart += RxStaCnt2.field.RxDupliCount;
+	// Update RX Overflow counter
+	pAd->Counters8023.RxNoBuffer += (RxStaCnt2.field.RxFifoOverflowCount);
+
+	//pAd->RalinkCounters.RxCount = 0;
+#ifdef RT2870
+	if (pAd->RalinkCounters.RxCount != pAd->watchDogRxCnt)
+	{
+		pAd->watchDogRxCnt = pAd->RalinkCounters.RxCount;
+		pAd->watchDogRxOverFlowCnt = 0;
+	}
+	else
+	{
+		if (RxStaCnt2.field.RxFifoOverflowCount)
+			pAd->watchDogRxOverFlowCnt++;
+		else
+			pAd->watchDogRxOverFlowCnt = 0;
+	}
+#endif // RT2870 //
+
+
+	//if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) ||
+	//	(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) && (pAd->MacTab.Size != 1)))
+	if (!pAd->bUpdateBcnCntDone)
+	{
+	// Update BEACON sent count
+	RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
+	RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
+	RTMP_IO_READ32(pAd, TX_STA_CNT2, &StaTx2.word);
+	pAd->RalinkCounters.OneSecBeaconSentCnt += TxStaCnt0.field.TxBeaconCount;
+	pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
+	pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
+	pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
+	pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
+	pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
+	pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
+	}
+
+	//if (pAd->bStaFifoTest == TRUE)
+	{
+		RTMP_IO_READ32(pAd, TX_AGG_CNT, &TxAggCnt.word);
+		RTMP_IO_READ32(pAd, TX_AGG_CNT0, &TxAggCnt0.word);
+		RTMP_IO_READ32(pAd, TX_AGG_CNT1, &TxAggCnt1.word);
+		RTMP_IO_READ32(pAd, TX_AGG_CNT2, &TxAggCnt2.word);
+		RTMP_IO_READ32(pAd, TX_AGG_CNT3, &TxAggCnt3.word);
+		RTMP_IO_READ32(pAd, TX_AGG_CNT4, &TxAggCnt4.word);
+		RTMP_IO_READ32(pAd, TX_AGG_CNT5, &TxAggCnt5.word);
+		RTMP_IO_READ32(pAd, TX_AGG_CNT6, &TxAggCnt6.word);
+		RTMP_IO_READ32(pAd, TX_AGG_CNT7, &TxAggCnt7.word);
+		pAd->RalinkCounters.TxAggCount += TxAggCnt.field.AggTxCount;
+		pAd->RalinkCounters.TxNonAggCount += TxAggCnt.field.NonAggTxCount;
+		pAd->RalinkCounters.TxAgg1MPDUCount += TxAggCnt0.field.AggSize1Count;
+		pAd->RalinkCounters.TxAgg2MPDUCount += TxAggCnt0.field.AggSize2Count;
+
+		pAd->RalinkCounters.TxAgg3MPDUCount += TxAggCnt1.field.AggSize3Count;
+		pAd->RalinkCounters.TxAgg4MPDUCount += TxAggCnt1.field.AggSize4Count;
+		pAd->RalinkCounters.TxAgg5MPDUCount += TxAggCnt2.field.AggSize5Count;
+		pAd->RalinkCounters.TxAgg6MPDUCount += TxAggCnt2.field.AggSize6Count;
+
+		pAd->RalinkCounters.TxAgg7MPDUCount += TxAggCnt3.field.AggSize7Count;
+		pAd->RalinkCounters.TxAgg8MPDUCount += TxAggCnt3.field.AggSize8Count;
+		pAd->RalinkCounters.TxAgg9MPDUCount += TxAggCnt4.field.AggSize9Count;
+		pAd->RalinkCounters.TxAgg10MPDUCount += TxAggCnt4.field.AggSize10Count;
+
+		pAd->RalinkCounters.TxAgg11MPDUCount += TxAggCnt5.field.AggSize11Count;
+		pAd->RalinkCounters.TxAgg12MPDUCount += TxAggCnt5.field.AggSize12Count;
+		pAd->RalinkCounters.TxAgg13MPDUCount += TxAggCnt6.field.AggSize13Count;
+		pAd->RalinkCounters.TxAgg14MPDUCount += TxAggCnt6.field.AggSize14Count;
+
+		pAd->RalinkCounters.TxAgg15MPDUCount += TxAggCnt7.field.AggSize15Count;
+		pAd->RalinkCounters.TxAgg16MPDUCount += TxAggCnt7.field.AggSize16Count;
+
+		// Calculate the transmitted A-MPDU count
+		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += TxAggCnt0.field.AggSize1Count;
+		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt0.field.AggSize2Count / 2);
+
+		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize3Count / 3);
+		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize4Count / 4);
+
+		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize5Count / 5);
+		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize6Count / 6);
+
+		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize7Count / 7);
+		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize8Count / 8);
+
+		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize9Count / 9);
+		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize10Count / 10);
+
+		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize11Count / 11);
+		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize12Count / 12);
+
+		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize13Count / 13);
+		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize14Count / 14);
+
+		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize15Count / 15);
+		pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize16Count / 16);
+	}
+
+#ifdef DBG_DIAGNOSE
+	{
+		RtmpDiagStruct	*pDiag;
+		COUNTER_RALINK	*pRalinkCounters;
+		UCHAR			ArrayCurIdx, i;
+
+		pDiag = &pAd->DiagStruct;
+		pRalinkCounters = &pAd->RalinkCounters;
+		ArrayCurIdx = pDiag->ArrayCurIdx;
+
+		if (pDiag->inited == 0)
+		{
+			NdisZeroMemory(pDiag, sizeof(struct _RtmpDiagStrcut_));
+			pDiag->ArrayStartIdx = pDiag->ArrayCurIdx = 0;
+			pDiag->inited = 1;
+		}
+		else
+		{
+			// Tx
+			pDiag->TxFailCnt[ArrayCurIdx] = TxStaCnt0.field.TxFailCount;
+			pDiag->TxAggCnt[ArrayCurIdx] = TxAggCnt.field.AggTxCount;
+			pDiag->TxNonAggCnt[ArrayCurIdx] = TxAggCnt.field.NonAggTxCount;
+			pDiag->TxAMPDUCnt[ArrayCurIdx][0] = TxAggCnt0.field.AggSize1Count;
+			pDiag->TxAMPDUCnt[ArrayCurIdx][1] = TxAggCnt0.field.AggSize2Count;
+			pDiag->TxAMPDUCnt[ArrayCurIdx][2] = TxAggCnt1.field.AggSize3Count;
+			pDiag->TxAMPDUCnt[ArrayCurIdx][3] = TxAggCnt1.field.AggSize4Count;
+			pDiag->TxAMPDUCnt[ArrayCurIdx][4] = TxAggCnt2.field.AggSize5Count;
+			pDiag->TxAMPDUCnt[ArrayCurIdx][5] = TxAggCnt2.field.AggSize6Count;
+			pDiag->TxAMPDUCnt[ArrayCurIdx][6] = TxAggCnt3.field.AggSize7Count;
+			pDiag->TxAMPDUCnt[ArrayCurIdx][7] = TxAggCnt3.field.AggSize8Count;
+			pDiag->TxAMPDUCnt[ArrayCurIdx][8] = TxAggCnt4.field.AggSize9Count;
+			pDiag->TxAMPDUCnt[ArrayCurIdx][9] = TxAggCnt4.field.AggSize10Count;
+			pDiag->TxAMPDUCnt[ArrayCurIdx][10] = TxAggCnt5.field.AggSize11Count;
+			pDiag->TxAMPDUCnt[ArrayCurIdx][11] = TxAggCnt5.field.AggSize12Count;
+			pDiag->TxAMPDUCnt[ArrayCurIdx][12] = TxAggCnt6.field.AggSize13Count;
+			pDiag->TxAMPDUCnt[ArrayCurIdx][13] = TxAggCnt6.field.AggSize14Count;
+			pDiag->TxAMPDUCnt[ArrayCurIdx][14] = TxAggCnt7.field.AggSize15Count;
+			pDiag->TxAMPDUCnt[ArrayCurIdx][15] = TxAggCnt7.field.AggSize16Count;
+
+			pDiag->RxCrcErrCnt[ArrayCurIdx] = RxStaCnt0.field.CrcErr;
+
+			INC_RING_INDEX(pDiag->ArrayCurIdx,  DIAGNOSE_TIME);
+			ArrayCurIdx = pDiag->ArrayCurIdx;
+			for (i =0; i < 9; i++)
+			{
+				pDiag->TxDescCnt[ArrayCurIdx][i]= 0;
+				pDiag->TxSWQueCnt[ArrayCurIdx][i] =0;
+				pDiag->TxMcsCnt[ArrayCurIdx][i] = 0;
+				pDiag->RxMcsCnt[ArrayCurIdx][i] = 0;
+			}
+			pDiag->TxDataCnt[ArrayCurIdx] = 0;
+			pDiag->TxFailCnt[ArrayCurIdx] = 0;
+			pDiag->RxDataCnt[ArrayCurIdx] = 0;
+			pDiag->RxCrcErrCnt[ArrayCurIdx]  = 0;
+//			for (i = 9; i < 16; i++)
+			for (i = 9; i < 24; i++) // 3*3
+			{
+				pDiag->TxDescCnt[ArrayCurIdx][i] = 0;
+				pDiag->TxMcsCnt[ArrayCurIdx][i] = 0;
+				pDiag->RxMcsCnt[ArrayCurIdx][i] = 0;
+}
+
+			if (pDiag->ArrayCurIdx == pDiag->ArrayStartIdx)
+				INC_RING_INDEX(pDiag->ArrayStartIdx,  DIAGNOSE_TIME);
+		}
+
+	}
+#endif // DBG_DIAGNOSE //
+
+
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Reset NIC from error
+
+	Arguments:
+		Adapter						Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+
+	Note:
+		Reset NIC from error state
+
+	========================================================================
+*/
+VOID	NICResetFromError(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	// Reset BBP (according to alex, reset ASIC will force reset BBP
+	// Therefore, skip the reset BBP
+	// RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x2);
+
+	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
+	// Remove ASIC from reset state
+	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
+
+	NICInitializeAdapter(pAd, FALSE);
+	NICInitAsicFromEEPROM(pAd);
+
+	// Switch to current channel, since during reset process, the connection should remains on.
+	AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+	AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		erase 8051 firmware image in MAC ASIC
+
+	Arguments:
+		Adapter						Pointer to our adapter
+
+	IRQL = PASSIVE_LEVEL
+
+	========================================================================
+*/
+VOID NICEraseFirmware(
+	IN PRTMP_ADAPTER pAd)
+{
+	ULONG i;
+
+	for(i=0; i<MAX_FIRMWARE_IMAGE_SIZE; i+=4)
+		RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, 0);
+
+}/* End of NICEraseFirmware */
+
+/*
+	========================================================================
+
+	Routine Description:
+		Load 8051 firmware RT2561.BIN file into MAC ASIC
+
+	Arguments:
+		Adapter						Pointer to our adapter
+
+	Return Value:
+		NDIS_STATUS_SUCCESS         firmware image load ok
+		NDIS_STATUS_FAILURE         image not found
+
+	IRQL = PASSIVE_LEVEL
+
+	========================================================================
+*/
+NDIS_STATUS NICLoadFirmware(
+	IN PRTMP_ADAPTER pAd)
+{
+#ifdef BIN_IN_FILE
+#define NICLF_DEFAULT_USE()	\
+	flg_default_firm_use = TRUE; \
+	printk("%s - Use default firmware!\n", __FUNCTION__);
+
+	NDIS_STATUS		Status = NDIS_STATUS_SUCCESS;
+	PUCHAR			src;
+	struct file		*srcf;
+	INT 			retval, orgfsuid, orgfsgid, i;
+   	mm_segment_t	orgfs;
+	PUCHAR			pFirmwareImage;
+	UINT			FileLength = 0;
+	UINT32			MacReg;
+	ULONG			Index;
+	ULONG			firm;
+	BOOLEAN			flg_default_firm_use = FALSE;
+
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> %s\n", __FUNCTION__));
+
+	/* init */
+	pFirmwareImage = NULL;
+	src = RTMP_FIRMWARE_FILE_NAME;
+
+	/* save uid and gid used for filesystem access.
+	   set user and group to 0 (root) */
+	orgfsuid = current->fsuid;
+	orgfsgid = current->fsgid;
+	current->fsuid = current->fsgid = 0;
+    orgfs = get_fs();
+    set_fs(KERNEL_DS);
+
+	pAd->FirmwareVersion = (FIRMWARE_MAJOR_VERSION << 8) + \
+						   FIRMWARE_MINOR_VERSION;
+
+
+	/* allocate firmware buffer */
+    pFirmwareImage = kmalloc(MAX_FIRMWARE_IMAGE_SIZE, MEM_ALLOC_FLAG);
+    if (pFirmwareImage == NULL)
+	{
+		/* allocate fail, use default firmware array in firmware.h */
+		printk("%s - Allocate memory fail!\n", __FUNCTION__);
+		NICLF_DEFAULT_USE();
+    }
+	else
+	{
+		/* allocate ok! zero the firmware buffer */
+		memset(pFirmwareImage, 0x00, MAX_FIRMWARE_IMAGE_SIZE);
+	} /* End of if */
+
+
+	/* if ok, read firmware file from *.bin file */
+	if (flg_default_firm_use == FALSE)
+	{
+		do
+		{
+			/* open the bin file */
+			srcf = filp_open(src, O_RDONLY, 0);
+
+			if (IS_ERR(srcf))
+			{
+				printk("%s - Error %ld opening %s\n",
+					   __FUNCTION__, -PTR_ERR(srcf), src);
+				NICLF_DEFAULT_USE();
+				break;
+			} /* End of if */
+
+			/* the object must have a read method */
+			if ((srcf->f_op == NULL) || (srcf->f_op->read == NULL))
+			{
+				printk("%s - %s does not have a write method\n", __FUNCTION__, src);
+				NICLF_DEFAULT_USE();
+				break;
+			} /* End of if */
+
+			/* read the firmware from the file *.bin */
+			FileLength = srcf->f_op->read(srcf,
+										  pFirmwareImage,
+										  MAX_FIRMWARE_IMAGE_SIZE,
+										  &srcf->f_pos);
+
+			if (FileLength != MAX_FIRMWARE_IMAGE_SIZE)
+			{
+				printk("%s: error file length (=%d) in RT2860AP.BIN\n",
+					   __FUNCTION__, FileLength);
+				NICLF_DEFAULT_USE();
+				break;
+			}
+			else
+			{
+				PUCHAR ptr = pFirmwareImage;
+				USHORT crc = 0xffff;
+
+
+				/* calculate firmware CRC */
+				for(i=0; i<(MAX_FIRMWARE_IMAGE_SIZE-2); i++, ptr++)
+					crc = ByteCRC16(BitReverse(*ptr), crc);
+				/* End of for */
+
+				if ((pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-2] != \
+								(UCHAR)BitReverse((UCHAR)(crc>>8))) ||
+					(pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-1] != \
+								(UCHAR)BitReverse((UCHAR)crc)))
+				{
+					/* CRC fail */
+					printk("%s: CRC = 0x%02x 0x%02x "
+						   "error, should be 0x%02x 0x%02x\n",
+						   __FUNCTION__,
+						   pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-2],
+						   pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-1],
+						   (UCHAR)(crc>>8), (UCHAR)(crc));
+					NICLF_DEFAULT_USE();
+					break;
+				}
+				else
+				{
+					/* firmware is ok */
+					pAd->FirmwareVersion = \
+						(pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-4] << 8) +
+						pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-3];
+
+					/* check if firmware version of the file is too old */
+					if ((pAd->FirmwareVersion) < \
+											((FIRMWARE_MAJOR_VERSION << 8) +
+									  	 	 FIRMWARE_MINOR_VERSION))
+					{
+						printk("%s: firmware version too old!\n", __FUNCTION__);
+						NICLF_DEFAULT_USE();
+						break;
+					} /* End of if */
+				} /* End of if */
+
+				DBGPRINT(RT_DEBUG_TRACE,
+						 ("NICLoadFirmware: CRC ok, ver=%d.%d\n",
+						  pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-4],
+						  pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-3]));
+			} /* End of if (FileLength == MAX_FIRMWARE_IMAGE_SIZE) */
+			break;
+		} while(TRUE);
+
+		/* close firmware file */
+		if (IS_ERR(srcf))
+			;
+		else
+		{
+			retval = filp_close(srcf, NULL);
+			if (retval)
+			{
+				DBGPRINT(RT_DEBUG_ERROR,
+						 ("--> Error %d closing %s\n", -retval, src));
+			} /* End of if */
+		} /* End of if */
+	} /* End of if */
+
+
+	/* write firmware to ASIC */
+	if (flg_default_firm_use == TRUE)
+	{
+		/* use default fimeware, free allocated buffer */
+		if (pFirmwareImage != NULL)
+			kfree(pFirmwareImage);
+		/* End of if */
+
+		/* use default *.bin array */
+		pFirmwareImage = FirmwareImage;
+		FileLength = sizeof(FirmwareImage);
+	} /* End of if */
+
+	/* enable Host program ram write selection */
+	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x10000);
+
+	for(i=0; i<FileLength; i+=4)
+	{
+		firm = pFirmwareImage[i] +
+			   (pFirmwareImage[i+3] << 24) +
+			   (pFirmwareImage[i+2] << 16) +
+			   (pFirmwareImage[i+1] << 8);
+
+		RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, firm);
+	} /* End of for */
+
+	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x00000);
+	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x00001);
+
+	/* initialize BBP R/W access agent */
+	RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, 0);
+	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, 0);
+
+	if (flg_default_firm_use == FALSE)
+	{
+		/* use file firmware, free allocated buffer */
+		if (pFirmwareImage != NULL)
+			kfree(pFirmwareImage);
+		/* End of if */
+	} /* End of if */
+
+	set_fs(orgfs);
+	current->fsuid = orgfsuid;
+	current->fsgid = orgfsgid;
+#else
+
+	NDIS_STATUS		Status = NDIS_STATUS_SUCCESS;
+	PUCHAR			pFirmwareImage;
+	ULONG			FileLength, Index;
+	//ULONG			firm;
+	UINT32			MacReg = 0;
+	UINT32			Version = (pAd->MACVersion >> 16);
+
+	pFirmwareImage = FirmwareImage;
+	FileLength = sizeof(FirmwareImage);
+
+	// New 8k byte firmware size for RT3071/RT3072
+	//printk("Usb Chip\n");
+	if (FIRMWAREIMAGE_LENGTH == FIRMWAREIMAGE_MAX_LENGTH)
+	//The firmware image consists of two parts. One is the origianl and the other is the new.
+	//Use Second Part
+	{
+#ifdef RT2870
+		if ((Version != 0x2860) && (Version != 0x2872) && (Version != 0x3070))
+		{	// Use Firmware V2.
+			//printk("KH:Use New Version,part2\n");
+			pFirmwareImage = (PUCHAR)&FirmwareImage[FIRMWAREIMAGEV1_LENGTH];
+			FileLength = FIRMWAREIMAGEV2_LENGTH;
+		}
+		else
+		{
+			//printk("KH:Use New Version,part1\n");
+			pFirmwareImage = FirmwareImage;
+			FileLength = FIRMWAREIMAGEV1_LENGTH;
+		}
+#endif // RT2870 //
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("KH: bin file should be 8KB.\n"));
+		Status = NDIS_STATUS_FAILURE;
+	}
+
+	RT28XX_WRITE_FIRMWARE(pAd, pFirmwareImage, FileLength);
+
+#endif
+
+	/* check if MCU is ready */
+	Index = 0;
+	do
+	{
+		RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacReg);
+
+		if (MacReg & 0x80)
+			break;
+
+		RTMPusecDelay(1000);
+	} while (Index++ < 1000);
+
+    if (Index >= 1000)
+	{
+		Status = NDIS_STATUS_FAILURE;
+		DBGPRINT(RT_DEBUG_ERROR, ("NICLoadFirmware: MCU is not ready\n\n\n"));
+	} /* End of if */
+
+    DBGPRINT(RT_DEBUG_TRACE,
+			 ("<=== %s (status=%d)\n", __FUNCTION__, Status));
+    return Status;
+} /* End of NICLoadFirmware */
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Load Tx rate switching parameters
+
+	Arguments:
+		Adapter						Pointer to our adapter
+
+	Return Value:
+		NDIS_STATUS_SUCCESS         firmware image load ok
+		NDIS_STATUS_FAILURE         image not found
+
+	IRQL = PASSIVE_LEVEL
+
+	Rate Table Format:
+		1. (B0: Valid Item number) (B1:Initial item from zero)
+		2. Item Number(Dec)      Mode(Hex)     Current MCS(Dec)    TrainUp(Dec)    TrainDown(Dec)
+
+	========================================================================
+*/
+NDIS_STATUS NICLoadRateSwitchingParams(
+	IN PRTMP_ADAPTER pAd)
+{
+	return NDIS_STATUS_SUCCESS;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		if  pSrc1 all zero with length Length, return 0.
+		If not all zero, return 1
+
+	Arguments:
+		pSrc1
+
+	Return Value:
+		1:			not all zero
+		0:			all zero
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+ULONG	RTMPNotAllZero(
+	IN	PVOID	pSrc1,
+	IN	ULONG	Length)
+{
+	PUCHAR	pMem1;
+	ULONG	Index = 0;
+
+	pMem1 = (PUCHAR) pSrc1;
+
+	for (Index = 0; Index < Length; Index++)
+	{
+		if (pMem1[Index] != 0x0)
+		{
+			break;
+		}
+	}
+
+	if (Index == Length)
+	{
+		return (0);
+	}
+	else
+	{
+		return (1);
+	}
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Compare two memory block
+
+	Arguments:
+		pSrc1		Pointer to first memory address
+		pSrc2		Pointer to second memory address
+
+	Return Value:
+		0:			memory is equal
+		1:			pSrc1 memory is larger
+		2:			pSrc2 memory is larger
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+ULONG	RTMPCompareMemory(
+	IN	PVOID	pSrc1,
+	IN	PVOID	pSrc2,
+	IN	ULONG	Length)
+{
+	PUCHAR	pMem1;
+	PUCHAR	pMem2;
+	ULONG	Index = 0;
+
+	pMem1 = (PUCHAR) pSrc1;
+	pMem2 = (PUCHAR) pSrc2;
+
+	for (Index = 0; Index < Length; Index++)
+	{
+		if (pMem1[Index] > pMem2[Index])
+			return (1);
+		else if (pMem1[Index] < pMem2[Index])
+			return (2);
+	}
+
+	// Equal
+	return (0);
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Zero out memory block
+
+	Arguments:
+		pSrc1		Pointer to memory address
+		Length		Size
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTMPZeroMemory(
+	IN	PVOID	pSrc,
+	IN	ULONG	Length)
+{
+	PUCHAR	pMem;
+	ULONG	Index = 0;
+
+	pMem = (PUCHAR) pSrc;
+
+	for (Index = 0; Index < Length; Index++)
+	{
+		pMem[Index] = 0x00;
+	}
+}
+
+VOID	RTMPFillMemory(
+	IN	PVOID	pSrc,
+	IN	ULONG	Length,
+	IN	UCHAR	Fill)
+{
+	PUCHAR	pMem;
+	ULONG	Index = 0;
+
+	pMem = (PUCHAR) pSrc;
+
+	for (Index = 0; Index < Length; Index++)
+	{
+		pMem[Index] = Fill;
+	}
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Copy data from memory block 1 to memory block 2
+
+	Arguments:
+		pDest		Pointer to destination memory address
+		pSrc		Pointer to source memory address
+		Length		Copy size
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTMPMoveMemory(
+	OUT	PVOID	pDest,
+	IN	PVOID	pSrc,
+	IN	ULONG	Length)
+{
+	PUCHAR	pMem1;
+	PUCHAR	pMem2;
+	UINT	Index;
+
+	ASSERT((Length==0) || (pDest && pSrc));
+
+	pMem1 = (PUCHAR) pDest;
+	pMem2 = (PUCHAR) pSrc;
+
+	for (Index = 0; Index < Length; Index++)
+	{
+		pMem1[Index] = pMem2[Index];
+	}
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Initialize port configuration structure
+
+	Arguments:
+		Adapter						Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+VOID	UserCfgInit(
+	IN	PRTMP_ADAPTER pAd)
+{
+//	EDCA_PARM DefaultEdcaParm;
+    UINT key_index, bss_index;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--> UserCfgInit\n"));
+
+	//
+	//  part I. intialize common configuration
+	//
+#ifdef RT2870
+	pAd->BulkOutReq = 0;
+
+	pAd->BulkOutComplete = 0;
+	pAd->BulkOutCompleteOther = 0;
+	pAd->BulkOutCompleteCancel = 0;
+	pAd->BulkInReq = 0;
+	pAd->BulkInComplete = 0;
+	pAd->BulkInCompleteFail = 0;
+
+	//pAd->QuickTimerP = 100;
+	//pAd->TurnAggrBulkInCount = 0;
+	pAd->bUsbTxBulkAggre = 0;
+
+	// init as unsed value to ensure driver will set to MCU once.
+	pAd->LedIndicatorStregth = 0xFF;
+
+	pAd->CommonCfg.MaxPktOneTxBulk = 2;
+	pAd->CommonCfg.TxBulkFactor = 1;
+	pAd->CommonCfg.RxBulkFactor =1;
+
+	pAd->CommonCfg.TxPower = 100; //mW
+
+	NdisZeroMemory(&pAd->CommonCfg.IOTestParm, sizeof(pAd->CommonCfg.IOTestParm));
+#endif // RT2870 //
+
+	for(key_index=0; key_index<SHARE_KEY_NUM; key_index++)
+	{
+		for(bss_index = 0; bss_index < MAX_MBSSID_NUM; bss_index++)
+		{
+			pAd->SharedKey[bss_index][key_index].KeyLen = 0;
+			pAd->SharedKey[bss_index][key_index].CipherAlg = CIPHER_NONE;
+        } /* End of for */
+    } /* End of for */
+
+	pAd->EepromAccess = FALSE;
+
+	pAd->Antenna.word = 0;
+	pAd->CommonCfg.BBPCurrentBW = BW_20;
+
+	pAd->LedCntl.word = 0;
+
+	pAd->bAutoTxAgcA = FALSE;			// Default is OFF
+	pAd->bAutoTxAgcG = FALSE;			// Default is OFF
+	pAd->RfIcType = RFIC_2820;
+
+	// Init timer for reset complete event
+	pAd->CommonCfg.CentralChannel = 1;
+	pAd->bForcePrintTX = FALSE;
+	pAd->bForcePrintRX = FALSE;
+	pAd->bStaFifoTest = FALSE;
+	pAd->bProtectionTest = FALSE;
+	pAd->bHCCATest = FALSE;
+	pAd->bGenOneHCCA = FALSE;
+	pAd->CommonCfg.Dsifs = 10;      // in units of usec
+	pAd->CommonCfg.TxPower = 100; //mW
+	pAd->CommonCfg.TxPowerPercentage = 0xffffffff; // AUTO
+	pAd->CommonCfg.TxPowerDefault = 0xffffffff; // AUTO
+	pAd->CommonCfg.TxPreamble = Rt802_11PreambleAuto; // use Long preamble on TX by defaut
+	pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
+	pAd->CommonCfg.RtsThreshold = 2347;
+	pAd->CommonCfg.FragmentThreshold = 2346;
+	pAd->CommonCfg.UseBGProtection = 0;    // 0: AUTO
+	pAd->CommonCfg.bEnableTxBurst = TRUE; //0;
+	pAd->CommonCfg.PhyMode = 0xff;     // unknown
+	pAd->CommonCfg.BandState = UNKNOWN_BAND;
+	pAd->CommonCfg.RadarDetect.CSPeriod = 10;
+	pAd->CommonCfg.RadarDetect.CSCount = 0;
+	pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
+	pAd->CommonCfg.RadarDetect.ChMovingTime = 65;
+	pAd->CommonCfg.RadarDetect.LongPulseRadarTh = 3;
+	pAd->CommonCfg.bAPSDCapable = FALSE;
+	pAd->CommonCfg.bNeedSendTriggerFrame = FALSE;
+	pAd->CommonCfg.TriggerTimerCount = 0;
+	pAd->CommonCfg.bAPSDForcePowerSave = FALSE;
+	pAd->CommonCfg.bCountryFlag = FALSE;
+	pAd->CommonCfg.TxStream = 0;
+	pAd->CommonCfg.RxStream = 0;
+
+	NdisZeroMemory(&pAd->BeaconTxWI, sizeof(pAd->BeaconTxWI));
+
+#ifdef DOT11_N_SUPPORT
+	NdisZeroMemory(&pAd->CommonCfg.HtCapability, sizeof(pAd->CommonCfg.HtCapability));
+	pAd->HTCEnable = FALSE;
+	pAd->bBroadComHT = FALSE;
+	pAd->CommonCfg.bRdg = FALSE;
+
+#ifdef DOT11N_DRAFT3
+	pAd->CommonCfg.Dot11OBssScanPassiveDwell = dot11OBSSScanPassiveDwell;	// Unit : TU. 5~1000
+	pAd->CommonCfg.Dot11OBssScanActiveDwell = dot11OBSSScanActiveDwell;	// Unit : TU. 10~1000
+	pAd->CommonCfg.Dot11BssWidthTriggerScanInt = dot11BSSWidthTriggerScanInterval;	// Unit : Second
+	pAd->CommonCfg.Dot11OBssScanPassiveTotalPerChannel = dot11OBSSScanPassiveTotalPerChannel;	// Unit : TU. 200~10000
+	pAd->CommonCfg.Dot11OBssScanActiveTotalPerChannel = dot11OBSSScanActiveTotalPerChannel;	// Unit : TU. 20~10000
+	pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor = dot11BSSWidthChannelTransactionDelayFactor;
+	pAd->CommonCfg.Dot11OBssScanActivityThre = dot11BSSScanActivityThreshold;	// Unit : percentage
+	pAd->CommonCfg.Dot11BssWidthChanTranDelay = (pAd->CommonCfg.Dot11BssWidthTriggerScanInt * pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor);
+#endif  // DOT11N_DRAFT3 //
+
+	NdisZeroMemory(&pAd->CommonCfg.AddHTInfo, sizeof(pAd->CommonCfg.AddHTInfo));
+	pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
+	pAd->CommonCfg.BACapability.field.MpduDensity = 0;
+	pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
+	pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64; //32;
+	pAd->CommonCfg.BACapability.field.TxBAWinLimit = 64; //32;
+	DBGPRINT(RT_DEBUG_TRACE, ("--> UserCfgInit. BACapability = 0x%x\n", pAd->CommonCfg.BACapability.word));
+
+	pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
+	BATableInit(pAd, &pAd->BATable);
+
+	pAd->CommonCfg.bExtChannelSwitchAnnouncement = 1;
+	pAd->CommonCfg.bHTProtect = 1;
+	pAd->CommonCfg.bMIMOPSEnable = TRUE;
+	pAd->CommonCfg.bBADecline = FALSE;
+	pAd->CommonCfg.bDisableReordering = FALSE;
+
+	pAd->CommonCfg.TxBASize = 7;
+
+	pAd->CommonCfg.REGBACapability.word = pAd->CommonCfg.BACapability.word;
+#endif // DOT11_N_SUPPORT //
+
+	//pAd->CommonCfg.HTPhyMode.field.BW = BW_20;
+	//pAd->CommonCfg.HTPhyMode.field.MCS = MCS_AUTO;
+	//pAd->CommonCfg.HTPhyMode.field.ShortGI = GI_800;
+	//pAd->CommonCfg.HTPhyMode.field.STBC = STBC_NONE;
+	pAd->CommonCfg.TxRate = RATE_6;
+
+	pAd->CommonCfg.MlmeTransmit.field.MCS = MCS_RATE_6;
+	pAd->CommonCfg.MlmeTransmit.field.BW = BW_20;
+	pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
+
+	pAd->CommonCfg.BeaconPeriod = 100;     // in mSec
+
+	//
+	// part II. intialize STA specific configuration
+	//
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_DIRECT);
+		RX_FILTER_CLEAR_FLAG(pAd, fRX_FILTER_ACCEPT_MULTICAST);
+		RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_BROADCAST);
+		RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_ALL_MULTICAST);
+
+		pAd->StaCfg.Psm = PWR_ACTIVE;
+
+		pAd->StaCfg.OrigWepStatus = Ndis802_11EncryptionDisabled;
+		pAd->StaCfg.PairCipher = Ndis802_11EncryptionDisabled;
+		pAd->StaCfg.GroupCipher = Ndis802_11EncryptionDisabled;
+		pAd->StaCfg.bMixCipher = FALSE;
+		pAd->StaCfg.DefaultKeyId = 0;
+
+		// 802.1x port control
+		pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
+		pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+		pAd->StaCfg.LastMicErrorTime = 0;
+		pAd->StaCfg.MicErrCnt        = 0;
+		pAd->StaCfg.bBlockAssoc      = FALSE;
+		pAd->StaCfg.WpaState         = SS_NOTUSE;
+
+		pAd->CommonCfg.NdisRadioStateOff = FALSE;		// New to support microsoft disable radio with OID command
+
+		pAd->StaCfg.RssiTrigger = 0;
+		NdisZeroMemory(&pAd->StaCfg.RssiSample, sizeof(RSSI_SAMPLE));
+		pAd->StaCfg.RssiTriggerMode = RSSI_TRIGGERED_UPON_BELOW_THRESHOLD;
+		pAd->StaCfg.AtimWin = 0;
+		pAd->StaCfg.DefaultListenCount = 3;//default listen count;
+		pAd->StaCfg.BssType = BSS_INFRA;  // BSS_INFRA or BSS_ADHOC or BSS_MONITOR
+		pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
+		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
+		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
+
+		pAd->StaCfg.bAutoTxRateSwitch = TRUE;
+		pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
+	}
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+	pAd->StaCfg.IEEE80211dClientMode = Rt802_11_D_None;
+#endif // EXT_BUILD_CHANNEL_LIST //
+#endif // CONFIG_STA_SUPPORT //
+
+	// global variables mXXXX used in MAC protocol state machines
+	OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
+	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
+	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
+
+	// PHY specification
+	pAd->CommonCfg.PhyMode = PHY_11BG_MIXED;		// default PHY mode
+	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);  // CCK use LONG preamble
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		// user desired power mode
+		pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
+		pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
+		pAd->StaCfg.bWindowsACCAMEnable = FALSE;
+
+#ifdef LEAP_SUPPORT
+		// CCX v1.0 releated init value
+		RTMPInitTimer(pAd, &pAd->StaCfg.LeapAuthTimer, GET_TIMER_FUNCTION(LeapAuthTimeout), pAd, FALSE);
+		pAd->StaCfg.LeapAuthMode = CISCO_AuthModeLEAPNone;
+		pAd->StaCfg.bCkipOn = FALSE;
+#endif // LEAP_SUPPORT //
+
+		RTMPInitTimer(pAd, &pAd->StaCfg.StaQuickResponeForRateUpTimer, GET_TIMER_FUNCTION(StaQuickResponeForRateUpExec), pAd, FALSE);
+		pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
+
+		// Patch for Ndtest
+		pAd->StaCfg.ScanCnt = 0;
+
+		// CCX 2.0 control flag init
+		pAd->StaCfg.CCXEnable = FALSE;
+		pAd->StaCfg.CCXReqType = MSRN_TYPE_UNUSED;
+		pAd->StaCfg.CCXQosECWMin	= 4;
+		pAd->StaCfg.CCXQosECWMax	= 10;
+
+		pAd->StaCfg.bHwRadio  = TRUE; // Default Hardware Radio status is On
+		pAd->StaCfg.bSwRadio  = TRUE; // Default Software Radio status is On
+		pAd->StaCfg.bRadio    = TRUE; // bHwRadio && bSwRadio
+		pAd->StaCfg.bHardwareRadio = FALSE;		// Default is OFF
+		pAd->StaCfg.bShowHiddenSSID = FALSE;		// Default no show
+
+		// Nitro mode control
+		pAd->StaCfg.bAutoReconnect = TRUE;
+
+		// Save the init time as last scan time, the system should do scan after 2 seconds.
+		// This patch is for driver wake up from standby mode, system will do scan right away.
+		pAd->StaCfg.LastScanTime = 0;
+		NdisZeroMemory(pAd->nickname, IW_ESSID_MAX_SIZE+1);
+		sprintf(pAd->nickname, "%s", STA_NIC_DEVICE_NAME);
+		RTMPInitTimer(pAd, &pAd->StaCfg.WpaDisassocAndBlockAssocTimer, GET_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc), pAd, FALSE);
+#ifdef WPA_SUPPLICANT_SUPPORT
+		pAd->StaCfg.IEEE8021X = FALSE;
+		pAd->StaCfg.IEEE8021x_required_keys = FALSE;
+		pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+		pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	// Default for extra information is not valid
+	pAd->ExtraInfo = EXTRA_INFO_CLEAR;
+
+	// Default Config change flag
+	pAd->bConfigChanged = FALSE;
+
+	//
+	// part III. AP configurations
+	//
+
+
+	//
+	// part IV. others
+	//
+	// dynamic BBP R66:sensibity tuning to overcome background noise
+	pAd->BbpTuning.bEnable                = TRUE;
+	pAd->BbpTuning.FalseCcaLowerThreshold = 100;
+	pAd->BbpTuning.FalseCcaUpperThreshold = 512;
+	pAd->BbpTuning.R66Delta               = 4;
+	pAd->Mlme.bEnableAutoAntennaCheck = TRUE;
+
+	//
+	// Also initial R66CurrentValue, RTUSBResumeMsduTransmission might use this value.
+	// if not initial this value, the default value will be 0.
+	//
+	pAd->BbpTuning.R66CurrentValue = 0x38;
+
+	pAd->Bbp94 = BBPR94_DEFAULT;
+	pAd->BbpForCCK = FALSE;
+
+	// Default is FALSE for test bit 1
+	//pAd->bTest1 = FALSE;
+
+	// initialize MAC table and allocate spin lock
+	NdisZeroMemory(&pAd->MacTab, sizeof(MAC_TABLE));
+	InitializeQueueHeader(&pAd->MacTab.McastPsQueue);
+	NdisAllocateSpinLock(&pAd->MacTabLock);
+
+	//RTMPInitTimer(pAd, &pAd->RECBATimer, RECBATimerTimeout, pAd, TRUE);
+	//RTMPSetTimer(&pAd->RECBATimer, REORDER_EXEC_INTV);
+
+#ifdef RALINK_ATE
+	NdisZeroMemory(&pAd->ate, sizeof(ATE_INFO));
+	pAd->ate.Mode = ATE_STOP;
+	pAd->ate.TxCount = 200;/* to exceed TX_RING_SIZE ... */
+	pAd->ate.TxLength = 1024;
+	pAd->ate.TxWI.ShortGI = 0;// LONG GI : 800 ns
+	pAd->ate.TxWI.PHYMODE = MODE_CCK;
+	pAd->ate.TxWI.MCS = 3;
+	pAd->ate.TxWI.BW = BW_20;
+	pAd->ate.Channel = 1;
+	pAd->ate.QID = QID_AC_BE;
+	pAd->ate.Addr1[0] = 0x00;
+	pAd->ate.Addr1[1] = 0x11;
+	pAd->ate.Addr1[2] = 0x22;
+	pAd->ate.Addr1[3] = 0xAA;
+	pAd->ate.Addr1[4] = 0xBB;
+	pAd->ate.Addr1[5] = 0xCC;
+	NdisMoveMemory(pAd->ate.Addr2, pAd->ate.Addr1, ETH_LENGTH_OF_ADDRESS);
+	NdisMoveMemory(pAd->ate.Addr3, pAd->ate.Addr1, ETH_LENGTH_OF_ADDRESS);
+	pAd->ate.bRxFer = 0;
+	pAd->ate.bQATxStart = FALSE;
+	pAd->ate.bQARxStart = FALSE;
+#ifdef RALINK_28xx_QA
+	//pAd->ate.Repeat = 0;
+	pAd->ate.TxStatus = 0;
+	pAd->ate.AtePid = 0;
+#endif // RALINK_28xx_QA //
+#endif // RALINK_ATE //
+
+
+	pAd->CommonCfg.bWiFiTest = FALSE;
+
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<-- UserCfgInit\n"));
+}
+
+// IRQL = PASSIVE_LEVEL
+UCHAR BtoH(char ch)
+{
+	if (ch >= '0' && ch <= '9') return (ch - '0');        // Handle numerals
+	if (ch >= 'A' && ch <= 'F') return (ch - 'A' + 0xA);  // Handle capitol hex digits
+	if (ch >= 'a' && ch <= 'f') return (ch - 'a' + 0xA);  // Handle small hex digits
+	return(255);
+}
+
+//
+//  FUNCTION: AtoH(char *, UCHAR *, int)
+//
+//  PURPOSE:  Converts ascii string to network order hex
+//
+//  PARAMETERS:
+//    src    - pointer to input ascii string
+//    dest   - pointer to output hex
+//    destlen - size of dest
+//
+//  COMMENTS:
+//
+//    2 ascii bytes make a hex byte so must put 1st ascii byte of pair
+//    into upper nibble and 2nd ascii byte of pair into lower nibble.
+//
+// IRQL = PASSIVE_LEVEL
+
+void AtoH(char * src, UCHAR * dest, int destlen)
+{
+	char * srcptr;
+	PUCHAR destTemp;
+
+	srcptr = src;
+	destTemp = (PUCHAR) dest;
+
+	while(destlen--)
+	{
+		*destTemp = BtoH(*srcptr++) << 4;    // Put 1st ascii byte in upper nibble.
+		*destTemp += BtoH(*srcptr++);      // Add 2nd ascii byte to above.
+		destTemp++;
+	}
+}
+
+VOID	RTMPPatchMacBbpBug(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	ULONG	Index;
+
+	// Initialize BBP register to default value
+	for (Index = 0; Index < NUM_BBP_REG_PARMS; Index++)
+	{
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register, (UCHAR)BBPRegTable[Index].Value);
+	}
+
+	// Initialize RF register to default value
+	AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+	AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+
+	// Re-init BBP register from EEPROM value
+	NICInitAsicFromEEPROM(pAd);
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Init timer objects
+
+	Arguments:
+		pAd			Pointer to our adapter
+		pTimer				Timer structure
+		pTimerFunc			Function to execute when timer expired
+		Repeat				Ture for period timer
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTMPInitTimer(
+	IN	PRTMP_ADAPTER			pAd,
+	IN	PRALINK_TIMER_STRUCT	pTimer,
+	IN	PVOID					pTimerFunc,
+	IN	PVOID					pData,
+	IN	BOOLEAN					Repeat)
+{
+	//
+	// Set Valid to TRUE for later used.
+	// It will crash if we cancel a timer or set a timer
+	// that we haven't initialize before.
+	//
+	pTimer->Valid      = TRUE;
+
+	pTimer->PeriodicType = Repeat;
+	pTimer->State      = FALSE;
+	pTimer->cookie = (ULONG) pData;
+
+#ifdef RT2870
+	pTimer->pAd = pAd;
+#endif // RT2870 //
+
+	RTMP_OS_Init_Timer(pAd,	&pTimer->TimerObj,	pTimerFunc, (PVOID) pTimer);
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Init timer objects
+
+	Arguments:
+		pTimer				Timer structure
+		Value				Timer value in milliseconds
+
+	Return Value:
+		None
+
+	Note:
+		To use this routine, must call RTMPInitTimer before.
+
+	========================================================================
+*/
+VOID	RTMPSetTimer(
+	IN	PRALINK_TIMER_STRUCT	pTimer,
+	IN	ULONG					Value)
+{
+	if (pTimer->Valid)
+	{
+		pTimer->TimerValue = Value;
+		pTimer->State      = FALSE;
+		if (pTimer->PeriodicType == TRUE)
+		{
+			pTimer->Repeat = TRUE;
+			RTMP_SetPeriodicTimer(&pTimer->TimerObj, Value);
+		}
+		else
+		{
+			pTimer->Repeat = FALSE;
+			RTMP_OS_Add_Timer(&pTimer->TimerObj, Value);
+		}
+	}
+	else
+	{
+		DBGPRINT_ERR(("RTMPSetTimer failed, Timer hasn't been initialize!\n"));
+	}
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Init timer objects
+
+	Arguments:
+		pTimer				Timer structure
+		Value				Timer value in milliseconds
+
+	Return Value:
+		None
+
+	Note:
+		To use this routine, must call RTMPInitTimer before.
+
+	========================================================================
+*/
+VOID	RTMPModTimer(
+	IN	PRALINK_TIMER_STRUCT	pTimer,
+	IN	ULONG					Value)
+{
+	BOOLEAN	Cancel;
+
+	if (pTimer->Valid)
+	{
+		pTimer->TimerValue = Value;
+		pTimer->State      = FALSE;
+		if (pTimer->PeriodicType == TRUE)
+		{
+			RTMPCancelTimer(pTimer, &Cancel);
+			RTMPSetTimer(pTimer, Value);
+		}
+		else
+		{
+			RTMP_OS_Mod_Timer(&pTimer->TimerObj, Value);
+		}
+	}
+	else
+	{
+		DBGPRINT_ERR(("RTMPModTimer failed, Timer hasn't been initialize!\n"));
+	}
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Cancel timer objects
+
+	Arguments:
+		Adapter						Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+		1.) To use this routine, must call RTMPInitTimer before.
+		2.) Reset NIC to initial state AS IS system boot up time.
+
+	========================================================================
+*/
+VOID	RTMPCancelTimer(
+	IN	PRALINK_TIMER_STRUCT	pTimer,
+	OUT	BOOLEAN					*pCancelled)
+{
+	if (pTimer->Valid)
+	{
+		if (pTimer->State == FALSE)
+			pTimer->Repeat = FALSE;
+			RTMP_OS_Del_Timer(&pTimer->TimerObj, pCancelled);
+
+		if (*pCancelled == TRUE)
+			pTimer->State = TRUE;
+
+#ifdef RT2870
+		// We need to go-through the TimerQ to findout this timer handler and remove it if
+		//		it's still waiting for execution.
+
+		RT2870_TimerQ_Remove(pTimer->pAd, pTimer);
+#endif // RT2870 //
+	}
+	else
+	{
+		//
+		// NdisMCancelTimer just canced the timer and not mean release the timer.
+		// And don't set the "Valid" to False. So that we can use this timer again.
+		//
+		DBGPRINT_ERR(("RTMPCancelTimer failed, Timer hasn't been initialize!\n"));
+	}
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Set LED Status
+
+	Arguments:
+		pAd						Pointer to our adapter
+		Status					LED Status
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+VOID RTMPSetLED(
+	IN PRTMP_ADAPTER 	pAd,
+	IN UCHAR			Status)
+{
+	//ULONG			data;
+	UCHAR			HighByte = 0;
+	UCHAR			LowByte;
+
+// In ATE mode of RT2860 AP/STA, we have erased 8051 firmware.
+// So LED mode is not supported when ATE is running.
+#ifdef RALINK_ATE
+	if (ATE_ON(pAd))
+		return;
+#endif // RALINK_ATE //
+
+	LowByte = pAd->LedCntl.field.LedMode&0x7f;
+	switch (Status)
+	{
+		case LED_LINK_DOWN:
+			HighByte = 0x20;
+			AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+			pAd->LedIndicatorStregth = 0;
+			break;
+		case LED_LINK_UP:
+			if (pAd->CommonCfg.Channel > 14)
+				HighByte = 0xa0;
+			else
+				HighByte = 0x60;
+			AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+			break;
+		case LED_RADIO_ON:
+			HighByte = 0x20;
+			AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+			break;
+		case LED_HALT:
+			LowByte = 0; // Driver sets MAC register and MAC controls LED
+		case LED_RADIO_OFF:
+			HighByte = 0;
+			AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+			break;
+        case LED_WPS:
+			HighByte = 0x10;
+			AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+			break;
+		case LED_ON_SITE_SURVEY:
+			HighByte = 0x08;
+			AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+			break;
+		case LED_POWER_UP:
+			HighByte = 0x04;
+			AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+			break;
+		default:
+			DBGPRINT(RT_DEBUG_WARN, ("RTMPSetLED::Unknown Status %d\n", Status));
+			break;
+	}
+
+    //
+	// Keep LED status for LED SiteSurvey mode.
+	// After SiteSurvey, we will set the LED mode to previous status.
+	//
+	if ((Status != LED_ON_SITE_SURVEY) && (Status != LED_POWER_UP))
+		pAd->LedStatus = Status;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetLED::Mode=%d,HighByte=0x%02x,LowByte=0x%02x\n", pAd->LedCntl.field.LedMode, HighByte, LowByte));
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Set LED Signal Stregth
+
+	Arguments:
+		pAd						Pointer to our adapter
+		Dbm						Signal Stregth
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+
+	Note:
+		Can be run on any IRQL level.
+
+		According to Microsoft Zero Config Wireless Signal Stregth definition as belows.
+		<= -90  No Signal
+		<= -81  Very Low
+		<= -71  Low
+		<= -67  Good
+		<= -57  Very Good
+		 > -57  Excellent
+	========================================================================
+*/
+VOID RTMPSetSignalLED(
+	IN PRTMP_ADAPTER 	pAd,
+	IN NDIS_802_11_RSSI Dbm)
+{
+	UCHAR		nLed = 0;
+
+	//
+	// if not Signal Stregth, then do nothing.
+	//
+	if (pAd->LedCntl.field.LedMode != LED_MODE_SIGNAL_STREGTH)
+	{
+		return;
+	}
+
+	if (Dbm <= -90)
+		nLed = 0;
+	else if (Dbm <= -81)
+		nLed = 1;
+	else if (Dbm <= -71)
+		nLed = 3;
+	else if (Dbm <= -67)
+		nLed = 7;
+	else if (Dbm <= -57)
+		nLed = 15;
+	else
+		nLed = 31;
+
+	//
+	// Update Signal Stregth to firmware if changed.
+	//
+	if (pAd->LedIndicatorStregth != nLed)
+	{
+		AsicSendCommandToMcu(pAd, 0x51, 0xff, nLed, pAd->LedCntl.field.Polarity);
+		pAd->LedIndicatorStregth = nLed;
+	}
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Enable RX
+
+	Arguments:
+		pAd						Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL <= DISPATCH_LEVEL
+
+	Note:
+		Before Enable RX, make sure you have enabled Interrupt.
+	========================================================================
+*/
+VOID RTMPEnableRxTx(
+	IN PRTMP_ADAPTER	pAd)
+{
+//	WPDMA_GLO_CFG_STRUC	GloCfg;
+//	ULONG	i = 0;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPEnableRxTx\n"));
+
+	// Enable Rx DMA.
+	RT28XXDMAEnable(pAd);
+
+	// enable RX of MAC block
+	if (pAd->OpMode == OPMODE_AP)
+	{
+		UINT32 rx_filter_flag = APNORMAL;
+
+
+		RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag);     // enable RX of DMA block
+	}
+	else
+	{
+		RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL);     // Staion not drop control frame will fail WiFi Certification.
+	}
+
+	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc);
+	DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPEnableRxTx\n"));
+}
+
+
diff --git a/drivers/staging/rt3070/common/rtmp_tkip.c b/drivers/staging/rt3070/common/rtmp_tkip.c
new file mode 100644
index 0000000..bf8986e
--- /dev/null
+++ b/drivers/staging/rt3070/common/rtmp_tkip.c
@@ -0,0 +1,1613 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	rtmp_tkip.c
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	Paul Wu		02-25-02		Initial
+*/
+
+#include	"../rt_config.h"
+
+// Rotation functions on 32 bit values
+#define ROL32( A, n ) \
+	( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) )
+#define ROR32( A, n ) ROL32( (A), 32-(n) )
+
+UINT Tkip_Sbox_Lower[256] =
+{
+	0xA5,0x84,0x99,0x8D,0x0D,0xBD,0xB1,0x54,
+	0x50,0x03,0xA9,0x7D,0x19,0x62,0xE6,0x9A,
+	0x45,0x9D,0x40,0x87,0x15,0xEB,0xC9,0x0B,
+	0xEC,0x67,0xFD,0xEA,0xBF,0xF7,0x96,0x5B,
+	0xC2,0x1C,0xAE,0x6A,0x5A,0x41,0x02,0x4F,
+	0x5C,0xF4,0x34,0x08,0x93,0x73,0x53,0x3F,
+	0x0C,0x52,0x65,0x5E,0x28,0xA1,0x0F,0xB5,
+	0x09,0x36,0x9B,0x3D,0x26,0x69,0xCD,0x9F,
+	0x1B,0x9E,0x74,0x2E,0x2D,0xB2,0xEE,0xFB,
+	0xF6,0x4D,0x61,0xCE,0x7B,0x3E,0x71,0x97,
+	0xF5,0x68,0x00,0x2C,0x60,0x1F,0xC8,0xED,
+	0xBE,0x46,0xD9,0x4B,0xDE,0xD4,0xE8,0x4A,
+	0x6B,0x2A,0xE5,0x16,0xC5,0xD7,0x55,0x94,
+	0xCF,0x10,0x06,0x81,0xF0,0x44,0xBA,0xE3,
+	0xF3,0xFE,0xC0,0x8A,0xAD,0xBC,0x48,0x04,
+	0xDF,0xC1,0x75,0x63,0x30,0x1A,0x0E,0x6D,
+	0x4C,0x14,0x35,0x2F,0xE1,0xA2,0xCC,0x39,
+	0x57,0xF2,0x82,0x47,0xAC,0xE7,0x2B,0x95,
+	0xA0,0x98,0xD1,0x7F,0x66,0x7E,0xAB,0x83,
+	0xCA,0x29,0xD3,0x3C,0x79,0xE2,0x1D,0x76,
+	0x3B,0x56,0x4E,0x1E,0xDB,0x0A,0x6C,0xE4,
+	0x5D,0x6E,0xEF,0xA6,0xA8,0xA4,0x37,0x8B,
+	0x32,0x43,0x59,0xB7,0x8C,0x64,0xD2,0xE0,
+	0xB4,0xFA,0x07,0x25,0xAF,0x8E,0xE9,0x18,
+	0xD5,0x88,0x6F,0x72,0x24,0xF1,0xC7,0x51,
+	0x23,0x7C,0x9C,0x21,0xDD,0xDC,0x86,0x85,
+	0x90,0x42,0xC4,0xAA,0xD8,0x05,0x01,0x12,
+	0xA3,0x5F,0xF9,0xD0,0x91,0x58,0x27,0xB9,
+	0x38,0x13,0xB3,0x33,0xBB,0x70,0x89,0xA7,
+	0xB6,0x22,0x92,0x20,0x49,0xFF,0x78,0x7A,
+	0x8F,0xF8,0x80,0x17,0xDA,0x31,0xC6,0xB8,
+	0xC3,0xB0,0x77,0x11,0xCB,0xFC,0xD6,0x3A
+};
+
+UINT Tkip_Sbox_Upper[256] =
+{
+	0xC6,0xF8,0xEE,0xF6,0xFF,0xD6,0xDE,0x91,
+	0x60,0x02,0xCE,0x56,0xE7,0xB5,0x4D,0xEC,
+	0x8F,0x1F,0x89,0xFA,0xEF,0xB2,0x8E,0xFB,
+	0x41,0xB3,0x5F,0x45,0x23,0x53,0xE4,0x9B,
+	0x75,0xE1,0x3D,0x4C,0x6C,0x7E,0xF5,0x83,
+	0x68,0x51,0xD1,0xF9,0xE2,0xAB,0x62,0x2A,
+	0x08,0x95,0x46,0x9D,0x30,0x37,0x0A,0x2F,
+	0x0E,0x24,0x1B,0xDF,0xCD,0x4E,0x7F,0xEA,
+	0x12,0x1D,0x58,0x34,0x36,0xDC,0xB4,0x5B,
+	0xA4,0x76,0xB7,0x7D,0x52,0xDD,0x5E,0x13,
+	0xA6,0xB9,0x00,0xC1,0x40,0xE3,0x79,0xB6,
+	0xD4,0x8D,0x67,0x72,0x94,0x98,0xB0,0x85,
+	0xBB,0xC5,0x4F,0xED,0x86,0x9A,0x66,0x11,
+	0x8A,0xE9,0x04,0xFE,0xA0,0x78,0x25,0x4B,
+	0xA2,0x5D,0x80,0x05,0x3F,0x21,0x70,0xF1,
+	0x63,0x77,0xAF,0x42,0x20,0xE5,0xFD,0xBF,
+	0x81,0x18,0x26,0xC3,0xBE,0x35,0x88,0x2E,
+	0x93,0x55,0xFC,0x7A,0xC8,0xBA,0x32,0xE6,
+	0xC0,0x19,0x9E,0xA3,0x44,0x54,0x3B,0x0B,
+	0x8C,0xC7,0x6B,0x28,0xA7,0xBC,0x16,0xAD,
+	0xDB,0x64,0x74,0x14,0x92,0x0C,0x48,0xB8,
+	0x9F,0xBD,0x43,0xC4,0x39,0x31,0xD3,0xF2,
+	0xD5,0x8B,0x6E,0xDA,0x01,0xB1,0x9C,0x49,
+	0xD8,0xAC,0xF3,0xCF,0xCA,0xF4,0x47,0x10,
+	0x6F,0xF0,0x4A,0x5C,0x38,0x57,0x73,0x97,
+	0xCB,0xA1,0xE8,0x3E,0x96,0x61,0x0D,0x0F,
+	0xE0,0x7C,0x71,0xCC,0x90,0x06,0xF7,0x1C,
+	0xC2,0x6A,0xAE,0x69,0x17,0x99,0x3A,0x27,
+	0xD9,0xEB,0x2B,0x22,0xD2,0xA9,0x07,0x33,
+	0x2D,0x3C,0x15,0xC9,0x87,0xAA,0x50,0xA5,
+	0x03,0x59,0x09,0x1A,0x65,0xD7,0x84,0xD0,
+	0x82,0x29,0x5A,0x1E,0x7B,0xA8,0x6D,0x2C
+};
+
+/*****************************/
+/******** SBOX Table *********/
+/*****************************/
+
+UCHAR SboxTable[256] =
+{
+	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
+	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
+	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
+	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
+	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
+	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
+	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
+	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
+	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
+	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
+	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
+	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
+	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
+	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
+	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
+	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
+	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+};
+
+VOID xor_32(
+	IN  PUCHAR              a,
+	IN  PUCHAR              b,
+	OUT PUCHAR              out);
+
+VOID xor_128(
+	IN  PUCHAR              a,
+	IN  PUCHAR              b,
+	OUT PUCHAR              out);
+
+VOID next_key(
+	IN  PUCHAR              key,
+	IN  INT                 round);
+
+VOID byte_sub(
+	IN  PUCHAR              in,
+	OUT PUCHAR              out);
+
+VOID shift_row(
+	IN  PUCHAR              in,
+	OUT PUCHAR              out);
+
+VOID mix_column(
+	IN  PUCHAR              in,
+	OUT PUCHAR              out);
+
+UCHAR RTMPCkipSbox(
+	IN  UCHAR               a);
+//
+// Expanded IV for TKIP function.
+//
+typedef	struct	PACKED _IV_CONTROL_
+{
+	union PACKED
+	{
+		struct PACKED
+		{
+			UCHAR		rc0;
+			UCHAR		rc1;
+			UCHAR		rc2;
+
+			union PACKED
+			{
+				struct PACKED
+				{
+#ifdef RT_BIG_ENDIAN
+					UCHAR	KeyID:2;
+					UCHAR	ExtIV:1;
+					UCHAR	Rsvd:5;
+#else
+					UCHAR	Rsvd:5;
+					UCHAR	ExtIV:1;
+					UCHAR	KeyID:2;
+#endif
+				}	field;
+				UCHAR		Byte;
+			}	CONTROL;
+		}	field;
+
+		ULONG	word;
+	}	IV16;
+
+	ULONG	IV32;
+}	TKIP_IV, *PTKIP_IV;
+
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Convert from UCHAR[] to ULONG in a portable way
+
+	Arguments:
+      pMICKey		pointer to MIC Key
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+ULONG	RTMPTkipGetUInt32(
+	IN	PUCHAR	pMICKey)
+{
+	ULONG	res = 0;
+	INT		i;
+
+	for (i = 0; i < 4; i++)
+	{
+		res |= (*pMICKey++) << (8 * i);
+	}
+
+	return res;
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Convert from ULONG to UCHAR[] in a portable way
+
+	Arguments:
+      pDst			pointer to destination for convert ULONG to UCHAR[]
+      val			the value for convert
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTMPTkipPutUInt32(
+	IN OUT	PUCHAR		pDst,
+	IN		ULONG		val)
+{
+	INT i;
+
+	for(i = 0; i < 4; i++)
+	{
+		*pDst++ = (UCHAR) (val & 0xff);
+		val >>= 8;
+	}
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Set the MIC Key.
+
+	Arguments:
+      pAd		Pointer to our adapter
+      pMICKey		pointer to MIC Key
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+VOID RTMPTkipSetMICKey(
+	IN	PTKIP_KEY_INFO	pTkip,
+	IN	PUCHAR			pMICKey)
+{
+	// Set the key
+	pTkip->K0 = RTMPTkipGetUInt32(pMICKey);
+	pTkip->K1 = RTMPTkipGetUInt32(pMICKey + 4);
+	// and reset the message
+	pTkip->L = pTkip->K0;
+	pTkip->R = pTkip->K1;
+	pTkip->nBytesInM = 0;
+	pTkip->M = 0;
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Calculate the MIC Value.
+
+	Arguments:
+      pAd		Pointer to our adapter
+      uChar			Append this uChar
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTMPTkipAppendByte(
+	IN	PTKIP_KEY_INFO	pTkip,
+	IN	UCHAR 			uChar)
+{
+	// Append the byte to our word-sized buffer
+	pTkip->M |= (uChar << (8* pTkip->nBytesInM));
+	pTkip->nBytesInM++;
+	// Process the word if it is full.
+	if( pTkip->nBytesInM >= 4 )
+	{
+		pTkip->L ^= pTkip->M;
+		pTkip->R ^= ROL32( pTkip->L, 17 );
+		pTkip->L += pTkip->R;
+		pTkip->R ^= ((pTkip->L & 0xff00ff00) >> 8) | ((pTkip->L & 0x00ff00ff) << 8);
+		pTkip->L += pTkip->R;
+		pTkip->R ^= ROL32( pTkip->L, 3 );
+		pTkip->L += pTkip->R;
+		pTkip->R ^= ROR32( pTkip->L, 2 );
+		pTkip->L += pTkip->R;
+		// Clear the buffer
+		pTkip->M = 0;
+		pTkip->nBytesInM = 0;
+	}
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Calculate the MIC Value.
+
+	Arguments:
+      pAd		Pointer to our adapter
+      pSrc			Pointer to source data for Calculate MIC Value
+      Len			Indicate the length of the source data
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTMPTkipAppend(
+	IN	PTKIP_KEY_INFO	pTkip,
+	IN	PUCHAR			pSrc,
+	IN	UINT			nBytes)
+{
+	// This is simple
+	while(nBytes > 0)
+	{
+		RTMPTkipAppendByte(pTkip, *pSrc++);
+		nBytes--;
+	}
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Get the MIC Value.
+
+	Arguments:
+      pAd		Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+		the MIC Value is store in pAd->PrivateInfo.MIC
+	========================================================================
+*/
+VOID	RTMPTkipGetMIC(
+	IN	PTKIP_KEY_INFO	pTkip)
+{
+	// Append the minimum padding
+	RTMPTkipAppendByte(pTkip, 0x5a );
+	RTMPTkipAppendByte(pTkip, 0 );
+	RTMPTkipAppendByte(pTkip, 0 );
+	RTMPTkipAppendByte(pTkip, 0 );
+	RTMPTkipAppendByte(pTkip, 0 );
+	// and then zeroes until the length is a multiple of 4
+	while( pTkip->nBytesInM != 0 )
+	{
+		RTMPTkipAppendByte(pTkip, 0 );
+	}
+	// The appendByte function has already computed the result.
+	RTMPTkipPutUInt32(pTkip->MIC, pTkip->L);
+	RTMPTkipPutUInt32(pTkip->MIC + 4, pTkip->R);
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Init Tkip function.
+
+	Arguments:
+      pAd		Pointer to our adapter
+		pTKey       Pointer to the Temporal Key (TK), TK shall be 128bits.
+		KeyId		TK Key ID
+		pTA			Pointer to transmitter address
+		pMICKey		pointer to MIC Key
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTMPInitTkipEngine(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pKey,
+	IN	UCHAR			KeyId,
+	IN	PUCHAR			pTA,
+	IN	PUCHAR			pMICKey,
+	IN	PUCHAR			pTSC,
+	OUT	PULONG			pIV16,
+	OUT	PULONG			pIV32)
+{
+	TKIP_IV	tkipIv;
+
+	// Prepare 8 bytes TKIP encapsulation for MPDU
+	NdisZeroMemory(&tkipIv, sizeof(TKIP_IV));
+	tkipIv.IV16.field.rc0 = *(pTSC + 1);
+	tkipIv.IV16.field.rc1 = (tkipIv.IV16.field.rc0 | 0x20) & 0x7f;
+	tkipIv.IV16.field.rc2 = *pTSC;
+	tkipIv.IV16.field.CONTROL.field.ExtIV = 1;  // 0: non-extended IV, 1: an extended IV
+	tkipIv.IV16.field.CONTROL.field.KeyID = KeyId;
+//	tkipIv.IV32 = *(PULONG)(pTSC + 2);
+	NdisMoveMemory(&tkipIv.IV32, (pTSC + 2), 4);   // Copy IV
+
+	*pIV16 = tkipIv.IV16.word;
+	*pIV32 = tkipIv.IV32;
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Init MIC Value calculation function which include set MIC key &
+		calculate first 16 bytes (DA + SA + priority +  0)
+
+	Arguments:
+      pAd		Pointer to our adapter
+		pTKey       Pointer to the Temporal Key (TK), TK shall be 128bits.
+		pDA			Pointer to DA address
+		pSA			Pointer to SA address
+		pMICKey		pointer to MIC Key
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTMPInitMICEngine(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pKey,
+	IN	PUCHAR			pDA,
+	IN	PUCHAR			pSA,
+	IN  UCHAR           UserPriority,
+	IN	PUCHAR			pMICKey)
+{
+	ULONG Priority = UserPriority;
+
+	// Init MIC value calculation
+	RTMPTkipSetMICKey(&pAd->PrivateInfo.Tx, pMICKey);
+	// DA
+	RTMPTkipAppend(&pAd->PrivateInfo.Tx, pDA, MAC_ADDR_LEN);
+	// SA
+	RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSA, MAC_ADDR_LEN);
+	// Priority + 3 bytes of 0
+	RTMPTkipAppend(&pAd->PrivateInfo.Tx, (PUCHAR)&Priority, 4);
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Compare MIC value of received MSDU
+
+	Arguments:
+		pAd	Pointer to our adapter
+		pSrc        Pointer to the received Plain text data
+		pDA			Pointer to DA address
+		pSA			Pointer to SA address
+		pMICKey		pointer to MIC Key
+		Len         the length of the received plain text data exclude MIC value
+
+	Return Value:
+		TRUE        MIC value matched
+		FALSE       MIC value mismatched
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+BOOLEAN	RTMPTkipCompareMICValue(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pSrc,
+	IN	PUCHAR			pDA,
+	IN	PUCHAR			pSA,
+	IN	PUCHAR			pMICKey,
+	IN	UCHAR			UserPriority,
+	IN	UINT			Len)
+{
+	UCHAR	OldMic[8];
+	ULONG	Priority = UserPriority;
+
+	// Init MIC value calculation
+	RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
+	// DA
+	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
+	// SA
+	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
+	// Priority + 3 bytes of 0
+	RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4);
+
+	// Calculate MIC value from plain text data
+	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
+
+	// Get MIC valude from received frame
+	NdisMoveMemory(OldMic, pSrc + Len, 8);
+
+	// Get MIC value from decrypted plain data
+	RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
+
+	// Move MIC value from MSDU, this steps should move to data path.
+	// Since the MIC value might cross MPDUs.
+	if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8))
+	{
+		DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValue(): TKIP MIC Error !\n"));  //MIC error.
+
+
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Compare MIC value of received MSDU
+
+	Arguments:
+		pAd	Pointer to our adapter
+		pLLC		LLC header
+		pSrc        Pointer to the received Plain text data
+		pDA			Pointer to DA address
+		pSA			Pointer to SA address
+		pMICKey		pointer to MIC Key
+		Len         the length of the received plain text data exclude MIC value
+
+	Return Value:
+		TRUE        MIC value matched
+		FALSE       MIC value mismatched
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+BOOLEAN	RTMPTkipCompareMICValueWithLLC(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pLLC,
+	IN	PUCHAR			pSrc,
+	IN	PUCHAR			pDA,
+	IN	PUCHAR			pSA,
+	IN	PUCHAR			pMICKey,
+	IN	UINT			Len)
+{
+	UCHAR	OldMic[8];
+	ULONG	Priority = 0;
+
+	// Init MIC value calculation
+	RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
+	// DA
+	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
+	// SA
+	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
+	// Priority + 3 bytes of 0
+	RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4);
+
+	// Start with LLC header
+	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pLLC, 8);
+
+	// Calculate MIC value from plain text data
+	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
+
+	// Get MIC valude from received frame
+	NdisMoveMemory(OldMic, pSrc + Len, 8);
+
+	// Get MIC value from decrypted plain data
+	RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
+
+	// Move MIC value from MSDU, this steps should move to data path.
+	// Since the MIC value might cross MPDUs.
+	if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8))
+	{
+		DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValueWithLLC(): TKIP MIC Error !\n"));  //MIC error.
+
+
+		return (FALSE);
+	}
+	return (TRUE);
+}
+/*
+	========================================================================
+
+	Routine	Description:
+		Copy frame from waiting queue into relative ring buffer and set
+	appropriate ASIC register to kick hardware transmit function
+
+	Arguments:
+		pAd		Pointer	to our adapter
+		PNDIS_PACKET	Pointer to Ndis Packet for MIC calculation
+		pEncap			Pointer to LLC encap data
+		LenEncap		Total encap length, might be 0 which indicates no encap
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTMPCalculateMICValue(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PNDIS_PACKET	pPacket,
+	IN	PUCHAR			pEncap,
+	IN	PCIPHER_KEY		pKey,
+	IN	UCHAR			apidx)
+{
+	PACKET_INFO		PacketInfo;
+	PUCHAR			pSrcBufVA;
+	UINT			SrcBufLen;
+	PUCHAR			pSrc;
+    UCHAR           UserPriority;
+	UCHAR			vlan_offset = 0;
+
+	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
+
+	UserPriority = RTMP_GET_PACKET_UP(pPacket);
+	pSrc = pSrcBufVA;
+
+	// determine if this is a vlan packet
+	if (((*(pSrc + 12) << 8) + *(pSrc + 13)) == 0x8100)
+		vlan_offset = 4;
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+	{
+		RTMPInitMICEngine(
+			pAd,
+			pKey->Key,
+			pSrc,
+			pSrc + 6,
+			UserPriority,
+			pKey->TxMic);
+	}
+
+
+	if (pEncap != NULL)
+	{
+		// LLC encapsulation
+		RTMPTkipAppend(&pAd->PrivateInfo.Tx, pEncap, 6);
+		// Protocol Type
+		RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc + 12 + vlan_offset, 2);
+	}
+	SrcBufLen -= (14 + vlan_offset);
+	pSrc += (14 + vlan_offset);
+	do
+	{
+		if (SrcBufLen > 0)
+		{
+			RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc, SrcBufLen);
+		}
+
+		break;	// No need handle next packet
+
+	}	while (TRUE);		// End of copying payload
+
+	// Compute the final MIC Value
+	RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
+}
+
+
+/************************************************************/
+/* tkip_sbox()																*/
+/* Returns a 16 bit value from a 64K entry table. The Table */
+/* is synthesized from two 256 entry byte wide tables.		*/
+/************************************************************/
+
+UINT tkip_sbox(UINT index)
+{
+	UINT index_low;
+	UINT index_high;
+	UINT left, right;
+
+	index_low = (index % 256);
+	index_high = ((index >> 8) % 256);
+
+	left = Tkip_Sbox_Lower[index_low] + (Tkip_Sbox_Upper[index_low] * 256);
+	right = Tkip_Sbox_Upper[index_high] + (Tkip_Sbox_Lower[index_high] * 256);
+
+	return (left ^ right);
+}
+
+UINT rotr1(UINT a)
+{
+	unsigned int b;
+
+	if ((a & 0x01) == 0x01)
+	{
+		b = (a >> 1) | 0x8000;
+	}
+	else
+	{
+		b = (a >> 1) & 0x7fff;
+	}
+	b = b % 65536;
+	return b;
+}
+
+VOID RTMPTkipMixKey(
+	UCHAR *key,
+	UCHAR *ta,
+	ULONG pnl, /* Least significant 16 bits of PN */
+	ULONG pnh, /* Most significant 32 bits of PN */
+	UCHAR *rc4key,
+	UINT *p1k)
+{
+
+	UINT tsc0;
+	UINT tsc1;
+	UINT tsc2;
+
+	UINT ppk0;
+	UINT ppk1;
+	UINT ppk2;
+	UINT ppk3;
+	UINT ppk4;
+	UINT ppk5;
+
+	INT i;
+	INT j;
+
+	tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
+	tsc1 = (unsigned int)(pnh % 65536);
+	tsc2 = (unsigned int)(pnl % 65536); /* lsb */
+
+	/* Phase 1, step 1 */
+	p1k[0] = tsc1;
+	p1k[1] = tsc0;
+	p1k[2] = (UINT)(ta[0] + (ta[1]*256));
+	p1k[3] = (UINT)(ta[2] + (ta[3]*256));
+	p1k[4] = (UINT)(ta[4] + (ta[5]*256));
+
+	/* Phase 1, step 2 */
+	for (i=0; i<8; i++)
+	{
+		j = 2*(i & 1);
+		p1k[0] = (p1k[0] + tkip_sbox( (p1k[4] ^ ((256*key[1+j]) + key[j])) % 65536 )) % 65536;
+		p1k[1] = (p1k[1] + tkip_sbox( (p1k[0] ^ ((256*key[5+j]) + key[4+j])) % 65536 )) % 65536;
+		p1k[2] = (p1k[2] + tkip_sbox( (p1k[1] ^ ((256*key[9+j]) + key[8+j])) % 65536 )) % 65536;
+		p1k[3] = (p1k[3] + tkip_sbox( (p1k[2] ^ ((256*key[13+j]) + key[12+j])) % 65536 )) % 65536;
+		p1k[4] = (p1k[4] + tkip_sbox( (p1k[3] ^ (((256*key[1+j]) + key[j]))) % 65536 )) % 65536;
+		p1k[4] = (p1k[4] + i) % 65536;
+	}
+
+	/* Phase 2, Step 1 */
+	ppk0 = p1k[0];
+	ppk1 = p1k[1];
+	ppk2 = p1k[2];
+	ppk3 = p1k[3];
+	ppk4 = p1k[4];
+	ppk5 = (p1k[4] + tsc2) % 65536;
+
+	/* Phase2, Step 2 */
+	ppk0 = ppk0 + tkip_sbox( (ppk5 ^ ((256*key[1]) + key[0])) % 65536);
+	ppk1 = ppk1 + tkip_sbox( (ppk0 ^ ((256*key[3]) + key[2])) % 65536);
+	ppk2 = ppk2 + tkip_sbox( (ppk1 ^ ((256*key[5]) + key[4])) % 65536);
+	ppk3 = ppk3 + tkip_sbox( (ppk2 ^ ((256*key[7]) + key[6])) % 65536);
+	ppk4 = ppk4 + tkip_sbox( (ppk3 ^ ((256*key[9]) + key[8])) % 65536);
+	ppk5 = ppk5 + tkip_sbox( (ppk4 ^ ((256*key[11]) + key[10])) % 65536);
+
+	ppk0 = ppk0 + rotr1(ppk5 ^ ((256*key[13]) + key[12]));
+	ppk1 = ppk1 + rotr1(ppk0 ^ ((256*key[15]) + key[14]));
+	ppk2 = ppk2 + rotr1(ppk1);
+	ppk3 = ppk3 + rotr1(ppk2);
+	ppk4 = ppk4 + rotr1(ppk3);
+	ppk5 = ppk5 + rotr1(ppk4);
+
+	/* Phase 2, Step 3 */
+    /* Phase 2, Step 3 */
+
+	tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
+	tsc1 = (unsigned int)(pnh % 65536);
+	tsc2 = (unsigned int)(pnl % 65536); /* lsb */
+
+	rc4key[0] = (tsc2 >> 8) % 256;
+	rc4key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f;
+	rc4key[2] = tsc2 % 256;
+	rc4key[3] = ((ppk5 ^ ((256*key[1]) + key[0])) >> 1) % 256;
+
+	rc4key[4] = ppk0 % 256;
+	rc4key[5] = (ppk0 >> 8) % 256;
+
+	rc4key[6] = ppk1 % 256;
+	rc4key[7] = (ppk1 >> 8) % 256;
+
+	rc4key[8] = ppk2 % 256;
+	rc4key[9] = (ppk2 >> 8) % 256;
+
+	rc4key[10] = ppk3 % 256;
+	rc4key[11] = (ppk3 >> 8) % 256;
+
+	rc4key[12] = ppk4 % 256;
+	rc4key[13] = (ppk4 >> 8) % 256;
+
+	rc4key[14] = ppk5 % 256;
+	rc4key[15] = (ppk5 >> 8) % 256;
+}
+
+
+/************************************************/
+/* construct_mic_header1()                      */
+/* Builds the first MIC header block from       */
+/* header fields.                               */
+/************************************************/
+
+void construct_mic_header1(
+	unsigned char *mic_header1,
+	int header_length,
+	unsigned char *mpdu)
+{
+	mic_header1[0] = (unsigned char)((header_length - 2) / 256);
+	mic_header1[1] = (unsigned char)((header_length - 2) % 256);
+	mic_header1[2] = mpdu[0] & 0xcf;    /* Mute CF poll & CF ack bits */
+	mic_header1[3] = mpdu[1] & 0xc7;    /* Mute retry, more data and pwr mgt bits */
+	mic_header1[4] = mpdu[4];       /* A1 */
+	mic_header1[5] = mpdu[5];
+	mic_header1[6] = mpdu[6];
+	mic_header1[7] = mpdu[7];
+	mic_header1[8] = mpdu[8];
+	mic_header1[9] = mpdu[9];
+	mic_header1[10] = mpdu[10];     /* A2 */
+	mic_header1[11] = mpdu[11];
+	mic_header1[12] = mpdu[12];
+	mic_header1[13] = mpdu[13];
+	mic_header1[14] = mpdu[14];
+	mic_header1[15] = mpdu[15];
+}
+
+/************************************************/
+/* construct_mic_header2()                      */
+/* Builds the last MIC header block from        */
+/* header fields.                               */
+/************************************************/
+
+void construct_mic_header2(
+	unsigned char *mic_header2,
+	unsigned char *mpdu,
+	int a4_exists,
+	int qc_exists)
+{
+	int i;
+
+	for (i = 0; i<16; i++) mic_header2[i]=0x00;
+
+	mic_header2[0] = mpdu[16];    /* A3 */
+	mic_header2[1] = mpdu[17];
+	mic_header2[2] = mpdu[18];
+	mic_header2[3] = mpdu[19];
+	mic_header2[4] = mpdu[20];
+	mic_header2[5] = mpdu[21];
+
+	// In Sequence Control field, mute sequence numer bits (12-bit)
+	mic_header2[6] = mpdu[22] & 0x0f;   /* SC */
+	mic_header2[7] = 0x00; /* mpdu[23]; */
+
+	if ((!qc_exists) & a4_exists)
+	{
+		for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i];   /* A4 */
+
+	}
+
+	if (qc_exists && (!a4_exists))
+	{
+		mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */
+		mic_header2[9] = mpdu[25] & 0x00;
+	}
+
+	if (qc_exists && a4_exists)
+	{
+		for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i];   /* A4 */
+
+		mic_header2[14] = mpdu[30] & 0x0f;
+		mic_header2[15] = mpdu[31] & 0x00;
+	}
+}
+
+
+/************************************************/
+/* construct_mic_iv()                           */
+/* Builds the MIC IV from header fields and PN  */
+/************************************************/
+
+void construct_mic_iv(
+	unsigned char *mic_iv,
+	int qc_exists,
+	int a4_exists,
+	unsigned char *mpdu,
+	unsigned int payload_length,
+	unsigned char *pn_vector)
+{
+	int i;
+
+	mic_iv[0] = 0x59;
+	if (qc_exists && a4_exists)
+		mic_iv[1] = mpdu[30] & 0x0f;    /* QoS_TC           */
+	if (qc_exists && !a4_exists)
+		mic_iv[1] = mpdu[24] & 0x0f;   /* mute bits 7-4    */
+	if (!qc_exists)
+		mic_iv[1] = 0x00;
+	for (i = 2; i < 8; i++)
+		mic_iv[i] = mpdu[i + 8];                    /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
+#ifdef CONSISTENT_PN_ORDER
+		for (i = 8; i < 14; i++)
+			mic_iv[i] = pn_vector[i - 8];           /* mic_iv[8:13] = PN[0:5] */
+#else
+		for (i = 8; i < 14; i++)
+			mic_iv[i] = pn_vector[13 - i];          /* mic_iv[8:13] = PN[5:0] */
+#endif
+	i = (payload_length / 256);
+	i = (payload_length % 256);
+	mic_iv[14] = (unsigned char) (payload_length / 256);
+	mic_iv[15] = (unsigned char) (payload_length % 256);
+
+}
+
+
+
+/************************************/
+/* bitwise_xor()                    */
+/* A 128 bit, bitwise exclusive or  */
+/************************************/
+
+void bitwise_xor(unsigned char *ina, unsigned char *inb, unsigned char *out)
+{
+	int i;
+	for (i=0; i<16; i++)
+	{
+		out[i] = ina[i] ^ inb[i];
+	}
+}
+
+
+void aes128k128d(unsigned char *key, unsigned char *data, unsigned char *ciphertext)
+{
+	int round;
+	int i;
+	unsigned char intermediatea[16];
+	unsigned char intermediateb[16];
+	unsigned char round_key[16];
+
+	for(i=0; i<16; i++) round_key[i] = key[i];
+
+	for (round = 0; round < 11; round++)
+	{
+		if (round == 0)
+		{
+			xor_128(round_key, data, ciphertext);
+			next_key(round_key, round);
+		}
+		else if (round == 10)
+		{
+			byte_sub(ciphertext, intermediatea);
+			shift_row(intermediatea, intermediateb);
+			xor_128(intermediateb, round_key, ciphertext);
+		}
+		else    /* 1 - 9 */
+		{
+			byte_sub(ciphertext, intermediatea);
+			shift_row(intermediatea, intermediateb);
+			mix_column(&intermediateb[0], &intermediatea[0]);
+			mix_column(&intermediateb[4], &intermediatea[4]);
+			mix_column(&intermediateb[8], &intermediatea[8]);
+			mix_column(&intermediateb[12], &intermediatea[12]);
+			xor_128(intermediatea, round_key, ciphertext);
+			next_key(round_key, round);
+		}
+	}
+
+}
+
+void construct_ctr_preload(
+	unsigned char *ctr_preload,
+	int a4_exists,
+	int qc_exists,
+	unsigned char *mpdu,
+	unsigned char *pn_vector,
+	int c)
+{
+
+	int i = 0;
+	for (i=0; i<16; i++) ctr_preload[i] = 0x00;
+	i = 0;
+
+	ctr_preload[0] = 0x01;                                  /* flag */
+	if (qc_exists && a4_exists) ctr_preload[1] = mpdu[30] & 0x0f;   /* QoC_Control  */
+	if (qc_exists && !a4_exists) ctr_preload[1] = mpdu[24] & 0x0f;
+
+	for (i = 2; i < 8; i++)
+		ctr_preload[i] = mpdu[i + 8];                       /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
+#ifdef CONSISTENT_PN_ORDER
+	  for (i = 8; i < 14; i++)
+			ctr_preload[i] =    pn_vector[i - 8];           /* ctr_preload[8:13] = PN[0:5] */
+#else
+	  for (i = 8; i < 14; i++)
+			ctr_preload[i] =    pn_vector[13 - i];          /* ctr_preload[8:13] = PN[5:0] */
+#endif
+	ctr_preload[14] =  (unsigned char) (c / 256); // Ctr
+	ctr_preload[15] =  (unsigned char) (c % 256);
+
+}
+
+
+//
+// TRUE: Success!
+// FALSE: Decrypt Error!
+//
+BOOLEAN RTMPSoftDecryptTKIP(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR	pData,
+	IN ULONG	DataByteCnt,
+	IN UCHAR    UserPriority,
+	IN PCIPHER_KEY	pWpaKey)
+{
+	UCHAR			KeyID;
+	UINT			HeaderLen;
+    UCHAR			fc0;
+	UCHAR			fc1;
+	USHORT			fc;
+	UINT			frame_type;
+	UINT			frame_subtype;
+    UINT			from_ds;
+    UINT			to_ds;
+	INT				a4_exists;
+	INT				qc_exists;
+	USHORT			duration;
+	USHORT			seq_control;
+	USHORT			qos_control;
+	UCHAR			TA[MAC_ADDR_LEN];
+	UCHAR			DA[MAC_ADDR_LEN];
+	UCHAR			SA[MAC_ADDR_LEN];
+	UCHAR			RC4Key[16];
+	UINT			p1k[5]; //for mix_key;
+	ULONG			pnl;/* Least significant 16 bits of PN */
+	ULONG			pnh;/* Most significant 32 bits of PN */
+	UINT			num_blocks;
+	UINT			payload_remainder;
+	ARCFOURCONTEXT 	ArcFourContext;
+	UINT			crc32 = 0;
+	UINT			trailfcs = 0;
+	UCHAR			MIC[8];
+	UCHAR			TrailMIC[8];
+
+#ifdef RT_BIG_ENDIAN
+	RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
+#endif
+
+	fc0 = *pData;
+	fc1 = *(pData + 1);
+
+	fc = *((PUSHORT)pData);
+
+	frame_type = ((fc0 >> 2) & 0x03);
+	frame_subtype = ((fc0 >> 4) & 0x0f);
+
+    from_ds = (fc1 & 0x2) >> 1;
+    to_ds = (fc1 & 0x1);
+
+    a4_exists = (from_ds & to_ds);
+    qc_exists = ((frame_subtype == 0x08) ||    /* Assumed QoS subtypes */
+                  (frame_subtype == 0x09) ||   /* Likely to change.    */
+                  (frame_subtype == 0x0a) ||
+                  (frame_subtype == 0x0b)
+                 );
+
+	HeaderLen = 24;
+	if (a4_exists)
+		HeaderLen += 6;
+
+	KeyID = *((PUCHAR)(pData+ HeaderLen + 3));
+	KeyID = KeyID >> 6;
+
+	if (pWpaKey[KeyID].KeyLen == 0)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP failed!(KeyID[%d] Length can not be 0)\n", KeyID));
+		return FALSE;
+	}
+
+	duration = *((PUSHORT)(pData+2));
+
+	seq_control = *((PUSHORT)(pData+22));
+
+	if (qc_exists)
+	{
+		if (a4_exists)
+		{
+			qos_control = *((PUSHORT)(pData+30));
+		}
+		else
+		{
+			qos_control = *((PUSHORT)(pData+24));
+		}
+	}
+
+	if (to_ds == 0 && from_ds == 1)
+	{
+		NdisMoveMemory(DA, pData+4, MAC_ADDR_LEN);
+		NdisMoveMemory(SA, pData+16, MAC_ADDR_LEN);
+		NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);  //BSSID
+	}
+	else if (to_ds == 0 && from_ds == 0 )
+	{
+		NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
+		NdisMoveMemory(DA, pData+4, MAC_ADDR_LEN);
+		NdisMoveMemory(SA, pData+10, MAC_ADDR_LEN);
+	}
+	else if (to_ds == 1 && from_ds == 0)
+	{
+		NdisMoveMemory(SA, pData+10, MAC_ADDR_LEN);
+		NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
+		NdisMoveMemory(DA, pData+16, MAC_ADDR_LEN);
+	}
+	else if (to_ds == 1 && from_ds == 1)
+	{
+		NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
+		NdisMoveMemory(DA, pData+16, MAC_ADDR_LEN);
+		NdisMoveMemory(SA, pData+22, MAC_ADDR_LEN);
+	}
+
+	num_blocks = (DataByteCnt - 16) / 16;
+	payload_remainder = (DataByteCnt - 16) % 16;
+
+	pnl = (*(pData + HeaderLen)) * 256 + *(pData + HeaderLen + 2);
+	pnh = *((PULONG)(pData + HeaderLen + 4));
+	pnh = cpu2le32(pnh);
+	RTMPTkipMixKey(pWpaKey[KeyID].Key, TA, pnl, pnh, RC4Key, p1k);
+
+	ARCFOUR_INIT(&ArcFourContext, RC4Key, 16);
+
+	ARCFOUR_DECRYPT(&ArcFourContext, pData + HeaderLen, pData + HeaderLen + 8, DataByteCnt - HeaderLen - 8);
+	NdisMoveMemory(&trailfcs, pData + DataByteCnt - 8 - 4, 4);
+	crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 4);  //Skip IV+EIV 8 bytes & Skip last 4 bytes(FCS).
+	crc32 ^= 0xffffffff;             /* complement */
+
+    if(crc32 != cpu2le32(trailfcs))
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP, WEP Data ICV Error !\n"));	 //ICV error.
+
+		return (FALSE);
+	}
+
+	NdisMoveMemory(TrailMIC, pData + DataByteCnt - 8 - 8 - 4, 8);
+	RTMPInitMICEngine(pAd, pWpaKey[KeyID].Key, DA, SA, UserPriority, pWpaKey[KeyID].RxMic);
+	RTMPTkipAppend(&pAd->PrivateInfo.Tx, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 12);
+	RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
+	NdisMoveMemory(MIC, pAd->PrivateInfo.Tx.MIC, 8);
+
+	if (!NdisEqualMemory(MIC, TrailMIC, 8))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptTKIP, WEP Data MIC Error !\n"));	 //MIC error.
+		//RTMPReportMicError(pAd, &pWpaKey[KeyID]);	// marked by AlbertY @ 20060630
+		return (FALSE);
+	}
+
+#ifdef RT_BIG_ENDIAN
+	RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
+#endif
+	//DBGPRINT(RT_DEBUG_TRACE, "RTMPSoftDecryptTKIP Decript done!!\n");
+	return TRUE;
+}
+
+
+
+
+BOOLEAN RTMPSoftDecryptAES(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR	pData,
+	IN ULONG	DataByteCnt,
+	IN PCIPHER_KEY	pWpaKey)
+{
+	UCHAR			KeyID;
+	UINT			HeaderLen;
+	UCHAR			PN[6];
+	UINT			payload_len;
+	UINT			num_blocks;
+	UINT			payload_remainder;
+	USHORT			fc;
+	UCHAR			fc0;
+	UCHAR			fc1;
+	UINT			frame_type;
+	UINT			frame_subtype;
+	UINT			from_ds;
+	UINT			to_ds;
+	INT				a4_exists;
+	INT				qc_exists;
+	UCHAR			aes_out[16];
+	int 			payload_index;
+	UINT 			i;
+	UCHAR 			ctr_preload[16];
+	UCHAR 			chain_buffer[16];
+	UCHAR 			padded_buffer[16];
+	UCHAR 			mic_iv[16];
+	UCHAR 			mic_header1[16];
+	UCHAR 			mic_header2[16];
+	UCHAR			MIC[8];
+	UCHAR			TrailMIC[8];
+
+#ifdef RT_BIG_ENDIAN
+	RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
+#endif
+
+	fc0 = *pData;
+	fc1 = *(pData + 1);
+
+	fc = *((PUSHORT)pData);
+
+	frame_type = ((fc0 >> 2) & 0x03);
+	frame_subtype = ((fc0 >> 4) & 0x0f);
+
+	from_ds = (fc1 & 0x2) >> 1;
+	to_ds = (fc1 & 0x1);
+
+	a4_exists = (from_ds & to_ds);
+	qc_exists = ((frame_subtype == 0x08) ||    /* Assumed QoS subtypes */
+				  (frame_subtype == 0x09) ||   /* Likely to change.    */
+				  (frame_subtype == 0x0a) ||
+				  (frame_subtype == 0x0b)
+				 );
+
+	HeaderLen = 24;
+	if (a4_exists)
+		HeaderLen += 6;
+
+	KeyID = *((PUCHAR)(pData+ HeaderLen + 3));
+	KeyID = KeyID >> 6;
+
+	if (pWpaKey[KeyID].KeyLen == 0)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptAES failed!(KeyID[%d] Length can not be 0)\n", KeyID));
+		return FALSE;
+	}
+
+	PN[0] = *(pData+ HeaderLen);
+	PN[1] = *(pData+ HeaderLen + 1);
+	PN[2] = *(pData+ HeaderLen + 4);
+	PN[3] = *(pData+ HeaderLen + 5);
+	PN[4] = *(pData+ HeaderLen + 6);
+	PN[5] = *(pData+ HeaderLen + 7);
+
+	payload_len = DataByteCnt - HeaderLen - 8 - 8;	// 8 bytes for CCMP header , 8 bytes for MIC
+	payload_remainder = (payload_len) % 16;
+	num_blocks = (payload_len) / 16;
+
+
+
+	// Find start of payload
+	payload_index = HeaderLen + 8; //IV+EIV
+
+	for (i=0; i< num_blocks; i++)
+	{
+		construct_ctr_preload(ctr_preload,
+								a4_exists,
+								qc_exists,
+								pData,
+								PN,
+								i+1 );
+
+		aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
+
+		bitwise_xor(aes_out, pData + payload_index, chain_buffer);
+		NdisMoveMemory(pData + payload_index - 8, chain_buffer, 16);
+		payload_index += 16;
+	}
+
+	//
+	// If there is a short final block, then pad it
+	// encrypt it and copy the unpadded part back
+	//
+	if (payload_remainder > 0)
+	{
+		construct_ctr_preload(ctr_preload,
+								a4_exists,
+								qc_exists,
+								pData,
+								PN,
+								num_blocks + 1);
+
+		NdisZeroMemory(padded_buffer, 16);
+		NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder);
+
+		aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
+
+		bitwise_xor(aes_out, padded_buffer, chain_buffer);
+		NdisMoveMemory(pData + payload_index - 8, chain_buffer, payload_remainder);
+		payload_index += payload_remainder;
+	}
+
+	//
+	// Descrypt the MIC
+	//
+	construct_ctr_preload(ctr_preload,
+							a4_exists,
+							qc_exists,
+							pData,
+							PN,
+							0);
+	NdisZeroMemory(padded_buffer, 16);
+	NdisMoveMemory(padded_buffer, pData + payload_index, 8);
+
+	aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
+
+	bitwise_xor(aes_out, padded_buffer, chain_buffer);
+
+	NdisMoveMemory(TrailMIC, chain_buffer, 8);
+
+	//
+	// Calculate MIC
+	//
+
+	//Force the protected frame bit on
+	*(pData + 1) = *(pData + 1) | 0x40;
+
+	// Find start of payload
+	// Because the CCMP header has been removed
+	payload_index = HeaderLen;
+
+	construct_mic_iv(
+					mic_iv,
+					qc_exists,
+					a4_exists,
+					pData,
+					payload_len,
+					PN);
+
+	construct_mic_header1(
+						mic_header1,
+						HeaderLen,
+						pData);
+
+	construct_mic_header2(
+						mic_header2,
+						pData,
+						a4_exists,
+						qc_exists);
+
+	aes128k128d(pWpaKey[KeyID].Key, mic_iv, aes_out);
+	bitwise_xor(aes_out, mic_header1, chain_buffer);
+	aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
+	bitwise_xor(aes_out, mic_header2, chain_buffer);
+	aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
+
+	// iterate through each 16 byte payload block
+	for (i = 0; i < num_blocks; i++)
+	{
+		bitwise_xor(aes_out, pData + payload_index, chain_buffer);
+		payload_index += 16;
+		aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
+	}
+
+	// Add on the final payload block if it needs padding
+	if (payload_remainder > 0)
+	{
+		NdisZeroMemory(padded_buffer, 16);
+		NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder);
+
+		bitwise_xor(aes_out, padded_buffer, chain_buffer);
+		aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
+	}
+
+	// aes_out contains padded mic, discard most significant
+	// 8 bytes to generate 64 bit MIC
+	for (i = 0 ; i < 8; i++) MIC[i] = aes_out[i];
+
+	if (!NdisEqualMemory(MIC, TrailMIC, 8))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptAES, MIC Error !\n"));	 //MIC error.
+		return FALSE;
+	}
+
+#ifdef RT_BIG_ENDIAN
+	RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
+#endif
+
+	return TRUE;
+}
+
+/****************************************/
+/* aes128k128d()                        */
+/* Performs a 128 bit AES encrypt with  */
+/* 128 bit data.                        */
+/****************************************/
+VOID xor_128(
+	IN  PUCHAR  a,
+	IN  PUCHAR  b,
+	OUT PUCHAR  out)
+{
+	INT i;
+
+	for (i=0;i<16; i++)
+	{
+		out[i] = a[i] ^ b[i];
+	}
+}
+
+VOID next_key(
+	IN  PUCHAR  key,
+	IN  INT     round)
+{
+	UCHAR       rcon;
+	UCHAR       sbox_key[4];
+	UCHAR       rcon_table[12] =
+	{
+		0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
+		0x1b, 0x36, 0x36, 0x36
+	};
+
+	sbox_key[0] = RTMPCkipSbox(key[13]);
+	sbox_key[1] = RTMPCkipSbox(key[14]);
+	sbox_key[2] = RTMPCkipSbox(key[15]);
+	sbox_key[3] = RTMPCkipSbox(key[12]);
+
+	rcon = rcon_table[round];
+
+	xor_32(&key[0], sbox_key, &key[0]);
+	key[0] = key[0] ^ rcon;
+
+	xor_32(&key[4], &key[0], &key[4]);
+	xor_32(&key[8], &key[4], &key[8]);
+	xor_32(&key[12], &key[8], &key[12]);
+}
+
+VOID xor_32(
+	IN  PUCHAR  a,
+	IN  PUCHAR  b,
+	OUT PUCHAR  out)
+{
+	INT i;
+
+	for (i=0;i<4; i++)
+	{
+		out[i] = a[i] ^ b[i];
+	}
+}
+
+VOID byte_sub(
+	IN  PUCHAR  in,
+	OUT PUCHAR  out)
+{
+	INT i;
+
+	for (i=0; i< 16; i++)
+	{
+		out[i] = RTMPCkipSbox(in[i]);
+	}
+}
+
+UCHAR RTMPCkipSbox(
+	IN  UCHAR   a)
+{
+	return SboxTable[(int)a];
+}
+
+VOID shift_row(
+	IN  PUCHAR  in,
+	OUT PUCHAR  out)
+{
+	out[0] =  in[0];
+	out[1] =  in[5];
+	out[2] =  in[10];
+	out[3] =  in[15];
+	out[4] =  in[4];
+	out[5] =  in[9];
+	out[6] =  in[14];
+	out[7] =  in[3];
+	out[8] =  in[8];
+	out[9] =  in[13];
+	out[10] = in[2];
+	out[11] = in[7];
+	out[12] = in[12];
+	out[13] = in[1];
+	out[14] = in[6];
+	out[15] = in[11];
+}
+
+VOID mix_column(
+	IN  PUCHAR  in,
+	OUT PUCHAR  out)
+{
+	INT         i;
+	UCHAR       add1b[4];
+	UCHAR       add1bf7[4];
+	UCHAR       rotl[4];
+	UCHAR       swap_halfs[4];
+	UCHAR       andf7[4];
+	UCHAR       rotr[4];
+	UCHAR       temp[4];
+	UCHAR       tempb[4];
+
+	for (i=0 ; i<4; i++)
+	{
+		if ((in[i] & 0x80)== 0x80)
+			add1b[i] = 0x1b;
+		else
+			add1b[i] = 0x00;
+	}
+
+	swap_halfs[0] = in[2];    /* Swap halfs */
+	swap_halfs[1] = in[3];
+	swap_halfs[2] = in[0];
+	swap_halfs[3] = in[1];
+
+	rotl[0] = in[3];        /* Rotate left 8 bits */
+	rotl[1] = in[0];
+	rotl[2] = in[1];
+	rotl[3] = in[2];
+
+	andf7[0] = in[0] & 0x7f;
+	andf7[1] = in[1] & 0x7f;
+	andf7[2] = in[2] & 0x7f;
+	andf7[3] = in[3] & 0x7f;
+
+	for (i = 3; i>0; i--)    /* logical shift left 1 bit */
+	{
+		andf7[i] = andf7[i] << 1;
+		if ((andf7[i-1] & 0x80) == 0x80)
+		{
+			andf7[i] = (andf7[i] | 0x01);
+		}
+	}
+	andf7[0] = andf7[0] << 1;
+	andf7[0] = andf7[0] & 0xfe;
+
+	xor_32(add1b, andf7, add1bf7);
+
+	xor_32(in, add1bf7, rotr);
+
+	temp[0] = rotr[0];         /* Rotate right 8 bits */
+	rotr[0] = rotr[1];
+	rotr[1] = rotr[2];
+	rotr[2] = rotr[3];
+	rotr[3] = temp[0];
+
+	xor_32(add1bf7, rotr, temp);
+	xor_32(swap_halfs, rotl,tempb);
+	xor_32(temp, tempb, out);
+}
+
diff --git a/drivers/staging/rt3070/common/rtmp_wep.c b/drivers/staging/rt3070/common/rtmp_wep.c
new file mode 100644
index 0000000..f5f0a3b
--- /dev/null
+++ b/drivers/staging/rt3070/common/rtmp_wep.c
@@ -0,0 +1,508 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	rtmp_wep.c
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	Paul Wu		10-28-02		Initial
+*/
+
+#include	"../rt_config.h"
+
+UINT FCSTAB_32[256] =
+{
+	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
+	0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+	0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+	0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+	0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+	0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+	0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
+	0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+	0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+	0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+	0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
+	0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+	0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
+	0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+	0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+	0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+	0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
+	0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+	0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
+	0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+	0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+	0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+	0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
+	0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+	0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+	0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+	0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+	0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+	0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
+	0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+	0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
+	0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+	0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+	0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+	0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+	0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+	0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
+	0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+	0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+	0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+	0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
+	0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+	0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
+	0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+	0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+	0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+	0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
+	0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+	0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
+	0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+	0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+	0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+	0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
+	0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+	0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+	0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+	0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+	0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+	0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
+	0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+	0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
+	0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+	0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+/*
+UCHAR   WEPKEY[] = {
+		//IV
+		0x00, 0x11, 0x22,
+		//WEP KEY
+		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
+	};
+ */
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Init WEP function.
+
+	Arguments:
+      pAd		Pointer to our adapter
+		pKey        Pointer to the WEP KEY
+		KeyId		   WEP Key ID
+		KeyLen      the length of WEP KEY
+		pDest       Pointer to the destination which Encryption data will store in.
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTMPInitWepEngine(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pKey,
+	IN	UCHAR			KeyId,
+	IN	UCHAR			KeyLen,
+	IN OUT	PUCHAR		pDest)
+{
+	UINT i;
+	UCHAR   WEPKEY[] = {
+		//IV
+		0x00, 0x11, 0x22,
+		//WEP KEY
+		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
+	};
+
+	pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32;   //Init crc32.
+
+#ifdef CONFIG_STA_SUPPORT
+    if (pAd->StaCfg.bCkipOn && (pAd->StaCfg.CkipFlag & 0x10) && (pAd->OpMode == OPMODE_STA))
+    {
+        ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, pKey, KeyLen);  //INIT SBOX, KEYLEN+3(IV)
+        NdisMoveMemory(pDest, pKey, 3);  //Append Init Vector
+    }
+    else
+#endif // CONFIG_STA_SUPPORT //
+    {
+		NdisMoveMemory(WEPKEY + 3, pKey, KeyLen);
+
+        for(i = 0; i < 3; i++)
+			WEPKEY[i] = RandomByte(pAd);   //Call mlme RandomByte() function.
+		ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, KeyLen + 3);  //INIT SBOX, KEYLEN+3(IV)
+
+		NdisMoveMemory(pDest, WEPKEY, 3);  //Append Init Vector
+    }
+	*(pDest+3) = (KeyId << 6);       //Append KEYID
+
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Encrypt transimitted data
+
+	Arguments:
+      pAd		Pointer to our adapter
+      pSrc        Pointer to the transimitted source data that will be encrypt
+      pDest       Pointer to the destination where entryption data will be store in.
+      Len			Indicate the length of the source data
+
+	Return Value:
+      None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTMPEncryptData(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pSrc,
+	IN	PUCHAR			pDest,
+	IN	UINT			Len)
+{
+	pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, pSrc, Len);
+	ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, pSrc, Len);
+}
+
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Decrypt received WEP data
+
+	Arguments:
+		pAdapter		Pointer to our adapter
+		pSrc        Pointer to the received data
+		Len         the length of the received data
+
+	Return Value:
+		TRUE        Decrypt WEP data success
+		FALSE       Decrypt WEP data failed
+
+	Note:
+
+	========================================================================
+*/
+BOOLEAN	RTMPSoftDecryptWEP(
+	IN PRTMP_ADAPTER 	pAd,
+	IN PUCHAR			pData,
+	IN ULONG			DataByteCnt,
+	IN PCIPHER_KEY		pGroupKey)
+{
+	UINT	trailfcs;
+	UINT    crc32;
+	UCHAR	KeyIdx;
+	UCHAR   WEPKEY[] = {
+		//IV
+		0x00, 0x11, 0x22,
+		//WEP KEY
+		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
+	};
+	UCHAR 	*pPayload = (UCHAR *)pData + LENGTH_802_11;
+	ULONG	payload_len = DataByteCnt - LENGTH_802_11;
+
+	NdisMoveMemory(WEPKEY, pPayload, 3);    //Get WEP IV
+
+	KeyIdx = (*(pPayload + 3) & 0xc0) >> 6;
+	if (pGroupKey[KeyIdx].KeyLen == 0)
+		return (FALSE);
+
+	NdisMoveMemory(WEPKEY + 3, pGroupKey[KeyIdx].Key, pGroupKey[KeyIdx].KeyLen);
+	ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, pGroupKey[KeyIdx].KeyLen + 3);
+	ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, pPayload, pPayload + 4, payload_len - 4);
+	NdisMoveMemory(&trailfcs, pPayload + payload_len - 8, 4);
+	crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pPayload, payload_len - 8);  //Skip last 4 bytes(FCS).
+	crc32 ^= 0xffffffff;             /* complement */
+
+    if(crc32 != cpu2le32(trailfcs))
+    {
+		DBGPRINT(RT_DEBUG_TRACE, ("! WEP Data CRC Error !\n"));	 //CRC error.
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		The Stream Cipher Encryption Algorithm "ARCFOUR" initialize
+
+	Arguments:
+	   Ctx         Pointer to ARCFOUR CONTEXT (SBOX)
+		pKey        Pointer to the WEP KEY
+		KeyLen      Indicate the length fo the WEP KEY
+
+	Return Value:
+	   None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+VOID	ARCFOUR_INIT(
+	IN	PARCFOURCONTEXT	Ctx,
+	IN	PUCHAR			pKey,
+	IN	UINT			KeyLen)
+{
+	UCHAR	t, u;
+	UINT	keyindex;
+	UINT	stateindex;
+	PUCHAR	state;
+	UINT	counter;
+
+	state = Ctx->STATE;
+	Ctx->X = 0;
+	Ctx->Y = 0;
+	for (counter = 0; counter < 256; counter++)
+		state[counter] = (UCHAR)counter;
+	keyindex = 0;
+	stateindex = 0;
+	for (counter = 0; counter < 256; counter++)
+	{
+		t = state[counter];
+		stateindex = (stateindex + pKey[keyindex] + t) & 0xff;
+		u = state[stateindex];
+		state[stateindex] = t;
+		state[counter] = u;
+		if (++keyindex >= KeyLen)
+			keyindex = 0;
+	}
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Get bytes from ARCFOUR CONTEXT (S-BOX)
+
+	Arguments:
+	   Ctx         Pointer to ARCFOUR CONTEXT (SBOX)
+
+	Return Value:
+	   UCHAR  - the value of the ARCFOUR CONTEXT (S-BOX)
+
+	Note:
+
+	========================================================================
+*/
+UCHAR	ARCFOUR_BYTE(
+	IN	PARCFOURCONTEXT		Ctx)
+{
+  UINT x;
+  UINT y;
+  UCHAR sx, sy;
+  PUCHAR state;
+
+  state = Ctx->STATE;
+  x = (Ctx->X + 1) & 0xff;
+  sx = state[x];
+  y = (sx + Ctx->Y) & 0xff;
+  sy = state[y];
+  Ctx->X = x;
+  Ctx->Y = y;
+  state[y] = sx;
+  state[x] = sy;
+
+  return(state[(sx + sy) & 0xff]);
+
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		The Stream Cipher Decryption Algorithm
+
+	Arguments:
+		Ctx         Pointer to ARCFOUR CONTEXT (SBOX)
+		pDest			Pointer to the Destination
+		pSrc        Pointer to the Source data
+		Len         Indicate the length of the Source data
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+VOID	ARCFOUR_DECRYPT(
+	IN	PARCFOURCONTEXT	Ctx,
+	IN	PUCHAR			pDest,
+	IN	PUCHAR			pSrc,
+	IN	UINT			Len)
+{
+	UINT i;
+
+	for (i = 0; i < Len; i++)
+		pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		The Stream Cipher Encryption Algorithm
+
+	Arguments:
+		Ctx         Pointer to ARCFOUR CONTEXT (SBOX)
+		pDest			Pointer to the Destination
+		pSrc        Pointer to the Source data
+		Len         Indicate the length of the Source dta
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+VOID	ARCFOUR_ENCRYPT(
+	IN	PARCFOURCONTEXT	Ctx,
+	IN	PUCHAR			pDest,
+	IN	PUCHAR			pSrc,
+	IN	UINT			Len)
+{
+	UINT i;
+
+	for (i = 0; i < Len; i++)
+		pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		The Stream Cipher Encryption Algorithm which conform to the special requirement to encrypt  GTK.
+
+	Arguments:
+		Ctx         Pointer to ARCFOUR CONTEXT (SBOX)
+		pDest			Pointer to the Destination
+		pSrc        Pointer to the Source data
+		Len         Indicate the length of the Source dta
+
+
+	========================================================================
+*/
+
+VOID	WPAARCFOUR_ENCRYPT(
+	IN	PARCFOURCONTEXT	Ctx,
+	IN	PUCHAR			pDest,
+	IN	PUCHAR			pSrc,
+	IN	UINT			Len)
+{
+	UINT i;
+        //discard first 256 bytes
+	for (i = 0; i < 256; i++)
+            ARCFOUR_BYTE(Ctx);
+
+	for (i = 0; i < Len; i++)
+		pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
+}
+
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Calculate a new FCS given the current FCS and the new data.
+
+	Arguments:
+		Fcs	      the original FCS value
+		Cp          pointer to the data which will be calculate the FCS
+		Len         the length of the data
+
+	Return Value:
+		UINT - FCS 32 bits
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+UINT	RTMP_CALC_FCS32(
+	IN	UINT	Fcs,
+	IN	PUCHAR	Cp,
+	IN	INT		Len)
+{
+	while (Len--)
+	   Fcs = (((Fcs) >> 8) ^ FCSTAB_32[((Fcs) ^ (*Cp++)) & 0xff]);
+
+	return (Fcs);
+}
+
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Get last FCS and encrypt it to the destination
+
+	Arguments:
+		pDest			Pointer to the Destination
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTMPSetICV(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR	pDest)
+{
+	pAd->PrivateInfo.FCSCRC32 ^= 0xffffffff;             /* complement */
+	pAd->PrivateInfo.FCSCRC32 = cpu2le32(pAd->PrivateInfo.FCSCRC32);
+
+	ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, (PUCHAR) &pAd->PrivateInfo.FCSCRC32, 4);
+}
+
diff --git a/drivers/staging/rt3070/common/rtusb_bulk.c b/drivers/staging/rt3070/common/rtusb_bulk.c
new file mode 100644
index 0000000..1a05703
--- /dev/null
+++ b/drivers/staging/rt3070/common/rtusb_bulk.c
@@ -0,0 +1,1382 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	rtusb_bulk.c
+
+	Abstract:
+
+	Revision History:
+	Who			When		What
+	--------	----------	----------------------------------------------
+	Name		Date		Modification logs
+	Paul Lin	06-25-2004	created
+
+*/
+
+#include	"../rt_config.h"
+// Match total 6 bulkout endpoint to corresponding queue.
+UCHAR	EpToQueue[6]={FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_MGMT};
+
+//static BOOLEAN SingleBulkOut = FALSE;
+
+void RTUSB_FILL_BULK_URB (struct urb *pUrb,
+	struct usb_device *pUsb_Dev,
+	unsigned int bulkpipe,
+	void *pTransferBuf,
+	int BufSize,
+	usb_complete_t Complete,
+	void *pContext)
+{
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+	usb_fill_bulk_urb(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, (usb_complete_t)Complete, pContext);
+#else
+	FILL_BULK_URB(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, Complete, pContext);
+#endif
+
+}
+
+VOID	RTUSBInitTxDesc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PTX_CONTEXT		pTxContext,
+	IN	UCHAR			BulkOutPipeId,
+	IN	usb_complete_t	Func)
+{
+	PURB				pUrb;
+	PUCHAR				pSrc = NULL;
+	POS_COOKIE			pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+	pUrb = pTxContext->pUrb;
+	ASSERT(pUrb);
+
+	// Store BulkOut PipeId
+	pTxContext->BulkOutPipeId = BulkOutPipeId;
+
+	if (pTxContext->bAggregatible)
+	{
+		pSrc = &pTxContext->TransferBuffer->Aggregation[2];
+	}
+	else
+	{
+		pSrc = (PUCHAR) pTxContext->TransferBuffer->field.WirelessPacket;
+	}
+
+
+	//Initialize a tx bulk urb
+	RTUSB_FILL_BULK_URB(pUrb,
+						pObj->pUsb_Dev,
+						usb_sndbulkpipe(pObj->pUsb_Dev, pAd->BulkOutEpAddr[BulkOutPipeId]),
+						pSrc,
+						pTxContext->BulkOutSize,
+						Func,
+						pTxContext);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+	if (pTxContext->bAggregatible)
+		pUrb->transfer_dma	= (pTxContext->data_dma + TX_BUFFER_NORMSIZE + 2);
+	else
+		pUrb->transfer_dma	= pTxContext->data_dma;
+
+	pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+#endif
+
+}
+
+VOID	RTUSBInitHTTxDesc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PHT_TX_CONTEXT	pTxContext,
+	IN	UCHAR			BulkOutPipeId,
+	IN	ULONG			BulkOutSize,
+	IN	usb_complete_t	Func)
+{
+	PURB				pUrb;
+	PUCHAR				pSrc = NULL;
+	POS_COOKIE			pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+	pUrb = pTxContext->pUrb;
+	ASSERT(pUrb);
+
+	// Store BulkOut PipeId
+	pTxContext->BulkOutPipeId = BulkOutPipeId;
+
+	pSrc = &pTxContext->TransferBuffer->field.WirelessPacket[pTxContext->NextBulkOutPosition];
+
+
+	//Initialize a tx bulk urb
+	RTUSB_FILL_BULK_URB(pUrb,
+						pObj->pUsb_Dev,
+						usb_sndbulkpipe(pObj->pUsb_Dev, pAd->BulkOutEpAddr[BulkOutPipeId]),
+						pSrc,
+						BulkOutSize,
+						Func,
+						pTxContext);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+	pUrb->transfer_dma	= (pTxContext->data_dma + pTxContext->NextBulkOutPosition);
+	pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+#endif
+
+}
+
+VOID	RTUSBInitRxDesc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PRX_CONTEXT		pRxContext)
+{
+	PURB				pUrb;
+	POS_COOKIE			pObj = (POS_COOKIE) pAd->OS_Cookie;
+	ULONG				RX_bulk_size;
+
+
+	pUrb = pRxContext->pUrb;
+	ASSERT(pUrb);
+
+	if ( pAd->BulkInMaxPacketSize == 64)
+		RX_bulk_size = 4096;
+	else
+		RX_bulk_size = MAX_RXBULK_SIZE;
+
+	//Initialize a rx bulk urb
+	RTUSB_FILL_BULK_URB(pUrb,
+						pObj->pUsb_Dev,
+						usb_rcvbulkpipe(pObj->pUsb_Dev, pAd->BulkInEpAddr),
+						&(pRxContext->TransferBuffer[pAd->NextRxBulkInPosition]),
+						RX_bulk_size - (pAd->NextRxBulkInPosition),
+						(usb_complete_t)RTUSBBulkRxComplete,
+						(void *)pRxContext);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+	pUrb->transfer_dma	= pRxContext->data_dma + pAd->NextRxBulkInPosition;
+	pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+#endif
+
+
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+	========================================================================
+*/
+
+#define BULK_OUT_LOCK(pLock, IrqFlags)	\
+		if(1 /*!(in_interrupt() & 0xffff0000)*/)	\
+			RTMP_IRQ_LOCK((pLock), IrqFlags);
+
+#define BULK_OUT_UNLOCK(pLock, IrqFlags)	\
+		if(1 /*!(in_interrupt() & 0xffff0000)*/)	\
+			RTMP_IRQ_UNLOCK((pLock), IrqFlags);
+
+
+VOID	RTUSBBulkOutDataPacket(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			BulkOutPipeId,
+	IN	UCHAR			Index)
+{
+
+	PHT_TX_CONTEXT	pHTTXContext;
+	PURB			pUrb;
+	int				ret = 0;
+	PTXINFO_STRUC	pTxInfo, pLastTxInfo = NULL;
+	PTXWI_STRUC             pTxWI;
+	ULONG			TmpBulkEndPos, ThisBulkSize;
+	unsigned long	IrqFlags = 0, IrqFlags2 = 0;
+	PUCHAR			pWirelessPkt, pAppendant;
+	BOOLEAN			bTxQLastRound = FALSE;
+	UCHAR			allzero[4]= {0x0,0x0,0x0,0x0};
+
+	BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+	if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
+	{
+		BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+		return;
+	}
+	pAd->BulkOutPending[BulkOutPipeId] = TRUE;
+
+	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
+		)
+	{
+		pAd->BulkOutPending[BulkOutPipeId] = FALSE;
+		BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+		return;
+	}
+	BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+
+	pHTTXContext = &(pAd->TxContext[BulkOutPipeId]);
+
+	BULK_OUT_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
+	if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)
+		|| ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition))
+	{
+		BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
+
+		BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+		pAd->BulkOutPending[BulkOutPipeId] = FALSE;
+
+		// Clear Data flag
+		RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
+		RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
+
+		BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+		return;
+	}
+
+	// Clear Data flag
+	RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
+	RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
+
+	//DBGPRINT(RT_DEBUG_TRACE,("BulkOut-B:I=0x%lx, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", in_interrupt(),
+	//							pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition,
+	//							pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
+	pHTTXContext->NextBulkOutPosition = pHTTXContext->ENextBulkOutPosition;
+	ThisBulkSize = 0;
+	TmpBulkEndPos = pHTTXContext->NextBulkOutPosition;
+	pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0];
+
+	if ((pHTTXContext->bCopySavePad == TRUE))
+	{
+		if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
+		{
+			DBGPRINT_RAW(RT_DEBUG_ERROR,("e1, allzero : %x  %x  %x  %x  %x  %x  %x  %x \n",
+				pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
+				,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
+		}
+		NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos], pHTTXContext->SavedPad, 8);
+		pHTTXContext->bCopySavePad = FALSE;
+		if (pAd->bForcePrintTX == TRUE)
+			DBGPRINT(RT_DEBUG_TRACE,("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld.   ENextBulk = %ld.\n",   pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition));
+	}
+
+	do
+	{
+		pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[TmpBulkEndPos];
+		pTxWI = (PTXWI_STRUC)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE];
+
+		if (pAd->bForcePrintTX == TRUE)
+			DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkOutDataPacket AMPDU = %d.\n",   pTxWI->AMPDU));
+
+		// add by Iverson, limit BulkOut size to 4k to pass WMM b mode 2T1R test items
+		//if ((ThisBulkSize != 0)  && (pTxWI->AMPDU == 0))
+		if ((ThisBulkSize != 0) && (pTxWI->PHYMODE == MODE_CCK))
+		{
+#ifdef INF_AMAZON_SE
+			/*Iverson Add for AMAZON USB (RT2070 &&  RT3070) to pass WMM A2-T4 ~ A2-T10*/
+			if(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
+			{
+				/*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate*/
+				if(pTxWI->PacketId == 6)
+                {
+                	pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+                	break;
+                }
+				else if (BulkOutPipeId == 1)
+				{
+					/*BK  No Limit BulkOut size .*/
+					pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+					break;
+				}
+				else if (((ThisBulkSize&0xffff8000) != 0) || (((ThisBulkSize&0x1000) == 0x1000) &&  (BulkOutPipeId == 0)  ))
+				{
+					/*BE  Limit BulkOut size to about 4k bytes.*/
+					pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+					break;
+				}
+				else if (((ThisBulkSize&0xffff8000) != 0) || (((ThisBulkSize&0x1c00) == 0x1c00) &&  (BulkOutPipeId == 2)  ))
+				{
+					/*VI Limit BulkOut size to about 7k bytes.*/
+					pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+					break;
+				}
+				else if (((ThisBulkSize&0xffff8000) != 0) || (((ThisBulkSize&0x2500) == 0x2500) &&  (BulkOutPipeId == 3)  ))
+				{
+					/*VO Limit BulkOut size to about 9k bytes.*/
+					pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+					break;
+				}
+			}
+			else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000))
+			{
+				/* Limit BulkOut size to about 4k bytes.*/
+				pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+				break;
+			}
+#else
+			if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000))
+			{
+				// Limit BulkOut size to about 4k bytes.
+				pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+				break;
+			}
+#endif // INF_AMAZON_SE //
+
+			else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0)  && (pTxWI->AMPDU == 0))*/)
+			{
+				// For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
+				// For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.
+				pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+				break;
+			}
+		}
+		// end Iverson
+		else
+		{
+#ifdef INF_AMAZON_SE
+//#ifdef DOT11_N_SUPPORT
+//			if(((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000) || ( (ThisBulkSize != 0)  && (pTxWI->AMPDU == 0)))
+//			{
+//				/* AMAZON_SE: BG mode Disable BulkOut Aggregate, N mode BulkOut Aggregaet size 24K */
+//				pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+//               break;
+//			}
+//			else
+//#endif // DOT11_N_SUPPORT //
+//			{
+				if(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && (pTxWI->AMPDU == 0))
+				{
+					if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0)) ||
+						(ThisBulkSize != 0))
+					{
+						/* AMAZON_SE: RT2070  Disable BulkOut Aggregate when WMM for USB issue */
+						pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+						break;
+					}
+				}
+/*
+				else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000))
+				{
+					// Limit BulkOut size to about 24k bytes.
+					pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+					break;
+				}
+			}
+*/
+#endif // INF_AMAZON_SE //
+
+			if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000))
+			{	// Limit BulkOut size to about 24k bytes.
+				pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+				break;
+			}
+
+			else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0)  && (pTxWI->AMPDU == 0))*/)
+			{	// For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
+				// For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.
+				pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+				break;
+			}
+		}
+
+		if (TmpBulkEndPos == pHTTXContext->CurWritePosition)
+		{
+			pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+			break;
+		}
+		//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+		if (pTxInfo->QSEL != FIFO_EDCA)
+		{
+			printk("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __FUNCTION__, pTxInfo->QSEL);
+			printk("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad);
+			hex_dump("Wrong QSel Pkt:", (PUCHAR)&pWirelessPkt[TmpBulkEndPos], (pHTTXContext->CurWritePosition - pHTTXContext->NextBulkOutPosition));
+		}
+		}
+#endif // CONFIG_STA_SUPPORT //
+
+		if (pTxInfo->USBDMATxPktLen <= 8)
+		{
+			BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
+			DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n",
+					pHTTXContext->BulkOutSize, pHTTXContext->bCopySavePad, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->CurWriteRealPos));
+			{
+				DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("%x  %x  %x  %x  %x  %x  %x  %x \n",
+					pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
+					,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
+			}
+			pAd->bForcePrintTX = TRUE;
+			BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+			pAd->BulkOutPending[BulkOutPipeId] = FALSE;
+			BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+			//DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen));
+			return;
+		}
+
+			// Increase Total transmit byte counter
+		pAd->RalinkCounters.OneSecTransmittedByteCount +=  pTxWI->MPDUtotalByteCount;
+		pAd->RalinkCounters.TransmittedByteCount +=  pTxWI->MPDUtotalByteCount;
+
+		pLastTxInfo = pTxInfo;
+
+		// Make sure we use EDCA QUEUE.
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		pTxInfo->QSEL = FIFO_EDCA; //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
+#endif // CONFIG_STA_SUPPORT //
+		ThisBulkSize += (pTxInfo->USBDMATxPktLen+4);
+		TmpBulkEndPos += (pTxInfo->USBDMATxPktLen+4);
+
+		if (TmpBulkEndPos != pHTTXContext->CurWritePosition)
+			pTxInfo->USBDMANextVLD = 1;
+
+		if (pTxInfo->SwUseLastRound == 1)
+		{
+			if (pHTTXContext->CurWritePosition == 8)
+				pTxInfo->USBDMANextVLD = 0;
+			pTxInfo->SwUseLastRound = 0;
+
+			bTxQLastRound = TRUE;
+			pHTTXContext->ENextBulkOutPosition = 8;
+
+	#ifdef RT_BIG_ENDIAN
+			RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
+			RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
+	#endif // RT_BIG_ENDIAN //
+
+			break;
+		}
+
+#ifdef RT_BIG_ENDIAN
+		RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
+		RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
+#endif // RT_BIG_ENDIAN //
+
+	}while (TRUE);
+
+	// adjust the pTxInfo->USBDMANextVLD value of last pTxInfo.
+	if (pLastTxInfo)
+	{
+#ifdef RT_BIG_ENDIAN
+		RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO);
+#endif // RT_BIG_ENDIAN //
+		pLastTxInfo->USBDMANextVLD = 0;
+#ifdef RT_BIG_ENDIAN
+		RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO);
+#endif // RT_BIG_ENDIAN //
+	}
+
+	/*
+		We need to copy SavedPad when following condition matched!
+			1. Not the last round of the TxQueue and
+			2. any match of following cases:
+				(1). The End Position of this bulk out is reach to the Currenct Write position and
+						the TxInfo and related header already write to the CurWritePosition.
+			   		=>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition)
+
+				(2). The EndPosition of the bulk out is not reach to the Current Write Position.
+					=>(ENextBulkOutPosition != CurWritePosition)
+	*/
+	if ((bTxQLastRound == FALSE) &&
+		 (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) && (pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition)) ||
+		  (pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition))
+		)
+	{
+		NdisMoveMemory(pHTTXContext->SavedPad, &pWirelessPkt[pHTTXContext->ENextBulkOutPosition], 8);
+		pHTTXContext->bCopySavePad = TRUE;
+		if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
+		{
+			PUCHAR	pBuf = &pHTTXContext->SavedPad[0];
+			DBGPRINT_RAW(RT_DEBUG_ERROR,("WARNING-Zero-3:%02x%02x%02x%02x%02x%02x%02x%02x,CWPos=%ld, CWRPos=%ld, bCW=%d, NBPos=%ld, TBPos=%ld, TBSize=%ld\n",
+				pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7], pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos,
+				pHTTXContext->bCurWriting, pHTTXContext->NextBulkOutPosition, TmpBulkEndPos, ThisBulkSize));
+
+			pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition];
+			DBGPRINT_RAW(RT_DEBUG_ERROR,("\tCWPos=%02x%02x%02x%02x%02x%02x%02x%02x\n", pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7]));
+		}
+		//DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad));
+	}
+
+	if (pAd->bForcePrintTX == TRUE)
+		DBGPRINT(RT_DEBUG_TRACE,("BulkOut-A:Size=%ld, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
+	//DBGPRINT(RT_DEBUG_LOUD,("BulkOut-A:Size=%ld, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, bLRound=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, bTxQLastRound));
+
+		// USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize.
+	pAppendant = &pWirelessPkt[TmpBulkEndPos];
+	NdisZeroMemory(pAppendant, 8);
+		ThisBulkSize += 4;
+		pHTTXContext->LastOne = TRUE;
+		if ((ThisBulkSize % pAd->BulkOutMaxPacketSize) == 0)
+			ThisBulkSize += 4;
+	pHTTXContext->BulkOutSize = ThisBulkSize;
+
+	pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1;
+	BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
+
+	// Init Tx context descriptor
+	RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete);
+
+	pUrb = pHTTXContext->pUrb;
+	if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
+
+		BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+		pAd->BulkOutPending[BulkOutPipeId] = FALSE;
+		pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
+		BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+		return;
+	}
+
+	BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+	pHTTXContext->IRPPending = TRUE;
+	BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+	pAd->BulkOutReq++;
+
+}
+
+
+VOID RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
+{
+	PHT_TX_CONTEXT	pHTTXContext;
+	PRTMP_ADAPTER	pAd;
+	POS_COOKIE 		pObj;
+	UCHAR			BulkOutPipeId;
+
+
+	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
+	pAd 			= pHTTXContext->pAd;
+	pObj 			= (POS_COOKIE) pAd->OS_Cookie;
+
+	// Store BulkOut PipeId
+	BulkOutPipeId	= pHTTXContext->BulkOutPipeId;
+	pAd->BulkOutDataOneSecCount++;
+
+	switch (BulkOutPipeId)
+	{
+		case 0:
+				pObj->ac0_dma_done_task.data = (unsigned long)pUrb;
+				tasklet_hi_schedule(&pObj->ac0_dma_done_task);
+				break;
+		case 1:
+				pObj->ac1_dma_done_task.data = (unsigned long)pUrb;
+				tasklet_hi_schedule(&pObj->ac1_dma_done_task);
+				break;
+		case 2:
+				pObj->ac2_dma_done_task.data = (unsigned long)pUrb;
+				tasklet_hi_schedule(&pObj->ac2_dma_done_task);
+				break;
+		case 3:
+				pObj->ac3_dma_done_task.data = (unsigned long)pUrb;
+				tasklet_hi_schedule(&pObj->ac3_dma_done_task);
+				break;
+		case 4:
+				pObj->hcca_dma_done_task.data = (unsigned long)pUrb;
+				tasklet_hi_schedule(&pObj->hcca_dma_done_task);
+				break;
+	}
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note: NULL frame use BulkOutPipeId = 0
+
+	========================================================================
+*/
+VOID	RTUSBBulkOutNullFrame(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	PTX_CONTEXT		pNullContext = &(pAd->NullContext);
+	PURB			pUrb;
+	int				ret = 0;
+	unsigned long	IrqFlags;
+
+	RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
+	if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
+	{
+		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
+		return;
+	}
+	pAd->BulkOutPending[0] = TRUE;
+	pAd->watchDogTxPendingCnt[0] = 1;
+	pNullContext->IRPPending = TRUE;
+	RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
+
+	// Increase Total transmit byte counter
+	pAd->RalinkCounters.TransmittedByteCount +=  pNullContext->BulkOutSize;
+
+
+	// Clear Null frame bulk flag
+	RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
+
+#ifdef RT_BIG_ENDIAN
+	RTMPDescriptorEndianChange((PUCHAR)pNullContext->TransferBuffer, TYPE_TXINFO);
+#endif // RT_BIG_ENDIAN //
+
+	// Init Tx context descriptor
+	RTUSBInitTxDesc(pAd, pNullContext, 0, (usb_complete_t)RTUSBBulkOutNullFrameComplete);
+
+	pUrb = pNullContext->pUrb;
+	if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
+	{
+		RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
+		pAd->BulkOutPending[0] = FALSE;
+		pAd->watchDogTxPendingCnt[0] = 0;
+		pNullContext->IRPPending = FALSE;
+		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
+
+		DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n", ret));
+		return;
+	}
+
+}
+
+// NULL frame use BulkOutPipeId = 0
+VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs)
+{
+	PRTMP_ADAPTER		pAd;
+	PTX_CONTEXT			pNullContext;
+	NTSTATUS			Status;
+	POS_COOKIE			pObj;
+
+
+	pNullContext	= (PTX_CONTEXT)pUrb->context;
+	pAd 			= pNullContext->pAd;
+	Status 			= pUrb->status;
+
+	pObj = (POS_COOKIE) pAd->OS_Cookie;
+	pObj->null_frame_complete_task.data = (unsigned long)pUrb;
+	tasklet_hi_schedule(&pObj->null_frame_complete_task);
+
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note: MLME use BulkOutPipeId = 0
+
+	========================================================================
+*/
+VOID	RTUSBBulkOutMLMEPacket(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			Index)
+{
+	PTX_CONTEXT		pMLMEContext;
+	PURB			pUrb;
+	int				ret = 0;
+	unsigned long	IrqFlags;
+
+	pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa;
+	pUrb = pMLMEContext->pUrb;
+
+	if ((pAd->MgmtRing.TxSwFreeIdx >= MGMT_RING_SIZE) ||
+		(pMLMEContext->InUse == FALSE) ||
+		(pMLMEContext->bWaitingBulkOut == FALSE))
+	{
+
+
+		// Clear MLME bulk flag
+		RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
+
+		return;
+	}
+
+
+	RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
+	if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
+	{
+		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
+		return;
+	}
+
+	pAd->BulkOutPending[MGMTPIPEIDX] = TRUE;
+	pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 1;
+	pMLMEContext->IRPPending = TRUE;
+	pMLMEContext->bWaitingBulkOut = FALSE;
+	RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
+
+	// Increase Total transmit byte counter
+	pAd->RalinkCounters.TransmittedByteCount +=  pMLMEContext->BulkOutSize;
+
+	// Clear MLME bulk flag
+	RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
+
+#ifdef RT_BIG_ENDIAN
+	RTMPDescriptorEndianChange((PUCHAR)pMLMEContext->TransferBuffer, TYPE_TXINFO);
+#endif // RT_BIG_ENDIAN //
+
+	// Init Tx context descriptor
+	RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutMLMEPacketComplete);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+	//For mgmt urb buffer, because we use sk_buff, so we need to notify the USB controller do dma mapping.
+	pUrb->transfer_dma	= 0;
+	pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP);
+#endif
+
+	pUrb = pMLMEContext->pUrb;
+	if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n", ret));
+		RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
+		pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
+		pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0;
+		pMLMEContext->IRPPending = FALSE;
+		pMLMEContext->bWaitingBulkOut = TRUE;
+		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
+
+		return;
+	}
+
+	//DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacket \n"));
+//	printk("<---RTUSBBulkOutMLMEPacket,Cpu=%d!, Dma=%d, SwIdx=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
+}
+
+
+VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
+{
+	PTX_CONTEXT			pMLMEContext;
+	PRTMP_ADAPTER		pAd;
+	NTSTATUS			Status;
+	POS_COOKIE 			pObj;
+	int					index;
+
+	//DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n"));
+	pMLMEContext	= (PTX_CONTEXT)pUrb->context;
+	pAd 			= pMLMEContext->pAd;
+	pObj 			= (POS_COOKIE)pAd->OS_Cookie;
+	Status			= pUrb->status;
+	index 			= pMLMEContext->SelfIdx;
+
+	pObj->mgmt_dma_done_task.data = (unsigned long)pUrb;
+	tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note: PsPoll use BulkOutPipeId = 0
+
+	========================================================================
+*/
+VOID	RTUSBBulkOutPsPoll(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	PTX_CONTEXT		pPsPollContext = &(pAd->PsPollContext);
+	PURB			pUrb;
+	int				ret = 0;
+	unsigned long	IrqFlags;
+
+	RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
+	if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
+	{
+		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
+		return;
+	}
+	pAd->BulkOutPending[0] = TRUE;
+	pAd->watchDogTxPendingCnt[0] = 1;
+	pPsPollContext->IRPPending = TRUE;
+	RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
+
+
+	// Clear PS-Poll bulk flag
+	RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);
+
+#ifdef RT_BIG_ENDIAN
+	RTMPDescriptorEndianChange((PUCHAR)pPsPollContext->TransferBuffer, TYPE_TXINFO);
+#endif // RT_BIG_ENDIAN //
+
+	// Init Tx context descriptor
+	RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutPsPollComplete);
+
+	pUrb = pPsPollContext->pUrb;
+	if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
+	{
+		RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
+		pAd->BulkOutPending[0] = FALSE;
+		pAd->watchDogTxPendingCnt[0] = 0;
+		pPsPollContext->IRPPending = FALSE;
+		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
+
+		DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n", ret));
+		return;
+	}
+
+}
+
+// PS-Poll frame use BulkOutPipeId = 0
+VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb,struct pt_regs *pt_regs)
+{
+	PRTMP_ADAPTER		pAd;
+	PTX_CONTEXT			pPsPollContext;
+	NTSTATUS			Status;
+	POS_COOKIE			pObj;
+
+
+	pPsPollContext= (PTX_CONTEXT)pUrb->context;
+	pAd = pPsPollContext->pAd;
+	Status = pUrb->status;
+	pObj = (POS_COOKIE) pAd->OS_Cookie;
+	pObj->pspoll_frame_complete_task.data = (unsigned long)pUrb;
+	tasklet_hi_schedule(&pObj->pspoll_frame_complete_task);
+
+}
+
+VOID DoBulkIn(IN RTMP_ADAPTER *pAd)
+{
+	PRX_CONTEXT		pRxContext;
+	PURB			pUrb;
+	int				ret = 0;
+	unsigned long	IrqFlags;
+
+	RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
+	pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
+	if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
+	{
+		RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+		return;
+	}
+	pRxContext->InUse = TRUE;
+	pRxContext->IRPPending = TRUE;
+	pAd->PendingRx++;
+	pAd->BulkInReq++;
+	RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+
+	// Init Rx context descriptor
+	NdisZeroMemory(pRxContext->TransferBuffer, pRxContext->BulkInOffset);
+	RTUSBInitRxDesc(pAd, pRxContext);
+
+	pUrb = pRxContext->pUrb;
+	if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
+	{	// fail
+
+		RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
+		pRxContext->InUse = FALSE;
+		pRxContext->IRPPending = FALSE;
+		pAd->PendingRx--;
+		pAd->BulkInReq--;
+		RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+		DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret));
+	}
+	else
+	{	// success
+		ASSERT((pRxContext->InUse == pRxContext->IRPPending));
+		//printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex);
+	}
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+	USB_RxPacket initializes a URB and uses the Rx IRP to submit it
+	to USB. It checks if an Rx Descriptor is available and passes the
+	the coresponding buffer to be filled. If no descriptor is available
+	fails the request. When setting the completion routine we pass our
+	Adapter Object as Context.
+
+	Arguments:
+
+	Return Value:
+		TRUE			found matched tuple cache
+		FALSE			no matched found
+
+	Note:
+
+	========================================================================
+*/
+#define fRTMP_ADAPTER_NEED_STOP_RX		\
+		(fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS |	\
+		 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
+		 fRTMP_ADAPTER_REMOVE_IN_PROGRESS | fRTMP_ADAPTER_BULKIN_RESET)
+
+#define fRTMP_ADAPTER_NEED_STOP_HANDLE_RX	\
+		(fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS |	\
+		 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
+		 fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
+
+VOID	RTUSBBulkReceive(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	PRX_CONTEXT		pRxContext;
+	unsigned long	IrqFlags;
+
+
+	/* sanity check */
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_HANDLE_RX))
+		return;
+
+	while(1)
+	{
+
+		RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
+		pRxContext = &(pAd->RxContext[pAd->NextRxBulkInReadIndex]);
+		if (((pRxContext->InUse == FALSE) && (pRxContext->Readable == TRUE)) &&
+			(pRxContext->bRxHandling == FALSE))
+		{
+			pRxContext->bRxHandling = TRUE;
+			RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+
+			// read RxContext, Since not
+#ifdef CONFIG_STA_SUPPORT
+			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+				STARxDoneInterruptHandle(pAd, TRUE);
+#endif // CONFIG_STA_SUPPORT //
+
+			// Finish to handle this bulkIn buffer.
+			RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
+			pRxContext->BulkInOffset = 0;
+			pRxContext->Readable = FALSE;
+			pRxContext->bRxHandling = FALSE;
+			pAd->ReadPosition = 0;
+			pAd->TransferBufferLength = 0;
+			INC_RING_INDEX(pAd->NextRxBulkInReadIndex, RX_RING_SIZE);
+			RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+
+		}
+		else
+		{
+			RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+			break;
+		}
+	}
+
+	if (!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_RX)))
+		DoBulkIn(pAd);
+
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		This routine process Rx Irp and call rx complete function.
+
+	Arguments:
+		DeviceObject	Pointer to the device object for next lower
+						device. DeviceObject passed in here belongs to
+						the next lower driver in the stack because we
+						were invoked via IoCallDriver in USB_RxPacket
+						AND it is not OUR device object
+	  Irp				Ptr to completed IRP
+	  Context			Ptr to our Adapter object (context specified
+						in IoSetCompletionRoutine
+
+	Return Value:
+		Always returns STATUS_MORE_PROCESSING_REQUIRED
+
+	Note:
+		Always returns STATUS_MORE_PROCESSING_REQUIRED
+	========================================================================
+*/
+VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs)
+{
+	// use a receive tasklet to handle received packets;
+	// or sometimes hardware IRQ will be disabled here, so we can not
+	// use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :<
+	PRX_CONTEXT		pRxContext;
+	PRTMP_ADAPTER	pAd;
+	POS_COOKIE 		pObj;
+
+
+	pRxContext	= (PRX_CONTEXT)pUrb->context;
+	pAd 		= pRxContext->pAd;
+	pObj 		= (POS_COOKIE) pAd->OS_Cookie;
+
+	pObj->rx_done_task.data = (unsigned long)pUrb;
+	tasklet_hi_schedule(&pObj->rx_done_task);
+
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTUSBKickBulkOut(
+	IN	PRTMP_ADAPTER pAd)
+{
+	// BulkIn Reset will reset whole USB PHY. So we need to make sure fRTMP_ADAPTER_BULKIN_RESET not flaged.
+	if (!RTMP_TEST_FLAG(pAd ,fRTMP_ADAPTER_NEED_STOP_TX)
+#ifdef RALINK_ATE
+		&& !(ATE_ON(pAd))
+#endif // RALINK_ATE //
+		)
+	{
+		// 2. PS-Poll frame is next
+		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL))
+		{
+			RTUSBBulkOutPsPoll(pAd);
+		}
+
+		// 5. Mlme frame is next
+		else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) &&
+				 (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE))
+		{
+			RTUSBBulkOutMLMEPacket(pAd, pAd->MgmtRing.TxDmaIdx);
+		}
+
+		// 6. Data frame normal is next
+		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL))
+		{
+			if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
+				(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+				))
+			{
+				RTUSBBulkOutDataPacket(pAd, 0, pAd->NextBulkOutIndex[0]);
+			}
+		}
+		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2))
+		{
+			if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
+				(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+				))
+			{
+				RTUSBBulkOutDataPacket(pAd, 1, pAd->NextBulkOutIndex[1]);
+			}
+		}
+		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3))
+		{
+			if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
+				(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+				))
+			{
+				RTUSBBulkOutDataPacket(pAd, 2, pAd->NextBulkOutIndex[2]);
+			}
+		}
+		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4))
+		{
+			if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
+				(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+				))
+			{
+				RTUSBBulkOutDataPacket(pAd, 3, pAd->NextBulkOutIndex[3]);
+			}
+		}
+		//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
+		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_5))
+		{
+			if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
+				(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+				))
+			{
+			}
+		}
+
+		// 7. Null frame is the last
+		else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL))
+		{
+			if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+			{
+				RTUSBBulkOutNullFrame(pAd);
+			}
+		}
+
+		// 8. No data avaliable
+		else
+		{
+
+		}
+	}
+#ifdef RALINK_ATE
+	/* If the mode is in ATE mode. */
+	else if((ATE_ON(pAd)) &&
+		!RTMP_TEST_FLAG(pAd ,fRTMP_ADAPTER_NEED_STOP_TX))// PETER : watch out !
+	{
+		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE))
+		{
+			ATE_RTUSBBulkOutDataPacket(pAd, 0);
+		}
+	}
+#endif // RALINK_ATE //
+
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+	Call from Reset action after BulkOut failed.
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTUSBCleanUpDataBulkOutQueue(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	UCHAR			Idx;
+	PHT_TX_CONTEXT	pTxContext;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpDataBulkOutQueue\n"));
+
+	for (Idx = 0; Idx < 4; Idx++)
+	{
+		pTxContext = &pAd->TxContext[Idx];
+
+		pTxContext->CurWritePosition = pTxContext->NextBulkOutPosition;
+		pTxContext->LastOne = FALSE;
+		NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
+		pAd->BulkOutPending[Idx] = FALSE;
+		NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpDataBulkOutQueue\n"));
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTUSBCleanUpMLMEBulkOutQueue(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpMLMEBulkOutQueue\n"));
+	DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpMLMEBulkOutQueue\n"));
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTUSBCancelPendingIRPs(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	RTUSBCancelPendingBulkInIRP(pAd);
+	RTUSBCancelPendingBulkOutIRP(pAd);
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTUSBCancelPendingBulkInIRP(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	PRX_CONTEXT		pRxContext;
+	UINT			i;
+
+	DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->RTUSBCancelPendingBulkInIRP\n"));
+	for ( i = 0; i < (RX_RING_SIZE); i++)
+	{
+		pRxContext = &(pAd->RxContext[i]);
+		if(pRxContext->IRPPending == TRUE)
+		{
+			RTUSB_UNLINK_URB(pRxContext->pUrb);
+			pRxContext->IRPPending = FALSE;
+			pRxContext->InUse = FALSE;
+			//NdisInterlockedDecrement(&pAd->PendingRx);
+			//pAd->PendingRx--;
+		}
+	}
+	DBGPRINT_RAW(RT_DEBUG_TRACE, ("<---RTUSBCancelPendingBulkInIRP\n"));
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTUSBCancelPendingBulkOutIRP(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	PHT_TX_CONTEXT		pHTTXContext;
+	PTX_CONTEXT			pMLMEContext;
+	PTX_CONTEXT			pBeaconContext;
+	PTX_CONTEXT			pNullContext;
+	PTX_CONTEXT			pPsPollContext;
+	PTX_CONTEXT			pRTSContext;
+	UINT				i, Idx;
+//	unsigned int 		IrqFlags;
+//	NDIS_SPIN_LOCK		*pLock;
+//	BOOLEAN				*pPending;
+
+
+//	pLock = &pAd->BulkOutLock[MGMTPIPEIDX];
+//	pPending = &pAd->BulkOutPending[MGMTPIPEIDX];
+
+	for (Idx = 0; Idx < 4; Idx++)
+	{
+		pHTTXContext = &(pAd->TxContext[Idx]);
+
+		if (pHTTXContext->IRPPending == TRUE)
+		{
+
+			// Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
+			// remove it from the HeadPendingSendList and NULL out HeadPendingSendList
+			//	when the last IRP on the list has been	cancelled; that's how we exit this loop
+			//
+
+			RTUSB_UNLINK_URB(pHTTXContext->pUrb);
+
+			// Sleep 200 microseconds to give cancellation time to work
+			RTMPusecDelay(200);
+		}
+
+#ifdef RALINK_ATE
+		pHTTXContext->bCopySavePad = 0;
+		pHTTXContext->CurWritePosition = 0;
+		pHTTXContext->CurWriteRealPos = 0;
+		pHTTXContext->bCurWriting = FALSE;
+		pHTTXContext->NextBulkOutPosition = 0;
+		pHTTXContext->ENextBulkOutPosition = 0;
+#endif // RALINK_ATE //
+		pAd->BulkOutPending[Idx] = FALSE;
+	}
+
+	//RTMP_IRQ_LOCK(pLock, IrqFlags);
+	for (i = 0; i < MGMT_RING_SIZE; i++)
+	{
+		pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
+		if(pMLMEContext && (pMLMEContext->IRPPending == TRUE))
+		{
+
+			// Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
+			// remove it from the HeadPendingSendList and NULL out HeadPendingSendList
+			//	when the last IRP on the list has been	cancelled; that's how we exit this loop
+			//
+
+			RTUSB_UNLINK_URB(pMLMEContext->pUrb);
+			pMLMEContext->IRPPending = FALSE;
+
+			// Sleep 200 microsecs to give cancellation time to work
+			RTMPusecDelay(200);
+		}
+	}
+	pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
+	//RTMP_IRQ_UNLOCK(pLock, IrqFlags);
+
+
+	for (i = 0; i < BEACON_RING_SIZE; i++)
+	{
+		pBeaconContext = &(pAd->BeaconContext[i]);
+
+		if(pBeaconContext->IRPPending == TRUE)
+		{
+
+			// Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
+			// remove it from the HeadPendingSendList and NULL out HeadPendingSendList
+			//	when the last IRP on the list has been	cancelled; that's how we exit this loop
+			//
+
+			RTUSB_UNLINK_URB(pBeaconContext->pUrb);
+
+			// Sleep 200 microsecs to give cancellation time to work
+			RTMPusecDelay(200);
+		}
+	}
+
+	pNullContext = &(pAd->NullContext);
+	if (pNullContext->IRPPending == TRUE)
+		RTUSB_UNLINK_URB(pNullContext->pUrb);
+
+	pRTSContext = &(pAd->RTSContext);
+	if (pRTSContext->IRPPending == TRUE)
+		RTUSB_UNLINK_URB(pRTSContext->pUrb);
+
+	pPsPollContext = &(pAd->PsPollContext);
+	if (pPsPollContext->IRPPending == TRUE)
+		RTUSB_UNLINK_URB(pPsPollContext->pUrb);
+
+	for (Idx = 0; Idx < 4; Idx++)
+	{
+		NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
+		pAd->BulkOutPending[Idx] = FALSE;
+		NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
+	}
+}
+
diff --git a/drivers/staging/rt3070/common/rtusb_data.c b/drivers/staging/rt3070/common/rtusb_data.c
new file mode 100644
index 0000000..521309a
--- /dev/null
+++ b/drivers/staging/rt3070/common/rtusb_data.c
@@ -0,0 +1,218 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	rtusb_data.c
+
+	Abstract:
+	Ralink USB driver Tx/Rx functions.
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+	Jan            03-25-2006    created
+
+*/
+#include	"../rt_config.h"
+
+extern  UCHAR Phy11BGNextRateUpward[]; // defined in mlme.c
+extern UCHAR	EpToQueue[];
+
+
+VOID REPORT_AMSDU_FRAMES_TO_LLC(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pData,
+	IN	ULONG			DataSize)
+{
+	PNDIS_PACKET	pPacket;
+	UINT			nMSDU;
+	struct			sk_buff *pSkb;
+
+	nMSDU = 0;
+	/* allocate a rx packet */
+	pSkb = dev_alloc_skb(RX_BUFFER_AGGRESIZE);
+	pPacket = (PNDIS_PACKET)OSPKT_TO_RTPKT(pSkb);
+	if (pSkb)
+	{
+
+		/* convert 802.11 to 802.3 packet */
+		pSkb->dev = get_netdev_from_bssid(pAd, BSS0);
+		RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
+		deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("Can't allocate skb\n"));
+	}
+}
+
+NDIS_STATUS	RTUSBFreeDescriptorRequest(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			BulkOutPipeId,
+	IN	UINT32			NumberRequired)
+{
+//	UCHAR			FreeNumber = 0;
+//	UINT			Index;
+	NDIS_STATUS		Status = NDIS_STATUS_FAILURE;
+	unsigned long   IrqFlags;
+	HT_TX_CONTEXT	*pHTTXContext;
+
+
+	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+	if ((pHTTXContext->CurWritePosition < pHTTXContext->NextBulkOutPosition) && ((pHTTXContext->CurWritePosition + NumberRequired + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition))
+	{
+
+		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
+	}
+	else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < (NumberRequired + LOCAL_TXBUF_SIZE)))
+	{
+		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
+	}
+	else if (pHTTXContext->bCurWriting == TRUE)
+	{
+		DBGPRINT(RT_DEBUG_TRACE,("RTUSBFreeD c3 --> QueIdx=%d, CWPos=%ld, NBOutPos=%ld!\n", BulkOutPipeId, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition));
+		RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
+	}
+	else
+	{
+		Status = NDIS_STATUS_SUCCESS;
+	}
+	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+
+
+	return (Status);
+}
+
+
+NDIS_STATUS RTUSBFreeDescriptorRelease(
+	IN RTMP_ADAPTER *pAd,
+	IN UCHAR		BulkOutPipeId)
+{
+	unsigned long   IrqFlags;
+	HT_TX_CONTEXT	*pHTTXContext;
+
+	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+	pHTTXContext->bCurWriting = FALSE;
+	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+
+	return (NDIS_STATUS_SUCCESS);
+}
+
+
+BOOLEAN	RTUSBNeedQueueBackForAgg(
+	IN RTMP_ADAPTER *pAd,
+	IN UCHAR		BulkOutPipeId)
+{
+	unsigned long   IrqFlags;
+	HT_TX_CONTEXT	*pHTTXContext;
+	BOOLEAN			needQueBack = FALSE;
+
+	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+
+	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+	if ((pHTTXContext->IRPPending == TRUE)  /*&& (pAd->TxSwQueue[BulkOutPipeId].Number == 0) */)
+	{
+		if ((pHTTXContext->CurWritePosition < pHTTXContext->ENextBulkOutPosition) &&
+			(((pHTTXContext->ENextBulkOutPosition+MAX_AGGREGATION_SIZE) < MAX_TXBULK_LIMIT) || (pHTTXContext->CurWritePosition > MAX_AGGREGATION_SIZE)))
+		{
+			needQueBack = TRUE;
+		}
+		else if ((pHTTXContext->CurWritePosition > pHTTXContext->ENextBulkOutPosition) &&
+				 ((pHTTXContext->ENextBulkOutPosition + MAX_AGGREGATION_SIZE) < pHTTXContext->CurWritePosition))
+		{
+			needQueBack = TRUE;
+		}
+	}
+	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+
+	return needQueBack;
+
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTUSBRejectPendingPackets(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	UCHAR			Index;
+	PQUEUE_ENTRY	pEntry;
+	PNDIS_PACKET	pPacket;
+	PQUEUE_HEADER	pQueue;
+
+
+	for (Index = 0; Index < 4; Index++)
+	{
+		NdisAcquireSpinLock(&pAd->TxSwQueueLock[Index]);
+		while (pAd->TxSwQueue[Index].Head != NULL)
+		{
+			pQueue = (PQUEUE_HEADER) &(pAd->TxSwQueue[Index]);
+			pEntry = RemoveHeadQueue(pQueue);
+			pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
+			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+		}
+		NdisReleaseSpinLock(&pAd->TxSwQueueLock[Index]);
+
+	}
+
+}
+
+VOID RTMPWriteTxInfo(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PTXINFO_STRUC 	pTxInfo,
+	IN	  USHORT		USBDMApktLen,
+	IN	  BOOLEAN		bWiv,
+	IN	  UCHAR			QueueSel,
+	IN	  UCHAR			NextValid,
+	IN	  UCHAR			TxBurst)
+{
+	pTxInfo->USBDMATxPktLen = USBDMApktLen;
+	pTxInfo->QSEL = QueueSel;
+	if (QueueSel != FIFO_EDCA)
+		DBGPRINT(RT_DEBUG_TRACE, ("====> QueueSel != FIFO_EDCA<============\n"));
+	pTxInfo->USBDMANextVLD = FALSE; //NextValid;  // Need to check with Jan about this.
+	pTxInfo->USBDMATxburst = TxBurst;
+	pTxInfo->WIV = bWiv;
+	pTxInfo->SwUseLastRound = 0;
+	pTxInfo->rsv = 0;
+	pTxInfo->rsv2 = 0;
+}
+
diff --git a/drivers/staging/rt3070/common/rtusb_io.c b/drivers/staging/rt3070/common/rtusb_io.c
new file mode 100644
index 0000000..a6a52e3
--- /dev/null
+++ b/drivers/staging/rt3070/common/rtusb_io.c
@@ -0,0 +1,1908 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+ 	Module Name:
+	rtusb_io.c
+
+	Abstract:
+
+	Revision History:
+	Who			When	    What
+	--------	----------  ----------------------------------------------
+	Name		Date	    Modification logs
+	Paul Lin    06-25-2004  created
+*/
+
+#include	"../rt_config.h"
+
+
+/*
+	========================================================================
+
+	Routine Description: NIC initialization complete
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+
+NTSTATUS	RTUSBFirmwareRun(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	NTSTATUS	Status;
+
+	Status = RTUSB_VendorRequest(
+		pAd,
+		USBD_TRANSFER_DIRECTION_OUT,
+		DEVICE_VENDOR_REQUEST_OUT,
+		0x01,
+		0x8,
+		0,
+		NULL,
+		0);
+
+	return Status;
+}
+
+
+
+/*
+	========================================================================
+
+	Routine Description: Write Firmware to NIC.
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+NTSTATUS RTUSBFirmwareWrite(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR		pFwImage,
+	IN ULONG		FwLen)
+{
+	UINT32		MacReg;
+	NTSTATUS 	Status;
+//	ULONG 		i;
+	USHORT		writeLen;
+
+	Status = RTUSBReadMACRegister(pAd, MAC_CSR0, &MacReg);
+
+
+	writeLen = FwLen;
+	RTUSBMultiWrite(pAd, FIRMWARE_IMAGE_BASE, pFwImage, writeLen);
+
+	Status = RTUSBWriteMACRegister(pAd, 0x7014, 0xffffffff);
+	Status = RTUSBWriteMACRegister(pAd, 0x701c, 0xffffffff);
+	Status = RTUSBFirmwareRun(pAd);
+
+	RTMPusecDelay(10000);
+	RTUSBWriteMACRegister(pAd,H2M_MAILBOX_CSR,0);
+	AsicSendCommandToMcu(pAd, 0x72, 0x00, 0x00, 0x00);//reset rf by MCU supported by new firmware
+
+	return Status;
+}
+
+
+/*
+	========================================================================
+
+	Routine Description: Get current firmware operation mode (Return Value)
+
+	Arguments:
+
+	Return Value:
+		0 or 1 = Downloaded by host driver
+		others = Driver doesn't download firmware
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+NTSTATUS	RTUSBFirmwareOpmode(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUINT32			pValue)
+{
+	NTSTATUS	Status;
+
+	Status = RTUSB_VendorRequest(
+		pAd,
+		(USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
+		DEVICE_VENDOR_REQUEST_IN,
+		0x1,
+		0x11,
+		0,
+		pValue,
+		4);
+	return Status;
+}
+NTSTATUS	RTUSBVenderReset(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	NTSTATUS	Status;
+	DBGPRINT_RAW(RT_DEBUG_ERROR, ("-->RTUSBVenderReset\n"));
+	Status = RTUSB_VendorRequest(
+		pAd,
+		USBD_TRANSFER_DIRECTION_OUT,
+		DEVICE_VENDOR_REQUEST_OUT,
+		0x01,
+		0x1,
+		0,
+		NULL,
+		0);
+
+	DBGPRINT_RAW(RT_DEBUG_ERROR, ("<--RTUSBVenderReset\n"));
+	return Status;
+}
+/*
+	========================================================================
+
+	Routine Description: Read various length data from RT2573
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+NTSTATUS	RTUSBMultiRead(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT			Offset,
+	OUT	PUCHAR			pData,
+	IN	USHORT			length)
+{
+	NTSTATUS	Status;
+
+	Status = RTUSB_VendorRequest(
+		pAd,
+		(USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
+		DEVICE_VENDOR_REQUEST_IN,
+		0x7,
+		0,
+		Offset,
+		pData,
+		length);
+
+	return Status;
+}
+
+/*
+	========================================================================
+
+	Routine Description: Write various length data to RT2573
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+NTSTATUS	RTUSBMultiWrite_OneByte(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT			Offset,
+	IN	PUCHAR			pData)
+{
+	NTSTATUS	Status;
+
+	// TODO: In 2870, use this funciton carefully cause it's not stable.
+	Status = RTUSB_VendorRequest(
+		pAd,
+		USBD_TRANSFER_DIRECTION_OUT,
+		DEVICE_VENDOR_REQUEST_OUT,
+		0x6,
+		0,
+		Offset,
+		pData,
+		1);
+
+	return Status;
+}
+
+NTSTATUS	RTUSBMultiWrite(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT			Offset,
+	IN	PUCHAR			pData,
+	IN	USHORT			length)
+{
+	NTSTATUS	Status;
+
+
+        USHORT          index = 0,Value;
+        PUCHAR          pSrc = pData;
+        USHORT          resude = 0;
+
+        resude = length % 2;
+		length  += resude;
+		do
+		{
+			Value =(USHORT)( *pSrc  | (*(pSrc + 1) << 8));
+		Status = RTUSBSingleWrite(pAd,Offset + index,Value);
+            index +=2;
+            length -= 2;
+            pSrc = pSrc + 2;
+        }while(length > 0);
+
+	return Status;
+}
+
+
+NTSTATUS RTUSBSingleWrite(
+	IN 	RTMP_ADAPTER 	*pAd,
+	IN	USHORT			Offset,
+	IN	USHORT			Value)
+{
+	NTSTATUS	Status;
+
+	Status = RTUSB_VendorRequest(
+		pAd,
+		USBD_TRANSFER_DIRECTION_OUT,
+		DEVICE_VENDOR_REQUEST_OUT,
+		0x2,
+		Value,
+		Offset,
+		NULL,
+		0);
+
+	return Status;
+
+}
+
+
+/*
+	========================================================================
+
+	Routine Description: Read 32-bit MAC register
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+NTSTATUS	RTUSBReadMACRegister(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT			Offset,
+	OUT	PUINT32			pValue)
+{
+	NTSTATUS	Status;
+	UINT32		localVal;
+
+	Status = RTUSB_VendorRequest(
+		pAd,
+		(USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
+		DEVICE_VENDOR_REQUEST_IN,
+		0x7,
+		0,
+		Offset,
+		&localVal,
+		4);
+
+	*pValue = le2cpu32(localVal);
+
+
+	if (Status < 0)
+		*pValue = 0xffffffff;
+
+	return Status;
+}
+
+
+/*
+	========================================================================
+
+	Routine Description: Write 32-bit MAC register
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+NTSTATUS	RTUSBWriteMACRegister(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT			Offset,
+	IN	UINT32			Value)
+{
+	NTSTATUS	Status;
+	UINT32		localVal;
+
+	localVal = Value;
+
+	Status = RTUSBSingleWrite(pAd, Offset, (USHORT)(localVal & 0xffff));
+	Status = RTUSBSingleWrite(pAd, Offset + 2, (USHORT)((localVal & 0xffff0000) >> 16));
+
+	return Status;
+}
+
+
+
+#if 1
+/*
+	========================================================================
+
+	Routine Description: Read 8-bit BBP register
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+NTSTATUS	RTUSBReadBBPRegister(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			Id,
+	IN	PUCHAR			pValue)
+{
+	BBP_CSR_CFG_STRUC	BbpCsr;
+	UINT			i = 0;
+	NTSTATUS		status;
+
+	// Verify the busy condition
+	do
+	{
+		status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
+		if(status >= 0)
+		{
+		if (!(BbpCsr.field.Busy == BUSY))
+			break;
+		}
+		printk("RTUSBReadBBPRegister(BBP_CSR_CFG_1):retry count=%d!\n", i);
+		i++;
+	}
+	while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
+
+	if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+	{
+		//
+		// Read failed then Return Default value.
+		//
+		*pValue = pAd->BbpWriteLatch[Id];
+
+		DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
+		return STATUS_UNSUCCESSFUL;
+	}
+
+	// Prepare for write material
+	BbpCsr.word 				= 0;
+	BbpCsr.field.fRead			= 1;
+	BbpCsr.field.Busy			= 1;
+	BbpCsr.field.RegNum 		= Id;
+	RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word);
+
+	i = 0;
+	// Verify the busy condition
+	do
+	{
+		status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
+		if (status >= 0)
+		{
+		if (!(BbpCsr.field.Busy == BUSY))
+		{
+			*pValue = (UCHAR)BbpCsr.field.Value;
+			break;
+		}
+		}
+		printk("RTUSBReadBBPRegister(BBP_CSR_CFG_2):retry count=%d!\n", i);
+		i++;
+	}
+	while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
+
+	if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+	{
+		//
+		// Read failed then Return Default value.
+		//
+		*pValue = pAd->BbpWriteLatch[Id];
+
+		DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
+		return STATUS_UNSUCCESSFUL;
+	}
+
+	return STATUS_SUCCESS;
+}
+#else
+/*
+	========================================================================
+
+	Routine Description: Read 8-bit BBP register via firmware
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+NTSTATUS	RTUSBReadBBPRegister(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			Id,
+	IN	PUCHAR			pValue)
+{
+	BBP_CSR_CFG_STRUC	BbpCsr;
+	int					i, k;
+	for (i=0; i<MAX_BUSY_COUNT; i++)
+	{
+		RTUSBReadMACRegister(pAd, H2M_BBP_AGENT, &BbpCsr.word);
+		if (BbpCsr.field.Busy == BUSY)
+		{
+			continue;
+		}
+		BbpCsr.word = 0;
+		BbpCsr.field.fRead = 1;
+		BbpCsr.field.BBP_RW_MODE = 1;
+		BbpCsr.field.Busy = 1;
+		BbpCsr.field.RegNum = Id;
+		RTUSBWriteMACRegister(pAd, H2M_BBP_AGENT, BbpCsr.word);
+		AsicSendCommandToMcu(pAd, 0x80, 0xff, 0x0, 0x0);
+		for (k=0; k<MAX_BUSY_COUNT; k++)
+		{
+			RTUSBReadMACRegister(pAd, H2M_BBP_AGENT, &BbpCsr.word);
+			if (BbpCsr.field.Busy == IDLE)
+				break;
+		}
+		if ((BbpCsr.field.Busy == IDLE) &&
+			(BbpCsr.field.RegNum == Id))
+		{
+			*pValue = (UCHAR)BbpCsr.field.Value;
+			break;
+		}
+	}
+	if (BbpCsr.field.Busy == BUSY)
+	{
+		DBGPRINT_ERR(("BBP read R%d=0x%x fail\n", Id, BbpCsr.word));
+		*pValue = pAd->BbpWriteLatch[Id];
+		return STATUS_UNSUCCESSFUL;
+	}
+	return STATUS_SUCCESS;
+}
+#endif
+
+#if 1
+/*
+	========================================================================
+
+	Routine Description: Write 8-bit BBP register
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+NTSTATUS	RTUSBWriteBBPRegister(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			Id,
+	IN	UCHAR			Value)
+{
+	BBP_CSR_CFG_STRUC	BbpCsr;
+	UINT			i = 0;
+	NTSTATUS		status;
+	// Verify the busy condition
+	do
+	{
+		status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
+		if (status >= 0)
+		{
+		if (!(BbpCsr.field.Busy == BUSY))
+			break;
+		}
+		printk("RTUSBWriteBBPRegister(BBP_CSR_CFG):retry count=%d!\n", i);
+		i++;
+	}
+	while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
+
+	if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+	{
+		DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
+		return STATUS_UNSUCCESSFUL;
+	}
+
+	// Prepare for write material
+	BbpCsr.word 				= 0;
+	BbpCsr.field.fRead			= 0;
+	BbpCsr.field.Value			= Value;
+	BbpCsr.field.Busy			= 1;
+	BbpCsr.field.RegNum 		= Id;
+	RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word);
+
+	pAd->BbpWriteLatch[Id] = Value;
+
+	return STATUS_SUCCESS;
+}
+#else
+/*
+	========================================================================
+
+	Routine Description: Write 8-bit BBP register via firmware
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+
+NTSTATUS	RTUSBWriteBBPRegister(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			Id,
+	IN	UCHAR			Value)
+
+{
+	BBP_CSR_CFG_STRUC	BbpCsr;
+	int					BusyCnt;
+	for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++)
+	{
+		RTMP_IO_READ32(pAd, H2M_BBP_AGENT, &BbpCsr.word);
+		if (BbpCsr.field.Busy == BUSY)
+			continue;
+		BbpCsr.word = 0;
+		BbpCsr.field.fRead = 0;
+		BbpCsr.field.BBP_RW_MODE = 1;
+		BbpCsr.field.Busy = 1;
+		BbpCsr.field.Value = Value;
+		BbpCsr.field.RegNum = Id;
+		RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, BbpCsr.word);
+		AsicSendCommandToMcu(pAd, 0x80, 0xff, 0x0, 0x0);
+		pAd->BbpWriteLatch[Id] = Value;
+		break;
+	}
+	if (BusyCnt == MAX_BUSY_COUNT)
+	{
+		DBGPRINT_ERR(("BBP write R%d=0x%x fail\n", Id, BbpCsr.word));
+		return STATUS_UNSUCCESSFUL;
+	}
+	return STATUS_SUCCESS;
+}
+#endif
+/*
+	========================================================================
+
+	Routine Description: Write RF register through MAC
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+NTSTATUS	RTUSBWriteRFRegister(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UINT32			Value)
+{
+	PHY_CSR4_STRUC	PhyCsr4;
+	UINT			i = 0;
+	NTSTATUS		status;
+
+	NdisZeroMemory(&PhyCsr4, sizeof(PHY_CSR4_STRUC));
+	do
+	{
+		status = RTUSBReadMACRegister(pAd, RF_CSR_CFG0, &PhyCsr4.word);
+		if (status >= 0)
+		{
+		if (!(PhyCsr4.field.Busy))
+			break;
+		}
+		printk("RTUSBWriteRFRegister(RF_CSR_CFG0):retry count=%d!\n", i);
+		i++;
+	}
+	while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
+
+	if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+	{
+		DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
+		return STATUS_UNSUCCESSFUL;
+	}
+
+	RTUSBWriteMACRegister(pAd, RF_CSR_CFG0, Value);
+
+	return STATUS_SUCCESS;
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+NTSTATUS	RTUSBReadEEPROM(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT			Offset,
+	OUT	PUCHAR			pData,
+	IN	USHORT			length)
+{
+	NTSTATUS	Status = STATUS_SUCCESS;
+
+#ifdef RT30xx
+	if(pAd->bUseEfuse)
+	{
+		Status =eFuseRead(pAd, Offset, pData, length);
+	}
+	else
+#endif // RT30xx //
+	{
+	Status = RTUSB_VendorRequest(
+		pAd,
+		(USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
+		DEVICE_VENDOR_REQUEST_IN,
+		0x9,
+		0,
+		Offset,
+		pData,
+		length);
+	}
+
+	return Status;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+NTSTATUS	RTUSBWriteEEPROM(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT			Offset,
+	IN	PUCHAR			pData,
+	IN	USHORT			length)
+{
+	NTSTATUS	Status = STATUS_SUCCESS;
+
+#ifdef RT30xx
+	if(pAd->bUseEfuse)
+	{
+		Status = eFuseWrite(pAd, Offset, pData, length);
+	}
+	else
+#endif // RT30xx //
+	{
+	Status = RTUSB_VendorRequest(
+		pAd,
+		USBD_TRANSFER_DIRECTION_OUT,
+		DEVICE_VENDOR_REQUEST_OUT,
+		0x8,
+		0,
+		Offset,
+		pData,
+		length);
+	}
+
+	return Status;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+VOID RTUSBPutToSleep(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	UINT32		value;
+
+	// Timeout 0x40 x 50us
+	value = (SLEEPCID<<16)+(OWNERMCU<<24)+ (0x40<<8)+1;
+	RTUSBWriteMACRegister(pAd, 0x7010, value);
+	RTUSBWriteMACRegister(pAd, 0x404, 0x30);
+	//RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+	DBGPRINT_RAW(RT_DEBUG_ERROR, ("Sleep Mailbox testvalue %x\n", value));
+
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+NTSTATUS RTUSBWakeUp(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	NTSTATUS	Status;
+
+	Status = RTUSB_VendorRequest(
+		pAd,
+		USBD_TRANSFER_DIRECTION_OUT,
+		DEVICE_VENDOR_REQUEST_OUT,
+		0x01,
+		0x09,
+		0,
+		NULL,
+		0);
+
+	return Status;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTUSBInitializeCmdQ(
+	IN	PCmdQ	cmdq)
+{
+	cmdq->head = NULL;
+	cmdq->tail = NULL;
+	cmdq->size = 0;
+	cmdq->CmdQState = RT2870_THREAD_INITED;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+NDIS_STATUS	RTUSBEnqueueCmdFromNdis(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	NDIS_OID		Oid,
+	IN	BOOLEAN			SetInformation,
+	IN	PVOID			pInformationBuffer,
+	IN	UINT32			InformationBufferLength)
+{
+	NDIS_STATUS	status;
+	PCmdQElmt	cmdqelmt = NULL;
+	POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+
+	if (pObj->RTUSBCmdThr_pid < 0)
+		return (NDIS_STATUS_RESOURCES);
+
+	status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt));
+	if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL))
+		return (NDIS_STATUS_RESOURCES);
+
+		cmdqelmt->buffer = NULL;
+		if (pInformationBuffer != NULL)
+		{
+			status = RTMPAllocateMemory((PVOID *)&cmdqelmt->buffer, InformationBufferLength);
+			if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL))
+			{
+				kfree(cmdqelmt);
+				return (NDIS_STATUS_RESOURCES);
+			}
+			else
+			{
+				NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength);
+				cmdqelmt->bufferlength = InformationBufferLength;
+			}
+		}
+		else
+			cmdqelmt->bufferlength = 0;
+
+	cmdqelmt->command = Oid;
+	cmdqelmt->CmdFromNdis = TRUE;
+	if (SetInformation == TRUE)
+		cmdqelmt->SetOperation = TRUE;
+	else
+		cmdqelmt->SetOperation = FALSE;
+
+	NdisAcquireSpinLock(&pAd->CmdQLock);
+	if (pAd->CmdQ.CmdQState & RT2870_THREAD_CAN_DO_INSERT)
+	{
+		EnqueueCmd((&pAd->CmdQ), cmdqelmt);
+		status = NDIS_STATUS_SUCCESS;
+	}
+	else
+	{
+		status = NDIS_STATUS_FAILURE;
+	}
+	NdisReleaseSpinLock(&pAd->CmdQLock);
+
+	if (status == NDIS_STATUS_FAILURE)
+	{
+		if (cmdqelmt->buffer)
+			NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
+		NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
+	}
+	else
+	RTUSBCMDUp(pAd);
+
+
+    return(NDIS_STATUS_SUCCESS);
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+NDIS_STATUS RTUSBEnqueueInternalCmd(
+	IN PRTMP_ADAPTER	pAd,
+	IN NDIS_OID			Oid,
+	IN PVOID			pInformationBuffer,
+	IN UINT32			InformationBufferLength)
+{
+	NDIS_STATUS	status;
+	PCmdQElmt	cmdqelmt = NULL;
+
+
+	status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt));
+	if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL))
+		return (NDIS_STATUS_RESOURCES);
+	NdisZeroMemory(cmdqelmt, sizeof(CmdQElmt));
+
+	if(InformationBufferLength > 0)
+	{
+		status = RTMPAllocateMemory((PVOID *)&cmdqelmt->buffer, InformationBufferLength);
+		if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL))
+		{
+			NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
+			return (NDIS_STATUS_RESOURCES);
+		}
+		else
+		{
+			NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength);
+			cmdqelmt->bufferlength = InformationBufferLength;
+		}
+	}
+	else
+	{
+		cmdqelmt->buffer = NULL;
+		cmdqelmt->bufferlength = 0;
+	}
+
+	cmdqelmt->command = Oid;
+	cmdqelmt->CmdFromNdis = FALSE;
+
+	if (cmdqelmt != NULL)
+	{
+		NdisAcquireSpinLock(&pAd->CmdQLock);
+		if (pAd->CmdQ.CmdQState & RT2870_THREAD_CAN_DO_INSERT)
+		{
+			EnqueueCmd((&pAd->CmdQ), cmdqelmt);
+			status = NDIS_STATUS_SUCCESS;
+		}
+		else
+		{
+			status = NDIS_STATUS_FAILURE;
+		}
+		NdisReleaseSpinLock(&pAd->CmdQLock);
+
+		if (status == NDIS_STATUS_FAILURE)
+		{
+			if (cmdqelmt->buffer)
+				NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
+			NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
+		}
+		else
+		RTUSBCMDUp(pAd);
+	}
+	return(NDIS_STATUS_SUCCESS);
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTUSBDequeueCmd(
+	IN	PCmdQ		cmdq,
+	OUT	PCmdQElmt	*pcmdqelmt)
+{
+	*pcmdqelmt = cmdq->head;
+
+	if (*pcmdqelmt != NULL)
+	{
+		cmdq->head = cmdq->head->next;
+		cmdq->size--;
+		if (cmdq->size == 0)
+			cmdq->tail = NULL;
+	}
+}
+
+/*
+    ========================================================================
+	  usb_control_msg - Builds a control urb, sends it off and waits for completion
+	  @dev: pointer to the usb device to send the message to
+	  @pipe: endpoint "pipe" to send the message to
+	  @request: USB message request value
+	  @requesttype: USB message request type value
+	  @value: USB message value
+	  @index: USB message index value
+	  @data: pointer to the data to send
+	  @size: length in bytes of the data to send
+	  @timeout: time in jiffies to wait for the message to complete before
+			  timing out (if 0 the wait is forever)
+	  Context: !in_interrupt ()
+
+	  This function sends a simple control message to a specified endpoint
+	  and waits for the message to complete, or timeout.
+	  If successful, it returns the number of bytes transferred, otherwise a negative error number.
+
+	 Don't use this function from within an interrupt context, like a
+	  bottom half handler.	If you need an asynchronous message, or need to send
+	  a message from within interrupt context, use usb_submit_urb()
+	  If a thread in your driver uses this call, make sure your disconnect()
+	  method can wait for it to complete.  Since you don't have a handle on
+	  the URB used, you can't cancel the request.
+
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+	========================================================================
+*/
+NTSTATUS    RTUSB_VendorRequest(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UINT32			TransferFlags,
+	IN	UCHAR			RequestType,
+	IN	UCHAR			Request,
+	IN	USHORT			Value,
+	IN	USHORT			Index,
+	IN	PVOID			TransferBuffer,
+	IN	UINT32			TransferBufferLength)
+{
+	int				ret;
+	POS_COOKIE		pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("device disconnected\n"));
+		return -1;
+	}
+	else if (in_interrupt())
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("in_interrupt, RTUSB_VendorRequest Request%02x Value%04x Offset%04x\n",Request,Value,Index));
+
+		return -1;
+	}
+	else
+	{
+#define MAX_RETRY_COUNT  10
+
+		int retryCount = 0;
+		void	*tmpBuf = TransferBuffer;
+
+		// Acquire Control token
+#ifdef INF_AMAZON_SE
+		ret = down_interruptible(&(pAd->UsbVendorReq_semaphore));
+		if (pAd->UsbVendorReqBuf)
+		{
+			ASSERT(TransferBufferLength <MAX_PARAM_BUFFER_SIZE);
+
+		   	tmpBuf = (void *)pAd->UsbVendorReqBuf;
+		   	NdisZeroMemory(pAd->UsbVendorReqBuf, TransferBufferLength);
+
+		   	if (RequestType == DEVICE_VENDOR_REQUEST_OUT)
+		   	 NdisMoveMemory(tmpBuf, TransferBuffer, TransferBufferLength);
+		}
+#endif // INF_AMAZON_SE //
+		do {
+		if( RequestType == DEVICE_VENDOR_REQUEST_OUT)
+			ret=usb_control_msg(pObj->pUsb_Dev, usb_sndctrlpipe( pObj->pUsb_Dev, 0 ), Request, RequestType, Value,Index, tmpBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);
+		else if(RequestType == DEVICE_VENDOR_REQUEST_IN)
+			ret=usb_control_msg(pObj->pUsb_Dev, usb_rcvctrlpipe( pObj->pUsb_Dev, 0 ), Request, RequestType, Value,Index, tmpBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);
+		else
+		{
+			DBGPRINT(RT_DEBUG_ERROR, ("vendor request direction is failed\n"));
+			ret = -1;
+		}
+
+			retryCount++;
+			if (ret < 0) {
+				printk("#\n");
+				RTMPusecDelay(5000);
+			}
+		} while((ret < 0) && (retryCount < MAX_RETRY_COUNT));
+
+#ifdef INF_AMAZON_SE
+	  	if ((pAd->UsbVendorReqBuf) && (RequestType == DEVICE_VENDOR_REQUEST_IN))
+			NdisMoveMemory(TransferBuffer, tmpBuf, TransferBufferLength);
+	  	up(&(pAd->UsbVendorReq_semaphore));
+#endif // INF_AMAZON_SE //
+
+        if (ret < 0) {
+//			DBGPRINT(RT_DEBUG_ERROR, ("USBVendorRequest failed ret=%d \n",ret));
+			DBGPRINT(RT_DEBUG_ERROR, ("RTUSB_VendorRequest failed(%d),TxFlags=0x%x, ReqType=%s, Req=0x%x, Index=0x%x\n",
+						ret, TransferFlags, (RequestType == DEVICE_VENDOR_REQUEST_OUT ? "OUT" : "IN"), Request, Index));
+			if (Request == 0x2)
+				DBGPRINT(RT_DEBUG_ERROR, ("\tRequest Value=0x%04x!\n", Value));
+
+			if ((TransferBuffer!= NULL) && (TransferBufferLength > 0))
+				hex_dump("Failed TransferBuffer value", TransferBuffer, TransferBufferLength);
+        }
+	}
+	return ret;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+	  Creates an IRP to submite an IOCTL_INTERNAL_USB_RESET_PORT
+	  synchronously. Callers of this function must be running at
+	  PASSIVE LEVEL.
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+	========================================================================
+*/
+NTSTATUS	RTUSB_ResetDevice(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	NTSTATUS		Status = TRUE;
+
+	DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->USB_ResetDevice\n"));
+	//RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);
+	return Status;
+}
+
+VOID CMDHandler(
+    IN PRTMP_ADAPTER pAd)
+{
+	PCmdQElmt		cmdqelmt;
+	PUCHAR			pData;
+	NDIS_STATUS		NdisStatus = NDIS_STATUS_SUCCESS;
+//	ULONG			Now = 0;
+	NTSTATUS		ntStatus;
+//	unsigned long	IrqFlags;
+
+	while (pAd->CmdQ.size > 0)
+	{
+		NdisStatus = NDIS_STATUS_SUCCESS;
+
+		NdisAcquireSpinLock(&pAd->CmdQLock);
+		RTUSBDequeueCmd(&pAd->CmdQ, &cmdqelmt);
+		NdisReleaseSpinLock(&pAd->CmdQLock);
+
+		if (cmdqelmt == NULL)
+			break;
+
+		pData = cmdqelmt->buffer;
+
+		if(!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
+		{
+			switch (cmdqelmt->command)
+			{
+				case CMDTHREAD_CHECK_GPIO:
+					{
+#ifdef CONFIG_STA_SUPPORT
+						UINT32 data;
+#endif // CONFIG_STA_SUPPORT //
+#ifdef RALINK_ATE
+       					if(ATE_ON(pAd))
+						{
+							DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
+							break;
+						}
+#endif // RALINK_ATE //
+
+#ifdef CONFIG_STA_SUPPORT
+
+
+						IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+						{
+							// Read GPIO pin2 as Hardware controlled radio state
+
+							RTUSBReadMACRegister( pAd, GPIO_CTRL_CFG, &data);
+
+							if (data & 0x04)
+							{
+								pAd->StaCfg.bHwRadio = TRUE;
+							}
+							else
+							{
+								pAd->StaCfg.bHwRadio = FALSE;
+							}
+
+							if(pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
+							{
+								pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
+								if(pAd->StaCfg.bRadio == TRUE)
+								{
+									DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio On !!!\n"));
+
+									MlmeRadioOn(pAd);
+									// Update extra information
+									pAd->ExtraInfo = EXTRA_INFO_CLEAR;
+								}
+								else
+								{
+									DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio Off !!!\n"));
+
+									MlmeRadioOff(pAd);
+									// Update extra information
+									pAd->ExtraInfo = HW_RADIO_OFF;
+								}
+							}
+						}
+#endif // CONFIG_STA_SUPPORT //
+					}
+					break;
+
+#ifdef CONFIG_STA_SUPPORT
+				case CMDTHREAD_QKERIODIC_EXECUT:
+					{
+						StaQuickResponeForRateUpExec(NULL, pAd, NULL, NULL);
+					}
+					break;
+#endif // CONFIG_STA_SUPPORT //
+
+				case CMDTHREAD_RESET_BULK_OUT:
+					{
+						UINT32		MACValue;
+						UCHAR		Index;
+						int			ret=0;
+						PHT_TX_CONTEXT	pHTTXContext;
+//						RTMP_TX_RING *pTxRing;
+						unsigned long IrqFlags;
+#ifdef RALINK_ATE
+						PTX_CONTEXT		pNullContext = &(pAd->NullContext);
+#endif // RALINK_ATE //
+						DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT(ResetPipeid=0x%0x)===>\n", pAd->bulkResetPipeid));
+						// All transfers must be aborted or cancelled before attempting to reset the pipe.
+						//RTUSBCancelPendingBulkOutIRP(pAd);
+						// Wait 10ms to let previous packet that are already in HW FIFO to clear. by MAXLEE 12-25-2007
+						Index = 0;
+						do
+						{
+							RTUSBReadMACRegister(pAd, TXRXQ_PCNT, &MACValue);
+							if ((MACValue & 0xf00000/*0x800000*/) == 0)
+								break;
+							Index++;
+							RTMPusecDelay(10000);
+						}while(Index < 100);
+						MACValue = 0;
+						RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
+						// To prevent Read Register error, we 2nd check the validity.
+						if ((MACValue & 0xc00000) == 0)
+							RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
+						// To prevent Read Register error, we 3rd check the validity.
+						if ((MACValue & 0xc00000) == 0)
+							RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
+						MACValue |= 0x80000;
+						RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue);
+
+						// Wait 1ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007
+						RTMPusecDelay(1000);
+
+						MACValue &= (~0x80000);
+						RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue);
+						DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tSet 0x2a0 bit19. Clear USB DMA TX path\n"));
+
+						// Wait 5ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007
+						//RTMPusecDelay(5000);
+
+						if ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG)
+						{
+							RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+							if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */)
+							{
+								RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
+							}
+							RTUSBKickBulkOut(pAd);
+
+							DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tTX MGMT RECOVER Done!\n"));
+						}
+						else
+						{
+							pHTTXContext = &(pAd->TxContext[pAd->bulkResetPipeid]);
+							//NdisAcquireSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
+							RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
+							if ( pAd->BulkOutPending[pAd->bulkResetPipeid] == FALSE)
+							{
+								pAd->BulkOutPending[pAd->bulkResetPipeid] = TRUE;
+								pHTTXContext->IRPPending = TRUE;
+								pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 1;
+
+								// no matter what, clean the flag
+								RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+
+								//NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
+								RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
+/*-----------------------------------------------------------------------------------------------*/
+#ifdef RALINK_ATE
+								if(ATE_ON(pAd))
+							    {
+									pNullContext->IRPPending = TRUE;
+									//
+									// If driver is still in ATE TXFRAME mode,
+									// keep on transmitting ATE frames.
+									//
+									DBGPRINT_RAW(RT_DEBUG_TRACE, ("pAd->ate.Mode == %d\npAd->ContinBulkOut == %d\npAd->BulkOutRemained == %d\n", pAd->ate.Mode, pAd->ContinBulkOut, atomic_read(&pAd->BulkOutRemained)));
+									if((pAd->ate.Mode == ATE_TXFRAME) && ((pAd->ContinBulkOut == TRUE) || (atomic_read(&pAd->BulkOutRemained) > 0)))
+								    {
+										DBGPRINT_RAW(RT_DEBUG_TRACE, ("After CMDTHREAD_RESET_BULK_OUT, continue to bulk out frames !\n"));
+
+										// Init Tx context descriptor
+										RTUSBInitTxDesc(pAd, pNullContext, 0/* pAd->bulkResetPipeid */, (usb_complete_t)ATE_RTUSBBulkOutDataPacketComplete);
+
+										if((ret = RTUSB_SUBMIT_URB(pNullContext->pUrb))!=0)
+										{
+											DBGPRINT(RT_DEBUG_ERROR, ("ATE_RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
+										}
+
+										pAd->BulkOutReq++;
+									}
+								}
+								else
+#endif // RALINK_ATE //
+/*-----------------------------------------------------------------------------------------------*/
+								{
+								RTUSBInitHTTxDesc(pAd, pHTTXContext, pAd->bulkResetPipeid, pHTTXContext->BulkOutSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete);
+
+								if((ret = RTUSB_SUBMIT_URB(pHTTXContext->pUrb))!=0)
+								{
+										RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
+									pAd->BulkOutPending[pAd->bulkResetPipeid] = FALSE;
+									pHTTXContext->IRPPending = FALSE;
+										pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 0;
+										RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
+
+										DBGPRINT(RT_DEBUG_ERROR, ("CmdThread : CMDTHREAD_RESET_BULK_OUT: Submit Tx URB failed %d\n", ret));
+								}
+									else
+									{
+										RTMP_IRQ_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
+										DBGPRINT_RAW(RT_DEBUG_TRACE,("\tCMDTHREAD_RESET_BULK_OUT: TxContext[%d]:CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, pending=%d!\n",
+												pAd->bulkResetPipeid, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition,
+															pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, pAd->BulkOutPending[pAd->bulkResetPipeid]));
+										DBGPRINT_RAW(RT_DEBUG_TRACE,("\t\tBulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n",
+															pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
+										RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
+										DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tCMDTHREAD_RESET_BULK_OUT: Submit Tx DATA URB for failed BulkReq(0x%lx) Done, status=%d!\n", pAd->bulkResetReq[pAd->bulkResetPipeid], pHTTXContext->pUrb->status));
+
+									}
+								}
+							}
+							else
+							{
+								//NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
+								//RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
+
+								DBGPRINT_RAW(RT_DEBUG_ERROR, ("CmdThread : TX DATA RECOVER FAIL for BulkReq(0x%lx) because BulkOutPending[%d] is TRUE!\n", pAd->bulkResetReq[pAd->bulkResetPipeid], pAd->bulkResetPipeid));
+								if (pAd->bulkResetPipeid == 0)
+								{
+									UCHAR	pendingContext = 0;
+									PHT_TX_CONTEXT pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[pAd->bulkResetPipeid ]);
+									PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
+									PTX_CONTEXT pNULLContext = (PTX_CONTEXT)(&pAd->PsPollContext);
+									PTX_CONTEXT pPsPollContext = (PTX_CONTEXT)(&pAd->NullContext);
+
+									if (pHTTXContext->IRPPending)
+										pendingContext |= 1;
+									else if (pMLMEContext->IRPPending)
+										pendingContext |= 2;
+									else if (pNULLContext->IRPPending)
+										pendingContext |= 4;
+									else if (pPsPollContext->IRPPending)
+										pendingContext |= 8;
+									else
+										pendingContext = 0;
+
+									DBGPRINT_RAW(RT_DEBUG_ERROR, ("\tTX Occupied by %d!\n", pendingContext));
+								}
+
+							// no matter what, clean the flag
+							RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+
+								RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
+
+								RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << pAd->bulkResetPipeid));
+							}
+
+							RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+							//RTUSBKickBulkOut(pAd);
+						}
+
+					}
+					/*
+						// Don't cancel BULKIN.
+						while ((atomic_read(&pAd->PendingRx) > 0) &&
+								(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+						{
+							if (atomic_read(&pAd->PendingRx) > 0)
+							{
+								DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!cancel it!\n"));
+								RTUSBCancelPendingBulkInIRP(pAd);
+							}
+							RTMPusecDelay(100000);
+						}
+
+						if ((atomic_read(&pAd->PendingRx) == 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
+						{
+							UCHAR	i;
+							RTUSBRxPacket(pAd);
+							pAd->NextRxBulkInReadIndex = 0;	// Next Rx Read index
+							pAd->NextRxBulkInIndex		= 0;	// Rx Bulk pointer
+							for (i = 0; i < (RX_RING_SIZE); i++)
+							{
+								PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
+
+								pRxContext->pAd	= pAd;
+								pRxContext->InUse		= FALSE;
+								pRxContext->IRPPending	= FALSE;
+								pRxContext->Readable	= FALSE;
+								pRxContext->ReorderInUse = FALSE;
+
+							}
+							RTUSBBulkReceive(pAd);
+							DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTUSBBulkReceive\n"));
+						}*/
+					DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT<===\n"));
+    	   			break;
+
+				case CMDTHREAD_RESET_BULK_IN:
+					DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN === >\n"));
+
+					// All transfers must be aborted or cancelled before attempting to reset the pipe.
+					{
+						UINT32		MACValue;
+/*-----------------------------------------------------------------------------------------------*/
+#ifdef RALINK_ATE
+						if (ATE_ON(pAd))
+						{
+							if((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+							{
+								DBGPRINT_RAW(RT_DEBUG_ERROR, ("ATE : BulkIn IRP Pending!!!\n"));
+								ATE_RTUSBCancelPendingBulkInIRP(pAd);
+								RTMPusecDelay(100000);
+								pAd->PendingRx = 0;
+							}
+						}
+						else
+#endif // RALINK_ATE //
+/*-----------------------------------------------------------------------------------------------*/
+						{
+						//while ((atomic_read(&pAd->PendingRx) > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+						if((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+						{
+							DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!!\n"));
+							RTUSBCancelPendingBulkInIRP(pAd);
+							RTMPusecDelay(100000);
+							pAd->PendingRx = 0;
+						}
+						}
+
+						// Wait 10ms before reading register.
+						RTMPusecDelay(10000);
+						ntStatus = RTUSBReadMACRegister(pAd, MAC_CSR0, &MACValue);
+
+						if ((NT_SUCCESS(ntStatus) == TRUE) &&
+							(!(RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF |
+													fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))))
+						{
+							UCHAR	i;
+
+							if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF |
+														fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))
+								break;
+							pAd->NextRxBulkInPosition = pAd->RxContext[pAd->NextRxBulkInIndex].BulkInOffset;
+							DBGPRINT(RT_DEBUG_TRACE, ("BULK_IN_RESET: NBIIdx=0x%x,NBIRIdx=0x%x, BIRPos=0x%lx. BIReq=x%lx, BIComplete=0x%lx, BICFail0x%lx\n",
+									pAd->NextRxBulkInIndex,  pAd->NextRxBulkInReadIndex, pAd->NextRxBulkInPosition, pAd->BulkInReq, pAd->BulkInComplete, pAd->BulkInCompleteFail));
+							for (i = 0; i < RX_RING_SIZE; i++)
+							{
+ 								DBGPRINT(RT_DEBUG_TRACE, ("\tRxContext[%d]: IRPPending=%d, InUse=%d, Readable=%d!\n"
+									, i, pAd->RxContext[i].IRPPending, pAd->RxContext[i].InUse, pAd->RxContext[i].Readable));
+							}
+ 							/*
+
+							DBGPRINT_RAW(RT_DEBUG_ERROR, ("==========================================\n"));
+
+							pAd->NextRxBulkInReadIndex = 0;	// Next Rx Read index
+							pAd->NextRxBulkInIndex		= 0;	// Rx Bulk pointer
+							for (i = 0; i < (RX_RING_SIZE); i++)
+							{
+								PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
+
+								pRxContext->pAd	= pAd;
+								pRxContext->InUse		= FALSE;
+								pRxContext->IRPPending	= FALSE;
+								pRxContext->Readable	= FALSE;
+								pRxContext->ReorderInUse = FALSE;
+
+							}*/
+							RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
+							for (i = 0; i < pAd->CommonCfg.NumOfBulkInIRP; i++)
+							{
+								//RTUSBBulkReceive(pAd);
+								PRX_CONTEXT		pRxContext;
+								PURB			pUrb;
+								int				ret = 0;
+								unsigned long	IrqFlags;
+
+
+								RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
+								pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
+								if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
+								{
+									RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+									break;
+								}
+								pRxContext->InUse = TRUE;
+								pRxContext->IRPPending = TRUE;
+								pAd->PendingRx++;
+								pAd->BulkInReq++;
+								RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+
+								// Init Rx context descriptor
+								RTUSBInitRxDesc(pAd, pRxContext);
+								pUrb = pRxContext->pUrb;
+								if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
+								{	// fail
+
+									RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
+									pRxContext->InUse = FALSE;
+									pRxContext->IRPPending = FALSE;
+									pAd->PendingRx--;
+									pAd->BulkInReq--;
+									RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+									DBGPRINT(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB failed(%d), status=%d\n", ret, pUrb->status));
+								}
+								else
+								{	// success
+									DBGPRINT_RAW(RT_DEBUG_TRACE, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB Done, status=%d!\n", pUrb->status));
+									ASSERT((pRxContext->InUse == pRxContext->IRPPending));
+								}
+							}
+
+						}
+						else
+						{
+							// Card must be removed
+							if (NT_SUCCESS(ntStatus) != TRUE)
+							{
+							RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
+								DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Read Register Failed!Card must be removed!!\n\n"));
+							}
+							else
+							{
+								DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Cannot do bulk in because flags(0x%lx) on !\n", pAd->Flags));
+						}
+					}
+					}
+					DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN <===\n"));
+					break;
+
+				case CMDTHREAD_SET_ASIC_WCID:
+					{
+						RT_SET_ASIC_WCID	SetAsicWcid;
+						USHORT		offset;
+						UINT32		MACValue, MACRValue = 0;
+						SetAsicWcid = *((PRT_SET_ASIC_WCID)(pData));
+
+						if (SetAsicWcid.WCID >= MAX_LEN_OF_MAC_TABLE)
+							return;
+
+						offset = MAC_WCID_BASE + ((UCHAR)SetAsicWcid.WCID)*HW_WCID_ENTRY_SIZE;
+
+						DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_SET_ASIC_WCID : WCID = %ld, SetTid  = %lx, DeleteTid = %lx.\n", SetAsicWcid.WCID, SetAsicWcid.SetTid, SetAsicWcid.DeleteTid));
+						MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[3]<<24)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[2]<<16)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[1]<<8)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[0]);
+						DBGPRINT_RAW(RT_DEBUG_TRACE, ("1-MACValue= %x,\n", MACValue));
+						RTUSBWriteMACRegister(pAd, offset, MACValue);
+						// Read bitmask
+						RTUSBReadMACRegister(pAd, offset+4, &MACRValue);
+						if ( SetAsicWcid.DeleteTid != 0xffffffff)
+							MACRValue &= (~SetAsicWcid.DeleteTid);
+						if (SetAsicWcid.SetTid != 0xffffffff)
+							MACRValue |= (SetAsicWcid.SetTid);
+						MACRValue &= 0xffff0000;
+
+						MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[5]<<8)+pAd->MacTab.Content[SetAsicWcid.WCID].Addr[4];
+						MACValue |= MACRValue;
+						RTUSBWriteMACRegister(pAd, offset+4, MACValue);
+
+						DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-MACValue= %x,\n", MACValue));
+					}
+					break;
+
+				case CMDTHREAD_SET_ASIC_WCID_CIPHER:
+					{
+#ifdef CONFIG_STA_SUPPORT
+						RT_SET_ASIC_WCID_ATTRI	SetAsicWcidAttri;
+						USHORT		offset;
+						UINT32		MACRValue = 0;
+						SHAREDKEY_MODE_STRUC csr1;
+						SetAsicWcidAttri = *((PRT_SET_ASIC_WCID_ATTRI)(pData));
+
+						if (SetAsicWcidAttri.WCID >= MAX_LEN_OF_MAC_TABLE)
+							return;
+
+						offset = MAC_WCID_ATTRIBUTE_BASE + ((UCHAR)SetAsicWcidAttri.WCID)*HW_WCID_ATTRI_SIZE;
+
+						DBGPRINT_RAW(RT_DEBUG_TRACE, ("Cmd : CMDTHREAD_SET_ASIC_WCID_CIPHER : WCID = %ld, Cipher = %lx.\n", SetAsicWcidAttri.WCID, SetAsicWcidAttri.Cipher));
+						// Read bitmask
+						RTUSBReadMACRegister(pAd, offset, &MACRValue);
+						MACRValue = 0;
+						MACRValue |= (((UCHAR)SetAsicWcidAttri.Cipher) << 1);
+
+						RTUSBWriteMACRegister(pAd, offset, MACRValue);
+						DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-offset = %x , MACValue= %x,\n", offset, MACRValue));
+
+						offset = PAIRWISE_IVEIV_TABLE_BASE + ((UCHAR)SetAsicWcidAttri.WCID)*HW_IVEIV_ENTRY_SIZE;
+						MACRValue = 0;
+						if ( (SetAsicWcidAttri.Cipher <= CIPHER_WEP128))
+							MACRValue |= ( pAd->StaCfg.DefaultKeyId << 30);
+						else
+							MACRValue |= (0x20000000);
+						RTUSBWriteMACRegister(pAd, offset, MACRValue);
+						DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-offset = %x , MACValue= %x,\n", offset, MACRValue));
+
+						//
+						// Update cipher algorithm. WSTA always use BSS0
+						//
+						// for adhoc mode only ,because wep status slow than add key, when use zero config
+						if (pAd->StaCfg.BssType == BSS_ADHOC )
+						{
+							offset = MAC_WCID_ATTRIBUTE_BASE;
+
+							RTUSBReadMACRegister(pAd, offset, &MACRValue);
+							MACRValue &= (~0xe);
+							MACRValue |= (((UCHAR)SetAsicWcidAttri.Cipher) << 1);
+
+							RTUSBWriteMACRegister(pAd, offset, MACRValue);
+
+							//Update group key cipher,,because wep status slow than add key, when use zero config
+							RTUSBReadMACRegister(pAd, SHARED_KEY_MODE_BASE+4*(0/2), &csr1.word);
+
+							csr1.field.Bss0Key0CipherAlg = SetAsicWcidAttri.Cipher;
+							csr1.field.Bss0Key1CipherAlg = SetAsicWcidAttri.Cipher;
+
+							RTUSBWriteMACRegister(pAd, SHARED_KEY_MODE_BASE+4*(0/2), csr1.word);
+						}
+#endif // CONFIG_STA_SUPPORT //
+					}
+					break;
+
+//Benson modified for USB interface, avoid in interrupt when write key, 20080724 -->
+				case RT_CMD_SET_KEY_TABLE: //General call for AsicAddPairwiseKeyEntry()
+				{
+					RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo;
+					KeyInfo = *((PRT_ADD_PAIRWISE_KEY_ENTRY)(pData));
+					AsicAddPairwiseKeyEntry(pAd,
+											KeyInfo.MacAddr,
+											(UCHAR)KeyInfo.MacTabMatchWCID,
+											&KeyInfo.CipherKey);
+				}
+					break;
+				case RT_CMD_SET_RX_WCID_TABLE: //General call for RTMPAddWcidAttributeEntry()
+				{
+					PMAC_TABLE_ENTRY pEntry;
+					UCHAR KeyIdx;
+					UCHAR CipherAlg;
+					UCHAR ApIdx;
+
+					pEntry = (PMAC_TABLE_ENTRY)(pData);
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+					KeyIdx = 0;
+					CipherAlg = pEntry->PairwiseKey.CipherAlg;
+					ApIdx = BSS0;
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+
+						RTMPAddWcidAttributeEntry(
+										  pAd,
+										  ApIdx,
+										  KeyIdx,
+										  CipherAlg,
+										  pEntry);
+					}
+						break;
+//Benson modified for USB interface, avoid in interrupt when write key, 20080724 <--
+
+				case CMDTHREAD_SET_CLIENT_MAC_ENTRY:
+					{
+						MAC_TABLE_ENTRY *pEntry;
+						pEntry = (MAC_TABLE_ENTRY *)pData;
+
+
+#ifdef CONFIG_STA_SUPPORT
+						IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+						{
+							AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)pEntry->Aid);
+							if ((pEntry->AuthMode <= Ndis802_11AuthModeAutoSwitch) && (pEntry->WepStatus == Ndis802_11Encryption1Enabled))
+							{
+								UINT32 uIV = 0;
+								PUCHAR  ptr;
+
+								ptr = (PUCHAR) &uIV;
+								*(ptr + 3) = (pAd->StaCfg.DefaultKeyId << 6);
+								AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, uIV, 0);
+								AsicUpdateWCIDAttribute(pAd, pEntry->Aid, BSS0, pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, FALSE);
+							}
+							else if (pEntry->AuthMode == Ndis802_11AuthModeWPANone)
+							{
+								UINT32 uIV = 0;
+								PUCHAR  ptr;
+
+								ptr = (PUCHAR) &uIV;
+								*(ptr + 3) = (pAd->StaCfg.DefaultKeyId << 6);
+								AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, uIV, 0);
+								AsicUpdateWCIDAttribute(pAd, pEntry->Aid, BSS0, pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, FALSE);
+							}
+							else
+							{
+								//
+								// Other case, disable engine.
+								// Don't worry WPA key, we will add WPA Key after 4-Way handshaking.
+								//
+								USHORT   offset;
+								offset = MAC_WCID_ATTRIBUTE_BASE + (pEntry->Aid * HW_WCID_ATTRI_SIZE);
+								// RX_PKEY_MODE:0 for no security; RX_KEY_TAB:0 for shared key table; BSS_IDX:0
+								RTUSBWriteMACRegister(pAd, offset, 0);
+							}
+						}
+#endif // CONFIG_STA_SUPPORT //
+
+						AsicUpdateRxWCIDTable(pAd, pEntry->Aid, pEntry->Addr);
+						printk("UpdateRxWCIDTable(): Aid=%d, Addr=%02x:%02x:%02x:%02x:%02x:%02x!\n", pEntry->Aid,
+								pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
+					}
+					break;
+
+// add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
+				case CMDTHREAD_UPDATE_PROTECT:
+					{
+						AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT), TRUE, 0);
+					}
+					break;
+// end johnli
+
+				case OID_802_11_ADD_WEP:
+					{
+#ifdef CONFIG_STA_SUPPORT
+						UINT	i;
+						UINT32	KeyIdx;
+						PNDIS_802_11_WEP	pWepKey;
+
+						DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::OID_802_11_ADD_WEP  \n"));
+
+						pWepKey = (PNDIS_802_11_WEP)pData;
+						KeyIdx = pWepKey->KeyIndex & 0x0fffffff;
+
+						// it is a shared key
+						if ((KeyIdx >= 4) || ((pWepKey->KeyLength != 5) && (pWepKey->KeyLength != 13)))
+						{
+							NdisStatus = NDIS_STATUS_INVALID_DATA;
+							DBGPRINT(RT_DEBUG_ERROR, ("CmdThread::OID_802_11_ADD_WEP, INVALID_DATA!!\n"));
+						}
+						else
+						{
+							UCHAR CipherAlg;
+							pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
+							NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
+							CipherAlg = (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 5)? CIPHER_WEP64 : CIPHER_WEP128;
+
+							//
+							// Change the WEP cipher to CKIP cipher if CKIP KP on.
+							// Funk UI or Meetinghouse UI will add ckip key from this path.
+							//
+
+							if (pAd->OpMode == OPMODE_STA)
+						 	{
+								pAd->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
+								pAd->MacTab.Content[BSSID_WCID].PairwiseKey.KeyLen = pAd->SharedKey[BSS0][KeyIdx].KeyLen;
+						 	}
+							pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CipherAlg;
+							if (pWepKey->KeyIndex & 0x80000000)
+							{
+								// Default key for tx (shared key)
+								UCHAR	IVEIV[8];
+								UINT32	WCIDAttri, Value;
+								USHORT	offset, offset2;
+								NdisZeroMemory(IVEIV, 8);
+								pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
+								// Add BSSID to WCTable. because this is Tx wep key.
+								// WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0
+								WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
+
+								offset = MAC_WCID_ATTRIBUTE_BASE + (BSSID_WCID* HW_WCID_ATTRI_SIZE);
+								RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
+								// 1. IV/EIV
+								// Specify key index to find shared key.
+								IVEIV[3] = (UCHAR)(KeyIdx<< 6);	//WEP Eiv bit off. groupkey index is not 0
+								offset = PAIRWISE_IVEIV_TABLE_BASE + (BSS0Mcast_WCID * HW_IVEIV_ENTRY_SIZE);
+								offset2 = PAIRWISE_IVEIV_TABLE_BASE + (BSSID_WCID* HW_IVEIV_ENTRY_SIZE);
+								for (i=0; i<8;)
+								{
+									Value = IVEIV[i];
+									Value += (IVEIV[i+1]<<8);
+									Value += (IVEIV[i+2]<<16);
+									Value += (IVEIV[i+3]<<24);
+									RTUSBWriteMACRegister(pAd, offset+i, Value);
+									RTUSBWriteMACRegister(pAd, offset2+i, Value);
+									i+=4;
+								}
+
+								// 2. WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:use share key, BSSIdx is 0
+								WCIDAttri = (pAd->SharedKey[BSS0][KeyIdx].CipherAlg<<1)|SHAREDKEYTABLE;
+								offset = MAC_WCID_ATTRIBUTE_BASE + (BSS0Mcast_WCID* HW_WCID_ATTRI_SIZE);
+							        DBGPRINT(RT_DEBUG_TRACE, ("BSS0Mcast_WCID : offset = %x, WCIDAttri = %x\n", offset, WCIDAttri));
+								RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
+
+							}
+							AsicAddSharedKeyEntry(pAd, BSS0, (UCHAR)KeyIdx, CipherAlg, pWepKey->KeyMaterial, NULL, NULL);
+							DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::OID_802_11_ADD_WEP (KeyIdx=%d, Len=%d-byte)\n", KeyIdx, pWepKey->KeyLength));
+						}
+#endif // CONFIG_STA_SUPPORT //
+					}
+					break;
+
+				case CMDTHREAD_802_11_COUNTER_MEASURE:
+					break;
+
+				default:
+					DBGPRINT(RT_DEBUG_ERROR, ("--> Control Thread !! ERROR !! Unknown(cmdqelmt->command=0x%x) !! \n", cmdqelmt->command));
+					break;
+			}
+		}
+
+		if (cmdqelmt->CmdFromNdis == TRUE)
+		{
+				if (cmdqelmt->buffer != NULL)
+					NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
+
+			NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
+		}
+		else
+		{
+			if ((cmdqelmt->buffer != NULL) && (cmdqelmt->bufferlength != 0))
+				NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
+            {
+				NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
+			}
+		}
+	}	/* end of while */
+}
+
diff --git a/drivers/staging/rt3070/common/spectrum.c b/drivers/staging/rt3070/common/spectrum.c
new file mode 100644
index 0000000..da57b12
--- /dev/null
+++ b/drivers/staging/rt3070/common/spectrum.c
@@ -0,0 +1,1876 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+	action.c
+
+    Abstract:
+    Handle association related requests either from WSTA or from local MLME
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+	Fonchi Wu    2008	  	   created for 802.11h
+ */
+
+#include "../rt_config.h"
+#include "../action.h"
+
+VOID MeasureReqTabInit(
+	IN PRTMP_ADAPTER pAd)
+{
+	NdisAllocateSpinLock(&pAd->CommonCfg.MeasureReqTabLock);
+
+	pAd->CommonCfg.pMeasureReqTab = kmalloc(sizeof(MEASURE_REQ_TAB), GFP_ATOMIC);
+	if (pAd->CommonCfg.pMeasureReqTab)
+		NdisZeroMemory(pAd->CommonCfg.pMeasureReqTab, sizeof(MEASURE_REQ_TAB));
+	else
+		DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->CommonCfg.pMeasureReqTab.\n", __FUNCTION__));
+
+	return;
+}
+
+VOID MeasureReqTabExit(
+	IN PRTMP_ADAPTER pAd)
+{
+	NdisFreeSpinLock(pAd->CommonCfg.MeasureReqTabLock);
+
+	if (pAd->CommonCfg.pMeasureReqTab)
+		kfree(pAd->CommonCfg.pMeasureReqTab);
+	pAd->CommonCfg.pMeasureReqTab = NULL;
+
+	return;
+}
+
+static PMEASURE_REQ_ENTRY MeasureReqLookUp(
+	IN PRTMP_ADAPTER	pAd,
+	IN UINT8			DialogToken)
+{
+	UINT HashIdx;
+	PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
+	PMEASURE_REQ_ENTRY pEntry = NULL;
+	PMEASURE_REQ_ENTRY pPrevEntry = NULL;
+
+	if (pTab == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__));
+		return NULL;
+	}
+
+	RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
+
+	HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken);
+	pEntry = pTab->Hash[HashIdx];
+
+	while (pEntry)
+	{
+		if (pEntry->DialogToken == DialogToken)
+			break;
+		else
+		{
+			pPrevEntry = pEntry;
+			pEntry = pEntry->pNext;
+		}
+	}
+
+	RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
+
+	return pEntry;
+}
+
+static PMEASURE_REQ_ENTRY MeasureReqInsert(
+	IN PRTMP_ADAPTER	pAd,
+	IN UINT8			DialogToken)
+{
+	INT i;
+	ULONG HashIdx;
+	PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
+	PMEASURE_REQ_ENTRY pEntry = NULL, pCurrEntry;
+	ULONG Now;
+
+	if(pTab == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__));
+		return NULL;
+	}
+
+	pEntry = MeasureReqLookUp(pAd, DialogToken);
+	if (pEntry == NULL)
+	{
+		RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
+		for (i = 0; i < MAX_MEASURE_REQ_TAB_SIZE; i++)
+		{
+			NdisGetSystemUpTime(&Now);
+			pEntry = &pTab->Content[i];
+
+			if ((pEntry->Valid == TRUE)
+				&& RTMP_TIME_AFTER((unsigned long)Now, (unsigned long)(pEntry->lastTime + MQ_REQ_AGE_OUT)))
+			{
+				PMEASURE_REQ_ENTRY pPrevEntry = NULL;
+				ULONG HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
+				PMEASURE_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
+
+				// update Hash list
+				do
+				{
+					if (pProbeEntry == pEntry)
+					{
+						if (pPrevEntry == NULL)
+						{
+							pTab->Hash[HashIdx] = pEntry->pNext;
+						}
+						else
+						{
+							pPrevEntry->pNext = pEntry->pNext;
+						}
+						break;
+					}
+
+					pPrevEntry = pProbeEntry;
+					pProbeEntry = pProbeEntry->pNext;
+				} while (pProbeEntry);
+
+				NdisZeroMemory(pEntry, sizeof(MEASURE_REQ_ENTRY));
+				pTab->Size--;
+
+				break;
+			}
+
+			if (pEntry->Valid == FALSE)
+				break;
+		}
+
+		if (i < MAX_MEASURE_REQ_TAB_SIZE)
+		{
+			NdisGetSystemUpTime(&Now);
+			pEntry->lastTime = Now;
+			pEntry->Valid = TRUE;
+			pEntry->DialogToken = DialogToken;
+			pTab->Size++;
+		}
+		else
+		{
+			pEntry = NULL;
+			DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab tab full.\n", __FUNCTION__));
+		}
+
+		// add this Neighbor entry into HASH table
+		if (pEntry)
+		{
+			HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken);
+			if (pTab->Hash[HashIdx] == NULL)
+			{
+				pTab->Hash[HashIdx] = pEntry;
+			}
+			else
+			{
+				pCurrEntry = pTab->Hash[HashIdx];
+				while (pCurrEntry->pNext != NULL)
+					pCurrEntry = pCurrEntry->pNext;
+				pCurrEntry->pNext = pEntry;
+			}
+		}
+
+		RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
+	}
+
+	return pEntry;
+}
+
+static VOID MeasureReqDelete(
+	IN PRTMP_ADAPTER	pAd,
+	IN UINT8			DialogToken)
+{
+	PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
+	PMEASURE_REQ_ENTRY pEntry = NULL;
+
+	if(pTab == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__));
+		return;
+	}
+
+	// if empty, return
+	if (pTab->Size == 0)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("pMeasureReqTab empty.\n"));
+		return;
+	}
+
+	pEntry = MeasureReqLookUp(pAd, DialogToken);
+	if (pEntry != NULL)
+	{
+		PMEASURE_REQ_ENTRY pPrevEntry = NULL;
+		ULONG HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
+		PMEASURE_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
+
+		RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
+		// update Hash list
+		do
+		{
+			if (pProbeEntry == pEntry)
+			{
+				if (pPrevEntry == NULL)
+				{
+					pTab->Hash[HashIdx] = pEntry->pNext;
+				}
+				else
+				{
+					pPrevEntry->pNext = pEntry->pNext;
+				}
+				break;
+			}
+
+			pPrevEntry = pProbeEntry;
+			pProbeEntry = pProbeEntry->pNext;
+		} while (pProbeEntry);
+
+		NdisZeroMemory(pEntry, sizeof(MEASURE_REQ_ENTRY));
+		pTab->Size--;
+
+		RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
+	}
+
+	return;
+}
+
+VOID TpcReqTabInit(
+	IN PRTMP_ADAPTER pAd)
+{
+	NdisAllocateSpinLock(&pAd->CommonCfg.TpcReqTabLock);
+
+	pAd->CommonCfg.pTpcReqTab = kmalloc(sizeof(TPC_REQ_TAB), GFP_ATOMIC);
+	if (pAd->CommonCfg.pTpcReqTab)
+		NdisZeroMemory(pAd->CommonCfg.pTpcReqTab, sizeof(TPC_REQ_TAB));
+	else
+		DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->CommonCfg.pTpcReqTab.\n", __FUNCTION__));
+
+	return;
+}
+
+VOID TpcReqTabExit(
+	IN PRTMP_ADAPTER pAd)
+{
+	NdisFreeSpinLock(pAd->CommonCfg.TpcReqTabLock);
+
+	if (pAd->CommonCfg.pTpcReqTab)
+		kfree(pAd->CommonCfg.pTpcReqTab);
+	pAd->CommonCfg.pTpcReqTab = NULL;
+
+	return;
+}
+
+static PTPC_REQ_ENTRY TpcReqLookUp(
+	IN PRTMP_ADAPTER	pAd,
+	IN UINT8			DialogToken)
+{
+	UINT HashIdx;
+	PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
+	PTPC_REQ_ENTRY pEntry = NULL;
+	PTPC_REQ_ENTRY pPrevEntry = NULL;
+
+	if (pTab == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__));
+		return NULL;
+	}
+
+	RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
+
+	HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken);
+	pEntry = pTab->Hash[HashIdx];
+
+	while (pEntry)
+	{
+		if (pEntry->DialogToken == DialogToken)
+			break;
+		else
+		{
+			pPrevEntry = pEntry;
+			pEntry = pEntry->pNext;
+		}
+	}
+
+	RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
+
+	return pEntry;
+}
+
+
+static PTPC_REQ_ENTRY TpcReqInsert(
+	IN PRTMP_ADAPTER	pAd,
+	IN UINT8			DialogToken)
+{
+	INT i;
+	ULONG HashIdx;
+	PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
+	PTPC_REQ_ENTRY pEntry = NULL, pCurrEntry;
+	ULONG Now;
+
+	if(pTab == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__));
+		return NULL;
+	}
+
+	pEntry = TpcReqLookUp(pAd, DialogToken);
+	if (pEntry == NULL)
+	{
+		RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
+		for (i = 0; i < MAX_TPC_REQ_TAB_SIZE; i++)
+		{
+			NdisGetSystemUpTime(&Now);
+			pEntry = &pTab->Content[i];
+
+			if ((pEntry->Valid == TRUE)
+				&& RTMP_TIME_AFTER((unsigned long)Now, (unsigned long)(pEntry->lastTime + TPC_REQ_AGE_OUT)))
+			{
+				PTPC_REQ_ENTRY pPrevEntry = NULL;
+				ULONG HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
+				PTPC_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
+
+				// update Hash list
+				do
+				{
+					if (pProbeEntry == pEntry)
+					{
+						if (pPrevEntry == NULL)
+						{
+							pTab->Hash[HashIdx] = pEntry->pNext;
+						}
+						else
+						{
+							pPrevEntry->pNext = pEntry->pNext;
+						}
+						break;
+					}
+
+					pPrevEntry = pProbeEntry;
+					pProbeEntry = pProbeEntry->pNext;
+				} while (pProbeEntry);
+
+				NdisZeroMemory(pEntry, sizeof(TPC_REQ_ENTRY));
+				pTab->Size--;
+
+				break;
+			}
+
+			if (pEntry->Valid == FALSE)
+				break;
+		}
+
+		if (i < MAX_TPC_REQ_TAB_SIZE)
+		{
+			NdisGetSystemUpTime(&Now);
+			pEntry->lastTime = Now;
+			pEntry->Valid = TRUE;
+			pEntry->DialogToken = DialogToken;
+			pTab->Size++;
+		}
+		else
+		{
+			pEntry = NULL;
+			DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab tab full.\n", __FUNCTION__));
+		}
+
+		// add this Neighbor entry into HASH table
+		if (pEntry)
+		{
+			HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken);
+			if (pTab->Hash[HashIdx] == NULL)
+			{
+				pTab->Hash[HashIdx] = pEntry;
+			}
+			else
+			{
+				pCurrEntry = pTab->Hash[HashIdx];
+				while (pCurrEntry->pNext != NULL)
+					pCurrEntry = pCurrEntry->pNext;
+				pCurrEntry->pNext = pEntry;
+			}
+		}
+
+		RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
+	}
+
+	return pEntry;
+}
+
+static VOID TpcReqDelete(
+	IN PRTMP_ADAPTER	pAd,
+	IN UINT8			DialogToken)
+{
+	PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
+	PTPC_REQ_ENTRY pEntry = NULL;
+
+	if(pTab == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__));
+		return;
+	}
+
+	// if empty, return
+	if (pTab->Size == 0)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("pTpcReqTab empty.\n"));
+		return;
+	}
+
+	pEntry = TpcReqLookUp(pAd, DialogToken);
+	if (pEntry != NULL)
+	{
+		PTPC_REQ_ENTRY pPrevEntry = NULL;
+		ULONG HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
+		PTPC_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
+
+		RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
+		// update Hash list
+		do
+		{
+			if (pProbeEntry == pEntry)
+			{
+				if (pPrevEntry == NULL)
+				{
+					pTab->Hash[HashIdx] = pEntry->pNext;
+				}
+				else
+				{
+					pPrevEntry->pNext = pEntry->pNext;
+				}
+				break;
+			}
+
+			pPrevEntry = pProbeEntry;
+			pProbeEntry = pProbeEntry->pNext;
+		} while (pProbeEntry);
+
+		NdisZeroMemory(pEntry, sizeof(TPC_REQ_ENTRY));
+		pTab->Size--;
+
+		RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
+	}
+
+	return;
+}
+
+/*
+	==========================================================================
+	Description:
+		Get Current TimeS tamp.
+
+	Parametrs:
+
+	Return	: Current Time Stamp.
+	==========================================================================
+ */
+static UINT64 GetCurrentTimeStamp(
+	IN PRTMP_ADAPTER pAd)
+{
+	// get current time stamp.
+	return 0;
+}
+
+/*
+	==========================================================================
+	Description:
+		Get Current Transmit Power.
+
+	Parametrs:
+
+	Return	: Current Time Stamp.
+	==========================================================================
+ */
+static UINT8 GetCurTxPwr(
+	IN PRTMP_ADAPTER pAd,
+	IN UINT8 Wcid)
+{
+	return 16; /* 16 dBm */
+}
+
+/*
+	==========================================================================
+	Description:
+		Insert Dialog Token into frame.
+
+	Parametrs:
+		1. frame buffer pointer.
+		2. frame length.
+		3. Dialog token.
+
+	Return	: None.
+	==========================================================================
+ */
+static VOID InsertDialogToken(
+	IN PRTMP_ADAPTER pAd,
+	OUT PUCHAR pFrameBuf,
+	OUT PULONG pFrameLen,
+	IN UINT8 DialogToken)
+{
+	ULONG TempLen;
+	MakeOutgoingFrame(pFrameBuf,	&TempLen,
+					1,				&DialogToken,
+					END_OF_ARGS);
+
+	*pFrameLen = *pFrameLen + TempLen;
+
+	return;
+}
+
+/*
+	==========================================================================
+	Description:
+		Insert TPC Request IE into frame.
+
+	Parametrs:
+		1. frame buffer pointer.
+		2. frame length.
+
+	Return	: None.
+	==========================================================================
+ */
+ static VOID InsertTpcReqIE(
+	IN PRTMP_ADAPTER pAd,
+	OUT PUCHAR pFrameBuf,
+	OUT PULONG pFrameLen)
+{
+	ULONG TempLen;
+	ULONG Len = 0;
+	UINT8 ElementID = IE_TPC_REQUEST;
+
+	MakeOutgoingFrame(pFrameBuf,					&TempLen,
+						1,							&ElementID,
+						1,							&Len,
+						END_OF_ARGS);
+
+	*pFrameLen = *pFrameLen + TempLen;
+
+	return;
+}
+
+/*
+	==========================================================================
+	Description:
+		Insert TPC Report IE into frame.
+
+	Parametrs:
+		1. frame buffer pointer.
+		2. frame length.
+		3. Transmit Power.
+		4. Link Margin.
+
+	Return	: None.
+	==========================================================================
+ */
+ static VOID InsertTpcReportIE(
+	IN PRTMP_ADAPTER pAd,
+	OUT PUCHAR pFrameBuf,
+	OUT PULONG pFrameLen,
+	IN UINT8 TxPwr,
+	IN UINT8 LinkMargin)
+{
+	ULONG TempLen;
+	ULONG Len = sizeof(TPC_REPORT_INFO);
+	UINT8 ElementID = IE_TPC_REPORT;
+	TPC_REPORT_INFO TpcReportIE;
+
+	TpcReportIE.TxPwr = TxPwr;
+	TpcReportIE.LinkMargin = LinkMargin;
+
+	MakeOutgoingFrame(pFrameBuf,					&TempLen,
+						1,							&ElementID,
+						1,							&Len,
+						Len,						&TpcReportIE,
+						END_OF_ARGS);
+
+	*pFrameLen = *pFrameLen + TempLen;
+
+
+	return;
+}
+
+/*
+	==========================================================================
+	Description:
+		Insert Channel Switch Announcement IE into frame.
+
+	Parametrs:
+		1. frame buffer pointer.
+		2. frame length.
+		3. channel switch announcement mode.
+		4. new selected channel.
+		5. channel switch announcement count.
+
+	Return	: None.
+	==========================================================================
+ */
+static VOID InsertChSwAnnIE(
+	IN PRTMP_ADAPTER pAd,
+	OUT PUCHAR pFrameBuf,
+	OUT PULONG pFrameLen,
+	IN UINT8 ChSwMode,
+	IN UINT8 NewChannel,
+	IN UINT8 ChSwCnt)
+{
+	ULONG TempLen;
+	ULONG Len = sizeof(CH_SW_ANN_INFO);
+	UINT8 ElementID = IE_CHANNEL_SWITCH_ANNOUNCEMENT;
+	CH_SW_ANN_INFO ChSwAnnIE;
+
+	ChSwAnnIE.ChSwMode = ChSwMode;
+	ChSwAnnIE.Channel = NewChannel;
+	ChSwAnnIE.ChSwCnt = ChSwCnt;
+
+	MakeOutgoingFrame(pFrameBuf,				&TempLen,
+						1,						&ElementID,
+						1,						&Len,
+						Len,					&ChSwAnnIE,
+						END_OF_ARGS);
+
+	*pFrameLen = *pFrameLen + TempLen;
+
+
+	return;
+}
+
+/*
+	==========================================================================
+	Description:
+		Insert Measure Request IE into frame.
+
+	Parametrs:
+		1. frame buffer pointer.
+		2. frame length.
+		3. Measure Token.
+		4. Measure Request Mode.
+		5. Measure Request Type.
+		6. Measure Channel.
+		7. Measure Start time.
+		8. Measure Duration.
+
+
+	Return	: None.
+	==========================================================================
+ */
+static VOID InsertMeasureReqIE(
+	IN PRTMP_ADAPTER pAd,
+	OUT PUCHAR pFrameBuf,
+	OUT PULONG pFrameLen,
+	IN PMEASURE_REQ_INFO pMeasureReqIE)
+{
+	ULONG TempLen;
+	UINT8 Len = sizeof(MEASURE_REQ_INFO);
+	UINT8 ElementID = IE_MEASUREMENT_REQUEST;
+
+	MakeOutgoingFrame(pFrameBuf,					&TempLen,
+						1,							&ElementID,
+						1,							&Len,
+						Len,						pMeasureReqIE,
+						END_OF_ARGS);
+
+	*pFrameLen = *pFrameLen + TempLen;
+
+	return;
+}
+
+/*
+	==========================================================================
+	Description:
+		Insert Measure Report IE into frame.
+
+	Parametrs:
+		1. frame buffer pointer.
+		2. frame length.
+		3. Measure Token.
+		4. Measure Request Mode.
+		5. Measure Request Type.
+		6. Length of Report Infomation
+		7. Pointer of Report Infomation Buffer.
+
+	Return	: None.
+	==========================================================================
+ */
+static VOID InsertMeasureReportIE(
+	IN PRTMP_ADAPTER pAd,
+	OUT PUCHAR pFrameBuf,
+	OUT PULONG pFrameLen,
+	IN PMEASURE_REPORT_INFO pMeasureReportIE,
+	IN UINT8 ReportLnfoLen,
+	IN PUINT8 pReportInfo)
+{
+	ULONG TempLen;
+	ULONG Len;
+	UINT8 ElementID = IE_MEASUREMENT_REPORT;
+
+	Len = sizeof(MEASURE_REPORT_INFO) + ReportLnfoLen;
+
+	MakeOutgoingFrame(pFrameBuf,					&TempLen,
+						1,							&ElementID,
+						1,							&Len,
+						Len,						pMeasureReportIE,
+						END_OF_ARGS);
+
+	*pFrameLen = *pFrameLen + TempLen;
+
+	if ((ReportLnfoLen > 0) && (pReportInfo != NULL))
+	{
+		MakeOutgoingFrame(pFrameBuf + *pFrameLen,		&TempLen,
+							ReportLnfoLen,				pReportInfo,
+							END_OF_ARGS);
+
+		*pFrameLen = *pFrameLen + TempLen;
+	}
+	return;
+}
+
+/*
+	==========================================================================
+	Description:
+		Prepare Measurement request action frame and enqueue it into
+		management queue waiting for transmition.
+
+	Parametrs:
+		1. the destination mac address of the frame.
+
+	Return	: None.
+	==========================================================================
+ */
+VOID EnqueueMeasurementReq(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pDA,
+	IN UINT8 MeasureToken,
+	IN UINT8 MeasureReqMode,
+	IN UINT8 MeasureReqType,
+	IN UINT8 MeasureCh,
+	IN UINT16 MeasureDuration)
+{
+	PUCHAR pOutBuffer = NULL;
+	NDIS_STATUS NStatus;
+	ULONG FrameLen;
+	HEADER_802_11 ActHdr;
+	MEASURE_REQ_INFO MeasureReqIE;
+	UINT8 RmReqDailogToken = RandomByte(pAd);
+	UINT64 MeasureStartTime = GetCurrentTimeStamp(pAd);
+
+	// build action frame header.
+	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
+						pAd->CurrentAddress);
+
+	NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
+	if(NStatus != NDIS_STATUS_SUCCESS)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
+		return;
+	}
+	NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
+	FrameLen = sizeof(HEADER_802_11);
+
+	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_MRQ);
+
+	// fill Dialog Token
+	InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, MeasureToken);
+
+	// prepare Measurement IE.
+	NdisZeroMemory(&MeasureReqIE, sizeof(MEASURE_REQ_INFO));
+	MeasureReqIE.Token = RmReqDailogToken;
+	MeasureReqIE.ReqMode.word = MeasureReqMode;
+	MeasureReqIE.ReqType = MeasureReqType;
+	MeasureReqIE.MeasureReq.ChNum = MeasureCh;
+	MeasureReqIE.MeasureReq.MeasureStartTime = cpu2le64(MeasureStartTime);
+	MeasureReqIE.MeasureReq.MeasureDuration = cpu2le16(MeasureDuration);
+	InsertMeasureReqIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureReqIE);
+
+	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+	MlmeFreeMemory(pAd, pOutBuffer);
+
+	return;
+}
+
+/*
+	==========================================================================
+	Description:
+		Prepare Measurement report action frame and enqueue it into
+		management queue waiting for transmition.
+
+	Parametrs:
+		1. the destination mac address of the frame.
+
+	Return	: None.
+	==========================================================================
+ */
+VOID EnqueueMeasurementRep(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pDA,
+	IN UINT8 DialogToken,
+	IN UINT8 MeasureToken,
+	IN UINT8 MeasureReqMode,
+	IN UINT8 MeasureReqType,
+	IN UINT8 ReportInfoLen,
+	IN PUINT8 pReportInfo)
+{
+	PUCHAR pOutBuffer = NULL;
+	NDIS_STATUS NStatus;
+	ULONG FrameLen;
+	HEADER_802_11 ActHdr;
+	MEASURE_REPORT_INFO MeasureRepIE;
+
+	// build action frame header.
+	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
+						pAd->CurrentAddress);
+
+	NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
+	if(NStatus != NDIS_STATUS_SUCCESS)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
+		return;
+	}
+	NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
+	FrameLen = sizeof(HEADER_802_11);
+
+	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_MRP);
+
+	// fill Dialog Token
+	InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
+
+	// prepare Measurement IE.
+	NdisZeroMemory(&MeasureRepIE, sizeof(MEASURE_REPORT_INFO));
+	MeasureRepIE.Token = MeasureToken;
+	MeasureRepIE.ReportMode.word = MeasureReqMode;
+	MeasureRepIE.ReportType = MeasureReqType;
+	InsertMeasureReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureRepIE, ReportInfoLen, pReportInfo);
+
+	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+	MlmeFreeMemory(pAd, pOutBuffer);
+
+	return;
+}
+
+/*
+	==========================================================================
+	Description:
+		Prepare TPC Request action frame and enqueue it into
+		management queue waiting for transmition.
+
+	Parametrs:
+		1. the destination mac address of the frame.
+
+	Return	: None.
+	==========================================================================
+ */
+VOID EnqueueTPCReq(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pDA,
+	IN UCHAR DialogToken)
+{
+	PUCHAR pOutBuffer = NULL;
+	NDIS_STATUS NStatus;
+	ULONG FrameLen;
+
+	HEADER_802_11 ActHdr;
+
+	// build action frame header.
+	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
+						pAd->CurrentAddress);
+
+	NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
+	if(NStatus != NDIS_STATUS_SUCCESS)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
+		return;
+	}
+	NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
+	FrameLen = sizeof(HEADER_802_11);
+
+	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_TPCRQ);
+
+	// fill Dialog Token
+	InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
+
+	// Insert TPC Request IE.
+	InsertTpcReqIE(pAd, (pOutBuffer + FrameLen), &FrameLen);
+
+	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+	MlmeFreeMemory(pAd, pOutBuffer);
+
+	return;
+}
+
+/*
+	==========================================================================
+	Description:
+		Prepare TPC Report action frame and enqueue it into
+		management queue waiting for transmition.
+
+	Parametrs:
+		1. the destination mac address of the frame.
+
+	Return	: None.
+	==========================================================================
+ */
+VOID EnqueueTPCRep(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pDA,
+	IN UINT8 DialogToken,
+	IN UINT8 TxPwr,
+	IN UINT8 LinkMargin)
+{
+	PUCHAR pOutBuffer = NULL;
+	NDIS_STATUS NStatus;
+	ULONG FrameLen;
+
+	HEADER_802_11 ActHdr;
+
+	// build action frame header.
+	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
+						pAd->CurrentAddress);
+
+	NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
+	if(NStatus != NDIS_STATUS_SUCCESS)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
+		return;
+	}
+	NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
+	FrameLen = sizeof(HEADER_802_11);
+
+	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_TPCRP);
+
+	// fill Dialog Token
+	InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
+
+	// Insert TPC Request IE.
+	InsertTpcReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, TxPwr, LinkMargin);
+
+	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+	MlmeFreeMemory(pAd, pOutBuffer);
+
+	return;
+}
+
+/*
+	==========================================================================
+	Description:
+		Prepare Channel Switch Announcement action frame and enqueue it into
+		management queue waiting for transmition.
+
+	Parametrs:
+		1. the destination mac address of the frame.
+		2. Channel switch announcement mode.
+		2. a New selected channel.
+
+	Return	: None.
+	==========================================================================
+ */
+VOID EnqueueChSwAnn(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pDA,
+	IN UINT8 ChSwMode,
+	IN UINT8 NewCh)
+{
+	PUCHAR pOutBuffer = NULL;
+	NDIS_STATUS NStatus;
+	ULONG FrameLen;
+
+	HEADER_802_11 ActHdr;
+
+	// build action frame header.
+	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
+						pAd->CurrentAddress);
+
+	NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
+	if(NStatus != NDIS_STATUS_SUCCESS)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
+		return;
+	}
+	NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
+	FrameLen = sizeof(HEADER_802_11);
+
+	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_CHANNEL_SWITCH);
+
+	InsertChSwAnnIE(pAd, (pOutBuffer + FrameLen), &FrameLen, ChSwMode, NewCh, 0);
+
+	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+	MlmeFreeMemory(pAd, pOutBuffer);
+
+	return;
+}
+
+static BOOLEAN DfsRequirementCheck(
+	IN PRTMP_ADAPTER pAd,
+	IN UINT8 Channel)
+{
+	BOOLEAN Result = FALSE;
+	INT i;
+
+	do
+	{
+		// check DFS procedure is running.
+		// make sure DFS procedure won't start twice.
+		if (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
+		{
+			Result = FALSE;
+			break;
+		}
+
+		// check the new channel carried from Channel Switch Announcemnet is valid.
+		for (i=0; i<pAd->ChannelListNum; i++)
+		{
+			if ((Channel == pAd->ChannelList[i].Channel)
+				&&(pAd->ChannelList[i].RemainingTimeForUse == 0))
+			{
+				// found radar signal in the channel. the channel can't use at least for 30 minutes.
+				pAd->ChannelList[i].RemainingTimeForUse = 1800;//30 min = 1800 sec
+				Result = TRUE;
+				break;
+			}
+		}
+	} while(FALSE);
+
+	return Result;
+}
+
+VOID NotifyChSwAnnToPeerAPs(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pRA,
+	IN PUCHAR pTA,
+	IN UINT8 ChSwMode,
+	IN UINT8 Channel)
+{
+#ifdef WDS_SUPPORT
+	if (!((pRA[0] & 0xff) == 0xff)) // is pRA a broadcase address.
+	{
+		INT i;
+		// info neighbor APs that Radar signal found throgh WDS link.
+		for (i = 0; i < MAX_WDS_ENTRY; i++)
+		{
+			if (ValidWdsEntry(pAd, i))
+			{
+				PUCHAR pDA = pAd->WdsTab.WdsEntry[i].PeerWdsAddr;
+
+				// DA equal to SA. have no necessary orignal AP which found Radar signal.
+				if (MAC_ADDR_EQUAL(pTA, pDA))
+					continue;
+
+				// send Channel Switch Action frame to info Neighbro APs.
+				EnqueueChSwAnn(pAd, pDA, ChSwMode, Channel);
+			}
+		}
+	}
+#endif // WDS_SUPPORT //
+}
+
+static VOID StartDFSProcedure(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR Channel,
+	IN UINT8 ChSwMode)
+{
+	// start DFS procedure
+	pAd->CommonCfg.Channel = Channel;
+#ifdef DOT11_N_SUPPORT
+	N_ChannelCheck(pAd);
+#endif // DOT11_N_SUPPORT //
+	pAd->CommonCfg.RadarDetect.RDMode = RD_SWITCHING_MODE;
+	pAd->CommonCfg.RadarDetect.CSCount = 0;
+}
+
+/*
+	==========================================================================
+	Description:
+		Channel Switch Announcement action frame sanity check.
+
+	Parametrs:
+		1. MLME message containing the received frame
+		2. message length.
+		3. Channel switch announcement infomation buffer.
+
+
+	Return	: None.
+	==========================================================================
+ */
+
+/*
+  Channel Switch Announcement IE.
+  +----+-----+-----------+------------+-----------+
+  | ID | Len |Ch Sw Mode | New Ch Num | Ch Sw Cnt |
+  +----+-----+-----------+------------+-----------+
+    1    1        1           1            1
+*/
+static BOOLEAN PeerChSwAnnSanity(
+	IN PRTMP_ADAPTER pAd,
+	IN VOID *pMsg,
+	IN ULONG MsgLen,
+	OUT PCH_SW_ANN_INFO pChSwAnnInfo)
+{
+	PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
+	PUCHAR pFramePtr = Fr->Octet;
+	BOOLEAN result = FALSE;
+	PEID_STRUCT eid_ptr;
+
+	// skip 802.11 header.
+	MsgLen -= sizeof(HEADER_802_11);
+
+	// skip category and action code.
+	pFramePtr += 2;
+	MsgLen -= 2;
+
+	if (pChSwAnnInfo == NULL)
+		return result;
+
+	eid_ptr = (PEID_STRUCT)pFramePtr;
+	while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
+	{
+		switch(eid_ptr->Eid)
+		{
+			case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
+				NdisMoveMemory(&pChSwAnnInfo->ChSwMode, eid_ptr->Octet, 1);
+				NdisMoveMemory(&pChSwAnnInfo->Channel, eid_ptr->Octet + 1, 1);
+				NdisMoveMemory(&pChSwAnnInfo->ChSwCnt, eid_ptr->Octet + 2, 1);
+
+				result = TRUE;
+                break;
+
+			default:
+				break;
+		}
+		eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+	}
+
+	return result;
+}
+
+/*
+	==========================================================================
+	Description:
+		Measurement request action frame sanity check.
+
+	Parametrs:
+		1. MLME message containing the received frame
+		2. message length.
+		3. Measurement request infomation buffer.
+
+	Return	: None.
+	==========================================================================
+ */
+static BOOLEAN PeerMeasureReqSanity(
+	IN PRTMP_ADAPTER pAd,
+	IN VOID *pMsg,
+	IN ULONG MsgLen,
+	OUT PUINT8 pDialogToken,
+	OUT PMEASURE_REQ_INFO pMeasureReqInfo)
+{
+	PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
+	PUCHAR pFramePtr = Fr->Octet;
+	BOOLEAN result = FALSE;
+	PEID_STRUCT eid_ptr;
+	PUCHAR ptr;
+	UINT64 MeasureStartTime;
+	UINT16 MeasureDuration;
+
+	// skip 802.11 header.
+	MsgLen -= sizeof(HEADER_802_11);
+
+	// skip category and action code.
+	pFramePtr += 2;
+	MsgLen -= 2;
+
+	if (pMeasureReqInfo == NULL)
+		return result;
+
+	NdisMoveMemory(pDialogToken, pFramePtr, 1);
+	pFramePtr += 1;
+	MsgLen -= 1;
+
+	eid_ptr = (PEID_STRUCT)pFramePtr;
+	while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
+	{
+		switch(eid_ptr->Eid)
+		{
+			case IE_MEASUREMENT_REQUEST:
+				NdisMoveMemory(&pMeasureReqInfo->Token, eid_ptr->Octet, 1);
+				NdisMoveMemory(&pMeasureReqInfo->ReqMode.word, eid_ptr->Octet + 1, 1);
+				NdisMoveMemory(&pMeasureReqInfo->ReqType, eid_ptr->Octet + 2, 1);
+				ptr = eid_ptr->Octet + 3;
+				NdisMoveMemory(&pMeasureReqInfo->MeasureReq.ChNum, ptr, 1);
+				NdisMoveMemory(&MeasureStartTime, ptr + 1, 8);
+				pMeasureReqInfo->MeasureReq.MeasureStartTime = SWAP64(MeasureStartTime);
+				NdisMoveMemory(&MeasureDuration, ptr + 9, 2);
+				pMeasureReqInfo->MeasureReq.MeasureDuration = SWAP16(MeasureDuration);
+
+				result = TRUE;
+				break;
+
+			default:
+				break;
+		}
+		eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+	}
+
+	return result;
+}
+
+/*
+	==========================================================================
+	Description:
+		Measurement report action frame sanity check.
+
+	Parametrs:
+		1. MLME message containing the received frame
+		2. message length.
+		3. Measurement report infomation buffer.
+		4. basic report infomation buffer.
+
+	Return	: None.
+	==========================================================================
+ */
+
+/*
+  Measurement Report IE.
+  +----+-----+-------+-------------+--------------+----------------+
+  | ID | Len | Token | Report Mode | Measure Type | Measure Report |
+  +----+-----+-------+-------------+--------------+----------------+
+    1     1      1          1             1            variable
+
+  Basic Report.
+  +--------+------------+----------+-----+
+  | Ch Num | Start Time | Duration | Map |
+  +--------+------------+----------+-----+
+      1          8           2        1
+
+  Map Field Bit Format.
+  +-----+---------------+---------------------+-------+------------+----------+
+  | Bss | OFDM Preamble | Unidentified signal | Radar | Unmeasured | Reserved |
+  +-----+---------------+---------------------+-------+------------+----------+
+     0          1                  2              3         4          5-7
+*/
+static BOOLEAN PeerMeasureReportSanity(
+	IN PRTMP_ADAPTER pAd,
+	IN VOID *pMsg,
+	IN ULONG MsgLen,
+	OUT PUINT8 pDialogToken,
+	OUT PMEASURE_REPORT_INFO pMeasureReportInfo,
+	OUT PUINT8 pReportBuf)
+{
+	PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
+	PUCHAR pFramePtr = Fr->Octet;
+	BOOLEAN result = FALSE;
+	PEID_STRUCT eid_ptr;
+	PUCHAR ptr;
+
+	// skip 802.11 header.
+	MsgLen -= sizeof(HEADER_802_11);
+
+	// skip category and action code.
+	pFramePtr += 2;
+	MsgLen -= 2;
+
+	if (pMeasureReportInfo == NULL)
+		return result;
+
+	NdisMoveMemory(pDialogToken, pFramePtr, 1);
+	pFramePtr += 1;
+	MsgLen -= 1;
+
+	eid_ptr = (PEID_STRUCT)pFramePtr;
+	while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
+	{
+		switch(eid_ptr->Eid)
+		{
+			case IE_MEASUREMENT_REPORT:
+				NdisMoveMemory(&pMeasureReportInfo->Token, eid_ptr->Octet, 1);
+				NdisMoveMemory(&pMeasureReportInfo->ReportMode, eid_ptr->Octet + 1, 1);
+				NdisMoveMemory(&pMeasureReportInfo->ReportType, eid_ptr->Octet + 2, 1);
+				if (pMeasureReportInfo->ReportType == RM_BASIC)
+				{
+					PMEASURE_BASIC_REPORT pReport = (PMEASURE_BASIC_REPORT)pReportBuf;
+					ptr = eid_ptr->Octet + 3;
+					NdisMoveMemory(&pReport->ChNum, ptr, 1);
+					NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
+					NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
+					NdisMoveMemory(&pReport->Map, ptr + 11, 1);
+
+				}
+				else if (pMeasureReportInfo->ReportType == RM_CCA)
+				{
+					PMEASURE_CCA_REPORT pReport = (PMEASURE_CCA_REPORT)pReportBuf;
+					ptr = eid_ptr->Octet + 3;
+					NdisMoveMemory(&pReport->ChNum, ptr, 1);
+					NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
+					NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
+					NdisMoveMemory(&pReport->CCA_Busy_Fraction, ptr + 11, 1);
+
+				}
+				else if (pMeasureReportInfo->ReportType == RM_RPI_HISTOGRAM)
+				{
+					PMEASURE_RPI_REPORT pReport = (PMEASURE_RPI_REPORT)pReportBuf;
+					ptr = eid_ptr->Octet + 3;
+					NdisMoveMemory(&pReport->ChNum, ptr, 1);
+					NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
+					NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
+					NdisMoveMemory(&pReport->RPI_Density, ptr + 11, 8);
+				}
+				result = TRUE;
+                break;
+
+			default:
+				break;
+		}
+		eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+	}
+
+	return result;
+}
+
+/*
+	==========================================================================
+	Description:
+		TPC Request action frame sanity check.
+
+	Parametrs:
+		1. MLME message containing the received frame
+		2. message length.
+		3. Dialog Token.
+
+	Return	: None.
+	==========================================================================
+ */
+static BOOLEAN PeerTpcReqSanity(
+	IN PRTMP_ADAPTER pAd,
+	IN VOID *pMsg,
+	IN ULONG MsgLen,
+	OUT PUINT8 pDialogToken)
+{
+	PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
+	PUCHAR pFramePtr = Fr->Octet;
+	BOOLEAN result = FALSE;
+	PEID_STRUCT eid_ptr;
+
+	MsgLen -= sizeof(HEADER_802_11);
+
+	// skip category and action code.
+	pFramePtr += 2;
+	MsgLen -= 2;
+
+	if (pDialogToken == NULL)
+		return result;
+
+	NdisMoveMemory(pDialogToken, pFramePtr, 1);
+	pFramePtr += 1;
+	MsgLen -= 1;
+
+	eid_ptr = (PEID_STRUCT)pFramePtr;
+	while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
+	{
+		switch(eid_ptr->Eid)
+		{
+			case IE_TPC_REQUEST:
+				result = TRUE;
+                break;
+
+			default:
+				break;
+		}
+		eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+	}
+
+	return result;
+}
+
+/*
+	==========================================================================
+	Description:
+		TPC Report action frame sanity check.
+
+	Parametrs:
+		1. MLME message containing the received frame
+		2. message length.
+		3. Dialog Token.
+		4. TPC Report IE.
+
+	Return	: None.
+	==========================================================================
+ */
+static BOOLEAN PeerTpcRepSanity(
+	IN PRTMP_ADAPTER pAd,
+	IN VOID *pMsg,
+	IN ULONG MsgLen,
+	OUT PUINT8 pDialogToken,
+	OUT PTPC_REPORT_INFO pTpcRepInfo)
+{
+	PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
+	PUCHAR pFramePtr = Fr->Octet;
+	BOOLEAN result = FALSE;
+	PEID_STRUCT eid_ptr;
+
+	MsgLen -= sizeof(HEADER_802_11);
+
+	// skip category and action code.
+	pFramePtr += 2;
+	MsgLen -= 2;
+
+	if (pDialogToken == NULL)
+		return result;
+
+	NdisMoveMemory(pDialogToken, pFramePtr, 1);
+	pFramePtr += 1;
+	MsgLen -= 1;
+
+	eid_ptr = (PEID_STRUCT)pFramePtr;
+	while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
+	{
+		switch(eid_ptr->Eid)
+		{
+			case IE_TPC_REPORT:
+				NdisMoveMemory(&pTpcRepInfo->TxPwr, eid_ptr->Octet, 1);
+				NdisMoveMemory(&pTpcRepInfo->LinkMargin, eid_ptr->Octet + 1, 1);
+				result = TRUE;
+                break;
+
+			default:
+				break;
+		}
+		eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+	}
+
+	return result;
+}
+
+/*
+	==========================================================================
+	Description:
+		Channel Switch Announcement action frame handler.
+
+	Parametrs:
+		Elme - MLME message containing the received frame
+
+	Return	: None.
+	==========================================================================
+ */
+static VOID PeerChSwAnnAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	CH_SW_ANN_INFO ChSwAnnInfo;
+	PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
+#ifdef CONFIG_STA_SUPPORT
+	UCHAR index = 0, Channel = 0, NewChannel = 0;
+	ULONG Bssidx = 0;
+#endif // CONFIG_STA_SUPPORT //
+
+	NdisZeroMemory(&ChSwAnnInfo, sizeof(CH_SW_ANN_INFO));
+	if (! PeerChSwAnnSanity(pAd, Elem->Msg, Elem->MsgLen, &ChSwAnnInfo))
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("Invalid Channel Switch Action Frame.\n"));
+		return;
+	}
+
+
+#ifdef CONFIG_STA_SUPPORT
+	if (pAd->OpMode == OPMODE_STA)
+	{
+		Bssidx = BssTableSearch(&pAd->ScanTab, pFr->Hdr.Addr3, pAd->CommonCfg.Channel);
+		if (Bssidx == BSS_NOT_FOUND)
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("PeerChSwAnnAction - Bssidx is not found\n"));
+			return;
+		}
+
+		DBGPRINT(RT_DEBUG_TRACE, ("\n****Bssidx is %d, Channel = %d\n", index, pAd->ScanTab.BssEntry[Bssidx].Channel));
+		hex_dump("SSID",pAd->ScanTab.BssEntry[Bssidx].Bssid ,6);
+
+		Channel = pAd->CommonCfg.Channel;
+		NewChannel = ChSwAnnInfo.Channel;
+
+		if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) && (Channel != NewChannel))
+		{
+			// Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection).
+			// In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results.
+			AsicSwitchChannel(pAd, 1, FALSE);
+			AsicLockChannel(pAd, 1);
+		    LinkDown(pAd, FALSE);
+			MlmeQueueInit(&pAd->Mlme.Queue);
+			BssTableInit(&pAd->ScanTab);
+		    RTMPusecDelay(1000000);		// use delay to prevent STA do reassoc
+
+			// channel sanity check
+			for (index = 0 ; index < pAd->ChannelListNum; index++)
+			{
+				if (pAd->ChannelList[index].Channel == NewChannel)
+				{
+					pAd->ScanTab.BssEntry[Bssidx].Channel = NewChannel;
+					pAd->CommonCfg.Channel = NewChannel;
+					AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+					AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+					DBGPRINT(RT_DEBUG_TRACE, ("&&&&&&&&&&&&&&&&PeerChSwAnnAction - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel));
+					break;
+				}
+			}
+
+			if (index >= pAd->ChannelListNum)
+			{
+				DBGPRINT_ERR(("&&&&&&&&&&&&&&&&&&&&&&&&&&PeerChSwAnnAction(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum));
+			}
+		}
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	return;
+}
+
+
+/*
+	==========================================================================
+	Description:
+		Measurement Request action frame handler.
+
+	Parametrs:
+		Elme - MLME message containing the received frame
+
+	Return	: None.
+	==========================================================================
+ */
+static VOID PeerMeasureReqAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
+	UINT8 DialogToken;
+	MEASURE_REQ_INFO MeasureReqInfo;
+	MEASURE_REPORT_MODE ReportMode;
+
+	if(PeerMeasureReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReqInfo))
+	{
+		ReportMode.word = 0;
+		ReportMode.field.Incapable = 1;
+		EnqueueMeasurementRep(pAd, pFr->Hdr.Addr2, DialogToken, MeasureReqInfo.Token, ReportMode.word, MeasureReqInfo.ReqType, 0, NULL);
+	}
+
+	return;
+}
+
+/*
+	==========================================================================
+	Description:
+		Measurement Report action frame handler.
+
+	Parametrs:
+		Elme - MLME message containing the received frame
+
+	Return	: None.
+	==========================================================================
+ */
+static VOID PeerMeasureReportAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	MEASURE_REPORT_INFO MeasureReportInfo;
+	PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
+	UINT8 DialogToken;
+	PUINT8 pMeasureReportInfo;
+
+//	if (pAd->CommonCfg.bIEEE80211H != TRUE)
+//		return;
+
+	if ((pMeasureReportInfo = kmalloc(sizeof(MEASURE_RPI_REPORT), GFP_ATOMIC)) == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%d).\n", __FUNCTION__, sizeof(MEASURE_RPI_REPORT)));
+		return;
+	}
+
+	NdisZeroMemory(&MeasureReportInfo, sizeof(MEASURE_REPORT_INFO));
+	NdisZeroMemory(pMeasureReportInfo, sizeof(MEASURE_RPI_REPORT));
+	if (PeerMeasureReportSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReportInfo, pMeasureReportInfo))
+	{
+		do {
+			PMEASURE_REQ_ENTRY pEntry = NULL;
+
+			// Not a autonomous measure report.
+			// check the dialog token field. drop it if the dialog token doesn't match.
+			if ((DialogToken != 0)
+				&& ((pEntry = MeasureReqLookUp(pAd, DialogToken)) == NULL))
+				break;
+
+			if (pEntry != NULL)
+				MeasureReqDelete(pAd, pEntry->DialogToken);
+
+			if (MeasureReportInfo.ReportType == RM_BASIC)
+			{
+				PMEASURE_BASIC_REPORT pBasicReport = (PMEASURE_BASIC_REPORT)pMeasureReportInfo;
+				if ((pBasicReport->Map.field.Radar)
+					&& (DfsRequirementCheck(pAd, pBasicReport->ChNum) == TRUE))
+				{
+					NotifyChSwAnnToPeerAPs(pAd, pFr->Hdr.Addr1, pFr->Hdr.Addr2, 1, pBasicReport->ChNum);
+					StartDFSProcedure(pAd, pBasicReport->ChNum, 1);
+				}
+			}
+		} while (FALSE);
+	}
+	else
+		DBGPRINT(RT_DEBUG_TRACE, ("Invalid Measurement Report Frame.\n"));
+
+	kfree(pMeasureReportInfo);
+
+	return;
+}
+
+/*
+	==========================================================================
+	Description:
+		TPC Request action frame handler.
+
+	Parametrs:
+		Elme - MLME message containing the received frame
+
+	Return	: None.
+	==========================================================================
+ */
+static VOID PeerTpcReqAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
+	PUCHAR pFramePtr = pFr->Octet;
+	UINT8 DialogToken;
+	UINT8 TxPwr = GetCurTxPwr(pAd, Elem->Wcid);
+	UINT8 LinkMargin = 0;
+	CHAR RealRssi;
+
+	// link margin: Ratio of the received signal power to the minimum desired by the station (STA). The
+	//				STA may incorporate rate information and channel conditions, including interference, into its computation
+	//				of link margin.
+
+	RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0),
+								ConvertToRssi(pAd, Elem->Rssi1, RSSI_1),
+								ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
+
+	// skip Category and action code.
+	pFramePtr += 2;
+
+	// Dialog token.
+	NdisMoveMemory(&DialogToken, pFramePtr, 1);
+
+	LinkMargin = (RealRssi / MIN_RCV_PWR);
+	if (PeerTpcReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken))
+		EnqueueTPCRep(pAd, pFr->Hdr.Addr2, DialogToken, TxPwr, LinkMargin);
+
+	return;
+}
+
+/*
+	==========================================================================
+	Description:
+		TPC Report action frame handler.
+
+	Parametrs:
+		Elme - MLME message containing the received frame
+
+	Return	: None.
+	==========================================================================
+ */
+static VOID PeerTpcRepAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	UINT8 DialogToken;
+	TPC_REPORT_INFO TpcRepInfo;
+	PTPC_REQ_ENTRY pEntry = NULL;
+
+	NdisZeroMemory(&TpcRepInfo, sizeof(TPC_REPORT_INFO));
+	if (PeerTpcRepSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &TpcRepInfo))
+	{
+		if ((pEntry = TpcReqLookUp(pAd, DialogToken)) != NULL)
+		{
+			TpcReqDelete(pAd, pEntry->DialogToken);
+			DBGPRINT(RT_DEBUG_TRACE, ("%s: DialogToken=%x, TxPwr=%d, LinkMargin=%d\n",
+				__FUNCTION__, DialogToken, TpcRepInfo.TxPwr, TpcRepInfo.LinkMargin));
+		}
+	}
+
+	return;
+}
+
+/*
+	==========================================================================
+	Description:
+		Spectrun action frames Handler such as channel switch annoucement,
+		measurement report, measurement request actions frames.
+
+	Parametrs:
+		Elme - MLME message containing the received frame
+
+	Return	: None.
+	==========================================================================
+ */
+VOID PeerSpectrumAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+
+	UCHAR	Action = Elem->Msg[LENGTH_802_11+1];
+
+	if (pAd->CommonCfg.bIEEE80211H != TRUE)
+		return;
+
+	switch(Action)
+	{
+		case SPEC_MRQ:
+			// current rt2860 unable do such measure specified in Measurement Request.
+			// reject all measurement request.
+			PeerMeasureReqAction(pAd, Elem);
+			break;
+
+		case SPEC_MRP:
+			PeerMeasureReportAction(pAd, Elem);
+			break;
+
+		case SPEC_TPCRQ:
+			PeerTpcReqAction(pAd, Elem);
+			break;
+
+		case SPEC_TPCRP:
+			PeerTpcRepAction(pAd, Elem);
+			break;
+
+		case SPEC_CHANNEL_SWITCH:
+{
+#ifdef DOT11N_DRAFT3
+				SEC_CHA_OFFSET_IE	Secondary;
+				CHA_SWITCH_ANNOUNCE_IE	ChannelSwitch;
+
+				// 802.11h only has Channel Switch Announcement IE.
+				RTMPMoveMemory(&ChannelSwitch, &Elem->Msg[LENGTH_802_11+4], sizeof (CHA_SWITCH_ANNOUNCE_IE));
+
+				// 802.11n D3.03 adds secondary channel offset element in the end.
+				if (Elem->MsgLen ==  (LENGTH_802_11 + 2 + sizeof (CHA_SWITCH_ANNOUNCE_IE) + sizeof (SEC_CHA_OFFSET_IE)))
+				{
+					RTMPMoveMemory(&Secondary, &Elem->Msg[LENGTH_802_11+9], sizeof (SEC_CHA_OFFSET_IE));
+				}
+				else
+				{
+					Secondary.SecondaryChannelOffset = 0;
+				}
+
+				if ((Elem->Msg[LENGTH_802_11+2] == IE_CHANNEL_SWITCH_ANNOUNCEMENT) && (Elem->Msg[LENGTH_802_11+3] == 3))
+				{
+					ChannelSwitchAction(pAd, Elem->Wcid, ChannelSwitch.NewChannel, Secondary.SecondaryChannelOffset);
+				}
+#endif // DOT11N_DRAFT3 //
+}
+			PeerChSwAnnAction(pAd, Elem);
+			break;
+	}
+
+	return;
+}
+
+/*
+	==========================================================================
+	Description:
+
+	Parametrs:
+
+	Return	: None.
+	==========================================================================
+ */
+INT Set_MeasureReq_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	UINT Aid = 1;
+	UINT ArgIdx;
+	PUCHAR thisChar;
+
+	MEASURE_REQ_MODE MeasureReqMode;
+	UINT8 MeasureReqToken = RandomByte(pAd);
+	UINT8 MeasureReqType = RM_BASIC;
+	UINT8 MeasureCh = 1;
+
+	ArgIdx = 1;
+	while ((thisChar = strsep((char **)&arg, "-")) != NULL)
+	{
+		switch(ArgIdx)
+		{
+			case 1:	// Aid.
+				Aid = simple_strtol(thisChar, 0, 16);
+				break;
+
+			case 2: // Measurement Request Type.
+				MeasureReqType = simple_strtol(thisChar, 0, 16);
+				if (MeasureReqType > 3)
+				{
+					DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow MeasureReqType(%d)\n", __FUNCTION__, MeasureReqType));
+					return TRUE;
+				}
+				break;
+
+			case 3: // Measurement channel.
+				MeasureCh = simple_strtol(thisChar, 0, 16);
+				break;
+		}
+		ArgIdx++;
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d, MeasureReqType=%d MeasureCh=%d\n", __FUNCTION__, Aid, MeasureReqType, MeasureCh));
+	if (!VALID_WCID(Aid))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __FUNCTION__, Aid));
+		return TRUE;
+	}
+
+	MeasureReqMode.word = 0;
+	MeasureReqMode.field.Enable = 1;
+
+	MeasureReqInsert(pAd, MeasureReqToken);
+
+	EnqueueMeasurementReq(pAd, pAd->MacTab.Content[Aid].Addr,
+		MeasureReqToken, MeasureReqMode.word, MeasureReqType, MeasureCh, 2000);
+
+	return TRUE;
+}
+
+INT Set_TpcReq_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	UINT Aid;
+
+	UINT8 TpcReqToken = RandomByte(pAd);
+
+	Aid = simple_strtol(arg, 0, 16);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d\n", __FUNCTION__, Aid));
+	if (!VALID_WCID(Aid))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __FUNCTION__, Aid));
+		return TRUE;
+	}
+
+	TpcReqInsert(pAd, TpcReqToken);
+
+	EnqueueTPCReq(pAd, pAd->MacTab.Content[Aid].Addr, TpcReqToken);
+
+	return TRUE;
+}
+
diff --git a/drivers/staging/rt3070/dfs.h b/drivers/staging/rt3070/dfs.h
new file mode 100644
index 0000000..752a635
--- /dev/null
+++ b/drivers/staging/rt3070/dfs.h
@@ -0,0 +1,100 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+    dfs.h
+
+    Abstract:
+    Support DFS function.
+
+    Revision History:
+    Who       When            What
+    --------  ----------      ----------------------------------------------
+    Fonchi    03-12-2007      created
+*/
+
+#define RADAR_PULSE 1
+#define RADAR_WIDTH 2
+
+#define WIDTH_RD_IDLE 0
+#define WIDTH_RD_CHECK 1
+
+
+VOID BbpRadarDetectionStart(
+	IN PRTMP_ADAPTER pAd);
+
+VOID BbpRadarDetectionStop(
+	IN PRTMP_ADAPTER pAd);
+
+VOID RadarDetectionStart(
+	IN PRTMP_ADAPTER pAd,
+	IN BOOLEAN CTS_Protect,
+	IN UINT8 CTSPeriod);
+
+VOID RadarDetectionStop(
+	IN PRTMP_ADAPTER	pAd);
+
+VOID RadarDetectPeriodic(
+	IN PRTMP_ADAPTER	pAd);
+
+
+BOOLEAN RadarChannelCheck(
+	IN PRTMP_ADAPTER	pAd,
+	IN UCHAR			Ch);
+
+ULONG JapRadarType(
+	IN PRTMP_ADAPTER pAd);
+
+ULONG RTMPBbpReadRadarDuration(
+	IN PRTMP_ADAPTER	pAd);
+
+ULONG RTMPReadRadarDuration(
+	IN PRTMP_ADAPTER	pAd);
+
+VOID RTMPCleanRadarDuration(
+	IN PRTMP_ADAPTER	pAd);
+
+VOID RTMPPrepareRDCTSFrame(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pDA,
+	IN	ULONG			Duration,
+	IN  UCHAR           RTSRate,
+	IN  ULONG           CTSBaseAddr,
+	IN  UCHAR			FrameGap);
+
+VOID RTMPPrepareRadarDetectParams(
+	IN PRTMP_ADAPTER	pAd);
+
+
+INT Set_ChMovingTime_Proc(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR arg);
+
+INT Set_LongPulseRadarTh_Proc(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR arg);
+
+
diff --git a/drivers/staging/rt3070/firmware.h b/drivers/staging/rt3070/firmware.h
new file mode 100644
index 0000000..b07783e
--- /dev/null
+++ b/drivers/staging/rt3070/firmware.h
@@ -0,0 +1,558 @@
+/*
+ Copyright (c) 2007, Ralink Technology Corporation
+ All rights reserved.
+
+ Redistribution.  Redistribution and use in binary form, without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ 	* Redistributions must reproduce the above copyright notice and the
+ 	following disclaimer in the documentation and/or other materials
+ 	provided with the distribution.
+ 	* Neither the name of Ralink Technology Corporation nor the names of its
+ 	suppliers may be used to endorse or promote products derived from this
+ 	software without specific prior written permission.
+ 	* No reverse engineering, decompilation, or disassembly of this software
+ 	is permitted.
+
+ Limited patent license. Ralink Technology Corporation grants a world-wide,
+ royalty-free, non-exclusive license under patents it now or hereafter
+ owns or controls to make, have made, use, import, offer to sell and
+ sell ("Utilize") this software, but solely to the extent that any
+ such patent is necessary to Utilize the software alone, or in
+ combination with an operating system licensed under an approved Open
+ Source license as listed by the Open Source Initiative at
+ http://opensource.org/licenses.  The patent license shall not apply to
+ any other combinations which include this software.  No hardware per
+ se is licensed hereunder.
+
+ DISCLAIMER.  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.
+*/
+/* AUTO GEN PLEASE DO NOT MODIFY IT */
+/* AUTO GEN PLEASE DO NOT MODIFY IT */
+
+
+UCHAR FirmwareImage [] = {
+0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x12, 0x67, 0x02,
+0x12, 0x68, 0x02, 0x12, 0x87, 0x02, 0x12, 0x8c, 0x12, 0x12, 0x88, 0x22, 0x02, 0x16, 0x49, 0x02,
+0x17, 0x1f, 0x02, 0x13, 0x77, 0x02, 0x12, 0x8d, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x17,
+0xc1, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x1b, 0xe5, 0x4c, 0x30, 0xe0, 0x04, 0x7f, 0x40,
+0x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, 0x8c, 0x74, 0x08, 0xf0, 0xe4,
+0x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, 0x90, 0x01, 0x80, 0xe0, 0xb4,
+0x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, 0xb4, 0x81, 0x09, 0x90, 0x01,
+0x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xc8, 0x22, 0x90, 0x04, 0x14, 0xe0, 0x20, 0xe7, 0x03, 0x02,
+0x12, 0x66, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0x9d, 0x10,
+0xb7, 0x31, 0x10, 0xe0, 0x50, 0x11, 0x04, 0x51, 0x11, 0x0d, 0x52, 0x11, 0x0d, 0x53, 0x11, 0x0d,
+0x54, 0x11, 0x4e, 0x55, 0x11, 0x7e, 0x70, 0x11, 0xa9, 0x71, 0x11, 0xd7, 0x72, 0x12, 0x1d, 0x73,
+0x12, 0x3e, 0x80, 0x00, 0x00, 0x12, 0x66, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d, 0x02, 0xaf,
+0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5,
+0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x85, 0x56, 0x41, 0xd2, 0x02, 0x22,
+0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60, 0x03, 0x02, 0x12, 0x66, 0x90, 0x70, 0x11,
+0xe0, 0x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60, 0x03, 0x02, 0x12, 0x66, 0x75, 0x4e, 0x03,
+0x75, 0x4f, 0x20, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x47, 0x22, 0x90, 0x04, 0x04,
+0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0, 0xff, 0x74, 0x47, 0x25, 0x57,
+0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48, 0x25, 0x57, 0xf8, 0xc6, 0xef,
+0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90,
+0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0xe5, 0x47,
+0x64, 0x07, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0x90,
+0x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03,
+0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0xd2, 0x04, 0x22, 0x90, 0x70,
+0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56,
+0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56,
+0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70,
+0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b,
+0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70,
+0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x10, 0x02, 0xe0, 0xb4, 0x70, 0x1e, 0xa3, 0xe0,
+0xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd, 0x90, 0x05, 0x05, 0xe0, 0x54,
+0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, 0x08, 0xf0, 0xe4, 0xf5, 0x4e, 0xf5,
+0x4f, 0x75, 0x3a, 0xff, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80,
+0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x4b, 0x80, 0x42, 0x90, 0x70, 0x10,
+0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74,
+0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70,
+0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90,
+0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90,
+0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22, 0xe5, 0x53, 0x70, 0x1a, 0x30, 0x60, 0x09, 0xb2,
+0x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04, 0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f,
+0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22, 0xc2, 0x42, 0xd3, 0x22, 0x22, 0xc2, 0x4b, 0xc2,
+0x4c, 0xe5, 0x44, 0x12, 0x0a, 0x9d, 0x12, 0xaf, 0x00, 0x13, 0x42, 0x04, 0x13, 0x3e, 0x08, 0x13,
+0x19, 0x10, 0x12, 0xc3, 0x20, 0x12, 0xe3, 0x60, 0x12, 0xf4, 0xa0, 0x00, 0x00, 0x13, 0x44, 0x85,
+0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x13,
+0x44, 0x80, 0x1b, 0xe5, 0x48, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5,
+0x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x66, 0x53, 0x43,
+0x0f, 0x80, 0x61, 0x85, 0x49, 0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06,
+0x70, 0x52, 0x80, 0x1b, 0xe5, 0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f,
+0xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x35, 0xe5,
+0x43, 0x54, 0x0f, 0x44, 0x10, 0xf5, 0x43, 0x80, 0x2b, 0xe5, 0x47, 0xb4, 0x04, 0x06, 0x53, 0x5e,
+0xfb, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e, 0x04, 0x75, 0x42, 0x09, 0xe5,
+0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5, 0x43, 0x80, 0x06, 0xd2, 0x4b,
+0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4, 0x54, 0xf0, 0xff, 0xe5, 0x43, 0x54,
+0x0f, 0x4f, 0xf5, 0x5f, 0x90, 0x70, 0x44, 0xf0, 0xa3, 0xe5, 0x5e, 0xf0, 0xa3, 0xe5, 0x4a, 0xf0,
+0xa3, 0xe5, 0x48, 0xf0, 0xa3, 0xe5, 0x4c, 0xf0, 0xa3, 0xe5, 0x44, 0xf0, 0xa3, 0xe5, 0x42, 0xf0,
+0xa3, 0xe5, 0x43, 0xf0, 0xd2, 0x60, 0x22, 0xe5, 0x47, 0x60, 0x10, 0x24, 0xc0, 0x70, 0x03, 0x12,
+0x16, 0x29, 0x12, 0x13, 0x8c, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x90, 0x04,
+0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45, 0x4f, 0x24, 0xff,
+0x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74, 0x1e, 0xf0, 0xe5,
+0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5, 0x5f, 0x20, 0xe5,
+0x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5, 0x25, 0x70, 0x05,
+0x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f, 0xe5, 0x5f, 0x30,
+0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5, 0x47, 0x64, 0x03,
+0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25, 0x70, 0x03, 0x30,
+0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02, 0x15, 0x25, 0xd2,
+0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b, 0xe5, 0x3a, 0x64,
+0x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0x90, 0x70, 0x46, 0xe5,
+0x2d, 0xf0, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2, 0x68, 0x20, 0x6b, 0x07, 0xe5,
+0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e, 0x20, 0xe2, 0x02, 0xb2, 0x6c,
+0x90, 0x70, 0x47, 0xe5, 0x2d, 0xf0, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26,
+0x30, 0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01,
+0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02,
+0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80,
+0x26, 0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f,
+0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80,
+0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c,
+0x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04,
+0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01,
+0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x71, 0x92, 0x70, 0x90, 0x10, 0x00, 0xe0,
+0x90, 0x10, 0x2f, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3, 0x94, 0x30, 0x40, 0x14, 0xa2, 0x71, 0x92,
+0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13, 0x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2,
+0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4c, 0x90, 0x02, 0x29,
+0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60, 0x14, 0x24, 0xfe, 0x60, 0x23,
+0x24, 0x03, 0x60, 0x03, 0x02, 0x16, 0x18, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x0f, 0x80, 0x07,
+0x90, 0x02, 0x28, 0xe0, 0x20, 0x47, 0x06, 0x54, 0xfe, 0xf0, 0x02, 0x16, 0x18, 0x44, 0x01, 0xf0,
+0x02, 0x16, 0x18, 0xe5, 0x46, 0x30, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x02,
+0x28, 0xe0, 0x54, 0xfe, 0x4f, 0xf0, 0x02, 0x16, 0x18, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0f, 0xe5,
+0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, 0x16, 0x18, 0xe4, 0xf5,
+0x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x2d, 0x14, 0x60, 0x2e,
+0x14, 0x60, 0x36, 0x24, 0xfc, 0x60, 0x5f, 0x24, 0xf9, 0x60, 0x1f, 0x24, 0x0e, 0x70, 0x69, 0xe5,
+0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01,
+0x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x24, 0xff, 0x80, 0x45, 0xa2, 0x47, 0x80, 0x41, 0xe5, 0x46,
+0x30, 0xe2, 0x03, 0xd3, 0x80, 0x27, 0xc3, 0x80, 0x24, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38,
+0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20,
+0x47, 0x04, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x38, 0xa2,
+0x47, 0xb3, 0x92, 0x39, 0x80, 0x19, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92,
+0x39, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x80, 0x07, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x92, 0x39, 0x90,
+0x02, 0x28, 0xe0, 0x54, 0xfc, 0x45, 0x27, 0xf0, 0x90, 0x70, 0x9c, 0xe5, 0x3a, 0xf0, 0xa3, 0xe5,
+0x47, 0xf0, 0x90, 0x70, 0x41, 0xe5, 0x3a, 0xf0, 0x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47,
+0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0x8f,
+0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5, 0x62, 0xc2, 0xaf, 0xe5, 0x51,
+0x14, 0x60, 0x46, 0x14, 0x60, 0x62, 0x24, 0x02, 0x60, 0x03, 0x02, 0x17, 0x03, 0xd2, 0x59, 0x75,
+0x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0, 0x20, 0xe7, 0x22, 0x90, 0x04,
+0x34, 0xe0, 0xb4, 0x02, 0x1b, 0xa3, 0xe0, 0xb4, 0x02, 0x16, 0xa3, 0xe0, 0xb4, 0x02, 0x11, 0x7f,
+0x20, 0x12, 0x16, 0x3f, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x80, 0x73,
+0xe5, 0x50, 0x70, 0x05, 0x75, 0x62, 0x03, 0x80, 0x6a, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70,
+0x11, 0x7f, 0x20, 0x12, 0x16, 0x3f, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02,
+0x80, 0x51, 0xe5, 0x50, 0x70, 0x02, 0x80, 0x46, 0x90, 0x02, 0xa3, 0xe0, 0x20, 0xe6, 0x3b, 0x90,
+0x04, 0x37, 0xe0, 0x64, 0x22, 0x70, 0x33, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96,
+0xf0, 0x90, 0x12, 0x04, 0x74, 0x0a, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0,
+0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54, 0xf9, 0xf0, 0x75,
+0x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x62,
+0x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0xad, 0x62,
+0xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf, 0x22, 0xc2,
+0xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d,
+0x02, 0xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70, 0x4c, 0x75, 0x52,
+0x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x44,
+0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, 0x04, 0x74,
+0x03, 0xf0, 0x90, 0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44, 0x0c, 0xf0,
+0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x0b, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41, 0x12, 0x17,
+0x8d, 0x80, 0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60,
+0x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff,
+0x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e,
+0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22,
+0x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70, 0x28, 0xe0, 0x90, 0x10,
+0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70, 0x2a, 0xe0, 0x90, 0x10,
+0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0x90,
+0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90, 0x70, 0x29, 0xf0, 0x90,
+0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70, 0x24, 0xe0, 0x44, 0x01,
+0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x94, 0x3f,
+0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x12, 0x67, 0x02,
+0x12, 0x68, 0x02, 0x12, 0x87, 0x02, 0x12, 0x8c, 0x12, 0x12, 0x88, 0x22, 0x02, 0x16, 0x49, 0x02,
+0x17, 0x1f, 0x02, 0x13, 0x77, 0x02, 0x12, 0x8d, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x17,
+0xc1, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x1b, 0xe5, 0x4c, 0x30, 0xe0, 0x04, 0x7f, 0x40,
+0x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, 0x8c, 0x74, 0x08, 0xf0, 0xe4,
+0x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, 0x90, 0x01, 0x80, 0xe0, 0xb4,
+0x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, 0xb4, 0x81, 0x09, 0x90, 0x01,
+0x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xdd, 0x22, 0x90, 0x04, 0x14, 0xe0, 0x20, 0xe7, 0x03, 0x02,
+0x12, 0x66, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0xb6, 0x10,
+0xb7, 0x31, 0x10, 0xe0, 0x50, 0x11, 0x04, 0x51, 0x11, 0x0d, 0x52, 0x11, 0x0d, 0x53, 0x11, 0x0d,
+0x54, 0x11, 0x4e, 0x55, 0x11, 0x7e, 0x70, 0x11, 0xa9, 0x71, 0x11, 0xd7, 0x72, 0x12, 0x1d, 0x73,
+0x12, 0x3e, 0x80, 0x00, 0x00, 0x12, 0x66, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d, 0x02, 0xaf,
+0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5,
+0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x85, 0x56, 0x41, 0xd2, 0x02, 0x22,
+0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60, 0x03, 0x02, 0x12, 0x66, 0x90, 0x70, 0x11,
+0xe0, 0x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60, 0x03, 0x02, 0x12, 0x66, 0x75, 0x4e, 0x03,
+0x75, 0x4f, 0x20, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x47, 0x22, 0x90, 0x04, 0x04,
+0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0, 0xff, 0x74, 0x47, 0x25, 0x57,
+0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48, 0x25, 0x57, 0xf8, 0xc6, 0xef,
+0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90,
+0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0xe5, 0x47,
+0x64, 0x07, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0x90,
+0x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03,
+0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0xd2, 0x04, 0x22, 0x90, 0x70,
+0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56,
+0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56,
+0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70,
+0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b,
+0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70,
+0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x10, 0x02, 0xe0, 0xb4, 0x70, 0x1e, 0xa3, 0xe0,
+0xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd, 0x90, 0x05, 0x05, 0xe0, 0x54,
+0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, 0x08, 0xf0, 0xe4, 0xf5, 0x4e, 0xf5,
+0x4f, 0x75, 0x3a, 0xff, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80,
+0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x4b, 0x80, 0x42, 0x90, 0x70, 0x10,
+0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74,
+0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70,
+0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90,
+0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90,
+0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22, 0xe5, 0x53, 0x70, 0x1a, 0x30, 0x60, 0x09, 0xb2,
+0x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04, 0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f,
+0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22, 0xc2, 0x42, 0xd3, 0x22, 0x22, 0xc2, 0x4b, 0xc2,
+0x4c, 0xe5, 0x44, 0x12, 0x0a, 0xb6, 0x12, 0xaf, 0x00, 0x13, 0x42, 0x04, 0x13, 0x3e, 0x08, 0x13,
+0x19, 0x10, 0x12, 0xc3, 0x20, 0x12, 0xe3, 0x60, 0x12, 0xf4, 0xa0, 0x00, 0x00, 0x13, 0x44, 0x85,
+0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x13,
+0x44, 0x80, 0x1b, 0xe5, 0x48, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5,
+0x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x66, 0x53, 0x43,
+0x0f, 0x80, 0x61, 0x85, 0x49, 0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06,
+0x70, 0x52, 0x80, 0x1b, 0xe5, 0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f,
+0xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x35, 0xe5,
+0x43, 0x54, 0x0f, 0x44, 0x10, 0xf5, 0x43, 0x80, 0x2b, 0xe5, 0x47, 0xb4, 0x04, 0x06, 0x53, 0x5e,
+0xfb, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e, 0x04, 0x75, 0x42, 0x09, 0xe5,
+0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5, 0x43, 0x80, 0x06, 0xd2, 0x4b,
+0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4, 0x54, 0xf0, 0xff, 0xe5, 0x43, 0x54,
+0x0f, 0x4f, 0xf5, 0x5f, 0x90, 0x70, 0x44, 0xf0, 0xa3, 0xe5, 0x5e, 0xf0, 0xa3, 0xe5, 0x4a, 0xf0,
+0xa3, 0xe5, 0x48, 0xf0, 0xa3, 0xe5, 0x4c, 0xf0, 0xa3, 0xe5, 0x44, 0xf0, 0xa3, 0xe5, 0x42, 0xf0,
+0xa3, 0xe5, 0x43, 0xf0, 0xd2, 0x60, 0x22, 0xe5, 0x47, 0x60, 0x10, 0x24, 0xc0, 0x70, 0x03, 0x12,
+0x16, 0x29, 0x12, 0x13, 0x8c, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x90, 0x04,
+0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45, 0x4f, 0x24, 0xff,
+0x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74, 0x1e, 0xf0, 0xe5,
+0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5, 0x5f, 0x20, 0xe5,
+0x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5, 0x25, 0x70, 0x05,
+0x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f, 0xe5, 0x5f, 0x30,
+0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5, 0x47, 0x64, 0x03,
+0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25, 0x70, 0x03, 0x30,
+0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02, 0x15, 0x25, 0xd2,
+0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b, 0xe5, 0x3a, 0x64,
+0x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0x90, 0x70, 0x46, 0xe5,
+0x2d, 0xf0, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2, 0x68, 0x20, 0x6b, 0x07, 0xe5,
+0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e, 0x20, 0xe2, 0x02, 0xb2, 0x6c,
+0x90, 0x70, 0x47, 0xe5, 0x2d, 0xf0, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26,
+0x30, 0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01,
+0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02,
+0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80,
+0x26, 0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f,
+0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80,
+0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c,
+0x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04,
+0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01,
+0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x71, 0x92, 0x70, 0x90, 0x10, 0x00, 0xe0,
+0x90, 0x10, 0x2f, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3, 0x94, 0x30, 0x40, 0x14, 0xa2, 0x71, 0x92,
+0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13, 0x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2,
+0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4c, 0x90, 0x02, 0x29,
+0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60, 0x14, 0x24, 0xfe, 0x60, 0x23,
+0x24, 0x03, 0x60, 0x03, 0x02, 0x16, 0x18, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x0f, 0x80, 0x07,
+0x90, 0x02, 0x28, 0xe0, 0x20, 0x47, 0x06, 0x54, 0xfe, 0xf0, 0x02, 0x16, 0x18, 0x44, 0x01, 0xf0,
+0x02, 0x16, 0x18, 0xe5, 0x46, 0x30, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x02,
+0x28, 0xe0, 0x54, 0xfe, 0x4f, 0xf0, 0x02, 0x16, 0x18, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0f, 0xe5,
+0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, 0x16, 0x18, 0xe4, 0xf5,
+0x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x2d, 0x14, 0x60, 0x2e,
+0x14, 0x60, 0x36, 0x24, 0xfc, 0x60, 0x5f, 0x24, 0xf9, 0x60, 0x1f, 0x24, 0x0e, 0x70, 0x69, 0xe5,
+0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01,
+0x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x24, 0xff, 0x80, 0x45, 0xa2, 0x47, 0x80, 0x41, 0xe5, 0x46,
+0x30, 0xe2, 0x03, 0xd3, 0x80, 0x27, 0xc3, 0x80, 0x24, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38,
+0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20,
+0x47, 0x04, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x38, 0xa2,
+0x47, 0xb3, 0x92, 0x39, 0x80, 0x19, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92,
+0x39, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x80, 0x07, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x92, 0x39, 0x90,
+0x02, 0x28, 0xe0, 0x54, 0xfc, 0x45, 0x27, 0xf0, 0x90, 0x70, 0x9c, 0xe5, 0x3a, 0xf0, 0xa3, 0xe5,
+0x47, 0xf0, 0x90, 0x70, 0x41, 0xe5, 0x3a, 0xf0, 0x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47,
+0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0x8f,
+0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5, 0x62, 0xc2, 0xaf, 0xe5, 0x51,
+0x14, 0x60, 0x46, 0x14, 0x60, 0x62, 0x24, 0x02, 0x60, 0x03, 0x02, 0x17, 0x03, 0xd2, 0x59, 0x75,
+0x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0, 0x20, 0xe7, 0x22, 0x90, 0x04,
+0x34, 0xe0, 0xb4, 0x02, 0x1b, 0xa3, 0xe0, 0xb4, 0x02, 0x16, 0xa3, 0xe0, 0xb4, 0x02, 0x11, 0x7f,
+0x20, 0x12, 0x16, 0x3f, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x80, 0x73,
+0xe5, 0x50, 0x70, 0x05, 0x75, 0x62, 0x03, 0x80, 0x6a, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70,
+0x11, 0x7f, 0x20, 0x12, 0x16, 0x3f, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02,
+0x80, 0x51, 0xe5, 0x50, 0x70, 0x02, 0x80, 0x46, 0x90, 0x02, 0xa3, 0xe0, 0x20, 0xe6, 0x3b, 0x90,
+0x04, 0x37, 0xe0, 0x64, 0x22, 0x70, 0x33, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96,
+0xf0, 0x90, 0x12, 0x04, 0x74, 0x0a, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0,
+0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54, 0xf9, 0xf0, 0x75,
+0x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x62,
+0x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0xad, 0x62,
+0xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf, 0x22, 0xc2,
+0xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d,
+0x02, 0xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70, 0x4c, 0x75, 0x52,
+0x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x44,
+0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, 0x04, 0x74,
+0x03, 0xf0, 0x90, 0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44, 0x0c, 0xf0,
+0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x0b, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41, 0x12, 0x17,
+0x8d, 0x80, 0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60,
+0x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff,
+0x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e,
+0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22,
+0x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70, 0x28, 0xe0, 0x90, 0x10,
+0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70, 0x2a, 0xe0, 0x90, 0x10,
+0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0x90,
+0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90, 0x70, 0x29, 0xf0, 0x90,
+0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70, 0x24, 0xe0, 0x44, 0x01,
+0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x9b, 0xc0, } ;
diff --git a/drivers/staging/rt3070/leap.h b/drivers/staging/rt3070/leap.h
new file mode 100644
index 0000000..6818c1f
--- /dev/null
+++ b/drivers/staging/rt3070/leap.h
@@ -0,0 +1,215 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	leap.h
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	Name		Date			Modification logs
+*/
+#ifndef __LEAP_H__
+#define __LEAP_H__
+
+// Messages for Associate state machine
+#define LEAP_MACHINE_BASE                   30
+
+#define LEAP_MSG_REQUEST_IDENTITY           31
+#define LEAP_MSG_REQUEST_LEAP               32
+#define LEAP_MSG_SUCCESS                    33
+#define LEAP_MSG_FAILED                     34
+#define LEAP_MSG_RESPONSE_LEAP              35
+#define LEAP_MSG_EAPOLKEY                   36
+#define LEAP_MSG_UNKNOWN                    37
+#define LEAP_MSG                            38
+//! assoc state-machine states
+#define LEAP_IDLE                           0
+#define LEAP_WAIT_IDENTITY_REQUEST          1
+#define LEAP_WAIT_CHANLLENGE_REQUEST        2
+#define LEAP_WAIT_SUCCESS                   3
+#define LEAP_WAIT_CHANLLENGE_RESPONSE       4
+#define LEAP_WAIT_EAPOLKEY                  5
+
+#define LEAP_REASON_INVALID_AUTH                    0x01
+#define LEAP_REASON_AUTH_TIMEOUT                    0x02
+#define LEAP_REASON_CHALLENGE_FROM_AP_FAILED        0x03
+#define LEAP_REASON_CHALLENGE_TO_AP_FAILED          0x04
+
+#define CISCO_AuthModeLEAP                          0x80
+#define CISCO_AuthModeLEAPNone                      0x00
+#define LEAP_AUTH_TIMEOUT                           30000
+#define LEAP_CHALLENGE_RESPONSE_LENGTH              24
+#define LEAP_CHALLENGE_REQUEST_LENGTH               8
+
+typedef struct _LEAP_EAPOL_HEADER_ {
+    UCHAR       Version;
+    UCHAR       Type;
+    UCHAR       Length[2];
+} LEAP_EAPOL_HEADER, *PLEAP_EAPOL_HEADER;
+
+typedef struct _LEAP_EAPOL_PACKET_ {
+    UCHAR       Code;
+    UCHAR       Identifier;
+    UCHAR       Length[2];
+    UCHAR       Type;
+} LEAP_EAPOL_PACKET, *PLEAP_EAPOL_PACKET;
+
+typedef struct _LEAP_EAP_CONTENTS_ {
+    UCHAR       Version;
+    UCHAR       Reserved;
+    UCHAR       Length;
+} LEAP_EAP_CONTENTS, *PLEAP_EAP_CONTENTS;
+
+/*** EAPOL key ***/
+typedef struct _EAPOL_KEY_HEADER_ {
+    UCHAR       Type;
+    UCHAR       Length[2];
+    UCHAR       Counter[8];
+    UCHAR       IV[16];
+    UCHAR       Index;
+    UCHAR       Signature[16];
+} EAPOL_KEY_HEADER, *PEAPOL_KEY_HEADER;
+
+BOOLEAN LeapMsgTypeSubst(
+    IN  UCHAR   EAPType,
+    OUT ULONG   *MsgType);
+
+VOID LeapMachinePerformAction(
+    IN PRTMP_ADAPTER    pAd,
+    IN STATE_MACHINE    *S,
+    IN MLME_QUEUE_ELEM  *Elem);
+
+VOID LeapMacHeaderInit(
+    IN  PRTMP_ADAPTER       pAd,
+    IN  OUT PHEADER_802_11  pHdr80211,
+    IN  UCHAR               wep,
+    IN  PUCHAR              pAddr3);
+
+VOID LeapStartAction(
+    IN PRTMP_ADAPTER    pAd,
+    IN MLME_QUEUE_ELEM  *Elem);
+
+VOID LeapIdentityAction(
+    IN PRTMP_ADAPTER    pAd,
+    IN MLME_QUEUE_ELEM  *Elem);
+
+VOID LeapPeerChallengeAction(
+    IN PRTMP_ADAPTER    pAd,
+    IN MLME_QUEUE_ELEM  *Elem);
+
+VOID HashPwd(
+    IN  PUCHAR  pwd,
+    IN  INT     pwdlen,
+    OUT PUCHAR  hash);
+
+VOID PeerChallengeResponse(
+    IN  PUCHAR  szChallenge,
+    IN  PUCHAR  smbPasswd,
+    OUT PUCHAR  szResponse);
+
+VOID ParityKey(
+    OUT PUCHAR  szOut,
+    IN  PUCHAR  szIn);
+
+VOID DesKey(
+    OUT ULONG   k[16][2],
+    IN  PUCHAR  key,
+    IN  INT     decrypt);
+
+VOID Des(
+    IN  ULONG   ks[16][2],
+    OUT UCHAR   block[8]);
+
+VOID DesEncrypt(
+    IN  PUCHAR  szClear,
+    IN  PUCHAR  szKey,
+    OUT PUCHAR  szOut);
+
+VOID LeapNetworkChallengeAction(
+    IN PRTMP_ADAPTER    pAd,
+    IN MLME_QUEUE_ELEM  *Elem);
+
+VOID LeapNetworkChallengeResponse(
+    IN PRTMP_ADAPTER    pAd,
+    IN MLME_QUEUE_ELEM  *Elem);
+
+VOID HashpwdHash(
+    IN  PUCHAR  hash,
+    IN  PUCHAR  hashhash);
+
+VOID ProcessSessionKey(
+    OUT PUCHAR  SessionKey,
+    IN  PUCHAR  hash2,
+    IN  PUCHAR  ChallengeToRadius,
+    IN  PUCHAR  ChallengeResponseFromRadius,
+    IN  PUCHAR  ChallengeFromRadius,
+    IN  PUCHAR  ChallengeResponseToRadius);
+
+VOID LeapEapolKeyAction(
+    IN PRTMP_ADAPTER    pAd,
+    IN MLME_QUEUE_ELEM  *Elem);
+
+VOID RogueApTableInit(
+    IN ROGUEAP_TABLE    *Tab);
+
+ULONG RogueApTableSearch(
+    IN ROGUEAP_TABLE    *Tab,
+    IN PUCHAR           pAddr);
+
+VOID RogueApEntrySet(
+    IN  PRTMP_ADAPTER   pAd,
+    OUT ROGUEAP_ENTRY   *pRogueAp,
+    IN PUCHAR           pAddr,
+    IN UCHAR            FaileCode);
+
+ULONG RogueApTableSetEntry(
+    IN  PRTMP_ADAPTER   pAd,
+    OUT ROGUEAP_TABLE  *Tab,
+    IN PUCHAR           pAddr,
+    IN UCHAR            FaileCode);
+
+VOID RogueApTableDeleteEntry(
+    IN OUT ROGUEAP_TABLE *Tab,
+    IN PUCHAR          pAddr);
+
+VOID LeapAuthTimeout(
+    IN PVOID SystemSpecific1,
+    IN PVOID FunctionContext,
+    IN PVOID SystemSpecific2,
+    IN PVOID SystemSpecific3);
+
+VOID LeapSendRogueAPReport(
+    IN  PRTMP_ADAPTER   pAd);
+
+BOOLEAN CCKMAssocRspSanity(
+    IN PRTMP_ADAPTER    pAd,
+    IN VOID             *Msg,
+    IN ULONG            MsgLen);
+
+#endif  // __LEAP_H__
diff --git a/drivers/staging/rt3070/link_list.h b/drivers/staging/rt3070/link_list.h
new file mode 100644
index 0000000..f652113
--- /dev/null
+++ b/drivers/staging/rt3070/link_list.h
@@ -0,0 +1,134 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+ */
+
+#ifndef __LINK_LIST_H__
+#define __LINK_LIST_H__
+
+typedef struct _LIST_ENTRY
+{
+	struct _LIST_ENTRY *pNext;
+} LIST_ENTRY, *PLIST_ENTRY;
+
+typedef struct _LIST_HEADR
+{
+	PLIST_ENTRY pHead;
+	PLIST_ENTRY pTail;
+	UCHAR size;
+} LIST_HEADER, *PLIST_HEADER;
+
+static inline VOID initList(
+	IN PLIST_HEADER pList)
+{
+	pList->pHead = pList->pTail = NULL;
+	pList->size = 0;
+	return;
+}
+
+static inline VOID insertTailList(
+	IN PLIST_HEADER pList,
+	IN PLIST_ENTRY pEntry)
+{
+	pEntry->pNext = NULL;
+	if (pList->pTail)
+		pList->pTail->pNext = pEntry;
+	else
+		pList->pHead = pEntry;
+	pList->pTail = pEntry;
+	pList->size++;
+
+	return;
+}
+
+static inline PLIST_ENTRY removeHeadList(
+	IN PLIST_HEADER pList)
+{
+	PLIST_ENTRY pNext;
+	PLIST_ENTRY pEntry;
+
+	pEntry = pList->pHead;
+	if (pList->pHead != NULL)
+	{
+		pNext = pList->pHead->pNext;
+		pList->pHead = pNext;
+		if (pNext == NULL)
+			pList->pTail = NULL;
+		pList->size--;
+	}
+	return pEntry;
+}
+
+static inline int getListSize(
+	IN PLIST_HEADER pList)
+{
+	return pList->size;
+}
+
+static inline PLIST_ENTRY delEntryList(
+	IN PLIST_HEADER pList,
+	IN PLIST_ENTRY pEntry)
+{
+	PLIST_ENTRY pCurEntry;
+	PLIST_ENTRY pPrvEntry;
+
+	if(pList->pHead == NULL)
+		return NULL;
+
+	if(pEntry == pList->pHead)
+	{
+		pCurEntry = pList->pHead;
+		pList->pHead = pCurEntry->pNext;
+
+		if(pList->pHead == NULL)
+			pList->pTail = NULL;
+
+		pList->size--;
+		return pCurEntry;
+	}
+
+	pPrvEntry = pList->pHead;
+	pCurEntry = pPrvEntry->pNext;
+	while(pCurEntry != NULL)
+	{
+		if (pEntry == pCurEntry)
+		{
+			pPrvEntry->pNext = pCurEntry->pNext;
+
+			if(pEntry == pList->pTail)
+				pList->pTail = pPrvEntry;
+
+			pList->size--;
+			break;
+		}
+		pPrvEntry = pCurEntry;
+		pCurEntry = pPrvEntry->pNext;
+	}
+
+	return pCurEntry;
+}
+
+#endif // ___LINK_LIST_H__ //
+
diff --git a/drivers/staging/rt3070/md4.h b/drivers/staging/rt3070/md4.h
new file mode 100644
index 0000000..f1e5b52
--- /dev/null
+++ b/drivers/staging/rt3070/md4.h
@@ -0,0 +1,42 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+ */
+
+#ifndef __MD4_H__
+#define __MD4_H__
+
+/* MD4 context. */
+typedef	struct	_MD4_CTX_	{
+	ULONG	state[4];        /* state (ABCD) */
+	ULONG	count[2];        /* number of bits, modulo 2^64 (lsb first) */
+	UCHAR	buffer[64];      /* input buffer */
+}	MD4_CTX;
+
+VOID MD4Init (MD4_CTX *);
+VOID MD4Update (MD4_CTX *, PUCHAR, UINT);
+VOID MD4Final (UCHAR [16], MD4_CTX *);
+
+#endif //__MD4_H__
\ No newline at end of file
diff --git a/drivers/staging/rt3070/md5.h b/drivers/staging/rt3070/md5.h
new file mode 100644
index 0000000..d85db12
--- /dev/null
+++ b/drivers/staging/rt3070/md5.h
@@ -0,0 +1,107 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	md5.h
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	Name		Date			Modification logs
+	jan			10-28-03		Initial
+	Rita    	11-23-04		Modify MD5 and SHA-1
+*/
+
+#ifndef	uint8
+#define	uint8  unsigned	char
+#endif
+
+#ifndef	uint32
+#define	uint32 unsigned	long int
+#endif
+
+
+#ifndef	__MD5_H__
+#define	__MD5_H__
+
+#define MD5_MAC_LEN 16
+
+typedef struct _MD5_CTX {
+    UINT32   Buf[4];             // buffers of four states
+	UCHAR   Input[64];          // input message
+	UINT32   LenInBitCount[2];   // length counter for input message, 0 up to 64 bits
+}   MD5_CTX;
+
+VOID MD5Init(MD5_CTX *pCtx);
+VOID MD5Update(MD5_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes);
+VOID MD5Final(UCHAR Digest[16], MD5_CTX *pCtx);
+VOID MD5Transform(UINT32 Buf[4], UINT32 Mes[16]);
+
+void md5_mac(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac);
+void hmac_md5(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac);
+
+//
+// SHA context
+//
+typedef	struct _SHA_CTX
+{
+	UINT32   Buf[5];             // buffers of five states
+	UCHAR   Input[80];          // input message
+	UINT32   LenInBitCount[2];   // length counter for input message, 0 up to 64 bits
+
+}	SHA_CTX;
+
+VOID SHAInit(SHA_CTX *pCtx);
+UCHAR SHAUpdate(SHA_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes);
+VOID SHAFinal(SHA_CTX *pCtx, UCHAR Digest[20]);
+VOID SHATransform(UINT32 Buf[5], UINT32 Mes[20]);
+
+#define SHA_DIGEST_LEN 20
+#endif // __MD5_H__
+
+/******************************************************************************/
+#ifndef	_AES_H
+#define	_AES_H
+
+typedef	struct
+{
+	uint32 erk[64];		/* encryption round	keys */
+	uint32 drk[64];		/* decryption round	keys */
+	int	nr;				/* number of rounds	*/
+}
+aes_context;
+
+int	 rtmp_aes_set_key( aes_context *ctx,	uint8 *key,	int	nbits );
+void rtmp_aes_encrypt( aes_context *ctx,	uint8 input[16], uint8 output[16] );
+void rtmp_aes_decrypt( aes_context *ctx,	uint8 input[16], uint8 output[16] );
+
+void F(char *password, unsigned char *ssid, int ssidlength, int iterations, int count, unsigned char *output);
+int PasswordHash(char *password, unsigned char *ssid, int ssidlength, unsigned char *output);
+
+#endif /* aes.h	*/
+
diff --git a/drivers/staging/rt3070/mlme.h b/drivers/staging/rt3070/mlme.h
new file mode 100644
index 0000000..b0035e1
--- /dev/null
+++ b/drivers/staging/rt3070/mlme.h
@@ -0,0 +1,1468 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	mlme.h
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	John Chang	2003-08-28		Created
+	John Chang  2004-09-06      modified for RT2600
+
+*/
+#ifndef __MLME_H__
+#define __MLME_H__
+
+//extern UCHAR BROADCAST_ADDR[];
+
+// maximum supported capability information -
+// ESS, IBSS, Privacy, Short Preamble, Spectrum mgmt, Short Slot
+#define SUPPORTED_CAPABILITY_INFO   0x0533
+
+#define END_OF_ARGS                 -1
+#define LFSR_MASK                   0x80000057
+#define MLME_TASK_EXEC_INTV         100/*200*/       //
+#define LEAD_TIME                   5
+#define MLME_TASK_EXEC_MULTIPLE       10  /*5*/       // MLME_TASK_EXEC_MULTIPLE * MLME_TASK_EXEC_INTV = 1 sec
+#define REORDER_EXEC_INTV         	100       // 0.1 sec
+//#define TBTT_PRELOAD_TIME         384        // usec. LomgPreamble + 24-byte at 1Mbps
+
+// The definition of Radar detection duration region
+#define CE		0
+#define FCC		1
+#define JAP		2
+#define JAP_W53	3
+#define JAP_W56	4
+#define MAX_RD_REGION 5
+
+#ifdef	NDIS51_MINIPORT
+#define BEACON_LOST_TIME            4000       // 2048 msec = 2 sec
+#else
+#define BEACON_LOST_TIME            4 * OS_HZ    // 2048 msec = 2 sec
+#endif
+
+#define DLS_TIMEOUT                 1200      // unit: msec
+#define AUTH_TIMEOUT                300       // unit: msec
+#define ASSOC_TIMEOUT               300       // unit: msec
+#define JOIN_TIMEOUT                2 * OS_HZ      // unit: msec
+#define SHORT_CHANNEL_TIME          90        // unit: msec
+#define MIN_CHANNEL_TIME            110        // unit: msec, for dual band scan
+#define MAX_CHANNEL_TIME            140       // unit: msec, for single band scan
+#define	FAST_ACTIVE_SCAN_TIME	    30 		  // Active scan waiting for probe response time
+#define CW_MIN_IN_BITS              4         // actual CwMin = 2^CW_MIN_IN_BITS - 1
+
+
+#ifdef CONFIG_STA_SUPPORT
+#ifndef CONFIG_AP_SUPPORT
+#define CW_MAX_IN_BITS              10        // actual CwMax = 2^CW_MAX_IN_BITS - 1
+#endif
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+extern UINT32 CW_MAX_IN_BITS;
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+
+// Note: RSSI_TO_DBM_OFFSET has been changed to variable for new RF (2004-0720).
+// SHould not refer to this constant anymore
+//#define RSSI_TO_DBM_OFFSET          120 // for RT2530 RSSI-115 = dBm
+#define RSSI_FOR_MID_TX_POWER       -55  // -55 db is considered mid-distance
+#define RSSI_FOR_LOW_TX_POWER       -45  // -45 db is considered very short distance and
+                                        // eligible to use a lower TX power
+#define RSSI_FOR_LOWEST_TX_POWER    -30
+//#define MID_TX_POWER_DELTA          0   // 0 db from full TX power upon mid-distance to AP
+#define LOW_TX_POWER_DELTA          6    // -3 db from full TX power upon very short distance. 1 grade is 0.5 db
+#define LOWEST_TX_POWER_DELTA       16   // -8 db from full TX power upon shortest distance. 1 grade is 0.5 db
+
+#define RSSI_TRIGGERED_UPON_BELOW_THRESHOLD     0
+#define RSSI_TRIGGERED_UPON_EXCCEED_THRESHOLD   1
+#define RSSI_THRESHOLD_FOR_ROAMING              25
+#define RSSI_DELTA                              5
+
+// Channel Quality Indication
+#define CQI_IS_GOOD(cqi)            ((cqi) >= 50)
+//#define CQI_IS_FAIR(cqi)          (((cqi) >= 20) && ((cqi) < 50))
+#define CQI_IS_POOR(cqi)            (cqi < 50)  //(((cqi) >= 5) && ((cqi) < 20))
+#define CQI_IS_BAD(cqi)             (cqi < 5)
+#define CQI_IS_DEAD(cqi)            (cqi == 0)
+
+// weighting factor to calculate Channel quality, total should be 100%
+#define RSSI_WEIGHTING                   50
+#define TX_WEIGHTING                     30
+#define RX_WEIGHTING                     20
+
+//#define PEER_KEY_NOT_USED                0
+//#define PEER_KEY_64_BIT                  64
+//#define PEER_KEY_128_BIT                 128
+
+//#define PEER_KEY_64BIT_LEN               8
+//#define PEER_KEY_128BIT_LEN              16
+
+#define BSS_NOT_FOUND                    0xFFFFFFFF
+
+
+#ifdef CONFIG_STA_SUPPORT
+#define MAX_LEN_OF_MLME_QUEUE            40 //10
+#endif // CONFIG_STA_SUPPORT //
+
+#define SCAN_PASSIVE                     18		// scan with no probe request, only wait beacon and probe response
+#define SCAN_ACTIVE                      19		// scan with probe request, and wait beacon and probe response
+#define	SCAN_CISCO_PASSIVE				 20		// Single channel passive scan
+#define	SCAN_CISCO_ACTIVE				 21		// Single channel active scan
+#define	SCAN_CISCO_NOISE				 22		// Single channel passive scan for noise histogram collection
+#define	SCAN_CISCO_CHANNEL_LOAD			 23		// Single channel passive scan for channel load collection
+#define FAST_SCAN_ACTIVE                 24		// scan with probe request, and wait beacon and probe response
+
+#ifdef DOT11N_DRAFT3
+#define SCAN_2040_BSS_COEXIST                  26
+#endif // DOT11N_DRAFT3 //
+
+//#define BSS_TABLE_EMPTY(x)             ((x).BssNr == 0)
+#define MAC_ADDR_IS_GROUP(Addr)       (((Addr[0]) & 0x01))
+#define MAC_ADDR_HASH(Addr)            (Addr[0] ^ Addr[1] ^ Addr[2] ^ Addr[3] ^ Addr[4] ^ Addr[5])
+#define MAC_ADDR_HASH_INDEX(Addr)      (MAC_ADDR_HASH(Addr) % HASH_TABLE_SIZE)
+#define TID_MAC_HASH(Addr,TID)            (TID^Addr[0] ^ Addr[1] ^ Addr[2] ^ Addr[3] ^ Addr[4] ^ Addr[5])
+#define TID_MAC_HASH_INDEX(Addr,TID)      (TID_MAC_HASH(Addr,TID) % HASH_TABLE_SIZE)
+
+// LED Control
+// assoiation ON. one LED ON. another blinking when TX, OFF when idle
+// no association, both LED off
+#define ASIC_LED_ACT_ON(pAd)        RTMP_IO_WRITE32(pAd, MAC_CSR14, 0x00031e46)
+#define ASIC_LED_ACT_OFF(pAd)       RTMP_IO_WRITE32(pAd, MAC_CSR14, 0x00001e46)
+
+// bit definition of the 2-byte pBEACON->Capability field
+#define CAP_IS_ESS_ON(x)                 (((x) & 0x0001) != 0)
+#define CAP_IS_IBSS_ON(x)                (((x) & 0x0002) != 0)
+#define CAP_IS_CF_POLLABLE_ON(x)         (((x) & 0x0004) != 0)
+#define CAP_IS_CF_POLL_REQ_ON(x)         (((x) & 0x0008) != 0)
+#define CAP_IS_PRIVACY_ON(x)             (((x) & 0x0010) != 0)
+#define CAP_IS_SHORT_PREAMBLE_ON(x)      (((x) & 0x0020) != 0)
+#define CAP_IS_PBCC_ON(x)                (((x) & 0x0040) != 0)
+#define CAP_IS_AGILITY_ON(x)             (((x) & 0x0080) != 0)
+#define CAP_IS_SPECTRUM_MGMT(x)          (((x) & 0x0100) != 0)  // 802.11e d9
+#define CAP_IS_QOS(x)                    (((x) & 0x0200) != 0)  // 802.11e d9
+#define CAP_IS_SHORT_SLOT(x)             (((x) & 0x0400) != 0)
+#define CAP_IS_APSD(x)                   (((x) & 0x0800) != 0)  // 802.11e d9
+#define CAP_IS_IMMED_BA(x)               (((x) & 0x1000) != 0)  // 802.11e d9
+#define CAP_IS_DSSS_OFDM(x)              (((x) & 0x2000) != 0)
+#define CAP_IS_DELAY_BA(x)               (((x) & 0x4000) != 0)  // 802.11e d9
+
+#define CAP_GENERATE(ess,ibss,priv,s_pre,s_slot,spectrum)  (((ess) ? 0x0001 : 0x0000) | ((ibss) ? 0x0002 : 0x0000) | ((priv) ? 0x0010 : 0x0000) | ((s_pre) ? 0x0020 : 0x0000) | ((s_slot) ? 0x0400 : 0x0000) | ((spectrum) ? 0x0100 : 0x0000))
+
+//#define STA_QOS_CAPABILITY               0 // 1-byte. see 802.11e d9.0 for bit definition
+
+#define ERP_IS_NON_ERP_PRESENT(x)        (((x) & 0x01) != 0)    // 802.11g
+#define ERP_IS_USE_PROTECTION(x)         (((x) & 0x02) != 0)    // 802.11g
+#define ERP_IS_USE_BARKER_PREAMBLE(x)    (((x) & 0x04) != 0)    // 802.11g
+
+#define DRS_TX_QUALITY_WORST_BOUND       8// 3  // just test by gary
+#define DRS_PENALTY                      8
+
+#define BA_NOTUSE 	2
+//BA Policy subfiled value in ADDBA frame
+#define IMMED_BA 	1
+#define DELAY_BA	0
+
+// BA Initiator subfield in DELBA frame
+#define ORIGINATOR	1
+#define RECIPIENT	0
+
+// ADDBA Status Code
+#define ADDBA_RESULTCODE_SUCCESS					0
+#define ADDBA_RESULTCODE_REFUSED					37
+#define ADDBA_RESULTCODE_INVALID_PARAMETERS			38
+
+// DELBA Reason Code
+#define DELBA_REASONCODE_QSTA_LEAVING				36
+#define DELBA_REASONCODE_END_BA						37
+#define DELBA_REASONCODE_UNKNOWN_BA					38
+#define DELBA_REASONCODE_TIMEOUT					39
+
+// reset all OneSecTx counters
+#define RESET_ONE_SEC_TX_CNT(__pEntry) \
+if (((__pEntry)) != NULL) \
+{ \
+	(__pEntry)->OneSecTxRetryOkCount = 0; \
+	(__pEntry)->OneSecTxFailCount = 0; \
+	(__pEntry)->OneSecTxNoRetryOkCount = 0; \
+}
+
+//
+// 802.11 frame formats
+//
+//  HT Capability INFO field in HT Cap IE .
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+	USHORT	LSIGTxopProSup:1;
+	USHORT	Forty_Mhz_Intolerant:1;
+	USHORT	PSMP:1;
+	USHORT	CCKmodein40:1;
+	USHORT	AMsduSize:1;
+	USHORT	DelayedBA:1;	//rt2860c not support
+	USHORT	RxSTBC:2;
+	USHORT	TxSTBC:1;
+	USHORT	ShortGIfor40:1;	//for40MHz
+	USHORT	ShortGIfor20:1;
+	USHORT	GF:1;	//green field
+	USHORT	MimoPs:2;//momi power safe
+	USHORT	ChannelWidth:1;
+	USHORT	AdvCoding:1;
+#else
+	USHORT	AdvCoding:1;
+	USHORT	ChannelWidth:1;
+	USHORT	MimoPs:2;//momi power safe
+	USHORT	GF:1;	//green field
+	USHORT	ShortGIfor20:1;
+	USHORT	ShortGIfor40:1;	//for40MHz
+	USHORT	TxSTBC:1;
+	USHORT	RxSTBC:2;
+	USHORT	DelayedBA:1;	//rt2860c not support
+	USHORT	AMsduSize:1;	// only support as zero
+	USHORT	CCKmodein40:1;
+	USHORT	PSMP:1;
+	USHORT	Forty_Mhz_Intolerant:1;
+	USHORT	LSIGTxopProSup:1;
+#endif	/* !RT_BIG_ENDIAN */
+} HT_CAP_INFO, *PHT_CAP_INFO;
+
+//  HT Capability INFO field in HT Cap IE .
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+	UCHAR	rsv:3;//momi power safe
+	UCHAR	MpduDensity:3;
+	UCHAR	MaxRAmpduFactor:2;
+#else
+	UCHAR	MaxRAmpduFactor:2;
+	UCHAR	MpduDensity:3;
+	UCHAR	rsv:3;//momi power safe
+#endif /* !RT_BIG_ENDIAN */
+} HT_CAP_PARM, *PHT_CAP_PARM;
+
+//  HT Capability INFO field in HT Cap IE .
+typedef struct PACKED {
+	UCHAR	MCSSet[10];
+	UCHAR	SupRate[2];  // unit : 1Mbps
+#ifdef RT_BIG_ENDIAN
+	UCHAR	rsv:3;
+	UCHAR	MpduDensity:1;
+	UCHAR	TxStream:2;
+	UCHAR	TxRxNotEqual:1;
+	UCHAR	TxMCSSetDefined:1;
+#else
+	UCHAR	TxMCSSetDefined:1;
+	UCHAR	TxRxNotEqual:1;
+	UCHAR	TxStream:2;
+	UCHAR	MpduDensity:1;
+	UCHAR	rsv:3;
+#endif // RT_BIG_ENDIAN //
+	UCHAR	rsv3[3];
+} HT_MCS_SET, *PHT_MCS_SET;
+
+//  HT Capability INFO field in HT Cap IE .
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+	USHORT	rsv2:4;
+	USHORT	RDGSupport:1;	//reverse Direction Grant  support
+	USHORT	PlusHTC:1;	//+HTC control field support
+	USHORT	MCSFeedback:2;	//0:no MCS feedback, 2:unsolicited MCS feedback, 3:Full MCS feedback,  1:rsv.
+	USHORT	rsv:5;//momi power safe
+	USHORT	TranTime:2;
+	USHORT	Pco:1;
+#else
+	USHORT	Pco:1;
+	USHORT	TranTime:2;
+	USHORT	rsv:5;//momi power safe
+	USHORT	MCSFeedback:2;	//0:no MCS feedback, 2:unsolicited MCS feedback, 3:Full MCS feedback,  1:rsv.
+	USHORT	PlusHTC:1;	//+HTC control field support
+	USHORT	RDGSupport:1;	//reverse Direction Grant  support
+	USHORT	rsv2:4;
+#endif /* RT_BIG_ENDIAN */
+} EXT_HT_CAP_INFO, *PEXT_HT_CAP_INFO;
+
+//  HT Beamforming field in HT Cap IE .
+typedef struct PACKED _HT_BF_CAP{
+#ifdef RT_BIG_ENDIAN
+	ULONG	rsv:3;
+	ULONG	ChanEstimation:2;
+	ULONG	CSIRowBFSup:2;
+	ULONG	ComSteerBFAntSup:2;
+	ULONG	NoComSteerBFAntSup:2;
+	ULONG	CSIBFAntSup:2;
+	ULONG	MinGrouping:2;
+	ULONG	ExpComBF:2;
+	ULONG	ExpNoComBF:2;
+	ULONG	ExpCSIFbk:2;
+	ULONG	ExpComSteerCapable:1;
+	ULONG	ExpNoComSteerCapable:1;
+	ULONG	ExpCSICapable:1;
+	ULONG	Calibration:2;
+	ULONG	ImpTxBFCapable:1;
+	ULONG	TxNDPCapable:1;
+	ULONG	RxNDPCapable:1;
+	ULONG	TxSoundCapable:1;
+	ULONG	RxSoundCapable:1;
+	ULONG	TxBFRecCapable:1;
+#else
+	ULONG	TxBFRecCapable:1;
+	ULONG	RxSoundCapable:1;
+	ULONG	TxSoundCapable:1;
+	ULONG	RxNDPCapable:1;
+	ULONG	TxNDPCapable:1;
+	ULONG	ImpTxBFCapable:1;
+	ULONG	Calibration:2;
+	ULONG	ExpCSICapable:1;
+	ULONG	ExpNoComSteerCapable:1;
+	ULONG	ExpComSteerCapable:1;
+	ULONG	ExpCSIFbk:2;
+	ULONG	ExpNoComBF:2;
+	ULONG	ExpComBF:2;
+	ULONG	MinGrouping:2;
+	ULONG	CSIBFAntSup:2;
+	ULONG	NoComSteerBFAntSup:2;
+	ULONG	ComSteerBFAntSup:2;
+	ULONG	CSIRowBFSup:2;
+	ULONG	ChanEstimation:2;
+	ULONG	rsv:3;
+#endif // RT_BIG_ENDIAN //
+} HT_BF_CAP, *PHT_BF_CAP;
+
+//  HT antenna selection field in HT Cap IE .
+typedef struct PACKED _HT_AS_CAP{
+#ifdef RT_BIG_ENDIAN
+	UCHAR	rsv:1;
+	UCHAR	TxSoundPPDU:1;
+	UCHAR	RxASel:1;
+	UCHAR	AntIndFbk:1;
+	UCHAR	ExpCSIFbk:1;
+	UCHAR	AntIndFbkTxASEL:1;
+	UCHAR	ExpCSIFbkTxASEL:1;
+	UCHAR	AntSelect:1;
+#else
+	UCHAR	AntSelect:1;
+	UCHAR	ExpCSIFbkTxASEL:1;
+	UCHAR	AntIndFbkTxASEL:1;
+	UCHAR	ExpCSIFbk:1;
+	UCHAR	AntIndFbk:1;
+	UCHAR	RxASel:1;
+	UCHAR	TxSoundPPDU:1;
+	UCHAR	rsv:1;
+#endif // RT_BIG_ENDIAN //
+} HT_AS_CAP, *PHT_AS_CAP;
+
+// Draft 1.0 set IE length 26, but is extensible..
+#define SIZE_HT_CAP_IE		26
+// The structure for HT Capability IE.
+typedef struct PACKED _HT_CAPABILITY_IE{
+	HT_CAP_INFO		HtCapInfo;
+	HT_CAP_PARM		HtCapParm;
+//	HT_MCS_SET		HtMCSSet;
+	UCHAR			MCSSet[16];
+	EXT_HT_CAP_INFO	ExtHtCapInfo;
+	HT_BF_CAP		TxBFCap;	// beamforming cap. rt2860c not support beamforming.
+	HT_AS_CAP		ASCap;	//antenna selection.
+} HT_CAPABILITY_IE, *PHT_CAPABILITY_IE;
+
+
+// 802.11n draft3 related structure definitions.
+// 7.3.2.60
+#define dot11OBSSScanPassiveDwell							20	// in TU. min amount of time that the STA continously scans each channel when performing an active OBSS scan.
+#define dot11OBSSScanActiveDwell							10	// in TU.min amount of time that the STA continously scans each channel when performing an passive OBSS scan.
+#define dot11BSSWidthTriggerScanInterval					300  // in sec. max interval between scan operations to be performed to detect BSS channel width trigger events.
+#define dot11OBSSScanPassiveTotalPerChannel					200	// in TU. min total amount of time that the STA scans each channel when performing a passive OBSS scan.
+#define dot11OBSSScanActiveTotalPerChannel					20	//in TU. min total amount of time that the STA scans each channel when performing a active OBSS scan
+#define dot11BSSWidthChannelTransactionDelayFactor			5	// min ratio between the delay time in performing a switch from 20MHz BSS to 20/40 BSS operation and the maxima
+																//	interval between overlapping BSS scan operations.
+#define dot11BSSScanActivityThreshold						25	// in %%, max total time that a STA may be active on the medium during a period of
+																//	(dot11BSSWidthChannelTransactionDelayFactor * dot11BSSWidthTriggerScanInterval) seconds without
+																//	being obligated to perform OBSS Scan operations. default is 25(== 0.25%)
+
+typedef struct PACKED _OVERLAP_BSS_SCAN_IE{
+	USHORT		ScanPassiveDwell;
+	USHORT		ScanActiveDwell;
+	USHORT		TriggerScanInt;				// Trigger scan interval
+	USHORT		PassiveTalPerChannel;		// passive total per channel
+	USHORT		ActiveTalPerChannel;		// active total per channel
+	USHORT		DelayFactor;				// BSS width channel transition delay factor
+	USHORT		ScanActThre;				// Scan Activity threshold
+}OVERLAP_BSS_SCAN_IE, *POVERLAP_BSS_SCAN_IE;
+
+
+//  7.3.2.56. 20/40 Coexistence element used in  Element ID = 72 = IE_2040_BSS_COEXIST
+typedef union PACKED _BSS_2040_COEXIST_IE{
+ struct PACKED {
+ #ifdef RT_BIG_ENDIAN
+	UCHAR	rsv:5;
+	UCHAR	BSS20WidthReq:1;
+	UCHAR	Intolerant40:1;
+	UCHAR	InfoReq:1;
+ #else
+	UCHAR	InfoReq:1;
+	UCHAR	Intolerant40:1;			// Inter-BSS. set 1 when prohibits a receiving BSS from operating as a 20/40 Mhz BSS.
+	UCHAR	BSS20WidthReq:1;		// Intra-BSS set 1 when prohibits a receiving AP from operating its BSS as a 20/40MHz BSS.
+	UCHAR	rsv:5;
+#endif // RT_BIG_ENDIAN //
+    } field;
+ UCHAR   word;
+} BSS_2040_COEXIST_IE, *PBSS_2040_COEXIST_IE;
+
+
+typedef struct  _TRIGGER_EVENTA{
+	BOOLEAN			bValid;
+	UCHAR	BSSID[6];
+	UCHAR	RegClass;	// Regulatory Class
+	USHORT	Channel;
+	ULONG	CDCounter;   // Maintain a seperate count down counter for each Event A.
+} TRIGGER_EVENTA, *PTRIGGER_EVENTA;
+
+// 20/40 trigger event table
+// If one Event A delete or created, or if Event B is detected or not detected, STA should send 2040BSSCoexistence to AP.
+#define MAX_TRIGGER_EVENT		64
+typedef struct  _TRIGGER_EVENT_TAB{
+	UCHAR	EventANo;
+	TRIGGER_EVENTA	EventA[MAX_TRIGGER_EVENT];
+	ULONG			EventBCountDown;	// Count down counter for Event B.
+} TRIGGER_EVENT_TAB, *PTRIGGER_EVENT_TAB;
+
+// 7.3.27 20/40 Bss Coexistence Mgmt capability used in extended capabilities information IE( ID = 127 = IE_EXT_CAPABILITY).
+//	This is the first octet and was defined in 802.11n D3.03 and 802.11yD9.0
+typedef struct PACKED _EXT_CAP_INFO_ELEMENT{
+#ifdef RT_BIG_ENDIAN
+	UCHAR	rsv2:5;
+	UCHAR	ExtendChannelSwitch:1;
+	UCHAR	rsv:1;
+	UCHAR	BssCoexistMgmtSupport:1;
+#else
+	UCHAR	BssCoexistMgmtSupport:1;
+	UCHAR	rsv:1;
+	UCHAR	ExtendChannelSwitch:1;
+	UCHAR	rsv2:5;
+#endif // RT_BIG_ENDIAN //
+}EXT_CAP_INFO_ELEMENT, *PEXT_CAP_INFO_ELEMENT;
+
+
+// 802.11n 7.3.2.61
+typedef struct PACKED _BSS_2040_COEXIST_ELEMENT{
+	UCHAR					ElementID;		// ID = IE_2040_BSS_COEXIST = 72
+	UCHAR					Len;
+	BSS_2040_COEXIST_IE		BssCoexistIe;
+}BSS_2040_COEXIST_ELEMENT, *PBSS_2040_COEXIST_ELEMENT;
+
+
+//802.11n 7.3.2.59
+typedef struct PACKED _BSS_2040_INTOLERANT_CH_REPORT{
+	UCHAR				ElementID;		// ID = IE_2040_BSS_INTOLERANT_REPORT = 73
+	UCHAR				Len;
+	UCHAR				RegulatoryClass;
+	UCHAR				ChList[0];
+}BSS_2040_INTOLERANT_CH_REPORT, *PBSS_2040_INTOLERANT_CH_REPORT;
+
+
+// The structure for channel switch annoucement IE. This is in 802.11n D3.03
+typedef struct PACKED _CHA_SWITCH_ANNOUNCE_IE{
+	UCHAR			SwitchMode;	//channel switch mode
+	UCHAR			NewChannel;	//
+	UCHAR			SwitchCount;	//
+} CHA_SWITCH_ANNOUNCE_IE, *PCHA_SWITCH_ANNOUNCE_IE;
+
+
+// The structure for channel switch annoucement IE. This is in 802.11n D3.03
+typedef struct PACKED _SEC_CHA_OFFSET_IE{
+	UCHAR			SecondaryChannelOffset;	 // 1: Secondary above, 3: Secondary below, 0: no Secondary
+} SEC_CHA_OFFSET_IE, *PSEC_CHA_OFFSET_IE;
+
+
+// This structure is extracted from struct RT_HT_CAPABILITY
+typedef struct {
+	BOOLEAN			bHtEnable;	 // If we should use ht rate.
+	BOOLEAN			bPreNHt;	 // If we should use ht rate.
+	//Substract from HT Capability IE
+	UCHAR			MCSSet[16];	//only supoort MCS=0-15,32 ,
+} RT_HT_PHY_INFO, *PRT_HT_PHY_INFO;
+
+//This structure substracts ralink supports from all 802.11n-related features.
+//Features not listed here but contained in 802.11n spec are not supported in rt2860.
+typedef struct {
+#ifdef RT_BIG_ENDIAN
+	USHORT	rsv:5;
+	USHORT	AmsduSize:1;	// Max receiving A-MSDU size
+	USHORT	AmsduEnable:1;	// Enable to transmit A-MSDU. Suggest disable. We should use A-MPDU to gain best benifit of 802.11n
+	USHORT	RxSTBC:2;	// 2 bits
+	USHORT	TxSTBC:1;
+	USHORT	ShortGIfor40:1;	//for40MHz
+	USHORT	ShortGIfor20:1;
+	USHORT	GF:1;	//green field
+	USHORT	MimoPs:2;//mimo power safe MMPS_
+	USHORT	ChannelWidth:1;
+#else
+	USHORT	ChannelWidth:1;
+	USHORT	MimoPs:2;//mimo power safe MMPS_
+	USHORT	GF:1;	//green field
+	USHORT	ShortGIfor20:1;
+	USHORT	ShortGIfor40:1;	//for40MHz
+	USHORT	TxSTBC:1;
+	USHORT	RxSTBC:2;	// 2 bits
+	USHORT	AmsduEnable:1;	// Enable to transmit A-MSDU. Suggest disable. We should use A-MPDU to gain best benifit of 802.11n
+	USHORT	AmsduSize:1;	// Max receiving A-MSDU size
+	USHORT	rsv:5;
+#endif
+
+	//Substract from Addiont HT INFO IE
+#ifdef RT_BIG_ENDIAN
+	UCHAR	RecomWidth:1;
+	UCHAR	ExtChanOffset:2;	// Please not the difference with following 	UCHAR	NewExtChannelOffset; from 802.11n
+	UCHAR	MpduDensity:3;
+	UCHAR	MaxRAmpduFactor:2;
+#else
+	UCHAR	MaxRAmpduFactor:2;
+	UCHAR	MpduDensity:3;
+	UCHAR	ExtChanOffset:2;	// Please not the difference with following 	UCHAR	NewExtChannelOffset; from 802.11n
+	UCHAR	RecomWidth:1;
+#endif
+
+#ifdef RT_BIG_ENDIAN
+	USHORT	rsv2:11;
+	USHORT	OBSS_NonHTExist:1;
+	USHORT	rsv3:1;
+	USHORT	NonGfPresent:1;
+	USHORT	OperaionMode:2;
+#else
+	USHORT	OperaionMode:2;
+	USHORT	NonGfPresent:1;
+	USHORT	rsv3:1;
+	USHORT	OBSS_NonHTExist:1;
+	USHORT	rsv2:11;
+#endif
+
+	// New Extension Channel Offset IE
+	UCHAR	NewExtChannelOffset;
+	// Extension Capability IE = 127
+	UCHAR	BSSCoexist2040;
+} RT_HT_CAPABILITY, *PRT_HT_CAPABILITY;
+
+//   field in Addtional HT Information IE .
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+	UCHAR	SerInterGranu:3;
+	UCHAR	S_PSMPSup:1;
+	UCHAR	RifsMode:1;
+	UCHAR	RecomWidth:1;
+	UCHAR	ExtChanOffset:2;
+#else
+	UCHAR	ExtChanOffset:2;
+	UCHAR	RecomWidth:1;
+	UCHAR	RifsMode:1;
+	UCHAR	S_PSMPSup:1;	 //Indicate support for scheduled PSMP
+	UCHAR	SerInterGranu:3;	 //service interval granularity
+#endif
+} ADD_HTINFO, *PADD_HTINFO;
+
+typedef struct PACKED{
+#ifdef RT_BIG_ENDIAN
+	USHORT	rsv2:11;
+	USHORT	OBSS_NonHTExist:1;
+	USHORT	rsv:1;
+	USHORT	NonGfPresent:1;
+	USHORT	OperaionMode:2;
+#else
+	USHORT	OperaionMode:2;
+	USHORT	NonGfPresent:1;
+	USHORT	rsv:1;
+	USHORT	OBSS_NonHTExist:1;
+	USHORT	rsv2:11;
+#endif
+} ADD_HTINFO2, *PADD_HTINFO2;
+
+
+// TODO: Need sync with spec about the definition of StbcMcs. In Draft 3.03, it's reserved.
+typedef struct PACKED{
+#ifdef RT_BIG_ENDIAN
+	USHORT	rsv:4;
+	USHORT	PcoPhase:1;
+	USHORT	PcoActive:1;
+	USHORT	LsigTxopProt:1;
+	USHORT	STBCBeacon:1;
+	USHORT	DualCTSProtect:1;
+	USHORT	DualBeacon:1;
+	USHORT	StbcMcs:6;
+#else
+	USHORT	StbcMcs:6;
+	USHORT	DualBeacon:1;
+	USHORT	DualCTSProtect:1;
+	USHORT	STBCBeacon:1;
+	USHORT	LsigTxopProt:1;	// L-SIG TXOP protection full support
+	USHORT	PcoActive:1;
+	USHORT	PcoPhase:1;
+	USHORT	rsv:4;
+#endif // RT_BIG_ENDIAN //
+} ADD_HTINFO3, *PADD_HTINFO3;
+
+#define SIZE_ADD_HT_INFO_IE		22
+typedef struct  PACKED{
+	UCHAR				ControlChan;
+	ADD_HTINFO			AddHtInfo;
+	ADD_HTINFO2			AddHtInfo2;
+	ADD_HTINFO3			AddHtInfo3;
+	UCHAR				MCSSet[16];		// Basic MCS set
+} ADD_HT_INFO_IE, *PADD_HT_INFO_IE;
+
+typedef struct  PACKED{
+	UCHAR				NewExtChanOffset;
+} NEW_EXT_CHAN_IE, *PNEW_EXT_CHAN_IE;
+
+
+// 4-byte HTC field.  maybe included in any frame except non-QOS data frame.  The Order bit must set 1.
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+    UINT32		RDG:1;	//RDG / More PPDU
+    UINT32		ACConstraint:1;	//feedback request
+    UINT32		rsv:5;  //calibration sequence
+    UINT32		ZLFAnnouce:1;	// ZLF announcement
+    UINT32		CSISTEERING:2;	//CSI/ STEERING
+    UINT32		FBKReq:2;	//feedback request
+    UINT32		CalSeq:2;  //calibration sequence
+    UINT32		CalPos:2;	// calibration position
+    UINT32		MFBorASC:7;	//Link adaptation feedback containing recommended MCS. 0x7f for no feedback or not available
+    UINT32		MFS:3;	//SET to the received value of MRS. 0x111 for unsolicited MFB.
+    UINT32		MRSorASI:3;	// MRQ Sequence identifier. unchanged during entire procedure. 0x000-0x110.
+    UINT32		MRQ:1;	//MCS feedback. Request for a MCS feedback
+    UINT32		TRQ:1;	//sounding request
+    UINT32		MA:1;	//management action payload exist in (QoS Null+HTC)
+#else
+    UINT32		MA:1;	//management action payload exist in (QoS Null+HTC)
+    UINT32		TRQ:1;	//sounding request
+    UINT32		MRQ:1;	//MCS feedback. Request for a MCS feedback
+    UINT32		MRSorASI:3;	// MRQ Sequence identifier. unchanged during entire procedure. 0x000-0x110.
+    UINT32		MFS:3;	//SET to the received value of MRS. 0x111 for unsolicited MFB.
+    UINT32		MFBorASC:7;	//Link adaptation feedback containing recommended MCS. 0x7f for no feedback or not available
+    UINT32		CalPos:2;	// calibration position
+    UINT32		CalSeq:2;  //calibration sequence
+    UINT32		FBKReq:2;	//feedback request
+    UINT32		CSISTEERING:2;	//CSI/ STEERING
+    UINT32		ZLFAnnouce:1;	// ZLF announcement
+    UINT32		rsv:5;  //calibration sequence
+    UINT32		ACConstraint:1;	//feedback request
+    UINT32		RDG:1;	//RDG / More PPDU
+#endif /* !RT_BIG_ENDIAN */
+} HT_CONTROL, *PHT_CONTROL;
+
+// 2-byte QOS CONTROL field
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+    USHORT      Txop_QueueSize:8;
+    USHORT      AMsduPresent:1;
+    USHORT      AckPolicy:2;  //0: normal ACK 1:No ACK 2:scheduled under MTBA/PSMP  3: BA
+    USHORT      EOSP:1;
+    USHORT      TID:4;
+#else
+    USHORT      TID:4;
+    USHORT      EOSP:1;
+    USHORT      AckPolicy:2;  //0: normal ACK 1:No ACK 2:scheduled under MTBA/PSMP  3: BA
+    USHORT      AMsduPresent:1;
+    USHORT      Txop_QueueSize:8;
+#endif /* !RT_BIG_ENDIAN */
+} QOS_CONTROL, *PQOS_CONTROL;
+
+// 2-byte Frame control field
+typedef	struct	PACKED {
+#ifdef RT_BIG_ENDIAN
+	USHORT		Order:1;			// Strict order expected
+	USHORT		Wep:1;				// Wep data
+	USHORT		MoreData:1;			// More data bit
+	USHORT		PwrMgmt:1;			// Power management bit
+	USHORT		Retry:1;			// Retry status bit
+	USHORT		MoreFrag:1;			// More fragment bit
+	USHORT		FrDs:1;				// From DS indication
+	USHORT		ToDs:1;				// To DS indication
+	USHORT		SubType:4;			// MSDU subtype
+	USHORT		Type:2;				// MSDU type
+	USHORT		Ver:2;				// Protocol version
+#else
+	USHORT		Ver:2;				// Protocol version
+	USHORT		Type:2;				// MSDU type
+	USHORT		SubType:4;			// MSDU subtype
+	USHORT		ToDs:1;				// To DS indication
+	USHORT		FrDs:1;				// From DS indication
+	USHORT		MoreFrag:1;			// More fragment bit
+	USHORT		Retry:1;			// Retry status bit
+	USHORT		PwrMgmt:1;			// Power management bit
+	USHORT		MoreData:1;			// More data bit
+	USHORT		Wep:1;				// Wep data
+	USHORT		Order:1;			// Strict order expected
+#endif /* !RT_BIG_ENDIAN */
+} FRAME_CONTROL, *PFRAME_CONTROL;
+
+typedef	struct	PACKED _HEADER_802_11	{
+    FRAME_CONTROL   FC;
+    USHORT          Duration;
+    UCHAR           Addr1[MAC_ADDR_LEN];
+    UCHAR           Addr2[MAC_ADDR_LEN];
+	UCHAR			Addr3[MAC_ADDR_LEN];
+#ifdef RT_BIG_ENDIAN
+	USHORT			Sequence:12;
+	USHORT			Frag:4;
+#else
+	USHORT			Frag:4;
+	USHORT			Sequence:12;
+#endif /* !RT_BIG_ENDIAN */
+	UCHAR			Octet[0];
+}	HEADER_802_11, *PHEADER_802_11;
+
+typedef struct PACKED _FRAME_802_11 {
+    HEADER_802_11   Hdr;
+    UCHAR            Octet[1];
+}   FRAME_802_11, *PFRAME_802_11;
+
+// QoSNull embedding of management action. When HT Control MA field set to 1.
+typedef struct PACKED _MA_BODY {
+    UCHAR            Category;
+    UCHAR            Action;
+    UCHAR            Octet[1];
+}   MA_BODY, *PMA_BODY;
+
+typedef	struct	PACKED _HEADER_802_3	{
+    UCHAR           DAAddr1[MAC_ADDR_LEN];
+    UCHAR           SAAddr2[MAC_ADDR_LEN];
+    UCHAR           Octet[2];
+}	HEADER_802_3, *PHEADER_802_3;
+////Block ACK related format
+// 2-byte BA Parameter  field  in 	DELBA frames to terminate an already set up bA
+typedef struct PACKED{
+#ifdef RT_BIG_ENDIAN
+    USHORT      TID:4;	// value of TC os TS
+    USHORT      Initiator:1;	// 1: originator    0:recipient
+    USHORT      Rsv:11;	// always set to 0
+#else
+    USHORT      Rsv:11;	// always set to 0
+    USHORT      Initiator:1;	// 1: originator    0:recipient
+    USHORT      TID:4;	// value of TC os TS
+#endif /* !RT_BIG_ENDIAN */
+} DELBA_PARM, *PDELBA_PARM;
+
+// 2-byte BA Parameter Set field  in ADDBA frames to signal parm for setting up a BA
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+    USHORT      BufSize:10;	// number of buffe of size 2304 octetsr
+    USHORT      TID:4;	// value of TC os TS
+    USHORT      BAPolicy:1;	// 1: immediately BA    0:delayed BA
+    USHORT      AMSDUSupported:1;	// 0: not permitted		1: permitted
+#else
+    USHORT      AMSDUSupported:1;	// 0: not permitted		1: permitted
+    USHORT      BAPolicy:1;	// 1: immediately BA    0:delayed BA
+    USHORT      TID:4;	// value of TC os TS
+    USHORT      BufSize:10;	// number of buffe of size 2304 octetsr
+#endif /* !RT_BIG_ENDIAN */
+} BA_PARM, *PBA_PARM;
+
+// 2-byte BA Starting Seq CONTROL field
+typedef union PACKED {
+    struct PACKED {
+#ifdef RT_BIG_ENDIAN
+    USHORT      StartSeq:12;   // sequence number of the 1st MSDU for which this BAR is sent
+	USHORT      FragNum:4;	// always set to 0
+#else
+    USHORT      FragNum:4;	// always set to 0
+	USHORT      StartSeq:12;   // sequence number of the 1st MSDU for which this BAR is sent
+#endif /* RT_BIG_ENDIAN */
+    }   field;
+    USHORT           word;
+} BASEQ_CONTROL, *PBASEQ_CONTROL;
+
+//BAControl and BARControl are the same
+// 2-byte BA CONTROL field in BA frame
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+    USHORT      TID:4;
+    USHORT      Rsv:9;
+    USHORT      Compressed:1;
+    USHORT      MTID:1;		//EWC V1.24
+    USHORT      ACKPolicy:1; // only related to N-Delayed BA. But not support in RT2860b. 0:NormalACK  1:No ACK
+#else
+    USHORT      ACKPolicy:1; // only related to N-Delayed BA. But not support in RT2860b. 0:NormalACK  1:No ACK
+    USHORT      MTID:1;		//EWC V1.24
+    USHORT      Compressed:1;
+    USHORT      Rsv:9;
+    USHORT      TID:4;
+#endif /* !RT_BIG_ENDIAN */
+} BA_CONTROL, *PBA_CONTROL;
+
+// 2-byte BAR CONTROL field in BAR frame
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+    USHORT      TID:4;
+    USHORT      Rsv1:9;
+    USHORT      Compressed:1;
+    USHORT      MTID:1;		//if this bit1, use  FRAME_MTBA_REQ,  if 0, use FRAME_BA_REQ
+    USHORT      ACKPolicy:1;
+#else
+    USHORT      ACKPolicy:1; // 0:normal ack,  1:no ack.
+    USHORT      MTID:1;		//if this bit1, use  FRAME_MTBA_REQ,  if 0, use FRAME_BA_REQ
+    USHORT      Compressed:1;
+    USHORT      Rsv1:9;
+    USHORT      TID:4;
+#endif /* !RT_BIG_ENDIAN */
+} BAR_CONTROL, *PBAR_CONTROL;
+
+// BARControl in MTBAR frame
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+    USHORT      NumTID:4;
+    USHORT      Rsv1:9;
+    USHORT      Compressed:1;
+    USHORT      MTID:1;
+    USHORT      ACKPolicy:1;
+#else
+    USHORT      ACKPolicy:1;
+    USHORT      MTID:1;
+    USHORT      Compressed:1;
+    USHORT      Rsv1:9;
+    USHORT      NumTID:4;
+#endif /* !RT_BIG_ENDIAN */
+} MTBAR_CONTROL, *PMTBAR_CONTROL;
+
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+    USHORT      TID:4;
+    USHORT      Rsv1:12;
+#else
+    USHORT      Rsv1:12;
+    USHORT      TID:4;
+#endif /* !RT_BIG_ENDIAN */
+} PER_TID_INFO, *PPER_TID_INFO;
+
+typedef struct {
+	PER_TID_INFO      PerTID;
+	BASEQ_CONTROL 	 BAStartingSeq;
+} EACH_TID, *PEACH_TID;
+
+
+typedef struct PACKED _PSPOLL_FRAME {
+    FRAME_CONTROL   FC;
+    USHORT          Aid;
+    UCHAR           Bssid[MAC_ADDR_LEN];
+    UCHAR           Ta[MAC_ADDR_LEN];
+}   PSPOLL_FRAME, *PPSPOLL_FRAME;
+
+typedef	struct	PACKED _RTS_FRAME	{
+    FRAME_CONTROL   FC;
+    USHORT          Duration;
+    UCHAR           Addr1[MAC_ADDR_LEN];
+    UCHAR           Addr2[MAC_ADDR_LEN];
+}RTS_FRAME, *PRTS_FRAME;
+
+// BAREQ AND MTBAREQ have the same subtype BAR, 802.11n BAR use compressed bitmap.
+typedef struct PACKED _FRAME_BA_REQ {
+	FRAME_CONTROL   FC;
+	USHORT          Duration;
+	UCHAR           Addr1[MAC_ADDR_LEN];
+	UCHAR           Addr2[MAC_ADDR_LEN];
+	BAR_CONTROL  BARControl;
+	BASEQ_CONTROL 	 BAStartingSeq;
+}   FRAME_BA_REQ, *PFRAME_BA_REQ;
+
+typedef struct PACKED _FRAME_MTBA_REQ {
+	FRAME_CONTROL   FC;
+	USHORT          Duration;
+	UCHAR           Addr1[MAC_ADDR_LEN];
+	UCHAR           Addr2[MAC_ADDR_LEN];
+	MTBAR_CONTROL  MTBARControl;
+	PER_TID_INFO	PerTIDInfo;
+	BASEQ_CONTROL 	 BAStartingSeq;
+}   FRAME_MTBA_REQ, *PFRAME_MTBA_REQ;
+
+// Compressed format is mandantory in HT STA
+typedef struct PACKED _FRAME_MTBA {
+	FRAME_CONTROL   FC;
+	USHORT          Duration;
+	UCHAR           Addr1[MAC_ADDR_LEN];
+	UCHAR           Addr2[MAC_ADDR_LEN];
+	BA_CONTROL  BAControl;
+	BASEQ_CONTROL 	 BAStartingSeq;
+	UCHAR		BitMap[8];
+}   FRAME_MTBA, *PFRAME_MTBA;
+
+typedef struct PACKED _FRAME_PSMP_ACTION {
+	HEADER_802_11   Hdr;
+	UCHAR	Category;
+	UCHAR	Action;
+	UCHAR	Psmp;	// 7.3.1.25
+}   FRAME_PSMP_ACTION, *PFRAME_PSMP_ACTION;
+
+typedef struct PACKED _FRAME_ACTION_HDR {
+	HEADER_802_11   Hdr;
+	UCHAR	Category;
+	UCHAR	Action;
+}   FRAME_ACTION_HDR, *PFRAME_ACTION_HDR;
+
+//Action Frame
+//Action Frame  Category:Spectrum,  Action:Channel Switch. 7.3.2.20
+typedef struct PACKED _CHAN_SWITCH_ANNOUNCE {
+	UCHAR					ElementID;	// ID = IE_CHANNEL_SWITCH_ANNOUNCEMENT = 37
+	UCHAR					Len;
+	CHA_SWITCH_ANNOUNCE_IE	CSAnnounceIe;
+}   CHAN_SWITCH_ANNOUNCE, *PCHAN_SWITCH_ANNOUNCE;
+
+
+//802.11n : 7.3.2.20a
+typedef struct PACKED _SECOND_CHAN_OFFSET {
+	UCHAR				ElementID;		// ID = IE_SECONDARY_CH_OFFSET = 62
+	UCHAR				Len;
+	SEC_CHA_OFFSET_IE	SecChOffsetIe;
+}   SECOND_CHAN_OFFSET, *PSECOND_CHAN_OFFSET;
+
+
+typedef struct PACKED _FRAME_SPETRUM_CS {
+	HEADER_802_11   Hdr;
+	UCHAR	Category;
+	UCHAR	Action;
+	CHAN_SWITCH_ANNOUNCE	CSAnnounce;
+	SECOND_CHAN_OFFSET		SecondChannel;
+}   FRAME_SPETRUM_CS, *PFRAME_SPETRUM_CS;
+
+
+typedef struct PACKED _FRAME_ADDBA_REQ {
+	HEADER_802_11   Hdr;
+	UCHAR	Category;
+	UCHAR	Action;
+	UCHAR	Token;	// 1
+	BA_PARM		BaParm;	      //  2 - 10
+	USHORT		TimeOutValue;	// 0 - 0
+	BASEQ_CONTROL	BaStartSeq; // 0-0
+}   FRAME_ADDBA_REQ, *PFRAME_ADDBA_REQ;
+
+typedef struct PACKED _FRAME_ADDBA_RSP {
+	HEADER_802_11   Hdr;
+	UCHAR	Category;
+	UCHAR	Action;
+	UCHAR	Token;
+	USHORT	StatusCode;
+	BA_PARM		BaParm; //0 - 2
+	USHORT		TimeOutValue;
+}   FRAME_ADDBA_RSP, *PFRAME_ADDBA_RSP;
+
+typedef struct PACKED _FRAME_DELBA_REQ {
+	HEADER_802_11   Hdr;
+	UCHAR	Category;
+	UCHAR	Action;
+	DELBA_PARM		DelbaParm;
+	USHORT	ReasonCode;
+}   FRAME_DELBA_REQ, *PFRAME_DELBA_REQ;
+
+
+//7.2.1.7
+typedef struct PACKED _FRAME_BAR {
+	FRAME_CONTROL   FC;
+	USHORT          Duration;
+	UCHAR           Addr1[MAC_ADDR_LEN];
+	UCHAR           Addr2[MAC_ADDR_LEN];
+	BAR_CONTROL		BarControl;
+	BASEQ_CONTROL	StartingSeq;
+}   FRAME_BAR, *PFRAME_BAR;
+
+//7.2.1.7
+typedef struct PACKED _FRAME_BA {
+	FRAME_CONTROL   FC;
+	USHORT          Duration;
+	UCHAR           Addr1[MAC_ADDR_LEN];
+	UCHAR           Addr2[MAC_ADDR_LEN];
+	BAR_CONTROL		BarControl;
+	BASEQ_CONTROL	StartingSeq;
+	UCHAR		bitmask[8];
+}   FRAME_BA, *PFRAME_BA;
+
+
+// Radio Measuement Request Frame Format
+typedef struct PACKED _FRAME_RM_REQ_ACTION {
+	HEADER_802_11   Hdr;
+	UCHAR	Category;
+	UCHAR	Action;
+	UCHAR	Token;
+	USHORT	Repetition;
+	UCHAR   data[0];
+}   FRAME_RM_REQ_ACTION, *PFRAME_RM_REQ_ACTION;
+
+typedef struct PACKED {
+	UCHAR		ID;
+	UCHAR		Length;
+	UCHAR		ChannelSwitchMode;
+	UCHAR		NewRegClass;
+	UCHAR		NewChannelNum;
+	UCHAR		ChannelSwitchCount;
+} HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE, *PHT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE;
+
+
+//
+// _Limit must be the 2**n - 1
+// _SEQ1 , _SEQ2 must be within 0 ~ _Limit
+//
+#define SEQ_STEPONE(_SEQ1, _SEQ2, _Limit)	((_SEQ1 == ((_SEQ2+1) & _Limit)))
+#define SEQ_SMALLER(_SEQ1, _SEQ2, _Limit)	(((_SEQ1-_SEQ2) & ((_Limit+1)>>1)))
+#define SEQ_LARGER(_SEQ1, _SEQ2, _Limit)	((_SEQ1 != _SEQ2) && !(((_SEQ1-_SEQ2) & ((_Limit+1)>>1))))
+#define SEQ_WITHIN_WIN(_SEQ1, _SEQ2, _WIN, _Limit) (SEQ_LARGER(_SEQ1, _SEQ2, _Limit) &&  \
+												SEQ_SMALLER(_SEQ1, ((_SEQ2+_WIN+1)&_Limit), _Limit))
+
+//
+// Contention-free parameter (without ID and Length)
+//
+typedef struct PACKED {
+    BOOLEAN     bValid;         // 1: variable contains valid value
+    UCHAR       CfpCount;
+    UCHAR       CfpPeriod;
+    USHORT      CfpMaxDuration;
+    USHORT      CfpDurRemaining;
+} CF_PARM, *PCF_PARM;
+
+typedef	struct	_CIPHER_SUITE	{
+	NDIS_802_11_ENCRYPTION_STATUS	PairCipher;		// Unicast cipher 1, this one has more secured cipher suite
+	NDIS_802_11_ENCRYPTION_STATUS	PairCipherAux;	// Unicast cipher 2 if AP announce two unicast cipher suite
+	NDIS_802_11_ENCRYPTION_STATUS	GroupCipher;	// Group cipher
+	USHORT							RsnCapability;	// RSN capability from beacon
+	BOOLEAN							bMixMode;		// Indicate Pair & Group cipher might be different
+}	CIPHER_SUITE, *PCIPHER_SUITE;
+
+// EDCA configuration from AP's BEACON/ProbeRsp
+typedef struct {
+    BOOLEAN     bValid;         // 1: variable contains valid value
+    BOOLEAN     bAdd;         // 1: variable contains valid value
+    BOOLEAN     bQAck;
+    BOOLEAN     bQueueRequest;
+    BOOLEAN     bTxopRequest;
+    BOOLEAN     bAPSDCapable;
+//  BOOLEAN     bMoreDataAck;
+    UCHAR       EdcaUpdateCount;
+    UCHAR       Aifsn[4];       // 0:AC_BK, 1:AC_BE, 2:AC_VI, 3:AC_VO
+    UCHAR       Cwmin[4];
+    UCHAR       Cwmax[4];
+    USHORT      Txop[4];      // in unit of 32-us
+    BOOLEAN     bACM[4];      // 1: Admission Control of AC_BK is mandattory
+} EDCA_PARM, *PEDCA_PARM;
+
+// QBSS LOAD information from QAP's BEACON/ProbeRsp
+typedef struct {
+    BOOLEAN     bValid;                     // 1: variable contains valid value
+    USHORT      StaNum;
+    UCHAR       ChannelUtilization;
+    USHORT      RemainingAdmissionControl;  // in unit of 32-us
+} QBSS_LOAD_PARM, *PQBSS_LOAD_PARM;
+
+// QBSS Info field in QSTA's assoc req
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+	UCHAR		Rsv2:1;
+	UCHAR		MaxSPLength:2;
+	UCHAR		Rsv1:1;
+	UCHAR		UAPSD_AC_BE:1;
+	UCHAR		UAPSD_AC_BK:1;
+	UCHAR		UAPSD_AC_VI:1;
+	UCHAR		UAPSD_AC_VO:1;
+#else
+    UCHAR		UAPSD_AC_VO:1;
+	UCHAR		UAPSD_AC_VI:1;
+	UCHAR		UAPSD_AC_BK:1;
+	UCHAR		UAPSD_AC_BE:1;
+	UCHAR		Rsv1:1;
+	UCHAR		MaxSPLength:2;
+	UCHAR		Rsv2:1;
+#endif /* !RT_BIG_ENDIAN */
+} QBSS_STA_INFO_PARM, *PQBSS_STA_INFO_PARM;
+
+// QBSS Info field in QAP's Beacon/ProbeRsp
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+	UCHAR		UAPSD:1;
+	UCHAR		Rsv:3;
+    UCHAR		ParamSetCount:4;
+#else
+    UCHAR		ParamSetCount:4;
+	UCHAR		Rsv:3;
+	UCHAR		UAPSD:1;
+#endif /* !RT_BIG_ENDIAN */
+} QBSS_AP_INFO_PARM, *PQBSS_AP_INFO_PARM;
+
+// QOS Capability reported in QAP's BEACON/ProbeRsp
+// QOS Capability sent out in QSTA's AssociateReq/ReAssociateReq
+typedef struct {
+    BOOLEAN     bValid;                     // 1: variable contains valid value
+    BOOLEAN     bQAck;
+    BOOLEAN     bQueueRequest;
+    BOOLEAN     bTxopRequest;
+//  BOOLEAN     bMoreDataAck;
+    UCHAR       EdcaUpdateCount;
+} QOS_CAPABILITY_PARM, *PQOS_CAPABILITY_PARM;
+
+#ifdef CONFIG_STA_SUPPORT
+typedef struct {
+    UCHAR       IELen;
+    UCHAR       IE[MAX_CUSTOM_LEN];
+} WPA_IE_;
+#endif // CONFIG_STA_SUPPORT //
+
+
+typedef struct {
+    UCHAR   Bssid[MAC_ADDR_LEN];
+    UCHAR   Channel;
+	UCHAR   CentralChannel;	//Store the wide-band central channel for 40MHz.  .used in 40MHz AP. Or this is the same as Channel.
+    UCHAR   BssType;
+    USHORT  AtimWin;
+    USHORT  BeaconPeriod;
+
+    UCHAR   SupRate[MAX_LEN_OF_SUPPORTED_RATES];
+    UCHAR   SupRateLen;
+    UCHAR   ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+    UCHAR   ExtRateLen;
+	HT_CAPABILITY_IE HtCapability;
+	UCHAR			HtCapabilityLen;
+	ADD_HT_INFO_IE AddHtInfo;	// AP might use this additional ht info IE
+	UCHAR			AddHtInfoLen;
+	UCHAR			NewExtChanOffset;
+	CHAR    Rssi;
+    UCHAR   Privacy;			// Indicate security function ON/OFF. Don't mess up with auth mode.
+	UCHAR	Hidden;
+
+    USHORT  DtimPeriod;
+    USHORT  CapabilityInfo;
+
+    USHORT  CfpCount;
+    USHORT  CfpPeriod;
+    USHORT  CfpMaxDuration;
+    USHORT  CfpDurRemaining;
+    UCHAR   SsidLen;
+    CHAR    Ssid[MAX_LEN_OF_SSID];
+
+    ULONG   LastBeaconRxTime; // OS's timestamp
+
+	BOOLEAN	bSES;
+
+	// New for WPA2
+	CIPHER_SUITE					WPA;			// AP announced WPA cipher suite
+	CIPHER_SUITE					WPA2;			// AP announced WPA2 cipher suite
+
+	// New for microsoft WPA support
+	NDIS_802_11_FIXED_IEs	FixIEs;
+	NDIS_802_11_AUTHENTICATION_MODE	AuthModeAux;	// Addition mode for WPA2 / WPA capable AP
+	NDIS_802_11_AUTHENTICATION_MODE	AuthMode;
+	NDIS_802_11_WEP_STATUS	WepStatus;				// Unicast Encryption Algorithm extract from VAR_IE
+	USHORT					VarIELen;				// Length of next VIE include EID & Length
+	UCHAR					VarIEs[MAX_VIE_LEN];
+
+	// CCX Ckip information
+    UCHAR   CkipFlag;
+
+	// CCX 2 TSF
+	UCHAR	PTSF[4];		// Parent TSF
+	UCHAR	TTSF[8];		// Target TSF
+
+    // 802.11e d9, and WMM
+	EDCA_PARM           EdcaParm;
+	QOS_CAPABILITY_PARM QosCapability;
+	QBSS_LOAD_PARM      QbssLoad;
+#ifdef CONFIG_STA_SUPPORT
+    WPA_IE_     WpaIE;
+    WPA_IE_     RsnIE;
+#ifdef EXT_BUILD_CHANNEL_LIST
+	UCHAR		CountryString[3];
+	BOOLEAN		bHasCountryIE;
+#endif // EXT_BUILD_CHANNEL_LIST //
+#endif // CONFIG_STA_SUPPORT //
+} BSS_ENTRY, *PBSS_ENTRY;
+
+typedef struct {
+    UCHAR           BssNr;
+    UCHAR           BssOverlapNr;
+    BSS_ENTRY       BssEntry[MAX_LEN_OF_BSS_TABLE];
+} BSS_TABLE, *PBSS_TABLE;
+
+
+typedef struct _MLME_QUEUE_ELEM {
+    ULONG             Machine;
+    ULONG             MsgType;
+    ULONG             MsgLen;
+    UCHAR             Msg[MGMT_DMA_BUFFER_SIZE];
+    LARGE_INTEGER     TimeStamp;
+    UCHAR             Rssi0;
+    UCHAR             Rssi1;
+    UCHAR             Rssi2;
+    UCHAR             Signal;
+    UCHAR             Channel;
+    UCHAR             Wcid;
+    BOOLEAN           Occupied;
+#ifdef MLME_EX
+	USHORT            Idx;
+#endif // MLME_EX //
+} MLME_QUEUE_ELEM, *PMLME_QUEUE_ELEM;
+
+typedef struct _MLME_QUEUE {
+    ULONG             Num;
+    ULONG             Head;
+    ULONG             Tail;
+    NDIS_SPIN_LOCK   Lock;
+    MLME_QUEUE_ELEM  Entry[MAX_LEN_OF_MLME_QUEUE];
+} MLME_QUEUE, *PMLME_QUEUE;
+
+typedef VOID (*STATE_MACHINE_FUNC)(VOID *Adaptor, MLME_QUEUE_ELEM *Elem);
+
+typedef struct _STATE_MACHINE {
+    ULONG                           Base;
+    ULONG                           NrState;
+    ULONG                           NrMsg;
+    ULONG                           CurrState;
+    STATE_MACHINE_FUNC             *TransFunc;
+} STATE_MACHINE, *PSTATE_MACHINE;
+
+
+// MLME AUX data structure that hold temporarliy settings during a connection attempt.
+// Once this attemp succeeds, all settings will be copy to pAd->StaActive.
+// A connection attempt (user set OID, roaming, CCX fast roaming,..) consists of
+// several steps (JOIN, AUTH, ASSOC or REASSOC) and may fail at any step. We purposely
+// separate this under-trial settings away from pAd->StaActive so that once
+// this new attempt failed, driver can auto-recover back to the active settings.
+typedef struct _MLME_AUX {
+    UCHAR               BssType;
+    UCHAR               Ssid[MAX_LEN_OF_SSID];
+    UCHAR               SsidLen;
+    UCHAR               Bssid[MAC_ADDR_LEN];
+	UCHAR				AutoReconnectSsid[MAX_LEN_OF_SSID];
+	UCHAR				AutoReconnectSsidLen;
+    USHORT              Alg;
+    UCHAR               ScanType;
+    UCHAR               Channel;
+	UCHAR               CentralChannel;
+    USHORT              Aid;
+    USHORT              CapabilityInfo;
+    USHORT              BeaconPeriod;
+    USHORT              CfpMaxDuration;
+    USHORT              CfpPeriod;
+    USHORT              AtimWin;
+
+	// Copy supported rate from desired AP's beacon. We are trying to match
+	// AP's supported and extended rate settings.
+	UCHAR		        SupRate[MAX_LEN_OF_SUPPORTED_RATES];
+	UCHAR		        ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+	UCHAR		        SupRateLen;
+	UCHAR		        ExtRateLen;
+	HT_CAPABILITY_IE		HtCapability;
+	UCHAR		        	HtCapabilityLen;
+	ADD_HT_INFO_IE		AddHtInfo;	// AP might use this additional ht info IE
+	UCHAR			NewExtChannelOffset;
+	//RT_HT_CAPABILITY	SupportedHtPhy;
+
+    // new for QOS
+    QOS_CAPABILITY_PARM APQosCapability;    // QOS capability of the current associated AP
+    EDCA_PARM           APEdcaParm;         // EDCA parameters of the current associated AP
+    QBSS_LOAD_PARM      APQbssLoad;         // QBSS load of the current associated AP
+
+    // new to keep Ralink specific feature
+    ULONG               APRalinkIe;
+
+    BSS_TABLE           SsidBssTab;     // AP list for the same SSID
+    BSS_TABLE           RoamTab;        // AP list eligible for roaming
+    ULONG               BssIdx;
+    ULONG               RoamIdx;
+
+	BOOLEAN				CurrReqIsFromNdis;
+
+    RALINK_TIMER_STRUCT BeaconTimer, ScanTimer;
+    RALINK_TIMER_STRUCT AuthTimer;
+    RALINK_TIMER_STRUCT AssocTimer, ReassocTimer, DisassocTimer;
+} MLME_AUX, *PMLME_AUX;
+
+typedef struct _MLME_ADDBA_REQ_STRUCT{
+	UCHAR   Wcid;	//
+	UCHAR   pAddr[MAC_ADDR_LEN];
+	UCHAR   BaBufSize;
+	USHORT	TimeOutValue;
+	UCHAR   TID;
+	UCHAR   Token;
+	USHORT	BaStartSeq;
+} MLME_ADDBA_REQ_STRUCT, *PMLME_ADDBA_REQ_STRUCT;
+
+
+typedef struct _MLME_DELBA_REQ_STRUCT{
+	UCHAR   Wcid;	//
+	UCHAR     Addr[MAC_ADDR_LEN];
+	UCHAR   TID;
+	UCHAR	Initiator;
+} MLME_DELBA_REQ_STRUCT, *PMLME_DELBA_REQ_STRUCT;
+
+// assoc struct is equal to reassoc
+typedef struct _MLME_ASSOC_REQ_STRUCT{
+    UCHAR     Addr[MAC_ADDR_LEN];
+    USHORT    CapabilityInfo;
+    USHORT    ListenIntv;
+    ULONG     Timeout;
+} MLME_ASSOC_REQ_STRUCT, *PMLME_ASSOC_REQ_STRUCT, MLME_REASSOC_REQ_STRUCT, *PMLME_REASSOC_REQ_STRUCT;
+
+typedef struct _MLME_DISASSOC_REQ_STRUCT{
+    UCHAR     Addr[MAC_ADDR_LEN];
+    USHORT    Reason;
+} MLME_DISASSOC_REQ_STRUCT, *PMLME_DISASSOC_REQ_STRUCT;
+
+typedef struct _MLME_AUTH_REQ_STRUCT {
+    UCHAR        Addr[MAC_ADDR_LEN];
+    USHORT       Alg;
+    ULONG        Timeout;
+} MLME_AUTH_REQ_STRUCT, *PMLME_AUTH_REQ_STRUCT;
+
+typedef struct _MLME_DEAUTH_REQ_STRUCT {
+    UCHAR        Addr[MAC_ADDR_LEN];
+    USHORT       Reason;
+} MLME_DEAUTH_REQ_STRUCT, *PMLME_DEAUTH_REQ_STRUCT;
+
+typedef struct {
+    ULONG      BssIdx;
+} MLME_JOIN_REQ_STRUCT;
+
+typedef struct _MLME_SCAN_REQ_STRUCT {
+    UCHAR      Bssid[MAC_ADDR_LEN];
+    UCHAR      BssType;
+    UCHAR      ScanType;
+    UCHAR      SsidLen;
+    CHAR       Ssid[MAX_LEN_OF_SSID];
+} MLME_SCAN_REQ_STRUCT, *PMLME_SCAN_REQ_STRUCT;
+
+typedef struct _MLME_START_REQ_STRUCT {
+    CHAR        Ssid[MAX_LEN_OF_SSID];
+    UCHAR       SsidLen;
+} MLME_START_REQ_STRUCT, *PMLME_START_REQ_STRUCT;
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+// structure for DLS
+typedef struct _RT_802_11_DLS {
+	USHORT						TimeOut;		// Use to time out while slience, unit: second , set by UI
+	USHORT						CountDownTimer;	// Use to time out while slience,unit: second , used by driver only
+	NDIS_802_11_MAC_ADDRESS		MacAddr;		// set by UI
+	UCHAR						Status;			// 0: none , 1: wait STAkey, 2: finish DLS setup , set by driver only
+	BOOLEAN						Valid;			// 1: valid , 0: invalid , set by UI, use to setup or tear down DLS link
+	RALINK_TIMER_STRUCT			Timer;			// Use to time out while handshake
+	USHORT						Sequence;
+	USHORT						MacTabMatchWCID;	// ASIC
+	BOOLEAN						bHTCap;
+	PVOID						pAd;
+} RT_802_11_DLS, *PRT_802_11_DLS;
+
+typedef struct _MLME_DLS_REQ_STRUCT {
+    PRT_802_11_DLS	pDLS;
+    USHORT			Reason;
+} MLME_DLS_REQ_STRUCT, *PMLME_DLS_REQ_STRUCT;
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+typedef struct PACKED {
+    UCHAR   Eid;
+    UCHAR   Len;
+    CHAR   Octet[1];
+} EID_STRUCT,*PEID_STRUCT, BEACON_EID_STRUCT, *PBEACON_EID_STRUCT;
+
+typedef struct PACKED _RTMP_TX_RATE_SWITCH
+{
+	UCHAR   ItemNo;
+#ifdef RT_BIG_ENDIAN
+	UCHAR	Rsv2:2;
+	UCHAR	Mode:2;
+	UCHAR	Rsv1:1;
+	UCHAR	BW:1;
+	UCHAR	ShortGI:1;
+	UCHAR	STBC:1;
+#else
+	UCHAR	STBC:1;
+	UCHAR	ShortGI:1;
+	UCHAR	BW:1;
+	UCHAR	Rsv1:1;
+	UCHAR	Mode:2;
+	UCHAR	Rsv2:2;
+#endif
+	UCHAR   CurrMCS;
+	UCHAR   TrainUp;
+	UCHAR   TrainDown;
+} RRTMP_TX_RATE_SWITCH, *PRTMP_TX_RATE_SWITCH;
+
+// ========================== AP mlme.h ===============================
+#define TBTT_PRELOAD_TIME       384        // usec. LomgPreamble + 24-byte at 1Mbps
+#define DEFAULT_DTIM_PERIOD     1
+
+// weighting factor to calculate Channel quality, total should be 100%
+//#define RSSI_WEIGHTING                   0
+//#define TX_WEIGHTING                     40
+//#define RX_WEIGHTING                     60
+
+#define MAC_TABLE_AGEOUT_TIME			300			// unit: sec
+#define MAC_TABLE_ASSOC_TIMEOUT			5			// unit: sec
+#define MAC_TABLE_FULL(Tab)				((Tab).size == MAX_LEN_OF_MAC_TABLE)
+
+// AP shall drop the sta if contine Tx fail count reach it.
+#define MAC_ENTRY_LIFE_CHECK_CNT		20			// packet cnt.
+
+// Value domain of pMacEntry->Sst
+typedef enum _Sst {
+    SST_NOT_AUTH,   // 0: equivalent to IEEE 802.11/1999 state 1
+    SST_AUTH,       // 1: equivalent to IEEE 802.11/1999 state 2
+    SST_ASSOC       // 2: equivalent to IEEE 802.11/1999 state 3
+} SST;
+
+// value domain of pMacEntry->AuthState
+typedef enum _AuthState {
+    AS_NOT_AUTH,
+    AS_AUTH_OPEN,       // STA has been authenticated using OPEN SYSTEM
+    AS_AUTH_KEY,        // STA has been authenticated using SHARED KEY
+    AS_AUTHENTICATING   // STA is waiting for AUTH seq#3 using SHARED KEY
+} AUTH_STATE;
+
+//for-wpa value domain of pMacEntry->WpaState  802.1i D3   p.114
+typedef enum _ApWpaState {
+    AS_NOTUSE,              // 0
+    AS_DISCONNECT,          // 1
+    AS_DISCONNECTED,        // 2
+    AS_INITIALIZE,          // 3
+    AS_AUTHENTICATION,      // 4
+    AS_AUTHENTICATION2,     // 5
+    AS_INITPMK,             // 6
+    AS_INITPSK,             // 7
+    AS_PTKSTART,            // 8
+    AS_PTKINIT_NEGOTIATING, // 9
+    AS_PTKINITDONE,         // 10
+    AS_UPDATEKEYS,          // 11
+    AS_INTEGRITY_FAILURE,   // 12
+    AS_KEYUPDATE,           // 13
+} AP_WPA_STATE;
+
+// for-wpa value domain of pMacEntry->WpaState  802.1i D3   p.114
+typedef enum _GTKState {
+    REKEY_NEGOTIATING,
+    REKEY_ESTABLISHED,
+    KEYERROR,
+} GTK_STATE;
+
+//  for-wpa  value domain of pMacEntry->WpaState  802.1i D3   p.114
+typedef enum _WpaGTKState {
+    SETKEYS,
+    SETKEYS_DONE,
+} WPA_GTK_STATE;
+// ====================== end of AP mlme.h ============================
+
+
+#endif	// MLME_H__
diff --git a/drivers/staging/rt3070/netif_block.h b/drivers/staging/rt3070/netif_block.h
new file mode 100644
index 0000000..6e5151c
--- /dev/null
+++ b/drivers/staging/rt3070/netif_block.h
@@ -0,0 +1,58 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+ */
+
+#ifndef __NET_IF_BLOCK_H__
+#define __NET_IF_BLOCK_H__
+
+//#include <linux/device.h>
+#include "link_list.h"
+#include "rtmp.h"
+
+#define FREE_NETIF_POOL_SIZE 32
+
+typedef struct _NETIF_ENTRY
+{
+	struct _NETIF_ENTRY *pNext;
+	PNET_DEV pNetDev;
+} NETIF_ENTRY, *PNETIF_ENTRY;
+
+void initblockQueueTab(
+	IN PRTMP_ADAPTER pAd);
+
+BOOLEAN blockNetIf(
+	IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry,
+	IN PNET_DEV pNetDev);
+
+VOID releaseNetIf(
+	IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry);
+
+VOID StopNetIfQueue(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR QueIdx,
+	IN PNDIS_PACKET pPacket);
+#endif // __NET_IF_BLOCK_H__
+
diff --git a/drivers/staging/rt3070/oid.h b/drivers/staging/rt3070/oid.h
new file mode 100644
index 0000000..f78bf0a
--- /dev/null
+++ b/drivers/staging/rt3070/oid.h
@@ -0,0 +1,1142 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	oid.h
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	Name		Date			Modification logs
+*/
+#ifndef _OID_H_
+#define _OID_H_
+
+//#include <linux/wireless.h>
+
+
+#define TRUE				1
+#define FALSE				0
+//
+// IEEE 802.11 Structures and definitions
+//
+#define MAX_TX_POWER_LEVEL              100   /* mW */
+#define MAX_RSSI_TRIGGER                -10    /* dBm */
+#define MIN_RSSI_TRIGGER                -200   /* dBm */
+#define MAX_FRAG_THRESHOLD              2346  /* byte count */
+#define MIN_FRAG_THRESHOLD              256   /* byte count */
+#define MAX_RTS_THRESHOLD               2347  /* byte count */
+
+// new types for Media Specific Indications
+// Extension channel offset
+#define EXTCHA_NONE			0
+#define EXTCHA_ABOVE		0x1
+#define EXTCHA_BELOW		0x3
+
+// BW
+#define BAND_WIDTH_20		0
+#define BAND_WIDTH_40		1
+#define BAND_WIDTH_BOTH		2
+#define BAND_WIDTH_10		3	// 802.11j has 10MHz. This definition is for internal usage. doesn't fill in the IE or other field.
+// SHORTGI
+#define GAP_INTERVAL_400	1	// only support in HT mode
+#define GAP_INTERVAL_800	0
+#define GAP_INTERVAL_BOTH	2
+
+#define NdisMediaStateConnected			1
+#define NdisMediaStateDisconnected		0
+
+#define NDIS_802_11_LENGTH_SSID         32
+#define NDIS_802_11_LENGTH_RATES        8
+#define NDIS_802_11_LENGTH_RATES_EX     16
+#define MAC_ADDR_LENGTH                 6
+#define MAX_NUM_OF_CHS					49 // 14 channels @2.4G +  12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL terminationc
+#define MAX_NUMBER_OF_EVENT				10  // entry # in EVENT table
+#define MAX_NUMBER_OF_MAC				32 // if MAX_MBSSID_NUM is 8, this value can't be larger than 211
+#define MAX_NUMBER_OF_ACL				64
+#define MAX_LENGTH_OF_SUPPORT_RATES		12    // 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
+#define MAX_NUMBER_OF_DLS_ENTRY			4
+
+
+
+#ifndef UNDER_CE
+// OID definition, since NDIS 5.0 didn't define these, we need to define for our own
+//#if _WIN32_WINNT<=0x0500
+
+#define OID_GEN_MACHINE_NAME               0x0001021A
+
+#ifdef RALINK_ATE
+#define RT_QUERY_ATE_TXDONE_COUNT			0x0401
+#endif // RALINK_ATE //
+#define RT_QUERY_SIGNAL_CONTEXT				0x0402
+#define RT_SET_IAPP_PID                 	0x0404
+#define RT_SET_APD_PID						0x0405
+#define RT_SET_DEL_MAC_ENTRY				0x0406
+
+//
+// IEEE 802.11 OIDs
+//
+#define	OID_GET_SET_TOGGLE			0x8000
+
+#define	OID_802_11_NETWORK_TYPES_SUPPORTED			0x0103
+#define	OID_802_11_NETWORK_TYPE_IN_USE				0x0104
+#define	OID_802_11_RSSI_TRIGGER						0x0107
+#define	RT_OID_802_11_RSSI							0x0108 //rt2860	only , kathy
+#define	RT_OID_802_11_RSSI_1						0x0109 //rt2860	only , kathy
+#define	RT_OID_802_11_RSSI_2						0x010A //rt2860	only , kathy
+#define	OID_802_11_NUMBER_OF_ANTENNAS				0x010B
+#define	OID_802_11_RX_ANTENNA_SELECTED				0x010C
+#define	OID_802_11_TX_ANTENNA_SELECTED				0x010D
+#define	OID_802_11_SUPPORTED_RATES					0x010E
+#define	OID_802_11_ADD_WEP							0x0112
+#define	OID_802_11_REMOVE_WEP						0x0113
+#define	OID_802_11_DISASSOCIATE						0x0114
+#define	OID_802_11_PRIVACY_FILTER					0x0118
+#define	OID_802_11_ASSOCIATION_INFORMATION			0x011E
+#define	OID_802_11_TEST								0x011F
+#define	RT_OID_802_11_COUNTRY_REGION				0x0507
+#define	OID_802_11_BSSID_LIST_SCAN					0x0508
+#define	OID_802_11_SSID								0x0509
+#define	OID_802_11_BSSID							0x050A
+#define	RT_OID_802_11_RADIO							0x050B
+#define	RT_OID_802_11_PHY_MODE						0x050C
+#define	RT_OID_802_11_STA_CONFIG					0x050D
+#define	OID_802_11_DESIRED_RATES					0x050E
+#define	RT_OID_802_11_PREAMBLE						0x050F
+#define	OID_802_11_WEP_STATUS						0x0510
+#define	OID_802_11_AUTHENTICATION_MODE				0x0511
+#define	OID_802_11_INFRASTRUCTURE_MODE				0x0512
+#define	RT_OID_802_11_RESET_COUNTERS				0x0513
+#define	OID_802_11_RTS_THRESHOLD					0x0514
+#define	OID_802_11_FRAGMENTATION_THRESHOLD			0x0515
+#define	OID_802_11_POWER_MODE						0x0516
+#define	OID_802_11_TX_POWER_LEVEL					0x0517
+#define	RT_OID_802_11_ADD_WPA						0x0518
+#define	OID_802_11_REMOVE_KEY						0x0519
+#define	OID_802_11_ADD_KEY							0x0520
+#define	OID_802_11_CONFIGURATION					0x0521
+#define	OID_802_11_TX_PACKET_BURST					0x0522
+#define	RT_OID_802_11_QUERY_NOISE_LEVEL				0x0523
+#define	RT_OID_802_11_EXTRA_INFO					0x0524
+#ifdef	DBG
+#define	RT_OID_802_11_HARDWARE_REGISTER				0x0525
+#endif
+#define OID_802_11_ENCRYPTION_STATUS            OID_802_11_WEP_STATUS
+#define OID_802_11_DEAUTHENTICATION                 0x0526
+#define OID_802_11_DROP_UNENCRYPTED                 0x0527
+#define OID_802_11_MIC_FAILURE_REPORT_FRAME         0x0528
+
+// For 802.1x daemin using to require current driver configuration
+#define OID_802_11_RADIUS_QUERY_SETTING				0x0540
+
+#define	RT_OID_DEVICE_NAME							0x0607
+#define	RT_OID_VERSION_INFO							0x0608
+#define	OID_802_11_BSSID_LIST						0x0609
+#define	OID_802_3_CURRENT_ADDRESS					0x060A
+#define	OID_GEN_MEDIA_CONNECT_STATUS				0x060B
+#define	RT_OID_802_11_QUERY_LINK_STATUS				0x060C
+#define	OID_802_11_RSSI								0x060D
+#define	OID_802_11_STATISTICS						0x060E
+#define	OID_GEN_RCV_OK								0x060F
+#define	OID_GEN_RCV_NO_BUFFER						0x0610
+#define	RT_OID_802_11_QUERY_EEPROM_VERSION			0x0611
+#define	RT_OID_802_11_QUERY_FIRMWARE_VERSION		0x0612
+#define	RT_OID_802_11_QUERY_LAST_RX_RATE			0x0613
+#define	RT_OID_802_11_TX_POWER_LEVEL_1				0x0614
+#define	RT_OID_802_11_QUERY_PIDVID					0x0615
+//for WPA_SUPPLICANT_SUPPORT
+#define OID_SET_COUNTERMEASURES                     0x0616
+#define OID_802_11_SET_IEEE8021X                    0x0617
+#define OID_802_11_SET_IEEE8021X_REQUIRE_KEY        0x0618
+#define OID_802_11_PMKID                            0x0620
+#define RT_OID_WPA_SUPPLICANT_SUPPORT               0x0621
+#define RT_OID_WE_VERSION_COMPILED                  0x0622
+#define RT_OID_NEW_DRIVER                           0x0623
+
+
+//rt2860 , kathy
+#define	RT_OID_802_11_SNR_0							0x0630
+#define	RT_OID_802_11_SNR_1							0x0631
+#define	RT_OID_802_11_QUERY_LAST_TX_RATE			0x0632
+#define	RT_OID_802_11_QUERY_HT_PHYMODE				0x0633
+#define	RT_OID_802_11_SET_HT_PHYMODE				0x0634
+#define	OID_802_11_RELOAD_DEFAULTS					0x0635
+#define	RT_OID_802_11_QUERY_APSD_SETTING			0x0636
+#define	RT_OID_802_11_SET_APSD_SETTING				0x0637
+#define	RT_OID_802_11_QUERY_APSD_PSM				0x0638
+#define	RT_OID_802_11_SET_APSD_PSM					0x0639
+#define	RT_OID_802_11_QUERY_DLS						0x063A
+#define	RT_OID_802_11_SET_DLS						0x063B
+#define	RT_OID_802_11_QUERY_DLS_PARAM				0x063C
+#define	RT_OID_802_11_SET_DLS_PARAM					0x063D
+#define RT_OID_802_11_QUERY_WMM              		0x063E
+#define RT_OID_802_11_SET_WMM      					0x063F
+#define RT_OID_802_11_QUERY_IMME_BA_CAP				0x0640
+#define RT_OID_802_11_SET_IMME_BA_CAP				0x0641
+#define RT_OID_802_11_QUERY_BATABLE					0x0642
+#define RT_OID_802_11_ADD_IMME_BA					0x0643
+#define RT_OID_802_11_TEAR_IMME_BA					0x0644
+#define RT_OID_DRIVER_DEVICE_NAME                   0x0645
+#define RT_OID_802_11_QUERY_DAT_HT_PHYMODE          0x0646
+#define RT_OID_QUERY_MULTIPLE_CARD_SUPPORT          0x0647
+
+// Ralink defined OIDs
+// Dennis Lee move to platform specific
+
+#define	RT_OID_802_11_BSSID					  (OID_GET_SET_TOGGLE |	OID_802_11_BSSID)
+#define	RT_OID_802_11_SSID					  (OID_GET_SET_TOGGLE |	OID_802_11_SSID)
+#define	RT_OID_802_11_INFRASTRUCTURE_MODE	  (OID_GET_SET_TOGGLE |	OID_802_11_INFRASTRUCTURE_MODE)
+#define	RT_OID_802_11_ADD_WEP				  (OID_GET_SET_TOGGLE |	OID_802_11_ADD_WEP)
+#define	RT_OID_802_11_ADD_KEY				  (OID_GET_SET_TOGGLE |	OID_802_11_ADD_KEY)
+#define	RT_OID_802_11_REMOVE_WEP			  (OID_GET_SET_TOGGLE |	OID_802_11_REMOVE_WEP)
+#define	RT_OID_802_11_REMOVE_KEY			  (OID_GET_SET_TOGGLE |	OID_802_11_REMOVE_KEY)
+#define	RT_OID_802_11_DISASSOCIATE			  (OID_GET_SET_TOGGLE |	OID_802_11_DISASSOCIATE)
+#define	RT_OID_802_11_AUTHENTICATION_MODE	  (OID_GET_SET_TOGGLE |	OID_802_11_AUTHENTICATION_MODE)
+#define	RT_OID_802_11_PRIVACY_FILTER		  (OID_GET_SET_TOGGLE |	OID_802_11_PRIVACY_FILTER)
+#define	RT_OID_802_11_BSSID_LIST_SCAN		  (OID_GET_SET_TOGGLE |	OID_802_11_BSSID_LIST_SCAN)
+#define	RT_OID_802_11_WEP_STATUS			  (OID_GET_SET_TOGGLE |	OID_802_11_WEP_STATUS)
+#define	RT_OID_802_11_RELOAD_DEFAULTS		  (OID_GET_SET_TOGGLE |	OID_802_11_RELOAD_DEFAULTS)
+#define	RT_OID_802_11_NETWORK_TYPE_IN_USE	  (OID_GET_SET_TOGGLE |	OID_802_11_NETWORK_TYPE_IN_USE)
+#define	RT_OID_802_11_TX_POWER_LEVEL		  (OID_GET_SET_TOGGLE |	OID_802_11_TX_POWER_LEVEL)
+#define	RT_OID_802_11_RSSI_TRIGGER			  (OID_GET_SET_TOGGLE |	OID_802_11_RSSI_TRIGGER)
+#define	RT_OID_802_11_FRAGMENTATION_THRESHOLD (OID_GET_SET_TOGGLE |	OID_802_11_FRAGMENTATION_THRESHOLD)
+#define	RT_OID_802_11_RTS_THRESHOLD			  (OID_GET_SET_TOGGLE |	OID_802_11_RTS_THRESHOLD)
+#define	RT_OID_802_11_RX_ANTENNA_SELECTED	  (OID_GET_SET_TOGGLE |	OID_802_11_RX_ANTENNA_SELECTED)
+#define	RT_OID_802_11_TX_ANTENNA_SELECTED	  (OID_GET_SET_TOGGLE |	OID_802_11_TX_ANTENNA_SELECTED)
+#define	RT_OID_802_11_SUPPORTED_RATES		  (OID_GET_SET_TOGGLE |	OID_802_11_SUPPORTED_RATES)
+#define	RT_OID_802_11_DESIRED_RATES			  (OID_GET_SET_TOGGLE |	OID_802_11_DESIRED_RATES)
+#define	RT_OID_802_11_CONFIGURATION			  (OID_GET_SET_TOGGLE |	OID_802_11_CONFIGURATION)
+#define	RT_OID_802_11_POWER_MODE			  (OID_GET_SET_TOGGLE |	OID_802_11_POWER_MODE)
+
+
+
+typedef enum _NDIS_802_11_STATUS_TYPE
+{
+    Ndis802_11StatusType_Authentication,
+    Ndis802_11StatusType_MediaStreamMode,
+    Ndis802_11StatusType_PMKID_CandidateList,
+    Ndis802_11StatusTypeMax    // not a real type, defined as an upper bound
+} NDIS_802_11_STATUS_TYPE, *PNDIS_802_11_STATUS_TYPE;
+
+typedef UCHAR   NDIS_802_11_MAC_ADDRESS[6];
+
+typedef struct _NDIS_802_11_STATUS_INDICATION
+{
+    NDIS_802_11_STATUS_TYPE StatusType;
+} NDIS_802_11_STATUS_INDICATION, *PNDIS_802_11_STATUS_INDICATION;
+
+// mask for authentication/integrity fields
+#define NDIS_802_11_AUTH_REQUEST_AUTH_FIELDS        0x0f
+
+#define NDIS_802_11_AUTH_REQUEST_REAUTH             0x01
+#define NDIS_802_11_AUTH_REQUEST_KEYUPDATE          0x02
+#define NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR     0x06
+#define NDIS_802_11_AUTH_REQUEST_GROUP_ERROR        0x0E
+
+typedef struct _NDIS_802_11_AUTHENTICATION_REQUEST
+{
+    ULONG Length;            // Length of structure
+    NDIS_802_11_MAC_ADDRESS Bssid;
+    ULONG Flags;
+} NDIS_802_11_AUTHENTICATION_REQUEST, *PNDIS_802_11_AUTHENTICATION_REQUEST;
+
+//Added new types for PMKID Candidate lists.
+typedef struct _PMKID_CANDIDATE {
+    NDIS_802_11_MAC_ADDRESS BSSID;
+    ULONG Flags;
+} PMKID_CANDIDATE, *PPMKID_CANDIDATE;
+
+typedef struct _NDIS_802_11_PMKID_CANDIDATE_LIST
+{
+    ULONG Version;       // Version of the structure
+    ULONG NumCandidates; // No. of pmkid candidates
+    PMKID_CANDIDATE CandidateList[1];
+} NDIS_802_11_PMKID_CANDIDATE_LIST, *PNDIS_802_11_PMKID_CANDIDATE_LIST;
+
+//Flags for PMKID Candidate list structure
+#define NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED	0x01
+
+// Added new types for OFDM 5G and 2.4G
+typedef enum _NDIS_802_11_NETWORK_TYPE
+{
+   Ndis802_11FH,
+   Ndis802_11DS,
+    Ndis802_11OFDM5,
+    Ndis802_11OFDM5_N,
+    Ndis802_11OFDM24,
+    Ndis802_11OFDM24_N,
+   Ndis802_11Automode,
+    Ndis802_11NetworkTypeMax    // not a real type, defined as an upper bound
+} NDIS_802_11_NETWORK_TYPE, *PNDIS_802_11_NETWORK_TYPE;
+
+typedef struct _NDIS_802_11_NETWORK_TYPE_LIST
+{
+    UINT                       NumberOfItems;  // in list below, at least 1
+   NDIS_802_11_NETWORK_TYPE    NetworkType [1];
+} NDIS_802_11_NETWORK_TYPE_LIST, *PNDIS_802_11_NETWORK_TYPE_LIST;
+
+typedef enum _NDIS_802_11_POWER_MODE
+{
+    Ndis802_11PowerModeCAM,
+    Ndis802_11PowerModeMAX_PSP,
+    Ndis802_11PowerModeFast_PSP,
+    Ndis802_11PowerModeLegacy_PSP,
+    Ndis802_11PowerModeMax      // not a real mode, defined as an upper bound
+} NDIS_802_11_POWER_MODE, *PNDIS_802_11_POWER_MODE;
+
+typedef ULONG   NDIS_802_11_TX_POWER_LEVEL; // in milliwatts
+
+//
+// Received Signal Strength Indication
+//
+typedef LONG    NDIS_802_11_RSSI;           // in dBm
+
+typedef struct _NDIS_802_11_CONFIGURATION_FH
+{
+   ULONG           Length;            // Length of structure
+   ULONG           HopPattern;        // As defined by 802.11, MSB set
+   ULONG           HopSet;            // to one if non-802.11
+   ULONG           DwellTime;         // units are Kusec
+} NDIS_802_11_CONFIGURATION_FH, *PNDIS_802_11_CONFIGURATION_FH;
+
+typedef struct _NDIS_802_11_CONFIGURATION
+{
+   ULONG                           Length;             // Length of structure
+   ULONG                           BeaconPeriod;       // units are Kusec
+   ULONG                           ATIMWindow;         // units are Kusec
+   ULONG                           DSConfig;           // Frequency, units are kHz
+   NDIS_802_11_CONFIGURATION_FH    FHConfig;
+} NDIS_802_11_CONFIGURATION, *PNDIS_802_11_CONFIGURATION;
+
+typedef struct _NDIS_802_11_STATISTICS
+{
+   ULONG           Length;             // Length of structure
+   LARGE_INTEGER   TransmittedFragmentCount;
+   LARGE_INTEGER   MulticastTransmittedFrameCount;
+   LARGE_INTEGER   FailedCount;
+   LARGE_INTEGER   RetryCount;
+   LARGE_INTEGER   MultipleRetryCount;
+   LARGE_INTEGER   RTSSuccessCount;
+   LARGE_INTEGER   RTSFailureCount;
+   LARGE_INTEGER   ACKFailureCount;
+   LARGE_INTEGER   FrameDuplicateCount;
+   LARGE_INTEGER   ReceivedFragmentCount;
+   LARGE_INTEGER   MulticastReceivedFrameCount;
+   LARGE_INTEGER   FCSErrorCount;
+   LARGE_INTEGER   TKIPLocalMICFailures;
+   LARGE_INTEGER   TKIPRemoteMICErrors;
+   LARGE_INTEGER   TKIPICVErrors;
+   LARGE_INTEGER   TKIPCounterMeasuresInvoked;
+   LARGE_INTEGER   TKIPReplays;
+   LARGE_INTEGER   CCMPFormatErrors;
+   LARGE_INTEGER   CCMPReplays;
+   LARGE_INTEGER   CCMPDecryptErrors;
+   LARGE_INTEGER   FourWayHandshakeFailures;
+} NDIS_802_11_STATISTICS, *PNDIS_802_11_STATISTICS;
+
+typedef  ULONG  NDIS_802_11_KEY_INDEX;
+typedef ULONGLONG   NDIS_802_11_KEY_RSC;
+
+#define MAX_RADIUS_SRV_NUM			2	  // 802.1x failover number
+
+typedef struct PACKED _RADIUS_SRV_INFO {
+	UINT32			radius_ip;
+	UINT32			radius_port;
+	UCHAR			radius_key[64];
+	UCHAR			radius_key_len;
+} RADIUS_SRV_INFO, *PRADIUS_SRV_INFO;
+
+typedef struct PACKED _RADIUS_KEY_INFO
+{
+	UCHAR			radius_srv_num;
+	RADIUS_SRV_INFO	radius_srv_info[MAX_RADIUS_SRV_NUM];
+	UCHAR			ieee8021xWEP;		 // dynamic WEP
+    UCHAR           key_index;
+    UCHAR           key_length;          // length of key in bytes
+    UCHAR           key_material[13];
+} RADIUS_KEY_INFO, *PRADIUS_KEY_INFO;
+
+// It's used by 802.1x daemon to require relative configuration
+typedef struct PACKED _RADIUS_CONF
+{
+    UINT32          Length;             // Length of this structure
+    UCHAR			mbss_num;			// indicate multiple BSS number
+	UINT32			own_ip_addr;
+	UINT32			retry_interval;
+	UINT32			session_timeout_interval;
+	UCHAR			EAPifname[IFNAMSIZ];
+	UCHAR			EAPifname_len;
+	UCHAR 			PreAuthifname[IFNAMSIZ];
+	UCHAR			PreAuthifname_len;
+	RADIUS_KEY_INFO	RadiusInfo[8/*MAX_MBSSID_NUM*/];
+} RADIUS_CONF, *PRADIUS_CONF;
+
+
+
+#ifdef CONFIG_STA_SUPPORT
+// Key mapping keys require a BSSID
+typedef struct _NDIS_802_11_KEY
+{
+    UINT           Length;             // Length of this structure
+    UINT           KeyIndex;
+    UINT           KeyLength;          // length of key in bytes
+    NDIS_802_11_MAC_ADDRESS BSSID;
+    NDIS_802_11_KEY_RSC KeyRSC;
+    UCHAR           KeyMaterial[1];     // variable length depending on above field
+} NDIS_802_11_KEY, *PNDIS_802_11_KEY;
+#endif // CONFIG_STA_SUPPORT //
+
+typedef struct _NDIS_802_11_REMOVE_KEY
+{
+    UINT           Length;             // Length of this structure
+    UINT           KeyIndex;
+    NDIS_802_11_MAC_ADDRESS BSSID;
+} NDIS_802_11_REMOVE_KEY, *PNDIS_802_11_REMOVE_KEY;
+
+typedef struct _NDIS_802_11_WEP
+{
+   UINT     Length;        // Length of this structure
+   UINT     KeyIndex;           // 0 is the per-client key, 1-N are the
+                                        // global keys
+   UINT     KeyLength;     // length of key in bytes
+   UCHAR     KeyMaterial[1];// variable length depending on above field
+} NDIS_802_11_WEP, *PNDIS_802_11_WEP;
+
+
+typedef enum _NDIS_802_11_NETWORK_INFRASTRUCTURE
+{
+   Ndis802_11IBSS,
+   Ndis802_11Infrastructure,
+   Ndis802_11AutoUnknown,
+   Ndis802_11Monitor,
+   Ndis802_11InfrastructureMax     // Not a real value, defined as upper bound
+} NDIS_802_11_NETWORK_INFRASTRUCTURE, *PNDIS_802_11_NETWORK_INFRASTRUCTURE;
+
+// Add new authentication modes
+typedef enum _NDIS_802_11_AUTHENTICATION_MODE
+{
+   Ndis802_11AuthModeOpen,
+   Ndis802_11AuthModeShared,
+   Ndis802_11AuthModeAutoSwitch,
+    Ndis802_11AuthModeWPA,
+    Ndis802_11AuthModeWPAPSK,
+    Ndis802_11AuthModeWPANone,
+   Ndis802_11AuthModeWPA2,
+   Ndis802_11AuthModeWPA2PSK,
+   	Ndis802_11AuthModeWPA1WPA2,
+	Ndis802_11AuthModeWPA1PSKWPA2PSK,
+   Ndis802_11AuthModeMax           // Not a real mode, defined as upper bound
+} NDIS_802_11_AUTHENTICATION_MODE, *PNDIS_802_11_AUTHENTICATION_MODE;
+
+typedef UCHAR   NDIS_802_11_RATES[NDIS_802_11_LENGTH_RATES];        // Set of 8 data rates
+typedef UCHAR   NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX];  // Set of 16 data rates
+
+typedef struct PACKED _NDIS_802_11_SSID
+{
+    UINT   SsidLength;         // length of SSID field below, in bytes;
+                                // this can be zero.
+    UCHAR   Ssid[NDIS_802_11_LENGTH_SSID];           // SSID information field
+} NDIS_802_11_SSID, *PNDIS_802_11_SSID;
+
+
+typedef struct PACKED _NDIS_WLAN_BSSID
+{
+   ULONG                               Length;     // Length of this structure
+   NDIS_802_11_MAC_ADDRESS             MacAddress; // BSSID
+   UCHAR                               Reserved[2];
+   NDIS_802_11_SSID                    Ssid;       // SSID
+   ULONG                               Privacy;    // WEP encryption requirement
+   NDIS_802_11_RSSI                    Rssi;       // receive signal strength in dBm
+   NDIS_802_11_NETWORK_TYPE            NetworkTypeInUse;
+   NDIS_802_11_CONFIGURATION           Configuration;
+   NDIS_802_11_NETWORK_INFRASTRUCTURE  InfrastructureMode;
+   NDIS_802_11_RATES                   SupportedRates;
+} NDIS_WLAN_BSSID, *PNDIS_WLAN_BSSID;
+
+typedef struct PACKED _NDIS_802_11_BSSID_LIST
+{
+   UINT           NumberOfItems;      // in list below, at least 1
+   NDIS_WLAN_BSSID Bssid[1];
+} NDIS_802_11_BSSID_LIST, *PNDIS_802_11_BSSID_LIST;
+
+// Added Capabilities, IELength and IEs for each BSSID
+typedef struct PACKED _NDIS_WLAN_BSSID_EX
+{
+    ULONG                               Length;             // Length of this structure
+    NDIS_802_11_MAC_ADDRESS             MacAddress;         // BSSID
+    UCHAR                               Reserved[2];
+    NDIS_802_11_SSID                    Ssid;               // SSID
+    UINT                                Privacy;            // WEP encryption requirement
+    NDIS_802_11_RSSI                    Rssi;               // receive signal
+                                                            // strength in dBm
+    NDIS_802_11_NETWORK_TYPE            NetworkTypeInUse;
+    NDIS_802_11_CONFIGURATION           Configuration;
+    NDIS_802_11_NETWORK_INFRASTRUCTURE  InfrastructureMode;
+    NDIS_802_11_RATES_EX                SupportedRates;
+    ULONG                               IELength;
+    UCHAR                               IEs[1];
+} NDIS_WLAN_BSSID_EX, *PNDIS_WLAN_BSSID_EX;
+
+typedef struct PACKED _NDIS_802_11_BSSID_LIST_EX
+{
+    UINT                   NumberOfItems;      // in list below, at least 1
+    NDIS_WLAN_BSSID_EX      Bssid[1];
+} NDIS_802_11_BSSID_LIST_EX, *PNDIS_802_11_BSSID_LIST_EX;
+
+typedef struct PACKED _NDIS_802_11_FIXED_IEs
+{
+    UCHAR Timestamp[8];
+    USHORT BeaconInterval;
+    USHORT Capabilities;
+} NDIS_802_11_FIXED_IEs, *PNDIS_802_11_FIXED_IEs;
+
+typedef struct _NDIS_802_11_VARIABLE_IEs
+{
+    UCHAR ElementID;
+    UCHAR Length;    // Number of bytes in data field
+    UCHAR data[1];
+} NDIS_802_11_VARIABLE_IEs, *PNDIS_802_11_VARIABLE_IEs;
+
+typedef  ULONG   NDIS_802_11_FRAGMENTATION_THRESHOLD;
+
+typedef  ULONG   NDIS_802_11_RTS_THRESHOLD;
+
+typedef  ULONG   NDIS_802_11_ANTENNA;
+
+typedef enum _NDIS_802_11_PRIVACY_FILTER
+{
+   Ndis802_11PrivFilterAcceptAll,
+   Ndis802_11PrivFilter8021xWEP
+} NDIS_802_11_PRIVACY_FILTER, *PNDIS_802_11_PRIVACY_FILTER;
+
+// Added new encryption types
+// Also aliased typedef to new name
+typedef enum _NDIS_802_11_WEP_STATUS
+{
+   Ndis802_11WEPEnabled,
+    Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
+   Ndis802_11WEPDisabled,
+    Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled,
+   Ndis802_11WEPKeyAbsent,
+    Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent,
+   Ndis802_11WEPNotSupported,
+    Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported,
+    Ndis802_11Encryption2Enabled,
+    Ndis802_11Encryption2KeyAbsent,
+    Ndis802_11Encryption3Enabled,
+    Ndis802_11Encryption3KeyAbsent,
+    Ndis802_11Encryption4Enabled,	// TKIP or AES mix
+    Ndis802_11Encryption4KeyAbsent,
+} NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS,
+  NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS;
+
+typedef enum _NDIS_802_11_RELOAD_DEFAULTS
+{
+   Ndis802_11ReloadWEPKeys
+} NDIS_802_11_RELOAD_DEFAULTS, *PNDIS_802_11_RELOAD_DEFAULTS;
+
+#define NDIS_802_11_AI_REQFI_CAPABILITIES      1
+#define NDIS_802_11_AI_REQFI_LISTENINTERVAL    2
+#define NDIS_802_11_AI_REQFI_CURRENTAPADDRESS  4
+
+#define NDIS_802_11_AI_RESFI_CAPABILITIES      1
+#define NDIS_802_11_AI_RESFI_STATUSCODE        2
+#define NDIS_802_11_AI_RESFI_ASSOCIATIONID     4
+
+typedef struct _NDIS_802_11_AI_REQFI
+{
+    USHORT Capabilities;
+    USHORT ListenInterval;
+    NDIS_802_11_MAC_ADDRESS  CurrentAPAddress;
+} NDIS_802_11_AI_REQFI, *PNDIS_802_11_AI_REQFI;
+
+typedef struct _NDIS_802_11_AI_RESFI
+{
+    USHORT Capabilities;
+    USHORT StatusCode;
+    USHORT AssociationId;
+} NDIS_802_11_AI_RESFI, *PNDIS_802_11_AI_RESFI;
+
+typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION
+{
+    ULONG                   Length;
+    USHORT                  AvailableRequestFixedIEs;
+    NDIS_802_11_AI_REQFI    RequestFixedIEs;
+    ULONG                   RequestIELength;
+    ULONG                   OffsetRequestIEs;
+    USHORT                  AvailableResponseFixedIEs;
+    NDIS_802_11_AI_RESFI    ResponseFixedIEs;
+    ULONG                   ResponseIELength;
+    ULONG                   OffsetResponseIEs;
+} NDIS_802_11_ASSOCIATION_INFORMATION, *PNDIS_802_11_ASSOCIATION_INFORMATION;
+
+typedef struct _NDIS_802_11_AUTHENTICATION_EVENT
+{
+    NDIS_802_11_STATUS_INDICATION       Status;
+    NDIS_802_11_AUTHENTICATION_REQUEST  Request[1];
+} NDIS_802_11_AUTHENTICATION_EVENT, *PNDIS_802_11_AUTHENTICATION_EVENT;
+
+/*
+typedef struct _NDIS_802_11_TEST
+{
+    ULONG Length;
+    ULONG Type;
+    union
+    {
+        NDIS_802_11_AUTHENTICATION_EVENT AuthenticationEvent;
+        NDIS_802_11_RSSI RssiTrigger;
+    };
+} NDIS_802_11_TEST, *PNDIS_802_11_TEST;
+ */
+
+// 802.11 Media stream constraints, associated with OID_802_11_MEDIA_STREAM_MODE
+typedef enum _NDIS_802_11_MEDIA_STREAM_MODE
+{
+    Ndis802_11MediaStreamOff,
+    Ndis802_11MediaStreamOn,
+} NDIS_802_11_MEDIA_STREAM_MODE, *PNDIS_802_11_MEDIA_STREAM_MODE;
+
+// PMKID Structures
+typedef UCHAR   NDIS_802_11_PMKID_VALUE[16];
+
+#ifdef CONFIG_STA_SUPPORT
+typedef struct _BSSID_INFO
+{
+    NDIS_802_11_MAC_ADDRESS BSSID;
+    NDIS_802_11_PMKID_VALUE PMKID;
+} BSSID_INFO, *PBSSID_INFO;
+
+typedef struct _NDIS_802_11_PMKID
+{
+    UINT    Length;
+    UINT    BSSIDInfoCount;
+    BSSID_INFO BSSIDInfo[1];
+} NDIS_802_11_PMKID, *PNDIS_802_11_PMKID;
+#endif // CONFIG_STA_SUPPORT //
+
+
+typedef struct _NDIS_802_11_AUTHENTICATION_ENCRYPTION
+{
+    NDIS_802_11_AUTHENTICATION_MODE AuthModeSupported;
+    NDIS_802_11_ENCRYPTION_STATUS EncryptStatusSupported;
+} NDIS_802_11_AUTHENTICATION_ENCRYPTION, *PNDIS_802_11_AUTHENTICATION_ENCRYPTION;
+
+typedef struct _NDIS_802_11_CAPABILITY
+{
+     ULONG Length;
+     ULONG Version;
+     ULONG NoOfPMKIDs;
+     ULONG NoOfAuthEncryptPairsSupported;
+     NDIS_802_11_AUTHENTICATION_ENCRYPTION AuthenticationEncryptionSupported[1];
+} NDIS_802_11_CAPABILITY, *PNDIS_802_11_CAPABILITY;
+
+//#endif //of WIN 2k
+#endif //UNDER_CE
+
+#if WIRELESS_EXT <= 11
+#ifndef SIOCDEVPRIVATE
+#define SIOCDEVPRIVATE                              0x8BE0
+#endif
+#define SIOCIWFIRSTPRIV								SIOCDEVPRIVATE
+#endif
+
+#ifdef CONFIG_STA_SUPPORT
+#define RT_PRIV_IOCTL_EXT							(SIOCIWFIRSTPRIV + 0x01) // Sync. with AP for wsc upnp daemon
+#define RTPRIV_IOCTL_SET							(SIOCIWFIRSTPRIV + 0x02)
+
+#ifdef DBG
+#define RTPRIV_IOCTL_BBP                            (SIOCIWFIRSTPRIV + 0x03)
+#define RTPRIV_IOCTL_MAC                            (SIOCIWFIRSTPRIV + 0x05)
+#define RTPRIV_IOCTL_RF                             (SIOCIWFIRSTPRIV + 0x13)
+#define RTPRIV_IOCTL_E2P                            (SIOCIWFIRSTPRIV + 0x07)
+#endif
+
+#ifdef RALINK_ATE
+#ifdef RALINK_28xx_QA
+#define RTPRIV_IOCTL_ATE							(SIOCIWFIRSTPRIV + 0x08)
+#endif // RALINK_28xx_QA //
+#endif // RALINK_ATE //
+
+#define RTPRIV_IOCTL_STATISTICS                     (SIOCIWFIRSTPRIV + 0x09)
+#define RTPRIV_IOCTL_ADD_PMKID_CACHE                (SIOCIWFIRSTPRIV + 0x0A)
+#define RTPRIV_IOCTL_RADIUS_DATA                    (SIOCIWFIRSTPRIV + 0x0C)
+#define RTPRIV_IOCTL_GSITESURVEY					(SIOCIWFIRSTPRIV + 0x0D)
+#define RT_PRIV_IOCTL								(SIOCIWFIRSTPRIV + 0x0E) // Sync. with RT61 (for wpa_supplicant)
+#define RTPRIV_IOCTL_GET_MAC_TABLE					(SIOCIWFIRSTPRIV + 0x0F)
+
+#define RTPRIV_IOCTL_SHOW							(SIOCIWFIRSTPRIV + 0x11)
+enum {
+    SHOW_CONN_STATUS = 4,
+    SHOW_DRVIER_VERION = 5,
+    SHOW_BA_INFO = 6,
+	SHOW_DESC_INFO = 7,
+#ifdef RT2870
+	SHOW_RXBULK_INFO = 8,
+	SHOW_TXBULK_INFO = 9,
+#endif // RT2870 //
+    RAIO_OFF = 10,
+    RAIO_ON = 11,
+#ifdef QOS_DLS_SUPPORT
+	SHOW_DLS_ENTRY_INFO = 19,
+#endif // QOS_DLS_SUPPORT //
+	SHOW_CFG_VALUE = 20,
+};
+
+
+#endif // CONFIG_STA_SUPPORT //
+
+
+
+#ifdef SNMP_SUPPORT
+//SNMP ieee 802dot11, kathy , 2008_0220
+// dot11res(3)
+#define RT_OID_802_11_MANUFACTUREROUI			0x0700
+#define RT_OID_802_11_MANUFACTURERNAME			0x0701
+#define RT_OID_802_11_RESOURCETYPEIDNAME		0x0702
+
+// dot11smt(1)
+#define RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED	0x0703
+#define RT_OID_802_11_POWERMANAGEMENTMODE		0x0704
+#define OID_802_11_WEPDEFAULTKEYVALUE			0x0705 // read , write
+#define OID_802_11_WEPDEFAULTKEYID				0x0706
+#define RT_OID_802_11_WEPKEYMAPPINGLENGTH		0x0707
+#define OID_802_11_SHORTRETRYLIMIT				0x0708
+#define OID_802_11_LONGRETRYLIMIT				0x0709
+#define RT_OID_802_11_PRODUCTID					0x0710
+#define RT_OID_802_11_MANUFACTUREID				0x0711
+
+// //dot11Phy(4)
+#define OID_802_11_CURRENTCHANNEL				0x0712
+
+//dot11mac
+#define RT_OID_802_11_MAC_ADDRESS				0x0713
+#endif // SNMP_SUPPORT //
+
+#define OID_802_11_BUILD_CHANNEL_EX				0x0714
+#define OID_802_11_GET_CH_LIST					0x0715
+#define OID_802_11_GET_COUNTRY_CODE				0x0716
+#define OID_802_11_GET_CHANNEL_GEOGRAPHY		0x0717
+
+//#define RT_OID_802_11_STATISTICS              (OID_GET_SET_TOGGLE | OID_802_11_STATISTICS)
+
+#ifdef CONFIG_STA_SUPPORT
+#define RT_OID_WSC_SET_PASSPHRASE                   0x0740 // passphrase for wpa(2)-psk
+#define RT_OID_WSC_DRIVER_AUTO_CONNECT              0x0741
+#define RT_OID_WSC_QUERY_DEFAULT_PROFILE            0x0742
+#define RT_OID_WSC_SET_CONN_BY_PROFILE_INDEX        0x0743
+#define RT_OID_WSC_SET_ACTION                       0x0744
+#define RT_OID_WSC_SET_SSID                         0x0745
+#define RT_OID_WSC_SET_PIN_CODE                     0x0746
+#define RT_OID_WSC_SET_MODE                         0x0747 // PIN or PBC
+#define RT_OID_WSC_SET_CONF_MODE                    0x0748 // Enrollee or Registrar
+#define RT_OID_WSC_SET_PROFILE                      0x0749
+#endif // CONFIG_STA_SUPPORT //
+#define RT_OID_802_11_WSC_QUERY_PROFILE				0x0750
+// for consistency with RT61
+#define RT_OID_WSC_QUERY_STATUS						0x0751
+#define RT_OID_WSC_PIN_CODE							0x0752
+#define RT_OID_WSC_UUID								0x0753
+#define RT_OID_WSC_SET_SELECTED_REGISTRAR			0x0754
+#define RT_OID_WSC_EAPMSG							0x0755
+#define RT_OID_WSC_MANUFACTURER						0x0756
+#define RT_OID_WSC_MODEL_NAME						0x0757
+#define RT_OID_WSC_MODEL_NO							0x0758
+#define RT_OID_WSC_SERIAL_NO						0x0759
+#define RT_OID_WSC_MAC_ADDRESS						0x0760
+
+#ifdef LLTD_SUPPORT
+// for consistency with RT61
+#define RT_OID_GET_PHY_MODE                         0x761
+#endif // LLTD_SUPPORT //
+
+#ifdef NINTENDO_AP
+//#define RT_OID_NINTENDO                             0x0D010770
+#define RT_OID_802_11_NINTENDO_GET_TABLE			0x0771 //((RT_OID_NINTENDO + 0x01) & 0xffff)
+#define RT_OID_802_11_NINTENDO_SET_TABLE			0x0772 //((RT_OID_NINTENDO + 0x02) & 0xffff)
+#define RT_OID_802_11_NINTENDO_CAPABLE				0x0773 //((RT_OID_NINTENDO + 0x03) & 0xffff)
+#endif // NINTENDO_AP //
+
+//Add Paul Chen for Accton
+//#define RT_OID_TX_POWER_LEVEL                 0xFF020010
+//#define RT_OID_SET_TX_POWER_LEVEL	          (OID_GET_SET_TOGGLE | RT_OID_TX_POWER_LEVEL)
+
+// New for MeetingHouse Api support
+#define OID_MH_802_1X_SUPPORTED               0xFFEDC100
+
+// MIMO Tx parameter, ShortGI, MCS, STBC, etc.  these are fields in TXWI. Don't change this definition!!!
+typedef union  _HTTRANSMIT_SETTING {
+#ifdef RT_BIG_ENDIAN
+	struct	{
+	USHORT		MODE:2;	// Use definition MODE_xxx.
+//	USHORT		rsv:3;
+	USHORT		TxBF:1;
+	USHORT		rsv:2;
+	USHORT		STBC:2;	//SPACE
+	USHORT		ShortGI:1;
+	USHORT		BW:1;	//channel bandwidth 20MHz or 40 MHz
+	USHORT   	MCS:7;                 // MCS
+	}	field;
+#else
+	struct	{
+	USHORT   	MCS:7;                 // MCS
+	USHORT		BW:1;	//channel bandwidth 20MHz or 40 MHz
+	USHORT		ShortGI:1;
+	USHORT		STBC:2;	//SPACE
+//	USHORT		rsv:3;
+	USHORT		rsv:2;
+	USHORT		TxBF:1;
+	USHORT		MODE:2;	// Use definition MODE_xxx.
+	}	field;
+#endif
+	USHORT		word;
+ } HTTRANSMIT_SETTING, *PHTTRANSMIT_SETTING;
+
+typedef enum _RT_802_11_PREAMBLE {
+    Rt802_11PreambleLong,
+    Rt802_11PreambleShort,
+    Rt802_11PreambleAuto
+} RT_802_11_PREAMBLE, *PRT_802_11_PREAMBLE;
+
+// Only for STA, need to sync with AP
+// 2005-03-08 match current RaConfig.
+typedef enum _RT_802_11_PHY_MODE {
+	PHY_11BG_MIXED = 0,
+	PHY_11B,
+	PHY_11A,
+	PHY_11ABG_MIXED,
+	PHY_11G,
+#ifdef DOT11_N_SUPPORT
+	PHY_11ABGN_MIXED,	// both band   5
+	PHY_11N_2_4G,		// 11n-only with 2.4G band   	6
+	PHY_11GN_MIXED,	// 2.4G band      7
+	PHY_11AN_MIXED,	// 5G  band       8
+	PHY_11BGN_MIXED,	// if check 802.11b.      9
+	PHY_11AGN_MIXED,	// if check 802.11b.      10
+	PHY_11N_5G,			// 11n-only with 5G band		11
+#endif // DOT11_N_SUPPORT //
+} RT_802_11_PHY_MODE;
+
+// put all proprietery for-query objects here to reduce # of Query_OID
+typedef struct _RT_802_11_LINK_STATUS {
+    ULONG   CurrTxRate;         // in units of 0.5Mbps
+    ULONG   ChannelQuality;     // 0..100 %
+    ULONG   TxByteCount;        // both ok and fail
+    ULONG   RxByteCount;        // both ok and fail
+    ULONG	CentralChannel;		// 40MHz central channel number
+} RT_802_11_LINK_STATUS, *PRT_802_11_LINK_STATUS;
+
+typedef struct _RT_802_11_EVENT_LOG {
+    LARGE_INTEGER   SystemTime;  // timestammp via NdisGetCurrentSystemTime()
+    UCHAR           Addr[MAC_ADDR_LENGTH];
+    USHORT          Event;       // EVENT_xxx
+} RT_802_11_EVENT_LOG, *PRT_802_11_EVENT_LOG;
+
+typedef struct _RT_802_11_EVENT_TABLE {
+    ULONG       Num;
+    ULONG       Rsv;     // to align Log[] at LARGE_INEGER boundary
+    RT_802_11_EVENT_LOG   Log[MAX_NUMBER_OF_EVENT];
+} RT_802_11_EVENT_TABLE, PRT_802_11_EVENT_TABLE;
+
+// MIMO Tx parameter, ShortGI, MCS, STBC, etc.  these are fields in TXWI. Don't change this definition!!!
+typedef union  _MACHTTRANSMIT_SETTING {
+	struct	{
+	USHORT   	MCS:7;                 // MCS
+	USHORT		BW:1;	//channel bandwidth 20MHz or 40 MHz
+	USHORT		ShortGI:1;
+	USHORT		STBC:2;	//SPACE
+	USHORT		rsv:3;
+	USHORT		MODE:2;	// Use definition MODE_xxx.
+	}	field;
+	USHORT		word;
+ } MACHTTRANSMIT_SETTING, *PMACHTTRANSMIT_SETTING;
+
+typedef struct _RT_802_11_MAC_ENTRY {
+    UCHAR       Addr[MAC_ADDR_LENGTH];
+    UCHAR       Aid;
+    UCHAR       Psm;     // 0:PWR_ACTIVE, 1:PWR_SAVE
+    UCHAR		MimoPs;  // 0:MMPS_STATIC, 1:MMPS_DYNAMIC, 3:MMPS_Enabled
+    CHAR		AvgRssi0;
+	CHAR		AvgRssi1;
+	CHAR		AvgRssi2;
+	UINT32		ConnectedTime;
+    MACHTTRANSMIT_SETTING	TxRate;
+} RT_802_11_MAC_ENTRY, *PRT_802_11_MAC_ENTRY;
+
+typedef struct _RT_802_11_MAC_TABLE {
+    ULONG       Num;
+    RT_802_11_MAC_ENTRY Entry[MAX_NUMBER_OF_MAC];
+} RT_802_11_MAC_TABLE, *PRT_802_11_MAC_TABLE;
+
+// structure for query/set hardware register - MAC, BBP, RF register
+typedef struct _RT_802_11_HARDWARE_REGISTER {
+    ULONG   HardwareType;       // 0:MAC, 1:BBP, 2:RF register, 3:EEPROM
+    ULONG   Offset;             // Q/S register offset addr
+    ULONG   Data;               // R/W data buffer
+} RT_802_11_HARDWARE_REGISTER, *PRT_802_11_HARDWARE_REGISTER;
+
+// structure to tune BBP R17 "RX AGC VGC init"
+//typedef struct _RT_802_11_RX_AGC_VGC_TUNING {
+//    UCHAR   FalseCcaLowerThreshold;  // 0-255, def 10
+//    UCHAR   FalseCcaUpperThreshold;  // 0-255, def 100
+//    UCHAR   VgcDelta;                // R17 +-= VgcDelta whenever flase CCA over UpprThreshold
+//                                     // or lower than LowerThresholdupper threshold
+//    UCHAR   VgcUpperBound;           // max value of R17
+//} RT_802_11_RX_AGC_VGC_TUNING, *PRT_802_11_RX_AGC_VGC_TUNING;
+
+typedef struct _RT_802_11_AP_CONFIG {
+    ULONG   EnableTxBurst;      // 0-disable, 1-enable
+    ULONG   EnableTurboRate;    // 0-disable, 1-enable 72/100mbps turbo rate
+    ULONG   IsolateInterStaTraffic;     // 0-disable, 1-enable isolation
+    ULONG   HideSsid;           // 0-disable, 1-enable hiding
+    ULONG   UseBGProtection;    // 0-AUTO, 1-always ON, 2-always OFF
+    ULONG   UseShortSlotTime;   // 0-no use, 1-use 9-us short slot time
+    ULONG   Rsv1;               // must be 0
+    ULONG   SystemErrorBitmap;  // ignore upon SET, return system error upon QUERY
+} RT_802_11_AP_CONFIG, *PRT_802_11_AP_CONFIG;
+
+// structure to query/set STA_CONFIG
+typedef struct _RT_802_11_STA_CONFIG {
+    ULONG   EnableTxBurst;      // 0-disable, 1-enable
+    ULONG   EnableTurboRate;    // 0-disable, 1-enable 72/100mbps turbo rate
+    ULONG   UseBGProtection;    // 0-AUTO, 1-always ON, 2-always OFF
+    ULONG   UseShortSlotTime;   // 0-no use, 1-use 9-us short slot time when applicable
+    ULONG   AdhocMode; 			// 0-11b rates only (WIFI spec), 1 - b/g mixed, 2 - g only
+    ULONG   HwRadioStatus;      // 0-OFF, 1-ON, default is 1, Read-Only
+    ULONG   Rsv1;               // must be 0
+    ULONG   SystemErrorBitmap;  // ignore upon SET, return system error upon QUERY
+} RT_802_11_STA_CONFIG, *PRT_802_11_STA_CONFIG;
+
+//
+//  For OID Query or Set about BA structure
+//
+typedef	struct	_OID_BACAP_STRUC	{
+		UCHAR		RxBAWinLimit;
+		UCHAR		TxBAWinLimit;
+		UCHAR		Policy;	// 0: DELAY_BA 1:IMMED_BA  (//BA Policy subfiled value in ADDBA frame)   2:BA-not use. other value invalid
+		UCHAR		MpduDensity;	// 0: DELAY_BA 1:IMMED_BA  (//BA Policy subfiled value in ADDBA frame)   2:BA-not use. other value invalid
+		UCHAR       	AmsduEnable;	//Enable AMSDU transmisstion
+		UCHAR       	AmsduSize;	// 0:3839, 1:7935 bytes. UINT  MSDUSizeToBytes[]	= { 3839, 7935};
+		UCHAR       	MMPSmode;	// MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable
+		BOOLEAN		AutoBA;	// Auto BA will automatically
+} OID_BACAP_STRUC, *POID_BACAP_STRUC;
+
+typedef struct _RT_802_11_ACL_ENTRY {
+    UCHAR   Addr[MAC_ADDR_LENGTH];
+    USHORT  Rsv;
+} RT_802_11_ACL_ENTRY, *PRT_802_11_ACL_ENTRY;
+
+typedef struct PACKED _RT_802_11_ACL {
+    ULONG   Policy;             // 0-disable, 1-positive list, 2-negative list
+    ULONG   Num;
+    RT_802_11_ACL_ENTRY Entry[MAX_NUMBER_OF_ACL];
+} RT_802_11_ACL, *PRT_802_11_ACL;
+
+typedef struct _RT_802_11_WDS {
+    ULONG						Num;
+    NDIS_802_11_MAC_ADDRESS		Entry[24/*MAX_NUM_OF_WDS_LINK*/];
+	ULONG						KeyLength;
+	UCHAR						KeyMaterial[32];
+} RT_802_11_WDS, *PRT_802_11_WDS;
+
+typedef struct _RT_802_11_TX_RATES_ {
+    UCHAR       SupRateLen;
+    UCHAR       SupRate[MAX_LENGTH_OF_SUPPORT_RATES];
+    UCHAR       ExtRateLen;
+    UCHAR       ExtRate[MAX_LENGTH_OF_SUPPORT_RATES];
+} RT_802_11_TX_RATES, *PRT_802_11_TX_RATES;
+
+
+// Definition of extra information code
+#define	GENERAL_LINK_UP			0x0			// Link is Up
+#define	GENERAL_LINK_DOWN		0x1			// Link is Down
+#define	HW_RADIO_OFF			0x2			// Hardware radio off
+#define	SW_RADIO_OFF			0x3			// Software radio off
+#define	AUTH_FAIL				0x4			// Open authentication fail
+#define	AUTH_FAIL_KEYS			0x5			// Shared authentication fail
+#define	ASSOC_FAIL				0x6			// Association failed
+#define	EAP_MIC_FAILURE			0x7			// Deauthencation because MIC failure
+#define	EAP_4WAY_TIMEOUT		0x8			// Deauthencation on 4-way handshake timeout
+#define	EAP_GROUP_KEY_TIMEOUT	0x9			// Deauthencation on group key handshake timeout
+#define	EAP_SUCCESS				0xa			// EAP succeed
+#define	DETECT_RADAR_SIGNAL		0xb         // Radar signal occur in current channel
+#define EXTRA_INFO_MAX			0xb			// Indicate Last OID
+
+#define EXTRA_INFO_CLEAR		0xffffffff
+
+// This is OID setting structure. So only GF or MM as Mode. This is valid when our wirelss mode has 802.11n in use.
+typedef struct {
+	RT_802_11_PHY_MODE		PhyMode; 	//
+	UCHAR		TransmitNo;
+	UCHAR		HtMode; 	//HTMODE_GF or HTMODE_MM
+	UCHAR		ExtOffset;	//extension channel above or below
+	UCHAR		MCS;
+	UCHAR   	BW;
+	UCHAR		STBC;
+	UCHAR		SHORTGI;
+	UCHAR		rsv;
+} OID_SET_HT_PHYMODE, *POID_SET_HT_PHYMODE;
+
+#ifdef NINTENDO_AP
+#define NINTENDO_MAX_ENTRY 16
+#define NINTENDO_SSID_NAME_LN 8
+#define NINTENDO_SSID_NAME "NWCUSBAP"
+#define NINTENDO_PROBE_REQ_FLAG_MASK 0x03
+#define NINTENDO_PROBE_REQ_ON 0x01
+#define NINTENDO_PROBE_REQ_SIGNAL 0x02
+#define NINTENDO_PROBE_RSP_ON 0x01
+#define NINTENDO_SSID_NICKNAME_LN 20
+
+#define NINTENDO_WEPKEY_LN 13
+
+typedef struct _NINTENDO_SSID
+{
+	UCHAR	NINTENDOFixChar[NINTENDO_SSID_NAME_LN];
+	UCHAR	zero1;
+	UCHAR	registe;
+	UCHAR	ID;
+	UCHAR	zero2;
+	UCHAR	NICKname[NINTENDO_SSID_NICKNAME_LN];
+} RT_NINTENDO_SSID, *PRT_NINTENDO_SSID;
+
+typedef struct _NINTENDO_ENTRY
+{
+	UCHAR	NICKname[NINTENDO_SSID_NICKNAME_LN];
+    UCHAR   DS_Addr[ETH_LENGTH_OF_ADDRESS];
+	UCHAR	registe;
+	UCHAR	UserSpaceAck;
+} RT_NINTENDO_ENTRY, *PRT_NINTENDO_ENTRY;
+
+//RTPRIV_IOCTL_NINTENDO_GET_TABLE
+//RTPRIV_IOCTL_NINTENDO_SET_TABLE
+typedef struct _NINTENDO_TABLE
+{
+	UINT				number;
+	RT_NINTENDO_ENTRY	entry[NINTENDO_MAX_ENTRY];
+} RT_NINTENDO_TABLE, *PRT_NINTENDO_TABLE;
+
+//RTPRIV_IOCTL_NINTENDO_SEED_WEPKEY
+typedef struct _NINTENDO_SEED_WEPKEY
+{
+	UCHAR	seed[NINTENDO_SSID_NICKNAME_LN];
+	UCHAR	wepkey[16];//use 13 for 104 bits wep key
+} RT_NINTENDO_SEED_WEPKEY, *PRT_NINTENDO_SEED_WEPKEY;
+#endif // NINTENDO_AP //
+
+#ifdef LLTD_SUPPORT
+typedef struct _RT_LLTD_ASSOICATION_ENTRY {
+    UCHAR           Addr[ETH_LENGTH_OF_ADDRESS];
+    unsigned short  MOR;        // maximum operational rate
+    UCHAR           phyMode;
+} RT_LLTD_ASSOICATION_ENTRY, *PRT_LLTD_ASSOICATION_ENTRY;
+
+typedef struct _RT_LLTD_ASSOICATION_TABLE {
+    unsigned int                Num;
+    RT_LLTD_ASSOICATION_ENTRY   Entry[MAX_NUMBER_OF_MAC];
+} RT_LLTD_ASSOICATION_TABLE, *PRT_LLTD_ASSOICATION_TABLE;
+#endif // LLTD_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+//rt2860, kathy 2007-0118
+// structure for DLS
+typedef struct _RT_802_11_DLS_UI {
+	USHORT						TimeOut;		// unit: second , set by UI
+	USHORT						CountDownTimer;	// unit: second , used by driver only
+	NDIS_802_11_MAC_ADDRESS		MacAddr;		// set by UI
+	UCHAR						Status;			// 0: none , 1: wait STAkey, 2: finish DLS setup , set by driver only
+	BOOLEAN						Valid;			// 1: valid , 0: invalid , set by UI, use to setup or tear down DLS link
+} RT_802_11_DLS_UI, *PRT_802_11_DLS_UI;
+
+typedef struct _RT_802_11_DLS_INFO {
+	RT_802_11_DLS_UI	Entry[MAX_NUMBER_OF_DLS_ENTRY];
+	UCHAR				num;
+} RT_802_11_DLS_INFO, *PRT_802_11_DLS_INFO;
+
+typedef enum _RT_802_11_DLS_MODE {
+    DLS_NONE,
+    DLS_WAIT_KEY,
+    DLS_FINISH
+} RT_802_11_DLS_MODE;
+#endif // QOS_DLS_SUPPORT //
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+#define	RT_ASSOC_EVENT_FLAG                         0x0101
+#define	RT_DISASSOC_EVENT_FLAG                      0x0102
+#define	RT_REQIE_EVENT_FLAG                         0x0103
+#define	RT_RESPIE_EVENT_FLAG                        0x0104
+#define	RT_ASSOCINFO_EVENT_FLAG                     0x0105
+#define RT_PMKIDCAND_FLAG                           0x0106
+#define RT_INTERFACE_DOWN                           0x0107
+#define RT_INTERFACE_UP                             0x0108
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+
+#define MAX_CUSTOM_LEN 128
+
+#ifdef CONFIG_STA_SUPPORT
+typedef enum _RT_802_11_D_CLIENT_MODE
+{
+   Rt802_11_D_None,
+   Rt802_11_D_Flexible,
+   Rt802_11_D_Strict,
+} RT_802_11_D_CLIENT_MODE, *PRT_802_11_D_CLIENT_MODE;
+#endif // CONFIG_STA_SUPPORT //
+
+typedef struct _RT_CHANNEL_LIST_INFO
+{
+	UCHAR ChannelList[MAX_NUM_OF_CHS];   // list all supported channels for site survey
+	UCHAR ChannelListNum; // number of channel in ChannelList[]
+} RT_CHANNEL_LIST_INFO, *PRT_CHANNEL_LIST_INFO;
+
+// WSC configured credential
+typedef	struct	_WSC_CREDENTIAL
+{
+	NDIS_802_11_SSID	SSID;				// mandatory
+	USHORT				AuthType;			// mandatory, 1: open, 2: wpa-psk, 4: shared, 8:wpa, 0x10: wpa2, 0x20: wpa2-psk
+	USHORT				EncrType;			// mandatory, 1: none, 2: wep, 4: tkip, 8: aes
+	UCHAR				Key[64];			// mandatory, Maximum 64 byte
+	USHORT				KeyLength;
+	UCHAR				MacAddr[6];			// mandatory, AP MAC address
+	UCHAR				KeyIndex;			// optional, default is 1
+	UCHAR				Rsvd[3];			// Make alignment
+}	WSC_CREDENTIAL, *PWSC_CREDENTIAL;
+
+// WSC configured profiles
+typedef	struct	_WSC_PROFILE
+{
+	UINT			ProfileCnt;
+	WSC_CREDENTIAL	Profile[8];				// Support up to 8 profiles
+}	WSC_PROFILE, *PWSC_PROFILE;
+
+
+
+#endif // _OID_H_
+
diff --git a/drivers/staging/rt3070/rt2870.h b/drivers/staging/rt3070/rt2870.h
new file mode 100644
index 0000000..d32a2bf
--- /dev/null
+++ b/drivers/staging/rt3070/rt2870.h
@@ -0,0 +1,756 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+ */
+
+#ifndef __RT2870_H__
+#define __RT2870_H__
+
+//usb header files
+#include <linux/usb.h>
+
+/* rtmp_def.h */
+//
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#define BULKAGGRE_ZISE          100
+#define RT28XX_DRVDATA_SET(_a)                                             usb_set_intfdata(_a, pAd);
+#define RT28XX_PUT_DEVICE                                                  usb_put_dev
+#define RTUSB_ALLOC_URB(iso)                                               usb_alloc_urb(iso, GFP_ATOMIC)
+#define RTUSB_SUBMIT_URB(pUrb)                                             usb_submit_urb(pUrb, GFP_ATOMIC)
+#define	RTUSB_URB_ALLOC_BUFFER(pUsb_Dev, BufSize, pDma_addr)               usb_buffer_alloc(pUsb_Dev, BufSize, GFP_ATOMIC, pDma_addr)
+#define	RTUSB_URB_FREE_BUFFER(pUsb_Dev, BufSize, pTransferBuf, Dma_addr)   usb_buffer_free(pUsb_Dev, BufSize, pTransferBuf, Dma_addr)
+#else
+#define BULKAGGRE_ZISE          60
+#define RT28XX_DRVDATA_SET(_a)
+#define RT28XX_PUT_DEVICE(dev_p)
+#define RTUSB_ALLOC_URB(iso)                                               usb_alloc_urb(iso)
+#define RTUSB_SUBMIT_URB(pUrb)                                             usb_submit_urb(pUrb)
+#define RTUSB_URB_ALLOC_BUFFER(pUsb_Dev, BufSize, pDma_addr)               kmalloc(BufSize, GFP_ATOMIC)
+#define	RTUSB_URB_FREE_BUFFER(pUsb_Dev, BufSize, pTransferBuf, Dma_addr)   kfree(pTransferBuf)
+#endif
+
+#define RXBULKAGGRE_ZISE        12
+#define MAX_TXBULK_LIMIT        (LOCAL_TXBUF_SIZE*(BULKAGGRE_ZISE-1))
+#define MAX_TXBULK_SIZE         (LOCAL_TXBUF_SIZE*BULKAGGRE_ZISE)
+#define MAX_RXBULK_SIZE         (LOCAL_TXBUF_SIZE*RXBULKAGGRE_ZISE)
+#define MAX_MLME_HANDLER_MEMORY 20
+#define BUFFER_SIZE				2400	//2048
+#define	TX_RING					0xa
+#define	PRIO_RING				0xc
+
+
+// Flags for Bulkflags control for bulk out data
+//
+#define	fRTUSB_BULK_OUT_DATA_NULL				0x00000001
+#define fRTUSB_BULK_OUT_RTS						0x00000002
+#define	fRTUSB_BULK_OUT_MLME					0x00000004
+
+#define	fRTUSB_BULK_OUT_DATA_NORMAL				0x00010000
+#define	fRTUSB_BULK_OUT_DATA_NORMAL_2			0x00020000
+#define	fRTUSB_BULK_OUT_DATA_NORMAL_3			0x00040000
+#define	fRTUSB_BULK_OUT_DATA_NORMAL_4			0x00080000
+#define	fRTUSB_BULK_OUT_DATA_NORMAL_5			0x00100000
+
+#define	fRTUSB_BULK_OUT_PSPOLL					0x00000020
+#define	fRTUSB_BULK_OUT_DATA_FRAG				0x00000040
+#define	fRTUSB_BULK_OUT_DATA_FRAG_2				0x00000080
+#define	fRTUSB_BULK_OUT_DATA_FRAG_3				0x00000100
+#define	fRTUSB_BULK_OUT_DATA_FRAG_4				0x00000200
+
+#ifdef RALINK_ATE
+#define	fRTUSB_BULK_OUT_DATA_ATE				0x00100000
+#endif // RALINK_ATE //
+
+#define RT2870_USB_DEVICES	\
+{	\
+	{USB_DEVICE(0x148F,0x2770)}, /* Ralink */		\
+	{USB_DEVICE(0x148F,0x2870)}, /* Ralink */		\
+	{USB_DEVICE(0x148F,0x3070)}, /* Ralink 3070 */	\
+	{USB_DEVICE(0x148F,0x3071)}, /* Ralink 3071 */	\
+	{USB_DEVICE(0x148F,0x3072)}, /* Ralink 3072 */	\
+	{USB_DEVICE(0x0B05,0x1731)}, /* Asus */			\
+	{USB_DEVICE(0x0B05,0x1732)}, /* Asus */			\
+	{USB_DEVICE(0x0B05,0x1742)}, /* Asus */			\
+	{USB_DEVICE(0x0DF6,0x0017)}, /* Sitecom */		\
+	{USB_DEVICE(0x0DF6,0x002B)}, /* Sitecom */		\
+	{USB_DEVICE(0x0DF6,0x002C)}, /* Sitecom */		\
+	{USB_DEVICE(0x0DF6,0x003E)}, /* Sitecom 3070 */	\
+	{USB_DEVICE(0x0DF6,0x002D)}, /* Sitecom */		\
+	{USB_DEVICE(0x0DF6,0x0039)}, /* Sitecom 2770 */	\
+	{USB_DEVICE(0x14B2,0x3C06)}, /* Conceptronic */	\
+	{USB_DEVICE(0x14B2,0x3C28)}, /* Conceptronic */	\
+	{USB_DEVICE(0x2019,0xED06)}, /* Planex Communications, Inc. */		\
+	{USB_DEVICE(0x2019,0xAB25)}, /* Planex Communications, Inc. RT3070 */		\
+	{USB_DEVICE(0x07D1,0x3C09)}, /* D-Link */		\
+	{USB_DEVICE(0x07D1,0x3C11)}, /* D-Link */		\
+	{USB_DEVICE(0x2001,0x3C09)}, /* D-Link */		\
+	{USB_DEVICE(0x2001,0x3C0A)}, /* D-Link 3072*/	\
+	{USB_DEVICE(0x14B2,0x3C07)}, /* AL */			\
+	{USB_DEVICE(0x14B2,0x3C12)}, /* AL 3070 */		\
+	{USB_DEVICE(0x050D,0x8053)}, /* Belkin */		\
+	{USB_DEVICE(0x14B2,0x3C23)}, /* Airlink */		\
+	{USB_DEVICE(0x14B2,0x3C27)}, /* Airlink */		\
+	{USB_DEVICE(0x07AA,0x002F)}, /* Corega */		\
+	{USB_DEVICE(0x07AA,0x003C)}, /* Corega */		\
+	{USB_DEVICE(0x07AA,0x003F)}, /* Corega */		\
+	{USB_DEVICE(0x18C5,0x0012)}, /* Corega 3070 */	\
+	{USB_DEVICE(0x1044,0x800B)}, /* Gigabyte */		\
+	{USB_DEVICE(0x1044,0x800D)}, /* Gigabyte GN-WB32L 3070 */		\
+	{USB_DEVICE(0x15A9,0x0006)}, /* Sparklan */		\
+	{USB_DEVICE(0x083A,0xB522)}, /* SMC */			\
+	{USB_DEVICE(0x083A,0xA618)}, /* SMC */			\
+	{USB_DEVICE(0x083A,0x8522)}, /* Arcadyan */		\
+	{USB_DEVICE(0x083A,0x7512)}, /* Arcadyan 2770 */		\
+	{USB_DEVICE(0x083A,0x7522)}, /* Arcadyan */		\
+	{USB_DEVICE(0x083A,0x7511)}, /* Arcadyan 3070 */ \
+	{USB_DEVICE(0x0CDE,0x0022)}, /* ZCOM */			\
+	{USB_DEVICE(0x0586,0x3416)}, /* Zyxel */		\
+	{USB_DEVICE(0x0CDE,0x0025)}, /* Zyxel */		\
+	{USB_DEVICE(0x1740,0x9701)}, /* EnGenius */		\
+	{USB_DEVICE(0x1740,0x9702)}, /* EnGenius */		\
+	{USB_DEVICE(0x1740,0x9703)}, /* EnGenius 3070 */		\
+	{USB_DEVICE(0x0471,0x200f)}, /* Philips */		\
+	{USB_DEVICE(0x14B2,0x3C25)}, /* Draytek */		\
+	{USB_DEVICE(0x13D3,0x3247)}, /* AzureWave */	\
+	{USB_DEVICE(0x13D3,0x3273)}, /* AzureWave 3070*/	\
+	{USB_DEVICE(0x083A,0x6618)}, /* Accton */		\
+	{USB_DEVICE(0x15c5,0x0008)}, /* Amit */			\
+	{USB_DEVICE(0x0E66,0x0001)}, /* Hawking */		\
+	{USB_DEVICE(0x0E66,0x0003)}, /* Hawking */		\
+	{USB_DEVICE(0x129B,0x1828)}, /* Siemens */		\
+	{USB_DEVICE(0x157E,0x300E)}, /* U-Media */		\
+	{USB_DEVICE(0x050d,0x805c)},					\
+	{USB_DEVICE(0x1482,0x3C09)}, /* Abocom*/		\
+	{USB_DEVICE(0x14B2,0x3C09)}, /* Alpha */		\
+	{USB_DEVICE(0x04E8,0x2018)}, /* samsung */  	\
+	{USB_DEVICE(0x07B8,0x3070)}, /* AboCom 3070 */	\
+	{USB_DEVICE(0x07B8,0x3071)}, /* AboCom 3071 */	\
+	{USB_DEVICE(0x07B8,0x3072)}, /* Abocom 3072 */	\
+	{USB_DEVICE(0x7392,0x7711)}, /* Edimax 3070 */	\
+	{USB_DEVICE(0x5A57,0x0280)}, /* Zinwell */		\
+	{USB_DEVICE(0x5A57,0x0282)}, /* Zinwell */		\
+	{USB_DEVICE(0x1A32,0x0304)}, /* Quanta 3070 */		\
+	{USB_DEVICE(0x0789,0x0162)}, /* Logitec 2870 */		\
+	{USB_DEVICE(0x0789,0x0163)}, /* Logitec 2870 */		\
+	{USB_DEVICE(0x0789,0x0164)}, /* Logitec 2870 */		\
+	{USB_DEVICE(0x1EDA,0x2310)}, /* AirTies 3070 */		\
+	{ }/* Terminating entry */                      \
+}
+
+#define	FREE_HTTX_RING(_p, _b, _t)			\
+{										\
+	if ((_t)->ENextBulkOutPosition == (_t)->CurWritePosition)				\
+	{																	\
+		(_t)->bRingEmpty = TRUE;			\
+	}																	\
+	/*NdisInterlockedDecrement(&(_p)->TxCount); */\
+}
+
+//
+// RXINFO appends at the end of each rx packet.
+//
+#ifdef RT_BIG_ENDIAN
+typedef	struct	PACKED _RXINFO_STRUC {
+	UINT32		PlcpSignal:12;
+	UINT32		LastAMSDU:1;
+	UINT32		CipherAlg:1;
+	UINT32		PlcpRssil:1;
+	UINT32		Decrypted:1;
+	UINT32		AMPDU:1;		// To be moved
+	UINT32		L2PAD:1;
+	UINT32		RSSI:1;
+	UINT32		HTC:1;
+	UINT32		AMSDU:1;		// rx with 802.3 header, not 802.11 header.
+	UINT32		CipherErr:2;        // 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid
+	UINT32		Crc:1;              // 1: CRC error
+	UINT32		MyBss:1;  	// 1: this frame belongs to the same BSSID
+	UINT32		Bcast:1;            // 1: this is a broadcast frame
+	UINT32		Mcast:1;            // 1: this is a multicast frame
+	UINT32		U2M:1;              // 1: this RX frame is unicast to me
+	UINT32		FRAG:1;
+	UINT32		NULLDATA:1;
+	UINT32		DATA:1;
+	UINT32		BA:1;
+}	RXINFO_STRUC, *PRXINFO_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
+#else
+typedef	struct	PACKED _RXINFO_STRUC {
+	UINT32		BA:1;
+	UINT32		DATA:1;
+	UINT32		NULLDATA:1;
+	UINT32		FRAG:1;
+	UINT32		U2M:1;              // 1: this RX frame is unicast to me
+	UINT32		Mcast:1;            // 1: this is a multicast frame
+	UINT32		Bcast:1;            // 1: this is a broadcast frame
+	UINT32		MyBss:1;  	// 1: this frame belongs to the same BSSID
+	UINT32		Crc:1;              // 1: CRC error
+	UINT32		CipherErr:2;        // 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid
+	UINT32		AMSDU:1;		// rx with 802.3 header, not 802.11 header.
+	UINT32		HTC:1;
+	UINT32		RSSI:1;
+	UINT32		L2PAD:1;
+	UINT32		AMPDU:1;		// To be moved
+	UINT32		Decrypted:1;
+	UINT32		PlcpRssil:1;
+	UINT32		CipherAlg:1;
+	UINT32		LastAMSDU:1;
+	UINT32		PlcpSignal:12;
+}	RXINFO_STRUC, *PRXINFO_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
+#endif
+
+
+//
+// TXINFO
+//
+#ifdef RT_BIG_ENDIAN
+typedef	struct	_TXINFO_STRUC {
+	// Word	0
+	UINT32		USBDMATxburst:1;//used ONLY in USB bulk Aggre. Force USB DMA transmit frame from current selected endpoint
+	UINT32		USBDMANextVLD:1;	//used ONLY in USB bulk Aggregation, NextValid
+	UINT32		rsv2:2;  // Software use.
+	UINT32		SwUseLastRound:1; // Software use.
+	UINT32		QSEL:2;	// select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
+	UINT32		WIV:1;	// Wireless Info Valid. 1 if Driver already fill WI,  o if DMA needs to copy WI to correctposition
+	UINT32		rsv:8;
+	UINT32		USBDMATxPktLen:16;	//used ONLY in USB bulk Aggregation,  Total byte counts of all sub-frame.
+}	TXINFO_STRUC, *PTXINFO_STRUC;
+#else
+typedef	struct	_TXINFO_STRUC {
+	// Word	0
+	UINT32		USBDMATxPktLen:16;	//used ONLY in USB bulk Aggregation,  Total byte counts of all sub-frame.
+	UINT32		rsv:8;
+	UINT32		WIV:1;	// Wireless Info Valid. 1 if Driver already fill WI,  o if DMA needs to copy WI to correctposition
+	UINT32		QSEL:2;	// select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
+	UINT32		SwUseLastRound:1; // Software use.
+	UINT32		rsv2:2;  // Software use.
+	UINT32		USBDMANextVLD:1;	//used ONLY in USB bulk Aggregation, NextValid
+	UINT32		USBDMATxburst:1;//used ONLY in USB bulk Aggre. Force USB DMA transmit frame from current selected endpoint
+}	TXINFO_STRUC, *PTXINFO_STRUC;
+#endif
+
+#define TXINFO_SIZE				4
+#define RXINFO_SIZE				4
+#define TXPADDING_SIZE			11
+
+//
+// Management ring buffer format
+//
+typedef	struct	_MGMT_STRUC	{
+	BOOLEAN		Valid;
+	PUCHAR		pBuffer;
+	ULONG		Length;
+}	MGMT_STRUC, *PMGMT_STRUC;
+
+
+/* ----------------- EEPROM Related MACRO ----------------- */
+#ifdef RT30xx
+#define RT28xx_EEPROM_READ16(pAd, offset, var)					\
+	do {														\
+		RTUSBReadEEPROM(pAd, offset, (PUCHAR)&(var), 2);		\
+		if(!pAd->bUseEfuse)										\
+			var = le2cpu16(var);								\
+	}while(0)
+
+#define RT28xx_EEPROM_WRITE16(pAd, offset, var)					\
+	do{															\
+		USHORT _tmpVar=var;										\
+		if(!pAd->bUseEfuse)									\
+		_tmpVar = cpu2le16(var);								\
+		RTUSBWriteEEPROM(pAd, offset, (PUCHAR)&(_tmpVar), 2);	\
+	}while(0)
+#endif // RT30xx //
+#ifndef RT30xx
+#define RT28xx_EEPROM_READ16(pAd, offset, var)					\
+	do {														\
+		RTUSBReadEEPROM(pAd, offset, (PUCHAR)&(var), 2);		\
+			var = le2cpu16(var);								\
+	}while(0)
+
+#define RT28xx_EEPROM_WRITE16(pAd, offset, var)					\
+	do{															\
+		USHORT _tmpVar=var;										\
+		_tmpVar = cpu2le16(var);								\
+		RTUSBWriteEEPROM(pAd, offset, (PUCHAR)&(_tmpVar), 2);	\
+	}while(0)
+#endif // RT30xx //
+
+/* ----------------- TASK/THREAD Related MACRO ----------------- */
+#define RT28XX_TASK_THREAD_INIT(pAd, Status)		\
+	Status = CreateThreads(net_dev);
+
+
+/* ----------------- Frimware Related MACRO ----------------- */
+#define RT28XX_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen)		\
+	RTUSBFirmwareWrite(_pAd, _pFwImage, _FwLen)
+
+/* ----------------- TX Related MACRO ----------------- */
+#define RT28XX_START_DEQUEUE(pAd, QueIdx, irqFlags)				\
+			{													\
+				RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags);		\
+				if (pAd->DeQueueRunning[QueIdx])						\
+				{														\
+					RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\
+					printk("DeQueueRunning[%d]= TRUE!\n", QueIdx);		\
+					continue;											\
+				}														\
+				else													\
+				{														\
+					pAd->DeQueueRunning[QueIdx] = TRUE;					\
+					RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\
+				}														\
+			}
+#define RT28XX_STOP_DEQUEUE(pAd, QueIdx, irqFlags)						\
+			do{															\
+				RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags);		\
+				pAd->DeQueueRunning[QueIdx] = FALSE;					\
+				RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);	\
+			}while(0)
+
+
+#define	RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \
+		(RTUSBFreeDescriptorRequest(pAd, pTxBlk->QueIdx, (pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))) == NDIS_STATUS_SUCCESS)
+
+#define RT28XX_RELEASE_DESC_RESOURCE(pAd, QueIdx)			\
+		do{}while(0)
+
+#define NEED_QUEUE_BACK_FOR_AGG(_pAd, _QueIdx, _freeNum, _TxFrameType) 		\
+		((_TxFrameType == TX_RALINK_FRAME) && (RTUSBNeedQueueBackForAgg(_pAd, _QueIdx)))
+
+
+
+#define fRTMP_ADAPTER_NEED_STOP_TX		\
+		(fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS |	\
+		 fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_BULKOUT_RESET | \
+		 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
+
+
+#define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)	\
+			RtmpUSB_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)
+
+#define HAL_WriteTxResource(pAd, pTxBlk,bIsLast, pFreeNumber)	\
+			RtmpUSB_WriteSingleTxResource(pAd, pTxBlk,bIsLast, pFreeNumber)
+
+#define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \
+			RtmpUSB_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber)
+
+#define HAL_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber)	\
+			RtmpUSB_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber)
+
+#define HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx)	\
+			RtmpUSB_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx)
+
+#define HAL_LastTxIdx(pAd, QueIdx,TxIdx) \
+			/*RtmpUSBDataLastTxIdx(pAd, QueIdx,TxIdx)*/
+
+#define HAL_KickOutTx(pAd, pTxBlk, QueIdx)	\
+			RtmpUSBDataKickOut(pAd, pTxBlk, QueIdx)
+
+
+#define HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen)	\
+			RtmpUSBMgmtKickOut(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen)
+
+#define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen)	\
+			RtmpUSBNullFrameKickOut(_pAd, _QueIdx, _pNullFrame, _frameLen)
+
+#define RTMP_PKT_TAIL_PADDING 	11 // 3(max 4 byte padding) + 4 (last packet padding) + 4 (MaxBulkOutsize align padding)
+
+extern UCHAR EpToQueue[6];
+
+
+#ifdef RT2870
+#define GET_TXRING_FREENO(_pAd, _QueIdx) 	(_QueIdx) //(_pAd->TxRing[_QueIdx].TxSwFreeIdx)
+#define GET_MGMTRING_FREENO(_pAd) 			(_pAd->MgmtRing.TxSwFreeIdx)
+#endif // RT2870 //
+
+
+/* ----------------- RX Related MACRO ----------------- */
+//#define RT28XX_RX_ERROR_CHECK				RTMPCheckRxWI
+
+#define RT28XX_RV_ALL_BUF_END(bBulkReceive)		\
+	/* We return STATUS_MORE_PROCESSING_REQUIRED so that the completion */	\
+	/* routine (IofCompleteRequest) will stop working on the irp. */		\
+	if (bBulkReceive == TRUE)	RTUSBBulkReceive(pAd);
+
+
+/* ----------------- ASIC Related MACRO ----------------- */
+// reset MAC of a station entry to 0xFFFFFFFFFFFF
+#define RT28XX_STA_ENTRY_MAC_RESET(pAd, Wcid)					\
+	{	RT_SET_ASIC_WCID	SetAsicWcid;						\
+		SetAsicWcid.WCID = Wcid;								\
+		SetAsicWcid.SetTid = 0xffffffff;						\
+		SetAsicWcid.DeleteTid = 0xffffffff;						\
+		RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_ASIC_WCID, 	\
+				&SetAsicWcid, sizeof(RT_SET_ASIC_WCID));	}
+
+// add this entry into ASIC RX WCID search table
+#define RT28XX_STA_ENTRY_ADD(pAd, pEntry)							\
+	RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_CLIENT_MAC_ENTRY, 	\
+							pEntry, sizeof(MAC_TABLE_ENTRY));
+
+// add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
+// Set MAC register value according operation mode
+#define RT28XX_UPDATE_PROTECT(pAd)	\
+ 	RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_UPDATE_PROTECT, NULL, 0);
+// end johnli
+
+// remove Pair-wise key material from ASIC
+// yet implement
+#define RT28XX_STA_ENTRY_KEY_DEL(pAd, BssIdx, Wcid)
+
+// add Client security information into ASIC WCID table and IVEIV table
+#define RT28XX_STA_SECURITY_INFO_ADD(pAd, apidx, KeyID, pEntry)						\
+	{	RT28XX_STA_ENTRY_MAC_RESET(pAd, pEntry->Aid);								\
+		if (pEntry->Aid >= 1) {														\
+			RT_SET_ASIC_WCID_ATTRI	SetAsicWcidAttri;								\
+			SetAsicWcidAttri.WCID = pEntry->Aid;									\
+			if ((pEntry->AuthMode <= Ndis802_11AuthModeAutoSwitch) &&				\
+				(pEntry->WepStatus == Ndis802_11Encryption1Enabled))				\
+			{																		\
+				SetAsicWcidAttri.Cipher = pAd->SharedKey[apidx][KeyID].CipherAlg;	\
+			}																		\
+			else if (pEntry->AuthMode == Ndis802_11AuthModeWPANone)					\
+			{																		\
+				SetAsicWcidAttri.Cipher = pAd->SharedKey[apidx][KeyID].CipherAlg;	\
+			}																		\
+			else SetAsicWcidAttri.Cipher = 0;										\
+            DBGPRINT(RT_DEBUG_TRACE, ("aid cipher = %ld\n",SetAsicWcidAttri.Cipher));       \
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_ASIC_WCID_CIPHER, 			\
+							&SetAsicWcidAttri, sizeof(RT_SET_ASIC_WCID_ATTRI)); } }
+
+// Insert the BA bitmap to ASIC for the Wcid entry
+#define RT28XX_ADD_BA_SESSION_TO_ASIC(_pAd, _Aid, _TID)					\
+		do{																\
+			RT_SET_ASIC_WCID	SetAsicWcid;							\
+			SetAsicWcid.WCID = (_Aid);									\
+			SetAsicWcid.SetTid = (0x10000<<(_TID));						\
+			SetAsicWcid.DeleteTid = 0xffffffff;							\
+			RTUSBEnqueueInternalCmd((_pAd), CMDTHREAD_SET_ASIC_WCID, &SetAsicWcid, sizeof(RT_SET_ASIC_WCID));	\
+		}while(0)
+
+// Remove the BA bitmap from ASIC for the Wcid entry
+#define RT28XX_DEL_BA_SESSION_FROM_ASIC(_pAd, _Wcid, _TID)				\
+		do{																\
+			RT_SET_ASIC_WCID	SetAsicWcid;							\
+			SetAsicWcid.WCID = (_Wcid);									\
+			SetAsicWcid.SetTid = (0xffffffff);							\
+			SetAsicWcid.DeleteTid = (0x10000<<(_TID) );					\
+			RTUSBEnqueueInternalCmd((_pAd), CMDTHREAD_SET_ASIC_WCID, &SetAsicWcid, sizeof(RT_SET_ASIC_WCID));	\
+		}while(0)
+
+
+/* ----------------- PCI/USB Related MACRO ----------------- */
+#define RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p)			\
+	((POS_COOKIE)handle)->pUsb_Dev = dev_p;
+
+// no use
+#define RT28XX_UNMAP()
+#define RT28XX_IRQ_REQUEST(net_dev)
+#define RT28XX_IRQ_RELEASE(net_dev)
+#define RT28XX_IRQ_INIT(pAd)
+#define RT28XX_IRQ_ENABLE(pAd)
+
+
+/* ----------------- MLME Related MACRO ----------------- */
+#define RT28XX_MLME_HANDLER(pAd)			RTUSBMlmeUp(pAd)
+
+#define RT28XX_MLME_PRE_SANITY_CHECK(pAd)								\
+	{	if ((pAd->CommonCfg.bHardwareRadio == TRUE) && 					\
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&		\
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) {	\
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_CHECK_GPIO, NULL, 0); } }
+
+#define RT28XX_MLME_STA_QUICK_RSP_WAKE_UP(pAd)	\
+	{	RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_QKERIODIC_EXECUT, NULL, 0);	\
+		RTUSBMlmeUp(pAd); }
+
+#define RT28XX_MLME_RESET_STATE_MACHINE(pAd)	\
+		        MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_RESET_CONF, 0, NULL);	\
+		        RTUSBMlmeUp(pAd);
+
+#define RT28XX_HANDLE_COUNTER_MEASURE(_pAd, _pEntry)		\
+	{	RTUSBEnqueueInternalCmd(_pAd, CMDTHREAD_802_11_COUNTER_MEASURE, _pEntry, sizeof(MAC_TABLE_ENTRY));	\
+		RTUSBMlmeUp(_pAd);									\
+	}
+
+
+/* ----------------- Power Save Related MACRO ----------------- */
+#define RT28XX_PS_POLL_ENQUEUE(pAd)						\
+	{	RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);	\
+		RTUSBKickBulkOut(pAd); }
+
+#define RT28xx_CHIP_NAME            "RT2870"
+#define USB_CYC_CFG                 0x02a4
+#define NT_SUCCESS(status)			(((status) > 0) ? (1):(0))
+#define InterlockedIncrement 	 	atomic_inc
+#define NdisInterlockedIncrement 	atomic_inc
+#define InterlockedDecrement		atomic_dec
+#define NdisInterlockedDecrement 	atomic_dec
+#define InterlockedExchange			atomic_set
+//#define NdisMSendComplete			RTMP_SendComplete
+#define NdisMCancelTimer			RTMPCancelTimer
+#define NdisAllocMemory(_ptr, _size, _flag)	\
+									do{_ptr = kmalloc((_size),(_flag));}while(0)
+#define NdisFreeMemory(a, b, c) 	kfree((a))
+#define NdisMSleep					RTMPusecDelay		/* unit: microsecond */
+
+
+#define USBD_TRANSFER_DIRECTION_OUT		0
+#define USBD_TRANSFER_DIRECTION_IN		0
+#define USBD_SHORT_TRANSFER_OK			0
+#define PURB			purbb_t
+
+#define RTUSB_FREE_URB(pUrb)	usb_free_urb(pUrb)
+
+//#undef MlmeAllocateMemory
+//#undef MlmeFreeMemory
+
+typedef struct usb_device	* PUSB_DEV;
+
+/* MACRO for linux usb */
+typedef struct urb *purbb_t;
+typedef struct usb_ctrlrequest devctrlrequest;
+#define PIRP		PVOID
+#define PMDL		PVOID
+#define NDIS_OID	UINT
+#ifndef USB_ST_NOERROR
+#define USB_ST_NOERROR     0
+#endif
+
+// vendor-specific control operations
+#define CONTROL_TIMEOUT_JIFFIES ( (100 * HZ) / 1000)
+#define UNLINK_TIMEOUT_MS		3
+
+/* unlink urb	*/
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,7)
+#define RTUSB_UNLINK_URB(pUrb)		usb_kill_urb(pUrb)
+#else
+#define RTUSB_UNLINK_URB(pUrb)		usb_unlink_urb(pUrb)
+#endif
+
+// Prototypes of completion funuc.
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#define RTUSBBulkOutDataPacketComplete(purb, pt_regs)    RTUSBBulkOutDataPacketComplete(purb)
+#define RTUSBBulkOutMLMEPacketComplete(pUrb, pt_regs)    RTUSBBulkOutMLMEPacketComplete(pUrb)
+#define RTUSBBulkOutNullFrameComplete(pUrb, pt_regs)     RTUSBBulkOutNullFrameComplete(pUrb)
+#define RTUSBBulkOutRTSFrameComplete(pUrb, pt_regs)      RTUSBBulkOutRTSFrameComplete(pUrb)
+#define RTUSBBulkOutPsPollComplete(pUrb, pt_regs)        RTUSBBulkOutPsPollComplete(pUrb)
+#define RTUSBBulkRxComplete(pUrb, pt_regs)               RTUSBBulkRxComplete(pUrb)
+#endif
+
+
+VOID RTUSBBulkOutDataPacketComplete(purbb_t purb, struct pt_regs *pt_regs);
+VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs);
+VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs);
+VOID RTUSBBulkOutRTSFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs);
+VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb, struct pt_regs *pt_regs);
+VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs);
+
+
+#define RTUSBMlmeUp(pAd)	        \
+{								    \
+	POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;	\
+	if(pObj->MLMEThr_pid>0)		    \
+        up(&(pAd->mlme_semaphore)); \
+}
+
+#define RTUSBCMDUp(pAd)	                \
+{									    \
+	POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;	\
+	if(pObj->RTUSBCmdThr_pid>0)		    \
+	    up(&(pAd->RTUSBCmd_semaphore)); \
+}
+
+
+static inline NDIS_STATUS RTMPAllocateMemory(
+	OUT PVOID *ptr,
+	IN size_t size)
+{
+	*ptr = kmalloc(size, GFP_ATOMIC);
+	if(*ptr)
+		return NDIS_STATUS_SUCCESS;
+	else
+		return NDIS_STATUS_RESOURCES;
+}
+
+/* rtmp.h */
+#define	BEACON_RING_SIZE                2
+#define DEVICE_VENDOR_REQUEST_OUT       0x40
+#define DEVICE_VENDOR_REQUEST_IN        0xc0
+#define INTERFACE_VENDOR_REQUEST_OUT    0x41
+#define INTERFACE_VENDOR_REQUEST_IN     0xc1
+#define MGMTPIPEIDX						0	// EP6 is highest priority
+
+#define BULKOUT_MGMT_RESET_FLAG				0x80
+
+#define RTUSB_SET_BULK_FLAG(_M, _F)				((_M)->BulkFlags |= (_F))
+#define RTUSB_CLEAR_BULK_FLAG(_M, _F)			((_M)->BulkFlags &= ~(_F))
+#define RTUSB_TEST_BULK_FLAG(_M, _F)			(((_M)->BulkFlags & (_F)) != 0)
+
+#define EnqueueCmd(cmdq, cmdqelmt)		\
+{										\
+	if (cmdq->size == 0)				\
+		cmdq->head = cmdqelmt;			\
+	else								\
+		cmdq->tail->next = cmdqelmt;	\
+	cmdq->tail = cmdqelmt;				\
+	cmdqelmt->next = NULL;				\
+	cmdq->size++;						\
+}
+
+typedef struct   _RT_SET_ASIC_WCID {
+	ULONG WCID;          // mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based
+	ULONG SetTid;        // time-based: seconds, packet-based: kilo-packets
+	ULONG DeleteTid;        // time-based: seconds, packet-based: kilo-packets
+} RT_SET_ASIC_WCID,*PRT_SET_ASIC_WCID;
+
+typedef struct   _RT_SET_ASIC_WCID_ATTRI {
+	ULONG	WCID;          // mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based
+	ULONG	Cipher;        // ASIC Cipher definition
+	UCHAR	Addr[ETH_LENGTH_OF_ADDRESS];
+} RT_SET_ASIC_WCID_ATTRI,*PRT_SET_ASIC_WCID_ATTRI;
+
+typedef struct _MLME_MEMORY_STRUCT {
+	PVOID                           AllocVa;    //Pointer to the base virtual address of the allocated memory
+	struct _MLME_MEMORY_STRUCT      *Next;      //Pointer to the next virtual address of the allocated memory
+}   MLME_MEMORY_STRUCT, *PMLME_MEMORY_STRUCT;
+
+typedef struct  _MLME_MEMORY_HANDLER {
+	BOOLEAN                 MemRunning;         //The flag of the Mlme memory handler's status
+	UINT                    MemoryCount;        //Total nonpaged system-space memory not size
+	UINT                    InUseCount;         //Nonpaged system-space memory in used counts
+	UINT                    UnUseCount;         //Nonpaged system-space memory available counts
+	INT                    PendingCount;       //Nonpaged system-space memory for free counts
+	PMLME_MEMORY_STRUCT     pInUseHead;         //Pointer to the first nonpaed memory not used
+	PMLME_MEMORY_STRUCT     pInUseTail;         //Pointer to the last nonpaged memory not used
+	PMLME_MEMORY_STRUCT     pUnUseHead;         //Pointer to the first nonpaged memory in used
+	PMLME_MEMORY_STRUCT     pUnUseTail;         //Pointer to the last nonpaged memory in used
+	PULONG                  MemFreePending[MAX_MLME_HANDLER_MEMORY];   //an array to keep pending free-memory's pointer (32bits)
+}   MLME_MEMORY_HANDLER, *PMLME_MEMORY_HANDLER;
+
+typedef	struct _CmdQElmt	{
+	UINT				command;
+	PVOID				buffer;
+	ULONG				bufferlength;
+	BOOLEAN				CmdFromNdis;
+	BOOLEAN				SetOperation;
+	struct _CmdQElmt	*next;
+}	CmdQElmt, *PCmdQElmt;
+
+typedef	struct	_CmdQ	{
+	UINT		size;
+	CmdQElmt	*head;
+	CmdQElmt	*tail;
+	UINT32		CmdQState;
+}CmdQ, *PCmdQ;
+
+//
+// For WPA SUPPLICANT: WIRELESS EXT support wireless events: v14 or newer
+//
+#if WIRELESS_EXT >= 14
+//#define WPA_SUPPLICANT_SUPPORT  1
+#endif
+
+/* oid.h */
+// Cipher suite type for mixed mode group cipher, P802.11i-2004
+typedef enum _RT_802_11_CIPHER_SUITE_TYPE {
+	Cipher_Type_NONE,
+	Cipher_Type_WEP40,
+	Cipher_Type_TKIP,
+	Cipher_Type_RSVD,
+	Cipher_Type_CCMP,
+	Cipher_Type_WEP104
+} RT_802_11_CIPHER_SUITE_TYPE, *PRT_802_11_CIPHER_SUITE_TYPE;
+
+//CMDTHREAD_MULTI_READ_MAC
+//CMDTHREAD_MULTI_WRITE_MAC
+//CMDTHREAD_VENDOR_EEPROM_READ
+//CMDTHREAD_VENDOR_EEPROM_WRITE
+typedef	struct	_CMDHandler_TLV	{
+	USHORT		Offset;
+	USHORT		Length;
+	UCHAR		DataFirst;
+}	CMDHandler_TLV, *PCMDHandler_TLV;
+
+// New for MeetingHouse Api support
+#define CMDTHREAD_VENDOR_RESET                      0x0D730101	// cmd
+#define CMDTHREAD_VENDOR_UNPLUG                     0x0D730102	// cmd
+#define CMDTHREAD_VENDOR_SWITCH_FUNCTION            0x0D730103	// cmd
+#define CMDTHREAD_MULTI_WRITE_MAC                   0x0D730107	// cmd
+#define CMDTHREAD_MULTI_READ_MAC                    0x0D730108	// cmd
+#define CMDTHREAD_VENDOR_EEPROM_WRITE               0x0D73010A	// cmd
+#define CMDTHREAD_VENDOR_EEPROM_READ                0x0D73010B	// cmd
+#define CMDTHREAD_VENDOR_ENTER_TESTMODE             0x0D73010C	// cmd
+#define CMDTHREAD_VENDOR_EXIT_TESTMODE              0x0D73010D	// cmd
+#define CMDTHREAD_VENDOR_WRITE_BBP                  0x0D730119	// cmd
+#define CMDTHREAD_VENDOR_READ_BBP                   0x0D730118	// cmd
+#define CMDTHREAD_VENDOR_WRITE_RF                   0x0D73011A	// cmd
+#define CMDTHREAD_VENDOR_FLIP_IQ                    0x0D73011D	// cmd
+#define CMDTHREAD_RESET_BULK_OUT                    0x0D730210	// cmd
+#define CMDTHREAD_RESET_BULK_IN                     0x0D730211	// cmd
+#define CMDTHREAD_SET_PSM_BIT_SAVE                  0x0D730212	// cmd
+#define CMDTHREAD_SET_RADIO                         0x0D730214	// cmd
+#define CMDTHREAD_UPDATE_TX_RATE                    0x0D730216	// cmd
+#define CMDTHREAD_802_11_ADD_KEY_WEP                0x0D730218	// cmd
+#define CMDTHREAD_RESET_FROM_ERROR                  0x0D73021A	// cmd
+#define CMDTHREAD_LINK_DOWN                         0x0D73021B	// cmd
+#define CMDTHREAD_RESET_FROM_NDIS                   0x0D73021C	// cmd
+#define CMDTHREAD_CHECK_GPIO                        0x0D730215	// cmd
+#define CMDTHREAD_FORCE_WAKE_UP                     0x0D730222	// cmd
+#define CMDTHREAD_SET_BW                            0x0D730225	// cmd
+#define CMDTHREAD_SET_ASIC_WCID                     0x0D730226	// cmd
+#define CMDTHREAD_SET_ASIC_WCID_CIPHER              0x0D730227	// cmd
+#define CMDTHREAD_QKERIODIC_EXECUT                  0x0D73023D	// cmd
+#define RT_CMD_SET_KEY_TABLE                        0x0D730228  // cmd
+#define RT_CMD_SET_RX_WCID_TABLE                    0x0D730229  // cmd
+#define CMDTHREAD_SET_CLIENT_MAC_ENTRY              0x0D73023E	// cmd
+#define CMDTHREAD_802_11_QUERY_HARDWARE_REGISTER    0x0D710105	// cmd
+#define CMDTHREAD_802_11_SET_PHY_MODE               0x0D79010C	// cmd
+#define CMDTHREAD_802_11_SET_STA_CONFIG             0x0D790111	// cmd
+#define CMDTHREAD_802_11_SET_PREAMBLE               0x0D790101	// cmd
+#define CMDTHREAD_802_11_COUNTER_MEASURE			0x0D790102	// cmd
+// add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
+#define CMDTHREAD_UPDATE_PROTECT					0x0D790103	// cmd
+// end johnli
+
+#define WPA1AKMBIT	    0x01
+#define WPA2AKMBIT	    0x02
+#define WPA1PSKAKMBIT   0x04
+#define WPA2PSKAKMBIT   0x08
+#define TKIPBIT         0x01
+#define CCMPBIT         0x02
+
+
+#define RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx) \
+    RT28xxUsbStaAsicForceWakeup(pAd, bFromTx);
+
+#define RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \
+    RT28xxUsbStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
+
+#define RT28XX_MLME_RADIO_ON(pAd) \
+    RT28xxUsbMlmeRadioOn(pAd);
+
+#define RT28XX_MLME_RADIO_OFF(pAd) \
+    RT28xxUsbMlmeRadioOFF(pAd);
+
+#endif //__RT2870_H__
diff --git a/drivers/staging/rt3070/rt28xx.h b/drivers/staging/rt3070/rt28xx.h
new file mode 100644
index 0000000..b637c4e
--- /dev/null
+++ b/drivers/staging/rt3070/rt28xx.h
@@ -0,0 +1,2725 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	rt28xx.h
+
+	Abstract:
+	RT28xx ASIC related definition & structures
+
+	Revision History:
+	Who			When		  What
+	--------	----------	  ----------------------------------------------
+       Jan Lee           Jan-3-2006     created for RT2860c
+*/
+
+#ifndef	__RT28XX_H__
+#define	__RT28XX_H__
+
+
+//
+// PCI registers - base address 0x0000
+//
+#define PCI_CFG			0x0000
+#define PCI_EECTRL			0x0004
+#define PCI_MCUCTRL			0x0008
+
+#define	OPT_14			0x114
+
+typedef int				NTSTATUS;
+#define	RETRY_LIMIT             10
+#define STATUS_SUCCESS				0x00
+#define STATUS_UNSUCCESSFUL 		0x01
+
+//
+// SCH/DMA registers - base address 0x0200
+//
+// INT_SOURCE_CSR: Interrupt source register. Write one to clear corresponding bit
+//
+#define DMA_CSR0      0x200
+#define INT_SOURCE_CSR      0x200
+#ifdef RT_BIG_ENDIAN
+typedef	union	_INT_SOURCE_CSR_STRUC	{
+	struct	{
+		UINT32       	:14;
+		UINT32       	TxCoherent:1;
+		UINT32       	RxCoherent:1;
+		UINT32       	GPTimer:1;
+		UINT32       	AutoWakeup:1;//bit14
+		UINT32       	TXFifoStatusInt:1;//FIFO Statistics is full, sw should read 0x171c
+		UINT32       	PreTBTT:1;
+		UINT32       	TBTTInt:1;
+		UINT32       	RxTxCoherent:1;
+		UINT32       	MCUCommandINT:1;
+		UINT32       	MgmtDmaDone:1;
+		UINT32       	HccaDmaDone:1;
+		UINT32       	Ac3DmaDone:1;
+		UINT32       	Ac2DmaDone:1;
+		UINT32       	Ac1DmaDone:1;
+		UINT32		Ac0DmaDone:1;
+		UINT32		RxDone:1;
+		UINT32		TxDelayINT:1;	//delayed interrupt, not interrupt until several int or time limit hit
+		UINT32		RxDelayINT:1; //dealyed interrupt
+	}	field;
+	UINT32			word;
+}	INT_SOURCE_CSR_STRUC, *PINT_SOURCE_CSR_STRUC;
+#else
+typedef	union	_INT_SOURCE_CSR_STRUC	{
+	struct	{
+		UINT32		RxDelayINT:1;
+		UINT32		TxDelayINT:1;
+		UINT32		RxDone:1;
+		UINT32		Ac0DmaDone:1;//4
+		UINT32       	Ac1DmaDone:1;
+		UINT32       	Ac2DmaDone:1;
+		UINT32       	Ac3DmaDone:1;
+		UINT32       	HccaDmaDone:1; // bit7
+		UINT32       	MgmtDmaDone:1;
+		UINT32       	MCUCommandINT:1;//bit 9
+		UINT32       	RxTxCoherent:1;
+		UINT32       	TBTTInt:1;
+		UINT32       	PreTBTT:1;
+		UINT32       	TXFifoStatusInt:1;//FIFO Statistics is full, sw should read 0x171c
+		UINT32       	AutoWakeup:1;//bit14
+		UINT32       	GPTimer:1;
+		UINT32       	RxCoherent:1;//bit16
+		UINT32       	TxCoherent:1;
+		UINT32       	:14;
+	}	field;
+	UINT32			word;
+} INT_SOURCE_CSR_STRUC, *PINT_SOURCE_CSR_STRUC;
+#endif
+
+//
+// INT_MASK_CSR:   Interrupt MASK register.   1: the interrupt is mask OFF
+//
+#define INT_MASK_CSR        0x204
+#ifdef RT_BIG_ENDIAN
+typedef	union	_INT_MASK_CSR_STRUC	{
+	struct	{
+		UINT32       	TxCoherent:1;
+		UINT32       	RxCoherent:1;
+		UINT32       	:20;
+		UINT32       	MCUCommandINT:1;
+		UINT32       	MgmtDmaDone:1;
+		UINT32       	HccaDmaDone:1;
+		UINT32       	Ac3DmaDone:1;
+		UINT32       	Ac2DmaDone:1;
+		UINT32       	Ac1DmaDone:1;
+		UINT32		Ac0DmaDone:1;
+		UINT32		RxDone:1;
+		UINT32		TxDelay:1;
+		UINT32		RXDelay_INT_MSK:1;
+	}	field;
+	UINT32			word;
+}INT_MASK_CSR_STRUC, *PINT_MASK_CSR_STRUC;
+#else
+typedef	union	_INT_MASK_CSR_STRUC	{
+	struct	{
+		UINT32		RXDelay_INT_MSK:1;
+		UINT32		TxDelay:1;
+		UINT32		RxDone:1;
+		UINT32		Ac0DmaDone:1;
+		UINT32       	Ac1DmaDone:1;
+		UINT32       	Ac2DmaDone:1;
+		UINT32       	Ac3DmaDone:1;
+		UINT32       	HccaDmaDone:1;
+		UINT32       	MgmtDmaDone:1;
+		UINT32       	MCUCommandINT:1;
+		UINT32       	:20;
+		UINT32       	RxCoherent:1;
+		UINT32       	TxCoherent:1;
+	}	field;
+	UINT32			word;
+} INT_MASK_CSR_STRUC, *PINT_MASK_CSR_STRUC;
+#endif
+#define WPDMA_GLO_CFG 	0x208
+#ifdef RT_BIG_ENDIAN
+typedef	union	_WPDMA_GLO_CFG_STRUC	{
+	struct	{
+		UINT32       	HDR_SEG_LEN:16;
+		UINT32       	RXHdrScater:8;
+		UINT32       	BigEndian:1;
+		UINT32       	EnTXWriteBackDDONE:1;
+		UINT32       	WPDMABurstSIZE:2;
+		UINT32		RxDMABusy:1;
+		UINT32		EnableRxDMA:1;
+		UINT32		TxDMABusy:1;
+		UINT32		EnableTxDMA:1;
+	}	field;
+	UINT32			word;
+}WPDMA_GLO_CFG_STRUC, *PWPDMA_GLO_CFG_STRUC;
+#else
+typedef	union	_WPDMA_GLO_CFG_STRUC	{
+	struct	{
+		UINT32		EnableTxDMA:1;
+		UINT32		TxDMABusy:1;
+		UINT32		EnableRxDMA:1;
+		UINT32		RxDMABusy:1;
+		UINT32       	WPDMABurstSIZE:2;
+		UINT32       	EnTXWriteBackDDONE:1;
+		UINT32       	BigEndian:1;
+		UINT32       	RXHdrScater:8;
+		UINT32       	HDR_SEG_LEN:16;
+	}	field;
+	UINT32			word;
+} WPDMA_GLO_CFG_STRUC, *PWPDMA_GLO_CFG_STRUC;
+#endif
+#define WPDMA_RST_IDX 	0x20c
+#ifdef RT_BIG_ENDIAN
+typedef	union	_WPDMA_RST_IDX_STRUC	{
+	struct	{
+		UINT32       	:15;
+		UINT32       	RST_DRX_IDX0:1;
+		UINT32       	rsv:10;
+		UINT32       	RST_DTX_IDX5:1;
+		UINT32       	RST_DTX_IDX4:1;
+		UINT32		RST_DTX_IDX3:1;
+		UINT32		RST_DTX_IDX2:1;
+		UINT32		RST_DTX_IDX1:1;
+		UINT32		RST_DTX_IDX0:1;
+	}	field;
+	UINT32			word;
+}WPDMA_RST_IDX_STRUC, *PWPDMA_RST_IDX_STRUC;
+#else
+typedef	union	_WPDMA_RST_IDX_STRUC	{
+	struct	{
+		UINT32		RST_DTX_IDX0:1;
+		UINT32		RST_DTX_IDX1:1;
+		UINT32		RST_DTX_IDX2:1;
+		UINT32		RST_DTX_IDX3:1;
+		UINT32       	RST_DTX_IDX4:1;
+		UINT32       	RST_DTX_IDX5:1;
+		UINT32       	rsv:10;
+		UINT32       	RST_DRX_IDX0:1;
+		UINT32       	:15;
+	}	field;
+	UINT32			word;
+} WPDMA_RST_IDX_STRUC, *PWPDMA_RST_IDX_STRUC;
+#endif
+#define DELAY_INT_CFG  0x0210
+#ifdef RT_BIG_ENDIAN
+typedef	union	_DELAY_INT_CFG_STRUC	{
+	struct	{
+		UINT32       	TXDLY_INT_EN:1;
+		UINT32       	TXMAX_PINT:7;
+		UINT32       	TXMAX_PTIME:8;
+		UINT32       	RXDLY_INT_EN:1;
+		UINT32       	RXMAX_PINT:7;
+		UINT32		RXMAX_PTIME:8;
+	}	field;
+	UINT32			word;
+}DELAY_INT_CFG_STRUC, *PDELAY_INT_CFG_STRUC;
+#else
+typedef	union	_DELAY_INT_CFG_STRUC	{
+	struct	{
+		UINT32		RXMAX_PTIME:8;
+		UINT32       	RXMAX_PINT:7;
+		UINT32       	RXDLY_INT_EN:1;
+		UINT32       	TXMAX_PTIME:8;
+		UINT32       	TXMAX_PINT:7;
+		UINT32       	TXDLY_INT_EN:1;
+	}	field;
+	UINT32			word;
+} DELAY_INT_CFG_STRUC, *PDELAY_INT_CFG_STRUC;
+#endif
+#define WMM_AIFSN_CFG   0x0214
+#ifdef RT_BIG_ENDIAN
+typedef	union	_AIFSN_CSR_STRUC	{
+	struct	{
+	    UINT32   Rsv:16;
+	    UINT32   Aifsn3:4;       // for AC_VO
+	    UINT32   Aifsn2:4;       // for AC_VI
+	    UINT32   Aifsn1:4;       // for AC_BK
+	    UINT32   Aifsn0:4;       // for AC_BE
+	}	field;
+	UINT32			word;
+}	AIFSN_CSR_STRUC, *PAIFSN_CSR_STRUC;
+#else
+typedef	union	_AIFSN_CSR_STRUC	{
+	struct	{
+	    UINT32   Aifsn0:4;       // for AC_BE
+	    UINT32   Aifsn1:4;       // for AC_BK
+	    UINT32   Aifsn2:4;       // for AC_VI
+	    UINT32   Aifsn3:4;       // for AC_VO
+	    UINT32   Rsv:16;
+	}	field;
+	UINT32			word;
+}	AIFSN_CSR_STRUC, *PAIFSN_CSR_STRUC;
+#endif
+//
+// CWMIN_CSR: CWmin for each EDCA AC
+//
+#define WMM_CWMIN_CFG   0x0218
+#ifdef RT_BIG_ENDIAN
+typedef	union	_CWMIN_CSR_STRUC	{
+	struct	{
+	    UINT32   Rsv:16;
+	    UINT32   Cwmin3:4;       // for AC_VO
+	    UINT32   Cwmin2:4;       // for AC_VI
+	    UINT32   Cwmin1:4;       // for AC_BK
+	    UINT32   Cwmin0:4;       // for AC_BE
+	}	field;
+	UINT32			word;
+}	CWMIN_CSR_STRUC, *PCWMIN_CSR_STRUC;
+#else
+typedef	union	_CWMIN_CSR_STRUC	{
+	struct	{
+	    UINT32   Cwmin0:4;       // for AC_BE
+	    UINT32   Cwmin1:4;       // for AC_BK
+	    UINT32   Cwmin2:4;       // for AC_VI
+	    UINT32   Cwmin3:4;       // for AC_VO
+	    UINT32   Rsv:16;
+	}	field;
+	UINT32			word;
+}	CWMIN_CSR_STRUC, *PCWMIN_CSR_STRUC;
+#endif
+
+//
+// CWMAX_CSR: CWmin for each EDCA AC
+//
+#define WMM_CWMAX_CFG   0x021c
+#ifdef RT_BIG_ENDIAN
+typedef	union	_CWMAX_CSR_STRUC	{
+	struct	{
+	    UINT32   Rsv:16;
+	    UINT32   Cwmax3:4;       // for AC_VO
+	    UINT32   Cwmax2:4;       // for AC_VI
+	    UINT32   Cwmax1:4;       // for AC_BK
+	    UINT32   Cwmax0:4;       // for AC_BE
+	}	field;
+	UINT32			word;
+}	CWMAX_CSR_STRUC, *PCWMAX_CSR_STRUC;
+#else
+typedef	union	_CWMAX_CSR_STRUC	{
+	struct	{
+	    UINT32   Cwmax0:4;       // for AC_BE
+	    UINT32   Cwmax1:4;       // for AC_BK
+	    UINT32   Cwmax2:4;       // for AC_VI
+	    UINT32   Cwmax3:4;       // for AC_VO
+	    UINT32   Rsv:16;
+	}	field;
+	UINT32			word;
+}	CWMAX_CSR_STRUC, *PCWMAX_CSR_STRUC;
+#endif
+
+
+//
+// AC_TXOP_CSR0: AC_BK/AC_BE TXOP register
+//
+#define WMM_TXOP0_CFG    0x0220
+#ifdef RT_BIG_ENDIAN
+typedef	union	_AC_TXOP_CSR0_STRUC	{
+	struct	{
+	    USHORT  Ac1Txop;        // for AC_BE, in unit of 32us
+	    USHORT  Ac0Txop;        // for AC_BK, in unit of 32us
+	}	field;
+	UINT32			word;
+}	AC_TXOP_CSR0_STRUC, *PAC_TXOP_CSR0_STRUC;
+#else
+typedef	union	_AC_TXOP_CSR0_STRUC	{
+	struct	{
+	    USHORT  Ac0Txop;        // for AC_BK, in unit of 32us
+	    USHORT  Ac1Txop;        // for AC_BE, in unit of 32us
+	}	field;
+	UINT32			word;
+}	AC_TXOP_CSR0_STRUC, *PAC_TXOP_CSR0_STRUC;
+#endif
+
+//
+// AC_TXOP_CSR1: AC_VO/AC_VI TXOP register
+//
+#define WMM_TXOP1_CFG    0x0224
+#ifdef RT_BIG_ENDIAN
+typedef	union	_AC_TXOP_CSR1_STRUC	{
+	struct	{
+	    USHORT  Ac3Txop;        // for AC_VO, in unit of 32us
+	    USHORT  Ac2Txop;        // for AC_VI, in unit of 32us
+	}	field;
+	UINT32			word;
+}	AC_TXOP_CSR1_STRUC, *PAC_TXOP_CSR1_STRUC;
+#else
+typedef	union	_AC_TXOP_CSR1_STRUC	{
+	struct	{
+	    USHORT  Ac2Txop;        // for AC_VI, in unit of 32us
+	    USHORT  Ac3Txop;        // for AC_VO, in unit of 32us
+	}	field;
+	UINT32			word;
+}	AC_TXOP_CSR1_STRUC, *PAC_TXOP_CSR1_STRUC;
+#endif
+#define RINGREG_DIFF			0x10
+#define GPIO_CTRL_CFG    0x0228	//MAC_CSR13
+#define MCU_CMD_CFG    0x022c
+#define TX_BASE_PTR0     0x0230	//AC_BK base address
+#define TX_MAX_CNT0      0x0234
+#define TX_CTX_IDX0       0x0238
+#define TX_DTX_IDX0      0x023c
+#define TX_BASE_PTR1     0x0240 	//AC_BE base address
+#define TX_MAX_CNT1      0x0244
+#define TX_CTX_IDX1       0x0248
+#define TX_DTX_IDX1      0x024c
+#define TX_BASE_PTR2     0x0250 	//AC_VI base address
+#define TX_MAX_CNT2      0x0254
+#define TX_CTX_IDX2       0x0258
+#define TX_DTX_IDX2      0x025c
+#define TX_BASE_PTR3     0x0260 	//AC_VO base address
+#define TX_MAX_CNT3      0x0264
+#define TX_CTX_IDX3       0x0268
+#define TX_DTX_IDX3      0x026c
+#define TX_BASE_PTR4     0x0270 	//HCCA base address
+#define TX_MAX_CNT4      0x0274
+#define TX_CTX_IDX4       0x0278
+#define TX_DTX_IDX4      0x027c
+#define TX_BASE_PTR5     0x0280 	//MGMT base address
+#define  TX_MAX_CNT5     0x0284
+#define TX_CTX_IDX5       0x0288
+#define TX_DTX_IDX5      0x028c
+#define TX_MGMTMAX_CNT      TX_MAX_CNT5
+#define TX_MGMTCTX_IDX       TX_CTX_IDX5
+#define TX_MGMTDTX_IDX      TX_DTX_IDX5
+#define RX_BASE_PTR     0x0290 	//RX base address
+#define RX_MAX_CNT      0x0294
+#define RX_CRX_IDX       0x0298
+#define RX_DRX_IDX      0x029c
+#define USB_DMA_CFG      0x02a0
+#ifdef RT_BIG_ENDIAN
+typedef	union	_USB_DMA_CFG_STRUC	{
+	struct	{
+	    UINT32  TxBusy:1;   	//USB DMA TX FSM busy . debug only
+	    UINT32  RxBusy:1;        //USB DMA RX FSM busy . debug only
+	    UINT32  EpoutValid:6;        //OUT endpoint data valid. debug only
+	    UINT32  TxBulkEn:1;        //Enable USB DMA Tx
+	    UINT32  RxBulkEn:1;        //Enable USB DMA Rx
+	    UINT32  RxBulkAggEn:1;        //Enable Rx Bulk Aggregation
+	    UINT32  TxopHalt:1;        //Halt TXOP count down when TX buffer is full.
+	    UINT32  TxClear:1;        //Clear USB DMA TX path
+	    UINT32  rsv:2;
+	    UINT32  phyclear:1;        		//phy watch dog enable. write 1
+	    UINT32  RxBulkAggLmt:8;        //Rx Bulk Aggregation Limit  in unit of 1024 bytes
+	    UINT32  RxBulkAggTOut:8;        //Rx Bulk Aggregation TimeOut  in unit of 33ns
+	}	field;
+	UINT32			word;
+}	USB_DMA_CFG_STRUC, *PUSB_DMA_CFG_STRUC;
+#else
+typedef	union	_USB_DMA_CFG_STRUC	{
+	struct	{
+	    UINT32  RxBulkAggTOut:8;        //Rx Bulk Aggregation TimeOut  in unit of 33ns
+	    UINT32  RxBulkAggLmt:8;        //Rx Bulk Aggregation Limit  in unit of 256 bytes
+	    UINT32  phyclear:1;        		//phy watch dog enable. write 1
+	    UINT32  rsv:2;
+	    UINT32  TxClear:1;        //Clear USB DMA TX path
+	    UINT32  TxopHalt:1;        //Halt TXOP count down when TX buffer is full.
+	    UINT32  RxBulkAggEn:1;        //Enable Rx Bulk Aggregation
+	    UINT32  RxBulkEn:1;        //Enable USB DMA Rx
+	    UINT32  TxBulkEn:1;        //Enable USB DMA Tx
+	    UINT32  EpoutValid:6;        //OUT endpoint data valid
+	    UINT32  RxBusy:1;        //USB DMA RX FSM busy
+	    UINT32  TxBusy:1;   	//USB DMA TX FSM busy
+	}	field;
+	UINT32			word;
+}	USB_DMA_CFG_STRUC, *PUSB_DMA_CFG_STRUC;
+#endif
+
+//
+//  3  PBF  registers
+//
+//
+// Most are for debug. Driver doesn't touch PBF register.
+#define 	PBF_SYS_CTRL 	 0x0400
+#define     PBF_CFG                 0x0408
+#define 	PBF_MAX_PCNT 	 0x040C
+#define 	PBF_CTRL	 	0x0410
+#define 	PBF_INT_STA	 0x0414
+#define 	PBF_INT_ENA	 0x0418
+#define 	TXRXQ_PCNT  	 0x0438
+#define 	PBF_DBG 	 	 0x043c
+#define     PBF_CAP_CTRL     0x0440
+
+
+// eFuse registers
+#define EFUSE_CTRL              0x0580
+#define EFUSE_DATA0             0x0590
+#define EFUSE_DATA1             0x0594
+#define EFUSE_DATA2             0x0598
+#define EFUSE_DATA3             0x059c
+#define EFUSE_USAGE_MAP_START   0x2d0
+#define EFUSE_USAGE_MAP_END     0x2fc
+#define EFUSE_TAG               0x2fe
+#define EFUSE_USAGE_MAP_SIZE    45
+
+#ifdef RT_BIG_ENDIAN
+typedef	union	_EFUSE_CTRL_STRUC {
+	struct	{
+		UINT32            SEL_EFUSE:1;
+		UINT32            EFSROM_KICK:1;
+		UINT32            RESERVED:4;
+		UINT32            EFSROM_AIN:10;
+		UINT32            EFSROM_LDO_ON_TIME:2;
+		UINT32            EFSROM_LDO_OFF_TIME:6;
+		UINT32            EFSROM_MODE:2;
+		UINT32            EFSROM_AOUT:6;
+	}	field;
+	UINT32			word;
+}	EFUSE_CTRL_STRUC, *PEFUSE_CTRL_STRUC;
+#else
+typedef	union	_EFUSE_CTRL_STRUC {
+	struct	{
+		UINT32            EFSROM_AOUT:6;
+		UINT32            EFSROM_MODE:2;
+		UINT32            EFSROM_LDO_OFF_TIME:6;
+		UINT32            EFSROM_LDO_ON_TIME:2;
+		UINT32            EFSROM_AIN:10;
+		UINT32            RESERVED:4;
+		UINT32            EFSROM_KICK:1;
+		UINT32            SEL_EFUSE:1;
+	}	field;
+	UINT32			word;
+}	EFUSE_CTRL_STRUC, *PEFUSE_CTRL_STRUC;
+#endif // RT_BIG_ENDIAN //
+
+#define LDO_CFG0 				0x05d4
+#define GPIO_SWITCH				0x05dc
+
+//
+//  4  MAC  registers
+//
+//
+//  4.1 MAC SYSTEM  configuration registers (offset:0x1000)
+//
+#define MAC_CSR0            0x1000
+#ifdef RT_BIG_ENDIAN
+typedef	union	_ASIC_VER_ID_STRUC	{
+	struct	{
+	    USHORT  ASICVer;        // version : 2860
+	    USHORT  ASICRev;        // reversion  : 0
+	}	field;
+	UINT32			word;
+}	ASIC_VER_ID_STRUC, *PASIC_VER_ID_STRUC;
+#else
+typedef	union	_ASIC_VER_ID_STRUC	{
+	struct	{
+	    USHORT  ASICRev;        // reversion  : 0
+	    USHORT  ASICVer;        // version : 2860
+	}	field;
+	UINT32			word;
+}	ASIC_VER_ID_STRUC, *PASIC_VER_ID_STRUC;
+#endif
+#define MAC_SYS_CTRL            0x1004		//MAC_CSR1
+#define MAC_ADDR_DW0            		0x1008		// MAC ADDR DW0
+#define MAC_ADDR_DW1           		 0x100c		// MAC ADDR DW1
+//
+// MAC_CSR2: STA MAC register 0
+//
+#ifdef RT_BIG_ENDIAN
+typedef	union	_MAC_DW0_STRUC	{
+	struct	{
+		UCHAR		Byte3;		// MAC address byte 3
+		UCHAR		Byte2;		// MAC address byte 2
+		UCHAR		Byte1;		// MAC address byte 1
+		UCHAR		Byte0;		// MAC address byte 0
+	}	field;
+	UINT32			word;
+}	MAC_DW0_STRUC, *PMAC_DW0_STRUC;
+#else
+typedef	union	_MAC_DW0_STRUC	{
+	struct	{
+		UCHAR		Byte0;		// MAC address byte 0
+		UCHAR		Byte1;		// MAC address byte 1
+		UCHAR		Byte2;		// MAC address byte 2
+		UCHAR		Byte3;		// MAC address byte 3
+	}	field;
+	UINT32			word;
+}	MAC_DW0_STRUC, *PMAC_DW0_STRUC;
+#endif
+
+//
+// MAC_CSR3: STA MAC register 1
+//
+#ifdef RT_BIG_ENDIAN
+typedef	union	_MAC_DW1_STRUC	{
+	struct	{
+		UCHAR		Rsvd1;
+		UCHAR		U2MeMask;
+		UCHAR		Byte5;		// MAC address byte 5
+		UCHAR		Byte4;		// MAC address byte 4
+	}	field;
+	UINT32			word;
+}	MAC_DW1_STRUC, *PMAC_DW1_STRUC;
+#else
+typedef	union	_MAC_DW1_STRUC	{
+	struct	{
+		UCHAR		Byte4;		// MAC address byte 4
+		UCHAR		Byte5;		// MAC address byte 5
+		UCHAR		U2MeMask;
+		UCHAR		Rsvd1;
+	}	field;
+	UINT32			word;
+}	MAC_DW1_STRUC, *PMAC_DW1_STRUC;
+#endif
+
+#define MAC_BSSID_DW0            		0x1010		// MAC BSSID DW0
+#define MAC_BSSID_DW1            		0x1014		// MAC BSSID DW1
+
+//
+// MAC_CSR5: BSSID register 1
+//
+#ifdef RT_BIG_ENDIAN
+typedef	union	_MAC_CSR5_STRUC	{
+	struct	{
+		USHORT		Rsvd:11;
+		USHORT		MBssBcnNum:3;
+		USHORT		BssIdMode:2; // 0: one BSSID, 10: 4 BSSID,  01: 2 BSSID , 11: 8BSSID
+		UCHAR		Byte5;		 // BSSID byte 5
+		UCHAR		Byte4;		 // BSSID byte 4
+	}	field;
+	UINT32			word;
+}	MAC_CSR5_STRUC, *PMAC_CSR5_STRUC;
+#else
+typedef	union	_MAC_CSR5_STRUC	{
+	struct	{
+		UCHAR		Byte4;		 // BSSID byte 4
+		UCHAR		Byte5;		 // BSSID byte 5
+		USHORT      	BssIdMask:2; // 0: one BSSID, 10: 4 BSSID,  01: 2 BSSID , 11: 8BSSID
+		USHORT		MBssBcnNum:3;
+		USHORT		Rsvd:11;
+	}	field;
+	UINT32			word;
+}	MAC_CSR5_STRUC, *PMAC_CSR5_STRUC;
+#endif
+
+#define MAX_LEN_CFG              0x1018		// rt2860b max 16k bytes. bit12:13 Maximum PSDU length (power factor) 0:2^13, 1:2^14, 2:2^15, 3:2^16
+#define BBP_CSR_CFG            		0x101c		//
+//
+// BBP_CSR_CFG: BBP serial control register
+//
+#ifdef RT_BIG_ENDIAN
+typedef	union	_BBP_CSR_CFG_STRUC	{
+	struct	{
+		UINT32		:12;
+		UINT32		BBP_RW_MODE:1;		// 0: use serial mode  1:parallel
+		UINT32		BBP_PAR_DUR:1;		    // 0: 4 MAC clock cycles  1: 8 MAC clock cycles
+		UINT32		Busy:1;				// 1: ASIC is busy execute BBP programming.
+		UINT32		fRead:1;		    // 0: Write	BBP, 1:	Read BBP
+		UINT32		RegNum:8;			// Selected	BBP	register
+		UINT32		Value:8;			// Register	value to program into BBP
+	}	field;
+	UINT32			word;
+}	BBP_CSR_CFG_STRUC, *PBBP_CSR_CFG_STRUC;
+#else
+typedef	union	_BBP_CSR_CFG_STRUC	{
+	struct	{
+		UINT32		Value:8;			// Register	value to program into BBP
+		UINT32		RegNum:8;			// Selected	BBP	register
+		UINT32		fRead:1;		    // 0: Write	BBP, 1:	Read BBP
+		UINT32		Busy:1;				// 1: ASIC is busy execute BBP programming.
+		UINT32		BBP_PAR_DUR:1;		     // 0: 4 MAC clock cycles  1: 8 MAC clock cycles
+		UINT32		BBP_RW_MODE:1;		// 0: use serial mode  1:parallel
+		UINT32		:12;
+	}	field;
+	UINT32			word;
+}	BBP_CSR_CFG_STRUC, *PBBP_CSR_CFG_STRUC;
+#endif
+#define RF_CSR_CFG0            		0x1020
+//
+// RF_CSR_CFG: RF control register
+//
+#ifdef RT_BIG_ENDIAN
+typedef	union	_RF_CSR_CFG0_STRUC	{
+	struct	{
+		UINT32		Busy:1;		    // 0: idle 1: 8busy
+		UINT32		Sel:1;				// 0:RF_LE0 activate  1:RF_LE1 activate
+		UINT32		StandbyMode:1;		    // 0: high when stand by 1:	low when standby
+		UINT32		bitwidth:5;			// Selected	BBP	register
+		UINT32		RegIdAndContent:24;			// Register	value to program into BBP
+	}	field;
+	UINT32			word;
+}	RF_CSR_CFG0_STRUC, *PRF_CSR_CFG0_STRUC;
+#else
+typedef	union	_RF_CSR_CFG0_STRUC	{
+	struct	{
+		UINT32		RegIdAndContent:24;			// Register	value to program into BBP
+		UINT32		bitwidth:5;			// Selected	BBP	register
+		UINT32		StandbyMode:1;		    // 0: high when stand by 1:	low when standby
+		UINT32		Sel:1;				// 0:RF_LE0 activate  1:RF_LE1 activate
+		UINT32		Busy:1;		    // 0: idle 1: 8busy
+	}	field;
+	UINT32			word;
+}	RF_CSR_CFG0_STRUC, *PRF_CSR_CFG0_STRUC;
+#endif
+#define RF_CSR_CFG1           		0x1024
+#ifdef RT_BIG_ENDIAN
+typedef	union	_RF_CSR_CFG1_STRUC	{
+	struct	{
+		UINT32		rsv:7;		    // 0: idle 1: 8busy
+		UINT32		RFGap:5;			// Gap between BB_CONTROL_RF and RF_LE. 0: 3 system clock cycle (37.5usec) 1: 5 system clock cycle (62.5usec)
+		UINT32		RegIdAndContent:24;			// Register	value to program into BBP
+	}	field;
+	UINT32			word;
+}	RF_CSR_CFG1_STRUC, *PRF_CSR_CFG1_STRUC;
+#else
+typedef	union	_RF_CSR_CFG1_STRUC	{
+	struct	{
+		UINT32		RegIdAndContent:24;			// Register	value to program into BBP
+		UINT32		RFGap:5;			// Gap between BB_CONTROL_RF and RF_LE. 0: 3 system clock cycle (37.5usec) 1: 5 system clock cycle (62.5usec)
+		UINT32		rsv:7;		    // 0: idle 1: 8busy
+	}	field;
+	UINT32			word;
+}	RF_CSR_CFG1_STRUC, *PRF_CSR_CFG1_STRUC;
+#endif
+#define RF_CSR_CFG2           		0x1028		//
+#ifdef RT_BIG_ENDIAN
+typedef	union	_RF_CSR_CFG2_STRUC	{
+	struct	{
+		UINT32		rsv:8;		    // 0: idle 1: 8busy
+		UINT32		RegIdAndContent:24;			// Register	value to program into BBP
+	}	field;
+	UINT32			word;
+}	RF_CSR_CFG2_STRUC, *PRF_CSR_CFG2_STRUC;
+#else
+typedef	union	_RF_CSR_CFG2_STRUC	{
+	struct	{
+		UINT32		RegIdAndContent:24;			// Register	value to program into BBP
+		UINT32		rsv:8;		    // 0: idle 1: 8busy
+	}	field;
+	UINT32			word;
+}	RF_CSR_CFG2_STRUC, *PRF_CSR_CFG2_STRUC;
+#endif
+#define LED_CFG           		0x102c		//  MAC_CSR14
+#ifdef RT_BIG_ENDIAN
+typedef	union	_LED_CFG_STRUC	{
+	struct	{
+		UINT32		:1;
+		UINT32		LedPolar:1;			// Led Polarity.  0: active low1: active high
+		UINT32		YLedMode:2;			// yellow Led Mode
+		UINT32		GLedMode:2;			// green Led Mode
+		UINT32		RLedMode:2;			// red Led Mode    0: off1: blinking upon TX2: periodic slow blinking3: always on
+		UINT32		rsv:2;
+		UINT32		SlowBlinkPeriod:6;			// slow blinking period. unit:1ms
+		UINT32		OffPeriod:8;			// blinking off period unit 1ms
+		UINT32		OnPeriod:8;			// blinking on period unit 1ms
+	}	field;
+	UINT32			word;
+}	LED_CFG_STRUC, *PLED_CFG_STRUC;
+#else
+typedef	union	_LED_CFG_STRUC	{
+	struct	{
+		UINT32		OnPeriod:8;			// blinking on period unit 1ms
+		UINT32		OffPeriod:8;			// blinking off period unit 1ms
+		UINT32		SlowBlinkPeriod:6;			// slow blinking period. unit:1ms
+		UINT32		rsv:2;
+		UINT32		RLedMode:2;			// red Led Mode    0: off1: blinking upon TX2: periodic slow blinking3: always on
+		UINT32		GLedMode:2;			// green Led Mode
+		UINT32		YLedMode:2;			// yellow Led Mode
+		UINT32		LedPolar:1;			// Led Polarity.  0: active low1: active high
+		UINT32		:1;
+	}	field;
+	UINT32			word;
+}	LED_CFG_STRUC, *PLED_CFG_STRUC;
+#endif
+//
+//  4.2 MAC TIMING  configuration registers (offset:0x1100)
+//
+#define XIFS_TIME_CFG             0x1100		 // MAC_CSR8  MAC_CSR9
+#ifdef RT_BIG_ENDIAN
+typedef	union	_IFS_SLOT_CFG_STRUC	{
+	struct	{
+	    UINT32  rsv:2;
+	    UINT32  BBRxendEnable:1;        //  reference RXEND signal to begin XIFS defer
+	    UINT32  EIFS:9;        //  unit 1us
+	    UINT32  OfdmXifsTime:4;        //OFDM SIFS. unit 1us. Applied after OFDM RX when MAC doesn't reference BBP signal BBRXEND
+	    UINT32  OfdmSifsTime:8;        //  unit 1us. Applied after OFDM RX/TX
+	    UINT32  CckmSifsTime:8;        //  unit 1us. Applied after CCK RX/TX
+	}	field;
+	UINT32			word;
+}	IFS_SLOT_CFG_STRUC, *PIFS_SLOT_CFG_STRUC;
+#else
+typedef	union	_IFS_SLOT_CFG_STRUC	{
+	struct	{
+	    UINT32  CckmSifsTime:8;        //  unit 1us. Applied after CCK RX/TX
+	    UINT32  OfdmSifsTime:8;        //  unit 1us. Applied after OFDM RX/TX
+	    UINT32  OfdmXifsTime:4;        //OFDM SIFS. unit 1us. Applied after OFDM RX when MAC doesn't reference BBP signal BBRXEND
+	    UINT32  EIFS:9;        //  unit 1us
+	    UINT32  BBRxendEnable:1;        //  reference RXEND signal to begin XIFS defer
+	    UINT32  rsv:2;
+	}	field;
+	UINT32			word;
+}	IFS_SLOT_CFG_STRUC, *PIFS_SLOT_CFG_STRUC;
+#endif
+
+#define BKOFF_SLOT_CFG             0x1104		 //  mac_csr9 last 8 bits
+#define NAV_TIME_CFG             0x1108		 // NAV  (MAC_CSR15)
+#define CH_TIME_CFG             0x110C		 	// Count as channel busy
+#define PBF_LIFE_TIMER             0x1110		 //TX/RX MPDU timestamp timer (free run)Unit: 1us
+#define BCN_TIME_CFG             0x1114		 // TXRX_CSR9
+
+#define BCN_OFFSET0				0x042C
+#define BCN_OFFSET1				0x0430
+
+//
+// BCN_TIME_CFG : Synchronization control register
+//
+#ifdef RT_BIG_ENDIAN
+typedef	union	_BCN_TIME_CFG_STRUC	{
+	struct	{
+		UINT32		TxTimestampCompensate:8;
+        UINT32       :3;
+		UINT32		bBeaconGen:1;		// Enable beacon generator
+        UINT32       bTBTTEnable:1;
+		UINT32		TsfSyncMode:2;		// Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode
+		UINT32		bTsfTicking:1;		// Enable TSF auto counting
+		UINT32       BeaconInterval:16;  // in unit of 1/16 TU
+	}	field;
+	UINT32			word;
+}	BCN_TIME_CFG_STRUC, *PBCN_TIME_CFG_STRUC;
+#else
+typedef	union	_BCN_TIME_CFG_STRUC	{
+	struct	{
+		UINT32       BeaconInterval:16;  // in unit of 1/16 TU
+		UINT32		bTsfTicking:1;		// Enable TSF auto counting
+		UINT32		TsfSyncMode:2;		// Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode
+        UINT32       bTBTTEnable:1;
+		UINT32		bBeaconGen:1;		// Enable beacon generator
+        UINT32       :3;
+		UINT32		TxTimestampCompensate:8;
+	}	field;
+	UINT32			word;
+}	BCN_TIME_CFG_STRUC, *PBCN_TIME_CFG_STRUC;
+#endif
+#define TBTT_SYNC_CFG            0x1118  		// txrx_csr10
+#define TSF_TIMER_DW0             0x111C  		// Local TSF timer lsb 32 bits. Read-only
+#define TSF_TIMER_DW1             0x1120  		// msb 32 bits. Read-only.
+#define TBTT_TIMER             	0x1124  		// TImer remains till next TBTT. Read-only.  TXRX_CSR14
+#define INT_TIMER_CFG              	0x1128  		//
+#define INT_TIMER_EN             	0x112c  		//  GP-timer and pre-tbtt Int enable
+#define CH_IDLE_STA              	0x1130  		//  channel idle time
+#define CH_BUSY_STA              	0x1134  		//  channle busy time
+//
+//  4.2 MAC POWER  configuration registers (offset:0x1200)
+//
+#define MAC_STATUS_CFG             0x1200		 // old MAC_CSR12
+#define PWR_PIN_CFG             0x1204		 // old MAC_CSR12
+#define AUTO_WAKEUP_CFG             0x1208		 // old MAC_CSR10
+//
+// AUTO_WAKEUP_CFG: Manual power control / status register
+//
+#ifdef RT_BIG_ENDIAN
+typedef	union	_AUTO_WAKEUP_STRUC	{
+	struct	{
+		UINT32		:16;
+		UINT32		EnableAutoWakeup:1;	// 0:sleep, 1:awake
+		UINT32       NumofSleepingTbtt:7;          // ForceWake has high privilege than PutToSleep when both set
+		UINT32       AutoLeadTime:8;
+	}	field;
+	UINT32			word;
+}	AUTO_WAKEUP_STRUC, *PAUTO_WAKEUP_STRUC;
+#else
+typedef	union	_AUTO_WAKEUP_STRUC	{
+	struct	{
+		UINT32       AutoLeadTime:8;
+		UINT32       NumofSleepingTbtt:7;          // ForceWake has high privilege than PutToSleep when both set
+		UINT32		EnableAutoWakeup:1;	// 0:sleep, 1:awake
+		UINT32		:16;
+	}	field;
+	UINT32			word;
+}	AUTO_WAKEUP_STRUC, *PAUTO_WAKEUP_STRUC;
+#endif
+//
+//  4.3 MAC TX  configuration registers (offset:0x1300)
+//
+
+#define EDCA_AC0_CFG	0x1300		//AC_TXOP_CSR0 0x3474
+#define EDCA_AC1_CFG	0x1304
+#define EDCA_AC2_CFG	0x1308
+#define EDCA_AC3_CFG	0x130c
+#ifdef RT_BIG_ENDIAN
+typedef	union	_EDCA_AC_CFG_STRUC	{
+	struct	{
+	    UINT32  :12;        //
+	    UINT32  Cwmax:4;        //unit power of 2
+	    UINT32  Cwmin:4;        //
+	    UINT32  Aifsn:4;        // # of slot time
+	    UINT32  AcTxop:8;        //  in unit of 32us
+	}	field;
+	UINT32			word;
+}	EDCA_AC_CFG_STRUC, *PEDCA_AC_CFG_STRUC;
+#else
+typedef	union	_EDCA_AC_CFG_STRUC	{
+	struct	{
+	    UINT32  AcTxop:8;        //  in unit of 32us
+	    UINT32  Aifsn:4;        // # of slot time
+	    UINT32  Cwmin:4;        //
+	    UINT32  Cwmax:4;        //unit power of 2
+	    UINT32  :12;       //
+	}	field;
+	UINT32			word;
+}	EDCA_AC_CFG_STRUC, *PEDCA_AC_CFG_STRUC;
+#endif
+
+#define EDCA_TID_AC_MAP	0x1310
+#define TX_PWR_CFG_0	0x1314
+#define TX_PWR_CFG_1	0x1318
+#define TX_PWR_CFG_2	0x131C
+#define TX_PWR_CFG_3	0x1320
+#define TX_PWR_CFG_4	0x1324
+#define TX_PIN_CFG		0x1328
+#define TX_BAND_CFG	0x132c		// 0x1 use upper 20MHz. 0 juse lower 20MHz
+#define TX_SW_CFG0		0x1330
+#define TX_SW_CFG1		0x1334
+#define TX_SW_CFG2		0x1338
+#define TXOP_THRES_CFG		0x133c
+#define TXOP_CTRL_CFG		0x1340
+#define TX_RTS_CFG		0x1344
+
+#ifdef RT_BIG_ENDIAN
+typedef	union	_TX_RTS_CFG_STRUC	{
+	struct	{
+	    UINT32       rsv:7;
+	    UINT32       RtsFbkEn:1;    // enable rts rate fallback
+	    UINT32       RtsThres:16;    // unit:byte
+	    UINT32       AutoRtsRetryLimit:8;
+	}	field;
+	UINT32			word;
+}	TX_RTS_CFG_STRUC, *PTX_RTS_CFG_STRUC;
+#else
+typedef	union	_TX_RTS_CFG_STRUC	{
+	struct	{
+	    UINT32       AutoRtsRetryLimit:8;
+	    UINT32       RtsThres:16;    // unit:byte
+	    UINT32       RtsFbkEn:1;    // enable rts rate fallback
+	    UINT32       rsv:7;     // 1: HT non-STBC control frame enable
+	}	field;
+	UINT32			word;
+}	TX_RTS_CFG_STRUC, *PTX_RTS_CFG_STRUC;
+#endif
+#define TX_TIMEOUT_CFG	0x1348
+#ifdef RT_BIG_ENDIAN
+typedef	union	_TX_TIMEOUT_CFG_STRUC	{
+	struct	{
+	    UINT32       rsv2:8;
+	    UINT32       TxopTimeout:8;	//TXOP timeout value for TXOP truncation.  It is recommended that (SLOT_TIME) > (TX_OP_TIMEOUT) > (RX_ACK_TIMEOUT)
+	    UINT32       RxAckTimeout:8;	// unit:slot. Used for TX precedure
+	    UINT32       MpduLifeTime:4;    //  expiration time = 2^(9+MPDU LIFE TIME)  us
+	    UINT32       rsv:4;
+	}	field;
+	UINT32			word;
+}	TX_TIMEOUT_CFG_STRUC, *PTX_TIMEOUT_CFG_STRUC;
+#else
+typedef	union	_TX_TIMEOUT_CFG_STRUC	{
+	struct	{
+	    UINT32       rsv:4;
+	    UINT32       MpduLifeTime:4;    //  expiration time = 2^(9+MPDU LIFE TIME)  us
+	    UINT32       RxAckTimeout:8;	// unit:slot. Used for TX precedure
+	    UINT32       TxopTimeout:8;	//TXOP timeout value for TXOP truncation.  It is recommended that (SLOT_TIME) > (TX_OP_TIMEOUT) > (RX_ACK_TIMEOUT)
+	    UINT32       rsv2:8;     // 1: HT non-STBC control frame enable
+	}	field;
+	UINT32			word;
+}	TX_TIMEOUT_CFG_STRUC, *PTX_TIMEOUT_CFG_STRUC;
+#endif
+#define TX_RTY_CFG	0x134c
+#ifdef RT_BIG_ENDIAN
+typedef	union PACKED _TX_RTY_CFG_STRUC	{
+	struct	{
+	    UINT32       rsv:1;
+	    UINT32       TxautoFBEnable:1;    // Tx retry PHY rate auto fallback enable
+	    UINT32       AggRtyMode:1;	// Aggregate MPDU retry mode.  0:expired by retry limit, 1: expired by mpdu life timer
+	    UINT32       NonAggRtyMode:1;	// Non-Aggregate MPDU retry mode.  0:expired by retry limit, 1: expired by mpdu life timer
+	    UINT32       LongRtyThre:12;	// Long retry threshoold
+	    UINT32       LongRtyLimit:8;	//long retry limit
+	    UINT32       ShortRtyLimit:8;	//  short retry limit
+
+	}	field;
+	UINT32			word;
+}	TX_RTY_CFG_STRUC, *PTX_RTY_CFG_STRUC;
+#else
+typedef	union PACKED _TX_RTY_CFG_STRUC	{
+	struct	{
+	    UINT32       ShortRtyLimit:8;	//  short retry limit
+	    UINT32       LongRtyLimit:8;	//long retry limit
+	    UINT32       LongRtyThre:12;	// Long retry threshoold
+	    UINT32       NonAggRtyMode:1;	// Non-Aggregate MPDU retry mode.  0:expired by retry limit, 1: expired by mpdu life timer
+	    UINT32       AggRtyMode:1;	// Aggregate MPDU retry mode.  0:expired by retry limit, 1: expired by mpdu life timer
+	    UINT32       TxautoFBEnable:1;    // Tx retry PHY rate auto fallback enable
+	    UINT32       rsv:1;     // 1: HT non-STBC control frame enable
+	}	field;
+	UINT32			word;
+}	TX_RTY_CFG_STRUC, *PTX_RTY_CFG_STRUC;
+#endif
+#define TX_LINK_CFG	0x1350
+#ifdef RT_BIG_ENDIAN
+typedef	union	PACKED _TX_LINK_CFG_STRUC	{
+	struct PACKED {
+	    UINT32       RemotMFS:8;	//remote MCS feedback sequence number
+	    UINT32       RemotMFB:8;    //  remote MCS feedback
+	    UINT32       rsv:3;	//
+	    UINT32       TxCFAckEn:1;	//   Piggyback CF-ACK enable
+	    UINT32       TxRDGEn:1;	// RDG TX enable
+	    UINT32       TxMRQEn:1;	//  MCS request TX enable
+	    UINT32       RemoteUMFSEnable:1;	//  remote unsolicit  MFB enable.  0: not apply remote remote unsolicit (MFS=7)
+	    UINT32       MFBEnable:1;	//  TX apply remote MFB 1:enable
+	    UINT32       RemoteMFBLifeTime:8;	//remote MFB life time. unit : 32us
+	}	field;
+	UINT32			word;
+}	TX_LINK_CFG_STRUC, *PTX_LINK_CFG_STRUC;
+#else
+typedef	union	PACKED _TX_LINK_CFG_STRUC	{
+	struct PACKED {
+	    UINT32       RemoteMFBLifeTime:8;	//remote MFB life time. unit : 32us
+	    UINT32       MFBEnable:1;	//  TX apply remote MFB 1:enable
+	    UINT32       RemoteUMFSEnable:1;	//  remote unsolicit  MFB enable.  0: not apply remote remote unsolicit (MFS=7)
+	    UINT32       TxMRQEn:1;	//  MCS request TX enable
+	    UINT32       TxRDGEn:1;	// RDG TX enable
+	    UINT32       TxCFAckEn:1;	//   Piggyback CF-ACK enable
+	    UINT32       rsv:3;	//
+	    UINT32       RemotMFB:8;    //  remote MCS feedback
+	    UINT32       RemotMFS:8;	//remote MCS feedback sequence number
+	}	field;
+	UINT32			word;
+}	TX_LINK_CFG_STRUC, *PTX_LINK_CFG_STRUC;
+#endif
+#define HT_FBK_CFG0	0x1354
+#ifdef RT_BIG_ENDIAN
+typedef	union PACKED _HT_FBK_CFG0_STRUC	{
+	struct	{
+	    UINT32       HTMCS7FBK:4;
+	    UINT32       HTMCS6FBK:4;
+	    UINT32       HTMCS5FBK:4;
+	    UINT32       HTMCS4FBK:4;
+	    UINT32       HTMCS3FBK:4;
+	    UINT32       HTMCS2FBK:4;
+	    UINT32       HTMCS1FBK:4;
+	    UINT32       HTMCS0FBK:4;
+	}	field;
+	UINT32			word;
+}	HT_FBK_CFG0_STRUC, *PHT_FBK_CFG0_STRUC;
+#else
+typedef	union PACKED _HT_FBK_CFG0_STRUC	{
+	struct	{
+	    UINT32       HTMCS0FBK:4;
+	    UINT32       HTMCS1FBK:4;
+	    UINT32       HTMCS2FBK:4;
+	    UINT32       HTMCS3FBK:4;
+	    UINT32       HTMCS4FBK:4;
+	    UINT32       HTMCS5FBK:4;
+	    UINT32       HTMCS6FBK:4;
+	    UINT32       HTMCS7FBK:4;
+	}	field;
+	UINT32			word;
+}	HT_FBK_CFG0_STRUC, *PHT_FBK_CFG0_STRUC;
+#endif
+#define HT_FBK_CFG1	0x1358
+#ifdef RT_BIG_ENDIAN
+typedef	union	_HT_FBK_CFG1_STRUC	{
+	struct	{
+	    UINT32       HTMCS15FBK:4;
+	    UINT32       HTMCS14FBK:4;
+	    UINT32       HTMCS13FBK:4;
+	    UINT32       HTMCS12FBK:4;
+	    UINT32       HTMCS11FBK:4;
+	    UINT32       HTMCS10FBK:4;
+	    UINT32       HTMCS9FBK:4;
+	    UINT32       HTMCS8FBK:4;
+	}	field;
+	UINT32			word;
+}	HT_FBK_CFG1_STRUC, *PHT_FBK_CFG1_STRUC;
+#else
+typedef	union	_HT_FBK_CFG1_STRUC	{
+	struct	{
+	    UINT32       HTMCS8FBK:4;
+	    UINT32       HTMCS9FBK:4;
+	    UINT32       HTMCS10FBK:4;
+	    UINT32       HTMCS11FBK:4;
+	    UINT32       HTMCS12FBK:4;
+	    UINT32       HTMCS13FBK:4;
+	    UINT32       HTMCS14FBK:4;
+	    UINT32       HTMCS15FBK:4;
+	}	field;
+	UINT32			word;
+}	HT_FBK_CFG1_STRUC, *PHT_FBK_CFG1_STRUC;
+#endif
+#define LG_FBK_CFG0	0x135c
+#ifdef RT_BIG_ENDIAN
+typedef	union	_LG_FBK_CFG0_STRUC	{
+	struct	{
+	    UINT32       OFDMMCS7FBK:4;	//initial value is 6
+	    UINT32       OFDMMCS6FBK:4;	//initial value is 5
+	    UINT32       OFDMMCS5FBK:4;	//initial value is 4
+	    UINT32       OFDMMCS4FBK:4;	//initial value is 3
+	    UINT32       OFDMMCS3FBK:4;	//initial value is 2
+	    UINT32       OFDMMCS2FBK:4;	//initial value is 1
+	    UINT32       OFDMMCS1FBK:4;	//initial value is 0
+	    UINT32       OFDMMCS0FBK:4;	//initial value is 0
+	}	field;
+	UINT32			word;
+}	LG_FBK_CFG0_STRUC, *PLG_FBK_CFG0_STRUC;
+#else
+typedef	union	_LG_FBK_CFG0_STRUC	{
+	struct	{
+	    UINT32       OFDMMCS0FBK:4;	//initial value is 0
+	    UINT32       OFDMMCS1FBK:4;	//initial value is 0
+	    UINT32       OFDMMCS2FBK:4;	//initial value is 1
+	    UINT32       OFDMMCS3FBK:4;	//initial value is 2
+	    UINT32       OFDMMCS4FBK:4;	//initial value is 3
+	    UINT32       OFDMMCS5FBK:4;	//initial value is 4
+	    UINT32       OFDMMCS6FBK:4;	//initial value is 5
+	    UINT32       OFDMMCS7FBK:4;	//initial value is 6
+	}	field;
+	UINT32			word;
+}	LG_FBK_CFG0_STRUC, *PLG_FBK_CFG0_STRUC;
+#endif
+#define LG_FBK_CFG1		0x1360
+#ifdef RT_BIG_ENDIAN
+typedef	union	_LG_FBK_CFG1_STRUC	{
+	struct	{
+	    UINT32       rsv:16;
+	    UINT32       CCKMCS3FBK:4;	//initial value is 2
+	    UINT32       CCKMCS2FBK:4;	//initial value is 1
+	    UINT32       CCKMCS1FBK:4;	//initial value is 0
+	    UINT32       CCKMCS0FBK:4;	//initial value is 0
+	}	field;
+	UINT32			word;
+}	LG_FBK_CFG1_STRUC, *PLG_FBK_CFG1_STRUC;
+#else
+typedef	union	_LG_FBK_CFG1_STRUC	{
+	struct	{
+	    UINT32       CCKMCS0FBK:4;	//initial value is 0
+	    UINT32       CCKMCS1FBK:4;	//initial value is 0
+	    UINT32       CCKMCS2FBK:4;	//initial value is 1
+	    UINT32       CCKMCS3FBK:4;	//initial value is 2
+	    UINT32       rsv:16;
+	}	field;
+	UINT32			word;
+}	LG_FBK_CFG1_STRUC, *PLG_FBK_CFG1_STRUC;
+#endif
+
+//=======================================================
+//================ Protection Paramater================================
+//=======================================================
+#define CCK_PROT_CFG	0x1364		//CCK Protection
+#define ASIC_SHORTNAV		1
+#define ASIC_LONGNAV		2
+#define ASIC_RTS		1
+#define ASIC_CTS		2
+#ifdef RT_BIG_ENDIAN
+typedef	union	_PROT_CFG_STRUC	{
+	struct	{
+	    UINT32       rsv:5;
+	    UINT32       RTSThEn:1;	//RTS threshold enable on CCK TX
+	    UINT32       TxopAllowGF40:1;	//CCK TXOP allowance.0:disallow.
+	    UINT32       TxopAllowGF20:1;	//CCK TXOP allowance.0:disallow.
+	    UINT32       TxopAllowMM40:1;	//CCK TXOP allowance.0:disallow.
+	    UINT32       TxopAllowMM20:1;	//CCK TXOP allowance. 0:disallow.
+	    UINT32       TxopAllowOfdm:1;	//CCK TXOP allowance.0:disallow.
+	    UINT32       TxopAllowCck:1;	//CCK TXOP allowance.0:disallow.
+	    UINT32       ProtectNav:2;	//TXOP protection type for CCK TX. 0:None, 1:ShortNAVprotect,  2:LongNAVProtect, 3:rsv
+	    UINT32       ProtectCtrl:2;	//Protection control frame type for CCK TX. 1:RTS/CTS, 2:CTS-to-self, 0:None, 3:rsv
+	    UINT32       ProtectRate:16;	//Protection control frame rate for CCK TX(RTS/CTS/CFEnd).
+	}	field;
+	UINT32			word;
+}	PROT_CFG_STRUC, *PPROT_CFG_STRUC;
+#else
+typedef	union	_PROT_CFG_STRUC	{
+	struct	{
+	    UINT32       ProtectRate:16;	//Protection control frame rate for CCK TX(RTS/CTS/CFEnd).
+	    UINT32       ProtectCtrl:2;	//Protection control frame type for CCK TX. 1:RTS/CTS, 2:CTS-to-self, 0:None, 3:rsv
+	    UINT32       ProtectNav:2;	//TXOP protection type for CCK TX. 0:None, 1:ShortNAVprotect,  2:LongNAVProtect, 3:rsv
+	    UINT32       TxopAllowCck:1;	//CCK TXOP allowance.0:disallow.
+	    UINT32       TxopAllowOfdm:1;	//CCK TXOP allowance.0:disallow.
+	    UINT32       TxopAllowMM20:1;	//CCK TXOP allowance. 0:disallow.
+	    UINT32       TxopAllowMM40:1;	//CCK TXOP allowance.0:disallow.
+	    UINT32       TxopAllowGF20:1;	//CCK TXOP allowance.0:disallow.
+	    UINT32       TxopAllowGF40:1;	//CCK TXOP allowance.0:disallow.
+	    UINT32       RTSThEn:1;	//RTS threshold enable on CCK TX
+	    UINT32       rsv:5;
+	}	field;
+	UINT32			word;
+}	PROT_CFG_STRUC, *PPROT_CFG_STRUC;
+#endif
+
+#define OFDM_PROT_CFG	0x1368		//OFDM Protection
+#define MM20_PROT_CFG	0x136C		//MM20 Protection
+#define MM40_PROT_CFG	0x1370		//MM40 Protection
+#define GF20_PROT_CFG	0x1374		//GF20 Protection
+#define GF40_PROT_CFG	0x1378		//GR40 Protection
+#define EXP_CTS_TIME	0x137C		//
+#define EXP_ACK_TIME	0x1380		//
+
+//
+//  4.4 MAC RX configuration registers (offset:0x1400)
+//
+#define RX_FILTR_CFG	0x1400			//TXRX_CSR0
+#define AUTO_RSP_CFG	0x1404			//TXRX_CSR4
+//
+// TXRX_CSR4: Auto-Responder/
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _AUTO_RSP_CFG_STRUC {
+ struct {
+     UINT32        :24;
+     UINT32       AckCtsPsmBit:1;   // Power bit value in conrtrol frame
+     UINT32       DualCTSEn:1;   // Power bit value in conrtrol frame
+     UINT32       rsv:1;   // Power bit value in conrtrol frame
+     UINT32       AutoResponderPreamble:1;    // 0:long, 1:short preamble
+     UINT32       CTS40MRef:1;  // Response CTS 40MHz duplicate mode
+     UINT32       CTS40MMode:1;  // Response CTS 40MHz duplicate mode
+     UINT32       BACAckPolicyEnable:1;    // 0:long, 1:short preamble
+     UINT32       AutoResponderEnable:1;
+ } field;
+ UINT32   word;
+} AUTO_RSP_CFG_STRUC, *PAUTO_RSP_CFG_STRUC;
+#else
+typedef union _AUTO_RSP_CFG_STRUC {
+ struct {
+     UINT32       AutoResponderEnable:1;
+     UINT32       BACAckPolicyEnable:1;    // 0:long, 1:short preamble
+     UINT32       CTS40MMode:1;  // Response CTS 40MHz duplicate mode
+     UINT32       CTS40MRef:1;  // Response CTS 40MHz duplicate mode
+     UINT32       AutoResponderPreamble:1;    // 0:long, 1:short preamble
+     UINT32       rsv:1;   // Power bit value in conrtrol frame
+     UINT32       DualCTSEn:1;   // Power bit value in conrtrol frame
+     UINT32       AckCtsPsmBit:1;   // Power bit value in conrtrol frame
+     UINT32        :24;
+ } field;
+ UINT32   word;
+} AUTO_RSP_CFG_STRUC, *PAUTO_RSP_CFG_STRUC;
+#endif
+
+#define LEGACY_BASIC_RATE	0x1408	//  TXRX_CSR5           0x3054
+#define HT_BASIC_RATE		0x140c
+#define HT_CTRL_CFG		0x1410
+#define SIFS_COST_CFG		0x1414
+#define RX_PARSER_CFG		0x1418	//Set NAV for all received frames
+
+//
+//  4.5 MAC Security configuration (offset:0x1500)
+//
+#define TX_SEC_CNT0		0x1500		//
+#define RX_SEC_CNT0		0x1504		//
+#define CCMP_FC_MUTE		0x1508		//
+//
+//  4.6 HCCA/PSMP (offset:0x1600)
+//
+#define TXOP_HLDR_ADDR0		0x1600
+#define TXOP_HLDR_ADDR1		0x1604
+#define TXOP_HLDR_ET		0x1608
+#define QOS_CFPOLL_RA_DW0		0x160c
+#define QOS_CFPOLL_A1_DW1		0x1610
+#define QOS_CFPOLL_QC		0x1614
+//
+//  4.7 MAC Statistis registers (offset:0x1700)
+//
+#define RX_STA_CNT0		0x1700		//
+#define RX_STA_CNT1		0x1704		//
+#define RX_STA_CNT2		0x1708		//
+
+//
+// RX_STA_CNT0_STRUC: RX PLCP error count & RX CRC error count
+//
+#ifdef RT_BIG_ENDIAN
+typedef	union	_RX_STA_CNT0_STRUC	{
+	struct	{
+	    USHORT  PhyErr;
+	    USHORT  CrcErr;
+	}	field;
+	UINT32			word;
+}	RX_STA_CNT0_STRUC, *PRX_STA_CNT0_STRUC;
+#else
+typedef	union	_RX_STA_CNT0_STRUC	{
+	struct	{
+	    USHORT  CrcErr;
+	    USHORT  PhyErr;
+	}	field;
+	UINT32			word;
+}	RX_STA_CNT0_STRUC, *PRX_STA_CNT0_STRUC;
+#endif
+
+//
+// RX_STA_CNT1_STRUC: RX False CCA count & RX LONG frame count
+//
+#ifdef RT_BIG_ENDIAN
+typedef	union	_RX_STA_CNT1_STRUC	{
+	struct	{
+	    USHORT  PlcpErr;
+	    USHORT  FalseCca;
+	}	field;
+	UINT32			word;
+}	RX_STA_CNT1_STRUC, *PRX_STA_CNT1_STRUC;
+#else
+typedef	union	_RX_STA_CNT1_STRUC	{
+	struct	{
+	    USHORT  FalseCca;
+	    USHORT  PlcpErr;
+	}	field;
+	UINT32			word;
+}	RX_STA_CNT1_STRUC, *PRX_STA_CNT1_STRUC;
+#endif
+
+//
+// RX_STA_CNT2_STRUC:
+//
+#ifdef RT_BIG_ENDIAN
+typedef	union	_RX_STA_CNT2_STRUC	{
+	struct	{
+	    USHORT  RxFifoOverflowCount;
+	    USHORT  RxDupliCount;
+	}	field;
+	UINT32			word;
+}	RX_STA_CNT2_STRUC, *PRX_STA_CNT2_STRUC;
+#else
+typedef	union	_RX_STA_CNT2_STRUC	{
+	struct	{
+	    USHORT  RxDupliCount;
+	    USHORT  RxFifoOverflowCount;
+	}	field;
+	UINT32			word;
+}	RX_STA_CNT2_STRUC, *PRX_STA_CNT2_STRUC;
+#endif
+#define TX_STA_CNT0		0x170C		//
+//
+// STA_CSR3: TX Beacon count
+//
+#ifdef RT_BIG_ENDIAN
+typedef	union	_TX_STA_CNT0_STRUC	{
+	struct	{
+	    USHORT  TxBeaconCount;
+	    USHORT  TxFailCount;
+	}	field;
+	UINT32			word;
+}	TX_STA_CNT0_STRUC, *PTX_STA_CNT0_STRUC;
+#else
+typedef	union	_TX_STA_CNT0_STRUC	{
+	struct	{
+	    USHORT  TxFailCount;
+	    USHORT  TxBeaconCount;
+	}	field;
+	UINT32			word;
+}	TX_STA_CNT0_STRUC, *PTX_STA_CNT0_STRUC;
+#endif
+#define TX_STA_CNT1		0x1710		//
+//
+// TX_STA_CNT1: TX tx count
+//
+#ifdef RT_BIG_ENDIAN
+typedef	union	_TX_STA_CNT1_STRUC	{
+	struct	{
+	    USHORT  TxRetransmit;
+	    USHORT  TxSuccess;
+	}	field;
+	UINT32			word;
+}	TX_STA_CNT1_STRUC, *PTX_STA_CNT1_STRUC;
+#else
+typedef	union	_TX_STA_CNT1_STRUC	{
+	struct	{
+	    USHORT  TxSuccess;
+	    USHORT  TxRetransmit;
+	}	field;
+	UINT32			word;
+}	TX_STA_CNT1_STRUC, *PTX_STA_CNT1_STRUC;
+#endif
+#define TX_STA_CNT2		0x1714		//
+//
+// TX_STA_CNT2: TX tx count
+//
+#ifdef RT_BIG_ENDIAN
+typedef	union	_TX_STA_CNT2_STRUC	{
+	struct	{
+	    USHORT  TxUnderFlowCount;
+	    USHORT  TxZeroLenCount;
+	}	field;
+	UINT32			word;
+}	TX_STA_CNT2_STRUC, *PTX_STA_CNT2_STRUC;
+#else
+typedef	union	_TX_STA_CNT2_STRUC	{
+	struct	{
+	    USHORT  TxZeroLenCount;
+	    USHORT  TxUnderFlowCount;
+	}	field;
+	UINT32			word;
+}	TX_STA_CNT2_STRUC, *PTX_STA_CNT2_STRUC;
+#endif
+#define TX_STA_FIFO		0x1718		//
+//
+// TX_STA_FIFO_STRUC: TX Result for specific PID status fifo register
+//
+#ifdef RT_BIG_ENDIAN
+typedef	union PACKED _TX_STA_FIFO_STRUC	{
+	struct	{
+		UINT32		Reserve:2;
+		UINT32		TxBF:1; // 3*3
+		UINT32		SuccessRate:13;	//include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
+//		UINT32		SuccessRate:16;	//include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
+		UINT32		wcid:8;		//wireless client index
+		UINT32       	TxAckRequired:1;    // ack required
+		UINT32       	TxAggre:1;    // Tx is aggregated
+		UINT32       	TxSuccess:1;   // Tx success. whether success or not
+		UINT32       	PidType:4;
+		UINT32       	bValid:1;   // 1:This register contains a valid TX result
+	}	field;
+	UINT32			word;
+}	TX_STA_FIFO_STRUC, *PTX_STA_FIFO_STRUC;
+#else
+typedef	union PACKED _TX_STA_FIFO_STRUC	{
+	struct	{
+		UINT32       	bValid:1;   // 1:This register contains a valid TX result
+		UINT32       	PidType:4;
+		UINT32       	TxSuccess:1;   // Tx No retry success
+		UINT32       	TxAggre:1;    // Tx Retry Success
+		UINT32       	TxAckRequired:1;    // Tx fail
+		UINT32		wcid:8;		//wireless client index
+//		UINT32		SuccessRate:16;	//include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
+		UINT32		SuccessRate:13;	//include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
+		UINT32		TxBF:1;
+		UINT32		Reserve:2;
+	}	field;
+	UINT32			word;
+}	TX_STA_FIFO_STRUC, *PTX_STA_FIFO_STRUC;
+#endif
+// Debug counter
+#define TX_AGG_CNT	0x171c
+#ifdef RT_BIG_ENDIAN
+typedef	union	_TX_AGG_CNT_STRUC	{
+	struct	{
+	    USHORT  AggTxCount;
+	    USHORT  NonAggTxCount;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT_STRUC, *PTX_AGG_CNT_STRUC;
+#else
+typedef	union	_TX_AGG_CNT_STRUC	{
+	struct	{
+	    USHORT  NonAggTxCount;
+	    USHORT  AggTxCount;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT_STRUC, *PTX_AGG_CNT_STRUC;
+#endif
+// Debug counter
+#define TX_AGG_CNT0	0x1720
+#ifdef RT_BIG_ENDIAN
+typedef	union	_TX_AGG_CNT0_STRUC	{
+	struct	{
+	    USHORT  AggSize2Count;
+	    USHORT  AggSize1Count;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT0_STRUC, *PTX_AGG_CNT0_STRUC;
+#else
+typedef	union	_TX_AGG_CNT0_STRUC	{
+	struct	{
+	    USHORT  AggSize1Count;
+	    USHORT  AggSize2Count;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT0_STRUC, *PTX_AGG_CNT0_STRUC;
+#endif
+// Debug counter
+#define TX_AGG_CNT1	0x1724
+#ifdef RT_BIG_ENDIAN
+typedef	union	_TX_AGG_CNT1_STRUC	{
+	struct	{
+	    USHORT  AggSize4Count;
+	    USHORT  AggSize3Count;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT1_STRUC, *PTX_AGG_CNT1_STRUC;
+#else
+typedef	union	_TX_AGG_CNT1_STRUC	{
+	struct	{
+	    USHORT  AggSize3Count;
+	    USHORT  AggSize4Count;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT1_STRUC, *PTX_AGG_CNT1_STRUC;
+#endif
+#define TX_AGG_CNT2	0x1728
+#ifdef RT_BIG_ENDIAN
+typedef	union	_TX_AGG_CNT2_STRUC	{
+	struct	{
+	    USHORT  AggSize6Count;
+	    USHORT  AggSize5Count;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT2_STRUC, *PTX_AGG_CNT2_STRUC;
+#else
+typedef	union	_TX_AGG_CNT2_STRUC	{
+	struct	{
+	    USHORT  AggSize5Count;
+	    USHORT  AggSize6Count;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT2_STRUC, *PTX_AGG_CNT2_STRUC;
+#endif
+// Debug counter
+#define TX_AGG_CNT3	0x172c
+#ifdef RT_BIG_ENDIAN
+typedef	union	_TX_AGG_CNT3_STRUC	{
+	struct	{
+	    USHORT  AggSize8Count;
+	    USHORT  AggSize7Count;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT3_STRUC, *PTX_AGG_CNT3_STRUC;
+#else
+typedef	union	_TX_AGG_CNT3_STRUC	{
+	struct	{
+	    USHORT  AggSize7Count;
+	    USHORT  AggSize8Count;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT3_STRUC, *PTX_AGG_CNT3_STRUC;
+#endif
+// Debug counter
+#define TX_AGG_CNT4	0x1730
+#ifdef RT_BIG_ENDIAN
+typedef	union	_TX_AGG_CNT4_STRUC	{
+	struct	{
+	    USHORT  AggSize10Count;
+	    USHORT  AggSize9Count;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT4_STRUC, *PTX_AGG_CNT4_STRUC;
+#else
+typedef	union	_TX_AGG_CNT4_STRUC	{
+	struct	{
+	    USHORT  AggSize9Count;
+	    USHORT  AggSize10Count;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT4_STRUC, *PTX_AGG_CNT4_STRUC;
+#endif
+#define TX_AGG_CNT5	0x1734
+#ifdef RT_BIG_ENDIAN
+typedef	union	_TX_AGG_CNT5_STRUC	{
+	struct	{
+	    USHORT  AggSize12Count;
+	    USHORT  AggSize11Count;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT5_STRUC, *PTX_AGG_CNT5_STRUC;
+#else
+typedef	union	_TX_AGG_CNT5_STRUC	{
+	struct	{
+	    USHORT  AggSize11Count;
+	    USHORT  AggSize12Count;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT5_STRUC, *PTX_AGG_CNT5_STRUC;
+#endif
+#define TX_AGG_CNT6		0x1738
+#ifdef RT_BIG_ENDIAN
+typedef	union	_TX_AGG_CNT6_STRUC	{
+	struct	{
+	    USHORT  AggSize14Count;
+	    USHORT  AggSize13Count;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT6_STRUC, *PTX_AGG_CNT6_STRUC;
+#else
+typedef	union	_TX_AGG_CNT6_STRUC	{
+	struct	{
+	    USHORT  AggSize13Count;
+	    USHORT  AggSize14Count;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT6_STRUC, *PTX_AGG_CNT6_STRUC;
+#endif
+#define TX_AGG_CNT7		0x173c
+#ifdef RT_BIG_ENDIAN
+typedef	union	_TX_AGG_CNT7_STRUC	{
+	struct	{
+	    USHORT  AggSize16Count;
+	    USHORT  AggSize15Count;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT7_STRUC, *PTX_AGG_CNT7_STRUC;
+#else
+typedef	union	_TX_AGG_CNT7_STRUC	{
+	struct	{
+	    USHORT  AggSize15Count;
+	    USHORT  AggSize16Count;
+	}	field;
+	UINT32			word;
+}	TX_AGG_CNT7_STRUC, *PTX_AGG_CNT7_STRUC;
+#endif
+#define MPDU_DENSITY_CNT		0x1740
+#ifdef RT_BIG_ENDIAN
+typedef	union	_MPDU_DEN_CNT_STRUC	{
+	struct	{
+	    USHORT  RXZeroDelCount;	//RX zero length delimiter count
+	    USHORT  TXZeroDelCount;	//TX zero length delimiter count
+	}	field;
+	UINT32			word;
+}	MPDU_DEN_CNT_STRUC, *PMPDU_DEN_CNT_STRUC;
+#else
+typedef	union	_MPDU_DEN_CNT_STRUC	{
+	struct	{
+	    USHORT  TXZeroDelCount;	//TX zero length delimiter count
+	    USHORT  RXZeroDelCount;	//RX zero length delimiter count
+	}	field;
+	UINT32			word;
+}	MPDU_DEN_CNT_STRUC, *PMPDU_DEN_CNT_STRUC;
+#endif
+//
+// TXRX control registers - base address 0x3000
+//
+// rt2860b  UNKNOWN reg use R/O Reg Addr 0x77d0 first..
+#define TXRX_CSR1           0x77d0
+
+//
+// Security key table memory, base address = 0x1000
+//
+#define MAC_WCID_BASE		0x1800 //8-bytes(use only 6-bytes) * 256 entry =
+#define HW_WCID_ENTRY_SIZE   8
+#define PAIRWISE_KEY_TABLE_BASE     0x4000      // 32-byte * 256-entry =  -byte
+#define HW_KEY_ENTRY_SIZE           0x20
+#define PAIRWISE_IVEIV_TABLE_BASE     0x6000      // 8-byte * 256-entry =  -byte
+#define MAC_IVEIV_TABLE_BASE     0x6000      // 8-byte * 256-entry =  -byte
+#define HW_IVEIV_ENTRY_SIZE   8
+#define MAC_WCID_ATTRIBUTE_BASE     0x6800      // 4-byte * 256-entry =  -byte
+#define HW_WCID_ATTRI_SIZE   4
+#define WCID_RESERVED          		0x6bfc
+#define SHARED_KEY_TABLE_BASE       0x6c00      // 32-byte * 16-entry = 512-byte
+#define SHARED_KEY_MODE_BASE       0x7000      // 32-byte * 16-entry = 512-byte
+#define HW_SHARED_KEY_MODE_SIZE   4
+#define SHAREDKEYTABLE			0
+#define PAIRWISEKEYTABLE			1
+
+
+#ifdef RT_BIG_ENDIAN
+typedef	union	_SHAREDKEY_MODE_STRUC	{
+	struct	{
+		UINT32       :1;
+		UINT32       Bss1Key3CipherAlg:3;
+		UINT32       :1;
+		UINT32       Bss1Key2CipherAlg:3;
+		UINT32       :1;
+		UINT32       Bss1Key1CipherAlg:3;
+		UINT32       :1;
+		UINT32       Bss1Key0CipherAlg:3;
+		UINT32       :1;
+		UINT32       Bss0Key3CipherAlg:3;
+		UINT32       :1;
+		UINT32       Bss0Key2CipherAlg:3;
+		UINT32       :1;
+		UINT32       Bss0Key1CipherAlg:3;
+		UINT32       :1;
+		UINT32       Bss0Key0CipherAlg:3;
+	}	field;
+	UINT32			word;
+}	SHAREDKEY_MODE_STRUC, *PSHAREDKEY_MODE_STRUC;
+#else
+typedef	union	_SHAREDKEY_MODE_STRUC	{
+	struct	{
+		UINT32       Bss0Key0CipherAlg:3;
+		UINT32       :1;
+		UINT32       Bss0Key1CipherAlg:3;
+		UINT32       :1;
+		UINT32       Bss0Key2CipherAlg:3;
+		UINT32       :1;
+		UINT32       Bss0Key3CipherAlg:3;
+		UINT32       :1;
+		UINT32       Bss1Key0CipherAlg:3;
+		UINT32       :1;
+		UINT32       Bss1Key1CipherAlg:3;
+		UINT32       :1;
+		UINT32       Bss1Key2CipherAlg:3;
+		UINT32       :1;
+		UINT32       Bss1Key3CipherAlg:3;
+		UINT32       :1;
+	}	field;
+	UINT32			word;
+}	SHAREDKEY_MODE_STRUC, *PSHAREDKEY_MODE_STRUC;
+#endif
+// 64-entry for pairwise key table
+typedef struct _HW_WCID_ENTRY {  // 8-byte per entry
+    UCHAR   Address[6];
+    UCHAR   Rsv[2];
+} HW_WCID_ENTRY, PHW_WCID_ENTRY;
+
+
+
+//
+// Other on-chip shared memory space, base = 0x2000
+//
+
+// CIS space - base address = 0x2000
+#define HW_CIS_BASE             0x2000
+
+// Carrier-sense CTS frame base address. It's where mac stores carrier-sense frame for carrier-sense function.
+#define HW_CS_CTS_BASE			0x7700
+// DFS CTS frame base address. It's where mac stores CTS frame for DFS.
+#define HW_DFS_CTS_BASE			0x7780
+#define HW_CTS_FRAME_SIZE		0x80
+
+// 2004-11-08 john - since NULL frame won't be that long (256 byte). We steal 16 tail bytes
+// to save debugging settings
+#define HW_DEBUG_SETTING_BASE   0x77f0  // 0x77f0~0x77ff total 16 bytes
+#define HW_DEBUG_SETTING_BASE2   0x7770  // 0x77f0~0x77ff total 16 bytes
+
+// In order to support maximum 8 MBSS and its maximum length is 512 for each beacon
+// Three section discontinue memory segments will be used.
+// 1. The original region for BCN 0~3
+// 2. Extract memory from FCE table for BCN 4~5
+// 3. Extract memory from Pair-wise key table for BCN 6~7
+//	  It occupied those memory of wcid 238~253 for BCN 6
+//						      and wcid 222~237 for BCN 7
+#define HW_BEACON_MAX_SIZE      0x1000 /* unit: byte */
+#define HW_BEACON_BASE0         0x7800
+#define HW_BEACON_BASE1         0x7A00
+#define HW_BEACON_BASE2         0x7C00
+#define HW_BEACON_BASE3         0x7E00
+#define HW_BEACON_BASE4         0x7200
+#define HW_BEACON_BASE5         0x7400
+#define HW_BEACON_BASE6         0x5DC0
+#define HW_BEACON_BASE7         0x5BC0
+
+#define HW_BEACON_MAX_COUNT     8
+#define HW_BEACON_OFFSET		0x0200
+#define HW_BEACON_CONTENT_LEN	(HW_BEACON_OFFSET - TXWI_SIZE)
+
+// HOST-MCU shared memory - base address = 0x2100
+#define HOST_CMD_CSR		0x404
+#define H2M_MAILBOX_CSR         0x7010
+#define H2M_MAILBOX_CID         0x7014
+#define H2M_MAILBOX_STATUS      0x701c
+#define H2M_INT_SRC             0x7024
+#define H2M_BBP_AGENT           0x7028
+#define M2H_CMD_DONE_CSR        0x000c
+#define MCU_TXOP_ARRAY_BASE     0x000c   // TODO: to be provided by Albert
+#define MCU_TXOP_ENTRY_SIZE     32       // TODO: to be provided by Albert
+#define MAX_NUM_OF_TXOP_ENTRY   16       // TODO: must be same with 8051 firmware
+#define MCU_MBOX_VERSION        0x01     // TODO: to be confirmed by Albert
+#define MCU_MBOX_VERSION_OFFSET 5        // TODO: to be provided by Albert
+
+//
+// Host DMA registers - base address 0x200 .  TX0-3=EDCAQid0-3, TX4=HCCA, TX5=MGMT,
+//
+//
+//  DMA RING DESCRIPTOR
+//
+#define E2PROM_CSR          0x0004
+#define IO_CNTL_CSR         0x77d0
+
+#ifdef RT2870
+// 8051 firmware image for usb - use last-half base address = 0x3000
+#define FIRMWARE_IMAGE_BASE     0x3000
+#define MAX_FIRMWARE_IMAGE_SIZE 0x1000    // 4kbyte
+#endif // RT2870 //
+
+// TODO: ????? old RT2560 registers. to keep them or remove them?
+//#define MCAST0                  0x0178  // multicast filter register 0
+//#define MCAST1                  0x017c  // multicast filter register 1
+
+
+// ================================================================
+// Tx /	Rx / Mgmt ring descriptor definition
+// ================================================================
+
+// the following PID values are used to mark outgoing frame type in TXD->PID so that
+// proper TX statistics can be collected based on these categories
+// b3-2 of PID field -
+#define PID_MGMT			0x05
+#define PID_BEACON			0x0c
+#define PID_DATA_NORMALUCAST	 	0x02
+#define PID_DATA_AMPDU	 	0x04
+#define PID_DATA_NO_ACK    	0x08
+#define PID_DATA_NOT_NORM_ACK	 	0x03
+// value domain of pTxD->HostQId (4-bit: 0~15)
+#define QID_AC_BK               1   // meet ACI definition in 802.11e
+#define QID_AC_BE               0   // meet ACI definition in 802.11e
+#define QID_AC_VI               2
+#define QID_AC_VO               3
+#define QID_HCCA                4
+#define NUM_OF_TX_RING          5
+#define QID_MGMT                13
+#define QID_RX                  14
+#define QID_OTHER               15
+
+
+// ------------------------------------------------------
+// BBP & RF	definition
+// ------------------------------------------------------
+#define	BUSY		                1
+#define	IDLE		                0
+
+#define	RF_R00					    0
+#define	RF_R01					    1
+#define	RF_R02					    2
+#define	RF_R03					    3
+#define	RF_R04					    4
+#define	RF_R05					    5
+#define	RF_R06					    6
+#define	RF_R07					    7
+#define	RF_R08					    8
+#define	RF_R09					    9
+#define	RF_R10					    10
+#define	RF_R11					    11
+#define	RF_R12					    12
+#define	RF_R13					    13
+#define	RF_R14					    14
+#define	RF_R15					    15
+#define	RF_R16					    16
+#define	RF_R17					    17
+#define	RF_R18					    18
+#define	RF_R19					    19
+#define	RF_R20					    20
+#define	RF_R21					    21
+#define	RF_R22					    22
+#define	RF_R23					    23
+#define	RF_R24					    24
+#define	RF_R25					    25
+#define	RF_R26					    26
+#define	RF_R27					    27
+#define	RF_R28					    28
+#define	RF_R29					    29
+#define	RF_R30					    30
+#define	RF_R31					    31
+
+#define	BBP_R0					    0  // version
+#define	BBP_R1				        1  // TSSI
+#define	BBP_R2          			2  // TX configure
+#define BBP_R3                      3
+#define BBP_R4                      4
+#define BBP_R5                      5
+#define BBP_R6                      6
+#define	BBP_R14			            14 // RX configure
+#define BBP_R16                     16
+#define BBP_R17                     17 // RX sensibility
+#define BBP_R18                     18
+#define BBP_R21                     21
+#define BBP_R22                     22
+#define BBP_R24                     24
+#define BBP_R25                     25
+#define BBP_R31                     31
+#define BBP_R49                     49 //TSSI
+#define BBP_R50                     50
+#define BBP_R51                     51
+#define BBP_R52                     52
+#define BBP_R55                     55
+#define BBP_R62                     62 // Rx SQ0 Threshold HIGH
+#define BBP_R63                     63
+#define BBP_R64                     64
+#define BBP_R65                     65
+#define BBP_R66                     66
+#define BBP_R67                     67
+#define BBP_R68                     68
+#define BBP_R69                     69
+#define BBP_R70                     70 // Rx AGC SQ CCK Xcorr threshold
+#define BBP_R73                     73
+#define BBP_R75						75
+#define BBP_R77                     77
+#define BBP_R79                     79
+#define BBP_R80                     80
+#define BBP_R81                     81
+#define BBP_R82                     82
+#define BBP_R83                     83
+#define BBP_R84                     84
+#define BBP_R86						86
+#define BBP_R91						91
+#define BBP_R92						92
+#define BBP_R94                     94 // Tx Gain Control
+#define BBP_R103                    103
+#define BBP_R105                    105
+#define BBP_R113                    113
+#define BBP_R114                    114
+#define BBP_R115                    115
+#define BBP_R116                    116
+#define BBP_R117                    117
+#define BBP_R118                    118
+#define BBP_R119                    119
+#define BBP_R120                    120
+#define BBP_R121                    121
+#define BBP_R122                    122
+#define BBP_R123                    123
+#ifdef RT30xx
+#define BBP_R138                    138 // add by johnli, RF power sequence setup, ADC dynamic on/off control
+#endif // RT30xx //
+
+
+#define BBPR94_DEFAULT              0x06 // Add 1 value will gain 1db
+
+//#define PHY_TR_SWITCH_TIME          5  // usec
+
+//#define BBP_R17_LOW_SENSIBILITY     0x50
+//#define BBP_R17_MID_SENSIBILITY     0x41
+//#define BBP_R17_DYNAMIC_UP_BOUND    0x40
+#define RSSI_FOR_VERY_LOW_SENSIBILITY -35
+#define RSSI_FOR_LOW_SENSIBILITY      -58
+#define RSSI_FOR_MID_LOW_SENSIBILITY  -80
+#define RSSI_FOR_MID_SENSIBILITY      -90
+
+//-------------------------------------------------------------------------
+// EEPROM definition
+//-------------------------------------------------------------------------
+#define EEDO                        0x08
+#define EEDI                        0x04
+#define EECS                        0x02
+#define EESK                        0x01
+#define EERL                        0x80
+
+#define EEPROM_WRITE_OPCODE         0x05
+#define EEPROM_READ_OPCODE          0x06
+#define EEPROM_EWDS_OPCODE          0x10
+#define EEPROM_EWEN_OPCODE          0x13
+
+#define	NUM_EEPROM_BBP_PARMS		19			// Include NIC Config 0, 1, CR, TX ALC step, BBPs
+#define	NUM_EEPROM_TX_G_PARMS		7
+#define	EEPROM_NIC1_OFFSET          0x34		// The address is from NIC config 0, not BBP register ID
+#define	EEPROM_NIC2_OFFSET          0x36		// The address is from NIC config 0, not BBP register ID
+#define	EEPROM_BBP_BASE_OFFSET		0xf0		// The address is from NIC config 0, not BBP register ID
+#define	EEPROM_G_TX_PWR_OFFSET		0x52
+#define	EEPROM_G_TX2_PWR_OFFSET		0x60
+#define EEPROM_LED1_OFFSET			0x3c
+#define EEPROM_LED2_OFFSET			0x3e
+#define EEPROM_LED3_OFFSET			0x40
+#define EEPROM_LNA_OFFSET			0x44
+#define EEPROM_RSSI_BG_OFFSET		0x46
+#define EEPROM_RSSI_A_OFFSET		0x4a
+#define EEPROM_DEFINE_MAX_TXPWR		0x4e
+#define EEPROM_TXPOWER_BYRATE_20MHZ_2_4G	0xde	// 20MHZ 2.4G tx power.
+#define EEPROM_TXPOWER_BYRATE_40MHZ_2_4G	0xee	// 40MHZ 2.4G tx power.
+#define EEPROM_TXPOWER_BYRATE_20MHZ_5G		0xfa	// 20MHZ 5G tx power.
+#define EEPROM_TXPOWER_BYRATE_40MHZ_5G		0x10a	// 40MHZ 5G tx power.
+#define EEPROM_A_TX_PWR_OFFSET      0x78
+#define EEPROM_A_TX2_PWR_OFFSET      0xa6
+//#define EEPROM_Japan_TX_PWR_OFFSET      0x90 // 802.11j
+//#define EEPROM_Japan_TX2_PWR_OFFSET      0xbe
+//#define EEPROM_TSSI_REF_OFFSET	0x54
+//#define EEPROM_TSSI_DELTA_OFFSET	0x24
+//#define EEPROM_CCK_TX_PWR_OFFSET  0x62
+//#define EEPROM_CALIBRATE_OFFSET	0x7c
+#define EEPROM_VERSION_OFFSET       0x02
+#define	EEPROM_FREQ_OFFSET			0x3a
+#define EEPROM_TXPOWER_BYRATE 	0xde	// 20MHZ power.
+#define EEPROM_TXPOWER_DELTA		0x50	// 20MHZ AND 40 MHZ use different power. This is delta in 40MHZ.
+#define VALID_EEPROM_VERSION        1
+
+// PairKeyMode definition
+#define PKMODE_NONE                 0
+#define PKMODE_WEP64                1
+#define PKMODE_WEP128               2
+#define PKMODE_TKIP                 3
+#define PKMODE_AES                  4
+#define PKMODE_CKIP64               5
+#define PKMODE_CKIP128              6
+#define PKMODE_TKIP_NO_MIC          7       // MIC appended by driver: not a valid value in hardware key table
+
+// =================================================================================
+// WCID  format
+// =================================================================================
+//7.1	WCID  ENTRY  format  : 8bytes
+typedef	struct	_WCID_ENTRY_STRUC {
+	UCHAR		RXBABitmap7;    // bit0 for TID8, bit7 for TID 15
+	UCHAR		RXBABitmap0;    // bit0 for TID0, bit7 for TID 7
+	UCHAR		MAC[6];	// 0 for shared key table.  1 for pairwise key table
+}	WCID_ENTRY_STRUC, *PWCID_ENTRY_STRUC;
+
+//8.1.1	SECURITY  KEY  format  : 8DW
+// 32-byte per entry, total 16-entry for shared key table, 64-entry for pairwise key table
+typedef struct _HW_KEY_ENTRY {          // 32-byte per entry
+    UCHAR   Key[16];
+    UCHAR   TxMic[8];
+    UCHAR   RxMic[8];
+} HW_KEY_ENTRY, *PHW_KEY_ENTRY;
+
+//8.1.2	IV/EIV  format  : 2DW
+
+//8.1.3	RX attribute entry format  : 1DW
+#ifdef RT_BIG_ENDIAN
+typedef	struct	_MAC_ATTRIBUTE_STRUC {
+	UINT32		rsv:22;
+	UINT32		RXWIUDF:3;
+	UINT32		BSSIDIdx:3; //multipleBSS index for the WCID
+	UINT32		PairKeyMode:3;
+	UINT32		KeyTab:1;	// 0 for shared key table.  1 for pairwise key table
+}	MAC_ATTRIBUTE_STRUC, *PMAC_ATTRIBUTE_STRUC;
+#else
+typedef	struct	_MAC_ATTRIBUTE_STRUC {
+	UINT32		KeyTab:1;	// 0 for shared key table.  1 for pairwise key table
+	UINT32		PairKeyMode:3;
+	UINT32		BSSIDIdx:3; //multipleBSS index for the WCID
+	UINT32		RXWIUDF:3;
+	UINT32		rsv:22;
+}	MAC_ATTRIBUTE_STRUC, *PMAC_ATTRIBUTE_STRUC;
+#endif
+
+
+// =================================================================================
+// TX / RX ring descriptor format
+// =================================================================================
+
+// the first 24-byte in TXD is called TXINFO and will be DMAed to MAC block through TXFIFO.
+// MAC block use this TXINFO to control the transmission behavior of this frame.
+#define FIFO_MGMT                 0
+#define FIFO_HCCA                 1
+#define FIFO_EDCA                 2
+
+//
+// TX descriptor format, Tx	ring, Mgmt Ring
+//
+#ifdef RT_BIG_ENDIAN
+typedef	struct	PACKED _TXD_STRUC {
+	// Word 0
+	UINT32		SDPtr0;
+	// Word 1
+	UINT32		DMADONE:1;
+	UINT32		LastSec0:1;
+	UINT32		SDLen0:14;
+	UINT32		Burst:1;
+	UINT32		LastSec1:1;
+	UINT32		SDLen1:14;
+	// Word 2
+	UINT32		SDPtr1;
+	// Word 3
+	UINT32		ICO:1;
+	UINT32		UCO:1;
+	UINT32		TCO:1;
+	UINT32		rsv:2;
+	UINT32		QSEL:2;	// select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
+	UINT32		WIV:1;	// Wireless Info Valid. 1 if Driver already fill WI,  o if DMA needs to copy WI to correctposition
+	UINT32		rsv2:24;
+}	TXD_STRUC, *PTXD_STRUC;
+#else
+typedef	struct	PACKED _TXD_STRUC {
+	// Word	0
+	UINT32		SDPtr0;
+	// Word	1
+	UINT32		SDLen1:14;
+	UINT32		LastSec1:1;
+	UINT32		Burst:1;
+	UINT32		SDLen0:14;
+	UINT32		LastSec0:1;
+	UINT32		DMADONE:1;
+	//Word2
+	UINT32		SDPtr1;
+	//Word3
+	UINT32		rsv2:24;
+	UINT32		WIV:1;	// Wireless Info Valid. 1 if Driver already fill WI,  o if DMA needs to copy WI to correctposition
+	UINT32		QSEL:2;	// select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
+	UINT32		rsv:2;
+	UINT32		TCO:1;	//
+	UINT32		UCO:1;	//
+	UINT32		ICO:1;	//
+}	TXD_STRUC, *PTXD_STRUC;
+#endif
+
+
+//
+// TXD Wireless Information format for Tx ring and Mgmt Ring
+//
+//txop : for txop mode
+// 0:txop for the MPDU frame will be handles by ASIC by register
+// 1/2/3:the MPDU frame is send after PIFS/backoff/SIFS
+#ifdef RT_BIG_ENDIAN
+typedef	struct	PACKED _TXWI_STRUC {
+	// Word 0
+	UINT32		PHYMODE:2;
+	UINT32		TxBF:1;	// 3*3
+	UINT32		rsv2:1;
+//	UINT32		rsv2:2;
+	UINT32		Ifs:1;	//
+	UINT32		STBC:2;	//channel bandwidth 20MHz or 40 MHz
+	UINT32		ShortGI:1;
+	UINT32		BW:1;	//channel bandwidth 20MHz or 40 MHz
+	UINT32		MCS:7;
+
+	UINT32		rsv:6;
+	UINT32		txop:2;	//tx back off mode 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs only when previous frame exchange is successful.
+	UINT32		MpduDensity:3;
+	UINT32		AMPDU:1;
+
+	UINT32		TS:1;
+	UINT32		CFACK:1;
+	UINT32		MIMOps:1;	// the remote peer is in dynamic MIMO-PS mode
+	UINT32		FRAG:1;		// 1 to inform TKIP engine this is a fragment.
+	// Word 1
+	UINT32		PacketId:4;
+	UINT32		MPDUtotalByteCount:12;
+	UINT32		WirelessCliID:8;
+	UINT32		BAWinSize:6;
+	UINT32		NSEQ:1;
+	UINT32		ACK:1;
+	// Word 2
+	UINT32		IV;
+	// Word 3
+	UINT32		EIV;
+}	TXWI_STRUC, *PTXWI_STRUC;
+#else
+typedef	struct	PACKED _TXWI_STRUC {
+	// Word	0
+	UINT32		FRAG:1;		// 1 to inform TKIP engine this is a fragment.
+	UINT32		MIMOps:1;	// the remote peer is in dynamic MIMO-PS mode
+	UINT32		CFACK:1;
+	UINT32		TS:1;
+
+	UINT32		AMPDU:1;
+	UINT32		MpduDensity:3;
+	UINT32		txop:2;	//FOR "THIS" frame. 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs only when previous frame exchange is successful.
+	UINT32		rsv:6;
+
+	UINT32		MCS:7;
+	UINT32		BW:1;	//channel bandwidth 20MHz or 40 MHz
+	UINT32		ShortGI:1;
+	UINT32		STBC:2;	// 1: STBC support MCS =0-7,   2,3 : RESERVE
+	UINT32		Ifs:1;	//
+//	UINT32		rsv2:2;	//channel bandwidth 20MHz or 40 MHz
+	UINT32		rsv2:1;
+	UINT32		TxBF:1;	// 3*3
+	UINT32		PHYMODE:2;
+	// Word	1
+	UINT32		ACK:1;
+	UINT32		NSEQ:1;
+	UINT32		BAWinSize:6;
+	UINT32		WirelessCliID:8;
+	UINT32		MPDUtotalByteCount:12;
+	UINT32		PacketId:4;
+	//Word2
+	UINT32		IV;
+	//Word3
+	UINT32		EIV;
+}	TXWI_STRUC, *PTXWI_STRUC;
+#endif
+//
+// Rx descriptor format, Rx	Ring
+//
+//
+// RXWI wireless information format, in PBF. invisible in driver.
+//
+#ifdef RT_BIG_ENDIAN
+typedef	struct	PACKED _RXWI_STRUC {
+	// Word 0
+	UINT32		TID:4;
+	UINT32		MPDUtotalByteCount:12;
+	UINT32		UDF:3;
+	UINT32		BSSID:3;
+	UINT32		KeyIndex:2;
+	UINT32		WirelessCliID:8;
+	// Word 1
+	UINT32		PHYMODE:2;              // 1: this RX frame is unicast to me
+	UINT32		rsv:3;
+	UINT32		STBC:2;
+	UINT32		ShortGI:1;
+	UINT32		BW:1;
+	UINT32		MCS:7;
+	UINT32		SEQUENCE:12;
+	UINT32		FRAG:4;
+	// Word 2
+	UINT32		rsv1:8;
+	UINT32		RSSI2:8;
+	UINT32		RSSI1:8;
+	UINT32		RSSI0:8;
+	// Word 3
+	UINT32		rsv2:16;
+	UINT32		SNR1:8;
+	UINT32		SNR0:8;
+}	RXWI_STRUC, *PRXWI_STRUC;
+#else
+typedef	struct	PACKED _RXWI_STRUC {
+	// Word	0
+	UINT32		WirelessCliID:8;
+	UINT32		KeyIndex:2;
+	UINT32		BSSID:3;
+	UINT32		UDF:3;
+	UINT32		MPDUtotalByteCount:12;
+	UINT32		TID:4;
+	// Word	1
+	UINT32		FRAG:4;
+	UINT32		SEQUENCE:12;
+	UINT32		MCS:7;
+	UINT32		BW:1;
+	UINT32		ShortGI:1;
+	UINT32		STBC:2;
+	UINT32		rsv:3;
+	UINT32		PHYMODE:2;              // 1: this RX frame is unicast to me
+	//Word2
+	UINT32		RSSI0:8;
+	UINT32		RSSI1:8;
+	UINT32		RSSI2:8;
+	UINT32		rsv1:8;
+	//Word3
+	UINT32		SNR0:8;
+	UINT32		SNR1:8;
+	UINT32		rsv2:16;
+}	RXWI_STRUC, *PRXWI_STRUC;
+#endif
+
+
+// =================================================================================
+// HOST-MCU communication data structure
+// =================================================================================
+
+//
+// H2M_MAILBOX_CSR: Host-to-MCU Mailbox
+//
+#ifdef RT_BIG_ENDIAN
+typedef union  _H2M_MAILBOX_STRUC {
+    struct {
+        UINT32       Owner:8;
+        UINT32       CmdToken:8;    // 0xff tells MCU not to report CmdDoneInt after excuting the command
+        UINT32       HighByte:8;
+        UINT32       LowByte:8;
+    }   field;
+    UINT32           word;
+} H2M_MAILBOX_STRUC, *PH2M_MAILBOX_STRUC;
+#else
+typedef union  _H2M_MAILBOX_STRUC {
+    struct {
+        UINT32       LowByte:8;
+        UINT32       HighByte:8;
+        UINT32       CmdToken:8;
+        UINT32       Owner:8;
+    }   field;
+    UINT32           word;
+} H2M_MAILBOX_STRUC, *PH2M_MAILBOX_STRUC;
+#endif
+
+//
+// M2H_CMD_DONE_CSR: MCU-to-Host command complete indication
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _M2H_CMD_DONE_STRUC {
+    struct  {
+        UINT32       CmdToken3;
+        UINT32       CmdToken2;
+        UINT32       CmdToken1;
+        UINT32       CmdToken0;
+    } field;
+    UINT32           word;
+} M2H_CMD_DONE_STRUC, *PM2H_CMD_DONE_STRUC;
+#else
+typedef union _M2H_CMD_DONE_STRUC {
+    struct  {
+        UINT32       CmdToken0;
+        UINT32       CmdToken1;
+        UINT32       CmdToken2;
+        UINT32       CmdToken3;
+    } field;
+    UINT32           word;
+} M2H_CMD_DONE_STRUC, *PM2H_CMD_DONE_STRUC;
+#endif
+
+
+
+//
+// MCU_LEDCS: MCU LED Control Setting.
+//
+#ifdef RT_BIG_ENDIAN
+typedef union  _MCU_LEDCS_STRUC {
+	struct	{
+		UCHAR		Polarity:1;
+		UCHAR		LedMode:7;
+	} field;
+	UCHAR				word;
+} MCU_LEDCS_STRUC, *PMCU_LEDCS_STRUC;
+#else
+typedef union  _MCU_LEDCS_STRUC {
+	struct	{
+		UCHAR		LedMode:7;
+		UCHAR		Polarity:1;
+	} field;
+	UCHAR			word;
+} MCU_LEDCS_STRUC, *PMCU_LEDCS_STRUC;
+#endif
+// =================================================================================
+// Register format
+// =================================================================================
+
+
+
+//NAV_TIME_CFG :NAV
+#ifdef RT_BIG_ENDIAN
+typedef	union	_NAV_TIME_CFG_STRUC	{
+	struct	{
+		USHORT		rsv:6;
+		USHORT		ZeroSifs:1;               // Applied zero SIFS timer after OFDM RX 0: disable
+		USHORT		Eifs:9;               // in unit of 1-us
+		UCHAR       SlotTime;    // in unit of 1-us
+		UCHAR		Sifs;               // in unit of 1-us
+	}	field;
+	UINT32			word;
+}	NAV_TIME_CFG_STRUC, *PNAV_TIME_CFG_STRUC;
+#else
+typedef	union	_NAV_TIME_CFG_STRUC	{
+	struct	{
+		UCHAR		Sifs;               // in unit of 1-us
+		UCHAR       SlotTime;    // in unit of 1-us
+		USHORT		Eifs:9;               // in unit of 1-us
+		USHORT		ZeroSifs:1;               // Applied zero SIFS timer after OFDM RX 0: disable
+		USHORT		rsv:6;
+	}	field;
+	UINT32			word;
+}	NAV_TIME_CFG_STRUC, *PNAV_TIME_CFG_STRUC;
+#endif
+
+
+
+
+
+//
+// RX_FILTR_CFG:  /RX configuration register
+//
+#ifdef RT_BIG_ENDIAN
+typedef	union	RX_FILTR_CFG_STRUC	{
+	struct	{
+		UINT32		:15;
+		UINT32       DropRsvCntlType:1;
+
+        	UINT32       	DropBAR:1;       //
+		UINT32		DropBA:1;		//
+		UINT32		DropPsPoll:1;		// Drop Ps-Poll
+		UINT32		DropRts:1;		// Drop Ps-Poll
+
+		UINT32		DropCts:1;		// Drop Ps-Poll
+		UINT32		DropAck:1;		// Drop Ps-Poll
+		UINT32		DropCFEnd:1;		// Drop Ps-Poll
+		UINT32		DropCFEndAck:1;		// Drop Ps-Poll
+
+		UINT32		DropDuplicate:1;		// Drop duplicate frame
+		UINT32		DropBcast:1;		// Drop broadcast frames
+		UINT32		DropMcast:1;		// Drop multicast frames
+		UINT32		DropVerErr:1;	    // Drop version error frame
+
+		UINT32		DropNotMyBSSID:1;			// Drop fram ToDs bit is true
+		UINT32		DropNotToMe:1;		// Drop not to me unicast frame
+		UINT32		DropPhyErr:1;		// Drop physical error
+		UINT32		DropCRCErr:1;		// Drop CRC error
+	}	field;
+	UINT32			word;
+}	RX_FILTR_CFG_STRUC, *PRX_FILTR_CFG_STRUC;
+#else
+typedef	union	_RX_FILTR_CFG_STRUC	{
+	struct	{
+		UINT32		DropCRCErr:1;		// Drop CRC error
+		UINT32		DropPhyErr:1;		// Drop physical error
+		UINT32		DropNotToMe:1;		// Drop not to me unicast frame
+		UINT32		DropNotMyBSSID:1;			// Drop fram ToDs bit is true
+
+		UINT32		DropVerErr:1;	    // Drop version error frame
+		UINT32		DropMcast:1;		// Drop multicast frames
+		UINT32		DropBcast:1;		// Drop broadcast frames
+		UINT32		DropDuplicate:1;		// Drop duplicate frame
+
+		UINT32		DropCFEndAck:1;		// Drop Ps-Poll
+		UINT32		DropCFEnd:1;		// Drop Ps-Poll
+		UINT32		DropAck:1;		// Drop Ps-Poll
+		UINT32		DropCts:1;		// Drop Ps-Poll
+
+		UINT32		DropRts:1;		// Drop Ps-Poll
+		UINT32		DropPsPoll:1;		// Drop Ps-Poll
+		UINT32		DropBA:1;		//
+        	UINT32       	DropBAR:1;       //
+
+		UINT32       	DropRsvCntlType:1;
+		UINT32		:15;
+	}	field;
+	UINT32			word;
+}	RX_FILTR_CFG_STRUC, *PRX_FILTR_CFG_STRUC;
+#endif
+
+
+
+
+//
+// PHY_CSR4: RF serial control register
+//
+#ifdef RT_BIG_ENDIAN
+typedef	union	_PHY_CSR4_STRUC	{
+	struct	{
+		UINT32		Busy:1;				// 1: ASIC is busy execute RF programming.
+		UINT32		PLL_LD:1;			// RF PLL_LD status
+		UINT32		IFSelect:1;			// 1: select IF	to program,	0: select RF to	program
+		UINT32		NumberOfBits:5;		// Number of bits used in RFRegValue (I:20,	RFMD:22)
+		UINT32		RFRegValue:24;		// Register	value (include register	id)	serial out to RF/IF	chip.
+	}	field;
+	UINT32			word;
+}	PHY_CSR4_STRUC, *PPHY_CSR4_STRUC;
+#else
+typedef	union	_PHY_CSR4_STRUC	{
+	struct	{
+		UINT32		RFRegValue:24;		// Register	value (include register	id)	serial out to RF/IF	chip.
+		UINT32		NumberOfBits:5;		// Number of bits used in RFRegValue (I:20,	RFMD:22)
+		UINT32		IFSelect:1;			// 1: select IF	to program,	0: select RF to	program
+		UINT32		PLL_LD:1;			// RF PLL_LD status
+		UINT32		Busy:1;				// 1: ASIC is busy execute RF programming.
+	}	field;
+	UINT32			word;
+}	PHY_CSR4_STRUC, *PPHY_CSR4_STRUC;
+#endif
+
+
+//
+// SEC_CSR5: shared key table security mode register
+//
+#ifdef RT_BIG_ENDIAN
+typedef	union	_SEC_CSR5_STRUC	{
+	struct	{
+        UINT32       :1;
+        UINT32       Bss3Key3CipherAlg:3;
+        UINT32       :1;
+        UINT32       Bss3Key2CipherAlg:3;
+        UINT32       :1;
+        UINT32       Bss3Key1CipherAlg:3;
+        UINT32       :1;
+        UINT32       Bss3Key0CipherAlg:3;
+        UINT32       :1;
+        UINT32       Bss2Key3CipherAlg:3;
+        UINT32       :1;
+        UINT32       Bss2Key2CipherAlg:3;
+        UINT32       :1;
+        UINT32       Bss2Key1CipherAlg:3;
+        UINT32       :1;
+        UINT32       Bss2Key0CipherAlg:3;
+	}	field;
+	UINT32			word;
+}	SEC_CSR5_STRUC, *PSEC_CSR5_STRUC;
+#else
+typedef	union	_SEC_CSR5_STRUC	{
+	struct	{
+        UINT32       Bss2Key0CipherAlg:3;
+        UINT32       :1;
+        UINT32       Bss2Key1CipherAlg:3;
+        UINT32       :1;
+        UINT32       Bss2Key2CipherAlg:3;
+        UINT32       :1;
+        UINT32       Bss2Key3CipherAlg:3;
+        UINT32       :1;
+        UINT32       Bss3Key0CipherAlg:3;
+        UINT32       :1;
+        UINT32       Bss3Key1CipherAlg:3;
+        UINT32       :1;
+        UINT32       Bss3Key2CipherAlg:3;
+        UINT32       :1;
+        UINT32       Bss3Key3CipherAlg:3;
+        UINT32       :1;
+	}	field;
+	UINT32			word;
+}	SEC_CSR5_STRUC, *PSEC_CSR5_STRUC;
+#endif
+
+
+//
+// HOST_CMD_CSR: For HOST to interrupt embedded processor
+//
+#ifdef RT_BIG_ENDIAN
+typedef	union	_HOST_CMD_CSR_STRUC	{
+	struct	{
+	    UINT32   Rsv:24;
+	    UINT32   HostCommand:8;
+	}	field;
+	UINT32			word;
+}	HOST_CMD_CSR_STRUC, *PHOST_CMD_CSR_STRUC;
+#else
+typedef	union	_HOST_CMD_CSR_STRUC	{
+	struct	{
+	    UINT32   HostCommand:8;
+	    UINT32   Rsv:24;
+	}	field;
+	UINT32			word;
+}	HOST_CMD_CSR_STRUC, *PHOST_CMD_CSR_STRUC;
+#endif
+
+
+//
+// AIFSN_CSR: AIFSN for each EDCA AC
+//
+
+
+
+//
+// E2PROM_CSR: EEPROM control register
+//
+#ifdef RT_BIG_ENDIAN
+typedef	union	_E2PROM_CSR_STRUC	{
+	struct	{
+		UINT32		Rsvd:25;
+		UINT32       LoadStatus:1;   // 1:loading, 0:done
+		UINT32		Type:1;			// 1: 93C46, 0:93C66
+		UINT32		EepromDO:1;
+		UINT32		EepromDI:1;
+		UINT32		EepromCS:1;
+		UINT32		EepromSK:1;
+		UINT32		Reload:1;		// Reload EEPROM content, write one to reload, self-cleared.
+	}	field;
+	UINT32			word;
+}	E2PROM_CSR_STRUC, *PE2PROM_CSR_STRUC;
+#else
+typedef	union	_E2PROM_CSR_STRUC	{
+	struct	{
+		UINT32		Reload:1;		// Reload EEPROM content, write one to reload, self-cleared.
+		UINT32		EepromSK:1;
+		UINT32		EepromCS:1;
+		UINT32		EepromDI:1;
+		UINT32		EepromDO:1;
+		UINT32		Type:1;			// 1: 93C46, 0:93C66
+		UINT32       LoadStatus:1;   // 1:loading, 0:done
+		UINT32		Rsvd:25;
+	}	field;
+	UINT32			word;
+}	E2PROM_CSR_STRUC, *PE2PROM_CSR_STRUC;
+#endif
+
+
+// -------------------------------------------------------------------
+//  E2PROM data layout
+// -------------------------------------------------------------------
+
+//
+// EEPROM antenna select format
+//
+#ifdef RT_BIG_ENDIAN
+typedef	union	_EEPROM_ANTENNA_STRUC	{
+	struct	{
+		USHORT      Rsv:4;
+		USHORT      RfIcType:4;             // see E2PROM document
+		USHORT		TxPath:4;	// 1: 1T, 2: 2T
+		USHORT		RxPath:4;	// 1: 1R, 2: 2R, 3: 3R
+	}	field;
+	USHORT			word;
+}	EEPROM_ANTENNA_STRUC, *PEEPROM_ANTENNA_STRUC;
+#else
+typedef	union	_EEPROM_ANTENNA_STRUC	{
+	struct	{
+		USHORT		RxPath:4;	// 1: 1R, 2: 2R, 3: 3R
+		USHORT		TxPath:4;	// 1: 1T, 2: 2T
+		USHORT      RfIcType:4;             // see E2PROM document
+		USHORT      Rsv:4;
+	}	field;
+	USHORT			word;
+}	EEPROM_ANTENNA_STRUC, *PEEPROM_ANTENNA_STRUC;
+#endif
+
+#ifdef RT_BIG_ENDIAN
+typedef	union _EEPROM_NIC_CINFIG2_STRUC	{
+	struct	{
+        USHORT		DACTestBit:1;			// control if driver should patch the DAC issue
+		USHORT		Rsv2:3;					// must be 0
+        USHORT		AntDiversity:1;			// Antenna diversity
+		USHORT		Rsv1:1;					// must be 0
+		USHORT		BW40MAvailForA:1;			// 0:enable, 1:disable
+		USHORT		BW40MAvailForG:1;			// 0:enable, 1:disable
+		USHORT		EnableWPSPBC:1;                 // WPS PBC Control bit
+		USHORT		BW40MSidebandForA:1;
+		USHORT		BW40MSidebandForG:1;
+		USHORT		CardbusAcceleration:1;	// !!! NOTE: 0 - enable, 1 - disable
+		USHORT		ExternalLNAForA:1;			// external LNA enable for 5G
+		USHORT		ExternalLNAForG:1;			// external LNA enable for 2.4G
+		USHORT		DynamicTxAgcControl:1;			//
+		USHORT		HardwareRadioControl:1;	// Whether RF is controlled by driver or HW. 1:enable hw control, 0:disable
+	}	field;
+	USHORT			word;
+}	EEPROM_NIC_CONFIG2_STRUC, *PEEPROM_NIC_CONFIG2_STRUC;
+#else
+typedef	union _EEPROM_NIC_CINFIG2_STRUC	{
+	struct {
+		USHORT		HardwareRadioControl:1;	// 1:enable, 0:disable
+		USHORT		DynamicTxAgcControl:1;			//
+		USHORT		ExternalLNAForG:1;				//
+		USHORT		ExternalLNAForA:1;			// external LNA enable for 2.4G
+		USHORT		CardbusAcceleration:1;	// !!! NOTE: 0 - enable, 1 - disable
+		USHORT		BW40MSidebandForG:1;
+		USHORT		BW40MSidebandForA:1;
+		USHORT		EnableWPSPBC:1;                 // WPS PBC Control bit
+		USHORT		BW40MAvailForG:1;			// 0:enable, 1:disable
+		USHORT		BW40MAvailForA:1;			// 0:enable, 1:disable
+		USHORT		Rsv1:1;					// must be 0
+		USHORT		AntDiversity:1;			// Antenna diversity
+		USHORT		Rsv2:3;					// must be 0
+		USHORT		DACTestBit:1;			// control if driver should patch the DAC issue
+	}	field;
+	USHORT			word;
+}	EEPROM_NIC_CONFIG2_STRUC, *PEEPROM_NIC_CONFIG2_STRUC;
+#endif
+
+//
+// TX_PWR Value valid range 0xFA(-6) ~ 0x24(36)
+//
+#ifdef RT_BIG_ENDIAN
+typedef	union	_EEPROM_TX_PWR_STRUC	{
+	struct	{
+		CHAR	Byte1;				// High Byte
+		CHAR	Byte0;				// Low Byte
+	}	field;
+	USHORT	word;
+}	EEPROM_TX_PWR_STRUC, *PEEPROM_TX_PWR_STRUC;
+#else
+typedef	union	_EEPROM_TX_PWR_STRUC	{
+	struct	{
+		CHAR	Byte0;				// Low Byte
+		CHAR	Byte1;				// High Byte
+	}	field;
+	USHORT	word;
+}	EEPROM_TX_PWR_STRUC, *PEEPROM_TX_PWR_STRUC;
+#endif
+
+#ifdef RT_BIG_ENDIAN
+typedef	union	_EEPROM_VERSION_STRUC	{
+	struct	{
+		UCHAR	Version;			// High Byte
+		UCHAR	FaeReleaseNumber;	// Low Byte
+	}	field;
+	USHORT	word;
+}	EEPROM_VERSION_STRUC, *PEEPROM_VERSION_STRUC;
+#else
+typedef	union	_EEPROM_VERSION_STRUC	{
+	struct	{
+		UCHAR	FaeReleaseNumber;	// Low Byte
+		UCHAR	Version;			// High Byte
+	}	field;
+	USHORT	word;
+}	EEPROM_VERSION_STRUC, *PEEPROM_VERSION_STRUC;
+#endif
+
+#ifdef RT_BIG_ENDIAN
+typedef	union	_EEPROM_LED_STRUC	{
+	struct	{
+		USHORT	Rsvd:3;				// Reserved
+		USHORT	LedMode:5;			// Led mode.
+		USHORT	PolarityGPIO_4:1;	// Polarity GPIO#4 setting.
+		USHORT	PolarityGPIO_3:1;	// Polarity GPIO#3 setting.
+		USHORT	PolarityGPIO_2:1;	// Polarity GPIO#2 setting.
+		USHORT	PolarityGPIO_1:1;	// Polarity GPIO#1 setting.
+		USHORT	PolarityGPIO_0:1;	// Polarity GPIO#0 setting.
+		USHORT	PolarityACT:1;		// Polarity ACT setting.
+		USHORT	PolarityRDY_A:1;		// Polarity RDY_A setting.
+		USHORT	PolarityRDY_G:1;		// Polarity RDY_G setting.
+	}	field;
+	USHORT	word;
+}	EEPROM_LED_STRUC, *PEEPROM_LED_STRUC;
+#else
+typedef	union	_EEPROM_LED_STRUC	{
+	struct	{
+		USHORT	PolarityRDY_G:1;		// Polarity RDY_G setting.
+		USHORT	PolarityRDY_A:1;		// Polarity RDY_A setting.
+		USHORT	PolarityACT:1;		// Polarity ACT setting.
+		USHORT	PolarityGPIO_0:1;	// Polarity GPIO#0 setting.
+		USHORT	PolarityGPIO_1:1;	// Polarity GPIO#1 setting.
+		USHORT	PolarityGPIO_2:1;	// Polarity GPIO#2 setting.
+		USHORT	PolarityGPIO_3:1;	// Polarity GPIO#3 setting.
+		USHORT	PolarityGPIO_4:1;	// Polarity GPIO#4 setting.
+		USHORT	LedMode:5;			// Led mode.
+		USHORT	Rsvd:3;				// Reserved
+	}	field;
+	USHORT	word;
+}	EEPROM_LED_STRUC, *PEEPROM_LED_STRUC;
+#endif
+
+#ifdef RT_BIG_ENDIAN
+typedef	union	_EEPROM_TXPOWER_DELTA_STRUC	{
+	struct	{
+		UCHAR	TxPowerEnable:1;// Enable
+		UCHAR	Type:1;			// 1: plus the delta value, 0: minus the delta value
+		UCHAR	DeltaValue:6;	// Tx Power dalta value (MAX=4)
+	}	field;
+	UCHAR	value;
+}	EEPROM_TXPOWER_DELTA_STRUC, *PEEPROM_TXPOWER_DELTA_STRUC;
+#else
+typedef	union	_EEPROM_TXPOWER_DELTA_STRUC	{
+	struct	{
+		UCHAR	DeltaValue:6;	// Tx Power dalta value (MAX=4)
+		UCHAR	Type:1;			// 1: plus the delta value, 0: minus the delta value
+		UCHAR	TxPowerEnable:1;// Enable
+	}	field;
+	UCHAR	value;
+}	EEPROM_TXPOWER_DELTA_STRUC, *PEEPROM_TXPOWER_DELTA_STRUC;
+#endif
+
+//
+// QOS_CSR0: TXOP holder address0 register
+//
+#ifdef RT_BIG_ENDIAN
+typedef	union	_QOS_CSR0_STRUC	{
+	struct	{
+		UCHAR		Byte3;		// MAC address byte 3
+		UCHAR		Byte2;		// MAC address byte 2
+		UCHAR		Byte1;		// MAC address byte 1
+		UCHAR		Byte0;		// MAC address byte 0
+	}	field;
+	UINT32			word;
+}	QOS_CSR0_STRUC, *PQOS_CSR0_STRUC;
+#else
+typedef	union	_QOS_CSR0_STRUC	{
+	struct	{
+		UCHAR		Byte0;		// MAC address byte 0
+		UCHAR		Byte1;		// MAC address byte 1
+		UCHAR		Byte2;		// MAC address byte 2
+		UCHAR		Byte3;		// MAC address byte 3
+	}	field;
+	UINT32			word;
+}	QOS_CSR0_STRUC, *PQOS_CSR0_STRUC;
+#endif
+
+//
+// QOS_CSR1: TXOP holder address1 register
+//
+#ifdef RT_BIG_ENDIAN
+typedef	union	_QOS_CSR1_STRUC	{
+	struct	{
+		UCHAR		Rsvd1;
+		UCHAR		Rsvd0;
+		UCHAR		Byte5;		// MAC address byte 5
+		UCHAR		Byte4;		// MAC address byte 4
+	}	field;
+	UINT32			word;
+}	QOS_CSR1_STRUC, *PQOS_CSR1_STRUC;
+#else
+typedef	union	_QOS_CSR1_STRUC	{
+	struct	{
+		UCHAR		Byte4;		// MAC address byte 4
+		UCHAR		Byte5;		// MAC address byte 5
+		UCHAR		Rsvd0;
+		UCHAR		Rsvd1;
+	}	field;
+	UINT32			word;
+}	QOS_CSR1_STRUC, *PQOS_CSR1_STRUC;
+#endif
+
+#define	RF_CSR_CFG	0x500
+#ifdef RT_BIG_ENDIAN
+typedef	union	_RF_CSR_CFG_STRUC	{
+	struct	{
+		UINT	Rsvd1:14;				// Reserved
+		UINT	RF_CSR_KICK:1;			// kick RF register read/write
+		UINT	RF_CSR_WR:1;			// 0: read  1: write
+		UINT	Rsvd2:3;				// Reserved
+		UINT	TESTCSR_RFACC_REGNUM:5;	// RF register ID
+		UINT	RF_CSR_DATA:8;			// DATA
+	}	field;
+	UINT	word;
+}	RF_CSR_CFG_STRUC, *PRF_CSR_CFG_STRUC;
+#else
+typedef	union	_RF_CSR_CFG_STRUC	{
+	struct	{
+		UINT	RF_CSR_DATA:8;			// DATA
+		UINT	TESTCSR_RFACC_REGNUM:5;	// RF register ID
+		UINT	Rsvd2:3;				// Reserved
+		UINT	RF_CSR_WR:1;			// 0: read  1: write
+		UINT	RF_CSR_KICK:1;			// kick RF register read/write
+		UINT	Rsvd1:14;				// Reserved
+	}	field;
+	UINT	word;
+}	RF_CSR_CFG_STRUC, *PRF_CSR_CFG_STRUC;
+#endif
+
+#endif	// __RT28XX_H__
diff --git a/drivers/staging/rt3070/rt_ate.c b/drivers/staging/rt3070/rt_ate.c
new file mode 100644
index 0000000..9238d96
--- /dev/null
+++ b/drivers/staging/rt3070/rt_ate.c
@@ -0,0 +1,6506 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+ */
+
+#include "rt_config.h"
+
+#ifdef UCOS
+INT IoctlResponse(PUCHAR payload, PUCHAR msg, INT len);
+#endif // UCOS //
+
+#define ATE_BBP_REG_NUM	168
+UCHAR restore_BBP[ATE_BBP_REG_NUM]={0};
+
+#ifdef RALINK_ATE
+UCHAR TemplateFrame[24] = {0x08/* Data type */,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0xAA,0xBB,0x12,0x34,0x56,0x00,0x11,0x22,0xAA,0xBB,0xCC,0x00,0x00};	// 802.11 MAC Header, Type:Data, Length:24bytes
+extern RTMP_RF_REGS RF2850RegTable[];
+extern UCHAR NUM_OF_2850_CHNL;
+
+#ifdef RT2870
+extern UCHAR EpToQueue[];
+extern VOID	RTUSBRejectPendingPackets(	IN	PRTMP_ADAPTER	pAd);
+#endif // RT2870 //
+
+#ifdef RT30xx
+//2008/07/10:KH adds to support 3070 ATE<--
+extern FREQUENCY_ITEM FreqItems3020[];
+extern UCHAR NUM_OF_3020_CHNL;
+//2008/07/10:KH adds to support 3070 ATE-->
+#endif // RT30xx //
+
+#ifdef UCOS
+extern INT ConsoleResponse(IN PUCHAR buff);
+extern int (*remote_display)(char *);
+#endif // UCOS //
+
+static CHAR CCKRateTable[] = {0, 1, 2, 3, 8, 9, 10, 11, -1}; /* CCK Mode. */
+static CHAR OFDMRateTable[] = {0, 1, 2, 3, 4, 5, 6, 7, -1}; /* OFDM Mode. */
+static CHAR HTMIXRateTable[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}; /* HT Mix Mode. */
+
+static INT TxDmaBusy(
+	IN PRTMP_ADAPTER pAd);
+
+static INT RxDmaBusy(
+	IN PRTMP_ADAPTER pAd);
+
+static VOID RtmpDmaEnable(
+	IN PRTMP_ADAPTER pAd,
+	IN INT Enable);
+
+static VOID BbpSoftReset(
+	IN PRTMP_ADAPTER pAd);
+
+static VOID RtmpRfIoWrite(
+	IN PRTMP_ADAPTER pAd);
+
+static INT ATESetUpFrame(
+	IN PRTMP_ADAPTER pAd,
+	IN UINT32 TxIdx);
+
+static INT ATETxPwrHandler(
+	IN PRTMP_ADAPTER pAd,
+	IN char index);
+
+static INT ATECmdHandler(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+static int CheckMCSValid(
+	IN UCHAR Mode,
+	IN UCHAR Mcs);
+
+
+#ifdef RT2870
+static VOID ATEWriteTxInfo(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PTXINFO_STRUC 	pTxInfo,
+	IN	  USHORT		USBDMApktLen,
+	IN	  BOOLEAN		bWiv,
+	IN	  UCHAR			QueueSel,
+	IN	  UCHAR			NextValid,
+	IN	  UCHAR			TxBurst);
+
+static VOID ATEWriteTxWI(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PTXWI_STRUC 	pTxWI,
+	IN	BOOLEAN			FRAG,
+	IN	BOOLEAN			InsTimestamp,
+	IN	BOOLEAN 		AMPDU,
+	IN	BOOLEAN 		Ack,
+	IN	BOOLEAN 		NSeq,		// HW new a sequence.
+	IN	UCHAR			BASize,
+	IN	UCHAR			WCID,
+	IN	ULONG			Length,
+	IN	UCHAR 			PID,
+	IN	UCHAR			MIMOps,
+	IN	UCHAR			Txopmode,
+	IN	BOOLEAN			CfAck,
+	IN	HTTRANSMIT_SETTING	Transmit);
+
+#endif // RT2870 //
+
+static VOID SetJapanFilter(
+	IN	PRTMP_ADAPTER	pAd);
+
+/*=========================end of prototype=========================*/
+
+
+#ifdef RT2870
+static INT TxDmaBusy(
+	IN PRTMP_ADAPTER pAd)
+{
+	INT result;
+	USB_DMA_CFG_STRUC UsbCfg;
+
+	RTMP_IO_READ32(pAd, USB_DMA_CFG, &UsbCfg.word);	// disable DMA
+	if (UsbCfg.field.TxBusy)
+		result = 1;
+	else
+		result = 0;
+
+	return result;
+}
+
+static INT RxDmaBusy(
+	IN PRTMP_ADAPTER pAd)
+{
+	INT result;
+	USB_DMA_CFG_STRUC UsbCfg;
+
+	RTMP_IO_READ32(pAd, USB_DMA_CFG, &UsbCfg.word);	// disable DMA
+	if (UsbCfg.field.RxBusy)
+		result = 1;
+	else
+		result = 0;
+
+	return result;
+}
+
+static VOID RtmpDmaEnable(
+	IN PRTMP_ADAPTER pAd,
+	IN INT Enable)
+{
+	BOOLEAN value;
+	ULONG WaitCnt;
+	USB_DMA_CFG_STRUC UsbCfg;
+
+	value = Enable > 0 ? 1 : 0;
+
+	// check DMA is in busy mode.
+	WaitCnt = 0;
+	while (TxDmaBusy(pAd) || RxDmaBusy(pAd))
+	{
+		RTMPusecDelay(10);
+		if (WaitCnt++ > 100)
+			break;
+	}
+
+	//Why not to clear USB DMA TX path first ???
+	RTMP_IO_READ32(pAd, USB_DMA_CFG, &UsbCfg.word);	// disable DMA
+	UsbCfg.field.TxBulkEn = value;
+	UsbCfg.field.RxBulkEn = value;
+	RTMP_IO_WRITE32(pAd, USB_DMA_CFG, UsbCfg.word);	// abort all TX rings
+	RTMPusecDelay(5000);
+
+	return;
+}
+#endif // RT2870 //
+
+static VOID BbpSoftReset(
+	IN PRTMP_ADAPTER pAd)
+{
+	UCHAR BbpData = 0;
+
+	// Soft reset, set BBP R21 bit0=1->0
+	ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R21, &BbpData);
+	BbpData |= 0x00000001; //set bit0=1
+	ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21, BbpData);
+
+	ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R21, &BbpData);
+	BbpData &= ~(0x00000001); //set bit0=0
+	ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21, BbpData);
+
+	return;
+}
+
+static VOID RtmpRfIoWrite(
+	IN PRTMP_ADAPTER pAd)
+{
+	// Set RF value 1's set R3[bit2] = [0]
+	RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
+	RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
+	RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
+	RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
+
+	RTMPusecDelay(200);
+
+	// Set RF value 2's set R3[bit2] = [1]
+	RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
+	RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
+	RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04));
+	RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
+
+	RTMPusecDelay(200);
+
+	// Set RF value 3's set R3[bit2] = [0]
+	RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
+	RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
+	RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
+	RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
+
+	return;
+}
+
+static int CheckMCSValid(
+	UCHAR Mode,
+	UCHAR Mcs)
+{
+	int i;
+	PCHAR pRateTab;
+
+	switch(Mode)
+	{
+		case 0:
+			pRateTab = CCKRateTable;
+			break;
+		case 1:
+			pRateTab = OFDMRateTable;
+			break;
+		case 2:
+		case 3:
+			pRateTab = HTMIXRateTable;
+			break;
+		default:
+			ATEDBGPRINT(RT_DEBUG_ERROR, ("unrecognizable Tx Mode %d\n", Mode));
+			return -1;
+			break;
+	}
+
+	i = 0;
+	while(pRateTab[i] != -1)
+	{
+		if (pRateTab[i] == Mcs)
+			return 0;
+		i++;
+	}
+
+	return -1;
+}
+
+#if 1
+static INT ATETxPwrHandler(
+	IN PRTMP_ADAPTER pAd,
+	IN char index)
+{
+	ULONG R;
+	CHAR TxPower;
+	UCHAR Bbp94 = 0;
+	BOOLEAN bPowerReduce = FALSE;
+#ifdef RT30xx
+	UCHAR RFValue;
+#endif // RT30xx //
+#ifdef RALINK_28xx_QA
+	if ((pAd->ate.bQATxStart == TRUE) || (pAd->ate.bQARxStart == TRUE))
+	{
+		/* When QA is used for Tx, pAd->ate.TxPower0/1 and real tx power
+		** are not synchronized.
+		*/
+/*
+		pAd->ate.TxPower0 = pAd->LatchRfRegs.xxx;
+		pAd->ate.TxPower1 = pAd->LatchRfRegs.xxx;
+*/
+		return 0;
+	}
+	else
+#endif // RALINK_28xx_QA //
+	{
+		TxPower = index == 0 ? pAd->ate.TxPower0 : pAd->ate.TxPower1;
+
+		if (pAd->ate.Channel <= 14)
+		{
+			if (TxPower > 31)
+			{
+				//
+				// R3, R4 can't large than 31 (0x24), 31 ~ 36 used by BBP 94
+				//
+				R = 31;
+				if (TxPower <= 36)
+					Bbp94 = BBPR94_DEFAULT + (UCHAR)(TxPower - 31);
+			}
+			else if (TxPower < 0)
+			{
+				//
+				// R3, R4 can't less than 0, -1 ~ -6 used by BBP 94
+				//
+				R = 0;
+				if (TxPower >= -6)
+					Bbp94 = BBPR94_DEFAULT + TxPower;
+			}
+			else
+			{
+				// 0 ~ 31
+				R = (ULONG) TxPower;
+				Bbp94 = BBPR94_DEFAULT;
+			}
+
+			ATEDBGPRINT(RT_DEBUG_TRACE, ("%s (TxPower=%d, R=%ld, BBP_R94=%d)\n", __FUNCTION__, TxPower, R, Bbp94));
+		}
+		else// 5.5 GHz
+		{
+			if (TxPower > 15)
+			{
+				//
+				// R3, R4 can't large than 15 (0x0F)
+				//
+				R = 15;
+			}
+			else if (TxPower < 0)
+			{
+				//
+				// R3, R4 can't less than 0
+				//
+				// -1 ~ -7
+				ASSERT((TxPower >= -7));
+				R = (ULONG)(TxPower + 7);
+				bPowerReduce = TRUE;
+			}
+			else
+			{
+				// 0 ~ 15
+				R = (ULONG) TxPower;
+			}
+
+			ATEDBGPRINT(RT_DEBUG_TRACE, ("%s (TxPower=%d, R=%lu)\n", __FUNCTION__, TxPower, R));
+		}
+//2008/09/10:KH adds to support 3070 ATE TX Power tunning real time<--
+#ifdef RT30xx
+		if(IS_RT30xx(pAd))
+		{
+			// Set Tx Power
+
+					RT30xxReadRFRegister(pAd, RF_R12, (PUCHAR)&RFValue);
+					RFValue = (RFValue & 0xE0) | TxPower;
+					RT30xxWriteRFRegister(pAd, RF_R12, (UCHAR)RFValue);
+					ATEDBGPRINT(RT_DEBUG_TRACE, ("3070 or 2070:%s (TxPower=%d, RFValue=%x)\n", __FUNCTION__, TxPower, RFValue));
+
+		}
+		else
+#endif // RT30xx //
+	      {
+		if (pAd->ate.Channel <= 14)
+		{
+			if (index == 0)
+			{
+				R = R << 9;		// shift TX power control to correct RF(R3) register bit position
+				R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
+				pAd->LatchRfRegs.R3 = R;
+			}
+			else
+			{
+				R = R << 6;		// shift TX power control to correct RF(R4) register bit position
+				R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
+				pAd->LatchRfRegs.R4 = R;
+			}
+		}
+		else// 5.5GHz
+		{
+			if (bPowerReduce == FALSE)
+			{
+				if (index == 0)
+				{
+					R = (R << 10) | (1 << 9);		// shift TX power control to correct RF(R3) register bit position
+					R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
+					pAd->LatchRfRegs.R3 = R;
+				}
+				else
+				{
+					R = (R << 7) | (1 << 6);		// shift TX power control to correct RF(R4) register bit position
+					R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
+					pAd->LatchRfRegs.R4 = R;
+				}
+			}
+			else
+			{
+				if (index == 0)
+				{
+					R = (R << 10);		// shift TX power control to correct RF(R3) register bit position
+					R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
+
+					/* Clear bit 9 of R3 to reduce 7dB. */
+					pAd->LatchRfRegs.R3 = (R & (~(1 << 9)));
+				}
+				else
+				{
+					R = (R << 7);		// shift TX power control to correct RF(R4) register bit position
+					R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
+
+					/* Clear bit 6 of R4 to reduce 7dB. */
+					pAd->LatchRfRegs.R4 = (R & (~(1 << 6)));
+				}
+			}
+		}
+		RtmpRfIoWrite(pAd);
+           }
+//2008/09/10:KH adds to support 3070 ATE TX Power tunning real time-->
+
+		return 0;
+	}
+}
+#else// 1 //
+static INT ATETxPwrHandler(
+	IN PRTMP_ADAPTER pAd,
+	IN char index)
+{
+	ULONG R;
+	CHAR TxPower;
+	UCHAR Bbp94 = 0;
+
+#ifdef RALINK_28xx_QA
+	if ((pAd->ate.bQATxStart == TRUE) || (pAd->ate.bQARxStart == TRUE))
+	{
+		// TODO: how to get current TxPower0/1 from pAd->LatchRfRegs ?
+		/* When QA is used for Tx, pAd->ate.TxPower0/1 and real tx power
+		** are not synchronized.
+		*/
+/*
+		pAd->ate.TxPower0 = pAd->LatchRfRegs.xxx;
+		pAd->ate.TxPower1 = pAd->LatchRfRegs.xxx;
+*/
+		return 0;
+	}
+	else
+#endif // RALINK_28xx_QA //
+	{
+		TxPower = index == 0 ? pAd->ate.TxPower0 : pAd->ate.TxPower1;
+
+	if (TxPower > 31)
+	{
+		//
+		// R3, R4 can't large than 36 (0x24), 31 ~ 36 used by BBP 94
+		//
+		R = 31;
+		if (TxPower <= 36)
+			Bbp94 = BBPR94_DEFAULT + (UCHAR)(TxPower - 31);
+	}
+	else if (TxPower < 0)
+	{
+		//
+		// R3, R4 can't less than 0, -1 ~ -6 used by BBP 94
+		//
+		R = 0;
+		if (TxPower >= -6)
+			Bbp94 = BBPR94_DEFAULT + TxPower;
+	}
+	else
+	{
+		// 0 ~ 31
+		R = (ULONG) TxPower;
+		Bbp94 = BBPR94_DEFAULT;
+	}
+
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("%s (TxPower=%d, R3=%ld, BBP_R94=%d)\n", __FUNCTION__, TxPower, R, Bbp94));
+
+		if (pAd->ate.Channel <= 14)
+		{
+	if (index == 0)
+	{
+		R = R << 9;		// shift TX power control to correct RF(R3) register bit position
+		R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
+		pAd->LatchRfRegs.R3 = R;
+	}
+	else
+	{
+		R = R << 6;		// shift TX power control to correct RF(R4) register bit position
+		R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
+		pAd->LatchRfRegs.R4 = R;
+	}
+		}
+		else
+		{
+			if (index == 0)
+			{
+				R = (R << 10) | (1 << 9);		// shift TX power control to correct RF(R3) register bit position
+				R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
+				pAd->LatchRfRegs.R3 = R;
+			}
+			else
+			{
+				R = (R << 7) | (1 << 6);		// shift TX power control to correct RF(R4) register bit position
+				R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
+				pAd->LatchRfRegs.R4 = R;
+			}
+		}
+
+	RtmpRfIoWrite(pAd);
+
+	return 0;
+	}
+}
+#endif // 1 //
+/*
+    ==========================================================================
+    Description:
+        Set ATE operation mode to
+        0. ATESTART  = Start ATE Mode
+        1. ATESTOP   = Stop ATE Mode
+        2. TXCONT    = Continuous Transmit
+        3. TXCARR    = Transmit Carrier
+        4. TXFRAME   = Transmit Frames
+        5. RXFRAME   = Receive Frames
+#ifdef RALINK_28xx_QA
+        6. TXSTOP    = Stop Any Type of Transmition
+        7. RXSTOP    = Stop Receiving Frames
+#endif // RALINK_28xx_QA //
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+/*                                                           */
+/*                                                           */
+/*=======================End of RT2860=======================*/
+
+
+/*======================Start of RT2870======================*/
+/*                                                           */
+/*                                                           */
+
+#ifdef RT2870
+static INT	ATECmdHandler(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	UINT32			Value;
+	UCHAR			BbpData;
+	UINT32          MacData;
+	UINT			i=0, atemode;
+	//NDIS_STATUS		Status = NDIS_STATUS_SUCCESS;
+	//PUCHAR			pDest;
+	UINT32 			temp;
+	ULONG			IrqFlags;
+
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("===> ATECmdHandler()\n"));
+	ATEAsicSwitchChannel(pAd);
+	/* AsicLockChannel() is empty function so far in fact */
+	AsicLockChannel(pAd, pAd->ate.Channel);
+
+	RTMPusecDelay(5000);
+
+	// Default value in BBP R22 is 0x0.
+	BbpData = 0;
+
+	/* Enter ATE mode and set Tx/Rx Idle */
+	if (!strcmp(arg, "ATESTART"))
+	{
+#ifdef CONFIG_STA_SUPPORT
+		BOOLEAN       Cancelled;
+#endif // CONFIG_STA_SUPPORT //
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: ATESTART\n"));
+
+		netif_stop_queue(pAd->net_dev);
+
+		atemode = pAd->ate.Mode;
+		pAd->ate.Mode = ATE_START;
+//		pAd->ate.TxDoneCount = pAd->ate.TxCount;
+		// Disable Rx
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+		Value &= ~(1 << 3);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+		// Disable auto responder
+		RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &temp);
+		temp = temp & 0xFFFFFFFE;
+		RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, temp);
+
+		// read MAC_SYS_CTRL and backup MAC_SYS_CTRL value.
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+		// clean bit4 to stop continuous Tx production test.
+		MacData &= 0xFFFFFFEF;
+		// Stop continuous TX production test.
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);//disable or cancel pending irp first ???
+
+        if (atemode & ATE_TXCARR
+#ifdef RT30xx
+ || atemode & ATE_TXCONT
+#endif // RT30xx //
+)
+		{
+#ifdef RT30xx
+			//Hardware Reset BBP
+			RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &temp);
+			temp = temp |0x00000002;
+			RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, temp);
+			RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &temp);
+			temp = temp & ~(0x00000002);
+			RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, temp);
+			//Restore All BBP Value
+			for(i=0;i<ATE_BBP_REG_NUM;i++)
+			ATE_BBP_IO_WRITE8_BY_REG_ID(pAd,i,restore_BBP[i]);
+#endif // RT30xx //
+
+			// No Carrier Test set BBP R22 bit7=0, bit6=0, bit[5~0]=0x0
+			ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+			BbpData &= 0xFFFFFF00; //clear bit7, bit6, bit[5~0]
+		    ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+		}
+		else if (atemode & ATE_TXCARRSUPP)
+		{
+#ifdef RT30xx
+			//Hardware Reset BBP
+			RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &temp);
+			temp = temp |0x00000002;
+			RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, temp);
+			RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &temp);
+			temp = temp & ~(0x00000002);
+			RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, temp);
+			//Restore All BBP Value
+			for(i=0;i<ATE_BBP_REG_NUM;i++)
+			ATE_BBP_IO_WRITE8_BY_REG_ID(pAd,i,restore_BBP[i]);
+#endif // RT30xx //
+
+			// No Cont. TX set BBP R22 bit7=0
+			ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+			BbpData &= ~(1 << 7); //set bit7=0
+			ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+
+			// No Carrier Suppression set BBP R24 bit0=0
+			ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R24, &BbpData);
+			BbpData &= 0xFFFFFFFE; //clear bit0
+		    ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, BbpData);
+		}
+		// We should free some resource which allocate when ATE_TXFRAME , ATE_STOP, and ATE_TXCONT.
+		// TODO:Should we free some resource which was allocated when LoopBack and ATE_STOP ?
+		else if ((atemode & ATE_TXFRAME) || (atemode == ATE_STOP))
+		{
+			if (atemode & ATE_TXCONT)
+			{
+				// Not Cont. TX anymore, so set BBP R22 bit7=0
+				ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+				BbpData &= ~(1 << 7); //set bit7=0
+				ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+			}
+			// Abort Tx, Rx DMA.
+			RtmpDmaEnable(pAd, 0);
+
+			{
+				// It seems nothing to free,
+				// because we didn't allocate any resource when we entered ATE_TXFRAME mode latestly.
+			}
+
+			// Start Tx, RX DMA
+			RtmpDmaEnable(pAd, 1);
+		}
+
+		RTUSBRejectPendingPackets(pAd);
+		RTUSBCleanUpDataBulkOutQueue(pAd);
+
+#ifdef CONFIG_STA_SUPPORT
+		//
+		// It will be called in MlmeSuspend().
+		//
+		// Cancel pending timers
+		RTMPCancelTimer(&pAd->MlmeAux.AssocTimer,     &Cancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer,   &Cancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer,   &Cancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.AuthTimer,       &Cancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer,     &Cancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.ScanTimer,       &Cancelled);
+#endif // CONFIG_STA_SUPPORT //
+
+		//RTUSBCleanUpMLMEWaitQueue(pAd);	/* not used in RT28xx */
+		RTUSBCleanUpMLMEBulkOutQueue(pAd);
+
+		// Sometimes kernel will hang on, so we avoid calling MlmeSuspend().
+//		MlmeSuspend(pAd, TRUE);
+		//RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled);
+
+		// Disable Rx
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+		Value &= ~(1 << 3);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+		// Abort Tx, RX DMA.
+		RtmpDmaEnable(pAd, 0);
+
+		// Disable Tx
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+		Value &= ~(1 << 2);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+		// Make sure there are no pending bulk in/out IRPs before we go on.
+/*=========================================================================*/
+		/* pAd->PendingRx is not of type atomic_t anymore in 28xx */
+//		while ((atomic_read(&pAd->PendingRx) > 0))	//pAd->BulkFlags != 0 wait bulk out finish
+		while ((pAd->PendingRx > 0))	//pAd->BulkFlags != 0 wait bulk out finish
+		{
+#if 1
+			ATE_RTUSBCancelPendingBulkInIRP(pAd);
+#else
+			NdisInterlockedDecrement(&pAd->PendingRx);
+#endif
+			/* delay 0.5 seconds */
+			RTMPusecDelay(500000);
+			pAd->PendingRx = 0;
+		}
+		/* peter : why don't we have to get BulkOutLock first ? */
+		while (((pAd->BulkOutPending[0] == TRUE) ||
+				(pAd->BulkOutPending[1] == TRUE) ||
+				(pAd->BulkOutPending[2] == TRUE) ||
+				(pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0))	//pAd->BulkFlags != 0 wait bulk out finish
+		{
+			do
+			{
+				/* pAd->BulkOutPending[y] will be set to FALSE in RTUSBCancelPendingBulkOutIRP(pAd) */
+				RTUSBCancelPendingBulkOutIRP(pAd);
+			} while (FALSE);
+
+			/* we have enough time delay in RTUSBCancelPendingBulkOutIRP(pAd)
+			** so this is not necessary
+			*/
+//			RTMPusecDelay(500000);
+		}
+
+		/* pAd->PendingRx is not of type atomic_t anymore in 28xx */
+//		ASSERT(atomic_read(&pAd->PendingRx) == 0);
+		ASSERT(pAd->PendingRx == 0);
+/*=========================================================================*/
+
+		// reset Rx statistics.
+		pAd->ate.LastSNR0 = 0;
+		pAd->ate.LastSNR1 = 0;
+		pAd->ate.LastRssi0 = 0;
+		pAd->ate.LastRssi1 = 0;
+		pAd->ate.LastRssi2 = 0;
+		pAd->ate.AvgRssi0 = 0;
+		pAd->ate.AvgRssi1 = 0;
+		pAd->ate.AvgRssi2 = 0;
+		pAd->ate.AvgRssi0X8 = 0;
+		pAd->ate.AvgRssi1X8 = 0;
+		pAd->ate.AvgRssi2X8 = 0;
+		pAd->ate.NumOfAvgRssiSample = 0;
+
+#ifdef RALINK_28xx_QA
+		// Tx frame
+		pAd->ate.bQATxStart = FALSE;
+		pAd->ate.bQARxStart = FALSE;
+		pAd->ate.seq = 0;
+
+		// counters
+		pAd->ate.U2M = 0;
+		pAd->ate.OtherData = 0;
+		pAd->ate.Beacon = 0;
+		pAd->ate.OtherCount = 0;
+		pAd->ate.TxAc0 = 0;
+		pAd->ate.TxAc1 = 0;
+		pAd->ate.TxAc2 = 0;
+		pAd->ate.TxAc3 = 0;
+		pAd->ate.TxHCCA = 0;
+		pAd->ate.TxMgmt = 0;
+		pAd->ate.RSSI0 = 0;
+		pAd->ate.RSSI1 = 0;
+		pAd->ate.RSSI2 = 0;
+		pAd->ate.SNR0 = 0;
+		pAd->ate.SNR1 = 0;
+
+		// control
+		pAd->ate.TxDoneCount = 0;
+		pAd->ate.TxStatus = 0; // task Tx status // 0 --> task is idle, 1 --> task is running
+#endif // RALINK_28xx_QA //
+
+		// Soft reset BBP.
+		BbpSoftReset(pAd);
+
+
+#ifdef CONFIG_STA_SUPPORT
+		AsicDisableSync(pAd);
+
+		/*
+		** If we skip "LinkDown()", we should disable protection
+		** to prevent from sending out RTS or CTS-to-self.
+		*/
+		ATEDisableAsicProtect(pAd);
+		RTMPStationStop(pAd);
+#endif // CONFIG_STA_SUPPORT //
+
+		// Default value in BBP R22 is 0x0.
+		BbpData = 0;
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+
+		// Clean bit4 to stop continuous Tx production test.
+		MacData &= 0xFFFFFFEF;
+	   	ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+	    	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+		//Clean ATE Bulk in/out counter and continue setup
+		InterlockedExchange(&pAd->BulkOutRemained, 0);
+
+		/* NdisAcquireSpinLock()/NdisReleaseSpinLock() need only one argument in RT28xx */
+		NdisAcquireSpinLock(&pAd->GenericLock);
+		pAd->ContinBulkOut = FALSE;
+		pAd->ContinBulkIn = FALSE;
+		NdisReleaseSpinLock(&pAd->GenericLock);
+
+		RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+	}
+	else if (!strcmp(arg, "ATESTOP"))
+	{
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE : ATESTOP ===>\n"));
+
+		// Default value in BBP R22 is 0x0.
+		BbpData = 0;
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);//0820
+		// Clean bit4 to stop continuous Tx production test.
+		MacData &= 0xFFFFFFEF;
+		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); // recover the MAC_SYS_CTRL register back.
+
+		// Disable Rx
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+		Value &= ~(1 << 3);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+		/*
+		** Abort Tx, RX DMA.
+		** Q   : How to do the following I/O if Tx, Rx DMA is aborted ?
+		** Ans : Bulk endpoints are aborted, while the control endpoint is not.
+		*/
+		RtmpDmaEnable(pAd, 0);
+
+		// Disable Tx
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+		Value &= ~(1 << 2);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+		/* Make sure there are no pending bulk in/out IRPs before we go on. */
+/*=========================================================================*/
+//		while ((atomic_read(&pAd->PendingRx) > 0))	//pAd->BulkFlags != 0 wait bulk out finish
+		while (pAd->PendingRx > 0)
+		{
+#if 1
+			ATE_RTUSBCancelPendingBulkInIRP(pAd);
+#else
+//			NdisInterlockedDecrement(&pAd->PendingRx);
+			pAd->PendingRx--;
+#endif
+			RTMPusecDelay(500000);
+		}
+
+		while (((pAd->BulkOutPending[0] == TRUE) ||
+				(pAd->BulkOutPending[1] == TRUE) ||
+				(pAd->BulkOutPending[2] == TRUE) ||
+				(pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0))	//pAd->BulkFlags != 0 wait bulk out finish
+		{
+			do
+			{
+				RTUSBCancelPendingBulkOutIRP(pAd);
+			} while (FALSE);
+
+			RTMPusecDelay(500000);
+		}
+
+//		ASSERT(atomic_read(&pAd->PendingRx) == 0);
+		ASSERT(pAd->PendingRx == 0);
+/*=========================================================================*/
+/*      Reset Rx RING                                                      */
+/*=========================================================================*/
+//		InterlockedExchange(&pAd->PendingRx, 0);
+		pAd->PendingRx = 0;
+		pAd->NextRxBulkInReadIndex = 0;	// Next Rx Read index
+		pAd->NextRxBulkInIndex = RX_RING_SIZE - 1;	// Rx Bulk pointer
+		pAd->NextRxBulkInPosition = 0;
+		for (i = 0; i < (RX_RING_SIZE); i++)
+		{
+			PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
+			NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE);
+			/* peter : why don't we have to get BulkInLock first ? */
+			pRxContext->pAd	= pAd;
+			pRxContext->pIrp = NULL;
+            /* peter debug ++ */
+			pRxContext->BulkInOffset = 0;
+			pRxContext->bRxHandling = FALSE;
+            /* peter debug -- */
+			pRxContext->InUse		= FALSE;
+			pRxContext->IRPPending	= FALSE;
+			pRxContext->Readable	= FALSE;
+//			pRxContext->ReorderInUse = FALSE;
+//			pRxContext->ReadPosOffset = 0;
+		}
+
+/*=========================================================================*/
+/*      Reset Tx RING                                                      */
+/*=========================================================================*/
+		do
+		{
+			RTUSBCancelPendingBulkOutIRP(pAd);
+		} while (FALSE);
+
+/*=========================================================================*/
+		// Enable auto responder.
+		RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &temp);
+		temp = temp | (0x01);
+		RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, temp);
+
+/*================================================*/
+		AsicEnableBssSync(pAd);
+
+		/* Soft reset BBP.*/
+		/* In 2870 chipset, ATE_BBP_IO_READ8_BY_REG_ID() == RTMP_BBP_IO_READ8_BY_REG_ID() */
+		/* Both rt2870ap and rt2870sta use BbpSoftReset(pAd) to do BBP soft reset */
+		BbpSoftReset(pAd);
+/*================================================*/
+		{
+#ifdef CONFIG_STA_SUPPORT
+			// Set all state machines back IDLE
+			pAd->Mlme.CntlMachine.CurrState    = CNTL_IDLE;
+			pAd->Mlme.AssocMachine.CurrState   = ASSOC_IDLE;
+			pAd->Mlme.AuthMachine.CurrState    = AUTH_REQ_IDLE;
+			pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE;
+			pAd->Mlme.SyncMachine.CurrState    = SYNC_IDLE;
+			pAd->Mlme.ActMachine.CurrState    = ACT_IDLE;
+#endif // CONFIG_STA_SUPPORT //
+
+			//
+			// ===> refer to MlmeRestartStateMachine().
+			// When we entered ATE_START mode, PeriodicTimer was not cancelled.
+			// So we don't have to set it here.
+			//
+			//RTMPSetTimer(pAd, &pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
+
+			ASSERT(pAd->CommonCfg.Channel != 0);
+
+			AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+			AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+
+
+#ifdef CONFIG_STA_SUPPORT
+		    RTMPStationStart(pAd);
+#endif // CONFIG_STA_SUPPORT //
+		}
+//
+// These two steps have been done when entering ATE_STOP mode.
+//
+		// Clean ATE Bulk in/out counter and continue setup.
+		InterlockedExchange(&pAd->BulkOutRemained, 0);
+		NdisAcquireSpinLock(&pAd->GenericLock);
+		pAd->ContinBulkOut = FALSE;
+		pAd->ContinBulkIn = FALSE;
+		NdisReleaseSpinLock(&pAd->GenericLock);
+
+		/* Wait 50ms to prevent next URB to bulkout during HW reset. */
+		/* todo : remove this if not necessary */
+		NdisMSleep(50000);
+
+		pAd->ate.Mode = ATE_STOP;
+
+		// Enable Tx
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+		Value |= (1 << 2);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+/*=========================================================================*/
+		/* restore RX_FILTR_CFG */
+#ifdef CONFIG_STA_SUPPORT
+		/* restore RX_FILTR_CFG in order that QA maybe set it to 0x3 */
+		RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL);
+#endif // CONFIG_STA_SUPPORT //
+/*=========================================================================*/
+
+		// Enable Tx, RX DMA.
+		RtmpDmaEnable(pAd, 1);
+
+		// Enable Rx
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+		Value |= (1 << 3);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+		// Wait 10ms to wait all of the bulk-in URBs to complete.
+		/* todo : remove this if not necessary */
+		NdisMSleep(10000);
+
+		// Everything is ready to start normal Tx/Rx.
+		RTUSBBulkReceive(pAd);
+		netif_start_queue(pAd->net_dev);
+
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("<=== ATE : ATESTOP \n"));
+	}
+	else if (!strcmp(arg, "TXCARR"))	// Tx Carrier
+	{
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXCARR\n"));
+		pAd->ate.Mode |= ATE_TXCARR;
+
+#ifdef RT30xx
+			for(i=0;i<ATE_BBP_REG_NUM;i++)
+				restore_BBP[i]=0;
+			//Record All BBP Value
+			for(i=0;i<ATE_BBP_REG_NUM;i++)
+			ATE_BBP_IO_READ8_BY_REG_ID(pAd,i,&restore_BBP[i]);
+#endif // RT30xx //
+
+		// Disable Rx
+		// May be we need not to do this, because these have been done in ATE_START mode ???
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+		Value &= ~(1 << 3);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+		// QA has done the following steps if it is used.
+		if (pAd->ate.bQATxStart == FALSE)
+		{
+			// Soft reset BBP.
+			BbpSoftReset(pAd);
+
+			// Carrier Test set BBP R22 bit7=1, bit6=1, bit[5~0]=0x01
+			ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+			BbpData &= 0xFFFFFF00; //clear bit7, bit6, bit[5~0]
+			BbpData |= 0x000000C1; //set bit7=1, bit6=1, bit[5~0]=0x01
+			ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+
+			// set MAC_SYS_CTRL(0x1004) Continuous Tx Production Test (bit4) = 1
+			RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+			Value = Value | 0x00000010;
+			RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+		}
+	}
+	else if (!strcmp(arg, "TXCONT"))	// Tx Continue
+	{
+		if (pAd->ate.bQATxStart == TRUE)
+		{
+			/* set MAC_SYS_CTRL(0x1004) bit4(Continuous Tx Production Test)
+			   and bit2(MAC TX enable) back to zero. */
+			RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+			MacData &= 0xFFFFFFEB;
+			RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+
+			// set BBP R22 bit7=0
+			ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+			BbpData &= 0xFFFFFF7F; //set bit7=0
+			ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+		}
+
+		/* for TxCont mode.
+		** Step 1: Send 50 packets first then wait for a moment.
+		** Step 2: Send more 50 packet then start continue mode.
+		*/
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXCONT\n"));
+
+#ifdef RT30xx
+				for(i=0;i<ATE_BBP_REG_NUM;i++)
+				restore_BBP[i]=0;
+			//Record All BBP Value
+			for(i=0;i<ATE_BBP_REG_NUM;i++)
+			ATE_BBP_IO_READ8_BY_REG_ID(pAd,i,&restore_BBP[i]);
+#endif // RT30xx //
+
+		// Step 1: send 50 packets first.
+		pAd->ate.Mode |= ATE_TXCONT;
+		pAd->ate.TxCount = 50;
+		pAd->ate.TxDoneCount = 0;
+
+		// Soft reset BBP.
+		BbpSoftReset(pAd);
+
+		// Abort Tx, RX DMA.
+		RtmpDmaEnable(pAd, 0);
+
+
+		/* Only needed if we have to send some normal frames. */
+		SetJapanFilter(pAd);
+
+		// Setup frame format.
+		ATESetUpFrame(pAd, 0);
+
+		// Enable Tx
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+		Value |= (1 << 2);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+		// Disable Rx
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+		Value &= ~(1 << 3);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+		// Start Tx, RX DMA.
+		RtmpDmaEnable(pAd, 1);
+
+		InterlockedExchange(&pAd->BulkOutRemained, pAd->ate.TxCount);
+
+#ifdef	RALINK_28xx_QA
+		if (pAd->ate.bQATxStart == TRUE)
+		{
+			pAd->ate.TxStatus = 1;
+			//pAd->ate.Repeat = 0;
+		}
+#endif	// RALINK_28xx_QA //
+
+		NdisAcquireSpinLock(&pAd->GenericLock);//0820
+		pAd->ContinBulkOut = FALSE;
+		NdisReleaseSpinLock(&pAd->GenericLock);
+
+		RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+
+		// Kick bulk out
+		RTUSBKickBulkOut(pAd);
+
+		/* To make sure all the 50 frames have been bulk out before executing step 2 */
+		while (atomic_read(&pAd->BulkOutRemained) > 0)
+		{
+			RTMPusecDelay(5000);
+		}
+
+		// Step 2: send more 50 packets then start continue mode.
+		// Abort Tx, RX DMA.
+		RtmpDmaEnable(pAd, 0);
+
+		// Cont. TX set BBP R22 bit7=1
+		ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+		BbpData |= 0x00000080; //set bit7=1
+		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+
+		pAd->ate.TxCount = 50;
+		pAd->ate.TxDoneCount = 0;
+
+		SetJapanFilter(pAd);
+
+		// Setup frame format.
+		ATESetUpFrame(pAd, 0);
+
+		// Enable Tx
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+		Value |= (1 << 2);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+		// Disable Rx
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+		Value &= ~(1 << 3);
+
+		// Start Tx, RX DMA.
+		RtmpDmaEnable(pAd, 1);
+
+		InterlockedExchange(&pAd->BulkOutRemained, pAd->ate.TxCount);
+
+#ifdef	RALINK_28xx_QA
+		if (pAd->ate.bQATxStart == TRUE)
+		{
+			pAd->ate.TxStatus = 1;
+			//pAd->ate.Repeat = 0;
+		}
+#endif	// RALINK_28xx_QA //
+
+		NdisAcquireSpinLock(&pAd->GenericLock);//0820
+		pAd->ContinBulkOut = FALSE;
+		NdisReleaseSpinLock(&pAd->GenericLock);
+
+		RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+		// Kick bulk out
+		RTUSBKickBulkOut(pAd);
+
+#if 1
+		RTMPusecDelay(500);
+#else
+		while (atomic_read(&pAd->BulkOutRemained) > 0)
+		{
+			RTMPusecDelay(5000);
+		}
+#endif // 1 //
+
+		// Set MAC_SYS_CTRL(0x1004) Continuous Tx Production Test (bit4) = 1.
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+		MacData |= 0x00000010;
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+	}
+	else if (!strcmp(arg, "TXFRAME"))	// Tx Frames
+	{
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXFRAME(Count=0x%08x)\n", pAd->ate.TxCount));
+		pAd->ate.Mode |= ATE_TXFRAME;
+
+		// Soft reset BBP.
+		BbpSoftReset(pAd);
+
+		// Default value in BBP R22 is 0x0.
+		BbpData = 0;
+
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+
+		// Clean bit4 to stop continuous Tx production test.
+		MacData &= 0xFFFFFFEF;
+
+	   	ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+
+#ifdef RALINK_28xx_QA
+		// add this for LoopBack mode
+		if (pAd->ate.bQARxStart == FALSE)
+		{
+			// Disable Rx
+			RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+			Value &= ~(1 << 3);
+			RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+		}
+
+		if (pAd->ate.bQATxStart == TRUE)
+		{
+			pAd->ate.TxStatus = 1;
+			//pAd->ate.Repeat = 0;
+		}
+#else
+		// Disable Rx
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+		Value &= ~(1 << 3);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+#endif // RALINK_28xx_QA //
+
+		// Enable Tx
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+		Value |= (1 << 2);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+        SetJapanFilter(pAd);
+
+		// Abort Tx, RX DMA.
+		RtmpDmaEnable(pAd, 0);
+
+		pAd->ate.TxDoneCount = 0;
+
+        // Setup frame format
+		ATESetUpFrame(pAd, 0);
+
+		// Start Tx, RX DMA.
+		RtmpDmaEnable(pAd, 1);
+
+		// Check count is continuous or not yet.
+		//
+		// Due to the type mismatch between "pAd->BulkOutRemained"(atomic_t) and "pAd->ate.TxCount"(UINT32)
+		//
+		if (pAd->ate.TxCount == 0)
+		{
+			InterlockedExchange(&pAd->BulkOutRemained, 0);
+		}
+		else
+		{
+			InterlockedExchange(&pAd->BulkOutRemained, pAd->ate.TxCount);
+		}
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("bulk out count = %d\n", atomic_read(&pAd->BulkOutRemained)));
+		ASSERT((atomic_read(&pAd->BulkOutRemained) >= 0));
+
+		if (atomic_read(&pAd->BulkOutRemained) == 0)
+		{
+			ATEDBGPRINT(RT_DEBUG_TRACE, ("Send packet countinuously\n"));
+
+			/* In 28xx, NdisAcquireSpinLock() == spin_lock_bh() */
+			/* NdisAcquireSpinLock only need one argument in 28xx. */
+			NdisAcquireSpinLock(&pAd->GenericLock);
+			pAd->ContinBulkOut = TRUE;
+			NdisReleaseSpinLock(&pAd->GenericLock);
+
+			/* In 28xx, BULK_OUT_LOCK() == spin_lock_irqsave() */
+			BULK_OUT_LOCK(&pAd->BulkOutLock[0], IrqFlags);// peter : NdisAcquireSpinLock ==> BULK_OUT_LOCK
+			pAd->BulkOutPending[0] = FALSE;
+			BULK_OUT_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);// peter : NdisAcquireSpinLock ==> BULK_OUT_LOCK
+		}
+		else
+		{
+			ATEDBGPRINT(RT_DEBUG_TRACE, ("Send packets depend on counter\n"));
+
+			NdisAcquireSpinLock(&pAd->GenericLock);
+			pAd->ContinBulkOut = FALSE;
+			NdisReleaseSpinLock(&pAd->GenericLock);
+
+			BULK_OUT_LOCK(&pAd->BulkOutLock[0], IrqFlags);
+			pAd->BulkOutPending[0] = FALSE;
+			BULK_OUT_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
+		}
+
+		RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+
+		// Kick bulk out
+		RTUSBKickBulkOut(pAd);
+	}
+#ifdef RALINK_28xx_QA
+	else if (!strcmp(arg, "TXSTOP")) 		//Enter ATE mode and set Tx/Rx Idle
+	{
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXSTOP\n"));
+
+		atemode = pAd->ate.Mode;
+		pAd->ate.Mode &= ATE_TXSTOP;
+		pAd->ate.bQATxStart = FALSE;
+//		pAd->ate.TxDoneCount = pAd->ate.TxCount;
+
+/*=========================================================================*/
+		if (atemode & ATE_TXCARR)
+		{
+			// No Carrier Test set BBP R22 bit7=0, bit6=0, bit[5~0]=0x0
+			ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+			BbpData &= 0xFFFFFF00; //clear bit7, bit6, bit[5~0]
+		    ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+		}
+		else if (atemode & ATE_TXCARRSUPP)
+		{
+			// No Cont. TX set BBP R22 bit7=0
+			ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+			BbpData &= ~(1 << 7); //set bit7=0
+			ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+
+			// No Carrier Suppression set BBP R24 bit0=0
+			ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R24, &BbpData);
+			BbpData &= 0xFFFFFFFE; //clear bit0
+		    ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, BbpData);
+		}
+		else if ((atemode & ATE_TXFRAME) || (atemode == ATE_STOP))
+		{
+			if (atemode & ATE_TXCONT)
+			{
+				// No Cont. TX set BBP R22 bit7=0
+				ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+				BbpData &= ~(1 << 7); //set bit7=0
+				ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+			}
+		}
+
+/*=========================================================================*/
+		RTUSBRejectPendingPackets(pAd);
+		RTUSBCleanUpDataBulkOutQueue(pAd);
+
+		/* not used in RT28xx */
+		//RTUSBCleanUpMLMEWaitQueue(pAd);
+		/* empty function so far */
+		RTUSBCleanUpMLMEBulkOutQueue(pAd);
+/*=========================================================================*/
+		// Abort Tx, RX DMA.
+		RtmpDmaEnable(pAd, 0);
+/*=========================================================================*/
+
+		/* In 28xx, pAd->PendingRx is not of type atomic_t anymore */
+//		while ((atomic_read(&pAd->PendingRx) > 0))	//pAd->BulkFlags != 0 wait bulk out finish
+		/* peter todo : BulkInLock */
+		while (pAd->PendingRx > 0)
+		{
+#if 1
+			ATE_RTUSBCancelPendingBulkInIRP(pAd);
+#else
+//			NdisInterlockedDecrement(&pAd->PendingRx);
+			pAd->PendingRx--;
+#endif
+			RTMPusecDelay(500000);
+		}
+
+		while (((pAd->BulkOutPending[0] == TRUE) ||
+				(pAd->BulkOutPending[1] == TRUE) ||
+				(pAd->BulkOutPending[2] == TRUE) ||
+				(pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0))	//pAd->BulkFlags != 0 wait bulk out finish
+		{
+			do
+			{
+				RTUSBCancelPendingBulkOutIRP(pAd);
+			} while (FALSE);
+
+			RTMPusecDelay(500000);
+		}
+
+		ASSERT(pAd->PendingRx == 0);
+/*=========================================================================*/
+		// Enable Tx, Rx DMA.
+		RtmpDmaEnable(pAd, 1);
+
+		/* task Tx status : 0 --> task is idle, 1 --> task is running */
+		pAd->ate.TxStatus = 0;
+
+		// Soft reset BBP.
+		BbpSoftReset(pAd);
+
+		// Disable Tx
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+		MacData &= (0xfffffffb);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+
+		//Clean ATE Bulk in/out counter and continue setup
+		InterlockedExchange(&pAd->BulkOutRemained, 0);
+
+		pAd->ContinBulkOut = FALSE;
+	}
+	else if (!strcmp(arg, "RXSTOP"))
+	{
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: RXSTOP\n"));
+		atemode = pAd->ate.Mode;
+
+		// Disable Rx
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+		Value &= ~(1 << 3);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+		pAd->ate.Mode &= ATE_RXSTOP;
+		pAd->ate.bQARxStart = FALSE;
+//		pAd->ate.TxDoneCount = pAd->ate.TxCount;
+
+/*=========================================================================*/
+		RTUSBRejectPendingPackets(pAd);
+		RTUSBCleanUpDataBulkOutQueue(pAd);
+
+		/* not used in RT28xx */
+		//RTUSBCleanUpMLMEWaitQueue(pAd);
+		RTUSBCleanUpMLMEBulkOutQueue(pAd);
+/*=========================================================================*/
+
+		// Abort Tx, RX DMA.
+		RtmpDmaEnable(pAd, 0);
+/*=========================================================================*/
+//		while ((atomic_read(&pAd->PendingRx) > 0))
+		while (pAd->PendingRx > 0)
+		{
+#if 1
+			ATE_RTUSBCancelPendingBulkInIRP(pAd);
+#else
+//			NdisInterlockedDecrement(&pAd->PendingRx);
+			pAd->PendingRx--;
+#endif
+			RTMPusecDelay(500000);
+		}
+
+		while (((pAd->BulkOutPending[0] == TRUE) ||
+				(pAd->BulkOutPending[1] == TRUE) ||
+				(pAd->BulkOutPending[2] == TRUE) ||
+				(pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0))	//pAd->BulkFlags != 0 wait bulk out finish
+		{
+			do
+			{
+				RTUSBCancelPendingBulkOutIRP(pAd);
+			} while (FALSE);
+
+			RTMPusecDelay(500000);
+		}
+
+		ASSERT(pAd->PendingRx == 0);
+/*=========================================================================*/
+
+		// Soft reset BBP.
+		BbpSoftReset(pAd);
+		pAd->ContinBulkIn = FALSE;
+	}
+#endif // RALINK_28xx_QA //
+	else if (!strcmp(arg, "RXFRAME")) // Rx Frames
+	{
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: RXFRAME\n"));
+
+		// Disable Rx of MAC block
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+		Value &= ~(1 << 3);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+		// Default value in BBP R22 is 0x0.
+		BbpData = 0;
+
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+		// Clean bit4 to stop continuous Tx production test.
+		MacData &= 0xFFFFFFEF;
+
+	   	ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+
+		pAd->ate.Mode |= ATE_RXFRAME;
+
+		// Abort Tx, RX DMA.
+		RtmpDmaEnable(pAd, 0);
+
+		// Disable TX of MAC block
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+		Value &= ~(1 << 2);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+        // Reset Rx RING.
+		for ( i = 0; i < (RX_RING_SIZE); i++)
+		{
+			PRX_CONTEXT  pRxContext = &(pAd->RxContext[i]);
+
+			pRxContext->InUse = FALSE;
+			pRxContext->IRPPending = FALSE;
+			pRxContext->Readable = FALSE;
+
+			//
+			// Get the urb from kernel back to driver.
+			//
+			RTUSB_UNLINK_URB(pRxContext->pUrb);
+
+			/* Sleep 200 microsecs to give cancellation time to work. */
+			NdisMSleep(200);
+			pAd->BulkInReq = 0;
+
+//			InterlockedExchange(&pAd->PendingRx, 0);
+			pAd->PendingRx = 0;
+			pAd->NextRxBulkInReadIndex = 0;	// Next Rx Read index
+			pAd->NextRxBulkInIndex		= RX_RING_SIZE - 1;	// Rx Bulk pointer
+			pAd->NextRxBulkInPosition = 0;
+		}
+
+		// read to clear counters
+		RTUSBReadMACRegister(pAd, RX_STA_CNT0, &temp); //RX PHY & RX CRC count
+		RTUSBReadMACRegister(pAd, RX_STA_CNT1, &temp); //RX PLCP error count & CCA false alarm count
+		RTUSBReadMACRegister(pAd, RX_STA_CNT2, &temp); //RX FIFO overflow frame count & RX duplicated filtered frame count
+
+		pAd->ContinBulkIn = TRUE;
+
+		// Enable Tx, RX DMA.
+		RtmpDmaEnable(pAd, 1);
+
+		// Enable RX of MAC block
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+		Value |= (1 << 3);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+		// Kick bulk in
+		RTUSBBulkReceive(pAd);
+	}
+	else
+	{
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: Invalid arg!\n"));
+		return FALSE;
+	}
+	RTMPusecDelay(5000);
+
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("<=== ATECmdHandler()\n"));
+
+	return TRUE;
+}
+#endif // RT2870 //
+
+INT	Set_ATE_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	if (ATECmdHandler(pAd, arg))
+	{
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_Proc Success\n"));
+
+
+		return TRUE;
+	}
+	else
+	{
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_Proc Failed\n"));
+		return FALSE;
+	}
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE ADDR1=DA for TxFrame(AP  : To DS = 0 ; From DS = 1)
+        or
+        Set ATE ADDR3=DA for TxFrame(STA : To DS = 1 ; From DS = 0)
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_ATE_DA_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	CHAR				*value;
+	INT					i;
+
+	if(strlen(arg) != 17)  //Mac address acceptable format 01:02:03:04:05:06 length 17
+		return FALSE;
+
+    for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
+	{
+		if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
+			return FALSE;  //Invalid
+
+
+#ifdef CONFIG_STA_SUPPORT
+		AtoH(value, &pAd->ate.Addr3[i++], 1);
+#endif // CONFIG_STA_SUPPORT //
+	}
+
+	if(i != 6)
+		return FALSE;  //Invalid
+
+
+#ifdef CONFIG_STA_SUPPORT
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_DA_Proc (DA = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAd->ate.Addr3[0],
+		pAd->ate.Addr3[1], pAd->ate.Addr3[2], pAd->ate.Addr3[3], pAd->ate.Addr3[4], pAd->ate.Addr3[5]));
+#endif // CONFIG_STA_SUPPORT //
+
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_DA_Proc Success\n"));
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE ADDR3=SA for TxFrame(AP  : To DS = 0 ; From DS = 1)
+        or
+        Set ATE ADDR2=SA for TxFrame(STA : To DS = 1 ; From DS = 0)
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_ATE_SA_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	CHAR				*value;
+	INT					i;
+
+	if(strlen(arg) != 17)  //Mac address acceptable format 01:02:03:04:05:06 length 17
+		return FALSE;
+
+    for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
+	{
+		if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
+			return FALSE;  //Invalid
+
+
+#ifdef CONFIG_STA_SUPPORT
+		AtoH(value, &pAd->ate.Addr2[i++], 1);
+#endif // CONFIG_STA_SUPPORT //
+	}
+
+	if(i != 6)
+		return FALSE;  //Invalid
+
+
+#ifdef CONFIG_STA_SUPPORT
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_SA_Proc (SA = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAd->ate.Addr2[0],
+		pAd->ate.Addr2[1], pAd->ate.Addr2[2], pAd->ate.Addr2[3], pAd->ate.Addr2[4], pAd->ate.Addr2[5]));
+#endif // CONFIG_STA_SUPPORT //
+
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_SA_Proc Success\n"));
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE ADDR2=BSSID for TxFrame(AP  : To DS = 0 ; From DS = 1)
+        or
+        Set ATE ADDR1=BSSID for TxFrame(STA : To DS = 1 ; From DS = 0)
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_ATE_BSSID_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	CHAR				*value;
+	INT					i;
+
+	if(strlen(arg) != 17)  //Mac address acceptable format 01:02:03:04:05:06 length 17
+		return FALSE;
+
+    for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
+	{
+		if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
+			return FALSE;  //Invalid
+
+
+#ifdef CONFIG_STA_SUPPORT
+		AtoH(value, &pAd->ate.Addr1[i++], 1);
+#endif // CONFIG_STA_SUPPORT //
+	}
+
+	if(i != 6)
+		return FALSE;  //Invalid
+
+
+#ifdef CONFIG_STA_SUPPORT
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_BSSID_Proc (BSSID = %2X:%2X:%2X:%2X:%2X:%2X)\n",	pAd->ate.Addr1[0],
+		pAd->ate.Addr1[1], pAd->ate.Addr1[2], pAd->ate.Addr1[3], pAd->ate.Addr1[4], pAd->ate.Addr1[5]));
+#endif // CONFIG_STA_SUPPORT //
+
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_BSSID_Proc Success\n"));
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE Tx Channel
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_ATE_CHANNEL_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	UCHAR channel;
+
+	channel = simple_strtol(arg, 0, 10);
+
+	if ((channel < 1) || (channel > 216))// to allow A band channel : ((channel < 1) || (channel > 14))
+	{
+		ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_CHANNEL_Proc::Out of range, it should be in range of 1~14.\n"));
+		return FALSE;
+	}
+	pAd->ate.Channel = channel;
+
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_CHANNEL_Proc (ATE Channel = %d)\n", pAd->ate.Channel));
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_CHANNEL_Proc Success\n"));
+
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE Tx Power0
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_ATE_TX_POWER0_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	CHAR TxPower;
+
+	TxPower = simple_strtol(arg, 0, 10);
+
+	if (pAd->ate.Channel <= 14)
+	{
+		if ((TxPower > 31) || (TxPower < 0))
+		{
+			ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER0_Proc::Out of range (Value=%d)\n", TxPower));
+			return FALSE;
+		}
+	}
+	else// 5.5GHz
+	{
+		if ((TxPower > 15) || (TxPower < -7))
+		{
+			ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER0_Proc::Out of range (Value=%d)\n", TxPower));
+			return FALSE;
+		}
+	}
+
+	pAd->ate.TxPower0 = TxPower;
+	ATETxPwrHandler(pAd, 0);
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_POWER0_Proc Success\n"));
+
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE Tx Power1
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_ATE_TX_POWER1_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	CHAR TxPower;
+
+	TxPower = simple_strtol(arg, 0, 10);
+
+	if (pAd->ate.Channel <= 14)
+	{
+	if ((TxPower > 31) || (TxPower < 0))
+	{
+		ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER1_Proc::Out of range (Value=%d)\n", TxPower));
+		return FALSE;
+	}
+	}
+	else
+	{
+		if ((TxPower > 15) || (TxPower < -7))
+		{
+			ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER1_Proc::Out of range (Value=%d)\n", TxPower));
+			return FALSE;
+		}
+	}
+
+	pAd->ate.TxPower1 = TxPower;
+	ATETxPwrHandler(pAd, 1);
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_POWER1_Proc Success\n"));
+
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE Tx Antenna
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_ATE_TX_Antenna_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	CHAR value;
+
+	value = simple_strtol(arg, 0, 10);
+
+	if ((value > 2) || (value < 0))
+	{
+		ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_Antenna_Proc::Out of range (Value=%d)\n", value));
+		return FALSE;
+	}
+
+	pAd->ate.TxAntennaSel = value;
+
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_Antenna_Proc (Antenna = %d)\n", pAd->ate.TxAntennaSel));
+	ATEDBGPRINT(RT_DEBUG_TRACE,("Ralink: Set_ATE_TX_Antenna_Proc Success\n"));
+
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE Rx Antenna
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_ATE_RX_Antenna_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	CHAR value;
+
+	value = simple_strtol(arg, 0, 10);
+
+	if ((value > 3) || (value < 0))
+	{
+		ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_RX_Antenna_Proc::Out of range (Value=%d)\n", value));
+		return FALSE;
+	}
+
+	pAd->ate.RxAntennaSel = value;
+
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_RX_Antenna_Proc (Antenna = %d)\n", pAd->ate.RxAntennaSel));
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_RX_Antenna_Proc Success\n"));
+
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE RF frequence offset
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_ATE_TX_FREQOFFSET_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	UCHAR RFFreqOffset;
+	ULONG R4;
+
+	RFFreqOffset = simple_strtol(arg, 0, 10);
+#ifndef RT30xx
+	if(RFFreqOffset >= 64)
+#endif // RT30xx //
+#ifdef RT30xx
+//2008/08/06: KH modified the limit of offset value from 65 to 95(0x5F)
+	if(RFFreqOffset >= 95)
+#endif // RT30xx //
+	{
+		ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_FREQOFFSET_Proc::Out of range, it should be in range of 0~63.\n"));
+		return FALSE;
+	}
+
+	pAd->ate.RFFreqOffset = RFFreqOffset;
+#ifdef RT30xx
+	if(IS_RT30xx(pAd))
+	{
+		// Set RF offset
+		UCHAR RFValue;
+		RT30xxReadRFRegister(pAd, RF_R23, (PUCHAR)&RFValue);
+				//2008/08/06: KH modified "pAd->RFFreqOffset" to "pAd->ate.RFFreqOffset"
+				RFValue = (RFValue & 0x80) | pAd->ate.RFFreqOffset;
+		RT30xxWriteRFRegister(pAd, RF_R23, (UCHAR)RFValue);
+	}
+	else
+#endif // RT30xx //
+	{
+
+		R4 = pAd->ate.RFFreqOffset << 15;		// shift TX power control to correct RF register bit position
+		R4 |= (pAd->LatchRfRegs.R4 & ((~0x001f8000)));
+		pAd->LatchRfRegs.R4 = R4;
+
+		RtmpRfIoWrite(pAd);
+	}
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_FREQOFFSET_Proc (RFFreqOffset = %d)\n", pAd->ate.RFFreqOffset));
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_FREQOFFSET_Proc Success\n"));
+
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE RF BW
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_ATE_TX_BW_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	int i;
+	UCHAR value = 0;
+	UCHAR BBPCurrentBW;
+
+	BBPCurrentBW = simple_strtol(arg, 0, 10);
+
+	if(BBPCurrentBW == 0)
+		pAd->ate.TxWI.BW = BW_20;
+	else
+		pAd->ate.TxWI.BW = BW_40;
+
+	if(pAd->ate.TxWI.BW == BW_20)
+	{
+		if(pAd->ate.Channel <= 14)
+		{
+ 		for (i=0; i<5; i++)
+ 		{
+				if (pAd->Tx20MPwrCfgGBand[i] != 0xffffffff)
+				{
+					RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx20MPwrCfgGBand[i]);
+					RTMPusecDelay(5000);
+				}
+			}
+		}
+		else
+		{
+			for (i=0; i<5; i++)
+			{
+				if (pAd->Tx20MPwrCfgABand[i] != 0xffffffff)
+ 			{
+					RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx20MPwrCfgABand[i]);
+ 				RTMPusecDelay(5000);
+ 			}
+ 		}
+		}
+
+		//Set BBP R4 bit[4:3]=0:0
+ 		ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value);
+ 		value &= (~0x18);
+ 		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value);
+
+  		//Set BBP R66=0x3C
+ 		value = 0x3C;
+ 		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, value);
+		//Set BBP R68=0x0B
+		//to improve Rx sensitivity.
+		value = 0x0B;
+		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R68, value);
+		//Set BBP R69=0x16
+		value = 0x16;
+ 		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, value);
+		//Set BBP R70=0x08
+		value = 0x08;
+ 		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, value);
+		//Set BBP R73=0x11
+		value = 0x11;
+ 		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, value);
+
+	    // If Channel=14, Bandwidth=20M and Mode=CCK, Set BBP R4 bit5=1
+	    // (Japan filter coefficients)
+	    // This segment of code will only works when ATETXMODE and ATECHANNEL
+	    // were set to MODE_CCK and 14 respectively before ATETXBW is set to 0.
+	    //=====================================================================
+		if (pAd->ate.Channel == 14)
+		{
+			int TxMode = pAd->ate.TxWI.PHYMODE;
+			if (TxMode == MODE_CCK)
+			{
+				// when Channel==14 && Mode==CCK && BandWidth==20M, BBP R4 bit5=1
+ 				ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value);
+				value |= 0x20; //set bit5=1
+ 				ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value);
+			}
+		}
+
+	    //=====================================================================
+		// If bandwidth != 40M, RF Reg4 bit 21 = 0.
+#ifdef RT30xx
+	// Set BW
+		if(IS_RT30xx(pAd))
+			RT30xxWriteRFRegister(pAd, RF_R24, (UCHAR) pAd->Mlme.CaliBW20RfR24);
+		else
+#endif // RT30xx //
+		{
+		pAd->LatchRfRegs.R4 &= ~0x00200000;
+		RtmpRfIoWrite(pAd);
+	}
+
+	}
+	else if(pAd->ate.TxWI.BW == BW_40)
+	{
+		if(pAd->ate.Channel <= 14)
+		{
+			for (i=0; i<5; i++)
+			{
+				if (pAd->Tx40MPwrCfgGBand[i] != 0xffffffff)
+				{
+					RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx40MPwrCfgGBand[i]);
+					RTMPusecDelay(5000);
+				}
+			}
+		}
+		else
+		{
+			for (i=0; i<5; i++)
+			{
+				if (pAd->Tx40MPwrCfgABand[i] != 0xffffffff)
+				{
+					RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx40MPwrCfgABand[i]);
+					RTMPusecDelay(5000);
+				}
+			}
+#ifdef DOT11_N_SUPPORT
+			if ((pAd->ate.TxWI.PHYMODE >= MODE_HTMIX) && (pAd->ate.TxWI.MCS == 7))
+			{
+    			value = 0x28;
+    			ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R67, value);
+			}
+#endif // DOT11_N_SUPPORT //
+		}
+
+		//Set BBP R4 bit[4:3]=1:0
+		ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value);
+		value &= (~0x18);
+		value |= 0x10;
+		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value);
+
+		//Set BBP R66=0x3C
+		value = 0x3C;
+		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, value);
+		//Set BBP R68=0x0C
+		//to improve Rx sensitivity.
+		value = 0x0C;
+		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R68, value);
+		//Set BBP R69=0x1A
+		value = 0x1A;
+		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, value);
+		//Set BBP R70=0x0A
+		value = 0x0A;
+		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, value);
+		//Set BBP R73=0x16
+		value = 0x16;
+		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, value);
+
+		// If bandwidth = 40M, set RF Reg4 bit 21 = 1.
+#ifdef RT30xx
+	// Set BW
+		if(IS_RT30xx(pAd))
+			RT30xxWriteRFRegister(pAd, RF_R24, (UCHAR) pAd->Mlme.CaliBW40RfR24);
+		else
+#endif // RT30xx //
+		{
+			pAd->LatchRfRegs.R4 |= 0x00200000;
+			RtmpRfIoWrite(pAd);
+		}
+	}
+
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_BW_Proc (BBPCurrentBW = %d)\n", pAd->ate.TxWI.BW));
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_BW_Proc Success\n"));
+
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE Tx frame length
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_ATE_TX_LENGTH_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	pAd->ate.TxLength = simple_strtol(arg, 0, 10);
+
+	if((pAd->ate.TxLength < 24) || (pAd->ate.TxLength > (MAX_FRAME_SIZE - 34/* == 2312 */)))
+	{
+		pAd->ate.TxLength = (MAX_FRAME_SIZE - 34/* == 2312 */);
+		ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_LENGTH_Proc::Out of range, it should be in range of 24~%d.\n", (MAX_FRAME_SIZE - 34/* == 2312 */)));
+		return FALSE;
+	}
+
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_LENGTH_Proc (TxLength = %d)\n", pAd->ate.TxLength));
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_LENGTH_Proc Success\n"));
+
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE Tx frame count
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_ATE_TX_COUNT_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	pAd->ate.TxCount = simple_strtol(arg, 0, 10);
+
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_COUNT_Proc (TxCount = %d)\n", pAd->ate.TxCount));
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_COUNT_Proc Success\n"));
+
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE Tx frame MCS
+
+        Return:
+        	TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_ATE_TX_MCS_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	UCHAR MCS;
+	int result;
+
+	MCS = simple_strtol(arg, 0, 10);
+	result = CheckMCSValid(pAd->ate.TxWI.PHYMODE, MCS);
+
+	if (result != -1)
+	{
+		pAd->ate.TxWI.MCS = (UCHAR)MCS;
+	}
+	else
+	{
+		ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_MCS_Proc::Out of range, refer to rate table.\n"));
+		return FALSE;
+	}
+
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_MCS_Proc (MCS = %d)\n", pAd->ate.TxWI.MCS));
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_MCS_Proc Success\n"));
+
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE Tx frame Mode
+        0: MODE_CCK
+        1: MODE_OFDM
+        2: MODE_HTMIX
+        3: MODE_HTGREENFIELD
+
+        Return:
+        	TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_ATE_TX_MODE_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	pAd->ate.TxWI.PHYMODE = simple_strtol(arg, 0, 10);
+
+	if(pAd->ate.TxWI.PHYMODE > 3)
+	{
+		pAd->ate.TxWI.PHYMODE = 0;
+		ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_MODE_Proc::Out of range. it should be in range of 0~3\n"));
+		ATEDBGPRINT(RT_DEBUG_ERROR, ("0: CCK, 1: OFDM, 2: HT_MIX, 3: HT_GREEN_FIELD.\n"));
+		return FALSE;
+	}
+
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_MODE_Proc (TxMode = %d)\n", pAd->ate.TxWI.PHYMODE));
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_MODE_Proc Success\n"));
+
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set ATE Tx frame GI
+
+        Return:
+        	TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_ATE_TX_GI_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	pAd->ate.TxWI.ShortGI = simple_strtol(arg, 0, 10);
+
+	if(pAd->ate.TxWI.ShortGI > 1)
+	{
+		pAd->ate.TxWI.ShortGI = 0;
+		ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_GI_Proc::Out of range\n"));
+		return FALSE;
+	}
+
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_GI_Proc (GI = %d)\n", pAd->ate.TxWI.ShortGI));
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_GI_Proc Success\n"));
+
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+    ==========================================================================
+ */
+INT	Set_ATE_RX_FER_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	pAd->ate.bRxFer = simple_strtol(arg, 0, 10);
+
+	if (pAd->ate.bRxFer == 1)
+	{
+		pAd->ate.RxCntPerSec = 0;
+		pAd->ate.RxTotalCnt = 0;
+	}
+
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_RX_FER_Proc (bRxFer = %d)\n", pAd->ate.bRxFer));
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_RX_FER_Proc Success\n"));
+
+
+	return TRUE;
+}
+
+INT Set_ATE_Read_RF_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+#ifdef RT30xx
+//2008/07/10:KH add to support RT30xx ATE<--
+	if(IS_RT30xx(pAd))
+	{
+			/* modify by WY for Read RF Reg. error */
+		UCHAR RFValue;
+		INT index=0;
+		for (index = 0; index < 32; index++)
+		{
+			RT30xxReadRFRegister(pAd, index, (PUCHAR)&RFValue);
+			printk("R%d=%d\n",index,RFValue);
+		}
+	}
+	else
+//2008/07/10:KH add to support RT30xx ATE-->
+#endif // RT30xx //
+	{
+		ate_print(KERN_EMERG "R1 = %lx\n", pAd->LatchRfRegs.R1);
+		ate_print(KERN_EMERG "R2 = %lx\n", pAd->LatchRfRegs.R2);
+		ate_print(KERN_EMERG "R3 = %lx\n", pAd->LatchRfRegs.R3);
+		ate_print(KERN_EMERG "R4 = %lx\n", pAd->LatchRfRegs.R4);
+	}
+	return TRUE;
+}
+
+INT Set_ATE_Write_RF1_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+#ifdef RT30xx
+//2008/07/10:KH add to support 3070 ATE<--
+	if(IS_RT30xx(pAd))
+	{
+		printk("Warning!! RT30xx Don't Support\n");
+		return FALSE;
+
+	}
+	else
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RT30xx //
+	{
+		UINT32 value = simple_strtol(arg, 0, 16);
+
+		pAd->LatchRfRegs.R1 = value;
+		RtmpRfIoWrite(pAd);
+	}
+	return TRUE;
+
+}
+
+INT Set_ATE_Write_RF2_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+#ifdef RT30xx
+//2008/07/10:KH add to support 3070 ATE<--
+	if(IS_RT30xx(pAd))
+	{
+		printk("Warning!! RT30xx Don't Support\n");
+		return FALSE;
+
+	}
+	else
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RT30xx //
+	{
+		UINT32 value = simple_strtol(arg, 0, 16);
+
+		pAd->LatchRfRegs.R2 = value;
+		RtmpRfIoWrite(pAd);
+	}
+	return TRUE;
+}
+
+INT Set_ATE_Write_RF3_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+#ifdef RT30xx
+//2008/07/10:KH add to support 3070 ATE<--
+	if(IS_RT30xx(pAd))
+	{
+		printk("Warning!! RT30xx Don't Support\n");
+		return FALSE;
+
+	}
+	else
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RT30xx //
+	{
+		UINT32 value = simple_strtol(arg, 0, 16);
+
+		pAd->LatchRfRegs.R3 = value;
+		RtmpRfIoWrite(pAd);
+	}
+	return TRUE;
+}
+
+INT Set_ATE_Write_RF4_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+#ifdef RT30xx
+//2008/07/10:KH add to support 3070 ATE<--
+	if(IS_RT30xx(pAd))
+	{
+		printk("Warning!! RT30xx Don't Support\n");
+		return FALSE;
+
+	}
+	else
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RT30xx //
+	{
+		UINT32 value = simple_strtol(arg, 0, 16);
+
+		pAd->LatchRfRegs.R4 = value;
+		RtmpRfIoWrite(pAd);
+	}
+	return TRUE;
+}
+#ifdef RT30xx
+//2008/07/10:KH add to support 3070 ATE<--
+INT	SET_ATE_3070RF_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	CHAR *this_char;
+	CHAR *value;
+	UINT32 Reg,RFValue;
+	if(IS_RT30xx(pAd))
+	{
+		printk("SET_ATE_3070RF_Proc=%s\n",arg);
+		this_char =arg;
+		if ((value = strchr(this_char, ':')) != NULL)
+			*value++ = 0;
+		Reg= simple_strtol(this_char, 0, 16);
+		RFValue= simple_strtol(value, 0, 16);
+		printk("RF Reg[%d]=%d\n",Reg,RFValue);
+		RT30xxWriteRFRegister(pAd, Reg,RFValue);
+	}
+	else
+		printk("Warning!! Only 3070 Support\n");
+	return TRUE;
+}
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RT30xx //
+/*
+    ==========================================================================
+    Description:
+        Load and Write EEPROM from a binary file prepared in advance.
+
+        Return:
+        	TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+#ifndef UCOS
+INT Set_ATE_Load_E2P_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	BOOLEAN		    ret = FALSE;
+	PUCHAR			src = EEPROM_BIN_FILE_NAME;
+	struct file		*srcf;
+	INT32 			retval, orgfsuid, orgfsgid;
+   	mm_segment_t	orgfs;
+	USHORT 			WriteEEPROM[(EEPROM_SIZE/2)];
+	UINT32			FileLength = 0;
+	UINT32 			value = simple_strtol(arg, 0, 10);
+
+	ATEDBGPRINT(RT_DEBUG_ERROR, ("===> %s (value=%d)\n\n", __FUNCTION__, value));
+
+	if (value > 0)
+	{
+		/* zero the e2p buffer */
+		NdisZeroMemory((PUCHAR)WriteEEPROM, EEPROM_SIZE);
+
+		/* save uid and gid used for filesystem access.
+	    ** set user and group to 0 (root)
+	    */
+		orgfsuid = current->fsuid;
+		orgfsgid = current->fsgid;
+		/* as root */
+		current->fsuid = current->fsgid = 0;
+    	orgfs = get_fs();
+    	set_fs(KERNEL_DS);
+
+		do
+		{
+			/* open the bin file */
+			srcf = filp_open(src, O_RDONLY, 0);
+
+			if (IS_ERR(srcf))
+			{
+				ate_print("%s - Error %ld opening %s\n", __FUNCTION__, -PTR_ERR(srcf), src);
+				break;
+			}
+
+			/* the object must have a read method */
+			if ((srcf->f_op == NULL) || (srcf->f_op->read == NULL))
+			{
+				ate_print("%s - %s does not have a read method\n", __FUNCTION__, src);
+				break;
+			}
+
+			/* read the firmware from the file *.bin */
+			FileLength = srcf->f_op->read(srcf,
+										  (PUCHAR)WriteEEPROM,
+										  EEPROM_SIZE,
+										  &srcf->f_pos);
+
+			if (FileLength != EEPROM_SIZE)
+			{
+				ate_print("%s: error file length (=%d) in e2p.bin\n",
+					   __FUNCTION__, FileLength);
+				break;
+			}
+			else
+			{
+				/* write the content of .bin file to EEPROM */
+				rt_ee_write_all(pAd, WriteEEPROM);
+				ret = TRUE;
+			}
+			break;
+		} while(TRUE);
+
+		/* close firmware file */
+		if (IS_ERR(srcf))
+		{
+				;
+		}
+		else
+		{
+			retval = filp_close(srcf, NULL);
+			if (retval)
+			{
+				ATEDBGPRINT(RT_DEBUG_ERROR, ("--> Error %d closing %s\n", -retval, src));
+
+			}
+		}
+
+		/* restore */
+		set_fs(orgfs);
+		current->fsuid = orgfsuid;
+		current->fsgid = orgfsgid;
+	}
+    ATEDBGPRINT(RT_DEBUG_ERROR, ("<=== %s (ret=%d)\n", __FUNCTION__, ret));
+
+    return ret;
+
+}
+#else
+INT Set_ATE_Load_E2P_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	USHORT 			WriteEEPROM[(EEPROM_SIZE/2)];
+	struct iwreq	*wrq = (struct iwreq *)arg;
+
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("===> %s (wrq->u.data.length = %d)\n\n", __FUNCTION__, wrq->u.data.length));
+
+	if (wrq->u.data.length != EEPROM_SIZE)
+	{
+		ate_print("%s: error length (=%d) from host\n",
+			   __FUNCTION__, wrq->u.data.length);
+		return FALSE;
+	}
+	else/* (wrq->u.data.length == EEPROM_SIZE) */
+	{
+		/* zero the e2p buffer */
+		NdisZeroMemory((PUCHAR)WriteEEPROM, EEPROM_SIZE);
+
+		/* fill the local buffer */
+		NdisMoveMemory((PUCHAR)WriteEEPROM, wrq->u.data.pointer, wrq->u.data.length);
+
+		do
+		{
+				/* write the content of .bin file to EEPROM */
+				rt_ee_write_all(pAd, WriteEEPROM);
+
+		} while(FALSE);
+		}
+
+    ATEDBGPRINT(RT_DEBUG_TRACE, ("<=== %s\n", __FUNCTION__));
+
+    return TRUE;
+
+}
+#endif // !UCOS //
+
+INT Set_ATE_Read_E2P_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	USHORT buffer[EEPROM_SIZE/2];
+	USHORT *p;
+	int i;
+
+	rt_ee_read_all(pAd, (USHORT *)buffer);
+	p = buffer;
+	for (i = 0; i < (EEPROM_SIZE/2); i++)
+	{
+		ate_print("%4.4x ", *p);
+		if (((i+1) % 16) == 0)
+			ate_print("\n");
+		p++;
+	}
+	return TRUE;
+}
+
+INT	Set_ATE_Show_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ate_print("Mode=%d\n", pAd->ate.Mode);
+	ate_print("TxPower0=%d\n", pAd->ate.TxPower0);
+	ate_print("TxPower1=%d\n", pAd->ate.TxPower1);
+	ate_print("TxAntennaSel=%d\n", pAd->ate.TxAntennaSel);
+	ate_print("RxAntennaSel=%d\n", pAd->ate.RxAntennaSel);
+	ate_print("BBPCurrentBW=%d\n", pAd->ate.TxWI.BW);
+	ate_print("GI=%d\n", pAd->ate.TxWI.ShortGI);
+	ate_print("MCS=%d\n", pAd->ate.TxWI.MCS);
+	ate_print("TxMode=%d\n", pAd->ate.TxWI.PHYMODE);
+	ate_print("Addr1=%02x:%02x:%02x:%02x:%02x:%02x\n",
+		pAd->ate.Addr1[0], pAd->ate.Addr1[1], pAd->ate.Addr1[2], pAd->ate.Addr1[3], pAd->ate.Addr1[4], pAd->ate.Addr1[5]);
+	ate_print("Addr2=%02x:%02x:%02x:%02x:%02x:%02x\n",
+		pAd->ate.Addr2[0], pAd->ate.Addr2[1], pAd->ate.Addr2[2], pAd->ate.Addr2[3], pAd->ate.Addr2[4], pAd->ate.Addr2[5]);
+	ate_print("Addr3=%02x:%02x:%02x:%02x:%02x:%02x\n",
+		pAd->ate.Addr3[0], pAd->ate.Addr3[1], pAd->ate.Addr3[2], pAd->ate.Addr3[3], pAd->ate.Addr3[4], pAd->ate.Addr3[5]);
+	ate_print("Channel=%d\n", pAd->ate.Channel);
+	ate_print("TxLength=%d\n", pAd->ate.TxLength);
+	ate_print("TxCount=%u\n", pAd->ate.TxCount);
+	ate_print("RFFreqOffset=%d\n", pAd->ate.RFFreqOffset);
+	ate_print(KERN_EMERG "Set_ATE_Show_Proc Success\n");
+	return TRUE;
+}
+
+INT	Set_ATE_Help_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ate_print("ATE=ATESTART, ATESTOP, TXCONT, TXCARR, TXFRAME, RXFRAME\n");
+	ate_print("ATEDA\n");
+	ate_print("ATESA\n");
+	ate_print("ATEBSSID\n");
+	ate_print("ATECHANNEL, range:0~14(unless A band !)\n");
+	ate_print("ATETXPOW0, set power level of antenna 1.\n");
+	ate_print("ATETXPOW1, set power level of antenna 2.\n");
+	ate_print("ATETXANT, set TX antenna. 0:all, 1:antenna one, 2:antenna two.\n");
+	ate_print("ATERXANT, set RX antenna.0:all, 1:antenna one, 2:antenna two, 3:antenna three.\n");
+	ate_print("ATETXFREQOFFSET, set frequency offset, range 0~63\n");
+	ate_print("ATETXBW, set BandWidth, 0:20MHz, 1:40MHz.\n");
+	ate_print("ATETXLEN, set Frame length, range 24~%d\n", (MAX_FRAME_SIZE - 34/* == 2312 */));
+	ate_print("ATETXCNT, set how many frame going to transmit.\n");
+	ate_print("ATETXMCS, set MCS, reference to rate table.\n");
+	ate_print("ATETXMODE, set Mode 0:CCK, 1:OFDM, 2:HT-Mix, 3:GreenField, reference to rate table.\n");
+	ate_print("ATETXGI, set GI interval, 0:Long, 1:Short\n");
+	ate_print("ATERXFER, 0:disable Rx Frame error rate. 1:enable Rx Frame error rate.\n");
+	ate_print("ATERRF, show all RF registers.\n");
+	ate_print("ATEWRF1, set RF1 register.\n");
+	ate_print("ATEWRF2, set RF2 register.\n");
+	ate_print("ATEWRF3, set RF3 register.\n");
+	ate_print("ATEWRF4, set RF4 register.\n");
+	ate_print("ATELDE2P, load EEPROM from .bin file.\n");
+	ate_print("ATERE2P, display all EEPROM content.\n");
+	ate_print("ATESHOW, display all parameters of ATE.\n");
+	ate_print("ATEHELP, online help.\n");
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+
+	AsicSwitchChannel() dedicated for ATE.
+
+    ==========================================================================
+*/
+VOID ATEAsicSwitchChannel(
+    IN PRTMP_ADAPTER pAd)
+{
+	UINT32 R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0, Value = 0;
+	CHAR TxPwer = 0, TxPwer2 = 0;
+	UCHAR index, BbpValue = 0, R66 = 0x30;
+	RTMP_RF_REGS *RFRegTable;
+	UCHAR Channel;
+
+#ifdef RALINK_28xx_QA
+	if ((pAd->ate.bQATxStart == TRUE) || (pAd->ate.bQARxStart == TRUE))
+	{
+		if (pAd->ate.Channel != pAd->LatchRfRegs.Channel)
+		{
+			pAd->ate.Channel = pAd->LatchRfRegs.Channel;
+		}
+		return;
+	}
+	else
+#endif // RALINK_28xx_QA //
+	Channel = pAd->ate.Channel;
+
+	// Select antenna
+	AsicAntennaSelect(pAd, Channel);
+
+	// fill Tx power value
+	TxPwer = pAd->ate.TxPower0;
+	TxPwer2 = pAd->ate.TxPower1;
+#ifdef RT30xx
+//2008/07/10:KH add to support 3070 ATE<--
+
+	// The RF programming sequence is difference between 3xxx and 2xxx
+	// The 3070 is 1T1R. Therefore, we don't need to set the number of Tx/Rx path and the only job is to set the parameters of channels.
+	if (IS_RT30xx(pAd) && ((pAd->RfIcType == RFIC_3020) ||
+(pAd->RfIcType == RFIC_3021) || (pAd->RfIcType == RFIC_3022) ||
+(pAd->RfIcType == RFIC_2020)))
+	{
+		/* modify by WY for Read RF Reg. error */
+		UCHAR RFValue;
+
+		for (index = 0; index < NUM_OF_3020_CHNL; index++)
+		{
+			if (Channel == FreqItems3020[index].Channel)
+			{
+				// Programming channel parameters
+				RT30xxWriteRFRegister(pAd, RF_R02, FreqItems3020[index].N);
+				RT30xxWriteRFRegister(pAd, RF_R03, FreqItems3020[index].K);
+
+				RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RFValue);
+				RFValue = (RFValue & 0xFC) | FreqItems3020[index].R;
+				RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RFValue);
+
+				// Set Tx Power
+				RT30xxReadRFRegister(pAd, RF_R12, (PUCHAR)&RFValue);
+				RFValue = (RFValue & 0xE0) | TxPwer;
+				RT30xxWriteRFRegister(pAd, RF_R12, (UCHAR)RFValue);
+
+				// Set RF offset
+				RT30xxReadRFRegister(pAd, RF_R23, (PUCHAR)&RFValue);
+				//2008/08/06: KH modified "pAd->RFFreqOffset" to "pAd->ate.RFFreqOffset"
+				RFValue = (RFValue & 0x80) | pAd->ate.RFFreqOffset;
+				RT30xxWriteRFRegister(pAd, RF_R23, (UCHAR)RFValue);
+
+				// Set BW
+				if (pAd->ate.TxWI.BW == BW_40)
+				{
+					RFValue = pAd->Mlme.CaliBW40RfR24;
+					//DISABLE_11N_CHECK(pAd);
+				}
+				else
+				{
+					RFValue = pAd->Mlme.CaliBW20RfR24;
+				}
+				RT30xxWriteRFRegister(pAd, RF_R24, (UCHAR)RFValue);
+
+				// Enable RF tuning
+				RT30xxReadRFRegister(pAd, RF_R07, (PUCHAR)&RFValue);
+				RFValue = RFValue | 0x1;
+				RT30xxWriteRFRegister(pAd, RF_R07, (UCHAR)RFValue);
+
+				// latch channel for future usage.
+				pAd->LatchRfRegs.Channel = Channel;
+
+				break;
+			}
+		}
+
+		DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
+			Channel,
+			pAd->RfIcType,
+			TxPwer,
+			TxPwer2,
+			pAd->Antenna.field.TxPath,
+			FreqItems3020[index].N,
+			FreqItems3020[index].K,
+			FreqItems3020[index].R));
+	}
+	else
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RT30xx //
+{
+	RFRegTable = RF2850RegTable;
+
+	switch (pAd->RfIcType)
+	{
+		/* But only 2850 and 2750 support 5.5GHz band... */
+		case RFIC_2820:
+		case RFIC_2850:
+		case RFIC_2720:
+		case RFIC_2750:
+
+			for (index = 0; index < NUM_OF_2850_CHNL; index++)
+			{
+				if (Channel == RFRegTable[index].Channel)
+				{
+					R2 = RFRegTable[index].R2;
+					if (pAd->Antenna.field.TxPath == 1)
+					{
+						R2 |= 0x4000;	// If TXpath is 1, bit 14 = 1;
+					}
+
+					if (pAd->Antenna.field.RxPath == 2)
+					{
+						switch (pAd->ate.RxAntennaSel)
+						{
+							case 1:
+								R2 |= 0x20040;
+								ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+								BbpValue &= 0xE4;
+								BbpValue |= 0x00;
+								ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+								break;
+							case 2:
+								R2 |= 0x10040;
+								ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+								BbpValue &= 0xE4;
+								BbpValue |= 0x01;
+								ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+								break;
+							default:
+								R2 |= 0x40;
+								ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+								BbpValue &= 0xE4;
+								/* Only enable two Antenna to receive. */
+								BbpValue |= 0x08;
+								ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+								break;
+						}
+					}
+					else if (pAd->Antenna.field.RxPath == 1)
+					{
+						R2 |= 0x20040;	// write 1 to off RxPath
+					}
+
+					if (pAd->Antenna.field.TxPath == 2)
+					{
+						if (pAd->ate.TxAntennaSel == 1)
+						{
+							R2 |= 0x4000;	// If TX Antenna select is 1 , bit 14 = 1; Disable Ant 2
+							ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue);
+							BbpValue &= 0xE7;		//11100111B
+							ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue);
+						}
+						else if (pAd->ate.TxAntennaSel == 2)
+						{
+							R2 |= 0x8000;	// If TX Antenna select is 2 , bit 15 = 1; Disable Ant 1
+							ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue);
+							BbpValue &= 0xE7;
+							BbpValue |= 0x08;
+							ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue);
+						}
+						else
+						{
+							ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue);
+							BbpValue &= 0xE7;
+							BbpValue |= 0x10;
+							ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue);
+						}
+					}
+					if (pAd->Antenna.field.RxPath == 3)
+					{
+						switch (pAd->ate.RxAntennaSel)
+						{
+							case 1:
+								R2 |= 0x20040;
+								ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+								BbpValue &= 0xE4;
+								BbpValue |= 0x00;
+								ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+								break;
+							case 2:
+								R2 |= 0x10040;
+								ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+								BbpValue &= 0xE4;
+								BbpValue |= 0x01;
+								ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+								break;
+							case 3:
+								R2 |= 0x30000;
+								ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+								BbpValue &= 0xE4;
+								BbpValue |= 0x02;
+								ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+								break;
+							default:
+								ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+								BbpValue &= 0xE4;
+								BbpValue |= 0x10;
+								ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+								break;
+						}
+					}
+
+					if (Channel > 14)
+					{
+						// initialize R3, R4
+						R3 = (RFRegTable[index].R3 & 0xffffc1ff);
+						R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->ate.RFFreqOffset << 15);
+
+                        // According the Rory's suggestion to solve the middle range issue.
+						// 5.5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB
+						// R3
+						if ((TxPwer >= -7) && (TxPwer < 0))
+						{
+							TxPwer = (7+TxPwer);
+							TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
+							R3 |= (TxPwer << 10);
+							ATEDBGPRINT(RT_DEBUG_TRACE, ("ATEAsicSwitchChannel: TxPwer=%d \n", TxPwer));
+						}
+						else
+						{
+							TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
+							R3 |= (TxPwer << 10) | (1 << 9);
+						}
+
+						// R4
+						if ((TxPwer2 >= -7) && (TxPwer2 < 0))
+						{
+							TxPwer2 = (7+TxPwer2);
+							TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
+							R4 |= (TxPwer2 << 7);
+							ATEDBGPRINT(RT_DEBUG_TRACE, ("ATEAsicSwitchChannel: TxPwer2=%d \n", TxPwer2));
+						}
+						else
+						{
+							TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
+							R4 |= (TxPwer2 << 7) | (1 << 6);
+						}
+					}
+					else
+					{
+						R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); // set TX power0
+						R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->ate.RFFreqOffset << 15) | (TxPwer2 <<6);// Set freq offset & TxPwr1
+					}
+
+					// Based on BBP current mode before changing RF channel.
+					if (pAd->ate.TxWI.BW == BW_40)
+					{
+						R4 |=0x200000;
+					}
+
+					// Update variables
+					pAd->LatchRfRegs.Channel = Channel;
+					pAd->LatchRfRegs.R1 = RFRegTable[index].R1;
+					pAd->LatchRfRegs.R2 = R2;
+					pAd->LatchRfRegs.R3 = R3;
+					pAd->LatchRfRegs.R4 = R4;
+
+					RtmpRfIoWrite(pAd);
+
+					break;
+				}
+			}
+			break;
+
+		default:
+			break;
+	}
+}
+	// Change BBP setting during switch from a->g, g->a
+	if (Channel <= 14)
+	{
+	    ULONG	TxPinCfg = 0x00050F0A;// 2007.10.09 by Brian : 0x0005050A ==> 0x00050F0A
+
+		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
+		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
+		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
+
+		/* For 1T/2R chip only... */
+	    if (pAd->NicConfig2.field.ExternalLNAForG)
+	    {
+	        ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
+	    }
+	    else
+	    {
+	        ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
+	    }
+
+        // According the Rory's suggestion to solve the middle range issue.
+		ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R86, &BbpValue);
+		ASSERT((BbpValue == 0x00));
+		if ((BbpValue != 0x00))
+		{
+			ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x00);
+		}
+
+		// 5.5GHz band selection PIN, bit1 and bit2 are complement
+		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
+		Value &= (~0x6);
+		Value |= (0x04);
+		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
+
+        // Turn off unused PA or LNA when only 1T or 1R.
+		if (pAd->Antenna.field.TxPath == 1)
+		{
+			TxPinCfg &= 0xFFFFFFF3;
+		}
+		if (pAd->Antenna.field.RxPath == 1)
+		{
+			TxPinCfg &= 0xFFFFF3FF;
+		}
+
+		RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+	}
+	else
+	{
+	    ULONG	TxPinCfg = 0x00050F05;//2007.10.09 by Brian : 0x00050505 ==> 0x00050F05
+
+		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
+		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
+		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
+		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
+
+        // According the Rory's suggestion to solve the middle range issue.
+		ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R86, &BbpValue);
+		ASSERT((BbpValue == 0x00));
+		if ((BbpValue != 0x00))
+		{
+			ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x00);
+		}
+		ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R91, &BbpValue);
+		ASSERT((BbpValue == 0x04));
+
+		ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R92, &BbpValue);
+		ASSERT((BbpValue == 0x00));
+
+		// 5.5GHz band selection PIN, bit1 and bit2 are complement
+		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
+		Value &= (~0x6);
+		Value |= (0x02);
+		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
+
+        // Turn off unused PA or LNA when only 1T or 1R.
+		if (pAd->Antenna.field.TxPath == 1)
+		{
+			TxPinCfg &= 0xFFFFFFF3;
+	    }
+		if (pAd->Antenna.field.RxPath == 1)
+		{
+			TxPinCfg &= 0xFFFFF3FF;
+		}
+
+		RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+	}
+
+    // R66 should be set according to Channel and use 20MHz when scanning
+	if (Channel <= 14)
+	{
+		// BG band
+		R66 = 0x2E + GET_LNA_GAIN(pAd);
+		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+	}
+	else
+	{
+		// 5.5 GHz band
+		if (pAd->ate.TxWI.BW == BW_20)
+		{
+			R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3);
+    		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+		}
+		else
+		{
+			R66 = (UCHAR)(0x3A + (GET_LNA_GAIN(pAd)*5)/3);
+			ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+		}
+	}
+
+	//
+	// On 11A, We should delay and wait RF/BBP to be stable
+	// and the appropriate time should be 1000 micro seconds
+	// 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.
+	//
+	RTMPusecDelay(1000);
+
+	if (Channel > 14)
+	{
+		// When 5.5GHz band the LSB of TxPwr will be used to reduced 7dB or not.
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
+								  Channel,
+								  pAd->RfIcType,
+								  pAd->Antenna.field.TxPath,
+								  pAd->LatchRfRegs.R1,
+								  pAd->LatchRfRegs.R2,
+								  pAd->LatchRfRegs.R3,
+								  pAd->LatchRfRegs.R4));
+	}
+	else
+	{
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%u, Pwr1=%u, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
+								  Channel,
+								  pAd->RfIcType,
+								  (R3 & 0x00003e00) >> 9,
+								  (R4 & 0x000007c0) >> 6,
+								  pAd->Antenna.field.TxPath,
+								  pAd->LatchRfRegs.R1,
+								  pAd->LatchRfRegs.R2,
+								  pAd->LatchRfRegs.R3,
+								  pAd->LatchRfRegs.R4));
+    }
+}
+
+//
+// In fact, no one will call this routine so far !
+//
+/*
+	==========================================================================
+	Description:
+		Gives CCK TX rate 2 more dB TX power.
+		This routine works only in ATE mode.
+
+		calculate desired Tx power in RF R3.Tx0~5,	should consider -
+		0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
+		1. TxPowerPercentage
+		2. auto calibration based on TSSI feedback
+		3. extra 2 db for CCK
+		4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
+
+	NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
+		it should be called AFTER MlmeDynamicTxRateSwitching()
+	==========================================================================
+ */
+VOID ATEAsicAdjustTxPower(
+	IN PRTMP_ADAPTER pAd)
+{
+	INT			i, j;
+	CHAR		DeltaPwr = 0;
+	BOOLEAN		bAutoTxAgc = FALSE;
+	UCHAR		TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
+	UCHAR		BbpR49 = 0, idx;
+	PCHAR		pTxAgcCompensate;
+	ULONG		TxPwr[5];
+	CHAR		Value;
+
+	/* no one calls this procedure so far */
+	if (pAd->ate.TxWI.BW == BW_40)
+	{
+		if (pAd->ate.Channel > 14)
+		{
+			TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
+			TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
+			TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
+			TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
+			TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
+		}
+		else
+		{
+			TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
+			TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
+			TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
+			TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
+			TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
+		}
+	}
+	else
+	{
+		if (pAd->ate.Channel > 14)
+		{
+			TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
+			TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
+			TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
+			TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
+			TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
+		}
+		else
+		{
+			TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
+			TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
+			TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
+			TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
+			TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
+		}
+	}
+
+	// TX power compensation for temperature variation based on TSSI.
+	// Do it per 4 seconds.
+	if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
+	{
+		if (pAd->ate.Channel <= 14)
+		{
+			/* bg channel */
+			bAutoTxAgc         = pAd->bAutoTxAgcG;
+			TssiRef            = pAd->TssiRefG;
+			pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
+			pTssiPlusBoundary  = &pAd->TssiPlusBoundaryG[0];
+			TxAgcStep          = pAd->TxAgcStepG;
+			pTxAgcCompensate   = &pAd->TxAgcCompensateG;
+		}
+		else
+		{
+			/* a channel */
+			bAutoTxAgc         = pAd->bAutoTxAgcA;
+			TssiRef            = pAd->TssiRefA;
+			pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
+			pTssiPlusBoundary  = &pAd->TssiPlusBoundaryA[0];
+			TxAgcStep          = pAd->TxAgcStepA;
+			pTxAgcCompensate   = &pAd->TxAgcCompensateA;
+		}
+
+		if (bAutoTxAgc)
+		{
+			/* BbpR49 is unsigned char */
+			ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
+
+			/* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
+			/* compensate: +4     +3   +2   +1    0   -1   -2   -3   -4 * steps */
+			/* step value is defined in pAd->TxAgcStepG for tx power value */
+
+			/* [4]+1+[4]   p4     p3   p2   p1   o1   m1   m2   m3   m4 */
+			/* ex:         0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
+			   above value are examined in mass factory production */
+			/*             [4]    [3]  [2]  [1]  [0]  [1]  [2]  [3]  [4] */
+
+			/* plus is 0x10 ~ 0x40, minus is 0x60 ~ 0x90 */
+			/* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
+			/* if value is 0x65, tx power will be -= TxAgcStep*(2-1) */
+
+			if (BbpR49 > pTssiMinusBoundary[1])
+			{
+				// Reading is larger than the reference value.
+				// Check for how large we need to decrease the Tx power.
+				for (idx = 1; idx < 5; idx++)
+				{
+					if (BbpR49 <= pTssiMinusBoundary[idx])  // Found the range
+						break;
+				}
+				// The index is the step we should decrease, idx = 0 means there is nothing to compensate
+//				if (R3 > (ULONG) (TxAgcStep * (idx-1)))
+					*pTxAgcCompensate = -(TxAgcStep * (idx-1));
+//				else
+//					*pTxAgcCompensate = -((UCHAR)R3);
+
+				DeltaPwr += (*pTxAgcCompensate);
+				ATEDBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
+					BbpR49, TssiRef, TxAgcStep, idx-1));
+			}
+			else if (BbpR49 < pTssiPlusBoundary[1])
+			{
+				// Reading is smaller than the reference value
+				// check for how large we need to increase the Tx power
+				for (idx = 1; idx < 5; idx++)
+				{
+					if (BbpR49 >= pTssiPlusBoundary[idx])   // Found the range
+						break;
+				}
+				// The index is the step we should increase, idx = 0 means there is nothing to compensate
+				*pTxAgcCompensate = TxAgcStep * (idx-1);
+				DeltaPwr += (*pTxAgcCompensate);
+				ATEDBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
+					BbpR49, TssiRef, TxAgcStep, idx-1));
+			}
+			else
+			{
+				*pTxAgcCompensate = 0;
+				ATEDBGPRINT(RT_DEBUG_TRACE, ("   Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
+					BbpR49, TssiRef, TxAgcStep, 0));
+			}
+		}
+	}
+	else
+	{
+		if (pAd->ate.Channel <= 14)
+		{
+			bAutoTxAgc         = pAd->bAutoTxAgcG;
+			pTxAgcCompensate   = &pAd->TxAgcCompensateG;
+		}
+		else
+		{
+			bAutoTxAgc         = pAd->bAutoTxAgcA;
+			pTxAgcCompensate   = &pAd->TxAgcCompensateA;
+		}
+
+		if (bAutoTxAgc)
+			DeltaPwr += (*pTxAgcCompensate);
+	}
+
+	/* calculate delta power based on the percentage specified from UI */
+	// E2PROM setting is calibrated for maximum TX power (i.e. 100%)
+	// We lower TX power here according to the percentage specified from UI
+	if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff)       // AUTO TX POWER control
+		;
+	else if (pAd->CommonCfg.TxPowerPercentage > 90)  // 91 ~ 100% & AUTO, treat as 100% in terms of mW
+		;
+	else if (pAd->CommonCfg.TxPowerPercentage > 60)  // 61 ~ 90%, treat as 75% in terms of mW
+	{
+		DeltaPwr -= 1;
+	}
+	else if (pAd->CommonCfg.TxPowerPercentage > 30)  // 31 ~ 60%, treat as 50% in terms of mW
+	{
+		DeltaPwr -= 3;
+	}
+	else if (pAd->CommonCfg.TxPowerPercentage > 15)  // 16 ~ 30%, treat as 25% in terms of mW
+	{
+		DeltaPwr -= 6;
+	}
+	else if (pAd->CommonCfg.TxPowerPercentage > 9)   // 10 ~ 15%, treat as 12.5% in terms of mW
+	{
+		DeltaPwr -= 9;
+	}
+	else                                           // 0 ~ 9 %, treat as MIN(~3%) in terms of mW
+	{
+		DeltaPwr -= 12;
+	}
+
+	/* reset different new tx power for different TX rate */
+	for(i=0; i<5; i++)
+	{
+		if (TxPwr[i] != 0xffffffff)
+		{
+			for (j=0; j<8; j++)
+			{
+				Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */
+
+				if ((Value + DeltaPwr) < 0)
+				{
+					Value = 0; /* min */
+				}
+				else if ((Value + DeltaPwr) > 0xF)
+				{
+					Value = 0xF; /* max */
+				}
+				else
+				{
+					Value += DeltaPwr; /* temperature compensation */
+				}
+
+				/* fill new value to CSR offset */
+				TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
+			}
+
+			/* write tx power value to CSR */
+			/* TX_PWR_CFG_0 (8 tx rate) for	TX power for OFDM 12M/18M
+											TX power for OFDM 6M/9M
+											TX power for CCK5.5M/11M
+											TX power for CCK1M/2M */
+			/* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
+			RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]);
+
+
+		}
+	}
+
+}
+
+/*
+	========================================================================
+	Routine Description:
+		Write TxWI for ATE mode.
+
+	Return Value:
+		None
+	========================================================================
+*/
+
+#ifdef RT2870
+static VOID ATEWriteTxWI(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PTXWI_STRUC 	pTxWI,
+	IN	BOOLEAN			FRAG,
+	IN	BOOLEAN			InsTimestamp,
+	IN	BOOLEAN 		AMPDU,
+	IN	BOOLEAN 		Ack,
+	IN	BOOLEAN 		NSeq,		// HW new a sequence.
+	IN	UCHAR			BASize,
+	IN	UCHAR			WCID,
+	IN	ULONG			Length,
+	IN	UCHAR 			PID,
+	IN	UCHAR			MIMOps,
+	IN	UCHAR			Txopmode,
+	IN	BOOLEAN			CfAck,
+	IN	HTTRANSMIT_SETTING	Transmit)
+{
+	//
+	// Always use Long preamble before verifiation short preamble functionality works well.
+	// Todo: remove the following line if short preamble functionality works
+	//
+	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
+	pTxWI->FRAG= FRAG;
+	pTxWI->TS= InsTimestamp;
+	pTxWI->AMPDU = AMPDU;
+
+	pTxWI->MIMOps = PWR_ACTIVE;
+	pTxWI->MpduDensity = 4;
+	pTxWI->ACK = Ack;
+	pTxWI->txop = Txopmode;
+	pTxWI->NSEQ = NSeq;
+	pTxWI->BAWinSize = BASize;
+
+	pTxWI->WirelessCliID = WCID;
+	pTxWI->MPDUtotalByteCount = Length;
+	pTxWI->PacketId = PID;
+
+	pTxWI->BW = Transmit.field.BW;
+	pTxWI->ShortGI = Transmit.field.ShortGI;
+	pTxWI->STBC= Transmit.field.STBC;
+
+	pTxWI->MCS = Transmit.field.MCS;
+	pTxWI->PHYMODE= Transmit.field.MODE;
+
+#ifdef DOT11_N_SUPPORT
+	//
+	// MMPS is 802.11n features. Because TxWI->MCS > 7 must be HT mode,
+	// so need not check if it's HT rate.
+	//
+	if ((MIMOps == MMPS_STATIC) && (pTxWI->MCS > 7))
+		pTxWI->MCS = 7;
+
+	if ((MIMOps == MMPS_DYNAMIC) && (pTxWI->MCS > 7)) // SMPS protect 2 spatial.
+		pTxWI->MIMOps = 1;
+#endif // DOT11_N_SUPPORT //
+
+	pTxWI->CFACK = CfAck;
+
+	return;
+}
+#endif // RT2870 //
+/*
+	========================================================================
+
+	Routine Description:
+		Disable protection for ATE.
+	========================================================================
+*/
+VOID ATEDisableAsicProtect(
+	IN		PRTMP_ADAPTER	pAd)
+{
+	PROT_CFG_STRUC	ProtCfg, ProtCfg4;
+	UINT32 Protect[6];
+	USHORT			offset;
+	UCHAR			i;
+	UINT32 MacReg = 0;
+
+	// Config ASIC RTS threshold register
+	RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
+	MacReg &= 0xFF0000FF;
+	MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
+	RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
+
+	// Initial common protection settings
+	RTMPZeroMemory(Protect, sizeof(Protect));
+	ProtCfg4.word = 0;
+	ProtCfg.word = 0;
+	ProtCfg.field.TxopAllowGF40 = 1;
+	ProtCfg.field.TxopAllowGF20 = 1;
+	ProtCfg.field.TxopAllowMM40 = 1;
+	ProtCfg.field.TxopAllowMM20 = 1;
+	ProtCfg.field.TxopAllowOfdm = 1;
+	ProtCfg.field.TxopAllowCck = 1;
+	ProtCfg.field.RTSThEn = 1;
+	ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+
+	// Handle legacy(B/G) protection
+	ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
+	ProtCfg.field.ProtectCtrl = 0;
+	Protect[0] = ProtCfg.word;
+	Protect[1] = ProtCfg.word;
+
+	// NO PROTECT
+	// 1.All STAs in the BSS are 20/40 MHz HT
+	// 2. in ai 20/40MHz BSS
+	// 3. all STAs are 20MHz in a 20MHz BSS
+	// Pure HT. no protection.
+
+	// MM20_PROT_CFG
+	//	Reserved (31:27)
+	// 	PROT_TXOP(25:20) -- 010111
+	//	PROT_NAV(19:18)  -- 01 (Short NAV protection)
+	//  PROT_CTRL(17:16) -- 00 (None)
+	// 	PROT_RATE(15:0)  -- 0x4004 (OFDM 24M)
+	Protect[2] = 0x01744004;
+
+	// MM40_PROT_CFG
+	//	Reserved (31:27)
+	// 	PROT_TXOP(25:20) -- 111111
+	//	PROT_NAV(19:18)  -- 01 (Short NAV protection)
+	//  PROT_CTRL(17:16) -- 00 (None)
+	// 	PROT_RATE(15:0)  -- 0x4084 (duplicate OFDM 24M)
+	Protect[3] = 0x03f44084;
+
+	// CF20_PROT_CFG
+	//	Reserved (31:27)
+	// 	PROT_TXOP(25:20) -- 010111
+	//	PROT_NAV(19:18)  -- 01 (Short NAV protection)
+	//  PROT_CTRL(17:16) -- 00 (None)
+	// 	PROT_RATE(15:0)  -- 0x4004 (OFDM 24M)
+	Protect[4] = 0x01744004;
+
+	// CF40_PROT_CFG
+	//	Reserved (31:27)
+	// 	PROT_TXOP(25:20) -- 111111
+	//	PROT_NAV(19:18)  -- 01 (Short NAV protection)
+	//  PROT_CTRL(17:16) -- 00 (None)
+	// 	PROT_RATE(15:0)  -- 0x4084 (duplicate OFDM 24M)
+	Protect[5] = 0x03f44084;
+
+	pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
+
+	offset = CCK_PROT_CFG;
+	for (i = 0;i < 6;i++)
+		RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]);
+
+}
+
+#ifdef RT2870
+/*
+	========================================================================
+	Routine	Description:
+		Write TxInfo for ATE mode.
+
+	Return Value:
+		None
+	========================================================================
+*/
+static VOID ATEWriteTxInfo(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PTXINFO_STRUC 	pTxInfo,
+	IN	USHORT		USBDMApktLen,
+	IN	BOOLEAN		bWiv,
+	IN	UCHAR			QueueSel,
+	IN	UCHAR			NextValid,
+	IN	UCHAR			TxBurst)
+{
+	pTxInfo->USBDMATxPktLen = USBDMApktLen;
+	pTxInfo->QSEL = QueueSel;
+
+	if (QueueSel != FIFO_EDCA)
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("=======> QueueSel != FIFO_EDCA<=======\n"));
+
+	pTxInfo->USBDMANextVLD = NextValid;
+	pTxInfo->USBDMATxburst = TxBurst;
+	pTxInfo->WIV = bWiv;
+	pTxInfo->SwUseLastRound = 0;
+	pTxInfo->rsv = 0;
+	pTxInfo->rsv2 = 0;
+
+	return;
+}
+#endif // RT2870 //
+
+/* There are two ways to convert Rssi */
+#if 1
+//
+// The way used with GET_LNA_GAIN().
+//
+CHAR ATEConvertToRssi(
+	IN PRTMP_ADAPTER pAd,
+	IN	CHAR	Rssi,
+	IN  UCHAR   RssiNumber)
+{
+	UCHAR	RssiOffset, LNAGain;
+
+	// Rssi equals to zero should be an invalid value
+	if (Rssi == 0)
+		return -99;
+
+	LNAGain = GET_LNA_GAIN(pAd);
+	if (pAd->LatchRfRegs.Channel > 14)
+	{
+		if (RssiNumber == 0)
+			RssiOffset = pAd->ARssiOffset0;
+		else if (RssiNumber == 1)
+			RssiOffset = pAd->ARssiOffset1;
+		else
+			RssiOffset = pAd->ARssiOffset2;
+	}
+	else
+	{
+		if (RssiNumber == 0)
+			RssiOffset = pAd->BGRssiOffset0;
+		else if (RssiNumber == 1)
+			RssiOffset = pAd->BGRssiOffset1;
+		else
+			RssiOffset = pAd->BGRssiOffset2;
+	}
+
+	return (-12 - RssiOffset - LNAGain - Rssi);
+}
+#else
+//
+// The way originally used in ATE of rt2860ap.
+//
+CHAR ATEConvertToRssi(
+	IN PRTMP_ADAPTER pAd,
+	IN	CHAR			Rssi,
+	IN  UCHAR   RssiNumber)
+{
+	UCHAR	RssiOffset, LNAGain;
+
+	// Rssi equals to zero should be an invalid value
+	if (Rssi == 0)
+		return -99;
+
+    if (pAd->LatchRfRegs.Channel > 14)
+    {
+        LNAGain = pAd->ALNAGain;
+        if (RssiNumber == 0)
+			RssiOffset = pAd->ARssiOffset0;
+		else if (RssiNumber == 1)
+			RssiOffset = pAd->ARssiOffset1;
+		else
+			RssiOffset = pAd->ARssiOffset2;
+    }
+    else
+    {
+        LNAGain = pAd->BLNAGain;
+        if (RssiNumber == 0)
+			RssiOffset = pAd->BGRssiOffset0;
+		else if (RssiNumber == 1)
+			RssiOffset = pAd->BGRssiOffset1;
+		else
+			RssiOffset = pAd->BGRssiOffset2;
+    }
+
+    return (-32 - RssiOffset + LNAGain - Rssi);
+}
+#endif /* end of #if 1 */
+
+/*
+	========================================================================
+
+	Routine Description:
+		Set Japan filter coefficients if needed.
+	Note:
+		This routine should only be called when
+		entering TXFRAME mode or TXCONT mode.
+
+	========================================================================
+*/
+static VOID SetJapanFilter(
+	IN		PRTMP_ADAPTER	pAd)
+{
+	UCHAR			BbpData = 0;
+
+	//
+	// If Channel=14 and Bandwidth=20M and Mode=CCK, set BBP R4 bit5=1
+	// (Japan Tx filter coefficients)when (TXFRAME or TXCONT).
+	//
+	ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BbpData);
+
+    if ((pAd->ate.TxWI.PHYMODE == MODE_CCK) && (pAd->ate.Channel == 14) && (pAd->ate.TxWI.BW == BW_20))
+    {
+        BbpData |= 0x20;    // turn on
+        ATEDBGPRINT(RT_DEBUG_TRACE, ("SetJapanFilter!!!\n"));
+    }
+    else
+    {
+		BbpData &= 0xdf;    // turn off
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("ClearJapanFilter!!!\n"));
+    }
+
+	ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BbpData);
+}
+
+VOID ATESampleRssi(
+	IN PRTMP_ADAPTER	pAd,
+	IN PRXWI_STRUC		pRxWI)
+{
+	/* There are two ways to collect RSSI. */
+#if 1
+	//pAd->LastRxRate = (USHORT)((pRxWI->MCS) + (pRxWI->BW <<7) + (pRxWI->ShortGI <<8)+ (pRxWI->PHYMODE <<14)) ;
+	if (pRxWI->RSSI0 != 0)
+	{
+		pAd->ate.LastRssi0	= ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI0, RSSI_0);
+		pAd->ate.AvgRssi0X8	= (pAd->ate.AvgRssi0X8 - pAd->ate.AvgRssi0) + pAd->ate.LastRssi0;
+		pAd->ate.AvgRssi0  	= pAd->ate.AvgRssi0X8 >> 3;
+	}
+	if (pRxWI->RSSI1 != 0)
+	{
+		pAd->ate.LastRssi1	= ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI1, RSSI_1);
+		pAd->ate.AvgRssi1X8	= (pAd->ate.AvgRssi1X8 - pAd->ate.AvgRssi1) + pAd->ate.LastRssi1;
+		pAd->ate.AvgRssi1	= pAd->ate.AvgRssi1X8 >> 3;
+	}
+	if (pRxWI->RSSI2 != 0)
+	{
+		pAd->ate.LastRssi2	= ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI2, RSSI_2);
+		pAd->ate.AvgRssi2X8	= (pAd->ate.AvgRssi2X8 - pAd->ate.AvgRssi2) + pAd->ate.LastRssi2;
+		pAd->ate.AvgRssi2	= pAd->ate.AvgRssi2X8 >> 3;
+	}
+
+	pAd->ate.LastSNR0 = (CHAR)(pRxWI->SNR0);// CHAR ==> UCHAR ?
+	pAd->ate.LastSNR1 = (CHAR)(pRxWI->SNR1);// CHAR ==> UCHAR ?
+
+	pAd->ate.NumOfAvgRssiSample ++;
+#else
+	pAd->ate.LastSNR0 = (CHAR)(pRxWI->SNR0);
+	pAd->ate.LastSNR1 = (CHAR)(pRxWI->SNR1);
+	pAd->ate.RxCntPerSec++;
+	pAd->ate.LastRssi0 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI0, RSSI_0);
+	pAd->ate.LastRssi1 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI1, RSSI_1);
+	pAd->ate.LastRssi2 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI2, RSSI_2);
+	pAd->ate.AvgRssi0X8 = (pAd->ate.AvgRssi0X8 - pAd->ate.AvgRssi0) + pAd->ate.LastRssi0;
+	pAd->ate.AvgRssi0 = pAd->ate.AvgRssi0X8 >> 3;
+	pAd->ate.AvgRssi1X8 = (pAd->ate.AvgRssi1X8 - pAd->ate.AvgRssi1) + pAd->ate.LastRssi1;
+	pAd->ate.AvgRssi1 = pAd->ate.AvgRssi1X8 >> 3;
+	pAd->ate.AvgRssi2X8 = (pAd->ate.AvgRssi2X8 - pAd->ate.AvgRssi2) + pAd->ate.LastRssi2;
+	pAd->ate.AvgRssi2 = pAd->ate.AvgRssi2X8 >> 3;
+	pAd->ate.NumOfAvgRssiSample ++;
+#endif
+}
+
+#ifdef CONFIG_STA_SUPPORT
+VOID RTMPStationStop(
+    IN  PRTMP_ADAPTER   pAd)
+{
+//	BOOLEAN       Cancelled;
+
+    ATEDBGPRINT(RT_DEBUG_TRACE, ("==> RTMPStationStop\n"));
+
+	// For rx statistics, we need to keep this timer running.
+//	RTMPCancelTimer(&pAd->Mlme.PeriodicTimer,      &Cancelled);
+
+    ATEDBGPRINT(RT_DEBUG_TRACE, ("<== RTMPStationStop\n"));
+}
+
+VOID RTMPStationStart(
+    IN  PRTMP_ADAPTER   pAd)
+{
+    ATEDBGPRINT(RT_DEBUG_TRACE, ("==> RTMPStationStart\n"));
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("<== RTMPStationStart\n"));
+}
+#endif // CONFIG_STA_SUPPORT //
+
+/*
+	==========================================================================
+	Description:
+		Setup Frame format.
+	NOTE:
+		This routine should only be used in ATE mode.
+	==========================================================================
+ */
+
+#ifdef RT2870
+/*======================Start of RT2870======================*/
+/*                                                           */
+/*                                                           */
+static INT ATESetUpFrame(
+	IN PRTMP_ADAPTER pAd,
+	IN UINT32 TxIdx)
+{
+	UINT j;
+	PTX_CONTEXT	pNullContext;
+	PUCHAR			pDest;
+	HTTRANSMIT_SETTING	TxHTPhyMode;
+	PTXWI_STRUC		pTxWI;
+	PTXINFO_STRUC		pTxInfo;
+	UINT32			TransferBufferLength, OrgBufferLength = 0;
+	UCHAR			padLen = 0;
+#ifdef RALINK_28xx_QA
+	PHEADER_802_11	pHeader80211 = NULL;
+#endif // RALINK_28xx_QA //
+
+	if ((RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) ||
+		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) ||
+		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) ||
+		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+	{
+		return -1;
+	}
+
+	/* We always use QID_AC_BE and FIFO_EDCA in ATE mode. */
+
+	pNullContext = &(pAd->NullContext);
+	ASSERT(pNullContext != NULL);
+
+	if (pNullContext->InUse == FALSE)
+	{
+		// Set the in use bit
+		pNullContext->InUse = TRUE;
+		NdisZeroMemory(&(pAd->NullFrame), sizeof(HEADER_802_11));
+
+		// Fill 802.11 header.
+#ifdef RALINK_28xx_QA
+		if (pAd->ate.bQATxStart == TRUE)
+		{
+			pHeader80211 = NdisMoveMemory(&(pAd->NullFrame), pAd->ate.Header, pAd->ate.HLen);
+//			pDest = NdisMoveMemory(&(pAd->NullFrame), pAd->ate.Header, pAd->ate.HLen);
+//			pHeader80211 = (PHEADER_802_11)pDest;
+		}
+		else
+#endif // RALINK_28xx_QA //
+		{
+			// Fill 802.11 header.
+			NdisMoveMemory(&(pAd->NullFrame), TemplateFrame, sizeof(HEADER_802_11));
+		}
+#ifdef RT_BIG_ENDIAN
+		RTMPFrameEndianChange(pAd, (PUCHAR)&(pAd->NullFrame), DIR_READ, FALSE);
+#endif // RT_BIG_ENDIAN //
+
+#ifdef RALINK_28xx_QA
+		if (pAd->ate.bQATxStart == TRUE)
+		{
+			/* modify sequence number.... */
+			if (pAd->ate.TxDoneCount == 0)
+			{
+				pAd->ate.seq = pHeader80211->Sequence;
+			}
+			else
+			{
+				pHeader80211->Sequence = ++pAd->ate.seq;
+			}
+			/* We already got all the addr. fields from QA GUI. */
+		}
+		else
+#endif // RALINK_28xx_QA //
+		{
+			COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->ate.Addr1);
+			COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->ate.Addr2);
+			COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->ate.Addr3);
+		}
+
+		RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[0], TX_BUFFER_NORMSIZE);//???
+		pTxInfo = (PTXINFO_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[0];
+
+#ifdef RALINK_28xx_QA
+		if (pAd->ate.bQATxStart == TRUE)
+		{
+			// Avoid to exceed the range of WirelessPacket[].
+			ASSERT(pAd->ate.TxInfo.USBDMATxPktLen <= (MAX_FRAME_SIZE - 34/* == 2312 */));
+			NdisMoveMemory(pTxInfo, &(pAd->ate.TxInfo), sizeof(pAd->ate.TxInfo));
+		}
+		else
+#endif // RALINK_28xx_QA //
+		{
+			// Avoid to exceed the range of WirelessPacket[].
+			ASSERT(pAd->ate.TxLength <= (MAX_FRAME_SIZE - 34/* == 2312 */));
+
+			// pTxInfo->USBDMATxPktLen will be updated to include padding later.
+			ATEWriteTxInfo(pAd, pTxInfo, (USHORT)(TXWI_SIZE + pAd->ate.TxLength), TRUE, EpToQueue[MGMTPIPEIDX], FALSE,  FALSE);
+			pTxInfo->QSEL = FIFO_EDCA;
+		}
+
+		pTxWI = (PTXWI_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
+
+		// Fill TxWI.
+		if (pAd->ate.bQATxStart == TRUE)
+		{
+			TxHTPhyMode.field.BW = pAd->ate.TxWI.BW;
+			TxHTPhyMode.field.ShortGI = pAd->ate.TxWI.ShortGI;
+			TxHTPhyMode.field.STBC = pAd->ate.TxWI.STBC;
+			TxHTPhyMode.field.MCS = pAd->ate.TxWI.MCS;
+			TxHTPhyMode.field.MODE = pAd->ate.TxWI.PHYMODE;
+			ATEWriteTxWI(pAd, pTxWI, pAd->ate.TxWI.FRAG, pAd->ate.TxWI.TS, pAd->ate.TxWI.AMPDU, pAd->ate.TxWI.ACK, pAd->ate.TxWI.NSEQ,
+				pAd->ate.TxWI.BAWinSize, BSSID_WCID, pAd->ate.TxWI.MPDUtotalByteCount/* include 802.11 header */, pAd->ate.TxWI.PacketId, 0, pAd->ate.TxWI.txop/*IFS_HTTXOP*/, pAd->ate.TxWI.CFACK/*FALSE*/, TxHTPhyMode);
+		}
+		else
+		{
+			TxHTPhyMode.field.BW = pAd->ate.TxWI.BW;
+			TxHTPhyMode.field.ShortGI = pAd->ate.TxWI.ShortGI;
+			TxHTPhyMode.field.STBC = 0;
+			TxHTPhyMode.field.MCS = pAd->ate.TxWI.MCS;
+			TxHTPhyMode.field.MODE = pAd->ate.TxWI.PHYMODE;
+
+			ATEWriteTxWI(pAd, pTxWI,  FALSE, FALSE, FALSE, FALSE/* No ack required. */, FALSE, 0, BSSID_WCID, pAd->ate.TxLength,
+				0, 0, IFS_HTTXOP, FALSE, TxHTPhyMode);// "MMPS_STATIC" instead of "MMPS_DYNAMIC" ???
+		}
+
+		RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE+TXWI_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
+
+		pDest = &(pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE+TXWI_SIZE+sizeof(HEADER_802_11)]);
+
+		// Prepare frame payload
+#ifdef RALINK_28xx_QA
+		if (pAd->ate.bQATxStart == TRUE)
+		{
+			// copy pattern
+			if ((pAd->ate.PLen != 0))
+			{
+				for (j = 0; j < pAd->ate.DLen; j+=pAd->ate.PLen)
+				{
+					RTMPMoveMemory(pDest, pAd->ate.Pattern, pAd->ate.PLen);
+					pDest += pAd->ate.PLen;
+				}
+			}
+			TransferBufferLength = TXINFO_SIZE + TXWI_SIZE + pAd->ate.TxWI.MPDUtotalByteCount;
+		}
+		else
+#endif // RALINK_28xx_QA //
+		{
+		    for (j = 0; j < (pAd->ate.TxLength - sizeof(HEADER_802_11)); j++)
+		    {
+				*pDest = 0xA5;
+				pDest += 1;
+		    }
+			TransferBufferLength = TXINFO_SIZE + TXWI_SIZE + pAd->ate.TxLength;
+		}
+
+#if 1
+		OrgBufferLength = TransferBufferLength;
+		TransferBufferLength = (TransferBufferLength + 3) & (~3);
+
+		// Always add 4 extra bytes at every packet.
+		padLen = TransferBufferLength - OrgBufferLength + 4;/* 4 == last packet padding */
+		ASSERT((padLen <= (RTMP_PKT_TAIL_PADDING - 4/* 4 == MaxBulkOutsize alignment padding */)));
+
+		/* Now memzero all extra padding bytes. */
+		NdisZeroMemory(pDest, padLen);
+		pDest += padLen;
+#else
+		if ((TransferBufferLength % 4) == 1)
+		{
+			NdisZeroMemory(pDest, 7);
+			pDest += 7;
+			TransferBufferLength  += 3;
+		}
+		else if ((TransferBufferLength % 4) == 2)
+		{
+			NdisZeroMemory(pDest, 6);
+			pDest += 6;
+			TransferBufferLength  += 2;
+		}
+		else if ((TransferBufferLength % 4) == 3)
+		{
+			NdisZeroMemory(pDest, 5);
+			pDest += 5;
+			TransferBufferLength  += 1;
+		}
+#endif // 1 //
+
+		// Update pTxInfo->USBDMATxPktLen to include padding.
+		pTxInfo->USBDMATxPktLen = TransferBufferLength - TXINFO_SIZE;
+
+		TransferBufferLength += 4;
+
+		// If TransferBufferLength is multiple of 64, add extra 4 bytes again.
+		if ((TransferBufferLength % pAd->BulkOutMaxPacketSize) == 0)
+		{
+			NdisZeroMemory(pDest, 4);
+			TransferBufferLength += 4;
+		}
+
+		// Fill out frame length information for global Bulk out arbitor
+		pAd->NullContext.BulkOutSize = TransferBufferLength;
+	}
+#ifdef RT_BIG_ENDIAN
+	RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
+	RTMPFrameEndianChange(pAd, (((PUCHAR)pTxInfo)+TXWI_SIZE+TXINFO_SIZE), DIR_WRITE, FALSE);
+    RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
+#endif // RT_BIG_ENDIAN //
+	return 0;
+}
+
+VOID ATE_RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
+{
+	PRTMP_ADAPTER		pAd;
+	PTX_CONTEXT		    pNullContext;
+	UCHAR				BulkOutPipeId;
+	NTSTATUS			Status;
+	unsigned long		IrqFlags;
+	ULONG			    OldValue;
+
+	pNullContext = (PTX_CONTEXT)pUrb->context;
+	pAd = pNullContext->pAd;
+
+
+	// Reset Null frame context flags
+	pNullContext->IRPPending = FALSE;
+	pNullContext->InUse = FALSE;
+	Status = pUrb->status;
+
+	// Store BulkOut PipeId
+	BulkOutPipeId = pNullContext->BulkOutPipeId;
+	pAd->BulkOutDataOneSecCount++;
+
+	if (Status == USB_ST_NOERROR)
+	{
+#ifdef RALINK_28xx_QA
+		if ((ATE_ON(pAd)) && (pAd->ate.bQATxStart == TRUE))
+		{
+			if (pAd->ate.QID == BulkOutPipeId)
+			{
+				// Let Rx can have a chance to break in during Tx process,
+				// especially for loopback mode in QA ATE.
+				// To trade off between tx performance and loopback mode integrity.
+				/* Q   : Now Rx is handled by tasklet, do we still need this delay ? */
+				/* Ans : Even tasklet is used, Rx/Tx < 1 if we do not delay for a while right here. */
+				RTMPusecDelay(500);
+				pAd->ate.TxDoneCount++;
+				pAd->RalinkCounters.KickTxCount++;
+				ASSERT(pAd->ate.QID == 0);
+				pAd->ate.TxAc0++;
+			}
+		}
+#endif // RALINK_28xx_QA //
+		pAd->BulkOutComplete++;
+
+		pAd->Counters8023.GoodTransmits++;
+
+		/* Don't worry about the queue is empty or not. This function will check itself. */
+		RTMPDeQueuePacket(pAd, TRUE, BulkOutPipeId, MAX_TX_PROCESS);
+
+		/* In 28xx, SendTxWaitQueue ==> TxSwQueue  */
+/*
+		if (pAd->SendTxWaitQueue[BulkOutPipeId].Number > 0)
+		{
+			RTMPDeQueuePacket(pAd, BulkOutPipeId);
+		}
+*/
+	}
+	else	// STATUS_OTHER
+	{
+		pAd->BulkOutCompleteOther++;
+
+		ATEDBGPRINT(RT_DEBUG_ERROR, ("BulkOutDataPacket Failed STATUS_OTHER = 0x%x . \n", Status));
+		ATEDBGPRINT(RT_DEBUG_ERROR, (">>BulkOutReq=0x%lx, BulkOutComplete=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete));
+
+		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
+		{
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+			/* In 28xx, RT_OID_USB_RESET_BULK_OUT ==> CMDTHREAD_RESET_BULK_OUT */
+			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+			// Check
+			BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+			pAd->BulkOutPending[BulkOutPipeId] = FALSE;
+			pAd->bulkResetPipeid = BulkOutPipeId;
+			BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+			return;
+		}
+	}
+
+
+
+	if (atomic_read(&pAd->BulkOutRemained) > 0)
+	{
+		atomic_dec(&pAd->BulkOutRemained);
+	}
+
+	// 1st - Transmit Success
+	OldValue = pAd->WlanCounters.TransmittedFragmentCount.u.LowPart;
+	pAd->WlanCounters.TransmittedFragmentCount.u.LowPart++;
+
+	if (pAd->WlanCounters.TransmittedFragmentCount.u.LowPart < OldValue)
+	{
+		pAd->WlanCounters.TransmittedFragmentCount.u.HighPart++;
+	}
+
+	if(((pAd->ContinBulkOut == TRUE ) ||(atomic_read(&pAd->BulkOutRemained) > 0)) && (pAd->ate.Mode & ATE_TXFRAME))
+	{
+		RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+	}
+	else
+	{
+		RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+#ifdef RALINK_28xx_QA
+		pAd->ate.TxStatus = 0;
+#endif // RALINK_28xx_QA //
+	}
+
+	BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+	pAd->BulkOutPending[BulkOutPipeId] = FALSE;
+	BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+	// Always call Bulk routine, even reset bulk.
+	// The protection of rest bulk should be in BulkOut routine.
+	RTUSBKickBulkOut(pAd);
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+	========================================================================
+*/
+VOID	ATE_RTUSBBulkOutDataPacket(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			BulkOutPipeId)
+{
+	PTX_CONTEXT		pNullContext = &(pAd->NullContext);
+	PURB			pUrb;
+	int				ret = 0;
+	unsigned long	IrqFlags;
+
+
+	ASSERT(BulkOutPipeId == 0);
+
+	/* Build up the frame first. */
+//	ATESetUpFrame(pAd, 0);
+
+	BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+	if (pAd->BulkOutPending[BulkOutPipeId] == TRUE)
+	{
+		BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+		return;
+	}
+
+	pAd->BulkOutPending[BulkOutPipeId] = TRUE;
+	BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+	// Increase Total transmit byte counter
+	pAd->RalinkCounters.OneSecTransmittedByteCount +=  pNullContext->BulkOutSize;
+	pAd->RalinkCounters.TransmittedByteCount +=  pNullContext->BulkOutSize;
+
+	// Clear ATE frame bulk out flag
+	RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+
+	// Init Tx context descriptor
+	pNullContext->IRPPending = TRUE;
+	RTUSBInitTxDesc(pAd, pNullContext, BulkOutPipeId, (usb_complete_t)ATE_RTUSBBulkOutDataPacketComplete);
+	pUrb = pNullContext->pUrb;
+
+	if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
+	{
+		ATEDBGPRINT(RT_DEBUG_ERROR, ("ATE_RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
+		return;
+	}
+
+	pAd->BulkOutReq++;
+	return;
+
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+	========================================================================
+*/
+VOID	ATE_RTUSBCancelPendingBulkInIRP(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	PRX_CONTEXT		pRxContext;
+	UINT			i;
+
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("--->ATE_RTUSBCancelPendingBulkInIRP\n"));
+#if 1
+	for ( i = 0; i < (RX_RING_SIZE); i++)
+	{
+		pRxContext = &(pAd->RxContext[i]);
+		if(pRxContext->IRPPending == TRUE)
+		{
+			RTUSB_UNLINK_URB(pRxContext->pUrb);
+			pRxContext->IRPPending = FALSE;
+			pRxContext->InUse = FALSE;
+			//NdisInterlockedDecrement(&pAd->PendingRx);
+			//pAd->PendingRx--;
+		}
+	}
+#else
+	for ( i = 0; i < (RX_RING_SIZE); i++)
+	{
+		pRxContext = &(pAd->RxContext[i]);
+		if(atomic_read(&pRxContext->IrpLock) == IRPLOCK_CANCELABLE)
+		{
+			RTUSB_UNLINK_URB(pRxContext->pUrb);
+		}
+		InterlockedExchange(&pRxContext->IrpLock, IRPLOCK_CANCE_START);
+	}
+#endif // 1 //
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("<---ATE_RTUSBCancelPendingBulkInIRP\n"));
+	return;
+}
+#endif // RT2870 //
+
+VOID rt_ee_read_all(PRTMP_ADAPTER pAd, USHORT *Data)
+{
+	USHORT i;
+	USHORT value;
+
+	for (i = 0 ; i < EEPROM_SIZE/2 ; )
+	{
+		/* "value" is expecially for some compilers... */
+		RT28xx_EEPROM_READ16(pAd, i*2, value);
+		Data[i] = value;
+		i++;
+	}
+}
+
+VOID rt_ee_write_all(PRTMP_ADAPTER pAd, USHORT *Data)
+{
+	USHORT i;
+	USHORT value;
+
+	for (i = 0 ; i < EEPROM_SIZE/2 ; )
+	{
+		/* "value" is expecially for some compilers... */
+		value = Data[i];
+		RT28xx_EEPROM_WRITE16(pAd, i*2, value);
+		i ++;
+	}
+}
+#ifdef RALINK_28xx_QA
+VOID ATE_QA_Statistics(
+	IN PRTMP_ADAPTER			pAd,
+	IN PRXWI_STRUC				pRxWI,
+	IN PRT28XX_RXD_STRUC		pRxD,
+	IN PHEADER_802_11			pHeader)
+{
+	// update counter first
+	if (pHeader != NULL)
+	{
+		if (pHeader->FC.Type == BTYPE_DATA)
+		{
+			if (pRxD->U2M)
+				pAd->ate.U2M++;
+			else
+				pAd->ate.OtherData++;
+		}
+		else if (pHeader->FC.Type == BTYPE_MGMT)
+		{
+			if (pHeader->FC.SubType == SUBTYPE_BEACON)
+				pAd->ate.Beacon++;
+			else
+				pAd->ate.OtherCount++;
+		}
+		else if (pHeader->FC.Type == BTYPE_CNTL)
+		{
+			pAd->ate.OtherCount++;
+		}
+	}
+	pAd->ate.RSSI0 = pRxWI->RSSI0;
+	pAd->ate.RSSI1 = pRxWI->RSSI1;
+	pAd->ate.RSSI2 = pRxWI->RSSI2;
+	pAd->ate.SNR0 = pRxWI->SNR0;
+	pAd->ate.SNR1 = pRxWI->SNR1;
+}
+
+/* command id with Cmd Type == 0x0008(for 28xx)/0x0005(for iNIC) */
+#define RACFG_CMD_RF_WRITE_ALL		0x0000
+#define RACFG_CMD_E2PROM_READ16		0x0001
+#define RACFG_CMD_E2PROM_WRITE16	0x0002
+#define RACFG_CMD_E2PROM_READ_ALL	0x0003
+#define RACFG_CMD_E2PROM_WRITE_ALL	0x0004
+#define RACFG_CMD_IO_READ			0x0005
+#define RACFG_CMD_IO_WRITE			0x0006
+#define RACFG_CMD_IO_READ_BULK		0x0007
+#define RACFG_CMD_BBP_READ8			0x0008
+#define RACFG_CMD_BBP_WRITE8		0x0009
+#define RACFG_CMD_BBP_READ_ALL		0x000a
+#define RACFG_CMD_GET_COUNTER		0x000b
+#define RACFG_CMD_CLEAR_COUNTER		0x000c
+
+#define RACFG_CMD_RSV1				0x000d
+#define RACFG_CMD_RSV2				0x000e
+#define RACFG_CMD_RSV3				0x000f
+
+#define RACFG_CMD_TX_START			0x0010
+#define RACFG_CMD_GET_TX_STATUS		0x0011
+#define RACFG_CMD_TX_STOP			0x0012
+#define RACFG_CMD_RX_START			0x0013
+#define RACFG_CMD_RX_STOP			0x0014
+#define RACFG_CMD_GET_NOISE_LEVEL	0x0015
+
+#define RACFG_CMD_ATE_START			0x0080
+#define RACFG_CMD_ATE_STOP			0x0081
+
+#define RACFG_CMD_ATE_START_TX_CARRIER		0x0100
+#define RACFG_CMD_ATE_START_TX_CONT			0x0101
+#define RACFG_CMD_ATE_START_TX_FRAME		0x0102
+#define RACFG_CMD_ATE_SET_BW	            0x0103
+#define RACFG_CMD_ATE_SET_TX_POWER0	        0x0104
+#define RACFG_CMD_ATE_SET_TX_POWER1			0x0105
+#define RACFG_CMD_ATE_SET_FREQ_OFFSET		0x0106
+#define RACFG_CMD_ATE_GET_STATISTICS		0x0107
+#define RACFG_CMD_ATE_RESET_COUNTER			0x0108
+#define RACFG_CMD_ATE_SEL_TX_ANTENNA		0x0109
+#define RACFG_CMD_ATE_SEL_RX_ANTENNA		0x010a
+#define RACFG_CMD_ATE_SET_PREAMBLE			0x010b
+#define RACFG_CMD_ATE_SET_CHANNEL			0x010c
+#define RACFG_CMD_ATE_SET_ADDR1				0x010d
+#define RACFG_CMD_ATE_SET_ADDR2				0x010e
+#define RACFG_CMD_ATE_SET_ADDR3				0x010f
+#define RACFG_CMD_ATE_SET_RATE				0x0110
+#define RACFG_CMD_ATE_SET_TX_FRAME_LEN		0x0111
+#define RACFG_CMD_ATE_SET_TX_FRAME_COUNT	0x0112
+#define RACFG_CMD_ATE_START_RX_FRAME		0x0113
+#define RACFG_CMD_ATE_E2PROM_READ_BULK	0x0114
+#define RACFG_CMD_ATE_E2PROM_WRITE_BULK	0x0115
+#define RACFG_CMD_ATE_IO_WRITE_BULK		0x0116
+#define RACFG_CMD_ATE_BBP_READ_BULK		0x0117
+#define RACFG_CMD_ATE_BBP_WRITE_BULK	0x0118
+#define RACFG_CMD_ATE_RF_READ_BULK		0x0119
+#define RACFG_CMD_ATE_RF_WRITE_BULK		0x011a
+
+
+
+#define A2Hex(_X, _p) 				\
+{									\
+	UCHAR *p;						\
+	_X = 0;							\
+	p = _p;							\
+	while (((*p >= 'a') && (*p <= 'f')) || ((*p >= 'A') && (*p <= 'F')) || ((*p >= '0') && (*p <= '9')))		\
+	{												\
+		if ((*p >= 'a') && (*p <= 'f'))				\
+			_X = _X * 16 + *p - 87;					\
+		else if ((*p >= 'A') && (*p <= 'F'))		\
+			_X = _X * 16 + *p - 55;					\
+		else if ((*p >= '0') && (*p <= '9'))		\
+			_X = _X * 16 + *p - 48;					\
+		p++;										\
+	}												\
+}
+
+
+static VOID memcpy_exl(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len);
+static VOID memcpy_exs(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len);
+static VOID RTMP_IO_READ_BULK(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, UINT32 len);
+
+#ifdef UCOS
+int ate_copy_to_user(
+	IN PUCHAR payload,
+	IN PUCHAR msg,
+	IN INT    len)
+{
+	memmove(payload, msg, len);
+	return 0;
+}
+
+#undef	copy_to_user
+#define copy_to_user(x,y,z) ate_copy_to_user((PUCHAR)x, (PUCHAR)y, z)
+#endif // UCOS //
+
+#define	LEN_OF_ARG 16
+
+VOID RtmpDoAte(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq)
+{
+	unsigned short Command_Id;
+	struct ate_racfghdr *pRaCfg;
+	INT	Status = NDIS_STATUS_SUCCESS;
+
+
+
+	if((pRaCfg = kmalloc(sizeof(struct ate_racfghdr), GFP_KERNEL)) == NULL)
+	{
+		Status = -EINVAL;
+		return;
+	}
+
+	NdisZeroMemory(pRaCfg, sizeof(struct ate_racfghdr));
+
+    if (copy_from_user((PUCHAR)pRaCfg, wrq->u.data.pointer, wrq->u.data.length))
+	{
+		Status = -EFAULT;
+		kfree(pRaCfg);
+		return;
+	}
+
+
+	Command_Id = ntohs(pRaCfg->command_id);
+
+	ATEDBGPRINT(RT_DEBUG_TRACE,("\n%s: Command_Id = 0x%04x !\n", __FUNCTION__, Command_Id));
+
+	switch (Command_Id)
+	{
+ 		// We will get this command when QA starts.
+		case RACFG_CMD_ATE_START:
+			{
+				ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START\n"));
+
+				// prepare feedback as soon as we can to avoid QA timeout.
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+				ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_TRACE, ("copy_to_user() fail in case RACFG_CMD_ATE_START\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START is done !\n"));
+				}
+				Set_ATE_Proc(pAdapter, "ATESTART");
+			}
+			break;
+
+ 		// We will get this command either QA is closed or ated is killed by user.
+		case RACFG_CMD_ATE_STOP:
+			{
+#ifndef UCOS
+				INT32 ret;
+#endif // !UCOS //
+
+				ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_STOP\n"));
+
+				// Distinguish this command came from QA(via ated)
+				// or ate daemon according to the existence of pid in payload.
+				// No need to prepare feedback if this cmd came directly from ate daemon.
+				pRaCfg->length = ntohs(pRaCfg->length);
+
+				if (pRaCfg->length == sizeof(pAdapter->ate.AtePid))
+				{
+					// This command came from QA.
+					// Get the pid of ATE daemon.
+					memcpy((UCHAR *)&pAdapter->ate.AtePid,
+						(&pRaCfg->data[0]) - 2/* == &(pRaCfg->status) */,
+						sizeof(pAdapter->ate.AtePid));
+
+					// prepare feedback as soon as we can to avoid QA timeout.
+					pRaCfg->length = htons(2);
+					pRaCfg->status = htons(0);
+
+					wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+										+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+										+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+					ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+
+	            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+	            	{
+	            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_STOP\n"));
+	                    Status = -EFAULT;
+	            	}
+
+					//
+					// kill ATE daemon when leaving ATE mode.
+					// We must kill ATE daemon first before setting ATESTOP,
+					// or Microsoft will report sth. wrong.
+#ifndef UCOS
+					ret = kill_proc(pAdapter->ate.AtePid, SIGTERM, 1);
+					if (ret)
+					{
+						ATEDBGPRINT(RT_DEBUG_ERROR, ("%s: unable to signal thread\n", pAdapter->net_dev->name));
+					}
+#endif // !UCOS //
+				}
+
+#ifdef UCOS
+				// Roger add to avoid error message after close QA
+				if (pAdapter->CSRBaseAddress == RT2860_CSR_ADDR)
+				{
+
+					// prepare feedback as soon as we can to avoid QA timeout.
+					pRaCfg->length = htons(2);
+					pRaCfg->status = htons(0);
+
+					wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+										+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+										+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+					ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+	            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+	            	{
+	            		ATEDBGPRINT(RT_DEBUG_TRACE, ("copy_to_user() fail in case RACFG_CMD_AP_START\n"));
+	                    Status = -EFAULT;
+	            	}
+				}
+#endif // UCOS //
+
+				// AP might have in ATE_STOP mode due to cmd from QA.
+				if (ATE_ON(pAdapter))
+				{
+					// Someone has killed ate daemon while QA GUI is still open.
+					Set_ATE_Proc(pAdapter, "ATESTOP");
+					ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_AP_START is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_RF_WRITE_ALL:
+			{
+				UINT32 R1, R2, R3, R4;
+				USHORT channel;
+
+				memcpy(&R1, pRaCfg->data-2, 4);
+				memcpy(&R2, pRaCfg->data+2, 4);
+				memcpy(&R3, pRaCfg->data+6, 4);
+				memcpy(&R4, pRaCfg->data+10, 4);
+				memcpy(&channel, pRaCfg->data+14, 2);
+
+				pAdapter->LatchRfRegs.R1 = ntohl(R1);
+				pAdapter->LatchRfRegs.R2 = ntohl(R2);
+				pAdapter->LatchRfRegs.R3 = ntohl(R3);
+				pAdapter->LatchRfRegs.R4 = ntohl(R4);
+				pAdapter->LatchRfRegs.Channel = ntohs(channel);
+
+				RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R1);
+				RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R2);
+				RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R3);
+				RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R4);
+
+				// prepare feedback
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+				ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RF_WRITE_ALL\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RF_WRITE_ALL is done !\n"));
+				}
+			}
+            break;
+
+		case RACFG_CMD_E2PROM_READ16:
+			{
+				USHORT	offset, value, tmp;
+
+				offset = ntohs(pRaCfg->status);
+				/* "tmp" is expecially for some compilers... */
+				RT28xx_EEPROM_READ16(pAdapter, offset, tmp);
+				value = tmp;
+				value = htons(value);
+
+				ATEDBGPRINT(RT_DEBUG_TRACE,("EEPROM Read offset = 0x%04x, value = 0x%04x\n", offset, value));
+
+				// prepare feedback
+				pRaCfg->length = htons(4);
+				pRaCfg->status = htons(0);
+				memcpy(pRaCfg->data, &value, 2);
+
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+				ATEDBGPRINT(RT_DEBUG_TRACE, ("sizeof(struct ate_racfghdr) = %d\n", sizeof(struct ate_racfghdr)));
+				ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_READ16\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_E2PROM_READ16 is done !\n"));
+				}
+           	}
+			break;
+
+		case RACFG_CMD_E2PROM_WRITE16:
+			{
+				USHORT	offset, value;
+
+				offset = ntohs(pRaCfg->status);
+				memcpy(&value, pRaCfg->data, 2);
+				value = ntohs(value);
+				RT28xx_EEPROM_WRITE16(pAdapter, offset, value);
+
+				// prepare feedback
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_WRITE16\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_E2PROM_WRITE16 is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_E2PROM_READ_ALL:
+			{
+				USHORT buffer[EEPROM_SIZE/2];
+
+				rt_ee_read_all(pAdapter,(USHORT *)buffer);
+				memcpy_exs(pAdapter, pRaCfg->data, (UCHAR *)buffer, EEPROM_SIZE);
+
+				// prepare feedback
+				pRaCfg->length = htons(2+EEPROM_SIZE);
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_READ_ALL\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_E2PROM_READ_ALL is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_E2PROM_WRITE_ALL:
+			{
+				USHORT buffer[EEPROM_SIZE/2];
+
+				NdisZeroMemory((UCHAR *)buffer, EEPROM_SIZE);
+				memcpy_exs(pAdapter, (UCHAR *)buffer, (UCHAR *)&pRaCfg->status, EEPROM_SIZE);
+				rt_ee_write_all(pAdapter,(USHORT *)buffer);
+
+				// prepare feedback
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_WRITE_ALL\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_ERROR, ("RACFG_CMD_E2PROM_WRITE_ALL is done !\n"));
+				}
+
+			}
+			break;
+
+		case RACFG_CMD_IO_READ:
+			{
+				UINT32	offset;
+				UINT32	value;
+
+				memcpy(&offset, &pRaCfg->status, 4);
+				offset = ntohl(offset);
+
+				// We do not need the base address.
+				// So just extract the offset out.
+				offset &= 0x0000FFFF;
+				RTMP_IO_READ32(pAdapter, offset, &value);
+				value = htonl(value);
+
+				// prepare feedback
+				pRaCfg->length = htons(6);
+				pRaCfg->status = htons(0);
+				memcpy(pRaCfg->data, &value, 4);
+
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_IO_READ\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_IO_READ is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_IO_WRITE:
+			{
+				UINT32	offset, value;
+
+				memcpy(&offset, pRaCfg->data-2, 4);
+				memcpy(&value, pRaCfg->data+2, 4);
+
+				offset = ntohl(offset);
+
+				// We do not need the base address.
+				// So just extract out the offset.
+				offset &= 0x0000FFFF;
+				value = ntohl(value);
+				ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_IO_WRITE: offset = %x, value = %x\n", offset, value));
+				RTMP_IO_WRITE32(pAdapter, offset, value);
+
+				// prepare feedback
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_IO_WRITE\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_IO_WRITE is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_IO_READ_BULK:
+			{
+				UINT32	offset;
+				USHORT	len;
+
+				memcpy(&offset, &pRaCfg->status, 4);
+				offset = ntohl(offset);
+
+				// We do not need the base address.
+				// So just extract the offset.
+				offset &= 0x0000FFFF;
+				memcpy(&len, pRaCfg->data+2, 2);
+				len = ntohs(len);
+
+				if (len > 371)
+				{
+					ATEDBGPRINT(RT_DEBUG_TRACE,("len is too large, make it smaller\n"));
+					pRaCfg->length = htons(2);
+					pRaCfg->status = htons(1);
+					break;
+				}
+
+				RTMP_IO_READ_BULK(pAdapter, pRaCfg->data, (UCHAR *)offset, len*4);// unit in four bytes
+
+				// prepare feedback
+				pRaCfg->length = htons(2+len*4);// unit in four bytes
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_IO_READ_BULK\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_IO_READ_BULK is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_BBP_READ8:
+			{
+				USHORT	offset;
+				UCHAR	value;
+
+				value = 0;
+				offset = ntohs(pRaCfg->status);
+
+				if (ATE_ON(pAdapter))
+				{
+					ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, offset,  &value);
+				}
+				else
+				{
+					RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, offset,  &value);
+				}
+				// prepare feedback
+				pRaCfg->length = htons(3);
+				pRaCfg->status = htons(0);
+				pRaCfg->data[0] = value;
+
+				ATEDBGPRINT(RT_DEBUG_TRACE,("BBP value = %x\n", value));
+
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_BBP_READ8\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_BBP_READ8 is done !\n"));
+				}
+			}
+			break;
+		case RACFG_CMD_BBP_WRITE8:
+			{
+				USHORT	offset;
+				UCHAR	value;
+
+				offset = ntohs(pRaCfg->status);
+				memcpy(&value, pRaCfg->data, 1);
+
+				if (ATE_ON(pAdapter))
+				{
+					ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, offset,  value);
+				}
+				else
+				{
+					RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, offset,  value);
+				}
+
+				if ((offset == BBP_R1) || (offset == BBP_R3))
+				{
+					SyncTxRxConfig(pAdapter, offset, value);
+				}
+
+				// prepare feedback
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_BBP_WRITE8\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_BBP_WRITE8 is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_BBP_READ_ALL:
+			{
+				USHORT j;
+
+				for (j = 0; j < 137; j++)
+				{
+					pRaCfg->data[j] = 0;
+
+					if (ATE_ON(pAdapter))
+					{
+						ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, j,  &pRaCfg->data[j]);
+					}
+					else
+					{
+						RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, j,  &pRaCfg->data[j]);
+					}
+				}
+
+				// prepare feedback
+				pRaCfg->length = htons(2+137);
+				pRaCfg->status = htons(0);
+
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_BBP_READ_ALL\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_BBP_READ_ALL is done !\n"));
+				}
+			}
+
+			break;
+
+		case RACFG_CMD_ATE_E2PROM_READ_BULK:
+		{
+			USHORT offset;
+			USHORT len;
+			USHORT buffer[EEPROM_SIZE/2];
+
+			offset = ntohs(pRaCfg->status);
+			memcpy(&len, pRaCfg->data, 2);
+			len = ntohs(len);
+
+			rt_ee_read_all(pAdapter,(USHORT *)buffer);
+			if (offset + len <= EEPROM_SIZE)
+				memcpy_exs(pAdapter, pRaCfg->data, (UCHAR *)buffer+offset, len);
+			else
+				ATEDBGPRINT(RT_DEBUG_ERROR, ("exceed EEPROM size\n"));
+
+			// prepare feedback
+			pRaCfg->length = htons(2+len);
+			pRaCfg->status = htons(0);
+			wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            {
+            	ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_E2PROM_READ_BULK\n"));
+                Status = -EFAULT;
+            }
+			else
+			{
+               	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_E2PROM_READ_BULK is done !\n"));
+			}
+
+		}
+			break;
+
+		case RACFG_CMD_ATE_E2PROM_WRITE_BULK:
+		{
+			USHORT offset;
+			USHORT len;
+			USHORT buffer[EEPROM_SIZE/2];
+
+			offset = ntohs(pRaCfg->status);
+			memcpy(&len, pRaCfg->data, 2);
+			len = ntohs(len);
+
+			rt_ee_read_all(pAdapter,(USHORT *)buffer);
+			memcpy_exs(pAdapter, (UCHAR *)buffer + offset, (UCHAR *)pRaCfg->data + 2, len);
+			rt_ee_write_all(pAdapter,(USHORT *)buffer);
+
+			// prepare feedback
+			pRaCfg->length = htons(2);
+			pRaCfg->status = htons(0);
+			wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+								+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+								+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+            if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            {
+            	ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_E2PROM_WRITE_BULK\n"));
+                   Status = -EFAULT;
+            }
+			else
+			{
+               	ATEDBGPRINT(RT_DEBUG_ERROR, ("RACFG_CMD_ATE_E2PROM_WRITE_BULK is done !\n"));
+			}
+
+		}
+			break;
+
+		case RACFG_CMD_ATE_IO_WRITE_BULK:
+		{
+			UINT32 offset, i, value;
+			USHORT len;
+
+			memcpy(&offset, &pRaCfg->status, 4);
+			offset = ntohl(offset);
+			memcpy(&len, pRaCfg->data+2, 2);
+			len = ntohs(len);
+
+			for (i = 0; i < len; i += 4)
+			{
+				memcpy_exl(pAdapter, (UCHAR *)&value, pRaCfg->data+4+i, 4);
+				printk("Write %x %x\n", offset + i, value);
+				RTMP_IO_WRITE32(pAdapter, (offset +i) & 0xffff, value);
+			}
+
+			// prepare feedback
+			pRaCfg->length = htons(2);
+			pRaCfg->status = htons(0);
+			wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+								+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+								+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+            if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            {
+            	ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_IO_WRITE_BULK\n"));
+                   Status = -EFAULT;
+            }
+			else
+			{
+               	ATEDBGPRINT(RT_DEBUG_ERROR, ("RACFG_CMD_ATE_IO_WRITE_BULK is done !\n"));
+			}
+
+		}
+			break;
+
+		case RACFG_CMD_ATE_BBP_READ_BULK:
+		{
+			USHORT offset;
+			USHORT len;
+			USHORT j;
+
+			offset = ntohs(pRaCfg->status);
+			memcpy(&len, pRaCfg->data, 2);
+			len = ntohs(len);
+
+
+			for (j = offset; j < (offset+len); j++)
+			{
+				pRaCfg->data[j - offset] = 0;
+
+				if (pAdapter->ate.Mode == ATE_STOP)
+				{
+					RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, j,  &pRaCfg->data[j - offset]);
+				}
+				else
+				{
+					ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, j,  &pRaCfg->data[j - offset]);
+				}
+			}
+
+			// prepare feedback
+			pRaCfg->length = htons(2+len);
+			pRaCfg->status = htons(0);
+			wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+								+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+								+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            {
+            	ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_BBP_READ_BULK\n"));
+                   Status = -EFAULT;
+            }
+			else
+			{
+               	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_BBP_READ_BULK is done !\n"));
+			}
+
+		}
+			break;
+
+		case RACFG_CMD_ATE_BBP_WRITE_BULK:
+		{
+			USHORT offset;
+			USHORT len;
+			USHORT j;
+			UCHAR *value;
+
+			offset = ntohs(pRaCfg->status);
+			memcpy(&len, pRaCfg->data, 2);
+			len = ntohs(len);
+
+			for (j = offset; j < (offset+len); j++)
+			{
+				value = pRaCfg->data + 2 + (j - offset);
+				if (pAdapter->ate.Mode == ATE_STOP)
+				{
+					RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, j,  *value);
+				}
+				else
+				{
+					ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, j,  *value);
+				}
+			}
+
+			// prepare feedback
+			pRaCfg->length = htons(2);
+			pRaCfg->status = htons(0);
+			wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+								+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+								+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            {
+            	ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_BBP_WRITE_BULK\n"));
+                   Status = -EFAULT;
+            }
+			else
+			{
+               	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_BBP_WRITE_BULK is done !\n"));
+			}
+		}
+			break;
+
+#ifdef CONFIG_RALINK_RT3052
+		case RACFG_CMD_ATE_RF_READ_BULK:
+		{
+			USHORT offset;
+			USHORT len;
+			USHORT j;
+
+			offset = ntohs(pRaCfg->status);
+			memcpy(&len, pRaCfg->data, 2);
+			len = ntohs(len);
+
+			for (j = offset; j < (offset+len); j++)
+			{
+				pRaCfg->data[j - offset] = 0;
+				RT30xxReadRFRegister(pAdapter, j,  &pRaCfg->data[j - offset]);
+			}
+
+			// prepare feedback
+			pRaCfg->length = htons(2+len);
+			pRaCfg->status = htons(0);
+			wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+								+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+								+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            {
+            	ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_RF_READ_BULK\n"));
+                   Status = -EFAULT;
+            }
+			else
+			{
+               	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_RF_READ_BULK is done !\n"));
+			}
+
+		}
+			break;
+
+		case RACFG_CMD_ATE_RF_WRITE_BULK:
+		{
+			USHORT offset;
+			USHORT len;
+			USHORT j;
+			UCHAR *value;
+
+			offset = ntohs(pRaCfg->status);
+			memcpy(&len, pRaCfg->data, 2);
+			len = ntohs(len);
+
+			for (j = offset; j < (offset+len); j++)
+			{
+				value = pRaCfg->data + 2 + (j - offset);
+				RT30xxWriteRFRegister(pAdapter, j,  *value);
+			}
+
+			// prepare feedback
+			pRaCfg->length = htons(2);
+			pRaCfg->status = htons(0);
+			wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+								+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+								+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            {
+            	ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_RF_WRITE_BULK\n"));
+                   Status = -EFAULT;
+            }
+			else
+			{
+               	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_RF_WRITE_BULK is done !\n"));
+			}
+
+		}
+			break;
+#endif
+
+
+		case RACFG_CMD_GET_NOISE_LEVEL:
+			{
+				UCHAR	channel;
+				INT32   buffer[3][10];/* 3 : RxPath ; 10 : no. of per rssi samples */
+
+				channel = (ntohs(pRaCfg->status) & 0x00FF);
+				CalNoiseLevel(pAdapter, channel, buffer);
+				memcpy_exl(pAdapter, (UCHAR *)pRaCfg->data, (UCHAR *)&(buffer[0][0]), (sizeof(INT32)*3*10));
+
+				// prepare feedback
+				pRaCfg->length = htons(2 + (sizeof(INT32)*3*10));
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_GET_NOISE_LEVEL\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_GET_NOISE_LEVEL is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_GET_COUNTER:
+			{
+				memcpy_exl(pAdapter, &pRaCfg->data[0], (UCHAR *)&pAdapter->ate.U2M, 4);
+				memcpy_exl(pAdapter, &pRaCfg->data[4], (UCHAR *)&pAdapter->ate.OtherData, 4);
+				memcpy_exl(pAdapter, &pRaCfg->data[8], (UCHAR *)&pAdapter->ate.Beacon, 4);
+				memcpy_exl(pAdapter, &pRaCfg->data[12], (UCHAR *)&pAdapter->ate.OtherCount, 4);
+				memcpy_exl(pAdapter, &pRaCfg->data[16], (UCHAR *)&pAdapter->ate.TxAc0, 4);
+				memcpy_exl(pAdapter, &pRaCfg->data[20], (UCHAR *)&pAdapter->ate.TxAc1, 4);
+				memcpy_exl(pAdapter, &pRaCfg->data[24], (UCHAR *)&pAdapter->ate.TxAc2, 4);
+				memcpy_exl(pAdapter, &pRaCfg->data[28], (UCHAR *)&pAdapter->ate.TxAc3, 4);
+				memcpy_exl(pAdapter, &pRaCfg->data[32], (UCHAR *)&pAdapter->ate.TxHCCA, 4);
+				memcpy_exl(pAdapter, &pRaCfg->data[36], (UCHAR *)&pAdapter->ate.TxMgmt, 4);
+				memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&pAdapter->ate.RSSI0, 4);
+				memcpy_exl(pAdapter, &pRaCfg->data[44], (UCHAR *)&pAdapter->ate.RSSI1, 4);
+				memcpy_exl(pAdapter, &pRaCfg->data[48], (UCHAR *)&pAdapter->ate.RSSI2, 4);
+				memcpy_exl(pAdapter, &pRaCfg->data[52], (UCHAR *)&pAdapter->ate.SNR0, 4);
+				memcpy_exl(pAdapter, &pRaCfg->data[56], (UCHAR *)&pAdapter->ate.SNR1, 4);
+
+				pRaCfg->length = htons(2+60);
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_GET_COUNTER\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_GET_COUNTER is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_CLEAR_COUNTER:
+			{
+				pAdapter->ate.U2M = 0;
+				pAdapter->ate.OtherData = 0;
+				pAdapter->ate.Beacon = 0;
+				pAdapter->ate.OtherCount = 0;
+				pAdapter->ate.TxAc0 = 0;
+				pAdapter->ate.TxAc1 = 0;
+				pAdapter->ate.TxAc2 = 0;
+				pAdapter->ate.TxAc3 = 0;
+				pAdapter->ate.TxHCCA = 0;
+				pAdapter->ate.TxMgmt = 0;
+				pAdapter->ate.TxDoneCount = 0;
+
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_CLEAR_COUNTER\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_CLEAR_COUNTER is done !\n"));
+				}
+			}
+
+			break;
+
+		case RACFG_CMD_TX_START:
+			{
+				USHORT *p;
+				USHORT	err = 1;
+				UCHAR   Bbp22Value = 0, Bbp24Value = 0;
+
+				if ((pAdapter->ate.TxStatus != 0) && (pAdapter->ate.Mode & ATE_TXFRAME))
+				{
+					ATEDBGPRINT(RT_DEBUG_TRACE,("Ate Tx is already running, to run next Tx, you must stop it first\n"));
+					err = 2;
+					goto TX_START_ERROR;
+				}
+				else if ((pAdapter->ate.TxStatus != 0) && !(pAdapter->ate.Mode & ATE_TXFRAME))
+				{
+					int i = 0;
+
+					while ((i++ < 10) && (pAdapter->ate.TxStatus != 0))
+					{
+						RTMPusecDelay(5000);
+					}
+
+					// force it to stop
+					pAdapter->ate.TxStatus = 0;
+					pAdapter->ate.TxDoneCount = 0;
+					//pAdapter->ate.Repeat = 0;
+					pAdapter->ate.bQATxStart = FALSE;
+				}
+
+				// If pRaCfg->length == 0, this "RACFG_CMD_TX_START" is for Carrier test or Carrier Suppression.
+				if (ntohs(pRaCfg->length) != 0)
+				{
+					// Get frame info
+#ifdef RT2870
+					NdisMoveMemory(&pAdapter->ate.TxInfo, pRaCfg->data - 2, 4);
+#ifdef RT_BIG_ENDIAN
+					RTMPDescriptorEndianChange((PUCHAR) &pAdapter->ate.TxInfo, TYPE_TXINFO);
+#endif // RT_BIG_ENDIAN //
+#endif // RT2870 //
+
+					NdisMoveMemory(&pAdapter->ate.TxWI, pRaCfg->data + 2, 16);
+#ifdef RT_BIG_ENDIAN
+					RTMPWIEndianChange((PUCHAR)&pAdapter->ate.TxWI, TYPE_TXWI);
+#endif // RT_BIG_ENDIAN //
+
+					NdisMoveMemory(&pAdapter->ate.TxCount, pRaCfg->data + 18, 4);
+					pAdapter->ate.TxCount = ntohl(pAdapter->ate.TxCount);
+
+					p = (USHORT *)(&pRaCfg->data[22]);
+					//p = pRaCfg->data + 22;
+					// always use QID_AC_BE
+					pAdapter->ate.QID = 0;
+					p = (USHORT *)(&pRaCfg->data[24]);
+					//p = pRaCfg->data + 24;
+					pAdapter->ate.HLen = ntohs(*p);
+
+					if (pAdapter->ate.HLen > 32)
+					{
+						ATEDBGPRINT(RT_DEBUG_ERROR,("pAdapter->ate.HLen > 32\n"));
+						err = 3;
+						goto TX_START_ERROR;
+					}
+
+					NdisMoveMemory(&pAdapter->ate.Header, pRaCfg->data + 26, pAdapter->ate.HLen);
+
+
+					pAdapter->ate.PLen = ntohs(pRaCfg->length) - (pAdapter->ate.HLen + 28);
+
+					if (pAdapter->ate.PLen > 32)
+					{
+						ATEDBGPRINT(RT_DEBUG_ERROR,("pAdapter->ate.PLen > 32\n"));
+						err = 4;
+						goto TX_START_ERROR;
+					}
+
+					NdisMoveMemory(&pAdapter->ate.Pattern, pRaCfg->data + 26 + pAdapter->ate.HLen, pAdapter->ate.PLen);
+					pAdapter->ate.DLen = pAdapter->ate.TxWI.MPDUtotalByteCount - pAdapter->ate.HLen;
+				}
+
+				ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R22, &Bbp22Value);
+
+				switch (Bbp22Value)
+				{
+					case BBP22_TXFRAME:
+						{
+							if (pAdapter->ate.TxCount == 0)
+							{
+							}
+							ATEDBGPRINT(RT_DEBUG_TRACE,("START TXFRAME\n"));
+							pAdapter->ate.bQATxStart = TRUE;
+							Set_ATE_Proc(pAdapter, "TXFRAME");
+						}
+						break;
+
+					case BBP22_TXCONT_OR_CARRSUPP:
+						{
+							ATEDBGPRINT(RT_DEBUG_TRACE,("BBP22_TXCONT_OR_CARRSUPP\n"));
+							ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, 24, &Bbp24Value);
+
+							switch (Bbp24Value)
+							{
+								case BBP24_TXCONT:
+									{
+										ATEDBGPRINT(RT_DEBUG_TRACE,("START TXCONT\n"));
+										pAdapter->ate.bQATxStart = TRUE;
+										Set_ATE_Proc(pAdapter, "TXCONT");
+									}
+									break;
+
+								case BBP24_CARRSUPP:
+									{
+										ATEDBGPRINT(RT_DEBUG_TRACE,("START TXCARRSUPP\n"));
+										pAdapter->ate.bQATxStart = TRUE;
+										pAdapter->ate.Mode |= ATE_TXCARRSUPP;
+									}
+									break;
+
+								default:
+									{
+										ATEDBGPRINT(RT_DEBUG_ERROR,("Unknown Start TX subtype !"));
+									}
+									break;
+							}
+						}
+						break;
+
+					case BBP22_TXCARR:
+						{
+							ATEDBGPRINT(RT_DEBUG_TRACE,("START TXCARR\n"));
+							pAdapter->ate.bQATxStart = TRUE;
+							Set_ATE_Proc(pAdapter, "TXCARR");
+						}
+						break;
+
+					default:
+						{
+							ATEDBGPRINT(RT_DEBUG_ERROR,("Unknown Start TX subtype !"));
+						}
+						break;
+				}
+
+				if (pAdapter->ate.bQATxStart == TRUE)
+				{
+					// prepare feedback
+					pRaCfg->length = htons(2);
+					pRaCfg->status = htons(0);
+
+					wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+										+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+										+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+	            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+	            	{
+	            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() was failed in case RACFG_CMD_TX_START\n"));
+	                    Status = -EFAULT;
+	            	}
+					else
+					{
+	                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_TX_START is done !\n"));
+					}
+					break;
+				}
+
+TX_START_ERROR:
+				// prepare feedback
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(err);
+
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_TX_START\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("feedback of TX_START_ERROR is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_GET_TX_STATUS:
+			{
+				UINT32 count;
+
+				// prepare feedback
+				pRaCfg->length = htons(6);
+				pRaCfg->status = htons(0);
+				count = htonl(pAdapter->ate.TxDoneCount);
+				NdisMoveMemory(pRaCfg->data, &count, 4);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_GET_TX_STATUS\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_GET_TX_STATUS is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_TX_STOP:
+			{
+				ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_TX_STOP\n"));
+
+				Set_ATE_Proc(pAdapter, "TXSTOP");
+
+				// prepare feedback
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_TRACE, ("copy_to_user() fail in case RACFG_CMD_TX_STOP\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_TX_STOP is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_RX_START:
+			{
+				ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_START\n"));
+
+				pAdapter->ate.bQARxStart = TRUE;
+				Set_ATE_Proc(pAdapter, "RXFRAME");
+
+				// prepare feedback
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RX_START\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RX_START is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_RX_STOP:
+			{
+				ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_STOP\n"));
+
+				Set_ATE_Proc(pAdapter, "RXSTOP");
+
+				// prepare feedback
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RX_STOP\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RX_STOP is done !\n"));
+				}
+			}
+			break;
+
+		/* The following cases are for new ATE GUI(not QA). */
+		/*==================================================*/
+		case RACFG_CMD_ATE_START_TX_CARRIER:
+			{
+				ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_CARRIER\n"));
+
+				Set_ATE_Proc(pAdapter, "TXCARR");
+
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+				ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_START_TX_CARRIER\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START_TX_CARRIER is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_ATE_START_TX_CONT:
+			{
+				ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_CONT\n"));
+
+				Set_ATE_Proc(pAdapter, "TXCONT");
+
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+				ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_START_TX_CONT\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START_TX_CONT is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_ATE_START_TX_FRAME:
+			{
+				ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_FRAME\n"));
+
+				Set_ATE_Proc(pAdapter, "TXFRAME");
+
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+				ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_START_TX_FRAME\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START_TX_FRAME is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_ATE_SET_BW:
+			{
+				SHORT    value = 0;
+				UCHAR    str[LEN_OF_ARG];
+
+				NdisZeroMemory(str, LEN_OF_ARG);
+
+				ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_BW\n"));
+
+				memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+				value = ntohs(value);
+				sprintf((PCHAR)str, "%d", value);
+
+				Set_ATE_TX_BW_Proc(pAdapter, str);
+
+				// prepare feedback
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_BW\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_BW is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_ATE_SET_TX_POWER0:
+			{
+				SHORT    value = 0;
+				UCHAR    str[LEN_OF_ARG];
+
+				NdisZeroMemory(str, LEN_OF_ARG);
+
+				ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_POWER0\n"));
+
+				memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+				value = ntohs(value);
+				sprintf((PCHAR)str, "%d", value);
+				Set_ATE_TX_POWER0_Proc(pAdapter, str);
+
+				// prepare feedback
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_POWER0\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_POWER0 is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_ATE_SET_TX_POWER1:
+			{
+				SHORT    value = 0;
+				UCHAR    str[LEN_OF_ARG];
+
+				NdisZeroMemory(str, LEN_OF_ARG);
+
+				ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_POWER1\n"));
+
+				memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+				value = ntohs(value);
+				sprintf((PCHAR)str, "%d", value);
+				Set_ATE_TX_POWER1_Proc(pAdapter, str);
+
+				// prepare feedback
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_POWER1\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_POWER1 is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_ATE_SET_FREQ_OFFSET:
+			{
+				SHORT    value = 0;
+				UCHAR    str[LEN_OF_ARG];
+
+				NdisZeroMemory(str, LEN_OF_ARG);
+
+				ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_FREQ_OFFSET\n"));
+
+				memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+				value = ntohs(value);
+				sprintf((PCHAR)str, "%d", value);
+				Set_ATE_TX_FREQOFFSET_Proc(pAdapter, str);
+
+				// prepare feedback
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_FREQ_OFFSET\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_FREQ_OFFSET is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_ATE_GET_STATISTICS:
+			{
+				ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_GET_STATISTICS\n"));
+
+				memcpy_exl(pAdapter, &pRaCfg->data[0], (UCHAR *)&pAdapter->ate.TxDoneCount, 4);
+				memcpy_exl(pAdapter, &pRaCfg->data[4], (UCHAR *)&pAdapter->WlanCounters.RetryCount.u.LowPart, 4);
+				memcpy_exl(pAdapter, &pRaCfg->data[8], (UCHAR *)&pAdapter->WlanCounters.FailedCount.u.LowPart, 4);
+				memcpy_exl(pAdapter, &pRaCfg->data[12], (UCHAR *)&pAdapter->WlanCounters.RTSSuccessCount.u.LowPart, 4);
+				memcpy_exl(pAdapter, &pRaCfg->data[16], (UCHAR *)&pAdapter->WlanCounters.RTSFailureCount.u.LowPart, 4);
+				memcpy_exl(pAdapter, &pRaCfg->data[20], (UCHAR *)&pAdapter->WlanCounters.ReceivedFragmentCount.QuadPart, 4);
+				memcpy_exl(pAdapter, &pRaCfg->data[24], (UCHAR *)&pAdapter->WlanCounters.FCSErrorCount.u.LowPart, 4);
+				memcpy_exl(pAdapter, &pRaCfg->data[28], (UCHAR *)&pAdapter->Counters8023.RxNoBuffer, 4);
+				memcpy_exl(pAdapter, &pRaCfg->data[32], (UCHAR *)&pAdapter->WlanCounters.FrameDuplicateCount.u.LowPart, 4);
+				memcpy_exl(pAdapter, &pRaCfg->data[36], (UCHAR *)&pAdapter->RalinkCounters.OneSecFalseCCACnt, 4);
+
+				if (pAdapter->ate.RxAntennaSel == 0)
+				{
+					INT32 RSSI0 = 0;
+					INT32 RSSI1 = 0;
+					INT32 RSSI2 = 0;
+
+					RSSI0 = (INT32)(pAdapter->ate.LastRssi0 - pAdapter->BbpRssiToDbmDelta);
+					RSSI1 = (INT32)(pAdapter->ate.LastRssi1 - pAdapter->BbpRssiToDbmDelta);
+					RSSI2 = (INT32)(pAdapter->ate.LastRssi2 - pAdapter->BbpRssiToDbmDelta);
+					memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&RSSI0, 4);
+					memcpy_exl(pAdapter, &pRaCfg->data[44], (UCHAR *)&RSSI1, 4);
+					memcpy_exl(pAdapter, &pRaCfg->data[48], (UCHAR *)&RSSI2, 4);
+					pRaCfg->length = htons(2+52);
+				}
+				else
+				{
+					INT32 RSSI0 = 0;
+
+					RSSI0 = (INT32)(pAdapter->ate.LastRssi0 - pAdapter->BbpRssiToDbmDelta);
+					memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&RSSI0, 4);
+					pRaCfg->length = htons(2+44);
+				}
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_GET_STATISTICS\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_GET_STATISTICS is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_ATE_RESET_COUNTER:
+			{
+				SHORT    value = 1;
+				UCHAR    str[LEN_OF_ARG];
+
+				NdisZeroMemory(str, LEN_OF_ARG);
+
+				ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_RESET_COUNTER\n"));
+
+				sprintf((PCHAR)str, "%d", value);
+				Set_ResetStatCounter_Proc(pAdapter, str);
+
+				pAdapter->ate.TxDoneCount = 0;
+
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_RESET_COUNTER\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_RESET_COUNTER is done !\n"));
+				}
+			}
+
+			break;
+
+		case RACFG_CMD_ATE_SEL_TX_ANTENNA:
+			{
+				SHORT    value = 0;
+				UCHAR    str[LEN_OF_ARG];
+
+				NdisZeroMemory(str, LEN_OF_ARG);
+
+				ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SEL_TX_ANTENNA\n"));
+
+				memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+				value = ntohs(value);
+				sprintf((PCHAR)str, "%d", value);
+				Set_ATE_TX_Antenna_Proc(pAdapter, str);
+
+				// prepare feedback
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SEL_TX_ANTENNA\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SEL_TX_ANTENNA is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_ATE_SEL_RX_ANTENNA:
+			{
+				SHORT    value = 0;
+				UCHAR    str[LEN_OF_ARG];
+
+				NdisZeroMemory(str, LEN_OF_ARG);
+
+				ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SEL_RX_ANTENNA\n"));
+
+				memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+				value = ntohs(value);
+				sprintf((PCHAR)str, "%d", value);
+				Set_ATE_RX_Antenna_Proc(pAdapter, str);
+
+				// prepare feedback
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SEL_RX_ANTENNA\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SEL_RX_ANTENNA is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_ATE_SET_PREAMBLE:
+			{
+				SHORT    value = 0;
+				UCHAR    str[LEN_OF_ARG];
+
+				NdisZeroMemory(str, LEN_OF_ARG);
+
+				ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_PREAMBLE\n"));
+
+				memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+				value = ntohs(value);
+				sprintf((PCHAR)str, "%d", value);
+				Set_ATE_TX_MODE_Proc(pAdapter, str);
+
+				// prepare feedback
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_PREAMBLE\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_PREAMBLE is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_ATE_SET_CHANNEL:
+			{
+				SHORT    value = 0;
+				UCHAR    str[LEN_OF_ARG];
+
+				NdisZeroMemory(str, LEN_OF_ARG);
+
+				ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_CHANNEL\n"));
+
+				memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+				value = ntohs(value);
+				sprintf((PCHAR)str, "%d", value);
+				Set_ATE_CHANNEL_Proc(pAdapter, str);
+
+				// prepare feedback
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_CHANNEL\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_CHANNEL is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_ATE_SET_ADDR1:
+			{
+				ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR1\n"));
+
+				// Addr is an array of UCHAR,
+				// so no need to perform endian swap.
+				memcpy(pAdapter->ate.Addr1, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN);
+
+				// prepare feedback
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_ADDR1\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+					ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_ADDR1 is done !\n (ADDR1 = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAdapter->ate.Addr1[0],
+						pAdapter->ate.Addr1[1], pAdapter->ate.Addr1[2], pAdapter->ate.Addr1[3], pAdapter->ate.Addr1[4], pAdapter->ate.Addr1[5]));
+				}
+			}
+			break;
+
+		case RACFG_CMD_ATE_SET_ADDR2:
+			{
+				ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR2\n"));
+
+				// Addr is an array of UCHAR,
+				// so no need to perform endian swap.
+				memcpy(pAdapter->ate.Addr2, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN);
+
+				// prepare feedback
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_ADDR2\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+					ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_ADDR2 is done !\n (ADDR2 = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAdapter->ate.Addr2[0],
+						pAdapter->ate.Addr2[1], pAdapter->ate.Addr2[2], pAdapter->ate.Addr2[3], pAdapter->ate.Addr2[4], pAdapter->ate.Addr2[5]));
+				}
+			}
+			break;
+
+		case RACFG_CMD_ATE_SET_ADDR3:
+			{
+				ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR3\n"));
+
+				// Addr is an array of UCHAR,
+				// so no need to perform endian swap.
+				memcpy(pAdapter->ate.Addr3, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN);
+
+				// prepare feedback
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_ADDR3\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+					ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_ADDR3 is done !\n (ADDR3 = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAdapter->ate.Addr3[0],
+						pAdapter->ate.Addr3[1], pAdapter->ate.Addr3[2], pAdapter->ate.Addr3[3], pAdapter->ate.Addr3[4], pAdapter->ate.Addr3[5]));
+				}
+			}
+			break;
+
+		case RACFG_CMD_ATE_SET_RATE:
+			{
+				SHORT    value = 0;
+				UCHAR    str[LEN_OF_ARG];
+
+				NdisZeroMemory(str, LEN_OF_ARG);
+
+				ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_RATE\n"));
+
+				memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+				value = ntohs(value);
+				sprintf((PCHAR)str, "%d", value);
+				Set_ATE_TX_MCS_Proc(pAdapter, str);
+
+				// prepare feedback
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_RATE\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_RATE is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_ATE_SET_TX_FRAME_LEN:
+			{
+				SHORT    value = 0;
+				UCHAR    str[LEN_OF_ARG];
+
+				NdisZeroMemory(str, LEN_OF_ARG);
+
+				ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_FRAME_LEN\n"));
+
+				memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+				value = ntohs(value);
+				sprintf((PCHAR)str, "%d", value);
+				Set_ATE_TX_LENGTH_Proc(pAdapter, str);
+
+				// prepare feedback
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_FRAME_LEN\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_FRAME_LEN is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_ATE_SET_TX_FRAME_COUNT:
+			{
+				USHORT    value = 0;
+				UCHAR    str[LEN_OF_ARG];
+
+				NdisZeroMemory(str, LEN_OF_ARG);
+
+				ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_FRAME_COUNT\n"));
+
+				memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+				value = ntohs(value);
+				{
+					sprintf((PCHAR)str, "%d", value);
+					Set_ATE_TX_COUNT_Proc(pAdapter, str);
+				}
+
+				// prepare feedback
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_FRAME_COUNT\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_FRAME_COUNT is done !\n"));
+				}
+			}
+			break;
+
+		case RACFG_CMD_ATE_START_RX_FRAME:
+			{
+				ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_START\n"));
+
+				Set_ATE_Proc(pAdapter, "RXFRAME");
+
+				// prepare feedback
+				pRaCfg->length = htons(2);
+				pRaCfg->status = htons(0);
+				wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+									+ sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+									+ sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+            	if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+            	{
+            		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RX_START\n"));
+                    Status = -EFAULT;
+            	}
+				else
+				{
+                	ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RX_START is done !\n"));
+				}
+			}
+			break;
+		default:
+			break;
+	}
+    ASSERT(pRaCfg != NULL);
+    if (pRaCfg != NULL)
+    {
+    kfree(pRaCfg);
+    }
+	return;
+}
+
+VOID BubbleSort(INT32 n, INT32 a[])
+{
+	INT32 k, j, temp;
+
+	for (k = n-1;  k>0;  k--)
+	{
+		for (j = 0; j<k; j++)
+		{
+			if(a[j] > a[j+1])
+			{
+				temp = a[j];
+				a[j]=a[j+1];
+				a[j+1]=temp;
+			}
+		}
+	}
+}
+
+VOID CalNoiseLevel(PRTMP_ADAPTER pAd, UCHAR channel, INT32 RSSI[3][10])
+{
+	INT32		RSSI0, RSSI1, RSSI2;
+ 	CHAR		Rssi0Offset, Rssi1Offset, Rssi2Offset;
+	UCHAR		BbpR50Rssi0 = 0, BbpR51Rssi1 = 0, BbpR52Rssi2 = 0;
+	UCHAR		Org_BBP66value = 0, Org_BBP69value = 0, Org_BBP70value = 0, data = 0;
+	USHORT		LNA_Gain = 0;
+	INT32       j = 0;
+	UCHAR		Org_Channel = pAd->ate.Channel;
+	USHORT	    GainValue = 0, OffsetValue = 0;
+
+	ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &Org_BBP66value);
+	ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R69, &Org_BBP69value);
+	ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R70, &Org_BBP70value);
+
+	//**********************************************************************
+	// Read the value of LNA gain and Rssi offset
+	//**********************************************************************
+	RT28xx_EEPROM_READ16(pAd, EEPROM_LNA_OFFSET, GainValue);
+
+	// for Noise Level
+	if (channel <= 14)
+	{
+		LNA_Gain = GainValue & 0x00FF;
+
+		RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET, OffsetValue);
+		Rssi0Offset = OffsetValue & 0x00FF;
+		Rssi1Offset = (OffsetValue & 0xFF00) >> 8;
+		RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_BG_OFFSET + 2)/* 0x48 */, OffsetValue);
+		Rssi2Offset = OffsetValue & 0x00FF;
+	}
+	else
+	{
+		LNA_Gain = (GainValue & 0xFF00) >> 8;
+
+		RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_A_OFFSET, OffsetValue);
+		Rssi0Offset = OffsetValue & 0x00FF;
+		Rssi1Offset = (OffsetValue & 0xFF00) >> 8;
+		RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_A_OFFSET + 2)/* 0x4C */, OffsetValue);
+		Rssi2Offset = OffsetValue & 0x00FF;
+	}
+	//**********************************************************************
+	{
+		pAd->ate.Channel = channel;
+		ATEAsicSwitchChannel(pAd);
+		mdelay(5);
+
+		data = 0x10;
+		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, data);
+		data = 0x40;
+		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, data);
+		data = 0x40;
+		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, data);
+		mdelay(5);
+
+		// Start Rx
+		pAd->ate.bQARxStart = TRUE;
+		Set_ATE_Proc(pAd, "RXFRAME");
+
+		mdelay(5);
+
+		for (j = 0; j < 10; j++)
+		{
+			ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R50, &BbpR50Rssi0);
+			ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R51, &BbpR51Rssi1);
+			ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R52, &BbpR52Rssi2);
+
+			mdelay(10);
+
+			// Calculate RSSI 0
+			if (BbpR50Rssi0 == 0)
+			{
+				RSSI0 = -100;
+			}
+			else
+			{
+				RSSI0 = (INT32)(-12 - BbpR50Rssi0 - LNA_Gain - Rssi0Offset);
+			}
+			RSSI[0][j] = RSSI0;
+
+			if ( pAd->Antenna.field.RxPath >= 2 ) // 2R
+			{
+				// Calculate RSSI 1
+				if (BbpR51Rssi1 == 0)
+				{
+					RSSI1 = -100;
+				}
+				else
+				{
+					RSSI1 = (INT32)(-12 - BbpR51Rssi1 - LNA_Gain - Rssi1Offset);
+				}
+				RSSI[1][j] = RSSI1;
+			}
+
+			if ( pAd->Antenna.field.RxPath >= 3 ) // 3R
+			{
+				// Calculate RSSI 2
+				if (BbpR52Rssi2 == 0)
+					RSSI2 = -100;
+				else
+					RSSI2 = (INT32)(-12 - BbpR52Rssi2 - LNA_Gain - Rssi2Offset);
+
+				RSSI[2][j] = RSSI2;
+			}
+		}
+
+		// Stop Rx
+		Set_ATE_Proc(pAd, "RXSTOP");
+
+		mdelay(5);
+
+		BubbleSort(10, RSSI[0]);	// 1R
+
+		if ( pAd->Antenna.field.RxPath >= 2 ) // 2R
+		{
+			BubbleSort(10, RSSI[1]);
+		}
+
+		if ( pAd->Antenna.field.RxPath >= 3 ) // 3R
+		{
+			BubbleSort(10, RSSI[2]);
+		}
+
+	}
+
+	pAd->ate.Channel = Org_Channel;
+	ATEAsicSwitchChannel(pAd);
+
+	// Restore original value
+    ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, Org_BBP66value);
+    ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, Org_BBP69value);
+    ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, Org_BBP70value);
+
+	return;
+}
+
+BOOLEAN SyncTxRxConfig(PRTMP_ADAPTER pAd, USHORT offset, UCHAR value)
+{
+	UCHAR tmp = 0, bbp_data = 0;
+
+	if (ATE_ON(pAd))
+	{
+		ATE_BBP_IO_READ8_BY_REG_ID(pAd, offset, &bbp_data);
+	}
+	else
+	{
+		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, offset, &bbp_data);
+	}
+
+	/* confirm again */
+	ASSERT(bbp_data == value);
+
+	switch(offset)
+	{
+		case BBP_R1:
+			/* Need to sync. tx configuration with legacy ATE. */
+			tmp = (bbp_data & ((1 << 4) | (1 << 3))/* 0x18 */) >> 3;
+		    switch(tmp)
+		    {
+				/* The BBP R1 bit[4:3] = 2 :: Both DACs will be used by QA. */
+		        case 2:
+					/* All */
+					pAd->ate.TxAntennaSel = 0;
+		            break;
+				/* The BBP R1 bit[4:3] = 0 :: DAC 0 will be used by QA. */
+		        case 0:
+					/* Antenna one */
+					pAd->ate.TxAntennaSel = 1;
+		            break;
+				/* The BBP R1 bit[4:3] = 1 :: DAC 1 will be used by QA. */
+		        case 1:
+					/* Antenna two */
+					pAd->ate.TxAntennaSel = 2;
+		            break;
+		        default:
+		            DBGPRINT(RT_DEBUG_TRACE, ("%s -- Sth. wrong!  : return FALSE; \n", __FUNCTION__));
+		            return FALSE;
+		    }
+			break;/* case BBP_R1 */
+
+		case BBP_R3:
+			/* Need to sync. rx configuration with legacy ATE. */
+			tmp = (bbp_data & ((1 << 1) | (1 << 0))/* 0x03 */);
+		    switch(tmp)
+		    {
+				/* The BBP R3 bit[1:0] = 3 :: All ADCs will be used by QA. */
+		        case 3:
+					/* All */
+					pAd->ate.RxAntennaSel = 0;
+		            break;
+				/* The BBP R3 bit[1:0] = 0 :: ADC 0 will be used by QA, */
+				/* unless the BBP R3 bit[4:3] = 2 */
+		        case 0:
+					/* Antenna one */
+					pAd->ate.RxAntennaSel = 1;
+					tmp = ((bbp_data & ((1 << 4) | (1 << 3))/* 0x03 */) >> 3);
+					if (tmp == 2)// 3R
+					{
+						/* Default : All ADCs will be used by QA */
+						pAd->ate.RxAntennaSel = 0;
+					}
+		            break;
+				/* The BBP R3 bit[1:0] = 1 :: ADC 1 will be used by QA. */
+		        case 1:
+					/* Antenna two */
+					pAd->ate.RxAntennaSel = 2;
+		            break;
+				/* The BBP R3 bit[1:0] = 2 :: ADC 2 will be used by QA. */
+		        case 2:
+					/* Antenna three */
+					pAd->ate.RxAntennaSel = 3;
+		            break;
+		        default:
+		            DBGPRINT(RT_DEBUG_ERROR, ("%s -- Impossible!  : return FALSE; \n", __FUNCTION__));
+		            return FALSE;
+		    }
+			break;/* case BBP_R3 */
+
+        default:
+            DBGPRINT(RT_DEBUG_ERROR, ("%s -- Sth. wrong!  : return FALSE; \n", __FUNCTION__));
+            return FALSE;
+
+	}
+	return TRUE;
+}
+
+static VOID memcpy_exl(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len)
+{
+	ULONG i, Value = 0;
+	ULONG *pDst, *pSrc;
+	UCHAR *p8;
+
+	p8 = src;
+	pDst = (ULONG *) dst;
+	pSrc = (ULONG *) src;
+
+	for (i = 0 ; i < (len/4); i++)
+	{
+		/* For alignment issue, we need a variable "Value". */
+		memmove(&Value, pSrc, 4);
+		Value = htonl(Value);
+		memmove(pDst, &Value, 4);
+		pDst++;
+		pSrc++;
+	}
+	if ((len % 4) != 0)
+	{
+		/* wish that it will never reach here */
+		memmove(&Value, pSrc, (len % 4));
+		Value = htonl(Value);
+		memmove(pDst, &Value, (len % 4));
+	}
+}
+
+static VOID memcpy_exs(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len)
+{
+	ULONG i;
+	UCHAR *pDst, *pSrc;
+
+	pDst = dst;
+	pSrc = src;
+
+	for (i = 0; i < (len/2); i++)
+	{
+		memmove(pDst, pSrc, 2);
+		*((USHORT *)pDst) = htons(*((USHORT *)pDst));
+		pDst+=2;
+		pSrc+=2;
+	}
+
+	if ((len % 2) != 0)
+	{
+		memmove(pDst, pSrc, 1);
+	}
+}
+
+static VOID RTMP_IO_READ_BULK(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, UINT32 len)
+{
+	UINT32 i, Value;
+	UINT32 *pDst, *pSrc;
+
+	pDst = (UINT32 *) dst;
+	pSrc = (UINT32 *) src;
+
+	for (i = 0 ; i < (len/4); i++)
+	{
+		RTMP_IO_READ32(pAd, (ULONG)pSrc, &Value);
+		Value = htonl(Value);
+		memmove(pDst, &Value, 4);
+		pDst++;
+		pSrc++;
+	}
+	return;
+}
+
+INT Set_TxStop_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ATEDBGPRINT(RT_DEBUG_TRACE,("Set_TxStop_Proc\n"));
+
+	if (Set_ATE_Proc(pAd, "TXSTOP"))
+	{
+	return TRUE;
+}
+	else
+	{
+		return FALSE;
+	}
+}
+
+INT Set_RxStop_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ATEDBGPRINT(RT_DEBUG_TRACE,("Set_RxStop_Proc\n"));
+
+	if (Set_ATE_Proc(pAd, "RXSTOP"))
+	{
+	return TRUE;
+}
+	else
+	{
+		return FALSE;
+	}
+}
+#endif	// RALINK_28xx_QA //
+#endif	// RALINK_ATE //
+
diff --git a/drivers/staging/rt3070/rt_ate.h b/drivers/staging/rt3070/rt_ate.h
new file mode 100644
index 0000000..829ebb5
--- /dev/null
+++ b/drivers/staging/rt3070/rt_ate.h
@@ -0,0 +1,294 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+ */
+
+#ifndef __ATE_H__
+#define __ATE_H__
+
+#ifndef UCOS
+#define ate_print printk
+#define ATEDBGPRINT DBGPRINT
+
+#ifdef RT2870
+#define EEPROM_SIZE								0x400
+#ifdef CONFIG_STA_SUPPORT
+#define EEPROM_BIN_FILE_NAME  "/etc/Wireless/RT2870STA/e2p.bin"
+#endif // CONFIG_STA_SUPPORT //
+#endif // RT2870 //
+#else // !UCOS //
+#define fATE_LOAD_EEPROM						0x0C43
+#ifdef CONFIG_PRINTK
+extern INT ConsoleResponse(IN PUCHAR buff);
+extern int (*remote_display)(char *);
+extern void puts (const char *s);
+
+/* specificly defined to redirect and show ate-related messages to host. */
+/* Try to define ate_print as a macro. */
+#define ate_print(fmt, args...)                 \
+do{   int (*org_remote_display)(char *) = NULL;   \
+	org_remote_display = remote_display;\
+	/* Save original "remote_display" */\
+	remote_display = (int (*)(char *))ConsoleResponse;           \
+	printk(fmt, ## args);                       \
+	/* Restore the remote_display function pointer */        \
+	remote_display = org_remote_display; }while(0)
+
+#define ATEDBGPRINT(Level, Fmt)    	\
+{                                   \
+    if ((Level) <= RTDebugLevel)      \
+    {                               \
+        ate_print Fmt;					\
+    }                               \
+}
+#endif // CONFIG_PRINTK //
+#endif // !UCOS //
+
+#define ATE_ON(_p)              (((_p)->ate.Mode) != ATE_STOP)
+
+/* RT2880_iNIC will define "RT2860". */
+
+/* RT2880_iNIC will define RT2860. */
+
+#ifdef RT2870
+#define EEPROM_SIZE								0x400
+#ifdef CONFIG_STA_SUPPORT
+#define EEPROM_BIN_FILE_NAME  "/etc/Wireless/RT2870STA/e2p.bin"
+#endif // CONFIG_STA_SUPPORT //
+#endif // RT2870 //
+
+#ifdef RT2870
+#define ATE_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)    RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)
+#define ATE_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V)    RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V)
+
+#define BULK_OUT_LOCK(pLock, IrqFlags)	\
+		if(1 /*!(in_interrupt() & 0xffff0000)*/)	\
+			RTMP_IRQ_LOCK((pLock), IrqFlags);
+
+#define BULK_OUT_UNLOCK(pLock, IrqFlags)	\
+		if(1 /*!(in_interrupt() & 0xffff0000)*/)	\
+			RTMP_IRQ_UNLOCK((pLock), IrqFlags);
+
+// Prototypes of completion funuc.
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#define ATE_RTUSBBulkOutDataPacketComplete(purb, pt_regs)    ATE_RTUSBBulkOutDataPacketComplete(purb)
+#endif
+
+VOID ATE_RTUSBBulkOutDataPacketComplete(
+	IN purbb_t purb,
+	OUT struct pt_regs *pt_regs);
+
+VOID ATE_RTUSBBulkOutDataPacket(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			BulkOutPipeId);
+
+VOID ATE_RTUSBCancelPendingBulkInIRP(
+	IN	PRTMP_ADAPTER	pAd);
+#endif // RT2870 //
+
+#ifdef RT30xx
+#define ATE_RF_IO_READ8_BY_REG_ID(_A, _I, _pV)     RTMP_RF_IO_READ8_BY_REG_ID(_A, _I, _pV)
+#define ATE_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V)     RTMP_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V)
+#endif // RT30xx //
+
+
+VOID rt_ee_read_all(
+	IN  PRTMP_ADAPTER   pAd,
+	OUT USHORT *Data);
+
+
+VOID rt_ee_write_all(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  USHORT *Data);
+
+INT Set_ATE_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_ATE_DA_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_ATE_SA_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_ATE_BSSID_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_ATE_CHANNEL_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_ATE_TX_POWER0_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_ATE_TX_POWER1_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_ATE_TX_Antenna_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_ATE_RX_Antenna_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_ATE_TX_FREQOFFSET_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_ATE_TX_BW_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_ATE_TX_LENGTH_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_ATE_TX_COUNT_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_ATE_TX_MCS_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_ATE_TX_MODE_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_ATE_TX_GI_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+
+INT	Set_ATE_RX_FER_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT Set_ATE_Read_RF_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT Set_ATE_Write_RF1_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT Set_ATE_Write_RF2_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT Set_ATE_Write_RF3_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT Set_ATE_Write_RF4_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT Set_ATE_Load_E2P_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT Set_ATE_Read_E2P_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_ATE_Show_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_ATE_Help_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+#ifdef RALINK_ATE
+#ifdef RALINK_28xx_QA
+VOID ATE_QA_Statistics(
+	IN PRTMP_ADAPTER		pAd,
+	IN PRXWI_STRUC			pRxWI,
+	IN PRT28XX_RXD_STRUC    p28xxRxD,
+	IN PHEADER_802_11		pHeader);
+
+VOID RtmpDoAte(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq);
+
+VOID BubbleSort(
+	IN  INT32 n,
+	IN  INT32 a[]);
+
+VOID CalNoiseLevel(
+	IN  PRTMP_ADAPTER   pAdapter,
+	IN  UCHAR           channel,
+	OUT INT32           buffer[3][10]);
+
+BOOLEAN SyncTxRxConfig(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	USHORT			offset,
+	IN	UCHAR			value);
+
+INT Set_TxStop_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT Set_RxStop_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+#endif // RALINK_28xx_QA //
+#endif // RALINK_ATE //
+
+VOID ATEAsicSwitchChannel(
+	IN PRTMP_ADAPTER pAd);
+
+VOID ATEAsicAdjustTxPower(
+	IN PRTMP_ADAPTER pAd);
+
+VOID ATEDisableAsicProtect(
+	IN		PRTMP_ADAPTER	pAd);
+
+CHAR ATEConvertToRssi(
+	IN PRTMP_ADAPTER  pAd,
+	IN CHAR				Rssi,
+	IN UCHAR    RssiNumber);
+
+VOID ATESampleRssi(
+	IN PRTMP_ADAPTER	pAd,
+	IN PRXWI_STRUC		pRxWI);
+
+
+#ifdef CONFIG_STA_SUPPORT
+VOID RTMPStationStop(
+    IN  PRTMP_ADAPTER   pAd);
+
+VOID RTMPStationStart(
+    IN  PRTMP_ADAPTER   pAd);
+#endif // CONFIG_STA_SUPPORT //
+#endif // __ATE_H__ //
diff --git a/drivers/staging/rt3070/rt_config.h b/drivers/staging/rt3070/rt_config.h
new file mode 100644
index 0000000..9e06417
--- /dev/null
+++ b/drivers/staging/rt3070/rt_config.h
@@ -0,0 +1,121 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	rt_config.h
+
+	Abstract:
+	Central header file to maintain all include files for all NDIS
+	miniport driver routines.
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+	Paul Lin    08-01-2002    created
+
+*/
+#ifndef	__RT_CONFIG_H__
+#define	__RT_CONFIG_H__
+
+#include    "rtmp_type.h"
+#ifdef UCOS
+#include "includes.h"
+#include <stdio.h>
+#include 	"rt_ucos.h"
+#endif
+
+#ifdef LINUX
+#include	"rt_linux.h"
+#endif
+#include    "rtmp_def.h"
+#include    "rt28xx.h"
+
+
+#ifdef RT2870
+#include	"rt2870.h"
+#endif // RT2870 //
+
+#include    "oid.h"
+#include    "mlme.h"
+#include    "wpa.h"
+#include    "md5.h"
+#include    "rtmp.h"
+#include	"ap.h"
+#include	"dfs.h"
+#include	"chlist.h"
+#include	"spectrum.h"
+#ifdef MLME_EX
+#include	"mlme_ex_def.h"
+#include	"mlme_ex.h"
+#endif // MLME_EX //
+
+#undef AP_WSC_INCLUDED
+#undef STA_WSC_INCLUDED
+#undef WSC_INCLUDED
+
+
+#ifdef LEAP_SUPPORT
+#include    "leap.h"
+#endif // LEAP_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef BLOCK_NET_IF
+#include "netif_block.h"
+#endif // BLOCK_NET_IF //
+
+#ifdef IGMP_SNOOP_SUPPORT
+#include "igmp_snoop.h"
+#endif // IGMP_SNOOP_SUPPORT //
+
+#ifdef RALINK_ATE
+#include "rt_ate.h"
+#endif // RALINK_ATE //
+
+
+
+#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED)
+#define WSC_INCLUDED
+#endif
+
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+#ifndef WPA_SUPPLICANT_SUPPORT
+#error "Build for being controlled by NetworkManager or wext, please set HAS_WPA_SUPPLICANT=y and HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=y"
+#endif // WPA_SUPPLICANT_SUPPORT //
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+#endif // CONFIG_STA_SUPPORT //
+
+
+#ifdef IKANOS_VX_1X0
+#include	"vr_ikans.h"
+#endif // IKANOS_VX_1X0 //
+
+#endif	// __RT_CONFIG_H__
+
diff --git a/drivers/staging/rt3070/rt_linux.c b/drivers/staging/rt3070/rt_linux.c
new file mode 100644
index 0000000..bf33853
--- /dev/null
+++ b/drivers/staging/rt3070/rt_linux.c
@@ -0,0 +1,1063 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+ */
+
+#include "rt_config.h"
+
+ULONG	RTDebugLevel = RT_DEBUG_ERROR;
+
+BUILD_TIMER_FUNCTION(MlmePeriodicExec);
+//BUILD_TIMER_FUNCTION(MlmeRssiReportExec);
+BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
+BUILD_TIMER_FUNCTION(APSDPeriodicExec);
+BUILD_TIMER_FUNCTION(AsicRfTuningExec);
+#ifdef RT2870
+BUILD_TIMER_FUNCTION(BeaconUpdateExec);
+#endif // RT2870 //
+
+
+#ifdef CONFIG_STA_SUPPORT
+BUILD_TIMER_FUNCTION(BeaconTimeout);
+BUILD_TIMER_FUNCTION(ScanTimeout);
+BUILD_TIMER_FUNCTION(AuthTimeout);
+BUILD_TIMER_FUNCTION(AssocTimeout);
+BUILD_TIMER_FUNCTION(ReassocTimeout);
+BUILD_TIMER_FUNCTION(DisassocTimeout);
+BUILD_TIMER_FUNCTION(LinkDownExec);
+#ifdef LEAP_SUPPORT
+BUILD_TIMER_FUNCTION(LeapAuthTimeout);
+#endif
+BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
+BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
+#ifdef QOS_DLS_SUPPORT
+BUILD_TIMER_FUNCTION(DlsTimeoutAction);
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+
+
+
+// for wireless system event message
+char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
+	// system status event
+    "had associated successfully",							/* IW_ASSOC_EVENT_FLAG */
+    "had disassociated",									/* IW_DISASSOC_EVENT_FLAG */
+    "had deauthenticated",									/* IW_DEAUTH_EVENT_FLAG */
+    "had been aged-out and disassociated",					/* IW_AGEOUT_EVENT_FLAG */
+    "occurred CounterMeasures attack",						/* IW_COUNTER_MEASURES_EVENT_FLAG */
+    "occurred replay counter different in Key Handshaking",	/* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
+    "occurred RSNIE different in Key Handshaking",			/* IW_RSNIE_DIFF_EVENT_FLAG */
+    "occurred MIC different in Key Handshaking",			/* IW_MIC_DIFF_EVENT_FLAG */
+    "occurred ICV error in RX",								/* IW_ICV_ERROR_EVENT_FLAG */
+    "occurred MIC error in RX",								/* IW_MIC_ERROR_EVENT_FLAG */
+	"Group Key Handshaking timeout",						/* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
+	"Pairwise Key Handshaking timeout",						/* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
+	"RSN IE sanity check failure",							/* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
+	"set key done in WPA/WPAPSK",							/* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
+	"set key done in WPA2/WPA2PSK",                         /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
+	"connects with our wireless client",                    /* IW_STA_LINKUP_EVENT_FLAG */
+	"disconnects with our wireless client",                 /* IW_STA_LINKDOWN_EVENT_FLAG */
+	"scan completed"										/* IW_SCAN_COMPLETED_EVENT_FLAG */
+	"scan terminate!! Busy!! Enqueue fail!!"				/* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
+	};
+
+// for wireless IDS_spoof_attack event message
+char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = {
+    "detected conflict SSID",								/* IW_CONFLICT_SSID_EVENT_FLAG */
+    "detected spoofed association response",				/* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
+    "detected spoofed reassociation responses",				/* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
+    "detected spoofed probe response",						/* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
+    "detected spoofed beacon",								/* IW_SPOOF_BEACON_EVENT_FLAG */
+    "detected spoofed disassociation",						/* IW_SPOOF_DISASSOC_EVENT_FLAG */
+    "detected spoofed authentication",						/* IW_SPOOF_AUTH_EVENT_FLAG */
+    "detected spoofed deauthentication",					/* IW_SPOOF_DEAUTH_EVENT_FLAG */
+    "detected spoofed unknown management frame",			/* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
+	"detected replay attack"								/* IW_REPLAY_ATTACK_EVENT_FLAG */
+	};
+
+// for wireless IDS_flooding_attack event message
+char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = {
+	"detected authentication flooding",						/* IW_FLOOD_AUTH_EVENT_FLAG */
+    "detected association request flooding",				/* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
+    "detected reassociation request flooding",				/* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
+    "detected probe request flooding",						/* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
+    "detected disassociation flooding",						/* IW_FLOOD_DISASSOC_EVENT_FLAG */
+    "detected deauthentication flooding",					/* IW_FLOOD_DEAUTH_EVENT_FLAG */
+    "detected 802.1x eap-request flooding"					/* IW_FLOOD_EAP_REQ_EVENT_FLAG */
+	};
+
+
+/* timeout -- ms */
+VOID RTMP_SetPeriodicTimer(
+	IN	NDIS_MINIPORT_TIMER *pTimer,
+	IN	unsigned long timeout)
+{
+	timeout = ((timeout*HZ) / 1000);
+	pTimer->expires = jiffies + timeout;
+	add_timer(pTimer);
+}
+
+/* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
+VOID RTMP_OS_Init_Timer(
+	IN	PRTMP_ADAPTER pAd,
+	IN	NDIS_MINIPORT_TIMER *pTimer,
+	IN	TIMER_FUNCTION function,
+	IN	PVOID data)
+{
+	init_timer(pTimer);
+    pTimer->data = (unsigned long)data;
+    pTimer->function = function;
+}
+
+
+VOID RTMP_OS_Add_Timer(
+	IN	NDIS_MINIPORT_TIMER		*pTimer,
+	IN	unsigned long timeout)
+{
+	if (timer_pending(pTimer))
+		return;
+
+	timeout = ((timeout*HZ) / 1000);
+	pTimer->expires = jiffies + timeout;
+	add_timer(pTimer);
+}
+
+VOID RTMP_OS_Mod_Timer(
+	IN	NDIS_MINIPORT_TIMER		*pTimer,
+	IN	unsigned long timeout)
+{
+	timeout = ((timeout*HZ) / 1000);
+	mod_timer(pTimer, jiffies + timeout);
+}
+
+VOID RTMP_OS_Del_Timer(
+	IN	NDIS_MINIPORT_TIMER		*pTimer,
+	OUT	BOOLEAN					*pCancelled)
+{
+	if (timer_pending(pTimer))
+	{
+		*pCancelled = del_timer_sync(pTimer);
+	}
+	else
+	{
+		*pCancelled = TRUE;
+	}
+
+}
+
+VOID RTMP_OS_Release_Packet(
+	IN	PRTMP_ADAPTER pAd,
+	IN	PQUEUE_ENTRY  pEntry)
+{
+	//RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry);
+}
+
+// Unify all delay routine by using udelay
+VOID RTMPusecDelay(
+	IN	ULONG	usec)
+{
+	ULONG	i;
+
+	for (i = 0; i < (usec / 50); i++)
+		udelay(50);
+
+	if (usec % 50)
+		udelay(usec % 50);
+}
+
+void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
+{
+	time->u.LowPart = jiffies;
+}
+
+// pAd MUST allow to be NULL
+NDIS_STATUS os_alloc_mem(
+	IN	PRTMP_ADAPTER pAd,
+	OUT	PUCHAR *mem,
+	IN	ULONG  size)
+{
+	*mem = (PUCHAR) kmalloc(size, GFP_ATOMIC);
+	if (*mem)
+		return (NDIS_STATUS_SUCCESS);
+	else
+		return (NDIS_STATUS_FAILURE);
+}
+
+// pAd MUST allow to be NULL
+NDIS_STATUS os_free_mem(
+	IN	PRTMP_ADAPTER pAd,
+	IN	PUCHAR mem)
+{
+
+	ASSERT(mem);
+	kfree(mem);
+	return (NDIS_STATUS_SUCCESS);
+}
+
+
+PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
+	IN	PRTMP_ADAPTER pAd,
+	IN	ULONG	Length)
+{
+	struct sk_buff *pkt;
+
+	pkt = dev_alloc_skb(Length);
+
+	if (pkt == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("can't allocate frag rx %ld size packet\n",Length));
+	}
+
+	if (pkt)
+	{
+		RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
+	}
+
+	return (PNDIS_PACKET) pkt;
+}
+
+
+PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
+	IN	PRTMP_ADAPTER pAd,
+	IN	ULONG	Length,
+	IN	BOOLEAN	Cached,
+	OUT	PVOID	*VirtualAddress)
+{
+	struct sk_buff *pkt;
+
+	pkt = dev_alloc_skb(Length);
+
+	if (pkt == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("can't allocate tx %ld size packet\n",Length));
+	}
+
+	if (pkt)
+	{
+		RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
+		*VirtualAddress = (PVOID) pkt->data;
+	}
+	else
+	{
+		*VirtualAddress = (PVOID) NULL;
+	}
+
+	return (PNDIS_PACKET) pkt;
+}
+
+
+VOID build_tx_packet(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PNDIS_PACKET	pPacket,
+	IN	PUCHAR	pFrame,
+	IN	ULONG	FrameLen)
+{
+
+	struct sk_buff	*pTxPkt;
+
+	ASSERT(pPacket);
+	pTxPkt = RTPKT_TO_OSPKT(pPacket);
+
+	NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
+}
+
+VOID	RTMPFreeAdapter(
+	IN	PRTMP_ADAPTER	pAd)
+{
+    POS_COOKIE os_cookie;
+	int index;
+
+	os_cookie=(POS_COOKIE)pAd->OS_Cookie;
+
+	kfree(pAd->BeaconBuf);
+
+
+	NdisFreeSpinLock(&pAd->MgmtRingLock);
+
+
+	for (index =0 ; index < NUM_OF_TX_RING; index++)
+	{
+    	NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
+		NdisFreeSpinLock(&pAd->DeQueueLock[index]);
+		pAd->DeQueueRunning[index] = FALSE;
+	}
+
+	NdisFreeSpinLock(&pAd->irq_lock);
+
+
+	vfree(pAd); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa);
+	kfree(os_cookie);
+}
+
+BOOLEAN OS_Need_Clone_Packet(void)
+{
+	return (FALSE);
+}
+
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
+		must have only one NDIS BUFFER
+		return - byte copied. 0 means can't create NDIS PACKET
+		NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket
+
+	Arguments:
+		pAd 	Pointer to our adapter
+		pInsAMSDUHdr	EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
+		*pSrcTotalLen			return total packet length. This lenght is calculated with 802.3 format packet.
+
+	Return Value:
+		NDIS_STATUS_SUCCESS
+		NDIS_STATUS_FAILURE
+
+	Note:
+
+	========================================================================
+*/
+NDIS_STATUS RTMPCloneNdisPacket(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	BOOLEAN			pInsAMSDUHdr,
+	IN	PNDIS_PACKET	pInPacket,
+	OUT PNDIS_PACKET   *ppOutPacket)
+{
+
+	struct sk_buff *pkt;
+
+	ASSERT(pInPacket);
+	ASSERT(ppOutPacket);
+
+	// 1. Allocate a packet
+	pkt = dev_alloc_skb(2048);
+
+	if (pkt == NULL)
+	{
+		return NDIS_STATUS_FAILURE;
+	}
+
+ 	skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
+	NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket), GET_OS_PKT_LEN(pInPacket));
+	*ppOutPacket = OSPKT_TO_RTPKT(pkt);
+
+
+	RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
+
+	printk("###Clone###\n");
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+// the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket()
+NDIS_STATUS RTMPAllocateNdisPacket(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT PNDIS_PACKET   *ppPacket,
+	IN	PUCHAR			pHeader,
+	IN	UINT			HeaderLen,
+	IN	PUCHAR			pData,
+	IN	UINT			DataLen)
+{
+	PNDIS_PACKET	pPacket;
+	ASSERT(pData);
+	ASSERT(DataLen);
+
+	// 1. Allocate a packet
+	pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + TXPADDING_SIZE);
+	if (pPacket == NULL)
+ 	{
+		*ppPacket = NULL;
+#ifdef DEBUG
+		printk("RTMPAllocateNdisPacket Fail\n\n");
+#endif
+		return NDIS_STATUS_FAILURE;
+	}
+
+	// 2. clone the frame content
+	if (HeaderLen > 0)
+		NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
+	if (DataLen > 0)
+		NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, DataLen);
+
+	// 3. update length of packet
+ 	skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen+DataLen);
+
+	RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
+//	printk("%s : pPacket = %p, len = %d\n", __FUNCTION__, pPacket, GET_OS_PKT_LEN(pPacket));
+	*ppPacket = pPacket;
+	return NDIS_STATUS_SUCCESS;
+}
+
+/*
+  ========================================================================
+  Description:
+	This routine frees a miniport internally allocated NDIS_PACKET and its
+	corresponding NDIS_BUFFER and allocated memory.
+  ========================================================================
+*/
+VOID RTMPFreeNdisPacket(
+	IN PRTMP_ADAPTER pAd,
+	IN PNDIS_PACKET  pPacket)
+{
+	dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
+}
+
+
+// IRQL = DISPATCH_LEVEL
+// NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same
+//			 scatter gather buffer
+NDIS_STATUS Sniff2BytesFromNdisBuffer(
+	IN	PNDIS_BUFFER	pFirstBuffer,
+	IN	UCHAR			DesiredOffset,
+	OUT PUCHAR			pByte0,
+	OUT PUCHAR			pByte1)
+{
+    *pByte0 = *(PUCHAR)(pFirstBuffer + DesiredOffset);
+    *pByte1 = *(PUCHAR)(pFirstBuffer + DesiredOffset + 1);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+void RTMP_QueryPacketInfo(
+	IN  PNDIS_PACKET pPacket,
+	OUT PACKET_INFO  *pPacketInfo,
+	OUT PUCHAR		 *pSrcBufVA,
+	OUT	UINT		 *pSrcBufLen)
+{
+	pPacketInfo->BufferCount = 1;
+	pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
+	pPacketInfo->PhysicalBufferCount = 1;
+	pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
+
+	*pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
+	*pSrcBufLen = GET_OS_PKT_LEN(pPacket);
+}
+
+void RTMP_QueryNextPacketInfo(
+	IN  PNDIS_PACKET *ppPacket,
+	OUT PACKET_INFO  *pPacketInfo,
+	OUT PUCHAR		 *pSrcBufVA,
+	OUT	UINT		 *pSrcBufLen)
+{
+	PNDIS_PACKET pPacket = NULL;
+
+	if (*ppPacket)
+		pPacket = GET_OS_PKT_NEXT(*ppPacket);
+
+	if (pPacket)
+	{
+		pPacketInfo->BufferCount = 1;
+		pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
+		pPacketInfo->PhysicalBufferCount = 1;
+		pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
+
+		*pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
+		*pSrcBufLen = GET_OS_PKT_LEN(pPacket);
+		*ppPacket = GET_OS_PKT_NEXT(pPacket);
+	}
+	else
+	{
+		pPacketInfo->BufferCount = 0;
+		pPacketInfo->pFirstBuffer = NULL;
+		pPacketInfo->PhysicalBufferCount = 0;
+		pPacketInfo->TotalPacketLength = 0;
+
+		*pSrcBufVA = NULL;
+		*pSrcBufLen = 0;
+		*ppPacket = NULL;
+	}
+}
+
+// not yet support MBSS
+PNET_DEV get_netdev_from_bssid(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			FromWhichBSSID)
+{
+    PNET_DEV dev_p = NULL;
+
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		dev_p = pAd->net_dev;
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	ASSERT(dev_p);
+	return dev_p; /* return one of MBSS */
+}
+
+PNDIS_PACKET DuplicatePacket(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PNDIS_PACKET	pPacket,
+	IN	UCHAR			FromWhichBSSID)
+{
+	struct sk_buff	*skb;
+	PNDIS_PACKET	pRetPacket = NULL;
+	USHORT			DataSize;
+	UCHAR			*pData;
+
+	DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
+	pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
+
+
+	skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
+	if (skb)
+	{
+		skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
+		pRetPacket = OSPKT_TO_RTPKT(skb);
+	}
+
+	return pRetPacket;
+
+}
+
+PNDIS_PACKET duplicate_pkt(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pHeader802_3,
+    IN  UINT            HdrLen,
+	IN	PUCHAR			pData,
+	IN	ULONG			DataSize,
+	IN	UCHAR			FromWhichBSSID)
+{
+	struct sk_buff	*skb;
+	PNDIS_PACKET	pPacket = NULL;
+
+
+	if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL)
+	{
+		skb_reserve(skb, 2);
+		NdisMoveMemory(skb->tail, pHeader802_3, HdrLen);
+		skb_put(skb, HdrLen);
+		NdisMoveMemory(skb->tail, pData, DataSize);
+		skb_put(skb, DataSize);
+		skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
+		pPacket = OSPKT_TO_RTPKT(skb);
+	}
+
+	return pPacket;
+}
+
+
+#define TKIP_TX_MIC_SIZE		8
+PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PNDIS_PACKET	pPacket)
+{
+	struct sk_buff	*skb, *newskb;
+
+
+	skb = RTPKT_TO_OSPKT(pPacket);
+	if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE)
+	{
+		// alloc a new skb and copy the packet
+		newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
+		dev_kfree_skb_any(skb);
+		if (newskb == NULL)
+		{
+			DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
+			return NULL;
+		}
+		skb = newskb;
+	}
+
+	return OSPKT_TO_RTPKT(skb);
+}
+
+
+
+
+PNDIS_PACKET ClonePacket(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PNDIS_PACKET	pPacket,
+	IN	PUCHAR			pData,
+	IN	ULONG			DataSize)
+{
+	struct sk_buff	*pRxPkt;
+	struct sk_buff	*pClonedPkt;
+
+	ASSERT(pPacket);
+	pRxPkt = RTPKT_TO_OSPKT(pPacket);
+
+	// clone the packet
+	pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
+
+	if (pClonedPkt)
+	{
+    	// set the correct dataptr and data len
+    	pClonedPkt->dev = pRxPkt->dev;
+    	pClonedPkt->data = pData;
+    	pClonedPkt->len = DataSize;
+    	pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
+		ASSERT(DataSize < 1530);
+	}
+	return pClonedPkt;
+}
+
+//
+// change OS packet DataPtr and DataLen
+//
+void  update_os_packet_info(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	RX_BLK			*pRxBlk,
+	IN  UCHAR			FromWhichBSSID)
+{
+	struct sk_buff	*pOSPkt;
+
+	ASSERT(pRxBlk->pRxPacket);
+	pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
+
+	pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
+	pOSPkt->data = pRxBlk->pData;
+	pOSPkt->len = pRxBlk->DataSize;
+	pOSPkt->tail = pOSPkt->data + pOSPkt->len;
+}
+
+
+void wlan_802_11_to_802_3_packet(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	RX_BLK			*pRxBlk,
+	IN	PUCHAR			pHeader802_3,
+	IN  UCHAR			FromWhichBSSID)
+{
+	struct sk_buff	*pOSPkt;
+
+	ASSERT(pRxBlk->pRxPacket);
+	ASSERT(pHeader802_3);
+
+	pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
+
+	pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
+	pOSPkt->data = pRxBlk->pData;
+	pOSPkt->len = pRxBlk->DataSize;
+	pOSPkt->tail = pOSPkt->data + pOSPkt->len;
+
+	//
+	// copy 802.3 header
+	//
+	//
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3);
+#endif // CONFIG_STA_SUPPORT //
+	}
+
+
+
+void announce_802_3_packet(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PNDIS_PACKET	pPacket)
+{
+
+	struct sk_buff	*pRxPkt;
+
+	ASSERT(pPacket);
+
+	pRxPkt = RTPKT_TO_OSPKT(pPacket);
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+    /* Push up the protocol stack */
+#ifdef IKANOS_VX_1X0
+	IKANOS_DataFrameRx(pAd, pRxPkt->dev, pRxPkt, pRxPkt->len);
+#else
+	pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
+
+//#ifdef CONFIG_5VT_ENHANCE
+//	*(int*)(pRxPkt->cb) = BRIDGE_TAG;
+//#endif
+	netif_rx(pRxPkt);
+#endif // IKANOS_VX_1X0 //
+}
+
+
+PRTMP_SCATTER_GATHER_LIST
+rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg)
+{
+	sg->NumberOfElements = 1;
+	sg->Elements[0].Address =  GET_OS_PKT_DATAPTR(pPacket);
+	sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
+	return (sg);
+}
+
+void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
+{
+	unsigned char *pt;
+	int x;
+
+	if (RTDebugLevel < RT_DEBUG_TRACE)
+		return;
+
+	pt = pSrcBufVA;
+	printk("%s: %p, len = %d\n",str,  pSrcBufVA, SrcBufLen);
+	for (x=0; x<SrcBufLen; x++)
+	{
+		if (x % 16 == 0)
+			printk("0x%04x : ", x);
+		printk("%02x ", ((unsigned char)pt[x]));
+		if (x%16 == 15) printk("\n");
+	}
+	printk("\n");
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Send log message through wireless event
+
+		Support standard iw_event with IWEVCUSTOM. It is used below.
+
+		iwreq_data.data.flags is used to store event_flag that is defined by user.
+		iwreq_data.data.length is the length of the event log.
+
+		The format of the event log is composed of the entry's MAC address and
+		the desired log message (refer to pWirelessEventText).
+
+			ex: 11:22:33:44:55:66 has associated successfully
+
+		p.s. The requirement of Wireless Extension is v15 or newer.
+
+	========================================================================
+*/
+VOID RTMPSendWirelessEvent(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT			Event_flag,
+	IN	PUCHAR 			pAddr,
+	IN	UCHAR			BssIdx,
+	IN	CHAR			Rssi)
+{
+#if WIRELESS_EXT >= 15
+
+	union 	iwreq_data      wrqu;
+	PUCHAR 	pBuf = NULL, pBufPtr = NULL;
+	USHORT	event, type, BufLen;
+	UCHAR	event_table_len = 0;
+
+	type = Event_flag & 0xFF00;
+	event = Event_flag & 0x00FF;
+
+	switch (type)
+	{
+		case IW_SYS_EVENT_FLAG_START:
+			event_table_len = IW_SYS_EVENT_TYPE_NUM;
+			break;
+
+		case IW_SPOOF_EVENT_FLAG_START:
+			event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
+			break;
+
+		case IW_FLOOD_EVENT_FLAG_START:
+			event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
+			break;
+	}
+
+	if (event_table_len == 0)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __FUNCTION__, type));
+		return;
+	}
+
+	if (event >= event_table_len)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __FUNCTION__, event));
+		return;
+	}
+
+	//Allocate memory and copy the msg.
+	if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL)
+	{
+		//Prepare the payload
+		memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
+
+		pBufPtr = pBuf;
+
+		if (pAddr)
+			pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr));
+		else if (BssIdx < MAX_MBSSID_NUM)
+			pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(ra%d) ", BssIdx);
+		else
+			pBufPtr += sprintf(pBufPtr, "(RT2860) ");
+
+		if (type == IW_SYS_EVENT_FLAG_START)
+			pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]);
+		else if (type == IW_SPOOF_EVENT_FLAG_START)
+			pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi);
+		else if (type == IW_FLOOD_EVENT_FLAG_START)
+			pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]);
+		else
+			pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
+
+		pBufPtr[pBufPtr - pBuf] = '\0';
+		BufLen = pBufPtr - pBuf;
+
+		memset(&wrqu, 0, sizeof(wrqu));
+	    wrqu.data.flags = Event_flag;
+		wrqu.data.length = BufLen;
+
+		//send wireless event
+	    wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, pBuf);
+
+		//DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __FUNCTION__, pBuf));
+
+		kfree(pBuf);
+	}
+	else
+		DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __FUNCTION__));
+#else
+	DBGPRINT(RT_DEBUG_ERROR, ("%s : The Wireless Extension MUST be v15 or newer.\n", __FUNCTION__));
+#endif  /* WIRELESS_EXT >= 15 */
+}
+
+
+#ifdef CONFIG_STA_SUPPORT
+void send_monitor_packets(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	RX_BLK			*pRxBlk)
+{
+    struct sk_buff	*pOSPkt;
+    wlan_ng_prism2_header *ph;
+    int rate_index = 0;
+    USHORT header_len = 0;
+    UCHAR temp_header[40] = {0};
+
+    u_int32_t ralinkrate[256] = {2,4,11,22, 12,18,24,36,48,72,96,  108,   109, 110, 111, 112, 13, 26, 39, 52,78,104, 117, 130, 26, 52, 78,104, 156, 208, 234, 260, 27, 54,81,108,162, 216, 243, 270, // Last 38
+	54, 108, 162, 216, 324, 432, 486, 540,  14, 29, 43, 57, 87, 115, 130, 144, 29, 59,87,115, 173, 230,260, 288, 30, 60,90,120,180,240,270,300,60,120,180,240,360,480,540,600, 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,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80};
+
+
+    ASSERT(pRxBlk->pRxPacket);
+    if (pRxBlk->DataSize < 10)
+    {
+        DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __FUNCTION__, pRxBlk->DataSize));
+		goto err_free_sk_buff;
+    }
+
+    if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
+    {
+        DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%d)\n", __FUNCTION__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
+		goto err_free_sk_buff;
+    }
+
+    pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
+	pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
+    if (pRxBlk->pHeader->FC.Type == BTYPE_DATA)
+    {
+        pRxBlk->DataSize -= LENGTH_802_11;
+        if ((pRxBlk->pHeader->FC.ToDs == 1) &&
+            (pRxBlk->pHeader->FC.FrDs == 1))
+            header_len = LENGTH_802_11_WITH_ADDR4;
+        else
+            header_len = LENGTH_802_11;
+
+        // QOS
+    	if (pRxBlk->pHeader->FC.SubType & 0x08)
+    	{
+    	    header_len += 2;
+    		// Data skip QOS contorl field
+    		pRxBlk->DataSize -=2;
+    	}
+
+    	// Order bit: A-Ralink or HTC+
+    	if (pRxBlk->pHeader->FC.Order)
+    	{
+    	    header_len += 4;
+			// Data skip HTC contorl field
+			pRxBlk->DataSize -= 4;
+    	}
+
+        // Copy Header
+        if (header_len <= 40)
+            NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
+
+        // skip HW padding
+    	if (pRxBlk->RxD.L2PAD)
+    	    pRxBlk->pData += (header_len + 2);
+        else
+            pRxBlk->pData += header_len;
+    } //end if
+
+
+	if (pRxBlk->DataSize < pOSPkt->len) {
+        skb_trim(pOSPkt,pRxBlk->DataSize);
+    } else {
+        skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len));
+    } //end if
+
+    if ((pRxBlk->pData - pOSPkt->data) > 0) {
+	    skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data));
+	    skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data));
+    } //end if
+
+    if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) {
+        if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) {
+	        DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __FUNCTION__));
+			goto err_free_sk_buff;
+	    } //end if
+    } //end if
+
+    if (header_len > 0)
+        NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len);
+
+    ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header));
+	NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header));
+
+    ph->msgcode		    = DIDmsg_lnxind_wlansniffrm;
+	ph->msglen		    = sizeof(wlan_ng_prism2_header);
+	strcpy(ph->devname, pAd->net_dev->name);
+
+    ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
+	ph->hosttime.status = 0;
+	ph->hosttime.len = 4;
+	ph->hosttime.data = jiffies;
+
+	ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
+	ph->mactime.status = 0;
+	ph->mactime.len = 0;
+	ph->mactime.data = 0;
+
+    ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
+	ph->istx.status = 0;
+	ph->istx.len = 0;
+	ph->istx.data = 0;
+
+    ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
+	ph->channel.status = 0;
+	ph->channel.len = 4;
+
+    ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel;
+
+    ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
+	ph->rssi.status = 0;
+	ph->rssi.len = 4;
+    ph->rssi.data = (u_int32_t)RTMPMaxRssi(pAd, ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI0, RSSI_0), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI1, RSSI_1), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI2, RSSI_2));;
+
+	ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
+	ph->signal.status = 0;
+	ph->signal.len = 4;
+	ph->signal.data = 0; //rssi + noise;
+
+	ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
+	ph->noise.status = 0;
+	ph->noise.len = 4;
+	ph->noise.data = 0;
+
+#ifdef DOT11_N_SUPPORT
+    if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX)
+    {
+    	rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS);
+    }
+    else
+#endif // DOT11_N_SUPPORT //
+	if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
+    	rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4;
+    else
+    	rate_index = (UCHAR)(pRxBlk->pRxWI->MCS);
+    if (rate_index < 0)
+        rate_index = 0;
+    if (rate_index > 255)
+        rate_index = 255;
+
+	ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
+	ph->rate.status = 0;
+	ph->rate.len = 4;
+    ph->rate.data = ralinkrate[rate_index];
+
+	ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
+    ph->frmlen.status = 0;
+	ph->frmlen.len = 4;
+	ph->frmlen.data	= (u_int32_t)pRxBlk->DataSize;
+
+
+    pOSPkt->pkt_type = PACKET_OTHERHOST;
+    pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
+    pOSPkt->ip_summed = CHECKSUM_NONE;
+    netif_rx(pOSPkt);
+
+    return;
+
+err_free_sk_buff:
+	RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+	return;
+
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
+{
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+	daemonize(pThreadName /*"%s",pAd->net_dev->name*/);
+
+	allow_signal(SIGTERM);
+	allow_signal(SIGKILL);
+	current->flags |= PF_NOFREEZE;
+#else
+	unsigned long flags;
+
+	daemonize();
+	reparent_to_init();
+	strcpy(current->comm, pThreadName);
+
+	siginitsetinv(&current->blocked, sigmask(SIGTERM) | sigmask(SIGKILL));
+
+	/* Allow interception of SIGKILL only
+	 * Don't allow other signals to interrupt the transmission */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22)
+	spin_lock_irqsave(&current->sigmask_lock, flags);
+	flush_signals(current);
+	recalc_sigpending(current);
+	spin_unlock_irqrestore(&current->sigmask_lock, flags);
+#endif
+#endif
+
+    /* signal that we've started the thread */
+	complete(pNotify);
+
+}
+
+void RTMP_IndicateMediaState(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	if (pAd->CommonCfg.bWirelessEvent)
+	{
+		if (pAd->IndicateMediaState == NdisMediaStateConnected)
+		{
+			RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+		}
+		else
+		{
+			RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+		}
+	}
+}
+
diff --git a/drivers/staging/rt3070/rt_linux.h b/drivers/staging/rt3070/rt_linux.h
new file mode 100644
index 0000000..0540d02
--- /dev/null
+++ b/drivers/staging/rt3070/rt_linux.h
@@ -0,0 +1,887 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+ */
+
+/***********************************************************************/
+/*                                                                     */
+/*   Program:    rt_linux.c                                            */
+/*   Created:    4/21/2006 1:17:38 PM                                  */
+/*   Author:     Wu Xi-Kun                                             */
+/*   Comments:   `description`                                         */
+/*                                                                     */
+/*---------------------------------------------------------------------*/
+/*                                                                     */
+/* History:                                                            */
+/*    Revision 1.1 4/21/2006 1:17:38 PM  xsikun                        */
+/*    Initial revision                                                 */
+/*                                                                     */
+/***********************************************************************/
+
+#include "rtmp_type.h"
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/ethtool.h>
+#include <linux/wireless.h>
+#include <linux/proc_fs.h>
+#include <linux/delay.h>
+#include <linux/if_arp.h>
+#include <linux/ctype.h>
+#include <linux/vmalloc.h>
+
+
+#include <linux/wireless.h>
+#include <net/iw_handler.h>
+
+// load firmware
+#define __KERNEL_SYSCALLS__
+#include <linux/unistd.h>
+#include <asm/uaccess.h>
+
+
+#define MEM_ALLOC_FLAG      (GFP_ATOMIC) //(GFP_DMA | GFP_ATOMIC)
+
+#ifndef IFNAMSIZ
+#define IFNAMSIZ 16
+#endif
+
+//#define CONFIG_CKIP_SUPPORT
+
+#undef __inline
+#define __inline	   static inline
+
+typedef int (*HARD_START_XMIT_FUNC)(struct sk_buff *skb, struct net_device *net_dev);
+
+// add by kathy
+
+#ifdef CONFIG_STA_SUPPORT
+
+#ifdef RT2870
+#define STA_PROFILE_PATH			"/etc/Wireless/RT2870STA/RT2870STA.dat"
+#define STA_RT2870_IMAGE_FILE_NAME  "/etc/Wireless/RT2870STA/rt2870.bin"
+#define STA_NIC_DEVICE_NAME			"RT2870STA"
+#define STA_DRIVER_VERSION			"2.0.1.0"
+#ifdef MULTIPLE_CARD_SUPPORT
+#define CARD_INFO_PATH			"/etc/Wireless/RT2870STA/RT2870STACard.dat"
+#endif // MULTIPLE_CARD_SUPPORT //
+#endif // RT2870 //
+
+#endif // CONFIG_STA_SUPPORT //
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+
+#define RTMP_TIME_AFTER(a,b)		\
+	(typecheck(unsigned long, (unsigned long)a) && \
+	 typecheck(unsigned long, (unsigned long)b) && \
+	 ((long)(b) - (long)(a) < 0))
+
+#define RTMP_TIME_AFTER_EQ(a,b)	\
+	(typecheck(unsigned long, (unsigned long)a) && \
+	 typecheck(unsigned long, (unsigned long)b) && \
+	 ((long)(a) - (long)(b) >= 0))
+#define RTMP_TIME_BEFORE(a,b)	RTMP_TIME_AFTER_EQ(b,a)
+#else
+#define RTMP_TIME_AFTER(a,b) time_after(a, b)
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#define RT_MOD_INC_USE_COUNT() \
+	if (!try_module_get(THIS_MODULE)) \
+	{ \
+		DBGPRINT(RT_DEBUG_ERROR, ("%s: cannot reserve module\n", __FUNCTION__)); \
+		return -1; \
+	}
+
+#define RT_MOD_DEC_USE_COUNT() module_put(THIS_MODULE);
+#else
+#define RT_MOD_INC_USE_COUNT()	MOD_INC_USE_COUNT;
+#define RT_MOD_DEC_USE_COUNT() MOD_DEC_USE_COUNT;
+#endif
+
+#define OS_HZ			HZ
+
+#define ETH_LENGTH_OF_ADDRESS	6
+
+#define IN
+#define OUT
+
+#define NDIS_STATUS                             INT
+#define NDIS_STATUS_SUCCESS                     0x00
+#define NDIS_STATUS_FAILURE                     0x01
+#define NDIS_STATUS_INVALID_DATA				0x02
+#define NDIS_STATUS_RESOURCES                   0x03
+
+#define MIN_NET_DEVICE_FOR_AID			0x00		//0x00~0x3f
+#define MIN_NET_DEVICE_FOR_MBSSID		0x00		//0x00,0x10,0x20,0x30
+#define MIN_NET_DEVICE_FOR_WDS			0x10		//0x40,0x50,0x60,0x70
+#define MIN_NET_DEVICE_FOR_APCLI		0x20
+#define MIN_NET_DEVICE_FOR_MESH			0x30
+#ifdef CONFIG_STA_SUPPORT
+#define MIN_NET_DEVICE_FOR_DLS			0x40
+#endif // CONFIG_STA_SUPPORT //
+
+
+#ifdef CONFIG_STA_SUPPORT
+#define NDIS_PACKET_TYPE_DIRECTED		0
+#define NDIS_PACKET_TYPE_MULTICAST		1
+#define NDIS_PACKET_TYPE_BROADCAST		2
+#define NDIS_PACKET_TYPE_ALL_MULTICAST	3
+#endif // CONFIG_STA_SUPPORT //
+
+struct os_lock  {
+	spinlock_t		lock;
+	unsigned long  	flags;
+};
+
+
+struct os_cookie {
+
+#ifdef RT2870
+	struct usb_device		*pUsb_Dev;
+
+	struct pid *		MLMEThr_pid;
+	struct pid *		RTUSBCmdThr_pid;
+	struct pid *		TimerQThr_pid;
+#endif // RT2870 //
+
+	struct tasklet_struct 	rx_done_task;
+	struct tasklet_struct 	mgmt_dma_done_task;
+	struct tasklet_struct 	ac0_dma_done_task;
+	struct tasklet_struct 	ac1_dma_done_task;
+	struct tasklet_struct 	ac2_dma_done_task;
+	struct tasklet_struct 	ac3_dma_done_task;
+	struct tasklet_struct 	hcca_dma_done_task;
+	struct tasklet_struct	tbtt_task;
+#ifdef RT2870
+	struct tasklet_struct	null_frame_complete_task;
+	struct tasklet_struct	rts_frame_complete_task;
+	struct tasklet_struct	pspoll_frame_complete_task;
+#endif // RT2870 //
+
+
+	unsigned long			apd_pid; //802.1x daemon pid
+	INT						ioctl_if_type;
+	INT 					ioctl_if;
+};
+
+typedef struct _VIRTUAL_ADAPTER
+{
+	struct net_device		*RtmpDev;
+	struct net_device		*VirtualDev;
+} VIRTUAL_ADAPTER, PVIRTUAL_ADAPTER;
+
+#undef  ASSERT
+#define ASSERT(x)                                                               \
+{                                                                               \
+    if (!(x))                                                                   \
+    {                                                                           \
+        printk(KERN_WARNING __FILE__ ":%d assert " #x "failed\n", __LINE__);    \
+    }                                                                           \
+}
+
+typedef struct os_cookie	* POS_COOKIE;
+typedef struct pci_dev 		* PPCI_DEV;
+typedef struct net_device	* PNET_DEV;
+typedef void				* PNDIS_PACKET;
+typedef char				NDIS_PACKET;
+typedef PNDIS_PACKET		* PPNDIS_PACKET;
+typedef	dma_addr_t			NDIS_PHYSICAL_ADDRESS;
+typedef	dma_addr_t			* PNDIS_PHYSICAL_ADDRESS;
+//typedef struct timer_list	RALINK_TIMER_STRUCT;
+//typedef struct timer_list	* PRALINK_TIMER_STRUCT;
+//typedef struct os_lock		NDIS_SPIN_LOCK;
+typedef spinlock_t			NDIS_SPIN_LOCK;
+typedef struct timer_list	NDIS_MINIPORT_TIMER;
+typedef void				* NDIS_HANDLE;
+typedef char 				* PNDIS_BUFFER;
+
+
+
+void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen);
+
+dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size, int sd_idx, int direction);
+void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, int direction);
+
+
+////////////////////////////////////////
+// MOVE TO rtmp.h ?
+/////////////////////////////////////////
+#define PKTSRC_NDIS             0x7f
+#define PKTSRC_DRIVER           0x0f
+#define PRINT_MAC(addr)	\
+	addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
+
+
+#define RT2860_PCI_DEVICE_ID		0x0601
+
+#ifdef RT2870
+#define PCI_MAP_SINGLE(_handle, _ptr, _size, _dir) (ULONG)0
+
+#define PCI_UNMAP_SINGLE(_handle, _ptr, _size, _dir)
+#endif // RT2870 //
+
+
+#define BEACON_FRAME_DMA_CACHE_WBACK(_ptr, _size)	\
+	dma_cache_wback(_ptr, _size)
+
+
+//////////////////////////////////////////
+//
+//////////////////////////////////////////
+
+
+#define NdisMIndicateStatus(_w, _x, _y, _z)
+
+
+typedef struct timer_list	RTMP_OS_TIMER;
+
+#ifdef RT2870
+/* ----------------- Timer Related MARCO ---------------*/
+// In RT2870, we have a lot of timer functions and will read/write register, it's
+//	not allowed in Linux USB sub-system to do it ( because of sleep issue when submit
+//  to ctrl pipe). So we need a wrapper function to take care it.
+
+typedef VOID (*RT2870_TIMER_HANDLE)(
+	IN  PVOID   SystemSpecific1,
+	IN  PVOID   FunctionContext,
+	IN  PVOID   SystemSpecific2,
+	IN  PVOID   SystemSpecific3);
+#endif // RT2870 //
+
+
+typedef struct  _RALINK_TIMER_STRUCT    {
+    RTMP_OS_TIMER		TimerObj;       // Ndis Timer object
+	BOOLEAN				Valid;			// Set to True when call RTMPInitTimer
+    BOOLEAN             State;          // True if timer cancelled
+    BOOLEAN	      		PeriodicType;	// True if timer is periodic timer
+    BOOLEAN             Repeat;         // True if periodic timer
+    ULONG               TimerValue;     // Timer value in milliseconds
+	ULONG				cookie;			// os specific object
+#ifdef RT2870
+	RT2870_TIMER_HANDLE	handle;
+	void				*pAd;
+#endif // RT2870 //
+}   RALINK_TIMER_STRUCT, *PRALINK_TIMER_STRUCT;
+
+
+#ifdef RT2870
+
+typedef enum _RT2870_KERNEL_THREAD_STATUS_
+{
+	RT2870_THREAD_UNKNOWN = 0,
+	RT2870_THREAD_INITED = 1,
+	RT2870_THREAD_RUNNING = 2,
+	RT2870_THREAD_STOPED = 4,
+}RT2870_KERNEL_THREAD_STATUS;
+
+#define RT2870_THREAD_CAN_DO_INSERT		(RT2870_THREAD_INITED |RT2870_THREAD_RUNNING)
+
+typedef struct _RT2870_TIMER_ENTRY_
+{
+	RALINK_TIMER_STRUCT 			*pRaTimer;
+	struct _RT2870_TIMER_ENTRY_ 	*pNext;
+}RT2870_TIMER_ENTRY;
+
+
+#define TIMER_QUEUE_SIZE_MAX	128
+typedef struct _RT2870_TIMER_QUEUE_
+{
+	unsigned int		status;
+	//wait_queue_head_t 	timerWaitQ;
+	//atomic_t			count;
+	UCHAR				*pTimerQPoll;
+	RT2870_TIMER_ENTRY	*pQPollFreeList;
+	RT2870_TIMER_ENTRY 	*pQHead;
+	RT2870_TIMER_ENTRY 	*pQTail;
+}RT2870_TIMER_QUEUE;
+#endif // RT2870 //
+
+
+//#define DBG	1
+
+//
+//  MACRO for debugging information
+//
+
+#ifdef DBG
+extern ULONG    RTDebugLevel;
+
+#define DBGPRINT_RAW(Level, Fmt)    \
+{                                   \
+    if (Level <= RTDebugLevel)      \
+    {                               \
+        printk Fmt;               \
+    }                               \
+}
+
+#define DBGPRINT(Level, Fmt)    DBGPRINT_RAW(Level, Fmt)
+
+
+#define DBGPRINT_ERR(Fmt)           \
+{                                   \
+    printk("ERROR!!! ");          \
+    printk Fmt;                  \
+}
+
+#define DBGPRINT_S(Status, Fmt)		\
+{									\
+	printk Fmt;					\
+}
+
+
+#else
+#define DBGPRINT(Level, Fmt)
+#define DBGPRINT_RAW(Level, Fmt)
+#define DBGPRINT_S(Status, Fmt)
+#define DBGPRINT_ERR(Fmt)
+#endif
+
+
+//
+//  spin_lock enhanced for Nested spin lock
+//
+#define NdisAllocateSpinLock(__lock)      \
+{                                       \
+    spin_lock_init((spinlock_t *)(__lock));               \
+}
+
+#define NdisFreeSpinLock(lock)          \
+{                                       \
+}
+
+
+#define RTMP_SEM_LOCK(__lock)					\
+{												\
+	spin_lock_bh((spinlock_t *)(__lock));				\
+}
+
+#define RTMP_SEM_UNLOCK(__lock)					\
+{												\
+	spin_unlock_bh((spinlock_t *)(__lock));				\
+}
+
+// sample, use semaphore lock to replace IRQ lock, 2007/11/15
+#define RTMP_IRQ_LOCK(__lock, __irqflags)			\
+{													\
+	__irqflags = 0;									\
+	spin_lock_bh((spinlock_t *)(__lock));			\
+	pAd->irq_disabled |= 1; \
+}
+
+#define RTMP_IRQ_UNLOCK(__lock, __irqflag)			\
+{													\
+	pAd->irq_disabled &= 0; \
+	spin_unlock_bh((spinlock_t *)(__lock));			\
+}
+
+#define RTMP_INT_LOCK(__lock, __irqflags)			\
+{													\
+	spin_lock_irqsave((spinlock_t *)__lock, __irqflags);	\
+}
+
+#define RTMP_INT_UNLOCK(__lock, __irqflag)			\
+{													\
+	spin_unlock_irqrestore((spinlock_t *)(__lock), ((unsigned long)__irqflag));	\
+}
+
+#ifdef RT2870
+#define RTMP_IO_READ32(_A, _R, _pV)								\
+	RTUSBReadMACRegister(_A, _R, _pV)
+
+#define RTMP_IO_READ8(_A, _R, _pV)								\
+{																\
+}
+
+#define RTMP_IO_WRITE32(_A, _R, _V)								\
+	RTUSBWriteMACRegister(_A, _R, _V)
+
+
+#define RTMP_IO_WRITE8(_A, _R, _V)								\
+{																\
+	USHORT	_Val = _V;											\
+	RTUSBSingleWrite(_A, _R, _Val);								\
+}
+
+
+#define RTMP_IO_WRITE16(_A, _R, _V)								\
+{																\
+	RTUSBSingleWrite(_A, _R, _V);								\
+}
+#endif // RT2870 //
+
+#ifndef wait_event_interruptible_timeout
+#define __wait_event_interruptible_timeout(wq, condition, ret) \
+do { \
+        wait_queue_t __wait; \
+        init_waitqueue_entry(&__wait, current); \
+        add_wait_queue(&wq, &__wait); \
+        for (;;) { \
+                set_current_state(TASK_INTERRUPTIBLE); \
+                if (condition) \
+                        break; \
+                if (!signal_pending(current)) { \
+                        ret = schedule_timeout(ret); \
+                        if (!ret) \
+                                break; \
+                        continue; \
+                } \
+                ret = -ERESTARTSYS; \
+                break; \
+        } \
+        current->state = TASK_RUNNING; \
+        remove_wait_queue(&wq, &__wait); \
+} while (0)
+
+#define wait_event_interruptible_timeout(wq, condition, timeout) \
+({ \
+        long __ret = timeout; \
+        if (!(condition)) \
+                __wait_event_interruptible_timeout(wq, condition, __ret); \
+        __ret; \
+})
+#endif
+#define ONE_TICK 1
+#define OS_WAIT(_time) \
+{	int _i; \
+	long _loop = ((_time)/(1000/OS_HZ)) > 0 ? ((_time)/(1000/OS_HZ)) : 1;\
+	wait_queue_head_t _wait; \
+	init_waitqueue_head(&_wait); \
+	for (_i=0; _i<(_loop); _i++) \
+		wait_event_interruptible_timeout(_wait, 0, ONE_TICK); }
+
+
+/* Modified by Wu Xi-Kun 4/21/2006 */
+typedef void (*TIMER_FUNCTION)(unsigned long);
+
+#define COPY_MAC_ADDR(Addr1, Addr2)             memcpy((Addr1), (Addr2), MAC_ADDR_LEN)
+
+#define MlmeAllocateMemory(_pAd, _ppVA) os_alloc_mem(_pAd, _ppVA, MGMT_DMA_BUFFER_SIZE)
+#define MlmeFreeMemory(_pAd, _pVA)     os_free_mem(_pAd, _pVA)
+
+
+#ifdef RT2870
+#define BUILD_TIMER_FUNCTION(_func)													\
+void linux_##_func(unsigned long data)												\
+{																					\
+	PRALINK_TIMER_STRUCT	_pTimer = (PRALINK_TIMER_STRUCT)data;					\
+	RT2870_TIMER_ENTRY		*_pQNode;												\
+	RTMP_ADAPTER			*_pAd;													\
+																				\
+	_pTimer->handle = _func;															\
+	_pAd = (RTMP_ADAPTER *)_pTimer->pAd;												\
+	_pQNode = RT2870_TimerQ_Insert(_pAd, _pTimer); 									\
+	if ((_pQNode == NULL) && (_pAd->TimerQ.status & RT2870_THREAD_CAN_DO_INSERT))	\
+		RTMP_OS_Add_Timer(&_pTimer->TimerObj, HZ);               					\
+}
+#endif // RT2870 //
+
+
+#define DECLARE_TIMER_FUNCTION(_func)			\
+void linux_##_func(unsigned long data)
+
+#define GET_TIMER_FUNCTION(_func)				\
+		linux_##_func
+
+DECLARE_TIMER_FUNCTION(MlmePeriodicExec);
+DECLARE_TIMER_FUNCTION(MlmeRssiReportExec);
+DECLARE_TIMER_FUNCTION(AsicRxAntEvalTimeout);
+DECLARE_TIMER_FUNCTION(APSDPeriodicExec);
+DECLARE_TIMER_FUNCTION(AsicRfTuningExec);
+#ifdef RT2870
+DECLARE_TIMER_FUNCTION(BeaconUpdateExec);
+#endif // RT2870 //
+
+
+#ifdef CONFIG_STA_SUPPORT
+DECLARE_TIMER_FUNCTION(BeaconTimeout);
+DECLARE_TIMER_FUNCTION(ScanTimeout);
+DECLARE_TIMER_FUNCTION(AuthTimeout);
+DECLARE_TIMER_FUNCTION(AssocTimeout);
+DECLARE_TIMER_FUNCTION(ReassocTimeout);
+DECLARE_TIMER_FUNCTION(DisassocTimeout);
+DECLARE_TIMER_FUNCTION(LinkDownExec);
+#ifdef LEAP_SUPPORT
+DECLARE_TIMER_FUNCTION(LeapAuthTimeout);
+#endif
+DECLARE_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
+DECLARE_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
+DECLARE_TIMER_FUNCTION(PsPollWakeExec);
+DECLARE_TIMER_FUNCTION(RadioOnExec);
+
+#ifdef QOS_DLS_SUPPORT
+DECLARE_TIMER_FUNCTION(DlsTimeoutAction);
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+#undef AP_WSC_INCLUDED
+#undef STA_WSC_INCLUDED
+#undef WSC_INCLUDED
+
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED)
+#define WSC_INCLUDED
+#endif
+
+
+
+void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time);
+
+
+/*
+ * packet helper
+ * 	- convert internal rt packet to os packet or
+ *             os packet to rt packet
+ */
+#define RTPKT_TO_OSPKT(_p)		((struct sk_buff *)(_p))
+#define OSPKT_TO_RTPKT(_p)		((PNDIS_PACKET)(_p))
+
+#define GET_OS_PKT_DATAPTR(_pkt) \
+		(RTPKT_TO_OSPKT(_pkt)->data)
+
+#define GET_OS_PKT_LEN(_pkt) \
+		(RTPKT_TO_OSPKT(_pkt)->len)
+
+#define GET_OS_PKT_DATATAIL(_pkt) \
+		(RTPKT_TO_OSPKT(_pkt)->tail)
+
+#define GET_OS_PKT_HEAD(_pkt) \
+		(RTPKT_TO_OSPKT(_pkt)->head)
+
+#define GET_OS_PKT_END(_pkt) \
+		(RTPKT_TO_OSPKT(_pkt)->end)
+
+#define GET_OS_PKT_NETDEV(_pkt) \
+		(RTPKT_TO_OSPKT(_pkt)->dev)
+
+#define GET_OS_PKT_TYPE(_pkt) \
+		(RTPKT_TO_OSPKT(_pkt))
+
+#define GET_OS_PKT_NEXT(_pkt) \
+		(RTPKT_TO_OSPKT(_pkt)->next)
+
+
+#define OS_NTOHS(_Val) \
+		(ntohs(_Val))
+#define OS_HTONS(_Val) \
+		(htons(_Val))
+#define OS_NTOHL(_Val) \
+		(ntohl(_Val))
+#define OS_HTONL(_Val) \
+		(htonl(_Val))
+
+/* statistics counter */
+#define STATS_INC_RX_PACKETS(_pAd, _dev)
+#define STATS_INC_TX_PACKETS(_pAd, _dev)
+
+#define STATS_INC_RX_BYTESS(_pAd, _dev, len)
+#define STATS_INC_TX_BYTESS(_pAd, _dev, len)
+
+#define STATS_INC_RX_ERRORS(_pAd, _dev)
+#define STATS_INC_TX_ERRORS(_pAd, _dev)
+
+#define STATS_INC_RX_DROPPED(_pAd, _dev)
+#define STATS_INC_TX_DROPPED(_pAd, _dev)
+
+
+#define CB_OFF  10
+
+
+//   check DDK NDIS_PACKET data structure and find out only MiniportReservedEx[0..7] can be used by our driver without
+//   ambiguity. Fields after pPacket->MiniportReservedEx[8] may be used by other wrapper layer thus crashes the driver
+//
+//#define RTMP_GET_PACKET_MR(_p)			(RTPKT_TO_OSPKT(_p))
+
+// User Priority
+#define RTMP_SET_PACKET_UP(_p, _prio)			(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+0] = _prio)
+#define RTMP_GET_PACKET_UP(_p)					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+0])
+
+// Fragment #
+#define RTMP_SET_PACKET_FRAGMENTS(_p, _num)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+1] = _num)
+#define RTMP_GET_PACKET_FRAGMENTS(_p)			(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+1])
+
+// 0x0 ~0x7f: TX to AP's own BSS which has the specified AID. if AID>127, set bit 7 in RTMP_SET_PACKET_EMACTAB too.
+//(this value also as MAC(on-chip WCID) table index)
+// 0x80~0xff: TX to a WDS link. b0~6: WDS index
+#define RTMP_SET_PACKET_WCID(_p, _wdsidx)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+2] = _wdsidx)
+#define RTMP_GET_PACKET_WCID(_p)          		((UCHAR)(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+2]))
+
+// 0xff: PKTSRC_NDIS, others: local TX buffer index. This value affects how to a packet
+#define RTMP_SET_PACKET_SOURCE(_p, _pktsrc)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+3] = _pktsrc)
+#define RTMP_GET_PACKET_SOURCE(_p)       		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+3])
+
+// RTS/CTS-to-self protection method
+#define RTMP_SET_PACKET_RTS(_p, _num)      		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+4] = _num)
+#define RTMP_GET_PACKET_RTS(_p)          		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+4])
+// see RTMP_S(G)ET_PACKET_EMACTAB
+
+// TX rate index
+#define RTMP_SET_PACKET_TXRATE(_p, _rate)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+5] = _rate)
+#define RTMP_GET_PACKET_TXRATE(_p)		  		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+5])
+
+// From which Interface
+#define RTMP_SET_PACKET_IF(_p, _ifdx)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+6] = _ifdx)
+#define RTMP_GET_PACKET_IF(_p)		  		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+6])
+#define RTMP_SET_PACKET_NET_DEVICE_MBSSID(_p, _bss)		RTMP_SET_PACKET_IF((_p), (_bss))
+#define RTMP_SET_PACKET_NET_DEVICE_WDS(_p, _bss)		RTMP_SET_PACKET_IF((_p), ((_bss) + MIN_NET_DEVICE_FOR_WDS))
+#define RTMP_SET_PACKET_NET_DEVICE_APCLI(_p, _idx)   	RTMP_SET_PACKET_IF((_p), ((_idx) + MIN_NET_DEVICE_FOR_APCLI))
+#define RTMP_SET_PACKET_NET_DEVICE_MESH(_p, _idx)   	RTMP_SET_PACKET_IF((_p), ((_idx) + MIN_NET_DEVICE_FOR_MESH))
+#define RTMP_GET_PACKET_NET_DEVICE_MBSSID(_p)			RTMP_GET_PACKET_IF((_p))
+#define RTMP_GET_PACKET_NET_DEVICE(_p)					RTMP_GET_PACKET_IF((_p))
+
+#define RTMP_SET_PACKET_MOREDATA(_p, _morebit)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+7] = _morebit)
+#define RTMP_GET_PACKET_MOREDATA(_p)				(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+7])
+
+//#define RTMP_SET_PACKET_NET_DEVICE_MBSSID(_p, _bss)	(RTPKT_TO_OSPKT(_p)->cb[8] = _bss)
+//#define RTMP_GET_PACKET_NET_DEVICE_MBSSID(_p)		(RTPKT_TO_OSPKT(_p)->cb[8])
+
+//
+//	Sepcific Pakcet Type definition
+//
+#define RTMP_PACKET_SPECIFIC_CB_OFFSET	11
+
+#define RTMP_PACKET_SPECIFIC_DHCP		0x01
+#define RTMP_PACKET_SPECIFIC_EAPOL		0x02
+#define RTMP_PACKET_SPECIFIC_IPV4		0x04
+#define RTMP_PACKET_SPECIFIC_WAI		0x08
+#define RTMP_PACKET_SPECIFIC_VLAN		0x10
+#define RTMP_PACKET_SPECIFIC_LLCSNAP	0x20
+
+//Specific
+#define RTMP_SET_PACKET_SPECIFIC(_p, _flg)	   	(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] = _flg)
+
+//DHCP
+#define RTMP_SET_PACKET_DHCP(_p, _flg)   													\
+			do{																				\
+				if (_flg)																	\
+					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_DHCP);		\
+				else																		\
+					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_DHCP);	\
+			}while(0)
+#define RTMP_GET_PACKET_DHCP(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_DHCP)
+
+//EAPOL
+#define RTMP_SET_PACKET_EAPOL(_p, _flg)   													\
+			do{																				\
+				if (_flg)																	\
+					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_EAPOL);		\
+				else																		\
+					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_EAPOL);	\
+			}while(0)
+#define RTMP_GET_PACKET_EAPOL(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_EAPOL)
+
+//WAI
+#define RTMP_SET_PACKET_WAI(_p, _flg)   													\
+			do{																				\
+				if (_flg)																	\
+					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_WAI);		\
+				else																		\
+					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_WAI);	\
+			}while(0)
+#define RTMP_GET_PACKET_WAI(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_WAI)
+
+#define RTMP_GET_PACKET_LOWRATE(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & (RTMP_PACKET_SPECIFIC_EAPOL | RTMP_PACKET_SPECIFIC_DHCP | RTMP_PACKET_SPECIFIC_WAI))
+
+//VLAN
+#define RTMP_SET_PACKET_VLAN(_p, _flg)   													\
+			do{																				\
+				if (_flg)																	\
+					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_VLAN);		\
+				else																		\
+					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_VLAN);	\
+			}while(0)
+#define RTMP_GET_PACKET_VLAN(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_VLAN)
+
+//LLC/SNAP
+#define RTMP_SET_PACKET_LLCSNAP(_p, _flg)   													\
+			do{																				\
+				if (_flg)																	\
+					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_LLCSNAP);		\
+				else																		\
+					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_LLCSNAP);		\
+			}while(0)
+
+#define RTMP_GET_PACKET_LLCSNAP(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_LLCSNAP)
+
+// IP
+#define RTMP_SET_PACKET_IPV4(_p, _flg)														\
+			do{																				\
+				if (_flg)																	\
+					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_IPV4);		\
+				else																		\
+					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_IPV4);	\
+			}while(0)
+
+#define RTMP_GET_PACKET_IPV4(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_IPV4)
+
+// If this flag is set, it indicates that this EAPoL frame MUST be clear.
+#define RTMP_SET_PACKET_CLEAR_EAP_FRAME(_p, _flg)   (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+12] = _flg)
+#define RTMP_GET_PACKET_CLEAR_EAP_FRAME(_p)         (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+12])
+
+#define RTMP_SET_PACKET_5VT(_p, _flg)   (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22] = _flg)
+#define RTMP_GET_PACKET_5VT(_p)         (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22])
+
+
+#ifdef INF_AMAZON_SE
+/*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate */
+#define RTMP_SET_PACKET_NOBULKOUT(_p, _morebit)			(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+23] = _morebit)
+#define RTMP_GET_PACKET_NOBULKOUT(_p)					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+23])
+#endif // INF_AMAZON_SE //
+
+
+
+#ifdef CONFIG_5VT_ENHANCE
+#define BRIDGE_TAG 0x35564252    // depends on 5VT define in br_input.c
+#endif
+
+
+#define NDIS_SET_PACKET_STATUS(_p, _status)
+
+
+#define GET_SG_LIST_FROM_PACKET(_p, _sc)	\
+    rt_get_sg_list_from_packet(_p, _sc)
+
+#define NdisMoveMemory(Destination, Source, Length) memmove(Destination, Source, Length)
+#define NdisZeroMemory(Destination, Length)         memset(Destination, 0, Length)
+#define NdisFillMemory(Destination, Length, Fill)   memset(Destination, Fill, Length)
+#define NdisEqualMemory(Source1, Source2, Length)   (!memcmp(Source1, Source2, Length))
+#define RTMPEqualMemory(Source1, Source2, Length)	(!memcmp(Source1, Source2, Length))
+
+
+#define RTMP_INC_REF(_A)		0
+#define RTMP_DEC_REF(_A)		0
+#define RTMP_GET_REF(_A)		0
+
+
+
+/*
+ * ULONG
+ * RTMP_GetPhysicalAddressLow(
+ *   IN NDIS_PHYSICAL_ADDRESS  PhysicalAddress);
+ */
+#define RTMP_GetPhysicalAddressLow(PhysicalAddress)		(PhysicalAddress)
+
+/*
+ * ULONG
+ * RTMP_GetPhysicalAddressHigh(
+ *   IN NDIS_PHYSICAL_ADDRESS  PhysicalAddress);
+ */
+#define RTMP_GetPhysicalAddressHigh(PhysicalAddress)		(0)
+
+/*
+ * VOID
+ * RTMP_SetPhysicalAddressLow(
+ *   IN NDIS_PHYSICAL_ADDRESS  PhysicalAddress,
+ *   IN ULONG  Value);
+ */
+#define RTMP_SetPhysicalAddressLow(PhysicalAddress, Value)	\
+			PhysicalAddress = Value;
+
+/*
+ * VOID
+ * RTMP_SetPhysicalAddressHigh(
+ *   IN NDIS_PHYSICAL_ADDRESS  PhysicalAddress,
+ *   IN ULONG  Value);
+ */
+#define RTMP_SetPhysicalAddressHigh(PhysicalAddress, Value)
+
+
+//CONTAINING_RECORD(pEntry, NDIS_PACKET, MiniportReservedEx);
+#define QUEUE_ENTRY_TO_PACKET(pEntry) \
+	(PNDIS_PACKET)(pEntry)
+
+#define PACKET_TO_QUEUE_ENTRY(pPacket) \
+	(PQUEUE_ENTRY)(pPacket)
+
+
+#ifndef CONTAINING_RECORD
+#define CONTAINING_RECORD(address, type, field)			\
+((type *)((PCHAR)(address) - offsetof(type, field)))
+#endif
+
+
+#define RELEASE_NDIS_PACKET(_pAd, _pPacket, _Status)                    \
+{                                                                       \
+        RTMPFreeNdisPacket(_pAd, _pPacket);                             \
+}
+
+
+#define SWITCH_PhyAB(_pAA, _pBB)    \
+{                                                                           \
+    ULONG	AABasePaHigh;                           \
+    ULONG	AABasePaLow;                           \
+    ULONG	BBBasePaHigh;                           \
+    ULONG	BBBasePaLow;                           \
+    BBBasePaHigh = RTMP_GetPhysicalAddressHigh(_pBB);                                                 \
+    BBBasePaLow = RTMP_GetPhysicalAddressLow(_pBB);                                                 \
+    AABasePaHigh = RTMP_GetPhysicalAddressHigh(_pAA);                                                 \
+    AABasePaLow = RTMP_GetPhysicalAddressLow(_pAA);                                                 \
+    RTMP_SetPhysicalAddressHigh(_pAA, BBBasePaHigh);                                                 \
+    RTMP_SetPhysicalAddressLow(_pAA, BBBasePaLow);                                                 \
+    RTMP_SetPhysicalAddressHigh(_pBB, AABasePaHigh);                                                 \
+    RTMP_SetPhysicalAddressLow(_pBB, AABasePaLow);                                                 \
+}
+
+
+#define NdisWriteErrorLogEntry(_a, _b, _c, _d)
+#define NdisMAllocateMapRegisters(_a, _b, _c, _d, _e)		NDIS_STATUS_SUCCESS
+
+
+#define NdisAcquireSpinLock		RTMP_SEM_LOCK
+#define NdisReleaseSpinLock		RTMP_SEM_UNLOCK
+
+static inline void NdisGetSystemUpTime(ULONG *time)
+{
+	*time = jiffies;
+}
+
+//pPacket = CONTAINING_RECORD(pEntry, NDIS_PACKET, MiniportReservedEx);
+#define QUEUE_ENTRY_TO_PKT(pEntry) \
+		((PNDIS_PACKET) (pEntry))
+
+int rt28xx_packet_xmit(struct sk_buff *skb);
+
+
+
+void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify);
+
+
+
diff --git a/drivers/staging/rt3070/rt_main_dev.c b/drivers/staging/rt3070/rt_main_dev.c
new file mode 100644
index 0000000..c000646
--- /dev/null
+++ b/drivers/staging/rt3070/rt_main_dev.c
@@ -0,0 +1,1800 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+    rt_main_dev.c
+
+    Abstract:
+    Create and register network interface.
+
+    Revision History:
+    Who         When            What
+    --------    ----------      ----------------------------------------------
+	Sample		Mar/21/07		Merge RT2870 and RT2860 drivers.
+*/
+
+#include "rt_config.h"
+
+#define FORTY_MHZ_INTOLERANT_INTERVAL	(60*1000) // 1 min
+
+#ifdef MULTIPLE_CARD_SUPPORT
+// record whether the card in the card list is used in the card file
+UINT8  MC_CardUsed[MAX_NUM_OF_MULTIPLE_CARD];
+// record used card mac address in the card list
+static UINT8  MC_CardMac[MAX_NUM_OF_MULTIPLE_CARD][6];
+#endif // MULTIPLE_CARD_SUPPORT //
+
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+UINT32 CW_MAX_IN_BITS;
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+
+/*---------------------------------------------------------------------*/
+/* Private Variables Used                                              */
+/*---------------------------------------------------------------------*/
+//static RALINK_TIMER_STRUCT     PeriodicTimer;
+
+char *mac = "";		   // default 00:00:00:00:00:00
+char *hostname = "";		   // default CMPC
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12)
+MODULE_PARM (mac, "s");
+#else
+module_param (mac, charp, 0);
+#endif
+MODULE_PARM_DESC (mac, "rt28xx: wireless mac addr");
+
+
+/*---------------------------------------------------------------------*/
+/* Prototypes of Functions Used                                        */
+/*---------------------------------------------------------------------*/
+#ifdef DOT11_N_SUPPORT
+extern BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num);
+extern void ba_reordering_resource_release(PRTMP_ADAPTER pAd);
+#endif // DOT11_N_SUPPORT //
+extern NDIS_STATUS NICLoadRateSwitchingParams(IN PRTMP_ADAPTER pAd);
+
+
+// public function prototype
+INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
+							IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
+
+// private function prototype
+static int rt28xx_init(IN struct net_device *net_dev);
+INT rt28xx_send_packets(IN struct sk_buff *skb_p, IN struct net_device *net_dev);
+
+#if LINUX_VERSION_CODE <= 0x20402	// Red Hat 7.1
+struct net_device *alloc_netdev(
+	int sizeof_priv,
+	const char *mask,
+	void (*setup)(struct net_device *));
+#endif // LINUX_VERSION_CODE //
+
+static void CfgInitHook(PRTMP_ADAPTER pAd);
+//static BOOLEAN RT28XXAvailRANameAssign(IN CHAR *name_p);
+
+#ifdef CONFIG_STA_SUPPORT
+extern	const struct iw_handler_def rt28xx_iw_handler_def;
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+extern	const struct iw_handler_def rt28xx_ap_iw_handler_def;
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+
+#if WIRELESS_EXT >= 12
+// This function will be called when query /proc
+struct iw_statistics *rt28xx_get_wireless_stats(
+    IN struct net_device *net_dev);
+#endif
+
+struct net_device_stats *RT28xx_get_ether_stats(
+    IN  struct net_device *net_dev);
+
+/*
+========================================================================
+Routine Description:
+    Close raxx interface.
+
+Arguments:
+	*net_dev			the raxx interface pointer
+
+Return Value:
+    0					Open OK
+	otherwise			Open Fail
+
+Note:
+	1. if open fail, kernel will not call the close function.
+	2. Free memory for
+		(1) Mlme Memory Handler:		MlmeHalt()
+		(2) TX & RX:					RTMPFreeTxRxRingMemory()
+		(3) BA Reordering: 				ba_reordering_resource_release()
+========================================================================
+*/
+int MainVirtualIF_close(IN struct net_device *net_dev)
+{
+    RTMP_ADAPTER *pAd = net_dev->ml_priv;
+
+	// Sanity check for pAd
+	if (pAd == NULL)
+		return 0; // close ok
+
+	netif_carrier_off(pAd->net_dev);
+	netif_stop_queue(pAd->net_dev);
+
+
+
+	VIRTUAL_IF_DOWN(pAd);
+
+	RT_MOD_DEC_USE_COUNT();
+
+	return 0; // close ok
+}
+
+/*
+========================================================================
+Routine Description:
+    Open raxx interface.
+
+Arguments:
+	*net_dev			the raxx interface pointer
+
+Return Value:
+    0					Open OK
+	otherwise			Open Fail
+
+Note:
+	1. if open fail, kernel will not call the close function.
+	2. Free memory for
+		(1) Mlme Memory Handler:		MlmeHalt()
+		(2) TX & RX:					RTMPFreeTxRxRingMemory()
+		(3) BA Reordering: 				ba_reordering_resource_release()
+========================================================================
+*/
+int MainVirtualIF_open(IN struct net_device *net_dev)
+{
+    RTMP_ADAPTER *pAd = net_dev->ml_priv;
+
+	// Sanity check for pAd
+	if (pAd == NULL)
+		return 0; // close ok
+
+	if (VIRTUAL_IF_UP(pAd) != 0)
+		return -1;
+
+	// increase MODULE use count
+	RT_MOD_INC_USE_COUNT();
+
+	netif_start_queue(net_dev);
+	netif_carrier_on(net_dev);
+	netif_wake_queue(net_dev);
+
+	return 0;
+}
+
+/*
+========================================================================
+Routine Description:
+    Close raxx interface.
+
+Arguments:
+	*net_dev			the raxx interface pointer
+
+Return Value:
+    0					Open OK
+	otherwise			Open Fail
+
+Note:
+	1. if open fail, kernel will not call the close function.
+	2. Free memory for
+		(1) Mlme Memory Handler:		MlmeHalt()
+		(2) TX & RX:					RTMPFreeTxRxRingMemory()
+		(3) BA Reordering: 				ba_reordering_resource_release()
+========================================================================
+*/
+int rt28xx_close(IN PNET_DEV dev)
+{
+	struct net_device * net_dev = (struct net_device *)dev;
+    RTMP_ADAPTER	*pAd = net_dev->ml_priv;
+	BOOLEAN 		Cancelled = FALSE;
+	UINT32			i = 0;
+#ifdef RT2870
+	DECLARE_WAIT_QUEUE_HEAD(unlink_wakeup);
+	DECLARE_WAITQUEUE(wait, current);
+
+	//RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
+#endif // RT2870 //
+
+
+    DBGPRINT(RT_DEBUG_TRACE, ("===> rt28xx_close\n"));
+
+	// Sanity check for pAd
+	if (pAd == NULL)
+		return 0; // close ok
+
+
+#ifdef WDS_SUPPORT
+	WdsDown(pAd);
+#endif // WDS_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+
+		// If dirver doesn't wake up firmware here,
+		// NICLoadFirmware will hang forever when interface is up again.
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+        {
+		    AsicForceWakeup(pAd, TRUE);
+        }
+
+#ifdef QOS_DLS_SUPPORT
+		// send DLS-TEAR_DOWN message,
+		if (pAd->CommonCfg.bDLSCapable)
+		{
+			UCHAR i;
+
+			// tear down local dls table entry
+			for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+			{
+				if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
+				{
+					RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
+					pAd->StaCfg.DLSEntry[i].Status	= DLS_NONE;
+					pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
+				}
+			}
+
+			// tear down peer dls table entry
+			for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+			{
+				if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
+				{
+					RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
+					pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+					pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
+				}
+			}
+			RT28XX_MLME_HANDLER(pAd);
+		}
+#endif // QOS_DLS_SUPPORT //
+
+		if (INFRA_ON(pAd) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+		{
+			MLME_DISASSOC_REQ_STRUCT	DisReq;
+			MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
+
+			COPY_MAC_ADDR(DisReq.Addr, pAd->CommonCfg.Bssid);
+			DisReq.Reason =  REASON_DEAUTH_STA_LEAVING;
+
+			MsgElem->Machine = ASSOC_STATE_MACHINE;
+			MsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
+			MsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
+			NdisMoveMemory(MsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
+
+			// Prevent to connect AP again in STAMlmePeriodicExec
+			pAd->MlmeAux.AutoReconnectSsidLen= 32;
+			NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
+
+			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
+			MlmeDisassocReqAction(pAd, MsgElem);
+			kfree(MsgElem);
+
+			RTMPusecDelay(1000);
+		}
+
+#ifdef RT2870
+	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
+#endif // RT2870 //
+
+#ifdef CCX_SUPPORT
+		RTMPCancelTimer(&pAd->StaCfg.LeapAuthTimer, &Cancelled);
+#endif
+
+		RTMPCancelTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, &Cancelled);
+		RTMPCancelTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, &Cancelled);
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+		{
+			union iwreq_data    wrqu;
+			// send wireless event to wpa_supplicant for infroming interface down.
+			memset(&wrqu, 0, sizeof(wrqu));
+			wrqu.data.flags = RT_INTERFACE_DOWN;
+			wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+		}
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+		MlmeRadioOff(pAd);
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+
+	for (i = 0 ; i < NUM_OF_TX_RING; i++)
+	{
+		while (pAd->DeQueueRunning[i] == TRUE)
+		{
+			printk("Waiting for TxQueue[%d] done..........\n", i);
+			RTMPusecDelay(1000);
+		}
+	}
+
+#ifdef RT2870
+	// ensure there are no more active urbs.
+	add_wait_queue (&unlink_wakeup, &wait);
+	pAd->wait = &unlink_wakeup;
+
+	// maybe wait for deletions to finish.
+	i = 0;
+	//while((i < 25) && atomic_read(&pAd->PendingRx) > 0)
+	while(i < 25)
+	{
+		unsigned long IrqFlags;
+
+		RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
+		if (pAd->PendingRx == 0)
+		{
+			RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+			break;
+		}
+		RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9)
+		msleep(UNLINK_TIMEOUT_MS);	//Time in millisecond
+#else
+		RTMPusecDelay(UNLINK_TIMEOUT_MS*1000);	//Time in microsecond
+#endif
+		i++;
+	}
+	pAd->wait = NULL;
+	remove_wait_queue (&unlink_wakeup, &wait);
+#endif // RT2870 //
+
+	//RTUSBCleanUpMLMEWaitQueue(pAd);	/*not used in RT28xx*/
+
+
+#ifdef RT2870
+	// We need clear timerQ related structure before exits of the timer thread.
+	RT2870_TimerQ_Exit(pAd);
+	// Close kernel threads or tasklets
+	RT28xxThreadTerminate(pAd);
+#endif // RT2870 //
+
+	// Stop Mlme state machine
+	MlmeHalt(pAd);
+
+	// Close kernel threads or tasklets
+	kill_thread_task(pAd);
+
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		MacTableReset(pAd);
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+
+	MeasureReqTabExit(pAd);
+	TpcReqTabExit(pAd);
+
+
+
+
+	// Free Ring or USB buffers
+	RTMPFreeTxRxRingMemory(pAd);
+
+	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+
+#ifdef DOT11_N_SUPPORT
+	// Free BA reorder resource
+	ba_reordering_resource_release(pAd);
+#endif // DOT11_N_SUPPORT //
+
+#ifdef RT2870
+#ifdef INF_AMAZON_SE
+	if (pAd->UsbVendorReqBuf)
+		os_free_mem(pAd, pAd->UsbVendorReqBuf);
+#endif // INF_AMAZON_SE //
+#endif // RT2870 //
+
+	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP);
+
+	return 0; // close ok
+} /* End of rt28xx_close */
+
+static int rt28xx_init(IN struct net_device *net_dev)
+{
+	PRTMP_ADAPTER 			pAd = net_dev->ml_priv;
+	UINT					index;
+	UCHAR					TmpPhy;
+//	ULONG					Value=0;
+	NDIS_STATUS				Status;
+//    OID_SET_HT_PHYMODE		SetHT;
+//	WPDMA_GLO_CFG_STRUC     GloCfg;
+	UINT32 		MacCsr0 = 0;
+	UINT32		MacValue = 0;
+
+#ifdef RT2870
+#ifdef INF_AMAZON_SE
+	init_MUTEX(&(pAd->UsbVendorReq_semaphore));
+	os_alloc_mem(pAd, (PUCHAR)&pAd->UsbVendorReqBuf, MAX_PARAM_BUFFER_SIZE - 1);
+	if (pAd->UsbVendorReqBuf == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("Allocate vendor request temp buffer failed!\n"));
+		goto err0;
+	}
+#endif // INF_AMAZON_SE //
+#endif // RT2870 //
+
+#ifdef DOT11_N_SUPPORT
+	// Allocate BA Reordering memory
+	ba_reordering_resource_init(pAd, MAX_REORDERING_MPDU_NUM);
+#endif // DOT11_N_SUPPORT //
+
+	// Make sure MAC gets ready.
+	index = 0;
+	do
+	{
+		RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
+		pAd->MACVersion = MacCsr0;
+
+		if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF))
+			break;
+
+		RTMPusecDelay(10);
+	} while (index++ < 100);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0  [ Ver:Rev=0x%08x]\n", pAd->MACVersion));
+/*Iverson patch PCIE L1 issue */
+
+	// Disable DMA
+	RT28XXDMADisable(pAd);
+
+
+	// Load 8051 firmware
+	Status = NICLoadFirmware(pAd);
+	if (Status != NDIS_STATUS_SUCCESS)
+	{
+		DBGPRINT_ERR(("NICLoadFirmware failed, Status[=0x%08x]\n", Status));
+		goto err1;
+	}
+
+	NICLoadRateSwitchingParams(pAd);
+
+	// Disable interrupts here which is as soon as possible
+	// This statement should never be true. We might consider to remove it later
+
+	Status = RTMPAllocTxRxRingMemory(pAd);
+	if (Status != NDIS_STATUS_SUCCESS)
+	{
+		DBGPRINT_ERR(("RTMPAllocDMAMemory failed, Status[=0x%08x]\n", Status));
+		goto err1;
+	}
+
+	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
+
+	// initialize MLME
+	//
+
+	Status = MlmeInit(pAd);
+	if (Status != NDIS_STATUS_SUCCESS)
+	{
+		DBGPRINT_ERR(("MlmeInit failed, Status[=0x%08x]\n", Status));
+		goto err2;
+	}
+
+	// Initialize pAd->StaCfg, pAd->ApCfg, pAd->CommonCfg to manufacture default
+	//
+	UserCfgInit(pAd);
+
+#ifdef RT2870
+	// We need init timerQ related structure before create the timer thread.
+	RT2870_TimerQ_Init(pAd);
+#endif // RT2870 //
+
+	RT28XX_TASK_THREAD_INIT(pAd, Status);
+	if (Status != NDIS_STATUS_SUCCESS)
+		goto err1;
+
+//	COPY_MAC_ADDR(pAd->ApCfg.MBSSID[apidx].Bssid, netif->hwaddr);
+//	pAd->bForcePrintTX = TRUE;
+
+	CfgInitHook(pAd);
+
+
+#ifdef BLOCK_NET_IF
+	initblockQueueTab(pAd);
+#endif // BLOCK_NET_IF //
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		NdisAllocateSpinLock(&pAd->MacTabLock);
+#endif // CONFIG_STA_SUPPORT //
+
+	MeasureReqTabInit(pAd);
+	TpcReqTabInit(pAd);
+
+	//
+	// Init the hardware, we need to init asic before read registry, otherwise mac register will be reset
+	//
+	Status = NICInitializeAdapter(pAd, TRUE);
+	if (Status != NDIS_STATUS_SUCCESS)
+	{
+		DBGPRINT_ERR(("NICInitializeAdapter failed, Status[=0x%08x]\n", Status));
+		if (Status != NDIS_STATUS_SUCCESS)
+		goto err3;
+	}
+
+	// Read parameters from Config File
+	Status = RTMPReadParametersHook(pAd);
+
+	printk("1. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
+	if (Status != NDIS_STATUS_SUCCESS)
+	{
+		DBGPRINT_ERR(("NICReadRegParameters failed, Status[=0x%08x]\n",Status));
+		goto err4;
+	}
+
+#ifdef RT2870
+	pAd->CommonCfg.bMultipleIRP = FALSE;
+
+	if (pAd->CommonCfg.bMultipleIRP)
+		pAd->CommonCfg.NumOfBulkInIRP = RX_RING_SIZE;
+	else
+		pAd->CommonCfg.NumOfBulkInIRP = 1;
+#endif // RT2870 //
+
+
+   	//Init Ba Capability parameters.
+//	RT28XX_BA_INIT(pAd);
+#ifdef DOT11_N_SUPPORT
+	pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
+	pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable;
+	pAd->CommonCfg.DesiredHtPhy.AmsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
+	pAd->CommonCfg.DesiredHtPhy.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
+	// UPdata to HT IE
+	pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
+	pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
+	pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
+#endif // DOT11_N_SUPPORT //
+
+	// after reading Registry, we now know if in AP mode or STA mode
+
+	// Load 8051 firmware; crash when FW image not existent
+	// Status = NICLoadFirmware(pAd);
+	// if (Status != NDIS_STATUS_SUCCESS)
+	//    break;
+
+	printk("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
+
+	// We should read EEPROM for all cases.  rt2860b
+	NICReadEEPROMParameters(pAd, mac);
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+	printk("3. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
+
+	NICInitAsicFromEEPROM(pAd); //rt2860b
+
+	// Set PHY to appropriate mode
+	TmpPhy = pAd->CommonCfg.PhyMode;
+	pAd->CommonCfg.PhyMode = 0xff;
+	RTMPSetPhyMode(pAd, TmpPhy);
+#ifdef DOT11_N_SUPPORT
+	SetCommonHT(pAd);
+#endif // DOT11_N_SUPPORT //
+
+	// No valid channels.
+	if (pAd->ChannelListNum == 0)
+	{
+		printk("Wrong configuration. No valid channel found. Check \"ContryCode\" and \"ChannelGeography\" setting.\n");
+		goto err4;
+	}
+
+#ifdef DOT11_N_SUPPORT
+	printk("MCS Set = %02x %02x %02x %02x %02x\n", pAd->CommonCfg.HtCapability.MCSSet[0],
+           pAd->CommonCfg.HtCapability.MCSSet[1], pAd->CommonCfg.HtCapability.MCSSet[2],
+           pAd->CommonCfg.HtCapability.MCSSet[3], pAd->CommonCfg.HtCapability.MCSSet[4]);
+#endif // DOT11_N_SUPPORT //
+
+#ifdef RT30xx
+    //Init RT30xx RFRegisters after read RFIC type from EEPROM
+	NICInitRT30xxRFRegisters(pAd);
+#endif // RT30xx //
+
+//		APInitialize(pAd);
+
+#ifdef IKANOS_VX_1X0
+	VR_IKANOS_FP_Init(pAd->ApCfg.BssidNum, pAd->PermanentAddress);
+#endif // IKANOS_VX_1X0 //
+
+		//
+	// Initialize RF register to default value
+	//
+	AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+	AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+
+	if (pAd && (Status != NDIS_STATUS_SUCCESS))
+	{
+		//
+		// Undo everything if it failed
+		//
+		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+		{
+//			NdisMDeregisterInterrupt(&pAd->Interrupt);
+			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
+		}
+//		RTMPFreeAdapter(pAd); // we will free it in disconnect()
+	}
+	else if (pAd)
+	{
+		// Microsoft HCT require driver send a disconnect event after driver initialization.
+		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
+//		pAd->IndicateMediaState = NdisMediaStateDisconnected;
+		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
+
+		DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event B!\n"));
+
+
+#ifdef RT2870
+		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);
+		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
+
+		//
+		// Support multiple BulkIn IRP,
+		// the value on pAd->CommonCfg.NumOfBulkInIRP may be large than 1.
+		//
+		for(index=0; index<pAd->CommonCfg.NumOfBulkInIRP; index++)
+		{
+			RTUSBBulkReceive(pAd);
+			DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkReceive!\n" ));
+		}
+#endif // RT2870 //
+	}// end of else
+
+
+	DBGPRINT_S(Status, ("<==== RTMPInitialize, Status=%x\n", Status));
+
+	return TRUE;
+
+
+err4:
+err3:
+	MlmeHalt(pAd);
+err2:
+	RTMPFreeTxRxRingMemory(pAd);
+//	RTMPFreeAdapter(pAd);
+err1:
+
+#ifdef DOT11_N_SUPPORT
+	os_free_mem(pAd, pAd->mpdu_blk_pool.mem); // free BA pool
+#endif // DOT11_N_SUPPORT //
+	RT28XX_IRQ_RELEASE(net_dev);
+
+	// shall not set priv to NULL here because the priv didn't been free yet.
+	//net_dev->ml_priv = 0;
+#ifdef INF_AMAZON_SE
+err0:
+#endif // INF_AMAZON_SE //
+	printk("!!! %s Initialized fail !!!\n", RT28xx_CHIP_NAME);
+	return FALSE;
+} /* End of rt28xx_init */
+
+
+/*
+========================================================================
+Routine Description:
+    Open raxx interface.
+
+Arguments:
+	*net_dev			the raxx interface pointer
+
+Return Value:
+    0					Open OK
+	otherwise			Open Fail
+
+Note:
+========================================================================
+*/
+int rt28xx_open(IN PNET_DEV dev)
+{
+	struct net_device * net_dev = (struct net_device *)dev;
+	PRTMP_ADAPTER pAd = net_dev->ml_priv;
+	int retval = 0;
+ 	POS_COOKIE pObj;
+
+
+	// Sanity check for pAd
+	if (pAd == NULL)
+	{
+		/* if 1st open fail, pAd will be free;
+		   So the net_dev->ml_priv will be NULL in 2rd open */
+		return -1;
+	}
+
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+	if (pAd->OpMode == OPMODE_AP)
+	{
+		CW_MAX_IN_BITS = 6;
+	}
+	else if (pAd->OpMode == OPMODE_STA)
+	{
+		CW_MAX_IN_BITS = 10;
+	}
+
+#if WIRELESS_EXT >= 12
+	if (net_dev->ml_priv_flags == INT_MAIN)
+	{
+		if (pAd->OpMode == OPMODE_AP)
+			net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_ap_iw_handler_def;
+		else if (pAd->OpMode == OPMODE_STA)
+			net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_iw_handler_def;
+	}
+#endif // WIRELESS_EXT >= 12 //
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+	// Init
+ 	pObj = (POS_COOKIE)pAd->OS_Cookie;
+
+	// reset Adapter flags
+	RTMP_CLEAR_FLAGS(pAd);
+
+	// Request interrupt service routine for PCI device
+	// register the interrupt routine with the os
+	RT28XX_IRQ_REQUEST(net_dev);
+
+
+	// Init BssTab & ChannelInfo tabbles for auto channel select.
+
+
+	// Chip & other init
+	if (rt28xx_init(net_dev) == FALSE)
+		goto err;
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		NdisZeroMemory(pAd->StaCfg.dev_name, 16);
+		NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name, strlen(net_dev->name));
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	// Set up the Mac address
+	NdisMoveMemory(net_dev->dev_addr, (void *) pAd->CurrentAddress, 6);
+
+	// Init IRQ parameters
+	RT28XX_IRQ_INIT(pAd);
+
+	// Various AP function init
+
+
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+		{
+			union iwreq_data    wrqu;
+			// send wireless event to wpa_supplicant for infroming interface down.
+			memset(&wrqu, 0, sizeof(wrqu));
+			wrqu.data.flags = RT_INTERFACE_UP;
+			wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+		}
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	// Enable Interrupt
+	RT28XX_IRQ_ENABLE(pAd);
+
+	// Now Enable RxTx
+	RTMPEnableRxTx(pAd);
+	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP);
+
+	{
+	UINT32 reg = 0;
+	RTMP_IO_READ32(pAd, 0x1300, &reg);  // clear garbage interrupts
+	printk("0x1300 = %08x\n", reg);
+	}
+
+	{
+//	u32 reg;
+//	u8  byte;
+//	u16 tmp;
+
+//	RTMP_IO_READ32(pAd, XIFS_TIME_CFG, &reg);
+
+//	tmp = 0x0805;
+//	reg  = (reg & 0xffff0000) | tmp;
+//	RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, reg);
+
+	}
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+	return (retval);
+
+err:
+	return (-1);
+} /* End of rt28xx_open */
+
+
+/* Must not be called for mdev and apdev */
+static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER pAd)
+{
+	NDIS_STATUS Status;
+	INT     i=0;
+	CHAR    slot_name[IFNAMSIZ];
+	struct net_device   *device;
+
+
+	//ether_setup(dev);
+	dev->hard_start_xmit = rt28xx_send_packets;
+
+#ifdef IKANOS_VX_1X0
+	dev->hard_start_xmit = IKANOS_DataFramesTx;
+#endif // IKANOS_VX_1X0 //
+
+//	dev->set_multicast_list = ieee80211_set_multicast_list;
+//	dev->change_mtu = ieee80211_change_mtu;
+#ifdef CONFIG_STA_SUPPORT
+#if WIRELESS_EXT >= 12
+	if (pAd->OpMode == OPMODE_STA)
+	{
+		dev->wireless_handlers = &rt28xx_iw_handler_def;
+	}
+#endif //WIRELESS_EXT >= 12
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+#if WIRELESS_EXT >= 12
+	if (pAd->OpMode == OPMODE_AP)
+	{
+		dev->wireless_handlers = &rt28xx_ap_iw_handler_def;
+	}
+#endif //WIRELESS_EXT >= 12
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+
+#if WIRELESS_EXT < 21
+		dev->get_wireless_stats = rt28xx_get_wireless_stats;
+#endif
+	dev->get_stats = RT28xx_get_ether_stats;
+	dev->open = MainVirtualIF_open; //rt28xx_open;
+	dev->stop = MainVirtualIF_close; //rt28xx_close;
+//	dev->uninit = ieee80211_if_reinit;
+//	dev->destructor = ieee80211_if_free;
+	dev->priv_flags = INT_MAIN;
+	dev->do_ioctl = rt28xx_ioctl;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+    dev->validate_addr = NULL;
+#endif
+	// find available device name
+	for (i = 0; i < 8; i++)
+	{
+#ifdef MULTIPLE_CARD_SUPPORT
+		if (pAd->MC_RowID >= 0)
+			sprintf(slot_name, "ra%02d_%d", pAd->MC_RowID, i);
+		else
+#endif // MULTIPLE_CARD_SUPPORT //
+		sprintf(slot_name, "ra%d", i);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+        device = dev_get_by_name(dev_net(dev), slot_name);
+#else
+        device = dev_get_by_name(dev->nd_net, slot_name);
+#endif
+#else
+		device = dev_get_by_name(slot_name);
+#endif
+		if (device != NULL) dev_put(device);
+#else
+		for (device = dev_base; device != NULL; device = device->next)
+		{
+			if (strncmp(device->name, slot_name, 4) == 0)
+				break;
+		}
+#endif
+		if(device == NULL)
+			break;
+	}
+
+	if(i == 8)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("No available slot name\n"));
+		Status = NDIS_STATUS_FAILURE;
+	}
+	else
+	{
+#ifdef MULTIPLE_CARD_SUPPORT
+		if (pAd->MC_RowID >= 0)
+	        sprintf(dev->name, "ra%02d_%d", pAd->MC_RowID, i);
+		else
+#endif // MULTIPLE_CARD_SUPPORT //
+		sprintf(dev->name, "ra%d", i);
+		Status = NDIS_STATUS_SUCCESS;
+	}
+
+	return Status;
+
+}
+
+
+#ifdef MULTIPLE_CARD_SUPPORT
+/*
+========================================================================
+Routine Description:
+    Get card profile path.
+
+Arguments:
+    pAd
+
+Return Value:
+    TRUE		- Find a card profile
+	FALSE		- use default profile
+
+Note:
+========================================================================
+*/
+extern INT RTMPGetKeyParameter(
+    IN  PCHAR   key,
+    OUT PCHAR   dest,
+    IN  INT     destsize,
+    IN  PCHAR   buffer);
+
+BOOLEAN RTMP_CardInfoRead(
+	IN	PRTMP_ADAPTER pAd)
+{
+#define MC_SELECT_CARDID		0	/* use CARD ID (0 ~ 31) to identify different cards */
+#define MC_SELECT_MAC			1	/* use CARD MAC to identify different cards */
+#define MC_SELECT_CARDTYPE		2	/* use CARD type (abgn or bgn) to identify different cards */
+
+#define LETTER_CASE_TRANSLATE(txt_p, card_id)			\
+	{	UINT32 _len; char _char;						\
+		for(_len=0; _len<strlen(card_id); _len++) {		\
+			_char = *(txt_p + _len);					\
+			if (('A' <= _char) && (_char <= 'Z'))		\
+				*(txt_p+_len) = 'a'+(_char-'A');		\
+		} }
+
+	struct file *srcf;
+	INT retval, orgfsuid, orgfsgid;
+   	mm_segment_t orgfs;
+	CHAR *buffer, *tmpbuf, card_id_buf[30], RFIC_word[30];
+	BOOLEAN flg_match_ok = FALSE;
+	INT32 card_select_method;
+	INT32 card_free_id, card_nouse_id, card_same_mac_id, card_match_id;
+	EEPROM_ANTENNA_STRUC antenna;
+	USHORT addr01, addr23, addr45;
+	UINT8 mac[6];
+	UINT32 data, card_index;
+	UCHAR *start_ptr;
+
+
+	// init
+	buffer = kmalloc(MAX_INI_BUFFER_SIZE, MEM_ALLOC_FLAG);
+	if (buffer == NULL)
+        return FALSE;
+
+	tmpbuf = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
+	if(tmpbuf == NULL)
+	{
+		kfree(buffer);
+        return NDIS_STATUS_FAILURE;
+	}
+
+	orgfsuid = current->fsuid;
+	orgfsgid = current->fsgid;
+	current->fsuid = current->fsgid = 0;
+    orgfs = get_fs();
+    set_fs(KERNEL_DS);
+
+	// get RF IC type
+	RTMP_IO_READ32(pAd, E2PROM_CSR, &data);
+
+	if ((data & 0x30) == 0)
+		pAd->EEPROMAddressNum = 6;	// 93C46
+	else if ((data & 0x30) == 0x10)
+		pAd->EEPROMAddressNum = 8;	// 93C66
+	else
+		pAd->EEPROMAddressNum = 8;	// 93C86
+
+	//antenna.word = RTMP_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET);
+	RT28xx_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET, antenna.word);
+
+	if ((antenna.field.RfIcType == RFIC_2850) ||
+		(antenna.field.RfIcType == RFIC_2750))
+	{
+		/* ABGN card */
+		strcpy(RFIC_word, "abgn");
+	}
+	else
+	{
+		/* BGN card */
+		strcpy(RFIC_word, "bgn");
+	}
+
+	// get MAC address
+	//addr01 = RTMP_EEPROM_READ16(pAd, 0x04);
+	//addr23 = RTMP_EEPROM_READ16(pAd, 0x06);
+	//addr45 = RTMP_EEPROM_READ16(pAd, 0x08);
+	RT28xx_EEPROM_READ16(pAd, 0x04, addr01);
+	RT28xx_EEPROM_READ16(pAd, 0x06, addr23);
+	RT28xx_EEPROM_READ16(pAd, 0x08, addr45);
+
+	mac[0] = (UCHAR)(addr01 & 0xff);
+	mac[1] = (UCHAR)(addr01 >> 8);
+	mac[2] = (UCHAR)(addr23 & 0xff);
+	mac[3] = (UCHAR)(addr23 >> 8);
+	mac[4] = (UCHAR)(addr45 & 0xff);
+	mac[5] = (UCHAR)(addr45 >> 8);
+
+	// open card information file
+	srcf = filp_open(CARD_INFO_PATH, O_RDONLY, 0);
+	if (IS_ERR(srcf))
+	{
+		/* card information file does not exist */
+			DBGPRINT(RT_DEBUG_TRACE,
+				("--> Error %ld opening %s\n", -PTR_ERR(srcf), CARD_INFO_PATH));
+		return FALSE;
+	}
+
+	if (srcf->f_op && srcf->f_op->read)
+	{
+		/* card information file exists so reading the card information */
+		memset(buffer, 0x00, MAX_INI_BUFFER_SIZE);
+		retval = srcf->f_op->read(srcf, buffer, MAX_INI_BUFFER_SIZE, &srcf->f_pos);
+		if (retval < 0)
+		{
+			/* read fail */
+				DBGPRINT(RT_DEBUG_TRACE,
+					("--> Read %s error %d\n", CARD_INFO_PATH, -retval));
+		}
+		else
+		{
+			/* get card selection method */
+			memset(tmpbuf, 0x00, MAX_PARAM_BUFFER_SIZE);
+			card_select_method = MC_SELECT_CARDTYPE; // default
+
+			if (RTMPGetKeyParameter("SELECT", tmpbuf, 256, buffer))
+			{
+				if (strcmp(tmpbuf, "CARDID") == 0)
+					card_select_method = MC_SELECT_CARDID;
+				else if (strcmp(tmpbuf, "MAC") == 0)
+					card_select_method = MC_SELECT_MAC;
+				else if (strcmp(tmpbuf, "CARDTYPE") == 0)
+					card_select_method = MC_SELECT_CARDTYPE;
+			}
+
+			DBGPRINT(RT_DEBUG_TRACE,
+					("MC> Card Selection = %d\n", card_select_method));
+
+			// init
+			card_free_id = -1;
+			card_nouse_id = -1;
+			card_same_mac_id = -1;
+			card_match_id = -1;
+
+			// search current card information records
+			for(card_index=0;
+				card_index<MAX_NUM_OF_MULTIPLE_CARD;
+				card_index++)
+			{
+				if ((*(UINT32 *)&MC_CardMac[card_index][0] == 0) &&
+					(*(UINT16 *)&MC_CardMac[card_index][4] == 0))
+				{
+					// MAC is all-0 so the entry is available
+					MC_CardUsed[card_index] = 0;
+
+					if (card_free_id < 0)
+						card_free_id = card_index; // 1st free entry
+				}
+				else
+				{
+					if (memcmp(MC_CardMac[card_index], mac, 6) == 0)
+					{
+						// we find the entry with same MAC
+						if (card_same_mac_id < 0)
+							card_same_mac_id = card_index; // 1st same entry
+					}
+					else
+					{
+						// MAC is not all-0 but used flag == 0
+						if ((MC_CardUsed[card_index] == 0) &&
+							(card_nouse_id < 0))
+						{
+							card_nouse_id = card_index; // 1st available entry
+						}
+					}
+				}
+			}
+
+			DBGPRINT(RT_DEBUG_TRACE,
+					("MC> Free = %d, Same = %d, NOUSE = %d\n",
+					card_free_id, card_same_mac_id, card_nouse_id));
+
+			if ((card_same_mac_id >= 0) &&
+				((card_select_method == MC_SELECT_CARDID) ||
+				(card_select_method == MC_SELECT_CARDTYPE)))
+			{
+				// same MAC entry is found
+				card_match_id = card_same_mac_id;
+
+				if (card_select_method == MC_SELECT_CARDTYPE)
+				{
+					// for CARDTYPE
+					sprintf(card_id_buf, "%02dCARDTYPE%s",
+							card_match_id, RFIC_word);
+
+					if ((start_ptr=rtstrstruncasecmp(buffer, card_id_buf)) != NULL)
+					{
+						// we found the card ID
+						LETTER_CASE_TRANSLATE(start_ptr, card_id_buf);
+					}
+				}
+			}
+			else
+			{
+				// the card is 1st plug-in, try to find the match card profile
+				switch(card_select_method)
+				{
+					case MC_SELECT_CARDID: // CARDID
+					default:
+						if (card_free_id >= 0)
+							card_match_id = card_free_id;
+						else
+							card_match_id = card_nouse_id;
+						break;
+
+					case MC_SELECT_MAC: // MAC
+						sprintf(card_id_buf, "MAC%02x:%02x:%02x:%02x:%02x:%02x",
+								mac[0], mac[1], mac[2],
+								mac[3], mac[4], mac[5]);
+
+						/* try to find the key word in the card file */
+						if ((start_ptr=rtstrstruncasecmp(buffer, card_id_buf)) != NULL)
+						{
+							LETTER_CASE_TRANSLATE(start_ptr, card_id_buf);
+
+							/* get the row ID (2 ASCII characters) */
+							start_ptr -= 2;
+							card_id_buf[0] = *(start_ptr);
+							card_id_buf[1] = *(start_ptr+1);
+							card_id_buf[2] = 0x00;
+
+							card_match_id = simple_strtol(card_id_buf, 0, 10);
+						}
+						break;
+
+					case MC_SELECT_CARDTYPE: // CARDTYPE
+						card_nouse_id = -1;
+
+						for(card_index=0;
+							card_index<MAX_NUM_OF_MULTIPLE_CARD;
+							card_index++)
+						{
+							sprintf(card_id_buf, "%02dCARDTYPE%s",
+									card_index, RFIC_word);
+
+							if ((start_ptr=rtstrstruncasecmp(buffer,
+														card_id_buf)) != NULL)
+							{
+								LETTER_CASE_TRANSLATE(start_ptr, card_id_buf);
+
+								if (MC_CardUsed[card_index] == 0)
+								{
+									/* current the card profile is not used */
+									if ((*(UINT32 *)&MC_CardMac[card_index][0] == 0) &&
+										(*(UINT16 *)&MC_CardMac[card_index][4] == 0))
+									{
+										// find it and no previous card use it
+										card_match_id = card_index;
+										break;
+									}
+									else
+									{
+										// ever a card use it
+										if (card_nouse_id < 0)
+											card_nouse_id = card_index;
+									}
+								}
+							}
+						}
+
+						// if not find a free one, use the available one
+						if (card_match_id < 0)
+							card_match_id = card_nouse_id;
+						break;
+				}
+			}
+
+			if (card_match_id >= 0)
+			{
+				// make up search keyword
+				switch(card_select_method)
+				{
+					case MC_SELECT_CARDID: // CARDID
+						sprintf(card_id_buf, "%02dCARDID", card_match_id);
+						break;
+
+					case MC_SELECT_MAC: // MAC
+						sprintf(card_id_buf,
+								"%02dmac%02x:%02x:%02x:%02x:%02x:%02x",
+								card_match_id,
+								mac[0], mac[1], mac[2],
+								mac[3], mac[4], mac[5]);
+						break;
+
+					case MC_SELECT_CARDTYPE: // CARDTYPE
+					default:
+						sprintf(card_id_buf, "%02dcardtype%s",
+								card_match_id, RFIC_word);
+						break;
+				}
+
+				DBGPRINT(RT_DEBUG_TRACE, ("Search Keyword = %s\n", card_id_buf));
+
+				// read card file path
+				if (RTMPGetKeyParameter(card_id_buf, tmpbuf, 256, buffer))
+				{
+					if (strlen(tmpbuf) < sizeof(pAd->MC_FileName))
+					{
+						// backup card information
+						pAd->MC_RowID = card_match_id; /* base 0 */
+						MC_CardUsed[card_match_id] = 1;
+						memcpy(MC_CardMac[card_match_id], mac, sizeof(mac));
+
+						// backup card file path
+						NdisMoveMemory(pAd->MC_FileName, tmpbuf , strlen(tmpbuf));
+						pAd->MC_FileName[strlen(tmpbuf)] = '\0';
+						flg_match_ok = TRUE;
+
+						DBGPRINT(RT_DEBUG_TRACE,
+								("Card Profile Name = %s\n", pAd->MC_FileName));
+					}
+					else
+					{
+						DBGPRINT(RT_DEBUG_ERROR,
+								("Card Profile Name length too large!\n"));
+					}
+				}
+				else
+				{
+					DBGPRINT(RT_DEBUG_ERROR,
+							("Can not find search key word in card.dat!\n"));
+				}
+
+				if ((flg_match_ok != TRUE) &&
+					(card_match_id < MAX_NUM_OF_MULTIPLE_CARD))
+				{
+					MC_CardUsed[card_match_id] = 0;
+					memset(MC_CardMac[card_match_id], 0, sizeof(mac));
+				}
+			} // if (card_match_id >= 0)
+		}
+	}
+
+	// close file
+	retval = filp_close(srcf, NULL);
+	set_fs(orgfs);
+	current->fsuid = orgfsuid;
+	current->fsgid = orgfsgid;
+	kfree(buffer);
+	kfree(tmpbuf);
+	return flg_match_ok;
+}
+#endif // MULTIPLE_CARD_SUPPORT //
+
+
+/*
+========================================================================
+Routine Description:
+    Probe RT28XX chipset.
+
+Arguments:
+    _dev_p				Point to the PCI or USB device
+	_dev_id_p			Point to the PCI or USB device ID
+
+Return Value:
+    0					Probe OK
+	-ENODEV				Probe Fail
+
+Note:
+========================================================================
+*/
+INT __devinit   rt28xx_probe(
+    IN  void *_dev_p,
+    IN  void *_dev_id_p,
+	IN  UINT argc,
+	OUT PRTMP_ADAPTER *ppAd)
+{
+    struct  net_device	*net_dev;
+    PRTMP_ADAPTER       pAd = (PRTMP_ADAPTER) NULL;
+    INT                 status;
+	PVOID				handle;
+#ifdef RT2870
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	/* kernel 2.4 series */
+	struct usb_device *dev_p = (struct usb_device *)_dev_p;
+#else
+	struct usb_interface *intf = (struct usb_interface *)_dev_p;
+	struct usb_device *dev_p = interface_to_usbdev(intf);
+
+	dev_p = usb_get_dev(dev_p);
+#endif // LINUX_VERSION_CODE //
+#endif // RT2870 //
+
+
+#ifdef CONFIG_STA_SUPPORT
+    DBGPRINT(RT_DEBUG_TRACE, ("STA Driver version-%s\n", STA_DRIVER_VERSION));
+#endif // CONFIG_STA_SUPPORT //
+
+	// Check chipset vendor/product ID
+//	if (RT28XXChipsetCheck(_dev_p) == FALSE)
+//		goto err_out;
+
+#if LINUX_VERSION_CODE <= 0x20402       // Red Hat 7.1
+    net_dev = alloc_netdev(sizeof(PRTMP_ADAPTER), "eth%d", ether_setup);
+#else
+    net_dev = alloc_etherdev(sizeof(PRTMP_ADAPTER));
+#endif
+    if (net_dev == NULL)
+    {
+        printk("alloc_netdev failed\n");
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
+		module_put(THIS_MODULE);
+#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
+#else
+		MOD_DEC_USE_COUNT;
+#endif
+        goto err_out;
+    }
+
+// sample
+//	if (rt_ieee80211_if_setup(net_dev) != NDIS_STATUS_SUCCESS)
+//		goto err_out;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+    SET_MODULE_OWNER(net_dev);
+#endif
+
+	netif_stop_queue(net_dev);
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+/* for supporting Network Manager */
+/* Set the sysfs physical device reference for the network logical device
+ * if set prior to registration will cause a symlink during initialization.
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+    SET_NETDEV_DEV(net_dev, &(dev_p->dev));
+#endif
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+	// Allocate RTMP_ADAPTER miniport adapter structure
+	handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL);
+	RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p);
+
+	status = RTMPAllocAdapterBlock(handle, &pAd);
+	if (status != NDIS_STATUS_SUCCESS)
+		goto err_out_free_netdev;
+
+	net_dev->ml_priv = (PVOID)pAd;
+    pAd->net_dev = net_dev; // must be before RT28XXNetDevInit()
+
+	RT28XXNetDevInit(_dev_p, net_dev, pAd);
+
+#ifdef CONFIG_STA_SUPPORT
+    pAd->StaCfg.OriDevType = net_dev->type;
+#endif // CONFIG_STA_SUPPORT //
+
+	// Find and assign a free interface name, raxx
+//	RT28XXAvailRANameAssign(net_dev->name);
+
+	// Post config
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	if (RT28XXProbePostConfig(_dev_p, pAd, argc) == FALSE)
+		goto err_out_unmap;
+#else
+	if (RT28XXProbePostConfig(_dev_p, pAd, 0) == FALSE)
+		goto err_out_unmap;
+#endif // LINUX_VERSION_CODE //
+
+#ifdef CONFIG_STA_SUPPORT
+	pAd->OpMode = OPMODE_STA;
+#endif // CONFIG_STA_SUPPORT //
+
+
+#ifdef MULTIPLE_CARD_SUPPORT
+	// find its profile path
+	pAd->MC_RowID = -1; // use default profile path
+	RTMP_CardInfoRead(pAd);
+
+	if (pAd->MC_RowID == -1)
+#ifdef CONFIG_STA_SUPPORT
+		strcpy(pAd->MC_FileName, STA_PROFILE_PATH);
+#endif // CONFIG_STA_SUPPORT //
+
+	DBGPRINT(RT_DEBUG_TRACE,
+			("MC> ROW = %d, PATH = %s\n", pAd->MC_RowID, pAd->MC_FileName));
+#endif // MULTIPLE_CARD_SUPPORT //
+
+	// sample move
+	if (rt_ieee80211_if_setup(net_dev, pAd) != NDIS_STATUS_SUCCESS)
+		goto err_out_unmap;
+
+    // Register this device
+    status = register_netdev(net_dev);
+    if (status)
+        goto err_out_unmap;
+
+    // Set driver data
+	RT28XX_DRVDATA_SET(_dev_p);
+
+
+
+	*ppAd = pAd;
+    return 0; // probe ok
+
+
+	/* --------------------------- ERROR HANDLE --------------------------- */
+err_out_unmap:
+	RTMPFreeAdapter(pAd);
+	RT28XX_UNMAP();
+
+err_out_free_netdev:
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+    free_netdev(net_dev);
+#else
+	kfree(net_dev);
+#endif
+
+err_out:
+	RT28XX_PUT_DEVICE(dev_p);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	return (LONG)NULL;
+#else
+    return -ENODEV; /* probe fail */
+#endif // LINUX_VERSION_CODE //
+} /* End of rt28xx_probe */
+
+
+/*
+========================================================================
+Routine Description:
+    The entry point for Linux kernel sent packet to our driver.
+
+Arguments:
+    sk_buff *skb		the pointer refer to a sk_buffer.
+
+Return Value:
+    0
+
+Note:
+	This function is the entry point of Tx Path for Os delivery packet to
+	our driver. You only can put OS-depened & STA/AP common handle procedures
+	in here.
+========================================================================
+*/
+int rt28xx_packet_xmit(struct sk_buff *skb)
+{
+	struct net_device *net_dev = skb->dev;
+	PRTMP_ADAPTER pAd = net_dev->ml_priv;
+	int status = 0;
+	PNDIS_PACKET pPacket = (PNDIS_PACKET) skb;
+
+	/* RT2870STA does this in RTMPSendPackets() */
+#ifdef RALINK_ATE
+	if (ATE_ON(pAd))
+	{
+		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_RESOURCES);
+		return 0;
+	}
+#endif // RALINK_ATE //
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		// Drop send request since we are in monitor mode
+		if (MONITOR_ON(pAd))
+		{
+			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+			goto done;
+		}
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+        // EapolStart size is 18
+	if (skb->len < 14)
+	{
+		//printk("bad packet size: %d\n", pkt->len);
+		hex_dump("bad packet", skb->data, skb->len);
+		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+		goto done;
+	}
+
+	RTMP_SET_PACKET_5VT(pPacket, 0);
+//	MiniportMMRequest(pAd, pkt->data, pkt->len);
+#ifdef CONFIG_5VT_ENHANCE
+    if (*(int*)(skb->cb) == BRIDGE_TAG) {
+		RTMP_SET_PACKET_5VT(pPacket, 1);
+    }
+#endif
+
+
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+
+		STASendPackets((NDIS_HANDLE)pAd, (PPNDIS_PACKET) &pPacket, 1);
+	}
+
+#endif // CONFIG_STA_SUPPORT //
+
+	status = 0;
+done:
+
+	return status;
+}
+
+
+/*
+========================================================================
+Routine Description:
+    Send a packet to WLAN.
+
+Arguments:
+    skb_p           points to our adapter
+    dev_p           which WLAN network interface
+
+Return Value:
+    0: transmit successfully
+    otherwise: transmit fail
+
+Note:
+========================================================================
+*/
+INT rt28xx_send_packets(
+	IN struct sk_buff 		*skb_p,
+	IN struct net_device 	*net_dev)
+{
+    RTMP_ADAPTER *pAd = net_dev->ml_priv;
+
+	if (!(net_dev->flags & IFF_UP))
+	{
+		RELEASE_NDIS_PACKET(pAd, (PNDIS_PACKET)skb_p, NDIS_STATUS_FAILURE);
+		return 0;
+	}
+
+	NdisZeroMemory((PUCHAR)&skb_p->cb[CB_OFF], 15);
+	RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb_p, MAIN_MBSSID);
+
+	return rt28xx_packet_xmit(skb_p);
+} /* End of MBSS_VirtualIF_PacketSend */
+
+
+
+
+#if LINUX_VERSION_CODE <= 0x20402	// Red Hat 7.1
+//static struct net_device *alloc_netdev(int sizeof_priv, const char *mask, void (*setup)(struct net_device *)) //sample
+struct net_device *alloc_netdev(
+	int sizeof_priv,
+	const char *mask,
+	void (*setup)(struct net_device *))
+{
+    struct net_device	*dev;
+    INT					alloc_size;
+
+
+    /* ensure 32-byte alignment of the private area */
+    alloc_size = sizeof (*dev) + sizeof_priv + 31;
+
+    dev = (struct net_device *) kmalloc(alloc_size, GFP_KERNEL);
+    if (dev == NULL)
+    {
+        DBGPRINT(RT_DEBUG_ERROR,
+				("alloc_netdev: Unable to allocate device memory.\n"));
+        return NULL;
+    }
+
+    memset(dev, 0, alloc_size);
+
+    if (sizeof_priv)
+        dev->ml_priv = (void *) (((long)(dev + 1) + 31) & ~31);
+
+    setup(dev);
+    strcpy(dev->name, mask);
+
+    return dev;
+}
+#endif // LINUX_VERSION_CODE //
+
+
+void CfgInitHook(PRTMP_ADAPTER pAd)
+{
+	pAd->bBroadComHT = TRUE;
+} /* End of CfgInitHook */
+
+
+#if WIRELESS_EXT >= 12
+// This function will be called when query /proc
+struct iw_statistics *rt28xx_get_wireless_stats(
+    IN struct net_device *net_dev)
+{
+	PRTMP_ADAPTER pAd = net_dev->ml_priv;
+
+
+	DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_get_wireless_stats --->\n"));
+
+	pAd->iw_stats.status = 0; // Status - device dependent for now
+
+	// link quality
+	pAd->iw_stats.qual.qual = ((pAd->Mlme.ChannelQuality * 12)/10 + 10);
+	if(pAd->iw_stats.qual.qual > 100)
+		pAd->iw_stats.qual.qual = 100;
+
+#ifdef CONFIG_STA_SUPPORT
+	if (pAd->OpMode == OPMODE_STA)
+		pAd->iw_stats.qual.level = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2);
+#endif // CONFIG_STA_SUPPORT //
+
+	pAd->iw_stats.qual.noise = pAd->BbpWriteLatch[66]; // noise level (dBm)
+
+	pAd->iw_stats.qual.noise += 256 - 143;
+	pAd->iw_stats.qual.updated = 1;     // Flags to know if updated
+#ifdef IW_QUAL_DBM
+	pAd->iw_stats.qual.updated |= IW_QUAL_DBM;	// Level + Noise are dBm
+#endif // IW_QUAL_DBM //
+
+	pAd->iw_stats.discard.nwid = 0;     // Rx : Wrong nwid/essid
+	pAd->iw_stats.miss.beacon = 0;      // Missed beacons/superframe
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<--- rt28xx_get_wireless_stats\n"));
+	return &pAd->iw_stats;
+} /* End of rt28xx_get_wireless_stats */
+#endif // WIRELESS_EXT //
+
+
+
+void tbtt_tasklet(unsigned long data)
+{
+#define MAX_TX_IN_TBTT		(16)
+
+}
+
+INT rt28xx_ioctl(
+	IN	struct net_device	*net_dev,
+	IN	OUT	struct ifreq	*rq,
+	IN	INT					cmd)
+{
+	VIRTUAL_ADAPTER	*pVirtualAd = NULL;
+	RTMP_ADAPTER	*pAd = NULL;
+	INT				ret = 0;
+
+	if (net_dev->priv_flags == INT_MAIN)
+	{
+		pAd = net_dev->ml_priv;
+	}
+	else
+	{
+		pVirtualAd = net_dev->ml_priv;
+		pAd = pVirtualAd->RtmpDev->ml_priv;
+	}
+
+	if (pAd == NULL)
+	{
+		/* if 1st open fail, pAd will be free;
+		   So the net_dev->ml_priv will be NULL in 2rd open */
+		return -ENETDOWN;
+	}
+
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		ret = rt28xx_sta_ioctl(net_dev, rq, cmd);
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	return ret;
+}
+
+/*
+    ========================================================================
+
+    Routine Description:
+        return ethernet statistics counter
+
+    Arguments:
+        net_dev                     Pointer to net_device
+
+    Return Value:
+        net_device_stats*
+
+    Note:
+
+    ========================================================================
+*/
+struct net_device_stats *RT28xx_get_ether_stats(
+    IN  struct net_device *net_dev)
+{
+    RTMP_ADAPTER *pAd = NULL;
+
+	if (net_dev)
+		pAd = net_dev->ml_priv;
+
+	if (pAd)
+	{
+
+		pAd->stats.rx_packets = pAd->WlanCounters.ReceivedFragmentCount.QuadPart;
+		pAd->stats.tx_packets = pAd->WlanCounters.TransmittedFragmentCount.QuadPart;
+
+		pAd->stats.rx_bytes = pAd->RalinkCounters.ReceivedByteCount;
+		pAd->stats.tx_bytes = pAd->RalinkCounters.TransmittedByteCount;
+
+		pAd->stats.rx_errors = pAd->Counters8023.RxErrors;
+		pAd->stats.tx_errors = pAd->Counters8023.TxErrors;
+
+		pAd->stats.rx_dropped = 0;
+		pAd->stats.tx_dropped = 0;
+
+	    pAd->stats.multicast = pAd->WlanCounters.MulticastReceivedFrameCount.QuadPart;   // multicast packets received
+	    pAd->stats.collisions = pAd->Counters8023.OneCollision + pAd->Counters8023.MoreCollisions;  // Collision packets
+
+	    pAd->stats.rx_length_errors = 0;
+	    pAd->stats.rx_over_errors = pAd->Counters8023.RxNoBuffer;                   // receiver ring buff overflow
+	    pAd->stats.rx_crc_errors = 0;//pAd->WlanCounters.FCSErrorCount;     // recved pkt with crc error
+	    pAd->stats.rx_frame_errors = pAd->Counters8023.RcvAlignmentErrors;          // recv'd frame alignment error
+	    pAd->stats.rx_fifo_errors = pAd->Counters8023.RxNoBuffer;                   // recv'r fifo overrun
+	    pAd->stats.rx_missed_errors = 0;                                            // receiver missed packet
+
+	    // detailed tx_errors
+	    pAd->stats.tx_aborted_errors = 0;
+	    pAd->stats.tx_carrier_errors = 0;
+	    pAd->stats.tx_fifo_errors = 0;
+	    pAd->stats.tx_heartbeat_errors = 0;
+	    pAd->stats.tx_window_errors = 0;
+
+	    // for cslip etc
+	    pAd->stats.rx_compressed = 0;
+	    pAd->stats.tx_compressed = 0;
+
+		return &pAd->stats;
+	}
+	else
+    	return NULL;
+}
+
diff --git a/drivers/staging/rt3070/rt_profile.c b/drivers/staging/rt3070/rt_profile.c
new file mode 100644
index 0000000..6eda27e
--- /dev/null
+++ b/drivers/staging/rt3070/rt_profile.c
@@ -0,0 +1,2041 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+ */
+
+#include "rt_config.h"
+
+#ifdef DOT11_N_SUPPORT
+static void HTParametersHook(
+	IN	PRTMP_ADAPTER pAd,
+	IN	CHAR		  *pValueStr,
+	IN	CHAR		  *pInput);
+#endif // DOT11_N_SUPPORT //
+
+#define ETH_MAC_ADDR_STR_LEN 17  // in format of xx:xx:xx:xx:xx:xx
+
+// We assume the s1 is a sting, s2 is a memory space with 6 bytes. and content of s1 will be changed.
+BOOLEAN rtstrmactohex(char *s1, char *s2)
+{
+	int i = 0;
+	char *ptokS = s1, *ptokE = s1;
+
+	if (strlen(s1) != ETH_MAC_ADDR_STR_LEN)
+		return FALSE;
+
+	while((*ptokS) != '\0')
+	{
+		if((ptokE = strchr(ptokS, ':')) != NULL)
+			*ptokE++ = '\0';
+		if ((strlen(ptokS) != 2) || (!isxdigit(*ptokS)) || (!isxdigit(*(ptokS+1))))
+			break; // fail
+		AtoH(ptokS, &s2[i++], 1);
+		ptokS = ptokE;
+		if (i == 6)
+			break; // parsing finished
+	}
+
+	return ( i == 6 ? TRUE : FALSE);
+
+}
+
+
+// we assume the s1 and s2 both are strings.
+BOOLEAN rtstrcasecmp(char *s1, char *s2)
+{
+	char *p1 = s1, *p2 = s2;
+
+	if (strlen(s1) != strlen(s2))
+		return FALSE;
+
+	while(*p1 != '\0')
+	{
+		if((*p1 != *p2) && ((*p1 ^ *p2) != 0x20))
+			return FALSE;
+		p1++;
+		p2++;
+	}
+
+	return TRUE;
+}
+
+// we assume the s1 (buffer) and s2 (key) both are strings.
+char * rtstrstruncasecmp(char * s1, char * s2)
+{
+	INT l1, l2, i;
+	char temp1, temp2;
+
+	l2 = strlen(s2);
+	if (!l2)
+		return (char *) s1;
+
+	l1 = strlen(s1);
+
+	while (l1 >= l2)
+	{
+		l1--;
+
+		for(i=0; i<l2; i++)
+		{
+			temp1 = *(s1+i);
+			temp2 = *(s2+i);
+
+			if (('a' <= temp1) && (temp1 <= 'z'))
+				temp1 = 'A'+(temp1-'a');
+			if (('a' <= temp2) && (temp2 <= 'z'))
+				temp2 = 'A'+(temp2-'a');
+
+			if (temp1 != temp2)
+				break;
+		}
+
+		if (i == l2)
+			return (char *) s1;
+
+		s1++;
+	}
+
+	return NULL; // not found
+}
+
+//add by kathy
+
+ /**
+  * strstr - Find the first substring in a %NUL terminated string
+  * @s1: The string to be searched
+  * @s2: The string to search for
+  */
+char * rtstrstr(const char * s1,const char * s2)
+{
+	INT l1, l2;
+
+	l2 = strlen(s2);
+	if (!l2)
+		return (char *) s1;
+
+	l1 = strlen(s1);
+
+	while (l1 >= l2)
+	{
+		l1--;
+		if (!memcmp(s1,s2,l2))
+			return (char *) s1;
+		s1++;
+	}
+
+	return NULL;
+}
+
+/**
+ * rstrtok - Split a string into tokens
+ * @s: The string to be searched
+ * @ct: The characters to search for
+ * * WARNING: strtok is deprecated, use strsep instead. However strsep is not compatible with old architecture.
+ */
+char * __rstrtok;
+char * rstrtok(char * s,const char * ct)
+{
+	char *sbegin, *send;
+
+	sbegin  = s ? s : __rstrtok;
+	if (!sbegin)
+	{
+		return NULL;
+	}
+
+	sbegin += strspn(sbegin,ct);
+	if (*sbegin == '\0')
+	{
+		__rstrtok = NULL;
+		return( NULL );
+	}
+
+	send = strpbrk( sbegin, ct);
+	if (send && *send != '\0')
+		*send++ = '\0';
+
+	__rstrtok = send;
+
+	return (sbegin);
+}
+
+/**
+ * delimitcnt - return the count of a given delimiter in a given string.
+ * @s: The string to be searched.
+ * @ct: The delimiter to search for.
+ * Notice : We suppose the delimiter is a single-char string(for example : ";").
+ */
+INT delimitcnt(char * s,const char * ct)
+{
+	INT count = 0;
+	/* point to the beginning of the line */
+	const char *token = s;
+
+	for ( ;; )
+	{
+		token = strpbrk(token, ct); /* search for delimiters */
+
+        if ( token == NULL )
+		{
+			/* advanced to the terminating null character */
+			break;
+		}
+		/* skip the delimiter */
+	    ++token;
+
+		/*
+		 * Print the found text: use len with %.*s to specify field width.
+		 */
+
+		/* accumulate delimiter count */
+	    ++count;
+	}
+    return count;
+}
+
+/*
+  * converts the Internet host address from the standard numbers-and-dots notation
+  * into binary data.
+  * returns nonzero if the address is valid, zero if not.
+  */
+int rtinet_aton(const char *cp, unsigned int *addr)
+{
+	unsigned int 	val;
+	int         	base, n;
+	char        	c;
+	unsigned int    parts[4];
+	unsigned int    *pp = parts;
+
+	for (;;)
+    {
+         /*
+          * Collect number up to ``.''.
+          * Values are specified as for C:
+          *	0x=hex, 0=octal, other=decimal.
+          */
+         val = 0;
+         base = 10;
+         if (*cp == '0')
+         {
+             if (*++cp == 'x' || *cp == 'X')
+                 base = 16, cp++;
+             else
+                 base = 8;
+         }
+         while ((c = *cp) != '\0')
+         {
+             if (isdigit((unsigned char) c))
+             {
+                 val = (val * base) + (c - '0');
+                 cp++;
+                 continue;
+             }
+             if (base == 16 && isxdigit((unsigned char) c))
+             {
+                 val = (val << 4) +
+                     (c + 10 - (islower((unsigned char) c) ? 'a' : 'A'));
+                 cp++;
+                 continue;
+             }
+             break;
+         }
+         if (*cp == '.')
+         {
+             /*
+              * Internet format: a.b.c.d a.b.c   (with c treated as 16-bits)
+              * a.b     (with b treated as 24 bits)
+              */
+             if (pp >= parts + 3 || val > 0xff)
+                 return 0;
+             *pp++ = val, cp++;
+         }
+         else
+             break;
+     }
+
+     /*
+      * Check for trailing junk.
+      */
+     while (*cp)
+         if (!isspace((unsigned char) *cp++))
+             return 0;
+
+     /*
+      * Concoct the address according to the number of parts specified.
+      */
+     n = pp - parts + 1;
+     switch (n)
+     {
+
+         case 1:         /* a -- 32 bits */
+             break;
+
+         case 2:         /* a.b -- 8.24 bits */
+             if (val > 0xffffff)
+                 return 0;
+             val |= parts[0] << 24;
+             break;
+
+         case 3:         /* a.b.c -- 8.8.16 bits */
+             if (val > 0xffff)
+                 return 0;
+             val |= (parts[0] << 24) | (parts[1] << 16);
+             break;
+
+         case 4:         /* a.b.c.d -- 8.8.8.8 bits */
+             if (val > 0xff)
+                 return 0;
+             val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+             break;
+     }
+
+     *addr = htonl(val);
+     return 1;
+
+}
+
+/*
+    ========================================================================
+
+    Routine Description:
+        Find key section for Get key parameter.
+
+    Arguments:
+        buffer                      Pointer to the buffer to start find the key section
+        section                     the key of the secion to be find
+
+    Return Value:
+        NULL                        Fail
+        Others                      Success
+    ========================================================================
+*/
+PUCHAR  RTMPFindSection(
+    IN  PCHAR   buffer)
+{
+    CHAR temp_buf[32];
+    PUCHAR  ptr;
+
+    strcpy(temp_buf, "Default");
+
+    if((ptr = rtstrstr(buffer, temp_buf)) != NULL)
+            return (ptr+strlen("\n"));
+        else
+            return NULL;
+}
+
+/*
+    ========================================================================
+
+    Routine Description:
+        Get key parameter.
+
+    Arguments:
+        key                         Pointer to key string
+        dest                        Pointer to destination
+        destsize                    The datasize of the destination
+        buffer                      Pointer to the buffer to start find the key
+
+    Return Value:
+        TRUE                        Success
+        FALSE                       Fail
+
+    Note:
+        This routine get the value with the matched key (case case-sensitive)
+    ========================================================================
+*/
+INT RTMPGetKeyParameter(
+    IN  PCHAR   key,
+    OUT PCHAR   dest,
+    IN  INT     destsize,
+    IN  PCHAR   buffer)
+{
+    UCHAR *temp_buf1 = NULL;
+    UCHAR *temp_buf2 = NULL;
+    CHAR *start_ptr;
+    CHAR *end_ptr;
+    CHAR *ptr;
+    CHAR *offset = 0;
+    INT  len;
+
+	//temp_buf1 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
+	os_alloc_mem(NULL, &temp_buf1, MAX_PARAM_BUFFER_SIZE);
+
+	if(temp_buf1 == NULL)
+        return (FALSE);
+
+	//temp_buf2 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
+	os_alloc_mem(NULL, &temp_buf2, MAX_PARAM_BUFFER_SIZE);
+	if(temp_buf2 == NULL)
+	{
+		os_free_mem(NULL, temp_buf1);
+        return (FALSE);
+	}
+
+    //find section
+    if((offset = RTMPFindSection(buffer)) == NULL)
+    {
+    	os_free_mem(NULL, temp_buf1);
+    	os_free_mem(NULL, temp_buf2);
+        return (FALSE);
+    }
+
+    strcpy(temp_buf1, "\n");
+    strcat(temp_buf1, key);
+    strcat(temp_buf1, "=");
+
+    //search key
+    if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
+    {
+		os_free_mem(NULL, temp_buf1);
+    	os_free_mem(NULL, temp_buf2);
+        return (FALSE);
+    }
+
+    start_ptr+=strlen("\n");
+    if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
+       end_ptr=start_ptr+strlen(start_ptr);
+
+    if (end_ptr<start_ptr)
+    {
+		os_free_mem(NULL, temp_buf1);
+    	os_free_mem(NULL, temp_buf2);
+        return (FALSE);
+    }
+
+    NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
+    temp_buf2[end_ptr-start_ptr]='\0';
+    len = strlen(temp_buf2);
+    strcpy(temp_buf1, temp_buf2);
+    if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
+    {
+		os_free_mem(NULL, temp_buf1);
+    	os_free_mem(NULL, temp_buf2);
+        return (FALSE);
+    }
+
+    strcpy(temp_buf2, start_ptr+1);
+    ptr = temp_buf2;
+    //trim space or tab
+    while(*ptr != 0x00)
+    {
+        if( (*ptr == ' ') || (*ptr == '\t') )
+            ptr++;
+        else
+           break;
+    }
+
+    len = strlen(ptr);
+    memset(dest, 0x00, destsize);
+    strncpy(dest, ptr, len >= destsize ?  destsize: len);
+
+	os_free_mem(NULL, temp_buf1);
+    os_free_mem(NULL, temp_buf2);
+    return TRUE;
+}
+
+/*
+    ========================================================================
+
+    Routine Description:
+        Get key parameter.
+
+    Arguments:
+        key                         Pointer to key string
+        dest                        Pointer to destination
+        destsize                    The datasize of the destination
+        buffer                      Pointer to the buffer to start find the key
+
+    Return Value:
+        TRUE                        Success
+        FALSE                       Fail
+
+    Note:
+        This routine get the value with the matched key (case case-sensitive).
+        It is called for parsing SSID and any key string.
+    ========================================================================
+*/
+INT RTMPGetCriticalParameter(
+    IN  PCHAR   key,
+    OUT PCHAR   dest,
+    IN  INT     destsize,
+    IN  PCHAR   buffer)
+{
+    UCHAR *temp_buf1 = NULL;
+    UCHAR *temp_buf2 = NULL;
+    CHAR *start_ptr;
+    CHAR *end_ptr;
+    CHAR *ptr;
+    CHAR *offset = 0;
+    INT  len;
+
+	//temp_buf1 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
+	os_alloc_mem(NULL, &temp_buf1, MAX_PARAM_BUFFER_SIZE);
+
+	if(temp_buf1 == NULL)
+        return (FALSE);
+
+	//temp_buf2 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
+	os_alloc_mem(NULL, &temp_buf2, MAX_PARAM_BUFFER_SIZE);
+	if(temp_buf2 == NULL)
+	{
+		os_free_mem(NULL, temp_buf1);
+        return (FALSE);
+	}
+
+    //find section
+    if((offset = RTMPFindSection(buffer)) == NULL)
+    {
+    	os_free_mem(NULL, temp_buf1);
+    	os_free_mem(NULL, temp_buf2);
+        return (FALSE);
+    }
+
+    strcpy(temp_buf1, "\n");
+    strcat(temp_buf1, key);
+    strcat(temp_buf1, "=");
+
+    //search key
+    if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
+    {
+		os_free_mem(NULL, temp_buf1);
+    	os_free_mem(NULL, temp_buf2);
+        return (FALSE);
+    }
+
+    start_ptr+=strlen("\n");
+    if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
+       end_ptr=start_ptr+strlen(start_ptr);
+
+    if (end_ptr<start_ptr)
+    {
+		os_free_mem(NULL, temp_buf1);
+    	os_free_mem(NULL, temp_buf2);
+        return (FALSE);
+    }
+
+    NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
+    temp_buf2[end_ptr-start_ptr]='\0';
+    len = strlen(temp_buf2);
+    strcpy(temp_buf1, temp_buf2);
+    if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
+    {
+		os_free_mem(NULL, temp_buf1);
+    	os_free_mem(NULL, temp_buf2);
+        return (FALSE);
+    }
+
+    strcpy(temp_buf2, start_ptr+1);
+    ptr = temp_buf2;
+
+    //trim tab
+    /* We cannot trim space(' ') for SSID and key string. */
+    while(*ptr != 0x00)
+    {
+        //if( (*ptr == ' ') || (*ptr == '\t') )
+        if( (*ptr == '\t') )
+            ptr++;
+        else
+           break;
+    }
+
+    len = strlen(ptr);
+    memset(dest, 0x00, destsize);
+    strncpy(dest, ptr, len >= destsize ?  destsize: len);
+
+	os_free_mem(NULL, temp_buf1);
+    os_free_mem(NULL, temp_buf2);
+    return TRUE;
+}
+
+/*
+    ========================================================================
+
+    Routine Description:
+        Get multiple key parameter.
+
+    Arguments:
+        key                         Pointer to key string
+        dest                        Pointer to destination
+        destsize                    The datasize of the destination
+        buffer                      Pointer to the buffer to start find the key
+
+    Return Value:
+        TRUE                        Success
+        FALSE                       Fail
+
+    Note:
+        This routine get the value with the matched key (case case-sensitive)
+    ========================================================================
+*/
+INT RTMPGetKeyParameterWithOffset(
+    IN  PCHAR   key,
+    OUT PCHAR   dest,
+    OUT	USHORT	*end_offset,
+    IN  INT     destsize,
+    IN  PCHAR   buffer,
+    IN	BOOLEAN	bTrimSpace)
+{
+    UCHAR *temp_buf1 = NULL;
+    UCHAR *temp_buf2 = NULL;
+    CHAR *start_ptr;
+    CHAR *end_ptr;
+    CHAR *ptr;
+    CHAR *offset = 0;
+    INT  len;
+
+	if (*end_offset >= MAX_INI_BUFFER_SIZE)
+		return (FALSE);
+
+	os_alloc_mem(NULL, &temp_buf1, MAX_PARAM_BUFFER_SIZE);
+
+	if(temp_buf1 == NULL)
+        return (FALSE);
+
+	os_alloc_mem(NULL, &temp_buf2, MAX_PARAM_BUFFER_SIZE);
+	if(temp_buf2 == NULL)
+	{
+		os_free_mem(NULL, temp_buf1);
+        return (FALSE);
+	}
+
+    //find section
+	if(*end_offset == 0)
+    {
+		if ((offset = RTMPFindSection(buffer)) == NULL)
+		{
+			os_free_mem(NULL, temp_buf1);
+	    	os_free_mem(NULL, temp_buf2);
+    	    return (FALSE);
+		}
+    }
+	else
+		offset = buffer + (*end_offset);
+
+    strcpy(temp_buf1, "\n");
+    strcat(temp_buf1, key);
+    strcat(temp_buf1, "=");
+
+    //search key
+    if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
+    {
+		os_free_mem(NULL, temp_buf1);
+    	os_free_mem(NULL, temp_buf2);
+        return (FALSE);
+    }
+
+    start_ptr+=strlen("\n");
+    if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
+       end_ptr=start_ptr+strlen(start_ptr);
+
+    if (end_ptr<start_ptr)
+    {
+		os_free_mem(NULL, temp_buf1);
+    	os_free_mem(NULL, temp_buf2);
+        return (FALSE);
+    }
+
+	*end_offset = end_ptr - buffer;
+
+    NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
+    temp_buf2[end_ptr-start_ptr]='\0';
+    len = strlen(temp_buf2);
+    strcpy(temp_buf1, temp_buf2);
+    if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
+    {
+		os_free_mem(NULL, temp_buf1);
+    	os_free_mem(NULL, temp_buf2);
+        return (FALSE);
+    }
+
+    strcpy(temp_buf2, start_ptr+1);
+    ptr = temp_buf2;
+    //trim space or tab
+    while(*ptr != 0x00)
+    {
+        if((bTrimSpace && (*ptr == ' ')) || (*ptr == '\t') )
+            ptr++;
+        else
+           break;
+    }
+
+    len = strlen(ptr);
+    memset(dest, 0x00, destsize);
+    strncpy(dest, ptr, len >= destsize ?  destsize: len);
+
+	os_free_mem(NULL, temp_buf1);
+    os_free_mem(NULL, temp_buf2);
+    return TRUE;
+}
+
+
+static int rtmp_parse_key_buffer_from_file(IN  PRTMP_ADAPTER pAd,IN  char *buffer,IN  ULONG KeyType,IN  INT BSSIdx,IN  INT KeyIdx)
+{
+	PUCHAR		keybuff;
+	INT			i = BSSIdx, idx = KeyIdx;
+	ULONG		KeyLen;
+	UCHAR		CipherAlg = CIPHER_WEP64;
+
+	keybuff = buffer;
+	KeyLen = strlen(keybuff);
+
+	if (KeyType == 1)
+	{//Ascii
+		if( (KeyLen == 5) || (KeyLen == 13))
+		{
+			pAd->SharedKey[i][idx].KeyLen = KeyLen;
+			NdisMoveMemory(pAd->SharedKey[i][idx].Key, keybuff, KeyLen);
+			if (KeyLen == 5)
+				CipherAlg = CIPHER_WEP64;
+			else
+				CipherAlg = CIPHER_WEP128;
+			pAd->SharedKey[i][idx].CipherAlg = CipherAlg;
+
+			DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) Key%dStr=%s and type=%s\n", i, idx+1, keybuff, (KeyType == 0) ? "Hex":"Ascii"));
+			return 1;
+		}
+		else
+		{//Invalid key length
+			DBGPRINT(RT_DEBUG_ERROR, ("Key%dStr is Invalid key length! KeyLen = %ld!\n", idx+1, KeyLen));
+			return 0;
+		}
+	}
+	else
+	{//Hex type
+		if( (KeyLen == 10) || (KeyLen == 26))
+		{
+			pAd->SharedKey[i][idx].KeyLen = KeyLen / 2;
+			AtoH(keybuff, pAd->SharedKey[i][idx].Key, KeyLen / 2);
+			if (KeyLen == 10)
+				CipherAlg = CIPHER_WEP64;
+			else
+				CipherAlg = CIPHER_WEP128;
+			pAd->SharedKey[i][idx].CipherAlg = CipherAlg;
+
+			DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) Key%dStr=%s and type=%s\n", i, idx+1, keybuff, (KeyType == 0) ? "Hex":"Ascii"));
+			return 1;
+		}
+		else
+		{//Invalid key length
+			DBGPRINT(RT_DEBUG_ERROR, ("I/F(ra%d) Key%dStr is Invalid key length! KeyLen = %ld!\n", i, idx+1, KeyLen));
+			return 0;
+		}
+	}
+}
+static void rtmp_read_key_parms_from_file(IN  PRTMP_ADAPTER pAd, char *tmpbuf, char *buffer)
+{
+	char		tok_str[16];
+	PUCHAR		macptr;
+	INT			i = 0, idx;
+	ULONG		KeyType[MAX_MBSSID_NUM];
+	ULONG		KeyIdx;
+
+	NdisZeroMemory(KeyType, MAX_MBSSID_NUM);
+
+	//DefaultKeyID
+	if(RTMPGetKeyParameter("DefaultKeyID", tmpbuf, 25, buffer))
+	{
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+			KeyIdx = simple_strtol(tmpbuf, 0, 10);
+			if((KeyIdx >= 1 ) && (KeyIdx <= 4))
+				pAd->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1);
+			else
+				pAd->StaCfg.DefaultKeyId = 0;
+
+			DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyID(0~3)=%d\n", pAd->StaCfg.DefaultKeyId));
+		}
+#endif // CONFIG_STA_SUPPORT //
+	}
+
+
+	for (idx = 0; idx < 4; idx++)
+	{
+		sprintf(tok_str, "Key%dType", idx + 1);
+		//Key1Type
+		if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer))
+		{
+		    for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+		    {
+			    KeyType[i] = simple_strtol(macptr, 0, 10);
+		    }
+
+#ifdef CONFIG_STA_SUPPORT
+			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+			{
+				sprintf(tok_str, "Key%dStr", idx + 1);
+				if (RTMPGetCriticalParameter(tok_str, tmpbuf, 128, buffer))
+				{
+					rtmp_parse_key_buffer_from_file(pAd, tmpbuf, KeyType[BSS0], BSS0, idx);
+				}
+			}
+#endif // CONFIG_STA_SUPPORT //
+		}
+	}
+}
+
+
+#ifdef CONFIG_STA_SUPPORT
+static void rtmp_read_sta_wmm_parms_from_file(IN  PRTMP_ADAPTER pAd, char *tmpbuf, char *buffer)
+{
+	PUCHAR					macptr;
+	INT						i=0;
+	BOOLEAN					bWmmEnable = FALSE;
+
+	//WmmCapable
+	if(RTMPGetKeyParameter("WmmCapable", tmpbuf, 32, buffer))
+	{
+		if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
+		{
+			pAd->CommonCfg.bWmmCapable = TRUE;
+			bWmmEnable = TRUE;
+		}
+		else //Disable
+		{
+			pAd->CommonCfg.bWmmCapable = FALSE;
+		}
+
+		DBGPRINT(RT_DEBUG_TRACE, ("WmmCapable=%d\n", pAd->CommonCfg.bWmmCapable));
+	}
+
+#ifdef QOS_DLS_SUPPORT
+	//DLSCapable
+	if(RTMPGetKeyParameter("DLSCapable", tmpbuf, 32, buffer))
+	{
+		if(simple_strtol(tmpbuf, 0, 10) != 0)  //Enable
+		{
+			pAd->CommonCfg.bDLSCapable = TRUE;
+		}
+		else //Disable
+		{
+			pAd->CommonCfg.bDLSCapable = FALSE;
+		}
+
+		DBGPRINT(RT_DEBUG_TRACE, ("bDLSCapable=%d\n", pAd->CommonCfg.bDLSCapable));
+	}
+#endif // QOS_DLS_SUPPORT //
+
+	//AckPolicy for AC_BK, AC_BE, AC_VI, AC_VO
+	if(RTMPGetKeyParameter("AckPolicy", tmpbuf, 32, buffer))
+	{
+		for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+		{
+			pAd->CommonCfg.AckPolicy[i] = (UCHAR)simple_strtol(macptr, 0, 10);
+
+			DBGPRINT(RT_DEBUG_TRACE, ("AckPolicy[%d]=%d\n", i, pAd->CommonCfg.AckPolicy[i]));
+		}
+	}
+
+	if (bWmmEnable)
+	{
+		//APSDCapable
+		if(RTMPGetKeyParameter("APSDCapable", tmpbuf, 10, buffer))
+		{
+			if(simple_strtol(tmpbuf, 0, 10) != 0)  //Enable
+				pAd->CommonCfg.bAPSDCapable = TRUE;
+			else
+				pAd->CommonCfg.bAPSDCapable = FALSE;
+
+			DBGPRINT(RT_DEBUG_TRACE, ("APSDCapable=%d\n", pAd->CommonCfg.bAPSDCapable));
+		}
+
+		//APSDAC for AC_BE, AC_BK, AC_VI, AC_VO
+		if(RTMPGetKeyParameter("APSDAC", tmpbuf, 32, buffer))
+		{
+			BOOLEAN apsd_ac[4];
+
+			for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+			{
+				apsd_ac[i] = (BOOLEAN)simple_strtol(macptr, 0, 10);
+
+				DBGPRINT(RT_DEBUG_TRACE, ("APSDAC%d  %d\n", i,  apsd_ac[i]));
+			}
+
+			pAd->CommonCfg.bAPSDAC_BE = apsd_ac[0];
+			pAd->CommonCfg.bAPSDAC_BK = apsd_ac[1];
+			pAd->CommonCfg.bAPSDAC_VI = apsd_ac[2];
+			pAd->CommonCfg.bAPSDAC_VO = apsd_ac[3];
+		}
+	}
+
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+NDIS_STATUS	RTMPReadParametersHook(
+	IN	PRTMP_ADAPTER pAd)
+{
+	PUCHAR					src = NULL;
+	struct file				*srcf;
+	INT 					retval, orgfsuid, orgfsgid;
+   	mm_segment_t			orgfs;
+	CHAR					*buffer;
+	CHAR					*tmpbuf;
+	ULONG					RtsThresh;
+	ULONG					FragThresh;
+#ifdef CONFIG_STA_SUPPORT
+	UCHAR	                keyMaterial[40];
+#endif // CONFIG_STA_SUPPORT //
+
+
+	PUCHAR					macptr;
+	INT						i = 0;
+
+	buffer = kmalloc(MAX_INI_BUFFER_SIZE, MEM_ALLOC_FLAG);
+	if(buffer == NULL)
+        return NDIS_STATUS_FAILURE;
+
+	tmpbuf = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
+	if(tmpbuf == NULL)
+	{
+		kfree(buffer);
+        return NDIS_STATUS_FAILURE;
+	}
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		src = STA_PROFILE_PATH;
+#endif // CONFIG_STA_SUPPORT //
+#ifdef MULTIPLE_CARD_SUPPORT
+	src = pAd->MC_FileName;
+#endif // MULTIPLE_CARD_SUPPORT //
+
+	// Save uid and gid used for filesystem access.
+	// Set user and group to 0 (root)
+#if 0
+	orgfsuid = current->fsuid;
+	orgfsgid = current->fsgid;
+	current->fsuid=current->fsgid = 0;
+#endif
+    orgfs = get_fs();
+    set_fs(KERNEL_DS);
+
+	if (src && *src)
+	{
+		srcf = filp_open(src, O_RDONLY, 0);
+		if (IS_ERR(srcf))
+		{
+			DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src));
+		}
+		else
+		{
+			// The object must have a read method
+			if (srcf->f_op && srcf->f_op->read)
+			{
+				memset(buffer, 0x00, MAX_INI_BUFFER_SIZE);
+				retval=srcf->f_op->read(srcf, buffer, MAX_INI_BUFFER_SIZE, &srcf->f_pos);
+				if (retval < 0)
+				{
+					DBGPRINT(RT_DEBUG_TRACE, ("--> Read %s error %d\n", src, -retval));
+				}
+				else
+				{
+					// set file parameter to portcfg
+					//CountryRegion
+					if(RTMPGetKeyParameter("CountryRegion", tmpbuf, 25, buffer))
+					{
+						pAd->CommonCfg.CountryRegion = (UCHAR) simple_strtol(tmpbuf, 0, 10);
+						DBGPRINT(RT_DEBUG_TRACE, ("CountryRegion=%d\n", pAd->CommonCfg.CountryRegion));
+					}
+					//CountryRegionABand
+					if(RTMPGetKeyParameter("CountryRegionABand", tmpbuf, 25, buffer))
+					{
+						pAd->CommonCfg.CountryRegionForABand= (UCHAR) simple_strtol(tmpbuf, 0, 10);
+						DBGPRINT(RT_DEBUG_TRACE, ("CountryRegionABand=%d\n", pAd->CommonCfg.CountryRegionForABand));
+					}
+					//CountryCode
+					if(RTMPGetKeyParameter("CountryCode", tmpbuf, 25, buffer))
+					{
+						NdisMoveMemory(pAd->CommonCfg.CountryCode, tmpbuf , 2);
+#ifdef CONFIG_STA_SUPPORT
+#ifdef EXT_BUILD_CHANNEL_LIST
+						IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+							NdisMoveMemory(pAd->StaCfg.StaOriCountryCode, tmpbuf , 2);
+#endif // EXT_BUILD_CHANNEL_LIST //
+#endif // CONFIG_STA_SUPPORT //
+						if (strlen(pAd->CommonCfg.CountryCode) != 0)
+						{
+							pAd->CommonCfg.bCountryFlag = TRUE;
+						}
+						DBGPRINT(RT_DEBUG_TRACE, ("CountryCode=%s\n", pAd->CommonCfg.CountryCode));
+					}
+					//ChannelGeography
+					if(RTMPGetKeyParameter("ChannelGeography", tmpbuf, 25, buffer))
+					{
+						UCHAR Geography = (UCHAR) simple_strtol(tmpbuf, 0, 10);
+						if (Geography <= BOTH)
+						{
+							pAd->CommonCfg.Geography = Geography;
+							pAd->CommonCfg.CountryCode[2] =
+								(pAd->CommonCfg.Geography == BOTH) ? ' ' : ((pAd->CommonCfg.Geography == IDOR) ? 'I' : 'O');
+#ifdef CONFIG_STA_SUPPORT
+#ifdef EXT_BUILD_CHANNEL_LIST
+						IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+							pAd->StaCfg.StaOriGeography = pAd->CommonCfg.Geography;
+#endif // EXT_BUILD_CHANNEL_LIST //
+#endif // CONFIG_STA_SUPPORT //
+							DBGPRINT(RT_DEBUG_TRACE, ("ChannelGeography=%d\n", pAd->CommonCfg.Geography));
+						}
+					}
+					else
+					{
+						pAd->CommonCfg.Geography = BOTH;
+						pAd->CommonCfg.CountryCode[2] = ' ';
+					}
+
+
+#ifdef CONFIG_STA_SUPPORT
+					IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+					{
+						//SSID
+						if (RTMPGetCriticalParameter("SSID", tmpbuf, 256, buffer))
+						{
+							if (strlen(tmpbuf) <= 32)
+							{
+			 					pAd->CommonCfg.SsidLen = (UCHAR) strlen(tmpbuf);
+								NdisZeroMemory(pAd->CommonCfg.Ssid, NDIS_802_11_LENGTH_SSID);
+								NdisMoveMemory(pAd->CommonCfg.Ssid, tmpbuf, pAd->CommonCfg.SsidLen);
+								pAd->MlmeAux.AutoReconnectSsidLen = pAd->CommonCfg.SsidLen;
+								NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, NDIS_802_11_LENGTH_SSID);
+								NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, tmpbuf, pAd->MlmeAux.AutoReconnectSsidLen);
+								pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen;
+								NdisZeroMemory(pAd->MlmeAux.Ssid, NDIS_802_11_LENGTH_SSID);
+								NdisMoveMemory(pAd->MlmeAux.Ssid, tmpbuf, pAd->MlmeAux.SsidLen);
+								DBGPRINT(RT_DEBUG_TRACE, ("%s::(SSID=%s)\n", __FUNCTION__, tmpbuf));
+							}
+						}
+					}
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+					IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+					{
+						//NetworkType
+						if (RTMPGetKeyParameter("NetworkType", tmpbuf, 25, buffer))
+						{
+							pAd->bConfigChanged = TRUE;
+							if (strcmp(tmpbuf, "Adhoc") == 0)
+								pAd->StaCfg.BssType = BSS_ADHOC;
+							else //Default Infrastructure mode
+								pAd->StaCfg.BssType = BSS_INFRA;
+							// Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
+							pAd->StaCfg.WpaState = SS_NOTUSE;
+							DBGPRINT(RT_DEBUG_TRACE, ("%s::(NetworkType=%d)\n", __FUNCTION__, pAd->StaCfg.BssType));
+						}
+					}
+#endif // CONFIG_STA_SUPPORT //
+					//Channel
+					if(RTMPGetKeyParameter("Channel", tmpbuf, 10, buffer))
+					{
+						pAd->CommonCfg.Channel = (UCHAR) simple_strtol(tmpbuf, 0, 10);
+						DBGPRINT(RT_DEBUG_TRACE, ("Channel=%d\n", pAd->CommonCfg.Channel));
+					}
+					//WirelessMode
+					if(RTMPGetKeyParameter("WirelessMode", tmpbuf, 10, buffer))
+					{
+						int value  = 0, maxPhyMode = PHY_11G;
+
+#ifdef DOT11_N_SUPPORT
+						maxPhyMode = PHY_11N_5G;
+#endif // DOT11_N_SUPPORT //
+
+						value = simple_strtol(tmpbuf, 0, 10);
+
+						if (value <= maxPhyMode)
+						{
+							pAd->CommonCfg.PhyMode = value;
+						}
+						DBGPRINT(RT_DEBUG_TRACE, ("PhyMode=%d\n", pAd->CommonCfg.PhyMode));
+					}
+                    //BasicRate
+					if(RTMPGetKeyParameter("BasicRate", tmpbuf, 10, buffer))
+					{
+						pAd->CommonCfg.BasicRateBitmap = (ULONG) simple_strtol(tmpbuf, 0, 10);
+						DBGPRINT(RT_DEBUG_TRACE, ("BasicRate=%ld\n", pAd->CommonCfg.BasicRateBitmap));
+					}
+					//BeaconPeriod
+					if(RTMPGetKeyParameter("BeaconPeriod", tmpbuf, 10, buffer))
+					{
+						pAd->CommonCfg.BeaconPeriod = (USHORT) simple_strtol(tmpbuf, 0, 10);
+						DBGPRINT(RT_DEBUG_TRACE, ("BeaconPeriod=%d\n", pAd->CommonCfg.BeaconPeriod));
+					}
+                    //TxPower
+					if(RTMPGetKeyParameter("TxPower", tmpbuf, 10, buffer))
+					{
+						pAd->CommonCfg.TxPowerPercentage = (ULONG) simple_strtol(tmpbuf, 0, 10);
+#ifdef CONFIG_STA_SUPPORT
+						IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+							pAd->CommonCfg.TxPowerDefault = pAd->CommonCfg.TxPowerPercentage;
+#endif // CONFIG_STA_SUPPORT //
+						DBGPRINT(RT_DEBUG_TRACE, ("TxPower=%ld\n", pAd->CommonCfg.TxPowerPercentage));
+					}
+					//BGProtection
+					if(RTMPGetKeyParameter("BGProtection", tmpbuf, 10, buffer))
+					{
+						switch (simple_strtol(tmpbuf, 0, 10))
+						{
+							case 1: //Always On
+								pAd->CommonCfg.UseBGProtection = 1;
+								break;
+							case 2: //Always OFF
+								pAd->CommonCfg.UseBGProtection = 2;
+								break;
+							case 0: //AUTO
+							default:
+								pAd->CommonCfg.UseBGProtection = 0;
+								break;
+						}
+						DBGPRINT(RT_DEBUG_TRACE, ("BGProtection=%ld\n", pAd->CommonCfg.UseBGProtection));
+					}
+					//OLBCDetection
+					if(RTMPGetKeyParameter("DisableOLBC", tmpbuf, 10, buffer))
+					{
+						switch (simple_strtol(tmpbuf, 0, 10))
+						{
+							case 1: //disable OLBC Detection
+								pAd->CommonCfg.DisableOLBCDetect = 1;
+								break;
+							case 0: //enable OLBC Detection
+								pAd->CommonCfg.DisableOLBCDetect = 0;
+								break;
+							default:
+								pAd->CommonCfg.DisableOLBCDetect= 0;
+								break;
+						}
+						DBGPRINT(RT_DEBUG_TRACE, ("OLBCDetection=%ld\n", pAd->CommonCfg.DisableOLBCDetect));
+					}
+					//TxPreamble
+					if(RTMPGetKeyParameter("TxPreamble", tmpbuf, 10, buffer))
+					{
+						switch (simple_strtol(tmpbuf, 0, 10))
+						{
+							case Rt802_11PreambleShort:
+								pAd->CommonCfg.TxPreamble = Rt802_11PreambleShort;
+								break;
+							case Rt802_11PreambleLong:
+							default:
+								pAd->CommonCfg.TxPreamble = Rt802_11PreambleLong;
+								break;
+						}
+						DBGPRINT(RT_DEBUG_TRACE, ("TxPreamble=%ld\n", pAd->CommonCfg.TxPreamble));
+					}
+					//RTSThreshold
+					if(RTMPGetKeyParameter("RTSThreshold", tmpbuf, 10, buffer))
+					{
+						RtsThresh = simple_strtol(tmpbuf, 0, 10);
+						if( (RtsThresh >= 1) && (RtsThresh <= MAX_RTS_THRESHOLD) )
+							pAd->CommonCfg.RtsThreshold  = (USHORT)RtsThresh;
+						else
+							pAd->CommonCfg.RtsThreshold = MAX_RTS_THRESHOLD;
+
+						DBGPRINT(RT_DEBUG_TRACE, ("RTSThreshold=%d\n", pAd->CommonCfg.RtsThreshold));
+					}
+					//FragThreshold
+					if(RTMPGetKeyParameter("FragThreshold", tmpbuf, 10, buffer))
+					{
+						FragThresh = simple_strtol(tmpbuf, 0, 10);
+						pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
+
+						if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
+						{ //illegal FragThresh so we set it to default
+							pAd->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
+							pAd->CommonCfg.bUseZeroToDisableFragment = TRUE;
+						}
+						else if (FragThresh % 2 == 1)
+						{
+							// The length of each fragment shall always be an even number of octets, except for the last fragment
+							// of an MSDU or MMPDU, which may be either an even or an odd number of octets.
+							pAd->CommonCfg.FragmentThreshold = (USHORT)(FragThresh - 1);
+						}
+						else
+						{
+							pAd->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
+						}
+						//pAd->CommonCfg.AllowFragSize = (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;
+						DBGPRINT(RT_DEBUG_TRACE, ("FragThreshold=%d\n", pAd->CommonCfg.FragmentThreshold));
+					}
+					//TxBurst
+					if(RTMPGetKeyParameter("TxBurst", tmpbuf, 10, buffer))
+					{
+//#ifdef WIFI_TEST
+//						pAd->CommonCfg.bEnableTxBurst = FALSE;
+//#else
+						if(simple_strtol(tmpbuf, 0, 10) != 0)  //Enable
+							pAd->CommonCfg.bEnableTxBurst = TRUE;
+						else //Disable
+							pAd->CommonCfg.bEnableTxBurst = FALSE;
+//#endif
+						DBGPRINT(RT_DEBUG_TRACE, ("TxBurst=%d\n", pAd->CommonCfg.bEnableTxBurst));
+					}
+
+#ifdef AGGREGATION_SUPPORT
+					//PktAggregate
+					if(RTMPGetKeyParameter("PktAggregate", tmpbuf, 10, buffer))
+					{
+						if(simple_strtol(tmpbuf, 0, 10) != 0)  //Enable
+							pAd->CommonCfg.bAggregationCapable = TRUE;
+						else //Disable
+							pAd->CommonCfg.bAggregationCapable = FALSE;
+#ifdef PIGGYBACK_SUPPORT
+						pAd->CommonCfg.bPiggyBackCapable = pAd->CommonCfg.bAggregationCapable;
+#endif // PIGGYBACK_SUPPORT //
+						DBGPRINT(RT_DEBUG_TRACE, ("PktAggregate=%d\n", pAd->CommonCfg.bAggregationCapable));
+					}
+#else
+					pAd->CommonCfg.bAggregationCapable = FALSE;
+					pAd->CommonCfg.bPiggyBackCapable = FALSE;
+#endif // AGGREGATION_SUPPORT //
+
+					// WmmCapable
+
+#ifdef CONFIG_STA_SUPPORT
+					IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+						rtmp_read_sta_wmm_parms_from_file(pAd, tmpbuf, buffer);
+#endif // CONFIG_STA_SUPPORT //
+
+					//ShortSlot
+					if(RTMPGetKeyParameter("ShortSlot", tmpbuf, 10, buffer))
+					{
+						if(simple_strtol(tmpbuf, 0, 10) != 0)  //Enable
+							pAd->CommonCfg.bUseShortSlotTime = TRUE;
+						else //Disable
+							pAd->CommonCfg.bUseShortSlotTime = FALSE;
+
+						DBGPRINT(RT_DEBUG_TRACE, ("ShortSlot=%d\n", pAd->CommonCfg.bUseShortSlotTime));
+					}
+					//IEEE80211H
+					if(RTMPGetKeyParameter("IEEE80211H", tmpbuf, 10, buffer))
+					{
+					    for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+					    {
+    						if(simple_strtol(macptr, 0, 10) != 0)  //Enable
+    							pAd->CommonCfg.bIEEE80211H = TRUE;
+    						else //Disable
+    							pAd->CommonCfg.bIEEE80211H = FALSE;
+
+    						DBGPRINT(RT_DEBUG_TRACE, ("IEEE80211H=%d\n", pAd->CommonCfg.bIEEE80211H));
+					    }
+					}
+					//CSPeriod
+					if(RTMPGetKeyParameter("CSPeriod", tmpbuf, 10, buffer))
+					{
+					    if(simple_strtol(tmpbuf, 0, 10) != 0)
+							pAd->CommonCfg.RadarDetect.CSPeriod = simple_strtol(tmpbuf, 0, 10);
+						else
+							pAd->CommonCfg.RadarDetect.CSPeriod = 0;
+
+   						DBGPRINT(RT_DEBUG_TRACE, ("CSPeriod=%d\n", pAd->CommonCfg.RadarDetect.CSPeriod));
+					}
+
+					//RDRegion
+					if(RTMPGetKeyParameter("RDRegion", tmpbuf, 128, buffer))
+					{
+						if ((strncmp(tmpbuf, "JAP_W53", 7) == 0) || (strncmp(tmpbuf, "jap_w53", 7) == 0))
+						{
+							pAd->CommonCfg.RadarDetect.RDDurRegion = JAP_W53;
+							pAd->CommonCfg.RadarDetect.DfsSessionTime = 15;
+						}
+						else if ((strncmp(tmpbuf, "JAP_W56", 7) == 0) || (strncmp(tmpbuf, "jap_w56", 7) == 0))
+						{
+							pAd->CommonCfg.RadarDetect.RDDurRegion = JAP_W56;
+							pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
+						}
+						else if ((strncmp(tmpbuf, "JAP", 3) == 0) || (strncmp(tmpbuf, "jap", 3) == 0))
+						{
+							pAd->CommonCfg.RadarDetect.RDDurRegion = JAP;
+							pAd->CommonCfg.RadarDetect.DfsSessionTime = 5;
+						}
+						else  if ((strncmp(tmpbuf, "FCC", 3) == 0) || (strncmp(tmpbuf, "fcc", 3) == 0))
+						{
+							pAd->CommonCfg.RadarDetect.RDDurRegion = FCC;
+							pAd->CommonCfg.RadarDetect.DfsSessionTime = 5;
+						}
+						else if ((strncmp(tmpbuf, "CE", 2) == 0) || (strncmp(tmpbuf, "ce", 2) == 0))
+						{
+							pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
+							pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
+						}
+						else
+						{
+							pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
+							pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
+						}
+
+						DBGPRINT(RT_DEBUG_TRACE, ("RDRegion=%d\n", pAd->CommonCfg.RadarDetect.RDDurRegion));
+					}
+					else
+					{
+						pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
+						pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
+					}
+
+					//WirelessEvent
+					if(RTMPGetKeyParameter("WirelessEvent", tmpbuf, 10, buffer))
+					{
+#if WIRELESS_EXT >= 15
+					    if(simple_strtol(tmpbuf, 0, 10) != 0)
+							pAd->CommonCfg.bWirelessEvent = simple_strtol(tmpbuf, 0, 10);
+						else
+							pAd->CommonCfg.bWirelessEvent = 0;	// disable
+#else
+						pAd->CommonCfg.bWirelessEvent = 0;	// disable
+#endif
+   						DBGPRINT(RT_DEBUG_TRACE, ("WirelessEvent=%d\n", pAd->CommonCfg.bWirelessEvent));
+					}
+					if(RTMPGetKeyParameter("WiFiTest", tmpbuf, 10, buffer))
+					{
+					    if(simple_strtol(tmpbuf, 0, 10) != 0)
+							pAd->CommonCfg.bWiFiTest= simple_strtol(tmpbuf, 0, 10);
+						else
+							pAd->CommonCfg.bWiFiTest = 0;	// disable
+
+   						DBGPRINT(RT_DEBUG_TRACE, ("WiFiTest=%d\n", pAd->CommonCfg.bWiFiTest));
+					}
+					//AuthMode
+					if(RTMPGetKeyParameter("AuthMode", tmpbuf, 128, buffer))
+					{
+#ifdef CONFIG_STA_SUPPORT
+						IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+						{
+							if ((strcmp(tmpbuf, "WEPAUTO") == 0) || (strcmp(tmpbuf, "wepauto") == 0))
+							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
+							else if ((strcmp(tmpbuf, "SHARED") == 0) || (strcmp(tmpbuf, "shared") == 0))
+							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeShared;
+							else if ((strcmp(tmpbuf, "WPAPSK") == 0) || (strcmp(tmpbuf, "wpapsk") == 0))
+							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
+							else if ((strcmp(tmpbuf, "WPANONE") == 0) || (strcmp(tmpbuf, "wpanone") == 0))
+							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
+							else if ((strcmp(tmpbuf, "WPA2PSK") == 0) || (strcmp(tmpbuf, "wpa2psk") == 0))
+							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
+#ifdef WPA_SUPPLICANT_SUPPORT
+							else if ((strcmp(tmpbuf, "WPA") == 0) || (strcmp(tmpbuf, "wpa") == 0))
+							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
+							else if ((strcmp(tmpbuf, "WPA2") == 0) || (strcmp(tmpbuf, "wpa2") == 0))
+							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
+#endif // WPA_SUPPLICANT_SUPPORT //
+				                        else
+				                            pAd->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
+
+				                        pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+
+							DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __FUNCTION__, pAd->StaCfg.WepStatus));
+						}
+#endif // CONFIG_STA_SUPPORT //
+					}
+					//EncrypType
+					if(RTMPGetKeyParameter("EncrypType", tmpbuf, 128, buffer))
+					{
+
+#ifdef CONFIG_STA_SUPPORT
+						IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+						{
+							if ((strcmp(tmpbuf, "WEP") == 0) || (strcmp(tmpbuf, "wep") == 0))
+								pAd->StaCfg.WepStatus	= Ndis802_11WEPEnabled;
+							else if ((strcmp(tmpbuf, "TKIP") == 0) || (strcmp(tmpbuf, "tkip") == 0))
+								pAd->StaCfg.WepStatus	= Ndis802_11Encryption2Enabled;
+							else if ((strcmp(tmpbuf, "AES") == 0) || (strcmp(tmpbuf, "aes") == 0))
+								pAd->StaCfg.WepStatus	= Ndis802_11Encryption3Enabled;
+							else
+								pAd->StaCfg.WepStatus	= Ndis802_11WEPDisabled;
+
+							// Update all wepstatus related
+							pAd->StaCfg.PairCipher		= pAd->StaCfg.WepStatus;
+							pAd->StaCfg.GroupCipher 	= pAd->StaCfg.WepStatus;
+							pAd->StaCfg.OrigWepStatus 	= pAd->StaCfg.WepStatus;
+							pAd->StaCfg.bMixCipher 		= FALSE;
+
+							//RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
+							DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __FUNCTION__, pAd->StaCfg.WepStatus));
+						}
+#endif // CONFIG_STA_SUPPORT //
+					}
+
+
+
+#ifdef CONFIG_STA_SUPPORT
+					IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+					{
+						if(RTMPGetCriticalParameter("WPAPSK", tmpbuf, 512, buffer))
+						{
+							int     err=0;
+
+							tmpbuf[strlen(tmpbuf)] = '\0'; // make STA can process .$^& for WPAPSK input
+
+							if ((pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
+								(pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
+								(pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
+								)
+							{
+								err = 1;
+							}
+							else if ((strlen(tmpbuf) >= 8) && (strlen(tmpbuf) < 64))
+							{
+								PasswordHash((char *)tmpbuf, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, keyMaterial);
+								NdisMoveMemory(pAd->StaCfg.PMK, keyMaterial, 32);
+
+							}
+							else if (strlen(tmpbuf) == 64)
+							{
+								AtoH(tmpbuf, keyMaterial, 32);
+								NdisMoveMemory(pAd->StaCfg.PMK, keyMaterial, 32);
+							}
+							else
+							{
+								err = 1;
+								DBGPRINT(RT_DEBUG_ERROR, ("%s::(WPAPSK key-string required 8 ~ 64 characters!)\n", __FUNCTION__));
+							}
+
+							if (err == 0)
+	                        			{
+	                        				if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+									(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+								{
+									// Start STA supplicant state machine
+									pAd->StaCfg.WpaState = SS_START;
+								}
+								else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+								{
+	/*
+									NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
+									pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
+									NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
+									NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
+									NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
+
+									// Decide its ChiperAlg
+									if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+										pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
+									else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
+										pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
+									else
+										pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
+	*/
+									pAd->StaCfg.WpaState = SS_NOTUSE;
+								}
+
+								DBGPRINT(RT_DEBUG_TRACE, ("%s::(WPAPSK=%s)\n", __FUNCTION__, tmpbuf));
+							}
+						}
+					}
+#endif // CONFIG_STA_SUPPORT //
+
+					//DefaultKeyID, KeyType, KeyStr
+					rtmp_read_key_parms_from_file(pAd, tmpbuf, buffer);
+
+
+					//HSCounter
+					/*if(RTMPGetKeyParameter("HSCounter", tmpbuf, 10, buffer))
+					{
+						switch (simple_strtol(tmpbuf, 0, 10))
+						{
+							case 1: //Enable
+								pAd->CommonCfg.bEnableHSCounter = TRUE;
+								break;
+							case 0: //Disable
+							default:
+								pAd->CommonCfg.bEnableHSCounter = FALSE;
+								break;
+						}
+						DBGPRINT(RT_DEBUG_TRACE, "HSCounter=%d\n", pAd->CommonCfg.bEnableHSCounter);
+					}*/
+
+#ifdef DOT11_N_SUPPORT
+					HTParametersHook(pAd, tmpbuf, buffer);
+#endif // DOT11_N_SUPPORT //
+
+
+#ifdef CARRIER_DETECTION_SUPPORT
+						//CarrierDetect
+						if(RTMPGetKeyParameter("CarrierDetect", tmpbuf, 128, buffer))
+						{
+							if ((strncmp(tmpbuf, "0", 1) == 0))
+								pAd->CommonCfg.CarrierDetect.Enable = FALSE;
+							else if ((strncmp(tmpbuf, "1", 1) == 0))
+								pAd->CommonCfg.CarrierDetect.Enable = TRUE;
+							else
+								pAd->CommonCfg.CarrierDetect.Enable = FALSE;
+
+							DBGPRINT(RT_DEBUG_TRACE, ("CarrierDetect.Enable=%d\n", pAd->CommonCfg.CarrierDetect.Enable));
+						}
+						else
+							pAd->CommonCfg.CarrierDetect.Enable = FALSE;
+#endif // CARRIER_DETECTION_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+					IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+					{
+						//PSMode
+						if (RTMPGetKeyParameter("PSMode", tmpbuf, 10, buffer))
+						{
+							if (pAd->StaCfg.BssType == BSS_INFRA)
+							{
+								if ((strcmp(tmpbuf, "MAX_PSP") == 0) || (strcmp(tmpbuf, "max_psp") == 0))
+								{
+									// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
+									// to exclude certain situations.
+									//	   MlmeSetPsm(pAd, PWR_SAVE);
+									OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
+									if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
+										pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
+									pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
+									pAd->StaCfg.DefaultListenCount = 5;
+								}
+								else if ((strcmp(tmpbuf, "Fast_PSP") == 0) || (strcmp(tmpbuf, "fast_psp") == 0)
+									|| (strcmp(tmpbuf, "FAST_PSP") == 0))
+								{
+									// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
+									// to exclude certain situations.
+									//	   MlmeSetPsmBit(pAd, PWR_SAVE);
+									OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
+									if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
+										pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
+									pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
+									pAd->StaCfg.DefaultListenCount = 3;
+								}
+								else if ((strcmp(tmpbuf, "Legacy_PSP") == 0) || (strcmp(tmpbuf, "legacy_psp") == 0)
+									|| (strcmp(tmpbuf, "LEGACY_PSP") == 0))
+								{
+									// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
+									// to exclude certain situations.
+									//	   MlmeSetPsmBit(pAd, PWR_SAVE);
+									OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
+									if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
+										pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
+									pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
+									pAd->StaCfg.DefaultListenCount = 3;
+								}
+								else
+								{ //Default Ndis802_11PowerModeCAM
+									// clear PSM bit immediately
+									MlmeSetPsmBit(pAd, PWR_ACTIVE);
+									OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
+									if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
+										pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
+									pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
+								}
+								DBGPRINT(RT_DEBUG_TRACE, ("PSMode=%ld\n", pAd->StaCfg.WindowsPowerMode));
+							}
+						}
+						// FastRoaming
+						if (RTMPGetKeyParameter("FastRoaming", tmpbuf, 32, buffer))
+						{
+							if (simple_strtol(tmpbuf, 0, 10) == 0)
+								pAd->StaCfg.bFastRoaming = FALSE;
+							else
+								pAd->StaCfg.bFastRoaming = TRUE;
+
+							DBGPRINT(RT_DEBUG_TRACE, ("FastRoaming=%d\n", pAd->StaCfg.bFastRoaming));
+						}
+						// RoamThreshold
+						if (RTMPGetKeyParameter("RoamThreshold", tmpbuf, 32, buffer))
+						{
+							long lInfo = simple_strtol(tmpbuf, 0, 10);
+
+							if (lInfo > 90 || lInfo < 60)
+								pAd->StaCfg.dBmToRoam = -70;
+							else
+								pAd->StaCfg.dBmToRoam = (CHAR)(-1)*lInfo;
+
+							DBGPRINT(RT_DEBUG_TRACE, ("RoamThreshold=%d  dBm\n", pAd->StaCfg.dBmToRoam));
+						}
+
+						if(RTMPGetKeyParameter("TGnWifiTest", tmpbuf, 10, buffer))
+						{
+							if(simple_strtol(tmpbuf, 0, 10) == 0)
+								pAd->StaCfg.bTGnWifiTest = FALSE;
+							else
+								pAd->StaCfg.bTGnWifiTest = TRUE;
+								DBGPRINT(RT_DEBUG_TRACE, ("TGnWifiTest=%d\n", pAd->StaCfg.bTGnWifiTest));
+						}
+					}
+#endif // CONFIG_STA_SUPPORT //
+
+
+#ifdef RT30xx
+#ifdef CONFIG_STA_SUPPORT
+						IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+						{
+							if(RTMPGetKeyParameter("AntDiversity", tmpbuf, 10, buffer))
+							{
+								for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+								{
+									if(simple_strtol(macptr, 0, 10) != 0)  //Enable
+										pAd->CommonCfg.bRxAntDiversity = TRUE;
+									else //Disable
+										pAd->CommonCfg.bRxAntDiversity = FALSE;
+
+									DBGPRINT(RT_DEBUG_ERROR, ("AntDiversity=%d\n", pAd->CommonCfg.bRxAntDiversity));
+								}
+							}
+						}
+#endif // CONFIG_STA_SUPPORT //
+#endif // RT30xx //
+				}
+			}
+			else
+			{
+				DBGPRINT(RT_DEBUG_TRACE, ("--> %s does not have a write method\n", src));
+			}
+
+			retval=filp_close(srcf,NULL);
+
+			if (retval)
+			{
+				DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
+			}
+		}
+	}
+
+	set_fs(orgfs);
+#if 0
+	current->fsuid = orgfsuid;
+	current->fsgid = orgfsgid;
+#endif
+
+	kfree(buffer);
+	kfree(tmpbuf);
+
+	return (NDIS_STATUS_SUCCESS);
+}
+
+#ifdef DOT11_N_SUPPORT
+static void	HTParametersHook(
+	IN	PRTMP_ADAPTER pAd,
+	IN	CHAR		  *pValueStr,
+	IN	CHAR		  *pInput)
+{
+
+	INT Value;
+
+    if (RTMPGetKeyParameter("HT_PROTECT", pValueStr, 25, pInput))
+    {
+        Value = simple_strtol(pValueStr, 0, 10);
+        if (Value == 0)
+        {
+            pAd->CommonCfg.bHTProtect = FALSE;
+        }
+        else
+        {
+            pAd->CommonCfg.bHTProtect = TRUE;
+        }
+        DBGPRINT(RT_DEBUG_TRACE, ("HT: Protection  = %s\n", (Value==0) ? "Disable" : "Enable"));
+    }
+
+    if (RTMPGetKeyParameter("HT_MIMOPSEnable", pValueStr, 25, pInput))
+    {
+        Value = simple_strtol(pValueStr, 0, 10);
+        if (Value == 0)
+        {
+            pAd->CommonCfg.bMIMOPSEnable = FALSE;
+        }
+        else
+        {
+            pAd->CommonCfg.bMIMOPSEnable = TRUE;
+        }
+        DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPSEnable  = %s\n", (Value==0) ? "Disable" : "Enable"));
+    }
+
+
+    if (RTMPGetKeyParameter("HT_MIMOPSMode", pValueStr, 25, pInput))
+    {
+        Value = simple_strtol(pValueStr, 0, 10);
+        if (Value > MMPS_ENABLE)
+        {
+			pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
+        }
+        else
+        {
+            //TODO: add mimo power saving mechanism
+            pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
+			//pAd->CommonCfg.BACapability.field.MMPSmode = Value;
+        }
+        DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPS Mode  = %d\n", Value));
+    }
+
+    if (RTMPGetKeyParameter("HT_BADecline", pValueStr, 25, pInput))
+    {
+        Value = simple_strtol(pValueStr, 0, 10);
+        if (Value == 0)
+        {
+            pAd->CommonCfg.bBADecline = FALSE;
+        }
+        else
+        {
+            pAd->CommonCfg.bBADecline = TRUE;
+        }
+        DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Decline  = %s\n", (Value==0) ? "Disable" : "Enable"));
+    }
+
+
+    if (RTMPGetKeyParameter("HT_DisableReordering", pValueStr, 25, pInput))
+    {
+        Value = simple_strtol(pValueStr, 0, 10);
+        if (Value == 0)
+        {
+            pAd->CommonCfg.bDisableReordering = FALSE;
+        }
+        else
+        {
+            pAd->CommonCfg.bDisableReordering = TRUE;
+        }
+        DBGPRINT(RT_DEBUG_TRACE, ("HT: DisableReordering  = %s\n", (Value==0) ? "Disable" : "Enable"));
+    }
+
+    if (RTMPGetKeyParameter("HT_AutoBA", pValueStr, 25, pInput))
+    {
+        Value = simple_strtol(pValueStr, 0, 10);
+        if (Value == 0)
+        {
+            pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
+	    pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
+        }
+        else
+        {
+            pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
+	    pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
+        }
+        pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA;
+	pAd->CommonCfg.REGBACapability.field.Policy = pAd->CommonCfg.BACapability.field.Policy;
+        DBGPRINT(RT_DEBUG_TRACE, ("HT: Auto BA  = %s\n", (Value==0) ? "Disable" : "Enable"));
+    }
+
+	// Tx_+HTC frame
+    if (RTMPGetKeyParameter("HT_HTC", pValueStr, 25, pInput))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+		if (Value == 0)
+		{
+			pAd->HTCEnable = FALSE;
+		}
+		else
+		{
+            		pAd->HTCEnable = TRUE;
+		}
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx +HTC frame = %s\n", (Value==0) ? "Disable" : "Enable"));
+	}
+
+	// Enable HT Link Adaptation Control
+	if (RTMPGetKeyParameter("HT_LinkAdapt", pValueStr, 25, pInput))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+		if (Value == 0)
+		{
+			pAd->bLinkAdapt = FALSE;
+		}
+		else
+		{
+			pAd->HTCEnable = TRUE;
+			pAd->bLinkAdapt = TRUE;
+		}
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: Link Adaptation Control = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)"));
+	}
+
+	// Reverse Direction Mechanism
+    if (RTMPGetKeyParameter("HT_RDG", pValueStr, 25, pInput))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+		if (Value == 0)
+		{
+			pAd->CommonCfg.bRdg = FALSE;
+		}
+		else
+		{
+			pAd->HTCEnable = TRUE;
+            pAd->CommonCfg.bRdg = TRUE;
+		}
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: RDG = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)"));
+	}
+
+
+
+
+	// Tx A-MSUD ?
+    if (RTMPGetKeyParameter("HT_AMSDU", pValueStr, 25, pInput))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+		if (Value == 0)
+		{
+			pAd->CommonCfg.BACapability.field.AmsduEnable = FALSE;
+		}
+		else
+		{
+            pAd->CommonCfg.BACapability.field.AmsduEnable = TRUE;
+		}
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx A-MSDU = %s\n", (Value==0) ? "Disable" : "Enable"));
+	}
+
+	// MPDU Density
+    if (RTMPGetKeyParameter("HT_MpduDensity", pValueStr, 25, pInput))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+		if (Value <=7 && Value >= 0)
+		{
+			pAd->CommonCfg.BACapability.field.MpduDensity = Value;
+			DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d\n", Value));
+		}
+		else
+		{
+			pAd->CommonCfg.BACapability.field.MpduDensity = 4;
+			DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d (Default)\n", 4));
+		}
+	}
+
+	// Max Rx BA Window Size
+    if (RTMPGetKeyParameter("HT_BAWinSize", pValueStr, 25, pInput))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+
+		if (Value >=1 && Value <= 64)
+		{
+			pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = Value;
+			pAd->CommonCfg.BACapability.field.RxBAWinLimit = Value;
+			DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = %d\n", Value));
+		}
+		else
+		{
+            pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = 64;
+			pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64;
+			DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = 64 (Defualt)\n"));
+		}
+
+	}
+
+	// Guard Interval
+	if (RTMPGetKeyParameter("HT_GI", pValueStr, 25, pInput))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+
+		if (Value == GI_400)
+		{
+			pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_400;
+		}
+		else
+		{
+			pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_800;
+		}
+
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: Guard Interval = %s\n", (Value==GI_400) ? "400" : "800" ));
+	}
+
+	// HT Operation Mode : Mixed Mode , Green Field
+	if (RTMPGetKeyParameter("HT_OpMode", pValueStr, 25, pInput))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+
+		if (Value == HTMODE_GF)
+		{
+
+			pAd->CommonCfg.RegTransmitSetting.field.HTMODE  = HTMODE_GF;
+		}
+		else
+		{
+			pAd->CommonCfg.RegTransmitSetting.field.HTMODE  = HTMODE_MM;
+		}
+
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: Operate Mode = %s\n", (Value==HTMODE_GF) ? "Green Field" : "Mixed Mode" ));
+	}
+
+	// Fixed Tx mode : CCK, OFDM
+	if (RTMPGetKeyParameter("FixedTxMode", pValueStr, 25, pInput))
+	{
+		UCHAR	fix_tx_mode;
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+			fix_tx_mode = FIXED_TXMODE_HT;
+
+			if (strcmp(pValueStr, "OFDM") == 0 || strcmp(pValueStr, "ofdm") == 0)
+			{
+				fix_tx_mode = FIXED_TXMODE_OFDM;
+			}
+			else if (strcmp(pValueStr, "CCK") == 0 || strcmp(pValueStr, "cck") == 0)
+			{
+		        fix_tx_mode = FIXED_TXMODE_CCK;
+			}
+			else if (strcmp(pValueStr, "HT") == 0 || strcmp(pValueStr, "ht") == 0)
+			{
+		        fix_tx_mode = FIXED_TXMODE_HT;
+		}
+		else
+		{
+				Value = simple_strtol(pValueStr, 0, 10);
+				// 1 : CCK
+				// 2 : OFDM
+				// otherwise : HT
+				if (Value == FIXED_TXMODE_CCK || Value == FIXED_TXMODE_OFDM)
+					fix_tx_mode = Value;
+				else
+					fix_tx_mode = FIXED_TXMODE_HT;
+		}
+
+			pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = fix_tx_mode;
+			DBGPRINT(RT_DEBUG_TRACE, ("Fixed Tx Mode = %d\n", fix_tx_mode));
+
+		}
+#endif // CONFIG_STA_SUPPORT //
+	}
+
+
+	// Channel Width
+	if (RTMPGetKeyParameter("HT_BW", pValueStr, 25, pInput))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+
+		if (Value == BW_40)
+		{
+			pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_40;
+		}
+		else
+		{
+            pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_20;
+		}
+
+#ifdef MCAST_RATE_SPECIFIC
+		pAd->CommonCfg.MCastPhyMode.field.BW = pAd->CommonCfg.RegTransmitSetting.field.BW;
+#endif // MCAST_RATE_SPECIFIC //
+
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: Channel Width = %s\n", (Value==BW_40) ? "40 MHz" : "20 MHz" ));
+	}
+
+	if (RTMPGetKeyParameter("HT_EXTCHA", pValueStr, 25, pInput))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+
+		if (Value == 0)
+		{
+
+			pAd->CommonCfg.RegTransmitSetting.field.EXTCHA  = EXTCHA_BELOW;
+		}
+		else
+		{
+            pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
+		}
+
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: Ext Channel = %s\n", (Value==0) ? "BELOW" : "ABOVE" ));
+	}
+
+	// MSC
+	if (RTMPGetKeyParameter("HT_MCS", pValueStr, 50, pInput))
+	{
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+			Value = simple_strtol(pValueStr, 0, 10);
+
+//			if ((Value >= 0 && Value <= 15) || (Value == 32))
+			if ((Value >= 0 && Value <= 23) || (Value == 32)) // 3*3
+		{
+				pAd->StaCfg.DesiredTransmitSetting.field.MCS  = Value;
+				pAd->StaCfg.bAutoTxRateSwitch = FALSE;
+				DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = %d\n", pAd->StaCfg.DesiredTransmitSetting.field.MCS));
+		}
+		else
+		{
+				pAd->StaCfg.DesiredTransmitSetting.field.MCS  = MCS_AUTO;
+				pAd->StaCfg.bAutoTxRateSwitch = TRUE;
+				DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = AUTO\n"));
+		}
+	}
+#endif // CONFIG_STA_SUPPORT //
+	}
+
+	// STBC
+    if (RTMPGetKeyParameter("HT_STBC", pValueStr, 25, pInput))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+		if (Value == STBC_USE)
+		{
+			pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_USE;
+		}
+		else
+		{
+			pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_NONE;
+		}
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: STBC = %d\n", pAd->CommonCfg.RegTransmitSetting.field.STBC));
+	}
+
+	// 40_Mhz_Intolerant
+	if (RTMPGetKeyParameter("HT_40MHZ_INTOLERANT", pValueStr, 25, pInput))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+		if (Value == 0)
+		{
+			pAd->CommonCfg.bForty_Mhz_Intolerant = FALSE;
+		}
+		else
+		{
+			pAd->CommonCfg.bForty_Mhz_Intolerant = TRUE;
+		}
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: 40MHZ INTOLERANT = %d\n", pAd->CommonCfg.bForty_Mhz_Intolerant));
+	}
+	//HT_TxStream
+	if(RTMPGetKeyParameter("HT_TxStream", pValueStr, 10, pInput))
+	{
+		switch (simple_strtol(pValueStr, 0, 10))
+		{
+			case 1:
+				pAd->CommonCfg.TxStream = 1;
+				break;
+			case 2:
+				pAd->CommonCfg.TxStream = 2;
+				break;
+			case 3: // 3*3
+			default:
+				pAd->CommonCfg.TxStream = 3;
+
+				if (pAd->MACVersion < RALINK_2883_VERSION)
+					pAd->CommonCfg.TxStream = 2; // only 2 tx streams for RT2860 series
+				break;
+		}
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx Stream = %d\n", pAd->CommonCfg.TxStream));
+	}
+	//HT_RxStream
+	if(RTMPGetKeyParameter("HT_RxStream", pValueStr, 10, pInput))
+	{
+		switch (simple_strtol(pValueStr, 0, 10))
+		{
+			case 1:
+				pAd->CommonCfg.RxStream = 1;
+				break;
+			case 2:
+				pAd->CommonCfg.RxStream = 2;
+				break;
+			case 3:
+			default:
+				pAd->CommonCfg.RxStream = 3;
+
+				if (pAd->MACVersion < RALINK_2883_VERSION)
+					pAd->CommonCfg.RxStream = 2; // only 2 rx streams for RT2860 series
+				break;
+		}
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: Rx Stream = %d\n", pAd->CommonCfg.RxStream));
+	}
+
+}
+#endif // DOT11_N_SUPPORT //
+
diff --git a/drivers/staging/rt3070/rtmp.h b/drivers/staging/rt3070/rtmp.h
new file mode 100644
index 0000000..d80d74f
--- /dev/null
+++ b/drivers/staging/rt3070/rtmp.h
@@ -0,0 +1,7728 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+    rtmp.h
+
+    Abstract:
+    Miniport generic portion header file
+
+    Revision History:
+    Who         When          What
+    --------    ----------    ----------------------------------------------
+    Paul Lin    2002-08-01    created
+    James Tan   2002-09-06    modified (Revise NTCRegTable)
+    John Chang  2004-09-06    modified for RT2600
+*/
+#ifndef __RTMP_H__
+#define __RTMP_H__
+
+#include "link_list.h"
+#include "spectrum_def.h"
+
+#ifdef MLME_EX
+#include "mlme_ex_def.h"
+#endif // MLME_EX //
+
+#ifdef CONFIG_STA_SUPPORT
+#include "aironet.h"
+#endif // CONFIG_STA_SUPPORT //
+
+#undef AP_WSC_INCLUDED
+#undef STA_WSC_INCLUDED
+#undef WSC_INCLUDED
+
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED)
+#define WSC_INCLUDED
+#endif
+
+
+
+
+
+//#define DBG		1
+
+//#define DBG_DIAGNOSE		1
+
+#if defined(CONFIG_AP_SUPPORT) && defined(CONFIG_STA_SUPPORT)
+#define IF_DEV_CONFIG_OPMODE_ON_AP(_pAd)	if(_pAd->OpMode == OPMODE_AP)
+#define IF_DEV_CONFIG_OPMODE_ON_STA(_pAd)	if(_pAd->OpMode == OPMODE_STA)
+#else
+#define IF_DEV_CONFIG_OPMODE_ON_AP(_pAd)
+#define IF_DEV_CONFIG_OPMODE_ON_STA(_pAd)
+#endif
+
+#define VIRTUAL_IF_INC(__pAd) ((__pAd)->VirtualIfCnt++)
+#define VIRTUAL_IF_DEC(__pAd) ((__pAd)->VirtualIfCnt--)
+#define VIRTUAL_IF_NUM(__pAd) ((__pAd)->VirtualIfCnt)
+
+#ifdef RT2870
+////////////////////////////////////////////////////////////////////////////
+// The TX_BUFFER structure forms the transmitted USB packet to the device
+////////////////////////////////////////////////////////////////////////////
+typedef struct __TX_BUFFER{
+	union	{
+		UCHAR			WirelessPacket[TX_BUFFER_NORMSIZE];
+		HEADER_802_11	NullFrame;
+		PSPOLL_FRAME	PsPollPacket;
+		RTS_FRAME		RTSFrame;
+	}field;
+	UCHAR			Aggregation[4];  //Buffer for save Aggregation size.
+} TX_BUFFER, *PTX_BUFFER;
+
+typedef struct __HTTX_BUFFER{
+	union	{
+		UCHAR			WirelessPacket[MAX_TXBULK_SIZE];
+		HEADER_802_11	NullFrame;
+		PSPOLL_FRAME	PsPollPacket;
+		RTS_FRAME		RTSFrame;
+	}field;
+	UCHAR			Aggregation[4];  //Buffer for save Aggregation size.
+} HTTX_BUFFER, *PHTTX_BUFFER;
+
+
+// used to track driver-generated write irps
+typedef struct _TX_CONTEXT
+{
+	PVOID			pAd;		//Initialized in MiniportInitialize
+	PURB			pUrb;			//Initialized in MiniportInitialize
+	PIRP			pIrp;			//used to cancel pending bulk out.
+									//Initialized in MiniportInitialize
+	PTX_BUFFER		TransferBuffer;	//Initialized in MiniportInitialize
+	ULONG			BulkOutSize;
+	UCHAR			BulkOutPipeId;
+	UCHAR			SelfIdx;
+	BOOLEAN			InUse;
+	BOOLEAN			bWaitingBulkOut; // at least one packet is in this TxContext, ready for making IRP anytime.
+	BOOLEAN			bFullForBulkOut; // all tx buffer are full , so waiting for tx bulkout.
+	BOOLEAN			IRPPending;
+	BOOLEAN			LastOne;
+	BOOLEAN			bAggregatible;
+	UCHAR			Header_802_3[LENGTH_802_3];
+	UCHAR			Rsv[2];
+	ULONG			DataOffset;
+	UINT			TxRate;
+	dma_addr_t		data_dma;		// urb dma on linux
+
+}	TX_CONTEXT, *PTX_CONTEXT, **PPTX_CONTEXT;
+
+
+// used to track driver-generated write irps
+typedef struct _HT_TX_CONTEXT
+{
+	PVOID			pAd;		//Initialized in MiniportInitialize
+	PURB			pUrb;			//Initialized in MiniportInitialize
+	PIRP			pIrp;			//used to cancel pending bulk out.
+									//Initialized in MiniportInitialize
+	PHTTX_BUFFER	TransferBuffer;	//Initialized in MiniportInitialize
+	ULONG			BulkOutSize;	// Indicate the total bulk-out size in bytes in one bulk-transmission
+	UCHAR			BulkOutPipeId;
+	BOOLEAN			IRPPending;
+	BOOLEAN			LastOne;
+	BOOLEAN			bCurWriting;
+	BOOLEAN			bRingEmpty;
+	BOOLEAN			bCopySavePad;
+	UCHAR			SavedPad[8];
+	UCHAR			Header_802_3[LENGTH_802_3];
+	ULONG			CurWritePosition;		// Indicate the buffer offset which packet will be inserted start from.
+	ULONG			CurWriteRealPos;		// Indicate the buffer offset which packet now are writing to.
+	ULONG			NextBulkOutPosition;	// Indicate the buffer start offset of a bulk-transmission
+	ULONG			ENextBulkOutPosition;	// Indicate the buffer end offset of a bulk-transmission
+	UINT			TxRate;
+	dma_addr_t		data_dma;		// urb dma on linux
+}	HT_TX_CONTEXT, *PHT_TX_CONTEXT, **PPHT_TX_CONTEXT;
+
+
+//
+// Structure to keep track of receive packets and buffers to indicate
+// receive data to the protocol.
+//
+typedef struct _RX_CONTEXT
+{
+	PUCHAR				TransferBuffer;
+	PVOID				pAd;
+	PIRP				pIrp;//used to cancel pending bulk in.
+	PURB				pUrb;
+	//These 2 Boolean shouldn't both be 1 at the same time.
+	ULONG				BulkInOffset;	// number of packets waiting for reordering .
+//	BOOLEAN				ReorderInUse;	// At least one packet in this buffer are in reordering buffer and wait for receive indication
+	BOOLEAN				bRxHandling;	// Notify this packet is being process now.
+	BOOLEAN				InUse;			// USB Hardware Occupied. Wait for USB HW to put packet.
+	BOOLEAN				Readable;		// Receive Complete back. OK for driver to indicate receiving packet.
+	BOOLEAN				IRPPending;		// TODO: To be removed
+	atomic_t			IrpLock;
+	NDIS_SPIN_LOCK		RxContextLock;
+	dma_addr_t			data_dma;		// urb dma on linux
+}	RX_CONTEXT, *PRX_CONTEXT;
+#endif // RT2870 //
+
+
+//
+//  NDIS Version definitions
+//
+#ifdef  NDIS50_MINIPORT
+#define RTMP_NDIS_MAJOR_VERSION     5
+#define RTMP_NDIS_MINOR_VERSION     0
+#endif
+
+#ifdef  NDIS51_MINIPORT
+#define RTMP_NDIS_MAJOR_VERSION     5
+#define RTMP_NDIS_MINOR_VERSION     1
+#endif
+
+extern  char    NIC_VENDOR_DESC[];
+extern  int     NIC_VENDOR_DESC_LEN;
+
+extern  unsigned char   SNAP_AIRONET[];
+extern  unsigned char   CipherSuiteCiscoCCKM[];
+extern  unsigned char   CipherSuiteCiscoCCKMLen;
+extern	unsigned char	CipherSuiteCiscoCCKM24[];
+extern	unsigned char	CipherSuiteCiscoCCKM24Len;
+extern  unsigned char   CipherSuiteCCXTkip[];
+extern  unsigned char   CipherSuiteCCXTkipLen;
+extern  unsigned char   CISCO_OUI[];
+extern  UCHAR	BaSizeArray[4];
+
+extern UCHAR BROADCAST_ADDR[MAC_ADDR_LEN];
+extern UCHAR MULTICAST_ADDR[MAC_ADDR_LEN];
+extern UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN];
+extern ULONG BIT32[32];
+extern UCHAR BIT8[8];
+extern char* CipherName[];
+extern char* MCSToMbps[];
+extern UCHAR	 RxwiMCSToOfdmRate[12];
+extern UCHAR SNAP_802_1H[6];
+extern UCHAR SNAP_BRIDGE_TUNNEL[6];
+extern UCHAR SNAP_AIRONET[8];
+extern UCHAR CKIP_LLC_SNAP[8];
+extern UCHAR EAPOL_LLC_SNAP[8];
+extern UCHAR EAPOL[2];
+extern UCHAR IPX[2];
+extern UCHAR APPLE_TALK[2];
+extern UCHAR RateIdToPlcpSignal[12]; // see IEEE802.11a-1999 p.14
+extern UCHAR	 OfdmRateToRxwiMCS[];
+extern UCHAR OfdmSignalToRateId[16] ;
+extern UCHAR default_cwmin[4];
+extern UCHAR default_cwmax[4];
+extern UCHAR default_sta_aifsn[4];
+extern UCHAR MapUserPriorityToAccessCategory[8];
+
+extern USHORT RateUpPER[];
+extern USHORT RateDownPER[];
+extern UCHAR  Phy11BNextRateDownward[];
+extern UCHAR  Phy11BNextRateUpward[];
+extern UCHAR  Phy11BGNextRateDownward[];
+extern UCHAR  Phy11BGNextRateUpward[];
+extern UCHAR  Phy11ANextRateDownward[];
+extern UCHAR  Phy11ANextRateUpward[];
+extern CHAR   RssiSafeLevelForTxRate[];
+extern UCHAR  RateIdToMbps[];
+extern USHORT RateIdTo500Kbps[];
+
+extern UCHAR  CipherSuiteWpaNoneTkip[];
+extern UCHAR  CipherSuiteWpaNoneTkipLen;
+
+extern UCHAR  CipherSuiteWpaNoneAes[];
+extern UCHAR  CipherSuiteWpaNoneAesLen;
+
+extern UCHAR  SsidIe;
+extern UCHAR  SupRateIe;
+extern UCHAR  ExtRateIe;
+
+#ifdef DOT11_N_SUPPORT
+extern UCHAR  HtCapIe;
+extern UCHAR  AddHtInfoIe;
+extern UCHAR  NewExtChanIe;
+#ifdef DOT11N_DRAFT3
+extern UCHAR  ExtHtCapIe;
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+
+extern UCHAR  ErpIe;
+extern UCHAR  DsIe;
+extern UCHAR  TimIe;
+extern UCHAR  WpaIe;
+extern UCHAR  Wpa2Ie;
+extern UCHAR  IbssIe;
+extern UCHAR  Ccx2Ie;
+extern UCHAR  WapiIe;
+
+extern UCHAR  WPA_OUI[];
+extern UCHAR  RSN_OUI[];
+extern UCHAR  WAPI_OUI[];
+extern UCHAR  WME_INFO_ELEM[];
+extern UCHAR  WME_PARM_ELEM[];
+extern UCHAR  Ccx2QosInfo[];
+extern UCHAR  Ccx2IeInfo[];
+extern UCHAR  RALINK_OUI[];
+extern UCHAR  PowerConstraintIE[];
+
+
+extern UCHAR  RateSwitchTable[];
+extern UCHAR  RateSwitchTable11B[];
+extern UCHAR  RateSwitchTable11G[];
+extern UCHAR  RateSwitchTable11BG[];
+
+#ifdef DOT11_N_SUPPORT
+extern UCHAR  RateSwitchTable11BGN1S[];
+extern UCHAR  RateSwitchTable11BGN2S[];
+extern UCHAR  RateSwitchTable11BGN2SForABand[];
+extern UCHAR  RateSwitchTable11N1S[];
+extern UCHAR  RateSwitchTable11N2S[];
+extern UCHAR  RateSwitchTable11N2SForABand[];
+
+#ifdef CONFIG_STA_SUPPORT
+extern UCHAR  PRE_N_HT_OUI[];
+#endif // CONFIG_STA_SUPPORT //
+#endif // DOT11_N_SUPPORT //
+
+#define	MAXSEQ		(0xFFF)
+
+#ifdef RALINK_ATE
+typedef	struct _ATE_INFO {
+	UCHAR	Mode;
+	CHAR	TxPower0;
+	CHAR	TxPower1;
+	CHAR    TxAntennaSel;
+	CHAR    RxAntennaSel;
+	TXWI_STRUC  TxWI; 	  // TXWI
+	USHORT	QID;
+	UCHAR	Addr1[MAC_ADDR_LEN];
+	UCHAR	Addr2[MAC_ADDR_LEN];
+	UCHAR	Addr3[MAC_ADDR_LEN];
+	UCHAR	Channel;
+	UINT32	TxLength;
+	UINT32	TxCount;
+	UINT32	TxDoneCount; // Tx DMA Done
+	UINT32	RFFreqOffset;
+	BOOLEAN	bRxFer;
+	BOOLEAN	bQATxStart; // Have compiled QA in and use it to ATE tx.
+	BOOLEAN	bQARxStart;	// Have compiled QA in and use it to ATE rx.
+	UINT32	RxTotalCnt;
+	UINT32	RxCntPerSec;
+
+	CHAR	LastSNR0;             // last received SNR
+	CHAR    LastSNR1;             // last received SNR for 2nd  antenna
+	CHAR    LastRssi0;            // last received RSSI
+	CHAR    LastRssi1;            // last received RSSI for 2nd  antenna
+	CHAR    LastRssi2;            // last received RSSI for 3rd  antenna
+	CHAR    AvgRssi0;             // last 8 frames' average RSSI
+	CHAR    AvgRssi1;             // last 8 frames' average RSSI
+	CHAR    AvgRssi2;             // last 8 frames' average RSSI
+	SHORT   AvgRssi0X8;           // sum of last 8 frames' RSSI
+	SHORT   AvgRssi1X8;           // sum of last 8 frames' RSSI
+	SHORT   AvgRssi2X8;           // sum of last 8 frames' RSSI
+
+	UINT32	NumOfAvgRssiSample;
+
+#ifdef RALINK_28xx_QA
+	// Tx frame
+#ifdef RT2870
+	/* not used in RT2860 */
+	TXINFO_STRUC		TxInfo; // TxInfo
+#endif // RT2870 //
+	USHORT		HLen; // Header Length
+	USHORT		PLen; // Pattern Length
+	UCHAR 		Header[32]; // Header buffer
+	UCHAR		Pattern[32]; // Pattern buffer
+	USHORT		DLen; // Data Length
+	USHORT		seq;
+	UINT32		CID;
+	pid_t 		AtePid;
+	// counters
+	UINT32		U2M;
+	UINT32		OtherData;
+	UINT32		Beacon;
+	UINT32		OtherCount;
+	UINT32		TxAc0;
+	UINT32		TxAc1;
+	UINT32		TxAc2;
+	UINT32		TxAc3;
+	UINT32		TxHCCA;
+	UINT32		TxMgmt;
+	UINT32		RSSI0;
+	UINT32		RSSI1;
+	UINT32		RSSI2;
+	UINT32		SNR0;
+	UINT32		SNR1;
+	// control
+	//UINT32		Repeat; // Tx Cpu count
+	UCHAR		TxStatus; // task Tx status // 0 --> task is idle, 1 --> task is running
+#endif // RALINK_28xx_QA //
+}	ATE_INFO, *PATE_INFO;
+
+#ifdef RALINK_28xx_QA
+struct ate_racfghdr {
+ 	UINT32		magic_no;
+	USHORT		command_type;
+	USHORT		command_id;
+	USHORT		length;
+	USHORT		sequence;
+	USHORT		status;
+	UCHAR		data[2046];
+}  __attribute__((packed));
+#endif // RALINK_28xx_QA //
+#endif // RALINK_ATE //
+
+#ifdef DOT11_N_SUPPORT
+struct reordering_mpdu
+{
+	struct reordering_mpdu	*next;
+	PNDIS_PACKET			pPacket;		/* coverted to 802.3 frame */
+	int						Sequence;		/* sequence number of MPDU */
+	BOOLEAN					bAMSDU;
+};
+
+struct reordering_list
+{
+	struct reordering_mpdu *next;
+	int 	qlen;
+};
+
+struct reordering_mpdu_pool
+{
+	PVOID					mem;
+	NDIS_SPIN_LOCK			lock;
+	struct reordering_list 	freelist;
+};
+#endif // DOT11_N_SUPPORT //
+
+typedef struct 	_RSSI_SAMPLE {
+	CHAR			LastRssi0;             // last received RSSI
+	CHAR			LastRssi1;             // last received RSSI
+	CHAR			LastRssi2;             // last received RSSI
+	CHAR			AvgRssi0;
+	CHAR			AvgRssi1;
+	CHAR			AvgRssi2;
+	SHORT			AvgRssi0X8;
+	SHORT			AvgRssi1X8;
+	SHORT			AvgRssi2X8;
+} RSSI_SAMPLE;
+
+//
+//  Queue structure and macros
+//
+typedef struct  _QUEUE_ENTRY    {
+	struct _QUEUE_ENTRY     *Next;
+}   QUEUE_ENTRY, *PQUEUE_ENTRY;
+
+// Queue structure
+typedef struct  _QUEUE_HEADER   {
+	PQUEUE_ENTRY    Head;
+	PQUEUE_ENTRY    Tail;
+	ULONG           Number;
+}   QUEUE_HEADER, *PQUEUE_HEADER;
+
+#define InitializeQueueHeader(QueueHeader)              \
+{                                                       \
+	(QueueHeader)->Head = (QueueHeader)->Tail = NULL;   \
+	(QueueHeader)->Number = 0;                          \
+}
+
+#define RemoveHeadQueue(QueueHeader)                \
+(QueueHeader)->Head;                                \
+{                                                   \
+	PQUEUE_ENTRY pNext;                             \
+	if ((QueueHeader)->Head != NULL)				\
+	{												\
+		pNext = (QueueHeader)->Head->Next;          \
+		(QueueHeader)->Head = pNext;                \
+		if (pNext == NULL)                          \
+			(QueueHeader)->Tail = NULL;             \
+		(QueueHeader)->Number--;                    \
+	}												\
+}
+
+#define InsertHeadQueue(QueueHeader, QueueEntry)            \
+{                                                           \
+		((PQUEUE_ENTRY)QueueEntry)->Next = (QueueHeader)->Head; \
+		(QueueHeader)->Head = (PQUEUE_ENTRY)(QueueEntry);       \
+		if ((QueueHeader)->Tail == NULL)                        \
+			(QueueHeader)->Tail = (PQUEUE_ENTRY)(QueueEntry);   \
+		(QueueHeader)->Number++;                                \
+}
+
+#define InsertTailQueue(QueueHeader, QueueEntry)                \
+{                                                               \
+	((PQUEUE_ENTRY)QueueEntry)->Next = NULL;                    \
+	if ((QueueHeader)->Tail)                                    \
+		(QueueHeader)->Tail->Next = (PQUEUE_ENTRY)(QueueEntry); \
+	else                                                        \
+		(QueueHeader)->Head = (PQUEUE_ENTRY)(QueueEntry);       \
+	(QueueHeader)->Tail = (PQUEUE_ENTRY)(QueueEntry);           \
+	(QueueHeader)->Number++;                                    \
+}
+
+//
+//  Macros for flag and ref count operations
+//
+#define RTMP_SET_FLAG(_M, _F)       ((_M)->Flags |= (_F))
+#define RTMP_CLEAR_FLAG(_M, _F)     ((_M)->Flags &= ~(_F))
+#define RTMP_CLEAR_FLAGS(_M)        ((_M)->Flags = 0)
+#define RTMP_TEST_FLAG(_M, _F)      (((_M)->Flags & (_F)) != 0)
+#define RTMP_TEST_FLAGS(_M, _F)     (((_M)->Flags & (_F)) == (_F))
+
+#define OPSTATUS_SET_FLAG(_pAd, _F)     ((_pAd)->CommonCfg.OpStatusFlags |= (_F))
+#define OPSTATUS_CLEAR_FLAG(_pAd, _F)   ((_pAd)->CommonCfg.OpStatusFlags &= ~(_F))
+#define OPSTATUS_TEST_FLAG(_pAd, _F)    (((_pAd)->CommonCfg.OpStatusFlags & (_F)) != 0)
+
+#define CLIENT_STATUS_SET_FLAG(_pEntry,_F)      ((_pEntry)->ClientStatusFlags |= (_F))
+#define CLIENT_STATUS_CLEAR_FLAG(_pEntry,_F)    ((_pEntry)->ClientStatusFlags &= ~(_F))
+#define CLIENT_STATUS_TEST_FLAG(_pEntry,_F)     (((_pEntry)->ClientStatusFlags & (_F)) != 0)
+
+#define RX_FILTER_SET_FLAG(_pAd, _F)    ((_pAd)->CommonCfg.PacketFilter |= (_F))
+#define RX_FILTER_CLEAR_FLAG(_pAd, _F)  ((_pAd)->CommonCfg.PacketFilter &= ~(_F))
+#define RX_FILTER_TEST_FLAG(_pAd, _F)   (((_pAd)->CommonCfg.PacketFilter & (_F)) != 0)
+
+#ifdef CONFIG_STA_SUPPORT
+#define STA_NO_SECURITY_ON(_p)          (_p->StaCfg.WepStatus == Ndis802_11EncryptionDisabled)
+#define STA_WEP_ON(_p)                  (_p->StaCfg.WepStatus == Ndis802_11Encryption1Enabled)
+#define STA_TKIP_ON(_p)                 (_p->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
+#define STA_AES_ON(_p)                  (_p->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+
+#define STA_TGN_WIFI_ON(_p)             (_p->StaCfg.bTGnWifiTest == TRUE)
+#endif // CONFIG_STA_SUPPORT //
+
+#define CKIP_KP_ON(_p)				((((_p)->StaCfg.CkipFlag) & 0x10) && ((_p)->StaCfg.bCkipCmicOn == TRUE))
+#define CKIP_CMIC_ON(_p)			((((_p)->StaCfg.CkipFlag) & 0x08) && ((_p)->StaCfg.bCkipCmicOn == TRUE))
+
+
+#define INC_RING_INDEX(_idx, _RingSize)    \
+{                                          \
+    (_idx) = (_idx+1) % (_RingSize);       \
+}
+
+// We will have a cost down version which mac version is 0x3090xxxx
+#define IS_RT3090(_pAd)				((((_pAd)->MACVersion & 0xffff0000) == 0x30710000) || (((_pAd)->MACVersion & 0xffff0000) == 0x30900000))
+
+#define IS_RT3070(_pAd)				(((_pAd)->MACVersion & 0xffff0000) == 0x30700000)
+#define IS_RT3071(_pAd)				(((_pAd)->MACVersion & 0xffff0000) == 0x30710000)
+#define IS_RT2070(_pAd)				(((_pAd)->RfIcType == RFIC_2020) || ((_pAd)->EFuseTag == 0x27))
+
+#define IS_RT30xx(_pAd)				(((_pAd)->MACVersion & 0xfff00000) == 0x30700000)
+
+#define RING_PACKET_INIT(_TxRing, _idx)    \
+{                                          \
+    _TxRing->Cell[_idx].pNdisPacket = NULL;                              \
+    _TxRing->Cell[_idx].pNextNdisPacket = NULL;                              \
+}
+
+#define TXDT_INIT(_TxD)    \
+{                                          \
+	NdisZeroMemory(_TxD, TXD_SIZE);	\
+	_TxD->DMADONE = 1;                              \
+}
+
+//Set last data segment
+#define RING_SET_LASTDS(_TxD, _IsSD0)    \
+{                                          \
+    if (_IsSD0) {_TxD->LastSec0 = 1;}     \
+    else {_TxD->LastSec1 = 1;}     \
+}
+
+// Increase TxTsc value for next transmission
+// TODO:
+// When i==6, means TSC has done one full cycle, do re-keying stuff follow specs
+// Should send a special event microsoft defined to request re-key
+#define INC_TX_TSC(_tsc)                                \
+{                                                       \
+    int i=0;                                            \
+    while (++_tsc[i] == 0x0)                            \
+    {                                                   \
+        i++;                                            \
+        if (i == 6)                                     \
+            break;                                      \
+    }                                                   \
+}
+
+#ifdef DOT11_N_SUPPORT
+// StaActive.SupportedHtPhy.MCSSet is copied from AP beacon.  Don't need to update here.
+#define COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd)                                 \
+{                                                                                       \
+	_pAd->StaActive.SupportedHtPhy.ChannelWidth = _pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth;      \
+	_pAd->StaActive.SupportedHtPhy.MimoPs = _pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs;      \
+	_pAd->StaActive.SupportedHtPhy.GF = _pAd->MlmeAux.HtCapability.HtCapInfo.GF;      \
+	_pAd->StaActive.SupportedHtPhy.ShortGIfor20 = _pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20;      \
+	_pAd->StaActive.SupportedHtPhy.ShortGIfor40 = _pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40;      \
+	_pAd->StaActive.SupportedHtPhy.TxSTBC = _pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC;      \
+	_pAd->StaActive.SupportedHtPhy.RxSTBC = _pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC;      \
+	_pAd->StaActive.SupportedHtPhy.ExtChanOffset = _pAd->MlmeAux.AddHtInfo.AddHtInfo.ExtChanOffset;      \
+	_pAd->StaActive.SupportedHtPhy.RecomWidth = _pAd->MlmeAux.AddHtInfo.AddHtInfo.RecomWidth;      \
+	_pAd->StaActive.SupportedHtPhy.OperaionMode = _pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode;      \
+	_pAd->StaActive.SupportedHtPhy.NonGfPresent = _pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent;      \
+	NdisMoveMemory((_pAd)->MacTab.Content[BSSID_WCID].HTCapability.MCSSet, (_pAd)->StaActive.SupportedPhyInfo.MCSSet, sizeof(UCHAR) * 16);\
+}
+
+#define COPY_AP_HTSETTINGS_FROM_BEACON(_pAd, _pHtCapability)                                 \
+{                                                                                       \
+	_pAd->MacTab.Content[BSSID_WCID].AMsduSize = (UCHAR)(_pHtCapability->HtCapInfo.AMsduSize);	\
+	_pAd->MacTab.Content[BSSID_WCID].MmpsMode= (UCHAR)(_pHtCapability->HtCapInfo.MimoPs);	\
+	_pAd->MacTab.Content[BSSID_WCID].MaxRAmpduFactor = (UCHAR)(_pHtCapability->HtCapParm.MaxRAmpduFactor);	\
+}
+#endif // DOT11_N_SUPPORT //
+
+//
+// MACRO for 32-bit PCI register read / write
+//
+// Usage : RTMP_IO_READ32(
+//              PRTMP_ADAPTER pAd,
+//              ULONG Register_Offset,
+//              PULONG  pValue)
+//
+//         RTMP_IO_WRITE32(
+//              PRTMP_ADAPTER pAd,
+//              ULONG Register_Offset,
+//              ULONG Value)
+//
+
+//
+// BBP & RF are using indirect access. Before write any value into it.
+// We have to make sure there is no outstanding command pending via checking busy bit.
+//
+#define MAX_BUSY_COUNT  100         // Number of retry before failing access BBP & RF indirect register
+//
+
+#ifdef RT2870
+#define RTMP_RF_IO_WRITE32(_A, _V)                 RTUSBWriteRFRegister(_A, _V)
+#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)   RTUSBReadBBPRegister(_A, _I, _pV)
+#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V)   RTUSBWriteBBPRegister(_A, _I, _V)
+
+#define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V)			RTUSBWriteBBPRegister(_A, _I, _V)
+#define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)   		RTUSBReadBBPRegister(_A, _I, _pV)
+#endif // RT2870 //
+
+#ifdef RT30xx
+#define RTMP_RF_IO_READ8_BY_REG_ID(_A, _I, _pV)    RT30xxReadRFRegister(_A, _I, _pV)
+#define RTMP_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V)    RT30xxWriteRFRegister(_A, _I, _V)
+#endif // RT30xx //
+
+#define     MAP_CHANNEL_ID_TO_KHZ(ch, khz)  {               \
+                switch (ch)                                 \
+                {                                           \
+                    case 1:     khz = 2412000;   break;     \
+                    case 2:     khz = 2417000;   break;     \
+                    case 3:     khz = 2422000;   break;     \
+                    case 4:     khz = 2427000;   break;     \
+                    case 5:     khz = 2432000;   break;     \
+                    case 6:     khz = 2437000;   break;     \
+                    case 7:     khz = 2442000;   break;     \
+                    case 8:     khz = 2447000;   break;     \
+                    case 9:     khz = 2452000;   break;     \
+                    case 10:    khz = 2457000;   break;     \
+                    case 11:    khz = 2462000;   break;     \
+                    case 12:    khz = 2467000;   break;     \
+                    case 13:    khz = 2472000;   break;     \
+                    case 14:    khz = 2484000;   break;     \
+                    case 36:  /* UNII */  khz = 5180000;   break;     \
+                    case 40:  /* UNII */  khz = 5200000;   break;     \
+                    case 44:  /* UNII */  khz = 5220000;   break;     \
+                    case 48:  /* UNII */  khz = 5240000;   break;     \
+                    case 52:  /* UNII */  khz = 5260000;   break;     \
+                    case 56:  /* UNII */  khz = 5280000;   break;     \
+                    case 60:  /* UNII */  khz = 5300000;   break;     \
+                    case 64:  /* UNII */  khz = 5320000;   break;     \
+                    case 149: /* UNII */  khz = 5745000;   break;     \
+                    case 153: /* UNII */  khz = 5765000;   break;     \
+                    case 157: /* UNII */  khz = 5785000;   break;     \
+                    case 161: /* UNII */  khz = 5805000;   break;     \
+                    case 165: /* UNII */  khz = 5825000;   break;     \
+                    case 100: /* HiperLAN2 */  khz = 5500000;   break;     \
+                    case 104: /* HiperLAN2 */  khz = 5520000;   break;     \
+                    case 108: /* HiperLAN2 */  khz = 5540000;   break;     \
+                    case 112: /* HiperLAN2 */  khz = 5560000;   break;     \
+                    case 116: /* HiperLAN2 */  khz = 5580000;   break;     \
+                    case 120: /* HiperLAN2 */  khz = 5600000;   break;     \
+                    case 124: /* HiperLAN2 */  khz = 5620000;   break;     \
+                    case 128: /* HiperLAN2 */  khz = 5640000;   break;     \
+                    case 132: /* HiperLAN2 */  khz = 5660000;   break;     \
+                    case 136: /* HiperLAN2 */  khz = 5680000;   break;     \
+                    case 140: /* HiperLAN2 */  khz = 5700000;   break;     \
+                    case 34:  /* Japan MMAC */   khz = 5170000;   break;   \
+                    case 38:  /* Japan MMAC */   khz = 5190000;   break;   \
+                    case 42:  /* Japan MMAC */   khz = 5210000;   break;   \
+                    case 46:  /* Japan MMAC */   khz = 5230000;   break;   \
+                    case 184: /* Japan */   khz = 4920000;   break;   \
+                    case 188: /* Japan */   khz = 4940000;   break;   \
+                    case 192: /* Japan */   khz = 4960000;   break;   \
+                    case 196: /* Japan */   khz = 4980000;   break;   \
+                    case 208: /* Japan, means J08 */   khz = 5040000;   break;   \
+                    case 212: /* Japan, means J12 */   khz = 5060000;   break;   \
+                    case 216: /* Japan, means J16 */   khz = 5080000;   break;   \
+                    default:    khz = 2412000;   break;     \
+                }                                           \
+            }
+
+#define     MAP_KHZ_TO_CHANNEL_ID(khz, ch)  {               \
+                switch (khz)                                \
+                {                                           \
+                    case 2412000:    ch = 1;     break;     \
+                    case 2417000:    ch = 2;     break;     \
+                    case 2422000:    ch = 3;     break;     \
+                    case 2427000:    ch = 4;     break;     \
+                    case 2432000:    ch = 5;     break;     \
+                    case 2437000:    ch = 6;     break;     \
+                    case 2442000:    ch = 7;     break;     \
+                    case 2447000:    ch = 8;     break;     \
+                    case 2452000:    ch = 9;     break;     \
+                    case 2457000:    ch = 10;    break;     \
+                    case 2462000:    ch = 11;    break;     \
+                    case 2467000:    ch = 12;    break;     \
+                    case 2472000:    ch = 13;    break;     \
+                    case 2484000:    ch = 14;    break;     \
+                    case 5180000:    ch = 36;  /* UNII */  break;     \
+                    case 5200000:    ch = 40;  /* UNII */  break;     \
+                    case 5220000:    ch = 44;  /* UNII */  break;     \
+                    case 5240000:    ch = 48;  /* UNII */  break;     \
+                    case 5260000:    ch = 52;  /* UNII */  break;     \
+                    case 5280000:    ch = 56;  /* UNII */  break;     \
+                    case 5300000:    ch = 60;  /* UNII */  break;     \
+                    case 5320000:    ch = 64;  /* UNII */  break;     \
+                    case 5745000:    ch = 149; /* UNII */  break;     \
+                    case 5765000:    ch = 153; /* UNII */  break;     \
+                    case 5785000:    ch = 157; /* UNII */  break;     \
+                    case 5805000:    ch = 161; /* UNII */  break;     \
+                    case 5825000:    ch = 165; /* UNII */  break;     \
+                    case 5500000:    ch = 100; /* HiperLAN2 */  break;     \
+                    case 5520000:    ch = 104; /* HiperLAN2 */  break;     \
+                    case 5540000:    ch = 108; /* HiperLAN2 */  break;     \
+                    case 5560000:    ch = 112; /* HiperLAN2 */  break;     \
+                    case 5580000:    ch = 116; /* HiperLAN2 */  break;     \
+                    case 5600000:    ch = 120; /* HiperLAN2 */  break;     \
+                    case 5620000:    ch = 124; /* HiperLAN2 */  break;     \
+                    case 5640000:    ch = 128; /* HiperLAN2 */  break;     \
+                    case 5660000:    ch = 132; /* HiperLAN2 */  break;     \
+                    case 5680000:    ch = 136; /* HiperLAN2 */  break;     \
+                    case 5700000:    ch = 140; /* HiperLAN2 */  break;     \
+                    case 5170000:    ch = 34;  /* Japan MMAC */   break;   \
+                    case 5190000:    ch = 38;  /* Japan MMAC */   break;   \
+                    case 5210000:    ch = 42;  /* Japan MMAC */   break;   \
+                    case 5230000:    ch = 46;  /* Japan MMAC */   break;   \
+                    case 4920000:    ch = 184; /* Japan */  break;   \
+                    case 4940000:    ch = 188; /* Japan */  break;   \
+                    case 4960000:    ch = 192; /* Japan */  break;   \
+                    case 4980000:    ch = 196; /* Japan */  break;   \
+                    case 5040000:    ch = 208; /* Japan, means J08 */  break;   \
+                    case 5060000:    ch = 212; /* Japan, means J12 */  break;   \
+                    case 5080000:    ch = 216; /* Japan, means J16 */  break;   \
+                    default:         ch = 1;     break;     \
+                }                                           \
+            }
+
+//
+// Common fragment list structure -  Identical to the scatter gather frag list structure
+//
+//#define RTMP_SCATTER_GATHER_ELEMENT         SCATTER_GATHER_ELEMENT
+//#define PRTMP_SCATTER_GATHER_ELEMENT        PSCATTER_GATHER_ELEMENT
+#define NIC_MAX_PHYS_BUF_COUNT              8
+
+typedef struct _RTMP_SCATTER_GATHER_ELEMENT {
+    PVOID		Address;
+    ULONG		Length;
+    PULONG		Reserved;
+} RTMP_SCATTER_GATHER_ELEMENT, *PRTMP_SCATTER_GATHER_ELEMENT;
+
+
+typedef struct _RTMP_SCATTER_GATHER_LIST {
+    ULONG  NumberOfElements;
+    PULONG Reserved;
+    RTMP_SCATTER_GATHER_ELEMENT Elements[NIC_MAX_PHYS_BUF_COUNT];
+} RTMP_SCATTER_GATHER_LIST, *PRTMP_SCATTER_GATHER_LIST;
+
+//
+//  Some utility macros
+//
+#ifndef min
+#define min(_a, _b)     (((_a) < (_b)) ? (_a) : (_b))
+#endif
+
+#ifndef max
+#define max(_a, _b)     (((_a) > (_b)) ? (_a) : (_b))
+#endif
+
+#define GET_LNA_GAIN(_pAd)	((_pAd->LatchRfRegs.Channel <= 14) ? (_pAd->BLNAGain) : ((_pAd->LatchRfRegs.Channel <= 64) ? (_pAd->ALNAGain0) : ((_pAd->LatchRfRegs.Channel <= 128) ? (_pAd->ALNAGain1) : (_pAd->ALNAGain2))))
+
+#define INC_COUNTER64(Val)          (Val.QuadPart++)
+
+#define INFRA_ON(_p)                (OPSTATUS_TEST_FLAG(_p, fOP_STATUS_INFRA_ON))
+#define ADHOC_ON(_p)                (OPSTATUS_TEST_FLAG(_p, fOP_STATUS_ADHOC_ON))
+#define MONITOR_ON(_p)              (((_p)->StaCfg.BssType) == BSS_MONITOR)
+#define IDLE_ON(_p)                 (!INFRA_ON(_p) && !ADHOC_ON(_p))
+
+// Check LEAP & CCKM flags
+#define LEAP_ON(_p)                 (((_p)->StaCfg.LeapAuthMode) == CISCO_AuthModeLEAP)
+#define LEAP_CCKM_ON(_p)            ((((_p)->StaCfg.LeapAuthMode) == CISCO_AuthModeLEAP) && ((_p)->StaCfg.LeapAuthInfo.CCKM == TRUE))
+
+// if orginal Ethernet frame contains no LLC/SNAP, then an extra LLC/SNAP encap is required
+#define EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(_pBufVA, _pExtraLlcSnapEncap)		\
+{																\
+	if (((*(_pBufVA + 12) << 8) + *(_pBufVA + 13)) > 1500)		\
+	{															\
+		_pExtraLlcSnapEncap = SNAP_802_1H;						\
+		if (NdisEqualMemory(IPX, _pBufVA + 12, 2) || 			\
+			NdisEqualMemory(APPLE_TALK, _pBufVA + 12, 2))		\
+		{														\
+			_pExtraLlcSnapEncap = SNAP_BRIDGE_TUNNEL;			\
+		}														\
+	}															\
+	else														\
+	{															\
+		_pExtraLlcSnapEncap = NULL;								\
+	}															\
+}
+
+// New Define for new Tx Path.
+#define EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(_pBufVA, _pExtraLlcSnapEncap)	\
+{																\
+	if (((*(_pBufVA) << 8) + *(_pBufVA + 1)) > 1500)			\
+	{															\
+		_pExtraLlcSnapEncap = SNAP_802_1H;						\
+		if (NdisEqualMemory(IPX, _pBufVA, 2) || 				\
+			NdisEqualMemory(APPLE_TALK, _pBufVA, 2))			\
+		{														\
+			_pExtraLlcSnapEncap = SNAP_BRIDGE_TUNNEL;			\
+		}														\
+	}															\
+	else														\
+	{															\
+		_pExtraLlcSnapEncap = NULL;								\
+	}															\
+}
+
+
+#define MAKE_802_3_HEADER(_p, _pMac1, _pMac2, _pType)                   \
+{                                                                       \
+    NdisMoveMemory(_p, _pMac1, MAC_ADDR_LEN);                           \
+    NdisMoveMemory((_p + MAC_ADDR_LEN), _pMac2, MAC_ADDR_LEN);          \
+    NdisMoveMemory((_p + MAC_ADDR_LEN * 2), _pType, LENGTH_802_3_TYPE); \
+}
+
+// if pData has no LLC/SNAP (neither RFC1042 nor Bridge tunnel), keep it that way.
+// else if the received frame is LLC/SNAP-encaped IPX or APPLETALK, preserve the LLC/SNAP field
+// else remove the LLC/SNAP field from the result Ethernet frame
+// Patch for WHQL only, which did not turn on Netbios but use IPX within its payload
+// Note:
+//     _pData & _DataSize may be altered (remove 8-byte LLC/SNAP) by this MACRO
+//     _pRemovedLLCSNAP: pointer to removed LLC/SNAP; NULL is not removed
+#define CONVERT_TO_802_3(_p8023hdr, _pDA, _pSA, _pData, _DataSize, _pRemovedLLCSNAP)      \
+{                                                                       \
+    char LLC_Len[2];                                                    \
+                                                                        \
+    _pRemovedLLCSNAP = NULL;                                            \
+    if (NdisEqualMemory(SNAP_802_1H, _pData, 6)  ||                     \
+        NdisEqualMemory(SNAP_BRIDGE_TUNNEL, _pData, 6))                 \
+    {                                                                   \
+        PUCHAR pProto = _pData + 6;                                     \
+                                                                        \
+        if ((NdisEqualMemory(IPX, pProto, 2) || NdisEqualMemory(APPLE_TALK, pProto, 2)) &&  \
+            NdisEqualMemory(SNAP_802_1H, _pData, 6))                    \
+        {                                                               \
+            LLC_Len[0] = (UCHAR)(_DataSize / 256);                      \
+            LLC_Len[1] = (UCHAR)(_DataSize % 256);                      \
+            MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, LLC_Len);          \
+        }                                                               \
+        else                                                            \
+        {                                                               \
+            MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, pProto);           \
+            _pRemovedLLCSNAP = _pData;                                  \
+            _DataSize -= LENGTH_802_1_H;                                \
+            _pData += LENGTH_802_1_H;                                   \
+        }                                                               \
+    }                                                                   \
+    else                                                                \
+    {                                                                   \
+        LLC_Len[0] = (UCHAR)(_DataSize / 256);                          \
+        LLC_Len[1] = (UCHAR)(_DataSize % 256);                          \
+        MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, LLC_Len);              \
+    }                                                                   \
+}
+
+#define SWITCH_AB( _pAA, _pBB)    \
+{                                                                           \
+    PVOID pCC;                                                          \
+    pCC = _pBB;                                                 \
+    _pBB = _pAA;                                                 \
+    _pAA = pCC;                                                 \
+}
+
+// Enqueue this frame to MLME engine
+// We need to enqueue the whole frame because MLME need to pass data type
+// information from 802.11 header
+#ifdef RT2870
+#define REPORT_MGMT_FRAME_TO_MLME(_pAd, Wcid, _pFrame, _FrameSize, _Rssi0, _Rssi1, _Rssi2, _PlcpSignal)        \
+{                                                                                       \
+    UINT32 High32TSF=0, Low32TSF=0;                                                          \
+    MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (UCHAR)_Rssi0, (UCHAR)_Rssi1,(UCHAR)_Rssi2,_FrameSize, _pFrame, (UCHAR)_PlcpSignal);   \
+}
+#endif // RT2870 //
+
+#ifdef RT30xx
+//Need to collect each ant's rssi concurrently
+//rssi1 is report to pair2 Ant and rss2 is reprot to pair1 Ant when 4 Ant
+#define COLLECT_RX_ANTENNA_AVERAGE_RSSI(_pAd, _rssi1, _rssi2)					\
+{																				\
+	SHORT	AvgRssi;															\
+	UCHAR	UsedAnt;															\
+	if (_pAd->RxAnt.EvaluatePeriod == 0)									\
+	{																		\
+		UsedAnt = _pAd->RxAnt.Pair1PrimaryRxAnt;							\
+		AvgRssi = _pAd->RxAnt.Pair1AvgRssi[UsedAnt];						\
+		if (AvgRssi < 0)													\
+			AvgRssi = AvgRssi - (AvgRssi >> 3) + _rssi1;					\
+		else																\
+			AvgRssi = _rssi1 << 3;											\
+		_pAd->RxAnt.Pair1AvgRssi[UsedAnt] = AvgRssi;						\
+	}																		\
+	else																	\
+	{																		\
+		UsedAnt = _pAd->RxAnt.Pair1SecondaryRxAnt;							\
+		AvgRssi = _pAd->RxAnt.Pair1AvgRssi[UsedAnt];						\
+		if ((AvgRssi < 0) && (_pAd->RxAnt.FirstPktArrivedWhenEvaluate))		\
+			AvgRssi = AvgRssi - (AvgRssi >> 3) + _rssi1;					\
+		else																\
+		{																	\
+			_pAd->RxAnt.FirstPktArrivedWhenEvaluate = TRUE;					\
+			AvgRssi = _rssi1 << 3;											\
+		}																	\
+		_pAd->RxAnt.Pair1AvgRssi[UsedAnt] = AvgRssi;						\
+		_pAd->RxAnt.RcvPktNumWhenEvaluate++;								\
+	}																		\
+}
+#endif // RT30xx //
+
+
+#define NDIS_QUERY_BUFFER(_NdisBuf, _ppVA, _pBufLen)                    \
+    NdisQueryBuffer(_NdisBuf, _ppVA, _pBufLen)
+
+#define MAC_ADDR_EQUAL(pAddr1,pAddr2)           RTMPEqualMemory((PVOID)(pAddr1), (PVOID)(pAddr2), MAC_ADDR_LEN)
+#define SSID_EQUAL(ssid1, len1, ssid2, len2)    ((len1==len2) && (RTMPEqualMemory(ssid1, ssid2, len1)))
+
+//
+// Check if it is Japan W53(ch52,56,60,64) channel.
+//
+#define JapanChannelCheck(channel)  ((channel == 52) || (channel == 56) || (channel == 60) || (channel == 64))
+
+#ifdef CONFIG_STA_SUPPORT
+#define STA_PORT_SECURED(_pAd) \
+{ \
+	_pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; \
+	NdisAcquireSpinLock(&_pAd->MacTabLock); \
+	_pAd->MacTab.Content[BSSID_WCID].PortSecured = _pAd->StaCfg.PortSecured; \
+	NdisReleaseSpinLock(&_pAd->MacTabLock); \
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+//
+// Register set pair for initialzation register set definition
+//
+typedef struct  _RTMP_REG_PAIR
+{
+	ULONG   Register;
+	ULONG   Value;
+} RTMP_REG_PAIR, *PRTMP_REG_PAIR;
+
+typedef struct  _REG_PAIR
+{
+	UCHAR   Register;
+	UCHAR   Value;
+} REG_PAIR, *PREG_PAIR;
+
+//
+// Register set pair for initialzation register set definition
+//
+typedef struct  _RTMP_RF_REGS
+{
+	UCHAR   Channel;
+	ULONG   R1;
+	ULONG   R2;
+	ULONG   R3;
+	ULONG   R4;
+} RTMP_RF_REGS, *PRTMP_RF_REGS;
+
+typedef struct _FREQUENCY_ITEM {
+	UCHAR	Channel;
+	UCHAR	N;
+	UCHAR	R;
+	UCHAR	K;
+} FREQUENCY_ITEM, *PFREQUENCY_ITEM;
+
+//
+//  Data buffer for DMA operation, the buffer must be contiguous physical memory
+//  Both DMA to / from CPU use the same structure.
+//
+typedef struct  _RTMP_DMABUF
+{
+	ULONG                   AllocSize;
+	PVOID                   AllocVa;            // TxBuf virtual address
+	NDIS_PHYSICAL_ADDRESS   AllocPa;            // TxBuf physical address
+} RTMP_DMABUF, *PRTMP_DMABUF;
+
+
+typedef	union	_HEADER_802_11_SEQ{
+#ifdef RT_BIG_ENDIAN
+    struct {
+   	USHORT			Sequence:12;
+	USHORT			Frag:4;
+    }   field;
+#else
+    struct {
+	USHORT			Frag:4;
+	USHORT			Sequence:12;
+    }   field;
+#endif
+    USHORT           value;
+}	HEADER_802_11_SEQ, *PHEADER_802_11_SEQ;
+
+//
+//  Data buffer for DMA operation, the buffer must be contiguous physical memory
+//  Both DMA to / from CPU use the same structure.
+//
+typedef struct  _RTMP_REORDERBUF
+{
+	BOOLEAN			IsFull;
+	PVOID                   AllocVa;            // TxBuf virtual address
+	UCHAR			Header802_3[14];
+	HEADER_802_11_SEQ			Sequence;	//support compressed bitmap BA, so no consider fragment in BA
+	UCHAR 		DataOffset;
+	USHORT 		Datasize;
+	ULONG                   AllocSize;
+#ifdef RT2870
+	PUCHAR					AllocPa;
+#endif // RT2870 //
+}   RTMP_REORDERBUF, *PRTMP_REORDERBUF;
+
+//
+// Control block (Descriptor) for all ring descriptor DMA operation, buffer must be
+// contiguous physical memory. NDIS_PACKET stored the binding Rx packet descriptor
+// which won't be released, driver has to wait until upper layer return the packet
+// before giveing up this rx ring descriptor to ASIC. NDIS_BUFFER is assocaited pair
+// to describe the packet buffer. For Tx, NDIS_PACKET stored the tx packet descriptor
+// which driver should ACK upper layer when the tx is physically done or failed.
+//
+typedef struct _RTMP_DMACB
+{
+	ULONG                   AllocSize;          // Control block size
+	PVOID                   AllocVa;            // Control block virtual address
+	NDIS_PHYSICAL_ADDRESS   AllocPa;            // Control block physical address
+	PNDIS_PACKET pNdisPacket;
+	PNDIS_PACKET pNextNdisPacket;
+
+	RTMP_DMABUF             DmaBuf;             // Associated DMA buffer structure
+} RTMP_DMACB, *PRTMP_DMACB;
+
+typedef struct _RTMP_TX_BUF
+{
+	PQUEUE_ENTRY    Next;
+	UCHAR           Index;
+	ULONG                   AllocSize;          // Control block size
+	PVOID                   AllocVa;            // Control block virtual address
+	NDIS_PHYSICAL_ADDRESS   AllocPa;            // Control block physical address
+} RTMP_TXBUF, *PRTMP_TXBUF;
+
+typedef struct _RTMP_RX_BUF
+{
+	BOOLEAN           InUse;
+	ULONG           	ByBaRecIndex;
+	RTMP_REORDERBUF	MAP_RXBuf[MAX_RX_REORDERBUF];
+} RTMP_RXBUF, *PRTMP_RXBUF;
+typedef struct _RTMP_TX_RING
+{
+	RTMP_DMACB  Cell[TX_RING_SIZE];
+	UINT32		TxCpuIdx;
+	UINT32		TxDmaIdx;
+	UINT32		TxSwFreeIdx; 	// software next free tx index
+} RTMP_TX_RING, *PRTMP_TX_RING;
+
+typedef struct _RTMP_RX_RING
+{
+	RTMP_DMACB  Cell[RX_RING_SIZE];
+	UINT32		RxCpuIdx;
+	UINT32		RxDmaIdx;
+	INT32		RxSwReadIdx; 	// software next read index
+} RTMP_RX_RING, *PRTMP_RX_RING;
+
+typedef struct _RTMP_MGMT_RING
+{
+	RTMP_DMACB  Cell[MGMT_RING_SIZE];
+	UINT32		TxCpuIdx;
+	UINT32		TxDmaIdx;
+	UINT32		TxSwFreeIdx; // software next free tx index
+} RTMP_MGMT_RING, *PRTMP_MGMT_RING;
+
+//
+//  Statistic counter structure
+//
+typedef struct _COUNTER_802_3
+{
+	// General Stats
+	ULONG       GoodTransmits;
+	ULONG       GoodReceives;
+	ULONG       TxErrors;
+	ULONG       RxErrors;
+	ULONG       RxNoBuffer;
+
+	// Ethernet Stats
+	ULONG       RcvAlignmentErrors;
+	ULONG       OneCollision;
+	ULONG       MoreCollisions;
+
+} COUNTER_802_3, *PCOUNTER_802_3;
+
+typedef struct _COUNTER_802_11 {
+	ULONG           Length;
+	LARGE_INTEGER   LastTransmittedFragmentCount;
+	LARGE_INTEGER   TransmittedFragmentCount;
+	LARGE_INTEGER   MulticastTransmittedFrameCount;
+	LARGE_INTEGER   FailedCount;
+	LARGE_INTEGER   RetryCount;
+	LARGE_INTEGER   MultipleRetryCount;
+	LARGE_INTEGER   RTSSuccessCount;
+	LARGE_INTEGER   RTSFailureCount;
+	LARGE_INTEGER   ACKFailureCount;
+	LARGE_INTEGER   FrameDuplicateCount;
+	LARGE_INTEGER   ReceivedFragmentCount;
+	LARGE_INTEGER   MulticastReceivedFrameCount;
+	LARGE_INTEGER   FCSErrorCount;
+} COUNTER_802_11, *PCOUNTER_802_11;
+
+typedef struct _COUNTER_RALINK {
+	ULONG           TransmittedByteCount;   // both successful and failure, used to calculate TX throughput
+	ULONG           ReceivedByteCount;      // both CRC okay and CRC error, used to calculate RX throughput
+	ULONG           BeenDisassociatedCount;
+	ULONG           BadCQIAutoRecoveryCount;
+	ULONG           PoorCQIRoamingCount;
+	ULONG           MgmtRingFullCount;
+	ULONG           RxCountSinceLastNULL;
+	ULONG           RxCount;
+	ULONG           RxRingErrCount;
+	ULONG           KickTxCount;
+	ULONG           TxRingErrCount;
+	LARGE_INTEGER   RealFcsErrCount;
+	ULONG           PendingNdisPacketCount;
+
+	ULONG           OneSecOsTxCount[NUM_OF_TX_RING];
+	ULONG           OneSecDmaDoneCount[NUM_OF_TX_RING];
+	UINT32          OneSecTxDoneCount;
+	ULONG           OneSecRxCount;
+	UINT32          OneSecTxAggregationCount;
+	UINT32          OneSecRxAggregationCount;
+
+	UINT32   		OneSecFrameDuplicateCount;
+
+#ifdef RT2870
+	ULONG           OneSecTransmittedByteCount;   // both successful and failure, used to calculate TX throughput
+#endif // RT2870 //
+
+	UINT32          OneSecTxNoRetryOkCount;
+	UINT32          OneSecTxRetryOkCount;
+	UINT32          OneSecTxFailCount;
+	UINT32          OneSecFalseCCACnt;      // CCA error count, for debug purpose, might move to global counter
+	UINT32          OneSecRxOkCnt;          // RX without error
+	UINT32          OneSecRxOkDataCnt;      // unicast-to-me DATA frame count
+	UINT32          OneSecRxFcsErrCnt;      // CRC error
+	UINT32          OneSecBeaconSentCnt;
+	UINT32          LastOneSecTotalTxCount; // OneSecTxNoRetryOkCount + OneSecTxRetryOkCount + OneSecTxFailCount
+	UINT32          LastOneSecRxOkDataCnt;  // OneSecRxOkDataCnt
+	ULONG		DuplicateRcv;
+	ULONG		TxAggCount;
+	ULONG		TxNonAggCount;
+	ULONG		TxAgg1MPDUCount;
+	ULONG		TxAgg2MPDUCount;
+	ULONG		TxAgg3MPDUCount;
+	ULONG		TxAgg4MPDUCount;
+	ULONG		TxAgg5MPDUCount;
+	ULONG		TxAgg6MPDUCount;
+	ULONG		TxAgg7MPDUCount;
+	ULONG		TxAgg8MPDUCount;
+	ULONG		TxAgg9MPDUCount;
+	ULONG		TxAgg10MPDUCount;
+	ULONG		TxAgg11MPDUCount;
+	ULONG		TxAgg12MPDUCount;
+	ULONG		TxAgg13MPDUCount;
+	ULONG		TxAgg14MPDUCount;
+	ULONG		TxAgg15MPDUCount;
+	ULONG		TxAgg16MPDUCount;
+
+	LARGE_INTEGER       TransmittedOctetsInAMSDU;
+	LARGE_INTEGER       TransmittedAMSDUCount;
+	LARGE_INTEGER       ReceivedOctesInAMSDUCount;
+	LARGE_INTEGER       ReceivedAMSDUCount;
+	LARGE_INTEGER       TransmittedAMPDUCount;
+	LARGE_INTEGER       TransmittedMPDUsInAMPDUCount;
+	LARGE_INTEGER       TransmittedOctetsInAMPDUCount;
+	LARGE_INTEGER       MPDUInReceivedAMPDUCount;
+} COUNTER_RALINK, *PCOUNTER_RALINK;
+
+typedef struct _PID_COUNTER {
+	ULONG           TxAckRequiredCount;      // CRC error
+	ULONG           TxAggreCount;
+	ULONG           TxSuccessCount; // OneSecTxNoRetryOkCount + OneSecTxRetryOkCount + OneSecTxFailCount
+	ULONG		LastSuccessRate;
+} PID_COUNTER, *PPID_COUNTER;
+
+typedef struct _COUNTER_DRS {
+	// to record the each TX rate's quality. 0 is best, the bigger the worse.
+	USHORT          TxQuality[MAX_STEP_OF_TX_RATE_SWITCH];
+	UCHAR           PER[MAX_STEP_OF_TX_RATE_SWITCH];
+	UCHAR           TxRateUpPenalty;      // extra # of second penalty due to last unstable condition
+	ULONG           CurrTxRateStableTime; // # of second in current TX rate
+	BOOLEAN         fNoisyEnvironment;
+	BOOLEAN         fLastSecAccordingRSSI;
+	UCHAR           LastSecTxRateChangeAction; // 0: no change, 1:rate UP, 2:rate down
+	UCHAR			LastTimeTxRateChangeAction; //Keep last time value of LastSecTxRateChangeAction
+	ULONG			LastTxOkCount;
+} COUNTER_DRS, *PCOUNTER_DRS;
+
+//
+//  Arcfour Structure Added by PaulWu
+//
+typedef struct  _ARCFOUR
+{
+	UINT            X;
+	UINT            Y;
+	UCHAR           STATE[256];
+} ARCFOURCONTEXT, *PARCFOURCONTEXT;
+
+// MIMO Tx parameter, ShortGI, MCS, STBC, etc.  these are fields in TXWI too. just copy to TXWI.
+typedef struct  _RECEIVE_SETTING {
+#ifdef RT_BIG_ENDIAN
+	USHORT		MIMO:1;
+	USHORT		OFDM:1;
+	USHORT		rsv:3;
+	USHORT		STBC:2;	//SPACE
+	USHORT		ShortGI:1;
+	USHORT		Mode:2;	//channel bandwidth 20MHz or 40 MHz
+	USHORT   	NumOfRX:2;                 // MIMO. WE HAVE 3R
+#else
+	USHORT   	NumOfRX:2;                 // MIMO. WE HAVE 3R
+	USHORT		Mode:2;	//channel bandwidth 20MHz or 40 MHz
+	USHORT		ShortGI:1;
+	USHORT		STBC:2;	//SPACE
+	USHORT		rsv:3;
+	USHORT		OFDM:1;
+	USHORT		MIMO:1;
+#endif
+ } RECEIVE_SETTING, *PRECEIVE_SETTING;
+
+// Shared key data structure
+typedef struct  _WEP_KEY {
+	UCHAR   KeyLen;                     // Key length for each key, 0: entry is invalid
+	UCHAR   Key[MAX_LEN_OF_KEY];        // right now we implement 4 keys, 128 bits max
+} WEP_KEY, *PWEP_KEY;
+
+typedef struct _CIPHER_KEY {
+	UCHAR   Key[16];            // right now we implement 4 keys, 128 bits max
+	UCHAR   RxMic[8];			// make alignment
+	UCHAR   TxMic[8];
+	UCHAR   TxTsc[6];           // 48bit TSC value
+	UCHAR   RxTsc[6];           // 48bit TSC value
+	UCHAR   CipherAlg;          // 0-none, 1:WEP64, 2:WEP128, 3:TKIP, 4:AES, 5:CKIP64, 6:CKIP128
+	UCHAR   KeyLen;
+#ifdef CONFIG_STA_SUPPORT
+	UCHAR   BssId[6];
+#endif // CONFIG_STA_SUPPORT //
+            // Key length for each key, 0: entry is invalid
+	UCHAR   Type;               // Indicate Pairwise/Group when reporting MIC error
+} CIPHER_KEY, *PCIPHER_KEY;
+
+typedef struct _BBP_TUNING_STRUCT {
+	BOOLEAN     Enable;
+	UCHAR       FalseCcaCountUpperBound;  // 100 per sec
+	UCHAR       FalseCcaCountLowerBound;  // 10 per sec
+	UCHAR       R17LowerBound;            // specified in E2PROM
+	UCHAR       R17UpperBound;            // 0x68 according to David Tung
+	UCHAR       CurrentR17Value;
+} BBP_TUNING, *PBBP_TUNING;
+
+typedef struct _SOFT_RX_ANT_DIVERSITY_STRUCT {
+	UCHAR     EvaluatePeriod;		 // 0:not evalute status, 1: evaluate status, 2: switching status
+	UCHAR     EvaluateStableCnt;
+	UCHAR     Pair1PrimaryRxAnt;     // 0:Ant-E1, 1:Ant-E2
+	UCHAR     Pair1SecondaryRxAnt;   // 0:Ant-E1, 1:Ant-E2
+	UCHAR     Pair2PrimaryRxAnt;     // 0:Ant-E3, 1:Ant-E4
+	UCHAR     Pair2SecondaryRxAnt;   // 0:Ant-E3, 1:Ant-E4
+	SHORT     Pair1AvgRssi[2];       // AvgRssi[0]:E1, AvgRssi[1]:E2
+	SHORT     Pair2AvgRssi[2];       // AvgRssi[0]:E3, AvgRssi[1]:E4
+	SHORT     Pair1LastAvgRssi;      //
+	SHORT     Pair2LastAvgRssi;      //
+	ULONG     RcvPktNumWhenEvaluate;
+	BOOLEAN   FirstPktArrivedWhenEvaluate;
+	RALINK_TIMER_STRUCT    RxAntDiversityTimer;
+} SOFT_RX_ANT_DIVERSITY, *PSOFT_RX_ANT_DIVERSITY;
+
+typedef struct _LEAP_AUTH_INFO {
+	BOOLEAN         Enabled;        //Ture: Enable LEAP Authentication
+	BOOLEAN         CCKM;           //Ture: Use Fast Reauthentication with CCKM
+	UCHAR           Reserve[2];
+	UCHAR           UserName[256];  //LEAP, User name
+	ULONG           UserNameLen;
+	UCHAR           Password[256];  //LEAP, User Password
+	ULONG           PasswordLen;
+} LEAP_AUTH_INFO, *PLEAP_AUTH_INFO;
+
+typedef struct {
+	UCHAR        Addr[MAC_ADDR_LEN];
+	UCHAR        ErrorCode[2];  //00 01-Invalid authentication type
+								//00 02-Authentication timeout
+								//00 03-Challenge from AP failed
+								//00 04-Challenge to AP failed
+	BOOLEAN      Reported;
+} ROGUEAP_ENTRY, *PROGUEAP_ENTRY;
+
+typedef struct {
+	UCHAR               RogueApNr;
+	ROGUEAP_ENTRY       RogueApEntry[MAX_LEN_OF_BSS_TABLE];
+} ROGUEAP_TABLE, *PROGUEAP_TABLE;
+
+typedef struct {
+	BOOLEAN     Enable;
+	UCHAR       Delta;
+	BOOLEAN     PlusSign;
+} CCK_TX_POWER_CALIBRATE, *PCCK_TX_POWER_CALIBRATE;
+
+//
+// Receive Tuple Cache Format
+//
+typedef struct  _TUPLE_CACHE    {
+	BOOLEAN         Valid;
+	UCHAR           MacAddress[MAC_ADDR_LEN];
+	USHORT          Sequence;
+	USHORT          Frag;
+} TUPLE_CACHE, *PTUPLE_CACHE;
+
+//
+// Fragment Frame structure
+//
+typedef struct  _FRAGMENT_FRAME {
+	PNDIS_PACKET    pFragPacket;
+	ULONG       RxSize;
+	USHORT      Sequence;
+	USHORT      LastFrag;
+	ULONG       Flags;          // Some extra frame information. bit 0: LLC presented
+} FRAGMENT_FRAME, *PFRAGMENT_FRAME;
+
+
+//
+// Packet information for NdisQueryPacket
+//
+typedef struct  _PACKET_INFO    {
+	UINT            PhysicalBufferCount;    // Physical breaks of buffer descripor chained
+	UINT            BufferCount ;           // Number of Buffer descriptor chained
+	UINT            TotalPacketLength ;     // Self explained
+	PNDIS_BUFFER    pFirstBuffer;           // Pointer to first buffer descriptor
+} PACKET_INFO, *PPACKET_INFO;
+
+//
+// Tkip Key structure which RC4 key & MIC calculation
+//
+typedef struct  _TKIP_KEY_INFO  {
+	UINT        nBytesInM;  // # bytes in M for MICKEY
+	ULONG       IV16;
+	ULONG       IV32;
+	ULONG       K0;         // for MICKEY Low
+	ULONG       K1;         // for MICKEY Hig
+	ULONG       L;          // Current state for MICKEY
+	ULONG       R;          // Current state for MICKEY
+	ULONG       M;          // Message accumulator for MICKEY
+	UCHAR       RC4KEY[16];
+	UCHAR       MIC[8];
+} TKIP_KEY_INFO, *PTKIP_KEY_INFO;
+
+//
+// Private / Misc data, counters for driver internal use
+//
+typedef struct  __PRIVATE_STRUC {
+	UINT       SystemResetCnt;         // System reset counter
+	UINT       TxRingFullCnt;          // Tx ring full occurrance number
+	UINT       PhyRxErrCnt;            // PHY Rx error count, for debug purpose, might move to global counter
+	// Variables for WEP encryption / decryption in rtmp_wep.c
+	UINT       FCSCRC32;
+	ARCFOURCONTEXT  WEPCONTEXT;
+	// Tkip stuff
+	TKIP_KEY_INFO   Tx;
+	TKIP_KEY_INFO   Rx;
+} PRIVATE_STRUC, *PPRIVATE_STRUC;
+
+// structure to tune BBP R66 (BBP TUNING)
+typedef struct _BBP_R66_TUNING {
+	BOOLEAN     bEnable;
+	USHORT      FalseCcaLowerThreshold;  // default 100
+	USHORT      FalseCcaUpperThreshold;  // default 512
+	UCHAR       R66Delta;
+	UCHAR       R66CurrentValue;
+	BOOLEAN		R66LowerUpperSelect; //Before LinkUp, Used LowerBound or UpperBound as R66 value.
+} BBP_R66_TUNING, *PBBP_R66_TUNING;
+
+// structure to store channel TX power
+typedef struct _CHANNEL_TX_POWER {
+	USHORT     RemainingTimeForUse;		//unit: sec
+	UCHAR      Channel;
+#ifdef DOT11N_DRAFT3
+	BOOLEAN       bEffectedChannel;	// For BW 40 operating in 2.4GHz , the "effected channel" is the channel that is covered in 40Mhz.
+#endif // DOT11N_DRAFT3 //
+	CHAR       Power;
+	CHAR       Power2;
+	UCHAR      MaxTxPwr;
+	UCHAR      DfsReq;
+} CHANNEL_TX_POWER, *PCHANNEL_TX_POWER;
+
+// structure to store 802.11j channel TX power
+typedef struct _CHANNEL_11J_TX_POWER {
+	UCHAR      Channel;
+	UCHAR      BW;	// BW_10 or BW_20
+	CHAR       Power;
+	CHAR       Power2;
+	USHORT     RemainingTimeForUse;		//unit: sec
+} CHANNEL_11J_TX_POWER, *PCHANNEL_11J_TX_POWER;
+
+typedef enum _ABGBAND_STATE_ {
+	UNKNOWN_BAND,
+	BG_BAND,
+	A_BAND,
+} ABGBAND_STATE;
+
+typedef struct _MLME_STRUCT {
+#ifdef CONFIG_STA_SUPPORT
+	// STA state machines
+	STATE_MACHINE           CntlMachine;
+	STATE_MACHINE           AssocMachine;
+	STATE_MACHINE           AuthMachine;
+	STATE_MACHINE           AuthRspMachine;
+	STATE_MACHINE           SyncMachine;
+	STATE_MACHINE           WpaPskMachine;
+	STATE_MACHINE           LeapMachine;
+	STATE_MACHINE           AironetMachine;
+	STATE_MACHINE_FUNC      AssocFunc[ASSOC_FUNC_SIZE];
+	STATE_MACHINE_FUNC      AuthFunc[AUTH_FUNC_SIZE];
+	STATE_MACHINE_FUNC      AuthRspFunc[AUTH_RSP_FUNC_SIZE];
+	STATE_MACHINE_FUNC      SyncFunc[SYNC_FUNC_SIZE];
+	STATE_MACHINE_FUNC      WpaPskFunc[WPA_PSK_FUNC_SIZE];
+	STATE_MACHINE_FUNC      AironetFunc[AIRONET_FUNC_SIZE];
+#endif // CONFIG_STA_SUPPORT //
+	STATE_MACHINE_FUNC      ActFunc[ACT_FUNC_SIZE];
+	// Action
+	STATE_MACHINE           ActMachine;
+
+
+#ifdef QOS_DLS_SUPPORT
+	STATE_MACHINE			DlsMachine;
+	STATE_MACHINE_FUNC      DlsFunc[DLS_FUNC_SIZE];
+#endif // QOS_DLS_SUPPORT //
+
+
+
+
+	ULONG                   ChannelQuality;  // 0..100, Channel Quality Indication for Roaming
+	ULONG                   Now32;           // latch the value of NdisGetSystemUpTime()
+	ULONG                   LastSendNULLpsmTime;
+
+	BOOLEAN                 bRunning;
+	NDIS_SPIN_LOCK          TaskLock;
+	MLME_QUEUE              Queue;
+
+	UINT                    ShiftReg;
+
+	RALINK_TIMER_STRUCT     PeriodicTimer;
+	RALINK_TIMER_STRUCT     APSDPeriodicTimer;
+	RALINK_TIMER_STRUCT     LinkDownTimer;
+	RALINK_TIMER_STRUCT     LinkUpTimer;
+	ULONG                   PeriodicRound;
+	ULONG                   OneSecPeriodicRound;
+
+	UCHAR					RealRxPath;
+	BOOLEAN					bLowThroughput;
+	BOOLEAN					bEnableAutoAntennaCheck;
+	RALINK_TIMER_STRUCT		RxAntEvalTimer;
+
+#ifdef RT30xx
+	UCHAR CaliBW40RfR24;
+	UCHAR CaliBW20RfR24;
+#endif // RT30xx //
+
+} MLME_STRUCT, *PMLME_STRUCT;
+
+// structure for radar detection and channel switch
+typedef struct _RADAR_DETECT_STRUCT {
+    //BOOLEAN		IEEE80211H;			// 0: disable, 1: enable IEEE802.11h
+	UCHAR		CSCount;			//Channel switch counter
+	UCHAR		CSPeriod;			//Channel switch period (beacon count)
+	UCHAR		RDCount;			//Radar detection counter
+	UCHAR		RDMode;				//Radar Detection mode
+	UCHAR		RDDurRegion;		//Radar detection duration region
+	UCHAR		BBPR16;
+	UCHAR		BBPR17;
+	UCHAR		BBPR18;
+	UCHAR		BBPR21;
+	UCHAR		BBPR22;
+	UCHAR		BBPR64;
+	ULONG		InServiceMonitorCount; // unit: sec
+	UINT8		DfsSessionTime;
+	BOOLEAN		bFastDfs;
+	UINT8		ChMovingTime;
+	UINT8		LongPulseRadarTh;
+} RADAR_DETECT_STRUCT, *PRADAR_DETECT_STRUCT;
+
+#ifdef CARRIER_DETECTION_SUPPORT
+typedef enum CD_STATE_n
+{
+	CD_NORMAL,
+	CD_SILENCE,
+	CD_MAX_STATE
+} CD_STATE;
+
+typedef struct CARRIER_DETECTION_s
+{
+	BOOLEAN					Enable;
+	UINT8					CDSessionTime;
+	UINT8					CDPeriod;
+	CD_STATE				CD_State;
+} CARRIER_DETECTION, *PCARRIER_DETECTION;
+#endif // CARRIER_DETECTION_SUPPORT //
+
+typedef enum _REC_BLOCKACK_STATUS
+{
+    Recipient_NONE=0,
+	Recipient_USED,
+	Recipient_HandleRes,
+    Recipient_Accept
+} REC_BLOCKACK_STATUS, *PREC_BLOCKACK_STATUS;
+
+typedef enum _ORI_BLOCKACK_STATUS
+{
+    Originator_NONE=0,
+	Originator_USED,
+    Originator_WaitRes,
+    Originator_Done
+} ORI_BLOCKACK_STATUS, *PORI_BLOCKACK_STATUS;
+
+#ifdef DOT11_N_SUPPORT
+typedef struct _BA_ORI_ENTRY{
+	UCHAR   Wcid;
+	UCHAR   TID;
+	UCHAR   BAWinSize;
+	UCHAR   Token;
+// Sequence is to fill every outgoing QoS DATA frame's sequence field in 802.11 header.
+	USHORT	Sequence;
+	USHORT	TimeOutValue;
+	ORI_BLOCKACK_STATUS  ORI_BA_Status;
+	RALINK_TIMER_STRUCT ORIBATimer;
+	PVOID	pAdapter;
+} BA_ORI_ENTRY, *PBA_ORI_ENTRY;
+
+typedef struct _BA_REC_ENTRY {
+	UCHAR   Wcid;
+	UCHAR   TID;
+	UCHAR   BAWinSize;	// 7.3.1.14. each buffer is capable of holding a max AMSDU or MSDU.
+	//UCHAR	NumOfRxPkt;
+	//UCHAR    Curindidx; // the head in the RX reordering buffer
+	USHORT		LastIndSeq;
+//	USHORT		LastIndSeqAtTimer;
+	USHORT		TimeOutValue;
+	RALINK_TIMER_STRUCT RECBATimer;
+	ULONG		LastIndSeqAtTimer;
+	ULONG		nDropPacket;
+	ULONG		rcvSeq;
+	REC_BLOCKACK_STATUS  REC_BA_Status;
+//	UCHAR	RxBufIdxUsed;
+	// corresponding virtual address for RX reordering packet storage.
+	//RTMP_REORDERDMABUF MAP_RXBuf[MAX_RX_REORDERBUF];
+	NDIS_SPIN_LOCK          RxReRingLock;                 // Rx Ring spinlock
+//	struct _BA_REC_ENTRY *pNext;
+	PVOID	pAdapter;
+	struct reordering_list	list;
+} BA_REC_ENTRY, *PBA_REC_ENTRY;
+
+
+typedef struct {
+	ULONG		numAsRecipient;		// I am recipient of numAsRecipient clients. These client are in the BARecEntry[]
+	ULONG		numAsOriginator;	// I am originator of 	numAsOriginator clients. These clients are in the BAOriEntry[]
+	BA_ORI_ENTRY       BAOriEntry[MAX_LEN_OF_BA_ORI_TABLE];
+	BA_REC_ENTRY       BARecEntry[MAX_LEN_OF_BA_REC_TABLE];
+} BA_TABLE, *PBA_TABLE;
+
+//For QureyBATableOID use;
+typedef struct  PACKED _OID_BA_REC_ENTRY{
+	UCHAR   MACAddr[MAC_ADDR_LEN];
+	UCHAR   BaBitmap;   // if (BaBitmap&(1<<TID)), this session with{MACAddr, TID}exists, so read BufSize[TID] for BufferSize
+	UCHAR   rsv;
+	UCHAR   BufSize[8];
+	REC_BLOCKACK_STATUS	REC_BA_Status[8];
+} OID_BA_REC_ENTRY, *POID_BA_REC_ENTRY;
+
+//For QureyBATableOID use;
+typedef struct  PACKED _OID_BA_ORI_ENTRY{
+	UCHAR   MACAddr[MAC_ADDR_LEN];
+	UCHAR   BaBitmap;  // if (BaBitmap&(1<<TID)), this session with{MACAddr, TID}exists, so read BufSize[TID] for BufferSize, read ORI_BA_Status[TID] for status
+	UCHAR   rsv;
+	UCHAR   BufSize[8];
+	ORI_BLOCKACK_STATUS  ORI_BA_Status[8];
+} OID_BA_ORI_ENTRY, *POID_BA_ORI_ENTRY;
+
+typedef struct _QUERYBA_TABLE{
+	OID_BA_ORI_ENTRY       BAOriEntry[32];
+	OID_BA_REC_ENTRY       BARecEntry[32];
+	UCHAR   OriNum;// Number of below BAOriEntry
+	UCHAR   RecNum;// Number of below BARecEntry
+} QUERYBA_TABLE, *PQUERYBA_TABLE;
+
+typedef	union	_BACAP_STRUC	{
+#ifdef RT_BIG_ENDIAN
+	struct	{
+		UINT32     :4;
+		UINT32     b2040CoexistScanSup:1;		//As Sta, support do 2040 coexistence scan for AP. As Ap, support monitor trigger event to check if can use BW 40MHz.
+		UINT32     bHtAdhoc:1;			// adhoc can use ht rate.
+		UINT32     MMPSmode:2;	// MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable
+		UINT32     AmsduSize:1;	// 0:3839, 1:7935 bytes. UINT  MSDUSizeToBytes[]	= { 3839, 7935};
+		UINT32     AmsduEnable:1;	//Enable AMSDU transmisstion
+		UINT32		MpduDensity:3;
+		UINT32		Policy:2;	// 0: DELAY_BA 1:IMMED_BA  (//BA Policy subfiled value in ADDBA frame)   2:BA-not use
+		UINT32		AutoBA:1;	// automatically BA
+		UINT32		TxBAWinLimit:8;
+		UINT32		RxBAWinLimit:8;
+	}	field;
+#else
+	struct	{
+		UINT32		RxBAWinLimit:8;
+		UINT32		TxBAWinLimit:8;
+		UINT32		AutoBA:1;	// automatically BA
+		UINT32		Policy:2;	// 0: DELAY_BA 1:IMMED_BA  (//BA Policy subfiled value in ADDBA frame)   2:BA-not use
+		UINT32		MpduDensity:3;
+		UINT32       	AmsduEnable:1;	//Enable AMSDU transmisstion
+		UINT32       	AmsduSize:1;	// 0:3839, 1:7935 bytes. UINT  MSDUSizeToBytes[]	= { 3839, 7935};
+		UINT32       	MMPSmode:2;	// MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable
+		UINT32       	bHtAdhoc:1;			// adhoc can use ht rate.
+		UINT32       	b2040CoexistScanSup:1;		//As Sta, support do 2040 coexistence scan for AP. As Ap, support monitor trigger event to check if can use BW 40MHz.
+		UINT32       	:4;
+	}	field;
+#endif
+	UINT32			word;
+} BACAP_STRUC, *PBACAP_STRUC;
+#endif // DOT11_N_SUPPORT //
+
+//This structure is for all 802.11n card InterOptibilityTest action. Reset all Num every n second.  (Details see MLMEPeriodic)
+typedef	struct	_IOT_STRUC	{
+	UCHAR			Threshold[2];
+	UCHAR			ReorderTimeOutNum[MAX_LEN_OF_BA_REC_TABLE];	// compare with threshold[0]
+	UCHAR			RefreshNum[MAX_LEN_OF_BA_REC_TABLE];	// compare with threshold[1]
+	ULONG			OneSecInWindowCount;
+	ULONG			OneSecFrameDuplicateCount;
+	ULONG			OneSecOutWindowCount;
+	UCHAR			DelOriAct;
+	UCHAR			DelRecAct;
+	UCHAR			RTSShortProt;
+	UCHAR			RTSLongProt;
+	BOOLEAN			bRTSLongProtOn;
+#ifdef CONFIG_STA_SUPPORT
+	BOOLEAN			bLastAtheros;
+    BOOLEAN			bCurrentAtheros;
+    BOOLEAN         bNowAtherosBurstOn;
+	BOOLEAN			bNextDisableRxBA;
+    BOOLEAN			bToggle;
+#endif // CONFIG_STA_SUPPORT //
+} IOT_STRUC, *PIOT_STRUC;
+
+// This is the registry setting for 802.11n transmit setting.  Used in advanced page.
+typedef union _REG_TRANSMIT_SETTING {
+#ifdef RT_BIG_ENDIAN
+ struct {
+         UINT32  rsv:13;
+		 UINT32  EXTCHA:2;
+		 UINT32  HTMODE:1;
+		 UINT32  TRANSNO:2;
+		 UINT32  STBC:1; //SPACE
+		 UINT32  ShortGI:1;
+		 UINT32  BW:1; //channel bandwidth 20MHz or 40 MHz
+		 UINT32  TxBF:1; // 3*3
+		 UINT32  rsv0:10;
+		 //UINT32  MCS:7;                 // MCS
+         //UINT32  PhyMode:4;
+    } field;
+#else
+ struct {
+         //UINT32  PhyMode:4;
+         //UINT32  MCS:7;                 // MCS
+		 UINT32  rsv0:10;
+		 UINT32  TxBF:1;
+         UINT32  BW:1; //channel bandwidth 20MHz or 40 MHz
+         UINT32  ShortGI:1;
+         UINT32  STBC:1; //SPACE
+         UINT32  TRANSNO:2;
+         UINT32  HTMODE:1;
+         UINT32  EXTCHA:2;
+         UINT32  rsv:13;
+    } field;
+#endif
+ UINT32   word;
+} REG_TRANSMIT_SETTING, *PREG_TRANSMIT_SETTING;
+
+typedef union  _DESIRED_TRANSMIT_SETTING {
+#ifdef RT_BIG_ENDIAN
+	struct	{
+			USHORT		rsv:3;
+			USHORT		FixedTxMode:2;			// If MCS isn't AUTO, fix rate in CCK, OFDM or HT mode.
+			USHORT		PhyMode:4;
+			USHORT   	MCS:7;                 // MCS
+	}	field;
+#else
+	struct	{
+			USHORT   	MCS:7;                 	// MCS
+			USHORT		PhyMode:4;
+			USHORT	 	FixedTxMode:2;			// If MCS isn't AUTO, fix rate in CCK, OFDM or HT mode.
+			USHORT		rsv:3;
+	}	field;
+#endif
+	USHORT		word;
+ } DESIRED_TRANSMIT_SETTING, *PDESIRED_TRANSMIT_SETTING;
+
+typedef struct {
+	BOOLEAN		IsRecipient;
+	UCHAR   MACAddr[MAC_ADDR_LEN];
+	UCHAR   TID;
+	UCHAR   nMSDU;
+	USHORT   TimeOut;
+	BOOLEAN bAllTid;  // If True, delete all TID for BA sessions with this MACaddr.
+} OID_ADD_BA_ENTRY, *POID_ADD_BA_ENTRY;
+
+//
+// Multiple SSID structure
+//
+#define WLAN_MAX_NUM_OF_TIM			((MAX_LEN_OF_MAC_TABLE >> 3) + 1) /* /8 + 1 */
+#define WLAN_CT_TIM_BCMC_OFFSET		0 /* unit: 32B */
+
+/* clear bcmc TIM bit */
+#define WLAN_MR_TIM_BCMC_CLEAR(apidx) \
+	pAd->ApCfg.MBSSID[apidx].TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] &= ~BIT8[0];
+
+/* set bcmc TIM bit */
+#define WLAN_MR_TIM_BCMC_SET(apidx) \
+	pAd->ApCfg.MBSSID[apidx].TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] |= BIT8[0];
+
+/* clear a station PS TIM bit */
+#define WLAN_MR_TIM_BIT_CLEAR(ad_p, apidx, wcid) \
+	{	UCHAR tim_offset = wcid >> 3; \
+		UCHAR bit_offset = wcid & 0x7; \
+		ad_p->ApCfg.MBSSID[apidx].TimBitmaps[tim_offset] &= (~BIT8[bit_offset]); }
+
+/* set a station PS TIM bit */
+#define WLAN_MR_TIM_BIT_SET(ad_p, apidx, wcid) \
+	{	UCHAR tim_offset = wcid >> 3; \
+		UCHAR bit_offset = wcid & 0x7; \
+		ad_p->ApCfg.MBSSID[apidx].TimBitmaps[tim_offset] |= BIT8[bit_offset]; }
+
+#ifdef RT2870
+#define BEACON_BITMAP_MASK		0xff
+typedef struct _BEACON_SYNC_STRUCT_
+{
+	UCHAR        			BeaconBuf[HW_BEACON_MAX_COUNT][HW_BEACON_OFFSET];
+	UCHAR					BeaconTxWI[HW_BEACON_MAX_COUNT][TXWI_SIZE];
+	ULONG 					TimIELocationInBeacon[HW_BEACON_MAX_COUNT];
+	ULONG					CapabilityInfoLocationInBeacon[HW_BEACON_MAX_COUNT];
+	BOOLEAN					EnableBeacon;		// trigger to enable beacon transmission.
+	UCHAR					BeaconBitMap;		// NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter need to change.
+	UCHAR					DtimBitOn;			// NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter need to change.
+}BEACON_SYNC_STRUCT;
+#endif // RT2870 //
+
+typedef struct _MULTISSID_STRUCT {
+	UCHAR								Bssid[MAC_ADDR_LEN];
+    UCHAR                               SsidLen;
+    CHAR                                Ssid[MAX_LEN_OF_SSID];
+    USHORT                              CapabilityInfo;
+
+    PNET_DEV                   			MSSIDDev;
+
+	NDIS_802_11_AUTHENTICATION_MODE     AuthMode;
+	NDIS_802_11_WEP_STATUS              WepStatus;
+	NDIS_802_11_WEP_STATUS				GroupKeyWepStatus;
+	WPA_MIX_PAIR_CIPHER					WpaMixPairCipher;
+
+	ULONG								TxCount;
+	ULONG								RxCount;
+	ULONG								ReceivedByteCount;
+	ULONG								TransmittedByteCount;
+	ULONG								RxErrorCount;
+	ULONG								RxDropCount;
+
+	HTTRANSMIT_SETTING					HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
+	RT_HT_PHY_INFO						DesiredHtPhyInfo;
+	DESIRED_TRANSMIT_SETTING        	DesiredTransmitSetting; // Desired transmit setting. this is for reading registry setting only. not useful.
+	BOOLEAN								bAutoTxRateSwitch;
+
+	//CIPHER_KEY                          SharedKey[SHARE_KEY_NUM]; // ref pAd->SharedKey[BSS][4]
+	UCHAR                               DefaultKeyId;
+
+	UCHAR								TxRate;       // RATE_1, RATE_2, RATE_5_5, RATE_11, ...
+	UCHAR     							DesiredRates[MAX_LEN_OF_SUPPORTED_RATES];// OID_802_11_DESIRED_RATES
+	UCHAR								DesiredRatesIndex;
+	UCHAR     							MaxTxRate;            // RATE_1, RATE_2, RATE_5_5, RATE_11
+
+//	ULONG           					TimBitmap;      // bit0 for broadcast, 1 for AID1, 2 for AID2, ...so on
+//    ULONG           					TimBitmap2;     // b0 for AID32, b1 for AID33, ... and so on
+	UCHAR								TimBitmaps[WLAN_MAX_NUM_OF_TIM];
+
+    // WPA
+    UCHAR                               GMK[32];
+    UCHAR                               PMK[32];
+	UCHAR								GTK[32];
+    BOOLEAN                             IEEE8021X;
+    BOOLEAN                             PreAuth;
+    UCHAR                               GNonce[32];
+    UCHAR                               PortSecured;
+    NDIS_802_11_PRIVACY_FILTER          PrivacyFilter;
+    UCHAR                               BANClass3Data;
+    ULONG                               IsolateInterStaTraffic;
+
+    UCHAR                               RSNIE_Len[2];
+    UCHAR                               RSN_IE[2][MAX_LEN_OF_RSNIE];
+
+
+    UCHAR                   			TimIELocationInBeacon;
+    UCHAR                   			CapabilityInfoLocationInBeacon;
+    // outgoing BEACON frame buffer and corresponding TXWI
+	// PTXWI_STRUC                           BeaconTxWI; //
+    CHAR                                BeaconBuf[MAX_BEACON_SIZE]; // NOTE: BeaconBuf should be 4-byte aligned
+
+    BOOLEAN                             bHideSsid;
+	UINT16								StationKeepAliveTime; // unit: second
+
+    USHORT                              VLAN_VID;
+    USHORT                              VLAN_Priority;
+
+    RT_802_11_ACL						AccessControlList;
+
+	// EDCA Qos
+    BOOLEAN								bWmmCapable;	// 0:disable WMM, 1:enable WMM
+    BOOLEAN								bDLSCapable;	// 0:disable DLS, 1:enable DLS
+
+	UCHAR           					DlsPTK[64];		// Due to windows dirver count on meetinghouse to handle 4-way shake
+
+	// For 802.1x daemon setting per BSS
+	UCHAR								radius_srv_num;
+	RADIUS_SRV_INFO						radius_srv_info[MAX_RADIUS_SRV_NUM];
+
+#ifdef RTL865X_SOC
+	unsigned int						mylinkid;
+#endif
+
+
+	UINT32					RcvdConflictSsidCount;
+	UINT32					RcvdSpoofedAssocRespCount;
+	UINT32					RcvdSpoofedReassocRespCount;
+	UINT32					RcvdSpoofedProbeRespCount;
+	UINT32					RcvdSpoofedBeaconCount;
+	UINT32					RcvdSpoofedDisassocCount;
+	UINT32					RcvdSpoofedAuthCount;
+	UINT32					RcvdSpoofedDeauthCount;
+	UINT32					RcvdSpoofedUnknownMgmtCount;
+	UINT32					RcvdReplayAttackCount;
+
+	CHAR					RssiOfRcvdConflictSsid;
+	CHAR					RssiOfRcvdSpoofedAssocResp;
+	CHAR					RssiOfRcvdSpoofedReassocResp;
+	CHAR					RssiOfRcvdSpoofedProbeResp;
+	CHAR					RssiOfRcvdSpoofedBeacon;
+	CHAR					RssiOfRcvdSpoofedDisassoc;
+	CHAR					RssiOfRcvdSpoofedAuth;
+	CHAR					RssiOfRcvdSpoofedDeauth;
+	CHAR					RssiOfRcvdSpoofedUnknownMgmt;
+	CHAR					RssiOfRcvdReplayAttack;
+
+	BOOLEAN					bBcnSntReq;
+	UCHAR					BcnBufIdx;
+} MULTISSID_STRUCT, *PMULTISSID_STRUCT;
+
+
+
+#ifdef DOT11N_DRAFT3
+typedef enum _BSS2040COEXIST_FLAG{
+	BSS_2040_COEXIST_DISABLE = 0,
+	BSS_2040_COEXIST_TIMER_FIRED  = 1,
+	BSS_2040_COEXIST_INFO_SYNC = 2,
+	BSS_2040_COEXIST_INFO_NOTIFY = 4,
+}BSS2040COEXIST_FLAG;
+#endif // DOT11N_DRAFT3 //
+
+// configuration common to OPMODE_AP as well as OPMODE_STA
+typedef struct _COMMON_CONFIG {
+
+	BOOLEAN		bCountryFlag;
+	UCHAR		CountryCode[3];
+	UCHAR		Geography;
+	UCHAR       CountryRegion;      // Enum of country region, 0:FCC, 1:IC, 2:ETSI, 3:SPAIN, 4:France, 5:MKK, 6:MKK1, 7:Israel
+	UCHAR       CountryRegionForABand;	// Enum of country region for A band
+	UCHAR       PhyMode;            // PHY_11A, PHY_11B, PHY_11BG_MIXED, PHY_ABG_MIXED
+	USHORT      Dsifs;              // in units of usec
+	ULONG       PacketFilter;       // Packet filter for receiving
+
+	CHAR        Ssid[MAX_LEN_OF_SSID]; // NOT NULL-terminated
+	UCHAR       SsidLen;               // the actual ssid length in used
+	UCHAR       LastSsidLen;               // the actual ssid length in used
+	CHAR        LastSsid[MAX_LEN_OF_SSID]; // NOT NULL-terminated
+	UCHAR		LastBssid[MAC_ADDR_LEN];
+
+	UCHAR       Bssid[MAC_ADDR_LEN];
+	USHORT      BeaconPeriod;
+	UCHAR       Channel;
+	UCHAR       CentralChannel;    	// Central Channel when using 40MHz is indicating. not real channel.
+
+	UCHAR       SupRate[MAX_LEN_OF_SUPPORTED_RATES];
+	UCHAR       SupRateLen;
+	UCHAR       ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+	UCHAR       ExtRateLen;
+	UCHAR       DesireRate[MAX_LEN_OF_SUPPORTED_RATES];      // OID_802_11_DESIRED_RATES
+	UCHAR       MaxDesiredRate;
+	UCHAR       ExpectedACKRate[MAX_LEN_OF_SUPPORTED_RATES];
+
+	ULONG       BasicRateBitmap;        // backup basic ratebitmap
+
+	BOOLEAN		bAPSDCapable;
+	BOOLEAN		bInServicePeriod;
+	BOOLEAN		bAPSDAC_BE;
+	BOOLEAN		bAPSDAC_BK;
+	BOOLEAN		bAPSDAC_VI;
+	BOOLEAN		bAPSDAC_VO;
+	BOOLEAN		bNeedSendTriggerFrame;
+	BOOLEAN		bAPSDForcePowerSave;	// Force power save mode, should only use in APSD-STAUT
+	ULONG		TriggerTimerCount;
+	UCHAR		MaxSPLength;
+	UCHAR		BBPCurrentBW;	// BW_10, 	BW_20, BW_40
+	// move to MULTISSID_STRUCT for MBSS
+	//HTTRANSMIT_SETTING	HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
+	REG_TRANSMIT_SETTING        RegTransmitSetting; //registry transmit setting. this is for reading registry setting only. not useful.
+	//UCHAR       FixedTxMode;              // Fixed Tx Mode (CCK, OFDM), for HT fixed tx mode (GF, MIX) , refer to RegTransmitSetting.field.HTMode
+	UCHAR       TxRate;                 // Same value to fill in TXD. TxRate is 6-bit
+	UCHAR       MaxTxRate;              // RATE_1, RATE_2, RATE_5_5, RATE_11
+	UCHAR       TxRateIndex;            // Tx rate index in RateSwitchTable
+	UCHAR       TxRateTableSize;        // Valid Tx rate table size in RateSwitchTable
+	//BOOLEAN		bAutoTxRateSwitch;
+	UCHAR       MinTxRate;              // RATE_1, RATE_2, RATE_5_5, RATE_11
+	UCHAR       RtsRate;                // RATE_xxx
+	HTTRANSMIT_SETTING	MlmeTransmit;   // MGMT frame PHY rate setting when operatin at Ht rate.
+	UCHAR       MlmeRate;               // RATE_xxx, used to send MLME frames
+	UCHAR       BasicMlmeRate;          // Default Rate for sending MLME frames
+
+	USHORT      RtsThreshold;           // in unit of BYTE
+	USHORT      FragmentThreshold;      // in unit of BYTE
+
+	UCHAR       TxPower;                // in unit of mW
+	ULONG       TxPowerPercentage;      // 0~100 %
+	ULONG       TxPowerDefault;         // keep for TxPowerPercentage
+
+#ifdef DOT11_N_SUPPORT
+	BACAP_STRUC        BACapability; //   NO USE = 0XFF  ;  IMMED_BA =1  ;  DELAY_BA=0
+	BACAP_STRUC        REGBACapability; //   NO USE = 0XFF  ;  IMMED_BA =1  ;  DELAY_BA=0
+#endif // DOT11_N_SUPPORT //
+	IOT_STRUC		IOTestParm;	// 802.11n InterOpbility Test Parameter;
+	ULONG       TxPreamble;             // Rt802_11PreambleLong, Rt802_11PreambleShort, Rt802_11PreambleAuto
+	BOOLEAN     bUseZeroToDisableFragment;     // Microsoft use 0 as disable
+	ULONG       UseBGProtection;        // 0: auto, 1: always use, 2: always not use
+	BOOLEAN     bUseShortSlotTime;      // 0: disable, 1 - use short slot (9us)
+	BOOLEAN     bEnableTxBurst;         // 1: enble TX PACKET BURST, 0: disable TX PACKET BURST
+	BOOLEAN     bAggregationCapable;      // 1: enable TX aggregation when the peer supports it
+	BOOLEAN     bPiggyBackCapable;		// 1: enable TX piggy-back according MAC's version
+	BOOLEAN     bIEEE80211H;			// 1: enable IEEE802.11h spec.
+	ULONG		DisableOLBCDetect;		// 0: enable OLBC detect; 1 disable OLBC detect
+
+#ifdef DOT11_N_SUPPORT
+	BOOLEAN				bRdg;
+#endif // DOT11_N_SUPPORT //
+	BOOLEAN             bWmmCapable;        // 0:disable WMM, 1:enable WMM
+	QOS_CAPABILITY_PARM APQosCapability;    // QOS capability of the current associated AP
+	EDCA_PARM           APEdcaParm;         // EDCA parameters of the current associated AP
+	QBSS_LOAD_PARM      APQbssLoad;         // QBSS load of the current associated AP
+	UCHAR               AckPolicy[4];       // ACK policy of the specified AC. see ACK_xxx
+#ifdef CONFIG_STA_SUPPORT
+	BOOLEAN				bDLSCapable;		// 0:disable DLS, 1:enable DLS
+#endif // CONFIG_STA_SUPPORT //
+	// a bitmap of BOOLEAN flags. each bit represent an operation status of a particular
+	// BOOLEAN control, either ON or OFF. These flags should always be accessed via
+	// OPSTATUS_TEST_FLAG(), OPSTATUS_SET_FLAG(), OP_STATUS_CLEAR_FLAG() macros.
+	// see fOP_STATUS_xxx in RTMP_DEF.C for detail bit definition
+	ULONG               OpStatusFlags;
+
+	BOOLEAN				NdisRadioStateOff; //For HCT 12.0, set this flag to TRUE instead of called MlmeRadioOff.
+	ABGBAND_STATE		BandState;		// For setting BBP used on B/G or A mode.
+	BOOLEAN				bRxAntDiversity; // 0:disable, 1:enable Software Rx Antenna Diversity.
+
+	// IEEE802.11H--DFS.
+	RADAR_DETECT_STRUCT	RadarDetect;
+
+#ifdef CARRIER_DETECTION_SUPPORT
+	CARRIER_DETECTION		CarrierDetect;
+#endif // CARRIER_DETECTION_SUPPORT //
+
+#ifdef DOT11_N_SUPPORT
+	// HT
+	UCHAR			BASize;		// USer desired BAWindowSize. Should not exceed our max capability
+	//RT_HT_CAPABILITY	SupportedHtPhy;
+	RT_HT_CAPABILITY	DesiredHtPhy;
+	HT_CAPABILITY_IE		HtCapability;
+	ADD_HT_INFO_IE		AddHTInfo;	// Useful as AP.
+	//This IE is used with channel switch announcement element when changing to a new 40MHz.
+	//This IE is included in channel switch ammouncement frames 7.4.1.5, beacons, probe Rsp.
+	NEW_EXT_CHAN_IE	NewExtChanOffset;	//7.3.2.20A, 1 if extension channel is above the control channel, 3 if below, 0 if not present
+
+#ifdef DOT11N_DRAFT3
+	UCHAR					Bss2040CoexistFlag;		// bit 0: bBssCoexistTimerRunning, bit 1: NeedSyncAddHtInfo.
+	RALINK_TIMER_STRUCT	Bss2040CoexistTimer;
+
+	//This IE is used for 20/40 BSS Coexistence.
+	BSS_2040_COEXIST_IE		BSS2040CoexistInfo;
+	// ====== 11n D3.0 =======================>
+	USHORT					Dot11OBssScanPassiveDwell;				// Unit : TU. 5~1000
+	USHORT					Dot11OBssScanActiveDwell;				// Unit : TU. 10~1000
+	USHORT					Dot11BssWidthTriggerScanInt;			// Unit : Second
+	USHORT					Dot11OBssScanPassiveTotalPerChannel;	// Unit : TU. 200~10000
+	USHORT					Dot11OBssScanActiveTotalPerChannel;	// Unit : TU. 20~10000
+	USHORT					Dot11BssWidthChanTranDelayFactor;
+	USHORT					Dot11OBssScanActivityThre;				// Unit : percentage
+
+	ULONG					Dot11BssWidthChanTranDelay;			// multiple of (Dot11BssWidthTriggerScanInt * Dot11BssWidthChanTranDelayFactor)
+	ULONG					CountDownCtr;	// CountDown Counter from (Dot11BssWidthTriggerScanInt * Dot11BssWidthChanTranDelayFactor)
+
+	NDIS_SPIN_LOCK          TriggerEventTabLock;
+	BSS_2040_COEXIST_IE		LastBSSCoexist2040;
+	BSS_2040_COEXIST_IE		BSSCoexist2040;
+	TRIGGER_EVENT_TAB		TriggerEventTab;
+	UCHAR					ChannelListIdx;
+	// <====== 11n D3.0 =======================
+	BOOLEAN					bOverlapScanning;
+#endif // DOT11N_DRAFT3 //
+
+    BOOLEAN                 bHTProtect;
+    BOOLEAN                 bMIMOPSEnable;
+    BOOLEAN					bBADecline;
+	BOOLEAN					bDisableReordering;
+	BOOLEAN					bForty_Mhz_Intolerant;
+	BOOLEAN					bExtChannelSwitchAnnouncement;
+	BOOLEAN					bRcvBSSWidthTriggerEvents;
+	ULONG					LastRcvBSSWidthTriggerEventsTime;
+
+	UCHAR					TxBASize;
+#endif // DOT11_N_SUPPORT //
+
+	// Enable wireless event
+	BOOLEAN				bWirelessEvent;
+	BOOLEAN				bWiFiTest;				// Enable this parameter for WiFi test
+
+	// Tx & Rx Stream number selection
+	UCHAR				TxStream;
+	UCHAR				RxStream;
+
+	// transmit phy mode, trasmit rate for Multicast.
+#ifdef MCAST_RATE_SPECIFIC
+	UCHAR				McastTransmitMcs;
+	UCHAR				McastTransmitPhyMode;
+#endif // MCAST_RATE_SPECIFIC //
+
+	BOOLEAN     		bHardwareRadio;     // Hardware controlled Radio enabled
+
+#ifdef RT2870
+	BOOLEAN     		bMultipleIRP;       // Multiple Bulk IN flag
+	UCHAR       		NumOfBulkInIRP;     // if bMultipleIRP == TRUE, NumOfBulkInIRP will be 4 otherwise be 1
+ 	RT_HT_CAPABILITY	SupportedHtPhy;
+	ULONG				MaxPktOneTxBulk;
+	UCHAR				TxBulkFactor;
+	UCHAR				RxBulkFactor;
+
+	BEACON_SYNC_STRUCT	*pBeaconSync;
+	RALINK_TIMER_STRUCT	BeaconUpdateTimer;
+	UINT32				BeaconAdjust;
+	UINT32				BeaconFactor;
+	UINT32				BeaconRemain;
+#endif // RT2870 //
+
+
+ 	NDIS_SPIN_LOCK			MeasureReqTabLock;
+	PMEASURE_REQ_TAB		pMeasureReqTab;
+
+	NDIS_SPIN_LOCK			TpcReqTabLock;
+	PTPC_REQ_TAB			pTpcReqTab;
+
+	// transmit phy mode, trasmit rate for Multicast.
+#ifdef MCAST_RATE_SPECIFIC
+	HTTRANSMIT_SETTING		MCastPhyMode;
+#endif // MCAST_RATE_SPECIFIC //
+
+#ifdef SINGLE_SKU
+	UINT16					DefineMaxTxPwr;
+#endif // SINGLE_SKU //
+
+
+} COMMON_CONFIG, *PCOMMON_CONFIG;
+
+
+#ifdef CONFIG_STA_SUPPORT
+/* Modified by Wu Xi-Kun 4/21/2006 */
+// STA configuration and status
+typedef struct _STA_ADMIN_CONFIG {
+	// GROUP 1 -
+	//   User configuration loaded from Registry, E2PROM or OID_xxx. These settings describe
+	//   the user intended configuration, but not necessary fully equal to the final
+	//   settings in ACTIVE BSS after negotiation/compromize with the BSS holder (either
+	//   AP or IBSS holder).
+	//   Once initialized, user configuration can only be changed via OID_xxx
+	UCHAR       BssType;              // BSS_INFRA or BSS_ADHOC
+	USHORT      AtimWin;          // used when starting a new IBSS
+
+	// GROUP 2 -
+	//   User configuration loaded from Registry, E2PROM or OID_xxx. These settings describe
+	//   the user intended configuration, and should be always applied to the final
+	//   settings in ACTIVE BSS without compromising with the BSS holder.
+	//   Once initialized, user configuration can only be changed via OID_xxx
+	UCHAR       RssiTrigger;
+	UCHAR       RssiTriggerMode;      // RSSI_TRIGGERED_UPON_BELOW_THRESHOLD or RSSI_TRIGGERED_UPON_EXCCEED_THRESHOLD
+	USHORT      DefaultListenCount;   // default listen count;
+	ULONG       WindowsPowerMode;           // Power mode for AC power
+	ULONG       WindowsBatteryPowerMode;    // Power mode for battery if exists
+	BOOLEAN     bWindowsACCAMEnable;        // Enable CAM power mode when AC on
+	BOOLEAN     bAutoReconnect;         // Set to TRUE when setting OID_802_11_SSID with no matching BSSID
+	ULONG       WindowsPowerProfile;    // Windows power profile, for NDIS5.1 PnP
+
+	// MIB:ieee802dot11.dot11smt(1).dot11StationConfigTable(1)
+	USHORT      Psm;                  // power management mode   (PWR_ACTIVE|PWR_SAVE)
+	USHORT      DisassocReason;
+	UCHAR       DisassocSta[MAC_ADDR_LEN];
+	USHORT      DeauthReason;
+	UCHAR       DeauthSta[MAC_ADDR_LEN];
+	USHORT      AuthFailReason;
+	UCHAR       AuthFailSta[MAC_ADDR_LEN];
+
+	NDIS_802_11_PRIVACY_FILTER          PrivacyFilter;  // PrivacyFilter enum for 802.1X
+	NDIS_802_11_AUTHENTICATION_MODE     AuthMode;       // This should match to whatever microsoft defined
+	NDIS_802_11_WEP_STATUS              WepStatus;
+	NDIS_802_11_WEP_STATUS				OrigWepStatus;	// Original wep status set from OID
+
+	// Add to support different cipher suite for WPA2/WPA mode
+	NDIS_802_11_ENCRYPTION_STATUS		GroupCipher;		// Multicast cipher suite
+	NDIS_802_11_ENCRYPTION_STATUS		PairCipher;			// Unicast cipher suite
+	BOOLEAN								bMixCipher;			// Indicate current Pair & Group use different cipher suites
+	USHORT								RsnCapability;
+
+	NDIS_802_11_WEP_STATUS              GroupKeyWepStatus;
+
+	UCHAR		PMK[32];                // WPA PSK mode PMK
+	UCHAR       PTK[64];                // WPA PSK mode PTK
+	UCHAR		GTK[32];				// GTK from authenticator
+	BSSID_INFO	SavedPMK[PMKID_NO];
+	UINT		SavedPMKNum;			// Saved PMKID number
+
+	UCHAR		DefaultKeyId;
+
+
+	// WPA 802.1x port control, WPA_802_1X_PORT_SECURED, WPA_802_1X_PORT_NOT_SECURED
+	UCHAR       PortSecured;
+
+	// For WPA countermeasures
+	ULONG       LastMicErrorTime;   // record last MIC error time
+	ULONG       MicErrCnt;          // Should be 0, 1, 2, then reset to zero (after disassoiciation).
+	BOOLEAN     bBlockAssoc;        // Block associate attempt for 60 seconds after counter measure occurred.
+	// For WPA-PSK supplicant state
+	WPA_STATE   WpaState;           // Default is SS_NOTUSE and handled by microsoft 802.1x
+	UCHAR       ReplayCounter[8];
+	UCHAR       ANonce[32];         // ANonce for WPA-PSK from aurhenticator
+	UCHAR       SNonce[32];         // SNonce for WPA-PSK
+
+	UCHAR       LastSNR0;             // last received BEACON's SNR
+	UCHAR       LastSNR1;            // last received BEACON's SNR for 2nd  antenna
+	RSSI_SAMPLE RssiSample;
+	ULONG       NumOfAvgRssiSample;
+
+	ULONG       LastBeaconRxTime;     // OS's timestamp of the last BEACON RX time
+	ULONG       Last11bBeaconRxTime;  // OS's timestamp of the last 11B BEACON RX time
+	ULONG		Last11gBeaconRxTime;	// OS's timestamp of the last 11G BEACON RX time
+	ULONG		Last20NBeaconRxTime;	// OS's timestamp of the last 20MHz N BEACON RX time
+
+	ULONG       LastScanTime;       // Record last scan time for issue BSSID_SCAN_LIST
+	ULONG       ScanCnt;            // Scan counts since most recent SSID, BSSID, SCAN OID request
+	BOOLEAN     bSwRadio;           // Software controlled Radio On/Off, TRUE: On
+	BOOLEAN     bHwRadio;           // Hardware controlled Radio On/Off, TRUE: On
+	BOOLEAN     bRadio;             // Radio state, And of Sw & Hw radio state
+	BOOLEAN     bHardwareRadio;     // Hardware controlled Radio enabled
+	BOOLEAN     bShowHiddenSSID;    // Show all known SSID in SSID list get operation
+
+    //BOOLEAN		AdhocBOnlyJoined;	// Indicate Adhoc B Join.
+    //BOOLEAN		AdhocBGJoined;		// Indicate Adhoc B/G Join.
+    //BOOLEAN		Adhoc20NJoined;		// Indicate Adhoc 20MHz N Join.
+
+	// New for WPA, windows want us to to keep association information and
+	// Fixed IEs from last association response
+	NDIS_802_11_ASSOCIATION_INFORMATION     AssocInfo;
+	USHORT       ReqVarIELen;                // Length of next VIE include EID & Length
+	UCHAR       ReqVarIEs[MAX_VIE_LEN];		// The content saved here should be little-endian format.
+	USHORT       ResVarIELen;                // Length of next VIE include EID & Length
+	UCHAR       ResVarIEs[MAX_VIE_LEN];
+
+	UCHAR       RSNIE_Len;
+	UCHAR       RSN_IE[MAX_LEN_OF_RSNIE];	// The content saved here should be little-endian format.
+
+	// New variables used for CCX 1.0
+	BOOLEAN             bCkipOn;
+	BOOLEAN             bCkipCmicOn;
+	UCHAR               CkipFlag;
+	UCHAR               GIV[3];  //for CCX iv
+	UCHAR               RxSEQ[4];
+	UCHAR               TxSEQ[4];
+	UCHAR               CKIPMIC[4];
+	UCHAR               LeapAuthMode;
+	LEAP_AUTH_INFO      LeapAuthInfo;
+	UCHAR               HashPwd[16];
+	UCHAR               NetworkChallenge[8];
+	UCHAR               NetworkChallengeResponse[24];
+	UCHAR               PeerChallenge[8];
+
+	UCHAR               PeerChallengeResponse[24];
+	UCHAR               SessionKey[16]; //Network session keys (NSK)
+	RALINK_TIMER_STRUCT LeapAuthTimer;
+	ROGUEAP_TABLE       RogueApTab;   //Cisco CCX1 Rogue AP Detection
+
+	// New control flags for CCX
+	CCX_CONTROL         CCXControl;                 // Master administration state
+	BOOLEAN             CCXEnable;                  // Actual CCX state
+	UCHAR               CCXScanChannel;             // Selected channel for CCX beacon request
+	USHORT              CCXScanTime;                // Time out to wait for beacon and probe response
+	UCHAR               CCXReqType;                 // Current processing CCX request type
+	BSS_TABLE           CCXBssTab;                  // BSS Table
+	UCHAR               FrameReportBuf[2048];       // Buffer for creating frame report
+	USHORT              FrameReportLen;             // Current Frame report length
+	ULONG               CLBusyBytes;                // Save the total bytes received durning channel load scan time
+	USHORT              RPIDensity[8];              // Array for RPI density collection
+	// Start address of each BSS table within FrameReportBuf
+	// It's important to update the RxPower of the corresponding Bss
+	USHORT              BssReportOffset[MAX_LEN_OF_BSS_TABLE];
+	USHORT              BeaconToken;                // Token for beacon report
+	ULONG               LastBssIndex;               // Most current reported Bss index
+	RM_REQUEST_ACTION   MeasurementRequest[16];     // Saved measurement request
+	UCHAR               RMReqCnt;                   // Number of measurement request saved.
+	UCHAR               CurrentRMReqIdx;            // Number of measurement request saved.
+	BOOLEAN             ParallelReq;                // Parallel measurement, only one request performed,
+													// It must be the same channel with maximum duration
+	USHORT              ParallelDuration;           // Maximum duration for parallel measurement
+	UCHAR               ParallelChannel;            // Only one channel with parallel measurement
+	USHORT              IAPPToken;                  // IAPP dialog token
+	UCHAR               CCXQosECWMin;               // Cisco QOS ECWMin for AC 0
+	UCHAR               CCXQosECWMax;               // Cisco QOS ECWMax for AC 0
+	// Hack for channel load and noise histogram parameters
+	UCHAR               NHFactor;                   // Parameter for Noise histogram
+	UCHAR               CLFactor;                   // Parameter for channel load
+
+	UCHAR               KRK[16];        //Key Refresh Key.
+	UCHAR               BTK[32];        //Base Transient Key
+	BOOLEAN             CCKMLinkUpFlag;
+	ULONG               CCKMRN;    //(Re)Association request number.
+	LARGE_INTEGER       CCKMBeaconAtJoinTimeStamp;  //TSF timer for Re-assocaite to the new AP
+	UCHAR               AironetCellPowerLimit;      //in dBm
+	UCHAR               AironetIPAddress[4];        //eg. 192.168.1.1
+	BOOLEAN             CCXAdjacentAPReportFlag;    //flag for determining report Assoc Lost time
+	CHAR                CCXAdjacentAPSsid[MAX_LEN_OF_SSID]; //Adjacent AP's SSID report
+	UCHAR               CCXAdjacentAPSsidLen;               // the actual ssid length in used
+	UCHAR               CCXAdjacentAPBssid[MAC_ADDR_LEN];         //Adjacent AP's BSSID report
+	USHORT              CCXAdjacentAPChannel;
+	ULONG               CCXAdjacentAPLinkDownTime;  //for Spec S32.
+
+	RALINK_TIMER_STRUCT	StaQuickResponeForRateUpTimer;
+	BOOLEAN				StaQuickResponeForRateUpTimerRunning;
+
+	UCHAR           	DtimCount;      // 0.. DtimPeriod-1
+	UCHAR           	DtimPeriod;     // default = 3
+
+#ifdef QOS_DLS_SUPPORT
+	RT_802_11_DLS		DLSEntry[MAX_NUM_OF_DLS_ENTRY];
+	UCHAR				DlsReplayCounter[8];
+#endif // QOS_DLS_SUPPORT //
+	////////////////////////////////////////////////////////////////////////////////////////
+	// This is only for WHQL test.
+	BOOLEAN				WhqlTest;
+	////////////////////////////////////////////////////////////////////////////////////////
+
+    RALINK_TIMER_STRUCT WpaDisassocAndBlockAssocTimer;
+    // Fast Roaming
+	BOOLEAN		        bFastRoaming;       // 0:disable fast roaming, 1:enable fast roaming
+	CHAR		        dBmToRoam;          // the condition to roam when receiving Rssi less than this value. It's negative value.
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+    BOOLEAN             IEEE8021X;
+    BOOLEAN             IEEE8021x_required_keys;
+    CIPHER_KEY	        DesireSharedKey[4];	// Record user desired WEP keys
+    UCHAR               DesireSharedKeyId;
+
+    // 0: driver ignores wpa_supplicant
+    // 1: wpa_supplicant initiates scanning and AP selection
+    // 2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters
+    UCHAR               WpaSupplicantUP;
+	UCHAR				WpaSupplicantScanCount;
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+    CHAR                dev_name[16];
+    USHORT              OriDevType;
+
+    BOOLEAN             bTGnWifiTest;
+	BOOLEAN			    bScanReqIsFromWebUI;
+
+	HTTRANSMIT_SETTING				HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
+	DESIRED_TRANSMIT_SETTING       	DesiredTransmitSetting;
+	RT_HT_PHY_INFO					DesiredHtPhyInfo;
+	BOOLEAN							bAutoTxRateSwitch;
+
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+	UCHAR				IEEE80211dClientMode;
+	UCHAR				StaOriCountryCode[3];
+	UCHAR				StaOriGeography;
+#endif // EXT_BUILD_CHANNEL_LIST //
+} STA_ADMIN_CONFIG, *PSTA_ADMIN_CONFIG;
+
+// This data structure keep the current active BSS/IBSS's configuration that this STA
+// had agreed upon joining the network. Which means these parameters are usually decided
+// by the BSS/IBSS creator instead of user configuration. Data in this data structurre
+// is valid only when either ADHOC_ON(pAd) or INFRA_ON(pAd) is TRUE.
+// Normally, after SCAN or failed roaming attempts, we need to recover back to
+// the current active settings.
+typedef struct _STA_ACTIVE_CONFIG {
+	USHORT      Aid;
+	USHORT      AtimWin;                // in kusec; IBSS parameter set element
+	USHORT      CapabilityInfo;
+	USHORT      CfpMaxDuration;
+	USHORT      CfpPeriod;
+
+	// Copy supported rate from desired AP's beacon. We are trying to match
+	// AP's supported and extended rate settings.
+	UCHAR       SupRate[MAX_LEN_OF_SUPPORTED_RATES];
+	UCHAR       ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+	UCHAR       SupRateLen;
+	UCHAR       ExtRateLen;
+	// Copy supported ht from desired AP's beacon. We are trying to match
+	RT_HT_PHY_INFO		SupportedPhyInfo;
+	RT_HT_CAPABILITY	SupportedHtPhy;
+} STA_ACTIVE_CONFIG, *PSTA_ACTIVE_CONFIG;
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef RT2870
+typedef struct   RT_ADD_PAIRWISE_KEY_ENTRY {
+        NDIS_802_11_MAC_ADDRESS         MacAddr;
+        USHORT                          MacTabMatchWCID;        // ASIC
+        CIPHER_KEY      CipherKey;
+} RT_ADD_PAIRWISE_KEY_ENTRY,*PRT_ADD_PAIRWISE_KEY_ENTRY;
+#endif // RT2870 //
+
+// ----------- start of AP --------------------------
+// AUTH-RSP State Machine Aux data structure
+typedef struct _AP_MLME_AUX {
+	UCHAR               Addr[MAC_ADDR_LEN];
+	USHORT              Alg;
+	CHAR                Challenge[CIPHER_TEXT_LEN];
+} AP_MLME_AUX, *PAP_MLME_AUX;
+
+// structure to define WPA Group Key Rekey Interval
+typedef struct PACKED _RT_802_11_WPA_REKEY {
+	ULONG ReKeyMethod;          // mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based
+	ULONG ReKeyInterval;        // time-based: seconds, packet-based: kilo-packets
+} RT_WPA_REKEY,*PRT_WPA_REKEY, RT_802_11_WPA_REKEY, *PRT_802_11_WPA_REKEY;
+
+typedef struct _MAC_TABLE_ENTRY {
+	//Choose 1 from ValidAsWDS and ValidAsCLI  to validize.
+	BOOLEAN		ValidAsCLI;		// Sta mode, set this TRUE after Linkup,too.
+	BOOLEAN		ValidAsWDS;	// This is WDS Entry. only for AP mode.
+	BOOLEAN		ValidAsApCli;   //This is a AP-Client entry, only for AP mode which enable AP-Client functions.
+	BOOLEAN		ValidAsMesh;
+	BOOLEAN		ValidAsDls;	// This is DLS Entry. only for STA mode.
+	BOOLEAN		isCached;
+	BOOLEAN		bIAmBadAtheros;
+
+	UCHAR         	EnqueueEapolStartTimerRunning;  // Enqueue EAPoL-Start for triggering EAP SM
+	//jan for wpa
+	// record which entry revoke MIC Failure , if it leaves the BSS itself, AP won't update aMICFailTime MIB
+	UCHAR           CMTimerRunning;
+	UCHAR           apidx;			// MBSS number
+	UCHAR           RSNIE_Len;
+	UCHAR           RSN_IE[MAX_LEN_OF_RSNIE];
+	UCHAR           ANonce[LEN_KEY_DESC_NONCE];
+	UCHAR           R_Counter[LEN_KEY_DESC_REPLAY];
+	UCHAR           PTK[64];
+	UCHAR           ReTryCounter;
+	RALINK_TIMER_STRUCT                 RetryTimer;
+	RALINK_TIMER_STRUCT					EnqueueStartForPSKTimer;	// A timer which enqueue EAPoL-Start for triggering PSK SM
+	NDIS_802_11_AUTHENTICATION_MODE     AuthMode;   // This should match to whatever microsoft defined
+	NDIS_802_11_WEP_STATUS              WepStatus;
+	AP_WPA_STATE    WpaState;
+	GTK_STATE       GTKState;
+	USHORT          PortSecured;
+	NDIS_802_11_PRIVACY_FILTER  PrivacyFilter;      // PrivacyFilter enum for 802.1X
+	CIPHER_KEY      PairwiseKey;
+	PVOID           pAd;
+    INT				PMKID_CacheIdx;
+    UCHAR			PMKID[LEN_PMKID];
+
+
+	UCHAR           Addr[MAC_ADDR_LEN];
+	UCHAR           PsMode;
+	SST             Sst;
+	AUTH_STATE      AuthState; // for SHARED KEY authentication state machine used only
+	BOOLEAN			IsReassocSta;	// Indicate whether this is a reassociation procedure
+	USHORT          Aid;
+	USHORT          CapabilityInfo;
+	UCHAR           LastRssi;
+	ULONG           NoDataIdleCount;
+	UINT16			StationKeepAliveCount; // unit: second
+	ULONG           PsQIdleCount;
+	QUEUE_HEADER    PsQueue;
+
+	UINT32			StaConnectTime;		// the live time of this station since associated with AP
+
+
+#ifdef DOT11_N_SUPPORT
+	BOOLEAN			bSendBAR;
+	USHORT			NoBADataCountDown;
+
+	UINT32   		CachedBuf[16];		// UINT (4 bytes) for alignment
+	UINT			TxBFCount; // 3*3
+#endif // DOT11_N_SUPPORT //
+	UINT			FIFOCount;
+	UINT			DebugFIFOCount;
+	UINT			DebugTxCount;
+    BOOLEAN			bDlsInit;
+
+
+//====================================================
+//WDS entry needs these
+// rt2860 add this. if ValidAsWDS==TRUE, MatchWDSTabIdx is the index in WdsTab.MacTab
+	UINT			MatchWDSTabIdx;
+	UCHAR           MaxSupportedRate;
+	UCHAR           CurrTxRate;
+	UCHAR           CurrTxRateIndex;
+	// to record the each TX rate's quality. 0 is best, the bigger the worse.
+	USHORT          TxQuality[MAX_STEP_OF_TX_RATE_SWITCH];
+//	USHORT          OneSecTxOkCount;
+	UINT32			OneSecTxNoRetryOkCount;
+	UINT32          OneSecTxRetryOkCount;
+	UINT32          OneSecTxFailCount;
+	UINT32			ContinueTxFailCnt;
+	UINT32          CurrTxRateStableTime; // # of second in current TX rate
+	UCHAR           TxRateUpPenalty;      // extra # of second penalty due to last unstable condition
+//====================================================
+
+
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+	UINT			MatchDlsEntryIdx; // indicate the index in pAd->StaCfg.DLSEntry
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+	BOOLEAN         fNoisyEnvironment;
+	BOOLEAN			fLastSecAccordingRSSI;
+	UCHAR           LastSecTxRateChangeAction; // 0: no change, 1:rate UP, 2:rate down
+	CHAR			LastTimeTxRateChangeAction; //Keep last time value of LastSecTxRateChangeAction
+	ULONG			LastTxOkCount;
+	UCHAR           PER[MAX_STEP_OF_TX_RATE_SWITCH];
+
+	// a bitmap of BOOLEAN flags. each bit represent an operation status of a particular
+	// BOOLEAN control, either ON or OFF. These flags should always be accessed via
+	// CLIENT_STATUS_TEST_FLAG(), CLIENT_STATUS_SET_FLAG(), CLIENT_STATUS_CLEAR_FLAG() macros.
+	// see fOP_STATUS_xxx in RTMP_DEF.C for detail bit definition. fCLIENT_STATUS_AMSDU_INUSED
+	ULONG           ClientStatusFlags;
+
+	// TODO: Shall we move that to DOT11_N_SUPPORT???
+	HTTRANSMIT_SETTING	HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
+
+#ifdef DOT11_N_SUPPORT
+	// HT EWC MIMO-N used parameters
+	USHORT		RXBAbitmap;	// fill to on-chip  RXWI_BA_BITMASK in 8.1.3RX attribute entry format
+	USHORT		TXBAbitmap;	// This bitmap as originator, only keep in software used to mark AMPDU bit in TXWI
+	USHORT		TXAutoBAbitmap;
+	USHORT		BADeclineBitmap;
+	USHORT		BARecWcidArray[NUM_OF_TID];	// The mapping wcid of recipient session. if RXBAbitmap bit is masked
+	USHORT		BAOriWcidArray[NUM_OF_TID]; // The mapping wcid of originator session. if TXBAbitmap bit is masked
+	USHORT		BAOriSequence[NUM_OF_TID]; // The mapping wcid of originator session. if TXBAbitmap bit is masked
+
+	// 802.11n features.
+	UCHAR		MpduDensity;
+	UCHAR		MaxRAmpduFactor;
+	UCHAR		AMsduSize;
+	UCHAR		MmpsMode;	// MIMO power save more.
+
+	HT_CAPABILITY_IE		HTCapability;
+
+#ifdef DOT11N_DRAFT3
+	UCHAR		BSS2040CoexistenceMgmtSupport;
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+
+	BOOLEAN		bAutoTxRateSwitch;
+
+	UCHAR       RateLen;
+	struct _MAC_TABLE_ENTRY *pNext;
+    USHORT      TxSeq[NUM_OF_TID];
+	USHORT		NonQosDataSeq;
+
+	RSSI_SAMPLE	RssiSample;
+
+	UINT32			TXMCSExpected[16];
+	UINT32			TXMCSSuccessful[16];
+	UINT32			TXMCSFailed[16];
+	UINT32			TXMCSAutoFallBack[16][16];
+
+#ifdef CONFIG_STA_SUPPORT
+        ULONG                   LastBeaconRxTime;
+#endif // CONFIG_STA_SUPPORT //
+} MAC_TABLE_ENTRY, *PMAC_TABLE_ENTRY;
+
+typedef struct _MAC_TABLE {
+	USHORT			Size;
+	MAC_TABLE_ENTRY *Hash[HASH_TABLE_SIZE];
+	MAC_TABLE_ENTRY Content[MAX_LEN_OF_MAC_TABLE];
+	QUEUE_HEADER    McastPsQueue;
+	ULONG           PsQIdleCount;
+	BOOLEAN         fAnyStationInPsm;
+	BOOLEAN         fAnyStationBadAtheros;	// Check if any Station is atheros 802.11n Chip.  We need to use RTS/CTS with Atheros 802,.11n chip.
+	BOOLEAN			fAnyTxOPForceDisable;	// Check if it is necessary to disable BE TxOP
+	BOOLEAN			fAllStationAsRalink; 	// Check if all stations are ralink-chipset
+#ifdef DOT11_N_SUPPORT
+	BOOLEAN         fAnyStationIsLegacy;	// Check if I use legacy rate to transmit to my BSS Station/
+	BOOLEAN         fAnyStationNonGF;		// Check if any Station can't support GF.
+	BOOLEAN         fAnyStation20Only;		// Check if any Station can't support GF.
+	BOOLEAN			fAnyStationMIMOPSDynamic; // Check if any Station is MIMO Dynamic
+	BOOLEAN         fAnyBASession;   // Check if there is BA session.  Force turn on RTS/CTS
+#endif // DOT11_N_SUPPORT //
+} MAC_TABLE, *PMAC_TABLE;
+
+#ifdef DOT11_N_SUPPORT
+#define IS_HT_STA(_pMacEntry)	\
+	(_pMacEntry->MaxHTPhyMode.field.MODE >= MODE_HTMIX)
+
+#define IS_HT_RATE(_pMacEntry)	\
+	(_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
+
+#define PEER_IS_HT_RATE(_pMacEntry)	\
+	(_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
+#endif // DOT11_N_SUPPORT //
+
+typedef struct _WDS_ENTRY {
+	BOOLEAN         Valid;
+	UCHAR           Addr[MAC_ADDR_LEN];
+	ULONG           NoDataIdleCount;
+	struct _WDS_ENTRY *pNext;
+} WDS_ENTRY, *PWDS_ENTRY;
+
+typedef struct  _WDS_TABLE_ENTRY {
+	USHORT			Size;
+	UCHAR           WdsAddr[MAC_ADDR_LEN];
+	WDS_ENTRY       *Hash[HASH_TABLE_SIZE];
+	WDS_ENTRY       Content[MAX_LEN_OF_MAC_TABLE];
+	UCHAR           MaxSupportedRate;
+	UCHAR           CurrTxRate;
+	USHORT          TxQuality[MAX_LEN_OF_SUPPORTED_RATES];
+	USHORT          OneSecTxOkCount;
+	USHORT          OneSecTxRetryOkCount;
+	USHORT          OneSecTxFailCount;
+	ULONG           CurrTxRateStableTime; // # of second in current TX rate
+	UCHAR           TxRateUpPenalty;      // extra # of second penalty due to last unstable condition
+} WDS_TABLE_ENTRY, *PWDS_TABLE_ENTRY;
+
+typedef struct _RT_802_11_WDS_ENTRY {
+	PNET_DEV			dev;
+	UCHAR				Valid;
+	UCHAR				PhyMode;
+	UCHAR				PeerWdsAddr[MAC_ADDR_LEN];
+	UCHAR				MacTabMatchWCID;	// ASIC
+	NDIS_802_11_WEP_STATUS  WepStatus;
+	UCHAR					KeyIdx;
+	CIPHER_KEY          	WdsKey;
+	HTTRANSMIT_SETTING				HTPhyMode, MaxHTPhyMode, MinHTPhyMode;
+	RT_HT_PHY_INFO					DesiredHtPhyInfo;
+	BOOLEAN							bAutoTxRateSwitch;
+	DESIRED_TRANSMIT_SETTING       	DesiredTransmitSetting; // Desired transmit setting.
+} RT_802_11_WDS_ENTRY, *PRT_802_11_WDS_ENTRY;
+
+typedef struct _WDS_TABLE {
+	UCHAR               Mode;
+	ULONG               Size;
+	RT_802_11_WDS_ENTRY	WdsEntry[MAX_WDS_ENTRY];
+} WDS_TABLE, *PWDS_TABLE;
+
+typedef struct _APCLI_STRUCT {
+	PNET_DEV				dev;
+#ifdef RTL865X_SOC
+	unsigned int            mylinkid;
+#endif
+	BOOLEAN                 Enable;	// Set it as 1 if the apcli interface was configured to "1"  or by iwpriv cmd "ApCliEnable"
+	BOOLEAN                 Valid;	// Set it as 1 if the apcli interface associated success to remote AP.
+	UCHAR					MacTabWCID;	//WCID value, which point to the entry of ASIC Mac table.
+	UCHAR                   SsidLen;
+	CHAR                    Ssid[MAX_LEN_OF_SSID];
+
+	UCHAR                   CfgSsidLen;
+	CHAR                    CfgSsid[MAX_LEN_OF_SSID];
+	UCHAR                   CfgApCliBssid[ETH_LENGTH_OF_ADDRESS];
+	UCHAR                   CurrentAddress[ETH_LENGTH_OF_ADDRESS];
+
+	ULONG                   ApCliRcvBeaconTime;
+
+	ULONG                   CtrlCurrState;
+	ULONG                   SyncCurrState;
+	ULONG                   AuthCurrState;
+	ULONG                   AssocCurrState;
+	ULONG					WpaPskCurrState;
+
+	USHORT                  AuthReqCnt;
+	USHORT                  AssocReqCnt;
+
+	ULONG                   ClientStatusFlags;
+	UCHAR                   MpduDensity;
+
+	NDIS_802_11_AUTHENTICATION_MODE     AuthMode;   // This should match to whatever microsoft defined
+	NDIS_802_11_WEP_STATUS              WepStatus;
+
+	// Add to support different cipher suite for WPA2/WPA mode
+	NDIS_802_11_ENCRYPTION_STATUS		GroupCipher;		// Multicast cipher suite
+	NDIS_802_11_ENCRYPTION_STATUS		PairCipher;			// Unicast cipher suite
+	BOOLEAN								bMixCipher;			// Indicate current Pair & Group use different cipher suites
+	USHORT								RsnCapability;
+
+	UCHAR		PSK[100];				// reserve PSK key material
+	UCHAR       PSKLen;
+	UCHAR       PMK[32];                // WPA PSK mode PMK
+	//UCHAR       PTK[64];                // WPA PSK mode PTK
+	UCHAR		GTK[32];				// GTK from authenticator
+
+	//CIPHER_KEY		PairwiseKey;
+	CIPHER_KEY      SharedKey[SHARE_KEY_NUM];
+	UCHAR           DefaultKeyId;
+
+	// WPA 802.1x port control, WPA_802_1X_PORT_SECURED, WPA_802_1X_PORT_NOT_SECURED
+	//UCHAR       PortSecured;
+
+	// store RSN_IE built by driver
+	UCHAR		RSN_IE[MAX_LEN_OF_RSNIE];  // The content saved here should be convert to little-endian format.
+	UCHAR		RSNIE_Len;
+
+	// For WPA countermeasures
+	ULONG       LastMicErrorTime;   // record last MIC error time
+	//ULONG       MicErrCnt;          // Should be 0, 1, 2, then reset to zero (after disassoiciation).
+	BOOLEAN                 bBlockAssoc; // Block associate attempt for 60 seconds after counter measure occurred.
+
+	// For WPA-PSK supplicant state
+	//WPA_STATE   	WpaState;           // Default is SS_NOTUSE
+	//UCHAR       	ReplayCounter[8];
+	//UCHAR       	ANonce[32];         // ANonce for WPA-PSK from authenticator
+	UCHAR       	SNonce[32];         // SNonce for WPA-PSK
+	UCHAR			GNonce[32];			// GNonce for WPA-PSK from authenticator
+
+	HTTRANSMIT_SETTING				HTPhyMode, MaxHTPhyMode, MinHTPhyMode;
+	RT_HT_PHY_INFO					DesiredHtPhyInfo;
+	BOOLEAN							bAutoTxRateSwitch;
+	DESIRED_TRANSMIT_SETTING       	DesiredTransmitSetting; // Desired transmit setting.
+} APCLI_STRUCT, *PAPCLI_STRUCT;
+
+// ----------- end of AP ----------------------------
+
+#ifdef BLOCK_NET_IF
+typedef struct _BLOCK_QUEUE_ENTRY
+{
+	BOOLEAN SwTxQueueBlockFlag;
+	LIST_HEADER NetIfList;
+} BLOCK_QUEUE_ENTRY, *PBLOCK_QUEUE_ENTRY;
+#endif // BLOCK_NET_IF //
+
+
+struct wificonf
+{
+	BOOLEAN	bShortGI;
+	BOOLEAN bGreenField;
+};
+
+
+
+
+typedef struct _INF_PCI_CONFIG
+{
+	PUCHAR                  CSRBaseAddress;     // PCI MMIO Base Address, all access will use
+}INF_PCI_CONFIG;
+
+typedef struct _INF_USB_CONFIG
+{
+	UINT                BulkInEpAddr;		// bulk-in endpoint address
+	UINT                BulkOutEpAddr[6];	// bulk-out endpoint address
+
+}INF_USB_CONFIG;
+
+#ifdef IKANOS_VX_1X0
+	typedef void (*IkanosWlanTxCbFuncP)(void *, void *);
+
+	struct IKANOS_TX_INFO
+	{
+		struct net_device *netdev;
+		IkanosWlanTxCbFuncP *fp;
+	};
+#endif // IKANOS_VX_1X0 //
+
+#ifdef NINTENDO_AP
+typedef struct _NINDO_CTRL_BLOCK {
+
+	RT_NINTENDO_TABLE	DS_TABLE;
+
+#ifdef CHIP25XX
+	spinlock_t			NINTENDO_TABLE_Lock;
+#else
+	NDIS_SPIN_LOCK		NINTENDO_TABLE_Lock;
+#endif // CHIP25XX //
+
+	UCHAR				NINTENDO_UP_BUFFER[512];
+	UCHAR				Local_KeyIdx;
+	CIPHER_KEY			Local_SharedKey;
+	UCHAR				Local_bHideSsid;
+	UCHAR				Local_AuthMode;
+	UCHAR				Local_WepStatus;
+	USHORT				Local_CapabilityInfo;
+} NINDO_CTRL_BLOCK;
+#endif // NINTENDO_AP //
+
+
+#ifdef DBG_DIAGNOSE
+#define DIAGNOSE_TIME	10   // 10 sec
+typedef struct _RtmpDiagStrcut_
+{	// Diagnosis Related element
+	unsigned char		inited;
+	unsigned char 	qIdx;
+	unsigned char 	ArrayStartIdx;
+	unsigned char		ArrayCurIdx;
+	// Tx Related Count
+	USHORT			TxDataCnt[DIAGNOSE_TIME];
+	USHORT			TxFailCnt[DIAGNOSE_TIME];
+//	USHORT			TxDescCnt[DIAGNOSE_TIME][16];		// TxDesc queue length in scale of 0~14, >=15
+	USHORT			TxDescCnt[DIAGNOSE_TIME][24]; // 3*3	// TxDesc queue length in scale of 0~14, >=15
+//	USHORT			TxMcsCnt[DIAGNOSE_TIME][16];			// TxDate MCS Count in range from 0 to 15, step in 1.
+	USHORT			TxMcsCnt[DIAGNOSE_TIME][24]; // 3*3
+	USHORT			TxSWQueCnt[DIAGNOSE_TIME][9];		// TxSwQueue length in scale of 0, 1, 2, 3, 4, 5, 6, 7, >=8
+
+	USHORT			TxAggCnt[DIAGNOSE_TIME];
+	USHORT			TxNonAggCnt[DIAGNOSE_TIME];
+//	USHORT			TxAMPDUCnt[DIAGNOSE_TIME][16];		// 10 sec, TxDMA APMDU Aggregation count in range from 0 to 15, in setp of 1.
+	USHORT			TxAMPDUCnt[DIAGNOSE_TIME][24]; // 3*3 // 10 sec, TxDMA APMDU Aggregation count in range from 0 to 15, in setp of 1.
+	USHORT			TxRalinkCnt[DIAGNOSE_TIME];			// TxRalink Aggregation Count in 1 sec scale.
+	USHORT			TxAMSDUCnt[DIAGNOSE_TIME];			// TxAMSUD Aggregation Count in 1 sec scale.
+
+	// Rx Related Count
+	USHORT			RxDataCnt[DIAGNOSE_TIME];			// Rx Total Data count.
+	USHORT			RxCrcErrCnt[DIAGNOSE_TIME];
+//	USHORT			RxMcsCnt[DIAGNOSE_TIME][16];		// Rx MCS Count in range from 0 to 15, step in 1.
+	USHORT			RxMcsCnt[DIAGNOSE_TIME][24]; // 3*3
+}RtmpDiagStruct;
+#endif // DBG_DIAGNOSE //
+
+
+//
+//  The miniport adapter structure
+//
+typedef struct _RTMP_ADAPTER
+{
+	PVOID					OS_Cookie;	// save specific structure relative to OS
+	PNET_DEV				net_dev;
+	ULONG					VirtualIfCnt;
+
+
+
+	NDIS_SPIN_LOCK          irq_lock;
+	UCHAR                   irq_disabled;
+
+#ifdef RT2870
+/*****************************************************************************************/
+/*      USB related parameters                                                           */
+/*****************************************************************************************/
+	struct usb_config_descriptor		*config;
+	UINT								BulkInEpAddr;		// bulk-in endpoint address
+	UINT								BulkOutEpAddr[6];	// bulk-out endpoint address
+
+	UINT								NumberOfPipes;
+	USHORT								BulkOutMaxPacketSize;
+	USHORT								BulkInMaxPacketSize;
+
+	//======Control Flags
+	LONG                    	PendingIoCount;
+	ULONG						BulkFlags;
+	BOOLEAN                     bUsbTxBulkAggre;	// Flags for bulk out data priority
+
+
+	//======Timer Thread
+	RT2870_TIMER_QUEUE		TimerQ;
+	NDIS_SPIN_LOCK			TimerQLock;
+
+
+	//======Cmd Thread
+	CmdQ					CmdQ;
+	NDIS_SPIN_LOCK			CmdQLock;				// CmdQLock spinlock
+
+	BOOLEAN					TimerFunc_kill;
+	BOOLEAN					mlme_kill;
+
+
+	//======Semaphores (event)
+	struct semaphore			mlme_semaphore;			/* to sleep thread on	*/
+	struct semaphore			RTUSBCmd_semaphore;		/* to sleep thread on	*/
+	struct semaphore			RTUSBTimer_semaphore;
+#ifdef INF_AMAZON_SE
+	struct semaphore			UsbVendorReq_semaphore;
+	PVOID						UsbVendorReqBuf;
+#endif // INF_AMAZON_SE //
+	struct completion			TimerQComplete;
+	struct completion			mlmeComplete;
+	struct completion			CmdQComplete;
+	wait_queue_head_t			*wait;
+
+	//======Lock for 2870 ATE
+#ifdef RALINK_ATE
+	NDIS_SPIN_LOCK			GenericLock;		// ATE Tx/Rx generic spinlock
+#endif // RALINK_ATE //
+
+#endif // RT2870 //
+
+
+/*****************************************************************************************/
+	/*      Both PCI/USB related parameters                                                  */
+/*****************************************************************************************/
+
+
+/*****************************************************************************************/
+/*      Tx related parameters                                                           */
+/*****************************************************************************************/
+	BOOLEAN                 DeQueueRunning[NUM_OF_TX_RING];  // for ensuring RTUSBDeQueuePacket get call once
+	NDIS_SPIN_LOCK          DeQueueLock[NUM_OF_TX_RING];
+
+#ifdef RT2870
+	// Data related context and AC specified, 4 AC supported
+	NDIS_SPIN_LOCK			BulkOutLock[6];			// BulkOut spinlock for 4 ACs
+	NDIS_SPIN_LOCK			MLMEBulkOutLock;	// MLME BulkOut lock
+
+	HT_TX_CONTEXT			TxContext[NUM_OF_TX_RING];
+	NDIS_SPIN_LOCK			TxContextQueueLock[NUM_OF_TX_RING];		// TxContextQueue spinlock
+
+	// 4 sets of Bulk Out index and pending flag
+	UCHAR					NextBulkOutIndex[4];	// only used for 4 EDCA bulkout pipe
+
+	BOOLEAN					BulkOutPending[6];	// used for total 6 bulkout pipe
+	UCHAR					bulkResetPipeid;
+	BOOLEAN					MgmtBulkPending;
+	ULONG					bulkResetReq[6];
+#endif // RT2870 //
+
+	// resource for software backlog queues
+	QUEUE_HEADER            TxSwQueue[NUM_OF_TX_RING];  // 4 AC + 1 HCCA
+	NDIS_SPIN_LOCK          TxSwQueueLock[NUM_OF_TX_RING];	// TxSwQueue spinlock
+
+	RTMP_DMABUF             MgmtDescRing;               	// Shared memory for MGMT descriptors
+	RTMP_MGMT_RING          MgmtRing;
+	NDIS_SPIN_LOCK          MgmtRingLock;               	// Prio Ring spinlock
+
+
+/*****************************************************************************************/
+/*      Rx related parameters                                                           */
+/*****************************************************************************************/
+
+
+#ifdef RT2870
+	RX_CONTEXT				RxContext[RX_RING_SIZE];  // 1 for redundant multiple IRP bulk in.
+	NDIS_SPIN_LOCK			BulkInLock;				// BulkIn spinlock for 4 ACs
+	UCHAR					PendingRx;				// The Maxima pending Rx value should be 	RX_RING_SIZE.
+	UCHAR					NextRxBulkInIndex;		// Indicate the current RxContext Index which hold by Host controller.
+	UCHAR					NextRxBulkInReadIndex;	// Indicate the current RxContext Index which driver can read & process it.
+	ULONG					NextRxBulkInPosition;   // Want to contatenate 2 URB buffer while 1st is bulkin failed URB. This Position is 1st URB TransferLength.
+	ULONG					TransferBufferLength;	// current length of the packet buffer
+	ULONG					ReadPosition;			// current read position in a packet buffer
+#endif // RT2870 //
+
+
+/*****************************************************************************************/
+/*      ASIC related parameters                                                          */
+/*****************************************************************************************/
+	UINT32               	MACVersion;      	// MAC version. Record rt2860C(0x28600100) or rt2860D (0x28600101)..
+
+	// ---------------------------
+	// E2PROM
+	// ---------------------------
+	ULONG                   EepromVersion;          // byte 0: version, byte 1: revision, byte 2~3: unused
+	UCHAR                   EEPROMAddressNum;       // 93c46=6  93c66=8
+	USHORT                  EEPROMDefaultValue[NUM_EEPROM_BBP_PARMS];
+	BOOLEAN                 EepromAccess;
+	UCHAR                   EFuseTag;
+	ULONG                   FirmwareVersion;        // byte 0: Minor version, byte 1: Major version, otherwise unused.
+
+	// ---------------------------
+	// BBP Control
+	// ---------------------------
+	UCHAR                   BbpWriteLatch[140];     // record last BBP register value written via BBP_IO_WRITE/BBP_IO_WRITE_VY_REG_ID
+	UCHAR                   BbpRssiToDbmDelta;
+	BBP_R66_TUNING          BbpTuning;
+
+	// ----------------------------
+	// RFIC control
+	// ----------------------------
+	UCHAR                   RfIcType;       // RFIC_xxx
+	ULONG                   RfFreqOffset;   // Frequency offset for channel switching
+	RTMP_RF_REGS            LatchRfRegs;    // latch th latest RF programming value since RF IC doesn't support READ
+
+	EEPROM_ANTENNA_STRUC    Antenna;                            // Since ANtenna definition is different for a & g. We need to save it for future reference.
+	EEPROM_NIC_CONFIG2_STRUC    NicConfig2;
+
+	// This soft Rx Antenna Diversity mechanism is used only when user set
+	// RX Antenna = DIVERSITY ON
+	SOFT_RX_ANT_DIVERSITY   RxAnt;
+
+	UCHAR                   RFProgSeq;
+	CHANNEL_TX_POWER        TxPower[MAX_NUM_OF_CHANNELS];       // Store Tx power value for all channels.
+	CHANNEL_TX_POWER        ChannelList[MAX_NUM_OF_CHANNELS];   // list all supported channels for site survey
+	CHANNEL_11J_TX_POWER    TxPower11J[MAX_NUM_OF_11JCHANNELS];       // 802.11j channel and bw
+	CHANNEL_11J_TX_POWER    ChannelList11J[MAX_NUM_OF_11JCHANNELS];   // list all supported channels for site survey
+
+	UCHAR                   ChannelListNum;                     // number of channel in ChannelList[]
+	UCHAR					Bbp94;
+	BOOLEAN					BbpForCCK;
+	ULONG		Tx20MPwrCfgABand[5];
+	ULONG		Tx20MPwrCfgGBand[5];
+	ULONG		Tx40MPwrCfgABand[5];
+	ULONG		Tx40MPwrCfgGBand[5];
+
+	BOOLEAN     bAutoTxAgcA;                // Enable driver auto Tx Agc control
+	UCHAR	    TssiRefA;					// Store Tssi reference value as 25 temperature.
+	UCHAR	    TssiPlusBoundaryA[5];		// Tssi boundary for increase Tx power to compensate.
+	UCHAR	    TssiMinusBoundaryA[5];		// Tssi boundary for decrease Tx power to compensate.
+	UCHAR	    TxAgcStepA;					// Store Tx TSSI delta increment / decrement value
+	CHAR		TxAgcCompensateA;			// Store the compensation (TxAgcStep * (idx-1))
+
+	BOOLEAN     bAutoTxAgcG;                // Enable driver auto Tx Agc control
+	UCHAR	    TssiRefG;					// Store Tssi reference value as 25 temperature.
+	UCHAR	    TssiPlusBoundaryG[5];		// Tssi boundary for increase Tx power to compensate.
+	UCHAR	    TssiMinusBoundaryG[5];		// Tssi boundary for decrease Tx power to compensate.
+	UCHAR	    TxAgcStepG;					// Store Tx TSSI delta increment / decrement value
+	CHAR		TxAgcCompensateG;			// Store the compensation (TxAgcStep * (idx-1))
+
+	//+++For RT2870, the parameteres is start from BGRssiOffset1 ~ BGRssiOffset3
+	CHAR		BGRssiOffset0;				// Store B/G RSSI#0 Offset value on EEPROM 0x46h
+	CHAR		BGRssiOffset1;				// Store B/G RSSI#1 Offset value
+	CHAR		BGRssiOffset2;				// Store B/G RSSI#2 Offset value
+	//---
+
+	//+++For RT2870, the parameteres is start from ARssiOffset1 ~ ARssiOffset3
+	CHAR		ARssiOffset0;				// Store A RSSI#0 Offset value on EEPROM 0x4Ah
+	CHAR		ARssiOffset1;				// Store A RSSI#1 Offset value
+	CHAR		ARssiOffset2;				// Store A RSSI#2 Offset value
+	//---
+
+	CHAR		BLNAGain;					// Store B/G external LNA#0 value on EEPROM 0x44h
+	CHAR		ALNAGain0;					// Store A external LNA#0 value for ch36~64
+	CHAR		ALNAGain1;					// Store A external LNA#1 value for ch100~128
+	CHAR		ALNAGain2;					// Store A external LNA#2 value for ch132~165
+
+	// ----------------------------
+	// LED control
+	// ----------------------------
+	MCU_LEDCS_STRUC		LedCntl;
+	USHORT				Led1;	// read from EEPROM 0x3c
+	USHORT				Led2;	// EEPROM 0x3e
+	USHORT				Led3;	// EEPROM 0x40
+	UCHAR				LedIndicatorStregth;
+	UCHAR				RssiSingalstrengthOffet;
+    BOOLEAN				bLedOnScanning;
+	UCHAR				LedStatus;
+
+/*****************************************************************************************/
+/*      802.11 related parameters                                                        */
+/*****************************************************************************************/
+	// outgoing BEACON frame buffer and corresponding TXD
+	TXWI_STRUC              	BeaconTxWI;
+	PUCHAR						BeaconBuf;
+	USHORT						BeaconOffset[HW_BEACON_MAX_COUNT];
+
+	// pre-build PS-POLL and NULL frame upon link up. for efficiency purpose.
+	PSPOLL_FRAME            	PsPollFrame;
+	HEADER_802_11           	NullFrame;
+
+#ifdef RT2870
+	TX_CONTEXT				BeaconContext[BEACON_RING_SIZE];
+	TX_CONTEXT				NullContext;
+	TX_CONTEXT				PsPollContext;
+	TX_CONTEXT				RTSContext;
+#endif // RT2870 //
+
+
+
+//=========AP===========
+
+
+//=======STA===========
+#ifdef CONFIG_STA_SUPPORT
+/* Modified by Wu Xi-Kun 4/21/2006 */
+	// -----------------------------------------------
+	// STA specific configuration & operation status
+	// used only when pAd->OpMode == OPMODE_STA
+	// -----------------------------------------------
+	STA_ADMIN_CONFIG        StaCfg;           // user desired settings
+	STA_ACTIVE_CONFIG       StaActive;         // valid only when ADHOC_ON(pAd) || INFRA_ON(pAd)
+	CHAR                    nickname[IW_ESSID_MAX_SIZE+1]; // nickname, only used in the iwconfig i/f
+	NDIS_MEDIA_STATE        PreMediaState;
+#endif // CONFIG_STA_SUPPORT //
+
+//=======Common===========
+	// OP mode: either AP or STA
+	UCHAR                   OpMode;                     // OPMODE_STA, OPMODE_AP
+
+	NDIS_MEDIA_STATE        IndicateMediaState;			// Base on Indication state, default is NdisMediaStateDisConnected
+
+
+	// MAT related parameters
+
+	// configuration: read from Registry & E2PROM
+	BOOLEAN                 bLocalAdminMAC;             // Use user changed MAC
+	UCHAR                   PermanentAddress[MAC_ADDR_LEN];    // Factory default MAC address
+	UCHAR                   CurrentAddress[MAC_ADDR_LEN];      // User changed MAC address
+
+	// ------------------------------------------------------
+	// common configuration to both OPMODE_STA and OPMODE_AP
+	// ------------------------------------------------------
+	COMMON_CONFIG           CommonCfg;
+	MLME_STRUCT             Mlme;
+
+	// AP needs those vaiables for site survey feature.
+	MLME_AUX                MlmeAux;           // temporary settings used during MLME state machine
+	BSS_TABLE               ScanTab;           // store the latest SCAN result
+
+	//About MacTab, the sta driver will use #0 and #1 for multicast and AP.
+	MAC_TABLE                 MacTab;     // ASIC on-chip WCID entry table.  At TX, ASIC always use key according to this on-chip table.
+	NDIS_SPIN_LOCK          MacTabLock;
+
+#ifdef DOT11_N_SUPPORT
+	BA_TABLE			BATable;
+#endif // DOT11_N_SUPPORT //
+	NDIS_SPIN_LOCK          BATabLock;
+	RALINK_TIMER_STRUCT RECBATimer;
+
+	// encryption/decryption KEY tables
+	CIPHER_KEY              SharedKey[MAX_MBSSID_NUM][4]; // STA always use SharedKey[BSS0][0..3]
+
+		// RX re-assembly buffer for fragmentation
+	FRAGMENT_FRAME          FragFrame;                  // Frame storage for fragment frame
+
+	// various Counters
+	COUNTER_802_3           Counters8023;               // 802.3 counters
+	COUNTER_802_11          WlanCounters;               // 802.11 MIB counters
+	COUNTER_RALINK          RalinkCounters;             // Ralink propriety counters
+	COUNTER_DRS             DrsCounters;                // counters for Dynamic TX Rate Switching
+	PRIVATE_STRUC           PrivateInfo;                // Private information & counters
+
+	// flags, see fRTMP_ADAPTER_xxx flags
+	ULONG                   Flags;                      // Represent current device status
+
+	// current TX sequence #
+	USHORT                  Sequence;
+
+#ifdef UNDER_CE
+	NDIS_HANDLE             hGiISR;
+#endif
+
+
+	// Control disconnect / connect event generation
+	//+++Didn't used anymore
+	ULONG                   LinkDownTime;
+	//---
+	ULONG                   LastRxRate;
+	ULONG                   LastTxRate;
+	//+++Used only for Station
+	BOOLEAN                 bConfigChanged;         // Config Change flag for the same SSID setting
+	//---
+
+	ULONG                   ExtraInfo;              // Extra information for displaying status
+	ULONG                   SystemErrorBitmap;      // b0: E2PROM version error
+
+	//+++Didn't used anymore
+	ULONG                   MacIcVersion;           // MAC/BBP serial interface issue solved after ver.D
+	//---
+
+	// ---------------------------
+	// System event log
+	// ---------------------------
+	RT_802_11_EVENT_TABLE   EventTab;
+
+
+	BOOLEAN		HTCEnable;
+
+	/*****************************************************************************************/
+	/*      Statistic related parameters                                                     */
+	/*****************************************************************************************/
+#ifdef RT2870
+	ULONG						BulkOutDataOneSecCount;
+	ULONG						BulkInDataOneSecCount;
+	ULONG						BulkLastOneSecCount; // BulkOutDataOneSecCount + BulkInDataOneSecCount
+	ULONG						watchDogRxCnt;
+	ULONG						watchDogRxOverFlowCnt;
+	ULONG						watchDogTxPendingCnt[NUM_OF_TX_RING];
+#endif // RT2870 //
+
+	BOOLEAN						bUpdateBcnCntDone;
+	ULONG						watchDogMacDeadlock;	// prevent MAC/BBP into deadlock condition
+	// ----------------------------
+	// DEBUG paramerts
+	// ----------------------------
+	//ULONG		DebugSetting[4];
+	BOOLEAN		bBanAllBaSetup;
+	BOOLEAN		bPromiscuous;
+
+	// ----------------------------
+	// rt2860c emulation-use Parameters
+	// ----------------------------
+	ULONG		rtsaccu[30];
+	ULONG		ctsaccu[30];
+	ULONG		cfendaccu[30];
+	ULONG		bacontent[16];
+	ULONG		rxint[RX_RING_SIZE+1];
+	UCHAR		rcvba[60];
+	BOOLEAN		bLinkAdapt;
+	BOOLEAN		bForcePrintTX;
+	BOOLEAN		bForcePrintRX;
+	BOOLEAN		bDisablescanning;		//defined in RT2870 USB
+	BOOLEAN		bStaFifoTest;
+	BOOLEAN		bProtectionTest;
+	BOOLEAN		bHCCATest;
+	BOOLEAN		bGenOneHCCA;
+	BOOLEAN		bBroadComHT;
+	//+++Following add from RT2870 USB.
+	ULONG		BulkOutReq;
+	ULONG		BulkOutComplete;
+	ULONG		BulkOutCompleteOther;
+	ULONG		BulkOutCompleteCancel;	// seems not use now?
+	ULONG		BulkInReq;
+	ULONG		BulkInComplete;
+	ULONG		BulkInCompleteFail;
+	//---
+
+    struct wificonf			WIFItestbed;
+
+#ifdef RALINK_ATE
+	ATE_INFO				ate;
+#ifdef RT2870
+	BOOLEAN					ContinBulkOut;		//ATE bulk out control
+	BOOLEAN					ContinBulkIn;		//ATE bulk in control
+	atomic_t				BulkOutRemained;
+	atomic_t				BulkInRemained;
+#endif // RT2870 //
+#endif // RALINK_ATE //
+
+#ifdef DOT11_N_SUPPORT
+	struct reordering_mpdu_pool mpdu_blk_pool;
+#endif // DOT11_N_SUPPORT //
+
+	ULONG					OneSecondnonBEpackets;		// record non BE packets per second
+
+#if WIRELESS_EXT >= 12
+    struct iw_statistics    iw_stats;
+#endif
+
+	struct net_device_stats	stats;
+
+#ifdef BLOCK_NET_IF
+	BLOCK_QUEUE_ENTRY		blockQueueTab[NUM_OF_TX_RING];
+#endif // BLOCK_NET_IF //
+
+
+
+#ifdef MULTIPLE_CARD_SUPPORT
+	INT32					MC_RowID;
+	UCHAR					MC_FileName[256];
+#endif // MULTIPLE_CARD_SUPPORT //
+
+	ULONG					TbttTickCount;
+#ifdef PCI_MSI_SUPPORT
+	BOOLEAN					HaveMsi;
+#endif // PCI_MSI_SUPPORT //
+
+
+	UCHAR					is_on;
+
+#define TIME_BASE			(1000000/OS_HZ)
+#define TIME_ONE_SECOND		(1000000/TIME_BASE)
+	UCHAR					flg_be_adjust;
+	ULONG					be_adjust_last_time;
+
+#ifdef NINTENDO_AP
+	NINDO_CTRL_BLOCK		nindo_ctrl_block;
+#endif // NINTENDO_AP //
+
+
+#ifdef IKANOS_VX_1X0
+	struct IKANOS_TX_INFO	IkanosTxInfo;
+	struct IKANOS_TX_INFO	IkanosRxInfo[MAX_MBSSID_NUM + MAX_WDS_ENTRY + MAX_APCLI_NUM + MAX_MESH_NUM];
+#endif // IKANOS_VX_1X0 //
+
+
+#ifdef DBG_DIAGNOSE
+	RtmpDiagStruct	DiagStruct;
+#endif // DBG_DIAGNOSE //
+
+
+	UINT8					PM_FlgSuspend;
+
+#ifdef RT30xx
+//======efuse
+	BOOLEAN		bUseEfuse;
+	BOOLEAN		bEEPROMFile;
+#endif // RT30xx //
+
+} RTMP_ADAPTER, *PRTMP_ADAPTER;
+
+//
+// Cisco IAPP format
+//
+typedef struct  _CISCO_IAPP_CONTENT_
+{
+	USHORT     Length;        //IAPP Length
+	UCHAR      MessageType;      //IAPP type
+	UCHAR      FunctionCode;     //IAPP function type
+	UCHAR      DestinaionMAC[MAC_ADDR_LEN];
+	UCHAR      SourceMAC[MAC_ADDR_LEN];
+	USHORT     Tag;           //Tag(element IE) - Adjacent AP report
+	USHORT     TagLength;     //Length of element not including 4 byte header
+	UCHAR      OUI[4];           //0x00, 0x40, 0x96, 0x00
+	UCHAR      PreviousAP[MAC_ADDR_LEN];       //MAC Address of access point
+	USHORT     Channel;
+	USHORT     SsidLen;
+	UCHAR      Ssid[MAX_LEN_OF_SSID];
+	USHORT     Seconds;          //Seconds that the client has been disassociated.
+} CISCO_IAPP_CONTENT, *PCISCO_IAPP_CONTENT;
+
+#define DELAYINTMASK		0x0003fffb
+#define INTMASK				0x0003fffb
+#define IndMask				0x0003fffc
+#define RxINT				0x00000005	// Delayed Rx or indivi rx
+#define TxDataInt			0x000000fa	// Delayed Tx or indivi tx
+#define TxMgmtInt			0x00000102	// Delayed Tx or indivi tx
+#define TxCoherent			0x00020000	// tx coherent
+#define RxCoherent			0x00010000	// rx coherent
+#define McuCommand			0x00000200	// mcu
+#define PreTBTTInt			0x00001000	// Pre-TBTT interrupt
+#define TBTTInt				0x00000800		// TBTT interrupt
+#define GPTimeOutInt			0x00008000		// GPtimeout interrupt
+#define AutoWakeupInt		0x00004000		// AutoWakeupInt interrupt
+#define FifoStaFullInt			0x00002000	//  fifo statistics full interrupt
+
+
+typedef struct _RX_BLK_
+{
+//	RXD_STRUC		RxD; // sample
+	RT28XX_RXD_STRUC	RxD;
+	PRXWI_STRUC			pRxWI;
+	PHEADER_802_11		pHeader;
+	PNDIS_PACKET		pRxPacket;
+	UCHAR				*pData;
+	USHORT				DataSize;
+	USHORT				Flags;
+	UCHAR				UserPriority;	// for calculate TKIP MIC using
+} RX_BLK;
+
+
+#define RX_BLK_SET_FLAG(_pRxBlk, _flag)		(_pRxBlk->Flags |= _flag)
+#define RX_BLK_TEST_FLAG(_pRxBlk, _flag)	(_pRxBlk->Flags & _flag)
+#define RX_BLK_CLEAR_FLAG(_pRxBlk, _flag)	(_pRxBlk->Flags &= ~(_flag))
+
+
+#define fRX_WDS			0x0001
+#define fRX_AMSDU       0x0002
+#define fRX_ARALINK     0x0004
+#define fRX_HTC         0x0008
+#define fRX_PAD         0x0010
+#define fRX_AMPDU       0x0020
+#define fRX_QOS			0x0040
+#define fRX_INFRA		0x0080
+#define fRX_EAP			0x0100
+#define fRX_MESH		0x0200
+#define fRX_APCLI		0x0400
+#define fRX_DLS			0x0800
+#define fRX_WPI			0x1000
+
+#define LENGTH_AMSDU_SUBFRAMEHEAD	14
+#define LENGTH_ARALINK_SUBFRAMEHEAD	14
+#define LENGTH_ARALINK_HEADER_FIELD	 2
+
+#define TX_UNKOWN_FRAME			0x00
+#define TX_MCAST_FRAME			0x01
+#define TX_LEGACY_FRAME			0x02
+#define TX_AMPDU_FRAME			0x04
+#define TX_AMSDU_FRAME			0x08
+#define TX_RALINK_FRAME			0x10
+#define TX_FRAG_FRAME			0x20
+
+
+//	Currently the sizeof(TX_BLK) is 148 bytes.
+typedef struct _TX_BLK_
+{
+	UCHAR				QueIdx;
+	UCHAR				TxFrameType;				// Indicate the Transmission type of the all frames in one batch
+	UCHAR				TotalFrameNum;				// Total frame number want to send-out in one batch
+	USHORT				TotalFragNum;				// Total frame fragments required in one batch
+	USHORT				TotalFrameLen;				// Total length of all frames want to send-out in one batch
+
+	QUEUE_HEADER		TxPacketList;
+	MAC_TABLE_ENTRY		*pMacEntry;					// NULL: packet with 802.11 RA field is multicast/broadcast address
+	HTTRANSMIT_SETTING	*pTransmit;
+
+	// Following structure used for the characteristics of a specific packet.
+	PNDIS_PACKET		pPacket;
+	PUCHAR				pSrcBufHeader;				// Reference to the head of sk_buff->data
+	PUCHAR				pSrcBufData;				// Reference to the sk_buff->data, will changed depends on hanlding progresss
+	UINT				SrcBufLen;					// Length of packet payload which not including Layer 2 header
+	PUCHAR				pExtraLlcSnapEncap;			// NULL means no extra LLC/SNAP is required
+	UCHAR				HeaderBuf[80];				// TempBuffer for TX_INFO + TX_WI + 802.11 Header + padding + AMSDU SubHeader + LLC/SNAP
+	UCHAR				MpduHeaderLen;				// 802.11 header length NOT including the padding
+	UCHAR				HdrPadLen;					// recording Header Padding Length;
+	UCHAR				apidx;						// The interface associated to this packet
+	UCHAR				Wcid;						// The MAC entry associated to this packet
+	UCHAR				UserPriority;				// priority class of packet
+	UCHAR				FrameGap;					// what kind of IFS this packet use
+	UCHAR				MpduReqNum;					// number of fragments of this frame
+	UCHAR				TxRate;						// TODO: Obsoleted? Should change to MCS?
+	UCHAR				CipherAlg;					// cipher alogrithm
+	PCIPHER_KEY			pKey;
+
+
+
+	USHORT				Flags;						//See following definitions for detail.
+
+	//YOU SHOULD NOT TOUCH IT! Following parameters are used for hardware-depended layer.
+	ULONG				Priv;						// Hardware specific value saved in here.
+} TX_BLK, *PTX_BLK;
+
+
+#define fTX_bRtsRequired		0x0001	// Indicate if need send RTS frame for protection. Not used in RT2860/RT2870.
+#define fTX_bAckRequired       	0x0002	// the packet need ack response
+#define fTX_bPiggyBack     		0x0004	// Legacy device use Piggback or not
+#define fTX_bHTRate         	0x0008	// allow to use HT rate
+//#define fTX_bForceLowRate       0x0010	// force to use Low Rate
+#define fTX_bForceNonQoS       	0x0010	// force to transmit frame without WMM-QoS in HT mode
+#define fTX_bAllowFrag       	0x0020	// allow to fragment the packet, A-MPDU, A-MSDU, A-Ralink is not allowed to fragment
+#define fTX_bMoreData			0x0040	// there are more data packets in PowerSave Queue
+#define fTX_bWMM				0x0080	// QOS Data
+
+#define fTX_bClearEAPFrame		0x0100
+
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+
+
+#define TX_BLK_ASSIGN_FLAG(_pTxBlk, _flag, value)	\
+		do {										\
+			if (value) 								\
+				(_pTxBlk->Flags |= _flag) 			\
+			else 									\
+				(_pTxBlk->Flags &= ~(_flag))		\
+		}while(0)
+
+#define TX_BLK_SET_FLAG(_pTxBlk, _flag)		(_pTxBlk->Flags |= _flag)
+#define TX_BLK_TEST_FLAG(_pTxBlk, _flag)	(((_pTxBlk->Flags & _flag) == _flag) ? 1 : 0)
+#define TX_BLK_CLEAR_FLAG(_pTxBlk, _flag)	(_pTxBlk->Flags &= ~(_flag))
+
+
+
+
+
+//------------------------------------------------------------------------------------------
+
+
+
+#ifdef RT_BIG_ENDIAN
+static inline VOID	WriteBackToDescriptor(
+	IN  PUCHAR			Dest,
+ 	IN	PUCHAR			Src,
+    IN  BOOLEAN			DoEncrypt,
+	IN  ULONG           DescriptorType)
+{
+	UINT32 *p1, *p2;
+
+	p1 = ((UINT32 *)Dest);
+	p2 = ((UINT32 *)Src);
+
+	*p1 = *p2;
+	*(p1+2) = *(p2+2);
+	*(p1+3) = *(p2+3);
+	*(p1+1) = *(p2+1); // Word 1; this must be written back last
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Endian conversion of Tx/Rx descriptor .
+
+	Arguments:
+		pAd 	Pointer to our adapter
+		pData			Pointer to Tx/Rx descriptor
+		DescriptorType	Direction of the frame
+
+	Return Value:
+		None
+
+	Note:
+		Call this function when read or update descriptor
+	========================================================================
+*/
+static inline VOID	RTMPWIEndianChange(
+	IN	PUCHAR			pData,
+	IN	ULONG			DescriptorType)
+{
+	int size;
+	int i;
+
+	size = ((DescriptorType == TYPE_TXWI) ? TXWI_SIZE : RXWI_SIZE);
+
+	if(DescriptorType == TYPE_TXWI)
+	{
+		*((UINT32 *)(pData)) = SWAP32(*((UINT32 *)(pData)));		// Byte 0~3
+		*((UINT32 *)(pData + 4)) = SWAP32(*((UINT32 *)(pData+4)));	// Byte 4~7
+	}
+	else
+	{
+		for(i=0; i < size/4 ; i++)
+			*(((UINT32 *)pData) +i) = SWAP32(*(((UINT32 *)pData)+i));
+	}
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Endian conversion of Tx/Rx descriptor .
+
+	Arguments:
+		pAd 	Pointer to our adapter
+		pData			Pointer to Tx/Rx descriptor
+		DescriptorType	Direction of the frame
+
+	Return Value:
+		None
+
+	Note:
+		Call this function when read or update descriptor
+	========================================================================
+*/
+
+#ifdef RT2870
+static inline VOID	RTMPDescriptorEndianChange(
+	IN	PUCHAR			pData,
+	IN	ULONG			DescriptorType)
+{
+	*((UINT32 *)(pData)) = SWAP32(*((UINT32 *)(pData)));
+}
+#endif // RT2870 //
+/*
+	========================================================================
+
+	Routine Description:
+		Endian conversion of all kinds of 802.11 frames .
+
+	Arguments:
+		pAd 	Pointer to our adapter
+		pData			Pointer to the 802.11 frame structure
+		Dir 			Direction of the frame
+		FromRxDoneInt	Caller is from RxDone interrupt
+
+	Return Value:
+		None
+
+	Note:
+		Call this function when read or update buffer data
+	========================================================================
+*/
+static inline VOID	RTMPFrameEndianChange(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pData,
+	IN	ULONG			Dir,
+	IN	BOOLEAN 		FromRxDoneInt)
+{
+	PHEADER_802_11 pFrame;
+	PUCHAR	pMacHdr;
+
+	// swab 16 bit fields - Frame Control field
+	if(Dir == DIR_READ)
+	{
+		*(USHORT *)pData = SWAP16(*(USHORT *)pData);
+	}
+
+	pFrame = (PHEADER_802_11) pData;
+	pMacHdr = (PUCHAR) pFrame;
+
+	// swab 16 bit fields - Duration/ID field
+	*(USHORT *)(pMacHdr + 2) = SWAP16(*(USHORT *)(pMacHdr + 2));
+
+	// swab 16 bit fields - Sequence Control field
+	*(USHORT *)(pMacHdr + 22) = SWAP16(*(USHORT *)(pMacHdr + 22));
+
+	if(pFrame->FC.Type == BTYPE_MGMT)
+	{
+		switch(pFrame->FC.SubType)
+		{
+			case SUBTYPE_ASSOC_REQ:
+			case SUBTYPE_REASSOC_REQ:
+				// swab 16 bit fields - CapabilityInfo field
+				pMacHdr += sizeof(HEADER_802_11);
+				*(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+
+				// swab 16 bit fields - Listen Interval field
+				pMacHdr += 2;
+				*(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+				break;
+
+			case SUBTYPE_ASSOC_RSP:
+			case SUBTYPE_REASSOC_RSP:
+				// swab 16 bit fields - CapabilityInfo field
+				pMacHdr += sizeof(HEADER_802_11);
+				*(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+
+				// swab 16 bit fields - Status Code field
+				pMacHdr += 2;
+				*(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+
+				// swab 16 bit fields - AID field
+				pMacHdr += 2;
+				*(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+				break;
+
+			case SUBTYPE_AUTH:
+				// If from APHandleRxDoneInterrupt routine, it is still a encrypt format.
+				// The convertion is delayed to RTMPHandleDecryptionDoneInterrupt.
+				if(!FromRxDoneInt && pFrame->FC.Wep == 1)
+					break;
+				else
+				{
+					// swab 16 bit fields - Auth Alg No. field
+					pMacHdr += sizeof(HEADER_802_11);
+					*(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+
+					// swab 16 bit fields - Auth Seq No. field
+					pMacHdr += 2;
+					*(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+
+					// swab 16 bit fields - Status Code field
+					pMacHdr += 2;
+					*(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+				}
+				break;
+
+			case SUBTYPE_BEACON:
+			case SUBTYPE_PROBE_RSP:
+				// swab 16 bit fields - BeaconInterval field
+				pMacHdr += (sizeof(HEADER_802_11) + TIMESTAMP_LEN);
+				*(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+
+				// swab 16 bit fields - CapabilityInfo field
+				pMacHdr += sizeof(USHORT);
+				*(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+				break;
+
+			case SUBTYPE_DEAUTH:
+			case SUBTYPE_DISASSOC:
+				// swab 16 bit fields - Reason code field
+				pMacHdr += sizeof(HEADER_802_11);
+				*(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+				break;
+		}
+	}
+	else if( pFrame->FC.Type == BTYPE_DATA )
+	{
+	}
+	else if(pFrame->FC.Type == BTYPE_CNTL)
+	{
+		switch(pFrame->FC.SubType)
+		{
+			case SUBTYPE_BLOCK_ACK_REQ:
+				{
+					PFRAME_BA_REQ pBAReq = (PFRAME_BA_REQ)pFrame;
+					*(USHORT *)(&pBAReq->BARControl) = SWAP16(*(USHORT *)(&pBAReq->BARControl));
+					pBAReq->BAStartingSeq.word = SWAP16(pBAReq->BAStartingSeq.word);
+				}
+				break;
+			case SUBTYPE_BLOCK_ACK:
+				// For Block Ack packet, the HT_CONTROL field is in the same offset with Addr3
+				*(UINT32 *)(&pFrame->Addr3[0]) = SWAP32(*(UINT32 *)(&pFrame->Addr3[0]));
+				break;
+
+			case SUBTYPE_ACK:
+				//For ACK packet, the HT_CONTROL field is in the same offset with Addr2
+				*(UINT32 *)(&pFrame->Addr2[0])=	SWAP32(*(UINT32 *)(&pFrame->Addr2[0]));
+				break;
+		}
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("Invalid Frame Type!!!\n"));
+	}
+
+	// swab 16 bit fields - Frame Control
+	if(Dir == DIR_WRITE)
+	{
+		*(USHORT *)pData = SWAP16(*(USHORT *)pData);
+	}
+}
+#endif // RT_BIG_ENDIAN //
+
+
+static inline VOID ConvertMulticastIP2MAC(
+	IN PUCHAR pIpAddr,
+	IN PUCHAR *ppMacAddr,
+	IN UINT16 ProtoType)
+{
+	if (pIpAddr == NULL)
+		return;
+
+	if (ppMacAddr == NULL || *ppMacAddr == NULL)
+		return;
+
+	switch (ProtoType)
+	{
+		case ETH_P_IPV6:
+//			memset(*ppMacAddr, 0, ETH_LENGTH_OF_ADDRESS);
+			*(*ppMacAddr) = 0x33;
+			*(*ppMacAddr + 1) = 0x33;
+			*(*ppMacAddr + 2) = pIpAddr[12];
+			*(*ppMacAddr + 3) = pIpAddr[13];
+			*(*ppMacAddr + 4) = pIpAddr[14];
+			*(*ppMacAddr + 5) = pIpAddr[15];
+			break;
+
+		case ETH_P_IP:
+		default:
+//			memset(*ppMacAddr, 0, ETH_LENGTH_OF_ADDRESS);
+			*(*ppMacAddr) = 0x01;
+			*(*ppMacAddr + 1) = 0x00;
+			*(*ppMacAddr + 2) = 0x5e;
+			*(*ppMacAddr + 3) = pIpAddr[1] & 0x7f;
+			*(*ppMacAddr + 4) = pIpAddr[2];
+			*(*ppMacAddr + 5) = pIpAddr[3];
+			break;
+	}
+
+	return;
+}
+
+BOOLEAN RTMPCheckForHang(
+	IN  NDIS_HANDLE MiniportAdapterContext
+	);
+
+VOID  RTMPHalt(
+	IN  NDIS_HANDLE MiniportAdapterContext
+	);
+
+//
+//  Private routines in rtmp_init.c
+//
+NDIS_STATUS RTMPAllocAdapterBlock(
+	IN PVOID			handle,
+	OUT PRTMP_ADAPTER   *ppAdapter
+	);
+
+NDIS_STATUS RTMPAllocTxRxRingMemory(
+	IN  PRTMP_ADAPTER   pAd
+	);
+
+NDIS_STATUS RTMPFindAdapter(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  NDIS_HANDLE     WrapperConfigurationContext
+	);
+
+NDIS_STATUS	RTMPReadParametersHook(
+	IN	PRTMP_ADAPTER pAd
+	);
+
+VOID RTMPFreeAdapter(
+	IN  PRTMP_ADAPTER   pAd
+	);
+
+NDIS_STATUS NICReadRegParameters(
+	IN  PRTMP_ADAPTER       pAd,
+	IN  NDIS_HANDLE         WrapperConfigurationContext
+	);
+
+#ifdef RT30xx
+VOID NICInitRT30xxRFRegisters(
+	IN PRTMP_ADAPTER pAd);
+#endif // RT30xx //
+
+VOID NICReadEEPROMParameters(
+	IN  PRTMP_ADAPTER       pAd,
+	IN	PUCHAR				mac_addr);
+
+VOID NICInitAsicFromEEPROM(
+	IN  PRTMP_ADAPTER       pAd);
+
+VOID NICInitTxRxRingAndBacklogQueue(
+	IN  PRTMP_ADAPTER   pAd);
+
+NDIS_STATUS NICInitializeAdapter(
+	IN  PRTMP_ADAPTER   pAd,
+	IN   BOOLEAN    bHardReset);
+
+NDIS_STATUS NICInitializeAsic(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  BOOLEAN		bHardReset);
+
+VOID NICIssueReset(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID RTMPRingCleanUp(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  UCHAR           RingType);
+
+VOID RxTest(
+	IN  PRTMP_ADAPTER   pAd);
+
+NDIS_STATUS DbgSendPacket(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PNDIS_PACKET    pPacket);
+
+VOID UserCfgInit(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID NICResetFromError(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID NICEraseFirmware(
+	IN PRTMP_ADAPTER pAd);
+
+NDIS_STATUS NICLoadFirmware(
+	IN  PRTMP_ADAPTER   pAd);
+
+NDIS_STATUS NICLoadRateSwitchingParams(
+	IN PRTMP_ADAPTER pAd);
+
+BOOLEAN NICCheckForHang(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID NICUpdateFifoStaCounters(
+	IN PRTMP_ADAPTER pAd);
+
+VOID NICUpdateRawCounters(
+	IN  PRTMP_ADAPTER   pAd);
+
+ULONG	RTMPNotAllZero(
+	IN	PVOID	pSrc1,
+	IN	ULONG	Length);
+
+VOID RTMPZeroMemory(
+	IN  PVOID   pSrc,
+	IN  ULONG   Length);
+
+ULONG RTMPCompareMemory(
+	IN  PVOID   pSrc1,
+	IN  PVOID   pSrc2,
+	IN  ULONG   Length);
+
+VOID RTMPMoveMemory(
+	OUT PVOID   pDest,
+	IN  PVOID   pSrc,
+	IN  ULONG   Length);
+
+VOID AtoH(
+	char	*src,
+	UCHAR	*dest,
+	int		destlen);
+
+UCHAR BtoH(
+	char ch);
+
+VOID RTMPPatchMacBbpBug(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID RTMPPatchCardBus(
+	IN	PRTMP_ADAPTER	pAdapter);
+
+VOID RTMPPatchRalinkCardBus(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	ULONG			Bus);
+
+ULONG RTMPReadCBConfig(
+	IN	ULONG	Bus,
+	IN	ULONG	Slot,
+	IN	ULONG	Func,
+	IN	ULONG	Offset);
+
+VOID RTMPWriteCBConfig(
+	IN	ULONG	Bus,
+	IN	ULONG	Slot,
+	IN	ULONG	Func,
+	IN	ULONG	Offset,
+	IN	ULONG	Value);
+
+VOID RTMPInitTimer(
+	IN  PRTMP_ADAPTER           pAd,
+	IN  PRALINK_TIMER_STRUCT    pTimer,
+	IN  PVOID                   pTimerFunc,
+	IN	PVOID					pData,
+	IN  BOOLEAN                 Repeat);
+
+VOID RTMPSetTimer(
+	IN  PRALINK_TIMER_STRUCT    pTimer,
+	IN  ULONG                   Value);
+
+
+VOID RTMPModTimer(
+	IN	PRALINK_TIMER_STRUCT	pTimer,
+	IN	ULONG					Value);
+
+VOID RTMPCancelTimer(
+	IN  PRALINK_TIMER_STRUCT    pTimer,
+	OUT BOOLEAN                 *pCancelled);
+
+VOID RTMPSetLED(
+	IN PRTMP_ADAPTER 	pAd,
+	IN UCHAR			Status);
+
+VOID RTMPSetSignalLED(
+	IN PRTMP_ADAPTER 	pAd,
+	IN NDIS_802_11_RSSI Dbm);
+
+VOID RTMPEnableRxTx(
+	IN PRTMP_ADAPTER	pAd);
+
+//
+// prototype in action.c
+//
+VOID ActionStateMachineInit(
+    IN	PRTMP_ADAPTER	pAd,
+    IN  STATE_MACHINE *S,
+    OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID MlmeADDBAAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeDELBAAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeDLSAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeInvalidAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeQOSAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem);
+
+#ifdef DOT11_N_SUPPORT
+VOID PeerAddBAReqAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerAddBARspAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerDelBAAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerBAAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem);
+#endif // DOT11_N_SUPPORT //
+
+VOID SendPSMPAction(
+	IN PRTMP_ADAPTER	pAd,
+	IN UCHAR			Wcid,
+	IN UCHAR			Psmp);
+
+
+#ifdef DOT11N_DRAFT3
+VOID SendBSS2040CoexistMgmtAction(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR	Wcid,
+	IN	UCHAR	apidx,
+	IN	UCHAR	InfoReq);
+
+VOID SendNotifyBWActionFrame(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR  Wcid,
+	IN UCHAR apidx);
+
+BOOLEAN ChannelSwitchSanityCheck(
+	IN	PRTMP_ADAPTER	pAd,
+	IN    UCHAR  Wcid,
+	IN    UCHAR  NewChannel,
+	IN    UCHAR  Secondary);
+
+VOID ChannelSwitchAction(
+	IN	PRTMP_ADAPTER	pAd,
+	IN    UCHAR  Wcid,
+	IN    UCHAR  Channel,
+	IN    UCHAR  Secondary);
+
+ULONG BuildIntolerantChannelRep(
+	IN	PRTMP_ADAPTER	pAd,
+	IN    PUCHAR  pDest);
+
+VOID Update2040CoexistFrameAndNotify(
+	IN	PRTMP_ADAPTER	pAd,
+	IN    UCHAR  Wcid,
+	IN	BOOLEAN	bAddIntolerantCha);
+
+VOID Send2040CoexistAction(
+	IN	PRTMP_ADAPTER	pAd,
+	IN    UCHAR  Wcid,
+	IN	BOOLEAN	bAddIntolerantCha);
+#endif // DOT11N_DRAFT3 //
+
+VOID PeerRMAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerPublicAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem);
+
+#ifdef CONFIG_STA_SUPPORT
+VOID StaPublicAction(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR Bss2040Coexist);
+#endif // CONFIG_STA_SUPPORT //
+
+
+VOID PeerBSSTranAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem);
+
+#ifdef DOT11_N_SUPPORT
+VOID PeerHTAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem);
+#endif // DOT11_N_SUPPORT //
+
+VOID PeerQOSAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem);
+
+#ifdef QOS_DLS_SUPPORT
+VOID PeerDLSAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem);
+#endif // QOS_DLS_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+VOID DlsParmFill(
+	IN PRTMP_ADAPTER pAd,
+	IN OUT MLME_DLS_REQ_STRUCT *pDlsReq,
+	IN PRT_802_11_DLS pDls,
+	IN USHORT reason);
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef DOT11_N_SUPPORT
+VOID RECBATimerTimeout(
+    IN PVOID SystemSpecific1,
+    IN PVOID FunctionContext,
+    IN PVOID SystemSpecific2,
+    IN PVOID SystemSpecific3);
+
+VOID ORIBATimerTimeout(
+	IN	PRTMP_ADAPTER	pAd);
+
+VOID SendRefreshBAR(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	MAC_TABLE_ENTRY	*pEntry);
+#endif // DOT11_N_SUPPORT //
+
+VOID ActHeaderInit(
+    IN	PRTMP_ADAPTER	pAd,
+    IN OUT PHEADER_802_11 pHdr80211,
+    IN PUCHAR Addr1,
+    IN PUCHAR Addr2,
+    IN PUCHAR Addr3);
+
+VOID BarHeaderInit(
+	IN	PRTMP_ADAPTER	pAd,
+	IN OUT PFRAME_BAR pCntlBar,
+	IN PUCHAR pDA,
+	IN PUCHAR pSA);
+
+VOID InsertActField(
+	IN PRTMP_ADAPTER pAd,
+	OUT PUCHAR pFrameBuf,
+	OUT PULONG pFrameLen,
+	IN UINT8 Category,
+	IN UINT8 ActCode);
+
+BOOLEAN QosBADataParse(
+	IN PRTMP_ADAPTER	pAd,
+	IN BOOLEAN bAMSDU,
+	IN PUCHAR p8023Header,
+	IN UCHAR	WCID,
+	IN UCHAR	TID,
+	IN USHORT Sequence,
+	IN UCHAR DataOffset,
+	IN USHORT Datasize,
+	IN UINT   CurRxIndex);
+
+#ifdef DOT11_N_SUPPORT
+BOOLEAN CntlEnqueueForRecv(
+    IN	PRTMP_ADAPTER	pAd,
+	IN ULONG Wcid,
+    IN ULONG MsgLen,
+	IN PFRAME_BA_REQ pMsg);
+
+VOID BaAutoManSwitch(
+	IN	PRTMP_ADAPTER	pAd);
+#endif // DOT11_N_SUPPORT //
+
+VOID HTIOTCheck(
+	IN	PRTMP_ADAPTER	pAd,
+	IN    UCHAR     BatRecIdx);
+
+//
+// Private routines in rtmp_data.c
+//
+BOOLEAN RTMPHandleRxDoneInterrupt(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID RTMPHandleTxDoneInterrupt(
+	IN  PRTMP_ADAPTER   pAd);
+
+BOOLEAN RTMPHandleTxRingDmaDoneInterrupt(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  INT_SOURCE_CSR_STRUC TxRingBitmap);
+
+VOID RTMPHandleMgmtRingDmaDoneInterrupt(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID RTMPHandleTBTTInterrupt(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID RTMPHandlePreTBTTInterrupt(
+	IN  PRTMP_ADAPTER   pAd);
+
+void RTMPHandleTwakeupInterrupt(
+	IN PRTMP_ADAPTER pAd);
+
+VOID	RTMPHandleRxCoherentInterrupt(
+	IN	PRTMP_ADAPTER	pAd);
+
+BOOLEAN TxFrameIsAggregatible(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR          pPrevAddr1,
+	IN  PUCHAR          p8023hdr);
+
+BOOLEAN PeerIsAggreOn(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  ULONG          TxRate,
+    IN  PMAC_TABLE_ENTRY pMacEntry);
+
+NDIS_STATUS Sniff2BytesFromNdisBuffer(
+	IN  PNDIS_BUFFER    pFirstBuffer,
+	IN  UCHAR           DesiredOffset,
+	OUT PUCHAR          pByte0,
+	OUT PUCHAR          pByte1);
+
+NDIS_STATUS STASendPacket(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PNDIS_PACKET    pPacket);
+
+VOID STASendPackets(
+	IN  NDIS_HANDLE     MiniportAdapterContext,
+	IN  PPNDIS_PACKET   ppPacketArray,
+	IN  UINT            NumberOfPackets);
+
+VOID RTMPDeQueuePacket(
+	IN  PRTMP_ADAPTER   pAd,
+   	IN	BOOLEAN			bIntContext,
+	IN  UCHAR			QueIdx,
+	IN	UCHAR			Max_Tx_Packets);
+
+NDIS_STATUS	RTMPHardTransmit(
+	IN PRTMP_ADAPTER	pAd,
+	IN PNDIS_PACKET		pPacket,
+	IN  UCHAR			QueIdx,
+	OUT	PULONG			pFreeTXDLeft);
+
+NDIS_STATUS	STAHardTransmit(
+	IN PRTMP_ADAPTER	pAd,
+	IN TX_BLK			*pTxBlk,
+	IN  UCHAR			QueIdx);
+
+VOID STARxEAPOLFrameIndicate(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	MAC_TABLE_ENTRY	*pEntry,
+	IN	RX_BLK			*pRxBlk,
+	IN	UCHAR			FromWhichBSSID);
+
+NDIS_STATUS RTMPFreeTXDRequest(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  UCHAR           RingType,
+	IN  UCHAR           NumberRequired,
+	IN 	PUCHAR          FreeNumberIs);
+
+NDIS_STATUS MlmeHardTransmit(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  UCHAR	QueIdx,
+	IN  PNDIS_PACKET    pPacket);
+
+NDIS_STATUS MlmeHardTransmitMgmtRing(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  UCHAR	QueIdx,
+	IN  PNDIS_PACKET    pPacket);
+
+NDIS_STATUS MlmeHardTransmitTxRing(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  UCHAR	QueIdx,
+	IN  PNDIS_PACKET    pPacket);
+
+USHORT  RTMPCalcDuration(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  UCHAR           Rate,
+	IN  ULONG           Size);
+
+VOID RTMPWriteTxWI(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PTXWI_STRUC		pTxWI,
+	IN  BOOLEAN    		FRAG,
+	IN  BOOLEAN    		CFACK,
+	IN  BOOLEAN    		InsTimestamp,
+	IN	BOOLEAN			AMPDU,
+	IN	BOOLEAN			Ack,
+	IN	BOOLEAN			NSeq,		// HW new a sequence.
+	IN	UCHAR			BASize,
+	IN	UCHAR			WCID,
+	IN	ULONG			Length,
+	IN  UCHAR      		PID,
+	IN	UCHAR			TID,
+	IN	UCHAR			TxRate,
+	IN	UCHAR			Txopmode,
+	IN	BOOLEAN			CfAck,
+	IN	HTTRANSMIT_SETTING	*pTransmit);
+
+
+VOID RTMPWriteTxWI_Data(
+	IN	PRTMP_ADAPTER		pAd,
+	IN	OUT PTXWI_STRUC		pTxWI,
+	IN	TX_BLK				*pTxBlk);
+
+
+VOID RTMPWriteTxWI_Cache(
+	IN	PRTMP_ADAPTER		pAd,
+	IN	OUT PTXWI_STRUC		pTxWI,
+	IN	TX_BLK				*pTxBlk);
+
+VOID RTMPWriteTxDescriptor(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PTXD_STRUC		pTxD,
+	IN	BOOLEAN			bWIV,
+	IN	UCHAR			QSEL);
+
+VOID RTMPSuspendMsduTransmission(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID RTMPResumeMsduTransmission(
+	IN  PRTMP_ADAPTER   pAd);
+
+NDIS_STATUS MiniportMMRequest(
+	IN  PRTMP_ADAPTER   pAd,
+	IN	UCHAR			QueIdx,
+	IN	PUCHAR			pData,
+	IN  UINT            Length);
+
+NDIS_STATUS MiniportDataMMRequest(
+	 IN  PRTMP_ADAPTER   pAd,
+	 IN  UCHAR           QueIdx,
+	 IN  PUCHAR          pData,
+	 IN  UINT            Length);
+
+VOID RTMPSendNullFrame(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  UCHAR           TxRate,
+	IN	BOOLEAN			bQosNull);
+
+VOID RTMPSendDisassociationFrame(
+	IN	PRTMP_ADAPTER	pAd);
+
+VOID RTMPSendRTSFrame(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR          pDA,
+	IN	unsigned int	NextMpduSize,
+	IN  UCHAR           TxRate,
+	IN  UCHAR           RTSRate,
+	IN  USHORT          AckDuration,
+	IN  UCHAR           QueIdx,
+	IN  UCHAR			FrameGap);
+
+
+NDIS_STATUS RTMPApplyPacketFilter(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PRT28XX_RXD_STRUC      pRxD,
+	IN  PHEADER_802_11  pHeader);
+
+PQUEUE_HEADER   RTMPCheckTxSwQueue(
+	IN  PRTMP_ADAPTER   pAd,
+	OUT UCHAR           *QueIdx);
+
+#ifdef CONFIG_STA_SUPPORT
+VOID RTMPReportMicError(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PCIPHER_KEY     pWpaKey);
+
+VOID	WpaMicFailureReportFrame(
+	IN  PRTMP_ADAPTER    pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID    WpaDisassocApAndBlockAssoc(
+    IN  PVOID SystemSpecific1,
+    IN  PVOID FunctionContext,
+    IN  PVOID SystemSpecific2,
+    IN  PVOID SystemSpecific3);
+#endif // CONFIG_STA_SUPPORT //
+
+NDIS_STATUS RTMPCloneNdisPacket(
+	IN  PRTMP_ADAPTER   pAd,
+	IN	BOOLEAN    pInsAMSDUHdr,
+	IN  PNDIS_PACKET    pInPacket,
+	OUT PNDIS_PACKET   *ppOutPacket);
+
+NDIS_STATUS RTMPAllocateNdisPacket(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PNDIS_PACKET    *pPacket,
+	IN  PUCHAR          pHeader,
+	IN  UINT            HeaderLen,
+	IN  PUCHAR          pData,
+	IN  UINT            DataLen);
+
+VOID RTMPFreeNdisPacket(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PNDIS_PACKET    pPacket);
+
+BOOLEAN RTMPFreeTXDUponTxDmaDone(
+	IN PRTMP_ADAPTER    pAd,
+	IN UCHAR            QueIdx);
+
+BOOLEAN RTMPCheckDHCPFrame(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PNDIS_PACKET	pPacket);
+
+
+BOOLEAN RTMPCheckEtherType(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PNDIS_PACKET	pPacket);
+
+
+VOID RTMPCckBbpTuning(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UINT			TxRate);
+
+//
+// Private routines in rtmp_wep.c
+//
+VOID RTMPInitWepEngine(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR          pKey,
+	IN  UCHAR           KeyId,
+	IN  UCHAR           KeyLen,
+	IN  PUCHAR          pDest);
+
+VOID RTMPEncryptData(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR          pSrc,
+	IN  PUCHAR          pDest,
+	IN  UINT            Len);
+
+BOOLEAN	RTMPDecryptData(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	PUCHAR			pSrc,
+	IN	UINT			Len,
+	IN	UINT			idx);
+
+BOOLEAN	RTMPSoftDecryptWEP(
+	IN PRTMP_ADAPTER 	pAd,
+	IN PUCHAR			pData,
+	IN ULONG			DataByteCnt,
+	IN PCIPHER_KEY		pGroupKey);
+
+VOID RTMPSetICV(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR          pDest);
+
+VOID ARCFOUR_INIT(
+	IN  PARCFOURCONTEXT Ctx,
+	IN  PUCHAR          pKey,
+	IN  UINT            KeyLen);
+
+UCHAR   ARCFOUR_BYTE(
+	IN  PARCFOURCONTEXT     Ctx);
+
+VOID ARCFOUR_DECRYPT(
+	IN  PARCFOURCONTEXT Ctx,
+	IN  PUCHAR          pDest,
+	IN  PUCHAR          pSrc,
+	IN  UINT            Len);
+
+VOID ARCFOUR_ENCRYPT(
+	IN  PARCFOURCONTEXT Ctx,
+	IN  PUCHAR          pDest,
+	IN  PUCHAR          pSrc,
+	IN  UINT            Len);
+
+VOID WPAARCFOUR_ENCRYPT(
+	IN  PARCFOURCONTEXT Ctx,
+	IN  PUCHAR          pDest,
+	IN  PUCHAR          pSrc,
+	IN  UINT            Len);
+
+UINT RTMP_CALC_FCS32(
+	IN  UINT   Fcs,
+	IN  PUCHAR  Cp,
+	IN  INT     Len);
+
+//
+// MLME routines
+//
+
+// Asic/RF/BBP related functions
+
+VOID AsicAdjustTxPower(
+	IN PRTMP_ADAPTER pAd);
+
+VOID 	AsicUpdateProtect(
+	IN		PRTMP_ADAPTER	pAd,
+	IN 		USHORT			OperaionMode,
+	IN 		UCHAR			SetMask,
+	IN		BOOLEAN			bDisableBGProtect,
+	IN		BOOLEAN			bNonGFExist);
+
+VOID AsicSwitchChannel(
+	IN  PRTMP_ADAPTER   pAd,
+	IN	UCHAR			Channel,
+	IN	BOOLEAN			bScan);
+
+VOID AsicLockChannel(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR Channel) ;
+
+VOID AsicAntennaSelect(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  UCHAR           Channel);
+
+VOID AsicAntennaSetting(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	ABGBAND_STATE	BandState);
+
+VOID AsicRfTuningExec(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3);
+
+#ifdef CONFIG_STA_SUPPORT
+VOID AsicSleepThenAutoWakeup(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  USHORT TbttNumToNextWakeUp);
+
+VOID AsicForceSleep(
+	IN PRTMP_ADAPTER pAd);
+
+VOID AsicForceWakeup(
+	IN PRTMP_ADAPTER pAd,
+	IN BOOLEAN    bFromTx);
+#endif // CONFIG_STA_SUPPORT //
+
+VOID AsicSetBssid(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR pBssid);
+
+VOID AsicSetMcastWC(
+	IN PRTMP_ADAPTER pAd);
+
+VOID AsicDelWcidTab(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR	Wcid);
+
+VOID AsicEnableRDG(
+	IN PRTMP_ADAPTER pAd);
+
+VOID AsicDisableRDG(
+	IN PRTMP_ADAPTER pAd);
+
+VOID AsicDisableSync(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID AsicEnableBssSync(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID AsicEnableIbssSync(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID AsicSetEdcaParm(
+	IN PRTMP_ADAPTER pAd,
+	IN PEDCA_PARM    pEdcaParm);
+
+VOID AsicSetSlotTime(
+	IN PRTMP_ADAPTER pAd,
+	IN BOOLEAN bUseShortSlotTime);
+
+VOID AsicAddSharedKeyEntry(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR         BssIndex,
+	IN UCHAR         KeyIdx,
+	IN UCHAR         CipherAlg,
+	IN PUCHAR        pKey,
+	IN PUCHAR        pTxMic,
+	IN PUCHAR        pRxMic);
+
+VOID AsicRemoveSharedKeyEntry(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR         BssIndex,
+	IN UCHAR         KeyIdx);
+
+VOID AsicUpdateWCIDAttribute(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT		WCID,
+	IN UCHAR		BssIndex,
+	IN UCHAR        CipherAlg,
+	IN BOOLEAN		bUsePairewiseKeyTable);
+
+VOID AsicUpdateWCIDIVEIV(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT		WCID,
+	IN ULONG        uIV,
+	IN ULONG        uEIV);
+
+VOID AsicUpdateRxWCIDTable(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT		WCID,
+	IN PUCHAR        pAddr);
+
+VOID AsicAddKeyEntry(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT		WCID,
+	IN UCHAR		BssIndex,
+	IN UCHAR		KeyIdx,
+	IN PCIPHER_KEY	pCipherKey,
+	IN BOOLEAN		bUsePairewiseKeyTable,
+	IN BOOLEAN		bTxKey);
+
+VOID AsicAddPairwiseKeyEntry(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR        pAddr,
+	IN UCHAR		WCID,
+	IN CIPHER_KEY		 *pCipherKey);
+
+VOID AsicRemovePairwiseKeyEntry(
+	IN PRTMP_ADAPTER  pAd,
+	IN UCHAR		 BssIdx,
+	IN UCHAR		 Wcid);
+
+BOOLEAN AsicSendCommandToMcu(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR         Command,
+	IN UCHAR         Token,
+	IN UCHAR         Arg0,
+	IN UCHAR         Arg1);
+
+
+VOID MacAddrRandomBssid(
+	IN  PRTMP_ADAPTER   pAd,
+	OUT PUCHAR pAddr);
+
+VOID MgtMacHeaderInit(
+	IN  PRTMP_ADAPTER     pAd,
+	IN OUT PHEADER_802_11 pHdr80211,
+	IN UCHAR SubType,
+	IN UCHAR ToDs,
+	IN PUCHAR pDA,
+	IN PUCHAR pBssid);
+
+VOID MlmeRadioOff(
+	IN PRTMP_ADAPTER pAd);
+
+VOID MlmeRadioOn(
+	IN PRTMP_ADAPTER pAd);
+
+
+VOID BssTableInit(
+	IN BSS_TABLE *Tab);
+
+#ifdef DOT11_N_SUPPORT
+VOID BATableInit(
+	IN PRTMP_ADAPTER pAd,
+    IN BA_TABLE *Tab);
+#endif // DOT11_N_SUPPORT //
+
+ULONG BssTableSearch(
+	IN BSS_TABLE *Tab,
+	IN PUCHAR pBssid,
+	IN UCHAR Channel);
+
+ULONG BssSsidTableSearch(
+	IN BSS_TABLE *Tab,
+	IN PUCHAR    pBssid,
+	IN PUCHAR    pSsid,
+	IN UCHAR     SsidLen,
+	IN UCHAR     Channel);
+
+ULONG BssTableSearchWithSSID(
+	IN BSS_TABLE *Tab,
+	IN PUCHAR    Bssid,
+	IN PUCHAR    pSsid,
+	IN UCHAR     SsidLen,
+	IN UCHAR     Channel);
+
+VOID BssTableDeleteEntry(
+	IN OUT  PBSS_TABLE pTab,
+	IN      PUCHAR pBssid,
+	IN      UCHAR Channel);
+
+#ifdef DOT11_N_SUPPORT
+VOID BATableDeleteORIEntry(
+	IN OUT	PRTMP_ADAPTER pAd,
+	IN		BA_ORI_ENTRY	*pBAORIEntry);
+
+VOID BATableDeleteRECEntry(
+	IN OUT	PRTMP_ADAPTER pAd,
+	IN		BA_REC_ENTRY	*pBARECEntry);
+
+VOID BATableTearORIEntry(
+	IN OUT	PRTMP_ADAPTER pAd,
+	IN		UCHAR TID,
+	IN		UCHAR Wcid,
+	IN		BOOLEAN bForceDelete,
+	IN		BOOLEAN ALL);
+
+VOID BATableTearRECEntry(
+	IN OUT	PRTMP_ADAPTER pAd,
+	IN		UCHAR TID,
+	IN		UCHAR WCID,
+	IN		BOOLEAN ALL);
+#endif // DOT11_N_SUPPORT //
+
+VOID  BssEntrySet(
+	IN  PRTMP_ADAPTER   pAd,
+	OUT PBSS_ENTRY pBss,
+	IN PUCHAR pBssid,
+	IN CHAR Ssid[],
+	IN UCHAR SsidLen,
+	IN UCHAR BssType,
+	IN USHORT BeaconPeriod,
+	IN PCF_PARM CfParm,
+	IN USHORT AtimWin,
+	IN USHORT CapabilityInfo,
+	IN UCHAR SupRate[],
+	IN UCHAR SupRateLen,
+	IN UCHAR ExtRate[],
+	IN UCHAR ExtRateLen,
+	IN HT_CAPABILITY_IE *pHtCapability,
+	IN ADD_HT_INFO_IE *pAddHtInfo,	// AP might use this additional ht info IE
+	IN UCHAR			HtCapabilityLen,
+	IN UCHAR			AddHtInfoLen,
+	IN UCHAR			NewExtChanOffset,
+	IN UCHAR Channel,
+	IN CHAR Rssi,
+	IN LARGE_INTEGER TimeStamp,
+	IN UCHAR CkipFlag,
+	IN PEDCA_PARM pEdcaParm,
+	IN PQOS_CAPABILITY_PARM pQosCapability,
+	IN PQBSS_LOAD_PARM pQbssLoad,
+	IN USHORT LengthVIE,
+	IN PNDIS_802_11_VARIABLE_IEs pVIE);
+
+ULONG  BssTableSetEntry(
+	IN  PRTMP_ADAPTER   pAd,
+	OUT PBSS_TABLE pTab,
+	IN PUCHAR pBssid,
+	IN CHAR Ssid[],
+	IN UCHAR SsidLen,
+	IN UCHAR BssType,
+	IN USHORT BeaconPeriod,
+	IN CF_PARM *CfParm,
+	IN USHORT AtimWin,
+	IN USHORT CapabilityInfo,
+	IN UCHAR SupRate[],
+	IN UCHAR SupRateLen,
+	IN UCHAR ExtRate[],
+	IN UCHAR ExtRateLen,
+	IN HT_CAPABILITY_IE *pHtCapability,
+	IN ADD_HT_INFO_IE *pAddHtInfo,	// AP might use this additional ht info IE
+	IN UCHAR			HtCapabilityLen,
+	IN UCHAR			AddHtInfoLen,
+	IN UCHAR			NewExtChanOffset,
+	IN UCHAR Channel,
+	IN CHAR Rssi,
+	IN LARGE_INTEGER TimeStamp,
+	IN UCHAR CkipFlag,
+	IN PEDCA_PARM pEdcaParm,
+	IN PQOS_CAPABILITY_PARM pQosCapability,
+	IN PQBSS_LOAD_PARM pQbssLoad,
+	IN USHORT LengthVIE,
+	IN PNDIS_802_11_VARIABLE_IEs pVIE);
+
+#ifdef DOT11_N_SUPPORT
+VOID BATableInsertEntry(
+    IN	PRTMP_ADAPTER	pAd,
+	IN USHORT Aid,
+    IN USHORT		TimeOutValue,
+	IN USHORT		StartingSeq,
+    IN UCHAR TID,
+	IN UCHAR BAWinSize,
+	IN UCHAR OriginatorStatus,
+    IN BOOLEAN IsRecipient);
+
+#ifdef DOT11N_DRAFT3
+VOID Bss2040CoexistTimeOut(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3);
+
+
+VOID  TriEventInit(
+	IN	PRTMP_ADAPTER	pAd);
+
+ULONG TriEventTableSetEntry(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT TRIGGER_EVENT_TAB *Tab,
+	IN PUCHAR pBssid,
+	IN HT_CAPABILITY_IE *pHtCapability,
+	IN UCHAR			HtCapabilityLen,
+	IN UCHAR			RegClass,
+	IN UCHAR ChannelNo);
+
+VOID TriEventCounterMaintenance(
+	IN	PRTMP_ADAPTER	pAd);
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+
+VOID BssTableSsidSort(
+	IN  PRTMP_ADAPTER   pAd,
+	OUT BSS_TABLE *OutTab,
+	IN  CHAR Ssid[],
+	IN  UCHAR SsidLen);
+
+VOID  BssTableSortByRssi(
+	IN OUT BSS_TABLE *OutTab);
+
+VOID BssCipherParse(
+	IN OUT  PBSS_ENTRY  pBss);
+
+NDIS_STATUS  MlmeQueueInit(
+	IN MLME_QUEUE *Queue);
+
+VOID  MlmeQueueDestroy(
+	IN MLME_QUEUE *Queue);
+
+BOOLEAN MlmeEnqueue(
+	IN PRTMP_ADAPTER pAd,
+	IN ULONG Machine,
+	IN ULONG MsgType,
+	IN ULONG MsgLen,
+	IN VOID *Msg);
+
+BOOLEAN MlmeEnqueueForRecv(
+	IN  PRTMP_ADAPTER   pAd,
+	IN ULONG Wcid,
+	IN ULONG TimeStampHigh,
+	IN ULONG TimeStampLow,
+	IN UCHAR Rssi0,
+	IN UCHAR Rssi1,
+	IN UCHAR Rssi2,
+	IN ULONG MsgLen,
+	IN PVOID Msg,
+	IN UCHAR Signal);
+
+
+BOOLEAN MlmeDequeue(
+	IN MLME_QUEUE *Queue,
+	OUT MLME_QUEUE_ELEM **Elem);
+
+VOID    MlmeRestartStateMachine(
+	IN  PRTMP_ADAPTER   pAd);
+
+BOOLEAN  MlmeQueueEmpty(
+	IN MLME_QUEUE *Queue);
+
+BOOLEAN  MlmeQueueFull(
+	IN MLME_QUEUE *Queue);
+
+BOOLEAN  MsgTypeSubst(
+	IN PRTMP_ADAPTER pAd,
+	IN PFRAME_802_11 pFrame,
+	OUT INT *Machine,
+	OUT INT *MsgType);
+
+VOID StateMachineInit(
+	IN STATE_MACHINE *Sm,
+	IN STATE_MACHINE_FUNC Trans[],
+	IN ULONG StNr,
+	IN ULONG MsgNr,
+	IN STATE_MACHINE_FUNC DefFunc,
+	IN ULONG InitState,
+	IN ULONG Base);
+
+VOID StateMachineSetAction(
+	IN STATE_MACHINE *S,
+	IN ULONG St,
+	ULONG Msg,
+	IN STATE_MACHINE_FUNC F);
+
+VOID StateMachinePerformAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN STATE_MACHINE *S,
+	IN MLME_QUEUE_ELEM *Elem);
+
+VOID Drop(
+	IN  PRTMP_ADAPTER   pAd,
+	IN MLME_QUEUE_ELEM *Elem);
+
+VOID AssocStateMachineInit(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  STATE_MACHINE *Sm,
+	OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID ReassocTimeout(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3);
+
+VOID AssocTimeout(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3);
+
+VOID DisassocTimeout(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3);
+
+//----------------------------------------------
+VOID MlmeDisassocReqAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeAssocReqAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeReassocReqAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeDisassocReqAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID PeerAssocRspAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID PeerReassocRspAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID PeerDisassocAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID DisassocTimeoutAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID AssocTimeoutAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID  ReassocTimeoutAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID  Cls3errAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR pAddr);
+
+VOID SwitchBetweenWepAndCkip(
+	IN PRTMP_ADAPTER pAd);
+
+VOID  InvalidStateWhenAssoc(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID  InvalidStateWhenReassoc(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID InvalidStateWhenDisassociate(
+	IN  PRTMP_ADAPTER pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+#ifdef RT2870
+VOID MlmeCntlConfirm(
+	IN PRTMP_ADAPTER pAd,
+	IN ULONG MsgType,
+	IN USHORT Msg);
+#endif // RT2870 //
+
+VOID  ComposePsPoll(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID  ComposeNullFrame(
+	IN  PRTMP_ADAPTER pAd);
+
+VOID  AssocPostProc(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR pAddr2,
+	IN  USHORT CapabilityInfo,
+	IN  USHORT Aid,
+	IN  UCHAR SupRate[],
+	IN  UCHAR SupRateLen,
+	IN  UCHAR ExtRate[],
+	IN  UCHAR ExtRateLen,
+	IN PEDCA_PARM pEdcaParm,
+	IN HT_CAPABILITY_IE		*pHtCapability,
+	IN  UCHAR HtCapabilityLen,
+	IN ADD_HT_INFO_IE		*pAddHtInfo);
+
+VOID AuthStateMachineInit(
+	IN  PRTMP_ADAPTER   pAd,
+	IN PSTATE_MACHINE sm,
+	OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID AuthTimeout(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3);
+
+VOID MlmeAuthReqAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID PeerAuthRspAtSeq2Action(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID PeerAuthRspAtSeq4Action(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID AuthTimeoutAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID Cls2errAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR pAddr);
+
+VOID MlmeDeauthReqAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID InvalidStateWhenAuth(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+//=============================================
+
+VOID AuthRspStateMachineInit(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PSTATE_MACHINE Sm,
+	IN  STATE_MACHINE_FUNC Trans[]);
+
+VOID PeerDeauthAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerAuthSimpleRspGenAndSend(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PHEADER_802_11  pHdr80211,
+	IN  USHORT Alg,
+	IN  USHORT Seq,
+	IN  USHORT Reason,
+	IN  USHORT Status);
+
+//
+// Private routines in dls.c
+//
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+void DlsStateMachineInit(
+    IN PRTMP_ADAPTER pAd,
+    IN STATE_MACHINE *Sm,
+    OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID MlmeDlsReqAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerDlsReqAction(
+    IN PRTMP_ADAPTER	pAd,
+    IN MLME_QUEUE_ELEM	*Elem);
+
+VOID PeerDlsRspAction(
+    IN PRTMP_ADAPTER	pAd,
+    IN MLME_QUEUE_ELEM	*Elem);
+
+VOID MlmeDlsTearDownAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerDlsTearDownAction(
+    IN PRTMP_ADAPTER	pAd,
+    IN MLME_QUEUE_ELEM	*Elem);
+
+VOID RTMPCheckDLSTimeOut(
+	IN PRTMP_ADAPTER	pAd);
+
+BOOLEAN RTMPRcvFrameDLSCheck(
+	IN PRTMP_ADAPTER	pAd,
+	IN PHEADER_802_11	pHeader,
+	IN ULONG			Len,
+	IN PRT28XX_RXD_STRUC	pRxD);
+
+INT	RTMPCheckDLSFrame(
+	IN	PRTMP_ADAPTER	pAd,
+	IN  PUCHAR          pDA);
+
+VOID RTMPSendDLSTearDownFrame(
+	IN	PRTMP_ADAPTER	pAd,
+	IN  PUCHAR          pDA);
+
+NDIS_STATUS RTMPSendSTAKeyRequest(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pDA);
+
+NDIS_STATUS RTMPSendSTAKeyHandShake(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pDA);
+
+VOID DlsTimeoutAction(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3);
+
+BOOLEAN MlmeDlsReqSanity(
+	IN PRTMP_ADAPTER pAd,
+    IN VOID *Msg,
+    IN ULONG MsgLen,
+    OUT PRT_802_11_DLS *pDLS,
+    OUT PUSHORT pReason);
+
+INT Set_DlsEntryInfo_Display_Proc(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR arg);
+
+MAC_TABLE_ENTRY *MacTableInsertDlsEntry(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR	pAddr,
+	IN  UINT	DlsEntryIdx);
+
+BOOLEAN MacTableDeleteDlsEntry(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT wcid,
+	IN PUCHAR pAddr);
+
+MAC_TABLE_ENTRY *DlsEntryTableLookup(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR	pAddr,
+	IN BOOLEAN	bResetIdelCount);
+
+MAC_TABLE_ENTRY *DlsEntryTableLookupByWcid(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR	wcid,
+	IN PUCHAR	pAddr,
+	IN BOOLEAN	bResetIdelCount);
+
+INT	Set_DlsAddEntry_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_DlsTearDownEntry_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef QOS_DLS_SUPPORT
+BOOLEAN PeerDlsReqSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *Msg,
+    IN ULONG MsgLen,
+    OUT PUCHAR pDA,
+    OUT PUCHAR pSA,
+    OUT USHORT *pCapabilityInfo,
+    OUT USHORT *pDlsTimeout,
+    OUT UCHAR *pRatesLen,
+    OUT UCHAR Rates[],
+    OUT UCHAR *pHtCapabilityLen,
+    OUT HT_CAPABILITY_IE *pHtCapability);
+
+BOOLEAN PeerDlsRspSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *Msg,
+    IN ULONG MsgLen,
+    OUT PUCHAR pDA,
+    OUT PUCHAR pSA,
+    OUT USHORT *pCapabilityInfo,
+    OUT USHORT *pStatus,
+    OUT UCHAR *pRatesLen,
+    OUT UCHAR Rates[],
+    OUT UCHAR *pHtCapabilityLen,
+    OUT HT_CAPABILITY_IE *pHtCapability);
+
+BOOLEAN PeerDlsTearDownSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *Msg,
+    IN ULONG MsgLen,
+    OUT PUCHAR pDA,
+    OUT PUCHAR pSA,
+    OUT USHORT *pReason);
+#endif // QOS_DLS_SUPPORT //
+
+//========================================
+
+VOID SyncStateMachineInit(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  STATE_MACHINE *Sm,
+	OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID BeaconTimeout(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3);
+
+VOID ScanTimeout(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3);
+
+VOID MlmeScanReqAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID InvalidStateWhenScan(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID InvalidStateWhenJoin(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID InvalidStateWhenStart(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID PeerBeacon(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID EnqueueProbeRequest(
+	IN PRTMP_ADAPTER pAd);
+
+BOOLEAN ScanRunning(
+		IN PRTMP_ADAPTER pAd);
+//=========================================
+
+VOID MlmeCntlInit(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  STATE_MACHINE *S,
+	OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID MlmeCntlMachinePerformAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  STATE_MACHINE *S,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID CntlIdleProc(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID CntlOidScanProc(
+	IN  PRTMP_ADAPTER pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID CntlOidSsidProc(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM * Elem);
+
+VOID CntlOidRTBssidProc(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM * Elem);
+
+VOID CntlMlmeRoamingProc(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM * Elem);
+
+VOID CntlWaitDisassocProc(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID CntlWaitJoinProc(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID CntlWaitReassocProc(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID CntlWaitStartProc(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID CntlWaitAuthProc(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID CntlWaitAuthProc2(
+	IN  PRTMP_ADAPTER pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID CntlWaitAssocProc(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+#ifdef QOS_DLS_SUPPORT
+VOID CntlOidDLSSetupProc(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem);
+#endif // QOS_DLS_SUPPORT //
+
+VOID LinkUp(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  UCHAR BssType);
+
+VOID LinkDown(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  BOOLEAN         IsReqFromAP);
+
+VOID IterateOnBssTab(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID IterateOnBssTab2(
+	IN  PRTMP_ADAPTER   pAd);;
+
+VOID JoinParmFill(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  OUT MLME_JOIN_REQ_STRUCT *JoinReq,
+	IN  ULONG BssIdx);
+
+VOID AssocParmFill(
+	IN  PRTMP_ADAPTER   pAd,
+	IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq,
+	IN  PUCHAR pAddr,
+	IN  USHORT CapabilityInfo,
+	IN  ULONG Timeout,
+	IN  USHORT ListenIntv);
+
+VOID ScanParmFill(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  OUT MLME_SCAN_REQ_STRUCT *ScanReq,
+	IN  CHAR Ssid[],
+	IN  UCHAR SsidLen,
+	IN  UCHAR BssType,
+	IN  UCHAR ScanType);
+
+VOID DisassocParmFill(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq,
+	IN  PUCHAR pAddr,
+	IN  USHORT Reason);
+
+VOID StartParmFill(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  OUT MLME_START_REQ_STRUCT *StartReq,
+	IN  CHAR Ssid[],
+	IN  UCHAR SsidLen);
+
+VOID AuthParmFill(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  OUT MLME_AUTH_REQ_STRUCT *AuthReq,
+	IN  PUCHAR pAddr,
+	IN  USHORT Alg);
+
+VOID EnqueuePsPoll(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID EnqueueBeaconFrame(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID MlmeJoinReqAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeScanReqAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeStartReqAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID ScanTimeoutAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID BeaconTimeoutAtJoinAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID PeerBeaconAtScanAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID PeerBeaconAtJoinAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID PeerBeacon(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID PeerProbeReqAction(
+	IN  PRTMP_ADAPTER pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID ScanNextChannel(
+	IN  PRTMP_ADAPTER   pAd);
+
+ULONG MakeIbssBeacon(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID CCXAdjacentAPReport(
+	IN  PRTMP_ADAPTER   pAd);
+
+BOOLEAN MlmeScanReqSanity(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  VOID *Msg,
+	IN  ULONG MsgLen,
+	OUT UCHAR *BssType,
+	OUT CHAR ssid[],
+	OUT UCHAR *SsidLen,
+	OUT UCHAR *ScanType);
+
+BOOLEAN PeerBeaconAndProbeRspSanity(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  VOID *Msg,
+	IN  ULONG MsgLen,
+	IN  UCHAR MsgChannel,
+	OUT PUCHAR pAddr2,
+	OUT PUCHAR pBssid,
+	OUT CHAR Ssid[],
+	OUT UCHAR *pSsidLen,
+	OUT UCHAR *pBssType,
+	OUT USHORT *pBeaconPeriod,
+	OUT UCHAR *pChannel,
+	OUT UCHAR *pNewChannel,
+	OUT LARGE_INTEGER *pTimestamp,
+	OUT CF_PARM *pCfParm,
+	OUT USHORT *pAtimWin,
+	OUT USHORT *pCapabilityInfo,
+	OUT UCHAR *pErp,
+	OUT UCHAR *pDtimCount,
+	OUT UCHAR *pDtimPeriod,
+	OUT UCHAR *pBcastFlag,
+	OUT UCHAR *pMessageToMe,
+	OUT UCHAR SupRate[],
+	OUT UCHAR *pSupRateLen,
+	OUT UCHAR ExtRate[],
+	OUT UCHAR *pExtRateLen,
+	OUT	UCHAR *pCkipFlag,
+	OUT	UCHAR *pAironetCellPowerLimit,
+	OUT PEDCA_PARM       pEdcaParm,
+	OUT PQBSS_LOAD_PARM  pQbssLoad,
+	OUT PQOS_CAPABILITY_PARM pQosCapability,
+	OUT ULONG *pRalinkIe,
+	OUT UCHAR		 *pHtCapabilityLen,
+#ifdef CONFIG_STA_SUPPORT
+	OUT UCHAR		 *pPreNHtCapabilityLen,
+#endif // CONFIG_STA_SUPPORT //
+	OUT HT_CAPABILITY_IE *pHtCapability,
+	OUT UCHAR		 *AddHtInfoLen,
+	OUT ADD_HT_INFO_IE *AddHtInfo,
+	OUT UCHAR *NewExtChannel,
+	OUT USHORT *LengthVIE,
+	OUT PNDIS_802_11_VARIABLE_IEs pVIE);
+
+BOOLEAN PeerAddBAReqActionSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *pMsg,
+    IN ULONG MsgLen,
+	OUT PUCHAR pAddr2);
+
+BOOLEAN PeerAddBARspActionSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *pMsg,
+    IN ULONG MsgLen);
+
+BOOLEAN PeerDelBAActionSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN UCHAR Wcid,
+    IN VOID *pMsg,
+    IN ULONG MsgLen);
+
+BOOLEAN MlmeAssocReqSanity(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  VOID *Msg,
+	IN  ULONG MsgLen,
+	OUT PUCHAR pApAddr,
+	OUT USHORT *CapabilityInfo,
+	OUT ULONG *Timeout,
+	OUT USHORT *ListenIntv);
+
+BOOLEAN MlmeAuthReqSanity(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  VOID *Msg,
+	IN  ULONG MsgLen,
+	OUT PUCHAR pAddr,
+	OUT ULONG *Timeout,
+	OUT USHORT *Alg);
+
+BOOLEAN MlmeStartReqSanity(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  VOID *Msg,
+	IN  ULONG MsgLen,
+	OUT CHAR Ssid[],
+	OUT UCHAR *Ssidlen);
+
+BOOLEAN PeerAuthSanity(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  VOID *Msg,
+	IN  ULONG MsgLen,
+	OUT PUCHAR pAddr,
+	OUT USHORT *Alg,
+	OUT USHORT *Seq,
+	OUT USHORT *Status,
+	OUT CHAR ChlgText[]);
+
+BOOLEAN PeerAssocRspSanity(
+	IN  PRTMP_ADAPTER   pAd,
+    IN VOID *pMsg,
+	IN  ULONG MsgLen,
+	OUT PUCHAR pAddr2,
+	OUT USHORT *pCapabilityInfo,
+	OUT USHORT *pStatus,
+	OUT USHORT *pAid,
+	OUT UCHAR SupRate[],
+	OUT UCHAR *pSupRateLen,
+	OUT UCHAR ExtRate[],
+	OUT UCHAR *pExtRateLen,
+    OUT HT_CAPABILITY_IE		*pHtCapability,
+    OUT ADD_HT_INFO_IE		*pAddHtInfo,	// AP might use this additional ht info IE
+    OUT UCHAR			*pHtCapabilityLen,
+    OUT UCHAR			*pAddHtInfoLen,
+    OUT UCHAR			*pNewExtChannelOffset,
+	OUT PEDCA_PARM pEdcaParm,
+	OUT UCHAR *pCkipFlag);
+
+BOOLEAN PeerDisassocSanity(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  VOID *Msg,
+	IN  ULONG MsgLen,
+	OUT PUCHAR pAddr2,
+	OUT USHORT *Reason);
+
+BOOLEAN PeerWpaMessageSanity(
+    IN 	PRTMP_ADAPTER 		pAd,
+    IN 	PEAPOL_PACKET 		pMsg,
+    IN 	ULONG 				MsgLen,
+    IN 	UCHAR				MsgType,
+    IN 	MAC_TABLE_ENTRY  	*pEntry);
+
+BOOLEAN PeerDeauthSanity(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  VOID *Msg,
+	IN  ULONG MsgLen,
+	OUT PUCHAR pAddr2,
+	OUT USHORT *Reason);
+
+BOOLEAN PeerProbeReqSanity(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  VOID *Msg,
+	IN  ULONG MsgLen,
+	OUT PUCHAR pAddr2,
+	OUT CHAR Ssid[],
+	OUT UCHAR *pSsidLen);
+
+BOOLEAN GetTimBit(
+	IN  CHAR *Ptr,
+	IN  USHORT Aid,
+	OUT UCHAR *TimLen,
+	OUT UCHAR *BcastFlag,
+	OUT UCHAR *DtimCount,
+	OUT UCHAR *DtimPeriod,
+	OUT UCHAR *MessageToMe);
+
+UCHAR ChannelSanity(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR channel);
+
+NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(
+	IN PBSS_ENTRY pBss);
+
+BOOLEAN MlmeDelBAReqSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *Msg,
+    IN ULONG MsgLen);
+
+BOOLEAN MlmeAddBAReqSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *Msg,
+    IN ULONG MsgLen,
+    OUT PUCHAR pAddr2);
+
+ULONG MakeOutgoingFrame(
+	OUT CHAR *Buffer,
+	OUT ULONG *Length, ...);
+
+VOID  LfsrInit(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  ULONG Seed);
+
+UCHAR RandomByte(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID AsicUpdateAutoFallBackTable(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pTxRate);
+
+VOID  MlmePeriodicExec(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3);
+
+VOID LinkDownExec(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3);
+
+VOID LinkUpExec(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3);
+
+VOID STAMlmePeriodicExec(
+	PRTMP_ADAPTER pAd);
+
+VOID MlmeAutoScan(
+	IN PRTMP_ADAPTER pAd);
+
+VOID MlmeAutoReconnectLastSSID(
+	IN PRTMP_ADAPTER pAd);
+
+BOOLEAN MlmeValidateSSID(
+	IN PUCHAR pSsid,
+	IN UCHAR  SsidLen);
+
+VOID MlmeCheckForRoaming(
+	IN PRTMP_ADAPTER pAd,
+	IN ULONG    Now32);
+
+VOID MlmeCheckForFastRoaming(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  ULONG           Now);
+
+VOID MlmeDynamicTxRateSwitching(
+	IN PRTMP_ADAPTER pAd);
+
+VOID MlmeSetTxRate(
+	IN PRTMP_ADAPTER		pAd,
+	IN PMAC_TABLE_ENTRY		pEntry,
+	IN PRTMP_TX_RATE_SWITCH	pTxRate);
+
+VOID MlmeSelectTxRateTable(
+	IN PRTMP_ADAPTER		pAd,
+	IN PMAC_TABLE_ENTRY		pEntry,
+	IN PUCHAR				*ppTable,
+	IN PUCHAR				pTableSize,
+	IN PUCHAR				pInitTxRateIdx);
+
+VOID MlmeCalculateChannelQuality(
+	IN PRTMP_ADAPTER pAd,
+	IN ULONG Now);
+
+VOID MlmeCheckPsmChange(
+	IN PRTMP_ADAPTER pAd,
+	IN ULONG    Now32);
+
+VOID MlmeSetPsmBit(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT psm);
+
+VOID MlmeSetTxPreamble(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT TxPreamble);
+
+VOID UpdateBasicRateBitmap(
+	IN	PRTMP_ADAPTER	pAd);
+
+VOID MlmeUpdateTxRates(
+	IN PRTMP_ADAPTER 	pAd,
+	IN 	BOOLEAN		 	bLinkUp,
+	IN	UCHAR			apidx);
+
+#ifdef DOT11_N_SUPPORT
+VOID MlmeUpdateHtTxRates(
+	IN PRTMP_ADAPTER 		pAd,
+	IN	UCHAR				apidx);
+#endif // DOT11_N_SUPPORT //
+
+VOID    RTMPCheckRates(
+	IN      PRTMP_ADAPTER   pAd,
+	IN OUT  UCHAR           SupRate[],
+	IN OUT  UCHAR           *SupRateLen);
+
+#ifdef CONFIG_STA_SUPPORT
+BOOLEAN RTMPCheckChannel(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR		CentralChannel,
+	IN UCHAR		Channel);
+#endif // CONFIG_STA_SUPPORT //
+
+BOOLEAN 	RTMPCheckHt(
+	IN		PRTMP_ADAPTER	pAd,
+	IN		UCHAR	Wcid,
+	IN OUT	HT_CAPABILITY_IE			*pHtCapability,
+	IN OUT	ADD_HT_INFO_IE			*pAddHtInfo);
+
+VOID StaQuickResponeForRateUpExec(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3);
+
+VOID AsicBbpTuning1(
+	IN PRTMP_ADAPTER pAd);
+
+VOID AsicBbpTuning2(
+	IN PRTMP_ADAPTER pAd);
+
+VOID RTMPUpdateMlmeRate(
+	IN PRTMP_ADAPTER	pAd);
+
+CHAR RTMPMaxRssi(
+	IN PRTMP_ADAPTER	pAd,
+	IN CHAR				Rssi0,
+	IN CHAR				Rssi1,
+	IN CHAR				Rssi2);
+
+VOID AsicSetRxAnt(
+	IN PRTMP_ADAPTER	pAd,
+	IN UCHAR			Ant);
+
+VOID AsicEvaluateRxAnt(
+	IN PRTMP_ADAPTER	pAd);
+
+VOID AsicRxAntEvalTimeout(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3);
+
+VOID APSDPeriodicExec(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3);
+
+BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(
+	IN PRTMP_ADAPTER    pAd,
+	IN PMAC_TABLE_ENTRY	pEntry);
+
+UCHAR RTMPStaFixedTxMode(
+	IN PRTMP_ADAPTER    pAd,
+	IN PMAC_TABLE_ENTRY	pEntry);
+
+VOID RTMPUpdateLegacyTxSetting(
+		UCHAR				fixed_tx_mode,
+		PMAC_TABLE_ENTRY	pEntry);
+
+BOOLEAN RTMPAutoRateSwitchCheck(
+	IN PRTMP_ADAPTER    pAd);
+
+NDIS_STATUS MlmeInit(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID MlmeHandler(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID MlmeHalt(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID MlmeResetRalinkCounters(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID BuildChannelList(
+	IN PRTMP_ADAPTER pAd);
+
+UCHAR FirstChannel(
+	IN  PRTMP_ADAPTER   pAd);
+
+UCHAR NextChannel(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  UCHAR channel);
+
+VOID ChangeToCellPowerLimit(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR         AironetCellPowerLimit);
+
+VOID RaiseClock(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  UINT32 *x);
+
+VOID LowerClock(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  UINT32 *x);
+
+USHORT ShiftInBits(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID ShiftOutBits(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  USHORT data,
+	IN  USHORT count);
+
+VOID EEpromCleanup(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID EWDS(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID EWEN(
+	IN  PRTMP_ADAPTER   pAd);
+
+USHORT RTMP_EEPROM_READ16(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  USHORT Offset);
+
+VOID RTMP_EEPROM_WRITE16(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  USHORT Offset,
+	IN  USHORT Data);
+
+//
+// Prototypes of function definition in rtmp_tkip.c
+//
+VOID    RTMPInitTkipEngine(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR          pTKey,
+	IN  UCHAR           KeyId,
+	IN  PUCHAR          pTA,
+	IN  PUCHAR          pMICKey,
+	IN  PUCHAR          pTSC,
+	OUT PULONG          pIV16,
+	OUT PULONG          pIV32);
+
+VOID    RTMPInitMICEngine(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR          pKey,
+	IN  PUCHAR          pDA,
+	IN  PUCHAR          pSA,
+	IN  UCHAR           UserPriority,
+	IN  PUCHAR          pMICKey);
+
+BOOLEAN RTMPTkipCompareMICValue(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR          pSrc,
+	IN  PUCHAR          pDA,
+	IN  PUCHAR          pSA,
+	IN  PUCHAR          pMICKey,
+	IN	UCHAR			UserPriority,
+	IN  UINT            Len);
+
+VOID    RTMPCalculateMICValue(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PNDIS_PACKET    pPacket,
+	IN  PUCHAR          pEncap,
+	IN  PCIPHER_KEY     pKey,
+	IN	UCHAR			apidx);
+
+BOOLEAN RTMPTkipCompareMICValueWithLLC(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR          pLLC,
+	IN  PUCHAR          pSrc,
+	IN  PUCHAR          pDA,
+	IN  PUCHAR          pSA,
+	IN  PUCHAR          pMICKey,
+	IN  UINT            Len);
+
+VOID    RTMPTkipAppendByte(
+	IN  PTKIP_KEY_INFO  pTkip,
+	IN  UCHAR           uChar);
+
+VOID    RTMPTkipAppend(
+	IN  PTKIP_KEY_INFO  pTkip,
+	IN  PUCHAR          pSrc,
+	IN  UINT            nBytes);
+
+VOID    RTMPTkipGetMIC(
+	IN  PTKIP_KEY_INFO  pTkip);
+
+BOOLEAN RTMPSoftDecryptTKIP(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR	pData,
+	IN ULONG	DataByteCnt,
+	IN UCHAR    UserPriority,
+	IN PCIPHER_KEY	pWpaKey);
+
+BOOLEAN RTMPSoftDecryptAES(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR	pData,
+	IN ULONG	DataByteCnt,
+	IN PCIPHER_KEY	pWpaKey);
+
+//
+// Prototypes of function definition in cmm_info.c
+//
+NDIS_STATUS RTMPWPARemoveKeyProc(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PVOID           pBuf);
+
+VOID    RTMPWPARemoveAllKeys(
+	IN  PRTMP_ADAPTER   pAd);
+
+BOOLEAN RTMPCheckStrPrintAble(
+    IN  CHAR *pInPutStr,
+    IN  UCHAR strLen);
+
+VOID    RTMPSetPhyMode(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  ULONG phymode);
+
+VOID	RTMPUpdateHTIE(
+	IN	RT_HT_CAPABILITY	*pRtHt,
+	IN		UCHAR				*pMcsSet,
+	OUT		HT_CAPABILITY_IE *pHtCapability,
+	OUT		ADD_HT_INFO_IE		*pAddHtInfo);
+
+VOID	RTMPAddWcidAttributeEntry(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			BssIdx,
+	IN 	UCHAR		 	KeyIdx,
+	IN 	UCHAR		 	CipherAlg,
+	IN 	MAC_TABLE_ENTRY *pEntry);
+
+CHAR *GetEncryptType(
+	CHAR enc);
+
+CHAR *GetAuthMode(
+	CHAR auth);
+
+VOID RTMPIoctlGetSiteSurvey(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq);
+
+VOID RTMPIoctlGetMacTable(
+	IN PRTMP_ADAPTER pAd,
+	IN struct iwreq *wrq);
+
+VOID RTMPIndicateWPA2Status(
+	IN  PRTMP_ADAPTER  pAdapter);
+
+VOID	RTMPOPModeSwitching(
+	IN	PRTMP_ADAPTER	pAd);
+
+#ifdef CONFIG_STA_SUPPORT
+VOID    RTMPAddBSSIDCipher(
+    IN  PRTMP_ADAPTER   pAd,
+	IN	UCHAR	Aid,
+    IN  PNDIS_802_11_KEY    pKey,
+    IN  UCHAR   CipherAlg);
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef DOT11_N_SUPPORT
+VOID	RTMPSetHT(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	OID_SET_HT_PHYMODE *pHTPhyMode);
+
+VOID	RTMPSetIndividualHT(
+	IN	PRTMP_ADAPTER		pAd,
+	IN	UCHAR				apidx);
+#endif // DOT11_N_SUPPORT //
+
+VOID RTMPSendWirelessEvent(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT			Event_flag,
+	IN	PUCHAR 			pAddr,
+	IN  UCHAR			BssIdx,
+	IN	CHAR			Rssi);
+
+VOID	NICUpdateCntlCounters(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PHEADER_802_11	pHeader,
+	IN    UCHAR			SubType,
+	IN	PRXWI_STRUC 	pRxWI);
+//
+// prototype in wpa.c
+//
+BOOLEAN WpaMsgTypeSubst(
+	IN  UCHAR   EAPType,
+	OUT INT		*MsgType);
+
+VOID WpaPskStateMachineInit(
+	IN  PRTMP_ADAPTER       pAd,
+	IN  STATE_MACHINE       *S,
+	OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID WpaEAPOLKeyAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID    WpaPairMsg1Action(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID    WpaPairMsg3Action(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID    WpaGroupMsg1Action(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID    WpaMacHeaderInit(
+	IN      PRTMP_ADAPTER   pAd,
+	IN OUT  PHEADER_802_11  pHdr80211,
+	IN      UCHAR           wep,
+	IN      PUCHAR          pAddr1);
+
+VOID    Wpa2PairMsg1Action(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  MLME_QUEUE_ELEM *Elem);
+
+VOID    Wpa2PairMsg3Action(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  MLME_QUEUE_ELEM *Elem);
+
+BOOLEAN ParseKeyData(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  PUCHAR          pKeyData,
+    IN  UCHAR           KeyDataLen,
+	IN	UCHAR			bPairewise);
+
+VOID    RTMPToWirelessSta(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR          pHeader802_3,
+    IN  UINT            HdrLen,
+	IN  PUCHAR          pData,
+    IN  UINT            DataLen,
+    IN	BOOLEAN			is4wayFrame);
+
+VOID    HMAC_SHA1(
+	IN  UCHAR   *text,
+	IN  UINT    text_len,
+	IN  UCHAR   *key,
+	IN  UINT    key_len,
+	IN  UCHAR   *digest);
+
+VOID    PRF(
+	IN  UCHAR   *key,
+	IN  INT     key_len,
+	IN  UCHAR   *prefix,
+	IN  INT     prefix_len,
+	IN  UCHAR   *data,
+	IN  INT     data_len,
+	OUT UCHAR   *output,
+	IN  INT     len);
+
+VOID    CCKMPRF(
+	IN  UCHAR   *key,
+	IN  INT     key_len,
+	IN  UCHAR   *data,
+	IN  INT     data_len,
+	OUT UCHAR   *output,
+	IN  INT     len);
+
+VOID WpaCountPTK(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  UCHAR   *PMK,
+	IN  UCHAR   *ANonce,
+	IN  UCHAR   *AA,
+	IN  UCHAR   *SNonce,
+	IN  UCHAR   *SA,
+	OUT UCHAR   *output,
+	IN  UINT    len);
+
+VOID    GenRandom(
+	IN  PRTMP_ADAPTER   pAd,
+	IN	UCHAR			*macAddr,
+	OUT	UCHAR			*random);
+
+//
+// prototype in aironet.c
+//
+VOID    AironetStateMachineInit(
+	IN  PRTMP_ADAPTER       pAd,
+	IN  STATE_MACHINE       *S,
+	OUT STATE_MACHINE_FUNC  Trans[]);
+
+VOID    AironetMsgAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID    AironetRequestAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID    ChannelLoadRequestAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  UCHAR           Index);
+
+VOID    NoiseHistRequestAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  UCHAR           Index);
+
+VOID    BeaconRequestAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  UCHAR           Index);
+
+VOID    AironetReportAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem);
+
+VOID    ChannelLoadReportAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  UCHAR           Index);
+
+VOID    NoiseHistReportAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  UCHAR           Index);
+
+VOID    AironetFinalReportAction(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID    BeaconReportAction(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  UCHAR           Index);
+
+VOID    AironetAddBeaconReport(
+	IN  PRTMP_ADAPTER       pAd,
+	IN  ULONG               Index,
+	IN  PMLME_QUEUE_ELEM    pElem);
+
+VOID    AironetCreateBeaconReportFromBssTable(
+	IN  PRTMP_ADAPTER       pAd);
+
+VOID    DBGPRINT_TX_RING(
+	IN PRTMP_ADAPTER  pAd,
+	IN UCHAR          QueIdx);
+
+VOID DBGPRINT_RX_RING(
+	IN PRTMP_ADAPTER  pAd);
+
+CHAR    ConvertToRssi(
+	IN PRTMP_ADAPTER  pAd,
+	IN CHAR				Rssi,
+	IN UCHAR    RssiNumber);
+
+
+#ifdef DOT11N_DRAFT3
+VOID BuildEffectedChannelList(
+	IN PRTMP_ADAPTER pAd);
+#endif // DOT11N_DRAFT3 //
+
+
+VOID APAsicEvaluateRxAnt(
+	IN PRTMP_ADAPTER	pAd);
+
+
+VOID APAsicRxAntEvalTimeout(
+	IN PRTMP_ADAPTER	pAd);
+
+//
+// function prototype in cmm_wpa.c
+//
+BOOLEAN RTMPCheckWPAframe(
+	IN PRTMP_ADAPTER pAd,
+	IN PMAC_TABLE_ENTRY	pEntry,
+	IN PUCHAR 			pData,
+	IN ULONG 			DataByteCount,
+	IN UCHAR			FromWhichBSSID);
+
+VOID AES_GTK_KEY_UNWRAP(
+	IN  UCHAR   *key,
+	OUT UCHAR   *plaintext,
+	IN	UCHAR	c_len,
+	IN  UCHAR   *ciphertext);
+
+BOOLEAN RTMPCheckRSNIE(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR          pData,
+	IN  UCHAR           DataLen,
+	IN  MAC_TABLE_ENTRY *pEntry,
+	OUT	UCHAR			*Offset);
+
+BOOLEAN RTMPParseEapolKeyData(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR          pKeyData,
+	IN  UCHAR           KeyDataLen,
+	IN	UCHAR			GroupKeyIndex,
+	IN	UCHAR			MsgType,
+	IN	BOOLEAN			bWPA2,
+	IN  MAC_TABLE_ENTRY *pEntry);
+
+VOID	ConstructEapolMsg(
+	IN 	PRTMP_ADAPTER    	pAd,
+    IN 	UCHAR				PeerAuthMode,
+    IN 	UCHAR				PeerWepStatus,
+    IN 	UCHAR				MyGroupKeyWepStatus,
+    IN 	UCHAR				MsgType,
+    IN	UCHAR				DefaultKeyIdx,
+    IN 	UCHAR				*ReplayCounter,
+	IN 	UCHAR				*KeyNonce,
+	IN	UCHAR				*TxRSC,
+	IN	UCHAR				*PTK,
+	IN	UCHAR				*GTK,
+	IN	UCHAR				*RSNIE,
+	IN	UCHAR				RSNIE_Len,
+    OUT PEAPOL_PACKET       pMsg);
+
+VOID	CalculateMIC(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			PeerWepStatus,
+	IN	UCHAR			*PTK,
+	OUT PEAPOL_PACKET   pMsg);
+
+NDIS_STATUS	RTMPSoftDecryptBroadCastData(
+	IN	PRTMP_ADAPTER					pAd,
+	IN	RX_BLK							*pRxBlk,
+	IN  NDIS_802_11_ENCRYPTION_STATUS 	GroupCipher,
+	IN  PCIPHER_KEY						pShard_key);
+
+VOID	ConstructEapolKeyData(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			PeerAuthMode,
+	IN	UCHAR			PeerWepStatus,
+	IN	UCHAR			GroupKeyWepStatus,
+	IN 	UCHAR			MsgType,
+	IN	UCHAR			DefaultKeyIdx,
+	IN	BOOLEAN			bWPA2Capable,
+	IN	UCHAR			*PTK,
+	IN	UCHAR			*GTK,
+	IN	UCHAR			*RSNIE,
+	IN	UCHAR			RSNIE_LEN,
+	OUT PEAPOL_PACKET   pMsg);
+
+VOID RTMPMakeRSNIE(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  UINT            AuthMode,
+	IN  UINT            WepStatus,
+	IN	UCHAR			apidx);
+
+//
+// function prototype in ap_wpa.c
+//
+
+BOOLEAN APWpaMsgTypeSubst(
+	IN UCHAR    EAPType,
+	OUT INT *MsgType) ;
+
+MAC_TABLE_ENTRY *PACInquiry(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  ULONG           Wcid);
+
+BOOLEAN RTMPCheckMcast(
+	IN PRTMP_ADAPTER pAd,
+	IN PEID_STRUCT      eid_ptr,
+	IN MAC_TABLE_ENTRY  *pEntry);
+
+BOOLEAN RTMPCheckUcast(
+	IN PRTMP_ADAPTER pAd,
+	IN PEID_STRUCT      eid_ptr,
+	IN MAC_TABLE_ENTRY  *pEntry);
+
+BOOLEAN RTMPCheckAUTH(
+	IN PRTMP_ADAPTER pAd,
+	IN PEID_STRUCT      eid_ptr,
+	IN MAC_TABLE_ENTRY  *pEntry);
+
+VOID WPAStart4WayHS(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MAC_TABLE_ENTRY *pEntry,
+	IN	ULONG			TimeInterval);
+
+VOID WPAStart2WayGroupHS(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MAC_TABLE_ENTRY *pEntry);
+
+VOID APWpaEAPPacketAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem);
+
+VOID APWpaEAPOLStartAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem);
+
+VOID APWpaEAPOLLogoffAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem);
+
+VOID APWpaEAPOLKeyAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem);
+
+VOID APWpaEAPOLASFAlertAction(
+	IN  PRTMP_ADAPTER    pAd,
+	IN  MLME_QUEUE_ELEM  *Elem);
+
+VOID HandleCounterMeasure(
+	IN PRTMP_ADAPTER pAd,
+	IN MAC_TABLE_ENTRY  *pEntry);
+
+VOID PeerPairMsg2Action(
+	IN PRTMP_ADAPTER pAd,
+	IN MAC_TABLE_ENTRY  *pEntry,
+	IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerPairMsg4Action(
+	IN PRTMP_ADAPTER pAd,
+	IN MAC_TABLE_ENTRY  *pEntry,
+	IN MLME_QUEUE_ELEM *Elem);
+
+VOID CMTimerExec(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3);
+
+VOID WPARetryExec(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3);
+
+VOID EnqueueStartForPSKExec(
+    IN PVOID SystemSpecific1,
+    IN PVOID FunctionContext,
+    IN PVOID SystemSpecific2,
+    IN PVOID SystemSpecific3);
+
+VOID RTMPHandleSTAKey(
+    IN PRTMP_ADAPTER    pAdapter,
+    IN MAC_TABLE_ENTRY  *pEntry,
+    IN MLME_QUEUE_ELEM  *Elem);
+
+VOID PeerGroupMsg2Action(
+	IN  PRTMP_ADAPTER    pAd,
+	IN  PMAC_TABLE_ENTRY pEntry,
+	IN  VOID             *Msg,
+	IN  UINT             MsgLen);
+
+VOID PairDisAssocAction(
+	IN  PRTMP_ADAPTER    pAd,
+	IN  PMAC_TABLE_ENTRY pEntry,
+	IN  USHORT           Reason);
+
+VOID MlmeDeAuthAction(
+	IN  PRTMP_ADAPTER    pAd,
+	IN  PMAC_TABLE_ENTRY pEntry,
+	IN  USHORT           Reason);
+
+VOID GREKEYPeriodicExec(
+	IN  PVOID   SystemSpecific1,
+	IN  PVOID   FunctionContext,
+	IN  PVOID   SystemSpecific2,
+	IN  PVOID   SystemSpecific3);
+
+VOID CountGTK(
+	IN  UCHAR   *PMK,
+	IN  UCHAR   *GNonce,
+	IN  UCHAR   *AA,
+	OUT UCHAR   *output,
+	IN  UINT    len);
+
+VOID    GetSmall(
+	IN  PVOID   pSrc1,
+	IN  PVOID   pSrc2,
+	OUT PUCHAR  out,
+	IN  ULONG   Length);
+
+VOID    GetLarge(
+	IN  PVOID   pSrc1,
+	IN  PVOID   pSrc2,
+	OUT PUCHAR  out,
+	IN  ULONG   Length);
+
+VOID APGenRandom(
+	IN PRTMP_ADAPTER pAd,
+	OUT UCHAR       *random);
+
+VOID AES_GTK_KEY_WRAP(
+	IN UCHAR *key,
+	IN UCHAR *plaintext,
+	IN UCHAR p_len,
+	OUT UCHAR *ciphertext);
+
+VOID    WpaSend(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          pPacket,
+    IN  ULONG           Len);
+
+VOID    APToWirelessSta(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MAC_TABLE_ENTRY *pEntry,
+	IN  PUCHAR          pHeader802_3,
+	IN  UINT            HdrLen,
+	IN  PUCHAR          pData,
+	IN  UINT            DataLen,
+    IN	BOOLEAN			bClearFrame);
+
+VOID RTMPAddPMKIDCache(
+	IN  PRTMP_ADAPTER   		pAd,
+	IN	INT						apidx,
+	IN	PUCHAR				pAddr,
+	IN	UCHAR					*PMKID,
+	IN	UCHAR					*PMK);
+
+INT RTMPSearchPMKIDCache(
+	IN  PRTMP_ADAPTER   pAd,
+	IN	INT				apidx,
+	IN	PUCHAR		pAddr);
+
+VOID RTMPDeletePMKIDCache(
+	IN  PRTMP_ADAPTER   pAd,
+	IN	INT				apidx,
+	IN  INT				idx);
+
+VOID RTMPMaintainPMKIDCache(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID	RTMPSendTriggerFrame(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PVOID			pBuffer,
+	IN	ULONG			Length,
+	IN  UCHAR           TxRate,
+	IN	BOOLEAN			bQosNull);
+
+#ifdef RT30xx
+VOID RTMPFilterCalibration(
+	IN PRTMP_ADAPTER pAd);
+#endif // RT30xx //
+
+
+//typedef void (*TIMER_FUNCTION)(unsigned long);
+
+
+/* timeout -- ms */
+VOID RTMP_SetPeriodicTimer(
+	IN	NDIS_MINIPORT_TIMER *pTimer,
+	IN	unsigned long timeout);
+
+VOID RTMP_OS_Init_Timer(
+	IN	PRTMP_ADAPTER pAd,
+	IN	NDIS_MINIPORT_TIMER *pTimer,
+	IN	TIMER_FUNCTION function,
+	IN	PVOID data);
+
+VOID RTMP_OS_Add_Timer(
+	IN	NDIS_MINIPORT_TIMER	*pTimer,
+	IN	unsigned long timeout);
+
+VOID RTMP_OS_Mod_Timer(
+	IN	NDIS_MINIPORT_TIMER	*pTimer,
+	IN	unsigned long timeout);
+
+
+VOID RTMP_OS_Del_Timer(
+	IN	NDIS_MINIPORT_TIMER	*pTimer,
+	OUT	BOOLEAN				 *pCancelled);
+
+
+VOID RTMP_OS_Release_Packet(
+	IN	PRTMP_ADAPTER pAd,
+	IN	PQUEUE_ENTRY  pEntry);
+
+VOID RTMPusecDelay(
+	IN	ULONG	usec);
+
+NDIS_STATUS os_alloc_mem(
+	IN	PRTMP_ADAPTER pAd,
+	OUT	PUCHAR *mem,
+	IN	ULONG  size);
+
+NDIS_STATUS os_free_mem(
+	IN	PRTMP_ADAPTER pAd,
+	IN	PUCHAR mem);
+
+
+void RTMP_AllocateSharedMemory(
+	IN	PRTMP_ADAPTER pAd,
+	IN	ULONG	Length,
+	IN	BOOLEAN	Cached,
+	OUT	PVOID	*VirtualAddress,
+	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
+
+VOID RTMPFreeTxRxRingMemory(
+    IN  PRTMP_ADAPTER   pAd);
+
+NDIS_STATUS AdapterBlockAllocateMemory(
+	IN PVOID	handle,
+	OUT	PVOID	*ppAd);
+
+void RTMP_AllocateTxDescMemory(
+	IN	PRTMP_ADAPTER pAd,
+	IN	UINT	Index,
+	IN	ULONG	Length,
+	IN	BOOLEAN	Cached,
+	OUT	PVOID	*VirtualAddress,
+	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
+
+void RTMP_AllocateFirstTxBuffer(
+	IN	PRTMP_ADAPTER pAd,
+	IN	UINT	Index,
+	IN	ULONG	Length,
+	IN	BOOLEAN	Cached,
+	OUT	PVOID	*VirtualAddress,
+	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
+
+void RTMP_AllocateMgmtDescMemory(
+	IN	PRTMP_ADAPTER pAd,
+	IN	ULONG	Length,
+	IN	BOOLEAN	Cached,
+	OUT	PVOID	*VirtualAddress,
+	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
+
+void RTMP_AllocateRxDescMemory(
+	IN	PRTMP_ADAPTER pAd,
+	IN	ULONG	Length,
+	IN	BOOLEAN	Cached,
+	OUT	PVOID	*VirtualAddress,
+	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
+
+PNDIS_PACKET RTMP_AllocateRxPacketBuffer(
+	IN	PRTMP_ADAPTER pAd,
+	IN	ULONG	Length,
+	IN	BOOLEAN	Cached,
+	OUT	PVOID	*VirtualAddress,
+	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
+
+PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
+	IN	PRTMP_ADAPTER pAd,
+	IN	ULONG	Length,
+	IN	BOOLEAN	Cached,
+	OUT	PVOID	*VirtualAddress);
+
+PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
+	IN	PRTMP_ADAPTER pAd,
+	IN	ULONG	Length);
+
+void RTMP_QueryPacketInfo(
+	IN  PNDIS_PACKET pPacket,
+	OUT PACKET_INFO  *pPacketInfo,
+	OUT PUCHAR		 *pSrcBufVA,
+	OUT	UINT		 *pSrcBufLen);
+
+void RTMP_QueryNextPacketInfo(
+	IN  PNDIS_PACKET *ppPacket,
+	OUT PACKET_INFO  *pPacketInfo,
+	OUT PUCHAR		 *pSrcBufVA,
+	OUT	UINT		 *pSrcBufLen);
+
+
+BOOLEAN RTMP_FillTxBlkInfo(
+	IN RTMP_ADAPTER *pAd,
+	IN TX_BLK *pTxBlk);
+
+
+PRTMP_SCATTER_GATHER_LIST
+rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg);
+
+
+ void announce_802_3_packet(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PNDIS_PACKET	pPacket);
+
+
+UINT BA_Reorder_AMSDU_Annnounce(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PNDIS_PACKET	pPacket);
+
+
+UINT Handle_AMSDU_Packet(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pData,
+	IN	ULONG			DataSize,
+	IN  UCHAR			FromWhichBSSID);
+
+
+void convert_802_11_to_802_3_packet(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PNDIS_PACKET	pPacket,
+	IN	PUCHAR			p8023hdr,
+	IN	PUCHAR			pData,
+	IN	ULONG			DataSize,
+	IN  UCHAR			FromWhichBSSID);
+
+
+PNET_DEV get_netdev_from_bssid(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			FromWhichBSSID);
+
+
+PNDIS_PACKET duplicate_pkt(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pHeader802_3,
+    IN  UINT            HdrLen,
+	IN	PUCHAR			pData,
+	IN	ULONG			DataSize,
+	IN	UCHAR			FromWhichBSSID);
+
+
+PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PNDIS_PACKET	pOldPkt);
+
+PNDIS_PACKET duplicate_pkt_with_VLAN(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pHeader802_3,
+    IN  UINT            HdrLen,
+	IN	PUCHAR			pData,
+	IN	ULONG			DataSize,
+	IN	UCHAR			FromWhichBSSID);
+
+PNDIS_PACKET duplicate_pkt_with_WPI(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PNDIS_PACKET	pPacket,
+	IN	UINT32			ext_head_len,
+	IN	UINT32			ext_tail_len);
+
+UCHAR VLAN_8023_Header_Copy(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pHeader802_3,
+	IN	UINT            HdrLen,
+	OUT PUCHAR			pData,
+	IN	UCHAR			FromWhichBSSID);
+
+#ifdef DOT11_N_SUPPORT
+void ba_flush_reordering_timeout_mpdus(
+	IN PRTMP_ADAPTER	pAd,
+	IN PBA_REC_ENTRY	pBAEntry,
+	IN ULONG			Now32);
+
+
+VOID BAOriSessionSetUp(
+			IN PRTMP_ADAPTER    pAd,
+			IN MAC_TABLE_ENTRY	*pEntry,
+			IN UCHAR			TID,
+			IN USHORT			TimeOut,
+			IN ULONG			DelayTime,
+			IN BOOLEAN		isForced);
+
+VOID BASessionTearDownALL(
+	IN OUT	PRTMP_ADAPTER pAd,
+	IN		UCHAR Wcid);
+#endif // DOT11_N_SUPPORT //
+
+BOOLEAN OS_Need_Clone_Packet(void);
+
+
+VOID build_tx_packet(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PNDIS_PACKET	pPacket,
+	IN	PUCHAR	pFrame,
+	IN	ULONG	FrameLen);
+
+
+VOID BAOriSessionTearDown(
+	IN OUT	PRTMP_ADAPTER	pAd,
+	IN		UCHAR			Wcid,
+	IN		UCHAR			TID,
+	IN		BOOLEAN			bPassive,
+	IN		BOOLEAN			bForceSend);
+
+VOID BARecSessionTearDown(
+	IN OUT	PRTMP_ADAPTER	pAd,
+	IN		UCHAR			Wcid,
+	IN		UCHAR			TID,
+	IN		BOOLEAN			bPassive);
+
+BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num);
+void ba_reordering_resource_release(PRTMP_ADAPTER pAd);
+
+ULONG AutoChBssInsertEntry(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pBssid,
+	IN CHAR Ssid[],
+	IN UCHAR SsidLen,
+	IN UCHAR ChannelNo,
+	IN CHAR Rssi);
+
+void AutoChBssTableInit(
+	IN PRTMP_ADAPTER pAd);
+
+void ChannelInfoInit(
+	IN PRTMP_ADAPTER pAd);
+
+void AutoChBssTableDestroy(
+	IN PRTMP_ADAPTER pAd);
+
+void ChannelInfoDestroy(
+	IN PRTMP_ADAPTER pAd);
+
+UCHAR New_ApAutoSelectChannel(
+	IN PRTMP_ADAPTER pAd);
+
+
+#ifdef NINTENDO_AP
+VOID	InitNINTENDO_TABLE(
+	IN PRTMP_ADAPTER pAd);
+
+UCHAR	CheckNINTENDO_TABLE(
+	IN PRTMP_ADAPTER pAd,
+	PCHAR pDS_Ssid,
+	UCHAR DS_SsidLen,
+	PUCHAR pDS_Addr);
+
+UCHAR	DelNINTENDO_ENTRY(
+	IN	PRTMP_ADAPTER pAd,
+	UCHAR * pDS_Addr);
+
+VOID	RTMPIoctlNintendoCapable(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	struct iwreq	*wrq);
+
+VOID	RTMPIoctlNintendoGetTable(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	struct iwreq	*wrq);
+
+VOID	RTMPIoctlNintendoSetTable(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	struct iwreq	*wrq);
+
+#endif // NINTENDO_AP //
+
+BOOLEAN rtstrmactohex(
+	IN char *s1,
+	IN char *s2);
+
+BOOLEAN rtstrcasecmp(
+	IN char *s1,
+	IN char *s2);
+
+char *rtstrstruncasecmp(
+	IN char *s1,
+	IN char *s2);
+
+char    *rtstrstr(
+	IN	const char * s1,
+	IN	const char * s2);
+
+char *rstrtok(
+	IN char * s,
+	IN const char * ct);
+
+int rtinet_aton(
+	const char *cp,
+	unsigned int *addr);
+
+////////// common ioctl functions //////////
+INT Set_DriverVersion_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT Set_CountryRegion_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT Set_CountryRegionABand_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT Set_WirelessMode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT Set_Channel_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_ShortSlot_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_TxPower_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT Set_BGProtection_Proc(
+	IN  PRTMP_ADAPTER		pAd,
+	IN  PUCHAR			arg);
+
+INT Set_TxPreamble_Proc(
+	IN  PRTMP_ADAPTER		pAd,
+	IN  PUCHAR			arg);
+
+INT Set_RTSThreshold_Proc(
+	IN  PRTMP_ADAPTER		pAd,
+	IN  PUCHAR			arg);
+
+INT Set_FragThreshold_Proc(
+	IN  PRTMP_ADAPTER		pAd,
+	IN  PUCHAR			arg);
+
+INT Set_TxBurst_Proc(
+	IN  PRTMP_ADAPTER		pAd,
+	IN  PUCHAR			arg);
+
+#ifdef AGGREGATION_SUPPORT
+INT	Set_PktAggregate_Proc(
+	IN  PRTMP_ADAPTER		pAd,
+	IN  PUCHAR			arg);
+#endif
+
+INT	Set_IEEE80211H_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+#ifdef DBG
+INT	Set_Debug_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+#endif
+
+INT	Show_DescInfo_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_ResetStatCounter_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+#ifdef DOT11_N_SUPPORT
+INT	Set_BASetup_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_BADecline_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_BAOriTearDown_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_BARecTearDown_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_HtBw_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_HtMcs_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_HtGi_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_HtOpMode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_HtStbc_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_HtHtc_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_HtExtcha_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_HtMpduDensity_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_HtBaWinSize_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_HtRdg_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_HtLinkAdapt_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_HtAmsdu_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_HtAutoBa_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_HtProtect_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_HtMimoPs_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+
+INT	Set_ForceShortGI_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_ForceGF_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	SetCommonHT(
+	IN	PRTMP_ADAPTER	pAd);
+
+INT	Set_SendPSMPAction_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT	Set_HtMIMOPSmode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+
+INT	Set_HtTxBASize_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+#endif // DOT11_N_SUPPORT //
+
+
+
+#ifdef CONFIG_STA_SUPPORT
+//Dls ,	kathy
+VOID RTMPSendDLSTearDownFrame(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pDA);
+
+#ifdef DOT11_N_SUPPORT
+//Block ACK
+VOID QueryBATABLE(
+	IN  PRTMP_ADAPTER pAd,
+	OUT PQUERYBA_TABLE pBAT);
+#endif // DOT11_N_SUPPORT //
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+INT	    WpaCheckEapCode(
+	IN  PRTMP_ADAPTER   	pAd,
+	IN  PUCHAR				pFrame,
+	IN  USHORT				FrameLen,
+	IN  USHORT				OffSet);
+
+VOID    WpaSendMicFailureToWpaSupplicant(
+    IN  PRTMP_ADAPTER       pAd,
+    IN  BOOLEAN             bUnicast);
+
+VOID    SendAssocIEsToWpaSupplicant(
+    IN  PRTMP_ADAPTER       pAd);
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+int wext_notify_event_assoc(
+	IN  RTMP_ADAPTER *pAd);
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+#endif // CONFIG_STA_SUPPORT //
+
+
+
+#ifdef DOT11_N_SUPPORT
+VOID Handle_BSS_Width_Trigger_Events(
+	IN PRTMP_ADAPTER pAd);
+
+void build_ext_channel_switch_ie(
+	IN PRTMP_ADAPTER pAd,
+	IN HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE *pIE);
+#endif // DOT11_N_SUPPORT //
+
+
+BOOLEAN APRxDoneInterruptHandle(
+	IN	PRTMP_ADAPTER	pAd);
+
+BOOLEAN STARxDoneInterruptHandle(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	BOOLEAN			argc);
+
+#ifdef DOT11_N_SUPPORT
+// AMPDU packet indication
+VOID Indicate_AMPDU_Packet(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	RX_BLK			*pRxBlk,
+	IN	UCHAR			FromWhichBSSID);
+
+// AMSDU packet indication
+VOID Indicate_AMSDU_Packet(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	RX_BLK			*pRxBlk,
+	IN	UCHAR			FromWhichBSSID);
+#endif // DOT11_N_SUPPORT //
+
+// Normal legacy Rx packet indication
+VOID Indicate_Legacy_Packet(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	RX_BLK			*pRxBlk,
+	IN	UCHAR			FromWhichBSSID);
+
+VOID Indicate_EAPOL_Packet(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	RX_BLK			*pRxBlk,
+	IN	UCHAR			FromWhichBSSID);
+
+void  update_os_packet_info(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	RX_BLK			*pRxBlk,
+	IN	UCHAR			FromWhichBSSID);
+
+void wlan_802_11_to_802_3_packet(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	RX_BLK			*pRxBlk,
+	IN	PUCHAR			pHeader802_3,
+	IN  UCHAR			FromWhichBSSID);
+
+UINT deaggregate_AMSDU_announce(
+	IN	PRTMP_ADAPTER	pAd,
+	PNDIS_PACKET		pPacket,
+	IN	PUCHAR			pData,
+	IN	ULONG			DataSize);
+
+
+#ifdef CONFIG_STA_SUPPORT
+// remove LLC and get 802_3 Header
+#define  RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(_pRxBlk, _pHeader802_3)	\
+{																				\
+	PUCHAR _pRemovedLLCSNAP = NULL, _pDA, _pSA;                                 \
+																				\
+	if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_MESH))                                    \
+	{                                                                           \
+		_pDA = _pRxBlk->pHeader->Addr3;                                         \
+		_pSA = (PUCHAR)_pRxBlk->pHeader + sizeof(HEADER_802_11);                \
+	}                                                                           \
+	else                                                                        \
+	{                                                                           \
+		if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_INFRA))                              	\
+		{                                                                       \
+			_pDA = _pRxBlk->pHeader->Addr1;                                     \
+		if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_DLS))									\
+			_pSA = _pRxBlk->pHeader->Addr2;										\
+		else																	\
+			_pSA = _pRxBlk->pHeader->Addr3;                                     \
+		}                                                                       \
+		else                                                                    \
+		{                                                                       \
+			_pDA = _pRxBlk->pHeader->Addr1;                                     \
+			_pSA = _pRxBlk->pHeader->Addr2;                                     \
+		}                                                                       \
+	}                                                                           \
+																				\
+	CONVERT_TO_802_3(_pHeader802_3, _pDA, _pSA, _pRxBlk->pData, 				\
+		_pRxBlk->DataSize, _pRemovedLLCSNAP);                                   \
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+BOOLEAN APFowardWirelessStaToWirelessSta(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PNDIS_PACKET	pPacket,
+	IN	ULONG			FromWhichBSSID);
+
+VOID Announce_or_Forward_802_3_Packet(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PNDIS_PACKET	pPacket,
+	IN	UCHAR			FromWhichBSSID);
+
+VOID Sta_Announce_or_Forward_802_3_Packet(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PNDIS_PACKET	pPacket,
+	IN	UCHAR			FromWhichBSSID);
+
+
+#ifdef CONFIG_STA_SUPPORT
+#define ANNOUNCE_OR_FORWARD_802_3_PACKET(_pAd, _pPacket, _FromWhichBSS)\
+			Sta_Announce_or_Forward_802_3_Packet(_pAd, _pPacket, _FromWhichBSS);
+			//announce_802_3_packet(_pAd, _pPacket);
+#endif // CONFIG_STA_SUPPORT //
+
+
+PNDIS_PACKET DuplicatePacket(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PNDIS_PACKET	pPacket,
+	IN	UCHAR			FromWhichBSSID);
+
+
+PNDIS_PACKET ClonePacket(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PNDIS_PACKET	pPacket,
+	IN	PUCHAR			pData,
+	IN	ULONG			DataSize);
+
+
+// Normal, AMPDU or AMSDU
+VOID CmmRxnonRalinkFrameIndicate(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	RX_BLK			*pRxBlk,
+	IN	UCHAR			FromWhichBSSID);
+
+VOID CmmRxRalinkFrameIndicate(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	MAC_TABLE_ENTRY	*pEntry,
+	IN	RX_BLK			*pRxBlk,
+	IN	UCHAR			FromWhichBSSID);
+
+VOID Update_Rssi_Sample(
+	IN PRTMP_ADAPTER	pAd,
+	IN RSSI_SAMPLE		*pRssi,
+	IN PRXWI_STRUC		pRxWI);
+
+PNDIS_PACKET GetPacketFromRxRing(
+	IN		PRTMP_ADAPTER	pAd,
+	OUT		PRT28XX_RXD_STRUC		pSaveRxD,
+	OUT		BOOLEAN			*pbReschedule,
+	IN OUT	UINT32			*pRxPending);
+
+PNDIS_PACKET RTMPDeFragmentDataFrame(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	RX_BLK			*pRxBlk);
+
+////////////////////////////////////////
+
+
+
+
+
+#ifdef SNMP_SUPPORT
+//for snmp , kathy
+typedef struct _DefaultKeyIdxValue
+{
+	UCHAR	KeyIdx;
+	UCHAR	Value[16];
+} DefaultKeyIdxValue, *PDefaultKeyIdxValue;
+#endif
+
+
+#ifdef CONFIG_STA_SUPPORT
+enum {
+	DIDmsg_lnxind_wlansniffrm		= 0x00000044,
+	DIDmsg_lnxind_wlansniffrm_hosttime	= 0x00010044,
+	DIDmsg_lnxind_wlansniffrm_mactime	= 0x00020044,
+	DIDmsg_lnxind_wlansniffrm_channel	= 0x00030044,
+	DIDmsg_lnxind_wlansniffrm_rssi		= 0x00040044,
+	DIDmsg_lnxind_wlansniffrm_sq		= 0x00050044,
+	DIDmsg_lnxind_wlansniffrm_signal	= 0x00060044,
+	DIDmsg_lnxind_wlansniffrm_noise		= 0x00070044,
+	DIDmsg_lnxind_wlansniffrm_rate		= 0x00080044,
+	DIDmsg_lnxind_wlansniffrm_istx		= 0x00090044,
+	DIDmsg_lnxind_wlansniffrm_frmlen	= 0x000A0044
+};
+enum {
+	P80211ENUM_msgitem_status_no_value	= 0x00
+};
+enum {
+	P80211ENUM_truth_false			= 0x00,
+	P80211ENUM_truth_true			= 0x01
+};
+
+/* Definition from madwifi */
+typedef struct {
+        UINT32 did;
+        UINT16 status;
+        UINT16 len;
+        UINT32 data;
+} p80211item_uint32_t;
+
+typedef struct {
+        UINT32 msgcode;
+        UINT32 msglen;
+#define WLAN_DEVNAMELEN_MAX 16
+        UINT8 devname[WLAN_DEVNAMELEN_MAX];
+        p80211item_uint32_t hosttime;
+        p80211item_uint32_t mactime;
+        p80211item_uint32_t channel;
+        p80211item_uint32_t rssi;
+        p80211item_uint32_t sq;
+        p80211item_uint32_t signal;
+        p80211item_uint32_t noise;
+        p80211item_uint32_t rate;
+        p80211item_uint32_t istx;
+        p80211item_uint32_t frmlen;
+} wlan_ng_prism2_header;
+
+/* The radio capture header precedes the 802.11 header. */
+typedef struct PACKED _ieee80211_radiotap_header {
+    UINT8	it_version;	/* Version 0. Only increases
+				 * for drastic changes,
+				 * introduction of compatible
+				 * new fields does not count.
+				 */
+    UINT8	it_pad;
+    UINT16     it_len;         /* length of the whole
+				 * header in bytes, including
+				 * it_version, it_pad,
+				 * it_len, and data fields.
+				 */
+    UINT32   it_present;	/* A bitmap telling which
+					 * fields are present. Set bit 31
+					 * (0x80000000) to extend the
+					 * bitmap by another 32 bits.
+					 * Additional extensions are made
+					 * by setting bit 31.
+					 */
+}ieee80211_radiotap_header ;
+
+enum ieee80211_radiotap_type {
+    IEEE80211_RADIOTAP_TSFT = 0,
+    IEEE80211_RADIOTAP_FLAGS = 1,
+    IEEE80211_RADIOTAP_RATE = 2,
+    IEEE80211_RADIOTAP_CHANNEL = 3,
+    IEEE80211_RADIOTAP_FHSS = 4,
+    IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
+    IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
+    IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
+    IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
+    IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
+    IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
+    IEEE80211_RADIOTAP_ANTENNA = 11,
+    IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
+    IEEE80211_RADIOTAP_DB_ANTNOISE = 13
+};
+
+#define WLAN_RADIOTAP_PRESENT (			\
+	(1 << IEEE80211_RADIOTAP_TSFT)	|	\
+	(1 << IEEE80211_RADIOTAP_FLAGS) |	\
+	(1 << IEEE80211_RADIOTAP_RATE)  | 	\
+	 0)
+
+typedef struct _wlan_radiotap_header {
+	ieee80211_radiotap_header wt_ihdr;
+	INT64 wt_tsft;
+	UINT8 wt_flags;
+	UINT8 wt_rate;
+} wlan_radiotap_header;
+/* Definition from madwifi */
+
+void send_monitor_packets(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	RX_BLK			*pRxBlk);
+
+#if WIRELESS_EXT >= 12
+// This function will be called when query /proc
+struct iw_statistics *rt28xx_get_wireless_stats(
+    IN struct net_device *net_dev);
+#endif
+
+VOID    RTMPSetDesiredRates(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  LONG            Rates);
+#endif // CONFIG_STA_SUPPORT //
+
+INT	Set_FixedTxMode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+INT	Set_OpMode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+
+static inline char* GetPhyMode(
+	int Mode)
+{
+	switch(Mode)
+	{
+		case MODE_CCK:
+			return "CCK";
+
+		case MODE_OFDM:
+			return "OFDM";
+#ifdef DOT11_N_SUPPORT
+		case MODE_HTMIX:
+			return "HTMIX";
+
+		case MODE_HTGREENFIELD:
+			return "GREEN";
+#endif // DOT11_N_SUPPORT //
+		default:
+			return "N/A";
+	}
+}
+
+
+static inline char* GetBW(
+	int BW)
+{
+	switch(BW)
+	{
+		case BW_10:
+			return "10M";
+
+		case BW_20:
+			return "20M";
+#ifdef DOT11_N_SUPPORT
+		case BW_40:
+			return "40M";
+#endif // DOT11_N_SUPPORT //
+		default:
+			return "N/A";
+	}
+}
+
+
+VOID RT28xxThreadTerminate(
+	IN RTMP_ADAPTER *pAd);
+
+BOOLEAN RT28XXChipsetCheck(
+	IN void *_dev_p);
+
+BOOLEAN RT28XXNetDevInit(
+	IN void 				*_dev_p,
+	IN struct  net_device	*net_dev,
+	IN RTMP_ADAPTER 		*pAd);
+
+BOOLEAN RT28XXProbePostConfig(
+	IN void 				*_dev_p,
+	IN RTMP_ADAPTER 		*pAd,
+	IN INT32				argc);
+
+VOID RT28XXDMADisable(
+	IN RTMP_ADAPTER 		*pAd);
+
+VOID RT28XXDMAEnable(
+	IN RTMP_ADAPTER 		*pAd);
+
+VOID RT28xx_UpdateBeaconToAsic(
+	IN RTMP_ADAPTER * pAd,
+	IN INT apidx,
+	IN ULONG BeaconLen,
+	IN ULONG UpdatePos);
+
+INT rt28xx_ioctl(
+	IN	struct net_device	*net_dev,
+	IN	OUT	struct ifreq	*rq,
+	IN	INT			cmd);
+
+
+#ifdef CONFIG_STA_SUPPORT
+INT rt28xx_sta_ioctl(
+	IN	struct net_device	*net_dev,
+	IN	OUT	struct ifreq	*rq,
+	IN	INT			cmd);
+#endif // CONFIG_STA_SUPPORT //
+
+BOOLEAN RT28XXSecurityKeyAdd(
+	IN		PRTMP_ADAPTER		pAd,
+	IN		ULONG				apidx,
+	IN		ULONG				KeyIdx,
+	IN		MAC_TABLE_ENTRY 	*pEntry);
+
+////////////////////////////////////////
+PNDIS_PACKET GetPacketFromRxRing(
+	IN		PRTMP_ADAPTER	pAd,
+	OUT		PRT28XX_RXD_STRUC	pSaveRxD,
+	OUT		BOOLEAN			*pbReschedule,
+	IN OUT	UINT32			*pRxPending);
+
+
+void kill_thread_task(PRTMP_ADAPTER pAd);
+
+void tbtt_tasklet(unsigned long data);
+
+
+VOID AsicTurnOffRFClk(
+	IN PRTMP_ADAPTER    pAd,
+	IN	UCHAR           Channel);
+
+VOID AsicTurnOnRFClk(
+	IN PRTMP_ADAPTER 	pAd,
+	IN	UCHAR			Channel);
+
+#ifdef RT30xx
+NTSTATUS RT30xxWriteRFRegister(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			RegID,
+	IN	UCHAR			Value);
+
+NTSTATUS RT30xxReadRFRegister(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			RegID,
+	IN	PUCHAR			pValue);
+
+//2008/09/11:KH add to support efuse<--
+UCHAR eFuseReadRegisters(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT Offset,
+	IN	USHORT Length,
+	OUT	USHORT* pData);
+
+VOID eFuseReadPhysical(
+	IN	PRTMP_ADAPTER	pAd,
+  	IN	PUSHORT lpInBuffer,
+  	IN	ULONG nInBufferSize,
+  	OUT	PUSHORT lpOutBuffer,
+  	IN	ULONG nOutBufferSize
+);
+
+NTSTATUS eFuseRead(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT			Offset,
+	OUT	PUCHAR			pData,
+	IN	USHORT			Length);
+
+VOID eFusePhysicalWriteRegisters(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT Offset,
+	IN	USHORT Length,
+	OUT	USHORT* pData);
+
+NTSTATUS eFuseWriteRegisters(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT Offset,
+	IN	USHORT Length,
+	IN	USHORT* pData);
+
+VOID eFuseWritePhysical(
+	IN	PRTMP_ADAPTER	pAd,
+  	PUSHORT lpInBuffer,
+	ULONG nInBufferSize,
+  	PUCHAR lpOutBuffer,
+  	ULONG nOutBufferSize
+);
+
+NTSTATUS eFuseWrite(
+   	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT			Offset,
+	IN	PUCHAR			pData,
+	IN	USHORT			length);
+
+INT set_eFuseGetFreeBlockCount_Proc(
+   	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT set_eFusedump_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT set_eFuseLoadFromBin_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+NTSTATUS eFuseWriteRegistersFromBin(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT Offset,
+	IN	USHORT Length,
+	IN	USHORT* pData);
+
+VOID eFusePhysicalReadRegisters(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT Offset,
+	IN	USHORT Length,
+	OUT	USHORT* pData);
+
+NDIS_STATUS NICLoadEEPROM(
+	IN PRTMP_ADAPTER pAd);
+
+BOOLEAN bNeedLoadEEPROM(
+	IN	PRTMP_ADAPTER	pAd);
+//2008/09/11:KH add to support efuse-->
+#endif // RT30xx //
+
+#ifdef RT30xx
+// add by johnli, RF power sequence setup
+VOID RT30xxLoadRFNormalModeSetup(
+	IN PRTMP_ADAPTER 	pAd);
+
+VOID RT30xxLoadRFSleepModeSetup(
+	IN PRTMP_ADAPTER 	pAd);
+
+VOID RT30xxReverseRFSleepModeSetup(
+	IN PRTMP_ADAPTER 	pAd);
+// end johnli
+#endif // RT30xx //
+
+#ifdef RT2870
+//
+// Function Prototype in rtusb_bulk.c
+//
+VOID	RTUSBInitTxDesc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PTX_CONTEXT		pTxContext,
+	IN	UCHAR			BulkOutPipeId,
+	IN	usb_complete_t	Func);
+
+VOID	RTUSBInitHTTxDesc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PHT_TX_CONTEXT	pTxContext,
+	IN	UCHAR			BulkOutPipeId,
+	IN	ULONG			BulkOutSize,
+	IN	usb_complete_t	Func);
+
+VOID	RTUSBInitRxDesc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PRX_CONTEXT		pRxContext);
+
+VOID RTUSBCleanUpDataBulkOutQueue(
+	IN	PRTMP_ADAPTER	pAd);
+
+VOID RTUSBCancelPendingBulkOutIRP(
+	IN	PRTMP_ADAPTER	pAd);
+
+VOID RTUSBBulkOutDataPacket(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			BulkOutPipeId,
+	IN	UCHAR			Index);
+
+VOID RTUSBBulkOutNullFrame(
+	IN	PRTMP_ADAPTER	pAd);
+
+VOID RTUSBBulkOutRTSFrame(
+	IN	PRTMP_ADAPTER	pAd);
+
+VOID RTUSBCancelPendingBulkInIRP(
+	IN	PRTMP_ADAPTER	pAd);
+
+VOID RTUSBCancelPendingIRPs(
+	IN	PRTMP_ADAPTER	pAd);
+
+VOID RTUSBBulkOutMLMEPacket(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			Index);
+
+VOID RTUSBBulkOutPsPoll(
+	IN	PRTMP_ADAPTER	pAd);
+
+VOID RTUSBCleanUpMLMEBulkOutQueue(
+	IN	PRTMP_ADAPTER	pAd);
+
+VOID RTUSBKickBulkOut(
+	IN	PRTMP_ADAPTER pAd);
+
+VOID	RTUSBBulkReceive(
+	IN	PRTMP_ADAPTER	pAd);
+
+VOID DoBulkIn(
+	IN RTMP_ADAPTER *pAd);
+
+VOID RTUSBInitRxDesc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN  PRX_CONTEXT		pRxContext);
+
+VOID RTUSBBulkRxHandle(
+	IN unsigned long data);
+
+//
+// Function Prototype in rtusb_io.c
+//
+NTSTATUS RTUSBMultiRead(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT			Offset,
+	OUT	PUCHAR			pData,
+	IN	USHORT			length);
+
+NTSTATUS RTUSBMultiWrite(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT			Offset,
+	IN	PUCHAR			pData,
+	IN	USHORT			length);
+
+NTSTATUS RTUSBMultiWrite_OneByte(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT			Offset,
+	IN	PUCHAR			pData);
+
+NTSTATUS RTUSBReadBBPRegister(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			Id,
+	IN	PUCHAR			pValue);
+
+NTSTATUS RTUSBWriteBBPRegister(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			Id,
+	IN	UCHAR			Value);
+
+NTSTATUS RTUSBWriteRFRegister(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UINT32			Value);
+
+NTSTATUS RTUSB_VendorRequest(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UINT32			TransferFlags,
+	IN	UCHAR			ReservedBits,
+	IN	UCHAR			Request,
+	IN	USHORT			Value,
+	IN	USHORT			Index,
+	IN	PVOID			TransferBuffer,
+	IN	UINT32			TransferBufferLength);
+
+NTSTATUS RTUSBReadEEPROM(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT			Offset,
+	OUT	PUCHAR			pData,
+	IN	USHORT			length);
+
+NTSTATUS RTUSBWriteEEPROM(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT			Offset,
+	IN	PUCHAR			pData,
+	IN	USHORT			length);
+
+VOID RTUSBPutToSleep(
+	IN	PRTMP_ADAPTER	pAd);
+
+NTSTATUS RTUSBWakeUp(
+	IN	PRTMP_ADAPTER	pAd);
+
+VOID RTUSBInitializeCmdQ(
+	IN	PCmdQ	cmdq);
+
+NDIS_STATUS	RTUSBEnqueueCmdFromNdis(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	NDIS_OID		Oid,
+	IN	BOOLEAN			SetInformation,
+	IN	PVOID			pInformationBuffer,
+	IN	UINT32			InformationBufferLength);
+
+NDIS_STATUS RTUSBEnqueueInternalCmd(
+	IN	PRTMP_ADAPTER	pAd,
+	IN NDIS_OID			Oid,
+	IN PVOID			pInformationBuffer,
+	IN UINT32			InformationBufferLength);
+
+VOID RTUSBDequeueCmd(
+	IN	PCmdQ		cmdq,
+	OUT	PCmdQElmt	*pcmdqelmt);
+
+INT RTUSBCmdThread(
+	IN OUT PVOID Context);
+
+INT TimerQThread(
+	IN OUT PVOID Context);
+
+RT2870_TIMER_ENTRY *RT2870_TimerQ_Insert(
+	IN RTMP_ADAPTER *pAd,
+	IN RALINK_TIMER_STRUCT *pTimer);
+
+BOOLEAN RT2870_TimerQ_Remove(
+	IN RTMP_ADAPTER *pAd,
+	IN RALINK_TIMER_STRUCT *pTimer);
+
+void RT2870_TimerQ_Exit(
+	IN RTMP_ADAPTER *pAd);
+
+void RT2870_TimerQ_Init(
+	IN RTMP_ADAPTER *pAd);
+
+VOID RT2870_BssBeaconExit(
+	IN RTMP_ADAPTER *pAd);
+
+VOID RT2870_BssBeaconStop(
+	IN RTMP_ADAPTER *pAd);
+
+VOID RT2870_BssBeaconStart(
+	IN RTMP_ADAPTER * pAd);
+
+VOID RT2870_BssBeaconInit(
+	IN RTMP_ADAPTER *pAd);
+
+VOID RT2870_WatchDog(
+	IN RTMP_ADAPTER *pAd);
+
+NTSTATUS RTUSBWriteMACRegister(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT			Offset,
+	IN	UINT32			Value);
+
+NTSTATUS RTUSBReadMACRegister(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT			Offset,
+	OUT	PUINT32			pValue);
+
+NTSTATUS RTUSBSingleWrite(
+	IN 	RTMP_ADAPTER 	*pAd,
+	IN	USHORT			Offset,
+	IN	USHORT			Value);
+
+NTSTATUS RTUSBFirmwareRun(
+	IN	PRTMP_ADAPTER	pAd);
+
+NTSTATUS RTUSBFirmwareWrite(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR		pFwImage,
+	IN ULONG		FwLen);
+
+NTSTATUS	RTUSBFirmwareOpmode(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PUINT32			pValue);
+
+NTSTATUS	RTUSBVenderReset(
+	IN	PRTMP_ADAPTER	pAd);
+
+NDIS_STATUS RTUSBSetHardWareRegister(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	PVOID			pBuf);
+
+NDIS_STATUS RTUSBQueryHardWareRegister(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	PVOID			pBuf);
+
+VOID CMDHandler(
+    IN PRTMP_ADAPTER pAd);
+
+
+NDIS_STATUS	 CreateThreads(
+	IN	struct net_device *net_dev );
+
+
+VOID MacTableInitialize(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID MlmeSetPsm(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT psm);
+
+NDIS_STATUS RTMPWPAAddKeyProc(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PVOID           pBuf);
+
+VOID AsicRxAntEvalAction(
+	IN PRTMP_ADAPTER pAd);
+
+void append_pkt(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pHeader802_3,
+    IN  UINT            HdrLen,
+	IN	PUCHAR			pData,
+	IN	ULONG			DataSize,
+	OUT  PNDIS_PACKET	*ppPacket);
+
+UINT deaggregate_AMSDU_announce(
+	IN	PRTMP_ADAPTER	pAd,
+	PNDIS_PACKET		pPacket,
+	IN	PUCHAR			pData,
+	IN	ULONG			DataSize);
+
+NDIS_STATUS	RTMPCheckRxError(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PHEADER_802_11	pHeader,
+	IN	PRXWI_STRUC	pRxWI,
+	IN	PRT28XX_RXD_STRUC	pRxINFO);
+
+
+VOID RTUSBMlmeHardTransmit(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PMGMT_STRUC		pMgmt);
+
+INT MlmeThread(
+	IN PVOID Context);
+
+//
+// Function Prototype in rtusb_data.c
+//
+NDIS_STATUS	RTUSBFreeDescriptorRequest(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			BulkOutPipeId,
+	IN	UINT32			NumberRequired);
+
+
+BOOLEAN	RTUSBNeedQueueBackForAgg(
+	IN RTMP_ADAPTER *pAd,
+	IN UCHAR		BulkOutPipeId);
+
+
+VOID RTMPWriteTxInfo(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PTXINFO_STRUC 	pTxInfo,
+	IN	  USHORT		USBDMApktLen,
+	IN	  BOOLEAN		bWiv,
+	IN	  UCHAR			QueueSel,
+	IN	  UCHAR			NextValid,
+	IN	  UCHAR			TxBurst);
+
+//
+// Function Prototype in cmm_data_2870.c
+//
+USHORT RtmpUSB_WriteSubTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	BOOLEAN			bIsLast,
+	OUT	USHORT			*FreeNumber);
+
+USHORT RtmpUSB_WriteSingleTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	BOOLEAN			bIsLast,
+	OUT	USHORT			*FreeNumber);
+
+USHORT	RtmpUSB_WriteFragTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	UCHAR			fragNum,
+	OUT	USHORT			*FreeNumber);
+
+USHORT RtmpUSB_WriteMultiTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	UCHAR			frameNum,
+	OUT	USHORT			*FreeNumber);
+
+VOID RtmpUSB_FinalWriteTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	USHORT			totalMPDUSize,
+	IN	USHORT			TxIdx);
+
+VOID RtmpUSBDataLastTxIdx(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			QueIdx,
+	IN	USHORT			TxIdx);
+
+VOID RtmpUSBDataKickOut(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	UCHAR			QueIdx);
+
+
+int RtmpUSBMgmtKickOut(
+	IN RTMP_ADAPTER 	*pAd,
+	IN UCHAR 			QueIdx,
+	IN PNDIS_PACKET		pPacket,
+	IN PUCHAR			pSrcBufVA,
+	IN UINT 			SrcBufLen);
+
+VOID RtmpUSBNullFrameKickOut(
+	IN RTMP_ADAPTER *pAd,
+	IN UCHAR		QueIdx,
+	IN UCHAR		*pNullFrame,
+	IN UINT32		frameLen);
+
+VOID RT28xxUsbStaAsicForceWakeup(
+	IN PRTMP_ADAPTER pAd,
+	IN BOOLEAN       bFromTx);
+
+VOID RT28xxUsbStaAsicSleepThenAutoWakeup(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT TbttNumToNextWakeUp);
+
+VOID RT28xxUsbMlmeRadioOn(
+	IN PRTMP_ADAPTER pAd);
+
+VOID RT28xxUsbMlmeRadioOFF(
+	IN PRTMP_ADAPTER pAd);
+#endif // RT2870 //
+
+////////////////////////////////////////
+
+VOID QBSS_LoadInit(
+ 	IN		RTMP_ADAPTER	*pAd);
+
+UINT32 QBSS_LoadElementAppend(
+ 	IN		RTMP_ADAPTER	*pAd,
+	OUT		UINT8			*buf_p);
+
+VOID QBSS_LoadUpdate(
+ 	IN		RTMP_ADAPTER	*pAd);
+
+///////////////////////////////////////
+INT RTMPShowCfgValue(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pName,
+	IN	PUCHAR			pBuf);
+
+PCHAR   RTMPGetRalinkAuthModeStr(
+    IN  NDIS_802_11_AUTHENTICATION_MODE authMode);
+
+PCHAR   RTMPGetRalinkEncryModeStr(
+    IN  USHORT encryMode);
+//////////////////////////////////////
+
+#ifdef CONFIG_STA_SUPPORT
+VOID AsicStaBbpTuning(
+	IN PRTMP_ADAPTER pAd);
+
+BOOLEAN StaAddMacTableEntry(
+	IN  PRTMP_ADAPTER		pAd,
+	IN  PMAC_TABLE_ENTRY	pEntry,
+	IN  UCHAR				MaxSupportedRateIn500Kbps,
+	IN  HT_CAPABILITY_IE	*pHtCapability,
+	IN  UCHAR				HtCapabilityLen,
+	IN  USHORT        		CapabilityInfo);
+#endif // CONFIG_STA_SUPPORT //
+
+void RTMP_IndicateMediaState(
+	IN	PRTMP_ADAPTER	pAd);
+
+VOID ReSyncBeaconTime(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID RTMPSetAGCInitValue(
+	IN PRTMP_ADAPTER	pAd,
+	IN UCHAR			BandWidth);
+
+int rt28xx_close(IN PNET_DEV dev);
+int rt28xx_open(IN PNET_DEV dev);
+
+__inline INT VIRTUAL_IF_UP(PRTMP_ADAPTER pAd)
+{
+extern VOID MeshMakeBeacon(IN PRTMP_ADAPTER pAd, IN UCHAR idx);
+extern VOID MeshUpdateBeaconFrame(IN PRTMP_ADAPTER pAd, IN UCHAR idx);
+
+	if (VIRTUAL_IF_NUM(pAd) == 0)
+	{
+		if (rt28xx_open(pAd->net_dev) != 0)
+			return -1;
+	}
+	else
+	{
+	}
+	VIRTUAL_IF_INC(pAd);
+	return 0;
+}
+
+__inline VOID VIRTUAL_IF_DOWN(PRTMP_ADAPTER pAd)
+{
+	VIRTUAL_IF_DEC(pAd);
+	if (VIRTUAL_IF_NUM(pAd) == 0)
+		rt28xx_close(pAd->net_dev);
+	return;
+}
+
+
+#endif  // __RTMP_H__
+
diff --git a/drivers/staging/rt3070/rtmp_ckipmic.h b/drivers/staging/rt3070/rtmp_ckipmic.h
new file mode 100644
index 0000000..a3d949a
--- /dev/null
+++ b/drivers/staging/rt3070/rtmp_ckipmic.h
@@ -0,0 +1,113 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	rtmp_ckipmic.h
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	Name		Date			Modification logs
+*/
+#ifndef	__RTMP_CKIPMIC_H__
+#define	__RTMP_CKIPMIC_H__
+
+typedef	struct	_MIC_CONTEXT	{
+	/* --- MMH context                            */
+	UCHAR		CK[16];				/* the key                                    */
+	UCHAR		coefficient[16];	/* current aes counter mode coefficients      */
+	ULONGLONG	accum;				/* accumulated mic, reduced to u32 in final() */
+	UINT		position;			/* current position (byte offset) in message  */
+	UCHAR		part[4];			/* for conversion of message to u32 for mmh   */
+}	MIC_CONTEXT, *PMIC_CONTEXT;
+
+VOID	CKIP_key_permute(
+	OUT	UCHAR	*PK,			/* output permuted key */
+	IN	UCHAR	*CK,			/* input CKIP key */
+	IN	UCHAR	toDsFromDs,		/* input toDs/FromDs bits */
+	IN	UCHAR	*piv);			/* input pointer to IV */
+
+VOID	RTMPCkipMicInit(
+	IN	PMIC_CONTEXT		pContext,
+	IN	PUCHAR				CK);
+
+VOID RTMPMicUpdate(
+    IN  PMIC_CONTEXT        pContext,
+    IN  PUCHAR              pOctets,
+    IN  INT                 len);
+
+ULONG RTMPMicGetCoefficient(
+    IN  PMIC_CONTEXT         pContext);
+
+VOID xor_128(
+    IN  PUCHAR              a,
+    IN  PUCHAR              b,
+    OUT PUCHAR              out);
+
+UCHAR RTMPCkipSbox(
+    IN  UCHAR               a);
+
+VOID xor_32(
+    IN  PUCHAR              a,
+    IN  PUCHAR              b,
+    OUT PUCHAR              out);
+
+VOID next_key(
+    IN  PUCHAR              key,
+    IN  INT                 round);
+
+VOID byte_sub(
+    IN  PUCHAR              in,
+    OUT PUCHAR              out);
+
+VOID shift_row(
+    IN  PUCHAR              in,
+    OUT PUCHAR              out);
+
+VOID mix_column(
+    IN  PUCHAR              in,
+    OUT PUCHAR              out);
+
+VOID RTMPAesEncrypt(
+    IN  PUCHAR              key,
+    IN  PUCHAR              data,
+    IN  PUCHAR              ciphertext);
+
+VOID RTMPMicFinal(
+    IN  PMIC_CONTEXT        pContext,
+    OUT UCHAR               digest[4]);
+
+VOID RTMPCkipInsertCMIC(
+    IN  PRTMP_ADAPTER   pAd,
+    OUT PUCHAR          pMIC,
+    IN  PUCHAR          p80211hdr,
+    IN  PNDIS_PACKET    pPacket,
+    IN  PCIPHER_KEY     pKey,
+    IN  PUCHAR          mic_snap);
+
+#endif //__RTMP_CKIPMIC_H__
diff --git a/drivers/staging/rt3070/rtmp_def.h b/drivers/staging/rt3070/rtmp_def.h
new file mode 100644
index 0000000..2599f7c
--- /dev/null
+++ b/drivers/staging/rt3070/rtmp_def.h
@@ -0,0 +1,1559 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+    rtmp_def.h
+
+    Abstract:
+    Miniport related definition header
+
+    Revision History:
+    Who         When          What
+    --------    ----------    ----------------------------------------------
+    Paul Lin    08-01-2002    created
+    John Chang  08-05-2003    add definition for 11g & other drafts
+*/
+#ifndef __RTMP_DEF_H__
+#define __RTMP_DEF_H__
+
+#include "oid.h"
+
+#undef AP_WSC_INCLUDED
+#undef STA_WSC_INCLUDED
+#undef WSC_INCLUDED
+
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED)
+#define WSC_INCLUDED
+#endif
+//
+//  Debug information verbosity: lower values indicate higher urgency
+//
+#define RT_DEBUG_OFF        0
+#define RT_DEBUG_ERROR      1
+#define RT_DEBUG_WARN       2
+#define RT_DEBUG_TRACE      3
+#define RT_DEBUG_INFO       4
+#define RT_DEBUG_LOUD       5
+
+#define NIC_TAG             ((ULONG)'0682')
+#define NIC_DBG_STRING      ("**RT28xx**")
+
+#ifdef SNMP_SUPPORT
+// for snmp
+// to get manufacturer OUI, kathy, 2008_0220
+#define ManufacturerOUI_LEN			3
+#define ManufacturerNAME			("Ralink Technology Company.")
+#define	ResourceTypeIdName			("Ralink_ID")
+#endif
+
+
+//#define PACKED
+
+#define RALINK_2883_VERSION		((UINT32)0x28830300)
+#define RALINK_2880E_VERSION	((UINT32)0x28720200)
+#define RALINK_3070_VERSION		((UINT32)0x30700200)
+
+//
+// NDIS version in use by the NIC driver.
+// The high byte is the major version. The low byte is the minor version.
+//
+#ifdef  NDIS51_MINIPORT
+#define NIC_DRIVER_VERSION      0x0501
+#else
+#define NIC_DRIVER_VERSION      0x0500
+#endif
+
+//
+// NDIS media type, current is ethernet, change if native wireless supported
+//
+#define NIC_MEDIA_TYPE          NdisMedium802_3
+#define NIC_PCI_HDR_LENGTH      0xe2
+#define NIC_MAX_PACKET_SIZE     2304
+#define NIC_HEADER_SIZE         14
+#define MAX_MAP_REGISTERS_NEEDED 32
+#define MIN_MAP_REGISTERS_NEEDED 2   //Todo: should consider fragment issue.
+
+//
+// interface type, we use PCI
+//
+#define NIC_INTERFACE_TYPE      NdisInterfacePci
+#define NIC_INTERRUPT_MODE      NdisInterruptLevelSensitive
+
+//
+// buffer size passed in NdisMQueryAdapterResources
+// We should only need three adapter resources (IO, interrupt and memory),
+// Some devices get extra resources, so have room for 10 resources
+//                    UF_SIZE   (sizeof(NDIS_RESOURCE_LIST) + (10*sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)))
+
+
+#define NIC_RESOURCE_B//
+// IO space length
+//
+#define NIC_MAP_IOSPACE_LENGTH  sizeof(CSR_STRUC)
+
+#define MAX_RX_PKT_LEN	1520
+
+//
+// Entry number for each DMA descriptor ring
+//
+
+
+#ifdef RT2870
+#define TX_RING_SIZE            8 // 1
+#define PRIO_RING_SIZE          8
+#define MGMT_RING_SIZE       32 // PRIO_RING_SIZE
+#define RX_RING_SIZE            8
+#define MAX_TX_PROCESS          4
+#define LOCAL_TXBUF_SIZE        2048
+#endif // RT2870 //
+
+#ifdef MULTIPLE_CARD_SUPPORT
+// MC: Multple Cards
+#define MAX_NUM_OF_MULTIPLE_CARD		32
+#endif // MULTIPLE_CARD_SUPPORT //
+
+#define MAX_RX_PROCESS          128 //64 //32
+#define NUM_OF_LOCAL_TXBUF      2
+#define TXD_SIZE                16
+#define TXWI_SIZE               16
+#define RXD_SIZE               	16
+#define RXWI_SIZE             	16
+// TXINFO_SIZE + TXWI_SIZE + 802.11 Header Size + AMSDU sub frame header
+#define TX_DMA_1ST_BUFFER_SIZE  96    // only the 1st physical buffer is pre-allocated
+#define MGMT_DMA_BUFFER_SIZE    1536 //2048
+#define RX_BUFFER_AGGRESIZE     3840 //3904 //3968 //4096 //2048 //4096
+#define RX_BUFFER_NORMSIZE      3840 //3904 //3968 //4096 //2048 //4096
+#define TX_BUFFER_NORMSIZE		RX_BUFFER_NORMSIZE
+#define MAX_FRAME_SIZE          2346                    // Maximum 802.11 frame size
+#define MAX_AGGREGATION_SIZE    3840 //3904 //3968 //4096
+#define MAX_NUM_OF_TUPLE_CACHE  2
+#define MAX_MCAST_LIST_SIZE     32
+#define MAX_LEN_OF_VENDOR_DESC  64
+//#define MAX_SIZE_OF_MCAST_PSQ   (NUM_OF_LOCAL_TXBUF >> 2) // AP won't spend more than 1/4 of total buffers on M/BCAST PSQ
+#define MAX_SIZE_OF_MCAST_PSQ               32
+
+#define MAX_RX_PROCESS_CNT	(RX_RING_SIZE)
+
+
+#define MAX_PACKETS_IN_QUEUE				(512) //(512)    // to pass WMM A5-WPAPSK
+#define MAX_PACKETS_IN_MCAST_PS_QUEUE		32
+#define MAX_PACKETS_IN_PS_QUEUE				128	//32
+#define WMM_NUM_OF_AC                       4  /* AC0, AC1, AC2, and AC3 */
+
+
+//2008/09/11:KH add to support efuse<--
+#define MAX_EEPROM_BIN_FILE_SIZE					1024
+//2008/09/11:KH add to support efuse-->
+
+// RxFilter
+#define STANORMAL	 0x17f97
+#define APNORMAL	 0x15f97
+//
+//  RTMP_ADAPTER flags
+//
+#define fRTMP_ADAPTER_MAP_REGISTER          0x00000001
+#define fRTMP_ADAPTER_INTERRUPT_IN_USE      0x00000002
+#define fRTMP_ADAPTER_HARDWARE_ERROR        0x00000004
+#define fRTMP_ADAPTER_SCATTER_GATHER        0x00000008
+#define fRTMP_ADAPTER_SEND_PACKET_ERROR     0x00000010
+#define fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS 0x00000020
+#define fRTMP_ADAPTER_HALT_IN_PROGRESS      0x00000040
+#define fRTMP_ADAPTER_RESET_IN_PROGRESS     0x00000080
+#define fRTMP_ADAPTER_NIC_NOT_EXIST         0x00000100
+#define fRTMP_ADAPTER_TX_RING_ALLOCATED     0x00000200
+#define fRTMP_ADAPTER_REMOVE_IN_PROGRESS    0x00000400
+#define fRTMP_ADAPTER_MIMORATE_INUSED       0x00000800
+#define fRTMP_ADAPTER_RX_RING_ALLOCATED     0x00001000
+#define fRTMP_ADAPTER_INTERRUPT_ACTIVE      0x00002000
+#define fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS  0x00004000
+#define	fRTMP_ADAPTER_REASSOC_IN_PROGRESS	0x00008000
+#define	fRTMP_ADAPTER_MEDIA_STATE_PENDING	0x00010000
+#define	fRTMP_ADAPTER_RADIO_OFF				0x00020000
+#define fRTMP_ADAPTER_BULKOUT_RESET			0x00040000
+#define	fRTMP_ADAPTER_BULKIN_RESET			0x00080000
+#define fRTMP_ADAPTER_RDG_ACTIVE			0x00100000
+#define fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE 0x00200000
+#define fRTMP_ADAPTER_SCAN_2040 			0x04000000
+#define	fRTMP_ADAPTER_RADIO_MEASUREMENT		0x08000000
+
+#define fRTMP_ADAPTER_START_UP         		0x10000000	//Devive already initialized and enabled Tx/Rx.
+#define fRTMP_ADAPTER_MEDIA_STATE_CHANGE    0x20000000
+#define fRTMP_ADAPTER_IDLE_RADIO_OFF        0x40000000
+
+// Lock bit for accessing different ring buffers
+//#define fRTMP_ADAPTER_TX_RING_BUSY        0x80000000
+//#define fRTMP_ADAPTER_MGMT_RING_BUSY      0x40000000
+//#define fRTMP_ADAPTER_ATIM_RING_BUSY      0x20000000
+//#define fRTMP_ADAPTER_RX_RING_BUSY        0x10000000
+
+// Lock bit for accessing different queue
+//#define   fRTMP_ADAPTER_TX_QUEUE_BUSY     0x08000000
+//#define   fRTMP_ADAPTER_MGMT_QUEUE_BUSY   0x04000000
+
+//
+//  STA operation status flags
+//
+#define fOP_STATUS_INFRA_ON                 0x00000001
+#define fOP_STATUS_ADHOC_ON                 0x00000002
+#define fOP_STATUS_BG_PROTECTION_INUSED     0x00000004
+#define fOP_STATUS_SHORT_SLOT_INUSED        0x00000008
+#define fOP_STATUS_SHORT_PREAMBLE_INUSED    0x00000010
+#define fOP_STATUS_RECEIVE_DTIM             0x00000020
+//#define fOP_STATUS_TX_RATE_SWITCH_ENABLED   0x00000040
+#define fOP_STATUS_MEDIA_STATE_CONNECTED    0x00000080
+#define fOP_STATUS_WMM_INUSED               0x00000100
+#define fOP_STATUS_AGGREGATION_INUSED       0x00000200
+#define fOP_STATUS_DOZE                     0x00000400  // debug purpose
+#define fOP_STATUS_PIGGYBACK_INUSED         0x00000800  // piggy-back, and aggregation
+#define fOP_STATUS_APSD_INUSED				0x00001000
+#define fOP_STATUS_TX_AMSDU_INUSED			0x00002000
+#define fOP_STATUS_MAX_RETRY_ENABLED		0x00004000
+#define fOP_STATUS_WAKEUP_NOW               0x00008000
+#define fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE       0x00020000
+
+#ifdef DOT11N_DRAFT3
+#define fOP_STATUS_SCAN_2040               	    0x00040000
+#endif // DOT11N_DRAFT3 //
+
+#define CCKSETPROTECT		0x1
+#define OFDMSETPROTECT		0x2
+#define MM20SETPROTECT		0x4
+#define MM40SETPROTECT		0x8
+#define GF20SETPROTECT		0x10
+#define GR40SETPROTECT		0x20
+#define ALLN_SETPROTECT		(GR40SETPROTECT | GF20SETPROTECT | MM40SETPROTECT | MM20SETPROTECT)
+
+//
+//  AP's client table operation status flags
+//
+#define fCLIENT_STATUS_WMM_CAPABLE          0x00000001  // CLIENT can parse QOS DATA frame
+#define fCLIENT_STATUS_AGGREGATION_CAPABLE  0x00000002  // CLIENT can receive Ralink's proprietary TX aggregation frame
+#define fCLIENT_STATUS_PIGGYBACK_CAPABLE    0x00000004  // CLIENT support piggy-back
+#define fCLIENT_STATUS_AMSDU_INUSED			0x00000008
+#define fCLIENT_STATUS_SGI20_CAPABLE		0x00000010
+#define fCLIENT_STATUS_SGI40_CAPABLE		0x00000020
+#define fCLIENT_STATUS_TxSTBC_CAPABLE		0x00000040
+#define fCLIENT_STATUS_RxSTBC_CAPABLE		0x00000080
+#define fCLIENT_STATUS_HTC_CAPABLE			0x00000100
+#define fCLIENT_STATUS_RDG_CAPABLE			0x00000200
+#define fCLIENT_STATUS_MCSFEEDBACK_CAPABLE  0x00000400
+#define fCLIENT_STATUS_APSD_CAPABLE         0x00000800  /* UAPSD STATION */
+
+#ifdef DOT11N_DRAFT3
+#define fCLIENT_STATUS_BSSCOEXIST_CAPABLE	0x00001000
+#endif // DOT11N_DRAFT3 //
+
+#define fCLIENT_STATUS_RALINK_CHIPSET		0x00100000
+//
+//  STA configuration flags
+//
+//#define fSTA_CFG_ENABLE_TX_BURST          0x00000001
+
+// 802.11n Operating Mode Definition. 0-3 also used in ASICUPdateProtect switch case
+#define HT_NO_PROTECT	0
+#define HT_LEGACY_PROTECT	1
+#define HT_40_PROTECT	2
+#define HT_2040_PROTECT	3
+#define HT_RTSCTS_6M	7
+//following is our own definition in order to turn on our ASIC protection register in INFRASTRUCTURE.
+#define HT_ATHEROS	8
+#define HT_FORCERTSCTS	9	// Force turn on RTS/CTS first. then go to evaluate if this force RTS is necessary.
+
+//
+// RX Packet Filter control flags. Apply on pAd->PacketFilter
+//
+#define fRX_FILTER_ACCEPT_DIRECT            NDIS_PACKET_TYPE_DIRECTED
+#define fRX_FILTER_ACCEPT_MULTICAST         NDIS_PACKET_TYPE_MULTICAST
+#define fRX_FILTER_ACCEPT_BROADCAST         NDIS_PACKET_TYPE_BROADCAST
+#define fRX_FILTER_ACCEPT_ALL_MULTICAST     NDIS_PACKET_TYPE_ALL_MULTICAST
+
+//
+// Error code section
+//
+// NDIS_ERROR_CODE_ADAPTER_NOT_FOUND
+#define ERRLOG_READ_PCI_SLOT_FAILED     0x00000101L
+#define ERRLOG_WRITE_PCI_SLOT_FAILED    0x00000102L
+#define ERRLOG_VENDOR_DEVICE_NOMATCH    0x00000103L
+
+// NDIS_ERROR_CODE_ADAPTER_DISABLED
+#define ERRLOG_BUS_MASTER_DISABLED      0x00000201L
+
+// NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION
+#define ERRLOG_INVALID_SPEED_DUPLEX     0x00000301L
+#define ERRLOG_SET_SECONDARY_FAILED     0x00000302L
+
+// NDIS_ERROR_CODE_OUT_OF_RESOURCES
+#define ERRLOG_OUT_OF_MEMORY            0x00000401L
+#define ERRLOG_OUT_OF_SHARED_MEMORY     0x00000402L
+#define ERRLOG_OUT_OF_MAP_REGISTERS     0x00000403L
+#define ERRLOG_OUT_OF_BUFFER_POOL       0x00000404L
+#define ERRLOG_OUT_OF_NDIS_BUFFER       0x00000405L
+#define ERRLOG_OUT_OF_PACKET_POOL       0x00000406L
+#define ERRLOG_OUT_OF_NDIS_PACKET       0x00000407L
+#define ERRLOG_OUT_OF_LOOKASIDE_MEMORY  0x00000408L
+
+// NDIS_ERROR_CODE_HARDWARE_FAILURE
+#define ERRLOG_SELFTEST_FAILED          0x00000501L
+#define ERRLOG_INITIALIZE_ADAPTER       0x00000502L
+#define ERRLOG_REMOVE_MINIPORT          0x00000503L
+
+// NDIS_ERROR_CODE_RESOURCE_CONFLICT
+#define ERRLOG_MAP_IO_SPACE             0x00000601L
+#define ERRLOG_QUERY_ADAPTER_RESOURCES  0x00000602L
+#define ERRLOG_NO_IO_RESOURCE           0x00000603L
+#define ERRLOG_NO_INTERRUPT_RESOURCE    0x00000604L
+#define ERRLOG_NO_MEMORY_RESOURCE       0x00000605L
+
+
+// WDS definition
+#define	MAX_WDS_ENTRY               4
+#define WDS_PAIRWISE_KEY_OFFSET     60    // WDS links uses pairwise key#60 ~ 63 in ASIC pairwise key table
+
+#define	WDS_DISABLE_MODE            0
+#define	WDS_RESTRICT_MODE           1
+#define	WDS_BRIDGE_MODE             2
+#define	WDS_REPEATER_MODE           3
+#define	WDS_LAZY_MODE               4
+
+
+#define MAX_MESH_NUM				0
+
+#define MAX_APCLI_NUM				0
+
+#define MAX_MBSSID_NUM				1
+#ifdef MBSS_SUPPORT
+#undef	MAX_MBSSID_NUM
+#define MAX_MBSSID_NUM				(8 - MAX_MESH_NUM - MAX_APCLI_NUM)
+#endif // MBSS_SUPPORT //
+
+/* sanity check for apidx */
+#define MBSS_MR_APIDX_SANITY_CHECK(apidx) \
+    { if (apidx > MAX_MBSSID_NUM) { \
+          printk("%s> Error! apidx = %d > MAX_MBSSID_NUM!\n", __FUNCTION__, apidx); \
+	  apidx = MAIN_MBSSID; } }
+
+#define VALID_WCID(_wcid)	((_wcid) > 0 && (_wcid) < MAX_LEN_OF_MAC_TABLE )
+
+#define MAIN_MBSSID                 0
+#define FIRST_MBSSID                1
+
+
+#define MAX_BEACON_SIZE				512
+// If the MAX_MBSSID_NUM is larger than 6,
+// it shall reserve some WCID space(wcid 222~253) for beacon frames.
+// -	these wcid 238~253 are reserved for beacon#6(ra6).
+// -	these wcid 222~237 are reserved for beacon#7(ra7).
+#if defined(MAX_MBSSID_NUM) && (MAX_MBSSID_NUM == 8)
+#define HW_RESERVED_WCID	222
+#elif defined(MAX_MBSSID_NUM) && (MAX_MBSSID_NUM == 7)
+#define HW_RESERVED_WCID	238
+#else
+#define HW_RESERVED_WCID	255
+#endif
+
+// Then dedicate wcid of DFS and Carrier-Sense.
+#define DFS_CTS_WCID 		(HW_RESERVED_WCID - 1)
+#define CS_CTS_WCID 		(HW_RESERVED_WCID - 2)
+#define LAST_SPECIFIC_WCID	(HW_RESERVED_WCID - 2)
+
+// If MAX_MBSSID_NUM is 8, the maximum available wcid for the associated STA is 211.
+// If MAX_MBSSID_NUM is 7, the maximum available wcid for the associated STA is 228.
+#define MAX_AVAILABLE_CLIENT_WCID	(LAST_SPECIFIC_WCID - MAX_MBSSID_NUM - 1)
+
+// TX need WCID to find Cipher Key
+// these wcid 212 ~ 219 are reserved for bc/mc packets if MAX_MBSSID_NUM is 8.
+#define GET_GroupKey_WCID(__wcid, __bssidx) \
+	{										\
+		__wcid = LAST_SPECIFIC_WCID - (MAX_MBSSID_NUM) + __bssidx;	\
+	}
+
+#define IsGroupKeyWCID(__wcid) (((__wcid) < LAST_SPECIFIC_WCID) && ((__wcid) >= (LAST_SPECIFIC_WCID - (MAX_MBSSID_NUM))))
+
+
+// definition to support multiple BSSID
+#define BSS0                            0
+#define BSS1                            1
+#define BSS2                            2
+#define BSS3                            3
+#define BSS4                            4
+#define BSS5                            5
+#define BSS6                            6
+#define BSS7                            7
+
+
+//============================================================
+// Length definitions
+#define PEER_KEY_NO                     2
+#define MAC_ADDR_LEN                    6
+#define TIMESTAMP_LEN                   8
+#define MAX_LEN_OF_SUPPORTED_RATES      MAX_LENGTH_OF_SUPPORT_RATES // 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
+#define MAX_LEN_OF_KEY                  32      // 32 octets == 256 bits, Redefine for WPA
+#define MAX_NUM_OF_CHANNELS             MAX_NUM_OF_CHS      // 14 channels @2.4G +  12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination
+#define MAX_NUM_OF_11JCHANNELS             20      // 14 channels @2.4G +  12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination
+#define MAX_LEN_OF_SSID                 32
+#define CIPHER_TEXT_LEN                 128
+#define HASH_TABLE_SIZE                 256
+#define MAX_VIE_LEN                     1024   // New for WPA cipher suite variable IE sizes.
+#define MAX_SUPPORT_MCS             32
+
+//============================================================
+// ASIC WCID Table definition.
+//============================================================
+#define BSSID_WCID		1	// in infra mode, always put bssid with this WCID
+#define MCAST_WCID	0x0
+#define BSS0Mcast_WCID	0x0
+#define BSS1Mcast_WCID	0xf8
+#define BSS2Mcast_WCID	0xf9
+#define BSS3Mcast_WCID	0xfa
+#define BSS4Mcast_WCID	0xfb
+#define BSS5Mcast_WCID	0xfc
+#define BSS6Mcast_WCID	0xfd
+#define BSS7Mcast_WCID	0xfe
+#define RESERVED_WCID		0xff
+
+#define MAX_NUM_OF_ACL_LIST				MAX_NUMBER_OF_ACL
+
+#define MAX_LEN_OF_MAC_TABLE            MAX_NUMBER_OF_MAC // if MAX_MBSSID_NUM is 8, this value can't be larger than 211
+
+#if MAX_LEN_OF_MAC_TABLE>MAX_AVAILABLE_CLIENT_WCID
+#error MAX_LEN_OF_MAC_TABLE can not be larger than MAX_AVAILABLE_CLIENT_WCID!!!!
+#endif
+
+#define MAX_NUM_OF_WDS_LINK_PERBSSID	            3
+#define MAX_NUM_OF_WDS_LINK	            (MAX_NUM_OF_WDS_LINK_PERBSSID*MAX_MBSSID_NUM)
+#define MAX_NUM_OF_EVENT                MAX_NUMBER_OF_EVENT
+#define WDS_LINK_START_WCID				(MAX_LEN_OF_MAC_TABLE-1)
+
+#define NUM_OF_TID			8
+#define MAX_AID_BA                    4
+#define MAX_LEN_OF_BA_REC_TABLE          ((NUM_OF_TID * MAX_LEN_OF_MAC_TABLE)/2)//   (NUM_OF_TID*MAX_AID_BA + 32)	 //Block ACK recipient
+#define MAX_LEN_OF_BA_ORI_TABLE          ((NUM_OF_TID * MAX_LEN_OF_MAC_TABLE)/2)//   (NUM_OF_TID*MAX_AID_BA + 32)   // Block ACK originator
+#define MAX_LEN_OF_BSS_TABLE             64
+#define MAX_REORDERING_MPDU_NUM			 512
+
+// key related definitions
+#define SHARE_KEY_NUM                   4
+#define MAX_LEN_OF_SHARE_KEY            16    // byte count
+#define MAX_LEN_OF_PEER_KEY             16    // byte count
+#define PAIRWISE_KEY_NUM                64    // in MAC ASIC pairwise key table
+#define GROUP_KEY_NUM                   4
+#define PMK_LEN                         32
+#define WDS_PAIRWISE_KEY_OFFSET         60    // WDS links uses pairwise key#60 ~ 63 in ASIC pairwise key table
+#define	PMKID_NO                        4     // Number of PMKID saved supported
+#define MAX_LEN_OF_MLME_BUFFER          2048
+
+// power status related definitions
+#define PWR_ACTIVE                      0
+#define PWR_SAVE                        1
+#define PWR_MMPS                        2			//MIMO power save
+//#define PWR_UNKNOWN                   2
+
+// Auth and Assoc mode related definitions
+#define AUTH_MODE_OPEN                  0x00
+#define AUTH_MODE_KEY                   0x01
+//#define AUTH_MODE_AUTO_SWITCH         0x03
+//#define AUTH_MODE_DEAUTH              0x04
+//#define AUTH_MODE_UPLAYER             0x05 // reserved for 802.11i use
+
+// BSS Type definitions
+#define BSS_ADHOC                       0  // = Ndis802_11IBSS
+#define BSS_INFRA                       1  // = Ndis802_11Infrastructure
+#define BSS_ANY                         2  // = Ndis802_11AutoUnknown
+#define BSS_MONITOR			            3  // = Ndis802_11Monitor
+
+
+// Reason code definitions
+#define REASON_RESERVED                 0
+#define REASON_UNSPECIFY                1
+#define REASON_NO_LONGER_VALID          2
+#define REASON_DEAUTH_STA_LEAVING       3
+#define REASON_DISASSOC_INACTIVE        4
+#define REASON_DISASSPC_AP_UNABLE       5
+#define REASON_CLS2ERR                  6
+#define REASON_CLS3ERR                  7
+#define REASON_DISASSOC_STA_LEAVING     8
+#define REASON_STA_REQ_ASSOC_NOT_AUTH   9
+#define REASON_INVALID_IE               13
+#define REASON_MIC_FAILURE              14
+#define REASON_4_WAY_TIMEOUT            15
+#define REASON_GROUP_KEY_HS_TIMEOUT     16
+#define REASON_IE_DIFFERENT             17
+#define REASON_MCIPHER_NOT_VALID        18
+#define REASON_UCIPHER_NOT_VALID        19
+#define REASON_AKMP_NOT_VALID           20
+#define REASON_UNSUPPORT_RSNE_VER       21
+#define REASON_INVALID_RSNE_CAP         22
+#define REASON_8021X_AUTH_FAIL          23
+#define REASON_CIPHER_SUITE_REJECTED    24
+#define REASON_DECLINED                 37
+
+#define REASON_QOS_UNSPECIFY              32
+#define REASON_QOS_LACK_BANDWIDTH         33
+#define REASON_POOR_CHANNEL_CONDITION     34
+#define REASON_QOS_OUTSIDE_TXOP_LIMITION  35
+#define REASON_QOS_QSTA_LEAVING_QBSS      36
+#define REASON_QOS_UNWANTED_MECHANISM     37
+#define REASON_QOS_MECH_SETUP_REQUIRED    38
+#define REASON_QOS_REQUEST_TIMEOUT        39
+#define REASON_QOS_CIPHER_NOT_SUPPORT     45
+
+// Status code definitions
+#define MLME_SUCCESS                    0
+#define MLME_UNSPECIFY_FAIL             1
+#define MLME_CANNOT_SUPPORT_CAP         10
+#define MLME_REASSOC_DENY_ASSOC_EXIST   11
+#define MLME_ASSOC_DENY_OUT_SCOPE       12
+#define MLME_ALG_NOT_SUPPORT            13
+#define MLME_SEQ_NR_OUT_OF_SEQUENCE     14
+#define MLME_REJ_CHALLENGE_FAILURE      15
+#define MLME_REJ_TIMEOUT                  16
+#define MLME_ASSOC_REJ_UNABLE_HANDLE_STA  17
+#define MLME_ASSOC_REJ_DATA_RATE          18
+
+#define MLME_ASSOC_REJ_NO_EXT_RATE        22
+#define MLME_ASSOC_REJ_NO_EXT_RATE_PBCC   23
+#define MLME_ASSOC_REJ_NO_CCK_OFDM        24
+
+#define MLME_QOS_UNSPECIFY                32
+#define MLME_REQUEST_DECLINED             37
+#define MLME_REQUEST_WITH_INVALID_PARAM   38
+#define MLME_DLS_NOT_ALLOW_IN_QBSS        48
+#define MLME_DEST_STA_NOT_IN_QBSS         49
+#define MLME_DEST_STA_IS_NOT_A_QSTA       50
+
+#define MLME_INVALID_FORMAT             0x51
+#define MLME_FAIL_NO_RESOURCE           0x52
+#define MLME_STATE_MACHINE_REJECT       0x53
+#define MLME_MAC_TABLE_FAIL             0x54
+
+// IE code
+#define IE_SSID                         0
+#define IE_SUPP_RATES                   1
+#define IE_FH_PARM                      2
+#define IE_DS_PARM                      3
+#define IE_CF_PARM                      4
+#define IE_TIM                          5
+#define IE_IBSS_PARM                    6
+#define IE_COUNTRY                      7     // 802.11d
+#define IE_802_11D_REQUEST              10    // 802.11d
+#define IE_QBSS_LOAD                    11    // 802.11e d9
+#define IE_EDCA_PARAMETER               12    // 802.11e d9
+#define IE_TSPEC                        13    // 802.11e d9
+#define IE_TCLAS                        14    // 802.11e d9
+#define IE_SCHEDULE                     15    // 802.11e d9
+#define IE_CHALLENGE_TEXT               16
+#define IE_POWER_CONSTRAINT             32    // 802.11h d3.3
+#define IE_POWER_CAPABILITY             33    // 802.11h d3.3
+#define IE_TPC_REQUEST                  34    // 802.11h d3.3
+#define IE_TPC_REPORT                   35    // 802.11h d3.3
+#define IE_SUPP_CHANNELS                36    // 802.11h d3.3
+#define IE_CHANNEL_SWITCH_ANNOUNCEMENT  37    // 802.11h d3.3
+#define IE_MEASUREMENT_REQUEST          38    // 802.11h d3.3
+#define IE_MEASUREMENT_REPORT           39    // 802.11h d3.3
+#define IE_QUIET                        40    // 802.11h d3.3
+#define IE_IBSS_DFS                     41    // 802.11h d3.3
+#define IE_ERP                          42    // 802.11g
+#define IE_TS_DELAY                     43    // 802.11e d9
+#define IE_TCLAS_PROCESSING             44    // 802.11e d9
+#define IE_QOS_CAPABILITY               46    // 802.11e d6
+#define IE_HT_CAP                       45    // 802.11n d1. HT CAPABILITY. ELEMENT ID TBD
+#define IE_AP_CHANNEL_REPORT			51    // 802.11k d6
+#define IE_HT_CAP2                         52    // 802.11n d1. HT CAPABILITY. ELEMENT ID TBD
+#define IE_RSN                          48    // 802.11i d3.0
+#define IE_WPA2                         48    // WPA2
+#define IE_EXT_SUPP_RATES               50    // 802.11g
+#define IE_SUPP_REG_CLASS               59    // 802.11y. Supported regulatory classes.
+#define IE_EXT_CHANNEL_SWITCH_ANNOUNCEMENT	60	// 802.11n
+#define IE_ADD_HT                         61    // 802.11n d1. ADDITIONAL HT CAPABILITY. ELEMENT ID TBD
+#define IE_ADD_HT2                        53    // 802.11n d1. ADDITIONAL HT CAPABILITY. ELEMENT ID TBD
+
+
+// For 802.11n D3.03
+//#define IE_NEW_EXT_CHA_OFFSET             62    // 802.11n d1. New extension channel offset elemet
+#define IE_SECONDARY_CH_OFFSET		62	// 802.11n D3.03	Secondary Channel Offset element
+#define IE_WAPI							68		// WAPI information element
+#define IE_2040_BSS_COEXIST               72    // 802.11n D3.0.3
+#define IE_2040_BSS_INTOLERANT_REPORT     73    // 802.11n D3.03
+#define IE_OVERLAPBSS_SCAN_PARM           74    // 802.11n D3.03
+#define IE_EXT_CAPABILITY                127   // 802.11n D3.03
+
+
+#define IE_WPA                          221   // WPA
+#define IE_VENDOR_SPECIFIC              221   // Wifi WMM (WME)
+
+#define OUI_BROADCOM_HT              51   //
+#define OUI_BROADCOM_HTADD              52   //
+#define OUI_PREN_HT_CAP              51   //
+#define OUI_PREN_ADD_HT              52   //
+
+// CCX information
+#define IE_AIRONET_CKIP                 133   // CCX1.0 ID 85H for CKIP
+#define IE_AP_TX_POWER                  150   // CCX 2.0 for AP transmit power
+#define IE_MEASUREMENT_CAPABILITY       221   // CCX 2.0
+#define IE_CCX_V2                       221
+#define IE_AIRONET_IPADDRESS            149   // CCX ID 95H for IP Address
+#define IE_AIRONET_CCKMREASSOC          156   // CCX ID 9CH for CCKM Reassociation Request element
+#define CKIP_NEGOTIATION_LENGTH         30
+#define AIRONET_IPADDRESS_LENGTH        10
+#define AIRONET_CCKMREASSOC_LENGTH      24
+
+// ========================================================
+// MLME state machine definition
+// ========================================================
+
+// STA MLME state mahcines
+#define ASSOC_STATE_MACHINE             1
+#define AUTH_STATE_MACHINE              2
+#define AUTH_RSP_STATE_MACHINE          3
+#define SYNC_STATE_MACHINE              4
+#define MLME_CNTL_STATE_MACHINE         5
+#define WPA_PSK_STATE_MACHINE           6
+#define LEAP_STATE_MACHINE              7
+#define AIRONET_STATE_MACHINE           8
+#define ACTION_STATE_MACHINE           9
+
+// AP MLME state machines
+#define AP_ASSOC_STATE_MACHINE          11
+#define AP_AUTH_STATE_MACHINE           12
+#define AP_AUTH_RSP_STATE_MACHINE       13
+#define AP_SYNC_STATE_MACHINE           14
+#define AP_CNTL_STATE_MACHINE           15
+#define AP_WPA_STATE_MACHINE            16
+
+#define WSC_STATE_MACHINE            17
+#define WSC_UPNP_STATE_MACHINE		    18
+
+
+
+#ifdef QOS_DLS_SUPPORT
+#define DLS_STATE_MACHINE               26
+#endif // QOS_DLS_SUPPORT //
+
+//
+// STA's CONTROL/CONNECT state machine: states, events, total function #
+//
+#define CNTL_IDLE                       0
+#define CNTL_WAIT_DISASSOC              1
+#define CNTL_WAIT_JOIN                  2
+#define CNTL_WAIT_REASSOC               3
+#define CNTL_WAIT_START                 4
+#define CNTL_WAIT_AUTH                  5
+#define CNTL_WAIT_ASSOC                 6
+#define CNTL_WAIT_AUTH2                 7
+#define CNTL_WAIT_OID_LIST_SCAN         8
+#define CNTL_WAIT_OID_DISASSOC          9
+#ifdef RT2870
+#define CNTL_WAIT_SCAN_FOR_CONNECT      10
+#endif // RT2870 //
+
+#define MT2_ASSOC_CONF                  34
+#define MT2_AUTH_CONF                   35
+#define MT2_DEAUTH_CONF                 36
+#define MT2_DISASSOC_CONF               37
+#define MT2_REASSOC_CONF                38
+#define MT2_PWR_MGMT_CONF               39
+#define MT2_JOIN_CONF                   40
+#define MT2_SCAN_CONF                   41
+#define MT2_START_CONF                  42
+#define MT2_GET_CONF                    43
+#define MT2_SET_CONF                    44
+#define MT2_RESET_CONF                  45
+#define MT2_MLME_ROAMING_REQ            52
+
+#define CNTL_FUNC_SIZE                  1
+
+//
+// STA's ASSOC state machine: states, events, total function #
+//
+#define ASSOC_IDLE                      0
+#define ASSOC_WAIT_RSP                  1
+#define REASSOC_WAIT_RSP                2
+#define DISASSOC_WAIT_RSP               3
+#define MAX_ASSOC_STATE                 4
+
+#define ASSOC_MACHINE_BASE              0
+#define MT2_MLME_ASSOC_REQ              0
+#define MT2_MLME_REASSOC_REQ            1
+#define MT2_MLME_DISASSOC_REQ           2
+#define MT2_PEER_DISASSOC_REQ           3
+#define MT2_PEER_ASSOC_REQ              4
+#define MT2_PEER_ASSOC_RSP              5
+#define MT2_PEER_REASSOC_REQ            6
+#define MT2_PEER_REASSOC_RSP            7
+#define MT2_DISASSOC_TIMEOUT            8
+#define MT2_ASSOC_TIMEOUT               9
+#define MT2_REASSOC_TIMEOUT             10
+#define MAX_ASSOC_MSG                   11
+
+#define ASSOC_FUNC_SIZE                 (MAX_ASSOC_STATE * MAX_ASSOC_MSG)
+
+//
+// ACT state machine: states, events, total function #
+//
+#define ACT_IDLE                      0
+#define MAX_ACT_STATE                 1
+
+#define ACT_MACHINE_BASE              0
+
+//Those PEER_xx_CATE number is based on real Categary value in IEEE spec. Please don'es modify it by your self.
+//Category
+#define MT2_PEER_SPECTRUM_CATE              0
+#define MT2_PEER_QOS_CATE              1
+#define MT2_PEER_DLS_CATE             2
+#define MT2_PEER_BA_CATE             3
+#define MT2_PEER_PUBLIC_CATE             4
+#define MT2_PEER_RM_CATE             5
+#define MT2_PEER_HT_CATE             7	//	7.4.7
+#define MAX_PEER_CATE_MSG                   7
+#define MT2_MLME_ADD_BA_CATE             8
+#define MT2_MLME_ORI_DELBA_CATE             9
+#define MT2_MLME_REC_DELBA_CATE             10
+#define MT2_MLME_QOS_CATE              11
+#define MT2_MLME_DLS_CATE             12
+#define MT2_ACT_INVALID             13
+#define MAX_ACT_MSG                   14
+
+//Category field
+#define CATEGORY_SPECTRUM		0
+#define CATEGORY_QOS			1
+#define CATEGORY_DLS			2
+#define CATEGORY_BA			3
+#define CATEGORY_PUBLIC		4
+#define CATEGORY_RM			5
+#define CATEGORY_HT			7
+
+
+// DLS Action frame definition
+#define ACTION_DLS_REQUEST			0
+#define ACTION_DLS_RESPONSE			1
+#define ACTION_DLS_TEARDOWN			2
+
+//Spectrum  Action field value 802.11h 7.4.1
+#define SPEC_MRQ	0	// Request
+#define SPEC_MRP	1	//Report
+#define SPEC_TPCRQ	2
+#define SPEC_TPCRP	3
+#define SPEC_CHANNEL_SWITCH	4
+
+
+//BA  Action field value
+#define ADDBA_REQ	0
+#define ADDBA_RESP	1
+#define DELBA   2
+
+//Public's  Action field value in Public Category.  Some in 802.11y and some in 11n
+#define ACTION_BSS_2040_COEXIST				0	// 11n
+#define ACTION_DSE_ENABLEMENT					1	// 11y D9.0
+#define ACTION_DSE_DEENABLEMENT				2	// 11y D9.0
+#define ACTION_DSE_REG_LOCATION_ANNOUNCE	3	// 11y D9.0
+#define ACTION_EXT_CH_SWITCH_ANNOUNCE		4	// 11y D9.0
+#define ACTION_DSE_MEASUREMENT_REQ			5	// 11y D9.0
+#define ACTION_DSE_MEASUREMENT_REPORT		6	// 11y D9.0
+#define ACTION_MEASUREMENT_PILOT_ACTION		7  	// 11y D9.0
+#define ACTION_DSE_POWER_CONSTRAINT			8	// 11y D9.0
+
+
+//HT  Action field value
+#define NOTIFY_BW_ACTION				0
+#define SMPS_ACTION						1
+#define PSMP_ACTION   					2
+#define SETPCO_ACTION					3
+#define MIMO_CHA_MEASURE_ACTION			4
+#define MIMO_N_BEACONFORM				5
+#define MIMO_BEACONFORM					6
+#define ANTENNA_SELECT					7
+#define HT_INFO_EXCHANGE				8
+
+#define ACT_FUNC_SIZE                 (MAX_ACT_STATE * MAX_ACT_MSG)
+//
+// STA's AUTHENTICATION state machine: states, evvents, total function #
+//
+#define AUTH_REQ_IDLE                   0
+#define AUTH_WAIT_SEQ2                  1
+#define AUTH_WAIT_SEQ4                  2
+#define MAX_AUTH_STATE                  3
+
+#define AUTH_MACHINE_BASE               0
+#define MT2_MLME_AUTH_REQ               0
+#define MT2_PEER_AUTH_EVEN              1
+#define MT2_AUTH_TIMEOUT                2
+#define MAX_AUTH_MSG                    3
+
+#define AUTH_FUNC_SIZE                  (MAX_AUTH_STATE * MAX_AUTH_MSG)
+
+//
+// STA's AUTH_RSP state machine: states, events, total function #
+//
+#define AUTH_RSP_IDLE                   0
+#define AUTH_RSP_WAIT_CHAL              1
+#define MAX_AUTH_RSP_STATE              2
+
+#define AUTH_RSP_MACHINE_BASE           0
+#define MT2_AUTH_CHALLENGE_TIMEOUT      0
+#define MT2_PEER_AUTH_ODD               1
+#define MT2_PEER_DEAUTH                 2
+#define MAX_AUTH_RSP_MSG                3
+
+#define AUTH_RSP_FUNC_SIZE              (MAX_AUTH_RSP_STATE * MAX_AUTH_RSP_MSG)
+
+//
+// STA's SYNC state machine: states, events, total function #
+//
+#define SYNC_IDLE                       0  // merge NO_BSS,IBSS_IDLE,IBSS_ACTIVE and BSS in to 1 state
+#define JOIN_WAIT_BEACON                1
+#define SCAN_LISTEN                     2
+#define MAX_SYNC_STATE                  3
+
+#define SYNC_MACHINE_BASE               0
+#define MT2_MLME_SCAN_REQ               0
+#define MT2_MLME_JOIN_REQ               1
+#define MT2_MLME_START_REQ              2
+#define MT2_PEER_BEACON                 3
+#define MT2_PEER_PROBE_RSP              4
+#define MT2_PEER_ATIM                   5
+#define MT2_SCAN_TIMEOUT                6
+#define MT2_BEACON_TIMEOUT              7
+#define MT2_ATIM_TIMEOUT                8
+#define MT2_PEER_PROBE_REQ              9
+#define MAX_SYNC_MSG                    10
+
+#define SYNC_FUNC_SIZE                  (MAX_SYNC_STATE * MAX_SYNC_MSG)
+
+//Messages for the DLS state machine
+#define DLS_IDLE						0
+#define MAX_DLS_STATE					1
+
+#define DLS_MACHINE_BASE				0
+#define MT2_MLME_DLS_REQ			    0
+#define MT2_PEER_DLS_REQ			    1
+#define MT2_PEER_DLS_RSP			    2
+#define MT2_MLME_DLS_TEAR_DOWN		    3
+#define MT2_PEER_DLS_TEAR_DOWN		    4
+#define MAX_DLS_MSG				        5
+
+#define DLS_FUNC_SIZE					(MAX_DLS_STATE * MAX_DLS_MSG)
+
+//
+// STA's WPA-PSK State machine: states, events, total function #
+//
+#define WPA_PSK_IDLE					0
+#define MAX_WPA_PSK_STATE				1
+
+#define WPA_MACHINE_BASE                0
+#define MT2_EAPPacket                   0
+#define MT2_EAPOLStart                  1
+#define MT2_EAPOLLogoff                 2
+#define MT2_EAPOLKey                    3
+#define MT2_EAPOLASFAlert               4
+#define MAX_WPA_PSK_MSG                 5
+
+#define	WPA_PSK_FUNC_SIZE				(MAX_WPA_PSK_STATE * MAX_WPA_PSK_MSG)
+
+//
+// STA's CISCO-AIRONET State machine: states, events, total function #
+//
+#define AIRONET_IDLE					0
+#define	AIRONET_SCANNING				1
+#define MAX_AIRONET_STATE				2
+
+#define AIRONET_MACHINE_BASE		    0
+#define MT2_AIRONET_MSG				    0
+#define MT2_AIRONET_SCAN_REQ		    1
+#define MT2_AIRONET_SCAN_DONE		    2
+#define MAX_AIRONET_MSG				    3
+
+#define	AIRONET_FUNC_SIZE				(MAX_AIRONET_STATE * MAX_AIRONET_MSG)
+
+//
+// WSC State machine: states, events, total function #
+//
+
+//
+// AP's CONTROL/CONNECT state machine: states, events, total function #
+//
+#define AP_CNTL_FUNC_SIZE               1
+
+//
+// AP's ASSOC state machine: states, events, total function #
+//
+#define AP_ASSOC_IDLE                   0
+#define AP_MAX_ASSOC_STATE              1
+
+#define AP_ASSOC_MACHINE_BASE           0
+#define APMT2_MLME_DISASSOC_REQ         0
+#define APMT2_PEER_DISASSOC_REQ         1
+#define APMT2_PEER_ASSOC_REQ            2
+#define APMT2_PEER_REASSOC_REQ          3
+#define APMT2_CLS3ERR                   4
+#define AP_MAX_ASSOC_MSG                5
+
+#define AP_ASSOC_FUNC_SIZE              (AP_MAX_ASSOC_STATE * AP_MAX_ASSOC_MSG)
+
+//
+// AP's AUTHENTICATION state machine: states, events, total function #
+//
+#define AP_AUTH_REQ_IDLE                0
+#define AP_MAX_AUTH_STATE               1
+
+#define AP_AUTH_MACHINE_BASE            0
+#define APMT2_MLME_DEAUTH_REQ           0
+#define APMT2_CLS2ERR                   1
+#define AP_MAX_AUTH_MSG                 2
+
+#define AP_AUTH_FUNC_SIZE               (AP_MAX_AUTH_STATE * AP_MAX_AUTH_MSG)
+
+//
+// AP's AUTH-RSP state machine: states, events, total function #
+//
+#define AP_AUTH_RSP_IDLE                0
+#define AP_MAX_AUTH_RSP_STATE           1
+
+#define AP_AUTH_RSP_MACHINE_BASE        0
+#define APMT2_AUTH_CHALLENGE_TIMEOUT    0
+#define APMT2_PEER_AUTH_ODD             1
+#define APMT2_PEER_DEAUTH               2
+#define AP_MAX_AUTH_RSP_MSG             3
+
+#define AP_AUTH_RSP_FUNC_SIZE           (AP_MAX_AUTH_RSP_STATE * AP_MAX_AUTH_RSP_MSG)
+
+//
+// AP's SYNC state machine: states, events, total function #
+//
+#define AP_SYNC_IDLE                    0
+#define AP_SCAN_LISTEN					1
+#define AP_MAX_SYNC_STATE               2
+
+#define AP_SYNC_MACHINE_BASE            0
+#define APMT2_PEER_PROBE_REQ            0
+#define APMT2_PEER_BEACON               1
+#define APMT2_MLME_SCAN_REQ				2
+#define APMT2_PEER_PROBE_RSP			3
+#define APMT2_SCAN_TIMEOUT				4
+#define APMT2_MLME_SCAN_CNCL			5
+#define AP_MAX_SYNC_MSG                 6
+
+#define AP_SYNC_FUNC_SIZE               (AP_MAX_SYNC_STATE * AP_MAX_SYNC_MSG)
+
+//
+// AP's WPA state machine: states, events, total function #
+//
+#define AP_WPA_PTK                      0
+#define AP_MAX_WPA_PTK_STATE            1
+
+#define AP_WPA_MACHINE_BASE             0
+#define APMT2_EAPPacket                 0
+#define APMT2_EAPOLStart                1
+#define APMT2_EAPOLLogoff               2
+#define APMT2_EAPOLKey                  3
+#define APMT2_EAPOLASFAlert             4
+#define AP_MAX_WPA_MSG                  5
+
+#define AP_WPA_FUNC_SIZE                (AP_MAX_WPA_PTK_STATE * AP_MAX_WPA_MSG)
+
+
+
+// =============================================================================
+
+// value domain of 802.11 header FC.Tyte, which is b3..b2 of the 1st-byte of MAC header
+#define BTYPE_MGMT                  0
+#define BTYPE_CNTL                  1
+#define BTYPE_DATA                  2
+
+// value domain of 802.11 MGMT frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header
+#define SUBTYPE_ASSOC_REQ           0
+#define SUBTYPE_ASSOC_RSP           1
+#define SUBTYPE_REASSOC_REQ         2
+#define SUBTYPE_REASSOC_RSP         3
+#define SUBTYPE_PROBE_REQ           4
+#define SUBTYPE_PROBE_RSP           5
+#define SUBTYPE_BEACON              8
+#define SUBTYPE_ATIM                9
+#define SUBTYPE_DISASSOC            10
+#define SUBTYPE_AUTH                11
+#define SUBTYPE_DEAUTH              12
+#define SUBTYPE_ACTION              13
+#define SUBTYPE_ACTION_NO_ACK              14
+
+// value domain of 802.11 CNTL frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header
+#define SUBTYPE_WRAPPER       	7
+#define SUBTYPE_BLOCK_ACK_REQ       8
+#define SUBTYPE_BLOCK_ACK           9
+#define SUBTYPE_PS_POLL             10
+#define SUBTYPE_RTS                 11
+#define SUBTYPE_CTS                 12
+#define SUBTYPE_ACK                 13
+#define SUBTYPE_CFEND               14
+#define SUBTYPE_CFEND_CFACK         15
+
+// value domain of 802.11 DATA frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header
+#define SUBTYPE_DATA                0
+#define SUBTYPE_DATA_CFACK          1
+#define SUBTYPE_DATA_CFPOLL         2
+#define SUBTYPE_DATA_CFACK_CFPOLL   3
+#define SUBTYPE_NULL_FUNC           4
+#define SUBTYPE_CFACK               5
+#define SUBTYPE_CFPOLL              6
+#define SUBTYPE_CFACK_CFPOLL        7
+#define SUBTYPE_QDATA               8
+#define SUBTYPE_QDATA_CFACK         9
+#define SUBTYPE_QDATA_CFPOLL        10
+#define SUBTYPE_QDATA_CFACK_CFPOLL  11
+#define SUBTYPE_QOS_NULL            12
+#define SUBTYPE_QOS_CFACK           13
+#define SUBTYPE_QOS_CFPOLL          14
+#define SUBTYPE_QOS_CFACK_CFPOLL    15
+
+// ACK policy of QOS Control field bit 6:5
+#define NORMAL_ACK                  0x00  // b6:5 = 00
+#define NO_ACK                      0x20  // b6:5 = 01
+#define NO_EXPLICIT_ACK             0x40  // b6:5 = 10
+#define BLOCK_ACK                   0x60  // b6:5 = 11
+
+//
+// rtmp_data.c use these definition
+//
+#define LENGTH_802_11               24
+#define LENGTH_802_11_AND_H         30
+#define LENGTH_802_11_CRC_H         34
+#define LENGTH_802_11_CRC           28
+#define LENGTH_802_11_WITH_ADDR4    30
+#define LENGTH_802_3                14
+#define LENGTH_802_3_TYPE           2
+#define LENGTH_802_1_H              8
+#define LENGTH_EAPOL_H              4
+#define LENGTH_WMMQOS_H				2
+#define LENGTH_CRC                  4
+#define MAX_SEQ_NUMBER              0x0fff
+#define LENGTH_802_3_NO_TYPE		12
+#define LENGTH_802_1Q				4 /* VLAN related */
+
+// STA_CSR4.field.TxResult
+#define TX_RESULT_SUCCESS           0
+#define TX_RESULT_ZERO_LENGTH       1
+#define TX_RESULT_UNDER_RUN         2
+#define TX_RESULT_OHY_ERROR         4
+#define TX_RESULT_RETRY_FAIL        6
+
+// All PHY rate summary in TXD
+// Preamble MODE in TxD
+#define MODE_CCK	0
+#define MODE_OFDM   1
+#ifdef DOT11_N_SUPPORT
+#define MODE_HTMIX	2
+#define MODE_HTGREENFIELD	3
+#endif // DOT11_N_SUPPORT //
+// MCS for CCK.  BW.SGI.STBC are reserved
+#define MCS_LONGP_RATE_1                      0	 // long preamble CCK 1Mbps
+#define MCS_LONGP_RATE_2                      1	// long preamble CCK 1Mbps
+#define MCS_LONGP_RATE_5_5                    2
+#define MCS_LONGP_RATE_11                     3
+#define MCS_SHORTP_RATE_1                      4	 // long preamble CCK 1Mbps. short is forbidden in 1Mbps
+#define MCS_SHORTP_RATE_2                      5	// short preamble CCK 2Mbps
+#define MCS_SHORTP_RATE_5_5                    6
+#define MCS_SHORTP_RATE_11                     7
+// To send duplicate legacy OFDM. set BW=BW_40.  SGI.STBC are reserved
+#define MCS_RATE_6                      0   // legacy OFDM
+#define MCS_RATE_9                      1   // OFDM
+#define MCS_RATE_12                     2   // OFDM
+#define MCS_RATE_18                     3   // OFDM
+#define MCS_RATE_24                     4  // OFDM
+#define MCS_RATE_36                     5   // OFDM
+#define MCS_RATE_48                     6  // OFDM
+#define MCS_RATE_54                     7 // OFDM
+// HT
+#define MCS_0		0	// 1S
+#define MCS_1		1
+#define MCS_2		2
+#define MCS_3		3
+#define MCS_4		4
+#define MCS_5		5
+#define MCS_6		6
+#define MCS_7		7
+#define MCS_8		8	// 2S
+#define MCS_9		9
+#define MCS_10		10
+#define MCS_11		11
+#define MCS_12		12
+#define MCS_13		13
+#define MCS_14		14
+#define MCS_15		15
+#define MCS_16		16	// 3*3
+#define MCS_17		17
+#define MCS_18		18
+#define MCS_19		19
+#define MCS_20		20
+#define MCS_21		21
+#define MCS_22		22
+#define MCS_23		23
+#define MCS_32		32
+#define MCS_AUTO		33
+
+#ifdef DOT11_N_SUPPORT
+// OID_HTPHYMODE
+// MODE
+#define HTMODE_MM	0
+#define HTMODE_GF	1
+#endif // DOT11_N_SUPPORT //
+
+// Fixed Tx MODE - HT, CCK or OFDM
+#define FIXED_TXMODE_HT		0
+#define FIXED_TXMODE_CCK	1
+#define FIXED_TXMODE_OFDM 	2
+// BW
+#define BW_20		BAND_WIDTH_20
+#define BW_40		BAND_WIDTH_40
+#define BW_BOTH		BAND_WIDTH_BOTH
+#define BW_10		BAND_WIDTH_10	// 802.11j has 10MHz. This definition is for internal usage. doesn't fill in the IE or other field.
+
+#ifdef DOT11_N_SUPPORT
+// SHORTGI
+#define GI_400		GAP_INTERVAL_400	// only support in HT mode
+#define GI_BOTH		GAP_INTERVAL_BOTH
+#endif // DOT11_N_SUPPORT //
+#define GI_800		GAP_INTERVAL_800
+// STBC
+#define STBC_NONE	0
+#ifdef DOT11_N_SUPPORT
+#define STBC_USE	1	// limited use in rt2860b phy
+#define RXSTBC_ONE	1	// rx support of one spatial stream
+#define RXSTBC_TWO	2	// rx support of 1 and 2 spatial stream
+#define RXSTBC_THR	3	// rx support of 1~3 spatial stream
+// MCS FEEDBACK
+#define MCSFBK_NONE	0  // not support mcs feedback /
+#define MCSFBK_RSV	1	// reserved
+#define MCSFBK_UNSOLICIT	2	// only support unsolict mcs feedback
+#define MCSFBK_MRQ	3	// response to both MRQ and unsolict mcs feedback
+
+// MIMO power safe
+#define	MMPS_STATIC	0
+#define	MMPS_DYNAMIC		1
+#define   MMPS_RSV		2
+#define MMPS_ENABLE		3
+
+
+// A-MSDU size
+#define	AMSDU_0	0
+#define	AMSDU_1		1
+
+#endif // DOT11_N_SUPPORT //
+
+// MCS use 7 bits
+#define TXRATEMIMO		0x80
+#define TXRATEMCS		0x7F
+#define TXRATEOFDM		0x7F
+#define RATE_1                      0
+#define RATE_2                      1
+#define RATE_5_5                    2
+#define RATE_11                     3
+#define RATE_6                      4   // OFDM
+#define RATE_9                      5   // OFDM
+#define RATE_12                     6   // OFDM
+#define RATE_18                     7   // OFDM
+#define RATE_24                     8   // OFDM
+#define RATE_36                     9   // OFDM
+#define RATE_48                     10  // OFDM
+#define RATE_54                     11  // OFDM
+#define RATE_FIRST_OFDM_RATE        RATE_6
+#define RATE_LAST_OFDM_RATE        	RATE_54
+#define RATE_6_5                    12  // HT mix
+#define RATE_13                     13  // HT mix
+#define RATE_19_5                   14  // HT mix
+#define RATE_26                     15  // HT mix
+#define RATE_39                     16  // HT mix
+#define RATE_52                     17  // HT mix
+#define RATE_58_5                   18  // HT mix
+#define RATE_65                     19  // HT mix
+#define RATE_78                     20  // HT mix
+#define RATE_104                    21  // HT mix
+#define RATE_117                    22  // HT mix
+#define RATE_130                    23  // HT mix
+//#define RATE_AUTO_SWITCH            255 // for StaCfg.FixedTxRate only
+#define HTRATE_0                      12
+#define RATE_FIRST_MM_RATE        HTRATE_0
+#define RATE_FIRST_HT_RATE        HTRATE_0
+#define RATE_LAST_HT_RATE        HTRATE_0
+
+// pTxWI->txop
+#define IFS_HTTXOP                 0	// The txop will be handles by ASIC.
+#define IFS_PIFS                    1
+#define IFS_SIFS                    2
+#define IFS_BACKOFF                 3
+
+// pTxD->RetryMode
+#define LONG_RETRY                  1
+#define SHORT_RETRY                 0
+
+// Country Region definition
+#define REGION_MINIMUM_BG_BAND            0
+#define REGION_0_BG_BAND                  0       // 1-11
+#define REGION_1_BG_BAND                  1       // 1-13
+#define REGION_2_BG_BAND                  2       // 10-11
+#define REGION_3_BG_BAND                  3       // 10-13
+#define REGION_4_BG_BAND                  4       // 14
+#define REGION_5_BG_BAND                  5       // 1-14
+#define REGION_6_BG_BAND                  6       // 3-9
+#define REGION_7_BG_BAND                  7       // 5-13
+#define REGION_31_BG_BAND                 31       // 5-13
+#define REGION_MAXIMUM_BG_BAND            7
+
+#define REGION_MINIMUM_A_BAND             0
+#define REGION_0_A_BAND                   0       // 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165
+#define REGION_1_A_BAND                   1       // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
+#define REGION_2_A_BAND                   2       // 36, 40, 44, 48, 52, 56, 60, 64
+#define REGION_3_A_BAND                   3       // 52, 56, 60, 64, 149, 153, 157, 161
+#define REGION_4_A_BAND                   4       // 149, 153, 157, 161, 165
+#define REGION_5_A_BAND                   5       // 149, 153, 157, 161
+#define REGION_6_A_BAND                   6       // 36, 40, 44, 48
+#define REGION_7_A_BAND                   7       // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165
+#define REGION_8_A_BAND                   8       // 52, 56, 60, 64
+#define REGION_9_A_BAND                   9       // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165
+#define REGION_10_A_BAND                  10	  // 36, 40, 44, 48, 149, 153, 157, 161, 165
+#define REGION_11_A_BAND                  11	  // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161
+#define REGION_MAXIMUM_A_BAND             11
+
+// pTxD->CipherAlg
+#define CIPHER_NONE                 0
+#define CIPHER_WEP64                1
+#define CIPHER_WEP128               2
+#define CIPHER_TKIP                 3
+#define CIPHER_AES                  4
+#define CIPHER_CKIP64               5
+#define CIPHER_CKIP128              6
+#define CIPHER_TKIP_NO_MIC          7       // MIC appended by driver: not a valid value in hardware key table
+#define CIPHER_SMS4					8
+
+// value domain of pAd->RfIcType
+#define RFIC_2820                   1       // 2.4G 2T3R
+#define RFIC_2850                   2       // 2.4G/5G 2T3R
+#define RFIC_2720                   3       // 2.4G 1T2R
+#define RFIC_2750                   4       // 2.4G/5G 1T2R
+#define RFIC_3020                   5       // 2.4G 1T1R
+#define RFIC_2020                   6       // 2.4G B/G
+#define RFIC_3021                   7       // 2.4G 1T2R
+#define RFIC_3022                   8       // 2.4G 2T2R
+
+// LED Status.
+#define LED_LINK_DOWN               0
+#define LED_LINK_UP                 1
+#define LED_RADIO_OFF               2
+#define LED_RADIO_ON                3
+#define LED_HALT                    4
+#define LED_WPS                     5
+#define LED_ON_SITE_SURVEY          6
+#define LED_POWER_UP                7
+
+// value domain of pAd->LedCntl.LedMode and E2PROM
+#define LED_MODE_DEFAULT            0
+#define LED_MODE_TWO_LED			1
+#define LED_MODE_SIGNAL_STREGTH		8  // EEPROM define =8
+
+// RC4 init value, used fro WEP & TKIP
+#define PPPINITFCS32                0xffffffff   /* Initial FCS value */
+
+// value domain of pAd->StaCfg.PortSecured. 802.1X controlled port definition
+#define WPA_802_1X_PORT_SECURED     1
+#define WPA_802_1X_PORT_NOT_SECURED 2
+
+#define PAIRWISE_KEY                1
+#define GROUP_KEY                   2
+
+//definition of DRS
+#define MAX_STEP_OF_TX_RATE_SWITCH	32
+
+
+// pre-allocated free NDIS PACKET/BUFFER poll for internal usage
+#define MAX_NUM_OF_FREE_NDIS_PACKET 128
+
+//Block ACK
+#define MAX_TX_REORDERBUF   64
+#define MAX_RX_REORDERBUF   64
+#define DEFAULT_TX_TIMEOUT   30
+#define DEFAULT_RX_TIMEOUT   30
+
+// definition of Recipient or Originator
+#define I_RECIPIENT                  TRUE
+#define I_ORIGINATOR                   FALSE
+
+#define DEFAULT_BBP_TX_POWER        0
+#define DEFAULT_RF_TX_POWER         5
+
+#define MAX_INI_BUFFER_SIZE			4096
+#define MAX_PARAM_BUFFER_SIZE		(2048) // enough for ACL (18*64)
+											//18 : the length of Mac address acceptable format "01:02:03:04:05:06;")
+											//64 : MAX_NUM_OF_ACL_LIST
+// definition of pAd->OpMode
+#define OPMODE_STA                  0
+#define OPMODE_AP                   1
+//#define OPMODE_L3_BRG               2       // as AP and STA at the same time
+
+#ifdef RT_BIG_ENDIAN
+#define DIR_READ                    0
+#define DIR_WRITE                   1
+#define TYPE_TXD                    0
+#define TYPE_RXD                    1
+#define TYPE_TXINFO					0
+#define TYPE_RXINFO					1
+#define TYPE_TXWI					0
+#define TYPE_RXWI					1
+#endif
+
+// ========================= AP rtmp_def.h ===========================
+// value domain for pAd->EventTab.Log[].Event
+#define EVENT_RESET_ACCESS_POINT    0 // Log = "hh:mm:ss   Restart Access Point"
+#define EVENT_ASSOCIATED            1 // Log = "hh:mm:ss   STA 00:01:02:03:04:05 associated"
+#define EVENT_DISASSOCIATED         2 // Log = "hh:mm:ss   STA 00:01:02:03:04:05 left this BSS"
+#define EVENT_AGED_OUT              3 // Log = "hh:mm:ss   STA 00:01:02:03:04:05 was aged-out and removed from this BSS"
+#define EVENT_COUNTER_M             4
+#define EVENT_INVALID_PSK           5
+#define EVENT_MAX_EVENT_TYPE        6
+// ==== end of AP rtmp_def.h ============
+
+// definition RSSI Number
+#define RSSI_0					0
+#define RSSI_1					1
+#define RSSI_2					2
+
+// definition of radar detection
+#define RD_NORMAL_MODE				0	// Not found radar signal
+#define RD_SWITCHING_MODE			1	// Found radar signal, and doing channel switch
+#define RD_SILENCE_MODE				2	// After channel switch, need to be silence a while to ensure radar not found
+
+//Driver defined cid for mapping status and command.
+#define  SLEEPCID	0x11
+#define  WAKECID	0x22
+#define  QUERYPOWERCID	0x33
+#define  OWNERMCU	0x1
+#define  OWNERCPU	0x0
+
+// MBSSID definition
+#define ENTRY_NOT_FOUND             0xFF
+
+
+/* After Linux 2.6.9,
+ * VLAN module use Private (from user) interface flags (netdevice->priv_flags).
+ * #define IFF_802_1Q_VLAN 0x1         --    802.1Q VLAN device.  in if.h
+ * ref to ip_sabotage_out() [ out->priv_flags & IFF_802_1Q_VLAN ] in br_netfilter.c
+ *
+ * For this reason, we MUST use EVEN value in priv_flags
+ */
+#define INT_MAIN                    0x0100
+#define INT_MBSSID                  0x0200
+#define INT_WDS                     0x0300
+#define INT_APCLI                   0x0400
+#define INT_MESH                   	0x0500
+
+// Use bitmap to allow coexist of ATE_TXFRAME and ATE_RXFRAME(i.e.,to support LoopBack mode)
+#ifdef RALINK_ATE
+#define	ATE_START                   0x00   // Start ATE
+#define	ATE_STOP                    0x80   // Stop ATE
+#define	ATE_TXCONT                  0x05   // Continuous Transmit
+#define	ATE_TXCARR                  0x09   // Transmit Carrier
+#define	ATE_TXCARRSUPP              0x11   // Transmit Carrier Suppression
+#define	ATE_TXFRAME                 0x01   // Transmit Frames
+#define	ATE_RXFRAME                 0x02   // Receive Frames
+#ifdef RALINK_28xx_QA
+#define ATE_TXSTOP                  0xe2   // Stop Transmition(i.e., TXCONT, TXCARR, TXCARRSUPP, and TXFRAME)
+#define ATE_RXSTOP					0xfd   // Stop receiving Frames
+#define	BBP22_TXFRAME     			0x00   // Transmit Frames
+#define	BBP22_TXCONT_OR_CARRSUPP    0x80   // Continuous Transmit or Carrier Suppression
+#define	BBP22_TXCARR                0xc1   // Transmit Carrier
+#define	BBP24_TXCONT                0x00   // Continuous Transmit
+#define	BBP24_CARRSUPP              0x01   // Carrier Suppression
+#endif // RALINK_28xx_QA //
+#endif // RALINK_ATE //
+
+// WEP Key TYPE
+#define WEP_HEXADECIMAL_TYPE    0
+#define WEP_ASCII_TYPE          1
+
+
+
+// WIRELESS EVENTS definition
+/* Max number of char in custom event, refer to wireless_tools.28/wireless.20.h */
+#define IW_CUSTOM_MAX_LEN				  			255	/* In bytes */
+
+// For system event - start
+#define	IW_SYS_EVENT_FLAG_START                     0x0200
+#define	IW_ASSOC_EVENT_FLAG                         0x0200
+#define	IW_DISASSOC_EVENT_FLAG                      0x0201
+#define	IW_DEAUTH_EVENT_FLAG                      	0x0202
+#define	IW_AGEOUT_EVENT_FLAG                      	0x0203
+#define	IW_COUNTER_MEASURES_EVENT_FLAG              0x0204
+#define	IW_REPLAY_COUNTER_DIFF_EVENT_FLAG           0x0205
+#define	IW_RSNIE_DIFF_EVENT_FLAG           			0x0206
+#define	IW_MIC_DIFF_EVENT_FLAG           			0x0207
+#define IW_ICV_ERROR_EVENT_FLAG						0x0208
+#define IW_MIC_ERROR_EVENT_FLAG						0x0209
+#define IW_GROUP_HS_TIMEOUT_EVENT_FLAG				0x020A
+#define	IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG			0x020B
+#define IW_RSNIE_SANITY_FAIL_EVENT_FLAG				0x020C
+#define IW_SET_KEY_DONE_WPA1_EVENT_FLAG				0x020D
+#define IW_SET_KEY_DONE_WPA2_EVENT_FLAG				0x020E
+#define IW_STA_LINKUP_EVENT_FLAG					0x020F
+#define IW_STA_LINKDOWN_EVENT_FLAG					0x0210
+#define IW_SCAN_COMPLETED_EVENT_FLAG				0x0211
+#define IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG				0x0212
+// if add new system event flag, please upadte the IW_SYS_EVENT_FLAG_END
+#define	IW_SYS_EVENT_FLAG_END                       0x0212
+#define	IW_SYS_EVENT_TYPE_NUM						(IW_SYS_EVENT_FLAG_END - IW_SYS_EVENT_FLAG_START + 1)
+// For system event - end
+
+// For spoof attack event - start
+#define	IW_SPOOF_EVENT_FLAG_START                   0x0300
+#define IW_CONFLICT_SSID_EVENT_FLAG					0x0300
+#define IW_SPOOF_ASSOC_RESP_EVENT_FLAG				0x0301
+#define IW_SPOOF_REASSOC_RESP_EVENT_FLAG			0x0302
+#define IW_SPOOF_PROBE_RESP_EVENT_FLAG				0x0303
+#define IW_SPOOF_BEACON_EVENT_FLAG					0x0304
+#define IW_SPOOF_DISASSOC_EVENT_FLAG				0x0305
+#define IW_SPOOF_AUTH_EVENT_FLAG					0x0306
+#define IW_SPOOF_DEAUTH_EVENT_FLAG					0x0307
+#define IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG			0x0308
+#define IW_REPLAY_ATTACK_EVENT_FLAG					0x0309
+// if add new spoof attack event flag, please upadte the IW_SPOOF_EVENT_FLAG_END
+#define	IW_SPOOF_EVENT_FLAG_END                     0x0309
+#define	IW_SPOOF_EVENT_TYPE_NUM						(IW_SPOOF_EVENT_FLAG_END - IW_SPOOF_EVENT_FLAG_START + 1)
+// For spoof attack event - end
+
+// For flooding attack event - start
+#define	IW_FLOOD_EVENT_FLAG_START                   0x0400
+#define IW_FLOOD_AUTH_EVENT_FLAG					0x0400
+#define IW_FLOOD_ASSOC_REQ_EVENT_FLAG				0x0401
+#define IW_FLOOD_REASSOC_REQ_EVENT_FLAG				0x0402
+#define IW_FLOOD_PROBE_REQ_EVENT_FLAG				0x0403
+#define IW_FLOOD_DISASSOC_EVENT_FLAG				0x0404
+#define IW_FLOOD_DEAUTH_EVENT_FLAG					0x0405
+#define IW_FLOOD_EAP_REQ_EVENT_FLAG					0x0406
+// if add new flooding attack event flag, please upadte the IW_FLOOD_EVENT_FLAG_END
+#define	IW_FLOOD_EVENT_FLAG_END                   	0x0406
+#define	IW_FLOOD_EVENT_TYPE_NUM						(IW_FLOOD_EVENT_FLAG_END - IW_FLOOD_EVENT_FLAG_START + 1)
+// For flooding attack - end
+
+// End - WIRELESS EVENTS definition
+
+#ifdef CONFIG_STA_SUPPORT
+// definition for DLS, kathy
+#define	MAX_NUM_OF_INIT_DLS_ENTRY   1
+#define	MAX_NUM_OF_DLS_ENTRY        MAX_NUMBER_OF_DLS_ENTRY
+
+//Block ACK , rt2860, kathy
+#define MAX_TX_REORDERBUF		64
+#define MAX_RX_REORDERBUF		64
+#define DEFAULT_TX_TIMEOUT		30
+#define DEFAULT_RX_TIMEOUT		30
+#ifndef CONFIG_AP_SUPPORT
+#define MAX_BARECI_SESSION		8
+#endif
+
+#ifndef IW_ESSID_MAX_SIZE
+/* Maximum size of the ESSID and pAd->nickname strings */
+#define IW_ESSID_MAX_SIZE   		32
+#endif
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef MCAST_RATE_SPECIFIC
+#define MCAST_DISABLE	0
+#define MCAST_CCK		1
+#define MCAST_OFDM		2
+#define MCAST_HTMIX		3
+#endif // MCAST_RATE_SPECIFIC //
+
+// For AsicRadioOff/AsicRadioOn function
+#define DOT11POWERSAVE		0
+#define GUIRADIO_OFF		1
+#define RTMP_HALT		    2
+#define GUI_IDLE_POWER_SAVE		3
+// --
+
+
+// definition for WpaSupport flag
+#define WPA_SUPPLICANT_DISABLE				0
+#define WPA_SUPPLICANT_ENABLE				1
+#define	WPA_SUPPLICANT_ENABLE_WITH_WEB_UI	2
+
+// Endian byte swapping codes
+#define SWAP16(x) \
+    ((UINT16)( \
+    (((UINT16)(x) & (UINT16) 0x00ffU) << 8) | \
+    (((UINT16)(x) & (UINT16) 0xff00U) >> 8) ))
+
+#define SWAP32(x) \
+    ((UINT32)( \
+    (((UINT32)(x) & (UINT32) 0x000000ffUL) << 24) | \
+    (((UINT32)(x) & (UINT32) 0x0000ff00UL) <<  8) | \
+    (((UINT32)(x) & (UINT32) 0x00ff0000UL) >>  8) | \
+    (((UINT32)(x) & (UINT32) 0xff000000UL) >> 24) ))
+
+#define SWAP64(x) \
+    ((UINT64)( \
+    (UINT64)(((UINT64)(x) & (UINT64) 0x00000000000000ffULL) << 56) | \
+    (UINT64)(((UINT64)(x) & (UINT64) 0x000000000000ff00ULL) << 40) | \
+    (UINT64)(((UINT64)(x) & (UINT64) 0x0000000000ff0000ULL) << 24) | \
+    (UINT64)(((UINT64)(x) & (UINT64) 0x00000000ff000000ULL) <<  8) | \
+    (UINT64)(((UINT64)(x) & (UINT64) 0x000000ff00000000ULL) >>  8) | \
+    (UINT64)(((UINT64)(x) & (UINT64) 0x0000ff0000000000ULL) >> 24) | \
+    (UINT64)(((UINT64)(x) & (UINT64) 0x00ff000000000000ULL) >> 40) | \
+    (UINT64)(((UINT64)(x) & (UINT64) 0xff00000000000000ULL) >> 56) ))
+
+#ifdef RT_BIG_ENDIAN
+
+#define cpu2le64(x) SWAP64((x))
+#define le2cpu64(x) SWAP64((x))
+#define cpu2le32(x) SWAP32((x))
+#define le2cpu32(x) SWAP32((x))
+#define cpu2le16(x) SWAP16((x))
+#define le2cpu16(x) SWAP16((x))
+#define cpu2be64(x) ((UINT64)(x))
+#define be2cpu64(x) ((UINT64)(x))
+#define cpu2be32(x) ((UINT32)(x))
+#define be2cpu32(x) ((UINT32)(x))
+#define cpu2be16(x) ((UINT16)(x))
+#define be2cpu16(x) ((UINT16)(x))
+
+#else   // Little_Endian
+
+#define cpu2le64(x) ((UINT64)(x))
+#define le2cpu64(x) ((UINT64)(x))
+#define cpu2le32(x) ((UINT32)(x))
+#define le2cpu32(x) ((UINT32)(x))
+#define cpu2le16(x) ((UINT16)(x))
+#define le2cpu16(x) ((UINT16)(x))
+#define cpu2be64(x) SWAP64((x))
+#define be2cpu64(x) SWAP64((x))
+#define cpu2be32(x) SWAP32((x))
+#define be2cpu32(x) SWAP32((x))
+#define cpu2be16(x) SWAP16((x))
+#define be2cpu16(x) SWAP16((x))
+
+#endif  // RT_BIG_ENDIAN
+
+#endif  // __RTMP_DEF_H__
+
+
diff --git a/drivers/staging/rt3070/rtmp_type.h b/drivers/staging/rt3070/rtmp_type.h
new file mode 100644
index 0000000..4e4b168
--- /dev/null
+++ b/drivers/staging/rt3070/rtmp_type.h
@@ -0,0 +1,95 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+    rtmp_type.h
+
+    Abstract:
+
+    Revision History:
+    Who         When            What
+    --------    ----------      ----------------------------------------------
+    Name        Date            Modification logs
+    Paul Lin    1-2-2004
+*/
+#ifndef __RTMP_TYPE_H__
+#define __RTMP_TYPE_H__
+
+
+#define PACKED  __attribute__ ((packed))
+
+// Put platform dependent declaration here
+// For example, linux type definition
+typedef unsigned char		UINT8;
+typedef unsigned short		UINT16;
+typedef unsigned int		UINT32;
+typedef unsigned long long	UINT64;
+typedef int					INT32;
+typedef long long 			INT64;
+
+typedef unsigned char *			PUINT8;
+typedef unsigned short *		PUINT16;
+typedef unsigned int *			PUINT32;
+typedef unsigned long long *	PUINT64;
+typedef int	*					PINT32;
+typedef long long * 			PINT64;
+
+typedef signed char			CHAR;
+typedef signed short		SHORT;
+typedef signed int			INT;
+typedef signed long			LONG;
+typedef signed long long	LONGLONG;
+
+
+typedef unsigned char		UCHAR;
+typedef unsigned short		USHORT;
+typedef unsigned int		UINT;
+typedef unsigned long		ULONG;
+typedef unsigned long long	ULONGLONG;
+
+typedef unsigned char		BOOLEAN;
+typedef void				VOID;
+
+typedef VOID *				PVOID;
+typedef CHAR *				PCHAR;
+typedef UCHAR * 			PUCHAR;
+typedef USHORT *			PUSHORT;
+typedef LONG *				PLONG;
+typedef ULONG *				PULONG;
+typedef UINT *				PUINT;
+
+typedef unsigned int	NDIS_MEDIA_STATE;
+
+typedef union _LARGE_INTEGER {
+    struct {
+        UINT LowPart;
+        INT32 HighPart;
+    } u;
+    INT64 QuadPart;
+} LARGE_INTEGER;
+
+#endif  // __RTMP_TYPE_H__
+
diff --git a/drivers/staging/rt3070/spectrum.h b/drivers/staging/rt3070/spectrum.h
new file mode 100644
index 0000000..94cfa5b
--- /dev/null
+++ b/drivers/staging/rt3070/spectrum.h
@@ -0,0 +1,322 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+ */
+
+#ifndef __SPECTRUM_H__
+#define __SPECTRUM_H__
+
+#include "rtmp_type.h"
+#include "spectrum_def.h"
+
+typedef struct PACKED _TPC_REPORT_INFO
+{
+	UINT8 TxPwr;
+	UINT8 LinkMargin;
+} TPC_REPORT_INFO, *PTPC_REPORT_INFO;
+
+typedef struct PACKED _CH_SW_ANN_INFO
+{
+	UINT8 ChSwMode;
+	UINT8 Channel;
+	UINT8 ChSwCnt;
+} CH_SW_ANN_INFO, *PCH_SW_ANN_INFO;
+
+typedef union PACKED _MEASURE_REQ_MODE
+{
+#ifdef RT_BIG_ENDIAN
+	struct PACKED
+	{
+		UINT8 Rev1:4;
+		UINT8 Report:1;
+		UINT8 Request:1;
+		UINT8 Enable:1;
+		UINT8 Rev0:1;
+	} field;
+#else
+	struct PACKED
+	{
+		UINT8 Rev0:1;
+		UINT8 Enable:1;
+		UINT8 Request:1;
+		UINT8 Report:1;
+		UINT8 Rev1:4;
+	} field;
+#endif // RT_BIG_ENDIAN //
+	UINT8 word;
+} MEASURE_REQ_MODE, *PMEASURE_REQ_MODE;
+
+typedef struct PACKED _MEASURE_REQ
+{
+	UINT8 ChNum;
+	UINT64 MeasureStartTime;
+	UINT16 MeasureDuration;
+} MEASURE_REQ, *PMEASURE_REQ;
+
+typedef struct PACKED _MEASURE_REQ_INFO
+{
+	UINT8 Token;
+	MEASURE_REQ_MODE ReqMode;
+	UINT8 ReqType;
+	MEASURE_REQ MeasureReq;
+} MEASURE_REQ_INFO, *PMEASURE_REQ_INFO;
+
+typedef union PACKED _MEASURE_BASIC_REPORT_MAP
+{
+#ifdef RT_BIG_ENDIAN
+	struct PACKED
+	{
+		UINT8 Rev:3;
+		UINT8 Unmeasure:1;
+		UINT8 Radar:1;
+		UINT8 UnidentifiedSignal:1;
+		UINT8 OfdmPreamble:1;
+		UINT8 BSS:1;
+	} field;
+#else
+	struct PACKED
+	{
+		UINT8 BSS:1;
+		UINT8 OfdmPreamble:1;
+		UINT8 UnidentifiedSignal:1;
+		UINT8 Radar:1;
+		UINT8 Unmeasure:1;
+		UINT8 Rev:3;
+	} field;
+#endif // RT_BIG_ENDIAN //
+	UINT8 word;
+} MEASURE_BASIC_REPORT_MAP, *PMEASURE_BASIC_REPORT_MAP;
+
+typedef struct PACKED _MEASURE_BASIC_REPORT
+{
+	UINT8 ChNum;
+	UINT64 MeasureStartTime;
+	UINT16 MeasureDuration;
+	MEASURE_BASIC_REPORT_MAP Map;
+} MEASURE_BASIC_REPORT, *PMEASURE_BASIC_REPORT;
+
+typedef struct PACKED _MEASURE_CCA_REPORT
+{
+	UINT8 ChNum;
+	UINT64 MeasureStartTime;
+	UINT16 MeasureDuration;
+	UINT8 CCA_Busy_Fraction;
+} MEASURE_CCA_REPORT, *PMEASURE_CCA_REPORT;
+
+typedef struct PACKED _MEASURE_RPI_REPORT
+{
+	UINT8 ChNum;
+	UINT64 MeasureStartTime;
+	UINT16 MeasureDuration;
+	UINT8 RPI_Density[8];
+} MEASURE_RPI_REPORT, *PMEASURE_RPI_REPORT;
+
+typedef union PACKED _MEASURE_REPORT_MODE
+{
+	struct PACKED
+	{
+#ifdef RT_BIG_ENDIAN
+		UINT8 Rev:5;
+		UINT8 Refused:1;
+		UINT8 Incapable:1;
+		UINT8 Late:1;
+#else
+		UINT8 Late:1;
+		UINT8 Incapable:1;
+		UINT8 Refused:1;
+		UINT8 Rev:5;
+#endif // RT_BIG_ENDIAN //
+	} field;
+	UINT8 word;
+} MEASURE_REPORT_MODE, *PMEASURE_REPORT_MODE;
+
+typedef struct PACKED _MEASURE_REPORT_INFO
+{
+	UINT8 Token;
+	MEASURE_REPORT_MODE ReportMode;
+	UINT8 ReportType;
+	UINT8 Octect[0];
+} MEASURE_REPORT_INFO, *PMEASURE_REPORT_INFO;
+
+typedef struct PACKED _QUIET_INFO
+{
+	UINT8 QuietCnt;
+	UINT8 QuietPeriod;
+	UINT8 QuietDuration;
+	UINT8 QuietOffset;
+} QUIET_INFO, *PQUIET_INFO;
+
+/*
+	==========================================================================
+	Description:
+		Prepare Measurement request action frame and enqueue it into
+		management queue waiting for transmition.
+
+	Parametrs:
+		1. the destination mac address of the frame.
+
+	Return	: None.
+	==========================================================================
+ */
+VOID EnqueueMeasurementReq(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pDA,
+	IN UINT8 MeasureToken,
+	IN UINT8 MeasureReqMode,
+	IN UINT8 MeasureReqType,
+	IN UINT8 MeasureCh,
+	IN UINT16 MeasureDuration);
+
+/*
+	==========================================================================
+	Description:
+		Prepare Measurement report action frame and enqueue it into
+		management queue waiting for transmition.
+
+	Parametrs:
+		1. the destination mac address of the frame.
+
+	Return	: None.
+	==========================================================================
+ */
+VOID EnqueueMeasurementRep(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pDA,
+	IN UINT8 DialogToken,
+	IN UINT8 MeasureToken,
+	IN UINT8 MeasureReqMode,
+	IN UINT8 MeasureReqType,
+	IN UINT8 ReportInfoLen,
+	IN PUINT8 pReportInfo);
+
+/*
+	==========================================================================
+	Description:
+		Prepare TPC Request action frame and enqueue it into
+		management queue waiting for transmition.
+
+	Parametrs:
+		1. the destination mac address of the frame.
+
+	Return	: None.
+	==========================================================================
+ */
+VOID EnqueueTPCReq(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pDA,
+	IN UCHAR DialogToken);
+
+/*
+	==========================================================================
+	Description:
+		Prepare TPC Report action frame and enqueue it into
+		management queue waiting for transmition.
+
+	Parametrs:
+		1. the destination mac address of the frame.
+
+	Return	: None.
+	==========================================================================
+ */
+VOID EnqueueTPCRep(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pDA,
+	IN UINT8 DialogToken,
+	IN UINT8 TxPwr,
+	IN UINT8 LinkMargin);
+
+/*
+	==========================================================================
+	Description:
+		Prepare Channel Switch Announcement action frame and enqueue it into
+		management queue waiting for transmition.
+
+	Parametrs:
+		1. the destination mac address of the frame.
+		2. Channel switch announcement mode.
+		2. a New selected channel.
+
+	Return	: None.
+	==========================================================================
+ */
+VOID EnqueueChSwAnn(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pDA,
+	IN UINT8 ChSwMode,
+	IN UINT8 NewCh);
+
+/*
+	==========================================================================
+	Description:
+		Spectrun action frames Handler such as channel switch annoucement,
+		measurement report, measurement request actions frames.
+
+	Parametrs:
+		Elme - MLME message containing the received frame
+
+	Return	: None.
+	==========================================================================
+ */
+VOID PeerSpectrumAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem);
+
+/*
+	==========================================================================
+	Description:
+
+	Parametrs:
+
+	Return	: None.
+	==========================================================================
+ */
+INT Set_MeasureReq_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+INT Set_TpcReq_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+VOID MeasureReqTabInit(
+	IN PRTMP_ADAPTER pAd);
+
+VOID MeasureReqTabExit(
+	IN PRTMP_ADAPTER pAd);
+
+VOID TpcReqTabInit(
+	IN PRTMP_ADAPTER pAd);
+
+VOID TpcReqTabExit(
+	IN PRTMP_ADAPTER pAd);
+
+VOID NotifyChSwAnnToPeerAPs(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pRA,
+	IN PUCHAR pTA,
+	IN UINT8 ChSwMode,
+	IN UINT8 Channel);
+#endif // __SPECTRUM_H__ //
+
diff --git a/drivers/staging/rt3070/spectrum_def.h b/drivers/staging/rt3070/spectrum_def.h
new file mode 100644
index 0000000..4ca4817
--- /dev/null
+++ b/drivers/staging/rt3070/spectrum_def.h
@@ -0,0 +1,95 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+	spectrum_def.h
+
+    Abstract:
+    Handle association related requests either from WSTA or from local MLME
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+	Fonchi Wu    2008	  	   created for 802.11h
+ */
+
+#ifndef __SPECTRUM_DEF_H__
+#define __SPECTRUM_DEF_H__
+
+#define MAX_MEASURE_REQ_TAB_SIZE		3
+#define MAX_HASH_MEASURE_REQ_TAB_SIZE	MAX_MEASURE_REQ_TAB_SIZE
+
+#define MAX_TPC_REQ_TAB_SIZE			3
+#define MAX_HASH_TPC_REQ_TAB_SIZE		MAX_TPC_REQ_TAB_SIZE
+
+#define MIN_RCV_PWR				100		/* Negative value ((dBm) */
+
+#define RM_TPC_REQ				0
+#define RM_MEASURE_REQ			1
+
+#define RM_BASIC				0
+#define RM_CCA					1
+#define RM_RPI_HISTOGRAM		2
+
+#define TPC_REQ_AGE_OUT			500		/* ms */
+#define MQ_REQ_AGE_OUT			500		/* ms */
+
+#define TPC_DIALOGTOKEN_HASH_INDEX(_DialogToken)	((_DialogToken) % MAX_HASH_TPC_REQ_TAB_SIZE)
+#define MQ_DIALOGTOKEN_HASH_INDEX(_DialogToken)		((_DialogToken) % MAX_MEASURE_REQ_TAB_SIZE)
+
+typedef struct _MEASURE_REQ_ENTRY
+{
+	struct _MEASURE_REQ_ENTRY *pNext;
+	ULONG lastTime;
+	BOOLEAN	Valid;
+	UINT8 DialogToken;
+	UINT8 MeasureDialogToken[3];	// 0:basic measure, 1: CCA measure, 2: RPI_Histogram measure.
+} MEASURE_REQ_ENTRY, *PMEASURE_REQ_ENTRY;
+
+typedef struct _MEASURE_REQ_TAB
+{
+	UCHAR Size;
+	PMEASURE_REQ_ENTRY Hash[MAX_HASH_MEASURE_REQ_TAB_SIZE];
+	MEASURE_REQ_ENTRY Content[MAX_MEASURE_REQ_TAB_SIZE];
+} MEASURE_REQ_TAB, *PMEASURE_REQ_TAB;
+
+typedef struct _TPC_REQ_ENTRY
+{
+	struct _TPC_REQ_ENTRY *pNext;
+	ULONG lastTime;
+	BOOLEAN Valid;
+	UINT8 DialogToken;
+} TPC_REQ_ENTRY, *PTPC_REQ_ENTRY;
+
+typedef struct _TPC_REQ_TAB
+{
+	UCHAR Size;
+	PTPC_REQ_ENTRY Hash[MAX_HASH_TPC_REQ_TAB_SIZE];
+	TPC_REQ_ENTRY Content[MAX_TPC_REQ_TAB_SIZE];
+} TPC_REQ_TAB, *PTPC_REQ_TAB;
+
+#endif // __SPECTRUM_DEF_H__ //
+
diff --git a/drivers/staging/rt3070/sta/aironet.c b/drivers/staging/rt3070/sta/aironet.c
new file mode 100644
index 0000000..4af4a19
--- /dev/null
+++ b/drivers/staging/rt3070/sta/aironet.c
@@ -0,0 +1,1312 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	aironet.c
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	Paul Lin	04-06-15		Initial
+*/
+#include "../rt_config.h"
+
+/*
+	==========================================================================
+	Description:
+		association	state machine init,	including state	transition and timer init
+	Parameters:
+		S -	pointer	to the association state machine
+	==========================================================================
+ */
+VOID	AironetStateMachineInit(
+	IN	PRTMP_ADAPTER		pAd,
+	IN	STATE_MACHINE		*S,
+	OUT	STATE_MACHINE_FUNC	Trans[])
+{
+	StateMachineInit(S,	Trans, MAX_AIRONET_STATE, MAX_AIRONET_MSG, (STATE_MACHINE_FUNC)Drop, AIRONET_IDLE, AIRONET_MACHINE_BASE);
+	StateMachineSetAction(S, AIRONET_IDLE, MT2_AIRONET_MSG, (STATE_MACHINE_FUNC)AironetMsgAction);
+	StateMachineSetAction(S, AIRONET_IDLE, MT2_AIRONET_SCAN_REQ, (STATE_MACHINE_FUNC)AironetRequestAction);
+	StateMachineSetAction(S, AIRONET_SCANNING, MT2_AIRONET_SCAN_DONE, (STATE_MACHINE_FUNC)AironetReportAction);
+}
+
+/*
+	==========================================================================
+	Description:
+		This is	state machine function.
+		When receiving EAPOL packets which is  for 802.1x key management.
+		Use	both in	WPA, and WPAPSK	case.
+		In this	function, further dispatch to different	functions according	to the received	packet.	 3 categories are :
+		  1.  normal 4-way pairwisekey and 2-way groupkey handshake
+		  2.  MIC error	(Countermeasures attack)  report packet	from STA.
+		  3.  Request for pairwise/group key update	from STA
+	Return:
+	==========================================================================
+*/
+VOID	AironetMsgAction(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	MLME_QUEUE_ELEM	*Elem)
+{
+	USHORT							Length;
+	UCHAR							Index, i;
+	PUCHAR							pData;
+	PAIRONET_RM_REQUEST_FRAME		pRMReq;
+	PRM_REQUEST_ACTION				pReqElem;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("-----> AironetMsgAction\n"));
+
+	// 0. Get Aironet IAPP header first
+	pRMReq = (PAIRONET_RM_REQUEST_FRAME) &Elem->Msg[LENGTH_802_11];
+	pData  = (PUCHAR) &Elem->Msg[LENGTH_802_11];
+
+	// 1. Change endian format form network to little endian
+	Length = be2cpu16(pRMReq->IAPP.Length);
+
+	// 2.0 Sanity check, this should only happen when CCX 2.0 support is enabled
+	if (pAd->StaCfg.CCXEnable != TRUE)
+		return;
+
+	// 2.1 Radio measurement must be on
+	if (pAd->StaCfg.CCXControl.field.RMEnable != 1)
+		return;
+
+	// 2.2. Debug print all bit information
+	DBGPRINT(RT_DEBUG_TRACE, ("IAPP ID & Length %d\n", Length));
+	DBGPRINT(RT_DEBUG_TRACE, ("IAPP Type %x\n", pRMReq->IAPP.Type));
+	DBGPRINT(RT_DEBUG_TRACE, ("IAPP SubType %x\n", pRMReq->IAPP.SubType));
+	DBGPRINT(RT_DEBUG_TRACE, ("IAPP Dialog Token %x\n", pRMReq->IAPP.Token));
+	DBGPRINT(RT_DEBUG_TRACE, ("IAPP Activation Delay %x\n", pRMReq->Delay));
+	DBGPRINT(RT_DEBUG_TRACE, ("IAPP Measurement Offset %x\n", pRMReq->Offset));
+
+	// 3. Check IAPP frame type, it must be 0x32 for Cisco Aironet extension
+	if (pRMReq->IAPP.Type != AIRONET_IAPP_TYPE)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP type for Cisco Aironet extension\n"));
+		return;
+	}
+
+	// 4. Check IAPP frame subtype, it must be 0x01 for Cisco Aironet extension request.
+	//    Since we are acting as client only, we will disregards reply subtype.
+	if (pRMReq->IAPP.SubType != AIRONET_IAPP_SUBTYPE_REQUEST)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP subtype for Cisco Aironet extension\n"));
+		return;
+	}
+
+	// 5. Verify Destination MAC and Source MAC, both should be all zeros.
+	if (! MAC_ADDR_EQUAL(pRMReq->IAPP.DA, ZERO_MAC_ADDR))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP DA for Cisco Aironet extension, it's not Zero\n"));
+		return;
+	}
+
+	if (! MAC_ADDR_EQUAL(pRMReq->IAPP.SA, ZERO_MAC_ADDR))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP SA for Cisco Aironet extension, it's not Zero\n"));
+		return;
+	}
+
+	// 6. Reinit all report related fields
+	NdisZeroMemory(pAd->StaCfg.FrameReportBuf, 2048);
+	NdisZeroMemory(pAd->StaCfg.BssReportOffset, sizeof(USHORT) * MAX_LEN_OF_BSS_TABLE);
+	NdisZeroMemory(pAd->StaCfg.MeasurementRequest, sizeof(RM_REQUEST_ACTION) * 4);
+
+	// 7. Point to the start of first element report element
+	pAd->StaCfg.FrameReportLen   = LENGTH_802_11 + sizeof(AIRONET_IAPP_HEADER);
+	DBGPRINT(RT_DEBUG_TRACE, ("FR len = %d\n", pAd->StaCfg.FrameReportLen));
+	pAd->StaCfg.LastBssIndex     = 0xff;
+	pAd->StaCfg.RMReqCnt         = 0;
+	pAd->StaCfg.ParallelReq      = FALSE;
+	pAd->StaCfg.ParallelDuration = 0;
+	pAd->StaCfg.ParallelChannel  = 0;
+	pAd->StaCfg.IAPPToken        = pRMReq->IAPP.Token;
+	pAd->StaCfg.CurrentRMReqIdx  = 0;
+	pAd->StaCfg.CLBusyBytes      = 0;
+	// Reset the statistics
+	for (i = 0; i < 8; i++)
+		pAd->StaCfg.RPIDensity[i] = 0;
+
+	Index = 0;
+
+	// 8. Save dialog token for report
+	pAd->StaCfg.IAPPToken = pRMReq->IAPP.Token;
+
+	// Save Activation delay & measurement offset, Not really needed
+
+	// 9. Point to the first request element
+	pData += sizeof(AIRONET_RM_REQUEST_FRAME);
+	//    Length should exclude the CISCO Aironet SNAP header
+	Length -= (sizeof(AIRONET_RM_REQUEST_FRAME) - LENGTH_802_1_H);
+
+	// 10. Start Parsing the Measurement elements.
+	//    Be careful about multiple MR elements within one frames.
+	while (Length > 0)
+	{
+		pReqElem = (PRM_REQUEST_ACTION) pData;
+		switch (pReqElem->ReqElem.Eid)
+		{
+			case IE_MEASUREMENT_REQUEST:
+				// From the example, it seems we only need to support one request in one frame
+				// There is no multiple request in one frame.
+				// Besides, looks like we need to take care the measurement request only.
+				// The measurement request is always 4 bytes.
+
+				// Start parsing this type of request.
+				// 0. Eid is IE_MEASUREMENT_REQUEST
+				// 1. Length didn't include Eid and Length field, it always be 8.
+				// 2. Measurement Token, we nned to save it for the corresponding report.
+				// 3. Measurement Mode, Although there are definitions, but we din't see value other than
+				//    0 from test specs examples.
+				// 4. Measurement Type, this is what we need to do.
+				switch (pReqElem->ReqElem.Type)
+				{
+					case MSRN_TYPE_CHANNEL_LOAD_REQ:
+					case MSRN_TYPE_NOISE_HIST_REQ:
+					case MSRN_TYPE_BEACON_REQ:
+						// Check the Enable non-serving channel measurement control
+						if (pAd->StaCfg.CCXControl.field.DCRMEnable == 0)
+						{
+							// Check channel before enqueue the action
+							if (pReqElem->Measurement.Channel != pAd->CommonCfg.Channel)
+								break;
+						}
+						else
+						{
+							// If off channel measurement, check the TU duration limit
+							if (pReqElem->Measurement.Channel != pAd->CommonCfg.Channel)
+								if (pReqElem->Measurement.Duration > pAd->StaCfg.CCXControl.field.TuLimit)
+									break;
+						}
+
+						// Save requests and execute actions later
+						NdisMoveMemory(&pAd->StaCfg.MeasurementRequest[Index], pReqElem, sizeof(RM_REQUEST_ACTION));
+						Index += 1;
+						break;
+
+					case MSRN_TYPE_FRAME_REQ:
+						// Since it's option, we will support later
+						// FrameRequestAction(pAd, pData);
+						break;
+
+					default:
+						break;
+				}
+
+				// Point to next Measurement request
+				pData  += sizeof(RM_REQUEST_ACTION);
+				Length -= sizeof(RM_REQUEST_ACTION);
+				break;
+
+			// We accept request only, all others are dropped
+			case IE_MEASUREMENT_REPORT:
+			case IE_AP_TX_POWER:
+			case IE_MEASUREMENT_CAPABILITY:
+			default:
+				return;
+		}
+	}
+
+	// 11. Update some flags and index
+	pAd->StaCfg.RMReqCnt = Index;
+
+	if (Index)
+	{
+		MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_REQ, 0, NULL);
+		RT28XX_MLME_HANDLER(pAd);
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<----- AironetMsgAction\n"));
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+VOID	AironetRequestAction(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	MLME_QUEUE_ELEM	*Elem)
+{
+	PRM_REQUEST_ACTION	pReq;
+
+	// 1. Point to next request element
+	pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
+
+	// 2. Parse measurement type and call appropriate functions
+	if (pReq->ReqElem.Type == MSRN_TYPE_CHANNEL_LOAD_REQ)
+		// Channel Load measurement request
+		ChannelLoadRequestAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
+	else if (pReq->ReqElem.Type == MSRN_TYPE_NOISE_HIST_REQ)
+		// Noise Histogram measurement request
+		NoiseHistRequestAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
+	else if (pReq->ReqElem.Type == MSRN_TYPE_BEACON_REQ)
+		// Beacon measurement request
+		BeaconRequestAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
+	else
+		// Unknown. Do nothing and return, this should never happen
+		return;
+
+	// 3. Peek into the next request, if it's parallel, we will update the scan time to the largest one
+	if ((pAd->StaCfg.CurrentRMReqIdx + 1) < pAd->StaCfg.RMReqCnt)
+	{
+		pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx + 1];
+		// Check for parallel bit
+		if ((pReq->ReqElem.Mode & 0x01) && (pReq->Measurement.Channel == pAd->StaCfg.CCXScanChannel))
+		{
+			// Update parallel mode request information
+			pAd->StaCfg.ParallelReq = TRUE;
+			pAd->StaCfg.CCXScanTime = ((pReq->Measurement.Duration > pAd->StaCfg.CCXScanTime) ?
+			(pReq->Measurement.Duration) : (pAd->StaCfg.CCXScanTime));
+		}
+	}
+
+	// 4. Call RT28XX_MLME_HANDLER to execute the request mlme commands, Scan request is the only one used
+	RT28XX_MLME_HANDLER(pAd);
+
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Prepare channel load report action, special scan operation added
+		to support
+
+	Arguments:
+		pAd	Pointer	to our adapter
+		pData		Start from element ID
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+VOID	ChannelLoadRequestAction(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			Index)
+{
+	PRM_REQUEST_ACTION				pReq;
+	MLME_SCAN_REQ_STRUCT			ScanReq;
+	UCHAR							ZeroSsid[32];
+	NDIS_STATUS						NStatus;
+	PUCHAR							pOutBuffer = NULL;
+	PHEADER_802_11					pNullFrame;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadRequestAction ----->\n"));
+
+	pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[Index];
+	NdisZeroMemory(ZeroSsid, 32);
+
+	// Prepare for special scan request
+	// The scan definition is different with our Active, Passive scan definition.
+	// For CCX2, Active means send out probe request with broadcast BSSID.
+	// Passive means no probe request sent, only listen to the beacons.
+	// The channel scanned is fixed as specified, no need to scan all channels.
+	// The scan wait time is specified in the request too.
+	// Passive scan Mode
+
+	// Control state machine is not idle, reject the request
+	if ((pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) && (Index == 0))
+		return;
+
+	// Fill out stuff for scan request
+	ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_CHANNEL_LOAD);
+	MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
+	pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
+
+	// Reset some internal control flags to make sure this scan works.
+	BssTableInit(&pAd->StaCfg.CCXBssTab);
+	pAd->StaCfg.ScanCnt        = 0;
+	pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
+	pAd->StaCfg.CCXScanTime    = pReq->Measurement.Duration;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Duration %d, Channel %d!\n", pReq->Measurement.Duration, pReq->Measurement.Channel));
+
+	// If it's non serving channel scan, send out a null frame with PSM bit on.
+	if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
+	{
+		// Use MLME enqueue method
+		NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
+		if (NStatus	!= NDIS_STATUS_SUCCESS)
+			return;
+
+		pNullFrame = (PHEADER_802_11) pOutBuffer;;
+		// Make the power save Null frame with PSM bit on
+		MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
+		pNullFrame->Duration 	= 0;
+		pNullFrame->FC.Type 	= BTYPE_DATA;
+		pNullFrame->FC.PwrMgmt	= PWR_SAVE;
+
+		// Send using priority queue
+		MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
+		MlmeFreeMemory(pAd, pOutBuffer);
+		DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
+		RTMPusecDelay(5000);
+	}
+
+	pAd->StaCfg.CCXReqType     = MSRN_TYPE_CHANNEL_LOAD_REQ;
+	pAd->StaCfg.CLBusyBytes    = 0;
+	// Enable Rx with promiscuous reception
+	RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, 0x1010);
+
+	// Set channel load measurement flag
+	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
+
+	pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadRequestAction <-----\n"));
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Prepare noise histogram report action, special scan operation added
+		to support
+
+	Arguments:
+		pAd	Pointer	to our adapter
+		pData		Start from element ID
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+VOID	NoiseHistRequestAction(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			Index)
+{
+	PRM_REQUEST_ACTION				pReq;
+	MLME_SCAN_REQ_STRUCT			ScanReq;
+	UCHAR							ZeroSsid[32], i;
+	NDIS_STATUS						NStatus;
+	PUCHAR							pOutBuffer = NULL;
+	PHEADER_802_11					pNullFrame;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistRequestAction ----->\n"));
+
+	pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[Index];
+	NdisZeroMemory(ZeroSsid, 32);
+
+	// Prepare for special scan request
+	// The scan definition is different with our Active, Passive scan definition.
+	// For CCX2, Active means send out probe request with broadcast BSSID.
+	// Passive means no probe request sent, only listen to the beacons.
+	// The channel scanned is fixed as specified, no need to scan all channels.
+	// The scan wait time is specified in the request too.
+	// Passive scan Mode
+
+	// Control state machine is not idle, reject the request
+	if ((pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) && (Index == 0))
+		return;
+
+	// Fill out stuff for scan request
+	ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_NOISE);
+	MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
+	pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
+
+	// Reset some internal control flags to make sure this scan works.
+	BssTableInit(&pAd->StaCfg.CCXBssTab);
+	pAd->StaCfg.ScanCnt        = 0;
+	pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
+	pAd->StaCfg.CCXScanTime    = pReq->Measurement.Duration;
+	pAd->StaCfg.CCXReqType     = MSRN_TYPE_NOISE_HIST_REQ;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Duration %d, Channel %d!\n", pReq->Measurement.Duration, pReq->Measurement.Channel));
+
+	// If it's non serving channel scan, send out a null frame with PSM bit on.
+	if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
+	{
+		// Use MLME enqueue method
+		NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
+		if (NStatus	!= NDIS_STATUS_SUCCESS)
+			return;
+
+		pNullFrame = (PHEADER_802_11) pOutBuffer;
+		// Make the power save Null frame with PSM bit on
+		MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
+		pNullFrame->Duration 	= 0;
+		pNullFrame->FC.Type  	= BTYPE_DATA;
+		pNullFrame->FC.PwrMgmt	= PWR_SAVE;
+
+		// Send using priority queue
+		MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
+		MlmeFreeMemory(pAd, pOutBuffer);
+		DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
+		RTMPusecDelay(5000);
+	}
+
+	// Reset the statistics
+	for (i = 0; i < 8; i++)
+		pAd->StaCfg.RPIDensity[i] = 0;
+
+	// Enable Rx with promiscuous reception
+	RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, 0x1010);
+
+	// Set channel load measurement flag
+	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
+
+	pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistRequestAction <-----\n"));
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Prepare Beacon report action, special scan operation added
+		to support
+
+	Arguments:
+		pAd	Pointer	to our adapter
+		pData		Start from element ID
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+VOID	BeaconRequestAction(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			Index)
+{
+	PRM_REQUEST_ACTION				pReq;
+	NDIS_STATUS						NStatus;
+	PUCHAR							pOutBuffer = NULL;
+	PHEADER_802_11					pNullFrame;
+	MLME_SCAN_REQ_STRUCT			ScanReq;
+	UCHAR							ZeroSsid[32];
+
+	DBGPRINT(RT_DEBUG_TRACE, ("BeaconRequestAction ----->\n"));
+
+	pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[Index];
+	NdisZeroMemory(ZeroSsid, 32);
+
+	// Prepare for special scan request
+	// The scan definition is different with our Active, Passive scan definition.
+	// For CCX2, Active means send out probe request with broadcast BSSID.
+	// Passive means no probe request sent, only listen to the beacons.
+	// The channel scanned is fixed as specified, no need to scan all channels.
+	// The scan wait time is specified in the request too.
+	if (pReq->Measurement.ScanMode == MSRN_SCAN_MODE_PASSIVE)
+	{
+		// Passive scan Mode
+		DBGPRINT(RT_DEBUG_TRACE, ("Passive Scan Mode!\n"));
+
+		// Control state machine is not idle, reject the request
+		if ((pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) && (Index == 0))
+			return;
+
+		// Fill out stuff for scan request
+		ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_PASSIVE);
+		MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
+		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
+
+		// Reset some internal control flags to make sure this scan works.
+		BssTableInit(&pAd->StaCfg.CCXBssTab);
+		pAd->StaCfg.ScanCnt        = 0;
+		pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
+		pAd->StaCfg.CCXScanTime    = pReq->Measurement.Duration;
+		pAd->StaCfg.CCXReqType     = MSRN_TYPE_BEACON_REQ;
+		DBGPRINT(RT_DEBUG_TRACE, ("Duration %d!\n", pReq->Measurement.Duration));
+
+		// If it's non serving channel scan, send out a null frame with PSM bit on.
+		if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
+		{
+			// Use MLME enqueue method
+			NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
+			if (NStatus	!= NDIS_STATUS_SUCCESS)
+				return;
+
+			pNullFrame = (PHEADER_802_11) pOutBuffer;
+			// Make the power save Null frame with PSM bit on
+			MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
+			pNullFrame->Duration 	= 0;
+			pNullFrame->FC.Type     = BTYPE_DATA;
+			pNullFrame->FC.PwrMgmt  = PWR_SAVE;
+
+			// Send using priority queue
+			MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
+			MlmeFreeMemory(pAd, pOutBuffer);
+			DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
+			RTMPusecDelay(5000);
+		}
+
+		pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
+	}
+	else if (pReq->Measurement.ScanMode == MSRN_SCAN_MODE_ACTIVE)
+	{
+		// Active scan Mode
+		DBGPRINT(RT_DEBUG_TRACE, ("Active Scan Mode!\n"));
+
+		// Control state machine is not idle, reject the request
+		if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)
+			return;
+
+		// Fill out stuff for scan request
+		ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_ACTIVE);
+		MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
+		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
+
+		// Reset some internal control flags to make sure this scan works.
+		BssTableInit(&pAd->StaCfg.CCXBssTab);
+		pAd->StaCfg.ScanCnt        = 0;
+		pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
+		pAd->StaCfg.CCXScanTime    = pReq->Measurement.Duration;
+		pAd->StaCfg.CCXReqType     = MSRN_TYPE_BEACON_REQ;
+		DBGPRINT(RT_DEBUG_TRACE, ("Duration %d!\n", pReq->Measurement.Duration));
+
+		// If it's non serving channel scan, send out a null frame with PSM bit on.
+		if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
+		{
+			// Use MLME enqueue method
+			NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
+			if (NStatus	!= NDIS_STATUS_SUCCESS)
+				return;
+
+			pNullFrame = (PHEADER_802_11) pOutBuffer;
+			// Make the power save Null frame with PSM bit on
+			MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
+			pNullFrame->Duration 	= 0;
+			pNullFrame->FC.Type     = BTYPE_DATA;
+			pNullFrame->FC.PwrMgmt  = PWR_SAVE;
+
+			// Send using priority queue
+			MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
+			MlmeFreeMemory(pAd, pOutBuffer);
+			DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
+			RTMPusecDelay(5000);
+		}
+
+		pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
+	}
+	else if (pReq->Measurement.ScanMode == MSRN_SCAN_MODE_BEACON_TABLE)
+	{
+		// Beacon report Mode, report all the APS in current bss table
+		DBGPRINT(RT_DEBUG_TRACE, ("Beacon Report Mode!\n"));
+
+		// Copy current BSS table to CCX table, we can omit this step later on.
+		NdisMoveMemory(&pAd->StaCfg.CCXBssTab, &pAd->ScanTab, sizeof(BSS_TABLE));
+
+		// Create beacon report from Bss table
+		AironetCreateBeaconReportFromBssTable(pAd);
+
+		// Set state to scanning
+		pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
+
+		// Enqueue report request
+		// Cisco scan request is finished, prepare beacon report
+		MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
+	}
+	else
+	{
+		// Wrong scan Mode
+		DBGPRINT(RT_DEBUG_TRACE, ("Wrong Scan Mode!\n"));
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("BeaconRequestAction <-----\n"));
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+VOID	AironetReportAction(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	MLME_QUEUE_ELEM	*Elem)
+{
+	PRM_REQUEST_ACTION	pReq;
+	ULONG				Now32;
+
+    NdisGetSystemUpTime(&Now32);
+	pAd->StaCfg.LastBeaconRxTime = Now32;
+
+	pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
+
+	DBGPRINT(RT_DEBUG_TRACE, ("AironetReportAction ----->\n"));
+
+	// 1. Parse measurement type and call appropriate functions
+	if (pReq->ReqElem.Type == MSRN_TYPE_CHANNEL_LOAD_REQ)
+		// Channel Load measurement request
+		ChannelLoadReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
+	else if (pReq->ReqElem.Type == MSRN_TYPE_NOISE_HIST_REQ)
+		// Noise Histogram measurement request
+		NoiseHistReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
+	else if (pReq->ReqElem.Type == MSRN_TYPE_BEACON_REQ)
+		// Beacon measurement request
+		BeaconReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
+	else
+		// Unknown. Do nothing and return
+		;
+
+	// 2. Point to the correct index of action element, start from 0
+	pAd->StaCfg.CurrentRMReqIdx++;
+
+	// 3. Check for parallel actions
+	if (pAd->StaCfg.ParallelReq == TRUE)
+	{
+		pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
+
+		// Process next action right away
+		if (pReq->ReqElem.Type == MSRN_TYPE_CHANNEL_LOAD_REQ)
+			// Channel Load measurement request
+			ChannelLoadReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
+		else if (pReq->ReqElem.Type == MSRN_TYPE_NOISE_HIST_REQ)
+			// Noise Histogram measurement request
+			NoiseHistReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
+
+		pAd->StaCfg.ParallelReq = FALSE;
+		pAd->StaCfg.CurrentRMReqIdx++;
+	}
+
+	if (pAd->StaCfg.CurrentRMReqIdx >= pAd->StaCfg.RMReqCnt)
+	{
+		// 4. There is no more unprocessed measurement request, go for transmit this report
+		AironetFinalReportAction(pAd);
+		pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE;
+	}
+	else
+	{
+		pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
+
+		if (pReq->Measurement.Channel != pAd->CommonCfg.Channel)
+		{
+			RTMPusecDelay(100000);
+		}
+
+		// 5. There are more requests to be measure
+		MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_REQ, 0, NULL);
+		RT28XX_MLME_HANDLER(pAd);
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("AironetReportAction <-----\n"));
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+VOID	AironetFinalReportAction(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	PUCHAR					pDest;
+	PAIRONET_IAPP_HEADER	pIAPP;
+	PHEADER_802_11			pHeader;
+	UCHAR					AckRate = RATE_2;
+	USHORT					AckDuration = 0;
+	NDIS_STATUS				NStatus;
+	PUCHAR					pOutBuffer = NULL;
+	ULONG					FrameLen = 0;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("AironetFinalReportAction ----->\n"));
+
+	// 0. Set up the frame pointer, Frame was inited at the end of message action
+	pDest = &pAd->StaCfg.FrameReportBuf[LENGTH_802_11];
+
+	// 1. Update report IAPP fields
+	pIAPP = (PAIRONET_IAPP_HEADER) pDest;
+
+	// 2. Copy Cisco SNAP header
+	NdisMoveMemory(pIAPP->CiscoSnapHeader, SNAP_AIRONET, LENGTH_802_1_H);
+
+	// 3. network order for this 16bit length
+	pIAPP->Length  = cpu2be16(pAd->StaCfg.FrameReportLen - LENGTH_802_11 - LENGTH_802_1_H);
+
+	// 3.1 sanity check the report length, ignore it if there is nothing to report
+	if (be2cpu16(pIAPP->Length) <= 18)
+		return;
+
+	// 4. Type must be 0x32
+	pIAPP->Type    = AIRONET_IAPP_TYPE;
+
+	// 5. SubType for report must be 0x81
+	pIAPP->SubType = AIRONET_IAPP_SUBTYPE_REPORT;
+
+	// 6. DA is not used and must be zero, although the whole frame was cleared at the start of function
+	//    We will do it again here. We can use BSSID instead
+	COPY_MAC_ADDR(pIAPP->DA, pAd->CommonCfg.Bssid);
+
+	// 7. SA is the client reporting which must be our MAC
+	COPY_MAC_ADDR(pIAPP->SA, pAd->CurrentAddress);
+
+	// 8. Copy the saved dialog token
+	pIAPP->Token = pAd->StaCfg.IAPPToken;
+
+	// 9. Make the Report frame 802.11 header
+	//    Reuse function in wpa.c
+	pHeader = (PHEADER_802_11) pAd->StaCfg.FrameReportBuf;
+	pAd->Sequence ++;
+	WpaMacHeaderInit(pAd, pHeader, 0, pAd->CommonCfg.Bssid);
+
+	// ACK size	is 14 include CRC, and its rate	is based on real time information
+	AckRate     = pAd->CommonCfg.ExpectedACKRate[pAd->CommonCfg.MlmeRate];
+	AckDuration = RTMPCalcDuration(pAd, AckRate, 14);
+	pHeader->Duration = pAd->CommonCfg.Dsifs + AckDuration;
+
+	// Use MLME enqueue method
+	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
+	if (NStatus	!= NDIS_STATUS_SUCCESS)
+		return;
+
+	// 10. Prepare report frame with dynamic outbuffer. Just simply copy everything.
+	MakeOutgoingFrame(pOutBuffer,                       &FrameLen,
+	                  pAd->StaCfg.FrameReportLen, pAd->StaCfg.FrameReportBuf,
+		              END_OF_ARGS);
+
+	// 11. Send using priority queue
+	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+	MlmeFreeMemory(pAd, pOutBuffer);
+
+	pAd->StaCfg.CCXReqType = MSRN_TYPE_UNUSED;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("AironetFinalReportAction <-----\n"));
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+VOID	ChannelLoadReportAction(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			Index)
+{
+	PMEASUREMENT_REPORT_ELEMENT	pReport;
+	PCHANNEL_LOAD_REPORT		pLoad;
+	PUCHAR						pDest;
+	UCHAR						CCABusyFraction;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadReportAction ----->\n"));
+
+	// Disable Rx with promiscuous reception, make it back to normal
+	RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); // Staion not drop control frame will fail WiFi Certification.
+
+	// 0. Setup pointer for processing beacon & probe response
+	pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen];
+	pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest;
+
+	// 1. Fill Measurement report element field.
+	pReport->Eid    = IE_MEASUREMENT_REPORT;
+	// Fixed Length at 9, not include Eid and length fields
+	pReport->Length = 9;
+	pReport->Token  = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Token;
+	pReport->Mode   = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Mode;
+	pReport->Type   = MSRN_TYPE_CHANNEL_LOAD_REQ;
+
+	// 2. Fill channel report measurement data
+	pDest += sizeof(MEASUREMENT_REPORT_ELEMENT);
+	pLoad  = (PCHANNEL_LOAD_REPORT) pDest;
+	pLoad->Channel  = pAd->StaCfg.MeasurementRequest[Index].Measurement.Channel;
+	pLoad->Spare    = 0;
+	pLoad->Duration = pAd->StaCfg.MeasurementRequest[Index].Measurement.Duration;
+
+	// 3. Calculate the CCA Busy Fraction
+	//    (Bytes + ACK size) * 8 / Tx speed * 255 / 1000 / measurement duration, use 24 us Tx speed
+	//     =  (Bytes + ACK) / 12 / duration
+	//     9 is the good value for pAd->StaCfg.CLFactor
+	// CCABusyFraction = (UCHAR) (pAd->StaCfg.CLBusyBytes / 9 / pLoad->Duration);
+	CCABusyFraction = (UCHAR) (pAd->StaCfg.CLBusyBytes / pAd->StaCfg.CLFactor / pLoad->Duration);
+	if (CCABusyFraction < 10)
+			CCABusyFraction = (UCHAR) (pAd->StaCfg.CLBusyBytes / 3 / pLoad->Duration) + 1;
+
+	pLoad->CCABusy = CCABusyFraction;
+	DBGPRINT(RT_DEBUG_TRACE, ("CLBusyByte %ld, Duration %d, Result, %d\n", pAd->StaCfg.CLBusyBytes, pLoad->Duration, CCABusyFraction));
+
+	DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen %d\n", pAd->StaCfg.FrameReportLen));
+	pAd->StaCfg.FrameReportLen += (sizeof(MEASUREMENT_REPORT_ELEMENT) + sizeof(CHANNEL_LOAD_REPORT));
+	DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen %d\n", pAd->StaCfg.FrameReportLen));
+
+	// 4. Clear channel load measurement flag
+	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
+
+	// 5. reset to idle state
+	pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadReportAction <-----\n"));
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+VOID	NoiseHistReportAction(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			Index)
+{
+	PMEASUREMENT_REPORT_ELEMENT	pReport;
+	PNOISE_HIST_REPORT			pNoise;
+	PUCHAR						pDest;
+	UCHAR						i,NoiseCnt;
+	USHORT						TotalRPICnt, TotalRPISum;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistReportAction ----->\n"));
+
+	// 0. Disable Rx with promiscuous reception, make it back to normal
+	RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); // Staion not drop control frame will fail WiFi Certification.
+	// 1. Setup pointer for processing beacon & probe response
+	pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen];
+	pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest;
+
+	// 2. Fill Measurement report element field.
+	pReport->Eid    = IE_MEASUREMENT_REPORT;
+	// Fixed Length at 16, not include Eid and length fields
+	pReport->Length = 16;
+	pReport->Token  = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Token;
+	pReport->Mode   = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Mode;
+	pReport->Type   = MSRN_TYPE_NOISE_HIST_REQ;
+
+	// 3. Fill noise histogram report measurement data
+	pDest += sizeof(MEASUREMENT_REPORT_ELEMENT);
+	pNoise  = (PNOISE_HIST_REPORT) pDest;
+	pNoise->Channel  = pAd->StaCfg.MeasurementRequest[Index].Measurement.Channel;
+	pNoise->Spare    = 0;
+	pNoise->Duration = pAd->StaCfg.MeasurementRequest[Index].Measurement.Duration;
+	// 4. Fill Noise histogram, the total RPI counts should be 0.4 * TU
+	//    We estimate 4000 normal packets received durning 10 seconds test.
+	//    Adjust it if required.
+	// 3 is a good value for pAd->StaCfg.NHFactor
+	// TotalRPICnt = pNoise->Duration * 3 / 10;
+	TotalRPICnt = pNoise->Duration * pAd->StaCfg.NHFactor / 10;
+	TotalRPISum = 0;
+
+	for (i = 0; i < 8; i++)
+	{
+		TotalRPISum += pAd->StaCfg.RPIDensity[i];
+		DBGPRINT(RT_DEBUG_TRACE, ("RPI %d Conuts %d\n", i, pAd->StaCfg.RPIDensity[i]));
+	}
+
+	// Double check if the counter is larger than our expectation.
+	// We will replace it with the total number plus a fraction.
+	if (TotalRPISum > TotalRPICnt)
+		TotalRPICnt = TotalRPISum + pNoise->Duration / 20;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Total RPI Conuts %d\n", TotalRPICnt));
+
+	// 5. Initialize noise count for the total summation of 0xff
+	NoiseCnt = 0;
+	for (i = 1; i < 8; i++)
+	{
+		pNoise->Density[i] = (UCHAR) (pAd->StaCfg.RPIDensity[i] * 255 / TotalRPICnt);
+		if ((pNoise->Density[i] == 0) && (pAd->StaCfg.RPIDensity[i] != 0))
+			pNoise->Density[i]++;
+		NoiseCnt += pNoise->Density[i];
+		DBGPRINT(RT_DEBUG_TRACE, ("Reported RPI[%d]  = 0x%02x\n", i, pNoise->Density[i]));
+	}
+
+	// 6. RPI[0] represents the rest of counts
+	pNoise->Density[0] = 0xff - NoiseCnt;
+	DBGPRINT(RT_DEBUG_TRACE, ("Reported RPI[0]  = 0x%02x\n", pNoise->Density[0]));
+
+	pAd->StaCfg.FrameReportLen += (sizeof(MEASUREMENT_REPORT_ELEMENT) + sizeof(NOISE_HIST_REPORT));
+
+	// 7. Clear channel load measurement flag
+	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
+
+	// 8. reset to idle state
+	pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistReportAction <-----\n"));
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Prepare Beacon report action,
+
+	Arguments:
+		pAd	Pointer	to our adapter
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+VOID	BeaconReportAction(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			Index)
+{
+	DBGPRINT(RT_DEBUG_TRACE, ("BeaconReportAction ----->\n"));
+
+	// Looks like we don't have anything thing need to do here.
+	// All measurement report already finished in AddBeaconReport
+	// The length is in the FrameReportLen
+
+	// reset Beacon index for next beacon request
+	pAd->StaCfg.LastBssIndex = 0xff;
+
+	// reset to idle state
+	pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("BeaconReportAction <-----\n"));
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+		Index		Current BSSID in CCXBsstab entry index
+
+	Return Value:
+
+	Note:
+
+	========================================================================
+*/
+VOID	AironetAddBeaconReport(
+	IN	PRTMP_ADAPTER		pAd,
+	IN	ULONG				Index,
+	IN	PMLME_QUEUE_ELEM	pElem)
+{
+	PVOID						pMsg;
+	PUCHAR						pSrc, pDest;
+	UCHAR						ReqIdx;
+	ULONG						MsgLen;
+	USHORT						Length;
+	PFRAME_802_11				pFrame;
+	PMEASUREMENT_REPORT_ELEMENT	pReport;
+	PEID_STRUCT			        pEid;
+	PBEACON_REPORT				pBeaconReport;
+	PBSS_ENTRY					pBss;
+
+	// 0. Setup pointer for processing beacon & probe response
+	pMsg   = pElem->Msg;
+	MsgLen = pElem->MsgLen;
+	pFrame = (PFRAME_802_11) pMsg;
+	pSrc   = pFrame->Octet;				// Start from AP TSF
+	pBss   = (PBSS_ENTRY) &pAd->StaCfg.CCXBssTab.BssEntry[Index];
+	ReqIdx = pAd->StaCfg.CurrentRMReqIdx;
+
+	// 1 Check the Index, if we already create this entry, only update the average RSSI
+	if ((Index <= pAd->StaCfg.LastBssIndex) && (pAd->StaCfg.LastBssIndex != 0xff))
+	{
+		pDest  = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.BssReportOffset[Index]];
+		// Point to bss report information
+		pDest += sizeof(MEASUREMENT_REPORT_ELEMENT);
+		pBeaconReport = (PBEACON_REPORT) pDest;
+
+		// Update Rx power, in dBm
+		// Get the original RSSI readback from BBP
+		pBeaconReport->RxPower += pAd->BbpRssiToDbmDelta;
+		// Average the Rssi reading
+		pBeaconReport->RxPower  = (pBeaconReport->RxPower + pBss->Rssi) / 2;
+		// Get to dBm format
+		pBeaconReport->RxPower -= pAd->BbpRssiToDbmDelta;
+
+		DBGPRINT(RT_DEBUG_TRACE, ("Bssid %02x:%02x:%02x:%02x:%02x:%02x ",
+			pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2],
+			pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5]));
+		DBGPRINT(RT_DEBUG_TRACE, ("RxPower[%ld] Rssi %d, Avg Rssi %d\n", Index, (pBss->Rssi - pAd->BbpRssiToDbmDelta), pBeaconReport->RxPower - 256));
+		DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen = %d\n", pAd->StaCfg.BssReportOffset[Index]));
+
+		// Update other information here
+
+		// Done
+		return;
+	}
+
+	// 2. Update reported Index
+	pAd->StaCfg.LastBssIndex = Index;
+
+	// 3. Setup the buffer address for copying this BSSID into reporting frame
+	//    The offset should start after 802.11 header and report frame header.
+	pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen];
+
+	// 4. Save the start offset of each Bss in report frame
+	pAd->StaCfg.BssReportOffset[Index] = pAd->StaCfg.FrameReportLen;
+
+	// 5. Fill Measurement report fields
+	pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest;
+	pReport->Eid = IE_MEASUREMENT_REPORT;
+	pReport->Length = 0;
+	pReport->Token  = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Token;
+	pReport->Mode   = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Mode;
+	pReport->Type   = MSRN_TYPE_BEACON_REQ;
+	Length          = sizeof(MEASUREMENT_REPORT_ELEMENT);
+	pDest          += sizeof(MEASUREMENT_REPORT_ELEMENT);
+
+	// 6. Start thebeacon report format
+	pBeaconReport = (PBEACON_REPORT) pDest;
+	pDest        += sizeof(BEACON_REPORT);
+	Length       += sizeof(BEACON_REPORT);
+
+	// 7. Copy Channel number
+	pBeaconReport->Channel        = pBss->Channel;
+	pBeaconReport->Spare          = 0;
+	pBeaconReport->Duration       = pAd->StaCfg.MeasurementRequest[ReqIdx].Measurement.Duration;
+	pBeaconReport->PhyType        = ((pBss->SupRateLen+pBss->ExtRateLen > 4) ? PHY_ERP : PHY_DSS);
+	// 8. Rx power, in dBm
+	pBeaconReport->RxPower        = pBss->Rssi - pAd->BbpRssiToDbmDelta;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Bssid %02x:%02x:%02x:%02x:%02x:%02x ",
+		pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2],
+		pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5]));
+	DBGPRINT(RT_DEBUG_TRACE, ("RxPower[%ld], Rssi %d\n", Index, pBeaconReport->RxPower - 256));
+	DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen = %d\n", pAd->StaCfg.FrameReportLen));
+
+	pBeaconReport->BeaconInterval = pBss->BeaconPeriod;
+	COPY_MAC_ADDR(pBeaconReport->BSSID, pFrame->Hdr.Addr3);
+	NdisMoveMemory(pBeaconReport->ParentTSF, pSrc, 4);
+	NdisMoveMemory(pBeaconReport->TargetTSF, &pElem->TimeStamp.u.LowPart, 4);
+	NdisMoveMemory(&pBeaconReport->TargetTSF[4], &pElem->TimeStamp.u.HighPart, 4);
+
+	// 9. Skip the beacon frame and offset to start of capabilityinfo since we already processed capabilityinfo
+	pSrc += (TIMESTAMP_LEN + 2);
+	pBeaconReport->CapabilityInfo = *(USHORT *)pSrc;
+
+	// 10. Point to start of element ID
+	pSrc += 2;
+	pEid = (PEID_STRUCT) pSrc;
+
+	// 11. Start process all variable Eid oayload and add the appropriate to the frame report
+	while (((PUCHAR) pEid + pEid->Len + 1) < ((PUCHAR) pFrame + MsgLen))
+	{
+		// Only limited EID are required to report for CCX 2. It includes SSID, Supported rate,
+		// FH paramenter set, DS parameter set, CF parameter set, IBSS parameter set,
+		// TIM (report first 4 bytes only, radio measurement capability
+		switch (pEid->Eid)
+		{
+			case IE_SSID:
+			case IE_SUPP_RATES:
+			case IE_FH_PARM:
+			case IE_DS_PARM:
+			case IE_CF_PARM:
+			case IE_IBSS_PARM:
+				NdisMoveMemory(pDest, pEid, pEid->Len + 2);
+				pDest  += (pEid->Len + 2);
+				Length += (pEid->Len + 2);
+				break;
+
+			case IE_MEASUREMENT_CAPABILITY:
+				// Since this IE is duplicated with WPA security IE, we has to do sanity check before
+				// recognize it.
+				// 1. It also has fixed 6 bytes IE length.
+				if (pEid->Len != 6)
+					break;
+				// 2. Check the Cisco Aironet OUI
+				if (NdisEqualMemory(CISCO_OUI, (pSrc + 2), 3))
+				{
+					// Matched, this is what we want
+					NdisMoveMemory(pDest, pEid, pEid->Len + 2);
+					pDest  += (pEid->Len + 2);
+					Length += (pEid->Len + 2);
+				}
+				break;
+
+			case IE_TIM:
+				if (pEid->Len > 4)
+				{
+					// May truncate and report the first 4 bytes only, with the eid & len, total should be 6
+					NdisMoveMemory(pDest, pEid, 6);
+					pDest  += 6;
+					Length += 6;
+				}
+				else
+				{
+					NdisMoveMemory(pDest, pEid, pEid->Len + 2);
+					pDest  += (pEid->Len + 2);
+					Length += (pEid->Len + 2);
+				}
+				break;
+
+			default:
+				break;
+		}
+		// 12. Move to next element ID
+		pSrc += (2 + pEid->Len);
+		pEid = (PEID_STRUCT) pSrc;
+	}
+
+	// 13. Update the length in the header, not include EID and length
+	pReport->Length = Length - 4;
+
+	// 14. Update the frame report buffer data length
+	pAd->StaCfg.FrameReportLen += Length;
+	DBGPRINT(RT_DEBUG_TRACE, ("FR len = %d\n", pAd->StaCfg.FrameReportLen));
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+		Index		Current BSSID in CCXBsstab entry index
+
+	Return Value:
+
+	Note:
+
+	========================================================================
+*/
+VOID	AironetCreateBeaconReportFromBssTable(
+	IN	PRTMP_ADAPTER		pAd)
+{
+	PMEASUREMENT_REPORT_ELEMENT	pReport;
+	PBEACON_REPORT				pBeaconReport;
+	UCHAR						Index, ReqIdx;
+	USHORT						Length;
+	PUCHAR						pDest;
+	PBSS_ENTRY					pBss;
+
+	// 0. setup base pointer
+	ReqIdx = pAd->StaCfg.CurrentRMReqIdx;
+
+	for (Index = 0; Index < pAd->StaCfg.CCXBssTab.BssNr; Index++)
+	{
+		// 1. Setup the buffer address for copying this BSSID into reporting frame
+		//    The offset should start after 802.11 header and report frame header.
+		pDest  = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen];
+		pBss   = (PBSS_ENTRY) &pAd->StaCfg.CCXBssTab.BssEntry[Index];
+		Length = 0;
+
+		// 2. Fill Measurement report fields
+		pReport         = (PMEASUREMENT_REPORT_ELEMENT) pDest;
+		pReport->Eid    = IE_MEASUREMENT_REPORT;
+		pReport->Length = 0;
+		pReport->Token  = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Token;
+		pReport->Mode   = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Mode;
+		pReport->Type   = MSRN_TYPE_BEACON_REQ;
+		Length          = sizeof(MEASUREMENT_REPORT_ELEMENT);
+		pDest          += sizeof(MEASUREMENT_REPORT_ELEMENT);
+
+		// 3. Start the beacon report format
+		pBeaconReport = (PBEACON_REPORT) pDest;
+		pDest        += sizeof(BEACON_REPORT);
+		Length       += sizeof(BEACON_REPORT);
+
+		// 4. Copy Channel number
+		pBeaconReport->Channel        = pBss->Channel;
+		pBeaconReport->Spare          = 0;
+		pBeaconReport->Duration       = pAd->StaCfg.MeasurementRequest[ReqIdx].Measurement.Duration;
+		pBeaconReport->PhyType        = ((pBss->SupRateLen+pBss->ExtRateLen > 4) ? PHY_ERP : PHY_DSS);
+		pBeaconReport->RxPower        = pBss->Rssi - pAd->BbpRssiToDbmDelta;
+		pBeaconReport->BeaconInterval = pBss->BeaconPeriod;
+		pBeaconReport->CapabilityInfo = pBss->CapabilityInfo;
+		COPY_MAC_ADDR(pBeaconReport->BSSID, pBss->Bssid);
+		NdisMoveMemory(pBeaconReport->ParentTSF, pBss->PTSF, 4);
+		NdisMoveMemory(pBeaconReport->TargetTSF, pBss->TTSF, 8);
+
+		// 5. Create SSID
+		*pDest++ = 0x00;
+		*pDest++ = pBss->SsidLen;
+		NdisMoveMemory(pDest, pBss->Ssid, pBss->SsidLen);
+		pDest  += pBss->SsidLen;
+		Length += (2 + pBss->SsidLen);
+
+		// 6. Create SupportRates
+		*pDest++ = 0x01;
+		*pDest++ = pBss->SupRateLen;
+		NdisMoveMemory(pDest, pBss->SupRate, pBss->SupRateLen);
+		pDest  += pBss->SupRateLen;
+		Length += (2 + pBss->SupRateLen);
+
+		// 7. DS Parameter
+		*pDest++ = 0x03;
+		*pDest++ = 1;
+		*pDest++ = pBss->Channel;
+		Length  += 3;
+
+		// 8. IBSS parameter if presents
+		if (pBss->BssType == BSS_ADHOC)
+		{
+			*pDest++ = 0x06;
+			*pDest++ = 2;
+			*(PUSHORT) pDest = pBss->AtimWin;
+			pDest   += 2;
+			Length  += 4;
+		}
+
+		// 9. Update length field, not include EID and length
+		pReport->Length = Length - 4;
+
+		// 10. Update total frame size
+		pAd->StaCfg.FrameReportLen += Length;
+	}
+}
diff --git a/drivers/staging/rt3070/sta/assoc.c b/drivers/staging/rt3070/sta/assoc.c
new file mode 100644
index 0000000..5c33a89
--- /dev/null
+++ b/drivers/staging/rt3070/sta/assoc.c
@@ -0,0 +1,2060 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	assoc.c
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	John		2004-9-3		porting from RT2500
+*/
+#include "../rt_config.h"
+
+UCHAR	CipherWpaTemplate[] = {
+		0xdd, 					// WPA IE
+		0x16,					// Length
+		0x00, 0x50, 0xf2, 0x01,	// oui
+		0x01, 0x00,				// Version
+		0x00, 0x50, 0xf2, 0x02,	// Multicast
+		0x01, 0x00,				// Number of unicast
+		0x00, 0x50, 0xf2, 0x02,	// unicast
+		0x01, 0x00,				// number of authentication method
+		0x00, 0x50, 0xf2, 0x01	// authentication
+		};
+
+UCHAR	CipherWpa2Template[] = {
+		0x30,					// RSN IE
+		0x14,					// Length
+		0x01, 0x00,				// Version
+		0x00, 0x0f, 0xac, 0x02,	// group cipher, TKIP
+		0x01, 0x00,				// number of pairwise
+		0x00, 0x0f, 0xac, 0x02,	// unicast
+		0x01, 0x00,				// number of authentication method
+		0x00, 0x0f, 0xac, 0x02,	// authentication
+		0x00, 0x00,				// RSN capability
+		};
+
+UCHAR	Ccx2IeInfo[] = { 0x00, 0x40, 0x96, 0x03, 0x02};
+
+/*
+	==========================================================================
+	Description:
+		association state machine init, including state transition and timer init
+	Parameters:
+		S - pointer to the association state machine
+
+	IRQL = PASSIVE_LEVEL
+
+	==========================================================================
+ */
+VOID AssocStateMachineInit(
+	IN	PRTMP_ADAPTER	pAd,
+	IN  STATE_MACHINE *S,
+	OUT STATE_MACHINE_FUNC Trans[])
+{
+	StateMachineInit(S, Trans, MAX_ASSOC_STATE, MAX_ASSOC_MSG, (STATE_MACHINE_FUNC)Drop, ASSOC_IDLE, ASSOC_MACHINE_BASE);
+
+	// first column
+	StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)MlmeAssocReqAction);
+	StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)MlmeReassocReqAction);
+	StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)MlmeDisassocReqAction);
+	StateMachineSetAction(S, ASSOC_IDLE, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
+
+	// second column
+	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
+	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
+	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
+	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
+	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_ASSOC_RSP, (STATE_MACHINE_FUNC)PeerAssocRspAction);
+	//
+	// Patch 3Com AP MOde:3CRWE454G72
+	// We send Assoc request frame to this AP, it always send Reassoc Rsp not Associate Rsp.
+	//
+	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_REASSOC_RSP, (STATE_MACHINE_FUNC)PeerAssocRspAction);
+	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_ASSOC_TIMEOUT, (STATE_MACHINE_FUNC)AssocTimeoutAction);
+
+	// third column
+	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
+	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
+	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
+	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
+	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_REASSOC_RSP, (STATE_MACHINE_FUNC)PeerReassocRspAction);
+	//
+	// Patch, AP doesn't send Reassociate Rsp frame to Station.
+	//
+	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_ASSOC_RSP, (STATE_MACHINE_FUNC)PeerReassocRspAction);
+	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_REASSOC_TIMEOUT, (STATE_MACHINE_FUNC)ReassocTimeoutAction);
+
+	// fourth column
+	StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
+	StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
+	StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
+	StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
+	StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_DISASSOC_TIMEOUT, (STATE_MACHINE_FUNC)DisassocTimeoutAction);
+
+	// initialize the timer
+	RTMPInitTimer(pAd, &pAd->MlmeAux.AssocTimer, GET_TIMER_FUNCTION(AssocTimeout), pAd, FALSE);
+	RTMPInitTimer(pAd, &pAd->MlmeAux.ReassocTimer, GET_TIMER_FUNCTION(ReassocTimeout), pAd, FALSE);
+	RTMPInitTimer(pAd, &pAd->MlmeAux.DisassocTimer, GET_TIMER_FUNCTION(DisassocTimeout), pAd, FALSE);
+}
+
+/*
+	==========================================================================
+	Description:
+		Association timeout procedure. After association timeout, this function
+		will be called and it will put a message into the MLME queue
+	Parameters:
+		Standard timer parameters
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID AssocTimeout(IN PVOID SystemSpecific1,
+				 IN PVOID FunctionContext,
+				 IN PVOID SystemSpecific2,
+				 IN PVOID SystemSpecific3)
+{
+	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+	// Do nothing if the driver is starting halt state.
+	// This might happen when timer already been fired before cancel timer with mlmehalt
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+		return;
+
+	MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_ASSOC_TIMEOUT, 0, NULL);
+	RT28XX_MLME_HANDLER(pAd);
+}
+
+/*
+	==========================================================================
+	Description:
+		Reassociation timeout procedure. After reassociation timeout, this
+		function will be called and put a message into the MLME queue
+	Parameters:
+		Standard timer parameters
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID ReassocTimeout(IN PVOID SystemSpecific1,
+					IN PVOID FunctionContext,
+					IN PVOID SystemSpecific2,
+					IN PVOID SystemSpecific3)
+{
+	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+	// Do nothing if the driver is starting halt state.
+	// This might happen when timer already been fired before cancel timer with mlmehalt
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+		return;
+
+	MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_REASSOC_TIMEOUT, 0, NULL);
+	RT28XX_MLME_HANDLER(pAd);
+}
+
+/*
+	==========================================================================
+	Description:
+		Disassociation timeout procedure. After disassociation timeout, this
+		function will be called and put a message into the MLME queue
+	Parameters:
+		Standard timer parameters
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID DisassocTimeout(IN PVOID SystemSpecific1,
+					IN PVOID FunctionContext,
+					IN PVOID SystemSpecific2,
+					IN PVOID SystemSpecific3)
+{
+	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+	// Do nothing if the driver is starting halt state.
+	// This might happen when timer already been fired before cancel timer with mlmehalt
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+		return;
+
+	MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_DISASSOC_TIMEOUT, 0, NULL);
+	RT28XX_MLME_HANDLER(pAd);
+}
+
+/*
+	==========================================================================
+	Description:
+		mlme assoc req handling procedure
+	Parameters:
+		Adapter - Adapter pointer
+		Elem - MLME Queue Element
+	Pre:
+		the station has been authenticated and the following information is stored in the config
+			-# SSID
+			-# supported rates and their length
+			-# listen interval (Adapter->StaCfg.default_listen_count)
+			-# Transmit power  (Adapter->StaCfg.tx_power)
+	Post  :
+		-# An association request frame is generated and sent to the air
+		-# Association timer starts
+		-# Association state -> ASSOC_WAIT_RSP
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID MlmeAssocReqAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	UCHAR			ApAddr[6];
+	HEADER_802_11	AssocHdr;
+	UCHAR			Ccx2Len = 5;
+	UCHAR			WmeIe[9] = {IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
+	USHORT			ListenIntv;
+	ULONG			Timeout;
+	USHORT			CapabilityInfo;
+	BOOLEAN			TimerCancelled;
+	PUCHAR			pOutBuffer = NULL;
+	NDIS_STATUS		NStatus;
+	ULONG			FrameLen = 0;
+	ULONG			tmp;
+	USHORT			VarIesOffset;
+	UCHAR			CkipFlag;
+	UCHAR			CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH];
+	UCHAR			AironetCkipIe = IE_AIRONET_CKIP;
+	UCHAR			AironetCkipLen = CKIP_NEGOTIATION_LENGTH;
+	UCHAR			AironetIPAddressIE = IE_AIRONET_IPADDRESS;
+	UCHAR			AironetIPAddressLen = AIRONET_IPADDRESS_LENGTH;
+	UCHAR			AironetIPAddressBuffer[AIRONET_IPADDRESS_LENGTH] = {0x00, 0x40, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
+	USHORT			Status;
+
+	// Block all authentication request durning WPA block period
+	if (pAd->StaCfg.bBlockAssoc == TRUE)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Block Assoc request durning WPA block period!\n"));
+		pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+		Status = MLME_STATE_MACHINE_REJECT;
+		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
+	}
+	// check sanity first
+	else if (MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, &Timeout, &ListenIntv))
+	{
+		RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &TimerCancelled);
+		COPY_MAC_ADDR(pAd->MlmeAux.Bssid, ApAddr);
+
+		// Get an unused nonpaged memory
+		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+		if (NStatus != NDIS_STATUS_SUCCESS)
+		{
+			DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeAssocReqAction() allocate memory failed \n"));
+			pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+			Status = MLME_FAIL_NO_RESOURCE;
+			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
+			return;
+		}
+
+		// Add by James 03/06/27
+		pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
+		// Association don't need to report MAC address
+		pAd->StaCfg.AssocInfo.AvailableRequestFixedIEs =
+			NDIS_802_11_AI_REQFI_CAPABILITIES | NDIS_802_11_AI_REQFI_LISTENINTERVAL;
+		pAd->StaCfg.AssocInfo.RequestFixedIEs.Capabilities = CapabilityInfo;
+		pAd->StaCfg.AssocInfo.RequestFixedIEs.ListenInterval = ListenIntv;
+		// Only reassociate need this
+		//COPY_MAC_ADDR(pAd->StaCfg.AssocInfo.RequestFixedIEs.CurrentAPAddress, ApAddr);
+		pAd->StaCfg.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
+
+        NdisZeroMemory(pAd->StaCfg.ReqVarIEs, MAX_VIE_LEN);
+		// First add SSID
+		VarIesOffset = 0;
+		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &SsidIe, 1);
+		VarIesOffset += 1;
+		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &pAd->MlmeAux.SsidLen, 1);
+		VarIesOffset += 1;
+		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
+		VarIesOffset += pAd->MlmeAux.SsidLen;
+
+		// Second add Supported rates
+		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &SupRateIe, 1);
+		VarIesOffset += 1;
+		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &pAd->MlmeAux.SupRateLen, 1);
+		VarIesOffset += 1;
+		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, pAd->MlmeAux.SupRate, pAd->MlmeAux.SupRateLen);
+		VarIesOffset += pAd->MlmeAux.SupRateLen;
+		// End Add by James
+
+        if ((pAd->CommonCfg.Channel > 14) &&
+            (pAd->CommonCfg.bIEEE80211H == TRUE))
+            CapabilityInfo |= 0x0100;
+
+		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send ASSOC request...\n"));
+		MgtMacHeaderInit(pAd, &AssocHdr, SUBTYPE_ASSOC_REQ, 0, ApAddr, ApAddr);
+
+		// Build basic frame first
+		MakeOutgoingFrame(pOutBuffer,				&FrameLen,
+						  sizeof(HEADER_802_11),	&AssocHdr,
+						  2,						&CapabilityInfo,
+						  2,						&ListenIntv,
+						  1,						&SsidIe,
+						  1,						&pAd->MlmeAux.SsidLen,
+						  pAd->MlmeAux.SsidLen, 	pAd->MlmeAux.Ssid,
+						  1,						&SupRateIe,
+						  1,						&pAd->MlmeAux.SupRateLen,
+						  pAd->MlmeAux.SupRateLen,  pAd->MlmeAux.SupRate,
+						  END_OF_ARGS);
+
+		if (pAd->MlmeAux.ExtRateLen != 0)
+		{
+			MakeOutgoingFrame(pOutBuffer + FrameLen,    &tmp,
+							  1,                        &ExtRateIe,
+							  1,                        &pAd->MlmeAux.ExtRateLen,
+							  pAd->MlmeAux.ExtRateLen,  pAd->MlmeAux.ExtRate,
+							  END_OF_ARGS);
+			FrameLen += tmp;
+		}
+
+#ifdef DOT11_N_SUPPORT
+		// HT
+		if ((pAd->MlmeAux.HtCapabilityLen > 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+		{
+			ULONG TmpLen;
+			UCHAR HtLen;
+			UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
+			if (pAd->StaActive.SupportedPhyInfo.bPreNHt == TRUE)
+			{
+				HtLen = SIZE_HT_CAP_IE + 4;
+				MakeOutgoingFrame(pOutBuffer + FrameLen,            &TmpLen,
+							  1,                                &WpaIe,
+							  1,                                &HtLen,
+							  4,                                &BROADCOM[0],
+							 pAd->MlmeAux.HtCapabilityLen,          &pAd->MlmeAux.HtCapability,
+							  END_OF_ARGS);
+			}
+			else
+			{
+#ifdef RT_BIG_ENDIAN
+		        HT_CAPABILITY_IE HtCapabilityTmp;
+#endif
+
+#ifndef RT_BIG_ENDIAN
+				MakeOutgoingFrame(pOutBuffer + FrameLen,            &TmpLen,
+							  1,                                &HtCapIe,
+							  1,                                &pAd->MlmeAux.HtCapabilityLen,
+							 pAd->MlmeAux.HtCapabilityLen,          &pAd->MlmeAux.HtCapability,
+							  END_OF_ARGS);
+#else
+                NdisZeroMemory(&HtCapabilityTmp, sizeof(HT_CAPABILITY_IE));
+                NdisMoveMemory(&HtCapabilityTmp, &pAd->MlmeAux.HtCapability, pAd->MlmeAux.HtCapabilityLen);
+        		*(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
+        		*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
+
+        		MakeOutgoingFrame(pOutBuffer + FrameLen,         &TmpLen,
+        							1,                           &HtCapIe,
+        							1,                           &pAd->MlmeAux.HtCapabilityLen,
+        							pAd->MlmeAux.HtCapabilityLen,&HtCapabilityTmp,
+        							END_OF_ARGS);
+#endif
+			}
+			FrameLen += TmpLen;
+		}
+#endif // DOT11_N_SUPPORT //
+
+		// add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION
+		// Case I: (Aggregation + Piggy-Back)
+		// 1. user enable aggregation, AND
+		// 2. Mac support piggy-back
+		// 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON
+		// Case II: (Aggregation)
+		// 1. user enable aggregation, AND
+		// 2. AP annouces it's AGGREGATION-capable in BEACON
+		if (pAd->CommonCfg.bAggregationCapable)
+		{
+			if ((pAd->CommonCfg.bPiggyBackCapable) && ((pAd->MlmeAux.APRalinkIe & 0x00000003) == 3))
+			{
+				ULONG TmpLen;
+				UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x03, 0x00, 0x00, 0x00};
+				MakeOutgoingFrame(pOutBuffer+FrameLen,           &TmpLen,
+								  9,                             RalinkIe,
+								  END_OF_ARGS);
+				FrameLen += TmpLen;
+			}
+			else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
+			{
+				ULONG TmpLen;
+				UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x01, 0x00, 0x00, 0x00};
+				MakeOutgoingFrame(pOutBuffer+FrameLen,           &TmpLen,
+								  9,                             RalinkIe,
+								  END_OF_ARGS);
+				FrameLen += TmpLen;
+			}
+		}
+		else
+		{
+			ULONG TmpLen;
+			UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x06, 0x00, 0x00, 0x00};
+			MakeOutgoingFrame(pOutBuffer+FrameLen,		 &TmpLen,
+							  9,						 RalinkIe,
+							  END_OF_ARGS);
+			FrameLen += TmpLen;
+		}
+
+		if (pAd->MlmeAux.APEdcaParm.bValid)
+		{
+			if (pAd->CommonCfg.bAPSDCapable && pAd->MlmeAux.APEdcaParm.bAPSDCapable)
+			{
+				QBSS_STA_INFO_PARM QosInfo;
+
+				NdisZeroMemory(&QosInfo, sizeof(QBSS_STA_INFO_PARM));
+				QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE;
+				QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK;
+				QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI;
+				QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO;
+				QosInfo.MaxSPLength = pAd->CommonCfg.MaxSPLength;
+				WmeIe[8] |= *(PUCHAR)&QosInfo;
+			}
+			else
+			{
+                // The Parameter Set Count is set to ¡§0¡¨ in the association request frames
+                // WmeIe[8] |= (pAd->MlmeAux.APEdcaParm.EdcaUpdateCount & 0x0f);
+			}
+
+			MakeOutgoingFrame(pOutBuffer + FrameLen,    &tmp,
+							  9,                        &WmeIe[0],
+							  END_OF_ARGS);
+			FrameLen += tmp;
+		}
+
+		//
+		// Let WPA(#221) Element ID on the end of this association frame.
+		// Otherwise some AP will fail on parsing Element ID and set status fail on Assoc Rsp.
+		// For example: Put Vendor Specific IE on the front of WPA IE.
+		// This happens on AP (Model No:Linksys WRK54G)
+		//
+		if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+            (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
+            (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
+            (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
+			)
+            )
+		{
+			UCHAR RSNIe = IE_WPA;
+
+			if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
+                (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
+			{
+				RSNIe = IE_WPA2;
+			}
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+#ifdef SIOCSIWGENIE
+			if (pAd->StaCfg.WpaSupplicantUP != 1)
+#endif // SIOCSIWGENIE //
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+            	RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
+
+            // Check for WPA PMK cache list
+			if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
+			{
+			    INT     idx;
+                BOOLEAN FoundPMK = FALSE;
+				// Search chched PMKID, append it if existed
+				for (idx = 0; idx < PMKID_NO; idx++)
+				{
+					if (NdisEqualMemory(ApAddr, &pAd->StaCfg.SavedPMK[idx].BSSID, 6))
+					{
+						FoundPMK = TRUE;
+						break;
+					}
+				}
+
+				if (FoundPMK)
+				{
+					// Set PMK number
+					*(PUSHORT) &pAd->StaCfg.RSN_IE[pAd->StaCfg.RSNIE_Len] = 1;
+					NdisMoveMemory(&pAd->StaCfg.RSN_IE[pAd->StaCfg.RSNIE_Len + 2], &pAd->StaCfg.SavedPMK[idx].PMKID, 16);
+                    pAd->StaCfg.RSNIE_Len += 18;
+				}
+			}
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+#ifdef SIOCSIWGENIE
+			if (pAd->StaCfg.WpaSupplicantUP == 1)
+			{
+				MakeOutgoingFrame(pOutBuffer + FrameLen,    		&tmp,
+		                        	pAd->StaCfg.RSNIE_Len,			pAd->StaCfg.RSN_IE,
+		                        	END_OF_ARGS);
+			}
+			else
+#endif
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+			{
+				MakeOutgoingFrame(pOutBuffer + FrameLen,    		&tmp,
+				              		1,                              &RSNIe,
+		                        	1,                              &pAd->StaCfg.RSNIE_Len,
+		                        	pAd->StaCfg.RSNIE_Len,			pAd->StaCfg.RSN_IE,
+		                        	END_OF_ARGS);
+			}
+
+			FrameLen += tmp;
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+#ifdef SIOCSIWGENIE
+			if (pAd->StaCfg.WpaSupplicantUP != 1)
+#endif
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+			{
+	            // Append Variable IE
+	            NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &RSNIe, 1);
+	            VarIesOffset += 1;
+	            NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &pAd->StaCfg.RSNIE_Len, 1);
+	            VarIesOffset += 1;
+			}
+			NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len);
+			VarIesOffset += pAd->StaCfg.RSNIE_Len;
+
+			// Set Variable IEs Length
+			pAd->StaCfg.ReqVarIELen = VarIesOffset;
+		}
+
+		// We have update that at PeerBeaconAtJoinRequest()
+		CkipFlag = pAd->StaCfg.CkipFlag;
+		if (CkipFlag != 0)
+		{
+			NdisZeroMemory(CkipNegotiationBuffer, CKIP_NEGOTIATION_LENGTH);
+			CkipNegotiationBuffer[2] = 0x66;
+			// Make it try KP & MIC, since we have to follow the result from AssocRsp
+			CkipNegotiationBuffer[8] = 0x18;
+			CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH - 1] = 0x22;
+			CkipFlag = 0x18;
+
+			MakeOutgoingFrame(pOutBuffer + FrameLen, 	&tmp,
+						1,						  		&AironetCkipIe,
+						1,						  		&AironetCkipLen,
+						AironetCkipLen, 		  		CkipNegotiationBuffer,
+						END_OF_ARGS);
+			FrameLen += tmp;
+		}
+
+		// Add CCX v2 request if CCX2 admin state is on
+		if (pAd->StaCfg.CCXControl.field.Enable == 1)
+		{
+
+			//
+			// Add AironetIPAddressIE for Cisco CCX 2.X
+			// Add CCX Version
+			//
+			MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+						1,							&AironetIPAddressIE,
+						1,							&AironetIPAddressLen,
+						AironetIPAddressLen,		AironetIPAddressBuffer,
+						1,							&Ccx2Ie,
+						1,							&Ccx2Len,
+						Ccx2Len,				    Ccx2IeInfo,
+						END_OF_ARGS);
+			FrameLen += tmp;
+
+			//
+			// Add CipherSuite CCKM or LeapTkip if setting.
+			//
+#ifdef LEAP_SUPPORT
+			if (LEAP_CCKM_ON(pAd))
+			{
+				MakeOutgoingFrame(pOutBuffer + FrameLen,	&tmp,
+						CipherSuiteCiscoCCKMLen,		CipherSuiteCiscoCCKM,
+						END_OF_ARGS);
+				FrameLen += tmp;
+
+				// Third add RSN
+				NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, CipherSuiteCiscoCCKM, CipherSuiteCiscoCCKMLen); //Save CipherSuite
+				VarIesOffset += CipherSuiteCiscoCCKMLen;
+			}
+			else if ((pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP) && (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled))
+			{
+				MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+						CipherSuiteCCXTkipLen,	    CipherSuiteCCXTkip,
+						END_OF_ARGS);
+				FrameLen += tmp;
+
+				// Third add RSN
+				NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, CipherSuiteCCXTkip, CipherSuiteCCXTkipLen);
+				VarIesOffset += CipherSuiteCCXTkipLen;
+			}
+#endif // LEAP_SUPPORT //
+
+			// Add by James 03/06/27
+			// Set Variable IEs Length
+			pAd->StaCfg.ReqVarIELen = VarIesOffset;
+			pAd->StaCfg.AssocInfo.RequestIELength = VarIesOffset;
+
+			// OffsetResponseIEs follow ReqVarIE
+			pAd->StaCfg.AssocInfo.OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAd->StaCfg.ReqVarIELen;
+			// End Add by James
+		}
+
+
+		MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+		MlmeFreeMemory(pAd, pOutBuffer);
+
+		RTMPSetTimer(&pAd->MlmeAux.AssocTimer, Timeout);
+		pAd->Mlme.AssocMachine.CurrState = ASSOC_WAIT_RSP;
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeAssocReqAction() sanity check failed. BUG!!!!!! \n"));
+		pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+		Status = MLME_INVALID_FORMAT;
+		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
+	}
+
+}
+
+/*
+	==========================================================================
+	Description:
+		mlme reassoc req handling procedure
+	Parameters:
+		Elem -
+	Pre:
+		-# SSID  (Adapter->StaCfg.ssid[])
+		-# BSSID (AP address, Adapter->StaCfg.bssid)
+		-# Supported rates (Adapter->StaCfg.supported_rates[])
+		-# Supported rates length (Adapter->StaCfg.supported_rates_len)
+		-# Tx power (Adapter->StaCfg.tx_power)
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID MlmeReassocReqAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	UCHAR			ApAddr[6];
+	HEADER_802_11	ReassocHdr;
+	UCHAR			Ccx2Len = 5;
+	UCHAR			WmeIe[9] = {IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
+	USHORT			CapabilityInfo, ListenIntv;
+	ULONG			Timeout;
+	ULONG			FrameLen = 0;
+	BOOLEAN			TimerCancelled;
+	NDIS_STATUS		NStatus;
+	ULONG			tmp;
+	PUCHAR			pOutBuffer = NULL;
+//CCX 2.X
+#ifdef LEAP_SUPPORT
+	UCHAR			CkipFlag;
+	UCHAR			CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH];
+	UCHAR			AironetCkipIe = IE_AIRONET_CKIP;
+	UCHAR			AironetCkipLen = CKIP_NEGOTIATION_LENGTH;
+	UCHAR			AironetIPAddressIE = IE_AIRONET_IPADDRESS;
+	UCHAR			AironetIPAddressLen = AIRONET_IPADDRESS_LENGTH;
+	UCHAR			AironetIPAddressBuffer[AIRONET_IPADDRESS_LENGTH] = {0x00, 0x40, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
+	UCHAR			AironetCCKMReassocIE = IE_AIRONET_CCKMREASSOC;
+	UCHAR			AironetCCKMReassocLen = AIRONET_CCKMREASSOC_LENGTH;
+	UCHAR			AironetCCKMReassocBuffer[AIRONET_CCKMREASSOC_LENGTH];
+	UCHAR			AironetOUI[] = {0x00, 0x40, 0x96, 0x00};
+	UCHAR			MICMN[16];
+	UCHAR			CalcMicBuffer[80];
+	ULONG			CalcMicBufferLen = 0;
+#endif // LEAP_SUPPORT //
+	USHORT			Status;
+
+	// Block all authentication request durning WPA block period
+	if (pAd->StaCfg.bBlockAssoc == TRUE)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Block ReAssoc request durning WPA block period!\n"));
+		pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+		Status = MLME_STATE_MACHINE_REJECT;
+		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
+	}
+	// the parameters are the same as the association
+	else if(MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, &Timeout, &ListenIntv))
+	{
+		RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &TimerCancelled);
+
+		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
+		if(NStatus != NDIS_STATUS_SUCCESS)
+		{
+			DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeReassocReqAction() allocate memory failed \n"));
+			pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+			Status = MLME_FAIL_NO_RESOURCE;
+			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
+			return;
+		}
+
+		COPY_MAC_ADDR(pAd->MlmeAux.Bssid, ApAddr);
+
+		// make frame, use bssid as the AP address??
+		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send RE-ASSOC request...\n"));
+		MgtMacHeaderInit(pAd, &ReassocHdr, SUBTYPE_REASSOC_REQ, 0, ApAddr, ApAddr);
+		MakeOutgoingFrame(pOutBuffer,               &FrameLen,
+						  sizeof(HEADER_802_11),    &ReassocHdr,
+						  2,                        &CapabilityInfo,
+						  2,                        &ListenIntv,
+						  MAC_ADDR_LEN,             ApAddr,
+						  1,                        &SsidIe,
+						  1,                        &pAd->MlmeAux.SsidLen,
+						  pAd->MlmeAux.SsidLen,     pAd->MlmeAux.Ssid,
+						  1,                        &SupRateIe,
+						  1,						&pAd->MlmeAux.SupRateLen,
+						  pAd->MlmeAux.SupRateLen,  pAd->MlmeAux.SupRate,
+						  END_OF_ARGS);
+
+		if (pAd->MlmeAux.ExtRateLen != 0)
+		{
+			MakeOutgoingFrame(pOutBuffer + FrameLen,        &tmp,
+							  1,                            &ExtRateIe,
+							  1,                            &pAd->MlmeAux.ExtRateLen,
+							  pAd->MlmeAux.ExtRateLen,	    pAd->MlmeAux.ExtRate,
+							  END_OF_ARGS);
+			FrameLen += tmp;
+		}
+
+		if (pAd->MlmeAux.APEdcaParm.bValid)
+		{
+			if (pAd->CommonCfg.bAPSDCapable && pAd->MlmeAux.APEdcaParm.bAPSDCapable)
+			{
+				QBSS_STA_INFO_PARM QosInfo;
+
+				NdisZeroMemory(&QosInfo, sizeof(QBSS_STA_INFO_PARM));
+				QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE;
+				QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK;
+				QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI;
+				QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO;
+				QosInfo.MaxSPLength = pAd->CommonCfg.MaxSPLength;
+				WmeIe[8] |= *(PUCHAR)&QosInfo;
+			}
+
+			MakeOutgoingFrame(pOutBuffer + FrameLen,    &tmp,
+							  9,                        &WmeIe[0],
+							  END_OF_ARGS);
+			FrameLen += tmp;
+		}
+
+#ifdef DOT11_N_SUPPORT
+		// HT
+		if ((pAd->MlmeAux.HtCapabilityLen > 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+		{
+			ULONG TmpLen;
+			UCHAR HtLen;
+			UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
+			if (pAd->StaActive.SupportedPhyInfo.bPreNHt == TRUE)
+			{
+				HtLen = SIZE_HT_CAP_IE + 4;
+				MakeOutgoingFrame(pOutBuffer + FrameLen,            &TmpLen,
+							  1,                                &WpaIe,
+							  1,                                &HtLen,
+							  4,                                &BROADCOM[0],
+							 pAd->MlmeAux.HtCapabilityLen,          &pAd->MlmeAux.HtCapability,
+							  END_OF_ARGS);
+			}
+			else
+			{
+				MakeOutgoingFrame(pOutBuffer + FrameLen,            &TmpLen,
+							  1,                                &HtCapIe,
+							  1,                                &pAd->MlmeAux.HtCapabilityLen,
+							 pAd->MlmeAux.HtCapabilityLen,          &pAd->MlmeAux.HtCapability,
+							  END_OF_ARGS);
+			}
+			FrameLen += TmpLen;
+		}
+#endif // DOT11_N_SUPPORT //
+
+		// add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION
+		// Case I: (Aggregation + Piggy-Back)
+		// 1. user enable aggregation, AND
+		// 2. Mac support piggy-back
+		// 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON
+		// Case II: (Aggregation)
+		// 1. user enable aggregation, AND
+		// 2. AP annouces it's AGGREGATION-capable in BEACON
+		if (pAd->CommonCfg.bAggregationCapable)
+		{
+			if ((pAd->CommonCfg.bPiggyBackCapable) && ((pAd->MlmeAux.APRalinkIe & 0x00000003) == 3))
+			{
+				ULONG TmpLen;
+				UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x03, 0x00, 0x00, 0x00};
+				MakeOutgoingFrame(pOutBuffer+FrameLen,           &TmpLen,
+								  9,                             RalinkIe,
+								  END_OF_ARGS);
+				FrameLen += TmpLen;
+			}
+			else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
+			{
+				ULONG TmpLen;
+				UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x01, 0x00, 0x00, 0x00};
+				MakeOutgoingFrame(pOutBuffer+FrameLen,           &TmpLen,
+								  9,                             RalinkIe,
+								  END_OF_ARGS);
+				FrameLen += TmpLen;
+			}
+		}
+		else
+		{
+			ULONG TmpLen;
+			UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x04, 0x00, 0x00, 0x00};
+			MakeOutgoingFrame(pOutBuffer+FrameLen,		 &TmpLen,
+							  9,						 RalinkIe,
+							  END_OF_ARGS);
+			FrameLen += TmpLen;
+		}
+#ifdef LEAP_SUPPORT
+		if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
+		{
+			CkipFlag = pAd->StaCfg.CkipFlag;	// We have update that at PeerBeaconAtJoinRequest()
+			if (CkipFlag != 0)
+			{
+				NdisZeroMemory(CkipNegotiationBuffer, CKIP_NEGOTIATION_LENGTH);
+				CkipNegotiationBuffer[2] = 0x66;
+				// Make it try KP & MIC, since we have to follow the result from AssocRsp
+				CkipNegotiationBuffer[8] = 0x18;
+				CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH - 1] = 0x22;
+
+				MakeOutgoingFrame(pOutBuffer + FrameLen,            &tmp,
+									1,                              &AironetCkipIe,
+									1,                              &AironetCkipLen,
+									AironetCkipLen,                 CkipNegotiationBuffer,
+									END_OF_ARGS);
+				FrameLen += tmp;
+			}
+
+			MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+							1,                              &AironetIPAddressIE,
+							1,                              &AironetIPAddressLen,
+							AironetIPAddressLen,            AironetIPAddressBuffer,
+							END_OF_ARGS);
+			FrameLen += tmp;
+
+			//
+			// The RN is incremented before each reassociation request.
+			//
+			pAd->StaCfg.CCKMRN++;
+			//
+			// Calculate MIC = hmac-md5(krk, STA-ID|BSSID|RSNIE|TSF|RN);
+			//
+			COPY_MAC_ADDR(CalcMicBuffer, pAd->CurrentAddress);
+			CalcMicBufferLen = MAC_ADDR_LEN;
+			COPY_MAC_ADDR(CalcMicBuffer + CalcMicBufferLen, pAd->MlmeAux.Bssid);
+			CalcMicBufferLen += MAC_ADDR_LEN;
+			NdisMoveMemory(CalcMicBuffer + CalcMicBufferLen, CipherSuiteCiscoCCKM, CipherSuiteCiscoCCKMLen);
+			CalcMicBufferLen += CipherSuiteCiscoCCKMLen;
+			NdisMoveMemory(CalcMicBuffer + CalcMicBufferLen, (PUCHAR) &pAd->StaCfg.CCKMBeaconAtJoinTimeStamp, sizeof(pAd->StaCfg.CCKMBeaconAtJoinTimeStamp));
+			CalcMicBufferLen += sizeof(pAd->StaCfg.CCKMBeaconAtJoinTimeStamp);
+			NdisMoveMemory(CalcMicBuffer + CalcMicBufferLen, (PUCHAR)&pAd->StaCfg.CCKMRN, sizeof(pAd->StaCfg.CCKMRN));
+			CalcMicBufferLen += sizeof(pAd->StaCfg.CCKMRN);
+			hmac_md5(pAd->StaCfg.KRK, LEN_EAP_MICK, CalcMicBuffer, CalcMicBufferLen, MICMN);
+
+			//
+			// fill up CCKM reassociation request element
+			//
+			NdisMoveMemory(AironetCCKMReassocBuffer, AironetOUI, 4);
+			NdisMoveMemory(AironetCCKMReassocBuffer + 4, (PUCHAR)&pAd->StaCfg.CCKMBeaconAtJoinTimeStamp, 8);
+			NdisMoveMemory(AironetCCKMReassocBuffer + 12, (PUCHAR) &pAd->StaCfg.CCKMRN, 4);
+			NdisMoveMemory(AironetCCKMReassocBuffer +16, MICMN, 8);
+
+			MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+							1,                      &AironetCCKMReassocIE,
+							1,                      &AironetCCKMReassocLen,
+							AironetCCKMReassocLen,  AironetCCKMReassocBuffer,
+							END_OF_ARGS);
+			FrameLen += tmp;
+
+			MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+							CipherSuiteCiscoCCKMLen,CipherSuiteCiscoCCKM,
+							END_OF_ARGS);
+			FrameLen += tmp;
+		}
+#endif // LEAP_SUPPORT //
+
+		// Add CCX v2 request if CCX2 admin state is on
+		if (pAd->StaCfg.CCXControl.field.Enable == 1)
+		{
+			//
+			// Add CCX Version
+			//
+			MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+						1,							&Ccx2Ie,
+						1,							&Ccx2Len,
+						Ccx2Len,				    Ccx2IeInfo,
+						END_OF_ARGS);
+			FrameLen += tmp;
+		}
+
+		MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+		MlmeFreeMemory(pAd, pOutBuffer);
+
+		RTMPSetTimer(&pAd->MlmeAux.ReassocTimer, Timeout); /* in mSec */
+		pAd->Mlme.AssocMachine.CurrState = REASSOC_WAIT_RSP;
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeReassocReqAction() sanity check failed. BUG!!!! \n"));
+		pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+		Status = MLME_INVALID_FORMAT;
+		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
+	}
+}
+
+/*
+	==========================================================================
+	Description:
+		Upper layer issues disassoc request
+	Parameters:
+		Elem -
+
+	IRQL = PASSIVE_LEVEL
+
+	==========================================================================
+ */
+VOID MlmeDisassocReqAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	PMLME_DISASSOC_REQ_STRUCT pDisassocReq;
+	HEADER_802_11         DisassocHdr;
+	PHEADER_802_11        pDisassocHdr;
+	PUCHAR                pOutBuffer = NULL;
+	ULONG                 FrameLen = 0;
+	NDIS_STATUS           NStatus;
+	BOOLEAN               TimerCancelled;
+	ULONG                 Timeout = 0;
+	USHORT                Status;
+
+#ifdef QOS_DLS_SUPPORT
+	// send DLS-TEAR_DOWN message,
+	if (pAd->CommonCfg.bDLSCapable)
+	{
+		UCHAR i;
+
+		// tear down local dls table entry
+		for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+		{
+			if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
+			{
+				RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
+				pAd->StaCfg.DLSEntry[i].Status	= DLS_NONE;
+				pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
+			}
+		}
+
+		// tear down peer dls table entry
+		for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+		{
+			if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
+			{
+				RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
+				pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+				pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
+			}
+		}
+	}
+#endif // QOS_DLS_SUPPORT //
+
+	// skip sanity check
+	pDisassocReq = (PMLME_DISASSOC_REQ_STRUCT)(Elem->Msg);
+
+	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
+	if (NStatus != NDIS_STATUS_SUCCESS)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - MlmeDisassocReqAction() allocate memory failed\n"));
+		pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+		Status = MLME_FAIL_NO_RESOURCE;
+		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
+		return;
+	}
+
+
+
+	RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &TimerCancelled);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send DISASSOC request[BSSID::%02x:%02x:%02x:%02x:%02x:%02x (Reason=%d)\n",
+				pDisassocReq->Addr[0], pDisassocReq->Addr[1], pDisassocReq->Addr[2],
+				pDisassocReq->Addr[3], pDisassocReq->Addr[4], pDisassocReq->Addr[5], pDisassocReq->Reason));
+	MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pDisassocReq->Addr, pDisassocReq->Addr);	// patch peap ttls switching issue
+	MakeOutgoingFrame(pOutBuffer,           &FrameLen,
+					  sizeof(HEADER_802_11),&DisassocHdr,
+					  2,                    &pDisassocReq->Reason,
+					  END_OF_ARGS);
+	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+
+	// To patch Instance and Buffalo(N) AP
+	// Driver has to send deauth to Instance AP, but Buffalo(N) needs to send disassoc to reset Authenticator's state machine
+	// Therefore, we send both of them.
+	pDisassocHdr = (PHEADER_802_11)pOutBuffer;
+	pDisassocHdr->FC.SubType = SUBTYPE_DEAUTH;
+	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+
+	MlmeFreeMemory(pAd, pOutBuffer);
+
+	pAd->StaCfg.DisassocReason = REASON_DISASSOC_STA_LEAVING;
+	COPY_MAC_ADDR(pAd->StaCfg.DisassocSta, pDisassocReq->Addr);
+
+	RTMPSetTimer(&pAd->MlmeAux.DisassocTimer, Timeout); /* in mSec */
+	pAd->Mlme.AssocMachine.CurrState = DISASSOC_WAIT_RSP;
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+    if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
+	{
+        union iwreq_data    wrqu;
+        //send disassociate event to wpa_supplicant
+        memset(&wrqu, 0, sizeof(wrqu));
+        wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
+        wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+    }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+    {
+        union iwreq_data    wrqu;
+        memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+        wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+    }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+}
+
+/*
+	==========================================================================
+	Description:
+		peer sends assoc rsp back
+	Parameters:
+		Elme - MLME message containing the received frame
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID PeerAssocRspAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	USHORT        CapabilityInfo, Status, Aid;
+	UCHAR         SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen;
+	UCHAR         ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen;
+	UCHAR         Addr2[MAC_ADDR_LEN];
+	BOOLEAN       TimerCancelled;
+	UCHAR         CkipFlag;
+	EDCA_PARM     EdcaParm;
+	HT_CAPABILITY_IE		HtCapability;
+	ADD_HT_INFO_IE		AddHtInfo;	// AP might use this additional ht info IE
+	UCHAR			HtCapabilityLen;
+	UCHAR			AddHtInfoLen;
+	UCHAR			NewExtChannelOffset = 0xff;
+
+	if (PeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status, &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen,
+		&HtCapability,&AddHtInfo, &HtCapabilityLen,&AddHtInfoLen,&NewExtChannelOffset, &EdcaParm, &CkipFlag))
+	{
+		// The frame is for me ?
+		if(MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspAction():ASSOC - receive ASSOC_RSP to me (status=%d)\n", Status));
+#ifdef DOT11_N_SUPPORT
+			DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspAction():MacTable [%d].AMsduSize = %d. ClientStatusFlags = 0x%lx \n",Elem->Wcid, pAd->MacTab.Content[BSSID_WCID].AMsduSize, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
+#endif // DOT11_N_SUPPORT //
+			RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &TimerCancelled);
+			if(Status == MLME_SUCCESS)
+			{
+				UCHAR			MaxSupportedRateIn500Kbps = 0;
+				UCHAR			idx;
+
+				// supported rates array may not be sorted. sort it and find the maximum rate
+			    for (idx=0; idx<SupRateLen; idx++)
+                {
+			        if (MaxSupportedRateIn500Kbps < (SupRate[idx] & 0x7f))
+			            MaxSupportedRateIn500Kbps = SupRate[idx] & 0x7f;
+                }
+
+				for (idx=0; idx<ExtRateLen; idx++)
+                {
+			        if (MaxSupportedRateIn500Kbps < (ExtRate[idx] & 0x7f))
+			            MaxSupportedRateIn500Kbps = ExtRate[idx] & 0x7f;
+                }
+				// go to procedure listed on page 376
+				AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen,
+					&EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo);
+
+				StaAddMacTableEntry(pAd, &pAd->MacTab.Content[BSSID_WCID], MaxSupportedRateIn500Kbps, &HtCapability, HtCapabilityLen, CapabilityInfo);
+
+				pAd->StaCfg.CkipFlag = CkipFlag;
+				if (CkipFlag & 0x18)
+				{
+					NdisZeroMemory(pAd->StaCfg.TxSEQ, 4);
+					NdisZeroMemory(pAd->StaCfg.RxSEQ, 4);
+					NdisZeroMemory(pAd->StaCfg.CKIPMIC, 4);
+					pAd->StaCfg.GIV[0] = RandomByte(pAd);
+					pAd->StaCfg.GIV[1] = RandomByte(pAd);
+					pAd->StaCfg.GIV[2] = RandomByte(pAd);
+					pAd->StaCfg.bCkipOn = TRUE;
+					DBGPRINT(RT_DEBUG_TRACE, ("<CCX> pAd->StaCfg.CkipFlag = 0x%02x\n", pAd->StaCfg.CkipFlag));
+				}
+			}
+			else
+			{
+				// Faile on Association, we need to check the status code
+				// Is that a Rogue AP?
+#ifdef LEAP_SUPPORT
+				if ((pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP) && (Status == MLME_ALG_NOT_SUPPORT))
+				{ //Possibly Rogue AP
+					RogueApTableSetEntry(pAd, &pAd->StaCfg.RogueApTab, pAd->MlmeAux.Bssid, LEAP_REASON_INVALID_AUTH);
+				}
+#endif // LEAP_SUPPORT //
+			}
+			pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
+		}
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerAssocRspAction() sanity check fail\n"));
+	}
+}
+
+/*
+	==========================================================================
+	Description:
+		peer sends reassoc rsp
+	Parametrs:
+		Elem - MLME message cntaining the received frame
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID PeerReassocRspAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	USHORT      CapabilityInfo;
+	USHORT      Status;
+	USHORT      Aid;
+	UCHAR       SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen;
+	UCHAR       ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen;
+	UCHAR       Addr2[MAC_ADDR_LEN];
+	UCHAR       CkipFlag;
+	BOOLEAN     TimerCancelled;
+	EDCA_PARM   EdcaParm;
+	HT_CAPABILITY_IE		HtCapability;
+	ADD_HT_INFO_IE		AddHtInfo;	// AP might use this additional ht info IE
+	UCHAR			HtCapabilityLen;
+	UCHAR			AddHtInfoLen;
+	UCHAR			NewExtChannelOffset = 0xff;
+
+	if(PeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status, &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen,
+								&HtCapability,	&AddHtInfo, &HtCapabilityLen, &AddHtInfoLen,&NewExtChannelOffset, &EdcaParm, &CkipFlag))
+	{
+		if(MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid)) // The frame is for me ?
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - receive REASSOC_RSP to me (status=%d)\n", Status));
+			RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &TimerCancelled);
+
+			if(Status == MLME_SUCCESS)
+			{
+				// go to procedure listed on page 376
+				AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen,
+					 &EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo);
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+                if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
+                {
+                    union iwreq_data    wrqu;
+
+                    SendAssocIEsToWpaSupplicant(pAd);
+                    memset(&wrqu, 0, sizeof(wrqu));
+                    wrqu.data.flags = RT_ASSOC_EVENT_FLAG;
+                    wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+                }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+                {
+                    union iwreq_data    wrqu;
+                    wext_notify_event_assoc(pAd);
+
+                    memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+                    memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
+                    wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+
+                }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+			}
+
+			//
+			// Cisco Leap CCKM supported Re-association.
+			//
+#ifdef LEAP_SUPPORT
+			if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
+			{
+				if (CCKMAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen) == TRUE)
+				{
+					pAd->StaCfg.CkipFlag = CkipFlag;
+					if (CkipFlag & 0x18)
+					{
+						NdisZeroMemory(pAd->StaCfg.TxSEQ, 4);
+						NdisZeroMemory(pAd->StaCfg.RxSEQ, 4);
+						NdisZeroMemory(pAd->StaCfg.CKIPMIC, 4);
+						pAd->StaCfg.GIV[0] = RandomByte(pAd);
+						pAd->StaCfg.GIV[1] = RandomByte(pAd);
+						pAd->StaCfg.GIV[2] = RandomByte(pAd);
+						pAd->StaCfg.bCkipOn = TRUE;
+						DBGPRINT(RT_DEBUG_TRACE, ("<CCX> pAd->StaCfg.CkipFlag = 0x%02x\n", pAd->StaCfg.CkipFlag));
+					}
+
+					pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+					MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
+				}
+				else
+				{
+					DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - CCKMAssocRspSanity() sanity check fail\n"));
+				}
+			}
+			else
+#endif // LEAP_SUPPORT //
+			{
+				// CkipFlag is no use for reassociate
+				pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+				MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
+			}
+		}
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerReassocRspAction() sanity check fail\n"));
+	}
+
+}
+
+/*
+	==========================================================================
+	Description:
+		procedures on IEEE 802.11/1999 p.376
+	Parametrs:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID AssocPostProc(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pAddr2,
+	IN USHORT CapabilityInfo,
+	IN USHORT Aid,
+	IN UCHAR SupRate[],
+	IN UCHAR SupRateLen,
+	IN UCHAR ExtRate[],
+	IN UCHAR ExtRateLen,
+	IN PEDCA_PARM pEdcaParm,
+	IN HT_CAPABILITY_IE		*pHtCapability,
+	IN UCHAR HtCapabilityLen,
+	IN ADD_HT_INFO_IE		*pAddHtInfo)	// AP might use this additional ht info IE
+{
+	ULONG Idx;
+
+	pAd->MlmeAux.BssType = BSS_INFRA;
+	COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pAddr2);
+	pAd->MlmeAux.Aid = Aid;
+	pAd->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
+#ifdef DOT11_N_SUPPORT
+	// Some HT AP might lost WMM IE. We add WMM ourselves. beacuase HT requires QoS on.
+	if ((HtCapabilityLen > 0) && (pEdcaParm->bValid == FALSE))
+	{
+		pEdcaParm->bValid = TRUE;
+		pEdcaParm->Aifsn[0] = 3;
+		pEdcaParm->Aifsn[1] = 7;
+		pEdcaParm->Aifsn[2] = 2;
+		pEdcaParm->Aifsn[3] = 2;
+
+		pEdcaParm->Cwmin[0] = 4;
+		pEdcaParm->Cwmin[1] = 4;
+		pEdcaParm->Cwmin[2] = 3;
+		pEdcaParm->Cwmin[3] = 2;
+
+		pEdcaParm->Cwmax[0] = 10;
+		pEdcaParm->Cwmax[1] = 10;
+		pEdcaParm->Cwmax[2] = 4;
+		pEdcaParm->Cwmax[3] = 3;
+
+		pEdcaParm->Txop[0]  = 0;
+		pEdcaParm->Txop[1]  = 0;
+		pEdcaParm->Txop[2]  = 96;
+		pEdcaParm->Txop[3]  = 48;
+
+	}
+#endif // DOT11_N_SUPPORT //
+
+	NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
+
+	// filter out un-supported rates
+	pAd->MlmeAux.SupRateLen = SupRateLen;
+	NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen);
+	RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
+
+	// filter out un-supported rates
+	pAd->MlmeAux.ExtRateLen = ExtRateLen;
+	NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen);
+	RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
+
+#ifdef DOT11_N_SUPPORT
+	if (HtCapabilityLen > 0)
+	{
+		RTMPCheckHt(pAd, BSSID_WCID, pHtCapability, pAddHtInfo);
+	}
+	DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===>  AP.AMsduSize = %d. ClientStatusFlags = 0x%lx \n", pAd->MacTab.Content[BSSID_WCID].AMsduSize, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
+
+	DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===>    (Mmps=%d, AmsduSize=%d, )\n",
+		pAd->MacTab.Content[BSSID_WCID].MmpsMode, pAd->MacTab.Content[BSSID_WCID].AMsduSize));
+#endif // DOT11_N_SUPPORT //
+
+	// Set New WPA information
+	Idx = BssTableSearch(&pAd->ScanTab, pAddr2, pAd->MlmeAux.Channel);
+	if (Idx == BSS_NOT_FOUND)
+	{
+		DBGPRINT_ERR(("ASSOC - Can't find BSS after receiving Assoc response\n"));
+	}
+	else
+	{
+		// Init variable
+		pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = 0;
+		NdisZeroMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, MAX_LEN_OF_RSNIE);
+
+		// Store appropriate RSN_IE for WPA SM negotiation later
+		if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pAd->ScanTab.BssEntry[Idx].VarIELen != 0))
+		{
+			PUCHAR              pVIE;
+			USHORT              len;
+			PEID_STRUCT         pEid;
+
+			pVIE = pAd->ScanTab.BssEntry[Idx].VarIEs;
+			len	 = pAd->ScanTab.BssEntry[Idx].VarIELen;
+
+			while (len > 0)
+			{
+				pEid = (PEID_STRUCT) pVIE;
+				// For WPA/WPAPSK
+				if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
+					&& (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
+				{
+					NdisMoveMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, pVIE, (pEid->Len + 2));
+					pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = (pEid->Len + 2);
+					DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> Store RSN_IE for WPA SM negotiation \n"));
+				}
+				// For WPA2/WPA2PSK
+				else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
+					&& (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2 || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+				{
+					NdisMoveMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, pVIE, (pEid->Len + 2));
+					pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = (pEid->Len + 2);
+					DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> Store RSN_IE for WPA2 SM negotiation \n"));
+				}
+
+				pVIE += (pEid->Len + 2);
+				len  -= (pEid->Len + 2);
+			}
+		}
+
+		if (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == 0)
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> no RSN_IE \n"));
+		}
+		else
+		{
+			hex_dump("RSN_IE", pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len);
+		}
+	}
+}
+
+/*
+	==========================================================================
+	Description:
+		left part of IEEE 802.11/1999 p.374
+	Parameters:
+		Elem - MLME message containing the received frame
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID PeerDisassocAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	UCHAR         Addr2[MAC_ADDR_LEN];
+	USHORT        Reason;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction()\n"));
+	if(PeerDisassocSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason))
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction() Reason = %d\n", Reason));
+		if (INFRA_ON(pAd) && MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, Addr2))
+		{
+
+			if (pAd->CommonCfg.bWirelessEvent)
+			{
+				RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+			}
+
+
+#ifdef LEAP_SUPPORT
+			if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+			{
+				// Cisco_LEAP has start a timer
+				// We should cancel it if using LEAP
+				RTMPCancelTimer(&pAd->StaCfg.LeapAuthTimer, &TimerCancelled);
+				//Check is it mach the LEAP Authentication failed as possible a Rogue AP
+				//on it's PortSecured not equal to WPA_802_1X_PORT_SECURED while process the Association.
+				if ((pAd->Mlme.LeapMachine.CurrState != LEAP_IDLE) && (pAd->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED))
+				{
+					RogueApTableSetEntry(pAd, &pAd->StaCfg.RogueApTab, Addr2, LEAP_REASON_AUTH_TIMEOUT);
+				}
+			}
+#endif	// LEAP_SUPPORT //
+			//
+			// Get Current System time and Turn on AdjacentAPReport
+			//
+			NdisGetSystemUpTime(&pAd->StaCfg.CCXAdjacentAPLinkDownTime);
+			pAd->StaCfg.CCXAdjacentAPReportFlag = TRUE;
+			LinkDown(pAd, TRUE);
+			pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+            if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
+			{
+                union iwreq_data    wrqu;
+                //send disassociate event to wpa_supplicant
+                memset(&wrqu, 0, sizeof(wrqu));
+                wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
+                wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+            }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+            {
+                union iwreq_data    wrqu;
+                memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+                wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+            }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+		}
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction() sanity check fail\n"));
+	}
+
+}
+
+/*
+	==========================================================================
+	Description:
+		what the state machine will do after assoc timeout
+	Parameters:
+		Elme -
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID AssocTimeoutAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	USHORT  Status;
+	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - AssocTimeoutAction\n"));
+	pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+	Status = MLME_REJ_TIMEOUT;
+	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
+}
+
+/*
+	==========================================================================
+	Description:
+		what the state machine will do after reassoc timeout
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID ReassocTimeoutAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	USHORT  Status;
+	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - ReassocTimeoutAction\n"));
+	pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+	Status = MLME_REJ_TIMEOUT;
+	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
+}
+
+/*
+	==========================================================================
+	Description:
+		what the state machine will do after disassoc timeout
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID DisassocTimeoutAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	USHORT  Status;
+	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - DisassocTimeoutAction\n"));
+	pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+	Status = MLME_SUCCESS;
+	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
+}
+
+VOID InvalidStateWhenAssoc(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	USHORT  Status;
+	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenAssoc(state=%ld), reset ASSOC state machine\n",
+		pAd->Mlme.AssocMachine.CurrState));
+	pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+	Status = MLME_STATE_MACHINE_REJECT;
+	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
+}
+
+VOID InvalidStateWhenReassoc(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	USHORT Status;
+	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenReassoc(state=%ld), reset ASSOC state machine\n",
+		pAd->Mlme.AssocMachine.CurrState));
+	pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+	Status = MLME_STATE_MACHINE_REJECT;
+	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
+}
+
+VOID InvalidStateWhenDisassociate(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	USHORT Status;
+	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenDisassoc(state=%ld), reset ASSOC state machine\n",
+		pAd->Mlme.AssocMachine.CurrState));
+	pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+	Status = MLME_STATE_MACHINE_REJECT;
+	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
+}
+
+/*
+	==========================================================================
+	Description:
+		right part of IEEE 802.11/1999 page 374
+	Note:
+		This event should never cause ASSOC state machine perform state
+		transition, and has no relationship with CNTL machine. So we separate
+		this routine as a service outside of ASSOC state transition table.
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID Cls3errAction(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR        pAddr)
+{
+	HEADER_802_11         DisassocHdr;
+	PHEADER_802_11        pDisassocHdr;
+	PUCHAR                pOutBuffer = NULL;
+	ULONG                 FrameLen = 0;
+	NDIS_STATUS           NStatus;
+	USHORT                Reason = REASON_CLS3ERR;
+
+	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
+	if (NStatus != NDIS_STATUS_SUCCESS)
+		return;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Class 3 Error, Send DISASSOC frame\n"));
+	MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pAddr, pAd->CommonCfg.Bssid);	// patch peap ttls switching issue
+	MakeOutgoingFrame(pOutBuffer,           &FrameLen,
+					  sizeof(HEADER_802_11),&DisassocHdr,
+					  2,                    &Reason,
+					  END_OF_ARGS);
+	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+
+	// To patch Instance and Buffalo(N) AP
+	// Driver has to send deauth to Instance AP, but Buffalo(N) needs to send disassoc to reset Authenticator's state machine
+	// Therefore, we send both of them.
+	pDisassocHdr = (PHEADER_802_11)pOutBuffer;
+	pDisassocHdr->FC.SubType = SUBTYPE_DEAUTH;
+	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+
+	MlmeFreeMemory(pAd, pOutBuffer);
+
+	pAd->StaCfg.DisassocReason = REASON_CLS3ERR;
+	COPY_MAC_ADDR(pAd->StaCfg.DisassocSta, pAddr);
+}
+
+ /*
+	 ==========================================================================
+	 Description:
+		 Switch between WEP and CKIP upon new association up.
+	 Parameters:
+
+	 IRQL = DISPATCH_LEVEL
+
+	 ==========================================================================
+  */
+VOID SwitchBetweenWepAndCkip(
+	IN PRTMP_ADAPTER pAd)
+{
+	int            i;
+	SHAREDKEY_MODE_STRUC  csr1;
+
+	// if KP is required. change the CipherAlg in hardware shard key table from WEP
+	// to CKIP. else remain as WEP
+	if (pAd->StaCfg.bCkipOn && (pAd->StaCfg.CkipFlag & 0x10))
+	{
+		// modify hardware key table so that MAC use correct algorithm to decrypt RX
+		RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE, &csr1.word);
+		if (csr1.field.Bss0Key0CipherAlg == CIPHER_WEP64)
+			csr1.field.Bss0Key0CipherAlg = CIPHER_CKIP64;
+		else if (csr1.field.Bss0Key0CipherAlg == CIPHER_WEP128)
+			csr1.field.Bss0Key0CipherAlg = CIPHER_CKIP128;
+
+		if (csr1.field.Bss0Key1CipherAlg == CIPHER_WEP64)
+			csr1.field.Bss0Key1CipherAlg = CIPHER_CKIP64;
+		else if (csr1.field.Bss0Key1CipherAlg == CIPHER_WEP128)
+			csr1.field.Bss0Key1CipherAlg = CIPHER_CKIP128;
+
+		if (csr1.field.Bss0Key2CipherAlg == CIPHER_WEP64)
+			csr1.field.Bss0Key2CipherAlg = CIPHER_CKIP64;
+		else if (csr1.field.Bss0Key2CipherAlg == CIPHER_WEP128)
+			csr1.field.Bss0Key2CipherAlg = CIPHER_CKIP128;
+
+		if (csr1.field.Bss0Key3CipherAlg == CIPHER_WEP64)
+			csr1.field.Bss0Key3CipherAlg = CIPHER_CKIP64;
+		else if (csr1.field.Bss0Key3CipherAlg == CIPHER_WEP128)
+			csr1.field.Bss0Key3CipherAlg = CIPHER_CKIP128;
+		RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE, csr1.word);
+		DBGPRINT(RT_DEBUG_TRACE, ("SwitchBetweenWepAndCkip: modify BSS0 cipher to %s\n", CipherName[csr1.field.Bss0Key0CipherAlg]));
+
+		// modify software key table so that driver can specify correct algorithm in TXD upon TX
+		for (i=0; i<SHARE_KEY_NUM; i++)
+		{
+			if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_WEP64)
+				pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_CKIP64;
+			else if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_WEP128)
+				pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_CKIP128;
+		}
+	}
+
+	// else if KP NOT inused. change the CipherAlg in hardware shard key table from CKIP
+	// to WEP.
+	else
+	{
+		// modify hardware key table so that MAC use correct algorithm to decrypt RX
+		RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE, &csr1.word);
+		if (csr1.field.Bss0Key0CipherAlg == CIPHER_CKIP64)
+			csr1.field.Bss0Key0CipherAlg = CIPHER_WEP64;
+		else if (csr1.field.Bss0Key0CipherAlg == CIPHER_CKIP128)
+			csr1.field.Bss0Key0CipherAlg = CIPHER_WEP128;
+
+		if (csr1.field.Bss0Key1CipherAlg == CIPHER_CKIP64)
+			csr1.field.Bss0Key1CipherAlg = CIPHER_WEP64;
+		else if (csr1.field.Bss0Key1CipherAlg == CIPHER_CKIP128)
+			csr1.field.Bss0Key1CipherAlg = CIPHER_WEP128;
+
+		if (csr1.field.Bss0Key2CipherAlg == CIPHER_CKIP64)
+			csr1.field.Bss0Key2CipherAlg = CIPHER_WEP64;
+		else if (csr1.field.Bss0Key2CipherAlg == CIPHER_CKIP128)
+			csr1.field.Bss0Key2CipherAlg = CIPHER_WEP128;
+
+		if (csr1.field.Bss0Key3CipherAlg == CIPHER_CKIP64)
+			csr1.field.Bss0Key3CipherAlg = CIPHER_WEP64;
+		else if (csr1.field.Bss0Key3CipherAlg == CIPHER_CKIP128)
+			csr1.field.Bss0Key3CipherAlg = CIPHER_WEP128;
+
+		// modify software key table so that driver can specify correct algorithm in TXD upon TX
+		for (i=0; i<SHARE_KEY_NUM; i++)
+		{
+			if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_CKIP64)
+				pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_WEP64;
+			else if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_CKIP128)
+				pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_WEP128;
+		}
+
+		//
+		// On WPA-NONE, must update CipherAlg.
+		// Because the OID_802_11_WEP_STATUS was been set after OID_802_11_ADD_KEY
+		// and CipherAlg will be CIPHER_NONE by Windows ZeroConfig.
+		// So we need to update CipherAlg after connect.
+		//
+		if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+		{
+			for (i = 0; i < SHARE_KEY_NUM; i++)
+			{
+				if (pAd->SharedKey[BSS0][i].KeyLen != 0)
+				{
+					if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
+					{
+						pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_TKIP;
+					}
+					else if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+					{
+						pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_AES;
+					}
+				}
+				else
+				{
+					pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_NONE;
+				}
+			}
+
+			csr1.field.Bss0Key0CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
+			csr1.field.Bss0Key1CipherAlg = pAd->SharedKey[BSS0][1].CipherAlg;
+			csr1.field.Bss0Key2CipherAlg = pAd->SharedKey[BSS0][2].CipherAlg;
+			csr1.field.Bss0Key3CipherAlg = pAd->SharedKey[BSS0][3].CipherAlg;
+		}
+		RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE, csr1.word);
+		DBGPRINT(RT_DEBUG_TRACE, ("SwitchBetweenWepAndCkip: modify BSS0 cipher to %s\n", CipherName[csr1.field.Bss0Key0CipherAlg]));
+	}
+}
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+VOID    SendAssocIEsToWpaSupplicant(
+    IN  PRTMP_ADAPTER pAd)
+{
+    union iwreq_data    wrqu;
+    unsigned char custom[IW_CUSTOM_MAX] = {0};
+
+    if ((pAd->StaCfg.ReqVarIELen + 17) <= IW_CUSTOM_MAX)
+    {
+        sprintf(custom, "ASSOCINFO_ReqIEs=");
+	    NdisMoveMemory(custom+17, pAd->StaCfg.ReqVarIEs, pAd->StaCfg.ReqVarIELen);
+	    memset(&wrqu, 0, sizeof(wrqu));
+        wrqu.data.length = pAd->StaCfg.ReqVarIELen + 17;
+        wrqu.data.flags = RT_REQIE_EVENT_FLAG;
+        wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, custom);
+
+        memset(&wrqu, 0, sizeof(wrqu));
+        wrqu.data.flags = RT_ASSOCINFO_EVENT_FLAG;
+        wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+    }
+    else
+        DBGPRINT(RT_DEBUG_TRACE, ("pAd->StaCfg.ReqVarIELen + 17 > MAX_CUSTOM_LEN\n"));
+
+    return;
+}
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+int wext_notify_event_assoc(
+	IN  RTMP_ADAPTER *pAd)
+{
+    union iwreq_data    wrqu;
+    char custom[IW_CUSTOM_MAX] = {0};
+
+#if WIRELESS_EXT > 17
+    if (pAd->StaCfg.ReqVarIELen <= IW_CUSTOM_MAX)
+    {
+        wrqu.data.length = pAd->StaCfg.ReqVarIELen;
+        memcpy(custom, pAd->StaCfg.ReqVarIEs, pAd->StaCfg.ReqVarIELen);
+        wireless_send_event(pAd->net_dev, IWEVASSOCREQIE, &wrqu, custom);
+    }
+    else
+        DBGPRINT(RT_DEBUG_TRACE, ("pAd->StaCfg.ReqVarIELen > MAX_CUSTOM_LEN\n"));
+#else
+    if (((pAd->StaCfg.ReqVarIELen*2) + 17) <= IW_CUSTOM_MAX)
+    {
+        UCHAR   idx;
+        wrqu.data.length = (pAd->StaCfg.ReqVarIELen*2) + 17;
+        sprintf(custom, "ASSOCINFO(ReqIEs=");
+        for (idx=0; idx<pAd->StaCfg.ReqVarIELen; idx++)
+                sprintf(custom, "%s%02x", custom, pAd->StaCfg.ReqVarIEs[idx]);
+        wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, custom);
+    }
+    else
+        DBGPRINT(RT_DEBUG_TRACE, ("(pAd->StaCfg.ReqVarIELen*2) + 17 > MAX_CUSTOM_LEN\n"));
+#endif
+
+	return 0;
+
+}
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+
+BOOLEAN StaAddMacTableEntry(
+	IN  PRTMP_ADAPTER		pAd,
+	IN  PMAC_TABLE_ENTRY	pEntry,
+	IN  UCHAR				MaxSupportedRateIn500Kbps,
+	IN  HT_CAPABILITY_IE	*pHtCapability,
+	IN  UCHAR				HtCapabilityLen,
+	IN  USHORT        		CapabilityInfo)
+{
+	UCHAR            MaxSupportedRate = RATE_11;
+
+	if (ADHOC_ON(pAd))
+		CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
+
+	switch (MaxSupportedRateIn500Kbps)
+    {
+        case 108: MaxSupportedRate = RATE_54;   break;
+        case 96:  MaxSupportedRate = RATE_48;   break;
+        case 72:  MaxSupportedRate = RATE_36;   break;
+        case 48:  MaxSupportedRate = RATE_24;   break;
+        case 36:  MaxSupportedRate = RATE_18;   break;
+        case 24:  MaxSupportedRate = RATE_12;   break;
+        case 18:  MaxSupportedRate = RATE_9;    break;
+        case 12:  MaxSupportedRate = RATE_6;    break;
+        case 22:  MaxSupportedRate = RATE_11;   break;
+        case 11:  MaxSupportedRate = RATE_5_5;  break;
+        case 4:   MaxSupportedRate = RATE_2;    break;
+        case 2:   MaxSupportedRate = RATE_1;    break;
+        default:  MaxSupportedRate = RATE_11;   break;
+    }
+
+    if ((pAd->CommonCfg.PhyMode == PHY_11G) && (MaxSupportedRate < RATE_FIRST_OFDM_RATE))
+        return FALSE;
+
+#ifdef DOT11_N_SUPPORT
+	// 11n only
+	if (((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G))&& (HtCapabilityLen == 0))
+		return FALSE;
+#endif // DOT11_N_SUPPORT //
+
+	if (!pEntry)
+        return FALSE;
+
+	NdisAcquireSpinLock(&pAd->MacTabLock);
+	if (pEntry)
+	{
+		pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+		if ((MaxSupportedRate < RATE_FIRST_OFDM_RATE) ||
+			(pAd->CommonCfg.PhyMode == PHY_11B))
+		{
+			pEntry->RateLen = 4;
+			if (MaxSupportedRate >= RATE_FIRST_OFDM_RATE)
+				MaxSupportedRate = RATE_11;
+		}
+		else
+			pEntry->RateLen = 12;
+
+		pEntry->MaxHTPhyMode.word = 0;
+		pEntry->MinHTPhyMode.word = 0;
+		pEntry->HTPhyMode.word = 0;
+		pEntry->MaxSupportedRate = MaxSupportedRate;
+		if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
+		{
+			pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
+			pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+			pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
+			pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+			pEntry->HTPhyMode.field.MODE = MODE_CCK;
+			pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+		}
+		else
+		{
+			pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
+			pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+			pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
+			pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+			pEntry->HTPhyMode.field.MODE = MODE_OFDM;
+			pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+		}
+		pEntry->CapabilityInfo = CapabilityInfo;
+		CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE);
+		CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE);
+	}
+
+#ifdef DOT11_N_SUPPORT
+	// If this Entry supports 802.11n, upgrade to HT rate.
+	if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+	{
+		UCHAR	j, bitmask; //k,bitmask;
+		CHAR    i;
+
+		if (ADHOC_ON(pAd))
+			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
+		if ((pHtCapability->HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
+		{
+			pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
+		}
+		else
+		{
+			pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+			pAd->MacTab.fAnyStationNonGF = TRUE;
+			pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
+		}
+
+		if ((pHtCapability->HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
+		{
+			pEntry->MaxHTPhyMode.field.BW= BW_40;
+			pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(pHtCapability->HtCapInfo.ShortGIfor40));
+		}
+		else
+		{
+			pEntry->MaxHTPhyMode.field.BW = BW_20;
+			pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(pHtCapability->HtCapInfo.ShortGIfor20));
+			pAd->MacTab.fAnyStation20Only = TRUE;
+		}
+
+		// 3*3
+		if (pAd->MACVersion >= RALINK_2883_VERSION && pAd->MACVersion < RALINK_3070_VERSION)
+			pEntry->MaxHTPhyMode.field.TxBF = pAd->CommonCfg.RegTransmitSetting.field.TxBF;
+
+		// find max fixed rate
+		for (i=23; i>=0; i--) // 3*3
+		{
+			j = i/8;
+			bitmask = (1<<(i-(j*8)));
+			if ((pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j] & bitmask) && (pHtCapability->MCSSet[j] & bitmask))
+			{
+				pEntry->MaxHTPhyMode.field.MCS = i;
+				break;
+			}
+			if (i==0)
+				break;
+		}
+
+
+		if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
+		{
+			if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
+			{
+				// Fix MCS as HT Duplicated Mode
+				pEntry->MaxHTPhyMode.field.BW = 1;
+				pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+				pEntry->MaxHTPhyMode.field.STBC = 0;
+				pEntry->MaxHTPhyMode.field.ShortGI = 0;
+				pEntry->MaxHTPhyMode.field.MCS = 32;
+			}
+			else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
+			{
+				// STA supports fixed MCS
+				pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+			}
+		}
+
+		pEntry->MaxHTPhyMode.field.STBC = (pHtCapability->HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
+		pEntry->MpduDensity = pHtCapability->HtCapParm.MpduDensity;
+		pEntry->MaxRAmpduFactor = pHtCapability->HtCapParm.MaxRAmpduFactor;
+		pEntry->MmpsMode = (UCHAR)pHtCapability->HtCapInfo.MimoPs;
+		pEntry->AMsduSize = (UCHAR)pHtCapability->HtCapInfo.AMsduSize;
+		pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+
+		if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable && (pAd->CommonCfg.REGBACapability.field.AutoBA == FALSE))
+			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED);
+		if (pHtCapability->HtCapInfo.ShortGIfor20)
+			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
+		if (pHtCapability->HtCapInfo.ShortGIfor40)
+			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
+		if (pHtCapability->HtCapInfo.TxSTBC)
+			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
+		if (pHtCapability->HtCapInfo.RxSTBC)
+			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
+		if (pHtCapability->ExtHtCapInfo.PlusHTC)
+			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
+		if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport)
+			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
+		if (pHtCapability->ExtHtCapInfo.MCSFeedback == 0x03)
+			CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
+	}
+	else
+	{
+		pAd->MacTab.fAnyStationIsLegacy = TRUE;
+	}
+
+	NdisMoveMemory(&pEntry->HTCapability, pHtCapability, sizeof(HT_CAPABILITY_IE));
+#endif // DOT11_N_SUPPORT //
+
+	pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+	pEntry->CurrTxRate = pEntry->MaxSupportedRate;
+
+	// Set asic auto fall back
+	if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
+	{
+		PUCHAR					pTable;
+		UCHAR					TableSize = 0;
+
+		MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
+		pEntry->bAutoTxRateSwitch = TRUE;
+	}
+	else
+	{
+		pEntry->HTPhyMode.field.MODE	= pAd->StaCfg.HTPhyMode.field.MODE;
+		pEntry->HTPhyMode.field.MCS	= pAd->StaCfg.HTPhyMode.field.MCS;
+		pEntry->bAutoTxRateSwitch = FALSE;
+
+		// If the legacy mode is set, overwrite the transmit setting of this entry.
+		RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
+	}
+
+	pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+	pEntry->Sst = SST_ASSOC;
+	pEntry->AuthState = AS_AUTH_OPEN;
+	pEntry->AuthMode = pAd->StaCfg.AuthMode;
+	pEntry->WepStatus = pAd->StaCfg.WepStatus;
+
+	NdisReleaseSpinLock(&pAd->MacTabLock);
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+    if (pAd->StaCfg.WpaSupplicantUP)
+    {
+        union iwreq_data    wrqu;
+
+        SendAssocIEsToWpaSupplicant(pAd);
+        memset(&wrqu, 0, sizeof(wrqu));
+        wrqu.data.flags = RT_ASSOC_EVENT_FLAG;
+        wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+    }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+    {
+        union iwreq_data    wrqu;
+        wext_notify_event_assoc(pAd);
+
+        memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+        memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
+        wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+
+    }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+	return TRUE;
+}
+
+
diff --git a/drivers/staging/rt3070/sta/auth.c b/drivers/staging/rt3070/sta/auth.c
new file mode 100644
index 0000000..032b5df
--- /dev/null
+++ b/drivers/staging/rt3070/sta/auth.c
@@ -0,0 +1,475 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	auth.c
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	John		2004-9-3		porting from RT2500
+*/
+#include "../rt_config.h"
+
+/*
+    ==========================================================================
+    Description:
+        authenticate state machine init, including state transition and timer init
+    Parameters:
+        Sm - pointer to the auth state machine
+    Note:
+        The state machine looks like this
+
+                        AUTH_REQ_IDLE           AUTH_WAIT_SEQ2                   AUTH_WAIT_SEQ4
+    MT2_MLME_AUTH_REQ   mlme_auth_req_action    invalid_state_when_auth          invalid_state_when_auth
+    MT2_PEER_AUTH_EVEN  drop                    peer_auth_even_at_seq2_action    peer_auth_even_at_seq4_action
+    MT2_AUTH_TIMEOUT    Drop                    auth_timeout_action              auth_timeout_action
+
+	IRQL = PASSIVE_LEVEL
+
+    ==========================================================================
+ */
+
+void AuthStateMachineInit(
+    IN PRTMP_ADAPTER pAd,
+    IN STATE_MACHINE *Sm,
+    OUT STATE_MACHINE_FUNC Trans[])
+{
+    StateMachineInit(Sm, Trans, MAX_AUTH_STATE, MAX_AUTH_MSG, (STATE_MACHINE_FUNC)Drop, AUTH_REQ_IDLE, AUTH_MACHINE_BASE);
+
+    // the first column
+    StateMachineSetAction(Sm, AUTH_REQ_IDLE, MT2_MLME_AUTH_REQ, (STATE_MACHINE_FUNC)MlmeAuthReqAction);
+
+    // the second column
+    StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_MLME_AUTH_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAuth);
+    StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_PEER_AUTH_EVEN, (STATE_MACHINE_FUNC)PeerAuthRspAtSeq2Action);
+    StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_AUTH_TIMEOUT, (STATE_MACHINE_FUNC)AuthTimeoutAction);
+
+    // the third column
+    StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_MLME_AUTH_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAuth);
+    StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_PEER_AUTH_EVEN, (STATE_MACHINE_FUNC)PeerAuthRspAtSeq4Action);
+    StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_AUTH_TIMEOUT, (STATE_MACHINE_FUNC)AuthTimeoutAction);
+
+	RTMPInitTimer(pAd, &pAd->MlmeAux.AuthTimer, GET_TIMER_FUNCTION(AuthTimeout), pAd, FALSE);
+}
+
+/*
+    ==========================================================================
+    Description:
+        function to be executed at timer thread when auth timer expires
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+VOID AuthTimeout(
+    IN PVOID SystemSpecific1,
+    IN PVOID FunctionContext,
+    IN PVOID SystemSpecific2,
+    IN PVOID SystemSpecific3)
+{
+    RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+    DBGPRINT(RT_DEBUG_TRACE,("AUTH - AuthTimeout\n"));
+
+	// Do nothing if the driver is starting halt state.
+	// This might happen when timer already been fired before cancel timer with mlmehalt
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+		return;
+
+	// send a de-auth to reset AP's state machine (Patch AP-Dir635)
+	if (pAd->Mlme.AuthMachine.CurrState == AUTH_WAIT_SEQ2)
+		Cls2errAction(pAd, pAd->MlmeAux.Bssid);
+
+
+    MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_AUTH_TIMEOUT, 0, NULL);
+    RT28XX_MLME_HANDLER(pAd);
+}
+
+
+/*
+    ==========================================================================
+    Description:
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+VOID MlmeAuthReqAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem)
+{
+    UCHAR              Addr[6];
+    USHORT             Alg, Seq, Status;
+    ULONG              Timeout;
+    HEADER_802_11      AuthHdr;
+    BOOLEAN            TimerCancelled;
+    NDIS_STATUS        NStatus;
+    PUCHAR             pOutBuffer = NULL;
+    ULONG              FrameLen = 0;
+
+	// Block all authentication request durning WPA block period
+	if (pAd->StaCfg.bBlockAssoc == TRUE)
+	{
+        DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Block Auth request durning WPA block period!\n"));
+        pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+        Status = MLME_STATE_MACHINE_REJECT;
+        MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+	}
+    else if(MlmeAuthReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr, &Timeout, &Alg))
+    {
+        // reset timer
+        RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &TimerCancelled);
+        COPY_MAC_ADDR(pAd->MlmeAux.Bssid, Addr);
+        pAd->MlmeAux.Alg  = Alg;
+        Seq = 1;
+        Status = MLME_SUCCESS;
+
+        NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
+        if(NStatus != NDIS_STATUS_SUCCESS)
+        {
+            DBGPRINT(RT_DEBUG_TRACE, ("AUTH - MlmeAuthReqAction(Alg:%d) allocate memory failed\n", Alg));
+            pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+            Status = MLME_FAIL_NO_RESOURCE;
+            MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+            return;
+        }
+
+        DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send AUTH request seq#1 (Alg=%d)...\n", Alg));
+        MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr, pAd->MlmeAux.Bssid);
+        MakeOutgoingFrame(pOutBuffer,           &FrameLen,
+                          sizeof(HEADER_802_11),&AuthHdr,
+                          2,                    &Alg,
+                          2,                    &Seq,
+                          2,                    &Status,
+                          END_OF_ARGS);
+        MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+    	MlmeFreeMemory(pAd, pOutBuffer);
+
+        RTMPSetTimer(&pAd->MlmeAux.AuthTimer, Timeout);
+        pAd->Mlme.AuthMachine.CurrState = AUTH_WAIT_SEQ2;
+    }
+    else
+    {
+        DBGPRINT_ERR(("AUTH - MlmeAuthReqAction() sanity check failed\n"));
+        pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+        Status = MLME_INVALID_FORMAT;
+        MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+    }
+}
+
+/*
+    ==========================================================================
+    Description:
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+VOID PeerAuthRspAtSeq2Action(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem)
+{
+    UCHAR         Addr2[MAC_ADDR_LEN];
+    USHORT        Seq, Status, RemoteStatus, Alg;
+    UCHAR         ChlgText[CIPHER_TEXT_LEN];
+    UCHAR         CyperChlgText[CIPHER_TEXT_LEN + 8 + 8];
+    UCHAR         Element[2];
+    HEADER_802_11 AuthHdr;
+    BOOLEAN       TimerCancelled;
+    PUCHAR        pOutBuffer = NULL;
+    NDIS_STATUS   NStatus;
+    ULONG         FrameLen = 0;
+    USHORT        Status2;
+
+    if (PeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status, ChlgText))
+    {
+        if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && Seq == 2)
+        {
+            DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Receive AUTH_RSP seq#2 to me (Alg=%d, Status=%d)\n", Alg, Status));
+            RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &TimerCancelled);
+
+            if (Status == MLME_SUCCESS)
+            {
+                // Authentication Mode "LEAP" has allow for CCX 1.X
+                if ((pAd->MlmeAux.Alg == Ndis802_11AuthModeOpen)
+#ifdef LEAP_SUPPORT
+					|| (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+#endif // LEAP_SUPPORT //
+				)
+                {
+                    pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+#ifdef LEAP_SUPPORT
+                    pAd->Mlme.LeapMachine.CurrState = LEAP_IDLE;
+#endif // LEAP_SUPPORT //
+                    MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+                }
+                else
+                {
+                    // 2. shared key, need to be challenged
+                    Seq++;
+                    RemoteStatus = MLME_SUCCESS;
+
+					// Get an unused nonpaged memory
+                    NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+                    if(NStatus != NDIS_STATUS_SUCCESS)
+                    {
+                        DBGPRINT(RT_DEBUG_TRACE, ("AUTH - PeerAuthRspAtSeq2Action() allocate memory fail\n"));
+                        pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+                        Status2 = MLME_FAIL_NO_RESOURCE;
+                        MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status2);
+                        return;
+                    }
+
+                    DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send AUTH request seq#3...\n"));
+                    MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr2, pAd->MlmeAux.Bssid);
+                    AuthHdr.FC.Wep = 1;
+                    // Encrypt challenge text & auth information
+                    RTMPInitWepEngine(
+                    	pAd,
+                    	pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
+                    	pAd->StaCfg.DefaultKeyId,
+                    	pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen,
+                    	CyperChlgText);
+
+					Alg = cpu2le16(*(USHORT *)&Alg);
+					Seq = cpu2le16(*(USHORT *)&Seq);
+					RemoteStatus= cpu2le16(*(USHORT *)&RemoteStatus);
+
+					RTMPEncryptData(pAd, (PUCHAR) &Alg, CyperChlgText + 4, 2);
+					RTMPEncryptData(pAd, (PUCHAR) &Seq, CyperChlgText + 6, 2);
+					RTMPEncryptData(pAd, (PUCHAR) &RemoteStatus, CyperChlgText + 8, 2);
+					Element[0] = 16;
+					Element[1] = 128;
+					RTMPEncryptData(pAd, Element, CyperChlgText + 10, 2);
+					RTMPEncryptData(pAd, ChlgText, CyperChlgText + 12, 128);
+					RTMPSetICV(pAd, CyperChlgText + 140);
+                    MakeOutgoingFrame(pOutBuffer,               &FrameLen,
+                                      sizeof(HEADER_802_11),    &AuthHdr,
+                                      CIPHER_TEXT_LEN + 16,     CyperChlgText,
+                                      END_OF_ARGS);
+                    MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+                	MlmeFreeMemory(pAd, pOutBuffer);
+
+                    RTMPSetTimer(&pAd->MlmeAux.AuthTimer, AUTH_TIMEOUT);
+                    pAd->Mlme.AuthMachine.CurrState = AUTH_WAIT_SEQ4;
+                }
+            }
+            else
+            {
+#ifdef LEAP_SUPPORT
+                if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+                {
+                    //Invalid Authentication possible rogue AP
+                    //Add this Ap to Rogue AP.
+                    RogueApTableSetEntry(pAd, &pAd->StaCfg.RogueApTab, Addr2, LEAP_REASON_INVALID_AUTH);
+				}
+#endif // LEAP_SUPPORT //
+                pAd->StaCfg.AuthFailReason = Status;
+                COPY_MAC_ADDR(pAd->StaCfg.AuthFailSta, Addr2);
+                pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+                MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+            }
+        }
+    }
+    else
+    {
+        DBGPRINT(RT_DEBUG_TRACE, ("AUTH - PeerAuthSanity() sanity check fail\n"));
+    }
+}
+
+/*
+    ==========================================================================
+    Description:
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+VOID PeerAuthRspAtSeq4Action(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem)
+{
+    UCHAR         Addr2[MAC_ADDR_LEN];
+    USHORT        Alg, Seq, Status;
+    CHAR          ChlgText[CIPHER_TEXT_LEN];
+    BOOLEAN       TimerCancelled;
+
+    if(PeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status, ChlgText))
+    {
+        if(MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && Seq == 4)
+        {
+            DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Receive AUTH_RSP seq#4 to me\n"));
+            RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &TimerCancelled);
+
+            if (Status != MLME_SUCCESS)
+            {
+                pAd->StaCfg.AuthFailReason = Status;
+                COPY_MAC_ADDR(pAd->StaCfg.AuthFailSta, Addr2);
+            }
+
+            pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+            MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+        }
+    }
+    else
+    {
+        DBGPRINT(RT_DEBUG_TRACE, ("AUTH - PeerAuthRspAtSeq4Action() sanity check fail\n"));
+    }
+}
+
+/*
+    ==========================================================================
+    Description:
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+VOID MlmeDeauthReqAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem)
+{
+    MLME_DEAUTH_REQ_STRUCT *pInfo;
+    HEADER_802_11 DeauthHdr;
+    PUCHAR        pOutBuffer = NULL;
+    NDIS_STATUS   NStatus;
+    ULONG         FrameLen = 0;
+    USHORT        Status;
+
+    pInfo = (MLME_DEAUTH_REQ_STRUCT *)Elem->Msg;
+
+    NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
+    if (NStatus != NDIS_STATUS_SUCCESS)
+    {
+        DBGPRINT(RT_DEBUG_TRACE, ("AUTH - MlmeDeauthReqAction() allocate memory fail\n"));
+        pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+        Status = MLME_FAIL_NO_RESOURCE;
+        MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2, &Status);
+        return;
+    }
+
+
+    DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send DE-AUTH request (Reason=%d)...\n", pInfo->Reason));
+    MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pInfo->Addr, pAd->MlmeAux.Bssid);
+    MakeOutgoingFrame(pOutBuffer,           &FrameLen,
+                      sizeof(HEADER_802_11),&DeauthHdr,
+                      2,                    &pInfo->Reason,
+                      END_OF_ARGS);
+    MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+	MlmeFreeMemory(pAd, pOutBuffer);
+
+    pAd->StaCfg.DeauthReason = pInfo->Reason;
+    COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pInfo->Addr);
+    pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+    Status = MLME_SUCCESS;
+    MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2, &Status);
+
+	// send wireless event - for deauthentication
+	if (pAd->CommonCfg.bWirelessEvent)
+		RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+}
+
+/*
+    ==========================================================================
+    Description:
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+VOID AuthTimeoutAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem)
+{
+    USHORT Status;
+    DBGPRINT(RT_DEBUG_TRACE, ("AUTH - AuthTimeoutAction\n"));
+    pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+    Status = MLME_REJ_TIMEOUT;
+    MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+}
+
+/*
+    ==========================================================================
+    Description:
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+VOID InvalidStateWhenAuth(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem)
+{
+    USHORT Status;
+    DBGPRINT(RT_DEBUG_TRACE, ("AUTH - InvalidStateWhenAuth (state=%ld), reset AUTH state machine\n", pAd->Mlme.AuthMachine.CurrState));
+    pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+    Status = MLME_STATE_MACHINE_REJECT;
+    MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+}
+
+/*
+    ==========================================================================
+    Description:
+        Some STA/AP
+    Note:
+        This action should never trigger AUTH state transition, therefore we
+        separate it from AUTH state machine, and make it as a standalone service
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+VOID Cls2errAction(
+    IN PRTMP_ADAPTER pAd,
+    IN PUCHAR pAddr)
+{
+    HEADER_802_11 DeauthHdr;
+    PUCHAR        pOutBuffer = NULL;
+    NDIS_STATUS   NStatus;
+    ULONG         FrameLen = 0;
+    USHORT        Reason = REASON_CLS2ERR;
+
+    NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
+    if (NStatus != NDIS_STATUS_SUCCESS)
+        return;
+
+    DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Class 2 error, Send DEAUTH frame...\n"));
+    MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pAddr, pAd->MlmeAux.Bssid);
+    MakeOutgoingFrame(pOutBuffer,           &FrameLen,
+                      sizeof(HEADER_802_11),&DeauthHdr,
+                      2,                    &Reason,
+                      END_OF_ARGS);
+    MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+	MlmeFreeMemory(pAd, pOutBuffer);
+
+    pAd->StaCfg.DeauthReason = Reason;
+    COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pAddr);
+}
+
+
diff --git a/drivers/staging/rt3070/sta/auth_rsp.c b/drivers/staging/rt3070/sta/auth_rsp.c
new file mode 100644
index 0000000..f7aa4b9
--- /dev/null
+++ b/drivers/staging/rt3070/sta/auth_rsp.c
@@ -0,0 +1,167 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	auth_rsp.c
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	John		2004-10-1		copy from RT2560
+*/
+#include "../rt_config.h"
+
+/*
+    ==========================================================================
+    Description:
+        authentication state machine init procedure
+    Parameters:
+        Sm - the state machine
+
+	IRQL = PASSIVE_LEVEL
+
+    ==========================================================================
+ */
+VOID AuthRspStateMachineInit(
+    IN PRTMP_ADAPTER pAd,
+    IN PSTATE_MACHINE Sm,
+    IN STATE_MACHINE_FUNC Trans[])
+{
+    StateMachineInit(Sm, Trans, MAX_AUTH_RSP_STATE, MAX_AUTH_RSP_MSG, (STATE_MACHINE_FUNC)Drop, AUTH_RSP_IDLE, AUTH_RSP_MACHINE_BASE);
+
+    // column 1
+    StateMachineSetAction(Sm, AUTH_RSP_IDLE, MT2_PEER_DEAUTH, (STATE_MACHINE_FUNC)PeerDeauthAction);
+
+    // column 2
+    StateMachineSetAction(Sm, AUTH_RSP_WAIT_CHAL, MT2_PEER_DEAUTH, (STATE_MACHINE_FUNC)PeerDeauthAction);
+
+}
+
+/*
+    ==========================================================================
+    Description:
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+*/
+VOID PeerAuthSimpleRspGenAndSend(
+    IN PRTMP_ADAPTER pAd,
+    IN PHEADER_802_11 pHdr80211,
+    IN USHORT Alg,
+    IN USHORT Seq,
+    IN USHORT Reason,
+    IN USHORT Status)
+{
+    HEADER_802_11     AuthHdr;
+    ULONG             FrameLen = 0;
+    PUCHAR            pOutBuffer = NULL;
+    NDIS_STATUS       NStatus;
+
+    if (Reason != MLME_SUCCESS)
+    {
+        DBGPRINT(RT_DEBUG_TRACE, ("Peer AUTH fail...\n"));
+        return;
+    }
+
+	//Get an unused nonpaged memory
+    NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+    if (NStatus != NDIS_STATUS_SUCCESS)
+        return;
+
+    DBGPRINT(RT_DEBUG_TRACE, ("Send AUTH response (seq#2)...\n"));
+    MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, pHdr80211->Addr2, pAd->MlmeAux.Bssid);
+    MakeOutgoingFrame(pOutBuffer,               &FrameLen,
+                      sizeof(HEADER_802_11),    &AuthHdr,
+                      2,                        &Alg,
+                      2,                        &Seq,
+                      2,                        &Reason,
+                      END_OF_ARGS);
+    MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+	MlmeFreeMemory(pAd, pOutBuffer);
+}
+
+/*
+    ==========================================================================
+    Description:
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+*/
+VOID PeerDeauthAction(
+    IN PRTMP_ADAPTER pAd,
+    IN PMLME_QUEUE_ELEM Elem)
+{
+    UCHAR       Addr2[MAC_ADDR_LEN];
+    USHORT      Reason;
+
+    if (PeerDeauthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason))
+    {
+        if (INFRA_ON(pAd) && MAC_ADDR_EQUAL(Addr2, pAd->CommonCfg.Bssid))
+        {
+            DBGPRINT(RT_DEBUG_TRACE,("AUTH_RSP - receive DE-AUTH from our AP (Reason=%d)\n", Reason));
+
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+            {
+                union iwreq_data    wrqu;
+                memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+                wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+            }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+
+			// send wireless event - for deauthentication
+			if (pAd->CommonCfg.bWirelessEvent)
+				RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+
+            LinkDown(pAd, TRUE);
+
+            // Authentication Mode Cisco_LEAP has start a timer
+            // We should cancel it if using LEAP
+#ifdef LEAP_SUPPORT
+            if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+            {
+                RTMPCancelTimer(&pAd->StaCfg.LeapAuthTimer, &TimerCancelled);
+                //Check is it mach the LEAP Authentication failed as possible a Rogue AP
+                //on it's PortSecured not equal to WPA_802_1X_PORT_SECURED while process the Authenticaton.
+                if ((pAd->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED) && (pAd->Mlme.LeapMachine.CurrState != LEAP_IDLE))
+                {
+                    RogueApTableSetEntry(pAd, &pAd->StaCfg.RogueApTab, Addr2, LEAP_REASON_AUTH_TIMEOUT);
+                }
+            }
+#endif // LEAP_SUPPORT //
+        }
+    }
+    else
+    {
+        DBGPRINT(RT_DEBUG_TRACE,("AUTH_RSP - PeerDeauthAction() sanity check fail\n"));
+    }
+}
+
diff --git a/drivers/staging/rt3070/sta/connect.c b/drivers/staging/rt3070/sta/connect.c
new file mode 100644
index 0000000..152c0bd
--- /dev/null
+++ b/drivers/staging/rt3070/sta/connect.c
@@ -0,0 +1,2857 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	connect.c
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	John			2004-08-08			Major modification from RT2560
+*/
+#include "../rt_config.h"
+
+UCHAR	CipherSuiteWpaNoneTkip[] = {
+		0x00, 0x50, 0xf2, 0x01,	// oui
+		0x01, 0x00,				// Version
+		0x00, 0x50, 0xf2, 0x02,	// Multicast
+		0x01, 0x00,				// Number of unicast
+		0x00, 0x50, 0xf2, 0x02,	// unicast
+		0x01, 0x00,				// number of authentication method
+		0x00, 0x50, 0xf2, 0x00	// authentication
+		};
+UCHAR	CipherSuiteWpaNoneTkipLen = (sizeof(CipherSuiteWpaNoneTkip) / sizeof(UCHAR));
+
+UCHAR	CipherSuiteWpaNoneAes[] = {
+		0x00, 0x50, 0xf2, 0x01,	// oui
+		0x01, 0x00,				// Version
+		0x00, 0x50, 0xf2, 0x04,	// Multicast
+		0x01, 0x00,				// Number of unicast
+		0x00, 0x50, 0xf2, 0x04,	// unicast
+		0x01, 0x00,				// number of authentication method
+		0x00, 0x50, 0xf2, 0x00	// authentication
+		};
+UCHAR	CipherSuiteWpaNoneAesLen = (sizeof(CipherSuiteWpaNoneAes) / sizeof(UCHAR));
+
+// The following MACRO is called after 1. starting an new IBSS, 2. succesfully JOIN an IBSS,
+// or 3. succesfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS
+// All settings successfuly negotiated furing MLME state machines become final settings
+// and are copied to pAd->StaActive
+#define COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd)                                 \
+{                                                                                       \
+	(_pAd)->CommonCfg.SsidLen = (_pAd)->MlmeAux.SsidLen;                                \
+	NdisMoveMemory((_pAd)->CommonCfg.Ssid, (_pAd)->MlmeAux.Ssid, (_pAd)->MlmeAux.SsidLen); \
+	COPY_MAC_ADDR((_pAd)->CommonCfg.Bssid, (_pAd)->MlmeAux.Bssid);                      \
+	(_pAd)->CommonCfg.Channel = (_pAd)->MlmeAux.Channel;                                \
+	(_pAd)->CommonCfg.CentralChannel = (_pAd)->MlmeAux.CentralChannel;                  \
+	(_pAd)->StaActive.Aid = (_pAd)->MlmeAux.Aid;                                        \
+	(_pAd)->StaActive.AtimWin = (_pAd)->MlmeAux.AtimWin;                                \
+	(_pAd)->StaActive.CapabilityInfo = (_pAd)->MlmeAux.CapabilityInfo;                  \
+	(_pAd)->CommonCfg.BeaconPeriod = (_pAd)->MlmeAux.BeaconPeriod;                      \
+	(_pAd)->StaActive.CfpMaxDuration = (_pAd)->MlmeAux.CfpMaxDuration;                  \
+	(_pAd)->StaActive.CfpPeriod = (_pAd)->MlmeAux.CfpPeriod;                            \
+	(_pAd)->StaActive.SupRateLen = (_pAd)->MlmeAux.SupRateLen;                          \
+	NdisMoveMemory((_pAd)->StaActive.SupRate, (_pAd)->MlmeAux.SupRate, (_pAd)->MlmeAux.SupRateLen);\
+	(_pAd)->StaActive.ExtRateLen = (_pAd)->MlmeAux.ExtRateLen;                          \
+	NdisMoveMemory((_pAd)->StaActive.ExtRate, (_pAd)->MlmeAux.ExtRate, (_pAd)->MlmeAux.ExtRateLen);\
+	NdisMoveMemory(&(_pAd)->CommonCfg.APEdcaParm, &(_pAd)->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));\
+	NdisMoveMemory(&(_pAd)->CommonCfg.APQosCapability, &(_pAd)->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));\
+	NdisMoveMemory(&(_pAd)->CommonCfg.APQbssLoad, &(_pAd)->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));\
+	COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].Addr, (_pAd)->MlmeAux.Bssid);      \
+	(_pAd)->MacTab.Content[BSSID_WCID].Aid = (_pAd)->MlmeAux.Aid;                       \
+	(_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = (_pAd)->StaCfg.PairCipher;\
+	COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.BssId, (_pAd)->MlmeAux.Bssid);\
+	(_pAd)->MacTab.Content[BSSID_WCID].RateLen = (_pAd)->StaActive.SupRateLen + (_pAd)->StaActive.ExtRateLen;\
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = PASSIVE_LEVEL
+
+	==========================================================================
+*/
+VOID MlmeCntlInit(
+	IN PRTMP_ADAPTER pAd,
+	IN STATE_MACHINE *S,
+	OUT STATE_MACHINE_FUNC Trans[])
+{
+	// Control state machine differs from other state machines, the interface
+	// follows the standard interface
+	pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+*/
+VOID MlmeCntlMachinePerformAction(
+	IN PRTMP_ADAPTER pAd,
+	IN STATE_MACHINE *S,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	switch(pAd->Mlme.CntlMachine.CurrState)
+	{
+		case CNTL_IDLE:
+			{
+				CntlIdleProc(pAd, Elem);
+			}
+			break;
+		case CNTL_WAIT_DISASSOC:
+			CntlWaitDisassocProc(pAd, Elem);
+			break;
+		case CNTL_WAIT_JOIN:
+			CntlWaitJoinProc(pAd, Elem);
+			break;
+
+		// CNTL_WAIT_REASSOC is the only state in CNTL machine that does
+		// not triggered directly or indirectly by "RTMPSetInformation(OID_xxx)".
+		// Therefore not protected by NDIS's "only one outstanding OID request"
+		// rule. Which means NDIS may SET OID in the middle of ROAMing attempts.
+		// Current approach is to block new SET request at RTMPSetInformation()
+		// when CntlMachine.CurrState is not CNTL_IDLE
+		case CNTL_WAIT_REASSOC:
+			CntlWaitReassocProc(pAd, Elem);
+			break;
+
+		case CNTL_WAIT_START:
+			CntlWaitStartProc(pAd, Elem);
+			break;
+		case CNTL_WAIT_AUTH:
+			CntlWaitAuthProc(pAd, Elem);
+			break;
+		case CNTL_WAIT_AUTH2:
+			CntlWaitAuthProc2(pAd, Elem);
+			break;
+		case CNTL_WAIT_ASSOC:
+			CntlWaitAssocProc(pAd, Elem);
+			break;
+
+		case CNTL_WAIT_OID_LIST_SCAN:
+			if(Elem->MsgType == MT2_SCAN_CONF)
+			{
+				// Resume TxRing after SCANING complete. We hope the out-of-service time
+				// won't be too long to let upper layer time-out the waiting frames
+				RTMPResumeMsduTransmission(pAd);
+				if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED)
+				{
+					// Cisco scan request is finished, prepare beacon report
+					MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
+				}
+				pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+
+                //
+				// Set LED status to previous status.
+				//
+				if (pAd->bLedOnScanning)
+				{
+					pAd->bLedOnScanning = FALSE;
+					RTMPSetLED(pAd, pAd->LedStatus);
+				}
+#ifdef DOT11N_DRAFT3
+				// AP sent a 2040Coexistence mgmt frame, then station perform a scan, and then send back the respone.
+				if (pAd->CommonCfg.BSSCoexist2040.field.InfoReq == 1)
+				{
+					Update2040CoexistFrameAndNotify(pAd, BSSID_WCID, TRUE);
+				}
+#endif // DOT11N_DRAFT3 //
+			}
+			break;
+
+		case CNTL_WAIT_OID_DISASSOC:
+			if (Elem->MsgType == MT2_DISASSOC_CONF)
+			{
+				LinkDown(pAd, FALSE);
+				pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+			}
+			break;
+#ifdef RT2870
+		//
+		// This state is for that we want to connect to an AP but
+		// it didn't find on BSS List table. So we need to scan the air first,
+		// after that we can try to connect to the desired AP if available.
+		//
+		case CNTL_WAIT_SCAN_FOR_CONNECT:
+			if(Elem->MsgType == MT2_SCAN_CONF)
+			{
+				// Resume TxRing after SCANING complete. We hope the out-of-service time
+				// won't be too long to let upper layer time-out the waiting frames
+				RTMPResumeMsduTransmission(pAd);
+#ifdef CCX_SUPPORT
+				if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED)
+				{
+					// Cisco scan request is finished, prepare beacon report
+					MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
+				}
+#endif // CCX_SUPPORT //
+				pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+
+				//
+				// Check if we can connect to.
+				//
+				BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
+				if (pAd->MlmeAux.SsidBssTab.BssNr > 0)
+				{
+					MlmeAutoReconnectLastSSID(pAd);
+				}
+			}
+			break;
+#endif // RT2870 //
+		default:
+			DBGPRINT_ERR(("!ERROR! CNTL - Illegal message type(=%ld)", Elem->MsgType));
+			break;
+	}
+}
+
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+*/
+VOID CntlIdleProc(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	MLME_DISASSOC_REQ_STRUCT   DisassocReq;
+
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
+		return;
+
+	switch(Elem->MsgType)
+	{
+		case OID_802_11_SSID:
+			CntlOidSsidProc(pAd, Elem);
+			break;
+
+		case OID_802_11_BSSID:
+			CntlOidRTBssidProc(pAd,Elem);
+			break;
+
+		case OID_802_11_BSSID_LIST_SCAN:
+			CntlOidScanProc(pAd,Elem);
+			break;
+
+		case OID_802_11_DISASSOCIATE:
+#ifdef RALINK_ATE
+			if(ATE_ON(pAd))
+			{
+				DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
+				break;
+			}
+#endif // RALINK_ATE //
+			DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
+			MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
+			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
+#ifdef WPA_SUPPLICANT_SUPPORT
+            if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE_WITH_WEB_UI)
+#endif // WPA_SUPPLICANT_SUPPORT //
+            {
+    			// Set the AutoReconnectSsid to prevent it reconnect to old SSID
+    			// Since calling this indicate user don't want to connect to that SSID anymore.
+    			pAd->MlmeAux.AutoReconnectSsidLen= 32;
+    			NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
+            }
+			break;
+
+		case MT2_MLME_ROAMING_REQ:
+			CntlMlmeRoamingProc(pAd, Elem);
+			break;
+
+        case OID_802_11_MIC_FAILURE_REPORT_FRAME:
+            WpaMicFailureReportFrame(pAd, Elem);
+            break;
+
+#ifdef QOS_DLS_SUPPORT
+		case RT_OID_802_11_SET_DLS_PARAM:
+			CntlOidDLSSetupProc(pAd, Elem);
+			break;
+#endif // QOS_DLS_SUPPORT //
+
+		default:
+			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",Elem->MsgType));
+			break;
+	}
+}
+
+VOID CntlOidScanProc(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	MLME_SCAN_REQ_STRUCT       ScanReq;
+	ULONG                      BssIdx = BSS_NOT_FOUND;
+	BSS_ENTRY                  CurrBss;
+
+#ifdef RALINK_ATE
+/* Disable scanning when ATE is running. */
+	if (ATE_ON(pAd))
+		return;
+#endif // RALINK_ATE //
+
+
+	// record current BSS if network is connected.
+	// 2003-2-13 do not include current IBSS if this is the only STA in this IBSS.
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+	{
+		BssIdx = BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Channel);
+		if (BssIdx != BSS_NOT_FOUND)
+		{
+			NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
+		}
+	}
+
+	// clean up previous SCAN result, add current BSS back to table if any
+	BssTableInit(&pAd->ScanTab);
+	if (BssIdx != BSS_NOT_FOUND)
+	{
+		// DDK Note: If the NIC is associated with a particular BSSID and SSID
+		//    that are not contained in the list of BSSIDs generated by this scan, the
+		//    BSSID description of the currently associated BSSID and SSID should be
+		//    appended to the list of BSSIDs in the NIC's database.
+		// To ensure this, we append this BSS as the first entry in SCAN result
+		NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss, sizeof(BSS_ENTRY));
+		pAd->ScanTab.BssNr = 1;
+	}
+
+	ScanParmFill(pAd, &ScanReq, "", 0, BSS_ANY, SCAN_ACTIVE);
+	MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
+		sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
+	pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
+}
+
+/*
+	==========================================================================
+	Description:
+		Before calling this routine, user desired SSID should already been
+		recorded in CommonCfg.Ssid[]
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+*/
+VOID CntlOidSsidProc(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM * Elem)
+{
+	PNDIS_802_11_SSID          pOidSsid = (NDIS_802_11_SSID *)Elem->Msg;
+	MLME_DISASSOC_REQ_STRUCT   DisassocReq;
+	ULONG					   Now;
+
+	// Step 1. record the desired user settings to MlmeAux
+	NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
+	NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
+	pAd->MlmeAux.SsidLen = (UCHAR)pOidSsid->SsidLength;
+	NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
+	pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
+
+
+	//
+	// Update Reconnect Ssid, that user desired to connect.
+	//
+	NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
+	NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
+	pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
+
+	// step 2. find all matching BSS in the lastest SCAN result (inBssTab)
+	//    & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order
+	BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
+			pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
+	NdisGetSystemUpTime(&Now);
+
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
+		(pAd->CommonCfg.SsidLen == pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen) &&
+		NdisEqualMemory(pAd->CommonCfg.Ssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid, pAd->CommonCfg.SsidLen) &&
+		MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid))
+	{
+		// Case 1. already connected with an AP who has the desired SSID
+		//         with highest RSSI
+
+		// Add checking Mode "LEAP" for CCX 1.0
+		if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
+			 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+			 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
+			 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
+#ifdef LEAP_SUPPORT
+			 || (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+#endif // LEAP_SUPPORT //
+			 ) &&
+			(pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
+		{
+			// case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo
+			//          connection process
+			DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
+			DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
+			MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
+						sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
+			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
+		}
+		else if (pAd->bConfigChanged == TRUE)
+		{
+			// case 1.2 Important Config has changed, we have to reconnect to the same AP
+			DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n"));
+			DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
+			MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
+						sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
+			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
+		}
+		else
+		{
+			// case 1.3. already connected to the SSID with highest RSSI.
+			DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n"));
+			//
+			// (HCT 12.1) 1c_wlan_mediaevents required
+			// media connect events are indicated when associating with the same AP
+			//
+			if (INFRA_ON(pAd))
+			{
+				//
+				// Since MediaState already is NdisMediaStateConnected
+				// We just indicate the connect event again to meet the WHQL required.
+				//
+				pAd->IndicateMediaState = NdisMediaStateConnected;
+				RTMP_IndicateMediaState(pAd);
+                pAd->ExtraInfo = GENERAL_LINK_UP;   // Update extra information to link is up
+			}
+
+			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+            {
+                union iwreq_data    wrqu;
+
+                memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+                memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
+                wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+
+            }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+		}
+	}
+	else if (INFRA_ON(pAd))
+	{
+		//
+		// For RT61
+		// [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
+		// RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect
+		// But media status is connected, so the SSID not report correctly.
+		//
+		if (!SSID_EQUAL(pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen))
+		{
+			//
+			// Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event.
+			//
+			pAd->MlmeAux.CurrReqIsFromNdis = TRUE;
+		}
+		// case 2. active INFRA association existent
+		//    roaming is done within miniport driver, nothing to do with configuration
+		//    utility. so upon a new SET(OID_802_11_SSID) is received, we just
+		//    disassociate with the current associated AP,
+		//    then perform a new association with this new SSID, no matter the
+		//    new/old SSID are the same or not.
+		DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
+		DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
+		MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
+					sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
+		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
+	}
+	else
+	{
+		if (ADHOC_ON(pAd))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
+			LinkDown(pAd, FALSE);
+			OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
+			pAd->IndicateMediaState = NdisMediaStateDisconnected;
+			RTMP_IndicateMediaState(pAd);
+            pAd->ExtraInfo = GENERAL_LINK_DOWN;
+			DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
+		}
+
+		if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) &&
+			(pAd->StaCfg.bAutoReconnect == TRUE) &&
+			(pAd->MlmeAux.BssType == BSS_INFRA) &&
+			(MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen) == TRUE)
+			)
+		{
+			MLME_SCAN_REQ_STRUCT       ScanReq;
+
+			DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
+			ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
+			MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
+			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
+			// Reset Missed scan number
+			pAd->StaCfg.LastScanTime = Now;
+		}
+		else
+		{
+			pAd->MlmeAux.BssIdx = 0;
+			IterateOnBssTab(pAd);
+		}
+	}
+}
+
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+*/
+VOID CntlOidRTBssidProc(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM * Elem)
+{
+	ULONG       BssIdx;
+	PUCHAR      pOidBssid = (PUCHAR)Elem->Msg;
+	MLME_DISASSOC_REQ_STRUCT    DisassocReq;
+	MLME_JOIN_REQ_STRUCT        JoinReq;
+
+#ifdef RALINK_ATE
+/* No need to perform this routine when ATE is running. */
+	if (ATE_ON(pAd))
+		return;
+#endif // RALINK_ATE //
+
+	// record user desired settings
+	COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
+	pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
+
+	//
+	// Update Reconnect Ssid, that user desired to connect.
+	//
+	NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
+	pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
+	NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
+
+	// find the desired BSS in the latest SCAN result table
+	BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
+	if (BssIdx == BSS_NOT_FOUND)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
+		pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+		return;
+	}
+
+	// copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why?
+	// Because we need this entry to become the JOIN target in later on SYNC state machine
+	pAd->MlmeAux.BssIdx = 0;
+	pAd->MlmeAux.SsidBssTab.BssNr = 1;
+	NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
+
+	//pAd->MlmeAux.AutoReconnectSsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
+	//NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->ScanTab.BssEntry[BssIdx].SsidLen);
+
+	// Add SSID into MlmeAux for site surey joining hidden SSID
+	//pAd->MlmeAux.SsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
+	//NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->MlmeAux.SsidLen);
+
+	// 2002-11-26 skip the following checking. i.e. if user wants to re-connect to same AP
+	//   we just follow normal procedure. The reason of user doing this may because he/she changed
+	//   AP to another channel, but we still received BEACON from it thus don't claim Link Down.
+	//   Since user knows he's changed AP channel, he'll re-connect again. By skipping the following
+	//   checking, we'll disassociate then re-do normal association with this AP at the new channel.
+	// 2003-1-6 Re-enable this feature based on microsoft requirement which prefer not to re-do
+	//   connection when setting the same BSSID.
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
+		MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pOidBssid))
+	{
+		// already connected to the same BSSID, go back to idle state directly
+		DBGPRINT(RT_DEBUG_TRACE, ("CNTL - already in this BSSID. ignore this SET_BSSID request\n"));
+		pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+            {
+                union iwreq_data    wrqu;
+
+                memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+                memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
+                wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+
+            }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+	}
+	else
+	{
+		if (INFRA_ON(pAd))
+		{
+			// disassoc from current AP first
+			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - disassociate with current AP ...\n"));
+			DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
+			MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
+						sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
+
+			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
+		}
+		else
+		{
+			if (ADHOC_ON(pAd))
+			{
+				DBGPRINT(RT_DEBUG_TRACE, ("CNTL - drop current ADHOC\n"));
+				LinkDown(pAd, FALSE);
+				OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
+				pAd->IndicateMediaState = NdisMediaStateDisconnected;
+				RTMP_IndicateMediaState(pAd);
+                pAd->ExtraInfo = GENERAL_LINK_DOWN;
+				DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
+			}
+
+			// Change the wepstatus to original wepstatus
+			pAd->StaCfg.WepStatus   = pAd->StaCfg.OrigWepStatus;
+			pAd->StaCfg.PairCipher  = pAd->StaCfg.OrigWepStatus;
+			pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
+
+			// Check cipher suite, AP must have more secured cipher than station setting
+			// Set the Pairwise and Group cipher to match the intended AP setting
+			// We can only connect to AP with less secured cipher setting
+			if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
+			{
+				pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.GroupCipher;
+
+				if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher)
+					pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher;
+				else if (pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
+					pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux;
+				else	// There is no PairCipher Aux, downgrade our capability to TKIP
+					pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
+			}
+			else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+			{
+				pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.GroupCipher;
+
+				if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher)
+					pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher;
+				else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
+					pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux;
+				else	// There is no PairCipher Aux, downgrade our capability to TKIP
+					pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
+
+				// RSN capability
+				pAd->StaCfg.RsnCapability = pAd->ScanTab.BssEntry[BssIdx].WPA2.RsnCapability;
+			}
+
+			// Set Mix cipher flag
+			pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
+			if (pAd->StaCfg.bMixCipher == TRUE)
+			{
+				// If mix cipher, re-build RSNIE
+				RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
+			}
+			// No active association, join the BSS immediately
+			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
+				pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5]));
+
+			JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
+			MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
+
+			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
+		}
+	}
+}
+
+// Roaming is the only external request triggering CNTL state machine
+// despite of other "SET OID" operation. All "SET OID" related oerations
+// happen in sequence, because no other SET OID will be sent to this device
+// until the the previous SET operation is complete (successful o failed).
+// So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
+// or been corrupted by other "SET OID"?
+//
+// IRQL = DISPATCH_LEVEL
+VOID CntlMlmeRoamingProc(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	// TODO:
+	// AP in different channel may show lower RSSI than actual value??
+	// should we add a weighting factor to compensate it?
+	DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n"));
+
+	NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab));
+	pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
+
+	BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
+	pAd->MlmeAux.BssIdx = 0;
+	IterateOnBssTab(pAd);
+}
+
+#ifdef QOS_DLS_SUPPORT
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+*/
+VOID CntlOidDLSSetupProc(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	PRT_802_11_DLS		pDLS = (PRT_802_11_DLS)Elem->Msg;
+	MLME_DLS_REQ_STRUCT	MlmeDlsReq;
+	INT					i;
+	USHORT				reason = REASON_UNSPECIFY;
+
+	DBGPRINT(RT_DEBUG_TRACE,("CNTL - (OID set %02x:%02x:%02x:%02x:%02x:%02x with Valid=%d, Status=%d, TimeOut=%d, CountDownTimer=%d)\n",
+		pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5],
+		pDLS->Valid, pDLS->Status, pDLS->TimeOut, pDLS->CountDownTimer));
+
+	if (!pAd->CommonCfg.bDLSCapable)
+		return;
+
+	// DLS will not be supported when Adhoc mode
+	if (INFRA_ON(pAd))
+	{
+		for (i = 0; i < MAX_NUM_OF_DLS_ENTRY; i++)
+		{
+			if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
+				(pDLS->TimeOut == pAd->StaCfg.DLSEntry[i].TimeOut) && MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
+			{
+				// 1. Same setting, just drop it
+				DBGPRINT(RT_DEBUG_TRACE,("CNTL - setting unchanged\n"));
+				break;
+			}
+			else if (!pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
+				MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
+			{
+				// 2. Disable DLS link case, just tear down DLS link
+				reason = REASON_QOS_UNWANTED_MECHANISM;
+				pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
+				pAd->StaCfg.DLSEntry[i].Status	= DLS_NONE;
+				DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+				MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+				DBGPRINT(RT_DEBUG_TRACE,("CNTL - start tear down procedure\n"));
+				break;
+			}
+			else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid && !pAd->StaCfg.DLSEntry[i].Valid)
+			{
+				// 3. Enable case, start DLS setup procedure
+				NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, sizeof(RT_802_11_DLS_UI));
+
+				//Update countdown timer
+				pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
+				DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+				MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+				DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS setup case\n"));
+				break;
+			}
+			else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
+				(pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) && !MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
+			{
+				// 4. update mac case, tear down old DLS and setup new DLS
+				reason = REASON_QOS_UNWANTED_MECHANISM;
+				pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
+				pAd->StaCfg.DLSEntry[i].Status	= DLS_NONE;
+				DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+				MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+				NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, sizeof(RT_802_11_DLS_UI));
+				DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+				MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+				DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS tear down and restart case\n"));
+				break;
+			}
+			else if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
+				MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr) && (pAd->StaCfg.DLSEntry[i].TimeOut != pDLS->TimeOut))
+			{
+				// 5. update timeout case, start DLS setup procedure (no tear down)
+				pAd->StaCfg.DLSEntry[i].TimeOut	= pDLS->TimeOut;
+				//Update countdown timer
+				pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
+				DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+				MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+				DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS update timeout case\n"));
+				break;
+			}
+			else if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
+				(pAd->StaCfg.DLSEntry[i].Status != DLS_FINISH) && MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
+			{
+				// 6. re-setup case, start DLS setup procedure (no tear down)
+				DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+				MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+				DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS retry setup procedure\n"));
+				break;
+			}
+			else
+			{
+				DBGPRINT(RT_DEBUG_WARN,("CNTL - DLS not changed in entry - %d - Valid=%d, Status=%d, TimeOut=%d\n",
+					i, pAd->StaCfg.DLSEntry[i].Valid, pAd->StaCfg.DLSEntry[i].Status, pAd->StaCfg.DLSEntry[i].TimeOut));
+			}
+		}
+	}
+}
+#endif // QOS_DLS_SUPPORT //
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+*/
+VOID CntlWaitDisassocProc(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	MLME_START_REQ_STRUCT     StartReq;
+
+	if (Elem->MsgType == MT2_DISASSOC_CONF)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
+
+	    if (pAd->CommonCfg.bWirelessEvent)
+		{
+			RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+		}
+
+		LinkDown(pAd, FALSE);
+
+		// case 1. no matching BSS, and user wants ADHOC, so we just start a new one
+		if ((pAd->MlmeAux.SsidBssTab.BssNr==0) && (pAd->StaCfg.BssType == BSS_ADHOC))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
+			StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
+			MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
+			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
+		}
+		// case 2. try each matched BSS
+		else
+		{
+			pAd->MlmeAux.BssIdx = 0;
+
+			IterateOnBssTab(pAd);
+		}
+	}
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+*/
+VOID CntlWaitJoinProc(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	USHORT                      Reason;
+	MLME_AUTH_REQ_STRUCT        AuthReq;
+
+	if (Elem->MsgType == MT2_JOIN_CONF)
+	{
+		NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
+		if (Reason == MLME_SUCCESS)
+		{
+			// 1. joined an IBSS, we are pretty much done here
+			if (pAd->MlmeAux.BssType == BSS_ADHOC)
+			{
+			    //
+				// 5G bands rules of Japan:
+				// Ad hoc must be disabled in W53(ch52,56,60,64) channels.
+				//
+				if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
+                      RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
+				   )
+				{
+					pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+					DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
+					return;
+				}
+
+				LinkUp(pAd, BSS_ADHOC);
+				pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+				DBGPRINT(RT_DEBUG_TRACE, ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
+				pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
+				pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
+
+                pAd->IndicateMediaState = NdisMediaStateConnected;
+                pAd->ExtraInfo = GENERAL_LINK_UP;
+			}
+			// 2. joined a new INFRA network, start from authentication
+			else
+			{
+#ifdef LEAP_SUPPORT
+				// Add AuthMode "LEAP" for CCX 1.X
+				if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+				{
+					AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
+				}
+				else
+#endif // LEAP_SUPPORT //
+				{
+					// either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
+					if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
+						(pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
+					{
+						AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
+					}
+					else
+					{
+						AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
+					}
+				}
+				MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
+							sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
+
+				pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
+			}
+		}
+		else
+		{
+			// 3. failed, try next BSS
+			pAd->MlmeAux.BssIdx++;
+			IterateOnBssTab(pAd);
+		}
+	}
+}
+
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+*/
+VOID CntlWaitStartProc(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	USHORT      Result;
+
+	if (Elem->MsgType == MT2_START_CONF)
+	{
+		NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
+		if (Result == MLME_SUCCESS)
+		{
+		    //
+			// 5G bands rules of Japan:
+			// Ad hoc must be disabled in W53(ch52,56,60,64) channels.
+			//
+			if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
+                  RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
+			   )
+			{
+				pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+				DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
+				return;
+			}
+#ifdef DOT11_N_SUPPORT
+			if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+			{
+				N_ChannelCheck(pAd);
+				SetCommonHT(pAd);
+				NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &pAd->CommonCfg.AddHTInfo, sizeof(ADD_HT_INFO_IE));
+				RTMPCheckHt(pAd, BSSID_WCID, &pAd->CommonCfg.HtCapability, &pAd->CommonCfg.AddHTInfo);
+				pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
+				NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
+				NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], &pAd->CommonCfg.HtCapability.MCSSet[0], 16);
+				COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
+
+				if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth  == BW_40) &&
+					(pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
+				{
+					pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel + 2;
+				}
+				else if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth  == BW_40) &&
+						 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
+				{
+					pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel - 2;
+				}
+			}
+			else
+#endif // DOT11_N_SUPPORT //
+			{
+				pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
+			}
+			LinkUp(pAd, BSS_ADHOC);
+			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+			// Before send beacon, driver need do radar detection
+			if ((pAd->CommonCfg.Channel > 14 )
+				&& (pAd->CommonCfg.bIEEE80211H == 1)
+				&& RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
+			{
+				pAd->CommonCfg.RadarDetect.RDMode = RD_SILENCE_MODE;
+				pAd->CommonCfg.RadarDetect.RDCount = 0;
+#ifdef DFS_SUPPORT
+				BbpRadarDetectionStart(pAd);
+#endif // DFS_SUPPORT //
+			}
+
+			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
+				pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
+				pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
+		}
+		else
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Start IBSS fail. BUG!!!!!\n"));
+			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+		}
+	}
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+*/
+VOID CntlWaitAuthProc(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	USHORT                       Reason;
+	MLME_ASSOC_REQ_STRUCT        AssocReq;
+	MLME_AUTH_REQ_STRUCT         AuthReq;
+
+	if (Elem->MsgType == MT2_AUTH_CONF)
+	{
+		NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
+		if (Reason == MLME_SUCCESS)
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
+			AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
+						  ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
+
+#ifdef LEAP_SUPPORT
+			//
+			// Cisco Leap CCKM supported Re-association.
+			//
+			if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
+			{
+				//if CCKM is turn on , that's mean Fast Reauthentication
+				//Use CCKM Reassociation instead of normal association for Fast Roaming.
+				MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
+							sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
+
+				pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
+			}
+			else
+#endif // LEAP_SUPPORT //
+			{
+				MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
+							sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
+
+				pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
+			}
+		}
+		else
+		{
+			// This fail may because of the AP already keep us in its MAC table without
+			// ageing-out. The previous authentication attempt must have let it remove us.
+			// so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
+			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try again...\n"));
+#ifdef LEAP_SUPPORT
+			//Add AuthMode "LEAP" for CCX 1.X
+			if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+			{
+				AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
+			}
+			else
+#endif // LEAP_SUPPORT //
+			{
+				if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
+					(pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
+				{
+					// either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
+					AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
+				}
+				else
+				{
+					AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
+				}
+			}
+			MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
+						sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
+
+			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
+		}
+	}
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+*/
+VOID CntlWaitAuthProc2(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	USHORT                       Reason;
+	MLME_ASSOC_REQ_STRUCT        AssocReq;
+	MLME_AUTH_REQ_STRUCT         AuthReq;
+
+	if (Elem->MsgType == MT2_AUTH_CONF)
+	{
+		NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
+		if (Reason == MLME_SUCCESS)
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
+			AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
+						  ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
+			MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
+						sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
+
+			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
+		}
+		else
+		{
+#ifdef LEAP_SUPPORT
+			// Process LEAP first, since it use different control variable
+			// We don't want to affect other poven operation
+			if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+			{
+				// LEAP Auth not success, try next BSS
+				DBGPRINT(RT_DEBUG_TRACE, ("CNTL - *LEAP* AUTH FAIL, give up; try next BSS\n"));
+				DBGPRINT(RT_DEBUG_TRACE, ("Total match BSSID [=%d]\n", pAd->MlmeAux.SsidBssTab.BssNr));
+				pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+				pAd->MlmeAux.BssIdx++;
+				IterateOnBssTab(pAd);
+			}
+			else
+#endif // LEAP_SUPPORT //
+			if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
+				 (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared))
+			{
+				DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try OPEN system...\n"));
+				AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
+				MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
+							sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
+
+				pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
+			}
+			else
+			{
+				// not success, try next BSS
+				DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, give up; try next BSS\n"));
+				pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
+				pAd->MlmeAux.BssIdx++;
+				IterateOnBssTab(pAd);
+			}
+		}
+	}
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+*/
+VOID CntlWaitAssocProc(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	USHORT      Reason;
+
+	if (Elem->MsgType == MT2_ASSOC_CONF)
+	{
+		NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
+		if (Reason == MLME_SUCCESS)
+		{
+			LinkUp(pAd, BSS_INFRA);
+			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
+
+			if (pAd->CommonCfg.bWirelessEvent)
+			{
+				RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+			}
+		}
+		else
+		{
+			// not success, try next BSS
+			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association fails on BSS #%ld\n",pAd->MlmeAux.BssIdx));
+			pAd->MlmeAux.BssIdx++;
+			IterateOnBssTab(pAd);
+		}
+	}
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+*/
+VOID CntlWaitReassocProc(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	USHORT      Result;
+
+	if (Elem->MsgType == MT2_REASSOC_CONF)
+	{
+		NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
+		if (Result == MLME_SUCCESS)
+		{
+			//
+			// NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
+			//
+			LinkUp(pAd, BSS_INFRA);
+
+			// send wireless event - for association
+			if (pAd->CommonCfg.bWirelessEvent)
+				RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+
+
+#ifdef LEAP_SUPPORT
+			if (LEAP_CCKM_ON(pAd))
+			{
+				STA_PORT_SECURED(pAd);
+				pAd->StaCfg.WpaState = SS_FINISH;
+			}
+#endif // LEAP_SUPPORT //
+			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
+		}
+		else
+		{
+			// reassoc failed, try to pick next BSS in the BSS Table
+			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
+			pAd->MlmeAux.RoamIdx++;
+			IterateOnBssTab2(pAd);
+		}
+	}
+}
+
+
+VOID	AdhocTurnOnQos(
+	IN  PRTMP_ADAPTER pAd)
+{
+#define AC0_DEF_TXOP		0
+#define AC1_DEF_TXOP		0
+#define AC2_DEF_TXOP		94
+#define AC3_DEF_TXOP		47
+
+	// Turn on QOs if use HT rate.
+	if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
+	{
+		pAd->CommonCfg.APEdcaParm.bValid = TRUE;
+		pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
+		pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
+		pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
+		pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
+
+		pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
+		pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
+		pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
+		pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
+
+		pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10;
+		pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6;
+		pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
+		pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
+
+		pAd->CommonCfg.APEdcaParm.Txop[0]  = 0;
+		pAd->CommonCfg.APEdcaParm.Txop[1]  = 0;
+		pAd->CommonCfg.APEdcaParm.Txop[2]  = AC2_DEF_TXOP;
+		pAd->CommonCfg.APEdcaParm.Txop[3]  = AC3_DEF_TXOP;
+	}
+	AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+*/
+VOID LinkUp(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR BssType)
+{
+	ULONG	Now;
+	UINT32	Data;
+	BOOLEAN	Cancelled;
+	UCHAR	Value = 0, idx;
+	MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
+
+	pEntry = &pAd->MacTab.Content[BSSID_WCID];
+
+	//
+	// ASSOC - DisassocTimeoutAction
+	// CNTL - Dis-associate successful
+	// !!! LINK DOWN !!!
+	// [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
+	//
+	// To prevent DisassocTimeoutAction to call Link down after we link up,
+	// cancel the DisassocTimer no matter what it start or not.
+	//
+	RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer,  &Cancelled);
+
+	COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
+
+#ifdef DOT11_N_SUPPORT
+	COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
+#endif // DOT11_N_SUPPORT //
+	// It's quite difficult to tell if a newly added KEY is WEP or CKIP until a new BSS
+	// is formed (either ASSOC/RE-ASSOC done or IBSS started. LinkUP should be a safe place
+	// to examine if cipher algorithm switching is required.
+	//rt2860b. Don't know why need this
+	SwitchBetweenWepAndCkip(pAd);
+
+
+	if (BssType == BSS_ADHOC)
+	{
+		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
+		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
+
+#ifdef DOT11_N_SUPPORT
+		if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth  == BW_40) &&
+			(pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
+		{
+			pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
+		}
+		else if ((pAd->CommonCfg.Channel > 2) &&
+				 (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth  == BW_40) &&
+				 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
+		{
+			pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
+		}
+#endif // DOT11_N_SUPPORT //
+
+#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
+		// No carrier detection when adhoc
+		// CarrierDetectionStop(pAd);
+		pAd->CommonCfg.CarrierDetect.CD_State = CD_NORMAL;
+#endif // CARRIER_DETECTION_SUPPORT //
+
+#ifdef DOT11_N_SUPPORT
+		if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+			AdhocTurnOnQos(pAd);
+#endif // DOT11_N_SUPPORT //
+
+		DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n" ));
+	}
+	else
+	{
+		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
+		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
+
+		DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n" ));
+	}
+
+	// 3*3
+	// reset Tx beamforming bit
+	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
+	Value &= (~0x01);
+	Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
+	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
+
+#ifdef DOT11_N_SUPPORT
+	// Change to AP channel
+    if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
+	{
+		// Must using 40MHz.
+		pAd->CommonCfg.BBPCurrentBW = BW_40;
+		AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+		AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+
+		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
+		Value &= (~0x18);
+		Value |= 0x10;
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
+
+		//  RX : control channel at lower
+		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
+		Value &= (~0x20);
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
+
+		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
+		Data &= 0xfffffffe;
+		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
+
+		if (pAd->MACVersion == 0x28600100)
+		{
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
+            DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
+		}
+
+		DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
+	}
+	else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
+    {
+	    // Must using 40MHz.
+		pAd->CommonCfg.BBPCurrentBW = BW_40;
+		AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+	    AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+
+		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
+		Value &= (~0x18);
+		Value |= 0x10;
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
+
+		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
+		Data |= 0x1;
+		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
+
+		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
+	    Value |= (0x20);
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
+
+		if (pAd->MACVersion == 0x28600100)
+		{
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
+			    DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
+		}
+
+	    DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
+    }
+    else
+#endif // DOT11_N_SUPPORT //
+    {
+	    pAd->CommonCfg.BBPCurrentBW = BW_20;
+		pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
+		AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+		AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+
+		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
+		Value &= (~0x18);
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
+
+		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
+		Data &= 0xfffffffe;
+		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
+
+		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
+		Value &= (~0x20);
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
+
+		if (pAd->MACVersion == 0x28600100)
+		{
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
+            DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
+		}
+
+	    DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz LINK UP !!! \n" ));
+    }
+
+	RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
+	//
+	// Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission
+	//
+	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
+		BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
+
+#ifdef DOT11_N_SUPPORT
+	DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (Density =%d, )\n", pAd->MacTab.Content[BSSID_WCID].MpduDensity));
+#endif // DOT11_N_SUPPORT //
+
+		AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
+
+	AsicSetSlotTime(pAd, TRUE);
+	AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
+
+	// Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit
+	AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, FALSE);
+
+#ifdef DOT11_N_SUPPORT
+	if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
+	{
+		// Update HT protectionfor based on AP's operating mode.
+    	if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
+    	{
+    		AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode,  ALLN_SETPROTECT, FALSE, TRUE);
+    	}
+    	else
+   			AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode,  ALLN_SETPROTECT, FALSE, FALSE);
+	}
+#endif // DOT11_N_SUPPORT //
+
+	NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
+
+	NdisGetSystemUpTime(&Now);
+	pAd->StaCfg.LastBeaconRxTime = Now;   // last RX timestamp
+
+	if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
+		CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo))
+	{
+		MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
+	}
+
+	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
+
+	if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE)
+	{
+#ifdef DFS_SUPPORT
+		RadarDetectionStop(pAd);
+#endif // DFS_SUPPORT //
+	}
+	pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
+
+	if (BssType == BSS_ADHOC)
+	{
+		MakeIbssBeacon(pAd);
+		if ((pAd->CommonCfg.Channel > 14)
+			&& (pAd->CommonCfg.bIEEE80211H == 1)
+			&& RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
+		{
+			; //Do nothing
+		}
+		else
+		{
+			AsicEnableIbssSync(pAd);
+		}
+
+		// In ad hoc mode, use MAC table from index 1.
+		// p.s ASIC use all 0xff as termination of WCID table search.To prevent it's 0xff-ff-ff-ff-ff-ff, Write 0 here.
+		RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
+		RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
+
+		// If WEP is enabled, add key material and cipherAlg into Asic
+		// Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
+
+		if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
+		{
+			PUCHAR	Key;
+			UCHAR 	CipherAlg;
+
+			for (idx=0; idx < SHARE_KEY_NUM; idx++)
+        	{
+				CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
+    			Key = pAd->SharedKey[BSS0][idx].Key;
+
+				if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
+				{
+					// Set key material and cipherAlg to Asic
+    				AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
+
+                    if (idx == pAd->StaCfg.DefaultKeyId)
+					{
+						// Update WCID attribute table and IVEIV table for this group key table
+						RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
+					}
+				}
+
+
+			}
+		}
+		// If WPANone is enabled, add key material and cipherAlg into Asic
+		// Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
+		else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+		{
+			pAd->StaCfg.DefaultKeyId = 0;	// always be zero
+
+            NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
+							pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
+			NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
+
+            if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+            {
+    			NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
+    			NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
+            }
+
+			// Decide its ChiperAlg
+			if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+				pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
+			else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
+				pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
+			else
+            {
+                DBGPRINT(RT_DEBUG_TRACE, ("Unknow Cipher (=%d), set Cipher to AES\n", pAd->StaCfg.PairCipher));
+				pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
+            }
+
+			// Set key material and cipherAlg to Asic
+			AsicAddSharedKeyEntry(pAd,
+								  BSS0,
+								  0,
+								  pAd->SharedKey[BSS0][0].CipherAlg,
+								  pAd->SharedKey[BSS0][0].Key,
+								  pAd->SharedKey[BSS0][0].TxMic,
+								  pAd->SharedKey[BSS0][0].RxMic);
+
+            // Update WCID attribute table and IVEIV table for this group key table
+			RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pAd->SharedKey[BSS0][0].CipherAlg, NULL);
+
+		}
+
+	}
+	else // BSS_INFRA
+	{
+		// Check the new SSID with last SSID
+		while (Cancelled == TRUE)
+		{
+			if (pAd->CommonCfg.LastSsidLen == pAd->CommonCfg.SsidLen)
+			{
+				if (RTMPCompareMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen) == 0)
+				{
+					// Link to the old one no linkdown is required.
+					break;
+				}
+			}
+			// Send link down event before set to link up
+			pAd->IndicateMediaState = NdisMediaStateDisconnected;
+			RTMP_IndicateMediaState(pAd);
+            pAd->ExtraInfo = GENERAL_LINK_DOWN;
+			DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
+			break;
+		}
+
+		//
+		// On WPA mode, Remove All Keys if not connect to the last BSSID
+		// Key will be set after 4-way handshake.
+		//
+		if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
+		{
+			ULONG 		IV;
+
+			// Remove all WPA keys
+			RTMPWPARemoveAllKeys(pAd);
+			pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+			pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
+
+			// Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP
+			// If IV related values are too large in GroupMsg2, AP would ignore this message.
+			IV = 0;
+			IV |= (pAd->StaCfg.DefaultKeyId << 30);
+			AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
+		}
+		// NOTE:
+		// the decision of using "short slot time" or not may change dynamically due to
+		// new STA association to the AP. so we have to decide that upon parsing BEACON, not here
+
+		// NOTE:
+		// the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
+		// due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
+
+		ComposePsPoll(pAd);
+		ComposeNullFrame(pAd);
+
+			AsicEnableBssSync(pAd);
+
+		// Add BSSID to WCID search table
+		AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
+
+		NdisAcquireSpinLock(&pAd->MacTabLock);
+		// add this BSSID entry into HASH table
+		{
+			UCHAR HashIdx;
+
+			//pEntry = &pAd->MacTab.Content[BSSID_WCID];
+			HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
+			if (pAd->MacTab.Hash[HashIdx] == NULL)
+			{
+				pAd->MacTab.Hash[HashIdx] = pEntry;
+			}
+			else
+			{
+				pCurrEntry = pAd->MacTab.Hash[HashIdx];
+				while (pCurrEntry->pNext != NULL)
+					pCurrEntry = pCurrEntry->pNext;
+				pCurrEntry->pNext = pEntry;
+			}
+		}
+		NdisReleaseSpinLock(&pAd->MacTabLock);
+
+
+		// If WEP is enabled, add paiewise and shared key
+#ifdef WPA_SUPPLICANT_SUPPORT
+        if (((pAd->StaCfg.WpaSupplicantUP)&&
+             (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)&&
+             (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
+            ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)&&
+              (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)))
+#else
+		if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
+#endif // WPA_SUPPLICANT_SUPPORT //
+		{
+			PUCHAR	Key;
+			UCHAR 	CipherAlg;
+
+			for (idx=0; idx < SHARE_KEY_NUM; idx++)
+        	{
+				CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
+    			Key = pAd->SharedKey[BSS0][idx].Key;
+
+				if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
+				{
+					// Set key material and cipherAlg to Asic
+    				AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
+
+					if (idx == pAd->StaCfg.DefaultKeyId)
+					{
+						// Assign group key info
+						RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
+
+						// Assign pairwise key info
+						RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
+					}
+				}
+			}
+		}
+
+		// only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
+		// should wait until at least 2 active nodes in this BSSID.
+		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
+
+        // For GUI ++
+		if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
+		{
+			pAd->IndicateMediaState = NdisMediaStateConnected;
+			pAd->ExtraInfo = GENERAL_LINK_UP;
+			RTMP_IndicateMediaState(pAd);
+		}
+        // --
+
+		// Add BSSID in my MAC Table.
+        NdisAcquireSpinLock(&pAd->MacTabLock);
+		RTMPMoveMemory(pAd->MacTab.Content[BSSID_WCID].Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
+		pAd->MacTab.Content[BSSID_WCID].Aid = BSSID_WCID;
+		pAd->MacTab.Content[BSSID_WCID].pAd = pAd;
+		pAd->MacTab.Content[BSSID_WCID].ValidAsCLI = TRUE;	//Although this is bssid..still set ValidAsCl
+		pAd->MacTab.Size = 1;	// infra mode always set MACtab size =1.
+		pAd->MacTab.Content[BSSID_WCID].Sst = SST_ASSOC;
+		pAd->MacTab.Content[BSSID_WCID].AuthState = SST_ASSOC;
+		pAd->MacTab.Content[BSSID_WCID].AuthMode = pAd->StaCfg.AuthMode;
+		pAd->MacTab.Content[BSSID_WCID].WepStatus = pAd->StaCfg.WepStatus;
+        NdisReleaseSpinLock(&pAd->MacTabLock);
+
+		DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!!  ClientStatusFlags=%lx)\n",
+			pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
+
+		MlmeUpdateTxRates(pAd, TRUE, BSS0);
+#ifdef DOT11_N_SUPPORT
+		MlmeUpdateHtTxRates(pAd, BSS0);
+		DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", pAd->StaActive.SupportedPhyInfo.bHtEnable));
+#endif // DOT11_N_SUPPORT //
+
+		//
+		// Report Adjacent AP report.
+		//
+#ifdef LEAP_SUPPORT
+		CCXAdjacentAPReport(pAd);
+#endif // LEAP_SUPPORT //
+
+		if (pAd->CommonCfg.bAggregationCapable)
+		{
+			if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)
+			{
+
+				OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
+				OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
+                RTMPSetPiggyBack(pAd, TRUE);
+				DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
+			}
+			else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
+			{
+				OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
+			}
+		}
+
+		if (pAd->MlmeAux.APRalinkIe != 0x0)
+		{
+#ifdef DOT11_N_SUPPORT
+			if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RDG_CAPABLE))
+			{
+				AsicEnableRDG(pAd);
+			}
+#endif // DOT11_N_SUPPORT //
+			OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
+			CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
+		}
+		else
+		{
+			OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
+			CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
+		}
+	}
+
+#ifdef DOT11_N_SUPPORT
+	DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_CONNECT Event B!.BACapability = %x. ClientStatusFlags = %lx\n", pAd->CommonCfg.BACapability.word, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
+#endif // DOT11_N_SUPPORT //
+
+	// Set LED
+	RTMPSetLED(pAd, LED_LINK_UP);
+
+	pAd->Mlme.PeriodicRound = 0;
+	pAd->Mlme.OneSecPeriodicRound = 0;
+	pAd->bConfigChanged = FALSE;        // Reset config flag
+	pAd->ExtraInfo = GENERAL_LINK_UP;   // Update extra information to link is up
+
+	// Set asic auto fall back
+	{
+		PUCHAR					pTable;
+		UCHAR					TableSize = 0;
+
+		MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], &pTable, &TableSize, &pAd->CommonCfg.TxRateIndex);
+		AsicUpdateAutoFallBackTable(pAd, pTable);
+	}
+
+	NdisAcquireSpinLock(&pAd->MacTabLock);
+    pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
+    pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
+	if (pAd->StaCfg.bAutoTxRateSwitch == FALSE)
+	{
+		pEntry->bAutoTxRateSwitch = FALSE;
+#ifdef DOT11_N_SUPPORT
+		if (pEntry->HTPhyMode.field.MCS == 32)
+			pEntry->HTPhyMode.field.ShortGI = GI_800;
+
+		if ((pEntry->HTPhyMode.field.MCS > MCS_7) || (pEntry->HTPhyMode.field.MCS == 32))
+			pEntry->HTPhyMode.field.STBC = STBC_NONE;
+#endif // DOT11_N_SUPPORT //
+		// If the legacy mode is set, overwrite the transmit setting of this entry.
+		if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
+			RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
+	}
+	else
+		pEntry->bAutoTxRateSwitch = TRUE;
+	NdisReleaseSpinLock(&pAd->MacTabLock);
+
+	//  Let Link Status Page display first initial rate.
+	pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
+	// Select DAC according to HT or Legacy
+	if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00)
+	{
+		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
+		Value &= (~0x18);
+		if (pAd->Antenna.field.TxPath == 2)
+		{
+		    Value |= 0x10;
+		}
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
+	}
+	else
+	{
+		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
+		Value &= (~0x18);
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
+	}
+
+#ifdef DOT11_N_SUPPORT
+	if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
+	{
+	}
+	else if (pEntry->MaxRAmpduFactor == 0)
+	{
+	    // If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0.
+	    // Because our Init value is 1 at MACRegTable.
+		RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
+	}
+#endif // DOT11_N_SUPPORT //
+
+	// Patch for Marvel AP to gain high throughput
+	// Need to set as following,
+	// 1. Set txop in register-EDCA_AC0_CFG as 0x60
+	// 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero
+	// 3. PBF_MAX_PCNT as 0x1F3FBF9F
+	// 4. kick per two packets when dequeue
+	//
+	// Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable
+	//
+	// if 1. Legacy AP WMM on,  or 2. 11n AP, AMPDU disable.  Force turn off burst no matter what bEnableTxBurst is.
+#ifdef DOT11_N_SUPPORT
+//	if ((!IS_RT30xx(pAd)) &&
+	if (!((pAd->CommonCfg.RxStream == 1)&&(pAd->CommonCfg.TxStream == 1)) &&
+		(((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
+		|| ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE))))
+	{
+		RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
+		Data  &= 0xFFFFFF00;
+		RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+
+		RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
+		DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
+	}
+	else
+#endif // DOT11_N_SUPPORT //
+	if (pAd->CommonCfg.bEnableTxBurst)
+	{
+		RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
+		Data  &= 0xFFFFFF00;
+		Data  |= 0x60;
+		RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+		pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
+
+		RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
+		DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
+	}
+	else
+	{
+		RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
+		Data  &= 0xFFFFFF00;
+		RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+
+		RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
+		DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
+	}
+
+#ifdef DOT11_N_SUPPORT
+	// Re-check to turn on TX burst or not.
+	if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) && ((STA_WEP_ON(pAd))||(STA_TKIP_ON(pAd))))
+	{
+		pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
+		if (pAd->CommonCfg.bEnableTxBurst)
+		{
+		    UINT32 MACValue = 0;
+			// Force disable  TXOP value in this case. The same action in MLMEUpdateProtect too.
+			// I didn't change PBF_MAX_PCNT setting.
+			RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
+			MACValue  &= 0xFFFFFF00;
+			RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
+			pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
+		}
+	}
+	else
+	{
+		pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
+	}
+#endif // DOT11_N_SUPPORT //
+
+	pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
+	COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
+	DBGPRINT(RT_DEBUG_TRACE, ("!!!pAd->bNextDisableRxBA= %d \n", pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
+	// BSSID add in one MAC entry too.  Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap
+	// Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver.
+	// Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same.
+
+    if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled)
+    {
+        pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+		pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
+	}
+
+	NdisAcquireSpinLock(&pAd->MacTabLock);
+	pEntry->PortSecured = pAd->StaCfg.PortSecured;
+	NdisReleaseSpinLock(&pAd->MacTabLock);
+
+    //
+	// Patch Atheros AP TX will breakdown issue.
+	// AP Model: DLink DWL-8200AP
+	//
+	if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && STA_TKIP_ON(pAd))
+	{
+		RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
+	}
+	else
+	{
+		RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
+	}
+
+	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+	if ((pAd->CommonCfg.BACapability.field.b2040CoexistScanSup) && (pAd->CommonCfg.Channel <= 11))
+	{
+		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SCAN_2040);
+		BuildEffectedChannelList(pAd);
+	}
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+}
+
+/*
+	==========================================================================
+
+	Routine	Description:
+		Disconnect current BSSID
+
+	Arguments:
+		pAd				- Pointer to our adapter
+		IsReqFromAP		- Request from AP
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+		We need more information to know it's this requst from AP.
+		If yes! we need to do extra handling, for example, remove the WPA key.
+		Otherwise on 4-way handshaking will faied, since the WPA key didn't be
+		remove while auto reconnect.
+		Disconnect request from AP, it means we will start afresh 4-way handshaking
+		on WPA mode.
+
+	==========================================================================
+*/
+VOID LinkDown(
+	IN PRTMP_ADAPTER pAd,
+	IN  BOOLEAN      IsReqFromAP)
+{
+	UCHAR			    i, ByteValue = 0;
+
+	// Do nothing if monitor mode is on
+	if (MONITOR_ON(pAd))
+		return;
+
+#ifdef RALINK_ATE
+	// Nothing to do in ATE mode.
+	if (ATE_ON(pAd))
+		return;
+#endif // RALINK_ATE //
+
+    if (pAd->CommonCfg.bWirelessEvent)
+	{
+		RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
+	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
+
+	if (ADHOC_ON(pAd))		// Adhoc mode link down
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
+
+		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
+		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
+		pAd->IndicateMediaState = NdisMediaStateDisconnected;
+		RTMP_IndicateMediaState(pAd);
+        pAd->ExtraInfo = GENERAL_LINK_DOWN;
+		BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
+		DBGPRINT(RT_DEBUG_TRACE, ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size));
+	}
+	else					// Infra structure mode
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n"));
+
+#ifdef QOS_DLS_SUPPORT
+		// DLS tear down frame must be sent before link down
+		// send DLS-TEAR_DOWN message
+		if (pAd->CommonCfg.bDLSCapable)
+		{
+			// tear down local dls table entry
+			for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+			{
+				if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
+				{
+					pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+					RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
+				}
+			}
+
+			// tear down peer dls table entry
+			for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+			{
+				if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status ==  DLS_FINISH))
+				{
+					pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+					RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
+				}
+			}
+		}
+#endif // QOS_DLS_SUPPORT //
+
+		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
+		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
+
+		// Saved last SSID for linkup comparison
+		pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
+		NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen);
+		COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
+		if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE)
+		{
+			pAd->IndicateMediaState = NdisMediaStateDisconnected;
+			RTMP_IndicateMediaState(pAd);
+            pAd->ExtraInfo = GENERAL_LINK_DOWN;
+			DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
+			pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
+		}
+		else
+		{
+            //
+			// If disassociation request is from NDIS, then we don't need to delete BSSID from entry.
+			// Otherwise lost beacon or receive De-Authentication from AP,
+			// then we should delete BSSID from BssTable.
+			// If we don't delete from entry, roaming will fail.
+			//
+			BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
+		}
+
+		// restore back to -
+		//      1. long slot (20 us) or short slot (9 us) time
+		//      2. turn on/off RTS/CTS and/or CTS-to-self protection
+		//      3. short preamble
+		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
+
+		if (pAd->StaCfg.CCXAdjacentAPReportFlag == TRUE)
+		{
+			//
+			// Record current AP's information.
+			// for later used reporting Adjacent AP report.
+			//
+			pAd->StaCfg.CCXAdjacentAPChannel = pAd->CommonCfg.Channel;
+			pAd->StaCfg.CCXAdjacentAPSsidLen = pAd->CommonCfg.SsidLen;
+			NdisMoveMemory(pAd->StaCfg.CCXAdjacentAPSsid, pAd->CommonCfg.Ssid, pAd->StaCfg.CCXAdjacentAPSsidLen);
+			COPY_MAC_ADDR(pAd->StaCfg.CCXAdjacentAPBssid, pAd->CommonCfg.Bssid);
+		}
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+		// Country IE of the AP will be evaluated and will be used.
+		if (pAd->StaCfg.IEEE80211dClientMode != Rt802_11_D_None)
+		{
+			NdisMoveMemory(&pAd->CommonCfg.CountryCode[0], &pAd->StaCfg.StaOriCountryCode[0], 2);
+			pAd->CommonCfg.Geography = pAd->StaCfg.StaOriGeography;
+			BuildChannelListEx(pAd);
+		}
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+	}
+
+	for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
+	{
+		if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
+			MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr);
+	}
+
+	pAd->StaCfg.CCXQosECWMin	= 4;
+	pAd->StaCfg.CCXQosECWMax	= 10;
+
+	AsicSetSlotTime(pAd, TRUE); //FALSE);
+	AsicSetEdcaParm(pAd, NULL);
+
+	// Set LED
+	RTMPSetLED(pAd, LED_LINK_DOWN);
+    pAd->LedIndicatorStregth = 0xF0;
+    RTMPSetSignalLED(pAd, -100);	// Force signal strength Led to be turned off, firmware is not done it.
+
+		AsicDisableSync(pAd);
+
+	pAd->Mlme.PeriodicRound = 0;
+	pAd->Mlme.OneSecPeriodicRound = 0;
+
+	if (pAd->StaCfg.BssType == BSS_INFRA)
+	{
+	// Remove StaCfg Information after link down
+	NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
+	NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
+		pAd->CommonCfg.SsidLen = 0;
+	}
+#ifdef DOT11_N_SUPPORT
+	NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
+	NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(ADD_HT_INFO_IE));
+	pAd->MlmeAux.HtCapabilityLen = 0;
+	pAd->MlmeAux.NewExtChannelOffset = 0xff;
+#endif // DOT11_N_SUPPORT //
+
+	// Reset WPA-PSK state. Only reset when supplicant enabled
+	if (pAd->StaCfg.WpaState != SS_NOTUSE)
+	{
+		pAd->StaCfg.WpaState = SS_START;
+		// Clear Replay counter
+		NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
+
+#ifdef QOS_DLS_SUPPORT
+		if (pAd->CommonCfg.bDLSCapable)
+			NdisZeroMemory(pAd->StaCfg.DlsReplayCounter, 8);
+#endif // QOS_DLS_SUPPORT //
+	}
+
+
+	//
+	// if link down come from AP, we need to remove all WPA keys on WPA mode.
+	// otherwise will cause 4-way handshaking failed, since the WPA key not empty.
+	//
+	if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
+	{
+		// Remove all WPA keys
+		RTMPWPARemoveAllKeys(pAd);
+	}
+
+	// 802.1x port control
+#ifdef WPA_SUPPLICANT_SUPPORT
+	// Prevent clear PortSecured here with static WEP
+	// NetworkManger set security policy first then set SSID to connect AP.
+	if (pAd->StaCfg.WpaSupplicantUP &&
+		(pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
+		(pAd->StaCfg.IEEE8021X == FALSE))
+	{
+		pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+	}
+	else
+#endif // WPA_SUPPLICANT_SUPPORT //
+	{
+		pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+		pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
+	}
+
+	NdisAcquireSpinLock(&pAd->MacTabLock);
+	pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
+	NdisReleaseSpinLock(&pAd->MacTabLock);
+
+	pAd->StaCfg.MicErrCnt = 0;
+
+	// Turn off Ckip control flag
+	pAd->StaCfg.bCkipOn = FALSE;
+	pAd->StaCfg.CCXEnable = FALSE;
+
+    pAd->IndicateMediaState = NdisMediaStateDisconnected;
+	// Update extra information to link is up
+	pAd->ExtraInfo = GENERAL_LINK_DOWN;
+
+    //pAd->StaCfg.AdhocBOnlyJoined = FALSE;
+	//pAd->StaCfg.AdhocBGJoined = FALSE;
+	//pAd->StaCfg.Adhoc20NJoined = FALSE;
+    pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
+
+	// Reset the Current AP's IP address
+	NdisZeroMemory(pAd->StaCfg.AironetIPAddress, 4);
+#ifdef RT2870
+	pAd->bUsbTxBulkAggre = FALSE;
+#endif // RT2870 //
+
+	// Clean association information
+	NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
+	pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
+	pAd->StaCfg.ReqVarIELen = 0;
+	pAd->StaCfg.ResVarIELen = 0;
+
+	//
+	// Reset RSSI value after link down
+	//
+	pAd->StaCfg.RssiSample.AvgRssi0 = 0;
+	pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
+	pAd->StaCfg.RssiSample.AvgRssi1 = 0;
+	pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
+	pAd->StaCfg.RssiSample.AvgRssi2 = 0;
+	pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
+
+	// Restore MlmeRate
+	pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
+	pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
+
+#ifdef DOT11_N_SUPPORT
+	//
+	// After Link down, reset piggy-back setting in ASIC. Disable RDG.
+	//
+	if (pAd->CommonCfg.BBPCurrentBW == BW_40)
+	{
+		pAd->CommonCfg.BBPCurrentBW = BW_20;
+		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
+		ByteValue &= (~0x18);
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
+	}
+#endif // DOT11_N_SUPPORT //
+	// Reset DAC
+	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
+	ByteValue &= (~0x18);
+	if (pAd->Antenna.field.TxPath == 2)
+	{
+		ByteValue |= 0x10;
+	}
+	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
+
+	RTMPSetPiggyBack(pAd,FALSE);
+	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
+
+#ifdef DOT11_N_SUPPORT
+	pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
+#endif // DOT11_N_SUPPORT //
+
+	// Restore all settings in the following.
+	AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
+	AsicDisableRDG(pAd);
+	pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
+	pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
+
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SCAN_2040);
+	pAd->CommonCfg.BSSCoexist2040.word = 0;
+	TriEventInit(pAd);
+	for (i = 0; i < (pAd->ChannelListNum - 1); i++)
+	{
+		pAd->ChannelList[i].bEffectedChannel = FALSE;
+	}
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+
+	RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
+	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+	if (pAd->StaCfg.WpaSupplicantUP) {
+		union iwreq_data    wrqu;
+		//send disassociate event to wpa_supplicant
+		memset(&wrqu, 0, sizeof(wrqu));
+		wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
+		wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+	}
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+	{
+		union iwreq_data    wrqu;
+		memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+		wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+	}
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+#ifdef RT30xx
+	if (IS_RT3090(pAd))
+	{
+		UINT32				macdata;
+		// disable MMPS BBP control register
+		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &ByteValue);
+		ByteValue &= ~(0x04);	//bit 2
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, ByteValue);
+
+		// disable MMPS MAC control register
+		RTMP_IO_READ32(pAd, 0x1210, &macdata);
+		macdata &= ~(0x09);	//bit 0, 3
+		RTMP_IO_WRITE32(pAd, 0x1210, macdata);
+	}
+#endif // RT30xx //
+
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+*/
+VOID IterateOnBssTab(
+	IN PRTMP_ADAPTER pAd)
+{
+	MLME_START_REQ_STRUCT   StartReq;
+	MLME_JOIN_REQ_STRUCT    JoinReq;
+	ULONG                   BssIdx;
+
+	// Change the wepstatus to original wepstatus
+	pAd->StaCfg.WepStatus   = pAd->StaCfg.OrigWepStatus;
+	pAd->StaCfg.PairCipher  = pAd->StaCfg.OrigWepStatus;
+	pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
+
+	BssIdx = pAd->MlmeAux.BssIdx;
+	if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr)
+	{
+		// Check cipher suite, AP must have more secured cipher than station setting
+		// Set the Pairwise and Group cipher to match the intended AP setting
+		// We can only connect to AP with less secured cipher setting
+		if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
+		{
+			pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.GroupCipher;
+
+			if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher)
+				pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher;
+			else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
+				pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux;
+			else	// There is no PairCipher Aux, downgrade our capability to TKIP
+				pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
+		}
+		else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+		{
+			pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.GroupCipher;
+
+			if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher)
+				pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher;
+			else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
+				pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux;
+			else	// There is no PairCipher Aux, downgrade our capability to TKIP
+				pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
+
+			// RSN capability
+			pAd->StaCfg.RsnCapability = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.RsnCapability;
+		}
+
+		// Set Mix cipher flag
+		pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
+		if (pAd->StaCfg.bMixCipher == TRUE)
+		{
+			// If mix cipher, re-build RSNIE
+			RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
+		}
+
+		DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr));
+		JoinParmFill(pAd, &JoinReq, BssIdx);
+		MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
+					&JoinReq);
+		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
+	}
+	else if (pAd->StaCfg.BssType == BSS_ADHOC)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
+		StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
+		MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
+		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
+	}
+	else // no more BSS
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, stay @ ch #%d\n", pAd->CommonCfg.Channel));
+		AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+		AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+		pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+	}
+}
+
+// for re-association only
+// IRQL = DISPATCH_LEVEL
+VOID IterateOnBssTab2(
+	IN PRTMP_ADAPTER pAd)
+{
+	MLME_REASSOC_REQ_STRUCT ReassocReq;
+	ULONG                   BssIdx;
+	BSS_ENTRY               *pBss;
+
+	BssIdx = pAd->MlmeAux.RoamIdx;
+	pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
+
+	if (BssIdx < pAd->MlmeAux.RoamTab.BssNr)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.RoamTab.BssNr));
+
+		AsicSwitchChannel(pAd, pBss->Channel, FALSE);
+		AsicLockChannel(pAd, pBss->Channel);
+
+		// reassociate message has the same structure as associate message
+		AssocParmFill(pAd, &ReassocReq, pBss->Bssid, pBss->CapabilityInfo,
+					  ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
+		MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
+					sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
+
+		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
+	}
+	else // no more BSS
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All fast roaming failed, back to ch #%d\n",pAd->CommonCfg.Channel));
+		AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+		AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+		pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+	}
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+*/
+VOID JoinParmFill(
+	IN PRTMP_ADAPTER pAd,
+	IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
+	IN ULONG BssIdx)
+{
+	JoinReq->BssIdx = BssIdx;
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+*/
+VOID ScanParmFill(
+	IN PRTMP_ADAPTER pAd,
+	IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
+	IN CHAR Ssid[],
+	IN UCHAR SsidLen,
+	IN UCHAR BssType,
+	IN UCHAR ScanType)
+{
+    NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
+	ScanReq->SsidLen = SsidLen;
+	NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
+	ScanReq->BssType = BssType;
+	ScanReq->ScanType = ScanType;
+}
+
+#ifdef QOS_DLS_SUPPORT
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+*/
+VOID DlsParmFill(
+	IN PRTMP_ADAPTER pAd,
+	IN OUT MLME_DLS_REQ_STRUCT *pDlsReq,
+	IN PRT_802_11_DLS pDls,
+	IN USHORT reason)
+{
+	pDlsReq->pDLS = pDls;
+	pDlsReq->Reason = reason;
+}
+#endif // QOS_DLS_SUPPORT //
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+*/
+VOID StartParmFill(
+	IN PRTMP_ADAPTER pAd,
+	IN OUT MLME_START_REQ_STRUCT *StartReq,
+	IN CHAR Ssid[],
+	IN UCHAR SsidLen)
+{
+	ASSERT(SsidLen <= MAX_LEN_OF_SSID);
+	NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
+	StartReq->SsidLen = SsidLen;
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+*/
+VOID AuthParmFill(
+	IN PRTMP_ADAPTER pAd,
+	IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
+	IN PUCHAR pAddr,
+	IN USHORT Alg)
+{
+	COPY_MAC_ADDR(AuthReq->Addr, pAddr);
+	AuthReq->Alg = Alg;
+	AuthReq->Timeout = AUTH_TIMEOUT;
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+
+
+#ifdef RT2870
+
+VOID MlmeCntlConfirm(
+	IN PRTMP_ADAPTER pAd,
+	IN ULONG MsgType,
+	IN USHORT Msg)
+{
+	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MsgType, sizeof(USHORT), &Msg);
+}
+
+VOID ComposePsPoll(
+	IN PRTMP_ADAPTER pAd)
+{
+	PTXINFO_STRUC		pTxInfo;
+	PTXWI_STRUC		pTxWI;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("ComposePsPoll\n"));
+	NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
+
+	pAd->PsPollFrame.FC.PwrMgmt = 0;
+	pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
+	pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
+	pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
+	COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
+	COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
+
+	RTMPZeroMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0], 100);
+	pTxInfo = (PTXINFO_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0];
+	RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(PSPOLL_FRAME)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE,  FALSE);
+	pTxWI = (PTXWI_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
+	RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(PSPOLL_FRAME)),
+		0,  0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
+	RTMPMoveMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
+	// Append 4 extra zero bytes.
+	pAd->PsPollContext.BulkOutSize =  TXINFO_SIZE + TXWI_SIZE + sizeof(PSPOLL_FRAME) + 4;
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID ComposeNullFrame(
+	IN PRTMP_ADAPTER pAd)
+{
+	PTXINFO_STRUC		pTxInfo;
+	PTXWI_STRUC		pTxWI;
+
+	NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
+	pAd->NullFrame.FC.Type = BTYPE_DATA;
+	pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
+	pAd->NullFrame.FC.ToDs = 1;
+	COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
+	COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
+	COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
+	RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[0], 100);
+	pTxInfo = (PTXINFO_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[0];
+	RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE,  FALSE);
+	pTxWI = (PTXWI_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
+	RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
+		0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
+	RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
+	pAd->NullContext.BulkOutSize =  TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
+}
+#endif // RT2870 //
+
+
+/*
+	==========================================================================
+	Description:
+		Pre-build a BEACON frame in the shared memory
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+*/
+ULONG MakeIbssBeacon(
+	IN PRTMP_ADAPTER pAd)
+{
+	UCHAR         DsLen = 1, IbssLen = 2;
+	UCHAR         LocalErpIe[3] = {IE_ERP, 1, 0x04};
+	HEADER_802_11 BcnHdr;
+	USHORT        CapabilityInfo;
+	LARGE_INTEGER FakeTimestamp;
+	ULONG         FrameLen = 0;
+	PTXWI_STRUC	  pTxWI = &pAd->BeaconTxWI;
+	CHAR         *pBeaconFrame = pAd->BeaconBuf;
+	BOOLEAN       Privacy;
+	UCHAR         SupRate[MAX_LEN_OF_SUPPORTED_RATES];
+	UCHAR         SupRateLen = 0;
+	UCHAR         ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+	UCHAR         ExtRateLen = 0;
+	UCHAR         RSNIe = IE_WPA;
+
+	if ((pAd->CommonCfg.PhyMode == PHY_11B) && (pAd->CommonCfg.Channel <= 14))
+	{
+		SupRate[0] = 0x82; // 1 mbps
+		SupRate[1] = 0x84; // 2 mbps
+		SupRate[2] = 0x8b; // 5.5 mbps
+		SupRate[3] = 0x96; // 11 mbps
+		SupRateLen = 4;
+		ExtRateLen = 0;
+	}
+	else if (pAd->CommonCfg.Channel > 14)
+	{
+		SupRate[0]  = 0x8C;    // 6 mbps, in units of 0.5 Mbps, basic rate
+		SupRate[1]  = 0x12;    // 9 mbps, in units of 0.5 Mbps
+		SupRate[2]  = 0x98;    // 12 mbps, in units of 0.5 Mbps, basic rate
+		SupRate[3]  = 0x24;    // 18 mbps, in units of 0.5 Mbps
+		SupRate[4]  = 0xb0;    // 24 mbps, in units of 0.5 Mbps, basic rate
+		SupRate[5]  = 0x48;    // 36 mbps, in units of 0.5 Mbps
+		SupRate[6]  = 0x60;    // 48 mbps, in units of 0.5 Mbps
+		SupRate[7]  = 0x6c;    // 54 mbps, in units of 0.5 Mbps
+		SupRateLen  = 8;
+		ExtRateLen  = 0;
+
+		//
+		// Also Update MlmeRate & RtsRate for G only & A only
+		//
+		pAd->CommonCfg.MlmeRate = RATE_6;
+		pAd->CommonCfg.RtsRate = RATE_6;
+		pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
+		pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
+		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+	}
+	else
+	{
+		SupRate[0] = 0x82; // 1 mbps
+		SupRate[1] = 0x84; // 2 mbps
+		SupRate[2] = 0x8b; // 5.5 mbps
+		SupRate[3] = 0x96; // 11 mbps
+		SupRateLen = 4;
+
+		ExtRate[0]  = 0x0C;    // 6 mbps, in units of 0.5 Mbps,
+		ExtRate[1]  = 0x12;    // 9 mbps, in units of 0.5 Mbps
+		ExtRate[2]  = 0x18;    // 12 mbps, in units of 0.5 Mbps,
+		ExtRate[3]  = 0x24;    // 18 mbps, in units of 0.5 Mbps
+		ExtRate[4]  = 0x30;    // 24 mbps, in units of 0.5 Mbps,
+		ExtRate[5]  = 0x48;    // 36 mbps, in units of 0.5 Mbps
+		ExtRate[6]  = 0x60;    // 48 mbps, in units of 0.5 Mbps
+		ExtRate[7]  = 0x6c;    // 54 mbps, in units of 0.5 Mbps
+		ExtRateLen  = 8;
+	}
+
+	pAd->StaActive.SupRateLen = SupRateLen;
+	NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
+	pAd->StaActive.ExtRateLen = ExtRateLen;
+	NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
+
+	// compose IBSS beacon frame
+	MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->CommonCfg.Bssid);
+	Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
+			  (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
+			  (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
+	CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
+
+	MakeOutgoingFrame(pBeaconFrame,                &FrameLen,
+					  sizeof(HEADER_802_11),           &BcnHdr,
+					  TIMESTAMP_LEN,                   &FakeTimestamp,
+					  2,                               &pAd->CommonCfg.BeaconPeriod,
+					  2,                               &CapabilityInfo,
+					  1,                               &SsidIe,
+					  1,                               &pAd->CommonCfg.SsidLen,
+					  pAd->CommonCfg.SsidLen,          pAd->CommonCfg.Ssid,
+					  1,                               &SupRateIe,
+					  1,                               &SupRateLen,
+					  SupRateLen,                      SupRate,
+					  1,                               &DsIe,
+					  1,                               &DsLen,
+					  1,                               &pAd->CommonCfg.Channel,
+					  1,                               &IbssIe,
+					  1,                               &IbssLen,
+					  2,                               &pAd->StaActive.AtimWin,
+					  END_OF_ARGS);
+
+	// add ERP_IE and EXT_RAE IE of in 802.11g
+	if (ExtRateLen)
+	{
+		ULONG	tmp;
+
+		MakeOutgoingFrame(pBeaconFrame + FrameLen,         &tmp,
+						  3,                               LocalErpIe,
+						  1,                               &ExtRateIe,
+						  1,                               &ExtRateLen,
+						  ExtRateLen,                      ExtRate,
+						  END_OF_ARGS);
+		FrameLen += tmp;
+	}
+
+	// If adhoc secruity is set for WPA-None, append the cipher suite IE
+	if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+	{
+		ULONG tmp;
+        RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
+
+		MakeOutgoingFrame(pBeaconFrame + FrameLen,        	&tmp,
+						  1,                              	&RSNIe,
+						  1,                            	&pAd->StaCfg.RSNIE_Len,
+						  pAd->StaCfg.RSNIE_Len,      		pAd->StaCfg.RSN_IE,
+						  END_OF_ARGS);
+		FrameLen += tmp;
+	}
+
+#ifdef DOT11_N_SUPPORT
+	if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+	{
+		ULONG TmpLen;
+		UCHAR HtLen, HtLen1;
+
+#ifdef RT_BIG_ENDIAN
+		HT_CAPABILITY_IE HtCapabilityTmp;
+		ADD_HT_INFO_IE	addHTInfoTmp;
+		USHORT	b2lTmp, b2lTmp2;
+#endif
+
+		// add HT Capability IE
+		HtLen = sizeof(pAd->CommonCfg.HtCapability);
+		HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
+#ifndef RT_BIG_ENDIAN
+		MakeOutgoingFrame(pBeaconFrame+FrameLen,	&TmpLen,
+						  1,						&HtCapIe,
+						  1,						&HtLen,
+						  HtLen,					&pAd->CommonCfg.HtCapability,
+						  1,						&AddHtInfoIe,
+						  1,						&HtLen1,
+						  HtLen1,					&pAd->CommonCfg.AddHTInfo,
+						  END_OF_ARGS);
+#else
+		NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
+		*(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
+		*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
+
+		NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, HtLen1);
+		*(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2));
+		*(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3));
+
+		MakeOutgoingFrame(pBeaconFrame+FrameLen,	&TmpLen,
+						  1,						&HtCapIe,
+						  1,						&HtLen,
+						  HtLen,					&HtCapabilityTmp,
+						  1,						&AddHtInfoIe,
+						  1,						&HtLen1,
+						  HtLen1,					&addHTInfoTmp,
+						  END_OF_ARGS);
+#endif
+		FrameLen += TmpLen;
+	}
+#endif // DOT11_N_SUPPORT //
+
+	//beacon use reserved WCID 0xff
+    if (pAd->CommonCfg.Channel > 14)
+    {
+	RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE,  TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
+		PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
+    }
+    else
+    {
+        // Set to use 1Mbps for Adhoc beacon.
+		HTTRANSMIT_SETTING Transmit;
+        Transmit.word = 0;
+        RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE,  TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
+    		PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &Transmit);
+    }
+
+#ifdef RT_BIG_ENDIAN
+	RTMPFrameEndianChange(pAd, pBeaconFrame, DIR_WRITE, FALSE);
+	RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
+#endif
+
+    DBGPRINT(RT_DEBUG_TRACE, ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
+					FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode));
+	return FrameLen;
+}
+
+
diff --git a/drivers/staging/rt3070/sta/dls.c b/drivers/staging/rt3070/sta/dls.c
new file mode 100644
index 0000000..8bcd413
--- /dev/null
+++ b/drivers/staging/rt3070/sta/dls.c
@@ -0,0 +1,2170 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+    dls.c
+
+    Abstract:
+    Handle WMM-DLS state machine
+
+    Revision History:
+    Who         When          What
+    --------    ----------    ----------------------------------------------
+    Rory Chen   02-14-2006
+	Arvin Tai	06-03-2008	  Modified for RT28xx
+ */
+
+#include "../rt_config.h"
+
+/*
+    ==========================================================================
+    Description:
+        dls state machine init, including state transition and timer init
+    Parameters:
+        Sm - pointer to the dls state machine
+    Note:
+        The state machine looks like this
+
+                            DLS_IDLE
+    MT2_MLME_DLS_REQUEST   MlmeDlsReqAction
+    MT2_PEER_DLS_REQUEST   PeerDlsReqAction
+    MT2_PEER_DLS_RESPONSE  PeerDlsRspAction
+    MT2_MLME_DLS_TEARDOWN  MlmeTearDownAction
+    MT2_PEER_DLS_TEARDOWN  PeerTearDownAction
+
+	IRQL = PASSIVE_LEVEL
+
+    ==========================================================================
+ */
+void DlsStateMachineInit(
+    IN PRTMP_ADAPTER pAd,
+    IN STATE_MACHINE *Sm,
+    OUT STATE_MACHINE_FUNC Trans[])
+{
+	UCHAR	i;
+
+    StateMachineInit(Sm, (STATE_MACHINE_FUNC*)Trans, MAX_DLS_STATE, MAX_DLS_MSG, (STATE_MACHINE_FUNC)Drop, DLS_IDLE, DLS_MACHINE_BASE);
+
+    // the first column
+    StateMachineSetAction(Sm, DLS_IDLE, MT2_MLME_DLS_REQ, (STATE_MACHINE_FUNC)MlmeDlsReqAction);
+    StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_REQ, (STATE_MACHINE_FUNC)PeerDlsReqAction);
+    StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_RSP, (STATE_MACHINE_FUNC)PeerDlsRspAction);
+    StateMachineSetAction(Sm, DLS_IDLE, MT2_MLME_DLS_TEAR_DOWN, (STATE_MACHINE_FUNC)MlmeDlsTearDownAction);
+    StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_TEAR_DOWN, (STATE_MACHINE_FUNC)PeerDlsTearDownAction);
+
+	for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
+	{
+		pAd->StaCfg.DLSEntry[i].pAd = pAd;
+		RTMPInitTimer(pAd, &pAd->StaCfg.DLSEntry[i].Timer, GET_TIMER_FUNCTION(DlsTimeoutAction), pAd, FALSE);
+	}
+}
+
+/*
+    ==========================================================================
+    Description:
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+VOID MlmeDlsReqAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem)
+{
+	PUCHAR			pOutBuffer = NULL;
+	NDIS_STATUS		NStatus;
+	ULONG			FrameLen = 0;
+	HEADER_802_11	DlsReqHdr;
+	PRT_802_11_DLS	pDLS = NULL;
+	UCHAR			Category = CATEGORY_DLS;
+	UCHAR			Action = ACTION_DLS_REQUEST;
+	ULONG			tmp;
+	USHORT			reason;
+	ULONG			Timeout;
+	BOOLEAN			TimerCancelled;
+
+	if(!MlmeDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, &pDLS, &reason))
+		return;
+
+	DBGPRINT(RT_DEBUG_TRACE,("DLS - MlmeDlsReqAction() \n"));
+
+	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
+	if (NStatus != NDIS_STATUS_SUCCESS)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("DLS - MlmeDlsReqAction() allocate memory failed \n"));
+		return;
+	}
+
+	ActHeaderInit(pAd, &DlsReqHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+
+	// Build basic frame first
+	MakeOutgoingFrame(pOutBuffer,				&FrameLen,
+					sizeof(HEADER_802_11),		&DlsReqHdr,
+					1,							&Category,
+					1,							&Action,
+					6,							&pDLS->MacAddr,
+					6,							pAd->CurrentAddress,
+					2,							&pAd->StaActive.CapabilityInfo,
+					2,							&pDLS->TimeOut,
+					1,							&SupRateIe,
+					1,							&pAd->MlmeAux.SupRateLen,
+					pAd->MlmeAux.SupRateLen,	pAd->MlmeAux.SupRate,
+					END_OF_ARGS);
+
+	if (pAd->MlmeAux.ExtRateLen != 0)
+	{
+		MakeOutgoingFrame(pOutBuffer + FrameLen,	&tmp,
+						  1,						&ExtRateIe,
+						  1,						&pAd->MlmeAux.ExtRateLen,
+						  pAd->MlmeAux.ExtRateLen,	pAd->MlmeAux.ExtRate,
+						  END_OF_ARGS);
+		FrameLen += tmp;
+	}
+
+#ifdef DOT11_N_SUPPORT
+	if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+	{
+		UCHAR HtLen;
+
+#ifdef RT_BIG_ENDIAN
+		HT_CAPABILITY_IE HtCapabilityTmp;
+#endif
+
+		// add HT Capability IE
+		HtLen = sizeof(HT_CAPABILITY_IE);
+#ifndef RT_BIG_ENDIAN
+		MakeOutgoingFrame(pOutBuffer + FrameLen,	&tmp,
+							1,						&HtCapIe,
+							1,						&HtLen,
+							HtLen,					&pAd->CommonCfg.HtCapability,
+							END_OF_ARGS);
+#else
+		NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
+							*(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
+							*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
+
+		MakeOutgoingFrame(pOutBuffer + FrameLen,	&tmp,
+							1,						&HtCapIe,
+							1,						&HtLen,
+							HtLen,					&HtCapabilityTmp,
+							END_OF_ARGS);
+#endif
+		FrameLen = FrameLen + tmp;
+	}
+#endif // DOT11_N_SUPPORT //
+
+	RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
+	Timeout = DLS_TIMEOUT;
+	RTMPSetTimer(&pDLS->Timer, Timeout);
+
+	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+	MlmeFreeMemory(pAd, pOutBuffer);
+}
+
+/*
+    ==========================================================================
+    Description:
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+VOID PeerDlsReqAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem)
+{
+	PUCHAR			pOutBuffer = NULL;
+	NDIS_STATUS		NStatus;
+	ULONG			FrameLen = 0;
+	USHORT			StatusCode = MLME_SUCCESS;
+	HEADER_802_11	DlsRspHdr;
+	UCHAR			Category = CATEGORY_DLS;
+	UCHAR			Action = ACTION_DLS_RESPONSE;
+	ULONG			tmp;
+	USHORT			CapabilityInfo;
+	UCHAR			DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
+	USHORT			DLSTimeOut;
+	SHORT			i;
+	ULONG			Timeout;
+	BOOLEAN			TimerCancelled;
+	PRT_802_11_DLS	pDLS = NULL;
+	UCHAR			MaxSupportedRateIn500Kbps = 0;
+    UCHAR			SupportedRatesLen;
+    UCHAR			SupportedRates[MAX_LEN_OF_SUPPORTED_RATES];
+	UCHAR			HtCapabilityLen;
+	HT_CAPABILITY_IE	HtCapability;
+
+	if (!PeerDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &CapabilityInfo, &DLSTimeOut,
+							&SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, &HtCapability))
+		return;
+
+    // supported rates array may not be sorted. sort it and find the maximum rate
+    for (i = 0; i < SupportedRatesLen; i++)
+    {
+        if (MaxSupportedRateIn500Kbps < (SupportedRates[i] & 0x7f))
+            MaxSupportedRateIn500Kbps = SupportedRates[i] & 0x7f;
+    }
+
+	DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsReqAction() from %02x:%02x:%02x:%02x:%02x:%02x\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
+
+	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
+	if (NStatus != NDIS_STATUS_SUCCESS)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsReqAction() allocate memory failed \n"));
+		return;
+	}
+
+	if (!INFRA_ON(pAd))
+	{
+		StatusCode = MLME_REQUEST_DECLINED;
+	}
+	else if (!pAd->CommonCfg.bWmmCapable)
+	{
+		StatusCode = MLME_DEST_STA_IS_NOT_A_QSTA;
+	}
+	else if (!pAd->CommonCfg.bDLSCapable)
+	{
+		StatusCode = MLME_REQUEST_DECLINED;
+	}
+	else
+	{
+		// find table to update parameters
+		for (i = (MAX_NUM_OF_DLS_ENTRY-1); i >= 0; i--)
+		{
+			if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
+			{
+				if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+					pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
+				else
+				{
+					RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+					pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
+				}
+
+				pAd->StaCfg.DLSEntry[i].Sequence = 0;
+				pAd->StaCfg.DLSEntry[i].TimeOut = DLSTimeOut;
+				pAd->StaCfg.DLSEntry[i].CountDownTimer = DLSTimeOut;
+				if (HtCapabilityLen != 0)
+					pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
+				else
+					pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
+				pDLS = &pAd->StaCfg.DLSEntry[i];
+				break;
+			}
+		}
+
+		// can not find in table, create a new one
+		if (i < 0)
+		{
+			DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsReqAction() can not find same entry \n"));
+			for (i=(MAX_NUM_OF_DLS_ENTRY - 1); i >= MAX_NUM_OF_INIT_DLS_ENTRY; i--)
+			{
+				if (!pAd->StaCfg.DLSEntry[i].Valid)
+				{
+					MAC_TABLE_ENTRY *pEntry;
+					UCHAR MaxSupportedRate = RATE_11;
+
+					if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+					{
+						pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
+					}
+					else
+					{
+						RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+						pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
+					}
+
+					pAd->StaCfg.DLSEntry[i].Sequence = 0;
+					pAd->StaCfg.DLSEntry[i].Valid = TRUE;
+					pAd->StaCfg.DLSEntry[i].TimeOut = DLSTimeOut;
+					pAd->StaCfg.DLSEntry[i].CountDownTimer = DLSTimeOut;
+					NdisMoveMemory(pAd->StaCfg.DLSEntry[i].MacAddr, SA, MAC_ADDR_LEN);
+					if (HtCapabilityLen != 0)
+						pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
+					else
+						pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
+					pDLS = &pAd->StaCfg.DLSEntry[i];
+					pEntry = MacTableInsertDlsEntry(pAd, SA, i);
+
+					switch (MaxSupportedRateIn500Kbps)
+					{
+						case 108: MaxSupportedRate = RATE_54;   break;
+						case 96:  MaxSupportedRate = RATE_48;   break;
+						case 72:  MaxSupportedRate = RATE_36;   break;
+						case 48:  MaxSupportedRate = RATE_24;   break;
+						case 36:  MaxSupportedRate = RATE_18;   break;
+						case 24:  MaxSupportedRate = RATE_12;   break;
+						case 18:  MaxSupportedRate = RATE_9;    break;
+						case 12:  MaxSupportedRate = RATE_6;    break;
+						case 22:  MaxSupportedRate = RATE_11;   break;
+						case 11:  MaxSupportedRate = RATE_5_5;  break;
+						case 4:   MaxSupportedRate = RATE_2;    break;
+						case 2:   MaxSupportedRate = RATE_1;    break;
+						default:  MaxSupportedRate = RATE_11;   break;
+					}
+
+					pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
+
+					if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
+					{
+						pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
+						pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+						pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
+						pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+						pEntry->HTPhyMode.field.MODE = MODE_CCK;
+						pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+					}
+					else
+					{
+						pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
+						pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+						pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
+						pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+						pEntry->HTPhyMode.field.MODE = MODE_OFDM;
+						pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+					}
+
+					pEntry->MaxHTPhyMode.field.BW = BW_20;
+					pEntry->MinHTPhyMode.field.BW = BW_20;
+
+#ifdef DOT11_N_SUPPORT
+					pEntry->HTCapability.MCSSet[0] = 0;
+					pEntry->HTCapability.MCSSet[1] = 0;
+
+					// If this Entry supports 802.11n, upgrade to HT rate.
+					if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+					{
+						UCHAR	j, bitmask; //k,bitmask;
+						CHAR    ii;
+
+						if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
+						{
+							pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
+						}
+						else
+						{
+							pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+							pAd->MacTab.fAnyStationNonGF = TRUE;
+							pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
+						}
+
+						if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
+						{
+							pEntry->MaxHTPhyMode.field.BW= BW_40;
+							pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
+						}
+						else
+						{
+							pEntry->MaxHTPhyMode.field.BW = BW_20;
+							pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
+							pAd->MacTab.fAnyStation20Only = TRUE;
+						}
+
+						// find max fixed rate
+						for (ii=15; ii>=0; ii--)
+						{
+							j = ii/8;
+							bitmask = (1<<(ii-(j*8)));
+							if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
+							{
+								pEntry->MaxHTPhyMode.field.MCS = ii;
+								break;
+							}
+							if (ii==0)
+								break;
+						}
+
+
+						if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
+						{
+
+							printk("@@@ pAd->CommonCfg.RegTransmitSetting.field.MCS = %d\n",
+								pAd->StaCfg.DesiredTransmitSetting.field.MCS);
+							if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
+							{
+								// Fix MCS as HT Duplicated Mode
+								pEntry->MaxHTPhyMode.field.BW = 1;
+								pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+								pEntry->MaxHTPhyMode.field.STBC = 0;
+								pEntry->MaxHTPhyMode.field.ShortGI = 0;
+								pEntry->MaxHTPhyMode.field.MCS = 32;
+							}
+							else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
+							{
+								// STA supports fixed MCS
+								pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+							}
+						}
+
+						pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
+						pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
+						pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
+						pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
+						pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
+						pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+
+						if (HtCapability.HtCapInfo.ShortGIfor20)
+							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
+						if (HtCapability.HtCapInfo.ShortGIfor40)
+							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
+						if (HtCapability.HtCapInfo.TxSTBC)
+							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
+						if (HtCapability.HtCapInfo.RxSTBC)
+							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
+						if (HtCapability.ExtHtCapInfo.PlusHTC)
+							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
+						if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
+							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
+						if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
+							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
+
+						NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
+					}
+#endif // DOT11_N_SUPPORT //
+
+					pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+					pEntry->CurrTxRate = pEntry->MaxSupportedRate;
+					CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
+
+					if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
+					{
+						PUCHAR pTable;
+						UCHAR TableSize = 0;
+
+						MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
+						pEntry->bAutoTxRateSwitch = TRUE;
+					}
+					else
+					{
+						pEntry->HTPhyMode.field.MODE	= pAd->StaCfg.HTPhyMode.field.MODE;
+						pEntry->HTPhyMode.field.MCS	= pAd->StaCfg.HTPhyMode.field.MCS;
+						pEntry->bAutoTxRateSwitch = FALSE;
+
+						RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
+					}
+					pEntry->RateLen = SupportedRatesLen;
+
+					break;
+				}
+			}
+		}
+		StatusCode = MLME_SUCCESS;
+
+		// can not find in table, create a new one
+		if (i < 0)
+		{
+			StatusCode = MLME_QOS_UNSPECIFY;
+			DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsReqAction() DLSEntry table full(only can support %d DLS session) \n", MAX_NUM_OF_DLS_ENTRY - MAX_NUM_OF_INIT_DLS_ENTRY));
+		}
+		else
+		{
+			DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsReqAction() use entry(%d) %02x:%02x:%02x:%02x:%02x:%02x\n",
+				i, SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
+		}
+	}
+
+	ActHeaderInit(pAd, &DlsRspHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+
+	// Build basic frame first
+	if (StatusCode == MLME_SUCCESS)
+	{
+		MakeOutgoingFrame(pOutBuffer,				&FrameLen,
+						sizeof(HEADER_802_11),		&DlsRspHdr,
+						1,							&Category,
+						1,							&Action,
+						2,							&StatusCode,
+						6,							SA,
+						6,							pAd->CurrentAddress,
+						2,							&pAd->StaActive.CapabilityInfo,
+						1,							&SupRateIe,
+						1,							&pAd->MlmeAux.SupRateLen,
+						pAd->MlmeAux.SupRateLen,	pAd->MlmeAux.SupRate,
+						END_OF_ARGS);
+
+		if (pAd->MlmeAux.ExtRateLen != 0)
+		{
+			MakeOutgoingFrame(pOutBuffer + FrameLen,	&tmp,
+							  1,						&ExtRateIe,
+							  1,						&pAd->MlmeAux.ExtRateLen,
+							  pAd->MlmeAux.ExtRateLen, 	pAd->MlmeAux.ExtRate,
+							  END_OF_ARGS);
+			FrameLen += tmp;
+		}
+
+#ifdef DOT11_N_SUPPORT
+		if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+		{
+			UCHAR HtLen;
+
+#ifdef RT_BIG_ENDIAN
+			HT_CAPABILITY_IE HtCapabilityTmp;
+#endif
+
+			// add HT Capability IE
+			HtLen = sizeof(HT_CAPABILITY_IE);
+#ifndef RT_BIG_ENDIAN
+			MakeOutgoingFrame(pOutBuffer + FrameLen,	&tmp,
+								1,						&HtCapIe,
+								1,						&HtLen,
+								HtLen,					&pAd->CommonCfg.HtCapability,
+								END_OF_ARGS);
+#else
+			NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
+								*(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
+								*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
+
+			MakeOutgoingFrame(pOutBuffer + FrameLen,	&tmp,
+								1,						&HtCapIe,
+								1,						&HtLen,
+								HtLen,					&HtCapabilityTmp,
+								END_OF_ARGS);
+#endif
+			FrameLen = FrameLen + tmp;
+		}
+#endif // DOT11_N_SUPPORT //
+
+		if (pDLS && (pDLS->Status != DLS_FINISH))
+		{
+			RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
+			Timeout = DLS_TIMEOUT;
+			RTMPSetTimer(&pDLS->Timer, Timeout);
+		}
+	}
+	else
+	{
+		MakeOutgoingFrame(pOutBuffer,				&FrameLen,
+						sizeof(HEADER_802_11),		&DlsRspHdr,
+						1,							&Category,
+						1,							&Action,
+						2,							&StatusCode,
+						6,							SA,
+						6,							pAd->CurrentAddress,
+						END_OF_ARGS);
+	}
+
+	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+	MlmeFreeMemory(pAd, pOutBuffer);
+}
+
+/*
+    ==========================================================================
+    Description:
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+VOID PeerDlsRspAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem)
+{
+	USHORT		CapabilityInfo;
+	UCHAR		DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
+	USHORT		StatusCode;
+	SHORT		i;
+	BOOLEAN		TimerCancelled;
+	UCHAR		MaxSupportedRateIn500Kbps = 0;
+    UCHAR		SupportedRatesLen;
+    UCHAR		SupportedRates[MAX_LEN_OF_SUPPORTED_RATES];
+	UCHAR		HtCapabilityLen;
+	HT_CAPABILITY_IE	HtCapability;
+
+	if (!pAd->CommonCfg.bDLSCapable)
+		return;
+
+	if (!INFRA_ON(pAd))
+		return;
+
+	if (!PeerDlsRspSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &CapabilityInfo, &StatusCode,
+							&SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, &HtCapability))
+		return;
+
+    // supported rates array may not be sorted. sort it and find the maximum rate
+    for (i=0; i<SupportedRatesLen; i++)
+    {
+        if (MaxSupportedRateIn500Kbps < (SupportedRates[i] & 0x7f))
+            MaxSupportedRateIn500Kbps = SupportedRates[i] & 0x7f;
+    }
+
+	DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x with StatusCode=%d, CapabilityInfo=0x%x\n",
+		SA[0], SA[1], SA[2], SA[3], SA[4], SA[5], StatusCode, CapabilityInfo));
+
+	for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+	{
+		if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
+		{
+			if (StatusCode == MLME_SUCCESS)
+			{
+				MAC_TABLE_ENTRY *pEntry;
+				UCHAR MaxSupportedRate = RATE_11;
+
+				pEntry = MacTableInsertDlsEntry(pAd, SA, i);
+
+				switch (MaxSupportedRateIn500Kbps)
+				{
+					case 108: MaxSupportedRate = RATE_54;   break;
+					case 96:  MaxSupportedRate = RATE_48;   break;
+					case 72:  MaxSupportedRate = RATE_36;   break;
+					case 48:  MaxSupportedRate = RATE_24;   break;
+					case 36:  MaxSupportedRate = RATE_18;   break;
+					case 24:  MaxSupportedRate = RATE_12;   break;
+					case 18:  MaxSupportedRate = RATE_9;    break;
+					case 12:  MaxSupportedRate = RATE_6;    break;
+					case 22:  MaxSupportedRate = RATE_11;   break;
+					case 11:  MaxSupportedRate = RATE_5_5;  break;
+					case 4:   MaxSupportedRate = RATE_2;    break;
+					case 2:   MaxSupportedRate = RATE_1;    break;
+					default:  MaxSupportedRate = RATE_11;   break;
+				}
+
+				pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
+
+				if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
+				{
+					pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
+					pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+					pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
+					pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+					pEntry->HTPhyMode.field.MODE = MODE_CCK;
+					pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+				}
+				else
+				{
+					pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
+					pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+					pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
+					pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+					pEntry->HTPhyMode.field.MODE = MODE_OFDM;
+					pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+				}
+
+				pEntry->MaxHTPhyMode.field.BW = BW_20;
+				pEntry->MinHTPhyMode.field.BW = BW_20;
+
+#ifdef DOT11_N_SUPPORT
+				pEntry->HTCapability.MCSSet[0] = 0;
+				pEntry->HTCapability.MCSSet[1] = 0;
+
+				// If this Entry supports 802.11n, upgrade to HT rate.
+				if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+				{
+					UCHAR	j, bitmask; //k,bitmask;
+					CHAR    ii;
+
+					if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
+					{
+						pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
+					}
+					else
+					{
+						pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+						pAd->MacTab.fAnyStationNonGF = TRUE;
+						pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
+					}
+
+					if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
+					{
+						pEntry->MaxHTPhyMode.field.BW= BW_40;
+						pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
+					}
+					else
+					{
+						pEntry->MaxHTPhyMode.field.BW = BW_20;
+						pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
+						pAd->MacTab.fAnyStation20Only = TRUE;
+					}
+
+					// find max fixed rate
+					for (ii=15; ii>=0; ii--)
+					{
+						j = ii/8;
+						bitmask = (1<<(ii-(j*8)));
+						if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
+						{
+							pEntry->MaxHTPhyMode.field.MCS = ii;
+							break;
+						}
+						if (ii==0)
+							break;
+					}
+
+					if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
+					{
+						if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
+						{
+							// Fix MCS as HT Duplicated Mode
+							pEntry->MaxHTPhyMode.field.BW = 1;
+							pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+							pEntry->MaxHTPhyMode.field.STBC = 0;
+							pEntry->MaxHTPhyMode.field.ShortGI = 0;
+							pEntry->MaxHTPhyMode.field.MCS = 32;
+						}
+						else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
+						{
+							// STA supports fixed MCS
+							pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+						}
+					}
+
+					pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
+					pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
+					pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
+					pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
+					pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
+					pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+
+					if (HtCapability.HtCapInfo.ShortGIfor20)
+						CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
+					if (HtCapability.HtCapInfo.ShortGIfor40)
+						CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
+					if (HtCapability.HtCapInfo.TxSTBC)
+						CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
+					if (HtCapability.HtCapInfo.RxSTBC)
+						CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
+					if (HtCapability.ExtHtCapInfo.PlusHTC)
+						CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
+					if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
+						CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
+					if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
+						CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
+
+					NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
+				}
+#endif // DOT11_N_SUPPORT //
+				pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+				pEntry->CurrTxRate = pEntry->MaxSupportedRate;
+				CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
+
+				if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
+				{
+					PUCHAR pTable;
+					UCHAR TableSize = 0;
+
+					MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
+					pEntry->bAutoTxRateSwitch = TRUE;
+				}
+				else
+				{
+					pEntry->HTPhyMode.field.MODE	= pAd->StaCfg.HTPhyMode.field.MODE;
+					pEntry->HTPhyMode.field.MCS	= pAd->StaCfg.HTPhyMode.field.MCS;
+					pEntry->bAutoTxRateSwitch = FALSE;
+
+					RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
+				}
+				pEntry->RateLen = SupportedRatesLen;
+
+				if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+				{
+					// If support WPA or WPA2, start STAKey hand shake,
+					// If failed hand shake, just tear down peer DLS
+					if (RTMPSendSTAKeyRequest(pAd, pAd->StaCfg.DLSEntry[i].MacAddr) != NDIS_STATUS_SUCCESS)
+					{
+						MLME_DLS_REQ_STRUCT	MlmeDlsReq;
+						USHORT				reason = REASON_QOS_CIPHER_NOT_SUPPORT;
+
+						DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+						MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+						pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+						pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
+						DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed when call RTMPSendSTAKeyRequest \n"));
+					}
+					else
+					{
+						pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
+						DBGPRINT(RT_DEBUG_TRACE,("DLS - waiting for STAKey handshake procedure\n"));
+					}
+				}
+				else
+				{
+					RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+					pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
+					DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x Succeed with WEP or no security\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
+				}
+
+				//initialize seq no for DLS frames.
+				pAd->StaCfg.DLSEntry[i].Sequence = 0;
+				if (HtCapabilityLen != 0)
+					pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
+				else
+					pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
+			}
+			else
+			{
+				// DLS setup procedure failed.
+				pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+				pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
+				RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+				DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed with StatusCode=%d \n", StatusCode));
+			}
+		}
+	}
+
+	if (i >= MAX_NUM_OF_INIT_DLS_ENTRY)
+	{
+		DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() update timeout value \n"));
+		for (i=(MAX_NUM_OF_DLS_ENTRY-1); i>=MAX_NUM_OF_INIT_DLS_ENTRY; i--)
+		{
+			if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
+			{
+				if (StatusCode == MLME_SUCCESS)
+				{
+					MAC_TABLE_ENTRY *pEntry;
+					UCHAR MaxSupportedRate = RATE_11;
+
+					pEntry = MacTableInsertDlsEntry(pAd, SA, i);
+
+					switch (MaxSupportedRateIn500Kbps)
+					{
+						case 108: MaxSupportedRate = RATE_54;   break;
+						case 96:  MaxSupportedRate = RATE_48;   break;
+						case 72:  MaxSupportedRate = RATE_36;   break;
+						case 48:  MaxSupportedRate = RATE_24;   break;
+						case 36:  MaxSupportedRate = RATE_18;   break;
+						case 24:  MaxSupportedRate = RATE_12;   break;
+						case 18:  MaxSupportedRate = RATE_9;    break;
+						case 12:  MaxSupportedRate = RATE_6;    break;
+						case 22:  MaxSupportedRate = RATE_11;   break;
+						case 11:  MaxSupportedRate = RATE_5_5;  break;
+						case 4:   MaxSupportedRate = RATE_2;    break;
+						case 2:   MaxSupportedRate = RATE_1;    break;
+						default:  MaxSupportedRate = RATE_11;   break;
+					}
+
+					pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
+
+					if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
+					{
+						pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
+						pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+						pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
+						pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+						pEntry->HTPhyMode.field.MODE = MODE_CCK;
+						pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+					}
+					else
+					{
+						pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
+						pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+						pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
+						pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+						pEntry->HTPhyMode.field.MODE = MODE_OFDM;
+						pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+					}
+
+					pEntry->MaxHTPhyMode.field.BW = BW_20;
+					pEntry->MinHTPhyMode.field.BW = BW_20;
+
+#ifdef DOT11_N_SUPPORT
+					pEntry->HTCapability.MCSSet[0] = 0;
+					pEntry->HTCapability.MCSSet[1] = 0;
+
+					// If this Entry supports 802.11n, upgrade to HT rate.
+					if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+					{
+						UCHAR	j, bitmask; //k,bitmask;
+						CHAR    ii;
+
+						if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
+						{
+							pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
+						}
+						else
+						{
+							pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+							pAd->MacTab.fAnyStationNonGF = TRUE;
+							pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
+						}
+
+						if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
+						{
+							pEntry->MaxHTPhyMode.field.BW= BW_40;
+							pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
+						}
+						else
+						{
+							pEntry->MaxHTPhyMode.field.BW = BW_20;
+							pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
+							pAd->MacTab.fAnyStation20Only = TRUE;
+						}
+
+						// find max fixed rate
+						for (ii=15; ii>=0; ii--)
+						{
+							j = ii/8;
+							bitmask = (1<<(ii-(j*8)));
+							if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
+							{
+								pEntry->MaxHTPhyMode.field.MCS = ii;
+								break;
+							}
+							if (ii==0)
+								break;
+						}
+
+						if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
+						{
+							printk("@@@ pAd->CommonCfg.RegTransmitSetting.field.MCS = %d\n",
+								pAd->StaCfg.DesiredTransmitSetting.field.MCS);
+							if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
+							{
+								// Fix MCS as HT Duplicated Mode
+								pEntry->MaxHTPhyMode.field.BW = 1;
+								pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+								pEntry->MaxHTPhyMode.field.STBC = 0;
+								pEntry->MaxHTPhyMode.field.ShortGI = 0;
+								pEntry->MaxHTPhyMode.field.MCS = 32;
+							}
+							else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
+							{
+								// STA supports fixed MCS
+								pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+							}
+						}
+
+						pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
+						pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
+						pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
+						pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
+						pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
+						pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+
+						if (HtCapability.HtCapInfo.ShortGIfor20)
+							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
+						if (HtCapability.HtCapInfo.ShortGIfor40)
+							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
+						if (HtCapability.HtCapInfo.TxSTBC)
+							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
+						if (HtCapability.HtCapInfo.RxSTBC)
+							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
+						if (HtCapability.ExtHtCapInfo.PlusHTC)
+							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
+						if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
+							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
+						if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
+							CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
+
+						NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
+					}
+#endif // DOT11_N_SUPPORT //
+
+					pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+					pEntry->CurrTxRate = pEntry->MaxSupportedRate;
+					CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
+
+					if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
+					{
+						PUCHAR pTable;
+						UCHAR TableSize = 0;
+
+						MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
+						pEntry->bAutoTxRateSwitch = TRUE;
+					}
+					else
+					{
+						pEntry->HTPhyMode.field.MODE	= pAd->StaCfg.HTPhyMode.field.MODE;
+						pEntry->HTPhyMode.field.MCS	= pAd->StaCfg.HTPhyMode.field.MCS;
+						pEntry->bAutoTxRateSwitch = FALSE;
+
+						RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
+					}
+					pEntry->RateLen = SupportedRatesLen;
+
+					if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+					{
+						// If support WPA or WPA2, start STAKey hand shake,
+						// If failed hand shake, just tear down peer DLS
+						if (RTMPSendSTAKeyRequest(pAd, pAd->StaCfg.DLSEntry[i].MacAddr) != NDIS_STATUS_SUCCESS)
+						{
+							MLME_DLS_REQ_STRUCT	MlmeDlsReq;
+							USHORT				reason = REASON_QOS_CIPHER_NOT_SUPPORT;
+
+							DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+							MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+							pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+							pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
+							DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed when call RTMPSendSTAKeyRequest \n"));
+						}
+						else
+						{
+							pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
+							DBGPRINT(RT_DEBUG_TRACE,("DLS - waiting for STAKey handshake procedure\n"));
+						}
+					}
+					else
+					{
+						RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+						pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
+						DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x Succeed with WEP or no security\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
+					}
+					pAd->StaCfg.DLSEntry[i].Sequence = 0;
+					if (HtCapabilityLen != 0)
+						pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
+					else
+						pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
+				}
+				else
+				{
+					// DLS setup procedure failed.
+					pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+					pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
+					RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+					DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed with StatusCode=%d \n", StatusCode));
+				}
+			}
+		}
+	}
+}
+
+/*
+    ==========================================================================
+    Description:
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+VOID MlmeDlsTearDownAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem)
+{
+	PUCHAR			pOutBuffer = NULL;
+	NDIS_STATUS		NStatus;
+	ULONG			FrameLen = 0;
+	UCHAR			Category = CATEGORY_DLS;
+	UCHAR			Action = ACTION_DLS_TEARDOWN;
+	USHORT			ReasonCode = REASON_QOS_UNSPECIFY;
+	HEADER_802_11	DlsTearDownHdr;
+	PRT_802_11_DLS	pDLS;
+	BOOLEAN			TimerCancelled;
+	UCHAR			i;
+
+	if(!MlmeDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, &pDLS, &ReasonCode))
+		return;
+
+	DBGPRINT(RT_DEBUG_TRACE,("DLS - MlmeDlsTearDownAction() with ReasonCode=%d \n", ReasonCode));
+
+	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
+	if (NStatus != NDIS_STATUS_SUCCESS)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("DLS - MlmeDlsTearDownAction() allocate memory failed \n"));
+		return;
+	}
+
+	ActHeaderInit(pAd, &DlsTearDownHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+
+	// Build basic frame first
+	MakeOutgoingFrame(pOutBuffer,				&FrameLen,
+					sizeof(HEADER_802_11),		&DlsTearDownHdr,
+					1,							&Category,
+					1,							&Action,
+					6,							&pDLS->MacAddr,
+					6,							pAd->CurrentAddress,
+					2,							&ReasonCode,
+					END_OF_ARGS);
+
+	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+	MlmeFreeMemory(pAd, pOutBuffer);
+	RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
+
+	// Remove key in local dls table entry
+	for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+	{
+		if (MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
+		{
+			MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
+		}
+	}
+
+	// clear peer dls table entry
+	for (i = MAX_NUM_OF_INIT_DLS_ENTRY; i < MAX_NUM_OF_DLS_ENTRY; i++)
+	{
+		if (MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
+		{
+			pAd->StaCfg.DLSEntry[i].Status	= DLS_NONE;
+			pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
+			RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+			MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
+		}
+	}
+}
+
+/*
+    ==========================================================================
+    Description:
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+VOID PeerDlsTearDownAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem)
+{
+	UCHAR			DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
+	USHORT			ReasonCode;
+	UINT			i;
+	BOOLEAN			TimerCancelled;
+
+	if (!pAd->CommonCfg.bDLSCapable)
+		return;
+
+	if (!INFRA_ON(pAd))
+		return;
+
+	if (!PeerDlsTearDownSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &ReasonCode))
+		return;
+
+	DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsTearDownAction() from %02x:%02x:%02x:%02x:%02x:%02x with ReasonCode=%d\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5], ReasonCode));
+
+	// clear local dls table entry
+	for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+	{
+		if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
+		{
+			pAd->StaCfg.DLSEntry[i].Status	= DLS_NONE;
+			pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
+			RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+			//AsicDelWcidTab(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
+			//AsicRemovePairwiseKeyEntry(pAd, BSS0, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
+			MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
+		}
+	}
+
+	// clear peer dls table entry
+	for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+	{
+		if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
+		{
+			pAd->StaCfg.DLSEntry[i].Status	= DLS_NONE;
+			pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
+			RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+			//AsicDelWcidTab(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
+			//AsicRemovePairwiseKeyEntry(pAd, BSS0, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
+			MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
+		}
+	}
+}
+
+/*
+    ==========================================================================
+    Description:
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+VOID RTMPCheckDLSTimeOut(
+	IN PRTMP_ADAPTER	pAd)
+{
+	ULONG				i;
+	MLME_DLS_REQ_STRUCT	MlmeDlsReq;
+	USHORT				reason = REASON_QOS_UNSPECIFY;
+
+	if (! pAd->CommonCfg.bDLSCapable)
+		return;
+
+	if (! INFRA_ON(pAd))
+		return;
+
+	// If timeout value is equaled to zero, it means always not be timeout.
+
+	// update local dls table entry
+	for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+	{
+		if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
+			&& (pAd->StaCfg.DLSEntry[i].TimeOut != 0))
+		{
+			pAd->StaCfg.DLSEntry[i].CountDownTimer --;
+
+			if (pAd->StaCfg.DLSEntry[i].CountDownTimer == 0)
+			{
+				reason = REASON_QOS_REQUEST_TIMEOUT;
+				pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
+				pAd->StaCfg.DLSEntry[i].Status	= DLS_NONE;
+				DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+				MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+			}
+		}
+	}
+
+	// update peer dls table entry
+	for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+	{
+		if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
+			&& (pAd->StaCfg.DLSEntry[i].TimeOut != 0))
+		{
+			pAd->StaCfg.DLSEntry[i].CountDownTimer --;
+
+			if (pAd->StaCfg.DLSEntry[i].CountDownTimer == 0)
+			{
+				reason = REASON_QOS_REQUEST_TIMEOUT;
+				pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
+				pAd->StaCfg.DLSEntry[i].Status	= DLS_NONE;
+				DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+				MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+			}
+		}
+	}
+}
+
+/*
+    ==========================================================================
+    Description:
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+BOOLEAN RTMPRcvFrameDLSCheck(
+	IN PRTMP_ADAPTER	pAd,
+	IN PHEADER_802_11	pHeader,
+	IN ULONG			Len,
+	IN PRT28XX_RXD_STRUC	pRxD)
+{
+	ULONG			i;
+	BOOLEAN			bFindEntry = FALSE;
+	BOOLEAN			bSTAKeyFrame = FALSE;
+	PEAPOL_PACKET	pEap;
+	PUCHAR			pProto, pAddr = NULL;
+	PUCHAR			pSTAKey = NULL;
+	UCHAR			ZeroReplay[LEN_KEY_DESC_REPLAY];
+	UCHAR			Mic[16], OldMic[16];
+	UCHAR			digest[80];
+	UCHAR			DlsPTK[80];
+	UCHAR			temp[64];
+	BOOLEAN			TimerCancelled;
+	CIPHER_KEY		PairwiseKey;
+
+
+	if (! pAd->CommonCfg.bDLSCapable)
+		return bSTAKeyFrame;
+
+	if (! INFRA_ON(pAd))
+		return bSTAKeyFrame;
+
+	if (! (pHeader->FC.SubType & 0x08))
+		return bSTAKeyFrame;
+
+	if (Len < LENGTH_802_11 + 6 + 2 + 2)
+		return bSTAKeyFrame;
+
+	pProto	= (PUCHAR)pHeader + LENGTH_802_11 + 2 + 6;	// QOS Control field , 0xAA 0xAA 0xAA 0x00 0x00 0x00
+	pAddr	= pHeader->Addr2;
+
+	// L2PAD bit on will pad 2 bytes at LLC
+	if (pRxD->L2PAD)
+	{
+		pProto += 2;
+	}
+
+	if (RTMPEqualMemory(EAPOL, pProto, 2) && (pAd->StaCfg.AuthMode >=  Ndis802_11AuthModeWPA))
+	{
+		pEap = (PEAPOL_PACKET) (pProto + 2);
+
+		DBGPRINT(RT_DEBUG_TRACE,("DLS - Sniff Len=%ld, DataLen=%d, KeyMic=%d, Install=%d, KeyAck=%d, Secure=%d, EKD_DL=%d, Error=%d, Request=%d\n", Len,
+			                                                             (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE + 16),
+			                                                             pEap->KeyDesc.KeyInfo.KeyMic,
+			                                                             pEap->KeyDesc.KeyInfo.Install,
+			                                                             pEap->KeyDesc.KeyInfo.KeyAck,
+			                                                             pEap->KeyDesc.KeyInfo.Secure,
+			                                                             pEap->KeyDesc.KeyInfo.EKD_DL,
+			                                                             pEap->KeyDesc.KeyInfo.Error,
+			                                                             pEap->KeyDesc.KeyInfo.Request));
+
+		if ((Len >= (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE + 16)) && pEap->KeyDesc.KeyInfo.KeyMic
+			&& pEap->KeyDesc.KeyInfo.Install && pEap->KeyDesc.KeyInfo.KeyAck && pEap->KeyDesc.KeyInfo.Secure
+			&& pEap->KeyDesc.KeyInfo.EKD_DL && !pEap->KeyDesc.KeyInfo.Error && !pEap->KeyDesc.KeyInfo.Request)
+		{
+			// First validate replay counter, only accept message with larger replay counter
+			// Let equal pass, some AP start with all zero replay counter
+			NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
+			if ((RTMPCompareMemory(pEap->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1) &&
+				(RTMPCompareMemory(pEap->KeyDesc.ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
+				return bSTAKeyFrame;
+
+			//RTMPMoveMemory(pAd->StaCfg.ReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+			RTMPMoveMemory(pAd->StaCfg.DlsReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+			DBGPRINT(RT_DEBUG_TRACE,("DLS - Sniff replay counter (%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x) Len=%ld, KeyDataLen=%d\n",
+				pAd->StaCfg.ReplayCounter[0], pAd->StaCfg.ReplayCounter[1], pAd->StaCfg.ReplayCounter[2],
+				pAd->StaCfg.ReplayCounter[3], pAd->StaCfg.ReplayCounter[4],	pAd->StaCfg.ReplayCounter[5],
+				pAd->StaCfg.ReplayCounter[6], pAd->StaCfg.ReplayCounter[7], Len, pEap->KeyDesc.KeyData[1]));
+
+			// put these code segment to get the replay counter
+			if (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)
+				return bSTAKeyFrame;
+
+			// Check MIC value
+			// Save the MIC and replace with zero
+			// use proprietary PTK
+			NdisZeroMemory(temp, 64);
+			NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
+			WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
+
+			NdisMoveMemory(OldMic, pEap->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+			NdisZeroMemory(pEap->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+			if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+			{
+				// AES
+				HMAC_SHA1((PUCHAR) pEap, pEap->Body_Len[1] + 4, DlsPTK, LEN_EAP_MICK, digest);
+				NdisMoveMemory(Mic,	digest,	LEN_KEY_DESC_MIC);
+			}
+			else
+			{
+				hmac_md5(DlsPTK, LEN_EAP_MICK, (PUCHAR) pEap, pEap->Body_Len[1] + 4, Mic);
+			}
+
+			if (!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
+			{
+				DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in Msg1 of STAKey handshake! \n"));
+				return bSTAKeyFrame;
+			}
+			else
+				DBGPRINT(RT_DEBUG_TRACE, ("MIC VALID in Msg1 of STAKey handshake! \n"));
+#if 1
+			if ((pEap->KeyDesc.KeyData[0] == 0xDD) && (pEap->KeyDesc.KeyData[2] == 0x00) && (pEap->KeyDesc.KeyData[3] == 0x0C)
+				&& (pEap->KeyDesc.KeyData[4] == 0x43) && (pEap->KeyDesc.KeyData[5] == 0x02))
+			{
+				pAddr			= pEap->KeyDesc.KeyData + 8;		// Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2)
+				pSTAKey			= pEap->KeyDesc.KeyData + 14;	// Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2), STAKey_Mac_Addr(6)
+
+				DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 from %02x:%02x:%02x:%02x:%02x:%02x Len=%ld, KeyDataLen=%d\n",
+					pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5], Len, pEap->KeyDesc.KeyData[1]));
+
+				bSTAKeyFrame = TRUE;
+			}
+#else
+			if ((pEap->KeyDesc.KeyData[0] == 0xDD) && (pEap->KeyDesc.KeyData[2] == 0x00) && (pEap->KeyDesc.KeyData[3] == 0x0F)
+				&& (pEap->KeyDesc.KeyData[4] == 0xAC) && (pEap->KeyDesc.KeyData[5] == 0x02))
+			{
+				pAddr			= pEap->KeyDesc.KeyData + 8;		// Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2)
+				pSTAKey			= pEap->KeyDesc.KeyData + 14;	// Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2), STAKey_Mac_Addr(6)
+
+				DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 from %02x:%02x:%02x:%02x:%02x:%02x Len=%d, KeyDataLen=%d\n",
+					pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5], Len, pEap->KeyDesc.KeyData[1]));
+
+				bSTAKeyFrame = TRUE;
+			}
+#endif
+
+		}
+		else if (Len >= (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE))
+		{
+			RTMPMoveMemory(pAd->StaCfg.DlsReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+			DBGPRINT(RT_DEBUG_TRACE,("DLS - Sniff replay counter 2(%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x) Len=%ld, KeyDataLen=%d\n",
+				pAd->StaCfg.ReplayCounter[0], pAd->StaCfg.ReplayCounter[1], pAd->StaCfg.ReplayCounter[2],
+				pAd->StaCfg.ReplayCounter[3], pAd->StaCfg.ReplayCounter[4],	pAd->StaCfg.ReplayCounter[5],
+				pAd->StaCfg.ReplayCounter[6], pAd->StaCfg.ReplayCounter[7], Len, pEap->KeyDesc.KeyData[1]));
+
+		}
+	}
+
+	// If timeout value is equaled to zero, it means always not be timeout.
+	// update local dls table entry
+	for (i= 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+	{
+		if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
+		{
+			if (bSTAKeyFrame)
+			{
+				PMAC_TABLE_ENTRY pEntry;
+
+				// STAKey frame, add pairwise key table
+				pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
+				RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+
+				PairwiseKey.KeyLen = LEN_TKIP_EK;
+				NdisMoveMemory(PairwiseKey.Key, &pSTAKey[0], LEN_TKIP_EK);
+				NdisMoveMemory(PairwiseKey.TxMic, &pSTAKey[16], LEN_TKIP_RXMICK);
+				NdisMoveMemory(PairwiseKey.RxMic, &pSTAKey[24], LEN_TKIP_TXMICK);
+
+				PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg;
+
+				pEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
+				//AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE);	// reserve 0 for multicast, 1 for unicast
+				//AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
+				// Add Pair-wise key to Asic
+#ifdef RT2870
+//Benson modified for USB interface, avoid in interrupt when write key, 20080724 -->
+                                {
+                                        RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo;
+                                        COPY_MAC_ADDR(KeyInfo.MacAddr,pAd->StaCfg.DLSEntry[i].MacAddr);
+                                        KeyInfo.MacTabMatchWCID=pAd->StaCfg.DLSEntry[i].MacTabMatchWCID;
+                                        NdisMoveMemory(&KeyInfo.CipherKey,  &PairwiseKey,sizeof(CIPHER_KEY));
+                                        RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_KEY_TABLE, &KeyInfo, sizeof(RT_ADD_PAIRWISE_KEY_ENTRY));
+                                }
+                                {
+                                        PMAC_TABLE_ENTRY pDLSEntry;
+                                        pDLSEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
+                                        pDLSEntry->PairwiseKey.CipherAlg=PairwiseKey.CipherAlg;
+                                        RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_RX_WCID_TABLE, pDLSEntry, sizeof(MAC_TABLE_ENTRY));
+                                }
+//Benson modified for USB interface, avoid in interrupt when write key, 20080724 <--
+#endif // RT2870 //
+				NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
+				DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Peer STA MAC Address STAKey) \n"));
+
+				RTMPSendSTAKeyHandShake(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
+
+				DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Initiator side)\n"));
+			}
+			else
+			{
+				// Data frame, update timeout value
+				if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
+				{
+					pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
+					//AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
+				}
+			}
+
+			bFindEntry = TRUE;
+		}
+	}
+
+	// update peer dls table entry
+	for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+	{
+		if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
+		{
+			if (bSTAKeyFrame)
+			{
+				PMAC_TABLE_ENTRY pEntry = NULL;
+
+				// STAKey frame, add pairwise key table, and send STAkey Msg-2
+				pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
+				RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+
+				PairwiseKey.KeyLen = LEN_TKIP_EK;
+				NdisMoveMemory(PairwiseKey.Key, &pSTAKey[0], LEN_TKIP_EK);
+				NdisMoveMemory(PairwiseKey.TxMic, &pSTAKey[16], LEN_TKIP_RXMICK);
+				NdisMoveMemory(PairwiseKey.RxMic, &pSTAKey[24], LEN_TKIP_TXMICK);
+
+				PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg;
+
+				pEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
+				//AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE);	// reserve 0 for multicast, 1 for unicast
+				//AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
+				// Add Pair-wise key to Asic
+#ifdef RT2870
+//Benson modified for USB interface, avoid in interrupt when write key, 20080724 -->
+                                {
+                                        RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo;
+                                        COPY_MAC_ADDR(KeyInfo.MacAddr,pAd->StaCfg.DLSEntry[i].MacAddr);
+                                        KeyInfo.MacTabMatchWCID=pAd->StaCfg.DLSEntry[i].MacTabMatchWCID;
+                                        NdisMoveMemory(&KeyInfo.CipherKey,  &PairwiseKey,sizeof(CIPHER_KEY));
+                                        RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_KEY_TABLE, &KeyInfo, sizeof(RT_ADD_PAIRWISE_KEY_ENTRY));
+                                }
+                                {
+                                        PMAC_TABLE_ENTRY pDLSEntry;
+                                        pDLSEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
+                                        pDLSEntry->PairwiseKey.CipherAlg=PairwiseKey.CipherAlg;
+                                        RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_RX_WCID_TABLE, pDLSEntry, sizeof(MAC_TABLE_ENTRY));
+                                }
+//Benson modified for USB interface, avoid in interrupt when write key, 20080724 <--
+#endif // RT2870 //
+				NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
+				DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Initiator STA MAC Address STAKey)\n"));
+
+				// If support WPA or WPA2, start STAKey hand shake,
+				// If failed hand shake, just tear down peer DLS
+				if (RTMPSendSTAKeyHandShake(pAd, pAddr) != NDIS_STATUS_SUCCESS)
+				{
+					MLME_DLS_REQ_STRUCT	MlmeDlsReq;
+					USHORT				reason = REASON_QOS_CIPHER_NOT_SUPPORT;
+
+					pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
+					pAd->StaCfg.DLSEntry[i].Status	= DLS_NONE;
+					DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+					MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+				}
+				else
+				{
+					DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Peer side)\n"));
+				}
+			}
+			else
+			{
+				// Data frame, update timeout value
+				if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
+				{
+					pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
+				}
+			}
+
+			bFindEntry = TRUE;
+		}
+	}
+
+
+	return bSTAKeyFrame;
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Check if the frame can be sent through DLS direct link interface
+
+	Arguments:
+		pAd		Pointer	to adapter
+
+	Return Value:
+		DLS entry index
+
+	Note:
+
+	========================================================================
+*/
+INT	RTMPCheckDLSFrame(
+	IN	PRTMP_ADAPTER	pAd,
+	IN  PUCHAR          pDA)
+{
+	INT rval = -1;
+	INT	i;
+
+	if (!pAd->CommonCfg.bDLSCapable)
+		return rval;
+
+	if (!INFRA_ON(pAd))
+		return rval;
+
+	do{
+		// check local dls table entry
+		for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+		{
+			if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
+				MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
+			{
+				rval = i;
+				break;
+			}
+		}
+
+		// check peer dls table entry
+		for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+		{
+			if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
+				MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
+			{
+				rval = i;
+				break;
+			}
+		}
+	} while (FALSE);
+
+	return rval;
+}
+
+/*
+    ==========================================================================
+    Description:
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+VOID RTMPSendDLSTearDownFrame(
+	IN	PRTMP_ADAPTER	pAd,
+	IN  PUCHAR          pDA)
+{
+	PUCHAR			pOutBuffer = NULL;
+	NDIS_STATUS		NStatus;
+	HEADER_802_11	DlsTearDownHdr;
+	ULONG			FrameLen = 0;
+	USHORT			Reason = REASON_QOS_QSTA_LEAVING_QBSS;
+	UCHAR			Category = CATEGORY_DLS;
+	UCHAR			Action = ACTION_DLS_TEARDOWN;
+	UCHAR			i = 0;
+
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
+		RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
+		return;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame \n"));
+
+	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
+	if (NStatus != NDIS_STATUS_SUCCESS)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("ASSOC - RTMPSendDLSTearDownFrame() allocate memory failed \n"));
+		return;
+	}
+
+	ActHeaderInit(pAd, &DlsTearDownHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+	MakeOutgoingFrame(pOutBuffer,				&FrameLen,
+					sizeof(HEADER_802_11),		&DlsTearDownHdr,
+					1,							&Category,
+					1,							&Action,
+					6,							pDA,
+					6,							pAd->CurrentAddress,
+					2,							&Reason,
+					END_OF_ARGS);
+
+	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+	MlmeFreeMemory(pAd, pOutBuffer);
+
+	// Remove key in local dls table entry
+	for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+	{
+		if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
+			&& MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
+		{
+			MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
+		}
+	}
+
+	// Remove key in peer dls table entry
+	for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+	{
+		if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
+			&& MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
+		{
+			MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
+		}
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame and remove key in (i=%d) \n", i));
+}
+
+/*
+    ==========================================================================
+    Description:
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+NDIS_STATUS RTMPSendSTAKeyRequest(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pDA)
+{
+	UCHAR				Header802_3[14];
+	NDIS_STATUS			NStatus;
+	ULONG				FrameLen = 0;
+	EAPOL_PACKET		Packet;
+	UCHAR				Mic[16];
+	UCHAR				digest[80];
+	PUCHAR				pOutBuffer = NULL;
+	PNDIS_PACKET		pNdisPacket;
+	UCHAR				temp[64];
+	UCHAR				DlsPTK[80];
+
+	DBGPRINT(RT_DEBUG_TRACE,("DLS - RTMPSendSTAKeyRequest() to %02x:%02x:%02x:%02x:%02x:%02x\n", pDA[0], pDA[1], pDA[2], pDA[3], pDA[4], pDA[5]));
+
+	pAd->Sequence ++;
+	MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
+
+	// Zero message body
+	NdisZeroMemory(&Packet, sizeof(Packet));
+	Packet.ProVer = EAPOL_VER;
+	Packet.ProType    = EAPOLKey;
+	Packet.Body_Len[1]  = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + 6 + MAC_ADDR_LEN;		// data field contain KDE andPeer MAC address
+
+	// STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
+	if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
+    {
+        Packet.KeyDesc.Type = WPA1_KEY_DESC;
+    }
+    else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+    {
+        Packet.KeyDesc.Type = WPA2_KEY_DESC;
+    }
+
+	// Key descriptor version
+	Packet.KeyDesc.KeyInfo.KeyDescVer =
+		(((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) || (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
+
+	Packet.KeyDesc.KeyInfo.KeyMic	= 1;
+	Packet.KeyDesc.KeyInfo.Secure	= 1;
+	Packet.KeyDesc.KeyInfo.Request	= 1;
+
+	Packet.KeyDesc.KeyDataLen[1]	= 12;
+
+	// use our own OUI to distinguish proprietary with standard.
+	Packet.KeyDesc.KeyData[0]		= 0xDD;
+	Packet.KeyDesc.KeyData[1]		= 0x0A;
+	Packet.KeyDesc.KeyData[2]		= 0x00;
+	Packet.KeyDesc.KeyData[3]		= 0x0C;
+	Packet.KeyDesc.KeyData[4]		= 0x43;
+	Packet.KeyDesc.KeyData[5]		= 0x03;
+	NdisMoveMemory(&Packet.KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN);
+
+	NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY);
+
+	// Allocate buffer for transmitting message
+	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+	if (NStatus	!= NDIS_STATUS_SUCCESS)
+		return NStatus;
+
+	// Prepare EAPOL frame for MIC calculation
+	// Be careful, only EAPOL frame is counted for MIC calculation
+	MakeOutgoingFrame(pOutBuffer,           &FrameLen,
+		              Packet.Body_Len[1] + 4,    &Packet,
+		              END_OF_ARGS);
+
+	// use proprietary PTK
+	NdisZeroMemory(temp, 64);
+	NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
+	WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
+
+	// calculate MIC
+	if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+	{
+		// AES
+		NdisZeroMemory(digest,	sizeof(digest));
+		HMAC_SHA1(pOutBuffer, FrameLen, DlsPTK, LEN_EAP_MICK, digest);
+		NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
+	}
+	else
+	{
+		NdisZeroMemory(Mic,	sizeof(Mic));
+		hmac_md5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
+		NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
+	}
+
+	MakeOutgoingFrame(pOutBuffer,           &FrameLen,
+	                  sizeof(Header802_3),	Header802_3,
+		              Packet.Body_Len[1] + 4,	&Packet,
+		              END_OF_ARGS);
+
+	NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen);
+	if (NStatus == NDIS_STATUS_SUCCESS)
+	{
+		RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID);
+		STASendPacket(pAd, pNdisPacket);
+		RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+	}
+
+	MlmeFreeMemory(pAd, pOutBuffer);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyRequest- Send STAKey request (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen));
+
+	return NStatus;
+}
+
+/*
+    ==========================================================================
+    Description:
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+NDIS_STATUS RTMPSendSTAKeyHandShake(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pDA)
+{
+	UCHAR				Header802_3[14];
+	NDIS_STATUS			NStatus;
+	ULONG				FrameLen = 0;
+	EAPOL_PACKET		Packet;
+	UCHAR				Mic[16];
+	UCHAR				digest[80];
+	PUCHAR				pOutBuffer = NULL;
+	PNDIS_PACKET		pNdisPacket;
+	UCHAR				temp[64];
+	UCHAR				DlsPTK[80];			// Due to dirver can not get PTK, use proprietary PTK
+
+	DBGPRINT(RT_DEBUG_TRACE,("DLS - RTMPSendSTAKeyHandShake() to %02x:%02x:%02x:%02x:%02x:%02x\n", pDA[0], pDA[1], pDA[2], pDA[3], pDA[4], pDA[5]));
+
+	pAd->Sequence ++;
+	MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
+
+	// Zero message body
+	NdisZeroMemory(&Packet, sizeof(Packet));
+	Packet.ProVer = EAPOL_VER;
+	Packet.ProType    = EAPOLKey;
+	Packet.Body_Len[1]  = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + 6 + MAC_ADDR_LEN;		// data field contain KDE and Peer MAC address
+
+	// STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
+	if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
+    {
+        Packet.KeyDesc.Type = WPA1_KEY_DESC;
+    }
+    else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+    {
+        Packet.KeyDesc.Type = WPA2_KEY_DESC;
+    }
+
+	// Key descriptor version
+	Packet.KeyDesc.KeyInfo.KeyDescVer =
+		(((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) || (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
+
+	Packet.KeyDesc.KeyInfo.KeyMic	= 1;
+	Packet.KeyDesc.KeyInfo.Secure	= 1;
+
+	Packet.KeyDesc.KeyDataLen[1]	= 12;
+
+	// use our own OUI to distinguish proprietary with standard.
+	Packet.KeyDesc.KeyData[0]		= 0xDD;
+	Packet.KeyDesc.KeyData[1]		= 0x0A;
+	Packet.KeyDesc.KeyData[2]		= 0x00;
+	Packet.KeyDesc.KeyData[3]		= 0x0C;
+	Packet.KeyDesc.KeyData[4]		= 0x43;
+	Packet.KeyDesc.KeyData[5]		= 0x03;
+	NdisMoveMemory(&Packet.KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN);
+
+	NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY);
+
+	// Allocate buffer for transmitting message
+	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+	if (NStatus	!= NDIS_STATUS_SUCCESS)
+		return NStatus;
+
+	// Prepare EAPOL frame for MIC calculation
+	// Be careful, only EAPOL frame is counted for MIC calculation
+	MakeOutgoingFrame(pOutBuffer,           &FrameLen,
+		              Packet.Body_Len[1] + 4,    &Packet,
+		              END_OF_ARGS);
+
+	// use proprietary PTK
+	NdisZeroMemory(temp, 64);
+	NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
+	WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
+
+	// calculate MIC
+	if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+	{
+		// AES
+		NdisZeroMemory(digest,	sizeof(digest));
+		HMAC_SHA1(pOutBuffer, FrameLen, DlsPTK, LEN_EAP_MICK, digest);
+		NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
+	}
+	else
+	{
+		NdisZeroMemory(Mic,	sizeof(Mic));
+		hmac_md5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
+		NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
+	}
+
+	MakeOutgoingFrame(pOutBuffer,           &FrameLen,
+	                  sizeof(Header802_3),	Header802_3,
+		              Packet.Body_Len[1] + 4,	&Packet,
+		              END_OF_ARGS);
+
+	NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen);
+	if (NStatus == NDIS_STATUS_SUCCESS)
+	{
+		RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID);
+		STASendPacket(pAd, pNdisPacket);
+		RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+	}
+
+	MlmeFreeMemory(pAd, pOutBuffer);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyHandShake- Send STAKey Message-2 (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen));
+
+	return NStatus;
+}
+
+VOID DlsTimeoutAction(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3)
+{
+	MLME_DLS_REQ_STRUCT		MlmeDlsReq;
+	USHORT					reason;
+	PRT_802_11_DLS			pDLS = (PRT_802_11_DLS)FunctionContext;
+	PRTMP_ADAPTER			pAd = pDLS->pAd;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("DlsTimeout - Tear down DLS links (%02x:%02x:%02x:%02x:%02x:%02x)\n",
+		pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5]));
+
+	if ((pDLS) && (pDLS->Valid))
+	{
+		reason			= REASON_QOS_REQUEST_TIMEOUT;
+		pDLS->Valid		= FALSE;
+		pDLS->Status	= DLS_NONE;
+		DlsParmFill(pAd, &MlmeDlsReq, pDLS, reason);
+		MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+		RT28XX_MLME_HANDLER(pAd);
+	}
+}
+
+/*
+================================================================
+Description : because DLS and CLI share the same WCID table in ASIC.
+Mesh entry also insert to pAd->MacTab.content[].  Such is marked as ValidAsDls = TRUE.
+Also fills the pairwise key.
+Because front MAX_AID_BA entries have direct mapping to BAEntry, which is only used as CLI. So we insert Dls
+from index MAX_AID_BA.
+================================================================
+*/
+MAC_TABLE_ENTRY *MacTableInsertDlsEntry(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR	pAddr,
+	IN  UINT	DlsEntryIdx)
+{
+	PMAC_TABLE_ENTRY pEntry = NULL;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableInsertDlsEntry\n"));
+	// if FULL, return
+	if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
+		return NULL;
+
+	do
+	{
+		if((pEntry = DlsEntryTableLookup(pAd, pAddr, TRUE)) != NULL)
+			break;
+
+		// allocate one MAC entry
+		pEntry = MacTableInsertEntry(pAd, pAddr, DlsEntryIdx + MIN_NET_DEVICE_FOR_DLS, TRUE);
+		if (pEntry)
+		{
+			pAd->StaCfg.DLSEntry[DlsEntryIdx].MacTabMatchWCID = pEntry->Aid;
+			pEntry->MatchDlsEntryIdx = DlsEntryIdx;
+			pEntry->AuthMode = pAd->StaCfg.AuthMode;
+			pEntry->WepStatus = pAd->StaCfg.WepStatus;
+
+			DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertDlsEntry - allocate entry #%d, Total= %d\n",pEntry->Aid, pAd->MacTab.Size));
+
+			// If legacy WEP is used, set pair-wise cipherAlg into WCID attribute table for this entry
+			if ((pEntry->ValidAsDls) && (pEntry->WepStatus == Ndis802_11WEPEnabled))
+			{
+				UCHAR KeyIdx = 0;
+				UCHAR CipherAlg = 0;
+
+				KeyIdx	= pAd->StaCfg.DefaultKeyId;
+
+				CipherAlg 	= pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
+
+				RTMPAddWcidAttributeEntry(pAd,
+											BSS0,
+											pAd->StaCfg.DefaultKeyId,
+											pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
+											pEntry);
+			}
+
+			break;
+		}
+	} while(FALSE);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableInsertDlsEntry\n"));
+
+	return pEntry;
+}
+
+
+/*
+	==========================================================================
+	Description:
+		Delete all Mesh Entry in pAd->MacTab
+	==========================================================================
+ */
+BOOLEAN MacTableDeleteDlsEntry(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT wcid,
+	IN PUCHAR pAddr)
+{
+	DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableDeleteDlsEntry\n"));
+
+	if (!VALID_WCID(wcid))
+		return FALSE;
+
+	MacTableDeleteEntry(pAd, wcid, pAddr);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableDeleteDlsEntry\n"));
+
+	return TRUE;
+}
+
+MAC_TABLE_ENTRY *DlsEntryTableLookup(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR	pAddr,
+	IN BOOLEAN	bResetIdelCount)
+{
+	ULONG HashIdx;
+	MAC_TABLE_ENTRY *pEntry = NULL;
+
+	RTMP_SEM_LOCK(&pAd->MacTabLock);
+	HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
+	pEntry = pAd->MacTab.Hash[HashIdx];
+
+	while (pEntry)
+	{
+		if ((pEntry->ValidAsDls == TRUE)
+			&& MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
+		{
+			if(bResetIdelCount)
+				pEntry->NoDataIdleCount = 0;
+			break;
+		}
+		else
+			pEntry = pEntry->pNext;
+	}
+
+	RTMP_SEM_UNLOCK(&pAd->MacTabLock);
+	return pEntry;
+}
+
+MAC_TABLE_ENTRY *DlsEntryTableLookupByWcid(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR	wcid,
+	IN PUCHAR	pAddr,
+	IN BOOLEAN	bResetIdelCount)
+{
+	ULONG DLsIndex;
+	PMAC_TABLE_ENTRY pCurEntry = NULL;
+	PMAC_TABLE_ENTRY pEntry = NULL;
+
+	if (!VALID_WCID(wcid))
+		return NULL;
+
+	RTMP_SEM_LOCK(&pAd->MacTabLock);
+
+	do
+	{
+		pCurEntry = &pAd->MacTab.Content[wcid];
+
+		DLsIndex = 0xff;
+		if ((pCurEntry) && (pCurEntry->ValidAsDls== TRUE))
+		{
+			DLsIndex = pCurEntry->MatchDlsEntryIdx;
+		}
+
+		if (DLsIndex == 0xff)
+			break;
+
+		if (MAC_ADDR_EQUAL(pCurEntry->Addr, pAddr))
+		{
+			if(bResetIdelCount)
+				pCurEntry->NoDataIdleCount = 0;
+			pEntry = pCurEntry;
+			break;
+		}
+	} while(FALSE);
+
+	RTMP_SEM_UNLOCK(&pAd->MacTabLock);
+
+	return pEntry;
+}
+
+INT Set_DlsEntryInfo_Display_Proc(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR arg)
+{
+	INT i;
+
+	printk("\n%-19s%-8s\n", "MAC", "TIMEOUT\n");
+	for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
+	{
+		if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
+		{
+			printk("%02x:%02x:%02x:%02x:%02x:%02x  ",
+				pAd->StaCfg.DLSEntry[i].MacAddr[0], pAd->StaCfg.DLSEntry[i].MacAddr[1], pAd->StaCfg.DLSEntry[i].MacAddr[2],
+				pAd->StaCfg.DLSEntry[i].MacAddr[3], pAd->StaCfg.DLSEntry[i].MacAddr[4], pAd->StaCfg.DLSEntry[i].MacAddr[5]);
+			printk("%-8d\n", pAd->StaCfg.DLSEntry[i].TimeOut);
+		}
+	}
+
+	return TRUE;
+}
+
+INT	Set_DlsAddEntry_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+    UCHAR	mac[MAC_ADDR_LEN];
+	USHORT	Timeout;
+	char *token, sepValue[] = ":", DASH = '-';
+	INT i;
+    RT_802_11_DLS	Dls;
+
+    if(strlen(arg) < 19)  //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and timeout value in decimal format.
+		return FALSE;
+
+	token = strchr(arg, DASH);
+	if ((token != NULL) && (strlen(token)>1))
+	{
+		Timeout = simple_strtol((token+1), 0, 10);
+
+		*token = '\0';
+		for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
+		{
+			if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
+				return FALSE;
+			AtoH(token, (PUCHAR)(&mac[i]), 1);
+		}
+		if(i != 6)
+			return FALSE;
+
+	    printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%d", mac[0], mac[1],
+	           mac[2], mac[3], mac[4], mac[5], (int)Timeout);
+
+		NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
+		Dls.TimeOut = Timeout;
+		COPY_MAC_ADDR(Dls.MacAddr, mac);
+		Dls.Valid = 1;
+
+		MlmeEnqueue(pAd,
+					MLME_CNTL_STATE_MACHINE,
+					RT_OID_802_11_SET_DLS_PARAM,
+					sizeof(RT_802_11_DLS),
+					&Dls);
+
+		return TRUE;
+	}
+
+	return FALSE;
+
+}
+
+INT	Set_DlsTearDownEntry_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	UCHAR			macAddr[MAC_ADDR_LEN];
+	CHAR			*value;
+	INT				i;
+	RT_802_11_DLS	Dls;
+
+	if(strlen(arg) != 17)  //Mac address acceptable format 01:02:03:04:05:06 length 17
+		return FALSE;
+
+	for (i=0, value = rstrtok(arg,":"); value; value = rstrtok(NULL,":"))
+	{
+		if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
+			return FALSE;  //Invalid
+
+		AtoH(value, &macAddr[i++], 2);
+	}
+
+	printk("\n%02x:%02x:%02x:%02x:%02x:%02x", macAddr[0], macAddr[1],
+	           macAddr[2], macAddr[3], macAddr[4], macAddr[5]);
+
+	NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
+	COPY_MAC_ADDR(Dls.MacAddr, macAddr);
+	Dls.Valid = 0;
+
+	MlmeEnqueue(pAd,
+				MLME_CNTL_STATE_MACHINE,
+				RT_OID_802_11_SET_DLS_PARAM,
+				sizeof(RT_802_11_DLS),
+				&Dls);
+
+	return TRUE;
+}
+
diff --git a/drivers/staging/rt3070/sta/rtmp_data.c b/drivers/staging/rt3070/sta/rtmp_data.c
new file mode 100644
index 0000000..b0f259b
--- /dev/null
+++ b/drivers/staging/rt3070/sta/rtmp_data.c
@@ -0,0 +1,2637 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	rtmp_data.c
+
+	Abstract:
+	Data path subroutines
+
+	Revision History:
+	Who 		When			What
+	--------	----------		----------------------------------------------
+	John		      Aug/17/04		major modification for RT2561/2661
+	Jan Lee	      Mar/17/06		major modification for RT2860 New Ring Design
+*/
+#include "../rt_config.h"
+
+
+
+VOID STARxEAPOLFrameIndicate(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	MAC_TABLE_ENTRY	*pEntry,
+	IN	RX_BLK			*pRxBlk,
+	IN	UCHAR			FromWhichBSSID)
+{
+	PRT28XX_RXD_STRUC	pRxD = &(pRxBlk->RxD);
+	PRXWI_STRUC		pRxWI = pRxBlk->pRxWI;
+	UCHAR			*pTmpBuf;
+
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+	if (pAd->StaCfg.WpaSupplicantUP)
+	{
+		// All EAPoL frames have to pass to upper layer (ex. WPA_SUPPLICANT daemon)
+		// TBD : process fragmented EAPol frames
+		{
+			// In 802.1x mode, if the received frame is EAP-SUCCESS packet, turn on the PortSecured variable
+			if ( pAd->StaCfg.IEEE8021X == TRUE &&
+				 (EAP_CODE_SUCCESS == WpaCheckEapCode(pAd, pRxBlk->pData, pRxBlk->DataSize, LENGTH_802_1_H)))
+			{
+				PUCHAR	Key;
+				UCHAR 	CipherAlg;
+				int     idx = 0;
+
+				DBGPRINT_RAW(RT_DEBUG_TRACE, ("Receive EAP-SUCCESS Packet\n"));
+				//pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+				STA_PORT_SECURED(pAd);
+
+                if (pAd->StaCfg.IEEE8021x_required_keys == FALSE)
+                {
+                    idx = pAd->StaCfg.DesireSharedKeyId;
+                    CipherAlg = pAd->StaCfg.DesireSharedKey[idx].CipherAlg;
+					Key = pAd->StaCfg.DesireSharedKey[idx].Key;
+
+                    if (pAd->StaCfg.DesireSharedKey[idx].KeyLen > 0)
+    				{
+#ifdef RT2870
+						union
+						{
+							char buf[sizeof(NDIS_802_11_WEP)+MAX_LEN_OF_KEY- 1];
+							NDIS_802_11_WEP keyinfo;
+						}  WepKey;
+						int len;
+
+
+						NdisZeroMemory(&WepKey, sizeof(WepKey));
+						len =pAd->StaCfg.DesireSharedKey[idx].KeyLen;
+
+						NdisMoveMemory(WepKey.keyinfo.KeyMaterial,
+							pAd->StaCfg.DesireSharedKey[idx].Key,
+							pAd->StaCfg.DesireSharedKey[idx].KeyLen);
+
+						WepKey.keyinfo.KeyIndex = 0x80000000 + idx;
+						WepKey.keyinfo.KeyLength = len;
+						pAd->SharedKey[BSS0][idx].KeyLen =(UCHAR) (len <= 5 ? 5 : 13);
+
+						pAd->IndicateMediaState = NdisMediaStateConnected;
+						pAd->ExtraInfo = GENERAL_LINK_UP;
+						// need to enqueue cmd to thread
+						RTUSBEnqueueCmdFromNdis(pAd, OID_802_11_ADD_WEP, TRUE, &WepKey, sizeof(WepKey.keyinfo) + len - 1);
+#endif // RT2870 //
+						// For Preventing ShardKey Table is cleared by remove key procedure.
+    					pAd->SharedKey[BSS0][idx].CipherAlg = CipherAlg;
+						pAd->SharedKey[BSS0][idx].KeyLen = pAd->StaCfg.DesireSharedKey[idx].KeyLen;
+						NdisMoveMemory(pAd->SharedKey[BSS0][idx].Key,
+									   pAd->StaCfg.DesireSharedKey[idx].Key,
+									   pAd->StaCfg.DesireSharedKey[idx].KeyLen);
+    				}
+				}
+			}
+
+			Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
+			return;
+		}
+	}
+	else
+#endif // WPA_SUPPLICANT_SUPPORT //
+	{
+		// Special DATA frame that has to pass to MLME
+		//	 1. Cisco Aironet frames for CCX2. We need pass it to MLME for special process
+		//	 2. EAPOL handshaking frames when driver supplicant enabled, pass to MLME for special process
+		{
+			pTmpBuf = pRxBlk->pData - LENGTH_802_11;
+			NdisMoveMemory(pTmpBuf, pRxBlk->pHeader, LENGTH_802_11);
+			REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pTmpBuf, pRxBlk->DataSize + LENGTH_802_11, pRxWI->RSSI0, pRxWI->RSSI1, pRxWI->RSSI2, pRxD->PlcpSignal);
+			DBGPRINT_RAW(RT_DEBUG_TRACE, ("!!! report EAPOL/AIRONET DATA to MLME (len=%d) !!!\n", pRxBlk->DataSize));
+		}
+	}
+
+	RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+	return;
+
+}
+
+VOID STARxDataFrameAnnounce(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	MAC_TABLE_ENTRY	*pEntry,
+	IN	RX_BLK			*pRxBlk,
+	IN	UCHAR			FromWhichBSSID)
+{
+
+	// non-EAP frame
+	if (!RTMPCheckWPAframe(pAd, pEntry, pRxBlk->pData, pRxBlk->DataSize, FromWhichBSSID))
+	{
+
+		{
+			// drop all non-EAP DATA frame before
+			// this client's Port-Access-Control is secured
+			if (pRxBlk->pHeader->FC.Wep)
+			{
+				// unsupported cipher suite
+				if (pAd->StaCfg.WepStatus == Ndis802_11EncryptionDisabled)
+				{
+					// release packet
+					RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+					return;
+				}
+			}
+			else
+			{
+				// encryption in-use but receive a non-EAPOL clear text frame, drop it
+				if ((pAd->StaCfg.WepStatus != Ndis802_11EncryptionDisabled) &&
+					(pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
+				{
+					// release packet
+					RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+					return;
+				}
+			}
+		}
+		RX_BLK_CLEAR_FLAG(pRxBlk, fRX_EAP);
+		if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_ARALINK))
+		{
+			// Normal legacy, AMPDU or AMSDU
+			CmmRxnonRalinkFrameIndicate(pAd, pRxBlk, FromWhichBSSID);
+
+		}
+		else
+		{
+			// ARALINK
+			CmmRxRalinkFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
+		}
+#ifdef QOS_DLS_SUPPORT
+		RX_BLK_CLEAR_FLAG(pRxBlk, fRX_DLS);
+#endif // QOS_DLS_SUPPORT //
+	}
+	else
+	{
+		RX_BLK_SET_FLAG(pRxBlk, fRX_EAP);
+#ifdef DOT11_N_SUPPORT
+		if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0))
+		{
+			Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
+		}
+		else
+#endif // DOT11_N_SUPPORT //
+		{
+			// Determin the destination of the EAP frame
+			//  to WPA state machine or upper layer
+			STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
+		}
+	}
+}
+
+
+// For TKIP frame, calculate the MIC value
+BOOLEAN STACheckTkipMICValue(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	MAC_TABLE_ENTRY	*pEntry,
+	IN	RX_BLK			*pRxBlk)
+{
+	PHEADER_802_11	pHeader = pRxBlk->pHeader;
+	UCHAR			*pData = pRxBlk->pData;
+	USHORT			DataSize = pRxBlk->DataSize;
+	UCHAR			UserPriority = pRxBlk->UserPriority;
+	PCIPHER_KEY		pWpaKey;
+	UCHAR			*pDA, *pSA;
+
+	pWpaKey = &pAd->SharedKey[BSS0][pRxBlk->pRxWI->KeyIndex];
+
+	pDA = pHeader->Addr1;
+	if (RX_BLK_TEST_FLAG(pRxBlk, fRX_INFRA))
+	{
+		pSA = pHeader->Addr3;
+	}
+	else
+	{
+		pSA = pHeader->Addr2;
+	}
+
+	if (RTMPTkipCompareMICValue(pAd,
+								pData,
+								pDA,
+								pSA,
+								pWpaKey->RxMic,
+								UserPriority,
+								DataSize) == FALSE)
+	{
+		DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error 2\n"));
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+		if (pAd->StaCfg.WpaSupplicantUP)
+		{
+			WpaSendMicFailureToWpaSupplicant(pAd, (pWpaKey->Type == PAIRWISEKEY) ? TRUE : FALSE);
+		}
+		else
+#endif // WPA_SUPPLICANT_SUPPORT //
+		{
+			RTMPReportMicError(pAd, pWpaKey);
+		}
+
+		// release packet
+		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+
+//
+// All Rx routines use RX_BLK structure to hande rx events
+// It is very important to build pRxBlk attributes
+//  1. pHeader pointer to 802.11 Header
+//  2. pData pointer to payload including LLC (just skip Header)
+//  3. set payload size including LLC to DataSize
+//  4. set some flags with RX_BLK_SET_FLAG()
+//
+VOID STAHandleRxDataFrame(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	RX_BLK			*pRxBlk)
+{
+	PRT28XX_RXD_STRUC				pRxD = &(pRxBlk->RxD);
+	PRXWI_STRUC						pRxWI = pRxBlk->pRxWI;
+	PHEADER_802_11					pHeader = pRxBlk->pHeader;
+	PNDIS_PACKET					pRxPacket = pRxBlk->pRxPacket;
+	BOOLEAN 						bFragment = FALSE;
+	MAC_TABLE_ENTRY	    			*pEntry = NULL;
+	UCHAR							FromWhichBSSID = BSS0;
+	UCHAR                           UserPriority = 0;
+
+	{
+		// before LINK UP, all DATA frames are rejected
+		if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+		{
+			// release packet
+			RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+			return;
+		}
+
+#ifdef QOS_DLS_SUPPORT
+		//if ((pHeader->FC.FrDs == 0) && (pHeader->FC.ToDs == 0))
+		if (RTMPRcvFrameDLSCheck(pAd, pHeader, pRxWI->MPDUtotalByteCount, pRxD))
+		{
+			return;
+		}
+#endif // QOS_DLS_SUPPORT //
+
+		// Drop not my BSS frames
+		if (pRxD->MyBss == 0)
+		{
+			{
+				// release packet
+				RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+				return;
+			}
+		}
+
+		pAd->RalinkCounters.RxCountSinceLastNULL++;
+		if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable && (pHeader->FC.SubType & 0x08))
+		{
+			UCHAR *pData;
+			DBGPRINT(RT_DEBUG_TRACE,("bAPSDCapable\n"));
+
+			// Qos bit 4
+			pData = (PUCHAR)pHeader + LENGTH_802_11;
+			if ((*pData >> 4) & 0x01)
+			{
+				DBGPRINT(RT_DEBUG_TRACE,("RxDone- Rcv EOSP frame, driver may fall into sleep\n"));
+				pAd->CommonCfg.bInServicePeriod = FALSE;
+
+				// Force driver to fall into sleep mode when rcv EOSP frame
+				if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+				{
+					USHORT  TbttNumToNextWakeUp;
+					USHORT  NextDtim = pAd->StaCfg.DtimPeriod;
+					ULONG   Now;
+
+					NdisGetSystemUpTime(&Now);
+					NextDtim -= (USHORT)(Now - pAd->StaCfg.LastBeaconRxTime)/pAd->CommonCfg.BeaconPeriod;
+
+					TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount;
+					if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))
+						TbttNumToNextWakeUp = NextDtim;
+
+					MlmeSetPsmBit(pAd, PWR_SAVE);
+					// if WMM-APSD is failed, try to disable following line
+					AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
+				}
+			}
+
+			if ((pHeader->FC.MoreData) && (pAd->CommonCfg.bInServicePeriod))
+			{
+				DBGPRINT(RT_DEBUG_TRACE,("Sending another trigger frame when More Data bit is set to 1\n"));
+			}
+		}
+
+		// Drop NULL, CF-ACK(no data), CF-POLL(no data), and CF-ACK+CF-POLL(no data) data frame
+		if ((pHeader->FC.SubType & 0x04)) // bit 2 : no DATA
+		{
+			// release packet
+			RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+			return;
+		}
+
+	    // Drop not my BSS frame (we can not only check the MyBss bit in RxD)
+#ifdef QOS_DLS_SUPPORT
+	    if (!pAd->CommonCfg.bDLSCapable)
+	    {
+#endif // QOS_DLS_SUPPORT //
+		if (INFRA_ON(pAd))
+		{
+			// Infrastructure mode, check address 2 for BSSID
+			if (!RTMPEqualMemory(&pHeader->Addr2, &pAd->CommonCfg.Bssid, 6))
+			{
+				// Receive frame not my BSSID
+	            // release packet
+	            RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+				return;
+			}
+		}
+		else	// Ad-Hoc mode or Not associated
+		{
+			// Ad-Hoc mode, check address 3 for BSSID
+			if (!RTMPEqualMemory(&pHeader->Addr3, &pAd->CommonCfg.Bssid, 6))
+			{
+				// Receive frame not my BSSID
+	            // release packet
+	            RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+				return;
+			}
+		}
+#ifdef QOS_DLS_SUPPORT
+	    }
+#endif // QOS_DLS_SUPPORT //
+
+		//
+		// find pEntry
+		//
+		if (pRxWI->WirelessCliID < MAX_LEN_OF_MAC_TABLE)
+		{
+			pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];
+		}
+		else
+		{
+			// 1. release packet if infra mode
+			// 2. new a pEntry if ad-hoc mode
+			RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+			return;
+		}
+
+		// infra or ad-hoc
+		if (INFRA_ON(pAd))
+		{
+			RX_BLK_SET_FLAG(pRxBlk, fRX_INFRA);
+#ifdef QOS_DLS_SUPPORT
+			if ((pHeader->FC.FrDs == 0) && (pHeader->FC.ToDs == 0))
+				RX_BLK_SET_FLAG(pRxBlk, fRX_DLS);
+			else
+#endif // QOS_DLS_SUPPORT //
+			ASSERT(pRxWI->WirelessCliID == BSSID_WCID);
+		}
+
+		// check Atheros Client
+		if ((pEntry->bIAmBadAtheros == FALSE) &&  (pRxD->AMPDU == 1) && (pHeader->FC.Retry ))
+		{
+			pEntry->bIAmBadAtheros = TRUE;
+			pAd->CommonCfg.IOTestParm.bCurrentAtheros = TRUE;
+			pAd->CommonCfg.IOTestParm.bLastAtheros = TRUE;
+			if (!STA_AES_ON(pAd))
+			{
+				AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, TRUE, FALSE);
+			}
+		}
+	}
+
+	pRxBlk->pData = (UCHAR *)pHeader;
+
+	//
+	// update RxBlk->pData, DataSize
+	// 802.11 Header, QOS, HTC, Hw Padding
+	//
+
+	// 1. skip 802.11 HEADER
+	{
+		pRxBlk->pData += LENGTH_802_11;
+		pRxBlk->DataSize -= LENGTH_802_11;
+	}
+
+	// 2. QOS
+	if (pHeader->FC.SubType & 0x08)
+	{
+		RX_BLK_SET_FLAG(pRxBlk, fRX_QOS);
+		UserPriority = *(pRxBlk->pData) & 0x0f;
+		// bit 7 in QoS Control field signals the HT A-MSDU format
+		if ((*pRxBlk->pData) & 0x80)
+		{
+			RX_BLK_SET_FLAG(pRxBlk, fRX_AMSDU);
+		}
+
+		// skip QOS contorl field
+		pRxBlk->pData += 2;
+		pRxBlk->DataSize -=2;
+	}
+	pRxBlk->UserPriority = UserPriority;
+
+	// 3. Order bit: A-Ralink or HTC+
+	if (pHeader->FC.Order)
+	{
+#ifdef AGGREGATION_SUPPORT
+		if ((pRxWI->PHYMODE <= MODE_OFDM) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)))
+		{
+			RX_BLK_SET_FLAG(pRxBlk, fRX_ARALINK);
+		}
+		else
+#endif
+		{
+#ifdef DOT11_N_SUPPORT
+			RX_BLK_SET_FLAG(pRxBlk, fRX_HTC);
+			// skip HTC contorl field
+			pRxBlk->pData += 4;
+			pRxBlk->DataSize -= 4;
+#endif // DOT11_N_SUPPORT //
+		}
+	}
+
+	// 4. skip HW padding
+	if (pRxD->L2PAD)
+	{
+		// just move pData pointer
+		// because DataSize excluding HW padding
+		RX_BLK_SET_FLAG(pRxBlk, fRX_PAD);
+		pRxBlk->pData += 2;
+	}
+
+#ifdef DOT11_N_SUPPORT
+	if (pRxD->BA)
+	{
+		RX_BLK_SET_FLAG(pRxBlk, fRX_AMPDU);
+	}
+#endif // DOT11_N_SUPPORT //
+
+
+	//
+	// Case I  Process Broadcast & Multicast data frame
+	//
+	if (pRxD->Bcast || pRxD->Mcast)
+	{
+		INC_COUNTER64(pAd->WlanCounters.MulticastReceivedFrameCount);
+
+		// Drop Mcast/Bcast frame with fragment bit on
+		if (pHeader->FC.MoreFrag)
+		{
+			// release packet
+			RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+			return;
+		}
+
+		// Filter out Bcast frame which AP relayed for us
+		if (pHeader->FC.FrDs && MAC_ADDR_EQUAL(pHeader->Addr3, pAd->CurrentAddress))
+		{
+			// release packet
+			RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+			return;
+		}
+
+		Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
+		return;
+	}
+	else if (pRxD->U2M)
+	{
+		pAd->LastRxRate = (USHORT)((pRxWI->MCS) + (pRxWI->BW <<7) + (pRxWI->ShortGI <<8)+ (pRxWI->PHYMODE <<14)) ;
+
+
+#ifdef QOS_DLS_SUPPORT
+        if (RX_BLK_TEST_FLAG(pRxBlk, fRX_DLS))
+		{
+			MAC_TABLE_ENTRY *pDlsEntry = NULL;
+
+			pDlsEntry = DlsEntryTableLookupByWcid(pAd, pRxWI->WirelessCliID, pHeader->Addr2, TRUE);
+										                        if(pDlsEntry)
+			Update_Rssi_Sample(pAd, &pDlsEntry->RssiSample, pRxWI);
+		}
+		else
+#endif // QOS_DLS_SUPPORT //
+		if (ADHOC_ON(pAd))
+		{
+			pEntry = MacTableLookup(pAd, pHeader->Addr2);
+			if (pEntry)
+				Update_Rssi_Sample(pAd, &pEntry->RssiSample, pRxWI);
+		}
+
+
+		Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
+
+		pAd->StaCfg.LastSNR0 = (UCHAR)(pRxWI->SNR0);
+		pAd->StaCfg.LastSNR1 = (UCHAR)(pRxWI->SNR1);
+
+		pAd->RalinkCounters.OneSecRxOkDataCnt++;
+
+
+    	if (!((pHeader->Frag == 0) && (pHeader->FC.MoreFrag == 0)))
+    	{
+    		// re-assemble the fragmented packets
+    		// return complete frame (pRxPacket) or NULL
+    		bFragment = TRUE;
+    		pRxPacket = RTMPDeFragmentDataFrame(pAd, pRxBlk);
+    	}
+
+    	if (pRxPacket)
+    	{
+			pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];
+
+    		// process complete frame
+    		if (bFragment && (pRxD->Decrypted) && (pEntry->WepStatus == Ndis802_11Encryption2Enabled))
+    		{
+				// Minus MIC length
+				pRxBlk->DataSize -= 8;
+
+    			// For TKIP frame, calculate the MIC value
+    			if (STACheckTkipMICValue(pAd, pEntry, pRxBlk) == FALSE)
+    			{
+    				return;
+    			}
+    		}
+
+    		STARxDataFrameAnnounce(pAd, pEntry, pRxBlk, FromWhichBSSID);
+			return;
+    	}
+    	else
+    	{
+    		// just return
+    		// because RTMPDeFragmentDataFrame() will release rx packet,
+    		// if packet is fragmented
+    		return;
+    	}
+	}
+
+	ASSERT(0);
+	// release packet
+	RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+}
+
+VOID STAHandleRxMgmtFrame(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	RX_BLK			*pRxBlk)
+{
+	PRT28XX_RXD_STRUC	pRxD = &(pRxBlk->RxD);
+	PRXWI_STRUC		pRxWI = pRxBlk->pRxWI;
+	PHEADER_802_11	pHeader = pRxBlk->pHeader;
+	PNDIS_PACKET	pRxPacket = pRxBlk->pRxPacket;
+
+	do
+	{
+
+		// We should collect RSSI not only U2M data but also my beacon
+		if ((pHeader->FC.SubType == SUBTYPE_BEACON) && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2))
+			&& (pAd->RxAnt.EvaluatePeriod == 0))
+		{
+			Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
+
+			pAd->StaCfg.LastSNR0 = (UCHAR)(pRxWI->SNR0);
+			pAd->StaCfg.LastSNR1 = (UCHAR)(pRxWI->SNR1);
+		}
+
+#ifdef RT30xx
+		// collect rssi information for antenna diversity
+		if (pAd->NicConfig2.field.AntDiversity)
+		{
+			if ((pRxD->U2M) || ((pHeader->FC.SubType == SUBTYPE_BEACON) && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2))))
+			{
+					COLLECT_RX_ANTENNA_AVERAGE_RSSI(pAd, ConvertToRssi(pAd, (UCHAR)pRxWI->RSSI0, RSSI_0), 0); //Note: RSSI2 not used on RT73
+					pAd->StaCfg.NumOfAvgRssiSample ++;
+			}
+		}
+#endif // RT30xx //
+
+		// First check the size, it MUST not exceed the mlme queue size
+		if (pRxWI->MPDUtotalByteCount > MGMT_DMA_BUFFER_SIZE)
+		{
+			DBGPRINT_ERR(("STAHandleRxMgmtFrame: frame too large, size = %d \n", pRxWI->MPDUtotalByteCount));
+			break;
+		}
+
+		REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pHeader, pRxWI->MPDUtotalByteCount,
+									pRxWI->RSSI0, pRxWI->RSSI1, pRxWI->RSSI2, pRxD->PlcpSignal);
+	} while (FALSE);
+
+	RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
+}
+
+VOID STAHandleRxControlFrame(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	RX_BLK			*pRxBlk)
+{
+#ifdef DOT11_N_SUPPORT
+	PRXWI_STRUC		pRxWI = pRxBlk->pRxWI;
+#endif // DOT11_N_SUPPORT //
+	PHEADER_802_11	pHeader = pRxBlk->pHeader;
+	PNDIS_PACKET	pRxPacket = pRxBlk->pRxPacket;
+
+	switch (pHeader->FC.SubType)
+	{
+		case SUBTYPE_BLOCK_ACK_REQ:
+#ifdef DOT11_N_SUPPORT
+			{
+				CntlEnqueueForRecv(pAd, pRxWI->WirelessCliID, (pRxWI->MPDUtotalByteCount), (PFRAME_BA_REQ)pHeader);
+			}
+			break;
+#endif // DOT11_N_SUPPORT //
+		case SUBTYPE_BLOCK_ACK:
+		case SUBTYPE_ACK:
+		default:
+			break;
+	}
+
+	RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Process RxDone interrupt, running in DPC level
+
+	Arguments:
+		pAd Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+		This routine has to maintain Rx ring read pointer.
+		Need to consider QOS DATA format when converting to 802.3
+	========================================================================
+*/
+BOOLEAN STARxDoneInterruptHandle(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	BOOLEAN			argc)
+{
+	NDIS_STATUS			Status;
+	UINT32			RxProcessed, RxPending;
+	BOOLEAN			bReschedule = FALSE;
+	RT28XX_RXD_STRUC	*pRxD;
+	UCHAR			*pData;
+	PRXWI_STRUC		pRxWI;
+	PNDIS_PACKET	pRxPacket;
+	PHEADER_802_11	pHeader;
+	RX_BLK			RxCell;
+
+	RxProcessed = RxPending = 0;
+
+	// process whole rx ring
+	while (1)
+	{
+
+		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF |
+								fRTMP_ADAPTER_RESET_IN_PROGRESS |
+								fRTMP_ADAPTER_HALT_IN_PROGRESS |
+								fRTMP_ADAPTER_NIC_NOT_EXIST) ||
+			!RTMP_TEST_FLAG(pAd,fRTMP_ADAPTER_START_UP))
+		{
+			break;
+		}
+
+
+		RxProcessed ++; // test
+
+		// 1. allocate a new data packet into rx ring to replace received packet
+		//    then processing the received packet
+		// 2. the callee must take charge of release of packet
+		// 3. As far as driver is concerned ,
+		//    the rx packet must
+		//      a. be indicated to upper layer or
+		//      b. be released if it is discarded
+		pRxPacket = GetPacketFromRxRing(pAd, &(RxCell.RxD), &bReschedule, &RxPending);
+		if (pRxPacket == NULL)
+		{
+			// no more packet to process
+			break;
+		}
+
+		// get rx ring descriptor
+		pRxD = &(RxCell.RxD);
+		// get rx data buffer
+		pData	= GET_OS_PKT_DATAPTR(pRxPacket);
+		pRxWI	= (PRXWI_STRUC) pData;
+		pHeader = (PHEADER_802_11) (pData+RXWI_SIZE) ;
+
+#ifdef RT_BIG_ENDIAN
+	    RTMPFrameEndianChange(pAd, (PUCHAR)pHeader, DIR_READ, TRUE);
+		RTMPWIEndianChange((PUCHAR)pRxWI, TYPE_RXWI);
+#endif
+
+		// build RxCell
+		RxCell.pRxWI = pRxWI;
+		RxCell.pHeader = pHeader;
+		RxCell.pRxPacket = pRxPacket;
+		RxCell.pData = (UCHAR *) pHeader;
+		RxCell.DataSize = pRxWI->MPDUtotalByteCount;
+		RxCell.Flags = 0;
+
+		// Increase Total receive byte counter after real data received no mater any error or not
+		pAd->RalinkCounters.ReceivedByteCount +=  pRxWI->MPDUtotalByteCount;
+		pAd->RalinkCounters.RxCount ++;
+
+		INC_COUNTER64(pAd->WlanCounters.ReceivedFragmentCount);
+
+		if (pRxWI->MPDUtotalByteCount < 14)
+			Status = NDIS_STATUS_FAILURE;
+
+        if (MONITOR_ON(pAd))
+		{
+            send_monitor_packets(pAd, &RxCell);
+			break;
+		}
+		/* RT2870 invokes STARxDoneInterruptHandle() in rtusb_bulk.c */
+#ifdef RALINK_ATE
+		if (ATE_ON(pAd))
+		{
+			pAd->ate.RxCntPerSec++;
+			ATESampleRssi(pAd, pRxWI);
+#ifdef RALINK_28xx_QA
+			if (pAd->ate.bQARxStart == TRUE)
+			{
+				/* (*pRxD) has been swapped in GetPacketFromRxRing() */
+				ATE_QA_Statistics(pAd, pRxWI, pRxD,	pHeader);
+			}
+#endif // RALINK_28xx_QA //
+			RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
+			continue;
+		}
+#endif // RALINK_ATE //
+
+		// Check for all RxD errors
+		Status = RTMPCheckRxError(pAd, pHeader, pRxWI, pRxD);
+
+		// Handle the received frame
+		if (Status == NDIS_STATUS_SUCCESS)
+		{
+			switch (pHeader->FC.Type)
+			{
+				// CASE I, receive a DATA frame
+				case BTYPE_DATA:
+				{
+					// process DATA frame
+					STAHandleRxDataFrame(pAd, &RxCell);
+				}
+				break;
+				// CASE II, receive a MGMT frame
+				case BTYPE_MGMT:
+				{
+					STAHandleRxMgmtFrame(pAd, &RxCell);
+				}
+				break;
+				// CASE III. receive a CNTL frame
+				case BTYPE_CNTL:
+				{
+					STAHandleRxControlFrame(pAd, &RxCell);
+				}
+				break;
+				// discard other type
+				default:
+					RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+					break;
+			}
+		}
+		else
+		{
+			pAd->Counters8023.RxErrors++;
+			// discard this frame
+			RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+		}
+	}
+
+	return bReschedule;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+	Arguments:
+		pAd 	Pointer to our adapter
+
+	IRQL = DISPATCH_LEVEL
+
+	========================================================================
+*/
+VOID	RTMPHandleTwakeupInterrupt(
+	IN PRTMP_ADAPTER pAd)
+{
+	AsicForceWakeup(pAd, FALSE);
+}
+
+/*
+========================================================================
+Routine Description:
+    Early checking and OS-depened parsing for Tx packet send to our STA driver.
+
+Arguments:
+    NDIS_HANDLE 	MiniportAdapterContext	Pointer refer to the device handle, i.e., the pAd.
+	PPNDIS_PACKET	ppPacketArray			The packet array need to do transmission.
+	UINT			NumberOfPackets			Number of packet in packet array.
+
+Return Value:
+	NONE
+
+Note:
+	This function do early checking and classification for send-out packet.
+	You only can put OS-depened & STA related code in here.
+========================================================================
+*/
+VOID STASendPackets(
+	IN	NDIS_HANDLE		MiniportAdapterContext,
+	IN	PPNDIS_PACKET	ppPacketArray,
+	IN	UINT			NumberOfPackets)
+{
+	UINT			Index;
+	PRTMP_ADAPTER	pAd = (PRTMP_ADAPTER) MiniportAdapterContext;
+	PNDIS_PACKET	pPacket;
+	BOOLEAN			allowToSend = FALSE;
+
+
+	for (Index = 0; Index < NumberOfPackets; Index++)
+	{
+		pPacket = ppPacketArray[Index];
+
+		do
+		{
+
+			if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
+				RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
+				RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
+			{
+				// Drop send request since hardware is in reset state
+					break;
+			}
+			else if (!INFRA_ON(pAd) && !ADHOC_ON(pAd))
+			{
+				// Drop send request since there are no physical connection yet
+					break;
+			}
+			else
+			{
+				// Record that orignal packet source is from NDIS layer,so that
+				// later on driver knows how to release this NDIS PACKET
+#ifdef QOS_DLS_SUPPORT
+				MAC_TABLE_ENTRY *pEntry;
+				PUCHAR pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
+
+				pEntry = MacTableLookup(pAd, pSrcBufVA);
+				if (pEntry && (pEntry->ValidAsDls == TRUE))
+				{
+					RTMP_SET_PACKET_WCID(pPacket, pEntry->Aid);
+				}
+				else
+#endif // QOS_DLS_SUPPORT //
+				RTMP_SET_PACKET_WCID(pPacket, 0); // this field is useless when in STA mode
+				RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
+				NDIS_SET_PACKET_STATUS(pPacket, NDIS_STATUS_PENDING);
+				pAd->RalinkCounters.PendingNdisPacketCount++;
+
+				allowToSend = TRUE;
+			}
+		} while(FALSE);
+
+		if (allowToSend == TRUE)
+			STASendPacket(pAd, pPacket);
+		else
+			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+	}
+
+	// Dequeue outgoing frames from TxSwQueue[] and process it
+	RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+
+}
+
+
+/*
+========================================================================
+Routine Description:
+	This routine is used to do packet parsing and classification for Tx packet
+	to STA device, and it will en-queue packets to our TxSwQueue depends on AC
+	class.
+
+Arguments:
+	pAd    		Pointer to our adapter
+	pPacket 	Pointer to send packet
+
+Return Value:
+	NDIS_STATUS_SUCCESS			If succes to queue the packet into TxSwQueue.
+	NDIS_STATUS_FAILURE			If failed to do en-queue.
+
+Note:
+	You only can put OS-indepened & STA related code in here.
+========================================================================
+*/
+NDIS_STATUS STASendPacket(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PNDIS_PACKET	pPacket)
+{
+	PACKET_INFO 	PacketInfo;
+	PUCHAR			pSrcBufVA;
+	UINT			SrcBufLen;
+	UINT			AllowFragSize;
+	UCHAR			NumberOfFrag;
+//	UCHAR			RTSRequired;
+	UCHAR			QueIdx, UserPriority;
+	MAC_TABLE_ENTRY *pEntry = NULL;
+	unsigned int 	IrqFlags;
+	UCHAR			FlgIsIP = 0;
+	UCHAR			Rate;
+
+	// Prepare packet information structure for buffer descriptor
+	// chained within a single NDIS packet.
+	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
+
+	if (pSrcBufVA == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("STASendPacket --> pSrcBufVA == NULL !!!SrcBufLen=%x\n",SrcBufLen));
+		// Resourece is low, system did not allocate virtual address
+		// return NDIS_STATUS_FAILURE directly to upper layer
+		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+		return NDIS_STATUS_FAILURE;
+	}
+
+
+	if (SrcBufLen < 14)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("STASendPacket --> Ndis Packet buffer error !!!\n"));
+		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+		return (NDIS_STATUS_FAILURE);
+	}
+
+	// In HT rate adhoc mode, A-MPDU is often used. So need to lookup BA Table and MAC Entry.
+	// Note multicast packets in adhoc also use BSSID_WCID index.
+	{
+		if(INFRA_ON(pAd))
+		{
+#ifdef QOS_DLS_SUPPORT
+			USHORT	tmpWcid;
+
+			tmpWcid = RTMP_GET_PACKET_WCID(pPacket);
+			if (VALID_WCID(tmpWcid) &&
+				(pAd->MacTab.Content[tmpWcid].ValidAsDls== TRUE))
+			{
+				pEntry = &pAd->MacTab.Content[tmpWcid];
+				Rate = pAd->MacTab.Content[tmpWcid].CurrTxRate;
+			}
+			else
+#endif // QOS_DLS_SUPPORT //
+			{
+			pEntry = &pAd->MacTab.Content[BSSID_WCID];
+			RTMP_SET_PACKET_WCID(pPacket, BSSID_WCID);
+			Rate = pAd->CommonCfg.TxRate;
+		}
+		}
+		else if (ADHOC_ON(pAd))
+		{
+			if (*pSrcBufVA & 0x01)
+			{
+				RTMP_SET_PACKET_WCID(pPacket, MCAST_WCID);
+				pEntry = &pAd->MacTab.Content[MCAST_WCID];
+			}
+			else
+			{
+				pEntry = MacTableLookup(pAd, pSrcBufVA);
+			}
+			Rate = pAd->CommonCfg.TxRate;
+		}
+	}
+
+	if (!pEntry)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("STASendPacket->Cannot find pEntry(%2x:%2x:%2x:%2x:%2x:%2x) in MacTab!\n", PRINT_MAC(pSrcBufVA)));
+		// Resourece is low, system did not allocate virtual address
+		// return NDIS_STATUS_FAILURE directly to upper layer
+		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+		return NDIS_STATUS_FAILURE;
+	}
+
+	if (ADHOC_ON(pAd)
+		)
+	{
+		RTMP_SET_PACKET_WCID(pPacket, (UCHAR)pEntry->Aid);
+	}
+
+	//
+	// Check the Ethernet Frame type of this packet, and set the RTMP_SET_PACKET_SPECIFIC flags.
+	//		Here we set the PACKET_SPECIFIC flags(LLC, VLAN, DHCP/ARP, EAPOL).
+	RTMPCheckEtherType(pAd, pPacket);
+
+
+
+	//
+	// WPA 802.1x secured port control - drop all non-802.1x frame before port secured
+	//
+	if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
+		 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+		 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
+		 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
+#ifdef WPA_SUPPLICANT_SUPPORT
+		  || (pAd->StaCfg.IEEE8021X == TRUE)
+#endif // WPA_SUPPLICANT_SUPPORT //
+#ifdef LEAP_SUPPORT
+		  || (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+#endif // LEAP_SUPPORT //
+		  )
+		  && ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) || (pAd->StaCfg.MicErrCnt >= 2))
+		  && (RTMP_GET_PACKET_EAPOL(pPacket)== FALSE)
+		  )
+	{
+		DBGPRINT(RT_DEBUG_TRACE,("STASendPacket --> Drop packet before port secured !!!\n"));
+		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+
+		return (NDIS_STATUS_FAILURE);
+	}
+
+
+	// STEP 1. Decide number of fragments required to deliver this MSDU.
+	//	   The estimation here is not very accurate because difficult to
+	//	   take encryption overhead into consideration here. The result
+	//	   "NumberOfFrag" is then just used to pre-check if enough free
+	//	   TXD are available to hold this MSDU.
+
+
+	if (*pSrcBufVA & 0x01)	// fragmentation not allowed on multicast & broadcast
+		NumberOfFrag = 1;
+	else if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED))
+		NumberOfFrag = 1;	// Aggregation overwhelms fragmentation
+	else if (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED))
+		NumberOfFrag = 1;	// Aggregation overwhelms fragmentation
+#ifdef DOT11_N_SUPPORT
+	else if ((pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTMIX) || (pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTGREENFIELD))
+		NumberOfFrag = 1;	// MIMO RATE overwhelms fragmentation
+#endif // DOT11_N_SUPPORT //
+	else
+	{
+		// The calculated "NumberOfFrag" is a rough estimation because of various
+		// encryption/encapsulation overhead not taken into consideration. This number is just
+		// used to make sure enough free TXD are available before fragmentation takes place.
+		// In case the actual required number of fragments of an NDIS packet
+		// excceeds "NumberOfFrag"caculated here and not enough free TXD available, the
+		// last fragment (i.e. last MPDU) will be dropped in RTMPHardTransmit() due to out of
+		// resource, and the NDIS packet will be indicated NDIS_STATUS_FAILURE. This should
+		// rarely happen and the penalty is just like a TX RETRY fail. Affordable.
+
+		AllowFragSize = (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;
+		NumberOfFrag = ((PacketInfo.TotalPacketLength - LENGTH_802_3 + LENGTH_802_1_H) / AllowFragSize) + 1;
+		// To get accurate number of fragmentation, Minus 1 if the size just match to allowable fragment size
+		if (((PacketInfo.TotalPacketLength - LENGTH_802_3 + LENGTH_802_1_H) % AllowFragSize) == 0)
+		{
+			NumberOfFrag--;
+		}
+	}
+
+	// Save fragment number to Ndis packet reserved field
+	RTMP_SET_PACKET_FRAGMENTS(pPacket, NumberOfFrag);
+
+
+	// STEP 2. Check the requirement of RTS:
+	//	   If multiple fragment required, RTS is required only for the first fragment
+	//	   if the fragment size large than RTS threshold
+	//     For RT28xx, Let ASIC send RTS/CTS
+	RTMP_SET_PACKET_RTS(pPacket, 0);
+	RTMP_SET_PACKET_TXRATE(pPacket, pAd->CommonCfg.TxRate);
+
+	//
+	// STEP 3. Traffic classification. outcome = <UserPriority, QueIdx>
+	//
+	UserPriority = 0;
+	QueIdx		 = QID_AC_BE;
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
+		CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE))
+	{
+		USHORT Protocol;
+		UCHAR  LlcSnapLen = 0, Byte0, Byte1;
+		do
+		{
+			// get Ethernet protocol field
+			Protocol = (USHORT)((pSrcBufVA[12] << 8) + pSrcBufVA[13]);
+			if (Protocol <= 1500)
+			{
+				// get Ethernet protocol field from LLC/SNAP
+				if (Sniff2BytesFromNdisBuffer(PacketInfo.pFirstBuffer, LENGTH_802_3 + 6, &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
+					break;
+
+				Protocol = (USHORT)((Byte0 << 8) + Byte1);
+				LlcSnapLen = 8;
+			}
+
+			// always AC_BE for non-IP packet
+			if (Protocol != 0x0800)
+				break;
+
+			// get IP header
+			if (Sniff2BytesFromNdisBuffer(PacketInfo.pFirstBuffer, LENGTH_802_3 + LlcSnapLen, &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
+				break;
+
+			// return AC_BE if packet is not IPv4
+			if ((Byte0 & 0xf0) != 0x40)
+				break;
+
+			FlgIsIP = 1;
+			UserPriority = (Byte1 & 0xe0) >> 5;
+			QueIdx = MapUserPriorityToAccessCategory[UserPriority];
+
+			// TODO: have to check ACM bit. apply TSPEC if ACM is ON
+			// TODO: downgrade UP & QueIdx before passing ACM
+			if (pAd->CommonCfg.APEdcaParm.bACM[QueIdx])
+			{
+				UserPriority = 0;
+				QueIdx		 = QID_AC_BE;
+			}
+		} while (FALSE);
+	}
+
+	RTMP_SET_PACKET_UP(pPacket, UserPriority);
+
+
+
+	// Make sure SendTxWait queue resource won't be used by other threads
+	RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+	if (pAd->TxSwQueue[QueIdx].Number >= MAX_PACKETS_IN_QUEUE)
+	{
+		RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+#ifdef BLOCK_NET_IF
+		StopNetIfQueue(pAd, QueIdx, pPacket);
+#endif // BLOCK_NET_IF //
+		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+
+		return NDIS_STATUS_FAILURE;
+	}
+	else
+	{
+		InsertTailQueue(&pAd->TxSwQueue[QueIdx], PACKET_TO_QUEUE_ENTRY(pPacket));
+	}
+	RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+
+#ifdef DOT11_N_SUPPORT
+    if ((pAd->CommonCfg.BACapability.field.AutoBA == TRUE)&&
+        IS_HT_STA(pEntry))
+	{
+	    //PMAC_TABLE_ENTRY pMacEntry = &pAd->MacTab.Content[BSSID_WCID];
+		if (((pEntry->TXBAbitmap & (1<<UserPriority)) == 0) &&
+            ((pEntry->BADeclineBitmap & (1<<UserPriority)) == 0) &&
+            (pEntry->PortSecured == WPA_802_1X_PORT_SECURED)
+			 // For IOT compatibility, if
+			 // 1. It is Ralink chip or
+			 // 2. It is OPEN or AES mode,
+			 // then BA session can be bulit.
+			 && ((pEntry->ValidAsCLI && pAd->MlmeAux.APRalinkIe != 0x0) ||
+			 	 (pEntry->WepStatus == Ndis802_11WEPDisabled || pEntry->WepStatus == Ndis802_11Encryption3Enabled))
+			)
+		{
+			BAOriSessionSetUp(pAd, pEntry, 0, 0, 10, FALSE);
+		}
+	}
+#endif // DOT11_N_SUPPORT //
+
+	pAd->RalinkCounters.OneSecOsTxCount[QueIdx]++; // TODO: for debug only. to be removed
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		This subroutine will scan through releative ring descriptor to find
+		out avaliable free ring descriptor and compare with request size.
+
+	Arguments:
+		pAd Pointer to our adapter
+		QueIdx		Selected TX Ring
+
+	Return Value:
+		NDIS_STATUS_FAILURE 	Not enough free descriptor
+		NDIS_STATUS_SUCCESS 	Enough free descriptor
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+
+#ifdef RT2870
+/*
+	Actually, this function used to check if the TxHardware Queue still has frame need to send.
+	If no frame need to send, go to sleep, else, still wake up.
+*/
+NDIS_STATUS RTMPFreeTXDRequest(
+	IN		PRTMP_ADAPTER	pAd,
+	IN		UCHAR			QueIdx,
+	IN		UCHAR			NumberRequired,
+	IN		PUCHAR			FreeNumberIs)
+{
+	//ULONG		FreeNumber = 0;
+	NDIS_STATUS 	Status = NDIS_STATUS_FAILURE;
+	unsigned long   IrqFlags;
+	HT_TX_CONTEXT	*pHTTXContext;
+
+	switch (QueIdx)
+	{
+		case QID_AC_BK:
+		case QID_AC_BE:
+		case QID_AC_VI:
+		case QID_AC_VO:
+		case QID_HCCA:
+			{
+				pHTTXContext = &pAd->TxContext[QueIdx];
+				RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+				if ((pHTTXContext->CurWritePosition != pHTTXContext->ENextBulkOutPosition) ||
+					(pHTTXContext->IRPPending == TRUE))
+				{
+					Status = NDIS_STATUS_FAILURE;
+				}
+				else
+				{
+					Status = NDIS_STATUS_SUCCESS;
+				}
+				RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+			}
+			break;
+
+		case QID_MGMT:
+			if (pAd->MgmtRing.TxSwFreeIdx != MGMT_RING_SIZE)
+				Status = NDIS_STATUS_FAILURE;
+			else
+				Status = NDIS_STATUS_SUCCESS;
+			break;
+
+		default:
+			DBGPRINT(RT_DEBUG_ERROR,("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx));
+			break;
+	}
+
+	return (Status);
+
+}
+#endif // RT2870 //
+
+
+VOID RTMPSendDisassociationFrame(
+	IN	PRTMP_ADAPTER	pAd)
+{
+}
+
+VOID	RTMPSendNullFrame(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			TxRate,
+	IN	BOOLEAN 		bQosNull)
+{
+	UCHAR	NullFrame[48];
+	ULONG	Length;
+	PHEADER_802_11	pHeader_802_11;
+
+
+#ifdef RALINK_ATE
+	if(ATE_ON(pAd))
+	{
+		return;
+	}
+#endif // RALINK_ATE //
+
+    // WPA 802.1x secured port control
+    if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
+         (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+         (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
+         (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
+#ifdef WPA_SUPPLICANT_SUPPORT
+			  || (pAd->StaCfg.IEEE8021X == TRUE)
+#endif
+        ) &&
+       (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
+	{
+		return;
+	}
+
+	NdisZeroMemory(NullFrame, 48);
+	Length = sizeof(HEADER_802_11);
+
+	pHeader_802_11 = (PHEADER_802_11) NullFrame;
+
+	pHeader_802_11->FC.Type = BTYPE_DATA;
+	pHeader_802_11->FC.SubType = SUBTYPE_NULL_FUNC;
+	pHeader_802_11->FC.ToDs = 1;
+	COPY_MAC_ADDR(pHeader_802_11->Addr1, pAd->CommonCfg.Bssid);
+	COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
+	COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
+
+	if (pAd->CommonCfg.bAPSDForcePowerSave)
+	{
+		pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
+	}
+	else
+	{
+		pHeader_802_11->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE) ? 1: 0;
+	}
+	pHeader_802_11->Duration = pAd->CommonCfg.Dsifs + RTMPCalcDuration(pAd, TxRate, 14);
+
+	pAd->Sequence++;
+	pHeader_802_11->Sequence = pAd->Sequence;
+
+	// Prepare QosNull function frame
+	if (bQosNull)
+	{
+		pHeader_802_11->FC.SubType = SUBTYPE_QOS_NULL;
+
+		// copy QOS control bytes
+		NullFrame[Length]	=  0;
+		NullFrame[Length+1] =  0;
+		Length += 2;// if pad with 2 bytes for alignment, APSD will fail
+	}
+
+	HAL_KickOutNullFrameTx(pAd, 0, NullFrame, Length);
+
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID	RTMPSendRTSFrame(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pDA,
+	IN	unsigned int	NextMpduSize,
+	IN	UCHAR			TxRate,
+	IN	UCHAR			RTSRate,
+	IN	USHORT			AckDuration,
+	IN	UCHAR			QueIdx,
+	IN	UCHAR			FrameGap)
+{
+}
+
+
+
+// --------------------------------------------------------
+//  FIND ENCRYPT KEY AND DECIDE CIPHER ALGORITHM
+//		Find the WPA key, either Group or Pairwise Key
+//		LEAP + TKIP also use WPA key.
+// --------------------------------------------------------
+// Decide WEP bit and cipher suite to be used. Same cipher suite should be used for whole fragment burst
+// In Cisco CCX 2.0 Leap Authentication
+//		   WepStatus is Ndis802_11Encryption1Enabled but the key will use PairwiseKey
+//		   Instead of the SharedKey, SharedKey Length may be Zero.
+VOID STAFindCipherAlgorithm(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk)
+{
+	NDIS_802_11_ENCRYPTION_STATUS	Cipher;				// To indicate cipher used for this packet
+	UCHAR							CipherAlg = CIPHER_NONE;		// cipher alogrithm
+	UCHAR							KeyIdx = 0xff;
+	PUCHAR							pSrcBufVA;
+	PCIPHER_KEY						pKey = NULL;
+
+	pSrcBufVA = GET_OS_PKT_DATAPTR(pTxBlk->pPacket);
+
+	{
+	    // Select Cipher
+	    if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd)))
+	        Cipher = pAd->StaCfg.GroupCipher; // Cipher for Multicast or Broadcast
+	    else
+	        Cipher = pAd->StaCfg.PairCipher; // Cipher for Unicast
+
+		if (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket))
+		{
+			ASSERT(pAd->SharedKey[BSS0][0].CipherAlg <= CIPHER_CKIP128);
+
+			// 4-way handshaking frame must be clear
+			if (!(TX_BLK_TEST_FLAG(pTxBlk, fTX_bClearEAPFrame)) && (pAd->SharedKey[BSS0][0].CipherAlg) &&
+				(pAd->SharedKey[BSS0][0].KeyLen))
+			{
+				CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
+				KeyIdx = 0;
+			}
+		}
+		else if (Cipher == Ndis802_11Encryption1Enabled)
+		{
+#ifdef LEAP_SUPPORT
+			if (pAd->StaCfg.CkipFlag & 0x10) // Cisco CKIP KP is on
+			{
+				if (LEAP_CCKM_ON(pAd))
+				{
+					if (((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd))))
+						KeyIdx = 1;
+					else
+						KeyIdx = 0;
+				}
+				else
+					KeyIdx = pAd->StaCfg.DefaultKeyId;
+			}
+			else if (pAd->StaCfg.CkipFlag & 0x08) // only CKIP CMIC
+				KeyIdx = pAd->StaCfg.DefaultKeyId;
+			else if (LEAP_CCKM_ON(pAd))
+			{
+				if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd)))
+					KeyIdx = 1;
+				else
+					KeyIdx = 0;
+			}
+			else	// standard WEP64 or WEP128
+#endif // LEAP_SUPPORT //
+				KeyIdx = pAd->StaCfg.DefaultKeyId;
+		}
+		else if ((Cipher == Ndis802_11Encryption2Enabled) ||
+				 (Cipher == Ndis802_11Encryption3Enabled))
+		{
+			if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd))) // multicast
+				KeyIdx = pAd->StaCfg.DefaultKeyId;
+			else if (pAd->SharedKey[BSS0][0].KeyLen)
+				KeyIdx = 0;
+			else
+				KeyIdx = pAd->StaCfg.DefaultKeyId;
+		}
+
+		if (KeyIdx == 0xff)
+			CipherAlg = CIPHER_NONE;
+		else if ((Cipher == Ndis802_11EncryptionDisabled) || (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 0))
+			CipherAlg = CIPHER_NONE;
+#ifdef WPA_SUPPLICANT_SUPPORT
+	    else if ( pAd->StaCfg.WpaSupplicantUP &&
+	             (Cipher == Ndis802_11Encryption1Enabled) &&
+	             (pAd->StaCfg.IEEE8021X == TRUE) &&
+	             (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
+	        CipherAlg = CIPHER_NONE;
+#endif // WPA_SUPPLICANT_SUPPORT //
+		else
+		{
+			//Header_802_11.FC.Wep = 1;
+			CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
+			pKey = &pAd->SharedKey[BSS0][KeyIdx];
+		}
+	}
+
+	pTxBlk->CipherAlg = CipherAlg;
+	pTxBlk->pKey = pKey;
+}
+
+
+VOID STABuildCommon802_11Header(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  TX_BLK          *pTxBlk)
+{
+
+	HEADER_802_11	*pHeader_802_11;
+#ifdef QOS_DLS_SUPPORT
+	BOOLEAN	bDLSFrame = FALSE;
+	INT	DlsEntryIndex = 0;
+#endif // QOS_DLS_SUPPORT //
+
+	//
+	// MAKE A COMMON 802.11 HEADER
+	//
+
+	// normal wlan header size : 24 octets
+	pTxBlk->MpduHeaderLen = sizeof(HEADER_802_11);
+
+	pHeader_802_11 = (HEADER_802_11 *) &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
+
+	NdisZeroMemory(pHeader_802_11, sizeof(HEADER_802_11));
+
+	pHeader_802_11->FC.FrDs = 0;
+	pHeader_802_11->FC.Type = BTYPE_DATA;
+	pHeader_802_11->FC.SubType = ((TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) ? SUBTYPE_QDATA : SUBTYPE_DATA);
+
+#ifdef QOS_DLS_SUPPORT
+	if (INFRA_ON(pAd))
+	{
+		// Check if the frame can be sent through DLS direct link interface
+		// If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability)
+		DlsEntryIndex = RTMPCheckDLSFrame(pAd, pTxBlk->pSrcBufHeader);
+		if (DlsEntryIndex >= 0)
+			bDLSFrame = TRUE;
+		else
+			bDLSFrame = FALSE;
+	}
+#endif // QOS_DLS_SUPPORT //
+
+    if (pTxBlk->pMacEntry)
+	{
+		if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bForceNonQoS))
+		{
+			pHeader_802_11->Sequence = pTxBlk->pMacEntry->NonQosDataSeq;
+			pTxBlk->pMacEntry->NonQosDataSeq = (pTxBlk->pMacEntry->NonQosDataSeq+1) & MAXSEQ;
+		}
+		else
+		{
+#ifdef QOS_DLS_SUPPORT
+			if (bDLSFrame)
+			{
+				pHeader_802_11->Sequence = pAd->StaCfg.DLSEntry[DlsEntryIndex].Sequence;
+				pAd->StaCfg.DLSEntry[DlsEntryIndex].Sequence = (pAd->StaCfg.DLSEntry[DlsEntryIndex].Sequence+1) & MAXSEQ;
+			}
+			else
+#endif // QOS_DLS_SUPPORT //
+			{
+    	    pHeader_802_11->Sequence = pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority];
+    	    pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority] = (pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority]+1) & MAXSEQ;
+    	}
+	}
+	}
+	else
+	{
+		pHeader_802_11->Sequence = pAd->Sequence;
+		pAd->Sequence = (pAd->Sequence+1) & MAXSEQ; // next sequence
+	}
+
+	pHeader_802_11->Frag = 0;
+
+	pHeader_802_11->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
+
+	{
+		if (INFRA_ON(pAd))
+		{
+#ifdef QOS_DLS_SUPPORT
+			if (bDLSFrame)
+			{
+				COPY_MAC_ADDR(pHeader_802_11->Addr1, pTxBlk->pSrcBufHeader);
+				COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
+				COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
+				pHeader_802_11->FC.ToDs = 0;
+			}
+			else
+#endif // QOS_DLS_SUPPORT //
+			{
+			COPY_MAC_ADDR(pHeader_802_11->Addr1, pAd->CommonCfg.Bssid);
+			COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
+			COPY_MAC_ADDR(pHeader_802_11->Addr3, pTxBlk->pSrcBufHeader);
+			pHeader_802_11->FC.ToDs = 1;
+		}
+		}
+		else if (ADHOC_ON(pAd))
+		{
+			COPY_MAC_ADDR(pHeader_802_11->Addr1, pTxBlk->pSrcBufHeader);
+			COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
+			COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
+			pHeader_802_11->FC.ToDs = 0;
+		}
+	}
+
+	if (pTxBlk->CipherAlg != CIPHER_NONE)
+		pHeader_802_11->FC.Wep = 1;
+
+	// -----------------------------------------------------------------
+	// STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later.
+	// -----------------------------------------------------------------
+	if (pAd->CommonCfg.bAPSDForcePowerSave)
+    	pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
+	else
+    	pHeader_802_11->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
+}
+
+#ifdef DOT11_N_SUPPORT
+VOID STABuildCache802_11Header(
+	IN RTMP_ADAPTER		*pAd,
+	IN TX_BLK			*pTxBlk,
+	IN UCHAR			*pHeader)
+{
+	MAC_TABLE_ENTRY	*pMacEntry;
+	PHEADER_802_11	pHeader80211;
+
+	pHeader80211 = (PHEADER_802_11)pHeader;
+	pMacEntry = pTxBlk->pMacEntry;
+
+	//
+	// Update the cached 802.11 HEADER
+	//
+
+	// normal wlan header size : 24 octets
+	pTxBlk->MpduHeaderLen = sizeof(HEADER_802_11);
+
+	// More Bit
+	pHeader80211->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
+
+	// Sequence
+	pHeader80211->Sequence = pMacEntry->TxSeq[pTxBlk->UserPriority];
+    pMacEntry->TxSeq[pTxBlk->UserPriority] = (pMacEntry->TxSeq[pTxBlk->UserPriority]+1) & MAXSEQ;
+
+	{
+		// Check if the frame can be sent through DLS direct link interface
+		// If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability)
+#ifdef QOS_DLS_SUPPORT
+		BOOLEAN	bDLSFrame = FALSE;
+		INT	DlsEntryIndex = 0;
+
+		DlsEntryIndex = RTMPCheckDLSFrame(pAd, pTxBlk->pSrcBufHeader);
+		if (DlsEntryIndex >= 0)
+			bDLSFrame = TRUE;
+		else
+			bDLSFrame = FALSE;
+#endif // QOS_DLS_SUPPORT //
+
+		// The addr3 of normal packet send from DS is Dest Mac address.
+#ifdef QOS_DLS_SUPPORT
+		if (bDLSFrame)
+		{
+			COPY_MAC_ADDR(pHeader80211->Addr1, pTxBlk->pSrcBufHeader);
+			COPY_MAC_ADDR(pHeader80211->Addr3, pAd->CommonCfg.Bssid);
+			pHeader80211->FC.ToDs = 0;
+		}
+		else
+#endif // QOS_DLS_SUPPORT //
+		if (ADHOC_ON(pAd))
+			COPY_MAC_ADDR(pHeader80211->Addr3, pAd->CommonCfg.Bssid);
+		else
+			COPY_MAC_ADDR(pHeader80211->Addr3, pTxBlk->pSrcBufHeader);
+	}
+
+	// -----------------------------------------------------------------
+	// STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later.
+	// -----------------------------------------------------------------
+	if (pAd->CommonCfg.bAPSDForcePowerSave)
+    	pHeader80211->FC.PwrMgmt = PWR_SAVE;
+	else
+    	pHeader80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
+}
+#endif // DOT11_N_SUPPORT //
+
+static inline PUCHAR STA_Build_ARalink_Frame_Header(
+	IN RTMP_ADAPTER *pAd,
+	IN TX_BLK		*pTxBlk)
+{
+	PUCHAR			pHeaderBufPtr;
+	HEADER_802_11	*pHeader_802_11;
+	PNDIS_PACKET	pNextPacket;
+	UINT32			nextBufLen;
+	PQUEUE_ENTRY	pQEntry;
+
+	STAFindCipherAlgorithm(pAd, pTxBlk);
+	STABuildCommon802_11Header(pAd, pTxBlk);
+
+
+	pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
+	pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
+
+	// steal "order" bit to mark "aggregation"
+	pHeader_802_11->FC.Order = 1;
+
+	// skip common header
+	pHeaderBufPtr += pTxBlk->MpduHeaderLen;
+
+	if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
+	{
+		//
+		// build QOS Control bytes
+		//
+		*pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
+
+		*(pHeaderBufPtr+1) = 0;
+		pHeaderBufPtr +=2;
+		pTxBlk->MpduHeaderLen += 2;
+	}
+
+	// padding at front of LLC header. LLC header should at 4-bytes aligment.
+	pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
+	pHeaderBufPtr = (PCHAR)ROUND_UP(pHeaderBufPtr, 4);
+	pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
+
+	// For RA Aggregation,
+	// put the 2nd MSDU length(extra 2-byte field) after QOS_CONTROL in little endian format
+	pQEntry = pTxBlk->TxPacketList.Head;
+	pNextPacket = QUEUE_ENTRY_TO_PKT(pQEntry);
+	nextBufLen = GET_OS_PKT_LEN(pNextPacket);
+	if (RTMP_GET_PACKET_VLAN(pNextPacket))
+		nextBufLen -= LENGTH_802_1Q;
+
+	*pHeaderBufPtr = (UCHAR)nextBufLen & 0xff;
+	*(pHeaderBufPtr+1) = (UCHAR)(nextBufLen >> 8);
+
+	pHeaderBufPtr += 2;
+	pTxBlk->MpduHeaderLen += 2;
+
+	return pHeaderBufPtr;
+
+}
+
+#ifdef DOT11_N_SUPPORT
+static inline PUCHAR STA_Build_AMSDU_Frame_Header(
+	IN RTMP_ADAPTER *pAd,
+	IN TX_BLK		*pTxBlk)
+{
+	PUCHAR			pHeaderBufPtr;//, pSaveBufPtr;
+	HEADER_802_11	*pHeader_802_11;
+
+
+	STAFindCipherAlgorithm(pAd, pTxBlk);
+	STABuildCommon802_11Header(pAd, pTxBlk);
+
+	pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
+	pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
+
+	// skip common header
+	pHeaderBufPtr += pTxBlk->MpduHeaderLen;
+
+	//
+	// build QOS Control bytes
+	//
+	*pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
+
+	//
+	// A-MSDU packet
+	//
+	*pHeaderBufPtr |= 0x80;
+
+	*(pHeaderBufPtr+1) = 0;
+	pHeaderBufPtr +=2;
+	pTxBlk->MpduHeaderLen += 2;
+
+	//pSaveBufPtr = pHeaderBufPtr;
+
+	//
+	// padding at front of LLC header
+	// LLC header should locate at 4-octets aligment
+	//
+	// @@@ MpduHeaderLen excluding padding @@@
+	//
+	pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
+	pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
+	pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
+
+	return pHeaderBufPtr;
+
+}
+
+
+VOID STA_AMPDU_Frame_Tx(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk)
+{
+	HEADER_802_11	*pHeader_802_11;
+	PUCHAR			pHeaderBufPtr;
+	USHORT			FreeNumber;
+	MAC_TABLE_ENTRY	*pMacEntry;
+	BOOLEAN			bVLANPkt;
+	PQUEUE_ENTRY	pQEntry;
+
+	ASSERT(pTxBlk);
+
+	while(pTxBlk->TxPacketList.Head)
+	{
+		pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
+		pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
+		if ( RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
+		{
+			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+			continue;
+		}
+
+		bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
+
+		pMacEntry = pTxBlk->pMacEntry;
+		if (pMacEntry->isCached)
+		{
+			// NOTE: Please make sure the size of pMacEntry->CachedBuf[] is smaller than pTxBlk->HeaderBuf[]!!!!
+			NdisMoveMemory((PUCHAR)&pTxBlk->HeaderBuf[TXINFO_SIZE], (PUCHAR)&pMacEntry->CachedBuf[0], TXWI_SIZE + sizeof(HEADER_802_11));
+			pHeaderBufPtr = (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE]);
+			STABuildCache802_11Header(pAd, pTxBlk, pHeaderBufPtr);
+		}
+		else
+		{
+			STAFindCipherAlgorithm(pAd, pTxBlk);
+			STABuildCommon802_11Header(pAd, pTxBlk);
+
+			pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
+		}
+
+
+		pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
+
+		// skip common header
+		pHeaderBufPtr += pTxBlk->MpduHeaderLen;
+
+		//
+		// build QOS Control bytes
+		//
+		*pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
+		*(pHeaderBufPtr+1) = 0;
+		pHeaderBufPtr +=2;
+		pTxBlk->MpduHeaderLen += 2;
+
+		//
+		// build HTC+
+		// HTC control filed following QoS field
+		//
+		if ((pAd->CommonCfg.bRdg == TRUE) && CLIENT_STATUS_TEST_FLAG(pTxBlk->pMacEntry, fCLIENT_STATUS_RDG_CAPABLE))
+		{
+			if (pMacEntry->isCached == FALSE)
+			{
+				// mark HTC bit
+				pHeader_802_11->FC.Order = 1;
+
+				NdisZeroMemory(pHeaderBufPtr, 4);
+				*(pHeaderBufPtr+3) |= 0x80;
+			}
+			pHeaderBufPtr += 4;
+			pTxBlk->MpduHeaderLen += 4;
+		}
+
+		//pTxBlk->MpduHeaderLen = pHeaderBufPtr - pTxBlk->HeaderBuf - TXWI_SIZE - TXINFO_SIZE;
+		ASSERT(pTxBlk->MpduHeaderLen >= 24);
+
+		// skip 802.3 header
+		pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
+		pTxBlk->SrcBufLen  -= LENGTH_802_3;
+
+		// skip vlan tag
+		if (bVLANPkt)
+		{
+			pTxBlk->pSrcBufData	+= LENGTH_802_1Q;
+			pTxBlk->SrcBufLen	-= LENGTH_802_1Q;
+		}
+
+		//
+		// padding at front of LLC header
+		// LLC header should locate at 4-octets aligment
+		//
+		// @@@ MpduHeaderLen excluding padding @@@
+		//
+		pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
+		pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
+		pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
+
+		{
+
+			//
+			// Insert LLC-SNAP encapsulation - 8 octets
+			//
+			EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
+			if (pTxBlk->pExtraLlcSnapEncap)
+			{
+				NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
+				pHeaderBufPtr += 6;
+				// get 2 octets (TypeofLen)
+				NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
+				pHeaderBufPtr += 2;
+				pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
+			}
+
+		}
+
+		if (pMacEntry->isCached)
+		{
+            RTMPWriteTxWI_Cache(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+		}
+		else
+		{
+			RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+
+			NdisZeroMemory((PUCHAR)(&pMacEntry->CachedBuf[0]), sizeof(pMacEntry->CachedBuf));
+			NdisMoveMemory((PUCHAR)(&pMacEntry->CachedBuf[0]), (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), (pHeaderBufPtr - (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE])));
+			pMacEntry->isCached = TRUE;
+		}
+
+		// calculate Transmitted AMPDU count and ByteCount
+		{
+			pAd->RalinkCounters.TransmittedMPDUsInAMPDUCount.u.LowPart ++;
+			pAd->RalinkCounters.TransmittedOctetsInAMPDUCount.QuadPart += pTxBlk->SrcBufLen;
+		}
+
+		//FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
+
+		HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);
+
+		//
+		// Kick out Tx
+		//
+		HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+
+		pAd->RalinkCounters.KickTxCount++;
+		pAd->RalinkCounters.OneSecTxDoneCount++;
+	}
+
+}
+
+
+VOID STA_AMSDU_Frame_Tx(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk)
+{
+	PUCHAR			pHeaderBufPtr;
+	USHORT			FreeNumber;
+	USHORT			subFramePayloadLen = 0;	// AMSDU Subframe length without AMSDU-Header / Padding.
+	USHORT			totalMPDUSize=0;
+	UCHAR			*subFrameHeader;
+	UCHAR			padding = 0;
+	USHORT			FirstTx = 0, LastTxIdx = 0;
+	BOOLEAN			bVLANPkt;
+	int 			frameNum = 0;
+	PQUEUE_ENTRY	pQEntry;
+
+
+	ASSERT(pTxBlk);
+
+	ASSERT((pTxBlk->TxPacketList.Number > 1));
+
+	while(pTxBlk->TxPacketList.Head)
+	{
+		pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
+		pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
+		if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
+		{
+			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+			continue;
+		}
+
+		bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
+
+		// skip 802.3 header
+		pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
+		pTxBlk->SrcBufLen  -= LENGTH_802_3;
+
+		// skip vlan tag
+		if (bVLANPkt)
+		{
+			pTxBlk->pSrcBufData	+= LENGTH_802_1Q;
+			pTxBlk->SrcBufLen	-= LENGTH_802_1Q;
+		}
+
+		if (frameNum == 0)
+		{
+			pHeaderBufPtr = STA_Build_AMSDU_Frame_Header(pAd, pTxBlk);
+
+			// NOTE: TxWI->MPDUtotalByteCount will be updated after final frame was handled.
+			RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+		}
+		else
+		{
+			pHeaderBufPtr = &pTxBlk->HeaderBuf[0];
+			padding = ROUND_UP(LENGTH_AMSDU_SUBFRAMEHEAD + subFramePayloadLen, 4) - (LENGTH_AMSDU_SUBFRAMEHEAD + subFramePayloadLen);
+			NdisZeroMemory(pHeaderBufPtr, padding + LENGTH_AMSDU_SUBFRAMEHEAD);
+			pHeaderBufPtr += padding;
+			pTxBlk->MpduHeaderLen = padding;
+		}
+
+		//
+		// A-MSDU subframe
+		//   DA(6)+SA(6)+Length(2) + LLC/SNAP Encap
+		//
+		subFrameHeader = pHeaderBufPtr;
+		subFramePayloadLen = pTxBlk->SrcBufLen;
+
+		NdisMoveMemory(subFrameHeader, pTxBlk->pSrcBufHeader, 12);
+
+
+		pHeaderBufPtr += LENGTH_AMSDU_SUBFRAMEHEAD;
+		pTxBlk->MpduHeaderLen += LENGTH_AMSDU_SUBFRAMEHEAD;
+
+
+		//
+		// Insert LLC-SNAP encapsulation - 8 octets
+		//
+		EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
+
+		subFramePayloadLen = pTxBlk->SrcBufLen;
+
+		if (pTxBlk->pExtraLlcSnapEncap)
+		{
+			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
+			pHeaderBufPtr += 6;
+			// get 2 octets (TypeofLen)
+			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
+			pHeaderBufPtr += 2;
+			pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
+			subFramePayloadLen += LENGTH_802_1_H;
+		}
+
+		// update subFrame Length field
+		subFrameHeader[12] = (subFramePayloadLen & 0xFF00) >> 8;
+		subFrameHeader[13] = subFramePayloadLen & 0xFF;
+
+		totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
+
+		if (frameNum ==0)
+			FirstTx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
+		else
+			LastTxIdx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
+
+		frameNum++;
+
+		pAd->RalinkCounters.KickTxCount++;
+		pAd->RalinkCounters.OneSecTxDoneCount++;
+
+		// calculate Transmitted AMSDU Count and ByteCount
+		{
+			pAd->RalinkCounters.TransmittedAMSDUCount.u.LowPart ++;
+			pAd->RalinkCounters.TransmittedOctetsInAMSDU.QuadPart += totalMPDUSize;
+		}
+
+	}
+
+	HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
+	HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);
+
+	//
+	// Kick out Tx
+	//
+	HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+}
+#endif // DOT11_N_SUPPORT //
+
+VOID STA_Legacy_Frame_Tx(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk)
+{
+	HEADER_802_11	*pHeader_802_11;
+	PUCHAR			pHeaderBufPtr;
+	USHORT			FreeNumber;
+	BOOLEAN			bVLANPkt;
+	PQUEUE_ENTRY	pQEntry;
+
+	ASSERT(pTxBlk);
+
+
+	pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
+	pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
+	if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
+	{
+		RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+		return;
+	}
+
+	if (pTxBlk->TxFrameType == TX_MCAST_FRAME)
+	{
+		INC_COUNTER64(pAd->WlanCounters.MulticastTransmittedFrameCount);
+	}
+
+	if (RTMP_GET_PACKET_RTS(pTxBlk->pPacket))
+		TX_BLK_SET_FLAG(pTxBlk, fTX_bRtsRequired);
+	else
+		TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bRtsRequired);
+
+	bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
+
+	if (pTxBlk->TxRate < pAd->CommonCfg.MinTxRate)
+		pTxBlk->TxRate = pAd->CommonCfg.MinTxRate;
+
+	STAFindCipherAlgorithm(pAd, pTxBlk);
+	STABuildCommon802_11Header(pAd, pTxBlk);
+
+
+	// skip 802.3 header
+	pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
+	pTxBlk->SrcBufLen  -= LENGTH_802_3;
+
+	// skip vlan tag
+	if (bVLANPkt)
+	{
+		pTxBlk->pSrcBufData	+= LENGTH_802_1Q;
+		pTxBlk->SrcBufLen	-= LENGTH_802_1Q;
+	}
+
+	pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
+	pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
+
+	// skip common header
+	pHeaderBufPtr += pTxBlk->MpduHeaderLen;
+
+	if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
+	{
+		//
+		// build QOS Control bytes
+		//
+		*pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
+		*(pHeaderBufPtr+1) = 0;
+		pHeaderBufPtr +=2;
+		pTxBlk->MpduHeaderLen += 2;
+	}
+
+	// The remaining content of MPDU header should locate at 4-octets aligment
+	pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
+	pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
+	pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
+
+	{
+
+		//
+		// Insert LLC-SNAP encapsulation - 8 octets
+		//
+		//
+   		// if original Ethernet frame contains no LLC/SNAP,
+		// then an extra LLC/SNAP encap is required
+		//
+		EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader, pTxBlk->pExtraLlcSnapEncap);
+		if (pTxBlk->pExtraLlcSnapEncap)
+		{
+			UCHAR vlan_size;
+
+			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
+			pHeaderBufPtr += 6;
+			// skip vlan tag
+			vlan_size =  (bVLANPkt) ? LENGTH_802_1Q : 0;
+			// get 2 octets (TypeofLen)
+			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader+12+vlan_size, 2);
+			pHeaderBufPtr += 2;
+			pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
+		}
+
+	}
+
+	//
+	// prepare for TXWI
+	// use Wcid as Key Index
+	//
+
+	RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+
+	//FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
+
+	HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);
+
+	pAd->RalinkCounters.KickTxCount++;
+	pAd->RalinkCounters.OneSecTxDoneCount++;
+
+	//
+	// Kick out Tx
+	//
+	HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+}
+
+
+VOID STA_ARalink_Frame_Tx(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk)
+{
+	PUCHAR			pHeaderBufPtr;
+	USHORT			FreeNumber;
+	USHORT			totalMPDUSize=0;
+	USHORT			FirstTx, LastTxIdx;
+	int 			frameNum = 0;
+	BOOLEAN			bVLANPkt;
+	PQUEUE_ENTRY	pQEntry;
+
+
+	ASSERT(pTxBlk);
+
+	ASSERT((pTxBlk->TxPacketList.Number== 2));
+
+
+	FirstTx = LastTxIdx = 0;  // Is it ok init they as 0?
+	while(pTxBlk->TxPacketList.Head)
+	{
+		pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
+		pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
+
+		if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
+		{
+			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+			continue;
+		}
+
+		bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
+
+		// skip 802.3 header
+		pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
+		pTxBlk->SrcBufLen  -= LENGTH_802_3;
+
+		// skip vlan tag
+		if (bVLANPkt)
+		{
+			pTxBlk->pSrcBufData	+= LENGTH_802_1Q;
+			pTxBlk->SrcBufLen	-= LENGTH_802_1Q;
+		}
+
+		if (frameNum == 0)
+		{	// For first frame, we need to create the 802.11 header + padding(optional) + RA-AGG-LEN + SNAP Header
+
+			pHeaderBufPtr = STA_Build_ARalink_Frame_Header(pAd, pTxBlk);
+
+			// It's ok write the TxWI here, because the TxWI->MPDUtotalByteCount
+			//	will be updated after final frame was handled.
+			RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+
+
+			//
+			// Insert LLC-SNAP encapsulation - 8 octets
+			//
+			EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
+
+			if (pTxBlk->pExtraLlcSnapEncap)
+			{
+				NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
+				pHeaderBufPtr += 6;
+				// get 2 octets (TypeofLen)
+				NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
+				pHeaderBufPtr += 2;
+				pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
+			}
+		}
+		else
+		{	// For second aggregated frame, we need create the 802.3 header to headerBuf, because PCI will copy it to SDPtr0.
+
+			pHeaderBufPtr = &pTxBlk->HeaderBuf[0];
+			pTxBlk->MpduHeaderLen = 0;
+
+			// A-Ralink sub-sequent frame header is the same as 802.3 header.
+			//   DA(6)+SA(6)+FrameType(2)
+			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader, 12);
+			pHeaderBufPtr += 12;
+			// get 2 octets (TypeofLen)
+			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
+			pHeaderBufPtr += 2;
+			pTxBlk->MpduHeaderLen = LENGTH_ARALINK_SUBFRAMEHEAD;
+		}
+
+		totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
+
+		//FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
+		if (frameNum ==0)
+			FirstTx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
+		else
+			LastTxIdx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
+
+		frameNum++;
+
+		pAd->RalinkCounters.OneSecTxAggregationCount++;
+		pAd->RalinkCounters.KickTxCount++;
+		pAd->RalinkCounters.OneSecTxDoneCount++;
+
+	}
+
+	HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
+	HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);
+
+	//
+	// Kick out Tx
+	//
+	HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+
+}
+
+
+VOID STA_Fragment_Frame_Tx(
+	IN RTMP_ADAPTER *pAd,
+	IN TX_BLK		*pTxBlk)
+{
+	HEADER_802_11	*pHeader_802_11;
+	PUCHAR			pHeaderBufPtr;
+	USHORT			FreeNumber;
+	UCHAR 			fragNum = 0;
+	PACKET_INFO		PacketInfo;
+	USHORT			EncryptionOverhead = 0;
+	UINT32			FreeMpduSize, SrcRemainingBytes;
+	USHORT			AckDuration;
+	UINT 			NextMpduSize;
+	BOOLEAN			bVLANPkt;
+	PQUEUE_ENTRY	pQEntry;
+
+
+	ASSERT(pTxBlk);
+
+	pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
+	pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
+	if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
+	{
+		RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+		return;
+	}
+
+	ASSERT(TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag));
+	bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
+
+	STAFindCipherAlgorithm(pAd, pTxBlk);
+	STABuildCommon802_11Header(pAd, pTxBlk);
+
+	if (pTxBlk->CipherAlg == CIPHER_TKIP)
+	{
+		pTxBlk->pPacket = duplicate_pkt_with_TKIP_MIC(pAd, pTxBlk->pPacket);
+		if (pTxBlk->pPacket == NULL)
+			return;
+		RTMP_QueryPacketInfo(pTxBlk->pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen);
+	}
+
+	// skip 802.3 header
+	pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
+	pTxBlk->SrcBufLen  -= LENGTH_802_3;
+
+
+	// skip vlan tag
+	if (bVLANPkt)
+	{
+		pTxBlk->pSrcBufData	+= LENGTH_802_1Q;
+		pTxBlk->SrcBufLen	-= LENGTH_802_1Q;
+	}
+
+	pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
+	pHeader_802_11 = (HEADER_802_11 *)pHeaderBufPtr;
+
+
+	// skip common header
+	pHeaderBufPtr += pTxBlk->MpduHeaderLen;
+
+	if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
+	{
+		//
+		// build QOS Control bytes
+		//
+		*pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
+
+		*(pHeaderBufPtr+1) = 0;
+		pHeaderBufPtr +=2;
+		pTxBlk->MpduHeaderLen += 2;
+	}
+
+	//
+	// padding at front of LLC header
+	// LLC header should locate at 4-octets aligment
+	//
+	pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
+	pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
+	pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
+
+
+
+	//
+	// Insert LLC-SNAP encapsulation - 8 octets
+	//
+	//
+   	// if original Ethernet frame contains no LLC/SNAP,
+	// then an extra LLC/SNAP encap is required
+	//
+	EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader, pTxBlk->pExtraLlcSnapEncap);
+	if (pTxBlk->pExtraLlcSnapEncap)
+	{
+		UCHAR vlan_size;
+
+		NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
+		pHeaderBufPtr += 6;
+		// skip vlan tag
+		vlan_size =  (bVLANPkt) ? LENGTH_802_1Q : 0;
+		// get 2 octets (TypeofLen)
+		NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader+12+vlan_size, 2);
+		pHeaderBufPtr += 2;
+		pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
+	}
+
+
+	// If TKIP is used and fragmentation is required. Driver has to
+	//	append TKIP MIC at tail of the scatter buffer
+	//	MAC ASIC will only perform IV/EIV/ICV insertion but no TKIP MIC
+	if (pTxBlk->CipherAlg == CIPHER_TKIP)
+	{
+
+		// NOTE: DON'T refer the skb->len directly after following copy. Becasue the length is not adjust
+		//			to correct lenght, refer to pTxBlk->SrcBufLen for the packet length in following progress.
+		NdisMoveMemory(pTxBlk->pSrcBufData + pTxBlk->SrcBufLen, &pAd->PrivateInfo.Tx.MIC[0], 8);
+		//skb_put((RTPKT_TO_OSPKT(pTxBlk->pPacket))->tail, 8);
+		pTxBlk->SrcBufLen += 8;
+		pTxBlk->TotalFrameLen += 8;
+		pTxBlk->CipherAlg = CIPHER_TKIP_NO_MIC;
+	}
+
+	//
+	// calcuate the overhead bytes that encryption algorithm may add. This
+	// affects the calculate of "duration" field
+	//
+	if ((pTxBlk->CipherAlg == CIPHER_WEP64) || (pTxBlk->CipherAlg == CIPHER_WEP128))
+		EncryptionOverhead = 8; //WEP: IV[4] + ICV[4];
+	else if (pTxBlk->CipherAlg == CIPHER_TKIP_NO_MIC)
+		EncryptionOverhead = 12;//TKIP: IV[4] + EIV[4] + ICV[4], MIC will be added to TotalPacketLength
+	else if (pTxBlk->CipherAlg == CIPHER_TKIP)
+		EncryptionOverhead = 20;//TKIP: IV[4] + EIV[4] + ICV[4] + MIC[8]
+	else if (pTxBlk->CipherAlg == CIPHER_AES)
+		EncryptionOverhead = 16;	// AES: IV[4] + EIV[4] + MIC[8]
+	else
+		EncryptionOverhead = 0;
+
+	// decide how much time an ACK/CTS frame will consume in the air
+	AckDuration = RTMPCalcDuration(pAd, pAd->CommonCfg.ExpectedACKRate[pTxBlk->TxRate], 14);
+
+	// Init the total payload length of this frame.
+	SrcRemainingBytes = pTxBlk->SrcBufLen;
+
+	pTxBlk->TotalFragNum = 0xff;
+
+	do {
+
+		FreeMpduSize = pAd->CommonCfg.FragmentThreshold - LENGTH_CRC;
+
+		FreeMpduSize -= pTxBlk->MpduHeaderLen;
+
+		if (SrcRemainingBytes <= FreeMpduSize)
+		{	// this is the last or only fragment
+
+			pTxBlk->SrcBufLen = SrcRemainingBytes;
+
+			pHeader_802_11->FC.MoreFrag = 0;
+			pHeader_802_11->Duration = pAd->CommonCfg.Dsifs + AckDuration;
+
+			// Indicate the lower layer that this's the last fragment.
+			pTxBlk->TotalFragNum = fragNum;
+		}
+		else
+		{	// more fragment is required
+
+			pTxBlk->SrcBufLen = FreeMpduSize;
+
+			NextMpduSize = min(((UINT)SrcRemainingBytes - pTxBlk->SrcBufLen), ((UINT)pAd->CommonCfg.FragmentThreshold));
+			pHeader_802_11->FC.MoreFrag = 1;
+			pHeader_802_11->Duration = (3 * pAd->CommonCfg.Dsifs) + (2 * AckDuration) + RTMPCalcDuration(pAd, pTxBlk->TxRate, NextMpduSize + EncryptionOverhead);
+		}
+
+		if (fragNum == 0)
+			pTxBlk->FrameGap = IFS_HTTXOP;
+		else
+			pTxBlk->FrameGap = IFS_SIFS;
+
+		RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+
+		HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, &FreeNumber);
+
+		pAd->RalinkCounters.KickTxCount++;
+		pAd->RalinkCounters.OneSecTxDoneCount++;
+
+		// Update the frame number, remaining size of the NDIS packet payload.
+
+		// space for 802.11 header.
+		if (fragNum == 0 && pTxBlk->pExtraLlcSnapEncap)
+			pTxBlk->MpduHeaderLen -= LENGTH_802_1_H;
+
+		fragNum++;
+		SrcRemainingBytes -= pTxBlk->SrcBufLen;
+		pTxBlk->pSrcBufData += pTxBlk->SrcBufLen;
+
+		pHeader_802_11->Frag++;	 // increase Frag #
+
+	}while(SrcRemainingBytes > 0);
+
+	//
+	// Kick out Tx
+	//
+	HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+}
+
+
+#define RELEASE_FRAMES_OF_TXBLK(_pAd, _pTxBlk, _pQEntry, _Status) 										\
+		while(_pTxBlk->TxPacketList.Head)														\
+		{																						\
+			_pQEntry = RemoveHeadQueue(&_pTxBlk->TxPacketList);									\
+			RELEASE_NDIS_PACKET(_pAd, QUEUE_ENTRY_TO_PACKET(_pQEntry), _Status);	\
+		}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Copy frame from waiting queue into relative ring buffer and set
+	appropriate ASIC register to kick hardware encryption before really
+	sent out to air.
+
+	Arguments:
+		pAd 	Pointer to our adapter
+		PNDIS_PACKET	Pointer to outgoing Ndis frame
+		NumberOfFrag	Number of fragment required
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+NDIS_STATUS STAHardTransmit(
+	IN PRTMP_ADAPTER	pAd,
+	IN TX_BLK 			*pTxBlk,
+	IN	UCHAR			QueIdx)
+{
+	NDIS_PACKET		*pPacket;
+	PQUEUE_ENTRY	pQEntry;
+
+	// ---------------------------------------------
+	// STEP 0. DO SANITY CHECK AND SOME EARLY PREPARATION.
+	// ---------------------------------------------
+	//
+	ASSERT(pTxBlk->TxPacketList.Number);
+	if (pTxBlk->TxPacketList.Head == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("pTxBlk->TotalFrameNum == %ld!\n", pTxBlk->TxPacketList.Number));
+		return NDIS_STATUS_FAILURE;
+	}
+
+	pPacket = QUEUE_ENTRY_TO_PACKET(pTxBlk->TxPacketList.Head);
+
+	// ------------------------------------------------------------------
+	// STEP 1. WAKE UP PHY
+	//		outgoing frame always wakeup PHY to prevent frame lost and
+	//		turn off PSM bit to improve performance
+	// ------------------------------------------------------------------
+	// not to change PSM bit, just send this frame out?
+	if ((pAd->StaCfg.Psm == PWR_SAVE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+	{
+	    DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicForceWakeup At HardTx\n"));
+		AsicForceWakeup(pAd, TRUE);
+	}
+
+	// It should not change PSM bit, when APSD turn on.
+	if ((!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable) && (pAd->CommonCfg.bAPSDForcePowerSave == FALSE))
+		|| (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket))
+		|| (RTMP_GET_PACKET_WAI(pTxBlk->pPacket)))
+	{
+		if ((pAd->StaCfg.Psm == PWR_SAVE) &&
+            (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeFast_PSP))
+			MlmeSetPsmBit(pAd, PWR_ACTIVE);
+	}
+
+	switch (pTxBlk->TxFrameType)
+	{
+#ifdef DOT11_N_SUPPORT
+		case TX_AMPDU_FRAME:
+				STA_AMPDU_Frame_Tx(pAd, pTxBlk);
+			break;
+		case TX_AMSDU_FRAME:
+				STA_AMSDU_Frame_Tx(pAd, pTxBlk);
+			break;
+#endif // DOT11_N_SUPPORT //
+		case TX_LEGACY_FRAME:
+				STA_Legacy_Frame_Tx(pAd, pTxBlk);
+			break;
+		case TX_MCAST_FRAME:
+				STA_Legacy_Frame_Tx(pAd, pTxBlk);
+			break;
+		case TX_RALINK_FRAME:
+				STA_ARalink_Frame_Tx(pAd, pTxBlk);
+			break;
+		case TX_FRAG_FRAME:
+				STA_Fragment_Frame_Tx(pAd, pTxBlk);
+			break;
+		default:
+			{
+				// It should not happened!
+				DBGPRINT(RT_DEBUG_ERROR, ("Send a pacekt was not classified!! It should not happen!\n"));
+				while(pTxBlk->TxPacketList.Number)
+				{
+					pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
+					pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
+					if (pPacket)
+						RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+				}
+			}
+			break;
+	}
+
+	return (NDIS_STATUS_SUCCESS);
+
+}
+
+ULONG  HashBytesPolynomial(UCHAR *value, unsigned int len)
+{
+   unsigned char *word = value;
+   unsigned int ret = 0;
+   unsigned int i;
+
+   for(i=0; i < len; i++)
+   {
+	  int mod = i % 32;
+	  ret ^=(unsigned int) (word[i]) << mod;
+	  ret ^=(unsigned int) (word[i]) >> (32 - mod);
+   }
+   return ret;
+}
+
+VOID Sta_Announce_or_Forward_802_3_Packet(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PNDIS_PACKET	pPacket,
+	IN	UCHAR			FromWhichBSSID)
+{
+	if (TRUE
+		)
+	{
+		announce_802_3_packet(pAd, pPacket);
+	}
+	else
+	{
+		// release packet
+		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+	}
+}
+
diff --git a/drivers/staging/rt3070/sta/sanity.c b/drivers/staging/rt3070/sta/sanity.c
new file mode 100644
index 0000000..2398724
--- /dev/null
+++ b/drivers/staging/rt3070/sta/sanity.c
@@ -0,0 +1,420 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	sanity.c
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	John Chang  2004-09-01      add WMM support
+*/
+#include "../rt_config.h"
+
+extern UCHAR	CISCO_OUI[];
+
+extern UCHAR	WPA_OUI[];
+extern UCHAR	RSN_OUI[];
+extern UCHAR	WME_INFO_ELEM[];
+extern UCHAR	WME_PARM_ELEM[];
+extern UCHAR	Ccx2QosInfo[];
+extern UCHAR	RALINK_OUI[];
+extern UCHAR	BROADCOM_OUI[];
+
+/*
+    ==========================================================================
+    Description:
+        MLME message sanity check
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+ */
+BOOLEAN MlmeStartReqSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *Msg,
+    IN ULONG MsgLen,
+    OUT CHAR Ssid[],
+    OUT UCHAR *pSsidLen)
+{
+    MLME_START_REQ_STRUCT *Info;
+
+    Info = (MLME_START_REQ_STRUCT *)(Msg);
+
+    if (Info->SsidLen > MAX_LEN_OF_SSID)
+    {
+        DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqSanity fail - wrong SSID length\n"));
+        return FALSE;
+    }
+
+    *pSsidLen = Info->SsidLen;
+    NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen);
+
+    return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        MLME message sanity check
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+
+    IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+BOOLEAN PeerAssocRspSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *pMsg,
+    IN ULONG MsgLen,
+    OUT PUCHAR pAddr2,
+    OUT USHORT *pCapabilityInfo,
+    OUT USHORT *pStatus,
+    OUT USHORT *pAid,
+    OUT UCHAR SupRate[],
+    OUT UCHAR *pSupRateLen,
+    OUT UCHAR ExtRate[],
+    OUT UCHAR *pExtRateLen,
+    OUT HT_CAPABILITY_IE		*pHtCapability,
+    OUT ADD_HT_INFO_IE		*pAddHtInfo,	// AP might use this additional ht info IE
+    OUT UCHAR			*pHtCapabilityLen,
+    OUT UCHAR			*pAddHtInfoLen,
+    OUT UCHAR			*pNewExtChannelOffset,
+    OUT PEDCA_PARM pEdcaParm,
+    OUT UCHAR *pCkipFlag)
+{
+    CHAR          IeType, *Ptr;
+    PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
+    PEID_STRUCT   pEid;
+    ULONG         Length = 0;
+
+	*pNewExtChannelOffset = 0xff;
+	*pHtCapabilityLen = 0;
+	*pAddHtInfoLen = 0;
+    COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
+    Ptr = pFrame->Octet;
+    Length += LENGTH_802_11;
+
+    NdisMoveMemory(pCapabilityInfo, &pFrame->Octet[0], 2);
+    Length += 2;
+    NdisMoveMemory(pStatus,         &pFrame->Octet[2], 2);
+    Length += 2;
+    *pCkipFlag = 0;
+    *pExtRateLen = 0;
+    pEdcaParm->bValid = FALSE;
+
+    if (*pStatus != MLME_SUCCESS)
+        return TRUE;
+
+    NdisMoveMemory(pAid, &pFrame->Octet[4], 2);
+    Length += 2;
+
+    // Aid already swaped byte order in RTMPFrameEndianChange() for big endian platform
+    *pAid = (*pAid) & 0x3fff; // AID is low 14-bit
+
+    // -- get supported rates from payload and advance the pointer
+    IeType = pFrame->Octet[6];
+    *pSupRateLen = pFrame->Octet[7];
+    if ((IeType != IE_SUPP_RATES) || (*pSupRateLen > MAX_LEN_OF_SUPPORTED_RATES))
+    {
+        DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspSanity fail - wrong SupportedRates IE\n"));
+        return FALSE;
+    }
+    else
+        NdisMoveMemory(SupRate, &pFrame->Octet[8], *pSupRateLen);
+
+    Length = Length + 2 + *pSupRateLen;
+
+    // many AP implement proprietary IEs in non-standard order, we'd better
+    // tolerate mis-ordered IEs to get best compatibility
+    pEid = (PEID_STRUCT) &pFrame->Octet[8 + (*pSupRateLen)];
+
+    // get variable fields from payload and advance the pointer
+    while ((Length + 2 + pEid->Len) <= MsgLen)
+    {
+        switch (pEid->Eid)
+        {
+            case IE_EXT_SUPP_RATES:
+                if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
+                {
+                    NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len);
+                    *pExtRateLen = pEid->Len;
+                }
+                break;
+
+             case IE_HT_CAP:
+            case IE_HT_CAP2:
+			if (pEid->Len >= SIZE_HT_CAP_IE)  //Note: allow extension.!!
+			{
+				NdisMoveMemory(pHtCapability, pEid->Octet, SIZE_HT_CAP_IE);
+
+				*(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
+				*(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
+
+				*pHtCapabilityLen = SIZE_HT_CAP_IE;
+			}
+			else
+			{
+				DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_HT_CAP. \n"));
+			}
+
+		break;
+#ifdef DOT11_N_SUPPORT
+            case IE_ADD_HT:
+            case IE_ADD_HT2:
+			if (pEid->Len >= sizeof(ADD_HT_INFO_IE))
+			{
+				// This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only
+				// copy first sizeof(ADD_HT_INFO_IE)
+				NdisMoveMemory(pAddHtInfo, pEid->Octet, sizeof(ADD_HT_INFO_IE));
+
+				*(USHORT *)(&pAddHtInfo->AddHtInfo2) = cpu2le16(*(USHORT *)(&pAddHtInfo->AddHtInfo2));
+				*(USHORT *)(&pAddHtInfo->AddHtInfo3) = cpu2le16(*(USHORT *)(&pAddHtInfo->AddHtInfo3));
+
+				*pAddHtInfoLen = SIZE_ADD_HT_INFO_IE;
+			}
+			else
+			{
+				DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_ADD_HT. \n"));
+			}
+
+		break;
+            case IE_SECONDARY_CH_OFFSET:
+			if (pEid->Len == 1)
+			{
+				*pNewExtChannelOffset = pEid->Octet[0];
+			}
+			else
+			{
+				DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
+			}
+#endif // DOT11_N_SUPPORT //
+		break;
+            case IE_AIRONET_CKIP:
+                // 0. Check Aironet IE length, it must be larger or equal to 28
+                //    Cisco's AP VxWork version(will not be supported) used this IE length as 28
+                //    Cisco's AP IOS version used this IE length as 30
+                if (pEid->Len < (CKIP_NEGOTIATION_LENGTH - 2))
+                break;
+
+                // 1. Copy CKIP flag byte to buffer for process
+                *pCkipFlag = *(pEid->Octet + 8);
+                break;
+
+            case IE_AIRONET_IPADDRESS:
+                if (pEid->Len != 0x0A)
+                break;
+
+                // Get Cisco Aironet IP information
+                if (NdisEqualMemory(pEid->Octet, CISCO_OUI, 3) == 1)
+                    NdisMoveMemory(pAd->StaCfg.AironetIPAddress, pEid->Octet + 4, 4);
+                break;
+
+            // CCX2, WMM use the same IE value
+            // case IE_CCX_V2:
+            case IE_VENDOR_SPECIFIC:
+                // handle WME PARAMTER ELEMENT
+                if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) && (pEid->Len == 24))
+                {
+                    PUCHAR ptr;
+                    int i;
+
+                    // parsing EDCA parameters
+                    pEdcaParm->bValid          = TRUE;
+                    pEdcaParm->bQAck           = FALSE; // pEid->Octet[0] & 0x10;
+                    pEdcaParm->bQueueRequest   = FALSE; // pEid->Octet[0] & 0x20;
+                    pEdcaParm->bTxopRequest    = FALSE; // pEid->Octet[0] & 0x40;
+                    //pEdcaParm->bMoreDataAck    = FALSE; // pEid->Octet[0] & 0x80;
+                    pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f;
+                    pEdcaParm->bAPSDCapable    = (pEid->Octet[6] & 0x80) ? 1 : 0;
+                    ptr = &pEid->Octet[8];
+                    for (i=0; i<4; i++)
+                    {
+                        UCHAR aci = (*ptr & 0x60) >> 5; // b5~6 is AC INDEX
+                        pEdcaParm->bACM[aci]  = (((*ptr) & 0x10) == 0x10);   // b5 is ACM
+                        pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f;               // b0~3 is AIFSN
+                        pEdcaParm->Cwmin[aci] = *(ptr+1) & 0x0f;             // b0~4 is Cwmin
+                        pEdcaParm->Cwmax[aci] = *(ptr+1) >> 4;               // b5~8 is Cwmax
+                        pEdcaParm->Txop[aci]  = *(ptr+2) + 256 * (*(ptr+3)); // in unit of 32-us
+                        ptr += 4; // point to next AC
+                    }
+                }
+
+                // handle CCX IE
+                else
+                {
+                    // 0. Check the size and CCX admin control
+                    if (pAd->StaCfg.CCXControl.field.Enable == 0)
+                        break;
+                    if (pEid->Len != 5)
+                        break;
+
+                    // Turn CCX2 if matched
+                    if (NdisEqualMemory(pEid->Octet, Ccx2IeInfo, 5) == 1)
+                        pAd->StaCfg.CCXEnable = TRUE;
+                    break;
+                }
+                break;
+
+            default:
+                DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspSanity - ignore unrecognized EID = %d\n", pEid->Eid));
+                break;
+        }
+
+        Length = Length + 2 + pEid->Len;
+        pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
+    }
+
+    // Force CCX2 enable to TRUE for those AP didn't replay CCX v2 IE, we still force it to be on
+    if (pAd->StaCfg.CCXControl.field.Enable == 1)
+        pAd->StaCfg.CCXEnable = TRUE;
+
+    return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        MLME message sanity check
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+BOOLEAN PeerProbeReqSanity(
+    IN PRTMP_ADAPTER pAd,
+    IN VOID *Msg,
+    IN ULONG MsgLen,
+    OUT PUCHAR pAddr2,
+    OUT CHAR Ssid[],
+    OUT UCHAR *pSsidLen)
+{
+    UCHAR         Idx;
+    UCHAR	      RateLen;
+    CHAR          IeType;
+    PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
+
+    COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
+
+    if ((pFrame->Octet[0] != IE_SSID) || (pFrame->Octet[1] > MAX_LEN_OF_SSID))
+    {
+        DBGPRINT(RT_DEBUG_TRACE, ("PeerProbeReqSanity fail - wrong SSID IE(Type=%d,Len=%d)\n",pFrame->Octet[0],pFrame->Octet[1]));
+        return FALSE;
+    }
+
+    *pSsidLen = pFrame->Octet[1];
+    NdisMoveMemory(Ssid, &pFrame->Octet[2], *pSsidLen);
+
+    Idx = *pSsidLen + 2;
+
+    // -- get supported rates from payload and advance the pointer
+    IeType = pFrame->Octet[Idx];
+    RateLen = pFrame->Octet[Idx + 1];
+    if (IeType != IE_SUPP_RATES)
+    {
+        DBGPRINT(RT_DEBUG_TRACE, ("PeerProbeReqSanity fail - wrong SupportRates IE(Type=%d,Len=%d)\n",pFrame->Octet[Idx],pFrame->Octet[Idx+1]));
+        return FALSE;
+    }
+    else
+    {
+        if ((pAd->CommonCfg.PhyMode == PHY_11G) && (RateLen < 8))
+            return (FALSE);
+    }
+
+    return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+BOOLEAN GetTimBit(
+    IN CHAR *Ptr,
+    IN USHORT Aid,
+    OUT UCHAR *TimLen,
+    OUT UCHAR *BcastFlag,
+    OUT UCHAR *DtimCount,
+    OUT UCHAR *DtimPeriod,
+    OUT UCHAR *MessageToMe)
+{
+    UCHAR          BitCntl, N1, N2, MyByte, MyBit;
+    CHAR          *IdxPtr;
+
+    IdxPtr = Ptr;
+
+    IdxPtr ++;
+    *TimLen = *IdxPtr;
+
+    // get DTIM Count from TIM element
+    IdxPtr ++;
+    *DtimCount = *IdxPtr;
+
+    // get DTIM Period from TIM element
+    IdxPtr++;
+    *DtimPeriod = *IdxPtr;
+
+    // get Bitmap Control from TIM element
+    IdxPtr++;
+    BitCntl = *IdxPtr;
+
+    if ((*DtimCount == 0) && (BitCntl & 0x01))
+        *BcastFlag = TRUE;
+    else
+        *BcastFlag = FALSE;
+
+    // Parse Partial Virtual Bitmap from TIM element
+    N1 = BitCntl & 0xfe;    // N1 is the first bitmap byte#
+    N2 = *TimLen - 4 + N1;  // N2 is the last bitmap byte#
+
+    if ((Aid < (N1 << 3)) || (Aid >= ((N2 + 1) << 3)))
+        *MessageToMe = FALSE;
+    else
+    {
+        MyByte = (Aid >> 3) - N1;                       // my byte position in the bitmap byte-stream
+        MyBit = Aid % 16 - ((MyByte & 0x01)? 8:0);
+
+        IdxPtr += (MyByte + 1);
+
+        //if (*IdxPtr)
+        //    DBGPRINT(RT_DEBUG_WARN, ("TIM bitmap = 0x%02x\n", *IdxPtr));
+
+        if (*IdxPtr & (0x01 << MyBit))
+            *MessageToMe = TRUE;
+        else
+            *MessageToMe = FALSE;
+    }
+
+    return TRUE;
+}
+
diff --git a/drivers/staging/rt3070/sta/sync.c b/drivers/staging/rt3070/sta/sync.c
new file mode 100644
index 0000000..2b5b3b0
--- /dev/null
+++ b/drivers/staging/rt3070/sta/sync.c
@@ -0,0 +1,1755 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	sync.c
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	John Chang	2004-09-01      modified for rt2561/2661
+	Jan Lee		2006-08-01      modified for rt2860 for 802.11n
+*/
+#include "../rt_config.h"
+
+#define ADHOC_ENTRY_BEACON_LOST_TIME	(2*OS_HZ)	// 2 sec
+
+/*
+	==========================================================================
+	Description:
+		The sync state machine,
+	Parameters:
+		Sm - pointer to the state machine
+	Note:
+		the state machine looks like the following
+
+	==========================================================================
+ */
+VOID SyncStateMachineInit(
+	IN PRTMP_ADAPTER pAd,
+	IN STATE_MACHINE *Sm,
+	OUT STATE_MACHINE_FUNC Trans[])
+{
+	StateMachineInit(Sm, Trans, MAX_SYNC_STATE, MAX_SYNC_MSG, (STATE_MACHINE_FUNC)Drop, SYNC_IDLE, SYNC_MACHINE_BASE);
+
+	// column 1
+	StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)MlmeScanReqAction);
+	StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)MlmeJoinReqAction);
+	StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)MlmeStartReqAction);
+	StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeacon);
+	StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_PROBE_REQ, (STATE_MACHINE_FUNC)PeerProbeReqAction);
+
+	//column 2
+	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenScan);
+	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenJoin);
+	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenStart);
+	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtJoinAction);
+	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_BEACON_TIMEOUT, (STATE_MACHINE_FUNC)BeaconTimeoutAtJoinAction);
+
+	// column 3
+	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenScan);
+	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenJoin);
+	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenStart);
+	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction);
+	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_PROBE_RSP, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction);
+	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_SCAN_TIMEOUT, (STATE_MACHINE_FUNC)ScanTimeoutAction);
+
+	// timer init
+	RTMPInitTimer(pAd, &pAd->MlmeAux.BeaconTimer, GET_TIMER_FUNCTION(BeaconTimeout), pAd, FALSE);
+	RTMPInitTimer(pAd, &pAd->MlmeAux.ScanTimer, GET_TIMER_FUNCTION(ScanTimeout), pAd, FALSE);
+}
+
+/*
+	==========================================================================
+	Description:
+		Beacon timeout handler, executed in timer thread
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID BeaconTimeout(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3)
+{
+	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+	DBGPRINT(RT_DEBUG_TRACE,("SYNC - BeaconTimeout\n"));
+
+	// Do nothing if the driver is starting halt state.
+	// This might happen when timer already been fired before cancel timer with mlmehalt
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
+		return;
+
+#ifdef DOT11_N_SUPPORT
+	if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
+		)
+	{
+		UCHAR        BBPValue = 0;
+		AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+		AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+		BBPValue &= (~0x18);
+		BBPValue |= 0x10;
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+		DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr));
+	}
+#endif // DOT11_N_SUPPORT //
+
+	MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_BEACON_TIMEOUT, 0, NULL);
+	RT28XX_MLME_HANDLER(pAd);
+}
+
+/*
+	==========================================================================
+	Description:
+		Scan timeout handler, executed in timer thread
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID ScanTimeout(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3)
+{
+	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+
+	// Do nothing if the driver is starting halt state.
+	// This might happen when timer already been fired before cancel timer with mlmehalt
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
+		return;
+
+	if (MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_SCAN_TIMEOUT, 0, NULL))
+	{
+		RT28XX_MLME_HANDLER(pAd);
+	}
+	else
+	{
+		// To prevent SyncMachine.CurrState is SCAN_LISTEN forever.
+		pAd->MlmeAux.Channel = 0;
+		ScanNextChannel(pAd);
+		if (pAd->CommonCfg.bWirelessEvent)
+		{
+			RTMPSendWirelessEvent(pAd, IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+		}
+	}
+}
+
+/*
+	==========================================================================
+	Description:
+		MLME SCAN req state machine procedure
+	==========================================================================
+ */
+VOID MlmeScanReqAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	UCHAR          Ssid[MAX_LEN_OF_SSID], SsidLen, ScanType, BssType, BBPValue = 0;
+	BOOLEAN        TimerCancelled;
+	ULONG		   Now;
+	USHORT         Status;
+	PHEADER_802_11 pHdr80211;
+	PUCHAR         pOutBuffer = NULL;
+	NDIS_STATUS    NStatus;
+
+	// Check the total scan tries for one single OID command
+	// If this is the CCX 2.0 Case, skip that!
+	if ( !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeScanReqAction before Startup\n"));
+		return;
+	}
+
+	// Increase the scan retry counters.
+	pAd->StaCfg.ScanCnt++;
+
+
+	// first check the parameter sanity
+	if (MlmeScanReqSanity(pAd,
+						  Elem->Msg,
+						  Elem->MsgLen,
+						  &BssType,
+						  Ssid,
+						  &SsidLen,
+						  &ScanType))
+	{
+
+		// Check for channel load and noise hist request
+		// Suspend MSDU only at scan request, not the last two mentioned
+		if ((ScanType == SCAN_CISCO_NOISE) || (ScanType == SCAN_CISCO_CHANNEL_LOAD))
+		{
+			if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
+				RTMPSuspendMsduTransmission(pAd);			// Suspend MSDU transmission here
+		}
+		else
+		{
+			// Suspend MSDU transmission here
+			RTMPSuspendMsduTransmission(pAd);
+		}
+
+		//
+		// To prevent data lost.
+		// Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
+		// And should send an NULL data with turned PSM bit off to AP, when scan progress done
+		//
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd)))
+		{
+			NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);
+			if (NStatus	== NDIS_STATUS_SUCCESS)
+			{
+				pHdr80211 = (PHEADER_802_11) pOutBuffer;
+				MgtMacHeaderInit(pAd, pHdr80211, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
+				pHdr80211->Duration = 0;
+				pHdr80211->FC.Type = BTYPE_DATA;
+				pHdr80211->FC.PwrMgmt = PWR_SAVE;
+
+				// Send using priority queue
+				MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
+				DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqAction -- Send PSM Data frame for off channel RM\n"));
+				MlmeFreeMemory(pAd, pOutBuffer);
+				RTMPusecDelay(5000);
+			}
+		}
+
+		NdisGetSystemUpTime(&Now);
+		pAd->StaCfg.LastScanTime = Now;
+		// reset all the timers
+		RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
+
+		// record desired BSS parameters
+		pAd->MlmeAux.BssType = BssType;
+		pAd->MlmeAux.ScanType = ScanType;
+		pAd->MlmeAux.SsidLen = SsidLen;
+        NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
+		NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
+
+		// start from the first channel
+		pAd->MlmeAux.Channel = FirstChannel(pAd);
+
+		// Change the scan channel when dealing with CCX beacon report
+		if ((ScanType == SCAN_CISCO_PASSIVE) || (ScanType == SCAN_CISCO_ACTIVE) ||
+			(ScanType == SCAN_CISCO_CHANNEL_LOAD) || (ScanType == SCAN_CISCO_NOISE))
+			pAd->MlmeAux.Channel = pAd->StaCfg.CCXScanChannel;
+
+		// Let BBP register at 20MHz to do scan
+		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+		BBPValue &= (~0x18);
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+		DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
+		ScanNextChannel(pAd);
+	}
+	else
+	{
+		DBGPRINT_ERR(("SYNC - MlmeScanReqAction() sanity check fail\n"));
+		pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+		Status = MLME_INVALID_FORMAT;
+		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
+	}
+}
+
+/*
+	==========================================================================
+	Description:
+		MLME JOIN req state machine procedure
+	==========================================================================
+ */
+VOID MlmeJoinReqAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	UCHAR        BBPValue = 0;
+	BSS_ENTRY    *pBss;
+	BOOLEAN       TimerCancelled;
+	HEADER_802_11 Hdr80211;
+	NDIS_STATUS   NStatus;
+	ULONG         FrameLen = 0;
+	PUCHAR        pOutBuffer = NULL;
+	PUCHAR        pSupRate = NULL;
+	UCHAR         SupRateLen;
+	PUCHAR        pExtRate = NULL;
+	UCHAR         ExtRateLen;
+	UCHAR         ASupRate[] = {0x8C, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6C};
+	UCHAR         ASupRateLen = sizeof(ASupRate)/sizeof(UCHAR);
+	MLME_JOIN_REQ_STRUCT *pInfo = (MLME_JOIN_REQ_STRUCT *)(Elem->Msg);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo->BssIdx));
+
+
+	// reset all the timers
+	RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
+	RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
+
+	pBss = &pAd->MlmeAux.SsidBssTab.BssEntry[pInfo->BssIdx];
+
+	// record the desired SSID & BSSID we're waiting for
+	COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pBss->Bssid);
+
+	// If AP's SSID is not hidden, it is OK for updating ssid to MlmeAux again.
+	if (pBss->Hidden == 0)
+	{
+		NdisMoveMemory(pAd->MlmeAux.Ssid, pBss->Ssid, pBss->SsidLen);
+		pAd->MlmeAux.SsidLen = pBss->SsidLen;
+	}
+
+	pAd->MlmeAux.BssType = pBss->BssType;
+	pAd->MlmeAux.Channel = pBss->Channel;
+	pAd->MlmeAux.CentralChannel = pBss->CentralChannel;
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+	// Country IE of the AP will be evaluated and will be used.
+	if ((pAd->StaCfg.IEEE80211dClientMode != Rt802_11_D_None) &&
+		(pBss->bHasCountryIE == TRUE))
+	{
+		NdisMoveMemory(&pAd->CommonCfg.CountryCode[0], &pBss->CountryString[0], 2);
+		if (pBss->CountryString[2] == 'I')
+			pAd->CommonCfg.Geography = IDOR;
+		else if (pBss->CountryString[2] == 'O')
+			pAd->CommonCfg.Geography = ODOR;
+		else
+			pAd->CommonCfg.Geography = BOTH;
+		BuildChannelListEx(pAd);
+	}
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+	// Let BBP register at 20MHz to do scan
+	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+	BBPValue &= (~0x18);
+	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+	DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
+
+	// switch channel and waiting for beacon timer
+	AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
+	AsicLockChannel(pAd, pAd->MlmeAux.Channel);
+	RTMPSetTimer(&pAd->MlmeAux.BeaconTimer, JOIN_TIMEOUT);
+
+    do
+	{
+		if (((pAd->CommonCfg.bIEEE80211H == 1) &&
+            (pAd->MlmeAux.Channel > 14) &&
+             RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
+#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
+             || (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
+#endif // CARRIER_DETECTION_SUPPORT //
+            )
+		{
+			//
+			// We can't send any Probe request frame to meet 802.11h.
+			//
+			if (pBss->Hidden == 0)
+				break;
+		}
+
+		//
+		// send probe request
+		//
+		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+		if (NStatus == NDIS_STATUS_SUCCESS)
+		{
+			if (pAd->MlmeAux.Channel <= 14)
+			{
+				pSupRate = pAd->CommonCfg.SupRate;
+				SupRateLen = pAd->CommonCfg.SupRateLen;
+				pExtRate = pAd->CommonCfg.ExtRate;
+				ExtRateLen = pAd->CommonCfg.ExtRateLen;
+			}
+			else
+			{
+				//
+				// Overwrite Support Rate, CCK rate are not allowed
+				//
+				pSupRate = ASupRate;
+				SupRateLen = ASupRateLen;
+				ExtRateLen = 0;
+			}
+
+			if (pAd->MlmeAux.BssType == BSS_INFRA)
+				MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, pAd->MlmeAux.Bssid, pAd->MlmeAux.Bssid);
+			else
+				MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
+
+			MakeOutgoingFrame(pOutBuffer,               &FrameLen,
+							  sizeof(HEADER_802_11),    &Hdr80211,
+							  1,                        &SsidIe,
+							  1,                        &pAd->MlmeAux.SsidLen,
+							  pAd->MlmeAux.SsidLen,	    pAd->MlmeAux.Ssid,
+							  1,                        &SupRateIe,
+							  1,                        &SupRateLen,
+							  SupRateLen,               pSupRate,
+							  END_OF_ARGS);
+
+			if (ExtRateLen)
+			{
+				ULONG Tmp;
+				MakeOutgoingFrame(pOutBuffer + FrameLen,            &Tmp,
+								  1,                                &ExtRateIe,
+								  1,                                &ExtRateLen,
+								  ExtRateLen,                       pExtRate,
+								  END_OF_ARGS);
+				FrameLen += Tmp;
+			}
+
+
+			MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+			MlmeFreeMemory(pAd, pOutBuffer);
+		}
+    } while (FALSE);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("SYNC - Switch to ch %d, Wait BEACON from %02x:%02x:%02x:%02x:%02x:%02x\n",
+		pBss->Channel, pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2], pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5]));
+
+	pAd->Mlme.SyncMachine.CurrState = JOIN_WAIT_BEACON;
+}
+
+/*
+	==========================================================================
+	Description:
+		MLME START Request state machine procedure, starting an IBSS
+	==========================================================================
+ */
+VOID MlmeStartReqAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	UCHAR         Ssid[MAX_LEN_OF_SSID], SsidLen;
+	BOOLEAN       TimerCancelled;
+
+	// New for WPA security suites
+	UCHAR						VarIE[MAX_VIE_LEN]; 	// Total VIE length = MAX_VIE_LEN - -5
+	NDIS_802_11_VARIABLE_IEs	*pVIE = NULL;
+	LARGE_INTEGER				TimeStamp;
+	BOOLEAN Privacy;
+	USHORT Status;
+
+	// Init Variable IE structure
+	pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
+	pVIE->Length = 0;
+	TimeStamp.u.LowPart  = 0;
+	TimeStamp.u.HighPart = 0;
+
+	if (MlmeStartReqSanity(pAd, Elem->Msg, Elem->MsgLen, Ssid, &SsidLen))
+	{
+		// reset all the timers
+		RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
+		RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
+
+		//
+		// Start a new IBSS. All IBSS parameters are decided now....
+		//
+		DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqAction - Start a new IBSS. All IBSS parameters are decided now.... \n"));
+		pAd->MlmeAux.BssType           = BSS_ADHOC;
+		NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
+		pAd->MlmeAux.SsidLen           = SsidLen;
+
+		// generate a radom number as BSSID
+		MacAddrRandomBssid(pAd, pAd->MlmeAux.Bssid);
+		DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqAction - generate a radom number as BSSID \n"));
+
+		Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
+				  (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
+				  (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
+		pAd->MlmeAux.CapabilityInfo    = CAP_GENERATE(0,1,Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 1, 0);
+		pAd->MlmeAux.BeaconPeriod      = pAd->CommonCfg.BeaconPeriod;
+		pAd->MlmeAux.AtimWin           = pAd->StaCfg.AtimWin;
+		pAd->MlmeAux.Channel           = pAd->CommonCfg.Channel;
+
+		pAd->CommonCfg.CentralChannel  = pAd->CommonCfg.Channel;
+		pAd->MlmeAux.CentralChannel    = pAd->CommonCfg.CentralChannel;
+
+		pAd->MlmeAux.SupRateLen= pAd->CommonCfg.SupRateLen;
+		NdisMoveMemory(pAd->MlmeAux.SupRate, pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
+		RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
+		pAd->MlmeAux.ExtRateLen = pAd->CommonCfg.ExtRateLen;
+		NdisMoveMemory(pAd->MlmeAux.ExtRate, pAd->CommonCfg.ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
+		RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
+#ifdef DOT11_N_SUPPORT
+		if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+		{
+			RTMPUpdateHTIE(&pAd->CommonCfg.DesiredHtPhy, &pAd->StaCfg.DesiredHtPhyInfo.MCSSet[0], &pAd->MlmeAux.HtCapability, &pAd->MlmeAux.AddHtInfo);
+			pAd->MlmeAux.HtCapabilityLen = sizeof(HT_CAPABILITY_IE);
+			// Not turn pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE here.
+			DBGPRINT(RT_DEBUG_TRACE, ("SYNC -pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE\n"));
+		}
+		else
+#endif // DOT11_N_SUPPORT //
+		{
+			pAd->MlmeAux.HtCapabilityLen = 0;
+			pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
+		}
+		// temporarily not support QOS in IBSS
+		NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));
+		NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));
+		NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));
+
+		AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
+		AsicLockChannel(pAd, pAd->MlmeAux.Channel);
+
+		DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeStartReqAction(ch= %d,sup rates= %d, ext rates=%d)\n",
+			pAd->MlmeAux.Channel, pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen));
+
+		pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+		Status = MLME_SUCCESS;
+		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
+	}
+	else
+	{
+		DBGPRINT_ERR(("SYNC - MlmeStartReqAction() sanity check fail.\n"));
+		pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+		Status = MLME_INVALID_FORMAT;
+		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
+	}
+}
+
+/*
+	==========================================================================
+	Description:
+		peer sends beacon back when scanning
+	==========================================================================
+ */
+VOID PeerBeaconAtScanAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	UCHAR           Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
+	UCHAR           Ssid[MAX_LEN_OF_SSID], BssType, Channel, NewChannel,
+					SsidLen, DtimCount, DtimPeriod, BcastFlag, MessageToMe;
+	CF_PARM         CfParm;
+	USHORT          BeaconPeriod, AtimWin, CapabilityInfo;
+	PFRAME_802_11   pFrame;
+	LARGE_INTEGER   TimeStamp;
+	UCHAR           Erp;
+	UCHAR         	SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+	UCHAR		  	SupRateLen, ExtRateLen;
+	USHORT 			LenVIE;
+	UCHAR			CkipFlag;
+	UCHAR			AironetCellPowerLimit;
+	EDCA_PARM       EdcaParm;
+	QBSS_LOAD_PARM  QbssLoad;
+	QOS_CAPABILITY_PARM QosCapability;
+	ULONG						RalinkIe;
+	UCHAR						VarIE[MAX_VIE_LEN];		// Total VIE length = MAX_VIE_LEN - -5
+	NDIS_802_11_VARIABLE_IEs	*pVIE = NULL;
+	HT_CAPABILITY_IE		HtCapability;
+	ADD_HT_INFO_IE		AddHtInfo;	// AP might use this additional ht info IE
+	UCHAR			HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
+	UCHAR			AddHtInfoLen;
+	UCHAR			NewExtChannelOffset = 0xff;
+
+
+	// NdisFillMemory(Ssid, MAX_LEN_OF_SSID, 0x00);
+	pFrame = (PFRAME_802_11) Elem->Msg;
+	// Init Variable IE structure
+	pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
+	pVIE->Length = 0;
+#ifdef DOT11_N_SUPPORT
+    RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
+	RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
+#endif // DOT11_N_SUPPORT //
+
+	if (PeerBeaconAndProbeRspSanity(pAd,
+								Elem->Msg,
+								Elem->MsgLen,
+								Elem->Channel,
+								Addr2,
+								Bssid,
+								Ssid,
+								&SsidLen,
+								&BssType,
+								&BeaconPeriod,
+								&Channel,
+								&NewChannel,
+								&TimeStamp,
+								&CfParm,
+								&AtimWin,
+								&CapabilityInfo,
+								&Erp,
+								&DtimCount,
+								&DtimPeriod,
+								&BcastFlag,
+								&MessageToMe,
+								SupRate,
+								&SupRateLen,
+								ExtRate,
+								&ExtRateLen,
+								&CkipFlag,
+								&AironetCellPowerLimit,
+								&EdcaParm,
+								&QbssLoad,
+								&QosCapability,
+								&RalinkIe,
+								&HtCapabilityLen,
+								&PreNHtCapabilityLen,
+								&HtCapability,
+								&AddHtInfoLen,
+								&AddHtInfo,
+								&NewExtChannelOffset,
+								&LenVIE,
+								pVIE))
+	{
+		ULONG Idx;
+		CHAR Rssi = 0;
+
+		Idx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
+		if (Idx != BSS_NOT_FOUND)
+			Rssi = pAd->ScanTab.BssEntry[Idx].Rssi;
+
+		Rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
+
+
+#ifdef DOT11_N_SUPPORT
+		if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
+			HtCapabilityLen = SIZE_HT_CAP_IE;
+#endif // DOT11_N_SUPPORT //
+		if ((pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED) && (Channel == pAd->StaCfg.CCXScanChannel))
+		{
+			Idx = BssTableSetEntry(pAd, &pAd->StaCfg.CCXBssTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
+						 &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen,ExtRate, ExtRateLen, &HtCapability,
+						 &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag,
+						 &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
+			if (Idx != BSS_NOT_FOUND)
+			{
+				NdisMoveMemory(pAd->StaCfg.CCXBssTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4);
+				NdisMoveMemory(&pAd->StaCfg.CCXBssTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
+				NdisMoveMemory(&pAd->StaCfg.CCXBssTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
+				if (pAd->StaCfg.CCXReqType == MSRN_TYPE_BEACON_REQ)
+					AironetAddBeaconReport(pAd, Idx, Elem);
+			}
+		}
+		else
+		{
+			Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
+						  &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,  &HtCapability,
+						 &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag,
+						 &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+			if (pAd->ChannelList[pAd->CommonCfg.ChannelListIdx].bEffectedChannel == TRUE)
+			{
+				UCHAR		RegClass;
+				PeerBeaconAndProbeRspSanity2(pAd, Elem->Msg, Elem->MsgLen, &RegClass);
+				TriEventTableSetEntry(pAd, &pAd->CommonCfg.TriggerEventTab, Bssid, &HtCapability, HtCapabilityLen, RegClass, Channel);
+			}
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+			if (Idx != BSS_NOT_FOUND)
+			{
+				NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4);
+				NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
+				NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
+			}
+		}
+	}
+	// sanity check fail, ignored
+}
+
+/*
+	==========================================================================
+	Description:
+		When waiting joining the (I)BSS, beacon received from external
+	==========================================================================
+ */
+VOID PeerBeaconAtJoinAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	UCHAR         Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
+	UCHAR         Ssid[MAX_LEN_OF_SSID], SsidLen, BssType, Channel, MessageToMe,
+				  DtimCount, DtimPeriod, BcastFlag, NewChannel;
+	LARGE_INTEGER TimeStamp;
+	USHORT        BeaconPeriod, AtimWin, CapabilityInfo;
+	CF_PARM       Cf;
+	BOOLEAN       TimerCancelled;
+	UCHAR         Erp;
+	UCHAR         SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+	UCHAR		  SupRateLen, ExtRateLen;
+	UCHAR         CkipFlag;
+	USHORT 		  LenVIE;
+	UCHAR		  AironetCellPowerLimit;
+	EDCA_PARM       EdcaParm;
+	QBSS_LOAD_PARM  QbssLoad;
+	QOS_CAPABILITY_PARM QosCapability;
+	USHORT        Status;
+	UCHAR						VarIE[MAX_VIE_LEN];		// Total VIE length = MAX_VIE_LEN - -5
+	NDIS_802_11_VARIABLE_IEs	*pVIE = NULL;
+	ULONG           RalinkIe;
+	ULONG         Idx;
+	HT_CAPABILITY_IE		HtCapability;
+	ADD_HT_INFO_IE		AddHtInfo;	// AP might use this additional ht info IE
+	UCHAR				HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
+	UCHAR			AddHtInfoLen;
+	UCHAR			NewExtChannelOffset = 0xff;
+#ifdef DOT11_N_SUPPORT
+	UCHAR			CentralChannel;
+#endif // DOT11_N_SUPPORT //
+
+	// Init Variable IE structure
+	pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
+	pVIE->Length = 0;
+    RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
+	RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
+
+
+	if (PeerBeaconAndProbeRspSanity(pAd,
+								Elem->Msg,
+								Elem->MsgLen,
+								Elem->Channel,
+								Addr2,
+								Bssid,
+								Ssid,
+								&SsidLen,
+								&BssType,
+								&BeaconPeriod,
+								&Channel,
+								&NewChannel,
+								&TimeStamp,
+								&Cf,
+								&AtimWin,
+								&CapabilityInfo,
+								&Erp,
+								&DtimCount,
+								&DtimPeriod,
+								&BcastFlag,
+								&MessageToMe,
+								SupRate,
+								&SupRateLen,
+								ExtRate,
+								&ExtRateLen,
+								&CkipFlag,
+								&AironetCellPowerLimit,
+								&EdcaParm,
+								&QbssLoad,
+								&QosCapability,
+								&RalinkIe,
+								&HtCapabilityLen,
+								&PreNHtCapabilityLen,
+								&HtCapability,
+								&AddHtInfoLen,
+								&AddHtInfo,
+								&NewExtChannelOffset,
+								&LenVIE,
+								pVIE))
+	{
+		// Disqualify 11b only adhoc when we are in 11g only adhoc mode
+		if ((BssType == BSS_ADHOC) && (pAd->CommonCfg.PhyMode == PHY_11G) && ((SupRateLen+ExtRateLen)< 12))
+			return;
+
+		// BEACON from desired BSS/IBSS found. We should be able to decide most
+		// BSS parameters here.
+		// Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION?
+		//    Do we need to receover back all parameters belonging to previous BSS?
+		// A. Should be not. There's no back-door recover to previous AP. It still need
+		//    a new JOIN-AUTH-ASSOC sequence.
+		if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Bssid))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("SYNC - receive desired BEACON at JoinWaitBeacon... Channel = %d\n", Channel));
+			RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
+
+			// Update RSSI to prevent No signal display when cards first initialized
+			pAd->StaCfg.RssiSample.LastRssi0	= ConvertToRssi(pAd, Elem->Rssi0, RSSI_0);
+			pAd->StaCfg.RssiSample.LastRssi1	= ConvertToRssi(pAd, Elem->Rssi1, RSSI_1);
+			pAd->StaCfg.RssiSample.LastRssi2	= ConvertToRssi(pAd, Elem->Rssi2, RSSI_2);
+			pAd->StaCfg.RssiSample.AvgRssi0	= pAd->StaCfg.RssiSample.LastRssi0;
+			pAd->StaCfg.RssiSample.AvgRssi0X8	= pAd->StaCfg.RssiSample.AvgRssi0 << 3;
+			pAd->StaCfg.RssiSample.AvgRssi1	= pAd->StaCfg.RssiSample.LastRssi1;
+			pAd->StaCfg.RssiSample.AvgRssi1X8	= pAd->StaCfg.RssiSample.AvgRssi1 << 3;
+			pAd->StaCfg.RssiSample.AvgRssi2	= pAd->StaCfg.RssiSample.LastRssi2;
+			pAd->StaCfg.RssiSample.AvgRssi2X8	= pAd->StaCfg.RssiSample.AvgRssi2 << 3;
+
+			//
+			// We need to check if SSID only set to any, then we can record the current SSID.
+			// Otherwise will cause hidden SSID association failed.
+			//
+			if (pAd->MlmeAux.SsidLen == 0)
+			{
+				NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
+				pAd->MlmeAux.SsidLen = SsidLen;
+			}
+			else
+			{
+				Idx = BssSsidTableSearch(&pAd->ScanTab, Bssid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Channel);
+
+				if (Idx != BSS_NOT_FOUND)
+				{
+					//
+					// Multiple SSID case, used correct CapabilityInfo
+					//
+					CapabilityInfo = pAd->ScanTab.BssEntry[Idx].CapabilityInfo;
+				}
+			}
+			NdisMoveMemory(pAd->MlmeAux.Bssid, Bssid, MAC_ADDR_LEN);
+			pAd->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
+			pAd->MlmeAux.BssType = BssType;
+			pAd->MlmeAux.BeaconPeriod = BeaconPeriod;
+			pAd->MlmeAux.Channel = Channel;
+			pAd->MlmeAux.AtimWin = AtimWin;
+			pAd->MlmeAux.CfpPeriod = Cf.CfpPeriod;
+			pAd->MlmeAux.CfpMaxDuration = Cf.CfpMaxDuration;
+			pAd->MlmeAux.APRalinkIe = RalinkIe;
+
+			// Copy AP's supported rate to MlmeAux for creating assoication request
+			// Also filter out not supported rate
+			pAd->MlmeAux.SupRateLen = SupRateLen;
+			NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen);
+			RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
+			pAd->MlmeAux.ExtRateLen = ExtRateLen;
+			NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen);
+			RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
+
+            NdisZeroMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, 16);
+#ifdef DOT11_N_SUPPORT
+			pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
+			pAd->MlmeAux.HtCapabilityLen = HtCapabilityLen;
+
+			// filter out un-supported ht rates
+			if (((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+			{
+				RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
+   				RTMPMoveMemory(&pAd->MlmeAux.AddHtInfo, &AddHtInfo, SIZE_ADD_HT_INFO_IE);
+
+				// StaActive.SupportedHtPhy.MCSSet stores Peer AP's 11n Rx capability
+				NdisMoveMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, HtCapability.MCSSet, 16);
+				pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
+				pAd->MlmeAux.HtCapabilityLen = SIZE_HT_CAP_IE;
+				pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
+				if (PreNHtCapabilityLen > 0)
+					pAd->StaActive.SupportedPhyInfo.bPreNHt = TRUE;
+				RTMPCheckHt(pAd, BSSID_WCID, &HtCapability, &AddHtInfo);
+				// Copy AP Parameter to StaActive.  This is also in LinkUp.
+				DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction! (MpduDensity=%d, MaxRAmpduFactor=%d, BW=%d)\n",
+					pAd->StaActive.SupportedHtPhy.MpduDensity, pAd->StaActive.SupportedHtPhy.MaxRAmpduFactor, HtCapability.HtCapInfo.ChannelWidth));
+
+				if (AddHtInfoLen > 0)
+				{
+					CentralChannel = AddHtInfo.ControlChan;
+		 			// Check again the Bandwidth capability of this AP.
+		 			if ((AddHtInfo.ControlChan > 2)&& (AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (HtCapability.HtCapInfo.ChannelWidth == BW_40))
+		 			{
+		 				CentralChannel = AddHtInfo.ControlChan - 2;
+		 			}
+		 			else if ((AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (HtCapability.HtCapInfo.ChannelWidth == BW_40))
+		 			{
+		 				CentralChannel = AddHtInfo.ControlChan + 2;
+		 			}
+
+					// Check Error .
+					if (pAd->MlmeAux.CentralChannel != CentralChannel)
+		 				DBGPRINT(RT_DEBUG_ERROR, ("PeerBeaconAtJoinAction HT===>Beacon Central Channel = %d, Control Channel = %d. Mlmeaux CentralChannel = %d\n", CentralChannel, AddHtInfo.ControlChan, pAd->MlmeAux.CentralChannel));
+
+		 			DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d,  .\n", CentralChannel, AddHtInfo.ControlChan));
+
+				}
+
+			}
+			else
+#endif // DOT11_N_SUPPORT //
+			{
+   				// To prevent error, let legacy AP must have same CentralChannel and Channel.
+				if ((HtCapabilityLen == 0) && (PreNHtCapabilityLen == 0))
+					pAd->MlmeAux.CentralChannel = pAd->MlmeAux.Channel;
+
+				pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
+				RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
+				RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE);
+			}
+
+			RTMPUpdateMlmeRate(pAd);
+
+			// copy QOS related information
+			if ((pAd->CommonCfg.bWmmCapable)
+#ifdef DOT11_N_SUPPORT
+				 || (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+#endif // DOT11_N_SUPPORT //
+				)
+			{
+				NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, &EdcaParm, sizeof(EDCA_PARM));
+				NdisMoveMemory(&pAd->MlmeAux.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM));
+				NdisMoveMemory(&pAd->MlmeAux.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM));
+			}
+			else
+			{
+				NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));
+				NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));
+				NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));
+			}
+
+			DBGPRINT(RT_DEBUG_TRACE, ("SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n",
+										pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen));
+
+#ifdef LEAP_SUPPORT
+			// Update CkipFlag
+			pAd->StaCfg.CkipFlag = CkipFlag;
+
+			// Keep TimeStamp for Re-Association used.
+			if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
+				pAd->StaCfg.CCKMBeaconAtJoinTimeStamp = TimeStamp;
+#endif // LEAP_SUPPORT //
+
+			if (AironetCellPowerLimit != 0xFF)
+			{
+				//We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power
+				ChangeToCellPowerLimit(pAd, AironetCellPowerLimit);
+			}
+			else  //Used the default TX Power Percentage.
+				pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
+
+			pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+			Status = MLME_SUCCESS;
+			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
+		}
+		// not to me BEACON, ignored
+	}
+	// sanity check fail, ignore this frame
+}
+
+/*
+	==========================================================================
+	Description:
+		receive BEACON from peer
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID PeerBeacon(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	UCHAR         Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
+	CHAR          Ssid[MAX_LEN_OF_SSID];
+	CF_PARM       CfParm;
+	UCHAR         SsidLen, MessageToMe=0, BssType, Channel, NewChannel, index=0;
+	UCHAR         DtimCount=0, DtimPeriod=0, BcastFlag=0;
+	USHORT        CapabilityInfo, AtimWin, BeaconPeriod;
+	LARGE_INTEGER TimeStamp;
+	USHORT        TbttNumToNextWakeUp;
+	UCHAR         Erp;
+	UCHAR         SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+	UCHAR		  SupRateLen, ExtRateLen;
+	UCHAR		  CkipFlag;
+	USHORT        LenVIE;
+	UCHAR		  AironetCellPowerLimit;
+	EDCA_PARM       EdcaParm;
+	QBSS_LOAD_PARM  QbssLoad;
+	QOS_CAPABILITY_PARM QosCapability;
+	ULONG           RalinkIe;
+	// New for WPA security suites
+	UCHAR						VarIE[MAX_VIE_LEN];		// Total VIE length = MAX_VIE_LEN - -5
+	NDIS_802_11_VARIABLE_IEs	*pVIE = NULL;
+	HT_CAPABILITY_IE		HtCapability;
+	ADD_HT_INFO_IE		AddHtInfo;	// AP might use this additional ht info IE
+	UCHAR			HtCapabilityLen, PreNHtCapabilityLen;
+	UCHAR			AddHtInfoLen;
+	UCHAR			NewExtChannelOffset = 0xff;
+
+
+#ifdef RALINK_ATE
+    if (ATE_ON(pAd))
+    {
+		return;
+    }
+#endif // RALINK_ATE //
+
+	if (!(INFRA_ON(pAd) || ADHOC_ON(pAd)
+		))
+		return;
+
+	// Init Variable IE structure
+	pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
+	pVIE->Length = 0;
+    RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
+	RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
+
+	if (PeerBeaconAndProbeRspSanity(pAd,
+								Elem->Msg,
+								Elem->MsgLen,
+								Elem->Channel,
+								Addr2,
+								Bssid,
+								Ssid,
+								&SsidLen,
+								&BssType,
+								&BeaconPeriod,
+								&Channel,
+								&NewChannel,
+								&TimeStamp,
+								&CfParm,
+								&AtimWin,
+								&CapabilityInfo,
+								&Erp,
+								&DtimCount,
+								&DtimPeriod,
+								&BcastFlag,
+								&MessageToMe,
+								SupRate,
+								&SupRateLen,
+								ExtRate,
+								&ExtRateLen,
+								&CkipFlag,
+								&AironetCellPowerLimit,
+								&EdcaParm,
+								&QbssLoad,
+								&QosCapability,
+								&RalinkIe,
+								&HtCapabilityLen,
+								&PreNHtCapabilityLen,
+								&HtCapability,
+								&AddHtInfoLen,
+								&AddHtInfo,
+								&NewExtChannelOffset,
+								&LenVIE,
+								pVIE))
+	{
+		BOOLEAN is_my_bssid, is_my_ssid;
+		ULONG   Bssidx, Now;
+		BSS_ENTRY *pBss;
+		CHAR		RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
+
+		is_my_bssid = MAC_ADDR_EQUAL(Bssid, pAd->CommonCfg.Bssid)? TRUE : FALSE;
+		is_my_ssid = SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen)? TRUE:FALSE;
+
+
+		// ignore BEACON not for my SSID
+		if ((! is_my_ssid) && (! is_my_bssid))
+			return;
+
+		// It means STA waits disassoc completely from this AP, ignores this beacon.
+		if (pAd->Mlme.CntlMachine.CurrState == CNTL_WAIT_DISASSOC)
+			return;
+
+#ifdef DOT11_N_SUPPORT
+		// Copy Control channel for this BSSID.
+		if (AddHtInfoLen != 0)
+			Channel = AddHtInfo.ControlChan;
+
+		if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
+			HtCapabilityLen = SIZE_HT_CAP_IE;
+#endif // DOT11_N_SUPPORT //
+
+		//
+		// Housekeeping "SsidBssTab" table for later-on ROAMing usage.
+		//
+		Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
+		if (Bssidx == BSS_NOT_FOUND)
+		{
+			// discover new AP of this network, create BSS entry
+			Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
+						 &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,
+						&HtCapability, &AddHtInfo,HtCapabilityLen,AddHtInfoLen,NewExtChannelOffset, Channel,
+						RealRssi, TimeStamp, CkipFlag, &EdcaParm, &QosCapability,
+						&QbssLoad, LenVIE, pVIE);
+			if (Bssidx == BSS_NOT_FOUND) // return if BSS table full
+				return;
+
+			NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF, &Elem->Msg[24], 4);
+			NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
+			NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
+
+
+
+		}
+
+		if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) && (Channel != NewChannel))
+		{
+			// Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection).
+			// In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results.
+			AsicSwitchChannel(pAd, 1, FALSE);
+			AsicLockChannel(pAd, 1);
+		    LinkDown(pAd, FALSE);
+			MlmeQueueInit(&pAd->Mlme.Queue);
+			BssTableInit(&pAd->ScanTab);
+		    RTMPusecDelay(1000000);		// use delay to prevent STA do reassoc
+
+			// channel sanity check
+			for (index = 0 ; index < pAd->ChannelListNum; index++)
+			{
+				if (pAd->ChannelList[index].Channel == NewChannel)
+				{
+					pAd->ScanTab.BssEntry[Bssidx].Channel = NewChannel;
+					pAd->CommonCfg.Channel = NewChannel;
+					AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+					AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+					DBGPRINT(RT_DEBUG_TRACE, ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel));
+					break;
+				}
+			}
+
+			if (index >= pAd->ChannelListNum)
+			{
+				DBGPRINT_ERR(("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum));
+			}
+		}
+
+		// if the ssid matched & bssid unmatched, we should select the bssid with large value.
+		// This might happened when two STA start at the same time
+		if ((! is_my_bssid) && ADHOC_ON(pAd))
+		{
+			INT	i;
+
+			// Add the safeguard against the mismatch of adhoc wep status
+			if (pAd->StaCfg.WepStatus != pAd->ScanTab.BssEntry[Bssidx].WepStatus)
+			{
+				DBGPRINT(RT_DEBUG_TRACE, ("SYNC - Not matched wep status %d %d\n", pAd->StaCfg.WepStatus, pAd->ScanTab.BssEntry[Bssidx].WepStatus));
+				DBGPRINT(RT_DEBUG_TRACE, ("bssid=%s\n", pAd->ScanTab.BssEntry[Bssidx].Bssid));
+				return;
+			}
+
+			// collapse into the ADHOC network which has bigger BSSID value.
+			for (i = 0; i < 6; i++)
+			{
+				if (Bssid[i] > pAd->CommonCfg.Bssid[i])
+				{
+					DBGPRINT(RT_DEBUG_TRACE, ("SYNC - merge to the IBSS with bigger BSSID=%02x:%02x:%02x:%02x:%02x:%02x\n",
+						Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
+					AsicDisableSync(pAd);
+					COPY_MAC_ADDR(pAd->CommonCfg.Bssid, Bssid);
+					AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
+					MakeIbssBeacon(pAd);        // re-build BEACON frame
+					AsicEnableIbssSync(pAd);    // copy BEACON frame to on-chip memory
+					is_my_bssid = TRUE;
+					break;
+				}
+				else if (Bssid[i] < pAd->CommonCfg.Bssid[i])
+					break;
+			}
+		}
+
+
+		NdisGetSystemUpTime(&Now);
+		pBss = &pAd->ScanTab.BssEntry[Bssidx];
+		pBss->Rssi = RealRssi;       // lastest RSSI
+		pBss->LastBeaconRxTime = Now;   // last RX timestamp
+
+		//
+		// BEACON from my BSSID - either IBSS or INFRA network
+		//
+		if (is_my_bssid)
+		{
+			RXWI_STRUC	RxWI;
+
+			pAd->StaCfg.DtimCount = DtimCount;
+			pAd->StaCfg.DtimPeriod = DtimPeriod;
+			pAd->StaCfg.LastBeaconRxTime = Now;
+
+
+			RxWI.RSSI0 = Elem->Rssi0;
+			RxWI.RSSI1 = Elem->Rssi1;
+			RxWI.RSSI2 = Elem->Rssi2;
+
+			Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, &RxWI);
+			if (AironetCellPowerLimit != 0xFF)
+			{
+				//
+				// We get the Cisco (ccx) "TxPower Limit" required
+				// Changed to appropriate TxPower Limit for Ciso Compatible Extensions
+				//
+				ChangeToCellPowerLimit(pAd, AironetCellPowerLimit);
+			}
+			else
+			{
+				//
+				// AironetCellPowerLimit equal to 0xFF means the Cisco (ccx) "TxPower Limit" not exist.
+				// Used the default TX Power Percentage, that set from UI.
+				//
+				pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
+			}
+
+			if (ADHOC_ON(pAd) && (CAP_IS_IBSS_ON(CapabilityInfo)))
+			{
+				UCHAR			MaxSupportedRateIn500Kbps = 0;
+				UCHAR			idx;
+				MAC_TABLE_ENTRY *pEntry;
+
+				// supported rates array may not be sorted. sort it and find the maximum rate
+			    for (idx=0; idx<SupRateLen; idx++)
+						{
+			        if (MaxSupportedRateIn500Kbps < (SupRate[idx] & 0x7f))
+			            MaxSupportedRateIn500Kbps = SupRate[idx] & 0x7f;
+						}
+
+				for (idx=0; idx<ExtRateLen; idx++)
+			    {
+			        if (MaxSupportedRateIn500Kbps < (ExtRate[idx] & 0x7f))
+			            MaxSupportedRateIn500Kbps = ExtRate[idx] & 0x7f;
+					}
+
+				// look up the existing table
+				pEntry = MacTableLookup(pAd, Addr2);
+
+				// Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon.
+				// To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station.
+				if ((ADHOC_ON(pAd) && (Elem->Wcid == RESERVED_WCID)) ||
+					(pEntry && ((pEntry->LastBeaconRxTime + ADHOC_ENTRY_BEACON_LOST_TIME) < Now)))
+						{
+					if (pEntry == NULL)
+						// Another adhoc joining, add to our MAC table.
+						pEntry = MacTableInsertEntry(pAd, Addr2, BSS0, FALSE);
+
+					if (StaAddMacTableEntry(pAd, pEntry, MaxSupportedRateIn500Kbps, &HtCapability, HtCapabilityLen, CapabilityInfo) == FALSE)
+					{
+						DBGPRINT(RT_DEBUG_TRACE, ("ADHOC - Add Entry failed.\n"));
+						return;
+					}
+
+					if (pEntry &&
+						(Elem->Wcid == RESERVED_WCID))
+				{
+						idx = pAd->StaCfg.DefaultKeyId;
+						RT28XX_STA_SECURITY_INFO_ADD(pAd, BSS0, idx, pEntry);
+				}
+				}
+
+				if (pEntry && pEntry->ValidAsCLI)
+					pEntry->LastBeaconRxTime = Now;
+
+				// At least another peer in this IBSS, declare MediaState as CONNECTED
+				if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+				{
+					OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
+
+					pAd->IndicateMediaState = NdisMediaStateConnected;
+					RTMP_IndicateMediaState(pAd);
+	                pAd->ExtraInfo = GENERAL_LINK_UP;
+					AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
+
+					// 2003/03/12 - john
+					// Make sure this entry in "ScanTab" table, thus complies to Microsoft's policy that
+					// "site survey" result should always include the current connected network.
+					//
+					Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
+					if (Bssidx == BSS_NOT_FOUND)
+					{
+						Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
+									&CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability,
+									&AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, RealRssi, TimeStamp, 0,
+									&EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
+					}
+					DBGPRINT(RT_DEBUG_TRACE, ("ADHOC  fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
+				}
+			}
+
+			if (INFRA_ON(pAd))
+			{
+				BOOLEAN bUseShortSlot, bUseBGProtection;
+
+				// decide to use/change to -
+				//      1. long slot (20 us) or short slot (9 us) time
+				//      2. turn on/off RTS/CTS and/or CTS-to-self protection
+				//      3. short preamble
+
+				//bUseShortSlot = pAd->CommonCfg.bUseShortSlotTime && CAP_IS_SHORT_SLOT(CapabilityInfo);
+				bUseShortSlot = CAP_IS_SHORT_SLOT(CapabilityInfo);
+				if (bUseShortSlot != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))
+					AsicSetSlotTime(pAd, bUseShortSlot);
+
+				bUseBGProtection = (pAd->CommonCfg.UseBGProtection == 1) ||    // always use
+								   ((pAd->CommonCfg.UseBGProtection == 0) && ERP_IS_USE_PROTECTION(Erp));
+
+				if (pAd->CommonCfg.Channel > 14) // always no BG protection in A-band. falsely happened when switching A/G band to a dual-band AP
+					bUseBGProtection = FALSE;
+
+				if (bUseBGProtection != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
+				{
+					if (bUseBGProtection)
+					{
+						OPSTATUS_SET_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
+						AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),FALSE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1));
+					}
+					else
+					{
+						OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
+						AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),TRUE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1));
+					}
+
+					DBGPRINT(RT_DEBUG_WARN, ("SYNC - AP changed B/G protection to %d\n", bUseBGProtection));
+				}
+
+#ifdef DOT11_N_SUPPORT
+				// check Ht protection mode. and adhere to the Non-GF device indication by AP.
+				if ((AddHtInfoLen != 0) &&
+					((AddHtInfo.AddHtInfo2.OperaionMode != pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode) ||
+					(AddHtInfo.AddHtInfo2.NonGfPresent != pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent)))
+				{
+					pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent = AddHtInfo.AddHtInfo2.NonGfPresent;
+					pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode = AddHtInfo.AddHtInfo2.OperaionMode;
+					if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
+				{
+						AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
+					}
+					else
+						AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
+
+					DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP changed N OperaionMode to %d\n", pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode));
+				}
+#endif // DOT11_N_SUPPORT //
+
+				if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED) &&
+					ERP_IS_USE_BARKER_PREAMBLE(Erp))
+				{
+					MlmeSetTxPreamble(pAd, Rt802_11PreambleLong);
+					DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP forced to use LONG preamble\n"));
+				}
+
+				if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)    &&
+					(EdcaParm.bValid == TRUE)                          &&
+					(EdcaParm.EdcaUpdateCount != pAd->CommonCfg.APEdcaParm.EdcaUpdateCount))
+				{
+					DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP change EDCA parameters(from %d to %d)\n",
+						pAd->CommonCfg.APEdcaParm.EdcaUpdateCount,
+						EdcaParm.EdcaUpdateCount));
+					AsicSetEdcaParm(pAd, &EdcaParm);
+				}
+
+				// copy QOS related information
+				NdisMoveMemory(&pAd->CommonCfg.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM));
+				NdisMoveMemory(&pAd->CommonCfg.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM));
+			}
+
+			// only INFRASTRUCTURE mode support power-saving feature
+			if ((INFRA_ON(pAd) && (pAd->StaCfg.Psm == PWR_SAVE)) || (pAd->CommonCfg.bAPSDForcePowerSave))
+			{
+				UCHAR FreeNumber;
+				//  1. AP has backlogged unicast-to-me frame, stay AWAKE, send PSPOLL
+				//  2. AP has backlogged broadcast/multicast frame and we want those frames, stay AWAKE
+				//  3. we have outgoing frames in TxRing or MgmtRing, better stay AWAKE
+				//  4. Psm change to PWR_SAVE, but AP not been informed yet, we better stay AWAKE
+				//  5. otherwise, put PHY back to sleep to save battery.
+				if (MessageToMe)
+				{
+					if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable &&
+						pAd->CommonCfg.bAPSDAC_BE && pAd->CommonCfg.bAPSDAC_BK && pAd->CommonCfg.bAPSDAC_VI && pAd->CommonCfg.bAPSDAC_VO)
+					{
+						pAd->CommonCfg.bNeedSendTriggerFrame = TRUE;
+					}
+					else
+						RT28XX_PS_POLL_ENQUEUE(pAd);
+				}
+				else if (BcastFlag && (DtimCount == 0) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM))
+				{
+				}
+				else if ((pAd->TxSwQueue[QID_AC_BK].Number != 0)													||
+						(pAd->TxSwQueue[QID_AC_BE].Number != 0)														||
+						(pAd->TxSwQueue[QID_AC_VI].Number != 0)														||
+						(pAd->TxSwQueue[QID_AC_VO].Number != 0)														||
+						(RTMPFreeTXDRequest(pAd, QID_AC_BK, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS)	||
+						(RTMPFreeTXDRequest(pAd, QID_AC_BE, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS)	||
+						(RTMPFreeTXDRequest(pAd, QID_AC_VI, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS)	||
+						(RTMPFreeTXDRequest(pAd, QID_AC_VO, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS)	||
+						(RTMPFreeTXDRequest(pAd, QID_MGMT, MGMT_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS))
+				{
+					// TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme
+					// can we cheat here (i.e. just check MGMT & AC_BE) for better performance?
+				}
+				else
+				{
+					USHORT NextDtim = DtimCount;
+
+					if (NextDtim == 0)
+						NextDtim = DtimPeriod;
+
+					TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount;
+					if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))
+						TbttNumToNextWakeUp = NextDtim;
+
+					if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+					{
+						AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
+					}
+				}
+			}
+		}
+		// not my BSSID, ignore it
+	}
+	// sanity check fail, ignore this frame
+}
+
+/*
+	==========================================================================
+	Description:
+		Receive PROBE REQ from remote peer when operating in IBSS mode
+	==========================================================================
+ */
+VOID PeerProbeReqAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	UCHAR         Addr2[MAC_ADDR_LEN];
+	CHAR          Ssid[MAX_LEN_OF_SSID];
+	UCHAR         SsidLen;
+#ifdef DOT11_N_SUPPORT
+	UCHAR		  HtLen, AddHtLen, NewExtLen;
+#endif // DOT11_N_SUPPORT //
+	HEADER_802_11 ProbeRspHdr;
+	NDIS_STATUS   NStatus;
+	PUCHAR        pOutBuffer = NULL;
+	ULONG         FrameLen = 0;
+	LARGE_INTEGER FakeTimestamp;
+	UCHAR         DsLen = 1, IbssLen = 2;
+	UCHAR         LocalErpIe[3] = {IE_ERP, 1, 0};
+	BOOLEAN       Privacy;
+	USHORT        CapabilityInfo;
+	UCHAR		  RSNIe = IE_WPA;
+
+	if (! ADHOC_ON(pAd))
+		return;
+
+	if (PeerProbeReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen))
+	{
+		if ((SsidLen == 0) || SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen))
+		{
+			// allocate and send out ProbeRsp frame
+			NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
+			if (NStatus != NDIS_STATUS_SUCCESS)
+				return;
+
+			//pAd->StaCfg.AtimWin = 0;  // ??????
+
+			Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
+					  (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
+					  (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
+			CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
+
+			MakeOutgoingFrame(pOutBuffer,                   &FrameLen,
+							  sizeof(HEADER_802_11),        &ProbeRspHdr,
+							  TIMESTAMP_LEN,                &FakeTimestamp,
+							  2,                            &pAd->CommonCfg.BeaconPeriod,
+							  2,                            &CapabilityInfo,
+							  1,                            &SsidIe,
+							  1,                            &pAd->CommonCfg.SsidLen,
+							  pAd->CommonCfg.SsidLen,       pAd->CommonCfg.Ssid,
+							  1,                            &SupRateIe,
+							  1,                            &pAd->StaActive.SupRateLen,
+							  pAd->StaActive.SupRateLen,    pAd->StaActive.SupRate,
+							  1,                            &DsIe,
+							  1,                            &DsLen,
+							  1,                            &pAd->CommonCfg.Channel,
+							  1,                            &IbssIe,
+							  1,                            &IbssLen,
+							  2,                            &pAd->StaActive.AtimWin,
+							  END_OF_ARGS);
+
+			if (pAd->StaActive.ExtRateLen)
+			{
+				ULONG tmp;
+				MakeOutgoingFrame(pOutBuffer + FrameLen,        &tmp,
+								  3,                            LocalErpIe,
+								  1,                            &ExtRateIe,
+								  1,                            &pAd->StaActive.ExtRateLen,
+								  pAd->StaActive.ExtRateLen,    &pAd->StaActive.ExtRate,
+								  END_OF_ARGS);
+				FrameLen += tmp;
+			}
+
+			// If adhoc secruity is set for WPA-None, append the cipher suite IE
+			if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+			{
+				ULONG tmp;
+				MakeOutgoingFrame(pOutBuffer + FrameLen,        	&tmp,
+						  			1,                              &RSNIe,
+						  			1,                            	&pAd->StaCfg.RSNIE_Len,
+						  			pAd->StaCfg.RSNIE_Len,      	pAd->StaCfg.RSN_IE,
+						  			END_OF_ARGS);
+				FrameLen += tmp;
+			}
+#ifdef DOT11_N_SUPPORT
+			if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+			{
+				ULONG TmpLen;
+				UCHAR	BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
+				HtLen = sizeof(pAd->CommonCfg.HtCapability);
+				AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo);
+				NewExtLen = 1;
+				//New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame
+				if (pAd->bBroadComHT == TRUE)
+				{
+					MakeOutgoingFrame(pOutBuffer + FrameLen,            &TmpLen,
+								  1,                                &WpaIe,
+								  4,                                &BROADCOM[0],
+								 pAd->MlmeAux.HtCapabilityLen,          &pAd->MlmeAux.HtCapability,
+								  END_OF_ARGS);
+				}
+				else
+				{
+				MakeOutgoingFrame(pOutBuffer + FrameLen,            &TmpLen,
+								  1,                                &HtCapIe,
+								  1,                                &HtLen,
+								 sizeof(HT_CAPABILITY_IE),          &pAd->CommonCfg.HtCapability,
+								  1,                                &AddHtInfoIe,
+								  1,                                &AddHtLen,
+								 sizeof(ADD_HT_INFO_IE),          &pAd->CommonCfg.AddHTInfo,
+								  1,                                &NewExtChanIe,
+								  1,                                &NewExtLen,
+								 sizeof(NEW_EXT_CHAN_IE),          &pAd->CommonCfg.NewExtChanOffset,
+								  END_OF_ARGS);
+				}
+				FrameLen += TmpLen;
+			}
+#endif // DOT11_N_SUPPORT //
+			MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+			MlmeFreeMemory(pAd, pOutBuffer);
+		}
+	}
+}
+
+VOID BeaconTimeoutAtJoinAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	USHORT Status;
+	DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BeaconTimeoutAtJoinAction\n"));
+	pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+	Status = MLME_REJ_TIMEOUT;
+	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
+}
+
+/*
+	==========================================================================
+	Description:
+		Scan timeout procedure. basically add channel index by 1 and rescan
+	==========================================================================
+ */
+VOID ScanTimeoutAction(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	pAd->MlmeAux.Channel = NextChannel(pAd, pAd->MlmeAux.Channel);
+
+	// Only one channel scanned for CISCO beacon request
+	if ((pAd->MlmeAux.ScanType == SCAN_CISCO_ACTIVE) ||
+		(pAd->MlmeAux.ScanType == SCAN_CISCO_PASSIVE) ||
+		(pAd->MlmeAux.ScanType == SCAN_CISCO_NOISE) ||
+		(pAd->MlmeAux.ScanType == SCAN_CISCO_CHANNEL_LOAD))
+		pAd->MlmeAux.Channel = 0;
+
+	// this routine will stop if pAd->MlmeAux.Channel == 0
+	ScanNextChannel(pAd);
+}
+
+/*
+	==========================================================================
+	Description:
+	==========================================================================
+ */
+VOID InvalidStateWhenScan(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	USHORT Status;
+	DBGPRINT(RT_DEBUG_TRACE, ("AYNC - InvalidStateWhenScan(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
+	pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+	Status = MLME_STATE_MACHINE_REJECT;
+	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
+}
+
+/*
+	==========================================================================
+	Description:
+	==========================================================================
+ */
+VOID InvalidStateWhenJoin(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	USHORT Status;
+	DBGPRINT(RT_DEBUG_TRACE, ("InvalidStateWhenJoin(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
+	pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+	Status = MLME_STATE_MACHINE_REJECT;
+	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
+}
+
+/*
+	==========================================================================
+	Description:
+	==========================================================================
+ */
+VOID InvalidStateWhenStart(
+	IN PRTMP_ADAPTER pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	USHORT Status;
+	DBGPRINT(RT_DEBUG_TRACE, ("InvalidStateWhenStart(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
+	pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+	Status = MLME_STATE_MACHINE_REJECT;
+	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
+}
+
+/*
+	==========================================================================
+	Description:
+
+	IRQL = DISPATCH_LEVEL
+
+	==========================================================================
+ */
+VOID EnqueuePsPoll(
+	IN PRTMP_ADAPTER pAd)
+{
+#ifdef RALINK_ATE
+    if (ATE_ON(pAd))
+    {
+		return;
+    }
+#endif // RALINK_ATE //
+
+
+	if (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeLegacy_PSP)
+    	pAd->PsPollFrame.FC.PwrMgmt = PWR_SAVE;
+	MiniportMMRequest(pAd, 0, (PUCHAR)&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
+}
+
+
+/*
+	==========================================================================
+	Description:
+	==========================================================================
+ */
+VOID EnqueueProbeRequest(
+	IN PRTMP_ADAPTER pAd)
+{
+	NDIS_STATUS     NState;
+	PUCHAR          pOutBuffer;
+	ULONG           FrameLen = 0;
+	HEADER_802_11   Hdr80211;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("force out a ProbeRequest ...\n"));
+
+	NState = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
+	if (NState == NDIS_STATUS_SUCCESS)
+	{
+		MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
+
+		// this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse
+		MakeOutgoingFrame(pOutBuffer,                     &FrameLen,
+						  sizeof(HEADER_802_11),          &Hdr80211,
+						  1,                              &SsidIe,
+						  1,                              &pAd->CommonCfg.SsidLen,
+						  pAd->CommonCfg.SsidLen,		  pAd->CommonCfg.Ssid,
+						  1,                              &SupRateIe,
+						  1,                              &pAd->StaActive.SupRateLen,
+						  pAd->StaActive.SupRateLen,      pAd->StaActive.SupRate,
+						  END_OF_ARGS);
+		MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+		MlmeFreeMemory(pAd, pOutBuffer);
+	}
+
+}
+
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+VOID BuildEffectedChannelList(
+	IN PRTMP_ADAPTER pAd)
+{
+	UCHAR		EChannel[11];
+	UCHAR		i, j, k;
+	UCHAR		UpperChannel = 0, LowerChannel = 0;
+
+	RTMPZeroMemory(EChannel, 11);
+	i = 0;
+	// Find upper channel and lower channel.
+	if (pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel)
+	{
+		UpperChannel = pAd->CommonCfg.Channel;
+		LowerChannel = pAd->CommonCfg.CentralChannel;
+	}
+	else if (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
+	{
+		UpperChannel = pAd->CommonCfg.CentralChannel;
+		LowerChannel = pAd->CommonCfg.Channel;
+	}
+	else
+	{
+		return;
+	}
+
+	// Record channels that is below lower channel..
+	if (LowerChannel > 1)
+	{
+		EChannel[0] = LowerChannel - 1;
+		i = 1;
+		if (LowerChannel > 2)
+		{
+			EChannel[1] = LowerChannel - 2;
+			i = 2;
+			if (LowerChannel > 3)
+			{
+				EChannel[2] = LowerChannel - 3;
+				i = 3;
+			}
+		}
+	}
+	// Record channels that is between  lower channel and upper channel.
+	for (k = LowerChannel;k < UpperChannel;k++)
+	{
+		EChannel[i] = k;
+		i++;
+	}
+	// Record channels that is above upper channel..
+	if (LowerChannel < 11)
+	{
+		EChannel[i] = UpperChannel + 1;
+		i++;
+		if (LowerChannel < 10)
+		{
+			EChannel[i] = LowerChannel + 2;
+			i++;
+			if (LowerChannel < 9)
+			{
+				EChannel[i] = LowerChannel + 3;
+				i++;
+			}
+		}
+	}
+	//
+	for (j = 0;j < i;j++)
+	{
+		for (k = 0;k < pAd->ChannelListNum;k++)
+		{
+			if (pAd->ChannelList[k].Channel == EChannel[j])
+			{
+				pAd->ChannelList[k].bEffectedChannel = TRUE;
+				DBGPRINT(RT_DEBUG_TRACE,(" EffectedChannel( =%d)\n", EChannel[j]));
+				break;
+			}
+		}
+	}
+}
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+
+BOOLEAN ScanRunning(
+		IN PRTMP_ADAPTER pAd)
+{
+	return (pAd->Mlme.SyncMachine.CurrState == SCAN_LISTEN) ? TRUE : FALSE;
+}
+
diff --git a/drivers/staging/rt3070/sta/wpa.c b/drivers/staging/rt3070/sta/wpa.c
new file mode 100644
index 0000000..63d0830
--- /dev/null
+++ b/drivers/staging/rt3070/sta/wpa.c
@@ -0,0 +1,2099 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	wpa.c
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	Jan	Lee		03-07-22		Initial
+	Paul Lin	03-11-28		Modify for supplicant
+*/
+#include "../rt_config.h"
+
+#define		WPARSNIE	0xdd
+#define		WPA2RSNIE	0x30
+
+//extern UCHAR BIT8[];
+UCHAR	CipherWpaPskTkip[] = {
+		0xDD, 0x16,				// RSN IE
+		0x00, 0x50, 0xf2, 0x01,	// oui
+		0x01, 0x00,				// Version
+		0x00, 0x50, 0xf2, 0x02,	// Multicast
+		0x01, 0x00,				// Number of unicast
+		0x00, 0x50, 0xf2, 0x02,	// unicast
+		0x01, 0x00,				// number of authentication method
+		0x00, 0x50, 0xf2, 0x02	// authentication
+		};
+UCHAR	CipherWpaPskTkipLen = (sizeof(CipherWpaPskTkip) / sizeof(UCHAR));
+
+UCHAR	CipherWpaPskAes[] = {
+		0xDD, 0x16, 			// RSN IE
+		0x00, 0x50, 0xf2, 0x01,	// oui
+		0x01, 0x00,				// Version
+		0x00, 0x50, 0xf2, 0x04,	// Multicast
+		0x01, 0x00,				// Number of unicast
+		0x00, 0x50, 0xf2, 0x04,	// unicast
+		0x01, 0x00,				// number of authentication method
+		0x00, 0x50, 0xf2, 0x02	// authentication
+		};
+UCHAR	CipherWpaPskAesLen = (sizeof(CipherWpaPskAes) / sizeof(UCHAR));
+
+UCHAR	CipherSuiteCiscoCCKM[] = {
+		0xDD, 0x16,				// RSN IE
+		0x00, 0x50, 0xf2, 0x01, // oui
+		0x01, 0x00,				// Version
+		0x00, 0x40, 0x96, 0x01, // Multicast
+		0x01, 0x00,				// Number of uicast
+		0x00, 0x40, 0x96, 0x01, // unicast
+		0x01, 0x00,				// number of authentication method
+		0x00, 0x40, 0x96, 0x00  // Authentication
+		};
+UCHAR	CipherSuiteCiscoCCKMLen = (sizeof(CipherSuiteCiscoCCKM) / sizeof(UCHAR));
+
+UCHAR	CipherSuiteCiscoCCKM24[] = {
+		0xDD, 0x18,				// RSN IE
+		0x00, 0x50, 0xf2, 0x01, // oui
+		0x01, 0x00,				// Version
+		0x00, 0x40, 0x96, 0x01, // Multicast
+		0x01, 0x00,				// Number of uicast
+		0x00, 0x40, 0x96, 0x01, // unicast
+		0x01, 0x00,				// number of authentication method
+		0x00, 0x40, 0x96, 0x00,
+		0x28, 0x00// Authentication
+		};
+
+UCHAR	CipherSuiteCiscoCCKM24Len = (sizeof(CipherSuiteCiscoCCKM24) / sizeof(UCHAR));
+
+UCHAR	CipherSuiteCCXTkip[] = {
+		0xDD, 0x16,				// RSN IE
+		0x00, 0x50, 0xf2, 0x01,	// oui
+		0x01, 0x00,				// Version
+		0x00, 0x50, 0xf2, 0x02,	// Multicast
+		0x01, 0x00,				// Number of unicast
+		0x00, 0x50, 0xf2, 0x02,	// unicast
+		0x01, 0x00,				// number of authentication method
+		0x00, 0x50, 0xf2, 0x01	// authentication
+		};
+UCHAR	CipherSuiteCCXTkipLen = (sizeof(CipherSuiteCCXTkip) / sizeof(UCHAR));
+
+UCHAR	CCX_LLC_HDR[] = {0xAA, 0xAA, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02};
+UCHAR	LLC_NORMAL[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
+
+UCHAR	EAPOL_FRAME[] = {0x88, 0x8E};
+
+BOOLEAN CheckRSNIE(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR          pData,
+	IN  UCHAR           DataLen,
+	OUT	UCHAR			*Offset);
+
+void inc_byte_array(UCHAR *counter, int len);
+
+/*
+	========================================================================
+
+	Routine Description:
+		Classify WPA EAP message type
+
+	Arguments:
+		EAPType		Value of EAP message type
+		MsgType		Internal Message definition for MLME state machine
+
+	Return Value:
+		TRUE		Found appropriate message type
+		FALSE		No appropriate message type
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+		All these constants are defined in wpa.h
+		For supplicant, there is only EAPOL Key message avaliable
+
+	========================================================================
+*/
+BOOLEAN	WpaMsgTypeSubst(
+	IN	UCHAR	EAPType,
+	OUT	INT		*MsgType)
+{
+	switch (EAPType)
+	{
+		case EAPPacket:
+			*MsgType = MT2_EAPPacket;
+			break;
+		case EAPOLStart:
+			*MsgType = MT2_EAPOLStart;
+			break;
+		case EAPOLLogoff:
+			*MsgType = MT2_EAPOLLogoff;
+			break;
+		case EAPOLKey:
+			*MsgType = MT2_EAPOLKey;
+			break;
+		case EAPOLASFAlert:
+			*MsgType = MT2_EAPOLASFAlert;
+			break;
+		default:
+			return FALSE;
+	}
+	return TRUE;
+}
+
+/*
+	==========================================================================
+	Description:
+		association	state machine init,	including state	transition and timer init
+	Parameters:
+		S -	pointer	to the association state machine
+	==========================================================================
+ */
+VOID WpaPskStateMachineInit(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	STATE_MACHINE *S,
+	OUT	STATE_MACHINE_FUNC Trans[])
+{
+	StateMachineInit(S,	Trans, MAX_WPA_PSK_STATE, MAX_WPA_PSK_MSG, (STATE_MACHINE_FUNC)Drop, WPA_PSK_IDLE, WPA_MACHINE_BASE);
+	StateMachineSetAction(S, WPA_PSK_IDLE, MT2_EAPOLKey, (STATE_MACHINE_FUNC)WpaEAPOLKeyAction);
+}
+
+/*
+	==========================================================================
+	Description:
+		This is	state machine function.
+		When receiving EAPOL packets which is  for 802.1x key management.
+		Use	both in	WPA, and WPAPSK	case.
+		In this	function, further dispatch to different	functions according	to the received	packet.	 3 categories are :
+		  1.  normal 4-way pairwisekey and 2-way groupkey handshake
+		  2.  MIC error	(Countermeasures attack)  report packet	from STA.
+		  3.  Request for pairwise/group key update	from STA
+	Return:
+	==========================================================================
+*/
+VOID WpaEAPOLKeyAction(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	MLME_QUEUE_ELEM	*Elem)
+
+{
+	INT             MsgType = EAPOL_MSG_INVALID;
+	PKEY_DESCRIPTER pKeyDesc;
+	PHEADER_802_11  pHeader; //red
+	UCHAR           ZeroReplay[LEN_KEY_DESC_REPLAY];
+	UCHAR EapolVr;
+	KEY_INFO		peerKeyInfo;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("-----> WpaEAPOLKeyAction\n"));
+
+	// Get 802.11 header first
+	pHeader = (PHEADER_802_11) Elem->Msg;
+
+	// Get EAPoL-Key Descriptor
+	pKeyDesc = (PKEY_DESCRIPTER) &Elem->Msg[(LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H)];
+
+	NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
+	NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pKeyDesc->KeyInfo, sizeof(KEY_INFO));
+
+	*((USHORT *)&peerKeyInfo) = cpu2le16(*((USHORT *)&peerKeyInfo));
+
+
+	// 1. Check EAPOL frame version and type
+	EapolVr	= (UCHAR) Elem->Msg[LENGTH_802_11+LENGTH_802_1_H];
+
+    if (((EapolVr != EAPOL_VER) && (EapolVr != EAPOL_VER2)) || ((pKeyDesc->Type != WPA1_KEY_DESC) && (pKeyDesc->Type != WPA2_KEY_DESC)))
+	{
+        DBGPRINT(RT_DEBUG_ERROR, ("Key descripter does not match with WPA rule\n"));
+			return;
+	}
+
+	// First validate replay counter, only accept message with larger replay counter
+	// Let equal pass, some AP start with all zero replay counter
+	NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
+
+	if((RTMPCompareMemory(pKeyDesc->ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1) &&
+		(RTMPCompareMemory(pKeyDesc->ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("   ReplayCounter not match   \n"));
+		return;
+	}
+
+	// Process WPA2PSK frame
+	if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
+	{
+		if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
+			(peerKeyInfo.EKD_DL == 0) &&
+			(peerKeyInfo.KeyAck == 1) &&
+			(peerKeyInfo.KeyMic == 0) &&
+			(peerKeyInfo.Secure == 0) &&
+			(peerKeyInfo.Error == 0) &&
+			(peerKeyInfo.Request == 0))
+		{
+			MsgType = EAPOL_PAIR_MSG_1;
+			DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 1\n"));
+		} else if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
+			(peerKeyInfo.EKD_DL  == 1) &&
+			(peerKeyInfo.KeyAck == 1) &&
+			(peerKeyInfo.KeyMic == 1) &&
+			(peerKeyInfo.Secure == 1) &&
+			(peerKeyInfo.Error == 0) &&
+			(peerKeyInfo.Request == 0))
+		{
+			MsgType = EAPOL_PAIR_MSG_3;
+			DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 3\n"));
+		} else if((peerKeyInfo.KeyType == GROUPKEY) &&
+			(peerKeyInfo.EKD_DL == 1) &&
+			(peerKeyInfo.KeyAck == 1) &&
+			(peerKeyInfo.KeyMic == 1) &&
+			(peerKeyInfo.Secure == 1) &&
+			(peerKeyInfo.Error == 0) &&
+			(peerKeyInfo.Request == 0))
+		{
+			MsgType = EAPOL_GROUP_MSG_1;
+			DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Group Message 1\n"));
+		}
+
+		// We will assume link is up (assoc suceess and port not secured).
+		// All state has to be able to process message from previous state
+		switch(pAd->StaCfg.WpaState)
+		{
+		case SS_START:
+			if(MsgType == EAPOL_PAIR_MSG_1)
+			{
+				Wpa2PairMsg1Action(pAd, Elem);
+				pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
+			}
+			break;
+
+		case SS_WAIT_MSG_3:
+			if(MsgType == EAPOL_PAIR_MSG_1)
+			{
+				Wpa2PairMsg1Action(pAd, Elem);
+				pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
+			}
+			else if(MsgType == EAPOL_PAIR_MSG_3)
+			{
+				Wpa2PairMsg3Action(pAd, Elem);
+				pAd->StaCfg.WpaState = SS_WAIT_GROUP;
+			}
+			break;
+
+		case SS_WAIT_GROUP:		// When doing group key exchange
+		case SS_FINISH:			// This happened when update group key
+			if(MsgType == EAPOL_PAIR_MSG_1)
+			{
+			    // Reset port secured variable
+				pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+				Wpa2PairMsg1Action(pAd, Elem);
+				pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
+			}
+			else if(MsgType == EAPOL_PAIR_MSG_3)
+			{
+			    // Reset port secured variable
+				pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+				Wpa2PairMsg3Action(pAd, Elem);
+				pAd->StaCfg.WpaState = SS_WAIT_GROUP;
+			}
+			else if(MsgType == EAPOL_GROUP_MSG_1)
+			{
+				WpaGroupMsg1Action(pAd, Elem);
+				pAd->StaCfg.WpaState = SS_FINISH;
+			}
+			break;
+
+		default:
+			break;
+		}
+	}
+	// Process WPAPSK Frame
+	// Classify message Type, either pairwise message 1, 3, or group message 1 for supplicant
+	else if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
+	{
+		if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
+			(peerKeyInfo.KeyIndex == 0) &&
+			(peerKeyInfo.KeyAck == 1) &&
+			(peerKeyInfo.KeyMic == 0) &&
+			(peerKeyInfo.Secure == 0) &&
+			(peerKeyInfo.Error == 0) &&
+			(peerKeyInfo.Request == 0))
+		{
+			MsgType = EAPOL_PAIR_MSG_1;
+			DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 1\n"));
+		}
+		else if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
+			(peerKeyInfo.KeyIndex == 0) &&
+			(peerKeyInfo.KeyAck == 1) &&
+			(peerKeyInfo.KeyMic == 1) &&
+			(peerKeyInfo.Secure == 0) &&
+			(peerKeyInfo.Error == 0) &&
+			(peerKeyInfo.Request == 0))
+		{
+			MsgType = EAPOL_PAIR_MSG_3;
+			DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 3\n"));
+		}
+		else if((peerKeyInfo.KeyType == GROUPKEY) &&
+			(peerKeyInfo.KeyIndex != 0) &&
+			(peerKeyInfo.KeyAck == 1) &&
+			(peerKeyInfo.KeyMic == 1) &&
+			(peerKeyInfo.Secure == 1) &&
+			(peerKeyInfo.Error == 0) &&
+			(peerKeyInfo.Request == 0))
+		{
+			MsgType = EAPOL_GROUP_MSG_1;
+			DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Group Message 1\n"));
+		}
+
+		// We will assume link is up (assoc suceess and port not secured).
+		// All state has to be able to process message from previous state
+		switch(pAd->StaCfg.WpaState)
+		{
+		case SS_START:
+			if(MsgType == EAPOL_PAIR_MSG_1)
+			{
+				WpaPairMsg1Action(pAd, Elem);
+				pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
+			}
+			break;
+
+		case SS_WAIT_MSG_3:
+			if(MsgType == EAPOL_PAIR_MSG_1)
+			{
+				WpaPairMsg1Action(pAd, Elem);
+				pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
+			}
+			else if(MsgType == EAPOL_PAIR_MSG_3)
+			{
+				WpaPairMsg3Action(pAd, Elem);
+				pAd->StaCfg.WpaState = SS_WAIT_GROUP;
+			}
+			break;
+
+		case SS_WAIT_GROUP:		// When doing group key exchange
+		case SS_FINISH:			// This happened when update group key
+			if(MsgType == EAPOL_PAIR_MSG_1)
+			{
+				WpaPairMsg1Action(pAd, Elem);
+				pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
+				// Reset port secured variable
+				pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+			}
+			else if(MsgType == EAPOL_PAIR_MSG_3)
+			{
+				WpaPairMsg3Action(pAd, Elem);
+				pAd->StaCfg.WpaState = SS_WAIT_GROUP;
+				// Reset port secured variable
+				pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+			}
+			else if(MsgType == EAPOL_GROUP_MSG_1)
+			{
+				WpaGroupMsg1Action(pAd, Elem);
+				pAd->StaCfg.WpaState = SS_FINISH;
+			}
+			break;
+
+		default:
+			break;
+		}
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<----- WpaEAPOLKeyAction\n"));
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Process Pairwise key 4-way handshaking
+
+	Arguments:
+		pAd	Pointer	to our adapter
+		Elem		Message body
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+VOID	WpaPairMsg1Action(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem)
+{
+	PHEADER_802_11      pHeader;
+	UCHAR				*mpool, *PTK, *digest;
+	PUCHAR              pOutBuffer = NULL;
+	UCHAR               Header802_3[14];
+	ULONG               FrameLen = 0;
+	PEAPOL_PACKET       pMsg1;
+	EAPOL_PACKET        Packet;
+	UCHAR               Mic[16];
+
+	DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg1Action ----->\n"));
+
+	// allocate memory pool
+	os_alloc_mem(pAd, (PUCHAR *)&mpool, 256);
+
+	if (mpool == NULL)
+		return;
+
+	// PTK Len = 80.
+	PTK = (UCHAR *) ROUND_UP(mpool, 4);
+	// digest Len = 80.
+	digest = (UCHAR *) ROUND_UP(PTK + 80, 4);
+
+	pHeader = (PHEADER_802_11) Elem->Msg;
+
+	// Process message 1 from authenticator
+	pMsg1 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+
+	// 1. Save Replay counter, it will use to verify message 3 and construct message 2
+	NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg1->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+	// 2. Save ANonce
+	NdisMoveMemory(pAd->StaCfg.ANonce, pMsg1->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE);
+
+	// Generate random SNonce
+	GenRandom(pAd, pAd->CurrentAddress, pAd->StaCfg.SNonce);
+
+	// Calc PTK(ANonce, SNonce)
+	WpaCountPTK(pAd,
+		pAd->StaCfg.PMK,
+		pAd->StaCfg.ANonce,
+		pAd->CommonCfg.Bssid,
+		pAd->StaCfg.SNonce,
+		pAd->CurrentAddress,
+		PTK,
+		LEN_PTK);
+
+	// Save key to PTK entry
+	NdisMoveMemory(pAd->StaCfg.PTK, PTK, LEN_PTK);
+
+	// init 802.3 header and Fill Packet
+	MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
+
+	// Zero Message 2 body
+	NdisZeroMemory(&Packet, sizeof(Packet));
+	Packet.ProVer	= EAPOL_VER;
+	Packet.ProType	= EAPOLKey;
+	//
+	// Message 2 as  EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)
+	//
+	Packet.KeyDesc.Type = WPA1_KEY_DESC;
+	// 1. Key descriptor version and appropriate RSN IE
+	if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
+	{
+		Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
+	}
+	else	  // TKIP
+	{
+		Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
+	}
+
+	// fill in Data Material and its length
+	Packet.KeyDesc.KeyData[0] = IE_WPA;
+	Packet.KeyDesc.KeyData[1] = pAd->StaCfg.RSNIE_Len;
+	Packet.KeyDesc.KeyDataLen[1] = pAd->StaCfg.RSNIE_Len + 2;
+	NdisMoveMemory(&Packet.KeyDesc.KeyData[2], pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len);
+
+	// Update packet length after decide Key data payload
+	Packet.Body_Len[1]  = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + Packet.KeyDesc.KeyDataLen[1];
+
+	// Update Key length
+	Packet.KeyDesc.KeyLength[0] = pMsg1->KeyDesc.KeyLength[0];
+	Packet.KeyDesc.KeyLength[1] = pMsg1->KeyDesc.KeyLength[1];
+	// 2. Key Type PeerKey
+	Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
+
+	// 3. KeyMic field presented
+	Packet.KeyDesc.KeyInfo.KeyMic  = 1;
+
+	//Convert to little-endian format.
+	*((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
+
+
+	// 4. Fill SNonce
+	NdisMoveMemory(Packet.KeyDesc.KeyNonce, pAd->StaCfg.SNonce, LEN_KEY_DESC_NONCE);
+
+	// 5. Key Replay Count
+	NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+	// Send EAPOL(0, 1, 0, 0, 0, P, 0, SNonce, MIC, RSN_IE)
+	// Out buffer for transmitting message 2
+	MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer);  // allocate memory
+	if(pOutBuffer == NULL)
+	{
+		os_free_mem(pAd, mpool);
+		return;
+	}
+	// Prepare EAPOL frame for MIC calculation
+	// Be careful, only EAPOL frame is counted for MIC calculation
+	MakeOutgoingFrame(pOutBuffer,           &FrameLen,
+		Packet.Body_Len[1] + 4,    &Packet,
+		END_OF_ARGS);
+
+	// 6. Prepare and Fill MIC value
+	NdisZeroMemory(Mic, sizeof(Mic));
+	if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
+	{	// AES
+
+		HMAC_SHA1(pOutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest);
+		NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+	}
+	else
+	{	// TKIP
+		hmac_md5(PTK,  LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
+	}
+	NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
+
+	//hex_dump("MIC", Mic, LEN_KEY_DESC_MIC);
+
+		MakeOutgoingFrame(pOutBuffer,           	&FrameLen,
+			  			LENGTH_802_3,     			&Header802_3,
+						Packet.Body_Len[1] + 4,    &Packet,
+						END_OF_ARGS);
+
+
+	// 5. Copy frame to Tx ring and send Msg 2 to authenticator
+	RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
+
+	MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
+	os_free_mem(pAd, (PUCHAR)mpool);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg1Action <-----\n"));
+}
+
+VOID Wpa2PairMsg1Action(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem)
+{
+	PHEADER_802_11      pHeader;
+	UCHAR				*mpool, *PTK, *digest;
+	PUCHAR              pOutBuffer = NULL;
+	UCHAR               Header802_3[14];
+	ULONG               FrameLen = 0;
+	PEAPOL_PACKET       pMsg1;
+	EAPOL_PACKET        Packet;
+	UCHAR               Mic[16];
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg1Action ----->\n"));
+
+	// allocate memory pool
+	os_alloc_mem(pAd, (PUCHAR *)&mpool, 256);
+
+	if (mpool == NULL)
+		return;
+
+	// PTK Len = 80.
+	PTK = (UCHAR *) ROUND_UP(mpool, 4);
+	// digest Len = 80.
+	digest = (UCHAR *) ROUND_UP(PTK + 80, 4);
+
+	pHeader = (PHEADER_802_11) Elem->Msg;
+
+	// Process message 1 from authenticator
+		pMsg1 = (PEAPOL_PACKET)	&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+
+	// 1. Save Replay counter, it will use to verify message 3 and construct message 2
+	NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg1->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+	// 2. Save ANonce
+	NdisMoveMemory(pAd->StaCfg.ANonce, pMsg1->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE);
+
+	// Generate random SNonce
+	GenRandom(pAd, pAd->CurrentAddress, pAd->StaCfg.SNonce);
+
+	if(pMsg1->KeyDesc.KeyDataLen[1] > 0 )
+	{
+		// cached PMKID
+	}
+
+	// Calc PTK(ANonce, SNonce)
+	WpaCountPTK(pAd,
+		pAd->StaCfg.PMK,
+		pAd->StaCfg.ANonce,
+		pAd->CommonCfg.Bssid,
+		pAd->StaCfg.SNonce,
+		pAd->CurrentAddress,
+		PTK,
+		LEN_PTK);
+
+	// Save key to PTK entry
+	NdisMoveMemory(pAd->StaCfg.PTK, PTK, LEN_PTK);
+
+	// init 802.3 header and Fill Packet
+	MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
+
+	// Zero message 2 body
+	NdisZeroMemory(&Packet, sizeof(Packet));
+	Packet.ProVer	= EAPOL_VER;
+	Packet.ProType	= EAPOLKey;
+	//
+	// Message 2 as  EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)
+	//
+	Packet.KeyDesc.Type = WPA2_KEY_DESC;
+
+	// 1. Key descriptor version and appropriate RSN IE
+	if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+	{
+		Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
+	}
+	else	  // TKIP
+	{
+		Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
+	}
+
+	// fill in Data Material and its length
+	Packet.KeyDesc.KeyData[0] = IE_WPA2;
+	Packet.KeyDesc.KeyData[1] = pAd->StaCfg.RSNIE_Len;
+	Packet.KeyDesc.KeyDataLen[1] = pAd->StaCfg.RSNIE_Len + 2;
+	NdisMoveMemory(&Packet.KeyDesc.KeyData[2], pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len);
+
+	// Update packet length after decide Key data payload
+	Packet.Body_Len[1]  = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + Packet.KeyDesc.KeyDataLen[1];
+
+	// 2. Key Type PeerKey
+	Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
+
+	// 3. KeyMic field presented
+	Packet.KeyDesc.KeyInfo.KeyMic  = 1;
+
+	// Update Key Length
+	Packet.KeyDesc.KeyLength[0] = 0;
+	Packet.KeyDesc.KeyLength[1] = pMsg1->KeyDesc.KeyLength[1];
+
+	// 4. Fill SNonce
+	NdisMoveMemory(Packet.KeyDesc.KeyNonce, pAd->StaCfg.SNonce, LEN_KEY_DESC_NONCE);
+
+	// 5. Key Replay Count
+	NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+	// Convert to little-endian format.
+	*((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
+
+	// Send EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)
+	// Out buffer for transmitting message 2
+	MlmeAllocateMemory(pAd,  (PUCHAR *)&pOutBuffer);  // allocate memory
+	if(pOutBuffer == NULL)
+	{
+		os_free_mem(pAd, mpool);
+		return;
+	}
+
+	// Prepare EAPOL frame for MIC calculation
+	// Be careful, only EAPOL frame is counted for MIC calculation
+	MakeOutgoingFrame(pOutBuffer,        &FrameLen,
+		Packet.Body_Len[1] + 4, &Packet,
+		END_OF_ARGS);
+
+	// 6. Prepare and Fill MIC value
+	NdisZeroMemory(Mic, sizeof(Mic));
+	if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+	{
+		// AES
+		HMAC_SHA1(pOutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest);
+		NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+	}
+	else
+	{
+		hmac_md5(PTK,  LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
+	}
+	NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
+
+
+	// Make  Transmitting frame
+	MakeOutgoingFrame(pOutBuffer,           	&FrameLen,
+			  			LENGTH_802_3,     		&Header802_3,
+						Packet.Body_Len[1] + 4, &Packet,
+						END_OF_ARGS);
+
+
+	// 5. Copy frame to Tx ring
+	RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
+
+	MlmeFreeMemory(pAd, pOutBuffer);
+	os_free_mem(pAd, mpool);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg1Action <-----\n"));
+
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Process Pairwise key 4-way handshaking
+
+	Arguments:
+		pAd	Pointer	to our adapter
+		Elem		Message body
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+VOID	WpaPairMsg3Action(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	MLME_QUEUE_ELEM	*Elem)
+
+{
+	PHEADER_802_11      pHeader;
+	PUCHAR          	pOutBuffer = NULL;
+	UCHAR               Header802_3[14];
+	ULONG           	FrameLen = 0;
+	EAPOL_PACKET        Packet;
+	PEAPOL_PACKET       pMsg3;
+	UCHAR           	Mic[16], OldMic[16];
+	MAC_TABLE_ENTRY 	*pEntry = NULL;
+	UCHAR				skip_offset;
+	KEY_INFO			peerKeyInfo;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg3Action ----->\n"));
+
+	// Record 802.11 header & the received EAPOL packet Msg3
+	pHeader = (PHEADER_802_11) Elem->Msg;
+	pMsg3 = (PEAPOL_PACKET)	&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+
+	NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
+	NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pMsg3->KeyDesc.KeyInfo, sizeof(KEY_INFO));
+
+	*((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo));
+
+
+	// 1. Verify cipher type match
+	if (pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer != 2))
+	{
+		return;
+	}
+	else if(pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1))
+	{
+		return;
+	}
+
+	// Verify RSN IE
+	//if (!RTMPEqualMemory(pMsg3->KeyDesc.KeyData, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len))
+	if (!CheckRSNIE(pAd, pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1], &skip_offset))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("RSN_IE Different in Msg 3 of WPA1 4-way handshake!! \n"));
+		hex_dump("The original RSN_IE", pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len);
+		hex_dump("The received RSN_IE", pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1]);
+		return;
+	}
+	else
+		DBGPRINT(RT_DEBUG_TRACE, ("RSN_IE VALID in Msg 3 of WPA1 4-way handshake!! \n"));
+
+
+	// 2. Check MIC value
+	// Save the MIC and replace with zero
+	NdisMoveMemory(OldMic, pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+	NdisZeroMemory(pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+	if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
+	{
+		// AES
+		UCHAR digest[80];
+
+		HMAC_SHA1((PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
+		NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+	}
+	else	// TKIP
+	{
+		hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, Mic);
+	}
+
+	if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in msg 3 of 4-way handshake!!!!!!!!!! \n"));
+		return;
+	}
+	else
+		DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in msg 3 of 4-way handshake!!!!!!!!!! \n"));
+
+	// 3. Check Replay Counter, it has to be larger than last one. No need to be exact one larger
+	if(RTMPCompareMemory(pMsg3->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1)
+		return;
+
+	// Update new replay counter
+	NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+	// 4. Double check ANonce
+	if(!NdisEqualMemory(pAd->StaCfg.ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE))
+		return;
+
+	// init 802.3 header and Fill Packet
+	MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
+
+	// Zero Message 4 body
+	NdisZeroMemory(&Packet, sizeof(Packet));
+	Packet.ProVer	= EAPOL_VER;
+	Packet.ProType	= EAPOLKey;
+	Packet.Body_Len[1]  = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE;		// No data field
+
+	//
+	// Message 4 as  EAPOL-Key(0,1,0,0,0,P,0,0,MIC,0)
+	//
+	Packet.KeyDesc.Type = WPA1_KEY_DESC;
+
+	// Key descriptor version and appropriate RSN IE
+	Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer;
+
+	// Update Key Length
+	Packet.KeyDesc.KeyLength[0] = pMsg3->KeyDesc.KeyLength[0];
+	Packet.KeyDesc.KeyLength[1] = pMsg3->KeyDesc.KeyLength[1];
+
+	// Key Type PeerKey
+	Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
+
+	// KeyMic field presented
+	Packet.KeyDesc.KeyInfo.KeyMic  = 1;
+
+	// In Msg3,  KeyInfo.secure =0 if Group Key HS to come. 1 if no group key HS
+	// Station sends Msg4  KeyInfo.secure should be the same as that in Msg.3
+	Packet.KeyDesc.KeyInfo.Secure= peerKeyInfo.Secure;
+
+	// Convert to little-endian format.
+	*((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
+
+	// Key Replay count
+	NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+	// Out buffer for transmitting message 4
+	MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer);  // allocate memory
+	if(pOutBuffer == NULL)
+		return;
+
+	// Prepare EAPOL frame for MIC calculation
+	// Be careful, only EAPOL frame is counted for MIC calculation
+	MakeOutgoingFrame(pOutBuffer,           &FrameLen,
+		Packet.Body_Len[1] + 4,    &Packet,
+		END_OF_ARGS);
+
+	// Prepare and Fill MIC value
+	NdisZeroMemory(Mic, sizeof(Mic));
+	if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
+	{
+		// AES
+		UCHAR digest[80];
+
+		HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
+		NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+	}
+	else
+	{
+		hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
+	}
+	NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
+
+	// Update PTK
+	// Prepare pair-wise key information into shared key table
+	NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
+	pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
+    NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
+	NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
+	NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
+
+	// Decide its ChiperAlg
+	if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+		pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
+	else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
+		pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
+	else
+		pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
+
+	// Update these related information to MAC_TABLE_ENTRY
+	pEntry = &pAd->MacTab.Content[BSSID_WCID];
+	NdisMoveMemory(pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
+	NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
+	NdisMoveMemory(pEntry->PairwiseKey.TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
+	pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
+
+	// Update pairwise key information to ASIC Shared Key Table
+	AsicAddSharedKeyEntry(pAd,
+						  BSS0,
+						  0,
+						  pAd->SharedKey[BSS0][0].CipherAlg,
+						  pAd->SharedKey[BSS0][0].Key,
+						  pAd->SharedKey[BSS0][0].TxMic,
+						  pAd->SharedKey[BSS0][0].RxMic);
+
+	// Update ASIC WCID attribute table and IVEIV table
+	RTMPAddWcidAttributeEntry(pAd,
+							  BSS0,
+							  0,
+							  pAd->SharedKey[BSS0][0].CipherAlg,
+							  pEntry);
+
+	// Make transmitting frame
+	MakeOutgoingFrame(pOutBuffer,           	&FrameLen,
+			  			LENGTH_802_3,     		&Header802_3,
+						Packet.Body_Len[1] + 4, &Packet,
+						END_OF_ARGS);
+
+
+	// Copy frame to Tx ring and Send Message 4 to authenticator
+	RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
+
+	MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg3Action <-----\n"));
+}
+
+VOID    Wpa2PairMsg3Action(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  MLME_QUEUE_ELEM *Elem)
+
+{
+	PHEADER_802_11      pHeader;
+	PUCHAR              pOutBuffer = NULL;
+	UCHAR               Header802_3[14];
+	ULONG               FrameLen = 0;
+	EAPOL_PACKET        Packet;
+	PEAPOL_PACKET       pMsg3;
+	UCHAR               Mic[16], OldMic[16];
+	UCHAR               *mpool, *KEYDATA, *digest;
+	UCHAR               Key[32];
+	MAC_TABLE_ENTRY 	*pEntry = NULL;
+	KEY_INFO			peerKeyInfo;
+
+	// allocate memory
+	os_alloc_mem(pAd, (PUCHAR *)&mpool, 1024);
+
+	if(mpool == NULL)
+		return;
+
+	// KEYDATA Len = 512.
+	KEYDATA = (UCHAR *) ROUND_UP(mpool, 4);
+	// digest Len = 80.
+	digest = (UCHAR *) ROUND_UP(KEYDATA + 512, 4);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg3Action ----->\n"));
+
+	pHeader = (PHEADER_802_11) Elem->Msg;
+
+	// Process message 3 frame.
+	pMsg3 = (PEAPOL_PACKET)	&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+
+	NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
+	NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pMsg3->KeyDesc.KeyInfo, sizeof(KEY_INFO));
+
+	*((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo));
+
+	// 1. Verify cipher type match
+	if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer!= 2))
+	{
+		os_free_mem(pAd, (PUCHAR)mpool);
+		return;
+	}
+	else if(pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1))
+	{
+		os_free_mem(pAd, (PUCHAR)mpool);
+		return;
+	}
+
+	// 2. Check MIC value
+	// Save the MIC and replace with zero
+	NdisMoveMemory(OldMic, pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+	NdisZeroMemory(pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+	if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+	{
+		// AES
+		HMAC_SHA1((PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
+		NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+	}
+	else
+	{
+		hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, Mic);
+	}
+
+	if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in msg 3 of 4-way handshake!!!!!!!!!! \n"));
+		os_free_mem(pAd, (PUCHAR)mpool);
+		return;
+	}
+	else
+		DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in msg 3 of 4-way handshake!!!!!!!!!! \n"));
+
+	// 3. Check Replay Counter, it has to be larger than last one. No need to be exact one larger
+	if(RTMPCompareMemory(pMsg3->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1)
+	{
+		os_free_mem(pAd, (PUCHAR)mpool);
+		return;
+	}
+
+	// Update new replay counter
+	NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+	// 4. Double check ANonce
+	if(!NdisEqualMemory(pAd->StaCfg.ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE))
+	{
+		os_free_mem(pAd, (PUCHAR)mpool);
+		return;
+	}
+
+	// Obtain GTK
+	// 5. Decrypt GTK from Key Data
+	DBGPRINT_RAW(RT_DEBUG_TRACE, ("EKD = %d\n", peerKeyInfo.EKD_DL));
+	if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+	{
+		// Decrypt AES GTK
+		AES_GTK_KEY_UNWRAP(&pAd->StaCfg.PTK[16], KEYDATA, pMsg3->KeyDesc.KeyDataLen[1],pMsg3->KeyDesc.KeyData);
+	}
+	else	  // TKIP
+	{
+		INT i;
+		// Decrypt TKIP GTK
+		// Construct 32 bytes RC4 Key
+		NdisMoveMemory(Key, pMsg3->KeyDesc.KeyIv, 16);
+		NdisMoveMemory(&Key[16], &pAd->StaCfg.PTK[16], 16);
+		ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
+		//discard first 256 bytes
+		for(i = 0; i < 256; i++)
+			ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
+		// Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
+		ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1]);
+	}
+
+	if (!ParseKeyData(pAd, KEYDATA, pMsg3->KeyDesc.KeyDataLen[1], 1))
+	{
+		os_free_mem(pAd, (PUCHAR)mpool);
+		return;
+	}
+
+	// Update GTK to ASIC
+	// Update group key information to ASIC Shared Key Table
+	AsicAddSharedKeyEntry(pAd,
+						  BSS0,
+						  pAd->StaCfg.DefaultKeyId,
+						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
+						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
+						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
+						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
+
+	// Update ASIC WCID attribute table and IVEIV table
+	RTMPAddWcidAttributeEntry(pAd,
+							  BSS0,
+							  pAd->StaCfg.DefaultKeyId,
+							  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
+							  NULL);
+
+	// init 802.3 header and Fill Packet
+	MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
+
+	// Zero message 4 body
+	NdisZeroMemory(&Packet, sizeof(Packet));
+	Packet.ProVer	= EAPOL_VER;
+	Packet.ProType	= EAPOLKey;
+	Packet.Body_Len[1]  	= sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE;		// No data field
+
+	//
+	// Message 4 as  EAPOL-Key(0,1,0,0,0,P,0,0,MIC,0)
+	//
+	Packet.KeyDesc.Type = WPA2_KEY_DESC;
+
+	// Key descriptor version and appropriate RSN IE
+	Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer;
+
+	// Update Key Length
+	Packet.KeyDesc.KeyLength[0] = pMsg3->KeyDesc.KeyLength[0];
+	Packet.KeyDesc.KeyLength[1] = pMsg3->KeyDesc.KeyLength[1];
+
+	// Key Type PeerKey
+	Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
+
+	// KeyMic field presented
+	Packet.KeyDesc.KeyInfo.KeyMic  = 1;
+	Packet.KeyDesc.KeyInfo.Secure = 1;
+
+	// Convert to little-endian format.
+	*((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
+
+	// Key Replay count
+	NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+	// Out buffer for transmitting message 4
+	MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer);  // allocate memory
+	if(pOutBuffer == NULL)
+	{
+		os_free_mem(pAd, (PUCHAR)mpool);
+		return;
+	}
+
+	// Prepare EAPOL frame for MIC calculation
+	// Be careful, only EAPOL frame is counted for MIC calculation
+	MakeOutgoingFrame(pOutBuffer,           &FrameLen,
+		Packet.Body_Len[1] + 4,    &Packet,
+		END_OF_ARGS);
+
+	// Prepare and Fill MIC value
+	NdisZeroMemory(Mic, sizeof(Mic));
+	if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+	{
+		// AES
+		HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
+		NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+	}
+	else
+	{
+		hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
+	}
+	NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
+
+	// Update PTK
+	// Prepare pair-wise key information into shared key table
+	NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
+	pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
+    NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
+	NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
+	NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
+
+	// Decide its ChiperAlg
+	if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+		pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
+	else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
+		pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
+	else
+		pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
+
+	// Update these related information to MAC_TABLE_ENTRY
+	pEntry = &pAd->MacTab.Content[BSSID_WCID];
+	NdisMoveMemory(&pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
+	NdisMoveMemory(&pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
+	NdisMoveMemory(&pEntry->PairwiseKey.TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
+	pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
+
+	// Update pairwise key information to ASIC Shared Key Table
+	AsicAddSharedKeyEntry(pAd,
+						  BSS0,
+						  0,
+						  pAd->SharedKey[BSS0][0].CipherAlg,
+						  pAd->SharedKey[BSS0][0].Key,
+						  pAd->SharedKey[BSS0][0].TxMic,
+						  pAd->SharedKey[BSS0][0].RxMic);
+
+	// Update ASIC WCID attribute table and IVEIV table
+	RTMPAddWcidAttributeEntry(pAd,
+							  BSS0,
+							  0,
+							  pAd->SharedKey[BSS0][0].CipherAlg,
+							  pEntry);
+
+	// Make  Transmitting frame
+	MakeOutgoingFrame(pOutBuffer,           	&FrameLen,
+			  			LENGTH_802_3,     		&Header802_3,
+						Packet.Body_Len[1] + 4, &Packet,
+						END_OF_ARGS);
+
+
+	// Copy frame to Tx ring and Send Message 4 to authenticator
+	RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
+
+	// set 802.1x port control
+	//pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+	STA_PORT_SECURED(pAd);
+
+    // Indicate Connected for GUI
+    pAd->IndicateMediaState = NdisMediaStateConnected;
+
+	MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
+	os_free_mem(pAd, (PUCHAR)mpool);
+
+
+	// send wireless event - for set key done WPA2
+	if (pAd->CommonCfg.bWirelessEvent)
+		RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pEntry->Addr, BSS0, 0);
+
+	DBGPRINT(RT_DEBUG_ERROR, ("Wpa2PairMsg3Action <-----\n"));
+
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Process Group key 2-way handshaking
+
+	Arguments:
+		pAd	Pointer	to our adapter
+		Elem		Message body
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+VOID	WpaGroupMsg1Action(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	MLME_QUEUE_ELEM	*Elem)
+
+{
+	PUCHAR              pOutBuffer = NULL;
+	UCHAR               Header802_3[14];
+	ULONG               FrameLen = 0;
+	EAPOL_PACKET        Packet;
+	PEAPOL_PACKET       pGroup;
+	UCHAR               *mpool, *digest, *KEYDATA;
+	UCHAR               Mic[16], OldMic[16];
+	UCHAR               GTK[32], Key[32];
+	KEY_INFO			peerKeyInfo;
+
+	// allocate memory
+	os_alloc_mem(pAd, (PUCHAR *)&mpool, 1024);
+
+	if(mpool == NULL)
+		return;
+
+	// digest Len = 80.
+	digest = (UCHAR *) ROUND_UP(mpool, 4);
+	// KEYDATA Len = 512.
+	KEYDATA = (UCHAR *) ROUND_UP(digest + 80, 4);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("WpaGroupMsg1Action ----->\n"));
+
+	// Process Group Message 1 frame. skip 802.11 header(24) & LLC_SNAP header(8)
+	pGroup = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+
+	NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
+	NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pGroup->KeyDesc.KeyInfo, sizeof(KEY_INFO));
+
+	*((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo));
+
+	// 0. Check cipher type match
+	if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer != 2))
+	{
+		os_free_mem(pAd, (PUCHAR)mpool);
+		return;
+	}
+	else if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1))
+	{
+		os_free_mem(pAd, (PUCHAR)mpool);
+		return;
+	}
+
+	// 1. Verify Replay counter
+	//    Check Replay Counter, it has to be larger than last one. No need to be exact one larger
+	if(RTMPCompareMemory(pGroup->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1)
+	{
+		os_free_mem(pAd, (PUCHAR)mpool);
+		return;
+	}
+
+	// Update new replay counter
+	NdisMoveMemory(pAd->StaCfg.ReplayCounter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+	// 2. Verify MIC is valid
+	// Save the MIC and replace with zero
+	NdisMoveMemory(OldMic, pGroup->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+	NdisZeroMemory(pGroup->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+
+	if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
+	{	// AES
+		HMAC_SHA1((PUCHAR) pGroup, pGroup->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
+		NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+	}
+	else
+	{	// TKIP
+		hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pGroup, pGroup->Body_Len[1] + 4, Mic);
+	}
+
+	if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in group msg 1 of 2-way handshake!!!!!!!!!! \n"));
+		MlmeFreeMemory(pAd, (PUCHAR)mpool);
+		return;
+	}
+	else
+		DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in group msg 1 of 2-way handshake!!!!!!!!!! \n"));
+
+
+	// 3. Decrypt GTK from Key Data
+	if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+	{
+		// Decrypt AES GTK
+		AES_GTK_KEY_UNWRAP(&pAd->StaCfg.PTK[16], KEYDATA,  pGroup->KeyDesc.KeyDataLen[1], pGroup->KeyDesc.KeyData);
+	}
+	else	// TKIP
+	{
+		INT i;
+
+		// Decrypt TKIP GTK
+		// Construct 32 bytes RC4 Key
+		NdisMoveMemory(Key, pGroup->KeyDesc.KeyIv, 16);
+		NdisMoveMemory(&Key[16], &pAd->StaCfg.PTK[16], 16);
+		ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
+		//discard first 256 bytes
+		for(i = 0; i < 256; i++)
+			ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
+		// Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
+		ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, pGroup->KeyDesc.KeyData, pGroup->KeyDesc.KeyDataLen[1]);
+	}
+
+	// Process decrypted key data material
+	// Parse keyData to handle KDE format for WPA2PSK
+	if (peerKeyInfo.EKD_DL)
+	{
+		if (!ParseKeyData(pAd, KEYDATA, pGroup->KeyDesc.KeyDataLen[1], 0))
+		{
+			os_free_mem(pAd, (PUCHAR)mpool);
+			return;
+		}
+	}
+	else	// WPAPSK
+	{
+		// set key material, TxMic and RxMic for WPAPSK
+		NdisMoveMemory(GTK, KEYDATA, 32);
+		NdisMoveMemory(pAd->StaCfg.GTK, GTK, 32);
+		pAd->StaCfg.DefaultKeyId = peerKeyInfo.KeyIndex;
+
+		// Prepare pair-wise key information into shared key table
+		NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
+		pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
+		NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, GTK, LEN_TKIP_EK);
+		NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, &GTK[16], LEN_TKIP_RXMICK);
+		NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, &GTK[24], LEN_TKIP_TXMICK);
+
+		// Update Shared Key CipherAlg
+		pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
+		if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
+			pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
+		else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
+			pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
+
+    	//hex_dump("Group Key :", pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, LEN_TKIP_EK);
+	}
+
+	// Update group key information to ASIC Shared Key Table
+	AsicAddSharedKeyEntry(pAd,
+						  BSS0,
+						  pAd->StaCfg.DefaultKeyId,
+						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
+						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
+						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
+						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
+
+	// Update ASIC WCID attribute table and IVEIV table
+	RTMPAddWcidAttributeEntry(pAd,
+							  BSS0,
+							  pAd->StaCfg.DefaultKeyId,
+							  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
+							  NULL);
+
+	// set 802.1x port control
+	//pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+	STA_PORT_SECURED(pAd);
+
+    // Indicate Connected for GUI
+    pAd->IndicateMediaState = NdisMediaStateConnected;
+
+	// init header and Fill Packet
+	MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
+
+	// Zero Group message 1 body
+	NdisZeroMemory(&Packet, sizeof(Packet));
+	Packet.ProVer	= EAPOL_VER;
+	Packet.ProType	= EAPOLKey;
+	Packet.Body_Len[1]  = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE;		// No data field
+
+	//
+	// Group Message 2 as  EAPOL-Key(1,0,0,0,G,0,0,MIC,0)
+	//
+	if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
+	{
+		Packet.KeyDesc.Type = WPA2_KEY_DESC;
+	}
+	else
+	{
+		Packet.KeyDesc.Type = WPA1_KEY_DESC;
+	}
+
+	// Key descriptor version and appropriate RSN IE
+	Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer;
+
+	// Update Key Length
+	Packet.KeyDesc.KeyLength[0] = pGroup->KeyDesc.KeyLength[0];
+	Packet.KeyDesc.KeyLength[1] = pGroup->KeyDesc.KeyLength[1];
+
+	// Key Index as G-Msg 1
+	if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
+		Packet.KeyDesc.KeyInfo.KeyIndex = peerKeyInfo.KeyIndex;
+
+	// Key Type Group key
+	Packet.KeyDesc.KeyInfo.KeyType = GROUPKEY;
+
+	// KeyMic field presented
+	Packet.KeyDesc.KeyInfo.KeyMic  = 1;
+
+	// Secure bit
+	Packet.KeyDesc.KeyInfo.Secure  = 1;
+
+	// Convert to little-endian format.
+	*((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
+
+	// Key Replay count
+	NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+	// Out buffer for transmitting group message 2
+	MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer);  // allocate memory
+	if(pOutBuffer == NULL)
+	{
+		MlmeFreeMemory(pAd, (PUCHAR)mpool);
+		return;
+	}
+
+	// Prepare EAPOL frame for MIC calculation
+	// Be careful, only EAPOL frame is counted for MIC calculation
+	MakeOutgoingFrame(pOutBuffer,           &FrameLen,
+		Packet.Body_Len[1] + 4,    &Packet,
+		END_OF_ARGS);
+
+	// Prepare and Fill MIC value
+	NdisZeroMemory(Mic, sizeof(Mic));
+	if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
+	{
+		// AES
+		HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
+		NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+	}
+	else
+	{
+		hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
+	}
+	NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
+
+
+	MakeOutgoingFrame(pOutBuffer,       		&FrameLen,
+						LENGTH_802_3,     		&Header802_3,
+						Packet.Body_Len[1] + 4, &Packet,
+						END_OF_ARGS);
+
+
+	// 5. Copy frame to Tx ring and prepare for encryption
+	RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, FALSE);
+
+	// 6 Free allocated memory
+	MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
+	os_free_mem(pAd, (PUCHAR)mpool);
+
+	// send wireless event - for set key done WPA2
+	if (pAd->CommonCfg.bWirelessEvent)
+		RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("WpaGroupMsg1Action <-----\n"));
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Init WPA MAC header
+
+	Arguments:
+		pAd	Pointer	to our adapter
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+VOID	WpaMacHeaderInit(
+	IN		PRTMP_ADAPTER	pAd,
+	IN OUT	PHEADER_802_11	pHdr80211,
+	IN		UCHAR			wep,
+	IN		PUCHAR		    pAddr1)
+{
+	NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
+	pHdr80211->FC.Type	= BTYPE_DATA;
+	pHdr80211->FC.ToDs	= 1;
+	if (wep	== 1)
+		pHdr80211->FC.Wep = 1;
+
+	 //	Addr1: BSSID, Addr2: SA, Addr3:	DA
+	COPY_MAC_ADDR(pHdr80211->Addr1, pAddr1);
+	COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
+	COPY_MAC_ADDR(pHdr80211->Addr3, pAd->CommonCfg.Bssid);
+	pHdr80211->Sequence =	pAd->Sequence;
+}
+
+/*
+	========================================================================
+
+	Routine	Description:
+		Copy frame from waiting queue into relative ring buffer and set
+	appropriate ASIC register to kick hardware encryption before really
+	sent out to air.
+
+	Arguments:
+		pAd		Pointer	to our adapter
+		PNDIS_PACKET	Pointer to outgoing Ndis frame
+		NumberOfFrag	Number of fragment required
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+VOID    RTMPToWirelessSta(
+	IN	PRTMP_ADAPTER	pAd,
+	IN  PUCHAR          pHeader802_3,
+    IN  UINT            HdrLen,
+	IN  PUCHAR          pData,
+    IN  UINT            DataLen,
+    IN	BOOLEAN			is4wayFrame)
+
+{
+	NDIS_STATUS     Status;
+	PNDIS_PACKET    pPacket;
+	UCHAR   Index;
+
+	do
+	{
+		// 1. build a NDIS packet and call RTMPSendPacket();
+		//    be careful about how/when to release this internal allocated NDIS PACKET buffer
+		Status = RTMPAllocateNdisPacket(pAd, &pPacket, pHeader802_3, HdrLen, pData, DataLen);
+		if (Status != NDIS_STATUS_SUCCESS)
+			break;
+
+		if (is4wayFrame)
+			RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 1);
+		else
+			RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 0);
+
+		// 2. send out the packet
+		Status = STASendPacket(pAd, pPacket);
+		if(Status == NDIS_STATUS_SUCCESS)
+		{
+			// Dequeue one frame from TxSwQueue0..3 queue and process it
+			// There are three place calling dequeue for TX ring.
+			// 1. Here, right after queueing the frame.
+			// 2. At the end of TxRingTxDone service routine.
+			// 3. Upon NDIS call RTMPSendPackets
+			if((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
+				(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)))
+			{
+				for(Index = 0; Index < 5; Index ++)
+					if(pAd->TxSwQueue[Index].Number > 0)
+						RTMPDeQueuePacket(pAd, FALSE, Index, MAX_TX_PROCESS);
+			}
+		}
+	} while(FALSE);
+
+}
+
+/*
+    ========================================================================
+
+    Routine Description:
+    Check Sanity RSN IE form AP
+
+    Arguments:
+
+    Return Value:
+
+
+    ========================================================================
+*/
+BOOLEAN CheckRSNIE(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR          pData,
+	IN  UCHAR           DataLen,
+	OUT	UCHAR			*Offset)
+{
+	PUCHAR              pVIE;
+	UCHAR               len;
+	PEID_STRUCT         pEid;
+	BOOLEAN				result = FALSE;
+
+	pVIE = pData;
+	len	 = DataLen;
+	*Offset = 0;
+
+	while (len > sizeof(RSNIE2))
+	{
+		pEid = (PEID_STRUCT) pVIE;
+		// WPA RSN IE
+		if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)))
+		{
+			if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) &&
+				(NdisEqualMemory(pVIE, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len)) &&
+				(pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == (pEid->Len + 2)))
+			{
+					DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> WPA/WPAPSK RSN IE matched in Msg 3, Length(%d) \n", (pEid->Len + 2)));
+					result = TRUE;
+			}
+
+			*Offset += (pEid->Len + 2);
+		}
+		// WPA2 RSN IE
+		else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3)))
+		{
+			if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2 || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) &&
+				(NdisEqualMemory(pVIE, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len)) &&
+				(pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == (pEid->Len + 2)))
+			{
+					DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", (pEid->Len + 2)));
+					result = TRUE;
+			}
+
+			*Offset += (pEid->Len + 2);
+		}
+		else
+		{
+			break;
+		}
+
+		pVIE += (pEid->Len + 2);
+		len  -= (pEid->Len + 2);
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> skip_offset(%d) \n", *Offset));
+
+	return result;
+
+}
+
+
+/*
+    ========================================================================
+
+    Routine Description:
+    Parse KEYDATA field.  KEYDATA[] May contain 2 RSN IE and optionally GTK.
+    GTK  is encaptulated in KDE format at  p.83 802.11i D10
+
+    Arguments:
+
+    Return Value:
+
+    Note:
+        802.11i D10
+
+    ========================================================================
+*/
+BOOLEAN ParseKeyData(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR          pKeyData,
+	IN  UCHAR           KeyDataLen,
+	IN	UCHAR			bPairewise)
+{
+    PKDE_ENCAP          pKDE = NULL;
+    PUCHAR              pMyKeyData = pKeyData;
+    UCHAR               KeyDataLength = KeyDataLen;
+    UCHAR               GTKLEN;
+	UCHAR				skip_offset;
+
+	// Verify The RSN IE contained in Pairewise-Msg 3 and skip it
+	if (bPairewise)
+    {
+		// Check RSN IE whether it is WPA2/WPA2PSK
+		if (!CheckRSNIE(pAd, pKeyData, KeyDataLen, &skip_offset))
+		{
+			DBGPRINT(RT_DEBUG_ERROR, ("ParseKeyData ==> WPA2/WPA2PSK RSN IE mismatched \n"));
+			hex_dump("Get KEYDATA :", pKeyData, KeyDataLen);
+			return FALSE;
+    	}
+    	else
+		{
+			// skip RSN IE
+			pMyKeyData += skip_offset;
+			KeyDataLength -= skip_offset;
+
+			//DBGPRINT(RT_DEBUG_TRACE, ("ParseKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", skip_offset));
+		}
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE,("ParseKeyData ==> KeyDataLength %d without RSN_IE \n", KeyDataLength));
+
+	// Parse EKD format
+	if (KeyDataLength >= 8)
+    {
+        pKDE = (PKDE_ENCAP) pMyKeyData;
+    }
+	else
+    {
+		DBGPRINT(RT_DEBUG_ERROR, ("ERROR: KeyDataLength is too short \n"));
+        return FALSE;
+    }
+
+
+	// Sanity check - shared key index should not be 0
+	if (pKDE->GTKEncap.Kid == 0)
+    {
+        DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key index zero \n"));
+        return FALSE;
+    }
+
+	// Sanity check - KED length
+	if (KeyDataLength < (pKDE->Len + 2))
+    {
+        DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The len from KDE is too short \n"));
+        return FALSE;
+    }
+
+	// Get GTK length - refer to IEEE 802.11i-2004 p.82
+	GTKLEN = pKDE->Len -6;
+
+	if (GTKLEN < LEN_AES_KEY)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN));
+        return FALSE;
+	}
+	else
+		DBGPRINT(RT_DEBUG_TRACE, ("GTK Key with KDE formet got index=%d, len=%d \n", pKDE->GTKEncap.Kid, GTKLEN));
+
+	// Update GTK
+	// set key material, TxMic and RxMic for WPAPSK
+	NdisMoveMemory(pAd->StaCfg.GTK, pKDE->GTKEncap.GTK, 32);
+	pAd->StaCfg.DefaultKeyId = pKDE->GTKEncap.Kid;
+
+	// Update shared key table
+	NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
+	pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
+	NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pKDE->GTKEncap.GTK, LEN_TKIP_EK);
+	NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, &pKDE->GTKEncap.GTK[16], LEN_TKIP_RXMICK);
+	NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, &pKDE->GTKEncap.GTK[24], LEN_TKIP_TXMICK);
+
+	// Update Shared Key CipherAlg
+	pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
+	if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
+		pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
+	else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
+		pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
+
+	return TRUE;
+
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Cisco CCKM PRF function
+
+	Arguments:
+		key				Cisco Base Transient Key (BTK)
+		key_len			The key length of the BTK
+		data			Ruquest Number(RN) + BSSID
+		data_len		The length of the data
+		output			Store for PTK(Pairwise transient keys)
+		len				The length of the output
+	Return Value:
+		None
+
+	Note:
+		802.1i	Annex F.9
+
+	========================================================================
+*/
+VOID CCKMPRF(
+	IN	UCHAR	*key,
+	IN	INT		key_len,
+	IN	UCHAR	*data,
+	IN	INT		data_len,
+	OUT	UCHAR	*output,
+	IN	INT		len)
+{
+	INT		i;
+	UCHAR	input[1024];
+	INT		currentindex = 0;
+	INT		total_len;
+
+	NdisMoveMemory(input, data, data_len);
+	total_len = data_len;
+	input[total_len] = 0;
+	total_len++;
+	for	(i = 0;	i <	(len + 19) / 20; i++)
+	{
+		HMAC_SHA1(input, total_len,	key, key_len, &output[currentindex]);
+		currentindex +=	20;
+		input[total_len - 1]++;
+	}
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Process MIC error indication and record MIC error timer.
+
+	Arguments:
+		pAd 	Pointer to our adapter
+		pWpaKey 		Pointer to the WPA key structure
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTMPReportMicError(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PCIPHER_KEY 	pWpaKey)
+{
+	ULONG	Now;
+    UCHAR   unicastKey = (pWpaKey->Type == PAIRWISE_KEY ? 1:0);
+
+	// Record Last MIC error time and count
+	Now = jiffies;
+	if (pAd->StaCfg.MicErrCnt == 0)
+	{
+		pAd->StaCfg.MicErrCnt++;
+		pAd->StaCfg.LastMicErrorTime = Now;
+        NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
+	}
+	else if (pAd->StaCfg.MicErrCnt == 1)
+	{
+		if ((pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ)) < Now)
+		{
+			// Update Last MIC error time, this did not violate two MIC errors within 60 seconds
+			pAd->StaCfg.LastMicErrorTime = Now;
+		}
+		else
+		{
+
+			if (pAd->CommonCfg.bWirelessEvent)
+				RTMPSendWirelessEvent(pAd, IW_COUNTER_MEASURES_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+
+			pAd->StaCfg.LastMicErrorTime = Now;
+			// Violate MIC error counts, MIC countermeasures kicks in
+			pAd->StaCfg.MicErrCnt++;
+			// We shall block all reception
+			// We shall clean all Tx ring and disassoicate from AP after next EAPOL frame
+			//
+			// No necessary to clean all Tx ring, on RTMPHardTransmit will stop sending non-802.1X EAPOL packets
+			// if pAd->StaCfg.MicErrCnt greater than 2.
+			//
+			// RTMPRingCleanUp(pAd, QID_AC_BK);
+			// RTMPRingCleanUp(pAd, QID_AC_BE);
+			// RTMPRingCleanUp(pAd, QID_AC_VI);
+			// RTMPRingCleanUp(pAd, QID_AC_VO);
+			// RTMPRingCleanUp(pAd, QID_HCCA);
+		}
+	}
+	else
+	{
+		// MIC error count >= 2
+		// This should not happen
+		;
+	}
+    MlmeEnqueue(pAd,
+				MLME_CNTL_STATE_MACHINE,
+				OID_802_11_MIC_FAILURE_REPORT_FRAME,
+				1,
+				&unicastKey);
+
+    if (pAd->StaCfg.MicErrCnt == 2)
+    {
+        RTMPSetTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, 100);
+    }
+}
+
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#define	LENGTH_EAP_H    4
+// If the received frame is EAP-Packet ,find out its EAP-Code (Request(0x01), Response(0x02), Success(0x03), Failure(0x04)).
+INT	    WpaCheckEapCode(
+	IN  PRTMP_ADAPTER   		pAd,
+	IN  PUCHAR				pFrame,
+	IN  USHORT				FrameLen,
+	IN  USHORT				OffSet)
+{
+
+	PUCHAR	pData;
+	INT	result = 0;
+
+	if( FrameLen < OffSet + LENGTH_EAPOL_H + LENGTH_EAP_H )
+		return result;
+
+	pData = pFrame + OffSet; // skip offset bytes
+
+	if(*(pData+1) == EAPPacket) 	// 802.1x header - Packet Type
+	{
+		 result = *(pData+4);		// EAP header - Code
+	}
+
+	return result;
+}
+
+VOID    WpaSendMicFailureToWpaSupplicant(
+    IN  PRTMP_ADAPTER    pAd,
+    IN  BOOLEAN          bUnicast)
+{
+    union iwreq_data    wrqu;
+    char custom[IW_CUSTOM_MAX] = {0};
+
+    sprintf(custom, "MLME-MICHAELMICFAILURE.indication");
+    if (bUnicast)
+        sprintf(custom, "%s unicast", custom);
+    wrqu.data.length = strlen(custom);
+    wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, custom);
+
+    return;
+}
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+VOID	WpaMicFailureReportFrame(
+	IN  PRTMP_ADAPTER   pAd,
+	IN MLME_QUEUE_ELEM *Elem)
+{
+	PUCHAR              pOutBuffer = NULL;
+	UCHAR               Header802_3[14];
+	ULONG               FrameLen = 0;
+	EAPOL_PACKET        Packet;
+	UCHAR               Mic[16];
+    BOOLEAN             bUnicast;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame ----->\n"));
+
+    bUnicast = (Elem->Msg[0] == 1 ? TRUE:FALSE);
+	pAd->Sequence = ((pAd->Sequence) + 1) & (MAX_SEQ_NUMBER);
+
+	// init 802.3 header and Fill Packet
+	MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
+
+	NdisZeroMemory(&Packet, sizeof(Packet));
+	Packet.ProVer	= EAPOL_VER;
+	Packet.ProType	= EAPOLKey;
+
+	Packet.KeyDesc.Type = WPA1_KEY_DESC;
+
+    // Request field presented
+    Packet.KeyDesc.KeyInfo.Request = 1;
+
+	if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
+	{
+		Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
+	}
+	else	  // TKIP
+	{
+		Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
+	}
+
+    Packet.KeyDesc.KeyInfo.KeyType = (bUnicast ? PAIRWISEKEY : GROUPKEY);
+
+	// KeyMic field presented
+	Packet.KeyDesc.KeyInfo.KeyMic  = 1;
+
+    // Error field presented
+	Packet.KeyDesc.KeyInfo.Error  = 1;
+
+	// Update packet length after decide Key data payload
+	Packet.Body_Len[1]  = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE;
+
+	// Key Replay Count
+	NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
+    inc_byte_array(pAd->StaCfg.ReplayCounter, 8);
+
+	// Convert to little-endian format.
+	*((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
+
+
+	MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer);  // allocate memory
+	if(pOutBuffer == NULL)
+	{
+		return;
+	}
+
+	// Prepare EAPOL frame for MIC calculation
+	// Be careful, only EAPOL frame is counted for MIC calculation
+	MakeOutgoingFrame(pOutBuffer,               &FrameLen,
+		              Packet.Body_Len[1] + 4,   &Packet,
+		              END_OF_ARGS);
+
+	// Prepare and Fill MIC value
+	NdisZeroMemory(Mic, sizeof(Mic));
+	if(pAd->StaCfg.WepStatus  == Ndis802_11Encryption3Enabled)
+	{	// AES
+        UCHAR digest[20] = {0};
+		HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
+		NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+	}
+	else
+	{	// TKIP
+		hmac_md5(pAd->StaCfg.PTK,  LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
+	}
+	NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
+
+    MakeOutgoingFrame(pOutBuffer,           	&FrameLen,
+    	  			LENGTH_802_3,     			&Header802_3,
+    				Packet.Body_Len[1] + 4,     &Packet,
+    				END_OF_ARGS);
+
+	// opy frame to Tx ring and send MIC failure report frame to authenticator
+	RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, FALSE);
+
+	MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame <-----\n"));
+}
+
+/** from wpa_supplicant
+ * inc_byte_array - Increment arbitrary length byte array by one
+ * @counter: Pointer to byte array
+ * @len: Length of the counter in bytes
+ *
+ * This function increments the last byte of the counter by one and continues
+ * rolling over to more significant bytes if the byte was incremented from
+ * 0xff to 0x00.
+ */
+void inc_byte_array(UCHAR *counter, int len)
+{
+	int pos = len - 1;
+	while (pos >= 0) {
+		counter[pos]++;
+		if (counter[pos] != 0)
+			break;
+		pos--;
+	}
+}
+
+VOID WpaDisassocApAndBlockAssoc(
+    IN PVOID SystemSpecific1,
+    IN PVOID FunctionContext,
+    IN PVOID SystemSpecific2,
+    IN PVOID SystemSpecific3)
+{
+    RTMP_ADAPTER                *pAd = (PRTMP_ADAPTER)FunctionContext;
+    MLME_DISASSOC_REQ_STRUCT    DisassocReq;
+
+	// disassoc from current AP first
+	DBGPRINT(RT_DEBUG_TRACE, ("RTMPReportMicError - disassociate with current AP after sending second continuous EAPOL frame\n"));
+	DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_MIC_FAILURE);
+	MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
+
+	pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
+	pAd->StaCfg.bBlockAssoc = TRUE;
+}
+
diff --git a/drivers/staging/rt3070/sta_ioctl.c b/drivers/staging/rt3070/sta_ioctl.c
new file mode 100644
index 0000000..0794548
--- /dev/null
+++ b/drivers/staging/rt3070/sta_ioctl.c
@@ -0,0 +1,7203 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+    Module Name:
+    sta_ioctl.c
+
+    Abstract:
+    IOCTL related subroutines
+
+    Revision History:
+    Who         When          What
+    --------    ----------    ----------------------------------------------
+    Rory Chen   01-03-2003    created
+	Rory Chen   02-14-2005    modify to support RT61
+*/
+
+#include	"rt_config.h"
+
+#ifdef DBG
+extern ULONG    RTDebugLevel;
+#endif
+
+#define NR_WEP_KEYS 				4
+#define WEP_SMALL_KEY_LEN 			(40/8)
+#define WEP_LARGE_KEY_LEN 			(104/8)
+
+#define GROUP_KEY_NO                4
+
+extern UCHAR    CipherWpa2Template[];
+extern UCHAR    CipherWpaPskTkip[];
+extern UCHAR    CipherWpaPskTkipLen;
+
+typedef struct PACKED _RT_VERSION_INFO{
+    UCHAR       DriverVersionW;
+    UCHAR       DriverVersionX;
+    UCHAR       DriverVersionY;
+    UCHAR       DriverVersionZ;
+    UINT        DriverBuildYear;
+    UINT        DriverBuildMonth;
+    UINT        DriverBuildDay;
+} RT_VERSION_INFO, *PRT_VERSION_INFO;
+
+struct iw_priv_args privtab[] = {
+{ RTPRIV_IOCTL_SET,
+  IW_PRIV_TYPE_CHAR | 1024, 0,
+  "set"},
+
+{ RTPRIV_IOCTL_SHOW, 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
+  ""},
+{ RTPRIV_IOCTL_SHOW, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
+  ""},
+/* --- sub-ioctls definitions --- */
+    { SHOW_CONN_STATUS,
+	  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "connStatus" },
+	{ SHOW_DRVIER_VERION,
+	  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "driverVer" },
+    { SHOW_BA_INFO,
+	  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "bainfo" },
+	{ SHOW_DESC_INFO,
+	  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "descinfo" },
+    { RAIO_OFF,
+	  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_off" },
+	{ RAIO_ON,
+	  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_on" },
+#ifdef QOS_DLS_SUPPORT
+	{ SHOW_DLS_ENTRY_INFO,
+	  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "dlsentryinfo" },
+#endif // QOS_DLS_SUPPORT //
+	{ SHOW_CFG_VALUE,
+	  IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "show" },
+/* --- sub-ioctls relations --- */
+
+#ifdef DBG
+{ RTPRIV_IOCTL_BBP,
+  IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
+  "bbp"},
+{ RTPRIV_IOCTL_MAC,
+  IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
+  "mac"},
+#ifdef RT30xx
+{ RTPRIV_IOCTL_RF,
+  IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
+  "rf"},
+#endif // RT30xx //
+{ RTPRIV_IOCTL_E2P,
+  IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
+  "e2p"},
+#endif  /* DBG */
+
+{ RTPRIV_IOCTL_STATISTICS,
+  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
+  "stat"},
+{ RTPRIV_IOCTL_GSITESURVEY,
+  0, IW_PRIV_TYPE_CHAR | 1024,
+  "get_site_survey"},
+
+
+};
+
+INT Set_SSID_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          arg);
+
+#ifdef WMM_SUPPORT
+INT	Set_WmmCapable_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+#endif
+
+INT Set_NetworkType_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          arg);
+
+INT Set_AuthMode_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          arg);
+
+INT Set_EncrypType_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          arg);
+
+INT Set_DefaultKeyID_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          arg);
+
+INT Set_Key1_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          arg);
+
+INT Set_Key2_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          arg);
+
+INT Set_Key3_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          arg);
+
+INT Set_Key4_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          arg);
+
+INT Set_WPAPSK_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          arg);
+
+
+INT Set_PSMode_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          arg);
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+INT Set_Wpa_Support(
+    IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef DBG
+
+VOID RTMPIoctlMAC(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq);
+
+VOID RTMPIoctlE2PROM(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  struct iwreq    *wrq);
+
+#ifdef RT30xx
+VOID RTMPIoctlRF(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  struct iwreq    *wrq);
+#endif // RT30xx //
+#endif // DBG //
+
+
+NDIS_STATUS RTMPWPANoneAddKeyProc(
+    IN  PRTMP_ADAPTER   pAd,
+    IN	PVOID			pBuf);
+
+INT Set_FragTest_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          arg);
+
+#ifdef DOT11_N_SUPPORT
+INT Set_TGnWifiTest_Proc(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  PUCHAR          arg);
+#endif // DOT11_N_SUPPORT //
+
+INT Set_LongRetryLimit_Proc(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	PUCHAR			arg);
+
+INT Set_ShortRetryLimit_Proc(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	PUCHAR			arg);
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+INT Set_Ieee80211dClientMode_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          arg);
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+#ifdef CARRIER_DETECTION_SUPPORT
+INT Set_CarrierDetect_Proc(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  PUCHAR          arg);
+#endif // CARRIER_DETECTION_SUPPORT //
+
+static struct {
+	CHAR *name;
+	INT (*set_proc)(PRTMP_ADAPTER pAdapter, PUCHAR arg);
+} *PRTMP_PRIVATE_SET_PROC, RTMP_PRIVATE_SUPPORT_PROC[] = {
+	{"DriverVersion",				Set_DriverVersion_Proc},
+	{"CountryRegion",				Set_CountryRegion_Proc},
+	{"CountryRegionABand",			Set_CountryRegionABand_Proc},
+	{"SSID",						Set_SSID_Proc},
+	{"WirelessMode",				Set_WirelessMode_Proc},
+	{"TxBurst",					Set_TxBurst_Proc},
+	{"TxPreamble",				Set_TxPreamble_Proc},
+	{"TxPower",					Set_TxPower_Proc},
+	{"Channel",					Set_Channel_Proc},
+	{"BGProtection",				Set_BGProtection_Proc},
+	{"RTSThreshold",				Set_RTSThreshold_Proc},
+	{"FragThreshold",				Set_FragThreshold_Proc},
+#ifdef DOT11_N_SUPPORT
+	{"HtBw",		                Set_HtBw_Proc},
+	{"HtMcs",		                Set_HtMcs_Proc},
+	{"HtGi",		                Set_HtGi_Proc},
+	{"HtOpMode",		            Set_HtOpMode_Proc},
+	{"HtExtcha",		            Set_HtExtcha_Proc},
+	{"HtMpduDensity",		        Set_HtMpduDensity_Proc},
+	{"HtBaWinSize",		        	Set_HtBaWinSize_Proc},
+	{"HtRdg",		        		Set_HtRdg_Proc},
+	{"HtAmsdu",		        		Set_HtAmsdu_Proc},
+	{"HtAutoBa",		        	Set_HtAutoBa_Proc},
+	{"HtBaDecline",					Set_BADecline_Proc},
+	{"HtProtect",		        	Set_HtProtect_Proc},
+	{"HtMimoPs",		        	Set_HtMimoPs_Proc},
+#endif // DOT11_N_SUPPORT //
+
+#ifdef AGGREGATION_SUPPORT
+	{"PktAggregate",				Set_PktAggregate_Proc},
+#endif
+
+#ifdef WMM_SUPPORT
+	{"WmmCapable",					Set_WmmCapable_Proc},
+#endif
+	{"IEEE80211H",					Set_IEEE80211H_Proc},
+    {"NetworkType",                 Set_NetworkType_Proc},
+	{"AuthMode",					Set_AuthMode_Proc},
+	{"EncrypType",					Set_EncrypType_Proc},
+	{"DefaultKeyID",				Set_DefaultKeyID_Proc},
+	{"Key1",						Set_Key1_Proc},
+	{"Key2",						Set_Key2_Proc},
+	{"Key3",						Set_Key3_Proc},
+	{"Key4",						Set_Key4_Proc},
+	{"WPAPSK",						Set_WPAPSK_Proc},
+	{"ResetCounter",				Set_ResetStatCounter_Proc},
+	{"PSMode",                      Set_PSMode_Proc},
+#ifdef DBG
+	{"Debug",						Set_Debug_Proc},
+#endif
+
+#ifdef RALINK_ATE
+	{"ATE",							Set_ATE_Proc},
+	{"ATEDA",						Set_ATE_DA_Proc},
+	{"ATESA",						Set_ATE_SA_Proc},
+	{"ATEBSSID",					Set_ATE_BSSID_Proc},
+	{"ATECHANNEL",					Set_ATE_CHANNEL_Proc},
+	{"ATETXPOW0",					Set_ATE_TX_POWER0_Proc},
+	{"ATETXPOW1",					Set_ATE_TX_POWER1_Proc},
+	{"ATETXANT",					Set_ATE_TX_Antenna_Proc},
+	{"ATERXANT",					Set_ATE_RX_Antenna_Proc},
+	{"ATETXFREQOFFSET",				Set_ATE_TX_FREQOFFSET_Proc},
+	{"ATETXBW",						Set_ATE_TX_BW_Proc},
+	{"ATETXLEN",					Set_ATE_TX_LENGTH_Proc},
+	{"ATETXCNT",					Set_ATE_TX_COUNT_Proc},
+	{"ATETXMCS",					Set_ATE_TX_MCS_Proc},
+	{"ATETXMODE",					Set_ATE_TX_MODE_Proc},
+	{"ATETXGI",						Set_ATE_TX_GI_Proc},
+	{"ATERXFER",					Set_ATE_RX_FER_Proc},
+	{"ATERRF",						Set_ATE_Read_RF_Proc},
+	{"ATEWRF1",						Set_ATE_Write_RF1_Proc},
+	{"ATEWRF2",						Set_ATE_Write_RF2_Proc},
+	{"ATEWRF3",						Set_ATE_Write_RF3_Proc},
+	{"ATEWRF4",						Set_ATE_Write_RF4_Proc},
+	{"ATELDE2P",				    Set_ATE_Load_E2P_Proc},
+	{"ATERE2P",						Set_ATE_Read_E2P_Proc},
+	{"ATESHOW",						Set_ATE_Show_Proc},
+	{"ATEHELP",						Set_ATE_Help_Proc},
+
+#ifdef RALINK_28xx_QA
+	{"TxStop",						Set_TxStop_Proc},
+	{"RxStop",						Set_RxStop_Proc},
+#endif // RALINK_28xx_QA //
+#endif // RALINK_ATE //
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+    {"WpaSupport",                  Set_Wpa_Support},
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+
+
+	{"FixedTxMode",                 Set_FixedTxMode_Proc},
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+	{"OpMode",						Set_OpMode_Proc},
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+#ifdef DOT11_N_SUPPORT
+    {"TGnWifiTest",                 Set_TGnWifiTest_Proc},
+    {"ForceGF",		        		Set_ForceGF_Proc},
+#endif // DOT11_N_SUPPORT //
+#ifdef QOS_DLS_SUPPORT
+	{"DlsAddEntry",					Set_DlsAddEntry_Proc},
+	{"DlsTearDownEntry",			Set_DlsTearDownEntry_Proc},
+#endif // QOS_DLS_SUPPORT //
+	{"LongRetry",	        		Set_LongRetryLimit_Proc},
+	{"ShortRetry",	        		Set_ShortRetryLimit_Proc},
+#ifdef EXT_BUILD_CHANNEL_LIST
+	{"11dClientMode",				Set_Ieee80211dClientMode_Proc},
+#endif // EXT_BUILD_CHANNEL_LIST //
+#ifdef CARRIER_DETECTION_SUPPORT
+	{"CarrierDetect",				Set_CarrierDetect_Proc},
+#endif // CARRIER_DETECTION_SUPPORT //
+//2008/09/11:KH add to support efuse<--
+#ifdef RT30xx
+	{"efuseFreeNumber",				set_eFuseGetFreeBlockCount_Proc},
+	{"efuseDump",					set_eFusedump_Proc},
+	{"efuseLoadFromBin",				set_eFuseLoadFromBin_Proc},
+#endif // RT30xx //
+//2008/09/11:KH add to support efuse-->
+	{NULL,}
+};
+
+
+VOID RTMPAddKey(
+	IN	PRTMP_ADAPTER	    pAd,
+	IN	PNDIS_802_11_KEY    pKey)
+{
+	ULONG				KeyIdx;
+	MAC_TABLE_ENTRY  	*pEntry;
+
+    DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey ------>\n"));
+
+	if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+	{
+		if (pKey->KeyIndex & 0x80000000)
+		{
+		    if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+            {
+                NdisZeroMemory(pAd->StaCfg.PMK, 32);
+                NdisMoveMemory(pAd->StaCfg.PMK, pKey->KeyMaterial, pKey->KeyLength);
+                goto end;
+            }
+		    // Update PTK
+		    NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
+            pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
+            NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pKey->KeyMaterial, LEN_TKIP_EK);
+#ifdef WPA_SUPPLICANT_SUPPORT
+            if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+            {
+                NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
+                NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
+            }
+            else
+#endif // WPA_SUPPLICANT_SUPPORT //
+            {
+            	NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
+                NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
+            }
+
+            // Decide its ChiperAlg
+        	if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+        		pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
+        	else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
+        		pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
+        	else
+        		pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
+
+            // Update these related information to MAC_TABLE_ENTRY
+        	pEntry = &pAd->MacTab.Content[BSSID_WCID];
+            NdisMoveMemory(pEntry->PairwiseKey.Key, pAd->SharedKey[BSS0][0].Key, LEN_TKIP_EK);
+        	NdisMoveMemory(pEntry->PairwiseKey.RxMic, pAd->SharedKey[BSS0][0].RxMic, LEN_TKIP_RXMICK);
+        	NdisMoveMemory(pEntry->PairwiseKey.TxMic, pAd->SharedKey[BSS0][0].TxMic, LEN_TKIP_TXMICK);
+        	pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
+
+        	// Update pairwise key information to ASIC Shared Key Table
+        	AsicAddSharedKeyEntry(pAd,
+        						  BSS0,
+        						  0,
+        						  pAd->SharedKey[BSS0][0].CipherAlg,
+        						  pAd->SharedKey[BSS0][0].Key,
+        						  pAd->SharedKey[BSS0][0].TxMic,
+        						  pAd->SharedKey[BSS0][0].RxMic);
+
+        	// Update ASIC WCID attribute table and IVEIV table
+        	RTMPAddWcidAttributeEntry(pAd,
+        							  BSS0,
+        							  0,
+        							  pAd->SharedKey[BSS0][0].CipherAlg,
+        							  pEntry);
+
+            if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
+            {
+                // set 802.1x port control
+	            //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+				STA_PORT_SECURED(pAd);
+
+                // Indicate Connected for GUI
+                pAd->IndicateMediaState = NdisMediaStateConnected;
+            }
+		}
+        else
+        {
+            // Update GTK
+            pAd->StaCfg.DefaultKeyId = (pKey->KeyIndex & 0xFF);
+            NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
+            pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
+            NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pKey->KeyMaterial, LEN_TKIP_EK);
+#ifdef WPA_SUPPLICANT_SUPPORT
+            if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
+            {
+                NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
+                NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
+            }
+            else
+#endif // WPA_SUPPLICANT_SUPPORT //
+            {
+            	NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
+                NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
+            }
+
+            // Update Shared Key CipherAlg
+    		pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
+    		if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
+    			pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
+    		else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
+    			pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
+
+            // Update group key information to ASIC Shared Key Table
+        	AsicAddSharedKeyEntry(pAd,
+        						  BSS0,
+        						  pAd->StaCfg.DefaultKeyId,
+        						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
+        						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
+        						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
+        						  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
+
+        	// Update ASIC WCID attribute table and IVEIV table
+        	RTMPAddWcidAttributeEntry(pAd,
+        							  BSS0,
+        							  pAd->StaCfg.DefaultKeyId,
+        							  pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
+        							  NULL);
+
+            // set 802.1x port control
+	        //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+			STA_PORT_SECURED(pAd);
+
+            // Indicate Connected for GUI
+            pAd->IndicateMediaState = NdisMediaStateConnected;
+        }
+	}
+	else	// dynamic WEP from wpa_supplicant
+	{
+		UCHAR	CipherAlg;
+    	PUCHAR	Key;
+
+		if(pKey->KeyLength == 32)
+			goto end;
+
+		KeyIdx = pKey->KeyIndex & 0x0fffffff;
+
+		if (KeyIdx < 4)
+		{
+			// it is a default shared key, for Pairwise key setting
+			if (pKey->KeyIndex & 0x80000000)
+			{
+				pEntry = MacTableLookup(pAd, pKey->BSSID);
+
+				if (pEntry)
+				{
+					DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey: Set Pair-wise Key\n"));
+
+					// set key material and key length
+ 					pEntry->PairwiseKey.KeyLen = (UCHAR)pKey->KeyLength;
+					NdisMoveMemory(pEntry->PairwiseKey.Key, &pKey->KeyMaterial, pKey->KeyLength);
+
+					// set Cipher type
+					if (pKey->KeyLength == 5)
+						pEntry->PairwiseKey.CipherAlg = CIPHER_WEP64;
+					else
+						pEntry->PairwiseKey.CipherAlg = CIPHER_WEP128;
+
+					// Add Pair-wise key to Asic
+					AsicAddPairwiseKeyEntry(
+						pAd,
+						pEntry->Addr,
+						(UCHAR)pEntry->Aid,
+                		&pEntry->PairwiseKey);
+
+					// update WCID attribute table and IVEIV table for this entry
+					RTMPAddWcidAttributeEntry(
+						pAd,
+						BSS0,
+						KeyIdx, // The value may be not zero
+						pEntry->PairwiseKey.CipherAlg,
+						pEntry);
+
+				}
+			}
+			else
+            {
+				// Default key for tx (shared key)
+				pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
+
+				// set key material and key length
+				pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pKey->KeyLength;
+				NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pKey->KeyMaterial, pKey->KeyLength);
+
+				// Set Ciper type
+				if (pKey->KeyLength == 5)
+					pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP64;
+				else
+					pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP128;
+
+    			CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
+    			Key = pAd->SharedKey[BSS0][KeyIdx].Key;
+
+				// Set Group key material to Asic
+    			AsicAddSharedKeyEntry(pAd, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
+
+				// Update WCID attribute table and IVEIV table for this group key table
+				RTMPAddWcidAttributeEntry(pAd, BSS0, KeyIdx, CipherAlg, NULL);
+
+			}
+		}
+	}
+end:
+	return;
+}
+
+char * rtstrchr(const char * s, int c)
+{
+    for(; *s != (char) c; ++s)
+        if (*s == '\0')
+            return NULL;
+    return (char *) s;
+}
+
+/*
+This is required for LinEX2004/kernel2.6.7 to provide iwlist scanning function
+*/
+
+int
+rt_ioctl_giwname(struct net_device *dev,
+		   struct iw_request_info *info,
+		   char *name, char *extra)
+{
+//	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+#ifdef RT2870
+	strncpy(name, "RT2870 Wireless", IFNAMSIZ);
+#endif // RT2870 //
+	return 0;
+}
+
+int rt_ioctl_siwfreq(struct net_device *dev,
+			struct iw_request_info *info,
+			struct iw_freq *freq, char *extra)
+{
+	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+	int 	chan = -1;
+
+    //check if the interface is down
+    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+    {
+        DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+        return -ENETDOWN;
+    }
+
+
+	if (freq->e > 1)
+		return -EINVAL;
+
+	if((freq->e == 0) && (freq->m <= 1000))
+		chan = freq->m;	// Setting by channel number
+	else
+		MAP_KHZ_TO_CHANNEL_ID( (freq->m /100) , chan); // Setting by frequency - search the table , like 2.412G, 2.422G,
+
+    if (ChannelSanity(pAdapter, chan) == TRUE)
+    {
+	pAdapter->CommonCfg.Channel = chan;
+	DBGPRINT(RT_DEBUG_ERROR, ("==>rt_ioctl_siwfreq::SIOCSIWFREQ[cmd=0x%x] (Channel=%d)\n", SIOCSIWFREQ, pAdapter->CommonCfg.Channel));
+    }
+    else
+        return -EINVAL;
+
+	return 0;
+}
+int rt_ioctl_giwfreq(struct net_device *dev,
+		   struct iw_request_info *info,
+		   struct iw_freq *freq, char *extra)
+{
+    VIRTUAL_ADAPTER *pVirtualAd = NULL;
+	PRTMP_ADAPTER pAdapter;
+	UCHAR ch;
+	ULONG	m;
+
+	if (dev->priv_flags == INT_MAIN)
+	{
+		pAdapter = dev->ml_priv;
+	}
+	else
+	{
+		pVirtualAd = dev->ml_priv;
+		pAdapter = pVirtualAd->RtmpDev->ml_priv;
+	}
+
+	if (pAdapter == NULL)
+	{
+		/* if 1st open fail, pAd will be free;
+		   So the net_dev->ml_priv will be NULL in 2rd open */
+		return -ENETDOWN;
+	}
+
+		ch = pAdapter->CommonCfg.Channel;
+
+	DBGPRINT(RT_DEBUG_TRACE,("==>rt_ioctl_giwfreq  %d\n", ch));
+
+    MAP_CHANNEL_ID_TO_KHZ(ch, m);
+	freq->m = m * 100;
+	freq->e = 1;
+	return 0;
+}
+
+int rt_ioctl_siwmode(struct net_device *dev,
+		   struct iw_request_info *info,
+		   __u32 *mode, char *extra)
+{
+	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+	//check if the interface is down
+    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+    {
+    	DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+       	return -ENETDOWN;
+    }
+
+	switch (*mode)
+	{
+		case IW_MODE_ADHOC:
+			Set_NetworkType_Proc(pAdapter, "Adhoc");
+			break;
+		case IW_MODE_INFRA:
+			Set_NetworkType_Proc(pAdapter, "Infra");
+			break;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
+        case IW_MODE_MONITOR:
+			Set_NetworkType_Proc(pAdapter, "Monitor");
+			break;
+#endif
+		default:
+			DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_siwmode::SIOCSIWMODE (unknown %d)\n", *mode));
+			return -EINVAL;
+	}
+
+	// Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
+	pAdapter->StaCfg.WpaState = SS_NOTUSE;
+
+	return 0;
+}
+
+int rt_ioctl_giwmode(struct net_device *dev,
+		   struct iw_request_info *info,
+		   __u32 *mode, char *extra)
+{
+	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+	if (ADHOC_ON(pAdapter))
+		*mode = IW_MODE_ADHOC;
+    else if (INFRA_ON(pAdapter))
+		*mode = IW_MODE_INFRA;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
+    else if (MONITOR_ON(pAdapter))
+    {
+        *mode = IW_MODE_MONITOR;
+    }
+#endif
+    else
+        *mode = IW_MODE_AUTO;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("==>rt_ioctl_giwmode(mode=%d)\n", *mode));
+	return 0;
+}
+
+int rt_ioctl_siwsens(struct net_device *dev,
+		   struct iw_request_info *info,
+		   char *name, char *extra)
+{
+	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+	//check if the interface is down
+    	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+    	{
+        	DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+        	return -ENETDOWN;
+    	}
+
+	return 0;
+}
+
+int rt_ioctl_giwsens(struct net_device *dev,
+		   struct iw_request_info *info,
+		   char *name, char *extra)
+{
+	return 0;
+}
+
+int rt_ioctl_giwrange(struct net_device *dev,
+		   struct iw_request_info *info,
+		   struct iw_point *data, char *extra)
+{
+	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+	struct iw_range *range = (struct iw_range *) extra;
+	u16 val;
+	int i;
+
+	DBGPRINT(RT_DEBUG_TRACE ,("===>rt_ioctl_giwrange\n"));
+	data->length = sizeof(struct iw_range);
+	memset(range, 0, sizeof(struct iw_range));
+
+	range->txpower_capa = IW_TXPOW_DBM;
+
+	if (INFRA_ON(pAdapter)||ADHOC_ON(pAdapter))
+	{
+		range->min_pmp = 1 * 1024;
+		range->max_pmp = 65535 * 1024;
+		range->min_pmt = 1 * 1024;
+		range->max_pmt = 1000 * 1024;
+		range->pmp_flags = IW_POWER_PERIOD;
+		range->pmt_flags = IW_POWER_TIMEOUT;
+		range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT |
+			IW_POWER_UNICAST_R | IW_POWER_ALL_R;
+	}
+
+	range->we_version_compiled = WIRELESS_EXT;
+	range->we_version_source = 14;
+
+	range->retry_capa = IW_RETRY_LIMIT;
+	range->retry_flags = IW_RETRY_LIMIT;
+	range->min_retry = 0;
+	range->max_retry = 255;
+
+	range->num_channels =  pAdapter->ChannelListNum;
+
+	val = 0;
+	for (i = 1; i <= range->num_channels; i++)
+	{
+		u32 m;
+		range->freq[val].i = pAdapter->ChannelList[i-1].Channel;
+		MAP_CHANNEL_ID_TO_KHZ(pAdapter->ChannelList[i-1].Channel, m);
+		range->freq[val].m = m * 100; /* HZ */
+
+		range->freq[val].e = 1;
+		val++;
+		if (val == IW_MAX_FREQUENCIES)
+			break;
+	}
+	range->num_frequency = val;
+
+	range->max_qual.qual = 100; /* what is correct max? This was not
+					* documented exactly. At least
+					* 69 has been observed. */
+	range->max_qual.level = 0; /* dB */
+	range->max_qual.noise = 0; /* dB */
+
+	/* What would be suitable values for "average/typical" qual? */
+	range->avg_qual.qual = 20;
+	range->avg_qual.level = -60;
+	range->avg_qual.noise = -95;
+	range->sensitivity = 3;
+
+	range->max_encoding_tokens = NR_WEP_KEYS;
+	range->num_encoding_sizes = 2;
+	range->encoding_size[0] = 5;
+	range->encoding_size[1] = 13;
+
+	range->min_rts = 0;
+	range->max_rts = 2347;
+	range->min_frag = 256;
+	range->max_frag = 2346;
+
+#if WIRELESS_EXT > 17
+	/* IW_ENC_CAPA_* bit field */
+	range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
+					IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
+#endif
+
+	return 0;
+}
+
+int rt_ioctl_siwap(struct net_device *dev,
+		      struct iw_request_info *info,
+		      struct sockaddr *ap_addr, char *extra)
+{
+	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+    NDIS_802_11_MAC_ADDRESS Bssid;
+
+	//check if the interface is down
+	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+	{
+       	DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+       	return -ENETDOWN;
+    }
+
+	if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
+    {
+        RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
+        DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
+    }
+
+    // tell CNTL state machine to call NdisMSetInformationComplete() after completing
+    // this request, because this request is initiated by NDIS.
+    pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
+	// Prevent to connect AP again in STAMlmePeriodicExec
+	pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
+
+    memset(Bssid, 0, MAC_ADDR_LEN);
+    memcpy(Bssid, ap_addr->sa_data, MAC_ADDR_LEN);
+    MlmeEnqueue(pAdapter,
+                MLME_CNTL_STATE_MACHINE,
+                OID_802_11_BSSID,
+                sizeof(NDIS_802_11_MAC_ADDRESS),
+                (VOID *)&Bssid);
+
+    DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCSIWAP %02x:%02x:%02x:%02x:%02x:%02x\n",
+        Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
+
+	return 0;
+}
+
+int rt_ioctl_giwap(struct net_device *dev,
+		      struct iw_request_info *info,
+		      struct sockaddr *ap_addr, char *extra)
+{
+	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+	if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
+	{
+		ap_addr->sa_family = ARPHRD_ETHER;
+		memcpy(ap_addr->sa_data, &pAdapter->CommonCfg.Bssid, ETH_ALEN);
+	}
+#ifdef WPA_SUPPLICANT_SUPPORT
+    // Add for RT2870
+    else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
+    {
+        ap_addr->sa_family = ARPHRD_ETHER;
+        memcpy(ap_addr->sa_data, &pAdapter->MlmeAux.Bssid, ETH_ALEN);
+    }
+#endif // WPA_SUPPLICANT_SUPPORT //
+	else
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIWAP(=EMPTY)\n"));
+		return -ENOTCONN;
+	}
+
+	return 0;
+}
+
+/*
+ * Units are in db above the noise floor. That means the
+ * rssi values reported in the tx/rx descriptors in the
+ * driver are the SNR expressed in db.
+ *
+ * If you assume that the noise floor is -95, which is an
+ * excellent assumption 99.5 % of the time, then you can
+ * derive the absolute signal level (i.e. -95 + rssi).
+ * There are some other slight factors to take into account
+ * depending on whether the rssi measurement is from 11b,
+ * 11g, or 11a.   These differences are at most 2db and
+ * can be documented.
+ *
+ * NB: various calculations are based on the orinoco/wavelan
+ *     drivers for compatibility
+ */
+static void set_quality(PRTMP_ADAPTER pAdapter,
+                        struct iw_quality *iq,
+                        signed char rssi)
+{
+	__u8 ChannelQuality;
+
+	// Normalize Rssi
+	if (rssi >= -50)
+		ChannelQuality = 100;
+	else if (rssi >= -80) // between -50 ~ -80dbm
+		ChannelQuality = (__u8)(24 + ((rssi + 80) * 26)/10);
+	else if (rssi >= -90)   // between -80 ~ -90dbm
+        ChannelQuality = (__u8)((rssi + 90) * 26)/10;
+	else
+		ChannelQuality = 0;
+
+    iq->qual = (__u8)ChannelQuality;
+
+    iq->level = (__u8)(rssi);
+    iq->noise = (pAdapter->BbpWriteLatch[66] > pAdapter->BbpTuning.FalseCcaUpperThreshold) ? ((__u8)pAdapter->BbpTuning.FalseCcaUpperThreshold) : ((__u8) pAdapter->BbpWriteLatch[66]); 	// noise level (dBm)
+    iq->noise += 256 - 143;
+    iq->updated = pAdapter->iw_stats.qual.updated;
+}
+
+int rt_ioctl_iwaplist(struct net_device *dev,
+			struct iw_request_info *info,
+			struct iw_point *data, char *extra)
+{
+ 	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+	struct sockaddr addr[IW_MAX_AP];
+	struct iw_quality qual[IW_MAX_AP];
+	int i;
+
+   	//check if the interface is down
+    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+    {
+       	DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+		data->length = 0;
+		return 0;
+        //return -ENETDOWN;
+	}
+
+	for (i = 0; i <IW_MAX_AP ; i++)
+	{
+		if (i >=  pAdapter->ScanTab.BssNr)
+			break;
+		addr[i].sa_family = ARPHRD_ETHER;
+			memcpy(addr[i].sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
+		set_quality(pAdapter, &qual[i], pAdapter->ScanTab.BssEntry[i].Rssi);
+	}
+	data->length = i;
+	memcpy(extra, &addr, i*sizeof(addr[0]));
+	data->flags = 1;		/* signal quality present (sort of) */
+	memcpy(extra + i*sizeof(addr[0]), &qual, i*sizeof(qual[i]));
+
+	return 0;
+}
+
+#ifdef SIOCGIWSCAN
+int rt_ioctl_siwscan(struct net_device *dev,
+			struct iw_request_info *info,
+			struct iw_point *data, char *extra)
+{
+	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+	ULONG								Now;
+	int Status = NDIS_STATUS_SUCCESS;
+
+	//check if the interface is down
+	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+		return -ENETDOWN;
+	}
+
+	if (MONITOR_ON(pAdapter))
+    {
+        DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
+        return -EINVAL;
+    }
+
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+	if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
+	{
+		pAdapter->StaCfg.WpaSupplicantScanCount++;
+	}
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+    pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
+	if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+		return 0;
+	do{
+		Now = jiffies;
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+		if ((pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) &&
+			(pAdapter->StaCfg.WpaSupplicantScanCount > 3))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("!!! WpaSupplicantScanCount > 3\n"));
+			Status = NDIS_STATUS_SUCCESS;
+			break;
+		}
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+		if ((OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
+			((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
+			(pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) &&
+			(pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
+			Status = NDIS_STATUS_SUCCESS;
+			break;
+		}
+
+		if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
+		{
+			RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
+			DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
+		}
+
+		// tell CNTL state machine to call NdisMSetInformationComplete() after completing
+		// this request, because this request is initiated by NDIS.
+		pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
+		// Reset allowed scan retries
+		pAdapter->StaCfg.ScanCnt = 0;
+		pAdapter->StaCfg.LastScanTime = Now;
+
+		MlmeEnqueue(pAdapter,
+			MLME_CNTL_STATE_MACHINE,
+			OID_802_11_BSSID_LIST_SCAN,
+			0,
+			NULL);
+
+		Status = NDIS_STATUS_SUCCESS;
+		RT28XX_MLME_HANDLER(pAdapter);
+	}while(0);
+	return 0;
+}
+
+int rt_ioctl_giwscan(struct net_device *dev,
+			struct iw_request_info *info,
+			struct iw_point *data, char *extra)
+{
+
+	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+	int i=0;
+	char *current_ev = extra, *previous_ev = extra;
+	char *end_buf;
+	char *current_val, custom[MAX_CUSTOM_LEN] = {0};
+#ifndef IWEVGENIE
+	char idx;
+#endif // IWEVGENIE //
+	struct iw_event iwe;
+
+	if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+    {
+		/*
+		 * Still scanning, indicate the caller should try again.
+		 */
+		return -EAGAIN;
+	}
+
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+	if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
+	{
+		pAdapter->StaCfg.WpaSupplicantScanCount = 0;
+	}
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+	if (pAdapter->ScanTab.BssNr == 0)
+	{
+		data->length = 0;
+		return 0;
+	}
+
+#if WIRELESS_EXT >= 17
+    if (data->length > 0)
+        end_buf = extra + data->length;
+    else
+        end_buf = extra + IW_SCAN_MAX_DATA;
+#else
+    end_buf = extra + IW_SCAN_MAX_DATA;
+#endif
+
+	for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
+	{
+		if (current_ev >= end_buf)
+        {
+#if WIRELESS_EXT >= 17
+            return -E2BIG;
+#else
+			break;
+#endif
+        }
+
+		//MAC address
+		//================================
+		memset(&iwe, 0, sizeof(iwe));
+		iwe.cmd = SIOCGIWAP;
+		iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+				memcpy(iwe.u.ap_addr.sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, ETH_ALEN);
+
+        previous_ev = current_ev;
+			current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+        if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+            return -E2BIG;
+#else
+			break;
+#endif
+
+		/*
+		Protocol:
+			it will show scanned AP's WirelessMode .
+			it might be
+					802.11a
+					802.11a/n
+					802.11g/n
+					802.11b/g/n
+					802.11g
+					802.11b/g
+		*/
+		memset(&iwe, 0, sizeof(iwe));
+		iwe.cmd = SIOCGIWNAME;
+
+
+	{
+		PBSS_ENTRY pBssEntry=&pAdapter->ScanTab.BssEntry[i];
+		BOOLEAN isGonly=FALSE;
+		int rateCnt=0;
+
+		if (pBssEntry->Channel>14)
+		{
+			if (pBssEntry->HtCapabilityLen!=0)
+				strcpy(iwe.u.name,"802.11a/n");
+			else
+				strcpy(iwe.u.name,"802.11a");
+		}
+		else
+		{
+			/*
+				if one of non B mode rate is set supported rate . it mean G only.
+			*/
+			for (rateCnt=0;rateCnt<pBssEntry->SupRateLen;rateCnt++)
+			{
+				/*
+					6Mbps(140) 9Mbps(146) and >=12Mbps(152) are supported rate , it mean G only.
+				*/
+				if (pBssEntry->SupRate[rateCnt]==140 || pBssEntry->SupRate[rateCnt]==146 || pBssEntry->SupRate[rateCnt]>=152)
+					isGonly=TRUE;
+			}
+
+			for (rateCnt=0;rateCnt<pBssEntry->ExtRateLen;rateCnt++)
+			{
+				if (pBssEntry->ExtRate[rateCnt]==140 || pBssEntry->ExtRate[rateCnt]==146 || pBssEntry->ExtRate[rateCnt]>=152)
+					isGonly=TRUE;
+			}
+
+
+			if (pBssEntry->HtCapabilityLen!=0)
+			{
+				if (isGonly==TRUE)
+					strcpy(iwe.u.name,"802.11g/n");
+				else
+					strcpy(iwe.u.name,"802.11b/g/n");
+			}
+			else
+			{
+				if (isGonly==TRUE)
+					strcpy(iwe.u.name,"802.11g");
+				else
+				{
+					if (pBssEntry->SupRateLen==4 && pBssEntry->ExtRateLen==0)
+						strcpy(iwe.u.name,"802.11b");
+					else
+						strcpy(iwe.u.name,"802.11b/g");
+				}
+			}
+		}
+	}
+
+		previous_ev = current_ev;
+		current_ev	 = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+		if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+	   		return -E2BIG;
+#else
+			break;
+#endif
+
+		//ESSID
+		//================================
+		memset(&iwe, 0, sizeof(iwe));
+		iwe.cmd = SIOCGIWESSID;
+		iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].SsidLen;
+		iwe.u.data.flags = 1;
+
+        previous_ev = current_ev;
+		current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pAdapter->ScanTab.BssEntry[i].Ssid);
+        if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+            return -E2BIG;
+#else
+			break;
+#endif
+
+		//Network Type
+		//================================
+		memset(&iwe, 0, sizeof(iwe));
+		iwe.cmd = SIOCGIWMODE;
+		if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11IBSS)
+		{
+			iwe.u.mode = IW_MODE_ADHOC;
+		}
+		else if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11Infrastructure)
+		{
+			iwe.u.mode = IW_MODE_INFRA;
+		}
+		else
+		{
+			iwe.u.mode = IW_MODE_AUTO;
+		}
+		iwe.len = IW_EV_UINT_LEN;
+
+        previous_ev = current_ev;
+		current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,  IW_EV_UINT_LEN);
+        if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+            return -E2BIG;
+#else
+			break;
+#endif
+
+		//Channel and Frequency
+		//================================
+		memset(&iwe, 0, sizeof(iwe));
+		iwe.cmd = SIOCGIWFREQ;
+		if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
+			iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
+		else
+			iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
+		iwe.u.freq.e = 0;
+		iwe.u.freq.i = 0;
+
+		previous_ev = current_ev;
+		current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
+        if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+            return -E2BIG;
+#else
+			break;
+#endif
+
+        //Add quality statistics
+        //================================
+        memset(&iwe, 0, sizeof(iwe));
+    	iwe.cmd = IWEVQUAL;
+    	iwe.u.qual.level = 0;
+    	iwe.u.qual.noise = 0;
+        set_quality(pAdapter, &iwe.u.qual, pAdapter->ScanTab.BssEntry[i].Rssi);
+    	current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+        if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+            return -E2BIG;
+#else
+			break;
+#endif
+
+		//Encyption key
+		//================================
+		memset(&iwe, 0, sizeof(iwe));
+		iwe.cmd = SIOCGIWENCODE;
+		if (CAP_IS_PRIVACY_ON (pAdapter->ScanTab.BssEntry[i].CapabilityInfo ))
+			iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+		else
+			iwe.u.data.flags = IW_ENCODE_DISABLED;
+
+        previous_ev = current_ev;
+        current_ev = iwe_stream_add_point(info, current_ev, end_buf,&iwe, (char *)pAdapter->SharedKey[BSS0][(iwe.u.data.flags & IW_ENCODE_INDEX)-1].Key);
+        if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+            return -E2BIG;
+#else
+			break;
+#endif
+
+		//Bit Rate
+		//================================
+		if (pAdapter->ScanTab.BssEntry[i].SupRateLen)
+        {
+            UCHAR tmpRate = pAdapter->ScanTab.BssEntry[i].SupRate[pAdapter->ScanTab.BssEntry[i].SupRateLen-1];
+			memset(&iwe, 0, sizeof(iwe));
+			iwe.cmd = SIOCGIWRATE;
+    		current_val = current_ev + IW_EV_LCP_LEN;
+            if (tmpRate == 0x82)
+                iwe.u.bitrate.value =  1 * 1000000;
+            else if (tmpRate == 0x84)
+                iwe.u.bitrate.value =  2 * 1000000;
+            else if (tmpRate == 0x8B)
+                iwe.u.bitrate.value =  5.5 * 1000000;
+            else if (tmpRate == 0x96)
+                iwe.u.bitrate.value =  11 * 1000000;
+            else
+    		    iwe.u.bitrate.value =  (tmpRate/2) * 1000000;
+
+			iwe.u.bitrate.disabled = 0;
+			current_val = iwe_stream_add_value(info, current_ev,
+				current_val, end_buf, &iwe,
+    			IW_EV_PARAM_LEN);
+
+        	if((current_val-current_ev)>IW_EV_LCP_LEN)
+            	current_ev = current_val;
+        	else
+#if WIRELESS_EXT >= 17
+                return -E2BIG;
+#else
+			    break;
+#endif
+        }
+
+#ifdef IWEVGENIE
+		//WPA IE
+		if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
+		{
+			memset(&iwe, 0, sizeof(iwe));
+			memset(&custom[0], 0, MAX_CUSTOM_LEN);
+			memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].WpaIE.IE[0]),
+						   pAdapter->ScanTab.BssEntry[i].WpaIE.IELen);
+			iwe.cmd = IWEVGENIE;
+			iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].WpaIE.IELen;
+			current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, custom);
+			if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+                return -E2BIG;
+#else
+			    break;
+#endif
+		}
+
+		//WPA2 IE
+        if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0)
+        {
+        	memset(&iwe, 0, sizeof(iwe));
+			memset(&custom[0], 0, MAX_CUSTOM_LEN);
+			memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].RsnIE.IE[0]),
+						   pAdapter->ScanTab.BssEntry[i].RsnIE.IELen);
+			iwe.cmd = IWEVGENIE;
+			iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].RsnIE.IELen;
+			current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, custom);
+			if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+                return -E2BIG;
+#else
+			    break;
+#endif
+        }
+#else
+        //WPA IE
+		//================================
+        if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
+        {
+    		NdisZeroMemory(&iwe, sizeof(iwe));
+			memset(&custom[0], 0, MAX_CUSTOM_LEN);
+    		iwe.cmd = IWEVCUSTOM;
+            iwe.u.data.length = (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen * 2) + 7;
+            NdisMoveMemory(custom, "wpa_ie=", 7);
+            for (idx = 0; idx < pAdapter->ScanTab.BssEntry[i].WpaIE.IELen; idx++)
+                sprintf(custom, "%s%02x", custom, pAdapter->ScanTab.BssEntry[i].WpaIE.IE[idx]);
+            previous_ev = current_ev;
+    		current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,  custom);
+            if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+                return -E2BIG;
+#else
+			    break;
+#endif
+        }
+
+        //WPA2 IE
+        if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0)
+        {
+    		NdisZeroMemory(&iwe, sizeof(iwe));
+			memset(&custom[0], 0, MAX_CUSTOM_LEN);
+    		iwe.cmd = IWEVCUSTOM;
+            iwe.u.data.length = (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen * 2) + 7;
+            NdisMoveMemory(custom, "rsn_ie=", 7);
+			for (idx = 0; idx < pAdapter->ScanTab.BssEntry[i].RsnIE.IELen; idx++)
+                sprintf(custom, "%s%02x", custom, pAdapter->ScanTab.BssEntry[i].RsnIE.IE[idx]);
+            previous_ev = current_ev;
+    		current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,  custom);
+            if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+                return -E2BIG;
+#else
+			    break;
+#endif
+        }
+#endif // IWEVGENIE //
+	}
+
+	data->length = current_ev - extra;
+    pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
+	DBGPRINT(RT_DEBUG_ERROR ,("===>rt_ioctl_giwscan. %d(%d) BSS returned, data->length = %d\n",i , pAdapter->ScanTab.BssNr, data->length));
+	return 0;
+}
+#endif
+
+int rt_ioctl_siwessid(struct net_device *dev,
+			 struct iw_request_info *info,
+			 struct iw_point *data, char *essid)
+{
+	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+	//check if the interface is down
+    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+    {
+       	DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+       	return -ENETDOWN;
+    }
+
+	if (data->flags)
+	{
+		PCHAR	pSsidString = NULL;
+
+		// Includes null character.
+		if (data->length > (IW_ESSID_MAX_SIZE + 1))
+			return -E2BIG;
+
+		pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
+		if (pSsidString)
+		{
+			NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
+			NdisMoveMemory(pSsidString, essid, data->length);
+			if (Set_SSID_Proc(pAdapter, pSsidString) == FALSE)
+				return -EINVAL;
+		}
+		else
+			return -ENOMEM;
+	}
+	else
+	{
+		// ANY ssid
+		if (Set_SSID_Proc(pAdapter, "") == FALSE)
+			return -EINVAL;
+    }
+	return 0;
+}
+
+int rt_ioctl_giwessid(struct net_device *dev,
+			 struct iw_request_info *info,
+			 struct iw_point *data, char *essid)
+{
+	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+	data->flags = 1;
+    if (MONITOR_ON(pAdapter))
+    {
+        data->length  = 0;
+        return 0;
+    }
+
+	if (OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED))
+	{
+		DBGPRINT(RT_DEBUG_TRACE ,("MediaState is connected\n"));
+		data->length = pAdapter->CommonCfg.SsidLen;
+		memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
+	}
+#ifdef RT2870
+#ifdef WPA_SUPPLICANT_SUPPORT
+    // Add for RT2870
+    else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
+    {
+        data->length = pAdapter->CommonCfg.SsidLen;
+		memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
+	}
+#endif // WPA_SUPPLICANT_SUPPORT //
+#endif // RT2870 //
+	else
+	{//the ANY ssid was specified
+		data->length  = 0;
+		DBGPRINT(RT_DEBUG_TRACE ,("MediaState is not connected, ess\n"));
+	}
+
+	return 0;
+
+}
+
+int rt_ioctl_siwnickn(struct net_device *dev,
+			 struct iw_request_info *info,
+			 struct iw_point *data, char *nickname)
+{
+	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+    //check if the interface is down
+    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+    {
+        DBGPRINT(RT_DEBUG_TRACE ,("INFO::Network is down!\n"));
+        return -ENETDOWN;
+    }
+
+	if (data->length > IW_ESSID_MAX_SIZE)
+		return -EINVAL;
+
+	memset(pAdapter->nickname, 0, IW_ESSID_MAX_SIZE + 1);
+	memcpy(pAdapter->nickname, nickname, data->length);
+
+
+	return 0;
+}
+
+int rt_ioctl_giwnickn(struct net_device *dev,
+			 struct iw_request_info *info,
+			 struct iw_point *data, char *nickname)
+{
+	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+	if (data->length > strlen(pAdapter->nickname) + 1)
+		data->length = strlen(pAdapter->nickname) + 1;
+	if (data->length > 0) {
+		memcpy(nickname, pAdapter->nickname, data->length-1);
+		nickname[data->length-1] = '\0';
+	}
+	return 0;
+}
+
+int rt_ioctl_siwrts(struct net_device *dev,
+		       struct iw_request_info *info,
+		       struct iw_param *rts, char *extra)
+{
+	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+	u16 val;
+
+    //check if the interface is down
+    if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+    {
+        DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+        return -ENETDOWN;
+    }
+
+	if (rts->disabled)
+		val = MAX_RTS_THRESHOLD;
+	else if (rts->value < 0 || rts->value > MAX_RTS_THRESHOLD)
+		return -EINVAL;
+	else if (rts->value == 0)
+	    val = MAX_RTS_THRESHOLD;
+	else
+		val = rts->value;
+
+	if (val != pAdapter->CommonCfg.RtsThreshold)
+		pAdapter->CommonCfg.RtsThreshold = val;
+
+	return 0;
+}
+
+int rt_ioctl_giwrts(struct net_device *dev,
+		       struct iw_request_info *info,
+		       struct iw_param *rts, char *extra)
+{
+	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+	//check if the interface is down
+    	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+    	{
+      		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+        	return -ENETDOWN;
+    	}
+
+	rts->value = pAdapter->CommonCfg.RtsThreshold;
+	rts->disabled = (rts->value == MAX_RTS_THRESHOLD);
+	rts->fixed = 1;
+
+	return 0;
+}
+
+int rt_ioctl_siwfrag(struct net_device *dev,
+			struct iw_request_info *info,
+			struct iw_param *frag, char *extra)
+{
+	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+	u16 val;
+
+	//check if the interface is down
+    	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+    	{
+      		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+        	return -ENETDOWN;
+    	}
+
+	if (frag->disabled)
+		val = MAX_FRAG_THRESHOLD;
+	else if (frag->value >= MIN_FRAG_THRESHOLD || frag->value <= MAX_FRAG_THRESHOLD)
+        val = __cpu_to_le16(frag->value & ~0x1); /* even numbers only */
+	else if (frag->value == 0)
+	    val = MAX_FRAG_THRESHOLD;
+	else
+		return -EINVAL;
+
+	pAdapter->CommonCfg.FragmentThreshold = val;
+	return 0;
+}
+
+int rt_ioctl_giwfrag(struct net_device *dev,
+			struct iw_request_info *info,
+			struct iw_param *frag, char *extra)
+{
+	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+	//check if the interface is down
+    	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+    	{
+      		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+        	return -ENETDOWN;
+    	}
+
+	frag->value = pAdapter->CommonCfg.FragmentThreshold;
+	frag->disabled = (frag->value == MAX_FRAG_THRESHOLD);
+	frag->fixed = 1;
+
+	return 0;
+}
+
+#define MAX_WEP_KEY_SIZE 13
+#define MIN_WEP_KEY_SIZE 5
+int rt_ioctl_siwencode(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_point *erq, char *extra)
+{
+	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+	//check if the interface is down
+    	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+    	{
+      		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+        	return -ENETDOWN;
+    	}
+
+	if ((erq->length == 0) &&
+        (erq->flags & IW_ENCODE_DISABLED))
+	{
+		pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
+		pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
+		pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
+        pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
+        goto done;
+	}
+	else if (erq->flags & IW_ENCODE_RESTRICTED || erq->flags & IW_ENCODE_OPEN)
+	{
+	    //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+		STA_PORT_SECURED(pAdapter);
+		pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
+		pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
+		pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
+        pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+		if (erq->flags & IW_ENCODE_RESTRICTED)
+			pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
+    	else
+			pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
+	}
+
+    if (erq->length > 0)
+	{
+		int keyIdx = (erq->flags & IW_ENCODE_INDEX) - 1;
+		/* Check the size of the key */
+		if (erq->length > MAX_WEP_KEY_SIZE)
+		{
+			return -EINVAL;
+		}
+		/* Check key index */
+		if ((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
+        {
+            DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::Wrong keyIdx=%d! Using default key instead (%d)\n",
+                                        keyIdx, pAdapter->StaCfg.DefaultKeyId));
+
+            //Using default key
+			keyIdx = pAdapter->StaCfg.DefaultKeyId;
+        }
+		else
+		{
+			pAdapter->StaCfg.DefaultKeyId=keyIdx;
+		}
+
+        NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,  16);
+
+		if (erq->length == MAX_WEP_KEY_SIZE)
+        {
+			pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
+            pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
+		}
+		else if (erq->length == MIN_WEP_KEY_SIZE)
+        {
+            pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
+            pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
+		}
+		else
+			/* Disable the key */
+			pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
+
+		/* Check if the key is not marked as invalid */
+		if(!(erq->flags & IW_ENCODE_NOKEY))
+		{
+			/* Copy the key in the driver */
+			NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, extra, erq->length);
+        }
+	}
+    else
+			{
+		/* Do we want to just set the transmit key index ? */
+		int index = (erq->flags & IW_ENCODE_INDEX) - 1;
+		if ((index >= 0) && (index < 4))
+        {
+			pAdapter->StaCfg.DefaultKeyId = index;
+            }
+        else
+			/* Don't complain if only change the mode */
+		if(!erq->flags & IW_ENCODE_MODE)
+		{
+				return -EINVAL;
+		}
+	}
+
+done:
+    DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::erq->flags=%x\n",erq->flags));
+	DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::AuthMode=%x\n",pAdapter->StaCfg.AuthMode));
+	DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::DefaultKeyId=%x, KeyLen = %d\n",pAdapter->StaCfg.DefaultKeyId , pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen));
+	DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::WepStatus=%x\n",pAdapter->StaCfg.WepStatus));
+	return 0;
+}
+
+int
+rt_ioctl_giwencode(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_point *erq, char *key)
+{
+	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+	int kid;
+
+	//check if the interface is down
+	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+	{
+  		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+    	return -ENETDOWN;
+	}
+
+	kid = erq->flags & IW_ENCODE_INDEX;
+	DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_giwencode %d\n", erq->flags & IW_ENCODE_INDEX));
+
+	if (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled)
+	{
+		erq->length = 0;
+		erq->flags = IW_ENCODE_DISABLED;
+	}
+	else if ((kid > 0) && (kid <=4))
+	{
+		// copy wep key
+		erq->flags = kid ;			/* NB: base 1 */
+		if (erq->length > pAdapter->SharedKey[BSS0][kid-1].KeyLen)
+			erq->length = pAdapter->SharedKey[BSS0][kid-1].KeyLen;
+		memcpy(key, pAdapter->SharedKey[BSS0][kid-1].Key, erq->length);
+		//if ((kid == pAdapter->PortCfg.DefaultKeyId))
+		//erq->flags |= IW_ENCODE_ENABLED;	/* XXX */
+		if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
+			erq->flags |= IW_ENCODE_RESTRICTED;		/* XXX */
+		else
+			erq->flags |= IW_ENCODE_OPEN;		/* XXX */
+
+	}
+	else if (kid == 0)
+	{
+		if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
+			erq->flags |= IW_ENCODE_RESTRICTED;		/* XXX */
+		else
+			erq->flags |= IW_ENCODE_OPEN;		/* XXX */
+		erq->length = pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen;
+		memcpy(key, pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key, erq->length);
+		// copy default key ID
+		if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
+			erq->flags |= IW_ENCODE_RESTRICTED;		/* XXX */
+		else
+			erq->flags |= IW_ENCODE_OPEN;		/* XXX */
+		erq->flags = pAdapter->StaCfg.DefaultKeyId + 1;			/* NB: base 1 */
+		erq->flags |= IW_ENCODE_ENABLED;	/* XXX */
+	}
+
+	return 0;
+
+}
+
+static int
+rt_ioctl_setparam(struct net_device *dev, struct iw_request_info *info,
+			 void *w, char *extra)
+{
+    VIRTUAL_ADAPTER	*pVirtualAd = NULL;
+	PRTMP_ADAPTER pAdapter;
+	POS_COOKIE pObj;
+	char *this_char = extra;
+	char *value;
+	int  Status=0;
+
+	if (dev->priv_flags == INT_MAIN)
+	{
+		pAdapter = dev->ml_priv;
+	}
+	else
+	{
+		pVirtualAd = dev->ml_priv;
+		pAdapter = pVirtualAd->RtmpDev->ml_priv;
+	}
+	pObj = (POS_COOKIE) pAdapter->OS_Cookie;
+
+	if (pAdapter == NULL)
+	{
+		/* if 1st open fail, pAd will be free;
+		   So the net_dev->ml_priv will be NULL in 2rd open */
+		return -ENETDOWN;
+	}
+
+	{
+		pObj->ioctl_if_type = INT_MAIN;
+        pObj->ioctl_if = MAIN_MBSSID;
+	}
+
+	//check if the interface is down
+    	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+    	{
+      		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+			return -ENETDOWN;
+    	}
+
+	if (!*this_char)
+		return -EINVAL;
+
+	if ((value = rtstrchr(this_char, '=')) != NULL)
+	    *value++ = 0;
+
+	if (!value)
+	    return -EINVAL;
+
+	// reject setting nothing besides ANY ssid(ssidLen=0)
+    if (!*value && (strcmp(this_char, "SSID") != 0))
+        return -EINVAL;
+
+	for (PRTMP_PRIVATE_SET_PROC = RTMP_PRIVATE_SUPPORT_PROC; PRTMP_PRIVATE_SET_PROC->name; PRTMP_PRIVATE_SET_PROC++)
+	{
+	    if (strcmp(this_char, PRTMP_PRIVATE_SET_PROC->name) == 0)
+	    {
+	        if(!PRTMP_PRIVATE_SET_PROC->set_proc(pAdapter, value))
+	        {	//FALSE:Set private failed then return Invalid argument
+			    Status = -EINVAL;
+	        }
+		    break;	//Exit for loop.
+	    }
+	}
+
+	if(PRTMP_PRIVATE_SET_PROC->name == NULL)
+	{  //Not found argument
+	    Status = -EINVAL;
+	    DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_setparam:: (iwpriv) Not Support Set Command [%s=%s]\n", this_char, value));
+	}
+
+    return Status;
+}
+
+
+static int
+rt_private_get_statistics(struct net_device *dev, struct iw_request_info *info,
+		struct iw_point *wrq, char *extra)
+{
+	INT				Status = 0;
+    PRTMP_ADAPTER   pAd = dev->ml_priv;
+
+    if (extra == NULL)
+    {
+        wrq->length = 0;
+        return -EIO;
+    }
+
+    memset(extra, 0x00, IW_PRIV_SIZE_MASK);
+    sprintf(extra, "\n\n");
+
+#ifdef RALINK_ATE
+	if (ATE_ON(pAd))
+	{
+	    sprintf(extra+strlen(extra), "Tx success                      = %ld\n", (ULONG)pAd->ate.TxDoneCount);
+	    //sprintf(extra+strlen(extra), "Tx success without retry        = %ld\n", (ULONG)pAd->ate.TxDoneCount);
+	}
+	else
+#endif // RALINK_ATE //
+	{
+    sprintf(extra+strlen(extra), "Tx success                      = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart);
+    sprintf(extra+strlen(extra), "Tx success without retry        = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart - (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
+	}
+    sprintf(extra+strlen(extra), "Tx success after retry          = %ld\n", (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
+    sprintf(extra+strlen(extra), "Tx fail to Rcv ACK after retry  = %ld\n", (ULONG)pAd->WlanCounters.FailedCount.QuadPart);
+    sprintf(extra+strlen(extra), "RTS Success Rcv CTS             = %ld\n", (ULONG)pAd->WlanCounters.RTSSuccessCount.QuadPart);
+    sprintf(extra+strlen(extra), "RTS Fail Rcv CTS                = %ld\n", (ULONG)pAd->WlanCounters.RTSFailureCount.QuadPart);
+
+    sprintf(extra+strlen(extra), "Rx success                      = %ld\n", (ULONG)pAd->WlanCounters.ReceivedFragmentCount.QuadPart);
+    sprintf(extra+strlen(extra), "Rx with CRC                     = %ld\n", (ULONG)pAd->WlanCounters.FCSErrorCount.QuadPart);
+    sprintf(extra+strlen(extra), "Rx drop due to out of resource  = %ld\n", (ULONG)pAd->Counters8023.RxNoBuffer);
+    sprintf(extra+strlen(extra), "Rx duplicate frame              = %ld\n", (ULONG)pAd->WlanCounters.FrameDuplicateCount.QuadPart);
+
+    sprintf(extra+strlen(extra), "False CCA (one second)          = %ld\n", (ULONG)pAd->RalinkCounters.OneSecFalseCCACnt);
+#ifdef RALINK_ATE
+	if (ATE_ON(pAd))
+	{
+		if (pAd->ate.RxAntennaSel == 0)
+		{
+    		sprintf(extra+strlen(extra), "RSSI-A                          = %ld\n", (LONG)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta));
+			sprintf(extra+strlen(extra), "RSSI-B (if available)           = %ld\n", (LONG)(pAd->ate.LastRssi1 - pAd->BbpRssiToDbmDelta));
+			sprintf(extra+strlen(extra), "RSSI-C (if available)           = %ld\n\n", (LONG)(pAd->ate.LastRssi2 - pAd->BbpRssiToDbmDelta));
+		}
+		else
+		{
+    		sprintf(extra+strlen(extra), "RSSI                            = %ld\n", (LONG)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta));
+		}
+	}
+	else
+#endif // RALINK_ATE //
+	{
+    	sprintf(extra+strlen(extra), "RSSI-A                          = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi0 - pAd->BbpRssiToDbmDelta));
+        sprintf(extra+strlen(extra), "RSSI-B (if available)           = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi1 - pAd->BbpRssiToDbmDelta));
+        sprintf(extra+strlen(extra), "RSSI-C (if available)           = %ld\n\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi2 - pAd->BbpRssiToDbmDelta));
+	}
+#ifdef WPA_SUPPLICANT_SUPPORT
+    sprintf(extra+strlen(extra), "WpaSupplicantUP                 = %d\n\n", pAd->StaCfg.WpaSupplicantUP);
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+
+    wrq->length = strlen(extra) + 1; // 1: size of '\0'
+    DBGPRINT(RT_DEBUG_TRACE, ("<== rt_private_get_statistics, wrq->length = %d\n", wrq->length));
+
+    return Status;
+}
+
+#ifdef DOT11_N_SUPPORT
+void	getBaInfo(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			pOutBuf)
+{
+	INT i, j;
+	BA_ORI_ENTRY *pOriBAEntry;
+	BA_REC_ENTRY *pRecBAEntry;
+
+	for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+	{
+		PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
+		if (((pEntry->ValidAsCLI || pEntry->ValidAsApCli) && (pEntry->Sst == SST_ASSOC))
+			|| (pEntry->ValidAsWDS) || (pEntry->ValidAsMesh))
+		{
+			sprintf(pOutBuf, "%s\n%02X:%02X:%02X:%02X:%02X:%02X (Aid = %d) (AP) -\n",
+                pOutBuf,
+				pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
+				pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5], pEntry->Aid);
+
+			sprintf(pOutBuf, "%s[Recipient]\n", pOutBuf);
+			for (j=0; j < NUM_OF_TID; j++)
+			{
+				if (pEntry->BARecWcidArray[j] != 0)
+				{
+					pRecBAEntry =&pAd->BATable.BARecEntry[pEntry->BARecWcidArray[j]];
+					sprintf(pOutBuf, "%sTID=%d, BAWinSize=%d, LastIndSeq=%d, ReorderingPkts=%d\n", pOutBuf, j, pRecBAEntry->BAWinSize, pRecBAEntry->LastIndSeq, pRecBAEntry->list.qlen);
+				}
+			}
+			sprintf(pOutBuf, "%s\n", pOutBuf);
+
+			sprintf(pOutBuf, "%s[Originator]\n", pOutBuf);
+			for (j=0; j < NUM_OF_TID; j++)
+			{
+				if (pEntry->BAOriWcidArray[j] != 0)
+				{
+					pOriBAEntry =&pAd->BATable.BAOriEntry[pEntry->BAOriWcidArray[j]];
+					sprintf(pOutBuf, "%sTID=%d, BAWinSize=%d, StartSeq=%d, CurTxSeq=%d\n", pOutBuf, j, pOriBAEntry->BAWinSize, pOriBAEntry->Sequence, pEntry->TxSeq[j]);
+				}
+			}
+			sprintf(pOutBuf, "%s\n\n", pOutBuf);
+		}
+        if (strlen(pOutBuf) > (IW_PRIV_SIZE_MASK - 30))
+                break;
+	}
+
+	return;
+}
+#endif // DOT11_N_SUPPORT //
+
+static int
+rt_private_show(struct net_device *dev, struct iw_request_info *info,
+		struct iw_point *wrq, char *extra)
+{
+    INT				Status = 0;
+    VIRTUAL_ADAPTER	*pVirtualAd = NULL;
+    PRTMP_ADAPTER   pAd;
+	POS_COOKIE		pObj;
+    u32             subcmd = wrq->flags;
+
+	if (dev->priv_flags == INT_MAIN)
+		pAd = dev->ml_priv;
+	else
+	{
+		pVirtualAd = dev->ml_priv;
+		pAd = pVirtualAd->RtmpDev->ml_priv;
+	}
+	pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+	if (pAd == NULL)
+	{
+		/* if 1st open fail, pAd will be free;
+		   So the net_dev->ml_priv will be NULL in 2rd open */
+		return -ENETDOWN;
+	}
+
+    if (extra == NULL)
+    {
+        wrq->length = 0;
+        return -EIO;
+    }
+    memset(extra, 0x00, IW_PRIV_SIZE_MASK);
+
+	{
+		pObj->ioctl_if_type = INT_MAIN;
+        pObj->ioctl_if = MAIN_MBSSID;
+	}
+
+    switch(subcmd)
+    {
+
+        case SHOW_CONN_STATUS:
+            if (MONITOR_ON(pAd))
+            {
+#ifdef DOT11_N_SUPPORT
+                if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
+                    pAd->CommonCfg.RegTransmitSetting.field.BW)
+                    sprintf(extra, "Monitor Mode(CentralChannel %d)\n", pAd->CommonCfg.CentralChannel);
+                else
+#endif // DOT11_N_SUPPORT //
+                    sprintf(extra, "Monitor Mode(Channel %d)\n", pAd->CommonCfg.Channel);
+            }
+            else
+            {
+                if (pAd->IndicateMediaState == NdisMediaStateConnected)
+            	{
+            	    if (INFRA_ON(pAd))
+                    {
+                    sprintf(extra, "Connected(AP: %s[%02X:%02X:%02X:%02X:%02X:%02X])\n",
+                                    pAd->CommonCfg.Ssid,
+                                    pAd->CommonCfg.Bssid[0],
+                                    pAd->CommonCfg.Bssid[1],
+                                    pAd->CommonCfg.Bssid[2],
+                                    pAd->CommonCfg.Bssid[3],
+                                    pAd->CommonCfg.Bssid[4],
+                                    pAd->CommonCfg.Bssid[5]);
+            		DBGPRINT(RT_DEBUG_TRACE ,("Ssid=%s ,Ssidlen = %d\n",pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen));
+            	}
+                    else if (ADHOC_ON(pAd))
+                        sprintf(extra, "Connected\n");
+            	}
+            	else
+            	{
+            	    sprintf(extra, "Disconnected\n");
+            		DBGPRINT(RT_DEBUG_TRACE ,("ConnStatus is not connected\n"));
+            	}
+            }
+            wrq->length = strlen(extra) + 1; // 1: size of '\0'
+            break;
+        case SHOW_DRVIER_VERION:
+            sprintf(extra, "Driver version-%s, %s %s\n", STA_DRIVER_VERSION, __DATE__, __TIME__ );
+            wrq->length = strlen(extra) + 1; // 1: size of '\0'
+            break;
+#ifdef DOT11_N_SUPPORT
+        case SHOW_BA_INFO:
+            getBaInfo(pAd, extra);
+            wrq->length = strlen(extra) + 1; // 1: size of '\0'
+            break;
+#endif // DOT11_N_SUPPORT //
+		case SHOW_DESC_INFO:
+			{
+				Show_DescInfo_Proc(pAd, NULL);
+				wrq->length = 0; // 1: size of '\0'
+			}
+			break;
+        case RAIO_OFF:
+            if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+            {
+                sprintf(extra, "Scanning\n");
+                wrq->length = strlen(extra) + 1; // 1: size of '\0'
+                break;
+            }
+            pAd->StaCfg.bSwRadio = FALSE;
+            if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
+            {
+                pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
+                if (pAd->StaCfg.bRadio == FALSE)
+                {
+                    MlmeRadioOff(pAd);
+                    // Update extra information
+					pAd->ExtraInfo = SW_RADIO_OFF;
+                }
+            }
+            sprintf(extra, "Radio Off\n");
+            wrq->length = strlen(extra) + 1; // 1: size of '\0'
+            break;
+        case RAIO_ON:
+            if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+            {
+                sprintf(extra, "Scanning\n");
+                wrq->length = strlen(extra) + 1; // 1: size of '\0'
+                break;
+            }
+            pAd->StaCfg.bSwRadio = TRUE;
+            //if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
+            {
+                pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
+                if (pAd->StaCfg.bRadio == TRUE)
+                {
+                    MlmeRadioOn(pAd);
+                    // Update extra information
+					pAd->ExtraInfo = EXTRA_INFO_CLEAR;
+                }
+            }
+            sprintf(extra, "Radio On\n");
+            wrq->length = strlen(extra) + 1; // 1: size of '\0'
+            break;
+
+
+#ifdef QOS_DLS_SUPPORT
+		case SHOW_DLS_ENTRY_INFO:
+			{
+				Set_DlsEntryInfo_Display_Proc(pAd, NULL);
+				wrq->length = 0; // 1: size of '\0'
+			}
+			break;
+#endif // QOS_DLS_SUPPORT //
+
+		case SHOW_CFG_VALUE:
+			{
+				Status = RTMPShowCfgValue(pAd, wrq->pointer, extra);
+				if (Status == 0)
+					wrq->length = strlen(extra) + 1; // 1: size of '\0'
+			}
+			break;
+        default:
+            DBGPRINT(RT_DEBUG_TRACE, ("%s - unknow subcmd = %d\n", __FUNCTION__, subcmd));
+            break;
+    }
+
+    return Status;
+}
+
+#ifdef SIOCSIWMLME
+int rt_ioctl_siwmlme(struct net_device *dev,
+			   struct iw_request_info *info,
+			   union iwreq_data *wrqu,
+			   char *extra)
+{
+	PRTMP_ADAPTER   pAd = dev->ml_priv;
+	struct iw_mlme *pMlme = (struct iw_mlme *)wrqu->data.pointer;
+	MLME_QUEUE_ELEM				MsgElem;
+	MLME_DISASSOC_REQ_STRUCT	DisAssocReq;
+	MLME_DEAUTH_REQ_STRUCT      DeAuthReq;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __FUNCTION__));
+
+	if (pMlme == NULL)
+		return -EINVAL;
+
+	switch(pMlme->cmd)
+	{
+#ifdef IW_MLME_DEAUTH
+		case IW_MLME_DEAUTH:
+			DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DEAUTH\n", __FUNCTION__));
+			COPY_MAC_ADDR(DeAuthReq.Addr, pAd->CommonCfg.Bssid);
+			DeAuthReq.Reason = pMlme->reason_code;
+			MsgElem.MsgLen = sizeof(MLME_DEAUTH_REQ_STRUCT);
+			NdisMoveMemory(MsgElem.Msg, &DeAuthReq, sizeof(MLME_DEAUTH_REQ_STRUCT));
+			MlmeDeauthReqAction(pAd, &MsgElem);
+			if (INFRA_ON(pAd))
+			{
+			    LinkDown(pAd, FALSE);
+			    pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+			}
+			break;
+#endif // IW_MLME_DEAUTH //
+#ifdef IW_MLME_DISASSOC
+		case IW_MLME_DISASSOC:
+			DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DISASSOC\n", __FUNCTION__));
+			COPY_MAC_ADDR(DisAssocReq.Addr, pAd->CommonCfg.Bssid);
+			DisAssocReq.Reason =  pMlme->reason_code;
+
+			MsgElem.Machine = ASSOC_STATE_MACHINE;
+			MsgElem.MsgType = MT2_MLME_DISASSOC_REQ;
+			MsgElem.MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
+			NdisMoveMemory(MsgElem.Msg, &DisAssocReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
+
+			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
+			MlmeDisassocReqAction(pAd, &MsgElem);
+			break;
+#endif // IW_MLME_DISASSOC //
+		default:
+			DBGPRINT(RT_DEBUG_TRACE, ("====> %s - Unknow Command\n", __FUNCTION__));
+			break;
+	}
+
+	return 0;
+}
+#endif // SIOCSIWMLME //
+
+#if WIRELESS_EXT > 17
+int rt_ioctl_siwauth(struct net_device *dev,
+			  struct iw_request_info *info,
+			  union iwreq_data *wrqu, char *extra)
+{
+	PRTMP_ADAPTER   pAdapter = dev->ml_priv;
+	struct iw_param *param = &wrqu->param;
+
+    //check if the interface is down
+	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+	{
+  		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+    	return -ENETDOWN;
+	}
+	switch (param->flags & IW_AUTH_INDEX) {
+    	case IW_AUTH_WPA_VERSION:
+            if (param->value == IW_AUTH_WPA_VERSION_WPA)
+            {
+                pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
+				if (pAdapter->StaCfg.BssType == BSS_ADHOC)
+					pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
+            }
+            else if (param->value == IW_AUTH_WPA_VERSION_WPA2)
+                pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
+
+            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __FUNCTION__, param->value));
+            break;
+    	case IW_AUTH_CIPHER_PAIRWISE:
+            if (param->value == IW_AUTH_CIPHER_NONE)
+            {
+                pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
+                pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+                pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
+            }
+            else if (param->value == IW_AUTH_CIPHER_WEP40 ||
+                     param->value == IW_AUTH_CIPHER_WEP104)
+            {
+                pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
+                pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+                pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
+#ifdef WPA_SUPPLICANT_SUPPORT
+                pAdapter->StaCfg.IEEE8021X = FALSE;
+#endif // WPA_SUPPLICANT_SUPPORT //
+            }
+            else if (param->value == IW_AUTH_CIPHER_TKIP)
+            {
+                pAdapter->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
+                pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+                pAdapter->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
+            }
+            else if (param->value == IW_AUTH_CIPHER_CCMP)
+            {
+                pAdapter->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
+                pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+                pAdapter->StaCfg.PairCipher = Ndis802_11Encryption3Enabled;
+            }
+            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_PAIRWISE - param->value = %d!\n", __FUNCTION__, param->value));
+            break;
+    	case IW_AUTH_CIPHER_GROUP:
+            if (param->value == IW_AUTH_CIPHER_NONE)
+            {
+                pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
+            }
+            else if (param->value == IW_AUTH_CIPHER_WEP40 ||
+                     param->value == IW_AUTH_CIPHER_WEP104)
+            {
+                pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
+            }
+            else if (param->value == IW_AUTH_CIPHER_TKIP)
+            {
+                pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled;
+            }
+            else if (param->value == IW_AUTH_CIPHER_CCMP)
+            {
+                pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled;
+            }
+            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_GROUP - param->value = %d!\n", __FUNCTION__, param->value));
+            break;
+    	case IW_AUTH_KEY_MGMT:
+            if (param->value == IW_AUTH_KEY_MGMT_802_1X)
+            {
+                if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
+                {
+                    pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
+#ifdef WPA_SUPPLICANT_SUPPORT
+                    pAdapter->StaCfg.IEEE8021X = FALSE;
+#endif // WPA_SUPPLICANT_SUPPORT //
+                }
+                else if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
+                {
+                    pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
+#ifdef WPA_SUPPLICANT_SUPPORT
+                    pAdapter->StaCfg.IEEE8021X = FALSE;
+#endif // WPA_SUPPLICANT_SUPPORT //
+                }
+#ifdef WPA_SUPPLICANT_SUPPORT
+                else
+                    // WEP 1x
+                    pAdapter->StaCfg.IEEE8021X = TRUE;
+#endif // WPA_SUPPLICANT_SUPPORT //
+            }
+            else if (param->value == 0)
+            {
+                //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+				STA_PORT_SECURED(pAdapter);
+            }
+            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_KEY_MGMT - param->value = %d!\n", __FUNCTION__, param->value));
+            break;
+    	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+            break;
+    	case IW_AUTH_PRIVACY_INVOKED:
+            /*if (param->value == 0)
+			{
+                pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
+                pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
+                pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+                pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
+        	    pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
+            }*/
+            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_PRIVACY_INVOKED - param->value = %d!\n", __FUNCTION__, param->value));
+    		break;
+    	case IW_AUTH_DROP_UNENCRYPTED:
+            if (param->value != 0)
+                pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+			else
+			{
+                //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+				STA_PORT_SECURED(pAdapter);
+			}
+            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __FUNCTION__, param->value));
+    		break;
+    	case IW_AUTH_80211_AUTH_ALG:
+			if (param->value & IW_AUTH_ALG_SHARED_KEY)
+            {
+				pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
+			}
+            else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
+            {
+				pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
+			}
+            else
+				return -EINVAL;
+            DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_80211_AUTH_ALG - param->value = %d!\n", __FUNCTION__, param->value));
+			break;
+    	case IW_AUTH_WPA_ENABLED:
+    		DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_ENABLED - Driver supports WPA!(param->value = %d)\n", __FUNCTION__, param->value));
+    		break;
+    	default:
+    		return -EOPNOTSUPP;
+}
+
+	return 0;
+}
+
+int rt_ioctl_giwauth(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	PRTMP_ADAPTER   pAdapter = dev->ml_priv;
+	struct iw_param *param = &wrqu->param;
+
+    //check if the interface is down
+	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+    {
+  		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+    	return -ENETDOWN;
+    }
+
+	switch (param->flags & IW_AUTH_INDEX) {
+	case IW_AUTH_DROP_UNENCRYPTED:
+        param->value = (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled) ? 0 : 1;
+		break;
+
+	case IW_AUTH_80211_AUTH_ALG:
+        param->value = (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared) ? IW_AUTH_ALG_SHARED_KEY : IW_AUTH_ALG_OPEN_SYSTEM;
+		break;
+
+	case IW_AUTH_WPA_ENABLED:
+		param->value = (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) ? 1 : 0;
+		break;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+    DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_giwauth::param->value = %d!\n", param->value));
+	return 0;
+}
+
+void fnSetCipherKey(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  INT             keyIdx,
+    IN  UCHAR           CipherAlg,
+    IN  BOOLEAN         bGTK,
+    IN  struct iw_encode_ext *ext)
+{
+    NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
+    pAdapter->SharedKey[BSS0][keyIdx].KeyLen = LEN_TKIP_EK;
+    NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, LEN_TKIP_EK);
+    NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].TxMic, ext->key + LEN_TKIP_EK, LEN_TKIP_TXMICK);
+    NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].RxMic, ext->key + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
+    pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CipherAlg;
+
+    // Update group key information to ASIC Shared Key Table
+	AsicAddSharedKeyEntry(pAdapter,
+						  BSS0,
+						  keyIdx,
+						  pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
+						  pAdapter->SharedKey[BSS0][keyIdx].Key,
+						  pAdapter->SharedKey[BSS0][keyIdx].TxMic,
+						  pAdapter->SharedKey[BSS0][keyIdx].RxMic);
+
+    if (bGTK)
+        // Update ASIC WCID attribute table and IVEIV table
+    	RTMPAddWcidAttributeEntry(pAdapter,
+    							  BSS0,
+    							  keyIdx,
+    							  pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
+    							  NULL);
+    else
+        // Update ASIC WCID attribute table and IVEIV table
+    	RTMPAddWcidAttributeEntry(pAdapter,
+    							  BSS0,
+    							  keyIdx,
+    							  pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
+    							  &pAdapter->MacTab.Content[BSSID_WCID]);
+}
+
+int rt_ioctl_siwencodeext(struct net_device *dev,
+			   struct iw_request_info *info,
+			   union iwreq_data *wrqu,
+			   char *extra)
+			{
+    PRTMP_ADAPTER   pAdapter = dev->ml_priv;
+	struct iw_point *encoding = &wrqu->encoding;
+	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+    int keyIdx, alg = ext->alg;
+
+    //check if the interface is down
+	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+	{
+  		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+    	return -ENETDOWN;
+	}
+
+    if (encoding->flags & IW_ENCODE_DISABLED)
+	{
+        keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
+        // set BSSID wcid entry of the Pair-wise Key table as no-security mode
+	    AsicRemovePairwiseKeyEntry(pAdapter, BSS0, BSSID_WCID);
+        pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
+		pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_NONE;
+		AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)keyIdx);
+        NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
+        DBGPRINT(RT_DEBUG_TRACE, ("%s::Remove all keys!(encoding->flags = %x)\n", __FUNCTION__, encoding->flags));
+    }
+					else
+    {
+        // Get Key Index and convet to our own defined key index
+    	keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
+    	if((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
+    		return -EINVAL;
+
+        if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
+        {
+            pAdapter->StaCfg.DefaultKeyId = keyIdx;
+            DBGPRINT(RT_DEBUG_TRACE, ("%s::DefaultKeyId = %d\n", __FUNCTION__, pAdapter->StaCfg.DefaultKeyId));
+        }
+
+        switch (alg) {
+    		case IW_ENCODE_ALG_NONE:
+                DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_NONE\n", __FUNCTION__));
+    			break;
+    		case IW_ENCODE_ALG_WEP:
+                DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_WEP - ext->key_len = %d, keyIdx = %d\n", __FUNCTION__, ext->key_len, keyIdx));
+    			if (ext->key_len == MAX_WEP_KEY_SIZE)
+                {
+        			pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
+                    pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
+				}
+        		else if (ext->key_len == MIN_WEP_KEY_SIZE)
+                {
+                    pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
+                    pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
+			}
+        		else
+                    return -EINVAL;
+
+                NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,  16);
+			    NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, ext->key_len);
+    			break;
+            case IW_ENCODE_ALG_TKIP:
+                DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_TKIP - keyIdx = %d, ext->key_len = %d\n", __FUNCTION__, keyIdx, ext->key_len));
+                if (ext->key_len == 32)
+                {
+                    if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
+                    {
+                        fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, FALSE, ext);
+                        if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
+                        {
+                            //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+                            STA_PORT_SECURED(pAdapter);
+                        }
+		}
+                    else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
+                    {
+                        fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, TRUE, ext);
+
+                        // set 802.1x port control
+            	        //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+            	        STA_PORT_SECURED(pAdapter);
+                    }
+                }
+                else
+                    return -EINVAL;
+                break;
+            case IW_ENCODE_ALG_CCMP:
+                if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
+		{
+                    fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, FALSE, ext);
+                    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
+                    	//pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+                    	STA_PORT_SECURED(pAdapter);
+                }
+                else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
+                {
+                    fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, TRUE, ext);
+
+                    // set 802.1x port control
+        	        //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+        	        STA_PORT_SECURED(pAdapter);
+                }
+                break;
+    		default:
+    			return -EINVAL;
+		}
+    }
+
+    return 0;
+}
+
+int
+rt_ioctl_giwencodeext(struct net_device *dev,
+			  struct iw_request_info *info,
+			  union iwreq_data *wrqu, char *extra)
+{
+	PRTMP_ADAPTER pAd = dev->ml_priv;
+	PCHAR pKey = NULL;
+	struct iw_point *encoding = &wrqu->encoding;
+	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+	int idx, max_key_len;
+
+	DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_giwencodeext\n"));
+
+	max_key_len = encoding->length - sizeof(*ext);
+	if (max_key_len < 0)
+		return -EINVAL;
+
+	idx = encoding->flags & IW_ENCODE_INDEX;
+	if (idx)
+	{
+		if (idx < 1 || idx > 4)
+			return -EINVAL;
+		idx--;
+
+		if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
+			(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled))
+		{
+			if (idx != pAd->StaCfg.DefaultKeyId)
+			{
+				ext->key_len = 0;
+				return 0;
+			}
+		}
+	}
+	else
+		idx = pAd->StaCfg.DefaultKeyId;
+
+	encoding->flags = idx + 1;
+	memset(ext, 0, sizeof(*ext));
+
+	ext->key_len = 0;
+	switch(pAd->StaCfg.WepStatus) {
+		case Ndis802_11WEPDisabled:
+			ext->alg = IW_ENCODE_ALG_NONE;
+			encoding->flags |= IW_ENCODE_DISABLED;
+			break;
+		case Ndis802_11WEPEnabled:
+			ext->alg = IW_ENCODE_ALG_WEP;
+			if (pAd->SharedKey[BSS0][idx].KeyLen > max_key_len)
+				return -E2BIG;
+			else
+			{
+				ext->key_len = pAd->SharedKey[BSS0][idx].KeyLen;
+				pKey = &(pAd->SharedKey[BSS0][idx].Key[0]);
+			}
+			break;
+		case Ndis802_11Encryption2Enabled:
+		case Ndis802_11Encryption3Enabled:
+			if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
+				ext->alg = IW_ENCODE_ALG_TKIP;
+			else
+				ext->alg = IW_ENCODE_ALG_CCMP;
+
+			if (max_key_len < 32)
+				return -E2BIG;
+			else
+			{
+				ext->key_len = 32;
+				pKey = &pAd->StaCfg.PMK[0];
+			}
+			break;
+		default:
+			return -EINVAL;
+	}
+
+	if (ext->key_len && pKey)
+	{
+		encoding->flags |= IW_ENCODE_ENABLED;
+		memcpy(ext->key, pKey, ext->key_len);
+	}
+
+	return 0;
+}
+
+#ifdef SIOCSIWGENIE
+int rt_ioctl_siwgenie(struct net_device *dev,
+			  struct iw_request_info *info,
+			  union iwreq_data *wrqu, char *extra)
+{
+	PRTMP_ADAPTER   pAd = dev->ml_priv;
+
+	if (wrqu->data.length > MAX_LEN_OF_RSNIE ||
+	    (wrqu->data.length && extra == NULL))
+		return -EINVAL;
+
+	if (wrqu->data.length)
+	{
+		pAd->StaCfg.RSNIE_Len = wrqu->data.length;
+		NdisMoveMemory(&pAd->StaCfg.RSN_IE[0], extra, pAd->StaCfg.RSNIE_Len);
+	}
+	else
+	{
+		pAd->StaCfg.RSNIE_Len = 0;
+		NdisZeroMemory(&pAd->StaCfg.RSN_IE[0], MAX_LEN_OF_RSNIE);
+	}
+
+	return 0;
+}
+#endif // SIOCSIWGENIE //
+
+int rt_ioctl_giwgenie(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	PRTMP_ADAPTER   pAd = dev->ml_priv;
+
+	if ((pAd->StaCfg.RSNIE_Len == 0) ||
+		(pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA))
+	{
+		wrqu->data.length = 0;
+		return 0;
+	}
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+#ifdef SIOCSIWGENIE
+	if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
+	{
+	if (wrqu->data.length < pAd->StaCfg.RSNIE_Len)
+		return -E2BIG;
+
+	wrqu->data.length = pAd->StaCfg.RSNIE_Len;
+	memcpy(extra, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
+	}
+	else
+#endif // SIOCSIWGENIE //
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+	{
+		UCHAR RSNIe = IE_WPA;
+
+		if (wrqu->data.length < (pAd->StaCfg.RSNIE_Len + 2)) // ID, Len
+			return -E2BIG;
+		wrqu->data.length = pAd->StaCfg.RSNIE_Len + 2;
+
+		if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
+            (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
+			RSNIe = IE_RSN;
+
+		extra[0] = (char)RSNIe;
+		extra[1] = pAd->StaCfg.RSNIE_Len;
+		memcpy(extra+2, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
+	}
+
+	return 0;
+}
+
+int rt_ioctl_siwpmksa(struct net_device *dev,
+			   struct iw_request_info *info,
+			   union iwreq_data *wrqu,
+			   char *extra)
+{
+	PRTMP_ADAPTER   pAd = dev->ml_priv;
+	struct iw_pmksa *pPmksa = (struct iw_pmksa *)wrqu->data.pointer;
+	INT	CachedIdx = 0, idx = 0;
+
+	if (pPmksa == NULL)
+		return -EINVAL;
+
+	DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_siwpmksa\n"));
+	switch(pPmksa->cmd)
+	{
+		case IW_PMKSA_FLUSH:
+			NdisZeroMemory(pAd->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
+			DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_FLUSH\n"));
+			break;
+		case IW_PMKSA_REMOVE:
+			for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
+			{
+		        // compare the BSSID
+		        if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
+		        {
+		        	NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN);
+					NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].PMKID, 16);
+					for (idx = CachedIdx; idx < (pAd->StaCfg.SavedPMKNum - 1); idx++)
+					{
+						NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].BSSID[0], &pAd->StaCfg.SavedPMK[idx+1].BSSID[0], MAC_ADDR_LEN);
+						NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].PMKID[0], &pAd->StaCfg.SavedPMK[idx+1].PMKID[0], 16);
+					}
+					pAd->StaCfg.SavedPMKNum--;
+			        break;
+		        }
+	        }
+
+			DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_REMOVE\n"));
+			break;
+		case IW_PMKSA_ADD:
+			for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
+			{
+		        // compare the BSSID
+		        if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
+			        break;
+	        }
+
+	        // Found, replace it
+	        if (CachedIdx < PMKID_NO)
+	        {
+		        DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
+		        NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
+				NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
+		        pAd->StaCfg.SavedPMKNum++;
+	        }
+	        // Not found, replace the last one
+	        else
+	        {
+		        // Randomly replace one
+		        CachedIdx = (pPmksa->bssid.sa_data[5] % PMKID_NO);
+		        DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
+		        NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
+				NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
+	        }
+
+			DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_ADD\n"));
+			break;
+		default:
+			DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - Unknow Command!!\n"));
+			break;
+	}
+
+	return 0;
+}
+#endif // #if WIRELESS_EXT > 17
+
+#ifdef DBG
+static int
+rt_private_ioctl_bbp(struct net_device *dev, struct iw_request_info *info,
+		struct iw_point *wrq, char *extra)
+			{
+	CHAR				*this_char;
+	CHAR				*value = NULL;
+	UCHAR				regBBP = 0;
+//	CHAR				arg[255]={0};
+	UINT32				bbpId;
+	UINT32				bbpValue;
+	BOOLEAN				bIsPrintAllBBP = FALSE;
+	INT					Status = 0;
+    PRTMP_ADAPTER       pAdapter = dev->ml_priv;
+
+
+	memset(extra, 0x00, IW_PRIV_SIZE_MASK);
+
+	if (wrq->length > 1) //No parameters.
+				{
+		sprintf(extra, "\n");
+
+		//Parsing Read or Write
+		this_char = wrq->pointer;
+		DBGPRINT(RT_DEBUG_TRACE, ("this_char=%s\n", this_char));
+		if (!*this_char)
+			goto next;
+
+		if ((value = rtstrchr(this_char, '=')) != NULL)
+			*value++ = 0;
+
+		if (!value || !*value)
+		{ //Read
+			DBGPRINT(RT_DEBUG_TRACE, ("this_char=%s, value=%s\n", this_char, value));
+			if (sscanf(this_char, "%d", &(bbpId)) == 1)
+			{
+#ifndef RT30xx
+				if (bbpId <= 136)
+#endif // RT30xx //
+#ifdef RT30xx
+				if (bbpId <= 138)  // edit by johnli, RF power sequence setup, add BBP R138 for ADC dynamic on/off control
+#endif // RT30xx //
+				{
+#ifdef RALINK_ATE
+					if (ATE_ON(pAdapter))
+					{
+						ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+					}
+					else
+#endif // RALINK_ATE //
+					{
+					RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+					}
+					sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X\n", bbpId, bbpId*2, regBBP);
+                    wrq->length = strlen(extra) + 1; // 1: size of '\0'
+					DBGPRINT(RT_DEBUG_TRACE, ("msg=%s\n", extra));
+				}
+				else
+				{//Invalid parametes, so default printk all bbp
+					bIsPrintAllBBP = TRUE;
+					goto next;
+				}
+			}
+			else
+			{ //Invalid parametes, so default printk all bbp
+				bIsPrintAllBBP = TRUE;
+				goto next;
+			}
+		}
+		else
+		{ //Write
+			if ((sscanf(this_char, "%d", &(bbpId)) == 1) && (sscanf(value, "%x", &(bbpValue)) == 1))
+			{
+#ifndef RT30xx
+				if (bbpId <= 136)
+#endif // RT30xx //
+#ifdef RT30xx
+				if (bbpId <= 138)  // edit by johnli, RF power sequence setup, add BBP R138 for ADC dynamic on/off control
+#endif // RT30xx //
+				{
+#ifdef RALINK_ATE
+					if (ATE_ON(pAdapter))
+					{
+						ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, bbpId, bbpValue);
+						//Read it back for showing
+						ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+					}
+					else
+#endif // RALINK_ATE //
+					{
+					    RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, bbpId, bbpValue);
+    					//Read it back for showing
+    					RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+			}
+					sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X\n", bbpId, bbpId*2, regBBP);
+                    wrq->length = strlen(extra) + 1; // 1: size of '\0'
+					DBGPRINT(RT_DEBUG_TRACE, ("msg=%s\n", extra));
+				}
+				else
+				{//Invalid parametes, so default printk all bbp
+					bIsPrintAllBBP = TRUE;
+					goto next;
+				}
+			}
+			else
+			{ //Invalid parametes, so default printk all bbp
+				bIsPrintAllBBP = TRUE;
+				goto next;
+			}
+		}
+		}
+	else
+		bIsPrintAllBBP = TRUE;
+
+next:
+	if (bIsPrintAllBBP)
+	{
+		memset(extra, 0x00, IW_PRIV_SIZE_MASK);
+		sprintf(extra, "\n");
+#ifndef RT30xx
+		for (bbpId = 0; bbpId <= 136; bbpId++)
+#endif // RT30xx //
+#ifdef RT30xx
+		for (bbpId = 0; bbpId <= 138; bbpId++)  // edit by johnli, RF power sequence setup, add BBP R138 for ADC dynamic on/off control
+#endif // RT30xx //
+		{
+		    if (strlen(extra) >= (IW_PRIV_SIZE_MASK - 10))
+                break;
+#ifdef RALINK_ATE
+			if (ATE_ON(pAdapter))
+			{
+				ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+			}
+			else
+#endif // RALINK_ATE //
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+/*
+			sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X    ", bbpId, bbpId*2, regBBP);
+			if (bbpId%5 == 4)
+				sprintf(extra+strlen(extra), "\n");
+*/
+			sprintf(extra+strlen(extra), "%03d = %02X\n", bbpId, regBBP);  // edit by johnli, change display format
+		}
+
+        wrq->length = strlen(extra) + 1; // 1: size of '\0'
+        DBGPRINT(RT_DEBUG_TRACE, ("wrq->length = %d\n", wrq->length));
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<==rt_private_ioctl_bbp\n\n"));
+
+    return Status;
+}
+#endif // DBG //
+
+int rt_ioctl_siwrate(struct net_device *dev,
+			struct iw_request_info *info,
+			union iwreq_data *wrqu, char *extra)
+{
+    PRTMP_ADAPTER   pAd = dev->ml_priv;
+    UINT32          rate = wrqu->bitrate.value, fixed = wrqu->bitrate.fixed;
+
+    //check if the interface is down
+	if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+	{
+  		DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::Network is down!\n"));
+    	return -ENETDOWN;
+	}
+
+    DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(rate = %d, fixed = %d)\n", rate, fixed));
+    /* rate = -1 => auto rate
+       rate = X, fixed = 1 => (fixed rate X)
+    */
+    if (rate == -1)
+    {
+		//Auto Rate
+		pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
+		pAd->StaCfg.bAutoTxRateSwitch = TRUE;
+		if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
+		    (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
+			RTMPSetDesiredRates(pAd, -1);
+
+#ifdef DOT11_N_SUPPORT
+		SetCommonHT(pAd);
+#endif // DOT11_N_SUPPORT //
+    }
+    else
+    {
+        if (fixed)
+        {
+        	pAd->StaCfg.bAutoTxRateSwitch = FALSE;
+            if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
+                (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
+                RTMPSetDesiredRates(pAd, rate);
+            else
+            {
+                pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
+#ifdef DOT11_N_SUPPORT
+                SetCommonHT(pAd);
+#endif // DOT11_N_SUPPORT //
+            }
+            DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(HtMcs=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.MCS));
+        }
+        else
+        {
+            // TODO: rate = X, fixed = 0 => (rates <= X)
+            return -EOPNOTSUPP;
+        }
+    }
+
+    return 0;
+}
+
+int rt_ioctl_giwrate(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+    PRTMP_ADAPTER   pAd = dev->ml_priv;
+    int rate_index = 0, rate_count = 0;
+    HTTRANSMIT_SETTING ht_setting;
+    __s32 ralinkrate[] =
+	{2,  4,   11,  22, // CCK
+	12, 18,   24,  36, 48, 72, 96, 108, // OFDM
+	13, 26,   39,  52,  78, 104, 117, 130, 26,  52,  78, 104, 156, 208, 234, 260, // 20MHz, 800ns GI, MCS: 0 ~ 15
+	39, 78,  117, 156, 234, 312, 351, 390,										  // 20MHz, 800ns GI, MCS: 16 ~ 23
+	27, 54,   81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, // 40MHz, 800ns GI, MCS: 0 ~ 15
+	81, 162, 243, 324, 486, 648, 729, 810,										  // 40MHz, 800ns GI, MCS: 16 ~ 23
+	14, 29,   43,  57,  87, 115, 130, 144, 29, 59,   87, 115, 173, 230, 260, 288, // 20MHz, 400ns GI, MCS: 0 ~ 15
+	43, 87,  130, 173, 260, 317, 390, 433,										  // 20MHz, 400ns GI, MCS: 16 ~ 23
+	30, 60,   90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, // 40MHz, 400ns GI, MCS: 0 ~ 15
+	90, 180, 270, 360, 540, 720, 810, 900};										  // 40MHz, 400ns GI, MCS: 16 ~ 23
+
+    rate_count = sizeof(ralinkrate)/sizeof(__s32);
+    //check if the interface is down
+	if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+	{
+  		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+    	return -ENETDOWN;
+	}
+
+    if ((pAd->StaCfg.bAutoTxRateSwitch == FALSE) &&
+        (INFRA_ON(pAd)) &&
+        ((pAd->CommonCfg.PhyMode <= PHY_11G) || (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM)))
+        ht_setting.word = pAd->StaCfg.HTPhyMode.word;
+    else
+        ht_setting.word = pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word;
+
+#ifdef DOT11_N_SUPPORT
+    if (ht_setting.field.MODE >= MODE_HTMIX)
+    {
+//    	rate_index = 12 + ((UCHAR)ht_setting.field.BW *16) + ((UCHAR)ht_setting.field.ShortGI *32) + ((UCHAR)ht_setting.field.MCS);
+    	rate_index = 12 + ((UCHAR)ht_setting.field.BW *24) + ((UCHAR)ht_setting.field.ShortGI *48) + ((UCHAR)ht_setting.field.MCS);
+    }
+    else
+#endif // DOT11_N_SUPPORT //
+    if (ht_setting.field.MODE == MODE_OFDM)
+    	rate_index = (UCHAR)(ht_setting.field.MCS) + 4;
+    else if (ht_setting.field.MODE == MODE_CCK)
+    	rate_index = (UCHAR)(ht_setting.field.MCS);
+
+    if (rate_index < 0)
+        rate_index = 0;
+
+    if (rate_index > rate_count)
+        rate_index = rate_count;
+
+    wrqu->bitrate.value = ralinkrate[rate_index] * 500000;
+    wrqu->bitrate.disabled = 0;
+
+    return 0;
+}
+
+static const iw_handler rt_handler[] =
+{
+	(iw_handler) NULL,			            /* SIOCSIWCOMMIT */
+	(iw_handler) rt_ioctl_giwname,			/* SIOCGIWNAME   */
+	(iw_handler) NULL,			            /* SIOCSIWNWID   */
+	(iw_handler) NULL,			            /* SIOCGIWNWID   */
+	(iw_handler) rt_ioctl_siwfreq,		    /* SIOCSIWFREQ   */
+	(iw_handler) rt_ioctl_giwfreq,		    /* SIOCGIWFREQ   */
+	(iw_handler) rt_ioctl_siwmode,		    /* SIOCSIWMODE   */
+	(iw_handler) rt_ioctl_giwmode,		    /* SIOCGIWMODE   */
+	(iw_handler) NULL,		                /* SIOCSIWSENS   */
+	(iw_handler) NULL,		                /* SIOCGIWSENS   */
+	(iw_handler) NULL /* not used */,		/* SIOCSIWRANGE  */
+	(iw_handler) rt_ioctl_giwrange,		    /* SIOCGIWRANGE  */
+	(iw_handler) NULL /* not used */,		/* SIOCSIWPRIV   */
+	(iw_handler) NULL /* kernel code */,    /* SIOCGIWPRIV   */
+	(iw_handler) NULL /* not used */,		/* SIOCSIWSTATS  */
+	(iw_handler) rt28xx_get_wireless_stats /* kernel code */,    /* SIOCGIWSTATS  */
+	(iw_handler) NULL,		                /* SIOCSIWSPY    */
+	(iw_handler) NULL,		                /* SIOCGIWSPY    */
+	(iw_handler) NULL,				        /* SIOCSIWTHRSPY */
+	(iw_handler) NULL,				        /* SIOCGIWTHRSPY */
+	(iw_handler) rt_ioctl_siwap,            /* SIOCSIWAP     */
+	(iw_handler) rt_ioctl_giwap,		    /* SIOCGIWAP     */
+#ifdef SIOCSIWMLME
+	(iw_handler) rt_ioctl_siwmlme,	        /* SIOCSIWMLME   */
+#else
+	(iw_handler) NULL,				        /* SIOCSIWMLME */
+#endif // SIOCSIWMLME //
+	(iw_handler) rt_ioctl_iwaplist,		    /* SIOCGIWAPLIST */
+#ifdef SIOCGIWSCAN
+	(iw_handler) rt_ioctl_siwscan,		    /* SIOCSIWSCAN   */
+	(iw_handler) rt_ioctl_giwscan,		    /* SIOCGIWSCAN   */
+#else
+	(iw_handler) NULL,				        /* SIOCSIWSCAN   */
+	(iw_handler) NULL,				        /* SIOCGIWSCAN   */
+#endif /* SIOCGIWSCAN */
+	(iw_handler) rt_ioctl_siwessid,		    /* SIOCSIWESSID  */
+	(iw_handler) rt_ioctl_giwessid,		    /* SIOCGIWESSID  */
+	(iw_handler) rt_ioctl_siwnickn,		    /* SIOCSIWNICKN  */
+	(iw_handler) rt_ioctl_giwnickn,		    /* SIOCGIWNICKN  */
+	(iw_handler) NULL,				        /* -- hole --    */
+	(iw_handler) NULL,				        /* -- hole --    */
+	(iw_handler) rt_ioctl_siwrate,          /* SIOCSIWRATE   */
+	(iw_handler) rt_ioctl_giwrate,          /* SIOCGIWRATE   */
+	(iw_handler) rt_ioctl_siwrts,		    /* SIOCSIWRTS    */
+	(iw_handler) rt_ioctl_giwrts,		    /* SIOCGIWRTS    */
+	(iw_handler) rt_ioctl_siwfrag,		    /* SIOCSIWFRAG   */
+	(iw_handler) rt_ioctl_giwfrag,		    /* SIOCGIWFRAG   */
+	(iw_handler) NULL,		                /* SIOCSIWTXPOW  */
+	(iw_handler) NULL,		                /* SIOCGIWTXPOW  */
+	(iw_handler) NULL,		                /* SIOCSIWRETRY  */
+	(iw_handler) NULL,		                /* SIOCGIWRETRY  */
+	(iw_handler) rt_ioctl_siwencode,		/* SIOCSIWENCODE */
+	(iw_handler) rt_ioctl_giwencode,		/* SIOCGIWENCODE */
+	(iw_handler) NULL,		                /* SIOCSIWPOWER  */
+	(iw_handler) NULL,		                /* SIOCGIWPOWER  */
+	(iw_handler) NULL,						/* -- hole -- */
+	(iw_handler) NULL,						/* -- hole -- */
+#if WIRELESS_EXT > 17
+    (iw_handler) rt_ioctl_siwgenie,         /* SIOCSIWGENIE  */
+	(iw_handler) rt_ioctl_giwgenie,         /* SIOCGIWGENIE  */
+	(iw_handler) rt_ioctl_siwauth,		    /* SIOCSIWAUTH   */
+	(iw_handler) rt_ioctl_giwauth,		    /* SIOCGIWAUTH   */
+	(iw_handler) rt_ioctl_siwencodeext,	    /* SIOCSIWENCODEEXT */
+	(iw_handler) rt_ioctl_giwencodeext,		/* SIOCGIWENCODEEXT */
+	(iw_handler) rt_ioctl_siwpmksa,         /* SIOCSIWPMKSA  */
+#endif
+};
+
+static const iw_handler rt_priv_handlers[] = {
+	(iw_handler) NULL, /* + 0x00 */
+	(iw_handler) NULL, /* + 0x01 */
+#ifndef CONFIG_AP_SUPPORT
+	(iw_handler) rt_ioctl_setparam, /* + 0x02 */
+#else
+	(iw_handler) NULL, /* + 0x02 */
+#endif // CONFIG_AP_SUPPORT //
+#ifdef DBG
+	(iw_handler) rt_private_ioctl_bbp, /* + 0x03 */
+#else
+	(iw_handler) NULL, /* + 0x03 */
+#endif
+	(iw_handler) NULL, /* + 0x04 */
+	(iw_handler) NULL, /* + 0x05 */
+	(iw_handler) NULL, /* + 0x06 */
+	(iw_handler) NULL, /* + 0x07 */
+	(iw_handler) NULL, /* + 0x08 */
+	(iw_handler) rt_private_get_statistics, /* + 0x09 */
+	(iw_handler) NULL, /* + 0x0A */
+	(iw_handler) NULL, /* + 0x0B */
+	(iw_handler) NULL, /* + 0x0C */
+	(iw_handler) NULL, /* + 0x0D */
+	(iw_handler) NULL, /* + 0x0E */
+	(iw_handler) NULL, /* + 0x0F */
+	(iw_handler) NULL, /* + 0x10 */
+	(iw_handler) rt_private_show, /* + 0x11 */
+    (iw_handler) NULL, /* + 0x12 */
+	(iw_handler) NULL, /* + 0x13 */
+	(iw_handler) NULL, /* + 0x15 */
+	(iw_handler) NULL, /* + 0x17 */
+	(iw_handler) NULL, /* + 0x18 */
+};
+
+const struct iw_handler_def rt28xx_iw_handler_def =
+{
+#define	N(a)	(sizeof (a) / sizeof (a[0]))
+	.standard	= (iw_handler *) rt_handler,
+	.num_standard	= sizeof(rt_handler) / sizeof(iw_handler),
+	.private	= (iw_handler *) rt_priv_handlers,
+	.num_private		= N(rt_priv_handlers),
+	.private_args	= (struct iw_priv_args *) privtab,
+	.num_private_args	= N(privtab),
+#if IW_HANDLER_VERSION >= 7
+    .get_wireless_stats = rt28xx_get_wireless_stats,
+#endif
+};
+
+INT RTMPSetInformation(
+    IN  PRTMP_ADAPTER pAdapter,
+    IN  OUT struct ifreq    *rq,
+    IN  INT                 cmd)
+{
+    struct iwreq                        *wrq = (struct iwreq *) rq;
+    NDIS_802_11_SSID                    Ssid;
+    NDIS_802_11_MAC_ADDRESS             Bssid;
+    RT_802_11_PHY_MODE                  PhyMode;
+    RT_802_11_STA_CONFIG                StaConfig;
+    NDIS_802_11_RATES                   aryRates;
+    RT_802_11_PREAMBLE                  Preamble;
+    NDIS_802_11_WEP_STATUS              WepStatus;
+    NDIS_802_11_AUTHENTICATION_MODE     AuthMode = Ndis802_11AuthModeMax;
+    NDIS_802_11_NETWORK_INFRASTRUCTURE  BssType;
+    NDIS_802_11_RTS_THRESHOLD           RtsThresh;
+    NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
+    NDIS_802_11_POWER_MODE              PowerMode;
+    PNDIS_802_11_KEY                    pKey = NULL;
+    PNDIS_802_11_WEP			        pWepKey =NULL;
+    PNDIS_802_11_REMOVE_KEY             pRemoveKey = NULL;
+    NDIS_802_11_CONFIGURATION           Config, *pConfig = NULL;
+    NDIS_802_11_NETWORK_TYPE            NetType;
+    ULONG                               Now;
+    UINT                                KeyIdx = 0;
+    INT                                 Status = NDIS_STATUS_SUCCESS, MaxPhyMode = PHY_11G;
+    ULONG                               PowerTemp;
+    BOOLEAN                             RadioState;
+    BOOLEAN                             StateMachineTouched = FALSE;
+#ifdef DOT11_N_SUPPORT
+	OID_SET_HT_PHYMODE					HT_PhyMode;	//11n ,kathy
+#endif // DOT11_N_SUPPORT //
+#ifdef WPA_SUPPLICANT_SUPPORT
+    PNDIS_802_11_PMKID                  pPmkId = NULL;
+    BOOLEAN				                IEEE8021xState = FALSE;
+    BOOLEAN				                IEEE8021x_required_keys = FALSE;
+    UCHAR                               wpa_supplicant_enable = 0;
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef SNMP_SUPPORT
+	TX_RTY_CFG_STRUC			tx_rty_cfg;
+	ULONG						ShortRetryLimit, LongRetryLimit;
+	UCHAR						ctmp;
+#endif // SNMP_SUPPORT //
+
+
+#ifdef DOT11_N_SUPPORT
+	MaxPhyMode = PHY_11N_5G;
+#endif // DOT11_N_SUPPORT //
+
+
+	DBGPRINT(RT_DEBUG_TRACE, ("-->RTMPSetInformation(),	0x%08x\n", cmd&0x7FFF));
+    switch(cmd & 0x7FFF) {
+        case RT_OID_802_11_COUNTRY_REGION:
+            if (wrq->u.data.length < sizeof(UCHAR))
+                Status = -EINVAL;
+			// Only avaliable when EEPROM not programming
+            else if (!(pAdapter->CommonCfg.CountryRegion & 0x80) && !(pAdapter->CommonCfg.CountryRegionForABand & 0x80))
+            {
+                ULONG   Country;
+                UCHAR	TmpPhy;
+
+				Status = copy_from_user(&Country, wrq->u.data.pointer, wrq->u.data.length);
+				pAdapter->CommonCfg.CountryRegion = (UCHAR)(Country & 0x000000FF);
+				pAdapter->CommonCfg.CountryRegionForABand = (UCHAR)((Country >> 8) & 0x000000FF);
+                TmpPhy = pAdapter->CommonCfg.PhyMode;
+				pAdapter->CommonCfg.PhyMode = 0xff;
+				// Build all corresponding channel information
+				RTMPSetPhyMode(pAdapter, TmpPhy);
+#ifdef DOT11_N_SUPPORT
+				SetCommonHT(pAdapter);
+#endif // DOT11_N_SUPPORT //
+				DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_COUNTRY_REGION (A:%d  B/G:%d)\n", pAdapter->CommonCfg.CountryRegionForABand,
+				    pAdapter->CommonCfg.CountryRegion));
+            }
+            break;
+        case OID_802_11_BSSID_LIST_SCAN:
+ #ifdef RALINK_ATE
+			if (ATE_ON(pAdapter))
+			{
+				DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
+				break;
+			}
+#endif // RALINK_ATE //
+            Now = jiffies;
+			DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID_LIST_SCAN, TxCnt = %d \n", pAdapter->RalinkCounters.LastOneSecTotalTxCount));
+
+            if (MONITOR_ON(pAdapter))
+            {
+                DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
+                break;
+            }
+
+			//Benson add 20080527, when radio off, sta don't need to scan
+			if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF))
+				break;
+
+			if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+			{
+                DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is scanning now !!!\n"));
+				pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
+				Status = NDIS_STATUS_SUCCESS;
+                break;
+            }
+
+			if (pAdapter->RalinkCounters.LastOneSecTotalTxCount > 100)
+            {
+                DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
+				Status = NDIS_STATUS_SUCCESS;
+				pAdapter->StaCfg.ScanCnt = 99;		// Prevent auto scan triggered by this OID
+				break;
+            }
+
+            if ((OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
+				((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
+				(pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+				(pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
+				(pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) &&
+                (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
+            {
+                DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
+				Status = NDIS_STATUS_SUCCESS;
+				pAdapter->StaCfg.ScanCnt = 99;		// Prevent auto scan triggered by this OID
+				break;
+            }
+
+
+            if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
+            {
+                RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
+                DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
+            }
+
+            // tell CNTL state machine to call NdisMSetInformationComplete() after completing
+            // this request, because this request is initiated by NDIS.
+            pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
+            // Reset allowed scan retries
+            pAdapter->StaCfg.ScanCnt = 0;
+            pAdapter->StaCfg.LastScanTime = Now;
+
+			pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
+            RTMP_SET_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+            MlmeEnqueue(pAdapter,
+                        MLME_CNTL_STATE_MACHINE,
+                        OID_802_11_BSSID_LIST_SCAN,
+                        0,
+                        NULL);
+
+            Status = NDIS_STATUS_SUCCESS;
+            StateMachineTouched = TRUE;
+            break;
+        case OID_802_11_SSID:
+            if (wrq->u.data.length != sizeof(NDIS_802_11_SSID))
+                Status = -EINVAL;
+            else
+            {
+            	PCHAR pSsidString = NULL;
+                Status = copy_from_user(&Ssid, wrq->u.data.pointer, wrq->u.data.length);
+
+				DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SSID (Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
+                if (Ssid.SsidLength > MAX_LEN_OF_SSID)
+                    Status = -EINVAL;
+                else
+                {
+                	if (Ssid.SsidLength == 0)
+                	{
+                		Set_SSID_Proc(pAdapter, "");
+                	}
+					else
+                	{
+	                	pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
+						if (pSsidString)
+						{
+							NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
+							NdisMoveMemory(pSsidString, Ssid.Ssid, Ssid.SsidLength);
+	                		Set_SSID_Proc(pAdapter, pSsidString);
+							kfree(pSsidString);
+						}
+						else
+							Status = -ENOMEM;
+                	}
+                }
+            }
+            break;
+        case OID_802_11_BSSID:
+#ifdef RALINK_ATE
+			if (ATE_ON(pAdapter))
+			{
+				DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
+				break;
+			}
+#endif // RALINK_ATE //
+            if (wrq->u.data.length != sizeof(NDIS_802_11_MAC_ADDRESS))
+                Status  = -EINVAL;
+            else
+            {
+                Status = copy_from_user(&Bssid, wrq->u.data.pointer, wrq->u.data.length);
+
+                // tell CNTL state machine to call NdisMSetInformationComplete() after completing
+                // this request, because this request is initiated by NDIS.
+                pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
+
+				// Prevent to connect AP again in STAMlmePeriodicExec
+				pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
+
+                // Reset allowed scan retries
+				pAdapter->StaCfg.ScanCnt = 0;
+
+                if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
+                {
+                    RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
+                    DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
+                }
+                MlmeEnqueue(pAdapter,
+                            MLME_CNTL_STATE_MACHINE,
+                            OID_802_11_BSSID,
+                            sizeof(NDIS_802_11_MAC_ADDRESS),
+                            (VOID *)&Bssid);
+                Status = NDIS_STATUS_SUCCESS;
+                StateMachineTouched = TRUE;
+
+                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID %02x:%02x:%02x:%02x:%02x:%02x\n",
+                                        Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
+            }
+            break;
+        case RT_OID_802_11_RADIO:
+            if (wrq->u.data.length != sizeof(BOOLEAN))
+                Status  = -EINVAL;
+            else
+            {
+                Status = copy_from_user(&RadioState, wrq->u.data.pointer, wrq->u.data.length);
+                DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RADIO (=%d)\n", RadioState));
+                if (pAdapter->StaCfg.bSwRadio != RadioState)
+                {
+                    pAdapter->StaCfg.bSwRadio = RadioState;
+                    if (pAdapter->StaCfg.bRadio != (pAdapter->StaCfg.bHwRadio && pAdapter->StaCfg.bSwRadio))
+                    {
+                        pAdapter->StaCfg.bRadio = (pAdapter->StaCfg.bHwRadio && pAdapter->StaCfg.bSwRadio);
+                        if (pAdapter->StaCfg.bRadio == TRUE)
+                        {
+                            MlmeRadioOn(pAdapter);
+                            // Update extra information
+							pAdapter->ExtraInfo = EXTRA_INFO_CLEAR;
+                        }
+                        else
+                        {
+                            MlmeRadioOff(pAdapter);
+                            // Update extra information
+							pAdapter->ExtraInfo = SW_RADIO_OFF;
+                        }
+                    }
+                }
+            }
+            break;
+        case RT_OID_802_11_PHY_MODE:
+            if (wrq->u.data.length != sizeof(RT_802_11_PHY_MODE))
+                Status  = -EINVAL;
+            else
+            {
+                Status = copy_from_user(&PhyMode, wrq->u.data.pointer, wrq->u.data.length);
+				if (PhyMode <= MaxPhyMode)
+				{
+                	RTMPSetPhyMode(pAdapter, PhyMode);
+#ifdef DOT11_N_SUPPORT
+					SetCommonHT(pAdapter);
+#endif // DOT11_N_SUPPORT //
+				}
+                DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PHY_MODE (=%d)\n", PhyMode));
+            }
+            break;
+        case RT_OID_802_11_STA_CONFIG:
+            if (wrq->u.data.length != sizeof(RT_802_11_STA_CONFIG))
+                Status  = -EINVAL;
+            else
+            {
+                Status = copy_from_user(&StaConfig, wrq->u.data.pointer, wrq->u.data.length);
+                pAdapter->CommonCfg.bEnableTxBurst = StaConfig.EnableTxBurst;
+                pAdapter->CommonCfg.UseBGProtection = StaConfig.UseBGProtection;
+                pAdapter->CommonCfg.bUseShortSlotTime = 1; // 2003-10-30 always SHORT SLOT capable
+                if ((pAdapter->CommonCfg.PhyMode != StaConfig.AdhocMode) &&
+					(StaConfig.AdhocMode <= MaxPhyMode))
+                {
+                    // allow dynamic change of "USE OFDM rate or not" in ADHOC mode
+                    // if setting changed, need to reset current TX rate as well as BEACON frame format
+                    pAdapter->CommonCfg.PhyMode = StaConfig.AdhocMode;
+                    if (pAdapter->StaCfg.BssType == BSS_ADHOC)
+                    {
+                    	RTMPSetPhyMode(pAdapter, PhyMode);
+                        MlmeUpdateTxRates(pAdapter, FALSE, 0);
+                        MakeIbssBeacon(pAdapter);           // re-build BEACON frame
+                        AsicEnableIbssSync(pAdapter);   // copy to on-chip memory
+                    }
+                }
+                DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_STA_CONFIG (Burst=%d, Protection=%ld,ShortSlot=%d\n",
+                                        pAdapter->CommonCfg.bEnableTxBurst,
+                                        pAdapter->CommonCfg.UseBGProtection,
+                                        pAdapter->CommonCfg.bUseShortSlotTime));
+            }
+            break;
+        case OID_802_11_DESIRED_RATES:
+            if (wrq->u.data.length != sizeof(NDIS_802_11_RATES))
+                Status  = -EINVAL;
+            else
+            {
+                Status = copy_from_user(&aryRates, wrq->u.data.pointer, wrq->u.data.length);
+                NdisZeroMemory(pAdapter->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
+                NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates, sizeof(NDIS_802_11_RATES));
+                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DESIRED_RATES (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n",
+                    pAdapter->CommonCfg.DesireRate[0],pAdapter->CommonCfg.DesireRate[1],
+                    pAdapter->CommonCfg.DesireRate[2],pAdapter->CommonCfg.DesireRate[3],
+                    pAdapter->CommonCfg.DesireRate[4],pAdapter->CommonCfg.DesireRate[5],
+                    pAdapter->CommonCfg.DesireRate[6],pAdapter->CommonCfg.DesireRate[7] ));
+                // Changing DesiredRate may affect the MAX TX rate we used to TX frames out
+                MlmeUpdateTxRates(pAdapter, FALSE, 0);
+            }
+            break;
+        case RT_OID_802_11_PREAMBLE:
+            if (wrq->u.data.length != sizeof(RT_802_11_PREAMBLE))
+                Status  = -EINVAL;
+            else
+            {
+                Status = copy_from_user(&Preamble, wrq->u.data.pointer, wrq->u.data.length);
+                if (Preamble == Rt802_11PreambleShort)
+                {
+                    pAdapter->CommonCfg.TxPreamble = Preamble;
+                    MlmeSetTxPreamble(pAdapter, Rt802_11PreambleShort);
+                }
+                else if ((Preamble == Rt802_11PreambleLong) || (Preamble == Rt802_11PreambleAuto))
+                {
+                    // if user wants AUTO, initialize to LONG here, then change according to AP's
+                    // capability upon association.
+                    pAdapter->CommonCfg.TxPreamble = Preamble;
+                    MlmeSetTxPreamble(pAdapter, Rt802_11PreambleLong);
+                }
+                else
+                {
+                    Status = -EINVAL;
+                    break;
+                }
+                DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PREAMBLE (=%d)\n", Preamble));
+            }
+            break;
+        case OID_802_11_WEP_STATUS:
+            if (wrq->u.data.length != sizeof(NDIS_802_11_WEP_STATUS))
+                Status  = -EINVAL;
+            else
+            {
+                Status = copy_from_user(&WepStatus, wrq->u.data.pointer, wrq->u.data.length);
+                // Since TKIP, AES, WEP are all supported. It should not have any invalid setting
+                if (WepStatus <= Ndis802_11Encryption3KeyAbsent)
+                {
+                    if (pAdapter->StaCfg.WepStatus != WepStatus)
+                    {
+                        // Config has changed
+                        pAdapter->bConfigChanged = TRUE;
+                    }
+                    pAdapter->StaCfg.WepStatus     = WepStatus;
+                    pAdapter->StaCfg.OrigWepStatus = WepStatus;
+                    pAdapter->StaCfg.PairCipher    = WepStatus;
+                	pAdapter->StaCfg.GroupCipher   = WepStatus;
+                }
+                else
+                {
+                    Status  = -EINVAL;
+                    break;
+                }
+                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEP_STATUS (=%d)\n",WepStatus));
+            }
+            break;
+        case OID_802_11_AUTHENTICATION_MODE:
+            if (wrq->u.data.length != sizeof(NDIS_802_11_AUTHENTICATION_MODE))
+                Status  = -EINVAL;
+            else
+            {
+                Status = copy_from_user(&AuthMode, wrq->u.data.pointer, wrq->u.data.length);
+                if (AuthMode > Ndis802_11AuthModeMax)
+                {
+                    Status  = -EINVAL;
+                    break;
+                }
+                else
+                {
+                    if (pAdapter->StaCfg.AuthMode != AuthMode)
+                    {
+                        // Config has changed
+                        pAdapter->bConfigChanged = TRUE;
+                    }
+                    pAdapter->StaCfg.AuthMode = AuthMode;
+                }
+                pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_AUTHENTICATION_MODE (=%d) \n",pAdapter->StaCfg.AuthMode));
+            }
+            break;
+        case OID_802_11_INFRASTRUCTURE_MODE:
+            if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_INFRASTRUCTURE))
+                Status  = -EINVAL;
+            else
+            {
+                Status = copy_from_user(&BssType, wrq->u.data.pointer, wrq->u.data.length);
+
+				if (BssType == Ndis802_11IBSS)
+					Set_NetworkType_Proc(pAdapter, "Adhoc");
+				else if (BssType == Ndis802_11Infrastructure)
+					Set_NetworkType_Proc(pAdapter, "Infra");
+				else if (BssType == Ndis802_11Monitor)
+					Set_NetworkType_Proc(pAdapter, "Monitor");
+				else
+				{
+					Status  = -EINVAL;
+					DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_INFRASTRUCTURE_MODE (unknown)\n"));
+				}
+			}
+			break;
+	 case OID_802_11_REMOVE_WEP:
+            DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_WEP\n"));
+            if (wrq->u.data.length != sizeof(NDIS_802_11_KEY_INDEX))
+            {
+				Status = -EINVAL;
+            }
+            else
+            {
+				KeyIdx = *(NDIS_802_11_KEY_INDEX *) wrq->u.data.pointer;
+
+				if (KeyIdx & 0x80000000)
+				{
+					// Should never set default bit when remove key
+					Status = -EINVAL;
+				}
+				else
+				{
+					KeyIdx = KeyIdx & 0x0fffffff;
+					if (KeyIdx >= 4){
+						Status = -EINVAL;
+					}
+					else
+					{
+						pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = 0;
+						pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
+						AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)KeyIdx);
+					}
+				}
+            }
+            break;
+        case RT_OID_802_11_RESET_COUNTERS:
+            NdisZeroMemory(&pAdapter->WlanCounters, sizeof(COUNTER_802_11));
+            NdisZeroMemory(&pAdapter->Counters8023, sizeof(COUNTER_802_3));
+            NdisZeroMemory(&pAdapter->RalinkCounters, sizeof(COUNTER_RALINK));
+            pAdapter->Counters8023.RxNoBuffer   = 0;
+			pAdapter->Counters8023.GoodReceives = 0;
+			pAdapter->Counters8023.RxNoBuffer   = 0;
+#ifdef RT2870
+			pAdapter->BulkOutComplete	= 0;
+			pAdapter->BulkOutCompleteOther= 0;
+			pAdapter->BulkOutCompleteCancel = 0;
+			pAdapter->BulkOutReq = 0;
+			pAdapter->BulkInReq= 0;
+			pAdapter->BulkInComplete = 0;
+			pAdapter->BulkInCompleteFail = 0;
+#endif // RT2870 //
+            DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RESET_COUNTERS \n"));
+            break;
+        case OID_802_11_RTS_THRESHOLD:
+            if (wrq->u.data.length != sizeof(NDIS_802_11_RTS_THRESHOLD))
+                Status  = -EINVAL;
+            else
+            {
+                Status = copy_from_user(&RtsThresh, wrq->u.data.pointer, wrq->u.data.length);
+                if (RtsThresh > MAX_RTS_THRESHOLD)
+                    Status  = -EINVAL;
+                else
+                    pAdapter->CommonCfg.RtsThreshold = (USHORT)RtsThresh;
+            }
+            DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_RTS_THRESHOLD (=%ld)\n",RtsThresh));
+            break;
+        case OID_802_11_FRAGMENTATION_THRESHOLD:
+            if (wrq->u.data.length != sizeof(NDIS_802_11_FRAGMENTATION_THRESHOLD))
+                Status  = -EINVAL;
+            else
+            {
+                Status = copy_from_user(&FragThresh, wrq->u.data.pointer, wrq->u.data.length);
+                pAdapter->CommonCfg.bUseZeroToDisableFragment = FALSE;
+                if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
+                {
+                    if (FragThresh == 0)
+                    {
+                        pAdapter->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
+                        pAdapter->CommonCfg.bUseZeroToDisableFragment = TRUE;
+                    }
+                    else
+                        Status  = -EINVAL;
+                }
+                else
+                    pAdapter->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
+            }
+            DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_FRAGMENTATION_THRESHOLD (=%ld) \n",FragThresh));
+            break;
+        case OID_802_11_POWER_MODE:
+            if (wrq->u.data.length != sizeof(NDIS_802_11_POWER_MODE))
+                Status = -EINVAL;
+            else
+            {
+                Status = copy_from_user(&PowerMode, wrq->u.data.pointer, wrq->u.data.length);
+                if (PowerMode == Ndis802_11PowerModeCAM)
+                	Set_PSMode_Proc(pAdapter, "CAM");
+                else if (PowerMode == Ndis802_11PowerModeMAX_PSP)
+                	Set_PSMode_Proc(pAdapter, "Max_PSP");
+                else if (PowerMode == Ndis802_11PowerModeFast_PSP)
+					Set_PSMode_Proc(pAdapter, "Fast_PSP");
+                else if (PowerMode == Ndis802_11PowerModeLegacy_PSP)
+					Set_PSMode_Proc(pAdapter, "Legacy_PSP");
+                else
+                    Status = -EINVAL;
+            }
+            DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_POWER_MODE (=%d)\n",PowerMode));
+            break;
+         case RT_OID_802_11_TX_POWER_LEVEL_1:
+			if (wrq->u.data.length  < sizeof(ULONG))
+				Status = -EINVAL;
+			else
+			{
+				Status = copy_from_user(&PowerTemp, wrq->u.data.pointer, wrq->u.data.length);
+				if (PowerTemp > 100)
+					PowerTemp = 0xffffffff;  // AUTO
+				pAdapter->CommonCfg.TxPowerDefault = PowerTemp; //keep current setting.
+					pAdapter->CommonCfg.TxPowerPercentage = pAdapter->CommonCfg.TxPowerDefault;
+                DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAdapter->CommonCfg.TxPowerPercentage));
+			}
+	        break;
+		case OID_802_11_NETWORK_TYPE_IN_USE:
+			if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_TYPE))
+				Status = -EINVAL;
+			else
+			{
+				Status = copy_from_user(&NetType, wrq->u.data.pointer, wrq->u.data.length);
+
+				if (NetType == Ndis802_11DS)
+					RTMPSetPhyMode(pAdapter, PHY_11B);
+				else if (NetType == Ndis802_11OFDM24)
+					RTMPSetPhyMode(pAdapter, PHY_11BG_MIXED);
+				else if (NetType == Ndis802_11OFDM5)
+					RTMPSetPhyMode(pAdapter, PHY_11A);
+				else
+					Status = -EINVAL;
+#ifdef DOT11_N_SUPPORT
+				if (Status == NDIS_STATUS_SUCCESS)
+					SetCommonHT(pAdapter);
+#endif // DOT11_N_SUPPORT //
+                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_NETWORK_TYPE_IN_USE (=%d)\n",NetType));
+		    }
+			break;
+        // For WPA PSK PMK key
+        case RT_OID_802_11_ADD_WPA:
+            pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
+            if(pKey == NULL)
+            {
+                Status = -ENOMEM;
+                break;
+            }
+
+            Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
+            if (pKey->Length != wrq->u.data.length)
+            {
+                Status  = -EINVAL;
+                DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!!\n"));
+            }
+            else
+            {
+                if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
+				    (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
+				    (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone) )
+                {
+                    Status = -EOPNOTSUPP;
+                    DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!! [AuthMode != WPAPSK/WPA2PSK/WPANONE]\n"));
+                }
+                else if ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+						 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
+						 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) )     // Only for WPA PSK mode
+				{
+                    NdisMoveMemory(pAdapter->StaCfg.PMK, &pKey->KeyMaterial, pKey->KeyLength);
+                    // Use RaConfig as PSK agent.
+                    // Start STA supplicant state machine
+                    if (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
+                        pAdapter->StaCfg.WpaState = SS_START;
+
+                    DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
+                }
+                else
+                {
+                    pAdapter->StaCfg.WpaState = SS_NOTUSE;
+                    DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
+                }
+            }
+            kfree(pKey);
+            break;
+        case OID_802_11_REMOVE_KEY:
+            pRemoveKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
+            if(pRemoveKey == NULL)
+            {
+                Status = -ENOMEM;
+                break;
+            }
+
+            Status = copy_from_user(pRemoveKey, wrq->u.data.pointer, wrq->u.data.length);
+            if (pRemoveKey->Length != wrq->u.data.length)
+            {
+                Status  = -EINVAL;
+                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!\n"));
+            }
+            else
+            {
+                if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+                {
+                    RTMPWPARemoveKeyProc(pAdapter, pRemoveKey);
+                    DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Remove WPA Key!!\n"));
+                }
+                else
+                {
+                    KeyIdx = pRemoveKey->KeyIndex;
+
+                    if (KeyIdx & 0x80000000)
+                    {
+                        // Should never set default bit when remove key
+                        Status  = -EINVAL;
+                        DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(Should never set default bit when remove key)\n"));
+                    }
+                    else
+                    {
+                        KeyIdx = KeyIdx & 0x0fffffff;
+                        if (KeyIdx > 3)
+                        {
+                            Status  = -EINVAL;
+                            DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(KeyId[%d] out of range)\n", KeyIdx));
+                        }
+                        else
+                        {
+                            pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = 0;
+                            pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
+                            AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)KeyIdx);
+                            DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY (id=0x%x, Len=%d-byte)\n", pRemoveKey->KeyIndex, pRemoveKey->Length));
+                        }
+                    }
+                }
+            }
+            kfree(pRemoveKey);
+            break;
+        // New for WPA
+        case OID_802_11_ADD_KEY:
+            pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
+            if(pKey == NULL)
+            {
+                Status = -ENOMEM;
+                break;
+            }
+            Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
+            if (pKey->Length != wrq->u.data.length)
+            {
+                Status  = -EINVAL;
+                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY, Failed!!\n"));
+            }
+            else
+            {
+                RTMPAddKey(pAdapter, pKey);
+                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
+            }
+            kfree(pKey);
+            break;
+        case OID_802_11_CONFIGURATION:
+            if (wrq->u.data.length != sizeof(NDIS_802_11_CONFIGURATION))
+                Status  = -EINVAL;
+            else
+            {
+                Status = copy_from_user(&Config, wrq->u.data.pointer, wrq->u.data.length);
+                pConfig = &Config;
+
+                if ((pConfig->BeaconPeriod >= 20) && (pConfig->BeaconPeriod <=400))
+                     pAdapter->CommonCfg.BeaconPeriod = (USHORT) pConfig->BeaconPeriod;
+
+                pAdapter->StaActive.AtimWin = (USHORT) pConfig->ATIMWindow;
+                MAP_KHZ_TO_CHANNEL_ID(pConfig->DSConfig, pAdapter->CommonCfg.Channel);
+                //
+				// Save the channel on MlmeAux for CntlOidRTBssidProc used.
+				//
+				pAdapter->MlmeAux.Channel = pAdapter->CommonCfg.Channel;
+
+                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CONFIGURATION (BeacnPeriod=%ld,AtimW=%ld,Ch=%d)\n",
+                    pConfig->BeaconPeriod, pConfig->ATIMWindow, pAdapter->CommonCfg.Channel));
+                // Config has changed
+                pAdapter->bConfigChanged = TRUE;
+            }
+            break;
+#ifdef DOT11_N_SUPPORT
+		case RT_OID_802_11_SET_HT_PHYMODE:
+			if (wrq->u.data.length	!= sizeof(OID_SET_HT_PHYMODE))
+				Status = -EINVAL;
+			else
+			{
+			    POID_SET_HT_PHYMODE	pHTPhyMode = &HT_PhyMode;
+
+				Status = copy_from_user(&HT_PhyMode, wrq->u.data.pointer, wrq->u.data.length);
+				DBGPRINT(RT_DEBUG_TRACE, ("Set::pHTPhyMode	(PhyMode = %d,TransmitNo = %d, HtMode =	%d,	ExtOffset =	%d , MCS = %d, BW =	%d,	STBC = %d, SHORTGI = %d) \n",
+				pHTPhyMode->PhyMode, pHTPhyMode->TransmitNo,pHTPhyMode->HtMode,pHTPhyMode->ExtOffset,
+				pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC,	pHTPhyMode->SHORTGI));
+				if (pAdapter->CommonCfg.PhyMode	>= PHY_11ABGN_MIXED)
+					RTMPSetHT(pAdapter,	pHTPhyMode);
+			}
+			DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_HT_PHYMODE(MCS=%d,BW=%d,SGI=%d,STBC=%d)\n",
+				pAdapter->StaCfg.HTPhyMode.field.MCS, pAdapter->StaCfg.HTPhyMode.field.BW, pAdapter->StaCfg.HTPhyMode.field.ShortGI,
+				pAdapter->StaCfg.HTPhyMode.field.STBC));
+			break;
+#endif // DOT11_N_SUPPORT //
+		case RT_OID_802_11_SET_APSD_SETTING:
+			if (wrq->u.data.length != sizeof(ULONG))
+				Status = -EINVAL;
+			else
+			{
+				ULONG apsd ;
+				Status = copy_from_user(&apsd, wrq->u.data.pointer,	wrq->u.data.length);
+
+				/*-------------------------------------------------------------------
+				|B31~B7	|	B6~B5	 |	 B4	 |	 B3	 |	B2	 |	B1	 |	   B0		|
+				---------------------------------------------------------------------
+				| Rsvd	| Max SP Len | AC_VO | AC_VI | AC_BK | AC_BE | APSD	Capable	|
+				---------------------------------------------------------------------*/
+				pAdapter->CommonCfg.bAPSDCapable = (apsd & 0x00000001) ? TRUE :	FALSE;
+				pAdapter->CommonCfg.bAPSDAC_BE = ((apsd	& 0x00000002) >> 1)	? TRUE : FALSE;
+				pAdapter->CommonCfg.bAPSDAC_BK = ((apsd	& 0x00000004) >> 2)	? TRUE : FALSE;
+				pAdapter->CommonCfg.bAPSDAC_VI = ((apsd	& 0x00000008) >> 3)	? TRUE : FALSE;
+				pAdapter->CommonCfg.bAPSDAC_VO = ((apsd	& 0x00000010) >> 4)	? TRUE : FALSE;
+				pAdapter->CommonCfg.MaxSPLength	= (UCHAR)((apsd	& 0x00000060) >> 5);
+
+				DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_APSD_SETTING (apsd=0x%lx, APSDCap=%d, [BE,BK,VI,VO]=[%d/%d/%d/%d],	MaxSPLen=%d)\n", apsd, pAdapter->CommonCfg.bAPSDCapable,
+					pAdapter->CommonCfg.bAPSDAC_BE,	pAdapter->CommonCfg.bAPSDAC_BK,	pAdapter->CommonCfg.bAPSDAC_VI,	pAdapter->CommonCfg.bAPSDAC_VO,	pAdapter->CommonCfg.MaxSPLength));
+			}
+			break;
+
+		case RT_OID_802_11_SET_APSD_PSM:
+			if (wrq->u.data.length	!= sizeof(ULONG))
+				Status = -EINVAL;
+			else
+			{
+				// Driver needs	to notify AP when PSM changes
+				Status = copy_from_user(&pAdapter->CommonCfg.bAPSDForcePowerSave, wrq->u.data.pointer, wrq->u.data.length);
+				if (pAdapter->CommonCfg.bAPSDForcePowerSave	!= pAdapter->StaCfg.Psm)
+				{
+					MlmeSetPsmBit(pAdapter,	pAdapter->CommonCfg.bAPSDForcePowerSave);
+					RTMPSendNullFrame(pAdapter,	pAdapter->CommonCfg.TxRate,	TRUE);
+				}
+				DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_APSD_PSM (bAPSDForcePowerSave:%d)\n",	pAdapter->CommonCfg.bAPSDForcePowerSave));
+			}
+			break;
+#ifdef QOS_DLS_SUPPORT
+		case RT_OID_802_11_SET_DLS:
+			if (wrq->u.data.length != sizeof(ULONG))
+				Status = -EINVAL;
+			else
+			{
+				BOOLEAN	oldvalue = pAdapter->CommonCfg.bDLSCapable;
+				Status = copy_from_user(&pAdapter->CommonCfg.bDLSCapable, wrq->u.data.pointer, wrq->u.data.length);
+				if (oldvalue &&	!pAdapter->CommonCfg.bDLSCapable)
+				{
+					int	i;
+					// tear	down local dls table entry
+					for	(i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+					{
+						if (pAdapter->StaCfg.DLSEntry[i].Valid && (pAdapter->StaCfg.DLSEntry[i].Status == DLS_FINISH))
+						{
+							pAdapter->StaCfg.DLSEntry[i].Status	= DLS_NONE;
+							pAdapter->StaCfg.DLSEntry[i].Valid	= FALSE;
+							RTMPSendDLSTearDownFrame(pAdapter, pAdapter->StaCfg.DLSEntry[i].MacAddr);
+						}
+					}
+
+					// tear	down peer dls table	entry
+					for	(i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+					{
+						if (pAdapter->StaCfg.DLSEntry[i].Valid && (pAdapter->StaCfg.DLSEntry[i].Status == DLS_FINISH))
+						{
+							pAdapter->StaCfg.DLSEntry[i].Status	= DLS_NONE;
+							pAdapter->StaCfg.DLSEntry[i].Valid	= FALSE;
+							RTMPSendDLSTearDownFrame(pAdapter, pAdapter->StaCfg.DLSEntry[i].MacAddr);
+						}
+					}
+				}
+
+				DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS (=%d)\n", pAdapter->CommonCfg.bDLSCapable));
+			}
+			break;
+
+		case RT_OID_802_11_SET_DLS_PARAM:
+			if (wrq->u.data.length	!= sizeof(RT_802_11_DLS_UI))
+				Status = -EINVAL;
+			else
+			{
+				RT_802_11_DLS	Dls;
+
+				NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
+				RTMPMoveMemory(&Dls, wrq->u.data.pointer, sizeof(RT_802_11_DLS_UI));
+				MlmeEnqueue(pAdapter,
+							MLME_CNTL_STATE_MACHINE,
+							RT_OID_802_11_SET_DLS_PARAM,
+							sizeof(RT_802_11_DLS),
+							&Dls);
+				DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS_PARAM \n"));
+			}
+			break;
+#endif // QOS_DLS_SUPPORT //
+		case RT_OID_802_11_SET_WMM:
+			if (wrq->u.data.length	!= sizeof(BOOLEAN))
+				Status = -EINVAL;
+			else
+			{
+				Status = copy_from_user(&pAdapter->CommonCfg.bWmmCapable, wrq->u.data.pointer, wrq->u.data.length);
+				DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_WMM (=%d)	\n", pAdapter->CommonCfg.bWmmCapable));
+			}
+			break;
+
+		case OID_802_11_DISASSOCIATE:
+#ifdef RALINK_ATE
+			if (ATE_ON(pAdapter))
+			{
+				DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
+				break;
+			}
+#endif // RALINK_ATE //
+			//
+			// Set NdisRadioStateOff to	TRUE, instead of called	MlmeRadioOff.
+			// Later on, NDIS_802_11_BSSID_LIST_EX->NumberOfItems should be	0
+			// when	query OID_802_11_BSSID_LIST.
+			//
+			// TRUE:  NumberOfItems	will set to	0.
+			// FALSE: NumberOfItems	no change.
+			//
+			pAdapter->CommonCfg.NdisRadioStateOff =	TRUE;
+			// Set to immediately send the media disconnect	event
+			pAdapter->MlmeAux.CurrReqIsFromNdis	= TRUE;
+			DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DISASSOCIATE	\n"));
+
+			if (INFRA_ON(pAdapter))
+			{
+				if (pAdapter->Mlme.CntlMachine.CurrState !=	CNTL_IDLE)
+				{
+					RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
+					DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME	busy, reset	MLME state machine !!!\n"));
+				}
+
+				MlmeEnqueue(pAdapter,
+					MLME_CNTL_STATE_MACHINE,
+					OID_802_11_DISASSOCIATE,
+					0,
+					NULL);
+
+				StateMachineTouched	= TRUE;
+			}
+			break;
+
+#ifdef DOT11_N_SUPPORT
+		case RT_OID_802_11_SET_IMME_BA_CAP:
+				if (wrq->u.data.length != sizeof(OID_BACAP_STRUC))
+					Status = -EINVAL;
+				else
+				{
+					OID_BACAP_STRUC Orde ;
+					Status = copy_from_user(&Orde, wrq->u.data.pointer, wrq->u.data.length);
+					if (Orde.Policy > BA_NOTUSE)
+					{
+						Status = NDIS_STATUS_INVALID_DATA;
+					}
+					else if (Orde.Policy == BA_NOTUSE)
+					{
+						pAdapter->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
+						pAdapter->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
+						pAdapter->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
+						pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
+						pAdapter->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
+						pAdapter->CommonCfg.DesiredHtPhy.MimoPs= Orde.MMPSmode;
+						pAdapter->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
+						// UPdata to HT IE
+						pAdapter->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
+						pAdapter->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
+						pAdapter->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
+					}
+					else
+					{
+                        pAdapter->CommonCfg.BACapability.field.AutoBA = Orde.AutoBA;
+						pAdapter->CommonCfg.BACapability.field.Policy = IMMED_BA; // we only support immediate BA.
+						pAdapter->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
+						pAdapter->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
+						pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
+						pAdapter->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
+						pAdapter->CommonCfg.DesiredHtPhy.MimoPs = Orde.MMPSmode;
+						pAdapter->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
+
+						// UPdata to HT IE
+						pAdapter->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
+						pAdapter->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
+						pAdapter->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
+
+						if (pAdapter->CommonCfg.BACapability.field.RxBAWinLimit > MAX_RX_REORDERBUF)
+							pAdapter->CommonCfg.BACapability.field.RxBAWinLimit = MAX_RX_REORDERBUF;
+
+					}
+
+					pAdapter->CommonCfg.REGBACapability.word = pAdapter->CommonCfg.BACapability.word;
+					DBGPRINT(RT_DEBUG_TRACE, ("Set::(Orde.AutoBA = %d) (Policy=%d)(ReBAWinLimit=%d)(TxBAWinLimit=%d)(AutoMode=%d)\n",Orde.AutoBA, pAdapter->CommonCfg.BACapability.field.Policy,
+						pAdapter->CommonCfg.BACapability.field.RxBAWinLimit,pAdapter->CommonCfg.BACapability.field.TxBAWinLimit, pAdapter->CommonCfg.BACapability.field.AutoBA));
+					DBGPRINT(RT_DEBUG_TRACE, ("Set::(MimoPs = %d)(AmsduEnable = %d) (AmsduSize=%d)(MpduDensity=%d)\n",pAdapter->CommonCfg.DesiredHtPhy.MimoPs, pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable,
+						pAdapter->CommonCfg.DesiredHtPhy.AmsduSize, pAdapter->CommonCfg.DesiredHtPhy.MpduDensity));
+				}
+
+				break;
+		case RT_OID_802_11_ADD_IMME_BA:
+			DBGPRINT(RT_DEBUG_TRACE, (" Set :: RT_OID_802_11_ADD_IMME_BA \n"));
+			if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY))
+					Status = -EINVAL;
+			else
+			{
+				UCHAR		        index;
+				OID_ADD_BA_ENTRY    BA;
+				MAC_TABLE_ENTRY     *pEntry;
+
+				Status = copy_from_user(&BA, wrq->u.data.pointer, wrq->u.data.length);
+				if (BA.TID > 15)
+				{
+					Status = NDIS_STATUS_INVALID_DATA;
+					break;
+				}
+				else
+				{
+					//BATableInsertEntry
+					//As ad-hoc mode, BA pair is not limited to only BSSID. so add via OID.
+					index = BA.TID;
+					// in ad hoc mode, when adding BA pair, we should insert this entry into MACEntry too
+					pEntry = MacTableLookup(pAdapter, BA.MACAddr);
+					if (!pEntry)
+					{
+						DBGPRINT(RT_DEBUG_TRACE, ("RT_OID_802_11_ADD_IMME_BA. break on no connection.----:%x:%x\n", BA.MACAddr[4], BA.MACAddr[5]));
+						break;
+					}
+					if (BA.IsRecipient == FALSE)
+					{
+					    if (pEntry->bIAmBadAtheros == TRUE)
+							pAdapter->CommonCfg.BACapability.field.RxBAWinLimit = 0x10;
+
+						BAOriSessionSetUp(pAdapter, pEntry, index, 0, 100, TRUE);
+					}
+					else
+					{
+						//BATableInsertEntry(pAdapter, pEntry->Aid, BA.MACAddr, 0, 0xffff, BA.TID, BA.nMSDU, BA.IsRecipient);
+					}
+
+					DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_IMME_BA. Rec = %d. Mac = %x:%x:%x:%x:%x:%x . \n",
+						BA.IsRecipient, BA.MACAddr[0], BA.MACAddr[1], BA.MACAddr[2], BA.MACAddr[2]
+						, BA.MACAddr[4], BA.MACAddr[5]));
+				}
+			}
+			break;
+
+		case RT_OID_802_11_TEAR_IMME_BA:
+			DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA \n"));
+			if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY))
+					Status = -EINVAL;
+			else
+			{
+				POID_ADD_BA_ENTRY	pBA;
+				MAC_TABLE_ENTRY *pEntry;
+
+				pBA = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
+
+				if (pBA == NULL)
+				{
+					DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA kmalloc() can't allocate enough memory\n"));
+					Status = NDIS_STATUS_FAILURE;
+				}
+				else
+				{
+					Status = copy_from_user(pBA, wrq->u.data.pointer, wrq->u.data.length);
+					DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA(TID=%d, bAllTid=%d)\n", pBA->TID, pBA->bAllTid));
+
+					if (!pBA->bAllTid && (pBA->TID > NUM_OF_TID))
+					{
+						Status = NDIS_STATUS_INVALID_DATA;
+						break;
+					}
+
+					if (pBA->IsRecipient == FALSE)
+					{
+						pEntry = MacTableLookup(pAdapter, pBA->MACAddr);
+						DBGPRINT(RT_DEBUG_TRACE, (" pBA->IsRecipient == FALSE\n"));
+						if (pEntry)
+						{
+							DBGPRINT(RT_DEBUG_TRACE, (" pBA->pEntry\n"));
+							BAOriSessionTearDown(pAdapter, pEntry->Aid, pBA->TID, FALSE, TRUE);
+						}
+						else
+							DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
+					}
+					else
+					{
+						pEntry = MacTableLookup(pAdapter, pBA->MACAddr);
+						if (pEntry)
+						{
+							BARecSessionTearDown( pAdapter, (UCHAR)pEntry->Aid, pBA->TID, TRUE);
+						}
+						else
+							DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
+					}
+					kfree(pBA);
+				}
+            }
+            break;
+#endif // DOT11_N_SUPPORT //
+
+        // For WPA_SUPPLICANT to set static wep key
+    	case OID_802_11_ADD_WEP:
+    	    pWepKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
+
+    	    if(pWepKey == NULL)
+            {
+                Status = -ENOMEM;
+				DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed!!\n"));
+                break;
+            }
+            Status = copy_from_user(pWepKey, wrq->u.data.pointer, wrq->u.data.length);
+            if (Status)
+            {
+                Status  = -EINVAL;
+                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (length mismatch)!!\n"));
+            }
+            else
+            {
+		        KeyIdx = pWepKey->KeyIndex & 0x0fffffff;
+                // KeyIdx must be 0 ~ 3
+                if (KeyIdx > 4)
+    			{
+                    Status  = -EINVAL;
+                    DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (KeyIdx must be smaller than 4)!!\n"));
+                }
+                else
+                {
+                    UCHAR CipherAlg = 0;
+                    PUCHAR Key;
+
+                    // set key material and key length
+                    NdisZeroMemory(pAdapter->SharedKey[BSS0][KeyIdx].Key, 16);
+                    pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
+                    NdisMoveMemory(pAdapter->SharedKey[BSS0][KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
+
+                    switch(pWepKey->KeyLength)
+                    {
+                        case 5:
+                            CipherAlg = CIPHER_WEP64;
+                            break;
+                        case 13:
+                            CipherAlg = CIPHER_WEP128;
+                            break;
+                        default:
+                            DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, only support CIPHER_WEP64(len:5) & CIPHER_WEP128(len:13)!!\n"));
+                            Status = -EINVAL;
+                            break;
+                    }
+                    pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CipherAlg;
+
+                    // Default key for tx (shared key)
+                    if (pWepKey->KeyIndex & 0x80000000)
+                    {
+#ifdef WPA_SUPPLICANT_SUPPORT
+                        // set key material and key length
+                        NdisZeroMemory(pAdapter->StaCfg.DesireSharedKey[KeyIdx].Key, 16);
+                        pAdapter->StaCfg.DesireSharedKey[KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
+                        NdisMoveMemory(pAdapter->StaCfg.DesireSharedKey[KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
+                        pAdapter->StaCfg.DesireSharedKeyId = KeyIdx;
+                        pAdapter->StaCfg.DesireSharedKey[KeyIdx].CipherAlg = CipherAlg;
+#endif // WPA_SUPPLICANT_SUPPORT //
+                        pAdapter->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
+                    }
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+                    if (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)
+#endif // WPA_SUPPLICANT_SUPPORT
+                    {
+                        Key = pAdapter->SharedKey[BSS0][KeyIdx].Key;
+
+                        // Set key material and cipherAlg to Asic
+        				AsicAddSharedKeyEntry(pAdapter, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
+
+                        if (pWepKey->KeyIndex & 0x80000000)
+                        {
+                            PMAC_TABLE_ENTRY pEntry = &pAdapter->MacTab.Content[BSSID_WCID];
+                            // Assign group key info
+    						RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, NULL);
+    						// Assign pairwise key info
+    						RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, pEntry);
+                        }
+                    }
+					DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP (id=0x%x, Len=%d-byte), %s\n", pWepKey->KeyIndex, pWepKey->KeyLength, (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED) ? "Port Secured":"Port NOT Secured"));
+				}
+            }
+            kfree(pWepKey);
+            break;
+#ifdef WPA_SUPPLICANT_SUPPORT
+	    case OID_SET_COUNTERMEASURES:
+            if (wrq->u.data.length != sizeof(int))
+                Status  = -EINVAL;
+            else
+            {
+                int enabled = 0;
+                Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length);
+                if (enabled == 1)
+                    pAdapter->StaCfg.bBlockAssoc = TRUE;
+                else
+                    // WPA MIC error should block association attempt for 60 seconds
+                    pAdapter->StaCfg.bBlockAssoc = FALSE;
+                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_SET_COUNTERMEASURES bBlockAssoc=%s\n", pAdapter->StaCfg.bBlockAssoc ? "TRUE":"FALSE"));
+            }
+	        break;
+        case RT_OID_WPA_SUPPLICANT_SUPPORT:
+			if (wrq->u.data.length != sizeof(UCHAR))
+                Status  = -EINVAL;
+            else
+            {
+                Status = copy_from_user(&wpa_supplicant_enable, wrq->u.data.pointer, wrq->u.data.length);
+    			pAdapter->StaCfg.WpaSupplicantUP = wpa_supplicant_enable;
+    			DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAdapter->StaCfg.WpaSupplicantUP));
+			}
+            break;
+        case OID_802_11_DEAUTHENTICATION:
+            if (wrq->u.data.length != sizeof(MLME_DEAUTH_REQ_STRUCT))
+                Status  = -EINVAL;
+            else
+            {
+                MLME_DEAUTH_REQ_STRUCT      *pInfo;
+				MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
+
+                pInfo = (MLME_DEAUTH_REQ_STRUCT *) MsgElem->Msg;
+                Status = copy_from_user(pInfo, wrq->u.data.pointer, wrq->u.data.length);
+                MlmeDeauthReqAction(pAdapter, MsgElem);
+				kfree(MsgElem);
+
+                if (INFRA_ON(pAdapter))
+                {
+                    LinkDown(pAdapter, FALSE);
+                    pAdapter->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+                }
+                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DEAUTHENTICATION (Reason=%d)\n", pInfo->Reason));
+            }
+            break;
+        case OID_802_11_DROP_UNENCRYPTED:
+            if (wrq->u.data.length != sizeof(int))
+                Status  = -EINVAL;
+            else
+            {
+                int enabled = 0;
+                Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length);
+                if (enabled == 1)
+                    pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+                else
+                    pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+				NdisAcquireSpinLock(&pAdapter->MacTabLock);
+				pAdapter->MacTab.Content[BSSID_WCID].PortSecured = pAdapter->StaCfg.PortSecured;
+				NdisReleaseSpinLock(&pAdapter->MacTabLock);
+                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DROP_UNENCRYPTED (=%d)\n", enabled));
+            }
+            break;
+        case OID_802_11_SET_IEEE8021X:
+            if (wrq->u.data.length != sizeof(BOOLEAN))
+                Status  = -EINVAL;
+            else
+            {
+                Status = copy_from_user(&IEEE8021xState, wrq->u.data.pointer, wrq->u.data.length);
+		        pAdapter->StaCfg.IEEE8021X = IEEE8021xState;
+                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X (=%d)\n", IEEE8021xState));
+            }
+            break;
+        case OID_802_11_SET_IEEE8021X_REQUIRE_KEY:
+			if (wrq->u.data.length != sizeof(BOOLEAN))
+				 Status  = -EINVAL;
+            else
+            {
+                Status = copy_from_user(&IEEE8021x_required_keys, wrq->u.data.pointer, wrq->u.data.length);
+				pAdapter->StaCfg.IEEE8021x_required_keys = IEEE8021x_required_keys;
+				DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X_REQUIRE_KEY (%d)\n", IEEE8021x_required_keys));
+			}
+			break;
+        case OID_802_11_PMKID:
+	        pPmkId = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
+
+	        if(pPmkId == NULL) {
+                Status = -ENOMEM;
+                break;
+            }
+            Status = copy_from_user(pPmkId, wrq->u.data.pointer, wrq->u.data.length);
+
+	        // check the PMKID information
+	        if (pPmkId->BSSIDInfoCount == 0)
+                NdisZeroMemory(pAdapter->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
+	        else
+	        {
+		        PBSSID_INFO	pBssIdInfo;
+		        UINT		BssIdx;
+		        UINT		CachedIdx;
+
+		        for (BssIdx = 0; BssIdx < pPmkId->BSSIDInfoCount; BssIdx++)
+		        {
+			        // point to the indexed BSSID_INFO structure
+			        pBssIdInfo = (PBSSID_INFO) ((PUCHAR) pPmkId + 2 * sizeof(UINT) + BssIdx * sizeof(BSSID_INFO));
+			        // Find the entry in the saved data base.
+			        for (CachedIdx = 0; CachedIdx < pAdapter->StaCfg.SavedPMKNum; CachedIdx++)
+			        {
+				        // compare the BSSID
+				        if (NdisEqualMemory(pBssIdInfo->BSSID, pAdapter->StaCfg.SavedPMK[CachedIdx].BSSID, sizeof(NDIS_802_11_MAC_ADDRESS)))
+					        break;
+			        }
+
+			        // Found, replace it
+			        if (CachedIdx < PMKID_NO)
+			        {
+				        DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx));
+				        NdisMoveMemory(&pAdapter->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
+				        pAdapter->StaCfg.SavedPMKNum++;
+			        }
+			        // Not found, replace the last one
+			        else
+			        {
+				        // Randomly replace one
+				        CachedIdx = (pBssIdInfo->BSSID[5] % PMKID_NO);
+				        DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx));
+				        NdisMoveMemory(&pAdapter->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
+			        }
+		        }
+			}
+			if(pPmkId)
+				kfree(pPmkId);
+	        break;
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+
+
+#ifdef SNMP_SUPPORT
+		case OID_802_11_SHORTRETRYLIMIT:
+			if (wrq->u.data.length != sizeof(ULONG))
+				Status = -EINVAL;
+			else
+			{
+				Status = copy_from_user(&ShortRetryLimit, wrq->u.data.pointer, wrq->u.data.length);
+				RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
+				tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
+				RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
+				DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SHORTRETRYLIMIT (tx_rty_cfg.field.ShortRetryLimit=%d, ShortRetryLimit=%ld)\n", tx_rty_cfg.field.ShortRtyLimit, ShortRetryLimit));
+			}
+			break;
+
+		case OID_802_11_LONGRETRYLIMIT:
+			DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT \n"));
+			if (wrq->u.data.length != sizeof(ULONG))
+				Status = -EINVAL;
+			else
+			{
+				Status = copy_from_user(&LongRetryLimit, wrq->u.data.pointer, wrq->u.data.length);
+				RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
+				tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
+				RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
+				DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT (tx_rty_cfg.field.LongRetryLimit= %d,LongRetryLimit=%ld)\n", tx_rty_cfg.field.LongRtyLimit, LongRetryLimit));
+			}
+			break;
+
+		case OID_802_11_WEPDEFAULTKEYVALUE:
+			DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE\n"));
+			pKey = kmalloc(wrq->u.data.length, GFP_KERNEL);
+			Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
+			//pKey = &WepKey;
+
+			if ( pKey->Length != wrq->u.data.length)
+			{
+				Status = -EINVAL;
+				DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE, Failed!!\n"));
+			}
+			KeyIdx = pKey->KeyIndex & 0x0fffffff;
+			DBGPRINT(RT_DEBUG_TRACE,("pKey->KeyIndex =%d, pKey->KeyLength=%d\n", pKey->KeyIndex, pKey->KeyLength));
+
+			// it is a shared key
+			if (KeyIdx > 4)
+				Status = -EINVAL;
+			else
+			{
+				pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen = (UCHAR) pKey->KeyLength;
+				NdisMoveMemory(&pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key, &pKey->KeyMaterial, pKey->KeyLength);
+				if (pKey->KeyIndex & 0x80000000)
+				{
+					// Default key for tx (shared key)
+					pAdapter->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
+				}
+				//RestartAPIsRequired = TRUE;
+			}
+			break;
+
+
+		case OID_802_11_WEPDEFAULTKEYID:
+			DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYID \n"));
+
+			if (wrq->u.data.length != sizeof(UCHAR))
+				Status = -EINVAL;
+			else
+				Status = copy_from_user(&pAdapter->StaCfg.DefaultKeyId, wrq->u.data.pointer, wrq->u.data.length);
+
+			break;
+
+
+		case OID_802_11_CURRENTCHANNEL:
+			DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CURRENTCHANNEL \n"));
+			if (wrq->u.data.length != sizeof(UCHAR))
+				Status = -EINVAL;
+			else
+			{
+				Status = copy_from_user(&ctmp, wrq->u.data.pointer, wrq->u.data.length);
+				sprintf(&ctmp,"%d", ctmp);
+				Set_Channel_Proc(pAdapter, &ctmp);
+			}
+			break;
+#endif
+
+
+
+        default:
+            DBGPRINT(RT_DEBUG_TRACE, ("Set::unknown IOCTL's subcmd = 0x%08x\n", cmd));
+            Status = -EOPNOTSUPP;
+            break;
+    }
+
+
+    return Status;
+}
+
+INT RTMPQueryInformation(
+    IN  PRTMP_ADAPTER pAdapter,
+    IN  OUT struct ifreq    *rq,
+    IN  INT                 cmd)
+{
+    struct iwreq                        *wrq = (struct iwreq *) rq;
+    NDIS_802_11_BSSID_LIST_EX           *pBssidList = NULL;
+    PNDIS_WLAN_BSSID_EX                 pBss;
+    NDIS_802_11_SSID                    Ssid;
+    NDIS_802_11_CONFIGURATION           *pConfiguration = NULL;
+    RT_802_11_LINK_STATUS               *pLinkStatus = NULL;
+    RT_802_11_STA_CONFIG                *pStaConfig = NULL;
+    NDIS_802_11_STATISTICS              *pStatistics = NULL;
+    NDIS_802_11_RTS_THRESHOLD           RtsThresh;
+    NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
+    NDIS_802_11_POWER_MODE              PowerMode;
+    NDIS_802_11_NETWORK_INFRASTRUCTURE  BssType;
+    RT_802_11_PREAMBLE                  PreamType;
+    NDIS_802_11_AUTHENTICATION_MODE     AuthMode;
+    NDIS_802_11_WEP_STATUS              WepStatus;
+    NDIS_MEDIA_STATE                    MediaState;
+    ULONG                               BssBufSize, ulInfo=0, NetworkTypeList[4], apsd = 0;
+    USHORT                              BssLen = 0;
+    PUCHAR                              pBuf = NULL, pPtr;
+    INT                                 Status = NDIS_STATUS_SUCCESS;
+    UINT                                we_version_compiled;
+    UCHAR                               i, Padding = 0;
+    BOOLEAN                             RadioState;
+	UCHAR	driverVersion[8];
+    OID_SET_HT_PHYMODE			        *pHTPhyMode = NULL;
+
+
+#ifdef SNMP_SUPPORT
+	//for snmp, kathy
+	DefaultKeyIdxValue			*pKeyIdxValue;
+	INT							valueLen;
+	TX_RTY_CFG_STRUC			tx_rty_cfg;
+	ULONG						ShortRetryLimit, LongRetryLimit;
+	UCHAR						tmp[64];
+#endif //SNMP
+
+    switch(cmd)
+    {
+        case RT_OID_DEVICE_NAME:
+            wrq->u.data.length = sizeof(STA_NIC_DEVICE_NAME);
+            Status = copy_to_user(wrq->u.data.pointer, STA_NIC_DEVICE_NAME, wrq->u.data.length);
+            break;
+        case RT_OID_VERSION_INFO:
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_VERSION_INFO \n"));
+			wrq->u.data.length = 8*sizeof(UCHAR);
+			sprintf(&driverVersion[0], "%s", STA_DRIVER_VERSION);
+			driverVersion[7] = '\0';
+			if (copy_to_user(wrq->u.data.pointer, &driverVersion, wrq->u.data.length))
+            {
+				Status = -EFAULT;
+            }
+            break;
+#ifdef RALINK_ATE
+		case RT_QUERY_ATE_TXDONE_COUNT:
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_QUERY_ATE_TXDONE_COUNT \n"));
+			wrq->u.data.length = sizeof(UINT32);
+			if (copy_to_user(wrq->u.data.pointer, &pAdapter->ate.TxDoneCount, wrq->u.data.length))
+			{
+				Status = -EFAULT;
+			}
+			break;
+#endif // RALINK_ATE //
+        case OID_802_11_BSSID_LIST:
+            if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+            {
+            	/*
+            	 * Still scanning, indicate the caller should try again.
+            	 */
+            	DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (Still scanning)\n"));
+				return -EAGAIN;
+            }
+            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (%d BSS returned)\n",pAdapter->ScanTab.BssNr));
+			pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
+            // Claculate total buffer size required
+            BssBufSize = sizeof(ULONG);
+
+            for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
+            {
+                // Align pointer to 4 bytes boundary.
+                //Padding = 4 - (pAdapter->ScanTab.BssEntry[i].VarIELen & 0x0003);
+                //if (Padding == 4)
+                //    Padding = 0;
+                BssBufSize += (sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen + Padding);
+            }
+
+            // For safety issue, we add 256 bytes just in case
+            BssBufSize += 256;
+            // Allocate the same size as passed from higher layer
+            pBuf = kmalloc(BssBufSize, MEM_ALLOC_FLAG);
+            if(pBuf == NULL)
+            {
+                Status = -ENOMEM;
+                break;
+            }
+            // Init 802_11_BSSID_LIST_EX structure
+            NdisZeroMemory(pBuf, BssBufSize);
+            pBssidList = (PNDIS_802_11_BSSID_LIST_EX) pBuf;
+            pBssidList->NumberOfItems = pAdapter->ScanTab.BssNr;
+
+            // Calculate total buffer length
+            BssLen = 4; // Consist of NumberOfItems
+            // Point to start of NDIS_WLAN_BSSID_EX
+            // pPtr = pBuf + sizeof(ULONG);
+            pPtr = (PUCHAR) &pBssidList->Bssid[0];
+            for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
+            {
+                pBss = (PNDIS_WLAN_BSSID_EX) pPtr;
+                NdisMoveMemory(&pBss->MacAddress, &pAdapter->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
+                if ((pAdapter->ScanTab.BssEntry[i].Hidden == 1) && (pAdapter->StaCfg.bShowHiddenSSID == FALSE))
+                {
+                    //
+					// We must return this SSID during 4way handshaking, otherwise Aegis will failed to parse WPA infomation
+					// and then failed to send EAPOl farame.
+					//
+					if ((pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pAdapter->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED))
+					{
+						pBss->Ssid.SsidLength = pAdapter->ScanTab.BssEntry[i].SsidLen;
+						NdisMoveMemory(pBss->Ssid.Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
+					}
+					else
+                    	pBss->Ssid.SsidLength = 0;
+                }
+                else
+                {
+                    pBss->Ssid.SsidLength = pAdapter->ScanTab.BssEntry[i].SsidLen;
+                    NdisMoveMemory(pBss->Ssid.Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
+                }
+                pBss->Privacy = pAdapter->ScanTab.BssEntry[i].Privacy;
+                pBss->Rssi = pAdapter->ScanTab.BssEntry[i].Rssi - pAdapter->BbpRssiToDbmDelta;
+                pBss->NetworkTypeInUse = NetworkTypeInUseSanity(&pAdapter->ScanTab.BssEntry[i]);
+                pBss->Configuration.Length = sizeof(NDIS_802_11_CONFIGURATION);
+                pBss->Configuration.BeaconPeriod = pAdapter->ScanTab.BssEntry[i].BeaconPeriod;
+                pBss->Configuration.ATIMWindow = pAdapter->ScanTab.BssEntry[i].AtimWin;
+
+                MAP_CHANNEL_ID_TO_KHZ(pAdapter->ScanTab.BssEntry[i].Channel, pBss->Configuration.DSConfig);
+
+                if (pAdapter->ScanTab.BssEntry[i].BssType == BSS_INFRA)
+                    pBss->InfrastructureMode = Ndis802_11Infrastructure;
+                else
+                    pBss->InfrastructureMode = Ndis802_11IBSS;
+
+                NdisMoveMemory(pBss->SupportedRates, pAdapter->ScanTab.BssEntry[i].SupRate, pAdapter->ScanTab.BssEntry[i].SupRateLen);
+                NdisMoveMemory(pBss->SupportedRates + pAdapter->ScanTab.BssEntry[i].SupRateLen,
+                               pAdapter->ScanTab.BssEntry[i].ExtRate,
+                               pAdapter->ScanTab.BssEntry[i].ExtRateLen);
+
+                if (pAdapter->ScanTab.BssEntry[i].VarIELen == 0)
+                {
+                    pBss->IELength = sizeof(NDIS_802_11_FIXED_IEs);
+                    NdisMoveMemory(pBss->IEs, &pAdapter->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
+                    pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
+                }
+                else
+                {
+                    pBss->IELength = (ULONG)(sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen);
+                    pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
+                    NdisMoveMemory(pBss->IEs, &pAdapter->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
+                    NdisMoveMemory(pBss->IEs + sizeof(NDIS_802_11_FIXED_IEs), pAdapter->ScanTab.BssEntry[i].VarIEs, pAdapter->ScanTab.BssEntry[i].VarIELen);
+                    pPtr += pAdapter->ScanTab.BssEntry[i].VarIELen;
+                }
+                pBss->Length = (ULONG)(sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen + Padding);
+
+#if WIRELESS_EXT < 17
+                if ((BssLen + pBss->Length) < wrq->u.data.length)
+                BssLen += pBss->Length;
+                else
+                {
+                    pBssidList->NumberOfItems = i;
+                    break;
+                }
+#else
+                BssLen += pBss->Length;
+#endif
+            }
+
+#if WIRELESS_EXT < 17
+            wrq->u.data.length = BssLen;
+#else
+            if (BssLen > wrq->u.data.length)
+            {
+                kfree(pBssidList);
+                return -E2BIG;
+            }
+            else
+                wrq->u.data.length = BssLen;
+#endif
+            Status = copy_to_user(wrq->u.data.pointer, pBssidList, BssLen);
+            kfree(pBssidList);
+            break;
+        case OID_802_3_CURRENT_ADDRESS:
+            wrq->u.data.length = MAC_ADDR_LEN;
+            Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
+            break;
+        case OID_GEN_MEDIA_CONNECT_STATUS:
+            if (pAdapter->IndicateMediaState == NdisMediaStateConnected)
+                MediaState = NdisMediaStateConnected;
+            else
+                MediaState = NdisMediaStateDisconnected;
+
+            wrq->u.data.length = sizeof(NDIS_MEDIA_STATE);
+            Status = copy_to_user(wrq->u.data.pointer, &MediaState, wrq->u.data.length);
+            break;
+        case OID_802_11_BSSID:
+#ifdef RALINK_ATE
+			if (ATE_ON(pAdapter))
+			{
+				DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
+				Status = NDIS_STATUS_RESOURCES;
+				break;
+			}
+#endif // RALINK_ATE //
+            if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
+            {
+                Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Bssid, sizeof(NDIS_802_11_MAC_ADDRESS));
+
+            }
+            else
+            {
+                DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID(=EMPTY)\n"));
+                Status = -ENOTCONN;
+            }
+            break;
+        case OID_802_11_SSID:
+			NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
+			NdisZeroMemory(Ssid.Ssid, MAX_LEN_OF_SSID);
+            Ssid.SsidLength = pAdapter->CommonCfg.SsidLen;
+			memcpy(Ssid.Ssid, pAdapter->CommonCfg.Ssid,	Ssid.SsidLength);
+            wrq->u.data.length = sizeof(NDIS_802_11_SSID);
+            Status = copy_to_user(wrq->u.data.pointer, &Ssid, wrq->u.data.length);
+            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SSID (Len=%d, ssid=%s)\n", Ssid.SsidLength,Ssid.Ssid));
+            break;
+        case RT_OID_802_11_QUERY_LINK_STATUS:
+            pLinkStatus = (RT_802_11_LINK_STATUS *) kmalloc(sizeof(RT_802_11_LINK_STATUS), MEM_ALLOC_FLAG);
+            if (pLinkStatus)
+            {
+                pLinkStatus->CurrTxRate = RateIdTo500Kbps[pAdapter->CommonCfg.TxRate];   // unit : 500 kbps
+                pLinkStatus->ChannelQuality = pAdapter->Mlme.ChannelQuality;
+                pLinkStatus->RxByteCount = pAdapter->RalinkCounters.ReceivedByteCount;
+                pLinkStatus->TxByteCount = pAdapter->RalinkCounters.TransmittedByteCount;
+        		pLinkStatus->CentralChannel = pAdapter->CommonCfg.CentralChannel;
+                wrq->u.data.length = sizeof(RT_802_11_LINK_STATUS);
+                Status = copy_to_user(wrq->u.data.pointer, pLinkStatus, wrq->u.data.length);
+                kfree(pLinkStatus);
+                DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS\n"));
+            }
+            else
+            {
+                DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS(kmalloc failed)\n"));
+                Status = -EFAULT;
+            }
+            break;
+        case OID_802_11_CONFIGURATION:
+            pConfiguration = (NDIS_802_11_CONFIGURATION *) kmalloc(sizeof(NDIS_802_11_CONFIGURATION), MEM_ALLOC_FLAG);
+            if (pConfiguration)
+            {
+                pConfiguration->Length = sizeof(NDIS_802_11_CONFIGURATION);
+                pConfiguration->BeaconPeriod = pAdapter->CommonCfg.BeaconPeriod;
+                pConfiguration->ATIMWindow = pAdapter->StaActive.AtimWin;
+                MAP_CHANNEL_ID_TO_KHZ(pAdapter->CommonCfg.Channel, pConfiguration->DSConfig);
+                wrq->u.data.length = sizeof(NDIS_802_11_CONFIGURATION);
+                Status = copy_to_user(wrq->u.data.pointer, pConfiguration, wrq->u.data.length);
+                DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(BeaconPeriod=%ld,AtimW=%ld,Channel=%d) \n",
+                                        pConfiguration->BeaconPeriod, pConfiguration->ATIMWindow, pAdapter->CommonCfg.Channel));
+				kfree(pConfiguration);
+            }
+            else
+            {
+                DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(kmalloc failed)\n"));
+                Status = -EFAULT;
+            }
+            break;
+		case RT_OID_802_11_SNR_0:
+			if ((pAdapter->StaCfg.LastSNR0 > 0))
+			{
+				ulInfo = ((0xeb	- pAdapter->StaCfg.LastSNR0) * 3) /	16 ;
+				wrq->u.data.length = sizeof(ulInfo);
+				Status = copy_to_user(wrq->u.data.pointer, &ulInfo,	wrq->u.data.length);
+				DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_SNR_0(0x=%lx)\n", ulInfo));
+			}
+            else
+			    Status = -EFAULT;
+			break;
+		case RT_OID_802_11_SNR_1:
+			if ((pAdapter->Antenna.field.RxPath	> 1) &&
+                (pAdapter->StaCfg.LastSNR1 > 0))
+			{
+				ulInfo = ((0xeb	- pAdapter->StaCfg.LastSNR1) * 3) /	16 ;
+				wrq->u.data.length = sizeof(ulInfo);
+				Status = copy_to_user(wrq->u.data.pointer, &ulInfo,	wrq->u.data.length);
+				DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(0x=%lx)\n",ulInfo));
+			}
+			else
+				Status = -EFAULT;
+            DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(pAdapter->StaCfg.LastSNR1=%d)\n",pAdapter->StaCfg.LastSNR1));
+			break;
+        case OID_802_11_RSSI_TRIGGER:
+            ulInfo = pAdapter->StaCfg.RssiSample.LastRssi0 - pAdapter->BbpRssiToDbmDelta;
+            wrq->u.data.length = sizeof(ulInfo);
+            Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RSSI_TRIGGER(=%ld)\n", ulInfo));
+            break;
+		case OID_802_11_RSSI:
+        case RT_OID_802_11_RSSI:
+			ulInfo = pAdapter->StaCfg.RssiSample.LastRssi0;
+			wrq->u.data.length = sizeof(ulInfo);
+			Status = copy_to_user(wrq->u.data.pointer, &ulInfo,	wrq->u.data.length);
+			break;
+		case RT_OID_802_11_RSSI_1:
+            ulInfo = pAdapter->StaCfg.RssiSample.LastRssi1;
+			wrq->u.data.length = sizeof(ulInfo);
+			Status = copy_to_user(wrq->u.data.pointer, &ulInfo,	wrq->u.data.length);
+			break;
+        case RT_OID_802_11_RSSI_2:
+            ulInfo = pAdapter->StaCfg.RssiSample.LastRssi2;
+			wrq->u.data.length = sizeof(ulInfo);
+			Status = copy_to_user(wrq->u.data.pointer, &ulInfo,	wrq->u.data.length);
+			break;
+        case OID_802_11_STATISTICS:
+            pStatistics = (NDIS_802_11_STATISTICS *) kmalloc(sizeof(NDIS_802_11_STATISTICS), MEM_ALLOC_FLAG);
+            if (pStatistics)
+            {
+                DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS \n"));
+                // add the most up-to-date h/w raw counters into software counters
+			    NICUpdateRawCounters(pAdapter);
+
+                // Sanity check for calculation of sucessful count
+                if (pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart < pAdapter->WlanCounters.RetryCount.QuadPart)
+                    pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart = pAdapter->WlanCounters.RetryCount.QuadPart;
+
+                pStatistics->TransmittedFragmentCount.QuadPart = pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart;
+                pStatistics->MulticastTransmittedFrameCount.QuadPart = pAdapter->WlanCounters.MulticastTransmittedFrameCount.QuadPart;
+                pStatistics->FailedCount.QuadPart = pAdapter->WlanCounters.FailedCount.QuadPart;
+                pStatistics->RetryCount.QuadPart = pAdapter->WlanCounters.RetryCount.QuadPart;
+                pStatistics->MultipleRetryCount.QuadPart = pAdapter->WlanCounters.MultipleRetryCount.QuadPart;
+                pStatistics->RTSSuccessCount.QuadPart = pAdapter->WlanCounters.RTSSuccessCount.QuadPart;
+                pStatistics->RTSFailureCount.QuadPart = pAdapter->WlanCounters.RTSFailureCount.QuadPart;
+                pStatistics->ACKFailureCount.QuadPart = pAdapter->WlanCounters.ACKFailureCount.QuadPart;
+                pStatistics->FrameDuplicateCount.QuadPart = pAdapter->WlanCounters.FrameDuplicateCount.QuadPart;
+                pStatistics->ReceivedFragmentCount.QuadPart = pAdapter->WlanCounters.ReceivedFragmentCount.QuadPart;
+                pStatistics->MulticastReceivedFrameCount.QuadPart = pAdapter->WlanCounters.MulticastReceivedFrameCount.QuadPart;
+#ifdef DBG
+                pStatistics->FCSErrorCount = pAdapter->RalinkCounters.RealFcsErrCount;
+#else
+                pStatistics->FCSErrorCount.QuadPart = pAdapter->WlanCounters.FCSErrorCount.QuadPart;
+                pStatistics->FrameDuplicateCount.u.LowPart = pAdapter->WlanCounters.FrameDuplicateCount.u.LowPart / 100;
+#endif
+                wrq->u.data.length = sizeof(NDIS_802_11_STATISTICS);
+                Status = copy_to_user(wrq->u.data.pointer, pStatistics, wrq->u.data.length);
+                kfree(pStatistics);
+            }
+            else
+            {
+                DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS(kmalloc failed)\n"));
+                Status = -EFAULT;
+            }
+            break;
+        case OID_GEN_RCV_OK:
+            ulInfo = pAdapter->Counters8023.GoodReceives;
+            wrq->u.data.length = sizeof(ulInfo);
+            Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+            break;
+        case OID_GEN_RCV_NO_BUFFER:
+            ulInfo = pAdapter->Counters8023.RxNoBuffer;
+            wrq->u.data.length = sizeof(ulInfo);
+            Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+            break;
+        case RT_OID_802_11_PHY_MODE:
+            ulInfo = (ULONG)pAdapter->CommonCfg.PhyMode;
+            wrq->u.data.length = sizeof(ulInfo);
+            Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+            DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PHY_MODE (=%ld)\n", ulInfo));
+            break;
+        case RT_OID_802_11_STA_CONFIG:
+            pStaConfig = (RT_802_11_STA_CONFIG *) kmalloc(sizeof(RT_802_11_STA_CONFIG), MEM_ALLOC_FLAG);
+            if (pStaConfig)
+            {
+                DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG\n"));
+                pStaConfig->EnableTxBurst = pAdapter->CommonCfg.bEnableTxBurst;
+                pStaConfig->EnableTurboRate = 0;
+                pStaConfig->UseBGProtection = pAdapter->CommonCfg.UseBGProtection;
+                pStaConfig->UseShortSlotTime = pAdapter->CommonCfg.bUseShortSlotTime;
+                //pStaConfig->AdhocMode = pAdapter->StaCfg.AdhocMode;
+                pStaConfig->HwRadioStatus = (pAdapter->StaCfg.bHwRadio == TRUE) ? 1 : 0;
+                pStaConfig->Rsv1 = 0;
+                pStaConfig->SystemErrorBitmap = pAdapter->SystemErrorBitmap;
+                wrq->u.data.length = sizeof(RT_802_11_STA_CONFIG);
+                Status = copy_to_user(wrq->u.data.pointer, pStaConfig, wrq->u.data.length);
+                kfree(pStaConfig);
+            }
+            else
+            {
+                DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
+                Status = -EFAULT;
+            }
+            break;
+        case OID_802_11_RTS_THRESHOLD:
+            RtsThresh = pAdapter->CommonCfg.RtsThreshold;
+            wrq->u.data.length = sizeof(RtsThresh);
+            Status = copy_to_user(wrq->u.data.pointer, &RtsThresh, wrq->u.data.length);
+            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RTS_THRESHOLD(=%ld)\n", RtsThresh));
+            break;
+        case OID_802_11_FRAGMENTATION_THRESHOLD:
+            FragThresh = pAdapter->CommonCfg.FragmentThreshold;
+            if (pAdapter->CommonCfg.bUseZeroToDisableFragment == TRUE)
+                FragThresh = 0;
+            wrq->u.data.length = sizeof(FragThresh);
+            Status = copy_to_user(wrq->u.data.pointer, &FragThresh, wrq->u.data.length);
+            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_FRAGMENTATION_THRESHOLD(=%ld)\n", FragThresh));
+            break;
+        case OID_802_11_POWER_MODE:
+            PowerMode = pAdapter->StaCfg.WindowsPowerMode;
+            wrq->u.data.length = sizeof(PowerMode);
+            Status = copy_to_user(wrq->u.data.pointer, &PowerMode, wrq->u.data.length);
+            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_POWER_MODE(=%d)\n", PowerMode));
+            break;
+        case RT_OID_802_11_RADIO:
+            RadioState = (BOOLEAN) pAdapter->StaCfg.bSwRadio;
+            wrq->u.data.length = sizeof(RadioState);
+            Status = copy_to_user(wrq->u.data.pointer, &RadioState, wrq->u.data.length);
+            DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_RADIO (=%d)\n", RadioState));
+            break;
+        case OID_802_11_INFRASTRUCTURE_MODE:
+            if (pAdapter->StaCfg.BssType == BSS_ADHOC)
+                BssType = Ndis802_11IBSS;
+            else if (pAdapter->StaCfg.BssType == BSS_INFRA)
+                BssType = Ndis802_11Infrastructure;
+            else if (pAdapter->StaCfg.BssType == BSS_MONITOR)
+                BssType = Ndis802_11Monitor;
+            else
+                BssType = Ndis802_11AutoUnknown;
+
+            wrq->u.data.length = sizeof(BssType);
+            Status = copy_to_user(wrq->u.data.pointer, &BssType, wrq->u.data.length);
+            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_INFRASTRUCTURE_MODE(=%d)\n", BssType));
+            break;
+        case RT_OID_802_11_PREAMBLE:
+            PreamType = pAdapter->CommonCfg.TxPreamble;
+            wrq->u.data.length = sizeof(PreamType);
+            Status = copy_to_user(wrq->u.data.pointer, &PreamType, wrq->u.data.length);
+            DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PREAMBLE(=%d)\n", PreamType));
+            break;
+        case OID_802_11_AUTHENTICATION_MODE:
+            AuthMode = pAdapter->StaCfg.AuthMode;
+            wrq->u.data.length = sizeof(AuthMode);
+            Status = copy_to_user(wrq->u.data.pointer, &AuthMode, wrq->u.data.length);
+            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_AUTHENTICATION_MODE(=%d)\n", AuthMode));
+            break;
+        case OID_802_11_WEP_STATUS:
+            WepStatus = pAdapter->StaCfg.WepStatus;
+            wrq->u.data.length = sizeof(WepStatus);
+            Status = copy_to_user(wrq->u.data.pointer, &WepStatus, wrq->u.data.length);
+            DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEP_STATUS(=%d)\n", WepStatus));
+            break;
+        case OID_802_11_TX_POWER_LEVEL:
+			wrq->u.data.length = sizeof(ULONG);
+			Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.TxPower, wrq->u.data.length);
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_TX_POWER_LEVEL %x\n",pAdapter->CommonCfg.TxPower));
+			break;
+        case RT_OID_802_11_TX_POWER_LEVEL_1:
+            wrq->u.data.length = sizeof(ULONG);
+            Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.TxPowerPercentage, wrq->u.data.length);
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAdapter->CommonCfg.TxPowerPercentage));
+			break;
+        case OID_802_11_NETWORK_TYPES_SUPPORTED:
+			if ((pAdapter->RfIcType	== RFIC_2850) || (pAdapter->RfIcType ==	RFIC_2750))
+			{
+				NetworkTypeList[0] = 3;                 // NumberOfItems = 3
+				NetworkTypeList[1] = Ndis802_11DS;      // NetworkType[1] = 11b
+				NetworkTypeList[2] = Ndis802_11OFDM24;  // NetworkType[2] = 11g
+				NetworkTypeList[3] = Ndis802_11OFDM5;   // NetworkType[3] = 11a
+                wrq->u.data.length = 16;
+				Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length);
+			}
+			else
+			{
+				NetworkTypeList[0] = 2;                 // NumberOfItems = 2
+				NetworkTypeList[1] = Ndis802_11DS;      // NetworkType[1] = 11b
+				NetworkTypeList[2] = Ndis802_11OFDM24;  // NetworkType[2] = 11g
+			    wrq->u.data.length = 12;
+				Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length);
+			}
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_NETWORK_TYPES_SUPPORTED\n"));
+				break;
+	    case OID_802_11_NETWORK_TYPE_IN_USE:
+            wrq->u.data.length = sizeof(ULONG);
+			if (pAdapter->CommonCfg.PhyMode == PHY_11A)
+				ulInfo = Ndis802_11OFDM5;
+			else if ((pAdapter->CommonCfg.PhyMode == PHY_11BG_MIXED) || (pAdapter->CommonCfg.PhyMode == PHY_11G))
+				ulInfo = Ndis802_11OFDM24;
+			else
+				ulInfo = Ndis802_11DS;
+            Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+			break;
+        case RT_OID_802_11_QUERY_LAST_RX_RATE:
+            ulInfo = (ULONG)pAdapter->LastRxRate;
+            wrq->u.data.length = sizeof(ulInfo);
+			Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_RX_RATE (=%ld)\n", ulInfo));
+			break;
+		case RT_OID_802_11_QUERY_LAST_TX_RATE:
+			//ulInfo = (ULONG)pAdapter->LastTxRate;
+			ulInfo = (ULONG)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word;
+			wrq->u.data.length = sizeof(ulInfo);
+			Status = copy_to_user(wrq->u.data.pointer, &ulInfo,	wrq->u.data.length);
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_TX_RATE (=%lx)\n", ulInfo));
+			break;
+        case RT_OID_802_11_QUERY_EEPROM_VERSION:
+            wrq->u.data.length = sizeof(ULONG);
+            Status = copy_to_user(wrq->u.data.pointer, &pAdapter->EepromVersion, wrq->u.data.length);
+            break;
+        case RT_OID_802_11_QUERY_FIRMWARE_VERSION:
+            wrq->u.data.length = sizeof(ULONG);
+            Status = copy_to_user(wrq->u.data.pointer, &pAdapter->FirmwareVersion, wrq->u.data.length);
+			break;
+	    case RT_OID_802_11_QUERY_NOISE_LEVEL:
+			wrq->u.data.length = sizeof(UCHAR);
+			Status = copy_to_user(wrq->u.data.pointer, &pAdapter->BbpWriteLatch[66], wrq->u.data.length);
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_NOISE_LEVEL (=%d)\n", pAdapter->BbpWriteLatch[66]));
+			break;
+	    case RT_OID_802_11_EXTRA_INFO:
+			wrq->u.data.length = sizeof(ULONG);
+			Status = copy_to_user(wrq->u.data.pointer, &pAdapter->ExtraInfo, wrq->u.data.length);
+	        DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_EXTRA_INFO (=%ld)\n", pAdapter->ExtraInfo));
+	        break;
+	    case RT_OID_WE_VERSION_COMPILED:
+	        wrq->u.data.length = sizeof(UINT);
+	        we_version_compiled = WIRELESS_EXT;
+	        Status = copy_to_user(wrq->u.data.pointer, &we_version_compiled, wrq->u.data.length);
+	        break;
+		case RT_OID_802_11_QUERY_APSD_SETTING:
+			apsd = (pAdapter->CommonCfg.bAPSDCapable | (pAdapter->CommonCfg.bAPSDAC_BE << 1) | (pAdapter->CommonCfg.bAPSDAC_BK << 2)
+				| (pAdapter->CommonCfg.bAPSDAC_VI << 3)	| (pAdapter->CommonCfg.bAPSDAC_VO << 4)	| (pAdapter->CommonCfg.MaxSPLength << 5));
+
+			wrq->u.data.length = sizeof(ULONG);
+			Status = copy_to_user(wrq->u.data.pointer, &apsd, wrq->u.data.length);
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_APSD_SETTING (=0x%lx,APSDCap=%d,AC_BE=%d,AC_BK=%d,AC_VI=%d,AC_VO=%d,MAXSPLen=%d)\n",
+				apsd,pAdapter->CommonCfg.bAPSDCapable,pAdapter->CommonCfg.bAPSDAC_BE,pAdapter->CommonCfg.bAPSDAC_BK,pAdapter->CommonCfg.bAPSDAC_VI,pAdapter->CommonCfg.bAPSDAC_VO,pAdapter->CommonCfg.MaxSPLength));
+			break;
+		case RT_OID_802_11_QUERY_APSD_PSM:
+			wrq->u.data.length = sizeof(ULONG);
+			Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bAPSDForcePowerSave, wrq->u.data.length);
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_APSD_PSM (=%d)\n", pAdapter->CommonCfg.bAPSDForcePowerSave));
+			break;
+		case RT_OID_802_11_QUERY_WMM:
+			wrq->u.data.length = sizeof(BOOLEAN);
+			Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bWmmCapable, wrq->u.data.length);
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_WMM (=%d)\n",	pAdapter->CommonCfg.bWmmCapable));
+			break;
+#ifdef WPA_SUPPLICANT_SUPPORT
+        case RT_OID_NEW_DRIVER:
+            {
+                UCHAR enabled = 1;
+    	        wrq->u.data.length = sizeof(UCHAR);
+    	        Status = copy_to_user(wrq->u.data.pointer, &enabled, wrq->u.data.length);
+                DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_NEW_DRIVER (=%d)\n", enabled));
+            }
+	        break;
+        case RT_OID_WPA_SUPPLICANT_SUPPORT:
+	        wrq->u.data.length = sizeof(UCHAR);
+	        Status = copy_to_user(wrq->u.data.pointer, &pAdapter->StaCfg.WpaSupplicantUP, wrq->u.data.length);
+            DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAdapter->StaCfg.WpaSupplicantUP));
+	        break;
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+        case RT_OID_DRIVER_DEVICE_NAME:
+            DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_DRIVER_DEVICE_NAME \n"));
+			wrq->u.data.length = 16;
+			if (copy_to_user(wrq->u.data.pointer, pAdapter->StaCfg.dev_name, wrq->u.data.length))
+			{
+				Status = -EFAULT;
+			}
+            break;
+        case RT_OID_802_11_QUERY_HT_PHYMODE:
+            pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG);
+            if (pHTPhyMode)
+            {
+                pHTPhyMode->PhyMode = pAdapter->CommonCfg.PhyMode;
+    			pHTPhyMode->HtMode = (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE;
+    			pHTPhyMode->BW = (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.BW;
+    			pHTPhyMode->MCS= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS;
+    			pHTPhyMode->SHORTGI= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI;
+    			pHTPhyMode->STBC= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC;
+
+    			pHTPhyMode->ExtOffset = ((pAdapter->CommonCfg.CentralChannel < pAdapter->CommonCfg.Channel) ? (EXTCHA_BELOW) : (EXTCHA_ABOVE));
+                wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE);
+                if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length))
+    			{
+    				Status = -EFAULT;
+    			}
+    			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n",
+    				pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset));
+    			DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word));
+            }
+            else
+            {
+                DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
+                Status = -EFAULT;
+            }
+            break;
+        case RT_OID_802_11_COUNTRY_REGION:
+            DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_COUNTRY_REGION \n"));
+			wrq->u.data.length = sizeof(ulInfo);
+            ulInfo = pAdapter->CommonCfg.CountryRegionForABand;
+            ulInfo = (ulInfo << 8)|(pAdapter->CommonCfg.CountryRegion);
+			if (copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length))
+            {
+				Status = -EFAULT;
+            }
+            break;
+        case RT_OID_802_11_QUERY_DAT_HT_PHYMODE:
+            pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG);
+            if (pHTPhyMode)
+            {
+                pHTPhyMode->PhyMode = pAdapter->CommonCfg.PhyMode;
+    			pHTPhyMode->HtMode = (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.HTMODE;
+    			pHTPhyMode->BW = (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.BW;
+    			pHTPhyMode->MCS= (UCHAR)pAdapter->StaCfg.DesiredTransmitSetting.field.MCS;
+    			pHTPhyMode->SHORTGI= (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.ShortGI;
+    			pHTPhyMode->STBC= (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.STBC;
+
+                wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE);
+                if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length))
+    			{
+    				Status = -EFAULT;
+    			}
+    			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n",
+    				pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset));
+    			DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word));
+            }
+            else
+            {
+                DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
+                Status = -EFAULT;
+            }
+            break;
+        case RT_OID_QUERY_MULTIPLE_CARD_SUPPORT:
+			wrq->u.data.length = sizeof(UCHAR);
+            i = 0;
+#ifdef MULTIPLE_CARD_SUPPORT
+            i = 1;
+#endif // MULTIPLE_CARD_SUPPORT //
+			if (copy_to_user(wrq->u.data.pointer, &i, wrq->u.data.length))
+            {
+				Status = -EFAULT;
+            }
+            DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_QUERY_MULTIPLE_CARD_SUPPORT(=%d) \n", i));
+            break;
+#ifdef SNMP_SUPPORT
+		case RT_OID_802_11_MAC_ADDRESS:
+            wrq->u.data.length = MAC_ADDR_LEN;
+            Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
+			break;
+
+		case RT_OID_802_11_MANUFACTUREROUI:
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTUREROUI \n"));
+			wrq->u.data.length = ManufacturerOUI_LEN;
+			Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
+			break;
+
+		case RT_OID_802_11_MANUFACTURERNAME:
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTURERNAME \n"));
+			wrq->u.data.length = strlen(ManufacturerNAME);
+			Status = copy_to_user(wrq->u.data.pointer, ManufacturerNAME, wrq->u.data.length);
+			break;
+
+		case RT_OID_802_11_RESOURCETYPEIDNAME:
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_RESOURCETYPEIDNAME \n"));
+			wrq->u.data.length = strlen(ResourceTypeIdName);
+			Status = copy_to_user(wrq->u.data.pointer, ResourceTypeIdName, wrq->u.data.length);
+			break;
+
+		case RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED:
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED \n"));
+			ulInfo = 1; // 1 is support wep else 2 is not support.
+			wrq->u.data.length = sizeof(ulInfo);
+			Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+			break;
+
+		case RT_OID_802_11_POWERMANAGEMENTMODE:
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_POWERMANAGEMENTMODE \n"));
+			if (pAdapter->StaCfg.Psm == PSMP_ACTION)
+				ulInfo = 1; // 1 is power active else 2 is power save.
+			else
+				ulInfo = 2;
+
+			wrq->u.data.length = sizeof(ulInfo);
+			Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+			break;
+
+		case OID_802_11_WEPDEFAULTKEYVALUE:
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEPDEFAULTKEYVALUE \n"));
+			//KeyIdxValue.KeyIdx = pAd->PortCfg.MBSSID[pAd->IoctlIF].DefaultKeyId;
+			pKeyIdxValue = wrq->u.data.pointer;
+			DBGPRINT(RT_DEBUG_TRACE,("KeyIdxValue.KeyIdx = %d, \n",pKeyIdxValue->KeyIdx));
+			valueLen = pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen;
+			NdisMoveMemory(pKeyIdxValue->Value,
+						   &pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key,
+						   valueLen);
+			pKeyIdxValue->Value[valueLen]='\0';
+
+			wrq->u.data.length = sizeof(DefaultKeyIdxValue);
+
+			Status = copy_to_user(wrq->u.data.pointer, pKeyIdxValue, wrq->u.data.length);
+			DBGPRINT(RT_DEBUG_TRACE,("DefaultKeyId = %d, total len = %d, str len=%d, KeyValue= %02x %02x %02x %02x \n", pAdapter->StaCfg.DefaultKeyId, wrq->u.data.length, pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen,
+			pAdapter->SharedKey[BSS0][0].Key[0],
+			pAdapter->SharedKey[BSS0][1].Key[0],
+			pAdapter->SharedKey[BSS0][2].Key[0],
+			pAdapter->SharedKey[BSS0][3].Key[0]));
+			break;
+
+		case OID_802_11_WEPDEFAULTKEYID:
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WEPDEFAULTKEYID \n"));
+			wrq->u.data.length = sizeof(UCHAR);
+			Status = copy_to_user(wrq->u.data.pointer, &pAdapter->StaCfg.DefaultKeyId, wrq->u.data.length);
+			DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyId =%d \n", pAdapter->StaCfg.DefaultKeyId));
+			break;
+
+		case RT_OID_802_11_WEPKEYMAPPINGLENGTH:
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WEPKEYMAPPINGLENGTH \n"));
+			wrq->u.data.length = sizeof(UCHAR);
+			Status = copy_to_user(wrq->u.data.pointer,
+									&pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen,
+									wrq->u.data.length);
+			break;
+
+		case OID_802_11_SHORTRETRYLIMIT:
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SHORTRETRYLIMIT \n"));
+			wrq->u.data.length = sizeof(ULONG);
+			RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
+			ShortRetryLimit = tx_rty_cfg.field.ShortRtyLimit;
+			DBGPRINT(RT_DEBUG_TRACE, ("ShortRetryLimit =%ld,  tx_rty_cfg.field.ShortRetryLimit=%d\n", ShortRetryLimit, tx_rty_cfg.field.ShortRtyLimit));
+			Status = copy_to_user(wrq->u.data.pointer, &ShortRetryLimit, wrq->u.data.length);
+			break;
+
+		case OID_802_11_LONGRETRYLIMIT:
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_LONGRETRYLIMIT \n"));
+			wrq->u.data.length = sizeof(ULONG);
+			RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
+			LongRetryLimit = tx_rty_cfg.field.LongRtyLimit;
+			DBGPRINT(RT_DEBUG_TRACE, ("LongRetryLimit =%ld,  tx_rty_cfg.field.LongRtyLimit=%d\n", LongRetryLimit, tx_rty_cfg.field.LongRtyLimit));
+			Status = copy_to_user(wrq->u.data.pointer, &LongRetryLimit, wrq->u.data.length);
+			break;
+
+		case RT_OID_802_11_PRODUCTID:
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRODUCTID \n"));
+
+#ifdef RT2870
+			sprintf(tmp, "%04x %04x\n", ((POS_COOKIE)pAdapter->OS_Cookie)->pUsb_Dev->descriptor.idVendor ,((POS_COOKIE)pAdapter->OS_Cookie)->pUsb_Dev->descriptor.idProduct);
+
+#endif // RT2870 //
+			wrq->u.data.length = strlen(tmp);
+			Status = copy_to_user(wrq->u.data.pointer, tmp, wrq->u.data.length);
+			break;
+
+		case RT_OID_802_11_MANUFACTUREID:
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTUREID \n"));
+			wrq->u.data.length = strlen(ManufacturerNAME);
+			Status = copy_to_user(wrq->u.data.pointer, ManufacturerNAME, wrq->u.data.length);
+			break;
+
+		case OID_802_11_CURRENTCHANNEL:
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CURRENTCHANNEL \n"));
+			wrq->u.data.length = sizeof(UCHAR);
+			DBGPRINT(RT_DEBUG_TRACE, ("sizeof UCHAR=%d, channel=%d \n", sizeof(UCHAR), pAdapter->CommonCfg.Channel));
+			Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Channel, wrq->u.data.length);
+			DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
+			break;
+#endif //SNMP_SUPPORT
+
+		case OID_802_11_BUILD_CHANNEL_EX:
+			{
+				UCHAR value;
+				DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BUILD_CHANNEL_EX \n"));
+				wrq->u.data.length = sizeof(UCHAR);
+#ifdef EXT_BUILD_CHANNEL_LIST
+				DBGPRINT(RT_DEBUG_TRACE, ("Support EXT_BUILD_CHANNEL_LIST.\n"));
+				value = 1;
+#else
+				DBGPRINT(RT_DEBUG_TRACE, ("Doesn't support EXT_BUILD_CHANNEL_LIST.\n"));
+				value = 0;
+#endif // EXT_BUILD_CHANNEL_LIST //
+				Status = copy_to_user(wrq->u.data.pointer, &value, 1);
+				DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
+			}
+			break;
+
+		case OID_802_11_GET_CH_LIST:
+			{
+				PRT_CHANNEL_LIST_INFO pChListBuf;
+
+				DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CH_LIST \n"));
+				if (pAdapter->ChannelListNum == 0)
+				{
+					wrq->u.data.length = 0;
+					break;
+				}
+
+				pChListBuf = (RT_CHANNEL_LIST_INFO *) kmalloc(sizeof(RT_CHANNEL_LIST_INFO), MEM_ALLOC_FLAG);
+				if (pChListBuf == NULL)
+				{
+					wrq->u.data.length = 0;
+					break;
+				}
+
+				pChListBuf->ChannelListNum = pAdapter->ChannelListNum;
+				for (i = 0; i < pChListBuf->ChannelListNum; i++)
+					pChListBuf->ChannelList[i] = pAdapter->ChannelList[i].Channel;
+
+				wrq->u.data.length = sizeof(RT_CHANNEL_LIST_INFO);
+				Status = copy_to_user(wrq->u.data.pointer, pChListBuf, sizeof(RT_CHANNEL_LIST_INFO));
+				DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
+
+				if (pChListBuf)
+					kfree(pChListBuf);
+			}
+			break;
+
+		case OID_802_11_GET_COUNTRY_CODE:
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_COUNTRY_CODE \n"));
+			wrq->u.data.length = 2;
+			Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.CountryCode, 2);
+			DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
+			break;
+
+		case OID_802_11_GET_CHANNEL_GEOGRAPHY:
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CHANNEL_GEOGRAPHY \n"));
+			wrq->u.data.length = 1;
+			Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Geography, 1);
+			DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
+			break;
+
+
+#ifdef QOS_DLS_SUPPORT
+		case RT_OID_802_11_QUERY_DLS:
+			wrq->u.data.length = sizeof(BOOLEAN);
+			Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bDLSCapable, wrq->u.data.length);
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS(=%d)\n", pAdapter->CommonCfg.bDLSCapable));
+			break;
+
+		case RT_OID_802_11_QUERY_DLS_PARAM:
+			{
+				PRT_802_11_DLS_INFO	pDlsInfo = kmalloc(sizeof(RT_802_11_DLS_INFO), GFP_ATOMIC);
+				if (pDlsInfo == NULL)
+					break;
+
+				for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
+				{
+					RTMPMoveMemory(&pDlsInfo->Entry[i], &pAdapter->StaCfg.DLSEntry[i], sizeof(RT_802_11_DLS_UI));
+				}
+
+				pDlsInfo->num = MAX_NUM_OF_DLS_ENTRY;
+				wrq->u.data.length = sizeof(RT_802_11_DLS_INFO);
+				Status = copy_to_user(wrq->u.data.pointer, pDlsInfo, wrq->u.data.length);
+				DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS_PARAM\n"));
+
+				if (pDlsInfo)
+					kfree(pDlsInfo);
+			}
+			break;
+#endif // QOS_DLS_SUPPORT //
+        default:
+            DBGPRINT(RT_DEBUG_TRACE, ("Query::unknown IOCTL's subcmd = 0x%08x\n", cmd));
+            Status = -EOPNOTSUPP;
+            break;
+    }
+    return Status;
+}
+
+INT rt28xx_sta_ioctl(
+	IN	struct net_device	*net_dev,
+	IN	OUT	struct ifreq	*rq,
+	IN	INT					cmd)
+{
+	POS_COOKIE			pObj;
+	VIRTUAL_ADAPTER		*pVirtualAd = NULL;
+	RTMP_ADAPTER        *pAd = NULL;
+	struct iwreq        *wrq = (struct iwreq *) rq;
+	BOOLEAN				StateMachineTouched = FALSE;
+	INT					Status = NDIS_STATUS_SUCCESS;
+	USHORT				subcmd;
+
+	if (net_dev->priv_flags == INT_MAIN)
+	{
+		pAd = net_dev->ml_priv;
+	}
+	else
+	{
+		pVirtualAd = net_dev->ml_priv;
+		pAd = pVirtualAd->RtmpDev->ml_priv;
+	}
+	pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+	if (pAd == NULL)
+	{
+		/* if 1st open fail, pAd will be free;
+		   So the net_dev->ml_priv will be NULL in 2rd open */
+		return -ENETDOWN;
+	}
+
+    //check if the interface is down
+    if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+    {
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+	    if (wrq->u.data.pointer == NULL)
+	    {
+		    return Status;
+	    }
+
+	    if (strstr(wrq->u.data.pointer, "OpMode") == NULL)
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+        {
+            DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+		    return -ENETDOWN;
+        }
+    }
+
+	{	// determine this ioctl command is comming from which interface.
+		pObj->ioctl_if_type = INT_MAIN;
+		pObj->ioctl_if = MAIN_MBSSID;
+	}
+
+	switch(cmd)
+	{
+#ifdef RALINK_ATE
+#ifdef RALINK_28xx_QA
+		case RTPRIV_IOCTL_ATE:
+			{
+				RtmpDoAte(pAd, wrq);
+			}
+			break;
+#endif // RALINK_28xx_QA //
+#endif // RALINK_ATE //
+        case SIOCGIFHWADDR:
+			DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIFHWADDR\n"));
+			memcpy(wrq->u.name, pAd->CurrentAddress, ETH_ALEN);
+			break;
+		case SIOCGIWNAME:
+        {
+        	char *name=&wrq->u.name[0];
+        	rt_ioctl_giwname(net_dev, NULL, name, NULL);
+			break;
+		}
+		case SIOCGIWESSID:  //Get ESSID
+        {
+        	struct iw_point *essid=&wrq->u.essid;
+        	rt_ioctl_giwessid(net_dev, NULL, essid, essid->pointer);
+			break;
+		}
+		case SIOCSIWESSID:  //Set ESSID
+        {
+        	struct iw_point	*essid=&wrq->u.essid;
+        	rt_ioctl_siwessid(net_dev, NULL, essid, essid->pointer);
+			break;
+		}
+		case SIOCSIWNWID:   // set network id (the cell)
+		case SIOCGIWNWID:   // get network id
+			Status = -EOPNOTSUPP;
+			break;
+		case SIOCSIWFREQ:   //set channel/frequency (Hz)
+        {
+        	struct iw_freq *freq=&wrq->u.freq;
+        	rt_ioctl_siwfreq(net_dev, NULL, freq, NULL);
+			break;
+		}
+		case SIOCGIWFREQ:   // get channel/frequency (Hz)
+        {
+        	struct iw_freq *freq=&wrq->u.freq;
+        	rt_ioctl_giwfreq(net_dev, NULL, freq, NULL);
+			break;
+		}
+		case SIOCSIWNICKN: //set node name/nickname
+        {
+        	struct iw_point *data=&wrq->u.data;
+        	rt_ioctl_siwnickn(net_dev, NULL, data, NULL);
+			break;
+		}
+		case SIOCGIWNICKN: //get node name/nickname
+        {
+        	struct iw_point *data=&wrq->u.data;
+        	rt_ioctl_giwnickn(net_dev, NULL, data, NULL);
+			break;
+		}
+		case SIOCGIWRATE:   //get default bit rate (bps)
+		    rt_ioctl_giwrate(net_dev, NULL, &wrq->u, NULL);
+            break;
+	    case SIOCSIWRATE:  //set default bit rate (bps)
+	        rt_ioctl_siwrate(net_dev, NULL, &wrq->u, NULL);
+            break;
+        case SIOCGIWRTS:  // get RTS/CTS threshold (bytes)
+        {
+        	struct iw_param *rts=&wrq->u.rts;
+        	rt_ioctl_giwrts(net_dev, NULL, rts, NULL);
+			break;
+		}
+        case SIOCSIWRTS:  //set RTS/CTS threshold (bytes)
+        {
+        	struct iw_param *rts=&wrq->u.rts;
+        	rt_ioctl_siwrts(net_dev, NULL, rts, NULL);
+			break;
+		}
+        case SIOCGIWFRAG:  //get fragmentation thr (bytes)
+        {
+        	struct iw_param *frag=&wrq->u.frag;
+        	rt_ioctl_giwfrag(net_dev, NULL, frag, NULL);
+			break;
+		}
+        case SIOCSIWFRAG:  //set fragmentation thr (bytes)
+        {
+        	struct iw_param *frag=&wrq->u.frag;
+        	rt_ioctl_siwfrag(net_dev, NULL, frag, NULL);
+			break;
+		}
+        case SIOCGIWENCODE:  //get encoding token & mode
+        {
+        	struct iw_point *erq=&wrq->u.encoding;
+        	if(erq->pointer)
+        		rt_ioctl_giwencode(net_dev, NULL, erq, erq->pointer);
+			break;
+		}
+        case SIOCSIWENCODE:  //set encoding token & mode
+        {
+        	struct iw_point *erq=&wrq->u.encoding;
+        	if(erq->pointer)
+        		rt_ioctl_siwencode(net_dev, NULL, erq, erq->pointer);
+			break;
+		}
+		case SIOCGIWAP:     //get access point MAC addresses
+        {
+        	struct sockaddr *ap_addr=&wrq->u.ap_addr;
+        	rt_ioctl_giwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
+			break;
+		}
+	    case SIOCSIWAP:  //set access point MAC addresses
+        {
+        	struct sockaddr *ap_addr=&wrq->u.ap_addr;
+        	rt_ioctl_siwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
+			break;
+		}
+		case SIOCGIWMODE:   //get operation mode
+        {
+        	__u32 *mode=&wrq->u.mode;
+        	rt_ioctl_giwmode(net_dev, NULL, mode, NULL);
+			break;
+		}
+		case SIOCSIWMODE:   //set operation mode
+        {
+        	__u32 *mode=&wrq->u.mode;
+        	rt_ioctl_siwmode(net_dev, NULL, mode, NULL);
+			break;
+		}
+		case SIOCGIWSENS:   //get sensitivity (dBm)
+		case SIOCSIWSENS:	//set sensitivity (dBm)
+		case SIOCGIWPOWER:  //get Power Management settings
+		case SIOCSIWPOWER:  //set Power Management settings
+		case SIOCGIWTXPOW:  //get transmit power (dBm)
+		case SIOCSIWTXPOW:  //set transmit power (dBm)
+		case SIOCGIWRANGE:	//Get range of parameters
+		case SIOCGIWRETRY:	//get retry limits and lifetime
+		case SIOCSIWRETRY:	//set retry limits and lifetime
+			Status = -EOPNOTSUPP;
+			break;
+		case RT_PRIV_IOCTL:
+        case RT_PRIV_IOCTL_EXT:
+			subcmd = wrq->u.data.flags;
+			if( subcmd & OID_GET_SET_TOGGLE)
+				Status = RTMPSetInformation(pAd, rq, subcmd);
+			else
+				Status = RTMPQueryInformation(pAd, rq, subcmd);
+			break;
+		case SIOCGIWPRIV:
+			if (wrq->u.data.pointer)
+			{
+				if ( access_ok(VERIFY_WRITE, wrq->u.data.pointer, sizeof(privtab)) != TRUE)
+					break;
+				wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
+				if (copy_to_user(wrq->u.data.pointer, privtab, sizeof(privtab)))
+					Status = -EFAULT;
+			}
+			break;
+		case RTPRIV_IOCTL_SET:
+			if(access_ok(VERIFY_READ, wrq->u.data.pointer, wrq->u.data.length) != TRUE)
+				break;
+			rt_ioctl_setparam(net_dev, NULL, NULL, wrq->u.data.pointer);
+			break;
+		case RTPRIV_IOCTL_GSITESURVEY:
+			RTMPIoctlGetSiteSurvey(pAd, wrq);
+		    break;
+#ifdef DBG
+		case RTPRIV_IOCTL_MAC:
+			RTMPIoctlMAC(pAd, wrq);
+			break;
+		case RTPRIV_IOCTL_E2P:
+			RTMPIoctlE2PROM(pAd, wrq);
+			break;
+#ifdef RT30xx
+		case RTPRIV_IOCTL_RF:
+			RTMPIoctlRF(pAd, wrq);
+			break;
+#endif // RT30xx //
+#endif // DBG //
+        case SIOCETHTOOL:
+                break;
+		default:
+			DBGPRINT(RT_DEBUG_ERROR, ("IOCTL::unknown IOCTL's cmd = 0x%08x\n", cmd));
+			Status = -EOPNOTSUPP;
+			break;
+	}
+
+    if(StateMachineTouched) // Upper layer sent a MLME-related operations
+    	RT28XX_MLME_HANDLER(pAd);
+
+	return Status;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set SSID
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT Set_SSID_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          arg)
+{
+    NDIS_802_11_SSID                    Ssid, *pSsid=NULL;
+    BOOLEAN                             StateMachineTouched = FALSE;
+    int                                 success = TRUE;
+
+    if( strlen(arg) <= MAX_LEN_OF_SSID)
+    {
+        NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
+        if (strlen(arg) != 0)
+        {
+            NdisMoveMemory(Ssid.Ssid, arg, strlen(arg));
+            Ssid.SsidLength = strlen(arg);
+        }
+        else   //ANY ssid
+        {
+            Ssid.SsidLength = 0;
+		    memcpy(Ssid.Ssid, "", 0);
+			pAdapter->StaCfg.BssType = BSS_INFRA;
+			pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
+	        pAdapter->StaCfg.WepStatus  = Ndis802_11EncryptionDisabled;
+		}
+        pSsid = &Ssid;
+
+        if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
+        {
+            RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
+            DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
+        }
+
+        pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
+        pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
+		pAdapter->bConfigChanged = TRUE;
+
+        MlmeEnqueue(pAdapter,
+                    MLME_CNTL_STATE_MACHINE,
+                    OID_802_11_SSID,
+                    sizeof(NDIS_802_11_SSID),
+                    (VOID *)pSsid);
+
+        StateMachineTouched = TRUE;
+        DBGPRINT(RT_DEBUG_TRACE, ("Set_SSID_Proc::(Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
+    }
+    else
+        success = FALSE;
+
+    if (StateMachineTouched) // Upper layer sent a MLME-related operations
+    	RT28XX_MLME_HANDLER(pAdapter);
+
+    return success;
+}
+
+#ifdef WMM_SUPPORT
+/*
+    ==========================================================================
+    Description:
+        Set WmmCapable Enable or Disable
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_WmmCapable_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	BOOLEAN	bWmmCapable;
+
+	bWmmCapable = simple_strtol(arg, 0, 10);
+
+	if ((bWmmCapable == 1)
+#ifdef RT2870
+		&& (pAd->NumberOfPipes >= 5)
+#endif // RT2870 //
+		)
+		pAd->CommonCfg.bWmmCapable = TRUE;
+	else if (bWmmCapable == 0)
+		pAd->CommonCfg.bWmmCapable = FALSE;
+	else
+		return FALSE;  //Invalid argument
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_WmmCapable_Proc::(bWmmCapable=%d)\n",
+		pAd->CommonCfg.bWmmCapable));
+
+	return TRUE;
+}
+#endif // WMM_SUPPORT //
+
+/*
+    ==========================================================================
+    Description:
+        Set Network Type(Infrastructure/Adhoc mode)
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT Set_NetworkType_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          arg)
+{
+    UINT32	Value = 0;
+
+    if (strcmp(arg, "Adhoc") == 0)
+	{
+		if (pAdapter->StaCfg.BssType != BSS_ADHOC)
+		{
+			// Config has changed
+			pAdapter->bConfigChanged = TRUE;
+            if (MONITOR_ON(pAdapter))
+            {
+                RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
+                RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
+				Value &= (~0x80);
+				RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
+                OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
+                pAdapter->StaCfg.bAutoReconnect = TRUE;
+                LinkDown(pAdapter, FALSE);
+            }
+			if (INFRA_ON(pAdapter))
+			{
+				//BOOLEAN Cancelled;
+				// Set the AutoReconnectSsid to prevent it reconnect to old SSID
+				// Since calling this indicate user don't want to connect to that SSID anymore.
+				pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
+				NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
+
+				LinkDown(pAdapter, FALSE);
+
+				DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event BB!\n"));
+			}
+		}
+		pAdapter->StaCfg.BssType = BSS_ADHOC;
+        pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
+		DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(AD-HOC)\n"));
+	}
+    else if (strcmp(arg, "Infra") == 0)
+	{
+		if (pAdapter->StaCfg.BssType != BSS_INFRA)
+		{
+			// Config has changed
+			pAdapter->bConfigChanged = TRUE;
+            if (MONITOR_ON(pAdapter))
+            {
+                RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
+                RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
+				Value &= (~0x80);
+				RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
+                OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
+                pAdapter->StaCfg.bAutoReconnect = TRUE;
+                LinkDown(pAdapter, FALSE);
+            }
+			if (ADHOC_ON(pAdapter))
+			{
+				// Set the AutoReconnectSsid to prevent it reconnect to old SSID
+				// Since calling this indicate user don't want to connect to that SSID anymore.
+				pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
+				NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
+
+				LinkDown(pAdapter, FALSE);
+			}
+		}
+		pAdapter->StaCfg.BssType = BSS_INFRA;
+        pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
+		DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(INFRA)\n"));
+
+        pAdapter->StaCfg.BssType = BSS_INFRA;
+	}
+    else if (strcmp(arg, "Monitor") == 0)
+    {
+		UCHAR	bbpValue = 0;
+		BCN_TIME_CFG_STRUC csr;
+		OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_INFRA_ON);
+        OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_ADHOC_ON);
+		OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
+		// disable all periodic state machine
+		pAdapter->StaCfg.bAutoReconnect = FALSE;
+		// reset all mlme state machine
+		RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
+		DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_MEDIA_STATE_CONNECTED \n"));
+        if (pAdapter->CommonCfg.CentralChannel == 0)
+        {
+#ifdef DOT11_N_SUPPORT
+            if (pAdapter->CommonCfg.PhyMode == PHY_11AN_MIXED)
+                pAdapter->CommonCfg.CentralChannel = 36;
+            else
+#endif // DOT11_N_SUPPORT //
+                pAdapter->CommonCfg.CentralChannel = 6;
+        }
+#ifdef DOT11_N_SUPPORT
+        else
+            N_ChannelCheck(pAdapter);
+#endif // DOT11_N_SUPPORT //
+
+#ifdef DOT11_N_SUPPORT
+	if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
+            pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
+            pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
+		{
+			// 40MHz ,control channel at lower
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
+			bbpValue &= (~0x18);
+			bbpValue |= 0x10;
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
+			pAdapter->CommonCfg.BBPCurrentBW = BW_40;
+			//  RX : control channel at lower
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
+			bbpValue &= (~0x20);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
+
+			RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
+			Value &= 0xfffffffe;
+			RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
+			pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel + 2;
+            AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
+		    AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
+            DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
+                                       pAdapter->CommonCfg.Channel,
+                                       pAdapter->CommonCfg.CentralChannel));
+		}
+		else if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
+                 pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
+                 pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_BELOW)
+		{
+			// 40MHz ,control channel at upper
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
+			bbpValue &= (~0x18);
+			bbpValue |= 0x10;
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
+			pAdapter->CommonCfg.BBPCurrentBW = BW_40;
+			RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
+			Value |= 0x1;
+			RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
+
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
+			bbpValue |= (0x20);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
+			pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel - 2;
+            AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
+		    AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
+            DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
+                                       pAdapter->CommonCfg.Channel,
+                                       pAdapter->CommonCfg.CentralChannel));
+		}
+		else
+#endif // DOT11_N_SUPPORT //
+		{
+			// 20MHz
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
+			bbpValue &= (~0x18);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
+			pAdapter->CommonCfg.BBPCurrentBW = BW_20;
+			AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.Channel, FALSE);
+			AsicLockChannel(pAdapter, pAdapter->CommonCfg.Channel);
+			DBGPRINT(RT_DEBUG_TRACE, ("BW_20, Channel(%d)\n", pAdapter->CommonCfg.Channel));
+		}
+		// Enable Rx with promiscuous reception
+		RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, 0x3);
+		// ASIC supporsts sniffer function with replacing RSSI with timestamp.
+		//RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
+		//Value |= (0x80);
+		//RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
+		// disable sync
+		RTMP_IO_READ32(pAdapter, BCN_TIME_CFG, &csr.word);
+		csr.field.bBeaconGen = 0;
+		csr.field.bTBTTEnable = 0;
+		csr.field.TsfSyncMode = 0;
+		RTMP_IO_WRITE32(pAdapter, BCN_TIME_CFG, csr.word);
+
+		pAdapter->StaCfg.BssType = BSS_MONITOR;
+        pAdapter->net_dev->type = ARPHRD_IEEE80211_PRISM; //ARPHRD_IEEE80211; // IEEE80211
+		DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(MONITOR)\n"));
+    }
+
+    // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
+    pAdapter->StaCfg.WpaState = SS_NOTUSE;
+
+    DBGPRINT(RT_DEBUG_TRACE, ("Set_NetworkType_Proc::(NetworkType=%d)\n", pAdapter->StaCfg.BssType));
+
+    return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set Authentication mode
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT Set_AuthMode_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          arg)
+{
+    if ((strcmp(arg, "WEPAUTO") == 0) || (strcmp(arg, "wepauto") == 0))
+        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
+    else if ((strcmp(arg, "OPEN") == 0) || (strcmp(arg, "open") == 0))
+        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
+    else if ((strcmp(arg, "SHARED") == 0) || (strcmp(arg, "shared") == 0))
+        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
+    else if ((strcmp(arg, "WPAPSK") == 0) || (strcmp(arg, "wpapsk") == 0))
+        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
+    else if ((strcmp(arg, "WPANONE") == 0) || (strcmp(arg, "wpanone") == 0))
+        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
+    else if ((strcmp(arg, "WPA2PSK") == 0) || (strcmp(arg, "wpa2psk") == 0))
+        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
+#ifdef WPA_SUPPLICANT_SUPPORT
+    else if ((strcmp(arg, "WPA") == 0) || (strcmp(arg, "wpa") == 0))
+        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
+    else if ((strcmp(arg, "WPA2") == 0) || (strcmp(arg, "wpa2") == 0))
+        pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
+#endif // WPA_SUPPLICANT_SUPPORT //
+    else
+        return FALSE;
+
+    pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+
+    DBGPRINT(RT_DEBUG_TRACE, ("Set_AuthMode_Proc::(AuthMode=%d)\n", pAdapter->StaCfg.AuthMode));
+
+    return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set Encryption Type
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT Set_EncrypType_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          arg)
+{
+    if ((strcmp(arg, "NONE") == 0) || (strcmp(arg, "none") == 0))
+    {
+        if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+            return TRUE;    // do nothing
+
+        pAdapter->StaCfg.WepStatus     = Ndis802_11WEPDisabled;
+        pAdapter->StaCfg.PairCipher    = Ndis802_11WEPDisabled;
+	    pAdapter->StaCfg.GroupCipher   = Ndis802_11WEPDisabled;
+    }
+    else if ((strcmp(arg, "WEP") == 0) || (strcmp(arg, "wep") == 0))
+    {
+        if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+            return TRUE;    // do nothing
+
+        pAdapter->StaCfg.WepStatus     = Ndis802_11WEPEnabled;
+        pAdapter->StaCfg.PairCipher    = Ndis802_11WEPEnabled;
+	    pAdapter->StaCfg.GroupCipher   = Ndis802_11WEPEnabled;
+    }
+    else if ((strcmp(arg, "TKIP") == 0) || (strcmp(arg, "tkip") == 0))
+    {
+        if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
+            return TRUE;    // do nothing
+
+        pAdapter->StaCfg.WepStatus     = Ndis802_11Encryption2Enabled;
+        pAdapter->StaCfg.PairCipher    = Ndis802_11Encryption2Enabled;
+	    pAdapter->StaCfg.GroupCipher   = Ndis802_11Encryption2Enabled;
+    }
+    else if ((strcmp(arg, "AES") == 0) || (strcmp(arg, "aes") == 0))
+    {
+        if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
+            return TRUE;    // do nothing
+
+        pAdapter->StaCfg.WepStatus     = Ndis802_11Encryption3Enabled;
+        pAdapter->StaCfg.PairCipher    = Ndis802_11Encryption3Enabled;
+	    pAdapter->StaCfg.GroupCipher   = Ndis802_11Encryption3Enabled;
+    }
+    else
+        return FALSE;
+
+    pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+
+    DBGPRINT(RT_DEBUG_TRACE, ("Set_EncrypType_Proc::(EncrypType=%d)\n", pAdapter->StaCfg.WepStatus));
+
+    return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set Default Key ID
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT Set_DefaultKeyID_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          arg)
+{
+    ULONG                               KeyIdx;
+
+    KeyIdx = simple_strtol(arg, 0, 10);
+    if((KeyIdx >= 1 ) && (KeyIdx <= 4))
+        pAdapter->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1 );
+    else
+        return FALSE;  //Invalid argument
+
+    DBGPRINT(RT_DEBUG_TRACE, ("Set_DefaultKeyID_Proc::(DefaultKeyID=%d)\n", pAdapter->StaCfg.DefaultKeyId));
+
+    return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set WEP KEY1
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT Set_Key1_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          arg)
+{
+    int                                 KeyLen;
+    int                                 i;
+    UCHAR                               CipherAlg=CIPHER_WEP64;
+
+    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+        return TRUE;    // do nothing
+
+    KeyLen = strlen(arg);
+
+    switch (KeyLen)
+    {
+        case 5: //wep 40 Ascii type
+            pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
+            memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
+            CipherAlg = CIPHER_WEP64;
+            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
+            break;
+        case 10: //wep 40 Hex type
+            for(i=0; i < KeyLen; i++)
+            {
+                if( !isxdigit(*(arg+i)) )
+                    return FALSE;  //Not Hex value;
+            }
+            pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
+            AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
+            CipherAlg = CIPHER_WEP64;
+            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
+            break;
+        case 13: //wep 104 Ascii type
+            pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
+            memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
+            CipherAlg = CIPHER_WEP128;
+            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
+            break;
+        case 26: //wep 104 Hex type
+            for(i=0; i < KeyLen; i++)
+            {
+                if( !isxdigit(*(arg+i)) )
+                    return FALSE;  //Not Hex value;
+            }
+            pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
+            AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
+            CipherAlg = CIPHER_WEP128;
+            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
+            break;
+        default: //Invalid argument
+            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::Invalid argument (=%s)\n", arg));
+            return FALSE;
+    }
+
+    pAdapter->SharedKey[BSS0][0].CipherAlg = CipherAlg;
+
+    // Set keys (into ASIC)
+    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+        ;   // not support
+    else    // Old WEP stuff
+    {
+        AsicAddSharedKeyEntry(pAdapter,
+                              0,
+                              0,
+                              pAdapter->SharedKey[BSS0][0].CipherAlg,
+                              pAdapter->SharedKey[BSS0][0].Key,
+                              NULL,
+                              NULL);
+    }
+
+    return TRUE;
+}
+/*
+    ==========================================================================
+
+    Description:
+        Set WEP KEY2
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT Set_Key2_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          arg)
+{
+    int                                 KeyLen;
+    int                                 i;
+    UCHAR                               CipherAlg=CIPHER_WEP64;
+
+    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+        return TRUE;    // do nothing
+
+    KeyLen = strlen(arg);
+
+    switch (KeyLen)
+    {
+        case 5: //wep 40 Ascii type
+            pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
+            memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
+            CipherAlg = CIPHER_WEP64;
+            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
+            break;
+        case 10: //wep 40 Hex type
+            for(i=0; i < KeyLen; i++)
+            {
+                if( !isxdigit(*(arg+i)) )
+                    return FALSE;  //Not Hex value;
+            }
+            pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
+            AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
+            CipherAlg = CIPHER_WEP64;
+            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
+            break;
+        case 13: //wep 104 Ascii type
+            pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
+            memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
+            CipherAlg = CIPHER_WEP128;
+            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
+            break;
+        case 26: //wep 104 Hex type
+            for(i=0; i < KeyLen; i++)
+            {
+                if( !isxdigit(*(arg+i)) )
+                    return FALSE;  //Not Hex value;
+            }
+            pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
+            AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
+            CipherAlg = CIPHER_WEP128;
+            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
+            break;
+        default: //Invalid argument
+            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::Invalid argument (=%s)\n", arg));
+            return FALSE;
+    }
+    pAdapter->SharedKey[BSS0][1].CipherAlg = CipherAlg;
+
+    // Set keys (into ASIC)
+    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+        ;   // not support
+    else    // Old WEP stuff
+    {
+        AsicAddSharedKeyEntry(pAdapter,
+                              0,
+                              1,
+                              pAdapter->SharedKey[BSS0][1].CipherAlg,
+                              pAdapter->SharedKey[BSS0][1].Key,
+                              NULL,
+                              NULL);
+    }
+
+    return TRUE;
+}
+/*
+    ==========================================================================
+    Description:
+        Set WEP KEY3
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT Set_Key3_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          arg)
+{
+    int                                 KeyLen;
+    int                                 i;
+    UCHAR                               CipherAlg=CIPHER_WEP64;
+
+    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+        return TRUE;    // do nothing
+
+    KeyLen = strlen(arg);
+
+    switch (KeyLen)
+    {
+        case 5: //wep 40 Ascii type
+            pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
+            memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
+            CipherAlg = CIPHER_WEP64;
+            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
+            break;
+        case 10: //wep 40 Hex type
+            for(i=0; i < KeyLen; i++)
+            {
+                if( !isxdigit(*(arg+i)) )
+                    return FALSE;  //Not Hex value;
+            }
+            pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
+            AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
+            CipherAlg = CIPHER_WEP64;
+            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
+            break;
+        case 13: //wep 104 Ascii type
+            pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
+            memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
+            CipherAlg = CIPHER_WEP128;
+            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
+            break;
+        case 26: //wep 104 Hex type
+            for(i=0; i < KeyLen; i++)
+            {
+                if( !isxdigit(*(arg+i)) )
+                    return FALSE;  //Not Hex value;
+            }
+            pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
+            AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
+            CipherAlg = CIPHER_WEP128;
+            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
+            break;
+        default: //Invalid argument
+            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::Invalid argument (=%s)\n", arg));
+            return FALSE;
+    }
+    pAdapter->SharedKey[BSS0][2].CipherAlg = CipherAlg;
+
+    // Set keys (into ASIC)
+    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+        ;   // not support
+    else    // Old WEP stuff
+    {
+        AsicAddSharedKeyEntry(pAdapter,
+                              0,
+                              2,
+                              pAdapter->SharedKey[BSS0][2].CipherAlg,
+                              pAdapter->SharedKey[BSS0][2].Key,
+                              NULL,
+                              NULL);
+    }
+
+    return TRUE;
+}
+/*
+    ==========================================================================
+    Description:
+        Set WEP KEY4
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT Set_Key4_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          arg)
+{
+    int                                 KeyLen;
+    int                                 i;
+    UCHAR                               CipherAlg=CIPHER_WEP64;
+
+    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+        return TRUE;    // do nothing
+
+    KeyLen = strlen(arg);
+
+    switch (KeyLen)
+    {
+        case 5: //wep 40 Ascii type
+            pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
+            memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
+            CipherAlg = CIPHER_WEP64;
+            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
+            break;
+        case 10: //wep 40 Hex type
+            for(i=0; i < KeyLen; i++)
+            {
+                if( !isxdigit(*(arg+i)) )
+                    return FALSE;  //Not Hex value;
+            }
+            pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
+            AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
+            CipherAlg = CIPHER_WEP64;
+            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
+            break;
+        case 13: //wep 104 Ascii type
+            pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
+            memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
+            CipherAlg = CIPHER_WEP128;
+            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
+            break;
+        case 26: //wep 104 Hex type
+            for(i=0; i < KeyLen; i++)
+            {
+                if( !isxdigit(*(arg+i)) )
+                    return FALSE;  //Not Hex value;
+            }
+            pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
+            AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
+            CipherAlg = CIPHER_WEP128;
+            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
+            break;
+        default: //Invalid argument
+            DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::Invalid argument (=%s)\n", arg));
+            return FALSE;
+    }
+    pAdapter->SharedKey[BSS0][3].CipherAlg = CipherAlg;
+
+    // Set keys (into ASIC)
+    if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+        ;   // not support
+    else    // Old WEP stuff
+    {
+        AsicAddSharedKeyEntry(pAdapter,
+                              0,
+                              3,
+                              pAdapter->SharedKey[BSS0][3].CipherAlg,
+                              pAdapter->SharedKey[BSS0][3].Key,
+                              NULL,
+                              NULL);
+    }
+
+    return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set WPA PSK key
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT Set_WPAPSK_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          arg)
+{
+    UCHAR                   keyMaterial[40];
+
+    if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
+        (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
+	    (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
+		)
+        return TRUE;    // do nothing
+
+    DBGPRINT(RT_DEBUG_TRACE, ("Set_WPAPSK_Proc::(WPAPSK=%s)\n", arg));
+
+    NdisZeroMemory(keyMaterial, 40);
+
+    if ((strlen(arg) < 8) || (strlen(arg) > 64))
+    {
+        DBGPRINT(RT_DEBUG_TRACE, ("Set failed!!(WPAPSK=%s), WPAPSK key-string required 8 ~ 64 characters \n", arg));
+        return FALSE;
+    }
+
+    if (strlen(arg) == 64)
+    {
+        AtoH(arg, keyMaterial, 32);
+        NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
+
+    }
+    else
+    {
+        PasswordHash((char *)arg, pAdapter->MlmeAux.Ssid, pAdapter->MlmeAux.SsidLen, keyMaterial);
+        NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
+    }
+
+
+
+    if(pAdapter->StaCfg.BssType == BSS_ADHOC &&
+       pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+    {
+         pAdapter->StaCfg.WpaState = SS_NOTUSE;
+    }
+    else
+    {
+        // Start STA supplicant state machine
+        pAdapter->StaCfg.WpaState = SS_START;
+    }
+
+    return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Set Power Saving mode
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT Set_PSMode_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          arg)
+{
+    if (pAdapter->StaCfg.BssType == BSS_INFRA)
+    {
+        if ((strcmp(arg, "Max_PSP") == 0) ||
+			(strcmp(arg, "max_psp") == 0) ||
+			(strcmp(arg, "MAX_PSP") == 0))
+        {
+            // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
+            // to exclude certain situations.
+            if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
+                pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
+            pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
+            OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
+            pAdapter->StaCfg.DefaultListenCount = 5;
+
+        }
+        else if ((strcmp(arg, "Fast_PSP") == 0) ||
+				 (strcmp(arg, "fast_psp") == 0) ||
+                 (strcmp(arg, "FAST_PSP") == 0))
+        {
+            // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
+            // to exclude certain situations.
+            OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
+            if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
+                pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
+            pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
+            pAdapter->StaCfg.DefaultListenCount = 3;
+        }
+        else if ((strcmp(arg, "Legacy_PSP") == 0) ||
+                 (strcmp(arg, "legacy_psp") == 0) ||
+                 (strcmp(arg, "LEGACY_PSP") == 0))
+        {
+            // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
+            // to exclude certain situations.
+            OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
+            if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
+                pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
+            pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
+            pAdapter->StaCfg.DefaultListenCount = 3;
+        }
+        else
+        {
+            //Default Ndis802_11PowerModeCAM
+            // clear PSM bit immediately
+            MlmeSetPsmBit(pAdapter, PWR_ACTIVE);
+            OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
+            if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
+                pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
+            pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
+        }
+
+        DBGPRINT(RT_DEBUG_TRACE, ("Set_PSMode_Proc::(PSMode=%ld)\n", pAdapter->StaCfg.WindowsPowerMode));
+    }
+    else
+        return FALSE;
+
+
+    return TRUE;
+}
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+/*
+    ==========================================================================
+    Description:
+        Set WpaSupport flag.
+    Value:
+        0: Driver ignore wpa_supplicant.
+        1: wpa_supplicant initiates scanning and AP selection.
+        2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters.
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT Set_Wpa_Support(
+    IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+
+    if ( simple_strtol(arg, 0, 10) == 0)
+        pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
+    else if ( simple_strtol(arg, 0, 10) == 1)
+        pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
+    else if ( simple_strtol(arg, 0, 10) == 2)
+        pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE_WITH_WEB_UI;
+    else
+        pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
+
+    DBGPRINT(RT_DEBUG_TRACE, ("Set_Wpa_Support::(WpaSupplicantUP=%d)\n", pAd->StaCfg.WpaSupplicantUP));
+
+    return TRUE;
+}
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef DBG
+/*
+    ==========================================================================
+    Description:
+        Read / Write MAC
+    Arguments:
+        pAdapter                    Pointer to our adapter
+        wrq                         Pointer to the ioctl argument
+
+    Return Value:
+        None
+
+    Note:
+        Usage:
+               1.) iwpriv ra0 mac 0        ==> read MAC where Addr=0x0
+               2.) iwpriv ra0 mac 0=12     ==> write MAC where Addr=0x0, value=12
+    ==========================================================================
+*/
+VOID RTMPIoctlMAC(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq)
+{
+	CHAR				*this_char;
+	CHAR				*value;
+	INT					j = 0, k = 0;
+	CHAR				msg[1024];
+	CHAR				arg[255];
+	ULONG				macAddr = 0;
+	UCHAR				temp[16], temp2[16];
+	UINT32				macValue = 0;
+	INT					Status;
+	BOOLEAN				bIsPrintAllMAC = FALSE;
+
+
+	memset(msg, 0x00, 1024);
+	if (wrq->u.data.length > 1) //No parameters.
+	{
+	    Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
+		sprintf(msg, "\n");
+
+		//Parsing Read or Write
+	    this_char = arg;
+		if (!*this_char)
+			goto next;
+
+		if ((value = rtstrchr(this_char, '=')) != NULL)
+			*value++ = 0;
+
+		if (!value || !*value)
+		{ //Read
+			// Sanity check
+			if(strlen(this_char) > 4)
+				goto next;
+
+			j = strlen(this_char);
+			while(j-- > 0)
+			{
+				if(this_char[j] > 'f' || this_char[j] < '0')
+					return;
+			}
+
+			// Mac Addr
+			k = j = strlen(this_char);
+			while(j-- > 0)
+			{
+				this_char[4-k+j] = this_char[j];
+			}
+
+			while(k < 4)
+				this_char[3-k++]='0';
+			this_char[4]='\0';
+
+			if(strlen(this_char) == 4)
+			{
+				AtoH(this_char, temp, 2);
+				macAddr = *temp*256 + temp[1];
+				if (macAddr < 0xFFFF)
+				{
+					RTMP_IO_READ32(pAdapter, macAddr, &macValue);
+					DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%lx, MacValue=%x\n", macAddr, macValue));
+					sprintf(msg+strlen(msg), "[0x%08lX]:%08X  ", macAddr , macValue);
+				}
+				else
+				{//Invalid parametes, so default printk all mac
+					bIsPrintAllMAC = TRUE;
+					goto next;
+				}
+			}
+		}
+		else
+		{ //Write
+			memcpy(&temp2, value, strlen(value));
+			temp2[strlen(value)] = '\0';
+
+			// Sanity check
+			if((strlen(this_char) > 4) || strlen(temp2) > 8)
+				goto next;
+
+			j = strlen(this_char);
+			while(j-- > 0)
+			{
+				if(this_char[j] > 'f' || this_char[j] < '0')
+					return;
+			}
+
+			j = strlen(temp2);
+			while(j-- > 0)
+			{
+				if(temp2[j] > 'f' || temp2[j] < '0')
+					return;
+			}
+
+			//MAC Addr
+			k = j = strlen(this_char);
+			while(j-- > 0)
+			{
+				this_char[4-k+j] = this_char[j];
+			}
+
+			while(k < 4)
+				this_char[3-k++]='0';
+			this_char[4]='\0';
+
+			//MAC value
+			k = j = strlen(temp2);
+			while(j-- > 0)
+			{
+				temp2[8-k+j] = temp2[j];
+			}
+
+			while(k < 8)
+				temp2[7-k++]='0';
+			temp2[8]='\0';
+
+			{
+				AtoH(this_char, temp, 2);
+				macAddr = *temp*256 + temp[1];
+
+				AtoH(temp2, temp, 4);
+				macValue = *temp*256*256*256 + temp[1]*256*256 + temp[2]*256 + temp[3];
+
+				// debug mode
+				if (macAddr == (HW_DEBUG_SETTING_BASE + 4))
+				{
+					// 0x2bf4: byte0 non-zero: enable R17 tuning, 0: disable R17 tuning
+                    if (macValue & 0x000000ff)
+                    {
+                        pAdapter->BbpTuning.bEnable = TRUE;
+                        DBGPRINT(RT_DEBUG_TRACE,("turn on R17 tuning\n"));
+                    }
+                    else
+                    {
+                        UCHAR R66;
+                        pAdapter->BbpTuning.bEnable = FALSE;
+                        R66 = 0x26 + GET_LNA_GAIN(pAdapter);
+#ifdef RALINK_ATE
+						if (ATE_ON(pAdapter))
+						{
+							ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R66, (0x26 + GET_LNA_GAIN(pAdapter)));
+						}
+						else
+#endif // RALINK_ATE //
+						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R66, (0x26 + GET_LNA_GAIN(pAdapter)));
+                        DBGPRINT(RT_DEBUG_TRACE,("turn off R17 tuning, restore to 0x%02x\n", R66));
+                    }
+					return;
+				}
+
+				DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%02lx, MacValue=0x%x\n", macAddr, macValue));
+
+				RTMP_IO_WRITE32(pAdapter, macAddr, macValue);
+				sprintf(msg+strlen(msg), "[0x%08lX]:%08X  ", macAddr, macValue);
+			}
+		}
+	}
+	else
+		bIsPrintAllMAC = TRUE;
+next:
+	if (bIsPrintAllMAC)
+	{
+		struct file		*file_w;
+		PCHAR			fileName = "MacDump.txt";
+		mm_segment_t	orig_fs;
+
+		orig_fs = get_fs();
+		set_fs(KERNEL_DS);
+
+		// open file
+		file_w = filp_open(fileName, O_WRONLY|O_CREAT, 0);
+		if (IS_ERR(file_w))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("-->2) %s: Error %ld opening %s\n", __FUNCTION__, -PTR_ERR(file_w), fileName));
+		}
+		else
+		{
+			if (file_w->f_op && file_w->f_op->write)
+			{
+				file_w->f_pos = 0;
+				macAddr = 0x1000;
+
+				while (macAddr <= 0x1800)
+				{
+					RTMP_IO_READ32(pAdapter, macAddr, &macValue);
+					sprintf(msg, "%08lx = %08X\n", macAddr, macValue);
+
+					// write data to file
+					file_w->f_op->write(file_w, msg, strlen(msg), &file_w->f_pos);
+
+					printk("%s", msg);
+					macAddr += 4;
+				}
+				sprintf(msg, "\nDump all MAC values to %s\n", fileName);
+			}
+			filp_close(file_w, NULL);
+		}
+		set_fs(orig_fs);
+	}
+	if(strlen(msg) == 1)
+		sprintf(msg+strlen(msg), "===>Error command format!");
+
+	// Copy the information into the user buffer
+	wrq->u.data.length = strlen(msg);
+	Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlMAC\n\n"));
+}
+
+/*
+    ==========================================================================
+    Description:
+        Read / Write E2PROM
+    Arguments:
+        pAdapter                    Pointer to our adapter
+        wrq                         Pointer to the ioctl argument
+
+    Return Value:
+        None
+
+    Note:
+        Usage:
+               1.) iwpriv ra0 e2p 0     	==> read E2PROM where Addr=0x0
+               2.) iwpriv ra0 e2p 0=1234    ==> write E2PROM where Addr=0x0, value=1234
+    ==========================================================================
+*/
+VOID RTMPIoctlE2PROM(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq)
+{
+	CHAR				*this_char;
+	CHAR				*value;
+	INT					j = 0, k = 0;
+	CHAR				msg[1024];
+	CHAR				arg[255];
+	USHORT				eepAddr = 0;
+	UCHAR				temp[16], temp2[16];
+	USHORT				eepValue;
+	int					Status;
+	BOOLEAN				bIsPrintAllE2P = FALSE;
+
+
+	memset(msg, 0x00, 1024);
+	if (wrq->u.data.length > 1) //No parameters.
+	{
+	    Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
+		sprintf(msg, "\n");
+
+	    //Parsing Read or Write
+		this_char = arg;
+
+
+		if (!*this_char)
+			goto next;
+
+		if ((value = rtstrchr(this_char, '=')) != NULL)
+			*value++ = 0;
+
+		if (!value || !*value)
+		{ //Read
+
+			// Sanity check
+			if(strlen(this_char) > 4)
+				goto next;
+
+			j = strlen(this_char);
+			while(j-- > 0)
+			{
+				if(this_char[j] > 'f' || this_char[j] < '0')
+					return;
+			}
+
+			// E2PROM addr
+			k = j = strlen(this_char);
+			while(j-- > 0)
+			{
+				this_char[4-k+j] = this_char[j];
+			}
+
+			while(k < 4)
+				this_char[3-k++]='0';
+			this_char[4]='\0';
+
+			if(strlen(this_char) == 4)
+			{
+				AtoH(this_char, temp, 2);
+				eepAddr = *temp*256 + temp[1];
+				if (eepAddr < 0xFFFF)
+				{
+					RT28xx_EEPROM_READ16(pAdapter, eepAddr, eepValue);
+					sprintf(msg+strlen(msg), "[0x%04X]:0x%04X  ", eepAddr , eepValue);
+				}
+				else
+				{//Invalid parametes, so default printk all bbp
+					bIsPrintAllE2P = TRUE;
+					goto next;
+				}
+			}
+		}
+		else
+		{ //Write
+			memcpy(&temp2, value, strlen(value));
+			temp2[strlen(value)] = '\0';
+
+			// Sanity check
+			if((strlen(this_char) > 4) || strlen(temp2) > 8)
+				goto next;
+
+			j = strlen(this_char);
+			while(j-- > 0)
+			{
+				if(this_char[j] > 'f' || this_char[j] < '0')
+					return;
+			}
+			j = strlen(temp2);
+			while(j-- > 0)
+			{
+				if(temp2[j] > 'f' || temp2[j] < '0')
+					return;
+			}
+
+			//MAC Addr
+			k = j = strlen(this_char);
+			while(j-- > 0)
+			{
+				this_char[4-k+j] = this_char[j];
+			}
+
+			while(k < 4)
+				this_char[3-k++]='0';
+			this_char[4]='\0';
+
+			//MAC value
+			k = j = strlen(temp2);
+			while(j-- > 0)
+			{
+				temp2[4-k+j] = temp2[j];
+			}
+
+			while(k < 4)
+				temp2[3-k++]='0';
+			temp2[4]='\0';
+
+			AtoH(this_char, temp, 2);
+			eepAddr = *temp*256 + temp[1];
+
+			AtoH(temp2, temp, 2);
+			eepValue = *temp*256 + temp[1];
+
+			RT28xx_EEPROM_WRITE16(pAdapter, eepAddr, eepValue);
+			sprintf(msg+strlen(msg), "[0x%02X]:%02X  ", eepAddr, eepValue);
+		}
+	}
+	else
+		bIsPrintAllE2P = TRUE;
+next:
+	if (bIsPrintAllE2P)
+	{
+		struct file		*file_w;
+		PCHAR			fileName = "EEPROMDump.txt";
+		mm_segment_t	orig_fs;
+
+		orig_fs = get_fs();
+		set_fs(KERNEL_DS);
+
+		// open file
+		file_w = filp_open(fileName, O_WRONLY|O_CREAT, 0);
+		if (IS_ERR(file_w))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("-->2) %s: Error %ld opening %s\n", __FUNCTION__, -PTR_ERR(file_w), fileName));
+		}
+		else
+		{
+			if (file_w->f_op && file_w->f_op->write)
+			{
+				file_w->f_pos = 0;
+				eepAddr = 0x00;
+
+				while (eepAddr <= 0xFE)
+				{
+					RT28xx_EEPROM_READ16(pAdapter, eepAddr, eepValue);
+					sprintf(msg, "%08x = %04x\n", eepAddr , eepValue);
+
+					// write data to file
+					file_w->f_op->write(file_w, msg, strlen(msg), &file_w->f_pos);
+
+					printk("%s", msg);
+					eepAddr += 2;
+				}
+				sprintf(msg, "\nDump all EEPROM values to %s\n", fileName);
+			}
+			filp_close(file_w, NULL);
+		}
+		set_fs(orig_fs);
+	}
+	if(strlen(msg) == 1)
+		sprintf(msg+strlen(msg), "===>Error command format!");
+
+
+	// Copy the information into the user buffer
+	wrq->u.data.length = strlen(msg);
+	Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlE2PROM\n"));
+}
+#ifdef RT30xx
+/*
+    ==========================================================================
+    Description:
+        Read / Write RF register
+Arguments:
+    pAdapter                    Pointer to our adapter
+    wrq                         Pointer to the ioctl argument
+
+    Return Value:
+        None
+
+    Note:
+        Usage:
+               1.) iwpriv ra0 rf                ==> read all RF registers
+               2.) iwpriv ra0 rf 1              ==> read RF where RegID=1
+               3.) iwpriv ra0 rf 1=10		    ==> write RF R1=0x10
+    ==========================================================================
+*/
+VOID RTMPIoctlRF(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq)
+{
+	CHAR				*this_char;
+	CHAR				*value;
+	UCHAR				regRF = 0;
+	CHAR				msg[2048];
+	CHAR				arg[255];
+	INT					rfId;
+	LONG				rfValue;
+	int					Status;
+	BOOLEAN				bIsPrintAllRF = FALSE;
+
+
+	memset(msg, 0x00, 2048);
+	if (wrq->u.data.length > 1) //No parameters.
+	{
+	    Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
+		sprintf(msg, "\n");
+
+	    //Parsing Read or Write
+		this_char = arg;
+		if (!*this_char)
+			goto next;
+
+		if ((value = strchr(this_char, '=')) != NULL)
+			*value++ = 0;
+
+		if (!value || !*value)
+		{ //Read
+			if (sscanf(this_char, "%d", &(rfId)) == 1)
+			{
+				if (rfId <= 31)
+				{
+					// In RT2860 ATE mode, we do not load 8051 firmware.
+                                            //We must access RF directly.
+                    // For RT2870 ATE mode, ATE_RF_IO_WRITE8(/READ8)_BY_REG_ID are redefined.
+#ifdef RALINK_ATE
+					if (ATE_ON(pAdapter))
+					{
+						ATE_RF_IO_READ8_BY_REG_ID(pAdapter, rfId, &regRF);
+					}
+					else
+#endif // RALINK_ATE //
+					// according to Andy, Gary, David require.
+					// the command rf shall read rf register directly for dubug.
+					// BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+					RT30xxReadRFRegister(pAdapter, rfId, &regRF);
+
+					sprintf(msg+strlen(msg), "R%02d[0x%02x]:%02X  ", rfId, rfId*2, regRF);
+				}
+				else
+				{//Invalid parametes, so default printk all RF
+					bIsPrintAllRF = TRUE;
+					goto next;
+				}
+			}
+			else
+			{ //Invalid parametes, so default printk all RF
+				bIsPrintAllRF = TRUE;
+				goto next;
+			}
+		}
+		else
+		{ //Write
+			if ((sscanf(this_char, "%d", &(rfId)) == 1) && (sscanf(value, "%lx", &(rfValue)) == 1))
+			{
+				if (rfId <= 31)
+				{
+					// In RT2860 ATE mode, we do not load 8051 firmware.
+					// We should access RF registers directly.
+                    // For RT2870 ATE mode, ATE_RF_IO_WRITE8/READ8_BY_REG_ID are redefined.
+#ifdef RALINK_ATE
+						if (ATE_ON(pAdapter))
+						{
+							ATE_RF_IO_READ8_BY_REG_ID(pAdapter, rfId, &regRF);
+							ATE_RF_IO_WRITE8_BY_REG_ID(pAdapter, (UCHAR)rfId,(UCHAR) rfValue);
+							//Read it back for showing
+							ATE_RF_IO_READ8_BY_REG_ID(pAdapter, rfId, &regRF);
+							sprintf(msg+strlen(msg), "R%02d[0x%02X]:%02X\n", rfId, rfId*2, regRF);
+						}
+						else
+#endif // RALINK_ATE //
+						{
+							// according to Andy, Gary, David require.
+							// the command RF shall read/write RF register directly for dubug.
+							//BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+					                //BBP_IO_WRITE8_BY_REG_ID(pAdapter, (UCHAR)bbpId,(UCHAR) bbpValue);
+							RT30xxReadRFRegister(pAdapter, rfId, &regRF);
+							RT30xxWriteRFRegister(pAdapter, (UCHAR)rfId,(UCHAR) rfValue);
+					                //Read it back for showing
+							//BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+							RT30xxReadRFRegister(pAdapter, rfId, &regRF);
+					                sprintf(msg+strlen(msg), "R%02d[0x%02X]:%02X\n", rfId, rfId*2, regRF);
+				                }
+				}
+				else
+				{//Invalid parametes, so default printk all RF
+					bIsPrintAllRF = TRUE;
+				}
+			}
+			else
+			{ //Invalid parametes, so default printk all RF
+				bIsPrintAllRF = TRUE;
+			}
+		}
+	}
+	else
+		bIsPrintAllRF = TRUE;
+next:
+	if (bIsPrintAllRF)
+	{
+		memset(msg, 0x00, 2048);
+		sprintf(msg, "\n");
+		for (rfId = 0; rfId <= 31; rfId++)
+		{
+			// In RT2860 ATE mode, we do not load 8051 firmware.
+            // We should access RF registers directly.
+            // For RT2870 ATE mode, ATE_RF_IO_WRITE8/READ8_BY_REG_ID are redefined.
+#ifdef RALINK_ATE
+				if (ATE_ON(pAdapter))
+				{
+					ATE_RF_IO_READ8_BY_REG_ID(pAdapter, rfId, &regRF);
+				}
+				else
+#endif // RALINK_ATE //
+
+			// according to Andy, Gary, David require.
+			// the command RF shall read/write RF register directly for dubug.
+			RT30xxReadRFRegister(pAdapter, rfId, &regRF);
+			sprintf(msg+strlen(msg), "%03d = %02X\n", rfId, regRF);
+		}
+		// Copy the information into the user buffer
+		DBGPRINT(RT_DEBUG_TRACE, ("strlen(msg)=%d\n", (UINT32)strlen(msg)));
+		wrq->u.data.length = strlen(msg);
+		if (copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("%s: copy_to_user() fail\n", __FUNCTION__));
+		}
+	}
+	else
+	{
+		if(strlen(msg) == 1)
+			sprintf(msg+strlen(msg), "===>Error command format!");
+
+		DBGPRINT(RT_DEBUG_TRACE, ("copy to user [msg=%s]\n", msg));
+		// Copy the information into the user buffer
+		DBGPRINT(RT_DEBUG_TRACE, ("strlen(msg) =%d\n", (UINT32)strlen(msg)));
+
+		// Copy the information into the user buffer
+		wrq->u.data.length = strlen(msg);
+		Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlRF\n\n"));
+}
+#endif // RT30xx //
+#endif // DBG //
+
+
+
+
+INT Set_TGnWifiTest_Proc(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  PUCHAR          arg)
+{
+    if (simple_strtol(arg, 0, 10) == 0)
+        pAd->StaCfg.bTGnWifiTest = FALSE;
+    else
+        pAd->StaCfg.bTGnWifiTest = TRUE;
+
+    DBGPRINT(RT_DEBUG_TRACE, ("IF Set_TGnWifiTest_Proc::(bTGnWifiTest=%d)\n", pAd->StaCfg.bTGnWifiTest));
+	return TRUE;
+}
+
+INT Set_LongRetryLimit_Proc(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	PUCHAR			arg)
+{
+	TX_RTY_CFG_STRUC	tx_rty_cfg;
+	UCHAR				LongRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
+
+	RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
+	tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
+	RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
+	DBGPRINT(RT_DEBUG_TRACE, ("IF Set_LongRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
+	return TRUE;
+}
+
+INT Set_ShortRetryLimit_Proc(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	PUCHAR			arg)
+{
+	TX_RTY_CFG_STRUC	tx_rty_cfg;
+	UCHAR				ShortRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
+
+	RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
+	tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
+	RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
+	DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ShortRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
+	return TRUE;
+}
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+INT Set_Ieee80211dClientMode_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          arg)
+{
+    if (simple_strtol(arg, 0, 10) == 0)
+        pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_None;
+    else if (simple_strtol(arg, 0, 10) == 1)
+        pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_Flexible;
+    else if (simple_strtol(arg, 0, 10) == 2)
+        pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_Strict;
+    else
+        return FALSE;
+
+    DBGPRINT(RT_DEBUG_TRACE, ("Set_Ieee802dMode_Proc::(IEEEE0211dMode=%d)\n", pAdapter->StaCfg.IEEE80211dClientMode));
+    return TRUE;
+}
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+#ifdef CARRIER_DETECTION_SUPPORT
+INT Set_CarrierDetect_Proc(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  PUCHAR          arg)
+{
+    if (simple_strtol(arg, 0, 10) == 0)
+        pAd->CommonCfg.CarrierDetect.Enable = FALSE;
+    else
+        pAd->CommonCfg.CarrierDetect.Enable = TRUE;
+
+    DBGPRINT(RT_DEBUG_TRACE, ("IF Set_CarrierDetect_Proc::(CarrierDetect.Enable=%d)\n", pAd->CommonCfg.CarrierDetect.Enable));
+	return TRUE;
+}
+#endif // CARRIER_DETECTION_SUPPORT //
+
diff --git a/drivers/staging/rt3070/wpa.h b/drivers/staging/rt3070/wpa.h
new file mode 100644
index 0000000..88c7c8b
--- /dev/null
+++ b/drivers/staging/rt3070/wpa.h
@@ -0,0 +1,356 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, 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 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.             *
+ *                                                                       *
+ *************************************************************************
+
+	Module Name:
+	wpa.h
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	Name		Date			Modification logs
+*/
+
+#ifndef	__WPA_H__
+#define	__WPA_H__
+
+// EAPOL Key descripter frame format related length
+#define LEN_KEY_DESC_NONCE			32
+#define LEN_KEY_DESC_IV				16
+#define LEN_KEY_DESC_RSC			8
+#define LEN_KEY_DESC_ID				8
+#define LEN_KEY_DESC_REPLAY			8
+#define LEN_KEY_DESC_MIC			16
+
+// The length is the EAPoL-Key frame except key data field.
+// Please refer to 802.11i-2004 ,Figure 43u in p.78
+#define LEN_EAPOL_KEY_MSG			(sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE)
+
+// EAP Code Type.
+#define EAP_CODE_REQUEST	1
+#define EAP_CODE_RESPONSE	2
+#define EAP_CODE_SUCCESS    3
+#define EAP_CODE_FAILURE    4
+
+// EAPOL frame Protocol Version
+#define	EAPOL_VER					1
+#define	EAPOL_VER2					2
+
+// EAPOL-KEY Descriptor Type
+#define	WPA1_KEY_DESC				0xfe
+#define WPA2_KEY_DESC               0x02
+
+// Key Descriptor Version of Key Information
+#define	DESC_TYPE_TKIP				1
+#define	DESC_TYPE_AES				2
+#define DESC_TYPE_MESH				3
+
+#define LEN_MSG1_2WAY               0x7f
+#define MAX_LEN_OF_EAP_HS           256
+
+#define LEN_MASTER_KEY				32
+
+// EAPOL EK, MK
+#define LEN_EAP_EK					16
+#define LEN_EAP_MICK				16
+#define LEN_EAP_KEY					((LEN_EAP_EK)+(LEN_EAP_MICK))
+// TKIP key related
+#define LEN_PMKID					16
+#define LEN_TKIP_EK					16
+#define LEN_TKIP_RXMICK				8
+#define LEN_TKIP_TXMICK				8
+#define LEN_AES_EK					16
+#define LEN_AES_KEY					LEN_AES_EK
+#define LEN_TKIP_KEY				((LEN_TKIP_EK)+(LEN_TKIP_RXMICK)+(LEN_TKIP_TXMICK))
+#define TKIP_AP_TXMICK_OFFSET		((LEN_EAP_KEY)+(LEN_TKIP_EK))
+#define TKIP_AP_RXMICK_OFFSET		(TKIP_AP_TXMICK_OFFSET+LEN_TKIP_TXMICK)
+#define TKIP_GTK_LENGTH				((LEN_TKIP_EK)+(LEN_TKIP_RXMICK)+(LEN_TKIP_TXMICK))
+#define LEN_PTK						((LEN_EAP_KEY)+(LEN_TKIP_KEY))
+
+// RSN IE Length definition
+#define MAX_LEN_OF_RSNIE         	90
+#define MIN_LEN_OF_RSNIE         	8
+
+//EAP Packet Type
+#define	EAPPacket		0
+#define	EAPOLStart		1
+#define	EAPOLLogoff		2
+#define	EAPOLKey		3
+#define	EAPOLASFAlert	4
+#define	EAPTtypeMax		5
+
+#define	EAPOL_MSG_INVALID	0
+#define	EAPOL_PAIR_MSG_1	1
+#define	EAPOL_PAIR_MSG_2	2
+#define	EAPOL_PAIR_MSG_3	3
+#define	EAPOL_PAIR_MSG_4	4
+#define	EAPOL_GROUP_MSG_1	5
+#define	EAPOL_GROUP_MSG_2	6
+
+#define PAIRWISEKEY					1
+#define GROUPKEY					0
+
+// Retry timer counter initial value
+#define PEER_MSG1_RETRY_TIMER_CTR           0
+#define PEER_MSG3_RETRY_TIMER_CTR           10
+#define GROUP_MSG1_RETRY_TIMER_CTR          20
+
+
+#define EAPOL_START_DISABLE					0
+#define EAPOL_START_PSK						1
+#define EAPOL_START_1X						2
+
+#define MIX_CIPHER_WPA_TKIP_ON(x)       (((x) & 0x08) != 0)
+#define MIX_CIPHER_WPA_AES_ON(x)        (((x) & 0x04) != 0)
+#define MIX_CIPHER_WPA2_TKIP_ON(x)      (((x) & 0x02) != 0)
+#define MIX_CIPHER_WPA2_AES_ON(x)       (((x) & 0x01) != 0)
+
+#define ROUND_UP(__x, __y) \
+	(((ULONG)((__x)+((__y)-1))) & ((ULONG)~((__y)-1)))
+
+#define	ADD_ONE_To_64BIT_VAR(_V)		\
+{										\
+	UCHAR	cnt = LEN_KEY_DESC_REPLAY;	\
+	do									\
+	{									\
+		cnt--;							\
+		_V[cnt]++;						\
+		if (cnt == 0)					\
+			break;						\
+	}while (_V[cnt] == 0);				\
+}
+
+#define IS_WPA_CAPABILITY(a)       (((a) >= Ndis802_11AuthModeWPA) && ((a) <= Ndis802_11AuthModeWPA1PSKWPA2PSK))
+
+// EAPOL Key Information definition within Key descriptor format
+typedef	struct PACKED _KEY_INFO
+{
+#ifdef RT_BIG_ENDIAN
+	UCHAR	KeyAck:1;
+    UCHAR	Install:1;
+    UCHAR	KeyIndex:2;
+    UCHAR	KeyType:1;
+    UCHAR	KeyDescVer:3;
+    UCHAR	Rsvd:3;
+    UCHAR	EKD_DL:1;		// EKD for AP; DL for STA
+    UCHAR	Request:1;
+    UCHAR	Error:1;
+    UCHAR	Secure:1;
+    UCHAR	KeyMic:1;
+#else
+	UCHAR	KeyMic:1;
+	UCHAR	Secure:1;
+	UCHAR	Error:1;
+	UCHAR	Request:1;
+	UCHAR	EKD_DL:1;       // EKD for AP; DL for STA
+	UCHAR	Rsvd:3;
+	UCHAR	KeyDescVer:3;
+	UCHAR	KeyType:1;
+	UCHAR	KeyIndex:2;
+	UCHAR	Install:1;
+	UCHAR	KeyAck:1;
+#endif
+}	KEY_INFO, *PKEY_INFO;
+
+// EAPOL Key descriptor format
+typedef	struct PACKED _KEY_DESCRIPTER
+{
+	UCHAR		Type;
+	KEY_INFO	KeyInfo;
+	UCHAR		KeyLength[2];
+	UCHAR		ReplayCounter[LEN_KEY_DESC_REPLAY];
+	UCHAR		KeyNonce[LEN_KEY_DESC_NONCE];
+	UCHAR		KeyIv[LEN_KEY_DESC_IV];
+	UCHAR		KeyRsc[LEN_KEY_DESC_RSC];
+	UCHAR		KeyId[LEN_KEY_DESC_ID];
+	UCHAR		KeyMic[LEN_KEY_DESC_MIC];
+	UCHAR		KeyDataLen[2];
+	UCHAR		KeyData[MAX_LEN_OF_RSNIE];
+}	KEY_DESCRIPTER, *PKEY_DESCRIPTER;
+
+typedef	struct PACKED _EAPOL_PACKET
+{
+	UCHAR	 			ProVer;
+	UCHAR	 			ProType;
+	UCHAR	 			Body_Len[2];
+	KEY_DESCRIPTER		KeyDesc;
+}	EAPOL_PACKET, *PEAPOL_PACKET;
+
+//802.11i D10 page 83
+typedef struct PACKED _GTK_ENCAP
+{
+#ifndef RT_BIG_ENDIAN
+    UCHAR               Kid:2;
+    UCHAR               tx:1;
+    UCHAR               rsv:5;
+    UCHAR               rsv1;
+#else
+    UCHAR               rsv:5;
+    UCHAR               tx:1;
+    UCHAR               Kid:2;
+    UCHAR               rsv1;
+#endif
+    UCHAR               GTK[TKIP_GTK_LENGTH];
+}   GTK_ENCAP, *PGTK_ENCAP;
+
+typedef struct PACKED _KDE_ENCAP
+{
+    UCHAR               Type;
+    UCHAR               Len;
+    UCHAR               OUI[3];
+    UCHAR               DataType;
+    GTK_ENCAP      GTKEncap;
+}   KDE_ENCAP, *PKDE_ENCAP;
+
+// For WPA1
+typedef struct PACKED _RSNIE {
+    UCHAR   oui[4];
+    USHORT  version;
+    UCHAR   mcast[4];
+    USHORT  ucount;
+    struct PACKED {
+        UCHAR oui[4];
+    }ucast[1];
+} RSNIE, *PRSNIE;
+
+// For WPA2
+typedef struct PACKED _RSNIE2 {
+    USHORT  version;
+    UCHAR   mcast[4];
+    USHORT  ucount;
+    struct PACKED {
+        UCHAR oui[4];
+    }ucast[1];
+} RSNIE2, *PRSNIE2;
+
+// AKM Suite
+typedef struct PACKED _RSNIE_AUTH {
+    USHORT acount;
+    struct PACKED {
+        UCHAR oui[4];
+    }auth[1];
+} RSNIE_AUTH,*PRSNIE_AUTH;
+
+typedef	union PACKED _RSN_CAPABILITIES	{
+	struct	PACKED {
+#ifdef RT_BIG_ENDIAN
+        USHORT		Rsvd:10;
+        USHORT		GTKSA_R_Counter:2;
+        USHORT		PTKSA_R_Counter:2;
+        USHORT		No_Pairwise:1;
+		USHORT		PreAuth:1;
+#else
+        USHORT		PreAuth:1;
+		USHORT		No_Pairwise:1;
+		USHORT		PTKSA_R_Counter:2;
+		USHORT		GTKSA_R_Counter:2;
+		USHORT		Rsvd:10;
+#endif
+	}	field;
+	USHORT			word;
+}	RSN_CAPABILITIES, *PRSN_CAPABILITIES;
+
+typedef struct PACKED _EAP_HDR {
+    UCHAR   ProVer;
+    UCHAR   ProType;
+    UCHAR   Body_Len[2];
+    UCHAR   code;
+    UCHAR   identifier;
+    UCHAR   length[2]; // including code and identifier, followed by length-2 octets of data
+} EAP_HDR, *PEAP_HDR;
+
+// For supplicant state machine states. 802.11i Draft 4.1, p. 97
+// We simplified it
+typedef	enum	_WpaState
+{
+	SS_NOTUSE,				// 0
+	SS_START,				// 1
+	SS_WAIT_MSG_3,			// 2
+	SS_WAIT_GROUP,			// 3
+	SS_FINISH,  			// 4
+	SS_KEYUPDATE,			// 5
+}	WPA_STATE;
+
+//
+//	The definition of the cipher combination
+//
+// 	 bit3	bit2  bit1   bit0
+//	+------------+------------+
+// 	|	  WPA	 |	   WPA2   |
+//	+------+-----+------+-----+
+//	| TKIP | AES | TKIP | AES |
+//	|	0  |  1  |   1  |  0  | -> 0x06
+//	|	0  |  1  |   1  |  1  | -> 0x07
+//	|	1  |  0  |   0  |  1  | -> 0x09
+//	|	1  |  0  |   1  |  1  | -> 0x0B
+//	|	1  |  1  |   0  |  1  | -> 0x0D
+//	|	1  |  1  |   1  |  0  | -> 0x0E
+//	|	1  |  1  |   1  |  1  |	-> 0x0F
+//	+------+-----+------+-----+
+//
+typedef	enum	_WpaMixPairCipher
+{
+	MIX_CIPHER_NOTUSE 			= 0x00,
+	WPA_NONE_WPA2_TKIPAES		= 0x03,		// WPA2-TKIPAES
+	WPA_AES_WPA2_TKIP 			= 0x06,
+	WPA_AES_WPA2_TKIPAES		= 0x07,
+	WPA_TKIP_WPA2_AES			= 0x09,
+	WPA_TKIP_WPA2_TKIPAES		= 0x0B,
+	WPA_TKIPAES_WPA2_NONE		= 0x0C,		// WPA-TKIPAES
+	WPA_TKIPAES_WPA2_AES		= 0x0D,
+	WPA_TKIPAES_WPA2_TKIP		= 0x0E,
+	WPA_TKIPAES_WPA2_TKIPAES	= 0x0F,
+}	WPA_MIX_PAIR_CIPHER;
+
+typedef struct PACKED _RSN_IE_HEADER_STRUCT	{
+	UCHAR		Eid;
+	UCHAR		Length;
+	USHORT		Version;	// Little endian format
+}	RSN_IE_HEADER_STRUCT, *PRSN_IE_HEADER_STRUCT;
+
+// Cipher suite selector types
+typedef struct PACKED _CIPHER_SUITE_STRUCT	{
+	UCHAR		Oui[3];
+	UCHAR		Type;
+}	CIPHER_SUITE_STRUCT, *PCIPHER_SUITE_STRUCT;
+
+// Authentication and Key Management suite selector
+typedef struct PACKED _AKM_SUITE_STRUCT	{
+	UCHAR		Oui[3];
+	UCHAR		Type;
+}	AKM_SUITE_STRUCT, *PAKM_SUITE_STRUCT;
+
+// RSN capability
+typedef struct	PACKED _RSN_CAPABILITY	{
+	USHORT		Rsv:10;
+	USHORT		GTKSAReplayCnt:2;
+	USHORT		PTKSAReplayCnt:2;
+	USHORT		NoPairwise:1;
+	USHORT		PreAuth:1;
+}	RSN_CAPABILITY, *PRSN_CAPABILITY;
+
+#endif
diff --git a/drivers/staging/rtl8187se/dot11d.h b/drivers/staging/rtl8187se/dot11d.h
index 49f53fe..2417da9 100644
--- a/drivers/staging/rtl8187se/dot11d.h
+++ b/drivers/staging/rtl8187se/dot11d.h
@@ -1,101 +1,101 @@
-#ifndef __INC_DOT11D_H

-#define __INC_DOT11D_H

-

-#include "ieee80211.h"

-

-//#define ENABLE_DOT11D

-

-//#define DOT11D_MAX_CHNL_NUM 83

-

-typedef struct _CHNL_TXPOWER_TRIPLE {

-	u8 FirstChnl;

-	u8  NumChnls;

-	u8  MaxTxPowerInDbm;

-}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;

-

-typedef enum _DOT11D_STATE {

-	DOT11D_STATE_NONE = 0,

-	DOT11D_STATE_LEARNED,

-	DOT11D_STATE_DONE,

-}DOT11D_STATE;

-

-typedef struct _RT_DOT11D_INFO {

-	//DECLARE_RT_OBJECT(RT_DOT11D_INFO);

-

-	bool bEnabled; // dot11MultiDomainCapabilityEnabled

-

-	u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.

-	u8  CountryIeBuf[MAX_IE_LEN];

-	u8  CountryIeSrcAddr[6]; // Source AP of the country IE.

-	u8  CountryIeWatchdog; 

-

-	u8  channel_map[MAX_CHANNEL_NUMBER+1];  //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)

-	//u8  ChnlListLen; // #Bytes valid in ChnlList[].

-	//u8  ChnlList[DOT11D_MAX_CHNL_NUM];

-	u8  MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];

-

-	DOT11D_STATE State;

-}RT_DOT11D_INFO, *PRT_DOT11D_INFO;

-#define eqMacAddr(a,b)		( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )

-#define cpMacAddr(des,src)	      ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])

-#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))

-

-#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled

-#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)

-

-#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) 

-#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)

-

-#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \

-	(((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \

-	FALSE : \

-	(!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))

-

-#define CIE_WATCHDOG_TH 1

-#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog

-#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0 

-#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)

-

-#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)

-

-

-void

-Dot11d_Init(

-	struct ieee80211_device *dev

-	);

-

-void

-Dot11d_Reset(

-	struct ieee80211_device *dev

-	);

-

-void

-Dot11d_UpdateCountryIe(

-	struct ieee80211_device *dev,

-	u8 *		pTaddr,

-	u16	CoutryIeLen,

-	u8 * pCoutryIe	 

-	);

-

-u8

-DOT11D_GetMaxTxPwrInDbm(

-	struct ieee80211_device *dev,

-	u8 Channel

-	);

-

-void

-DOT11D_ScanComplete(

-	struct ieee80211_device * dev

-	);

-

-int IsLegalChannel(

-	struct ieee80211_device * dev,

-	u8 channel

-);

-

-int ToLegalChannel(

-	struct ieee80211_device * dev,

-	u8 channel

-);

-

-#endif // #ifndef __INC_DOT11D_H

+#ifndef __INC_DOT11D_H
+#define __INC_DOT11D_H
+
+#include "ieee80211.h"
+
+//#define ENABLE_DOT11D
+
+//#define DOT11D_MAX_CHNL_NUM 83
+
+typedef struct _CHNL_TXPOWER_TRIPLE {
+	u8 FirstChnl;
+	u8  NumChnls;
+	u8  MaxTxPowerInDbm;
+}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
+
+typedef enum _DOT11D_STATE {
+	DOT11D_STATE_NONE = 0,
+	DOT11D_STATE_LEARNED,
+	DOT11D_STATE_DONE,
+}DOT11D_STATE;
+
+typedef struct _RT_DOT11D_INFO {
+	//DECLARE_RT_OBJECT(RT_DOT11D_INFO);
+
+	bool bEnabled; // dot11MultiDomainCapabilityEnabled
+
+	u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
+	u8  CountryIeBuf[MAX_IE_LEN];
+	u8  CountryIeSrcAddr[6]; // Source AP of the country IE.
+	u8  CountryIeWatchdog;
+
+	u8  channel_map[MAX_CHANNEL_NUMBER+1];  //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
+	//u8  ChnlListLen; // #Bytes valid in ChnlList[].
+	//u8  ChnlList[DOT11D_MAX_CHNL_NUM];
+	u8  MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
+
+	DOT11D_STATE State;
+}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
+#define eqMacAddr(a,b)		( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
+#define cpMacAddr(des,src)	      ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
+#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
+
+#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
+#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
+
+#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
+#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
+
+#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
+	(((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
+	FALSE : \
+	(!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
+
+#define CIE_WATCHDOG_TH 1
+#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
+#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
+#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
+
+#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
+
+
+void
+Dot11d_Init(
+	struct ieee80211_device *dev
+	);
+
+void
+Dot11d_Reset(
+	struct ieee80211_device *dev
+	);
+
+void
+Dot11d_UpdateCountryIe(
+	struct ieee80211_device *dev,
+	u8 *		pTaddr,
+	u16	CoutryIeLen,
+	u8 * pCoutryIe
+	);
+
+u8
+DOT11D_GetMaxTxPwrInDbm(
+	struct ieee80211_device *dev,
+	u8 Channel
+	);
+
+void
+DOT11D_ScanComplete(
+	struct ieee80211_device * dev
+	);
+
+int IsLegalChannel(
+	struct ieee80211_device * dev,
+	u8 channel
+);
+
+int ToLegalChannel(
+	struct ieee80211_device * dev,
+	u8 channel
+);
+
+#endif // #ifndef __INC_DOT11D_H
diff --git a/drivers/staging/rtl8187se/ieee80211/dot11d.c b/drivers/staging/rtl8187se/ieee80211/dot11d.c
index 5d8b752f..54bcdcf 100644
--- a/drivers/staging/rtl8187se/ieee80211/dot11d.c
+++ b/drivers/staging/rtl8187se/ieee80211/dot11d.c
@@ -1,246 +1,246 @@
-#ifdef ENABLE_DOT11D

-//-----------------------------------------------------------------------------

-//	File:

-//		Dot11d.c

-//

-//	Description:

-//		Implement 802.11d. 

-//

-//-----------------------------------------------------------------------------

-

-#include "dot11d.h"

-

-void

-Dot11d_Init(struct ieee80211_device *ieee)

-{

-	PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);

-

-	pDot11dInfo->bEnabled = 0;

-

-	pDot11dInfo->State = DOT11D_STATE_NONE;

-	pDot11dInfo->CountryIeLen = 0;

-	memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);  

-	memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);

-	RESET_CIE_WATCHDOG(ieee);

-

-	printk("Dot11d_Init()\n");

-}

-

-//

-//	Description:

-//		Reset to the state as we are just entering a regulatory domain.

-//

-void

-Dot11d_Reset(struct ieee80211_device *ieee)

-{

-	u32 i;

-	PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);

-

-	// Clear old channel map

-	memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);

-	memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);

-	// Set new channel map

-	for (i=1; i<=11; i++) {

-		(pDot11dInfo->channel_map)[i] = 1;

-	}

-	for (i=12; i<=14; i++) {

-		(pDot11dInfo->channel_map)[i] = 2;

-	}

-

-	pDot11dInfo->State = DOT11D_STATE_NONE;

-	pDot11dInfo->CountryIeLen = 0;

-	RESET_CIE_WATCHDOG(ieee);

-

-	//printk("Dot11d_Reset()\n");

-}

-

-//

-//	Description:

-//		Update country IE from Beacon or Probe Resopnse 

-//		and configure PHY for operation in the regulatory domain.

-//

-//	TODO: 

-//		Configure Tx power.

-//

-//	Assumption:

-//		1. IS_DOT11D_ENABLE() is TRUE.

-//		2. Input IE is an valid one.

-//

-void

-Dot11d_UpdateCountryIe(

-	struct ieee80211_device *dev,

-	u8 *		pTaddr,

-	u16	CoutryIeLen,

-	u8 * pCoutryIe	 

-	)

-{

-	PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);

-	u8 i, j, NumTriples, MaxChnlNum;

-	PCHNL_TXPOWER_TRIPLE pTriple;

-

-	if((CoutryIeLen - 3)%3 != 0)

-	{

-		printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");

-		Dot11d_Reset(dev);

-		return;

-	}

-

-	memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);

-	memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);

-	MaxChnlNum = 0;

-	NumTriples = (CoutryIeLen - 3) / 3; // skip 3-byte country string.

-	pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3);

-	for(i = 0; i < NumTriples; i++)

-	{

-		if(MaxChnlNum >= pTriple->FirstChnl)

-		{ // It is not in a monotonically increasing order, so stop processing.

-			printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");

-			Dot11d_Reset(dev);

-			return; 

-		}

-		if(MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + pTriple->NumChnls))

-		{ // It is not a valid set of channel id, so stop processing.

-			printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");

-			Dot11d_Reset(dev);

-			return; 

-		}

-

-		for(j = 0 ; j < pTriple->NumChnls; j++)

-		{

-			pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1;

-			pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = pTriple->MaxTxPowerInDbm;

-			MaxChnlNum = pTriple->FirstChnl + j;

-		}	

-

-		pTriple = (PCHNL_TXPOWER_TRIPLE)((u8*)pTriple + 3);

-	}

-#if 1

-	//printk("Dot11d_UpdateCountryIe(): Channel List:\n");

-	printk("Channel List:");

-	for(i=1; i<= MAX_CHANNEL_NUMBER; i++)

-		if(pDot11dInfo->channel_map[i] > 0)

-			printk(" %d", i);

-	printk("\n");

-#endif

-

-	UPDATE_CIE_SRC(dev, pTaddr);

-

-	pDot11dInfo->CountryIeLen = CoutryIeLen;

-	memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe,CoutryIeLen);

-	pDot11dInfo->State = DOT11D_STATE_LEARNED;

-}

-

-void dump_chnl_map(u8 * channel_map)

-{

-	int i;

-	printk("Channel List:");

-	for(i=1; i<= MAX_CHANNEL_NUMBER; i++)

-		if(channel_map[i] > 0)

-			printk(" %d(%d)", i, channel_map[i]);

-	printk("\n");

-}

-

-u8

-DOT11D_GetMaxTxPwrInDbm(

-	struct ieee80211_device *dev,

-	u8 Channel

-	)

-{

-	PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);

-	u8 MaxTxPwrInDbm = 255;

-

-	if(MAX_CHANNEL_NUMBER < Channel)

-	{ 

-		printk("DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");

-		return MaxTxPwrInDbm; 

-	}

-	if(pDot11dInfo->channel_map[Channel])

-	{

-		MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel];	

-	}

-

-	return MaxTxPwrInDbm;

-}

-

-

-void

-DOT11D_ScanComplete(

-	struct ieee80211_device * dev

-	)

-{

-	PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);

-

-	switch(pDot11dInfo->State)

-	{

-	case DOT11D_STATE_LEARNED:

-		pDot11dInfo->State = DOT11D_STATE_DONE;

-		break;

-

-	case DOT11D_STATE_DONE:

-		if( GET_CIE_WATCHDOG(dev) == 0 )

-		{ // Reset country IE if previous one is gone. 

-			Dot11d_Reset(dev); 

-		}

-		break;

-	case DOT11D_STATE_NONE:

-		break;

-	}

-}

-

-int IsLegalChannel(

-	struct ieee80211_device * dev,

-	u8 channel

-)

-{

-	PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);

-

-	if(MAX_CHANNEL_NUMBER < channel)

-	{ 

-		printk("IsLegalChannel(): Invalid Channel\n");

-		return 0; 

-	}

-	if(pDot11dInfo->channel_map[channel] > 0)

-		return 1;

-	return 0;

-}

-

-int ToLegalChannel(

-	struct ieee80211_device * dev,

-	u8 channel

-)

-{

-	PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);

-	u8 default_chn = 0;

-	u32 i = 0;

-

-	for (i=1; i<= MAX_CHANNEL_NUMBER; i++)

-	{

-		if(pDot11dInfo->channel_map[i] > 0)

-		{

-			default_chn = i;

-			break;

-		}

-	}

-

-	if(MAX_CHANNEL_NUMBER < channel)

-	{ 

-		printk("IsLegalChannel(): Invalid Channel\n");

-		return default_chn; 

-	}

-	

-	if(pDot11dInfo->channel_map[channel] > 0)

-		return channel;

-	

-	return default_chn;

-}

-

-#if 0

-EXPORT_SYMBOL(Dot11d_Init);

-EXPORT_SYMBOL(Dot11d_Reset);

-EXPORT_SYMBOL(Dot11d_UpdateCountryIe);

-EXPORT_SYMBOL(DOT11D_GetMaxTxPwrInDbm);

-EXPORT_SYMBOL(DOT11D_ScanComplete);

-EXPORT_SYMBOL(IsLegalChannel);

-EXPORT_SYMBOL(ToLegalChannel);

-#endif

-#endif

+#ifdef ENABLE_DOT11D
+//-----------------------------------------------------------------------------
+//	File:
+//		Dot11d.c
+//
+//	Description:
+//		Implement 802.11d.
+//
+//-----------------------------------------------------------------------------
+
+#include "dot11d.h"
+
+void
+Dot11d_Init(struct ieee80211_device *ieee)
+{
+	PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
+
+	pDot11dInfo->bEnabled = 0;
+
+	pDot11dInfo->State = DOT11D_STATE_NONE;
+	pDot11dInfo->CountryIeLen = 0;
+	memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
+	memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
+	RESET_CIE_WATCHDOG(ieee);
+
+	printk("Dot11d_Init()\n");
+}
+
+//
+//	Description:
+//		Reset to the state as we are just entering a regulatory domain.
+//
+void
+Dot11d_Reset(struct ieee80211_device *ieee)
+{
+	u32 i;
+	PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
+
+	// Clear old channel map
+	memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
+	memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
+	// Set new channel map
+	for (i=1; i<=11; i++) {
+		(pDot11dInfo->channel_map)[i] = 1;
+	}
+	for (i=12; i<=14; i++) {
+		(pDot11dInfo->channel_map)[i] = 2;
+	}
+
+	pDot11dInfo->State = DOT11D_STATE_NONE;
+	pDot11dInfo->CountryIeLen = 0;
+	RESET_CIE_WATCHDOG(ieee);
+
+	//printk("Dot11d_Reset()\n");
+}
+
+//
+//	Description:
+//		Update country IE from Beacon or Probe Resopnse
+//		and configure PHY for operation in the regulatory domain.
+//
+//	TODO:
+//		Configure Tx power.
+//
+//	Assumption:
+//		1. IS_DOT11D_ENABLE() is TRUE.
+//		2. Input IE is an valid one.
+//
+void
+Dot11d_UpdateCountryIe(
+	struct ieee80211_device *dev,
+	u8 *		pTaddr,
+	u16	CoutryIeLen,
+	u8 * pCoutryIe
+	)
+{
+	PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
+	u8 i, j, NumTriples, MaxChnlNum;
+	PCHNL_TXPOWER_TRIPLE pTriple;
+
+	if((CoutryIeLen - 3)%3 != 0)
+	{
+		printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
+		Dot11d_Reset(dev);
+		return;
+	}
+
+	memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
+	memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
+	MaxChnlNum = 0;
+	NumTriples = (CoutryIeLen - 3) / 3; // skip 3-byte country string.
+	pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3);
+	for(i = 0; i < NumTriples; i++)
+	{
+		if(MaxChnlNum >= pTriple->FirstChnl)
+		{ // It is not in a monotonically increasing order, so stop processing.
+			printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
+			Dot11d_Reset(dev);
+			return;
+		}
+		if(MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + pTriple->NumChnls))
+		{ // It is not a valid set of channel id, so stop processing.
+			printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");
+			Dot11d_Reset(dev);
+			return;
+		}
+
+		for(j = 0 ; j < pTriple->NumChnls; j++)
+		{
+			pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1;
+			pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = pTriple->MaxTxPowerInDbm;
+			MaxChnlNum = pTriple->FirstChnl + j;
+		}
+
+		pTriple = (PCHNL_TXPOWER_TRIPLE)((u8*)pTriple + 3);
+	}
+#if 1
+	//printk("Dot11d_UpdateCountryIe(): Channel List:\n");
+	printk("Channel List:");
+	for(i=1; i<= MAX_CHANNEL_NUMBER; i++)
+		if(pDot11dInfo->channel_map[i] > 0)
+			printk(" %d", i);
+	printk("\n");
+#endif
+
+	UPDATE_CIE_SRC(dev, pTaddr);
+
+	pDot11dInfo->CountryIeLen = CoutryIeLen;
+	memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe,CoutryIeLen);
+	pDot11dInfo->State = DOT11D_STATE_LEARNED;
+}
+
+void dump_chnl_map(u8 * channel_map)
+{
+	int i;
+	printk("Channel List:");
+	for(i=1; i<= MAX_CHANNEL_NUMBER; i++)
+		if(channel_map[i] > 0)
+			printk(" %d(%d)", i, channel_map[i]);
+	printk("\n");
+}
+
+u8
+DOT11D_GetMaxTxPwrInDbm(
+	struct ieee80211_device *dev,
+	u8 Channel
+	)
+{
+	PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
+	u8 MaxTxPwrInDbm = 255;
+
+	if(MAX_CHANNEL_NUMBER < Channel)
+	{
+		printk("DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");
+		return MaxTxPwrInDbm;
+	}
+	if(pDot11dInfo->channel_map[Channel])
+	{
+		MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel];
+	}
+
+	return MaxTxPwrInDbm;
+}
+
+
+void
+DOT11D_ScanComplete(
+	struct ieee80211_device * dev
+	)
+{
+	PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
+
+	switch(pDot11dInfo->State)
+	{
+	case DOT11D_STATE_LEARNED:
+		pDot11dInfo->State = DOT11D_STATE_DONE;
+		break;
+
+	case DOT11D_STATE_DONE:
+		if( GET_CIE_WATCHDOG(dev) == 0 )
+		{ // Reset country IE if previous one is gone.
+			Dot11d_Reset(dev);
+		}
+		break;
+	case DOT11D_STATE_NONE:
+		break;
+	}
+}
+
+int IsLegalChannel(
+	struct ieee80211_device * dev,
+	u8 channel
+)
+{
+	PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
+
+	if(MAX_CHANNEL_NUMBER < channel)
+	{
+		printk("IsLegalChannel(): Invalid Channel\n");
+		return 0;
+	}
+	if(pDot11dInfo->channel_map[channel] > 0)
+		return 1;
+	return 0;
+}
+
+int ToLegalChannel(
+	struct ieee80211_device * dev,
+	u8 channel
+)
+{
+	PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
+	u8 default_chn = 0;
+	u32 i = 0;
+
+	for (i=1; i<= MAX_CHANNEL_NUMBER; i++)
+	{
+		if(pDot11dInfo->channel_map[i] > 0)
+		{
+			default_chn = i;
+			break;
+		}
+	}
+
+	if(MAX_CHANNEL_NUMBER < channel)
+	{
+		printk("IsLegalChannel(): Invalid Channel\n");
+		return default_chn;
+	}
+
+	if(pDot11dInfo->channel_map[channel] > 0)
+		return channel;
+
+	return default_chn;
+}
+
+#if 0
+EXPORT_SYMBOL(Dot11d_Init);
+EXPORT_SYMBOL(Dot11d_Reset);
+EXPORT_SYMBOL(Dot11d_UpdateCountryIe);
+EXPORT_SYMBOL(DOT11D_GetMaxTxPwrInDbm);
+EXPORT_SYMBOL(DOT11D_ScanComplete);
+EXPORT_SYMBOL(IsLegalChannel);
+EXPORT_SYMBOL(ToLegalChannel);
+#endif
+#endif
diff --git a/drivers/staging/rtl8187se/ieee80211/dot11d.h b/drivers/staging/rtl8187se/ieee80211/dot11d.h
index 64bcf15..82576b5 100644
--- a/drivers/staging/rtl8187se/ieee80211/dot11d.h
+++ b/drivers/staging/rtl8187se/ieee80211/dot11d.h
@@ -1,102 +1,102 @@
-#ifndef __INC_DOT11D_H

-#define __INC_DOT11D_H

-

-#include "ieee80211.h"

-

-//#define ENABLE_DOT11D

-

-//#define DOT11D_MAX_CHNL_NUM 83

-

-typedef struct _CHNL_TXPOWER_TRIPLE {

-	u8 FirstChnl;

-	u8  NumChnls;

-	u8  MaxTxPowerInDbm;

-}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;

-

-typedef enum _DOT11D_STATE {

-	DOT11D_STATE_NONE = 0,

-	DOT11D_STATE_LEARNED,

-	DOT11D_STATE_DONE,

-}DOT11D_STATE;

-

-typedef struct _RT_DOT11D_INFO {

-	//DECLARE_RT_OBJECT(RT_DOT11D_INFO);

-

-	bool bEnabled; // dot11MultiDomainCapabilityEnabled

-

-	u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.

-	u8  CountryIeBuf[MAX_IE_LEN];

-	u8  CountryIeSrcAddr[6]; // Source AP of the country IE.

-	u8  CountryIeWatchdog; 

-

-	u8  channel_map[MAX_CHANNEL_NUMBER+1];  //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)

-	//u8  ChnlListLen; // #Bytes valid in ChnlList[].

-	//u8  ChnlList[DOT11D_MAX_CHNL_NUM];

-	u8  MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];

-

-	DOT11D_STATE State;

-}RT_DOT11D_INFO, *PRT_DOT11D_INFO;

-#define eqMacAddr(a,b)		( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )

-#define cpMacAddr(des,src)	      ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])

-#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))

-

-#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled

-#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)

-

-#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) 

-#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)

-

-#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \

-	(((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \

-	FALSE : \

-	(!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))

-

-#define CIE_WATCHDOG_TH 1

-#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog

-#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0 

-#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)

-

-#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)

-

-

-void

-Dot11d_Init(

-	struct ieee80211_device *dev

-	);

-

-void

-Dot11d_Reset(

-	struct ieee80211_device *dev

-	);

-

-void

-Dot11d_UpdateCountryIe(

-	struct ieee80211_device *dev,

-	u8 *		pTaddr,

-	u16	CoutryIeLen,

-	u8 * pCoutryIe	 

-	);

-

-u8

-DOT11D_GetMaxTxPwrInDbm(

-	struct ieee80211_device *dev,

-	u8 Channel

-	);

-

-void

-DOT11D_ScanComplete(

-	struct ieee80211_device * dev

-	);

-

-int IsLegalChannel(

-	struct ieee80211_device * dev,

-	u8 channel

-);

-

-int ToLegalChannel(

-	struct ieee80211_device * dev,

-	u8 channel

-);

-

-void dump_chnl_map(u8 * channel_map);

-#endif // #ifndef __INC_DOT11D_H

+#ifndef __INC_DOT11D_H
+#define __INC_DOT11D_H
+
+#include "ieee80211.h"
+
+//#define ENABLE_DOT11D
+
+//#define DOT11D_MAX_CHNL_NUM 83
+
+typedef struct _CHNL_TXPOWER_TRIPLE {
+	u8 FirstChnl;
+	u8  NumChnls;
+	u8  MaxTxPowerInDbm;
+}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
+
+typedef enum _DOT11D_STATE {
+	DOT11D_STATE_NONE = 0,
+	DOT11D_STATE_LEARNED,
+	DOT11D_STATE_DONE,
+}DOT11D_STATE;
+
+typedef struct _RT_DOT11D_INFO {
+	//DECLARE_RT_OBJECT(RT_DOT11D_INFO);
+
+	bool bEnabled; // dot11MultiDomainCapabilityEnabled
+
+	u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
+	u8  CountryIeBuf[MAX_IE_LEN];
+	u8  CountryIeSrcAddr[6]; // Source AP of the country IE.
+	u8  CountryIeWatchdog;
+
+	u8  channel_map[MAX_CHANNEL_NUMBER+1];  //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
+	//u8  ChnlListLen; // #Bytes valid in ChnlList[].
+	//u8  ChnlList[DOT11D_MAX_CHNL_NUM];
+	u8  MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
+
+	DOT11D_STATE State;
+}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
+#define eqMacAddr(a,b)		( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
+#define cpMacAddr(des,src)	      ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
+#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
+
+#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
+#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
+
+#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
+#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
+
+#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
+	(((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
+	FALSE : \
+	(!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
+
+#define CIE_WATCHDOG_TH 1
+#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
+#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
+#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
+
+#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
+
+
+void
+Dot11d_Init(
+	struct ieee80211_device *dev
+	);
+
+void
+Dot11d_Reset(
+	struct ieee80211_device *dev
+	);
+
+void
+Dot11d_UpdateCountryIe(
+	struct ieee80211_device *dev,
+	u8 *		pTaddr,
+	u16	CoutryIeLen,
+	u8 * pCoutryIe
+	);
+
+u8
+DOT11D_GetMaxTxPwrInDbm(
+	struct ieee80211_device *dev,
+	u8 Channel
+	);
+
+void
+DOT11D_ScanComplete(
+	struct ieee80211_device * dev
+	);
+
+int IsLegalChannel(
+	struct ieee80211_device * dev,
+	u8 channel
+);
+
+int ToLegalChannel(
+	struct ieee80211_device * dev,
+	u8 channel
+);
+
+void dump_chnl_map(u8 * channel_map);
+#endif // #ifndef __INC_DOT11D_H
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
index 6aad61e..d1295e5 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
@@ -842,14 +842,14 @@
 
 	if (len>MAX_WPA_IE_LEN || (len && ie == NULL))
 	{
-		printk("return error out, len:%d\n", len);
+		printk("return error out, len:%zu\n", len);
 	return -EINVAL;
 	}
 
 	if (len)
 	{
 		if (len != ie[1]+2){
-			printk("len:%d, ie:%d\n", len, ie[1]);
+			printk("len:%zu, ie:%d\n", len, ie[1]);
 			return -EINVAL;
 		}
 		buf = kmalloc(len, GFP_KERNEL);
diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c
index ff1f23f..6ecd12d 100644
--- a/drivers/staging/rtl8187se/r8180_core.c
+++ b/drivers/staging/rtl8187se/r8180_core.c
@@ -3161,7 +3161,7 @@
 		return ;
 
 	}
-	//while(! *tail & (1<<31)){
+	//while(! (*tail & (1<<31))){
 		*tail= 0; // zeroes header
 
 		*tail = *tail| (1<<29) ; //fist segment of the packet
diff --git a/drivers/staging/rtl8187se/r8180_dm.c b/drivers/staging/rtl8187se/r8180_dm.c
index 742dc11..93b5a7b 100644
--- a/drivers/staging/rtl8187se/r8180_dm.c
+++ b/drivers/staging/rtl8187se/r8180_dm.c
@@ -1,1725 +1,1725 @@
-//#include "r8180.h"

-#include "r8180_dm.h"

-#include "r8180_hw.h"

-#include "r8180_93cx6.h"

-//{by amy 080312

-

-//

-//	Description:

-//		Return TRUE if we shall perform High Power Mecahnism, FALSE otherwise.	

-//

-//+by amy 080312

-#define RATE_ADAPTIVE_TIMER_PERIOD      300

-

-bool CheckHighPower(struct net_device *dev)

-{

-	struct r8180_priv *priv = ieee80211_priv(dev);

-	struct ieee80211_device *ieee = priv->ieee80211;

-

-	if(!priv->bRegHighPowerMechanism)

-	{

-		return false;

-	}

-		

-	if(ieee->state == IEEE80211_LINKED_SCANNING)

-	{

-		return false;

-	}

-

-	return true;

-}

-

-//

-//	Description:

-//		Update Tx power level if necessary.

-//		See also DoRxHighPower() and SetTxPowerLevel8185() for reference.

-//

-//	Note:

-//		The reason why we udpate Tx power level here instead of DoRxHighPower() 

-//		is the number of IO to change Tx power is much more than chane TR switch 

-//		and they are related to OFDM and MAC registers. 

-//		So, we don't want to update it so frequently in per-Rx packet base. 

-//

-void

-DoTxHighPower(

-	struct net_device *dev

-	)

-{

-	struct r8180_priv *priv = ieee80211_priv(dev);

-	u16			HiPwrUpperTh = 0;

-	u16			HiPwrLowerTh = 0;

-	u8			RSSIHiPwrUpperTh;

-	u8			RSSIHiPwrLowerTh;

-	u8			u1bTmp;

-	char			OfdmTxPwrIdx, CckTxPwrIdx;

-

-	//printk("----> DoTxHighPower()\n");

-

-	HiPwrUpperTh = priv->RegHiPwrUpperTh;

-	HiPwrLowerTh = priv->RegHiPwrLowerTh;						

-	

-	HiPwrUpperTh = HiPwrUpperTh * 10;

-	HiPwrLowerTh = HiPwrLowerTh * 10;

-	RSSIHiPwrUpperTh = priv->RegRSSIHiPwrUpperTh;

-	RSSIHiPwrLowerTh = priv->RegRSSIHiPwrLowerTh;

-

-	//lzm add 080826

-	OfdmTxPwrIdx  = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel]; 

-	CckTxPwrIdx  = priv->chtxpwr[priv->ieee80211->current_network.channel]; 

-

-	//	printk("DoTxHighPower() - UndecoratedSmoothedSS:%d, CurCCKRSSI = %d , bCurCCKPkt= %d \n", priv->UndecoratedSmoothedSS, priv->CurCCKRSSI, priv->bCurCCKPkt );

-	

-	if((priv->UndecoratedSmoothedSS > HiPwrUpperTh) ||

-		(priv->bCurCCKPkt && (priv->CurCCKRSSI > RSSIHiPwrUpperTh)))

-	{

-		// Stevenl suggested that degrade 8dbm in high power sate. 2007-12-04 Isaiah 

-		

-	//	printk("=====>DoTxHighPower() - High Power - UndecoratedSmoothedSS:%d,  HiPwrUpperTh = %d \n", priv->UndecoratedSmoothedSS, HiPwrUpperTh );

-		priv->bToUpdateTxPwr = true;

-		u1bTmp= read_nic_byte(dev, CCK_TXAGC);

-

-		// If it never enter High Power.

-		if( CckTxPwrIdx == u1bTmp)

-		{

-		u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0;  // 8dbm

-		write_nic_byte(dev, CCK_TXAGC, u1bTmp);

-

-		u1bTmp= read_nic_byte(dev, OFDM_TXAGC);

-		u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0;  // 8dbm

-		write_nic_byte(dev, OFDM_TXAGC, u1bTmp);

-		}

-		

-	}

-	else if((priv->UndecoratedSmoothedSS < HiPwrLowerTh) &&

-		(!priv->bCurCCKPkt || priv->CurCCKRSSI < RSSIHiPwrLowerTh))

-	{

-	//	 printk("DoTxHighPower() - lower Power - UndecoratedSmoothedSS:%d,  HiPwrUpperTh = %d \n", priv->UndecoratedSmoothedSS, HiPwrLowerTh );

-		if(priv->bToUpdateTxPwr)

-		{

-			priv->bToUpdateTxPwr = false;

-			//SD3 required.

-			u1bTmp= read_nic_byte(dev, CCK_TXAGC);			

-			if(u1bTmp < CckTxPwrIdx)

-			{

-			//u1bTmp = ((u1bTmp+16) > 35) ? 35: (u1bTmp+16);  // 8dbm

-			//write_nic_byte(dev, CCK_TXAGC, u1bTmp);

-			write_nic_byte(dev, CCK_TXAGC, CckTxPwrIdx);

-			}

-

-			u1bTmp= read_nic_byte(dev, OFDM_TXAGC);

-			if(u1bTmp < OfdmTxPwrIdx)

-			{

-			//u1bTmp = ((u1bTmp+16) > 35) ? 35: (u1bTmp+16);  // 8dbm

-			//write_nic_byte(dev, OFDM_TXAGC, u1bTmp);

-			write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);

-			}

-		}

-	}

-

-	//printk("<---- DoTxHighPower()\n");

-}

-

-

-//

-//	Description:

-//		Callback function of UpdateTxPowerWorkItem.

-//		Because of some event happend, e.g. CCX TPC, High Power Mechanism, 

-//		We update Tx power of current channel again. 

-//

-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))

-void rtl8180_tx_pw_wq (struct work_struct *work)

-{

-//      struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);

-//      struct ieee80211_device * ieee = (struct ieee80211_device*)

-//                                             container_of(work, struct ieee80211_device, watch_dog_wq);

-        struct delayed_work *dwork = container_of(work,struct delayed_work,work);

-        struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,tx_pw_wq);

-        struct net_device *dev = ieee->dev;

-#else

-void rtl8180_tx_pw_wq(struct net_device *dev)

-{

-	// struct r8180_priv *priv = ieee80211_priv(dev);

-#endif

-

-//	printk("----> UpdateTxPowerWorkItemCallback()\n");

-	

-	DoTxHighPower(dev);	

-	

-//	printk("<---- UpdateTxPowerWorkItemCallback()\n");

-}

-

-

-//

-//	Description:

-//		Return TRUE if we shall perform DIG Mecahnism, FALSE otherwise.	

-//

-bool

-CheckDig(

-	struct net_device *dev

-	)

-{

-	struct r8180_priv *priv = ieee80211_priv(dev);

-	struct ieee80211_device *ieee = priv->ieee80211;

-

-	if(!priv->bDigMechanism)

-		return false;

-

-	if(ieee->state != IEEE80211_LINKED)

-		return false;

-

-	//if(priv->CurrentOperaRate < 36) // Schedule Dig under all OFDM rates. By Bruce, 2007-06-01.

-	if((priv->ieee80211->rate/5) < 36) // Schedule Dig under all OFDM rates. By Bruce, 2007-06-01.

-		return false;

-	return true;

-}

-//

-//	Description:

-//		Implementation of DIG for Zebra and Zebra2.	

-//

-void

-DIG_Zebra(

-	struct net_device *dev

-	)

-{

-	struct r8180_priv *priv = ieee80211_priv(dev);

-	u16			CCKFalseAlarm, OFDMFalseAlarm;

-	u16			OfdmFA1, OfdmFA2;

-	int			InitialGainStep = 7; // The number of initial gain stages.

-	int			LowestGainStage = 4; // The capable lowest stage of performing dig workitem.

-	u32 			AwakePeriodIn2Sec=0;

-

-	//printk("---------> DIG_Zebra()\n");

-

-	CCKFalseAlarm = (u16)(priv->FalseAlarmRegValue & 0x0000ffff);

-	OFDMFalseAlarm = (u16)((priv->FalseAlarmRegValue >> 16) & 0x0000ffff);

-	OfdmFA1 =  0x15;

-	OfdmFA2 = ((u16)(priv->RegDigOfdmFaUpTh)) << 8;

-

-//	printk("DIG**********CCK False Alarm: %#X \n",CCKFalseAlarm);

-//	printk("DIG**********OFDM False Alarm: %#X \n",OFDMFalseAlarm);

-

-        // The number of initial gain steps is different, by Bruce, 2007-04-13.

-	if (priv->InitialGain == 0 ) //autoDIG

-	{ // Advised from SD3 DZ

-		priv->InitialGain = 4; // In 87B, m74dBm means State 4 (m82dBm)

-	}

-	//if(pHalData->VersionID != VERSION_8187B_B)

-	{ // Advised from SD3 DZ

-		OfdmFA1 =  0x20;

-	}

-	

-#if 1 //lzm reserved 080826

-	AwakePeriodIn2Sec = (2000-priv ->DozePeriodInPast2Sec);

-	//printk("&&& DozePeriod=%d AwakePeriod=%d\n", priv->DozePeriodInPast2Sec, AwakePeriodIn2Sec);

-	priv ->DozePeriodInPast2Sec=0;

-	

-	if(AwakePeriodIn2Sec)

-	{	

-		//RT_TRACE(COMP_DIG, DBG_TRACE, ("DIG: AwakePeriodIn2Sec(%d) - FATh(0x%X , 0x%X) ->",AwakePeriodIn2Sec, OfdmFA1, OfdmFA2));

-		// adjuest DIG threshold.

-		OfdmFA1 =  (u16)((OfdmFA1*AwakePeriodIn2Sec)  / 2000) ;  	

-		OfdmFA2 =  (u16)((OfdmFA2*AwakePeriodIn2Sec)  / 2000) ;

-		//RT_TRACE(COMP_DIG, DBG_TRACE, ("( 0x%X , 0x%X)\n", OfdmFA1, OfdmFA2));

-	}

-	else

-	{

-		;//RT_TRACE(COMP_DIG, DBG_WARNING, ("ERROR!!  AwakePeriodIn2Sec should not be ZERO!!\n"));

-	}

-#endif

-

-	InitialGainStep = 8;

-	LowestGainStage = priv->RegBModeGainStage; // Lowest gain stage.

-

-	if (OFDMFalseAlarm > OfdmFA1)

-	{

-		if (OFDMFalseAlarm > OfdmFA2)

-		{

-			priv->DIG_NumberFallbackVote++;

-			if (priv->DIG_NumberFallbackVote >1)

-			{

-				//serious OFDM  False Alarm, need fallback

-				if (priv->InitialGain < InitialGainStep)

-				{

-					priv->InitialGainBackUp= priv->InitialGain;

-

-					priv->InitialGain = (priv->InitialGain + 1);

-//					printk("DIG**********OFDM False Alarm: %#X,  OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);

-//					printk("DIG+++++++ fallback OFDM:%d \n", priv->InitialGain);

-					UpdateInitialGain(dev); 

-				}

-				priv->DIG_NumberFallbackVote = 0;

-				priv->DIG_NumberUpgradeVote=0;

-			}

-		}

-		else

-		{

-			if (priv->DIG_NumberFallbackVote)

-				priv->DIG_NumberFallbackVote--;

-		}

-		priv->DIG_NumberUpgradeVote=0;		

-	}

-	else	

-	{

-		if (priv->DIG_NumberFallbackVote)

-			priv->DIG_NumberFallbackVote--;

-		priv->DIG_NumberUpgradeVote++;

-

-		if (priv->DIG_NumberUpgradeVote>9)

-		{

-			if (priv->InitialGain > LowestGainStage) // In 87B, m78dBm means State 4 (m864dBm)

-			{

-				priv->InitialGainBackUp= priv->InitialGain;

-

-				priv->InitialGain = (priv->InitialGain - 1);

-//				printk("DIG**********OFDM False Alarm: %#X,  OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);

-//				printk("DIG--------- Upgrade OFDM:%d \n", priv->InitialGain);

-				UpdateInitialGain(dev); 

-			}

-			priv->DIG_NumberFallbackVote = 0;

-			priv->DIG_NumberUpgradeVote=0;

-		}

-	}

-

-//	printk("DIG+++++++ OFDM:%d\n", priv->InitialGain);	

-	//printk("<--------- DIG_Zebra()\n");

-}

-

-//

-//	Description:

-//		Dispatch DIG implementation according to RF. 	

-//

-void

-DynamicInitGain(

-	struct net_device *dev

-	)

-{

-	struct r8180_priv *priv = ieee80211_priv(dev);

-

-	switch(priv->rf_chip)

-	{

-		case RF_ZEBRA2:  // [AnnieWorkaround] For Zebra2, 2005-08-01.

-		case RF_ZEBRA4:

-			DIG_Zebra( dev );

-			break;

-		

-		default:

-			printk("DynamicInitGain(): unknown RFChipID(%d) !!!\n", priv->rf_chip);

-			break;

-	}

-}

-

-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))

-void rtl8180_hw_dig_wq (struct work_struct *work)

-{

-//      struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);

-//      struct ieee80211_device * ieee = (struct ieee80211_device*)

-//                                             container_of(work, struct ieee80211_device, watch_dog_wq);

-        struct delayed_work *dwork = container_of(work,struct delayed_work,work);

-        struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_dig_wq);

-        struct net_device *dev = ieee->dev;

-#else

-void rtl8180_hw_dig_wq(struct net_device *dev)

-{

-	

-#endif

-	struct r8180_priv *priv = ieee80211_priv(dev);

-

-	// Read CCK and OFDM False Alarm.

-	priv->FalseAlarmRegValue = read_nic_dword(dev, CCK_FALSE_ALARM);

-	

-

-	// Adjust Initial Gain dynamically.

-	DynamicInitGain(dev);

-	

-}

-

-int

-IncludedInSupportedRates(

-        struct r8180_priv       *priv,

-        u8              TxRate  )

-{

-    u8 rate_len;

-        u8 rate_ex_len;

-        u8                      RateMask = 0x7F;

-        u8                      idx;

-        unsigned short          Found = 0;

-        u8                      NaiveTxRate = TxRate&RateMask;

-

-    rate_len = priv->ieee80211->current_network.rates_len;

-        rate_ex_len = priv->ieee80211->current_network.rates_ex_len;

-        for( idx=0; idx< rate_len; idx++ )

-        {

-                if( (priv->ieee80211->current_network.rates[idx] & RateMask) == NaiveTxRate )

-                {

-                        Found = 1;

-                        goto found_rate;

-                }

-        }

-    for( idx=0; idx< rate_ex_len; idx++ )

-        {

-                if( (priv->ieee80211->current_network.rates_ex[idx] & RateMask) == NaiveTxRate )

-                {

-                        Found = 1;

-                        goto found_rate;

-                }

-        }

-        return Found;

-        found_rate:

-        return Found;

-}

-

-//

-//      Description:

-//              Get the Tx rate one degree up form the input rate in the supported rates.

-//              Return the upgrade rate if it is successed, otherwise return the input rate.

-//      By Bruce, 2007-06-05.

-// 

-u8

-GetUpgradeTxRate(

-        struct net_device *dev,

-        u8                              rate

-        )

-{

-        struct r8180_priv *priv = ieee80211_priv(dev);

-        u8                      UpRate;

-

-        // Upgrade 1 degree.

-        switch(rate)

-        {

-        case 108: // Up to 54Mbps.

-                UpRate = 108;

-                break;

-

-        case 96: // Up to 54Mbps.

-                UpRate = 108;

-                break;

-

-        case 72: // Up to 48Mbps.

-                UpRate = 96;

-                break;

-

-        case 48: // Up to 36Mbps.

-                UpRate = 72;

-                break;

-

-        case 36: // Up to 24Mbps.

-                UpRate = 48;

-                break;

-

-        case 22: // Up to 18Mbps.

-                UpRate = 36;

-                break;

-

-        case 11: // Up to 11Mbps.

-                UpRate = 22;

-                break;

-

-        case 4: // Up to 5.5Mbps.

-                UpRate = 11;

-                break;

-

-        case 2: // Up to 2Mbps.

-                UpRate = 4;

-                break;

-

-        default:

-                printk("GetUpgradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);

-                return rate;

-        }

-        // Check if the rate is valid.

-        if(IncludedInSupportedRates(priv, UpRate))

-        {

-//              printk("GetUpgradeTxRate(): GetUpgrade Tx rate(%d) from %d !\n", UpRate, priv->CurrentOperaRate);

-                return UpRate;

-        }

-        else

-        {

-                //printk("GetUpgradeTxRate(): Tx rate (%d) is not in supported rates\n", UpRate);

-                return rate;

-        }

-        return rate;

-}

-//

-//      Description:

-//              Get the Tx rate one degree down form the input rate in the supported rates.

-//              Return the degrade rate if it is successed, otherwise return the input rate.

-//      By Bruce, 2007-06-05.

-// 

-u8

-GetDegradeTxRate(

-        struct net_device *dev,

-        u8         rate

-        )

-{

-        struct r8180_priv *priv = ieee80211_priv(dev);

-        u8                      DownRate;

-

-        // Upgrade 1 degree.

-        switch(rate)

-        {

-        case 108: // Down to 48Mbps.

-                DownRate = 96;

-                break;

-

-        case 96: // Down to 36Mbps.

-                DownRate = 72;

-                break;

-

-        case 72: // Down to 24Mbps.

-                DownRate = 48;

-                break;

-

-        case 48: // Down to 18Mbps.

-                DownRate = 36;

-                break;

-

-        case 36: // Down to 11Mbps.

-                DownRate = 22;

-                break;

-

-        case 22: // Down to 5.5Mbps.

-                DownRate = 11;

-                break;

-

-        case 11: // Down to 2Mbps.

-                DownRate = 4;

-                break;

-

-        case 4: // Down to 1Mbps.

-                DownRate = 2;

-                break;

-

-        case 2: // Down to 1Mbps.

-                DownRate = 2;

-                break;

-

-        default:

-                printk("GetDegradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);

-                return rate;

-        }

-        // Check if the rate is valid.

-        if(IncludedInSupportedRates(priv, DownRate))

-        {

-//              printk("GetDegradeTxRate(): GetDegrade Tx rate(%d) from %d!\n", DownRate, priv->CurrentOperaRate);

-                return DownRate;

-        }

-        else

-        {

-                //printk("GetDegradeTxRate(): Tx rate (%d) is not in supported rates\n", DownRate);

-                return rate;

-        }

-        return rate;

-}

-//

-//      Helper function to determine if specified data rate is 

-//      CCK rate.

-//      2005.01.25, by rcnjko.

-//

-bool

-MgntIsCckRate(

-        u16     rate

-        )

-{

-        bool bReturn = false;

-

-        if((rate <= 22) && (rate != 12) && (rate != 18))

-        {

-                bReturn = true;

-        }

-

-        return bReturn;

-}

-#ifdef CONFIG_RTL818X_S

-//

-//	Description:

-//		Tx Power tracking mechanism routine on 87SE.

-// 	Created by Roger, 2007.12.11.

-//

-void

-TxPwrTracking87SE(

-	struct net_device *dev

-)

-{		

-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);

-	u8	tmpu1Byte, CurrentThermal, Idx;	

-	char	CckTxPwrIdx, OfdmTxPwrIdx;	

-	//u32	u4bRfReg;

-	

-	tmpu1Byte = read_nic_byte(dev, EN_LPF_CAL);

-	CurrentThermal = (tmpu1Byte & 0xf0)>>4; //[ 7:4]: thermal meter indication.

-	CurrentThermal = (CurrentThermal>0x0c)? 0x0c:CurrentThermal;//lzm add 080826

-

-	//printk("TxPwrTracking87SE(): CurrentThermal(%d)\n", CurrentThermal);

-	

-	if( CurrentThermal != priv->ThermalMeter)

-	{	

-//		printk("TxPwrTracking87SE(): Thermal meter changed!!!\n");

-

-		// Update Tx Power level on each channel.

-		for(Idx = 1; Idx<15; Idx++)

-		{			

-			CckTxPwrIdx = priv->chtxpwr[Idx];

-			OfdmTxPwrIdx = priv->chtxpwr_ofdm[Idx];			

-			

-			if( CurrentThermal > priv->ThermalMeter )

-			{ // higher thermal meter.		

-				CckTxPwrIdx += (CurrentThermal - priv->ThermalMeter)*2;

-				OfdmTxPwrIdx += (CurrentThermal - priv->ThermalMeter)*2;

-			

-				if(CckTxPwrIdx >35)

-					CckTxPwrIdx = 35; // Force TxPower to maximal index.

-				if(OfdmTxPwrIdx >35)

-					OfdmTxPwrIdx = 35;				

-			}

-			else

-			{ // lower thermal meter.				

-				CckTxPwrIdx -= (priv->ThermalMeter - CurrentThermal)*2;

-				OfdmTxPwrIdx -= (priv->ThermalMeter - CurrentThermal)*2;

-

-				if(CckTxPwrIdx <0)

-					CckTxPwrIdx = 0;		

-				if(OfdmTxPwrIdx <0)

-					OfdmTxPwrIdx = 0;				

-			}					

-			

-			// Update TxPower level on CCK and OFDM resp.

-			priv->chtxpwr[Idx] = CckTxPwrIdx;

-			priv->chtxpwr_ofdm[Idx] = OfdmTxPwrIdx;				

-		}	

-

-		// Update TxPower level immediately.

-		rtl8225z2_SetTXPowerLevel(dev, priv->ieee80211->current_network.channel);

-	}	

-	priv->ThermalMeter = CurrentThermal;					

-}

-void

-StaRateAdaptive87SE(

-	struct net_device *dev

-	)

-{

-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);

-	unsigned long 			CurrTxokCnt;

-	u16			CurrRetryCnt;

-	u16			CurrRetryRate;

-	//u16			i,idx;

-	unsigned long       	CurrRxokCnt;

-	bool			bTryUp = false;

-	bool			bTryDown = false;

-	u8			TryUpTh = 1;

-	u8			TryDownTh = 2;

-	u32			TxThroughput;

-	long		CurrSignalStrength;

-	bool		bUpdateInitialGain = false;

-    	u8			u1bOfdm=0, u1bCck = 0;

-	char		OfdmTxPwrIdx, CckTxPwrIdx;	

-

-	priv->RateAdaptivePeriod= RATE_ADAPTIVE_TIMER_PERIOD;

-

-

-	CurrRetryCnt	= priv->CurrRetryCnt;

-	CurrTxokCnt	= priv->NumTxOkTotal - priv->LastTxokCnt;

-	CurrRxokCnt	= priv->ieee80211->NumRxOkTotal - priv->LastRxokCnt;

-	CurrSignalStrength = priv->Stats_RecvSignalPower;

-	TxThroughput = (u32)(priv->NumTxOkBytesTotal - priv->LastTxOKBytes);

-	priv->LastTxOKBytes = priv->NumTxOkBytesTotal;

-	priv->CurrentOperaRate = priv->ieee80211->rate/5;

-	//printk("priv->CurrentOperaRate is %d\n",priv->CurrentOperaRate);

-	//2 Compute retry ratio.

-	if (CurrTxokCnt>0)

-	{

-		CurrRetryRate = (u16)(CurrRetryCnt*100/CurrTxokCnt);

-	}

-	else

-	{ // It may be serious retry. To distinguish serious retry or no packets modified by Bruce

-		CurrRetryRate = (u16)(CurrRetryCnt*100/1);

-	}

-

-

-	//

-	// Added by Roger, 2007.01.02.

-	// For debug information.

-	//

-	//printk("\n(1) pHalData->LastRetryRate: %d \n",priv->LastRetryRate);

-	//printk("(2) RetryCnt = %d  \n", CurrRetryCnt);	

-	//printk("(3) TxokCnt = %d \n", CurrTxokCnt);

-	//printk("(4) CurrRetryRate = %d \n", CurrRetryRate);	

-	//printk("(5) CurrSignalStrength = %d \n",CurrSignalStrength);

-	//printk("(6) TxThroughput is %d\n",TxThroughput);

-	//printk("priv->NumTxOkBytesTotal is %d\n",priv->NumTxOkBytesTotal);		

-

-	priv->LastRetryCnt = priv->CurrRetryCnt;

-	priv->LastTxokCnt = priv->NumTxOkTotal;

-	priv->LastRxokCnt = priv->ieee80211->NumRxOkTotal;

-	priv->CurrRetryCnt = 0;

-

-	//2No Tx packets, return to init_rate or not?

-	if (CurrRetryRate==0 && CurrTxokCnt == 0)

-	{	

-		//

-		//After 9 (30*300ms) seconds in this condition, we try to raise rate.

-		//

-		priv->TryupingCountNoData++;

-		

-//		printk("No Tx packets, TryupingCountNoData(%d)\n", priv->TryupingCountNoData);

-		//[TRC Dell Lab] Extend raised period from 4.5sec to 9sec, Isaiah 2008-02-15 18:00 

-		if (priv->TryupingCountNoData>30)

-		{

-			priv->TryupingCountNoData = 0;

-		 	priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);		

-			// Reset Fail Record

-			priv->LastFailTxRate = 0;

-			priv->LastFailTxRateSS = -200;

-			priv->FailTxRateCount = 0;

-		}

-		goto SetInitialGain;

-	}

-        else

-	{

-		priv->TryupingCountNoData=0; //Reset trying up times.

-	}

-

-

-	//

-	// For Netgear case, I comment out the following signal strength estimation,

-	// which can results in lower rate to transmit when sample is NOT enough (e.g. PING request).  

-	// 2007.04.09, by Roger.	

-	//	

-

-	//

-	// Restructure rate adaptive as the following main stages:

-	// (1) Add retry threshold in 54M upgrading condition with signal strength.

-	// (2) Add the mechanism to degrade to CCK rate according to signal strength 

-	//		and retry rate.

-	// (3) Remove all Initial Gain Updates over OFDM rate. To avoid the complicated 

-	//		situation, Initial Gain Update is upon on DIG mechanism except CCK rate.

-	// (4) Add the mehanism of trying to upgrade tx rate.

-	// (5) Record the information of upping tx rate to avoid trying upping tx rate constantly.

-	// By Bruce, 2007-06-05.

-	//	

-	//

-

-	// 11Mbps or 36Mbps

-	// Check more times in these rate(key rates).

-	//

-	if(priv->CurrentOperaRate == 22 || priv->CurrentOperaRate == 72)

-	{ 

-		TryUpTh += 9;

-	}

-	//

-	// Let these rates down more difficult.

-	//

-	if(MgntIsCckRate(priv->CurrentOperaRate) || priv->CurrentOperaRate == 36)

-	{

-			TryDownTh += 1;

-	}

-

-	//1 Adjust Rate.

-	if (priv->bTryuping == true)

-	{	

-		//2 For Test Upgrading mechanism

-		// Note:

-		// 	Sometimes the throughput is upon on the capability bwtween the AP and NIC,

-		// 	thus the low data rate does not improve the performance.

-		// 	We randomly upgrade the data rate and check if the retry rate is improved.

-		

-		// Upgrading rate did not improve the retry rate, fallback to the original rate.

-		if ( (CurrRetryRate > 25) && TxThroughput < priv->LastTxThroughput)

-		{

-			//Not necessary raising rate, fall back rate.

-			bTryDown = true;

-			//printk("case1-1: Not necessary raising rate, fall back rate....\n");

-			//printk("case1-1: pMgntInfo->CurrentOperaRate =%d, TxThroughput = %d, LastThroughput = %d\n",

-			//		priv->CurrentOperaRate, TxThroughput, priv->LastTxThroughput);			

-		}

-		else

-		{

-			priv->bTryuping = false;

-		}

-	}	

-	else if (CurrSignalStrength > -47 && (CurrRetryRate < 50))

-	{

-		//2For High Power

-		//

-		// Added by Roger, 2007.04.09.

-		// Return to highest data rate, if signal strength is good enough.

-		// SignalStrength threshold(-50dbm) is for RTL8186.

-		// Revise SignalStrength threshold to -51dbm.	

-		//

-		// Also need to check retry rate for safety, by Bruce, 2007-06-05.

-		if(priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate )

-		{

-			bTryUp = true;

-			// Upgrade Tx Rate directly.

-			priv->TryupingCount += TryUpTh;

-		}

-//		printk("case2: StaRateAdaptive87SE: Power(%d) is high enough!!. \n", CurrSignalStrength);			

-					

-	}

-	else if(CurrTxokCnt > 9 && CurrTxokCnt< 100 && CurrRetryRate >= 600) 

-	{

-		//2 For Serious Retry

-		//

-		// Traffic is not busy but our Tx retry is serious. 

-		//

-		bTryDown = true;

-		// Let Rate Mechanism to degrade tx rate directly.

-		priv->TryDownCountLowData += TryDownTh;

-//		printk("case3: RA: Tx Retry is serious. Degrade Tx Rate to %d directly...\n", priv->CurrentOperaRate);	

-	}

-	else if ( priv->CurrentOperaRate == 108 )

-	{

-		//2For 54Mbps

-		// Air Link

-		if ( (CurrRetryRate>26)&&(priv->LastRetryRate>25))

-//		if ( (CurrRetryRate>40)&&(priv->LastRetryRate>39))

-		{

-			//Down to rate 48Mbps.

-			bTryDown = true;

-		}

-		// Cable Link

-		else if ( (CurrRetryRate>17)&&(priv->LastRetryRate>16) && (CurrSignalStrength > -72)) 

-//		else if ( (CurrRetryRate>17)&&(priv->LastRetryRate>16) && (CurrSignalStrength > -72))

-		{

-			//Down to rate 48Mbps.

-			bTryDown = true;

-		}

-

-		if(bTryDown && (CurrSignalStrength < -75)) //cable link

-		{

-			priv->TryDownCountLowData += TryDownTh;

-		}

-		//printk("case4---54M \n");	

-

-	}

-	else if ( priv->CurrentOperaRate == 96 )

-	{

-		//2For 48Mbps

-		//Air Link

-		if ( ((CurrRetryRate>48) && (priv->LastRetryRate>47)))

-//		if ( ((CurrRetryRate>65) && (priv->LastRetryRate>64)))

-

-		{	

-			//Down to rate 36Mbps.

-			bTryDown = true;

-		}

-		//Cable Link

-		else if ( ((CurrRetryRate>21) && (priv->LastRetryRate>20)) && (CurrSignalStrength > -74))

-		{

-			//Down to rate 36Mbps.

-			bTryDown = true;

-		}

-		else if((CurrRetryRate>  (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))

-//		else if((CurrRetryRate>  (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))

-		{

-			bTryDown = true;

-			priv->TryDownCountLowData += TryDownTh;

-		}

-		else if ( (CurrRetryRate<8) && (priv->LastRetryRate<8) ) //TO DO: need to consider (RSSI)

-//		else if ( (CurrRetryRate<28) && (priv->LastRetryRate<8) ) 

-		{

-			bTryUp = true;

-		}

-

-		if(bTryDown && (CurrSignalStrength < -75))

-		{

-			priv->TryDownCountLowData += TryDownTh;

-		}

-		//printk("case5---48M \n");	

-	}

-	else if ( priv->CurrentOperaRate == 72 )

-	{

-		//2For 36Mbps

-		if ( (CurrRetryRate>43) && (priv->LastRetryRate>41)) 

-//		if ( (CurrRetryRate>60) && (priv->LastRetryRate>59))

-		{	

-			//Down to rate 24Mbps.

-			bTryDown = true;

-		}

-		else if((CurrRetryRate>  (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))

-//		else if((CurrRetryRate>  (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))

-		{

-			bTryDown = true;

-			priv->TryDownCountLowData += TryDownTh;

-		}

-		else if ( (CurrRetryRate<15) &&  (priv->LastRetryRate<16)) //TO DO: need to consider (RSSI)

-//		else if ( (CurrRetryRate<35) &&  (priv->LastRetryRate<36))

-		{

-			bTryUp = true;

-		}

-

-		if(bTryDown && (CurrSignalStrength < -80))

-		{

-			priv->TryDownCountLowData += TryDownTh;

-		}

-		//printk("case6---36M \n");	

-	}

-	else if ( priv->CurrentOperaRate == 48 )

-	{

-		//2For 24Mbps

-		// Air Link

-		if ( ((CurrRetryRate>63) && (priv->LastRetryRate>62)))

-//		if ( ((CurrRetryRate>83) && (priv->LastRetryRate>82)))

-		{	

-			//Down to rate 18Mbps.

-			bTryDown = true;

-		}

-		//Cable Link

-		else if ( ((CurrRetryRate>33) && (priv->LastRetryRate>32)) && (CurrSignalStrength > -82) )

-//		 else if ( ((CurrRetryRate>50) && (priv->LastRetryRate>49)) && (CurrSignalStrength > -82) )

-		{

-			//Down to rate 18Mbps.

-			bTryDown = true;

-		}

-		else if((CurrRetryRate>  (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))

-//		else if((CurrRetryRate>  (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))

-

-		{

-			bTryDown = true;

-			priv->TryDownCountLowData += TryDownTh;

-		}

-  		else if ( (CurrRetryRate<20) && (priv->LastRetryRate<21)) //TO DO: need to consider (RSSI)

-//		else if ( (CurrRetryRate<40) && (priv->LastRetryRate<41))

-		{	

-			bTryUp = true;	

-		}

-

-		if(bTryDown && (CurrSignalStrength < -82))

-		{

-			priv->TryDownCountLowData += TryDownTh;

-		}

-		//printk("case7---24M \n");	

-	}

-	else if ( priv->CurrentOperaRate == 36 )

-	{

-		//2For 18Mbps

-		// original (109, 109) 

-		//[TRC Dell Lab] (90, 91), Isaiah 2008-02-18 23:24

-		//			     (85, 86), Isaiah 2008-02-18 24:00

-		if ( ((CurrRetryRate>85) && (priv->LastRetryRate>86)))

-//		if ( ((CurrRetryRate>115) && (priv->LastRetryRate>116)))

-		{

-			//Down to rate 11Mbps.

-			bTryDown = true;

-		}

-		//[TRC Dell Lab]  Isaiah 2008-02-18 23:24

-		else if((CurrRetryRate>  (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))

-//		else if((CurrRetryRate>  (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))

-		{

-			bTryDown = true;

-			priv->TryDownCountLowData += TryDownTh;

-		}

-		else if ( (CurrRetryRate<22) && (priv->LastRetryRate<23)) //TO DO: need to consider (RSSI)

-//		else if ( (CurrRetryRate<42) && (priv->LastRetryRate<43))

-		{	

-			bTryUp = true;	

-		}

-		//printk("case8---18M \n");	

-	}

-	else if ( priv->CurrentOperaRate == 22 )

-	{

-		//2For 11Mbps

-		if (CurrRetryRate>95)

-//		if (CurrRetryRate>155)

-		{

-			bTryDown = true;

-		}

-		else if ( (CurrRetryRate<29) && (priv->LastRetryRate <30) )//TO DO: need to consider (RSSI)

-//		else if ( (CurrRetryRate<49) && (priv->LastRetryRate <50) )

-			{

-			bTryUp = true;

-			}

-		//printk("case9---11M \n");	

-		}	

-	else if ( priv->CurrentOperaRate == 11 )

-	{

-		//2For 5.5Mbps

-		if (CurrRetryRate>149) 

-//		if (CurrRetryRate>189)

-		{	

-			bTryDown = true;			

-		}

-		else if ( (CurrRetryRate<60) && (priv->LastRetryRate < 65))

-//		else if ( (CurrRetryRate<80) && (priv->LastRetryRate < 85))

-

-			{

-			bTryUp = true;

-			}		

-		//printk("case10---5.5M \n");	

-		}

-	else if ( priv->CurrentOperaRate == 4 )

-	{

-		//2For 2 Mbps

-		if((CurrRetryRate>99) && (priv->LastRetryRate>99))

-//		if((CurrRetryRate>199) && (priv->LastRetryRate>199))

-		{

-			bTryDown = true;			

-		}

-		else if ( (CurrRetryRate < 65) && (priv->LastRetryRate < 70))

-//		else if ( (CurrRetryRate < 85) && (priv->LastRetryRate < 90))

-		{

-			bTryUp = true;

-		}

-		//printk("case11---2M \n");	

-	}

-	else if ( priv->CurrentOperaRate == 2 )

-	{

-		//2For 1 Mbps

-		if( (CurrRetryRate<70) && (priv->LastRetryRate<75))

-//		if( (CurrRetryRate<90) && (priv->LastRetryRate<95))

-		{

-			bTryUp = true;

-		}

-		//printk("case12---1M \n");	

-	}

-

-	if(bTryUp && bTryDown)

-    	printk("StaRateAdaptive87B(): Tx Rate tried upping and downing simultaneously!\n");

-				

-	//1 Test Upgrading Tx Rate

-	// Sometimes the cause of the low throughput (high retry rate) is the compatibility between the AP and NIC.

-	// To test if the upper rate may cause lower retry rate, this mechanism randomly occurs to test upgrading tx rate.

-	if(!bTryUp && !bTryDown && (priv->TryupingCount == 0) && (priv->TryDownCountLowData == 0)

-		&& priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate && priv->FailTxRateCount < 2)

-	{

-		if(jiffies% (CurrRetryRate + 101) == 0)

-		{

-			bTryUp = true;	

-			priv->bTryuping = true;

-			//printk("StaRateAdaptive87SE(): Randomly try upgrading...\n");

-		}

-	}

-

-	//1 Rate Mechanism

-	if(bTryUp)

-	{

-		priv->TryupingCount++;

-		priv->TryDownCountLowData = 0;

-			

-		{

-//			printk("UP: pHalData->TryupingCount = %d\n", priv->TryupingCount);

-//			printk("UP: TryUpTh(%d)+ (FailTxRateCount(%d))^2 =%d\n", 

-//				TryUpTh, priv->FailTxRateCount, (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount) );

-//			printk("UP: pHalData->bTryuping=%d\n",  priv->bTryuping);

-

-		}

-		

-		//

-		// Check more times if we need to upgrade indeed.

-		// Because the largest value of pHalData->TryupingCount is 0xFFFF and 

-		// the largest value of pHalData->FailTxRateCount is 0x14,

-		// this condition will be satisfied at most every 2 min.

-		//

-

-		if((priv->TryupingCount > (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount)) ||

-			(CurrSignalStrength > priv->LastFailTxRateSS) || priv->bTryuping)

-		{

-			priv->TryupingCount = 0;

-			// 

-			// When transfering from CCK to OFDM, DIG is an important issue.

-			//

-			if(priv->CurrentOperaRate == 22)

-				bUpdateInitialGain = true;

-

-			// The difference in throughput between 48Mbps and 36Mbps is 8M.

-			// So, we must be carefully in this rate scale. Isaiah 2008-02-15.

-			//

-			if(  ((priv->CurrentOperaRate == 72) || (priv->CurrentOperaRate == 48) || (priv->CurrentOperaRate == 36)) &&

-				(priv->FailTxRateCount > 2) )

-				priv->RateAdaptivePeriod= (RATE_ADAPTIVE_TIMER_PERIOD/2);

-			

-			// (1)To avoid upgrade frequently to the fail tx rate, add the FailTxRateCount into the threshold.

-			// (2)If the signal strength is increased, it may be able to upgrade.

-

-			priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);

-//			printk("StaRateAdaptive87SE(): Upgrade Tx Rate to %d\n", priv->CurrentOperaRate);

-

-			//[TRC Dell Lab] Bypass 12/9/6, Isaiah 2008-02-18 20:00 

-			if(priv->CurrentOperaRate ==36)

-			{

-				priv->bUpdateARFR=true;

-				write_nic_word(dev, ARFR, 0x0F8F); //bypass 12/9/6

-//				printk("UP: ARFR=0xF8F\n");

-			}

-			else if(priv->bUpdateARFR)

-			{

-				priv->bUpdateARFR=false;

-				write_nic_word(dev, ARFR, 0x0FFF); //set 1M ~ 54Mbps.

-//				printk("UP: ARFR=0xFFF\n");

-			}

-				

-			// Update Fail Tx rate and count.

-			if(priv->LastFailTxRate != priv->CurrentOperaRate)

-			{

-				priv->LastFailTxRate = priv->CurrentOperaRate;

-				priv->FailTxRateCount = 0;

-				priv->LastFailTxRateSS = -200; // Set lowest power.

-			}

-		}

-	}

-	else

-	{	

-		if(priv->TryupingCount > 0)

-			priv->TryupingCount --;

-	}

-	

-	if(bTryDown)

-	{

-		priv->TryDownCountLowData++;

-		priv->TryupingCount = 0;

-		{

-//			printk("DN: pHalData->TryDownCountLowData = %d\n",priv->TryDownCountLowData);

-//			printk("DN: TryDownTh =%d\n", TryDownTh);

-//			printk("DN: pHalData->bTryuping=%d\n",  priv->bTryuping);

-		}

-						

-		//Check if Tx rate can be degraded or Test trying upgrading should fallback.

-		if(priv->TryDownCountLowData > TryDownTh || priv->bTryuping)

-		{

-			priv->TryDownCountLowData = 0;

-			priv->bTryuping = false;

-			// Update fail information.

-			if(priv->LastFailTxRate == priv->CurrentOperaRate)

-			{

-				priv->FailTxRateCount ++;

-				// Record the Tx fail rate signal strength.

-				if(CurrSignalStrength > priv->LastFailTxRateSS)

-				{

-					priv->LastFailTxRateSS = CurrSignalStrength;

-				}

-			}

-			else

-			{

-				priv->LastFailTxRate = priv->CurrentOperaRate;

-				priv->FailTxRateCount = 1;

-				priv->LastFailTxRateSS = CurrSignalStrength;

-			}

-			priv->CurrentOperaRate = GetDegradeTxRate(dev, priv->CurrentOperaRate);

-

-			// Reduce chariot training time at weak signal strength situation. SD3 ED demand. 

-			//[TRC Dell Lab] Revise Signal Threshold from -75 to -80 , Isaiah 2008-02-18 20:00 

-			if( (CurrSignalStrength < -80) && (priv->CurrentOperaRate > 72 ))

-			{

-				priv->CurrentOperaRate = 72;

-//				printk("DN: weak signal strength (%d), degrade to 36Mbps\n", CurrSignalStrength);

-			}

-

-			//[TRC Dell Lab] Bypass 12/9/6, Isaiah 2008-02-18 20:00 

-			if(priv->CurrentOperaRate ==36)

-			{

-				priv->bUpdateARFR=true;

-				write_nic_word(dev, ARFR, 0x0F8F); //bypass 12/9/6

-//				printk("DN: ARFR=0xF8F\n");

-			}

-			else if(priv->bUpdateARFR)

-			{

-				priv->bUpdateARFR=false;

-				write_nic_word(dev, ARFR, 0x0FFF); //set 1M ~ 54Mbps.

-//				printk("DN: ARFR=0xFFF\n");

-			}

-				

-			//

-			// When it is CCK rate, it may need to update initial gain to receive lower power packets.

-			//

-			if(MgntIsCckRate(priv->CurrentOperaRate))

-			{

-				bUpdateInitialGain = true;

-			}

-//			printk("StaRateAdaptive87SE(): Degrade Tx Rate to %d\n", priv->CurrentOperaRate);

-		}

-	}

-	else

-	{

-		if(priv->TryDownCountLowData > 0)

-			priv->TryDownCountLowData --;

-	}

-			

-	// Keep the Tx fail rate count to equal to 0x15 at most.

-	// Reduce the fail count at least to 10 sec if tx rate is tending stable.

-	if(priv->FailTxRateCount >= 0x15 || 

-		(!bTryUp && !bTryDown && priv->TryDownCountLowData == 0 && priv->TryupingCount && priv->FailTxRateCount > 0x6))

-	{

-		priv->FailTxRateCount --;

-	}		

-

-

-	OfdmTxPwrIdx  = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel]; 

-	CckTxPwrIdx  = priv->chtxpwr[priv->ieee80211->current_network.channel]; 

-	

-	//[TRC Dell Lab] Mac0x9e increase 2 level in 36M~18M situation, Isaiah 2008-02-18 24:00 

-	if((priv->CurrentOperaRate < 96) &&(priv->CurrentOperaRate > 22))

-	{

-		u1bCck = read_nic_byte(dev, CCK_TXAGC);

-		u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);

-

-		// case 1: Never enter High power

-		if(u1bCck == CckTxPwrIdx )

-		{

-			if(u1bOfdm != (OfdmTxPwrIdx+2) )

-			{

-			priv->bEnhanceTxPwr= true;

-			u1bOfdm = ((u1bOfdm+2) > 35) ? 35: (u1bOfdm+2);

-			write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);

-//			printk("Enhance OFDM_TXAGC : +++++ u1bOfdm= 0x%x\n", u1bOfdm);

-			}

-		}

-		// case 2: enter high power

-		else if(u1bCck < CckTxPwrIdx)

-		{

-			if(!priv->bEnhanceTxPwr)

-			{

-				priv->bEnhanceTxPwr= true;

-				u1bOfdm = ((u1bOfdm+2) > 35) ? 35: (u1bOfdm+2);

-				write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);

-				//RT_TRACE(COMP_RATE, DBG_TRACE, ("Enhance OFDM_TXAGC(2) : +++++ u1bOfdm= 0x%x\n", u1bOfdm));

-			}

-		}

-	}

-	else if(priv->bEnhanceTxPwr)  //54/48/11/5.5/2/1

-	{

-		u1bCck = read_nic_byte(dev, CCK_TXAGC);

-		u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);

-

-		// case 1: Never enter High power

-		if(u1bCck == CckTxPwrIdx )

-		{

-		priv->bEnhanceTxPwr= false;

-		write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);

-		//printk("Recover OFDM_TXAGC : ===== u1bOfdm= 0x%x\n", OfdmTxPwrIdx);

-		}

-		// case 2: enter high power

-		else if(u1bCck < CckTxPwrIdx)

-		{

-			priv->bEnhanceTxPwr= false;

-			u1bOfdm = ((u1bOfdm-2) > 0) ? (u1bOfdm-2): 0;

-			write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);

-			//RT_TRACE(COMP_RATE, DBG_TRACE, ("Recover OFDM_TXAGC(2): ===== u1bOfdm= 0x%x\n", u1bOfdm));

-

-		}

-	}

-

-	//

-	// We need update initial gain when we set tx rate "from OFDM to CCK" or

-	// "from CCK to OFDM". 

-	//

-SetInitialGain:

-	if(bUpdateInitialGain)

-	{

-		if(MgntIsCckRate(priv->CurrentOperaRate)) // CCK

-		{

-			if(priv->InitialGain > priv->RegBModeGainStage)

-			{

-				priv->InitialGainBackUp= priv->InitialGain;

-

-				if(CurrSignalStrength < -85) // Low power, OFDM [0x17] = 26.

-				{

-					//SD3 SYs suggest that CurrSignalStrength < -65, ofdm 0x17=26.

-					priv->InitialGain = priv->RegBModeGainStage;

-				}

-				else if(priv->InitialGain > priv->RegBModeGainStage + 1)

-				{

-					priv->InitialGain -= 2;

-				}

-				else

-				{

-					priv->InitialGain --;

-				}

-				printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);			

-				UpdateInitialGain(dev);

-			}

-		}

-		else // OFDM

-		{			

-			if(priv->InitialGain < 4)

-			{

-				priv->InitialGainBackUp= priv->InitialGain;

-

-				priv->InitialGain ++;

-				printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);			

-				UpdateInitialGain(dev);

-			}					

-		}

-	}

-

-	//Record the related info

-	priv->LastRetryRate = CurrRetryRate;

-	priv->LastTxThroughput = TxThroughput;

-	priv->ieee80211->rate = priv->CurrentOperaRate * 5;

-}

-

-#endif

-#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)

-void rtl8180_rate_adapter(struct work_struct * work)

-{

-	struct delayed_work *dwork = container_of(work,struct delayed_work,work);

-        struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,rate_adapter_wq);

-        struct net_device *dev = ieee->dev;

-#else

-void rtl8180_rate_adapter(struct net_device *dev)

-{

-

-#endif

-        //struct r8180_priv *priv = ieee80211_priv(dev);

-//    DMESG("---->rtl8180_rate_adapter");

-        StaRateAdaptive87SE(dev);

-//   DMESG("<----rtl8180_rate_adapter");

-}

-void timer_rate_adaptive(unsigned long data)

-{

-	struct r8180_priv* priv = ieee80211_priv((struct net_device *)data);

-	//DMESG("---->timer_rate_adaptive()\n");

-	if(!priv->up)

-	{

-//		DMESG("<----timer_rate_adaptive():driver is not up!\n");

-		return;

-	}

-	if((priv->ieee80211->iw_mode != IW_MODE_MASTER)

-			&& (priv->ieee80211->state == IEEE80211_LINKED) &&

-			(priv->ForcedDataRate == 0) )

-	{

-//	DMESG("timer_rate_adaptive():schedule rate_adapter_wq\n");

-#ifdef CONFIG_RTL818X_S

-		queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->rate_adapter_wq);

-//		StaRateAdaptive87SE((struct net_device *)data);

-#endif

-	}

-	priv->rateadapter_timer.expires = jiffies + MSECS(priv->RateAdaptivePeriod);

-	add_timer(&priv->rateadapter_timer);

-	//DMESG("<----timer_rate_adaptive()\n");

-}

-//by amy 080312}

-void

-SwAntennaDiversityRxOk8185(

-	struct net_device *dev, 

-	u8 SignalStrength

-	)

-{

-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);

-

-//	printk("+SwAntennaDiversityRxOk8185: RxSs: %d\n", SignalStrength);

-

-	priv->AdRxOkCnt++;

-

-	if( priv->AdRxSignalStrength != -1)

-	{

-		priv->AdRxSignalStrength = ((priv->AdRxSignalStrength*7) + (SignalStrength*3)) / 10;

-	}

-	else

-	{ // Initialization case.

-		priv->AdRxSignalStrength = SignalStrength;

-	}

-//{+by amy 080312

-	if( priv->LastRxPktAntenna ) //Main antenna.	

-		priv->AdMainAntennaRxOkCnt++;	

-	else	 // Aux antenna.

-		priv->AdAuxAntennaRxOkCnt++;

-//+by amy 080312

-//	printk("-SwAntennaDiversityRxOk8185: AdRxOkCnt: %d AdRxSignalStrength: %d\n", priv->AdRxOkCnt, priv->AdRxSignalStrength);

-}

-//

-//	Description:

-//		Change Antenna Switch.

-//

-bool

-SetAntenna8185(

-	struct net_device *dev,

-	u8		u1bAntennaIndex

-	)

-{

-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);

-	bool bAntennaSwitched = false;

-

-//	printk("+SetAntenna8185(): Antenna is switching to: %d \n", u1bAntennaIndex);

-

-	switch(u1bAntennaIndex)

-	{

-	case 0:

-		switch(priv->rf_chip)

-		{

-		case RF_ZEBRA2:

-		case RF_ZEBRA4:

-#ifdef CONFIG_RTL8185B

-#ifdef CONFIG_RTL818X_S

-			// Mac register, main antenna

-			write_nic_byte(dev, ANTSEL, 0x03); 

-			//base band

-			write_phy_cck(dev,0x11, 0x9b); // Config CCK RX antenna.

-			write_phy_ofdm(dev, 0x0d, 0x5c); // Config OFDM RX antenna.

-

-#else

-			// Mac register, main antenna

-			write_nic_byte(dev, ANTSEL, 0x03); 

-			//base band

-			write_phy_cck(dev, 0x10, 0x9b); // Config CCK RX antenna.

-			write_phy_ofdm(dev, 0x0d, 0x5c); // Config OFDM RX antenna.

-#endif

-#endif

-

-			bAntennaSwitched = true;

-			break;

-

-		default:

-			printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);

-			break;

-		}

-		break;

-

-	case 1:

-		switch(priv->rf_chip)

-		{

-		case RF_ZEBRA2:

-		case RF_ZEBRA4:

-#ifdef CONFIG_RTL8185B

-#ifdef CONFIG_RTL818X_S

-			// Mac register, aux antenna

-			write_nic_byte(dev, ANTSEL, 0x00); 

-			//base band

-			write_phy_cck(dev, 0x11, 0xbb); // Config CCK RX antenna.

-			write_phy_ofdm(dev, 0x0d, 0x54); // Config OFDM RX antenna.

-#else

-			// Mac register, aux antenna

-			write_nic_byte(dev, ANTSEL, 0x00); 

-			//base band

-			write_phy_cck(dev, 0x10, 0xbb); // Config CCK RX antenna.

-			write_phy_ofdm(dev, 0x0d, 0x54); // Config OFDM RX antenna.

-#endif

-#endif

-

-			bAntennaSwitched = true;

-			break;

-

-		default:

-			printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);

-			break;

-		}

-		break;

-

-	default:

-		printk("SetAntenna8185: unkown u1bAntennaIndex(%d)\n", u1bAntennaIndex);

-		break;

-	}

-

-	if(bAntennaSwitched)

-	{

-		priv->CurrAntennaIndex = u1bAntennaIndex;

-	}

-

-//	printk("-SetAntenna8185(): return (%#X)\n", bAntennaSwitched);

-

-	return bAntennaSwitched;

-}

-//

-//	Description:

-//		Toggle Antenna switch.

-//

-bool

-SwitchAntenna(

-	struct net_device *dev

-	)

-{

-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);

-

-	bool		bResult;

-

-	if(priv->CurrAntennaIndex == 0)

-	{

-#if 0//lzm del 080826

-//by amy 080312

-#ifdef CONFIG_RTL818X_S

-		if(priv->bSwAntennaDiverity)

-			bResult = SetAntennaConfig87SE(dev, 1, true);

-		else			

-#endif

-#endif

-			bResult = SetAntenna8185(dev, 1);

-//by amy 080312

-//		printk("SwitchAntenna(): switching to antenna 1 ......\n");

-//		bResult = SetAntenna8185(dev, 1);//-by amy 080312

-	}

-	else

-	{

-#if 0//lzm del 080826

-//by amy 080312

-#ifdef CONFIG_RTL818X_S

-		if(priv->bSwAntennaDiverity)

-			bResult = SetAntennaConfig87SE(dev, 0, true);

-		else	

-#endif

-#endif

-			bResult = SetAntenna8185(dev, 0);

-//by amy 080312

-//		printk("SwitchAntenna(): switching to antenna 0 ......\n");

-//		bResult = SetAntenna8185(dev, 0);//-by amy 080312

-	}

-

-	return bResult;

-}

-//

-//	Description:

-//		Engine of SW Antenna Diversity mechanism.

-//		Since 8187 has no Tx part information, 

-//		this implementation is only dependend on Rx part information. 

-//

-//	2006.04.17, by rcnjko.

-//

-void

-SwAntennaDiversity(

-	struct net_device *dev

-	)

-{

-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);

-	bool   bSwCheckSS=false;

-//	printk("+SwAntennaDiversity(): CurrAntennaIndex: %d\n", priv->CurrAntennaIndex);

-//	printk("AdTickCount is %d\n",priv->AdTickCount);

-//by amy 080312

-	if(bSwCheckSS)

-	{

-		priv->AdTickCount++;

-	

-		printk("(1) AdTickCount: %d, AdCheckPeriod: %d\n", 

-			priv->AdTickCount, priv->AdCheckPeriod);

-		printk("(2) AdRxSignalStrength: %ld, AdRxSsThreshold: %ld\n", 

-			priv->AdRxSignalStrength, priv->AdRxSsThreshold);

-	}

-//	priv->AdTickCount++;//-by amy 080312

-	

-	// Case 1. No Link.

-	if(priv->ieee80211->state != IEEE80211_LINKED)

-	{

-	//	printk("SwAntennaDiversity(): Case 1. No Link.\n");

-

-		priv->bAdSwitchedChecking = false;

-		// I switch antenna here to prevent any one of antenna is broken before link established, 2006.04.18, by rcnjko..

-		SwitchAntenna(dev);

-	}

-	// Case 2. Linked but no packet received.

-	else if(priv->AdRxOkCnt == 0)

-	{

-	//	printk("SwAntennaDiversity(): Case 2. Linked but no packet received.\n");

-

-		priv->bAdSwitchedChecking = false;

-		SwitchAntenna(dev);

-	}

-	// Case 3. Evaluate last antenna switch action and undo it if necessary.

-	else if(priv->bAdSwitchedChecking == true)

-	{

-	//	printk("SwAntennaDiversity(): Case 3. Evaluate last antenna switch action.\n");

-

-		priv->bAdSwitchedChecking = false;

-

-		// Adjust Rx signal strength threashold.

-		priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2;

-

-		priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?	

-					priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;

-		if(priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched)

-		{ // Rx signal strength is not improved after we swtiched antenna. => Swich back.

-//			printk("SwAntennaDiversity(): Rx Signal Strength is not improved, CurrRxSs: %d, LastRxSs: %d\n", 

-//				priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);

-//by amy 080312

-			// Increase Antenna Diversity checking period due to bad decision.

-			priv->AdCheckPeriod *= 2;

-//by amy 080312

-			// Increase Antenna Diversity checking period.

-			if(priv->AdCheckPeriod > priv->AdMaxCheckPeriod)

-				priv->AdCheckPeriod = priv->AdMaxCheckPeriod;

-	

-			// Wrong deceision => switch back.

-			SwitchAntenna(dev);

-		}

-		else

-		{ // Rx Signal Strength is improved. 

-//			printk("SwAntennaDiversity(): Rx Signal Strength is improved, CurrRxSs: %d, LastRxSs: %d\n", 

-//				priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);

-

-			// Reset Antenna Diversity checking period to its min value.

-			priv->AdCheckPeriod = priv->AdMinCheckPeriod;

-		}

-

-//		printk("SwAntennaDiversity(): AdRxSsThreshold: %d, AdCheckPeriod: %d\n",

-//			priv->AdRxSsThreshold, priv->AdCheckPeriod);

-	}

-	// Case 4. Evaluate if we shall switch antenna now.

-	// Cause Table Speed is very fast in TRC Dell Lab, we check it every time. 

-	else// if(priv->AdTickCount >= priv->AdCheckPeriod)//-by amy 080312

-	{

-//		printk("SwAntennaDiversity(): Case 4. Evaluate if we shall switch antenna now.\n");

-

-		priv->AdTickCount = 0;

-

-		//

-		// <Roger_Notes> We evaluate RxOk counts for each antenna first and than 

-		// evaluate signal strength. 

-		// The following operation can overcome the disability of CCA on both two antennas

-		// When signal strength was extremely low or high.

-		// 2008.01.30.

-		// 

-		

-		//

-		// Evaluate RxOk count from each antenna if we shall switch default antenna now.

-		// Added by Roger, 2008.02.21.

-//{by amy 080312

-		if((priv->AdMainAntennaRxOkCnt < priv->AdAuxAntennaRxOkCnt) 

-			&& (priv->CurrAntennaIndex == 0))

-		{ // We set Main antenna as default but RxOk count was less than Aux ones.

-

-	//		printk("SwAntennaDiversity(): Main antenna RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n", 

-	//			priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);

-			

-			// Switch to Aux antenna.

-			SwitchAntenna(dev);	

-			priv->bHWAdSwitched = true;

-		}

-		else if((priv->AdAuxAntennaRxOkCnt < priv->AdMainAntennaRxOkCnt) 

-			&& (priv->CurrAntennaIndex == 1))

-		{ // We set Aux antenna as default but RxOk count was less than Main ones.

-

-	//		printk("SwAntennaDiversity(): Aux antenna RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n", 

-	//			priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);

-			

-			// Switch to Main antenna.

-			SwitchAntenna(dev);

-			priv->bHWAdSwitched = true;

-		}

-		else

-		{// Default antenna is better.

-

-	//		printk("SwAntennaDiversity(): Default antenna is better., AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n", 

-	//			priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);

-

-			// Still need to check current signal strength.

-			priv->bHWAdSwitched = false;	

-		}

-		//

-		// <Roger_Notes> We evaluate Rx signal strength ONLY when default antenna 

-		// didn't changed by HW evaluation. 

-		// 2008.02.27.

-		//

-		// [TRC Dell Lab] SignalStrength is inaccuracy. Isaiah 2008-03-05 

-		// For example, Throughput of aux is better than main antenna(about 10M v.s 2M), 

-		// but AdRxSignalStrength is less than main. 

-		// Our guess is that main antenna have lower throughput and get many change 

-		// to receive more CCK packets(ex.Beacon) which have stronger SignalStrength.

-		//

-		if( (!priv->bHWAdSwitched) && (bSwCheckSS))

-		{

-//by amy 080312}

-		// Evaluate Rx signal strength if we shall switch antenna now.

-		if(priv->AdRxSignalStrength < priv->AdRxSsThreshold)

-		{ // Rx signal strength is weak => Switch Antenna.

-//			printk("SwAntennaDiversity(): Rx Signal Strength is weak, CurrRxSs: %d, RxSsThreshold: %d\n", 

-//				priv->AdRxSignalStrength, priv->AdRxSsThreshold);	

-

-			priv->AdRxSsBeforeSwitched = priv->AdRxSignalStrength; 

-			priv->bAdSwitchedChecking = true;

-

-			SwitchAntenna(dev);

-		}

-		else

-		{ // Rx signal strength is OK. 

-//			printk("SwAntennaDiversity(): Rx Signal Strength is OK, CurrRxSs: %d, RxSsThreshold: %d\n", 

-//				priv->AdRxSignalStrength, priv->AdRxSsThreshold);

-

-			priv->bAdSwitchedChecking = false;

-			// Increase Rx signal strength threashold if necessary.

-			if(	(priv->AdRxSignalStrength > (priv->AdRxSsThreshold + 10)) && // Signal is much stronger than current threshold

-				priv->AdRxSsThreshold <= priv->AdMaxRxSsThreshold) // Current threhold is not yet reach upper limit.

-			{

-				priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2;

-				priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?

-												priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;//+by amy 080312

-			}

-

-			// Reduce Antenna Diversity checking period if possible. 

-			if( priv->AdCheckPeriod > priv->AdMinCheckPeriod )

-			{

-				priv->AdCheckPeriod /= 2; 

-			}

-		}

-		}

-	}

-//by amy 080312

-	// Reset antenna diversity Rx related statistics.

-	priv->AdRxOkCnt = 0;

-	priv->AdMainAntennaRxOkCnt = 0;

-	priv->AdAuxAntennaRxOkCnt = 0;

-//by amy 080312

-

-//	priv->AdRxOkCnt = 0;//-by amy 080312

-

-//	printk("-SwAntennaDiversity()\n");

-}

-

-//

-//	Description:

-//		Return TRUE if we shall perform Tx Power Tracking Mecahnism, FALSE otherwise.	

-//

-bool

-CheckTxPwrTracking(	struct net_device *dev)

-{

-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);

-

-	if(!priv->bTxPowerTrack)

-	{

-		return false;

-	}

-

-//lzm reserved 080826

-	//if(priv->bScanInProgress)

-	//{

-	//	return false;

-	//}

-

-	//if 87SE is in High Power , don't do Tx Power Tracking. asked by SD3 ED. 2008-08-08 Isaiah 

-	if(priv->bToUpdateTxPwr)

-	{

-		return false;

-	}

-		

-	return true;

-}

-

-

-//

-//	Description:

-//		Timer callback function of SW Antenna Diversity.

-//

-void

-SwAntennaDiversityTimerCallback(

-	struct net_device *dev

-	)

-{

-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);

-	RT_RF_POWER_STATE rtState;

-	

-	//printk("+SwAntennaDiversityTimerCallback()\n");

-

-	//

-	// We do NOT need to switch antenna while RF is off.

-	// 2007.05.09, added by Roger.

-	//

-	rtState = priv->eRFPowerState;

-	do{

-		if (rtState == eRfOff)

-		{	

-//			printk("SwAntennaDiversityTimer - RF is OFF.\n");

-			break;

-		}  	

-		else if (rtState == eRfSleep)

-		{	

-			// Don't access BB/RF under Disable PLL situation.

-			//RT_TRACE((COMP_RF|COMP_ANTENNA), DBG_LOUD, ("SwAntennaDiversityTimerCallback(): RF is Sleep => skip it\n"));

-			break;

-		}  

-		SwAntennaDiversity(dev);

-

-	}while(false);

-

-	if(priv->up)

-	{

-		priv->SwAntennaDiversityTimer.expires = jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD);

-		add_timer(&priv->SwAntennaDiversityTimer);

-	}

-

-	//printk("-SwAntennaDiversityTimerCallback()\n");

-}

-

+//#include "r8180.h"
+#include "r8180_dm.h"
+#include "r8180_hw.h"
+#include "r8180_93cx6.h"
+//{by amy 080312
+
+//
+//	Description:
+//		Return TRUE if we shall perform High Power Mecahnism, FALSE otherwise.
+//
+//+by amy 080312
+#define RATE_ADAPTIVE_TIMER_PERIOD      300
+
+bool CheckHighPower(struct net_device *dev)
+{
+	struct r8180_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_device *ieee = priv->ieee80211;
+
+	if(!priv->bRegHighPowerMechanism)
+	{
+		return false;
+	}
+
+	if(ieee->state == IEEE80211_LINKED_SCANNING)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+//
+//	Description:
+//		Update Tx power level if necessary.
+//		See also DoRxHighPower() and SetTxPowerLevel8185() for reference.
+//
+//	Note:
+//		The reason why we udpate Tx power level here instead of DoRxHighPower()
+//		is the number of IO to change Tx power is much more than chane TR switch
+//		and they are related to OFDM and MAC registers.
+//		So, we don't want to update it so frequently in per-Rx packet base.
+//
+void
+DoTxHighPower(
+	struct net_device *dev
+	)
+{
+	struct r8180_priv *priv = ieee80211_priv(dev);
+	u16			HiPwrUpperTh = 0;
+	u16			HiPwrLowerTh = 0;
+	u8			RSSIHiPwrUpperTh;
+	u8			RSSIHiPwrLowerTh;
+	u8			u1bTmp;
+	char			OfdmTxPwrIdx, CckTxPwrIdx;
+
+	//printk("----> DoTxHighPower()\n");
+
+	HiPwrUpperTh = priv->RegHiPwrUpperTh;
+	HiPwrLowerTh = priv->RegHiPwrLowerTh;
+
+	HiPwrUpperTh = HiPwrUpperTh * 10;
+	HiPwrLowerTh = HiPwrLowerTh * 10;
+	RSSIHiPwrUpperTh = priv->RegRSSIHiPwrUpperTh;
+	RSSIHiPwrLowerTh = priv->RegRSSIHiPwrLowerTh;
+
+	//lzm add 080826
+	OfdmTxPwrIdx  = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel];
+	CckTxPwrIdx  = priv->chtxpwr[priv->ieee80211->current_network.channel];
+
+	//	printk("DoTxHighPower() - UndecoratedSmoothedSS:%d, CurCCKRSSI = %d , bCurCCKPkt= %d \n", priv->UndecoratedSmoothedSS, priv->CurCCKRSSI, priv->bCurCCKPkt );
+
+	if((priv->UndecoratedSmoothedSS > HiPwrUpperTh) ||
+		(priv->bCurCCKPkt && (priv->CurCCKRSSI > RSSIHiPwrUpperTh)))
+	{
+		// Stevenl suggested that degrade 8dbm in high power sate. 2007-12-04 Isaiah
+
+	//	printk("=====>DoTxHighPower() - High Power - UndecoratedSmoothedSS:%d,  HiPwrUpperTh = %d \n", priv->UndecoratedSmoothedSS, HiPwrUpperTh );
+		priv->bToUpdateTxPwr = true;
+		u1bTmp= read_nic_byte(dev, CCK_TXAGC);
+
+		// If it never enter High Power.
+		if( CckTxPwrIdx == u1bTmp)
+		{
+		u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0;  // 8dbm
+		write_nic_byte(dev, CCK_TXAGC, u1bTmp);
+
+		u1bTmp= read_nic_byte(dev, OFDM_TXAGC);
+		u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0;  // 8dbm
+		write_nic_byte(dev, OFDM_TXAGC, u1bTmp);
+		}
+
+	}
+	else if((priv->UndecoratedSmoothedSS < HiPwrLowerTh) &&
+		(!priv->bCurCCKPkt || priv->CurCCKRSSI < RSSIHiPwrLowerTh))
+	{
+	//	 printk("DoTxHighPower() - lower Power - UndecoratedSmoothedSS:%d,  HiPwrUpperTh = %d \n", priv->UndecoratedSmoothedSS, HiPwrLowerTh );
+		if(priv->bToUpdateTxPwr)
+		{
+			priv->bToUpdateTxPwr = false;
+			//SD3 required.
+			u1bTmp= read_nic_byte(dev, CCK_TXAGC);
+			if(u1bTmp < CckTxPwrIdx)
+			{
+			//u1bTmp = ((u1bTmp+16) > 35) ? 35: (u1bTmp+16);  // 8dbm
+			//write_nic_byte(dev, CCK_TXAGC, u1bTmp);
+			write_nic_byte(dev, CCK_TXAGC, CckTxPwrIdx);
+			}
+
+			u1bTmp= read_nic_byte(dev, OFDM_TXAGC);
+			if(u1bTmp < OfdmTxPwrIdx)
+			{
+			//u1bTmp = ((u1bTmp+16) > 35) ? 35: (u1bTmp+16);  // 8dbm
+			//write_nic_byte(dev, OFDM_TXAGC, u1bTmp);
+			write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);
+			}
+		}
+	}
+
+	//printk("<---- DoTxHighPower()\n");
+}
+
+
+//
+//	Description:
+//		Callback function of UpdateTxPowerWorkItem.
+//		Because of some event happend, e.g. CCX TPC, High Power Mechanism,
+//		We update Tx power of current channel again.
+//
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void rtl8180_tx_pw_wq (struct work_struct *work)
+{
+//      struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
+//      struct ieee80211_device * ieee = (struct ieee80211_device*)
+//                                             container_of(work, struct ieee80211_device, watch_dog_wq);
+        struct delayed_work *dwork = container_of(work,struct delayed_work,work);
+        struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,tx_pw_wq);
+        struct net_device *dev = ieee->dev;
+#else
+void rtl8180_tx_pw_wq(struct net_device *dev)
+{
+	// struct r8180_priv *priv = ieee80211_priv(dev);
+#endif
+
+//	printk("----> UpdateTxPowerWorkItemCallback()\n");
+
+	DoTxHighPower(dev);
+
+//	printk("<---- UpdateTxPowerWorkItemCallback()\n");
+}
+
+
+//
+//	Description:
+//		Return TRUE if we shall perform DIG Mecahnism, FALSE otherwise.
+//
+bool
+CheckDig(
+	struct net_device *dev
+	)
+{
+	struct r8180_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_device *ieee = priv->ieee80211;
+
+	if(!priv->bDigMechanism)
+		return false;
+
+	if(ieee->state != IEEE80211_LINKED)
+		return false;
+
+	//if(priv->CurrentOperaRate < 36) // Schedule Dig under all OFDM rates. By Bruce, 2007-06-01.
+	if((priv->ieee80211->rate/5) < 36) // Schedule Dig under all OFDM rates. By Bruce, 2007-06-01.
+		return false;
+	return true;
+}
+//
+//	Description:
+//		Implementation of DIG for Zebra and Zebra2.
+//
+void
+DIG_Zebra(
+	struct net_device *dev
+	)
+{
+	struct r8180_priv *priv = ieee80211_priv(dev);
+	u16			CCKFalseAlarm, OFDMFalseAlarm;
+	u16			OfdmFA1, OfdmFA2;
+	int			InitialGainStep = 7; // The number of initial gain stages.
+	int			LowestGainStage = 4; // The capable lowest stage of performing dig workitem.
+	u32 			AwakePeriodIn2Sec=0;
+
+	//printk("---------> DIG_Zebra()\n");
+
+	CCKFalseAlarm = (u16)(priv->FalseAlarmRegValue & 0x0000ffff);
+	OFDMFalseAlarm = (u16)((priv->FalseAlarmRegValue >> 16) & 0x0000ffff);
+	OfdmFA1 =  0x15;
+	OfdmFA2 = ((u16)(priv->RegDigOfdmFaUpTh)) << 8;
+
+//	printk("DIG**********CCK False Alarm: %#X \n",CCKFalseAlarm);
+//	printk("DIG**********OFDM False Alarm: %#X \n",OFDMFalseAlarm);
+
+        // The number of initial gain steps is different, by Bruce, 2007-04-13.
+	if (priv->InitialGain == 0 ) //autoDIG
+	{ // Advised from SD3 DZ
+		priv->InitialGain = 4; // In 87B, m74dBm means State 4 (m82dBm)
+	}
+	//if(pHalData->VersionID != VERSION_8187B_B)
+	{ // Advised from SD3 DZ
+		OfdmFA1 =  0x20;
+	}
+
+#if 1 //lzm reserved 080826
+	AwakePeriodIn2Sec = (2000-priv ->DozePeriodInPast2Sec);
+	//printk("&&& DozePeriod=%d AwakePeriod=%d\n", priv->DozePeriodInPast2Sec, AwakePeriodIn2Sec);
+	priv ->DozePeriodInPast2Sec=0;
+
+	if(AwakePeriodIn2Sec)
+	{
+		//RT_TRACE(COMP_DIG, DBG_TRACE, ("DIG: AwakePeriodIn2Sec(%d) - FATh(0x%X , 0x%X) ->",AwakePeriodIn2Sec, OfdmFA1, OfdmFA2));
+		// adjuest DIG threshold.
+		OfdmFA1 =  (u16)((OfdmFA1*AwakePeriodIn2Sec)  / 2000) ;
+		OfdmFA2 =  (u16)((OfdmFA2*AwakePeriodIn2Sec)  / 2000) ;
+		//RT_TRACE(COMP_DIG, DBG_TRACE, ("( 0x%X , 0x%X)\n", OfdmFA1, OfdmFA2));
+	}
+	else
+	{
+		;//RT_TRACE(COMP_DIG, DBG_WARNING, ("ERROR!!  AwakePeriodIn2Sec should not be ZERO!!\n"));
+	}
+#endif
+
+	InitialGainStep = 8;
+	LowestGainStage = priv->RegBModeGainStage; // Lowest gain stage.
+
+	if (OFDMFalseAlarm > OfdmFA1)
+	{
+		if (OFDMFalseAlarm > OfdmFA2)
+		{
+			priv->DIG_NumberFallbackVote++;
+			if (priv->DIG_NumberFallbackVote >1)
+			{
+				//serious OFDM  False Alarm, need fallback
+				if (priv->InitialGain < InitialGainStep)
+				{
+					priv->InitialGainBackUp= priv->InitialGain;
+
+					priv->InitialGain = (priv->InitialGain + 1);
+//					printk("DIG**********OFDM False Alarm: %#X,  OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);
+//					printk("DIG+++++++ fallback OFDM:%d \n", priv->InitialGain);
+					UpdateInitialGain(dev);
+				}
+				priv->DIG_NumberFallbackVote = 0;
+				priv->DIG_NumberUpgradeVote=0;
+			}
+		}
+		else
+		{
+			if (priv->DIG_NumberFallbackVote)
+				priv->DIG_NumberFallbackVote--;
+		}
+		priv->DIG_NumberUpgradeVote=0;
+	}
+	else
+	{
+		if (priv->DIG_NumberFallbackVote)
+			priv->DIG_NumberFallbackVote--;
+		priv->DIG_NumberUpgradeVote++;
+
+		if (priv->DIG_NumberUpgradeVote>9)
+		{
+			if (priv->InitialGain > LowestGainStage) // In 87B, m78dBm means State 4 (m864dBm)
+			{
+				priv->InitialGainBackUp= priv->InitialGain;
+
+				priv->InitialGain = (priv->InitialGain - 1);
+//				printk("DIG**********OFDM False Alarm: %#X,  OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);
+//				printk("DIG--------- Upgrade OFDM:%d \n", priv->InitialGain);
+				UpdateInitialGain(dev);
+			}
+			priv->DIG_NumberFallbackVote = 0;
+			priv->DIG_NumberUpgradeVote=0;
+		}
+	}
+
+//	printk("DIG+++++++ OFDM:%d\n", priv->InitialGain);
+	//printk("<--------- DIG_Zebra()\n");
+}
+
+//
+//	Description:
+//		Dispatch DIG implementation according to RF.
+//
+void
+DynamicInitGain(
+	struct net_device *dev
+	)
+{
+	struct r8180_priv *priv = ieee80211_priv(dev);
+
+	switch(priv->rf_chip)
+	{
+		case RF_ZEBRA2:  // [AnnieWorkaround] For Zebra2, 2005-08-01.
+		case RF_ZEBRA4:
+			DIG_Zebra( dev );
+			break;
+
+		default:
+			printk("DynamicInitGain(): unknown RFChipID(%d) !!!\n", priv->rf_chip);
+			break;
+	}
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void rtl8180_hw_dig_wq (struct work_struct *work)
+{
+//      struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
+//      struct ieee80211_device * ieee = (struct ieee80211_device*)
+//                                             container_of(work, struct ieee80211_device, watch_dog_wq);
+        struct delayed_work *dwork = container_of(work,struct delayed_work,work);
+        struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_dig_wq);
+        struct net_device *dev = ieee->dev;
+#else
+void rtl8180_hw_dig_wq(struct net_device *dev)
+{
+
+#endif
+	struct r8180_priv *priv = ieee80211_priv(dev);
+
+	// Read CCK and OFDM False Alarm.
+	priv->FalseAlarmRegValue = read_nic_dword(dev, CCK_FALSE_ALARM);
+
+
+	// Adjust Initial Gain dynamically.
+	DynamicInitGain(dev);
+
+}
+
+int
+IncludedInSupportedRates(
+        struct r8180_priv       *priv,
+        u8              TxRate  )
+{
+    u8 rate_len;
+        u8 rate_ex_len;
+        u8                      RateMask = 0x7F;
+        u8                      idx;
+        unsigned short          Found = 0;
+        u8                      NaiveTxRate = TxRate&RateMask;
+
+    rate_len = priv->ieee80211->current_network.rates_len;
+        rate_ex_len = priv->ieee80211->current_network.rates_ex_len;
+        for( idx=0; idx< rate_len; idx++ )
+        {
+                if( (priv->ieee80211->current_network.rates[idx] & RateMask) == NaiveTxRate )
+                {
+                        Found = 1;
+                        goto found_rate;
+                }
+        }
+    for( idx=0; idx< rate_ex_len; idx++ )
+        {
+                if( (priv->ieee80211->current_network.rates_ex[idx] & RateMask) == NaiveTxRate )
+                {
+                        Found = 1;
+                        goto found_rate;
+                }
+        }
+        return Found;
+        found_rate:
+        return Found;
+}
+
+//
+//      Description:
+//              Get the Tx rate one degree up form the input rate in the supported rates.
+//              Return the upgrade rate if it is successed, otherwise return the input rate.
+//      By Bruce, 2007-06-05.
+//
+u8
+GetUpgradeTxRate(
+        struct net_device *dev,
+        u8                              rate
+        )
+{
+        struct r8180_priv *priv = ieee80211_priv(dev);
+        u8                      UpRate;
+
+        // Upgrade 1 degree.
+        switch(rate)
+        {
+        case 108: // Up to 54Mbps.
+                UpRate = 108;
+                break;
+
+        case 96: // Up to 54Mbps.
+                UpRate = 108;
+                break;
+
+        case 72: // Up to 48Mbps.
+                UpRate = 96;
+                break;
+
+        case 48: // Up to 36Mbps.
+                UpRate = 72;
+                break;
+
+        case 36: // Up to 24Mbps.
+                UpRate = 48;
+                break;
+
+        case 22: // Up to 18Mbps.
+                UpRate = 36;
+                break;
+
+        case 11: // Up to 11Mbps.
+                UpRate = 22;
+                break;
+
+        case 4: // Up to 5.5Mbps.
+                UpRate = 11;
+                break;
+
+        case 2: // Up to 2Mbps.
+                UpRate = 4;
+                break;
+
+        default:
+                printk("GetUpgradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
+                return rate;
+        }
+        // Check if the rate is valid.
+        if(IncludedInSupportedRates(priv, UpRate))
+        {
+//              printk("GetUpgradeTxRate(): GetUpgrade Tx rate(%d) from %d !\n", UpRate, priv->CurrentOperaRate);
+                return UpRate;
+        }
+        else
+        {
+                //printk("GetUpgradeTxRate(): Tx rate (%d) is not in supported rates\n", UpRate);
+                return rate;
+        }
+        return rate;
+}
+//
+//      Description:
+//              Get the Tx rate one degree down form the input rate in the supported rates.
+//              Return the degrade rate if it is successed, otherwise return the input rate.
+//      By Bruce, 2007-06-05.
+//
+u8
+GetDegradeTxRate(
+        struct net_device *dev,
+        u8         rate
+        )
+{
+        struct r8180_priv *priv = ieee80211_priv(dev);
+        u8                      DownRate;
+
+        // Upgrade 1 degree.
+        switch(rate)
+        {
+        case 108: // Down to 48Mbps.
+                DownRate = 96;
+                break;
+
+        case 96: // Down to 36Mbps.
+                DownRate = 72;
+                break;
+
+        case 72: // Down to 24Mbps.
+                DownRate = 48;
+                break;
+
+        case 48: // Down to 18Mbps.
+                DownRate = 36;
+                break;
+
+        case 36: // Down to 11Mbps.
+                DownRate = 22;
+                break;
+
+        case 22: // Down to 5.5Mbps.
+                DownRate = 11;
+                break;
+
+        case 11: // Down to 2Mbps.
+                DownRate = 4;
+                break;
+
+        case 4: // Down to 1Mbps.
+                DownRate = 2;
+                break;
+
+        case 2: // Down to 1Mbps.
+                DownRate = 2;
+                break;
+
+        default:
+                printk("GetDegradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
+                return rate;
+        }
+        // Check if the rate is valid.
+        if(IncludedInSupportedRates(priv, DownRate))
+        {
+//              printk("GetDegradeTxRate(): GetDegrade Tx rate(%d) from %d!\n", DownRate, priv->CurrentOperaRate);
+                return DownRate;
+        }
+        else
+        {
+                //printk("GetDegradeTxRate(): Tx rate (%d) is not in supported rates\n", DownRate);
+                return rate;
+        }
+        return rate;
+}
+//
+//      Helper function to determine if specified data rate is
+//      CCK rate.
+//      2005.01.25, by rcnjko.
+//
+bool
+MgntIsCckRate(
+        u16     rate
+        )
+{
+        bool bReturn = false;
+
+        if((rate <= 22) && (rate != 12) && (rate != 18))
+        {
+                bReturn = true;
+        }
+
+        return bReturn;
+}
+#ifdef CONFIG_RTL818X_S
+//
+//	Description:
+//		Tx Power tracking mechanism routine on 87SE.
+// 	Created by Roger, 2007.12.11.
+//
+void
+TxPwrTracking87SE(
+	struct net_device *dev
+)
+{
+	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+	u8	tmpu1Byte, CurrentThermal, Idx;
+	char	CckTxPwrIdx, OfdmTxPwrIdx;
+	//u32	u4bRfReg;
+
+	tmpu1Byte = read_nic_byte(dev, EN_LPF_CAL);
+	CurrentThermal = (tmpu1Byte & 0xf0)>>4; //[ 7:4]: thermal meter indication.
+	CurrentThermal = (CurrentThermal>0x0c)? 0x0c:CurrentThermal;//lzm add 080826
+
+	//printk("TxPwrTracking87SE(): CurrentThermal(%d)\n", CurrentThermal);
+
+	if( CurrentThermal != priv->ThermalMeter)
+	{
+//		printk("TxPwrTracking87SE(): Thermal meter changed!!!\n");
+
+		// Update Tx Power level on each channel.
+		for(Idx = 1; Idx<15; Idx++)
+		{
+			CckTxPwrIdx = priv->chtxpwr[Idx];
+			OfdmTxPwrIdx = priv->chtxpwr_ofdm[Idx];
+
+			if( CurrentThermal > priv->ThermalMeter )
+			{ // higher thermal meter.
+				CckTxPwrIdx += (CurrentThermal - priv->ThermalMeter)*2;
+				OfdmTxPwrIdx += (CurrentThermal - priv->ThermalMeter)*2;
+
+				if(CckTxPwrIdx >35)
+					CckTxPwrIdx = 35; // Force TxPower to maximal index.
+				if(OfdmTxPwrIdx >35)
+					OfdmTxPwrIdx = 35;
+			}
+			else
+			{ // lower thermal meter.
+				CckTxPwrIdx -= (priv->ThermalMeter - CurrentThermal)*2;
+				OfdmTxPwrIdx -= (priv->ThermalMeter - CurrentThermal)*2;
+
+				if(CckTxPwrIdx <0)
+					CckTxPwrIdx = 0;
+				if(OfdmTxPwrIdx <0)
+					OfdmTxPwrIdx = 0;
+			}
+
+			// Update TxPower level on CCK and OFDM resp.
+			priv->chtxpwr[Idx] = CckTxPwrIdx;
+			priv->chtxpwr_ofdm[Idx] = OfdmTxPwrIdx;
+		}
+
+		// Update TxPower level immediately.
+		rtl8225z2_SetTXPowerLevel(dev, priv->ieee80211->current_network.channel);
+	}
+	priv->ThermalMeter = CurrentThermal;
+}
+void
+StaRateAdaptive87SE(
+	struct net_device *dev
+	)
+{
+	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+	unsigned long 			CurrTxokCnt;
+	u16			CurrRetryCnt;
+	u16			CurrRetryRate;
+	//u16			i,idx;
+	unsigned long       	CurrRxokCnt;
+	bool			bTryUp = false;
+	bool			bTryDown = false;
+	u8			TryUpTh = 1;
+	u8			TryDownTh = 2;
+	u32			TxThroughput;
+	long		CurrSignalStrength;
+	bool		bUpdateInitialGain = false;
+    	u8			u1bOfdm=0, u1bCck = 0;
+	char		OfdmTxPwrIdx, CckTxPwrIdx;
+
+	priv->RateAdaptivePeriod= RATE_ADAPTIVE_TIMER_PERIOD;
+
+
+	CurrRetryCnt	= priv->CurrRetryCnt;
+	CurrTxokCnt	= priv->NumTxOkTotal - priv->LastTxokCnt;
+	CurrRxokCnt	= priv->ieee80211->NumRxOkTotal - priv->LastRxokCnt;
+	CurrSignalStrength = priv->Stats_RecvSignalPower;
+	TxThroughput = (u32)(priv->NumTxOkBytesTotal - priv->LastTxOKBytes);
+	priv->LastTxOKBytes = priv->NumTxOkBytesTotal;
+	priv->CurrentOperaRate = priv->ieee80211->rate/5;
+	//printk("priv->CurrentOperaRate is %d\n",priv->CurrentOperaRate);
+	//2 Compute retry ratio.
+	if (CurrTxokCnt>0)
+	{
+		CurrRetryRate = (u16)(CurrRetryCnt*100/CurrTxokCnt);
+	}
+	else
+	{ // It may be serious retry. To distinguish serious retry or no packets modified by Bruce
+		CurrRetryRate = (u16)(CurrRetryCnt*100/1);
+	}
+
+
+	//
+	// Added by Roger, 2007.01.02.
+	// For debug information.
+	//
+	//printk("\n(1) pHalData->LastRetryRate: %d \n",priv->LastRetryRate);
+	//printk("(2) RetryCnt = %d  \n", CurrRetryCnt);
+	//printk("(3) TxokCnt = %d \n", CurrTxokCnt);
+	//printk("(4) CurrRetryRate = %d \n", CurrRetryRate);
+	//printk("(5) CurrSignalStrength = %d \n",CurrSignalStrength);
+	//printk("(6) TxThroughput is %d\n",TxThroughput);
+	//printk("priv->NumTxOkBytesTotal is %d\n",priv->NumTxOkBytesTotal);
+
+	priv->LastRetryCnt = priv->CurrRetryCnt;
+	priv->LastTxokCnt = priv->NumTxOkTotal;
+	priv->LastRxokCnt = priv->ieee80211->NumRxOkTotal;
+	priv->CurrRetryCnt = 0;
+
+	//2No Tx packets, return to init_rate or not?
+	if (CurrRetryRate==0 && CurrTxokCnt == 0)
+	{
+		//
+		//After 9 (30*300ms) seconds in this condition, we try to raise rate.
+		//
+		priv->TryupingCountNoData++;
+
+//		printk("No Tx packets, TryupingCountNoData(%d)\n", priv->TryupingCountNoData);
+		//[TRC Dell Lab] Extend raised period from 4.5sec to 9sec, Isaiah 2008-02-15 18:00
+		if (priv->TryupingCountNoData>30)
+		{
+			priv->TryupingCountNoData = 0;
+		 	priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
+			// Reset Fail Record
+			priv->LastFailTxRate = 0;
+			priv->LastFailTxRateSS = -200;
+			priv->FailTxRateCount = 0;
+		}
+		goto SetInitialGain;
+	}
+        else
+	{
+		priv->TryupingCountNoData=0; //Reset trying up times.
+	}
+
+
+	//
+	// For Netgear case, I comment out the following signal strength estimation,
+	// which can results in lower rate to transmit when sample is NOT enough (e.g. PING request).
+	// 2007.04.09, by Roger.
+	//
+
+	//
+	// Restructure rate adaptive as the following main stages:
+	// (1) Add retry threshold in 54M upgrading condition with signal strength.
+	// (2) Add the mechanism to degrade to CCK rate according to signal strength
+	//		and retry rate.
+	// (3) Remove all Initial Gain Updates over OFDM rate. To avoid the complicated
+	//		situation, Initial Gain Update is upon on DIG mechanism except CCK rate.
+	// (4) Add the mehanism of trying to upgrade tx rate.
+	// (5) Record the information of upping tx rate to avoid trying upping tx rate constantly.
+	// By Bruce, 2007-06-05.
+	//
+	//
+
+	// 11Mbps or 36Mbps
+	// Check more times in these rate(key rates).
+	//
+	if(priv->CurrentOperaRate == 22 || priv->CurrentOperaRate == 72)
+	{
+		TryUpTh += 9;
+	}
+	//
+	// Let these rates down more difficult.
+	//
+	if(MgntIsCckRate(priv->CurrentOperaRate) || priv->CurrentOperaRate == 36)
+	{
+			TryDownTh += 1;
+	}
+
+	//1 Adjust Rate.
+	if (priv->bTryuping == true)
+	{
+		//2 For Test Upgrading mechanism
+		// Note:
+		// 	Sometimes the throughput is upon on the capability bwtween the AP and NIC,
+		// 	thus the low data rate does not improve the performance.
+		// 	We randomly upgrade the data rate and check if the retry rate is improved.
+
+		// Upgrading rate did not improve the retry rate, fallback to the original rate.
+		if ( (CurrRetryRate > 25) && TxThroughput < priv->LastTxThroughput)
+		{
+			//Not necessary raising rate, fall back rate.
+			bTryDown = true;
+			//printk("case1-1: Not necessary raising rate, fall back rate....\n");
+			//printk("case1-1: pMgntInfo->CurrentOperaRate =%d, TxThroughput = %d, LastThroughput = %d\n",
+			//		priv->CurrentOperaRate, TxThroughput, priv->LastTxThroughput);
+		}
+		else
+		{
+			priv->bTryuping = false;
+		}
+	}
+	else if (CurrSignalStrength > -47 && (CurrRetryRate < 50))
+	{
+		//2For High Power
+		//
+		// Added by Roger, 2007.04.09.
+		// Return to highest data rate, if signal strength is good enough.
+		// SignalStrength threshold(-50dbm) is for RTL8186.
+		// Revise SignalStrength threshold to -51dbm.
+		//
+		// Also need to check retry rate for safety, by Bruce, 2007-06-05.
+		if(priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate )
+		{
+			bTryUp = true;
+			// Upgrade Tx Rate directly.
+			priv->TryupingCount += TryUpTh;
+		}
+//		printk("case2: StaRateAdaptive87SE: Power(%d) is high enough!!. \n", CurrSignalStrength);
+
+	}
+	else if(CurrTxokCnt > 9 && CurrTxokCnt< 100 && CurrRetryRate >= 600)
+	{
+		//2 For Serious Retry
+		//
+		// Traffic is not busy but our Tx retry is serious.
+		//
+		bTryDown = true;
+		// Let Rate Mechanism to degrade tx rate directly.
+		priv->TryDownCountLowData += TryDownTh;
+//		printk("case3: RA: Tx Retry is serious. Degrade Tx Rate to %d directly...\n", priv->CurrentOperaRate);
+	}
+	else if ( priv->CurrentOperaRate == 108 )
+	{
+		//2For 54Mbps
+		// Air Link
+		if ( (CurrRetryRate>26)&&(priv->LastRetryRate>25))
+//		if ( (CurrRetryRate>40)&&(priv->LastRetryRate>39))
+		{
+			//Down to rate 48Mbps.
+			bTryDown = true;
+		}
+		// Cable Link
+		else if ( (CurrRetryRate>17)&&(priv->LastRetryRate>16) && (CurrSignalStrength > -72))
+//		else if ( (CurrRetryRate>17)&&(priv->LastRetryRate>16) && (CurrSignalStrength > -72))
+		{
+			//Down to rate 48Mbps.
+			bTryDown = true;
+		}
+
+		if(bTryDown && (CurrSignalStrength < -75)) //cable link
+		{
+			priv->TryDownCountLowData += TryDownTh;
+		}
+		//printk("case4---54M \n");
+
+	}
+	else if ( priv->CurrentOperaRate == 96 )
+	{
+		//2For 48Mbps
+		//Air Link
+		if ( ((CurrRetryRate>48) && (priv->LastRetryRate>47)))
+//		if ( ((CurrRetryRate>65) && (priv->LastRetryRate>64)))
+
+		{
+			//Down to rate 36Mbps.
+			bTryDown = true;
+		}
+		//Cable Link
+		else if ( ((CurrRetryRate>21) && (priv->LastRetryRate>20)) && (CurrSignalStrength > -74))
+		{
+			//Down to rate 36Mbps.
+			bTryDown = true;
+		}
+		else if((CurrRetryRate>  (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
+//		else if((CurrRetryRate>  (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
+		{
+			bTryDown = true;
+			priv->TryDownCountLowData += TryDownTh;
+		}
+		else if ( (CurrRetryRate<8) && (priv->LastRetryRate<8) ) //TO DO: need to consider (RSSI)
+//		else if ( (CurrRetryRate<28) && (priv->LastRetryRate<8) )
+		{
+			bTryUp = true;
+		}
+
+		if(bTryDown && (CurrSignalStrength < -75))
+		{
+			priv->TryDownCountLowData += TryDownTh;
+		}
+		//printk("case5---48M \n");
+	}
+	else if ( priv->CurrentOperaRate == 72 )
+	{
+		//2For 36Mbps
+		if ( (CurrRetryRate>43) && (priv->LastRetryRate>41))
+//		if ( (CurrRetryRate>60) && (priv->LastRetryRate>59))
+		{
+			//Down to rate 24Mbps.
+			bTryDown = true;
+		}
+		else if((CurrRetryRate>  (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
+//		else if((CurrRetryRate>  (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
+		{
+			bTryDown = true;
+			priv->TryDownCountLowData += TryDownTh;
+		}
+		else if ( (CurrRetryRate<15) &&  (priv->LastRetryRate<16)) //TO DO: need to consider (RSSI)
+//		else if ( (CurrRetryRate<35) &&  (priv->LastRetryRate<36))
+		{
+			bTryUp = true;
+		}
+
+		if(bTryDown && (CurrSignalStrength < -80))
+		{
+			priv->TryDownCountLowData += TryDownTh;
+		}
+		//printk("case6---36M \n");
+	}
+	else if ( priv->CurrentOperaRate == 48 )
+	{
+		//2For 24Mbps
+		// Air Link
+		if ( ((CurrRetryRate>63) && (priv->LastRetryRate>62)))
+//		if ( ((CurrRetryRate>83) && (priv->LastRetryRate>82)))
+		{
+			//Down to rate 18Mbps.
+			bTryDown = true;
+		}
+		//Cable Link
+		else if ( ((CurrRetryRate>33) && (priv->LastRetryRate>32)) && (CurrSignalStrength > -82) )
+//		 else if ( ((CurrRetryRate>50) && (priv->LastRetryRate>49)) && (CurrSignalStrength > -82) )
+		{
+			//Down to rate 18Mbps.
+			bTryDown = true;
+		}
+		else if((CurrRetryRate>  (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
+//		else if((CurrRetryRate>  (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
+
+		{
+			bTryDown = true;
+			priv->TryDownCountLowData += TryDownTh;
+		}
+  		else if ( (CurrRetryRate<20) && (priv->LastRetryRate<21)) //TO DO: need to consider (RSSI)
+//		else if ( (CurrRetryRate<40) && (priv->LastRetryRate<41))
+		{
+			bTryUp = true;
+		}
+
+		if(bTryDown && (CurrSignalStrength < -82))
+		{
+			priv->TryDownCountLowData += TryDownTh;
+		}
+		//printk("case7---24M \n");
+	}
+	else if ( priv->CurrentOperaRate == 36 )
+	{
+		//2For 18Mbps
+		// original (109, 109)
+		//[TRC Dell Lab] (90, 91), Isaiah 2008-02-18 23:24
+		//			     (85, 86), Isaiah 2008-02-18 24:00
+		if ( ((CurrRetryRate>85) && (priv->LastRetryRate>86)))
+//		if ( ((CurrRetryRate>115) && (priv->LastRetryRate>116)))
+		{
+			//Down to rate 11Mbps.
+			bTryDown = true;
+		}
+		//[TRC Dell Lab]  Isaiah 2008-02-18 23:24
+		else if((CurrRetryRate>  (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
+//		else if((CurrRetryRate>  (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
+		{
+			bTryDown = true;
+			priv->TryDownCountLowData += TryDownTh;
+		}
+		else if ( (CurrRetryRate<22) && (priv->LastRetryRate<23)) //TO DO: need to consider (RSSI)
+//		else if ( (CurrRetryRate<42) && (priv->LastRetryRate<43))
+		{
+			bTryUp = true;
+		}
+		//printk("case8---18M \n");
+	}
+	else if ( priv->CurrentOperaRate == 22 )
+	{
+		//2For 11Mbps
+		if (CurrRetryRate>95)
+//		if (CurrRetryRate>155)
+		{
+			bTryDown = true;
+		}
+		else if ( (CurrRetryRate<29) && (priv->LastRetryRate <30) )//TO DO: need to consider (RSSI)
+//		else if ( (CurrRetryRate<49) && (priv->LastRetryRate <50) )
+			{
+			bTryUp = true;
+			}
+		//printk("case9---11M \n");
+		}
+	else if ( priv->CurrentOperaRate == 11 )
+	{
+		//2For 5.5Mbps
+		if (CurrRetryRate>149)
+//		if (CurrRetryRate>189)
+		{
+			bTryDown = true;
+		}
+		else if ( (CurrRetryRate<60) && (priv->LastRetryRate < 65))
+//		else if ( (CurrRetryRate<80) && (priv->LastRetryRate < 85))
+
+			{
+			bTryUp = true;
+			}
+		//printk("case10---5.5M \n");
+		}
+	else if ( priv->CurrentOperaRate == 4 )
+	{
+		//2For 2 Mbps
+		if((CurrRetryRate>99) && (priv->LastRetryRate>99))
+//		if((CurrRetryRate>199) && (priv->LastRetryRate>199))
+		{
+			bTryDown = true;
+		}
+		else if ( (CurrRetryRate < 65) && (priv->LastRetryRate < 70))
+//		else if ( (CurrRetryRate < 85) && (priv->LastRetryRate < 90))
+		{
+			bTryUp = true;
+		}
+		//printk("case11---2M \n");
+	}
+	else if ( priv->CurrentOperaRate == 2 )
+	{
+		//2For 1 Mbps
+		if( (CurrRetryRate<70) && (priv->LastRetryRate<75))
+//		if( (CurrRetryRate<90) && (priv->LastRetryRate<95))
+		{
+			bTryUp = true;
+		}
+		//printk("case12---1M \n");
+	}
+
+	if(bTryUp && bTryDown)
+    	printk("StaRateAdaptive87B(): Tx Rate tried upping and downing simultaneously!\n");
+
+	//1 Test Upgrading Tx Rate
+	// Sometimes the cause of the low throughput (high retry rate) is the compatibility between the AP and NIC.
+	// To test if the upper rate may cause lower retry rate, this mechanism randomly occurs to test upgrading tx rate.
+	if(!bTryUp && !bTryDown && (priv->TryupingCount == 0) && (priv->TryDownCountLowData == 0)
+		&& priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate && priv->FailTxRateCount < 2)
+	{
+		if(jiffies% (CurrRetryRate + 101) == 0)
+		{
+			bTryUp = true;
+			priv->bTryuping = true;
+			//printk("StaRateAdaptive87SE(): Randomly try upgrading...\n");
+		}
+	}
+
+	//1 Rate Mechanism
+	if(bTryUp)
+	{
+		priv->TryupingCount++;
+		priv->TryDownCountLowData = 0;
+
+		{
+//			printk("UP: pHalData->TryupingCount = %d\n", priv->TryupingCount);
+//			printk("UP: TryUpTh(%d)+ (FailTxRateCount(%d))^2 =%d\n",
+//				TryUpTh, priv->FailTxRateCount, (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount) );
+//			printk("UP: pHalData->bTryuping=%d\n",  priv->bTryuping);
+
+		}
+
+		//
+		// Check more times if we need to upgrade indeed.
+		// Because the largest value of pHalData->TryupingCount is 0xFFFF and
+		// the largest value of pHalData->FailTxRateCount is 0x14,
+		// this condition will be satisfied at most every 2 min.
+		//
+
+		if((priv->TryupingCount > (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount)) ||
+			(CurrSignalStrength > priv->LastFailTxRateSS) || priv->bTryuping)
+		{
+			priv->TryupingCount = 0;
+			//
+			// When transfering from CCK to OFDM, DIG is an important issue.
+			//
+			if(priv->CurrentOperaRate == 22)
+				bUpdateInitialGain = true;
+
+			// The difference in throughput between 48Mbps and 36Mbps is 8M.
+			// So, we must be carefully in this rate scale. Isaiah 2008-02-15.
+			//
+			if(  ((priv->CurrentOperaRate == 72) || (priv->CurrentOperaRate == 48) || (priv->CurrentOperaRate == 36)) &&
+				(priv->FailTxRateCount > 2) )
+				priv->RateAdaptivePeriod= (RATE_ADAPTIVE_TIMER_PERIOD/2);
+
+			// (1)To avoid upgrade frequently to the fail tx rate, add the FailTxRateCount into the threshold.
+			// (2)If the signal strength is increased, it may be able to upgrade.
+
+			priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
+//			printk("StaRateAdaptive87SE(): Upgrade Tx Rate to %d\n", priv->CurrentOperaRate);
+
+			//[TRC Dell Lab] Bypass 12/9/6, Isaiah 2008-02-18 20:00
+			if(priv->CurrentOperaRate ==36)
+			{
+				priv->bUpdateARFR=true;
+				write_nic_word(dev, ARFR, 0x0F8F); //bypass 12/9/6
+//				printk("UP: ARFR=0xF8F\n");
+			}
+			else if(priv->bUpdateARFR)
+			{
+				priv->bUpdateARFR=false;
+				write_nic_word(dev, ARFR, 0x0FFF); //set 1M ~ 54Mbps.
+//				printk("UP: ARFR=0xFFF\n");
+			}
+
+			// Update Fail Tx rate and count.
+			if(priv->LastFailTxRate != priv->CurrentOperaRate)
+			{
+				priv->LastFailTxRate = priv->CurrentOperaRate;
+				priv->FailTxRateCount = 0;
+				priv->LastFailTxRateSS = -200; // Set lowest power.
+			}
+		}
+	}
+	else
+	{
+		if(priv->TryupingCount > 0)
+			priv->TryupingCount --;
+	}
+
+	if(bTryDown)
+	{
+		priv->TryDownCountLowData++;
+		priv->TryupingCount = 0;
+		{
+//			printk("DN: pHalData->TryDownCountLowData = %d\n",priv->TryDownCountLowData);
+//			printk("DN: TryDownTh =%d\n", TryDownTh);
+//			printk("DN: pHalData->bTryuping=%d\n",  priv->bTryuping);
+		}
+
+		//Check if Tx rate can be degraded or Test trying upgrading should fallback.
+		if(priv->TryDownCountLowData > TryDownTh || priv->bTryuping)
+		{
+			priv->TryDownCountLowData = 0;
+			priv->bTryuping = false;
+			// Update fail information.
+			if(priv->LastFailTxRate == priv->CurrentOperaRate)
+			{
+				priv->FailTxRateCount ++;
+				// Record the Tx fail rate signal strength.
+				if(CurrSignalStrength > priv->LastFailTxRateSS)
+				{
+					priv->LastFailTxRateSS = CurrSignalStrength;
+				}
+			}
+			else
+			{
+				priv->LastFailTxRate = priv->CurrentOperaRate;
+				priv->FailTxRateCount = 1;
+				priv->LastFailTxRateSS = CurrSignalStrength;
+			}
+			priv->CurrentOperaRate = GetDegradeTxRate(dev, priv->CurrentOperaRate);
+
+			// Reduce chariot training time at weak signal strength situation. SD3 ED demand.
+			//[TRC Dell Lab] Revise Signal Threshold from -75 to -80 , Isaiah 2008-02-18 20:00
+			if( (CurrSignalStrength < -80) && (priv->CurrentOperaRate > 72 ))
+			{
+				priv->CurrentOperaRate = 72;
+//				printk("DN: weak signal strength (%d), degrade to 36Mbps\n", CurrSignalStrength);
+			}
+
+			//[TRC Dell Lab] Bypass 12/9/6, Isaiah 2008-02-18 20:00
+			if(priv->CurrentOperaRate ==36)
+			{
+				priv->bUpdateARFR=true;
+				write_nic_word(dev, ARFR, 0x0F8F); //bypass 12/9/6
+//				printk("DN: ARFR=0xF8F\n");
+			}
+			else if(priv->bUpdateARFR)
+			{
+				priv->bUpdateARFR=false;
+				write_nic_word(dev, ARFR, 0x0FFF); //set 1M ~ 54Mbps.
+//				printk("DN: ARFR=0xFFF\n");
+			}
+
+			//
+			// When it is CCK rate, it may need to update initial gain to receive lower power packets.
+			//
+			if(MgntIsCckRate(priv->CurrentOperaRate))
+			{
+				bUpdateInitialGain = true;
+			}
+//			printk("StaRateAdaptive87SE(): Degrade Tx Rate to %d\n", priv->CurrentOperaRate);
+		}
+	}
+	else
+	{
+		if(priv->TryDownCountLowData > 0)
+			priv->TryDownCountLowData --;
+	}
+
+	// Keep the Tx fail rate count to equal to 0x15 at most.
+	// Reduce the fail count at least to 10 sec if tx rate is tending stable.
+	if(priv->FailTxRateCount >= 0x15 ||
+		(!bTryUp && !bTryDown && priv->TryDownCountLowData == 0 && priv->TryupingCount && priv->FailTxRateCount > 0x6))
+	{
+		priv->FailTxRateCount --;
+	}
+
+
+	OfdmTxPwrIdx  = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel];
+	CckTxPwrIdx  = priv->chtxpwr[priv->ieee80211->current_network.channel];
+
+	//[TRC Dell Lab] Mac0x9e increase 2 level in 36M~18M situation, Isaiah 2008-02-18 24:00
+	if((priv->CurrentOperaRate < 96) &&(priv->CurrentOperaRate > 22))
+	{
+		u1bCck = read_nic_byte(dev, CCK_TXAGC);
+		u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);
+
+		// case 1: Never enter High power
+		if(u1bCck == CckTxPwrIdx )
+		{
+			if(u1bOfdm != (OfdmTxPwrIdx+2) )
+			{
+			priv->bEnhanceTxPwr= true;
+			u1bOfdm = ((u1bOfdm+2) > 35) ? 35: (u1bOfdm+2);
+			write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
+//			printk("Enhance OFDM_TXAGC : +++++ u1bOfdm= 0x%x\n", u1bOfdm);
+			}
+		}
+		// case 2: enter high power
+		else if(u1bCck < CckTxPwrIdx)
+		{
+			if(!priv->bEnhanceTxPwr)
+			{
+				priv->bEnhanceTxPwr= true;
+				u1bOfdm = ((u1bOfdm+2) > 35) ? 35: (u1bOfdm+2);
+				write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
+				//RT_TRACE(COMP_RATE, DBG_TRACE, ("Enhance OFDM_TXAGC(2) : +++++ u1bOfdm= 0x%x\n", u1bOfdm));
+			}
+		}
+	}
+	else if(priv->bEnhanceTxPwr)  //54/48/11/5.5/2/1
+	{
+		u1bCck = read_nic_byte(dev, CCK_TXAGC);
+		u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);
+
+		// case 1: Never enter High power
+		if(u1bCck == CckTxPwrIdx )
+		{
+		priv->bEnhanceTxPwr= false;
+		write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);
+		//printk("Recover OFDM_TXAGC : ===== u1bOfdm= 0x%x\n", OfdmTxPwrIdx);
+		}
+		// case 2: enter high power
+		else if(u1bCck < CckTxPwrIdx)
+		{
+			priv->bEnhanceTxPwr= false;
+			u1bOfdm = ((u1bOfdm-2) > 0) ? (u1bOfdm-2): 0;
+			write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
+			//RT_TRACE(COMP_RATE, DBG_TRACE, ("Recover OFDM_TXAGC(2): ===== u1bOfdm= 0x%x\n", u1bOfdm));
+
+		}
+	}
+
+	//
+	// We need update initial gain when we set tx rate "from OFDM to CCK" or
+	// "from CCK to OFDM".
+	//
+SetInitialGain:
+	if(bUpdateInitialGain)
+	{
+		if(MgntIsCckRate(priv->CurrentOperaRate)) // CCK
+		{
+			if(priv->InitialGain > priv->RegBModeGainStage)
+			{
+				priv->InitialGainBackUp= priv->InitialGain;
+
+				if(CurrSignalStrength < -85) // Low power, OFDM [0x17] = 26.
+				{
+					//SD3 SYs suggest that CurrSignalStrength < -65, ofdm 0x17=26.
+					priv->InitialGain = priv->RegBModeGainStage;
+				}
+				else if(priv->InitialGain > priv->RegBModeGainStage + 1)
+				{
+					priv->InitialGain -= 2;
+				}
+				else
+				{
+					priv->InitialGain --;
+				}
+				printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);
+				UpdateInitialGain(dev);
+			}
+		}
+		else // OFDM
+		{
+			if(priv->InitialGain < 4)
+			{
+				priv->InitialGainBackUp= priv->InitialGain;
+
+				priv->InitialGain ++;
+				printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);
+				UpdateInitialGain(dev);
+			}
+		}
+	}
+
+	//Record the related info
+	priv->LastRetryRate = CurrRetryRate;
+	priv->LastTxThroughput = TxThroughput;
+	priv->ieee80211->rate = priv->CurrentOperaRate * 5;
+}
+
+#endif
+#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
+void rtl8180_rate_adapter(struct work_struct * work)
+{
+	struct delayed_work *dwork = container_of(work,struct delayed_work,work);
+        struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,rate_adapter_wq);
+        struct net_device *dev = ieee->dev;
+#else
+void rtl8180_rate_adapter(struct net_device *dev)
+{
+
+#endif
+        //struct r8180_priv *priv = ieee80211_priv(dev);
+//    DMESG("---->rtl8180_rate_adapter");
+        StaRateAdaptive87SE(dev);
+//   DMESG("<----rtl8180_rate_adapter");
+}
+void timer_rate_adaptive(unsigned long data)
+{
+	struct r8180_priv* priv = ieee80211_priv((struct net_device *)data);
+	//DMESG("---->timer_rate_adaptive()\n");
+	if(!priv->up)
+	{
+//		DMESG("<----timer_rate_adaptive():driver is not up!\n");
+		return;
+	}
+	if((priv->ieee80211->iw_mode != IW_MODE_MASTER)
+			&& (priv->ieee80211->state == IEEE80211_LINKED) &&
+			(priv->ForcedDataRate == 0) )
+	{
+//	DMESG("timer_rate_adaptive():schedule rate_adapter_wq\n");
+#ifdef CONFIG_RTL818X_S
+		queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->rate_adapter_wq);
+//		StaRateAdaptive87SE((struct net_device *)data);
+#endif
+	}
+	priv->rateadapter_timer.expires = jiffies + MSECS(priv->RateAdaptivePeriod);
+	add_timer(&priv->rateadapter_timer);
+	//DMESG("<----timer_rate_adaptive()\n");
+}
+//by amy 080312}
+void
+SwAntennaDiversityRxOk8185(
+	struct net_device *dev,
+	u8 SignalStrength
+	)
+{
+	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+
+//	printk("+SwAntennaDiversityRxOk8185: RxSs: %d\n", SignalStrength);
+
+	priv->AdRxOkCnt++;
+
+	if( priv->AdRxSignalStrength != -1)
+	{
+		priv->AdRxSignalStrength = ((priv->AdRxSignalStrength*7) + (SignalStrength*3)) / 10;
+	}
+	else
+	{ // Initialization case.
+		priv->AdRxSignalStrength = SignalStrength;
+	}
+//{+by amy 080312
+	if( priv->LastRxPktAntenna ) //Main antenna.
+		priv->AdMainAntennaRxOkCnt++;
+	else	 // Aux antenna.
+		priv->AdAuxAntennaRxOkCnt++;
+//+by amy 080312
+//	printk("-SwAntennaDiversityRxOk8185: AdRxOkCnt: %d AdRxSignalStrength: %d\n", priv->AdRxOkCnt, priv->AdRxSignalStrength);
+}
+//
+//	Description:
+//		Change Antenna Switch.
+//
+bool
+SetAntenna8185(
+	struct net_device *dev,
+	u8		u1bAntennaIndex
+	)
+{
+	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+	bool bAntennaSwitched = false;
+
+//	printk("+SetAntenna8185(): Antenna is switching to: %d \n", u1bAntennaIndex);
+
+	switch(u1bAntennaIndex)
+	{
+	case 0:
+		switch(priv->rf_chip)
+		{
+		case RF_ZEBRA2:
+		case RF_ZEBRA4:
+#ifdef CONFIG_RTL8185B
+#ifdef CONFIG_RTL818X_S
+			// Mac register, main antenna
+			write_nic_byte(dev, ANTSEL, 0x03);
+			//base band
+			write_phy_cck(dev,0x11, 0x9b); // Config CCK RX antenna.
+			write_phy_ofdm(dev, 0x0d, 0x5c); // Config OFDM RX antenna.
+
+#else
+			// Mac register, main antenna
+			write_nic_byte(dev, ANTSEL, 0x03);
+			//base band
+			write_phy_cck(dev, 0x10, 0x9b); // Config CCK RX antenna.
+			write_phy_ofdm(dev, 0x0d, 0x5c); // Config OFDM RX antenna.
+#endif
+#endif
+
+			bAntennaSwitched = true;
+			break;
+
+		default:
+			printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);
+			break;
+		}
+		break;
+
+	case 1:
+		switch(priv->rf_chip)
+		{
+		case RF_ZEBRA2:
+		case RF_ZEBRA4:
+#ifdef CONFIG_RTL8185B
+#ifdef CONFIG_RTL818X_S
+			// Mac register, aux antenna
+			write_nic_byte(dev, ANTSEL, 0x00);
+			//base band
+			write_phy_cck(dev, 0x11, 0xbb); // Config CCK RX antenna.
+			write_phy_ofdm(dev, 0x0d, 0x54); // Config OFDM RX antenna.
+#else
+			// Mac register, aux antenna
+			write_nic_byte(dev, ANTSEL, 0x00);
+			//base band
+			write_phy_cck(dev, 0x10, 0xbb); // Config CCK RX antenna.
+			write_phy_ofdm(dev, 0x0d, 0x54); // Config OFDM RX antenna.
+#endif
+#endif
+
+			bAntennaSwitched = true;
+			break;
+
+		default:
+			printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);
+			break;
+		}
+		break;
+
+	default:
+		printk("SetAntenna8185: unkown u1bAntennaIndex(%d)\n", u1bAntennaIndex);
+		break;
+	}
+
+	if(bAntennaSwitched)
+	{
+		priv->CurrAntennaIndex = u1bAntennaIndex;
+	}
+
+//	printk("-SetAntenna8185(): return (%#X)\n", bAntennaSwitched);
+
+	return bAntennaSwitched;
+}
+//
+//	Description:
+//		Toggle Antenna switch.
+//
+bool
+SwitchAntenna(
+	struct net_device *dev
+	)
+{
+	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+
+	bool		bResult;
+
+	if(priv->CurrAntennaIndex == 0)
+	{
+#if 0//lzm del 080826
+//by amy 080312
+#ifdef CONFIG_RTL818X_S
+		if(priv->bSwAntennaDiverity)
+			bResult = SetAntennaConfig87SE(dev, 1, true);
+		else
+#endif
+#endif
+			bResult = SetAntenna8185(dev, 1);
+//by amy 080312
+//		printk("SwitchAntenna(): switching to antenna 1 ......\n");
+//		bResult = SetAntenna8185(dev, 1);//-by amy 080312
+	}
+	else
+	{
+#if 0//lzm del 080826
+//by amy 080312
+#ifdef CONFIG_RTL818X_S
+		if(priv->bSwAntennaDiverity)
+			bResult = SetAntennaConfig87SE(dev, 0, true);
+		else
+#endif
+#endif
+			bResult = SetAntenna8185(dev, 0);
+//by amy 080312
+//		printk("SwitchAntenna(): switching to antenna 0 ......\n");
+//		bResult = SetAntenna8185(dev, 0);//-by amy 080312
+	}
+
+	return bResult;
+}
+//
+//	Description:
+//		Engine of SW Antenna Diversity mechanism.
+//		Since 8187 has no Tx part information,
+//		this implementation is only dependend on Rx part information.
+//
+//	2006.04.17, by rcnjko.
+//
+void
+SwAntennaDiversity(
+	struct net_device *dev
+	)
+{
+	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+	bool   bSwCheckSS=false;
+//	printk("+SwAntennaDiversity(): CurrAntennaIndex: %d\n", priv->CurrAntennaIndex);
+//	printk("AdTickCount is %d\n",priv->AdTickCount);
+//by amy 080312
+	if(bSwCheckSS)
+	{
+		priv->AdTickCount++;
+
+		printk("(1) AdTickCount: %d, AdCheckPeriod: %d\n",
+			priv->AdTickCount, priv->AdCheckPeriod);
+		printk("(2) AdRxSignalStrength: %ld, AdRxSsThreshold: %ld\n",
+			priv->AdRxSignalStrength, priv->AdRxSsThreshold);
+	}
+//	priv->AdTickCount++;//-by amy 080312
+
+	// Case 1. No Link.
+	if(priv->ieee80211->state != IEEE80211_LINKED)
+	{
+	//	printk("SwAntennaDiversity(): Case 1. No Link.\n");
+
+		priv->bAdSwitchedChecking = false;
+		// I switch antenna here to prevent any one of antenna is broken before link established, 2006.04.18, by rcnjko..
+		SwitchAntenna(dev);
+	}
+	// Case 2. Linked but no packet received.
+	else if(priv->AdRxOkCnt == 0)
+	{
+	//	printk("SwAntennaDiversity(): Case 2. Linked but no packet received.\n");
+
+		priv->bAdSwitchedChecking = false;
+		SwitchAntenna(dev);
+	}
+	// Case 3. Evaluate last antenna switch action and undo it if necessary.
+	else if(priv->bAdSwitchedChecking == true)
+	{
+	//	printk("SwAntennaDiversity(): Case 3. Evaluate last antenna switch action.\n");
+
+		priv->bAdSwitchedChecking = false;
+
+		// Adjust Rx signal strength threashold.
+		priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2;
+
+		priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
+					priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;
+		if(priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched)
+		{ // Rx signal strength is not improved after we swtiched antenna. => Swich back.
+//			printk("SwAntennaDiversity(): Rx Signal Strength is not improved, CurrRxSs: %d, LastRxSs: %d\n",
+//				priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
+//by amy 080312
+			// Increase Antenna Diversity checking period due to bad decision.
+			priv->AdCheckPeriod *= 2;
+//by amy 080312
+			// Increase Antenna Diversity checking period.
+			if(priv->AdCheckPeriod > priv->AdMaxCheckPeriod)
+				priv->AdCheckPeriod = priv->AdMaxCheckPeriod;
+
+			// Wrong deceision => switch back.
+			SwitchAntenna(dev);
+		}
+		else
+		{ // Rx Signal Strength is improved.
+//			printk("SwAntennaDiversity(): Rx Signal Strength is improved, CurrRxSs: %d, LastRxSs: %d\n",
+//				priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
+
+			// Reset Antenna Diversity checking period to its min value.
+			priv->AdCheckPeriod = priv->AdMinCheckPeriod;
+		}
+
+//		printk("SwAntennaDiversity(): AdRxSsThreshold: %d, AdCheckPeriod: %d\n",
+//			priv->AdRxSsThreshold, priv->AdCheckPeriod);
+	}
+	// Case 4. Evaluate if we shall switch antenna now.
+	// Cause Table Speed is very fast in TRC Dell Lab, we check it every time.
+	else// if(priv->AdTickCount >= priv->AdCheckPeriod)//-by amy 080312
+	{
+//		printk("SwAntennaDiversity(): Case 4. Evaluate if we shall switch antenna now.\n");
+
+		priv->AdTickCount = 0;
+
+		//
+		// <Roger_Notes> We evaluate RxOk counts for each antenna first and than
+		// evaluate signal strength.
+		// The following operation can overcome the disability of CCA on both two antennas
+		// When signal strength was extremely low or high.
+		// 2008.01.30.
+		//
+
+		//
+		// Evaluate RxOk count from each antenna if we shall switch default antenna now.
+		// Added by Roger, 2008.02.21.
+//{by amy 080312
+		if((priv->AdMainAntennaRxOkCnt < priv->AdAuxAntennaRxOkCnt)
+			&& (priv->CurrAntennaIndex == 0))
+		{ // We set Main antenna as default but RxOk count was less than Aux ones.
+
+	//		printk("SwAntennaDiversity(): Main antenna RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
+	//			priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
+
+			// Switch to Aux antenna.
+			SwitchAntenna(dev);
+			priv->bHWAdSwitched = true;
+		}
+		else if((priv->AdAuxAntennaRxOkCnt < priv->AdMainAntennaRxOkCnt)
+			&& (priv->CurrAntennaIndex == 1))
+		{ // We set Aux antenna as default but RxOk count was less than Main ones.
+
+	//		printk("SwAntennaDiversity(): Aux antenna RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
+	//			priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
+
+			// Switch to Main antenna.
+			SwitchAntenna(dev);
+			priv->bHWAdSwitched = true;
+		}
+		else
+		{// Default antenna is better.
+
+	//		printk("SwAntennaDiversity(): Default antenna is better., AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
+	//			priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
+
+			// Still need to check current signal strength.
+			priv->bHWAdSwitched = false;
+		}
+		//
+		// <Roger_Notes> We evaluate Rx signal strength ONLY when default antenna
+		// didn't changed by HW evaluation.
+		// 2008.02.27.
+		//
+		// [TRC Dell Lab] SignalStrength is inaccuracy. Isaiah 2008-03-05
+		// For example, Throughput of aux is better than main antenna(about 10M v.s 2M),
+		// but AdRxSignalStrength is less than main.
+		// Our guess is that main antenna have lower throughput and get many change
+		// to receive more CCK packets(ex.Beacon) which have stronger SignalStrength.
+		//
+		if( (!priv->bHWAdSwitched) && (bSwCheckSS))
+		{
+//by amy 080312}
+		// Evaluate Rx signal strength if we shall switch antenna now.
+		if(priv->AdRxSignalStrength < priv->AdRxSsThreshold)
+		{ // Rx signal strength is weak => Switch Antenna.
+//			printk("SwAntennaDiversity(): Rx Signal Strength is weak, CurrRxSs: %d, RxSsThreshold: %d\n",
+//				priv->AdRxSignalStrength, priv->AdRxSsThreshold);
+
+			priv->AdRxSsBeforeSwitched = priv->AdRxSignalStrength;
+			priv->bAdSwitchedChecking = true;
+
+			SwitchAntenna(dev);
+		}
+		else
+		{ // Rx signal strength is OK.
+//			printk("SwAntennaDiversity(): Rx Signal Strength is OK, CurrRxSs: %d, RxSsThreshold: %d\n",
+//				priv->AdRxSignalStrength, priv->AdRxSsThreshold);
+
+			priv->bAdSwitchedChecking = false;
+			// Increase Rx signal strength threashold if necessary.
+			if(	(priv->AdRxSignalStrength > (priv->AdRxSsThreshold + 10)) && // Signal is much stronger than current threshold
+				priv->AdRxSsThreshold <= priv->AdMaxRxSsThreshold) // Current threhold is not yet reach upper limit.
+			{
+				priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2;
+				priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
+												priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;//+by amy 080312
+			}
+
+			// Reduce Antenna Diversity checking period if possible.
+			if( priv->AdCheckPeriod > priv->AdMinCheckPeriod )
+			{
+				priv->AdCheckPeriod /= 2;
+			}
+		}
+		}
+	}
+//by amy 080312
+	// Reset antenna diversity Rx related statistics.
+	priv->AdRxOkCnt = 0;
+	priv->AdMainAntennaRxOkCnt = 0;
+	priv->AdAuxAntennaRxOkCnt = 0;
+//by amy 080312
+
+//	priv->AdRxOkCnt = 0;//-by amy 080312
+
+//	printk("-SwAntennaDiversity()\n");
+}
+
+//
+//	Description:
+//		Return TRUE if we shall perform Tx Power Tracking Mecahnism, FALSE otherwise.
+//
+bool
+CheckTxPwrTracking(	struct net_device *dev)
+{
+	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+
+	if(!priv->bTxPowerTrack)
+	{
+		return false;
+	}
+
+//lzm reserved 080826
+	//if(priv->bScanInProgress)
+	//{
+	//	return false;
+	//}
+
+	//if 87SE is in High Power , don't do Tx Power Tracking. asked by SD3 ED. 2008-08-08 Isaiah
+	if(priv->bToUpdateTxPwr)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+
+//
+//	Description:
+//		Timer callback function of SW Antenna Diversity.
+//
+void
+SwAntennaDiversityTimerCallback(
+	struct net_device *dev
+	)
+{
+	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+	RT_RF_POWER_STATE rtState;
+
+	//printk("+SwAntennaDiversityTimerCallback()\n");
+
+	//
+	// We do NOT need to switch antenna while RF is off.
+	// 2007.05.09, added by Roger.
+	//
+	rtState = priv->eRFPowerState;
+	do{
+		if (rtState == eRfOff)
+		{
+//			printk("SwAntennaDiversityTimer - RF is OFF.\n");
+			break;
+		}
+		else if (rtState == eRfSleep)
+		{
+			// Don't access BB/RF under Disable PLL situation.
+			//RT_TRACE((COMP_RF|COMP_ANTENNA), DBG_LOUD, ("SwAntennaDiversityTimerCallback(): RF is Sleep => skip it\n"));
+			break;
+		}
+		SwAntennaDiversity(dev);
+
+	}while(false);
+
+	if(priv->up)
+	{
+		priv->SwAntennaDiversityTimer.expires = jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD);
+		add_timer(&priv->SwAntennaDiversityTimer);
+	}
+
+	//printk("-SwAntennaDiversityTimerCallback()\n");
+}
+
diff --git a/drivers/staging/rtl8187se/r8180_dm.h b/drivers/staging/rtl8187se/r8180_dm.h
index 3de92f0..b2736c8 100644
--- a/drivers/staging/rtl8187se/r8180_dm.h
+++ b/drivers/staging/rtl8187se/r8180_dm.h
@@ -1,41 +1,41 @@
-#ifndef R8180_DM_H 

-#define R8180_DM_H

-

-#include "r8180.h"

-//#include "r8180_hw.h"

-//#include "r8180_93cx6.h"

-void SwAntennaDiversityRxOk8185(struct net_device *dev, u8 SignalStrength);

-bool SetAntenna8185(struct net_device *dev,	u8 u1bAntennaIndex);

-bool SwitchAntenna(	struct net_device *dev);

-void SwAntennaDiversity(struct net_device *dev	);

-void SwAntennaDiversityTimerCallback(struct net_device *dev);

-bool CheckDig(struct net_device *dev);

-bool CheckHighPower(struct net_device *dev);

-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))

-void rtl8180_hw_dig_wq (struct work_struct *work);

-#else

-void rtl8180_hw_dig_wq(struct net_device *dev);

-#endif

-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))

-void rtl8180_tx_pw_wq (struct work_struct *work);

-#else

-void rtl8180_tx_pw_wq(struct net_device *dev);

-#endif

-#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)

-void rtl8180_rate_adapter(struct work_struct * work);

-

-#else

-void rtl8180_rate_adapter(struct net_device *dev);

-

-#endif

-void TxPwrTracking87SE(struct net_device *dev);

-bool CheckTxPwrTracking(struct net_device *dev);

-#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)

-void rtl8180_rate_adapter(struct work_struct * work);

-#else

-void rtl8180_rate_adapter(struct net_device *dev);

-#endif

-void timer_rate_adaptive(unsigned long data);

-

-

-#endif

+#ifndef R8180_DM_H
+#define R8180_DM_H
+
+#include "r8180.h"
+//#include "r8180_hw.h"
+//#include "r8180_93cx6.h"
+void SwAntennaDiversityRxOk8185(struct net_device *dev, u8 SignalStrength);
+bool SetAntenna8185(struct net_device *dev,	u8 u1bAntennaIndex);
+bool SwitchAntenna(	struct net_device *dev);
+void SwAntennaDiversity(struct net_device *dev	);
+void SwAntennaDiversityTimerCallback(struct net_device *dev);
+bool CheckDig(struct net_device *dev);
+bool CheckHighPower(struct net_device *dev);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void rtl8180_hw_dig_wq (struct work_struct *work);
+#else
+void rtl8180_hw_dig_wq(struct net_device *dev);
+#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void rtl8180_tx_pw_wq (struct work_struct *work);
+#else
+void rtl8180_tx_pw_wq(struct net_device *dev);
+#endif
+#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
+void rtl8180_rate_adapter(struct work_struct * work);
+
+#else
+void rtl8180_rate_adapter(struct net_device *dev);
+
+#endif
+void TxPwrTracking87SE(struct net_device *dev);
+bool CheckTxPwrTracking(struct net_device *dev);
+#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
+void rtl8180_rate_adapter(struct work_struct * work);
+#else
+void rtl8180_rate_adapter(struct net_device *dev);
+#endif
+void timer_rate_adaptive(unsigned long data);
+
+
+#endif
diff --git a/drivers/staging/rtl8187se/r8180_wx.c b/drivers/staging/rtl8187se/r8180_wx.c
index 8b3901d..979ba0b 100644
--- a/drivers/staging/rtl8187se/r8180_wx.c
+++ b/drivers/staging/rtl8187se/r8180_wx.c
@@ -1274,8 +1274,8 @@
 
 }
 static int r8180_wx_set_auth(struct net_device *dev,
-                                        struct iw_request_info *info,
-                                        struct iw_param *data, char *extra)
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
 {
 	//printk("====>%s()\n", __func__);
 	struct r8180_priv *priv = ieee80211_priv(dev);
@@ -1285,7 +1285,7 @@
 		return 0;
 
 	down(&priv->wx_sem);
-	ret = ieee80211_wx_set_auth(priv->ieee80211, info, data, extra);
+	ret = ieee80211_wx_set_auth(priv->ieee80211, info, &wrqu->param, extra);
 	up(&priv->wx_sem);
 	return ret;
 }
@@ -1312,8 +1312,8 @@
 	return ret;
 }
 static int r8180_wx_set_gen_ie(struct net_device *dev,
-                                        struct iw_request_info *info,
-                                        struct iw_point *data, char *extra)
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
 {
 //	printk("====>%s(), len:%d\n", __func__, data->length);
 	int ret=0;
@@ -1325,7 +1325,7 @@
 
         down(&priv->wx_sem);
 #if 1
-        ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->length);
+        ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, wrqu->data.length);
 #endif
         up(&priv->wx_sem);
 	//printk("<======%s(), ret:%d\n", __func__, ret);
diff --git a/drivers/staging/serqt_usb/Kconfig b/drivers/staging/serqt_usb/Kconfig
new file mode 100644
index 0000000..cc1af5d
--- /dev/null
+++ b/drivers/staging/serqt_usb/Kconfig
@@ -0,0 +1,9 @@
+config USB_SERIAL_QUATECH_ESU100
+	tristate "USB Quatech ESU-100 8 Port Serial Driver"
+	depends on USB_SERIAL
+	help
+	  Say Y here if you want to use the Quatech ESU-100 8 port usb to
+	  serial adapter.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called serqt_usb.
diff --git a/drivers/staging/serqt_usb/Makefile b/drivers/staging/serqt_usb/Makefile
new file mode 100644
index 0000000..4fd1da2
--- /dev/null
+++ b/drivers/staging/serqt_usb/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_USB_SERIAL_QUATECH_ESU100)		+= serqt_usb.o
diff --git a/drivers/staging/serqt_usb/TODO b/drivers/staging/serqt_usb/TODO
new file mode 100644
index 0000000..34ecca8
--- /dev/null
+++ b/drivers/staging/serqt_usb/TODO
@@ -0,0 +1,8 @@
+Things to do for this driver to get merged into the main portion of the
+kernel:
+	- checkpatch cleanups
+	- sparse clean
+	- port to the usb-serial layer instead of doing it all on its
+	  own.
+
+Send patches to Greg Kroah-Hartman <greg@kroah.com>
diff --git a/drivers/staging/serqt_usb/serqt_usb.c b/drivers/staging/serqt_usb/serqt_usb.c
new file mode 100644
index 0000000..1781510
--- /dev/null
+++ b/drivers/staging/serqt_usb/serqt_usb.c
@@ -0,0 +1,2779 @@
+/*
+ * This code was developed for the Quatech USB line for linux, it used
+ * much of the code developed by Greg Kroah-Hartman for USB serial devices
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/wait.h>
+#include <linux/types.h>
+#include <linux/version.h>
+#include <linux/uaccess.h>
+
+/* Use our own dbg macro */
+/* #define DEBUG_ON */
+/* #undef dbg */
+#ifdef DEBUG_ON
+#define  mydbg(const...)    printk(const)
+#else
+#define  mydbg(const...)
+#endif
+
+/* parity check flag */
+#define RELEVANT_IFLAG(iflag)	(iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+
+#define SERIAL_TTY_MAJOR	        0	/* Nice legal number now */
+#define SERIAL_TTY_MINORS	        255	/* loads of devices :) */
+#define MAX_NUM_PORTS		        8	/* The maximum number of ports one device can grab at once */
+#define PREFUFF_LEVEL_CONSERVATIVE  128
+#define ATC_DISABLED                0x00
+
+#define RR_BITS             0x03	/* for clearing clock bits */
+#define DUPMODE_BITS        0xc0
+
+#define RS232_MODE          0x00
+#define RTSCTS_TO_CONNECTOR 0x40
+#define CLKS_X4             0x02
+
+#define LOOPMODE_BITS       0x41	/* LOOP1 = b6, LOOP0 = b0 (PORT B) */
+#define ALL_LOOPBACK        0x01
+#define MODEM_CTRL          0x40
+
+#define THISCHAR                    data[i]
+#define NEXTCHAR                    data[i + 1]
+#define THIRDCHAR                  data[i + 2]
+#define FOURTHCHAR                  data[i + 3]
+
+/*
+ * Useful defintions for port A, Port B and Port C
+ */
+#define FULLPWRBIT          0x00000080
+#define NEXT_BOARD_POWER_BIT        0x00000004
+
+#define SERIAL_LSR_OE       0x02
+#define SERIAL_LSR_PE       0x04
+#define SERIAL_LSR_FE       0x08
+#define SERIAL_LSR_BI       0x10
+
+#define SERIAL_LSR_TEMT     0x40
+
+#define  DIV_LATCH_LS               0x00
+#define  XMT_HOLD_REGISTER          0x00
+#define  XVR_BUFFER_REGISTER        0x00
+#define  DIV_LATCH_MS               0x01
+#define  FIFO_CONTROL_REGISTER      0x02
+#define  LINE_CONTROL_REGISTER      0x03
+#define  MODEM_CONTROL_REGISTER     0x04
+#define  LINE_STATUS_REGISTER       0x05
+#define  MODEM_STATUS_REGISTER      0x06
+
+#define  SERIAL_MCR_DTR             0x01
+#define  SERIAL_MCR_RTS             0x02
+#define  SERIAL_MCR_LOOP            0x10
+
+#define  SERIAL_MSR_CTS             0x10
+#define  SERIAL_MSR_CD              0x80
+#define  SERIAL_MSR_RI              0x40
+#define  SERIAL_MSR_DSR             0x20
+#define  SERIAL_MSR_MASK            0xf0
+
+#define  SERIAL_8_DATA              0x03
+#define  SERIAL_7_DATA              0x02
+#define  SERIAL_6_DATA              0x01
+#define  SERIAL_5_DATA              0x00
+
+#define  SERIAL_ODD_PARITY          0X08
+#define  SERIAL_EVEN_PARITY         0X18
+#define  SERIAL_TWO_STOPB           0x04
+#define  SERIAL_ONE_STOPB           0x00
+
+#define  MAX_BAUD_RATE              460800
+#define  MAX_BAUD_REMAINDER         4608
+
+#define QT_SET_GET_DEVICE           0xc2
+#define QT_OPEN_CLOSE_CHANNEL       0xca
+#define QT_GET_SET_PREBUF_TRIG_LVL  0xcc
+#define QT_SET_ATF                  0xcd
+#define QT_GET_SET_REGISTER         0xc0
+#define QT_GET_SET_UART             0xc1
+#define QT_HW_FLOW_CONTROL_MASK     0xc5
+#define QT_SW_FLOW_CONTROL_MASK     0xc6
+#define QT_SW_FLOW_CONTROL_DISABLE  0xc7
+#define QT_BREAK_CONTROL            0xc8
+
+#define SERIALQT_PCI_IOC_MAGIC 'k'
+#define SERIALQT_WRITE_QOPR _IOW(SERIALQT_PCI_IOC_MAGIC, 0, int)
+#define SERIALQT_WRITE_QMCR _IOW(SERIALQT_PCI_IOC_MAGIC, 1, int)
+#define SERIALQT_GET_NUMOF_UNITS _IOR(SERIALQT_PCI_IOC_MAGIC, 2, void *)
+#define SERIALQT_GET_THIS_UNIT _IOR(SERIALQT_PCI_IOC_MAGIC, 3, void *)
+#define SERIALQT_READ_QOPR _IOR(SERIALQT_PCI_IOC_MAGIC, 4, int)
+#define SERIALQT_READ_QMCR _IOR(SERIALQT_PCI_IOC_MAGIC, 5, int)
+#define SERIALQT_IS422_EXTENDED _IOR(SERIALQT_PCI_IOC_MAGIC, 6, int)	/* returns successful if 422 extended */
+
+#define USBD_TRANSFER_DIRECTION_IN    0xc0
+#define USBD_TRANSFER_DIRECTION_OUT   0x40
+
+#define ATC_DISABLED                0x00
+#define ATC_RTS_ENABLED                 0x02
+#define ATC_DTR_ENABLED                 0x01
+
+#define RR_BITS             0x03	/* for clearing clock bits */
+#define DUPMODE_BITS        0xc0
+
+#define FULL_DUPLEX         0x00
+#define HALF_DUPLEX_RTS     0x40
+#define HALF_DUPLEX_DTR     0x80
+
+#define QMCR_FULL_DUPLEX  0x00
+#define QMCR_HALF_DUPLEX_RTS 0x02
+#define QMCR_HALF_DUPLEX_DTR 0x01
+#define QMCR_HALF_DUPLEX_MASK 0x03
+#define QMCR_CONNECTOR_MASK 0x1C
+
+#define QMCR_RX_EN_MASK 0x20
+
+#define QMCR_ALL_LOOPBACK    0x10
+#define QMCR_MODEM_CONTROL   0X00
+
+#define SERIALQT_IOC_MAXNR 6
+
+struct usb_serial_port {
+	struct usb_serial *serial;	/* pointer back to the owner of this port */
+	struct tty_struct *tty;	/* the coresponding tty for this port */
+	unsigned char number;
+	char active;		/* someone has this device open */
+
+	unsigned char *interrupt_in_buffer;
+	struct urb *interrupt_in_urb;
+	__u8 interrupt_in_endpointAddress;
+
+	unsigned char *bulk_in_buffer;
+	unsigned char *xfer_to_tty_buffer;
+	struct urb *read_urb;
+	__u8 bulk_in_endpointAddress;
+
+	unsigned char *bulk_out_buffer;
+	int bulk_out_size;
+	struct urb *write_urb;
+	__u8 bulk_out_endpointAddress;
+
+	wait_queue_head_t write_wait;
+	wait_queue_head_t wait;
+	struct work_struct work;
+
+	int open_count;		/* number of times this port has been opened */
+	struct semaphore sem;	/* locks this structure */
+
+	__u8 shadowLCR;		/* last LCR value received */
+	__u8 shadowMCR;		/* last MCR value received */
+	__u8 shadowMSR;		/* last MSR value received */
+	__u8 shadowLSR;		/* last LSR value received */
+	int RxHolding;
+	char closePending;
+	int ReadBulkStopped;
+
+	void *private;		/* data private to the specific port */
+};
+
+struct identity {
+	int index;
+	int n_identity;
+};
+
+struct usb_serial {
+	struct usb_device *dev;
+	struct usb_interface *interface;	/* the interface for this device */
+	struct tty_driver *tty_driver;	/* the tty_driver for this device */
+	unsigned char minor;	/* the starting minor number for this device */
+	unsigned char num_ports;	/* the number of ports this device has */
+	char num_interrupt_in;	/* number of interrupt in endpoints we have */
+	char num_bulk_in;	/* number of bulk in endpoints we have */
+	char num_bulk_out;	/* number of bulk out endpoints we have */
+	unsigned char num_OpenCount;	/* the number of ports this device has */
+
+	__u16 vendor;		/* vendor id of this device */
+	__u16 product;		/* product id of this device */
+	struct usb_serial_port port[MAX_NUM_PORTS];
+
+	void *private;		/* data private to the specific driver */
+};
+
+static inline int port_paranoia_check(struct usb_serial_port *port,
+				      const char *function)
+{
+	if (!port) {
+		dbg("%s - port == NULL", function);
+		return -1;
+	}
+	if (!port->serial) {
+		dbg("%s - port->serial == NULL\n", function);
+		return -1;
+	}
+	if (!port->tty) {
+		dbg("%s - port->tty == NULL\n", function);
+		return -1;
+	}
+
+	return 0;
+}
+
+/* Inline functions to check the sanity of a pointer that is passed to us */
+static inline int serial_paranoia_check(struct usb_serial *serial,
+					const char *function)
+{
+	if (!serial) {
+		dbg("%s - serial == NULL\n", function);
+		return -1;
+	}
+
+	return 0;
+}
+
+static inline struct usb_serial *get_usb_serial(struct usb_serial_port *port,
+						const char *function)
+{
+	/* if no port was specified, or it fails a paranoia check */
+	if (!port ||
+	    port_paranoia_check(port, function) ||
+	    serial_paranoia_check(port->serial, function)) {
+		/* then say that we dont have a valid usb_serial thing, which will
+		 * end up genrating -ENODEV return values */
+		return NULL;
+	}
+
+	return port->serial;
+}
+
+struct qt_get_device_data {
+	__u8 porta;
+	__u8 portb;
+	__u8 portc;
+};
+
+struct qt_open_channel_data {
+	__u8 line_status;
+	__u8 modem_status;
+};
+
+static void ProcessLineStatus(struct usb_serial_port *port,
+			      unsigned char line_status);
+static void ProcessModemStatus(struct usb_serial_port *port,
+			       unsigned char modem_status);
+static void ProcessRxChar(struct usb_serial_port *port, unsigned char Data);
+static struct usb_serial *get_free_serial(int num_ports, int *minor);
+
+static int serqt_probe(struct usb_interface *interface,
+		       const struct usb_device_id *id);
+
+static void serqt_usb_disconnect(struct usb_interface *interface);
+static int box_set_device(struct usb_serial *serial,
+			  struct qt_get_device_data *pDeviceData);
+static int box_get_device(struct usb_serial *serial,
+			  struct qt_get_device_data *pDeviceData);
+static int serial_open(struct tty_struct *tty, struct file *filp);
+static void serial_close(struct tty_struct *tty, struct file *filp);
+static int serial_write_room(struct tty_struct *tty);
+static int serial_ioctl(struct tty_struct *tty, struct file *file,
+			unsigned int cmd, unsigned long arg);
+static void serial_set_termios(struct tty_struct *tty, struct ktermios *old);
+static int serial_write(struct tty_struct *tty, const unsigned char *buf,
+			int count);
+
+static void serial_throttle(struct tty_struct *tty);
+static void serial_unthrottle(struct tty_struct *tty);
+static int serial_break(struct tty_struct *tty, int break_state);
+static int serial_chars_in_buffer(struct tty_struct *tty);
+
+static int qt_open(struct usb_serial_port *port, struct file *filp);
+static int BoxSetPrebufferLevel(struct usb_serial *serial);
+
+static int BoxSetATC(struct usb_serial *serial, __u16 n_Mode);
+static int BoxSetUart(struct usb_serial *serial, unsigned short Uart_Number,
+		      unsigned short default_divisor,
+		      unsigned char default_LCR);
+
+static int BoxOPenCloseChannel(struct usb_serial *serial, __u16 Uart_Number,
+			       __u16 OpenClose,
+			       struct qt_open_channel_data *pDeviceData);
+static void qt_close(struct usb_serial_port *port, struct file *filp);
+static int BoxGetRegister(struct usb_serial *serial, unsigned short Uart_Number,
+			  unsigned short Register_Num, __u8 *pValue);
+static int BoxSetRegister(struct usb_serial *serial, unsigned short Uart_Number,
+			  unsigned short Register_Num, unsigned short Value);
+static void qt_write_bulk_callback(struct urb *urb);
+static int qt_write(struct usb_serial_port *port, int from_user,
+		    const unsigned char *buf, int count);
+static void port_softint(struct work_struct *work);
+static int qt_write_room(struct usb_serial_port *port);
+static int qt_chars_in_buffer(struct usb_serial_port *port);
+static int qt_ioctl(struct usb_serial_port *port, struct file *file,
+		    unsigned int cmd, unsigned long arg);
+static void qt_set_termios(struct usb_serial_port *port,
+			   struct ktermios *old_termios);
+static int BoxSetHW_FlowCtrl(struct usb_serial *serial, unsigned int UartNumber,
+			     int bSet);
+static int BoxDisable_SW_FlowCtrl(struct usb_serial *serial, __u16 UartNumber);
+static int EmulateWriteQMCR_Reg(int index, unsigned uc_value);
+static int EmulateReadQMCR_Reg(int index, unsigned *uc_value);
+static struct usb_serial *find_the_box(unsigned int index);
+static int ioctl_serial_usb(struct inode *innod, struct file *filp, unsigned int cmd,
+		     unsigned long arg);
+
+static int BoxSetSW_FlowCtrl(struct usb_serial *serial, __u16 Uart,
+			     unsigned char stop_char, unsigned char start_char);
+static void qt_read_bulk_callback(struct urb *urb);
+
+static void port_sofrint(void *private);
+
+static void return_serial(struct usb_serial *serial);
+
+static int serial_tiocmset(struct tty_struct *tty, struct file *file,
+			   unsigned int set, unsigned int clear);
+static int serial_tiocmget(struct tty_struct *tty, struct file *file);
+
+static int qt_tiocmset(struct usb_serial_port *port, struct file *file,
+		       unsigned int value);
+
+static int qt_tiocmget(struct usb_serial_port *port, struct file *file);
+
+/* Version Information */
+#define DRIVER_VERSION "v2.14"
+#define DRIVER_AUTHOR "Tim Gobeli, Quatech, Inc"
+#define DRIVER_DESC "Quatech USB to Serial Driver"
+
+#define	USB_VENDOR_ID_QUATECH			0x061d	/* Quatech VID */
+#define DEVICE_ID_QUATECH_RS232_SINGLE_PORT	0xC020	/* SSU100 */
+#define DEVICE_ID_QUATECH_RS422_SINGLE_PORT	0xC030	/* SSU200 */
+#define DEVICE_ID_QUATECH_RS232_DUAL_PORT	0xC040	/* DSU100 */
+#define DEVICE_ID_QUATECH_RS422_DUAL_PORT	0xC050	/* DSU200 */
+#define DEVICE_ID_QUATECH_RS232_FOUR_PORT	0xC060	/* QSU100 */
+#define DEVICE_ID_QUATECH_RS422_FOUR_PORT	0xC070	/* QSU200 */
+#define DEVICE_ID_QUATECH_RS232_EIGHT_PORT_A	0xC080	/* ESU100A */
+#define DEVICE_ID_QUATECH_RS232_EIGHT_PORT_B	0xC081	/* ESU100B */
+#define DEVICE_ID_QUATECH_RS422_EIGHT_PORT_A	0xC0A0	/* ESU200A */
+#define DEVICE_ID_QUATECH_RS422_EIGHT_PORT_B	0xC0A1	/* ESU200B */
+#define DEVICE_ID_QUATECH_RS232_16_PORT_A	0xC090	/* HSU100A */
+#define DEVICE_ID_QUATECH_RS232_16_PORT_B	0xC091	/* HSU100B */
+#define DEVICE_ID_QUATECH_RS232_16_PORT_C	0xC092	/* HSU100C */
+#define DEVICE_ID_QUATECH_RS232_16_PORT_D	0xC093	/* HSU100D */
+#define DEVICE_ID_QUATECH_RS422_16_PORT_A	0xC0B0	/* HSU200A */
+#define DEVICE_ID_QUATECH_RS422_16_PORT_B	0xC0B1	/* HSU200B */
+#define DEVICE_ID_QUATECH_RS422_16_PORT_C	0xC0B2	/* HSU200C */
+#define DEVICE_ID_QUATECH_RS422_16_PORT_D	0xC0B3	/* HSU200D */
+
+/* table of Quatech devices  */
+static struct usb_device_id serqt_table[] = {
+	{USB_DEVICE
+	 (USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_SINGLE_PORT)},
+	{USB_DEVICE
+	 (USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_SINGLE_PORT)},
+	{USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_DUAL_PORT)},
+	{USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_DUAL_PORT)},
+	{USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_FOUR_PORT)},
+	{USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_FOUR_PORT)},
+	{USB_DEVICE
+	 (USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_EIGHT_PORT_A)},
+	{USB_DEVICE
+	 (USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_EIGHT_PORT_B)},
+	{USB_DEVICE
+	 (USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_EIGHT_PORT_A)},
+	{USB_DEVICE
+	 (USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_EIGHT_PORT_B)},
+	{USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_16_PORT_A)},
+	{USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_16_PORT_B)},
+	{USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_16_PORT_C)},
+	{USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_16_PORT_D)},
+	{USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_16_PORT_A)},
+	{USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_16_PORT_B)},
+	{USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_16_PORT_C)},
+	{USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_16_PORT_D)},
+	{}			/* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, serqt_table);
+
+static int major_number;
+static struct usb_serial *serial_table[SERIAL_TTY_MINORS];	/* initially all NULL */
+
+/* table of Quatech 422devices  */
+static unsigned int serqt_422_table[] = {
+	DEVICE_ID_QUATECH_RS422_SINGLE_PORT,
+	DEVICE_ID_QUATECH_RS422_DUAL_PORT,
+	DEVICE_ID_QUATECH_RS422_FOUR_PORT,
+	DEVICE_ID_QUATECH_RS422_EIGHT_PORT_A,
+	DEVICE_ID_QUATECH_RS422_EIGHT_PORT_B,
+	DEVICE_ID_QUATECH_RS422_16_PORT_A,
+	DEVICE_ID_QUATECH_RS422_16_PORT_B,
+	DEVICE_ID_QUATECH_RS422_16_PORT_C,
+	DEVICE_ID_QUATECH_RS422_16_PORT_D,
+	0			/* terminate with zero */
+};
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver serqt_usb_driver = {
+	.name = "quatech-usb-serial",
+	.probe = serqt_probe,
+	.disconnect = serqt_usb_disconnect,
+	.id_table = serqt_table,
+};
+
+static struct ktermios *serial_termios[SERIAL_TTY_MINORS];
+static struct ktermios *serial_termios_locked[SERIAL_TTY_MINORS];
+
+static const struct tty_operations serial_ops = {
+	.open = serial_open,
+	.close = serial_close,
+	.write = serial_write,
+	.write_room = serial_write_room,
+	.ioctl = serial_ioctl,
+	.set_termios = serial_set_termios,
+	.throttle = serial_throttle,
+	.unthrottle = serial_unthrottle,
+	.break_ctl = serial_break,
+	.chars_in_buffer = serial_chars_in_buffer,
+	.tiocmset = serial_tiocmset,
+	.tiocmget = serial_tiocmget,
+};
+
+static struct tty_driver serial_tty_driver = {
+	.magic = TTY_DRIVER_MAGIC,
+	.driver_name = "Quatech usb-serial",
+	.name = "ttyQT_USB",
+	.major = SERIAL_TTY_MAJOR,
+	.minor_start = 0,
+	.num = SERIAL_TTY_MINORS,
+	.type = TTY_DRIVER_TYPE_SERIAL,
+	.subtype = SERIAL_TYPE_NORMAL,
+	.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV,
+
+	.termios = serial_termios,
+	.termios_locked = serial_termios_locked,
+	.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL,
+
+	.init_termios.c_iflag = ICRNL | IXON,
+	.init_termios.c_oflag = OPOST,
+
+	.init_termios.c_lflag =
+	    ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN,
+};
+
+/* fops for parent device */
+static const struct file_operations serialqt_usb_fops = {
+	.ioctl = ioctl_serial_usb,
+};
+
+ /**
+ *	  serqt_probe
+ *
+ *	Called by the usb core when a new device is connected that it thinks
+ *	this driver might be interested in.
+ *
+ */
+static int serqt_probe(struct usb_interface *interface,
+		       const struct usb_device_id *id)
+{
+	struct usb_device *dev = interface_to_usbdev(interface);
+	struct usb_serial *serial = NULL;
+	struct usb_serial_port *port;
+	struct usb_endpoint_descriptor *endpoint;
+	struct usb_endpoint_descriptor *interrupt_in_endpoint[MAX_NUM_PORTS];
+	struct usb_endpoint_descriptor *bulk_in_endpoint[MAX_NUM_PORTS];
+	struct usb_endpoint_descriptor *bulk_out_endpoint[MAX_NUM_PORTS];
+	int minor;
+	int buffer_size;
+	int i;
+	struct usb_host_interface *iface_desc;
+	int num_interrupt_in = 0;
+	int num_bulk_in = 0;
+	int num_bulk_out = 0;
+	int num_ports;
+	struct qt_get_device_data DeviceData;
+	int status;
+
+	mydbg("In %s\n", __func__);
+
+	/* let's find the endpoints needed */
+	/* check out the endpoints */
+	iface_desc = interface->cur_altsetting;;
+	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+		endpoint = &iface_desc->endpoint[i].desc;
+
+		if ((endpoint->bEndpointAddress & 0x80) &&
+		    ((endpoint->bmAttributes & 3) == 0x02)) {
+			/* we found a bulk in endpoint */
+			mydbg("found bulk in");
+			bulk_in_endpoint[num_bulk_in] = endpoint;
+			++num_bulk_in;
+		}
+
+		if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
+		    ((endpoint->bmAttributes & 3) == 0x02)) {
+			/* we found a bulk out endpoint */
+			mydbg("found bulk out\n");
+			bulk_out_endpoint[num_bulk_out] = endpoint;
+			++num_bulk_out;
+		}
+
+		if ((endpoint->bEndpointAddress & 0x80) &&
+		    ((endpoint->bmAttributes & 3) == 0x03)) {
+			/* we found a interrupt in endpoint */
+			mydbg("found interrupt in\n");
+			interrupt_in_endpoint[num_interrupt_in] = endpoint;
+			++num_interrupt_in;
+		}
+	}
+
+	/* found all that we need */
+	dev_info(&interface->dev, "Quatech converter detected\n");
+	num_ports = num_bulk_out;
+	if (num_ports == 0) {
+		err("Quatech device with no bulk out, not allowed.");
+		return -ENODEV;
+
+	}
+
+	serial = get_free_serial(num_ports, &minor);
+	if (serial == NULL) {
+		err("No more free serial devices");
+		return -ENODEV;
+	}
+
+	serial->dev = dev;
+	serial->interface = interface;
+	serial->minor = minor;
+	serial->num_ports = num_ports;
+	serial->num_bulk_in = num_bulk_in;
+	serial->num_bulk_out = num_bulk_out;
+	serial->num_interrupt_in = num_interrupt_in;
+	serial->vendor = dev->descriptor.idVendor;
+	serial->product = dev->descriptor.idProduct;
+
+	/* set up the endpoint information */
+	for (i = 0; i < num_bulk_in; ++i) {
+		endpoint = bulk_in_endpoint[i];
+		port = &serial->port[i];
+		port->read_urb = usb_alloc_urb(0, GFP_KERNEL);
+		if (!port->read_urb) {
+			err("No free urbs available");
+			goto probe_error;
+		}
+		buffer_size = endpoint->wMaxPacketSize;
+		port->bulk_in_endpointAddress = endpoint->bEndpointAddress;
+		port->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
+		port->xfer_to_tty_buffer = kmalloc(buffer_size, GFP_KERNEL);
+		if (!port->bulk_in_buffer) {
+			err("Couldn't allocate bulk_in_buffer");
+			goto probe_error;
+		}
+		usb_fill_bulk_urb(port->read_urb, dev,
+				  usb_rcvbulkpipe(dev,
+						  endpoint->bEndpointAddress),
+				  port->bulk_in_buffer, buffer_size,
+				  qt_read_bulk_callback, port);
+	}
+
+	for (i = 0; i < num_bulk_out; ++i) {
+		endpoint = bulk_out_endpoint[i];
+		port = &serial->port[i];
+		port->write_urb = usb_alloc_urb(0, GFP_KERNEL);
+		if (!port->write_urb) {
+			err("No free urbs available");
+			goto probe_error;
+		}
+		buffer_size = endpoint->wMaxPacketSize;
+		port->bulk_out_size = buffer_size;
+		port->bulk_out_endpointAddress = endpoint->bEndpointAddress;
+		port->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
+		if (!port->bulk_out_buffer) {
+			err("Couldn't allocate bulk_out_buffer");
+			goto probe_error;
+		}
+		usb_fill_bulk_urb(port->write_urb, dev,
+				  usb_sndbulkpipe(dev,
+						  endpoint->bEndpointAddress),
+				  port->bulk_out_buffer, buffer_size,
+				  qt_write_bulk_callback, port);
+
+	}
+
+	/* For us numb of bulkin  or out = number of ports */
+	mydbg("%s - setting up %d port structures for this device\n",
+	      __func__, num_bulk_in);
+	for (i = 0; i < num_bulk_in; ++i) {
+		port = &serial->port[i];
+		port->number = i + serial->minor;
+		port->serial = serial;
+
+		INIT_WORK(&port->work, port_softint);
+
+		init_MUTEX(&port->sem);
+
+	}
+	status = box_get_device(serial, &DeviceData);
+	if (status < 0) {
+		mydbg(__FILE__ "box_get_device failed");
+		goto probe_error;
+	}
+
+	mydbg(__FILE__ "DeviceData.portb = 0x%x", DeviceData.portb);
+
+	DeviceData.portb &= ~FULLPWRBIT;
+	mydbg(__FILE__ "Changing DeviceData.portb to 0x%x", DeviceData.portb);
+
+	status = box_set_device(serial, &DeviceData);
+	if (status < 0) {
+		mydbg(__FILE__ "box_set_device failed\n");
+		goto probe_error;
+	}
+
+	/* initialize the devfs nodes for this device and let the user know what ports we are bound to */
+	for (i = 0; i < serial->num_ports; ++i) {
+		dev_info(&interface->dev,
+			 "Converter now attached to ttyUSB%d (or usb/tts/%d for devfs)",
+			 serial->port[i].number, serial->port[i].number);
+	}
+
+	/* usb_serial_console_init (debug, minor); */
+
+	/***********TAG add start next board here ****/
+	status = box_get_device(serial, &DeviceData);
+	if (status < 0) {
+		mydbg(__FILE__ "box_get_device failed");
+		goto probe_error;
+	}
+	/*
+	 * and before we power up lets initialiaze parnent device stuff here before
+	 * we set thmem via any other method such as the property pages
+	 */
+	switch (serial->product) {
+	case DEVICE_ID_QUATECH_RS232_SINGLE_PORT:
+	case DEVICE_ID_QUATECH_RS232_DUAL_PORT:
+	case DEVICE_ID_QUATECH_RS232_FOUR_PORT:
+	case DEVICE_ID_QUATECH_RS232_EIGHT_PORT_A:
+	case DEVICE_ID_QUATECH_RS232_EIGHT_PORT_B:
+	case DEVICE_ID_QUATECH_RS232_16_PORT_A:
+	case DEVICE_ID_QUATECH_RS232_16_PORT_B:
+	case DEVICE_ID_QUATECH_RS232_16_PORT_C:
+	case DEVICE_ID_QUATECH_RS232_16_PORT_D:
+		DeviceData.porta &= ~(RR_BITS | DUPMODE_BITS);
+		DeviceData.porta |= CLKS_X4;
+		DeviceData.portb &= ~(LOOPMODE_BITS);
+		DeviceData.portb |= RS232_MODE;
+		break;
+
+	case DEVICE_ID_QUATECH_RS422_SINGLE_PORT:
+	case DEVICE_ID_QUATECH_RS422_DUAL_PORT:
+	case DEVICE_ID_QUATECH_RS422_FOUR_PORT:
+	case DEVICE_ID_QUATECH_RS422_EIGHT_PORT_A:
+	case DEVICE_ID_QUATECH_RS422_EIGHT_PORT_B:
+	case DEVICE_ID_QUATECH_RS422_16_PORT_A:
+	case DEVICE_ID_QUATECH_RS422_16_PORT_B:
+	case DEVICE_ID_QUATECH_RS422_16_PORT_C:
+	case DEVICE_ID_QUATECH_RS422_16_PORT_D:
+		DeviceData.porta &= ~(RR_BITS | DUPMODE_BITS);
+		DeviceData.porta |= CLKS_X4;
+		DeviceData.portb &= ~(LOOPMODE_BITS);
+		DeviceData.portb |= ALL_LOOPBACK;
+		break;
+	default:
+		DeviceData.porta &= ~(RR_BITS | DUPMODE_BITS);
+		DeviceData.porta |= CLKS_X4;
+		DeviceData.portb &= ~(LOOPMODE_BITS);
+		DeviceData.portb |= RS232_MODE;
+		break;
+
+	}
+	status = BoxSetPrebufferLevel(serial);	/* sets to default vaue */
+	if (status < 0) {
+		mydbg(__FILE__ "BoxSetPrebufferLevel failed\n");
+		goto probe_error;
+	}
+
+	status = BoxSetATC(serial, ATC_DISABLED);
+	if (status < 0) {
+		mydbg(__FILE__ "BoxSetATC failed\n");
+		goto probe_error;
+	}
+	/**********************************************************/
+	mydbg(__FILE__ "DeviceData.portb = 0x%x", DeviceData.portb);
+
+	DeviceData.portb |= NEXT_BOARD_POWER_BIT;
+	mydbg(__FILE__ "Changing DeviceData.portb to 0x%x", DeviceData.portb);
+
+	status = box_set_device(serial, &DeviceData);
+	if (status < 0) {
+		mydbg(__FILE__ "box_set_device failed\n");
+		goto probe_error;
+	}
+
+	mydbg("Exit Success %s\n", __func__);
+
+	usb_set_intfdata(interface, serial);
+	return 0;
+
+probe_error:
+
+	for (i = 0; i < num_bulk_in; ++i) {
+		port = &serial->port[i];
+		usb_free_urb(port->read_urb);
+		kfree(port->bulk_in_buffer);
+	}
+	for (i = 0; i < num_bulk_out; ++i) {
+		port = &serial->port[i];
+		usb_free_urb(port->write_urb);
+		kfree(port->bulk_out_buffer);
+		kfree(port->xfer_to_tty_buffer);
+	}
+	for (i = 0; i < num_interrupt_in; ++i) {
+		port = &serial->port[i];
+		usb_free_urb(port->interrupt_in_urb);
+		kfree(port->interrupt_in_buffer);
+	}
+
+	/* return the minor range that this device had */
+	return_serial(serial);
+	mydbg("Exit fail %s\n", __func__);
+
+	/* free up any memory that we allocated */
+	kfree(serial);
+	return -EIO;
+}
+
+/*
+ * returns the serial_table array pointers that are taken
+ * up in consecutive positions for each port to a common usb_serial structure
+ * back to NULL
+ */
+static void return_serial(struct usb_serial *serial)
+{
+	int i;
+
+	mydbg("%s\n", __func__);
+
+	if (serial == NULL)
+		return;
+
+	for (i = 0; i < serial->num_ports; ++i)
+		serial_table[serial->minor + i] = NULL;
+
+	return;
+}
+
+/*
+ * Finds the first locatio int the serial_table array where it can fit
+ * num_ports number of consecutive points to a common usb_serial
+ * structure,allocates a stucture points to it in all the structures, and
+ * returns the index to the first location in the array in the "minor"
+ * variable.
+ */
+static struct usb_serial *get_free_serial(int num_ports, int *minor)
+{
+	struct usb_serial *serial = NULL;
+	int i, j;
+	int good_spot;
+
+	mydbg("%s %d\n", __func__, num_ports);
+
+	*minor = 0;
+	for (i = 0; i < SERIAL_TTY_MINORS; ++i) {
+		if (serial_table[i])
+			continue;
+
+		good_spot = 1;
+		/*
+		 * find a spot in the array where you can fit consecutive
+		 * positions to put the pointers to the usb_serail allocated
+		 * structure for all the minor numbers (ie. ports)
+		 */
+		for (j = 1; j <= num_ports - 1; ++j)
+			if (serial_table[i + j])
+				good_spot = 0;
+		if (good_spot == 0)
+			continue;
+
+		serial = kmalloc(sizeof(struct usb_serial), GFP_KERNEL);
+		if (!serial) {
+			err("%s - Out of memory", __func__);
+			return NULL;
+		}
+		memset(serial, 0, sizeof(struct usb_serial));
+		serial_table[i] = serial;
+		*minor = i;
+		mydbg("%s - minor base = %d\n", __func__, *minor);
+
+		/*
+		 * copy in the pointer into the array starting a the *minor
+		 * position minor is the index into the array.
+		 */
+		for (i = *minor + 1;
+		     (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i)
+			serial_table[i] = serial;
+		return serial;
+	}
+	return NULL;
+}
+
+static int flip_that(struct tty_struct *tty, __u16 UartNumber,
+		     struct usb_serial *serial)
+{
+	tty_flip_buffer_push(tty);
+	tty_schedule_flip(tty);
+	return 0;
+}
+
+/* Handles processing and moving data to the tty layer */
+static void port_sofrint(void *private)
+{
+	struct usb_serial_port *port = (struct usb_serial_port *)private;
+	struct usb_serial *serial = get_usb_serial(port, __func__);
+	struct tty_struct *tty = port->tty;
+	unsigned char *data = port->read_urb->transfer_buffer;
+	unsigned int UartNumber;
+	struct urb *urb = port->read_urb;
+	unsigned int RxCount = urb->actual_length;
+	int i, result;
+	int flag, flag_data;
+
+	/* UartNumber = MINOR(port->tty->device) - serial->minor; */
+	UartNumber = tty->index - serial->minor;
+
+	mydbg("%s - port %d\n", __func__, port->number);
+	mydbg("%s - port->RxHolding = %d\n", __func__, port->RxHolding);
+
+	if (port_paranoia_check(port, __func__) != 0) {
+		mydbg("%s - port_paranoia_check, exiting\n", __func__);
+		port->ReadBulkStopped = 1;
+		return;
+	}
+
+	if (!serial) {
+		mydbg("%s - bad serial pointer, exiting\n", __func__);
+		return;
+	}
+	if (port->closePending == 1) {
+		/* Were closing , stop reading */
+		mydbg("%s - (port->closepending == 1\n", __func__);
+		port->ReadBulkStopped = 1;
+		return;
+	}
+
+	/*
+	 * RxHolding is asserted by throttle, if we assert it, we're not
+	 * receiving any more characters and let the box handle the flow
+	 * control
+	 */
+	if (port->RxHolding == 1) {
+		port->ReadBulkStopped = 1;
+		return;
+	}
+
+	if (urb->status) {
+		port->ReadBulkStopped = 1;
+
+		mydbg("%s - nonzero read bulk status received: %d\n",
+		      __func__, urb->status);
+		return;
+	}
+
+	tty = port->tty;
+	mydbg("%s - port %d, tty =0x%p\n", __func__, port->number, tty);
+
+	if (tty && RxCount) {
+		flag_data = 0;
+		for (i = 0; i < RxCount; ++i) {
+			/* Look ahead code here */
+			if ((i <= (RxCount - 3)) && (THISCHAR == 0x1b)
+			    && (NEXTCHAR == 0x1b)) {
+				flag = 0;
+				switch (THIRDCHAR) {
+				case 0x00:
+					/* Line status change 4th byte must follow */
+					if (i > (RxCount - 4)) {
+						mydbg("Illegal escape sequences in received data\n");
+						break;
+					}
+					ProcessLineStatus(port, FOURTHCHAR);
+					i += 3;
+					flag = 1;
+					break;
+
+				case 0x01:
+					/* Modem status status change 4th byte must follow */
+					mydbg("Modem status status. \n");
+					if (i > (RxCount - 4)) {
+						mydbg
+						    ("Illegal escape sequences in received data\n");
+						break;
+					}
+					ProcessModemStatus(port, FOURTHCHAR);
+					i += 3;
+					flag = 1;
+					break;
+				case 0xff:
+					mydbg("No status sequence. \n");
+
+					ProcessRxChar(port, THISCHAR);
+					ProcessRxChar(port, NEXTCHAR);
+					i += 2;
+					break;
+				}
+				if (flag == 1)
+					continue;
+			}
+
+			if (tty && urb->actual_length) {
+				tty_buffer_request_room(tty, 1);
+				tty_insert_flip_string(tty, (data + i), 1);
+			}
+
+		}
+		tty_flip_buffer_push(tty);
+	}
+
+	/* Continue trying to always read  */
+	usb_fill_bulk_urb(port->read_urb, serial->dev,
+			  usb_rcvbulkpipe(serial->dev,
+					  port->bulk_in_endpointAddress),
+			  port->read_urb->transfer_buffer,
+			  port->read_urb->transfer_buffer_length,
+			  qt_read_bulk_callback, port);
+	result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+	if (result)
+		mydbg("%s - failed resubmitting read urb, error %d",
+		      __func__, result);
+	else {
+		if (tty && RxCount)
+			flip_that(tty, UartNumber, serial);
+	}
+
+	return;
+
+}
+
+static void qt_read_bulk_callback(struct urb *urb)
+{
+
+	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+
+	if (urb->status) {
+		port->ReadBulkStopped = 1;
+		mydbg("%s - nonzero write bulk status received: %d\n",
+		      __func__, urb->status);
+		return;
+	}
+
+	port_sofrint((void *)port);
+	schedule_work(&port->work);
+}
+
+static void ProcessRxChar(struct usb_serial_port *port, unsigned char Data)
+{
+	struct tty_struct *tty;
+	struct urb *urb = port->read_urb;
+	tty = port->tty;
+	/* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
+
+	if (tty && urb->actual_length) {
+		tty_buffer_request_room(tty, 1);
+		tty_insert_flip_string(tty, &Data, 1);
+		/* tty_flip_buffer_push(tty); */
+	}
+
+	return;
+}
+
+static void ProcessLineStatus(struct usb_serial_port *port,
+			      unsigned char line_status)
+{
+
+	port->shadowLSR =
+	    line_status & (SERIAL_LSR_OE | SERIAL_LSR_PE | SERIAL_LSR_FE |
+			   SERIAL_LSR_BI);
+	return;
+}
+
+static void ProcessModemStatus(struct usb_serial_port *port,
+			       unsigned char modem_status)
+{
+
+	port->shadowMSR = modem_status;
+	wake_up_interruptible(&port->wait);
+	return;
+}
+
+static void serqt_usb_disconnect(struct usb_interface *interface)
+{
+	struct usb_serial *serial = usb_get_intfdata(interface);
+	/* struct device *dev = &interface->dev; */
+	struct usb_serial_port *port;
+	int i;
+
+	mydbg("%s\n", __func__);
+	if (serial) {
+
+		serial->dev = NULL;
+
+		for (i = 0; i < serial->num_ports; ++i)
+			serial->port[i].open_count = 0;
+
+		for (i = 0; i < serial->num_bulk_in; ++i) {
+			port = &serial->port[i];
+			usb_unlink_urb(port->read_urb);
+			usb_free_urb(port->read_urb);
+			kfree(port->bulk_in_buffer);
+		}
+		for (i = 0; i < serial->num_bulk_out; ++i) {
+			port = &serial->port[i];
+			usb_unlink_urb(port->write_urb);
+			usb_free_urb(port->write_urb);
+			kfree(port->bulk_out_buffer);
+		}
+		for (i = 0; i < serial->num_interrupt_in; ++i) {
+			port = &serial->port[i];
+			usb_unlink_urb(port->interrupt_in_urb);
+			usb_free_urb(port->interrupt_in_urb);
+			kfree(port->interrupt_in_buffer);
+	}
+
+		/* return the minor range that this device had */
+		return_serial(serial);
+
+		/* free up any memory that we allocated */
+		kfree(serial);
+
+	} else {
+		dev_info(&interface->dev, "device disconnected");
+	}
+
+}
+
+static struct usb_serial *get_serial_by_minor(unsigned int minor)
+{
+	return serial_table[minor];
+}
+
+/*****************************************************************************
+ * Driver tty interface functions
+ *****************************************************************************/
+static int serial_open(struct tty_struct *tty, struct file *filp)
+{
+	struct usb_serial *serial;
+	struct usb_serial_port *port;
+	unsigned int portNumber;
+	int retval = 0;
+
+	mydbg("%s\n", __func__);
+
+	/* initialize the pointer incase something fails */
+	tty->driver_data = NULL;
+
+	/* get the serial object associated with this tty pointer */
+	/* serial = get_serial_by_minor (MINOR(tty->device)); */
+
+	/* get the serial object associated with this tty pointer */
+	serial = get_serial_by_minor(tty->index);
+
+	if (serial_paranoia_check(serial, __func__))
+		return -ENODEV;
+
+	/* set up our port structure making the tty driver remember our port object, and us it */
+	portNumber = tty->index - serial->minor;
+	port = &serial->port[portNumber];
+	tty->driver_data = port;
+
+	down(&port->sem);
+	port->tty = tty;
+
+	++port->open_count;
+	if (port->open_count == 1) {
+		port->closePending = 0;
+		mydbg("%s port->closepending = 0\n", __func__);
+
+		port->RxHolding = 0;
+		mydbg("%s port->RxHolding = 0\n", __func__);
+
+		retval = qt_open(port, filp);
+	}
+
+	if (retval)
+		port->open_count = 0;
+	mydbg("%s returning port->closePending  = %d\n", __func__,
+	      port->closePending);
+
+	up(&port->sem);
+	return retval;
+}
+
+/*****************************************************************************
+ *device's specific driver functions
+ *****************************************************************************/
+static int qt_open(struct usb_serial_port *port, struct file *filp)
+{
+	struct usb_serial *serial = port->serial;
+	int result = 0;
+	unsigned int UartNumber;
+	struct qt_get_device_data DeviceData;
+	struct qt_open_channel_data ChannelData;
+	unsigned short default_divisor = 0x30;		/* gives 9600 baud rate */
+	unsigned char default_LCR = SERIAL_8_DATA;	/* 8, none , 1 */
+	int status = 0;
+
+	if (port_paranoia_check(port, __func__))
+		return -ENODEV;
+
+	mydbg("%s - port %d\n", __func__, port->number);
+
+	/* force low_latency on so that our tty_push actually forces the data through,
+	   otherwise it is scheduled, and with high data rates (like with OHCI) data
+	   can get lost. */
+	if (port->tty)
+		port->tty->low_latency = 0;
+
+	UartNumber = port->tty->index - serial->minor;
+
+	status = box_get_device(serial, &DeviceData);
+	if (status < 0) {
+		mydbg(__FILE__ "box_get_device failed\n");
+		return status;
+	}
+	serial->num_OpenCount++;
+	mydbg("%s serial->num_OpenCount  = %d\n", __func__,
+	      serial->num_OpenCount);
+	/* Open uart channel */
+
+	/* Port specific setups */
+	status = BoxOPenCloseChannel(serial, UartNumber, 1, &ChannelData);
+	if (status < 0) {
+		mydbg(__FILE__ "BoxOPenCloseChannel failed\n");
+		return status;
+	}
+	mydbg(__FILE__ "BoxOPenCloseChannel completed.\n");
+
+	port->shadowLSR = ChannelData.line_status &
+	    (SERIAL_LSR_OE | SERIAL_LSR_PE | SERIAL_LSR_FE | SERIAL_LSR_BI);
+
+	port->shadowMSR = ChannelData.modem_status &
+	    (SERIAL_MSR_CTS | SERIAL_MSR_DSR | SERIAL_MSR_RI | SERIAL_MSR_CD);
+
+	/* Set Baud rate to default and turn off (default)flow control here */
+	status = BoxSetUart(serial, UartNumber, default_divisor, default_LCR);
+	if (status < 0) {
+		mydbg(__FILE__ "BoxSetUart failed\n");
+		return status;
+	}
+	mydbg(__FILE__ "BoxSetUart completed.\n");
+
+	/* Put this here to make it responsive to stty and defauls set by the tty layer */
+	qt_set_termios(port, NULL);
+
+	/* Initialize the wait que head */
+	init_waitqueue_head(&(port->wait));
+
+	/* if we have a bulk endpoint, start reading from it */
+	if (serial->num_bulk_in) {
+		/* Start reading from the device */
+		usb_fill_bulk_urb(port->read_urb, serial->dev,
+				  usb_rcvbulkpipe(serial->dev,
+						  port->
+						  bulk_in_endpointAddress),
+				  port->read_urb->transfer_buffer,
+				  port->read_urb->transfer_buffer_length,
+				  qt_read_bulk_callback, port);
+
+		port->ReadBulkStopped = 0;
+
+		result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+
+		if (result) {
+			err("%s - failed resubmitting read urb, error %d\n",
+			    __func__, result);
+			port->ReadBulkStopped = 1;
+		}
+
+	}
+
+	return result;
+}
+
+static void serial_close(struct tty_struct *tty, struct file *filp)
+{
+	struct usb_serial_port *port =
+	    (struct usb_serial_port *)tty->driver_data;
+	struct usb_serial *serial = get_usb_serial(port, __func__);
+
+	if (!serial)
+		return;
+
+	down(&port->sem);
+
+	mydbg("%s - port %d\n", __func__, port->number);
+
+	/* if disconnect beat us to the punch here, there's nothing to do */
+	if (tty->driver_data) {
+		if (!port->open_count) {
+			mydbg("%s - port not opened\n", __func__);
+			goto exit;
+		}
+
+		--port->open_count;
+		if (port->open_count <= 0) {
+			port->closePending = 1;
+			mydbg("%s - port->closePending = 1\n", __func__);
+
+			if (serial->dev) {
+				qt_close(port, filp);
+				port->open_count = 0;
+			}
+		}
+
+	}
+
+exit:
+	up(&port->sem);
+
+	mydbg("%s - %d return\n", __func__, port->number);
+
+}
+
+static void qt_close(struct usb_serial_port *port, struct file *filp)
+{
+	unsigned long jift = jiffies + 10 * HZ;
+	__u8 LSR_Value, MCR_Value;
+	struct usb_serial *serial = port->serial;
+	int status;
+	unsigned int UartNumber;
+
+	struct qt_open_channel_data ChannelData;
+	status = 0;
+	LSR_Value = 0;
+
+	mydbg("%s - port %d\n", __func__, port->number);
+	UartNumber = port->tty->index - serial->minor;
+
+	/* shutdown any bulk reads that might be going on */
+	if (serial->num_bulk_out)
+		usb_unlink_urb(port->write_urb);
+	if (serial->num_bulk_in)
+		usb_unlink_urb(port->read_urb);
+
+	/* wait up to 30 seconds for transmitter to empty */
+	do {
+		status = BoxGetRegister(serial, UartNumber, LINE_STATUS_REGISTER, &LSR_Value);
+		if (status < 0) {
+			mydbg(__FILE__ "box_get_device failed\n");
+			break;
+		}
+
+		if ((LSR_Value & SERIAL_LSR_TEMT)
+		    && (port->ReadBulkStopped == 1))
+			break;
+		schedule();
+
+	}
+	while (jiffies <= jift)
+		;
+
+	if (jiffies > jift)
+		mydbg("%s - port %d timout of checking transmitter empty\n",
+		      __func__, port->number);
+	else
+		mydbg("%s - port %d checking transmitter empty succeded\n",
+		      __func__, port->number);
+
+	status =
+	    BoxGetRegister(serial, UartNumber, MODEM_CONTROL_REGISTER,
+			   &MCR_Value);
+	mydbg(__FILE__ "BoxGetRegister MCR = 0x%x.\n", MCR_Value);
+
+	if (status >= 0) {
+		MCR_Value &= ~(SERIAL_MCR_DTR | SERIAL_MCR_RTS);
+		/* status = BoxSetRegister(serial, UartNumber, MODEM_CONTROL_REGISTER, MCR_Value); */
+	}
+
+	/* Close uart channel */
+	status = BoxOPenCloseChannel(serial, UartNumber, 0, &ChannelData);
+	if (status < 0)
+		mydbg("%s - port %d BoxOPenCloseChannel failed.\n",
+		      __func__, port->number);
+
+	serial->num_OpenCount--;
+
+}
+
+static int serial_write(struct tty_struct *tty, const unsigned char *buf,
+			int count)
+{
+	struct usb_serial_port *port =
+	    (struct usb_serial_port *)tty->driver_data;
+	struct usb_serial *serial;
+	int retval = -EINVAL;
+	unsigned int UartNumber;
+	int from_user = 0;
+
+	serial = get_usb_serial(port, __func__);
+	if (serial == NULL)
+		return -ENODEV;
+	/* This can happen if we get disconnected a */
+	if (port->open_count == 0)
+		return -ENODEV;
+	UartNumber = port->tty->index - serial->minor;
+
+	mydbg("%s - port %d, %d byte(s)\n", __func__, port->number, count);
+	mydbg("%s - port->RxHolding =  %d\n", __func__, port->RxHolding);
+
+	if (!port->open_count) {
+		mydbg("%s - port not opened\n", __func__);
+		goto exit;
+	}
+
+	retval = qt_write(port, from_user, buf, count);
+
+exit:
+	return retval;
+}
+
+static int qt_write(struct usb_serial_port *port, int from_user,
+		    const unsigned char *buf, int count)
+{
+	int result;
+	unsigned int UartNumber;
+
+	struct usb_serial *serial = get_usb_serial(port, __func__);
+	if (serial == NULL)
+		return -ENODEV;
+
+	mydbg("%s - port %d\n", __func__, port->number);
+
+	if (count == 0) {
+		mydbg("%s - write request of 0 bytes\n", __func__);
+		return 0;
+	}
+
+	UartNumber = port->tty->index - serial->minor;
+	/* only do something if we have a bulk out endpoint */
+	if (serial->num_bulk_out) {
+		if (port->write_urb->status == -EINPROGRESS) {
+			mydbg("%s - already writing\n", __func__);
+			return 0;
+		}
+
+		count =
+		    (count > port->bulk_out_size) ? port->bulk_out_size : count;
+
+		if (from_user) {
+			if (copy_from_user
+			    (port->write_urb->transfer_buffer, buf, count))
+				return -EFAULT;
+		} else {
+			memcpy(port->write_urb->transfer_buffer, buf, count);
+		}
+
+		/* usb_serial_debug_data(__FILE__, __func__, count, port->write_urb->transfer_buffer); */
+
+		/* set up our urb */
+
+		usb_fill_bulk_urb(port->write_urb, serial->dev,
+				  usb_sndbulkpipe(serial->dev,
+						  port->
+						  bulk_out_endpointAddress),
+				  port->write_urb->transfer_buffer, count,
+				  qt_write_bulk_callback, port);
+
+		/* send the data out the bulk port */
+		result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
+		if (result)
+			mydbg("%s - failed submitting write urb, error %d\n",
+			      __func__, result);
+		else
+			result = count;
+
+		return result;
+	}
+
+	/* no bulk out, so return 0 bytes written */
+	return 0;
+}
+
+static void qt_write_bulk_callback(struct urb *urb)
+{
+	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+	struct usb_serial *serial = get_usb_serial(port, __func__);
+
+	mydbg("%s - port %d\n", __func__, port->number);
+
+	if (!serial) {
+		mydbg("%s - bad serial pointer, exiting\n", __func__);
+		return;
+	}
+
+	if (urb->status) {
+		mydbg("%s - nonzero write bulk status received: %d\n",
+		      __func__, urb->status);
+		return;
+	}
+	port_softint(&port->work);
+	schedule_work(&port->work);
+
+	return;
+}
+
+static void port_softint(struct work_struct *work)
+{
+	struct usb_serial_port *port =
+	    container_of(work, struct usb_serial_port, work);
+	struct usb_serial *serial = get_usb_serial(port, __func__);
+	struct tty_struct *tty;
+
+	mydbg("%s - port %d\n", __func__, port->number);
+
+	if (!serial)
+		return;
+
+	tty = port->tty;
+	if (!tty)
+		return;
+#if 0
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP))
+	    && tty->ldisc.write_wakeup) {
+		mydbg("%s - write wakeup call.\n", __func__);
+		(tty->ldisc.write_wakeup) (tty);
+	}
+#endif
+
+	wake_up_interruptible(&tty->write_wait);
+}
+static int serial_write_room(struct tty_struct *tty)
+{
+	struct usb_serial_port *port =
+	    (struct usb_serial_port *)tty->driver_data;
+	struct usb_serial *serial = get_usb_serial(port, __func__);
+	int retval = -EINVAL;
+
+	if (!serial)
+		return -ENODEV;
+
+	down(&port->sem);
+
+	mydbg("%s - port %d\n", __func__, port->number);
+
+	if (!port->open_count) {
+		mydbg("%s - port not open\n", __func__);
+		goto exit;
+	}
+
+	retval = qt_write_room(port);
+
+exit:
+	up(&port->sem);
+	return retval;
+}
+static int qt_write_room(struct usb_serial_port *port)
+{
+	struct usb_serial *serial = port->serial;
+	int room = 0;
+	if (port->closePending == 1) {
+		mydbg("%s - port->closePending == 1\n", __func__);
+		return -ENODEV;
+	}
+
+	mydbg("%s - port %d\n", __func__, port->number);
+
+	if (serial->num_bulk_out) {
+		if (port->write_urb->status != -EINPROGRESS)
+			room = port->bulk_out_size;
+	}
+
+	mydbg("%s - returns %d\n", __func__, room);
+	return room;
+}
+static int serial_chars_in_buffer(struct tty_struct *tty)
+{
+	struct usb_serial_port *port =
+	    (struct usb_serial_port *)tty->driver_data;
+	struct usb_serial *serial = get_usb_serial(port, __func__);
+	int retval = -EINVAL;
+
+	if (!serial)
+		return -ENODEV;
+
+	down(&port->sem);
+
+	mydbg("%s = port %d\n", __func__, port->number);
+
+	if (!port->open_count) {
+		mydbg("%s - port not open\n", __func__);
+		goto exit;
+	}
+
+	retval = qt_chars_in_buffer(port);
+
+exit:
+	up(&port->sem);
+	return retval;
+}
+
+static int qt_chars_in_buffer(struct usb_serial_port *port)
+{
+	struct usb_serial *serial = port->serial;
+	int chars = 0;
+
+	mydbg("%s - port %d\n", __func__, port->number);
+
+	if (serial->num_bulk_out) {
+		if (port->write_urb->status == -EINPROGRESS)
+			chars = port->write_urb->transfer_buffer_length;
+	}
+
+	mydbg("%s - returns %d\n", __func__, chars);
+	return chars;
+}
+
+static int serial_tiocmset(struct tty_struct *tty, struct file *file,
+			   unsigned int set, unsigned int clear)
+{
+
+	struct usb_serial_port *port =
+	    (struct usb_serial_port *)tty->driver_data;
+	struct usb_serial *serial = get_usb_serial(port, __func__);
+	int retval = -ENODEV;
+	unsigned int UartNumber;
+	mydbg("In %s \n", __func__);
+
+	if (!serial)
+		return -ENODEV;
+
+	UartNumber = port->tty->index - serial->minor;
+
+	down(&port->sem);
+
+	mydbg("%s - port %d \n", __func__, port->number);
+	mydbg("%s - port->RxHolding = %d\n", __func__, port->RxHolding);
+
+	if (!port->open_count) {
+		mydbg("%s - port not open\n", __func__);
+		goto exit;
+	}
+
+	retval = qt_tiocmset(port, file, set);
+
+exit:
+	up(&port->sem);
+	return retval;
+}
+
+static int qt_tiocmset(struct usb_serial_port *port, struct file *file,
+		       unsigned int value)
+{
+
+	__u8 MCR_Value;
+	int status;
+	unsigned int UartNumber;
+
+	struct usb_serial *serial = get_usb_serial(port, __func__);
+	if (serial == NULL)
+		return -ENODEV;
+
+	mydbg("%s - port %d\n", __func__, port->number);
+
+    /**************************************************************************************/
+    /**  TIOCMGET
+     */
+	UartNumber = port->tty->index - serial->minor;
+	status =
+	    BoxGetRegister(port->serial, UartNumber, MODEM_CONTROL_REGISTER,
+			   &MCR_Value);
+	if (status < 0)
+		return -ESPIPE;
+
+	/*
+	 * Turn off the RTS and DTR and loopbcck and then only turn on what was
+	 * asked for
+	 */
+	MCR_Value &= ~(SERIAL_MCR_RTS | SERIAL_MCR_DTR | SERIAL_MCR_LOOP);
+	if (value & TIOCM_RTS)
+		MCR_Value |= SERIAL_MCR_RTS;
+	if (value & TIOCM_DTR)
+		MCR_Value |= SERIAL_MCR_DTR;
+	if (value & TIOCM_LOOP)
+		MCR_Value |= SERIAL_MCR_LOOP;
+
+	status =
+	    BoxSetRegister(port->serial, UartNumber, MODEM_CONTROL_REGISTER,
+			   MCR_Value);
+	if (status < 0)
+		return -ESPIPE;
+	else
+		return 0;
+}
+
+static int serial_tiocmget(struct tty_struct *tty, struct file *file)
+{
+
+	struct usb_serial_port *port =
+	    (struct usb_serial_port *)tty->driver_data;
+
+	struct usb_serial *serial = get_usb_serial(port, __func__);
+	int retval = -ENODEV;
+	unsigned int UartNumber;
+	mydbg("In %s \n", __func__);
+
+	if (!serial)
+		return -ENODEV;
+
+	UartNumber = port->tty->index - serial->minor;
+
+	down(&port->sem);
+
+	mydbg("%s - port %d\n", __func__, port->number);
+	mydbg("%s - port->RxHolding = %d\n", __func__, port->RxHolding);
+
+	if (!port->open_count) {
+		mydbg("%s - port not open\n", __func__);
+		goto exit;
+	}
+
+	retval = qt_tiocmget(port, file);
+
+exit:
+	up(&port->sem);
+	return retval;
+}
+
+static int qt_tiocmget(struct usb_serial_port *port, struct file *file)
+{
+
+	__u8 MCR_Value;
+	__u8 MSR_Value;
+	unsigned int result = 0;
+	int status;
+	unsigned int UartNumber;
+	struct tty_struct *tty;
+
+	struct usb_serial *serial = get_usb_serial(port, __func__);
+	if (serial == NULL)
+		return -ENODEV;
+	tty = port->tty;
+
+	mydbg("%s - port %d, tty =0x%p\n", __func__, port->number, tty);
+
+    /**************************************************************************************/
+    /**  TIOCMGET
+     */
+	UartNumber = port->tty->index - serial->minor;
+	status =
+	    BoxGetRegister(port->serial, UartNumber, MODEM_CONTROL_REGISTER,
+			   &MCR_Value);
+	if (status >= 0) {
+		status =
+		    BoxGetRegister(port->serial, UartNumber,
+				   MODEM_STATUS_REGISTER, &MSR_Value);
+
+	}
+
+	if (status >= 0) {
+		result = ((MCR_Value & SERIAL_MCR_DTR) ? TIOCM_DTR : 0)
+		    /* DTR IS SET */
+		    | ((MCR_Value & SERIAL_MCR_RTS) ? TIOCM_RTS : 0)
+		    /* RTS IS SET */
+		    | ((MSR_Value & SERIAL_MSR_CTS) ? TIOCM_CTS : 0)
+		    /* CTS is set */
+		    | ((MSR_Value & SERIAL_MSR_CD) ? TIOCM_CAR : 0)
+		    /* Carrier detect is set */
+		    | ((MSR_Value & SERIAL_MSR_RI) ? TIOCM_RI : 0)
+		    /* Ring indicator set */
+		    | ((MSR_Value & SERIAL_MSR_DSR) ? TIOCM_DSR : 0);
+		/* DSR is set */
+		return result;
+
+	} else
+		return -ESPIPE;
+}
+
+static int serial_ioctl(struct tty_struct *tty, struct file *file,
+			unsigned int cmd, unsigned long arg)
+{
+
+	struct usb_serial_port *port =
+	    (struct usb_serial_port *)tty->driver_data;
+	struct usb_serial *serial = get_usb_serial(port, __func__);
+	int retval = -ENODEV;
+	unsigned int UartNumber;
+	mydbg("In %s \n", __func__);
+
+	if (!serial)
+		return -ENODEV;
+
+	UartNumber = port->tty->index - serial->minor;
+
+	down(&port->sem);
+
+	mydbg("%s - port %d, cmd 0x%.4x\n", __func__, port->number, cmd);
+	mydbg("%s - port->RxHolding = %d\n", __func__, port->RxHolding);
+
+	if (!port->open_count) {
+		mydbg("%s - port not open\n", __func__);
+		goto exit;
+	}
+
+	retval = qt_ioctl(port, file, cmd, arg);
+
+exit:
+	up(&port->sem);
+	return retval;
+}
+static int qt_ioctl(struct usb_serial_port *port, struct file *file,
+		    unsigned int cmd, unsigned long arg)
+{
+	__u8 MCR_Value;
+	__u8 MSR_Value;
+	unsigned short Prev_MSR_Value;
+	unsigned int value, result = 0;
+	int status;
+	unsigned int UartNumber;
+	struct tty_struct *tty;
+
+	struct usb_serial *serial = get_usb_serial(port, __func__);
+	if (serial == NULL)
+		return -ENODEV;
+	tty = port->tty;
+
+	mydbg("%s - port %d, tty =0x%p\n", __func__, port->number, tty);
+
+	/* TIOCMGET */
+	UartNumber = port->tty->index - serial->minor;
+
+	if (cmd == TIOCMGET) {
+		MCR_Value = port->shadowMCR;
+		MSR_Value = port->shadowMSR;
+
+		{
+			result = ((MCR_Value & SERIAL_MCR_DTR) ? TIOCM_DTR : 0)
+			    /* DTR IS SET */
+			    | ((MCR_Value & SERIAL_MCR_RTS) ? TIOCM_RTS : 0)
+			    /* RTS IS SET */
+			    | ((MSR_Value & SERIAL_MSR_CTS) ? TIOCM_CTS : 0)
+			    /* CTS is set */
+			    | ((MSR_Value & SERIAL_MSR_CD) ? TIOCM_CAR : 0)
+			    /* Carrier detect is set */
+			    | ((MSR_Value & SERIAL_MSR_RI) ? TIOCM_RI : 0)
+			    /* Ring indicator set */
+			    | ((MSR_Value & SERIAL_MSR_DSR) ? TIOCM_DSR : 0);
+			/* DSR is set */
+			if (copy_to_user
+			    ((unsigned int *)arg, &result,
+			     sizeof(unsigned int)))
+				return -EFAULT;
+			return 0;
+
+		}
+	}
+
+	/* TIOCMBIS, TIOCMBIC, AND TIOCMSET */
+	if (cmd == TIOCMBIS || cmd == TIOCMBIC || cmd == TIOCMSET) {
+		status =
+		    BoxGetRegister(port->serial, UartNumber,
+				   MODEM_CONTROL_REGISTER, &MCR_Value);
+		if (status < 0)
+			return -ESPIPE;
+		if (copy_from_user
+		    (&value, (unsigned int *)arg, sizeof(unsigned int)))
+			return -EFAULT;
+
+		switch (cmd) {
+		case TIOCMBIS:
+			if (value & TIOCM_RTS)
+				MCR_Value |= SERIAL_MCR_RTS;
+			if (value & TIOCM_DTR)
+				MCR_Value |= SERIAL_MCR_DTR;
+			if (value & TIOCM_LOOP)
+				MCR_Value |= SERIAL_MCR_LOOP;
+			break;
+		case TIOCMBIC:
+			if (value & TIOCM_RTS)
+				MCR_Value &= ~SERIAL_MCR_RTS;
+			if (value & TIOCM_DTR)
+				MCR_Value &= ~SERIAL_MCR_DTR;
+			if (value & TIOCM_LOOP)
+				MCR_Value &= ~SERIAL_MCR_LOOP;
+			break;
+		case TIOCMSET:
+			/*
+			 * Turn off the RTS and DTR and loopbcck and then only
+			 * turn on what was asked for
+			 */
+			MCR_Value &=
+			    ~(SERIAL_MCR_RTS | SERIAL_MCR_DTR |
+			      SERIAL_MCR_LOOP);
+			if (value & TIOCM_RTS)
+				MCR_Value |= SERIAL_MCR_RTS;
+			if (value & TIOCM_DTR)
+				MCR_Value |= SERIAL_MCR_DTR;
+			if (value & TIOCM_LOOP)
+				MCR_Value |= SERIAL_MCR_LOOP;
+			break;
+		default:
+			break;
+
+		}
+		status =
+		    BoxSetRegister(port->serial, UartNumber,
+				   MODEM_CONTROL_REGISTER, MCR_Value);
+		if (status < 0)
+			return -ESPIPE;
+		else {
+			port->shadowMCR = MCR_Value;
+			return 0;
+		}
+
+	}
+    /**************************************************************************************/
+   /**   TIOCMBIS, TIOCMBIC, AND TIOCMSET    end
+   */
+    /**************************************************************************************/
+
+	if (cmd == TIOCMIWAIT) {
+		DECLARE_WAITQUEUE(wait, current);
+		Prev_MSR_Value = port->shadowMSR & SERIAL_MSR_MASK;
+		while (1) {
+			add_wait_queue(&port->wait, &wait);
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule();
+			remove_wait_queue(&port->wait, &wait);
+			/* see if a signal woke us up */
+			if (signal_pending(current))
+				return -ERESTARTSYS;
+			MSR_Value = port->shadowMSR & SERIAL_MSR_MASK;
+			if (MSR_Value == Prev_MSR_Value)
+				return -EIO;	/* no change error */
+
+			if ((arg & TIOCM_RNG
+			     && ((Prev_MSR_Value & SERIAL_MSR_RI) ==
+				 (MSR_Value & SERIAL_MSR_RI)))
+			    || (arg & TIOCM_DSR
+				&& ((Prev_MSR_Value & SERIAL_MSR_DSR) ==
+				    (MSR_Value & SERIAL_MSR_DSR)))
+			    || (arg & TIOCM_CD
+				&& ((Prev_MSR_Value & SERIAL_MSR_CD) ==
+				    (MSR_Value & SERIAL_MSR_CD)))
+			    || (arg & TIOCM_CTS
+				&& ((Prev_MSR_Value & SERIAL_MSR_CTS) ==
+				    (MSR_Value & SERIAL_MSR_CTS)))) {
+				return 0;
+			}
+
+		}
+
+	}
+	mydbg("%s -No ioctl for that one.  port = %d\n", __func__,
+	      port->number);
+
+	return -ENOIOCTLCMD;
+}
+
+static void serial_set_termios(struct tty_struct *tty, struct ktermios *old)
+{
+	struct usb_serial_port *port =
+	    (struct usb_serial_port *)tty->driver_data;
+	struct usb_serial *serial = get_usb_serial(port, __func__);
+
+	if (!serial)
+		return;
+
+	down(&port->sem);
+
+	mydbg("%s - port %d\n", __func__, port->number);
+
+	if (!port->open_count) {
+		mydbg("%s - port not open\n", __func__);
+		goto exit;
+	}
+
+	/* pass on to the driver specific version of this function if it is available */
+	qt_set_termios(port, old);
+
+exit:
+	up(&port->sem);
+}
+
+static void qt_set_termios(struct usb_serial_port *port,
+			   struct ktermios *old_termios)
+{
+	unsigned int cflag;
+	int baud, divisor, remainder;
+	unsigned char LCR_change_to = 0;
+	struct tty_struct *tty;
+	int status;
+	struct usb_serial *serial;
+	__u16 UartNumber;
+	__u16 tmp, tmp2;
+
+	mydbg("%s - port %d\n", __func__, port->number);
+
+	tmp = port->tty->index;
+	mydbg("%s - MINOR(port->tty->index) =  %d\n", __func__, tmp);
+
+	serial = port->serial;
+	tmp2 = serial->minor;
+	mydbg("%s - serial->minor =  %d\n", __func__, tmp2);
+
+	UartNumber = port->tty->index - serial->minor;
+
+	tty = port->tty;
+
+	cflag = tty->termios->c_cflag;
+
+	if (old_termios) {
+		if ((cflag == old_termios->c_cflag)
+		    && (RELEVANT_IFLAG(tty->termios->c_iflag) ==
+			RELEVANT_IFLAG(old_termios->c_iflag))) {
+			mydbg("%s - Nothing to change\n", __func__);
+			return;
+		}
+
+	}
+
+	mydbg("%s - 3\n", __func__);
+
+	switch (cflag) {
+	case CS5:
+		LCR_change_to |= SERIAL_5_DATA;
+		break;
+	case CS6:
+		LCR_change_to |= SERIAL_6_DATA;
+		break;
+	case CS7:
+		LCR_change_to |= SERIAL_7_DATA;
+		break;
+	default:
+	case CS8:
+		LCR_change_to |= SERIAL_8_DATA;
+		break;
+	}
+
+	/* Parity stuff */
+	if (cflag & PARENB) {
+		if (cflag & PARODD)
+			LCR_change_to |= SERIAL_ODD_PARITY;
+		else
+			LCR_change_to |= SERIAL_EVEN_PARITY;
+	}
+	if (cflag & CSTOPB)
+		LCR_change_to |= SERIAL_TWO_STOPB;
+	else
+		LCR_change_to |= SERIAL_TWO_STOPB;
+
+	mydbg("%s - 4\n", __func__);
+	/* Thats the LCR stuff, go ahead and set it */
+	baud = tty_get_baud_rate(tty);
+	if (!baud) {
+		/* pick a default, any default... */
+		baud = 9600;
+	}
+
+	mydbg("%s - got baud = %d\n", __func__, baud);
+
+	divisor = MAX_BAUD_RATE / baud;
+	remainder = MAX_BAUD_RATE % baud;
+	/* Round to nearest divisor */
+	if (((remainder * 2) >= baud) && (baud != 110))
+		divisor++;
+
+	/*
+	 * Set Baud rate to default and turn off (default)flow control here
+	 */
+	status =
+	    BoxSetUart(serial, UartNumber, (unsigned short)divisor,
+		       LCR_change_to);
+	if (status < 0) {
+		mydbg(__FILE__ "BoxSetUart failed\n");
+		return;
+	}
+
+	/* Now determine flow control */
+	if (cflag & CRTSCTS) {
+		mydbg("%s - Enabling HW flow control port %d\n", __func__,
+		      port->number);
+
+		/* Enable RTS/CTS flow control */
+		status = BoxSetHW_FlowCtrl(serial, UartNumber, 1);
+
+		if (status < 0) {
+			mydbg(__FILE__ "BoxSetHW_FlowCtrl failed\n");
+			return;
+		}
+	} else {
+		/* Disable RTS/CTS flow control */
+		mydbg("%s - disabling HW flow control port %d\n", __func__,
+		      port->number);
+
+		status = BoxSetHW_FlowCtrl(serial, UartNumber, 0);
+		if (status < 0) {
+			mydbg(__FILE__ "BoxSetHW_FlowCtrl failed\n");
+			return;
+		}
+
+	}
+
+	/* if we are implementing XON/XOFF, set the start and stop character in
+	 * the device */
+	if (I_IXOFF(tty) || I_IXON(tty)) {
+		unsigned char stop_char = STOP_CHAR(tty);
+		unsigned char start_char = START_CHAR(tty);
+		status =
+		    BoxSetSW_FlowCtrl(serial, UartNumber, stop_char,
+				      start_char);
+		if (status < 0)
+			mydbg(__FILE__ "BoxSetSW_FlowCtrl (enabled) failed\n");
+
+	} else {
+		/* disable SW flow control */
+		status = BoxDisable_SW_FlowCtrl(serial, UartNumber);
+		if (status < 0)
+			mydbg(__FILE__ "BoxSetSW_FlowCtrl (diabling) failed\n");
+
+	}
+
+}
+
+/****************************************************************************
+* BoxGetRegister
+*	issuse a GET_REGISTER vendor-spcific request on the default control pipe
+*	If successful, fills in the  pValue with the register value asked for
+****************************************************************************/
+static int BoxGetRegister(struct usb_serial *serial, unsigned short Uart_Number,
+			  unsigned short Register_Num, __u8 *pValue)
+{
+	int result;
+	__u16 current_length;
+
+	current_length = sizeof(struct qt_get_device_data);
+
+	result =
+	    usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+			    QT_GET_SET_REGISTER, 0xC0, Register_Num,
+			    Uart_Number, (void *)pValue, sizeof(*pValue), 300);
+
+	return result;
+}
+
+/****************************************************************************
+* BoxSetRegister
+*	issuse a GET_REGISTER vendor-spcific request on the default control pipe
+*	If successful, fills in the  pValue with the register value asked for
+****************************************************************************/
+static int BoxSetRegister(struct usb_serial *serial, unsigned short Uart_Number,
+			  unsigned short Register_Num, unsigned short Value)
+{
+	int result;
+	unsigned short RegAndByte;
+
+	RegAndByte = Value;
+	RegAndByte = RegAndByte << 8;
+	RegAndByte = RegAndByte + Register_Num;
+
+/*
+	result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+				 QT_GET_SET_REGISTER, 0xC0, Register_Num,
+				 Uart_Number, NULL, 0, 300);
+*/
+
+	result =
+	    usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			    QT_GET_SET_REGISTER, 0x40, RegAndByte, Uart_Number,
+			    NULL, 0, 300);
+
+	return result;
+}
+
+/**
+ * box_get_device
+ *   Issue a GET_DEVICE vendor-specific request on the default control pipe If
+ *   successful, fills in the qt_get_device_data structure pointed to by
+ *   device_data, otherwise return a negative error number of the problem.
+ */
+static int box_get_device(struct usb_serial *serial,
+			  struct qt_get_device_data *device_data)
+{
+	int result;
+	__u16 current_length;
+	unsigned char *transfer_buffer;
+
+	current_length = sizeof(struct qt_get_device_data);
+	transfer_buffer = kmalloc(current_length, GFP_KERNEL);
+	if (!transfer_buffer)
+		return -ENOMEM;
+
+	result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+				 QT_SET_GET_DEVICE, 0xc0, 0, 0,
+				 transfer_buffer, current_length, 300);
+	if (result > 0)
+		memcpy(device_data, transfer_buffer, current_length);
+	kfree(transfer_buffer);
+
+	return result;
+}
+
+/**
+ * box_set_device
+ *   Issue a SET_DEVICE vendor-specific request on the default control pipe If
+ *   successful returns the number of bytes written, otherwise it returns a
+ *   negative error number of the problem.
+ */
+static int box_set_device(struct usb_serial *serial,
+			  struct qt_get_device_data *device_data)
+{
+	int result;
+	__u16 length;
+	__u16 PortSettings;
+
+	PortSettings = ((__u16) (device_data->portb));
+	PortSettings = (PortSettings << 8);
+	PortSettings += ((__u16) (device_data->porta));
+
+	length = sizeof(struct qt_get_device_data);
+	mydbg("%s - PortSettings = 0x%x\n", __func__, PortSettings);
+
+	result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+				 QT_SET_GET_DEVICE, 0x40, PortSettings,
+				 0, NULL, 0, 300);
+	return result;
+}
+
+/****************************************************************************
+ * BoxOPenCloseChannel
+ * This funciotn notifies the device that the device driver wishes to open a particular UART channel. its
+ * purpose is to allow the device driver and the device to synchronize state information.
+ * OpenClose = 1 for open , 0 for close
+  ****************************************************************************/
+static int BoxOPenCloseChannel(struct usb_serial *serial, __u16 Uart_Number,
+			       __u16 OpenClose,
+			       struct qt_open_channel_data *pDeviceData)
+{
+	int result;
+	__u16 length;
+	__u8 Direcion;
+	unsigned int pipe;
+	length = sizeof(struct qt_open_channel_data);
+
+	/* if opening... */
+	if (OpenClose == 1) {
+		Direcion = USBD_TRANSFER_DIRECTION_IN;
+		pipe = usb_rcvctrlpipe(serial->dev, 0);
+		result =
+		    usb_control_msg(serial->dev, pipe, QT_OPEN_CLOSE_CHANNEL,
+				    Direcion, OpenClose, Uart_Number,
+				    pDeviceData, length, 300);
+
+	} else {
+		Direcion = USBD_TRANSFER_DIRECTION_OUT;
+		pipe = usb_sndctrlpipe(serial->dev, 0);
+		result =
+		    usb_control_msg(serial->dev, pipe, QT_OPEN_CLOSE_CHANNEL,
+				    Direcion, OpenClose, Uart_Number, NULL, 0,
+				    300);
+
+	}
+
+	return result;
+}
+
+/****************************************************************************
+ *  BoxSetPrebufferLevel
+   TELLS BOX WHEN TO ASSERT FLOW CONTROL
+ ****************************************************************************/
+static int BoxSetPrebufferLevel(struct usb_serial *serial)
+{
+	int result;
+	__u16 buffer_length;
+
+	buffer_length = PREFUFF_LEVEL_CONSERVATIVE;
+	result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+				 QT_GET_SET_PREBUF_TRIG_LVL, 0x40,
+				 buffer_length, 0, NULL, 0, 300);
+	return result;
+}
+
+/****************************************************************************
+ *  BoxSetATC
+   TELLS BOX WHEN TO ASSERT automatic transmitter control
+   ****************************************************************************/
+static int BoxSetATC(struct usb_serial *serial, __u16 n_Mode)
+{
+	int result;
+	__u16 buffer_length;
+
+	buffer_length = PREFUFF_LEVEL_CONSERVATIVE;
+
+	result =
+	    usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			    QT_SET_ATF, 0x40, n_Mode, 0, NULL, 0, 300);
+
+	return result;
+}
+
+/****************************************************************************
+* BoxSetUart
+*	issuse a SET_UART vendor-spcific request on the default control pipe
+*	If successful sets baud rate divisor and LCR value
+****************************************************************************/
+static int BoxSetUart(struct usb_serial *serial, unsigned short Uart_Number,
+		      unsigned short default_divisor, unsigned char default_LCR)
+{
+	int result;
+	unsigned short UartNumandLCR;
+
+	UartNumandLCR = (default_LCR << 8) + Uart_Number;
+
+	result =
+	    usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			    QT_GET_SET_UART, 0x40, default_divisor,
+			    UartNumandLCR, NULL, 0, 300);
+
+	return result;
+}
+
+static int BoxSetHW_FlowCtrl(struct usb_serial *serial, unsigned int UartNumber,
+			     int bSet)
+{
+	__u8 MCR_Value = 0;
+	__u8 MSR_Value = 0, MOUT_Value = 0;
+	struct usb_serial_port *port;
+	unsigned int status;
+
+	port = serial->port;
+
+	if (bSet == 1) {
+		/* flow control, box will clear RTS line to prevent remote */
+		MCR_Value = SERIAL_MCR_RTS;
+	}			/* device from xmitting more chars */
+	else {
+		/* no flow control to remote device */
+		MCR_Value = 0;
+
+	}
+	MOUT_Value = MCR_Value << 8;
+
+	if (bSet == 1) {
+		/* flow control, box will inhibit xmit data if CTS line is
+		 * asserted */
+		MSR_Value = SERIAL_MSR_CTS;
+	} else {
+		/* Box will not inhimbe xmit data due to CTS line */
+		MSR_Value = 0;
+	}
+	MOUT_Value |= MSR_Value;
+
+	status =
+	    usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			    QT_HW_FLOW_CONTROL_MASK, 0x40, MOUT_Value,
+			    UartNumber, NULL, 0, 300);
+	return status;
+
+}
+
+static int BoxSetSW_FlowCtrl(struct usb_serial *serial, __u16 UartNumber,
+			     unsigned char stop_char, unsigned char start_char)
+{
+	__u16 nSWflowout;
+	int result;
+
+	nSWflowout = start_char << 8;
+	nSWflowout = (unsigned short)stop_char;
+
+	result =
+	    usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			    QT_SW_FLOW_CONTROL_MASK, 0x40, nSWflowout,
+			    UartNumber, NULL, 0, 300);
+	return result;
+
+}
+static int BoxDisable_SW_FlowCtrl(struct usb_serial *serial, __u16 UartNumber)
+{
+	int result;
+
+	result =
+	    usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			    QT_SW_FLOW_CONTROL_DISABLE, 0x40, 0, UartNumber,
+			    NULL, 0, 300);
+	return result;
+
+}
+
+static void serial_throttle(struct tty_struct *tty)
+{
+	struct usb_serial_port *port =
+	    (struct usb_serial_port *)tty->driver_data;
+	struct usb_serial *serial = get_usb_serial(port, __func__);
+	mydbg("%s - port %d\n", __func__, port->number);
+
+	if (!serial)
+		return;
+
+	down(&port->sem);
+
+	if (!port->open_count) {
+		mydbg("%s - port not open\n", __func__);
+		goto exit;
+	}
+	/* shut down any bulk reads that may be going on */
+/*	usb_unlink_urb (port->read_urb); */
+	/* pass on to the driver specific version of this function */
+	port->RxHolding = 1;
+	mydbg("%s - port->RxHolding = 1\n", __func__);
+
+exit:
+	up(&port->sem);
+	return;
+}
+
+static void serial_unthrottle(struct tty_struct *tty)
+{
+	struct usb_serial_port *port =
+	    (struct usb_serial_port *)tty->driver_data;
+	struct usb_serial *serial = get_usb_serial(port, __func__);
+	unsigned int result;
+
+	if (!serial)
+		return;
+	down(&port->sem);
+
+	mydbg("%s - port %d\n", __func__, port->number);
+
+	if (!port->open_count) {
+		mydbg("%s - port not open\n", __func__);
+		goto exit;
+	}
+
+	if (port->RxHolding == 1) {
+		mydbg("%s -port->RxHolding == 1\n", __func__);
+
+		port->RxHolding = 0;
+		mydbg("%s - port->RxHolding = 0\n", __func__);
+
+		/* if we have a bulk endpoint, start it up */
+		if ((serial->num_bulk_in) && (port->ReadBulkStopped == 1)) {
+			/* Start reading from the device */
+			usb_fill_bulk_urb(port->read_urb, serial->dev,
+					  usb_rcvbulkpipe(serial->dev,
+							  port->
+							  bulk_in_endpointAddress),
+					  port->read_urb->transfer_buffer,
+					  port->read_urb->
+					  transfer_buffer_length,
+					  qt_read_bulk_callback, port);
+			result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+			if (result)
+				err("%s - failed restarting read urb, error %d",
+				    __func__, result);
+		}
+	}
+exit:
+	up(&port->sem);
+	return;
+
+}
+
+static int serial_break(struct tty_struct *tty, int break_state)
+{
+	struct usb_serial_port *port =
+	    (struct usb_serial_port *)tty->driver_data;
+	struct usb_serial *serial = get_usb_serial(port, __func__);
+	__u16 UartNumber, Break_Value;
+	unsigned int result;
+
+	UartNumber = port->tty->index - serial->minor;
+	if (!serial)
+		return -ENODEV;
+
+	if (break_state == -1)
+		Break_Value = 1;
+	else
+		Break_Value = 0;
+
+	down(&port->sem);
+
+	mydbg("%s - port %d\n", __func__, port->number);
+
+	if (!port->open_count) {
+		mydbg("%s - port not open\n", __func__);
+		goto exit;
+	}
+
+	result =
+	    usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			    QT_BREAK_CONTROL, 0x40, Break_Value, UartNumber,
+			    NULL, 0, 300);
+
+exit:
+	up(&port->sem);
+	return 0;
+}
+
+static int ioctl_serial_usb(struct inode *innod, struct file *filp, unsigned int cmd,
+		     unsigned long arg)
+{
+
+	unsigned err;
+	unsigned ucOPR_NewValue, uc_Value;
+	int *p_Num_of_adapters, counts, index, *p_QMCR_Value;
+	struct identity *p_Identity_of;
+	struct identity Identity_of;
+	struct usb_serial *lastserial, *serial;
+
+	mydbg(KERN_DEBUG "ioctl_serial_usb  cmd =\n");
+	if (_IOC_TYPE(cmd) != SERIALQT_PCI_IOC_MAGIC)
+		return -ENOTTY;
+	if (_IOC_NR(cmd) > SERIALQT_IOC_MAXNR)
+		return -ENOTTY;
+	mydbg(KERN_DEBUG "ioctl_serial_usb  cmd = 0x%x\n", cmd);
+	err = 0;
+	switch (cmd) {
+
+	case SERIALQT_WRITE_QMCR:
+		err = -ENOTTY;
+		index = arg >> 16;
+		counts = 0;
+
+		ucOPR_NewValue = arg;
+
+		err = EmulateWriteQMCR_Reg(index, ucOPR_NewValue);
+		break;
+
+	case SERIALQT_READ_QMCR:
+		err = -ENOTTY;
+		p_QMCR_Value = (int *)arg;
+		index = arg >> 16;
+		counts = 0;
+
+		err = EmulateReadQMCR_Reg(index, &uc_Value);
+		if (err == 0)
+			err = put_user(uc_Value, p_QMCR_Value);
+		break;
+
+	case SERIALQT_GET_NUMOF_UNITS:
+		p_Num_of_adapters = (int *)arg;
+		counts = 0;	/* Initialize counts to zero */
+		/* struct usb_serial *lastserial = serial_table[0], *serial; */
+		lastserial = serial_table[0];
+
+		mydbg(KERN_DEBUG "SERIALQT_GET_NUMOF_UNITS \n");
+		/* if first pointer is nonull, we at least have one box */
+		if (lastserial)
+			counts = 1;	/* we at least have one box */
+
+		for (index = 1; index < SERIAL_TTY_MINORS; index++) {
+			serial = serial_table[index];
+			if (serial) {
+				if (serial != lastserial) {
+					/* we had a change in the array, hence
+					 * another box is there */
+					lastserial = serial;
+					counts++;
+				}
+			} else
+				break;
+		}
+
+		mydbg(KERN_DEBUG "ioctl_serial_usb writting counts = %d",
+		      counts);
+
+		err = put_user(counts, p_Num_of_adapters);
+
+		break;
+	case SERIALQT_GET_THIS_UNIT:
+		counts = 0;
+		p_Identity_of = (struct identity *)arg;
+		/* copy user structure to local variable */
+		get_user(Identity_of.index, &p_Identity_of->index);
+		mydbg(KERN_DEBUG "SERIALQT_GET_THIS_UNIT Identity_of.index\n");
+		mydbg(KERN_DEBUG
+		      "SERIALQT_GET_THIS_UNIT Identity_of.index= 0x%x\n",
+		      Identity_of.index);
+
+		err = -ENOTTY;
+		serial = find_the_box(Identity_of.index);
+		if (serial) {
+			err =
+			    put_user(serial->product,
+				     &p_Identity_of->n_identity);
+
+		}
+		break;
+
+	case SERIALQT_IS422_EXTENDED:
+		err = -ENOTTY;
+		mydbg(KERN_DEBUG "SERIALQT_IS422_EXTENDED \n");
+		index = arg >> 16;
+
+		counts = 0;
+
+		mydbg(KERN_DEBUG
+		      "SERIALQT_IS422_EXTENDED, looking Identity_of.indext = 0x%x\n",
+		      index);
+		serial = find_the_box(index);
+		if (serial) {
+			mydbg("%s index = 0x%x, serial = 0x%p\n", __func__,
+			      index, serial);
+			for (counts = 0; serqt_422_table[counts] != 0; counts++) {
+
+				mydbg
+				    ("%s serial->product = = 0x%x, serqt_422_table[counts] = 0x%x\n",
+				     __func__, serial->product,
+				     serqt_422_table[counts]);
+				if (serial->product == serqt_422_table[counts]) {
+					err = 0;
+
+					mydbg
+					    ("%s found match for 422extended\n",
+					     __func__);
+					break;
+				}
+			}
+		}
+		break;
+
+	default:
+		err = -ENOTTY;
+	}
+
+	mydbg("%s returning err = 0x%x\n", __func__, err);
+	return err;
+}
+
+static struct usb_serial *find_the_box(unsigned int index)
+{
+	struct usb_serial *lastserial, *foundserial, *serial;
+	int counts = 0, index2;
+	lastserial = serial_table[0];
+	foundserial = NULL;
+	for (index2 = 0; index2 < SERIAL_TTY_MINORS; index2++) {
+		serial = serial_table[index2];
+
+		mydbg("%s index = 0x%x, index2 = 0x%x, serial = 0x%p\n",
+		      __func__, index, index2, serial);
+
+		if (serial) {
+			/* first see if this is the unit we'er looking for */
+			mydbg
+			    ("%s inside if(serial) counts = 0x%x , index = 0x%x\n",
+			     __func__, counts, index);
+			if (counts == index) {
+				/* we found the one we're looking for, copythe
+				 * product Id to user */
+				mydbg("%s we found the one we're looking for serial = 0x%p\n",
+				     __func__, serial);
+				foundserial = serial;
+				break;
+			}
+
+			if (serial != lastserial) {
+				/* when we have a change in the pointer */
+				lastserial = serial;
+				counts++;
+			}
+		} else
+			break;	/* no matches */
+	}
+
+	mydbg("%s returning foundserial = 0x%p\n", __func__, foundserial);
+	return foundserial;
+}
+
+static int EmulateWriteQMCR_Reg(int index, unsigned uc_value)
+{
+
+	__u16 ATC_Mode = 0;
+	struct usb_serial *serial;
+	int status;
+	struct qt_get_device_data DeviceData;
+	unsigned uc_temp = 0;
+	mydbg("Inside %s, uc_value = 0x%x\n", __func__, uc_value);
+
+	DeviceData.porta = 0;
+	DeviceData.portb = 0;
+	serial = find_the_box(index);
+	/* Determine Duplex mode */
+	if (!(serial))
+		return -ENOTTY;
+	status = box_get_device(serial, &DeviceData);
+	if (status < 0) {
+		mydbg(__FILE__ "box_set_device failed\n");
+		return status;
+	}
+
+	uc_temp = uc_value & QMCR_HALF_DUPLEX_MASK;
+	switch (uc_temp) {
+	case QMCR_FULL_DUPLEX:
+		DeviceData.porta &= ~DUPMODE_BITS;
+		DeviceData.porta |= FULL_DUPLEX;
+		ATC_Mode = ATC_DISABLED;
+		break;
+	case QMCR_HALF_DUPLEX_RTS:
+		DeviceData.porta &= ~DUPMODE_BITS;
+		DeviceData.porta |= HALF_DUPLEX_RTS;
+		ATC_Mode = ATC_RTS_ENABLED;
+		break;
+	case QMCR_HALF_DUPLEX_DTR:
+		DeviceData.porta &= ~DUPMODE_BITS;
+		DeviceData.porta |= HALF_DUPLEX_DTR;
+		ATC_Mode = ATC_DTR_ENABLED;
+		break;
+	default:
+		break;
+	}
+
+	uc_temp = uc_value & QMCR_CONNECTOR_MASK;
+	switch (uc_temp) {
+	case QMCR_MODEM_CONTROL:
+		DeviceData.portb &= ~LOOPMODE_BITS;	/* reset connection bits */
+		DeviceData.portb |= MODEM_CTRL;
+		break;
+	case QMCR_ALL_LOOPBACK:
+		DeviceData.portb &= ~LOOPMODE_BITS;	/* reset connection bits */
+		DeviceData.portb |= ALL_LOOPBACK;
+		break;
+	}
+
+	mydbg(__FILE__ "Calling box_set_device with failed\n");
+	status = box_set_device(serial, &DeviceData);
+	if (status < 0) {
+		mydbg(__FILE__ "box_set_device failed\n");
+		return status;
+	}
+
+	/* This bit (otherwise unused) i'll used  to detect whether ATC is
+	 * selected */
+	if (uc_value & QMCR_RX_EN_MASK) {
+
+		mydbg(__FILE__
+		      "calling BoxsetATC with DeviceData.porta = 0x%x and DeviceData.portb = 0x%x\n",
+		      DeviceData.porta, DeviceData.portb);
+		status = BoxSetATC(serial, ATC_Mode);
+		if (status < 0) {
+			mydbg(__FILE__ "BoxSetATC failed\n");
+			return status;
+		}
+	} else {
+
+		mydbg(__FILE__
+		      "calling BoxsetATC with DeviceData.porta = 0x%x and DeviceData.portb = 0x%x\n",
+		      DeviceData.porta, DeviceData.portb);
+		status = BoxSetATC(serial, ATC_DISABLED);
+		if (status < 0) {
+			mydbg(__FILE__ "BoxSetATC failed\n");
+			return status;
+		}
+	}
+
+	return 0;
+
+}
+
+static int EmulateReadQMCR_Reg(int index, unsigned *uc_value)
+{
+	struct usb_serial *serial;
+	int status;
+	struct qt_get_device_data DeviceData;
+	__u8 uc_temp;
+
+	*uc_value = 0;
+
+	serial = find_the_box(index);
+	if (!(serial))
+		return -ENOTTY;
+
+	status = box_get_device(serial, &DeviceData);
+	if (status < 0) {
+		mydbg(__FILE__ "box_get_device failed\n");
+		return status;
+	}
+	uc_temp = DeviceData.porta & DUPMODE_BITS;
+	switch (uc_temp) {
+	case FULL_DUPLEX:
+		*uc_value |= QMCR_FULL_DUPLEX;
+		break;
+	case HALF_DUPLEX_RTS:
+		*uc_value |= QMCR_HALF_DUPLEX_RTS;
+		break;
+	case HALF_DUPLEX_DTR:
+		*uc_value |= QMCR_HALF_DUPLEX_DTR;
+		break;
+	default:
+		break;
+	}
+
+	/* I use this for ATC control se */
+	uc_temp = DeviceData.portb & LOOPMODE_BITS;
+
+	switch (uc_temp) {
+	case ALL_LOOPBACK:
+		*uc_value |= QMCR_ALL_LOOPBACK;
+		break;
+	case MODEM_CTRL:
+		*uc_value |= QMCR_MODEM_CONTROL;
+		break;
+	default:
+		break;
+
+	}
+	return 0;
+
+}
+
+static int __init serqt_usb_init(void)
+{
+	int i, result;
+	int status = 0;
+
+	mydbg("%s\n", __func__);
+	tty_set_operations(&serial_tty_driver, &serial_ops);
+	result = tty_register_driver(&serial_tty_driver);
+	if (result) {
+		mydbg("tty_register_driver failed error = 0x%x", result);
+		return result;
+	}
+
+	/* Initalize our global data */
+	for (i = 0; i < SERIAL_TTY_MINORS; ++i)
+		serial_table[i] = NULL;
+
+	/* register this driver with the USB subsystem */
+	result = usb_register(&serqt_usb_driver);
+	if (result < 0) {
+		err("usb_register failed for the " __FILE__
+		    " driver. Error number %d", result);
+		return result;
+	}
+	status = 0;		/* Dynamic assignment of major number */
+	major_number =
+	    register_chrdev(status, "SerialQT_USB", &serialqt_usb_fops);
+	if (major_number < 0) {
+		mydbg(KERN_DEBUG "No devices found \n\n");
+		return -EBUSY;
+	} else
+		mydbg(KERN_DEBUG "SerQT_USB major number assignment = %d \n\n",
+		      major_number);
+
+	printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION);
+	return 0;
+}
+
+static void __exit serqt_usb_exit(void)
+{
+	/* deregister this driver with the USB subsystem */
+	usb_deregister(&serqt_usb_driver);
+	tty_unregister_driver(&serial_tty_driver);
+	unregister_chrdev(major_number, "SerialQT_USB");
+}
+
+module_init(serqt_usb_init);
+module_exit(serqt_usb_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/slicoss/gbdownload.h b/drivers/staging/slicoss/gbdownload.h
deleted file mode 100644
index 794432bd..0000000
--- a/drivers/staging/slicoss/gbdownload.h
+++ /dev/null
@@ -1,8215 +0,0 @@
-#define MOJAVE_UCODE_VERS_STRING	"1.2"
-#define MOJAVE_UCODE_VERS_DATE  	"2006/03/27 15:12:22"
-#define MOJAVE_UCODE_HOSTIF_ID  	3
-
-static s32 MNumSections = 0x2;
-static u32 MSectionSize[] =
-{
-	0x00008000, 0x00010000,
-};
-
-static u32 MSectionStart[] =
-{
-	0x00000000, 0x00008000,
-};
-
-static u8 MojaveUCode[2][65536] =
-{
-	{
-	0x12, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x18, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x03, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
-	0x98, 0xb0, 0x01, 0x00, 0x04, 0x80, 0xa2, 0x40, 0xfd, 0x7f, 0x00, 0x00,
-	0x09, 0x00, 0xa2, 0x49, 0xdd, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0x80, 0xb2, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xd1, 0xb1, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0x80, 0xb2, 0x01, 0x00, 0x09, 0x00, 0xa2, 0x40,
-	0x75, 0x7d, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x0b, 0x00, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0x09, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x11, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x80, 0x1f, 0xe9, 0x18, 0x31, 0x00, 0x00, 0x00, 0x00, 0x41, 0xe9,
-	0x80, 0xb2, 0x01, 0x00, 0x0f, 0x00, 0x40, 0xe9, 0x80, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x16, 0x00, 0x29, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x16, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
-	0x0f, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x50, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x10, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x1c, 0x00, 0x29, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x1c, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
-	0x11, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x50, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x01, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x20, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x22, 0x00, 0x29, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x22, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
-	0x0e, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
-	0xdd, 0x81, 0x01, 0x00, 0x2b, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x3c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x27, 0x00, 0x14, 0xbc,
-	0x80, 0x32, 0x00, 0x00, 0x14, 0x01, 0x13, 0xbc, 0x80, 0x32, 0x00, 0x00,
-	0x54, 0x95, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0xff, 0xff, 0x00, 0x40,
-	0xe5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x40, 0x49, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0xb7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xb5, 0xb3, 0x01, 0x00,
-	0xd9, 0x00, 0x00, 0x40, 0xb3, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xb6, 0xd3, 0x01, 0x00, 0x32, 0x00, 0x95, 0xe8, 0x80, 0x32, 0x00, 0x00,
-	0xff, 0xff, 0x00, 0xe8, 0x80, 0x88, 0x01, 0x00, 0xb8, 0x00, 0x26, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xfd, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xff, 0xb3, 0x01, 0x00, 0x3c, 0x00, 0x22, 0x50,
-	0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfd, 0x93, 0x01, 0x00,
-	0xa5, 0xa5, 0x00, 0xa6, 0xb4, 0xa7, 0x01, 0x00, 0x3c, 0x00, 0xa2, 0x50,
-	0xb5, 0x73, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x3c, 0x00, 0xa2, 0x45, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0xfd, 0x93, 0x01, 0x00, 0x41, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x7f, 0x00, 0x00, 0x20, 0xf5, 0xcf, 0x01, 0x00, 0x1c, 0x01, 0x00, 0xfa,
-	0xb3, 0x33, 0x01, 0x00, 0xa5, 0xa5, 0x00, 0xda, 0xb5, 0xab, 0x01, 0x00,
-	0x99, 0x00, 0xa2, 0x50, 0xb5, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0xfd, 0x93, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x44, 0xb3, 0x33, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
-	0xd7, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0xda, 0xed, 0x8b, 0x01, 0x00,
-	0xd5, 0x00, 0x00, 0x46, 0xb3, 0x33, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40,
-	0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xd7, 0xb1, 0x01, 0x00,
-	0xff, 0x00, 0x00, 0xda, 0xef, 0x8b, 0x01, 0x00, 0xff, 0x00, 0x00, 0xda,
-	0xe3, 0x8f, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x48, 0xb3, 0x33, 0x01, 0x00,
-	0x3c, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0xff, 0x00, 0x00, 0xda,
-	0xd7, 0x8d, 0x01, 0x00, 0xff, 0xff, 0x00, 0xda, 0xf1, 0xdb, 0x01, 0x00,
-	0xff, 0x00, 0x00, 0xda, 0xe9, 0x8b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
-	0xe9, 0xe3, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x4b, 0xb3, 0x33, 0x01, 0x00,
-	0x2c, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
-	0xd7, 0xb1, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x4c, 0xb3, 0x33, 0x01, 0x00,
-	0xff, 0xff, 0x00, 0xda, 0xeb, 0xdb, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x4e,
-	0xb3, 0x33, 0x01, 0x00, 0x03, 0x00, 0x00, 0xda, 0x81, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5c, 0x81, 0xe0, 0x01, 0x00, 0xff, 0xff, 0x00, 0xda,
-	0xb5, 0xdb, 0x01, 0x00, 0x5c, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x01, 0x00, 0x00, 0xda, 0xb5, 0xcf, 0x01, 0x00, 0x00, 0xf0, 0x00, 0xa7,
-	0xb4, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0x81, 0x94, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xd8, 0xb1, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x50,
-	0xb3, 0x33, 0x01, 0x00, 0xff, 0xff, 0x00, 0xda, 0xb5, 0x8b, 0x01, 0x00,
-	0x62, 0x00, 0x26, 0x4c, 0xb5, 0x63, 0x00, 0x00, 0x01, 0x00, 0x00, 0xda,
-	0xb5, 0xcf, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xdf, 0xb1, 0x01, 0x00,
-	0xd5, 0x00, 0x00, 0x52, 0xb3, 0x33, 0x01, 0x00, 0xff, 0x00, 0x00, 0xda,
-	0x4b, 0x89, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda, 0xdf, 0xf7, 0x01, 0x00,
-	0xff, 0x00, 0x00, 0xef, 0xdf, 0x8b, 0x01, 0x00, 0x69, 0x00, 0x22, 0x40,
-	0xdf, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xfd, 0x93, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0xda, 0xd7, 0xe5, 0x01, 0x00, 0xf8, 0x00, 0x00, 0xda,
-	0xb3, 0x8b, 0x01, 0x00, 0x34, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd9, 0xd7, 0xb1, 0x01, 0x00, 0x02, 0x00, 0x00, 0xd9,
-	0xd5, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xd7, 0xb1, 0x01, 0x00,
-	0x22, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xb5, 0xf3, 0x01, 0x00,
-	0x03, 0x00, 0x00, 0xda, 0x7b, 0x89, 0x01, 0x00, 0x00, 0x01, 0x00, 0x40,
-	0xdd, 0x9b, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x5d, 0xb3, 0x33, 0x01, 0x00,
-	0xff, 0xff, 0x00, 0xda, 0xe7, 0x8b, 0x01, 0x00, 0x8a, 0x00, 0x26, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xfd, 0x93, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0xe7, 0xe3, 0x01, 0x00, 0x00, 0x01, 0x00, 0x40,
-	0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xe7, 0x97, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf3, 0xd7, 0xb1, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x5e,
-	0xb3, 0x33, 0x01, 0x00, 0xff, 0x00, 0x00, 0xda, 0xe5, 0x8b, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0xe5, 0xe3, 0x01, 0x00, 0x08, 0x01, 0x00, 0x40,
-	0xd5, 0x99, 0x01, 0x00, 0xff, 0x00, 0x00, 0xda, 0xb5, 0x8f, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf7, 0xb5, 0x97, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
-	0xd7, 0xb1, 0x01, 0x00, 0x3c, 0x01, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0xe5, 0x97, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
-	0xd7, 0xb1, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40, 0xdd, 0x9b, 0x01, 0x00,
-	0x96, 0x00, 0x22, 0xf5, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xee, 0xd5, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf6, 0xeb, 0x97, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf5,
-	0xd7, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x00, 0xea, 0xd4, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf7, 0xe3, 0x97, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf1,
-	0xd7, 0xb1, 0x01, 0x00, 0x3c, 0x00, 0x00, 0xee, 0xdd, 0xcb, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xee, 0xd5, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0xe9, 0x97, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf4, 0xd7, 0xb1, 0x01, 0x00,
-	0xd5, 0x00, 0x00, 0x4a, 0xb3, 0x33, 0x01, 0x00, 0xff, 0xff, 0x00, 0xda,
-	0xdd, 0x89, 0x01, 0x00, 0xb7, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x05, 0x00, 0x00, 0xa6,
-	0xd6, 0xb1, 0x01, 0x00, 0x9a, 0x13, 0x00, 0xeb, 0xd6, 0x99, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x02, 0x00, 0xa6,
-	0xd6, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x00, 0xeb, 0xd6, 0x99, 0x01, 0x00,
-	0x2c, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x05, 0x00, 0x00, 0xa6,
-	0xd6, 0xb1, 0x01, 0x00, 0x9a, 0x13, 0x00, 0xeb, 0xd6, 0x99, 0x01, 0x00,
-	0x3c, 0x01, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40,
-	0xd7, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xfd, 0x93, 0x01, 0x00,
-	0x3c, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa6,
-	0xd6, 0xb1, 0x01, 0x00, 0x00, 0x01, 0x00, 0xeb, 0xd6, 0x99, 0x01, 0x00,
-	0x00, 0x01, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x06, 0x00, 0x00, 0xa6,
-	0xd6, 0xb1, 0x01, 0x00, 0x9a, 0x13, 0x00, 0xeb, 0xd6, 0x99, 0x01, 0x00,
-	0x08, 0x01, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x02, 0x00, 0xa6,
-	0xd6, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x00, 0xeb, 0xd6, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xd9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xdf, 0xb1, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
-	0xa0, 0x00, 0x00, 0xa6, 0xd6, 0xb1, 0x01, 0x00, 0x64, 0x00, 0x00, 0x40,
-	0x4b, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7b, 0x99, 0x01, 0x00,
-	0x02, 0x04, 0x00, 0x40, 0xdd, 0x99, 0x01, 0x00, 0xb7, 0x00, 0x13, 0xbc,
-	0x80, 0x32, 0x00, 0x00, 0x02, 0x08, 0x00, 0x40, 0xdd, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0xdd, 0x91, 0x01, 0x00, 0xb8, 0x00, 0x95, 0xe8,
-	0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x2f, 0xe9, 0xfa, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xd1, 0xb1, 0x01, 0x00, 0xff, 0x00, 0x00, 0x42,
-	0x80, 0x88, 0x01, 0x00, 0x34, 0x00, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
-	0xb8, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x02, 0x80, 0x22, 0x40, 0x80, 0x32, 0x00, 0x00,
-	0xb8, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f,
-	0x81, 0xb0, 0x01, 0x00, 0xca, 0x00, 0x09, 0xf9, 0x81, 0x32, 0x00, 0x00,
-	0xc8, 0x00, 0x08, 0xf9, 0x81, 0x32, 0x00, 0x00, 0xd4, 0x00, 0x1f, 0xfd,
-	0xf9, 0x33, 0x00, 0x00, 0xc7, 0x00, 0x9e, 0xfd, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4a, 0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x80, 0x48,
-	0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xf7, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x49, 0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
-	0x19, 0xb1, 0x01, 0x00, 0xcf, 0x00, 0x0a, 0xf9, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x40, 0xfb, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0xfd,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x07, 0x80, 0xf9, 0xf3, 0x8f, 0x01, 0x00,
-	0x00, 0x07, 0x42, 0xf9, 0xf3, 0x8f, 0x01, 0x00, 0xd3, 0x00, 0xa2, 0xff,
-	0xf7, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x43, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0xa2, 0xff, 0xfb, 0xef, 0x00, 0x00, 0x00, 0x00, 0x80, 0xfc,
-	0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb0, 0x01, 0x00,
-	0xd8, 0x00, 0x06, 0xfe, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0xb3, 0xe3, 0x01, 0x00, 0x1c, 0x01, 0x00, 0xfa, 0xb3, 0xc3, 0x00, 0x00,
-	0xda, 0x00, 0x00, 0x42, 0x8d, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x8d, 0xb0, 0x01, 0x00, 0x00, 0x04, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
-	0xeb, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x84, 0x96, 0x80, 0xb2, 0x00, 0x00,
-	0x26, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x25, 0x01, 0x00, 0x40,
-	0x2d, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2d, 0x81, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xda, 0xb5, 0xeb, 0x01, 0x00, 0xe4, 0x00, 0x84, 0x96,
-	0x80, 0x32, 0x00, 0x00, 0xe5, 0x00, 0x00, 0x40, 0xb5, 0x93, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xb5, 0x83, 0x01, 0x00, 0xde, 0x00, 0xa2, 0x41,
-	0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x2d, 0x81, 0x01, 0x00,
-	0x26, 0x01, 0x00, 0x41, 0x2d, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0xb3, 0xc3, 0x01, 0x00, 0xda, 0x00, 0xa2, 0x41, 0x8d, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0xda, 0xb5, 0xbf, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xdb, 0x81, 0xd0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd9, 0xb9, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xb8, 0xe3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xdc, 0xb9, 0xeb, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0xb8, 0x97, 0x01, 0x00, 0x15, 0x00, 0x00, 0xdc,
-	0xb9, 0xe7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x2d, 0x81, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xdb, 0x81, 0xb0, 0x01, 0x00, 0x27, 0x01, 0x00, 0x42,
-	0x2d, 0x11, 0x01, 0x00, 0x25, 0x01, 0x00, 0x40, 0x2d, 0x11, 0x01, 0x00,
-	0x28, 0x01, 0x00, 0x40, 0x2d, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x2d, 0x91, 0x01, 0x00, 0x26, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x25, 0x01, 0x00, 0x40, 0x2d, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x2d, 0x81, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x41, 0x81, 0xd0, 0x00, 0x00,
-	0x00, 0x00, 0x84, 0x96, 0x80, 0x32, 0x01, 0x00, 0xff, 0x00, 0xa0, 0xdc,
-	0xb9, 0x6b, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x41, 0x2d, 0x91, 0x00, 0x00,
-	0xf8, 0x00, 0x00, 0x41, 0x2d, 0x81, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x40,
-	0xb3, 0x33, 0x01, 0x00, 0x00, 0x00, 0x90, 0xda, 0x8b, 0xb0, 0x00, 0x00,
-	0x11, 0x00, 0x00, 0x45, 0x88, 0xf4, 0x01, 0x00, 0x40, 0x00, 0x00, 0x44,
-	0x80, 0xce, 0x01, 0x00, 0x00, 0x00, 0xa4, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0xa3, 0x44, 0x89, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x89, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x87, 0xb0, 0x01, 0x00,
-	0xd9, 0x00, 0x00, 0x43, 0xb2, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0xb5, 0xf3, 0x01, 0x00, 0x0c, 0x01, 0xa0, 0xda, 0x8b, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x8b, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x87, 0xc0, 0x01, 0x00, 0x08, 0x01, 0xa2, 0x41, 0x89, 0x50, 0x00, 0x00,
-	0xff, 0xff, 0x00, 0x45, 0x88, 0x88, 0x01, 0x00, 0x10, 0x00, 0x00, 0x45,
-	0x8a, 0xf4, 0x01, 0x00, 0x12, 0x01, 0x90, 0x44, 0x8a, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x8b, 0xc0, 0x01, 0x00, 0xff, 0xff, 0x00, 0x45,
-	0x8a, 0xa8, 0x01, 0x00, 0x00, 0x00, 0x80, 0x50, 0x8b, 0xe0, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x40, 0xf9, 0x9b, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x40,
-	0xb3, 0xcf, 0x01, 0x00, 0x1c, 0x01, 0x00, 0xfc, 0x19, 0x31, 0x01, 0x00,
-	0x1c, 0x01, 0x40, 0xda, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x41, 0xda,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xf9, 0xc3, 0x01, 0x00,
-	0x16, 0x01, 0x9f, 0xda, 0x81, 0x32, 0x00, 0x00, 0x02, 0x80, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x91, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd9, 0x2b, 0xb1, 0x01, 0x00, 0x1e, 0x01, 0x9f, 0x94,
-	0x80, 0x32, 0x00, 0x00, 0x18, 0x00, 0x00, 0x94, 0x92, 0xe4, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0xb5, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
-	0xb4, 0x97, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xb3, 0xc3, 0x01, 0x00,
-	0x1d, 0x01, 0xa2, 0x41, 0x91, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x2b, 0xb1, 0x01, 0x00, 0x29, 0x01, 0x00, 0x51, 0x93, 0xb0, 0x00, 0x00,
-	0x29, 0x01, 0x00, 0x4d, 0x93, 0xb0, 0x00, 0x00, 0x29, 0x01, 0x00, 0x49,
-	0x93, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x93, 0xb0, 0x01, 0x00,
-	0x29, 0x01, 0xa2, 0x41, 0x93, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x11, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x12, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x13, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x14, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x15, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x16, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x17, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x18, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x19, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x1a, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1b, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x1d, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1e, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x04, 0x00, 0x40,
-	0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xa1, 0xd1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x1b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x19, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x15, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x0d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0b, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x09, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x07, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x01, 0xb0, 0x01, 0x00, 0x44, 0x01, 0x20, 0x48, 0xa1, 0x51, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x50, 0x01, 0x22, 0x4b,
-	0x74, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x60, 0x00, 0x00, 0x4b, 0x60, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb1,
-	0x7e, 0xb1, 0x01, 0x00, 0x51, 0x01, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x4e, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x80, 0x40,
-	0x97, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x58, 0x07, 0x90, 0x01, 0x00,
-	0xf3, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0xa5, 0xb3, 0x01, 0x00, 0xaf, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xc5, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
-	0x07, 0x90, 0x01, 0x00, 0xf3, 0x9f, 0x00, 0x40, 0xbf, 0xb3, 0x00, 0x00,
-	0x5f, 0x01, 0x22, 0xcc, 0x85, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51,
-	0x07, 0x90, 0x01, 0x00, 0xf3, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb,
-	0xa3, 0xc9, 0x01, 0x00, 0xd0, 0x14, 0x00, 0x40, 0xa1, 0x9b, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x20, 0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xca, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5,
-	0xe1, 0xb1, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x20, 0x62, 0xdd, 0x01, 0x00, 0x68, 0x01, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x85, 0x93, 0x01, 0x00,
-	0xc5, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xd0, 0x14, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa, 0xba, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfa, 0xa4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0xbc, 0xb3, 0x01, 0x00, 0x00, 0x14, 0x2f, 0x40, 0x81, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xe7, 0xa7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd8,
-	0xa9, 0xb3, 0x01, 0x00, 0xff, 0x00, 0x00, 0xdd, 0x81, 0x88, 0x01, 0x00,
-	0x02, 0x00, 0x00, 0x40, 0x80, 0xf4, 0x01, 0x00, 0x78, 0x01, 0x00, 0x40,
-	0x80, 0xc8, 0x01, 0x00, 0x88, 0x01, 0x00, 0xdd, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x10, 0xb1, 0x00, 0x00, 0x89, 0x01, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x8a, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x8b, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x8c, 0x01, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x8d, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x8f, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x91, 0x01, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xd2, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x55, 0x01, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xe1, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x7f, 0x02, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x80, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xf1, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xf2, 0x9f, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x77, 0x01, 0x00, 0x41, 0x81, 0xc0, 0x1a, 0x00,
-	0x5a, 0x01, 0x51, 0x40, 0x81, 0xb2, 0x1a, 0x00, 0x5a, 0x01, 0x52, 0x40,
-	0x81, 0xb2, 0x1a, 0x00, 0x5a, 0x01, 0x55, 0x40, 0x81, 0xb2, 0x1a, 0x00,
-	0x5a, 0x01, 0x56, 0x40, 0x81, 0xb2, 0x1a, 0x00, 0x55, 0x01, 0x91, 0x81,
-	0x80, 0x30, 0x1a, 0x00, 0x5a, 0x01, 0x45, 0x40, 0x81, 0xb2, 0x1a, 0x00,
-	0x55, 0x01, 0x91, 0x82, 0x80, 0x30, 0x1a, 0x00, 0x5a, 0x01, 0x46, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x89, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x2f, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x00, 0x14, 0x00, 0x40,
-	0x49, 0x99, 0x01, 0x00, 0xb5, 0x01, 0x22, 0xde, 0xe1, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x81, 0xc0, 0x01, 0x00, 0x94, 0x01, 0xa2, 0x44, 0x81, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0x49, 0xd1, 0x01, 0x00, 0x9c, 0x01, 0x22, 0x40,
-	0xe1, 0x6d, 0x00, 0x00, 0x98, 0x01, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
-	0x55, 0x01, 0x00, 0x41, 0xbf, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0xbf, 0xb3, 0x01, 0x00, 0x55, 0x01, 0xa0, 0x0f, 0xbd, 0x6f, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xde, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x49, 0xc1, 0x01, 0x00, 0xb7, 0x01, 0x00, 0x40, 0x19, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x42, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff,
-	0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde, 0x19, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x42, 0xff, 0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff,
-	0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x49, 0xc1, 0x01, 0x00,
-	0x00, 0x00, 0x2f, 0xff, 0xe1, 0xb1, 0x01, 0x00, 0x08, 0x14, 0x00, 0xa4,
-	0x80, 0xcc, 0x01, 0x00, 0xac, 0x01, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x85, 0xc0, 0x01, 0x00, 0xaa, 0x01, 0xa2, 0x4c,
-	0x81, 0x50, 0x00, 0x00, 0xb6, 0x01, 0x22, 0xd2, 0x81, 0x32, 0x00, 0x00,
-	0xb1, 0x01, 0x22, 0x41, 0xa5, 0x6f, 0x00, 0x00, 0x55, 0x01, 0xa2, 0xe0,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd2, 0xc1, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5c, 0x89, 0x90, 0x01, 0x00, 0x00, 0x00, 0x40, 0x42,
-	0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0x43, 0x80, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x88, 0x94, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x44,
-	0xe0, 0xb1, 0x00, 0x00, 0xb3, 0x01, 0x00, 0x48, 0x49, 0xc1, 0x00, 0x00,
-	0xb1, 0x01, 0x00, 0x5b, 0x89, 0x90, 0x00, 0x00, 0xb0, 0x9f, 0x00, 0xa0,
-	0x9e, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x81, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0xcb, 0x83, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0xba, 0x01, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0xc4, 0x01, 0x91, 0x82, 0x82, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x8a, 0x80, 0xb0, 0x01, 0x00, 0xb6, 0x9f, 0x00, 0x40,
-	0x80, 0xce, 0x01, 0x00, 0xc3, 0x01, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xc4, 0x01, 0x56, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53,
-	0x6f, 0x93, 0x01, 0x00, 0xf3, 0x9f, 0x00, 0x52, 0x6f, 0x93, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4d, 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0xcd, 0x83, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0xc7, 0x01, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x00, 0x00, 0x46, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0xd1, 0x01, 0x91, 0x81, 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
-	0x80, 0xb0, 0x01, 0x00, 0xb6, 0x9f, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
-	0xd0, 0x01, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xd1, 0x01, 0x55, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x6f, 0x93, 0x01, 0x00,
-	0xf3, 0x9f, 0x00, 0x53, 0x6f, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x83, 0xb0, 0x01, 0x00, 0x00, 0x14, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x23, 0x40, 0x81, 0xb0, 0x01, 0x00, 0xda, 0x01, 0x22, 0xde,
-	0xe1, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x49, 0xc1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00, 0xd5, 0x01, 0xa2, 0x44,
-	0x81, 0x6c, 0x00, 0x00, 0x55, 0x01, 0x00, 0x43, 0xbf, 0xb3, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x18, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x40, 0xf8,
-	0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0xf0, 0x80, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x40, 0xe1, 0xb1, 0x00, 0x00,
-	0xe2, 0x01, 0x00, 0x40, 0x91, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x91, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x2e, 0x40, 0x49, 0xb1, 0x01, 0x00,
-	0x05, 0x00, 0x00, 0x40, 0xa3, 0x9b, 0x01, 0x00, 0x08, 0x00, 0x00, 0xdd,
-	0x81, 0xf4, 0x01, 0x00, 0xe7, 0x01, 0x00, 0x40, 0x80, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x10, 0xb1, 0x00, 0x00, 0xed, 0x01, 0x00, 0x40,
-	0x81, 0xb0, 0x00, 0x00, 0x58, 0x01, 0x00, 0xde, 0xa1, 0xb3, 0x00, 0x00,
-	0xff, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x01, 0x02, 0x00, 0x40,
-	0x81, 0xb0, 0x00, 0x00, 0x07, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x57, 0x01, 0x00, 0xdf, 0xe1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0,
-	0xba, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde, 0xa1, 0xb1, 0x01, 0x00,
-	0x02, 0x00, 0x00, 0xd2, 0xa5, 0xe7, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2,
-	0xc1, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00,
-	0xf7, 0x01, 0x22, 0x44, 0xc1, 0x53, 0x00, 0x00, 0xf6, 0x01, 0x84, 0x41,
-	0x81, 0x40, 0x00, 0x00, 0xfa, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd0, 0x45, 0xb1, 0x01, 0x00, 0xf1, 0x01, 0x00, 0x41,
-	0xa1, 0xc1, 0x00, 0x00, 0xb1, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xc5, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x5a, 0x01, 0x00, 0xdd,
-	0xa1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb0, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x40, 0xa5, 0x9b, 0x01, 0x00, 0xb1, 0x02, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x40, 0x00, 0x00, 0xd3, 0xa7, 0xcb, 0x01, 0x00,
-	0xc5, 0x02, 0x00, 0xe0, 0xa5, 0xb3, 0x00, 0x00, 0x03, 0x00, 0x00, 0x40,
-	0xa3, 0x9b, 0x01, 0x00, 0x58, 0x01, 0x00, 0xde, 0xa1, 0xb3, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0xbf, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde,
-	0x81, 0x90, 0x01, 0x00, 0x55, 0x01, 0xa2, 0xba, 0x80, 0x04, 0x00, 0x00,
-	0x60, 0x00, 0x00, 0xde, 0x61, 0x99, 0x01, 0x00, 0x04, 0x02, 0xa8, 0xb1,
-	0x80, 0x30, 0x00, 0x00, 0x57, 0x01, 0x00, 0x40, 0xe0, 0xb1, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xd0, 0xba, 0xb3, 0x01, 0x00, 0x68, 0x02, 0x00, 0x40,
-	0x81, 0x98, 0x01, 0x00, 0x5d, 0x02, 0x00, 0x4d, 0x83, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0xe1, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0xe3, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xe5, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0xe9, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0xeb, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf5, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0xf7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0xf9, 0xb3, 0x01, 0x00, 0x15, 0x02, 0x22, 0x40, 0x8f, 0x6f, 0x00, 0x00,
-	0x75, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x5d, 0x02, 0x00, 0xc7,
-	0x83, 0x30, 0x01, 0x00, 0x7d, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
-	0x5d, 0x02, 0x00, 0x42, 0x83, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe8,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe9, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xea, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xeb,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x85, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xec, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xed,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb2, 0xf0, 0xb1, 0x01, 0x00,
-	0xe0, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xab, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb8,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb9, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xba, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xbb,
-	0xf0, 0xb1, 0x01, 0x00, 0x29, 0x02, 0xb8, 0x40, 0x81, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0x90, 0x01, 0x00, 0x2b, 0x02, 0xb9, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0x90, 0x01, 0x00,
-	0x2d, 0x02, 0xba, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x81, 0x90, 0x01, 0x00, 0x2f, 0x02, 0xbb, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x81, 0x90, 0x01, 0x00, 0x31, 0x02, 0xbc, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x81, 0x90, 0x01, 0x00,
-	0x33, 0x02, 0xbd, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x81, 0x90, 0x01, 0x00, 0x35, 0x02, 0xbe, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x46, 0x81, 0x90, 0x01, 0x00, 0x37, 0x02, 0xbf, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x81, 0x90, 0x01, 0x00,
-	0x39, 0x02, 0xc8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
-	0x81, 0x90, 0x01, 0x00, 0x3b, 0x02, 0xc9, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x49, 0x81, 0x90, 0x01, 0x00, 0x3d, 0x02, 0xca, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x81, 0x90, 0x01, 0x00,
-	0x3f, 0x02, 0xcb, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x81, 0x90, 0x01, 0x00, 0x41, 0x02, 0xcc, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0x81, 0x90, 0x01, 0x00, 0x43, 0x02, 0xcd, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x81, 0x90, 0x01, 0x00,
-	0x45, 0x02, 0xce, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e,
-	0x81, 0x90, 0x01, 0x00, 0x47, 0x02, 0xcf, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4f, 0x81, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf0, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40, 0xa5, 0x9b, 0x01, 0x00,
-	0xaf, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc5, 0x02, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xd0, 0x14, 0x2e, 0x06, 0xa5, 0xb3, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0xd3, 0xa7, 0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf2, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf4,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf5, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfa, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xeb, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xee,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xef, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf3, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xf1, 0xb1, 0x01, 0x00,
-	0xf7, 0x01, 0x00, 0xc7, 0xe1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x63, 0x02, 0x00, 0x48, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x51, 0x40, 0x1a, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x4d, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x60, 0x02, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x5c, 0x02, 0x49, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x52, 0x40, 0x1c, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x4e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x65, 0x02, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
-	0x5c, 0x02, 0x4a, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
-	0x9e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0xd8, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xa1, 0xd0, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2,
-	0xd2, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xd4, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd0, 0xd6, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd1,
-	0xdc, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2, 0xde, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x88, 0xda, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd4,
-	0x8e, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xe6, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xac, 0xec, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x99,
-	0xfa, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xe0, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd5, 0xe2, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5,
-	0xe4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xe8, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd5, 0xea, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5,
-	0xf4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xf6, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd5, 0xf8, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc7,
-	0xa9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x40, 0xb1, 0x01, 0x00,
-	0x81, 0x02, 0x00, 0x40, 0x91, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x91, 0xb0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xa3, 0x9b, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0xdd, 0x81, 0xf4, 0x01, 0x00, 0x85, 0x02, 0x00, 0x40,
-	0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0xb1, 0x00, 0x00,
-	0x8a, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x95, 0x02, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x95, 0x02, 0x00, 0x46, 0xa3, 0xb3, 0x00, 0x00,
-	0x98, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x9e, 0x02, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x8c, 0x02, 0x23, 0x50, 0xa5, 0x6f, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0xa5, 0xb3, 0x01, 0x00, 0xbc, 0x02, 0x00, 0x42,
-	0xa5, 0x63, 0x01, 0x00, 0xc5, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xd0, 0x14, 0x2d, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
-	0xba, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde, 0xa1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x00, 0xb0, 0x01, 0x00, 0x94, 0x02, 0x22, 0x44,
-	0xa5, 0x53, 0x00, 0x00, 0x91, 0x02, 0x00, 0x41, 0xa1, 0xc1, 0x00, 0x00,
-	0x5a, 0x01, 0x00, 0xdd, 0xa1, 0xb1, 0x00, 0x00, 0xbc, 0x02, 0x00, 0xde,
-	0xa1, 0x33, 0x01, 0x00, 0xc5, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x5a, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0xbf, 0xb3, 0x01, 0x00, 0x55, 0x01, 0xa2, 0xd2, 0x77, 0x7d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xd2, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde,
-	0x63, 0xb1, 0x01, 0x00, 0x9b, 0x02, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x5a, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xbc, 0x02, 0x00, 0x54,
-	0xa5, 0x33, 0x01, 0x00, 0xc5, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xd0, 0x14, 0x2d, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0xd0, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xd2, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0xd4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0xd6, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x08, 0xb1, 0x01, 0x00,
-	0xa9, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x5d, 0x02, 0x00, 0x46,
-	0x83, 0x30, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xa0, 0x9e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe8,
-	0x43, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe9, 0x45, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xea, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xeb,
-	0xa1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x40, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xe7, 0xa7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd8,
-	0xa9, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00,
-	0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
-	0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd3, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd4,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xe1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd1, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x20,
-	0x62, 0xdd, 0x01, 0x00, 0xb9, 0x02, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0xcc, 0x85, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe7,
-	0xa7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xa9, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb,
-	0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x46, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd2, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xf1, 0xb1, 0x01, 0x00,
-	0xb8, 0x02, 0x00, 0xd4, 0xe1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xcc,
-	0x85, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x81, 0xb0, 0x01, 0x00,
-	0xc7, 0x02, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0xc6, 0x02, 0xa2, 0xf2,
-	0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0xcc, 0x85, 0x83, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb0, 0x01, 0x00, 0xcb, 0x02, 0x80, 0xa5,
-	0x80, 0x32, 0x00, 0x00, 0xcc, 0x02, 0x00, 0xa5, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00, 0xcd, 0x02, 0x80, 0xa5,
-	0x80, 0x32, 0x00, 0x00, 0x80, 0x01, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
-	0xd6, 0x02, 0x20, 0x4f, 0x81, 0x6c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40,
-	0x83, 0x98, 0x01, 0x00, 0xd6, 0x02, 0x20, 0x4b, 0x81, 0x6c, 0x00, 0x00,
-	0x80, 0x00, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00, 0xd6, 0x02, 0x20, 0x47,
-	0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0x03, 0x90, 0x00, 0x41,
-	0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00,
-	0x00, 0x14, 0x2f, 0x4c, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0xda, 0x02, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
-	0x02, 0x00, 0x00, 0xa5, 0x80, 0xc8, 0x01, 0x00, 0xdd, 0x02, 0xa2, 0xa5,
-	0x80, 0x6c, 0x00, 0x00, 0x20, 0x00, 0x00, 0x90, 0x20, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x23, 0x91, 0x01, 0x00, 0xe0, 0x02, 0x1f, 0x91,
-	0x80, 0x32, 0x00, 0x00, 0x30, 0x00, 0x00, 0x90, 0x20, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x23, 0x91, 0x01, 0x00, 0xe3, 0x02, 0x1f, 0x91,
-	0x80, 0x32, 0x00, 0x00, 0x70, 0x00, 0x00, 0x90, 0x20, 0xa9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x23, 0x91, 0x01, 0x00, 0xe6, 0x02, 0x1f, 0x91,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x23, 0x91, 0x01, 0x00,
-	0xe8, 0x02, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00, 0x40, 0x68, 0x00, 0x90,
-	0x20, 0xa9, 0x01, 0x00, 0xe0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x21, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x22, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0x23, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x24, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x25, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0x26, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x27, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0xd0, 0x14, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
-	0x02, 0x01, 0x00, 0xa6, 0x80, 0xb0, 0x01, 0x00, 0x04, 0x03, 0x00, 0x40,
-	0x80, 0x98, 0x01, 0x00, 0x06, 0x05, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
-	0x08, 0x07, 0x00, 0x41, 0x82, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xe0, 0xb1, 0x01, 0x00,
-	0x30, 0x03, 0x00, 0x40, 0x85, 0x30, 0x01, 0x00, 0x39, 0x03, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xd8, 0x14, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0xff, 0x02, 0xa2, 0xf8, 0x80, 0x6c, 0x00, 0x00, 0x00, 0x03, 0x22, 0xf0,
-	0x82, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x21, 0x91, 0x01, 0x00,
-	0xd0, 0x14, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x30, 0x03, 0x00, 0x0c,
-	0x85, 0x30, 0x01, 0x00, 0x30, 0x03, 0x00, 0x4d, 0x85, 0x10, 0x01, 0x00,
-	0x30, 0x03, 0x00, 0x4e, 0x85, 0x10, 0x01, 0x00, 0xd0, 0x14, 0x20, 0x4f,
-	0xe1, 0xb1, 0x01, 0x00, 0x30, 0x03, 0x00, 0x4f, 0x85, 0x10, 0x01, 0x00,
-	0x39, 0x03, 0x00, 0x0c, 0x85, 0x30, 0x01, 0x00, 0xd8, 0x14, 0x20, 0x43,
-	0x81, 0xb0, 0x01, 0x00, 0x0f, 0x03, 0x22, 0xf0, 0x9e, 0x6e, 0x00, 0x00,
-	0x39, 0x03, 0x00, 0x4d, 0x85, 0x10, 0x01, 0x00, 0xd8, 0x14, 0x20, 0x42,
-	0x81, 0xb0, 0x01, 0x00, 0x0f, 0x03, 0x22, 0xf0, 0x9e, 0x6e, 0x00, 0x00,
-	0x39, 0x03, 0x00, 0x4e, 0x85, 0x10, 0x01, 0x00, 0xd8, 0x14, 0x20, 0x41,
-	0x81, 0xb0, 0x01, 0x00, 0x11, 0x03, 0xa2, 0xf0, 0x9e, 0x6e, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x49, 0x81, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x20, 0x95, 0x01, 0x00, 0x03, 0x00, 0x00, 0x90, 0x20, 0x8d, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x21, 0x95, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1b,
-	0x89, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
-	0x30, 0x03, 0x00, 0x17, 0x85, 0x30, 0x01, 0x00, 0x30, 0x03, 0x00, 0x58,
-	0x85, 0x10, 0x01, 0x00, 0x30, 0x03, 0x00, 0x59, 0x85, 0x10, 0x01, 0x00,
-	0xd0, 0x14, 0x20, 0x4f, 0xe1, 0xb1, 0x01, 0x00, 0x30, 0x03, 0x00, 0x5a,
-	0x85, 0x10, 0x01, 0x00, 0x39, 0x03, 0x00, 0x17, 0x85, 0x30, 0x01, 0x00,
-	0xd8, 0x14, 0x20, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x23, 0x03, 0x22, 0xf0,
-	0x9e, 0x6e, 0x00, 0x00, 0x39, 0x03, 0x00, 0x58, 0x85, 0x10, 0x01, 0x00,
-	0xd8, 0x14, 0x20, 0x41, 0x81, 0xb0, 0x01, 0x00, 0x23, 0x03, 0x22, 0xf0,
-	0x9e, 0x6e, 0x00, 0x00, 0x39, 0x03, 0x00, 0x59, 0x85, 0x10, 0x01, 0x00,
-	0xd8, 0x14, 0x20, 0x42, 0x81, 0xb0, 0x01, 0x00, 0x27, 0x03, 0xa2, 0xf0,
-	0x9e, 0x6e, 0x00, 0x00, 0x03, 0x00, 0x00, 0x90, 0x20, 0x8d, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x20, 0x95, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
-	0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x88, 0xe0, 0x01, 0x00,
-	0x2f, 0x03, 0xa2, 0x42, 0x21, 0x7d, 0x00, 0x00, 0xa5, 0xa5, 0x00, 0x40,
-	0x81, 0x98, 0x01, 0x00, 0xd0, 0x14, 0x20, 0x40, 0xe0, 0xb1, 0x01, 0x00,
-	0x30, 0x03, 0x00, 0x44, 0x84, 0x30, 0x01, 0x00, 0x39, 0x03, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xd8, 0x14, 0x20, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x2f, 0x03, 0xa2, 0xf0, 0x80, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x89, 0xe0, 0x01, 0x00, 0xe0, 0x00, 0x80, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x70, 0x15, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00,
-	0xd0, 0x14, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55,
-	0x87, 0xb4, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x70, 0x15, 0x00, 0x43, 0x62, 0x99, 0x01, 0x00, 0x36, 0x03, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x41, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x70, 0x15, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
-	0xf1, 0xb1, 0x01, 0x00, 0xd8, 0x14, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55,
-	0x87, 0xb4, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x70, 0x15, 0x00, 0x43, 0x62, 0x99, 0x01, 0x00, 0x3f, 0x03, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x87, 0xb0, 0x01, 0x00,
-	0x42, 0x03, 0xa2, 0x41, 0x87, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xf2,
-	0x86, 0xb0, 0x00, 0x00, 0x10, 0x00, 0x00, 0xf1, 0x86, 0xf4, 0x01, 0x00,
-	0x41, 0x03, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x84, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0xa2, 0x48, 0x84, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x8f, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x62, 0xb1, 0x01, 0x00, 0x49, 0x03, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xf5, 0x9f, 0x00, 0x47, 0x98, 0x30, 0x01, 0x00,
-	0x00, 0x08, 0x00, 0x47, 0x8e, 0xc8, 0x01, 0x00, 0x47, 0x03, 0x00, 0x5c,
-	0x8f, 0x80, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x58, 0x15, 0x2d, 0x40, 0x8d, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x2d, 0xf0,
-	0x88, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x8a, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x81, 0xb0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x45,
-	0x82, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x8b, 0xf0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0x83, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0x82, 0x94, 0x01, 0x00, 0x20, 0x00, 0x00, 0x41, 0x60, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x8d, 0xc0, 0x01, 0x00, 0x64, 0x03, 0x22, 0x5f,
-	0x8d, 0x6c, 0x00, 0x00, 0x55, 0x03, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
-	0x53, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40,
-	0x85, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x82, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x43,
-	0x86, 0xd8, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x41, 0x85, 0x50, 0x01, 0x00,
-	0x60, 0x03, 0x00, 0x41, 0x83, 0xe0, 0x00, 0x00, 0x5e, 0x03, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0x85, 0xe0, 0x01, 0x00,
-	0xd0, 0x14, 0x2f, 0x46, 0x84, 0x94, 0x01, 0x00, 0x20, 0x00, 0x00, 0x42,
-	0x60, 0x99, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x07, 0x00, 0x00, 0x45,
-	0x80, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x8b, 0xf0, 0x01, 0x00,
-	0x00, 0x04, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00, 0x6f, 0x03, 0xa0, 0x41,
-	0x81, 0x50, 0x00, 0x00, 0x6d, 0x03, 0x00, 0x41, 0x82, 0xe8, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x41, 0x8e, 0xc0, 0x01, 0x00, 0xae, 0x03, 0x00, 0x40,
-	0xa3, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0x81, 0xb0, 0x01, 0x00,
-	0x60, 0x15, 0x00, 0x40, 0x85, 0x98, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40,
-	0x40, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x41, 0x94, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x41, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x40, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0xa3, 0x55, 0x81, 0x6c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0xa3, 0xc1, 0x01, 0x00, 0x73, 0x03, 0x00, 0x50, 0x85, 0xc0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40,
-	0x83, 0x98, 0x01, 0x00, 0x00, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x7e, 0x03, 0xa2, 0x41,
-	0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00,
-	0x0b, 0x00, 0x00, 0x44, 0x82, 0xf4, 0x01, 0x00, 0x1a, 0x15, 0x00, 0xa6,
-	0x86, 0xb0, 0x01, 0x00, 0x70, 0x15, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
-	0x00, 0x08, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x16, 0x00, 0x40, 0xe1, 0x99, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x70, 0x15, 0x00, 0x43,
-	0x62, 0x99, 0x01, 0x00, 0x88, 0x03, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x8a, 0x03, 0x22, 0x5a, 0x73, 0x7d, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0x8b, 0x03, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00,
-	0x00, 0x08, 0x00, 0x42, 0x84, 0xc8, 0x01, 0x00, 0x83, 0x03, 0xa2, 0x41,
-	0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xf7, 0x0f, 0x00, 0xbc,
-	0x80, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	},
-	{
-	0x31, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x34, 0x80, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x35, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1b, 0x80, 0x81, 0x80,
-	0x80, 0x32, 0x00, 0x00, 0xe6, 0x89, 0xa2, 0x40, 0x91, 0x6f, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0x90, 0xb3, 0x01, 0x00, 0x5c, 0x95, 0x2e, 0xa2,
-	0x80, 0xb0, 0x01, 0x00, 0xff, 0x00, 0x00, 0x80, 0xf4, 0x89, 0x01, 0x00,
-	0x90, 0x95, 0x2a, 0xc8, 0xe5, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa1,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xa4, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd2, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd4, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd3, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xee,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x44, 0xb1, 0x01, 0x00, 0x18, 0x80, 0x11, 0x81,
-	0x98, 0x30, 0x00, 0x00, 0x00, 0x00, 0x51, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x1a, 0x80, 0x11, 0x82, 0x98, 0x30, 0x00, 0x00, 0x00, 0x00, 0x52, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0xe6, 0x89, 0x00, 0x48, 0xfd, 0x93, 0x00, 0x00,
-	0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x23, 0x80, 0xa2, 0x42,
-	0xfd, 0x7f, 0x00, 0x00, 0x20, 0x80, 0x00, 0x80, 0x80, 0x32, 0x00, 0x00,
-	0x22, 0x80, 0x11, 0x81, 0x82, 0x30, 0x00, 0x00, 0x22, 0x80, 0x51, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x22, 0x80, 0x11, 0x82, 0x82, 0x30, 0x00, 0x00,
-	0x22, 0x80, 0x52, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2c, 0x80, 0x00, 0x48,
-	0xfd, 0x93, 0x00, 0x00, 0x27, 0x80, 0x00, 0x80, 0x80, 0x32, 0x00, 0x00,
-	0x26, 0x80, 0xa2, 0x53, 0x07, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x51, 0x53,
-	0x07, 0x90, 0x01, 0x00, 0x2a, 0x80, 0x00, 0x52, 0x07, 0x90, 0x00, 0x00,
-	0x29, 0x80, 0xa2, 0x52, 0x07, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x52, 0x52,
-	0x07, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0xf3, 0x93, 0x01, 0x00, 0x5c, 0x95, 0x2e, 0xa2, 0x52, 0xb3, 0x01, 0x00,
-	0xff, 0x00, 0x00, 0x80, 0xf4, 0x89, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa9, 0x45, 0xb1, 0x01, 0x00,
-	0x30, 0x80, 0x00, 0x4c, 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x45, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x55, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x1b, 0x84, 0x05, 0x40, 0x49, 0xb1, 0x00, 0x00, 0x1b, 0x84, 0x05, 0x40,
-	0x49, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x05, 0x40, 0x49, 0xb1, 0x01, 0x00,
-	0xe1, 0x80, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0xde, 0xb2, 0x01, 0x00, 0x77, 0x00, 0x00, 0x40, 0x4b, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
-	0xfd, 0x83, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40, 0x9b, 0x9b, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xa5, 0x9c, 0xb3, 0x01, 0x00, 0xde, 0x99, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x58, 0x95, 0x20, 0x44, 0xe0, 0xb1, 0x01, 0x00,
-	0x00, 0xc0, 0x00, 0xa6, 0x36, 0xb1, 0x01, 0x00, 0xd0, 0x14, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x00, 0x38, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x06, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x05, 0x18, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x02, 0x09, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x50, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x7b, 0x03, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xe0, 0x83, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x10, 0x84, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x08, 0x84, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x60, 0x95, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
-	0x70, 0x95, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
-	0xdd, 0x91, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x91, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x85, 0xb3, 0x01, 0x00, 0x5c, 0x95, 0x20, 0x40,
-	0xe1, 0xb1, 0x01, 0x00, 0x1a, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x71, 0x83, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x02, 0x00, 0x00, 0x97,
-	0x80, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2e, 0xb1, 0x01, 0x00,
-	0x02, 0x00, 0x00, 0x40, 0x2e, 0xdd, 0x01, 0x00, 0x90, 0x01, 0x00, 0x40,
-	0x93, 0x98, 0x01, 0x00, 0x29, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x5c, 0x81, 0x00, 0x40, 0xaf, 0x33, 0x01, 0x00, 0x61, 0x99, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x55, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x49, 0x84, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x77, 0x01, 0x00, 0x41, 0x81, 0xc0, 0x00, 0x00,
-	0x71, 0x80, 0x51, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x72, 0x80, 0x52, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x73, 0x80, 0x55, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x74, 0x80, 0x56, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x55, 0x01, 0x91, 0x81,
-	0x80, 0x30, 0x00, 0x00, 0x5a, 0x01, 0x45, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x55, 0x01, 0x91, 0x82, 0x80, 0x30, 0x00, 0x00, 0x5a, 0x01, 0x46, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x5a, 0x01, 0x00, 0x48, 0xfd, 0x93, 0x00, 0x00,
-	0x5a, 0x01, 0x00, 0x48, 0xfd, 0x93, 0x00, 0x00, 0x5a, 0x01, 0x00, 0x49,
-	0xfd, 0x83, 0x00, 0x00, 0x5a, 0x01, 0x00, 0x4a, 0xfd, 0x83, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb,
-	0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x46, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd2, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x20,
-	0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0xd0, 0xe1, 0xb1, 0x00, 0x00,
-	0x7c, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
-	0x98, 0xb0, 0x01, 0x00, 0x04, 0x80, 0x00, 0x40, 0x8b, 0xb3, 0x00, 0x00,
-	0xb1, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x84, 0x80, 0xa2, 0x41,
-	0x97, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xa1, 0xc1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x04,
-	0x80, 0x94, 0x00, 0x00, 0x80, 0x15, 0x3f, 0x42, 0x97, 0xe3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x03,
-	0x02, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x07, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0xcb, 0x99, 0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0xcc,
-	0xf3, 0x83, 0x01, 0x00, 0x8e, 0x80, 0xa2, 0x41, 0x97, 0x6f, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xcb, 0xf3, 0x93, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb,
-	0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x44, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xa1, 0xe0, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0x20, 0x62, 0xdd, 0x01, 0x00,
-	0x95, 0x80, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xc6, 0x02, 0x00, 0x20,
-	0x42, 0x31, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x41, 0x05, 0x6c, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0xcb, 0xdb, 0x91, 0x01, 0x00, 0x00, 0x00, 0x19, 0x41,
-	0x8b, 0xb3, 0x01, 0x00, 0x60, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x9b, 0x80, 0xa8, 0xb1, 0x8c, 0x33, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0x9d, 0x80, 0xa8, 0xb1, 0x94, 0x33, 0x00, 0x00,
-	0xa3, 0x80, 0x14, 0xc6, 0x81, 0x32, 0x00, 0x00, 0x18, 0x00, 0x00, 0xc6,
-	0x83, 0xf4, 0x01, 0x00, 0x6a, 0x84, 0x22, 0x4f, 0x83, 0x04, 0x00, 0x00,
-	0x7f, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xff, 0x01, 0x00, 0xc6,
-	0x81, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x97, 0xa3, 0x01, 0x00,
-	0x7f, 0x80, 0x1f, 0x5c, 0x97, 0x53, 0x00, 0x00, 0x9e, 0x83, 0x1d, 0xc6,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x43, 0x81, 0xf0, 0x01, 0x00,
-	0xa9, 0x80, 0x00, 0x40, 0x10, 0xc9, 0x00, 0x00, 0x05, 0x81, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x36, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xda, 0x81, 0x00, 0xca, 0x63, 0xb3, 0x00, 0x00, 0x2d, 0x81, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x14, 0x81, 0x00, 0x4d, 0x83, 0xb0, 0x00, 0x00,
-	0x1e, 0x81, 0x00, 0x4e, 0x61, 0xb1, 0x00, 0x00, 0x0d, 0x81, 0x00, 0x40,
-	0x85, 0xb0, 0x00, 0x00, 0x14, 0x81, 0x00, 0x4c, 0x83, 0xb0, 0x00, 0x00,
-	0xf0, 0x80, 0x00, 0x40, 0x85, 0xb0, 0x00, 0x00, 0x91, 0x81, 0x00, 0x40,
-	0x49, 0xb1, 0x00, 0x00, 0x3d, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00,
-	0x8d, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x0d, 0x81, 0x00, 0x40,
-	0x85, 0xb0, 0x00, 0x00, 0xdd, 0x81, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00,
-	0x6a, 0x84, 0x00, 0xca, 0x9b, 0xb3, 0x00, 0x00, 0x46, 0x81, 0x00, 0x40,
-	0xc1, 0xb1, 0x00, 0x00, 0x4e, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00,
-	0x55, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00, 0x56, 0x81, 0x00, 0x40,
-	0xc1, 0xb1, 0x00, 0x00, 0x57, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00,
-	0x58, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00, 0x59, 0x81, 0x00, 0x40,
-	0x81, 0xb0, 0x00, 0x00, 0x59, 0x81, 0x00, 0x41, 0x81, 0xb0, 0x00, 0x00,
-	0xce, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xdd, 0x83, 0x00, 0xbb,
-	0xab, 0xb3, 0x00, 0x00, 0xdb, 0x81, 0x00, 0xca, 0xcf, 0xb3, 0x00, 0x00,
-	0xd3, 0x80, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00, 0xdf, 0x80, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xdc, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x6a, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xda, 0x80, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x6a, 0x84, 0x00, 0xca, 0x77, 0xb3, 0x00, 0x00,
-	0x15, 0x81, 0x00, 0x4d, 0x83, 0xb0, 0x00, 0x00, 0x1c, 0x81, 0x00, 0x4e,
-	0x61, 0xb1, 0x00, 0x00, 0x0d, 0x81, 0x00, 0xbb, 0x85, 0xb0, 0x00, 0x00,
-	0x15, 0x81, 0x00, 0x4c, 0x83, 0xb0, 0x00, 0x00, 0x0d, 0x81, 0x00, 0xbb,
-	0x85, 0xb0, 0x00, 0x00, 0xf0, 0x80, 0x00, 0xbb, 0x85, 0xb0, 0x00, 0x00,
-	0xe2, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x6a, 0x84, 0x00, 0xca,
-	0x4d, 0xb3, 0x00, 0x00, 0x64, 0x82, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00,
-	0x8f, 0x82, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00, 0xc8, 0x14, 0x2e, 0xbb,
-	0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xee, 0x82, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0xe0, 0xb1, 0x01, 0x00, 0xff, 0x7f, 0x00, 0xa2,
-	0xa0, 0x8b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xa5, 0xb3, 0x01, 0x00,
-	0x75, 0x80, 0x00, 0xca, 0xa7, 0x33, 0x01, 0x00, 0x02, 0x81, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x4e, 0x01, 0x00, 0x4d, 0x93, 0x30, 0x01, 0x00,
-	0x4e, 0x01, 0x00, 0x4e, 0x93, 0x30, 0x01, 0x00, 0x4e, 0x01, 0x00, 0x4c,
-	0x93, 0x30, 0x01, 0x00, 0x08, 0x84, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x6a, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x54, 0x95, 0x00, 0x40,
-	0x45, 0x99, 0x01, 0x00, 0x6a, 0x84, 0x00, 0xca, 0xe5, 0xb1, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x97, 0xb0, 0x01, 0x00, 0xe8, 0x80, 0x22, 0x42,
-	0x8f, 0x6f, 0x00, 0x00, 0xea, 0x80, 0x22, 0x41, 0x8f, 0x6f, 0x00, 0x00,
-	0xec, 0x80, 0x1e, 0xca, 0x81, 0x32, 0x00, 0x00, 0xee, 0x80, 0x1f, 0xca,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xc9, 0xb1, 0x01, 0x00,
-	0x6a, 0x84, 0x00, 0x42, 0x8f, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca,
-	0xcd, 0xb1, 0x01, 0x00, 0x6a, 0x84, 0x00, 0x41, 0x8f, 0xb3, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xca, 0xcf, 0xb1, 0x01, 0x00, 0x6a, 0x84, 0x00, 0x40,
-	0x8f, 0xb3, 0x00, 0x00, 0x00, 0x81, 0x00, 0xa6, 0xc6, 0xb1, 0x01, 0x00,
-	0x6a, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0xa6,
-	0xc6, 0xb1, 0x01, 0x00, 0x6a, 0x84, 0x00, 0x40, 0x8f, 0xb3, 0x00, 0x00,
-	0x78, 0x18, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00, 0x10, 0x00, 0x2f, 0x9c,
-	0x89, 0xb0, 0x01, 0x00, 0x07, 0x81, 0x00, 0x40, 0x39, 0x33, 0x01, 0x00,
-	0x18, 0x00, 0x2f, 0x9b, 0x89, 0xb0, 0x01, 0x00, 0x07, 0x81, 0x00, 0x40,
-	0x37, 0x33, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x9a, 0x89, 0xb0, 0x01, 0x00,
-	0x07, 0x81, 0x00, 0x40, 0x35, 0x33, 0x01, 0x00, 0x08, 0x00, 0x2f, 0x99,
-	0x89, 0xb0, 0x01, 0x00, 0x07, 0x81, 0x00, 0x40, 0x33, 0x33, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0xae, 0x47, 0xc9, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40,
-	0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00, 0x40, 0x18, 0x00, 0x40,
-	0xe1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0xae, 0x63, 0xdd, 0x01, 0x00, 0x02, 0x81, 0x28, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xff, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x02, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
-	0x69, 0x93, 0x01, 0x00, 0x6a, 0x84, 0x1a, 0x44, 0x93, 0x93, 0x00, 0x00,
-	0x05, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x81, 0x00, 0x58,
-	0x69, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf0, 0xd1, 0x01, 0x00,
-	0x00, 0x00, 0xa4, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x0c, 0x81, 0xa2, 0x40,
-	0xe1, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x45, 0xd1, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x41,
-	0xe1, 0xd1, 0x01, 0x00, 0x0d, 0x81, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x62, 0xb1, 0x01, 0x00, 0x11, 0x81, 0x28, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x0e, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xca, 0x63, 0xb1, 0x01, 0x00, 0x11, 0x81, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x6a, 0x84, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x16, 0x81, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00, 0x16, 0x81, 0x00, 0xbb,
-	0x81, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x60, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x62, 0xb1, 0x01, 0x00, 0x17, 0x81, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0x63, 0xb1, 0x01, 0x00,
-	0x6a, 0x84, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x19, 0x81, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x50, 0x95, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x1f, 0x81, 0x00, 0xbb, 0x87, 0xb0, 0x00, 0x00, 0x50, 0x95, 0x2f, 0x40,
-	0x87, 0xb0, 0x01, 0x00, 0x21, 0x81, 0x22, 0x40, 0x95, 0x7f, 0x00, 0x00,
-	0x6a, 0x84, 0x60, 0x40, 0x95, 0x83, 0x00, 0x00, 0x02, 0x00, 0x2d, 0xf0,
-	0x84, 0xb0, 0x01, 0x00, 0x22, 0x81, 0x36, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x62, 0xb1, 0x01, 0x00, 0x23, 0x81, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x62, 0xb1, 0x01, 0x00,
-	0x25, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca,
-	0x63, 0xb1, 0x01, 0x00, 0x27, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x16, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x6a, 0x84, 0x22, 0x41,
-	0x43, 0x51, 0x00, 0x00, 0x00, 0x08, 0x00, 0xca, 0x95, 0xcb, 0x01, 0x00,
-	0x22, 0x81, 0x00, 0x41, 0x85, 0xc0, 0x00, 0x00, 0x2f, 0x81, 0xa2, 0x42,
-	0x67, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x67, 0xb3, 0x01, 0x00,
-	0x2f, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x65, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x93, 0x83, 0x01, 0x00,
-	0x00, 0x00, 0x1a, 0xca, 0x69, 0x97, 0x01, 0x00, 0x6a, 0x84, 0x26, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x34, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x6a, 0x84, 0x1a, 0x44, 0x93, 0x93, 0x00, 0x00, 0x6a, 0x84, 0x20, 0x43,
-	0x95, 0x6f, 0x00, 0x00, 0x6a, 0x84, 0x80, 0xca, 0x67, 0x33, 0x00, 0x00,
-	0x6a, 0x84, 0x22, 0x40, 0x65, 0x6f, 0x00, 0x00, 0x6a, 0x84, 0x00, 0x6f,
-	0xdb, 0x91, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x35, 0x80, 0x22, 0x40, 0x80, 0x32, 0x00, 0x00, 0x6a, 0x84, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x95, 0x93, 0x01, 0x00,
-	0x42, 0x81, 0xa2, 0x44, 0x21, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0x95, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x95, 0x93, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x57, 0x95, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
-	0xc3, 0xb1, 0x01, 0x00, 0x45, 0x81, 0x22, 0x5b, 0x95, 0x7f, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4b, 0xfd, 0x93, 0x01, 0x00, 0x6a, 0x84, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x49, 0x81, 0x22, 0x40, 0xaf, 0x6f, 0x00, 0x00,
-	0x1b, 0xf5, 0x00, 0xca, 0x95, 0x9b, 0x01, 0x00, 0x4a, 0x81, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x1b, 0xfd, 0x00, 0xca, 0x95, 0x9b, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xca, 0x7f, 0xb3, 0x01, 0x00, 0x26, 0x01, 0x00, 0xca,
-	0xc5, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x95, 0x83, 0x01, 0x00,
-	0x6a, 0x84, 0x00, 0xca, 0xc5, 0xb1, 0x00, 0x00, 0xdf, 0x6f, 0x00, 0xca,
-	0x95, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55, 0x95, 0x93, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xca, 0xc7, 0xb1, 0x01, 0x00, 0x6a, 0x84, 0x22, 0x5f,
-	0x95, 0x7f, 0x00, 0x00, 0x26, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x95, 0x83, 0x01, 0x00, 0x6a, 0x84, 0x00, 0xca,
-	0xc7, 0xb1, 0x00, 0x00, 0x6a, 0x84, 0x00, 0xca, 0xc9, 0xb1, 0x00, 0x00,
-	0x6a, 0x84, 0x00, 0xca, 0xcb, 0xb1, 0x00, 0x00, 0x6a, 0x84, 0x00, 0xca,
-	0xcd, 0xb1, 0x00, 0x00, 0x6a, 0x84, 0x00, 0xca, 0xcf, 0xb1, 0x00, 0x00,
-	0x00, 0x00, 0x2e, 0x42, 0x81, 0xe0, 0x01, 0x00, 0x98, 0x14, 0x00, 0x40,
-	0x48, 0xc9, 0x01, 0x00, 0x6a, 0x84, 0x00, 0xca, 0xe1, 0xb1, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x09, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
-	0x82, 0xb0, 0x01, 0x00, 0x5e, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00, 0x60, 0x81, 0xa2, 0x5e,
-	0x0b, 0x7d, 0x00, 0x00, 0x20, 0x80, 0x00, 0xa6, 0x08, 0xb1, 0x01, 0x00,
-	0x62, 0x81, 0x9f, 0x85, 0x82, 0x30, 0x00, 0x00, 0x61, 0x81, 0xa2, 0x4f,
-	0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x21, 0xb3, 0x01, 0x00,
-	0x02, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0xc9, 0x81, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x10, 0x00, 0x00, 0x41, 0x84, 0xe4, 0x01, 0x00,
-	0x03, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0xc9, 0x81, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xf0, 0xff, 0x00, 0x41, 0x86, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x84, 0x94, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xa6,
-	0x86, 0xb0, 0x01, 0x00, 0x10, 0xc4, 0x00, 0x43, 0x86, 0x98, 0x01, 0x00,
-	0x75, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x21, 0xb3, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
-	0x1c, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0x72, 0x81, 0xa2, 0x5e,
-	0x0b, 0x7d, 0x00, 0x00, 0x04, 0x00, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00,
-	0x7e, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x41, 0x01, 0x00, 0xa6,
-	0x86, 0xb0, 0x01, 0x00, 0x50, 0x0c, 0x00, 0x43, 0x86, 0x98, 0x01, 0x00,
-	0x7a, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x21, 0xb3, 0x01, 0x00, 0x7e, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x41, 0x01, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00, 0x60, 0x0c, 0x00, 0x43,
-	0x86, 0x98, 0x01, 0x00, 0x7e, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x21, 0xb3, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
-	0x82, 0xb0, 0x01, 0x00, 0x7f, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
-	0x40, 0x13, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00, 0x87, 0x81, 0x22, 0x43,
-	0x21, 0x6f, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
-	0x12, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0x84, 0x81, 0xa2, 0x5e,
-	0x0b, 0x7d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00,
-	0x8c, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6,
-	0x82, 0xb0, 0x01, 0x00, 0x19, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00,
-	0x89, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x41,
-	0x08, 0x99, 0x01, 0x00, 0x8c, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
-	0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca, 0x81, 0x94, 0x01, 0x00,
-	0x8f, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x6a, 0x84, 0x00, 0x40,
-	0x08, 0xb1, 0x00, 0x00, 0xc8, 0x14, 0x2e, 0xbb, 0x85, 0xb0, 0x01, 0x00,
-	0x92, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x87, 0xb0, 0x01, 0x00, 0xa1, 0x81, 0x22, 0x43, 0x21, 0x6f, 0x00, 0x00,
-	0xb0, 0x81, 0x22, 0x44, 0x21, 0x6f, 0x00, 0x00, 0x11, 0x80, 0x00, 0xa6,
-	0x82, 0xb0, 0x01, 0x00, 0xc9, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xb8, 0x81, 0x22, 0x4a, 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x87, 0x90, 0x01, 0x00, 0x9c, 0x81, 0x22, 0x4d, 0x83, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x87, 0x90, 0x01, 0x00, 0x9e, 0x81, 0x22, 0x4f,
-	0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x87, 0x90, 0x01, 0x00,
-	0xa0, 0x81, 0x22, 0x4e, 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x87, 0x90, 0x01, 0x00, 0xb8, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x01, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0xc9, 0x81, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x01, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
-	0xc9, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb8, 0x81, 0x22, 0x42,
-	0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x87, 0x90, 0x01, 0x00,
-	0x1c, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0xc9, 0x81, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xab, 0x81, 0x22, 0x45, 0x83, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x87, 0x90, 0x01, 0x00, 0xad, 0x81, 0x22, 0x44,
-	0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x87, 0x90, 0x01, 0x00,
-	0xaf, 0x81, 0x22, 0x43, 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x87, 0x90, 0x01, 0x00, 0xb8, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x01, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0xc9, 0x81, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x01, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
-	0xc9, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb8, 0x81, 0x22, 0x42,
-	0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x87, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x87, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x87, 0x90, 0x01, 0x00, 0x00, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
-	0xc9, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xbc, 0x81, 0x22, 0x4b,
-	0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x87, 0x80, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xaf, 0xb3, 0x01, 0x00, 0xc5, 0x81, 0x22, 0x40, 0x87, 0x7c, 0x00, 0x00,
-	0xc5, 0x81, 0xa2, 0x41, 0x87, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0xae, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb3, 0x01, 0x00,
-	0xc4, 0x81, 0x22, 0x42, 0x87, 0x7c, 0x00, 0x00, 0xc5, 0x81, 0x00, 0x0b,
-	0x7d, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x7d, 0xb3, 0x01, 0x00,
-	0xff, 0x7f, 0x00, 0xa2, 0xa0, 0x8b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0xa5, 0xb3, 0x01, 0x00, 0x75, 0x80, 0x00, 0xca, 0xa7, 0x33, 0x01, 0x00,
-	0x02, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x20, 0x00, 0x00, 0x41,
-	0x82, 0xdc, 0x01, 0x00, 0xca, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x08, 0xb1, 0x01, 0x00, 0xcc, 0x81, 0x9f, 0x85,
-	0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0xd1, 0x81, 0x14, 0xf7, 0x81, 0x30, 0x00, 0x00, 0xd1, 0x81, 0xa2, 0x49,
-	0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0xfd, 0x93, 0x01, 0x00,
-	0xd4, 0x81, 0x15, 0xf8, 0x81, 0x14, 0x00, 0x00, 0xd4, 0x81, 0xa2, 0x4a,
-	0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0xfd, 0x93, 0x01, 0x00,
-	0xd6, 0x81, 0xa2, 0xc8, 0x81, 0x32, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40,
-	0x80, 0xdc, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40, 0x80, 0xdc, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xef, 0xb3, 0x01, 0x00, 0xd8, 0x81, 0x42, 0x40,
-	0xf1, 0x33, 0x00, 0x00, 0x04, 0x81, 0x00, 0x40, 0x68, 0x97, 0x00, 0x00,
-	0x6a, 0x84, 0x00, 0xbb, 0x6b, 0xb3, 0x00, 0x00, 0x6a, 0x84, 0x00, 0xbb,
-	0xb1, 0xb3, 0x00, 0x00, 0x6a, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xcc, 0x14, 0x2e, 0x40, 0x87, 0xb0, 0x01, 0x00, 0xff, 0x7f, 0x00, 0xa2,
-	0xa0, 0x8b, 0x01, 0x00, 0xd8, 0x00, 0x00, 0x43, 0xb2, 0x33, 0x01, 0x00,
-	0x00, 0x00, 0x68, 0xda, 0x89, 0xb0, 0x01, 0x00, 0x7c, 0x00, 0x00, 0x40,
-	0x8b, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x89, 0xf0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x89, 0xd0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x44,
-	0x88, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x87, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0xa5, 0xb3, 0x01, 0x00, 0xd8, 0x00, 0x00, 0x43,
-	0xb2, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x87, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0xa5, 0xc3, 0x01, 0x00, 0xf8, 0x81, 0x22, 0x44, 0x89, 0x50, 0x00, 0x00,
-	0xf8, 0x81, 0x22, 0x44, 0x8b, 0x50, 0x00, 0x00, 0xe7, 0x81, 0xa2, 0x50,
-	0xa5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xa5, 0xe3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xca, 0xa7, 0xb3, 0x01, 0x00, 0x75, 0x80, 0x00, 0xbb,
-	0x85, 0x30, 0x01, 0x00, 0xcc, 0x14, 0x2e, 0xd2, 0x95, 0xc3, 0x01, 0x00,
-	0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
-	0x42, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x81, 0xb0, 0x01, 0x00,
-	0xf5, 0x81, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0xf4, 0x81, 0xa2, 0xf2,
-	0x80, 0x30, 0x00, 0x00, 0xe7, 0x81, 0x00, 0x40, 0xa5, 0xb3, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0xa5, 0xe3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
-	0xa7, 0xb3, 0x01, 0x00, 0x75, 0x80, 0x00, 0xbb, 0x85, 0x30, 0x01, 0x00,
-	0x02, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xd9, 0x00, 0x00, 0x41,
-	0xb3, 0x73, 0x01, 0x00, 0x00, 0x00, 0x80, 0x50, 0xb5, 0xf3, 0x01, 0x00,
-	0xd8, 0x00, 0x00, 0x41, 0xb3, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd9,
-	0xb3, 0xfb, 0x01, 0x00, 0x00, 0x30, 0x00, 0xa6, 0xb8, 0xb3, 0x01, 0x00,
-	0xf2, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x25, 0x01, 0x00, 0x42,
-	0x2d, 0x01, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
-	0xeb, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x81, 0xb0, 0x01, 0x00, 0x26, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x09, 0x82, 0x10, 0xda, 0xb5, 0x6b, 0x00, 0x00, 0x0a, 0x82, 0x00, 0x41,
-	0x2d, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x2d, 0x91, 0x01, 0x00,
-	0x28, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x25, 0x01, 0x00, 0x40,
-	0x2d, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2d, 0x81, 0x01, 0x00,
-	0x06, 0x82, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x26, 0x01, 0x00, 0x42,
-	0x2d, 0x01, 0x01, 0x00, 0x25, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x26, 0x01, 0x00, 0x42, 0x2d, 0x11, 0x01, 0x00, 0x25, 0x01, 0x00, 0x40,
-	0x2d, 0x11, 0x01, 0x00, 0x15, 0x82, 0x04, 0x40, 0x2d, 0x01, 0x00, 0x00,
-	0x25, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x11, 0x82, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x28, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x25, 0x01, 0x00, 0x42, 0x2d, 0x01, 0x01, 0x00, 0xf2, 0x00, 0x00, 0x40,
-	0xb9, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x2d, 0x81, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x41, 0x2d, 0x81, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x03, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x18, 0xb1, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40,
-	0x83, 0x98, 0x01, 0x00, 0x00, 0x19, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x42, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x18, 0xb1, 0x01, 0x00, 0x1f, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
-	0x00, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x19, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x43, 0xc1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
-	0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x81, 0xd0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf6, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x43, 0xc1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00, 0x29, 0x82, 0xa2, 0x54,
-	0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf7, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00, 0x30, 0x82, 0xa2, 0x06,
-	0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x07, 0x91, 0xb0, 0x01, 0x00, 0xe1, 0x80, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x39, 0x82, 0xa2, 0x40, 0x97, 0x6c, 0x00, 0x00,
-	0x28, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00, 0x3a, 0x82, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
-	0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
-	0xf5, 0xb1, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x42, 0xb3, 0x43, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xda, 0xf5, 0xb1, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x42,
-	0xb3, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xf5, 0xb1, 0x01, 0x00,
-	0x4e, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda, 0xf7, 0xf5, 0x01, 0x00,
-	0x50, 0x00, 0x00, 0x40, 0x91, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0x8f, 0xb0, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x48, 0xb2, 0x33, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xda, 0xf7, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda,
-	0xf7, 0xf5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x91, 0xc0, 0x01, 0x00,
-	0x45, 0x82, 0xa2, 0x41, 0x8f, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x45, 0xd1, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
-	0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
-	0xfd, 0xb1, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
-	0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
-	0xfd, 0xb1, 0x01, 0x00, 0x18, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
-	0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
-	0xfd, 0xb1, 0x01, 0x00, 0x16, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
-	0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
-	0xfd, 0xb1, 0x01, 0x00, 0x34, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0x91, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x6e, 0xda, 0x8f, 0xb0, 0x01, 0x00,
-	0x02, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0xda, 0xfd, 0xb1, 0x01, 0x00,
-	0x6f, 0x82, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00, 0x6f, 0x82, 0x22, 0x45,
-	0xfd, 0x7f, 0x00, 0x00, 0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
-	0x35, 0x82, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00, 0x08, 0x00, 0x00, 0x48,
-	0xb2, 0xcb, 0x01, 0x00, 0xfe, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x6d, 0x82, 0xa2, 0x40, 0x8f, 0x6c, 0x00, 0x00, 0x72, 0x82, 0x22, 0x20,
-	0xb5, 0x6f, 0x00, 0x00, 0x6f, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xdb, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x72, 0x82, 0x22, 0x40,
-	0x97, 0x6c, 0x00, 0x00, 0x6f, 0x82, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4f, 0x69, 0x93, 0x01, 0x00, 0x04, 0x81, 0x00, 0x58,
-	0x69, 0x93, 0x00, 0x00, 0x54, 0x16, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
-	0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
-	0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x46, 0x00, 0x00, 0x40,
-	0xb3, 0x9b, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0xda, 0xf7, 0xf5, 0x01, 0x00, 0x48, 0x00, 0x00, 0x40,
-	0x95, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x97, 0xb0, 0x01, 0x00,
-	0xfc, 0x81, 0x00, 0x4a, 0xb2, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
-	0xf7, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda, 0xf7, 0xf5, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x95, 0xc0, 0x01, 0x00, 0x85, 0x82, 0xa2, 0x41,
-	0x97, 0x50, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x40, 0xa5, 0x9b, 0x01, 0x00,
-	0x40, 0x16, 0x00, 0x40, 0xa1, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
-	0xa7, 0xb3, 0x01, 0x00, 0x75, 0x80, 0x00, 0xbb, 0x85, 0x30, 0x01, 0x00,
-	0x02, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xa7, 0x82, 0x22, 0x45,
-	0xfd, 0x7f, 0x00, 0x00, 0xe0, 0x15, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x1a, 0x00, 0x00, 0xa2, 0x80, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0xf1, 0xb1, 0x01, 0x00, 0xf0, 0x15, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xca, 0xf1, 0xb1, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0xa0, 0x00, 0x00, 0x40, 0x62, 0xdd, 0x01, 0x00,
-	0x96, 0x82, 0xa8, 0xbb, 0xe1, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x83, 0xb0, 0x01, 0x00, 0x99, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
-	0x98, 0x82, 0xa2, 0xf2, 0x82, 0x30, 0x00, 0x00, 0xe1, 0x80, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x9f, 0x82, 0xa2, 0x40, 0x97, 0x6c, 0x00, 0x00,
-	0x28, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00, 0xa0, 0x82, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
-	0xf0, 0x15, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xa7, 0x82, 0xa2, 0xfa, 0xb4, 0x6f, 0x00, 0x00,
-	0xfc, 0x81, 0x00, 0x42, 0xb3, 0x43, 0x01, 0x00, 0xa7, 0x82, 0xa2, 0xfa,
-	0xb4, 0x6f, 0x00, 0x00, 0xfc, 0x81, 0x00, 0x42, 0xb3, 0x43, 0x01, 0x00,
-	0xaa, 0x82, 0x22, 0xfa, 0xb4, 0x6f, 0x00, 0x00, 0xa7, 0x82, 0x42, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x69, 0x93, 0x01, 0x00,
-	0x04, 0x81, 0x00, 0x58, 0x69, 0x93, 0x00, 0x00, 0x40, 0x16, 0x00, 0x40,
-	0x45, 0x99, 0x01, 0x00, 0x35, 0x82, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00,
-	0xf6, 0x15, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x5c, 0x16, 0x00, 0x40,
-	0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x6e, 0xfa, 0x8e, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
-	0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb4, 0xb3, 0x01, 0x00,
-	0xb8, 0x82, 0xa2, 0x40, 0x8f, 0x6c, 0x00, 0x00, 0xfc, 0x15, 0x20, 0x20,
-	0xe1, 0xb1, 0x01, 0x00, 0xbd, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xdb, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xbd, 0x82, 0x22, 0x40,
-	0x97, 0x6c, 0x00, 0x00, 0xba, 0x82, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4f, 0x69, 0x93, 0x01, 0x00, 0x04, 0x81, 0x00, 0x58,
-	0x69, 0x93, 0x00, 0x00, 0x34, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xc2, 0x82, 0x22, 0x50, 0xb5, 0x6f, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x91, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
-	0xb2, 0xcb, 0x01, 0x00, 0xf6, 0x15, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0xff, 0x81, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00, 0x02, 0x00, 0x00, 0x48,
-	0xb2, 0xcb, 0x01, 0x00, 0xf8, 0x15, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0xff, 0x81, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00, 0x04, 0x00, 0x00, 0x48,
-	0xb2, 0xcb, 0x01, 0x00, 0xfa, 0x15, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0xff, 0x81, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00, 0x08, 0x00, 0x00, 0x48,
-	0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x15, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x94, 0xb0, 0x01, 0x00, 0xff, 0xff, 0x00, 0x4a,
-	0xb4, 0x8b, 0x01, 0x00, 0xff, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x0a, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x00, 0x00, 0x4a,
-	0xb4, 0xf7, 0x01, 0x00, 0xff, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x34, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x48,
-	0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xd8, 0x82, 0x22, 0x50, 0xb5, 0x6f, 0x00, 0x00, 0xd9, 0x82, 0x00, 0x50,
-	0xb5, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xb5, 0xb3, 0x01, 0x00,
-	0xff, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x02, 0x81, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x16, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x30, 0x31, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x32, 0x33, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x34, 0x35, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x36, 0x37, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x38, 0x39, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x41, 0x42, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x43, 0x44, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x45, 0x46, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x47, 0x48, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x49, 0x4a, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x40,
-	0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf7, 0xb1, 0x01, 0x00,
-	0xe7, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x80, 0x16, 0x2e, 0x06,
-	0x83, 0xb0, 0x01, 0x00, 0x36, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
-	0xea, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x22, 0x00, 0x00, 0x40,
-	0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb, 0xf6, 0xb1, 0x01, 0x00,
-	0xed, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x62, 0x00, 0x00, 0x40,
-	0x95, 0x98, 0x01, 0x00, 0x00, 0x83, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x16, 0x2d, 0x06, 0x83, 0xb0, 0x01, 0x00, 0x80, 0x16, 0x00, 0x40,
-	0x45, 0x99, 0x01, 0x00, 0x5c, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
-	0xf3, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
-	0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71, 0xf9, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x72, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x73,
-	0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x74, 0xf9, 0xb1, 0x01, 0x00,
-	0x54, 0x00, 0x00, 0x40, 0x95, 0x98, 0x01, 0x00, 0x00, 0x83, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x70, 0x95, 0xb0, 0x01, 0x00,
-	0xff, 0x82, 0x22, 0x70, 0xb5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41,
-	0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x97, 0xb0, 0x01, 0x00,
-	0x45, 0x67, 0x00, 0xa6, 0xe0, 0xb2, 0x01, 0x00, 0x01, 0x23, 0x00, 0x70,
-	0xe1, 0x9a, 0x01, 0x00, 0xcd, 0xef, 0x00, 0xa6, 0xe2, 0xb2, 0x01, 0x00,
-	0x89, 0xab, 0x00, 0x71, 0xe3, 0x9a, 0x01, 0x00, 0xba, 0x98, 0x00, 0xa6,
-	0xe4, 0xb2, 0x01, 0x00, 0xfe, 0xdc, 0x00, 0x72, 0xe5, 0x9a, 0x01, 0x00,
-	0x32, 0x10, 0x00, 0xa6, 0xe6, 0xb2, 0x01, 0x00, 0x76, 0x54, 0x00, 0x73,
-	0xe7, 0x9a, 0x01, 0x00, 0xd2, 0xc3, 0x00, 0xa6, 0xe8, 0xb2, 0x01, 0x00,
-	0xf0, 0xe1, 0x00, 0x74, 0xe9, 0x9a, 0x01, 0x00, 0x80, 0x16, 0x00, 0x4a,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x81, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4a, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf7, 0xb1, 0x01, 0x00, 0x0d, 0x83, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
-	0x80, 0x16, 0x00, 0x4a, 0x44, 0xc9, 0x01, 0x00, 0xfc, 0x16, 0x2a, 0x47,
-	0xe7, 0xb5, 0x01, 0x00, 0x03, 0x00, 0x00, 0x4a, 0xe8, 0xe5, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x8d, 0xb0, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40,
-	0xa3, 0x99, 0x01, 0x00, 0x80, 0x16, 0x3d, 0x46, 0x8d, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
-	0x40, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00,
-	0x16, 0x83, 0xa2, 0x41, 0x89, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
-	0xeb, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71, 0xed, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x72, 0xef, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x73,
-	0xf1, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x74, 0xf3, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0x41,
-	0x80, 0x88, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40, 0xa2, 0xc9, 0x01, 0x00,
-	0x33, 0x83, 0xa0, 0x50, 0x83, 0x6c, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x40,
-	0x98, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x99, 0x84, 0x01, 0x00,
-	0x50, 0x03, 0x00, 0x4c, 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
-	0x86, 0xb0, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40, 0x98, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4f, 0x99, 0x84, 0x01, 0x00, 0x50, 0x03, 0x00, 0x4c,
-	0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x86, 0xa4, 0x01, 0x00,
-	0x02, 0x00, 0x00, 0x40, 0x98, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f,
-	0x99, 0x84, 0x01, 0x00, 0x50, 0x03, 0x00, 0x4c, 0xa2, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x20, 0x86, 0xa4, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40,
-	0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x40, 0xa4, 0x01, 0x00,
-	0x01, 0x00, 0x00, 0x20, 0x88, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0x41, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x40, 0x94, 0x01, 0x00,
-	0x05, 0x00, 0x00, 0x75, 0x89, 0xe4, 0x01, 0x00, 0x1b, 0x00, 0x00, 0x75,
-	0x85, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x84, 0x94, 0x01, 0x00,
-	0x3d, 0x83, 0xa3, 0x53, 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76,
-	0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77, 0x89, 0x84, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x76, 0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
-	0x8b, 0xa4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
-	0x4c, 0x83, 0x00, 0x45, 0x88, 0x94, 0x00, 0x00, 0x27, 0x00, 0x00, 0x41,
-	0x80, 0xce, 0x01, 0x00, 0x42, 0x83, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x76, 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
-	0x89, 0xa4, 0x01, 0x00, 0x4c, 0x83, 0x00, 0x78, 0x89, 0xa4, 0x00, 0x00,
-	0x3b, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00, 0x3f, 0x83, 0xaa, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x89, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x77, 0x89, 0x84, 0x01, 0x00, 0x00, 0x00, 0x00, 0x76,
-	0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x88, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
-	0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
-	0x4c, 0x83, 0x00, 0x45, 0x88, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x84, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x79, 0x85, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x20, 0x84, 0xc0, 0x01, 0x00, 0x53, 0x83, 0xa3, 0x53,
-	0x83, 0x6c, 0x00, 0x00, 0x82, 0x5a, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00,
-	0x99, 0x79, 0x00, 0x42, 0x84, 0xc8, 0x01, 0x00, 0x60, 0x83, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x27, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00,
-	0x58, 0x83, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00, 0xd9, 0x6e, 0x00, 0xa6,
-	0x84, 0xc0, 0x01, 0x00, 0xa1, 0xeb, 0x00, 0x42, 0x84, 0xc8, 0x01, 0x00,
-	0x60, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x41,
-	0x80, 0xce, 0x01, 0x00, 0x5d, 0x83, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x1b, 0x8f, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00, 0xdc, 0xbc, 0x00, 0x42,
-	0x84, 0xc8, 0x01, 0x00, 0x60, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x62, 0xca, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00, 0xd6, 0xc1, 0x00, 0x42,
-	0x84, 0xc8, 0x01, 0x00, 0x60, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x78, 0xf3, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
-	0xf1, 0xb2, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x76, 0x89, 0xe4, 0x01, 0x00,
-	0x02, 0x00, 0x00, 0x76, 0xef, 0xf6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0xee, 0x96, 0x01, 0x00, 0x00, 0x00, 0x00, 0x75, 0xed, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0xea, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x83, 0xc0, 0x01, 0x00, 0x4f, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00,
-	0x1f, 0x83, 0x2a, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75,
-	0xe1, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x76, 0xe3, 0xc2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x77, 0xe5, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78,
-	0xe7, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x79, 0xe9, 0xc2, 0x01, 0x00,
-	0x13, 0x83, 0x81, 0x41, 0x8d, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x9d, 0x83, 0xa2, 0x4b, 0xb7, 0x6f, 0x00, 0x00,
-	0x9d, 0x83, 0xa2, 0x41, 0x2f, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0xfd, 0x93, 0x01, 0x00, 0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
-	0x35, 0x82, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00, 0x9c, 0x83, 0x22, 0x40,
-	0x8f, 0x6c, 0x00, 0x00, 0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0xfe, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xdb, 0x82, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x9c, 0x83, 0xa2, 0x40, 0x97, 0x6c, 0x00, 0x00,
-	0x5e, 0x16, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x7c, 0x16, 0x20, 0xf6,
-	0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x31, 0xb3, 0x01, 0x00,
-	0x80, 0x83, 0x22, 0x4f, 0x8f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51,
-	0xfd, 0x93, 0x01, 0x00, 0x82, 0x83, 0x22, 0x40, 0x8f, 0x7c, 0x00, 0x00,
-	0x86, 0x83, 0x00, 0x54, 0xfd, 0x93, 0x00, 0x00, 0x84, 0x83, 0x22, 0x42,
-	0x8f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0xfd, 0x93, 0x01, 0x00,
-	0x86, 0x83, 0x22, 0x41, 0x8f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53,
-	0xfd, 0x93, 0x01, 0x00, 0x9a, 0x83, 0x22, 0x51, 0xfd, 0x7f, 0x00, 0x00,
-	0x34, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x48,
-	0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x95, 0x83, 0xa2, 0x40, 0xb5, 0x6f, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x48,
-	0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x48, 0x96, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xda, 0x97, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x4b,
-	0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xff, 0x81, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x30, 0xb5, 0xb3, 0x01, 0x00, 0xff, 0x81, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x99, 0x83, 0x22, 0x40,
-	0xb5, 0x6f, 0x00, 0x00, 0x9d, 0x83, 0x00, 0x54, 0xfd, 0x93, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x51, 0xfd, 0x83, 0x01, 0x00, 0x1c, 0x00, 0x00, 0xfe,
-	0x7f, 0xd9, 0x01, 0x00, 0x9d, 0x83, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x55, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x2f, 0x41, 0x99, 0xb3, 0x01, 0x00, 0xa8, 0x83, 0x22, 0x44,
-	0x81, 0x6c, 0x00, 0x00, 0xb0, 0x83, 0x22, 0x48, 0x81, 0x6c, 0x00, 0x00,
-	0xaa, 0x83, 0x22, 0x4c, 0x81, 0x6c, 0x00, 0x00, 0xb4, 0x83, 0x22, 0x50,
-	0x81, 0x6c, 0x00, 0x00, 0xb5, 0x83, 0x22, 0x54, 0x81, 0x6c, 0x00, 0x00,
-	0xb7, 0x83, 0x22, 0x58, 0x81, 0x6c, 0x00, 0x00, 0xbc, 0x83, 0x22, 0x5c,
-	0x81, 0x6c, 0x00, 0x00, 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xbc, 0x09, 0xb0, 0x01, 0x00, 0x6a, 0x84, 0x00, 0xca,
-	0x01, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x03, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0xf3, 0x83, 0x01, 0x00, 0xae, 0x83, 0xa2, 0x42,
-	0x05, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x05, 0xb0, 0x01, 0x00,
-	0x6a, 0x84, 0x22, 0xca, 0x07, 0x14, 0x00, 0x00, 0x6a, 0x84, 0x00, 0x45,
-	0xf3, 0x93, 0x00, 0x00, 0x6a, 0x84, 0x20, 0x43, 0x95, 0x6f, 0x00, 0x00,
-	0x6a, 0x84, 0x80, 0xca, 0x05, 0x30, 0x00, 0x00, 0x6a, 0x84, 0x22, 0x01,
-	0x80, 0x30, 0x00, 0x00, 0x6a, 0x84, 0x00, 0xcb, 0xdb, 0x91, 0x00, 0x00,
-	0x5c, 0x01, 0x00, 0xbc, 0xab, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc,
-	0xb1, 0xb3, 0x01, 0x00, 0x6a, 0x84, 0x00, 0xca, 0xcf, 0xb3, 0x00, 0x00,
-	0xff, 0x00, 0x00, 0xca, 0x81, 0x88, 0x01, 0x00, 0x6a, 0x84, 0xa2, 0x40,
-	0x74, 0x7d, 0x00, 0x00, 0x60, 0x00, 0x20, 0x40, 0x60, 0x99, 0x01, 0x00,
-	0xb9, 0x83, 0xa8, 0xb1, 0x82, 0x30, 0x00, 0x00, 0xb8, 0x83, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x6a, 0x84, 0x00, 0xca, 0x79, 0xb3, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4e, 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0xcb, 0x83, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0xbf, 0x83, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x00, 0x00, 0x45, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0xca, 0x83, 0x91, 0x82, 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a,
-	0x80, 0xb0, 0x01, 0x00, 0xb6, 0x9f, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
-	0xc8, 0x83, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xca, 0x83, 0x56, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00, 0xb6, 0x03, 0x00, 0x40,
-	0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x52, 0x07, 0x90, 0x01, 0x00,
-	0xf3, 0x9f, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e,
-	0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xcd, 0x83, 0x01, 0x00,
-	0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xcf, 0x83, 0xa2, 0x41,
-	0x81, 0x50, 0x00, 0x00, 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xda, 0x83, 0x91, 0x81,
-	0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x80, 0xb0, 0x01, 0x00,
-	0xb6, 0x9f, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00, 0xd8, 0x83, 0xa6, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xda, 0x83, 0x55, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x52,
-	0x07, 0x90, 0x01, 0x00, 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00, 0xf3, 0x9f, 0x00, 0x41,
-	0x8b, 0xb3, 0x00, 0x00, 0xb1, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
-	0xc4, 0x14, 0x2f, 0x40, 0x99, 0xb3, 0x01, 0x00, 0x5c, 0x01, 0x00, 0x40,
-	0x49, 0xb1, 0x00, 0x00, 0x58, 0x15, 0x2d, 0x40, 0x8d, 0xb0, 0x01, 0x00,
-	0xd0, 0x14, 0x2d, 0xf0, 0x88, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x8f, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6, 0x90, 0xb0, 0x01, 0x00,
-	0x00, 0xf8, 0x00, 0x48, 0x90, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x93, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x8a, 0xb0, 0x01, 0x00,
-	0x6a, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x02, 0x00, 0x00, 0xa6,
-	0x80, 0xb0, 0x01, 0x00, 0xec, 0x83, 0x22, 0x40, 0x82, 0x6c, 0x00, 0x00,
-	0xf0, 0x83, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x47, 0x03, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x8d, 0xc0, 0x01, 0x00,
-	0xf5, 0x83, 0x22, 0x5f, 0x8d, 0x6c, 0x00, 0x00, 0xe7, 0x83, 0xa2, 0x41,
-	0x93, 0x50, 0x00, 0x00, 0xe5, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xff, 0x07, 0x00, 0x47, 0x84, 0x88, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xf5, 0x9f, 0x00, 0x47, 0x80, 0x30, 0x01, 0x00,
-	0x00, 0x02, 0x00, 0x47, 0x8e, 0xc8, 0x01, 0x00, 0xf0, 0x83, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x50, 0xb3, 0x01, 0x00,
-	0xfb, 0x83, 0x20, 0x18, 0x89, 0x6c, 0x00, 0x00, 0x04, 0x00, 0x00, 0xa6,
-	0x84, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00,
-	0x00, 0x10, 0x00, 0x40, 0x55, 0x9b, 0x01, 0x00, 0xfe, 0x83, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0xa6, 0x84, 0xb0, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40,
-	0x55, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x50, 0xd3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xa8, 0x4f, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x4e, 0xd3, 0x01, 0x00, 0x5e, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x6c, 0x03, 0x00, 0x42, 0x80, 0x30, 0x01, 0x00, 0xf0, 0x83, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x07, 0x84, 0x22, 0xa7, 0x8f, 0x6c, 0x00, 0x00,
-	0x49, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x04, 0x84, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0xa0, 0x94, 0x2e, 0x43, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0x09, 0x84, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
-	0x50, 0x95, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0xac, 0x94, 0x2e, 0x43,
-	0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
-	0x0d, 0x84, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0xae, 0x03, 0x00, 0x40, 0xa3, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x60, 0x15, 0x00, 0x40,
-	0x85, 0x98, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40, 0x40, 0xe4, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x59, 0x41, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x41, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x40, 0x94, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xa3, 0x41,
-	0x81, 0x6c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00,
-	0x13, 0x84, 0x00, 0x50, 0x85, 0xc0, 0x00, 0x00, 0x49, 0x84, 0xa2, 0x41,
-	0x01, 0x7d, 0x00, 0x00, 0x21, 0x84, 0x22, 0x58, 0x73, 0x7d, 0x00, 0x00,
-	0x78, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x1c, 0x84, 0xa8, 0xb1,
-	0x9c, 0x30, 0x00, 0x00, 0x30, 0x00, 0x38, 0x45, 0x9d, 0xe0, 0x01, 0x00,
-	0x01, 0x00, 0x00, 0x0e, 0x10, 0xc9, 0x00, 0x00, 0x21, 0x84, 0x33, 0xc4,
-	0x81, 0x30, 0x00, 0x00, 0x24, 0x84, 0xa1, 0xad, 0x9d, 0x20, 0x00, 0x00,
-	0x1b, 0x84, 0x13, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x13, 0x4e,
-	0x5a, 0x83, 0x01, 0x00, 0x30, 0x00, 0x38, 0x45, 0x9d, 0xe0, 0x01, 0x00,
-	0x2c, 0x84, 0x22, 0xab, 0x80, 0x04, 0x00, 0x00, 0x2a, 0x84, 0xa2, 0x40,
-	0x01, 0x7d, 0x00, 0x00, 0x2c, 0x84, 0x22, 0x5f, 0x57, 0x7d, 0x00, 0x00,
-	0x21, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2c, 0x84, 0x22, 0x5e,
-	0x57, 0x7d, 0x00, 0x00, 0x84, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x31, 0x84, 0x22, 0x54, 0x73, 0x7d, 0x00, 0x00, 0x74, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0x2c, 0x84, 0xa8, 0xb1, 0x00, 0x30, 0x00, 0x00,
-	0xfa, 0x85, 0xa2, 0x5f, 0x01, 0x7c, 0x00, 0x00, 0x5c, 0x89, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x33, 0x84, 0xa2, 0x5f, 0x59, 0x27, 0x00, 0x00,
-	0x35, 0x84, 0xa2, 0x5c, 0x73, 0x7d, 0x00, 0x00, 0x3c, 0x84, 0xa2, 0x5e,
-	0x73, 0x7d, 0x00, 0x00, 0x46, 0x84, 0x22, 0x5c, 0x73, 0x7d, 0x00, 0x00,
-	0x47, 0x84, 0x37, 0x40, 0x81, 0x32, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0x36, 0x84, 0xa8, 0xb1, 0x36, 0x30, 0x00, 0x00,
-	0x7c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x38, 0x84, 0xa8, 0xb1,
-	0x00, 0x30, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x02, 0x88, 0x01, 0x00,
-	0x29, 0x86, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x47, 0x84, 0x34, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x3d, 0x84, 0xa8, 0xb1, 0x12, 0x30, 0x00, 0x00, 0x44, 0x84, 0x52, 0x21,
-	0x13, 0x04, 0x00, 0x00, 0x00, 0x00, 0x14, 0x41, 0x2f, 0xc3, 0x01, 0x00,
-	0xff, 0x3f, 0x00, 0x09, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x01, 0xf0, 0x01, 0x00, 0x87, 0x84, 0x00, 0x34, 0x13, 0x84, 0x00, 0x00,
-	0xff, 0x3f, 0x14, 0x09, 0x00, 0x8c, 0x01, 0x00, 0xe5, 0x84, 0x00, 0x43,
-	0x01, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x47, 0x84, 0x33, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x13, 0x4e,
-	0x5a, 0x93, 0x00, 0x00, 0xe6, 0x89, 0xa2, 0x48, 0xfd, 0x7f, 0x00, 0x00,
-	0x4e, 0x84, 0x22, 0x59, 0x73, 0x7d, 0x00, 0x00, 0x79, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0x4a, 0x84, 0x28, 0xb1, 0x7e, 0x31, 0x00, 0x00,
-	0x4b, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x52, 0x84, 0x21, 0xac,
-	0x9c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1f, 0xc3, 0x01, 0x00,
-	0x04, 0x00, 0xa0, 0x5f, 0x9d, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e,
-	0x58, 0x91, 0x01, 0x00, 0x56, 0x84, 0x22, 0x5a, 0x73, 0x7d, 0x00, 0x00,
-	0x7a, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x53, 0x84, 0xa8, 0xb1,
-	0x7e, 0x31, 0x00, 0x00, 0x01, 0x00, 0x00, 0xcf, 0x11, 0xc9, 0x00, 0x00,
-	0x5c, 0x84, 0xa2, 0x40, 0x93, 0x7f, 0x00, 0x00, 0x5c, 0x84, 0x22, 0x44,
-	0x93, 0x7f, 0x00, 0x00, 0x58, 0x84, 0x42, 0xa5, 0x80, 0x30, 0x00, 0x00,
-	0x5b, 0x84, 0xa2, 0x40, 0x93, 0x7f, 0x00, 0x00, 0x71, 0x84, 0x1a, 0x40,
-	0x93, 0x93, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x9a, 0x80, 0xa2, 0x40, 0x73, 0x7d, 0x00, 0x00, 0x9b, 0x89, 0x22, 0x44,
-	0x21, 0x6f, 0x00, 0x00, 0x92, 0x89, 0x22, 0x40, 0x65, 0x7d, 0x00, 0x00,
-	0xa0, 0x89, 0xa2, 0x5b, 0x73, 0x7d, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x49,
-	0x33, 0x7d, 0x00, 0x00, 0x66, 0x84, 0x22, 0x48, 0x33, 0x7d, 0x00, 0x00,
-	0xff, 0x01, 0x00, 0x99, 0x80, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x81, 0xe0, 0x01, 0x00, 0xa8, 0x98, 0x2f, 0x40, 0x33, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xe0, 0xc1, 0x01, 0x00, 0x69, 0x84, 0x22, 0x40,
-	0xaf, 0x6f, 0x00, 0x00, 0x69, 0x84, 0x22, 0x40, 0x81, 0x6f, 0x00, 0x00,
-	0xef, 0x89, 0x1f, 0xa5, 0x82, 0x6f, 0x00, 0x00, 0x49, 0x84, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x40, 0x8b, 0xb3, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x58, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e,
-	0x62, 0xb1, 0x01, 0x00, 0x1b, 0x84, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x6c, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x6f, 0x84, 0x33, 0x40,
-	0x1f, 0x30, 0x00, 0x00, 0x1b, 0x84, 0x13, 0x4e, 0x5a, 0x93, 0x00, 0x00,
-	0x73, 0x84, 0xa0, 0xce, 0x81, 0x50, 0x00, 0x00, 0x85, 0x84, 0xa0, 0xcd,
-	0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x9c, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xb1, 0x81, 0xb0, 0x01, 0x00, 0x85, 0x84, 0x22, 0xb5,
-	0x81, 0x14, 0x00, 0x00, 0x80, 0x15, 0x2f, 0x40, 0x49, 0xb1, 0x01, 0x00,
-	0x77, 0x84, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x60, 0xb4,
-	0x65, 0x97, 0x01, 0x00, 0xd0, 0x15, 0x2e, 0x40, 0x69, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x1a, 0x44, 0x93, 0x83, 0x01, 0x00, 0x1a, 0x00, 0x00, 0xa2,
-	0x80, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xb1, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb5,
-	0xf1, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x62, 0xb1, 0x01, 0x00, 0x80, 0x84, 0xa8, 0xa1,
-	0xe0, 0x31, 0x00, 0x00, 0x5c, 0x84, 0x00, 0x88, 0x9e, 0xb3, 0x00, 0x00,
-	0x5c, 0x84, 0xa2, 0x41, 0x67, 0x6f, 0x00, 0x00, 0x5c, 0x84, 0x00, 0x6f,
-	0xdb, 0x91, 0x00, 0x00, 0x85, 0x84, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x5c, 0x84, 0x1a, 0x40, 0x93, 0x83, 0x00, 0x00, 0x00, 0x99, 0x00, 0x09,
-	0x46, 0xc9, 0x01, 0x00, 0x3f, 0x00, 0x00, 0xf3, 0x0c, 0x88, 0x01, 0x00,
-	0x90, 0x84, 0xa6, 0x42, 0x13, 0x60, 0x00, 0x00, 0x3f, 0x97, 0x00, 0x95,
-	0x03, 0x30, 0x01, 0x00, 0x8b, 0x84, 0x45, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x75, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x8c, 0x84, 0xa8, 0xb1,
-	0x0c, 0x30, 0x00, 0x00, 0x46, 0x97, 0x1d, 0x10, 0x94, 0x30, 0x01, 0x00,
-	0x91, 0x84, 0x00, 0x58, 0x1f, 0x90, 0x00, 0x00, 0x38, 0x97, 0x00, 0x95,
-	0x03, 0x30, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x2d, 0xf0,
-	0x2e, 0xb0, 0x01, 0x00, 0xee, 0x07, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
-	0x98, 0x84, 0x23, 0x4b, 0xe4, 0x6d, 0x00, 0x00, 0x98, 0x84, 0x22, 0x4b,
-	0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1f, 0x90, 0x01, 0x00,
-	0x22, 0x00, 0x2f, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x9b, 0x84, 0x83, 0x17,
-	0x80, 0x32, 0x00, 0x00, 0x26, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x9d, 0x84, 0x85, 0x17, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
-	0x47, 0xc1, 0x01, 0x00, 0xa2, 0x84, 0x22, 0x55, 0x2f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x43, 0xd1, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xfa,
-	0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x97, 0xe0, 0x01, 0x00,
-	0xa3, 0x84, 0x00, 0x4b, 0x44, 0xc1, 0x00, 0x00, 0x12, 0x00, 0x00, 0xa2,
-	0x44, 0xc9, 0x01, 0x00, 0x28, 0x00, 0x00, 0xf6, 0x02, 0xcc, 0x01, 0x00,
-	0x0a, 0x00, 0x00, 0xa1, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x16, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x28, 0xf0, 0x10, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2,
-	0x2a, 0xb0, 0x01, 0x00, 0xc0, 0x28, 0x3c, 0x46, 0x0d, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x2d, 0x44, 0x95, 0xb0, 0x01, 0x00, 0xaf, 0x84, 0xa2, 0xf8,
-	0x0e, 0x30, 0x00, 0x00, 0xbf, 0x84, 0x22, 0x41, 0x95, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x2d, 0x50, 0x49, 0xc1, 0x01, 0x00, 0xab, 0x84, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xac, 0x84, 0xa2, 0xf8, 0x16, 0x6c, 0x00, 0x00,
-	0xac, 0x84, 0xa2, 0xf8, 0x10, 0x6c, 0x00, 0x00, 0xac, 0x84, 0xa2, 0xf0,
-	0x1a, 0x6c, 0x00, 0x00, 0xbd, 0x84, 0x22, 0x58, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00, 0xb4, 0x84, 0x47, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xb8, 0x84, 0xa2, 0xf3, 0x74, 0x06, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x06, 0xe6, 0x95, 0x01, 0x00, 0xbd, 0x84, 0x1f, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x96, 0xb0, 0x01, 0x00,
-	0x3f, 0x00, 0x1f, 0xf3, 0x0c, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00,
-	0xbb, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xbd, 0x84, 0x47, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xc5, 0x84, 0x1f, 0x41, 0x2d, 0xc3, 0x00, 0x00,
-	0xc3, 0x84, 0x22, 0x58, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x62, 0xb1, 0x01, 0x00,
-	0xc1, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xc3, 0x84, 0x47, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xec, 0x84, 0x1f, 0x41, 0x2d, 0xc3, 0x00, 0x00,
-	0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00, 0x0b, 0x96, 0x00, 0x07,
-	0x16, 0x30, 0x01, 0x00, 0xd3, 0x84, 0x22, 0x41, 0x81, 0x6c, 0x00, 0x00,
-	0xcb, 0x84, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0xd2, 0x84, 0x22, 0x5f, 0x0f, 0x7c, 0x00, 0x00,
-	0xff, 0x96, 0x00, 0x5f, 0x01, 0x10, 0x01, 0x00, 0xd1, 0x84, 0x22, 0x40,
-	0x95, 0x6c, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x74, 0x96, 0x00, 0x52,
-	0x95, 0x30, 0x01, 0x00, 0x7b, 0x96, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
-	0xff, 0x89, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00, 0xdb, 0x84, 0xa2, 0x5a,
-	0x1f, 0x7c, 0x00, 0x00, 0x86, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xdb, 0x84, 0x22, 0x20, 0x85, 0x6c, 0x00, 0x00, 0xd8, 0x84, 0x9c, 0x0f,
-	0x80, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x66, 0x96, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x85, 0x98, 0x00, 0x42,
-	0x61, 0x31, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0xce, 0x99, 0x00, 0x07, 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0xde, 0x84, 0x82, 0xf0, 0x18, 0x30, 0x00, 0x00,
-	0x66, 0x8b, 0x00, 0x45, 0x8f, 0xb0, 0x00, 0x00, 0x28, 0x20, 0x00, 0xa6,
-	0x96, 0xb0, 0x01, 0x00, 0xe2, 0x84, 0x22, 0x17, 0x96, 0x04, 0x00, 0x00,
-	0xf5, 0x97, 0x00, 0x4b, 0x95, 0x30, 0x01, 0x00, 0x66, 0x8b, 0x00, 0x4b,
-	0x8f, 0xb0, 0x00, 0x00, 0x0b, 0x97, 0x00, 0x03, 0x48, 0x31, 0x01, 0x00,
-	0xe7, 0x94, 0x00, 0x40, 0x81, 0x30, 0x01, 0x00, 0x66, 0x8b, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x68, 0x50, 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0xe9, 0x84, 0xa8, 0x00,
-	0xe0, 0x31, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x0f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x2e, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x17, 0xb0, 0x01, 0x00, 0x00, 0x41, 0x00, 0xa6, 0x96, 0xb0, 0x01, 0x00,
-	0xee, 0x07, 0x2e, 0x47, 0x97, 0x90, 0x01, 0x00, 0xff, 0x84, 0x22, 0x17,
-	0x96, 0x04, 0x00, 0x00, 0xfd, 0x84, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00,
-	0xfd, 0x84, 0x23, 0xa2, 0x02, 0x6c, 0x00, 0x00, 0x74, 0x96, 0x00, 0x52,
-	0x95, 0x30, 0x01, 0x00, 0x04, 0x00, 0x22, 0x41, 0x97, 0x50, 0x00, 0x00,
-	0x0c, 0x00, 0x2d, 0x00, 0x12, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x00, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x80, 0x01, 0x00,
-	0x7b, 0x96, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
-	0x00, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x03, 0xb0, 0x01, 0x00,
-	0x1c, 0x85, 0x00, 0x5c, 0x17, 0x90, 0x00, 0x00, 0x11, 0x85, 0x22, 0x43,
-	0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x1f, 0x90, 0x01, 0x00,
-	0x0a, 0x85, 0x22, 0x5f, 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x10,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x58, 0xf1, 0xb1, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00,
-	0xe0, 0xc9, 0x01, 0x00, 0x06, 0x85, 0x45, 0x42, 0x61, 0x31, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x07, 0x85, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x1d, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x20, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0xff, 0x0f, 0x00, 0xf6,
-	0x80, 0x88, 0x01, 0x00, 0x0e, 0x85, 0xa2, 0xa6, 0x81, 0x6c, 0x00, 0x00,
-	0x11, 0x85, 0x00, 0xf2, 0x3a, 0xb0, 0x00, 0x00, 0xf7, 0x85, 0xa2, 0x4b,
-	0xfd, 0x7f, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x15, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1c, 0x85, 0x22, 0x4a,
-	0x2f, 0x7c, 0x00, 0x00, 0x1c, 0x85, 0x22, 0x48, 0x2f, 0x7c, 0x00, 0x00,
-	0x0a, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x3f, 0x00, 0x00, 0xf2,
-	0x86, 0x88, 0x01, 0x00, 0x1f, 0x00, 0x00, 0x43, 0x84, 0x88, 0x01, 0x00,
-	0x05, 0x00, 0x00, 0x43, 0x80, 0xf4, 0x01, 0x00, 0x98, 0x94, 0x3d, 0x42,
-	0x81, 0xe0, 0x01, 0x00, 0x1c, 0x85, 0xa2, 0x42, 0xe0, 0x7d, 0x00, 0x00,
-	0xf7, 0x85, 0xa2, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x15, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x1c, 0x85, 0x47, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa3,
-	0x09, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x41, 0x47, 0xc3, 0x01, 0x00,
-	0x22, 0x85, 0x22, 0xa1, 0x09, 0x6c, 0x00, 0x00, 0x6b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x1f, 0x85, 0x00, 0x03, 0x48, 0xb1, 0x00, 0x00,
-	0x5b, 0x85, 0xa3, 0x92, 0x03, 0x6c, 0x00, 0x00, 0xf4, 0x98, 0x00, 0x40,
-	0x95, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x43, 0xc3, 0x01, 0x00,
-	0x15, 0x8a, 0x22, 0x08, 0x80, 0x32, 0x00, 0x00, 0x28, 0x85, 0x22, 0x5c,
-	0x17, 0x7c, 0x00, 0x00, 0x29, 0x85, 0x00, 0x00, 0x2a, 0xb0, 0x00, 0x00,
-	0x12, 0x00, 0x00, 0x00, 0x2a, 0xc8, 0x01, 0x00, 0x02, 0x00, 0x00, 0x08,
-	0x80, 0xc8, 0x01, 0x00, 0x2d, 0x85, 0xa2, 0x43, 0x2f, 0x7c, 0x00, 0x00,
-	0xf8, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x49, 0x85, 0x00, 0x5e,
-	0x17, 0x90, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x8c, 0xcc, 0x01, 0x00,
-	0xf8, 0x97, 0x00, 0x4c, 0x03, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x46,
-	0x02, 0xb0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00,
-	0x0c, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x40,
-	0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x15, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
-	0x36, 0x85, 0xa8, 0x54, 0x17, 0x10, 0x00, 0x00, 0x49, 0x85, 0x00, 0x5e,
-	0x17, 0x90, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x2a, 0xc8, 0x01, 0x00,
-	0x48, 0x85, 0x22, 0x43, 0x2f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01,
-	0x8c, 0xcc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x03, 0xb0, 0x01, 0x00,
-	0x19, 0x98, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x46,
-	0x02, 0xb0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00,
-	0x0c, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x09,
-	0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x15, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
-	0x49, 0x85, 0x28, 0x54, 0x17, 0x10, 0x00, 0x00, 0x45, 0x85, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x19, 0x98, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00,
-	0x4b, 0x85, 0x22, 0x50, 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56,
-	0x17, 0x90, 0x01, 0x00, 0x07, 0x00, 0x00, 0x17, 0x98, 0x88, 0x01, 0x00,
-	0x4e, 0x85, 0xa2, 0x41, 0x99, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
-	0x17, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x4f, 0x85, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x56, 0x85, 0x22, 0x43,
-	0x2f, 0x7c, 0x00, 0x00, 0x16, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x1d, 0xe4, 0xb1, 0x01, 0x00, 0xa1, 0x97, 0x00, 0x5e,
-	0x05, 0x10, 0x01, 0x00, 0x59, 0x85, 0xa2, 0x5f, 0x2f, 0x7c, 0x00, 0x00,
-	0xb9, 0x94, 0x00, 0x01, 0x38, 0x43, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x15, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x5d, 0x85, 0xa2, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0xf4, 0x85, 0x00, 0x41,
-	0x43, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x27, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x11, 0xb0, 0x01, 0x00, 0x5f, 0x85, 0x35, 0x01,
-	0x86, 0x30, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x66, 0x85, 0x28, 0xb1, 0x30, 0x30, 0x00, 0x00, 0x60, 0x85, 0x22, 0x4d,
-	0x75, 0x7d, 0x00, 0x00, 0xe4, 0x85, 0xa2, 0x40, 0x11, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x43, 0xc3, 0x01, 0x00, 0xf3, 0x85, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x66, 0x85, 0xa8, 0xb1, 0x12, 0x30, 0x00, 0x00, 0x6f, 0x85, 0xa2, 0x40,
-	0x11, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x43, 0xc3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x09, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
-	0x2c, 0xb0, 0x01, 0x00, 0xde, 0x07, 0x00, 0x43, 0x80, 0xce, 0x01, 0x00,
-	0x60, 0x85, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00, 0x74, 0x85, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x40, 0x00, 0x3e, 0x43, 0x27, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
-	0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x27, 0xc0, 0x01, 0x00,
-	0x60, 0x85, 0xa3, 0x0b, 0x87, 0x50, 0x00, 0x00, 0x00, 0x00, 0x15, 0x40,
-	0x1b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
-	0x12, 0x00, 0x00, 0x00, 0x2a, 0xc8, 0x01, 0x00, 0x40, 0x00, 0x2d, 0x40,
-	0x39, 0xb0, 0x01, 0x00, 0x7c, 0x85, 0xa2, 0x40, 0x27, 0x6c, 0x00, 0x00,
-	0x22, 0x00, 0x00, 0x08, 0x12, 0xc8, 0x01, 0x00, 0xde, 0x07, 0x00, 0x40,
-	0x25, 0x98, 0x01, 0x00, 0x7f, 0x85, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x12, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x30, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x25, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00, 0x14, 0x00, 0x20, 0x01,
-	0xe0, 0xb1, 0x01, 0x00, 0xee, 0x07, 0x00, 0x40, 0x37, 0x98, 0x01, 0x00,
-	0x84, 0x85, 0x23, 0x01, 0x36, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-	0x36, 0xb0, 0x01, 0x00, 0x8f, 0x85, 0x82, 0x41, 0x23, 0x40, 0x00, 0x00,
-	0x20, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x8b, 0x85, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x88, 0x85, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0xeb, 0x95, 0x00, 0x43, 0x23, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x32, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x23, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19,
-	0x44, 0xc9, 0x01, 0x00, 0x9e, 0x85, 0x22, 0x45, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19,
-	0x62, 0xdd, 0x01, 0x00, 0x95, 0x85, 0xa8, 0x15, 0xe0, 0x31, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x03, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x33, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x25, 0xd0, 0x01, 0x00,
-	0x0c, 0x00, 0x2d, 0x4c, 0x13, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x37, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x2b, 0xc0, 0x01, 0x00,
-	0x84, 0x85, 0x00, 0x45, 0x1f, 0x80, 0x00, 0x00, 0xa0, 0x85, 0xa3, 0x12,
-	0x36, 0x6c, 0x00, 0x00, 0xa1, 0x85, 0x68, 0x1b, 0x28, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x68, 0x12, 0x28, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19,
-	0x62, 0xdd, 0x01, 0x00, 0xa4, 0x85, 0xa8, 0x15, 0xe0, 0x31, 0x00, 0x00,
-	0xca, 0x85, 0x22, 0x14, 0x02, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x33, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0x24, 0xd0, 0x01, 0x00,
-	0x0c, 0x00, 0x2d, 0x14, 0x12, 0xc0, 0x01, 0x00, 0xc3, 0x85, 0xa2, 0x14,
-	0x36, 0x50, 0x00, 0x00, 0xb4, 0x85, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
-	0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0xb2, 0x85, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xaf, 0x85, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x5c,
-	0x1f, 0x80, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf0, 0x2a, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5c, 0x2b, 0x80, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
-	0x37, 0x98, 0x01, 0x00, 0xb9, 0x85, 0x23, 0x01, 0x36, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0x36, 0xb0, 0x01, 0x00, 0xc4, 0x85, 0x22, 0x1b,
-	0x02, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x2e, 0x5c, 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
-	0xff, 0x07, 0x00, 0x15, 0xe0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
-	0xc0, 0x85, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xc4, 0x85, 0x00, 0x03,
-	0x48, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x2a, 0xc0, 0x01, 0x00,
-	0x84, 0x85, 0xa2, 0x40, 0x25, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x39, 0xc0, 0x01, 0x00, 0x40, 0x00, 0x3d, 0x43, 0x39, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0b, 0x25, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x12, 0xb0, 0x01, 0x00, 0x84, 0x85, 0x00, 0xf0, 0x30, 0xb0, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00, 0xd0, 0x85, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00, 0xcd, 0x85, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0xeb, 0x95, 0x00, 0x40, 0x2b, 0x30, 0x01, 0x00, 0x18, 0x00, 0x2e, 0x03,
-	0x48, 0xb1, 0x01, 0x00, 0xd4, 0x85, 0x22, 0x50, 0x2f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x56, 0x17, 0x90, 0x01, 0x00, 0x07, 0x00, 0x00, 0x17,
-	0x98, 0x88, 0x01, 0x00, 0xd7, 0x85, 0xa2, 0x41, 0x99, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x55, 0x17, 0x90, 0x01, 0x00, 0xda, 0x85, 0x22, 0x43,
-	0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x17, 0x90, 0x01, 0x00,
-	0x16, 0x00, 0x20, 0x1d, 0xe4, 0xb1, 0x01, 0x00, 0xdc, 0x85, 0xa3, 0x40,
-	0x27, 0x6c, 0x00, 0x00, 0xde, 0x85, 0x60, 0x5f, 0x17, 0x90, 0x00, 0x00,
-	0x00, 0x84, 0x00, 0x0b, 0x16, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x60, 0x13,
-	0x16, 0x94, 0x01, 0x00, 0xa1, 0x97, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00,
-	0x15, 0x8a, 0xa2, 0x5f, 0x2f, 0x7c, 0x00, 0x00, 0x14, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00,
-	0xb9, 0x94, 0x00, 0x01, 0x38, 0x43, 0x01, 0x00, 0x15, 0x8a, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4d, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
-	0x62, 0xb1, 0x01, 0x00, 0xe6, 0x85, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x08, 0x62, 0xb1, 0x01, 0x00, 0xe8, 0x85, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xf3, 0x85, 0x22, 0x13, 0x82, 0x6c, 0x00, 0x00,
-	0x40, 0x00, 0x3d, 0x43, 0x83, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x2c, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x16, 0x62, 0xb1, 0x01, 0x00, 0xee, 0x85, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x62, 0xb1, 0x01, 0x00,
-	0xf0, 0x85, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xea, 0x85, 0x00, 0x41,
-	0x83, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x15, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x82, 0x00, 0xa6, 0x04, 0xb0, 0x01, 0x00, 0xa0, 0x98, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0xe3, 0x89, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00,
-	0x74, 0x96, 0x00, 0x52, 0x95, 0x30, 0x01, 0x00, 0x7b, 0x96, 0x00, 0x4b,
-	0x02, 0xb0, 0x00, 0x00, 0x15, 0x8a, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x01, 0x80, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00,
-	0x0e, 0xf4, 0x01, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x88, 0x01, 0x00,
-	0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00, 0x0b, 0x96, 0x00, 0x07,
-	0x16, 0x30, 0x01, 0x00, 0x05, 0x86, 0x22, 0x41, 0x81, 0x6c, 0x00, 0x00,
-	0x03, 0x86, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x04, 0x86, 0x22, 0x5f, 0x0f, 0x7c, 0x00, 0x00,
-	0xff, 0x89, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00, 0x0d, 0x86, 0xa2, 0x5a,
-	0x1f, 0x7c, 0x00, 0x00, 0x86, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x0d, 0x86, 0x22, 0x20, 0x85, 0x6c, 0x00, 0x00, 0x0a, 0x86, 0x9c, 0x0f,
-	0x80, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x66, 0x96, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x85, 0x98, 0x00, 0x42,
-	0x61, 0x31, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0xce, 0x99, 0x00, 0x07, 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x18, 0xb0, 0x01, 0x00,
-	0x13, 0x86, 0x22, 0x3a, 0x01, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x8e, 0xb0, 0x01, 0x00, 0x66, 0x8b, 0x00, 0x40, 0x01, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x2e, 0x00, 0x2d, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x17, 0x86, 0xa2, 0x40, 0xe7, 0x6d, 0x00, 0x00,
-	0x0a, 0x00, 0x00, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x66, 0x8b, 0x00, 0x40,
-	0x01, 0xb0, 0x00, 0x00, 0x51, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x38, 0x97, 0x00, 0x95, 0x03, 0x30, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00,
-	0x22, 0x00, 0x2d, 0xf0, 0x2e, 0xb0, 0x01, 0x00, 0x28, 0x20, 0x00, 0xa6,
-	0x96, 0xb0, 0x01, 0x00, 0x20, 0x86, 0x22, 0x17, 0x96, 0x04, 0x00, 0x00,
-	0xf5, 0x97, 0x00, 0x4b, 0x95, 0x30, 0x01, 0x00, 0x66, 0x8b, 0x00, 0x4c,
-	0x8f, 0xb0, 0x00, 0x00, 0x22, 0x86, 0x83, 0x17, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x43, 0xc1, 0x01, 0x00, 0x24, 0x86, 0x85, 0x17,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x43, 0xc1, 0x01, 0x00,
-	0x28, 0x00, 0x00, 0xf6, 0x02, 0xcc, 0x01, 0x00, 0x12, 0x00, 0x00, 0xa1,
-	0x2a, 0xc8, 0x01, 0x00, 0x0b, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xe7, 0x94, 0x00, 0x41, 0x81, 0x30, 0x01, 0x00, 0x66, 0x8b, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xd0, 0x01, 0x00,
-	0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x00, 0x40,
-	0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00, 0x2e, 0x86, 0x46, 0x47,
-	0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
-	0x2f, 0x86, 0xa8, 0x1b, 0xe0, 0x31, 0x00, 0x00, 0x1b, 0x84, 0x1e, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x03, 0xe0, 0x01, 0x00,
-	0x08, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x54, 0x86, 0x01, 0xfb,
-	0x08, 0x30, 0x00, 0x00, 0xa7, 0x86, 0x87, 0xfb, 0x22, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xfa, 0x0e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x14, 0xb0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00,
-	0x0b, 0x96, 0x00, 0x07, 0x16, 0x30, 0x01, 0x00, 0x4a, 0x86, 0x22, 0x41,
-	0x81, 0x6c, 0x00, 0x00, 0x3e, 0x86, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x49, 0x86, 0x22, 0x5f,
-	0x0f, 0x7c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x04, 0x7e, 0x89, 0x01, 0x00,
-	0x42, 0x86, 0xa6, 0x5f, 0x0f, 0x00, 0x00, 0x00, 0x5f, 0x95, 0x00, 0x40,
-	0x05, 0x30, 0x01, 0x00, 0x47, 0x86, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x13, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x03,
-	0x48, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x84, 0xb0, 0x01, 0x00, 0xea, 0x96, 0x00, 0x40,
-	0x05, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
-	0xff, 0x89, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00, 0x52, 0x86, 0xa2, 0x5a,
-	0x1f, 0x7c, 0x00, 0x00, 0x86, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x52, 0x86, 0x22, 0x20, 0x85, 0x6c, 0x00, 0x00, 0x4f, 0x86, 0x9c, 0x0f,
-	0x80, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x66, 0x96, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x85, 0x98, 0x00, 0x42,
-	0x61, 0x31, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0xce, 0x99, 0x00, 0x07, 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x18, 0xb0, 0x01, 0x00,
-	0x56, 0x86, 0x21, 0x04, 0x80, 0x20, 0x00, 0x00, 0x57, 0x86, 0x00, 0x40,
-	0x10, 0xc9, 0x00, 0x00, 0xa8, 0x8a, 0x00, 0x4b, 0x81, 0xb0, 0x00, 0x00,
-	0x76, 0x86, 0x00, 0x43, 0x81, 0xb0, 0x00, 0x00, 0x7a, 0x86, 0x00, 0xfb,
-	0x22, 0xb0, 0x00, 0x00, 0xa8, 0x8a, 0x00, 0x41, 0x81, 0xb0, 0x00, 0x00,
-	0x66, 0x8b, 0x00, 0x4e, 0x8f, 0xb0, 0x00, 0x00, 0x72, 0x86, 0x00, 0x5a,
-	0x8f, 0xb0, 0x00, 0x00, 0x5f, 0x86, 0x00, 0x47, 0x8f, 0xb0, 0x00, 0x00,
-	0xa8, 0x8a, 0x00, 0x53, 0x81, 0xb0, 0x00, 0x00, 0xa8, 0x8a, 0x00, 0x56,
-	0x81, 0xb0, 0x00, 0x00, 0x32, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x66, 0x8b, 0xa0, 0x0a, 0xe4, 0x6d, 0x00, 0x00, 0x65, 0x86, 0xa2, 0x41,
-	0x19, 0x7c, 0x00, 0x00, 0x64, 0x86, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00,
-	0x66, 0x8b, 0x00, 0x53, 0x8f, 0xb0, 0x00, 0x00, 0x66, 0x8b, 0x00, 0x54,
-	0x8f, 0xb0, 0x00, 0x00, 0x6e, 0x86, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00,
-	0x68, 0x86, 0xa2, 0x0a, 0xe4, 0x6d, 0x00, 0x00, 0x66, 0x8b, 0x00, 0x5d,
-	0x8f, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x80, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0a, 0x80, 0xd0, 0x01, 0x00, 0x6c, 0x86, 0xa0, 0x91,
-	0x81, 0x6c, 0x00, 0x00, 0x66, 0x8b, 0x00, 0x5e, 0x8f, 0xb0, 0x00, 0x00,
-	0x25, 0x00, 0x00, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x66, 0x8b, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x70, 0x86, 0x20, 0x91, 0xe5, 0x6d, 0x00, 0x00,
-	0x66, 0x8b, 0x00, 0x54, 0x8f, 0xb0, 0x00, 0x00, 0x21, 0x00, 0x00, 0x40,
-	0x8f, 0x98, 0x01, 0x00, 0x66, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x32, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x66, 0x8b, 0xa0, 0x0a,
-	0xe4, 0x6d, 0x00, 0x00, 0x24, 0x00, 0x00, 0x40, 0x8f, 0x98, 0x01, 0x00,
-	0x66, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x2d, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3, 0x82, 0xf4, 0x01, 0x00,
-	0xa8, 0x8a, 0xa0, 0x42, 0x83, 0x6c, 0x00, 0x00, 0xa8, 0x8a, 0x00, 0x54,
-	0x81, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x0e, 0xb0, 0x01, 0x00,
-	0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00, 0x00, 0xb5, 0x00, 0x0d,
-	0x42, 0xc9, 0x01, 0x00, 0x07, 0x00, 0x00, 0x07, 0x16, 0x88, 0x01, 0x00,
-	0x83, 0x86, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x40,
-	0x87, 0x98, 0x01, 0x00, 0x3d, 0x99, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0xff, 0x89, 0x00, 0x5c,
-	0x1f, 0x90, 0x00, 0x00, 0x95, 0x86, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00,
-	0x90, 0x86, 0xa2, 0x54, 0xfd, 0x7f, 0x00, 0x00, 0x88, 0x86, 0x22, 0x55,
-	0xfd, 0x7f, 0x00, 0x00, 0x82, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
-	0x80, 0x86, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x80, 0x86, 0x22, 0x53,
-	0xfd, 0x7f, 0x00, 0x00, 0x14, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x96, 0xb0, 0x01, 0x00, 0x10, 0x00, 0x00, 0x4b,
-	0x80, 0xf4, 0x01, 0x00, 0x0c, 0xbc, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
-	0x90, 0x86, 0x22, 0x43, 0x80, 0x6c, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4b,
-	0x80, 0x88, 0x01, 0x00, 0x80, 0x86, 0xa2, 0x43, 0x80, 0x6c, 0x00, 0x00,
-	0x7c, 0x96, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x91, 0x86, 0x43, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x94, 0x86, 0xa0, 0xf0, 0x30, 0x6f, 0x00, 0x00,
-	0x86, 0x86, 0x1b, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x41,
-	0x31, 0xc3, 0x01, 0x00, 0x90, 0x95, 0x00, 0x40, 0x25, 0x30, 0x01, 0x00,
-	0x99, 0x86, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x66, 0x96, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00,
-	0x14, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x07, 0x18, 0xe4, 0x01, 0x00, 0x00, 0x08, 0x00, 0x0c,
-	0xe0, 0x99, 0x01, 0x00, 0xce, 0x99, 0x00, 0x07, 0x96, 0x30, 0x01, 0x00,
-	0x00, 0xb5, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00, 0xa0, 0x86, 0x30, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x91, 0x01, 0x00,
-	0x00, 0x02, 0x00, 0xa1, 0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b,
-	0xe6, 0x91, 0x01, 0x00, 0x04, 0x00, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x10, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0xa8, 0x8a, 0x00, 0x40,
-	0x81, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x28, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfb, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x14, 0xb0, 0x01, 0x00, 0xb1, 0x86, 0x22, 0x46, 0x23, 0x7c, 0x00, 0x00,
-	0xad, 0x86, 0x22, 0x40, 0x87, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
-	0x1f, 0x90, 0x01, 0x00, 0xaf, 0x86, 0x22, 0x41, 0x87, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x1f, 0x90, 0x01, 0x00, 0xb1, 0x86, 0x22, 0x42,
-	0x87, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x1f, 0x90, 0x01, 0x00,
-	0xb1, 0x86, 0x47, 0x1b, 0x2c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
-	0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x41, 0x41, 0xc3, 0x01, 0x00,
-	0xe0, 0x86, 0x23, 0x92, 0x15, 0x6c, 0x00, 0x00, 0xe0, 0x86, 0xa2, 0x45,
-	0x1f, 0x7c, 0x00, 0x00, 0xe4, 0x86, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00,
-	0x17, 0x00, 0x00, 0xd0, 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x27, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x00, 0x0a, 0x24, 0xc8, 0x01, 0x00,
-	0xc7, 0x95, 0x00, 0x40, 0x0f, 0x30, 0x01, 0x00, 0xde, 0x86, 0x22, 0x08,
-	0x40, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00,
-	0xf0, 0x07, 0x00, 0x12, 0x24, 0xcc, 0x01, 0x00, 0xba, 0x86, 0xaa, 0x41,
-	0x27, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x13, 0x80, 0xcc, 0x01, 0x00,
-	0xda, 0x86, 0x26, 0x40, 0x23, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x83, 0xb0, 0x01, 0x00, 0x60, 0x00, 0x00, 0x03, 0x84, 0xc8, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x10, 0x48, 0xcd, 0x01, 0x00, 0x17, 0x00, 0x00, 0xd0,
-	0xa2, 0xc9, 0x01, 0x00, 0xc7, 0x86, 0xa2, 0x40, 0x83, 0x6c, 0x00, 0x00,
-	0xd3, 0x86, 0x00, 0x41, 0x83, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x42,
-	0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x68, 0x21, 0x38, 0x96, 0x01, 0x00,
-	0x00, 0x00, 0x2e, 0x50, 0x49, 0xc1, 0x01, 0x00, 0xcc, 0x86, 0xa2, 0x44,
-	0x23, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x20,
-	0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
-	0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0xcf, 0x86, 0xa8, 0x42,
-	0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x85, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0xa3, 0xc1, 0x01, 0x00, 0xc5, 0x86, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
-	0xda, 0x86, 0x22, 0x40, 0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0xd7, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x48, 0xb1, 0x01, 0x00,
-	0xee, 0x07, 0x00, 0x40, 0x25, 0x98, 0x01, 0x00, 0x17, 0x00, 0x00, 0xd0,
-	0x2a, 0xc8, 0x01, 0x00, 0xed, 0x86, 0x00, 0x17, 0x10, 0xb0, 0x00, 0x00,
-	0xaa, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xe4, 0x86, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xc7, 0x95, 0x00, 0x92, 0x25, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x31, 0xb0, 0x01, 0x00, 0xe4, 0x86, 0x22, 0x08,
-	0x2e, 0x30, 0x00, 0x00, 0xed, 0x86, 0x00, 0x41, 0x27, 0xb0, 0x00, 0x00,
-	0x80, 0x80, 0x00, 0xa6, 0x04, 0xb0, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40,
-	0x87, 0x98, 0x01, 0x00, 0x3d, 0x99, 0x00, 0x0a, 0x8c, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
-	0x1f, 0x90, 0x01, 0x00, 0xec, 0x86, 0x22, 0x9f, 0x13, 0x6c, 0x00, 0x00,
-	0x02, 0x00, 0x00, 0x88, 0x1c, 0xcc, 0x01, 0x00, 0x6b, 0x84, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xff, 0x89, 0x00, 0x41, 0x3f, 0xc3, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x00, 0x01,
-	0x80, 0xce, 0x01, 0x00, 0x01, 0x87, 0x2a, 0x40, 0x81, 0x30, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40,
-	0x81, 0x98, 0x01, 0x00, 0xf6, 0x86, 0xa2, 0x48, 0x1f, 0x7c, 0x00, 0x00,
-	0xf6, 0x86, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0xf6, 0x86, 0xa3, 0x07,
-	0x03, 0x6c, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
-	0xf9, 0x86, 0xa3, 0x40, 0x02, 0x6c, 0x00, 0x00, 0x28, 0x00, 0x00, 0x01,
-	0xf0, 0xcd, 0x01, 0x00, 0xfb, 0x86, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00,
-	0x28, 0x00, 0x00, 0x40, 0xf0, 0xcd, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x0e, 0xcc, 0x01, 0x00, 0x28, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00,
-	0x28, 0x00, 0x00, 0x00, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
-	0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xff, 0x86, 0xa8, 0x5c,
-	0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x08, 0xb0, 0x01, 0x00, 0xa0, 0x01, 0x2d, 0x40,
-	0x00, 0xc0, 0x01, 0x00, 0xe7, 0x88, 0x22, 0x0f, 0x42, 0x05, 0x00, 0x00,
-	0x12, 0x87, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
-	0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
-	0x0d, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x0a, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x12, 0x87, 0x22, 0x07, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0x42, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07,
-	0x42, 0xc1, 0x01, 0x00, 0x00, 0x80, 0x00, 0xa1, 0x46, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00, 0xd1, 0x87, 0xa2, 0x45,
-	0x1f, 0x7c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x2d, 0x54, 0x29, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x0e, 0xb0, 0x01, 0x00, 0x42, 0x00, 0x00, 0x03,
-	0x0a, 0xc8, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xa4, 0x0c, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14,
-	0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0x24, 0xd0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x14, 0x10, 0xc0, 0x01, 0x00, 0x12, 0x00, 0x00, 0x08,
-	0x10, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
-	0xfe, 0x7f, 0x00, 0x05, 0x44, 0xc9, 0x01, 0x00, 0x23, 0x87, 0x20, 0x94,
-	0x15, 0x6c, 0x00, 0x00, 0x24, 0x87, 0x00, 0x94, 0xe5, 0xb1, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x0a, 0xe4, 0xb1, 0x01, 0x00, 0x3d, 0x87, 0x22, 0x01,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x2e, 0xa4, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x48, 0xc1, 0x01, 0x00, 0x2a, 0x87, 0xa3, 0x07, 0x02, 0x6c, 0x00, 0x00,
-	0x2b, 0x87, 0x68, 0x01, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x07,
-	0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x02, 0xd0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0d, 0x0a, 0xc0, 0x01, 0x00, 0x37, 0x87, 0x22, 0x40,
-	0x03, 0x6c, 0x00, 0x00, 0x37, 0x87, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
-	0x5f, 0x87, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x34, 0x87, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x62, 0xb1, 0x01, 0x00, 0x39, 0x87, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x5f, 0x87, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xa4, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
-	0x48, 0xc1, 0x01, 0x00, 0x42, 0x87, 0xa3, 0x12, 0x0e, 0x6c, 0x00, 0x00,
-	0x43, 0x87, 0x68, 0x07, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x12,
-	0x1a, 0xb0, 0x01, 0x00, 0x46, 0x87, 0x80, 0x08, 0xf0, 0x31, 0x00, 0x00,
-	0x01, 0x00, 0x00, 0x11, 0x98, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0x1e, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
-	0x01, 0x1f, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00, 0x4a, 0x87, 0xa8, 0x5c,
-	0x1f, 0x10, 0x00, 0x00, 0x7d, 0x87, 0x22, 0x0d, 0x14, 0x6c, 0x00, 0x00,
-	0x50, 0x87, 0x22, 0x0d, 0x24, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
-	0x10, 0xc0, 0x01, 0x00, 0x54, 0x87, 0x00, 0x0d, 0x24, 0xd0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x2b, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15,
-	0xa2, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x20, 0x10, 0xc8, 0x01, 0x00,
-	0xf0, 0x07, 0x00, 0x40, 0x25, 0x98, 0x01, 0x00, 0x56, 0x87, 0x22, 0x42,
-	0x23, 0x6c, 0x00, 0x00, 0x5f, 0x87, 0x00, 0x41, 0x23, 0xc0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x57, 0x87, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x48, 0xb1, 0x01, 0x00, 0x5d, 0x87, 0x22, 0x47, 0x1f, 0x7c, 0x00, 0x00,
-	0xfb, 0x95, 0x00, 0x43, 0x23, 0x30, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x0f,
-	0x1e, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
-	0x7d, 0x87, 0x22, 0x0d, 0x14, 0x50, 0x00, 0x00, 0x7c, 0x87, 0xa2, 0x0d,
-	0x0e, 0x50, 0x00, 0x00, 0x6b, 0x87, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0x69, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x66, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03,
-	0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00,
-	0x00, 0x00, 0x2d, 0x06, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00,
-	0x70, 0x87, 0x1f, 0xf0, 0x0e, 0x30, 0x00, 0x00, 0x24, 0x87, 0x00, 0x4c,
-	0x0d, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x5f, 0x0f, 0x80, 0x01, 0x00,
-	0x24, 0x87, 0x23, 0x07, 0x14, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10,
-	0x48, 0xc9, 0x01, 0x00, 0x24, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00,
-	0x24, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
-	0x79, 0x87, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00, 0x24, 0x87, 0x00, 0x03,
-	0x0c, 0xb0, 0x00, 0x00, 0x24, 0x87, 0x00, 0x0d, 0x18, 0xc0, 0x00, 0x00,
-	0x04, 0x00, 0x2e, 0x14, 0x0a, 0xd0, 0x01, 0x00, 0x12, 0x00, 0x00, 0x05,
-	0x48, 0xcd, 0x01, 0x00, 0xfe, 0x7f, 0x00, 0x05, 0x42, 0xc9, 0x01, 0x00,
-	0x0c, 0x00, 0x2a, 0xf2, 0xe0, 0xb1, 0x01, 0x00, 0x83, 0x87, 0x22, 0x40,
-	0x31, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x60, 0x18, 0x38, 0x96, 0x01, 0x00,
-	0x1e, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x00, 0x81, 0x00, 0xf6,
-	0x80, 0xce, 0x01, 0x00, 0x87, 0x87, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x43, 0xc1, 0x01, 0x00, 0x89, 0x87, 0x22, 0x0b,
-	0xed, 0x6d, 0x00, 0x00, 0x08, 0x00, 0x00, 0xa1, 0x42, 0xc9, 0x01, 0x00,
-	0x02, 0x00, 0x00, 0xa1, 0x46, 0xc9, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xfa,
-	0x94, 0x88, 0x01, 0x00, 0x02, 0x00, 0x00, 0x4a, 0x86, 0xe4, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf6, 0x0e, 0xb0, 0x01, 0x00, 0x91, 0x87, 0x22, 0x47,
-	0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x1f, 0x43, 0x0e, 0x50, 0x00, 0x00,
-	0x91, 0x87, 0xa0, 0x46, 0x0f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x0f, 0xc0, 0x01, 0x00, 0x95, 0x87, 0x22, 0x48, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x91, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x0f, 0xa2,
-	0x42, 0x31, 0x00, 0x00, 0x98, 0x87, 0x00, 0x40, 0x89, 0xb0, 0x00, 0x00,
-	0x0c, 0x00, 0x00, 0xa2, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x95, 0xd0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfc, 0x82, 0xb0, 0x01, 0x00, 0x9b, 0x87, 0xa0, 0x41,
-	0x90, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x91, 0xc0, 0x01, 0x00,
-	0xa0, 0x87, 0x22, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0xa0, 0x87, 0xa0, 0x43,
-	0x89, 0x6c, 0x00, 0x00, 0xa0, 0x87, 0x20, 0x45, 0x89, 0x6c, 0x00, 0x00,
-	0xa0, 0x87, 0xa0, 0x41, 0x0e, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x0f, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x89, 0xc0, 0x01, 0x00,
-	0x98, 0x87, 0xa2, 0x41, 0x95, 0x50, 0x00, 0x00, 0xa9, 0x87, 0x22, 0x48,
-	0x1f, 0x7c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x48, 0x92, 0xf4, 0x01, 0x00,
-	0xff, 0xff, 0x00, 0x48, 0x90, 0x88, 0x01, 0x00, 0xa7, 0x87, 0x90, 0x48,
-	0x92, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00,
-	0x0a, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20,
-	0x93, 0xa4, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
-	0x12, 0x00, 0x00, 0x14, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x17,
-	0xf0, 0xb1, 0x01, 0x00, 0x12, 0x00, 0x00, 0x05, 0xe0, 0xcd, 0x01, 0x00,
-	0x30, 0x00, 0x00, 0x10, 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x40, 0x62, 0xdd, 0x01, 0x00,
-	0xaf, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xbc, 0x87, 0x22, 0x5c,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x2d, 0x10, 0x48, 0xc1, 0x01, 0x00, 0xb9, 0x87, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xb6, 0x87, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0xbc, 0x87, 0x87, 0x5c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x48, 0xb1, 0x01, 0x00, 0xfb, 0x95, 0x00, 0x41, 0x23, 0x40, 0x01, 0x00,
-	0xbe, 0x87, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0x52, 0x89, 0x00, 0x17,
-	0x10, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x03, 0x48, 0xb1, 0x01, 0x00,
-	0xc1, 0x87, 0xa0, 0x07, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe4, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x17, 0xf0, 0x01, 0x00, 0xc5, 0x87, 0x90, 0xf2,
-	0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00, 0x10, 0x00, 0x00, 0x14,
-	0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x2b, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf2, 0x2a, 0x94, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0xcf, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0xcc, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x17,
-	0x10, 0xdc, 0x01, 0x00, 0x52, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x90, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xd5, 0x87, 0x22, 0x5c,
-	0x1f, 0x7c, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x66, 0x96, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x05,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00,
-	0x04, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x3c, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x00, 0x14, 0x02, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0x34, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
-	0x32, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05, 0x0a, 0xc8, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x0e, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xa4,
-	0x0c, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00, 0x1b, 0x88, 0x22, 0x01,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x2e, 0xa4, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x48, 0xc1, 0x01, 0x00, 0xea, 0x87, 0xa3, 0x07, 0x02, 0x6c, 0x00, 0x00,
-	0xeb, 0x87, 0x68, 0x01, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x07,
-	0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x02, 0xd0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0d, 0x0a, 0xc0, 0x01, 0x00, 0xfd, 0x87, 0x22, 0x40,
-	0x03, 0x6c, 0x00, 0x00, 0xf7, 0x87, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
-	0x37, 0x88, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0xf4, 0x87, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x62, 0xb1, 0x01, 0x00, 0xf9, 0x87, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x37, 0x88, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x62, 0xb1, 0x01, 0x00, 0xff, 0x87, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x22, 0x00, 0x00, 0x19,
-	0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00,
-	0x0f, 0x00, 0x00, 0xf2, 0x3a, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x3b, 0xe0, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x14, 0x02, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x1d, 0x02, 0xc0, 0x01, 0x00, 0x0b, 0x88, 0x23, 0x1a,
-	0x02, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x03, 0xc0, 0x01, 0x00,
-	0x37, 0x88, 0x00, 0x01, 0x34, 0xc0, 0x00, 0x00, 0x0c, 0x00, 0x2d, 0x1d,
-	0x48, 0xc1, 0x01, 0x00, 0xf0, 0x00, 0x00, 0xf2, 0x30, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x31, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14,
-	0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x02, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x18, 0x02, 0xc0, 0x01, 0x00, 0x13, 0x88, 0x22, 0x1a,
-	0x02, 0x50, 0x00, 0x00, 0x37, 0x88, 0x00, 0x01, 0x34, 0xc0, 0x00, 0x00,
-	0x22, 0x00, 0x00, 0x19, 0x48, 0xc9, 0x01, 0x00, 0x02, 0x00, 0x2d, 0x14,
-	0x48, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x14, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x1d, 0x14, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
-	0x14, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x24, 0xb0, 0x01, 0x00,
-	0x12, 0x00, 0x00, 0x17, 0x10, 0xc8, 0x01, 0x00, 0x37, 0x88, 0x00, 0x1a,
-	0x10, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xa4, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
-	0x48, 0xc1, 0x01, 0x00, 0x20, 0x88, 0xa3, 0x12, 0x0e, 0x6c, 0x00, 0x00,
-	0x21, 0x88, 0x68, 0x07, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x12,
-	0x1a, 0xb0, 0x01, 0x00, 0x24, 0x88, 0x80, 0x08, 0xf0, 0x31, 0x00, 0x00,
-	0x01, 0x00, 0x00, 0x11, 0x98, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0x1e, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
-	0x01, 0x1f, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00, 0x28, 0x88, 0xa8, 0x5c,
-	0x1f, 0x10, 0x00, 0x00, 0x54, 0x88, 0x22, 0x0d, 0x14, 0x50, 0x00, 0x00,
-	0x54, 0x88, 0x22, 0x0d, 0x24, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
-	0x10, 0xc0, 0x01, 0x00, 0x2f, 0x88, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
-	0x37, 0x88, 0x00, 0x41, 0x23, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x30, 0x88, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x48, 0xb1, 0x01, 0x00,
-	0xfb, 0x95, 0x00, 0x43, 0x23, 0x30, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x0f,
-	0x1e, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
-	0x53, 0x88, 0xa2, 0x0d, 0x0e, 0x50, 0x00, 0x00, 0x42, 0x88, 0x22, 0x46,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00,
-	0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x40, 0x88, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x3d, 0x88, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x20, 0x80, 0x00, 0x03, 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0xe1, 0x91, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x06, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x04, 0xb0, 0x01, 0x00, 0x47, 0x88, 0x1f, 0xf0, 0x0e, 0x30, 0x00, 0x00,
-	0xe4, 0x87, 0x00, 0x4c, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x5f,
-	0x0f, 0x80, 0x01, 0x00, 0xe4, 0x87, 0x23, 0x07, 0x14, 0x6c, 0x00, 0x00,
-	0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x24, 0x00, 0x00, 0x40,
-	0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
-	0xf0, 0xb1, 0x01, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
-	0x62, 0xdd, 0x01, 0x00, 0x50, 0x88, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
-	0xe4, 0x87, 0x00, 0x03, 0x0c, 0xb0, 0x00, 0x00, 0xe4, 0x87, 0x00, 0x0d,
-	0x18, 0xc0, 0x00, 0x00, 0x71, 0x88, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x19, 0x0a, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05,
-	0x48, 0xc9, 0x01, 0x00, 0x0a, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00,
-	0x02, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x20, 0x40,
-	0xe5, 0xb1, 0x01, 0x00, 0x0d, 0x00, 0x2d, 0x1d, 0x48, 0xc1, 0x01, 0x00,
-	0x09, 0x00, 0x00, 0xf3, 0x38, 0x88, 0x01, 0x00, 0x0d, 0x00, 0x20, 0x50,
-	0xe7, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x2d, 0x40, 0x3f, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf4, 0x32, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x20, 0x40,
-	0xe1, 0xb1, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05, 0x48, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00, 0x02, 0x00, 0x00, 0x1d,
-	0x94, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x91, 0xb0, 0x01, 0x00,
-	0x66, 0x88, 0xa0, 0xfc, 0x90, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x91, 0xc0, 0x01, 0x00, 0x64, 0x88, 0xa2, 0x41, 0x95, 0x50, 0x00, 0x00,
-	0x04, 0x80, 0x00, 0x05, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0x48, 0xc1, 0x01, 0x00,
-	0x02, 0x00, 0x00, 0x18, 0x94, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x18,
-	0x90, 0xb0, 0x01, 0x00, 0x6e, 0x88, 0xa0, 0xfc, 0x90, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x91, 0xc0, 0x01, 0x00, 0x6c, 0x88, 0xa2, 0x41,
-	0x95, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0xe0, 0xb1, 0x01, 0x00,
-	0x10, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05,
-	0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0x48, 0xc1, 0x01, 0x00,
-	0x04, 0x80, 0x00, 0x05, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x16, 0xc0, 0x01, 0x00,
-	0x76, 0x88, 0x42, 0x30, 0x3d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e,
-	0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x41, 0x3d, 0xc3, 0x01, 0x00,
-	0x04, 0x00, 0x20, 0x42, 0xec, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1e,
-	0x82, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x2e, 0x1d, 0x82, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x66, 0x18, 0x82, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x80, 0xc0, 0x01, 0x00, 0x80, 0x88, 0xa0, 0x41, 0x80, 0x44, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00, 0x10, 0x00, 0x00, 0x40,
-	0x92, 0xf4, 0x01, 0x00, 0x0a, 0x00, 0x2e, 0x30, 0x81, 0x84, 0x01, 0x00,
-	0x84, 0x88, 0x90, 0x40, 0x92, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x93, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20, 0x93, 0xa4, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x1d, 0x48, 0xc1, 0x01, 0x00, 0x04, 0x00, 0x20, 0x19,
-	0xe8, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x16, 0xc0, 0x01, 0x00,
-	0x8a, 0x88, 0xa0, 0x19, 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x17, 0xc0, 0x01, 0x00, 0x0d, 0x00, 0x2f, 0x1e, 0x32, 0xc0, 0x01, 0x00,
-	0x8f, 0x88, 0xa2, 0x40, 0x15, 0x6c, 0x00, 0x00, 0x8e, 0x88, 0xa0, 0x1c,
-	0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x63, 0xf3, 0x38, 0x94, 0x01, 0x00, 0x10, 0x00, 0x00, 0x05,
-	0x48, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x2e, 0x1e, 0x98, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x60, 0x1a, 0x98, 0xc0, 0x01, 0x00, 0x0c, 0x00, 0x20, 0x40,
-	0xe1, 0xb1, 0x01, 0x00, 0x9d, 0x88, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0x9b, 0x88, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x98, 0x88, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03,
-	0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00,
-	0x30, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x12, 0x00, 0x00, 0x1a,
-	0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x17, 0xf0, 0xb1, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10,
-	0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x40, 0x62, 0xdd, 0x01, 0x00, 0xa3, 0x88, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xb1, 0x88, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x10,
-	0x48, 0xc1, 0x01, 0x00, 0xad, 0x88, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0xaa, 0x88, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
-	0x1f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x48, 0xb1, 0x01, 0x00,
-	0xfb, 0x95, 0x00, 0x41, 0x23, 0x40, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x0f,
-	0x1e, 0x8c, 0x01, 0x00, 0x20, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0b, 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x17, 0xf0, 0x01, 0x00, 0xb6, 0x88, 0x90, 0xf2, 0x16, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20,
-	0x17, 0xa4, 0x01, 0x00, 0x10, 0x00, 0x00, 0x14, 0x2a, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x1d, 0x2a, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x2b, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x2a, 0x94, 0x01, 0x00,
-	0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0xc1, 0x88, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xbe, 0x88, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x17, 0x10, 0xdc, 0x01, 0x00, 0xde, 0x88, 0x22, 0x40,
-	0x15, 0x6c, 0x00, 0x00, 0xc9, 0x88, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x1f, 0x90, 0x01, 0x00, 0xc8, 0x88, 0x22, 0x9f,
-	0x13, 0x6c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x88, 0x1c, 0xcc, 0x01, 0x00,
-	0x6b, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x3f, 0xc3, 0x01, 0x00, 0x4e, 0x99, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xcc, 0x88, 0xa2, 0x41, 0x87, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e,
-	0x3e, 0xc0, 0x01, 0x00, 0xde, 0x88, 0x22, 0x40, 0x15, 0x6c, 0x00, 0x00,
-	0xcf, 0x88, 0x20, 0x1e, 0x14, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
-	0x3c, 0xb0, 0x01, 0x00, 0xc7, 0x95, 0x00, 0x1e, 0x24, 0x30, 0x01, 0x00,
-	0xd4, 0x88, 0x22, 0x08, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52,
-	0x11, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x10, 0xc0, 0x01, 0x00,
-	0x37, 0x88, 0x00, 0x40, 0x17, 0xb0, 0x00, 0x00, 0x6b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0xc7, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xd1, 0x88, 0xa2, 0x08, 0x2e, 0x30, 0x00, 0x00, 0x80, 0x80, 0x00, 0xa6,
-	0x04, 0xb0, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x03, 0x44, 0x99, 0x01, 0x00, 0x04, 0x00, 0x22, 0x04,
-	0xe0, 0x31, 0x00, 0x00, 0x3d, 0x99, 0x00, 0x1f, 0x8c, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0xff, 0x89, 0x00, 0x5c,
-	0x1f, 0x90, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0x99, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0x04, 0xe0, 0x31, 0x00, 0x00, 0x4e, 0x99, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xe3, 0x88, 0xa2, 0x41, 0x87, 0x7c, 0x00, 0x00,
-	0xe4, 0x88, 0x00, 0x1e, 0x3e, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
-	0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
-	0x3d, 0x99, 0x00, 0x40, 0x0f, 0x30, 0x01, 0x00, 0xff, 0x89, 0x00, 0x5c,
-	0x1f, 0x90, 0x00, 0x00, 0xef, 0x88, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0xef, 0x88, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0xec, 0x88, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xf4, 0x88, 0x22, 0x07,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x42, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x07, 0x42, 0xc1, 0x01, 0x00, 0x00, 0x80, 0x00, 0xa1,
-	0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00,
-	0x04, 0x00, 0x2e, 0x03, 0x48, 0xb1, 0x01, 0x00, 0xf7, 0x88, 0x20, 0x94,
-	0x15, 0x6c, 0x00, 0x00, 0xf8, 0x88, 0x00, 0x94, 0xe1, 0xb1, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x0a, 0xe0, 0xb1, 0x01, 0x00, 0xfb, 0x88, 0x22, 0x40,
-	0x31, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x60, 0x18, 0x38, 0x96, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x00, 0x89, 0xa8, 0x40,
-	0x23, 0x30, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x2d, 0x52, 0x11, 0xc0, 0x01, 0x00, 0x10, 0x00, 0x00, 0x03,
-	0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x0e, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xa4, 0x0c, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4,
-	0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xc1, 0x01, 0x00,
-	0x0e, 0x89, 0xa3, 0x12, 0x0e, 0x6c, 0x00, 0x00, 0x0f, 0x89, 0x68, 0x07,
-	0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x12, 0x1a, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0x61, 0xb1, 0x01, 0x00, 0x01, 0x1f, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00,
-	0x14, 0x89, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00, 0x45, 0x89, 0x22, 0x0d,
-	0x14, 0x6c, 0x00, 0x00, 0x1a, 0x89, 0x22, 0x0d, 0x24, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x0d, 0x10, 0xc0, 0x01, 0x00, 0x1e, 0x89, 0x00, 0x0d,
-	0x24, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x2b, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x15, 0xa2, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x20,
-	0x10, 0xc8, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40, 0x25, 0x98, 0x01, 0x00,
-	0x20, 0x89, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00, 0x27, 0x89, 0x00, 0x41,
-	0x23, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x21, 0x89, 0xa8, 0x5c,
-	0x1f, 0x00, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x48, 0xb1, 0x01, 0x00, 0xc2, 0x94, 0x00, 0x43,
-	0x23, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0x0d, 0x14, 0x50, 0x00, 0x00, 0x44, 0x89, 0xa2, 0x0d,
-	0x0e, 0x50, 0x00, 0x00, 0x33, 0x89, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0x31, 0x89, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x2e, 0x89, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03,
-	0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00,
-	0x00, 0x00, 0x2d, 0x06, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00,
-	0x38, 0x89, 0x1f, 0xf0, 0x0e, 0x30, 0x00, 0x00, 0x09, 0x89, 0x00, 0x4c,
-	0x0d, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x5f, 0x0f, 0x80, 0x01, 0x00,
-	0x09, 0x89, 0x23, 0x07, 0x14, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10,
-	0x48, 0xc9, 0x01, 0x00, 0x24, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00,
-	0x24, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
-	0x41, 0x89, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00, 0x09, 0x89, 0x00, 0x03,
-	0x0c, 0xb0, 0x00, 0x00, 0x09, 0x89, 0x00, 0x0d, 0x18, 0xc0, 0x00, 0x00,
-	0x4e, 0x89, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
-	0x1f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x2d, 0x10, 0x48, 0xc1, 0x01, 0x00, 0x4e, 0x89, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x4b, 0x89, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x48, 0xb1, 0x01, 0x00, 0xc2, 0x94, 0x00, 0x41,
-	0x23, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x17, 0x10, 0xb0, 0x01, 0x00,
-	0x52, 0x89, 0x00, 0x40, 0x2b, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03,
-	0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe0, 0xb1, 0x01, 0x00,
-	0x57, 0x89, 0x22, 0x9f, 0x13, 0x6c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x88,
-	0x1c, 0xcc, 0x01, 0x00, 0x6b, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x4e, 0x99, 0x00, 0x41, 0x3f, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x8d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
-	0x3d, 0x99, 0x00, 0x40, 0x0f, 0x30, 0x01, 0x00, 0x15, 0x8a, 0x00, 0x5c,
-	0x1f, 0x90, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0e, 0xf4, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x3a, 0x01, 0x84, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07,
-	0x1a, 0xf4, 0x01, 0x00, 0x0b, 0x96, 0x00, 0x07, 0x16, 0x30, 0x01, 0x00,
-	0x66, 0x89, 0x22, 0x41, 0x81, 0x6c, 0x00, 0x00, 0x64, 0x89, 0x22, 0x42,
-	0x81, 0x6c, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x65, 0x89, 0x22, 0x5f, 0x0f, 0x7c, 0x00, 0x00, 0xff, 0x89, 0x00, 0x40,
-	0x0f, 0xb0, 0x00, 0x00, 0x6e, 0x89, 0xa2, 0x5a, 0x1f, 0x7c, 0x00, 0x00,
-	0x86, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x6e, 0x89, 0x22, 0x20,
-	0x85, 0x6c, 0x00, 0x00, 0x6b, 0x89, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x66, 0x96, 0x00, 0x5c,
-	0x1f, 0x00, 0x01, 0x00, 0x85, 0x98, 0x00, 0x42, 0x61, 0x31, 0x01, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xce, 0x99, 0x00, 0x07,
-	0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x80, 0xb0, 0x01, 0x00, 0xa8, 0x8a, 0xa2, 0x5f, 0x81, 0x6c, 0x00, 0x00,
-	0xa8, 0x00, 0x2d, 0x43, 0x19, 0x80, 0x01, 0x00, 0x37, 0x00, 0x2d, 0xf0,
-	0x24, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3, 0x8e, 0xf4, 0x01, 0x00,
-	0x0f, 0x00, 0x00, 0xf3, 0x90, 0x88, 0x01, 0x00, 0x7d, 0x89, 0x22, 0x48,
-	0x8e, 0x6c, 0x00, 0x00, 0x36, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x58, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00, 0x7d, 0x89, 0x1f, 0xf0,
-	0x24, 0x6c, 0x00, 0x00, 0x7c, 0x89, 0x23, 0x41, 0x8f, 0x6c, 0x00, 0x00,
-	0xa8, 0x8a, 0x00, 0x47, 0x81, 0xb0, 0x00, 0x00, 0xa8, 0x8a, 0x00, 0x48,
-	0x81, 0xb0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0xb0, 0x00, 0x2d, 0xf0, 0x14, 0xb0, 0x01, 0x00, 0x82, 0x89, 0x22, 0x0a,
-	0x90, 0x40, 0x00, 0x00, 0x21, 0x99, 0x00, 0x40, 0x91, 0x30, 0x01, 0x00,
-	0xa8, 0x8a, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0xb0, 0x00, 0x2d, 0x45,
-	0x81, 0xb0, 0x01, 0x00, 0x8e, 0x89, 0x22, 0xf0, 0x2c, 0x30, 0x00, 0x00,
-	0xa3, 0x00, 0x2d, 0x30, 0x83, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x2d, 0xf3,
-	0x82, 0xe0, 0x01, 0x00, 0x88, 0x89, 0xa3, 0x41, 0x2c, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x16, 0x82, 0xb0, 0x01, 0x00, 0x98, 0x00, 0x2d, 0xf0,
-	0x82, 0xc0, 0x01, 0x00, 0x88, 0x00, 0x2d, 0xf0, 0x82, 0xd0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf2, 0x98, 0xe8, 0x01, 0x00, 0xa8, 0x8a, 0x20, 0x4c,
-	0x82, 0x6c, 0x00, 0x00, 0x7c, 0x00, 0x2d, 0x41, 0x98, 0xe8, 0x01, 0x00,
-	0xa8, 0x8a, 0x20, 0xf0, 0x98, 0x6c, 0x00, 0x00, 0xff, 0x89, 0x22, 0x0a,
-	0x80, 0x32, 0x00, 0x00, 0x40, 0x02, 0x00, 0x0c, 0x7e, 0x89, 0x01, 0x00,
-	0xff, 0x89, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xa8, 0x8a, 0x00, 0x49,
-	0x81, 0xb0, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x80, 0xb0, 0x01, 0x00,
-	0x96, 0x89, 0x22, 0x43, 0x21, 0x6f, 0x00, 0x00, 0x13, 0x80, 0x00, 0x40,
-	0x80, 0xdc, 0x01, 0x00, 0x97, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x1a, 0x80, 0x00, 0x40, 0x80, 0xdc, 0x01, 0x00, 0x97, 0x89, 0xa2, 0x5e,
-	0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0xb1, 0x01, 0x00,
-	0x99, 0x89, 0x9f, 0x85, 0x80, 0x32, 0x00, 0x00, 0x9d, 0x89, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x5f, 0x84, 0x22, 0x40, 0x57, 0x7d, 0x00, 0x00,
-	0x01, 0x00, 0x00, 0x40, 0x57, 0x99, 0x01, 0x00, 0x9d, 0x89, 0x42, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
-	0x49, 0x84, 0x1a, 0x5b, 0x69, 0x93, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0xa0, 0x89, 0xa8, 0xb1, 0x80, 0x30, 0x00, 0x00,
-	0xc9, 0x89, 0x1d, 0x40, 0x80, 0x32, 0x00, 0x00, 0xba, 0x89, 0x22, 0x40,
-	0xaf, 0x6f, 0x00, 0x00, 0xba, 0x89, 0x22, 0x5b, 0x81, 0x7c, 0x00, 0x00,
-	0x04, 0x00, 0x22, 0x5d, 0x73, 0x7d, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0xa6, 0x89, 0xa8, 0xb1, 0x94, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
-	0x62, 0xb1, 0x01, 0x00, 0xa9, 0x89, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xab, 0x89, 0x43, 0x40, 0x81, 0x32, 0x00, 0x00, 0xb9, 0x89, 0x22, 0x57,
-	0x73, 0x7d, 0x00, 0x00, 0x77, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0xad, 0x89, 0xa8, 0xb1, 0x94, 0x30, 0x00, 0x00, 0x77, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0xaf, 0x89, 0xa8, 0xb1, 0x96, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
-	0x62, 0xb1, 0x01, 0x00, 0xb2, 0x89, 0xa8, 0x4a, 0x80, 0x33, 0x00, 0x00,
-	0xb7, 0x89, 0x22, 0x5f, 0x95, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x62, 0xb1, 0x01, 0x00, 0xb5, 0x89, 0xa8, 0x4b, 0xac, 0x33, 0x00, 0x00,
-	0x00, 0x00, 0x1b, 0xa5, 0x82, 0xb3, 0x01, 0x00, 0xba, 0x89, 0x00, 0xbe,
-	0x83, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x40, 0x81, 0xb3, 0x01, 0x00,
-	0x40, 0x18, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00, 0x04, 0x00, 0x00, 0xa6,
-	0x86, 0xb0, 0x01, 0x00, 0xc7, 0x89, 0xa2, 0x40, 0x86, 0x04, 0x00, 0x00,
-	0x1b, 0x84, 0x9c, 0x40, 0x80, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0x40,
-	0x88, 0x88, 0x01, 0x00, 0xe3, 0x89, 0x00, 0x50, 0x47, 0x31, 0x01, 0x00,
-	0x36, 0x00, 0x00, 0x44, 0x88, 0xcc, 0x01, 0x00, 0xc3, 0x89, 0x52, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xe3, 0x89, 0x00, 0x40, 0x47, 0x31, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x89, 0xb0, 0x01, 0x00, 0xe3, 0x89, 0x00, 0x48,
-	0x47, 0x31, 0x01, 0x00, 0xe3, 0x89, 0x00, 0x05, 0x47, 0x31, 0x01, 0x00,
-	0x1b, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x41, 0xe1, 0xc1, 0x00, 0x00,
-	0x78, 0x18, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00, 0xd0, 0x89, 0x22, 0x54,
-	0x81, 0x7c, 0x00, 0x00, 0xcb, 0x89, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x82, 0x00, 0xb4, 0x69, 0xdf, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x44,
-	0x93, 0x93, 0x01, 0x00, 0x28, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0xe3, 0x89, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00, 0xde, 0x89, 0x0f, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x40, 0x88, 0x88, 0x01, 0x00,
-	0xe3, 0x89, 0x00, 0x50, 0x47, 0x31, 0x01, 0x00, 0x36, 0x00, 0x00, 0x44,
-	0x88, 0xcc, 0x01, 0x00, 0xd6, 0x89, 0x99, 0x40, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0x89, 0xd0, 0x01, 0x00, 0xd8, 0x89, 0x9b, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x89, 0xd0, 0x01, 0x00,
-	0xda, 0x89, 0x1f, 0x44, 0x80, 0x32, 0x00, 0x00, 0xe3, 0x89, 0x00, 0x40,
-	0x47, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x89, 0xb0, 0x01, 0x00,
-	0xe3, 0x89, 0x00, 0x48, 0x47, 0x31, 0x01, 0x00, 0xe3, 0x89, 0x00, 0x58,
-	0x47, 0x31, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x10, 0x00, 0x00, 0x40, 0x86, 0xf4, 0x01, 0x00, 0x6f, 0x00, 0x00, 0x43,
-	0x86, 0x88, 0x01, 0x00, 0x1b, 0x84, 0x26, 0x05, 0x47, 0x31, 0x00, 0x00,
-	0xe3, 0x89, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x44, 0xf0, 0x41, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x80, 0x41,
-	0xe1, 0xc1, 0x01, 0x00, 0x04, 0x00, 0x00, 0xcb, 0x81, 0xc8, 0x01, 0x00,
-	0xe9, 0x89, 0x22, 0x40, 0xf2, 0x7f, 0x00, 0x00, 0x81, 0x80, 0x00, 0x6f,
-	0x97, 0x33, 0x01, 0x00, 0xeb, 0x89, 0x22, 0x40, 0x73, 0x7d, 0x00, 0x00,
-	0x9b, 0x80, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00, 0xe6, 0x89, 0x22, 0x59,
-	0x73, 0x7d, 0x00, 0x00, 0x79, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0xe6, 0x89, 0x28, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0xec, 0x89, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x22, 0xc0, 0x95, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xd6, 0x97, 0xb0, 0x01, 0x00, 0xf4, 0x89, 0x22, 0x5d,
-	0x73, 0x7d, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0xf2, 0x89, 0xa8, 0xb1, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e,
-	0x7f, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xc5, 0xb1, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x25, 0x01, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xf7, 0x89, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
-	0xf9, 0x89, 0x43, 0x5f, 0x7f, 0x13, 0x00, 0x00, 0x26, 0x01, 0x00, 0xbf,
-	0xc5, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x7f, 0x83, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5e, 0x7f, 0x93, 0x01, 0x00, 0x75, 0x98, 0x00, 0xbf,
-	0xc5, 0x31, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x06, 0x8a, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0x06, 0x8a, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x03, 0x8a, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x62, 0x95, 0x22, 0x02,
-	0x80, 0x32, 0x00, 0x00, 0x07, 0x8a, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00, 0x62, 0x95, 0x1a, 0x02,
-	0x68, 0x97, 0x00, 0x00, 0x11, 0x8a, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x11, 0x8a, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x0e, 0x8a, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x6c, 0x95, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00, 0x12, 0x8a, 0x42, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
-	0x6c, 0x95, 0x1a, 0x02, 0x68, 0x97, 0x00, 0x00, 0x1c, 0x8a, 0x9c, 0x0f,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
-	0x1c, 0x8a, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x19, 0x8a, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x6f, 0x84, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00,
-	0x1d, 0x8a, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x93, 0x93, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x02, 0x68, 0x97, 0x01, 0x00,
-	0x6f, 0x84, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0xa6,
-	0x56, 0xb1, 0x01, 0x00, 0x56, 0x95, 0x2f, 0x40, 0x05, 0xb0, 0x01, 0x00,
-	0x6d, 0x8a, 0xa2, 0x40, 0xe7, 0x6d, 0x00, 0x00, 0xb8, 0x94, 0x29, 0x41,
-	0xe7, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0xef, 0x93, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf2, 0x0e, 0xb0, 0x01, 0x00, 0x29, 0x00, 0x00, 0x40,
-	0x0d, 0x98, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07, 0x12, 0xe4, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xa7, 0x13, 0xc0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07,
-	0x1a, 0xf4, 0x01, 0x00, 0x07, 0x00, 0x00, 0x07, 0x16, 0x88, 0x01, 0x00,
-	0xff, 0xff, 0x00, 0x10, 0x34, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0x34, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
-	0x20, 0x18, 0x00, 0x40, 0x11, 0x98, 0x01, 0x00, 0x00, 0xb5, 0x00, 0x0d,
-	0x42, 0xc9, 0x01, 0x00, 0x51, 0x8a, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
-	0x32, 0x8a, 0x44, 0x40, 0x81, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0x07,
-	0x84, 0x89, 0x01, 0x00, 0x39, 0x8a, 0x05, 0xc2, 0x24, 0x30, 0x00, 0x00,
-	0x51, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x6e, 0x8a, 0x1c, 0xf0, 0x18, 0x30, 0x01, 0x00,
-	0x51, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x48, 0x8a, 0xa0, 0x48, 0x23, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x35, 0xd0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x1a,
-	0x42, 0xc9, 0x01, 0x00, 0x42, 0x8a, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x1a,
-	0x62, 0xdd, 0x01, 0x00, 0x3f, 0x8a, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x6e, 0x8a, 0x00, 0xf8, 0x18, 0x30, 0x01, 0x00,
-	0x43, 0x8a, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00, 0xff, 0xff, 0x00, 0x10,
-	0x34, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x34, 0x94, 0x01, 0x00,
-	0x20, 0x18, 0x00, 0x40, 0x11, 0x98, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x1a,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x1a, 0x62, 0xdd, 0x01, 0x00,
-	0x4c, 0x8a, 0xa8, 0x09, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x35, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x11, 0xc0, 0x01, 0x00, 0x5d, 0x8a, 0x22, 0x41,
-	0x0d, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0f, 0xc0, 0x01, 0x00,
-	0x59, 0x8a, 0xa0, 0xaa, 0x0f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x0f, 0xb0, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07, 0x12, 0xe4, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xa7, 0x13, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x1b, 0xb0, 0x01, 0x00, 0x30, 0x8a, 0x00, 0x41, 0x17, 0xb0, 0x00, 0x00,
-	0x00, 0x02, 0x00, 0x09, 0x12, 0xc8, 0x01, 0x00, 0x30, 0x8a, 0x83, 0x41,
-	0x17, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00,
-	0x30, 0x8a, 0x00, 0x41, 0x1b, 0xc0, 0x00, 0x00, 0x68, 0x8a, 0x23, 0x40,
-	0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x35, 0xd0, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x1a, 0x42, 0xc9, 0x01, 0x00, 0x65, 0x8a, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x1a, 0x62, 0xdd, 0x01, 0x00, 0x62, 0x8a, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x20, 0x98, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x6e, 0x8a, 0x00, 0xf8,
-	0x18, 0x30, 0x01, 0x00, 0x66, 0x8a, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x0f, 0xc0, 0x01, 0x00, 0x6b, 0x8a, 0xa0, 0xaa,
-	0x0f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0f, 0xb0, 0x01, 0x00,
-	0xb8, 0x94, 0x20, 0x07, 0xe4, 0xb1, 0x01, 0x00, 0x56, 0x95, 0x20, 0x40,
-	0xe7, 0xb1, 0x01, 0x00, 0xff, 0x89, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00,
-	0xff, 0xff, 0x00, 0x0c, 0x80, 0xd8, 0x01, 0x00, 0xc0, 0x02, 0x00, 0x0c,
-	0x7e, 0x89, 0x01, 0x00, 0x80, 0x8a, 0x26, 0x54, 0x61, 0x31, 0x00, 0x00,
-	0x76, 0x8a, 0x87, 0x0c, 0x80, 0x32, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x40,
-	0x62, 0x99, 0x01, 0x00, 0x76, 0x8a, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x76, 0x8a, 0xa2, 0x54, 0x77, 0x7d, 0x00, 0x00, 0x72, 0x8a, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x7b, 0x8a, 0x22, 0x46, 0x19, 0x7c, 0x00, 0x00,
-	0x0d, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x01, 0x00,
-	0x77, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x80, 0x8a, 0x22, 0x49,
-	0x19, 0x7c, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x54,
-	0x77, 0x7d, 0x01, 0x00, 0x7b, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x10, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x01, 0x00,
-	0x80, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x30, 0x94, 0x2f, 0x55,
-	0xf1, 0x93, 0x01, 0x00, 0x00, 0x40, 0x00, 0xa6, 0x56, 0xb1, 0x01, 0x00,
-	0x6f, 0x84, 0xa2, 0x41, 0xe5, 0x51, 0x00, 0x00, 0x64, 0x00, 0x00, 0x40,
-	0xe5, 0x99, 0x01, 0x00, 0x88, 0x8a, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x8b, 0x8a, 0xa2, 0x93, 0x57, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x57, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x1a, 0xab, 0x27, 0xb3, 0x01, 0x00,
-	0x6f, 0x84, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00, 0x6f, 0x84, 0x22, 0x51,
-	0xfd, 0x7f, 0x00, 0x00, 0x6f, 0x84, 0xa2, 0x41, 0x1d, 0x53, 0x00, 0x00,
-	0x50, 0x46, 0x00, 0x40, 0x1d, 0x9b, 0x01, 0x00, 0x34, 0x82, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0xfc, 0x81, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00, 0x97, 0x8a, 0x22, 0x40,
-	0xb5, 0x6f, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0xff, 0x81, 0x00, 0x41, 0xb5, 0x53, 0x01, 0x00, 0x6f, 0x84, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0xfd, 0x83, 0x01, 0x00,
-	0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x35, 0x82, 0x00, 0x40,
-	0x49, 0x31, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
-	0x91, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0xff, 0x81, 0x00, 0x40, 0xb5, 0x33, 0x01, 0x00, 0x60, 0x16, 0x20, 0x40,
-	0xe5, 0xb1, 0x01, 0x00, 0xdb, 0x82, 0x00, 0x40, 0xb5, 0x33, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xff, 0xff, 0x00, 0x4a,
-	0xb4, 0x8b, 0x01, 0x00, 0xff, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x0a, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x00, 0x00, 0x4a,
-	0xb4, 0xf7, 0x01, 0x00, 0xff, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x6f, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x05, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x08, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0x20, 0x40, 0xe6, 0xb1, 0x01, 0x00, 0x03, 0x00, 0x00, 0x40,
-	0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x96, 0xc0, 0x01, 0x00,
-	0xae, 0x8a, 0x00, 0x4b, 0x10, 0xc9, 0x00, 0x00, 0xd1, 0x8d, 0x00, 0x41,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x05, 0x8e, 0x00, 0x41,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x37, 0x8e, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x37, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x37, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x37, 0x8e, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x76, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x9f, 0x8e, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0xa3, 0x8e, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
-	0x0b, 0x90, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0xaf, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xae, 0x8e, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x6f, 0x8f, 0x00, 0x42,
-	0x09, 0xb0, 0x00, 0x00, 0x6f, 0x8f, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0x6f, 0x8f, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x9b, 0x8f, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0xb9, 0x8f, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xb9, 0x8f, 0x00, 0x44,
-	0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0xb9, 0x8f, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xe1, 0x8f, 0x00, 0x44,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
-	0xf2, 0x8f, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0xf2, 0x8f, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xf4, 0x8f, 0x00, 0x42,
-	0x09, 0xb0, 0x00, 0x00, 0xf4, 0x8f, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0xf4, 0x8f, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xf4, 0x8f, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0xfc, 0x8f, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
-	0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x0d, 0x90, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
-	0xfd, 0x8f, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x0d, 0x90, 0x00, 0x44,
-	0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x0e, 0x90, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x90, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00,
-	0x6d, 0x8f, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x6d, 0x8f, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0x6d, 0x8f, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
-	0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x41,
-	0x09, 0xb0, 0x00, 0x00, 0x0f, 0x90, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
-	0x0f, 0x90, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x0f, 0x90, 0x00, 0x44,
-	0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x16, 0x90, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x18, 0x90, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x24, 0x90, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0x8d, 0x90, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xa3, 0x8e, 0x00, 0x44,
-	0x09, 0xb0, 0x00, 0x00, 0x0b, 0x90, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x95, 0x90, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0xa3, 0x8e, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x0b, 0x90, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xa6, 0x90, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x73, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0x91, 0x90, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xa3, 0x8e, 0x00, 0x44,
-	0x09, 0xb0, 0x00, 0x00, 0x0b, 0x90, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x07, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf3, 0x08, 0xb0, 0x01, 0x00, 0x06, 0x00, 0x20, 0x47,
-	0xe6, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x47, 0x96, 0xe4, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x96, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0x96, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x96, 0xc0, 0x01, 0x00,
-	0x6e, 0x8b, 0x00, 0x4b, 0x10, 0xc9, 0x00, 0x00, 0xbe, 0x90, 0x00, 0x49,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xf7, 0x90, 0x00, 0x42,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xfd, 0x90, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x0b, 0x91, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x2c, 0x91, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x27, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x2f, 0x91, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x87, 0x91, 0x00, 0x44,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x86, 0x91, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x00, 0x91, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x00, 0x91, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0x00, 0x91, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x00, 0x91, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x00, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
-	0x00, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x00, 0x91, 0x00, 0x48,
-	0x09, 0xb0, 0x00, 0x00, 0x00, 0x91, 0x00, 0x49, 0x09, 0xb0, 0x00, 0x00,
-	0x00, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x00, 0x91, 0x00, 0x4b,
-	0x09, 0xb0, 0x00, 0x00, 0x00, 0x91, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
-	0x00, 0x91, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xe6, 0x91, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xe6, 0x91, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xe6, 0x91, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xfe, 0x91, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x15, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xf2, 0x91, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x6a, 0x94, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x2c, 0x91, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0x0b, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
-	0x25, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x48,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x27, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x87, 0x91, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x2f, 0x91, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x25, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x86, 0x91, 0x00, 0x4c,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x1b, 0x92, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
-	0x1b, 0x92, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0xba, 0x8d, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0xba, 0x8d, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x1b, 0x92, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x00, 0x91, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00, 0x3e, 0x92, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x26, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x26, 0x92, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x26, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x3e, 0x92, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x25, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x26, 0x92, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x4d, 0x92, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x4d, 0x92, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xaf, 0x92, 0x00, 0x40, 0x09, 0xb0, 0x00, 0x00, 0xcc, 0x92, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0xc0, 0x92, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
-	0x1e, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x1e, 0x92, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0xcc, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0xd3, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0xd3, 0x92, 0x00, 0x48,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xc0, 0x92, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x1e, 0x92, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x1e, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0xc0, 0x92, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xe6, 0x91, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xe6, 0x91, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0xe6, 0x91, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x25, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xe6, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xe6, 0x91, 0x00, 0x4c,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x3d, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x31, 0x92, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x25, 0x92, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x25, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x3d, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0xba, 0x8d, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0xba, 0x8d, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x31, 0x92, 0x00, 0x48,
-	0x09, 0xb0, 0x00, 0x00, 0x25, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x25, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x31, 0x92, 0x00, 0x48,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xd5, 0x92, 0x00, 0x42,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xd5, 0x92, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xd5, 0x92, 0x00, 0x4b,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xd5, 0x92, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xd5, 0x92, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0xd5, 0x92, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0xd5, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0xd5, 0x92, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xd5, 0x92, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xd5, 0x92, 0x00, 0x4c,
-	0x09, 0xb0, 0x00, 0x00, 0xd5, 0x92, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xef, 0x92, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x15, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xef, 0x92, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xf6, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x15, 0x92, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xf6, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xf6, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x19, 0x94, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x18, 0x94, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x19, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x18, 0x94, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xe0, 0x92, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xec, 0x92, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xec, 0x92, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xec, 0x92, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xec, 0x92, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xec, 0x92, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0xec, 0x92, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0xec, 0x92, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0xec, 0x92, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xec, 0x92, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xfe, 0x91, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x15, 0x92, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xf2, 0x91, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xb8, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x5f, 0x94, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x5f, 0x94, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x5f, 0x94, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x5f, 0x94, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x5f, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x5f, 0x94, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xf2, 0x91, 0x00, 0x42,
-	0x09, 0xb0, 0x00, 0x00, 0x6a, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xf2, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x15, 0x92, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x6a, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x6a, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x6e, 0x94, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x15, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xb0, 0x94, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x6e, 0x94, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x7f, 0x94, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x5d, 0x94, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x7f, 0x94, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x25, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x48,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x5d, 0x94, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x90, 0x94, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x15, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x90, 0x94, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x90, 0x94, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x0b, 0x91, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x2c, 0x91, 0x00, 0x42,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xae, 0x94, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x2c, 0x91, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0x0b, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
-	0x25, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x48,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xae, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xb0, 0x94, 0x00, 0x4a,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x15, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xb0, 0x94, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x6b, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x6b, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x15, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x6b, 0x94, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x6b, 0x94, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xb6, 0x94, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x5d, 0x94, 0x00, 0x4a,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xb6, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x25, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x5d, 0x94, 0x00, 0x4a,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x2f, 0x91, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x2f, 0x91, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00,
-	0x25, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x48,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x07, 0x00, 0x2e, 0x4b,
-	0x19, 0x90, 0x01, 0x00, 0x0a, 0x8a, 0x00, 0x04, 0xe6, 0xb1, 0x00, 0x00,
-	0xba, 0x8d, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0xaf, 0x97, 0x00, 0x3a,
-	0x81, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xba, 0x8d, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x0f,
-	0x1e, 0x8c, 0x01, 0x00, 0x21, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xca, 0x8d, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
-	0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
-	0xca, 0x8d, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0xc7, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x13, 0x86, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00,
-	0xcb, 0x8d, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x93, 0x93, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x02, 0x68, 0x97, 0x01, 0x00,
-	0x13, 0x86, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x05, 0x00, 0x2e, 0x4b,
-	0x19, 0x90, 0x01, 0x00, 0x0a, 0x8a, 0x00, 0x04, 0xe6, 0xb1, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x8d, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0xa1, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0xe0, 0xb1, 0x01, 0x00, 0x3d, 0x99, 0x00, 0x06, 0x07, 0x40, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x06, 0x07, 0xd0, 0x01, 0x00, 0xd4, 0x00, 0x2e, 0x5c,
-	0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf0, 0xb1, 0x01, 0x00,
-	0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfe, 0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
-	0x96, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
-	0x96, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x96, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x96, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfe, 0x96, 0xc0, 0x01, 0x00, 0x00, 0x30, 0x00, 0x4b,
-	0x94, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x95, 0xf0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4a, 0x96, 0xc0, 0x01, 0x00, 0x5e, 0x01, 0x2e, 0x34,
-	0x97, 0x84, 0x01, 0x00, 0x02, 0x00, 0x00, 0x4b, 0xe4, 0xe5, 0x01, 0x00,
-	0x64, 0x01, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
-	0x86, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x2e, 0xa7, 0x87, 0xc0, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x40,
-	0xf1, 0x99, 0x01, 0x00, 0x58, 0x01, 0x00, 0x43, 0xf0, 0xc9, 0x01, 0x00,
-	0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
-	0xf4, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x1a, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
-	0x08, 0x00, 0x2e, 0x40, 0x95, 0xb0, 0x01, 0x00, 0xfc, 0x8d, 0x20, 0x4b,
-	0x94, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
-	0xf9, 0x8d, 0x00, 0x41, 0x95, 0xc0, 0x00, 0x00, 0x10, 0x80, 0x00, 0x10,
-	0x44, 0xc9, 0x01, 0x00, 0x03, 0x8e, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0xff, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0xaf, 0x97, 0x00, 0x40, 0x81, 0x30, 0x01, 0x00,
-	0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x0c, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x86, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x88, 0xb0, 0x01, 0x00, 0x08, 0x8e, 0x42, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x0b, 0x8e, 0xa2, 0x4c, 0xfd, 0x7f, 0x00, 0x00,
-	0x0c, 0x8e, 0x00, 0x4c, 0xfd, 0x93, 0x00, 0x00, 0x0d, 0x8e, 0x20, 0xf0,
-	0x56, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x56, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x1a, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x44, 0xc9, 0x01, 0x00, 0x64, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
-	0x70, 0x00, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x13, 0x8e, 0xa8, 0x44,
-	0xe0, 0x31, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x8c, 0xc8, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x46, 0x44, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40,
-	0xf1, 0x99, 0x01, 0x00, 0x68, 0x01, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00,
-	0x64, 0x00, 0x00, 0x43, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x62, 0xb1, 0x01, 0x00,
-	0x1b, 0x8e, 0xa8, 0x44, 0xe0, 0x31, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x09, 0x00, 0x00, 0x07, 0x86, 0xe4, 0x01, 0x00,
-	0x38, 0x00, 0x2e, 0xa7, 0x87, 0xc0, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x23, 0x8e, 0x22, 0x43, 0xe7, 0x7d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00, 0x26, 0x8e, 0x22, 0x44,
-	0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x45, 0xc1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4a, 0x19, 0x90, 0x01, 0x00, 0x68, 0x01, 0x20, 0xa2,
-	0xe4, 0xb1, 0x01, 0x00, 0x88, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x2a, 0x8e, 0x23, 0x0b, 0xe5, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x19, 0x90, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
-	0x50, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x58, 0x01, 0x00, 0x43,
-	0xf0, 0xc9, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x62, 0xb1, 0x01, 0x00, 0x2f, 0x8e, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x5c, 0x00, 0x2e, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x60, 0xf0, 0x96, 0xb0, 0x01, 0x00, 0xaf, 0x97, 0x00, 0x41,
-	0x81, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x3a, 0x8e, 0xa2, 0x49, 0x19, 0x7c, 0x00, 0x00, 0x86, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x3e, 0x8e, 0x00, 0x40, 0xe5, 0xb1, 0x00, 0x00,
-	0x86, 0x00, 0x2f, 0x49, 0x19, 0x80, 0x01, 0x00, 0x3e, 0x8e, 0xa2, 0xf2,
-	0x80, 0x32, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0xe7, 0x91, 0x01, 0x00, 0x41, 0x8e, 0xa2, 0x46,
-	0x19, 0x7c, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x45, 0x8e, 0x00, 0x40, 0xe5, 0xb1, 0x00, 0x00, 0xa0, 0x00, 0x2f, 0x46,
-	0x19, 0x80, 0x01, 0x00, 0x45, 0x8e, 0xa2, 0xf2, 0x80, 0x32, 0x00, 0x00,
-	0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0xe7, 0x91, 0x01, 0x00, 0xa8, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x34, 0x00, 0x2d, 0xf0, 0x24, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
-	0x0c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x10, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfb, 0x12, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3,
-	0x16, 0x88, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3, 0x14, 0xf4, 0x01, 0x00,
-	0x70, 0x8e, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x58, 0x8e, 0x22, 0x0a,
-	0x16, 0x6c, 0x00, 0x00, 0x58, 0x00, 0x3d, 0x43, 0x13, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0,
-	0x84, 0x30, 0x00, 0x00, 0xe7, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x13, 0xc0, 0x01, 0x00,
-	0x57, 0x8e, 0xa0, 0x43, 0x13, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x13, 0xb0, 0x01, 0x00, 0x4d, 0x8e, 0x00, 0x41, 0x15, 0xd0, 0x00, 0x00,
-	0x70, 0x8e, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00, 0x58, 0x00, 0x3d, 0x43,
-	0x13, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0xf0, 0x84, 0x30, 0x00, 0x00, 0xe7, 0x98, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x40, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x70, 0x8e, 0x22, 0x41, 0x15, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x11, 0xc0, 0x01, 0x00, 0x64, 0x8e, 0xa0, 0x43,
-	0x11, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0xb0, 0x01, 0x00,
-	0x58, 0x00, 0x3d, 0x43, 0x11, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x36, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x00, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x83, 0xb0, 0x01, 0x00, 0xee, 0x97, 0x00, 0x47,
-	0x61, 0x31, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x5f, 0x95, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x6c, 0x8e, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x60, 0x8e, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
-	0x37, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x20, 0x98, 0x00, 0x51,
-	0x81, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x34, 0x00, 0x2e, 0x41, 0xf5, 0xb1, 0x01, 0x00, 0x00, 0x11, 0x00, 0x40,
-	0xe5, 0x99, 0x01, 0x00, 0x78, 0x8e, 0x00, 0x48, 0x19, 0x90, 0x00, 0x00,
-	0x34, 0x00, 0x2e, 0x41, 0xf5, 0xb1, 0x01, 0x00, 0x00, 0x11, 0x00, 0x40,
-	0xe5, 0x99, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00, 0x7d, 0x8e, 0x22, 0x45,
-	0x23, 0x7c, 0x00, 0x00, 0xb0, 0x00, 0x2f, 0xf0, 0x8c, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x60, 0xf0, 0x8c, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x35, 0x00, 0x2d, 0xf0, 0x8c, 0xb0, 0x01, 0x00,
-	0x58, 0x00, 0x3e, 0x43, 0xe7, 0xe1, 0x01, 0x00, 0x82, 0x8e, 0x22, 0x48,
-	0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x8d, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x68, 0x0a, 0x8c, 0xc0, 0x01, 0x00, 0x38, 0x00, 0x2a, 0x4a,
-	0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00,
-	0x3c, 0x00, 0x20, 0x1b, 0xe0, 0xb1, 0x01, 0x00, 0x10, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x38, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x26, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf8,
-	0x02, 0x30, 0x00, 0x00, 0x90, 0x8e, 0x23, 0x01, 0x14, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x82, 0xb0, 0x01, 0x00, 0x4c, 0x00, 0x20, 0xf0, 0xe4, 0xb1, 0x01, 0x00,
-	0x44, 0x00, 0x20, 0x40, 0xe0, 0xb1, 0x01, 0x00, 0x48, 0x00, 0x20, 0x41,
-	0xe0, 0xb1, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0x10, 0x32, 0xb0, 0x01, 0x00,
-	0x21, 0x99, 0x00, 0xf0, 0x24, 0x30, 0x01, 0x00, 0x99, 0x8e, 0xa2, 0x44,
-	0x81, 0x6c, 0x00, 0x00, 0x97, 0x8e, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0x8a, 0x96, 0x00, 0x40, 0x3b, 0x30, 0x01, 0x00, 0xbd, 0x8e, 0xa2, 0x08,
-	0x3c, 0x30, 0x00, 0x00, 0x99, 0x8e, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xc7, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xbd, 0x8e, 0xa2, 0x08,
-	0x3c, 0x30, 0x00, 0x00, 0x50, 0x00, 0x20, 0x1c, 0xe0, 0xb1, 0x01, 0x00,
-	0x54, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00, 0x4e, 0x00, 0x20, 0x01,
-	0xe4, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x20, 0x0a, 0xe0, 0xb1, 0x01, 0x00,
-	0x20, 0x98, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x69, 0x96, 0x00, 0xf3, 0x94, 0x30, 0x01, 0x00, 0x78, 0x8e, 0x22, 0x4a,
-	0x80, 0x32, 0x00, 0x00, 0xa5, 0x8e, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x69, 0x96, 0x00, 0xf3,
-	0x94, 0x30, 0x01, 0x00, 0x58, 0x00, 0x3e, 0x43, 0x97, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x1b, 0xf0, 0xb1, 0x01, 0x00, 0x1f, 0x00, 0x60, 0x00,
-	0x00, 0x8c, 0x01, 0x00, 0xcf, 0x8d, 0x85, 0x11, 0x80, 0x32, 0x00, 0x00,
-	0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0xb0, 0x00, 0x2f, 0xf0,
-	0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0xf0, 0x8c, 0xc0, 0x01, 0x00,
-	0x20, 0x98, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xaf, 0x8e, 0x00, 0x49, 0x19, 0x80, 0x00, 0x00,
-	0xb4, 0x8e, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x8a, 0x96, 0x00, 0x40,
-	0x3b, 0x30, 0x01, 0x00, 0xb8, 0x8e, 0xa2, 0x08, 0x3c, 0x30, 0x00, 0x00,
-	0x20, 0x98, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xc7, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xb8, 0x8e, 0xa2, 0x08, 0x3c, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x5f,
-	0x81, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x50, 0x00, 0x2d, 0x10, 0x32, 0xb0, 0x01, 0x00, 0x54, 0x00, 0x2d, 0xf0,
-	0x38, 0xb0, 0x01, 0x00, 0x4e, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00,
-	0x40, 0x00, 0x2d, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x14, 0xb0, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10, 0x8c, 0xc8, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x46, 0x44, 0xc9, 0x01, 0x00, 0x68, 0x01, 0x2d, 0x44,
-	0x61, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x68, 0xf2, 0x80, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05,
-	0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x37, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x36, 0xd0, 0x01, 0x00, 0x5c, 0x01, 0x2e, 0x40,
-	0x10, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x52, 0x81, 0xd0, 0x01, 0x00, 0xcb, 0x8e, 0x20, 0x94,
-	0x81, 0x6c, 0x00, 0x00, 0xb5, 0x97, 0x00, 0x94, 0xe5, 0x31, 0x01, 0x00,
-	0xcc, 0x8e, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb5, 0x97, 0x00, 0x40,
-	0xe4, 0x31, 0x01, 0x00, 0x20, 0x00, 0x00, 0x46, 0x62, 0xdd, 0x01, 0x00,
-	0xcc, 0x8e, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x0f,
-	0x1e, 0x8c, 0x01, 0x00, 0xdc, 0x8e, 0x82, 0x41, 0x23, 0x40, 0x00, 0x00,
-	0x20, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0xd6, 0x8e, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xd3, 0x8e, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x48, 0xb1, 0x01, 0x00, 0xfb, 0x95, 0x00, 0x43,
-	0x23, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x23, 0xb0, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x0f, 0x1e, 0x8c, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x19, 0x44, 0xc9, 0x01, 0x00, 0xe4, 0x8e, 0x22, 0x41,
-	0x19, 0x7c, 0x00, 0x00, 0xe0, 0x8e, 0xa3, 0x01, 0x0c, 0x6c, 0x00, 0x00,
-	0xe1, 0x8e, 0x00, 0x06, 0x04, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-	0x04, 0xb0, 0x01, 0x00, 0xe3, 0x8e, 0x20, 0x02, 0x36, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x1b, 0x04, 0xb0, 0x01, 0x00, 0xe7, 0x8e, 0x00, 0x02,
-	0xf0, 0xb1, 0x00, 0x00, 0xe6, 0x8e, 0xa3, 0x01, 0x0c, 0x6c, 0x00, 0x00,
-	0xe7, 0x8e, 0x68, 0x06, 0x04, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x01,
-	0x04, 0xb0, 0x01, 0x00, 0xe9, 0x8e, 0x80, 0x08, 0xf0, 0x31, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x11, 0x1e, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1c,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
-	0x01, 0x1f, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00, 0xeb, 0x8e, 0xa8, 0x13,
-	0xe0, 0x31, 0x00, 0x00, 0x22, 0x8f, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00,
-	0x44, 0x00, 0x2d, 0x02, 0x0c, 0xd0, 0x01, 0x00, 0x12, 0x8f, 0xa2, 0x02,
-	0x02, 0x50, 0x00, 0x00, 0xf9, 0x8e, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
-	0x20, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0xf8, 0x8e, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xf4, 0x8e, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x44, 0x00, 0x2d, 0x5c,
-	0x1f, 0x80, 0x01, 0x00, 0x48, 0x00, 0x2d, 0xf0, 0x38, 0xb0, 0x01, 0x00,
-	0x4c, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00, 0x38, 0x00, 0x2f, 0xf2,
-	0x02, 0xb0, 0x01, 0x00, 0x13, 0x8f, 0x22, 0x01, 0x14, 0x6c, 0x00, 0x00,
-	0x06, 0x8f, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0x1f, 0x80, 0x01, 0x00, 0x20, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00,
-	0x05, 0x8f, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x02, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x38, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00, 0x38, 0x00, 0x2d, 0xf0,
-	0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0xe1, 0xc1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x22, 0x4a,
-	0xf1, 0xb1, 0x01, 0x00, 0x44, 0x00, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4a, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
-	0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0x0f, 0x8f, 0xa8, 0x5c,
-	0x1f, 0x10, 0x00, 0x00, 0x13, 0x8f, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x02, 0x38, 0xc0, 0x01, 0x00, 0x1d, 0x8f, 0x22, 0x06,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
-	0x1b, 0x8f, 0xa2, 0x02, 0x36, 0x6c, 0x00, 0x00, 0x04, 0x00, 0x8f, 0x0d,
-	0x42, 0x31, 0x00, 0x00, 0x10, 0x00, 0x00, 0xf8, 0x10, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5c, 0x11, 0x80, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
-	0x37, 0x98, 0x01, 0x00, 0xcf, 0x8e, 0x00, 0xa1, 0x1a, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00, 0xcf, 0x8e, 0x00, 0x02,
-	0x36, 0xd0, 0x00, 0x00, 0x50, 0x00, 0x20, 0x1c, 0xe0, 0xb1, 0x01, 0x00,
-	0x54, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00, 0x4e, 0x00, 0x20, 0x01,
-	0xe4, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x20, 0x0a, 0xe0, 0xb1, 0x01, 0x00,
-	0x27, 0x8f, 0x00, 0x5f, 0x01, 0xb0, 0x00, 0x00, 0x37, 0x00, 0x2d, 0x46,
-	0x01, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3, 0x80, 0xf4, 0x01, 0x00,
-	0x26, 0x8f, 0xa0, 0x43, 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
-	0x01, 0xb0, 0x01, 0x00, 0x40, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00, 0x2d, 0x8f, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00, 0x2a, 0x8f, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0xfb, 0x95, 0x00, 0x10, 0x48, 0x31, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0x34, 0x8f, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x31, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x60, 0x01, 0x2f, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe4, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x17, 0xf0, 0x01, 0x00, 0x39, 0x8f, 0x90, 0xf2,
-	0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00, 0x32, 0x00, 0x00, 0xa6,
-	0x2a, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x2a, 0x94, 0x01, 0x00,
-	0x42, 0x8f, 0x22, 0x49, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
-	0x1f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
-	0x00, 0xf0, 0x00, 0x0c, 0x18, 0x8c, 0x01, 0x00, 0xf5, 0x97, 0x00, 0x4c,
-	0x95, 0x30, 0x01, 0x00, 0x52, 0x8f, 0x00, 0x00, 0x92, 0xb0, 0x00, 0x00,
-	0x49, 0x8f, 0x22, 0x40, 0xaf, 0x6f, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x1e,
-	0x94, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15, 0x96, 0xb0, 0x01, 0x00,
-	0x72, 0x98, 0x00, 0x40, 0x05, 0x30, 0x01, 0x00, 0x48, 0x8f, 0xa2, 0x40,
-	0x97, 0x6c, 0x00, 0x00, 0x5b, 0x8f, 0x00, 0x47, 0x19, 0x80, 0x00, 0x00,
-	0x52, 0x8f, 0x00, 0x00, 0x92, 0xb0, 0x00, 0x00, 0x49, 0x8f, 0x43, 0x48,
-	0x61, 0x31, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x1e, 0x62, 0xdd, 0x01, 0x00,
-	0x4e, 0x8f, 0x28, 0x40, 0x05, 0x30, 0x00, 0x00, 0x4a, 0x8f, 0x22, 0x48,
-	0x77, 0x7d, 0x00, 0x00, 0x51, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x15, 0x62, 0xb1, 0x01, 0x00, 0x5a, 0x8f, 0x28, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x4e, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x1b, 0x00, 0x92, 0xb0, 0x01, 0x00, 0x57, 0x8f, 0x22, 0x41,
-	0x19, 0x7c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0xcc, 0x95, 0x00, 0xf8, 0x00, 0x30, 0x01, 0x00, 0x54, 0x8f, 0xa2, 0x41,
-	0x3b, 0x50, 0x00, 0x00, 0x5b, 0x8f, 0x00, 0x49, 0x00, 0xb0, 0x00, 0x00,
-	0xff, 0x07, 0x00, 0x1e, 0x00, 0x8c, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x5b, 0x8f, 0x00, 0x49, 0x00, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x1b, 0x47, 0x19, 0x80, 0x01, 0x00, 0x5e, 0x8f, 0x22, 0x5f,
-	0x01, 0x6c, 0x00, 0x00, 0x4b, 0x99, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xaa, 0x8a, 0x00, 0x00, 0x80, 0xb0, 0x00, 0x00, 0x65, 0x8f, 0x22, 0x5c,
-	0x1f, 0x7c, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x65, 0x8f, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x62, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x65, 0x8f, 0x40, 0x05, 0x48, 0x31, 0x00, 0x00,
-	0xff, 0xff, 0x00, 0x07, 0x94, 0x89, 0x01, 0x00, 0x6b, 0x8f, 0x85, 0xca,
-	0x94, 0x30, 0x00, 0x00, 0x4b, 0x99, 0x18, 0x5c, 0x1f, 0x00, 0x01, 0x00,
-	0x0e, 0x00, 0x00, 0x0f, 0x1e, 0x8c, 0x01, 0x00, 0x72, 0x89, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x20, 0x98, 0x18, 0x00, 0x80, 0x30, 0x01, 0x00,
-	0xcf, 0x8d, 0x00, 0x47, 0x19, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x19, 0x80, 0x01, 0x00, 0xcf, 0x8d, 0x22, 0x47, 0x19, 0x7c, 0x00, 0x00,
-	0xc7, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x72, 0x8f, 0xa2, 0x08,
-	0x80, 0x32, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xb5, 0x97, 0x00, 0x40, 0x0d, 0x30, 0x01, 0x00, 0x9c, 0x01, 0x00, 0x40,
-	0x45, 0x99, 0x01, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x98, 0x88, 0x01, 0x00,
-	0x8b, 0x00, 0x2d, 0x50, 0x17, 0xf0, 0x01, 0x00, 0x78, 0x8f, 0x90, 0x4c,
-	0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
-	0x7a, 0x8f, 0x22, 0x43, 0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x45, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00,
-	0x68, 0x01, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x5c, 0x01, 0x2e, 0xf2,
-	0x80, 0xb0, 0x01, 0x00, 0x3e, 0x00, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
-	0x81, 0x8f, 0x24, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0x81, 0xc0, 0x01, 0x00, 0x82, 0x8f, 0x00, 0x94, 0xe5, 0xb1, 0x00, 0x00,
-	0x02, 0x00, 0x62, 0x40, 0x7e, 0xcd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57,
-	0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
-	0x03, 0x00, 0x00, 0x40, 0xf0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
-	0xf0, 0xb1, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x62, 0xb1, 0x01, 0x00, 0x88, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x94, 0x8f, 0x22, 0x40, 0xaf, 0x6f, 0x00, 0x00,
-	0x00, 0x40, 0x00, 0x08, 0x94, 0xdc, 0x01, 0x00, 0x72, 0x98, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x92, 0x8f, 0x22, 0x40, 0x97, 0x6c, 0x00, 0x00,
-	0xcc, 0x95, 0x00, 0x08, 0x00, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
-	0xcf, 0x8d, 0x00, 0x47, 0x19, 0x80, 0x00, 0x00, 0x94, 0x8f, 0x43, 0x48,
-	0x61, 0x31, 0x00, 0x00, 0x00, 0x50, 0x00, 0x08, 0x62, 0xdd, 0x01, 0x00,
-	0x9a, 0x8f, 0x28, 0x40, 0x05, 0x30, 0x00, 0x00, 0x95, 0x8f, 0x22, 0x48,
-	0x77, 0x7d, 0x00, 0x00, 0xcc, 0x95, 0x1b, 0x08, 0x00, 0x30, 0x01, 0x00,
-	0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xcf, 0x8d, 0x1b, 0x47,
-	0x19, 0x80, 0x00, 0x00, 0x35, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x01, 0x00, 0x63, 0xf3, 0x84, 0xc8, 0x01, 0x00, 0x9f, 0x8f, 0xa0, 0x43,
-	0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x63, 0x40, 0x85, 0xb0, 0x01, 0x00,
-	0xa8, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x37, 0x00, 0x2f, 0xf0,
-	0x24, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3, 0x82, 0xcc, 0x01, 0x00,
-	0xaa, 0x8f, 0xa2, 0x41, 0x9e, 0x06, 0x00, 0x00, 0xcf, 0x8d, 0x22, 0x44,
-	0x83, 0x70, 0x00, 0x00, 0x36, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x58, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00, 0xcf, 0x8d, 0x1f, 0xf0,
-	0x24, 0x6c, 0x00, 0x00, 0x4b, 0x99, 0x00, 0x48, 0x81, 0x30, 0x01, 0x00,
-	0xaa, 0x8a, 0x23, 0x41, 0x83, 0x6c, 0x00, 0x00, 0xaa, 0x8a, 0x00, 0x47,
-	0x81, 0xb0, 0x00, 0x00, 0x58, 0x00, 0x3d, 0x43, 0x85, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x36, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x00, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
-	0xee, 0x97, 0x00, 0x47, 0x61, 0x31, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00,
-	0x08, 0x00, 0x2d, 0xf0, 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x8e, 0xb0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0, 0x14, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x7e, 0x8e, 0xa2, 0x40,
-	0x8f, 0x7c, 0x00, 0x00, 0xb8, 0x8f, 0x22, 0x47, 0x8f, 0x7c, 0x00, 0x00,
-	0x7e, 0x8e, 0x00, 0x48, 0x19, 0x90, 0x00, 0x00, 0x27, 0x90, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x36, 0x00, 0x2d, 0x5d, 0x05, 0xb4, 0x01, 0x00,
-	0x37, 0x00, 0x2d, 0xf3, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
-	0x8e, 0xb0, 0x01, 0x00, 0x5c, 0x00, 0x3d, 0x43, 0x81, 0xe0, 0x01, 0x00,
-	0xa8, 0x00, 0x2d, 0xf0, 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x24, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10, 0x86, 0xdc, 0x01, 0x00,
-	0x40, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0xce, 0x94, 0x00, 0x4a,
-	0xf0, 0x31, 0x01, 0x00, 0x36, 0x00, 0x2f, 0x5c, 0x1f, 0x90, 0x01, 0x00,
-	0xc6, 0x8f, 0xa2, 0x50, 0x8f, 0x50, 0x00, 0x00, 0x34, 0x00, 0x20, 0x40,
-	0xe1, 0xb1, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x63, 0x41, 0x81, 0xc0, 0x01, 0x00, 0xc9, 0x8f, 0xa0, 0x43,
-	0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x63, 0x40, 0x81, 0xb0, 0x01, 0x00,
-	0x37, 0x00, 0x20, 0x47, 0xe6, 0xb1, 0x01, 0x00, 0xcf, 0x8d, 0x22, 0x47,
-	0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0x00, 0x47, 0x0c, 0xf4, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4f, 0x8f, 0x84, 0x01, 0x00, 0xde, 0x8f, 0x22, 0x47,
-	0x0c, 0x6c, 0x00, 0x00, 0x58, 0x00, 0x3d, 0x43, 0x81, 0xe0, 0x01, 0x00,
-	0xde, 0x8f, 0x1f, 0xf0, 0x24, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
-	0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
-	0xd7, 0x8f, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0xd4, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0xd7, 0x8f, 0x42, 0x40, 0x05, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x5d,
-	0x69, 0x93, 0x01, 0x00, 0xdc, 0x8f, 0x23, 0x41, 0x0d, 0x6c, 0x00, 0x00,
-	0xb9, 0x8f, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x4b, 0x99, 0x00, 0x05,
-	0x48, 0x31, 0x01, 0x00, 0xaa, 0x8a, 0x00, 0x48, 0x81, 0xb0, 0x00, 0x00,
-	0xcf, 0x8d, 0x22, 0x40, 0x8f, 0x6c, 0x00, 0x00, 0x20, 0x98, 0x00, 0x5f,
-	0x81, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xa2, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
-	0x84, 0xb0, 0x01, 0x00, 0xa6, 0x00, 0x2d, 0x49, 0x19, 0x90, 0x01, 0x00,
-	0x02, 0x00, 0x00, 0xf2, 0x80, 0xf4, 0x01, 0x00, 0xb8, 0x00, 0x2d, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x80, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x82, 0xf8, 0x01, 0x00, 0x19, 0x00, 0x00, 0x40,
-	0x81, 0x98, 0x01, 0x00, 0xed, 0x8f, 0xa0, 0x40, 0x82, 0x6c, 0x00, 0x00,
-	0x2c, 0x01, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0xed, 0x8f, 0xa3, 0x40,
-	0x82, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x80, 0xb0, 0x01, 0x00,
-	0xef, 0x8f, 0x20, 0x4c, 0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x85, 0xc0, 0x01, 0x00, 0x86, 0x00, 0x20, 0x40, 0xe4, 0xb1, 0x01, 0x00,
-	0xa2, 0x00, 0x20, 0x42, 0xe6, 0xb1, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xaf, 0x97, 0x00, 0x50, 0x81, 0x30, 0x01, 0x00,
-	0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x80, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x8d, 0xb0, 0x01, 0x00, 0x3d, 0x99, 0x00, 0x40,
-	0x87, 0x30, 0x01, 0x00, 0xb0, 0x00, 0x2f, 0x5c, 0x1f, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0x60, 0xf0, 0x80, 0xc0, 0x01, 0x00, 0x20, 0x98, 0x00, 0x5f,
-	0x81, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xcf, 0x8d, 0x22, 0x46,
-	0x19, 0x7c, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x01, 0x00, 0x62, 0xf2, 0x96, 0xcc, 0x01, 0x00, 0xcf, 0x8d, 0xa6, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x20, 0x98, 0x00, 0x4a, 0x81, 0x30, 0x01, 0x00,
-	0xf5, 0x97, 0x00, 0x46, 0x95, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xcf, 0x8d, 0x22, 0x49, 0x19, 0x7c, 0x00, 0x00,
-	0x86, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x62, 0xf2,
-	0x80, 0xcc, 0x01, 0x00, 0xcf, 0x8d, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x20, 0x98, 0x00, 0x4a, 0x81, 0x30, 0x01, 0x00, 0xf5, 0x97, 0x00, 0x47,
-	0x95, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x5f, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x5c,
-	0x1f, 0x90, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xba, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x62, 0xf2, 0x80, 0xc8, 0x01, 0x00,
-	0x13, 0x90, 0x90, 0x40, 0x80, 0x32, 0x00, 0x00, 0xff, 0xff, 0x62, 0x40,
-	0x81, 0x98, 0x01, 0x00, 0xa4, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0xcf, 0x8d, 0x22, 0x40, 0xe5, 0x6d, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x41,
-	0xe5, 0xc1, 0x00, 0x00, 0xaf, 0x97, 0x00, 0x4d, 0x81, 0x30, 0x01, 0x00,
-	0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x96, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0xe0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x8d, 0xb0, 0x01, 0x00, 0x3d, 0x99, 0x00, 0x40,
-	0x87, 0x30, 0x01, 0x00, 0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x23, 0x90, 0x80, 0xf3, 0x96, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xe7, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x19, 0x90, 0x01, 0x00,
-	0xcf, 0x8d, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x34, 0x00, 0x00, 0x40,
-	0x45, 0x99, 0x01, 0x00, 0x01, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x00, 0x11, 0x00, 0x40, 0xe5, 0x99, 0x01, 0x00, 0xc7, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x38, 0x90, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
-	0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
-	0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x63, 0x51, 0x83, 0xd0, 0x01, 0x00,
-	0x34, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3,
-	0x84, 0xcc, 0x01, 0x00, 0x30, 0x90, 0x9f, 0x42, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x63, 0x42, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x03, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00,
-	0x32, 0x90, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b,
-	0x62, 0xb1, 0x01, 0x00, 0x33, 0x90, 0xa8, 0x4b, 0x19, 0x10, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x62, 0xb1, 0x01, 0x00, 0x35, 0x90, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xff, 0x89, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0,
-	0x94, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x2d, 0xf0, 0x30, 0xb0, 0x01, 0x00,
-	0x35, 0x00, 0x2d, 0xf0, 0x28, 0xb0, 0x01, 0x00, 0x58, 0x00, 0x3e, 0x43,
-	0xe7, 0xe1, 0x01, 0x00, 0x01, 0x00, 0x00, 0x18, 0xf0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4a, 0xe0, 0xb1, 0x01, 0x00, 0x38, 0x00, 0x20, 0x00,
-	0xe0, 0xb1, 0x01, 0x00, 0x3c, 0x00, 0x20, 0x1b, 0xe0, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x2b, 0xb0, 0x01, 0x00, 0x04, 0x98, 0x00, 0x40, 0x0d, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x18, 0x16, 0xc0, 0x01, 0x00, 0x47, 0x90, 0xa0, 0x14,
-	0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
-	0x0e, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
-	0xf8, 0xb1, 0x01, 0x00, 0xb0, 0x00, 0x2d, 0x14, 0xf8, 0xb1, 0x01, 0x00,
-	0x10, 0x50, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0x50, 0x90, 0x22, 0x4a,
-	0x19, 0x7c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x43, 0x86, 0xc8, 0x01, 0x00,
-	0x00, 0x30, 0x00, 0x0b, 0x16, 0xc8, 0x01, 0x00, 0x50, 0x90, 0xa4, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
-	0x01, 0x00, 0x6e, 0x43, 0x86, 0x98, 0x01, 0x00, 0x3b, 0x98, 0x00, 0x30,
-	0x81, 0x30, 0x01, 0x00, 0x54, 0x90, 0xa0, 0x41, 0x17, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x5b, 0x90, 0x22, 0x4a,
-	0x19, 0x7c, 0x00, 0x00, 0x08, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00,
-	0xcc, 0x00, 0x2d, 0xab, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab,
-	0x17, 0xc0, 0x01, 0x00, 0x5a, 0x90, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x64, 0xf0,
-	0x82, 0xb0, 0x01, 0x00, 0x90, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x60, 0x41, 0x31, 0xc0, 0x01, 0x00, 0xbc, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x61, 0x90, 0x06, 0x0c, 0x80, 0x32, 0x00, 0x00,
-	0xa0, 0x00, 0x20, 0xf2, 0xe4, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x09, 0x46,
-	0x19, 0x10, 0x00, 0x00, 0x9c, 0x01, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
-	0xff, 0xff, 0x00, 0x0b, 0x98, 0x88, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0x50,
-	0x17, 0xf0, 0x01, 0x00, 0x66, 0x90, 0x90, 0x4c, 0x16, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x68, 0x90, 0x22, 0x43,
-	0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00,
-	0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00, 0x68, 0x01, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x5c, 0x01, 0x2e, 0xf2, 0x80, 0xb0, 0x01, 0x00,
-	0x3e, 0x00, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00, 0x6f, 0x90, 0x24, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x81, 0xc0, 0x01, 0x00,
-	0x70, 0x90, 0x00, 0x94, 0xe5, 0xb1, 0x00, 0x00, 0x02, 0x00, 0x62, 0x40,
-	0x7e, 0xcd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57, 0x81, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00, 0x03, 0x00, 0x00, 0x40,
-	0xf0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00,
-	0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
-	0x76, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x80, 0x90, 0x22, 0x40, 0xaf, 0x6f, 0x00, 0x00, 0x00, 0x40, 0x00, 0x08,
-	0x94, 0xdc, 0x01, 0x00, 0x72, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x7b, 0x90, 0xa2, 0x40, 0x97, 0x6c, 0x00, 0x00, 0x35, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x84, 0x90, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
-	0x80, 0x90, 0x43, 0x48, 0x61, 0x31, 0x00, 0x00, 0x00, 0x50, 0x00, 0x08,
-	0x62, 0xdd, 0x01, 0x00, 0x81, 0x90, 0xa8, 0x40, 0x05, 0x30, 0x00, 0x00,
-	0x35, 0x00, 0x1b, 0x40, 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3,
-	0x84, 0xc8, 0x01, 0x00, 0x87, 0x90, 0xa0, 0x43, 0x85, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x63, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x37, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3, 0x82, 0xcc, 0x01, 0x00,
-	0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0xe7, 0x91, 0x01, 0x00, 0x20, 0x98, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00,
-	0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x69, 0x96, 0x00, 0xf3, 0x94, 0x30, 0x01, 0x00,
-	0x27, 0x90, 0x22, 0x4a, 0x80, 0x32, 0x00, 0x00, 0xa5, 0x8e, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x69, 0x96, 0x00, 0xf3, 0x94, 0x30, 0x01, 0x00, 0x75, 0x8e, 0x22, 0x4a,
-	0x80, 0x32, 0x00, 0x00, 0xa5, 0x8e, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x36, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
-	0x12, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3, 0x90, 0x88, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0xf3, 0x0c, 0xf4, 0x01, 0x00, 0x9f, 0x8e, 0x22, 0x06,
-	0x90, 0x6c, 0x00, 0x00, 0x5c, 0x00, 0x3d, 0x43, 0x13, 0xe0, 0x01, 0x00,
-	0xa8, 0x00, 0x2d, 0xf0, 0x94, 0xb0, 0x01, 0x00, 0x37, 0x00, 0x2f, 0xf0,
-	0x24, 0xb0, 0x01, 0x00, 0x36, 0x00, 0x2a, 0x50, 0xe7, 0xd1, 0x01, 0x00,
-	0x00, 0x00, 0x63, 0x41, 0x13, 0xc0, 0x01, 0x00, 0xa1, 0x90, 0xa0, 0x43,
-	0x13, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00,
-	0xcc, 0x94, 0x00, 0x10, 0x86, 0x30, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0xa3, 0x90, 0x42, 0x05, 0x48, 0x31, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00, 0x9f, 0x8e, 0x1a, 0x5d,
-	0x69, 0x93, 0x00, 0x00, 0x36, 0x00, 0x2d, 0x10, 0x86, 0xb0, 0x01, 0x00,
-	0x5c, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0xf0,
-	0x94, 0xb0, 0x01, 0x00, 0x35, 0x00, 0x2f, 0xf0, 0x24, 0xb0, 0x01, 0x00,
-	0x01, 0x00, 0x6b, 0xfb, 0x84, 0xc8, 0x01, 0x00, 0xae, 0x90, 0xa0, 0x43,
-	0x85, 0x6c, 0x00, 0x00, 0x35, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3,
-	0x12, 0xc8, 0x01, 0x00, 0xb1, 0x90, 0xa0, 0x43, 0x13, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x40, 0x80, 0x00, 0x03,
-	0x44, 0xc9, 0x01, 0x00, 0xce, 0x94, 0x00, 0x4a, 0xf0, 0x31, 0x01, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xb4, 0x90, 0x42, 0x05,
-	0x48, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
-	0x00, 0x00, 0x1a, 0x5d, 0x69, 0x93, 0x01, 0x00, 0x37, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x11, 0x00, 0x63, 0xf3, 0x82, 0xcc, 0x01, 0x00,
-	0xa3, 0x8f, 0x22, 0x41, 0x9e, 0x06, 0x00, 0x00, 0x35, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x58, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x36, 0xb0, 0x01, 0x00, 0xad, 0x8f, 0x00, 0xf0,
-	0x00, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0xbf, 0x90, 0x47, 0xf2, 0x12, 0x30, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42,
-	0x13, 0xf0, 0x01, 0x00, 0xc4, 0x90, 0x22, 0x47, 0xe7, 0x7d, 0x00, 0x00,
-	0x6b, 0x84, 0x1f, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xbe, 0x90, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xe7, 0x91, 0x01, 0x00,
-	0x00, 0x00, 0x1f, 0x42, 0x19, 0x90, 0x01, 0x00, 0x75, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0xc6, 0x90, 0xa8, 0xb1, 0x0c, 0x30, 0x00, 0x00,
-	0x46, 0x97, 0x00, 0x10, 0x94, 0x30, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0xc0, 0xa8, 0x3d, 0x46, 0x0d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x97, 0xb0, 0x01, 0x00, 0xd0, 0x90, 0x22, 0x40, 0xe1, 0x6d, 0x00, 0x00,
-	0x04, 0x00, 0x02, 0x41, 0x97, 0x40, 0x00, 0x00, 0xcd, 0x90, 0x00, 0x50,
-	0x43, 0xc1, 0x00, 0x00, 0xdc, 0x90, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x62, 0x4b, 0x12, 0x94, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
-	0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x97, 0xc0, 0x01, 0x00,
-	0x30, 0x00, 0x00, 0x10, 0x94, 0xc8, 0x01, 0x00, 0x00, 0x80, 0x00, 0x4a,
-	0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf1, 0xb1, 0x01, 0x00,
-	0x5e, 0x01, 0x00, 0x4b, 0xf0, 0xc9, 0x01, 0x00, 0x5e, 0x01, 0x00, 0x05,
-	0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x4a, 0x62, 0xdd, 0x01, 0x00, 0xda, 0x90, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x09,
-	0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x68, 0xa8, 0x97, 0xc0, 0x01, 0x00,
-	0xd4, 0x00, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
-	0xe2, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00,
-	0xe6, 0x90, 0x47, 0x40, 0x81, 0x32, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf3,
-	0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x1f, 0x55, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
-	0x62, 0xb1, 0x01, 0x00, 0xea, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xef, 0x90, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x62, 0xb1, 0x01, 0x00, 0xed, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x97, 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x96,
-	0x97, 0xb0, 0x01, 0x00, 0xf5, 0x90, 0x20, 0x09, 0x96, 0x6c, 0x00, 0x00,
-	0xf5, 0x90, 0x1f, 0x09, 0x96, 0x24, 0x00, 0x00, 0x6b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0xf0, 0x90, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xaf, 0x97, 0x00, 0x57, 0x81, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x05,
-	0x48, 0xb1, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0xfb, 0x90, 0x22, 0xf3, 0x80, 0x32, 0x00, 0x00, 0xaf, 0x97, 0x00, 0x42,
-	0x81, 0x30, 0x01, 0x00, 0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x20, 0x98, 0x00, 0x52, 0x81, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x42,
-	0x19, 0x80, 0x00, 0x00, 0xaf, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00,
-	0x20, 0x98, 0x00, 0x52, 0x81, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
-	0xc9, 0x96, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x22, 0x40,
-	0x95, 0x6c, 0x00, 0x00, 0x06, 0x91, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00,
-	0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xff, 0x89, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x74, 0x96, 0x00, 0x52,
-	0x95, 0x30, 0x01, 0x00, 0x7b, 0x96, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
-	0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xf4, 0x98, 0x00, 0x40,
-	0x95, 0x30, 0x01, 0x00, 0x11, 0x91, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
-	0xff, 0x89, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x19, 0x90, 0x01, 0x00, 0xaf, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00,
-	0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x23, 0x00, 0xa6,
-	0x16, 0xb0, 0x01, 0x00, 0x14, 0x91, 0x83, 0x1e, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x08, 0x00, 0x0b, 0x16, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x2a, 0xc0, 0x01, 0x00, 0xf8, 0x97, 0x00, 0x08, 0x80, 0x30, 0x01, 0x00,
-	0x18, 0x91, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00, 0x19, 0x98, 0x00, 0x43,
-	0x61, 0x31, 0x01, 0x00, 0xda, 0x94, 0x00, 0x40, 0x8d, 0x30, 0x01, 0x00,
-	0x00, 0x98, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0x20, 0x91, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x1d, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xa1, 0x97, 0x00, 0x5e,
-	0x05, 0x10, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x24, 0x91, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40,
-	0x13, 0x30, 0x01, 0x00, 0xbf, 0x8d, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
-	0xf9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x1f, 0x90, 0x01, 0x00,
-	0x2b, 0x91, 0x22, 0x43, 0x3d, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x19, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x3d, 0x80, 0x01, 0x00,
-	0x2c, 0x91, 0x00, 0x42, 0x19, 0x90, 0x00, 0x00, 0x14, 0x00, 0x2d, 0x45,
-	0x1f, 0x90, 0x01, 0x00, 0x87, 0x91, 0x83, 0x1e, 0x80, 0x32, 0x00, 0x00,
-	0x87, 0x91, 0x00, 0x44, 0x19, 0x90, 0x00, 0x00, 0xbf, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x3f, 0x91, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
-	0x3b, 0x91, 0xa2, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02,
-	0x04, 0xdc, 0x01, 0x00, 0xa0, 0x98, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0xe3, 0x89, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00, 0x38, 0x91, 0xa2, 0x41,
-	0x19, 0x7c, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x74, 0x96, 0x00, 0x15,
-	0x94, 0x30, 0x01, 0x00, 0x7b, 0x96, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
-	0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xf9, 0x96, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x19, 0x90, 0x01, 0x00,
-	0xaf, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00, 0xff, 0x89, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x42, 0x91, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
-	0xf9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x43, 0x91, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xc9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x6f, 0x91, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x15,
-	0x98, 0xc8, 0x01, 0x00, 0x6f, 0x91, 0xa0, 0x0b, 0x99, 0x6c, 0x00, 0x00,
-	0x30, 0x00, 0x00, 0x10, 0x80, 0xc8, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40,
-	0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x62, 0xb1, 0x01, 0x00,
-	0x4b, 0x91, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0xc0, 0x00, 0x00, 0x15, 0x98, 0xc8, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x0b,
-	0x99, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x6a, 0x50, 0x99, 0xc0, 0x01, 0x00,
-	0xc0, 0x00, 0x62, 0x01, 0x80, 0xcc, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x2d, 0x00, 0x2d, 0xf0, 0x22, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0x80, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
-	0x23, 0x80, 0x01, 0x00, 0xd4, 0x00, 0x3f, 0x41, 0xe7, 0xe1, 0x01, 0x00,
-	0x0b, 0x00, 0x00, 0x11, 0xe4, 0xf5, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x47,
-	0xe7, 0xb5, 0x01, 0x00, 0x5c, 0x91, 0x23, 0x0b, 0x81, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4f, 0xe5, 0x91, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
-	0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x03, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x15, 0x02, 0xd0, 0x01, 0x00, 0xf8, 0x97, 0x00, 0x00,
-	0x2a, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x61, 0x91, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0xcc, 0x95, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x01,
-	0x80, 0xce, 0x01, 0x00, 0x6d, 0x91, 0x26, 0x11, 0x00, 0x30, 0x00, 0x00,
-	0x10, 0x00, 0x00, 0x00, 0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
-	0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0xc0, 0x01, 0x00,
-	0xc0, 0x00, 0x00, 0x40, 0x99, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
-	0x98, 0xd0, 0x01, 0x00, 0xf8, 0x97, 0x00, 0x4c, 0x02, 0x30, 0x01, 0x00,
-	0xc0, 0x00, 0x00, 0x40, 0x03, 0x98, 0x01, 0x00, 0x74, 0x91, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x30, 0x00, 0x2f, 0x08, 0x80, 0xb0, 0x01, 0x00,
-	0xc0, 0x00, 0x00, 0x15, 0xf4, 0xc9, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x01,
-	0xe4, 0xcd, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40, 0x03, 0x98, 0x01, 0x00,
-	0xf8, 0x97, 0x00, 0x00, 0x2a, 0x40, 0x01, 0x00, 0x79, 0x91, 0x22, 0x44,
-	0x1f, 0x7c, 0x00, 0x00, 0xac, 0x00, 0x2f, 0x40, 0x13, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0xe0, 0xc1, 0x01, 0x00, 0xb0, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x7a, 0x91, 0x00, 0x01, 0xe0, 0xd1, 0x00, 0x00,
-	0xda, 0x94, 0x00, 0x40, 0x8d, 0x30, 0x01, 0x00, 0x80, 0x63, 0x00, 0xa6,
-	0x16, 0xb0, 0x01, 0x00, 0x00, 0x98, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x82, 0x91, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x7f, 0x91, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0xa1, 0x97, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0x85, 0x91, 0x22, 0x09,
-	0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xba, 0x8d, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x87, 0x91, 0x00, 0x4a,
-	0x1f, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xb0, 0x01, 0x00,
-	0x24, 0x00, 0x2d, 0x15, 0x10, 0xc0, 0x01, 0x00, 0x28, 0x00, 0x2d, 0xf0,
-	0x16, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00,
-	0x14, 0x00, 0x2f, 0xf2, 0x0c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
-	0xe0, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x15,
-	0x1a, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0x2a, 0xb0, 0x01, 0x00, 0x5b, 0x97, 0x00, 0x40,
-	0x35, 0xb0, 0x00, 0x00, 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
-	0xcb, 0x91, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00, 0x24, 0x00, 0x20, 0x0b,
-	0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00,
-	0x22, 0x00, 0x20, 0x06, 0xe4, 0xb1, 0x01, 0x00, 0xa1, 0x91, 0x22, 0x5c,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00,
-	0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0xa1, 0x91, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x9d, 0x91, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19,
-	0x42, 0xc9, 0x01, 0x00, 0xc4, 0x91, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0xb2, 0x91, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x21, 0x97, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x74, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xbf, 0x91, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0xa8, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0xae, 0x91, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0xe2, 0x95, 0x00, 0x40, 0x11, 0x30, 0x01, 0x00, 0xaf, 0x91, 0x00, 0x05,
-	0x48, 0xb1, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xb1, 0x91, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x6f, 0x84, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
-	0x21, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x70, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xb5, 0x91, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0xbb, 0x91, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xe2, 0x95, 0x00, 0x40,
-	0x11, 0x30, 0x01, 0x00, 0xbc, 0x91, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
-	0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xbe, 0x91, 0x22, 0x09,
-	0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x6f, 0x84, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0xc0, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0xc7, 0x91, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xe2, 0x95, 0x00, 0x40,
-	0x11, 0x30, 0x01, 0x00, 0xc8, 0x91, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
-	0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xca, 0x91, 0x22, 0x09,
-	0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
-	0xbf, 0x8d, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19,
-	0x42, 0xc9, 0x01, 0x00, 0xd2, 0x91, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0xce, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
-	0xd6, 0x91, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xe2, 0x95, 0x00, 0x40,
-	0x11, 0x30, 0x01, 0x00, 0xd7, 0x91, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
-	0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x08, 0x00, 0x2d, 0x0a,
-	0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x82, 0xb0, 0x01, 0x00,
-	0x14, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0xdc, 0x91, 0x03, 0x1e,
-	0x80, 0x32, 0x00, 0x00, 0xdd, 0x91, 0x00, 0x41, 0x87, 0xb0, 0x00, 0x00,
-	0x21, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0xea, 0x96, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
-	0xe1, 0x91, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40,
-	0x13, 0x30, 0x01, 0x00, 0xe4, 0x91, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00,
-	0x20, 0x98, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x19, 0x80, 0x01, 0x00, 0xba, 0x8d, 0xa2, 0x4a, 0x1f, 0x7c, 0x00, 0x00,
-	0xbf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xba, 0x00, 0x20, 0x40,
-	0xe5, 0xb1, 0x01, 0x00, 0xea, 0x91, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00,
-	0xcc, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xfb, 0x98, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x8d, 0x98, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
-	0xc0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xc4, 0x00, 0x2d, 0xf0,
-	0x82, 0xb0, 0x01, 0x00, 0xd8, 0x98, 0x00, 0xf0, 0x84, 0x30, 0x01, 0x00,
-	0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xbf, 0x8d, 0x22, 0x09,
-	0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
-	0xbf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0xf6, 0x91, 0x22, 0x40, 0xe7, 0x6d, 0x00, 0x00,
-	0x32, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xfe, 0x91, 0xa2, 0x40,
-	0xe5, 0x6d, 0x00, 0x00, 0xb6, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x24, 0x00, 0x20, 0x0b, 0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x20, 0x13,
-	0xe0, 0xb1, 0x01, 0x00, 0x22, 0x00, 0x20, 0x06, 0xe4, 0xb1, 0x01, 0x00,
-	0x14, 0x00, 0x20, 0x0a, 0xe0, 0xb1, 0x01, 0x00, 0xbf, 0x8d, 0x22, 0x09,
-	0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
-	0xbf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb6, 0x96, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x6f, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x0c, 0x92, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
-	0x99, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x15, 0x98, 0x50, 0x00, 0x00,
-	0x0c, 0x92, 0x20, 0x01, 0x98, 0x6c, 0x00, 0x00, 0x70, 0x00, 0x00, 0x03,
-	0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x46, 0x1f, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
-	0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0x09, 0x92, 0xa8, 0x00,
-	0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0xac, 0x00, 0x2f, 0x00, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
-	0xe0, 0xc1, 0x01, 0x00, 0x14, 0x00, 0x2f, 0x15, 0x10, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0a, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0x01,
-	0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x19, 0x90, 0x01, 0x00,
-	0x8e, 0x91, 0x22, 0x09, 0x80, 0x32, 0x00, 0x00, 0x20, 0x98, 0x00, 0x09,
-	0x80, 0x30, 0x01, 0x00, 0x8e, 0x91, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x82, 0xb0, 0x01, 0x00, 0x13, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0x43, 0xc1, 0x01, 0x00, 0xea, 0x96, 0x00, 0xf0,
-	0x84, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00,
-	0x2c, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x2d, 0x00, 0x20, 0x40,
-	0xe7, 0xb1, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x42, 0x19, 0x80, 0x00, 0x00,
-	0xdc, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xf5, 0x97, 0x00, 0x48,
-	0x95, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x21, 0x92, 0xa8, 0x40,
-	0x13, 0x30, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x27, 0x92, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x26, 0x92, 0x00, 0x40,
-	0x13, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xb0, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x14, 0x00, 0x2d, 0xf0,
-	0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x84, 0x30, 0x00, 0x00,
-	0x13, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0xea, 0x96, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
-	0x3f, 0x92, 0x00, 0x09, 0x00, 0xb0, 0x00, 0x00, 0xba, 0x8d, 0x87, 0x42,
-	0x19, 0x10, 0x00, 0x00, 0x8b, 0x00, 0x2f, 0x47, 0x19, 0x80, 0x01, 0x00,
-	0xba, 0x8d, 0x00, 0x40, 0xe7, 0x91, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x3d, 0x92, 0x22, 0x47, 0xe7, 0x7d, 0x00, 0x00,
-	0x51, 0x95, 0x00, 0x40, 0xe7, 0x31, 0x01, 0x00, 0x3d, 0x92, 0x22, 0x00,
-	0x80, 0x32, 0x00, 0x00, 0x38, 0x92, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00,
-	0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x3d, 0x92, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x32, 0x00, 0x2d, 0xf2, 0x94, 0xb0, 0x01, 0x00, 0x74, 0x96, 0x00, 0xf2,
-	0x02, 0x30, 0x01, 0x00, 0x7b, 0x96, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x3e, 0x92, 0x00, 0x40,
-	0x01, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
-	0x44, 0x92, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0x43, 0x92, 0xa2, 0x42,
-	0x19, 0x7c, 0x00, 0x00, 0xc9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x44, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xf9, 0x96, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xce, 0x92, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0x4c, 0x92, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x49, 0x92, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xce, 0x92, 0x00, 0x05,
-	0x48, 0xb1, 0x00, 0x00, 0xbf, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x52, 0x92, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0xaf, 0x97, 0x00, 0x4d,
-	0x81, 0x30, 0x01, 0x00, 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00,
-	0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x74, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x96, 0xb0, 0x01, 0x00, 0x60, 0x92, 0x22, 0x42, 0x96, 0x14, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x64, 0x00, 0x68, 0x40,
-	0x97, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00, 0x70, 0x00, 0x00, 0x05,
-	0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x5d, 0x92, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x61, 0x92, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2d, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x65, 0x92, 0x47, 0xf2, 0x12, 0x30, 0x00, 0x00,
-	0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00, 0x6a, 0x92, 0x22, 0x47,
-	0xe7, 0x7d, 0x00, 0x00, 0x6b, 0x84, 0x1f, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x64, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0xe7, 0x91, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x09, 0x96, 0xe4, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x68, 0xa8, 0x97, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
-	0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x72, 0x92, 0xa8, 0x40,
-	0xe1, 0x31, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00, 0x76, 0x92, 0x47, 0x05,
-	0x48, 0x31, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf3, 0x96, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x7e, 0x92, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x55, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x62, 0xb1, 0x01, 0x00, 0x7c, 0x92, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x07, 0x16, 0xb0, 0x01, 0x00, 0x00, 0x62, 0x00, 0x0b,
-	0x16, 0xdc, 0x01, 0x00, 0x51, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x96, 0x92, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0xff, 0x96, 0x00, 0x5f,
-	0x01, 0x10, 0x01, 0x00, 0x80, 0x92, 0x22, 0x40, 0x95, 0x6c, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x62, 0xb1, 0x01, 0x00, 0x88, 0x92, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x74, 0x96, 0x00, 0x52,
-	0x95, 0x30, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x80, 0x92, 0x22, 0x41, 0x97, 0x50, 0x00, 0x00, 0x0c, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5c, 0x01, 0x80, 0x01, 0x00, 0x7b, 0x96, 0x00, 0x4b,
-	0x02, 0xb0, 0x00, 0x00, 0x80, 0x92, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
-	0x00, 0x98, 0x00, 0x40, 0x03, 0x30, 0x01, 0x00, 0x17, 0x80, 0x00, 0x03,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x0c, 0x96, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0x63, 0x4c, 0x97, 0xf0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x03,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab, 0xe1, 0xb1, 0x01, 0x00,
-	0xa1, 0x97, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07,
-	0x1a, 0xf4, 0x01, 0x00, 0x07, 0x00, 0x00, 0x07, 0x16, 0x88, 0x01, 0x00,
-	0x00, 0xb5, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00, 0xa0, 0x92, 0x30, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x81, 0x01, 0x00,
-	0x00, 0xb7, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b,
-	0xe6, 0x81, 0x01, 0x00, 0x10, 0x00, 0x10, 0x0f, 0x94, 0xf4, 0x01, 0x00,
-	0xd1, 0x99, 0x00, 0x5f, 0x95, 0x04, 0x01, 0x00, 0x55, 0x96, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xaa, 0x92, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00,
-	0xa8, 0x92, 0x43, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x41,
-	0x31, 0xd3, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x0f, 0xb0, 0x01, 0x00, 0xb8, 0x95, 0x00, 0x41, 0x81, 0x30, 0x01, 0x00,
-	0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xbf, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xbb, 0x92, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x03, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00,
-	0xb4, 0x92, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b,
-	0x62, 0xb1, 0x01, 0x00, 0xb8, 0x92, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xb5, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x62, 0xb1, 0x01, 0x00, 0xb8, 0x92, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xff, 0x89, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x74, 0x00, 0x22, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00,
-	0xf5, 0x97, 0x00, 0x4a, 0x95, 0x30, 0x01, 0x00, 0xdc, 0x96, 0x00, 0x5c,
-	0x1f, 0x10, 0x01, 0x00, 0x52, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x2f, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xcc, 0x92, 0x22, 0x47,
-	0xe7, 0x7d, 0x00, 0x00, 0x51, 0x95, 0x00, 0x40, 0xe7, 0x31, 0x01, 0x00,
-	0xcc, 0x92, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0xc7, 0x92, 0xa2, 0x40,
-	0x1f, 0x7c, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xcc, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x32, 0x00, 0x2d, 0xf2, 0x94, 0xb0, 0x01, 0x00,
-	0x74, 0x96, 0x00, 0xf2, 0x02, 0x30, 0x01, 0x00, 0x7b, 0x96, 0x00, 0x4b,
-	0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0xf5, 0x97, 0x00, 0x48, 0x95, 0x30, 0x01, 0x00, 0xdc, 0x96, 0x00, 0x5c,
-	0x1f, 0x10, 0x01, 0x00, 0xd1, 0x92, 0x87, 0x42, 0x19, 0x10, 0x00, 0x00,
-	0x8b, 0x00, 0x2f, 0x47, 0x19, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xe7, 0x91, 0x01, 0x00, 0x20, 0x98, 0x00, 0x42, 0x81, 0x30, 0x01, 0x00,
-	0xba, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xdc, 0x96, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00,
-	0xba, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00, 0x8d, 0x98, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0xc4, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0xd8, 0x98, 0x00, 0xf0,
-	0x84, 0x30, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x20, 0x98, 0x00, 0x45, 0x81, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x22, 0x42,
-	0x19, 0x7c, 0x00, 0x00, 0xaf, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00,
-	0xba, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xbf, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xe5, 0x92, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0xaf, 0x97, 0x00, 0x47,
-	0x80, 0x30, 0x01, 0x00, 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00,
-	0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x10, 0x80, 0x00, 0x03,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0xe1, 0x00, 0xa6, 0x84, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x07, 0x84, 0x94, 0x01, 0x00,
-	0xa1, 0x97, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0xcc, 0x95, 0x00, 0x41, 0xe7, 0x41, 0x01, 0x00, 0xbf, 0x8d, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xb6, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x6f, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
-	0x2c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x0a,
-	0x2c, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
-	0x07, 0x00, 0x00, 0x0b, 0x96, 0x88, 0x01, 0x00, 0x01, 0x93, 0x26, 0x47,
-	0x97, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x97, 0xc0, 0x01, 0x00,
-	0x01, 0x93, 0x23, 0x4b, 0x0c, 0x6c, 0x00, 0x00, 0x33, 0x98, 0x00, 0x4b,
-	0x04, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
-	0x16, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x04, 0xb0, 0x01, 0x00,
-	0x33, 0x98, 0x00, 0x4b, 0x04, 0x50, 0x01, 0x00, 0x02, 0x93, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x33, 0x98, 0x00, 0x06, 0x04, 0x30, 0x01, 0x00,
-	0x08, 0x93, 0xa2, 0x48, 0x1f, 0x7c, 0x00, 0x00, 0x06, 0x93, 0x84, 0x48,
-	0x1f, 0x10, 0x00, 0x00, 0xac, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x08, 0x93, 0x00, 0x0a, 0xe0, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
-	0x02, 0xb0, 0x01, 0x00, 0xda, 0x94, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x09, 0x93, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00,
-	0x16, 0x93, 0x22, 0x06, 0x14, 0x50, 0x00, 0x00, 0x24, 0x97, 0x00, 0x45,
-	0x1f, 0x00, 0x01, 0x00, 0xf5, 0x92, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x12, 0x93, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xf5, 0x92, 0x00, 0x05,
-	0x48, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00,
-	0x08, 0x00, 0x2d, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
-	0xea, 0x96, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x1c, 0x93, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x22, 0x93, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40,
-	0x13, 0x30, 0x01, 0x00, 0x26, 0x93, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00,
-	0x20, 0x98, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00, 0x26, 0x93, 0xa2, 0x47,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x19, 0x80, 0x01, 0x00,
-	0xff, 0x07, 0x00, 0x08, 0x00, 0x8c, 0x01, 0x00, 0x34, 0x93, 0x22, 0x4a,
-	0x1f, 0x7c, 0x00, 0x00, 0x2c, 0x93, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00,
-	0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
-	0xe7, 0xb1, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0x30, 0x93, 0x22, 0x42,
-	0x19, 0x7c, 0x00, 0x00, 0xf9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x31, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc9, 0x96, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x2a, 0xd0, 0x01, 0x00,
-	0x32, 0x00, 0x2a, 0x15, 0xe4, 0xb1, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x16,
-	0xe4, 0xb1, 0x00, 0x00, 0x46, 0x93, 0x22, 0x16, 0x02, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0xf4, 0x98, 0x00, 0x40,
-	0x95, 0x30, 0x01, 0x00, 0x47, 0x93, 0x22, 0x40, 0x11, 0x6c, 0x00, 0x00,
-	0xac, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xb0, 0x00, 0x2b, 0x01,
-	0xe0, 0xc1, 0x01, 0x00, 0x00, 0x2b, 0x00, 0xa6, 0x16, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0xe0, 0xd1, 0x01, 0x00, 0xf8, 0x97, 0x00, 0x08,
-	0x80, 0x30, 0x01, 0x00, 0x3f, 0x93, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00,
-	0x19, 0x98, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x40, 0x93, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x98, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00, 0xa1, 0x97, 0x00, 0x5e,
-	0x05, 0x10, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xbf, 0x8d, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0x1f, 0x15, 0x1a, 0x50, 0x00, 0x00, 0x54, 0x93, 0x20, 0x16,
-	0x1a, 0x6c, 0x00, 0x00, 0x70, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x22, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
-	0x62, 0xdd, 0x01, 0x00, 0x51, 0x93, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0a, 0x2a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a,
-	0x2c, 0xd0, 0x01, 0x00, 0xac, 0x00, 0x2f, 0x40, 0x23, 0xb0, 0x01, 0x00,
-	0x5b, 0x93, 0x84, 0x45, 0x1f, 0x10, 0x00, 0x00, 0x5c, 0x93, 0x00, 0x0a,
-	0xe0, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x02, 0xb0, 0x01, 0x00,
-	0x5b, 0x97, 0x00, 0x40, 0x35, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19,
-	0x42, 0xc9, 0x01, 0x00, 0x64, 0x93, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x60, 0x93, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x73, 0x93, 0xa2, 0x02, 0x1a, 0x50, 0x00, 0x00,
-	0x74, 0x93, 0x22, 0x40, 0x2d, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08,
-	0xe0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x6b, 0x93, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf0, 0x10, 0xc8, 0x01, 0x00,
-	0xf0, 0x07, 0x00, 0x40, 0x1b, 0x98, 0x01, 0x00, 0x74, 0x93, 0x00, 0x5c,
-	0x11, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00,
-	0xe2, 0x95, 0x00, 0x40, 0x1f, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x78, 0x93, 0x23, 0x0d, 0x2c, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x1f, 0x90, 0x01, 0x00, 0x80, 0x93, 0x22, 0x46,
-	0x1f, 0x7c, 0x00, 0x00, 0x70, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x80, 0x93, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x7c, 0x93, 0xa8, 0x46, 0x1f, 0x00, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x08, 0x00, 0x2d, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
-	0xea, 0x96, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x85, 0x93, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x8b, 0x93, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40,
-	0x13, 0x30, 0x01, 0x00, 0x8f, 0x93, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00,
-	0x20, 0x98, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00, 0x8f, 0x93, 0xa2, 0x47,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x19, 0x80, 0x01, 0x00,
-	0xff, 0x07, 0x00, 0x08, 0x00, 0x8c, 0x01, 0x00, 0xa4, 0x93, 0x22, 0x4a,
-	0x1f, 0x7c, 0x00, 0x00, 0x95, 0x93, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00,
-	0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
-	0xe7, 0xb1, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0xa0, 0x93, 0x22, 0x42,
-	0x19, 0x7c, 0x00, 0x00, 0x99, 0x93, 0xa2, 0xf3, 0x84, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xa5, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x85, 0xd0, 0x01, 0x00, 0xd4, 0x00, 0x3e, 0x41, 0x85, 0xe0, 0x01, 0x00,
-	0x9d, 0x93, 0x22, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a,
-	0x11, 0x90, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x08, 0xe4, 0xf5, 0x01, 0x00,
-	0xf9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xa1, 0x93, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xc9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x30, 0x00, 0x2e, 0x00, 0x2a, 0xd0, 0x01, 0x00, 0x32, 0x00, 0x2a, 0x15,
-	0xe4, 0xb1, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x16, 0xe4, 0xb1, 0x00, 0x00,
-	0xa7, 0x93, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xf4, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0xb4, 0x93, 0x22, 0x47,
-	0x1f, 0x7c, 0x00, 0x00, 0xb1, 0x93, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
-	0xac, 0x93, 0xa2, 0xf3, 0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5,
-	0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x85, 0xd0, 0x01, 0x00,
-	0xd4, 0x00, 0x3e, 0x41, 0x85, 0xe0, 0x01, 0x00, 0xb0, 0x93, 0x22, 0x40,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x11, 0x90, 0x01, 0x00,
-	0x0b, 0x00, 0x00, 0x08, 0xe4, 0xf5, 0x01, 0x00, 0x58, 0x01, 0x2d, 0x00,
-	0x2a, 0xd0, 0x01, 0x00, 0x60, 0x01, 0x2d, 0xf0, 0x10, 0xb0, 0x01, 0x00,
-	0x3f, 0x91, 0x00, 0xf0, 0x2c, 0xb0, 0x00, 0x00, 0xf4, 0x98, 0x00, 0x41,
-	0x95, 0x30, 0x01, 0x00, 0xbb, 0x93, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x97, 0xb0, 0x01, 0x00, 0xb9, 0x93, 0x23, 0x0d,
-	0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x97, 0xc0, 0x01, 0x00,
-	0x7b, 0x96, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0xf4, 0x93, 0x00, 0x05,
-	0x48, 0xb1, 0x00, 0x00, 0xac, 0x00, 0x2f, 0x01, 0x14, 0xb0, 0x01, 0x00,
-	0xb0, 0x00, 0x2b, 0x01, 0xe0, 0xc1, 0x01, 0x00, 0x00, 0x2b, 0x00, 0xa6,
-	0x16, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0xd1, 0x01, 0x00,
-	0xcb, 0x93, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
-	0xc4, 0x93, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf0,
-	0x22, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x23, 0x80, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0x84, 0xb0, 0x01, 0x00, 0xce, 0x93, 0x23, 0x0d,
-	0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x02, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x08, 0x80, 0xb0, 0x01, 0x00, 0xd3, 0x93, 0x22, 0x40,
-	0x1b, 0x6c, 0x00, 0x00, 0xf8, 0x97, 0x00, 0x01, 0x84, 0x50, 0x01, 0x00,
-	0xdb, 0x93, 0x22, 0x40, 0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-	0x80, 0xc0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x10, 0x46, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4f, 0x43, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0xf0, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x40, 0xf0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa1, 0x62, 0xdd, 0x01, 0x00,
-	0xd9, 0x93, 0xa8, 0x11, 0xe0, 0x31, 0x00, 0x00, 0xea, 0x93, 0x00, 0x5e,
-	0x17, 0x90, 0x00, 0x00, 0xde, 0x93, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x0d, 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
-	0x84, 0xd0, 0x01, 0x00, 0xe3, 0x93, 0x22, 0x40, 0x1b, 0x6c, 0x00, 0x00,
-	0x19, 0x98, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00, 0xea, 0x93, 0x22, 0x40,
-	0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x12, 0xc0, 0x01, 0x00,
-	0x10, 0x80, 0x00, 0x10, 0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f,
-	0x43, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
-	0xf0, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa1, 0x62, 0xdd, 0x01, 0x00,
-	0xe8, 0x93, 0xa8, 0x11, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0xeb, 0x93, 0xa8, 0x0a, 0x02, 0x30, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00,
-	0xf2, 0x93, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00, 0xff, 0x07, 0x00, 0x11,
-	0x00, 0x8c, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x98, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00, 0xa1, 0x97, 0x00, 0x5e,
-	0x05, 0x10, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
-	0xbf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x8e, 0xb0, 0x01, 0x00, 0xb3, 0x96, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00, 0xea, 0x96, 0x00, 0x41,
-	0x87, 0x30, 0x01, 0x00, 0x6f, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x05, 0x94, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x01, 0x94, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x07, 0x94, 0x22, 0x09,
-	0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15,
-	0x1a, 0xd0, 0x01, 0x00, 0x0d, 0x94, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0xf4, 0x98, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00, 0x15, 0x94, 0x22, 0x08,
-	0x80, 0x32, 0x00, 0x00, 0x38, 0x93, 0x00, 0x00, 0x2a, 0xc0, 0x00, 0x00,
-	0xf4, 0x98, 0x00, 0x41, 0x95, 0x30, 0x01, 0x00, 0x10, 0x94, 0x22, 0x08,
-	0x80, 0x32, 0x00, 0x00, 0xbb, 0x93, 0x00, 0x00, 0x2a, 0xc0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x97, 0xb0, 0x01, 0x00, 0x13, 0x94, 0x23, 0x0d,
-	0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x97, 0xc0, 0x01, 0x00,
-	0x7b, 0x96, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0xba, 0x8d, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
-	0xaf, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x19, 0x94, 0x00, 0x4a, 0x1f, 0x90, 0x00, 0x00,
-	0xf4, 0x95, 0x00, 0x00, 0x10, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15,
-	0x10, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
-	0x07, 0x00, 0x00, 0x0b, 0x96, 0x88, 0x01, 0x00, 0x27, 0x94, 0x26, 0x47,
-	0x97, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x97, 0xc0, 0x01, 0x00,
-	0x27, 0x94, 0x23, 0x4b, 0x0c, 0x6c, 0x00, 0x00, 0x33, 0x98, 0x00, 0x4b,
-	0x04, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
-	0x16, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x04, 0xb0, 0x01, 0x00,
-	0x33, 0x98, 0x00, 0x4b, 0x04, 0x50, 0x01, 0x00, 0x28, 0x94, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x33, 0x98, 0x00, 0x06, 0x04, 0x30, 0x01, 0x00,
-	0x2d, 0x94, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
-	0x1b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x2c, 0xd0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0a, 0x02, 0xb0, 0x01, 0x00, 0xda, 0x94, 0x00, 0x01,
-	0x8c, 0x30, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00,
-	0x34, 0x94, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x30, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00, 0x3d, 0x94, 0x22, 0x06,
-	0x14, 0x50, 0x00, 0x00, 0x24, 0x97, 0x00, 0x45, 0x1f, 0x00, 0x01, 0x00,
-	0x1b, 0x94, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x39, 0x94, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x1b, 0x94, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
-	0x08, 0x00, 0x2d, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
-	0xea, 0x96, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x42, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x48, 0x94, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40,
-	0x13, 0x30, 0x01, 0x00, 0x4b, 0x94, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00,
-	0x20, 0x98, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x19, 0x80, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08, 0x00, 0x8c, 0x01, 0x00,
-	0x59, 0x94, 0x22, 0x4a, 0x1f, 0x7c, 0x00, 0x00, 0x51, 0x94, 0xa2, 0x16,
-	0x02, 0x30, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00,
-	0x55, 0x94, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0xf9, 0x96, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x56, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xc9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x00,
-	0x2a, 0xd0, 0x01, 0x00, 0x32, 0x00, 0x2a, 0x15, 0xe4, 0xb1, 0x01, 0x00,
-	0xba, 0x8d, 0x00, 0x16, 0xe4, 0xb1, 0x00, 0x00, 0x35, 0x93, 0xa2, 0x16,
-	0x02, 0x30, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xbf, 0x8d, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xf4, 0x95, 0x00, 0x4a, 0x1f, 0x10, 0x01, 0x00,
-	0x49, 0x93, 0x00, 0x10, 0x32, 0xb0, 0x00, 0x00, 0x8a, 0x00, 0x20, 0x40,
-	0xe7, 0xb1, 0x01, 0x00, 0x63, 0x94, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x66, 0x94, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x74, 0x96, 0x00, 0x15, 0x94, 0x30, 0x01, 0x00,
-	0x7b, 0x96, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x68, 0x94, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
-	0xaf, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00, 0x20, 0x98, 0x00, 0x45,
-	0x81, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xfe, 0x91, 0x00, 0x45, 0x1f, 0x90, 0x00, 0x00, 0xb6, 0x96, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x6f, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x49, 0x93, 0x00, 0x01, 0x2c, 0xb0, 0x00, 0x00, 0xbf, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x7a, 0x94, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x03, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00,
-	0x73, 0x94, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b,
-	0x62, 0xb1, 0x01, 0x00, 0x77, 0x94, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x74, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x62, 0xb1, 0x01, 0x00, 0x77, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xff, 0x89, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x58, 0x01, 0x20, 0x08,
-	0xe0, 0xb1, 0x01, 0x00, 0x60, 0x01, 0x20, 0x16, 0xe0, 0xb1, 0x01, 0x00,
-	0xb6, 0x96, 0x00, 0x47, 0x1f, 0x10, 0x01, 0x00, 0x6f, 0x96, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x49, 0x93, 0x00, 0x01, 0x2c, 0xb0, 0x00, 0x00,
-	0xbf, 0x95, 0x00, 0x47, 0x1f, 0x10, 0x01, 0x00, 0x8c, 0x94, 0xa2, 0x08,
-	0x80, 0x32, 0x00, 0x00, 0x88, 0x94, 0xa2, 0x42, 0x19, 0x7c, 0x00, 0x00,
-	0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00, 0xa0, 0x98, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0xe3, 0x89, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00,
-	0x74, 0x96, 0x00, 0x15, 0x94, 0x30, 0x01, 0x00, 0x7b, 0x96, 0x00, 0x4b,
-	0x02, 0xb0, 0x00, 0x00, 0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xf9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x19, 0x90, 0x01, 0x00, 0xaf, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00,
-	0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x58, 0x01, 0x20, 0x08,
-	0xe0, 0xb1, 0x01, 0x00, 0x60, 0x01, 0x20, 0x16, 0xe0, 0xb1, 0x01, 0x00,
-	0xf4, 0x95, 0x00, 0x10, 0x32, 0x30, 0x01, 0x00, 0x49, 0x93, 0x00, 0x40,
-	0x13, 0xb0, 0x00, 0x00, 0xbf, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x9c, 0x94, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02,
-	0x04, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x03, 0xf0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00, 0x95, 0x94, 0x37, 0x5c,
-	0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x62, 0xb1, 0x01, 0x00,
-	0x99, 0x94, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x96, 0x94, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0xb1, 0x01, 0x00,
-	0x99, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xff, 0x89, 0x17, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x8e, 0xb0, 0x01, 0x00,
-	0xb3, 0x96, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x85, 0xb0, 0x01, 0x00, 0xea, 0x96, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00,
-	0x6f, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0xab, 0x94, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0xa7, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x3f, 0x91, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00,
-	0x20, 0x98, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00, 0x3f, 0x91, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x14, 0x00, 0x2d, 0x45, 0x1f, 0x90, 0x01, 0x00,
-	0x87, 0x91, 0x00, 0x44, 0x19, 0x90, 0x00, 0x00, 0xb3, 0x94, 0xa2, 0x41,
-	0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x1f, 0x90, 0x01, 0x00,
-	0xef, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb6, 0x96, 0x00, 0x4a,
-	0x1f, 0x10, 0x01, 0x00, 0x6f, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x49, 0x93, 0x00, 0x01, 0x2c, 0xb0, 0x00, 0x00, 0xf4, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x49, 0x93, 0x00, 0x10, 0x32, 0xb0, 0x00, 0x00,
-	0xfe, 0x91, 0x00, 0x45, 0x1f, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x37, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x33, 0xc3, 0x01, 0x00,
-	0x36, 0x00, 0x00, 0x01, 0x02, 0xcc, 0x01, 0x00, 0x00, 0x00, 0xd2, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xbf, 0x94, 0x85, 0x17, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x9f, 0x48, 0x03, 0xd0, 0x00, 0x00, 0xc1, 0x94, 0x9c, 0x17,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x4c, 0x03, 0xd0, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x01, 0x34, 0xc3, 0x01, 0x00, 0x02, 0x00, 0x2d, 0x11,
-	0x10, 0xc1, 0x00, 0x00, 0xc6, 0x94, 0x00, 0x40, 0x43, 0xc1, 0x00, 0x00,
-	0xc6, 0x94, 0x00, 0x50, 0x43, 0xc1, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa1,
-	0x42, 0xc9, 0x01, 0x00, 0xca, 0x94, 0x22, 0x40, 0xe5, 0x6d, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x40, 0xe5, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x23, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x49, 0x1f, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0xa2, 0x41, 0x23, 0xd0, 0x00, 0x00, 0xc6, 0x94, 0x00, 0x50,
-	0x43, 0xd1, 0x00, 0x00, 0x40, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4a, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x12, 0xf0, 0xb1, 0x01, 0x00,
-	0xd0, 0x95, 0x00, 0x41, 0xe1, 0x31, 0x01, 0x00, 0x00, 0x80, 0x00, 0x43,
-	0x44, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
-	0xf0, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x03, 0xe0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xd7, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xba, 0x00, 0x20, 0x40,
-	0xe5, 0xb1, 0x01, 0x00, 0xb0, 0x00, 0x2f, 0x01, 0x8c, 0xd0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x46, 0xe0, 0xc1, 0x01, 0x00, 0xac, 0x00, 0x2f, 0x40,
-	0x13, 0xb0, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0x01, 0xe0, 0xc1, 0x01, 0x00,
-	0xe1, 0x94, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00, 0xfb, 0x98, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xe3, 0x94, 0x22, 0x47, 0x19, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x13, 0x90, 0x01, 0x00, 0x8d, 0x98, 0x00, 0x47,
-	0x19, 0x10, 0x01, 0x00, 0xc0, 0x00, 0x2d, 0x44, 0x1f, 0x90, 0x01, 0x00,
-	0xc4, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0xd8, 0x98, 0x00, 0xf0,
-	0x84, 0xb0, 0x00, 0x00, 0x90, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0xf8, 0x94, 0xa2, 0x4b, 0x1f, 0x7c, 0x00, 0x00, 0x4b, 0x95, 0xa2, 0x4c,
-	0x1f, 0x7c, 0x00, 0x00, 0xf8, 0x94, 0x1f, 0x1c, 0xe0, 0x6d, 0x00, 0x00,
-	0xfb, 0x94, 0xa2, 0x01, 0x80, 0x32, 0x00, 0x00, 0xa8, 0x00, 0x2d, 0x46,
-	0x8f, 0xb0, 0x01, 0x00, 0xf1, 0x94, 0x1f, 0x1c, 0xe0, 0x6d, 0x00, 0x00,
-	0xb4, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xf3, 0x94, 0x22, 0xf0,
-	0x3a, 0x6c, 0x00, 0x00, 0x48, 0x95, 0x1f, 0xf0, 0x3a, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0xa2, 0x40, 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x4f,
-	0x8f, 0xb0, 0x01, 0x00, 0x8a, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x49, 0x95, 0x20, 0x42, 0xe7, 0x6d, 0x00, 0x00, 0xf7, 0x94, 0x22, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x59, 0x8f, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x58, 0x8f, 0xb0, 0x01, 0x00, 0xfa, 0x94, 0x22, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x5c, 0x8f, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x5b, 0x8f, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0xb0, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00,
-	0xff, 0x94, 0xa2, 0x42, 0x24, 0x6c, 0x00, 0x00, 0x08, 0x95, 0x23, 0xf0,
-	0x02, 0x6c, 0x00, 0x00, 0x05, 0x95, 0xa2, 0xf0, 0x80, 0x32, 0x00, 0x00,
-	0x4a, 0x95, 0xa2, 0x42, 0x24, 0x6c, 0x00, 0x00, 0x4a, 0x95, 0xa2, 0x41,
-	0x03, 0x6c, 0x00, 0x00, 0x04, 0x95, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x51, 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x52,
-	0x8f, 0xb0, 0x01, 0x00, 0x4a, 0x95, 0x1f, 0x12, 0x84, 0x50, 0x00, 0x00,
-	0x4a, 0x95, 0xa0, 0x01, 0x84, 0x6c, 0x00, 0x00, 0xf8, 0x94, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x33, 0x95, 0xa2, 0x46, 0xe7, 0x7d, 0x00, 0x00, 0x14, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x25, 0x95, 0x22, 0xf0, 0x14, 0x30, 0x00, 0x00,
-	0x11, 0x95, 0x20, 0x0a, 0x02, 0x6c, 0x00, 0x00, 0x22, 0x95, 0x03, 0x1e,
-	0x80, 0x32, 0x00, 0x00, 0x10, 0x95, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x44, 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x49,
-	0x8f, 0xb0, 0x01, 0x00, 0x16, 0x95, 0x22, 0x0a, 0x02, 0x6c, 0x00, 0x00,
-	0x19, 0x95, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x15, 0x95, 0xa2, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x55, 0x8f, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x56, 0x8f, 0xb0, 0x01, 0x00, 0x18, 0x95, 0xa2, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43, 0x8f, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x48, 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
-	0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x82, 0xd0, 0x01, 0x00,
-	0x1f, 0x95, 0x20, 0x91, 0x83, 0x6c, 0x00, 0x00, 0x1e, 0x95, 0xa2, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x26, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
-	0x27, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x21, 0x95, 0xa2, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x1f, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
-	0x20, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x24, 0x95, 0xa2, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x22, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
-	0x23, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x88, 0x00, 0x2d, 0x44,
-	0x8f, 0xb0, 0x01, 0x00, 0x2e, 0x95, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0x2b, 0x95, 0xa2, 0x43, 0x3d, 0x7c, 0x00, 0x00, 0x2b, 0x95, 0xa2, 0xf2,
-	0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x40, 0x80, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00, 0x2d, 0x95, 0xa2, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43, 0x8f, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x48, 0x8f, 0xb0, 0x01, 0x00, 0x2b, 0x95, 0xa0, 0x91,
-	0x03, 0x6c, 0x00, 0x00, 0x29, 0x95, 0x22, 0x43, 0x3d, 0x7c, 0x00, 0x00,
-	0x32, 0x95, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x28, 0x00, 0x80, 0x40,
-	0x8f, 0x98, 0x01, 0x00, 0x29, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
-	0x14, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x3c, 0x95, 0xa2, 0xf0,
-	0x14, 0x30, 0x00, 0x00, 0x88, 0x00, 0x2d, 0x44, 0x8f, 0xb0, 0x01, 0x00,
-	0x39, 0x95, 0xa2, 0xf2, 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x40,
-	0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00,
-	0x2b, 0x95, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x29, 0x95, 0x20, 0x91,
-	0x03, 0x6c, 0x00, 0x00, 0x2b, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x40, 0x95, 0x20, 0x0a, 0x02, 0x6c, 0x00, 0x00, 0x3f, 0x95, 0xa2, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x44, 0x8f, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00, 0x45, 0x95, 0x22, 0x0a,
-	0x02, 0x6c, 0x00, 0x00, 0x19, 0x95, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0x44, 0x95, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x55,
-	0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x56, 0x8f, 0xb0, 0x01, 0x00,
-	0x47, 0x95, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43,
-	0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x48, 0x8f, 0xb0, 0x01, 0x00,
-	0x4d, 0x95, 0x00, 0x43, 0x95, 0xb0, 0x00, 0x00, 0x4d, 0x95, 0x00, 0x41,
-	0x95, 0xb0, 0x00, 0x00, 0x4d, 0x95, 0x00, 0x42, 0x95, 0xb0, 0x00, 0x00,
-	0x4d, 0x95, 0x00, 0x44, 0x95, 0xb0, 0x00, 0x00, 0x4d, 0x95, 0x00, 0x4c,
-	0x95, 0xb0, 0x00, 0x00, 0xf5, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x50, 0x95, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x4b,
-	0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x4c, 0x8f, 0xb0, 0x01, 0x00,
-	0x2d, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x2e, 0x00, 0x2f, 0xf3,
-	0x84, 0xb0, 0x01, 0x00, 0x55, 0x95, 0xa2, 0xf3, 0x96, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x01, 0xb0, 0x01, 0x00, 0x2d, 0x00, 0x2a, 0x41,
-	0xe7, 0xd1, 0x01, 0x00, 0xd4, 0x00, 0x3d, 0x41, 0x85, 0xe0, 0x01, 0x00,
-	0x0b, 0x00, 0x00, 0xf2, 0x00, 0xe4, 0x01, 0x00, 0x5b, 0x95, 0x22, 0x5a,
-	0x01, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1f, 0x90, 0x01, 0x00,
-	0x5c, 0x95, 0x00, 0x5a, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x1f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x63, 0x41, 0x85, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0xa0, 0xa5, 0x85, 0x6c, 0x01, 0x00, 0x00, 0x00, 0xe3, 0x40,
-	0x85, 0xb0, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x12, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0x3d, 0x99, 0x00, 0xf0,
-	0x8c, 0xb0, 0x00, 0x00, 0x69, 0x95, 0x22, 0x40, 0x0f, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x66, 0x95, 0xa2, 0x4b,
-	0x19, 0x7c, 0x00, 0x00, 0x67, 0x95, 0x22, 0xf0, 0x18, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x60, 0x4b, 0x19, 0x90, 0x01, 0x00, 0x32, 0x96, 0x00, 0x07,
-	0x10, 0x30, 0x01, 0x00, 0x6f, 0x84, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
-	0x6b, 0x95, 0x22, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0xb8, 0x95, 0x00, 0x40,
-	0x81, 0x30, 0x01, 0x00, 0x6f, 0x84, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x4b,
-	0x19, 0x90, 0x01, 0x00, 0x32, 0x96, 0x00, 0x07, 0x10, 0x30, 0x01, 0x00,
-	0x6f, 0x84, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x4b, 0x19, 0x90, 0x01, 0x00,
-	0x32, 0x96, 0x00, 0x07, 0x10, 0x30, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x05, 0xb0, 0x01, 0x00, 0x74, 0x95, 0x33, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x77, 0x95, 0xa1, 0xad, 0x95, 0x20, 0x00, 0x00, 0x85, 0x95, 0x13, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x13, 0x4a, 0x5a, 0x83, 0x01, 0x00,
-	0x30, 0x00, 0x39, 0x45, 0x95, 0xe0, 0x01, 0x00, 0x1f, 0x00, 0x00, 0x0f,
-	0x5e, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x5f, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x45, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04,
-	0x48, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x4a, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0c, 0x58, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07,
-	0x4e, 0xb0, 0x01, 0x00, 0x12, 0x86, 0x00, 0x40, 0x5d, 0x98, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x58, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
-	0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x41, 0x97, 0xb0, 0x00, 0x00,
-	0x82, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x97, 0xb0, 0x01, 0x00, 0x86, 0x95, 0x44, 0x07, 0x96, 0x30, 0x00, 0x00,
-	0xff, 0xff, 0x00, 0x4b, 0x84, 0x89, 0x01, 0x00, 0x00, 0x00, 0x1c, 0xc2,
-	0x24, 0xb0, 0x01, 0x00, 0x90, 0x95, 0xa2, 0x45, 0x25, 0x7c, 0x00, 0x00,
-	0x8a, 0x95, 0x31, 0x20, 0x85, 0x30, 0x00, 0x00, 0x91, 0x95, 0x22, 0x12,
-	0x48, 0x7f, 0x00, 0x00, 0x51, 0x98, 0x11, 0x12, 0x48, 0x03, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x12, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x1e, 0x94, 0x01, 0x00, 0x00, 0x00, 0x80, 0x5a, 0x1f, 0x90, 0x01, 0x00,
-	0x90, 0x95, 0x31, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4,
-	0x24, 0xb0, 0x01, 0x00, 0x91, 0x95, 0x22, 0x12, 0x48, 0x7f, 0x00, 0x00,
-	0x51, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x9e, 0x95, 0x0b, 0xf0, 0x84, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x11, 0x12, 0x48, 0x83, 0x01, 0x00, 0x9b, 0x95, 0x22, 0x50,
-	0x85, 0x70, 0x00, 0x00, 0x5e, 0x01, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x51, 0x97, 0x00, 0xf2, 0x96, 0x30, 0x01, 0x00, 0xd1, 0x99, 0x00, 0x12,
-	0x94, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x1f, 0x90, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x12, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x80, 0x4b,
-	0x1e, 0x94, 0x01, 0x00, 0x10, 0x00, 0x00, 0x42, 0x10, 0xf4, 0x01, 0x00,
-	0x00, 0xb7, 0x3f, 0x43, 0x11, 0xf0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x08,
-	0x8a, 0x88, 0x01, 0x00, 0xa1, 0x95, 0x30, 0xa1, 0x0c, 0x30, 0x00, 0x00,
-	0xa4, 0x95, 0x22, 0x45, 0xe6, 0x7d, 0x00, 0x00, 0x91, 0x95, 0x10, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x45, 0xe6, 0x91, 0x01, 0x00,
-	0x00, 0x00, 0x10, 0x12, 0x48, 0x83, 0x01, 0x00, 0x00, 0x00, 0x11, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x60, 0x4b, 0x85, 0x80, 0x01, 0x00,
-	0x5e, 0x01, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x51, 0x97, 0x00, 0xf2,
-	0x96, 0x30, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
-	0xd8, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x2e, 0x00, 0x2d, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0xaf, 0x95, 0x22, 0x40, 0xe7, 0x6d, 0x00, 0x00,
-	0x80, 0x00, 0x00, 0x40, 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf0, 0xb1, 0x01, 0x00, 0x09, 0x00, 0x00, 0x08, 0x86, 0xe4, 0x01, 0x00,
-	0x00, 0x00, 0x68, 0xa7, 0x87, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
-	0xb3, 0x95, 0xa8, 0x05, 0xe0, 0x31, 0x00, 0x00, 0x10, 0x00, 0x00, 0x12,
-	0x96, 0xe4, 0x01, 0x00, 0x00, 0x14, 0x00, 0x4b, 0x96, 0xdc, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x4b, 0x1e, 0x94, 0x01, 0x00, 0x10, 0x00, 0x00, 0x0f,
-	0x84, 0xf4, 0x01, 0x00, 0x1f, 0x00, 0x00, 0x42, 0x84, 0x88, 0x01, 0x00,
-	0xbc, 0x95, 0x22, 0x40, 0x80, 0x32, 0x00, 0x00, 0xbd, 0x95, 0x00, 0x42,
-	0x68, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x6a, 0xb1, 0x01, 0x00,
-	0xbd, 0x95, 0x31, 0x5a, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x42,
-	0x48, 0x93, 0x01, 0x00, 0xbf, 0x95, 0x35, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xc4, 0x95, 0x28, 0xb1,
-	0x2c, 0x30, 0x00, 0x00, 0xc0, 0x95, 0x22, 0x4d, 0x75, 0x7d, 0x00, 0x00,
-	0x00, 0x00, 0x95, 0x40, 0x11, 0xb0, 0x01, 0x00, 0x6d, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0xc4, 0x95, 0xa8, 0xb1, 0x10, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x95, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x7f, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0xcb, 0x95, 0x28, 0xb1, 0x10, 0x30, 0x00, 0x00,
-	0xc7, 0x95, 0x9f, 0xba, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x11, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x24, 0x11, 0x84, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00,
-	0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xcd, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xac, 0x94, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0xd1, 0x95, 0x32, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xd7, 0x95, 0x22, 0xf8, 0x96, 0x30, 0x00, 0x00, 0x04, 0x00, 0x22, 0xf8,
-	0x90, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x92, 0xb0, 0x01, 0x00,
-	0x01, 0x00, 0x00, 0x4b, 0xf0, 0xcd, 0x01, 0x00, 0x20, 0x00, 0x92, 0x48,
-	0xe0, 0xc9, 0x01, 0x00, 0x6c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0xdb, 0x95, 0x28, 0xb1, 0x92, 0x30, 0x00, 0x00, 0xd7, 0x95, 0x22, 0x4c,
-	0x75, 0x7d, 0x00, 0x00, 0x04, 0x00, 0x12, 0x40, 0x91, 0xb0, 0x00, 0x00,
-	0x6c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xdb, 0x95, 0xa8, 0xb1,
-	0x90, 0x30, 0x00, 0x00, 0xff, 0x00, 0x00, 0x48, 0x96, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4b, 0x90, 0xd0, 0x01, 0x00, 0x01, 0x00, 0x00, 0x4b,
-	0xf0, 0xcd, 0x01, 0x00, 0x20, 0x00, 0x00, 0x48, 0xf0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x92, 0x49, 0xe0, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x10,
-	0x48, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08, 0x82, 0x8c, 0x01, 0x00,
-	0xff, 0x07, 0x00, 0xf0, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x41,
-	0x00, 0xec, 0x00, 0x00, 0xe8, 0x95, 0x22, 0x1a, 0x00, 0x6c, 0x00, 0x00,
-	0xcc, 0x95, 0x00, 0x00, 0x34, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x49, 0xc1, 0x01, 0x00, 0xe4, 0x95, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x10,
-	0x48, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x15, 0x82, 0x8c, 0x01, 0x00,
-	0xff, 0x07, 0x00, 0xf0, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x41,
-	0x00, 0xec, 0x00, 0x00, 0xf1, 0x95, 0x22, 0x0d, 0x00, 0x6c, 0x00, 0x00,
-	0xcc, 0x95, 0x00, 0x00, 0x1a, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x49, 0xc1, 0x01, 0x00, 0xed, 0x95, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xf6, 0x95, 0x83, 0x1e,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x19, 0x90, 0x01, 0x00,
-	0x24, 0x00, 0x2d, 0x01, 0x2c, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x2d, 0xf0,
-	0x16, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00,
-	0x14, 0x00, 0x2f, 0xf2, 0x0c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0xe1, 0xb1, 0x01, 0x00, 0x02, 0x00, 0x2d, 0x11, 0x10, 0xc1, 0x00, 0x00,
-	0xff, 0x95, 0x00, 0x40, 0x43, 0xc1, 0x00, 0x00, 0xff, 0x95, 0x00, 0x50,
-	0x43, 0xc1, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa1, 0x42, 0xc9, 0x01, 0x00,
-	0x04, 0x96, 0x22, 0x40, 0xf5, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x43, 0xd1, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x40, 0xe5, 0x7d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x49,
-	0x1f, 0x90, 0x01, 0x00, 0x07, 0x96, 0x22, 0x11, 0x1e, 0x7c, 0x00, 0x00,
-	0x09, 0x96, 0xa0, 0xf0, 0x16, 0x40, 0x00, 0x00, 0x09, 0x96, 0x00, 0x41,
-	0x17, 0xc0, 0x00, 0x00, 0x09, 0x96, 0xa0, 0xf4, 0x16, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x41,
-	0x23, 0xd0, 0x00, 0x00, 0xff, 0x95, 0x00, 0x52, 0x43, 0xd1, 0x00, 0x00,
-	0x00, 0xb5, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00, 0x0c, 0x96, 0x30, 0x47,
-	0x17, 0x04, 0x00, 0x00, 0x0f, 0x96, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
-	0x00, 0x00, 0x90, 0x42, 0x81, 0xb0, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x0d,
-	0x46, 0xc9, 0x01, 0x00, 0x13, 0x96, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x0b, 0xe6, 0x91, 0x01, 0x00, 0x00, 0x00, 0x90, 0x41,
-	0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x14, 0x96, 0x40, 0x07, 0x96, 0x30, 0x00, 0x00, 0xdb, 0x99, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x1e, 0x96, 0xa2, 0x45, 0x95, 0x7c, 0x00, 0x00,
-	0x01, 0x97, 0x3f, 0x41, 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
-	0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xe6, 0xb1, 0x01, 0x00,
-	0x40, 0x97, 0x3e, 0x40, 0x97, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e,
-	0xe6, 0xb1, 0x01, 0x00, 0x40, 0x97, 0x3e, 0x40, 0x9d, 0xe0, 0x01, 0x00,
-	0x31, 0x96, 0x00, 0x3b, 0xe7, 0xb1, 0x00, 0x00, 0x1e, 0x96, 0x30, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x28, 0x96, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
-	0x00, 0xb5, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00, 0x24, 0x96, 0xa2, 0x0b,
-	0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x98, 0x42, 0x81, 0xb0, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x0d,
-	0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x91, 0x01, 0x00,
-	0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x98, 0x41,
-	0x81, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x21, 0xa2, 0x95, 0x20, 0x00, 0x00,
-	0x00, 0x00, 0x10, 0x4a, 0x44, 0x83, 0x01, 0x00, 0x00, 0x97, 0x3e, 0x41,
-	0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xf6, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4e, 0xe6, 0xb1, 0x01, 0x00, 0x40, 0x97, 0x3e, 0x40,
-	0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x3b, 0xe7, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0x07,
-	0x92, 0x89, 0x01, 0x00, 0x00, 0x00, 0x98, 0x40, 0x81, 0xb0, 0x01, 0x00,
-	0x03, 0x00, 0x00, 0x08, 0x86, 0xf4, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x43,
-	0x46, 0xc9, 0x01, 0x00, 0x07, 0x00, 0x00, 0x08, 0x82, 0x88, 0x01, 0x00,
-	0x35, 0x96, 0x40, 0x08, 0x96, 0x30, 0x00, 0x00, 0xdb, 0x99, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x41, 0x96, 0x22, 0x45, 0x95, 0x7c, 0x00, 0x00,
-	0x3d, 0x96, 0x22, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x0f,
-	0x96, 0xf4, 0x01, 0x00, 0x3a, 0x96, 0x31, 0x5f, 0x97, 0x04, 0x00, 0x00,
-	0x00, 0x00, 0x11, 0x4b, 0x48, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x6a, 0xb1, 0x01, 0x00, 0x3d, 0x96, 0x30, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0xe6, 0x81, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x97, 0x3f, 0x41, 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
-	0x96, 0xb0, 0x01, 0x00, 0x40, 0x97, 0x3d, 0x40, 0x97, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x63, 0xf3, 0x88, 0xb0, 0x01, 0x00, 0x49, 0x96, 0xa2, 0x3b,
-	0x89, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00,
-	0x01, 0x00, 0x00, 0xa6, 0x92, 0xb1, 0x01, 0x00, 0x4a, 0x96, 0x18, 0x4a,
-	0x44, 0x93, 0x00, 0x00, 0x00, 0x00, 0x18, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x30, 0x00, 0x39, 0x45, 0x97, 0xe0, 0x01, 0x00, 0x4f, 0x96, 0x22, 0x5a,
-	0x1f, 0x7c, 0x00, 0x00, 0x1f, 0x04, 0x00, 0x0f, 0x98, 0xd8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0x5e, 0x94, 0x01, 0x00, 0x51, 0x96, 0x00, 0x05,
-	0x4a, 0xb0, 0x00, 0x00, 0x1f, 0x04, 0x00, 0xa7, 0x5e, 0x84, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x4b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x58,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x52, 0x96, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x55, 0x96, 0x40, 0x07, 0x96, 0x30, 0x00, 0x00,
-	0xdb, 0x99, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x59, 0x96, 0x22, 0x45,
-	0x95, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0xd9, 0x99, 0x00, 0x4a, 0x44, 0x13, 0x01, 0x00, 0x00, 0x97, 0x3f, 0x41,
-	0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00,
-	0x40, 0x97, 0x3d, 0x40, 0x97, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x63, 0xf3,
-	0x88, 0xb0, 0x01, 0x00, 0x30, 0x00, 0x38, 0x45, 0x97, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x0f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x58,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00,
-	0x61, 0x96, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x5a, 0x96, 0xa2, 0x3b,
-	0x89, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x38, 0x45, 0x9d, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xd1, 0x99, 0x00, 0x12,
-	0x94, 0x30, 0x01, 0x00, 0x32, 0x96, 0x00, 0x5a, 0x1f, 0x00, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x5a, 0x1f, 0x90, 0x01, 0x00, 0x11, 0x00, 0x00, 0x4a,
-	0xe6, 0xc9, 0x01, 0x00, 0x34, 0x00, 0x2f, 0x4f, 0x95, 0x84, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x63, 0x4b,
-	0x84, 0xc8, 0x01, 0x00, 0x00, 0x00, 0xa0, 0x43, 0x85, 0x6c, 0x01, 0x00,
-	0x00, 0x00, 0xe3, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x30, 0x00, 0x2d, 0x44,
-	0x1f, 0x90, 0x01, 0x00, 0x32, 0x00, 0x2d, 0xf2, 0x2a, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0xf2, 0x02, 0x30, 0x00, 0x00, 0x51, 0x95, 0x00, 0x10,
-	0x32, 0x30, 0x01, 0x00, 0x32, 0x00, 0xa0, 0x40, 0xe5, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
-	0x99, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x02, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x03, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x97, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xa3, 0x4c, 0x02, 0xd0, 0x00, 0x00,
-	0x78, 0x96, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
-	0x36, 0xb0, 0x01, 0x00, 0x88, 0x96, 0x22, 0x41, 0x03, 0x50, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0xf1, 0xb1, 0x01, 0x00, 0x70, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x62, 0xb1, 0x01, 0x00, 0x81, 0x96, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x7c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x00, 0xb0, 0x01, 0x00, 0x7c, 0x96, 0x00, 0x5c,
-	0x01, 0x80, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x1b, 0x10, 0xb1, 0x00, 0x00, 0x68, 0x01, 0x2d, 0x06,
-	0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x82, 0xc0, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x03, 0x46, 0xc9, 0x01, 0x00, 0xc7, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xaf, 0x96, 0x22, 0x40, 0x11, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x68, 0x08, 0x38, 0x96, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x41,
-	0x82, 0xcc, 0x01, 0x00, 0x8d, 0x96, 0xaa, 0x41, 0x3b, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
-	0x11, 0x80, 0x01, 0x00, 0x01, 0x00, 0x00, 0x1d, 0x04, 0xcc, 0x01, 0x00,
-	0xae, 0x96, 0x26, 0x46, 0x23, 0x30, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03,
-	0x12, 0xc8, 0x01, 0x00, 0x64, 0x01, 0x20, 0xf0, 0xe0, 0xb1, 0x01, 0x00,
-	0xad, 0x96, 0x22, 0x41, 0x05, 0x50, 0x00, 0x00, 0x20, 0x00, 0x00, 0x03,
-	0x48, 0xc9, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xf8, 0x86, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x22, 0x44, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0xe0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
-	0x62, 0xdd, 0x01, 0x00, 0x9f, 0x96, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
-	0xac, 0x96, 0x22, 0x41, 0x05, 0x50, 0x00, 0x00, 0xaa, 0x96, 0xa2, 0x41,
-	0x23, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x1a, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0xa5, 0x96, 0xa8, 0x46, 0x23, 0x30, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03,
-	0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x42, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x13, 0xc0, 0x01, 0x00, 0x9a, 0x96, 0x00, 0x50,
-	0x49, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x04, 0x80, 0x00, 0x03, 0x1a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0xae, 0x96, 0x22, 0x40, 0x3b, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x00, 0xb0, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x5c,
-	0x01, 0x00, 0x01, 0x00, 0xaf, 0x96, 0x00, 0x41, 0x3b, 0xd0, 0x00, 0x00,
-	0x00, 0x00, 0x8d, 0x47, 0x80, 0x32, 0x01, 0x00, 0xb0, 0x00, 0x2f, 0x5f,
-	0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xe0, 0xf0, 0x8c, 0xc0, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x8c, 0xb0, 0x01, 0x00,
-	0xbb, 0x96, 0x8c, 0xf8, 0x8e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x19, 0x90, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf8, 0x14, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x16, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x26, 0xb0, 0x01, 0x00, 0x08, 0x00, 0x2e, 0xf8, 0x0c, 0xb0, 0x01, 0x00,
-	0x0c, 0x00, 0x2a, 0x4a, 0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x00, 0x00,
-	0xe0, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x20, 0x1b, 0xe0, 0xb1, 0x01, 0x00,
-	0xc8, 0x96, 0x20, 0x0a, 0x0c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x96, 0xb0, 0x01, 0x00,
-	0x20, 0x00, 0x20, 0xf0, 0xe4, 0xb1, 0x01, 0x00, 0x18, 0x00, 0x20, 0x4a,
-	0xe0, 0xb1, 0x01, 0x00, 0x1c, 0x00, 0x20, 0x4b, 0xe0, 0xb1, 0x01, 0x00,
-	0xb3, 0x96, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00, 0x2c, 0x00, 0x2d, 0x42,
-	0x19, 0x90, 0x01, 0x00, 0x2e, 0x00, 0x2f, 0xf3, 0x82, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00, 0xce, 0x96, 0xa2, 0xa5,
-	0x97, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41, 0x95, 0xb0, 0x01, 0x00,
-	0xd1, 0x96, 0xa2, 0x40, 0x97, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x83, 0xb0, 0x01, 0x00, 0x2d, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x63, 0x41, 0x97, 0xc0, 0x01, 0x00, 0xd4, 0x00, 0x3e, 0x41,
-	0x83, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00,
-	0xd6, 0x96, 0xa0, 0xa5, 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x83, 0xb0, 0x01, 0x00, 0x2c, 0x00, 0x20, 0x41, 0xe6, 0xb1, 0x01, 0x00,
-	0xdb, 0x96, 0x22, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
-	0x98, 0xdc, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x4c, 0xe4, 0xf5, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x1f, 0x80, 0x01, 0x00, 0x0b, 0x00, 0x80, 0x00,
-	0xe4, 0xf5, 0x01, 0x00, 0xd0, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x04, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x60, 0x41, 0x87, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5d, 0x05, 0x90, 0x00, 0x00,
-	0xe7, 0x96, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xd0, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5d, 0x05, 0x90, 0x00, 0x00,
-	0xf6, 0x96, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x2e, 0x00, 0x2f, 0xf3, 0x84, 0xb0, 0x01, 0x00,
-	0x01, 0x00, 0x63, 0xf3, 0x96, 0xc8, 0x01, 0x00, 0xfe, 0x96, 0x9f, 0x41,
-	0x85, 0x50, 0x00, 0x00, 0x01, 0x00, 0x00, 0xa5, 0x85, 0xcc, 0x01, 0x00,
-	0x2d, 0x00, 0xa0, 0x42, 0xe6, 0xb1, 0x01, 0x00, 0x5e, 0x01, 0x2d, 0x00,
-	0x80, 0xb0, 0x01, 0x00, 0x03, 0x97, 0x52, 0x43, 0x81, 0x60, 0x00, 0x00,
-	0x02, 0x00, 0x00, 0xf2, 0x82, 0xf4, 0x01, 0x00, 0x04, 0x97, 0x00, 0x41,
-	0x80, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x81, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5e, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x95, 0xb0, 0x00, 0x00,
-	0x05, 0x97, 0x9e, 0xbb, 0x80, 0x32, 0x00, 0x00, 0x0a, 0x97, 0xa2, 0x40,
-	0x1f, 0x7c, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x41, 0x95, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x15,
-	0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0x2b, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfc, 0x24, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
-	0x38, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3c, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfe, 0x3a, 0xb0, 0x01, 0x00, 0x1f, 0x97, 0x9c, 0x17,
-	0x80, 0x32, 0x00, 0x00, 0x14, 0x97, 0xa2, 0x4a, 0x19, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x4c, 0x1f, 0x90, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x1e,
-	0x98, 0xf4, 0x01, 0x00, 0x13, 0x97, 0xa2, 0x48, 0x99, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x15, 0x42, 0xb1, 0x01, 0x00, 0x13, 0x97, 0xa2, 0x8a,
-	0xf1, 0x6d, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x02, 0xcc, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfc, 0x3e, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x00, 0xf4,
-	0x28, 0xcc, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x1e, 0x97, 0x20, 0xf0, 0x3e, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x2b, 0xc0, 0x01, 0x00,
-	0xbf, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0xf3,
-	0x3a, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x4b, 0x19, 0x90, 0x01, 0x00,
-	0x07, 0x00, 0x2a, 0x0c, 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x04,
-	0xe6, 0xb1, 0x01, 0x00, 0x18, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x1c, 0x00, 0x2d, 0xf0, 0x16, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x2d, 0xf0,
-	0x26, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x2f, 0xf2, 0x0c, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0xa2, 0x06, 0x14, 0xec, 0x00, 0x00, 0x2b, 0x97, 0x22, 0x45,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xa3, 0x06, 0x2a, 0xec, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x96, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x2a, 0x4c, 0xe1, 0xc1, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10,
-	0x48, 0xc9, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
-	0x18, 0x00, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0xe0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
-	0x62, 0xdd, 0x01, 0x00, 0x35, 0x97, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x68, 0x01, 0x96, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x3b, 0x97, 0x45, 0x42,
-	0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
-	0x3c, 0x97, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x68, 0x01, 0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0xf0, 0xb1, 0x01, 0x00, 0x42, 0x97, 0x45, 0x42, 0x61, 0x31, 0x00, 0x00,
-	0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x43, 0x97, 0xa8, 0x00,
-	0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x30, 0x80, 0x00, 0x4a, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
-	0xf1, 0xb1, 0x01, 0x00, 0xc0, 0xa8, 0x3d, 0x46, 0x0d, 0xe0, 0x01, 0x00,
-	0xff, 0x7f, 0x00, 0xa1, 0xf0, 0x89, 0x01, 0x00, 0x02, 0x00, 0x00, 0x09,
-	0x96, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x97, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x60, 0xa8, 0x97, 0xc0, 0x01, 0x00, 0x4d, 0x97, 0x46, 0x42,
-	0x61, 0x31, 0x00, 0x00, 0x30, 0x00, 0x00, 0x4a, 0x62, 0xc9, 0x01, 0x00,
-	0x4e, 0x97, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9e, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x99, 0x3f, 0x42, 0x97, 0xf0, 0x01, 0x00,
-	0x52, 0x97, 0x47, 0x40, 0x81, 0x32, 0x00, 0x00, 0x5a, 0x97, 0x22, 0xf3,
-	0x74, 0x06, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf3, 0x94, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x07, 0xe7, 0x85, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x55,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x62, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x57, 0x97, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xa8, 0x36, 0xb0, 0x01, 0x00, 0x6a, 0x97, 0x82, 0x41,
-	0x23, 0x40, 0x00, 0x00, 0x5f, 0x97, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
-	0xda, 0x94, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00, 0x20, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0x65, 0x97, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x62, 0x97, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x23, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
-	0x6a, 0x97, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xe2, 0x95, 0x00, 0x43,
-	0x23, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x23, 0xb0, 0x01, 0x00,
-	0x6c, 0x97, 0xa3, 0x15, 0x0c, 0x6c, 0x00, 0x00, 0x6d, 0x97, 0x00, 0x06,
-	0x04, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x04, 0xb0, 0x01, 0x00,
-	0x6f, 0x97, 0x20, 0x02, 0x1a, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
-	0x04, 0xb0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x0b, 0x96, 0x88, 0x01, 0x00,
-	0x74, 0x97, 0x26, 0x47, 0x97, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x97, 0xc0, 0x01, 0x00, 0x74, 0x97, 0x23, 0x4b, 0x04, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4b, 0x04, 0xb0, 0x01, 0x00, 0x33, 0x98, 0x00, 0x05,
-	0x48, 0x31, 0x01, 0x00, 0x9e, 0x97, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00,
-	0x78, 0x97, 0xa2, 0x02, 0x2a, 0x50, 0x00, 0x00, 0x9e, 0x97, 0xa2, 0x45,
-	0x1f, 0x7c, 0x00, 0x00, 0x7a, 0x97, 0x22, 0x02, 0x0c, 0x50, 0x00, 0x00,
-	0x83, 0x97, 0x00, 0x02, 0x16, 0xc0, 0x00, 0x00, 0x82, 0x97, 0x22, 0x5c,
-	0x1f, 0x7c, 0x00, 0x00, 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
-	0x82, 0x97, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x7e, 0x97, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x24, 0x97, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x9e, 0x97, 0x22, 0x15,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
-	0x9d, 0x97, 0xa2, 0x02, 0x1a, 0x50, 0x00, 0x00, 0x8f, 0x97, 0x22, 0x46,
-	0x1f, 0x7c, 0x00, 0x00, 0x70, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00, 0x8f, 0x97, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x8b, 0x97, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf0, 0x10, 0xc8, 0x01, 0x00,
-	0x2f, 0x00, 0x2f, 0x5c, 0x11, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0xe7, 0x91, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40, 0x1b, 0x98, 0x01, 0x00,
-	0x5c, 0x97, 0x20, 0x15, 0x1a, 0x6c, 0x00, 0x00, 0x70, 0x00, 0x00, 0x03,
-	0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x22, 0x50, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08,
-	0xe0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
-	0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0x9a, 0x97, 0xa8, 0x46,
-	0x1f, 0x10, 0x00, 0x00, 0x5c, 0x97, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
-	0x5c, 0x97, 0x00, 0x02, 0x10, 0xc0, 0x00, 0x00, 0xa0, 0x97, 0xa2, 0x44,
-	0x1f, 0x7c, 0x00, 0x00, 0xda, 0x94, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x1b, 0x10, 0xb1, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x44, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x08, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
-	0xf0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x03, 0xe0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5c, 0x1f, 0x90, 0x00, 0x00,
-	0xa7, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x17, 0x00, 0x00, 0xd0,
-	0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x40, 0x27, 0xec, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x20, 0x00, 0xb0, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x41,
-	0xa3, 0x41, 0x01, 0x00, 0xab, 0x97, 0x00, 0x41, 0x27, 0xd0, 0x00, 0x00,
-	0x10, 0x00, 0x00, 0x07, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x80, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x40, 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xb2, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x98, 0x00, 0x40, 0x2b, 0x30, 0x01, 0x00, 0xac, 0x00, 0x2d, 0x06,
-	0x16, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0, 0x16, 0xc4, 0x01, 0x00,
-	0xba, 0x97, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x17, 0xc0, 0x01, 0x00, 0x0e, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x6c, 0xf0, 0x30, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x2d, 0x40,
-	0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x6c, 0xf0, 0x28, 0xb0, 0x01, 0x00,
-	0xc3, 0x97, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x43,
-	0x86, 0xc8, 0x01, 0x00, 0x00, 0x30, 0x00, 0x0b, 0x16, 0xc8, 0x01, 0x00,
-	0xc3, 0x97, 0xa4, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x17, 0xc0, 0x01, 0x00, 0xe4, 0x97, 0x22, 0x06, 0x80, 0x32, 0x00, 0x00,
-	0xd0, 0x97, 0xa2, 0x06, 0x14, 0x6c, 0x00, 0x00, 0xcd, 0x97, 0x22, 0x48,
-	0x19, 0x7c, 0x00, 0x00, 0xc8, 0x97, 0xa0, 0x41, 0x17, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x31, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x20, 0x18, 0xe0, 0xb1, 0x01, 0x00,
-	0x8b, 0x00, 0x2d, 0x48, 0x19, 0x80, 0x01, 0x00, 0x8b, 0x00, 0x20, 0x45,
-	0xe7, 0x91, 0x01, 0x00, 0xd0, 0x97, 0x00, 0x40, 0x87, 0x90, 0x00, 0x00,
-	0x08, 0x00, 0x00, 0x43, 0x86, 0x98, 0x01, 0x00, 0xd0, 0x97, 0xa0, 0x48,
-	0x17, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
-	0xb0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x10, 0x50, 0x00, 0x43,
-	0xfc, 0xc9, 0x01, 0x00, 0x3b, 0x98, 0x00, 0x30, 0x81, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xe5, 0xb1, 0x01, 0x00, 0xdb, 0x97, 0x22, 0x4a,
-	0x19, 0x7c, 0x00, 0x00, 0x08, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00,
-	0xcc, 0x00, 0x2d, 0xab, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab,
-	0x17, 0xc0, 0x01, 0x00, 0xda, 0x97, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0xdf, 0x97, 0x64, 0xf0,
-	0x82, 0xb0, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0xdf, 0x97, 0xa2, 0xf2, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0xe5, 0xb1, 0x01, 0x00, 0x8c, 0x00, 0x20, 0x18, 0xe0, 0xb1, 0x01, 0x00,
-	0x90, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x60, 0x06,
-	0x30, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x86, 0x0c, 0x80, 0xb2, 0x00, 0x00,
-	0xbc, 0x00, 0x2d, 0x46, 0x19, 0x90, 0x01, 0x00, 0xa0, 0x00, 0xa0, 0xf2,
-	0xe4, 0xb1, 0x01, 0x00, 0xb0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x10, 0x50, 0x00, 0x43, 0xfc, 0xc9, 0x01, 0x00, 0x3b, 0x98, 0x00, 0x30,
-	0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x4a, 0x19, 0xfc, 0x00, 0x00,
-	0x08, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0xab,
-	0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab, 0x17, 0xc0, 0x01, 0x00,
-	0xed, 0x97, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xe4, 0xf0, 0x82, 0xb0, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x1b, 0xe0, 0xb1, 0x00, 0x00,
-	0xf2, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0c,
-	0x7e, 0x89, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x4c, 0x95, 0x60, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x4a, 0x18, 0x94, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x44, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x01, 0xf0, 0x31, 0x00, 0x00,
-	0x20, 0x00, 0x00, 0x40, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x15,
-	0xe0, 0xb1, 0x00, 0x00, 0xfd, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x10, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0xe8, 0x5f, 0x17, 0x90, 0x01, 0x00, 0x70, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x7a, 0x01, 0x2e, 0xfe, 0x92, 0xb0, 0x01, 0x00,
-	0x8b, 0x00, 0x2d, 0xf6, 0x16, 0xb0, 0x01, 0x00, 0x0a, 0x98, 0x22, 0x43,
-	0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0xa6, 0x2a, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x6e, 0x06,
-	0x82, 0xc8, 0x01, 0x00, 0x0e, 0x98, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x45, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x6e, 0x4c,
-	0x83, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x92, 0xc0, 0x01, 0x00,
-	0x0f, 0x98, 0x42, 0x30, 0x3d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x66, 0x9e,
-	0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x41, 0x3d, 0xc3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x92, 0xc0, 0x01, 0x00, 0x06, 0x00, 0x00, 0xa2,
-	0x44, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x49, 0x98, 0xf4, 0x01, 0x00,
-	0x18, 0x98, 0x26, 0x30, 0x93, 0x04, 0x00, 0x00, 0x18, 0x98, 0x90, 0x4c,
-	0x92, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00,
-	0xff, 0xff, 0x80, 0x49, 0xec, 0xa9, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x44, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x01, 0xf0, 0x31, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
-	0xf0, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x00, 0x00, 0xa8, 0x15, 0xe0, 0xb1, 0x00, 0x00, 0x1d, 0x98, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x2a, 0x98, 0x22, 0x5f, 0x81, 0x7c, 0x00, 0x00,
-	0x29, 0x98, 0xa2, 0x40, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x19, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x07, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f,
-	0x97, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00,
-	0x29, 0x98, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x26, 0x98, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x21, 0x81, 0x84, 0x00, 0x00,
-	0x2d, 0x98, 0xa2, 0x5f, 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x43,
-	0x19, 0x7c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x19, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x07,
-	0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x96, 0x94, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x30, 0x98, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x19, 0x44, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x02,
-	0xf0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x13, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
-	0x00, 0x00, 0xa8, 0x08, 0xe0, 0xb1, 0x00, 0x00, 0x38, 0x98, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x7c, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00,
-	0x02, 0x00, 0x00, 0xf0, 0x98, 0xf4, 0x01, 0x00, 0x41, 0x98, 0x20, 0x4c,
-	0x84, 0x6c, 0x00, 0x00, 0x88, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x41, 0x98, 0x20, 0xf2, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x85, 0xb0, 0x01, 0x00, 0x98, 0x00, 0x2d, 0x14, 0x82, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x98, 0xb0, 0x01, 0x00, 0xa3, 0x00, 0x2d, 0x14,
-	0x98, 0xd0, 0x01, 0x00, 0x46, 0x98, 0x20, 0x4c, 0x84, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
-	0x80, 0xe0, 0x01, 0x00, 0x49, 0x98, 0x23, 0x40, 0x84, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x84, 0xb0, 0x01, 0x00, 0xd0, 0x00, 0x20, 0x14,
-	0xe0, 0xb1, 0x01, 0x00, 0x98, 0x00, 0x25, 0x42, 0x80, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x6e, 0xf3, 0x80, 0xf0, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x42,
-	0x82, 0xc0, 0x00, 0x00, 0x4f, 0x98, 0xa0, 0x40, 0x16, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x9f, 0xf0,
-	0x82, 0xec, 0x00, 0x00, 0x98, 0x00, 0xa0, 0x41, 0xe0, 0xb1, 0x01, 0x00,
-	0x52, 0x98, 0x00, 0x12, 0x10, 0xc9, 0x00, 0x00, 0x00, 0x48, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0xc0, 0x49, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x80, 0x4b, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x40, 0x4d, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0x4f, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0xc0, 0x50, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x52, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x40, 0x54, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0x56, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x57, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x80, 0x59, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x40, 0x5b, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x5d, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0xc0, 0x5e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x80, 0x60, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x40, 0x62, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0x64, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0xc0, 0x65, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x67, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x40, 0x69, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0x6b, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x6c, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x80, 0x6e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x40, 0x70, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x72, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0xc0, 0x73, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x80, 0x75, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x40, 0x77, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0x79, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0xc0, 0x7a, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x7c, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x40, 0x7e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x72, 0x98, 0x43, 0x57, 0x61, 0x31, 0x00, 0x00, 0x7e, 0x98, 0xa2, 0x57,
-	0x73, 0x7d, 0x00, 0x00, 0x7e, 0x98, 0xa2, 0x40, 0x81, 0x6f, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x10, 0x00, 0x4a,
-	0x62, 0xdd, 0x01, 0x00, 0x76, 0x98, 0xa8, 0x4a, 0x80, 0x33, 0x00, 0x00,
-	0x7b, 0x98, 0x22, 0x5f, 0x95, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x62, 0xb1, 0x01, 0x00, 0x79, 0x98, 0xa8, 0x4b, 0xac, 0x33, 0x00, 0x00,
-	0x00, 0x00, 0x1b, 0xa5, 0x82, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xbe,
-	0x83, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x97, 0xb0, 0x01, 0x00,
-	0x00, 0x10, 0x00, 0x4a, 0x62, 0xdd, 0x01, 0x00, 0x82, 0x98, 0x28, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x7e, 0x98, 0x22, 0x57, 0x77, 0x7d, 0x00, 0x00,
-	0x00, 0x00, 0x9b, 0x20, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x62, 0xb1, 0x01, 0x00, 0x82, 0x98, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x9b, 0x40, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
-	0x48, 0xb1, 0x01, 0x00, 0xa8, 0x01, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0xf0, 0xb1, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
-	0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x60, 0xa7, 0x97, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x8a, 0x98, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xa8, 0x00, 0x2d, 0x1c, 0x8a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x9f, 0xf0,
-	0x8a, 0xd0, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x40, 0x8b, 0xec, 0x00, 0x00,
-	0x8a, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xb4, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0xa4, 0x00, 0x2d, 0x45, 0xe0, 0xd1, 0x01, 0x00,
-	0x97, 0x98, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00, 0xbe, 0x00, 0x2f, 0xab,
-	0x83, 0xb0, 0x01, 0x00, 0xff, 0x98, 0x00, 0x14, 0x82, 0x50, 0x01, 0x00,
-	0x9c, 0x98, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x9c, 0x98, 0x22, 0xf2,
-	0x82, 0x30, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x9c, 0x98, 0x9f, 0x1c, 0xe0, 0x6d, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0xff, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xa8, 0x00, 0x20, 0x1c, 0xe0, 0xb1, 0x01, 0x00, 0x9c, 0x00, 0x2d, 0x30,
-	0x81, 0xb0, 0x01, 0x00, 0x88, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00,
-	0x94, 0x00, 0x2d, 0xf2, 0x86, 0xb0, 0x01, 0x00, 0xc6, 0x98, 0x23, 0xf0,
-	0x84, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x42, 0x88, 0xf4, 0x01, 0x00,
-	0xc6, 0x98, 0x20, 0x50, 0x89, 0x6c, 0x00, 0x00, 0xb5, 0x98, 0xa3, 0x92,
-	0x87, 0x6c, 0x00, 0x00, 0xa5, 0x98, 0x00, 0x44, 0x10, 0xc9, 0x00, 0x00,
-	0xc6, 0x98, 0x00, 0x0a, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x09,
-	0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x08, 0x87, 0xb0, 0x00, 0x00,
-	0xc6, 0x98, 0x00, 0x07, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x07,
-	0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x07, 0x87, 0xb0, 0x00, 0x00,
-	0xc6, 0x98, 0x00, 0x06, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x06,
-	0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x06, 0x87, 0xb0, 0x00, 0x00,
-	0xc6, 0x98, 0x00, 0x06, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x06,
-	0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x05, 0x87, 0xb0, 0x00, 0x00,
-	0xc6, 0x98, 0x00, 0x05, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x05,
-	0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x05, 0x87, 0xb0, 0x00, 0x00,
-	0xc6, 0x98, 0x00, 0x05, 0x87, 0xb0, 0x00, 0x00, 0xb6, 0x98, 0x00, 0x44,
-	0x10, 0xc9, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0f, 0x87, 0xb0, 0x00, 0x00,
-	0xc6, 0x98, 0x00, 0x0e, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0d,
-	0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0c, 0x87, 0xb0, 0x00, 0x00,
-	0xc6, 0x98, 0x00, 0x0c, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0c,
-	0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0c, 0x87, 0xb0, 0x00, 0x00,
-	0xc6, 0x98, 0x00, 0x0c, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0c,
-	0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0b, 0x87, 0xb0, 0x00, 0x00,
-	0xc6, 0x98, 0x00, 0x0b, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0b,
-	0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0b, 0x87, 0xb0, 0x00, 0x00,
-	0xc6, 0x98, 0x00, 0x0b, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0b,
-	0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0b, 0x87, 0xb0, 0x00, 0x00,
-	0xbf, 0x00, 0x2d, 0x43, 0x84, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf3,
-	0x80, 0xe0, 0x01, 0x00, 0xcb, 0x98, 0x23, 0x40, 0x84, 0x6c, 0x00, 0x00,
-	0x94, 0x00, 0x20, 0x9d, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x84, 0xb0, 0x01, 0x00, 0xcf, 0x98, 0xa2, 0xf0, 0x38, 0x6c, 0x00, 0x00,
-	0x9c, 0x00, 0x20, 0x42, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0x13, 0x94, 0x01, 0x00, 0x00, 0x00, 0x80, 0x46, 0x19, 0x80, 0x01, 0x00,
-	0x9c, 0x00, 0x20, 0x42, 0xe0, 0xb1, 0x01, 0x00, 0x37, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3, 0x80, 0xf4, 0x01, 0x00,
-	0x0f, 0x00, 0x00, 0xf3, 0x82, 0x88, 0x01, 0x00, 0xd5, 0x98, 0x23, 0x41,
-	0x80, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x13, 0x94, 0x01, 0x00,
-	0x00, 0x00, 0x89, 0x0c, 0x80, 0xb2, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0xa0, 0x00, 0xa0, 0xf2, 0xe4, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x9f, 0x41, 0x24, 0xec, 0x00, 0x00, 0xdf, 0x98, 0xa6, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x42, 0x38, 0xec, 0x00, 0x00,
-	0xdf, 0x98, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0xe1, 0x98, 0xa3, 0xf0, 0x3a, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xb4, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0xe5, 0x98, 0x22, 0xf0, 0x3a, 0x6c, 0x00, 0x00,
-	0xb4, 0x00, 0x20, 0x1d, 0xe0, 0xb1, 0x01, 0x00, 0x80, 0x00, 0x2d, 0x5f,
-	0x13, 0x94, 0x01, 0x00, 0xe5, 0x98, 0x23, 0xf0, 0x3a, 0x6c, 0x00, 0x00,
-	0x80, 0x00, 0x20, 0x1d, 0xe0, 0xb1, 0x01, 0x00, 0xc0, 0x00, 0x20, 0x12,
-	0xe0, 0xb1, 0x01, 0x00, 0xc4, 0x00, 0xa0, 0x1c, 0xe0, 0xb1, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0xe0, 0xb1, 0x01, 0x00, 0x12, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
-	0xee, 0x98, 0x9f, 0x41, 0x24, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x12, 0x8c, 0xd0, 0x01, 0x00,
-	0xef, 0x98, 0x00, 0x41, 0x24, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x8d, 0xb0, 0x01, 0x00, 0x3d, 0x99, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xf1, 0x98, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xbf, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x08, 0x80, 0x32, 0x01, 0x00,
-	0xf8, 0x98, 0xa2, 0x40, 0x95, 0x6c, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x82, 0x00, 0xa6, 0x04, 0xb0, 0x01, 0x00,
-	0xa0, 0x98, 0x2f, 0x40, 0x11, 0xb0, 0x01, 0x00, 0xe3, 0x89, 0x00, 0x41,
-	0x89, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x9f, 0xf8, 0x3e, 0xec, 0x00, 0x00,
-	0x00, 0x00, 0x9f, 0x12, 0xe0, 0xed, 0x00, 0x00, 0xc8, 0x00, 0x20, 0xab,
-	0xe1, 0xb1, 0x01, 0x00, 0xcc, 0x00, 0xa0, 0x1f, 0xe0, 0xb1, 0x01, 0x00,
-	0x01, 0x99, 0xa3, 0x5f, 0xe7, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0xe7, 0xc1, 0x01, 0x00, 0xa6, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x15, 0x99, 0x22, 0xf2, 0x86, 0x30, 0x00, 0x00, 0x03, 0x00, 0x00, 0x43,
-	0x84, 0xf4, 0x01, 0x00, 0x01, 0x00, 0x00, 0x41, 0x80, 0xcc, 0x01, 0x00,
-	0xb8, 0x00, 0x2d, 0x42, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x62, 0x40,
-	0x86, 0xc0, 0x01, 0x00, 0x09, 0x99, 0x1f, 0x43, 0x80, 0x32, 0x00, 0x00,
-	0x0a, 0x99, 0xa2, 0x40, 0x87, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x62, 0x41,
-	0x87, 0xb0, 0x01, 0x00, 0x0e, 0x99, 0x9f, 0x40, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x84, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x80, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf2, 0x88, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x00, 0x44,
-	0x84, 0xf4, 0x01, 0x00, 0xb8, 0x00, 0x2e, 0x42, 0x80, 0xd0, 0x01, 0x00,
-	0x00, 0x00, 0x62, 0x40, 0x88, 0xc0, 0x01, 0x00, 0x14, 0x99, 0x1f, 0x44,
-	0x80, 0x32, 0x00, 0x00, 0x18, 0x99, 0xa2, 0x40, 0x89, 0x6c, 0x00, 0x00,
-	0x18, 0x99, 0x62, 0x41, 0x89, 0xb0, 0x00, 0x00, 0x03, 0x00, 0x62, 0x41,
-	0x86, 0xe4, 0x01, 0x00, 0xb8, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
-	0x01, 0x00, 0x62, 0x41, 0x88, 0xe4, 0x01, 0x00, 0xa4, 0x00, 0x20, 0x40,
-	0xe5, 0xb1, 0x01, 0x00, 0xa2, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
-	0xbc, 0x00, 0x2e, 0x43, 0x87, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x86, 0xc0, 0x01, 0x00, 0x1e, 0x99, 0x20, 0x43, 0x87, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x43, 0xe5, 0xb1, 0x01, 0x00, 0x40, 0x01, 0x00, 0x43,
-	0x80, 0xce, 0x01, 0x00, 0x00, 0x00, 0xa4, 0x43, 0xe4, 0x31, 0x01, 0x00,
-	0x40, 0x01, 0xe2, 0x40, 0x87, 0x98, 0x01, 0x00, 0x88, 0x00, 0x2d, 0x44,
-	0x81, 0xb0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf2, 0x2e, 0xb0, 0x01, 0x00,
-	0x9c, 0x00, 0x2d, 0xf0, 0x86, 0xb0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0,
-	0x82, 0xb0, 0x01, 0x00, 0xba, 0x00, 0x2d, 0xf0, 0x98, 0xb0, 0x01, 0x00,
-	0x2b, 0x99, 0xa2, 0x12, 0x98, 0x6c, 0x00, 0x00, 0xbc, 0x00, 0x2d, 0xf2,
-	0x98, 0xb0, 0x01, 0x00, 0x2b, 0x99, 0xa0, 0xf2, 0x98, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x17, 0x82, 0xb0, 0x01, 0x00, 0x9c, 0x00, 0x20, 0x41,
-	0xe0, 0xb1, 0x01, 0x00, 0xb4, 0x00, 0x2d, 0x12, 0x86, 0xd0, 0x01, 0x00,
-	0x2e, 0x99, 0xa3, 0x41, 0xe0, 0x6d, 0x00, 0x00, 0x2f, 0x99, 0x00, 0xf0,
-	0x84, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x84, 0xb0, 0x01, 0x00,
-	0x80, 0x00, 0x2d, 0x43, 0x84, 0xd0, 0x01, 0x00, 0x32, 0x99, 0x9f, 0x42,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00,
-	0x34, 0x99, 0xa3, 0x42, 0x14, 0x6c, 0x00, 0x00, 0x35, 0x99, 0x00, 0x0a,
-	0x0c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x0c, 0xb0, 0x01, 0x00,
-	0x37, 0x99, 0xa0, 0x17, 0x0c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x17,
-	0x0c, 0xb0, 0x01, 0x00, 0x3c, 0x99, 0x22, 0x40, 0x0d, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0xa0, 0x0a, 0x0c, 0xec, 0x00, 0x00, 0x01, 0x00, 0x00, 0xf0,
-	0x82, 0xf4, 0x01, 0x00, 0x3c, 0x99, 0xa0, 0x41, 0x0c, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0xa2, 0xf0, 0x80, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb0, 0x01, 0x00, 0xd0, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x04, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x60, 0x41, 0x87, 0x94, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5d, 0x05, 0x90, 0x00, 0x00,
-	0x48, 0x99, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x4b,
-	0x19, 0x90, 0x01, 0x00, 0x05, 0x00, 0x2a, 0x0c, 0xe4, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x04, 0xe6, 0xb1, 0x01, 0x00, 0x52, 0x99, 0x22, 0x49,
-	0x1f, 0x7c, 0x00, 0x00, 0x42, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x49, 0x1f, 0x80, 0x01, 0x00, 0xaa, 0x97, 0x00, 0x40,
-	0x8d, 0xb0, 0x00, 0x00, 0x58, 0x99, 0x22, 0x40, 0xaf, 0x6f, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x15, 0x96, 0xb0, 0x01, 0x00, 0x72, 0x98, 0x00, 0x08,
-	0x94, 0x30, 0x01, 0x00, 0x57, 0x99, 0x22, 0x40, 0x97, 0x6c, 0x00, 0x00,
-	0xaa, 0x97, 0x00, 0x46, 0x87, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x87, 0xb0, 0x01, 0x00, 0x58, 0x99, 0x43, 0x48, 0x61, 0x31, 0x00, 0x00,
-	0x00, 0x10, 0x00, 0x08, 0x62, 0xdd, 0x01, 0x00, 0x5d, 0x99, 0x28, 0x40,
-	0x87, 0x30, 0x00, 0x00, 0x59, 0x99, 0x22, 0x48, 0x77, 0x7d, 0x00, 0x00,
-	0xaa, 0x97, 0x1b, 0x46, 0x87, 0xb0, 0x00, 0x00, 0x60, 0x99, 0x22, 0x5f,
-	0x11, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x15, 0x62, 0x31, 0x00, 0x00,
-	0x5e, 0x99, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00,
-	0x30, 0x00, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x93, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1f, 0xb0, 0x01, 0x00,
-	0xb1, 0x99, 0x00, 0x49, 0x96, 0x30, 0x01, 0x00, 0x07, 0x00, 0x00, 0x49,
-	0x06, 0xe4, 0x01, 0x00, 0x00, 0x39, 0x00, 0x03, 0x06, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0xd0,
-	0xa0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00,
-	0x65, 0x99, 0xa0, 0x54, 0x93, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x05,
-	0x97, 0xb0, 0x01, 0x00, 0x00, 0x48, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0xc0, 0x01, 0x00, 0xa2,
-	0x44, 0xc9, 0x01, 0x00, 0x6e, 0x99, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x20, 0x49, 0xb3, 0x01, 0x00, 0xb6, 0x99, 0x00, 0x40,
-	0x49, 0x31, 0x01, 0x00, 0x00, 0xb5, 0x2e, 0x08, 0x97, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x74, 0x99, 0xa2, 0x41,
-	0x97, 0x50, 0x00, 0x00, 0x18, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
-	0x00, 0x97, 0x2e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0x78, 0x99, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x40, 0x18, 0x2e, 0x05,
-	0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
-	0x7c, 0x99, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x57, 0x95, 0x20, 0x40,
-	0xe7, 0xb1, 0x01, 0x00, 0x30, 0x94, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
-	0x64, 0x00, 0x00, 0x40, 0xe5, 0x99, 0x01, 0x00, 0x56, 0x95, 0x20, 0x40,
-	0xe7, 0xb1, 0x01, 0x00, 0xb8, 0x94, 0x20, 0x41, 0xe5, 0xb1, 0x01, 0x00,
-	0xba, 0x94, 0x20, 0x41, 0xe5, 0xb1, 0x01, 0x00, 0x98, 0x94, 0x00, 0x40,
-	0x45, 0x99, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x86, 0x99, 0xa2, 0x41,
-	0x97, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x6f, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x68, 0xb1, 0x01, 0x00, 0x8a, 0x99, 0x85, 0x41, 0x97, 0x40, 0x00, 0x00,
-	0xc3, 0x99, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x39, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x37, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x35, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x33, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x41, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x3f, 0xb3, 0x01, 0x00, 0x3c, 0x00, 0x00, 0x40,
-	0x29, 0x9b, 0x01, 0x00, 0xee, 0x05, 0x00, 0x40, 0x25, 0x9b, 0x01, 0x00,
-	0x42, 0x00, 0x00, 0x40, 0x4b, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x2f, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2d, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x47, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x43, 0xb3, 0x01, 0x00, 0x60, 0x00, 0x00, 0x40, 0x2b, 0x9b, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x54, 0xef, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55,
-	0xf1, 0x93, 0x01, 0x00, 0xff, 0xff, 0x00, 0xa5, 0x3c, 0x8b, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x2c, 0x5b, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x2c,
-	0x45, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x59, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x57, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x27, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x53, 0xb3, 0x01, 0x00,
-	0xa7, 0x99, 0xa2, 0x50, 0xfd, 0x7f, 0x00, 0x00, 0xa7, 0x99, 0xa2, 0x51,
-	0xfd, 0x7f, 0x00, 0x00, 0xa8, 0x99, 0x00, 0x40, 0x1d, 0xb3, 0x00, 0x00,
-	0x50, 0x46, 0x00, 0x40, 0x1d, 0x9b, 0x01, 0x00, 0x00, 0xc0, 0x00, 0xa6,
-	0x88, 0xb3, 0x01, 0x00, 0xff, 0x3f, 0x00, 0xa6, 0x3a, 0xb3, 0x01, 0x00,
-	0x00, 0xc0, 0x00, 0x9d, 0x3b, 0x9b, 0x01, 0x00, 0xb4, 0x05, 0x00, 0x40,
-	0x23, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x4d, 0xb3, 0x01, 0x00,
-	0x08, 0x0a, 0x00, 0xa6, 0x14, 0xb3, 0x01, 0x00, 0x01, 0x01, 0x00, 0x8a,
-	0x15, 0x9b, 0x01, 0x00, 0x00, 0x80, 0x00, 0xa6, 0x56, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x5e, 0x57, 0xb5, 0x01, 0x00, 0x18, 0x00, 0x00, 0x4b,
-	0x20, 0xe4, 0x01, 0x00, 0x06, 0x00, 0x00, 0x4b, 0x96, 0xe4, 0x01, 0x00,
-	0x00, 0x43, 0x00, 0x4b, 0x96, 0xc8, 0x01, 0x00, 0x18, 0x00, 0x00, 0x10,
-	0x20, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x80, 0x4b, 0x20, 0x94, 0x01, 0x00,
-	0x00, 0x99, 0x2e, 0x0a, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0xb7, 0x99, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
-	0x00, 0x03, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00, 0x00, 0xa9, 0x00, 0x40,
-	0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
-	0xbb, 0x99, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40,
-	0x97, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55, 0x61, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00, 0xbf, 0x99, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xbf, 0x99, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x87, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4b, 0x80, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6,
-	0x82, 0xb1, 0x01, 0x00, 0xc5, 0x99, 0x85, 0x41, 0x97, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x97, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x90, 0xb1, 0x01, 0x00,
-	0x01, 0x00, 0x00, 0xa6, 0x92, 0xb1, 0x01, 0x00, 0xca, 0x99, 0x85, 0x41,
-	0x97, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0xce, 0x99, 0x44, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
-	0x80, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x9c, 0x4b, 0x82, 0x89, 0x01, 0x00,
-	0xd1, 0x99, 0x44, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a,
-	0x80, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x9c, 0xa6, 0x82, 0xb1, 0x01, 0x00,
-	0xd4, 0x99, 0x44, 0x40, 0x81, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4b,
-	0x84, 0x89, 0x01, 0x00, 0x00, 0x00, 0x9c, 0xc2, 0x24, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x80, 0x4b,
-	0x92, 0x89, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00,
-	0x01, 0x00, 0x80, 0xa6, 0x92, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0x4b,
-	0x94, 0x89, 0x01, 0x00, 0x00, 0x00, 0x80, 0xca, 0x94, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x81, 0xb0, 0x01, 0x00, 0xdf, 0x99, 0x80, 0xa5, 0x80, 0x32, 0x00, 0x00,
-	0xe0, 0x99, 0x00, 0xa5, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x81, 0xc0, 0x01, 0x00, 0xe1, 0x99, 0x80, 0xa5, 0x80, 0x32, 0x00, 0x00,
-	0x80, 0x01, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00, 0xea, 0x99, 0x20, 0x4f,
-	0x81, 0x6c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
-	0xea, 0x99, 0x20, 0x4b, 0x81, 0x6c, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40,
-	0x83, 0x98, 0x01, 0x00, 0xea, 0x99, 0x20, 0x47, 0x81, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x82, 0xdc, 0x01, 0x00, 0x03, 0x90, 0x00, 0x41, 0x20, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x14, 0x2f, 0x4c,
-	0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
-	0xee, 0x99, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x64, 0x00, 0x00, 0xa5,
-	0x80, 0xc8, 0x01, 0x00, 0xf1, 0x99, 0xa2, 0xa5, 0x80, 0x6c, 0x00, 0x00,
-	0x20, 0x00, 0x00, 0x90, 0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0x23, 0x91, 0x01, 0x00, 0xf4, 0x99, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
-	0x30, 0x00, 0x00, 0x90, 0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0x23, 0x91, 0x01, 0x00, 0xf7, 0x99, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
-	0x70, 0x00, 0x00, 0x90, 0x20, 0xa9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0x23, 0x91, 0x01, 0x00, 0xfa, 0x99, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x23, 0x91, 0x01, 0x00, 0xfc, 0x99, 0x1f, 0x91,
-	0x80, 0x32, 0x00, 0x00, 0x40, 0x68, 0x00, 0x90, 0x20, 0xa9, 0x01, 0x00,
-	0xe0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x21, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0x22, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x23, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x24, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0x25, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x26, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x27, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0xd0, 0x14, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00,
-	0x30, 0x03, 0x00, 0x40, 0x85, 0x30, 0x01, 0x00, 0xd0, 0x14, 0x00, 0x40,
-	0x45, 0x99, 0x01, 0x00, 0x02, 0x01, 0x00, 0xa6, 0x80, 0xb0, 0x01, 0x00,
-	0x04, 0x03, 0x00, 0x40, 0x80, 0x98, 0x01, 0x00, 0x06, 0x05, 0x00, 0xa6,
-	0x82, 0xb0, 0x01, 0x00, 0x08, 0x07, 0x00, 0x41, 0x82, 0x98, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0xe0, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40, 0x85, 0x98, 0x01, 0x00,
-	0x30, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x39, 0x03, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xd8, 0x14, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0xff, 0x02, 0xa2, 0xf8, 0x80, 0x6c, 0x00, 0x00, 0x00, 0x03, 0x22, 0xf0,
-	0x82, 0x6c, 0x00, 0x00, 0xff, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xd0, 0x14, 0x2e, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40,
-	0xa3, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xc1, 0xb3, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0xdd, 0x81, 0xf4, 0x01, 0x00, 0x1e, 0x9a, 0x00, 0x40,
-	0x10, 0xc9, 0x00, 0x00, 0x24, 0x9a, 0x00, 0x05, 0x81, 0xb0, 0x00, 0x00,
-	0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2c, 0x9a, 0x00, 0x05,
-	0x81, 0xb0, 0x00, 0x00, 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x31, 0x9a, 0x00, 0x44, 0xa5, 0xb3, 0x00, 0x00, 0x33, 0x9a, 0x00, 0x44,
-	0xa5, 0xb3, 0x00, 0x00, 0x02, 0x00, 0x00, 0x40, 0xa4, 0xe7, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xe0, 0x81, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0xc1,
-	0xf0, 0x89, 0x01, 0x00, 0x29, 0x9a, 0x22, 0x41, 0x81, 0x50, 0x00, 0x00,
-	0x25, 0x9a, 0x00, 0x41, 0xc1, 0xc3, 0x00, 0x00, 0xb1, 0x02, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xc5, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x5a, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x02, 0x00, 0x00, 0x40,
-	0xa4, 0xe7, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x91, 0xb1, 0x01, 0x00,
-	0xff, 0xff, 0x00, 0xc9, 0xf0, 0x89, 0x01, 0x00, 0x29, 0x9a, 0x22, 0x41,
-	0x81, 0x50, 0x00, 0x00, 0x2d, 0x9a, 0x00, 0x41, 0xc1, 0xc3, 0x00, 0x00,
-	0xff, 0xff, 0x00, 0xde, 0x85, 0x89, 0x01, 0x00, 0x29, 0x9a, 0x00, 0xc2,
-	0xe0, 0xb1, 0x00, 0x00, 0xff, 0xff, 0x00, 0xde, 0x95, 0x89, 0x01, 0x00,
-	0x29, 0x9a, 0x00, 0xca, 0xe0, 0xb1, 0x00, 0x00, 0x04, 0x00, 0x00, 0xcb,
-	0x81, 0xc8, 0x01, 0x00, 0x6a, 0x84, 0x00, 0x40, 0xf2, 0x93, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xb6, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00, 0xb6, 0x9f, 0x00, 0x88,
-	0x9a, 0xb0, 0x00, 0x00, 0xb6, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00,
-	0xb6, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00, 0xb6, 0x9f, 0x00, 0x88,
-	0x9a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x9a, 0xb0, 0x01, 0x00,
-	0xb6, 0x9f, 0x41, 0x40, 0x81, 0x32, 0x00, 0x00, 0xb9, 0x9f, 0x22, 0x40,
-	0x7b, 0x6f, 0x00, 0x00, 0xb6, 0x9f, 0x19, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x19, 0x41, 0x7b, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4,
-	0xc4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xc6, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x2f, 0xa2, 0xc8, 0xb3, 0x01, 0x00, 0x08, 0x14, 0x00, 0x40,
-	0x49, 0x99, 0x01, 0x00, 0xb0, 0x9f, 0x00, 0x4d, 0x9a, 0xcc, 0x01, 0x00,
-	0xc2, 0x9f, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0x49, 0xc1, 0x01, 0x00, 0xc0, 0x9f, 0xa2, 0x41, 0x9b, 0x50, 0x00, 0x00,
-	0xc6, 0x9f, 0x80, 0x80, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x52, 0x49,
-	0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0xfd, 0x93, 0x01, 0x00,
-	0xc9, 0x9f, 0x00, 0x42, 0xcd, 0x93, 0x00, 0x00, 0x00, 0x00, 0x51, 0x4a,
-	0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49, 0xfd, 0x93, 0x01, 0x00,
-	0xc9, 0x9f, 0x00, 0x43, 0xcb, 0x93, 0x00, 0x00, 0x00, 0x00, 0x50, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0xd9, 0x9f, 0x00, 0x40, 0x19, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x9a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x49, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x40, 0xf0, 0x80, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x41, 0x4d, 0x80, 0xb2, 0x01, 0x00, 0xd1, 0x9f, 0x00, 0x40,
-	0x19, 0x99, 0x01, 0x00, 0x00, 0x00, 0x4c, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x49, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x9a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x10, 0xb1, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xe2, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe3,
-	0x43, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x45, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x7b, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x48, 0x4f,
-	0x40, 0xb1, 0x01, 0x00, 0xd9, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x6a, 0x84, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x19, 0x9a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x35, 0x9a, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa8,
-	0x10, 0xb1, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00,
-	},
-};
diff --git a/drivers/staging/slicoss/gbrcvucode.h b/drivers/staging/slicoss/gbrcvucode.h
deleted file mode 100644
index 4fa5a4c..0000000
--- a/drivers/staging/slicoss/gbrcvucode.h
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (c) 1997-2002 Alacritech, 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:
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``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 ALACRITECH, INC. 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.
- *
- * The views and conclusions contained in the software and documentation
- * are those of the authors and should not be interpreted as representing
- * official policies, either expressed or implied, of Alacritech, Inc.
- *
- **************************************************************************/
-#define GB_RCVUCODE_VERS_STRING	"1.2"
-#define GB_RCVUCODE_VERS_DATE  	"2006/03/27 15:12:15"
-
-static u32 GBRcvUCodeLen = 512;
-
-static u8 GBRcvUCode[2560] =
-{
-0x47, 0x75, 0x01, 0x00, 0x04, 0xa0, 0x13, 0x01, 0x00, 0x1c, 0xb7, 0x5b, 0x09,
-0x30, 0x00, 0xb6, 0x5f, 0x01, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x20, 0x18, 0x3b,
-0x78, 0x3a, 0x00, 0x1c, 0xa2, 0x77, 0x01, 0x00, 0x1c, 0x07, 0x1d, 0x01, 0x70,
-0x18, 0xb3, 0x7b, 0xa9, 0xaa, 0x1e, 0xb4, 0x7b, 0x01, 0x0c, 0x1c, 0xb5, 0x7b,
-0x1d, 0x06, 0x1c, 0x00, 0x00, 0x40, 0x64, 0x08, 0x0c, 0x31, 0x56, 0x70, 0x04,
-0x0c, 0x31, 0x56, 0x80, 0x04, 0x0c, 0x31, 0x4a, 0x90, 0x04, 0x0c, 0x31, 0x46,
-0xa0, 0x00, 0x09, 0x25, 0x51, 0xc0, 0x04, 0x0c, 0x31, 0x4e, 0xb0, 0x00, 0xe9,
-0x24, 0x51, 0xc0, 0x04, 0xcc, 0xb3, 0x00, 0x1c, 0x1c, 0xeb, 0x2d, 0x01, 0x00,
-0x1c, 0x06, 0x56, 0x42, 0xd4, 0x08, 0x07, 0x9d, 0x00, 0x00, 0x1c, 0x7b, 0xb7,
-0x02, 0x00, 0x10, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0x06, 0x56, 0x5a, 0xc0, 0x04,
-0xa0, 0x30, 0x6c, 0x03, 0x00, 0xac, 0x30, 0x6d, 0x03, 0x00, 0xcd, 0x03, 0x3a,
-0x00, 0x1c, 0x7b, 0xb7, 0x02, 0x00, 0x1c, 0x60, 0x8e, 0x41, 0x54, 0x09, 0x29,
-0x25, 0x6d, 0x03, 0x00, 0x80, 0x8e, 0x41, 0x54, 0x09, 0x8c, 0x30, 0x8d, 0x00,
-0x04, 0x47, 0x1c, 0x01, 0x00, 0x1c, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0x00, 0x00,
-0x60, 0x00, 0x04, 0x47, 0x1c, 0x61, 0xc0, 0x04, 0x47, 0x1c, 0x6d, 0x03, 0x00,
-0x6c, 0x30, 0x01, 0x00, 0x1c, 0x4d, 0x34, 0x02, 0x00, 0x1c, 0x7b, 0xb7, 0x02,
-0x00, 0x1c, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0xc8, 0x83, 0x37, 0x00, 0x1c, 0x80,
-0x01, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x60, 0x00, 0x04, 0xa0, 0x0f, 0x40, 0x54,
-0x09, 0x00, 0x00, 0x6c, 0xc3, 0x04, 0x7b, 0xfb, 0xf2, 0x00, 0x1c, 0xcc, 0x33,
-0x0d, 0x00, 0x1c, 0xb4, 0x7b, 0xfd, 0x03, 0x1c, 0x80, 0x0e, 0x40, 0x54, 0x09,
-0xe0, 0xfb, 0x05, 0x00, 0x1c, 0x00, 0x00, 0xa0, 0x03, 0x00, 0xb3, 0x0f, 0x41,
-0x54, 0x09, 0x00, 0x00, 0xe8, 0x70, 0x04, 0x00, 0x00, 0xe8, 0x80, 0x04, 0x00,
-0x00, 0xa0, 0x93, 0x00, 0x61, 0x76, 0xa1, 0xc3, 0x04, 0xc0, 0x8d, 0x41, 0x54,
-0x09, 0xe0, 0x7b, 0x00, 0xc0, 0x1f, 0xa0, 0xfd, 0xc1, 0x01, 0x00, 0xcc, 0x33,
-0x05, 0x00, 0x1c, 0xd4, 0x03, 0x00, 0x3c, 0x1c, 0xd4, 0xd3, 0x1b, 0x00, 0x1c,
-0xc0, 0xd3, 0x52, 0x00, 0x1c, 0x00, 0x00, 0x74, 0x13, 0x04, 0x8e, 0x8e, 0x42,
-0x54, 0x09, 0x5b, 0x80, 0x76, 0x13, 0x04, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00,
-0x00, 0x90, 0x01, 0x00, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0xa0, 0x0f, 0x41, 0x54,
-0x09, 0xc0, 0x03, 0xfc, 0x7f, 0x1c, 0xa0, 0x01, 0x9c, 0x01, 0x00, 0x00, 0x00,
-0xa0, 0x01, 0x00, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0xc0, 0x03, 0xfc, 0x03, 0x1c,
-0xf5, 0x77, 0x01, 0x00, 0x1c, 0x26, 0x7a, 0xf6, 0x05, 0x1c, 0xa0, 0x0f, 0x41,
-0x54, 0x09, 0xb3, 0x0f, 0x41, 0x54, 0x09, 0xb5, 0x02, 0x02, 0x00, 0x1c, 0xa0,
-0x0f, 0x41, 0x54, 0x09, 0x7a, 0x06, 0x02, 0x00, 0x1c, 0xb5, 0x02, 0x02, 0x00,
-0x1c, 0x53, 0x0f, 0x42, 0x54, 0x09, 0xaf, 0x03, 0x01, 0x00, 0x1c, 0x7a, 0x0e,
-0x42, 0x54, 0x09, 0xb5, 0x02, 0x02, 0x00, 0x1c, 0x00, 0x00, 0x02, 0x00, 0x1c,
-0xa0, 0x3d, 0xa6, 0x11, 0x04, 0x00, 0x00, 0xa8, 0x11, 0x04, 0xd4, 0xd3, 0x52,
-0x00, 0x1c, 0xb5, 0x3e, 0xae, 0x01, 0x00, 0x20, 0xfb, 0xfd, 0xff, 0x1f, 0x80,
-0x2c, 0x84, 0x03, 0x00, 0xb9, 0x3a, 0x9a, 0x01, 0x00, 0x75, 0x3b, 0x02, 0x00,
-0x1c, 0xa7, 0x1c, 0x01, 0x00, 0x10, 0xdb, 0x83, 0x16, 0x00, 0x1c, 0xc7, 0x1d,
-0x1d, 0xc1, 0x04, 0xb9, 0x3b, 0x89, 0xc1, 0x04, 0x8b, 0x2c, 0x01, 0x00, 0x1c,
-0x6b, 0x2c, 0x31, 0xc1, 0x04, 0x00, 0x00, 0x74, 0x11, 0x00, 0xcb, 0x2c, 0x75,
-0xc1, 0x04, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0x54,
-0xd0, 0x02, 0x00, 0x1c, 0x49, 0x25, 0xad, 0x01, 0x00, 0xab, 0x2c, 0x7d, 0xc1,
-0x04, 0xa7, 0x1d, 0x6d, 0x03, 0x00, 0xcc, 0x33, 0x09, 0x00, 0x1c, 0xeb, 0x2d,
-0x01, 0x00, 0x1c, 0xea, 0x29, 0x01, 0x00, 0x1c, 0xa0, 0x0f, 0x41, 0x54, 0x09,
-0xae, 0x0f, 0x41, 0x54, 0x09, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0xd4, 0x07, 0xfc,
-0x03, 0x1c, 0x99, 0x3a, 0x02, 0x00, 0x1c, 0xbb, 0x38, 0x02, 0x00, 0x1c, 0x00,
-0x38, 0x00, 0x00, 0x1c, 0x00, 0x00, 0xf8, 0x01, 0x04, 0xdb, 0x3b, 0x7e, 0x00,
-0x1c, 0xc7, 0x1d, 0x01, 0x00, 0x1c, 0x26, 0x7a, 0x0a, 0x06, 0x1c, 0x27, 0x1d,
-0x01, 0x00, 0x1c, 0xb3, 0x0f, 0x41, 0x54, 0x09, 0x7a, 0x0e, 0x42, 0x54, 0x09,
-0x53, 0x0f, 0x42, 0x54, 0x09, 0x7a, 0x0e, 0x42, 0x54, 0x09, 0x53, 0x0f, 0x42,
-0x54, 0x09, 0x7a, 0x0e, 0x42, 0x54, 0x09, 0x53, 0x0f, 0x42, 0x54, 0x09, 0xa0,
-0x0f, 0x41, 0x54, 0x09, 0x7a, 0x06, 0x02, 0x00, 0x1c, 0x53, 0x0f, 0x42, 0x54,
-0x09, 0xaf, 0x03, 0x01, 0x00, 0x1c, 0x7a, 0x0e, 0x42, 0x54, 0x09, 0x53, 0x0f,
-0x42, 0x54, 0x09, 0x7a, 0x0e, 0x42, 0x54, 0x09, 0x53, 0x0f, 0x42, 0x54, 0x09,
-0x7a, 0x0e, 0x42, 0x54, 0x09, 0x53, 0x0f, 0x42, 0x54, 0x09, 0x7a, 0x0e, 0x42,
-0x54, 0x09, 0x00, 0x3d, 0x02, 0x00, 0x1c, 0x00, 0x00, 0x54, 0x12, 0x00, 0xcb,
-0x2c, 0x01, 0x00, 0x1c, 0x75, 0x3b, 0x02, 0x00, 0x1c, 0xa7, 0x1c, 0x01, 0x00,
-0x10, 0xa6, 0x7b, 0xf1, 0x05, 0x1c, 0x00, 0x00, 0x88, 0xc2, 0x04, 0xa6, 0x7b,
-0xf1, 0x05, 0x1c, 0x00, 0x00, 0xa0, 0xc2, 0x04, 0xcb, 0x2f, 0x05, 0x00, 0x1c,
-0x60, 0x2c, 0x00, 0x00, 0x1c, 0xc7, 0x1c, 0xe1, 0x02, 0x00, 0x53, 0x0f, 0x42,
-0x54, 0x09, 0xc0, 0x83, 0xf1, 0x32, 0x1c, 0x00, 0x00, 0x5c, 0x02, 0x04, 0x46,
-0x7a, 0xda, 0x05, 0x1c, 0x7a, 0x0e, 0x42, 0x54, 0x09, 0xc0, 0x83, 0xf1, 0x32,
-0x1c, 0x00, 0x00, 0x64, 0x02, 0x04, 0x40, 0xfa, 0x15, 0x00, 0x1c, 0x00, 0x00,
-0xa0, 0x02, 0x04, 0x46, 0x7a, 0xda, 0x05, 0x1c, 0xa0, 0x0f, 0x41, 0x54, 0x09,
-0xa0, 0x0f, 0x41, 0x54, 0x09, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0xa0, 0x0f, 0x41,
-0x54, 0x09, 0xb3, 0x7b, 0x01, 0xc0, 0x1f, 0x74, 0x0e, 0x40, 0x54, 0x09, 0xc0,
-0x03, 0x9c, 0x00, 0x1c, 0x80, 0x00, 0xf0, 0x02, 0x00, 0x00, 0x00, 0xf0, 0x02,
-0x04, 0x00, 0x00, 0xc4, 0x12, 0x05, 0x07, 0x1d, 0x01, 0x00, 0x1c, 0xd4, 0xd3,
-0x2b, 0x00, 0x1c, 0xd4, 0xd3, 0x52, 0x00, 0x1c, 0x80, 0x76, 0x95, 0x13, 0x04,
-0x00, 0x00, 0xf8, 0x02, 0x00, 0xa6, 0x7b, 0xa9, 0x03, 0x10, 0xc7, 0x9c, 0x00,
-0x00, 0x1c, 0x80, 0x2c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x78, 0x02, 0x04, 0x00,
-0x00, 0x6c, 0xc3, 0x04, 0xab, 0x2d, 0xf1, 0x12, 0x05, 0x07, 0x1d, 0xcd, 0xc2,
-0x04, 0x8b, 0x2d, 0x01, 0x00, 0x1c, 0x69, 0x25, 0x01, 0x00, 0x1c, 0xa6, 0x7b,
-0xa9, 0x03, 0x10, 0xcb, 0x2f, 0x09, 0x00, 0x1c, 0x60, 0x2c, 0x00, 0x00, 0x1c,
-0x00, 0x00, 0x60, 0x03, 0x00, 0x53, 0x0f, 0x42, 0x54, 0x09, 0x46, 0x7a, 0xda,
-0x05, 0x1c, 0x7a, 0x0e, 0x42, 0x54, 0x09, 0x40, 0xfa, 0x15, 0x00, 0x1c, 0x00,
-0x00, 0x28, 0x03, 0x04, 0x46, 0x7a, 0xda, 0x05, 0x1c, 0xb5, 0x0f, 0x41, 0x54,
-0x09, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0x73, 0xec, 0x42, 0x03, 0x04, 0x60, 0x2c,
-0x00, 0x00, 0x1c, 0x00, 0x00, 0x40, 0x03, 0x00, 0xc7, 0x1c, 0x01, 0x00, 0x1c,
-0x00, 0x00, 0x40, 0x13, 0x05, 0x07, 0x1d, 0x01, 0x00, 0x1c, 0xc0, 0xd7, 0x22,
-0x00, 0x1c, 0x75, 0x56, 0x96, 0x13, 0x04, 0x60, 0x2c, 0x00, 0x00, 0x1c, 0xe7,
-0x1c, 0x5d, 0x03, 0x04, 0xe7, 0x9c, 0x00, 0x00, 0x1c, 0xa6, 0x7b, 0xa9, 0x03,
-0x10, 0x80, 0x2c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x10, 0x03, 0x04, 0x00, 0x00,
-0x6c, 0xc3, 0x04, 0xb9, 0x7b, 0x01, 0x00, 0x1c, 0x00, 0x00, 0xa0, 0xc3, 0x04,
-0xcb, 0xaf, 0xfc, 0x07, 0x1c, 0xcb, 0x2f, 0x01, 0x04, 0x1c, 0xc7, 0x9f, 0x80,
-0x03, 0x1c, 0x00, 0x00, 0xa0, 0xc3, 0x04, 0xcb, 0xaf, 0xfc, 0x07, 0x1c, 0xcb,
-0x2f, 0x0d, 0x04, 0x1c, 0xc7, 0x9f, 0x80, 0x03, 0x1c, 0x00, 0x00, 0xa0, 0xc3,
-0x04, 0xcb, 0xaf, 0x00, 0xf8, 0x1d, 0xcb, 0x2f, 0x01, 0x00, 0x1d, 0x00, 0x00,
-0xa0, 0xc3, 0x04, 0x00, 0x00, 0xa0, 0x13, 0x05, 0x07, 0x1d, 0x01, 0x00, 0x1c,
-0xc0, 0x1d, 0xf0, 0xd3, 0x08, 0x27, 0x9d, 0xf8, 0x03, 0x00, 0xa0, 0xee, 0x56,
-0xd4, 0x00, 0xfb, 0x75, 0x19, 0x14, 0x04, 0x20, 0x7b, 0x06, 0x00, 0x1c, 0xc0,
-0x1c, 0x2c, 0x04, 0x00, 0x00, 0x00, 0xc4, 0xd3, 0x08, 0x00, 0x00, 0x10, 0xf4,
-0x00, 0xc0, 0xef, 0xf2, 0x00, 0x1c, 0x20, 0x25, 0x6c, 0x14, 0x04, 0x60, 0xb7,
-0xe6, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x15, 0x00, 0xcc, 0xb3, 0xfc, 0x03, 0x1c,
-0xcc, 0x33, 0x05, 0x02, 0x1c, 0x00, 0x00, 0x1c, 0xc5, 0x04, 0x60, 0xb7, 0x1e,
-0x05, 0x04, 0x00, 0x00, 0x1c, 0x15, 0x04, 0x00, 0x00, 0x6c, 0xc4, 0x04, 0xc0,
-0x1d, 0xac, 0xf3, 0x04, 0x00, 0x00, 0x78, 0xc4, 0x04, 0x07, 0x9d, 0x00, 0x00,
-0x1c, 0x1b, 0x74, 0x0d, 0xf4, 0x04, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0xe0, 0x7b,
-0x00, 0xfc, 0x1f, 0x39, 0x7f, 0x02, 0x00, 0x1c, 0x07, 0x1d, 0xb1, 0xc3, 0x04,
-0xa6, 0x7b, 0xc1, 0x03, 0x1c, 0x00, 0x00, 0x78, 0xc4, 0x04, 0xe0, 0x1c, 0x00,
-0x00, 0x1c, 0x00, 0x00, 0xb8, 0x03, 0x04, 0xcb, 0xaf, 0x00, 0xf8, 0x1d, 0xcb,
-0x2f, 0x01, 0x10, 0x1d, 0x00, 0x00, 0xc0, 0xc3, 0x04, 0x00, 0x00, 0xc0, 0x03,
-0x04, 0xcb, 0xaf, 0x00, 0xf8, 0x1d, 0xcb, 0x2f, 0x01, 0x18, 0x1d, 0xc7, 0x9f,
-0x00, 0x0b, 0x1c, 0x00, 0x00, 0xc0, 0xc3, 0x04, 0xfb, 0x75, 0x01, 0x00, 0x1c,
-0x07, 0x1d, 0x01, 0x00, 0x1c, 0xcc, 0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x01,
-0x02, 0x1c, 0x00, 0x00, 0xc0, 0xc3, 0x04, 0xa0, 0x1c, 0x00, 0x00, 0x1c, 0xa0,
-0xee, 0xb6, 0x03, 0x04, 0xcb, 0xaf, 0xfc, 0x07, 0x1c, 0xcb, 0x2f, 0x09, 0x04,
-0x1c, 0xfb, 0x75, 0x01, 0x00, 0x1c, 0x00, 0x00, 0xc0, 0xc3, 0x04, 0xcc, 0xb3,
-0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x01, 0x02, 0x1c, 0x00, 0x00, 0x1c, 0xc5, 0x04,
-0x00, 0x00, 0x88, 0x34, 0x05, 0xcc, 0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x15,
-0x02, 0x1c, 0x47, 0x9d, 0x64, 0xc4, 0x04, 0x00, 0x00, 0x88, 0x44, 0x00, 0x80,
-0x1d, 0x8c, 0x54, 0x04, 0x87, 0x1d, 0x9d, 0x04, 0x00, 0xce, 0x76, 0x01, 0x00,
-0x1c, 0xef, 0x76, 0xad, 0xc4, 0x04, 0xa4, 0x77, 0x9d, 0x24, 0x09, 0xe4, 0x76,
-0x01, 0x00, 0x1c, 0xc4, 0x76, 0x01, 0x00, 0x1c, 0x00, 0x00, 0xa8, 0x54, 0x04,
-0xd7, 0x76, 0x01, 0x50, 0x18, 0xf6, 0x76, 0x01, 0x00, 0x1c, 0x00, 0x00, 0x00,
-0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10, 0xcc, 0x30, 0x51, 0xc5, 0x04, 0xeb,
-0x2d, 0x01, 0x00, 0x1c, 0xea, 0x29, 0x01, 0x00, 0x1c, 0xc0, 0x59, 0x01, 0x00,
-0x1c, 0xf5, 0x77, 0x39, 0xc5, 0x04, 0xe0, 0x30, 0xec, 0x04, 0x00, 0x00, 0x4c,
-0xc0, 0x04, 0x00, 0x20, 0x4c, 0x04, 0x05, 0x00, 0x00, 0x00, 0xf8, 0x04, 0x00,
-0xcc, 0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x09, 0x02, 0x1c, 0xeb, 0x2d, 0xc5,
-0xc4, 0x04, 0xcc, 0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x19, 0x02, 0x1c, 0xeb,
-0x2d, 0xc5, 0xc4, 0x04, 0xcc, 0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x0d, 0x02,
-0x1c, 0xeb, 0x2d, 0xc5, 0xc4, 0x04, 0xcc, 0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33,
-0x11, 0x02, 0x1c, 0xeb, 0x2d, 0xc5, 0xc4, 0x04, 0x00, 0x7b, 0x00, 0x80, 0x1c,
-0xae, 0x77, 0x51, 0x05, 0x00, 0x00, 0x00, 0x04, 0xc0, 0x04, 0xd3, 0x8b, 0x00,
-0xfc, 0x1f, 0x60, 0x7a, 0x3c, 0x00, 0x1c, 0x60, 0x4c, 0xd0, 0x04, 0x00, 0xc0,
-0x2f, 0x20, 0x05, 0x1f, 0xe0, 0x30, 0xc0, 0x04, 0x00, 0x80, 0x25, 0xc0, 0x04,
-0x00, 0xb5, 0x5b, 0xc1, 0x04, 0x04, 0x69, 0x26, 0x01, 0x00, 0x1c, 0x6a, 0x2b,
-0x01, 0x00, 0x1c, 0x80, 0x1d, 0x00, 0x00, 0x1c, 0xa9, 0x25, 0x51, 0x05, 0x00,
-0xee, 0x30, 0x00, 0x00, 0x1c, 0xaf, 0x77, 0x11, 0x05, 0x00, 0xb4, 0x5f, 0x01,
-0x40, 0x18, 0x07, 0x9d, 0x54, 0x55, 0x04, 0xb7, 0x76, 0x01, 0x00, 0x1c, 0x96,
-0x76, 0x01, 0x00, 0x1c, 0x47, 0x1d, 0x01, 0x00, 0x1c, 0xa4, 0x33, 0x01, 0x60,
-0x18, 0xa4, 0x2f, 0x01, 0x60, 0x18, 0x64, 0x77, 0x01, 0x60, 0x18, 0x24, 0x77,
-0x01, 0x60, 0x18, 0x44, 0x77, 0x01, 0x00, 0x1c, 0x64, 0x88, 0x03, 0x00, 0x1c,
-0xa4, 0x3f, 0x01, 0x00, 0x1c, 0xa4, 0x3b, 0x01, 0x00, 0x1c, 0x53, 0x77, 0x01,
-0x00, 0x1c, 0xd3, 0xcf, 0x3b, 0x00, 0x1c, 0x53, 0x4f, 0x02, 0x00, 0x1c, 0xd3,
-0xcf, 0x00, 0x00, 0x1f, 0xda, 0xcf, 0x0b, 0x00, 0x1c, 0xd5, 0x57, 0x0f, 0x00,
-0x1c, 0xd3, 0xd3, 0x37, 0x00, 0x1c, 0xd4, 0x53, 0x0f, 0x00, 0x1c, 0xe0, 0x29,
-0x00, 0x00, 0x1c, 0xf5, 0xd5, 0xc0, 0x05, 0x00, 0x00, 0x00, 0xac, 0x55, 0x04,
-0x77, 0x56, 0x01, 0x00, 0x1c, 0x56, 0x53, 0x01, 0x00, 0x1c, 0x00, 0x00, 0x00,
-0x10, 0x18, 0x00, 0x00, 0x04, 0xc0, 0x04, 0xf5, 0x55, 0x01, 0x00, 0x1c, 0x00,
-0x00, 0xc4, 0x55, 0x04, 0x77, 0x56, 0x01, 0x00, 0x1c, 0x56, 0x53, 0x01, 0x00,
-0x1c, 0x00, 0x00, 0x00, 0x10, 0x18, 0x00, 0x00, 0x04, 0xc0, 0x04, 0xcb, 0x2f,
-0x01, 0x18, 0x10, 0xcb, 0x2f, 0x01, 0x10, 0x10, 0xcb, 0x2f, 0x01, 0x08, 0x10,
-0xcb, 0x2f, 0x01, 0x08, 0x10, 0xcb, 0x2f, 0x01, 0x20, 0x10, 0xcb, 0x2f, 0x01,
-0x00, 0x10, 0xcb, 0x2f, 0x01, 0x28, 0x10, 0x89, 0x25, 0x6d, 0xc2, 0x04, 0x00,
-0x00, 0x04, 0xc3, 0x04, 0x00, 0x00, 0x6c, 0xc3, 0x04, 0x00, 0x00, 0x6c, 0xc3,
-0x04, 0x00, 0x00, 0x6c, 0xc3, 0x04, 0x00, 0x00, 0x6c, 0xc2, 0x04, 0x00, 0x00,
-0x04, 0xc3, 0x04, 0x00, 0x00, 0x6c, 0xc3, 0x04, 0x00, 0x00, 0x6c, 0xc3, 0x04,
-0x00, 0x00, 0x6c, 0xc3, 0x04, 0x40, 0x1c, 0x68, 0xc0, 0x04, 0x40, 0x1c, 0x98,
-0xc0, 0x04, 0xa7, 0x77, 0x6d, 0xc3, 0x04, 0x00, 0x00, 0xc0, 0xc0, 0x04, 0x27,
-0x1d, 0xed, 0xc0, 0x04, 0x00, 0x00, 0x6c, 0xc3, 0x04, 0x00, 0x00, 0x6c, 0xc3,
-0x04, 0x00, 0x00, 0x6c, 0xc3, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
-0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
-0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
-0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00,
-0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6,
-0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
-0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
-0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
-0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00,
-0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6,
-0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
-0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
-0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
-0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00,
-0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6,
-0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
-0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
-0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
-0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00,
-0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6,
-0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
-0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
-0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
-0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00,
-0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6,
-0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
-0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
-0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
-0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00,
-0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6,
-0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
-0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
-0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
-0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00,
-0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6,
-0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
-0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
-0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
-0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00,
-0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6,
-0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
-0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
-0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
-0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
-};
diff --git a/drivers/staging/slicoss/oasisdbgdownload.h b/drivers/staging/slicoss/oasisdbgdownload.h
deleted file mode 100644
index 519e007..0000000
--- a/drivers/staging/slicoss/oasisdbgdownload.h
+++ /dev/null
@@ -1,6850 +0,0 @@
-#define OASIS_UCODE_VERS_STRING	"1.2"
-#define OASIS_UCODE_VERS_DATE  	"2006/03/27 15:11:22"
-#define OASIS_UCODE_HOSTIF_ID  	3
-
-static s32 ONumSections = 0x2;
-static u32 OSectionSize[] =
-{
-	0x00004000, 0x00010000,
-};
-
-static u32 OSectionStart[] =
-{
-	0x00000000, 0x00008000,
-};
-
-static u8 OasisUCode[2][65536] =
-{
-	{
-	0x15, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x21, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x03, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
-	0x98, 0xb0, 0x01, 0x00, 0x04, 0x80, 0xa2, 0x40, 0xfd, 0x7f, 0x00, 0x00,
-	0x09, 0x00, 0xa2, 0x49, 0xdd, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0x80, 0xb2, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xd1, 0xb1, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0x80, 0xb2, 0x01, 0x00, 0x09, 0x00, 0xa2, 0x40,
-	0x75, 0x7d, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x0b, 0x00, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0x09, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x8f, 0x98, 0x18, 0x31, 0x00, 0x00,
-	0x10, 0x00, 0x00, 0x98, 0x80, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x41, 0x98,
-	0x80, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x98, 0x80, 0xe4, 0x01, 0x00, 0x0e, 0x00, 0x40, 0x98,
-	0x80, 0x94, 0x00, 0x00, 0x11, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x19, 0x00, 0x29, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x19, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
-	0x0e, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x50, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x10, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x1f, 0x00, 0x29, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x1f, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
-	0x12, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x50, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x01, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x20, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x25, 0x00, 0x29, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x25, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
-	0x14, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
-	0xdd, 0x81, 0x01, 0x00, 0x12, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x33, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2a, 0x00, 0x14, 0xbc,
-	0x80, 0x32, 0x00, 0x00, 0xfe, 0x00, 0x13, 0xbc, 0x80, 0x32, 0x00, 0x00,
-	0x54, 0x95, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0xff, 0xff, 0x00, 0x40,
-	0xe5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x40, 0x49, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xfd, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0xb3, 0x01, 0x00,
-	0x33, 0x00, 0x18, 0xee, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x89, 0xb0, 0x01, 0x00, 0x32, 0x00, 0xa2, 0x41, 0x89, 0x50, 0x00, 0x00,
-	0x99, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x30, 0x94, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x20, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfa, 0xe0, 0xb3, 0x01, 0x00, 0x39, 0x00, 0x98, 0xee,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x80, 0xb0, 0x01, 0x00,
-	0x3b, 0x00, 0x80, 0xf3, 0xde, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0xfd, 0x93, 0x01, 0x00, 0x3e, 0x00, 0x83, 0xf3, 0x80, 0x32, 0x00, 0x00,
-	0xf0, 0x00, 0x00, 0xf3, 0x80, 0x88, 0x01, 0x00, 0x01, 0x80, 0x00, 0x40,
-	0x2e, 0xdd, 0x01, 0x00, 0x00, 0x94, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x46, 0x43, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa,
-	0x24, 0xb1, 0x01, 0x00, 0x7c, 0x00, 0x18, 0xee, 0x80, 0x32, 0x00, 0x00,
-	0x45, 0x00, 0x95, 0xe8, 0x80, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0xe8,
-	0x80, 0x88, 0x01, 0x00, 0x7c, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
-	0xec, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xd6, 0xb1, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0xd6, 0xb1, 0x01, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xee, 0x8b, 0x01, 0x00,
-	0x08, 0x01, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0xff, 0x00, 0x00, 0xf0,
-	0x80, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf7, 0x81, 0x94, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xd6, 0xb1, 0x01, 0x00, 0xff, 0x00, 0x00, 0xf8,
-	0x80, 0x88, 0x01, 0x00, 0x3c, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
-	0xff, 0x00, 0x00, 0xf0, 0xd6, 0x8d, 0x01, 0x00, 0xff, 0xff, 0x00, 0xf0,
-	0xf0, 0xdb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0x81, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x81, 0x94, 0x01, 0x00, 0x3c, 0x01, 0x00, 0x40,
-	0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xd6, 0xb1, 0x01, 0x00,
-	0xff, 0x00, 0x00, 0xf8, 0x80, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
-	0x81, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x81, 0x94, 0x01, 0x00,
-	0x3c, 0x02, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xd6, 0xb1, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0xd6, 0xb1, 0x01, 0x00, 0x1e, 0x00, 0x00, 0xf0,
-	0x82, 0xf4, 0x01, 0x00, 0xff, 0x3f, 0x00, 0xf8, 0x80, 0xd8, 0x01, 0x00,
-	0x64, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x81, 0xd0, 0x01, 0x00, 0xff, 0xff, 0x00, 0x40, 0x80, 0xd8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x80, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xd8, 0xb1, 0x01, 0x00, 0x68, 0x00, 0x22, 0xfa, 0x80, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0x81, 0xe0, 0x01, 0x00, 0x01, 0x00, 0x00, 0x40,
-	0x80, 0xcc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xde, 0xb1, 0x01, 0x00,
-	0x00, 0x01, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x10, 0x00, 0x00, 0xfa,
-	0x80, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x81, 0x94, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xd6, 0xb1, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40,
-	0xd5, 0x99, 0x01, 0x00, 0x10, 0x00, 0x00, 0xfa, 0x80, 0xe4, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf6, 0x81, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xd6, 0xb1, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0xfb, 0xd6, 0xe5, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40,
-	0xd5, 0x99, 0x01, 0x00, 0x18, 0x00, 0x00, 0xfb, 0xd6, 0xe5, 0x01, 0x00,
-	0x48, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x10, 0x00, 0x00, 0xfa,
-	0xd6, 0xe5, 0x01, 0x00, 0x50, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0xfb, 0xd6, 0xe5, 0x01, 0x00, 0x03, 0x00, 0x00, 0xfb,
-	0x7a, 0x89, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xdc, 0xb1, 0x01, 0x00,
-	0x7c, 0x00, 0x00, 0x4c, 0xdd, 0x91, 0x00, 0x00, 0x7c, 0x00, 0x95, 0xe8,
-	0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x2f, 0xe9, 0xfa, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xd1, 0xb1, 0x01, 0x00, 0xff, 0x00, 0x00, 0x42,
-	0x80, 0x88, 0x01, 0x00, 0x34, 0x00, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
-	0x7c, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x85, 0x00, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x02, 0x80, 0x22, 0x40, 0x80, 0x32, 0x00, 0x00,
-	0x7c, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f,
-	0x81, 0xb0, 0x01, 0x00, 0x8e, 0x00, 0x09, 0xf9, 0x81, 0x32, 0x00, 0x00,
-	0x8c, 0x00, 0x08, 0xf9, 0x81, 0x32, 0x00, 0x00, 0x98, 0x00, 0x1f, 0xfd,
-	0xf9, 0x33, 0x00, 0x00, 0x8b, 0x00, 0x9e, 0xfd, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4a, 0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x80, 0x48,
-	0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xf7, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x49, 0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
-	0x19, 0xb1, 0x01, 0x00, 0x93, 0x00, 0x0a, 0xf9, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x40, 0xfb, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0xfd,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x07, 0x80, 0xf9, 0xf3, 0x8f, 0x01, 0x00,
-	0x00, 0x07, 0x42, 0xf9, 0xf3, 0x8f, 0x01, 0x00, 0x97, 0x00, 0xa2, 0xff,
-	0xf7, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x43, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0xa2, 0xff, 0xfb, 0xef, 0x00, 0x00, 0x00, 0x00, 0x80, 0xfc,
-	0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb0, 0x01, 0x00,
-	0x00, 0x94, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xbb, 0x00, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x46, 0xfd, 0x7f, 0x01, 0x00,
-	0x00, 0x94, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xce, 0x00, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x44, 0xfd, 0x7f, 0x01, 0x00,
-	0x00, 0x94, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0xff, 0x7f, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0xff, 0x7f, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x9a, 0x13, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x01, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x00, 0x02, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x03, 0x01, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x9a, 0x13, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x02, 0x29, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x00, 0x67, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0xfd, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0xfd, 0x83, 0x01, 0x00,
-	0xff, 0x7f, 0x00, 0x40, 0x25, 0x99, 0x01, 0x00, 0xc4, 0x00, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x44, 0x80, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0xfd, 0x93, 0x01, 0x00, 0xe2, 0x00, 0x00, 0x40,
-	0x83, 0x30, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x45, 0x80, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x46, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40,
-	0x83, 0x98, 0x01, 0x00, 0xdd, 0x00, 0x00, 0x40, 0x2b, 0x31, 0x01, 0x00,
-	0x00, 0x00, 0xa2, 0x46, 0x88, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x94, 0x8c, 0xb0, 0x01, 0x00,
-	0xff, 0xff, 0x00, 0x46, 0x80, 0x88, 0x01, 0x00, 0xa5, 0xa5, 0xa2, 0x40,
-	0x80, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8d, 0xf0, 0x01, 0x00,
-	0xc9, 0x00, 0x82, 0x41, 0x89, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xfd, 0x83, 0x01, 0x00,
-	0xd4, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x44,
-	0x80, 0xb2, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x08, 0x83, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0xa2, 0x45, 0x80, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0x44,
-	0xfd, 0x93, 0x01, 0x00, 0x00, 0x30, 0x00, 0x08, 0x83, 0x98, 0x01, 0x00,
-	0x80, 0x00, 0x00, 0x40, 0x2b, 0x99, 0x01, 0x00, 0xdb, 0x00, 0x00, 0x40,
-	0x89, 0x30, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x46, 0x80, 0xb2, 0x00, 0x00,
-	0xff, 0xff, 0x00, 0x94, 0x80, 0x88, 0x01, 0x00, 0xa5, 0xa5, 0xa2, 0x40,
-	0x80, 0x4e, 0x01, 0x00, 0x00, 0x00, 0x80, 0x43, 0x89, 0xb0, 0x01, 0x00,
-	0x03, 0x84, 0x00, 0x41, 0x2c, 0x99, 0x01, 0x00, 0xde, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x03, 0x88, 0x00, 0x41, 0x2c, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x20, 0x8d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x9f, 0x96,
-	0x80, 0xb2, 0x00, 0x00, 0xdf, 0x00, 0xa2, 0x41, 0x8d, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xff, 0x7f, 0x00, 0x40,
-	0x25, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x89, 0xe0, 0x01, 0x00,
-	0xdd, 0x00, 0x00, 0x44, 0x82, 0x14, 0x01, 0x00, 0x00, 0x00, 0x90, 0x94,
-	0x8a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xf0, 0xb1, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x45, 0x88, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x89, 0xd0, 0x01, 0x00, 0xdd, 0x00, 0x00, 0x44, 0x2b, 0x41, 0x01, 0x00,
-	0xec, 0x00, 0x08, 0x41, 0x80, 0x32, 0x00, 0x00, 0xed, 0x00, 0x00, 0x94,
-	0x24, 0xb1, 0x00, 0x00, 0x10, 0x00, 0x00, 0x94, 0x24, 0xf5, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x94, 0xf0, 0xb1, 0x01, 0x00, 0xf2, 0x00, 0xa0, 0x44,
-	0x89, 0x50, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x44, 0x2b, 0x41, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x94, 0xf0, 0xb1, 0x01, 0x00, 0xef, 0x00, 0x20, 0x44,
-	0x89, 0x50, 0x00, 0x00, 0x10, 0x00, 0x00, 0x45, 0x88, 0xf4, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfa, 0x8a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xa3, 0x42,
-	0x89, 0xd0, 0x00, 0x00, 0xf7, 0x00, 0xa0, 0xfa, 0x8a, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x8b, 0xc0, 0x01, 0x00, 0xf5, 0x00, 0xa3, 0x42,
-	0x89, 0x50, 0x00, 0x00, 0xff, 0xff, 0x00, 0x45, 0x88, 0x88, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x45, 0x8a, 0xf4, 0x01, 0x00, 0xfc, 0x00, 0x90, 0x44,
-	0x8a, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x8b, 0xc0, 0x01, 0x00,
-	0xff, 0xff, 0x00, 0x45, 0x8a, 0xa8, 0x01, 0x00, 0x00, 0x00, 0x80, 0x50,
-	0x8b, 0xe0, 0x01, 0x00, 0xff, 0x7f, 0x00, 0x40, 0x25, 0x99, 0x01, 0x00,
-	0x7c, 0x00, 0x00, 0x40, 0x2b, 0x99, 0x01, 0x00, 0x00, 0x30, 0x00, 0x40,
-	0x83, 0x98, 0x01, 0x00, 0xdd, 0x00, 0x00, 0x08, 0x83, 0x14, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x94, 0x2a, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40,
-	0xf9, 0x9b, 0x01, 0x00, 0xdd, 0x00, 0x00, 0xfc, 0x19, 0x31, 0x01, 0x00,
-	0x00, 0x00, 0x40, 0x94, 0x80, 0xb2, 0x01, 0x00, 0xdd, 0x00, 0x00, 0x44,
-	0x2b, 0x41, 0x01, 0x00, 0x00, 0x00, 0x41, 0x94, 0x80, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0xf9, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x2b, 0xc1, 0x01, 0x00, 0x04, 0x01, 0x9f, 0x94, 0x80, 0x32, 0x00, 0x00,
-	0x02, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x10, 0x01, 0x00, 0x51,
-	0x93, 0xb0, 0x00, 0x00, 0x10, 0x01, 0x00, 0x4d, 0x93, 0xb0, 0x00, 0x00,
-	0x10, 0x01, 0x00, 0x49, 0x93, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x93, 0xb0, 0x01, 0x00, 0x10, 0x01, 0xa2, 0x41, 0x93, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x11, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x12, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x13, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x14, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x15, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x16, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x17, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x18, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x19, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x1b, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1d, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x1e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x70, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x71, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x72, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x73, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x74, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x75, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x76, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x77, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x78, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x79, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x7a, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x7b, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x7c, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x7d, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x7e, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x04, 0x00, 0x40,
-	0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xa1, 0xd1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x1b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x19, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x15, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x0d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0b, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x09, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x07, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x01, 0xb0, 0x01, 0x00, 0x3b, 0x01, 0x20, 0x48, 0xa1, 0x51, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x47, 0x01, 0x22, 0x4b,
-	0x74, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x60, 0x00, 0x00, 0x4b, 0x60, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb1,
-	0x7e, 0xb1, 0x01, 0x00, 0x48, 0x01, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x45, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x05, 0x00, 0x80, 0x40,
-	0x97, 0x98, 0x01, 0x00, 0x18, 0x00, 0x00, 0xaa, 0x96, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x43, 0x97, 0xf0, 0x01, 0x00, 0x07, 0x00, 0x00, 0xaa,
-	0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x58, 0x07, 0x90, 0x01, 0x00, 0xd8, 0x9f, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xa5, 0xb3, 0x01, 0x00,
-	0xd8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x07, 0x90, 0x01, 0x00,
-	0xd8, 0x9f, 0x00, 0x40, 0xbf, 0xb3, 0x00, 0x00, 0x5a, 0x01, 0x22, 0xcc,
-	0x85, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x07, 0x90, 0x01, 0x00,
-	0xd8, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x49, 0xb1, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00,
-	0xd0, 0x14, 0x00, 0x40, 0xa1, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
-	0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd0, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xe1, 0xb1, 0x01, 0x00,
-	0x07, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0x20,
-	0x62, 0xdd, 0x01, 0x00, 0x63, 0x01, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xcc, 0x85, 0x93, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xd0, 0x14, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfa, 0xba, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa,
-	0xa4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xbc, 0xb3, 0x01, 0x00,
-	0x00, 0x14, 0x2f, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe7,
-	0xa7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xa9, 0xb3, 0x01, 0x00,
-	0xff, 0x00, 0x00, 0xdd, 0x81, 0x88, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40,
-	0x80, 0xf4, 0x01, 0x00, 0x73, 0x01, 0x00, 0x40, 0x80, 0xc8, 0x01, 0x00,
-	0x86, 0x01, 0x00, 0xdd, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x10, 0xb1, 0x00, 0x00, 0x87, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x88, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x89, 0x01, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x8a, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x8b, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x8d, 0x01, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x8f, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb6, 0x01, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xc4, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc5, 0x01, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x82, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x83, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x28, 0x00, 0xb8, 0x02, 0x00, 0x40,
-	0x81, 0xb2, 0x28, 0x00, 0xd4, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x28, 0x00,
-	0xd5, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x28, 0x00, 0xd6, 0x9f, 0x00, 0x40,
-	0x81, 0xb2, 0x28, 0x00, 0xd7, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x28, 0x00,
-	0x72, 0x01, 0x00, 0x41, 0x81, 0xc0, 0x28, 0x00, 0x55, 0x01, 0x51, 0x49,
-	0xfd, 0x93, 0x28, 0x00, 0x55, 0x01, 0x52, 0x4a, 0xfd, 0x93, 0x2a, 0x00,
-	0x55, 0x01, 0x55, 0x49, 0xfd, 0x83, 0x2a, 0x00, 0x55, 0x01, 0x56, 0x4a,
-	0xfd, 0x83, 0x2a, 0x00, 0x50, 0x01, 0x91, 0x81, 0x80, 0x30, 0x2a, 0x00,
-	0x55, 0x01, 0x45, 0x40, 0x81, 0xb2, 0x2a, 0x00, 0x50, 0x01, 0x91, 0x82,
-	0x80, 0x30, 0x2a, 0x00, 0x55, 0x01, 0x46, 0x40, 0x81, 0xb2, 0x2a, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x89, 0xb0, 0x2b, 0x00, 0x00, 0x00, 0x2f, 0x40,
-	0x81, 0xb0, 0x01, 0x00, 0x00, 0x14, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00,
-	0xb3, 0x01, 0x22, 0xde, 0xe1, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00,
-	0x92, 0x01, 0xa2, 0x44, 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0x49, 0xd1, 0x01, 0x00, 0x9a, 0x01, 0x22, 0x40, 0xe1, 0x6d, 0x00, 0x00,
-	0x96, 0x01, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x50, 0x01, 0x00, 0x41,
-	0xbf, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xbf, 0xb3, 0x01, 0x00,
-	0x50, 0x01, 0xa0, 0x0f, 0xbd, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde,
-	0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x49, 0xc1, 0x01, 0x00,
-	0xb5, 0x01, 0x00, 0x40, 0x19, 0x99, 0x01, 0x00, 0x00, 0x00, 0x42, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff, 0x85, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xde, 0x19, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x42, 0xff,
-	0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff, 0xe1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x2f, 0xff,
-	0xe1, 0xb1, 0x01, 0x00, 0x08, 0x14, 0x00, 0xa4, 0x80, 0xcc, 0x01, 0x00,
-	0xaa, 0x01, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x85, 0xc0, 0x01, 0x00, 0xa8, 0x01, 0xa2, 0x4c, 0x81, 0x50, 0x00, 0x00,
-	0xb4, 0x01, 0x22, 0xd2, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x01, 0x22, 0x41,
-	0xa5, 0x6f, 0x00, 0x00, 0x50, 0x01, 0xa2, 0xe0, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xd2, 0xc1, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
-	0x89, 0x90, 0x01, 0x00, 0x00, 0x00, 0x40, 0x42, 0x80, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x41, 0x43, 0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x88, 0x94, 0x01, 0x00, 0x55, 0x01, 0x00, 0x44, 0xe0, 0xb1, 0x00, 0x00,
-	0xb1, 0x01, 0x00, 0x48, 0x49, 0xc1, 0x00, 0x00, 0xaf, 0x01, 0x00, 0x5b,
-	0x89, 0x90, 0x00, 0x00, 0xa8, 0x9f, 0x00, 0xa0, 0x9e, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x14, 0x00, 0x40,
-	0x49, 0x99, 0x01, 0x00, 0x00, 0x00, 0x23, 0x40, 0x81, 0xb0, 0x01, 0x00,
-	0xbe, 0x01, 0x22, 0xde, 0xe1, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00,
-	0xb9, 0x01, 0xa2, 0x44, 0x81, 0x6c, 0x00, 0x00, 0x50, 0x01, 0x00, 0x43,
-	0xbf, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x40, 0xf8, 0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0xf0,
-	0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x55, 0x01, 0x00, 0x40,
-	0xe1, 0xb1, 0x00, 0x00, 0xc6, 0x01, 0x00, 0x40, 0x91, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x91, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x2e, 0x40,
-	0x49, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40, 0xa3, 0x9b, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0xdd, 0x81, 0xf4, 0x01, 0x00, 0xcb, 0x01, 0x00, 0x40,
-	0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0xb1, 0x00, 0x00,
-	0xd1, 0x01, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00, 0x53, 0x01, 0x00, 0xde,
-	0xa1, 0xb3, 0x00, 0x00, 0xe3, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xe5, 0x01, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00, 0xeb, 0x01, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x52, 0x01, 0x00, 0xdf, 0xe1, 0xb1, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xd0, 0xba, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde,
-	0xa1, 0xb1, 0x01, 0x00, 0x02, 0x00, 0x00, 0xd2, 0xa5, 0xe7, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd2, 0xc1, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0xf0, 0xb1, 0x01, 0x00, 0xdb, 0x01, 0x22, 0x44, 0xc1, 0x53, 0x00, 0x00,
-	0xda, 0x01, 0x84, 0x41, 0x81, 0x40, 0x00, 0x00, 0xde, 0x01, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x45, 0xb1, 0x01, 0x00,
-	0xd5, 0x01, 0x00, 0x41, 0xa1, 0xc1, 0x00, 0x00, 0xda, 0x02, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x55, 0x01, 0x00, 0xdd, 0xa1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x81, 0xb0, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40, 0xa5, 0x9b, 0x01, 0x00,
-	0xda, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x40, 0x00, 0x00, 0xd3,
-	0xa7, 0xcb, 0x01, 0x00, 0xf8, 0x02, 0x00, 0xe0, 0xa5, 0xb3, 0x00, 0x00,
-	0x03, 0x00, 0x00, 0x40, 0xa3, 0x9b, 0x01, 0x00, 0x53, 0x01, 0x00, 0xde,
-	0xa1, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xbf, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xde, 0x81, 0x90, 0x01, 0x00, 0x50, 0x01, 0xa2, 0xba,
-	0x80, 0x04, 0x00, 0x00, 0x60, 0x00, 0x00, 0xde, 0x61, 0x99, 0x01, 0x00,
-	0xe8, 0x01, 0xa8, 0xb1, 0x80, 0x30, 0x00, 0x00, 0x52, 0x01, 0x00, 0x40,
-	0xe0, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xba, 0xb3, 0x01, 0x00,
-	0x6b, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x60, 0x02, 0x00, 0x4d,
-	0x83, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xe1, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0xe3, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0xe5, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xe9, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0xeb, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0xf5, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf7, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0xf9, 0xb3, 0x01, 0x00, 0xf9, 0x01, 0x22, 0x40,
-	0x8f, 0x6f, 0x00, 0x00, 0x78, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
-	0x60, 0x02, 0x00, 0xc7, 0x83, 0x30, 0x01, 0x00, 0x80, 0x02, 0x00, 0x40,
-	0x81, 0x98, 0x01, 0x00, 0x60, 0x02, 0x00, 0x42, 0x83, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xe8, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe9,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xea, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xeb, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x85,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xec, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xed, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb2,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa9, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xac, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb8, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xb9, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xba,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xf0, 0xb1, 0x01, 0x00,
-	0x0c, 0x02, 0xb8, 0x40, 0x81, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x81, 0x90, 0x01, 0x00, 0x0e, 0x02, 0xb9, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x81, 0x90, 0x01, 0x00, 0x10, 0x02, 0xba, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x81, 0x90, 0x01, 0x00,
-	0x12, 0x02, 0xbb, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x81, 0x90, 0x01, 0x00, 0x14, 0x02, 0xbc, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x81, 0x90, 0x01, 0x00, 0x16, 0x02, 0xbd, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x81, 0x90, 0x01, 0x00,
-	0x18, 0x02, 0xbe, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0x81, 0x90, 0x01, 0x00, 0x1a, 0x02, 0xbf, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x81, 0x90, 0x01, 0x00, 0x1c, 0x02, 0xc8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x81, 0x90, 0x01, 0x00,
-	0x1e, 0x02, 0xc9, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
-	0x81, 0x90, 0x01, 0x00, 0x20, 0x02, 0xca, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4a, 0x81, 0x90, 0x01, 0x00, 0x22, 0x02, 0xcb, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x81, 0x90, 0x01, 0x00,
-	0x24, 0x02, 0xcc, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0x81, 0x90, 0x01, 0x00, 0x26, 0x02, 0xcd, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4d, 0x81, 0x90, 0x01, 0x00, 0x28, 0x02, 0xce, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x81, 0x90, 0x01, 0x00,
-	0x2a, 0x02, 0xcf, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f,
-	0x81, 0x90, 0x01, 0x00, 0x2c, 0x02, 0xf0, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x81, 0x90, 0x01, 0x00, 0x2e, 0x02, 0xf1, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x81, 0x90, 0x01, 0x00,
-	0x30, 0x02, 0xf2, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52,
-	0x81, 0x90, 0x01, 0x00, 0x32, 0x02, 0xf3, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x53, 0x81, 0x90, 0x01, 0x00, 0x34, 0x02, 0xf4, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x81, 0x90, 0x01, 0x00,
-	0x36, 0x02, 0xf5, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
-	0x81, 0x90, 0x01, 0x00, 0x38, 0x02, 0xf6, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x56, 0x81, 0x90, 0x01, 0x00, 0x3a, 0x02, 0xf7, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x81, 0x90, 0x01, 0x00,
-	0x3c, 0x02, 0xf8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58,
-	0x81, 0x90, 0x01, 0x00, 0x3e, 0x02, 0xf9, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x59, 0x81, 0x90, 0x01, 0x00, 0x40, 0x02, 0xfa, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x81, 0x90, 0x01, 0x00,
-	0x42, 0x02, 0xfb, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b,
-	0x81, 0x90, 0x01, 0x00, 0x44, 0x02, 0xfc, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5c, 0x81, 0x90, 0x01, 0x00, 0x46, 0x02, 0xfd, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x81, 0x90, 0x01, 0x00,
-	0x48, 0x02, 0xfe, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e,
-	0x81, 0x90, 0x01, 0x00, 0x4a, 0x02, 0xff, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x81, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf0, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40, 0xa5, 0x9b, 0x01, 0x00,
-	0xd8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xd0, 0x14, 0x2e, 0x06, 0xa5, 0xb3, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0xd3, 0xa7, 0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf2, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf4,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf5, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfa, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xeb, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xee,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xef, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf3, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xf1, 0xb1, 0x01, 0x00,
-	0xdb, 0x01, 0x00, 0xc7, 0xe1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x66, 0x02, 0x00, 0x48, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x51, 0x40, 0x1a, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x4d, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x63, 0x02, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x5f, 0x02, 0x49, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x52, 0x40, 0x1c, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x4e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x68, 0x02, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
-	0x5f, 0x02, 0x4a, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
-	0x9e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0xd8, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xa1, 0xd0, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2,
-	0xd2, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xd4, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd0, 0xd6, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd1,
-	0xdc, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2, 0xde, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x88, 0xda, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd4,
-	0x8e, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xe6, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xac, 0xec, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x99,
-	0xfa, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xe0, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd5, 0xe2, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5,
-	0xe4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xe8, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd5, 0xea, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5,
-	0xf4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xf6, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd5, 0xf8, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc7,
-	0xa9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x40, 0xb1, 0x01, 0x00,
-	0x84, 0x02, 0x00, 0x40, 0x91, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x91, 0xb0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xa3, 0x9b, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0xdd, 0x81, 0xf4, 0x01, 0x00, 0x88, 0x02, 0x00, 0x40,
-	0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0xb1, 0x00, 0x00,
-	0x8d, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x98, 0x02, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x98, 0x02, 0x00, 0x46, 0xa3, 0xb3, 0x00, 0x00,
-	0x9b, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xa1, 0x02, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x8f, 0x02, 0x23, 0x50, 0xa5, 0x6f, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0xa5, 0xb3, 0x01, 0x00, 0xe8, 0x02, 0x00, 0x42,
-	0xa5, 0x63, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xd0, 0x14, 0x2d, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
-	0xba, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde, 0xa1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x00, 0xb0, 0x01, 0x00, 0x97, 0x02, 0x22, 0x44,
-	0xa5, 0x53, 0x00, 0x00, 0x94, 0x02, 0x00, 0x41, 0xa1, 0xc1, 0x00, 0x00,
-	0x55, 0x01, 0x00, 0xdd, 0xa1, 0xb1, 0x00, 0x00, 0xe8, 0x02, 0x00, 0xde,
-	0xa1, 0x33, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0xbf, 0xb3, 0x01, 0x00, 0x50, 0x01, 0xa2, 0xd2, 0x77, 0x7d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xd2, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde,
-	0x63, 0xb1, 0x01, 0x00, 0x9e, 0x02, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xe8, 0x02, 0x00, 0x54,
-	0xa5, 0x33, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xd0, 0x14, 0x2d, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0xd0, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xd2, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0xd4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0xd6, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x08, 0xb1, 0x01, 0x00,
-	0xac, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x60, 0x02, 0x00, 0x46,
-	0x83, 0x30, 0x01, 0x00, 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xa0, 0x9e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe8,
-	0x43, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe9, 0x45, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xea, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xeb,
-	0xa1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x40, 0xb1, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xd0, 0x14, 0x2e, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40,
-	0xa3, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xc1, 0xb3, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0xdd, 0x81, 0xf4, 0x01, 0x00, 0xbd, 0x02, 0x00, 0x40,
-	0x10, 0xc9, 0x00, 0x00, 0xc3, 0x02, 0x00, 0x05, 0x81, 0xb0, 0x00, 0x00,
-	0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xcb, 0x02, 0x00, 0x05,
-	0x81, 0xb0, 0x00, 0x00, 0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xd0, 0x02, 0x00, 0x44, 0xa5, 0xb3, 0x00, 0x00, 0xd2, 0x02, 0x00, 0x44,
-	0xa5, 0xb3, 0x00, 0x00, 0x02, 0x00, 0x00, 0x40, 0xa4, 0xe7, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xe0, 0x81, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0xc1,
-	0xf0, 0x89, 0x01, 0x00, 0xc8, 0x02, 0x22, 0x41, 0x81, 0x50, 0x00, 0x00,
-	0xc4, 0x02, 0x00, 0x41, 0xc1, 0xc3, 0x00, 0x00, 0xda, 0x02, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x02, 0x00, 0x00, 0x40,
-	0xa4, 0xe7, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x91, 0xb1, 0x01, 0x00,
-	0xff, 0xff, 0x00, 0xc9, 0xf0, 0x89, 0x01, 0x00, 0xc8, 0x02, 0x22, 0x41,
-	0x81, 0x50, 0x00, 0x00, 0xcc, 0x02, 0x00, 0x41, 0xc1, 0xc3, 0x00, 0x00,
-	0xff, 0xff, 0x00, 0xde, 0x85, 0x89, 0x01, 0x00, 0xc8, 0x02, 0x00, 0xc2,
-	0xe0, 0xb1, 0x00, 0x00, 0xff, 0xff, 0x00, 0xde, 0x95, 0x89, 0x01, 0x00,
-	0xc8, 0x02, 0x00, 0xca, 0xe0, 0xb1, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0xa7, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd8, 0xa9, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x49, 0xb1, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x20, 0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd4, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
-	0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd1, 0x61, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x20, 0x62, 0xdd, 0x01, 0x00, 0xe2, 0x02, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0xcc, 0x85, 0x93, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xe7, 0xa7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd8,
-	0xa9, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00,
-	0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
-	0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd0, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3,
-	0xf1, 0xb1, 0x01, 0x00, 0xe1, 0x02, 0x00, 0xd4, 0xe1, 0xb1, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xcc,
-	0x85, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x81, 0xb0, 0x01, 0x00,
-	0xfa, 0x02, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0xf9, 0x02, 0xa2, 0xf2,
-	0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0xcc, 0x85, 0x83, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xb5, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x41,
-	0x99, 0xb3, 0x01, 0x00, 0x0a, 0x03, 0x22, 0x44, 0x81, 0x6c, 0x00, 0x00,
-	0x12, 0x03, 0x22, 0x48, 0x81, 0x6c, 0x00, 0x00, 0x0c, 0x03, 0x22, 0x4c,
-	0x81, 0x6c, 0x00, 0x00, 0x16, 0x03, 0x22, 0x50, 0x81, 0x6c, 0x00, 0x00,
-	0x17, 0x03, 0x22, 0x54, 0x81, 0x6c, 0x00, 0x00, 0x19, 0x03, 0x22, 0x58,
-	0x81, 0x6c, 0x00, 0x00, 0x1e, 0x03, 0x22, 0x5c, 0x81, 0x6c, 0x00, 0x00,
-	0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc,
-	0x09, 0xb0, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0xca, 0x01, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0xf3, 0x83, 0x01, 0x00, 0x10, 0x03, 0xa2, 0x42, 0x05, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x05, 0xb0, 0x01, 0x00, 0xdd, 0x9f, 0x22, 0xca,
-	0x07, 0x14, 0x00, 0x00, 0xdd, 0x9f, 0x00, 0x45, 0xf3, 0x93, 0x00, 0x00,
-	0xdd, 0x9f, 0x20, 0x43, 0x95, 0x6f, 0x00, 0x00, 0xdd, 0x9f, 0x80, 0xca,
-	0x05, 0x30, 0x00, 0x00, 0xdd, 0x9f, 0x22, 0x01, 0x80, 0x30, 0x00, 0x00,
-	0xdd, 0x9f, 0x00, 0xcb, 0xdb, 0x91, 0x00, 0x00, 0x57, 0x01, 0x00, 0xbc,
-	0xab, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0xb1, 0xb3, 0x01, 0x00,
-	0xdd, 0x9f, 0x00, 0xca, 0xcf, 0xb3, 0x00, 0x00, 0xff, 0x00, 0x00, 0xca,
-	0x81, 0x88, 0x01, 0x00, 0xdd, 0x9f, 0xa2, 0x40, 0x74, 0x7d, 0x00, 0x00,
-	0x60, 0x00, 0x20, 0x40, 0x60, 0x99, 0x01, 0x00, 0x1b, 0x03, 0xa8, 0xb1,
-	0x82, 0x30, 0x00, 0x00, 0x1a, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xdd, 0x9f, 0x00, 0xca, 0x79, 0xb3, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x81, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0xcb, 0x83, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x22, 0x03, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x2d, 0x03, 0x91, 0x82, 0x82, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x8a, 0x80, 0xb0, 0x01, 0x00, 0xae, 0x9f, 0x00, 0x40,
-	0x80, 0xce, 0x01, 0x00, 0x2b, 0x03, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x2d, 0x03, 0x56, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb5, 0x03, 0x00, 0x40,
-	0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00,
-	0xb5, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x52,
-	0x07, 0x90, 0x01, 0x00, 0xd8, 0x9f, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4e, 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0xcd, 0x83, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x32, 0x03, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x00, 0x00, 0x46, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x3d, 0x03, 0x91, 0x81, 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
-	0x80, 0xb0, 0x01, 0x00, 0xae, 0x9f, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
-	0x3b, 0x03, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x3d, 0x03, 0x55, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xb5, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x52, 0x07, 0x90, 0x01, 0x00, 0xb5, 0x03, 0x00, 0x40,
-	0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00,
-	0xd8, 0x9f, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00, 0xb0, 0x03, 0x00, 0x40,
-	0xa1, 0x99, 0x01, 0x00, 0xc4, 0x14, 0x2f, 0x40, 0x99, 0xb3, 0x01, 0x00,
-	0x57, 0x01, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x30, 0x94, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x00, 0x90, 0x00, 0xf8,
-	0x80, 0x98, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf2, 0x88, 0xe4, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x40, 0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0x23, 0x91, 0x01, 0x00, 0x4d, 0x03, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
-	0x30, 0x00, 0x00, 0x40, 0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0x23, 0x91, 0x01, 0x00, 0x50, 0x03, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
-	0x40, 0x00, 0x00, 0x40, 0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0x23, 0x91, 0x01, 0x00, 0x53, 0x03, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x23, 0x91, 0x01, 0x00, 0x55, 0x03, 0x1f, 0x91,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x08, 0x80, 0x40, 0x20, 0x99, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x48, 0x84, 0x84, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
-	0x8f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x62, 0xb1, 0x01, 0x00,
-	0x5a, 0x03, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x08, 0x00, 0x47,
-	0x8e, 0xc8, 0x01, 0x00, 0x58, 0x03, 0x00, 0x5c, 0x8f, 0x80, 0x00, 0x00,
-	0xe0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x58, 0x15, 0x2d, 0x40,
-	0x8d, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x2d, 0xf0, 0x88, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfa, 0x8a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x81, 0xb0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x45, 0x82, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x8b, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
-	0x83, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x82, 0x94, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x41, 0x60, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x8d, 0xc0, 0x01, 0x00, 0x74, 0x03, 0x22, 0x5f, 0x8d, 0x6c, 0x00, 0x00,
-	0x65, 0x03, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x63, 0x03, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40, 0x85, 0x98, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x86, 0xb0, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x43, 0x86, 0xd8, 0x01, 0x00,
-	0x00, 0x00, 0xa6, 0x41, 0x85, 0x50, 0x01, 0x00, 0x70, 0x03, 0x00, 0x41,
-	0x83, 0xe0, 0x00, 0x00, 0x6e, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0x85, 0xe0, 0x01, 0x00, 0xd0, 0x14, 0x2f, 0x46,
-	0x84, 0x94, 0x01, 0x00, 0x20, 0x00, 0x00, 0x42, 0x60, 0x99, 0x01, 0x00,
-	0xc0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x07, 0x00, 0x00, 0x45, 0x80, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x8b, 0xf0, 0x01, 0x00, 0x00, 0x04, 0x00, 0x40,
-	0x83, 0x98, 0x01, 0x00, 0x85, 0x03, 0xa0, 0x41, 0x81, 0x50, 0x00, 0x00,
-	0x83, 0x03, 0x00, 0x41, 0x82, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41,
-	0x8e, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x49, 0xb1, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
-	0x00, 0x39, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0x8b, 0x03, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x44,
-	0x82, 0xf4, 0x01, 0x00, 0x1a, 0x15, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00,
-	0x70, 0x15, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x08, 0x00, 0x40,
-	0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x39, 0x00, 0x40, 0xe1, 0x99, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0x70, 0x15, 0x00, 0x43, 0x62, 0x99, 0x01, 0x00,
-	0x95, 0x03, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x97, 0x03, 0x22, 0x5a,
-	0x73, 0x7d, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x98, 0x03, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0x00, 0x08, 0x00, 0x42,
-	0x84, 0xc8, 0x01, 0x00, 0x90, 0x03, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x58, 0x15, 0x2d, 0x40,
-	0x8d, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x2d, 0xf0, 0x88, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x8f, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6,
-	0x90, 0xb0, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x48, 0x90, 0x98, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x93, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa,
-	0x8a, 0xb0, 0x01, 0x00, 0x80, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x02, 0x00, 0x00, 0xa6, 0x80, 0xb0, 0x01, 0x00, 0xac, 0x03, 0x22, 0x40,
-	0x82, 0x6c, 0x00, 0x00, 0xb0, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x58, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x8d, 0xc0, 0x01, 0x00, 0xb5, 0x03, 0x22, 0x5f, 0x8d, 0x6c, 0x00, 0x00,
-	0xa7, 0x03, 0xa2, 0x41, 0x93, 0x50, 0x00, 0x00, 0xa5, 0x03, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xff, 0x07, 0x00, 0x47, 0x84, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0xa6, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xed, 0x9f, 0x00, 0x47,
-	0x80, 0x30, 0x01, 0x00, 0x00, 0x02, 0x00, 0x47, 0x8e, 0xc8, 0x01, 0x00,
-	0xb0, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x50, 0xb3, 0x01, 0x00, 0xbb, 0x03, 0x20, 0x18, 0x89, 0x6c, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0xa6, 0x84, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
-	0x86, 0xb0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40, 0x55, 0x9b, 0x01, 0x00,
-	0xbe, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0xa6,
-	0x84, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00,
-	0x00, 0x10, 0x00, 0x40, 0x55, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x50, 0xd3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x4f, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x4e, 0xd3, 0x01, 0x00, 0x6e, 0x03, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x82, 0x03, 0x00, 0x42, 0x80, 0x30, 0x01, 0x00,
-	0xb0, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc7, 0x03, 0x22, 0xa7,
-	0x8f, 0x6c, 0x00, 0x00, 0x5a, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xc4, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0xc8, 0x14, 0x2e, 0xbb, 0x85, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xee, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xa0, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0xa5, 0xb3, 0x01, 0x00, 0xe1, 0x9f, 0x00, 0xca,
-	0xa7, 0x33, 0x01, 0x00, 0xe0, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xd6, 0x03, 0x22, 0x42,
-	0x75, 0x6f, 0x00, 0x00, 0xd8, 0x03, 0x22, 0x41, 0x75, 0x6f, 0x00, 0x00,
-	0xda, 0x03, 0x1e, 0xca, 0x81, 0x32, 0x00, 0x00, 0xdc, 0x03, 0x1f, 0xca,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xc9, 0xb1, 0x01, 0x00,
-	0xdd, 0x9f, 0x00, 0x42, 0x75, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca,
-	0xcd, 0xb1, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0x41, 0x75, 0xb3, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xca, 0xcf, 0xb1, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0x40,
-	0x75, 0xb3, 0x00, 0x00, 0x00, 0x81, 0x00, 0xa6, 0xc6, 0xb1, 0x01, 0x00,
-	0xdd, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0xa6,
-	0xc6, 0xb1, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0x40, 0x75, 0xb3, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x45, 0x01, 0x00, 0x4d, 0x93, 0x30, 0x01, 0x00,
-	0x45, 0x01, 0x00, 0x4e, 0x93, 0x30, 0x01, 0x00, 0x45, 0x01, 0x00, 0x4c,
-	0x93, 0x30, 0x01, 0x00, 0xec, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xdd, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x54, 0x95, 0x00, 0x40,
-	0x45, 0x99, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0xca, 0xe5, 0xb1, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xcc, 0x14, 0x2e, 0x40, 0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2,
-	0xa0, 0xb3, 0x01, 0x00, 0x15, 0x04, 0x00, 0x43, 0xb2, 0x33, 0x01, 0x00,
-	0x00, 0x00, 0x68, 0xda, 0x89, 0xb0, 0x01, 0x00, 0x7c, 0x00, 0x00, 0x40,
-	0x8b, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x89, 0xf0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x89, 0xd0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x44,
-	0x88, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x87, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0xa5, 0xb3, 0x01, 0x00, 0x15, 0x04, 0x00, 0x43,
-	0xb2, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x87, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0xa5, 0xc3, 0x01, 0x00, 0x0b, 0x04, 0x22, 0x44, 0x89, 0x50, 0x00, 0x00,
-	0x0b, 0x04, 0x22, 0x44, 0x8b, 0x50, 0x00, 0x00, 0xfa, 0x03, 0xa2, 0x50,
-	0xa5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xa5, 0xe3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xca, 0xa7, 0xb3, 0x01, 0x00, 0xe1, 0x9f, 0x00, 0xbb,
-	0x85, 0x30, 0x01, 0x00, 0xcc, 0x14, 0x2e, 0xd2, 0x95, 0xc3, 0x01, 0x00,
-	0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
-	0x42, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x81, 0xb0, 0x01, 0x00,
-	0x08, 0x04, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x07, 0x04, 0xa2, 0xf2,
-	0x80, 0x30, 0x00, 0x00, 0xfa, 0x03, 0x00, 0x40, 0xa5, 0xb3, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0xa5, 0xe3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
-	0xa7, 0xb3, 0x01, 0x00, 0xe1, 0x9f, 0x00, 0xbb, 0x85, 0x30, 0x01, 0x00,
-	0xe0, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd9, 0x2b, 0xb1, 0x01, 0x00,
-	0x00, 0x10, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00, 0xdb, 0x00, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xff, 0xff, 0x00, 0x94, 0xb4, 0x8b, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd9,
-	0x2b, 0xb1, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
-	0xdd, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0x94,
-	0xb4, 0xb3, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xd9, 0x2b, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
-	0x27, 0xb1, 0x01, 0x00, 0x06, 0xc0, 0x00, 0x40, 0x2d, 0x99, 0x01, 0x00,
-	0xde, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40,
-	0x83, 0x98, 0x01, 0x00, 0x02, 0xc4, 0x00, 0x41, 0x2c, 0x99, 0x01, 0x00,
-	0xde, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x40, 0x00, 0x40,
-	0x83, 0x98, 0x01, 0x00, 0x05, 0x82, 0x00, 0x41, 0x2c, 0x99, 0x01, 0x00,
-	0xde, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2d, 0x04, 0x80, 0x94,
-	0x80, 0x32, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x28, 0x04, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x80, 0x00, 0x40,
-	0x2d, 0x99, 0x01, 0x00, 0xde, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x31, 0x04, 0x00, 0x12,
-	0x10, 0xc9, 0x00, 0x00, 0x00, 0x48, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0xc0, 0x49, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x4b, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x40, 0x4d, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0x4f, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x50, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x80, 0x52, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x40, 0x54, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x56, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0xc0, 0x57, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x80, 0x59, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x40, 0x5b, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0x5d, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0xc0, 0x5e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x60, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x40, 0x62, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0x64, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x65, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x80, 0x67, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x40, 0x69, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x6b, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0xc0, 0x6c, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x80, 0x6e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x40, 0x70, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0x72, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0xc0, 0x73, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x75, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x40, 0x77, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0x79, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x7a, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x80, 0x7c, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x40, 0x7e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x59, 0x04, 0x00, 0x12, 0x10, 0xc9, 0x00, 0x00,
-	0x00, 0x80, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x82, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0x84, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0x86, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x88, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0x8a, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0x8c, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x8e, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0x90, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0x92, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x94, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0x96, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0x98, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x9a, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0x9c, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0x9e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xa0, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0xa2, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0xa4, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xa6, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0xa8, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0xaa, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xac, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0xae, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0xb0, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xb2, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0xb4, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0xb6, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xb8, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0xba, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0xbc, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xbe, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x87, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x80, 0xb1, 0x01, 0x00,
-	0x01, 0x00, 0x00, 0xa6, 0x82, 0xb1, 0x01, 0x00, 0x82, 0x04, 0x85, 0x41,
-	0x97, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x97, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x90, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6, 0x92, 0xb1, 0x01, 0x00,
-	0x87, 0x04, 0x85, 0x41, 0x97, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x90, 0x04, 0x60, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0xb1, 0x01, 0x00,
-	0xff, 0xff, 0xf0, 0x4b, 0x82, 0x89, 0x01, 0x00, 0x93, 0x04, 0x60, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x80, 0xb1, 0x01, 0x00,
-	0x01, 0x00, 0xf0, 0xa6, 0x82, 0xb1, 0x01, 0x00, 0x96, 0x04, 0x60, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4b, 0x84, 0x89, 0x01, 0x00,
-	0x00, 0x00, 0xf0, 0xc2, 0x24, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
-	0x90, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x80, 0x4b, 0x92, 0x89, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x80, 0xa6,
-	0x92, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0x4b, 0x94, 0x89, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0xca, 0x94, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x10, 0x00, 0x00, 0x4e, 0x98, 0xe4, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x07, 0x98, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x99, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x98, 0x94, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x49, 0x99, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0x88, 0x94, 0x01, 0x00, 0xa6, 0x04, 0x47, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xad, 0x04, 0x22, 0x20, 0x87, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0xa6, 0x04, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x1f, 0x80, 0x86, 0xb3, 0x01, 0x00, 0xb0, 0x04, 0x22, 0x4f,
-	0x77, 0x7d, 0x00, 0x00, 0xc0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x62, 0xb1, 0x01, 0x00, 0xb1, 0x04, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xb8, 0x04, 0x22, 0x4b, 0x89, 0x7c, 0x00, 0x00, 0xb6, 0x04, 0x22, 0x4f,
-	0x77, 0x7d, 0x00, 0x00, 0xc0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x62, 0xb1, 0x01, 0x00, 0xb6, 0x04, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x87, 0xb3, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x99, 0xb0, 0x01, 0x00, 0x6f, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0xc1, 0x04, 0xa8, 0xb1, 0x52, 0x33, 0x00, 0x00, 0xc6, 0x04, 0x22, 0x4b,
-	0x53, 0x7f, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0xc4, 0x04, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0xc1, 0x04, 0xa2, 0x41,
-	0x99, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x4f, 0x77, 0xfd, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x10, 0x00, 0x00, 0x4e, 0x98, 0xe4, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x07, 0x98, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x99, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x98, 0x94, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0x99, 0xe0, 0x01, 0x00, 0xd6, 0x04, 0x00, 0x4c,
-	0x88, 0x94, 0x00, 0x00, 0xd6, 0x04, 0x47, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xdd, 0x04, 0x22, 0x20, 0x87, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0xd6, 0x04, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x1f, 0x80, 0x86, 0xb3, 0x01, 0x00, 0xe0, 0x04, 0x22, 0x4f,
-	0x77, 0x7d, 0x00, 0x00, 0xf0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x62, 0xb1, 0x01, 0x00, 0xe1, 0x04, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xe8, 0x04, 0x22, 0x4a, 0x89, 0x7c, 0x00, 0x00, 0xe6, 0x04, 0x22, 0x4f,
-	0x77, 0x7d, 0x00, 0x00, 0xf0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x62, 0xb1, 0x01, 0x00, 0xe6, 0x04, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x87, 0xb3, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x99, 0xb0, 0x01, 0x00, 0x6f, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0xf1, 0x04, 0xa8, 0xb1, 0x52, 0x33, 0x00, 0x00, 0xf6, 0x04, 0x22, 0x4a,
-	0x53, 0x7f, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0xf4, 0x04, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0xf1, 0x04, 0xa2, 0x41,
-	0x99, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x4f, 0x77, 0xfd, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x00, 0x05, 0xa8, 0xb1, 0x80, 0x30, 0x00, 0x00, 0x12, 0x05, 0x1d, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x40, 0x18, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00, 0x10, 0x05, 0xa2, 0x40,
-	0x86, 0x04, 0x00, 0x00, 0xde, 0x9f, 0x9c, 0x40, 0x80, 0x32, 0x00, 0x00,
-	0xff, 0xff, 0x00, 0x40, 0x88, 0x88, 0x01, 0x00, 0x30, 0x05, 0x00, 0x50,
-	0x47, 0x31, 0x01, 0x00, 0x36, 0x00, 0x00, 0x44, 0x88, 0xcc, 0x01, 0x00,
-	0x0c, 0x05, 0x52, 0x40, 0x81, 0x32, 0x00, 0x00, 0x30, 0x05, 0x00, 0x40,
-	0x47, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x89, 0xb0, 0x01, 0x00,
-	0x30, 0x05, 0x00, 0x48, 0x47, 0x31, 0x01, 0x00, 0x30, 0x05, 0x00, 0x05,
-	0x47, 0x31, 0x01, 0x00, 0xde, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x28, 0x00, 0x00, 0x40, 0x47, 0x99, 0x1b, 0x00, 0xde, 0x9f, 0x00, 0x41,
-	0xe1, 0xc1, 0x1a, 0x00, 0x78, 0x18, 0x00, 0x40, 0x49, 0x99, 0x1b, 0x00,
-	0x19, 0x05, 0x22, 0x54, 0x81, 0x7c, 0x1a, 0x00, 0x14, 0x05, 0x42, 0x40,
-	0x81, 0x32, 0x1a, 0x00, 0x00, 0x82, 0x00, 0xb3, 0x67, 0xdf, 0x1b, 0x00,
-	0x00, 0x00, 0x1a, 0x44, 0x93, 0x93, 0x1b, 0x00, 0x28, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x1b, 0x00, 0x30, 0x05, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00,
-	0x27, 0x05, 0x0f, 0x40, 0x80, 0x32, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x40,
-	0x88, 0x88, 0x01, 0x00, 0x30, 0x05, 0x00, 0x50, 0x47, 0x31, 0x01, 0x00,
-	0x36, 0x00, 0x00, 0x44, 0x88, 0xcc, 0x01, 0x00, 0x1f, 0x05, 0x99, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x89, 0xd0, 0x01, 0x00,
-	0x21, 0x05, 0x9b, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0x89, 0xd0, 0x01, 0x00, 0x23, 0x05, 0x1f, 0x44, 0x80, 0x32, 0x00, 0x00,
-	0x30, 0x05, 0x00, 0x40, 0x47, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x89, 0xb0, 0x01, 0x00, 0x30, 0x05, 0x00, 0x48, 0x47, 0x31, 0x01, 0x00,
-	0x30, 0x05, 0x00, 0x58, 0x47, 0x31, 0x01, 0x00, 0xde, 0x9f, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x10, 0x00, 0x00, 0x40, 0x86, 0xf4, 0x01, 0x00,
-	0x6f, 0x00, 0x00, 0x43, 0x86, 0x88, 0x01, 0x00, 0xde, 0x9f, 0x26, 0x05,
-	0x47, 0x31, 0x00, 0x00, 0x30, 0x05, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00,
-	0xde, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x44, 0xf0, 0x41, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x80, 0x41,
-	0xe1, 0xc1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x4c, 0x01, 0x00, 0x07,
-	0x91, 0x30, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x40, 0x97, 0xec, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x05, 0x91, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x4c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x44, 0x05, 0xa2, 0x40,
-	0x97, 0x6c, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
-	0x45, 0x05, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40,
-	0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xda, 0xf5, 0xb1, 0x01, 0x00, 0x10, 0x04, 0x00, 0x42,
-	0xb3, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xf5, 0xb1, 0x01, 0x00,
-	0x10, 0x04, 0x00, 0x42, 0xb3, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
-	0xf5, 0xb1, 0x01, 0x00, 0x4e, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
-	0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda,
-	0xf7, 0xf5, 0x01, 0x00, 0x50, 0x00, 0x00, 0x40, 0x91, 0x98, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x8f, 0xb0, 0x01, 0x00, 0x10, 0x04, 0x00, 0x48,
-	0xb2, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xf7, 0xb1, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0xda, 0xf7, 0xf5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x91, 0xc0, 0x01, 0x00, 0x50, 0x05, 0xa2, 0x41, 0x8f, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x45, 0xd1, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40,
-	0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x40,
-	0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00, 0x1a, 0x00, 0x00, 0x40,
-	0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00, 0x18, 0x00, 0x00, 0x40,
-	0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00, 0x38, 0x05, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
-	0x91, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x6e, 0xda,
-	0x8f, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
-	0xfd, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0xda,
-	0xfd, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x7a, 0x05, 0x22, 0x45, 0xfd, 0x7f, 0x00, 0x00, 0x40, 0x16, 0x00, 0x40,
-	0x45, 0x99, 0x01, 0x00, 0xdb, 0x9f, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x15, 0x04, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x78, 0x05, 0xa2, 0x40, 0x8f, 0x6c, 0x00, 0x00,
-	0x7d, 0x05, 0x22, 0x20, 0xb5, 0x6f, 0x00, 0x00, 0x7a, 0x05, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xda, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x1f, 0x00,
-	0x7d, 0x05, 0x22, 0x40, 0x97, 0x6c, 0x1e, 0x00, 0x7a, 0x05, 0x42, 0x40,
-	0x81, 0x32, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x67, 0x93, 0x1f, 0x00,
-	0xdf, 0x9f, 0x00, 0x58, 0x67, 0x93, 0x1e, 0x00, 0x54, 0x16, 0x00, 0x40,
-	0x47, 0x99, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x1f, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xfe,
-	0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
-	0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00,
-	0x46, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda, 0xf7, 0xf5, 0x01, 0x00,
-	0x48, 0x00, 0x00, 0x40, 0x95, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x97, 0xb0, 0x01, 0x00, 0x10, 0x04, 0x00, 0x4a, 0xb2, 0x33, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xda, 0xf7, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda,
-	0xf7, 0xf5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x95, 0xc0, 0x01, 0x00,
-	0x90, 0x05, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x40,
-	0xa5, 0x9b, 0x01, 0x00, 0x40, 0x16, 0x00, 0x40, 0xa1, 0x9b, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xca, 0xa7, 0xb3, 0x01, 0x00, 0xe1, 0x9f, 0x00, 0xbb,
-	0x85, 0x30, 0x01, 0x00, 0xe0, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xb8, 0x05, 0x22, 0x45, 0xfd, 0x7f, 0x00, 0x00, 0xe0, 0x15, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x1a, 0x00, 0x00, 0xa2, 0x80, 0xdc, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0xf0, 0x15, 0x00, 0x40,
-	0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca, 0xf1, 0xb1, 0x01, 0x00,
-	0x07, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0x40,
-	0x62, 0xdd, 0x01, 0x00, 0xa7, 0x05, 0xa8, 0xbb, 0xe1, 0x31, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x83, 0xb0, 0x01, 0x00, 0xaa, 0x05, 0xa2, 0x41,
-	0x83, 0x50, 0x00, 0x00, 0xa9, 0x05, 0xa2, 0xf2, 0x82, 0x30, 0x00, 0x00,
-	0x4c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb0, 0x05, 0xa2, 0x40,
-	0x97, 0x6c, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
-	0xb1, 0x05, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40,
-	0xb3, 0x9b, 0x01, 0x00, 0xf0, 0x15, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb8, 0x05, 0xa2, 0xfa,
-	0xb4, 0x6f, 0x00, 0x00, 0x10, 0x04, 0x00, 0x42, 0xb3, 0x43, 0x01, 0x00,
-	0xb8, 0x05, 0xa2, 0xfa, 0xb4, 0x6f, 0x00, 0x00, 0x10, 0x04, 0x00, 0x42,
-	0xb3, 0x43, 0x01, 0x00, 0xbb, 0x05, 0x22, 0xfa, 0xb4, 0x6f, 0x00, 0x00,
-	0xb8, 0x05, 0x42, 0x40, 0x81, 0x32, 0x20, 0x00, 0x00, 0x00, 0x00, 0x4e,
-	0x67, 0x93, 0x21, 0x00, 0xdf, 0x9f, 0x00, 0x58, 0x67, 0x93, 0x20, 0x00,
-	0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x21, 0x00, 0xdb, 0x9f, 0x00, 0x40,
-	0x49, 0x31, 0x21, 0x00, 0xf6, 0x15, 0x00, 0x40, 0x43, 0x99, 0x21, 0x00,
-	0x5c, 0x16, 0x00, 0x40, 0x45, 0x99, 0x21, 0x00, 0x00, 0x00, 0x6e, 0xfa,
-	0x8e, 0xb0, 0x21, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0xb4, 0xb3, 0x01, 0x00, 0xc9, 0x05, 0xa2, 0x40, 0x8f, 0x6c, 0x00, 0x00,
-	0xfc, 0x15, 0x20, 0x20, 0xe1, 0xb1, 0x01, 0x00, 0xce, 0x05, 0x00, 0x40,
-	0x81, 0xb2, 0x24, 0x00, 0xda, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x25, 0x00,
-	0xce, 0x05, 0x22, 0x40, 0x97, 0x6c, 0x24, 0x00, 0xcb, 0x05, 0x42, 0x40,
-	0x81, 0x32, 0x24, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x67, 0x93, 0x25, 0x00,
-	0xdf, 0x9f, 0x00, 0x58, 0x67, 0x93, 0x24, 0x00, 0x38, 0x05, 0x00, 0x40,
-	0x81, 0x32, 0x25, 0x00, 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x25, 0x00,
-	0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xd3, 0x05, 0x22, 0x50,
-	0xb5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x91, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xf6, 0x15, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x20, 0x04, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00,
-	0x02, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xf8, 0x15, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x20, 0x04, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfa, 0x15, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x20, 0x04, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x15, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x94, 0xb0, 0x01, 0x00,
-	0xff, 0xff, 0x00, 0x4a, 0xb4, 0x8b, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x4a, 0xb4, 0xf7, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x38, 0x05, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xe9, 0x05, 0x22, 0x50, 0xb5, 0x6f, 0x00, 0x00,
-	0xea, 0x05, 0x00, 0x50, 0xb5, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xb5, 0xb3, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xe0, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x16, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x30, 0x31, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x32, 0x33, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x34, 0x35, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x36, 0x37, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x38, 0x39, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x41, 0x42, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x43, 0x44, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x45, 0x46, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x47, 0x48, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x49, 0x4a, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x40,
-	0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf7, 0xb1, 0x01, 0x00,
-	0xfc, 0x05, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x80, 0x16, 0x2e, 0x06,
-	0x83, 0xb0, 0x01, 0x00, 0x36, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
-	0xff, 0x05, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x22, 0x00, 0x00, 0x40,
-	0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb, 0xf6, 0xb1, 0x01, 0x00,
-	0x02, 0x06, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x62, 0x00, 0x00, 0x40,
-	0x95, 0x98, 0x01, 0x00, 0xdc, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x16, 0x2d, 0x06, 0x83, 0xb0, 0x01, 0x00, 0x80, 0x16, 0x00, 0x40,
-	0x45, 0x99, 0x01, 0x00, 0x5c, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
-	0x08, 0x06, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
-	0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71, 0xf9, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x72, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x73,
-	0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x74, 0xf9, 0xb1, 0x01, 0x00,
-	0x54, 0x00, 0x00, 0x40, 0x95, 0x98, 0x01, 0x00, 0xdc, 0x9f, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x70, 0x95, 0xb0, 0x01, 0x00,
-	0x14, 0x06, 0x22, 0x70, 0xb5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41,
-	0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x97, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x45, 0x67, 0x00, 0xa6, 0xe0, 0xb2, 0x01, 0x00, 0x01, 0x23, 0x00, 0x70,
-	0xe1, 0x9a, 0x01, 0x00, 0xcd, 0xef, 0x00, 0xa6, 0xe2, 0xb2, 0x01, 0x00,
-	0x89, 0xab, 0x00, 0x71, 0xe3, 0x9a, 0x01, 0x00, 0xba, 0x98, 0x00, 0xa6,
-	0xe4, 0xb2, 0x01, 0x00, 0xfe, 0xdc, 0x00, 0x72, 0xe5, 0x9a, 0x01, 0x00,
-	0x32, 0x10, 0x00, 0xa6, 0xe6, 0xb2, 0x01, 0x00, 0x76, 0x54, 0x00, 0x73,
-	0xe7, 0x9a, 0x01, 0x00, 0xd2, 0xc3, 0x00, 0xa6, 0xe8, 0xb2, 0x01, 0x00,
-	0xf0, 0xe1, 0x00, 0x74, 0xe9, 0x9a, 0x01, 0x00, 0x80, 0x16, 0x00, 0x4a,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x81, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4a, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf7, 0xb1, 0x01, 0x00, 0x25, 0x06, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
-	0x80, 0x16, 0x00, 0x4a, 0x44, 0xc9, 0x01, 0x00, 0xfc, 0x16, 0x2a, 0x47,
-	0xe7, 0xb5, 0x01, 0x00, 0x03, 0x00, 0x00, 0x4a, 0xe8, 0xe5, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x8d, 0xb0, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40,
-	0xa3, 0x99, 0x01, 0x00, 0x80, 0x16, 0x3d, 0x46, 0x8d, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
-	0x40, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00,
-	0x2e, 0x06, 0xa2, 0x41, 0x89, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
-	0xeb, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71, 0xed, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x72, 0xef, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x73,
-	0xf1, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x74, 0xf3, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0x41,
-	0x80, 0x88, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40, 0xa2, 0xc9, 0x01, 0x00,
-	0x4b, 0x06, 0xa0, 0x50, 0x83, 0x6c, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x40,
-	0x98, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x99, 0x84, 0x01, 0x00,
-	0x50, 0x03, 0x00, 0x4c, 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
-	0x86, 0xb0, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40, 0x98, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4f, 0x99, 0x84, 0x01, 0x00, 0x50, 0x03, 0x00, 0x4c,
-	0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x86, 0xa4, 0x01, 0x00,
-	0x02, 0x00, 0x00, 0x40, 0x98, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f,
-	0x99, 0x84, 0x01, 0x00, 0x50, 0x03, 0x00, 0x4c, 0xa2, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x20, 0x86, 0xa4, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40,
-	0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x40, 0xa4, 0x01, 0x00,
-	0x01, 0x00, 0x00, 0x20, 0x88, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0x41, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x40, 0x94, 0x01, 0x00,
-	0x05, 0x00, 0x00, 0x75, 0x89, 0xe4, 0x01, 0x00, 0x1b, 0x00, 0x00, 0x75,
-	0x85, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x84, 0x94, 0x01, 0x00,
-	0x55, 0x06, 0xa3, 0x53, 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76,
-	0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77, 0x89, 0x84, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x76, 0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
-	0x8b, 0xa4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
-	0x64, 0x06, 0x00, 0x45, 0x88, 0x94, 0x00, 0x00, 0x27, 0x00, 0x00, 0x41,
-	0x80, 0xce, 0x01, 0x00, 0x5a, 0x06, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x76, 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
-	0x89, 0xa4, 0x01, 0x00, 0x64, 0x06, 0x00, 0x78, 0x89, 0xa4, 0x00, 0x00,
-	0x3b, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00, 0x57, 0x06, 0xaa, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x89, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x77, 0x89, 0x84, 0x01, 0x00, 0x00, 0x00, 0x00, 0x76,
-	0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x88, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
-	0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
-	0x64, 0x06, 0x00, 0x45, 0x88, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x84, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x79, 0x85, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x20, 0x84, 0xc0, 0x01, 0x00, 0x6b, 0x06, 0xa3, 0x53,
-	0x83, 0x6c, 0x00, 0x00, 0x82, 0x5a, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00,
-	0x99, 0x79, 0x00, 0x42, 0x84, 0xc8, 0x01, 0x00, 0x78, 0x06, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x27, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00,
-	0x70, 0x06, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00, 0xd9, 0x6e, 0x00, 0xa6,
-	0x84, 0xc0, 0x01, 0x00, 0xa1, 0xeb, 0x00, 0x42, 0x84, 0xc8, 0x01, 0x00,
-	0x78, 0x06, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x41,
-	0x80, 0xce, 0x01, 0x00, 0x75, 0x06, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x1b, 0x8f, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00, 0xdc, 0xbc, 0x00, 0x42,
-	0x84, 0xc8, 0x01, 0x00, 0x78, 0x06, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x62, 0xca, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00, 0xd6, 0xc1, 0x00, 0x42,
-	0x84, 0xc8, 0x01, 0x00, 0x78, 0x06, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x78, 0xf3, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
-	0xf1, 0xb2, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x76, 0x89, 0xe4, 0x01, 0x00,
-	0x02, 0x00, 0x00, 0x76, 0xef, 0xf6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0xee, 0x96, 0x01, 0x00, 0x00, 0x00, 0x00, 0x75, 0xed, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0xea, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x83, 0xc0, 0x01, 0x00, 0x4f, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00,
-	0x37, 0x06, 0x2a, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75,
-	0xe1, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x76, 0xe3, 0xc2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x77, 0xe5, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78,
-	0xe7, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x79, 0xe9, 0xc2, 0x01, 0x00,
-	0x2b, 0x06, 0x81, 0x41, 0x8d, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0xfd, 0x93, 0x01, 0x00, 0x40, 0x16, 0x00, 0x40,
-	0x45, 0x99, 0x01, 0x00, 0xdb, 0x9f, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x15, 0x04, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xb9, 0x06, 0x22, 0x40, 0x8f, 0x6c, 0x00, 0x00,
-	0xda, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb9, 0x06, 0xa2, 0x40,
-	0x97, 0x6c, 0x00, 0x00, 0x5e, 0x16, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x7c, 0x16, 0x20, 0xf6, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x31, 0xb3, 0x01, 0x00, 0x9d, 0x06, 0x22, 0x4f, 0x8f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x51, 0xfd, 0x93, 0x01, 0x00, 0x9f, 0x06, 0x22, 0x40,
-	0x8f, 0x7c, 0x00, 0x00, 0xa3, 0x06, 0x00, 0x54, 0xfd, 0x93, 0x00, 0x00,
-	0xa1, 0x06, 0x22, 0x42, 0x8f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52,
-	0xfd, 0x93, 0x01, 0x00, 0xa3, 0x06, 0x22, 0x41, 0x8f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x53, 0xfd, 0x93, 0x01, 0x00, 0xb7, 0x06, 0x22, 0x51,
-	0xfd, 0x7f, 0x00, 0x00, 0x38, 0x05, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x0c, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xb2, 0x06, 0xa2, 0x40, 0xb5, 0x6f, 0x00, 0x00,
-	0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x48,
-	0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0x97, 0xc0, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0x4b, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x48,
-	0xb2, 0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x30, 0xb5, 0xb3, 0x01, 0x00,
-	0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x48,
-	0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xb6, 0x06, 0x22, 0x40, 0xb5, 0x6f, 0x00, 0x00, 0xba, 0x06, 0x00, 0x54,
-	0xfd, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0xfd, 0x83, 0x01, 0x00,
-	0x1c, 0x00, 0x00, 0xfe, 0x7f, 0xd9, 0x01, 0x00, 0xba, 0x06, 0xa6, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xfd, 0x93, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xe7, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc4, 0x06, 0x22, 0x5c,
-	0x1f, 0x7c, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0xe9, 0x9f, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00,
-	0x04, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x3c, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x00, 0x14, 0x02, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0x34, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
-	0x32, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05, 0x0a, 0xc8, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x0e, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xa4,
-	0x0c, 0xc8, 0x01, 0x00, 0xea, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00, 0x0a, 0x07, 0x22, 0x01,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x2e, 0xa4, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x48, 0xc1, 0x01, 0x00, 0xd9, 0x06, 0xa3, 0x07, 0x02, 0x6c, 0x00, 0x00,
-	0xda, 0x06, 0x68, 0x01, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x07,
-	0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x02, 0xd0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0d, 0x0a, 0xc0, 0x01, 0x00, 0xec, 0x06, 0x22, 0x40,
-	0x03, 0x6c, 0x00, 0x00, 0xe6, 0x06, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
-	0x23, 0x07, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0xe3, 0x06, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x62, 0xb1, 0x01, 0x00, 0xe8, 0x06, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00,
-	0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x23, 0x07, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x62, 0xb1, 0x01, 0x00, 0xee, 0x06, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00,
-	0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x22, 0x00, 0x00, 0x19,
-	0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00,
-	0x0f, 0x00, 0x00, 0xf2, 0x3a, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x3b, 0xe0, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x14, 0x02, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x1d, 0x02, 0xc0, 0x01, 0x00, 0xfa, 0x06, 0x23, 0x1a,
-	0x02, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x03, 0xc0, 0x01, 0x00,
-	0x23, 0x07, 0x00, 0x01, 0x34, 0xc0, 0x00, 0x00, 0x0c, 0x00, 0x2d, 0x1d,
-	0x48, 0xc1, 0x01, 0x00, 0xf0, 0x00, 0x00, 0xf2, 0x30, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x31, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14,
-	0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x02, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x18, 0x02, 0xc0, 0x01, 0x00, 0x02, 0x07, 0x22, 0x1a,
-	0x02, 0x50, 0x00, 0x00, 0x23, 0x07, 0x00, 0x01, 0x34, 0xc0, 0x00, 0x00,
-	0x22, 0x00, 0x00, 0x19, 0x48, 0xc9, 0x01, 0x00, 0x02, 0x00, 0x2d, 0x14,
-	0x48, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x14, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x1d, 0x14, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
-	0x14, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x24, 0xb0, 0x01, 0x00,
-	0x12, 0x00, 0x00, 0x17, 0x10, 0xc8, 0x01, 0x00, 0x23, 0x07, 0x00, 0x1a,
-	0x10, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xa4, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
-	0x48, 0xc1, 0x01, 0x00, 0x0f, 0x07, 0xa3, 0x12, 0x0e, 0x6c, 0x00, 0x00,
-	0x10, 0x07, 0x60, 0x07, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x60, 0x12,
-	0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x68, 0x0d, 0x16, 0x94, 0x01, 0x00,
-	0xff, 0xff, 0x00, 0x0b, 0x16, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00, 0x17, 0x07, 0xa8, 0x5c,
-	0x1f, 0x10, 0x00, 0x00, 0x40, 0x07, 0x22, 0x0d, 0x14, 0x50, 0x00, 0x00,
-	0x40, 0x07, 0x22, 0x0d, 0x24, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
-	0x10, 0xc0, 0x01, 0x00, 0x1e, 0x07, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
-	0x23, 0x07, 0x00, 0x41, 0x23, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x1f, 0x07, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
-	0x3f, 0x07, 0xa2, 0x0d, 0x0e, 0x50, 0x00, 0x00, 0x2e, 0x07, 0x22, 0x46,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00,
-	0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x2c, 0x07, 0x22, 0xf2,
-	0x64, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x29, 0x07, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x20, 0x80, 0x00, 0x03, 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0xe1, 0x91, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x06, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x04, 0xb0, 0x01, 0x00, 0x33, 0x07, 0x1f, 0xf0, 0x0e, 0x30, 0x00, 0x00,
-	0xd3, 0x06, 0x00, 0x4c, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x5f,
-	0x0f, 0x80, 0x01, 0x00, 0xd3, 0x06, 0x23, 0x07, 0x14, 0x6c, 0x00, 0x00,
-	0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x24, 0x00, 0x00, 0x40,
-	0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
-	0xf0, 0xb1, 0x01, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa4,
-	0x62, 0xdd, 0x01, 0x00, 0x3c, 0x07, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
-	0xd3, 0x06, 0x00, 0x03, 0x0c, 0xb0, 0x00, 0x00, 0xd3, 0x06, 0x00, 0x0d,
-	0x18, 0xc0, 0x00, 0x00, 0x5f, 0x07, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x19, 0x0a, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05,
-	0x48, 0xc9, 0x01, 0x00, 0x0a, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00,
-	0x02, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x20, 0x40,
-	0xe5, 0xb1, 0x01, 0x00, 0x0d, 0x00, 0x2d, 0x1d, 0x48, 0xc1, 0x01, 0x00,
-	0x09, 0x00, 0x00, 0xf3, 0x38, 0x88, 0x01, 0x00, 0x0d, 0x00, 0x20, 0x50,
-	0xe7, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x2d, 0x40, 0x3f, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf4, 0x32, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x20, 0x40,
-	0xe1, 0xb1, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05, 0x48, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00, 0x02, 0x00, 0x00, 0x1d,
-	0x94, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x91, 0xb0, 0x01, 0x00,
-	0x52, 0x07, 0xa0, 0xfc, 0x90, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x91, 0xc0, 0x01, 0x00, 0x50, 0x07, 0xa2, 0x41, 0x95, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xa4, 0x96, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x2e, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4b, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
-	0x48, 0xc1, 0x01, 0x00, 0x02, 0x00, 0x00, 0x18, 0x94, 0xf4, 0x01, 0x00,
-	0x00, 0x00, 0x2d, 0x18, 0x90, 0xb0, 0x01, 0x00, 0x5c, 0x07, 0xa0, 0xfc,
-	0x90, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x91, 0xc0, 0x01, 0x00,
-	0x5a, 0x07, 0xa2, 0x41, 0x95, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
-	0xe0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00,
-	0x04, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x80, 0xb0, 0x2d, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x16, 0xb0, 0x2d, 0x00,
-	0x22, 0x00, 0x00, 0x05, 0x48, 0xc9, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x14,
-	0x48, 0xc1, 0x2d, 0x00, 0x64, 0x07, 0x43, 0x30, 0x3d, 0x07, 0x2c, 0x00,
-	0x00, 0x00, 0x00, 0x9e, 0x85, 0xb0, 0x2d, 0x00, 0x00, 0x00, 0x1b, 0x41,
-	0x3d, 0xc3, 0x2d, 0x00, 0x04, 0x00, 0x20, 0x42, 0xec, 0xb1, 0x2d, 0x00,
-	0x00, 0x00, 0x00, 0x1e, 0x82, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x2e, 0x1d,
-	0x82, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x18, 0x82, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x80, 0xc0, 0x01, 0x00, 0x6e, 0x07, 0xa0, 0x41,
-	0x80, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x40, 0x92, 0xf4, 0x01, 0x00, 0x0a, 0x00, 0x2e, 0x30,
-	0x81, 0x84, 0x01, 0x00, 0x72, 0x07, 0x90, 0x40, 0x92, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20,
-	0x93, 0xa4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x48, 0xc1, 0x01, 0x00,
-	0x04, 0x00, 0x20, 0x19, 0xe8, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1e,
-	0x16, 0xc0, 0x01, 0x00, 0x78, 0x07, 0xa0, 0x19, 0x16, 0x44, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x0d, 0x00, 0x2f, 0x1e,
-	0x32, 0xc0, 0x01, 0x00, 0x7d, 0x07, 0xa2, 0x40, 0x15, 0x6c, 0x00, 0x00,
-	0x7c, 0x07, 0xa0, 0x1c, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x63, 0xf3, 0x38, 0x94, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x05, 0x48, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x2e, 0x1e,
-	0x98, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0x1a, 0x98, 0xc0, 0x01, 0x00,
-	0x0c, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x8b, 0x07, 0x22, 0x46,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00,
-	0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x89, 0x07, 0x22, 0xf2,
-	0x64, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x86, 0x07, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x20, 0x80, 0x00, 0x03, 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0xe1, 0x91, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
-	0x12, 0x00, 0x00, 0x1a, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x17,
-	0xf0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00,
-	0x30, 0x00, 0x00, 0x10, 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x40, 0x62, 0xdd, 0x01, 0x00,
-	0x91, 0x07, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x9b, 0x07, 0x22, 0x5c,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x2d, 0x10, 0x48, 0xc1, 0x01, 0x00, 0x9b, 0x07, 0x22, 0xf2,
-	0x64, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x98, 0x07, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0xeb, 0x9f, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x20, 0x00, 0x2f, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe4, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x17, 0xf0, 0x01, 0x00, 0xa1, 0x07, 0x90, 0xf2,
-	0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00, 0x10, 0x00, 0x00, 0x14,
-	0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x2a, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x2b, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
-	0x2a, 0x94, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
-	0xac, 0x07, 0x22, 0xf2, 0x64, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0xa9, 0x07, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x17, 0x10, 0xdc, 0x01, 0x00,
-	0xc9, 0x07, 0x22, 0x40, 0x15, 0x6c, 0x00, 0x00, 0xb4, 0x07, 0xa2, 0x44,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x1f, 0x90, 0x01, 0x00,
-	0xb3, 0x07, 0x22, 0x9f, 0x13, 0x6c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x88,
-	0x1c, 0xcc, 0x01, 0x00, 0xe4, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x3f, 0xc3, 0x01, 0x00, 0xe6, 0x9f, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xb7, 0x07, 0xa2, 0x41, 0x87, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x1e, 0x3e, 0xc0, 0x01, 0x00, 0xc9, 0x07, 0x22, 0x40,
-	0x15, 0x6c, 0x00, 0x00, 0xba, 0x07, 0x20, 0x1e, 0x14, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x0a, 0x3c, 0xb0, 0x01, 0x00, 0xe5, 0x9f, 0x00, 0x1e,
-	0x24, 0x30, 0x01, 0x00, 0xbf, 0x07, 0x22, 0x08, 0x2e, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x52, 0x11, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1a,
-	0x10, 0xc0, 0x01, 0x00, 0x23, 0x07, 0x00, 0x40, 0x17, 0xb0, 0x00, 0x00,
-	0xe4, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xe5, 0x9f, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xbc, 0x07, 0xa2, 0x08, 0x2e, 0x30, 0x00, 0x00,
-	0x80, 0x80, 0x00, 0xa6, 0x04, 0xb0, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40,
-	0x87, 0x98, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0x99, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0x04, 0xe0, 0x31, 0x00, 0x00, 0xe8, 0x9f, 0x00, 0x1f,
-	0x8c, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00,
-	0xe2, 0x9f, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03,
-	0x44, 0x99, 0x01, 0x00, 0x04, 0x00, 0x22, 0x04, 0xe0, 0x31, 0x00, 0x00,
-	0xe6, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xce, 0x07, 0xa2, 0x41,
-	0x87, 0x7c, 0x00, 0x00, 0xcf, 0x07, 0x00, 0x1e, 0x3e, 0xc0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x1f, 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x05, 0xb0, 0x01, 0x00, 0xe8, 0x9f, 0x00, 0x40, 0x0f, 0x30, 0x01, 0x00,
-	0xe2, 0x9f, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xf7, 0x07, 0x00, 0xbc, 0x80, 0xb2, 0x00, 0x00,
-	0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00,
-	},
-	{
-	0x31, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x34, 0x80, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x35, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1b, 0x80, 0x81, 0x80,
-	0x80, 0x32, 0x00, 0x00, 0xe4, 0x87, 0xa2, 0x40, 0x91, 0x6f, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0x90, 0xb3, 0x01, 0x00, 0x5c, 0x95, 0x2e, 0xa2,
-	0x80, 0xb0, 0x01, 0x00, 0xff, 0x00, 0x00, 0x80, 0xf4, 0x89, 0x01, 0x00,
-	0x90, 0x95, 0x2a, 0xc8, 0xe5, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa1,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xa4, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd2, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd4, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd3, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xee,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x44, 0xb1, 0x01, 0x00, 0x18, 0x80, 0x11, 0x81,
-	0x98, 0x30, 0x00, 0x00, 0x00, 0x00, 0x51, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x1a, 0x80, 0x11, 0x82, 0x98, 0x30, 0x00, 0x00, 0x00, 0x00, 0x52, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0xe4, 0x87, 0x00, 0x48, 0xfd, 0x93, 0x00, 0x00,
-	0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x23, 0x80, 0xa2, 0x42,
-	0xfd, 0x7f, 0x00, 0x00, 0x20, 0x80, 0x00, 0x80, 0x80, 0x32, 0x00, 0x00,
-	0x22, 0x80, 0x11, 0x81, 0x82, 0x30, 0x00, 0x00, 0x22, 0x80, 0x51, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x22, 0x80, 0x11, 0x82, 0x82, 0x30, 0x00, 0x00,
-	0x22, 0x80, 0x52, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2c, 0x80, 0x00, 0x48,
-	0xfd, 0x93, 0x00, 0x00, 0x27, 0x80, 0x00, 0x80, 0x80, 0x32, 0x00, 0x00,
-	0x26, 0x80, 0xa2, 0x53, 0x07, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x51, 0x53,
-	0x07, 0x90, 0x01, 0x00, 0x2a, 0x80, 0x00, 0x52, 0x07, 0x90, 0x00, 0x00,
-	0x29, 0x80, 0xa2, 0x52, 0x07, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x52, 0x52,
-	0x07, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0xf3, 0x93, 0x01, 0x00, 0x5c, 0x95, 0x2e, 0xa2, 0x52, 0xb3, 0x01, 0x00,
-	0xff, 0x00, 0x00, 0x80, 0xf4, 0x89, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa9, 0x45, 0xb1, 0x01, 0x00,
-	0x30, 0x80, 0x00, 0x4c, 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x45, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x55, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0xc6, 0x82, 0x05, 0x40, 0x49, 0xb1, 0x00, 0x00, 0xc6, 0x82, 0x05, 0x40,
-	0x49, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x05, 0x40, 0x49, 0xb1, 0x01, 0x00,
-	0x4c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0xde, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xfd, 0x93, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0xfd, 0x83, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40,
-	0x9b, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x9c, 0xb3, 0x01, 0x00,
-	0x48, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x58, 0x95, 0x20, 0x44,
-	0xe0, 0xb1, 0x01, 0x00, 0x04, 0x94, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf2, 0x24, 0xb1, 0x01, 0x00, 0x00, 0x0c, 0x00, 0xee,
-	0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x97, 0xf0, 0x01, 0x00,
-	0x44, 0x80, 0xa2, 0x43, 0x97, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0xfd, 0x93, 0x01, 0x00, 0x00, 0xc0, 0x00, 0xa6, 0x36, 0xb1, 0x01, 0x00,
-	0xd0, 0x14, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x00, 0x38, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x00, 0x06, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x03, 0x00, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x05, 0x10, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x02, 0x09, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x60, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x88, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xa0, 0x03, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xb9, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xb1, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x60, 0x95, 0x20, 0x40,
-	0xe1, 0xb1, 0x01, 0x00, 0x70, 0x95, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x49, 0xdd, 0x91, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x91, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7b, 0xb3, 0x01, 0x00,
-	0x99, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x85, 0xb3, 0x01, 0x00, 0x5c, 0x95, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
-	0x3c, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x90, 0x06, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x2f, 0x81, 0x01, 0x00,
-	0xa2, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x9e, 0x98, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x55, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x01, 0x83, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0xc6, 0x82, 0x00, 0x41, 0xe1, 0xc1, 0x00, 0x00, 0x78, 0x18, 0x00, 0x40,
-	0x49, 0x99, 0x01, 0x00, 0x19, 0x05, 0x22, 0x54, 0x81, 0x7c, 0x00, 0x00,
-	0x6c, 0x80, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x82, 0x00, 0xb4,
-	0x69, 0xdf, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x44, 0x93, 0x93, 0x01, 0x00,
-	0x28, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x18, 0x05, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x55, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x7d, 0x80, 0x22, 0x40,
-	0x97, 0x6c, 0x00, 0x00, 0x7a, 0x80, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4f, 0x69, 0x93, 0x01, 0x00, 0x43, 0x81, 0x00, 0x58,
-	0x69, 0x93, 0x00, 0x00, 0x54, 0x16, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x80, 0x05, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x80, 0x80, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4e, 0x69, 0x93, 0x01, 0x00, 0x43, 0x81, 0x00, 0x58,
-	0x69, 0x93, 0x00, 0x00, 0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
-	0x40, 0x05, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00, 0xf6, 0x15, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x5c, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x6e, 0xfa, 0x8e, 0xb0, 0x01, 0x00, 0xc1, 0x05, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x96, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x55, 0x82, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x96, 0x80, 0x22, 0x40, 0x97, 0x6c, 0x00, 0x00,
-	0x93, 0x80, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f,
-	0x69, 0x93, 0x01, 0x00, 0x43, 0x81, 0x00, 0x58, 0x69, 0x93, 0x00, 0x00,
-	0x38, 0x05, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x48,
-	0xb2, 0xcb, 0x01, 0x00, 0xd0, 0x05, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x83, 0x02, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xb8, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xd4, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xd5, 0x9f, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xd6, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xd7, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x72, 0x01, 0x00, 0x41,
-	0x81, 0xc0, 0x00, 0x00, 0x55, 0x01, 0x51, 0x49, 0xfd, 0x93, 0x00, 0x00,
-	0x55, 0x01, 0x52, 0x4a, 0xfd, 0x93, 0x00, 0x00, 0x55, 0x01, 0x55, 0x49,
-	0xfd, 0x83, 0x00, 0x00, 0x55, 0x01, 0x56, 0x4a, 0xfd, 0x83, 0x00, 0x00,
-	0x50, 0x01, 0x91, 0x81, 0x80, 0x30, 0x00, 0x00, 0x55, 0x01, 0x45, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x50, 0x01, 0x91, 0x82, 0x80, 0x30, 0x00, 0x00,
-	0x55, 0x01, 0x46, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x80, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x16, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05,
-	0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0x48, 0xc1, 0x01, 0x00,
-	0xb4, 0x80, 0x43, 0x30, 0x3d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e,
-	0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x1b, 0x41, 0x3d, 0xc3, 0x01, 0x00,
-	0x04, 0x00, 0x20, 0x42, 0xec, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x40,
-	0x91, 0x6f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00,
-	0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
-	0x46, 0xb1, 0x01, 0x00, 0xc4, 0x80, 0xa2, 0x40, 0xe1, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xd2, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x20,
-	0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0xd0, 0xe1, 0xb1, 0x00, 0x00,
-	0xc1, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
-	0x98, 0xb0, 0x01, 0x00, 0x04, 0x80, 0x00, 0x40, 0x8b, 0xb3, 0x00, 0x00,
-	0xb1, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0xc9, 0x80, 0xa2, 0x42,
-	0x97, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xa1, 0xc1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x04,
-	0x80, 0x94, 0x00, 0x00, 0x80, 0x15, 0x3f, 0x42, 0x97, 0xe3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x03,
-	0x02, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x07, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0xcb, 0x99, 0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0xcc,
-	0xf3, 0x83, 0x01, 0x00, 0xd3, 0x80, 0xa2, 0x42, 0x97, 0x6f, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xcb, 0xf3, 0x93, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb,
-	0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x44, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xa1, 0xe0, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0x20, 0x62, 0xdd, 0x01, 0x00,
-	0xda, 0x80, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xf9, 0x02, 0x00, 0x20,
-	0x42, 0x31, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x41, 0x05, 0x6c, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0xcb, 0xdb, 0x91, 0x01, 0x00, 0x00, 0x00, 0x19, 0x41,
-	0x8b, 0xb3, 0x01, 0x00, 0x60, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0xe0, 0x80, 0xa8, 0xb1, 0x8c, 0x33, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0xe2, 0x80, 0xa8, 0xb1, 0x94, 0x33, 0x00, 0x00,
-	0xe8, 0x80, 0x14, 0xc6, 0x81, 0x32, 0x00, 0x00, 0x18, 0x00, 0x00, 0xc6,
-	0x83, 0xf4, 0x01, 0x00, 0x22, 0x83, 0x22, 0x4f, 0x83, 0x04, 0x00, 0x00,
-	0xc4, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xff, 0x01, 0x00, 0xc6,
-	0x81, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x97, 0xa3, 0x01, 0x00,
-	0xc4, 0x80, 0x1f, 0x5c, 0x97, 0x53, 0x00, 0x00, 0x6d, 0x82, 0x1e, 0xc6,
-	0x81, 0x32, 0x00, 0x00, 0xf2, 0x80, 0x22, 0x48, 0xfd, 0x7f, 0x00, 0x00,
-	0xf2, 0x80, 0x22, 0x58, 0x81, 0x6c, 0x00, 0x00, 0xf2, 0x80, 0x22, 0x48,
-	0x81, 0x6c, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x40, 0x84, 0xcc, 0x01, 0x00,
-	0xf2, 0x80, 0x9f, 0x42, 0x80, 0x32, 0x00, 0x00, 0x22, 0x83, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xc4, 0x80, 0xa2, 0xc6, 0x8f, 0x06, 0x00, 0x00,
-	0xc4, 0x80, 0x1e, 0xc6, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x43,
-	0x81, 0xf0, 0x01, 0x00, 0xf6, 0x80, 0x00, 0x40, 0x10, 0xc9, 0x00, 0x00,
-	0x44, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x7e, 0x81, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x39, 0x82, 0x00, 0xca, 0x63, 0xb3, 0x00, 0x00,
-	0x75, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x55, 0x81, 0x00, 0x4d,
-	0x83, 0xb0, 0x00, 0x00, 0x60, 0x81, 0x00, 0x4e, 0x61, 0xb1, 0x00, 0x00,
-	0x4c, 0x81, 0x00, 0x40, 0x85, 0xb0, 0x00, 0x00, 0x55, 0x81, 0x00, 0x4c,
-	0x83, 0xb0, 0x00, 0x00, 0x2e, 0x81, 0x00, 0x40, 0x85, 0xb0, 0x00, 0x00,
-	0xf8, 0x81, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00, 0x86, 0x81, 0x00, 0x40,
-	0xc1, 0xb1, 0x00, 0x00, 0xf4, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x4c, 0x81, 0x00, 0x40, 0x85, 0xb0, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x40,
-	0x49, 0xb1, 0x00, 0x00, 0x22, 0x83, 0x00, 0xca, 0x9b, 0xb3, 0x00, 0x00,
-	0x90, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00, 0x94, 0x81, 0x00, 0x40,
-	0xc1, 0xb1, 0x00, 0x00, 0x9b, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00,
-	0x9c, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00, 0x9d, 0x81, 0x00, 0x40,
-	0xc1, 0xb1, 0x00, 0x00, 0x9e, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00,
-	0x9f, 0x81, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00, 0x9f, 0x81, 0x00, 0x41,
-	0x81, 0xb0, 0x00, 0x00, 0x2d, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xae, 0x82, 0x00, 0xbb, 0xab, 0xb3, 0x00, 0x00, 0x3a, 0x82, 0x00, 0xca,
-	0xcf, 0xb3, 0x00, 0x00, 0xc8, 0x03, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00,
-	0xe8, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc4, 0x80, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x22, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xe0, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x22, 0x83, 0x00, 0xca,
-	0x77, 0xb3, 0x00, 0x00, 0x56, 0x81, 0x00, 0x4d, 0x83, 0xb0, 0x00, 0x00,
-	0x5e, 0x81, 0x00, 0x4e, 0x61, 0xb1, 0x00, 0x00, 0x4c, 0x81, 0x00, 0xbb,
-	0x85, 0xb0, 0x00, 0x00, 0x56, 0x81, 0x00, 0x4c, 0x83, 0xb0, 0x00, 0x00,
-	0x4c, 0x81, 0x00, 0xbb, 0x85, 0xb0, 0x00, 0x00, 0x2e, 0x81, 0x00, 0xbb,
-	0x85, 0xb0, 0x00, 0x00, 0x20, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x22, 0x83, 0x00, 0xca, 0x4d, 0xb3, 0x00, 0x00, 0x70, 0x05, 0x00, 0x40,
-	0x49, 0xb1, 0x00, 0x00, 0xa0, 0x05, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00,
-	0x26, 0x81, 0x22, 0x42, 0x8f, 0x6f, 0x00, 0x00, 0x28, 0x81, 0x22, 0x41,
-	0x8f, 0x6f, 0x00, 0x00, 0x2a, 0x81, 0x1e, 0xca, 0x81, 0x32, 0x00, 0x00,
-	0x2c, 0x81, 0x1f, 0xca, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca,
-	0xc9, 0xb1, 0x01, 0x00, 0x22, 0x83, 0x00, 0x42, 0x8f, 0xb3, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xca, 0xcd, 0xb1, 0x01, 0x00, 0x22, 0x83, 0x00, 0x41,
-	0x8f, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xcf, 0xb1, 0x01, 0x00,
-	0x22, 0x83, 0x00, 0x40, 0x8f, 0xb3, 0x00, 0x00, 0x00, 0x81, 0x00, 0xa6,
-	0xc6, 0xb1, 0x01, 0x00, 0x22, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0xa6, 0xc6, 0xb1, 0x01, 0x00, 0x22, 0x83, 0x00, 0x40,
-	0x8f, 0xb3, 0x00, 0x00, 0x78, 0x18, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00,
-	0x10, 0x00, 0x2f, 0x9c, 0x89, 0xb0, 0x01, 0x00, 0x46, 0x81, 0x00, 0x40,
-	0x39, 0x33, 0x01, 0x00, 0x18, 0x00, 0x2f, 0x9b, 0x89, 0xb0, 0x01, 0x00,
-	0x46, 0x81, 0x00, 0x40, 0x37, 0x33, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x9a,
-	0x89, 0xb0, 0x01, 0x00, 0x46, 0x81, 0x00, 0x40, 0x35, 0x33, 0x01, 0x00,
-	0x08, 0x00, 0x2f, 0x99, 0x89, 0xb0, 0x01, 0x00, 0x46, 0x81, 0x00, 0x40,
-	0x33, 0x33, 0x01, 0x00, 0x00, 0x80, 0x00, 0xae, 0x47, 0xc9, 0x01, 0x00,
-	0xc4, 0x80, 0xa2, 0x40, 0xe1, 0x6d, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40,
-	0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00, 0x40, 0x18, 0x00, 0x40,
-	0xe1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0xae, 0x63, 0xdd, 0x01, 0x00, 0x41, 0x81, 0x28, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x3e, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x41, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
-	0x69, 0x93, 0x01, 0x00, 0x22, 0x83, 0x1a, 0x44, 0x93, 0x93, 0x00, 0x00,
-	0x44, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x43, 0x81, 0x00, 0x58,
-	0x69, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf0, 0xd1, 0x01, 0x00,
-	0x00, 0x00, 0xa4, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x4b, 0x81, 0xa2, 0x40,
-	0xe1, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x45, 0xd1, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x41,
-	0xe1, 0xd1, 0x01, 0x00, 0x4c, 0x81, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x62, 0xb1, 0x01, 0x00, 0x52, 0x81, 0x28, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x4d, 0x81, 0x22, 0x5c, 0x77, 0x7d, 0x00, 0x00,
-	0xc4, 0x80, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x4d, 0x81, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0x63, 0xb1, 0x01, 0x00,
-	0x52, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x22, 0x83, 0x17, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x57, 0x81, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00,
-	0x57, 0x81, 0x00, 0xbb, 0x81, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x60, 0xb1, 0x01, 0x00, 0xc4, 0x80, 0xa2, 0x41, 0x76, 0x7d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x62, 0xb1, 0x01, 0x00, 0x59, 0x81, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0x63, 0xb1, 0x01, 0x00,
-	0x22, 0x83, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x5b, 0x81, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x50, 0x95, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x61, 0x81, 0x00, 0xbb, 0x87, 0xb0, 0x00, 0x00, 0x50, 0x95, 0x2f, 0x40,
-	0x87, 0xb0, 0x01, 0x00, 0x65, 0x81, 0x22, 0x40, 0x95, 0x7f, 0x00, 0x00,
-	0xc4, 0x80, 0xa2, 0x40, 0xe1, 0x6d, 0x00, 0x00, 0xc4, 0x80, 0x22, 0x40,
-	0x95, 0x6f, 0x00, 0x00, 0x22, 0x83, 0x60, 0x40, 0x95, 0x83, 0x00, 0x00,
-	0x02, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00, 0xc4, 0x80, 0x22, 0x40,
-	0x85, 0x6c, 0x00, 0x00, 0xc4, 0x80, 0xa2, 0x40, 0x85, 0x7c, 0x00, 0x00,
-	0xc4, 0x80, 0xa2, 0x4e, 0x77, 0x7d, 0x00, 0x00, 0x69, 0x81, 0x36, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x62, 0xb1, 0x01, 0x00,
-	0x6a, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x62, 0xb1, 0x01, 0x00, 0x6c, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xca, 0x63, 0xb1, 0x01, 0x00, 0x6e, 0x81, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x16, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x74, 0x81, 0x22, 0x41, 0x43, 0x51, 0x00, 0x00, 0x00, 0x08, 0x00, 0xca,
-	0x95, 0xcb, 0x01, 0x00, 0x68, 0x81, 0x00, 0x41, 0x85, 0xc0, 0x00, 0x00,
-	0x22, 0x83, 0x00, 0x40, 0xe1, 0xb1, 0x00, 0x00, 0x77, 0x81, 0xa2, 0x42,
-	0x67, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x67, 0xb3, 0x01, 0x00,
-	0x77, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x65, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x93, 0x83, 0x01, 0x00,
-	0x00, 0x00, 0x1a, 0xca, 0x69, 0x97, 0x01, 0x00, 0x22, 0x83, 0x26, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x7c, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x22, 0x83, 0x1a, 0x44, 0x93, 0x93, 0x00, 0x00, 0xc4, 0x80, 0x20, 0x43,
-	0x95, 0x6f, 0x00, 0x00, 0x22, 0x83, 0x80, 0xca, 0x67, 0x33, 0x00, 0x00,
-	0x22, 0x83, 0x22, 0x40, 0x65, 0x6f, 0x00, 0x00, 0xc4, 0x80, 0xa2, 0x48,
-	0xdb, 0x7d, 0x00, 0x00, 0x22, 0x83, 0x00, 0x6f, 0xdb, 0x91, 0x00, 0x00,
-	0x85, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x35, 0x80, 0x22, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x22, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x58, 0x95, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0x95, 0x93, 0x01, 0x00, 0x8c, 0x81, 0xa2, 0x44, 0x21, 0x6f, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x95, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5e,
-	0x95, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57, 0x95, 0x93, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xca, 0xc3, 0xb1, 0x01, 0x00, 0x8f, 0x81, 0x22, 0x5b,
-	0x95, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b, 0xfd, 0x93, 0x01, 0x00,
-	0x22, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1b, 0xfd, 0x00, 0xca,
-	0x95, 0x9b, 0x01, 0x00, 0x0d, 0x01, 0x00, 0xca, 0xc5, 0x31, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x95, 0x83, 0x01, 0x00, 0x22, 0x83, 0x00, 0xca,
-	0xc5, 0xb1, 0x00, 0x00, 0xdf, 0x6f, 0x00, 0xca, 0x95, 0x9b, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x55, 0x95, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
-	0xc7, 0xb1, 0x01, 0x00, 0x22, 0x83, 0x22, 0x5f, 0x95, 0x7f, 0x00, 0x00,
-	0x0d, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0x95, 0x83, 0x01, 0x00, 0x22, 0x83, 0x00, 0xca, 0xc7, 0xb1, 0x00, 0x00,
-	0x22, 0x83, 0x00, 0xca, 0xc9, 0xb1, 0x00, 0x00, 0x22, 0x83, 0x00, 0xca,
-	0xcb, 0xb1, 0x00, 0x00, 0x22, 0x83, 0x00, 0xca, 0xcd, 0xb1, 0x00, 0x00,
-	0x22, 0x83, 0x00, 0xca, 0xcf, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x42,
-	0x81, 0xe0, 0x01, 0x00, 0x98, 0x14, 0x00, 0x40, 0x48, 0xc9, 0x01, 0x00,
-	0x22, 0x83, 0x00, 0xca, 0xe1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x09, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
-	0xa4, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x80, 0x00, 0x41,
-	0x08, 0x99, 0x01, 0x00, 0xa6, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
-	0x20, 0x80, 0x00, 0xa6, 0x08, 0xb1, 0x01, 0x00, 0xa8, 0x81, 0x9f, 0x85,
-	0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x83, 0x84, 0x01, 0x00,
-	0xdd, 0x81, 0x22, 0x30, 0x83, 0x6c, 0x00, 0x00, 0xa7, 0x81, 0xa2, 0x4f,
-	0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x21, 0xb3, 0x01, 0x00,
-	0x02, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x10, 0x00, 0x00, 0x41, 0x84, 0xe4, 0x01, 0x00,
-	0x03, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xf0, 0xff, 0x00, 0x41, 0x86, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x84, 0x94, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xa6,
-	0x86, 0xb0, 0x01, 0x00, 0x10, 0xc4, 0x00, 0x43, 0x86, 0x98, 0x01, 0x00,
-	0xbd, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x21, 0xb3, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
-	0x1c, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0xba, 0x81, 0xa2, 0x5e,
-	0x0b, 0x7d, 0x00, 0x00, 0x04, 0x00, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00,
-	0xcf, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x41, 0x01, 0x00, 0xa6,
-	0x86, 0xb0, 0x01, 0x00, 0x50, 0x0c, 0x00, 0x43, 0x86, 0x98, 0x01, 0x00,
-	0xc2, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x21, 0xb3, 0x01, 0x00, 0xcf, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x41, 0x01, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00, 0x60, 0x0c, 0x00, 0x43,
-	0x86, 0x98, 0x01, 0x00, 0xcf, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x21, 0xb3, 0x01, 0x00, 0x18, 0x80, 0x00, 0xa6,
-	0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xff, 0xff, 0x00, 0x41, 0x82, 0x88, 0x01, 0x00, 0x00, 0x77, 0x00, 0x41,
-	0x82, 0x8c, 0x01, 0x00, 0x01, 0x02, 0x00, 0x41, 0x82, 0x98, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0x18, 0x00, 0x00, 0x41,
-	0x82, 0xdc, 0x01, 0x00, 0xcd, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x08, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
-	0x82, 0xb0, 0x01, 0x00, 0xd0, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
-	0x40, 0x13, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00, 0xd8, 0x81, 0x22, 0x43,
-	0x21, 0x6f, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
-	0x12, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0xd5, 0x81, 0xa2, 0x5e,
-	0x0b, 0x7d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00,
-	0xf3, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6,
-	0x82, 0xb0, 0x01, 0x00, 0x19, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00,
-	0xda, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x41,
-	0x08, 0x99, 0x01, 0x00, 0xf3, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x21, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x83, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5e, 0x83, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57,
-	0x83, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xc2, 0xb1, 0x01, 0x00,
-	0x0c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0x83, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xc2, 0xb1, 0x01, 0x00,
-	0x0c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
-	0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
-	0x82, 0xb0, 0x01, 0x00, 0x11, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00,
-	0xec, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x01, 0x00, 0x00, 0x41,
-	0x08, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
-	0xef, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x40, 0x13, 0x00, 0x41,
-	0x08, 0x99, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x41, 0x2e, 0x99, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x80, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xca, 0x81, 0x94, 0x01, 0x00, 0xf6, 0x81, 0xa2, 0x5e,
-	0x0b, 0x7d, 0x00, 0x00, 0x22, 0x83, 0x00, 0x40, 0x08, 0xb1, 0x00, 0x00,
-	0xc8, 0x14, 0x2e, 0xbb, 0x85, 0xb0, 0x01, 0x00, 0xf9, 0x81, 0xa2, 0x5e,
-	0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x87, 0xb0, 0x01, 0x00,
-	0x08, 0x82, 0x22, 0x43, 0x21, 0x6f, 0x00, 0x00, 0x17, 0x82, 0x22, 0x44,
-	0x21, 0x6f, 0x00, 0x00, 0x11, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
-	0x28, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x1f, 0x82, 0x22, 0x4a,
-	0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x87, 0x90, 0x01, 0x00,
-	0x03, 0x82, 0x22, 0x4d, 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x87, 0x90, 0x01, 0x00, 0x05, 0x82, 0x22, 0x4f, 0x83, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x87, 0x90, 0x01, 0x00, 0x07, 0x82, 0x22, 0x4e,
-	0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x87, 0x90, 0x01, 0x00,
-	0x1f, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x01, 0x80, 0x00, 0xa6,
-	0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x01, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x1f, 0x82, 0x22, 0x42, 0x83, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x87, 0x90, 0x01, 0x00, 0x1c, 0x80, 0x00, 0xa6,
-	0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x12, 0x82, 0x22, 0x45, 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x87, 0x90, 0x01, 0x00, 0x14, 0x82, 0x22, 0x44, 0x83, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x87, 0x90, 0x01, 0x00, 0x16, 0x82, 0x22, 0x43,
-	0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x87, 0x90, 0x01, 0x00,
-	0x1f, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x01, 0x80, 0x00, 0xa6,
-	0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x01, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x1f, 0x82, 0x22, 0x42, 0x83, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x87, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x87, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x87, 0x90, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x23, 0x82, 0x22, 0x4b, 0x83, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x87, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0xe0, 0xb1, 0x01, 0x00, 0xff, 0x7f, 0x00, 0xa2, 0xa0, 0x8b, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0xa5, 0xb3, 0x01, 0x00, 0xb8, 0x80, 0x00, 0xca,
-	0xa7, 0x33, 0x01, 0x00, 0x41, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x20, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0x29, 0x82, 0xa2, 0x5e,
-	0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x08, 0xb1, 0x01, 0x00,
-	0x2b, 0x82, 0x9f, 0x85, 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x30, 0x82, 0x14, 0xf7, 0x81, 0x30, 0x00, 0x00,
-	0x30, 0x82, 0xa2, 0x49, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
-	0xfd, 0x93, 0x01, 0x00, 0x33, 0x82, 0x15, 0xf8, 0x81, 0x14, 0x00, 0x00,
-	0x33, 0x82, 0xa2, 0x4a, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
-	0xfd, 0x93, 0x01, 0x00, 0x35, 0x82, 0xa2, 0xc8, 0x81, 0x32, 0x00, 0x00,
-	0x40, 0x00, 0x00, 0x40, 0x80, 0xdc, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40,
-	0x80, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xef, 0xb3, 0x01, 0x00,
-	0x37, 0x82, 0x42, 0x40, 0xf1, 0x33, 0x00, 0x00, 0x43, 0x81, 0x00, 0x40,
-	0x68, 0x97, 0x00, 0x00, 0x22, 0x83, 0x00, 0xbb, 0x6b, 0xb3, 0x00, 0x00,
-	0x22, 0x83, 0x00, 0xbb, 0xb1, 0xb3, 0x00, 0x00, 0x22, 0x83, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x03, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x18, 0xb1, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40,
-	0x83, 0x98, 0x01, 0x00, 0x00, 0x19, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x42, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x18, 0xb1, 0x01, 0x00, 0x40, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
-	0x00, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x19, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x43, 0xc1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
-	0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x81, 0xd0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf6, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x43, 0xc1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00, 0x4a, 0x82, 0xa2, 0x54,
-	0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf7, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00, 0x51, 0x82, 0xa2, 0x06,
-	0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x16, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x80, 0x16, 0x2e, 0x06,
-	0x83, 0xb0, 0x01, 0x00, 0x36, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
-	0x57, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x22, 0x00, 0x00, 0x40,
-	0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb, 0xf6, 0xb1, 0x01, 0x00,
-	0x5a, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x62, 0x00, 0x00, 0x40,
-	0x95, 0x98, 0x01, 0x00, 0xdc, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x16, 0x2d, 0x06, 0x83, 0xb0, 0x01, 0x00, 0x80, 0x16, 0x00, 0x40,
-	0x45, 0x99, 0x01, 0x00, 0x5c, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
-	0x60, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
-	0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71, 0xf9, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x72, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x73,
-	0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x74, 0xf9, 0xb1, 0x01, 0x00,
-	0x54, 0x00, 0x00, 0x40, 0x95, 0x98, 0x01, 0x00, 0xdc, 0x9f, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x70, 0x95, 0xb0, 0x01, 0x00,
-	0x6c, 0x82, 0x22, 0x70, 0xb5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41,
-	0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x97, 0xb0, 0x01, 0x00,
-	0xc4, 0x80, 0xa2, 0x42, 0x97, 0x6f, 0x00, 0x00, 0xb6, 0x03, 0x00, 0x40,
-	0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x42, 0x99, 0xb3, 0x01, 0x00,
-	0x78, 0x82, 0x22, 0x44, 0x81, 0x6c, 0x00, 0x00, 0x80, 0x82, 0x22, 0x48,
-	0x81, 0x6c, 0x00, 0x00, 0x7a, 0x82, 0x22, 0x4c, 0x81, 0x6c, 0x00, 0x00,
-	0x85, 0x82, 0x22, 0x50, 0x81, 0x6c, 0x00, 0x00, 0x86, 0x82, 0x22, 0x54,
-	0x81, 0x6c, 0x00, 0x00, 0x88, 0x82, 0x22, 0x58, 0x81, 0x6c, 0x00, 0x00,
-	0x8d, 0x82, 0x22, 0x5c, 0x81, 0x6c, 0x00, 0x00, 0x50, 0x01, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x09, 0xb0, 0x01, 0x00,
-	0x22, 0x83, 0x00, 0xca, 0x01, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xf3, 0x83, 0x01, 0x00,
-	0x7e, 0x82, 0xa2, 0x42, 0x05, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x05, 0xb0, 0x01, 0x00, 0x22, 0x83, 0x22, 0xca, 0x07, 0x14, 0x00, 0x00,
-	0x22, 0x83, 0x00, 0x46, 0xf3, 0x93, 0x00, 0x00, 0x22, 0x83, 0x20, 0x43,
-	0x95, 0x6f, 0x00, 0x00, 0x22, 0x83, 0x80, 0xca, 0x05, 0x30, 0x00, 0x00,
-	0x22, 0x83, 0x22, 0x01, 0x80, 0x30, 0x00, 0x00, 0xc4, 0x80, 0xa2, 0x48,
-	0xdb, 0x7d, 0x00, 0x00, 0x22, 0x83, 0x00, 0xcb, 0xdb, 0x91, 0x00, 0x00,
-	0x57, 0x01, 0x00, 0xbc, 0xab, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc,
-	0xb1, 0xb3, 0x01, 0x00, 0x22, 0x83, 0x00, 0xca, 0xcf, 0xb3, 0x00, 0x00,
-	0xff, 0x00, 0x00, 0xca, 0x81, 0x88, 0x01, 0x00, 0x22, 0x83, 0xa2, 0x40,
-	0x74, 0x7d, 0x00, 0x00, 0x60, 0x00, 0x20, 0x40, 0x60, 0x99, 0x01, 0x00,
-	0x8a, 0x82, 0xa8, 0xb1, 0x82, 0x30, 0x00, 0x00, 0x89, 0x82, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x22, 0x83, 0x00, 0xca, 0x79, 0xb3, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4e, 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0xcb, 0x83, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x90, 0x82, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x00, 0x00, 0x45, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x9b, 0x82, 0x91, 0x82, 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a,
-	0x80, 0xb0, 0x01, 0x00, 0xae, 0x9f, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
-	0x99, 0x82, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x9b, 0x82, 0x56, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00, 0xb6, 0x03, 0x00, 0x40,
-	0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x52, 0x07, 0x90, 0x01, 0x00,
-	0xd8, 0x9f, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e,
-	0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xcd, 0x83, 0x01, 0x00,
-	0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xa0, 0x82, 0xa2, 0x41,
-	0x81, 0x50, 0x00, 0x00, 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xab, 0x82, 0x91, 0x81,
-	0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x80, 0xb0, 0x01, 0x00,
-	0xae, 0x9f, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00, 0xa9, 0x82, 0xa6, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xab, 0x82, 0x55, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x52,
-	0x07, 0x90, 0x01, 0x00, 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00, 0xd8, 0x9f, 0x00, 0x41,
-	0x8b, 0xb3, 0x00, 0x00, 0xb1, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
-	0xc4, 0x14, 0x2f, 0x40, 0x99, 0xb3, 0x01, 0x00, 0x57, 0x01, 0x00, 0x40,
-	0x49, 0xb1, 0x00, 0x00, 0xa0, 0x94, 0x2e, 0x43, 0x97, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0xb2, 0x82, 0xa2, 0x41,
-	0x97, 0x50, 0x00, 0x00, 0x50, 0x95, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
-	0xac, 0x94, 0x2e, 0x43, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0xb6, 0x82, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xae, 0x03, 0x00, 0x40,
-	0xa3, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb0, 0x01, 0x00,
-	0x60, 0x15, 0x00, 0x40, 0x85, 0x98, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40,
-	0x40, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x59, 0x41, 0x94, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x41, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x40, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xa3, 0x42,
-	0x81, 0x6c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00,
-	0xbc, 0x82, 0xa0, 0x42, 0x81, 0x6c, 0x00, 0x00, 0xbc, 0x82, 0x00, 0x50,
-	0x85, 0xc0, 0x00, 0x00, 0x01, 0x83, 0xa2, 0x41, 0x01, 0x7d, 0x00, 0x00,
-	0xcf, 0x82, 0x22, 0x58, 0x73, 0x7d, 0x00, 0x00, 0x78, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0xc7, 0x82, 0xa8, 0xb1, 0x9c, 0x30, 0x00, 0x00,
-	0x30, 0x00, 0x38, 0x45, 0x9d, 0xe0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5f,
-	0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x5e, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0xc0, 0x00, 0xa6, 0x1e, 0xa4, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e,
-	0x10, 0xc9, 0x00, 0x00, 0xcf, 0x82, 0x33, 0xc4, 0x81, 0x30, 0x00, 0x00,
-	0xd2, 0x82, 0xa1, 0xad, 0x9d, 0x20, 0x00, 0x00, 0xc6, 0x82, 0x13, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x13, 0x4e, 0x5a, 0x83, 0x01, 0x00,
-	0x30, 0x00, 0x38, 0x45, 0x9d, 0xe0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5f,
-	0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5e, 0x1f, 0x7c, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x40, 0x05, 0x6c, 0x00, 0x00, 0xdd, 0x82, 0x22, 0xab,
-	0x80, 0x04, 0x00, 0x00, 0xdb, 0x82, 0xa2, 0x40, 0x01, 0x7d, 0x00, 0x00,
-	0xdd, 0x82, 0x22, 0x5f, 0x57, 0x7d, 0x00, 0x00, 0x0f, 0x88, 0x00, 0x5f,
-	0x1f, 0xb4, 0x00, 0x00, 0xdd, 0x82, 0x22, 0x5e, 0x57, 0x7d, 0x00, 0x00,
-	0x7d, 0x88, 0x00, 0x5f, 0x1f, 0xb4, 0x00, 0x00, 0xe3, 0x82, 0x22, 0x54,
-	0x73, 0x7d, 0x00, 0x00, 0x74, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0xdd, 0x82, 0xa8, 0xb1, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0x1f, 0xb4, 0x01, 0x00, 0xf4, 0x84, 0xa2, 0x5f, 0x01, 0x7c, 0x00, 0x00,
-	0x92, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xe5, 0x82, 0xa2, 0x5f,
-	0x59, 0x27, 0x00, 0x00, 0xe7, 0x82, 0xa2, 0x5c, 0x73, 0x7d, 0x00, 0x00,
-	0xee, 0x82, 0xa2, 0x5e, 0x73, 0x7d, 0x00, 0x00, 0xfa, 0x82, 0x22, 0x5c,
-	0x73, 0x7d, 0x00, 0x00, 0xfb, 0x82, 0x37, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x7c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xe8, 0x82, 0xa8, 0xb1,
-	0x36, 0x30, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0xea, 0x82, 0xa8, 0xb1, 0x00, 0x30, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
-	0x02, 0x88, 0x01, 0x00, 0x34, 0x85, 0x17, 0x5f, 0x1f, 0xb4, 0x00, 0x00,
-	0xfb, 0x82, 0x34, 0x40, 0x81, 0x32, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0xef, 0x82, 0xa8, 0xb1, 0x12, 0x30, 0x00, 0x00,
-	0xf7, 0x82, 0x52, 0x21, 0x13, 0x04, 0x00, 0x00, 0x00, 0x00, 0x14, 0x41,
-	0x2f, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x1f, 0xb4, 0x01, 0x00,
-	0xff, 0x3f, 0x00, 0x09, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x01, 0xf0, 0x01, 0x00, 0x4f, 0x83, 0x00, 0x34, 0x13, 0x84, 0x00, 0x00,
-	0xff, 0x3f, 0x14, 0x09, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0x1f, 0xb4, 0x01, 0x00, 0xc2, 0x83, 0x00, 0x43, 0x01, 0xf0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xfb, 0x82, 0x33, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4e, 0x5a, 0x7f, 0x00, 0x00,
-	0x07, 0x00, 0x00, 0x4e, 0x80, 0xe4, 0x01, 0x00, 0x00, 0x39, 0x00, 0x40,
-	0x80, 0xc8, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x40, 0x06, 0x6c, 0x00, 0x00,
-	0xc6, 0x82, 0x13, 0x4e, 0x5a, 0x93, 0x00, 0x00, 0xe4, 0x87, 0xa2, 0x48,
-	0xfd, 0x7f, 0x00, 0x00, 0x05, 0x83, 0x02, 0xe6, 0x81, 0x32, 0x00, 0x00,
-	0x06, 0x83, 0x83, 0xe5, 0x81, 0x32, 0x00, 0x00, 0x8e, 0x82, 0x00, 0x42,
-	0x97, 0xb3, 0x00, 0x00, 0x9e, 0x82, 0x00, 0x42, 0x97, 0xb3, 0x00, 0x00,
-	0x09, 0x83, 0x22, 0x46, 0xf3, 0x7f, 0x00, 0x00, 0x0c, 0x83, 0xa2, 0x41,
-	0xf3, 0x7f, 0x00, 0x00, 0xc6, 0x80, 0x00, 0x42, 0x97, 0x33, 0x01, 0x00,
-	0x0c, 0x83, 0x22, 0x44, 0xf3, 0x7f, 0x00, 0x00, 0x0c, 0x83, 0xa2, 0x41,
-	0xf3, 0x7f, 0x00, 0x00, 0xc6, 0x80, 0x00, 0x6f, 0x97, 0x33, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0xac, 0x80, 0x32, 0x00, 0x00, 0x11, 0x83, 0x22, 0x5a,
-	0x73, 0x7d, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x0e, 0x83, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0x01, 0x00, 0x00, 0xcf,
-	0x11, 0xc9, 0x00, 0x00, 0x17, 0x83, 0xa2, 0x40, 0x93, 0x7f, 0x00, 0x00,
-	0x17, 0x83, 0x22, 0x44, 0x93, 0x7f, 0x00, 0x00, 0x13, 0x83, 0x42, 0xa5,
-	0x80, 0x30, 0x00, 0x00, 0x16, 0x83, 0xa2, 0x40, 0x93, 0x7f, 0x00, 0x00,
-	0x38, 0x83, 0x1a, 0x40, 0x93, 0x93, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0xdf, 0x80, 0xa2, 0x40, 0x73, 0x7d, 0x00, 0x00,
-	0xdf, 0x87, 0x22, 0x44, 0x21, 0x6f, 0x00, 0x00, 0xd6, 0x87, 0x22, 0x40,
-	0x65, 0x7d, 0x00, 0x00, 0x00, 0x05, 0xa2, 0x5b, 0x73, 0x7d, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x49, 0x33, 0x7d, 0x00, 0x00, 0x21, 0x83, 0x22, 0x48,
-	0x33, 0x7d, 0x00, 0x00, 0xff, 0x01, 0x00, 0x99, 0x80, 0xd8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x81, 0xe0, 0x01, 0x00, 0xa8, 0x98, 0x2f, 0x40,
-	0x33, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe0, 0xc1, 0x01, 0x00,
-	0x01, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc6, 0x82, 0x00, 0x40,
-	0x8b, 0xb3, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5e, 0x1f, 0x7c, 0x00, 0x00,
-	0x04, 0x00, 0x22, 0x5f, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e,
-	0x1f, 0x90, 0x01, 0x00, 0xc6, 0x82, 0x00, 0x5f, 0x1f, 0x80, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x5e, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x5f,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x1f, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x58,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x62, 0xb1, 0x01, 0x00,
-	0xc6, 0x82, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x2c, 0x83, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0x5e, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x5f,
-	0x1f, 0x7c, 0x00, 0x00, 0x32, 0x83, 0x33, 0x40, 0x1f, 0x30, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x4e, 0x5a, 0x7f, 0x00, 0x00, 0x07, 0x00, 0x00, 0x4e,
-	0x80, 0xe4, 0x01, 0x00, 0x00, 0x39, 0x00, 0x40, 0x80, 0xc8, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0x40, 0x06, 0x6c, 0x00, 0x00, 0xc6, 0x82, 0x13, 0x4e,
-	0x5a, 0x93, 0x00, 0x00, 0x3a, 0x83, 0xa0, 0xce, 0x81, 0x50, 0x00, 0x00,
-	0x4d, 0x83, 0xa0, 0xcd, 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5,
-	0x9c, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x81, 0xb0, 0x01, 0x00,
-	0x4d, 0x83, 0x22, 0xb5, 0x81, 0x14, 0x00, 0x00, 0x80, 0x15, 0x2f, 0x40,
-	0x49, 0xb1, 0x01, 0x00, 0x3e, 0x83, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x60, 0xb4, 0x65, 0x97, 0x01, 0x00, 0xd0, 0x15, 0x2e, 0x40,
-	0x69, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x44, 0x93, 0x83, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0x40, 0xe1, 0x6d, 0x00, 0x00, 0x1a, 0x00, 0x00, 0xa2,
-	0x80, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xb1, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb5,
-	0xf1, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x80, 0x00, 0x00, 0x40, 0x62, 0xdd, 0x01, 0x00, 0x48, 0x83, 0xa8, 0xa1,
-	0xe0, 0x31, 0x00, 0x00, 0x17, 0x83, 0x00, 0x88, 0x9e, 0xb3, 0x00, 0x00,
-	0x17, 0x83, 0xa2, 0x41, 0x67, 0x6f, 0x00, 0x00, 0x17, 0x83, 0x00, 0x6f,
-	0xdb, 0x91, 0x00, 0x00, 0x4d, 0x83, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x17, 0x83, 0x1a, 0x40, 0x93, 0x83, 0x00, 0x00, 0x00, 0x04, 0x00, 0x40,
-	0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0x5a, 0x01, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40,
-	0x01, 0x6c, 0x00, 0x00, 0x00, 0x99, 0x00, 0x09, 0x46, 0xc9, 0x01, 0x00,
-	0x3f, 0x00, 0x00, 0xf3, 0x0c, 0x88, 0x01, 0x00, 0x5c, 0x83, 0xa6, 0x42,
-	0x13, 0x60, 0x00, 0x00, 0x95, 0x96, 0x00, 0x95, 0x03, 0x30, 0x01, 0x00,
-	0x57, 0x83, 0x61, 0x40, 0x81, 0x32, 0x00, 0x00, 0x75, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0x58, 0x83, 0xa8, 0xb1, 0x0c, 0x30, 0x00, 0x00,
-	0xa3, 0x96, 0x71, 0x10, 0x94, 0x30, 0x01, 0x00, 0x5d, 0x83, 0x00, 0x58,
-	0x1f, 0x90, 0x00, 0x00, 0x87, 0x96, 0x00, 0x95, 0x03, 0x30, 0x01, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x03,
-	0x48, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x2d, 0xf0, 0x2e, 0xb0, 0x01, 0x00,
-	0x80, 0x04, 0x00, 0x17, 0x96, 0x88, 0x01, 0x00, 0x04, 0x00, 0xa6, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x4a, 0xc1, 0x00, 0x17, 0x96, 0xd8, 0x01, 0x00,
-	0x04, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xee, 0x07, 0x00, 0x40,
-	0x97, 0x98, 0x01, 0x00, 0x68, 0x83, 0x23, 0x4b, 0xe4, 0x6d, 0x00, 0x00,
-	0x68, 0x83, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x1f, 0x90, 0x01, 0x00, 0x22, 0x00, 0x2f, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x6b, 0x83, 0x83, 0x17, 0x80, 0x32, 0x00, 0x00, 0x26, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x6d, 0x83, 0x85, 0x17, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0x47, 0xc1, 0x01, 0x00, 0x72, 0x83, 0x22, 0x55,
-	0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x43, 0xd1, 0x01, 0x00,
-	0x0f, 0x00, 0x00, 0xfa, 0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x97, 0xe0, 0x01, 0x00, 0x73, 0x83, 0x00, 0x4b, 0x44, 0xc1, 0x00, 0x00,
-	0x12, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0x28, 0x00, 0x00, 0xf6,
-	0x02, 0xcc, 0x01, 0x00, 0x0a, 0x00, 0x00, 0xa1, 0x42, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x16, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x28, 0xf0,
-	0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x1a, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xa2, 0x2a, 0xb0, 0x01, 0x00, 0xc0, 0x28, 0x3c, 0x46,
-	0x0d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x44, 0x95, 0xb0, 0x01, 0x00,
-	0x7f, 0x83, 0xa2, 0xf8, 0x0e, 0x30, 0x00, 0x00, 0x8f, 0x83, 0x22, 0x41,
-	0x95, 0x50, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x50, 0x49, 0xc1, 0x01, 0x00,
-	0x7b, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x7c, 0x83, 0xa2, 0xf8,
-	0x16, 0x6c, 0x00, 0x00, 0x7c, 0x83, 0xa2, 0xf8, 0x10, 0x6c, 0x00, 0x00,
-	0x7c, 0x83, 0xa2, 0xf0, 0x1a, 0x6c, 0x00, 0x00, 0x8d, 0x83, 0x22, 0x58,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00,
-	0x84, 0x83, 0x65, 0x40, 0x81, 0x32, 0x00, 0x00, 0x88, 0x83, 0xa2, 0xf3,
-	0x74, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xe6, 0x95, 0x01, 0x00,
-	0x8d, 0x83, 0x75, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
-	0x96, 0xb0, 0x01, 0x00, 0x3f, 0x00, 0x75, 0xf3, 0x0c, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x55, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x62, 0xb1, 0x01, 0x00, 0x8b, 0x83, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x8d, 0x83, 0x67, 0x40, 0x81, 0x32, 0x00, 0x00, 0x95, 0x83, 0x77, 0x41,
-	0x2d, 0xc3, 0x00, 0x00, 0x93, 0x83, 0x22, 0x58, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x55, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
-	0x62, 0xb1, 0x01, 0x00, 0x91, 0x83, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x93, 0x83, 0x67, 0x40, 0x81, 0x32, 0x00, 0x00, 0xd3, 0x83, 0x77, 0x41,
-	0x2d, 0xc3, 0x00, 0x00, 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00,
-	0x12, 0x95, 0x00, 0x07, 0x16, 0x30, 0x01, 0x00, 0xa6, 0x83, 0x22, 0x41,
-	0x81, 0x6c, 0x00, 0x00, 0x9b, 0x83, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xa5, 0x83, 0x22, 0x5f,
-	0x0f, 0x7c, 0x00, 0x00, 0x48, 0x96, 0x00, 0x5f, 0x01, 0x10, 0x01, 0x00,
-	0xa1, 0x83, 0x22, 0x40, 0x95, 0x6c, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00,
-	0x9f, 0x95, 0x00, 0x52, 0x95, 0x30, 0x01, 0x00, 0xa6, 0x95, 0x00, 0x4b,
-	0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x0f, 0x80, 0x01, 0x00,
-	0x01, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00,
-	0x8a, 0x30, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00,
-	0xb5, 0x83, 0xa2, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5a,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0xb7, 0x00, 0x0d,
-	0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
-	0x6a, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb5, 0x83, 0x22, 0x20,
-	0x85, 0x6c, 0x00, 0x00, 0xb0, 0x83, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x87, 0x95, 0x00, 0x5c,
-	0x1f, 0x00, 0x01, 0x00, 0xc2, 0x97, 0x00, 0x42, 0x61, 0x31, 0x01, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x90, 0x04, 0x00, 0x07,
-	0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0x4b, 0xe1, 0x7d, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5c,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0xb9, 0x83, 0x82, 0xf0, 0x18, 0x30, 0x00, 0x00, 0x69, 0x89, 0x00, 0x45,
-	0x8f, 0xb0, 0x00, 0x00, 0x28, 0x20, 0x00, 0xa6, 0x96, 0xb0, 0x01, 0x00,
-	0xbf, 0x83, 0x22, 0x17, 0x96, 0x04, 0x00, 0x00, 0x34, 0x04, 0x00, 0x40,
-	0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
-	0x55, 0x97, 0x00, 0x4b, 0x95, 0x30, 0x01, 0x00, 0x69, 0x89, 0x00, 0x4b,
-	0x8f, 0xb0, 0x00, 0x00, 0x57, 0x96, 0x00, 0x03, 0x48, 0x31, 0x01, 0x00,
-	0xa9, 0x93, 0x00, 0x40, 0x81, 0x30, 0x01, 0x00, 0x69, 0x89, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00,
-	0x00, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00,
-	0x8a, 0x30, 0x01, 0x00, 0x04, 0x00, 0x22, 0x40, 0x01, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x68, 0x50,
-	0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x50,
-	0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0xce, 0x83, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10,
-	0x62, 0xc9, 0x01, 0x00, 0xd0, 0x83, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x03,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x2e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
-	0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00,
-	0x00, 0x41, 0x00, 0xa6, 0x96, 0xb0, 0x01, 0x00, 0xee, 0x07, 0x2e, 0x47,
-	0x97, 0x90, 0x01, 0x00, 0xe6, 0x83, 0x22, 0x17, 0x96, 0x04, 0x00, 0x00,
-	0xe4, 0x83, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0xe4, 0x83, 0x23, 0xa2,
-	0x02, 0x6c, 0x00, 0x00, 0x9f, 0x95, 0x00, 0x52, 0x95, 0x30, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0x41, 0x97, 0x50, 0x00, 0x00, 0x0c, 0x00, 0x2d, 0x00,
-	0x12, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5c, 0x01, 0x80, 0x01, 0x00, 0xa6, 0x95, 0x00, 0x4b,
-	0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x03, 0xb0, 0x01, 0x00, 0x03, 0x84, 0x00, 0x5c,
-	0x17, 0x90, 0x00, 0x00, 0xf8, 0x83, 0x22, 0x43, 0x2f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x1f, 0x90, 0x01, 0x00, 0xf1, 0x83, 0x22, 0x5f,
-	0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x58, 0xf1, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x03,
-	0xf0, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00,
-	0xed, 0x83, 0x62, 0x42, 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x62, 0xb1, 0x01, 0x00, 0xee, 0x83, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x23, 0x83, 0x72, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x00, 0x2d, 0x03,
-	0x48, 0xb1, 0x01, 0x00, 0xff, 0x0f, 0x00, 0xf6, 0x80, 0x88, 0x01, 0x00,
-	0xf5, 0x83, 0xa2, 0xa6, 0x81, 0x6c, 0x00, 0x00, 0xf8, 0x83, 0x00, 0xf2,
-	0x3a, 0xb0, 0x00, 0x00, 0xf1, 0x84, 0xa2, 0x4b, 0xfd, 0x7f, 0x00, 0x00,
-	0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x03, 0x88, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x03, 0x84, 0x22, 0x4a, 0x2f, 0x7c, 0x00, 0x00,
-	0x03, 0x84, 0x22, 0x48, 0x2f, 0x7c, 0x00, 0x00, 0x0a, 0x00, 0x2d, 0x03,
-	0x48, 0xb1, 0x01, 0x00, 0x3f, 0x00, 0x00, 0xf2, 0x86, 0x88, 0x01, 0x00,
-	0x1f, 0x00, 0x00, 0x43, 0x84, 0x88, 0x01, 0x00, 0x05, 0x00, 0x00, 0x43,
-	0x80, 0xf4, 0x01, 0x00, 0x98, 0x94, 0x3d, 0x42, 0x81, 0xe0, 0x01, 0x00,
-	0x03, 0x84, 0xa2, 0x42, 0xe0, 0x7d, 0x00, 0x00, 0xf1, 0x84, 0xa2, 0x4b,
-	0xfd, 0x7f, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x03, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x02, 0x04, 0x00, 0x40,
-	0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
-	0x05, 0x84, 0x69, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa3,
-	0x09, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x79, 0x41, 0x47, 0xc3, 0x01, 0x00,
-	0x04, 0x00, 0xa0, 0xa1, 0x09, 0x6c, 0x00, 0x00, 0x0c, 0x84, 0x22, 0xa1,
-	0x09, 0x6c, 0x00, 0x00, 0x27, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x08, 0x84, 0x00, 0x03, 0x48, 0xb1, 0x00, 0x00, 0x46, 0x84, 0xa3, 0x92,
-	0x03, 0x6c, 0x00, 0x00, 0x25, 0x98, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x43, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
-	0x80, 0xb2, 0x01, 0x00, 0x03, 0x88, 0x27, 0x08, 0x80, 0x32, 0x00, 0x00,
-	0x13, 0x84, 0x22, 0x5c, 0x17, 0x7c, 0x00, 0x00, 0x14, 0x84, 0x00, 0x00,
-	0x2a, 0xb0, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x2a, 0xc8, 0x01, 0x00,
-	0x02, 0x00, 0x00, 0x08, 0x80, 0xc8, 0x01, 0x00, 0x18, 0x84, 0xa2, 0x43,
-	0x2f, 0x7c, 0x00, 0x00, 0x58, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x34, 0x84, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01,
-	0x8c, 0xcc, 0x01, 0x00, 0x58, 0x97, 0x00, 0x4c, 0x03, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x2e, 0x46, 0x02, 0xb0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x10,
-	0x48, 0xc9, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00,
-	0x2c, 0x00, 0x00, 0x40, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
-	0xf0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x15, 0xe0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
-	0x62, 0xdd, 0x01, 0x00, 0x21, 0x84, 0xa8, 0x54, 0x17, 0x10, 0x00, 0x00,
-	0x34, 0x84, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
-	0x2a, 0xc8, 0x01, 0x00, 0x33, 0x84, 0x22, 0x43, 0x2f, 0x7c, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x01, 0x8c, 0xcc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0x03, 0xb0, 0x01, 0x00, 0x79, 0x97, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00,
-	0x00, 0x00, 0x2e, 0x46, 0x02, 0xb0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x10,
-	0x48, 0xc9, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00,
-	0x0c, 0x00, 0x00, 0x09, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
-	0xf0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x15, 0xe0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
-	0x62, 0xdd, 0x01, 0x00, 0x34, 0x84, 0x28, 0x54, 0x17, 0x10, 0x00, 0x00,
-	0x30, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x79, 0x97, 0x00, 0x43,
-	0x61, 0x31, 0x01, 0x00, 0x36, 0x84, 0x22, 0x50, 0x2f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x56, 0x17, 0x90, 0x01, 0x00, 0x07, 0x00, 0x00, 0x17,
-	0x98, 0x88, 0x01, 0x00, 0x39, 0x84, 0xa2, 0x41, 0x99, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x55, 0x17, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x3a, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x60, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x41, 0x84, 0x22, 0x43, 0x2f, 0x7c, 0x00, 0x00, 0x16, 0x80, 0x00, 0x03,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d, 0xe4, 0xb1, 0x01, 0x00,
-	0xfa, 0x96, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0x44, 0x84, 0xa2, 0x5f,
-	0x2f, 0x7c, 0x00, 0x00, 0x80, 0x93, 0x00, 0x01, 0x38, 0x43, 0x01, 0x00,
-	0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x03, 0x88, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x48, 0x84, 0xa2, 0x4b, 0xfd, 0x7f, 0x00, 0x00,
-	0xee, 0x84, 0x00, 0x41, 0x43, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x27, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2d, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x11, 0xb0, 0x01, 0x00, 0x4b, 0x84, 0x35, 0x01,
-	0x86, 0x30, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x54, 0x84, 0x28, 0xb1, 0x30, 0x30, 0x00, 0x00, 0x4c, 0x84, 0x22, 0x4d,
-	0x75, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x80, 0xb2, 0x01, 0x00,
-	0xdb, 0x84, 0xa7, 0x40, 0x11, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x43, 0xc3, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x40, 0x27, 0x6c, 0x00, 0x00,
-	0xed, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0x54, 0x84, 0xa8, 0xb1, 0x12, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x16, 0x80, 0xb2, 0x01, 0x00, 0x5e, 0x84, 0xa7, 0x40,
-	0x11, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x43, 0xc3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x09, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
-	0x2c, 0xb0, 0x01, 0x00, 0xde, 0x07, 0x00, 0x43, 0x80, 0xce, 0x01, 0x00,
-	0x4c, 0x84, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00, 0x63, 0x84, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x40, 0x00, 0x3e, 0x43, 0x27, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
-	0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x27, 0xc0, 0x01, 0x00,
-	0x4c, 0x84, 0xa3, 0x0b, 0x87, 0x50, 0x00, 0x00, 0x00, 0x00, 0x15, 0x40,
-	0x1b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0x03, 0x48, 0x6d, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
-	0x2a, 0xc8, 0x01, 0x00, 0x40, 0x00, 0x2d, 0x40, 0x39, 0xb0, 0x01, 0x00,
-	0x6d, 0x84, 0xa2, 0x40, 0x27, 0x6c, 0x00, 0x00, 0x22, 0x00, 0x00, 0x08,
-	0x12, 0xc8, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x16, 0x30, 0x6c, 0x00, 0x00,
-	0xde, 0x07, 0x00, 0x40, 0x25, 0x98, 0x01, 0x00, 0x70, 0x84, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x12, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x30, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b,
-	0x25, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
-	0x14, 0x00, 0x20, 0x01, 0xe0, 0xb1, 0x01, 0x00, 0xee, 0x07, 0x00, 0x40,
-	0x37, 0x98, 0x01, 0x00, 0x75, 0x84, 0x23, 0x01, 0x36, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0x36, 0xb0, 0x01, 0x00, 0x80, 0x84, 0x82, 0x41,
-	0x23, 0x40, 0x00, 0x00, 0x20, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
-	0x7c, 0x84, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x79, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0xed, 0x94, 0x00, 0x43, 0x23, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x23, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x19, 0x44, 0xc9, 0x01, 0x00, 0x91, 0x84, 0x22, 0x45,
-	0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x41, 0x23, 0x6c, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x0b, 0x25, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
-	0x88, 0x84, 0xa8, 0x15, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x03, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0x25, 0xd0, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x4c,
-	0x13, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x37, 0xd0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x2b, 0xc0, 0x01, 0x00, 0x75, 0x84, 0x00, 0x45,
-	0x1f, 0x80, 0x00, 0x00, 0x93, 0x84, 0xa3, 0x12, 0x36, 0x6c, 0x00, 0x00,
-	0x94, 0x84, 0x68, 0x1b, 0x28, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x12,
-	0x28, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
-	0x97, 0x84, 0xa8, 0x15, 0xe0, 0x31, 0x00, 0x00, 0xbf, 0x84, 0x22, 0x14,
-	0x02, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x14, 0x24, 0xd0, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x14,
-	0x12, 0xc0, 0x01, 0x00, 0xb7, 0x84, 0xa2, 0x14, 0x36, 0x50, 0x00, 0x00,
-	0xa7, 0x84, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x30, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0xa5, 0x84, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0xa2, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0x48, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x5c, 0x1f, 0x80, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0xf0, 0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
-	0x2b, 0x80, 0x01, 0x00, 0x04, 0x00, 0x22, 0x50, 0x2b, 0x6c, 0x00, 0x00,
-	0xf0, 0x07, 0x00, 0x40, 0x37, 0x98, 0x01, 0x00, 0xad, 0x84, 0x23, 0x01,
-	0x36, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x36, 0xb0, 0x01, 0x00,
-	0xb8, 0x84, 0x22, 0x1b, 0x02, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10,
-	0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x5c, 0x1f, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0xf0, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x15, 0xe0, 0x8d, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
-	0x62, 0xdd, 0x01, 0x00, 0xb4, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xb8, 0x84, 0x00, 0x03, 0x48, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
-	0x2a, 0xc0, 0x01, 0x00, 0x75, 0x84, 0xa2, 0x40, 0x25, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x39, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x20, 0x13,
-	0x38, 0x6c, 0x00, 0x00, 0x40, 0x00, 0x3d, 0x43, 0x39, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0b, 0x25, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x12, 0xb0, 0x01, 0x00, 0x75, 0x84, 0x00, 0xf0, 0x30, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19,
-	0x42, 0xc9, 0x01, 0x00, 0xc6, 0x84, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x19,
-	0x62, 0xdd, 0x01, 0x00, 0xc3, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xed, 0x94, 0x00, 0x40,
-	0x2b, 0x30, 0x01, 0x00, 0x18, 0x00, 0x2e, 0x03, 0x48, 0xb1, 0x01, 0x00,
-	0xca, 0x84, 0x22, 0x50, 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56,
-	0x17, 0x90, 0x01, 0x00, 0x07, 0x00, 0x00, 0x17, 0x98, 0x88, 0x01, 0x00,
-	0xcd, 0x84, 0xa2, 0x41, 0x99, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
-	0x17, 0x90, 0x01, 0x00, 0xd0, 0x84, 0x22, 0x43, 0x2f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x54, 0x17, 0x90, 0x01, 0x00, 0x16, 0x00, 0x20, 0x1d,
-	0xe4, 0xb1, 0x01, 0x00, 0xd2, 0x84, 0xa3, 0x40, 0x27, 0x6c, 0x00, 0x00,
-	0xd4, 0x84, 0x60, 0x5f, 0x17, 0x90, 0x00, 0x00, 0x00, 0x84, 0x00, 0x0b,
-	0x16, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x60, 0x13, 0x16, 0x94, 0x01, 0x00,
-	0xfa, 0x96, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x40,
-	0x0f, 0x6c, 0x00, 0x00, 0x03, 0x88, 0xa2, 0x5f, 0x2f, 0x7c, 0x00, 0x00,
-	0x14, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
-	0x02, 0xb0, 0x01, 0x00, 0x80, 0x93, 0x00, 0x01, 0x38, 0x43, 0x01, 0x00,
-	0x03, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x03,
-	0x48, 0x6d, 0x00, 0x00, 0x04, 0x00, 0x22, 0x4d, 0x75, 0x7d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4d,
-	0x61, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x22, 0x40, 0x11, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x16, 0x62, 0xb1, 0x01, 0x00, 0xe0, 0x84, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x62, 0xb1, 0x01, 0x00,
-	0xe2, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xed, 0x84, 0x22, 0x13,
-	0x82, 0x6c, 0x00, 0x00, 0x40, 0x00, 0x3d, 0x43, 0x83, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x2c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0x62, 0xb1, 0x01, 0x00,
-	0xe8, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
-	0x62, 0xb1, 0x01, 0x00, 0xea, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xe4, 0x84, 0x00, 0x41, 0x83, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x15, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x82, 0x00, 0xa6, 0x04, 0xb0, 0x01, 0x00,
-	0xa0, 0x98, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x30, 0x05, 0x00, 0x41,
-	0x89, 0x30, 0x01, 0x00, 0x9f, 0x95, 0x00, 0x52, 0x95, 0x30, 0x01, 0x00,
-	0xa6, 0x95, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0x03, 0x88, 0x00, 0x40,
-	0x0f, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x01, 0x80, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x00, 0x0e, 0xf4, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x88, 0x01, 0x00,
-	0x05, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00,
-	0x8a, 0x30, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00,
-	0x12, 0x95, 0x00, 0x07, 0x16, 0x30, 0x01, 0x00, 0x05, 0x85, 0x22, 0x41,
-	0x81, 0x6c, 0x00, 0x00, 0x00, 0x85, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x04, 0x85, 0x22, 0x5f,
-	0x0f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x0f, 0x80, 0x01, 0x00,
-	0x06, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00,
-	0x8a, 0x30, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00,
-	0x14, 0x85, 0xa2, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5a,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0xb7, 0x00, 0x0d,
-	0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
-	0x6a, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x14, 0x85, 0x22, 0x20,
-	0x85, 0x6c, 0x00, 0x00, 0x0f, 0x85, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x87, 0x95, 0x00, 0x5c,
-	0x1f, 0x00, 0x01, 0x00, 0xc2, 0x97, 0x00, 0x42, 0x61, 0x31, 0x01, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x90, 0x04, 0x00, 0x07,
-	0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0x4b, 0xe1, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x18, 0xb0, 0x01, 0x00,
-	0x19, 0x85, 0x22, 0x3a, 0x01, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x8e, 0xb0, 0x01, 0x00, 0x69, 0x89, 0x00, 0x40, 0x01, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x2e, 0x00, 0x2d, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x1e, 0x85, 0xa2, 0x40, 0xe7, 0x6d, 0x00, 0x00,
-	0x0a, 0x00, 0x00, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x69, 0x89, 0x00, 0x40,
-	0x01, 0xb0, 0x00, 0x00, 0x17, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0x35, 0x04, 0x00, 0x40,
-	0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
-	0x87, 0x96, 0x00, 0x95, 0x03, 0x30, 0x01, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00,
-	0x22, 0x00, 0x2d, 0xf0, 0x2e, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x17,
-	0x80, 0x32, 0x00, 0x00, 0x28, 0x20, 0x00, 0xa6, 0x96, 0xb0, 0x01, 0x00,
-	0x2b, 0x85, 0x22, 0x17, 0x96, 0x04, 0x00, 0x00, 0x55, 0x97, 0x00, 0x4b,
-	0x95, 0x30, 0x01, 0x00, 0x69, 0x89, 0x00, 0x4c, 0x8f, 0xb0, 0x00, 0x00,
-	0x2d, 0x85, 0x83, 0x17, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x43, 0xc1, 0x01, 0x00, 0x2f, 0x85, 0x85, 0x17, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0x43, 0xc1, 0x01, 0x00, 0x28, 0x00, 0x00, 0xf6,
-	0x02, 0xcc, 0x01, 0x00, 0x12, 0x00, 0x00, 0xa1, 0x2a, 0xc8, 0x01, 0x00,
-	0x57, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xa9, 0x93, 0x00, 0x41,
-	0x81, 0x30, 0x01, 0x00, 0x69, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0x00, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
-	0x48, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0xf0, 0xb1, 0x01, 0x00, 0x39, 0x85, 0x64, 0x47, 0x61, 0x31, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x3a, 0x85, 0xa8, 0x1b,
-	0xe0, 0x31, 0x00, 0x00, 0x23, 0x83, 0x74, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x03, 0xe0, 0x01, 0x00, 0x04, 0x00, 0xa0, 0x05,
-	0x03, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa3, 0x09, 0x03, 0x6c, 0x00, 0x00,
-	0x08, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x6b, 0x85, 0x01, 0xfb,
-	0x08, 0x30, 0x00, 0x00, 0xd5, 0x85, 0x87, 0xfb, 0x22, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xfa, 0x0e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x14, 0xb0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00,
-	0x12, 0x95, 0x00, 0x07, 0x16, 0x30, 0x01, 0x00, 0x5c, 0x85, 0x22, 0x41,
-	0x81, 0x6c, 0x00, 0x00, 0x4b, 0x85, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x5b, 0x85, 0x22, 0x5f,
-	0x0f, 0x7c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x04, 0x7e, 0x89, 0x01, 0x00,
-	0x51, 0x85, 0xa6, 0x5f, 0x0f, 0x00, 0x00, 0x00, 0x2b, 0x94, 0x00, 0x40,
-	0x05, 0x30, 0x01, 0x00, 0x0a, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
-	0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00, 0x58, 0x85, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x13, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
-	0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0xf0,
-	0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x84, 0xb0, 0x01, 0x00,
-	0x26, 0x96, 0x00, 0x40, 0x05, 0x30, 0x01, 0x00, 0x08, 0x04, 0x00, 0x40,
-	0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
-	0x1f, 0x90, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00,
-	0x69, 0x85, 0xa2, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5a,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0xb7, 0x00, 0x0d,
-	0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
-	0x6a, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x69, 0x85, 0x22, 0x20,
-	0x85, 0x6c, 0x00, 0x00, 0x66, 0x85, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x87, 0x95, 0x00, 0x5c,
-	0x1f, 0x00, 0x01, 0x00, 0xc2, 0x97, 0x00, 0x42, 0x61, 0x31, 0x01, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x90, 0x04, 0x00, 0x07,
-	0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x18, 0xb0, 0x01, 0x00, 0x6d, 0x85, 0x21, 0x04,
-	0x80, 0x20, 0x00, 0x00, 0x6e, 0x85, 0x00, 0x40, 0x10, 0xc9, 0x00, 0x00,
-	0xa1, 0x88, 0x00, 0x4b, 0x81, 0xb0, 0x00, 0x00, 0x9c, 0x85, 0x00, 0x43,
-	0x81, 0xb0, 0x00, 0x00, 0xa0, 0x85, 0x00, 0xfb, 0x22, 0xb0, 0x00, 0x00,
-	0xa1, 0x88, 0x00, 0x41, 0x81, 0xb0, 0x00, 0x00, 0x69, 0x89, 0x00, 0x4e,
-	0x8f, 0xb0, 0x00, 0x00, 0x91, 0x85, 0x00, 0x5a, 0x8f, 0xb0, 0x00, 0x00,
-	0x76, 0x85, 0x00, 0x47, 0x8f, 0xb0, 0x00, 0x00, 0xa1, 0x88, 0x00, 0x53,
-	0x81, 0xb0, 0x00, 0x00, 0xa1, 0x88, 0x00, 0x56, 0x81, 0xb0, 0x00, 0x00,
-	0x32, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x07, 0x04, 0x00, 0x40,
-	0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
-	0x3c, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x0a,
-	0x8a, 0x30, 0x01, 0x00, 0x3d, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
-	0x18, 0x00, 0x00, 0x11, 0x8a, 0xe4, 0x01, 0x00, 0x02, 0x99, 0x00, 0xf2,
-	0x8a, 0x14, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x69, 0x89, 0xa0, 0x0a, 0xe4, 0x6d, 0x00, 0x00, 0x84, 0x85, 0xa2, 0x41,
-	0x19, 0x7c, 0x00, 0x00, 0x83, 0x85, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00,
-	0x69, 0x89, 0x00, 0x53, 0x8f, 0xb0, 0x00, 0x00, 0x69, 0x89, 0x00, 0x54,
-	0x8f, 0xb0, 0x00, 0x00, 0x8d, 0x85, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00,
-	0x87, 0x85, 0xa2, 0x0a, 0xe4, 0x6d, 0x00, 0x00, 0x69, 0x89, 0x00, 0x5d,
-	0x8f, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x80, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0a, 0x80, 0xd0, 0x01, 0x00, 0x8b, 0x85, 0xa0, 0x91,
-	0x81, 0x6c, 0x00, 0x00, 0x69, 0x89, 0x00, 0x5e, 0x8f, 0xb0, 0x00, 0x00,
-	0x25, 0x00, 0x00, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x69, 0x89, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x8f, 0x85, 0x20, 0x91, 0xe5, 0x6d, 0x00, 0x00,
-	0x69, 0x89, 0x00, 0x54, 0x8f, 0xb0, 0x00, 0x00, 0x21, 0x00, 0x00, 0x40,
-	0x8f, 0x98, 0x01, 0x00, 0x69, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x32, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x07, 0x04, 0x00, 0x40,
-	0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
-	0x3c, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x0a,
-	0x8a, 0x30, 0x01, 0x00, 0x3d, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
-	0x02, 0x99, 0x00, 0xf2, 0x8a, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x69, 0x89, 0xa0, 0x0a, 0xe4, 0x6d, 0x00, 0x00,
-	0x24, 0x00, 0x00, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x69, 0x89, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0xf3, 0x82, 0xf4, 0x01, 0x00, 0xa1, 0x88, 0xa0, 0x42,
-	0x83, 0x6c, 0x00, 0x00, 0xa1, 0x88, 0x00, 0x54, 0x81, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xf2, 0x0e, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x23, 0x40,
-	0x0f, 0x6c, 0x00, 0x00, 0x04, 0x00, 0x20, 0xaa, 0x0f, 0x6c, 0x00, 0x00,
-	0x09, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00,
-	0x8a, 0x30, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00,
-	0x00, 0xb5, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00, 0x07, 0x00, 0x00, 0x07,
-	0x16, 0x88, 0x01, 0x00, 0xae, 0x85, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
-	0x0a, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0x78, 0x98, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x04, 0x00, 0x1c, 0x0f, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0xed, 0x87, 0x00, 0x5c,
-	0x1f, 0x90, 0x00, 0x00, 0xc0, 0x85, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00,
-	0xbb, 0x85, 0xa2, 0x54, 0xfd, 0x7f, 0x00, 0x00, 0xb3, 0x85, 0x22, 0x55,
-	0xfd, 0x7f, 0x00, 0x00, 0x82, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
-	0xaa, 0x85, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x22, 0x53,
-	0xfd, 0x7f, 0x00, 0x00, 0x14, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x96, 0xb0, 0x01, 0x00, 0x10, 0x00, 0x00, 0x4b,
-	0x80, 0xf4, 0x01, 0x00, 0x0c, 0xbc, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
-	0xbb, 0x85, 0x22, 0x43, 0x80, 0x6c, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4b,
-	0x80, 0x88, 0x01, 0x00, 0xaa, 0x85, 0xa2, 0x43, 0x80, 0x6c, 0x00, 0x00,
-	0x7c, 0x96, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xbc, 0x85, 0x46, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xbf, 0x85, 0xa0, 0xf0, 0x30, 0x6f, 0x00, 0x00,
-	0xb1, 0x85, 0x1e, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x41,
-	0x31, 0xc3, 0x01, 0x00, 0x79, 0x94, 0x00, 0x40, 0x25, 0x30, 0x01, 0x00,
-	0xc4, 0x85, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x87, 0x95, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00,
-	0x14, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x5a,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x96, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x07,
-	0x18, 0xe4, 0x01, 0x00, 0x00, 0x08, 0x00, 0x0c, 0xe0, 0x99, 0x01, 0x00,
-	0x90, 0x04, 0x00, 0x07, 0x96, 0x30, 0x01, 0x00, 0x00, 0xb5, 0x00, 0x0d,
-	0x46, 0xc9, 0x01, 0x00, 0xcc, 0x85, 0x30, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
-	0xe6, 0x91, 0x01, 0x00, 0x00, 0x02, 0x00, 0xa1, 0x46, 0xc9, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
-	0xe6, 0x91, 0x01, 0x00, 0x04, 0x00, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x10, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0xa1, 0x88, 0x00, 0x40,
-	0x81, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x28, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfb, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x14, 0xb0, 0x01, 0x00, 0xe0, 0x85, 0x22, 0x46, 0x23, 0x7c, 0x00, 0x00,
-	0x04, 0x00, 0x22, 0x40, 0x87, 0x6c, 0x00, 0x00, 0xdc, 0x85, 0x22, 0x40,
-	0x87, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x1f, 0x90, 0x01, 0x00,
-	0xde, 0x85, 0x22, 0x41, 0x87, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0x1f, 0x90, 0x01, 0x00, 0xe0, 0x85, 0x22, 0x42, 0x87, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x1f, 0x90, 0x01, 0x00, 0x04, 0x00, 0x22, 0x40,
-	0x09, 0x7c, 0x00, 0x00, 0xe1, 0x85, 0x66, 0x1b, 0x2c, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xa0, 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x76, 0x41,
-	0x41, 0xc3, 0x01, 0x00, 0x13, 0x86, 0x23, 0x92, 0x15, 0x6c, 0x00, 0x00,
-	0x13, 0x86, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00, 0x19, 0x86, 0x22, 0x4b,
-	0xfd, 0x7f, 0x00, 0x00, 0x17, 0x00, 0x00, 0xd0, 0xa2, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x27, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x00, 0x0a,
-	0x24, 0xc8, 0x01, 0x00, 0xb9, 0x94, 0x00, 0x40, 0x0f, 0x30, 0x01, 0x00,
-	0x11, 0x86, 0x22, 0x08, 0x40, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0xa3, 0xc1, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x12, 0x24, 0xcc, 0x01, 0x00,
-	0xea, 0x85, 0xaa, 0x41, 0x27, 0x40, 0x00, 0x00, 0x04, 0x00, 0xa3, 0x49,
-	0x27, 0x6c, 0x00, 0x00, 0x01, 0x00, 0x00, 0x13, 0x80, 0xcc, 0x01, 0x00,
-	0x0b, 0x86, 0x26, 0x40, 0x23, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x83, 0xb0, 0x01, 0x00, 0x60, 0x00, 0x00, 0x03, 0x84, 0xc8, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x10, 0x48, 0xcd, 0x01, 0x00, 0x17, 0x00, 0x00, 0xd0,
-	0xa2, 0xc9, 0x01, 0x00, 0xf8, 0x85, 0xa2, 0x40, 0x83, 0x6c, 0x00, 0x00,
-	0x04, 0x86, 0x00, 0x41, 0x83, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x42,
-	0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x68, 0x21, 0x38, 0x96, 0x01, 0x00,
-	0x00, 0x00, 0x2e, 0x50, 0x49, 0xc1, 0x01, 0x00, 0xfd, 0x85, 0xa2, 0x44,
-	0x23, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x20,
-	0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
-	0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0x00, 0x86, 0xa8, 0x42,
-	0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x85, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0xa3, 0xc1, 0x01, 0x00, 0xf6, 0x85, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
-	0x0b, 0x86, 0x22, 0x40, 0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x08, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x0b, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
-	0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0x48, 0xb1, 0x01, 0x00, 0xee, 0x07, 0x00, 0x40, 0x25, 0x98, 0x01, 0x00,
-	0x17, 0x00, 0x00, 0xd0, 0x2a, 0xc8, 0x01, 0x00, 0x24, 0x86, 0x00, 0x17,
-	0x10, 0xb0, 0x00, 0x00, 0x04, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x19, 0x86, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb9, 0x94, 0x00, 0x92,
-	0x25, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x31, 0xb0, 0x01, 0x00,
-	0x0b, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00,
-	0x8a, 0x30, 0x01, 0x00, 0x19, 0x86, 0x22, 0x08, 0x2e, 0x30, 0x00, 0x00,
-	0x24, 0x86, 0x00, 0x41, 0x27, 0xb0, 0x00, 0x00, 0x80, 0x80, 0x00, 0xa6,
-	0x04, 0xb0, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
-	0x78, 0x98, 0x00, 0x0a, 0x8c, 0x30, 0x01, 0x00, 0x04, 0x00, 0x1c, 0x0f,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00, 0x04, 0x00, 0xa0, 0x9f,
-	0x13, 0x6c, 0x00, 0x00, 0x23, 0x86, 0x22, 0x9f, 0x13, 0x6c, 0x00, 0x00,
-	0x02, 0x00, 0x00, 0x88, 0x1c, 0xcc, 0x01, 0x00, 0x27, 0x83, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xed, 0x87, 0x00, 0x41, 0x3f, 0xc3, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x00, 0x01,
-	0x80, 0xce, 0x01, 0x00, 0x38, 0x86, 0x2a, 0x40, 0x81, 0x30, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40,
-	0x81, 0x98, 0x01, 0x00, 0x2d, 0x86, 0xa2, 0x48, 0x1f, 0x7c, 0x00, 0x00,
-	0x2d, 0x86, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0x2d, 0x86, 0xa3, 0x07,
-	0x03, 0x6c, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
-	0x30, 0x86, 0xa3, 0x40, 0x02, 0x6c, 0x00, 0x00, 0x28, 0x00, 0x00, 0x01,
-	0xf0, 0xcd, 0x01, 0x00, 0x32, 0x86, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00,
-	0x28, 0x00, 0x00, 0x40, 0xf0, 0xcd, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x0e, 0xcc, 0x01, 0x00, 0x28, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00,
-	0x28, 0x00, 0x00, 0x00, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
-	0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x36, 0x86, 0xa8, 0x5c,
-	0x1f, 0x10, 0x00, 0x00, 0x04, 0x00, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x03, 0x48, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x08, 0xb0, 0x01, 0x00,
-	0xa0, 0x01, 0x2d, 0x40, 0x00, 0xc0, 0x01, 0x00, 0x19, 0x87, 0x22, 0x0f,
-	0x42, 0x05, 0x00, 0x00, 0x4b, 0x86, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0x46, 0x86, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x43, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x4b, 0x86, 0x22, 0x07,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x42, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x07, 0x42, 0xc1, 0x01, 0x00, 0x00, 0x80, 0x00, 0xa1,
-	0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00,
-	0xc0, 0x06, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03,
-	0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x54, 0x29, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x04, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0e, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5f,
-	0x0f, 0x7c, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x14, 0x80, 0xce, 0x01, 0x00,
-	0x04, 0x00, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00, 0x42, 0x00, 0x00, 0x03,
-	0x0a, 0xc8, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xa4, 0x0c, 0xc8, 0x01, 0x00,
-	0x10, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14,
-	0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0x24, 0xd0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x14, 0x10, 0xc0, 0x01, 0x00, 0x12, 0x00, 0x00, 0x08,
-	0x10, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
-	0xfe, 0x7f, 0x00, 0x05, 0x44, 0xc9, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xa2,
-	0x86, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xe4, 0xb1, 0x01, 0x00,
-	0x79, 0x86, 0x22, 0x01, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44,
-	0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0xa4, 0x80, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x48, 0xc1, 0x01, 0x00, 0x66, 0x86, 0xa3, 0x07,
-	0x02, 0x6c, 0x00, 0x00, 0x67, 0x86, 0x68, 0x01, 0x1a, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x68, 0x07, 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d,
-	0x02, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
-	0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0a, 0xc0, 0x01, 0x00,
-	0x73, 0x86, 0x22, 0x40, 0x03, 0x6c, 0x00, 0x00, 0x73, 0x86, 0x22, 0x42,
-	0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
-	0x62, 0xdd, 0x01, 0x00, 0x99, 0x86, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x70, 0x86, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x80, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x62, 0xb1, 0x01, 0x00, 0x75, 0x86, 0xa8, 0x40,
-	0x23, 0x30, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x99, 0x86, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44,
-	0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x86, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x2e, 0x10, 0x48, 0xc1, 0x01, 0x00, 0x7e, 0x86, 0xa3, 0x12,
-	0x0e, 0x6c, 0x00, 0x00, 0x7f, 0x86, 0x60, 0x07, 0x1a, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x60, 0x12, 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x68, 0x0d,
-	0x16, 0x94, 0x01, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x16, 0xd8, 0x01, 0x00,
-	0x14, 0x99, 0x00, 0x08, 0x98, 0x30, 0x01, 0x00, 0x00, 0x00, 0x68, 0x08,
-	0x3e, 0x96, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00, 0x87, 0x86, 0xa8, 0x5c,
-	0x1f, 0x10, 0x00, 0x00, 0xb9, 0x86, 0x22, 0x0d, 0x14, 0x6c, 0x00, 0x00,
-	0x8d, 0x86, 0x22, 0x0d, 0x24, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
-	0x10, 0xc0, 0x01, 0x00, 0x92, 0x86, 0x00, 0x0d, 0x24, 0xd0, 0x00, 0x00,
-	0x04, 0x00, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x2b, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15, 0xa2, 0xb1, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x20, 0x10, 0xc8, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
-	0x25, 0x98, 0x01, 0x00, 0x94, 0x86, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
-	0x99, 0x86, 0x00, 0x41, 0x23, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x95, 0x86, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
-	0xb9, 0x86, 0x22, 0x0d, 0x14, 0x50, 0x00, 0x00, 0xb8, 0x86, 0xa2, 0x0d,
-	0x0e, 0x50, 0x00, 0x00, 0xa5, 0x86, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0xa3, 0x86, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0xa0, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03,
-	0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00,
-	0x00, 0x00, 0x2d, 0x06, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0xf0, 0x0e, 0x30, 0x00, 0x00, 0xab, 0x86, 0xa2, 0x5f,
-	0x0f, 0x7c, 0x00, 0x00, 0x60, 0x86, 0x00, 0x4c, 0x0d, 0xc0, 0x00, 0x00,
-	0x00, 0x00, 0x2e, 0x5f, 0x0f, 0x80, 0x01, 0x00, 0x60, 0x86, 0x23, 0x07,
-	0x14, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x46, 0x1f, 0x7c, 0x00, 0x00,
-	0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x24, 0x00, 0x00, 0x40,
-	0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
-	0xf0, 0xb1, 0x01, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
-	0x62, 0xdd, 0x01, 0x00, 0xb5, 0x86, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
-	0x60, 0x86, 0x00, 0x03, 0x0c, 0xb0, 0x00, 0x00, 0x60, 0x86, 0x00, 0x0d,
-	0x18, 0xc0, 0x00, 0x00, 0x04, 0x00, 0x2e, 0x14, 0x0a, 0xd0, 0x01, 0x00,
-	0x12, 0x00, 0x00, 0x05, 0x48, 0xcd, 0x01, 0x00, 0xfe, 0x7f, 0x00, 0x05,
-	0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xa4, 0x86, 0x06, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0xa1, 0x86, 0x06, 0x00, 0x00, 0x0c, 0x00, 0x2a, 0xf2,
-	0xe0, 0xb1, 0x01, 0x00, 0xc1, 0x86, 0x22, 0x40, 0x31, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x60, 0x18, 0x38, 0x96, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x00, 0x81, 0x00, 0xf6, 0x80, 0xce, 0x01, 0x00,
-	0xc5, 0x86, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x43, 0xc1, 0x01, 0x00, 0xc7, 0x86, 0x22, 0x0b, 0xed, 0x6d, 0x00, 0x00,
-	0x08, 0x00, 0x00, 0xa1, 0x42, 0xc9, 0x01, 0x00, 0x02, 0x00, 0x00, 0xa1,
-	0x46, 0xc9, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xa1, 0x86, 0x06, 0x00, 0x00,
-	0x0f, 0x00, 0x00, 0xfa, 0x94, 0x88, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x45,
-	0x95, 0x6c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x4a, 0x86, 0xe4, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf6, 0x0e, 0xb0, 0x01, 0x00, 0xd1, 0x86, 0x22, 0x47,
-	0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x1f, 0x43, 0x0e, 0x50, 0x00, 0x00,
-	0xd1, 0x86, 0xa0, 0x46, 0x0f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x0f, 0xc0, 0x01, 0x00, 0xd5, 0x86, 0x22, 0x48, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x91, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x0f, 0xa2,
-	0x42, 0x31, 0x00, 0x00, 0xd8, 0x86, 0x00, 0x40, 0x89, 0xb0, 0x00, 0x00,
-	0x0c, 0x00, 0x00, 0xa2, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x95, 0xd0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfc, 0x82, 0xb0, 0x01, 0x00, 0xdb, 0x86, 0xa0, 0x41,
-	0x90, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x91, 0xc0, 0x01, 0x00,
-	0xe0, 0x86, 0x22, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0xe0, 0x86, 0xa0, 0x43,
-	0x89, 0x6c, 0x00, 0x00, 0xe0, 0x86, 0x20, 0x45, 0x89, 0x6c, 0x00, 0x00,
-	0xe0, 0x86, 0xa0, 0x41, 0x0e, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x0f, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x89, 0xc0, 0x01, 0x00,
-	0xd8, 0x86, 0xa2, 0x41, 0x95, 0x50, 0x00, 0x00, 0xed, 0x86, 0x22, 0x48,
-	0x1f, 0x7c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x48, 0x92, 0xf4, 0x01, 0x00,
-	0xff, 0xff, 0x00, 0x48, 0x90, 0x88, 0x01, 0x00, 0xe7, 0x86, 0x90, 0x48,
-	0x92, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00,
-	0x0a, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20,
-	0x93, 0xa4, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x43, 0x80, 0xcc, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xa2, 0x80, 0xc0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x40,
-	0x42, 0x6d, 0x00, 0x00, 0x04, 0x00, 0xa2, 0xa1, 0x86, 0x06, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x46, 0x1f, 0x7c, 0x00, 0x00, 0x14, 0x99, 0x00, 0x17,
-	0x98, 0x30, 0x01, 0x00, 0xff, 0x07, 0x00, 0x17, 0x7e, 0x89, 0x01, 0x00,
-	0x04, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x30, 0x80, 0x00, 0x10,
-	0x44, 0xc9, 0x01, 0x00, 0x12, 0x00, 0x00, 0x14, 0xf0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x17, 0xf0, 0xb1, 0x01, 0x00, 0x12, 0x00, 0x00, 0x05,
-	0xe0, 0xcd, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10, 0x80, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x40,
-	0x62, 0xdd, 0x01, 0x00, 0xf7, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x02, 0x87, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44,
-	0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x10, 0x48, 0xc1, 0x01, 0x00,
-	0x01, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0xfe, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00,
-	0x05, 0x87, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0x06, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x85, 0x87, 0x00, 0x17, 0x10, 0xb0, 0x00, 0x00,
-	0x0d, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x03,
-	0x48, 0xb1, 0x01, 0x00, 0x09, 0x87, 0xa0, 0x07, 0x16, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b,
-	0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x17, 0xf0, 0x01, 0x00,
-	0x0d, 0x87, 0x90, 0xf2, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x14, 0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x2b, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x2a, 0x94, 0x01, 0x00,
-	0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x17, 0x87, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x14, 0x87, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x17, 0x10, 0xdc, 0x01, 0x00, 0x85, 0x87, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x21, 0x87, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0x21, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x1e, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x26, 0x87, 0x22, 0x07,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x42, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x07, 0x42, 0xc1, 0x01, 0x00, 0x00, 0x80, 0x00, 0xa1,
-	0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00,
-	0x04, 0x00, 0x2e, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a,
-	0xe0, 0xb1, 0x01, 0x00, 0x2b, 0x87, 0x22, 0x40, 0x31, 0x6c, 0x00, 0x00,
-	0x0c, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x60, 0x18,
-	0x38, 0x96, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x62, 0xb1, 0x01, 0x00, 0x30, 0x87, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x52,
-	0x11, 0xc0, 0x01, 0x00, 0x10, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x04, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0e, 0xb0, 0x01, 0x00,
-	0x0c, 0x00, 0x00, 0xa4, 0x0c, 0xc8, 0x01, 0x00, 0x04, 0x00, 0x22, 0x40,
-	0x15, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xa4, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
-	0x48, 0xc1, 0x01, 0x00, 0x3f, 0x87, 0xa3, 0x12, 0x0e, 0x6c, 0x00, 0x00,
-	0x40, 0x87, 0x68, 0x07, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x12,
-	0x1a, 0xb0, 0x01, 0x00, 0x14, 0x99, 0x00, 0x08, 0x98, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x68, 0x08, 0x3e, 0x96, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
-	0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00, 0x47, 0x87, 0xa8, 0x5c,
-	0x1f, 0x10, 0x00, 0x00, 0x79, 0x87, 0x22, 0x0d, 0x14, 0x6c, 0x00, 0x00,
-	0x4d, 0x87, 0x22, 0x0d, 0x24, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
-	0x10, 0xc0, 0x01, 0x00, 0x52, 0x87, 0x00, 0x0d, 0x24, 0xd0, 0x00, 0x00,
-	0x04, 0x00, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x2b, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15, 0xa2, 0xb1, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x20, 0x10, 0xc8, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
-	0x25, 0x98, 0x01, 0x00, 0x54, 0x87, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
-	0x59, 0x87, 0x00, 0x41, 0x23, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x55, 0x87, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0x0d, 0x14, 0x50, 0x00, 0x00, 0x78, 0x87, 0xa2, 0x0d,
-	0x0e, 0x50, 0x00, 0x00, 0x65, 0x87, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0x63, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x60, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03,
-	0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00,
-	0x00, 0x00, 0x2d, 0x06, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0xf0, 0x0e, 0x30, 0x00, 0x00, 0x6b, 0x87, 0xa2, 0x5f,
-	0x0f, 0x7c, 0x00, 0x00, 0x39, 0x87, 0x00, 0x4c, 0x0d, 0xc0, 0x00, 0x00,
-	0x00, 0x00, 0x2e, 0x5f, 0x0f, 0x80, 0x01, 0x00, 0x39, 0x87, 0x23, 0x07,
-	0x14, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x46, 0x1f, 0x7c, 0x00, 0x00,
-	0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x24, 0x00, 0x00, 0x40,
-	0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
-	0xf0, 0xb1, 0x01, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
-	0x62, 0xdd, 0x01, 0x00, 0x75, 0x87, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
-	0x39, 0x87, 0x00, 0x03, 0x0c, 0xb0, 0x00, 0x00, 0x39, 0x87, 0x00, 0x0d,
-	0x18, 0xc0, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x46, 0x1f, 0x7c, 0x00, 0x00,
-	0x83, 0x87, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
-	0x1f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x2d, 0x10, 0x48, 0xc1, 0x01, 0x00, 0x83, 0x87, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x80, 0x87, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x17, 0x10, 0xb0, 0x01, 0x00, 0x85, 0x87, 0x00, 0x40,
-	0x2b, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x04, 0xe0, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0xa0, 0x9f, 0x13, 0x6c, 0x00, 0x00,
-	0x8c, 0x87, 0x22, 0x9f, 0x13, 0x6c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x88,
-	0x1c, 0xcc, 0x01, 0x00, 0x27, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x8d, 0x98, 0x00, 0x41, 0x3f, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x8d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
-	0x78, 0x98, 0x00, 0x40, 0x0f, 0x30, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
-	0x1f, 0x7c, 0x00, 0x00, 0x03, 0x88, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00,
-	0x10, 0x00, 0x00, 0x00, 0x0e, 0xf4, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x01, 0x84, 0x01, 0x00,
-	0x98, 0x87, 0x22, 0x50, 0x01, 0x6c, 0x00, 0x00, 0x0d, 0x04, 0x00, 0x40,
-	0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
-	0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00, 0x12, 0x95, 0x00, 0x07,
-	0x16, 0x30, 0x01, 0x00, 0xa3, 0x87, 0x22, 0x41, 0x81, 0x6c, 0x00, 0x00,
-	0x9e, 0x87, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0xa2, 0x87, 0x22, 0x5f, 0x0f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x0f, 0x80, 0x01, 0x00, 0x0e, 0x04, 0x00, 0x40,
-	0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
-	0xed, 0x87, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00, 0xb0, 0x87, 0xa2, 0x5a,
-	0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5a, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0xb5, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x0b,
-	0xe6, 0x7d, 0x00, 0x00, 0x00, 0xb7, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x6a, 0x94, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xb0, 0x87, 0x22, 0x20, 0x85, 0x6c, 0x00, 0x00,
-	0xad, 0x87, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x87, 0x95, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00,
-	0xc2, 0x97, 0x00, 0x42, 0x61, 0x31, 0x01, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x90, 0x04, 0x00, 0x07, 0x96, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xb0, 0x01, 0x00,
-	0xa1, 0x88, 0xa2, 0x5f, 0x81, 0x6c, 0x00, 0x00, 0xa8, 0x00, 0x2d, 0x43,
-	0x19, 0x80, 0x01, 0x00, 0x37, 0x00, 0x2d, 0xf0, 0x24, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0xf3, 0x8e, 0xf4, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3,
-	0x90, 0x88, 0x01, 0x00, 0x04, 0x00, 0xa3, 0x43, 0x8f, 0x6c, 0x00, 0x00,
-	0x04, 0x00, 0xa3, 0x43, 0x91, 0x6c, 0x00, 0x00, 0xc1, 0x87, 0x22, 0x48,
-	0x8e, 0x6c, 0x00, 0x00, 0x36, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x58, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00, 0xc1, 0x87, 0x1f, 0xf0,
-	0x24, 0x6c, 0x00, 0x00, 0xc0, 0x87, 0x23, 0x41, 0x8f, 0x6c, 0x00, 0x00,
-	0xa1, 0x88, 0x00, 0x47, 0x81, 0xb0, 0x00, 0x00, 0xa1, 0x88, 0x00, 0x48,
-	0x81, 0xb0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0xb0, 0x00, 0x2d, 0xf0, 0x14, 0xb0, 0x01, 0x00, 0xc6, 0x87, 0x22, 0x0a,
-	0x90, 0x40, 0x00, 0x00, 0x58, 0x98, 0x00, 0x40, 0x91, 0x30, 0x01, 0x00,
-	0xa1, 0x88, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0xb0, 0x00, 0x2d, 0x45,
-	0x81, 0xb0, 0x01, 0x00, 0xd2, 0x87, 0x22, 0xf0, 0x2c, 0x30, 0x00, 0x00,
-	0xa3, 0x00, 0x2d, 0x30, 0x83, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x2d, 0xf3,
-	0x82, 0xe0, 0x01, 0x00, 0xcc, 0x87, 0xa3, 0x41, 0x2c, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x16, 0x82, 0xb0, 0x01, 0x00, 0x98, 0x00, 0x2d, 0xf0,
-	0x82, 0xc0, 0x01, 0x00, 0x88, 0x00, 0x2d, 0xf0, 0x82, 0xd0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf2, 0x98, 0xe8, 0x01, 0x00, 0xa1, 0x88, 0x20, 0x4c,
-	0x82, 0x6c, 0x00, 0x00, 0x7c, 0x00, 0x2d, 0x41, 0x98, 0xe8, 0x01, 0x00,
-	0xa1, 0x88, 0x20, 0xf0, 0x98, 0x6c, 0x00, 0x00, 0xed, 0x87, 0x22, 0x0a,
-	0x80, 0x32, 0x00, 0x00, 0x40, 0x02, 0x00, 0x0c, 0x7e, 0x89, 0x01, 0x00,
-	0xed, 0x87, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xa1, 0x88, 0x00, 0x49,
-	0x81, 0xb0, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x80, 0xb0, 0x01, 0x00,
-	0xda, 0x87, 0x22, 0x43, 0x21, 0x6f, 0x00, 0x00, 0x13, 0x80, 0x00, 0x40,
-	0x80, 0xdc, 0x01, 0x00, 0xdb, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x1a, 0x80, 0x00, 0x40, 0x80, 0xdc, 0x01, 0x00, 0xdb, 0x87, 0xa2, 0x5e,
-	0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0xb1, 0x01, 0x00,
-	0xdd, 0x87, 0x9f, 0x85, 0x80, 0x32, 0x00, 0x00, 0xe1, 0x87, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x1a, 0x83, 0x22, 0x40, 0x57, 0x7d, 0x00, 0x00,
-	0x01, 0x00, 0x00, 0x40, 0x57, 0x99, 0x01, 0x00, 0xe1, 0x87, 0x42, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
-	0x01, 0x83, 0x1a, 0x5b, 0x69, 0x93, 0x00, 0x00, 0xe7, 0x87, 0x22, 0x46,
-	0xf3, 0x7f, 0x00, 0x00, 0xe7, 0x87, 0xa2, 0x41, 0xf3, 0x7f, 0x00, 0x00,
-	0xc6, 0x80, 0x00, 0x42, 0x97, 0x33, 0x01, 0x00, 0x04, 0x00, 0x00, 0xcb,
-	0x81, 0xc8, 0x01, 0x00, 0xea, 0x87, 0x22, 0x40, 0xf2, 0x7f, 0x00, 0x00,
-	0xc6, 0x80, 0x00, 0x6f, 0x97, 0x33, 0x01, 0x00, 0xec, 0x87, 0x22, 0x40,
-	0x73, 0x7d, 0x00, 0x00, 0xe0, 0x80, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00,
-	0xe4, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xf4, 0x87, 0x9c, 0x0f,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
-	0xf4, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0xf1, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x2e, 0x94, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00,
-	0xf5, 0x87, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x93, 0x93, 0x01, 0x00, 0x2e, 0x94, 0x1a, 0x02, 0x68, 0x97, 0x00, 0x00,
-	0xff, 0x87, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0xff, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0xfc, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x3e, 0x94, 0x22, 0x02,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x88, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00, 0x3e, 0x94, 0x1a, 0x02,
-	0x68, 0x97, 0x00, 0x00, 0x0a, 0x88, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x0a, 0x88, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x07, 0x88, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x2f, 0x83, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00, 0x0b, 0x88, 0x42, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
-	0x00, 0x00, 0x1a, 0x02, 0x68, 0x97, 0x01, 0x00, 0x2f, 0x83, 0x00, 0x40,
-	0x05, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0xa6, 0x56, 0xb1, 0x01, 0x00,
-	0x56, 0x95, 0x2f, 0x40, 0x05, 0xb0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x40,
-	0xe7, 0x6d, 0x00, 0x00, 0xb8, 0x94, 0x29, 0x41, 0xe7, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x54, 0xef, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
-	0x0e, 0xb0, 0x01, 0x00, 0x04, 0x00, 0xa3, 0x0c, 0x55, 0x6f, 0x00, 0x00,
-	0x29, 0x00, 0x00, 0x40, 0x0d, 0x98, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
-	0x12, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x13, 0xc0, 0x01, 0x00,
-	0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00, 0x07, 0x00, 0x00, 0x07,
-	0x16, 0x88, 0x01, 0x00, 0xff, 0xff, 0x00, 0x10, 0x34, 0xd8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0x34, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x23, 0xb0, 0x01, 0x00, 0x20, 0x18, 0x00, 0x40, 0x11, 0x98, 0x01, 0x00,
-	0x04, 0x00, 0x20, 0xaa, 0x0f, 0x6c, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x0d,
-	0x42, 0xc9, 0x01, 0x00, 0x43, 0x88, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
-	0x22, 0x88, 0x60, 0x40, 0x81, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0x07,
-	0x84, 0x89, 0x01, 0x00, 0x2b, 0x88, 0x05, 0xc2, 0x24, 0x30, 0x00, 0x00,
-	0x58, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x60, 0x88, 0x70, 0xf0, 0x18, 0x30, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x0c, 0x82, 0xf4, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x41,
-	0x0e, 0x6c, 0x00, 0x00, 0x43, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x70, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x3a, 0x88, 0xa0, 0x48,
-	0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x35, 0xd0, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x1a, 0x42, 0xc9, 0x01, 0x00, 0x34, 0x88, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x1a, 0x62, 0xdd, 0x01, 0x00, 0x31, 0x88, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x20, 0x98, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x60, 0x88, 0x00, 0xf8,
-	0x18, 0x30, 0x01, 0x00, 0x35, 0x88, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00,
-	0xff, 0xff, 0x00, 0x10, 0x34, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0x34, 0x94, 0x01, 0x00, 0x20, 0x18, 0x00, 0x40, 0x11, 0x98, 0x01, 0x00,
-	0x00, 0x00, 0x2e, 0x1a, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x1a,
-	0x62, 0xdd, 0x01, 0x00, 0x3e, 0x88, 0xa8, 0x09, 0xe0, 0x31, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x35, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x11, 0xc0, 0x01, 0x00,
-	0x4f, 0x88, 0x22, 0x41, 0x0d, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x0f, 0xc0, 0x01, 0x00, 0x4b, 0x88, 0xa0, 0xaa, 0x0f, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x0f, 0xb0, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
-	0x12, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x13, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x1b, 0xb0, 0x01, 0x00, 0x1f, 0x88, 0x00, 0x41,
-	0x17, 0xb0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x09, 0x12, 0xc8, 0x01, 0x00,
-	0x1f, 0x88, 0x83, 0x41, 0x17, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x17, 0xb0, 0x01, 0x00, 0x1f, 0x88, 0x00, 0x41, 0x1b, 0xc0, 0x00, 0x00,
-	0x5a, 0x88, 0x23, 0x40, 0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x35, 0xd0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x1a, 0x42, 0xc9, 0x01, 0x00,
-	0x57, 0x88, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x1a, 0x62, 0xdd, 0x01, 0x00,
-	0x54, 0x88, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x60, 0x88, 0x00, 0xf8, 0x18, 0x30, 0x01, 0x00, 0x58, 0x88, 0xa2, 0x41,
-	0x23, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0f, 0xc0, 0x01, 0x00,
-	0x5d, 0x88, 0xa0, 0xaa, 0x0f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x0f, 0xb0, 0x01, 0x00, 0xb8, 0x94, 0x20, 0x07, 0xe4, 0xb1, 0x01, 0x00,
-	0x56, 0x95, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40,
-	0x0f, 0xb0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x80, 0xd8, 0x01, 0x00,
-	0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x0c,
-	0x7e, 0x89, 0x01, 0x00, 0x79, 0x88, 0x26, 0x54, 0x61, 0x31, 0x00, 0x00,
-	0x6c, 0x88, 0x87, 0x0c, 0x80, 0x32, 0x00, 0x00, 0x1f, 0x04, 0x00, 0x40,
-	0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x0c, 0x8a, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00, 0x0f, 0x00, 0x00, 0x40,
-	0x62, 0x99, 0x01, 0x00, 0x6c, 0x88, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x00, 0x00, 0x68, 0x88, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x74, 0x88, 0x22, 0x46, 0x19, 0x7c, 0x00, 0x00,
-	0x2a, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x0c,
-	0x8a, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00,
-	0x0d, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x00, 0x00,
-	0x6d, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x79, 0x88, 0x22, 0x49,
-	0x19, 0x7c, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x54,
-	0x77, 0x7d, 0x00, 0x00, 0x74, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x10, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x00, 0x00,
-	0x79, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x30, 0x94, 0x2f, 0x55,
-	0xf1, 0x93, 0x01, 0x00, 0x00, 0x40, 0x00, 0xa6, 0x56, 0xb1, 0x01, 0x00,
-	0x2f, 0x83, 0xa2, 0x41, 0xe5, 0x51, 0x00, 0x00, 0x64, 0x00, 0x00, 0x40,
-	0xe5, 0x99, 0x01, 0x00, 0x81, 0x88, 0x44, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x84, 0x88, 0xa2, 0x93, 0x57, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x57, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x1c, 0xab, 0x27, 0xb3, 0x01, 0x00,
-	0x2f, 0x83, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00, 0x2f, 0x83, 0x22, 0x51,
-	0xfd, 0x7f, 0x00, 0x00, 0x2f, 0x83, 0xa2, 0x41, 0x1d, 0x53, 0x00, 0x00,
-	0x50, 0x46, 0x00, 0x40, 0x1d, 0x9b, 0x01, 0x00, 0x38, 0x05, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0x10, 0x04, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00, 0x90, 0x88, 0x22, 0x40,
-	0xb5, 0x6f, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0x20, 0x04, 0x00, 0x41, 0xb5, 0x53, 0x01, 0x00, 0x2f, 0x83, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0xfd, 0x83, 0x01, 0x00,
-	0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x40, 0x05, 0x00, 0x40,
-	0x49, 0x31, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
-	0x91, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0x20, 0x04, 0x00, 0x40, 0xb5, 0x33, 0x01, 0x00, 0x60, 0x16, 0x20, 0x40,
-	0xe5, 0xb1, 0x01, 0x00, 0x55, 0x82, 0x00, 0x40, 0xb5, 0x33, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xff, 0xff, 0x00, 0x4a,
-	0xb4, 0x8b, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x0a, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x00, 0x00, 0x4a,
-	0xb4, 0xf7, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x2f, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05,
-	0x48, 0x6d, 0x00, 0x00, 0x02, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0xf2, 0x0e, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x02,
-	0x80, 0x32, 0x00, 0x00, 0x05, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf3, 0x08, 0xb0, 0x01, 0x00, 0xab, 0x88, 0x22, 0x50,
-	0x81, 0x6c, 0x00, 0x00, 0x0f, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x40, 0x8a, 0xe4, 0x01, 0x00, 0x02, 0x99, 0x00, 0x04,
-	0x8a, 0x14, 0x01, 0x00, 0x04, 0x00, 0x20, 0x48, 0x09, 0x6c, 0x00, 0x00,
-	0x04, 0x00, 0x20, 0x57, 0x81, 0x6c, 0x00, 0x00, 0x04, 0x00, 0x20, 0x40,
-	0xe6, 0xb1, 0x01, 0x00, 0x03, 0x00, 0x00, 0x40, 0x96, 0xe4, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x04, 0x96, 0xc0, 0x01, 0x00, 0xb1, 0x88, 0x00, 0x4b,
-	0x10, 0xc9, 0x00, 0x00, 0xe1, 0x8b, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x16, 0x8c, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x52, 0x8c, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x52, 0x8c, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x52, 0x8c, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x52, 0x8c, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x99, 0x8c, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0xc8, 0x8c, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0xcc, 0x8c, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x3b, 0x8e, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xdc, 0x8c, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0xda, 0x8c, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0xdd, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x95, 0x8d, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
-	0x95, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x95, 0x8d, 0x00, 0x44,
-	0x09, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0xb5, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xdd, 0x8d, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0xdd, 0x8d, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
-	0xdd, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0xdd, 0x8d, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x0c, 0x8e, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0xdd, 0x8b, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x1f, 0x8e, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x1f, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0xdd, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x21, 0x8e, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
-	0x21, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x21, 0x8e, 0x00, 0x44,
-	0x09, 0xb0, 0x00, 0x00, 0x21, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x2c, 0x8e, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x3e, 0x8e, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x2d, 0x8e, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0x3e, 0x8e, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
-	0xdd, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x40, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x34, 0x8e, 0x00, 0x44,
-	0x09, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0xdd, 0x8b, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00, 0x93, 0x8d, 0x00, 0x42,
-	0x09, 0xb0, 0x00, 0x00, 0x93, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0x93, 0x8d, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00,
-	0x42, 0x8e, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x42, 0x8e, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0x42, 0x8e, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
-	0xdd, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x49, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x4b, 0x8e, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x58, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xbe, 0x8e, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0xcc, 0x8c, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
-	0x3b, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0xc6, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xcc, 0x8c, 0x00, 0x44,
-	0x09, 0xb0, 0x00, 0x00, 0x3b, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0xda, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x93, 0x8c, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xc2, 0x8e, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0xcc, 0x8c, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
-	0x3b, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x02, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf2,
-	0x0e, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x02, 0x80, 0x32, 0x00, 0x00,
-	0x07, 0x00, 0x2d, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
-	0x08, 0xb0, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x47, 0x8a, 0xe4, 0x01, 0x00, 0x02, 0x99, 0x00, 0x04,
-	0x8a, 0x14, 0x01, 0x00, 0x04, 0x00, 0x20, 0x4e, 0x09, 0x6c, 0x00, 0x00,
-	0x2a, 0x00, 0x00, 0x47, 0x80, 0xce, 0x01, 0x00, 0x04, 0x00, 0x24, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x06, 0x00, 0x20, 0x47, 0xe6, 0xb1, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0x47, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0x96, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x96, 0xd0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x04, 0x96, 0xc0, 0x01, 0x00, 0x7a, 0x89, 0x00, 0x4b,
-	0x10, 0xc9, 0x00, 0x00, 0xf6, 0x8e, 0x00, 0x49, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x2f, 0x8f, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x36, 0x8f, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x47, 0x8f, 0x00, 0x42,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x6a, 0x8f, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x64, 0x8f, 0x00, 0x4a,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x71, 0x8f, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xdc, 0x8f, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xda, 0x8f, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x41,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x3a, 0x8f, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x44,
-	0x09, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x3a, 0x8f, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
-	0x3a, 0x8f, 0x00, 0x49, 0x09, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x4a,
-	0x09, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00,
-	0x3a, 0x8f, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x4d,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x45, 0x90, 0x00, 0x42,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x45, 0x90, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x45, 0x90, 0x00, 0x4b,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x62, 0x90, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x7a, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x53, 0x90, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x0f, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x6a, 0x8f, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
-	0x47, 0x8f, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x64, 0x8f, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xdc, 0x8f, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x71, 0x8f, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0x62, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x48,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xda, 0x8f, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x81, 0x90, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x81, 0x90, 0x00, 0x42,
-	0x09, 0xb0, 0x00, 0x00, 0xc6, 0x8b, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0xc6, 0x8b, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x81, 0x90, 0x00, 0x4b,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x41,
-	0x09, 0xb0, 0x00, 0x00, 0xac, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x8f, 0x90, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x8f, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x8f, 0x90, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0xac, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x62, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x48,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x8f, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xbb, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0xbb, 0x90, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x2c, 0x91, 0x00, 0x40,
-	0x09, 0xb0, 0x00, 0x00, 0x4e, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x40, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x87, 0x90, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x87, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x4e, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x57, 0x91, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x57, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x40, 0x91, 0x00, 0x48,
-	0x09, 0xb0, 0x00, 0x00, 0x87, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x87, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x40, 0x91, 0x00, 0x48,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x45, 0x90, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x45, 0x90, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x45, 0x90, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
-	0x62, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x48,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x45, 0x90, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x45, 0x90, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xab, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x9d, 0x90, 0x00, 0x48,
-	0x09, 0xb0, 0x00, 0x00, 0x8e, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x8e, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0xab, 0x90, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0xc6, 0x8b, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0xc6, 0x8b, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x9d, 0x90, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
-	0x8e, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x8e, 0x90, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x9d, 0x90, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x5a, 0x91, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x5a, 0x91, 0x00, 0x44,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x5a, 0x91, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x5a, 0x91, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x5a, 0x91, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x5a, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
-	0x5a, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x5a, 0x91, 0x00, 0x48,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x5a, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x5a, 0x91, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
-	0x5a, 0x91, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x77, 0x91, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x7a, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x77, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x96, 0x92, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x7a, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x96, 0x92, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x96, 0x92, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xbf, 0x92, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xbd, 0x92, 0x00, 0x4a,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xbf, 0x92, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x62, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xbd, 0x92, 0x00, 0x4a,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x67, 0x91, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x74, 0x91, 0x00, 0x42,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x74, 0x91, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x74, 0x91, 0x00, 0x4b,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x74, 0x91, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x74, 0x91, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x74, 0x91, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0x74, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x74, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x74, 0x91, 0x00, 0x4c,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x62, 0x90, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x7a, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x53, 0x90, 0x00, 0x4c,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x7d, 0x93, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x93, 0x00, 0x42,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x93, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x93, 0x00, 0x4b,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x93, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x93, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x62, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x93, 0x00, 0x4c,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x53, 0x90, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
-	0x0f, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x53, 0x90, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x7a, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x0f, 0x93, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x0f, 0x93, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x16, 0x93, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x7a, 0x90, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x6e, 0x93, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x16, 0x93, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x2c, 0x93, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xfd, 0x92, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x2c, 0x93, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xfd, 0x92, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x44, 0x93, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x7a, 0x90, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x44, 0x93, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x44, 0x93, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x47, 0x8f, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x6a, 0x8f, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x67, 0x93, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x6a, 0x8f, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
-	0x47, 0x8f, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x67, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x6e, 0x93, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x7a, 0x90, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x6e, 0x93, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x10, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x10, 0x93, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x7a, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x10, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x10, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x77, 0x93, 0x00, 0x42,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xfd, 0x92, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x77, 0x93, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x62, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x48,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xfd, 0x92, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x71, 0x8f, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x71, 0x8f, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
-	0x04, 0x00, 0x22, 0x07, 0x80, 0x32, 0x00, 0x00, 0x07, 0x00, 0x2e, 0x4b,
-	0x19, 0x90, 0x01, 0x00, 0xf8, 0x87, 0x00, 0x04, 0xe6, 0xb1, 0x00, 0x00,
-	0xc6, 0x8b, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x09, 0x97, 0x00, 0x3a,
-	0x81, 0x30, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xc6, 0x8b, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x0f,
-	0x1e, 0x8c, 0x01, 0x00, 0x6d, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xd8, 0x8b, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
-	0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
-	0xd8, 0x8b, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0xd5, 0x8b, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x1a, 0x85, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00,
-	0xd9, 0x8b, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x93, 0x93, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x02, 0x68, 0x97, 0x01, 0x00,
-	0x1a, 0x85, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05,
-	0x48, 0x6d, 0x00, 0x00, 0x04, 0x00, 0x22, 0x07, 0x80, 0x32, 0x00, 0x00,
-	0x05, 0x00, 0x2e, 0x4b, 0x19, 0x90, 0x01, 0x00, 0xf8, 0x87, 0x00, 0x04,
-	0xe6, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x87, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x8d, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0xa1, 0x44, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0xe0, 0xb1, 0x01, 0x00, 0x78, 0x98, 0x00, 0x06,
-	0x07, 0x40, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x06, 0x07, 0xd0, 0x01, 0x00, 0xd4, 0x00, 0x2e, 0x5c,
-	0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf0, 0xb1, 0x01, 0x00,
-	0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfe, 0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
-	0x96, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
-	0x96, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x96, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x96, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfe, 0x96, 0xc0, 0x01, 0x00, 0x00, 0x30, 0x00, 0x4b,
-	0x94, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x95, 0xf0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4a, 0x96, 0xc0, 0x01, 0x00, 0x5e, 0x01, 0x2e, 0x34,
-	0x97, 0x84, 0x01, 0x00, 0x02, 0x00, 0x00, 0x4b, 0xe4, 0xe5, 0x01, 0x00,
-	0x64, 0x01, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
-	0x86, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x2e, 0xa7, 0x87, 0xc0, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x40,
-	0xf1, 0x99, 0x01, 0x00, 0x58, 0x01, 0x00, 0x43, 0xf0, 0xc9, 0x01, 0x00,
-	0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
-	0x05, 0x8c, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x1a, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
-	0x08, 0x00, 0x2e, 0x40, 0x95, 0xb0, 0x01, 0x00, 0x0d, 0x8c, 0x20, 0x4b,
-	0x94, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
-	0x0a, 0x8c, 0x00, 0x41, 0x95, 0xc0, 0x00, 0x00, 0x10, 0x80, 0x00, 0x10,
-	0x44, 0xc9, 0x01, 0x00, 0x14, 0x8c, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x10, 0x8c, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x09, 0x97, 0x00, 0x40, 0x81, 0x30, 0x01, 0x00,
-	0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x0c, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x86, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x88, 0xb0, 0x01, 0x00, 0x14, 0x80, 0x00, 0x03,
-	0x98, 0xc8, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xa1, 0x98, 0x6c, 0x00, 0x00,
-	0x1b, 0x8c, 0x44, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1e, 0x8c, 0xa2, 0x4c,
-	0xfd, 0x7f, 0x00, 0x00, 0x1f, 0x8c, 0x00, 0x4c, 0xfd, 0x93, 0x00, 0x00,
-	0x20, 0x8c, 0x20, 0xf0, 0x56, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x56, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x64, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x64, 0x00, 0x00, 0x40,
-	0x80, 0xcc, 0x01, 0x00, 0x04, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xd8, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x43,
-	0x81, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
-	0x64, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x70, 0x00, 0x00, 0x05,
-	0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x2b, 0x8c, 0xa8, 0x44, 0xe0, 0x31, 0x00, 0x00,
-	0x10, 0x00, 0x00, 0x10, 0x8c, 0xc8, 0x01, 0x00, 0x00, 0x80, 0x00, 0x46,
-	0x44, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
-	0x68, 0x01, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00, 0x64, 0x00, 0x00, 0x43,
-	0xf0, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x24, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0x62, 0xb1, 0x01, 0x00, 0x34, 0x8c, 0xa8, 0x44, 0xe0, 0x31, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x09, 0x00, 0x00, 0x07,
-	0x86, 0xe4, 0x01, 0x00, 0x38, 0x00, 0x2e, 0xa7, 0x87, 0xc0, 0x01, 0x00,
-	0x8b, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x3c, 0x8c, 0x22, 0x43,
-	0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00,
-	0x3f, 0x8c, 0x22, 0x44, 0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0x45, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x19, 0x90, 0x01, 0x00,
-	0x68, 0x01, 0x20, 0xa2, 0xe4, 0xb1, 0x01, 0x00, 0x88, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x43, 0x8c, 0x23, 0x0b, 0xe5, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x19, 0x90, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x44, 0xc9, 0x01, 0x00, 0x50, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
-	0x58, 0x01, 0x00, 0x43, 0xf0, 0xc9, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05,
-	0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x48, 0x8c, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x5c, 0x00, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x60, 0xf0, 0x96, 0xb0, 0x01, 0x00,
-	0xa0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf2,
-	0x80, 0x32, 0x00, 0x00, 0x09, 0x97, 0x00, 0x41, 0x81, 0x30, 0x01, 0x00,
-	0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x55, 0x8c, 0xa2, 0x49,
-	0x19, 0x7c, 0x00, 0x00, 0x86, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x59, 0x8c, 0x00, 0x40, 0xe5, 0xb1, 0x00, 0x00, 0x86, 0x00, 0x2f, 0x49,
-	0x19, 0x80, 0x01, 0x00, 0x59, 0x8c, 0xa2, 0xf2, 0x80, 0x32, 0x00, 0x00,
-	0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0xe7, 0x91, 0x01, 0x00, 0x5c, 0x8c, 0xa2, 0x46, 0x19, 0x7c, 0x00, 0x00,
-	0xa0, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x60, 0x8c, 0x00, 0x40,
-	0xe5, 0xb1, 0x00, 0x00, 0xa0, 0x00, 0x2f, 0x46, 0x19, 0x80, 0x01, 0x00,
-	0x60, 0x8c, 0xa2, 0xf2, 0x80, 0x32, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xe7, 0x91, 0x01, 0x00,
-	0x07, 0x00, 0x00, 0x4e, 0x80, 0xe4, 0x01, 0x00, 0x00, 0x39, 0x00, 0x40,
-	0x80, 0xc8, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x40, 0x06, 0x6c, 0x00, 0x00,
-	0xa8, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x34, 0x00, 0x2d, 0xf0,
-	0x24, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x0c, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfb, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
-	0x12, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3, 0x16, 0x88, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0xf3, 0x14, 0xf4, 0x01, 0x00, 0x90, 0x8c, 0x26, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x76, 0x8c, 0x22, 0x0a, 0x16, 0x6c, 0x00, 0x00,
-	0x58, 0x00, 0x3d, 0x43, 0x13, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x84, 0x30, 0x00, 0x00,
-	0x15, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x13, 0xc0, 0x01, 0x00, 0x75, 0x8c, 0xa0, 0x43,
-	0x13, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x13, 0xb0, 0x01, 0x00,
-	0x6b, 0x8c, 0x00, 0x41, 0x15, 0xd0, 0x00, 0x00, 0x90, 0x8c, 0x22, 0x0a,
-	0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x08, 0x12, 0x6c, 0x00, 0x00,
-	0x58, 0x00, 0x3d, 0x43, 0x13, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x84, 0x30, 0x00, 0x00,
-	0x15, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x40, 0x00, 0x20, 0x40,
-	0xe1, 0xb1, 0x01, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x90, 0x8c, 0x22, 0x41,
-	0x15, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x11, 0xc0, 0x01, 0x00,
-	0x83, 0x8c, 0xa0, 0x43, 0x11, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x11, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x06, 0x10, 0x6c, 0x00, 0x00,
-	0x58, 0x00, 0x3d, 0x43, 0x11, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x36, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x00, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x83, 0xb0, 0x01, 0x00, 0x4e, 0x97, 0x00, 0x47,
-	0x61, 0x31, 0x01, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x2b, 0x94, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x8c, 0x8c, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x7f, 0x8c, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
-	0x37, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x80, 0x97, 0x00, 0x51,
-	0x81, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x37, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf3,
-	0x80, 0x32, 0x00, 0x00, 0x34, 0x00, 0x2e, 0x41, 0xf5, 0xb1, 0x01, 0x00,
-	0x00, 0x11, 0x00, 0x40, 0xe5, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x48,
-	0x19, 0x7c, 0x00, 0x00, 0x9d, 0x8c, 0x00, 0x48, 0x19, 0x90, 0x00, 0x00,
-	0x37, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf3,
-	0x80, 0x32, 0x00, 0x00, 0x34, 0x00, 0x2e, 0x41, 0xf5, 0xb1, 0x01, 0x00,
-	0x00, 0x11, 0x00, 0x40, 0xe5, 0x99, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00,
-	0xa4, 0x8c, 0x22, 0x45, 0x23, 0x7c, 0x00, 0x00, 0xb0, 0x00, 0x2f, 0xf0,
-	0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0xf0, 0x8c, 0xc0, 0x01, 0x00,
-	0x7c, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa3, 0xf0,
-	0x8c, 0x6c, 0x00, 0x00, 0x90, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x35, 0x00, 0x2d, 0xf0, 0x8c, 0xb0, 0x01, 0x00, 0x34, 0x00, 0x2d, 0xf3,
-	0x84, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf3, 0x84, 0x6c, 0x00, 0x00,
-	0x58, 0x00, 0x3e, 0x43, 0x85, 0xe0, 0x01, 0x00, 0xab, 0x8c, 0x22, 0x48,
-	0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x8d, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x68, 0x0a, 0x8c, 0xc0, 0x01, 0x00, 0x38, 0x00, 0x2a, 0x4a,
-	0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00,
-	0x3c, 0x00, 0x20, 0x1b, 0xe0, 0xb1, 0x01, 0x00, 0x10, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x38, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x26, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf8,
-	0x02, 0x30, 0x00, 0x00, 0xb9, 0x8c, 0x23, 0x01, 0x14, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x82, 0xb0, 0x01, 0x00, 0x4c, 0x00, 0x20, 0xf0, 0xe4, 0xb1, 0x01, 0x00,
-	0x44, 0x00, 0x20, 0x40, 0xe0, 0xb1, 0x01, 0x00, 0x48, 0x00, 0x20, 0x41,
-	0xe0, 0xb1, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0x10, 0x32, 0xb0, 0x01, 0x00,
-	0x58, 0x98, 0x00, 0xf0, 0x24, 0x30, 0x01, 0x00, 0xc2, 0x8c, 0xa2, 0x44,
-	0x81, 0x6c, 0x00, 0x00, 0xc0, 0x8c, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0xb6, 0x95, 0x00, 0x40, 0x3b, 0x30, 0x01, 0x00, 0xea, 0x8c, 0xa2, 0x08,
-	0x3c, 0x30, 0x00, 0x00, 0xc2, 0x8c, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xb9, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xea, 0x8c, 0xa2, 0x08,
-	0x3c, 0x30, 0x00, 0x00, 0x50, 0x00, 0x20, 0x1c, 0xe0, 0xb1, 0x01, 0x00,
-	0x54, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00, 0x4e, 0x00, 0x20, 0x01,
-	0xe4, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x20, 0x0a, 0xe0, 0xb1, 0x01, 0x00,
-	0x80, 0x97, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x8f, 0x95, 0x00, 0xf3, 0x94, 0x30, 0x01, 0x00, 0x9d, 0x8c, 0x22, 0x4a,
-	0x80, 0x32, 0x00, 0x00, 0xce, 0x8c, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x8f, 0x95, 0x00, 0xf3,
-	0x94, 0x30, 0x01, 0x00, 0x04, 0x00, 0x20, 0x43, 0x97, 0x6c, 0x00, 0x00,
-	0x58, 0x00, 0x3e, 0x43, 0x97, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1b,
-	0xf0, 0xb1, 0x01, 0x00, 0x1f, 0x00, 0x60, 0x00, 0x00, 0x8c, 0x01, 0x00,
-	0xdd, 0x8b, 0x85, 0x11, 0x80, 0x32, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0xb0, 0x00, 0x2f, 0xf0, 0x8c, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x60, 0xf0, 0x8c, 0xc0, 0x01, 0x00, 0x7c, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa3, 0xf0, 0x8c, 0x6c, 0x00, 0x00,
-	0x80, 0x97, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x22, 0x49, 0x19, 0x7c, 0x00, 0x00,
-	0xdc, 0x8c, 0x00, 0x49, 0x19, 0x80, 0x00, 0x00, 0xe1, 0x8c, 0x22, 0x41,
-	0x19, 0x7c, 0x00, 0x00, 0xb6, 0x95, 0x00, 0x40, 0x3b, 0x30, 0x01, 0x00,
-	0xe5, 0x8c, 0xa2, 0x08, 0x3c, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x5f,
-	0x81, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xb9, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xe5, 0x8c, 0xa2, 0x08,
-	0x3c, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00,
-	0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x50, 0x00, 0x2d, 0x10,
-	0x32, 0xb0, 0x01, 0x00, 0x54, 0x00, 0x2d, 0xf0, 0x38, 0xb0, 0x01, 0x00,
-	0x4e, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00, 0x40, 0x00, 0x2d, 0xf2,
-	0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x14, 0xb0, 0x01, 0x00,
-	0x30, 0x00, 0x00, 0x10, 0x8c, 0xc8, 0x01, 0x00, 0x00, 0x80, 0x00, 0x46,
-	0x44, 0xc9, 0x01, 0x00, 0x68, 0x01, 0x2d, 0x44, 0x61, 0xb1, 0x01, 0x00,
-	0x10, 0x00, 0x68, 0xf2, 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
-	0xf0, 0xb1, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0b, 0x37, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x36, 0xd0, 0x01, 0x00, 0x5c, 0x01, 0x2e, 0x40, 0x10, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x06, 0x80, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x52,
-	0x81, 0xd0, 0x01, 0x00, 0x12, 0x97, 0x00, 0x40, 0xe4, 0x31, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x46, 0x62, 0xdd, 0x01, 0x00, 0xf6, 0x8c, 0xa8, 0x40,
-	0x23, 0x30, 0x00, 0x00, 0x08, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x10, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x04, 0x8d, 0x82, 0x41,
-	0x23, 0x40, 0x00, 0x00, 0x20, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
-	0x01, 0x8d, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0xfe, 0x8c, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x23, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19, 0x44, 0xc9, 0x01, 0x00,
-	0x0c, 0x8d, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x08, 0x8d, 0xa3, 0x01,
-	0x0c, 0x6c, 0x00, 0x00, 0x09, 0x8d, 0x00, 0x06, 0x04, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0x04, 0xb0, 0x01, 0x00, 0x0b, 0x8d, 0x20, 0x02,
-	0x36, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x04, 0xb0, 0x01, 0x00,
-	0x0f, 0x8d, 0x00, 0x02, 0xe0, 0xb1, 0x00, 0x00, 0x0e, 0x8d, 0xa3, 0x01,
-	0x0c, 0x6c, 0x00, 0x00, 0x0f, 0x8d, 0x00, 0x06, 0x04, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0x04, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x68, 0x02,
-	0x16, 0x94, 0x01, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x16, 0xd8, 0x01, 0x00,
-	0x00, 0x00, 0x68, 0x08, 0x3e, 0x96, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1c,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00, 0x14, 0x8d, 0xa8, 0x13,
-	0xe0, 0x31, 0x00, 0x00, 0x51, 0x8d, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00,
-	0x44, 0x00, 0x2d, 0x02, 0x0c, 0xd0, 0x01, 0x00, 0x3c, 0x8d, 0xa2, 0x02,
-	0x02, 0x50, 0x00, 0x00, 0x22, 0x8d, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
-	0x20, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x21, 0x8d, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x1d, 0x8d, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x44, 0x00, 0x2d, 0x5c,
-	0x1f, 0x80, 0x01, 0x00, 0x48, 0x00, 0x2d, 0xf0, 0x38, 0xb0, 0x01, 0x00,
-	0x4c, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00, 0x38, 0x00, 0x2f, 0xf2,
-	0x02, 0xb0, 0x01, 0x00, 0x3e, 0x8d, 0x22, 0x01, 0x14, 0x6c, 0x00, 0x00,
-	0x04, 0x00, 0xa4, 0x40, 0x81, 0x32, 0x00, 0x00, 0x30, 0x8d, 0x22, 0x46,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00,
-	0x20, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x2f, 0x8d, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x2c, 0x8d, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x38, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x94, 0xb0, 0x01, 0x00, 0x38, 0x00, 0x2d, 0xf0, 0x96, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0xe1, 0xc1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x03,
-	0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x22, 0x4a, 0xf1, 0xb1, 0x01, 0x00,
-	0x44, 0x00, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0xe0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
-	0x62, 0xdd, 0x01, 0x00, 0x39, 0x8d, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00,
-	0x3e, 0x8d, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-	0x38, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x24, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x4c, 0x8d, 0x22, 0x06, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x33, 0xc0, 0x01, 0x00, 0x4a, 0x8d, 0xa2, 0x02, 0x36, 0x6c, 0x00, 0x00,
-	0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x8f, 0x0d,
-	0x42, 0x31, 0x00, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x80, 0x32, 0x00, 0x00,
-	0x04, 0x00, 0x22, 0x5c, 0xe1, 0x7d, 0x00, 0x00, 0x04, 0x00, 0xa2, 0xf0,
-	0x6a, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0xf8, 0x10, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5c, 0x11, 0x80, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
-	0x37, 0x98, 0x01, 0x00, 0xfa, 0x8c, 0x00, 0xa1, 0x1a, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00, 0xfa, 0x8c, 0x00, 0x02,
-	0x36, 0xd0, 0x00, 0x00, 0x50, 0x00, 0x20, 0x1c, 0xe0, 0xb1, 0x01, 0x00,
-	0x54, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00, 0x4e, 0x00, 0x20, 0x01,
-	0xe4, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x20, 0x0a, 0xe0, 0xb1, 0x01, 0x00,
-	0x58, 0x8d, 0x00, 0x5f, 0x01, 0xb0, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x02,
-	0x02, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x02, 0x0c, 0x6c, 0x00, 0x00,
-	0x37, 0x00, 0x2d, 0x46, 0x01, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3,
-	0x80, 0xf4, 0x01, 0x00, 0x57, 0x8d, 0xa0, 0x43, 0x81, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x55, 0x01, 0xb0, 0x01, 0x00, 0x40, 0x00, 0x20, 0x40,
-	0xe1, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00,
-	0x5e, 0x8d, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
-	0x5b, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x0d, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x65, 0x8d, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x62, 0x8d, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x60, 0x01, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b,
-	0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x17, 0xf0, 0x01, 0x00,
-	0x6a, 0x8d, 0x90, 0xf2, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00,
-	0x32, 0x00, 0x00, 0xa6, 0x2a, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
-	0x2a, 0x94, 0x01, 0x00, 0x6d, 0x8d, 0x45, 0x48, 0x61, 0x31, 0x00, 0x00,
-	0x00, 0xd0, 0x00, 0x1e, 0x62, 0xdd, 0x01, 0x00, 0x72, 0x8d, 0x28, 0x40,
-	0x05, 0x30, 0x00, 0x00, 0x6e, 0x8d, 0x22, 0x48, 0x77, 0x7d, 0x00, 0x00,
-	0x75, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
-	0x62, 0xb1, 0x01, 0x00, 0x80, 0x8d, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x72, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00,
-	0x92, 0xb0, 0x01, 0x00, 0x7d, 0x8d, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0x04, 0x00, 0x22, 0x40, 0x3b, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa3, 0x48,
-	0x3b, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0xc3, 0x94, 0x00, 0xf8, 0x00, 0x30, 0x01, 0x00, 0x7a, 0x8d, 0xa2, 0x41,
-	0x3b, 0x50, 0x00, 0x00, 0x81, 0x8d, 0x00, 0x49, 0x00, 0xb0, 0x00, 0x00,
-	0xff, 0x07, 0x00, 0x1e, 0x00, 0x8c, 0x01, 0x00, 0xc3, 0x94, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x81, 0x8d, 0x00, 0x49, 0x00, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x1d, 0x47, 0x19, 0x80, 0x01, 0x00, 0x84, 0x8d, 0x22, 0x5f,
-	0x01, 0x6c, 0x00, 0x00, 0x87, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xa7, 0x88, 0x00, 0x00, 0x80, 0xb0, 0x00, 0x00, 0x8b, 0x8d, 0x22, 0x5c,
-	0x1f, 0x7c, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x8b, 0x8d, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x88, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x8b, 0x8d, 0x40, 0x05, 0x48, 0x31, 0x00, 0x00,
-	0xff, 0xff, 0x00, 0x07, 0x94, 0x89, 0x01, 0x00, 0x91, 0x8d, 0x85, 0xca,
-	0x94, 0x30, 0x00, 0x00, 0x87, 0x98, 0x18, 0x5c, 0x1f, 0x00, 0x01, 0x00,
-	0x0e, 0x00, 0x00, 0x0f, 0x1e, 0x8c, 0x01, 0x00, 0xb4, 0x87, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x80, 0x97, 0x18, 0x00, 0x80, 0x30, 0x01, 0x00,
-	0xdd, 0x8b, 0x00, 0x47, 0x19, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x19, 0x80, 0x01, 0x00, 0xdd, 0x8b, 0x22, 0x47, 0x19, 0x7c, 0x00, 0x00,
-	0xb9, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x98, 0x8d, 0xa2, 0x08,
-	0x80, 0x32, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x12, 0x97, 0x00, 0x40, 0x0d, 0x30, 0x01, 0x00, 0x9c, 0x01, 0x00, 0x40,
-	0x45, 0x99, 0x01, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x98, 0x88, 0x01, 0x00,
-	0x8b, 0x00, 0x2d, 0x50, 0x17, 0xf0, 0x01, 0x00, 0x9e, 0x8d, 0x90, 0x4c,
-	0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
-	0xa0, 0x8d, 0x22, 0x43, 0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x45, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00,
-	0x68, 0x01, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x5c, 0x01, 0x2e, 0xf2,
-	0x80, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x62, 0x40, 0x7e, 0xcd, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x57, 0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
-	0x48, 0xb1, 0x01, 0x00, 0x03, 0x00, 0x00, 0x40, 0xf0, 0x8d, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05,
-	0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0xaa, 0x8d, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0xae, 0x8d, 0x45, 0x48,
-	0x61, 0x31, 0x00, 0x00, 0x00, 0x50, 0x00, 0x08, 0x62, 0xdd, 0x01, 0x00,
-	0xb4, 0x8d, 0x28, 0x40, 0x05, 0x30, 0x00, 0x00, 0xaf, 0x8d, 0x22, 0x48,
-	0x77, 0x7d, 0x00, 0x00, 0xc3, 0x94, 0x1d, 0x08, 0x00, 0x30, 0x01, 0x00,
-	0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xdd, 0x8b, 0x1d, 0x47,
-	0x19, 0x80, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
-	0x35, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3,
-	0x84, 0xc8, 0x01, 0x00, 0xba, 0x8d, 0xa0, 0x43, 0x85, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x63, 0x40, 0x85, 0xb0, 0x01, 0x00, 0xa8, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x37, 0x00, 0x2f, 0xf0, 0x24, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0xf3, 0x9e, 0x06, 0x00, 0x00, 0x01, 0x00, 0x63, 0xf3,
-	0x82, 0xcc, 0x01, 0x00, 0xc8, 0x8d, 0xa2, 0x41, 0x9e, 0x06, 0x00, 0x00,
-	0xdd, 0x8b, 0x22, 0x44, 0x83, 0x70, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf0, 0x24, 0x6c, 0x00, 0x00,
-	0x36, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x58, 0x00, 0x3d, 0x43,
-	0xe7, 0xe1, 0x01, 0x00, 0xdd, 0x8b, 0x1f, 0xf0, 0x24, 0x6c, 0x00, 0x00,
-	0x87, 0x98, 0x00, 0x48, 0x81, 0x30, 0x01, 0x00, 0xa7, 0x88, 0x23, 0x41,
-	0x83, 0x6c, 0x00, 0x00, 0xa7, 0x88, 0x00, 0x47, 0x81, 0xb0, 0x00, 0x00,
-	0x34, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0x22, 0x42,
-	0xe6, 0x6d, 0x00, 0x00, 0x58, 0x00, 0x3d, 0x43, 0x85, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x36, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x00, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x00, 0xbe, 0x06, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40,
-	0x83, 0x98, 0x01, 0x00, 0x4e, 0x97, 0x00, 0x47, 0x61, 0x31, 0x01, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x03,
-	0x48, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x2d, 0xf0, 0x94, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x8e, 0xb0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0,
-	0x14, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0xa5, 0x8c, 0xa2, 0x40, 0x8f, 0x7c, 0x00, 0x00, 0xdb, 0x8d, 0x22, 0x47,
-	0x8f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x48, 0x19, 0x7c, 0x00, 0x00,
-	0xa5, 0x8c, 0x00, 0x48, 0x19, 0x90, 0x00, 0x00, 0x04, 0x00, 0x22, 0x46,
-	0x8f, 0x7c, 0x00, 0x00, 0x5d, 0x8e, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00, 0x36, 0x00, 0x2d, 0x5d,
-	0x05, 0xb4, 0x01, 0x00, 0x37, 0x00, 0x2d, 0xf3, 0x80, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf3, 0x8e, 0xb0, 0x01, 0x00, 0xf0, 0x00, 0x00, 0x47,
-	0x7e, 0x89, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x5c, 0x00, 0x3d, 0x43, 0x81, 0xe0, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0xf0,
-	0x94, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x4a, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x24, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
-	0x86, 0xdc, 0x01, 0x00, 0x40, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
-	0x8c, 0x93, 0x00, 0x4a, 0xf0, 0x31, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
-	0x1f, 0x7c, 0x00, 0x00, 0x36, 0x00, 0x2f, 0x5c, 0x1f, 0x90, 0x01, 0x00,
-	0xef, 0x8d, 0xa2, 0x50, 0x8f, 0x50, 0x00, 0x00, 0x34, 0x00, 0x20, 0x40,
-	0xe1, 0xb1, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xf0, 0x00, 0x00, 0x47, 0x7e, 0x89, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x63, 0x41, 0x81, 0xc0, 0x01, 0x00,
-	0xf4, 0x8d, 0xa0, 0x43, 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x63, 0x40,
-	0x81, 0xb0, 0x01, 0x00, 0x37, 0x00, 0x20, 0x47, 0xe6, 0xb1, 0x01, 0x00,
-	0xdd, 0x8b, 0x22, 0x47, 0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0x00, 0x47,
-	0x0c, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x8f, 0x84, 0x01, 0x00,
-	0x09, 0x8e, 0x22, 0x47, 0x0c, 0x6c, 0x00, 0x00, 0x58, 0x00, 0x3d, 0x43,
-	0x81, 0xe0, 0x01, 0x00, 0x09, 0x8e, 0x1f, 0xf0, 0x24, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0x02, 0x8e, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0xff, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x02, 0x8e, 0x42, 0x40,
-	0x05, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
-	0x00, 0x00, 0x1a, 0x5d, 0x69, 0x93, 0x01, 0x00, 0x07, 0x8e, 0x23, 0x41,
-	0x0d, 0x6c, 0x00, 0x00, 0xdd, 0x8d, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
-	0x87, 0x98, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00, 0xa7, 0x88, 0x00, 0x48,
-	0x81, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x22, 0x40, 0x8f, 0x6c, 0x00, 0x00,
-	0x80, 0x97, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x40, 0x02, 0x00, 0x0c, 0x7e, 0x89, 0x01, 0x00,
-	0x04, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x84, 0xb0, 0x01, 0x00,
-	0xa6, 0x00, 0x2d, 0x49, 0x19, 0x90, 0x01, 0x00, 0x02, 0x00, 0x00, 0xf2,
-	0x80, 0xf4, 0x01, 0x00, 0xb8, 0x00, 0x2d, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf2, 0x80, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x82, 0xf8, 0x01, 0x00, 0x19, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
-	0x1a, 0x8e, 0xa0, 0x40, 0x82, 0x6c, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x40,
-	0x81, 0x98, 0x01, 0x00, 0x1a, 0x8e, 0xa3, 0x40, 0x82, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x80, 0xb0, 0x01, 0x00, 0x1c, 0x8e, 0x20, 0x4c,
-	0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x85, 0xc0, 0x01, 0x00,
-	0x86, 0x00, 0x20, 0x40, 0xe4, 0xb1, 0x01, 0x00, 0xa2, 0x00, 0x20, 0x42,
-	0xe6, 0xb1, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x09, 0x97, 0x00, 0x50, 0x81, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0xf0, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x8d, 0xb0, 0x01, 0x00, 0x78, 0x98, 0x00, 0x40, 0x87, 0x30, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0xb0, 0x00, 0x2f, 0x5c,
-	0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x60, 0xf0, 0x80, 0xc0, 0x01, 0x00,
-	0x7c, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa3, 0xf0,
-	0x80, 0x6c, 0x00, 0x00, 0x80, 0x97, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00,
-	0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xdd, 0x8b, 0x22, 0x46, 0x19, 0x7c, 0x00, 0x00,
-	0xa0, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x62, 0xf2,
-	0x96, 0xcc, 0x01, 0x00, 0xdd, 0x8b, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x80, 0x97, 0x00, 0x4a, 0x81, 0x30, 0x01, 0x00, 0x55, 0x97, 0x00, 0x46,
-	0x95, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xdd, 0x8b, 0x22, 0x49, 0x19, 0x7c, 0x00, 0x00, 0x86, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x62, 0xf2, 0x80, 0xcc, 0x01, 0x00,
-	0xdd, 0x8b, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x80, 0x97, 0x00, 0x4a,
-	0x81, 0x30, 0x01, 0x00, 0x55, 0x97, 0x00, 0x47, 0x95, 0x30, 0x01, 0x00,
-	0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2b, 0x94, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
-	0xdd, 0x8b, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x46,
-	0x19, 0x7c, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x49, 0x19, 0x7c, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xba, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x01, 0x00, 0x62, 0xf2, 0x80, 0xc8, 0x01, 0x00, 0x46, 0x8e, 0x90, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0xff, 0xff, 0x62, 0x40, 0x81, 0x98, 0x01, 0x00,
-	0xa4, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xdd, 0x8b, 0x22, 0x40,
-	0xe5, 0x6d, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x41, 0xe5, 0xc1, 0x00, 0x00,
-	0x09, 0x97, 0x00, 0x4d, 0x81, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0xf0, 0x96, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xe1, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4b, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x8d, 0xb0, 0x01, 0x00, 0x78, 0x98, 0x00, 0x40, 0x87, 0x30, 0x01, 0x00,
-	0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x56, 0x8e, 0x80, 0xf3,
-	0x96, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe7, 0x81, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x19, 0x90, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
-	0x1f, 0x7c, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00,
-	0x37, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf3,
-	0x80, 0x32, 0x00, 0x00, 0x34, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
-	0x01, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x11, 0x00, 0x40,
-	0xe5, 0x99, 0x01, 0x00, 0xb9, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x6e, 0x8e, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x82, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x63, 0x51, 0x83, 0xd0, 0x01, 0x00, 0x34, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3, 0x84, 0xcc, 0x01, 0x00,
-	0x66, 0x8e, 0x9f, 0x42, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x63, 0x42,
-	0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x03, 0xf0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00, 0x68, 0x8e, 0x37, 0x5c,
-	0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x62, 0xb1, 0x01, 0x00,
-	0x69, 0x8e, 0xa8, 0x4b, 0x19, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x62, 0xb1, 0x01, 0x00, 0x6b, 0x8e, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xed, 0x87, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0, 0x94, 0xb0, 0x01, 0x00,
-	0xac, 0x00, 0x2d, 0xf0, 0x30, 0xb0, 0x01, 0x00, 0x35, 0x00, 0x2d, 0xf0,
-	0x28, 0xb0, 0x01, 0x00, 0x34, 0x00, 0x2d, 0xf3, 0x84, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0xf3, 0x84, 0x6c, 0x00, 0x00, 0x58, 0x00, 0x3e, 0x43,
-	0x85, 0xe0, 0x01, 0x00, 0x01, 0x00, 0x00, 0x18, 0xf0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4a, 0xe0, 0xb1, 0x01, 0x00, 0x38, 0x00, 0x20, 0x00,
-	0xe0, 0xb1, 0x01, 0x00, 0x3c, 0x00, 0x20, 0x1b, 0xe0, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x2b, 0xb0, 0x01, 0x00, 0x64, 0x97, 0x00, 0x40, 0x0d, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x18, 0x16, 0xc0, 0x01, 0x00, 0x7f, 0x8e, 0xa0, 0x14,
-	0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
-	0x0e, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
-	0xf8, 0xb1, 0x01, 0x00, 0xb0, 0x00, 0x2d, 0x14, 0xf8, 0xb1, 0x01, 0x00,
-	0x10, 0x50, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0x88, 0x8e, 0x22, 0x4a,
-	0x19, 0x7c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x43, 0x86, 0xc8, 0x01, 0x00,
-	0x00, 0x30, 0x00, 0x0b, 0x16, 0xc8, 0x01, 0x00, 0x88, 0x8e, 0xa4, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
-	0x01, 0x00, 0x6e, 0x43, 0x86, 0x98, 0x01, 0x00, 0xa8, 0x97, 0x00, 0x30,
-	0x81, 0x30, 0x01, 0x00, 0x8c, 0x8e, 0xa0, 0x41, 0x17, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x93, 0x8e, 0x22, 0x4a,
-	0x19, 0x7c, 0x00, 0x00, 0x08, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00,
-	0xcc, 0x00, 0x2d, 0xab, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab,
-	0x17, 0xc0, 0x01, 0x00, 0x92, 0x8e, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x64, 0xf0,
-	0x82, 0xb0, 0x01, 0x00, 0x90, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x60, 0x41, 0x31, 0xc0, 0x01, 0x00, 0xbc, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x99, 0x8e, 0x06, 0x0c, 0x80, 0x32, 0x00, 0x00,
-	0xa0, 0x00, 0x20, 0xf2, 0xe4, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x09, 0x46,
-	0x19, 0x10, 0x00, 0x00, 0x9c, 0x01, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
-	0xff, 0xff, 0x00, 0x0b, 0x98, 0x88, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0x50,
-	0x17, 0xf0, 0x01, 0x00, 0x9e, 0x8e, 0x90, 0x4c, 0x16, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0xa0, 0x8e, 0x22, 0x43,
-	0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00,
-	0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00, 0x68, 0x01, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x5c, 0x01, 0x2e, 0xf2, 0x80, 0xb0, 0x01, 0x00,
-	0x02, 0x00, 0x62, 0x40, 0x7e, 0xcd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57,
-	0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
-	0x03, 0x00, 0x00, 0x40, 0xf0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
-	0xf0, 0xb1, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x62, 0xb1, 0x01, 0x00, 0xaa, 0x8e, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0xae, 0x8e, 0x45, 0x48, 0x61, 0x31, 0x00, 0x00,
-	0x00, 0x50, 0x00, 0x08, 0x62, 0xdd, 0x01, 0x00, 0xaf, 0x8e, 0xa8, 0x40,
-	0x05, 0x30, 0x00, 0x00, 0x35, 0x00, 0x1d, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x01, 0x00, 0x63, 0xf3, 0x84, 0xc8, 0x01, 0x00, 0xb5, 0x8e, 0xa0, 0x43,
-	0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x63, 0x40, 0x85, 0xb0, 0x01, 0x00,
-	0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf3,
-	0x9e, 0x06, 0x00, 0x00, 0x01, 0x00, 0x63, 0xf3, 0x82, 0xcc, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0x41, 0x9e, 0x06, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x45, 0xe7, 0x7d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0xe7, 0x91, 0x01, 0x00, 0x80, 0x97, 0x00, 0x5f,
-	0x81, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x8f, 0x95, 0x00, 0xf3,
-	0x94, 0x30, 0x01, 0x00, 0x5d, 0x8e, 0x22, 0x4a, 0x80, 0x32, 0x00, 0x00,
-	0xce, 0x8c, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x8f, 0x95, 0x00, 0xf3, 0x94, 0x30, 0x01, 0x00,
-	0x97, 0x8c, 0x22, 0x4a, 0x80, 0x32, 0x00, 0x00, 0xce, 0x8c, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x36, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfb, 0x12, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3,
-	0x90, 0x88, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3, 0x0c, 0xf4, 0x01, 0x00,
-	0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0xc8, 0x8c, 0x22, 0x06,
-	0x90, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x5c, 0x00, 0x3d, 0x43, 0x13, 0xe0, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0xf0,
-	0x94, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x40, 0x95, 0x6c, 0x00, 0x00,
-	0x37, 0x00, 0x2f, 0xf0, 0x24, 0xb0, 0x01, 0x00, 0x36, 0x00, 0x2a, 0x50,
-	0xe7, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x63, 0x41, 0x13, 0xc0, 0x01, 0x00,
-	0xd5, 0x8e, 0xa0, 0x43, 0x13, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xe7, 0xb1, 0x01, 0x00, 0x89, 0x93, 0x00, 0x10, 0x86, 0x30, 0x01, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xd7, 0x8e, 0x42, 0x05,
-	0x48, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
-	0xc8, 0x8c, 0x1a, 0x5d, 0x69, 0x93, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05,
-	0x48, 0x6d, 0x00, 0x00, 0x36, 0x00, 0x2d, 0x10, 0x86, 0xb0, 0x01, 0x00,
-	0x5c, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0xf0,
-	0x94, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x4a, 0x80, 0x32, 0x00, 0x00,
-	0x35, 0x00, 0x2f, 0xf0, 0x24, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x6b, 0xfb,
-	0x84, 0xc8, 0x01, 0x00, 0xe4, 0x8e, 0xa0, 0x43, 0x85, 0x6c, 0x00, 0x00,
-	0x35, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3, 0x12, 0xc8, 0x01, 0x00,
-	0xe7, 0x8e, 0xa0, 0x43, 0x13, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xe7, 0xb1, 0x01, 0x00, 0x40, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
-	0x8c, 0x93, 0x00, 0x4a, 0xf0, 0x31, 0x01, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0xea, 0x8e, 0x42, 0x05, 0x48, 0x31, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x5d,
-	0x69, 0x93, 0x01, 0x00, 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0xf3, 0x9e, 0x06, 0x00, 0x00, 0x11, 0x00, 0x63, 0xf3,
-	0x82, 0xcc, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x41, 0x80, 0x32, 0x00, 0x00,
-	0xbf, 0x8d, 0x22, 0x41, 0x9e, 0x06, 0x00, 0x00, 0x35, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x58, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x36, 0xb0, 0x01, 0x00, 0xcd, 0x8d, 0x00, 0xf0,
-	0x00, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0xf7, 0x8e, 0x65, 0xf2, 0x12, 0x30, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42,
-	0x13, 0xf0, 0x01, 0x00, 0xfc, 0x8e, 0x22, 0x47, 0xe7, 0x7d, 0x00, 0x00,
-	0x27, 0x83, 0x75, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xf6, 0x8e, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xe7, 0x91, 0x01, 0x00,
-	0x00, 0x00, 0x75, 0x42, 0x19, 0x90, 0x01, 0x00, 0x75, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0xfe, 0x8e, 0xa8, 0xb1, 0x0c, 0x30, 0x00, 0x00,
-	0xa3, 0x96, 0x00, 0x10, 0x94, 0x30, 0x01, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0xc0, 0xa8, 0x3d, 0x46, 0x0d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x97, 0xb0, 0x01, 0x00, 0x08, 0x8f, 0x22, 0x40, 0xe1, 0x6d, 0x00, 0x00,
-	0x04, 0x00, 0x02, 0x41, 0x97, 0x40, 0x00, 0x00, 0x05, 0x8f, 0x00, 0x50,
-	0x43, 0xc1, 0x00, 0x00, 0x14, 0x8f, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x62, 0x4b, 0x12, 0x94, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
-	0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x97, 0xc0, 0x01, 0x00,
-	0x30, 0x00, 0x00, 0x10, 0x94, 0xc8, 0x01, 0x00, 0x00, 0x80, 0x00, 0x4a,
-	0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf1, 0xb1, 0x01, 0x00,
-	0x5e, 0x01, 0x00, 0x4b, 0xf0, 0xc9, 0x01, 0x00, 0x5e, 0x01, 0x00, 0x05,
-	0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x4a, 0x62, 0xdd, 0x01, 0x00, 0x12, 0x8f, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x09,
-	0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x68, 0xa8, 0x97, 0xc0, 0x01, 0x00,
-	0xd4, 0x00, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
-	0x1a, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00,
-	0x1e, 0x8f, 0x65, 0x40, 0x81, 0x32, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf3,
-	0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x75, 0x55, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
-	0x62, 0xb1, 0x01, 0x00, 0x22, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x27, 0x8f, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x62, 0xb1, 0x01, 0x00, 0x25, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x97, 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x96,
-	0x97, 0xb0, 0x01, 0x00, 0x2d, 0x8f, 0x20, 0x09, 0x96, 0x6c, 0x00, 0x00,
-	0x2d, 0x8f, 0x1f, 0x09, 0x96, 0x24, 0x00, 0x00, 0x27, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x28, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x09, 0x97, 0x00, 0x57, 0x81, 0x30, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x05,
-	0x48, 0xb1, 0x00, 0x00, 0x04, 0x00, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
-	0x2e, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x34, 0x8f, 0x22, 0xf3,
-	0x80, 0x32, 0x00, 0x00, 0x09, 0x97, 0x00, 0x42, 0x81, 0x30, 0x01, 0x00,
-	0xed, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x80, 0x97, 0x00, 0x52,
-	0x81, 0x30, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x42, 0x19, 0x80, 0x00, 0x00,
-	0x04, 0x00, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x09, 0x97, 0x00, 0x3a,
-	0x81, 0x30, 0x01, 0x00, 0x80, 0x97, 0x00, 0x52, 0x81, 0x30, 0x01, 0x00,
-	0xc6, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x05, 0xb0, 0x01, 0x00, 0xff, 0x95, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00,
-	0xc6, 0x8b, 0x22, 0x40, 0x95, 0x6c, 0x00, 0x00, 0x24, 0x04, 0x00, 0x40,
-	0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
-	0x42, 0x8f, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
-	0x02, 0xb0, 0x01, 0x00, 0x9f, 0x95, 0x00, 0x52, 0x95, 0x30, 0x01, 0x00,
-	0xa6, 0x95, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0xed, 0x87, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x25, 0x98, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00,
-	0x4e, 0x8f, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0x4e, 0x8f, 0xa2, 0x16,
-	0x80, 0x32, 0x00, 0x00, 0xed, 0x87, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4b, 0x19, 0x90, 0x01, 0x00, 0x09, 0x97, 0x00, 0x3a,
-	0x81, 0x30, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x23, 0x00, 0xa6, 0x16, 0xb0, 0x01, 0x00, 0x51, 0x8f, 0x83, 0x1e,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0b, 0x16, 0xdc, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x2a, 0xc0, 0x01, 0x00, 0x58, 0x97, 0x00, 0x08,
-	0x80, 0x30, 0x01, 0x00, 0x55, 0x8f, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00,
-	0x79, 0x97, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00, 0x98, 0x93, 0x00, 0x40,
-	0x8d, 0x30, 0x01, 0x00, 0x60, 0x97, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x5d, 0x8f, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x5a, 0x8f, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0xfa, 0x96, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0xc3, 0x94, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x61, 0x8f, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00,
-	0x80, 0x97, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00, 0xcd, 0x8b, 0x00, 0x05,
-	0x48, 0xb1, 0x00, 0x00, 0x36, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xc6, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4a,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x1f, 0x90, 0x01, 0x00,
-	0x69, 0x8f, 0x22, 0x43, 0x3d, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x19, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x3d, 0x80, 0x01, 0x00,
-	0x6a, 0x8f, 0x00, 0x42, 0x19, 0x90, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4f,
-	0x2b, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00,
-	0x14, 0x00, 0x2d, 0x45, 0x1f, 0x90, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf0,
-	0x14, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa0, 0x01, 0x14, 0x6c, 0x00, 0x00,
-	0xdc, 0x8f, 0x83, 0x1e, 0x80, 0x32, 0x00, 0x00, 0xdc, 0x8f, 0x00, 0x44,
-	0x19, 0x90, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0x47, 0xe7, 0x7d, 0x00, 0x00, 0xae, 0x94, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x84, 0x8f, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
-	0x84, 0x8f, 0xa2, 0x16, 0x80, 0x32, 0x00, 0x00, 0x80, 0x8f, 0xa2, 0x42,
-	0x19, 0x7c, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00,
-	0xa0, 0x98, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x30, 0x05, 0x00, 0x41,
-	0x89, 0x30, 0x01, 0x00, 0x7d, 0x8f, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x9f, 0x95, 0x00, 0x15, 0x94, 0x30, 0x01, 0x00,
-	0xa6, 0x95, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0xed, 0x87, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x36, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4b, 0x19, 0x90, 0x01, 0x00, 0x09, 0x97, 0x00, 0x3a,
-	0x81, 0x30, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x87, 0x8f, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x36, 0x96, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x88, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xff, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc0, 0x8f, 0x22, 0x41,
-	0x19, 0x7c, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x15, 0x98, 0xc8, 0x01, 0x00,
-	0xc0, 0x8f, 0xa0, 0x0b, 0x99, 0x6c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x44,
-	0x1f, 0x7c, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x7e, 0x89, 0x01, 0x00,
-	0x04, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10,
-	0x80, 0xc8, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40, 0x44, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x62, 0xb1, 0x01, 0x00, 0x93, 0x8f, 0xa8, 0x00,
-	0xe0, 0x31, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x15,
-	0x98, 0xc8, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x0b, 0x99, 0xd0, 0x01, 0x00,
-	0x00, 0x00, 0x6a, 0x50, 0x99, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x20, 0x0b,
-	0x99, 0x6c, 0x00, 0x00, 0xc0, 0x00, 0x62, 0x01, 0x80, 0xcc, 0x01, 0x00,
-	0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x2d, 0x00, 0x2d, 0xf0,
-	0x22, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x80, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5c, 0x23, 0x80, 0x01, 0x00, 0xd4, 0x00, 0x3f, 0x41,
-	0xe7, 0xe1, 0x01, 0x00, 0x04, 0x00, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
-	0x0b, 0x00, 0x00, 0xf2, 0x98, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5a,
-	0x99, 0x80, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x00, 0x98, 0x6c, 0x00, 0x00,
-	0x20, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x11,
-	0x8a, 0x30, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x11, 0xe4, 0xf5, 0x01, 0x00,
-	0x2f, 0x00, 0x20, 0x47, 0xe7, 0xb5, 0x01, 0x00, 0xab, 0x8f, 0x23, 0x0b,
-	0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0xe5, 0x91, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x08, 0x80, 0xb0, 0x01, 0x00, 0xc1, 0x00, 0x00, 0x01,
-	0x80, 0xce, 0x01, 0x00, 0x04, 0x00, 0xa4, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x0b, 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15,
-	0x02, 0xd0, 0x01, 0x00, 0x58, 0x97, 0x00, 0x00, 0x2a, 0x40, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0xb2, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x05,
-	0x48, 0x31, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x01, 0x80, 0xce, 0x01, 0x00,
-	0xbe, 0x8f, 0x26, 0x11, 0x00, 0x30, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
-	0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0x80, 0xc0, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40,
-	0x99, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x98, 0xd0, 0x01, 0x00,
-	0x58, 0x97, 0x00, 0x4c, 0x02, 0x30, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40,
-	0x03, 0x98, 0x01, 0x00, 0xc8, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x30, 0x00, 0x2f, 0x08, 0x80, 0xb0, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x15,
-	0xf4, 0xc9, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x01, 0xe4, 0xcd, 0x01, 0x00,
-	0xc1, 0x00, 0x00, 0x01, 0x80, 0xce, 0x01, 0x00, 0x04, 0x00, 0xa4, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0x20, 0x0b, 0xe5, 0x6d, 0x00, 0x00,
-	0xc0, 0x00, 0x00, 0x40, 0x03, 0x98, 0x01, 0x00, 0x58, 0x97, 0x00, 0x00,
-	0x2a, 0x40, 0x01, 0x00, 0xcd, 0x8f, 0x22, 0x44, 0x1f, 0x7c, 0x00, 0x00,
-	0xac, 0x00, 0x2f, 0x40, 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
-	0xe0, 0xc1, 0x01, 0x00, 0xb0, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0xce, 0x8f, 0x00, 0x01, 0xe0, 0xd1, 0x00, 0x00, 0x98, 0x93, 0x00, 0x40,
-	0x8d, 0x30, 0x01, 0x00, 0x80, 0x63, 0x00, 0xa6, 0x16, 0xb0, 0x01, 0x00,
-	0x60, 0x97, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0xd6, 0x8f, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0xd3, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xfa, 0x96, 0x00, 0x5e,
-	0x05, 0x10, 0x01, 0x00, 0xd9, 0x8f, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00,
-	0x80, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x05,
-	0x48, 0xb1, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4a, 0x1f, 0x7c, 0x00, 0x00,
-	0xdc, 0x8f, 0x00, 0x4a, 0x1f, 0x90, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4f,
-	0x2b, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x10, 0xb0, 0x01, 0x00, 0x24, 0x00, 0x2d, 0x15, 0x10, 0xc0, 0x01, 0x00,
-	0x28, 0x00, 0x2d, 0xf0, 0x16, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x2d, 0xf0,
-	0x26, 0xb0, 0x01, 0x00, 0x14, 0x00, 0x2f, 0xf2, 0x0c, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0xe0, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x32, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0x1f, 0x15, 0x1a, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x23, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2a, 0xb0, 0x01, 0x00,
-	0xb8, 0x96, 0x00, 0x40, 0x35, 0xb0, 0x00, 0x00, 0x2f, 0x00, 0x20, 0x40,
-	0xe7, 0xb1, 0x01, 0x00, 0x26, 0x90, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00, 0x24, 0x00, 0x20, 0x0b,
-	0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00,
-	0x22, 0x00, 0x20, 0x06, 0xe4, 0xb1, 0x01, 0x00, 0xfa, 0x8f, 0x22, 0x5c,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00,
-	0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0xfa, 0x8f, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xf6, 0x8f, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x14, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf0, 0x14, 0x6c, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00, 0x1f, 0x90, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x0d, 0x90, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
-	0x6d, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x54, 0x94, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x1a, 0x90, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x03, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x09, 0x90, 0x22, 0x41,
-	0x19, 0x7c, 0x00, 0x00, 0xe1, 0x94, 0x00, 0x40, 0x11, 0x30, 0x01, 0x00,
-	0x0a, 0x90, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x0c, 0x90, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00,
-	0x80, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x83, 0x00, 0x40,
-	0x05, 0xb0, 0x00, 0x00, 0x6d, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x49, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x10, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x16, 0x90, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0xe1, 0x94, 0x00, 0x40, 0x11, 0x30, 0x01, 0x00, 0x17, 0x90, 0x00, 0x05,
-	0x48, 0xb1, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x19, 0x90, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x2f, 0x83, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x1b, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x22, 0x90, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0xe1, 0x94, 0x00, 0x40, 0x11, 0x30, 0x01, 0x00, 0x23, 0x90, 0x00, 0x05,
-	0x48, 0xb1, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x25, 0x90, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x40,
-	0x13, 0x30, 0x01, 0x00, 0xcd, 0x8b, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
-	0x14, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf0,
-	0x14, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00,
-	0x2f, 0x90, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x2b, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00, 0x33, 0x90, 0x22, 0x41,
-	0x19, 0x7c, 0x00, 0x00, 0xe1, 0x94, 0x00, 0x40, 0x11, 0x30, 0x01, 0x00,
-	0x34, 0x90, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x08, 0x00, 0x2d, 0x0a, 0x84, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x14, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
-	0x3a, 0x90, 0x03, 0x1e, 0x80, 0x32, 0x00, 0x00, 0x3b, 0x90, 0x00, 0x41,
-	0x87, 0xb0, 0x00, 0x00, 0x21, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
-	0x26, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
-	0x40, 0x90, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x40,
-	0x13, 0x30, 0x01, 0x00, 0x43, 0x90, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00,
-	0x80, 0x97, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x19, 0x80, 0x01, 0x00, 0xc6, 0x8b, 0xa2, 0x4a, 0x1f, 0x7c, 0x00, 0x00,
-	0xcd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05,
-	0x48, 0x6d, 0x00, 0x00, 0xba, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00,
-	0x4b, 0x90, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0x4a,
-	0x19, 0x7c, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x2f, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xce, 0x97, 0x00, 0x40,
-	0x13, 0x30, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0xc4, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0x05, 0x98, 0x00, 0xf0,
-	0x84, 0x30, 0x01, 0x00, 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xcd, 0x8b, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x40,
-	0x13, 0x30, 0x01, 0x00, 0xcd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x2e, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x57, 0x90, 0x22, 0x40,
-	0xe7, 0x6d, 0x00, 0x00, 0x32, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x62, 0x90, 0xa2, 0x40, 0xe5, 0x6d, 0x00, 0x00, 0xec, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x24, 0x00, 0x20, 0x0b, 0xe0, 0xb1, 0x01, 0x00,
-	0x28, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00, 0x22, 0x00, 0x20, 0x06,
-	0xe4, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
-	0x14, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf0,
-	0x80, 0x32, 0x00, 0x00, 0x14, 0x00, 0x20, 0x0a, 0xe0, 0xb1, 0x01, 0x00,
-	0xcd, 0x8b, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x40,
-	0x13, 0x30, 0x01, 0x00, 0xcd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xec, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x97, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x70, 0x90, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x0b, 0x99, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x15,
-	0x98, 0x50, 0x00, 0x00, 0x70, 0x90, 0x20, 0x01, 0x98, 0x6c, 0x00, 0x00,
-	0x70, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x46,
-	0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
-	0x6d, 0x90, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0xac, 0x00, 0x2f, 0x00, 0x10, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0xe0, 0xc1, 0x01, 0x00, 0x14, 0x00, 0x2f, 0x15,
-	0x10, 0xc0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf0, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x0a, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0x01,
-	0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x19, 0x90, 0x01, 0x00,
-	0xe6, 0x8f, 0x22, 0x09, 0x80, 0x32, 0x00, 0x00, 0x80, 0x97, 0x00, 0x09,
-	0x80, 0x30, 0x01, 0x00, 0xe6, 0x8f, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x82, 0xb0, 0x01, 0x00, 0x13, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0x43, 0xc1, 0x01, 0x00, 0x26, 0x96, 0x00, 0xf0,
-	0x84, 0x30, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
-	0xc6, 0x8b, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x2c, 0x00, 0x20, 0x40,
-	0xe7, 0xb1, 0x01, 0x00, 0x2d, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
-	0x2e, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf3,
-	0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
-	0xc6, 0x8b, 0x00, 0x42, 0x19, 0x80, 0x00, 0x00, 0x16, 0x96, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x55, 0x97, 0x00, 0x48, 0x95, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x8a, 0x90, 0xa8, 0x40, 0x13, 0x30, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x90, 0x90, 0x00, 0x05,
-	0x48, 0xb1, 0x00, 0x00, 0x8f, 0x90, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x12, 0xb0, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x14, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0xf0,
-	0x84, 0x30, 0x00, 0x00, 0x13, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
-	0x26, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
-	0xad, 0x90, 0x00, 0x09, 0x00, 0xb0, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05,
-	0x48, 0x6d, 0x00, 0x00, 0xc6, 0x8b, 0x87, 0x42, 0x19, 0x10, 0x00, 0x00,
-	0x8b, 0x00, 0x2f, 0x47, 0x19, 0x80, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x40,
-	0xe7, 0x91, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00,
-	0x2f, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xab, 0x90, 0x22, 0x47,
-	0xe7, 0x7d, 0x00, 0x00, 0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0x17, 0x94, 0x00, 0x40, 0xe7, 0x31, 0x01, 0x00, 0xab, 0x90, 0x22, 0x00,
-	0x80, 0x32, 0x00, 0x00, 0xa6, 0x90, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00,
-	0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xab, 0x90, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x32, 0x00, 0x2d, 0xf2, 0x94, 0xb0, 0x01, 0x00, 0x9f, 0x95, 0x00, 0xf2,
-	0x02, 0x30, 0x01, 0x00, 0xa6, 0x95, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0xac, 0x90, 0x00, 0x40,
-	0x01, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
-	0xb2, 0x90, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0xb1, 0x90, 0xa2, 0x42,
-	0x19, 0x7c, 0x00, 0x00, 0xff, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xb2, 0x90, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x36, 0x96, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x51, 0x91, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0xba, 0x90, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0xb7, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x51, 0x91, 0x00, 0x05,
-	0x48, 0xb1, 0x00, 0x00, 0xae, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xc1, 0x90, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0xc1, 0x90, 0xa2, 0x16,
-	0x80, 0x32, 0x00, 0x00, 0x09, 0x97, 0x00, 0x4d, 0x81, 0x30, 0x01, 0x00,
-	0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x74, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x96, 0xb0, 0x01, 0x00,
-	0xd2, 0x90, 0x22, 0x42, 0x96, 0x14, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x44, 0xc9, 0x01, 0x00, 0x64, 0x00, 0x68, 0x40, 0x97, 0x98, 0x01, 0x00,
-	0x64, 0x00, 0x00, 0x4b, 0x80, 0xce, 0x01, 0x00, 0x04, 0x00, 0xa6, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00, 0x70, 0x00, 0x00, 0x05,
-	0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xce, 0x90, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0xd3, 0x90, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0xd7, 0x90, 0x65, 0xf2, 0x12, 0x30, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42,
-	0x13, 0xf0, 0x01, 0x00, 0xdc, 0x90, 0x22, 0x47, 0xe7, 0x7d, 0x00, 0x00,
-	0x27, 0x83, 0x75, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xd6, 0x90, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xe7, 0x91, 0x01, 0x00,
-	0x04, 0x00, 0x75, 0x09, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x68, 0xa8, 0x97, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0xe0, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x62, 0xb1, 0x01, 0x00, 0xe4, 0x90, 0xa8, 0x40, 0xe1, 0x31, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42,
-	0x13, 0xf0, 0x01, 0x00, 0xe8, 0x90, 0x65, 0x05, 0x48, 0x31, 0x00, 0x00,
-	0x3f, 0x00, 0x00, 0xf3, 0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xe7, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x75, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0xf0, 0x90, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00,
-	0xee, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
-	0x16, 0xb0, 0x01, 0x00, 0x00, 0x62, 0x00, 0x0b, 0x16, 0xdc, 0x01, 0x00,
-	0x2f, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x47,
-	0xe7, 0x7d, 0x00, 0x00, 0x17, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x0d, 0x91, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0x48, 0x96, 0x00, 0x5f,
-	0x01, 0x10, 0x01, 0x00, 0xf4, 0x90, 0x22, 0x40, 0x95, 0x6c, 0x00, 0x00,
-	0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0xfe, 0x90, 0xa8, 0x00,
-	0xe0, 0x31, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x04, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0x20, 0x31, 0x03, 0x6c, 0x00, 0x00, 0x9f, 0x95, 0x00, 0x52,
-	0x95, 0x30, 0x01, 0x00, 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xf4, 0x90, 0x22, 0x41, 0x97, 0x50, 0x00, 0x00, 0x0c, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5c, 0x01, 0x80, 0x01, 0x00, 0xa6, 0x95, 0x00, 0x4b,
-	0x02, 0xb0, 0x00, 0x00, 0xf4, 0x90, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
-	0x60, 0x97, 0x00, 0x40, 0x03, 0x30, 0x01, 0x00, 0x17, 0x80, 0x00, 0x03,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x0c, 0x96, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0x63, 0x4c, 0x97, 0xf0, 0x01, 0x00, 0x04, 0x00, 0x20, 0x4d,
-	0x97, 0x6c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40, 0x97, 0x6c, 0x00, 0x00,
-	0x10, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab,
-	0xe1, 0xb1, 0x01, 0x00, 0xfa, 0x96, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00,
-	0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00, 0x07, 0x00, 0x00, 0x07,
-	0x16, 0x88, 0x01, 0x00, 0x00, 0xb5, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00,
-	0x19, 0x91, 0x30, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0x0b,
-	0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x81, 0x01, 0x00,
-	0x00, 0xb7, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x0b,
-	0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x81, 0x01, 0x00,
-	0x10, 0x00, 0x10, 0x0f, 0x94, 0xf4, 0x01, 0x00, 0x93, 0x04, 0x00, 0x5f,
-	0x95, 0x04, 0x01, 0x00, 0x70, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x27, 0x91, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00, 0x23, 0x91, 0x46, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x26, 0x91, 0xa2, 0x40, 0x31, 0x6f, 0x00, 0x00,
-	0x04, 0x00, 0x1e, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x41,
-	0x31, 0xd3, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x0f, 0xb0, 0x01, 0x00, 0xa5, 0x94, 0x00, 0x41, 0x81, 0x30, 0x01, 0x00,
-	0xed, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xae, 0x94, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x3a, 0x91, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
-	0x3a, 0x91, 0xa2, 0x16, 0x80, 0x32, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02,
-	0x04, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x03, 0xf0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00, 0x32, 0x91, 0x37, 0x5c,
-	0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x62, 0xb1, 0x01, 0x00,
-	0x37, 0x91, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5c,
-	0x77, 0x7d, 0x00, 0x00, 0x33, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x62, 0xb1, 0x01, 0x00, 0x37, 0x91, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xed, 0x87, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x74, 0x00, 0x22, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xe1, 0xb1, 0x01, 0x00, 0x55, 0x97, 0x00, 0x4a, 0x95, 0x30, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x16, 0x96, 0x00, 0x5c,
-	0x1f, 0x10, 0x01, 0x00, 0xc1, 0x90, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x4e, 0x91, 0x22, 0x47, 0xe7, 0x7d, 0x00, 0x00,
-	0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x17, 0x94, 0x00, 0x40,
-	0xe7, 0x31, 0x01, 0x00, 0x4e, 0x91, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00,
-	0x49, 0x91, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x4e, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x30, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x32, 0x00, 0x2d, 0xf2,
-	0x94, 0xb0, 0x01, 0x00, 0x9f, 0x95, 0x00, 0xf2, 0x02, 0x30, 0x01, 0x00,
-	0xa6, 0x95, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x55, 0x97, 0x00, 0x48, 0x95, 0x30, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x16, 0x96, 0x00, 0x5c,
-	0x1f, 0x10, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
-	0x55, 0x91, 0x87, 0x42, 0x19, 0x10, 0x00, 0x00, 0x8b, 0x00, 0x2f, 0x47,
-	0x19, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe7, 0x91, 0x01, 0x00,
-	0x80, 0x97, 0x00, 0x42, 0x81, 0x30, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x16, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0xc6, 0x8b, 0x00, 0x5c,
-	0x1f, 0x90, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0xf0, 0x80, 0x32, 0x00, 0x00, 0xba, 0x00, 0x20, 0x40,
-	0xe5, 0xb1, 0x01, 0x00, 0xce, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xc0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xc4, 0x00, 0x2d, 0xf0,
-	0x82, 0xb0, 0x01, 0x00, 0x05, 0x98, 0x00, 0xf0, 0x84, 0x30, 0x01, 0x00,
-	0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x80, 0x97, 0x00, 0x45,
-	0x81, 0x30, 0x01, 0x00, 0xc6, 0x8b, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
-	0x09, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xae, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x6d, 0x91, 0xa2, 0x08,
-	0x80, 0x32, 0x00, 0x00, 0x6d, 0x91, 0xa2, 0x16, 0x80, 0x32, 0x00, 0x00,
-	0x09, 0x97, 0x00, 0x47, 0x80, 0x30, 0x01, 0x00, 0x00, 0x82, 0x00, 0x02,
-	0x04, 0xdc, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x10, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0xe1, 0x00, 0xa6,
-	0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x07,
-	0x84, 0x94, 0x01, 0x00, 0xfa, 0x96, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00,
-	0xc6, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0xc3, 0x94, 0x00, 0x41, 0xe7, 0x41, 0x01, 0x00,
-	0xcd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05,
-	0x48, 0x6d, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x48, 0x1f, 0x7c, 0x00, 0x00, 0xec, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x04, 0x00, 0xa3, 0x0a, 0x0c, 0x6c, 0x00, 0x00,
-	0x97, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
-	0x2c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x0a,
-	0x2c, 0x50, 0x00, 0x00, 0x14, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0xf0, 0x80, 0x32, 0x00, 0x00, 0x9b, 0x97, 0x00, 0x06,
-	0x04, 0x30, 0x01, 0x00, 0x8a, 0x91, 0xa2, 0x48, 0x1f, 0x7c, 0x00, 0x00,
-	0x88, 0x91, 0x84, 0x48, 0x1f, 0x10, 0x00, 0x00, 0xac, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x8a, 0x91, 0x00, 0x0a, 0xe0, 0xc1, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x0a, 0x02, 0xb0, 0x01, 0x00, 0x98, 0x93, 0x00, 0x01,
-	0x8c, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x8b, 0x91, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
-	0x10, 0xc0, 0x01, 0x00, 0x98, 0x91, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00,
-	0x73, 0x96, 0x00, 0x45, 0x1f, 0x00, 0x01, 0x00, 0x83, 0x91, 0x22, 0x5c,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x94, 0x91, 0xa8, 0x5c,
-	0x1f, 0x00, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x83, 0x91, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
-	0x1b, 0xb0, 0x01, 0x00, 0x08, 0x00, 0x2d, 0x40, 0x85, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x05, 0xb0, 0x01, 0x00, 0x26, 0x96, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x9e, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0xa4, 0x91, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00,
-	0x80, 0x97, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00, 0xa8, 0x91, 0x22, 0x44,
-	0x19, 0x7c, 0x00, 0x00, 0x80, 0x97, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00,
-	0xa8, 0x91, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x19, 0x80, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08, 0x00, 0x8c, 0x01, 0x00,
-	0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0xb7, 0x91, 0x22, 0x4a,
-	0x1f, 0x7c, 0x00, 0x00, 0xaf, 0x91, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00,
-	0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
-	0xe7, 0xb1, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0xb3, 0x91, 0x22, 0x42,
-	0x19, 0x7c, 0x00, 0x00, 0x36, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xb4, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xff, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x2a, 0xd0, 0x01, 0x00,
-	0x32, 0x00, 0x2a, 0x15, 0xe4, 0xb1, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x16,
-	0xe4, 0xb1, 0x00, 0x00, 0xcd, 0x91, 0x22, 0x16, 0x02, 0x30, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
-	0x2a, 0xb0, 0x01, 0x00, 0x25, 0x98, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00,
-	0xbd, 0x91, 0xa2, 0x40, 0x11, 0x6c, 0x00, 0x00, 0xce, 0x91, 0x22, 0x40,
-	0x2d, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
-	0x04, 0x00, 0x22, 0x44, 0x1f, 0x7c, 0x00, 0x00, 0xac, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0xb0, 0x00, 0x2b, 0x01, 0xe0, 0xc1, 0x01, 0x00,
-	0x00, 0x2b, 0x00, 0xa6, 0x16, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
-	0xe0, 0xd1, 0x01, 0x00, 0x58, 0x97, 0x00, 0x08, 0x80, 0x30, 0x01, 0x00,
-	0xc6, 0x91, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00, 0x79, 0x97, 0x00, 0x43,
-	0x61, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xc7, 0x91, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x60, 0x97, 0x00, 0x07,
-	0x16, 0x14, 0x01, 0x00, 0xfa, 0x96, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00,
-	0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
-	0xe7, 0xb1, 0x01, 0x00, 0xcd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x15,
-	0x1a, 0x50, 0x00, 0x00, 0xdc, 0x91, 0x20, 0x16, 0x1a, 0x6c, 0x00, 0x00,
-	0x04, 0x00, 0x22, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0x70, 0x00, 0x00, 0x03,
-	0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x22, 0x50, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
-	0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0xd9, 0x91, 0xa8, 0x46,
-	0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15,
-	0x10, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x2a, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0a, 0x2c, 0xd0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x16,
-	0x80, 0x32, 0x00, 0x00, 0x14, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0xf0, 0x80, 0x32, 0x00, 0x00, 0xac, 0x00, 0x2f, 0x40,
-	0x23, 0xb0, 0x01, 0x00, 0xe6, 0x91, 0x84, 0x45, 0x1f, 0x10, 0x00, 0x00,
-	0xe7, 0x91, 0x00, 0x0a, 0xe0, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
-	0x02, 0xb0, 0x01, 0x00, 0xb8, 0x96, 0x00, 0x40, 0x35, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19,
-	0x42, 0xc9, 0x01, 0x00, 0xf0, 0x91, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0xec, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x92, 0xa2, 0x02, 0x1a, 0x50, 0x00, 0x00,
-	0x05, 0x92, 0x22, 0x40, 0x2d, 0x6c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0xf0, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08, 0xe0, 0x8d, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x62, 0xb1, 0x01, 0x00, 0xf8, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0xf0, 0x10, 0xc8, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
-	0x1b, 0x98, 0x01, 0x00, 0x05, 0x92, 0x00, 0x5c, 0x11, 0x80, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x5f, 0x1b, 0x7c, 0x00, 0x00, 0xff, 0x07, 0x00, 0x08,
-	0x98, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x98, 0xc0, 0x01, 0x00,
-	0x04, 0x00, 0x20, 0x0b, 0x99, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-	0x10, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x40, 0x23, 0x6c, 0x00, 0x00,
-	0x04, 0x00, 0xa3, 0x43, 0x23, 0x6c, 0x00, 0x00, 0xe1, 0x94, 0x00, 0x40,
-	0x1f, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x0b, 0x92, 0x23, 0x0d, 0x2c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x1f, 0x90, 0x01, 0x00, 0x13, 0x92, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00,
-	0x70, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x13, 0x92, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x0f, 0x92, 0xa8, 0x46,
-	0x1f, 0x00, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x2d, 0x40,
-	0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x82, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00, 0x26, 0x96, 0x00, 0x41,
-	0x87, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x18, 0x92, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x1e, 0x92, 0x22, 0x09,
-	0x80, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
-	0x22, 0x92, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00, 0x80, 0x97, 0x00, 0x4f,
-	0x81, 0x30, 0x01, 0x00, 0x22, 0x92, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x19, 0x80, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08,
-	0x00, 0x8c, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x38, 0x92, 0x22, 0x4a, 0x1f, 0x7c, 0x00, 0x00, 0x29, 0x92, 0xa2, 0x16,
-	0x02, 0x30, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00,
-	0x34, 0x92, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x2d, 0x92, 0xa2, 0xf3,
-	0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x85, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x85, 0xd0, 0x01, 0x00, 0xd4, 0x00, 0x3e, 0x41,
-	0x85, 0xe0, 0x01, 0x00, 0x31, 0x92, 0x22, 0x40, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5a, 0x11, 0x90, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x08,
-	0xe4, 0xf5, 0x01, 0x00, 0x36, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x35, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xff, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x2a, 0xd0, 0x01, 0x00,
-	0x32, 0x00, 0x2a, 0x15, 0xe4, 0xb1, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x16,
-	0xe4, 0xb1, 0x00, 0x00, 0x3b, 0x92, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00,
-	0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x94, 0x92, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00,
-	0x4e, 0x92, 0x22, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa0, 0x91,
-	0x03, 0x6c, 0x00, 0x00, 0x48, 0x92, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
-	0x41, 0x92, 0xa2, 0xf3, 0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5,
-	0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x85, 0xd0, 0x01, 0x00,
-	0xd4, 0x00, 0x3e, 0x41, 0x85, 0xe0, 0x01, 0x00, 0x45, 0x92, 0x22, 0x40,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x11, 0x90, 0x01, 0x00,
-	0x0b, 0x00, 0x00, 0x08, 0xe4, 0xf5, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40,
-	0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x08, 0x8a, 0x30, 0x01, 0x00,
-	0x58, 0x01, 0x2d, 0x00, 0x2a, 0xd0, 0x01, 0x00, 0x60, 0x01, 0x2d, 0xf0,
-	0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x2c, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x16, 0x80, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x27, 0x40,
-	0x11, 0x6c, 0x00, 0x00, 0x84, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0xa3, 0x91, 0x03, 0x6c, 0x00, 0x00, 0x25, 0x98, 0x00, 0x41,
-	0x95, 0x30, 0x01, 0x00, 0x57, 0x92, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
-	0x57, 0x92, 0xa2, 0x16, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x97, 0xb0, 0x01, 0x00, 0x55, 0x92, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x97, 0xc0, 0x01, 0x00, 0xa6, 0x95, 0x00, 0x4b,
-	0x02, 0xb0, 0x00, 0x00, 0x94, 0x92, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00, 0x04, 0x00, 0x22, 0x44,
-	0x1f, 0x7c, 0x00, 0x00, 0xac, 0x00, 0x2f, 0x01, 0x14, 0xb0, 0x01, 0x00,
-	0xb0, 0x00, 0x2b, 0x01, 0xe0, 0xc1, 0x01, 0x00, 0x00, 0x2b, 0x00, 0xa6,
-	0x16, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0xe0, 0xd1, 0x01, 0x00, 0x6a, 0x92, 0x23, 0x0d,
-	0x02, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x63, 0x92, 0xa8, 0x00,
-	0xe0, 0x31, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf0, 0x22, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5c, 0x23, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
-	0x84, 0xb0, 0x01, 0x00, 0x6d, 0x92, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x0d, 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
-	0x80, 0xb0, 0x01, 0x00, 0x72, 0x92, 0x22, 0x40, 0x1b, 0x6c, 0x00, 0x00,
-	0x58, 0x97, 0x00, 0x01, 0x84, 0x50, 0x01, 0x00, 0x7b, 0x92, 0x22, 0x40,
-	0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0xc0, 0x01, 0x00,
-	0x10, 0x80, 0x00, 0x10, 0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f,
-	0x43, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x40, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
-	0xa0, 0x00, 0x00, 0xa1, 0x62, 0xdd, 0x01, 0x00, 0x78, 0x92, 0xa8, 0x11,
-	0xe0, 0x31, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40, 0x23, 0x6c, 0x00, 0x00,
-	0x8a, 0x92, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00, 0x7e, 0x92, 0x23, 0x0d,
-	0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x02, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0x84, 0xd0, 0x01, 0x00, 0x83, 0x92, 0x22, 0x40,
-	0x1b, 0x6c, 0x00, 0x00, 0x79, 0x97, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00,
-	0x8a, 0x92, 0x22, 0x40, 0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-	0x12, 0xc0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x10, 0x46, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4f, 0x43, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa1,
-	0x62, 0xdd, 0x01, 0x00, 0x88, 0x92, 0xa8, 0x11, 0xe0, 0x31, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x8b, 0x92, 0xa8, 0x0a, 0x02, 0x30, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x05,
-	0x48, 0x31, 0x01, 0x00, 0x92, 0x92, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00,
-	0xff, 0x07, 0x00, 0x11, 0x00, 0x8c, 0x01, 0x00, 0xc3, 0x94, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x60, 0x97, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00,
-	0xfa, 0x96, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
-	0xe7, 0xb1, 0x01, 0x00, 0xcd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x8e, 0xb0, 0x01, 0x00, 0xe6, 0x95, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
-	0x04, 0x00, 0x0c, 0x47, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x85, 0xb0, 0x01, 0x00, 0x26, 0x96, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00,
-	0x97, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x04, 0x00, 0x20, 0x91,
-	0x03, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
-	0xa8, 0x92, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0xa4, 0x92, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0xaa, 0x92, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x40,
-	0x13, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x15, 0x1a, 0xd0, 0x01, 0x00, 0xb1, 0x92, 0xa2, 0x41,
-	0x19, 0x7c, 0x00, 0x00, 0x25, 0x98, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x16, 0x80, 0xb2, 0x01, 0x00, 0xba, 0x92, 0x27, 0x08,
-	0x80, 0x32, 0x00, 0x00, 0xbd, 0x91, 0x00, 0x00, 0x2a, 0xc0, 0x00, 0x00,
-	0x25, 0x98, 0x00, 0x41, 0x95, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
-	0x80, 0xb2, 0x01, 0x00, 0xb5, 0x92, 0x27, 0x08, 0x80, 0x32, 0x00, 0x00,
-	0x57, 0x92, 0x00, 0x00, 0x2a, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x97, 0xb0, 0x01, 0x00, 0xb8, 0x92, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x97, 0xc0, 0x01, 0x00, 0xa6, 0x95, 0x00, 0x4b,
-	0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0xc6, 0x8b, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x09, 0x97, 0x00, 0x3a,
-	0x81, 0x30, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x4a, 0x1f, 0x7c, 0x00, 0x00, 0xbf, 0x92, 0x00, 0x4a,
-	0x1f, 0x90, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x4f, 0x2b, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x44,
-	0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00,
-	0xf9, 0x94, 0x00, 0x00, 0x10, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15,
-	0x10, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
-	0x9b, 0x97, 0x00, 0x06, 0x04, 0x30, 0x01, 0x00, 0xcc, 0x92, 0xa2, 0x44,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0a, 0x2c, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a,
-	0x02, 0xb0, 0x01, 0x00, 0x98, 0x93, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00, 0xd3, 0x92, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xcf, 0x92, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
-	0x10, 0xc0, 0x01, 0x00, 0xdc, 0x92, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00,
-	0x73, 0x96, 0x00, 0x45, 0x1f, 0x00, 0x01, 0x00, 0xc5, 0x92, 0x22, 0x5c,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xd8, 0x92, 0xa8, 0x5c,
-	0x1f, 0x00, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0xc5, 0x92, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x08, 0x00, 0x2d, 0x40,
-	0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x82, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00, 0x26, 0x96, 0x00, 0x41,
-	0x87, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xe1, 0x92, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0xe7, 0x92, 0x22, 0x09,
-	0x80, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
-	0xea, 0x92, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00, 0x80, 0x97, 0x00, 0x4f,
-	0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x19, 0x80, 0x01, 0x00,
-	0xff, 0x07, 0x00, 0x08, 0x00, 0x8c, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xf9, 0x92, 0x22, 0x4a, 0x1f, 0x7c, 0x00, 0x00,
-	0xf1, 0x92, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
-	0xc6, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2d, 0x00, 0x2d, 0x08,
-	0x2a, 0xb0, 0x01, 0x00, 0xf5, 0x92, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
-	0x36, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xf6, 0x92, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xff, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x30, 0x00, 0x2e, 0x00, 0x2a, 0xd0, 0x01, 0x00, 0x32, 0x00, 0x2a, 0x15,
-	0xe4, 0xb1, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x16, 0xe4, 0xb1, 0x00, 0x00,
-	0xb8, 0x91, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
-	0xcd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x22, 0x41,
-	0x19, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4f, 0x2b, 0x7c, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x45,
-	0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4a, 0x1f, 0x7c, 0x00, 0x00,
-	0xf9, 0x94, 0x00, 0x4a, 0x1f, 0x10, 0x01, 0x00, 0xd0, 0x91, 0x00, 0x10,
-	0x32, 0xb0, 0x00, 0x00, 0x8a, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
-	0x08, 0x93, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x0b, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x9f, 0x95, 0x00, 0x15, 0x94, 0x30, 0x01, 0x00, 0xa6, 0x95, 0x00, 0x4b,
-	0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x0d, 0x93, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x09, 0x97, 0x00, 0x3a,
-	0x81, 0x30, 0x01, 0x00, 0x80, 0x97, 0x00, 0x45, 0x81, 0x30, 0x01, 0x00,
-	0xc6, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x62, 0x90, 0x00, 0x45,
-	0x1f, 0x90, 0x00, 0x00, 0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0xec, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x04, 0x00, 0xa3, 0x0a, 0x0c, 0x6c, 0x00, 0x00,
-	0x97, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xd0, 0x91, 0x00, 0x01,
-	0x2c, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x48, 0x1f, 0x7c, 0x00, 0x00, 0xae, 0x94, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x26, 0x93, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
-	0x26, 0x93, 0xa2, 0x16, 0x80, 0x32, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02,
-	0x04, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x03, 0xf0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00, 0x1e, 0x93, 0x37, 0x5c,
-	0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x62, 0xb1, 0x01, 0x00,
-	0x23, 0x93, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5c,
-	0x77, 0x7d, 0x00, 0x00, 0x1f, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x62, 0xb1, 0x01, 0x00, 0x23, 0x93, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xed, 0x87, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x58, 0x01, 0x20, 0x08, 0xe0, 0xb1, 0x01, 0x00, 0x60, 0x01, 0x20, 0x16,
-	0xe0, 0xb1, 0x01, 0x00, 0xec, 0x95, 0x00, 0x47, 0x1f, 0x10, 0x01, 0x00,
-	0x04, 0x00, 0xa3, 0x0a, 0x0c, 0x6c, 0x00, 0x00, 0x97, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xd0, 0x91, 0x00, 0x01, 0x2c, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x47,
-	0x1f, 0x7c, 0x00, 0x00, 0xae, 0x94, 0x00, 0x47, 0x1f, 0x10, 0x01, 0x00,
-	0x3d, 0x93, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0x3d, 0x93, 0xa2, 0x16,
-	0x80, 0x32, 0x00, 0x00, 0x39, 0x93, 0xa2, 0x42, 0x19, 0x7c, 0x00, 0x00,
-	0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00, 0xa0, 0x98, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x30, 0x05, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x9f, 0x95, 0x00, 0x15,
-	0x94, 0x30, 0x01, 0x00, 0xa6, 0x95, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
-	0xed, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x36, 0x96, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x19, 0x90, 0x01, 0x00,
-	0x09, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x58, 0x01, 0x20, 0x08, 0xe0, 0xb1, 0x01, 0x00,
-	0x60, 0x01, 0x20, 0x16, 0xe0, 0xb1, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x4f,
-	0x2b, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00, 0xf9, 0x94, 0x00, 0x10,
-	0x32, 0x30, 0x01, 0x00, 0xd0, 0x91, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00,
-	0xae, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x52, 0x93, 0xa2, 0x08,
-	0x80, 0x32, 0x00, 0x00, 0x52, 0x93, 0xa2, 0x16, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x03, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00,
-	0x4a, 0x93, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b,
-	0x62, 0xb1, 0x01, 0x00, 0x4f, 0x93, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x5c, 0x77, 0x7d, 0x00, 0x00, 0x4b, 0x93, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0xb1, 0x01, 0x00,
-	0x4f, 0x93, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xed, 0x87, 0x17, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x8c, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x8e, 0xb0, 0x01, 0x00, 0xe6, 0x95, 0x00, 0x40,
-	0x13, 0x30, 0x01, 0x00, 0x04, 0x00, 0x0c, 0x47, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x26, 0x96, 0x00, 0x41,
-	0x87, 0x30, 0x01, 0x00, 0x97, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x04, 0x00, 0xa0, 0x91, 0x03, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0x64, 0x93, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x60, 0x93, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x84, 0x8f, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00,
-	0x80, 0x97, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00, 0x84, 0x8f, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x83, 0x1e, 0x80, 0x32, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x4f, 0x2b, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x45,
-	0x1f, 0x7c, 0x00, 0x00, 0x14, 0x00, 0x2d, 0x45, 0x1f, 0x90, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0xf0, 0x14, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa0, 0x01,
-	0x14, 0x6c, 0x00, 0x00, 0xdc, 0x8f, 0x00, 0x44, 0x19, 0x90, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x4a, 0x1f, 0x7c, 0x00, 0x00, 0x72, 0x93, 0xa2, 0x41,
-	0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x1f, 0x90, 0x01, 0x00,
-	0x77, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x48,
-	0x1f, 0x7c, 0x00, 0x00, 0xec, 0x95, 0x00, 0x4a, 0x1f, 0x10, 0x01, 0x00,
-	0x04, 0x00, 0xa3, 0x0a, 0x0c, 0x6c, 0x00, 0x00, 0x97, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xd0, 0x91, 0x00, 0x01, 0x2c, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4f,
-	0x2b, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00, 0xf9, 0x94, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xd0, 0x91, 0x00, 0x10, 0x32, 0xb0, 0x00, 0x00,
-	0x8b, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x46,
-	0xe7, 0x7d, 0x00, 0x00, 0x62, 0x90, 0x00, 0x45, 0x1f, 0x90, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x37, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x33, 0xc3, 0x01, 0x00, 0x36, 0x00, 0x00, 0x01, 0x02, 0xcc, 0x01, 0x00,
-	0x00, 0x00, 0xd2, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x86, 0x93, 0x85, 0x17,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x48, 0x03, 0xd0, 0x00, 0x00,
-	0x88, 0x93, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x4c,
-	0x03, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x34, 0xc3, 0x01, 0x00,
-	0x40, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
-	0xf0, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x12,
-	0xf0, 0xb1, 0x01, 0x00, 0xcb, 0x94, 0x00, 0x41, 0xe1, 0x31, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x43, 0x44, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x40,
-	0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x49, 0xf0, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x03,
-	0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x95, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x2d, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0xa5,
-	0x8a, 0x30, 0x01, 0x00, 0xba, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00,
-	0xb0, 0x00, 0x2f, 0x01, 0x8c, 0xd0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0xf0,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0xe0, 0xc1, 0x01, 0x00,
-	0xac, 0x00, 0x2f, 0x40, 0x13, 0xb0, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0x01,
-	0xe0, 0xc1, 0x01, 0x00, 0xa3, 0x93, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00,
-	0x04, 0x00, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00, 0x2f, 0x98, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xa5, 0x93, 0x22, 0x47, 0x19, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x13, 0x90, 0x01, 0x00, 0xce, 0x97, 0x00, 0x47,
-	0x19, 0x10, 0x01, 0x00, 0xc0, 0x00, 0x2d, 0x44, 0x1f, 0x90, 0x01, 0x00,
-	0xc4, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0x05, 0x98, 0x00, 0xf0,
-	0x84, 0xb0, 0x00, 0x00, 0x90, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0xba, 0x93, 0xa2, 0x4b, 0x1f, 0x7c, 0x00, 0x00, 0x0f, 0x94, 0xa2, 0x4c,
-	0x1f, 0x7c, 0x00, 0x00, 0xba, 0x93, 0x1f, 0x1c, 0xe0, 0x6d, 0x00, 0x00,
-	0xbd, 0x93, 0xa2, 0x01, 0x80, 0x32, 0x00, 0x00, 0xa8, 0x00, 0x2d, 0x46,
-	0x8f, 0xb0, 0x01, 0x00, 0xb3, 0x93, 0x1f, 0x1c, 0xe0, 0x6d, 0x00, 0x00,
-	0xb4, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xb5, 0x93, 0x22, 0xf0,
-	0x3a, 0x6c, 0x00, 0x00, 0x0c, 0x94, 0x1f, 0xf0, 0x3a, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0xa2, 0x40, 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x4f,
-	0x8f, 0xb0, 0x01, 0x00, 0x8a, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x0d, 0x94, 0x20, 0x42, 0xe7, 0x6d, 0x00, 0x00, 0xb9, 0x93, 0x22, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x59, 0x8f, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x58, 0x8f, 0xb0, 0x01, 0x00, 0xbc, 0x93, 0x22, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x5c, 0x8f, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x5b, 0x8f, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0xb0, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00,
-	0xc1, 0x93, 0xa2, 0x42, 0x24, 0x6c, 0x00, 0x00, 0xcc, 0x93, 0x23, 0xf0,
-	0x02, 0x6c, 0x00, 0x00, 0xb0, 0x00, 0x00, 0xa1, 0x80, 0xce, 0x01, 0x00,
-	0x04, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xc9, 0x93, 0xa2, 0xf0,
-	0x80, 0x32, 0x00, 0x00, 0x0e, 0x94, 0xa2, 0x42, 0x24, 0x6c, 0x00, 0x00,
-	0x0e, 0x94, 0xa2, 0x41, 0x03, 0x6c, 0x00, 0x00, 0xc8, 0x93, 0xa2, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x51, 0x8f, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x52, 0x8f, 0xb0, 0x01, 0x00, 0x0e, 0x94, 0x1f, 0x12,
-	0x84, 0x50, 0x00, 0x00, 0x0e, 0x94, 0xa0, 0x01, 0x84, 0x6c, 0x00, 0x00,
-	0xba, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0xf7, 0x93, 0xa2, 0x46, 0xe7, 0x7d, 0x00, 0x00,
-	0x14, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xe9, 0x93, 0x22, 0xf0,
-	0x14, 0x30, 0x00, 0x00, 0xd5, 0x93, 0x20, 0x0a, 0x02, 0x6c, 0x00, 0x00,
-	0xe6, 0x93, 0x03, 0x1e, 0x80, 0x32, 0x00, 0x00, 0xd4, 0x93, 0xa2, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x44, 0x8f, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00, 0xda, 0x93, 0x22, 0x0a,
-	0x02, 0x6c, 0x00, 0x00, 0xdd, 0x93, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0xd9, 0x93, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x55,
-	0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x56, 0x8f, 0xb0, 0x01, 0x00,
-	0xdc, 0x93, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43,
-	0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x48, 0x8f, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a,
-	0x82, 0xd0, 0x01, 0x00, 0xe3, 0x93, 0x20, 0x91, 0x83, 0x6c, 0x00, 0x00,
-	0xe2, 0x93, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x26, 0x00, 0x80, 0x40,
-	0x8f, 0x98, 0x01, 0x00, 0x27, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
-	0xe5, 0x93, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x1f, 0x00, 0x80, 0x40,
-	0x8f, 0x98, 0x01, 0x00, 0x20, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
-	0xe8, 0x93, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x22, 0x00, 0x80, 0x40,
-	0x8f, 0x98, 0x01, 0x00, 0x23, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
-	0x88, 0x00, 0x2d, 0x44, 0x8f, 0xb0, 0x01, 0x00, 0xf2, 0x93, 0xa2, 0x41,
-	0x19, 0x7c, 0x00, 0x00, 0xef, 0x93, 0xa2, 0x43, 0x3d, 0x7c, 0x00, 0x00,
-	0xef, 0x93, 0xa2, 0xf2, 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x40,
-	0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00,
-	0xf1, 0x93, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43,
-	0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x48, 0x8f, 0xb0, 0x01, 0x00,
-	0xef, 0x93, 0xa0, 0x91, 0x03, 0x6c, 0x00, 0x00, 0xed, 0x93, 0x22, 0x43,
-	0x3d, 0x7c, 0x00, 0x00, 0xf6, 0x93, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00,
-	0x28, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x29, 0x00, 0x80, 0x40,
-	0x8f, 0x98, 0x01, 0x00, 0x14, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x00, 0x94, 0xa2, 0xf0, 0x14, 0x30, 0x00, 0x00, 0x88, 0x00, 0x2d, 0x44,
-	0x8f, 0xb0, 0x01, 0x00, 0xfd, 0x93, 0xa2, 0xf2, 0x02, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0xa2, 0x40, 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x49,
-	0x8f, 0xb0, 0x01, 0x00, 0xef, 0x93, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0xed, 0x93, 0x20, 0x91, 0x03, 0x6c, 0x00, 0x00, 0xef, 0x93, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x94, 0x20, 0x0a, 0x02, 0x6c, 0x00, 0x00,
-	0x03, 0x94, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x44,
-	0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00,
-	0x09, 0x94, 0x22, 0x0a, 0x02, 0x6c, 0x00, 0x00, 0xdd, 0x93, 0xa2, 0x41,
-	0x19, 0x7c, 0x00, 0x00, 0x08, 0x94, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x55, 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x56,
-	0x8f, 0xb0, 0x01, 0x00, 0x0b, 0x94, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x43, 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x48,
-	0x8f, 0xb0, 0x01, 0x00, 0x11, 0x94, 0x00, 0x43, 0x95, 0xb0, 0x00, 0x00,
-	0x11, 0x94, 0x00, 0x41, 0x95, 0xb0, 0x00, 0x00, 0x11, 0x94, 0x00, 0x42,
-	0x95, 0xb0, 0x00, 0x00, 0x11, 0x94, 0x00, 0x44, 0x95, 0xb0, 0x00, 0x00,
-	0x11, 0x94, 0x00, 0x4c, 0x95, 0xb0, 0x00, 0x00, 0x30, 0x04, 0x00, 0x40,
-	0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x4a, 0x8a, 0x30, 0x01, 0x00,
-	0x55, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x16, 0x94, 0xa2, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x4b, 0x8f, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x4c, 0x8f, 0xb0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x05,
-	0x48, 0x6d, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x2e, 0x00, 0x2f, 0xf3, 0x84, 0xb0, 0x01, 0x00, 0x1c, 0x94, 0xa2, 0xf3,
-	0x96, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x01, 0xb0, 0x01, 0x00,
-	0x2d, 0x00, 0x2a, 0x41, 0xe7, 0xd1, 0x01, 0x00, 0xd4, 0x00, 0x3d, 0x41,
-	0x85, 0xe0, 0x01, 0x00, 0x0b, 0x00, 0x00, 0xf2, 0x00, 0xe4, 0x01, 0x00,
-	0x22, 0x94, 0x22, 0x5a, 0x01, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x1f, 0x90, 0x01, 0x00, 0x23, 0x94, 0x00, 0x5a, 0x01, 0x80, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x63, 0x41,
-	0x85, 0xc0, 0x01, 0x00, 0x26, 0x94, 0xa0, 0xa5, 0x85, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x63, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x12, 0x04, 0x00, 0x40,
-	0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0xa0, 0xa5,
-	0x85, 0x6c, 0x01, 0x00, 0x00, 0x00, 0xe3, 0x40, 0x85, 0xb0, 0x01, 0x00,
-	0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x12, 0x00, 0x00, 0x40,
-	0x87, 0x98, 0x01, 0x00, 0x78, 0x98, 0x00, 0xf0, 0x8c, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x22, 0x5f, 0x1f, 0x7c, 0x00, 0x00, 0x3b, 0x94, 0x22, 0x40,
-	0x0f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0x10, 0x00, 0x00, 0xf0,
-	0x98, 0xf4, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x07, 0x98, 0x6c, 0x00, 0x00,
-	0x10, 0x00, 0x00, 0x0c, 0x98, 0xf4, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x07,
-	0x98, 0x6c, 0x00, 0x00, 0x38, 0x94, 0xa2, 0x4b, 0x19, 0x7c, 0x00, 0x00,
-	0x39, 0x94, 0x22, 0xf0, 0x18, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x60, 0x4b,
-	0x19, 0x90, 0x01, 0x00, 0x3d, 0x95, 0x00, 0x07, 0x10, 0x30, 0x01, 0x00,
-	0x2f, 0x83, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x3d, 0x94, 0x22, 0x5a,
-	0x1f, 0x7c, 0x00, 0x00, 0xa5, 0x94, 0x00, 0x40, 0x81, 0x30, 0x01, 0x00,
-	0x2f, 0x83, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x22, 0x5f,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x60, 0x4b, 0x19, 0x90, 0x01, 0x00, 0x04, 0x00, 0x22, 0x5a,
-	0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40, 0x0f, 0x6c, 0x00, 0x00,
-	0x10, 0x00, 0x00, 0xf0, 0x96, 0xf4, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x07,
-	0x96, 0x6c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x0c, 0x96, 0xf4, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0x07, 0x96, 0x6c, 0x00, 0x00, 0x3d, 0x95, 0x00, 0x07,
-	0x10, 0x30, 0x01, 0x00, 0x2f, 0x83, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x22, 0x5f, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x4b, 0x19, 0x90, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40,
-	0x0f, 0x6c, 0x00, 0x00, 0x10, 0x00, 0x00, 0xf0, 0x96, 0xf4, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0x07, 0x96, 0x6c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x0c,
-	0x96, 0xf4, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x07, 0x96, 0x6c, 0x00, 0x00,
-	0x3d, 0x95, 0x00, 0x07, 0x10, 0x30, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x05, 0xb0, 0x01, 0x00, 0x54, 0x94, 0x33, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x57, 0x94, 0xa1, 0xad, 0x95, 0x20, 0x00, 0x00, 0x69, 0x94, 0x13, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x13, 0x4a, 0x5a, 0x83, 0x01, 0x00,
-	0x30, 0x00, 0x39, 0x45, 0x95, 0xe0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5f,
-	0x5f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5e, 0x5f, 0x7c, 0x00, 0x00,
-	0x1f, 0x00, 0x00, 0x0f, 0x5e, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5a,
-	0x5f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x5f, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x45, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04,
-	0x48, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x4a, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0c, 0x58, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07,
-	0x4e, 0xb0, 0x01, 0x00, 0x19, 0x85, 0x00, 0x40, 0x5d, 0x98, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0x44, 0x5f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x62, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0xa8, 0x41, 0x97, 0xb0, 0x00, 0x00, 0x66, 0x94, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x97, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0x40, 0x05, 0x6c, 0x00, 0x00, 0x15, 0x99, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x6c, 0x94, 0x60, 0x07, 0x96, 0x30, 0x00, 0x00,
-	0xff, 0xff, 0x00, 0x4b, 0x84, 0x89, 0x01, 0x00, 0x00, 0x00, 0x70, 0xc2,
-	0x24, 0xb0, 0x01, 0x00, 0x79, 0x94, 0xa2, 0x45, 0x25, 0x7c, 0x00, 0x00,
-	0x70, 0x94, 0x31, 0x20, 0x85, 0x30, 0x00, 0x00, 0x7a, 0x94, 0x22, 0x12,
-	0x48, 0x7f, 0x00, 0x00, 0x58, 0x04, 0x11, 0x12, 0x48, 0x03, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x12, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x1e, 0x94, 0x01, 0x00, 0x17, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x12, 0x8a, 0xb0, 0x01, 0x00, 0x02, 0x99, 0x00, 0x5f,
-	0x8b, 0x10, 0x01, 0x00, 0x00, 0x00, 0x80, 0x5a, 0x1f, 0x90, 0x01, 0x00,
-	0x79, 0x94, 0x31, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4,
-	0x24, 0xb0, 0x01, 0x00, 0x7a, 0x94, 0x22, 0x12, 0x48, 0x7f, 0x00, 0x00,
-	0x58, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x17, 0x04, 0x00, 0x40,
-	0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x12, 0x8a, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x89, 0x94, 0x0b, 0xf0,
-	0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x11, 0x12, 0x48, 0x83, 0x01, 0x00,
-	0x86, 0x94, 0x22, 0x50, 0x85, 0x70, 0x00, 0x00, 0x5e, 0x01, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0xae, 0x96, 0x00, 0xf2, 0x96, 0x30, 0x01, 0x00,
-	0x93, 0x04, 0x00, 0x12, 0x94, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5a,
-	0x1f, 0x90, 0x01, 0x00, 0x10, 0x00, 0x00, 0x12, 0x96, 0xe4, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x4b, 0x1e, 0x94, 0x01, 0x00, 0x10, 0x00, 0x00, 0x42,
-	0x10, 0xf4, 0x01, 0x00, 0x04, 0x00, 0x22, 0x08, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0xb7, 0x3f, 0x43, 0x11, 0xf0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x08,
-	0x8a, 0x88, 0x01, 0x00, 0x8d, 0x94, 0x30, 0xa1, 0x0c, 0x30, 0x00, 0x00,
-	0x90, 0x94, 0x22, 0x45, 0xe6, 0x7d, 0x00, 0x00, 0x7a, 0x94, 0x10, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x45, 0xe6, 0x91, 0x01, 0x00,
-	0x00, 0x00, 0x10, 0x12, 0x48, 0x83, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x05,
-	0x48, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x11, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x60, 0x4b, 0x85, 0x80, 0x01, 0x00, 0x5e, 0x01, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0xae, 0x96, 0x00, 0xf2, 0x96, 0x30, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0xd8, 0x00, 0x00, 0x40,
-	0x81, 0x98, 0x01, 0x00, 0x2e, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x9c, 0x94, 0x22, 0x40, 0xe7, 0x6d, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40,
-	0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf0, 0xb1, 0x01, 0x00,
-	0x09, 0x00, 0x00, 0x08, 0x86, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x68, 0xa7,
-	0x87, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0xa0, 0x94, 0xa8, 0x05,
-	0xe0, 0x31, 0x00, 0x00, 0x10, 0x00, 0x00, 0x12, 0x96, 0xe4, 0x01, 0x00,
-	0x00, 0x14, 0x00, 0x4b, 0x96, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x80, 0x4b,
-	0x1e, 0x94, 0x01, 0x00, 0x04, 0x00, 0x22, 0x5a, 0x1f, 0x7c, 0x00, 0x00,
-	0x10, 0x00, 0x00, 0x0f, 0x84, 0xf4, 0x01, 0x00, 0x1f, 0x00, 0x00, 0x42,
-	0x84, 0x88, 0x01, 0x00, 0xaa, 0x94, 0x22, 0x40, 0x80, 0x32, 0x00, 0x00,
-	0xab, 0x94, 0x00, 0x42, 0x68, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x6a, 0xb1, 0x01, 0x00, 0xab, 0x94, 0x31, 0x5a, 0x1f, 0x00, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x42, 0x48, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x91, 0x42,
-	0x48, 0x93, 0x01, 0x00, 0xae, 0x94, 0x35, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xb4, 0x94, 0x28, 0xb1,
-	0x2c, 0x30, 0x00, 0x00, 0xaf, 0x94, 0x22, 0x4d, 0x75, 0x7d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x2d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x95, 0x40,
-	0x11, 0xb0, 0x01, 0x00, 0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0xb4, 0x94, 0xa8, 0xb1, 0x10, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
-	0x80, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x27, 0x08, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x95, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x7f, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0xbf, 0x94, 0x28, 0xb1, 0x10, 0x30, 0x00, 0x00,
-	0xb9, 0x94, 0x9f, 0xba, 0x80, 0x32, 0x00, 0x00, 0x15, 0x00, 0x00, 0x40,
-	0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x11, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x5c,
-	0x11, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5a, 0x11, 0x7c, 0x00, 0x00,
-	0x04, 0x00, 0x22, 0x08, 0x48, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x24,
-	0x11, 0x84, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c, 0x01, 0x7c, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x5a, 0x01, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x00,
-	0x48, 0x06, 0x00, 0x00, 0x04, 0x00, 0x1f, 0xbb, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00,
-	0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xc8, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xac, 0x94, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0xcc, 0x94, 0x32, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xd4, 0x94, 0x22, 0xf8, 0x96, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x90, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x92, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0x80, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x27, 0x49,
-	0x80, 0x32, 0x00, 0x00, 0x01, 0x00, 0x00, 0x4b, 0xf0, 0xcd, 0x01, 0x00,
-	0x20, 0x00, 0x92, 0x48, 0xe0, 0xc9, 0x01, 0x00, 0x6c, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0xd8, 0x94, 0x28, 0xb1, 0x92, 0x30, 0x00, 0x00,
-	0xd4, 0x94, 0x22, 0x4c, 0x75, 0x7d, 0x00, 0x00, 0x04, 0x00, 0x12, 0x40,
-	0x91, 0xb0, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0xd8, 0x94, 0xa8, 0xb1, 0x90, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
-	0x80, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x27, 0x48, 0x80, 0x32, 0x00, 0x00,
-	0xff, 0x00, 0x00, 0x48, 0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x90, 0xd0, 0x01, 0x00, 0x01, 0x00, 0x00, 0x4b, 0xf0, 0xcd, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x48, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x92, 0x49,
-	0xe0, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x10, 0x48, 0xb1, 0x01, 0x00,
-	0xff, 0x07, 0x00, 0x08, 0x82, 0x8c, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
-	0x83, 0x7c, 0x00, 0x00, 0xff, 0x07, 0x00, 0xf0, 0x00, 0x8c, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0x5c, 0x01, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40,
-	0x01, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x41, 0x00, 0xec, 0x00, 0x00,
-	0xea, 0x94, 0x22, 0x1a, 0x00, 0x6c, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x00,
-	0x34, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x49, 0xc1, 0x01, 0x00,
-	0xe4, 0x94, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x10, 0x48, 0xb1, 0x01, 0x00,
-	0xff, 0x07, 0x00, 0x15, 0x82, 0x8c, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
-	0x83, 0x7c, 0x00, 0x00, 0xff, 0x07, 0x00, 0xf0, 0x00, 0x8c, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0x5c, 0x01, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40,
-	0x01, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x41, 0x00, 0xec, 0x00, 0x00,
-	0xf6, 0x94, 0x22, 0x0d, 0x00, 0x6c, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x00,
-	0x1a, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x49, 0xc1, 0x01, 0x00,
-	0xf0, 0x94, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0xfb, 0x94, 0x83, 0x1e, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x19, 0x90, 0x01, 0x00, 0x24, 0x00, 0x2d, 0x01,
-	0x2c, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x2d, 0xf0, 0x16, 0xb0, 0x01, 0x00,
-	0x22, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00, 0x14, 0x00, 0x2f, 0xf2,
-	0x0c, 0xb0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf0, 0x14, 0x6c, 0x00, 0x00,
-	0x04, 0x00, 0x20, 0x01, 0x14, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0xe1, 0xb1, 0x01, 0x00, 0x30, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
-	0x60, 0x97, 0x2e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0x04, 0x95, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
-	0x64, 0x97, 0x3e, 0x43, 0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0xe1, 0xb1, 0x01, 0x00, 0x64, 0x97, 0x3e, 0x43, 0x9d, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x0b, 0xe8, 0xb1, 0x01, 0x00, 0x64, 0x97, 0x3f, 0x43,
-	0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x16, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x64, 0x97, 0x3f, 0x43,
-	0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x16, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x60, 0x17, 0x3d, 0x43,
-	0x9d, 0xe0, 0x01, 0x00, 0x10, 0x00, 0x80, 0xa1, 0x16, 0xe4, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0x07, 0x16, 0x6c, 0x00, 0x00, 0x1a, 0x04, 0x00, 0x40,
-	0x89, 0x98, 0x01, 0x00, 0x10, 0x00, 0x00, 0x0b, 0x8a, 0xe4, 0x01, 0x00,
-	0x02, 0x99, 0x00, 0x0d, 0x8a, 0x14, 0x01, 0x00, 0x00, 0xb5, 0x00, 0x0d,
-	0x42, 0xc9, 0x01, 0x00, 0x17, 0x95, 0x30, 0x47, 0x17, 0x04, 0x00, 0x00,
-	0x1a, 0x95, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x90, 0x42,
-	0x81, 0xb0, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00,
-	0x1e, 0x95, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
-	0xe6, 0x91, 0x01, 0x00, 0x00, 0x00, 0x90, 0x41, 0x81, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x1f, 0x95, 0x40, 0x07,
-	0x96, 0x30, 0x00, 0x00, 0x9d, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x29, 0x95, 0xa2, 0x45, 0x95, 0x7c, 0x00, 0x00, 0x01, 0x97, 0x3f, 0x41,
-	0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4e, 0xe6, 0xb1, 0x01, 0x00, 0x40, 0x97, 0x3e, 0x40,
-	0x97, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xe6, 0xb1, 0x01, 0x00,
-	0x40, 0x97, 0x3e, 0x40, 0x9d, 0xe0, 0x01, 0x00, 0x3c, 0x95, 0x00, 0x3b,
-	0xe7, 0xb1, 0x00, 0x00, 0x29, 0x95, 0x30, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x33, 0x95, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x0d,
-	0x46, 0xc9, 0x01, 0x00, 0x2f, 0x95, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
-	0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x98, 0x42,
-	0x81, 0xb0, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0b, 0xe6, 0x91, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x98, 0x41, 0x81, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0x21, 0xa2, 0x95, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, 0x4a,
-	0x44, 0x83, 0x01, 0x00, 0x00, 0x97, 0x3e, 0x41, 0x95, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4e, 0xf6, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e,
-	0xe6, 0xb1, 0x01, 0x00, 0x40, 0x97, 0x3e, 0x40, 0x9d, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x3b, 0xe7, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
-	0x90, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0x07, 0x92, 0x89, 0x01, 0x00,
-	0x00, 0x00, 0x98, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x11, 0x04, 0x00, 0x40,
-	0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x08, 0x8a, 0x30, 0x01, 0x00,
-	0x03, 0x00, 0x00, 0x08, 0x86, 0xf4, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x43,
-	0x46, 0xc9, 0x01, 0x00, 0x07, 0x00, 0x00, 0x08, 0x82, 0x88, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0x08, 0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0x41,
-	0xe6, 0x7d, 0x00, 0x00, 0x44, 0x95, 0x40, 0x08, 0x96, 0x30, 0x00, 0x00,
-	0x9d, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x52, 0x95, 0x22, 0x45,
-	0x95, 0x7c, 0x00, 0x00, 0x4d, 0x95, 0x22, 0x5a, 0x1f, 0x7c, 0x00, 0x00,
-	0x10, 0x00, 0x00, 0x0f, 0x96, 0xf4, 0x01, 0x00, 0x49, 0x95, 0x31, 0x5f,
-	0x97, 0x04, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4b, 0x48, 0x7f, 0x00, 0x00,
-	0x00, 0x00, 0x11, 0x4b, 0x48, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x6a, 0xb1, 0x01, 0x00, 0x4d, 0x95, 0x30, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x04, 0x00, 0x22, 0x41, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0xe6, 0x81, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x97, 0x3f, 0x41,
-	0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00,
-	0x40, 0x97, 0x3d, 0x40, 0x97, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x63, 0xf3,
-	0x88, 0xb0, 0x01, 0x00, 0x5b, 0x95, 0xa2, 0x3b, 0x89, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6,
-	0x92, 0xb1, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x4a, 0x44, 0x7f, 0x00, 0x00,
-	0x5c, 0x95, 0x18, 0x4a, 0x44, 0x93, 0x00, 0x00, 0x00, 0x00, 0x18, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x3f, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
-	0x16, 0x00, 0x00, 0x12, 0x8a, 0xe4, 0x01, 0x00, 0x02, 0x99, 0x00, 0x4b,
-	0x8a, 0x14, 0x01, 0x00, 0x30, 0x00, 0x39, 0x45, 0x97, 0xe0, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0x5f, 0x5f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x5e,
-	0x5f, 0x7c, 0x00, 0x00, 0x1f, 0x04, 0x00, 0x2f, 0x7e, 0xd9, 0x01, 0x00,
-	0x04, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x68, 0x95, 0x22, 0x5a,
-	0x1f, 0x7c, 0x00, 0x00, 0x1f, 0x04, 0x00, 0x0f, 0x98, 0xd8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0x5e, 0x94, 0x01, 0x00, 0x6a, 0x95, 0x00, 0x05,
-	0x4a, 0xb0, 0x00, 0x00, 0x1f, 0x04, 0x00, 0xa7, 0x5e, 0x84, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x4b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5e,
-	0x5f, 0x90, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x08, 0x4e, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x58, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x6d, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x33, 0x04, 0x00, 0x40,
-	0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x07, 0x8a, 0x30, 0x01, 0x00,
-	0x72, 0x95, 0x40, 0x07, 0x96, 0x30, 0x00, 0x00, 0x9d, 0x04, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x76, 0x95, 0x22, 0x45, 0x95, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x4a,
-	0x44, 0x7f, 0x00, 0x00, 0x9b, 0x04, 0x00, 0x4a, 0x44, 0x13, 0x01, 0x00,
-	0x00, 0x97, 0x3f, 0x41, 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
-	0x96, 0xb0, 0x01, 0x00, 0x40, 0x97, 0x3d, 0x40, 0x97, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x63, 0xf3, 0x88, 0xb0, 0x01, 0x00, 0x30, 0x00, 0x38, 0x45,
-	0x97, 0xe0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5f, 0x1f, 0x7c, 0x00, 0x00,
-	0x04, 0x00, 0x22, 0x5e, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x20, 0xaa,
-	0x0f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x0f, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x58, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x62, 0xb1, 0x01, 0x00, 0x82, 0x95, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x78, 0x95, 0xa2, 0x3b, 0x89, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x38, 0x45,
-	0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0x08, 0x80, 0x32, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08,
-	0x94, 0xf4, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x4a, 0x46, 0xc9, 0x01, 0x00,
-	0x07, 0x00, 0x00, 0x08, 0x96, 0x88, 0x01, 0x00, 0x04, 0x00, 0x22, 0x4b,
-	0xe6, 0x7d, 0x00, 0x00, 0x93, 0x04, 0x00, 0x12, 0x94, 0x30, 0x01, 0x00,
-	0x3d, 0x95, 0x00, 0x5a, 0x1f, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x5a,
-	0x1f, 0x90, 0x01, 0x00, 0x11, 0x00, 0x00, 0x4a, 0xe6, 0xc9, 0x01, 0x00,
-	0x30, 0x00, 0x00, 0x4a, 0x80, 0xce, 0x01, 0x00, 0x04, 0x00, 0x24, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x34, 0x00, 0x2f, 0x4f, 0x95, 0x84, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x63, 0x4b,
-	0x84, 0xc8, 0x01, 0x00, 0x00, 0x00, 0xa0, 0x43, 0x85, 0x6c, 0x01, 0x00,
-	0x00, 0x00, 0xe3, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x30, 0x00, 0x2d, 0x44,
-	0x1f, 0x90, 0x01, 0x00, 0x32, 0x00, 0x2d, 0xf2, 0x2a, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0xf2,
-	0x02, 0x30, 0x00, 0x00, 0x17, 0x94, 0x00, 0x10, 0x32, 0x30, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0x42,
-	0x19, 0x7c, 0x00, 0x00, 0x32, 0x00, 0xa0, 0x40, 0xe5, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
-	0x99, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x02, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x03, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x97, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xa3, 0x4c, 0x02, 0xd0, 0x00, 0x00,
-	0xa3, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
-	0x36, 0xb0, 0x01, 0x00, 0xb4, 0x95, 0x22, 0x41, 0x03, 0x50, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0xf1, 0xb1, 0x01, 0x00, 0x70, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x62, 0xb1, 0x01, 0x00, 0xac, 0x95, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x7c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0x40, 0xe1, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x00, 0xb0, 0x01, 0x00, 0xa7, 0x95, 0x00, 0x5c, 0x01, 0x80, 0x00, 0x00,
-	0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1b,
-	0x10, 0xb1, 0x00, 0x00, 0x68, 0x01, 0x2d, 0x06, 0x82, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf2, 0x82, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
-	0x46, 0xc9, 0x01, 0x00, 0xb9, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xe2, 0x95, 0x22, 0x40, 0x11, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x68, 0x08,
-	0x38, 0x96, 0x01, 0x00, 0x3a, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
-	0x02, 0x99, 0x00, 0x08, 0x8a, 0x30, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x41,
-	0x82, 0xcc, 0x01, 0x00, 0xb9, 0x95, 0xaa, 0x41, 0x3b, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
-	0x11, 0x80, 0x01, 0x00, 0x04, 0x00, 0xa3, 0x48, 0x3b, 0x6c, 0x00, 0x00,
-	0x01, 0x00, 0x00, 0x1d, 0x04, 0xcc, 0x01, 0x00, 0xe0, 0x95, 0x26, 0x46,
-	0x23, 0x30, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x12, 0xc8, 0x01, 0x00,
-	0x04, 0x80, 0x00, 0x03, 0x98, 0xc8, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x4c,
-	0x42, 0x6d, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
-	0x64, 0x01, 0x20, 0xf0, 0xe0, 0xb1, 0x01, 0x00, 0xdf, 0x95, 0x22, 0x41,
-	0x05, 0x50, 0x00, 0x00, 0x20, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
-	0x0c, 0x00, 0x00, 0xf8, 0x86, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x22, 0x44,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x09, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
-	0xd1, 0x95, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00, 0xde, 0x95, 0x22, 0x41,
-	0x05, 0x50, 0x00, 0x00, 0xdc, 0x95, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xa1, 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0xd7, 0x95, 0xa8, 0x46, 0x23, 0x30, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0d, 0x42, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x13, 0xc0, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x50, 0x49, 0xc1, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x04, 0x80, 0x00, 0x03,
-	0x1a, 0xc8, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xe0, 0x95, 0x22, 0x40,
-	0x3b, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xb0, 0x01, 0x00,
-	0xc3, 0x94, 0x00, 0x5c, 0x01, 0x00, 0x01, 0x00, 0xe2, 0x95, 0x00, 0x41,
-	0x3b, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x47, 0x80, 0x32, 0x01, 0x00,
-	0xb0, 0x00, 0x2f, 0x5f, 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0xf0,
-	0x8c, 0xc0, 0x01, 0x00, 0x7c, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x04, 0x00, 0xa3, 0xf0, 0x8c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x8c, 0xb0, 0x01, 0x00, 0xf1, 0x95, 0x8c, 0xf8, 0x8e, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x19, 0x90, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf8,
-	0x14, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x16, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x26, 0xb0, 0x01, 0x00, 0x08, 0x00, 0x2e, 0xf8,
-	0x0c, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x2a, 0x4a, 0xe0, 0xb1, 0x01, 0x00,
-	0x28, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x20, 0x1b,
-	0xe0, 0xb1, 0x01, 0x00, 0xfe, 0x95, 0x20, 0x0a, 0x0c, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x96, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x20, 0xf0, 0xe4, 0xb1, 0x01, 0x00,
-	0x18, 0x00, 0x20, 0x4a, 0xe0, 0xb1, 0x01, 0x00, 0x1c, 0x00, 0x20, 0x4b,
-	0xe0, 0xb1, 0x01, 0x00, 0xe6, 0x95, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00, 0x2c, 0x00, 0x2d, 0x42,
-	0x19, 0x90, 0x01, 0x00, 0x2e, 0x00, 0x2f, 0xf3, 0x82, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00, 0x05, 0x96, 0xa2, 0xa5,
-	0x97, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41, 0x95, 0xb0, 0x01, 0x00,
-	0x08, 0x96, 0xa2, 0x40, 0x97, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x83, 0xb0, 0x01, 0x00, 0x2d, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x63, 0x41, 0x97, 0xc0, 0x01, 0x00, 0xd4, 0x00, 0x3e, 0x41,
-	0x83, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00,
-	0x0d, 0x96, 0xa0, 0xa5, 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x83, 0xb0, 0x01, 0x00, 0x2c, 0x00, 0x20, 0x41, 0xe6, 0xb1, 0x01, 0x00,
-	0x12, 0x96, 0x22, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
-	0x98, 0xdc, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x4c, 0xe4, 0xf5, 0x01, 0x00,
-	0x13, 0x96, 0x00, 0x40, 0x1f, 0x80, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
-	0xe4, 0xf5, 0x01, 0x00, 0x1e, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
-	0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0xcb, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x40,
-	0xe1, 0x6d, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x41, 0x87, 0xb0, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x49, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5d,
-	0x05, 0x90, 0x00, 0x00, 0x23, 0x96, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xcb, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xf0, 0xb1, 0x01, 0x00,
-	0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5d, 0x05, 0x90, 0x00, 0x00,
-	0x33, 0x96, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05,
-	0x48, 0x6d, 0x00, 0x00, 0x04, 0x00, 0x82, 0x0c, 0x80, 0x32, 0x00, 0x00,
-	0x2d, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x2e, 0x00, 0x2f, 0xf3,
-	0x84, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3, 0x96, 0xc8, 0x01, 0x00,
-	0x3d, 0x96, 0x9f, 0x41, 0x85, 0x50, 0x00, 0x00, 0x01, 0x00, 0x00, 0xa5,
-	0x85, 0xcc, 0x01, 0x00, 0x2d, 0x00, 0x20, 0x42, 0xe6, 0xb1, 0x01, 0x00,
-	0x04, 0x00, 0xa3, 0xa5, 0x97, 0x6c, 0x00, 0x00, 0xd4, 0x00, 0x3d, 0x41,
-	0x85, 0xe0, 0x01, 0x00, 0x0b, 0x00, 0x00, 0xf2, 0x98, 0xe4, 0x01, 0x00,
-	0x44, 0x96, 0x22, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x5a,
-	0x99, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x99, 0x80, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0x00, 0x98, 0x6c, 0x00, 0x00, 0x20, 0x04, 0x00, 0x40,
-	0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x21, 0x04, 0x00, 0x40,
-	0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0x00, 0x6a, 0x06, 0x00, 0x00, 0x5e, 0x01, 0x2d, 0x00,
-	0x80, 0xb0, 0x01, 0x00, 0x4f, 0x96, 0x52, 0x43, 0x81, 0x60, 0x00, 0x00,
-	0x02, 0x00, 0x00, 0xf2, 0x82, 0xf4, 0x01, 0x00, 0x50, 0x96, 0x00, 0x41,
-	0x80, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x81, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5e, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x95, 0xb0, 0x00, 0x00,
-	0x51, 0x96, 0x9e, 0xbb, 0x80, 0x32, 0x00, 0x00, 0x56, 0x96, 0xa2, 0x40,
-	0x1f, 0x7c, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x41, 0x95, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x15,
-	0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0x2b, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfc, 0x24, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
-	0x38, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3c, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfe, 0x3a, 0xb0, 0x01, 0x00, 0x6b, 0x96, 0x9c, 0x17,
-	0x80, 0x32, 0x00, 0x00, 0x60, 0x96, 0xa2, 0x4a, 0x19, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x4c, 0x1f, 0x90, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x1e,
-	0x98, 0xf4, 0x01, 0x00, 0x5f, 0x96, 0xa2, 0x48, 0x99, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x15, 0x42, 0xb1, 0x01, 0x00, 0x5f, 0x96, 0xa2, 0x8a,
-	0xf1, 0x6d, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x02, 0xcc, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfc, 0x3e, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x00, 0xf4,
-	0x28, 0xcc, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x6a, 0x96, 0x20, 0xf0, 0x3e, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x2b, 0xc0, 0x01, 0x00,
-	0xbf, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0xf3,
-	0x3a, 0xe0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
-	0x10, 0x00, 0x00, 0x0c, 0x96, 0xf4, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x07,
-	0x96, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x4b, 0x19, 0x90, 0x01, 0x00,
-	0x07, 0x00, 0x2a, 0x0c, 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x04,
-	0xe6, 0xb1, 0x01, 0x00, 0x18, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x1c, 0x00, 0x2d, 0xf0, 0x16, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x2d, 0xf0,
-	0x26, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x2f, 0xf2, 0x0c, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0xa2, 0x06, 0x14, 0xec, 0x00, 0x00, 0x7a, 0x96, 0x22, 0x45,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xa3, 0x06, 0x2a, 0xec, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x96, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x2a, 0x4c, 0xe1, 0xc1, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10,
-	0x48, 0xc9, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
-	0x18, 0x00, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0xe0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
-	0x62, 0xdd, 0x01, 0x00, 0x84, 0x96, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x95,
-	0x03, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00, 0x40, 0x00, 0x00, 0x03,
-	0xf0, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x2e, 0x50, 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
-	0x8f, 0x96, 0x62, 0x42, 0x61, 0x31, 0x00, 0x00, 0x20, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x90, 0x96, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x10, 0x00, 0x00, 0x10, 0x62, 0xc9, 0x01, 0x00, 0x92, 0x96, 0xa8, 0x00,
-	0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0x95, 0x03, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x10,
-	0x48, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00,
-	0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x50, 0x49, 0xc1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x06, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0xf0, 0xb1, 0x01, 0x00, 0x9d, 0x96, 0x62, 0x42, 0x61, 0x31, 0x00, 0x00,
-	0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x9e, 0x96, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
-	0xa0, 0x96, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x30, 0x80, 0x00, 0x4a, 0x44, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x06, 0xf1, 0xb1, 0x01, 0x00, 0xc0, 0xa8, 0x3d, 0x46,
-	0x0d, 0xe0, 0x01, 0x00, 0xff, 0x7f, 0x00, 0xa1, 0xf0, 0x89, 0x01, 0x00,
-	0x02, 0x00, 0x00, 0x09, 0x96, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0x97, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x60, 0xa8, 0x97, 0xc0, 0x01, 0x00,
-	0xaa, 0x96, 0x63, 0x42, 0x61, 0x31, 0x00, 0x00, 0x30, 0x00, 0x00, 0x4a,
-	0x62, 0xc9, 0x01, 0x00, 0xab, 0x96, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0xf3, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x99, 0x3f, 0x42,
-	0x97, 0xf0, 0x01, 0x00, 0xaf, 0x96, 0x65, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xb7, 0x96, 0x22, 0xf3, 0x74, 0x06, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf3,
-	0x94, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe7, 0x85, 0x01, 0x00,
-	0x00, 0x00, 0x75, 0x55, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
-	0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xb4, 0x96, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x36, 0xb0, 0x01, 0x00,
-	0xc7, 0x96, 0x82, 0x41, 0x23, 0x40, 0x00, 0x00, 0xbc, 0x96, 0xa2, 0x44,
-	0x1f, 0x7c, 0x00, 0x00, 0x98, 0x93, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00,
-	0x20, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0xc2, 0x96, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xbf, 0x96, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x23, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x32, 0xb0, 0x01, 0x00, 0xc7, 0x96, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0xe1, 0x94, 0x00, 0x43, 0x23, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x23, 0xb0, 0x01, 0x00, 0xc9, 0x96, 0xa3, 0x15, 0x0c, 0x6c, 0x00, 0x00,
-	0xca, 0x96, 0x00, 0x06, 0x04, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
-	0x04, 0xb0, 0x01, 0x00, 0xcc, 0x96, 0x20, 0x02, 0x1a, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x0d, 0x04, 0xb0, 0x01, 0x00, 0x9b, 0x97, 0x00, 0x05,
-	0x48, 0x31, 0x01, 0x00, 0xf7, 0x96, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00,
-	0xd0, 0x96, 0xa2, 0x02, 0x2a, 0x50, 0x00, 0x00, 0xf7, 0x96, 0xa2, 0x45,
-	0x1f, 0x7c, 0x00, 0x00, 0xd2, 0x96, 0x22, 0x02, 0x0c, 0x50, 0x00, 0x00,
-	0xdb, 0x96, 0x00, 0x02, 0x16, 0xc0, 0x00, 0x00, 0xda, 0x96, 0x22, 0x5c,
-	0x1f, 0x7c, 0x00, 0x00, 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
-	0xda, 0x96, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0xd6, 0x96, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x73, 0x96, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0xf7, 0x96, 0x22, 0x15,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
-	0xf6, 0x96, 0xa2, 0x02, 0x1a, 0x50, 0x00, 0x00, 0xe7, 0x96, 0x22, 0x46,
-	0x1f, 0x7c, 0x00, 0x00, 0x70, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00, 0xe7, 0x96, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xe3, 0x96, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x80, 0x32, 0x00, 0x00,
-	0x10, 0x00, 0x00, 0xf0, 0x10, 0xc8, 0x01, 0x00, 0x2f, 0x00, 0x2f, 0x5c,
-	0x11, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0xe7, 0x91, 0x01, 0x00,
-	0xf0, 0x07, 0x00, 0x40, 0x1b, 0x98, 0x01, 0x00, 0xb9, 0x96, 0x20, 0x15,
-	0x1a, 0x6c, 0x00, 0x00, 0x70, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x22, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0xf0, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08, 0xe0, 0x8d, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
-	0x62, 0xdd, 0x01, 0x00, 0xf3, 0x96, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
-	0xb9, 0x96, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0xb9, 0x96, 0x00, 0x02,
-	0x10, 0xc0, 0x00, 0x00, 0xf9, 0x96, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
-	0x98, 0x93, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1b,
-	0x10, 0xb1, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x10, 0x00, 0x00, 0x08,
-	0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x03, 0xe0, 0xc9, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5c,
-	0x1f, 0x90, 0x00, 0x00, 0x01, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x17, 0x00, 0x00, 0xd0, 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x40,
-	0x27, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xb0, 0x01, 0x00,
-	0xc3, 0x94, 0x00, 0x41, 0xa3, 0x41, 0x01, 0x00, 0x05, 0x97, 0x00, 0x41,
-	0x27, 0xd0, 0x00, 0x00, 0x36, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
-	0x02, 0x99, 0x00, 0x40, 0x8a, 0x30, 0x01, 0x00, 0x10, 0x00, 0x00, 0x07,
-	0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x80, 0x94, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40,
-	0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x14, 0xbb, 0x80, 0x32, 0x00, 0x00, 0x0e, 0x97, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
-	0x64, 0x97, 0x00, 0x40, 0x2b, 0x30, 0x01, 0x00, 0xac, 0x00, 0x2d, 0x06,
-	0x16, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0, 0x16, 0xc4, 0x01, 0x00,
-	0x18, 0x97, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x17, 0xc0, 0x01, 0x00, 0x0e, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x6c, 0xf0, 0x30, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x2d, 0x40,
-	0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x6c, 0xf0, 0x28, 0xb0, 0x01, 0x00,
-	0x21, 0x97, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x43,
-	0x86, 0xc8, 0x01, 0x00, 0x00, 0x30, 0x00, 0x0b, 0x16, 0xc8, 0x01, 0x00,
-	0x21, 0x97, 0xa4, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x17, 0xc0, 0x01, 0x00, 0x44, 0x97, 0x22, 0x06, 0x80, 0x32, 0x00, 0x00,
-	0x2f, 0x97, 0xa2, 0x06, 0x14, 0x6c, 0x00, 0x00, 0x2c, 0x97, 0x22, 0x48,
-	0x19, 0x7c, 0x00, 0x00, 0x26, 0x97, 0xa0, 0x41, 0x17, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x31, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x20, 0x18, 0xe0, 0xb1, 0x01, 0x00,
-	0x8b, 0x00, 0x2d, 0x48, 0x19, 0x80, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x45,
-	0xe7, 0x7d, 0x00, 0x00, 0x8b, 0x00, 0x20, 0x45, 0xe7, 0x91, 0x01, 0x00,
-	0x2f, 0x97, 0x00, 0x40, 0x87, 0x90, 0x00, 0x00, 0x08, 0x00, 0x00, 0x43,
-	0x86, 0x98, 0x01, 0x00, 0x2f, 0x97, 0xa0, 0x48, 0x17, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0xb0, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x10, 0x50, 0x00, 0x43, 0xfc, 0xc9, 0x01, 0x00,
-	0xa8, 0x97, 0x00, 0x30, 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xe5, 0xb1, 0x01, 0x00, 0x3a, 0x97, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00,
-	0x08, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0xab,
-	0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab, 0x17, 0xc0, 0x01, 0x00,
-	0x39, 0x97, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x17, 0xc0, 0x01, 0x00, 0x3e, 0x97, 0x64, 0xf0, 0x82, 0xb0, 0x00, 0x00,
-	0xa4, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x3e, 0x97, 0xa2, 0xf2,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xe5, 0xb1, 0x01, 0x00,
-	0x8c, 0x00, 0x20, 0x18, 0xe0, 0xb1, 0x01, 0x00, 0x90, 0x00, 0x00, 0x40,
-	0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x60, 0x06, 0x30, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x86, 0x0c, 0x80, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x49,
-	0x19, 0x7c, 0x00, 0x00, 0xbc, 0x00, 0x2d, 0x46, 0x19, 0x90, 0x01, 0x00,
-	0xa0, 0x00, 0xa0, 0xf2, 0xe4, 0xb1, 0x01, 0x00, 0xb0, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x10, 0x50, 0x00, 0x43, 0xfc, 0xc9, 0x01, 0x00,
-	0xa8, 0x97, 0x00, 0x30, 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x4a,
-	0x19, 0xfc, 0x00, 0x00, 0x08, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00,
-	0xcc, 0x00, 0x2d, 0xab, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab,
-	0x17, 0xc0, 0x01, 0x00, 0x4d, 0x97, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xe4, 0xf0,
-	0x82, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x1b,
-	0xe0, 0xb1, 0x00, 0x00, 0x52, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0xf0, 0x00, 0x0c, 0x7e, 0x89, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x4c,
-	0x95, 0x60, 0x01, 0x00, 0x00, 0x00, 0x80, 0x4a, 0x18, 0x94, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x01,
-	0xf0, 0x31, 0x00, 0x00, 0x20, 0x00, 0x00, 0x40, 0xf0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x00, 0x00, 0xa8, 0x15, 0xe0, 0xb1, 0x00, 0x00, 0x5d, 0x97, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x10, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x06, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xe8, 0x5f, 0x17, 0x90, 0x01, 0x00,
-	0x70, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x7a, 0x01, 0x2e, 0xfe,
-	0x92, 0xb0, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0xf6, 0x16, 0xb0, 0x01, 0x00,
-	0x6a, 0x97, 0x22, 0x43, 0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x45, 0xc1, 0x01, 0x00, 0x04, 0x00, 0x00, 0xa6, 0x2a, 0xb0, 0x01, 0x00,
-	0x28, 0x00, 0x6e, 0x06, 0x82, 0xc8, 0x01, 0x00, 0x6e, 0x97, 0x22, 0x4a,
-	0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x45, 0xd1, 0x01, 0x00,
-	0x00, 0x00, 0x6e, 0x4c, 0x83, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x92, 0xc0, 0x01, 0x00, 0x6f, 0x97, 0x43, 0x30, 0x3d, 0x07, 0x00, 0x00,
-	0x00, 0x00, 0x66, 0x9e, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x1b, 0x41,
-	0x3d, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x92, 0xc0, 0x01, 0x00,
-	0x06, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x49,
-	0x98, 0xf4, 0x01, 0x00, 0x78, 0x97, 0x26, 0x30, 0x93, 0x04, 0x00, 0x00,
-	0x78, 0x97, 0x90, 0x4c, 0x92, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x93, 0xc0, 0x01, 0x00, 0xff, 0xff, 0x80, 0x49, 0xec, 0xa9, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x01,
-	0xf0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x15, 0xe0, 0xb1, 0x00, 0x00,
-	0x7d, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x22, 0x20,
-	0x81, 0x6c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40, 0x81, 0x6c, 0x00, 0x00,
-	0x8f, 0x97, 0x22, 0x5f, 0x81, 0x7c, 0x00, 0x00, 0x8c, 0x97, 0xa2, 0x40,
-	0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x19, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x07,
-	0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x97, 0x94, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00, 0x8c, 0x97, 0x28, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x00, 0x00,
-	0x88, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x25, 0x04, 0x00, 0x40,
-	0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x40, 0x8a, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0xa2, 0x21, 0x81, 0x84, 0x00, 0x00, 0x92, 0x97, 0xa2, 0x5f,
-	0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x43, 0x19, 0x7c, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x19, 0x90, 0x01, 0x00, 0x25, 0x04, 0x00, 0x40,
-	0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x40, 0x8a, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x07,
-	0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x96, 0x94, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x00, 0x00,
-	0x97, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x22, 0x08,
-	0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00,
-	0xa0, 0x97, 0xa2, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0xb4, 0x05, 0x00, 0x02,
-	0x80, 0xce, 0x01, 0x00, 0x04, 0x00, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x19, 0x44, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x02,
-	0xf0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x13, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
-	0x00, 0x00, 0xa8, 0x08, 0xe0, 0xb1, 0x00, 0x00, 0xa5, 0x97, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
-	0xb0, 0x00, 0x00, 0xa1, 0x80, 0xce, 0x01, 0x00, 0x04, 0x00, 0xa6, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x7c, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00,
-	0x02, 0x00, 0x00, 0xf0, 0x98, 0xf4, 0x01, 0x00, 0xb1, 0x97, 0x20, 0x4c,
-	0x84, 0x6c, 0x00, 0x00, 0x88, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0xb1, 0x97, 0x20, 0xf2, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x85, 0xb0, 0x01, 0x00, 0x98, 0x00, 0x2d, 0x14, 0x82, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x98, 0xb0, 0x01, 0x00, 0xa3, 0x00, 0x2d, 0x14,
-	0x98, 0xd0, 0x01, 0x00, 0xb6, 0x97, 0x20, 0x4c, 0x84, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0x84, 0xb0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x30,
-	0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x80, 0xe0, 0x01, 0x00,
-	0xba, 0x97, 0x23, 0x40, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x84, 0xb0, 0x01, 0x00, 0xd0, 0x00, 0x20, 0x14, 0xe0, 0xb1, 0x01, 0x00,
-	0x98, 0x00, 0x25, 0x42, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x6e, 0xf3,
-	0x80, 0xf0, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x42, 0x82, 0xc0, 0x00, 0x00,
-	0xc0, 0x97, 0xa0, 0x40, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x9f, 0xf0, 0x82, 0xec, 0x00, 0x00,
-	0x98, 0x00, 0xa0, 0x41, 0xe0, 0xb1, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
-	0x1f, 0x7c, 0x00, 0x00, 0x37, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
-	0x02, 0x99, 0x00, 0x05, 0x8a, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
-	0xa8, 0x01, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0xf0, 0xb1, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07, 0x96, 0xe4, 0x01, 0x00,
-	0x00, 0x00, 0x60, 0xa7, 0x97, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xcb, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xa8, 0x00, 0x2d, 0x1c,
-	0x8a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x9f, 0xf0, 0x8a, 0xd0, 0x00, 0x00,
-	0x00, 0x00, 0xa2, 0x40, 0x8b, 0xec, 0x00, 0x00, 0x8a, 0x00, 0x20, 0x40,
-	0xe7, 0xb1, 0x01, 0x00, 0xb4, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0xa4, 0x00, 0x2d, 0x45, 0xe0, 0xd1, 0x01, 0x00, 0xd9, 0x97, 0x9c, 0x17,
-	0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00,
-	0xbe, 0x00, 0x2f, 0xab, 0x83, 0xb0, 0x01, 0x00, 0x35, 0x98, 0x00, 0x14,
-	0x82, 0x50, 0x01, 0x00, 0xde, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xde, 0x97, 0x22, 0xf2, 0x82, 0x30, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0xde, 0x97, 0x9f, 0x1c, 0xe0, 0x6d, 0x00, 0x00,
-	0xbe, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x35, 0x98, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xa8, 0x00, 0x20, 0x1c, 0xe0, 0xb1, 0x01, 0x00,
-	0x9c, 0x00, 0x2d, 0x30, 0x81, 0xb0, 0x01, 0x00, 0x88, 0x00, 0x2d, 0xf0,
-	0x84, 0xb0, 0x01, 0x00, 0x94, 0x00, 0x2d, 0xf2, 0x86, 0xb0, 0x01, 0x00,
-	0xf2, 0x97, 0x23, 0xf0, 0x84, 0x6c, 0x00, 0x00, 0xe6, 0x97, 0x23, 0x92,
-	0x87, 0x6c, 0x00, 0x00, 0xc9, 0x04, 0x00, 0xa6, 0x94, 0xb0, 0x01, 0x00,
-	0xe8, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6,
-	0x94, 0xb0, 0x01, 0x00, 0x60, 0x89, 0x00, 0x4a, 0x94, 0x98, 0x01, 0x00,
-	0xe8, 0x97, 0x68, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40,
-	0xbd, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0xb0, 0xb1, 0x01, 0x00,
-	0xbf, 0x00, 0x2d, 0x42, 0xb2, 0xb1, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf3,
-	0x80, 0xe0, 0x01, 0x00, 0xed, 0x97, 0xd4, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x78, 0xda, 0x84, 0xc0, 0x01, 0x00, 0xf7, 0x97, 0x23, 0x40,
-	0x84, 0x6c, 0x00, 0x00, 0x94, 0x00, 0x20, 0x9d, 0xe1, 0xb1, 0x01, 0x00,
-	0xf7, 0x97, 0x00, 0x40, 0x84, 0xb0, 0x00, 0x00, 0xbf, 0x00, 0x2d, 0x43,
-	0x84, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf3, 0x80, 0xe0, 0x01, 0x00,
-	0xf7, 0x97, 0x23, 0x40, 0x84, 0x6c, 0x00, 0x00, 0x94, 0x00, 0x20, 0x9d,
-	0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x84, 0xb0, 0x01, 0x00,
-	0xfb, 0x97, 0xa2, 0xf0, 0x38, 0x6c, 0x00, 0x00, 0x9c, 0x00, 0x20, 0x42,
-	0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x13, 0x94, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x46, 0x19, 0x80, 0x01, 0x00, 0x9c, 0x00, 0x20, 0x42,
-	0xe0, 0xb1, 0x01, 0x00, 0x37, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0xf3, 0x80, 0xf4, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3,
-	0x82, 0x88, 0x01, 0x00, 0x01, 0x98, 0x23, 0x41, 0x80, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x13, 0x94, 0x01, 0x00, 0x00, 0x00, 0x89, 0x0c,
-	0x80, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x86, 0x0c, 0x80, 0x32, 0x00, 0x00,
-	0xbc, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xa0, 0x00, 0xa0, 0xf2,
-	0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x9f, 0x41, 0x24, 0xec, 0x00, 0x00,
-	0x0d, 0x98, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x42,
-	0x38, 0xec, 0x00, 0x00, 0x0d, 0x98, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xb4, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x0f, 0x98, 0xa3, 0xf0,
-	0x3a, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa4, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xb4, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x13, 0x98, 0x22, 0xf0, 0x3a, 0x6c, 0x00, 0x00,
-	0xb4, 0x00, 0x20, 0x1d, 0xe0, 0xb1, 0x01, 0x00, 0x80, 0x00, 0x2d, 0x5f,
-	0x13, 0x94, 0x01, 0x00, 0x13, 0x98, 0x23, 0xf0, 0x3a, 0x6c, 0x00, 0x00,
-	0x80, 0x00, 0x20, 0x1d, 0xe0, 0xb1, 0x01, 0x00, 0xc0, 0x00, 0x20, 0x12,
-	0xe0, 0xb1, 0x01, 0x00, 0xc4, 0x00, 0xa0, 0x1c, 0xe0, 0xb1, 0x01, 0x00,
-	0x27, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x42,
-	0x8a, 0x30, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0xe0, 0xb1, 0x01, 0x00, 0x12, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
-	0x1f, 0x98, 0x9f, 0x41, 0x24, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x12, 0x8c, 0xd0, 0x01, 0x00,
-	0x20, 0x98, 0x00, 0x41, 0x24, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x8d, 0xb0, 0x01, 0x00, 0x78, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x22, 0x98, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xae, 0x94, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0x80, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0xa7, 0x08, 0x80, 0x32, 0x01, 0x00, 0x32, 0x04, 0x00, 0x40,
-	0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x08, 0x8a, 0x30, 0x01, 0x00,
-	0x2c, 0x98, 0xa2, 0x40, 0x95, 0x6c, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x82, 0x00, 0xa6, 0x04, 0xb0, 0x01, 0x00,
-	0xa0, 0x98, 0x2f, 0x40, 0x11, 0xb0, 0x01, 0x00, 0x30, 0x05, 0x00, 0x41,
-	0x89, 0xb0, 0x00, 0x00, 0xcc, 0x00, 0x00, 0xa1, 0x80, 0xce, 0x01, 0x00,
-	0x04, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9f, 0xf8,
-	0x3e, 0xec, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x12, 0xe0, 0xed, 0x00, 0x00,
-	0xc8, 0x00, 0x20, 0xab, 0xe1, 0xb1, 0x01, 0x00, 0xcc, 0x00, 0xa0, 0x1f,
-	0xe0, 0xb1, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
-	0x38, 0x98, 0xa3, 0x5f, 0xe7, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0xe7, 0xc1, 0x01, 0x00, 0xa6, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x4c, 0x98, 0x22, 0xf2, 0x86, 0x30, 0x00, 0x00, 0x03, 0x00, 0x00, 0x43,
-	0x84, 0xf4, 0x01, 0x00, 0x01, 0x00, 0x00, 0x41, 0x80, 0xcc, 0x01, 0x00,
-	0xb8, 0x00, 0x2d, 0x42, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x62, 0x40,
-	0x86, 0xc0, 0x01, 0x00, 0x40, 0x98, 0x1f, 0x43, 0x80, 0x32, 0x00, 0x00,
-	0x41, 0x98, 0xa2, 0x40, 0x87, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x62, 0x41,
-	0x87, 0xb0, 0x01, 0x00, 0x45, 0x98, 0x9f, 0x40, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x84, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x80, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf2, 0x88, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x00, 0x44,
-	0x84, 0xf4, 0x01, 0x00, 0xb8, 0x00, 0x2e, 0x42, 0x80, 0xd0, 0x01, 0x00,
-	0x00, 0x00, 0x62, 0x40, 0x88, 0xc0, 0x01, 0x00, 0x4b, 0x98, 0x1f, 0x44,
-	0x80, 0x32, 0x00, 0x00, 0x4f, 0x98, 0xa2, 0x40, 0x89, 0x6c, 0x00, 0x00,
-	0x4f, 0x98, 0x62, 0x41, 0x89, 0xb0, 0x00, 0x00, 0x03, 0x00, 0x62, 0x41,
-	0x86, 0xe4, 0x01, 0x00, 0xb8, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
-	0x01, 0x00, 0x62, 0x41, 0x88, 0xe4, 0x01, 0x00, 0xa4, 0x00, 0x20, 0x40,
-	0xe5, 0xb1, 0x01, 0x00, 0xa2, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
-	0xbc, 0x00, 0x2e, 0x43, 0x87, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x86, 0xc0, 0x01, 0x00, 0x55, 0x98, 0x20, 0x43, 0x87, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x43, 0xe5, 0xb1, 0x01, 0x00, 0x40, 0x01, 0x00, 0x43,
-	0x80, 0xce, 0x01, 0x00, 0x00, 0x00, 0xa4, 0x43, 0xe4, 0x31, 0x01, 0x00,
-	0x40, 0x01, 0xe2, 0x40, 0x87, 0x98, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x05,
-	0x48, 0x6d, 0x00, 0x00, 0x04, 0x00, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00,
-	0x88, 0x00, 0x2d, 0x44, 0x81, 0xb0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf2,
-	0x2e, 0xb0, 0x01, 0x00, 0x9c, 0x00, 0x2d, 0xf0, 0x86, 0xb0, 0x01, 0x00,
-	0x90, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0xba, 0x00, 0x2d, 0xf0,
-	0x98, 0xb0, 0x01, 0x00, 0x64, 0x98, 0xa2, 0x12, 0x98, 0x6c, 0x00, 0x00,
-	0xbc, 0x00, 0x2d, 0xf2, 0x98, 0xb0, 0x01, 0x00, 0x64, 0x98, 0xa0, 0xf2,
-	0x98, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x82, 0xb0, 0x01, 0x00,
-	0x9c, 0x00, 0x20, 0x41, 0xe0, 0xb1, 0x01, 0x00, 0xb4, 0x00, 0x2d, 0x12,
-	0x86, 0xd0, 0x01, 0x00, 0x67, 0x98, 0xa3, 0x41, 0xe0, 0x6d, 0x00, 0x00,
-	0x68, 0x98, 0x00, 0xf0, 0x84, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x84, 0xb0, 0x01, 0x00, 0x80, 0x00, 0x2d, 0x43, 0x84, 0xd0, 0x01, 0x00,
-	0x6b, 0x98, 0x9f, 0x42, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x85, 0xb0, 0x01, 0x00, 0x6d, 0x98, 0xa3, 0x42, 0x14, 0x6c, 0x00, 0x00,
-	0x6e, 0x98, 0x00, 0x0a, 0x0c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x0c, 0xb0, 0x01, 0x00, 0x70, 0x98, 0xa0, 0x17, 0x0c, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x17, 0x0c, 0xb0, 0x01, 0x00, 0x75, 0x98, 0x22, 0x40,
-	0x0d, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0a, 0x0c, 0xec, 0x00, 0x00,
-	0x01, 0x00, 0x00, 0xf0, 0x82, 0xf4, 0x01, 0x00, 0x75, 0x98, 0xa0, 0x41,
-	0x0c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xf0, 0x80, 0x32, 0x01, 0x00,
-	0x29, 0x00, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb0, 0x01, 0x00,
-	0xcb, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x04, 0x00, 0x22, 0x03,
-	0x80, 0x32, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x46, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x41, 0x87, 0x94, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x49, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5d,
-	0x05, 0x90, 0x00, 0x00, 0x84, 0x98, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00, 0x10, 0x00, 0x00, 0x0c,
-	0x96, 0xf4, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x07, 0x96, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x2e, 0x4b, 0x19, 0x90, 0x01, 0x00, 0x05, 0x00, 0x2a, 0x0c,
-	0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x04, 0xe6, 0xb1, 0x01, 0x00,
-	0x3e, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x08,
-	0x8a, 0x30, 0x01, 0x00, 0x8f, 0x98, 0x45, 0x48, 0x61, 0x31, 0x00, 0x00,
-	0x00, 0x10, 0x00, 0x08, 0x62, 0xdd, 0x01, 0x00, 0x95, 0x98, 0x28, 0x40,
-	0x87, 0x30, 0x00, 0x00, 0x90, 0x98, 0x22, 0x48, 0x77, 0x7d, 0x00, 0x00,
-	0x04, 0x00, 0x22, 0x40, 0x27, 0x6c, 0x00, 0x00, 0x04, 0x97, 0x1d, 0x46,
-	0x87, 0xb0, 0x00, 0x00, 0x98, 0x98, 0x22, 0x5f, 0x11, 0x7c, 0x00, 0x00,
-	0x04, 0x00, 0x22, 0x15, 0x62, 0x31, 0x00, 0x00, 0x96, 0x98, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x14, 0x2f, 0x4c,
-	0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
-	0x9b, 0x98, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00,
-	0x30, 0x00, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x93, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1f, 0xb0, 0x01, 0x00,
-	0xef, 0x98, 0x00, 0x49, 0x96, 0x30, 0x01, 0x00, 0x07, 0x00, 0x00, 0x49,
-	0x06, 0xe4, 0x01, 0x00, 0x00, 0x39, 0x00, 0x03, 0x06, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0xd0,
-	0xa0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00,
-	0xa2, 0x98, 0xa0, 0x54, 0x93, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x05,
-	0x97, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x02, 0x00, 0xa2,
-	0x44, 0xc9, 0x01, 0x00, 0xab, 0x98, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x20, 0x49, 0xb3, 0x01, 0x00, 0xf5, 0x98, 0x00, 0x40,
-	0x49, 0x31, 0x01, 0x00, 0x02, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0xb5, 0x2e, 0x08, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0xb2, 0x98, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
-	0x18, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00, 0x00, 0x97, 0x2e, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
-	0xb6, 0x98, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x49, 0xb1, 0x01, 0x00, 0x40, 0x18, 0x2e, 0x05, 0x97, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0xba, 0x98, 0xa2, 0x41,
-	0x97, 0x50, 0x00, 0x00, 0x57, 0x95, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
-	0x30, 0x94, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x64, 0x00, 0x00, 0x40,
-	0xe5, 0x99, 0x01, 0x00, 0x56, 0x95, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
-	0xb8, 0x94, 0x20, 0x41, 0xe5, 0xb1, 0x01, 0x00, 0xba, 0x94, 0x20, 0x41,
-	0xe5, 0xb1, 0x01, 0x00, 0x98, 0x94, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
-	0x02, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0xc4, 0x98, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x6f, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x68, 0xb1, 0x01, 0x00,
-	0xc8, 0x98, 0x85, 0x41, 0x97, 0x40, 0x00, 0x00, 0x80, 0x04, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x39, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x37, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x35, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x33, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x41, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x3f, 0xb3, 0x01, 0x00, 0xee, 0x05, 0x00, 0x40, 0x25, 0x9b, 0x01, 0x00,
-	0x42, 0x00, 0x00, 0x40, 0x4b, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x2f, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2d, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x47, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x43, 0xb3, 0x01, 0x00, 0x60, 0x00, 0x00, 0x40, 0x2b, 0x9b, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x54, 0xef, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55,
-	0xf1, 0x93, 0x01, 0x00, 0xff, 0xff, 0x00, 0xa5, 0x3c, 0x8b, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x2c, 0x5b, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x2c,
-	0x45, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x59, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x57, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x27, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x53, 0xb3, 0x01, 0x00,
-	0xe4, 0x98, 0xa2, 0x50, 0xfd, 0x7f, 0x00, 0x00, 0xe4, 0x98, 0xa2, 0x51,
-	0xfd, 0x7f, 0x00, 0x00, 0xe5, 0x98, 0x00, 0x40, 0x1d, 0xb3, 0x00, 0x00,
-	0x50, 0x46, 0x00, 0x40, 0x1d, 0x9b, 0x01, 0x00, 0x00, 0xc0, 0x00, 0xa6,
-	0x88, 0xb3, 0x01, 0x00, 0xff, 0x3f, 0x00, 0xa6, 0x3a, 0xb3, 0x01, 0x00,
-	0x00, 0xc0, 0x00, 0x9d, 0x3b, 0x9b, 0x01, 0x00, 0xb4, 0x05, 0x00, 0x40,
-	0x23, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x4d, 0xb3, 0x01, 0x00,
-	0x08, 0x0a, 0x00, 0xa6, 0x14, 0xb3, 0x01, 0x00, 0x01, 0x01, 0x00, 0x8a,
-	0x15, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x87, 0xb3, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0xa6, 0x56, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x5e,
-	0x57, 0xb5, 0x01, 0x00, 0x18, 0x00, 0x00, 0x4b, 0x20, 0xe4, 0x01, 0x00,
-	0x06, 0x00, 0x00, 0x4b, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x43, 0x00, 0x4b,
-	0x96, 0xc8, 0x01, 0x00, 0x18, 0x00, 0x00, 0x10, 0x20, 0xdc, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4b, 0x20, 0x94, 0x01, 0x00, 0x00, 0x00, 0x80, 0x57,
-	0x21, 0x90, 0x01, 0x00, 0x00, 0x99, 0x2e, 0x0a, 0x97, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0xf6, 0x98, 0xa2, 0x41,
-	0x97, 0x50, 0x00, 0x00, 0x00, 0x03, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
-	0x00, 0xa9, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0xfa, 0x98, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
-	0x30, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00,
-	0xfe, 0x98, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xfe, 0x98, 0xa2, 0x41,
-	0x97, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x4e, 0x98, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07,
-	0x98, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x99, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x80, 0x98, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
-	0x99, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x88, 0x94, 0x01, 0x00,
-	0x08, 0x99, 0x6a, 0x40, 0x81, 0x32, 0x00, 0x00, 0x0b, 0x99, 0x22, 0x4f,
-	0x77, 0x7d, 0x00, 0x00, 0xf0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x62, 0xb1, 0x01, 0x00, 0x0c, 0x99, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x13, 0x99, 0x22, 0x4a, 0x89, 0x7c, 0x00, 0x00, 0x11, 0x99, 0x22, 0x4f,
-	0x77, 0x7d, 0x00, 0x00, 0xf0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x62, 0xb1, 0x01, 0x00, 0x11, 0x99, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5a,
-	0x1f, 0x7c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x0f, 0x98, 0xf4, 0x01, 0x00,
-	0x04, 0x00, 0xa2, 0x5f, 0x99, 0x04, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xae, 0x9f, 0x00, 0x88,
-	0x9a, 0xb0, 0x00, 0x00, 0xae, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00,
-	0xae, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00, 0xae, 0x9f, 0x00, 0x88,
-	0x9a, 0xb0, 0x00, 0x00, 0xae, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x88, 0x9a, 0xb0, 0x01, 0x00, 0xae, 0x9f, 0x41, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xb2, 0x9f, 0x22, 0x40, 0x7b, 0x6f, 0x00, 0x00,
-	0x00, 0x00, 0x19, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xae, 0x9f, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x19, 0x41, 0x7b, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xa4, 0xc4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa1,
-	0xc6, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x2f, 0xa2, 0xc8, 0xb3, 0x01, 0x00,
-	0x08, 0x14, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00, 0xa8, 0x9f, 0x00, 0x4d,
-	0x9a, 0xcc, 0x01, 0x00, 0xbb, 0x9f, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0x49, 0xc1, 0x01, 0x00, 0xb9, 0x9f, 0xa2, 0x41,
-	0x9b, 0x50, 0x00, 0x00, 0xbf, 0x9f, 0x80, 0x80, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x52, 0x49, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
-	0xfd, 0x93, 0x01, 0x00, 0xc2, 0x9f, 0x00, 0x42, 0xcd, 0x93, 0x00, 0x00,
-	0x00, 0x00, 0x51, 0x4a, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
-	0xfd, 0x93, 0x01, 0x00, 0xc2, 0x9f, 0x00, 0x43, 0xcb, 0x93, 0x00, 0x00,
-	0x00, 0x00, 0x50, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xd2, 0x9f, 0x00, 0x40,
-	0x19, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x9a, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x49, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x40, 0xf0,
-	0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0x4d, 0x80, 0xb2, 0x01, 0x00,
-	0xca, 0x9f, 0x00, 0x40, 0x19, 0x99, 0x01, 0x00, 0x00, 0x00, 0x4c, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x49, 0xd1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x9a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4d,
-	0x10, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x49, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xe3, 0x43, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe4,
-	0x45, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7b, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x48, 0x4f, 0x40, 0xb1, 0x01, 0x00, 0xd2, 0x9f, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0xcb,
-	0x81, 0xc8, 0x01, 0x00, 0x22, 0x83, 0x00, 0x40, 0xf2, 0x93, 0x00, 0x00,
-	0x55, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x40, 0x05, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x18, 0x06, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x22, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc6, 0x82, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x43, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x41, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb8, 0x80, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xed, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x23, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x27, 0x83, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xb9, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x8d, 0x98, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x79, 0x94, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x78, 0x98, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x87, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x10, 0x95, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x0a, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xb1, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x19, 0x99, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00,
-	},
-};
diff --git a/drivers/staging/slicoss/oasisdownload.h b/drivers/staging/slicoss/oasisdownload.h
deleted file mode 100644
index 6438c23..0000000
--- a/drivers/staging/slicoss/oasisdownload.h
+++ /dev/null
@@ -1,6848 +0,0 @@
-#define OASIS_UCODE_VERS_STRING	"1.2"
-#define OASIS_UCODE_VERS_DATE  	"2006/03/27 15:10:37"
-#define OASIS_UCODE_HOSTIF_ID  	3
-
-static s32 ONumSections = 0x2;
-static u32 OSectionSize[] = {
-	0x00004000, 0x00010000,
-};
-
-static u32 OSectionStart[] = {
-	0x00000000, 0x00008000,
-};
-
-static u8 OasisUCode[2][65536] =
-{
-	{
-	0x15, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x21, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x03, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
-	0x98, 0xb0, 0x01, 0x00, 0x04, 0x80, 0xa2, 0x40, 0xfd, 0x7f, 0x00, 0x00,
-	0x09, 0x00, 0xa2, 0x49, 0xdd, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0x80, 0xb2, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xd1, 0xb1, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0x80, 0xb2, 0x01, 0x00, 0x09, 0x00, 0xa2, 0x40,
-	0x75, 0x7d, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x0b, 0x00, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0x09, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x8f, 0x98, 0x18, 0x31, 0x00, 0x00,
-	0x10, 0x00, 0x00, 0x98, 0x80, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x41, 0x98,
-	0x80, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x98, 0x80, 0xe4, 0x01, 0x00, 0x0e, 0x00, 0x40, 0x98,
-	0x80, 0x94, 0x00, 0x00, 0x11, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x19, 0x00, 0x29, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x19, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
-	0x0e, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x50, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x10, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x1f, 0x00, 0x29, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x1f, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
-	0x12, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x50, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x01, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x20, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x25, 0x00, 0x29, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x25, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
-	0x14, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
-	0xdd, 0x81, 0x01, 0x00, 0x12, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x33, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2a, 0x00, 0x14, 0xbc,
-	0x80, 0x32, 0x00, 0x00, 0xfe, 0x00, 0x13, 0xbc, 0x80, 0x32, 0x00, 0x00,
-	0x54, 0x95, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0xff, 0xff, 0x00, 0x40,
-	0xe5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x40, 0x49, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xfd, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0xb3, 0x01, 0x00,
-	0x33, 0x00, 0x18, 0xee, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x89, 0xb0, 0x01, 0x00, 0x32, 0x00, 0xa2, 0x41, 0x89, 0x50, 0x00, 0x00,
-	0x99, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x30, 0x94, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x20, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfa, 0xe0, 0xb3, 0x01, 0x00, 0x39, 0x00, 0x98, 0xee,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x80, 0xb0, 0x01, 0x00,
-	0x3b, 0x00, 0x80, 0xf3, 0xde, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0xfd, 0x93, 0x01, 0x00, 0x3e, 0x00, 0x83, 0xf3, 0x80, 0x32, 0x00, 0x00,
-	0xf0, 0x00, 0x00, 0xf3, 0x80, 0x88, 0x01, 0x00, 0x01, 0x80, 0x00, 0x40,
-	0x2e, 0xdd, 0x01, 0x00, 0x00, 0x94, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x46, 0x43, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa,
-	0x24, 0xb1, 0x01, 0x00, 0x7c, 0x00, 0x18, 0xee, 0x80, 0x32, 0x00, 0x00,
-	0x45, 0x00, 0x95, 0xe8, 0x80, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0xe8,
-	0x80, 0x88, 0x01, 0x00, 0x7c, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
-	0xec, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xd6, 0xb1, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0xd6, 0xb1, 0x01, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xee, 0x8b, 0x01, 0x00,
-	0x08, 0x01, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0xff, 0x00, 0x00, 0xf0,
-	0x80, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf7, 0x81, 0x94, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xd6, 0xb1, 0x01, 0x00, 0xff, 0x00, 0x00, 0xf8,
-	0x80, 0x88, 0x01, 0x00, 0x3c, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
-	0xff, 0x00, 0x00, 0xf0, 0xd6, 0x8d, 0x01, 0x00, 0xff, 0xff, 0x00, 0xf0,
-	0xf0, 0xdb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0x81, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x81, 0x94, 0x01, 0x00, 0x3c, 0x01, 0x00, 0x40,
-	0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xd6, 0xb1, 0x01, 0x00,
-	0xff, 0x00, 0x00, 0xf8, 0x80, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
-	0x81, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x81, 0x94, 0x01, 0x00,
-	0x3c, 0x02, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xd6, 0xb1, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0xd6, 0xb1, 0x01, 0x00, 0x1e, 0x00, 0x00, 0xf0,
-	0x82, 0xf4, 0x01, 0x00, 0xff, 0x3f, 0x00, 0xf8, 0x80, 0xd8, 0x01, 0x00,
-	0x64, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x81, 0xd0, 0x01, 0x00, 0xff, 0xff, 0x00, 0x40, 0x80, 0xd8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x80, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xd8, 0xb1, 0x01, 0x00, 0x68, 0x00, 0x22, 0xfa, 0x80, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0x81, 0xe0, 0x01, 0x00, 0x01, 0x00, 0x00, 0x40,
-	0x80, 0xcc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xde, 0xb1, 0x01, 0x00,
-	0x00, 0x01, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x10, 0x00, 0x00, 0xfa,
-	0x80, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x81, 0x94, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xd6, 0xb1, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40,
-	0xd5, 0x99, 0x01, 0x00, 0x10, 0x00, 0x00, 0xfa, 0x80, 0xe4, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf6, 0x81, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xd6, 0xb1, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0xfb, 0xd6, 0xe5, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40,
-	0xd5, 0x99, 0x01, 0x00, 0x18, 0x00, 0x00, 0xfb, 0xd6, 0xe5, 0x01, 0x00,
-	0x48, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x10, 0x00, 0x00, 0xfa,
-	0xd6, 0xe5, 0x01, 0x00, 0x50, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0xfb, 0xd6, 0xe5, 0x01, 0x00, 0x03, 0x00, 0x00, 0xfb,
-	0x7a, 0x89, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xdc, 0xb1, 0x01, 0x00,
-	0x7c, 0x00, 0x00, 0x4c, 0xdd, 0x91, 0x00, 0x00, 0x7c, 0x00, 0x95, 0xe8,
-	0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x2f, 0xe9, 0xfa, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xd1, 0xb1, 0x01, 0x00, 0xff, 0x00, 0x00, 0x42,
-	0x80, 0x88, 0x01, 0x00, 0x34, 0x00, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
-	0x7c, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x85, 0x00, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x02, 0x80, 0x22, 0x40, 0x80, 0x32, 0x00, 0x00,
-	0x7c, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f,
-	0x81, 0xb0, 0x01, 0x00, 0x8e, 0x00, 0x09, 0xf9, 0x81, 0x32, 0x00, 0x00,
-	0x8c, 0x00, 0x08, 0xf9, 0x81, 0x32, 0x00, 0x00, 0x98, 0x00, 0x1f, 0xfd,
-	0xf9, 0x33, 0x00, 0x00, 0x8b, 0x00, 0x9e, 0xfd, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4a, 0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x80, 0x48,
-	0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xf7, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x49, 0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
-	0x19, 0xb1, 0x01, 0x00, 0x93, 0x00, 0x0a, 0xf9, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x40, 0xfb, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0xfd,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x07, 0x80, 0xf9, 0xf3, 0x8f, 0x01, 0x00,
-	0x00, 0x07, 0x42, 0xf9, 0xf3, 0x8f, 0x01, 0x00, 0x97, 0x00, 0xa2, 0xff,
-	0xf7, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x43, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0xa2, 0xff, 0xfb, 0xef, 0x00, 0x00, 0x00, 0x00, 0x80, 0xfc,
-	0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb0, 0x01, 0x00,
-	0x00, 0x94, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xbb, 0x00, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x46, 0xfd, 0x7f, 0x01, 0x00,
-	0x00, 0x94, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xce, 0x00, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x44, 0xfd, 0x7f, 0x01, 0x00,
-	0x00, 0x94, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0xff, 0x7f, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0xff, 0x7f, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x9a, 0x13, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x01, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x00, 0x02, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x03, 0x01, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x9a, 0x13, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x02, 0x29, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x00, 0x67, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0xfd, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0xfd, 0x83, 0x01, 0x00,
-	0xff, 0x7f, 0x00, 0x40, 0x25, 0x99, 0x01, 0x00, 0xc4, 0x00, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x44, 0x80, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0xfd, 0x93, 0x01, 0x00, 0xe2, 0x00, 0x00, 0x40,
-	0x83, 0x30, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x45, 0x80, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x46, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40,
-	0x83, 0x98, 0x01, 0x00, 0xdd, 0x00, 0x00, 0x40, 0x2b, 0x31, 0x01, 0x00,
-	0x00, 0x00, 0xa2, 0x46, 0x88, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x94, 0x8c, 0xb0, 0x01, 0x00,
-	0xff, 0xff, 0x00, 0x46, 0x80, 0x88, 0x01, 0x00, 0xa5, 0xa5, 0xa2, 0x40,
-	0x80, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8d, 0xf0, 0x01, 0x00,
-	0xc9, 0x00, 0x82, 0x41, 0x89, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xfd, 0x83, 0x01, 0x00,
-	0xd4, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x44,
-	0x80, 0xb2, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x08, 0x83, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0xa2, 0x45, 0x80, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0x44,
-	0xfd, 0x93, 0x01, 0x00, 0x00, 0x30, 0x00, 0x08, 0x83, 0x98, 0x01, 0x00,
-	0x80, 0x00, 0x00, 0x40, 0x2b, 0x99, 0x01, 0x00, 0xdb, 0x00, 0x00, 0x40,
-	0x89, 0x30, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x46, 0x80, 0xb2, 0x00, 0x00,
-	0xff, 0xff, 0x00, 0x94, 0x80, 0x88, 0x01, 0x00, 0xa5, 0xa5, 0xa2, 0x40,
-	0x80, 0x4e, 0x01, 0x00, 0x00, 0x00, 0x80, 0x43, 0x89, 0xb0, 0x01, 0x00,
-	0x03, 0x84, 0x00, 0x41, 0x2c, 0x99, 0x01, 0x00, 0xde, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x03, 0x88, 0x00, 0x41, 0x2c, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x20, 0x8d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x9f, 0x96,
-	0x80, 0xb2, 0x00, 0x00, 0xdf, 0x00, 0xa2, 0x41, 0x8d, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xff, 0x7f, 0x00, 0x40,
-	0x25, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x89, 0xe0, 0x01, 0x00,
-	0xdd, 0x00, 0x00, 0x44, 0x82, 0x14, 0x01, 0x00, 0x00, 0x00, 0x90, 0x94,
-	0x8a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xf0, 0xb1, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x45, 0x88, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x89, 0xd0, 0x01, 0x00, 0xdd, 0x00, 0x00, 0x44, 0x2b, 0x41, 0x01, 0x00,
-	0xec, 0x00, 0x08, 0x41, 0x80, 0x32, 0x00, 0x00, 0xed, 0x00, 0x00, 0x94,
-	0x24, 0xb1, 0x00, 0x00, 0x10, 0x00, 0x00, 0x94, 0x24, 0xf5, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x94, 0xf0, 0xb1, 0x01, 0x00, 0xf2, 0x00, 0xa0, 0x44,
-	0x89, 0x50, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x44, 0x2b, 0x41, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x94, 0xf0, 0xb1, 0x01, 0x00, 0xef, 0x00, 0x20, 0x44,
-	0x89, 0x50, 0x00, 0x00, 0x10, 0x00, 0x00, 0x45, 0x88, 0xf4, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfa, 0x8a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xa3, 0x42,
-	0x89, 0xd0, 0x00, 0x00, 0xf7, 0x00, 0xa0, 0xfa, 0x8a, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x8b, 0xc0, 0x01, 0x00, 0xf5, 0x00, 0xa3, 0x42,
-	0x89, 0x50, 0x00, 0x00, 0xff, 0xff, 0x00, 0x45, 0x88, 0x88, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x45, 0x8a, 0xf4, 0x01, 0x00, 0xfc, 0x00, 0x90, 0x44,
-	0x8a, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x8b, 0xc0, 0x01, 0x00,
-	0xff, 0xff, 0x00, 0x45, 0x8a, 0xa8, 0x01, 0x00, 0x00, 0x00, 0x80, 0x50,
-	0x8b, 0xe0, 0x01, 0x00, 0xff, 0x7f, 0x00, 0x40, 0x25, 0x99, 0x01, 0x00,
-	0x7c, 0x00, 0x00, 0x40, 0x2b, 0x99, 0x01, 0x00, 0x00, 0x30, 0x00, 0x40,
-	0x83, 0x98, 0x01, 0x00, 0xdd, 0x00, 0x00, 0x08, 0x83, 0x14, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x94, 0x2a, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40,
-	0xf9, 0x9b, 0x01, 0x00, 0xdd, 0x00, 0x00, 0xfc, 0x19, 0x31, 0x01, 0x00,
-	0x00, 0x00, 0x40, 0x94, 0x80, 0xb2, 0x01, 0x00, 0xdd, 0x00, 0x00, 0x44,
-	0x2b, 0x41, 0x01, 0x00, 0x00, 0x00, 0x41, 0x94, 0x80, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0xf9, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x2b, 0xc1, 0x01, 0x00, 0x04, 0x01, 0x9f, 0x94, 0x80, 0x32, 0x00, 0x00,
-	0x02, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x10, 0x01, 0x00, 0x51,
-	0x93, 0xb0, 0x00, 0x00, 0x10, 0x01, 0x00, 0x4d, 0x93, 0xb0, 0x00, 0x00,
-	0x10, 0x01, 0x00, 0x49, 0x93, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x93, 0xb0, 0x01, 0x00, 0x10, 0x01, 0xa2, 0x41, 0x93, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x11, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x12, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x13, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x14, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x15, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x16, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x17, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x18, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x19, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x1b, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1d, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x1e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x70, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x71, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x72, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x73, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x74, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x75, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x76, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x77, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x78, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x79, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x7a, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x7b, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x7c, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x7d, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x7e, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x04, 0x00, 0x40,
-	0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xa1, 0xd1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x1b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x19, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x15, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x0d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0b, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x09, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x07, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x01, 0xb0, 0x01, 0x00, 0x3b, 0x01, 0x20, 0x48, 0xa1, 0x51, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x47, 0x01, 0x22, 0x4b,
-	0x74, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x60, 0x00, 0x00, 0x4b, 0x60, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb1,
-	0x7e, 0xb1, 0x01, 0x00, 0x48, 0x01, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x45, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x05, 0x00, 0x80, 0x40,
-	0x97, 0x98, 0x01, 0x00, 0x18, 0x00, 0x00, 0xaa, 0x96, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x43, 0x97, 0xf0, 0x01, 0x00, 0x07, 0x00, 0x00, 0xaa,
-	0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x58, 0x07, 0x90, 0x01, 0x00, 0xd8, 0x9f, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xa5, 0xb3, 0x01, 0x00,
-	0xd8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x07, 0x90, 0x01, 0x00,
-	0xd8, 0x9f, 0x00, 0x40, 0xbf, 0xb3, 0x00, 0x00, 0x5a, 0x01, 0x22, 0xcc,
-	0x85, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x07, 0x90, 0x01, 0x00,
-	0xd8, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x49, 0xb1, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00,
-	0xd0, 0x14, 0x00, 0x40, 0xa1, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
-	0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd0, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xe1, 0xb1, 0x01, 0x00,
-	0x07, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0x20,
-	0x62, 0xdd, 0x01, 0x00, 0x63, 0x01, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xcc, 0x85, 0x93, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xd0, 0x14, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfa, 0xba, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa,
-	0xa4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xbc, 0xb3, 0x01, 0x00,
-	0x00, 0x14, 0x2f, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe7,
-	0xa7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xa9, 0xb3, 0x01, 0x00,
-	0xff, 0x00, 0x00, 0xdd, 0x81, 0x88, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40,
-	0x80, 0xf4, 0x01, 0x00, 0x73, 0x01, 0x00, 0x40, 0x80, 0xc8, 0x01, 0x00,
-	0x86, 0x01, 0x00, 0xdd, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x10, 0xb1, 0x00, 0x00, 0x87, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x88, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x89, 0x01, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x8a, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x8b, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x8d, 0x01, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x8f, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb6, 0x01, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xc4, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc5, 0x01, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x82, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x83, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x28, 0x00, 0xb8, 0x02, 0x00, 0x40,
-	0x81, 0xb2, 0x28, 0x00, 0xd4, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x28, 0x00,
-	0xd5, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x28, 0x00, 0xd6, 0x9f, 0x00, 0x40,
-	0x81, 0xb2, 0x28, 0x00, 0xd7, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x28, 0x00,
-	0x72, 0x01, 0x00, 0x41, 0x81, 0xc0, 0x28, 0x00, 0x55, 0x01, 0x51, 0x49,
-	0xfd, 0x93, 0x28, 0x00, 0x55, 0x01, 0x52, 0x4a, 0xfd, 0x93, 0x2a, 0x00,
-	0x55, 0x01, 0x55, 0x49, 0xfd, 0x83, 0x2a, 0x00, 0x55, 0x01, 0x56, 0x4a,
-	0xfd, 0x83, 0x2a, 0x00, 0x50, 0x01, 0x91, 0x81, 0x80, 0x30, 0x2a, 0x00,
-	0x55, 0x01, 0x45, 0x40, 0x81, 0xb2, 0x2a, 0x00, 0x50, 0x01, 0x91, 0x82,
-	0x80, 0x30, 0x2a, 0x00, 0x55, 0x01, 0x46, 0x40, 0x81, 0xb2, 0x2a, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x89, 0xb0, 0x2b, 0x00, 0x00, 0x00, 0x2f, 0x40,
-	0x81, 0xb0, 0x01, 0x00, 0x00, 0x14, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00,
-	0xb3, 0x01, 0x22, 0xde, 0xe1, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00,
-	0x92, 0x01, 0xa2, 0x44, 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0x49, 0xd1, 0x01, 0x00, 0x9a, 0x01, 0x22, 0x40, 0xe1, 0x6d, 0x00, 0x00,
-	0x96, 0x01, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x50, 0x01, 0x00, 0x41,
-	0xbf, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xbf, 0xb3, 0x01, 0x00,
-	0x50, 0x01, 0xa0, 0x0f, 0xbd, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde,
-	0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x49, 0xc1, 0x01, 0x00,
-	0xb5, 0x01, 0x00, 0x40, 0x19, 0x99, 0x01, 0x00, 0x00, 0x00, 0x42, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff, 0x85, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xde, 0x19, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x42, 0xff,
-	0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff, 0xe1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x2f, 0xff,
-	0xe1, 0xb1, 0x01, 0x00, 0x08, 0x14, 0x00, 0xa4, 0x80, 0xcc, 0x01, 0x00,
-	0xaa, 0x01, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x85, 0xc0, 0x01, 0x00, 0xa8, 0x01, 0xa2, 0x4c, 0x81, 0x50, 0x00, 0x00,
-	0xb4, 0x01, 0x22, 0xd2, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x01, 0x22, 0x41,
-	0xa5, 0x6f, 0x00, 0x00, 0x50, 0x01, 0xa2, 0xe0, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xd2, 0xc1, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
-	0x89, 0x90, 0x01, 0x00, 0x00, 0x00, 0x40, 0x42, 0x80, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x41, 0x43, 0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x88, 0x94, 0x01, 0x00, 0x55, 0x01, 0x00, 0x44, 0xe0, 0xb1, 0x00, 0x00,
-	0xb1, 0x01, 0x00, 0x48, 0x49, 0xc1, 0x00, 0x00, 0xaf, 0x01, 0x00, 0x5b,
-	0x89, 0x90, 0x00, 0x00, 0xa8, 0x9f, 0x00, 0xa0, 0x9e, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x14, 0x00, 0x40,
-	0x49, 0x99, 0x01, 0x00, 0x00, 0x00, 0x23, 0x40, 0x81, 0xb0, 0x01, 0x00,
-	0xbe, 0x01, 0x22, 0xde, 0xe1, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00,
-	0xb9, 0x01, 0xa2, 0x44, 0x81, 0x6c, 0x00, 0x00, 0x50, 0x01, 0x00, 0x43,
-	0xbf, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x40, 0xf8, 0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0xf0,
-	0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x55, 0x01, 0x00, 0x40,
-	0xe1, 0xb1, 0x00, 0x00, 0xc6, 0x01, 0x00, 0x40, 0x91, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x91, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x2e, 0x40,
-	0x49, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40, 0xa3, 0x9b, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0xdd, 0x81, 0xf4, 0x01, 0x00, 0xcb, 0x01, 0x00, 0x40,
-	0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0xb1, 0x00, 0x00,
-	0xd1, 0x01, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00, 0x53, 0x01, 0x00, 0xde,
-	0xa1, 0xb3, 0x00, 0x00, 0xe3, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xe5, 0x01, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00, 0xeb, 0x01, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x52, 0x01, 0x00, 0xdf, 0xe1, 0xb1, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xd0, 0xba, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde,
-	0xa1, 0xb1, 0x01, 0x00, 0x02, 0x00, 0x00, 0xd2, 0xa5, 0xe7, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd2, 0xc1, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0xf0, 0xb1, 0x01, 0x00, 0xdb, 0x01, 0x22, 0x44, 0xc1, 0x53, 0x00, 0x00,
-	0xda, 0x01, 0x84, 0x41, 0x81, 0x40, 0x00, 0x00, 0xde, 0x01, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x45, 0xb1, 0x01, 0x00,
-	0xd5, 0x01, 0x00, 0x41, 0xa1, 0xc1, 0x00, 0x00, 0xda, 0x02, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x55, 0x01, 0x00, 0xdd, 0xa1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x81, 0xb0, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40, 0xa5, 0x9b, 0x01, 0x00,
-	0xda, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x40, 0x00, 0x00, 0xd3,
-	0xa7, 0xcb, 0x01, 0x00, 0xf8, 0x02, 0x00, 0xe0, 0xa5, 0xb3, 0x00, 0x00,
-	0x03, 0x00, 0x00, 0x40, 0xa3, 0x9b, 0x01, 0x00, 0x53, 0x01, 0x00, 0xde,
-	0xa1, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xbf, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xde, 0x81, 0x90, 0x01, 0x00, 0x50, 0x01, 0xa2, 0xba,
-	0x80, 0x04, 0x00, 0x00, 0x60, 0x00, 0x00, 0xde, 0x61, 0x99, 0x01, 0x00,
-	0xe8, 0x01, 0xa8, 0xb1, 0x80, 0x30, 0x00, 0x00, 0x52, 0x01, 0x00, 0x40,
-	0xe0, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xba, 0xb3, 0x01, 0x00,
-	0x6b, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x60, 0x02, 0x00, 0x4d,
-	0x83, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xe1, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0xe3, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0xe5, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xe9, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0xeb, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0xf5, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf7, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0xf9, 0xb3, 0x01, 0x00, 0xf9, 0x01, 0x22, 0x40,
-	0x8f, 0x6f, 0x00, 0x00, 0x78, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
-	0x60, 0x02, 0x00, 0xc7, 0x83, 0x30, 0x01, 0x00, 0x80, 0x02, 0x00, 0x40,
-	0x81, 0x98, 0x01, 0x00, 0x60, 0x02, 0x00, 0x42, 0x83, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xe8, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe9,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xea, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xeb, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x85,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xec, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xed, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb2,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa9, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xac, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb8, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xb9, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xba,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xf0, 0xb1, 0x01, 0x00,
-	0x0c, 0x02, 0xb8, 0x40, 0x81, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x81, 0x90, 0x01, 0x00, 0x0e, 0x02, 0xb9, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x81, 0x90, 0x01, 0x00, 0x10, 0x02, 0xba, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x81, 0x90, 0x01, 0x00,
-	0x12, 0x02, 0xbb, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x81, 0x90, 0x01, 0x00, 0x14, 0x02, 0xbc, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x81, 0x90, 0x01, 0x00, 0x16, 0x02, 0xbd, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x81, 0x90, 0x01, 0x00,
-	0x18, 0x02, 0xbe, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0x81, 0x90, 0x01, 0x00, 0x1a, 0x02, 0xbf, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x81, 0x90, 0x01, 0x00, 0x1c, 0x02, 0xc8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x81, 0x90, 0x01, 0x00,
-	0x1e, 0x02, 0xc9, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
-	0x81, 0x90, 0x01, 0x00, 0x20, 0x02, 0xca, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4a, 0x81, 0x90, 0x01, 0x00, 0x22, 0x02, 0xcb, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x81, 0x90, 0x01, 0x00,
-	0x24, 0x02, 0xcc, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0x81, 0x90, 0x01, 0x00, 0x26, 0x02, 0xcd, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4d, 0x81, 0x90, 0x01, 0x00, 0x28, 0x02, 0xce, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x81, 0x90, 0x01, 0x00,
-	0x2a, 0x02, 0xcf, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f,
-	0x81, 0x90, 0x01, 0x00, 0x2c, 0x02, 0xf0, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x81, 0x90, 0x01, 0x00, 0x2e, 0x02, 0xf1, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x81, 0x90, 0x01, 0x00,
-	0x30, 0x02, 0xf2, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52,
-	0x81, 0x90, 0x01, 0x00, 0x32, 0x02, 0xf3, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x53, 0x81, 0x90, 0x01, 0x00, 0x34, 0x02, 0xf4, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x81, 0x90, 0x01, 0x00,
-	0x36, 0x02, 0xf5, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
-	0x81, 0x90, 0x01, 0x00, 0x38, 0x02, 0xf6, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x56, 0x81, 0x90, 0x01, 0x00, 0x3a, 0x02, 0xf7, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x81, 0x90, 0x01, 0x00,
-	0x3c, 0x02, 0xf8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58,
-	0x81, 0x90, 0x01, 0x00, 0x3e, 0x02, 0xf9, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x59, 0x81, 0x90, 0x01, 0x00, 0x40, 0x02, 0xfa, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x81, 0x90, 0x01, 0x00,
-	0x42, 0x02, 0xfb, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b,
-	0x81, 0x90, 0x01, 0x00, 0x44, 0x02, 0xfc, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5c, 0x81, 0x90, 0x01, 0x00, 0x46, 0x02, 0xfd, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x81, 0x90, 0x01, 0x00,
-	0x48, 0x02, 0xfe, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e,
-	0x81, 0x90, 0x01, 0x00, 0x4a, 0x02, 0xff, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x81, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf0, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40, 0xa5, 0x9b, 0x01, 0x00,
-	0xd8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xd0, 0x14, 0x2e, 0x06, 0xa5, 0xb3, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0xd3, 0xa7, 0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf2, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf4,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf5, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfa, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xeb, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xee,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xef, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf3, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xf1, 0xb1, 0x01, 0x00,
-	0xdb, 0x01, 0x00, 0xc7, 0xe1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x66, 0x02, 0x00, 0x48, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x51, 0x40, 0x1a, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x4d, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x63, 0x02, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x5f, 0x02, 0x49, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x52, 0x40, 0x1c, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x4e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x68, 0x02, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
-	0x5f, 0x02, 0x4a, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
-	0x9e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0xd8, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xa1, 0xd0, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2,
-	0xd2, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xd4, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd0, 0xd6, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd1,
-	0xdc, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2, 0xde, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x88, 0xda, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd4,
-	0x8e, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xe6, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xac, 0xec, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x99,
-	0xfa, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xe0, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd5, 0xe2, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5,
-	0xe4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xe8, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd5, 0xea, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5,
-	0xf4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xf6, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd5, 0xf8, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc7,
-	0xa9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x40, 0xb1, 0x01, 0x00,
-	0x84, 0x02, 0x00, 0x40, 0x91, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x91, 0xb0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xa3, 0x9b, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0xdd, 0x81, 0xf4, 0x01, 0x00, 0x88, 0x02, 0x00, 0x40,
-	0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0xb1, 0x00, 0x00,
-	0x8d, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x98, 0x02, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x98, 0x02, 0x00, 0x46, 0xa3, 0xb3, 0x00, 0x00,
-	0x9b, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xa1, 0x02, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x8f, 0x02, 0x23, 0x50, 0xa5, 0x6f, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0xa5, 0xb3, 0x01, 0x00, 0xe8, 0x02, 0x00, 0x42,
-	0xa5, 0x63, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xd0, 0x14, 0x2d, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
-	0xba, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde, 0xa1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x00, 0xb0, 0x01, 0x00, 0x97, 0x02, 0x22, 0x44,
-	0xa5, 0x53, 0x00, 0x00, 0x94, 0x02, 0x00, 0x41, 0xa1, 0xc1, 0x00, 0x00,
-	0x55, 0x01, 0x00, 0xdd, 0xa1, 0xb1, 0x00, 0x00, 0xe8, 0x02, 0x00, 0xde,
-	0xa1, 0x33, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0xbf, 0xb3, 0x01, 0x00, 0x50, 0x01, 0xa2, 0xd2, 0x77, 0x7d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xd2, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde,
-	0x63, 0xb1, 0x01, 0x00, 0x9e, 0x02, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xe8, 0x02, 0x00, 0x54,
-	0xa5, 0x33, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xd0, 0x14, 0x2d, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0xd0, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xd2, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0xd4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0xd6, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x08, 0xb1, 0x01, 0x00,
-	0xac, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x60, 0x02, 0x00, 0x46,
-	0x83, 0x30, 0x01, 0x00, 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xa0, 0x9e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe8,
-	0x43, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe9, 0x45, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xea, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xeb,
-	0xa1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x40, 0xb1, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xd0, 0x14, 0x2e, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40,
-	0xa3, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xc1, 0xb3, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0xdd, 0x81, 0xf4, 0x01, 0x00, 0xbd, 0x02, 0x00, 0x40,
-	0x10, 0xc9, 0x00, 0x00, 0xc3, 0x02, 0x00, 0x05, 0x81, 0xb0, 0x00, 0x00,
-	0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xcb, 0x02, 0x00, 0x05,
-	0x81, 0xb0, 0x00, 0x00, 0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xd0, 0x02, 0x00, 0x44, 0xa5, 0xb3, 0x00, 0x00, 0xd2, 0x02, 0x00, 0x44,
-	0xa5, 0xb3, 0x00, 0x00, 0x02, 0x00, 0x00, 0x40, 0xa4, 0xe7, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xe0, 0x81, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0xc1,
-	0xf0, 0x89, 0x01, 0x00, 0xc8, 0x02, 0x22, 0x41, 0x81, 0x50, 0x00, 0x00,
-	0xc4, 0x02, 0x00, 0x41, 0xc1, 0xc3, 0x00, 0x00, 0xda, 0x02, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x02, 0x00, 0x00, 0x40,
-	0xa4, 0xe7, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x91, 0xb1, 0x01, 0x00,
-	0xff, 0xff, 0x00, 0xc9, 0xf0, 0x89, 0x01, 0x00, 0xc8, 0x02, 0x22, 0x41,
-	0x81, 0x50, 0x00, 0x00, 0xcc, 0x02, 0x00, 0x41, 0xc1, 0xc3, 0x00, 0x00,
-	0xff, 0xff, 0x00, 0xde, 0x85, 0x89, 0x01, 0x00, 0xc8, 0x02, 0x00, 0xc2,
-	0xe0, 0xb1, 0x00, 0x00, 0xff, 0xff, 0x00, 0xde, 0x95, 0x89, 0x01, 0x00,
-	0xc8, 0x02, 0x00, 0xca, 0xe0, 0xb1, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0xa7, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd8, 0xa9, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x49, 0xb1, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x20, 0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd4, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
-	0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd1, 0x61, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x20, 0x62, 0xdd, 0x01, 0x00, 0xe2, 0x02, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0xcc, 0x85, 0x93, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xe7, 0xa7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd8,
-	0xa9, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00,
-	0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
-	0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd0, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3,
-	0xf1, 0xb1, 0x01, 0x00, 0xe1, 0x02, 0x00, 0xd4, 0xe1, 0xb1, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xcc,
-	0x85, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x81, 0xb0, 0x01, 0x00,
-	0xfa, 0x02, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0xf9, 0x02, 0xa2, 0xf2,
-	0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0xcc, 0x85, 0x83, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xb5, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x41,
-	0x99, 0xb3, 0x01, 0x00, 0x0a, 0x03, 0x22, 0x44, 0x81, 0x6c, 0x00, 0x00,
-	0x12, 0x03, 0x22, 0x48, 0x81, 0x6c, 0x00, 0x00, 0x0c, 0x03, 0x22, 0x4c,
-	0x81, 0x6c, 0x00, 0x00, 0x16, 0x03, 0x22, 0x50, 0x81, 0x6c, 0x00, 0x00,
-	0x17, 0x03, 0x22, 0x54, 0x81, 0x6c, 0x00, 0x00, 0x19, 0x03, 0x22, 0x58,
-	0x81, 0x6c, 0x00, 0x00, 0x1e, 0x03, 0x22, 0x5c, 0x81, 0x6c, 0x00, 0x00,
-	0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc,
-	0x09, 0xb0, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0xca, 0x01, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0xf3, 0x83, 0x01, 0x00, 0x10, 0x03, 0xa2, 0x42, 0x05, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x05, 0xb0, 0x01, 0x00, 0xdd, 0x9f, 0x22, 0xca,
-	0x07, 0x14, 0x00, 0x00, 0xdd, 0x9f, 0x00, 0x45, 0xf3, 0x93, 0x00, 0x00,
-	0xdd, 0x9f, 0x20, 0x43, 0x95, 0x6f, 0x00, 0x00, 0xdd, 0x9f, 0x80, 0xca,
-	0x05, 0x30, 0x00, 0x00, 0xdd, 0x9f, 0x22, 0x01, 0x80, 0x30, 0x00, 0x00,
-	0xdd, 0x9f, 0x00, 0xcb, 0xdb, 0x91, 0x00, 0x00, 0x57, 0x01, 0x00, 0xbc,
-	0xab, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0xb1, 0xb3, 0x01, 0x00,
-	0xdd, 0x9f, 0x00, 0xca, 0xcf, 0xb3, 0x00, 0x00, 0xff, 0x00, 0x00, 0xca,
-	0x81, 0x88, 0x01, 0x00, 0xdd, 0x9f, 0xa2, 0x40, 0x74, 0x7d, 0x00, 0x00,
-	0x60, 0x00, 0x20, 0x40, 0x60, 0x99, 0x01, 0x00, 0x1b, 0x03, 0xa8, 0xb1,
-	0x82, 0x30, 0x00, 0x00, 0x1a, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xdd, 0x9f, 0x00, 0xca, 0x79, 0xb3, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x81, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0xcb, 0x83, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x22, 0x03, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x2d, 0x03, 0x91, 0x82, 0x82, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x8a, 0x80, 0xb0, 0x01, 0x00, 0xae, 0x9f, 0x00, 0x40,
-	0x80, 0xce, 0x01, 0x00, 0x2b, 0x03, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x2d, 0x03, 0x56, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb5, 0x03, 0x00, 0x40,
-	0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00,
-	0xb5, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x52,
-	0x07, 0x90, 0x01, 0x00, 0xd8, 0x9f, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4e, 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0xcd, 0x83, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x32, 0x03, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x00, 0x00, 0x46, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x3d, 0x03, 0x91, 0x81, 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
-	0x80, 0xb0, 0x01, 0x00, 0xae, 0x9f, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
-	0x3b, 0x03, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x3d, 0x03, 0x55, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xb5, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x52, 0x07, 0x90, 0x01, 0x00, 0xb5, 0x03, 0x00, 0x40,
-	0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00,
-	0xd8, 0x9f, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00, 0xb0, 0x03, 0x00, 0x40,
-	0xa1, 0x99, 0x01, 0x00, 0xc4, 0x14, 0x2f, 0x40, 0x99, 0xb3, 0x01, 0x00,
-	0x57, 0x01, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x30, 0x94, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x00, 0x90, 0x00, 0xf8,
-	0x80, 0x98, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf2, 0x88, 0xe4, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x40, 0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0x23, 0x91, 0x01, 0x00, 0x4d, 0x03, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
-	0x30, 0x00, 0x00, 0x40, 0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0x23, 0x91, 0x01, 0x00, 0x50, 0x03, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
-	0x40, 0x00, 0x00, 0x40, 0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0x23, 0x91, 0x01, 0x00, 0x53, 0x03, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x23, 0x91, 0x01, 0x00, 0x55, 0x03, 0x1f, 0x91,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x08, 0x80, 0x40, 0x20, 0x99, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x48, 0x84, 0x84, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
-	0x8f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x62, 0xb1, 0x01, 0x00,
-	0x5a, 0x03, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x08, 0x00, 0x47,
-	0x8e, 0xc8, 0x01, 0x00, 0x58, 0x03, 0x00, 0x5c, 0x8f, 0x80, 0x00, 0x00,
-	0xe0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x58, 0x15, 0x2d, 0x40,
-	0x8d, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x2d, 0xf0, 0x88, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfa, 0x8a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x81, 0xb0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x45, 0x82, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x8b, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
-	0x83, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x82, 0x94, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x41, 0x60, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x8d, 0xc0, 0x01, 0x00, 0x74, 0x03, 0x22, 0x5f, 0x8d, 0x6c, 0x00, 0x00,
-	0x65, 0x03, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x63, 0x03, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40, 0x85, 0x98, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x86, 0xb0, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x43, 0x86, 0xd8, 0x01, 0x00,
-	0x00, 0x00, 0xa6, 0x41, 0x85, 0x50, 0x01, 0x00, 0x70, 0x03, 0x00, 0x41,
-	0x83, 0xe0, 0x00, 0x00, 0x6e, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0x85, 0xe0, 0x01, 0x00, 0xd0, 0x14, 0x2f, 0x46,
-	0x84, 0x94, 0x01, 0x00, 0x20, 0x00, 0x00, 0x42, 0x60, 0x99, 0x01, 0x00,
-	0xc0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x07, 0x00, 0x00, 0x45, 0x80, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x8b, 0xf0, 0x01, 0x00, 0x00, 0x04, 0x00, 0x40,
-	0x83, 0x98, 0x01, 0x00, 0x85, 0x03, 0xa0, 0x41, 0x81, 0x50, 0x00, 0x00,
-	0x83, 0x03, 0x00, 0x41, 0x82, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41,
-	0x8e, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x49, 0xb1, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
-	0x00, 0x39, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0x8b, 0x03, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x44,
-	0x82, 0xf4, 0x01, 0x00, 0x1a, 0x15, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00,
-	0x70, 0x15, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x08, 0x00, 0x40,
-	0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x39, 0x00, 0x40, 0xe1, 0x99, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0x70, 0x15, 0x00, 0x43, 0x62, 0x99, 0x01, 0x00,
-	0x95, 0x03, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x97, 0x03, 0x22, 0x5a,
-	0x73, 0x7d, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x98, 0x03, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0x00, 0x08, 0x00, 0x42,
-	0x84, 0xc8, 0x01, 0x00, 0x90, 0x03, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x58, 0x15, 0x2d, 0x40,
-	0x8d, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x2d, 0xf0, 0x88, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x8f, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6,
-	0x90, 0xb0, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x48, 0x90, 0x98, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x93, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa,
-	0x8a, 0xb0, 0x01, 0x00, 0x80, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x02, 0x00, 0x00, 0xa6, 0x80, 0xb0, 0x01, 0x00, 0xac, 0x03, 0x22, 0x40,
-	0x82, 0x6c, 0x00, 0x00, 0xb0, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x58, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x8d, 0xc0, 0x01, 0x00, 0xb5, 0x03, 0x22, 0x5f, 0x8d, 0x6c, 0x00, 0x00,
-	0xa7, 0x03, 0xa2, 0x41, 0x93, 0x50, 0x00, 0x00, 0xa5, 0x03, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xff, 0x07, 0x00, 0x47, 0x84, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0xa6, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xed, 0x9f, 0x00, 0x47,
-	0x80, 0x30, 0x01, 0x00, 0x00, 0x02, 0x00, 0x47, 0x8e, 0xc8, 0x01, 0x00,
-	0xb0, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x50, 0xb3, 0x01, 0x00, 0xbb, 0x03, 0x20, 0x18, 0x89, 0x6c, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0xa6, 0x84, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
-	0x86, 0xb0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40, 0x55, 0x9b, 0x01, 0x00,
-	0xbe, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0xa6,
-	0x84, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00,
-	0x00, 0x10, 0x00, 0x40, 0x55, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x50, 0xd3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x4f, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x4e, 0xd3, 0x01, 0x00, 0x6e, 0x03, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x82, 0x03, 0x00, 0x42, 0x80, 0x30, 0x01, 0x00,
-	0xb0, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc7, 0x03, 0x22, 0xa7,
-	0x8f, 0x6c, 0x00, 0x00, 0x5a, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xc4, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0xc8, 0x14, 0x2e, 0xbb, 0x85, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xee, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xa0, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0xa5, 0xb3, 0x01, 0x00, 0xe1, 0x9f, 0x00, 0xca,
-	0xa7, 0x33, 0x01, 0x00, 0xe0, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xd6, 0x03, 0x22, 0x42,
-	0x75, 0x6f, 0x00, 0x00, 0xd8, 0x03, 0x22, 0x41, 0x75, 0x6f, 0x00, 0x00,
-	0xda, 0x03, 0x1e, 0xca, 0x81, 0x32, 0x00, 0x00, 0xdc, 0x03, 0x1f, 0xca,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xc9, 0xb1, 0x01, 0x00,
-	0xdd, 0x9f, 0x00, 0x42, 0x75, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca,
-	0xcd, 0xb1, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0x41, 0x75, 0xb3, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xca, 0xcf, 0xb1, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0x40,
-	0x75, 0xb3, 0x00, 0x00, 0x00, 0x81, 0x00, 0xa6, 0xc6, 0xb1, 0x01, 0x00,
-	0xdd, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0xa6,
-	0xc6, 0xb1, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0x40, 0x75, 0xb3, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x45, 0x01, 0x00, 0x4d, 0x93, 0x30, 0x01, 0x00,
-	0x45, 0x01, 0x00, 0x4e, 0x93, 0x30, 0x01, 0x00, 0x45, 0x01, 0x00, 0x4c,
-	0x93, 0x30, 0x01, 0x00, 0xec, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xdd, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x54, 0x95, 0x00, 0x40,
-	0x45, 0x99, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0xca, 0xe5, 0xb1, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xcc, 0x14, 0x2e, 0x40, 0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2,
-	0xa0, 0xb3, 0x01, 0x00, 0x15, 0x04, 0x00, 0x43, 0xb2, 0x33, 0x01, 0x00,
-	0x00, 0x00, 0x68, 0xda, 0x89, 0xb0, 0x01, 0x00, 0x7c, 0x00, 0x00, 0x40,
-	0x8b, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x89, 0xf0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x89, 0xd0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x44,
-	0x88, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x87, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0xa5, 0xb3, 0x01, 0x00, 0x15, 0x04, 0x00, 0x43,
-	0xb2, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x87, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0xa5, 0xc3, 0x01, 0x00, 0x0b, 0x04, 0x22, 0x44, 0x89, 0x50, 0x00, 0x00,
-	0x0b, 0x04, 0x22, 0x44, 0x8b, 0x50, 0x00, 0x00, 0xfa, 0x03, 0xa2, 0x50,
-	0xa5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xa5, 0xe3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xca, 0xa7, 0xb3, 0x01, 0x00, 0xe1, 0x9f, 0x00, 0xbb,
-	0x85, 0x30, 0x01, 0x00, 0xcc, 0x14, 0x2e, 0xd2, 0x95, 0xc3, 0x01, 0x00,
-	0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
-	0x42, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x81, 0xb0, 0x01, 0x00,
-	0x08, 0x04, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x07, 0x04, 0xa2, 0xf2,
-	0x80, 0x30, 0x00, 0x00, 0xfa, 0x03, 0x00, 0x40, 0xa5, 0xb3, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0xa5, 0xe3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
-	0xa7, 0xb3, 0x01, 0x00, 0xe1, 0x9f, 0x00, 0xbb, 0x85, 0x30, 0x01, 0x00,
-	0xe0, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd9, 0x2b, 0xb1, 0x01, 0x00,
-	0x00, 0x10, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00, 0xdb, 0x00, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xff, 0xff, 0x00, 0x94, 0xb4, 0x8b, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd9,
-	0x2b, 0xb1, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
-	0xdd, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0x94,
-	0xb4, 0xb3, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xd9, 0x2b, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
-	0x27, 0xb1, 0x01, 0x00, 0x06, 0xc0, 0x00, 0x40, 0x2d, 0x99, 0x01, 0x00,
-	0xde, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40,
-	0x83, 0x98, 0x01, 0x00, 0x02, 0xc4, 0x00, 0x41, 0x2c, 0x99, 0x01, 0x00,
-	0xde, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x40, 0x00, 0x40,
-	0x83, 0x98, 0x01, 0x00, 0x05, 0x82, 0x00, 0x41, 0x2c, 0x99, 0x01, 0x00,
-	0xde, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2d, 0x04, 0x80, 0x94,
-	0x80, 0x32, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x28, 0x04, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x80, 0x00, 0x40,
-	0x2d, 0x99, 0x01, 0x00, 0xde, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x31, 0x04, 0x00, 0x12,
-	0x10, 0xc9, 0x00, 0x00, 0x00, 0x48, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0xc0, 0x49, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x4b, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x40, 0x4d, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0x4f, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x50, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x80, 0x52, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x40, 0x54, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x56, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0xc0, 0x57, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x80, 0x59, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x40, 0x5b, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0x5d, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0xc0, 0x5e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x60, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x40, 0x62, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0x64, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x65, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x80, 0x67, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x40, 0x69, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x6b, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0xc0, 0x6c, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x80, 0x6e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x40, 0x70, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0x72, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0xc0, 0x73, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x75, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x40, 0x77, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0x79, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x7a, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x80, 0x7c, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x40, 0x7e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x59, 0x04, 0x00, 0x12, 0x10, 0xc9, 0x00, 0x00,
-	0x00, 0x80, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x82, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0x84, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0x86, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x88, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0x8a, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0x8c, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x8e, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0x90, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0x92, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x94, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0x96, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0x98, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x9a, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0x9c, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0x9e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xa0, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0xa2, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0xa4, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xa6, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0xa8, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0xaa, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xac, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0xae, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0xb0, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xb2, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0xb4, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0xb6, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xb8, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x00, 0xba, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
-	0x00, 0xbc, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xbe, 0x80, 0x40,
-	0x0b, 0x98, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x87, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x80, 0xb1, 0x01, 0x00,
-	0x01, 0x00, 0x00, 0xa6, 0x82, 0xb1, 0x01, 0x00, 0x82, 0x04, 0x85, 0x41,
-	0x97, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x97, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x90, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6, 0x92, 0xb1, 0x01, 0x00,
-	0x87, 0x04, 0x85, 0x41, 0x97, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x90, 0x04, 0x60, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0xb1, 0x01, 0x00,
-	0xff, 0xff, 0xf0, 0x4b, 0x82, 0x89, 0x01, 0x00, 0x93, 0x04, 0x60, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x80, 0xb1, 0x01, 0x00,
-	0x01, 0x00, 0xf0, 0xa6, 0x82, 0xb1, 0x01, 0x00, 0x96, 0x04, 0x60, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4b, 0x84, 0x89, 0x01, 0x00,
-	0x00, 0x00, 0xf0, 0xc2, 0x24, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
-	0x90, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x80, 0x4b, 0x92, 0x89, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x80, 0xa6,
-	0x92, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0x4b, 0x94, 0x89, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0xca, 0x94, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x10, 0x00, 0x00, 0x4e, 0x98, 0xe4, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x07, 0x98, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x99, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x98, 0x94, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x49, 0x99, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0x88, 0x94, 0x01, 0x00, 0xa6, 0x04, 0x47, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xad, 0x04, 0x22, 0x20, 0x87, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0xa6, 0x04, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x1f, 0x80, 0x86, 0xb3, 0x01, 0x00, 0xb0, 0x04, 0x22, 0x4f,
-	0x77, 0x7d, 0x00, 0x00, 0xc0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x62, 0xb1, 0x01, 0x00, 0xb1, 0x04, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xb8, 0x04, 0x22, 0x4b, 0x89, 0x7c, 0x00, 0x00, 0xb6, 0x04, 0x22, 0x4f,
-	0x77, 0x7d, 0x00, 0x00, 0xc0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x62, 0xb1, 0x01, 0x00, 0xb6, 0x04, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x87, 0xb3, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x99, 0xb0, 0x01, 0x00, 0x6f, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0xc1, 0x04, 0xa8, 0xb1, 0x52, 0x33, 0x00, 0x00, 0xc6, 0x04, 0x22, 0x4b,
-	0x53, 0x7f, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0xc4, 0x04, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0xc1, 0x04, 0xa2, 0x41,
-	0x99, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x4f, 0x77, 0xfd, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x10, 0x00, 0x00, 0x4e, 0x98, 0xe4, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x07, 0x98, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x99, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x98, 0x94, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0x99, 0xe0, 0x01, 0x00, 0xd6, 0x04, 0x00, 0x4c,
-	0x88, 0x94, 0x00, 0x00, 0xd6, 0x04, 0x47, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xdd, 0x04, 0x22, 0x20, 0x87, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0xd6, 0x04, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x1f, 0x80, 0x86, 0xb3, 0x01, 0x00, 0xe0, 0x04, 0x22, 0x4f,
-	0x77, 0x7d, 0x00, 0x00, 0xf0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x62, 0xb1, 0x01, 0x00, 0xe1, 0x04, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xe8, 0x04, 0x22, 0x4a, 0x89, 0x7c, 0x00, 0x00, 0xe6, 0x04, 0x22, 0x4f,
-	0x77, 0x7d, 0x00, 0x00, 0xf0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x62, 0xb1, 0x01, 0x00, 0xe6, 0x04, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x87, 0xb3, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x99, 0xb0, 0x01, 0x00, 0x6f, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0xf1, 0x04, 0xa8, 0xb1, 0x52, 0x33, 0x00, 0x00, 0xf6, 0x04, 0x22, 0x4a,
-	0x53, 0x7f, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0xf4, 0x04, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0xf1, 0x04, 0xa2, 0x41,
-	0x99, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x4f, 0x77, 0xfd, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x00, 0x05, 0xa8, 0xb1, 0x80, 0x30, 0x00, 0x00, 0x12, 0x05, 0x1d, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x40, 0x18, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00, 0x10, 0x05, 0xa2, 0x40,
-	0x86, 0x04, 0x00, 0x00, 0xde, 0x9f, 0x9c, 0x40, 0x80, 0x32, 0x00, 0x00,
-	0xff, 0xff, 0x00, 0x40, 0x88, 0x88, 0x01, 0x00, 0x30, 0x05, 0x00, 0x50,
-	0x47, 0x31, 0x01, 0x00, 0x36, 0x00, 0x00, 0x44, 0x88, 0xcc, 0x01, 0x00,
-	0x0c, 0x05, 0x52, 0x40, 0x81, 0x32, 0x00, 0x00, 0x30, 0x05, 0x00, 0x40,
-	0x47, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x89, 0xb0, 0x01, 0x00,
-	0x30, 0x05, 0x00, 0x48, 0x47, 0x31, 0x01, 0x00, 0x30, 0x05, 0x00, 0x05,
-	0x47, 0x31, 0x01, 0x00, 0xde, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x28, 0x00, 0x00, 0x40, 0x47, 0x99, 0x1b, 0x00, 0xde, 0x9f, 0x00, 0x41,
-	0xe1, 0xc1, 0x1a, 0x00, 0x78, 0x18, 0x00, 0x40, 0x49, 0x99, 0x1b, 0x00,
-	0x19, 0x05, 0x22, 0x54, 0x81, 0x7c, 0x1a, 0x00, 0x14, 0x05, 0x42, 0x40,
-	0x81, 0x32, 0x1a, 0x00, 0x00, 0x82, 0x00, 0xb3, 0x67, 0xdf, 0x1b, 0x00,
-	0x00, 0x00, 0x1a, 0x44, 0x93, 0x93, 0x1b, 0x00, 0x28, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x1b, 0x00, 0x30, 0x05, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00,
-	0x27, 0x05, 0x0f, 0x40, 0x80, 0x32, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x40,
-	0x88, 0x88, 0x01, 0x00, 0x30, 0x05, 0x00, 0x50, 0x47, 0x31, 0x01, 0x00,
-	0x36, 0x00, 0x00, 0x44, 0x88, 0xcc, 0x01, 0x00, 0x1f, 0x05, 0x99, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x89, 0xd0, 0x01, 0x00,
-	0x21, 0x05, 0x9b, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0x89, 0xd0, 0x01, 0x00, 0x23, 0x05, 0x1f, 0x44, 0x80, 0x32, 0x00, 0x00,
-	0x30, 0x05, 0x00, 0x40, 0x47, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x89, 0xb0, 0x01, 0x00, 0x30, 0x05, 0x00, 0x48, 0x47, 0x31, 0x01, 0x00,
-	0x30, 0x05, 0x00, 0x58, 0x47, 0x31, 0x01, 0x00, 0xde, 0x9f, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x10, 0x00, 0x00, 0x40, 0x86, 0xf4, 0x01, 0x00,
-	0x6f, 0x00, 0x00, 0x43, 0x86, 0x88, 0x01, 0x00, 0xde, 0x9f, 0x26, 0x05,
-	0x47, 0x31, 0x00, 0x00, 0x30, 0x05, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00,
-	0xde, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x44, 0xf0, 0x41, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x80, 0x41,
-	0xe1, 0xc1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x4c, 0x01, 0x00, 0x07,
-	0x91, 0x30, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x40, 0x97, 0xec, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x05, 0x91, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x4c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x44, 0x05, 0xa2, 0x40,
-	0x97, 0x6c, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
-	0x45, 0x05, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40,
-	0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xda, 0xf5, 0xb1, 0x01, 0x00, 0x10, 0x04, 0x00, 0x42,
-	0xb3, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xf5, 0xb1, 0x01, 0x00,
-	0x10, 0x04, 0x00, 0x42, 0xb3, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
-	0xf5, 0xb1, 0x01, 0x00, 0x4e, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
-	0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda,
-	0xf7, 0xf5, 0x01, 0x00, 0x50, 0x00, 0x00, 0x40, 0x91, 0x98, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x8f, 0xb0, 0x01, 0x00, 0x10, 0x04, 0x00, 0x48,
-	0xb2, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xf7, 0xb1, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0xda, 0xf7, 0xf5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x91, 0xc0, 0x01, 0x00, 0x50, 0x05, 0xa2, 0x41, 0x8f, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x45, 0xd1, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40,
-	0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x40,
-	0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00, 0x1a, 0x00, 0x00, 0x40,
-	0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00, 0x18, 0x00, 0x00, 0x40,
-	0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00, 0x38, 0x05, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
-	0x91, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x6e, 0xda,
-	0x8f, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
-	0xfd, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0xda,
-	0xfd, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x7a, 0x05, 0x22, 0x45, 0xfd, 0x7f, 0x00, 0x00, 0x40, 0x16, 0x00, 0x40,
-	0x45, 0x99, 0x01, 0x00, 0xdb, 0x9f, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x15, 0x04, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x78, 0x05, 0xa2, 0x40, 0x8f, 0x6c, 0x00, 0x00,
-	0x7d, 0x05, 0x22, 0x20, 0xb5, 0x6f, 0x00, 0x00, 0x7a, 0x05, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xda, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x1f, 0x00,
-	0x7d, 0x05, 0x22, 0x40, 0x97, 0x6c, 0x1e, 0x00, 0x7a, 0x05, 0x42, 0x40,
-	0x81, 0x32, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x67, 0x93, 0x1f, 0x00,
-	0xdf, 0x9f, 0x00, 0x58, 0x67, 0x93, 0x1e, 0x00, 0x54, 0x16, 0x00, 0x40,
-	0x47, 0x99, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x1f, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xfe,
-	0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
-	0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00,
-	0x46, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda, 0xf7, 0xf5, 0x01, 0x00,
-	0x48, 0x00, 0x00, 0x40, 0x95, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x97, 0xb0, 0x01, 0x00, 0x10, 0x04, 0x00, 0x4a, 0xb2, 0x33, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xda, 0xf7, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda,
-	0xf7, 0xf5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x95, 0xc0, 0x01, 0x00,
-	0x90, 0x05, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x40,
-	0xa5, 0x9b, 0x01, 0x00, 0x40, 0x16, 0x00, 0x40, 0xa1, 0x9b, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xca, 0xa7, 0xb3, 0x01, 0x00, 0xe1, 0x9f, 0x00, 0xbb,
-	0x85, 0x30, 0x01, 0x00, 0xe0, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xb8, 0x05, 0x22, 0x45, 0xfd, 0x7f, 0x00, 0x00, 0xe0, 0x15, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x1a, 0x00, 0x00, 0xa2, 0x80, 0xdc, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0xf0, 0x15, 0x00, 0x40,
-	0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca, 0xf1, 0xb1, 0x01, 0x00,
-	0x07, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0x40,
-	0x62, 0xdd, 0x01, 0x00, 0xa7, 0x05, 0xa8, 0xbb, 0xe1, 0x31, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x83, 0xb0, 0x01, 0x00, 0xaa, 0x05, 0xa2, 0x41,
-	0x83, 0x50, 0x00, 0x00, 0xa9, 0x05, 0xa2, 0xf2, 0x82, 0x30, 0x00, 0x00,
-	0x4c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb0, 0x05, 0xa2, 0x40,
-	0x97, 0x6c, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
-	0xb1, 0x05, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40,
-	0xb3, 0x9b, 0x01, 0x00, 0xf0, 0x15, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb8, 0x05, 0xa2, 0xfa,
-	0xb4, 0x6f, 0x00, 0x00, 0x10, 0x04, 0x00, 0x42, 0xb3, 0x43, 0x01, 0x00,
-	0xb8, 0x05, 0xa2, 0xfa, 0xb4, 0x6f, 0x00, 0x00, 0x10, 0x04, 0x00, 0x42,
-	0xb3, 0x43, 0x01, 0x00, 0xbb, 0x05, 0x22, 0xfa, 0xb4, 0x6f, 0x00, 0x00,
-	0xb8, 0x05, 0x42, 0x40, 0x81, 0x32, 0x20, 0x00, 0x00, 0x00, 0x00, 0x4e,
-	0x67, 0x93, 0x21, 0x00, 0xdf, 0x9f, 0x00, 0x58, 0x67, 0x93, 0x20, 0x00,
-	0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x21, 0x00, 0xdb, 0x9f, 0x00, 0x40,
-	0x49, 0x31, 0x21, 0x00, 0xf6, 0x15, 0x00, 0x40, 0x43, 0x99, 0x21, 0x00,
-	0x5c, 0x16, 0x00, 0x40, 0x45, 0x99, 0x21, 0x00, 0x00, 0x00, 0x6e, 0xfa,
-	0x8e, 0xb0, 0x21, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0xb4, 0xb3, 0x01, 0x00, 0xc9, 0x05, 0xa2, 0x40, 0x8f, 0x6c, 0x00, 0x00,
-	0xfc, 0x15, 0x20, 0x20, 0xe1, 0xb1, 0x01, 0x00, 0xce, 0x05, 0x00, 0x40,
-	0x81, 0xb2, 0x24, 0x00, 0xda, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x25, 0x00,
-	0xce, 0x05, 0x22, 0x40, 0x97, 0x6c, 0x24, 0x00, 0xcb, 0x05, 0x42, 0x40,
-	0x81, 0x32, 0x24, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x67, 0x93, 0x25, 0x00,
-	0xdf, 0x9f, 0x00, 0x58, 0x67, 0x93, 0x24, 0x00, 0x38, 0x05, 0x00, 0x40,
-	0x81, 0x32, 0x25, 0x00, 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x25, 0x00,
-	0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xd3, 0x05, 0x22, 0x50,
-	0xb5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x91, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xf6, 0x15, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x20, 0x04, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00,
-	0x02, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xf8, 0x15, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x20, 0x04, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfa, 0x15, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x20, 0x04, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x15, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x94, 0xb0, 0x01, 0x00,
-	0xff, 0xff, 0x00, 0x4a, 0xb4, 0x8b, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x4a, 0xb4, 0xf7, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x38, 0x05, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xe9, 0x05, 0x22, 0x50, 0xb5, 0x6f, 0x00, 0x00,
-	0xea, 0x05, 0x00, 0x50, 0xb5, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xb5, 0xb3, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xe0, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x16, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x30, 0x31, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x32, 0x33, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x34, 0x35, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x36, 0x37, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x38, 0x39, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x41, 0x42, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x43, 0x44, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x45, 0x46, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x47, 0x48, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x49, 0x4a, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x40,
-	0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf7, 0xb1, 0x01, 0x00,
-	0xfc, 0x05, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x80, 0x16, 0x2e, 0x06,
-	0x83, 0xb0, 0x01, 0x00, 0x36, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
-	0xff, 0x05, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x22, 0x00, 0x00, 0x40,
-	0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb, 0xf6, 0xb1, 0x01, 0x00,
-	0x02, 0x06, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x62, 0x00, 0x00, 0x40,
-	0x95, 0x98, 0x01, 0x00, 0xdc, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x16, 0x2d, 0x06, 0x83, 0xb0, 0x01, 0x00, 0x80, 0x16, 0x00, 0x40,
-	0x45, 0x99, 0x01, 0x00, 0x5c, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
-	0x08, 0x06, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
-	0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71, 0xf9, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x72, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x73,
-	0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x74, 0xf9, 0xb1, 0x01, 0x00,
-	0x54, 0x00, 0x00, 0x40, 0x95, 0x98, 0x01, 0x00, 0xdc, 0x9f, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x70, 0x95, 0xb0, 0x01, 0x00,
-	0x14, 0x06, 0x22, 0x70, 0xb5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41,
-	0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x97, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x45, 0x67, 0x00, 0xa6, 0xe0, 0xb2, 0x01, 0x00, 0x01, 0x23, 0x00, 0x70,
-	0xe1, 0x9a, 0x01, 0x00, 0xcd, 0xef, 0x00, 0xa6, 0xe2, 0xb2, 0x01, 0x00,
-	0x89, 0xab, 0x00, 0x71, 0xe3, 0x9a, 0x01, 0x00, 0xba, 0x98, 0x00, 0xa6,
-	0xe4, 0xb2, 0x01, 0x00, 0xfe, 0xdc, 0x00, 0x72, 0xe5, 0x9a, 0x01, 0x00,
-	0x32, 0x10, 0x00, 0xa6, 0xe6, 0xb2, 0x01, 0x00, 0x76, 0x54, 0x00, 0x73,
-	0xe7, 0x9a, 0x01, 0x00, 0xd2, 0xc3, 0x00, 0xa6, 0xe8, 0xb2, 0x01, 0x00,
-	0xf0, 0xe1, 0x00, 0x74, 0xe9, 0x9a, 0x01, 0x00, 0x80, 0x16, 0x00, 0x4a,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x81, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4a, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf7, 0xb1, 0x01, 0x00, 0x25, 0x06, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
-	0x80, 0x16, 0x00, 0x4a, 0x44, 0xc9, 0x01, 0x00, 0xfc, 0x16, 0x2a, 0x47,
-	0xe7, 0xb5, 0x01, 0x00, 0x03, 0x00, 0x00, 0x4a, 0xe8, 0xe5, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x8d, 0xb0, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40,
-	0xa3, 0x99, 0x01, 0x00, 0x80, 0x16, 0x3d, 0x46, 0x8d, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
-	0x40, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00,
-	0x2e, 0x06, 0xa2, 0x41, 0x89, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
-	0xeb, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71, 0xed, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x72, 0xef, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x73,
-	0xf1, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x74, 0xf3, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0x41,
-	0x80, 0x88, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40, 0xa2, 0xc9, 0x01, 0x00,
-	0x4b, 0x06, 0xa0, 0x50, 0x83, 0x6c, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x40,
-	0x98, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x99, 0x84, 0x01, 0x00,
-	0x50, 0x03, 0x00, 0x4c, 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
-	0x86, 0xb0, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40, 0x98, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4f, 0x99, 0x84, 0x01, 0x00, 0x50, 0x03, 0x00, 0x4c,
-	0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x86, 0xa4, 0x01, 0x00,
-	0x02, 0x00, 0x00, 0x40, 0x98, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f,
-	0x99, 0x84, 0x01, 0x00, 0x50, 0x03, 0x00, 0x4c, 0xa2, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x20, 0x86, 0xa4, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40,
-	0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x40, 0xa4, 0x01, 0x00,
-	0x01, 0x00, 0x00, 0x20, 0x88, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0x41, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x40, 0x94, 0x01, 0x00,
-	0x05, 0x00, 0x00, 0x75, 0x89, 0xe4, 0x01, 0x00, 0x1b, 0x00, 0x00, 0x75,
-	0x85, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x84, 0x94, 0x01, 0x00,
-	0x55, 0x06, 0xa3, 0x53, 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76,
-	0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77, 0x89, 0x84, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x76, 0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
-	0x8b, 0xa4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
-	0x64, 0x06, 0x00, 0x45, 0x88, 0x94, 0x00, 0x00, 0x27, 0x00, 0x00, 0x41,
-	0x80, 0xce, 0x01, 0x00, 0x5a, 0x06, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x76, 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
-	0x89, 0xa4, 0x01, 0x00, 0x64, 0x06, 0x00, 0x78, 0x89, 0xa4, 0x00, 0x00,
-	0x3b, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00, 0x57, 0x06, 0xaa, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x89, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x77, 0x89, 0x84, 0x01, 0x00, 0x00, 0x00, 0x00, 0x76,
-	0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x88, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
-	0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
-	0x64, 0x06, 0x00, 0x45, 0x88, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x84, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x79, 0x85, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x20, 0x84, 0xc0, 0x01, 0x00, 0x6b, 0x06, 0xa3, 0x53,
-	0x83, 0x6c, 0x00, 0x00, 0x82, 0x5a, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00,
-	0x99, 0x79, 0x00, 0x42, 0x84, 0xc8, 0x01, 0x00, 0x78, 0x06, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x27, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00,
-	0x70, 0x06, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00, 0xd9, 0x6e, 0x00, 0xa6,
-	0x84, 0xc0, 0x01, 0x00, 0xa1, 0xeb, 0x00, 0x42, 0x84, 0xc8, 0x01, 0x00,
-	0x78, 0x06, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x41,
-	0x80, 0xce, 0x01, 0x00, 0x75, 0x06, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x1b, 0x8f, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00, 0xdc, 0xbc, 0x00, 0x42,
-	0x84, 0xc8, 0x01, 0x00, 0x78, 0x06, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x62, 0xca, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00, 0xd6, 0xc1, 0x00, 0x42,
-	0x84, 0xc8, 0x01, 0x00, 0x78, 0x06, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x78, 0xf3, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
-	0xf1, 0xb2, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x76, 0x89, 0xe4, 0x01, 0x00,
-	0x02, 0x00, 0x00, 0x76, 0xef, 0xf6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0xee, 0x96, 0x01, 0x00, 0x00, 0x00, 0x00, 0x75, 0xed, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0xea, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x83, 0xc0, 0x01, 0x00, 0x4f, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00,
-	0x37, 0x06, 0x2a, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75,
-	0xe1, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x76, 0xe3, 0xc2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x77, 0xe5, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78,
-	0xe7, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x79, 0xe9, 0xc2, 0x01, 0x00,
-	0x2b, 0x06, 0x81, 0x41, 0x8d, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0xfd, 0x93, 0x01, 0x00, 0x40, 0x16, 0x00, 0x40,
-	0x45, 0x99, 0x01, 0x00, 0xdb, 0x9f, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x15, 0x04, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xb9, 0x06, 0x22, 0x40, 0x8f, 0x6c, 0x00, 0x00,
-	0xda, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb9, 0x06, 0xa2, 0x40,
-	0x97, 0x6c, 0x00, 0x00, 0x5e, 0x16, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x7c, 0x16, 0x20, 0xf6, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x31, 0xb3, 0x01, 0x00, 0x9d, 0x06, 0x22, 0x4f, 0x8f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x51, 0xfd, 0x93, 0x01, 0x00, 0x9f, 0x06, 0x22, 0x40,
-	0x8f, 0x7c, 0x00, 0x00, 0xa3, 0x06, 0x00, 0x54, 0xfd, 0x93, 0x00, 0x00,
-	0xa1, 0x06, 0x22, 0x42, 0x8f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52,
-	0xfd, 0x93, 0x01, 0x00, 0xa3, 0x06, 0x22, 0x41, 0x8f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x53, 0xfd, 0x93, 0x01, 0x00, 0xb7, 0x06, 0x22, 0x51,
-	0xfd, 0x7f, 0x00, 0x00, 0x38, 0x05, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x0c, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xb2, 0x06, 0xa2, 0x40, 0xb5, 0x6f, 0x00, 0x00,
-	0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x48,
-	0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0x97, 0xc0, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0x4b, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x48,
-	0xb2, 0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x30, 0xb5, 0xb3, 0x01, 0x00,
-	0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x48,
-	0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xb6, 0x06, 0x22, 0x40, 0xb5, 0x6f, 0x00, 0x00, 0xba, 0x06, 0x00, 0x54,
-	0xfd, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0xfd, 0x83, 0x01, 0x00,
-	0x1c, 0x00, 0x00, 0xfe, 0x7f, 0xd9, 0x01, 0x00, 0xba, 0x06, 0xa6, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xfd, 0x93, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xe7, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc4, 0x06, 0x22, 0x5c,
-	0x1f, 0x7c, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0xe9, 0x9f, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00,
-	0x04, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x3c, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x00, 0x14, 0x02, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0x34, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
-	0x32, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05, 0x0a, 0xc8, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x0e, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xa4,
-	0x0c, 0xc8, 0x01, 0x00, 0xea, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00, 0x0a, 0x07, 0x22, 0x01,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x2e, 0xa4, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x48, 0xc1, 0x01, 0x00, 0xd9, 0x06, 0xa3, 0x07, 0x02, 0x6c, 0x00, 0x00,
-	0xda, 0x06, 0x68, 0x01, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x07,
-	0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x02, 0xd0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0d, 0x0a, 0xc0, 0x01, 0x00, 0xec, 0x06, 0x22, 0x40,
-	0x03, 0x6c, 0x00, 0x00, 0xe6, 0x06, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
-	0x23, 0x07, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0xe3, 0x06, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x62, 0xb1, 0x01, 0x00, 0xe8, 0x06, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00,
-	0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x23, 0x07, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x62, 0xb1, 0x01, 0x00, 0xee, 0x06, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00,
-	0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x22, 0x00, 0x00, 0x19,
-	0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00,
-	0x0f, 0x00, 0x00, 0xf2, 0x3a, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x3b, 0xe0, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x14, 0x02, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x1d, 0x02, 0xc0, 0x01, 0x00, 0xfa, 0x06, 0x23, 0x1a,
-	0x02, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x03, 0xc0, 0x01, 0x00,
-	0x23, 0x07, 0x00, 0x01, 0x34, 0xc0, 0x00, 0x00, 0x0c, 0x00, 0x2d, 0x1d,
-	0x48, 0xc1, 0x01, 0x00, 0xf0, 0x00, 0x00, 0xf2, 0x30, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x31, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14,
-	0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x02, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x18, 0x02, 0xc0, 0x01, 0x00, 0x02, 0x07, 0x22, 0x1a,
-	0x02, 0x50, 0x00, 0x00, 0x23, 0x07, 0x00, 0x01, 0x34, 0xc0, 0x00, 0x00,
-	0x22, 0x00, 0x00, 0x19, 0x48, 0xc9, 0x01, 0x00, 0x02, 0x00, 0x2d, 0x14,
-	0x48, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x14, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x1d, 0x14, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
-	0x14, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x24, 0xb0, 0x01, 0x00,
-	0x12, 0x00, 0x00, 0x17, 0x10, 0xc8, 0x01, 0x00, 0x23, 0x07, 0x00, 0x1a,
-	0x10, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xa4, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
-	0x48, 0xc1, 0x01, 0x00, 0x0f, 0x07, 0xa3, 0x12, 0x0e, 0x6c, 0x00, 0x00,
-	0x10, 0x07, 0x60, 0x07, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x60, 0x12,
-	0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x68, 0x0d, 0x16, 0x94, 0x01, 0x00,
-	0xff, 0xff, 0x00, 0x0b, 0x16, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00, 0x17, 0x07, 0xa8, 0x5c,
-	0x1f, 0x10, 0x00, 0x00, 0x40, 0x07, 0x22, 0x0d, 0x14, 0x50, 0x00, 0x00,
-	0x40, 0x07, 0x22, 0x0d, 0x24, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
-	0x10, 0xc0, 0x01, 0x00, 0x1e, 0x07, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
-	0x23, 0x07, 0x00, 0x41, 0x23, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x1f, 0x07, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
-	0x3f, 0x07, 0xa2, 0x0d, 0x0e, 0x50, 0x00, 0x00, 0x2e, 0x07, 0x22, 0x46,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00,
-	0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x2c, 0x07, 0x22, 0xf2,
-	0x64, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x29, 0x07, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x20, 0x80, 0x00, 0x03, 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0xe1, 0x91, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x06, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x04, 0xb0, 0x01, 0x00, 0x33, 0x07, 0x1f, 0xf0, 0x0e, 0x30, 0x00, 0x00,
-	0xd3, 0x06, 0x00, 0x4c, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x5f,
-	0x0f, 0x80, 0x01, 0x00, 0xd3, 0x06, 0x23, 0x07, 0x14, 0x6c, 0x00, 0x00,
-	0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x24, 0x00, 0x00, 0x40,
-	0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
-	0xf0, 0xb1, 0x01, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa4,
-	0x62, 0xdd, 0x01, 0x00, 0x3c, 0x07, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
-	0xd3, 0x06, 0x00, 0x03, 0x0c, 0xb0, 0x00, 0x00, 0xd3, 0x06, 0x00, 0x0d,
-	0x18, 0xc0, 0x00, 0x00, 0x5f, 0x07, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x19, 0x0a, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05,
-	0x48, 0xc9, 0x01, 0x00, 0x0a, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00,
-	0x02, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x20, 0x40,
-	0xe5, 0xb1, 0x01, 0x00, 0x0d, 0x00, 0x2d, 0x1d, 0x48, 0xc1, 0x01, 0x00,
-	0x09, 0x00, 0x00, 0xf3, 0x38, 0x88, 0x01, 0x00, 0x0d, 0x00, 0x20, 0x50,
-	0xe7, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x2d, 0x40, 0x3f, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf4, 0x32, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x20, 0x40,
-	0xe1, 0xb1, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05, 0x48, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00, 0x02, 0x00, 0x00, 0x1d,
-	0x94, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x91, 0xb0, 0x01, 0x00,
-	0x52, 0x07, 0xa0, 0xfc, 0x90, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x91, 0xc0, 0x01, 0x00, 0x50, 0x07, 0xa2, 0x41, 0x95, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xa4, 0x96, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x2e, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4b, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
-	0x48, 0xc1, 0x01, 0x00, 0x02, 0x00, 0x00, 0x18, 0x94, 0xf4, 0x01, 0x00,
-	0x00, 0x00, 0x2d, 0x18, 0x90, 0xb0, 0x01, 0x00, 0x5c, 0x07, 0xa0, 0xfc,
-	0x90, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x91, 0xc0, 0x01, 0x00,
-	0x5a, 0x07, 0xa2, 0x41, 0x95, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
-	0xe0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00,
-	0x04, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x80, 0xb0, 0x2d, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x16, 0xb0, 0x2d, 0x00,
-	0x22, 0x00, 0x00, 0x05, 0x48, 0xc9, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x14,
-	0x48, 0xc1, 0x2d, 0x00, 0x64, 0x07, 0x43, 0x30, 0x3d, 0x07, 0x2c, 0x00,
-	0x00, 0x00, 0x00, 0x9e, 0x85, 0xb0, 0x2d, 0x00, 0x00, 0x00, 0x1b, 0x41,
-	0x3d, 0xc3, 0x2d, 0x00, 0x04, 0x00, 0x20, 0x42, 0xec, 0xb1, 0x2d, 0x00,
-	0x00, 0x00, 0x00, 0x1e, 0x82, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x2e, 0x1d,
-	0x82, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x18, 0x82, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x80, 0xc0, 0x01, 0x00, 0x6e, 0x07, 0xa0, 0x41,
-	0x80, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x40, 0x92, 0xf4, 0x01, 0x00, 0x0a, 0x00, 0x2e, 0x30,
-	0x81, 0x84, 0x01, 0x00, 0x72, 0x07, 0x90, 0x40, 0x92, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20,
-	0x93, 0xa4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x48, 0xc1, 0x01, 0x00,
-	0x04, 0x00, 0x20, 0x19, 0xe8, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1e,
-	0x16, 0xc0, 0x01, 0x00, 0x78, 0x07, 0xa0, 0x19, 0x16, 0x44, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x0d, 0x00, 0x2f, 0x1e,
-	0x32, 0xc0, 0x01, 0x00, 0x7d, 0x07, 0xa2, 0x40, 0x15, 0x6c, 0x00, 0x00,
-	0x7c, 0x07, 0xa0, 0x1c, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x63, 0xf3, 0x38, 0x94, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x05, 0x48, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x2e, 0x1e,
-	0x98, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0x1a, 0x98, 0xc0, 0x01, 0x00,
-	0x0c, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x8b, 0x07, 0x22, 0x46,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00,
-	0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x89, 0x07, 0x22, 0xf2,
-	0x64, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x86, 0x07, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x20, 0x80, 0x00, 0x03, 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0xe1, 0x91, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
-	0x12, 0x00, 0x00, 0x1a, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x17,
-	0xf0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00,
-	0x30, 0x00, 0x00, 0x10, 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x40, 0x62, 0xdd, 0x01, 0x00,
-	0x91, 0x07, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x9b, 0x07, 0x22, 0x5c,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x2d, 0x10, 0x48, 0xc1, 0x01, 0x00, 0x9b, 0x07, 0x22, 0xf2,
-	0x64, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x98, 0x07, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0xeb, 0x9f, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x20, 0x00, 0x2f, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe4, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x17, 0xf0, 0x01, 0x00, 0xa1, 0x07, 0x90, 0xf2,
-	0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00, 0x10, 0x00, 0x00, 0x14,
-	0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x2a, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x2b, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
-	0x2a, 0x94, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
-	0xac, 0x07, 0x22, 0xf2, 0x64, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0xa9, 0x07, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x17, 0x10, 0xdc, 0x01, 0x00,
-	0xc9, 0x07, 0x22, 0x40, 0x15, 0x6c, 0x00, 0x00, 0xb4, 0x07, 0xa2, 0x44,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x1f, 0x90, 0x01, 0x00,
-	0xb3, 0x07, 0x22, 0x9f, 0x13, 0x6c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x88,
-	0x1c, 0xcc, 0x01, 0x00, 0xe4, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x3f, 0xc3, 0x01, 0x00, 0xe6, 0x9f, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xb7, 0x07, 0xa2, 0x41, 0x87, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x1e, 0x3e, 0xc0, 0x01, 0x00, 0xc9, 0x07, 0x22, 0x40,
-	0x15, 0x6c, 0x00, 0x00, 0xba, 0x07, 0x20, 0x1e, 0x14, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x0a, 0x3c, 0xb0, 0x01, 0x00, 0xe5, 0x9f, 0x00, 0x1e,
-	0x24, 0x30, 0x01, 0x00, 0xbf, 0x07, 0x22, 0x08, 0x2e, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x52, 0x11, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1a,
-	0x10, 0xc0, 0x01, 0x00, 0x23, 0x07, 0x00, 0x40, 0x17, 0xb0, 0x00, 0x00,
-	0xe4, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xe5, 0x9f, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xbc, 0x07, 0xa2, 0x08, 0x2e, 0x30, 0x00, 0x00,
-	0x80, 0x80, 0x00, 0xa6, 0x04, 0xb0, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40,
-	0x87, 0x98, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0x99, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0x04, 0xe0, 0x31, 0x00, 0x00, 0xe8, 0x9f, 0x00, 0x1f,
-	0x8c, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00,
-	0xe2, 0x9f, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03,
-	0x44, 0x99, 0x01, 0x00, 0x04, 0x00, 0x22, 0x04, 0xe0, 0x31, 0x00, 0x00,
-	0xe6, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xce, 0x07, 0xa2, 0x41,
-	0x87, 0x7c, 0x00, 0x00, 0xcf, 0x07, 0x00, 0x1e, 0x3e, 0xc0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x1f, 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x05, 0xb0, 0x01, 0x00, 0xe8, 0x9f, 0x00, 0x40, 0x0f, 0x30, 0x01, 0x00,
-	0xe2, 0x9f, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xf7, 0x07, 0x00, 0xbc, 0x80, 0xb2, 0x00, 0x00,
-	0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00,
-	},
-	{
-	0x31, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x34, 0x80, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x35, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1b, 0x80, 0x81, 0x80,
-	0x80, 0x32, 0x00, 0x00, 0x0e, 0x87, 0xa2, 0x40, 0x91, 0x6f, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0x90, 0xb3, 0x01, 0x00, 0x5c, 0x95, 0x2e, 0xa2,
-	0x80, 0xb0, 0x01, 0x00, 0xff, 0x00, 0x00, 0x80, 0xf4, 0x89, 0x01, 0x00,
-	0x90, 0x95, 0x2a, 0xc8, 0xe5, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa1,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xa4, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd2, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd4, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xd3, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xee,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x44, 0xb1, 0x01, 0x00, 0x18, 0x80, 0x11, 0x81,
-	0x98, 0x30, 0x00, 0x00, 0x00, 0x00, 0x51, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x1a, 0x80, 0x11, 0x82, 0x98, 0x30, 0x00, 0x00, 0x00, 0x00, 0x52, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x0e, 0x87, 0x00, 0x48, 0xfd, 0x93, 0x00, 0x00,
-	0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x23, 0x80, 0xa2, 0x42,
-	0xfd, 0x7f, 0x00, 0x00, 0x20, 0x80, 0x00, 0x80, 0x80, 0x32, 0x00, 0x00,
-	0x22, 0x80, 0x11, 0x81, 0x82, 0x30, 0x00, 0x00, 0x22, 0x80, 0x51, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x22, 0x80, 0x11, 0x82, 0x82, 0x30, 0x00, 0x00,
-	0x22, 0x80, 0x52, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2c, 0x80, 0x00, 0x48,
-	0xfd, 0x93, 0x00, 0x00, 0x27, 0x80, 0x00, 0x80, 0x80, 0x32, 0x00, 0x00,
-	0x26, 0x80, 0xa2, 0x53, 0x07, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x51, 0x53,
-	0x07, 0x90, 0x01, 0x00, 0x2a, 0x80, 0x00, 0x52, 0x07, 0x90, 0x00, 0x00,
-	0x29, 0x80, 0xa2, 0x52, 0x07, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x52, 0x52,
-	0x07, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0xf3, 0x93, 0x01, 0x00, 0x5c, 0x95, 0x2e, 0xa2, 0x52, 0xb3, 0x01, 0x00,
-	0xff, 0x00, 0x00, 0x80, 0xf4, 0x89, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa9, 0x45, 0xb1, 0x01, 0x00,
-	0x30, 0x80, 0x00, 0x4c, 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x45, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x55, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0xaf, 0x82, 0x05, 0x40, 0x49, 0xb1, 0x00, 0x00, 0xaf, 0x82, 0x05, 0x40,
-	0x49, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x05, 0x40, 0x49, 0xb1, 0x01, 0x00,
-	0x4c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0xde, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xfd, 0x93, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0xfd, 0x83, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40,
-	0x9b, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x9c, 0xb3, 0x01, 0x00,
-	0x48, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x58, 0x95, 0x20, 0x44,
-	0xe0, 0xb1, 0x01, 0x00, 0x04, 0x94, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf2, 0x24, 0xb1, 0x01, 0x00, 0x00, 0x0c, 0x00, 0xee,
-	0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x97, 0xf0, 0x01, 0x00,
-	0x44, 0x80, 0xa2, 0x43, 0x97, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0xfd, 0x93, 0x01, 0x00, 0x00, 0xc0, 0x00, 0xa6, 0x36, 0xb1, 0x01, 0x00,
-	0xd0, 0x14, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x00, 0x38, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x00, 0x06, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x05, 0x10, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
-	0x02, 0x09, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0xf5, 0x99, 0x01, 0x00, 0x60, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x88, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xa0, 0x03, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xa2, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x9a, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x60, 0x95, 0x20, 0x40,
-	0xe1, 0xb1, 0x01, 0x00, 0x70, 0x95, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x49, 0xdd, 0x91, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x91, 0xb3, 0x01, 0x00, 0xe0, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x85, 0xb3, 0x01, 0x00, 0x5c, 0x95, 0x20, 0x40,
-	0xe1, 0xb1, 0x01, 0x00, 0x27, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x90, 0x06, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0x2f, 0x81, 0x01, 0x00, 0x8d, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xe5, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x55, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0xdd, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0xaf, 0x82, 0x00, 0x41, 0xe1, 0xc1, 0x00, 0x00, 0x78, 0x18, 0x00, 0x40,
-	0x49, 0x99, 0x01, 0x00, 0x19, 0x05, 0x22, 0x54, 0x81, 0x7c, 0x00, 0x00,
-	0x6c, 0x80, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x82, 0x00, 0xb4,
-	0x69, 0xdf, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x44, 0x93, 0x93, 0x01, 0x00,
-	0x28, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x18, 0x05, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x40, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x7d, 0x80, 0x22, 0x40,
-	0x97, 0x6c, 0x00, 0x00, 0x7a, 0x80, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4f, 0x69, 0x93, 0x01, 0x00, 0x38, 0x81, 0x00, 0x58,
-	0x69, 0x93, 0x00, 0x00, 0x54, 0x16, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x80, 0x05, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x80, 0x80, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4e, 0x69, 0x93, 0x01, 0x00, 0x38, 0x81, 0x00, 0x58,
-	0x69, 0x93, 0x00, 0x00, 0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
-	0x40, 0x05, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00, 0xf6, 0x15, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x5c, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x6e, 0xfa, 0x8e, 0xb0, 0x01, 0x00, 0xc1, 0x05, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x96, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x40, 0x82, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x96, 0x80, 0x22, 0x40, 0x97, 0x6c, 0x00, 0x00,
-	0x93, 0x80, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f,
-	0x69, 0x93, 0x01, 0x00, 0x38, 0x81, 0x00, 0x58, 0x69, 0x93, 0x00, 0x00,
-	0x38, 0x05, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x48,
-	0xb2, 0xcb, 0x01, 0x00, 0xd0, 0x05, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x83, 0x02, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xb8, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xd4, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xd5, 0x9f, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xd6, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xd7, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x72, 0x01, 0x00, 0x41,
-	0x81, 0xc0, 0x00, 0x00, 0x55, 0x01, 0x51, 0x48, 0xfd, 0x93, 0x00, 0x00,
-	0x55, 0x01, 0x52, 0x48, 0xfd, 0x93, 0x00, 0x00, 0x55, 0x01, 0x55, 0x49,
-	0xfd, 0x83, 0x00, 0x00, 0x55, 0x01, 0x56, 0x4a, 0xfd, 0x83, 0x00, 0x00,
-	0x50, 0x01, 0x91, 0x81, 0x80, 0x30, 0x00, 0x00, 0x55, 0x01, 0x45, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x50, 0x01, 0x91, 0x82, 0x80, 0x30, 0x00, 0x00,
-	0x55, 0x01, 0x46, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x80, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x16, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05,
-	0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0x48, 0xc1, 0x01, 0x00,
-	0xb4, 0x80, 0x43, 0x30, 0x3d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e,
-	0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x1b, 0x41, 0x3d, 0xc3, 0x01, 0x00,
-	0x04, 0x00, 0x20, 0x42, 0xec, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x49, 0xb1, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x20, 0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x20, 0x62, 0xdd, 0x01, 0x00,
-	0x00, 0x00, 0xa8, 0xd0, 0xe1, 0xb1, 0x00, 0x00, 0xbf, 0x80, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x98, 0xb0, 0x01, 0x00,
-	0x04, 0x80, 0x00, 0x40, 0x8b, 0xb3, 0x00, 0x00, 0xb1, 0x03, 0x00, 0x40,
-	0xa1, 0x99, 0x01, 0x00, 0xc7, 0x80, 0xa2, 0x42, 0x97, 0x6f, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0xa1, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x04, 0x80, 0x94, 0x00, 0x00,
-	0x80, 0x15, 0x3f, 0x42, 0x97, 0xe3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x03, 0x02, 0x94, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x07, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0xcb,
-	0x99, 0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xf3, 0x83, 0x01, 0x00,
-	0xd1, 0x80, 0xa2, 0x42, 0x97, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcb,
-	0xf3, 0x93, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x20, 0x44, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x04, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa1,
-	0xe0, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x20, 0x62, 0xdd, 0x01, 0x00, 0xd8, 0x80, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xf9, 0x02, 0x00, 0x20, 0x42, 0x31, 0x01, 0x00,
-	0x00, 0x00, 0xa2, 0x41, 0x05, 0x6c, 0x01, 0x00, 0x00, 0x00, 0x80, 0xcb,
-	0xdb, 0x91, 0x01, 0x00, 0x00, 0x00, 0x19, 0x41, 0x8b, 0xb3, 0x01, 0x00,
-	0x60, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xde, 0x80, 0xa8, 0xb1,
-	0x8c, 0x33, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0xe0, 0x80, 0xa8, 0xb1, 0x94, 0x33, 0x00, 0x00, 0xe6, 0x80, 0x14, 0xc6,
-	0x81, 0x32, 0x00, 0x00, 0x18, 0x00, 0x00, 0xc6, 0x83, 0xf4, 0x01, 0x00,
-	0xf4, 0x82, 0x22, 0x4f, 0x83, 0x04, 0x00, 0x00, 0xc2, 0x80, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xff, 0x01, 0x00, 0xc6, 0x81, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xc6, 0x97, 0xa3, 0x01, 0x00, 0xc2, 0x80, 0x1f, 0x5c,
-	0x97, 0x53, 0x00, 0x00, 0x58, 0x82, 0x1e, 0xc6, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x2f, 0x43, 0x81, 0xf0, 0x01, 0x00, 0xec, 0x80, 0x00, 0x40,
-	0x10, 0xc9, 0x00, 0x00, 0x39, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x6a, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x24, 0x82, 0x00, 0xca,
-	0x63, 0xb3, 0x00, 0x00, 0x61, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x48, 0x81, 0x00, 0x4d, 0x83, 0xb0, 0x00, 0x00, 0x52, 0x81, 0x00, 0x4e,
-	0x61, 0xb1, 0x00, 0x00, 0x41, 0x81, 0x00, 0x40, 0x85, 0xb0, 0x00, 0x00,
-	0x48, 0x81, 0x00, 0x4c, 0x83, 0xb0, 0x00, 0x00, 0x24, 0x81, 0x00, 0x40,
-	0x85, 0xb0, 0x00, 0x00, 0xe3, 0x81, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00,
-	0x71, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00, 0xdf, 0x81, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x41, 0x81, 0x00, 0x40, 0x85, 0xb0, 0x00, 0x00,
-	0xf0, 0x03, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00, 0xf4, 0x82, 0x00, 0xca,
-	0x9b, 0xb3, 0x00, 0x00, 0x7b, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00,
-	0x7f, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00, 0x86, 0x81, 0x00, 0x40,
-	0xc1, 0xb1, 0x00, 0x00, 0x87, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00,
-	0x88, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00, 0x89, 0x81, 0x00, 0x40,
-	0xc1, 0xb1, 0x00, 0x00, 0x8a, 0x81, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00,
-	0x8a, 0x81, 0x00, 0x41, 0x81, 0xb0, 0x00, 0x00, 0x18, 0x82, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x97, 0x82, 0x00, 0xbb, 0xab, 0xb3, 0x00, 0x00,
-	0x25, 0x82, 0x00, 0xca, 0xcf, 0xb3, 0x00, 0x00, 0xc8, 0x03, 0x00, 0x40,
-	0x49, 0xb1, 0x00, 0x00, 0xe8, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x26, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xf4, 0x82, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xf4, 0x82, 0x00, 0xca, 0x77, 0xb3, 0x00, 0x00, 0x49, 0x81, 0x00, 0x4d,
-	0x83, 0xb0, 0x00, 0x00, 0x50, 0x81, 0x00, 0x4e, 0x61, 0xb1, 0x00, 0x00,
-	0x41, 0x81, 0x00, 0xbb, 0x85, 0xb0, 0x00, 0x00, 0x49, 0x81, 0x00, 0x4c,
-	0x83, 0xb0, 0x00, 0x00, 0x41, 0x81, 0x00, 0xbb, 0x85, 0xb0, 0x00, 0x00,
-	0x24, 0x81, 0x00, 0xbb, 0x85, 0xb0, 0x00, 0x00, 0x16, 0x81, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xf4, 0x82, 0x00, 0xca, 0x4d, 0xb3, 0x00, 0x00,
-	0x70, 0x05, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00, 0xa0, 0x05, 0x00, 0x40,
-	0x49, 0xb1, 0x00, 0x00, 0x1c, 0x81, 0x22, 0x42, 0x8f, 0x6f, 0x00, 0x00,
-	0x1e, 0x81, 0x22, 0x41, 0x8f, 0x6f, 0x00, 0x00, 0x20, 0x81, 0x1e, 0xca,
-	0x81, 0x32, 0x00, 0x00, 0x22, 0x81, 0x1f, 0xca, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xca, 0xc9, 0xb1, 0x01, 0x00, 0xf4, 0x82, 0x00, 0x42,
-	0x8f, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xcd, 0xb1, 0x01, 0x00,
-	0xf4, 0x82, 0x00, 0x41, 0x8f, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca,
-	0xcf, 0xb1, 0x01, 0x00, 0xf4, 0x82, 0x00, 0x40, 0x8f, 0xb3, 0x00, 0x00,
-	0x00, 0x81, 0x00, 0xa6, 0xc6, 0xb1, 0x01, 0x00, 0xf4, 0x82, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0xa6, 0xc6, 0xb1, 0x01, 0x00,
-	0xf4, 0x82, 0x00, 0x40, 0x8f, 0xb3, 0x00, 0x00, 0x78, 0x18, 0x00, 0x40,
-	0x49, 0x99, 0x01, 0x00, 0x10, 0x00, 0x2f, 0x9c, 0x89, 0xb0, 0x01, 0x00,
-	0x3b, 0x81, 0x00, 0x40, 0x39, 0x33, 0x01, 0x00, 0x18, 0x00, 0x2f, 0x9b,
-	0x89, 0xb0, 0x01, 0x00, 0x3b, 0x81, 0x00, 0x40, 0x37, 0x33, 0x01, 0x00,
-	0x00, 0x00, 0x2f, 0x9a, 0x89, 0xb0, 0x01, 0x00, 0x3b, 0x81, 0x00, 0x40,
-	0x35, 0x33, 0x01, 0x00, 0x08, 0x00, 0x2f, 0x99, 0x89, 0xb0, 0x01, 0x00,
-	0x3b, 0x81, 0x00, 0x40, 0x33, 0x33, 0x01, 0x00, 0x00, 0x80, 0x00, 0xae,
-	0x47, 0xc9, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xca, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0xf0, 0xb1, 0x01, 0x00, 0x40, 0x18, 0x00, 0x40, 0xe1, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xae,
-	0x63, 0xdd, 0x01, 0x00, 0x36, 0x81, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x33, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x36, 0x81, 0x42, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x69, 0x93, 0x01, 0x00,
-	0xf4, 0x82, 0x1a, 0x44, 0x93, 0x93, 0x00, 0x00, 0x39, 0x81, 0x42, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x38, 0x81, 0x00, 0x58, 0x69, 0x93, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0xf0, 0xd1, 0x01, 0x00, 0x00, 0x00, 0xa4, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x40, 0x81, 0xa2, 0x40, 0xe1, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x45, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x41, 0xe1, 0xd1, 0x01, 0x00,
-	0x41, 0x81, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x62, 0xb1, 0x01, 0x00, 0x45, 0x81, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x42, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca,
-	0x63, 0xb1, 0x01, 0x00, 0x45, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xf4, 0x82, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x4a, 0x81, 0x00, 0x40,
-	0x81, 0xb0, 0x00, 0x00, 0x4a, 0x81, 0x00, 0xbb, 0x81, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x60, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x62, 0xb1, 0x01, 0x00, 0x4b, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xca, 0x63, 0xb1, 0x01, 0x00, 0xf4, 0x82, 0x28, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x4d, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x50, 0x95, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x53, 0x81, 0x00, 0xbb,
-	0x87, 0xb0, 0x00, 0x00, 0x50, 0x95, 0x2f, 0x40, 0x87, 0xb0, 0x01, 0x00,
-	0x55, 0x81, 0x22, 0x40, 0x95, 0x7f, 0x00, 0x00, 0xf4, 0x82, 0x60, 0x40,
-	0x95, 0x83, 0x00, 0x00, 0x02, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00,
-	0x56, 0x81, 0x36, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x62, 0xb1, 0x01, 0x00, 0x57, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x62, 0xb1, 0x01, 0x00, 0x59, 0x81, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0x63, 0xb1, 0x01, 0x00,
-	0x5b, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x16, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0xf4, 0x82, 0x22, 0x41, 0x43, 0x51, 0x00, 0x00,
-	0x00, 0x08, 0x00, 0xca, 0x95, 0xcb, 0x01, 0x00, 0x56, 0x81, 0x00, 0x41,
-	0x85, 0xc0, 0x00, 0x00, 0x63, 0x81, 0xa2, 0x42, 0x67, 0x6f, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x67, 0xb3, 0x01, 0x00, 0x63, 0x81, 0x42, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x65, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x93, 0x83, 0x01, 0x00, 0x00, 0x00, 0x1a, 0xca,
-	0x69, 0x97, 0x01, 0x00, 0xf4, 0x82, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x68, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0xf4, 0x82, 0x1a, 0x44,
-	0x93, 0x93, 0x00, 0x00, 0xf4, 0x82, 0x20, 0x43, 0x95, 0x6f, 0x00, 0x00,
-	0xf4, 0x82, 0x80, 0xca, 0x67, 0x33, 0x00, 0x00, 0xf4, 0x82, 0x22, 0x40,
-	0x65, 0x6f, 0x00, 0x00, 0xf4, 0x82, 0x00, 0x6f, 0xdb, 0x91, 0x00, 0x00,
-	0x85, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x35, 0x80, 0x22, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0xf4, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x58, 0x95, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0x95, 0x93, 0x01, 0x00, 0x77, 0x81, 0xa2, 0x44, 0x21, 0x6f, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x95, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5e,
-	0x95, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57, 0x95, 0x93, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xca, 0xc3, 0xb1, 0x01, 0x00, 0x7a, 0x81, 0x22, 0x5b,
-	0x95, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b, 0xfd, 0x93, 0x01, 0x00,
-	0xf4, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1b, 0xfd, 0x00, 0xca,
-	0x95, 0x9b, 0x01, 0x00, 0x0d, 0x01, 0x00, 0xca, 0xc5, 0x31, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x95, 0x83, 0x01, 0x00, 0xf4, 0x82, 0x00, 0xca,
-	0xc5, 0xb1, 0x00, 0x00, 0xdf, 0x6f, 0x00, 0xca, 0x95, 0x9b, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x55, 0x95, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
-	0xc7, 0xb1, 0x01, 0x00, 0xf4, 0x82, 0x22, 0x5f, 0x95, 0x7f, 0x00, 0x00,
-	0x0d, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0x95, 0x83, 0x01, 0x00, 0xf4, 0x82, 0x00, 0xca, 0xc7, 0xb1, 0x00, 0x00,
-	0xf4, 0x82, 0x00, 0xca, 0xc9, 0xb1, 0x00, 0x00, 0xf4, 0x82, 0x00, 0xca,
-	0xcb, 0xb1, 0x00, 0x00, 0xf4, 0x82, 0x00, 0xca, 0xcd, 0xb1, 0x00, 0x00,
-	0xf4, 0x82, 0x00, 0xca, 0xcf, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x42,
-	0x81, 0xe0, 0x01, 0x00, 0x98, 0x14, 0x00, 0x40, 0x48, 0xc9, 0x01, 0x00,
-	0xf4, 0x82, 0x00, 0xca, 0xe1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x09, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
-	0x8f, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x80, 0x00, 0x41,
-	0x08, 0x99, 0x01, 0x00, 0x91, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
-	0x20, 0x80, 0x00, 0xa6, 0x08, 0xb1, 0x01, 0x00, 0x93, 0x81, 0x9f, 0x85,
-	0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x83, 0x84, 0x01, 0x00,
-	0xc8, 0x81, 0x22, 0x30, 0x83, 0x6c, 0x00, 0x00, 0x92, 0x81, 0xa2, 0x4f,
-	0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x21, 0xb3, 0x01, 0x00,
-	0x02, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x10, 0x00, 0x00, 0x41, 0x84, 0xe4, 0x01, 0x00,
-	0x03, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xf0, 0xff, 0x00, 0x41, 0x86, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x84, 0x94, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xa6,
-	0x86, 0xb0, 0x01, 0x00, 0x10, 0xc4, 0x00, 0x43, 0x86, 0x98, 0x01, 0x00,
-	0xa8, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x21, 0xb3, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
-	0x1c, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0xa5, 0x81, 0xa2, 0x5e,
-	0x0b, 0x7d, 0x00, 0x00, 0x04, 0x00, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00,
-	0xba, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x41, 0x01, 0x00, 0xa6,
-	0x86, 0xb0, 0x01, 0x00, 0x50, 0x0c, 0x00, 0x43, 0x86, 0x98, 0x01, 0x00,
-	0xad, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x21, 0xb3, 0x01, 0x00, 0xba, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x41, 0x01, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00, 0x60, 0x0c, 0x00, 0x43,
-	0x86, 0x98, 0x01, 0x00, 0xba, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x21, 0xb3, 0x01, 0x00, 0x18, 0x80, 0x00, 0xa6,
-	0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xff, 0xff, 0x00, 0x41, 0x82, 0x88, 0x01, 0x00, 0x00, 0x77, 0x00, 0x41,
-	0x82, 0x8c, 0x01, 0x00, 0x01, 0x02, 0x00, 0x41, 0x82, 0x98, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0x18, 0x00, 0x00, 0x41,
-	0x82, 0xdc, 0x01, 0x00, 0xb8, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x08, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
-	0x82, 0xb0, 0x01, 0x00, 0xbb, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
-	0x40, 0x13, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00, 0xc3, 0x81, 0x22, 0x43,
-	0x21, 0x6f, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
-	0x12, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0xc0, 0x81, 0xa2, 0x5e,
-	0x0b, 0x7d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00,
-	0xde, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6,
-	0x82, 0xb0, 0x01, 0x00, 0x19, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00,
-	0xc5, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x41,
-	0x08, 0x99, 0x01, 0x00, 0xde, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x21, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x83, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5e, 0x83, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57,
-	0x83, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xc2, 0xb1, 0x01, 0x00,
-	0x0c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0x83, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xc2, 0xb1, 0x01, 0x00,
-	0x0c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
-	0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
-	0x82, 0xb0, 0x01, 0x00, 0x11, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00,
-	0xd7, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x01, 0x00, 0x00, 0x41,
-	0x08, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
-	0xda, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x40, 0x13, 0x00, 0x41,
-	0x08, 0x99, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x41, 0x2e, 0x99, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x80, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xca, 0x81, 0x94, 0x01, 0x00, 0xe1, 0x81, 0xa2, 0x5e,
-	0x0b, 0x7d, 0x00, 0x00, 0xf4, 0x82, 0x00, 0x40, 0x08, 0xb1, 0x00, 0x00,
-	0xc8, 0x14, 0x2e, 0xbb, 0x85, 0xb0, 0x01, 0x00, 0xe4, 0x81, 0xa2, 0x5e,
-	0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x87, 0xb0, 0x01, 0x00,
-	0xf3, 0x81, 0x22, 0x43, 0x21, 0x6f, 0x00, 0x00, 0x02, 0x82, 0x22, 0x44,
-	0x21, 0x6f, 0x00, 0x00, 0x11, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
-	0x13, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x0a, 0x82, 0x22, 0x4a,
-	0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x87, 0x90, 0x01, 0x00,
-	0xee, 0x81, 0x22, 0x4d, 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x87, 0x90, 0x01, 0x00, 0xf0, 0x81, 0x22, 0x4f, 0x83, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x87, 0x90, 0x01, 0x00, 0xf2, 0x81, 0x22, 0x4e,
-	0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x87, 0x90, 0x01, 0x00,
-	0x0a, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x01, 0x80, 0x00, 0xa6,
-	0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x01, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x0a, 0x82, 0x22, 0x42, 0x83, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x87, 0x90, 0x01, 0x00, 0x1c, 0x80, 0x00, 0xa6,
-	0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xfd, 0x81, 0x22, 0x45, 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x87, 0x90, 0x01, 0x00, 0xff, 0x81, 0x22, 0x44, 0x83, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x87, 0x90, 0x01, 0x00, 0x01, 0x82, 0x22, 0x43,
-	0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x87, 0x90, 0x01, 0x00,
-	0x0a, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x01, 0x80, 0x00, 0xa6,
-	0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x01, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x0a, 0x82, 0x22, 0x42, 0x83, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x87, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x87, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x87, 0x90, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x0e, 0x82, 0x22, 0x4b, 0x83, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x87, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0xe0, 0xb1, 0x01, 0x00, 0xff, 0x7f, 0x00, 0xa2, 0xa0, 0x8b, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0xa5, 0xb3, 0x01, 0x00, 0xb8, 0x80, 0x00, 0xca,
-	0xa7, 0x33, 0x01, 0x00, 0x36, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x20, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0x14, 0x82, 0xa2, 0x5e,
-	0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x08, 0xb1, 0x01, 0x00,
-	0x16, 0x82, 0x9f, 0x85, 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x1b, 0x82, 0x14, 0xf7, 0x81, 0x30, 0x00, 0x00,
-	0x1b, 0x82, 0xa2, 0x49, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
-	0xfd, 0x93, 0x01, 0x00, 0x1e, 0x82, 0x15, 0xf8, 0x81, 0x14, 0x00, 0x00,
-	0x1e, 0x82, 0xa2, 0x4a, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
-	0xfd, 0x93, 0x01, 0x00, 0x20, 0x82, 0xa2, 0xc8, 0x81, 0x32, 0x00, 0x00,
-	0x40, 0x00, 0x00, 0x40, 0x80, 0xdc, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40,
-	0x80, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xef, 0xb3, 0x01, 0x00,
-	0x22, 0x82, 0x42, 0x40, 0xf1, 0x33, 0x00, 0x00, 0x38, 0x81, 0x00, 0x40,
-	0x68, 0x97, 0x00, 0x00, 0xf4, 0x82, 0x00, 0xbb, 0x6b, 0xb3, 0x00, 0x00,
-	0xf4, 0x82, 0x00, 0xbb, 0xb1, 0xb3, 0x00, 0x00, 0xf4, 0x82, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x03, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x18, 0xb1, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40,
-	0x83, 0x98, 0x01, 0x00, 0x00, 0x19, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x42, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x18, 0xb1, 0x01, 0x00, 0x2b, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
-	0x00, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x19, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x43, 0xc1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
-	0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x81, 0xd0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf6, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x43, 0xc1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00, 0x35, 0x82, 0xa2, 0x54,
-	0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf7, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00, 0x3c, 0x82, 0xa2, 0x06,
-	0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x16, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x80, 0x16, 0x2e, 0x06,
-	0x83, 0xb0, 0x01, 0x00, 0x36, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
-	0x42, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x22, 0x00, 0x00, 0x40,
-	0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb, 0xf6, 0xb1, 0x01, 0x00,
-	0x45, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x62, 0x00, 0x00, 0x40,
-	0x95, 0x98, 0x01, 0x00, 0xdc, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x16, 0x2d, 0x06, 0x83, 0xb0, 0x01, 0x00, 0x80, 0x16, 0x00, 0x40,
-	0x45, 0x99, 0x01, 0x00, 0x5c, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
-	0x4b, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
-	0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71, 0xf9, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x72, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x73,
-	0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x74, 0xf9, 0xb1, 0x01, 0x00,
-	0x54, 0x00, 0x00, 0x40, 0x95, 0x98, 0x01, 0x00, 0xdc, 0x9f, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x70, 0x95, 0xb0, 0x01, 0x00,
-	0x57, 0x82, 0x22, 0x70, 0xb5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41,
-	0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x97, 0xb0, 0x01, 0x00,
-	0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x42,
-	0x99, 0xb3, 0x01, 0x00, 0x62, 0x82, 0x22, 0x44, 0x81, 0x6c, 0x00, 0x00,
-	0x6a, 0x82, 0x22, 0x48, 0x81, 0x6c, 0x00, 0x00, 0x64, 0x82, 0x22, 0x4c,
-	0x81, 0x6c, 0x00, 0x00, 0x6e, 0x82, 0x22, 0x50, 0x81, 0x6c, 0x00, 0x00,
-	0x6f, 0x82, 0x22, 0x54, 0x81, 0x6c, 0x00, 0x00, 0x71, 0x82, 0x22, 0x58,
-	0x81, 0x6c, 0x00, 0x00, 0x76, 0x82, 0x22, 0x5c, 0x81, 0x6c, 0x00, 0x00,
-	0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc,
-	0x09, 0xb0, 0x01, 0x00, 0xf4, 0x82, 0x00, 0xca, 0x01, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0xf3, 0x83, 0x01, 0x00, 0x68, 0x82, 0xa2, 0x42, 0x05, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x05, 0xb0, 0x01, 0x00, 0xf4, 0x82, 0x22, 0xca,
-	0x07, 0x14, 0x00, 0x00, 0xf4, 0x82, 0x00, 0x46, 0xf3, 0x93, 0x00, 0x00,
-	0xf4, 0x82, 0x20, 0x43, 0x95, 0x6f, 0x00, 0x00, 0xf4, 0x82, 0x80, 0xca,
-	0x05, 0x30, 0x00, 0x00, 0xf4, 0x82, 0x22, 0x01, 0x80, 0x30, 0x00, 0x00,
-	0xf4, 0x82, 0x00, 0xcb, 0xdb, 0x91, 0x00, 0x00, 0x57, 0x01, 0x00, 0xbc,
-	0xab, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0xb1, 0xb3, 0x01, 0x00,
-	0xf4, 0x82, 0x00, 0xca, 0xcf, 0xb3, 0x00, 0x00, 0xff, 0x00, 0x00, 0xca,
-	0x81, 0x88, 0x01, 0x00, 0xf4, 0x82, 0xa2, 0x40, 0x74, 0x7d, 0x00, 0x00,
-	0x60, 0x00, 0x20, 0x40, 0x60, 0x99, 0x01, 0x00, 0x73, 0x82, 0xa8, 0xb1,
-	0x82, 0x30, 0x00, 0x00, 0x72, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xf4, 0x82, 0x00, 0xca, 0x79, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e,
-	0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0xcb, 0x83, 0x01, 0x00,
-	0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x79, 0x82, 0xa2, 0x41,
-	0x81, 0x50, 0x00, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x84, 0x82, 0x91, 0x82,
-	0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x80, 0xb0, 0x01, 0x00,
-	0xae, 0x9f, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00, 0x82, 0x82, 0xa6, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x84, 0x82, 0x56, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53,
-	0x07, 0x90, 0x01, 0x00, 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x52, 0x07, 0x90, 0x01, 0x00, 0xd8, 0x9f, 0x00, 0x41,
-	0x8b, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x81, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0xcd, 0x83, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x89, 0x82, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x94, 0x82, 0x91, 0x81, 0x82, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x89, 0x80, 0xb0, 0x01, 0x00, 0xae, 0x9f, 0x00, 0x40,
-	0x80, 0xce, 0x01, 0x00, 0x92, 0x82, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x94, 0x82, 0x55, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb6, 0x03, 0x00, 0x40,
-	0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x52, 0x07, 0x90, 0x01, 0x00,
-	0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53,
-	0x07, 0x90, 0x01, 0x00, 0xd8, 0x9f, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00,
-	0xb1, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0xc4, 0x14, 0x2f, 0x40,
-	0x99, 0xb3, 0x01, 0x00, 0x57, 0x01, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00,
-	0xa0, 0x94, 0x2e, 0x43, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0x9b, 0x82, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
-	0x50, 0x95, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0xac, 0x94, 0x2e, 0x43,
-	0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
-	0x9f, 0x82, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0xae, 0x03, 0x00, 0x40, 0xa3, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x60, 0x15, 0x00, 0x40,
-	0x85, 0x98, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40, 0x40, 0xe4, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x59, 0x41, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x41, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x40, 0x94, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x57, 0x41, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xa3, 0x42, 0x81, 0x6c, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00, 0xa5, 0x82, 0xa0, 0x42,
-	0x81, 0x6c, 0x00, 0x00, 0xa5, 0x82, 0x00, 0x50, 0x85, 0xc0, 0x00, 0x00,
-	0xdd, 0x82, 0xa2, 0x41, 0x01, 0x7d, 0x00, 0x00, 0xb5, 0x82, 0x22, 0x58,
-	0x73, 0x7d, 0x00, 0x00, 0x78, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0xb0, 0x82, 0xa8, 0xb1, 0x9c, 0x30, 0x00, 0x00, 0x30, 0x00, 0x38, 0x45,
-	0x9d, 0xe0, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0xc9, 0x00, 0x00,
-	0xb5, 0x82, 0x33, 0xc4, 0x81, 0x30, 0x00, 0x00, 0xb8, 0x82, 0xa1, 0xad,
-	0x9d, 0x20, 0x00, 0x00, 0xaf, 0x82, 0x13, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x13, 0x4e, 0x5a, 0x83, 0x01, 0x00, 0x30, 0x00, 0x38, 0x45,
-	0x9d, 0xe0, 0x01, 0x00, 0xc0, 0x82, 0x22, 0xab, 0x80, 0x04, 0x00, 0x00,
-	0xbe, 0x82, 0xa2, 0x40, 0x01, 0x7d, 0x00, 0x00, 0xc0, 0x82, 0x22, 0x5f,
-	0x57, 0x7d, 0x00, 0x00, 0x36, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xc0, 0x82, 0x22, 0x5e, 0x57, 0x7d, 0x00, 0x00, 0x99, 0x87, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xc5, 0x82, 0x22, 0x54, 0x73, 0x7d, 0x00, 0x00,
-	0x74, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xc0, 0x82, 0xa8, 0xb1,
-	0x00, 0x30, 0x00, 0x00, 0x8a, 0x84, 0xa2, 0x5f, 0x01, 0x7c, 0x00, 0x00,
-	0xca, 0x86, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc7, 0x82, 0xa2, 0x5f,
-	0x59, 0x27, 0x00, 0x00, 0xc9, 0x82, 0xa2, 0x5c, 0x73, 0x7d, 0x00, 0x00,
-	0xd0, 0x82, 0xa2, 0x5e, 0x73, 0x7d, 0x00, 0x00, 0xda, 0x82, 0x22, 0x5c,
-	0x73, 0x7d, 0x00, 0x00, 0xdb, 0x82, 0x37, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x7c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xca, 0x82, 0xa8, 0xb1,
-	0x36, 0x30, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0xcc, 0x82, 0xa8, 0xb1, 0x00, 0x30, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
-	0x02, 0x88, 0x01, 0x00, 0xb9, 0x84, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xdb, 0x82, 0x34, 0x40, 0x81, 0x32, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0xd1, 0x82, 0xa8, 0xb1, 0x12, 0x30, 0x00, 0x00,
-	0xd8, 0x82, 0x52, 0x21, 0x13, 0x04, 0x00, 0x00, 0x00, 0x00, 0x14, 0x41,
-	0x2f, 0xc3, 0x01, 0x00, 0xff, 0x3f, 0x00, 0x09, 0x00, 0x8c, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x01, 0xf0, 0x01, 0x00, 0x11, 0x83, 0x00, 0x34,
-	0x13, 0x84, 0x00, 0x00, 0xff, 0x3f, 0x14, 0x09, 0x00, 0x8c, 0x01, 0x00,
-	0x6f, 0x83, 0x00, 0x43, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0xdb, 0x82, 0x33, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xaf, 0x82, 0x13, 0x4e, 0x5a, 0x93, 0x00, 0x00, 0x0e, 0x87, 0xa2, 0x48,
-	0xfd, 0x7f, 0x00, 0x00, 0x04, 0x00, 0xa2, 0xac, 0x80, 0x32, 0x00, 0x00,
-	0xe3, 0x82, 0x22, 0x5a, 0x73, 0x7d, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0xe0, 0x82, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00,
-	0x01, 0x00, 0x00, 0xcf, 0x11, 0xc9, 0x00, 0x00, 0xe9, 0x82, 0xa2, 0x40,
-	0x93, 0x7f, 0x00, 0x00, 0xe9, 0x82, 0x22, 0x44, 0x93, 0x7f, 0x00, 0x00,
-	0xe5, 0x82, 0x42, 0xa5, 0x80, 0x30, 0x00, 0x00, 0xe8, 0x82, 0xa2, 0x40,
-	0x93, 0x7f, 0x00, 0x00, 0xfb, 0x82, 0x1a, 0x40, 0x93, 0x93, 0x00, 0x00,
-	0x00, 0x00, 0x1a, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xdd, 0x80, 0xa2, 0x40,
-	0x73, 0x7d, 0x00, 0x00, 0x09, 0x87, 0x22, 0x44, 0x21, 0x6f, 0x00, 0x00,
-	0x00, 0x87, 0x22, 0x40, 0x65, 0x7d, 0x00, 0x00, 0x00, 0x05, 0xa2, 0x5b,
-	0x73, 0x7d, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x49, 0x33, 0x7d, 0x00, 0x00,
-	0xf3, 0x82, 0x22, 0x48, 0x33, 0x7d, 0x00, 0x00, 0xff, 0x01, 0x00, 0x99,
-	0x80, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x81, 0xe0, 0x01, 0x00,
-	0xa8, 0x98, 0x2f, 0x40, 0x33, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xe0, 0xc1, 0x01, 0x00, 0xdd, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x40, 0x8b, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x62, 0xb1, 0x01, 0x00,
-	0xaf, 0x82, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0xf6, 0x82, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xf9, 0x82, 0x33, 0x40, 0x1f, 0x30, 0x00, 0x00,
-	0xaf, 0x82, 0x13, 0x4e, 0x5a, 0x93, 0x00, 0x00, 0xfd, 0x82, 0xa0, 0xce,
-	0x81, 0x50, 0x00, 0x00, 0x0f, 0x83, 0xa0, 0xcd, 0x81, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xa5, 0x9c, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb1,
-	0x81, 0xb0, 0x01, 0x00, 0x0f, 0x83, 0x22, 0xb5, 0x81, 0x14, 0x00, 0x00,
-	0x80, 0x15, 0x2f, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x01, 0x83, 0x42, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x60, 0xb4, 0x65, 0x97, 0x01, 0x00,
-	0xd0, 0x15, 0x2e, 0x40, 0x69, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x44,
-	0x93, 0x83, 0x01, 0x00, 0x1a, 0x00, 0x00, 0xa2, 0x80, 0xdc, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb1,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb5, 0xf1, 0xb1, 0x01, 0x00,
-	0x05, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40,
-	0x62, 0xdd, 0x01, 0x00, 0x0a, 0x83, 0xa8, 0xa1, 0xe0, 0x31, 0x00, 0x00,
-	0xe9, 0x82, 0x00, 0x88, 0x9e, 0xb3, 0x00, 0x00, 0xe9, 0x82, 0xa2, 0x41,
-	0x67, 0x6f, 0x00, 0x00, 0xe9, 0x82, 0x00, 0x6f, 0xdb, 0x91, 0x00, 0x00,
-	0x0f, 0x83, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0xe9, 0x82, 0x1a, 0x40,
-	0x93, 0x83, 0x00, 0x00, 0x00, 0x99, 0x00, 0x09, 0x46, 0xc9, 0x01, 0x00,
-	0x3f, 0x00, 0x00, 0xf3, 0x0c, 0x88, 0x01, 0x00, 0x1a, 0x83, 0xa6, 0x42,
-	0x13, 0x60, 0x00, 0x00, 0x12, 0x94, 0x00, 0x95, 0x03, 0x30, 0x01, 0x00,
-	0x15, 0x83, 0x61, 0x40, 0x81, 0x32, 0x00, 0x00, 0x75, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0x16, 0x83, 0xa8, 0xb1, 0x0c, 0x30, 0x00, 0x00,
-	0x1f, 0x94, 0x71, 0x10, 0x94, 0x30, 0x01, 0x00, 0x1b, 0x83, 0x00, 0x58,
-	0x1f, 0x90, 0x00, 0x00, 0x05, 0x94, 0x00, 0x95, 0x03, 0x30, 0x01, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x03,
-	0x48, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x2d, 0xf0, 0x2e, 0xb0, 0x01, 0x00,
-	0xee, 0x07, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00, 0x22, 0x83, 0x23, 0x4b,
-	0xe4, 0x6d, 0x00, 0x00, 0x22, 0x83, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x1f, 0x90, 0x01, 0x00, 0x22, 0x00, 0x2f, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x25, 0x83, 0x83, 0x17, 0x80, 0x32, 0x00, 0x00,
-	0x26, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x27, 0x83, 0x85, 0x17,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x47, 0xc1, 0x01, 0x00,
-	0x2c, 0x83, 0x22, 0x55, 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x43, 0xd1, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xfa, 0x96, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x97, 0xe0, 0x01, 0x00, 0x2d, 0x83, 0x00, 0x4b,
-	0x44, 0xc1, 0x00, 0x00, 0x12, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00,
-	0x28, 0x00, 0x00, 0xf6, 0x02, 0xcc, 0x01, 0x00, 0x0a, 0x00, 0x00, 0xa1,
-	0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x16, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x28, 0xf0, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x2a, 0xb0, 0x01, 0x00,
-	0xc0, 0x28, 0x3c, 0x46, 0x0d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x44,
-	0x95, 0xb0, 0x01, 0x00, 0x39, 0x83, 0xa2, 0xf8, 0x0e, 0x30, 0x00, 0x00,
-	0x49, 0x83, 0x22, 0x41, 0x95, 0x50, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x50,
-	0x49, 0xc1, 0x01, 0x00, 0x35, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x36, 0x83, 0xa2, 0xf8, 0x16, 0x6c, 0x00, 0x00, 0x36, 0x83, 0xa2, 0xf8,
-	0x10, 0x6c, 0x00, 0x00, 0x36, 0x83, 0xa2, 0xf0, 0x1a, 0x6c, 0x00, 0x00,
-	0x47, 0x83, 0x22, 0x58, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42,
-	0x13, 0xf0, 0x01, 0x00, 0x3e, 0x83, 0x65, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x42, 0x83, 0xa2, 0xf3, 0x74, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
-	0xe6, 0x95, 0x01, 0x00, 0x47, 0x83, 0x75, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x06, 0x96, 0xb0, 0x01, 0x00, 0x3f, 0x00, 0x75, 0xf3,
-	0x0c, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55, 0x61, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00, 0x45, 0x83, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x47, 0x83, 0x67, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x4f, 0x83, 0x77, 0x41, 0x2d, 0xc3, 0x00, 0x00, 0x4d, 0x83, 0x22, 0x58,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x61, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x06, 0x62, 0xb1, 0x01, 0x00, 0x4b, 0x83, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x4d, 0x83, 0x67, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x7c, 0x83, 0x77, 0x41, 0x2d, 0xc3, 0x00, 0x00, 0x03, 0x00, 0x00, 0x07,
-	0x1a, 0xf4, 0x01, 0x00, 0xd8, 0x92, 0x00, 0x07, 0x16, 0x30, 0x01, 0x00,
-	0x5d, 0x83, 0x22, 0x41, 0x81, 0x6c, 0x00, 0x00, 0x55, 0x83, 0x22, 0x42,
-	0x81, 0x6c, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x5c, 0x83, 0x22, 0x5f, 0x0f, 0x7c, 0x00, 0x00, 0xcc, 0x93, 0x00, 0x5f,
-	0x01, 0x10, 0x01, 0x00, 0x5b, 0x83, 0x22, 0x40, 0x95, 0x6c, 0x00, 0x00,
-	0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
-	0x02, 0xb0, 0x01, 0x00, 0x41, 0x93, 0x00, 0x52, 0x95, 0x30, 0x01, 0x00,
-	0x48, 0x93, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0x14, 0x87, 0x00, 0x40,
-	0x0f, 0xb0, 0x00, 0x00, 0x65, 0x83, 0xa2, 0x5a, 0x1f, 0x7c, 0x00, 0x00,
-	0x53, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x65, 0x83, 0x22, 0x20,
-	0x85, 0x6c, 0x00, 0x00, 0x62, 0x83, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x33, 0x93, 0x00, 0x5c,
-	0x1f, 0x00, 0x01, 0x00, 0x25, 0x95, 0x00, 0x42, 0x61, 0x31, 0x01, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x90, 0x04, 0x00, 0x07,
-	0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x68, 0x83, 0x82, 0xf0, 0x18, 0x30, 0x00, 0x00, 0x7b, 0x88, 0x00, 0x45,
-	0x8f, 0xb0, 0x00, 0x00, 0x28, 0x20, 0x00, 0xa6, 0x96, 0xb0, 0x01, 0x00,
-	0x6c, 0x83, 0x22, 0x17, 0x96, 0x04, 0x00, 0x00, 0xc9, 0x94, 0x00, 0x4b,
-	0x95, 0x30, 0x01, 0x00, 0x7b, 0x88, 0x00, 0x4b, 0x8f, 0xb0, 0x00, 0x00,
-	0xd8, 0x93, 0x00, 0x03, 0x48, 0x31, 0x01, 0x00, 0xb4, 0x91, 0x00, 0x40,
-	0x81, 0x30, 0x01, 0x00, 0x7b, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x68, 0x50,
-	0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x50,
-	0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x77, 0x83, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10,
-	0x62, 0xc9, 0x01, 0x00, 0x79, 0x83, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x03,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x2e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
-	0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00,
-	0x00, 0x41, 0x00, 0xa6, 0x96, 0xb0, 0x01, 0x00, 0xee, 0x07, 0x2e, 0x47,
-	0x97, 0x90, 0x01, 0x00, 0x8f, 0x83, 0x22, 0x17, 0x96, 0x04, 0x00, 0x00,
-	0x8d, 0x83, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0x8d, 0x83, 0x23, 0xa2,
-	0x02, 0x6c, 0x00, 0x00, 0x41, 0x93, 0x00, 0x52, 0x95, 0x30, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0x41, 0x97, 0x50, 0x00, 0x00, 0x0c, 0x00, 0x2d, 0x00,
-	0x12, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5c, 0x01, 0x80, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b,
-	0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x03, 0xb0, 0x01, 0x00, 0xac, 0x83, 0x00, 0x5c,
-	0x17, 0x90, 0x00, 0x00, 0xa1, 0x83, 0x22, 0x43, 0x2f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x1f, 0x90, 0x01, 0x00, 0x9a, 0x83, 0x22, 0x5f,
-	0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x58, 0xf1, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x03,
-	0xf0, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00,
-	0x96, 0x83, 0x62, 0x42, 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x62, 0xb1, 0x01, 0x00, 0x97, 0x83, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xaf, 0x82, 0x72, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x00, 0x2d, 0x03,
-	0x48, 0xb1, 0x01, 0x00, 0xff, 0x0f, 0x00, 0xf6, 0x80, 0x88, 0x01, 0x00,
-	0x9e, 0x83, 0xa2, 0xa6, 0x81, 0x6c, 0x00, 0x00, 0xa1, 0x83, 0x00, 0xf2,
-	0x3a, 0xb0, 0x00, 0x00, 0x87, 0x84, 0xa2, 0x4b, 0xfd, 0x7f, 0x00, 0x00,
-	0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2a, 0x87, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xac, 0x83, 0x22, 0x4a, 0x2f, 0x7c, 0x00, 0x00,
-	0xac, 0x83, 0x22, 0x48, 0x2f, 0x7c, 0x00, 0x00, 0x0a, 0x00, 0x2d, 0x03,
-	0x48, 0xb1, 0x01, 0x00, 0x3f, 0x00, 0x00, 0xf2, 0x86, 0x88, 0x01, 0x00,
-	0x1f, 0x00, 0x00, 0x43, 0x84, 0x88, 0x01, 0x00, 0x05, 0x00, 0x00, 0x43,
-	0x80, 0xf4, 0x01, 0x00, 0x98, 0x94, 0x3d, 0x42, 0x81, 0xe0, 0x01, 0x00,
-	0xac, 0x83, 0xa2, 0x42, 0xe0, 0x7d, 0x00, 0x00, 0x87, 0x84, 0xa2, 0x4b,
-	0xfd, 0x7f, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x2a, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xac, 0x83, 0x69, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa3, 0x09, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x79, 0x41, 0x47, 0xc3, 0x01, 0x00, 0xb2, 0x83, 0x22, 0xa1,
-	0x09, 0x6c, 0x00, 0x00, 0xf5, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0xaf, 0x83, 0x00, 0x03, 0x48, 0xb1, 0x00, 0x00, 0xeb, 0x83, 0xa3, 0x92,
-	0x03, 0x6c, 0x00, 0x00, 0x7d, 0x95, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x43, 0xc3, 0x01, 0x00, 0x2a, 0x87, 0x22, 0x08,
-	0x80, 0x32, 0x00, 0x00, 0xb8, 0x83, 0x22, 0x5c, 0x17, 0x7c, 0x00, 0x00,
-	0xb9, 0x83, 0x00, 0x00, 0x2a, 0xb0, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
-	0x2a, 0xc8, 0x01, 0x00, 0x02, 0x00, 0x00, 0x08, 0x80, 0xc8, 0x01, 0x00,
-	0xbd, 0x83, 0xa2, 0x43, 0x2f, 0x7c, 0x00, 0x00, 0xcc, 0x94, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xd9, 0x83, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x01, 0x8c, 0xcc, 0x01, 0x00, 0xcc, 0x94, 0x00, 0x4c,
-	0x03, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x46, 0x02, 0xb0, 0x01, 0x00,
-	0x10, 0x80, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x01,
-	0xf0, 0xcd, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x40, 0xf0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x15,
-	0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
-	0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0xc6, 0x83, 0xa8, 0x54,
-	0x17, 0x10, 0x00, 0x00, 0xd9, 0x83, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00,
-	0x12, 0x00, 0x00, 0x00, 0x2a, 0xc8, 0x01, 0x00, 0xd8, 0x83, 0x22, 0x43,
-	0x2f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x8c, 0xcc, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0x03, 0xb0, 0x01, 0x00, 0xed, 0x94, 0x00, 0x43,
-	0x61, 0x31, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x46, 0x02, 0xb0, 0x01, 0x00,
-	0x10, 0x80, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x01,
-	0xf0, 0xcd, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x09, 0xf0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x15,
-	0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
-	0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0xd9, 0x83, 0x28, 0x54,
-	0x17, 0x10, 0x00, 0x00, 0xd5, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xed, 0x94, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00, 0xdb, 0x83, 0x22, 0x50,
-	0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x17, 0x90, 0x01, 0x00,
-	0x07, 0x00, 0x00, 0x17, 0x98, 0x88, 0x01, 0x00, 0xde, 0x83, 0xa2, 0x41,
-	0x99, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x17, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0xdf, 0x83, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xd4, 0x94, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xe6, 0x83, 0x22, 0x43, 0x2f, 0x7c, 0x00, 0x00,
-	0x16, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d,
-	0xe4, 0xb1, 0x01, 0x00, 0x75, 0x94, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00,
-	0xe9, 0x83, 0xa2, 0x5f, 0x2f, 0x7c, 0x00, 0x00, 0x90, 0x91, 0x00, 0x01,
-	0x38, 0x43, 0x01, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x2a, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xed, 0x83, 0xa2, 0x4b,
-	0xfd, 0x7f, 0x00, 0x00, 0x84, 0x84, 0x00, 0x41, 0x43, 0xc3, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x27, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x11, 0xb0, 0x01, 0x00, 0xef, 0x83, 0x35, 0x01, 0x86, 0x30, 0x00, 0x00,
-	0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xf6, 0x83, 0x28, 0xb1,
-	0x30, 0x30, 0x00, 0x00, 0xf0, 0x83, 0x22, 0x4d, 0x75, 0x7d, 0x00, 0x00,
-	0x74, 0x84, 0xa2, 0x40, 0x11, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x43, 0xc3, 0x01, 0x00, 0x83, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xf6, 0x83, 0xa8, 0xb1,
-	0x12, 0x30, 0x00, 0x00, 0xff, 0x83, 0xa2, 0x40, 0x11, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x43, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09,
-	0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0x2c, 0xb0, 0x01, 0x00,
-	0xde, 0x07, 0x00, 0x43, 0x80, 0xce, 0x01, 0x00, 0xf0, 0x83, 0xaa, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x04, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x40, 0x00, 0x3e, 0x43, 0x27, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0xe0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x27, 0xc0, 0x01, 0x00, 0xf0, 0x83, 0xa3, 0x0b,
-	0x87, 0x50, 0x00, 0x00, 0x00, 0x00, 0x15, 0x40, 0x1b, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00,
-	0x2a, 0xc8, 0x01, 0x00, 0x40, 0x00, 0x2d, 0x40, 0x39, 0xb0, 0x01, 0x00,
-	0x0c, 0x84, 0xa2, 0x40, 0x27, 0x6c, 0x00, 0x00, 0x22, 0x00, 0x00, 0x08,
-	0x12, 0xc8, 0x01, 0x00, 0xde, 0x07, 0x00, 0x40, 0x25, 0x98, 0x01, 0x00,
-	0x0f, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x12, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x30, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0b, 0x25, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x32, 0xb0, 0x01, 0x00, 0x14, 0x00, 0x20, 0x01, 0xe0, 0xb1, 0x01, 0x00,
-	0xee, 0x07, 0x00, 0x40, 0x37, 0x98, 0x01, 0x00, 0x14, 0x84, 0x23, 0x01,
-	0x36, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x36, 0xb0, 0x01, 0x00,
-	0x1f, 0x84, 0x82, 0x41, 0x23, 0x40, 0x00, 0x00, 0x20, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0x1b, 0x84, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x18, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xb8, 0x92, 0x00, 0x43,
-	0x23, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x23, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19, 0x44, 0xc9, 0x01, 0x00,
-	0x2e, 0x84, 0x22, 0x45, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
-	0x25, 0x84, 0xa8, 0x15, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x03, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0x25, 0xd0, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x4c,
-	0x13, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x37, 0xd0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x2b, 0xc0, 0x01, 0x00, 0x14, 0x84, 0x00, 0x45,
-	0x1f, 0x80, 0x00, 0x00, 0x30, 0x84, 0xa3, 0x12, 0x36, 0x6c, 0x00, 0x00,
-	0x31, 0x84, 0x68, 0x1b, 0x28, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x12,
-	0x28, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
-	0x34, 0x84, 0xa8, 0x15, 0xe0, 0x31, 0x00, 0x00, 0x5a, 0x84, 0x22, 0x14,
-	0x02, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x14, 0x24, 0xd0, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x14,
-	0x12, 0xc0, 0x01, 0x00, 0x53, 0x84, 0xa2, 0x14, 0x36, 0x50, 0x00, 0x00,
-	0x44, 0x84, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x30, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0x42, 0x84, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x3f, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0x48, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x5c, 0x1f, 0x80, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0xf0, 0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
-	0x2b, 0x80, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40, 0x37, 0x98, 0x01, 0x00,
-	0x49, 0x84, 0x23, 0x01, 0x36, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-	0x36, 0xb0, 0x01, 0x00, 0x54, 0x84, 0x22, 0x1b, 0x02, 0x6c, 0x00, 0x00,
-	0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x5c,
-	0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x15,
-	0xe0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
-	0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0x50, 0x84, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x54, 0x84, 0x00, 0x03, 0x48, 0xb1, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x14, 0x2a, 0xc0, 0x01, 0x00, 0x14, 0x84, 0xa2, 0x40,
-	0x25, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x39, 0xc0, 0x01, 0x00,
-	0x40, 0x00, 0x3d, 0x43, 0x39, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b,
-	0x25, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x12, 0xb0, 0x01, 0x00,
-	0x14, 0x84, 0x00, 0xf0, 0x30, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19,
-	0x42, 0xc9, 0x01, 0x00, 0x60, 0x84, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x19,
-	0x62, 0xdd, 0x01, 0x00, 0x5d, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xb8, 0x92, 0x00, 0x40,
-	0x2b, 0x30, 0x01, 0x00, 0x18, 0x00, 0x2e, 0x03, 0x48, 0xb1, 0x01, 0x00,
-	0x64, 0x84, 0x22, 0x50, 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56,
-	0x17, 0x90, 0x01, 0x00, 0x07, 0x00, 0x00, 0x17, 0x98, 0x88, 0x01, 0x00,
-	0x67, 0x84, 0xa2, 0x41, 0x99, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
-	0x17, 0x90, 0x01, 0x00, 0x6a, 0x84, 0x22, 0x43, 0x2f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x54, 0x17, 0x90, 0x01, 0x00, 0x16, 0x00, 0x20, 0x1d,
-	0xe4, 0xb1, 0x01, 0x00, 0x6c, 0x84, 0xa3, 0x40, 0x27, 0x6c, 0x00, 0x00,
-	0x6e, 0x84, 0x60, 0x5f, 0x17, 0x90, 0x00, 0x00, 0x00, 0x84, 0x00, 0x0b,
-	0x16, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x60, 0x13, 0x16, 0x94, 0x01, 0x00,
-	0x75, 0x94, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0x2a, 0x87, 0xa2, 0x5f,
-	0x2f, 0x7c, 0x00, 0x00, 0x14, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x90, 0x91, 0x00, 0x01,
-	0x38, 0x43, 0x01, 0x00, 0x2a, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4d,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0x62, 0xb1, 0x01, 0x00,
-	0x76, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
-	0x62, 0xb1, 0x01, 0x00, 0x78, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x83, 0x84, 0x22, 0x13, 0x82, 0x6c, 0x00, 0x00, 0x40, 0x00, 0x3d, 0x43,
-	0x83, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x10, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x2c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
-	0x62, 0xb1, 0x01, 0x00, 0x7e, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x08, 0x62, 0xb1, 0x01, 0x00, 0x80, 0x84, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x7a, 0x84, 0x00, 0x41, 0x83, 0xc0, 0x00, 0x00,
-	0x00, 0x00, 0x15, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x82, 0x00, 0xa6,
-	0x04, 0xb0, 0x01, 0x00, 0xa0, 0x98, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x30, 0x05, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00, 0x41, 0x93, 0x00, 0x52,
-	0x95, 0x30, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
-	0x2a, 0x87, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0x01, 0x80, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0e, 0xf4, 0x01, 0x00,
-	0x3f, 0x00, 0x00, 0x00, 0x00, 0x88, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07,
-	0x1a, 0xf4, 0x01, 0x00, 0xd8, 0x92, 0x00, 0x07, 0x16, 0x30, 0x01, 0x00,
-	0x95, 0x84, 0x22, 0x41, 0x81, 0x6c, 0x00, 0x00, 0x93, 0x84, 0x22, 0x42,
-	0x81, 0x6c, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x94, 0x84, 0x22, 0x5f, 0x0f, 0x7c, 0x00, 0x00, 0x14, 0x87, 0x00, 0x40,
-	0x0f, 0xb0, 0x00, 0x00, 0x9d, 0x84, 0xa2, 0x5a, 0x1f, 0x7c, 0x00, 0x00,
-	0x53, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x9d, 0x84, 0x22, 0x20,
-	0x85, 0x6c, 0x00, 0x00, 0x9a, 0x84, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x33, 0x93, 0x00, 0x5c,
-	0x1f, 0x00, 0x01, 0x00, 0x25, 0x95, 0x00, 0x42, 0x61, 0x31, 0x01, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x90, 0x04, 0x00, 0x07,
-	0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x18, 0xb0, 0x01, 0x00, 0xa3, 0x84, 0x22, 0x3a,
-	0x01, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0xb0, 0x01, 0x00,
-	0x7b, 0x88, 0x00, 0x40, 0x01, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x2e, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0xa7, 0x84, 0xa2, 0x40, 0xe7, 0x6d, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x40,
-	0x8f, 0x98, 0x01, 0x00, 0x7b, 0x88, 0x00, 0x40, 0x01, 0xb0, 0x00, 0x00,
-	0x1e, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x05, 0x94, 0x00, 0x95,
-	0x03, 0x30, 0x01, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x22, 0x00, 0x2d, 0xf0,
-	0x2e, 0xb0, 0x01, 0x00, 0x28, 0x20, 0x00, 0xa6, 0x96, 0xb0, 0x01, 0x00,
-	0xb0, 0x84, 0x22, 0x17, 0x96, 0x04, 0x00, 0x00, 0xc9, 0x94, 0x00, 0x4b,
-	0x95, 0x30, 0x01, 0x00, 0x7b, 0x88, 0x00, 0x4c, 0x8f, 0xb0, 0x00, 0x00,
-	0xb2, 0x84, 0x83, 0x17, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x43, 0xc1, 0x01, 0x00, 0xb4, 0x84, 0x85, 0x17, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0x43, 0xc1, 0x01, 0x00, 0x28, 0x00, 0x00, 0xf6,
-	0x02, 0xcc, 0x01, 0x00, 0x12, 0x00, 0x00, 0xa1, 0x2a, 0xc8, 0x01, 0x00,
-	0xd8, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb4, 0x91, 0x00, 0x41,
-	0x81, 0x30, 0x01, 0x00, 0x7b, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0x00, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
-	0x48, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0xf0, 0xb1, 0x01, 0x00, 0xbe, 0x84, 0x64, 0x47, 0x61, 0x31, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0xbf, 0x84, 0xa8, 0x1b,
-	0xe0, 0x31, 0x00, 0x00, 0xaf, 0x82, 0x74, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x03, 0xe0, 0x01, 0x00, 0x08, 0x00, 0x2d, 0x03,
-	0x48, 0xb1, 0x01, 0x00, 0xe4, 0x84, 0x01, 0xfb, 0x08, 0x30, 0x00, 0x00,
-	0x37, 0x85, 0x87, 0xfb, 0x22, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa,
-	0x0e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x14, 0xb0, 0x01, 0x00,
-	0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00, 0xd8, 0x92, 0x00, 0x07,
-	0x16, 0x30, 0x01, 0x00, 0xda, 0x84, 0x22, 0x41, 0x81, 0x6c, 0x00, 0x00,
-	0xce, 0x84, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0xd9, 0x84, 0x22, 0x5f, 0x0f, 0x7c, 0x00, 0x00,
-	0x38, 0x00, 0x00, 0x04, 0x7e, 0x89, 0x01, 0x00, 0xd2, 0x84, 0xa6, 0x5f,
-	0x0f, 0x00, 0x00, 0x00, 0x2c, 0x92, 0x00, 0x40, 0x05, 0x30, 0x01, 0x00,
-	0xd7, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x13, 0x00, 0x00, 0x40,
-	0x87, 0x98, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00,
-	0x0c, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x84, 0xb0, 0x01, 0x00, 0xb7, 0x93, 0x00, 0x40, 0x05, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00, 0x14, 0x87, 0x00, 0x40,
-	0x0f, 0xb0, 0x00, 0x00, 0xe2, 0x84, 0xa2, 0x5a, 0x1f, 0x7c, 0x00, 0x00,
-	0x53, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xe2, 0x84, 0x22, 0x20,
-	0x85, 0x6c, 0x00, 0x00, 0xdf, 0x84, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x33, 0x93, 0x00, 0x5c,
-	0x1f, 0x00, 0x01, 0x00, 0x25, 0x95, 0x00, 0x42, 0x61, 0x31, 0x01, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x90, 0x04, 0x00, 0x07,
-	0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x18, 0xb0, 0x01, 0x00, 0xe6, 0x84, 0x21, 0x04,
-	0x80, 0x20, 0x00, 0x00, 0xe7, 0x84, 0x00, 0x40, 0x10, 0xc9, 0x00, 0x00,
-	0xbd, 0x87, 0x00, 0x4b, 0x81, 0xb0, 0x00, 0x00, 0x06, 0x85, 0x00, 0x43,
-	0x81, 0xb0, 0x00, 0x00, 0x0a, 0x85, 0x00, 0xfb, 0x22, 0xb0, 0x00, 0x00,
-	0xbd, 0x87, 0x00, 0x41, 0x81, 0xb0, 0x00, 0x00, 0x7b, 0x88, 0x00, 0x4e,
-	0x8f, 0xb0, 0x00, 0x00, 0x02, 0x85, 0x00, 0x5a, 0x8f, 0xb0, 0x00, 0x00,
-	0xef, 0x84, 0x00, 0x47, 0x8f, 0xb0, 0x00, 0x00, 0xbd, 0x87, 0x00, 0x53,
-	0x81, 0xb0, 0x00, 0x00, 0xbd, 0x87, 0x00, 0x56, 0x81, 0xb0, 0x00, 0x00,
-	0x32, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x7b, 0x88, 0xa0, 0x0a,
-	0xe4, 0x6d, 0x00, 0x00, 0xf5, 0x84, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0xf4, 0x84, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00, 0x7b, 0x88, 0x00, 0x53,
-	0x8f, 0xb0, 0x00, 0x00, 0x7b, 0x88, 0x00, 0x54, 0x8f, 0xb0, 0x00, 0x00,
-	0xfe, 0x84, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00, 0xf8, 0x84, 0xa2, 0x0a,
-	0xe4, 0x6d, 0x00, 0x00, 0x7b, 0x88, 0x00, 0x5d, 0x8f, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xf2, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a,
-	0x80, 0xd0, 0x01, 0x00, 0xfc, 0x84, 0xa0, 0x91, 0x81, 0x6c, 0x00, 0x00,
-	0x7b, 0x88, 0x00, 0x5e, 0x8f, 0xb0, 0x00, 0x00, 0x25, 0x00, 0x00, 0x40,
-	0x8f, 0x98, 0x01, 0x00, 0x7b, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x85, 0x20, 0x91, 0xe5, 0x6d, 0x00, 0x00, 0x7b, 0x88, 0x00, 0x54,
-	0x8f, 0xb0, 0x00, 0x00, 0x21, 0x00, 0x00, 0x40, 0x8f, 0x98, 0x01, 0x00,
-	0x7b, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x32, 0x00, 0x2d, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x7b, 0x88, 0xa0, 0x0a, 0xe4, 0x6d, 0x00, 0x00,
-	0x24, 0x00, 0x00, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x7b, 0x88, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0xf3, 0x82, 0xf4, 0x01, 0x00, 0xbd, 0x87, 0xa0, 0x42,
-	0x83, 0x6c, 0x00, 0x00, 0xbd, 0x87, 0x00, 0x54, 0x81, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xf2, 0x0e, 0xb0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07,
-	0x1a, 0xf4, 0x01, 0x00, 0x00, 0xb5, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00,
-	0x07, 0x00, 0x00, 0x07, 0x16, 0x88, 0x01, 0x00, 0x13, 0x85, 0x22, 0x0b,
-	0xe6, 0x7d, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
-	0xc6, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x0f, 0xb0, 0x01, 0x00, 0x14, 0x87, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00,
-	0x25, 0x85, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00, 0x20, 0x85, 0xa2, 0x54,
-	0xfd, 0x7f, 0x00, 0x00, 0x18, 0x85, 0x22, 0x55, 0xfd, 0x7f, 0x00, 0x00,
-	0x82, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0x10, 0x85, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x10, 0x85, 0x22, 0x53, 0xfd, 0x7f, 0x00, 0x00,
-	0x14, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x96, 0xb0, 0x01, 0x00, 0x10, 0x00, 0x00, 0x4b, 0x80, 0xf4, 0x01, 0x00,
-	0x0c, 0xbc, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0x20, 0x85, 0x22, 0x43,
-	0x80, 0x6c, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4b, 0x80, 0x88, 0x01, 0x00,
-	0x10, 0x85, 0xa2, 0x43, 0x80, 0x6c, 0x00, 0x00, 0x7c, 0x96, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x21, 0x85, 0x46, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x24, 0x85, 0xa0, 0xf0, 0x30, 0x6f, 0x00, 0x00, 0x16, 0x85, 0x1e, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x41, 0x31, 0xc3, 0x01, 0x00,
-	0x5d, 0x92, 0x00, 0x40, 0x25, 0x30, 0x01, 0x00, 0x29, 0x85, 0x9c, 0x0f,
-	0x80, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x33, 0x93, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x14, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x96, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x07,
-	0x18, 0xe4, 0x01, 0x00, 0x00, 0x08, 0x00, 0x0c, 0xe0, 0x99, 0x01, 0x00,
-	0x90, 0x04, 0x00, 0x07, 0x96, 0x30, 0x01, 0x00, 0x00, 0xb5, 0x00, 0x0d,
-	0x46, 0xc9, 0x01, 0x00, 0x30, 0x85, 0x30, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x0b, 0xe6, 0x91, 0x01, 0x00, 0x00, 0x02, 0x00, 0xa1,
-	0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x91, 0x01, 0x00,
-	0x04, 0x00, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40,
-	0xe1, 0xb1, 0x01, 0x00, 0xbd, 0x87, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xfb, 0x28, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
-	0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x14, 0xb0, 0x01, 0x00,
-	0x41, 0x85, 0x22, 0x46, 0x23, 0x7c, 0x00, 0x00, 0x3d, 0x85, 0x22, 0x40,
-	0x87, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x1f, 0x90, 0x01, 0x00,
-	0x3f, 0x85, 0x22, 0x41, 0x87, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0x1f, 0x90, 0x01, 0x00, 0x41, 0x85, 0x22, 0x42, 0x87, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x1f, 0x90, 0x01, 0x00, 0x41, 0x85, 0x66, 0x1b,
-	0x2c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x13, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x76, 0x41, 0x41, 0xc3, 0x01, 0x00, 0x70, 0x85, 0x23, 0x92,
-	0x15, 0x6c, 0x00, 0x00, 0x70, 0x85, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00,
-	0x74, 0x85, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0x17, 0x00, 0x00, 0xd0,
-	0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x27, 0xb0, 0x01, 0x00,
-	0x02, 0x00, 0x00, 0x0a, 0x24, 0xc8, 0x01, 0x00, 0x94, 0x92, 0x00, 0x40,
-	0x0f, 0x30, 0x01, 0x00, 0x6e, 0x85, 0x22, 0x08, 0x40, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x12,
-	0x24, 0xcc, 0x01, 0x00, 0x4a, 0x85, 0xaa, 0x41, 0x27, 0x40, 0x00, 0x00,
-	0x01, 0x00, 0x00, 0x13, 0x80, 0xcc, 0x01, 0x00, 0x6a, 0x85, 0x26, 0x40,
-	0x23, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00,
-	0x60, 0x00, 0x00, 0x03, 0x84, 0xc8, 0x01, 0x00, 0x10, 0x00, 0x00, 0x10,
-	0x48, 0xcd, 0x01, 0x00, 0x17, 0x00, 0x00, 0xd0, 0xa2, 0xc9, 0x01, 0x00,
-	0x57, 0x85, 0xa2, 0x40, 0x83, 0x6c, 0x00, 0x00, 0x63, 0x85, 0x00, 0x41,
-	0x83, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x42, 0x44, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x68, 0x21, 0x38, 0x96, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x50,
-	0x49, 0xc1, 0x01, 0x00, 0x5c, 0x85, 0xa2, 0x44, 0x23, 0x6c, 0x00, 0x00,
-	0x30, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0xf1, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x20, 0xf0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
-	0x62, 0xdd, 0x01, 0x00, 0x5f, 0x85, 0xa8, 0x42, 0xe0, 0x31, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x85, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00,
-	0x55, 0x85, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x6a, 0x85, 0x22, 0x40,
-	0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x67, 0x85, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0x48, 0xb1, 0x01, 0x00, 0xee, 0x07, 0x00, 0x40,
-	0x25, 0x98, 0x01, 0x00, 0x17, 0x00, 0x00, 0xd0, 0x2a, 0xc8, 0x01, 0x00,
-	0x7d, 0x85, 0x00, 0x17, 0x10, 0xb0, 0x00, 0x00, 0x7e, 0x94, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x74, 0x85, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x94, 0x92, 0x00, 0x92, 0x25, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x31, 0xb0, 0x01, 0x00, 0x74, 0x85, 0x22, 0x08, 0x2e, 0x30, 0x00, 0x00,
-	0x7d, 0x85, 0x00, 0x41, 0x27, 0xb0, 0x00, 0x00, 0x80, 0x80, 0x00, 0xa6,
-	0x04, 0xb0, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
-	0xc6, 0x95, 0x00, 0x0a, 0x8c, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x0f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
-	0x7c, 0x85, 0x22, 0x9f, 0x13, 0x6c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x88,
-	0x1c, 0xcc, 0x01, 0x00, 0xf5, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x14, 0x87, 0x00, 0x41, 0x3f, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x0f, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x00, 0x01, 0x80, 0xce, 0x01, 0x00,
-	0x91, 0x85, 0x2a, 0x40, 0x81, 0x30, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x44, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
-	0x86, 0x85, 0xa2, 0x48, 0x1f, 0x7c, 0x00, 0x00, 0x86, 0x85, 0xa2, 0x47,
-	0x1f, 0x7c, 0x00, 0x00, 0x86, 0x85, 0xa3, 0x07, 0x03, 0x6c, 0x00, 0x00,
-	0x80, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x89, 0x85, 0xa3, 0x40,
-	0x02, 0x6c, 0x00, 0x00, 0x28, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00,
-	0x8b, 0x85, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40,
-	0xf0, 0xcd, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x0e, 0xcc, 0x01, 0x00,
-	0x28, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00, 0x28, 0x00, 0x00, 0x00,
-	0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0xe0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x8f, 0x85, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x08, 0xb0, 0x01, 0x00, 0xa0, 0x01, 0x2d, 0x40, 0x00, 0xc0, 0x01, 0x00,
-	0x5b, 0x86, 0x22, 0x0f, 0x42, 0x05, 0x00, 0x00, 0xa2, 0x85, 0x9c, 0x0f,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x9d, 0x85, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x9a, 0x85, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0xa2, 0x85, 0x22, 0x07, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0x42, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x42, 0xc1, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0xa1, 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0xe1, 0x91, 0x01, 0x00, 0xc0, 0x06, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00,
-	0x10, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x54,
-	0x29, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x0e, 0xb0, 0x01, 0x00, 0x42, 0x00, 0x00, 0x03, 0x0a, 0xc8, 0x01, 0x00,
-	0x0c, 0x00, 0x00, 0xa4, 0x0c, 0xc8, 0x01, 0x00, 0xd6, 0x92, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0x02, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x14, 0x24, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14,
-	0x10, 0xc0, 0x01, 0x00, 0x12, 0x00, 0x00, 0x08, 0x10, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00, 0xfe, 0x7f, 0x00, 0x05,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xe4, 0xb1, 0x01, 0x00,
-	0xcb, 0x85, 0x22, 0x01, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44,
-	0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0xa4, 0x80, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x48, 0xc1, 0x01, 0x00, 0xb8, 0x85, 0xa3, 0x07,
-	0x02, 0x6c, 0x00, 0x00, 0xb9, 0x85, 0x68, 0x01, 0x1a, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x68, 0x07, 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d,
-	0x02, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
-	0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0a, 0xc0, 0x01, 0x00,
-	0xc5, 0x85, 0x22, 0x40, 0x03, 0x6c, 0x00, 0x00, 0xc5, 0x85, 0x22, 0x42,
-	0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
-	0x62, 0xdd, 0x01, 0x00, 0xe9, 0x85, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xc2, 0x85, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x80, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x62, 0xb1, 0x01, 0x00, 0xc7, 0x85, 0xa8, 0x40,
-	0x23, 0x30, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0xe9, 0x85, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44,
-	0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x86, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x2e, 0x10, 0x48, 0xc1, 0x01, 0x00, 0xd0, 0x85, 0xa3, 0x12,
-	0x0e, 0x6c, 0x00, 0x00, 0xd1, 0x85, 0x60, 0x07, 0x1a, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x60, 0x12, 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x68, 0x0d,
-	0x16, 0x94, 0x01, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x16, 0xd8, 0x01, 0x00,
-	0x00, 0x00, 0x68, 0x08, 0x3e, 0x96, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00,
-	0xd8, 0x85, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00, 0x07, 0x86, 0x22, 0x0d,
-	0x14, 0x6c, 0x00, 0x00, 0xde, 0x85, 0x22, 0x0d, 0x24, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x0d, 0x10, 0xc0, 0x01, 0x00, 0xe2, 0x85, 0x00, 0x0d,
-	0x24, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x2b, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x15, 0xa2, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x20,
-	0x10, 0xc8, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40, 0x25, 0x98, 0x01, 0x00,
-	0xe4, 0x85, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00, 0xe9, 0x85, 0x00, 0x41,
-	0x23, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xe5, 0x85, 0xa8, 0x5c,
-	0x1f, 0x00, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00, 0x07, 0x86, 0x22, 0x0d,
-	0x14, 0x50, 0x00, 0x00, 0x06, 0x86, 0xa2, 0x0d, 0x0e, 0x50, 0x00, 0x00,
-	0xf5, 0x85, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0x1f, 0x80, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
-	0xf3, 0x85, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0xf0, 0x85, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03, 0x46, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x06,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00, 0xfa, 0x85, 0x1f, 0xf0,
-	0x0e, 0x30, 0x00, 0x00, 0xb2, 0x85, 0x00, 0x4c, 0x0d, 0xc0, 0x00, 0x00,
-	0x00, 0x00, 0x2e, 0x5f, 0x0f, 0x80, 0x01, 0x00, 0xb2, 0x85, 0x23, 0x07,
-	0x14, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00,
-	0x24, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00, 0x24, 0x00, 0x00, 0x00,
-	0x00, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
-	0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0x03, 0x86, 0xa8, 0x46,
-	0x1f, 0x10, 0x00, 0x00, 0xb2, 0x85, 0x00, 0x03, 0x0c, 0xb0, 0x00, 0x00,
-	0xb2, 0x85, 0x00, 0x0d, 0x18, 0xc0, 0x00, 0x00, 0x04, 0x00, 0x2e, 0x14,
-	0x0a, 0xd0, 0x01, 0x00, 0x12, 0x00, 0x00, 0x05, 0x48, 0xcd, 0x01, 0x00,
-	0xfe, 0x7f, 0x00, 0x05, 0x42, 0xc9, 0x01, 0x00, 0x0c, 0x00, 0x2a, 0xf2,
-	0xe0, 0xb1, 0x01, 0x00, 0x0d, 0x86, 0x22, 0x40, 0x31, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x60, 0x18, 0x38, 0x96, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x00, 0x81, 0x00, 0xf6, 0x80, 0xce, 0x01, 0x00,
-	0x11, 0x86, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x43, 0xc1, 0x01, 0x00, 0x13, 0x86, 0x22, 0x0b, 0xed, 0x6d, 0x00, 0x00,
-	0x08, 0x00, 0x00, 0xa1, 0x42, 0xc9, 0x01, 0x00, 0x02, 0x00, 0x00, 0xa1,
-	0x46, 0xc9, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xfa, 0x94, 0x88, 0x01, 0x00,
-	0x02, 0x00, 0x00, 0x4a, 0x86, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6,
-	0x0e, 0xb0, 0x01, 0x00, 0x1b, 0x86, 0x22, 0x47, 0x1f, 0x7c, 0x00, 0x00,
-	0x04, 0x00, 0x1f, 0x43, 0x0e, 0x50, 0x00, 0x00, 0x1b, 0x86, 0xa0, 0x46,
-	0x0f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0f, 0xc0, 0x01, 0x00,
-	0x1f, 0x86, 0x22, 0x48, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x91, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x0f, 0xa2, 0x42, 0x31, 0x00, 0x00,
-	0x22, 0x86, 0x00, 0x40, 0x89, 0xb0, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xa2,
-	0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x89, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x95, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
-	0x82, 0xb0, 0x01, 0x00, 0x25, 0x86, 0xa0, 0x41, 0x90, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x91, 0xc0, 0x01, 0x00, 0x2a, 0x86, 0x22, 0x47,
-	0x1f, 0x7c, 0x00, 0x00, 0x2a, 0x86, 0xa0, 0x43, 0x89, 0x6c, 0x00, 0x00,
-	0x2a, 0x86, 0x20, 0x45, 0x89, 0x6c, 0x00, 0x00, 0x2a, 0x86, 0xa0, 0x41,
-	0x0e, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0f, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x89, 0xc0, 0x01, 0x00, 0x22, 0x86, 0xa2, 0x41,
-	0x95, 0x50, 0x00, 0x00, 0x33, 0x86, 0x22, 0x48, 0x1f, 0x7c, 0x00, 0x00,
-	0x10, 0x00, 0x00, 0x48, 0x92, 0xf4, 0x01, 0x00, 0xff, 0xff, 0x00, 0x48,
-	0x90, 0x88, 0x01, 0x00, 0x31, 0x86, 0x90, 0x48, 0x92, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00, 0x0a, 0x00, 0x00, 0xa2,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20, 0x93, 0xa4, 0x01, 0x00,
-	0x30, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x12, 0x00, 0x00, 0x14,
-	0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x17, 0xf0, 0xb1, 0x01, 0x00,
-	0x12, 0x00, 0x00, 0x05, 0xe0, 0xcd, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10,
-	0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x40, 0x62, 0xdd, 0x01, 0x00, 0x39, 0x86, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x44, 0x86, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x10,
-	0x48, 0xc1, 0x01, 0x00, 0x43, 0x86, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x40, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
-	0x1f, 0x80, 0x01, 0x00, 0x47, 0x86, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00,
-	0xcc, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc0, 0x86, 0x00, 0x17,
-	0x10, 0xb0, 0x00, 0x00, 0xd3, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x2f, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x4b, 0x86, 0xa0, 0x07,
-	0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0b, 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x17, 0xf0, 0x01, 0x00, 0x4f, 0x86, 0x90, 0xf2, 0x16, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20,
-	0x17, 0xa4, 0x01, 0x00, 0x10, 0x00, 0x00, 0x14, 0x2a, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x2b, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
-	0x2a, 0x94, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
-	0x59, 0x86, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x56, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x17, 0x10, 0xdc, 0x01, 0x00,
-	0xc0, 0x86, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x63, 0x86, 0x9c, 0x0f,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x63, 0x86, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x60, 0x86, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x68, 0x86, 0x22, 0x07, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0x42, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x42, 0xc1, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0xa1, 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
-	0xe1, 0x91, 0x01, 0x00, 0x04, 0x00, 0x2e, 0x03, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0a, 0xe0, 0xb1, 0x01, 0x00, 0x6d, 0x86, 0x22, 0x40,
-	0x31, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x60, 0x18, 0x38, 0x96, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x72, 0x86, 0xa8, 0x40,
-	0x23, 0x30, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x2d, 0x52, 0x11, 0xc0, 0x01, 0x00, 0x10, 0x00, 0x00, 0x03,
-	0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x0e, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xa4, 0x0c, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4,
-	0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xc1, 0x01, 0x00,
-	0x80, 0x86, 0xa3, 0x12, 0x0e, 0x6c, 0x00, 0x00, 0x81, 0x86, 0x68, 0x07,
-	0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x12, 0x1a, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x68, 0x08,
-	0x3e, 0x96, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00,
-	0x86, 0x86, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00, 0xb5, 0x86, 0x22, 0x0d,
-	0x14, 0x6c, 0x00, 0x00, 0x8c, 0x86, 0x22, 0x0d, 0x24, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x0d, 0x10, 0xc0, 0x01, 0x00, 0x90, 0x86, 0x00, 0x0d,
-	0x24, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x2b, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x15, 0xa2, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x20,
-	0x10, 0xc8, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40, 0x25, 0x98, 0x01, 0x00,
-	0x92, 0x86, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00, 0x97, 0x86, 0x00, 0x41,
-	0x23, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x93, 0x86, 0xa8, 0x5c,
-	0x1f, 0x00, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x0d,
-	0x14, 0x50, 0x00, 0x00, 0xb4, 0x86, 0xa2, 0x0d, 0x0e, 0x50, 0x00, 0x00,
-	0xa3, 0x86, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0x1f, 0x80, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
-	0xa1, 0x86, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x9e, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03, 0x46, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x06,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00, 0xa8, 0x86, 0x1f, 0xf0,
-	0x0e, 0x30, 0x00, 0x00, 0x7b, 0x86, 0x00, 0x4c, 0x0d, 0xc0, 0x00, 0x00,
-	0x00, 0x00, 0x2e, 0x5f, 0x0f, 0x80, 0x01, 0x00, 0x7b, 0x86, 0x23, 0x07,
-	0x14, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00,
-	0x24, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00, 0x24, 0x00, 0x00, 0x00,
-	0x00, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
-	0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0xb1, 0x86, 0xa8, 0x46,
-	0x1f, 0x10, 0x00, 0x00, 0x7b, 0x86, 0x00, 0x03, 0x0c, 0xb0, 0x00, 0x00,
-	0x7b, 0x86, 0x00, 0x0d, 0x18, 0xc0, 0x00, 0x00, 0xbe, 0x86, 0x22, 0x5c,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00,
-	0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x10,
-	0x48, 0xc1, 0x01, 0x00, 0xbe, 0x86, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0xbb, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17,
-	0x10, 0xb0, 0x01, 0x00, 0xc0, 0x86, 0x00, 0x40, 0x2b, 0xb0, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x03, 0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04,
-	0xe0, 0xb1, 0x01, 0x00, 0xc5, 0x86, 0x22, 0x9f, 0x13, 0x6c, 0x00, 0x00,
-	0x02, 0x00, 0x00, 0x88, 0x1c, 0xcc, 0x01, 0x00, 0xf5, 0x82, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xd7, 0x95, 0x00, 0x41, 0x3f, 0x43, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x8d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x05, 0xb0, 0x01, 0x00, 0xc6, 0x95, 0x00, 0x40, 0x0f, 0x30, 0x01, 0x00,
-	0x2a, 0x87, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
-	0x0e, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x01, 0x84, 0x01, 0x00,
-	0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00, 0xd8, 0x92, 0x00, 0x07,
-	0x16, 0x30, 0x01, 0x00, 0xd4, 0x86, 0x22, 0x41, 0x81, 0x6c, 0x00, 0x00,
-	0xd2, 0x86, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0xd3, 0x86, 0x22, 0x5f, 0x0f, 0x7c, 0x00, 0x00,
-	0x14, 0x87, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00, 0xdc, 0x86, 0xa2, 0x5a,
-	0x1f, 0x7c, 0x00, 0x00, 0x53, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xdc, 0x86, 0x22, 0x20, 0x85, 0x6c, 0x00, 0x00, 0xd9, 0x86, 0x9c, 0x0f,
-	0x80, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x33, 0x93, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x25, 0x95, 0x00, 0x42,
-	0x61, 0x31, 0x01, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x90, 0x04, 0x00, 0x07, 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x18, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x80, 0xb0, 0x01, 0x00, 0xbd, 0x87, 0xa2, 0x5f,
-	0x81, 0x6c, 0x00, 0x00, 0xa8, 0x00, 0x2d, 0x43, 0x19, 0x80, 0x01, 0x00,
-	0x37, 0x00, 0x2d, 0xf0, 0x24, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3,
-	0x8e, 0xf4, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3, 0x90, 0x88, 0x01, 0x00,
-	0xeb, 0x86, 0x22, 0x48, 0x8e, 0x6c, 0x00, 0x00, 0x36, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x58, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00,
-	0xeb, 0x86, 0x1f, 0xf0, 0x24, 0x6c, 0x00, 0x00, 0xea, 0x86, 0x23, 0x41,
-	0x8f, 0x6c, 0x00, 0x00, 0xbd, 0x87, 0x00, 0x47, 0x81, 0xb0, 0x00, 0x00,
-	0xbd, 0x87, 0x00, 0x48, 0x81, 0xb0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0xb0, 0x00, 0x2d, 0xf0, 0x14, 0xb0, 0x01, 0x00,
-	0xf0, 0x86, 0x22, 0x0a, 0x90, 0x40, 0x00, 0x00, 0xaa, 0x95, 0x00, 0x40,
-	0x91, 0x30, 0x01, 0x00, 0xbd, 0x87, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00,
-	0xb0, 0x00, 0x2d, 0x45, 0x81, 0xb0, 0x01, 0x00, 0xfc, 0x86, 0x22, 0xf0,
-	0x2c, 0x30, 0x00, 0x00, 0xa3, 0x00, 0x2d, 0x30, 0x83, 0xb0, 0x01, 0x00,
-	0xac, 0x00, 0x2d, 0xf3, 0x82, 0xe0, 0x01, 0x00, 0xf6, 0x86, 0xa3, 0x41,
-	0x2c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x82, 0xb0, 0x01, 0x00,
-	0x98, 0x00, 0x2d, 0xf0, 0x82, 0xc0, 0x01, 0x00, 0x88, 0x00, 0x2d, 0xf0,
-	0x82, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x98, 0xe8, 0x01, 0x00,
-	0xbd, 0x87, 0x20, 0x4c, 0x82, 0x6c, 0x00, 0x00, 0x7c, 0x00, 0x2d, 0x41,
-	0x98, 0xe8, 0x01, 0x00, 0xbd, 0x87, 0x20, 0xf0, 0x98, 0x6c, 0x00, 0x00,
-	0x14, 0x87, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00, 0x40, 0x02, 0x00, 0x0c,
-	0x7e, 0x89, 0x01, 0x00, 0x14, 0x87, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xbd, 0x87, 0x00, 0x49, 0x81, 0xb0, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6,
-	0x80, 0xb0, 0x01, 0x00, 0x04, 0x87, 0x22, 0x43, 0x21, 0x6f, 0x00, 0x00,
-	0x13, 0x80, 0x00, 0x40, 0x80, 0xdc, 0x01, 0x00, 0x05, 0x87, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x1a, 0x80, 0x00, 0x40, 0x80, 0xdc, 0x01, 0x00,
-	0x05, 0x87, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x08, 0xb1, 0x01, 0x00, 0x07, 0x87, 0x9f, 0x85, 0x80, 0x32, 0x00, 0x00,
-	0x0b, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xec, 0x82, 0x22, 0x40,
-	0x57, 0x7d, 0x00, 0x00, 0x01, 0x00, 0x00, 0x40, 0x57, 0x99, 0x01, 0x00,
-	0x0b, 0x87, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x93, 0x93, 0x01, 0x00, 0xdd, 0x82, 0x1a, 0x5b, 0x69, 0x93, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0xcb, 0x81, 0xc8, 0x01, 0x00, 0x11, 0x87, 0x22, 0x40,
-	0xf2, 0x7f, 0x00, 0x00, 0xc4, 0x80, 0x00, 0x6f, 0x97, 0x33, 0x01, 0x00,
-	0x13, 0x87, 0x22, 0x40, 0x73, 0x7d, 0x00, 0x00, 0xde, 0x80, 0x00, 0x41,
-	0x8b, 0xb3, 0x00, 0x00, 0x0e, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x1b, 0x87, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0x1b, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x18, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x2f, 0x92, 0x22, 0x02,
-	0x80, 0x32, 0x00, 0x00, 0x1c, 0x87, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00, 0x2f, 0x92, 0x1a, 0x02,
-	0x68, 0x97, 0x00, 0x00, 0x26, 0x87, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x26, 0x87, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x23, 0x87, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x39, 0x92, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00, 0x27, 0x87, 0x42, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
-	0x39, 0x92, 0x1a, 0x02, 0x68, 0x97, 0x00, 0x00, 0x31, 0x87, 0x9c, 0x0f,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
-	0x31, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x2e, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0xf9, 0x82, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00,
-	0x32, 0x87, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x93, 0x93, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x02, 0x68, 0x97, 0x01, 0x00,
-	0xf9, 0x82, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0xa6,
-	0x56, 0xb1, 0x01, 0x00, 0x56, 0x95, 0x2f, 0x40, 0x05, 0xb0, 0x01, 0x00,
-	0x82, 0x87, 0xa2, 0x40, 0xe7, 0x6d, 0x00, 0x00, 0xb8, 0x94, 0x29, 0x41,
-	0xe7, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0xef, 0x93, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf2, 0x0e, 0xb0, 0x01, 0x00, 0x29, 0x00, 0x00, 0x40,
-	0x0d, 0x98, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07, 0x12, 0xe4, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xa7, 0x13, 0xc0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07,
-	0x1a, 0xf4, 0x01, 0x00, 0x07, 0x00, 0x00, 0x07, 0x16, 0x88, 0x01, 0x00,
-	0xff, 0xff, 0x00, 0x10, 0x34, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0x34, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
-	0x20, 0x18, 0x00, 0x40, 0x11, 0x98, 0x01, 0x00, 0x00, 0xb5, 0x00, 0x0d,
-	0x42, 0xc9, 0x01, 0x00, 0x66, 0x87, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
-	0x47, 0x87, 0x60, 0x40, 0x81, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0x07,
-	0x84, 0x89, 0x01, 0x00, 0x4e, 0x87, 0x05, 0xc2, 0x24, 0x30, 0x00, 0x00,
-	0x58, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x83, 0x87, 0x70, 0xf0, 0x18, 0x30, 0x01, 0x00,
-	0x66, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x70, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x5d, 0x87, 0xa0, 0x48, 0x23, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x35, 0xd0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x1a,
-	0x42, 0xc9, 0x01, 0x00, 0x57, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x1a,
-	0x62, 0xdd, 0x01, 0x00, 0x54, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x83, 0x87, 0x00, 0xf8, 0x18, 0x30, 0x01, 0x00,
-	0x58, 0x87, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00, 0xff, 0xff, 0x00, 0x10,
-	0x34, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x34, 0x94, 0x01, 0x00,
-	0x20, 0x18, 0x00, 0x40, 0x11, 0x98, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x1a,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x1a, 0x62, 0xdd, 0x01, 0x00,
-	0x61, 0x87, 0xa8, 0x09, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x35, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x11, 0xc0, 0x01, 0x00, 0x72, 0x87, 0x22, 0x41,
-	0x0d, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0f, 0xc0, 0x01, 0x00,
-	0x6e, 0x87, 0xa0, 0xaa, 0x0f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x0f, 0xb0, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07, 0x12, 0xe4, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xa7, 0x13, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x1b, 0xb0, 0x01, 0x00, 0x45, 0x87, 0x00, 0x41, 0x17, 0xb0, 0x00, 0x00,
-	0x00, 0x02, 0x00, 0x09, 0x12, 0xc8, 0x01, 0x00, 0x45, 0x87, 0x83, 0x41,
-	0x17, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00,
-	0x45, 0x87, 0x00, 0x41, 0x1b, 0xc0, 0x00, 0x00, 0x7d, 0x87, 0x23, 0x40,
-	0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x35, 0xd0, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x1a, 0x42, 0xc9, 0x01, 0x00, 0x7a, 0x87, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x1a, 0x62, 0xdd, 0x01, 0x00, 0x77, 0x87, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x20, 0x98, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x83, 0x87, 0x00, 0xf8,
-	0x18, 0x30, 0x01, 0x00, 0x7b, 0x87, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x0f, 0xc0, 0x01, 0x00, 0x80, 0x87, 0xa0, 0xaa,
-	0x0f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0f, 0xb0, 0x01, 0x00,
-	0xb8, 0x94, 0x20, 0x07, 0xe4, 0xb1, 0x01, 0x00, 0x56, 0x95, 0x20, 0x40,
-	0xe7, 0xb1, 0x01, 0x00, 0x14, 0x87, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00,
-	0xff, 0xff, 0x00, 0x0c, 0x80, 0xd8, 0x01, 0x00, 0xc0, 0x02, 0x00, 0x0c,
-	0x7e, 0x89, 0x01, 0x00, 0x95, 0x87, 0x26, 0x54, 0x61, 0x31, 0x00, 0x00,
-	0x8b, 0x87, 0x87, 0x0c, 0x80, 0x32, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x40,
-	0x62, 0x99, 0x01, 0x00, 0x8b, 0x87, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x8b, 0x87, 0xa2, 0x54, 0x77, 0x7d, 0x00, 0x00, 0x87, 0x87, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x90, 0x87, 0x22, 0x46, 0x19, 0x7c, 0x00, 0x00,
-	0x0d, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x01, 0x00,
-	0x8c, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x95, 0x87, 0x22, 0x49,
-	0x19, 0x7c, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x54,
-	0x77, 0x7d, 0x01, 0x00, 0x90, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x10, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x01, 0x00,
-	0x95, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x30, 0x94, 0x2f, 0x55,
-	0xf1, 0x93, 0x01, 0x00, 0x00, 0x40, 0x00, 0xa6, 0x56, 0xb1, 0x01, 0x00,
-	0xf9, 0x82, 0xa2, 0x41, 0xe5, 0x51, 0x00, 0x00, 0x64, 0x00, 0x00, 0x40,
-	0xe5, 0x99, 0x01, 0x00, 0x9d, 0x87, 0x44, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xa0, 0x87, 0xa2, 0x93, 0x57, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x57, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x1c, 0xab, 0x27, 0xb3, 0x01, 0x00,
-	0xf9, 0x82, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00, 0xf9, 0x82, 0x22, 0x51,
-	0xfd, 0x7f, 0x00, 0x00, 0xf9, 0x82, 0xa2, 0x41, 0x1d, 0x53, 0x00, 0x00,
-	0x50, 0x46, 0x00, 0x40, 0x1d, 0x9b, 0x01, 0x00, 0x38, 0x05, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0x10, 0x04, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00, 0xac, 0x87, 0x22, 0x40,
-	0xb5, 0x6f, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0x20, 0x04, 0x00, 0x41, 0xb5, 0x53, 0x01, 0x00, 0xf9, 0x82, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0xfd, 0x83, 0x01, 0x00,
-	0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x40, 0x05, 0x00, 0x40,
-	0x49, 0x31, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
-	0x91, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
-	0x20, 0x04, 0x00, 0x40, 0xb5, 0x33, 0x01, 0x00, 0x60, 0x16, 0x20, 0x40,
-	0xe5, 0xb1, 0x01, 0x00, 0x40, 0x82, 0x00, 0x40, 0xb5, 0x33, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xff, 0xff, 0x00, 0x4a,
-	0xb4, 0x8b, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x0a, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x00, 0x00, 0x4a,
-	0xb4, 0xf7, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xf9, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x05, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x08, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0x20, 0x40, 0xe6, 0xb1, 0x01, 0x00, 0x03, 0x00, 0x00, 0x40,
-	0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x96, 0xc0, 0x01, 0x00,
-	0xc3, 0x87, 0x00, 0x4b, 0x10, 0xc9, 0x00, 0x00, 0xe6, 0x8a, 0x00, 0x41,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x1a, 0x8b, 0x00, 0x41,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x4c, 0x8b, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x4c, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x4c, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x4c, 0x8b, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x8b, 0x8b, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xb4, 0x8b, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0xb8, 0x8b, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
-	0x03, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0xc4, 0x8b, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xc3, 0x8b, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x73, 0x8c, 0x00, 0x42,
-	0x09, 0xb0, 0x00, 0x00, 0x73, 0x8c, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0x73, 0x8c, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x93, 0x8c, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0xb1, 0x8c, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xb1, 0x8c, 0x00, 0x44,
-	0x09, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0xb1, 0x8c, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xd9, 0x8c, 0x00, 0x44,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
-	0xea, 0x8c, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0xea, 0x8c, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xec, 0x8c, 0x00, 0x42,
-	0x09, 0xb0, 0x00, 0x00, 0xec, 0x8c, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0xec, 0x8c, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xec, 0x8c, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0xf4, 0x8c, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
-	0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x05, 0x8d, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
-	0xf5, 0x8c, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x05, 0x8d, 0x00, 0x44,
-	0x09, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x06, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0xfc, 0x8c, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00,
-	0x71, 0x8c, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x71, 0x8c, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0x71, 0x8c, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
-	0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x41,
-	0x09, 0xb0, 0x00, 0x00, 0x07, 0x8d, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
-	0x07, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x07, 0x8d, 0x00, 0x44,
-	0x09, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x0e, 0x8d, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x10, 0x8d, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x1c, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0x7b, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xb8, 0x8b, 0x00, 0x44,
-	0x09, 0xb0, 0x00, 0x00, 0x03, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x83, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0xb8, 0x8b, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x03, 0x8d, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x94, 0x8d, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x88, 0x8b, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0x7f, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xb8, 0x8b, 0x00, 0x44,
-	0x09, 0xb0, 0x00, 0x00, 0x03, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x8f, 0xb0, 0x00, 0x00, 0x07, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf3, 0x08, 0xb0, 0x01, 0x00, 0x06, 0x00, 0x20, 0x47,
-	0xe6, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x47, 0x96, 0xe4, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x96, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0x96, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x96, 0xc0, 0x01, 0x00,
-	0x83, 0x88, 0x00, 0x4b, 0x10, 0xc9, 0x00, 0x00, 0xac, 0x8d, 0x00, 0x49,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xe5, 0x8d, 0x00, 0x42,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xeb, 0x8d, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xf9, 0x8d, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x1a, 0x8e, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x15, 0x8e, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x1d, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x75, 0x8e, 0x00, 0x44,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x74, 0x8e, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xee, 0x8d, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xee, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0xee, 0x8d, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xee, 0x8d, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0xee, 0x8d, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
-	0xee, 0x8d, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0xee, 0x8d, 0x00, 0x48,
-	0x09, 0xb0, 0x00, 0x00, 0xee, 0x8d, 0x00, 0x49, 0x09, 0xb0, 0x00, 0x00,
-	0xee, 0x8d, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0xee, 0x8d, 0x00, 0x4b,
-	0x09, 0xb0, 0x00, 0x00, 0xee, 0x8d, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
-	0xee, 0x8d, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xd4, 0x8e, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xd4, 0x8e, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xd4, 0x8e, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xec, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x03, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xe0, 0x8e, 0x00, 0x45,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x41, 0x91, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x1a, 0x8e, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0xf9, 0x8d, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
-	0x13, 0x8e, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x48,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x15, 0x8e, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x75, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x1d, 0x8e, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x13, 0x8e, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x74, 0x8e, 0x00, 0x4c,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x09, 0x8f, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
-	0x09, 0x8f, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8a, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8a, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x09, 0x8f, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xee, 0x8d, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00, 0x2c, 0x8f, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x14, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x14, 0x8f, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x14, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x2c, 0x8f, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x13, 0x8e, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x14, 0x8f, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x3b, 0x8f, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x3b, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x9d, 0x8f, 0x00, 0x40, 0x09, 0xb0, 0x00, 0x00, 0xba, 0x8f, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0xae, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
-	0x0c, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x0c, 0x8f, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0xba, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0xc1, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0xc1, 0x8f, 0x00, 0x48,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xae, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x0c, 0x8f, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x0c, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0xae, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xd4, 0x8e, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xd4, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0xd4, 0x8e, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x13, 0x8e, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xd4, 0x8e, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xd4, 0x8e, 0x00, 0x4c,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x2b, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x1f, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8f, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x13, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x2b, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8a, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8a, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x1f, 0x8f, 0x00, 0x48,
-	0x09, 0xb0, 0x00, 0x00, 0x13, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x13, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x1f, 0x8f, 0x00, 0x48,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xc3, 0x8f, 0x00, 0x42,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xc3, 0x8f, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xc3, 0x8f, 0x00, 0x4b,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xc3, 0x8f, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xc3, 0x8f, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0xc3, 0x8f, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0xc3, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0xc3, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xc3, 0x8f, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xc3, 0x8f, 0x00, 0x4c,
-	0x09, 0xb0, 0x00, 0x00, 0xc3, 0x8f, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xdd, 0x8f, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x03, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xdd, 0x8f, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xd8, 0x90, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x03, 0x8f, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xd8, 0x90, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xd8, 0x90, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xfb, 0x90, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xfa, 0x90, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xfb, 0x90, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xfa, 0x90, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xce, 0x8f, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xda, 0x8f, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xda, 0x8f, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xda, 0x8f, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xda, 0x8f, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xda, 0x8f, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0xda, 0x8f, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0xda, 0x8f, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0xda, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xda, 0x8f, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xec, 0x8e, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x03, 0x8f, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0xe0, 0x8e, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x8f, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x36, 0x91, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x36, 0x91, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x36, 0x91, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x36, 0x91, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
-	0x36, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x36, 0x91, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xe0, 0x8e, 0x00, 0x42,
-	0x09, 0xb0, 0x00, 0x00, 0x41, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xe0, 0x8e, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x03, 0x8f, 0x00, 0x47,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x41, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x41, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x45, 0x91, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x03, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x87, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x45, 0x91, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x56, 0x91, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x34, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x56, 0x91, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x13, 0x8e, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x48,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x34, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x67, 0x91, 0x00, 0x43,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x03, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x67, 0x91, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x67, 0x91, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0xf9, 0x8d, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x1a, 0x8e, 0x00, 0x42,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x85, 0x91, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x1a, 0x8e, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0xf9, 0x8d, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
-	0x13, 0x8e, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x48,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x85, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x87, 0x91, 0x00, 0x4a,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x03, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x87, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x42, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x42, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x03, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x42, 0x91, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x42, 0x91, 0x00, 0x46,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x8d, 0x91, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x34, 0x91, 0x00, 0x4a,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x8d, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
-	0x13, 0x8e, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x34, 0x91, 0x00, 0x4a,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x1d, 0x8e, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x1d, 0x8e, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00,
-	0x13, 0x8e, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x48,
-	0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
-	0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x07, 0x00, 0x2e, 0x4b,
-	0x19, 0x90, 0x01, 0x00, 0x1f, 0x87, 0x00, 0x04, 0xe6, 0xb1, 0x00, 0x00,
-	0xcf, 0x8a, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x83, 0x94, 0x00, 0x3a,
-	0x81, 0x30, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xcf, 0x8a, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x0f,
-	0x1e, 0x8c, 0x01, 0x00, 0xee, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xdf, 0x8a, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
-	0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
-	0xdf, 0x8a, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0xdc, 0x8a, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0xa3, 0x84, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00,
-	0xe0, 0x8a, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x93, 0x93, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x02, 0x68, 0x97, 0x01, 0x00,
-	0xa3, 0x84, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x05, 0x00, 0x2e, 0x4b,
-	0x19, 0x90, 0x01, 0x00, 0x1f, 0x87, 0x00, 0x04, 0xe6, 0xb1, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x8d, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0xa1, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0xe0, 0xb1, 0x01, 0x00, 0xc6, 0x95, 0x00, 0x06, 0x07, 0x40, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x06, 0x07, 0xd0, 0x01, 0x00, 0xd4, 0x00, 0x2e, 0x5c,
-	0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf0, 0xb1, 0x01, 0x00,
-	0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfe, 0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
-	0x96, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
-	0x96, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x96, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x96, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfe, 0x96, 0xc0, 0x01, 0x00, 0x00, 0x30, 0x00, 0x4b,
-	0x94, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x95, 0xf0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4a, 0x96, 0xc0, 0x01, 0x00, 0x5e, 0x01, 0x2e, 0x34,
-	0x97, 0x84, 0x01, 0x00, 0x02, 0x00, 0x00, 0x4b, 0xe4, 0xe5, 0x01, 0x00,
-	0x64, 0x01, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
-	0x86, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x2e, 0xa7, 0x87, 0xc0, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x40,
-	0xf1, 0x99, 0x01, 0x00, 0x58, 0x01, 0x00, 0x43, 0xf0, 0xc9, 0x01, 0x00,
-	0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
-	0x09, 0x8b, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x1a, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
-	0x08, 0x00, 0x2e, 0x40, 0x95, 0xb0, 0x01, 0x00, 0x11, 0x8b, 0x20, 0x4b,
-	0x94, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
-	0x0e, 0x8b, 0x00, 0x41, 0x95, 0xc0, 0x00, 0x00, 0x10, 0x80, 0x00, 0x10,
-	0x44, 0xc9, 0x01, 0x00, 0x18, 0x8b, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x14, 0x8b, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x83, 0x94, 0x00, 0x40, 0x81, 0x30, 0x01, 0x00,
-	0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x0c, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x86, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x88, 0xb0, 0x01, 0x00, 0x1d, 0x8b, 0x44, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x20, 0x8b, 0xa2, 0x4c, 0xfd, 0x7f, 0x00, 0x00,
-	0x21, 0x8b, 0x00, 0x4c, 0xfd, 0x93, 0x00, 0x00, 0x22, 0x8b, 0x20, 0xf0,
-	0x56, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x56, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x1c, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x44, 0xc9, 0x01, 0x00, 0x64, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
-	0x70, 0x00, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x28, 0x8b, 0xa8, 0x44,
-	0xe0, 0x31, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x8c, 0xc8, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x46, 0x44, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40,
-	0xf1, 0x99, 0x01, 0x00, 0x68, 0x01, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00,
-	0x64, 0x00, 0x00, 0x43, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x62, 0xb1, 0x01, 0x00,
-	0x30, 0x8b, 0xa8, 0x44, 0xe0, 0x31, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x09, 0x00, 0x00, 0x07, 0x86, 0xe4, 0x01, 0x00,
-	0x38, 0x00, 0x2e, 0xa7, 0x87, 0xc0, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x38, 0x8b, 0x22, 0x43, 0xe7, 0x7d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00, 0x3b, 0x8b, 0x22, 0x44,
-	0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x45, 0xc1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4a, 0x19, 0x90, 0x01, 0x00, 0x68, 0x01, 0x20, 0xa2,
-	0xe4, 0xb1, 0x01, 0x00, 0x88, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x3f, 0x8b, 0x23, 0x0b, 0xe5, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x19, 0x90, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
-	0x50, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x58, 0x01, 0x00, 0x43,
-	0xf0, 0xc9, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x62, 0xb1, 0x01, 0x00, 0x44, 0x8b, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x5c, 0x00, 0x2e, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x60, 0xf0, 0x96, 0xb0, 0x01, 0x00, 0x83, 0x94, 0x00, 0x41,
-	0x81, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x4f, 0x8b, 0xa2, 0x49, 0x19, 0x7c, 0x00, 0x00, 0x86, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x53, 0x8b, 0x00, 0x40, 0xe5, 0xb1, 0x00, 0x00,
-	0x86, 0x00, 0x2f, 0x49, 0x19, 0x80, 0x01, 0x00, 0x53, 0x8b, 0xa2, 0xf2,
-	0x80, 0x32, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0xe7, 0x91, 0x01, 0x00, 0x56, 0x8b, 0xa2, 0x46,
-	0x19, 0x7c, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x5a, 0x8b, 0x00, 0x40, 0xe5, 0xb1, 0x00, 0x00, 0xa0, 0x00, 0x2f, 0x46,
-	0x19, 0x80, 0x01, 0x00, 0x5a, 0x8b, 0xa2, 0xf2, 0x80, 0x32, 0x00, 0x00,
-	0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0xe7, 0x91, 0x01, 0x00, 0xa8, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x34, 0x00, 0x2d, 0xf0, 0x24, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
-	0x0c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x10, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfb, 0x12, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3,
-	0x16, 0x88, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3, 0x14, 0xf4, 0x01, 0x00,
-	0x85, 0x8b, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x6d, 0x8b, 0x22, 0x0a,
-	0x16, 0x6c, 0x00, 0x00, 0x58, 0x00, 0x3d, 0x43, 0x13, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0,
-	0x84, 0x30, 0x00, 0x00, 0x70, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x13, 0xc0, 0x01, 0x00,
-	0x6c, 0x8b, 0xa0, 0x43, 0x13, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x13, 0xb0, 0x01, 0x00, 0x62, 0x8b, 0x00, 0x41, 0x15, 0xd0, 0x00, 0x00,
-	0x85, 0x8b, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00, 0x58, 0x00, 0x3d, 0x43,
-	0x13, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0xf0, 0x84, 0x30, 0x00, 0x00, 0x70, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x40, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x85, 0x8b, 0x22, 0x41, 0x15, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x11, 0xc0, 0x01, 0x00, 0x79, 0x8b, 0xa0, 0x43,
-	0x11, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0xb0, 0x01, 0x00,
-	0x58, 0x00, 0x3d, 0x43, 0x11, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x36, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x00, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x83, 0xb0, 0x01, 0x00, 0xc2, 0x94, 0x00, 0x47,
-	0x61, 0x31, 0x01, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x2c, 0x92, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x81, 0x8b, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x75, 0x8b, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
-	0x37, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xf4, 0x94, 0x00, 0x51,
-	0x81, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x34, 0x00, 0x2e, 0x41, 0xf5, 0xb1, 0x01, 0x00, 0x00, 0x11, 0x00, 0x40,
-	0xe5, 0x99, 0x01, 0x00, 0x8d, 0x8b, 0x00, 0x48, 0x19, 0x90, 0x00, 0x00,
-	0x34, 0x00, 0x2e, 0x41, 0xf5, 0xb1, 0x01, 0x00, 0x00, 0x11, 0x00, 0x40,
-	0xe5, 0x99, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00, 0x92, 0x8b, 0x22, 0x45,
-	0x23, 0x7c, 0x00, 0x00, 0xb0, 0x00, 0x2f, 0xf0, 0x8c, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x60, 0xf0, 0x8c, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x35, 0x00, 0x2d, 0xf0, 0x8c, 0xb0, 0x01, 0x00,
-	0x58, 0x00, 0x3e, 0x43, 0xe7, 0xe1, 0x01, 0x00, 0x97, 0x8b, 0x22, 0x48,
-	0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x8d, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x68, 0x0a, 0x8c, 0xc0, 0x01, 0x00, 0x38, 0x00, 0x2a, 0x4a,
-	0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00,
-	0x3c, 0x00, 0x20, 0x1b, 0xe0, 0xb1, 0x01, 0x00, 0x10, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x38, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x26, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf8,
-	0x02, 0x30, 0x00, 0x00, 0xa5, 0x8b, 0x23, 0x01, 0x14, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x82, 0xb0, 0x01, 0x00, 0x4c, 0x00, 0x20, 0xf0, 0xe4, 0xb1, 0x01, 0x00,
-	0x44, 0x00, 0x20, 0x40, 0xe0, 0xb1, 0x01, 0x00, 0x48, 0x00, 0x20, 0x41,
-	0xe0, 0xb1, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0x10, 0x32, 0xb0, 0x01, 0x00,
-	0xaa, 0x95, 0x00, 0xf0, 0x24, 0x30, 0x01, 0x00, 0xae, 0x8b, 0xa2, 0x44,
-	0x81, 0x6c, 0x00, 0x00, 0xac, 0x8b, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0x57, 0x93, 0x00, 0x40, 0x3b, 0x30, 0x01, 0x00, 0xd2, 0x8b, 0xa2, 0x08,
-	0x3c, 0x30, 0x00, 0x00, 0xae, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x94, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xd2, 0x8b, 0xa2, 0x08,
-	0x3c, 0x30, 0x00, 0x00, 0x50, 0x00, 0x20, 0x1c, 0xe0, 0xb1, 0x01, 0x00,
-	0x54, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00, 0x4e, 0x00, 0x20, 0x01,
-	0xe4, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x20, 0x0a, 0xe0, 0xb1, 0x01, 0x00,
-	0xf4, 0x94, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x36, 0x93, 0x00, 0xf3, 0x94, 0x30, 0x01, 0x00, 0x8d, 0x8b, 0x22, 0x4a,
-	0x80, 0x32, 0x00, 0x00, 0xba, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x36, 0x93, 0x00, 0xf3,
-	0x94, 0x30, 0x01, 0x00, 0x58, 0x00, 0x3e, 0x43, 0x97, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x1b, 0xf0, 0xb1, 0x01, 0x00, 0x1f, 0x00, 0x60, 0x00,
-	0x00, 0x8c, 0x01, 0x00, 0xe4, 0x8a, 0x85, 0x11, 0x80, 0x32, 0x00, 0x00,
-	0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0xb0, 0x00, 0x2f, 0xf0,
-	0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0xf0, 0x8c, 0xc0, 0x01, 0x00,
-	0xf4, 0x94, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xc4, 0x8b, 0x00, 0x49, 0x19, 0x80, 0x00, 0x00,
-	0xc9, 0x8b, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x57, 0x93, 0x00, 0x40,
-	0x3b, 0x30, 0x01, 0x00, 0xcd, 0x8b, 0xa2, 0x08, 0x3c, 0x30, 0x00, 0x00,
-	0xf4, 0x94, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x94, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xcd, 0x8b, 0xa2, 0x08, 0x3c, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x5f,
-	0x81, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x50, 0x00, 0x2d, 0x10, 0x32, 0xb0, 0x01, 0x00, 0x54, 0x00, 0x2d, 0xf0,
-	0x38, 0xb0, 0x01, 0x00, 0x4e, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00,
-	0x40, 0x00, 0x2d, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x14, 0xb0, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10, 0x8c, 0xc8, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x46, 0x44, 0xc9, 0x01, 0x00, 0x68, 0x01, 0x2d, 0x44,
-	0x61, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x68, 0xf2, 0x80, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05,
-	0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x37, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x36, 0xd0, 0x01, 0x00, 0x5c, 0x01, 0x2e, 0x40,
-	0x10, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x52, 0x81, 0xd0, 0x01, 0x00, 0x89, 0x94, 0x00, 0x40,
-	0xe4, 0x31, 0x01, 0x00, 0x20, 0x00, 0x00, 0x46, 0x62, 0xdd, 0x01, 0x00,
-	0xde, 0x8b, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00, 0xce, 0x92, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xd6, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xec, 0x8b, 0x82, 0x41, 0x23, 0x40, 0x00, 0x00, 0x20, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0xe9, 0x8b, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0xe6, 0x8b, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x23, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19,
-	0x44, 0xc9, 0x01, 0x00, 0xf4, 0x8b, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0xf0, 0x8b, 0xa3, 0x01, 0x0c, 0x6c, 0x00, 0x00, 0xf1, 0x8b, 0x00, 0x06,
-	0x04, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0xb0, 0x01, 0x00,
-	0xf3, 0x8b, 0x20, 0x02, 0x36, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b,
-	0x04, 0xb0, 0x01, 0x00, 0xf7, 0x8b, 0x00, 0x02, 0xe0, 0xb1, 0x00, 0x00,
-	0xf6, 0x8b, 0xa3, 0x01, 0x0c, 0x6c, 0x00, 0x00, 0xf7, 0x8b, 0x00, 0x06,
-	0x04, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x68, 0x02, 0x16, 0x94, 0x01, 0x00, 0xff, 0xff, 0x00, 0x0b,
-	0x16, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x68, 0x08, 0x3e, 0x96, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x1c, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
-	0xfc, 0x8b, 0xa8, 0x13, 0xe0, 0x31, 0x00, 0x00, 0x33, 0x8c, 0x22, 0x02,
-	0x14, 0x50, 0x00, 0x00, 0x44, 0x00, 0x2d, 0x02, 0x0c, 0xd0, 0x01, 0x00,
-	0x23, 0x8c, 0xa2, 0x02, 0x02, 0x50, 0x00, 0x00, 0x0a, 0x8c, 0x22, 0x5c,
-	0x1f, 0x7c, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x09, 0x8c, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x05, 0x8c, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x44, 0x00, 0x2d, 0x5c, 0x1f, 0x80, 0x01, 0x00, 0x48, 0x00, 0x2d, 0xf0,
-	0x38, 0xb0, 0x01, 0x00, 0x4c, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00,
-	0x38, 0x00, 0x2f, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x24, 0x8c, 0x22, 0x01,
-	0x14, 0x6c, 0x00, 0x00, 0x17, 0x8c, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00, 0x20, 0x00, 0x2d, 0x03,
-	0x48, 0xb1, 0x01, 0x00, 0x16, 0x8c, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x13, 0x8c, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x38, 0x00, 0x2f, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00,
-	0x38, 0x00, 0x2d, 0xf0, 0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0xe1, 0xc1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x22, 0x4a, 0xf1, 0xb1, 0x01, 0x00, 0x44, 0x00, 0x00, 0x05,
-	0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4b, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
-	0x20, 0x8c, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00, 0x24, 0x8c, 0x00, 0x05,
-	0x48, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0xc0, 0x01, 0x00,
-	0x2e, 0x8c, 0x22, 0x06, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x33, 0xc0, 0x01, 0x00, 0x2c, 0x8c, 0xa2, 0x02, 0x36, 0x6c, 0x00, 0x00,
-	0x04, 0x00, 0x8f, 0x0d, 0x42, 0x31, 0x00, 0x00, 0x10, 0x00, 0x00, 0xf8,
-	0x10, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x11, 0x80, 0x01, 0x00,
-	0xf0, 0x07, 0x00, 0x40, 0x37, 0x98, 0x01, 0x00, 0xe2, 0x8b, 0x00, 0xa1,
-	0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00,
-	0xe2, 0x8b, 0x00, 0x02, 0x36, 0xd0, 0x00, 0x00, 0x50, 0x00, 0x20, 0x1c,
-	0xe0, 0xb1, 0x01, 0x00, 0x54, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00,
-	0x4e, 0x00, 0x20, 0x01, 0xe4, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x20, 0x0a,
-	0xe0, 0xb1, 0x01, 0x00, 0x38, 0x8c, 0x00, 0x5f, 0x01, 0xb0, 0x00, 0x00,
-	0x37, 0x00, 0x2d, 0x46, 0x01, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3,
-	0x80, 0xf4, 0x01, 0x00, 0x37, 0x8c, 0xa0, 0x43, 0x81, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x55, 0x01, 0xb0, 0x01, 0x00, 0x40, 0x00, 0x20, 0x40,
-	0xe1, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00,
-	0x3e, 0x8c, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
-	0x3b, 0x8c, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0xd3, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x45, 0x8c, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x42, 0x8c, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x60, 0x01, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b,
-	0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x17, 0xf0, 0x01, 0x00,
-	0x4a, 0x8c, 0x90, 0xf2, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00,
-	0x32, 0x00, 0x00, 0xa6, 0x2a, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
-	0x2a, 0x94, 0x01, 0x00, 0x4d, 0x8c, 0x45, 0x48, 0x61, 0x31, 0x00, 0x00,
-	0x00, 0xd0, 0x00, 0x1e, 0x62, 0xdd, 0x01, 0x00, 0x52, 0x8c, 0x28, 0x40,
-	0x05, 0x30, 0x00, 0x00, 0x4e, 0x8c, 0x22, 0x48, 0x77, 0x7d, 0x00, 0x00,
-	0x55, 0x8c, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
-	0x62, 0xb1, 0x01, 0x00, 0x5e, 0x8c, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x52, 0x8c, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00,
-	0x92, 0xb0, 0x01, 0x00, 0x5b, 0x8c, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x99, 0x92, 0x00, 0xf8,
-	0x00, 0x30, 0x01, 0x00, 0x58, 0x8c, 0xa2, 0x41, 0x3b, 0x50, 0x00, 0x00,
-	0x5f, 0x8c, 0x00, 0x49, 0x00, 0xb0, 0x00, 0x00, 0xff, 0x07, 0x00, 0x1e,
-	0x00, 0x8c, 0x01, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x5f, 0x8c, 0x00, 0x49, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x47,
-	0x19, 0x80, 0x01, 0x00, 0x62, 0x8c, 0x22, 0x5f, 0x01, 0x6c, 0x00, 0x00,
-	0xd4, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xbf, 0x87, 0x00, 0x00,
-	0x80, 0xb0, 0x00, 0x00, 0x69, 0x8c, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
-	0x20, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x69, 0x8c, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x66, 0x8c, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x69, 0x8c, 0x40, 0x05, 0x48, 0x31, 0x00, 0x00, 0xff, 0xff, 0x00, 0x07,
-	0x94, 0x89, 0x01, 0x00, 0x6f, 0x8c, 0x85, 0xca, 0x94, 0x30, 0x00, 0x00,
-	0xd4, 0x95, 0x18, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x0f,
-	0x1e, 0x8c, 0x01, 0x00, 0xe0, 0x86, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xf4, 0x94, 0x18, 0x00, 0x80, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x47,
-	0x19, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x19, 0x80, 0x01, 0x00,
-	0xe4, 0x8a, 0x22, 0x47, 0x19, 0x7c, 0x00, 0x00, 0x94, 0x92, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x76, 0x8c, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
-	0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x89, 0x94, 0x00, 0x40,
-	0x0d, 0x30, 0x01, 0x00, 0x9c, 0x01, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
-	0xff, 0xff, 0x00, 0x0b, 0x98, 0x88, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0x50,
-	0x17, 0xf0, 0x01, 0x00, 0x7c, 0x8c, 0x90, 0x4c, 0x16, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x7e, 0x8c, 0x22, 0x43,
-	0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00,
-	0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00, 0x68, 0x01, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x5c, 0x01, 0x2e, 0xf2, 0x80, 0xb0, 0x01, 0x00,
-	0x02, 0x00, 0x62, 0x40, 0x7e, 0xcd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57,
-	0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
-	0x03, 0x00, 0x00, 0x40, 0xf0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
-	0xf0, 0xb1, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x62, 0xb1, 0x01, 0x00, 0x88, 0x8c, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x8c, 0x8c, 0x45, 0x48, 0x61, 0x31, 0x00, 0x00,
-	0x00, 0x50, 0x00, 0x08, 0x62, 0xdd, 0x01, 0x00, 0x92, 0x8c, 0x28, 0x40,
-	0x05, 0x30, 0x00, 0x00, 0x8d, 0x8c, 0x22, 0x48, 0x77, 0x7d, 0x00, 0x00,
-	0x99, 0x92, 0x1d, 0x08, 0x00, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xe4, 0x8a, 0x1d, 0x47, 0x19, 0x80, 0x00, 0x00,
-	0x35, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3,
-	0x84, 0xc8, 0x01, 0x00, 0x97, 0x8c, 0xa0, 0x43, 0x85, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x63, 0x40, 0x85, 0xb0, 0x01, 0x00, 0xa8, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x37, 0x00, 0x2f, 0xf0, 0x24, 0xb0, 0x01, 0x00,
-	0x01, 0x00, 0x63, 0xf3, 0x82, 0xcc, 0x01, 0x00, 0xa2, 0x8c, 0xa2, 0x41,
-	0x9e, 0x06, 0x00, 0x00, 0xe4, 0x8a, 0x22, 0x44, 0x83, 0x70, 0x00, 0x00,
-	0x36, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x58, 0x00, 0x3d, 0x43,
-	0xe7, 0xe1, 0x01, 0x00, 0xe4, 0x8a, 0x1f, 0xf0, 0x24, 0x6c, 0x00, 0x00,
-	0xd4, 0x95, 0x00, 0x48, 0x81, 0x30, 0x01, 0x00, 0xbf, 0x87, 0x23, 0x41,
-	0x83, 0x6c, 0x00, 0x00, 0xbf, 0x87, 0x00, 0x47, 0x81, 0xb0, 0x00, 0x00,
-	0x58, 0x00, 0x3d, 0x43, 0x85, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x36, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xb0, 0x01, 0x00,
-	0x28, 0x00, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00, 0xc2, 0x94, 0x00, 0x47,
-	0x61, 0x31, 0x01, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x2d, 0xf0,
-	0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x8e, 0xb0, 0x01, 0x00,
-	0x90, 0x00, 0x2d, 0xf0, 0x14, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x93, 0x8b, 0xa2, 0x40, 0x8f, 0x7c, 0x00, 0x00,
-	0xb0, 0x8c, 0x22, 0x47, 0x8f, 0x7c, 0x00, 0x00, 0x93, 0x8b, 0x00, 0x48,
-	0x19, 0x90, 0x00, 0x00, 0x1f, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x36, 0x00, 0x2d, 0x5d, 0x05, 0xb4, 0x01, 0x00, 0x37, 0x00, 0x2d, 0xf3,
-	0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x8e, 0xb0, 0x01, 0x00,
-	0x5c, 0x00, 0x3d, 0x43, 0x81, 0xe0, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0xf0,
-	0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x24, 0xb0, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x10, 0x86, 0xdc, 0x01, 0x00, 0x40, 0x80, 0x00, 0x03,
-	0x44, 0xc9, 0x01, 0x00, 0x9b, 0x91, 0x00, 0x4a, 0xf0, 0x31, 0x01, 0x00,
-	0x36, 0x00, 0x2f, 0x5c, 0x1f, 0x90, 0x01, 0x00, 0xbe, 0x8c, 0xa2, 0x50,
-	0x8f, 0x50, 0x00, 0x00, 0x34, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
-	0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x63, 0x41,
-	0x81, 0xc0, 0x01, 0x00, 0xc1, 0x8c, 0xa0, 0x43, 0x81, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x63, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x37, 0x00, 0x20, 0x47,
-	0xe6, 0xb1, 0x01, 0x00, 0xe4, 0x8a, 0x22, 0x47, 0x80, 0x32, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x47, 0x0c, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f,
-	0x8f, 0x84, 0x01, 0x00, 0xd6, 0x8c, 0x22, 0x47, 0x0c, 0x6c, 0x00, 0x00,
-	0x58, 0x00, 0x3d, 0x43, 0x81, 0xe0, 0x01, 0x00, 0xd6, 0x8c, 0x1f, 0xf0,
-	0x24, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0xcf, 0x8c, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xcc, 0x8c, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0xcf, 0x8c, 0x42, 0x40, 0x05, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x93, 0x93, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x5d, 0x69, 0x93, 0x01, 0x00,
-	0xd4, 0x8c, 0x23, 0x41, 0x0d, 0x6c, 0x00, 0x00, 0xb1, 0x8c, 0x00, 0x05,
-	0x48, 0xb1, 0x00, 0x00, 0xd4, 0x95, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00,
-	0xbf, 0x87, 0x00, 0x48, 0x81, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x22, 0x40,
-	0x8f, 0x6c, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00,
-	0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x84, 0xb0, 0x01, 0x00,
-	0xa6, 0x00, 0x2d, 0x49, 0x19, 0x90, 0x01, 0x00, 0x02, 0x00, 0x00, 0xf2,
-	0x80, 0xf4, 0x01, 0x00, 0xb8, 0x00, 0x2d, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf2, 0x80, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x82, 0xf8, 0x01, 0x00, 0x19, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
-	0xe5, 0x8c, 0xa0, 0x40, 0x82, 0x6c, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x40,
-	0x81, 0x98, 0x01, 0x00, 0xe5, 0x8c, 0xa3, 0x40, 0x82, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x80, 0xb0, 0x01, 0x00, 0xe7, 0x8c, 0x20, 0x4c,
-	0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x85, 0xc0, 0x01, 0x00,
-	0x86, 0x00, 0x20, 0x40, 0xe4, 0xb1, 0x01, 0x00, 0xa2, 0x00, 0x20, 0x42,
-	0xe6, 0xb1, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x83, 0x94, 0x00, 0x50, 0x81, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0xf0, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x8d, 0xb0, 0x01, 0x00, 0xc6, 0x95, 0x00, 0x40, 0x87, 0x30, 0x01, 0x00,
-	0xb0, 0x00, 0x2f, 0x5c, 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x60, 0xf0,
-	0x80, 0xc0, 0x01, 0x00, 0xf4, 0x94, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00,
-	0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xe4, 0x8a, 0x22, 0x46, 0x19, 0x7c, 0x00, 0x00,
-	0xa0, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x62, 0xf2,
-	0x96, 0xcc, 0x01, 0x00, 0xe4, 0x8a, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xf4, 0x94, 0x00, 0x4a, 0x81, 0x30, 0x01, 0x00, 0xc9, 0x94, 0x00, 0x46,
-	0x95, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xe4, 0x8a, 0x22, 0x49, 0x19, 0x7c, 0x00, 0x00, 0x86, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x62, 0xf2, 0x80, 0xcc, 0x01, 0x00,
-	0xe4, 0x8a, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x4a,
-	0x81, 0x30, 0x01, 0x00, 0xc9, 0x94, 0x00, 0x47, 0x95, 0x30, 0x01, 0x00,
-	0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2c, 0x92, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00,
-	0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xba, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x01, 0x00, 0x62, 0xf2, 0x80, 0xc8, 0x01, 0x00, 0x0b, 0x8d, 0x90, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0xff, 0xff, 0x62, 0x40, 0x81, 0x98, 0x01, 0x00,
-	0xa4, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xe4, 0x8a, 0x22, 0x40,
-	0xe5, 0x6d, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x41, 0xe5, 0xc1, 0x00, 0x00,
-	0x83, 0x94, 0x00, 0x4d, 0x81, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0xf0, 0x96, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xe1, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4b, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x8d, 0xb0, 0x01, 0x00, 0xc6, 0x95, 0x00, 0x40, 0x87, 0x30, 0x01, 0x00,
-	0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x1b, 0x8d, 0x80, 0xf3,
-	0x96, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe7, 0x81, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x19, 0x90, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x5c,
-	0x1f, 0x90, 0x00, 0x00, 0x34, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
-	0x01, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x11, 0x00, 0x40,
-	0xe5, 0x99, 0x01, 0x00, 0x94, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x30, 0x8d, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x82, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x63, 0x51, 0x83, 0xd0, 0x01, 0x00, 0x34, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3, 0x84, 0xcc, 0x01, 0x00,
-	0x28, 0x8d, 0x9f, 0x42, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x63, 0x42,
-	0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x03, 0xf0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00, 0x2a, 0x8d, 0x37, 0x5c,
-	0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x62, 0xb1, 0x01, 0x00,
-	0x2b, 0x8d, 0xa8, 0x4b, 0x19, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x62, 0xb1, 0x01, 0x00, 0x2d, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x14, 0x87, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0, 0x94, 0xb0, 0x01, 0x00,
-	0xac, 0x00, 0x2d, 0xf0, 0x30, 0xb0, 0x01, 0x00, 0x35, 0x00, 0x2d, 0xf0,
-	0x28, 0xb0, 0x01, 0x00, 0x58, 0x00, 0x3e, 0x43, 0xe7, 0xe1, 0x01, 0x00,
-	0x01, 0x00, 0x00, 0x18, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
-	0xe0, 0xb1, 0x01, 0x00, 0x38, 0x00, 0x20, 0x00, 0xe0, 0xb1, 0x01, 0x00,
-	0x3c, 0x00, 0x20, 0x1b, 0xe0, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x20, 0x40,
-	0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2b, 0xb0, 0x01, 0x00,
-	0xd8, 0x94, 0x00, 0x40, 0x0d, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
-	0x16, 0xc0, 0x01, 0x00, 0x3f, 0x8d, 0xa0, 0x14, 0x16, 0x44, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x0e, 0x00, 0x00, 0xa2,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf8, 0xb1, 0x01, 0x00,
-	0xb0, 0x00, 0x2d, 0x14, 0xf8, 0xb1, 0x01, 0x00, 0x10, 0x50, 0x00, 0x40,
-	0x87, 0x98, 0x01, 0x00, 0x48, 0x8d, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00,
-	0x00, 0x30, 0x00, 0x43, 0x86, 0xc8, 0x01, 0x00, 0x00, 0x30, 0x00, 0x0b,
-	0x16, 0xc8, 0x01, 0x00, 0x48, 0x8d, 0xa4, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x01, 0x00, 0x6e, 0x43,
-	0x86, 0x98, 0x01, 0x00, 0x0f, 0x95, 0x00, 0x30, 0x81, 0x30, 0x01, 0x00,
-	0x4c, 0x8d, 0xa0, 0x41, 0x17, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x17, 0xc0, 0x01, 0x00, 0x53, 0x8d, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00,
-	0x08, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0xab,
-	0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab, 0x17, 0xc0, 0x01, 0x00,
-	0x52, 0x8d, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x64, 0xf0, 0x82, 0xb0, 0x01, 0x00,
-	0x90, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x60, 0x41,
-	0x31, 0xc0, 0x01, 0x00, 0xbc, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x59, 0x8d, 0x06, 0x0c, 0x80, 0x32, 0x00, 0x00, 0xa0, 0x00, 0x20, 0xf2,
-	0xe4, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x09, 0x46, 0x19, 0x10, 0x00, 0x00,
-	0x9c, 0x01, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0xff, 0xff, 0x00, 0x0b,
-	0x98, 0x88, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0x50, 0x17, 0xf0, 0x01, 0x00,
-	0x5e, 0x8d, 0x90, 0x4c, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x17, 0xc0, 0x01, 0x00, 0x60, 0x8d, 0x22, 0x43, 0xe7, 0x7d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20,
-	0x17, 0xa4, 0x01, 0x00, 0x68, 0x01, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x5c, 0x01, 0x2e, 0xf2, 0x80, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x62, 0x40,
-	0x7e, 0xcd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57, 0x81, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00, 0x03, 0x00, 0x00, 0x40,
-	0xf0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00,
-	0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
-	0x6a, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x6e, 0x8d, 0x45, 0x48, 0x61, 0x31, 0x00, 0x00, 0x00, 0x50, 0x00, 0x08,
-	0x62, 0xdd, 0x01, 0x00, 0x6f, 0x8d, 0xa8, 0x40, 0x05, 0x30, 0x00, 0x00,
-	0x35, 0x00, 0x1d, 0x40, 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3,
-	0x84, 0xc8, 0x01, 0x00, 0x75, 0x8d, 0xa0, 0x43, 0x85, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x63, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x37, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3, 0x82, 0xcc, 0x01, 0x00,
-	0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0xe7, 0x91, 0x01, 0x00, 0xf4, 0x94, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00,
-	0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x36, 0x93, 0x00, 0xf3, 0x94, 0x30, 0x01, 0x00,
-	0x1f, 0x8d, 0x22, 0x4a, 0x80, 0x32, 0x00, 0x00, 0xba, 0x8b, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x36, 0x93, 0x00, 0xf3, 0x94, 0x30, 0x01, 0x00, 0x8a, 0x8b, 0x22, 0x4a,
-	0x80, 0x32, 0x00, 0x00, 0xba, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x36, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
-	0x12, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3, 0x90, 0x88, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0xf3, 0x0c, 0xf4, 0x01, 0x00, 0xb4, 0x8b, 0x22, 0x06,
-	0x90, 0x6c, 0x00, 0x00, 0x5c, 0x00, 0x3d, 0x43, 0x13, 0xe0, 0x01, 0x00,
-	0xa8, 0x00, 0x2d, 0xf0, 0x94, 0xb0, 0x01, 0x00, 0x37, 0x00, 0x2f, 0xf0,
-	0x24, 0xb0, 0x01, 0x00, 0x36, 0x00, 0x2a, 0x50, 0xe7, 0xd1, 0x01, 0x00,
-	0x00, 0x00, 0x63, 0x41, 0x13, 0xc0, 0x01, 0x00, 0x8f, 0x8d, 0xa0, 0x43,
-	0x13, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00,
-	0x99, 0x91, 0x00, 0x10, 0x86, 0x30, 0x01, 0x00, 0xaf, 0x82, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x91, 0x8d, 0x42, 0x05, 0x48, 0x31, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00, 0xb4, 0x8b, 0x1a, 0x5d,
-	0x69, 0x93, 0x00, 0x00, 0x36, 0x00, 0x2d, 0x10, 0x86, 0xb0, 0x01, 0x00,
-	0x5c, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0xf0,
-	0x94, 0xb0, 0x01, 0x00, 0x35, 0x00, 0x2f, 0xf0, 0x24, 0xb0, 0x01, 0x00,
-	0x01, 0x00, 0x6b, 0xfb, 0x84, 0xc8, 0x01, 0x00, 0x9c, 0x8d, 0xa0, 0x43,
-	0x85, 0x6c, 0x00, 0x00, 0x35, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3,
-	0x12, 0xc8, 0x01, 0x00, 0x9f, 0x8d, 0xa0, 0x43, 0x13, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x40, 0x80, 0x00, 0x03,
-	0x44, 0xc9, 0x01, 0x00, 0x9b, 0x91, 0x00, 0x4a, 0xf0, 0x31, 0x01, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xa2, 0x8d, 0x42, 0x05,
-	0x48, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
-	0x00, 0x00, 0x1a, 0x5d, 0x69, 0x93, 0x01, 0x00, 0x37, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x11, 0x00, 0x63, 0xf3, 0x82, 0xcc, 0x01, 0x00,
-	0x9b, 0x8c, 0x22, 0x41, 0x9e, 0x06, 0x00, 0x00, 0x35, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x58, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x36, 0xb0, 0x01, 0x00, 0xa5, 0x8c, 0x00, 0xf0,
-	0x00, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0xad, 0x8d, 0x65, 0xf2, 0x12, 0x30, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42,
-	0x13, 0xf0, 0x01, 0x00, 0xb2, 0x8d, 0x22, 0x47, 0xe7, 0x7d, 0x00, 0x00,
-	0xf5, 0x82, 0x75, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xac, 0x8d, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xe7, 0x91, 0x01, 0x00,
-	0x00, 0x00, 0x75, 0x42, 0x19, 0x90, 0x01, 0x00, 0x75, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0xb4, 0x8d, 0xa8, 0xb1, 0x0c, 0x30, 0x00, 0x00,
-	0x1f, 0x94, 0x00, 0x10, 0x94, 0x30, 0x01, 0x00, 0xaf, 0x82, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0xc0, 0xa8, 0x3d, 0x46, 0x0d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x97, 0xb0, 0x01, 0x00, 0xbe, 0x8d, 0x22, 0x40, 0xe1, 0x6d, 0x00, 0x00,
-	0x04, 0x00, 0x02, 0x41, 0x97, 0x40, 0x00, 0x00, 0xbb, 0x8d, 0x00, 0x50,
-	0x43, 0xc1, 0x00, 0x00, 0xca, 0x8d, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x62, 0x4b, 0x12, 0x94, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
-	0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x97, 0xc0, 0x01, 0x00,
-	0x30, 0x00, 0x00, 0x10, 0x94, 0xc8, 0x01, 0x00, 0x00, 0x80, 0x00, 0x4a,
-	0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf1, 0xb1, 0x01, 0x00,
-	0x5e, 0x01, 0x00, 0x4b, 0xf0, 0xc9, 0x01, 0x00, 0x5e, 0x01, 0x00, 0x05,
-	0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x4a, 0x62, 0xdd, 0x01, 0x00, 0xc8, 0x8d, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x09,
-	0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x68, 0xa8, 0x97, 0xc0, 0x01, 0x00,
-	0xd4, 0x00, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
-	0xd0, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00,
-	0xd4, 0x8d, 0x65, 0x40, 0x81, 0x32, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf3,
-	0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x75, 0x55, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
-	0x62, 0xb1, 0x01, 0x00, 0xd8, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xdd, 0x8d, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x62, 0xb1, 0x01, 0x00, 0xdb, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x97, 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x96,
-	0x97, 0xb0, 0x01, 0x00, 0xe3, 0x8d, 0x20, 0x09, 0x96, 0x6c, 0x00, 0x00,
-	0xe3, 0x8d, 0x1f, 0x09, 0x96, 0x24, 0x00, 0x00, 0xf5, 0x82, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0xde, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x83, 0x94, 0x00, 0x57, 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x05,
-	0x48, 0xb1, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0xe9, 0x8d, 0x22, 0xf3, 0x80, 0x32, 0x00, 0x00, 0x83, 0x94, 0x00, 0x42,
-	0x81, 0x30, 0x01, 0x00, 0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xf4, 0x94, 0x00, 0x52, 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x42,
-	0x19, 0x80, 0x00, 0x00, 0x83, 0x94, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00,
-	0xf4, 0x94, 0x00, 0x52, 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
-	0x96, 0x93, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00, 0xcf, 0x8a, 0x22, 0x40,
-	0x95, 0x6c, 0x00, 0x00, 0xf4, 0x8d, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00,
-	0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x14, 0x87, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x41, 0x93, 0x00, 0x52,
-	0x95, 0x30, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
-	0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x7d, 0x95, 0x00, 0x40,
-	0x95, 0x30, 0x01, 0x00, 0xff, 0x8d, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
-	0x14, 0x87, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x19, 0x90, 0x01, 0x00, 0x83, 0x94, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00,
-	0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x23, 0x00, 0xa6,
-	0x16, 0xb0, 0x01, 0x00, 0x02, 0x8e, 0x83, 0x1e, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x08, 0x00, 0x0b, 0x16, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x2a, 0xc0, 0x01, 0x00, 0xcc, 0x94, 0x00, 0x08, 0x80, 0x30, 0x01, 0x00,
-	0x06, 0x8e, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00, 0xed, 0x94, 0x00, 0x43,
-	0x61, 0x31, 0x01, 0x00, 0xa7, 0x91, 0x00, 0x40, 0x8d, 0x30, 0x01, 0x00,
-	0xd4, 0x94, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0x0e, 0x8e, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x0b, 0x8e, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x75, 0x94, 0x00, 0x5e,
-	0x05, 0x10, 0x01, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x12, 0x8e, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40,
-	0x13, 0x30, 0x01, 0x00, 0xd4, 0x8a, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
-	0xc6, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x1f, 0x90, 0x01, 0x00,
-	0x19, 0x8e, 0x22, 0x43, 0x3d, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x19, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x3d, 0x80, 0x01, 0x00,
-	0x1a, 0x8e, 0x00, 0x42, 0x19, 0x90, 0x00, 0x00, 0x14, 0x00, 0x2d, 0x45,
-	0x1f, 0x90, 0x01, 0x00, 0x75, 0x8e, 0x83, 0x1e, 0x80, 0x32, 0x00, 0x00,
-	0x75, 0x8e, 0x00, 0x44, 0x19, 0x90, 0x00, 0x00, 0x8c, 0x92, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x2d, 0x8e, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
-	0x29, 0x8e, 0xa2, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02,
-	0x04, 0xdc, 0x01, 0x00, 0xa0, 0x98, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x30, 0x05, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00, 0x26, 0x8e, 0xa2, 0x41,
-	0x19, 0x7c, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x41, 0x93, 0x00, 0x15,
-	0x94, 0x30, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
-	0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc6, 0x93, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x19, 0x90, 0x01, 0x00,
-	0x83, 0x94, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00, 0x14, 0x87, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x30, 0x8e, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
-	0xc6, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x31, 0x8e, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x96, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x5d, 0x8e, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x15,
-	0x98, 0xc8, 0x01, 0x00, 0x5d, 0x8e, 0xa0, 0x0b, 0x99, 0x6c, 0x00, 0x00,
-	0x30, 0x00, 0x00, 0x10, 0x80, 0xc8, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40,
-	0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x62, 0xb1, 0x01, 0x00,
-	0x39, 0x8e, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0xc0, 0x00, 0x00, 0x15, 0x98, 0xc8, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x0b,
-	0x99, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x6a, 0x50, 0x99, 0xc0, 0x01, 0x00,
-	0xc0, 0x00, 0x62, 0x01, 0x80, 0xcc, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x2d, 0x00, 0x2d, 0xf0, 0x22, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0x80, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
-	0x23, 0x80, 0x01, 0x00, 0xd4, 0x00, 0x3f, 0x41, 0xe7, 0xe1, 0x01, 0x00,
-	0x0b, 0x00, 0x00, 0x11, 0xe4, 0xf5, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x47,
-	0xe7, 0xb5, 0x01, 0x00, 0x4a, 0x8e, 0x23, 0x0b, 0x81, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4f, 0xe5, 0x91, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
-	0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x03, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x15, 0x02, 0xd0, 0x01, 0x00, 0xcc, 0x94, 0x00, 0x00,
-	0x2a, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x4f, 0x8e, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x99, 0x92, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x01,
-	0x80, 0xce, 0x01, 0x00, 0x5b, 0x8e, 0x26, 0x11, 0x00, 0x30, 0x00, 0x00,
-	0x10, 0x00, 0x00, 0x00, 0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
-	0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0xc0, 0x01, 0x00,
-	0xc0, 0x00, 0x00, 0x40, 0x99, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
-	0x98, 0xd0, 0x01, 0x00, 0xcc, 0x94, 0x00, 0x4c, 0x02, 0x30, 0x01, 0x00,
-	0xc0, 0x00, 0x00, 0x40, 0x03, 0x98, 0x01, 0x00, 0x62, 0x8e, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x30, 0x00, 0x2f, 0x08, 0x80, 0xb0, 0x01, 0x00,
-	0xc0, 0x00, 0x00, 0x15, 0xf4, 0xc9, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x01,
-	0xe4, 0xcd, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40, 0x03, 0x98, 0x01, 0x00,
-	0xcc, 0x94, 0x00, 0x00, 0x2a, 0x40, 0x01, 0x00, 0x67, 0x8e, 0x22, 0x44,
-	0x1f, 0x7c, 0x00, 0x00, 0xac, 0x00, 0x2f, 0x40, 0x13, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0xe0, 0xc1, 0x01, 0x00, 0xb0, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x68, 0x8e, 0x00, 0x01, 0xe0, 0xd1, 0x00, 0x00,
-	0xa7, 0x91, 0x00, 0x40, 0x8d, 0x30, 0x01, 0x00, 0x80, 0x63, 0x00, 0xa6,
-	0x16, 0xb0, 0x01, 0x00, 0xd4, 0x94, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x70, 0x8e, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x6d, 0x8e, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x75, 0x94, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0x73, 0x8e, 0x22, 0x09,
-	0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xcf, 0x8a, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x75, 0x8e, 0x00, 0x4a,
-	0x1f, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xb0, 0x01, 0x00,
-	0x24, 0x00, 0x2d, 0x15, 0x10, 0xc0, 0x01, 0x00, 0x28, 0x00, 0x2d, 0xf0,
-	0x16, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00,
-	0x14, 0x00, 0x2f, 0xf2, 0x0c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
-	0xe0, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x15,
-	0x1a, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0x2a, 0xb0, 0x01, 0x00, 0x34, 0x94, 0x00, 0x40,
-	0x35, 0xb0, 0x00, 0x00, 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
-	0xb9, 0x8e, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00, 0x24, 0x00, 0x20, 0x0b,
-	0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00,
-	0x22, 0x00, 0x20, 0x06, 0xe4, 0xb1, 0x01, 0x00, 0x8f, 0x8e, 0x22, 0x5c,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00,
-	0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x8f, 0x8e, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x8b, 0x8e, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19,
-	0x42, 0xc9, 0x01, 0x00, 0xb2, 0x8e, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0xa0, 0x8e, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0xee, 0x93, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x41, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xad, 0x8e, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x96, 0x8e, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x9c, 0x8e, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0xaf, 0x92, 0x00, 0x40, 0x11, 0x30, 0x01, 0x00, 0x9d, 0x8e, 0x00, 0x05,
-	0x48, 0xb1, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x9f, 0x8e, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xf9, 0x82, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
-	0xee, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x3d, 0x92, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xa3, 0x8e, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0xa9, 0x8e, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xaf, 0x92, 0x00, 0x40,
-	0x11, 0x30, 0x01, 0x00, 0xaa, 0x8e, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
-	0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xac, 0x8e, 0x22, 0x09,
-	0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xf9, 0x82, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0xae, 0x8e, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0xb5, 0x8e, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xaf, 0x92, 0x00, 0x40,
-	0x11, 0x30, 0x01, 0x00, 0xb6, 0x8e, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
-	0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb8, 0x8e, 0x22, 0x09,
-	0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
-	0xd4, 0x8a, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19,
-	0x42, 0xc9, 0x01, 0x00, 0xc0, 0x8e, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0xbc, 0x8e, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
-	0xc4, 0x8e, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xaf, 0x92, 0x00, 0x40,
-	0x11, 0x30, 0x01, 0x00, 0xc5, 0x8e, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
-	0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x08, 0x00, 0x2d, 0x0a,
-	0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x82, 0xb0, 0x01, 0x00,
-	0x14, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0xca, 0x8e, 0x03, 0x1e,
-	0x80, 0x32, 0x00, 0x00, 0xcb, 0x8e, 0x00, 0x41, 0x87, 0xb0, 0x00, 0x00,
-	0x21, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0xb7, 0x93, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
-	0xcf, 0x8e, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40,
-	0x13, 0x30, 0x01, 0x00, 0xd2, 0x8e, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00,
-	0xf4, 0x94, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x19, 0x80, 0x01, 0x00, 0xcf, 0x8a, 0xa2, 0x4a, 0x1f, 0x7c, 0x00, 0x00,
-	0xd4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xba, 0x00, 0x20, 0x40,
-	0xe5, 0xb1, 0x01, 0x00, 0xd8, 0x8e, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00,
-	0xcc, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x84, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x2d, 0x95, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
-	0xc0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xc4, 0x00, 0x2d, 0xf0,
-	0x82, 0xb0, 0x01, 0x00, 0x61, 0x95, 0x00, 0xf0, 0x84, 0x30, 0x01, 0x00,
-	0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xd4, 0x8a, 0x22, 0x09,
-	0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
-	0xd4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0xe4, 0x8e, 0x22, 0x40, 0xe7, 0x6d, 0x00, 0x00,
-	0x32, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xec, 0x8e, 0xa2, 0x40,
-	0xe5, 0x6d, 0x00, 0x00, 0x83, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x24, 0x00, 0x20, 0x0b, 0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x20, 0x13,
-	0xe0, 0xb1, 0x01, 0x00, 0x22, 0x00, 0x20, 0x06, 0xe4, 0xb1, 0x01, 0x00,
-	0x14, 0x00, 0x20, 0x0a, 0xe0, 0xb1, 0x01, 0x00, 0xd4, 0x8a, 0x22, 0x09,
-	0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
-	0xd4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x83, 0x93, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x3c, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xfa, 0x8e, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
-	0x99, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x15, 0x98, 0x50, 0x00, 0x00,
-	0xfa, 0x8e, 0x20, 0x01, 0x98, 0x6c, 0x00, 0x00, 0x70, 0x00, 0x00, 0x03,
-	0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x46, 0x1f, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
-	0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0xf7, 0x8e, 0xa8, 0x00,
-	0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0xac, 0x00, 0x2f, 0x00, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
-	0xe0, 0xc1, 0x01, 0x00, 0x14, 0x00, 0x2f, 0x15, 0x10, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0a, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0x01,
-	0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x19, 0x90, 0x01, 0x00,
-	0x7c, 0x8e, 0x22, 0x09, 0x80, 0x32, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x09,
-	0x80, 0x30, 0x01, 0x00, 0x7c, 0x8e, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x82, 0xb0, 0x01, 0x00, 0x13, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0x43, 0xc1, 0x01, 0x00, 0xb7, 0x93, 0x00, 0xf0,
-	0x84, 0x30, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00,
-	0x2c, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x2d, 0x00, 0x20, 0x40,
-	0xe7, 0xb1, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x42, 0x19, 0x80, 0x00, 0x00,
-	0xa9, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc9, 0x94, 0x00, 0x48,
-	0x95, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x0f, 0x8f, 0xa8, 0x40,
-	0x13, 0x30, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x15, 0x8f, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x14, 0x8f, 0x00, 0x40,
-	0x13, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xb0, 0x01, 0x00,
-	0x08, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x14, 0x00, 0x2d, 0xf0,
-	0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x84, 0x30, 0x00, 0x00,
-	0x13, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0xb7, 0x93, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
-	0x2d, 0x8f, 0x00, 0x09, 0x00, 0xb0, 0x00, 0x00, 0xcf, 0x8a, 0x87, 0x42,
-	0x19, 0x10, 0x00, 0x00, 0x8b, 0x00, 0x2f, 0x47, 0x19, 0x80, 0x01, 0x00,
-	0xcf, 0x8a, 0x00, 0x40, 0xe7, 0x91, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x2b, 0x8f, 0x22, 0x47, 0xe7, 0x7d, 0x00, 0x00,
-	0x1e, 0x92, 0x00, 0x40, 0xe7, 0x31, 0x01, 0x00, 0x2b, 0x8f, 0x22, 0x00,
-	0x80, 0x32, 0x00, 0x00, 0x26, 0x8f, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00,
-	0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2b, 0x8f, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x32, 0x00, 0x2d, 0xf2, 0x94, 0xb0, 0x01, 0x00, 0x41, 0x93, 0x00, 0xf2,
-	0x02, 0x30, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x2c, 0x8f, 0x00, 0x40,
-	0x01, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
-	0x32, 0x8f, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0x31, 0x8f, 0xa2, 0x42,
-	0x19, 0x7c, 0x00, 0x00, 0x96, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x32, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc6, 0x93, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xbc, 0x8f, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0x3a, 0x8f, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x37, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xbc, 0x8f, 0x00, 0x05,
-	0x48, 0xb1, 0x00, 0x00, 0x8c, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x40, 0x8f, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0x83, 0x94, 0x00, 0x4d,
-	0x81, 0x30, 0x01, 0x00, 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00,
-	0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x74, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x96, 0xb0, 0x01, 0x00, 0x4e, 0x8f, 0x22, 0x42, 0x96, 0x14, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x64, 0x00, 0x68, 0x40,
-	0x97, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00, 0x70, 0x00, 0x00, 0x05,
-	0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x4b, 0x8f, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x4f, 0x8f, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2d, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x53, 0x8f, 0x65, 0xf2, 0x12, 0x30, 0x00, 0x00,
-	0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00, 0x58, 0x8f, 0x22, 0x47,
-	0xe7, 0x7d, 0x00, 0x00, 0xf5, 0x82, 0x75, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x52, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
-	0xe7, 0x91, 0x01, 0x00, 0x04, 0x00, 0x75, 0x09, 0x96, 0xe4, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x68, 0xa8, 0x97, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
-	0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x60, 0x8f, 0xa8, 0x40,
-	0xe1, 0x31, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00, 0x64, 0x8f, 0x65, 0x05,
-	0x48, 0x31, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf3, 0x96, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x75, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x6c, 0x8f, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x55, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x62, 0xb1, 0x01, 0x00, 0x6a, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x07, 0x16, 0xb0, 0x01, 0x00, 0x00, 0x62, 0x00, 0x0b,
-	0x16, 0xdc, 0x01, 0x00, 0x1e, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x84, 0x8f, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0xcc, 0x93, 0x00, 0x5f,
-	0x01, 0x10, 0x01, 0x00, 0x6e, 0x8f, 0x22, 0x40, 0x95, 0x6c, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x62, 0xb1, 0x01, 0x00, 0x76, 0x8f, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x41, 0x93, 0x00, 0x52,
-	0x95, 0x30, 0x01, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x6e, 0x8f, 0x22, 0x41, 0x97, 0x50, 0x00, 0x00, 0x0c, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5c, 0x01, 0x80, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b,
-	0x02, 0xb0, 0x00, 0x00, 0x6e, 0x8f, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
-	0xd4, 0x94, 0x00, 0x40, 0x03, 0x30, 0x01, 0x00, 0x17, 0x80, 0x00, 0x03,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x0c, 0x96, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0x63, 0x4c, 0x97, 0xf0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x03,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab, 0xe1, 0xb1, 0x01, 0x00,
-	0x75, 0x94, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07,
-	0x1a, 0xf4, 0x01, 0x00, 0x07, 0x00, 0x00, 0x07, 0x16, 0x88, 0x01, 0x00,
-	0x00, 0xb5, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00, 0x8e, 0x8f, 0x30, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x81, 0x01, 0x00,
-	0x00, 0xb7, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b,
-	0xe6, 0x81, 0x01, 0x00, 0x10, 0x00, 0x10, 0x0f, 0x94, 0xf4, 0x01, 0x00,
-	0x93, 0x04, 0x00, 0x5f, 0x95, 0x04, 0x01, 0x00, 0x22, 0x93, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x98, 0x8f, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00,
-	0x96, 0x8f, 0x46, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x41,
-	0x31, 0xd3, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x0f, 0xb0, 0x01, 0x00, 0x85, 0x92, 0x00, 0x41, 0x81, 0x30, 0x01, 0x00,
-	0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x8c, 0x92, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xa9, 0x8f, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x03, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00,
-	0xa2, 0x8f, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b,
-	0x62, 0xb1, 0x01, 0x00, 0xa6, 0x8f, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xa3, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x62, 0xb1, 0x01, 0x00, 0xa6, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x14, 0x87, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x74, 0x00, 0x22, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00,
-	0xc9, 0x94, 0x00, 0x4a, 0x95, 0x30, 0x01, 0x00, 0xa9, 0x93, 0x00, 0x5c,
-	0x1f, 0x10, 0x01, 0x00, 0x40, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x2f, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xba, 0x8f, 0x22, 0x47,
-	0xe7, 0x7d, 0x00, 0x00, 0x1e, 0x92, 0x00, 0x40, 0xe7, 0x31, 0x01, 0x00,
-	0xba, 0x8f, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0xb5, 0x8f, 0xa2, 0x40,
-	0x1f, 0x7c, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xba, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x32, 0x00, 0x2d, 0xf2, 0x94, 0xb0, 0x01, 0x00,
-	0x41, 0x93, 0x00, 0xf2, 0x02, 0x30, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b,
-	0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0xc9, 0x94, 0x00, 0x48, 0x95, 0x30, 0x01, 0x00, 0xa9, 0x93, 0x00, 0x5c,
-	0x1f, 0x10, 0x01, 0x00, 0xbf, 0x8f, 0x87, 0x42, 0x19, 0x10, 0x00, 0x00,
-	0x8b, 0x00, 0x2f, 0x47, 0x19, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xe7, 0x91, 0x01, 0x00, 0xf4, 0x94, 0x00, 0x42, 0x81, 0x30, 0x01, 0x00,
-	0xcf, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xa9, 0x93, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00,
-	0xba, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00, 0x2d, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0xc4, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0x61, 0x95, 0x00, 0xf0,
-	0x84, 0x30, 0x01, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xf4, 0x94, 0x00, 0x45, 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8a, 0x22, 0x42,
-	0x19, 0x7c, 0x00, 0x00, 0x83, 0x94, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00,
-	0xcf, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x8c, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xd3, 0x8f, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0x83, 0x94, 0x00, 0x47,
-	0x80, 0x30, 0x01, 0x00, 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00,
-	0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x10, 0x80, 0x00, 0x03,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0xe1, 0x00, 0xa6, 0x84, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x07, 0x84, 0x94, 0x01, 0x00,
-	0x75, 0x94, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x99, 0x92, 0x00, 0x41, 0xe7, 0x41, 0x01, 0x00, 0xd4, 0x8a, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x83, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x3c, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
-	0x2c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x0a,
-	0x2c, 0x50, 0x00, 0x00, 0x07, 0x95, 0x00, 0x06, 0x04, 0x30, 0x01, 0x00,
-	0xea, 0x8f, 0xa2, 0x48, 0x1f, 0x7c, 0x00, 0x00, 0xe8, 0x8f, 0x84, 0x48,
-	0x1f, 0x10, 0x00, 0x00, 0xac, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0xea, 0x8f, 0x00, 0x0a, 0xe0, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
-	0x02, 0xb0, 0x01, 0x00, 0xa7, 0x91, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0xeb, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00,
-	0xf8, 0x8f, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00, 0xf1, 0x93, 0x00, 0x45,
-	0x1f, 0x00, 0x01, 0x00, 0xe3, 0x8f, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0xf4, 0x8f, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xe3, 0x8f, 0x00, 0x05,
-	0x48, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00,
-	0x08, 0x00, 0x2d, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
-	0xb7, 0x93, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0xfe, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x04, 0x90, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40,
-	0x13, 0x30, 0x01, 0x00, 0x08, 0x90, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00,
-	0xf4, 0x94, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00, 0x08, 0x90, 0xa2, 0x47,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x19, 0x80, 0x01, 0x00,
-	0xff, 0x07, 0x00, 0x08, 0x00, 0x8c, 0x01, 0x00, 0x16, 0x90, 0x22, 0x4a,
-	0x1f, 0x7c, 0x00, 0x00, 0x0e, 0x90, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00,
-	0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
-	0xe7, 0xb1, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0x12, 0x90, 0x22, 0x42,
-	0x19, 0x7c, 0x00, 0x00, 0xc6, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x13, 0x90, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x96, 0x93, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x2a, 0xd0, 0x01, 0x00,
-	0x32, 0x00, 0x2a, 0x15, 0xe4, 0xb1, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x16,
-	0xe4, 0xb1, 0x00, 0x00, 0x28, 0x90, 0x22, 0x16, 0x02, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0x7d, 0x95, 0x00, 0x40,
-	0x95, 0x30, 0x01, 0x00, 0x29, 0x90, 0x22, 0x40, 0x11, 0x6c, 0x00, 0x00,
-	0xac, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xb0, 0x00, 0x2b, 0x01,
-	0xe0, 0xc1, 0x01, 0x00, 0x00, 0x2b, 0x00, 0xa6, 0x16, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0xe0, 0xd1, 0x01, 0x00, 0xcc, 0x94, 0x00, 0x08,
-	0x80, 0x30, 0x01, 0x00, 0x21, 0x90, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00,
-	0xed, 0x94, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x22, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0xd4, 0x94, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00, 0x75, 0x94, 0x00, 0x5e,
-	0x05, 0x10, 0x01, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xd4, 0x8a, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0x1f, 0x15, 0x1a, 0x50, 0x00, 0x00, 0x36, 0x90, 0x20, 0x16,
-	0x1a, 0x6c, 0x00, 0x00, 0x70, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x22, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
-	0x62, 0xdd, 0x01, 0x00, 0x33, 0x90, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0a, 0x2a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a,
-	0x2c, 0xd0, 0x01, 0x00, 0xac, 0x00, 0x2f, 0x40, 0x23, 0xb0, 0x01, 0x00,
-	0x3d, 0x90, 0x84, 0x45, 0x1f, 0x10, 0x00, 0x00, 0x3e, 0x90, 0x00, 0x0a,
-	0xe0, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x02, 0xb0, 0x01, 0x00,
-	0x34, 0x94, 0x00, 0x40, 0x35, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19,
-	0x42, 0xc9, 0x01, 0x00, 0x46, 0x90, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x42, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x55, 0x90, 0xa2, 0x02, 0x1a, 0x50, 0x00, 0x00,
-	0x56, 0x90, 0x22, 0x40, 0x2d, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08,
-	0xe0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x4d, 0x90, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf0, 0x10, 0xc8, 0x01, 0x00,
-	0xf0, 0x07, 0x00, 0x40, 0x1b, 0x98, 0x01, 0x00, 0x56, 0x90, 0x00, 0x5c,
-	0x11, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00,
-	0xaf, 0x92, 0x00, 0x40, 0x1f, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x5a, 0x90, 0x23, 0x0d, 0x2c, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x1f, 0x90, 0x01, 0x00, 0x62, 0x90, 0x22, 0x46,
-	0x1f, 0x7c, 0x00, 0x00, 0x70, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x62, 0x90, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x5e, 0x90, 0xa8, 0x46, 0x1f, 0x00, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x08, 0x00, 0x2d, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
-	0xb7, 0x93, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x67, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x6d, 0x90, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40,
-	0x13, 0x30, 0x01, 0x00, 0x71, 0x90, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00,
-	0xf4, 0x94, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00, 0x71, 0x90, 0xa2, 0x47,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x19, 0x80, 0x01, 0x00,
-	0xff, 0x07, 0x00, 0x08, 0x00, 0x8c, 0x01, 0x00, 0x86, 0x90, 0x22, 0x4a,
-	0x1f, 0x7c, 0x00, 0x00, 0x77, 0x90, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00,
-	0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
-	0xe7, 0xb1, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0x82, 0x90, 0x22, 0x42,
-	0x19, 0x7c, 0x00, 0x00, 0x7b, 0x90, 0xa2, 0xf3, 0x84, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xa5, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x85, 0xd0, 0x01, 0x00, 0xd4, 0x00, 0x3e, 0x41, 0x85, 0xe0, 0x01, 0x00,
-	0x7f, 0x90, 0x22, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a,
-	0x11, 0x90, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x08, 0xe4, 0xf5, 0x01, 0x00,
-	0xc6, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x83, 0x90, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x96, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x30, 0x00, 0x2e, 0x00, 0x2a, 0xd0, 0x01, 0x00, 0x32, 0x00, 0x2a, 0x15,
-	0xe4, 0xb1, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x16, 0xe4, 0xb1, 0x00, 0x00,
-	0x89, 0x90, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xd6, 0x90, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0x96, 0x90, 0x22, 0x47,
-	0x1f, 0x7c, 0x00, 0x00, 0x93, 0x90, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
-	0x8e, 0x90, 0xa2, 0xf3, 0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5,
-	0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x85, 0xd0, 0x01, 0x00,
-	0xd4, 0x00, 0x3e, 0x41, 0x85, 0xe0, 0x01, 0x00, 0x92, 0x90, 0x22, 0x40,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x11, 0x90, 0x01, 0x00,
-	0x0b, 0x00, 0x00, 0x08, 0xe4, 0xf5, 0x01, 0x00, 0x58, 0x01, 0x2d, 0x00,
-	0x2a, 0xd0, 0x01, 0x00, 0x60, 0x01, 0x2d, 0xf0, 0x10, 0xb0, 0x01, 0x00,
-	0x2d, 0x8e, 0x00, 0xf0, 0x2c, 0xb0, 0x00, 0x00, 0x7d, 0x95, 0x00, 0x41,
-	0x95, 0x30, 0x01, 0x00, 0x9d, 0x90, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x97, 0xb0, 0x01, 0x00, 0x9b, 0x90, 0x23, 0x0d,
-	0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x97, 0xc0, 0x01, 0x00,
-	0x48, 0x93, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0xd6, 0x90, 0x00, 0x05,
-	0x48, 0xb1, 0x00, 0x00, 0xac, 0x00, 0x2f, 0x01, 0x14, 0xb0, 0x01, 0x00,
-	0xb0, 0x00, 0x2b, 0x01, 0xe0, 0xc1, 0x01, 0x00, 0x00, 0x2b, 0x00, 0xa6,
-	0x16, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0xd1, 0x01, 0x00,
-	0xad, 0x90, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
-	0xa6, 0x90, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf0,
-	0x22, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x23, 0x80, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0x84, 0xb0, 0x01, 0x00, 0xb0, 0x90, 0x23, 0x0d,
-	0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x02, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x08, 0x80, 0xb0, 0x01, 0x00, 0xb5, 0x90, 0x22, 0x40,
-	0x1b, 0x6c, 0x00, 0x00, 0xcc, 0x94, 0x00, 0x01, 0x84, 0x50, 0x01, 0x00,
-	0xbd, 0x90, 0x22, 0x40, 0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-	0x80, 0xc0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x10, 0x46, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4f, 0x43, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0xf0, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x40, 0xf0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa1, 0x62, 0xdd, 0x01, 0x00,
-	0xbb, 0x90, 0xa8, 0x11, 0xe0, 0x31, 0x00, 0x00, 0xcc, 0x90, 0x00, 0x5e,
-	0x17, 0x90, 0x00, 0x00, 0xc0, 0x90, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x0d, 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
-	0x84, 0xd0, 0x01, 0x00, 0xc5, 0x90, 0x22, 0x40, 0x1b, 0x6c, 0x00, 0x00,
-	0xed, 0x94, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00, 0xcc, 0x90, 0x22, 0x40,
-	0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x12, 0xc0, 0x01, 0x00,
-	0x10, 0x80, 0x00, 0x10, 0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f,
-	0x43, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
-	0xf0, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa1, 0x62, 0xdd, 0x01, 0x00,
-	0xca, 0x90, 0xa8, 0x11, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0xcd, 0x90, 0xa8, 0x0a, 0x02, 0x30, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x99, 0x92, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00,
-	0xd4, 0x90, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00, 0xff, 0x07, 0x00, 0x11,
-	0x00, 0x8c, 0x01, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xd4, 0x94, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00, 0x75, 0x94, 0x00, 0x5e,
-	0x05, 0x10, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
-	0xd4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03,
-	0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x8e, 0xb0, 0x01, 0x00, 0x80, 0x93, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00, 0xb7, 0x93, 0x00, 0x41,
-	0x87, 0x30, 0x01, 0x00, 0x3c, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0xe7, 0x90, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xe3, 0x90, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0xe9, 0x90, 0x22, 0x09,
-	0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15,
-	0x1a, 0xd0, 0x01, 0x00, 0xef, 0x90, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0x7d, 0x95, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00, 0xf7, 0x90, 0x22, 0x08,
-	0x80, 0x32, 0x00, 0x00, 0x1a, 0x90, 0x00, 0x00, 0x2a, 0xc0, 0x00, 0x00,
-	0x7d, 0x95, 0x00, 0x41, 0x95, 0x30, 0x01, 0x00, 0xf2, 0x90, 0x22, 0x08,
-	0x80, 0x32, 0x00, 0x00, 0x9d, 0x90, 0x00, 0x00, 0x2a, 0xc0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x97, 0xb0, 0x01, 0x00, 0xf5, 0x90, 0x23, 0x0d,
-	0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x97, 0xc0, 0x01, 0x00,
-	0x48, 0x93, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0xcf, 0x8a, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
-	0x83, 0x94, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xfb, 0x90, 0x00, 0x4a, 0x1f, 0x90, 0x00, 0x00,
-	0xc1, 0x92, 0x00, 0x00, 0x10, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15,
-	0x10, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
-	0x07, 0x95, 0x00, 0x06, 0x04, 0x30, 0x01, 0x00, 0x04, 0x91, 0xa2, 0x44,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0a, 0x2c, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a,
-	0x02, 0xb0, 0x01, 0x00, 0xa7, 0x91, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00, 0x0b, 0x91, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x07, 0x91, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
-	0x10, 0xc0, 0x01, 0x00, 0x14, 0x91, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00,
-	0xf1, 0x93, 0x00, 0x45, 0x1f, 0x00, 0x01, 0x00, 0xfd, 0x90, 0x22, 0x5c,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x10, 0x91, 0xa8, 0x5c,
-	0x1f, 0x00, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0xfd, 0x90, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x08, 0x00, 0x2d, 0x40,
-	0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x82, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00, 0xb7, 0x93, 0x00, 0x41,
-	0x87, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x19, 0x91, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x1f, 0x91, 0x22, 0x09,
-	0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
-	0x22, 0x91, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x4f,
-	0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x19, 0x80, 0x01, 0x00,
-	0xff, 0x07, 0x00, 0x08, 0x00, 0x8c, 0x01, 0x00, 0x30, 0x91, 0x22, 0x4a,
-	0x1f, 0x7c, 0x00, 0x00, 0x28, 0x91, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00,
-	0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
-	0xe7, 0xb1, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0x2c, 0x91, 0x22, 0x42,
-	0x19, 0x7c, 0x00, 0x00, 0xc6, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x2d, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x96, 0x93, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x2a, 0xd0, 0x01, 0x00,
-	0x32, 0x00, 0x2a, 0x15, 0xe4, 0xb1, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x16,
-	0xe4, 0xb1, 0x00, 0x00, 0x17, 0x90, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00,
-	0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
-	0xe7, 0xb1, 0x01, 0x00, 0xd4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xc1, 0x92, 0x00, 0x4a, 0x1f, 0x10, 0x01, 0x00, 0x2b, 0x90, 0x00, 0x10,
-	0x32, 0xb0, 0x00, 0x00, 0x8a, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
-	0x3a, 0x91, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x3d, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x41, 0x93, 0x00, 0x15, 0x94, 0x30, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b,
-	0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x3f, 0x91, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x83, 0x94, 0x00, 0x3a,
-	0x81, 0x30, 0x01, 0x00, 0xf4, 0x94, 0x00, 0x45, 0x81, 0x30, 0x01, 0x00,
-	0xcf, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xec, 0x8e, 0x00, 0x45,
-	0x1f, 0x90, 0x00, 0x00, 0x83, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x3c, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2b, 0x90, 0x00, 0x01,
-	0x2c, 0xb0, 0x00, 0x00, 0x8c, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x51, 0x91, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02,
-	0x04, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x03, 0xf0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00, 0x4a, 0x91, 0x37, 0x5c,
-	0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x62, 0xb1, 0x01, 0x00,
-	0x4e, 0x91, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x4b, 0x91, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0xb1, 0x01, 0x00,
-	0x4e, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x14, 0x87, 0x17, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x58, 0x01, 0x20, 0x08, 0xe0, 0xb1, 0x01, 0x00,
-	0x60, 0x01, 0x20, 0x16, 0xe0, 0xb1, 0x01, 0x00, 0x83, 0x93, 0x00, 0x47,
-	0x1f, 0x10, 0x01, 0x00, 0x3c, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x2b, 0x90, 0x00, 0x01, 0x2c, 0xb0, 0x00, 0x00, 0x8c, 0x92, 0x00, 0x47,
-	0x1f, 0x10, 0x01, 0x00, 0x63, 0x91, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
-	0x5f, 0x91, 0xa2, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02,
-	0x04, 0xdc, 0x01, 0x00, 0xa0, 0x98, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
-	0x30, 0x05, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00, 0x41, 0x93, 0x00, 0x15,
-	0x94, 0x30, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
-	0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc6, 0x93, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x19, 0x90, 0x01, 0x00,
-	0x83, 0x94, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00, 0x14, 0x87, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x58, 0x01, 0x20, 0x08, 0xe0, 0xb1, 0x01, 0x00,
-	0x60, 0x01, 0x20, 0x16, 0xe0, 0xb1, 0x01, 0x00, 0xc1, 0x92, 0x00, 0x10,
-	0x32, 0x30, 0x01, 0x00, 0x2b, 0x90, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00,
-	0x8c, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x73, 0x91, 0xa2, 0x08,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x03, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
-	0x00, 0xc0, 0x01, 0x00, 0x6c, 0x91, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x1b, 0x62, 0xb1, 0x01, 0x00, 0x70, 0x91, 0x28, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x6d, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x62, 0xb1, 0x01, 0x00, 0x70, 0x91, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x14, 0x87, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x8c, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x8e, 0xb0, 0x01, 0x00, 0x80, 0x93, 0x00, 0x40,
-	0x13, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00,
-	0xb7, 0x93, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00, 0x3c, 0x93, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
-	0x82, 0x91, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x7e, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
-	0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x2d, 0x8e, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40,
-	0x13, 0x30, 0x01, 0x00, 0x2d, 0x8e, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x14, 0x00, 0x2d, 0x45, 0x1f, 0x90, 0x01, 0x00, 0x75, 0x8e, 0x00, 0x44,
-	0x19, 0x90, 0x00, 0x00, 0x8a, 0x91, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4a, 0x1f, 0x90, 0x01, 0x00, 0xdd, 0x8f, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x83, 0x93, 0x00, 0x4a, 0x1f, 0x10, 0x01, 0x00,
-	0x3c, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2b, 0x90, 0x00, 0x01,
-	0x2c, 0xb0, 0x00, 0x00, 0xc1, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x2b, 0x90, 0x00, 0x10, 0x32, 0xb0, 0x00, 0x00, 0xec, 0x8e, 0x00, 0x45,
-	0x1f, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x37, 0xc3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x33, 0xc3, 0x01, 0x00, 0x36, 0x00, 0x00, 0x01,
-	0x02, 0xcc, 0x01, 0x00, 0x00, 0x00, 0xd2, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x96, 0x91, 0x85, 0x17, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x48,
-	0x03, 0xd0, 0x00, 0x00, 0x98, 0x91, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x9f, 0x4c, 0x03, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01,
-	0x34, 0xc3, 0x01, 0x00, 0x40, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4a, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x12, 0xf0, 0xb1, 0x01, 0x00,
-	0x9d, 0x92, 0x00, 0x41, 0xe1, 0x31, 0x01, 0x00, 0x00, 0x80, 0x00, 0x43,
-	0x44, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
-	0xf0, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x03, 0xe0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xa4, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xba, 0x00, 0x20, 0x40,
-	0xe5, 0xb1, 0x01, 0x00, 0xb0, 0x00, 0x2f, 0x01, 0x8c, 0xd0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x46, 0xe0, 0xc1, 0x01, 0x00, 0xac, 0x00, 0x2f, 0x40,
-	0x13, 0xb0, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0x01, 0xe0, 0xc1, 0x01, 0x00,
-	0xae, 0x91, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00, 0x84, 0x95, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xb0, 0x91, 0x22, 0x47, 0x19, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x13, 0x90, 0x01, 0x00, 0x2d, 0x95, 0x00, 0x47,
-	0x19, 0x10, 0x01, 0x00, 0xc0, 0x00, 0x2d, 0x44, 0x1f, 0x90, 0x01, 0x00,
-	0xc4, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0x61, 0x95, 0x00, 0xf0,
-	0x84, 0xb0, 0x00, 0x00, 0x90, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0xc5, 0x91, 0xa2, 0x4b, 0x1f, 0x7c, 0x00, 0x00, 0x18, 0x92, 0xa2, 0x4c,
-	0x1f, 0x7c, 0x00, 0x00, 0xc5, 0x91, 0x1f, 0x1c, 0xe0, 0x6d, 0x00, 0x00,
-	0xc8, 0x91, 0xa2, 0x01, 0x80, 0x32, 0x00, 0x00, 0xa8, 0x00, 0x2d, 0x46,
-	0x8f, 0xb0, 0x01, 0x00, 0xbe, 0x91, 0x1f, 0x1c, 0xe0, 0x6d, 0x00, 0x00,
-	0xb4, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xc0, 0x91, 0x22, 0xf0,
-	0x3a, 0x6c, 0x00, 0x00, 0x15, 0x92, 0x1f, 0xf0, 0x3a, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0xa2, 0x40, 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x4f,
-	0x8f, 0xb0, 0x01, 0x00, 0x8a, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x16, 0x92, 0x20, 0x42, 0xe7, 0x6d, 0x00, 0x00, 0xc4, 0x91, 0x22, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x59, 0x8f, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x58, 0x8f, 0xb0, 0x01, 0x00, 0xc7, 0x91, 0x22, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x5c, 0x8f, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x5b, 0x8f, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0xb0, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00,
-	0xcc, 0x91, 0xa2, 0x42, 0x24, 0x6c, 0x00, 0x00, 0xd5, 0x91, 0x23, 0xf0,
-	0x02, 0x6c, 0x00, 0x00, 0xd2, 0x91, 0xa2, 0xf0, 0x80, 0x32, 0x00, 0x00,
-	0x17, 0x92, 0xa2, 0x42, 0x24, 0x6c, 0x00, 0x00, 0x17, 0x92, 0xa2, 0x41,
-	0x03, 0x6c, 0x00, 0x00, 0xd1, 0x91, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x51, 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x52,
-	0x8f, 0xb0, 0x01, 0x00, 0x17, 0x92, 0x1f, 0x12, 0x84, 0x50, 0x00, 0x00,
-	0x17, 0x92, 0xa0, 0x01, 0x84, 0x6c, 0x00, 0x00, 0xc5, 0x91, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x00, 0x92, 0xa2, 0x46, 0xe7, 0x7d, 0x00, 0x00, 0x14, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0xf2, 0x91, 0x22, 0xf0, 0x14, 0x30, 0x00, 0x00,
-	0xde, 0x91, 0x20, 0x0a, 0x02, 0x6c, 0x00, 0x00, 0xef, 0x91, 0x03, 0x1e,
-	0x80, 0x32, 0x00, 0x00, 0xdd, 0x91, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x44, 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x49,
-	0x8f, 0xb0, 0x01, 0x00, 0xe3, 0x91, 0x22, 0x0a, 0x02, 0x6c, 0x00, 0x00,
-	0xe6, 0x91, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xe2, 0x91, 0xa2, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x55, 0x8f, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x56, 0x8f, 0xb0, 0x01, 0x00, 0xe5, 0x91, 0xa2, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43, 0x8f, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x48, 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
-	0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x82, 0xd0, 0x01, 0x00,
-	0xec, 0x91, 0x20, 0x91, 0x83, 0x6c, 0x00, 0x00, 0xeb, 0x91, 0xa2, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x26, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
-	0x27, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00, 0xee, 0x91, 0xa2, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x1f, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
-	0x20, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00, 0xf1, 0x91, 0xa2, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x22, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
-	0x23, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x88, 0x00, 0x2d, 0x44,
-	0x8f, 0xb0, 0x01, 0x00, 0xfb, 0x91, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0xf8, 0x91, 0xa2, 0x43, 0x3d, 0x7c, 0x00, 0x00, 0xf8, 0x91, 0xa2, 0xf2,
-	0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x40, 0x80, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00, 0xfa, 0x91, 0xa2, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43, 0x8f, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x48, 0x8f, 0xb0, 0x01, 0x00, 0xf8, 0x91, 0xa0, 0x91,
-	0x03, 0x6c, 0x00, 0x00, 0xf6, 0x91, 0x22, 0x43, 0x3d, 0x7c, 0x00, 0x00,
-	0xff, 0x91, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x28, 0x00, 0x80, 0x40,
-	0x8f, 0x98, 0x01, 0x00, 0x29, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
-	0x14, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x09, 0x92, 0xa2, 0xf0,
-	0x14, 0x30, 0x00, 0x00, 0x88, 0x00, 0x2d, 0x44, 0x8f, 0xb0, 0x01, 0x00,
-	0x06, 0x92, 0xa2, 0xf2, 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x40,
-	0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00,
-	0xf8, 0x91, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xf6, 0x91, 0x20, 0x91,
-	0x03, 0x6c, 0x00, 0x00, 0xf8, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x0d, 0x92, 0x20, 0x0a, 0x02, 0x6c, 0x00, 0x00, 0x0c, 0x92, 0xa2, 0x40,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x44, 0x8f, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00, 0x12, 0x92, 0x22, 0x0a,
-	0x02, 0x6c, 0x00, 0x00, 0xe6, 0x91, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
-	0x11, 0x92, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x55,
-	0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x56, 0x8f, 0xb0, 0x01, 0x00,
-	0x14, 0x92, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43,
-	0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x48, 0x8f, 0xb0, 0x01, 0x00,
-	0x1a, 0x92, 0x00, 0x43, 0x95, 0xb0, 0x00, 0x00, 0x1a, 0x92, 0x00, 0x41,
-	0x95, 0xb0, 0x00, 0x00, 0x1a, 0x92, 0x00, 0x42, 0x95, 0xb0, 0x00, 0x00,
-	0x1a, 0x92, 0x00, 0x44, 0x95, 0xb0, 0x00, 0x00, 0x1a, 0x92, 0x00, 0x4c,
-	0x95, 0xb0, 0x00, 0x00, 0xc9, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x1d, 0x92, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x4b,
-	0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x4c, 0x8f, 0xb0, 0x01, 0x00,
-	0x2d, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x2e, 0x00, 0x2f, 0xf3,
-	0x84, 0xb0, 0x01, 0x00, 0x22, 0x92, 0xa2, 0xf3, 0x96, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x01, 0xb0, 0x01, 0x00, 0x2d, 0x00, 0x2a, 0x41,
-	0xe7, 0xd1, 0x01, 0x00, 0xd4, 0x00, 0x3d, 0x41, 0x85, 0xe0, 0x01, 0x00,
-	0x0b, 0x00, 0x00, 0xf2, 0x00, 0xe4, 0x01, 0x00, 0x28, 0x92, 0x22, 0x5a,
-	0x01, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1f, 0x90, 0x01, 0x00,
-	0x29, 0x92, 0x00, 0x5a, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x1f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x63, 0x41, 0x85, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0xa0, 0xa5, 0x85, 0x6c, 0x01, 0x00, 0x00, 0x00, 0xe3, 0x40,
-	0x85, 0xb0, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x12, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0xc6, 0x95, 0x00, 0xf0,
-	0x8c, 0xb0, 0x00, 0x00, 0x36, 0x92, 0x22, 0x40, 0x0f, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x33, 0x92, 0xa2, 0x4b,
-	0x19, 0x7c, 0x00, 0x00, 0x34, 0x92, 0x22, 0xf0, 0x18, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x60, 0x4b, 0x19, 0x90, 0x01, 0x00, 0xff, 0x92, 0x00, 0x07,
-	0x10, 0x30, 0x01, 0x00, 0xf9, 0x82, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
-	0x38, 0x92, 0x22, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0x85, 0x92, 0x00, 0x40,
-	0x81, 0x30, 0x01, 0x00, 0xf9, 0x82, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x4b,
-	0x19, 0x90, 0x01, 0x00, 0xff, 0x92, 0x00, 0x07, 0x10, 0x30, 0x01, 0x00,
-	0xf9, 0x82, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x4b, 0x19, 0x90, 0x01, 0x00,
-	0xff, 0x92, 0x00, 0x07, 0x10, 0x30, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x05, 0xb0, 0x01, 0x00, 0x41, 0x92, 0x33, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x44, 0x92, 0xa1, 0xad, 0x95, 0x20, 0x00, 0x00, 0x52, 0x92, 0x13, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x13, 0x4a, 0x5a, 0x83, 0x01, 0x00,
-	0x30, 0x00, 0x39, 0x45, 0x95, 0xe0, 0x01, 0x00, 0x1f, 0x00, 0x00, 0x0f,
-	0x5e, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x5f, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x45, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04,
-	0x48, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x4a, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x0c, 0x58, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07,
-	0x4e, 0xb0, 0x01, 0x00, 0xa2, 0x84, 0x00, 0x40, 0x5d, 0x98, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x58, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
-	0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x41, 0x97, 0xb0, 0x00, 0x00,
-	0x4f, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x97, 0xb0, 0x01, 0x00, 0x53, 0x92, 0x60, 0x07, 0x96, 0x30, 0x00, 0x00,
-	0xff, 0xff, 0x00, 0x4b, 0x84, 0x89, 0x01, 0x00, 0x00, 0x00, 0x70, 0xc2,
-	0x24, 0xb0, 0x01, 0x00, 0x5d, 0x92, 0xa2, 0x45, 0x25, 0x7c, 0x00, 0x00,
-	0x57, 0x92, 0x31, 0x20, 0x85, 0x30, 0x00, 0x00, 0x5e, 0x92, 0x22, 0x12,
-	0x48, 0x7f, 0x00, 0x00, 0x58, 0x04, 0x11, 0x12, 0x48, 0x03, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x12, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x1e, 0x94, 0x01, 0x00, 0x00, 0x00, 0x80, 0x5a, 0x1f, 0x90, 0x01, 0x00,
-	0x5d, 0x92, 0x31, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4,
-	0x24, 0xb0, 0x01, 0x00, 0x5e, 0x92, 0x22, 0x12, 0x48, 0x7f, 0x00, 0x00,
-	0x58, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x6b, 0x92, 0x0b, 0xf0, 0x84, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x11, 0x12, 0x48, 0x83, 0x01, 0x00, 0x68, 0x92, 0x22, 0x50,
-	0x85, 0x70, 0x00, 0x00, 0x5e, 0x01, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x2a, 0x94, 0x00, 0xf2, 0x96, 0x30, 0x01, 0x00, 0x93, 0x04, 0x00, 0x12,
-	0x94, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x1f, 0x90, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x12, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x80, 0x4b,
-	0x1e, 0x94, 0x01, 0x00, 0x10, 0x00, 0x00, 0x42, 0x10, 0xf4, 0x01, 0x00,
-	0x00, 0xb7, 0x3f, 0x43, 0x11, 0xf0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x08,
-	0x8a, 0x88, 0x01, 0x00, 0x6e, 0x92, 0x30, 0xa1, 0x0c, 0x30, 0x00, 0x00,
-	0x71, 0x92, 0x22, 0x45, 0xe6, 0x7d, 0x00, 0x00, 0x5e, 0x92, 0x10, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x45, 0xe6, 0x91, 0x01, 0x00,
-	0x00, 0x00, 0x10, 0x12, 0x48, 0x83, 0x01, 0x00, 0x00, 0x00, 0x11, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x60, 0x4b, 0x85, 0x80, 0x01, 0x00,
-	0x5e, 0x01, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x2a, 0x94, 0x00, 0xf2,
-	0x96, 0x30, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
-	0xd8, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x2e, 0x00, 0x2d, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x7c, 0x92, 0x22, 0x40, 0xe7, 0x6d, 0x00, 0x00,
-	0x80, 0x00, 0x00, 0x40, 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf0, 0xb1, 0x01, 0x00, 0x09, 0x00, 0x00, 0x08, 0x86, 0xe4, 0x01, 0x00,
-	0x00, 0x00, 0x68, 0xa7, 0x87, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
-	0x80, 0x92, 0xa8, 0x05, 0xe0, 0x31, 0x00, 0x00, 0x10, 0x00, 0x00, 0x12,
-	0x96, 0xe4, 0x01, 0x00, 0x00, 0x14, 0x00, 0x4b, 0x96, 0xdc, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x4b, 0x1e, 0x94, 0x01, 0x00, 0x10, 0x00, 0x00, 0x0f,
-	0x84, 0xf4, 0x01, 0x00, 0x1f, 0x00, 0x00, 0x42, 0x84, 0x88, 0x01, 0x00,
-	0x89, 0x92, 0x22, 0x40, 0x80, 0x32, 0x00, 0x00, 0x8a, 0x92, 0x00, 0x42,
-	0x68, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x6a, 0xb1, 0x01, 0x00,
-	0x8a, 0x92, 0x31, 0x5a, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x42,
-	0x48, 0x93, 0x01, 0x00, 0x8c, 0x92, 0x35, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x91, 0x92, 0x28, 0xb1,
-	0x2c, 0x30, 0x00, 0x00, 0x8d, 0x92, 0x22, 0x4d, 0x75, 0x7d, 0x00, 0x00,
-	0x00, 0x00, 0x95, 0x40, 0x11, 0xb0, 0x01, 0x00, 0x6d, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0x91, 0x92, 0xa8, 0xb1, 0x10, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x95, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x7f, 0x00, 0x00, 0x40,
-	0x61, 0x99, 0x01, 0x00, 0x98, 0x92, 0x28, 0xb1, 0x10, 0x30, 0x00, 0x00,
-	0x94, 0x92, 0x9f, 0xba, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x11, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x24, 0x11, 0x84, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00,
-	0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x9a, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xac, 0x94, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x9e, 0x92, 0x32, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xa4, 0x92, 0x22, 0xf8, 0x96, 0x30, 0x00, 0x00, 0x04, 0x00, 0x22, 0xf8,
-	0x90, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x92, 0xb0, 0x01, 0x00,
-	0x01, 0x00, 0x00, 0x4b, 0xf0, 0xcd, 0x01, 0x00, 0x20, 0x00, 0x92, 0x48,
-	0xe0, 0xc9, 0x01, 0x00, 0x6c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
-	0xa8, 0x92, 0x28, 0xb1, 0x92, 0x30, 0x00, 0x00, 0xa4, 0x92, 0x22, 0x4c,
-	0x75, 0x7d, 0x00, 0x00, 0x04, 0x00, 0x12, 0x40, 0x91, 0xb0, 0x00, 0x00,
-	0x6c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xa8, 0x92, 0xa8, 0xb1,
-	0x90, 0x30, 0x00, 0x00, 0xff, 0x00, 0x00, 0x48, 0x96, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4b, 0x90, 0xd0, 0x01, 0x00, 0x01, 0x00, 0x00, 0x4b,
-	0xf0, 0xcd, 0x01, 0x00, 0x20, 0x00, 0x00, 0x48, 0xf0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x92, 0x49, 0xe0, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x10,
-	0x48, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08, 0x82, 0x8c, 0x01, 0x00,
-	0xff, 0x07, 0x00, 0xf0, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x41,
-	0x00, 0xec, 0x00, 0x00, 0xb5, 0x92, 0x22, 0x1a, 0x00, 0x6c, 0x00, 0x00,
-	0x99, 0x92, 0x00, 0x00, 0x34, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x49, 0xc1, 0x01, 0x00, 0xb1, 0x92, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x10,
-	0x48, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x15, 0x82, 0x8c, 0x01, 0x00,
-	0xff, 0x07, 0x00, 0xf0, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x41,
-	0x00, 0xec, 0x00, 0x00, 0xbe, 0x92, 0x22, 0x0d, 0x00, 0x6c, 0x00, 0x00,
-	0x99, 0x92, 0x00, 0x00, 0x1a, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0x49, 0xc1, 0x01, 0x00, 0xba, 0x92, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xc3, 0x92, 0x83, 0x1e,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x19, 0x90, 0x01, 0x00,
-	0x24, 0x00, 0x2d, 0x01, 0x2c, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x2d, 0xf0,
-	0x16, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00,
-	0x14, 0x00, 0x2f, 0xf2, 0x0c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0xe1, 0xb1, 0x01, 0x00, 0x30, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
-	0x60, 0x97, 0x2e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0xca, 0x92, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
-	0x64, 0x97, 0x3e, 0x43, 0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0xe1, 0xb1, 0x01, 0x00, 0x64, 0x97, 0x3e, 0x43, 0x9d, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x0b, 0xe8, 0xb1, 0x01, 0x00, 0x64, 0x97, 0x3f, 0x43,
-	0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x16, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x64, 0x97, 0x3f, 0x43,
-	0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x16, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x60, 0x17, 0x3d, 0x43,
-	0x9d, 0xe0, 0x01, 0x00, 0x10, 0x00, 0x80, 0xa1, 0x16, 0xe4, 0x01, 0x00,
-	0x00, 0xb5, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00, 0xd9, 0x92, 0x30, 0x47,
-	0x17, 0x04, 0x00, 0x00, 0xdc, 0x92, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
-	0x00, 0x00, 0x90, 0x42, 0x81, 0xb0, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x0d,
-	0x46, 0xc9, 0x01, 0x00, 0xe0, 0x92, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x0b, 0xe6, 0x91, 0x01, 0x00, 0x00, 0x00, 0x90, 0x41,
-	0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0xe1, 0x92, 0x40, 0x07, 0x96, 0x30, 0x00, 0x00, 0x9d, 0x04, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0xeb, 0x92, 0xa2, 0x45, 0x95, 0x7c, 0x00, 0x00,
-	0x01, 0x97, 0x3f, 0x41, 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
-	0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xe6, 0xb1, 0x01, 0x00,
-	0x40, 0x97, 0x3e, 0x40, 0x97, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e,
-	0xe6, 0xb1, 0x01, 0x00, 0x40, 0x97, 0x3e, 0x40, 0x9d, 0xe0, 0x01, 0x00,
-	0xfe, 0x92, 0x00, 0x3b, 0xe7, 0xb1, 0x00, 0x00, 0xeb, 0x92, 0x30, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xf5, 0x92, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
-	0x00, 0xb5, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00, 0xf1, 0x92, 0xa2, 0x0b,
-	0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x98, 0x42, 0x81, 0xb0, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x0d,
-	0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x91, 0x01, 0x00,
-	0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x98, 0x41,
-	0x81, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x21, 0xa2, 0x95, 0x20, 0x00, 0x00,
-	0x00, 0x00, 0x10, 0x4a, 0x44, 0x83, 0x01, 0x00, 0x00, 0x97, 0x3e, 0x41,
-	0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xf6, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4e, 0xe6, 0xb1, 0x01, 0x00, 0x40, 0x97, 0x3e, 0x40,
-	0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x3b, 0xe7, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0x07,
-	0x92, 0x89, 0x01, 0x00, 0x00, 0x00, 0x98, 0x40, 0x81, 0xb0, 0x01, 0x00,
-	0x03, 0x00, 0x00, 0x08, 0x86, 0xf4, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x43,
-	0x46, 0xc9, 0x01, 0x00, 0x07, 0x00, 0x00, 0x08, 0x82, 0x88, 0x01, 0x00,
-	0x02, 0x93, 0x40, 0x08, 0x96, 0x30, 0x00, 0x00, 0x9d, 0x04, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x0e, 0x93, 0x22, 0x45, 0x95, 0x7c, 0x00, 0x00,
-	0x0a, 0x93, 0x22, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x0f,
-	0x96, 0xf4, 0x01, 0x00, 0x07, 0x93, 0x31, 0x5f, 0x97, 0x04, 0x00, 0x00,
-	0x00, 0x00, 0x11, 0x4b, 0x48, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x6a, 0xb1, 0x01, 0x00, 0x0a, 0x93, 0x30, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0xe6, 0x81, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x97, 0x3f, 0x41, 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
-	0x96, 0xb0, 0x01, 0x00, 0x40, 0x97, 0x3d, 0x40, 0x97, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x63, 0xf3, 0x88, 0xb0, 0x01, 0x00, 0x16, 0x93, 0xa2, 0x3b,
-	0x89, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00,
-	0x01, 0x00, 0x00, 0xa6, 0x92, 0xb1, 0x01, 0x00, 0x17, 0x93, 0x18, 0x4a,
-	0x44, 0x93, 0x00, 0x00, 0x00, 0x00, 0x18, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x30, 0x00, 0x39, 0x45, 0x97, 0xe0, 0x01, 0x00, 0x1c, 0x93, 0x22, 0x5a,
-	0x1f, 0x7c, 0x00, 0x00, 0x1f, 0x04, 0x00, 0x0f, 0x98, 0xd8, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0x5e, 0x94, 0x01, 0x00, 0x1e, 0x93, 0x00, 0x05,
-	0x4a, 0xb0, 0x00, 0x00, 0x1f, 0x04, 0x00, 0xa7, 0x5e, 0x84, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x4b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x58,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1f, 0x93, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x22, 0x93, 0x40, 0x07, 0x96, 0x30, 0x00, 0x00,
-	0x9d, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x26, 0x93, 0x22, 0x45,
-	0x95, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x9b, 0x04, 0x00, 0x4a, 0x44, 0x13, 0x01, 0x00, 0x00, 0x97, 0x3f, 0x41,
-	0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00,
-	0x40, 0x97, 0x3d, 0x40, 0x97, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x63, 0xf3,
-	0x88, 0xb0, 0x01, 0x00, 0x30, 0x00, 0x38, 0x45, 0x97, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x0f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x58,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00,
-	0x2e, 0x93, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x27, 0x93, 0xa2, 0x3b,
-	0x89, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x38, 0x45, 0x9d, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x93, 0x04, 0x00, 0x12,
-	0x94, 0x30, 0x01, 0x00, 0xff, 0x92, 0x00, 0x5a, 0x1f, 0x00, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x5a, 0x1f, 0x90, 0x01, 0x00, 0x11, 0x00, 0x00, 0x4a,
-	0xe6, 0xc9, 0x01, 0x00, 0x34, 0x00, 0x2f, 0x4f, 0x95, 0x84, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x63, 0x4b,
-	0x84, 0xc8, 0x01, 0x00, 0x00, 0x00, 0xa0, 0x43, 0x85, 0x6c, 0x01, 0x00,
-	0x00, 0x00, 0xe3, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x30, 0x00, 0x2d, 0x44,
-	0x1f, 0x90, 0x01, 0x00, 0x32, 0x00, 0x2d, 0xf2, 0x2a, 0xb0, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0xf2, 0x02, 0x30, 0x00, 0x00, 0x1e, 0x92, 0x00, 0x10,
-	0x32, 0x30, 0x01, 0x00, 0x32, 0x00, 0xa0, 0x40, 0xe5, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
-	0x99, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x02, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x03, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x97, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xa3, 0x4c, 0x02, 0xd0, 0x00, 0x00,
-	0x45, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
-	0x36, 0xb0, 0x01, 0x00, 0x55, 0x93, 0x22, 0x41, 0x03, 0x50, 0x00, 0x00,
-	0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
-	0xf1, 0xb1, 0x01, 0x00, 0x70, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
-	0x62, 0xb1, 0x01, 0x00, 0x4e, 0x93, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x7c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x00, 0xb0, 0x01, 0x00, 0x49, 0x93, 0x00, 0x5c,
-	0x01, 0x80, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x1b, 0x10, 0xb1, 0x00, 0x00, 0x68, 0x01, 0x2d, 0x06,
-	0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x82, 0xc0, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x03, 0x46, 0xc9, 0x01, 0x00, 0x94, 0x92, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x7c, 0x93, 0x22, 0x40, 0x11, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x68, 0x08, 0x38, 0x96, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x41,
-	0x82, 0xcc, 0x01, 0x00, 0x5a, 0x93, 0xaa, 0x41, 0x3b, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
-	0x11, 0x80, 0x01, 0x00, 0x01, 0x00, 0x00, 0x1d, 0x04, 0xcc, 0x01, 0x00,
-	0x7b, 0x93, 0x26, 0x46, 0x23, 0x30, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03,
-	0x12, 0xc8, 0x01, 0x00, 0x64, 0x01, 0x20, 0xf0, 0xe0, 0xb1, 0x01, 0x00,
-	0x7a, 0x93, 0x22, 0x41, 0x05, 0x50, 0x00, 0x00, 0x20, 0x00, 0x00, 0x03,
-	0x48, 0xc9, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xf8, 0x86, 0xc8, 0x01, 0x00,
-	0x00, 0x00, 0x22, 0x44, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0xe0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
-	0x62, 0xdd, 0x01, 0x00, 0x6c, 0x93, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
-	0x79, 0x93, 0x22, 0x41, 0x05, 0x50, 0x00, 0x00, 0x77, 0x93, 0xa2, 0x41,
-	0x23, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x1a, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x72, 0x93, 0xa8, 0x46, 0x23, 0x30, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03,
-	0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x42, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x13, 0xc0, 0x01, 0x00, 0x67, 0x93, 0x00, 0x50,
-	0x49, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0x04, 0x80, 0x00, 0x03, 0x1a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x7b, 0x93, 0x22, 0x40, 0x3b, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x00, 0xb0, 0x01, 0x00, 0x99, 0x92, 0x00, 0x5c,
-	0x01, 0x00, 0x01, 0x00, 0x7c, 0x93, 0x00, 0x41, 0x3b, 0xd0, 0x00, 0x00,
-	0x00, 0x00, 0x8d, 0x47, 0x80, 0x32, 0x01, 0x00, 0xb0, 0x00, 0x2f, 0x5f,
-	0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xe0, 0xf0, 0x8c, 0xc0, 0x01, 0x00,
-	0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x8c, 0xb0, 0x01, 0x00,
-	0x88, 0x93, 0x8c, 0xf8, 0x8e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
-	0x19, 0x90, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf8, 0x14, 0x30, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x16, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x26, 0xb0, 0x01, 0x00, 0x08, 0x00, 0x2e, 0xf8, 0x0c, 0xb0, 0x01, 0x00,
-	0x0c, 0x00, 0x2a, 0x4a, 0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x00, 0x00,
-	0xe0, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x20, 0x1b, 0xe0, 0xb1, 0x01, 0x00,
-	0x95, 0x93, 0x20, 0x0a, 0x0c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
-	0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x96, 0xb0, 0x01, 0x00,
-	0x20, 0x00, 0x20, 0xf0, 0xe4, 0xb1, 0x01, 0x00, 0x18, 0x00, 0x20, 0x4a,
-	0xe0, 0xb1, 0x01, 0x00, 0x1c, 0x00, 0x20, 0x4b, 0xe0, 0xb1, 0x01, 0x00,
-	0x80, 0x93, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00, 0x2c, 0x00, 0x2d, 0x42,
-	0x19, 0x90, 0x01, 0x00, 0x2e, 0x00, 0x2f, 0xf3, 0x82, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00, 0x9b, 0x93, 0xa2, 0xa5,
-	0x97, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41, 0x95, 0xb0, 0x01, 0x00,
-	0x9e, 0x93, 0xa2, 0x40, 0x97, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x83, 0xb0, 0x01, 0x00, 0x2d, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x63, 0x41, 0x97, 0xc0, 0x01, 0x00, 0xd4, 0x00, 0x3e, 0x41,
-	0x83, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00,
-	0xa3, 0x93, 0xa0, 0xa5, 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x83, 0xb0, 0x01, 0x00, 0x2c, 0x00, 0x20, 0x41, 0xe6, 0xb1, 0x01, 0x00,
-	0xa8, 0x93, 0x22, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
-	0x98, 0xdc, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x4c, 0xe4, 0xf5, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x1f, 0x80, 0x01, 0x00, 0x0b, 0x00, 0x80, 0x00,
-	0xe4, 0xf5, 0x01, 0x00, 0x9d, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x04, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x60, 0x41, 0x87, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5d, 0x05, 0x90, 0x00, 0x00,
-	0xb4, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x9d, 0x92, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5d, 0x05, 0x90, 0x00, 0x00,
-	0xc3, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x2e, 0x00, 0x2f, 0xf3, 0x84, 0xb0, 0x01, 0x00,
-	0x01, 0x00, 0x63, 0xf3, 0x96, 0xc8, 0x01, 0x00, 0xcb, 0x93, 0x9f, 0x41,
-	0x85, 0x50, 0x00, 0x00, 0x01, 0x00, 0x00, 0xa5, 0x85, 0xcc, 0x01, 0x00,
-	0x2d, 0x00, 0xa0, 0x42, 0xe6, 0xb1, 0x01, 0x00, 0x5e, 0x01, 0x2d, 0x00,
-	0x80, 0xb0, 0x01, 0x00, 0xd0, 0x93, 0x52, 0x43, 0x81, 0x60, 0x00, 0x00,
-	0x02, 0x00, 0x00, 0xf2, 0x82, 0xf4, 0x01, 0x00, 0xd1, 0x93, 0x00, 0x41,
-	0x80, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x81, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x5e, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x95, 0xb0, 0x00, 0x00,
-	0xd2, 0x93, 0x9e, 0xbb, 0x80, 0x32, 0x00, 0x00, 0xd7, 0x93, 0xa2, 0x40,
-	0x1f, 0x7c, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x41, 0x95, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x15,
-	0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0x2b, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfc, 0x24, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
-	0x38, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3c, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfe, 0x3a, 0xb0, 0x01, 0x00, 0xec, 0x93, 0x9c, 0x17,
-	0x80, 0x32, 0x00, 0x00, 0xe1, 0x93, 0xa2, 0x4a, 0x19, 0x7c, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x4c, 0x1f, 0x90, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x1e,
-	0x98, 0xf4, 0x01, 0x00, 0xe0, 0x93, 0xa2, 0x48, 0x99, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x15, 0x42, 0xb1, 0x01, 0x00, 0xe0, 0x93, 0xa2, 0x8a,
-	0xf1, 0x6d, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x02, 0xcc, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xfc, 0x3e, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x00, 0xf4,
-	0x28, 0xcc, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
-	0xeb, 0x93, 0x20, 0xf0, 0x3e, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x2b, 0xc0, 0x01, 0x00,
-	0xbf, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0xf3,
-	0x3a, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x4b, 0x19, 0x90, 0x01, 0x00,
-	0x07, 0x00, 0x2a, 0x0c, 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x04,
-	0xe6, 0xb1, 0x01, 0x00, 0x18, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x1c, 0x00, 0x2d, 0xf0, 0x16, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x2d, 0xf0,
-	0x26, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x2f, 0xf2, 0x0c, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0xa2, 0x06, 0x14, 0xec, 0x00, 0x00, 0xf8, 0x93, 0x22, 0x45,
-	0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xa3, 0x06, 0x2a, 0xec, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x96, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x2a, 0x4c, 0xe1, 0xc1, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10,
-	0x48, 0xc9, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
-	0x18, 0x00, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0xe0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
-	0x62, 0xdd, 0x01, 0x00, 0x02, 0x94, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
-	0x48, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00,
-	0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x50, 0x49, 0xc1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x06, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0xf0, 0xb1, 0x01, 0x00, 0x0c, 0x94, 0x62, 0x42, 0x61, 0x31, 0x00, 0x00,
-	0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x0d, 0x94, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x62, 0xc9, 0x01, 0x00,
-	0x0f, 0x94, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00, 0x40, 0x00, 0x00, 0x03,
-	0xf0, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x2e, 0x50, 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
-	0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
-	0x19, 0x94, 0x62, 0x42, 0x61, 0x31, 0x00, 0x00, 0x20, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x1a, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0x1c, 0x94, 0xa8, 0x00,
-	0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x30, 0x80, 0x00, 0x4a, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
-	0xf1, 0xb1, 0x01, 0x00, 0xc0, 0xa8, 0x3d, 0x46, 0x0d, 0xe0, 0x01, 0x00,
-	0xff, 0x7f, 0x00, 0xa1, 0xf0, 0x89, 0x01, 0x00, 0x02, 0x00, 0x00, 0x09,
-	0x96, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x97, 0xe0, 0x01, 0x00,
-	0x00, 0x00, 0x60, 0xa8, 0x97, 0xc0, 0x01, 0x00, 0x26, 0x94, 0x63, 0x42,
-	0x61, 0x31, 0x00, 0x00, 0x30, 0x00, 0x00, 0x4a, 0x62, 0xc9, 0x01, 0x00,
-	0x27, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x99, 0x3f, 0x42, 0x97, 0xf0, 0x01, 0x00,
-	0x2b, 0x94, 0x65, 0x40, 0x81, 0x32, 0x00, 0x00, 0x33, 0x94, 0x22, 0xf3,
-	0x74, 0x06, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf3, 0x94, 0x88, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x07, 0xe7, 0x85, 0x01, 0x00, 0x00, 0x00, 0x75, 0x55,
-	0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x62, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x30, 0x94, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x40, 0x81, 0xb2, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xa8, 0x36, 0xb0, 0x01, 0x00, 0x43, 0x94, 0x82, 0x41,
-	0x23, 0x40, 0x00, 0x00, 0x38, 0x94, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
-	0xa7, 0x91, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00, 0x20, 0x80, 0x00, 0x10,
-	0x42, 0xc9, 0x01, 0x00, 0x3e, 0x94, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x3b, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x23, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
-	0x43, 0x94, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xaf, 0x92, 0x00, 0x43,
-	0x23, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x23, 0xb0, 0x01, 0x00,
-	0x45, 0x94, 0xa3, 0x15, 0x0c, 0x6c, 0x00, 0x00, 0x46, 0x94, 0x00, 0x06,
-	0x04, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x04, 0xb0, 0x01, 0x00,
-	0x48, 0x94, 0x20, 0x02, 0x1a, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
-	0x04, 0xb0, 0x01, 0x00, 0x07, 0x95, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00,
-	0x72, 0x94, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00, 0x4c, 0x94, 0xa2, 0x02,
-	0x2a, 0x50, 0x00, 0x00, 0x72, 0x94, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00,
-	0x4e, 0x94, 0x22, 0x02, 0x0c, 0x50, 0x00, 0x00, 0x57, 0x94, 0x00, 0x02,
-	0x16, 0xc0, 0x00, 0x00, 0x56, 0x94, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
-	0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x56, 0x94, 0x22, 0x40,
-	0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
-	0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x52, 0x94, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0xf1, 0x93, 0x00, 0x5c,
-	0x1f, 0x00, 0x01, 0x00, 0x72, 0x94, 0x22, 0x15, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00, 0x71, 0x94, 0xa2, 0x02,
-	0x1a, 0x50, 0x00, 0x00, 0x63, 0x94, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00,
-	0x70, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
-	0x1f, 0x80, 0x01, 0x00, 0x63, 0x94, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x5f, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-	0x48, 0xb1, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0xf0, 0x10, 0xc8, 0x01, 0x00, 0x2f, 0x00, 0x2f, 0x5c,
-	0x11, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0xe7, 0x91, 0x01, 0x00,
-	0xf0, 0x07, 0x00, 0x40, 0x1b, 0x98, 0x01, 0x00, 0x35, 0x94, 0x20, 0x15,
-	0x1a, 0x6c, 0x00, 0x00, 0x70, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x22, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
-	0xf0, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08, 0xe0, 0x8d, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
-	0x62, 0xdd, 0x01, 0x00, 0x6e, 0x94, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
-	0x35, 0x94, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x35, 0x94, 0x00, 0x02,
-	0x10, 0xc0, 0x00, 0x00, 0x74, 0x94, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
-	0xa7, 0x91, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1b,
-	0x10, 0xb1, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x10, 0x00, 0x00, 0x08,
-	0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x03, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x00, 0x00, 0xa8, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x7b, 0x94, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x17, 0x00, 0x00, 0xd0, 0xa2, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0xa2, 0x40, 0x27, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
-	0x00, 0xb0, 0x01, 0x00, 0x99, 0x92, 0x00, 0x41, 0xa3, 0x41, 0x01, 0x00,
-	0x7f, 0x94, 0x00, 0x41, 0x27, 0xd0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07,
-	0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x80, 0x94, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40,
-	0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x86, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xd8, 0x94, 0x00, 0x40,
-	0x2b, 0x30, 0x01, 0x00, 0xac, 0x00, 0x2d, 0x06, 0x16, 0xc0, 0x01, 0x00,
-	0x90, 0x00, 0x2d, 0xf0, 0x16, 0xc4, 0x01, 0x00, 0x8e, 0x94, 0xa0, 0xf0,
-	0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
-	0x0e, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x6c, 0xf0,
-	0x30, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x2d, 0x40, 0x87, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x6c, 0xf0, 0x28, 0xb0, 0x01, 0x00, 0x97, 0x94, 0x22, 0x4a,
-	0x19, 0x7c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x43, 0x86, 0xc8, 0x01, 0x00,
-	0x00, 0x30, 0x00, 0x0b, 0x16, 0xc8, 0x01, 0x00, 0x97, 0x94, 0xa4, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
-	0xb8, 0x94, 0x22, 0x06, 0x80, 0x32, 0x00, 0x00, 0xa4, 0x94, 0xa2, 0x06,
-	0x14, 0x6c, 0x00, 0x00, 0xa1, 0x94, 0x22, 0x48, 0x19, 0x7c, 0x00, 0x00,
-	0x9c, 0x94, 0xa0, 0x41, 0x17, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x31, 0xc0, 0x01, 0x00,
-	0x90, 0x00, 0x20, 0x18, 0xe0, 0xb1, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0x48,
-	0x19, 0x80, 0x01, 0x00, 0x8b, 0x00, 0x20, 0x45, 0xe7, 0x91, 0x01, 0x00,
-	0xa4, 0x94, 0x00, 0x40, 0x87, 0x90, 0x00, 0x00, 0x08, 0x00, 0x00, 0x43,
-	0x86, 0x98, 0x01, 0x00, 0xa4, 0x94, 0xa0, 0x48, 0x17, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0xb0, 0x00, 0x00, 0x40,
-	0x43, 0x99, 0x01, 0x00, 0x10, 0x50, 0x00, 0x43, 0xfc, 0xc9, 0x01, 0x00,
-	0x0f, 0x95, 0x00, 0x30, 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xe5, 0xb1, 0x01, 0x00, 0xaf, 0x94, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00,
-	0x08, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0xab,
-	0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab, 0x17, 0xc0, 0x01, 0x00,
-	0xae, 0x94, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x17, 0xc0, 0x01, 0x00, 0xb3, 0x94, 0x64, 0xf0, 0x82, 0xb0, 0x00, 0x00,
-	0xa4, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xb3, 0x94, 0xa2, 0xf2,
-	0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xe5, 0xb1, 0x01, 0x00,
-	0x8c, 0x00, 0x20, 0x18, 0xe0, 0xb1, 0x01, 0x00, 0x90, 0x00, 0x00, 0x40,
-	0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x60, 0x06, 0x30, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x86, 0x0c, 0x80, 0xb2, 0x00, 0x00, 0xbc, 0x00, 0x2d, 0x46,
-	0x19, 0x90, 0x01, 0x00, 0xa0, 0x00, 0xa0, 0xf2, 0xe4, 0xb1, 0x01, 0x00,
-	0xb0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x10, 0x50, 0x00, 0x43,
-	0xfc, 0xc9, 0x01, 0x00, 0x0f, 0x95, 0x00, 0x30, 0x81, 0x30, 0x01, 0x00,
-	0x00, 0x00, 0xa2, 0x4a, 0x19, 0xfc, 0x00, 0x00, 0x08, 0x00, 0x00, 0xa2,
-	0x44, 0xc9, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0xab, 0xf9, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xab, 0x17, 0xc0, 0x01, 0x00, 0xc1, 0x94, 0xa0, 0xf0,
-	0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0xe4, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0xa8, 0x1b, 0xe0, 0xb1, 0x00, 0x00, 0xc6, 0x94, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0c, 0x7e, 0x89, 0x01, 0x00,
-	0x00, 0x00, 0xa6, 0x4c, 0x95, 0x60, 0x01, 0x00, 0x00, 0x00, 0x80, 0x4a,
-	0x18, 0x94, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0x01, 0xf0, 0x31, 0x00, 0x00, 0x20, 0x00, 0x00, 0x40,
-	0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
-	0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x15, 0xe0, 0xb1, 0x00, 0x00,
-	0xd1, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x10, 0x80, 0x00, 0x03,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x01, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xe8, 0x5f,
-	0x17, 0x90, 0x01, 0x00, 0x70, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x7a, 0x01, 0x2e, 0xfe, 0x92, 0xb0, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0xf6,
-	0x16, 0xb0, 0x01, 0x00, 0xde, 0x94, 0x22, 0x43, 0xe7, 0x7d, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00, 0x04, 0x00, 0x00, 0xa6,
-	0x2a, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x6e, 0x06, 0x82, 0xc8, 0x01, 0x00,
-	0xe2, 0x94, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
-	0x45, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x6e, 0x4c, 0x83, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x92, 0xc0, 0x01, 0x00, 0xe3, 0x94, 0x43, 0x30,
-	0x3d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x66, 0x9e, 0x83, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x1b, 0x41, 0x3d, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x92, 0xc0, 0x01, 0x00, 0x06, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00,
-	0x10, 0x00, 0x00, 0x49, 0x98, 0xf4, 0x01, 0x00, 0xec, 0x94, 0x26, 0x30,
-	0x93, 0x04, 0x00, 0x00, 0xec, 0x94, 0x90, 0x4c, 0x92, 0x40, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00, 0xff, 0xff, 0x80, 0x49,
-	0xec, 0xa9, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
-	0x04, 0x00, 0x22, 0x01, 0xf0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x15,
-	0xe0, 0xb1, 0x00, 0x00, 0xf1, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xfe, 0x94, 0x22, 0x5f, 0x81, 0x7c, 0x00, 0x00, 0xfd, 0x94, 0xa2, 0x40,
-	0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x19, 0x90, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x07,
-	0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x97, 0x94, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00, 0xfd, 0x94, 0x28, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xfa, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x00, 0x00, 0xa2, 0x21, 0x81, 0x84, 0x00, 0x00, 0x01, 0x95, 0xa2, 0x5f,
-	0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x43, 0x19, 0x7c, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x43, 0x19, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54,
-	0x61, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x07, 0x96, 0xe4, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x96, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19,
-	0x44, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x02, 0xf0, 0x31, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x0b, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x13,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x08,
-	0xe0, 0xb1, 0x00, 0x00, 0x0c, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x7c, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x00, 0xf0,
-	0x98, 0xf4, 0x01, 0x00, 0x15, 0x95, 0x20, 0x4c, 0x84, 0x6c, 0x00, 0x00,
-	0x88, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x15, 0x95, 0x20, 0xf2,
-	0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00,
-	0x98, 0x00, 0x2d, 0x14, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
-	0x98, 0xb0, 0x01, 0x00, 0xa3, 0x00, 0x2d, 0x14, 0x98, 0xd0, 0x01, 0x00,
-	0x1a, 0x95, 0x20, 0x4c, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
-	0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x80, 0xe0, 0x01, 0x00,
-	0x1d, 0x95, 0x23, 0x40, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x84, 0xb0, 0x01, 0x00, 0xd0, 0x00, 0x20, 0x14, 0xe0, 0xb1, 0x01, 0x00,
-	0x98, 0x00, 0x25, 0x42, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x6e, 0xf3,
-	0x80, 0xf0, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x42, 0x82, 0xc0, 0x00, 0x00,
-	0x23, 0x95, 0xa0, 0x40, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x9f, 0xf0, 0x82, 0xec, 0x00, 0x00,
-	0x98, 0x00, 0xa0, 0x41, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
-	0x48, 0xb1, 0x01, 0x00, 0xa8, 0x01, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x05, 0xf0, 0xb1, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
-	0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x60, 0xa7, 0x97, 0xc0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x2a, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xa8, 0x00, 0x2d, 0x1c, 0x8a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x9f, 0xf0,
-	0x8a, 0xd0, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x40, 0x8b, 0xec, 0x00, 0x00,
-	0x8a, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xb4, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0xa4, 0x00, 0x2d, 0x45, 0xe0, 0xd1, 0x01, 0x00,
-	0x37, 0x95, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00, 0xbe, 0x00, 0x2f, 0xab,
-	0x83, 0xb0, 0x01, 0x00, 0x88, 0x95, 0x00, 0x14, 0x82, 0x50, 0x01, 0x00,
-	0x3c, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x3c, 0x95, 0x22, 0xf2,
-	0x82, 0x30, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x3c, 0x95, 0x9f, 0x1c, 0xe0, 0x6d, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x40,
-	0x47, 0x99, 0x01, 0x00, 0x88, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0xa8, 0x00, 0x20, 0x1c, 0xe0, 0xb1, 0x01, 0x00, 0x9c, 0x00, 0x2d, 0x30,
-	0x81, 0xb0, 0x01, 0x00, 0x88, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00,
-	0x94, 0x00, 0x2d, 0xf2, 0x86, 0xb0, 0x01, 0x00, 0x4f, 0x95, 0x23, 0xf0,
-	0x84, 0x6c, 0x00, 0x00, 0x44, 0x95, 0x23, 0x92, 0x87, 0x6c, 0x00, 0x00,
-	0xc9, 0x04, 0x00, 0xa6, 0x94, 0xb0, 0x01, 0x00, 0x46, 0x95, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x94, 0xb0, 0x01, 0x00,
-	0x60, 0x89, 0x00, 0x4a, 0x94, 0x98, 0x01, 0x00, 0x46, 0x95, 0x68, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0xb0, 0xb1, 0x01, 0x00,
-	0xbf, 0x00, 0x2d, 0x42, 0xb2, 0xb1, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf3,
-	0x80, 0xe0, 0x01, 0x00, 0x4a, 0x95, 0xd4, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x78, 0xda, 0x84, 0xc0, 0x01, 0x00, 0x54, 0x95, 0x23, 0x40,
-	0x84, 0x6c, 0x00, 0x00, 0x94, 0x00, 0x20, 0x9d, 0xe1, 0xb1, 0x01, 0x00,
-	0x54, 0x95, 0x00, 0x40, 0x84, 0xb0, 0x00, 0x00, 0xbf, 0x00, 0x2d, 0x43,
-	0x84, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf3, 0x80, 0xe0, 0x01, 0x00,
-	0x54, 0x95, 0x23, 0x40, 0x84, 0x6c, 0x00, 0x00, 0x94, 0x00, 0x20, 0x9d,
-	0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x84, 0xb0, 0x01, 0x00,
-	0x58, 0x95, 0xa2, 0xf0, 0x38, 0x6c, 0x00, 0x00, 0x9c, 0x00, 0x20, 0x42,
-	0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x13, 0x94, 0x01, 0x00,
-	0x00, 0x00, 0x80, 0x46, 0x19, 0x80, 0x01, 0x00, 0x9c, 0x00, 0x20, 0x42,
-	0xe0, 0xb1, 0x01, 0x00, 0x37, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x04, 0x00, 0x00, 0xf3, 0x80, 0xf4, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3,
-	0x82, 0x88, 0x01, 0x00, 0x5e, 0x95, 0x23, 0x41, 0x80, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x5f, 0x13, 0x94, 0x01, 0x00, 0x00, 0x00, 0x89, 0x0c,
-	0x80, 0xb2, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0xa0, 0x00, 0xa0, 0xf2, 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x9f, 0x41,
-	0x24, 0xec, 0x00, 0x00, 0x68, 0x95, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x9f, 0x42, 0x38, 0xec, 0x00, 0x00, 0x68, 0x95, 0xa6, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x6a, 0x95, 0xa3, 0xf0, 0x3a, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0xb4, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
-	0x6e, 0x95, 0x22, 0xf0, 0x3a, 0x6c, 0x00, 0x00, 0xb4, 0x00, 0x20, 0x1d,
-	0xe0, 0xb1, 0x01, 0x00, 0x80, 0x00, 0x2d, 0x5f, 0x13, 0x94, 0x01, 0x00,
-	0x6e, 0x95, 0x23, 0xf0, 0x3a, 0x6c, 0x00, 0x00, 0x80, 0x00, 0x20, 0x1d,
-	0xe0, 0xb1, 0x01, 0x00, 0xc0, 0x00, 0x20, 0x12, 0xe0, 0xb1, 0x01, 0x00,
-	0xc4, 0x00, 0xa0, 0x1c, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xe0, 0xb1, 0x01, 0x00,
-	0x12, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0x77, 0x95, 0x9f, 0x41,
-	0x24, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x8c, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x12, 0x8c, 0xd0, 0x01, 0x00, 0x78, 0x95, 0x00, 0x41,
-	0x24, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x8d, 0xb0, 0x01, 0x00,
-	0xc6, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x7a, 0x95, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x8c, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x00, 0xa2, 0x08, 0x80, 0x32, 0x01, 0x00, 0x81, 0x95, 0xa2, 0x40,
-	0x95, 0x6c, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
-	0x00, 0x82, 0x00, 0xa6, 0x04, 0xb0, 0x01, 0x00, 0xa0, 0x98, 0x2f, 0x40,
-	0x11, 0xb0, 0x01, 0x00, 0x30, 0x05, 0x00, 0x41, 0x89, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x9f, 0xf8, 0x3e, 0xec, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x12,
-	0xe0, 0xed, 0x00, 0x00, 0xc8, 0x00, 0x20, 0xab, 0xe1, 0xb1, 0x01, 0x00,
-	0xcc, 0x00, 0xa0, 0x1f, 0xe0, 0xb1, 0x01, 0x00, 0x8a, 0x95, 0xa3, 0x5f,
-	0xe7, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xe7, 0xc1, 0x01, 0x00,
-	0xa6, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x9e, 0x95, 0x22, 0xf2,
-	0x86, 0x30, 0x00, 0x00, 0x03, 0x00, 0x00, 0x43, 0x84, 0xf4, 0x01, 0x00,
-	0x01, 0x00, 0x00, 0x41, 0x80, 0xcc, 0x01, 0x00, 0xb8, 0x00, 0x2d, 0x42,
-	0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x62, 0x40, 0x86, 0xc0, 0x01, 0x00,
-	0x92, 0x95, 0x1f, 0x43, 0x80, 0x32, 0x00, 0x00, 0x93, 0x95, 0xa2, 0x40,
-	0x87, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x62, 0x41, 0x87, 0xb0, 0x01, 0x00,
-	0x97, 0x95, 0x9f, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x84, 0xd0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
-	0x88, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x00, 0x44, 0x84, 0xf4, 0x01, 0x00,
-	0xb8, 0x00, 0x2e, 0x42, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x62, 0x40,
-	0x88, 0xc0, 0x01, 0x00, 0x9d, 0x95, 0x1f, 0x44, 0x80, 0x32, 0x00, 0x00,
-	0xa1, 0x95, 0xa2, 0x40, 0x89, 0x6c, 0x00, 0x00, 0xa1, 0x95, 0x62, 0x41,
-	0x89, 0xb0, 0x00, 0x00, 0x03, 0x00, 0x62, 0x41, 0x86, 0xe4, 0x01, 0x00,
-	0xb8, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x01, 0x00, 0x62, 0x41,
-	0x88, 0xe4, 0x01, 0x00, 0xa4, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00,
-	0xa2, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xbc, 0x00, 0x2e, 0x43,
-	0x87, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x86, 0xc0, 0x01, 0x00,
-	0xa7, 0x95, 0x20, 0x43, 0x87, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43,
-	0xe5, 0xb1, 0x01, 0x00, 0x40, 0x01, 0x00, 0x43, 0x80, 0xce, 0x01, 0x00,
-	0x00, 0x00, 0xa4, 0x43, 0xe4, 0x31, 0x01, 0x00, 0x40, 0x01, 0xe2, 0x40,
-	0x87, 0x98, 0x01, 0x00, 0x88, 0x00, 0x2d, 0x44, 0x81, 0xb0, 0x01, 0x00,
-	0x90, 0x00, 0x2d, 0xf2, 0x2e, 0xb0, 0x01, 0x00, 0x9c, 0x00, 0x2d, 0xf0,
-	0x86, 0xb0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00,
-	0xba, 0x00, 0x2d, 0xf0, 0x98, 0xb0, 0x01, 0x00, 0xb4, 0x95, 0xa2, 0x12,
-	0x98, 0x6c, 0x00, 0x00, 0xbc, 0x00, 0x2d, 0xf2, 0x98, 0xb0, 0x01, 0x00,
-	0xb4, 0x95, 0xa0, 0xf2, 0x98, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17,
-	0x82, 0xb0, 0x01, 0x00, 0x9c, 0x00, 0x20, 0x41, 0xe0, 0xb1, 0x01, 0x00,
-	0xb4, 0x00, 0x2d, 0x12, 0x86, 0xd0, 0x01, 0x00, 0xb7, 0x95, 0xa3, 0x41,
-	0xe0, 0x6d, 0x00, 0x00, 0xb8, 0x95, 0x00, 0xf0, 0x84, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x41, 0x84, 0xb0, 0x01, 0x00, 0x80, 0x00, 0x2d, 0x43,
-	0x84, 0xd0, 0x01, 0x00, 0xbb, 0x95, 0x9f, 0x42, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00, 0xbd, 0x95, 0xa3, 0x42,
-	0x14, 0x6c, 0x00, 0x00, 0xbe, 0x95, 0x00, 0x0a, 0x0c, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x42, 0x0c, 0xb0, 0x01, 0x00, 0xc0, 0x95, 0xa0, 0x17,
-	0x0c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x17, 0x0c, 0xb0, 0x01, 0x00,
-	0xc5, 0x95, 0x22, 0x40, 0x0d, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0a,
-	0x0c, 0xec, 0x00, 0x00, 0x01, 0x00, 0x00, 0xf0, 0x82, 0xf4, 0x01, 0x00,
-	0xc5, 0x95, 0xa0, 0x41, 0x0c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xf0,
-	0x80, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb0, 0x01, 0x00,
-	0x9d, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x04, 0x80, 0x00, 0x03,
-	0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x41,
-	0x87, 0x94, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
-	0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49, 0xf0, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
-	0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
-	0x00, 0x00, 0xa8, 0x5d, 0x05, 0x90, 0x00, 0x00, 0xd1, 0x95, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x4b, 0x19, 0x90, 0x01, 0x00,
-	0x05, 0x00, 0x2a, 0x0c, 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x04,
-	0xe6, 0xb1, 0x01, 0x00, 0xd7, 0x95, 0x45, 0x48, 0x61, 0x31, 0x00, 0x00,
-	0x00, 0x10, 0x00, 0x08, 0x62, 0xdd, 0x01, 0x00, 0xdc, 0x95, 0x28, 0x40,
-	0x87, 0x30, 0x00, 0x00, 0xd8, 0x95, 0x22, 0x48, 0x77, 0x7d, 0x00, 0x00,
-	0x7e, 0x94, 0x1d, 0x46, 0x87, 0xb0, 0x00, 0x00, 0xdf, 0x95, 0x22, 0x5f,
-	0x11, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x15, 0x62, 0x31, 0x00, 0x00,
-	0xdd, 0x95, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00,
-	0x00, 0x14, 0x2f, 0x4c, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0xe2, 0x95, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x49, 0xb1, 0x01, 0x00, 0x30, 0x00, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x93, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x1f, 0xb0, 0x01, 0x00, 0x35, 0x96, 0x00, 0x49, 0x96, 0x30, 0x01, 0x00,
-	0x07, 0x00, 0x00, 0x49, 0x06, 0xe4, 0x01, 0x00, 0x00, 0x39, 0x00, 0x03,
-	0x06, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
-	0x20, 0x00, 0x00, 0xd0, 0xa0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
-	0x93, 0xc0, 0x01, 0x00, 0xe9, 0x95, 0xa0, 0x54, 0x93, 0x6c, 0x00, 0x00,
-	0x00, 0x00, 0x2e, 0x05, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40,
-	0x49, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00,
-	0x00, 0x02, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0xf2, 0x95, 0xa2, 0x41,
-	0x97, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x49, 0xb3, 0x01, 0x00,
-	0x3b, 0x96, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00, 0xc8, 0x92, 0x00, 0x40,
-	0x81, 0x32, 0x01, 0x00, 0x00, 0xb5, 0x2e, 0x08, 0x97, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0xf9, 0x95, 0xa2, 0x41,
-	0x97, 0x50, 0x00, 0x00, 0x18, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
-	0x00, 0x97, 0x2e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0xfd, 0x95, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x40, 0x18, 0x2e, 0x05,
-	0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
-	0x01, 0x96, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x57, 0x95, 0x20, 0x40,
-	0xe7, 0xb1, 0x01, 0x00, 0x30, 0x94, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
-	0x64, 0x00, 0x00, 0x40, 0xe5, 0x99, 0x01, 0x00, 0x56, 0x95, 0x20, 0x40,
-	0xe7, 0xb1, 0x01, 0x00, 0xb8, 0x94, 0x20, 0x41, 0xe5, 0xb1, 0x01, 0x00,
-	0xba, 0x94, 0x20, 0x41, 0xe5, 0xb1, 0x01, 0x00, 0x98, 0x94, 0x00, 0x40,
-	0x45, 0x99, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x0b, 0x96, 0xa2, 0x41,
-	0x97, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x6f, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x68, 0xb1, 0x01, 0x00, 0x0f, 0x96, 0x85, 0x41, 0x97, 0x40, 0x00, 0x00,
-	0x80, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x39, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x37, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x35, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x33, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x41, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x3f, 0xb3, 0x01, 0x00, 0xee, 0x05, 0x00, 0x40,
-	0x25, 0x9b, 0x01, 0x00, 0x42, 0x00, 0x00, 0x40, 0x4b, 0x9b, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x2f, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x2d, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x47, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x43, 0xb3, 0x01, 0x00, 0x60, 0x00, 0x00, 0x40,
-	0x2b, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0xef, 0x93, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x55, 0xf1, 0x93, 0x01, 0x00, 0xff, 0xff, 0x00, 0xa5,
-	0x3c, 0x8b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x5b, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x2c, 0x45, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x59, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x57, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x40, 0x27, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x53, 0xb3, 0x01, 0x00, 0x2b, 0x96, 0xa2, 0x50, 0xfd, 0x7f, 0x00, 0x00,
-	0x2b, 0x96, 0xa2, 0x51, 0xfd, 0x7f, 0x00, 0x00, 0x2c, 0x96, 0x00, 0x40,
-	0x1d, 0xb3, 0x00, 0x00, 0x50, 0x46, 0x00, 0x40, 0x1d, 0x9b, 0x01, 0x00,
-	0x00, 0xc0, 0x00, 0xa6, 0x88, 0xb3, 0x01, 0x00, 0xff, 0x3f, 0x00, 0xa6,
-	0x3a, 0xb3, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x9d, 0x3b, 0x9b, 0x01, 0x00,
-	0xb4, 0x05, 0x00, 0x40, 0x23, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0x4d, 0xb3, 0x01, 0x00, 0x08, 0x0a, 0x00, 0xa6, 0x14, 0xb3, 0x01, 0x00,
-	0x01, 0x01, 0x00, 0x8a, 0x15, 0x9b, 0x01, 0x00, 0x00, 0x80, 0x00, 0xa6,
-	0x56, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x5e, 0x57, 0xb5, 0x01, 0x00,
-	0x18, 0x00, 0x00, 0x4b, 0x20, 0xe4, 0x01, 0x00, 0x06, 0x00, 0x00, 0x4b,
-	0x96, 0xe4, 0x01, 0x00, 0x00, 0x43, 0x00, 0x4b, 0x96, 0xc8, 0x01, 0x00,
-	0x18, 0x00, 0x00, 0x10, 0x20, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
-	0x20, 0x94, 0x01, 0x00, 0x00, 0x00, 0x80, 0x57, 0x21, 0x90, 0x01, 0x00,
-	0x00, 0x99, 0x2e, 0x0a, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
-	0xf1, 0xb1, 0x01, 0x00, 0x3c, 0x96, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
-	0x00, 0x03, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00, 0x00, 0xa9, 0x00, 0x40,
-	0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
-	0x40, 0x96, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40,
-	0x97, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55, 0x61, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00, 0x44, 0x96, 0xa8, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0x44, 0x96, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
-	0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xae, 0x9f, 0x00, 0x88,
-	0x9a, 0xb0, 0x00, 0x00, 0xae, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00,
-	0xae, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00, 0xae, 0x9f, 0x00, 0x88,
-	0x9a, 0xb0, 0x00, 0x00, 0xae, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x88, 0x9a, 0xb0, 0x01, 0x00, 0xae, 0x9f, 0x41, 0x40,
-	0x81, 0x32, 0x00, 0x00, 0xb2, 0x9f, 0x22, 0x40, 0x7b, 0x6f, 0x00, 0x00,
-	0x00, 0x00, 0x19, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xae, 0x9f, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x19, 0x41, 0x7b, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xa4, 0xc4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa1,
-	0xc6, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x2f, 0xa2, 0xc8, 0xb3, 0x01, 0x00,
-	0x08, 0x14, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00, 0xa8, 0x9f, 0x00, 0x4d,
-	0x9a, 0xcc, 0x01, 0x00, 0xbb, 0x9f, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x4c, 0x49, 0xc1, 0x01, 0x00, 0xb9, 0x9f, 0xa2, 0x41,
-	0x9b, 0x50, 0x00, 0x00, 0xbf, 0x9f, 0x80, 0x80, 0x80, 0x32, 0x00, 0x00,
-	0x00, 0x00, 0x52, 0x49, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
-	0xfd, 0x93, 0x01, 0x00, 0xc2, 0x9f, 0x00, 0x42, 0xcd, 0x93, 0x00, 0x00,
-	0x00, 0x00, 0x51, 0x4a, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
-	0xfd, 0x93, 0x01, 0x00, 0xc2, 0x9f, 0x00, 0x43, 0xcb, 0x93, 0x00, 0x00,
-	0x00, 0x00, 0x50, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xd2, 0x9f, 0x00, 0x40,
-	0x19, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x9a, 0xb0, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0x44, 0x49, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x40, 0xf0,
-	0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0x4d, 0x80, 0xb2, 0x01, 0x00,
-	0xca, 0x9f, 0x00, 0x40, 0x19, 0x99, 0x01, 0x00, 0x00, 0x00, 0x4c, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x49, 0xd1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xf0, 0x9a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4d,
-	0x10, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x49, 0xb1, 0x01, 0x00,
-	0x00, 0x00, 0x00, 0xe3, 0x43, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe4,
-	0x45, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7b, 0xb3, 0x01, 0x00,
-	0x00, 0x00, 0x48, 0x4f, 0x40, 0xb1, 0x01, 0x00, 0xd2, 0x9f, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0xcb,
-	0x81, 0xc8, 0x01, 0x00, 0xf4, 0x82, 0x00, 0x40, 0xf2, 0x93, 0x00, 0x00,
-	0x40, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x40, 0x05, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x18, 0x06, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xf4, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x38, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x36, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb8, 0x80, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xaf, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xf5, 0x82, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x94, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0xd7, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x5d, 0x92, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xc6, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x33, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xd6, 0x92, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0xd0, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x9a, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-	0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
-	0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
-	0x81, 0xb2, 0x00, 0x00,
-	},
-};
diff --git a/drivers/staging/slicoss/oasisrcvucode.h b/drivers/staging/slicoss/oasisrcvucode.h
deleted file mode 100644
index 5b3531f..0000000
--- a/drivers/staging/slicoss/oasisrcvucode.h
+++ /dev/null
@@ -1,205 +0,0 @@
-#define OASIS_RCVUCODE_VERS_STRING	"1.2"
-#define OASIS_RCVUCODE_VERS_DATE  	"2006/03/27 15:10:28"
-
-static u32 OasisRcvUCodeLen = 512;
-
-static u8 OasisRcvUCode[2560] =
-{
-0x47, 0x75, 0x01, 0x00, 0x04, 0xa0, 0x13, 0x01, 0x00, 0x1c, 0xb7, 0x5b, 0x09,
-0x30, 0x00, 0xb6, 0x5f, 0x01, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x20, 0x18, 0x3b,
-0x78, 0x3a, 0x00, 0x1c, 0xa2, 0x77, 0x01, 0x00, 0x1c, 0x07, 0x1d, 0x01, 0x70,
-0x18, 0xad, 0x7b, 0xf1, 0xff, 0x1c, 0xb3, 0x7b, 0xa9, 0xaa, 0x1e, 0xb4, 0x7b,
-0x01, 0x0c, 0x1c, 0xb5, 0x7b, 0x0d, 0x06, 0x1c, 0x00, 0x00, 0x30, 0x64, 0x08,
-0x0c, 0x31, 0x5a, 0x70, 0x04, 0x0c, 0x31, 0x5a, 0x80, 0x04, 0x0c, 0x31, 0x4e,
-0x90, 0x04, 0x0c, 0x31, 0x4a, 0xa0, 0x00, 0x09, 0x25, 0x55, 0xc0, 0x04, 0x0c,
-0x31, 0x52, 0xb0, 0x00, 0xe9, 0x24, 0x55, 0xc0, 0x04, 0xcc, 0xb3, 0x00, 0x1c,
-0x1c, 0xeb, 0x2d, 0x01, 0x00, 0x1c, 0x06, 0x56, 0x32, 0xd4, 0x08, 0x07, 0x9d,
-0x00, 0x00, 0x1c, 0x7b, 0xb7, 0x02, 0x00, 0x10, 0xa0, 0x0f, 0x31, 0x54, 0x09,
-0x06, 0x56, 0x5e, 0xc0, 0x04, 0xa0, 0x30, 0x54, 0x03, 0x00, 0xac, 0x30, 0x55,
-0x03, 0x00, 0xcd, 0x03, 0x3a, 0x00, 0x1c, 0x7b, 0xb7, 0x02, 0x00, 0x1c, 0x60,
-0x8e, 0x31, 0x54, 0x09, 0x29, 0x25, 0x55, 0x03, 0x00, 0x80, 0x8e, 0x31, 0x54,
-0x09, 0x8c, 0x30, 0x91, 0x00, 0x04, 0x47, 0x1c, 0x01, 0x00, 0x1c, 0xa0, 0x0f,
-0x31, 0x54, 0x09, 0x00, 0x00, 0x64, 0x00, 0x04, 0x47, 0x1c, 0x65, 0xc0, 0x04,
-0x47, 0x1c, 0x55, 0x03, 0x00, 0x6c, 0x30, 0x01, 0x00, 0x1c, 0x4d, 0x34, 0x02,
-0x00, 0x1c, 0x7b, 0xb7, 0x02, 0x00, 0x1c, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0xc8,
-0x83, 0x37, 0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x64, 0x00,
-0x04, 0xa0, 0x0f, 0x30, 0x54, 0x09, 0x00, 0x00, 0x54, 0xc3, 0x04, 0x7b, 0xfb,
-0xf2, 0x00, 0x1c, 0xcc, 0x33, 0x0d, 0x00, 0x1c, 0xb4, 0x7b, 0xfd, 0x03, 0x1c,
-0x80, 0x0e, 0x30, 0x54, 0x09, 0xe0, 0xfb, 0x05, 0x00, 0x1c, 0x00, 0x00, 0x8c,
-0x03, 0x00, 0xb3, 0x0f, 0x31, 0x54, 0x09, 0x00, 0x00, 0xec, 0x70, 0x04, 0x00,
-0x00, 0xec, 0x80, 0x04, 0x00, 0x00, 0x8c, 0x93, 0x00, 0x61, 0x76, 0x8d, 0xc3,
-0x04, 0xc0, 0x8d, 0x31, 0x54, 0x09, 0xe0, 0x7b, 0x00, 0xc0, 0x1f, 0xa0, 0xfd,
-0xc5, 0x01, 0x00, 0xcc, 0x33, 0x05, 0x00, 0x1c, 0xd4, 0x03, 0x00, 0x3c, 0x1c,
-0xd4, 0xd3, 0x1b, 0x00, 0x1c, 0xc0, 0xd3, 0x52, 0x00, 0x1c, 0x00, 0x00, 0x5c,
-0x13, 0x04, 0x8e, 0x8e, 0x32, 0x54, 0x09, 0x5b, 0x80, 0x5e, 0x13, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x94, 0x01, 0x00, 0xa0, 0x0f, 0x31, 0x54,
-0x09, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0xc0, 0x03, 0xfc, 0x7f, 0x1c, 0xa0, 0x01,
-0xa0, 0x01, 0x00, 0x00, 0x00, 0xa4, 0x01, 0x00, 0xa0, 0x0f, 0x31, 0x54, 0x09,
-0xc0, 0x03, 0xfc, 0x03, 0x1c, 0xf5, 0x77, 0x01, 0x00, 0x1c, 0x26, 0x7a, 0xe6,
-0x05, 0x1c, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0xb3, 0x0f, 0x31, 0x54, 0x09, 0xb5,
-0x02, 0x02, 0x00, 0x1c, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0x7a, 0x7e, 0x02, 0x00,
-0x1c, 0xb5, 0x02, 0x02, 0x00, 0x1c, 0x53, 0x0f, 0x32, 0x54, 0x09, 0xaf, 0x03,
-0x01, 0x00, 0x1c, 0x7a, 0x0e, 0x32, 0x54, 0x09, 0xb5, 0x02, 0x02, 0x00, 0x1c,
-0x00, 0x00, 0x02, 0x00, 0x1c, 0xa0, 0x3d, 0xaa, 0x11, 0x04, 0x00, 0x00, 0xac,
-0x11, 0x04, 0xd4, 0xd3, 0x52, 0x00, 0x1c, 0xb5, 0x3e, 0xb2, 0x01, 0x00, 0x20,
-0xfb, 0xfd, 0xff, 0x1f, 0x80, 0x2c, 0x6c, 0x03, 0x00, 0xb9, 0x3a, 0x9e, 0x01,
-0x00, 0x75, 0x3b, 0x02, 0x00, 0x1c, 0xa7, 0x1c, 0x01, 0x00, 0x10, 0xdb, 0x83,
-0x16, 0x00, 0x1c, 0xc7, 0x1d, 0x21, 0xc1, 0x04, 0xb9, 0x3b, 0x8d, 0xc1, 0x04,
-0x8b, 0x2c, 0x01, 0x00, 0x1c, 0x6b, 0x2c, 0x35, 0xc1, 0x04, 0x00, 0x00, 0x78,
-0x11, 0x00, 0xcb, 0x2c, 0x79, 0xc1, 0x04, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0xa0,
-0x0f, 0x31, 0x54, 0x09, 0x54, 0xd0, 0x02, 0x00, 0x1c, 0x49, 0x25, 0xb1, 0x01,
-0x00, 0xab, 0x2c, 0x81, 0xc1, 0x04, 0xa7, 0x1d, 0x55, 0x03, 0x00, 0xcc, 0x33,
-0x09, 0x00, 0x1c, 0xeb, 0x2d, 0x01, 0x00, 0x1c, 0xea, 0x29, 0x01, 0x00, 0x1c,
-0xa0, 0x0f, 0x31, 0x54, 0x09, 0xae, 0x0f, 0x31, 0x54, 0x09, 0xa0, 0x0f, 0x31,
-0x54, 0x09, 0xd4, 0x07, 0xfc, 0x03, 0x1c, 0x99, 0x3a, 0x02, 0x00, 0x1c, 0xbb,
-0x38, 0x02, 0x00, 0x1c, 0x00, 0x38, 0x00, 0x00, 0x1c, 0x00, 0x00, 0xfc, 0x01,
-0x04, 0xdb, 0x3b, 0x7e, 0x00, 0x1c, 0xc7, 0x1d, 0x01, 0x00, 0x1c, 0x26, 0x7a,
-0xfa, 0x05, 0x1c, 0x27, 0x1d, 0x01, 0x00, 0x1c, 0xb3, 0x0f, 0x31, 0x54, 0x09,
-0x7a, 0x0e, 0x32, 0x54, 0x09, 0x53, 0x0f, 0x32, 0x54, 0x09, 0x7a, 0x0e, 0x32,
-0x54, 0x09, 0x53, 0x0f, 0x32, 0x54, 0x09, 0x7a, 0x0e, 0x32, 0x54, 0x09, 0x53,
-0x0f, 0x32, 0x54, 0x09, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0x7a, 0x06, 0x02, 0x00,
-0x1c, 0x53, 0x0f, 0x32, 0x54, 0x09, 0xaf, 0x03, 0x01, 0x00, 0x1c, 0x7a, 0x0e,
-0x32, 0x54, 0x09, 0x53, 0x0f, 0x32, 0x54, 0x09, 0x7a, 0x0e, 0x32, 0x54, 0x09,
-0x53, 0x0f, 0x32, 0x54, 0x09, 0x7a, 0x0e, 0x32, 0x54, 0x09, 0x53, 0x0f, 0x32,
-0x54, 0x09, 0x7a, 0x0e, 0x32, 0x54, 0x09, 0x00, 0x3d, 0x02, 0x00, 0x1c, 0x00,
-0x00, 0x58, 0x12, 0x00, 0xcb, 0x2c, 0x01, 0x00, 0x1c, 0x75, 0x3b, 0x02, 0x00,
-0x1c, 0xa7, 0x1c, 0x01, 0x00, 0x10, 0xcb, 0x2f, 0x05, 0x00, 0x1c, 0x60, 0x2c,
-0x00, 0x00, 0x1c, 0xc7, 0x1c, 0xc9, 0x02, 0x00, 0xa0, 0x0f, 0x31, 0x54, 0x09,
-0x53, 0x07, 0x02, 0x00, 0x1c, 0x46, 0x7a, 0xca, 0x05, 0x1c, 0x7a, 0x0e, 0x32,
-0x54, 0x09, 0x40, 0xfa, 0x19, 0x00, 0x1c, 0x00, 0x00, 0x88, 0x02, 0x04, 0x46,
-0x7a, 0xca, 0x05, 0x1c, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0xa0, 0x0f, 0x31, 0x54,
-0x09, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0xb3, 0x7b,
-0x01, 0xc0, 0x1f, 0x74, 0x0e, 0x30, 0x54, 0x09, 0xc0, 0x03, 0x9c, 0x00, 0x1c,
-0x80, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x04, 0x00, 0x00, 0xac,
-0x12, 0x05, 0x07, 0x1d, 0x01, 0x00, 0x1c, 0xd4, 0xd3, 0x2b, 0x00, 0x1c, 0xd4,
-0xd3, 0x52, 0x00, 0x1c, 0x80, 0x76, 0x7d, 0x13, 0x04, 0x00, 0x00, 0xe0, 0x02,
-0x00, 0xa6, 0x7b, 0x95, 0x03, 0x10, 0xc7, 0x9c, 0x00, 0x00, 0x1c, 0x80, 0x2c,
-0x00, 0x00, 0x1c, 0x00, 0x00, 0x6c, 0x02, 0x04, 0x00, 0x00, 0x54, 0xc3, 0x04,
-0xab, 0x2d, 0xd9, 0x12, 0x05, 0x07, 0x1d, 0xb5, 0xc2, 0x04, 0x8b, 0x2d, 0x01,
-0x00, 0x1c, 0x69, 0x25, 0x01, 0x00, 0x1c, 0xa6, 0x7b, 0x95, 0x03, 0x10, 0xcb,
-0x2f, 0x09, 0x00, 0x1c, 0x60, 0x2c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x48, 0x03,
-0x00, 0x53, 0x0f, 0x32, 0x54, 0x09, 0x46, 0x7a, 0xca, 0x05, 0x1c, 0x7a, 0x0e,
-0x32, 0x54, 0x09, 0x40, 0xfa, 0x19, 0x00, 0x1c, 0x00, 0x00, 0x10, 0x03, 0x04,
-0x46, 0x7a, 0xca, 0x05, 0x1c, 0xb5, 0x0f, 0x31, 0x54, 0x09, 0xa0, 0x0f, 0x31,
-0x54, 0x09, 0x73, 0xec, 0x2a, 0x03, 0x04, 0x60, 0x2c, 0x00, 0x00, 0x1c, 0x00,
-0x00, 0x28, 0x03, 0x00, 0xc7, 0x1c, 0x01, 0x00, 0x1c, 0x00, 0x00, 0x28, 0x13,
-0x05, 0x07, 0x1d, 0x01, 0x00, 0x1c, 0xc0, 0xd7, 0x22, 0x00, 0x1c, 0x75, 0x56,
-0x7e, 0x13, 0x04, 0x60, 0x2c, 0x00, 0x00, 0x1c, 0xe7, 0x1c, 0x45, 0x03, 0x04,
-0xe7, 0x9c, 0x00, 0x00, 0x1c, 0xa6, 0x7b, 0x95, 0x03, 0x10, 0x80, 0x2c, 0x00,
-0x00, 0x1c, 0x00, 0x00, 0xf8, 0x02, 0x04, 0x00, 0x00, 0x54, 0xc3, 0x04, 0xb9,
-0x7b, 0x01, 0x00, 0x1c, 0x00, 0x00, 0x8c, 0xc3, 0x04, 0xcb, 0xaf, 0xfc, 0x07,
-0x1c, 0xcb, 0x2f, 0x01, 0x04, 0x1c, 0xc7, 0x9f, 0x80, 0x03, 0x1c, 0x00, 0x00,
-0x8c, 0xc3, 0x04, 0xcb, 0xaf, 0xfc, 0x07, 0x1c, 0xcb, 0x2f, 0x0d, 0x04, 0x1c,
-0xc7, 0x9f, 0x80, 0x03, 0x1c, 0x00, 0x00, 0x8c, 0xc3, 0x04, 0xcb, 0xaf, 0x00,
-0xf8, 0x1d, 0xcb, 0x2f, 0x01, 0x00, 0x1d, 0xa6, 0x7b, 0x95, 0x03, 0x1c, 0xc7,
-0x9c, 0x8c, 0xc3, 0x04, 0x00, 0x00, 0x8c, 0x13, 0x05, 0x07, 0x1d, 0x01, 0x00,
-0x1c, 0xc0, 0x1d, 0xdc, 0xd3, 0x08, 0x27, 0x9d, 0xe4, 0x03, 0x00, 0xa0, 0xee,
-0x46, 0xd4, 0x00, 0xfb, 0x75, 0x09, 0x14, 0x04, 0x20, 0x7b, 0x06, 0x00, 0x1c,
-0xc0, 0x1c, 0x1c, 0x04, 0x00, 0x00, 0x00, 0xb0, 0xd3, 0x08, 0x00, 0x00, 0x00,
-0xf4, 0x00, 0xc0, 0xef, 0xf2, 0x00, 0x1c, 0x20, 0x25, 0x5c, 0x14, 0x04, 0x60,
-0xb7, 0xd2, 0x03, 0x00, 0x00, 0x00, 0x0c, 0x15, 0x00, 0xcc, 0xb3, 0xfc, 0x03,
-0x1c, 0xcc, 0x33, 0x05, 0x02, 0x1c, 0x00, 0x00, 0x0c, 0xc5, 0x04, 0x60, 0xb7,
-0x0e, 0x05, 0x04, 0x00, 0x00, 0x0c, 0x15, 0x04, 0x00, 0x00, 0x5c, 0xc4, 0x04,
-0xc0, 0x1d, 0x98, 0xf3, 0x04, 0x00, 0x00, 0x68, 0xc4, 0x04, 0x07, 0x9d, 0x00,
-0x00, 0x1c, 0x1b, 0x74, 0xfd, 0xf3, 0x04, 0xa6, 0x7b, 0xf1, 0x03, 0x1c, 0xa0,
-0x0f, 0x69, 0x54, 0x09, 0xe0, 0x7b, 0x00, 0xfc, 0x1f, 0x39, 0x7f, 0x02, 0x00,
-0x1c, 0x07, 0x1d, 0x9d, 0xc3, 0x04, 0xa6, 0x7b, 0xad, 0x03, 0x1c, 0x00, 0x00,
-0x68, 0xc4, 0x04, 0xe0, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0xa4, 0x03, 0x04,
-0xcb, 0xaf, 0x00, 0xf8, 0x1d, 0xcb, 0x2f, 0x01, 0x10, 0x1d, 0x00, 0x00, 0xac,
-0xc3, 0x04, 0x00, 0x00, 0xac, 0x03, 0x04, 0xcb, 0xaf, 0x00, 0xf8, 0x1d, 0xcb,
-0x2f, 0x01, 0x18, 0x1d, 0xc7, 0x9f, 0x00, 0x0b, 0x1c, 0x00, 0x00, 0xac, 0xc3,
-0x04, 0xfb, 0x75, 0x01, 0x00, 0x1c, 0x07, 0x1d, 0x01, 0x00, 0x1c, 0xcc, 0xb3,
-0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x01, 0x02, 0x1c, 0x00, 0x00, 0xac, 0xc3, 0x04,
-0xa0, 0x1c, 0x00, 0x00, 0x1c, 0xa0, 0xee, 0xa2, 0x03, 0x04, 0xcb, 0xaf, 0xfc,
-0x07, 0x1c, 0xcb, 0x2f, 0x09, 0x04, 0x1c, 0xfb, 0x75, 0x01, 0x00, 0x1c, 0x00,
-0x00, 0xac, 0xc3, 0x04, 0xcc, 0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x01, 0x02,
-0x1c, 0x00, 0x00, 0x0c, 0xc5, 0x04, 0x00, 0x00, 0x78, 0x34, 0x05, 0xcc, 0xb3,
-0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x15, 0x02, 0x1c, 0x47, 0x9d, 0x54, 0xc4, 0x04,
-0x00, 0x00, 0x78, 0x44, 0x00, 0x80, 0x1d, 0x7c, 0x54, 0x04, 0x87, 0x1d, 0x8d,
-0x04, 0x00, 0xce, 0x76, 0x01, 0x00, 0x1c, 0xef, 0x76, 0x9d, 0xc4, 0x04, 0xa4,
-0x77, 0x8d, 0x24, 0x09, 0xe4, 0x76, 0x01, 0x00, 0x1c, 0xc4, 0x76, 0x01, 0x00,
-0x1c, 0x00, 0x00, 0x98, 0x54, 0x04, 0xd7, 0x76, 0x01, 0x50, 0x18, 0xf6, 0x76,
-0x01, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10,
-0xcc, 0x30, 0x45, 0xc5, 0x04, 0xeb, 0x2d, 0x01, 0x00, 0x1c, 0xea, 0x29, 0x01,
-0x00, 0x1c, 0xc0, 0x59, 0x01, 0x00, 0x1c, 0xf5, 0x77, 0x29, 0xc5, 0x04, 0xe0,
-0x30, 0xdc, 0x04, 0x00, 0x00, 0x4c, 0xb0, 0x04, 0x00, 0x20, 0x4c, 0xf4, 0x04,
-0x00, 0x00, 0x00, 0xe8, 0x04, 0x00, 0xcc, 0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33,
-0x09, 0x02, 0x1c, 0xeb, 0x2d, 0xb5, 0xc4, 0x04, 0xcc, 0xb3, 0xfc, 0x03, 0x1c,
-0xcc, 0x33, 0x19, 0x02, 0x1c, 0xeb, 0x2d, 0xb5, 0xc4, 0x04, 0xcc, 0xb3, 0xfc,
-0x03, 0x1c, 0xcc, 0x33, 0x0d, 0x02, 0x1c, 0xeb, 0x2d, 0xb5, 0xc4, 0x04, 0xcc,
-0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x11, 0x02, 0x1c, 0xeb, 0x2d, 0xb5, 0xc4,
-0x04, 0x00, 0x7b, 0x00, 0x80, 0x1c, 0xae, 0x77, 0x45, 0x05, 0x00, 0x00, 0x00,
-0x04, 0xc0, 0x04, 0xd3, 0x8b, 0x00, 0xfc, 0x1f, 0x60, 0x7a, 0x3c, 0x00, 0x1c,
-0x60, 0x4c, 0xc0, 0x04, 0x00, 0xc0, 0x2f, 0x20, 0x05, 0x1f, 0xe0, 0x30, 0xb0,
-0x04, 0x00, 0x80, 0x25, 0xb0, 0x04, 0x00, 0xb5, 0x5b, 0xb1, 0x04, 0x04, 0x69,
-0x26, 0x01, 0x00, 0x1c, 0x6a, 0x2b, 0x01, 0x00, 0x1c, 0x80, 0x1d, 0x00, 0x00,
-0x1c, 0xa9, 0x25, 0x45, 0x05, 0x00, 0xee, 0x30, 0x00, 0x00, 0x1c, 0xaf, 0x77,
-0x01, 0x05, 0x00, 0x00, 0x00, 0xac, 0x24, 0x04, 0xb4, 0x5f, 0x01, 0x40, 0x18,
-0x07, 0x9d, 0x48, 0x55, 0x04, 0xb7, 0x76, 0x01, 0x00, 0x1c, 0x96, 0x76, 0x01,
-0x00, 0x1c, 0x47, 0x1d, 0x01, 0x00, 0x1c, 0xa4, 0x33, 0x01, 0x60, 0x18, 0xa4,
-0x2f, 0x01, 0x60, 0x18, 0x64, 0x77, 0x01, 0x60, 0x18, 0x24, 0x77, 0x01, 0x60,
-0x18, 0x44, 0x77, 0x01, 0x00, 0x1c, 0x64, 0x88, 0x03, 0x00, 0x1c, 0xa4, 0x3f,
-0x01, 0x00, 0x1c, 0xa4, 0x3b, 0x01, 0x00, 0x1c, 0x53, 0x7b, 0x00, 0xc0, 0x1c,
-0xd3, 0xcf, 0x1b, 0x00, 0x1c, 0x53, 0x4f, 0x02, 0x00, 0x1c, 0xda, 0xcf, 0x00,
-0xc0, 0x1f, 0xd5, 0x57, 0x0f, 0x00, 0x1c, 0xd3, 0xd3, 0x37, 0x00, 0x1c, 0xd4,
-0x53, 0x0f, 0x00, 0x1c, 0xe0, 0x29, 0x00, 0x00, 0x1c, 0xf5, 0xd5, 0xb0, 0x05,
-0x00, 0x00, 0x00, 0x9c, 0x55, 0x04, 0x77, 0x56, 0x01, 0x00, 0x1c, 0x56, 0x53,
-0x01, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x10, 0x18, 0x00, 0x00, 0x04, 0xc0, 0x04,
-0xf5, 0x55, 0x01, 0x00, 0x1c, 0x00, 0x00, 0xb4, 0x55, 0x04, 0x77, 0x56, 0x01,
-0x00, 0x1c, 0x56, 0x53, 0x01, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x10, 0x18, 0x00,
-0x00, 0x04, 0xc0, 0x04, 0xcb, 0x2f, 0x01, 0x18, 0x10, 0xcb, 0x2f, 0x01, 0x10,
-0x10, 0xcb, 0x2f, 0x01, 0x08, 0x10, 0xcb, 0x2f, 0x01, 0x08, 0x10, 0xcb, 0x2f,
-0x01, 0x20, 0x10, 0xcb, 0x2f, 0x01, 0x28, 0x10, 0xcb, 0x2f, 0x01, 0x00, 0x10,
-0x89, 0x25, 0x61, 0xc2, 0x04, 0x00, 0x00, 0xec, 0xc2, 0x04, 0x00, 0x00, 0x54,
-0xc3, 0x04, 0x00, 0x00, 0x54, 0xc3, 0x04, 0x00, 0x00, 0x54, 0xc3, 0x04, 0x00,
-0x00, 0x60, 0xc2, 0x04, 0x00, 0x00, 0xec, 0xc2, 0x04, 0x00, 0x00, 0x54, 0xc3,
-0x04, 0x00, 0x00, 0x54, 0xc3, 0x04, 0x00, 0x00, 0x54, 0xc3, 0x04, 0x40, 0x1c,
-0x6c, 0xc0, 0x04, 0x40, 0x1c, 0x9c, 0xc0, 0x04, 0xa7, 0x77, 0x55, 0xc3, 0x04,
-0x00, 0x00, 0xc4, 0xc0, 0x04, 0x27, 0x1d, 0xf1, 0xc0, 0x04, 0x00, 0x00, 0x54,
-0xc3, 0x04, 0x00, 0x00, 0x54, 0xc3, 0x04, 0x00, 0x00, 0x54, 0xc3, 0x04, 0x00,
-0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
-0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
-0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
-0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
-0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00,
-0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
-0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
-0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
-0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
-0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00,
-0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
-0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
-0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
-0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
-0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00,
-0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
-0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
-0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
-0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
-0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00,
-0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
-0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
-0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
-0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
-0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00,
-0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
-0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
-0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
-0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
-0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00,
-0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
-0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
-0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
-0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
-0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00,
-0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
-0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
-0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
-0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
-0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00,
-0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
-0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
-0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
-0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
-0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
-};
diff --git a/drivers/staging/slicoss/slic.h b/drivers/staging/slicoss/slic.h
index a8ea59d..ccf7625 100644
--- a/drivers/staging/slicoss/slic.h
+++ b/drivers/staging/slicoss/slic.h
@@ -46,30 +46,10 @@
 #define OASIS_UCODE_VERS_DATE  	"2006/03/27 15:10:37"
 #define OASIS_UCODE_HOSTIF_ID  	3
 
-static s32 ONumSections = 0x2;
-static u32 OSectionSize[] = {
-	0x00004000, 0x00010000,
-};
-
-static u32 OSectionStart[] = {
-	0x00000000, 0x00008000,
-};
-
 #define MOJAVE_UCODE_VERS_STRING	"1.2"
 #define MOJAVE_UCODE_VERS_DATE  	"2006/03/27 15:12:22"
 #define MOJAVE_UCODE_HOSTIF_ID  	3
 
-static s32 MNumSections = 0x2;
-static u32 MSectionSize[] =
-{
-	0x00008000, 0x00010000,
-};
-
-static u32 MSectionStart[] =
-{
-	0x00000000, 0x00008000,
-};
-
 #define GB_RCVUCODE_VERS_STRING	"1.2"
 #define GB_RCVUCODE_VERS_DATE  	"2006/03/27 15:12:15"
 static u32 OasisRcvUCodeLen = 512;
@@ -201,17 +181,6 @@
 
 #define SLIC_MAX_CARDS              32
 #define SLIC_MAX_PORTS              4        /* Max # of ports per card   */
-#if SLIC_DUMP_ENABLED
-/*
-Dump buffer size
-
-This cannot be bigger than the max DMA size the card supports,
-given the current code structure in the host and ucode.
-Mojave supports 16K, Oasis supports 16K-1, so
-just set this at 15K, shouldnt make that much of a diff.
-*/
-#define DUMP_BUF_SIZE               0x3C00
-#endif
 
 
 struct mcast_address {
@@ -367,30 +336,6 @@
     u32             max_isr_xmits;
     u32             rcv_interrupt_yields;
     u32             tx_packets;
-#if SLIC_DUMP_ENABLED
-    u32             dumpstatus;           /* Result of dump UPR */
-    void *cmdbuffer;
-
-    ulong               cmdbuffer_phys;
-    u32             cmdbuffer_physl;
-    u32             cmdbuffer_physh;
-
-    u32             dump_count;
-    struct task_struct *dump_task_id;
-    u32             dump_wait_count;
-    uint                dumpthread_running; /* has a dump thread been init'd  */
-    uint                dump_requested;     /* 0 no, 1 = reqstd 2=curr 3=done */
-    u32             dumptime_start;
-    u32             dumptime_complete;
-    u32             dumptime_delta;
-    void *dumpbuffer;
-    ulong               dumpbuffer_phys;
-    u32             dumpbuffer_physl;
-    u32             dumpbuffer_physh;
-    wait_queue_head_t   dump_wq;
-    struct file        *dumphandle;
-    mm_segment_t        dumpfile_fs;
-#endif
     u32             debug_ix;
     ushort              reg_type[32];
     ushort              reg_offset[32];
@@ -516,8 +461,6 @@
     uint                upr_busy;
     struct timer_list   pingtimer;
     u32             pingtimerset;
-    struct timer_list   statstimer;
-    u32             statstimerset;
     struct timer_list   loadtimer;
     u32             loadtimerset;
     struct dentry      *debugfs_entry;
@@ -570,25 +513,6 @@
     struct net_device_stats stats;
 };
 
-#if SLIC_DUMP_ENABLED
-#define SLIC_DUMP_REQUESTED      1
-#define SLIC_DUMP_IN_PROGRESS    2
-#define SLIC_DUMP_DONE           3
-
-/****************************************************************************
- *
- * Microcode crash information structure.  This
- * structure is written out to the card's SRAM when the microcode panic's.
- *
- ****************************************************************************/
-struct slic_crash_info {
-    ushort  cpu_id;
-    ushort  crash_pc;
-};
-
-#define CRASH_INFO_OFFSET   0x155C
-
-#endif
 
 #define UPDATE_STATS(largestat, newstat, oldstat)                        \
 {                                                                        \
@@ -605,11 +529,11 @@
 
 #define ETHER_EQ_ADDR(_AddrA, _AddrB, _Result)                           \
 {                                                                        \
-    _Result = TRUE;                                                      \
+    _Result = true;                                                      \
     if (*(u32 *)(_AddrA) != *(u32 *)(_AddrB))                          \
-	_Result = FALSE;                                                 \
+	_Result = false;                                                 \
     if (*(u16 *)(&((_AddrA)[4])) != *(u16 *)(&((_AddrB)[4])))        \
-	_Result = FALSE;                                                 \
+	_Result = false;                                                 \
 }
 
 #if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
@@ -622,8 +546,8 @@
 #define   SLIC_GET_ADDR_HIGH(_addr)  (u32)0
 #endif
 
-#define FLUSH       TRUE
-#define DONT_FLUSH  FALSE
+#define FLUSH		true
+#define DONT_FLUSH	false
 
 #define SIOCSLICDUMPCARD         (SIOCDEVPRIVATE+9)
 #define SIOCSLICSETINTAGG        (SIOCDEVPRIVATE+10)
diff --git a/drivers/staging/slicoss/slic_os.h b/drivers/staging/slicoss/slic_os.h
deleted file mode 100644
index 46c6784..0000000
--- a/drivers/staging/slicoss/slic_os.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/**************************************************************************
- *
- * Copyright (c)2000-2002 Alacritech, 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:
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``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 ALACRITECH, INC. 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.
- *
- * The views and conclusions contained in the software and documentation
- * are those of the authors and should not be interpreted as representing
- * official policies, either expressed or implied, of Alacritech, Inc.
- *
- **************************************************************************/
-
-/*
- * FILENAME: slic_os.h
- *
- * These are the Linux-specific definitions required for the SLICOSS
- * driver, which should allow for greater portability to other OSes.
- */
-#ifndef _SLIC_OS_SPECIFIC_H_
-#define _SLIC_OS_SPECIFIC_H_
-
-#define FALSE               (0)
-#define TRUE                (1)
-
-#define SLIC_SECS_TO_JIFFS(x)  ((x) * HZ)
-#define SLIC_MS_TO_JIFFIES(x)  (SLIC_SECS_TO_JIFFS((x)) / 1000)
-
-#ifdef DEBUG_REGISTER_TRACE
-#define WRITE_REG(reg, value, flush)                                      \
-	{                                                           \
-		adapter->card->reg_type[adapter->card->debug_ix] = 0;   \
-		adapter->card->reg_offset[adapter->card->debug_ix] = \
-		((unsigned char *)(&reg)) - \
-		((unsigned char *)adapter->slic_regs); \
-		adapter->card->reg_value[adapter->card->debug_ix++] = value;  \
-		if (adapter->card->debug_ix == 32) \
-			adapter->card->debug_ix = 0;                      \
-		slic_reg32_write((&reg), (value), (flush));            \
-	}
-#define WRITE_REG64(a, reg, value, regh, valh, flush)                        \
-	{                                                           \
-		adapter->card->reg_type[adapter->card->debug_ix] = 1;        \
-		adapter->card->reg_offset[adapter->card->debug_ix] = \
-		((unsigned char *)(&reg)) - \
-		((unsigned char *)adapter->slic_regs); \
-		adapter->card->reg_value[adapter->card->debug_ix] = value;   \
-		adapter->card->reg_valueh[adapter->card->debug_ix++] = valh;  \
-		if (adapter->card->debug_ix == 32) \
-			adapter->card->debug_ix = 0;                      \
-		slic_reg64_write((a), (&reg), (value), (&regh), (valh), \
-				(flush));\
-	}
-#else
-#define WRITE_REG(reg, value, flush) \
-	slic_reg32_write((&reg), (value), (flush))
-#define WRITE_REG64(a, reg, value, regh, valh, flush) \
-	slic_reg64_write((a), (&reg), (value), (&regh), (valh), (flush))
-#endif
-
-#endif  /* _SLIC_OS_SPECIFIC_H_  */
-
diff --git a/drivers/staging/slicoss/slicbuild.h b/drivers/staging/slicoss/slicbuild.h
deleted file mode 100644
index ae05e04..0000000
--- a/drivers/staging/slicoss/slicbuild.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/**************************************************************************
- *
- * Copyright (c) 2000-2002 Alacritech, 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:
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``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 ALACRITECH, INC. 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.
- *
- * The views and conclusions contained in the software and documentation
- * are those of the authors and should not be interpreted as representing
- * official policies, either expressed or implied, of Alacritech, Inc.
- *
- **************************************************************************/
-
-/*
- * FILENAME: slicbuild.h
- *
- * The following contains the compiler directive switches used for
- * different SLIC build options.  They can all be set in the Makefile
- * but the defaults are defined here.
- */
-#ifndef _SLIC_BUILD_H_
-#define _SLIC_BUILD_H_
-
-#ifndef SLIC_PRODUCTION_BUILD
-#define SLIC_PRODUCTION_BUILD			1
-#endif
-#ifndef SLIC_FAILURE_RESET
-#define SLIC_FAILURE_RESET			1
-#endif
-#define DBG                         1
-#ifndef SLIC_ASSERT_ENABLED
-#define SLIC_ASSERT_ENABLED			1
-#endif
-#ifndef SLIC_MCAST_ENABLED
-#define SLIC_MCAST_ENABLED			1
-#endif
-#ifndef SLIC_GET_STATS_ENABLED
-#define SLIC_GET_STATS_ENABLED			1
-#endif
-#ifndef SLIC_GET_STATS_TIMER_ENABLED
-#define SLIC_GET_STATS_TIMER_ENABLED		0
-#endif
-#ifndef SLIC_PING_TIMER_ENABLED
-#define SLIC_PING_TIMER_ENABLED		1
-#endif
-#ifndef SLIC_IOCTL_SUPPORT_ENABLED
-#define SLIC_IOCTL_SUPPORT_ENABLED		1
-#endif
-#ifndef ATK_DEBUG
-#define ATK_DEBUG				1
-#endif
-#ifndef SLIC_POWER_MANAGEMENT_ENABLED
-#define SLIC_POWER_MANAGEMENT_ENABLED		0
-#endif
-#ifndef SLIC_INTERRUPT_PROCESS_LIMIT
-#define SLIC_INTERRUPT_PROCESS_LIMIT		1
-#endif
-#ifndef LINUX_FREES_ADAPTER_RESOURCES
-#define LINUX_FREES_ADAPTER_RESOURCES		1
-#endif
-#ifndef SLIC_OFFLOAD_IP_CHECKSUM
-#define SLIC_OFFLOAD_IP_CHECKSUM		1
-#endif
-#ifndef SLIC_POWER_MANAGEMENT_ENABLED
-#define SLIC_POWER_MANAGEMENT_ENABLED		0
-#endif
-#ifndef STATS_TIMER_INTERVAL
-#define STATS_TIMER_INTERVAL			2
-#endif
-#ifndef PING_TIMER_INTERVAL
-#define PING_TIMER_INTERVAL			1
-#endif
-
-#endif   /* _SLIC_BUILD_H_  */
diff --git a/drivers/staging/slicoss/slicdbg.h b/drivers/staging/slicoss/slicdbg.h
deleted file mode 100644
index c54e44f..0000000
--- a/drivers/staging/slicoss/slicdbg.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/**************************************************************************
- *
- * Copyright (c) 2000-2002 Alacritech, 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:
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``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 ALACRITECH, INC. 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.
- *
- * The views and conclusions contained in the software and documentation
- * are those of the authors and should not be interpreted as representing
- * official policies, either expressed or implied, of Alacritech, Inc.
- *
- **************************************************************************/
-
-/*
- * FILENAME: slicdbg.h
- *
- * All debug and assertion-based definitions and macros are included
- * in this file for the SLICOSS driver.
- */
-#ifndef _SLIC_DEBUG_H_
-#define _SLIC_DEBUG_H_
-
-#ifdef SLIC_DEFAULT_LOG_LEVEL
-#else
-#define SLICLEVEL   KERN_DEBUG
-#endif
-#define SLIC_DISPLAY              printk
-#define DBG_ERROR(n, args...)   SLIC_DISPLAY(KERN_EMERG n, ##args)
-
-#define SLIC_DEBUG_MESSAGE 1
-#if SLIC_DEBUG_MESSAGE
-/*#define DBG_MSG(n, args...)      SLIC_DISPLAY(SLICLEVEL n, ##args)*/
-#define DBG_MSG(n, args...)
-#else
-#define DBG_MSG(n, args...)
-#endif
-
-#ifdef ASSERT
-#undef ASSERT
-#endif
-
-#if SLIC_ASSERT_ENABLED
-#ifdef CONFIG_X86_64
-#define VALID_ADDRESS(p)  (1)
-#else
-#define VALID_ADDRESS(p)  (((u32)(p) & 0x80000000) || ((u32)(p) == 0))
-#endif
-#ifndef ASSERT
-#define ASSERT(a)                                                             \
-    {                                                                         \
-	if (!(a)) {                                                           \
-		DBG_ERROR("ASSERT() Failure: file %s, function %s  line %d\n",\
-		__FILE__, __func__, __LINE__);                          \
-		slic_assert_fail();                                       \
-	}                                                                 \
-    }
-#endif
-#ifndef ASSERTMSG
-#define ASSERTMSG(a,msg)                                                  \
-    {                                                                     \
-	if (!(a)) {                                                       \
-		DBG_ERROR("ASSERT() Failure: file %s, function %s"\
-			"line %d: %s\n",\
-			__FILE__, __func__, __LINE__, (msg));            \
-		slic_assert_fail();                                      \
-	}                                                                \
-    }
-#endif
-#else
-#ifndef ASSERT
-#define ASSERT(a)
-#endif
-#ifndef ASSERTMSG
-#define ASSERTMSG(a, msg)
-#endif
-#endif /* SLIC_ASSERT_ENABLED  */
-
-#endif  /*  _SLIC_DEBUG_H_  */
diff --git a/drivers/staging/slicoss/slicdump.h b/drivers/staging/slicoss/slicdump.h
deleted file mode 100644
index 92a9b44..0000000
--- a/drivers/staging/slicoss/slicdump.h
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- *
- * Copyright (c) 2000-2002 Alacritech, 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:
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``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 ALACRITECH, INC. 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.
- *
- * NO LICENSE TO ANY ALACRITECH PATENT CLAIM IS GRANTED BY ANY COPYRIGHT
- * LICENSE TO THIS OR OTHER SOFTWARE. THIS SOFTWARE MAY BE COVERED BY
- * ALACRITECH PATENTS INCLUDING BUT NOT LIMITED TO U.S. PATENT NOS. 6,226,680,
- * 6,247,060, 6,334,153, 6,389,479, 6,393,487, 6,427,171, 6,427,173
- * and 6,434,620.
- * THIS SOFTWARE IS NOT SUBJECT TO THE GNU GENERAL PUBLIC LICENSE (GPL).
- *
- * The views and conclusions contained in the software and
- * documentation are those of the authors and should not be
- * interpreted as representing official policies, either
- * expressed or implied, of Alacritech, Inc.
- */
-#ifndef _SLIC_DUMP_H_
-#define _SLIC_DUMP_H_
-
-#define DEBUG_SUCCESS   0
-
-/***********************************************************************
- *
- * Utility processor register locations
- *
- **********************************************************************/
-#define UTILITY_RESET       0x0
-#define UTILITY_ISP_ADDR    0x4     /* Interrupt status Pointer */
-#define UTILITY_ISR_ADDR    0x8     /* Interrupt status Register */
-#define UTILITY_ICR_ADDR    0xc     /* Interrupt Control Register */
-#define UTILITY_CPR_ADDR    0x10    /* Command Pointer Register */
-#define UTILITY_DPR_ADDR    0x14    /* Data Pointer Register */
-#define UTILITY_DMP_TRQ     0x18    /* Dump queue onto ALU for analyser */
-#define UTILITY_UPP_ADDR    0x1c    /* Bits 63-32 of cmd/data pointer */
-
-/***********************************************************************
- *
- * INIC status register bits
- *
- ***********************************************************************/
-#define SLIC_ISR_CC         0x10000000  /* Command complete - synchronous */
-#define SLIC_ISR_ERR        0x01000000  /* Command Error - synchronous */
-#define SLIC_ISR_CMD_MASK   0x11000000  /* Command status mask */
-#define SLIC_ISR_TPH        0x00080000  /* Transmit processor halted - async */
-#define SLIC_ISR_RPH        0x00040000  /* Receive processor halted - async */
-
-/***********************************************************************
- *
- * INIC Control register values
- *
- ***********************************************************************/
-#define SLIC_ICR_OFF        0           /* Interrupts disabled */
-#define SLIC_ICR_ON         1           /* Interrupts enabled */
-#define SLIC_ICR_MASK       2           /* Interrupts masked */
-
-#define WRITE_DREG(reg, value, flush)                           \
-{                                                               \
-    writel((value), (reg));                                     \
-    if ((flush)) {                                               \
-	mb();                                                   \
-    }                                                           \
-}
-
-/************************************************************************
- *
- * Command Format
- *
- * Each command contains a command byte which is defined as follows:
- *
- *  bits:   7-3     2       1-0
- *      ----------------------------------------------
- *      command     Alt. Proc   Processor
- *
- ************************************************************************/
-
-/*
- * Macro to create the command byte given the command, Alt. Proc, and
- * Processor values.  Note that the macro assumes that the values are
- * preshifted.  That is, the values for alt. proc are 0 for transmit and
- * 4 for receive.
- */
-#define COMMAND_BYTE(command, alt_proc, proc) ((command) | (alt_proc) | (proc))
-
-/*
- * Command values
- */
-#define CMD_HALT        0x0     /* Send a halt to the INIC */
-#define CMD_RUN         0x8     /* Start the halted INIC */
-#define CMD_STEP        0x10    /* Single step the inic */
-#define CMD_BREAK       0x18    /* Set a breakpoint - 8 byte command */
-#define CMD_RESET_BREAK 0x20    /* Reset a breakpoint - 8 byte cmd */
-#define CMD_DUMP        0x28    /* Dump INIC memory - 8 byte command */
-#define CMD_LOAD        0x30    /* Load INIC memory - 8 byte command */
-#define CMD_MAP         0x38    /* Map out a ROM instruction - 8 BC */
-#define CMD_CAM_OPS     0x38    /* perform ops on specific CAM */
-#define CMD_XMT         0x40    /* Transmit frame */
-#define CMD_RCV         0x48    /* Receive frame */
-
-/*
- * Alt. Proc values
- *
- * When the proc value is set to the utility processor, the Alt. Proc
- * specifies which processor handles the debugging.
- */
-#define ALT_PROC_TRANSMIT   0x0
-#define ALT_PROC_RECEIVE    0x4
-
-/*
- * Proc values
- */
-#define PROC_INVALID        0x0
-#define PROC_NONE           0x0  /* Gigabit use */
-#define PROC_TRANSMIT       0x1
-#define PROC_RECEIVE        0x2
-#define PROC_UTILITY        0x3
-
-/******************************************************************
- *
- * 8 byte command structure definitions
- *
- ******************************************************************/
-
-/*
- * Break and Reset Break command structure
- */
-struct BREAK {
-    unsigned char     command;    /* Command word defined above */
-    unsigned char     resvd;
-    ushort    count;      /* Number of executions before break */
-    u32   addr;       /* Address of break point */
-};
-
-/*
- * Dump and Load command structure
- */
-struct dump_cmd {
-    unsigned char     cmd;        /* Command word defined above */
-    unsigned char     desc;       /* Descriptor values - defined below */
-    ushort    count;      /* number of 4 byte words to be transferred */
-    u32   addr;       /* start address of dump or load */
-};
-
-/*
- * Receive or Transmit a frame.
- */
-struct RCV_OR_XMT_FRAME {
-    unsigned char     command;    /* Command word defined above */
-    unsigned char     MacId;      /* Mac ID of interface - transmit only */
-    ushort    count;      /* Length of frame in bytes */
-    u32   pad;        /* not used */
-};
-
-/*
- * Values of desc field in DUMP_OR_LOAD structure
- */
-#define DESC_RFILE          0x0     /* Register file */
-#define DESC_SRAM           0x1     /* SRAM */
-#define DESC_DRAM           0x2     /* DRAM */
-#define DESC_QUEUE          0x3     /* queues */
-#define DESC_REG            0x4     /* General registers (pc, status, etc) */
-#define DESC_SENSE          0x5     /* Sense register */
-
-/* Descriptor field definitions for CMD_DUMP_CAM */
-#define DUMP_CAM_A              0
-#define DUMP_CAM_B              1               /* unused at present */
-#define DUMP_CAM_C              2
-#define DUMP_CAM_D              3
-#define SEARCH_CAM_A            4
-#define SEARCH_CAM_C            5
-
-/*
- * Map command to replace a command in ROM with a command in WCS
- */
-struct MAP {
-    unsigned char   command;    /* Command word defined above */
-    unsigned char   not_used[3];
-    ushort  map_to;     /* Instruction address in WCS */
-    ushort  map_out;    /* Instruction address in ROM */
-};
-
-/*
- * Misc definitions
- */
-#define SLIC_MAX_QUEUE       32 /* Total # of queues on the INIC (0-31)*/
-#define SLIC_4MAX_REG       512 /* Total # of 4-port file-registers    */
-#define SLIC_1MAX_REG       384 /* Total # of file-registers           */
-#define SLIC_GBMAX_REG     1024 /* Total # of Gbit file-registers      */
-#define SLIC_NUM_REG         32 /* non-file-registers = NUM_REG in tm-simba.h */
-#define SLIC_GB_CAMA_SZE     32
-#define SLIC_GB_CAMB_SZE     16
-#define SLIC_GB_CAMAB_SZE    32
-#define SLIC_GB_CAMC_SZE     16
-#define SLIC_GB_CAMD_SZE     16
-#define SLIC_GB_CAMCD_SZE    32
-
-/*
- * Coredump header structure
- */
-struct CORE_Q {
-    u32   queueOff;           /* Offset of queue */
-    u32   queuesize;          /* size of queue */
-};
-
-#define DRIVER_NAME_SIZE    32
-
-struct sliccore_hdr {
-    unsigned char driver_version[DRIVER_NAME_SIZE]; /* Driver version string */
-    u32   RcvRegOff;          /* Offset of receive registers */
-    u32   RcvRegsize;         /* size of receive registers */
-    u32   XmtRegOff;          /* Offset of transmit registers */
-    u32   XmtRegsize;         /* size of transmit registers */
-    u32   FileRegOff;         /* Offset of register file */
-    u32   FileRegsize;        /* size of register file */
-    u32   SramOff;            /* Offset of Sram */
-    u32   Sramsize;           /* size of Sram */
-    u32   DramOff;            /* Offset of Dram */
-    u32   Dramsize;           /* size of Dram */
-    CORE_Q    queues[SLIC_MAX_QUEUE]; /* size and offsets of queues */
-    u32   CamAMOff;           /* Offset of CAM A contents */
-    u32   CamASize;           /* Size of Cam A */
-    u32   CamBMOff;           /* Offset of CAM B contents */
-    u32   CamBSize;           /* Size of Cam B */
-    u32   CamCMOff;           /* Offset of CAM C contents */
-    u32   CamCSize;           /* Size of Cam C */
-    u32   CamDMOff;           /* Offset of CAM D contents */
-    u32   CamDSize;           /* Size of Cam D */
-};
-
-/*
- * definitions needed for our kernel-mode gdb stub.
- */
-/***********************************************************************
- *
- * Definitions & Typedefs
- *
- **********************************************************************/
-#define BUFMAX      0x20000 /* 128k - size of input/output buffer */
-#define BUFMAXP2    5       /* 2**5 (32) 4K pages */
-
-#define IOCTL_SIMBA_BREAK           _IOW('s', 0, unsigned long)
-/* #define IOCTL_SIMBA_INIT            _IOW('s', 1, unsigned long) */
-#define IOCTL_SIMBA_KILL_TGT_PROC   _IOW('s', 2, unsigned long)
-
-/***********************************************************************
- *
- * Global variables
- *
- ***********************************************************************/
-
-#define THREADRECEIVE   1   /* bit 0 of StoppedThreads */
-#define THREADTRANSMIT  2   /* bit 1 of StoppedThreads */
-#define THREADBOTH      3   /* bit 0 and 1.. */
-
-#endif  /*  _SLIC_DUMP_H  */
diff --git a/drivers/staging/slicoss/slichw.h b/drivers/staging/slicoss/slichw.h
index d03e90b..6275d45 100644
--- a/drivers/staging/slicoss/slichw.h
+++ b/drivers/staging/slicoss/slichw.h
@@ -41,300 +41,286 @@
 #ifndef __SLICHW_H__
 #define __SLICHW_H__
 
-#define PCI_VENDOR_ID_ALACRITECH    0x139A
-#define SLIC_1GB_DEVICE_ID          0x0005
-#define SLIC_2GB_DEVICE_ID          0x0007  /*Oasis Device ID */
+#define PCI_VENDOR_ID_ALACRITECH	0x139A
+#define SLIC_1GB_DEVICE_ID		0x0005
+#define SLIC_2GB_DEVICE_ID		0x0007	/* Oasis Device ID */
 
-#define SLIC_1GB_CICADA_SUBSYS_ID   0x0008
+#define SLIC_1GB_CICADA_SUBSYS_ID	0x0008
 
-#define SLIC_NBR_MACS      4
+#define SLIC_NBR_MACS		4
 
-#define SLIC_RCVBUF_SIZE        2048
-#define SLIC_RCVBUF_HEADSIZE    34
-#define SLIC_RCVBUF_TAILSIZE    0
-#define SLIC_RCVBUF_DATASIZE    (SLIC_RCVBUF_SIZE - (SLIC_RCVBUF_HEADSIZE +\
-					SLIC_RCVBUF_TAILSIZE))
+#define SLIC_RCVBUF_SIZE	2048
+#define SLIC_RCVBUF_HEADSIZE	34
+#define SLIC_RCVBUF_TAILSIZE	0
+#define SLIC_RCVBUF_DATASIZE	(SLIC_RCVBUF_SIZE -		\
+				 (SLIC_RCVBUF_HEADSIZE +	\
+				  SLIC_RCVBUF_TAILSIZE))
 
-#define VGBSTAT_XPERR           0x40000000
-#define VGBSTAT_XERRSHFT        25
-#define VGBSTAT_XCSERR          0x23
-#define VGBSTAT_XUFLOW          0x22
-#define VGBSTAT_XHLEN           0x20
-#define VGBSTAT_NETERR          0x01000000
-#define VGBSTAT_NERRSHFT        16
-#define VGBSTAT_NERRMSK         0x1ff
-#define VGBSTAT_NCSERR          0x103
-#define VGBSTAT_NUFLOW          0x102
-#define VGBSTAT_NHLEN           0x100
-#define VGBSTAT_LNKERR          0x00000080
-#define VGBSTAT_LERRMSK         0xff
-#define VGBSTAT_LDEARLY         0x86
-#define VGBSTAT_LBOFLO          0x85
-#define VGBSTAT_LCODERR         0x84
-#define VGBSTAT_LDBLNBL         0x83
-#define VGBSTAT_LCRCERR         0x82
-#define VGBSTAT_LOFLO           0x81
-#define VGBSTAT_LUFLO           0x80
-#define IRHDDR_FLEN_MSK         0x0000ffff
-#define IRHDDR_SVALID           0x80000000
-#define IRHDDR_ERR              0x10000000
-#define VRHSTAT_802OE           0x80000000
-#define VRHSTAT_TPOFLO          0x10000000
-#define VRHSTATB_802UE          0x80000000
-#define VRHSTATB_RCVE           0x40000000
-#define VRHSTATB_BUFF           0x20000000
-#define VRHSTATB_CARRE          0x08000000
-#define VRHSTATB_LONGE          0x02000000
-#define VRHSTATB_PREA           0x01000000
-#define VRHSTATB_CRC            0x00800000
-#define VRHSTATB_DRBL           0x00400000
-#define VRHSTATB_CODE           0x00200000
-#define VRHSTATB_TPCSUM         0x00100000
-#define VRHSTATB_TPHLEN         0x00080000
-#define VRHSTATB_IPCSUM         0x00040000
-#define VRHSTATB_IPLERR         0x00020000
-#define VRHSTATB_IPHERR         0x00010000
-#define SLIC_MAX64_BCNT         23
-#define SLIC_MAX32_BCNT         26
-#define IHCMD_XMT_REQ           0x01
-#define IHFLG_IFSHFT            2
-#define SLIC_RSPBUF_SIZE        32
+#define VGBSTAT_XPERR		0x40000000
+#define VGBSTAT_XERRSHFT	25
+#define VGBSTAT_XCSERR		0x23
+#define VGBSTAT_XUFLOW		0x22
+#define VGBSTAT_XHLEN		0x20
+#define VGBSTAT_NETERR		0x01000000
+#define VGBSTAT_NERRSHFT	16
+#define VGBSTAT_NERRMSK		0x1ff
+#define VGBSTAT_NCSERR		0x103
+#define VGBSTAT_NUFLOW		0x102
+#define VGBSTAT_NHLEN		0x100
+#define VGBSTAT_LNKERR		0x00000080
+#define VGBSTAT_LERRMSK		0xff
+#define VGBSTAT_LDEARLY		0x86
+#define VGBSTAT_LBOFLO		0x85
+#define VGBSTAT_LCODERR		0x84
+#define VGBSTAT_LDBLNBL		0x83
+#define VGBSTAT_LCRCERR		0x82
+#define VGBSTAT_LOFLO		0x81
+#define VGBSTAT_LUFLO		0x80
+#define IRHDDR_FLEN_MSK		0x0000ffff
+#define IRHDDR_SVALID		0x80000000
+#define IRHDDR_ERR		0x10000000
+#define VRHSTAT_802OE		0x80000000
+#define VRHSTAT_TPOFLO		0x10000000
+#define VRHSTATB_802UE		0x80000000
+#define VRHSTATB_RCVE		0x40000000
+#define VRHSTATB_BUFF		0x20000000
+#define VRHSTATB_CARRE		0x08000000
+#define VRHSTATB_LONGE		0x02000000
+#define VRHSTATB_PREA		0x01000000
+#define VRHSTATB_CRC		0x00800000
+#define VRHSTATB_DRBL		0x00400000
+#define VRHSTATB_CODE		0x00200000
+#define VRHSTATB_TPCSUM		0x00100000
+#define VRHSTATB_TPHLEN		0x00080000
+#define VRHSTATB_IPCSUM		0x00040000
+#define VRHSTATB_IPLERR		0x00020000
+#define VRHSTATB_IPHERR		0x00010000
+#define SLIC_MAX64_BCNT		23
+#define SLIC_MAX32_BCNT		26
+#define IHCMD_XMT_REQ		0x01
+#define IHFLG_IFSHFT		2
+#define SLIC_RSPBUF_SIZE	32
 
-#define SLIC_RESET_MAGIC        0xDEAD
-#define ICR_INT_OFF             0
-#define ICR_INT_ON              1
-#define ICR_INT_MASK            2
+#define SLIC_RESET_MAGIC	0xDEAD
+#define ICR_INT_OFF		0
+#define ICR_INT_ON		1
+#define ICR_INT_MASK		2
 
-#define ISR_ERR                 0x80000000
-#define ISR_RCV                 0x40000000
-#define ISR_CMD                 0x20000000
-#define ISR_IO                  0x60000000
-#define ISR_UPC                 0x10000000
-#define ISR_LEVENT              0x08000000
-#define ISR_RMISS               0x02000000
-#define ISR_UPCERR              0x01000000
-#define ISR_XDROP               0x00800000
-#define ISR_UPCBSY              0x00020000
-#define ISR_EVMSK               0xffff0000
-#define ISR_PINGMASK            0x00700000
-#define ISR_PINGDSMASK          0x00710000
-#define ISR_UPCMASK             0x11000000
-#define SLIC_WCS_START          0x80000000
-#define SLIC_WCS_COMPARE        0x40000000
-#define SLIC_RCVWCS_BEGIN       0x40000000
-#define SLIC_RCVWCS_FINISH      0x80000000
-#define SLIC_PM_MAXPATTERNS     6
-#define SLIC_PM_PATTERNSIZE     128
-#define SLIC_PMCAPS_WAKEONLAN   0x00000001
-#define MIICR_REG_PCR           0x00000000
-#define MIICR_REG_4             0x00040000
-#define MIICR_REG_9             0x00090000
-#define MIICR_REG_16            0x00100000
-#define PCR_RESET               0x8000
-#define PCR_POWERDOWN           0x0800
-#define PCR_SPEED_100           0x2000
-#define PCR_SPEED_1000          0x0040
-#define PCR_AUTONEG             0x1000
-#define PCR_AUTONEG_RST         0x0200
-#define PCR_DUPLEX_FULL         0x0100
-#define PSR_LINKUP              0x0004
+#define ISR_ERR			0x80000000
+#define ISR_RCV			0x40000000
+#define ISR_CMD			0x20000000
+#define ISR_IO			0x60000000
+#define ISR_UPC			0x10000000
+#define ISR_LEVENT		0x08000000
+#define ISR_RMISS		0x02000000
+#define ISR_UPCERR		0x01000000
+#define ISR_XDROP		0x00800000
+#define ISR_UPCBSY		0x00020000
+#define ISR_EVMSK		0xffff0000
+#define ISR_PINGMASK		0x00700000
+#define ISR_PINGDSMASK		0x00710000
+#define ISR_UPCMASK		0x11000000
+#define SLIC_WCS_START		0x80000000
+#define SLIC_WCS_COMPARE	0x40000000
+#define SLIC_RCVWCS_BEGIN	0x40000000
+#define SLIC_RCVWCS_FINISH	0x80000000
+#define SLIC_PM_MAXPATTERNS	6
+#define SLIC_PM_PATTERNSIZE	128
+#define SLIC_PMCAPS_WAKEONLAN	0x00000001
+#define MIICR_REG_PCR		0x00000000
+#define MIICR_REG_4		0x00040000
+#define MIICR_REG_9		0x00090000
+#define MIICR_REG_16		0x00100000
+#define PCR_RESET		0x8000
+#define PCR_POWERDOWN		0x0800
+#define PCR_SPEED_100		0x2000
+#define PCR_SPEED_1000		0x0040
+#define PCR_AUTONEG		0x1000
+#define PCR_AUTONEG_RST		0x0200
+#define PCR_DUPLEX_FULL		0x0100
+#define PSR_LINKUP		0x0004
 
-#define PAR_ADV100FD            0x0100
-#define PAR_ADV100HD            0x0080
-#define PAR_ADV10FD             0x0040
-#define PAR_ADV10HD             0x0020
-#define PAR_ASYMPAUSE           0x0C00
-#define PAR_802_3               0x0001
+#define PAR_ADV100FD		0x0100
+#define PAR_ADV100HD		0x0080
+#define PAR_ADV10FD		0x0040
+#define PAR_ADV10HD		0x0020
+#define PAR_ASYMPAUSE		0x0C00
+#define PAR_802_3		0x0001
 
-#define PAR_ADV1000XFD          0x0020
-#define PAR_ADV1000XHD          0x0040
-#define PAR_ASYMPAUSE_FIBER     0x0180
+#define PAR_ADV1000XFD		0x0020
+#define PAR_ADV1000XHD		0x0040
+#define PAR_ASYMPAUSE_FIBER	0x0180
 
-#define PGC_ADV1000FD           0x0200
-#define PGC_ADV1000HD           0x0100
-#define SEEQ_LINKFAIL           0x4000
-#define SEEQ_SPEED              0x0080
-#define SEEQ_DUPLEX             0x0040
-#define TDK_DUPLEX              0x0800
-#define TDK_SPEED               0x0400
-#define MRV_REG16_XOVERON       0x0068
-#define MRV_REG16_XOVEROFF      0x0008
-#define MRV_SPEED_1000          0x8000
-#define MRV_SPEED_100           0x4000
-#define MRV_SPEED_10            0x0000
-#define MRV_FULLDUPLEX          0x2000
-#define MRV_LINKUP              0x0400
+#define PGC_ADV1000FD		0x0200
+#define PGC_ADV1000HD		0x0100
+#define SEEQ_LINKFAIL		0x4000
+#define SEEQ_SPEED		0x0080
+#define SEEQ_DUPLEX		0x0040
+#define TDK_DUPLEX		0x0800
+#define TDK_SPEED		0x0400
+#define MRV_REG16_XOVERON	0x0068
+#define MRV_REG16_XOVEROFF	0x0008
+#define MRV_SPEED_1000		0x8000
+#define MRV_SPEED_100		0x4000
+#define MRV_SPEED_10		0x0000
+#define MRV_FULLDUPLEX		0x2000
+#define MRV_LINKUP		0x0400
 
-#define GIG_LINKUP              0x0001
-#define GIG_FULLDUPLEX          0x0002
-#define GIG_SPEED_MASK          0x000C
-#define GIG_SPEED_1000          0x0008
-#define GIG_SPEED_100           0x0004
-#define GIG_SPEED_10            0x0000
+#define GIG_LINKUP		0x0001
+#define GIG_FULLDUPLEX		0x0002
+#define GIG_SPEED_MASK		0x000C
+#define GIG_SPEED_1000		0x0008
+#define GIG_SPEED_100		0x0004
+#define GIG_SPEED_10		0x0000
 
-#define MCR_RESET               0x80000000
-#define MCR_CRCEN               0x40000000
-#define MCR_FULLD               0x10000000
-#define MCR_PAD                 0x02000000
-#define MCR_RETRYLATE           0x01000000
-#define MCR_BOL_SHIFT           21
-#define MCR_IPG1_SHIFT          14
-#define MCR_IPG2_SHIFT          7
-#define MCR_IPG3_SHIFT          0
-#define GMCR_RESET              0x80000000
-#define GMCR_GBIT               0x20000000
-#define GMCR_FULLD              0x10000000
-#define GMCR_GAPBB_SHIFT        14
-#define GMCR_GAPR1_SHIFT        7
-#define GMCR_GAPR2_SHIFT        0
-#define GMCR_GAPBB_1000         0x60
-#define GMCR_GAPR1_1000         0x2C
-#define GMCR_GAPR2_1000         0x40
-#define GMCR_GAPBB_100          0x70
-#define GMCR_GAPR1_100          0x2C
-#define GMCR_GAPR2_100          0x40
-#define XCR_RESET               0x80000000
-#define XCR_XMTEN               0x40000000
-#define XCR_PAUSEEN             0x20000000
-#define XCR_LOADRNG             0x10000000
-#define RCR_RESET               0x80000000
-#define RCR_RCVEN               0x40000000
-#define RCR_RCVALL              0x20000000
-#define RCR_RCVBAD              0x10000000
-#define RCR_CTLEN               0x08000000
-#define RCR_ADDRAEN             0x02000000
-#define GXCR_RESET              0x80000000
-#define GXCR_XMTEN              0x40000000
-#define GXCR_PAUSEEN            0x20000000
-#define GRCR_RESET              0x80000000
-#define GRCR_RCVEN              0x40000000
-#define GRCR_RCVALL             0x20000000
-#define GRCR_RCVBAD             0x10000000
-#define GRCR_CTLEN              0x08000000
-#define GRCR_ADDRAEN            0x02000000
-#define GRCR_HASHSIZE_SHIFT     17
-#define GRCR_HASHSIZE           14
+#define MCR_RESET		0x80000000
+#define MCR_CRCEN		0x40000000
+#define MCR_FULLD		0x10000000
+#define MCR_PAD			0x02000000
+#define MCR_RETRYLATE		0x01000000
+#define MCR_BOL_SHIFT		21
+#define MCR_IPG1_SHIFT		14
+#define MCR_IPG2_SHIFT		7
+#define MCR_IPG3_SHIFT		0
+#define GMCR_RESET		0x80000000
+#define GMCR_GBIT		0x20000000
+#define GMCR_FULLD		0x10000000
+#define GMCR_GAPBB_SHIFT	14
+#define GMCR_GAPR1_SHIFT	7
+#define GMCR_GAPR2_SHIFT	0
+#define GMCR_GAPBB_1000		0x60
+#define GMCR_GAPR1_1000		0x2C
+#define GMCR_GAPR2_1000		0x40
+#define GMCR_GAPBB_100		0x70
+#define GMCR_GAPR1_100		0x2C
+#define GMCR_GAPR2_100		0x40
+#define XCR_RESET		0x80000000
+#define XCR_XMTEN		0x40000000
+#define XCR_PAUSEEN		0x20000000
+#define XCR_LOADRNG		0x10000000
+#define RCR_RESET		0x80000000
+#define RCR_RCVEN		0x40000000
+#define RCR_RCVALL		0x20000000
+#define RCR_RCVBAD		0x10000000
+#define RCR_CTLEN		0x08000000
+#define RCR_ADDRAEN		0x02000000
+#define GXCR_RESET		0x80000000
+#define GXCR_XMTEN		0x40000000
+#define GXCR_PAUSEEN		0x20000000
+#define GRCR_RESET		0x80000000
+#define GRCR_RCVEN		0x40000000
+#define GRCR_RCVALL		0x20000000
+#define GRCR_RCVBAD		0x10000000
+#define GRCR_CTLEN		0x08000000
+#define GRCR_ADDRAEN		0x02000000
+#define GRCR_HASHSIZE_SHIFT	17
+#define GRCR_HASHSIZE		14
 
-#define SLIC_EEPROM_ID        0xA5A5
-#define SLIC_SRAM_SIZE2GB     (64 * 1024)
-#define SLIC_SRAM_SIZE1GB     (32 * 1024)
-#define SLIC_HOSTID_DEFAULT   0xFFFF      /* uninitialized hostid */
-#define SLIC_NBR_MACS         4
-
-#ifndef FALSE
-#define FALSE  0
-#else
-#undef  FALSE
-#define FALSE  0
-#endif
-
-#ifndef TRUE
-#define TRUE   1
-#else
-#undef  TRUE
-#define TRUE   1
-#endif
+#define SLIC_EEPROM_ID		0xA5A5
+#define SLIC_SRAM_SIZE2GB	(64 * 1024)
+#define SLIC_SRAM_SIZE1GB	(32 * 1024)
+#define SLIC_HOSTID_DEFAULT	0xFFFF		/* uninitialized hostid */
+#define SLIC_NBR_MACS		4
 
 struct slic_rcvbuf {
-    unsigned char     pad1[6];
-    ushort    pad2;
-    u32   pad3;
-    u32   pad4;
-    u32   buffer;
-    u32   length;
-    u32   status;
-    u32   pad5;
-    ushort    pad6;
-    unsigned char     data[SLIC_RCVBUF_DATASIZE];
+	u8 pad1[6];
+	u16 pad2;
+	u32 pad3;
+	u32 pad4;
+	u32 buffer;
+	u32 length;
+	u32 status;
+	u32 pad5;
+	u16 pad6;
+	u8 data[SLIC_RCVBUF_DATASIZE];
 };
 
- struct slic_hddr_wds {
-  union {
-    struct {
-	u32    frame_status;
-	u32    frame_status_b;
-	u32    time_stamp;
-	u32    checksum;
-    } hdrs_14port;
-    struct {
-	u32    frame_status;
-	ushort     ByteCnt;
-	ushort     TpChksum;
-	ushort     CtxHash;
-	ushort     MacHash;
-	u32    BufLnk;
-    } hdrs_gbit;
-  } u0;
+struct slic_hddr_wds {
+	union {
+		struct {
+			u32 frame_status;
+			u32 frame_status_b;
+			u32 time_stamp;
+			u32 checksum;
+		} hdrs_14port;
+		struct {
+			u32 frame_status;
+			u16 ByteCnt;
+			u16 TpChksum;
+			u16 CtxHash;
+			u16 MacHash;
+			u32 BufLnk;
+		} hdrs_gbit;
+	} u0;
 };
 
-#define frame_status14        u0.hdrs_14port.frame_status
-#define frame_status_b14      u0.hdrs_14port.frame_status_b
-#define frame_statusGB        u0.hdrs_gbit.frame_status
+#define frame_status14		u0.hdrs_14port.frame_status
+#define frame_status_b14	u0.hdrs_14port.frame_status_b
+#define frame_statusGB		u0.hdrs_gbit.frame_status
 
 struct slic_host64sg {
-	u32        paddrl;
-	u32        paddrh;
-	u32        length;
+	u32 paddrl;
+	u32 paddrh;
+	u32 length;
 };
 
 struct slic_host64_cmd {
-    u32       hosthandle;
-    u32       RSVD;
-    unsigned char         command;
-    unsigned char         flags;
-    union {
-	ushort          rsv1;
-	ushort          rsv2;
-    } u0;
-    union {
-	struct {
-		u32            totlen;
-		struct slic_host64sg    bufs[SLIC_MAX64_BCNT];
-	} slic_buffers;
-    } u;
+	u32 hosthandle;
+	u32 RSVD;
+	u8 command;
+	u8 flags;
+	union {
+		u16 rsv1;
+		u16 rsv2;
+	} u0;
+	union {
+		struct {
+			u32 totlen;
+			struct slic_host64sg bufs[SLIC_MAX64_BCNT];
+		} slic_buffers;
+	} u;
 };
 
 struct slic_rspbuf {
-    u32   hosthandle;
-    u32   pad0;
-    u32   pad1;
-    u32   status;
-    u32   pad2[4];
-
+	u32 hosthandle;
+	u32 pad0;
+	u32 pad1;
+	u32 status;
+	u32 pad2[4];
 };
 
 struct slic_regs {
-	u32	slic_reset;		/* Reset Register */
+	u32	slic_reset;	/* Reset Register */
 	u32	pad0;
 
-	u32	slic_icr;		/* Interrupt Control Register */
+	u32	slic_icr;	/* Interrupt Control Register */
 	u32	pad2;
 #define SLIC_ICR		0x0008
 
-	u32	slic_isp;		/* Interrupt status pointer */
+	u32	slic_isp;	/* Interrupt status pointer */
 	u32	pad1;
 #define SLIC_ISP		0x0010
 
-    u32	slic_isr;		/* Interrupt status */
+	u32	slic_isr;	/* Interrupt status */
 	u32	pad3;
 #define SLIC_ISR		0x0018
 
-    u32	slic_hbar;		/* Header buffer address reg */
-	u32		pad4;
+	u32	slic_hbar;	/* Header buffer address reg */
+	u32	pad4;
 	/* 31-8 - phy addr of set of contiguous hdr buffers
 	    7-0 - number of buffers passed
 	   Buffers are 256 bytes long on 256-byte boundaries. */
 #define SLIC_HBAR		0x0020
 #define SLIC_HBAR_CNT_MSK	0x000000FF
 
-    u32	slic_dbar;	/* Data buffer handle & address reg */
-	u32		pad5;
+	u32	slic_dbar;	/* Data buffer handle & address reg */
+	u32	pad5;
 
 	/* 4 sets of registers; Buffers are 2K bytes long 2 per 4K page. */
 #define SLIC_DBAR		0x0028
 #define SLIC_DBAR_SIZE		2048
 
-    u32	slic_cbar;		 	/* Xmt Cmd buf addr regs.*/
+	u32	slic_cbar;	/* Xmt Cmd buf addr regs.*/
 	/* 1 per XMT interface
 	   31-5 - phy addr of host command buffer
 	    4-0 - length of cmd in multiples of 32 bytes
@@ -343,13 +329,13 @@
 #define SLIC_CBAR_LEN_MSK	0x0000001F
 #define SLIC_CBAR_ALIGN		0x00000020
 
-	u32	slic_wcs;		/* write control store*/
+	u32	slic_wcs;	/* write control store*/
 #define	SLIC_WCS		0x0034
 #define SLIC_WCS_START		0x80000000	/*Start the SLIC (Jump to WCS)*/
 #define SLIC_WCS_COMPARE	0x40000000	/* Compare with value in WCS*/
 
-    u32	slic_rbar;		/* Response buffer address reg.*/
-	u32		pad7;
+	u32	slic_rbar;	/* Response buffer address reg.*/
+	u32	pad7;
 	 /*31-8 - phy addr of set of contiguous response buffers
 	  7-0 - number of buffers passed
 	 Buffers are 32 bytes long on 32-byte boundaries.*/
@@ -357,215 +343,214 @@
 #define SLIC_RBAR_CNT_MSK	0x000000FF
 #define SLIC_RBAR_SIZE		32
 
-	u32	slic_stats;		/* read statistics (UPR) */
-	u32		pad8;
+	u32	slic_stats;	/* read statistics (UPR) */
+	u32	pad8;
 #define	SLIC_RSTAT		0x0040
 
-	u32	slic_rlsr;			/* read link status */
-	u32		pad9;
+	u32	slic_rlsr;	/* read link status */
+	u32	pad9;
 #define SLIC_LSTAT		0x0048
 
-	u32	slic_wmcfg;			/* Write Mac Config */
-	u32		pad10;
+	u32	slic_wmcfg;	/* Write Mac Config */
+	u32	pad10;
 #define	SLIC_WMCFG		0x0050
 
-	u32	slic_wphy;			/* Write phy register */
-	u32		pad11;
+	u32	slic_wphy;	/* Write phy register */
+	u32	pad11;
 #define SLIC_WPHY		0x0058
 
-	u32	slic_rcbar;			/*Rcv Cmd buf addr reg*/
-	u32		pad12;
+	u32	slic_rcbar;	/* Rcv Cmd buf addr reg */
+	u32	pad12;
 #define	SLIC_RCBAR		0x0060
 
-	u32	slic_rconfig;		/* Read SLIC Config*/
-	u32		pad13;
+	u32	slic_rconfig;	/* Read SLIC Config*/
+	u32	pad13;
 #define SLIC_RCONFIG	0x0068
 
-	u32	slic_intagg;		/* Interrupt aggregation time*/
-	u32		pad14;
+	u32	slic_intagg;	/* Interrupt aggregation time */
+	u32	pad14;
 #define SLIC_INTAGG		0x0070
 
-	u32	slic_wxcfg;		/* Write XMIT config reg*/
-	u32		pad16;
+	u32	slic_wxcfg;	/* Write XMIT config reg*/
+	u32	pad16;
 #define	SLIC_WXCFG		0x0078
 
-	u32	slic_wrcfg;		/* Write RCV config reg*/
-	u32		pad17;
+	u32	slic_wrcfg;	/* Write RCV config reg*/
+	u32	pad17;
 #define	SLIC_WRCFG		0x0080
 
-	u32	slic_wraddral;		/* Write rcv addr a low*/
-	u32		pad18;
+	u32	slic_wraddral;	/* Write rcv addr a low*/
+	u32	pad18;
 #define	SLIC_WRADDRAL	0x0088
 
-	u32	slic_wraddrah;		/* Write rcv addr a high*/
-	u32		pad19;
+	u32	slic_wraddrah;	/* Write rcv addr a high*/
+	u32	pad19;
 #define	SLIC_WRADDRAH	0x0090
 
-	u32	slic_wraddrbl;		/* Write rcv addr b low*/
-	u32		pad20;
+	u32	slic_wraddrbl;	/* Write rcv addr b low*/
+	u32	pad20;
 #define	SLIC_WRADDRBL	0x0098
 
-	u32	slic_wraddrbh;		/* Write rcv addr b high*/
+	u32	slic_wraddrbh;	/* Write rcv addr b high*/
 	u32		pad21;
 #define	SLIC_WRADDRBH	0x00a0
 
-	u32	slic_mcastlow;		/* Low bits of mcast mask*/
+	u32	slic_mcastlow;	/* Low bits of mcast mask*/
 	u32		pad22;
 #define	SLIC_MCASTLOW	0x00a8
 
-	u32	slic_mcasthigh;		/* High bits of mcast mask*/
+	u32	slic_mcasthigh;	/* High bits of mcast mask*/
 	u32		pad23;
 #define	SLIC_MCASTHIGH	0x00b0
 
-	u32	slic_ping;			/* Ping the card*/
-	u32		pad24;
+	u32	slic_ping;	/* Ping the card*/
+	u32	pad24;
 #define SLIC_PING		0x00b8
 
-	u32	slic_dump_cmd;		/* Dump command */
-	u32		pad25;
+	u32	slic_dump_cmd;	/* Dump command */
+	u32	pad25;
 #define SLIC_DUMP_CMD	0x00c0
 
-	u32	slic_dump_data;		/* Dump data pointer */
-	u32		pad26;
+	u32	slic_dump_data;	/* Dump data pointer */
+	u32	pad26;
 #define SLIC_DUMP_DATA	0x00c8
 
 	u32	slic_pcistatus;	/* Read card's pci_status register */
-	u32		pad27;
+	u32	pad27;
 #define	SLIC_PCISTATUS	0x00d0
 
-	u32	slic_wrhostid;		/* Write hostid field */
+	u32	slic_wrhostid;	/* Write hostid field */
 	u32		pad28;
 #define SLIC_WRHOSTID		 0x00d8
 #define SLIC_RDHOSTID_1GB	 0x1554
 #define SLIC_RDHOSTID_2GB	 0x1554
 
 	u32	slic_low_power;	/* Put card in a low power state */
-	u32		pad29;
+	u32	pad29;
 #define SLIC_LOW_POWER	0x00e0
 
 	u32	slic_quiesce;	/* force slic into quiescent state
-					 before soft reset */
-	u32		pad30;
+				   before soft reset */
+	u32	pad30;
 #define SLIC_QUIESCE	0x00e8
 
-	u32	slic_reset_iface;	/* reset interface queues */
-	u32		pad31;
+	u32	slic_reset_iface;/* reset interface queues */
+	u32	pad31;
 #define SLIC_RESET_IFACE 0x00f0
 
-    u32	slic_addr_upper;	/* Bits 63-32 for host i/f addrs */
-	u32		pad32;
+	u32	slic_addr_upper;/* Bits 63-32 for host i/f addrs */
+	u32	pad32;
 #define SLIC_ADDR_UPPER	0x00f8 /*Register is only written when it has changed*/
 
-    u32	slic_hbar64;		/* 64 bit Header buffer address reg */
-	u32		pad33;
+	u32	slic_hbar64;	/* 64 bit Header buffer address reg */
+	u32	pad33;
 #define SLIC_HBAR64		0x0100
 
-    u32	slic_dbar64;	/* 64 bit Data buffer handle & address reg */
-	u32		pad34;
+	u32	slic_dbar64;	/* 64 bit Data buffer handle & address reg */
+	u32	pad34;
 #define SLIC_DBAR64		0x0108
 
-    u32	slic_cbar64;	 	/* 64 bit Xmt Cmd buf addr regs. */
-	u32		pad35;
+	u32	slic_cbar64; 	/* 64 bit Xmt Cmd buf addr regs. */
+	u32	pad35;
 #define SLIC_CBAR64		0x0110
 
-    u32	slic_rbar64;		/* 64 bit Response buffer address reg.*/
-	u32		pad36;
+	u32	slic_rbar64;	/* 64 bit Response buffer address reg.*/
+	u32	pad36;
 #define SLIC_RBAR64		0x0118
 
-	u32	slic_rcbar64;		/* 64 bit Rcv Cmd buf addr reg*/
-	u32		pad37;
+	u32	slic_rcbar64;	/* 64 bit Rcv Cmd buf addr reg*/
+	u32	pad37;
 #define	SLIC_RCBAR64	0x0120
 
-	u32	slic_stats64;		/*read statistics (64 bit UPR)*/
-	u32		pad38;
+	u32	slic_stats64;	/* read statistics (64 bit UPR) */
+	u32	pad38;
 #define	SLIC_RSTAT64	0x0128
 
 	u32	slic_rcv_wcs;	/*Download Gigabit RCV sequencer ucode*/
-	u32		pad39;
+	u32	pad39;
 #define SLIC_RCV_WCS	0x0130
 #define SLIC_RCVWCS_BEGIN	0x40000000
 #define SLIC_RCVWCS_FINISH	0x80000000
 
-	u32	slic_wrvlanid;		/* Write VlanId field */
-	u32		pad40;
+	u32	slic_wrvlanid;	/* Write VlanId field */
+	u32	pad40;
 #define SLIC_WRVLANID	0x0138
 
-	u32	slic_read_xf_info;  /* Read Transformer info */
-	u32		pad41;
+	u32	slic_read_xf_info;	/* Read Transformer info */
+	u32	pad41;
 #define SLIC_READ_XF_INFO 	0x0140
 
-	u32	slic_write_xf_info; /* Write Transformer info */
-	u32		pad42;
+	u32	slic_write_xf_info;	/* Write Transformer info */
+	u32	pad42;
 #define SLIC_WRITE_XF_INFO 	0x0148
 
-	u32	RSVD1;              /* TOE Only */
-	u32		pad43;
+	u32	RSVD1;		/* TOE Only */
+	u32	pad43;
 
-	u32	RSVD2; 	            /* TOE Only */
-	u32		pad44;
+	u32	RSVD2;		/* TOE Only */
+	u32	pad44;
 
-	u32	RSVD3;              /* TOE Only */
-	u32		pad45;
+	u32	RSVD3;		/* TOE Only */
+	u32	pad45;
 
-	u32	RSVD4;              /* TOE Only */
-	u32		pad46;
+	u32	RSVD4;		/* TOE Only */
+	u32	pad46;
 
 	u32	slic_ticks_per_sec; /* Write card ticks per second */
-	u32		pad47;
+	u32	pad47;
 #define SLIC_TICKS_PER_SEC	0x0170
-
 };
 
 enum UPR_REQUEST {
-    SLIC_UPR_STATS,
-    SLIC_UPR_RLSR,
-    SLIC_UPR_WCFG,
-    SLIC_UPR_RCONFIG,
-    SLIC_UPR_RPHY,
-    SLIC_UPR_ENLB,
-    SLIC_UPR_ENCT,
-    SLIC_UPR_PDWN,
-    SLIC_UPR_PING,
-    SLIC_UPR_DUMP,
+	SLIC_UPR_STATS,
+	SLIC_UPR_RLSR,
+	SLIC_UPR_WCFG,
+	SLIC_UPR_RCONFIG,
+	SLIC_UPR_RPHY,
+	SLIC_UPR_ENLB,
+	SLIC_UPR_ENCT,
+	SLIC_UPR_PDWN,
+	SLIC_UPR_PING,
+	SLIC_UPR_DUMP,
 };
 
 struct inicpm_wakepattern {
-    u32    patternlength;
-    unsigned char      pattern[SLIC_PM_PATTERNSIZE];
-    unsigned char      mask[SLIC_PM_PATTERNSIZE];
+	u32 patternlength;
+	u8 pattern[SLIC_PM_PATTERNSIZE];
+	u8 mask[SLIC_PM_PATTERNSIZE];
 };
 
 struct inicpm_state {
-    u32                 powercaps;
-    u32                 powerstate;
-    u32                 wake_linkstatus;
-    u32                 wake_magicpacket;
-    u32                 wake_framepattern;
-    struct inicpm_wakepattern    wakepattern[SLIC_PM_MAXPATTERNS];
+	u32 powercaps;
+	u32 powerstate;
+	u32 wake_linkstatus;
+	u32 wake_magicpacket;
+	u32 wake_framepattern;
+	struct inicpm_wakepattern wakepattern[SLIC_PM_MAXPATTERNS];
 };
 
 struct slicpm_packet_pattern {
-    u32     priority;
-    u32     reserved;
-    u32     masksize;
-    u32     patternoffset;
-    u32     patternsize;
-    u32     patternflags;
+	u32 priority;
+	u32 reserved;
+	u32 masksize;
+	u32 patternoffset;
+	u32 patternsize;
+	u32 patternflags;
 };
 
 enum slicpm_power_state {
-    slicpm_state_unspecified = 0,
-    slicpm_state_d0,
-    slicpm_state_d1,
-    slicpm_state_d2,
-    slicpm_state_d3,
-    slicpm_state_maximum
+	slicpm_state_unspecified = 0,
+	slicpm_state_d0,
+	slicpm_state_d1,
+	slicpm_state_d2,
+	slicpm_state_d3,
+	slicpm_state_maximum
 };
 
 struct slicpm_wakeup_capabilities {
-    enum slicpm_power_state  min_magic_packet_wakeup;
-    enum slicpm_power_state  min_pattern_wakeup;
-    enum slicpm_power_state  min_link_change_wakeup;
+	enum slicpm_power_state min_magic_packet_wakeup;
+	enum slicpm_power_state min_pattern_wakeup;
+	enum slicpm_power_state min_link_change_wakeup;
 };
 
 struct slic_pnp_capabilities {
@@ -612,136 +597,135 @@
 };
 
 struct slic_stats {
-    union {
-	struct {
-		struct xmt_stats  xmt100;
-		struct rcv_stats  rcv100;
-	} stats_100;
-	struct {
-		struct xmt_statsgb     xmtGB;
-		struct rcv_statsgb     rcvGB;
-	} stats_GB;
-    } u;
+	union {
+		struct {
+			struct xmt_stats xmt100;
+			struct rcv_stats rcv100;
+		} stats_100;
+		struct {
+			struct xmt_statsgb xmtGB;
+			struct rcv_statsgb rcvGB;
+		} stats_GB;
+	} u;
 };
 
-#define xmit_tcp_segs100           u.stats_100.xmt100.xmit_tcp_segs
-#define xmit_tcp_bytes100          u.stats_100.xmt100.xmit_tcp_bytes
-#define xmit_bytes100              u.stats_100.xmt100.xmit_bytes
-#define xmit_collisions100         u.stats_100.xmt100.xmit_collisions
-#define xmit_unicasts100           u.stats_100.xmt100.xmit_unicasts
-#define xmit_other_error100        u.stats_100.xmt100.xmit_other_error
-#define xmit_excess_collisions100  u.stats_100.xmt100.xmit_excess_collisions
-#define rcv_tcp_segs100            u.stats_100.rcv100.rcv_tcp_segs
-#define rcv_tcp_bytes100           u.stats_100.rcv100.rcv_tcp_bytes
-#define rcv_bytes100               u.stats_100.rcv100.rcv_bytes
-#define rcv_unicasts100            u.stats_100.rcv100.rcv_unicasts
-#define rcv_other_error100         u.stats_100.rcv100.rcv_other_error
-#define rcv_drops100               u.stats_100.rcv100.rcv_drops
-#define xmit_tcp_segs_gb           u.stats_GB.xmtGB.xmit_tcp_segs
-#define xmit_tcp_bytes_gb          u.stats_GB.xmtGB.xmit_tcp_bytes
-#define xmit_bytes_gb              u.stats_GB.xmtGB.xmit_bytes
-#define xmit_collisions_gb         u.stats_GB.xmtGB.xmit_collisions
-#define xmit_unicasts_gb           u.stats_GB.xmtGB.xmit_unicasts
-#define xmit_other_error_gb        u.stats_GB.xmtGB.xmit_other_error
-#define xmit_excess_collisions_gb  u.stats_GB.xmtGB.xmit_excess_collisions
+#define xmit_tcp_segs100		u.stats_100.xmt100.xmit_tcp_segs
+#define xmit_tcp_bytes100		u.stats_100.xmt100.xmit_tcp_bytes
+#define xmit_bytes100			u.stats_100.xmt100.xmit_bytes
+#define xmit_collisions100		u.stats_100.xmt100.xmit_collisions
+#define xmit_unicasts100		u.stats_100.xmt100.xmit_unicasts
+#define xmit_other_error100		u.stats_100.xmt100.xmit_other_error
+#define xmit_excess_collisions100	u.stats_100.xmt100.xmit_excess_collisions
+#define rcv_tcp_segs100			u.stats_100.rcv100.rcv_tcp_segs
+#define rcv_tcp_bytes100		u.stats_100.rcv100.rcv_tcp_bytes
+#define rcv_bytes100			u.stats_100.rcv100.rcv_bytes
+#define rcv_unicasts100			u.stats_100.rcv100.rcv_unicasts
+#define rcv_other_error100		u.stats_100.rcv100.rcv_other_error
+#define rcv_drops100			u.stats_100.rcv100.rcv_drops
+#define xmit_tcp_segs_gb		u.stats_GB.xmtGB.xmit_tcp_segs
+#define xmit_tcp_bytes_gb		u.stats_GB.xmtGB.xmit_tcp_bytes
+#define xmit_bytes_gb			u.stats_GB.xmtGB.xmit_bytes
+#define xmit_collisions_gb		u.stats_GB.xmtGB.xmit_collisions
+#define xmit_unicasts_gb		u.stats_GB.xmtGB.xmit_unicasts
+#define xmit_other_error_gb		u.stats_GB.xmtGB.xmit_other_error
+#define xmit_excess_collisions_gb	u.stats_GB.xmtGB.xmit_excess_collisions
 
-#define rcv_tcp_segs_gb            u.stats_GB.rcvGB.rcv_tcp_segs
-#define rcv_tcp_bytes_gb           u.stats_GB.rcvGB.rcv_tcp_bytes
-#define rcv_bytes_gb               u.stats_GB.rcvGB.rcv_bytes
-#define rcv_unicasts_gb            u.stats_GB.rcvGB.rcv_unicasts
-#define rcv_other_error_gb         u.stats_GB.rcvGB.rcv_other_error
-#define rcv_drops_gb               u.stats_GB.rcvGB.rcv_drops
+#define rcv_tcp_segs_gb			u.stats_GB.rcvGB.rcv_tcp_segs
+#define rcv_tcp_bytes_gb		u.stats_GB.rcvGB.rcv_tcp_bytes
+#define rcv_bytes_gb			u.stats_GB.rcvGB.rcv_bytes
+#define rcv_unicasts_gb			u.stats_GB.rcvGB.rcv_unicasts
+#define rcv_other_error_gb		u.stats_GB.rcvGB.rcv_other_error
+#define rcv_drops_gb			u.stats_GB.rcvGB.rcv_drops
 
 struct slic_config_mac {
-    unsigned char        macaddrA[6];
+	u8 macaddrA[6];
 };
 
-#define ATK_FRU_FORMAT        0x00
-#define VENDOR1_FRU_FORMAT    0x01
-#define VENDOR2_FRU_FORMAT    0x02
-#define VENDOR3_FRU_FORMAT    0x03
-#define VENDOR4_FRU_FORMAT    0x04
-#define NO_FRU_FORMAT         0xFF
+#define ATK_FRU_FORMAT		0x00
+#define VENDOR1_FRU_FORMAT	0x01
+#define VENDOR2_FRU_FORMAT	0x02
+#define VENDOR3_FRU_FORMAT	0x03
+#define VENDOR4_FRU_FORMAT	0x04
+#define NO_FRU_FORMAT		0xFF
 
 struct atk_fru {
-    unsigned char        assembly[6];
-    unsigned char        revision[2];
-    unsigned char        serial[14];
-    unsigned char        pad[3];
+	u8 assembly[6];
+	u8 revision[2];
+	u8 serial[14];
+	u8 pad[3];
 };
 
 struct vendor1_fru {
-    unsigned char        commodity;
-    unsigned char        assembly[4];
-    unsigned char        revision[2];
-    unsigned char        supplier[2];
-    unsigned char        date[2];
-    unsigned char        sequence[3];
-    unsigned char        pad[13];
+	u8 commodity;
+	u8 assembly[4];
+	u8 revision[2];
+	u8 supplier[2];
+	u8 date[2];
+	u8 sequence[3];
+	u8 pad[13];
 };
 
 struct vendor2_fru {
-    unsigned char        part[8];
-    unsigned char        supplier[5];
-    unsigned char        date[3];
-    unsigned char        sequence[4];
-    unsigned char        pad[7];
+	u8 part[8];
+	u8 supplier[5];
+	u8 date[3];
+	u8 sequence[4];
+	u8 pad[7];
 };
 
 struct vendor3_fru {
-    unsigned char        assembly[6];
-    unsigned char        revision[2];
-    unsigned char        serial[14];
-    unsigned char        pad[3];
+	u8 assembly[6];
+	u8 revision[2];
+	u8 serial[14];
+	u8 pad[3];
 };
 
 struct vendor4_fru {
-    unsigned char        number[8];
-    unsigned char        part[8];
-    unsigned char        version[8];
-    unsigned char        pad[3];
+	u8 number[8];
+	u8 part[8];
+	u8 version[8];
+	u8 pad[3];
 };
 
 union oemfru {
-    struct vendor1_fru   vendor1_fru;
-    struct vendor2_fru   vendor2_fru;
-    struct vendor3_fru   vendor3_fru;
-    struct vendor4_fru   vendor4_fru;
+	struct vendor1_fru vendor1_fru;
+	struct vendor2_fru vendor2_fru;
+	struct vendor3_fru vendor3_fru;
+	struct vendor4_fru vendor4_fru;
 };
 
 /*
-   SLIC EEPROM structure for Mojave
-*/
+ * SLIC EEPROM structure for Mojave
+ */
 struct slic_eeprom {
-	ushort		Id;		/* 00 EEPROM/FLASH Magic code 'A5A5'*/
-	ushort		EecodeSize;	/* 01 Size of EEPROM Codes (bytes * 4)*/
-	ushort		FlashSize;	/* 02 Flash size */
-	ushort		EepromSize;	/* 03 EEPROM Size */
-	ushort		VendorId;	/* 04 Vendor ID */
-	ushort		DeviceId;	/* 05 Device ID */
-	unsigned char		RevisionId;	/* 06 Revision ID */
-	unsigned char		ClassCode[3];	/* 07 Class Code */
-	unsigned char		DbgIntPin;	/* 08 Debug Interrupt pin */
-	unsigned char		NetIntPin0;	/*    Network Interrupt Pin */
-	unsigned char		MinGrant;	/* 09 Minimum grant */
-	unsigned char		MaxLat;		/*    Maximum Latency */
-	ushort		PciStatus;	/* 10 PCI Status */
-	ushort		SubSysVId;	/* 11 Subsystem Vendor Id */
-	ushort		SubSysId;	/* 12 Subsystem ID */
-	ushort		DbgDevId;	/* 13 Debug Device Id */
-	ushort		DramRomFn;	/* 14 Dram/Rom function */
-	ushort		DSize2Pci;	/* 15 DRAM size to PCI (bytes * 64K) */
-	ushort	RSize2Pci;	/* 16 ROM extension size to PCI (bytes * 4k) */
-	unsigned char NetIntPin1;/* 17 Network Interface Pin 1
+	u16 Id;			/* 00 EEPROM/FLASH Magic code 'A5A5'*/
+	u16 EecodeSize;		/* 01 Size of EEPROM Codes (bytes * 4)*/
+	u16 FlashSize;		/* 02 Flash size */
+	u16 EepromSize;		/* 03 EEPROM Size */
+	u16 VendorId;		/* 04 Vendor ID */
+	u16 DeviceId;		/* 05 Device ID */
+	u8 RevisionId;		/* 06 Revision ID */
+	u8 ClassCode[3];	/* 07 Class Code */
+	u8 DbgIntPin;		/* 08 Debug Interrupt pin */
+	u8 NetIntPin0;		/*    Network Interrupt Pin */
+	u8 MinGrant;		/* 09 Minimum grant */
+	u8 MaxLat;		/*    Maximum Latency */
+	u16 PciStatus;		/* 10 PCI Status */
+	u16 SubSysVId;		/* 11 Subsystem Vendor Id */
+	u16 SubSysId;		/* 12 Subsystem ID */
+	u16 DbgDevId;		/* 13 Debug Device Id */
+	u16 DramRomFn;		/* 14 Dram/Rom function */
+	u16 DSize2Pci;		/* 15 DRAM size to PCI (bytes * 64K) */
+	u16 RSize2Pci;		/* 16 ROM extension size to PCI (bytes * 4k) */
+	u8 NetIntPin1;		/* 17 Network Interface Pin 1
 				    (simba/leone only) */
-	unsigned char NetIntPin2; /*Network Interface Pin 2 (simba/leone only)*/
+	u8 NetIntPin2;		/* Network Interface Pin 2 (simba/leone only)*/
 	union {
-		unsigned char NetIntPin3;/*18 Network Interface Pin 3
-					   (simba only)*/
-		unsigned char FreeTime;/*FreeTime setting (leone/mojave only) */
+		u8 NetIntPin3;	/* 18 Network Interface Pin 3 (simba only) */
+		u8 FreeTime;	/* FreeTime setting (leone/mojave only) */
 	} u1;
-	unsigned char	TBIctl;	/*    10-bit interface control (Mojave only) */
-	ushort		DramSize;	/* 19 DRAM size (bytes * 64k) */
+	u8 TBIctl;		/* 10-bit interface control (Mojave only) */
+	u16 DramSize;		/* 19 DRAM size (bytes * 64k) */
 	union {
 		struct {
 			/* Mac Interface Specific portions */
@@ -750,67 +734,64 @@
 		struct {
 			/* use above struct for MAC access */
 			struct slic_config_mac	pad[SLIC_NBR_MACS - 1];
-			ushort		DeviceId2;	/* Device ID for 2nd
-								PCI function */
-			unsigned char	IntPin2;	/* Interrupt pin for
-							   2nd PCI function */
-			unsigned char	ClassCode2[3];	/* Class Code for 2nd
-								PCI function */
+			u16 DeviceId2;	/* Device ID for 2nd PCI function */
+			u8 IntPin2;	/* Interrupt pin for 2nd PCI function */
+			u8 ClassCode2[3]; /* Class Code for 2nd PCI function */
 		} mojave;	/* 2nd function access for gigabit board */
 	} u2;
-	ushort		CfgByte6;	/* Config Byte 6 */
-	ushort		PMECapab;	/* Power Mgment capabilities */
-	ushort		NwClkCtrls;	/* NetworkClockControls */
-	unsigned char	FruFormat;	/* Alacritech FRU format type */
-	struct atk_fru   AtkFru;	/* Alacritech FRU information */
-	unsigned char	OemFruFormat;	/* optional OEM FRU format type */
-	union oemfru    OemFru;         /* optional OEM FRU information */
-	unsigned char	Pad[4];	/* Pad to 128 bytes - includes 2 cksum bytes
-				 *(if OEM FRU info exists) and two unusable
+	u16 CfgByte6;		/* Config Byte 6 */
+	u16 PMECapab;		/* Power Mgment capabilities */
+	u16 NwClkCtrls;		/* NetworkClockControls */
+	u8 FruFormat;		/* Alacritech FRU format type */
+	struct atk_fru  AtkFru;	/* Alacritech FRU information */
+	u8 OemFruFormat;	/* optional OEM FRU format type */
+	union oemfru OemFru;	/* optional OEM FRU information */
+	u8	Pad[4];		/* Pad to 128 bytes - includes 2 cksum bytes
+				 * (if OEM FRU info exists) and two unusable
 				 * bytes at the end */
 };
 
 /* SLIC EEPROM structure for Oasis */
 struct oslic_eeprom {
-	ushort		Id;		/* 00 EEPROM/FLASH Magic code 'A5A5' */
-	ushort		EecodeSize;	/* 01 Size of EEPROM Codes (bytes * 4)*/
-	ushort		FlashConfig0;	/* 02 Flash Config for SPI device 0 */
-	ushort		FlashConfig1;	/* 03 Flash Config for SPI device 1 */
-	ushort		VendorId;	/* 04 Vendor ID */
-	ushort		DeviceId;	/* 05 Device ID (function 0) */
-	unsigned char	RevisionId;	/* 06 Revision ID */
-	unsigned char	ClassCode[3];	/* 07 Class Code for PCI function 0 */
-	unsigned char	IntPin1;	/* 08 Interrupt pin for PCI function 1*/
-	unsigned char	ClassCode2[3];	/* 09 Class Code for PCI function 1 */
-	unsigned char	IntPin2;	/* 10 Interrupt pin for PCI function 2*/
-	unsigned char	IntPin0;	/*    Interrupt pin for PCI function 0*/
-	unsigned char		MinGrant;	/* 11 Minimum grant */
-	unsigned char		MaxLat;		/*    Maximum Latency */
-	ushort		SubSysVId;	/* 12 Subsystem Vendor Id */
-	ushort		SubSysId;	/* 13 Subsystem ID */
-	ushort		FlashSize;	/* 14 Flash size (bytes / 4K) */
-	ushort		DSize2Pci;	/* 15 DRAM size to PCI (bytes / 64K) */
-	ushort		RSize2Pci;	/* 16 Flash (ROM extension) size to
-						PCI (bytes / 4K) */
-	ushort		DeviceId1;	/* 17 Device Id (function 1) */
-	ushort		DeviceId2;	/* 18 Device Id (function 2) */
-	ushort		CfgByte6;	/* 19 Device Status Config Bytes 6-7 */
-	ushort		PMECapab;	/* 20 Power Mgment capabilities */
-	unsigned char		MSICapab;	/* 21 MSI capabilities */
-	unsigned char		ClockDivider;	/*    Clock divider */
-	ushort		PciStatusLow;	/* 22 PCI Status bits 15:0 */
-	ushort		PciStatusHigh;	/* 23 PCI Status bits 31:16 */
-	ushort		DramConfigLow;	/* 24 DRAM Configuration bits 15:0 */
-	ushort		DramConfigHigh;	/* 25 DRAM Configuration bits 31:16 */
-	ushort		DramSize;	/* 26 DRAM size (bytes / 64K) */
-	ushort		GpioTbiCtl;/* 27 GPIO/TBI controls for functions 1/0 */
-	ushort		EepromSize;		/* 28 EEPROM Size */
+	u16 Id;			/* 00 EEPROM/FLASH Magic code 'A5A5' */
+	u16 EecodeSize;		/* 01 Size of EEPROM Codes (bytes * 4)*/
+	u16 FlashConfig0;	/* 02 Flash Config for SPI device 0 */
+	u16 FlashConfig1;	/* 03 Flash Config for SPI device 1 */
+	u16 VendorId;		/* 04 Vendor ID */
+	u16 DeviceId;		/* 05 Device ID (function 0) */
+	u8 RevisionId;		/* 06 Revision ID */
+	u8 ClassCode[3];	/* 07 Class Code for PCI function 0 */
+	u8 IntPin1;		/* 08 Interrupt pin for PCI function 1*/
+	u8 ClassCode2[3];	/* 09 Class Code for PCI function 1 */
+	u8 IntPin2;		/* 10 Interrupt pin for PCI function 2*/
+	u8 IntPin0;		/*    Interrupt pin for PCI function 0*/
+	u8 MinGrant;		/* 11 Minimum grant */
+	u8 MaxLat;		/*    Maximum Latency */
+	u16 SubSysVId;		/* 12 Subsystem Vendor Id */
+	u16 SubSysId;		/* 13 Subsystem ID */
+	u16 FlashSize;		/* 14 Flash size (bytes / 4K) */
+	u16 DSize2Pci;		/* 15 DRAM size to PCI (bytes / 64K) */
+	u16 RSize2Pci;		/* 16 Flash (ROM extension) size to PCI
+					(bytes / 4K) */
+	u16 DeviceId1;		/* 17 Device Id (function 1) */
+	u16 DeviceId2;		/* 18 Device Id (function 2) */
+	u16 CfgByte6;		/* 19 Device Status Config Bytes 6-7 */
+	u16 PMECapab;		/* 20 Power Mgment capabilities */
+	u8 MSICapab;		/* 21 MSI capabilities */
+	u8 ClockDivider;	/*    Clock divider */
+	u16 PciStatusLow;	/* 22 PCI Status bits 15:0 */
+	u16 PciStatusHigh;	/* 23 PCI Status bits 31:16 */
+	u16 DramConfigLow;	/* 24 DRAM Configuration bits 15:0 */
+	u16 DramConfigHigh;	/* 25 DRAM Configuration bits 31:16 */
+	u16 DramSize;		/* 26 DRAM size (bytes / 64K) */
+	u16 GpioTbiCtl;		/* 27 GPIO/TBI controls for functions 1/0 */
+	u16 EepromSize;		/* 28 EEPROM Size */
 	struct slic_config_mac MacInfo[2];	/* 29 MAC addresses (2 ports) */
-	unsigned char	FruFormat;	/* 35 Alacritech FRU format type */
+	u8 FruFormat;		/* 35 Alacritech FRU format type */
 	struct atk_fru	AtkFru;	/* Alacritech FRU information */
-	unsigned char	OemFruFormat;	/* optional OEM FRU format type */
-	union oemfru    OemFru;         /* optional OEM FRU information */
-	unsigned char	Pad[4];	/* Pad to 128 bytes - includes 2 checksum bytes
+	u8 OemFruFormat;	/* optional OEM FRU format type */
+	union oemfru OemFru;	/* optional OEM FRU information */
+	u8 Pad[4];		/* Pad to 128 bytes - includes 2 checksum bytes
 				 * (if OEM FRU info exists) and two unusable
 				 * bytes at the end
 				 */
@@ -819,24 +800,25 @@
 #define	MAX_EECODE_SIZE	sizeof(struct slic_eeprom)
 #define MIN_EECODE_SIZE	0x62	/* code size without optional OEM FRU stuff */
 
-/* SLIC CONFIG structure
-
- This structure lives in the CARD structure and is valid for all
- board types.  It is filled in from the appropriate EEPROM structure
- by SlicGetConfigData().
-*/
+/*
+ * SLIC CONFIG structure
+ *
+ * This structure lives in the CARD structure and is valid for all board types.
+ * It is filled in from the appropriate EEPROM structure by
+ * SlicGetConfigData()
+ */
 struct slic_config {
 	bool EepromValid;	/* Valid EEPROM flag (checksum good?) */
-	ushort		DramSize;	/* DRAM size (bytes / 64K) */
+	u16 DramSize;		/* DRAM size (bytes / 64K) */
 	struct slic_config_mac MacInfo[SLIC_NBR_MACS]; /* MAC addresses */
-	unsigned char		FruFormat;	/* Alacritech FRU format type */
+	u8 FruFormat;		/* Alacritech FRU format type */
 	struct atk_fru	AtkFru;	/* Alacritech FRU information */
-	unsigned char	OemFruFormat;	/* optional OEM FRU format type */
+	u8 OemFruFormat;	/* optional OEM FRU format type */
 	union {
-		struct vendor1_fru   vendor1_fru;
-		struct vendor2_fru   vendor2_fru;
-		struct vendor3_fru   vendor3_fru;
-		struct vendor4_fru   vendor4_fru;
+		struct vendor1_fru vendor1_fru;
+		struct vendor2_fru vendor2_fru;
+		struct vendor3_fru vendor3_fru;
+		struct vendor4_fru vendor4_fru;
 	} OemFru;
 };
 
diff --git a/drivers/staging/slicoss/slicinc.h b/drivers/staging/slicoss/slicinc.h
deleted file mode 100644
index 71288c4..0000000
--- a/drivers/staging/slicoss/slicinc.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/**************************************************************************
- *
- * Copyright (c) 2000-2002 Alacritech, 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:
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``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 ALACRITECH, INC. 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.
- *
- * The views and conclusions contained in the software and documentation
- * are those of the authors and should not be interpreted as representing
- * official policies, either expressed or implied, of Alacritech, Inc.
- *
- **************************************************************************/
-
-/*
- * FILENAME: slicinc.h
- *
- * This file contains all other include files and prototype definitions
- * for the SLICOSS driver.
- */
-#ifndef _SLIC_INCLUDE_H_
-#define _SLIC_INCLUDE_H_
-
-#include "slic_os.h"
-#include "slicdbg.h"
-#include "slichw.h"
-#include "slic.h"
-
-static int slic_entry_probe(struct pci_dev              *pcidev,
-			const struct pci_device_id  *ent);
-static void slic_entry_remove(struct pci_dev *pcidev);
-
-static void slic_init_driver(void);
-static int  slic_entry_open(struct net_device *dev);
-static int  slic_entry_halt(struct net_device *dev);
-static int  slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static int  slic_xmit_start(struct sk_buff *skb, struct net_device *dev);
-static void slic_xmit_fail(struct adapter    *adapter,
-			struct sk_buff   *skb,
-			void *cmd,
-			u32           skbtype,
-			u32           status);
-static void slic_config_pci(struct pci_dev *pcidev);
-static struct sk_buff *slic_rcvqueue_getnext(struct adapter *adapter);
-
-static inline void slic_reg32_write(void __iomem *reg, u32 value, uint flush);
-static inline void slic_reg64_write(struct adapter *adapter, void __iomem *reg,
-	u32 value, void __iomem *regh, u32 paddrh, uint flush);
-
-#if SLIC_GET_STATS_ENABLED
-static struct net_device_stats *slic_get_stats(struct net_device *dev);
-#endif
-
-static int slic_mac_set_address(struct net_device *dev, void *ptr);
-static void slic_rcv_handler(struct adapter *adapter);
-static void slic_link_event_handler(struct adapter *adapter);
-static void slic_xmit_complete(struct adapter *adapter);
-static void slic_upr_request_complete(struct adapter *adapter, u32 isr);
-static int   slic_rspqueue_init(struct adapter *adapter);
-static int   slic_rspqueue_reset(struct adapter *adapter);
-static void  slic_rspqueue_free(struct adapter *adapter);
-static struct slic_rspbuf *slic_rspqueue_getnext(struct adapter *adapter);
-static void  slic_cmdqmem_init(struct adapter *adapter);
-static void  slic_cmdqmem_free(struct adapter *adapter);
-static u32 *slic_cmdqmem_addpage(struct adapter *adapter);
-static int   slic_cmdq_init(struct adapter *adapter);
-static void  slic_cmdq_free(struct adapter *adapter);
-static void  slic_cmdq_reset(struct adapter *adapter);
-static void  slic_cmdq_addcmdpage(struct adapter *adapter, u32 *page);
-static void  slic_cmdq_getdone(struct adapter *adapter);
-static void  slic_cmdq_putdone_irq(struct adapter *adapter,
-						struct slic_hostcmd *cmd);
-static struct slic_hostcmd *slic_cmdq_getfree(struct adapter *adapter);
-static int   slic_rcvqueue_init(struct adapter *adapter);
-static int   slic_rcvqueue_reset(struct adapter *adapter);
-static int   slic_rcvqueue_fill(struct adapter *adapter);
-static u32 slic_rcvqueue_reinsert(struct adapter *adapter, struct sk_buff *skb);
-static void  slic_rcvqueue_free(struct adapter *adapter);
-static void slic_rcv_handle_error(struct adapter *adapter,
-					struct slic_rcvbuf *rcvbuf);
-static void slic_adapter_set_hwaddr(struct adapter *adapter);
-static int slic_card_init(struct sliccard *card, struct adapter *adapter);
-static void slic_intagg_set(struct adapter *adapter, u32 value);
-static int  slic_card_download(struct adapter *adapter);
-static u32 slic_card_locate(struct adapter *adapter);
-
-static void slic_if_stop_queue(struct adapter *adapter);
-static void slic_if_start_queue(struct adapter *adapter);
-static int  slic_if_init(struct adapter *adapter);
-static int  slic_adapter_allocresources(struct adapter *adapter);
-static void slic_adapter_freeresources(struct adapter *adapter);
-static void slic_link_config(struct adapter *adapter, u32 linkspeed,
-			u32 linkduplex);
-static void slic_unmap_mmio_space(struct adapter *adapter);
-static void slic_card_cleanup(struct sliccard *card);
-static void slic_init_cleanup(struct adapter *adapter);
-static void slic_soft_reset(struct adapter *adapter);
-static bool slic_mac_filter(struct adapter *adapter,
-			struct ether_header *ether_frame);
-static void slic_mac_address_config(struct adapter *adapter);
-static void slic_mac_config(struct adapter *adapter);
-static void slic_mcast_set_mask(struct adapter *adapter);
-static int slic_mcast_add_list(struct adapter *adapter, char *address);
-static unsigned char slic_mcast_get_mac_hash(char *macaddr);
-static void  slic_mcast_set_bit(struct adapter *adapter, char *address);
-static void slic_config_set(struct adapter *adapter, bool linkchange);
-static void slic_config_clear(struct adapter *adapter);
-static void slic_config_get(struct adapter *adapter, u32 config,
-			u32 configh);
-static void slic_timer_load_check(ulong context);
-static void slic_timer_ping(ulong dev);
-static void slic_assert_fail(void);
-static ushort slic_eeprom_cksum(char *m, int len);
-/* upr */
-static void slic_upr_start(struct adapter *adapter);
-static void slic_link_upr_complete(struct adapter *adapter, u32 Isr);
-static int  slic_upr_request(struct adapter    *adapter,
-			u32            upr_request,
-			u32            upr_data,
-			u32            upr_data_h,
-			u32            upr_buffer,
-			u32            upr_buffer_h);
-static int  slic_upr_queue_request(struct adapter      *adapter,
-				u32            upr_request,
-				u32            upr_data,
-				u32            upr_data_h,
-				u32            upr_buffer,
-				u32            upr_buffer_h);
-static void slic_mcast_set_list(struct net_device *dev);
-static void slic_mcast_init_crc32(void);
-
-#if SLIC_DUMP_ENABLED
-static int   slic_dump_thread(void *context);
-static uint  slic_init_dump_thread(struct sliccard *card);
-static unsigned char slic_get_dump_index(char *path);
-static u32 slic_dump_card(struct sliccard *card, bool resume);
-static u32 slic_dump_halt(struct sliccard *card, unsigned char proc);
-static u32 slic_dump_reg(struct sliccard *card, unsigned char proc);
-static u32 slic_dump_data(struct sliccard *card, u32 addr,
-			ushort count, unsigned char desc);
-static u32 slic_dump_queue(struct sliccard *card, u32 buf_phys,
-			u32 buf_physh, u32 queue);
-static u32 slic_dump_load_queue(struct sliccard *card, u32 data,
-				u32 queue);
-static u32 slic_dump_cam(struct sliccard *card, u32 addr,
-			u32 count, unsigned char desc);
-
-static u32 slic_dump_resume(struct sliccard *card, unsigned char proc);
-static u32 slic_dump_send_cmd(struct sliccard *card, u32 cmd_phys,
-				u32 cmd_physh, u32 buf_phys,
-				u32 buf_physh);
-
-#define create_file(x)         STATUS_SUCCESS
-#define write_file(w, x, y, z) STATUS_SUCCESS
-#define close_file(x)          STATUS_SUCCESS
-#define read_file(w, x, y, z)  STATUS_SUCCESS
-#define open_file(x)           STATUS_SUCCESS
-
-/* PAGE_SIZE * 16 */
-#define DUMP_PAGE_SIZE         0xFFFF
-#define DUMP_PAGE_SIZE_HALF    0x7FFE
-#endif
-
-#endif /* _SLIC_INCLUDE_H_ */
diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c
index bf7da8f..953684f 100644
--- a/drivers/staging/slicoss/slicoss.c
+++ b/drivers/staging/slicoss/slicoss.c
@@ -55,19 +55,10 @@
  */
 
 
-#define SLIC_DUMP_ENABLED               0
 #define KLUDGE_FOR_4GB_BOUNDARY         1
 #define DEBUG_MICROCODE                 1
-#define SLIC_PRODUCTION_BUILD	        1
-#define SLIC_FAILURE_RESET	            1
 #define DBG                             1
-#define SLIC_ASSERT_ENABLED		        1
-#define SLIC_GET_STATS_ENABLED			1
-#define SLIC_GET_STATS_TIMER_ENABLED	0
-#define SLIC_PING_TIMER_ENABLED		    1
-#define SLIC_POWER_MANAGEMENT_ENABLED	0
 #define SLIC_INTERRUPT_PROCESS_LIMIT	1
-#define LINUX_FREES_ADAPTER_RESOURCES	1
 #define SLIC_OFFLOAD_IP_CHECKSUM		1
 #define STATS_TIMER_INTERVAL			2
 #define PING_TIMER_INTERVAL			    1
@@ -102,20 +93,73 @@
 #include <asm/unaligned.h>
 
 #include <linux/ethtool.h>
-#define SLIC_ETHTOOL_SUPPORT     1
-
 #include <linux/uaccess.h>
-#include "slicinc.h"
+#include "slichw.h"
+#include "slic.h"
 
-#if SLIC_DUMP_ENABLED
-#include "slicdump.h"
-#endif
+static struct net_device_stats *slic_get_stats(struct net_device *dev);
+static int slic_entry_open(struct net_device *dev);
+static int slic_entry_halt(struct net_device *dev);
+static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static int slic_xmit_start(struct sk_buff *skb, struct net_device *dev);
+static void slic_xmit_fail(struct adapter *adapter, struct sk_buff *skb,
+			   void *cmd, u32 skbtype, u32 status);
+static void slic_config_pci(struct pci_dev *pcidev);
+static struct sk_buff *slic_rcvqueue_getnext(struct adapter *adapter);
+static int slic_mac_set_address(struct net_device *dev, void *ptr);
+static void slic_link_event_handler(struct adapter *adapter);
+static void slic_upr_request_complete(struct adapter *adapter, u32 isr);
+static int slic_rspqueue_init(struct adapter *adapter);
+static void slic_rspqueue_free(struct adapter *adapter);
+static struct slic_rspbuf *slic_rspqueue_getnext(struct adapter *adapter);
+static int slic_cmdq_init(struct adapter *adapter);
+static void slic_cmdq_free(struct adapter *adapter);
+static void slic_cmdq_reset(struct adapter *adapter);
+static void slic_cmdq_addcmdpage(struct adapter *adapter, u32 *page);
+static void slic_cmdq_getdone(struct adapter *adapter);
+static void slic_cmdq_putdone_irq(struct adapter *adapter,
+				  struct slic_hostcmd *cmd);
+static struct slic_hostcmd *slic_cmdq_getfree(struct adapter *adapter);
+static int slic_rcvqueue_init(struct adapter *adapter);
+static int slic_rcvqueue_fill(struct adapter *adapter);
+static u32 slic_rcvqueue_reinsert(struct adapter *adapter, struct sk_buff *skb);
+static void slic_rcvqueue_free(struct adapter *adapter);
+static void slic_adapter_set_hwaddr(struct adapter *adapter);
+static int slic_card_init(struct sliccard *card, struct adapter *adapter);
+static void slic_intagg_set(struct adapter *adapter, u32 value);
+static int slic_card_download(struct adapter *adapter);
+static u32 slic_card_locate(struct adapter *adapter);
+static int slic_if_init(struct adapter *adapter);
+static int slic_adapter_allocresources(struct adapter *adapter);
+static void slic_adapter_freeresources(struct adapter *adapter);
+static void slic_link_config(struct adapter *adapter, u32 linkspeed,
+			     u32 linkduplex);
+static void slic_unmap_mmio_space(struct adapter *adapter);
+static void slic_card_cleanup(struct sliccard *card);
+static void slic_soft_reset(struct adapter *adapter);
+static bool slic_mac_filter(struct adapter *adapter,
+			    struct ether_header *ether_frame);
+static void slic_mac_address_config(struct adapter *adapter);
+static void slic_mac_config(struct adapter *adapter);
+static void slic_mcast_set_mask(struct adapter *adapter);
+static void slic_config_set(struct adapter *adapter, bool linkchange);
+static void slic_config_clear(struct adapter *adapter);
+static void slic_config_get(struct adapter *adapter, u32 config,
+			    u32 configh);
+static void slic_timer_load_check(ulong context);
+static void slic_assert_fail(void);
+static ushort slic_eeprom_cksum(char *m, int len);
+static void slic_upr_start(struct adapter *adapter);
+static void slic_link_upr_complete(struct adapter *adapter, u32 Isr);
+static int  slic_upr_request(struct adapter *adapter, u32 upr_request,
+			     u32 upr_data, u32 upr_data_h, u32 upr_buffer,
+			     u32 upr_buffer_h);
+static void slic_mcast_set_list(struct net_device *dev);
 
-#define SLIC_POWER_MANAGEMENT  0
 
 static uint slic_first_init = 1;
 static char *slic_banner = "Alacritech SLIC Technology(tm) Server "\
-		"and Storage Accelerator (Non-Accelerated)\n";
+		"and Storage Accelerator (Non-Accelerated)";
 
 static char *slic_proc_version = "2.0.351  2006/07/14 12:26:00";
 static char *slic_product_name = "SLIC Technology(tm) Server "\
@@ -129,8 +173,6 @@
 static struct base_driver slic_global = { {}, 0, 0, 0, 1, NULL, NULL };
 static int intagg_delay = 100;
 static u32 dynamic_intagg;
-static int errormsg;
-static int goodmsg;
 static unsigned int rcv_count;
 static struct dentry *slic_debugfs;
 
@@ -164,6 +206,21 @@
 
 MODULE_DEVICE_TABLE(pci, slic_pci_tbl);
 
+#ifdef ASSERT
+#undef ASSERT
+#endif
+
+#ifndef ASSERT
+#define ASSERT(a) do {							\
+	if (!(a)) {							\
+		printk(KERN_ERR "slicoss ASSERT() Failure: function %s"	\
+			"line %d\n", __func__, __LINE__);		\
+		slic_assert_fail();					\
+	}								\
+} while (0)
+#endif
+
+
 #define SLIC_GET_SLIC_HANDLE(_adapter, _pslic_handle)                   \
 {                                                                       \
     spin_lock_irqsave(&_adapter->handle_lock.lock,                      \
@@ -195,17 +252,16 @@
 static void slic_debug_card_create(struct sliccard *card);
 static void slic_debug_card_destroy(struct sliccard *card);
 
-static inline void slic_reg32_write(void __iomem *reg, u32 value, uint flush)
+static inline void slic_reg32_write(void __iomem *reg, u32 value, bool flush)
 {
 	writel(value, reg);
 	if (flush)
 		mb();
 }
 
-static inline void slic_reg64_write(struct adapter *adapter,
-			       void __iomem *reg,
-			       u32 value,
-			       void __iomem *regh, u32 paddrh, uint flush)
+static inline void slic_reg64_write(struct adapter *adapter, void __iomem *reg,
+				    u32 value, void __iomem *regh, u32 paddrh,
+				    bool flush)
 {
 	spin_lock_irqsave(&adapter->bit64reglock.lock,
 				adapter->bit64reglock.flags);
@@ -223,43 +279,12 @@
 static void slic_init_driver(void)
 {
 	if (slic_first_init) {
-		DBG_MSG("slicoss: %s slic_first_init set jiffies[%lx]\n",
-			__func__, jiffies);
 		slic_first_init = 0;
 		spin_lock_init(&slic_global.driver_lock.lock);
 		slic_debug_init();
 	}
 }
 
-static void slic_dbg_macaddrs(struct adapter *adapter)
-{
-	DBG_MSG("  (%s) curr %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
-		adapter->netdev->name, adapter->currmacaddr[0],
-		adapter->currmacaddr[1], adapter->currmacaddr[2],
-		adapter->currmacaddr[3], adapter->currmacaddr[4],
-		adapter->currmacaddr[5]);
-	DBG_MSG("  (%s) mac  %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
-		adapter->netdev->name, adapter->macaddr[0],
-		adapter->macaddr[1], adapter->macaddr[2],
-		adapter->macaddr[3], adapter->macaddr[4], adapter->macaddr[5]);
-	return;
-}
-
-#ifdef DEBUG_REGISTER_TRACE
-static void slic_dbg_register_trace(struct adapter *adapter,
-					struct sliccard *card)
-{
-	uint i;
-
-	DBG_ERROR("Dump Register Write Trace: curr_ix == %d\n", card->debug_ix);
-	for (i = 0; i < 32; i++) {
-		DBG_ERROR("%2d %d %4x %x %x\n",
-			  i, card->reg_type[i], card->reg_offset[i],
-			  card->reg_value[i], card->reg_valueh[i]);
-	}
-}
-#endif
-
 static void slic_init_adapter(struct net_device *netdev,
 			      struct pci_dev *pcidev,
 			      const struct pci_device_id *pci_tbl_entry,
@@ -268,9 +293,7 @@
 	ushort index;
 	struct slic_handle *pslic_handle;
 	struct adapter *adapter = (struct adapter *)netdev_priv(netdev);
-/*
-    DBG_MSG("slicoss: %s (%s)\n    netdev [%p]\n    adapter[%p]\n    "
-	    "pcidev [%p]\n", __func__, netdev->name, netdev, adapter, pcidev);*/
+
 /*	adapter->pcidev = pcidev;*/
 	adapter->vendid = pci_tbl_entry->vendor;
 	adapter->devid = pci_tbl_entry->device;
@@ -310,19 +333,11 @@
 		pslic_handle->next = adapter->pfree_slic_handles;
 		adapter->pfree_slic_handles = pslic_handle;
 	}
-/*
-    DBG_MSG(".........\nix[%d] phandle[%p] pfree[%p] next[%p]\n",
-	index, pslic_handle, adapter->pfree_slic_handles, pslic_handle->next);*/
 	adapter->pshmem = (struct slic_shmem *)
 					pci_alloc_consistent(adapter->pcidev,
 					sizeof(struct slic_shmem),
 					&adapter->
 					phys_shmem);
-/*
-      DBG_MSG("slicoss: %s (%s)\n   pshmem    [%p]\n   phys_shmem[%p]\n"\
-		"slic_regs [%p]\n", __func__, netdev->name, adapter->pshmem,
-		(void *)adapter->phys_shmem, adapter->slic_regs);
-*/
 	ASSERT(adapter->pshmem);
 
 	memset(adapter->pshmem, 0, sizeof(struct slic_shmem));
@@ -335,7 +350,7 @@
 {
 	static int cards_found;
 	static int did_version;
-	int err;
+	int err = -ENODEV;
 	struct net_device *netdev;
 	struct adapter *adapter;
 	void __iomem *memmapped_ioaddr = NULL;
@@ -344,54 +359,36 @@
 	ulong mmio_len = 0;
 	struct sliccard *card = NULL;
 
-	DBG_MSG("slicoss: %s 2.6 VERSION ENTER jiffies[%lx] cpu %d\n",
-		__func__, jiffies, smp_processor_id());
-
 	slic_global.dynamic_intagg = dynamic_intagg;
 
 	err = pci_enable_device(pcidev);
 
-	DBG_MSG("Call pci_enable_device(%p)  status[%x]\n", pcidev, err);
 	if (err)
 		return err;
 
 	if (slic_debug > 0 && did_version++ == 0) {
-		printk(slic_banner);
-		printk(slic_proc_version);
+		printk(KERN_DEBUG "%s\n", slic_banner);
+		printk(KERN_DEBUG "%s\n", slic_proc_version);
 	}
 
 	err = pci_set_dma_mask(pcidev, DMA_64BIT_MASK);
-	if (!err) {
-		DBG_MSG("pci_set_dma_mask(DMA_64BIT_MASK) successful\n");
-	} else {
+	if (err) {
 		err = pci_set_dma_mask(pcidev, DMA_32BIT_MASK);
-		if (err) {
-			DBG_MSG
-			    ("No usable DMA configuration, aborting  err[%x]\n",
-			     err);
-			return err;
-		}
-		DBG_MSG("pci_set_dma_mask(DMA_32BIT_MASK) successful\n");
+		if (err)
+			goto err_out_disable_pci;
 	}
 
-	DBG_MSG("Call pci_request_regions\n");
-
 	err = pci_request_regions(pcidev, DRV_NAME);
-	if (err) {
-		DBG_MSG("pci_request_regions FAILED err[%x]\n", err);
-		return err;
-	}
+	if (err)
+		goto err_out_disable_pci;
 
-	DBG_MSG("call pci_set_master\n");
 	pci_set_master(pcidev);
 
-	DBG_MSG("call alloc_etherdev\n");
 	netdev = alloc_etherdev(sizeof(struct adapter));
 	if (!netdev) {
 		err = -ENOMEM;
 		goto err_out_exit_slic_probe;
 	}
-	DBG_MSG("alloc_etherdev for slic netdev[%p]\n", netdev);
 
 	SET_NETDEV_DEV(netdev, &pcidev->dev);
 
@@ -403,24 +400,15 @@
 	mmio_start = pci_resource_start(pcidev, 0);
 	mmio_len = pci_resource_len(pcidev, 0);
 
-	DBG_MSG("slicoss: call ioremap(mmio_start[%lx], mmio_len[%lx])\n",
-		mmio_start, mmio_len);
 
-/*  memmapped_ioaddr =  (u32)ioremap_nocache(mmio_start, mmio_len);*/
+/*	memmapped_ioaddr =  (u32)ioremap_nocache(mmio_start, mmio_len);*/
 	memmapped_ioaddr = ioremap(mmio_start, mmio_len);
-	DBG_MSG("slicoss: %s MEMMAPPED_IOADDR [%p]\n", __func__,
-		memmapped_ioaddr);
 	if (!memmapped_ioaddr) {
-		DBG_ERROR("%s cannot remap MMIO region %lx @ %lx\n",
-			  __func__, mmio_len, mmio_start);
-		goto err_out_free_mmio_region;
+		dev_err(&pcidev->dev, "cannot remap MMIO region %lx @ %lx\n",
+			mmio_len, mmio_start);
+		goto err_out_free_netdev;
 	}
 
-	DBG_MSG
-	    ("slicoss: %s found Alacritech SLICOSS PCI, MMIO at %p, "\
-	    "start[%lx] len[%lx], IRQ %d.\n",
-	     __func__, memmapped_ioaddr, mmio_start, mmio_len, pcidev->irq);
-
 	slic_config_pci(pcidev);
 
 	slic_init_driver();
@@ -430,7 +418,7 @@
 
 	status = slic_card_locate(adapter);
 	if (status) {
-		DBG_ERROR("%s cannot locate card\n", __func__);
+		dev_err(&pcidev->dev, "cannot locate card\n");
 		goto err_out_free_mmio_region;
 	}
 
@@ -441,22 +429,13 @@
 		adapter->allocated = 1;
 	}
 
-	DBG_MSG("slicoss: %s    card:             %p\n", __func__,
-		adapter->card);
-	DBG_MSG("slicoss: %s    card->adapter[%d] == [%p]\n", __func__,
-		(uint) adapter->port, adapter);
-	DBG_MSG("slicoss: %s    card->adapters_allocated [%d]\n", __func__,
-		card->adapters_allocated);
-	DBG_MSG("slicoss: %s    card->adapters_activated [%d]\n", __func__,
-		card->adapters_activated);
-
 	status = slic_card_init(card, adapter);
 
 	if (status != STATUS_SUCCESS) {
 		card->state = CARD_FAIL;
 		adapter->state = ADAPT_FAIL;
 		adapter->linkstate = LINK_DOWN;
-		DBG_ERROR("slic_card_init FAILED status[%x]\n", status);
+		dev_err(&pcidev->dev, "FAILED status[%x]\n", status);
 	} else {
 		slic_adapter_set_hwaddr(adapter);
 	}
@@ -468,9 +447,7 @@
 	netdev->hard_start_xmit = slic_xmit_start;
 	netdev->do_ioctl = slic_ioctl;
 	netdev->set_mac_address = slic_mac_set_address;
-#if SLIC_GET_STATS_ENABLED
 	netdev->get_stats = slic_get_stats;
-#endif
 	netdev->set_multicast_list = slic_mcast_set_list;
 
 	slic_debug_adapter_create(adapter);
@@ -478,35 +455,25 @@
 	strcpy(netdev->name, "eth%d");
 	err = register_netdev(netdev);
 	if (err) {
-		DBG_ERROR("Cannot register net device, aborting.\n");
+		dev_err(&pcidev->dev, "Cannot register net device, aborting.\n");
 		goto err_out_unmap;
 	}
 
-	DBG_MSG
-	    ("slicoss: addr 0x%lx, irq %d, MAC addr "\
-	     "%02X:%02X:%02X:%02X:%02X:%02X\n",
-	     mmio_start, /*pci_resource_start(pcidev, 0), */ pcidev->irq,
-	     netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
-	     netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]);
-
 	cards_found++;
-	DBG_MSG("slicoss: %s EXIT status[%x] jiffies[%lx] cpu %d\n",
-		__func__, status, jiffies, smp_processor_id());
 
 	return status;
 
 err_out_unmap:
 	iounmap(memmapped_ioaddr);
-
 err_out_free_mmio_region:
 	release_mem_region(mmio_start, mmio_len);
-
+err_out_free_netdev:
+	free_netdev(netdev);
 err_out_exit_slic_probe:
 	pci_release_regions(pcidev);
-	DBG_ERROR("%s EXIT jiffies[%lx] cpu %d\n", __func__, jiffies,
-		  smp_processor_id());
-
-	return -ENODEV;
+err_out_disable_pci:
+	pci_disable_device(pcidev);
+	return err;
 }
 
 static int slic_entry_open(struct net_device *dev)
@@ -518,16 +485,6 @@
 
 	ASSERT(adapter);
 	ASSERT(card);
-	DBG_MSG
-	    ("slicoss: %s adapter->activated[%d] card->adapters[%x] "\
-	     "allocd[%x]\n", __func__, adapter->activated,
-	     card->adapters_activated,
-	     card->adapters_allocated);
-	DBG_MSG
-	    ("slicoss: %s (%s): [jiffies[%lx] cpu %d] dev[%p] adapt[%p] "\
-	     "port[%d] card[%p]\n",
-	     __func__, adapter->netdev->name, jiffies, smp_processor_id(),
-	     adapter->netdev, adapter, adapter->port, card);
 
 	netif_stop_queue(adapter->netdev);
 
@@ -554,29 +511,14 @@
 		}
 		return status;
 	}
-	DBG_MSG("slicoss: %s set card->master[%p] adapter[%p]\n", __func__,
-		card->master, adapter);
 	if (!card->master)
 		card->master = adapter;
-#if SLIC_DUMP_ENABLED
-	if (!(card->dumpthread_running))
-		init_waitqueue_head(&card->dump_wq);
-#endif
 
 	if (locked) {
 		spin_unlock_irqrestore(&slic_global.driver_lock.lock,
 					slic_global.driver_lock.flags);
 		locked = 0;
 	}
-#if SLIC_DUMP_ENABLED
-	if (!(card->dumpthread_running)) {
-		DBG_MSG("attempt to initialize dump thread\n");
-		status = slic_init_dump_thread(card);
-		/*
-		Even if the dump thread fails, we will continue at this point
-		*/
-	}
-#endif
 
 	return STATUS_SUCCESS;
 }
@@ -591,22 +533,15 @@
 	struct mcast_address *mcaddr, *mlist;
 
 	ASSERT(adapter);
-	DBG_MSG("slicoss: %s ENTER dev[%p] adapter[%p]\n", __func__, dev,
-		adapter);
 	slic_adapter_freeresources(adapter);
 	slic_unmap_mmio_space(adapter);
-	DBG_MSG("slicoss: %s unregister_netdev\n", __func__);
 	unregister_netdev(dev);
 
 	mmio_start = pci_resource_start(pcidev, 0);
 	mmio_len = pci_resource_len(pcidev, 0);
 
-	DBG_MSG("slicoss: %s rel_region(0) start[%x] len[%x]\n", __func__,
-		mmio_start, mmio_len);
 	release_mem_region(mmio_start, mmio_len);
 
-	DBG_MSG("slicoss: %s iounmap dev->base_addr[%x]\n", __func__,
-		(uint) dev->base_addr);
 	iounmap((void __iomem *)dev->base_addr);
 	/* free multicast addresses */
 	mlist = adapter->mcastaddrs;
@@ -620,10 +555,6 @@
 	ASSERT(card->adapters_allocated);
 	card->adapters_allocated--;
 	adapter->allocated = 0;
-	DBG_MSG
-	    ("slicoss: %s init[%x] alloc[%x] card[%p] adapter[%p]\n",
-	     __func__, card->adapters_activated, card->adapters_allocated,
-	     card, adapter);
 	if (!card->adapters_allocated) {
 		struct sliccard *curr_card = slic_global.slic_card;
 		if (curr_card == card) {
@@ -638,10 +569,8 @@
 		slic_global.num_slic_cards--;
 		slic_card_cleanup(card);
 	}
-	DBG_MSG("slicoss: %s deallocate device\n", __func__);
 	kfree(dev);
 	pci_release_regions(pcidev);
-	DBG_MSG("slicoss: %s EXIT\n", __func__);
 }
 
 static int slic_entry_halt(struct net_device *dev)
@@ -653,75 +582,35 @@
 	spin_lock_irqsave(&slic_global.driver_lock.lock,
 				slic_global.driver_lock.flags);
 	ASSERT(card);
-	DBG_MSG("slicoss: %s (%s) ENTER\n", __func__, dev->name);
-	DBG_MSG("slicoss: %s (%s) actvtd[%d] alloc[%d] state[%x] adapt[%p]\n",
-		__func__, dev->name, card->adapters_activated,
-		card->adapters_allocated, card->state, adapter);
-	slic_if_stop_queue(adapter);
+	netif_stop_queue(adapter->netdev);
 	adapter->state = ADAPT_DOWN;
 	adapter->linkstate = LINK_DOWN;
 	adapter->upr_list = NULL;
 	adapter->upr_busy = 0;
 	adapter->devflags_prev = 0;
-	DBG_MSG("slicoss: %s (%s) set adapter[%p] state to ADAPT_DOWN(%d)\n",
-		__func__, dev->name, adapter, adapter->state);
 	ASSERT(card->adapter[adapter->cardindex] == adapter);
-	WRITE_REG(slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
+	slic_reg32_write(&slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
 	adapter->all_reg_writes++;
 	adapter->icr_reg_writes++;
 	slic_config_clear(adapter);
-	DBG_MSG("slicoss: %s (%s) dev[%p] adapt[%p] card[%p]\n",
-		__func__, dev->name, dev, adapter, card);
 	if (adapter->activated) {
 		card->adapters_activated--;
 		slic_global.num_slic_ports_active--;
 		adapter->activated = 0;
 	}
 #ifdef AUTOMATIC_RESET
-	WRITE_REG(slic_regs->slic_reset_iface, 0, FLUSH);
+	slic_reg32_write(&slic_regs->slic_reset_iface, 0, FLUSH);
 #endif
 	/*
-	 *  Reset the adapter's rsp, cmd, and rcv queues
+	 *  Reset the adapter's cmd queues
 	 */
 	slic_cmdq_reset(adapter);
-	slic_rspqueue_reset(adapter);
-	slic_rcvqueue_reset(adapter);
 
 #ifdef AUTOMATIC_RESET
-	if (!card->adapters_activated) {
-
-#if SLIC_DUMP_ENABLED
-		if (card->dumpthread_running) {
-			uint status;
-			DBG_MSG("attempt to terminate dump thread pid[%x]\n",
-				card->dump_task_id);
-			status = kill_proc(card->dump_task_id->pid, SIGKILL, 1);
-
-			if (!status) {
-				int count = 10 * 100;
-				while (card->dumpthread_running && --count) {
-					current->state = TASK_INTERRUPTIBLE;
-					schedule_timeout(1);
-				}
-
-				if (!count) {
-					DBG_MSG
-					    ("slicmon thread cleanup FAILED \
-					     pid[%x]\n",
-					     card->dump_task_id->pid);
-				}
-			}
-		}
-#endif
-		DBG_MSG("slicoss: %s (%s) initiate CARD_HALT\n", __func__,
-			dev->name);
-
+	if (!card->adapters_activated)
 		slic_card_init(card, adapter);
-	}
 #endif
 
-	DBG_MSG("slicoss: %s (%s) EXIT\n", __func__, dev->name);
-	DBG_MSG("slicoss: %s EXIT\n", __func__);
 	spin_unlock_irqrestore(&slic_global.driver_lock.lock,
 				slic_global.driver_lock.flags);
 	return STATUS_SUCCESS;
@@ -729,69 +618,27 @@
 
 static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
+	struct adapter *adapter = (struct adapter *)netdev_priv(dev);
+	struct ethtool_cmd edata;
+	struct ethtool_cmd ecmd;
+	u32 data[7];
+	u32 intagg;
+
 	ASSERT(rq);
-/*
-      DBG_MSG("slicoss: %s cmd[%x] rq[%p] dev[%p]\n", __func__, cmd, rq, dev);
-*/
 	switch (cmd) {
 	case SIOCSLICSETINTAGG:
-		{
-			struct adapter *adapter = (struct adapter *)
-							netdev_priv(dev);
-			u32 data[7];
-			u32 intagg;
-
-			if (copy_from_user(data, rq->ifr_data, 28)) {
-				DBG_ERROR
-				    ("copy_from_user FAILED getting initial \
-				     params\n");
-				return -EFAULT;
-			}
-			intagg = data[0];
-			printk(KERN_EMERG
-			       "%s: set interrupt aggregation to %d\n",
-			       __func__, intagg);
-			slic_intagg_set(adapter, intagg);
-			return 0;
-		}
-#ifdef SLIC_USER_REQUEST_DUMP_ENABLED
-	case SIOCSLICDUMPCARD:
-		{
-			struct adapter *adapter = netdev_priv(dev);
-			struct sliccard *card;
-
-			ASSERT(adapter);
-			ASSERT(adapter->card)
-			card = adapter->card;
-
-			DBG_IOCTL("slic_ioctl  SIOCSLIC_DUMP_CARD\n");
-
-			if (card->dump_requested == SLIC_DUMP_DONE) {
-				printk(SLICLEVEL
-				       "SLIC Card dump to be overwritten\n");
-				card->dump_requested = SLIC_DUMP_REQUESTED;
-			} else if ((card->dump_requested == SLIC_DUMP_REQUESTED)
-				   || (card->dump_requested ==
-				       SLIC_DUMP_IN_PROGRESS)) {
-				printk(SLICLEVEL
-				       "SLIC Card dump Requested but already \
-					in progress... ignore\n");
-			} else {
-				printk(SLICLEVEL
-				       "SLIC Card #%d Dump Requested\n",
-				       card->cardnum);
-				card->dump_requested = SLIC_DUMP_REQUESTED;
-			}
-			return 0;
-		}
-#endif
+		if (copy_from_user(data, rq->ifr_data, 28))
+			return -EFAULT;
+		intagg = data[0];
+		dev_err(&dev->dev, "%s: set interrupt aggregation to %d\n",
+			__func__, intagg);
+		slic_intagg_set(adapter, intagg);
+		return 0;
 
 #ifdef SLIC_TRACE_DUMP_ENABLED
 	case SIOCSLICTRACEDUMP:
 		{
-			ulong data[7];
-			ulong value;
-
+			u32 value;
 			DBG_IOCTL("slic_ioctl  SIOCSLIC_TRACE_DUMP\n");
 
 			if (copy_from_user(data, rq->ifr_data, 28)) {
@@ -824,104 +671,76 @@
 			return 0;
 		}
 #endif
-#if SLIC_ETHTOOL_SUPPORT
 	case SIOCETHTOOL:
-		{
-			struct adapter *adapter = (struct adapter *)
-							netdev_priv(dev);
-			struct ethtool_cmd data;
-			struct ethtool_cmd ecmd;
+		ASSERT(adapter);
+		if (copy_from_user(&ecmd, rq->ifr_data, sizeof(ecmd)))
+			return -EFAULT;
 
-			ASSERT(adapter);
-/*                      DBG_MSG("slicoss: %s SIOCETHTOOL\n", __func__); */
-			if (copy_from_user(&ecmd, rq->ifr_data, sizeof(ecmd)))
+		if (ecmd.cmd == ETHTOOL_GSET) {
+			edata.supported = (SUPPORTED_10baseT_Half |
+					   SUPPORTED_10baseT_Full |
+					   SUPPORTED_100baseT_Half |
+					   SUPPORTED_100baseT_Full |
+					   SUPPORTED_Autoneg | SUPPORTED_MII);
+			edata.port = PORT_MII;
+			edata.transceiver = XCVR_INTERNAL;
+			edata.phy_address = 0;
+			if (adapter->linkspeed == LINK_100MB)
+				edata.speed = SPEED_100;
+			else if (adapter->linkspeed == LINK_10MB)
+				edata.speed = SPEED_10;
+			else
+				edata.speed = 0;
+
+			if (adapter->linkduplex == LINK_FULLD)
+				edata.duplex = DUPLEX_FULL;
+			else
+				edata.duplex = DUPLEX_HALF;
+
+			edata.autoneg = AUTONEG_ENABLE;
+			edata.maxtxpkt = 1;
+			edata.maxrxpkt = 1;
+			if (copy_to_user(rq->ifr_data, &edata, sizeof(edata)))
 				return -EFAULT;
 
-			if (ecmd.cmd == ETHTOOL_GSET) {
-				data.supported =
-				    (SUPPORTED_10baseT_Half |
-				     SUPPORTED_10baseT_Full |
-				     SUPPORTED_100baseT_Half |
-				     SUPPORTED_100baseT_Full |
-				     SUPPORTED_Autoneg | SUPPORTED_MII);
-				data.port = PORT_MII;
-				data.transceiver = XCVR_INTERNAL;
-				data.phy_address = 0;
-				if (adapter->linkspeed == LINK_100MB)
-					data.speed = SPEED_100;
-				else if (adapter->linkspeed == LINK_10MB)
-					data.speed = SPEED_10;
+		} else if (ecmd.cmd == ETHTOOL_SSET) {
+			if (!capable(CAP_NET_ADMIN))
+				return -EPERM;
+
+			if (adapter->linkspeed == LINK_100MB)
+				edata.speed = SPEED_100;
+			else if (adapter->linkspeed == LINK_10MB)
+				edata.speed = SPEED_10;
+			else
+				edata.speed = 0;
+
+			if (adapter->linkduplex == LINK_FULLD)
+				edata.duplex = DUPLEX_FULL;
+			else
+				edata.duplex = DUPLEX_HALF;
+
+			edata.autoneg = AUTONEG_ENABLE;
+			edata.maxtxpkt = 1;
+			edata.maxrxpkt = 1;
+			if ((ecmd.speed != edata.speed) ||
+			    (ecmd.duplex != edata.duplex)) {
+				u32 speed;
+				u32 duplex;
+
+				if (ecmd.speed == SPEED_10)
+					speed = 0;
 				else
-					data.speed = 0;
-
-				if (adapter->linkduplex == LINK_FULLD)
-					data.duplex = DUPLEX_FULL;
+					speed = PCR_SPEED_100;
+				if (ecmd.duplex == DUPLEX_FULL)
+					duplex = PCR_DUPLEX_FULL;
 				else
-					data.duplex = DUPLEX_HALF;
-
-				data.autoneg = AUTONEG_ENABLE;
-				data.maxtxpkt = 1;
-				data.maxrxpkt = 1;
-				if (copy_to_user
-				    (rq->ifr_data, &data, sizeof(data)))
-					return -EFAULT;
-
-			} else if (ecmd.cmd == ETHTOOL_SSET) {
-				if (!capable(CAP_NET_ADMIN))
-					return -EPERM;
-
-				if (adapter->linkspeed == LINK_100MB)
-					data.speed = SPEED_100;
-				else if (adapter->linkspeed == LINK_10MB)
-					data.speed = SPEED_10;
-				else
-					data.speed = 0;
-
-				if (adapter->linkduplex == LINK_FULLD)
-					data.duplex = DUPLEX_FULL;
-				else
-					data.duplex = DUPLEX_HALF;
-
-				data.autoneg = AUTONEG_ENABLE;
-				data.maxtxpkt = 1;
-				data.maxrxpkt = 1;
-				if ((ecmd.speed != data.speed) ||
-				    (ecmd.duplex != data.duplex)) {
-					u32 speed;
-					u32 duplex;
-
-					if (ecmd.speed == SPEED_10) {
-						speed = 0;
-						SLIC_DISPLAY
-						    ("%s: slic ETHTOOL set \
-						     link speed==10MB",
-						     dev->name);
-					} else {
-						speed = PCR_SPEED_100;
-						SLIC_DISPLAY
-						    ("%s: slic ETHTOOL set \
-						    link speed==100MB",
-						     dev->name);
-					}
-					if (ecmd.duplex == DUPLEX_FULL) {
-						duplex = PCR_DUPLEX_FULL;
-						SLIC_DISPLAY
-						    (": duplex==FULL\n");
-					} else {
-						duplex = 0;
-						SLIC_DISPLAY
-						    (": duplex==HALF\n");
-					}
-					slic_link_config(adapter,
-							 speed, duplex);
-					slic_link_event_handler(adapter);
-				}
+					duplex = 0;
+				slic_link_config(adapter, speed, duplex);
+				slic_link_event_handler(adapter);
 			}
-			return 0;
 		}
-#endif
+		return 0;
 	default:
-/*              DBG_MSG("slicoss: %s UNSUPPORTED[%x]\n", __func__, cmd); */
 		return -EOPNOTSUPP;
 	}
 }
@@ -970,11 +789,6 @@
 
 	card = adapter->card;
 	ASSERT(card);
-/*
-    DBG_ERROR("xmit_start (%s) ENTER skb[%p] len[%d] linkstate[%x] state[%x]\n",
-	adapter->netdev->name, skb, skb->len, adapter->linkstate,
-	 adapter->state);
-*/
 	if ((adapter->linkstate != LINK_UP) ||
 	    (adapter->state != ADAPT_UP) || (card->state != CARD_UP)) {
 		status = XMIT_FAIL_LINK_STATE;
@@ -1015,14 +829,13 @@
 	}
 #endif
 	if (hcmd->paddrh == 0) {
-		WRITE_REG(adapter->slic_regs->slic_cbar,
-			  (hcmd->paddrl | hcmd->cmdsize), DONT_FLUSH);
+		slic_reg32_write(&adapter->slic_regs->slic_cbar,
+				 (hcmd->paddrl | hcmd->cmdsize), DONT_FLUSH);
 	} else {
-		WRITE_REG64(adapter,
-			    adapter->slic_regs->slic_cbar64,
-			    (hcmd->paddrl | hcmd->cmdsize),
-			    adapter->slic_regs->slic_addr_upper,
-			    hcmd->paddrh, DONT_FLUSH);
+		slic_reg64_write(adapter, &adapter->slic_regs->slic_cbar64,
+				 (hcmd->paddrl | hcmd->cmdsize),
+				 &adapter->slic_regs->slic_addr_upper,
+				 hcmd->paddrh, DONT_FLUSH);
 	}
 xmit_done:
 	return 0;
@@ -1036,29 +849,29 @@
 		    void *cmd, u32 skbtype, u32 status)
 {
 	if (adapter->xmitq_full)
-		slic_if_stop_queue(adapter);
+		netif_stop_queue(adapter->netdev);
 	if ((cmd == NULL) && (status <= XMIT_FAIL_HOSTCMD_FAIL)) {
 		switch (status) {
 		case XMIT_FAIL_LINK_STATE:
-			DBG_ERROR
-			    ("(%s) reject xmit skb[%p: %x] linkstate[%s] \
-			     adapter[%s:%d] card[%s:%d]\n",
-			     adapter->netdev->name, skb, skb->pkt_type,
-			     SLIC_LINKSTATE(adapter->linkstate),
-			     SLIC_ADAPTER_STATE(adapter->state), adapter->state,
-			     SLIC_CARD_STATE(adapter->card->state),
-			     adapter->card->state);
+			dev_err(&adapter->netdev->dev,
+				"reject xmit skb[%p: %x] linkstate[%s] "
+				"adapter[%s:%d] card[%s:%d]\n",
+				skb, skb->pkt_type,
+				SLIC_LINKSTATE(adapter->linkstate),
+				SLIC_ADAPTER_STATE(adapter->state),
+				adapter->state,
+				SLIC_CARD_STATE(adapter->card->state),
+				adapter->card->state);
 			break;
 		case XMIT_FAIL_ZERO_LENGTH:
-			DBG_ERROR
-			    ("xmit_start skb->len == 0 skb[%p] type[%x]!!!! \n",
-			     skb, skb->pkt_type);
+			dev_err(&adapter->netdev->dev,
+				"xmit_start skb->len == 0 skb[%p] type[%x]\n",
+				skb, skb->pkt_type);
 			break;
 		case XMIT_FAIL_HOSTCMD_FAIL:
-			DBG_ERROR
-			    ("xmit_start skb[%p] type[%x] No host commands \
-			     available !!!! \n",
-			     skb, skb->pkt_type);
+			dev_err(&adapter->netdev->dev,
+				"xmit_start skb[%p] type[%x] No host commands "
+				"available\n", skb, skb->pkt_type);
 			break;
 		default:
 			ASSERT(0);
@@ -1183,11 +996,6 @@
 
 		if (!slic_mac_filter(adapter, (struct ether_header *)
 					rcvbuf->data)) {
-#if 0
-			DBG_MSG
-			    ("slicoss: %s (%s) drop frame due to mac filter\n",
-			     __func__, adapter->netdev->name);
-#endif
 			slic_rcvqueue_reinsert(adapter, skb);
 			continue;
 		}
@@ -1242,12 +1050,6 @@
 		ASSERT(hcmd);
 		ASSERT(hcmd->pslic_handle ==
 		       &adapter->slic_handles[slic_handle_word.handle_index]);
-/*
-      DBG_ERROR("xmit_complete (%s)   hcmd[%p]  hosthandle[%x]\n",
-		adapter->netdev->name, hcmd, hcmd->cmd64.hosthandle);
-      DBG_ERROR("    skb[%p] len %d  hcmdtype[%x]\n", hcmd->skb,
-		hcmd->skb->len, hcmd->type);
-*/
 		if (hcmd->type == SLIC_CMD_DUMB) {
 			if (hcmd->skb)
 				dev_kfree_skb_irq(hcmd->skb);
@@ -1267,7 +1069,8 @@
 	u32 isr;
 
 	if ((adapter->pshmem) && (adapter->pshmem->isr)) {
-		WRITE_REG(adapter->slic_regs->slic_icr, ICR_INT_MASK, FLUSH);
+		slic_reg32_write(&adapter->slic_regs->slic_icr,
+				 ICR_INT_MASK, FLUSH);
 		isr = adapter->isrcopy = adapter->pshmem->isr;
 		adapter->pshmem->isr = 0;
 		adapter->num_isrs++;
@@ -1299,29 +1102,18 @@
 							if (!count)
 								break;
 						}
-						DBG_MSG
-						    ("(%s): [%x] ISR_RMISS \
-						     initial[%x] pre[%x] \
-						     errors[%x] \
-						     post_count[%x]\n",
-						     adapter->netdev->name,
-						     isr, rcv_count, pre_count,
-						     errors, rcvq->count);
 					} else if (isr & ISR_XDROP) {
-						DBG_ERROR
-						    ("isr & ISR_ERR [%x] \
-						     ISR_XDROP \n",
-						     isr);
+						dev_err(&dev->dev,
+							"isr & ISR_ERR [%x] "
+							"ISR_XDROP \n", isr);
 					} else {
-						DBG_ERROR
-						    ("isr & ISR_ERR [%x]\n",
-						     isr);
+						dev_err(&dev->dev,
+							"isr & ISR_ERR [%x]\n",
+							isr);
 					}
 				}
 
 				if (isr & ISR_LEVENT) {
-					/*DBG_MSG("%s (%s)  ISR_LEVENT \n",
-					   __func__, adapter->netdev->name);*/
 					adapter->linkevent_interrupts++;
 					slic_link_event_handler(adapter);
 				}
@@ -1359,7 +1151,7 @@
 		adapter->isrcopy = 0;
 		adapter->all_reg_writes += 2;
 		adapter->isr_reg_writes++;
-		WRITE_REG(adapter->slic_regs->slic_isr, 0, FLUSH);
+		slic_reg32_write(&adapter->slic_regs->slic_isr, 0, FLUSH);
 	} else {
 		adapter->false_interrupts++;
 	}
@@ -1389,11 +1181,6 @@
 	pshmem = (struct slic_shmem *)adapter->phys_shmem;
 
 #if defined(CONFIG_X86_64)
-/*
-    DBG_MSG("slic_event_handler  pshmem->linkstatus[%x]  pshmem[%p]\n   \
-	&linkstatus[%p] &isr[%p]\n", adapter->pshmem->linkstatus, pshmem,
-	&pshmem->linkstatus, &pshmem->isr);
-*/
 	status = slic_upr_request(adapter,
 				  SLIC_UPR_RLSR,
 				  SLIC_GET_ADDR_LOW(&pshmem->linkstatus),
@@ -1411,46 +1198,29 @@
 
 static void slic_init_cleanup(struct adapter *adapter)
 {
-	DBG_MSG("slicoss: %s ENTER adapter[%p] ", __func__, adapter);
 	if (adapter->intrregistered) {
-		DBG_MSG("FREE_IRQ ");
 		adapter->intrregistered = 0;
 		free_irq(adapter->netdev->irq, adapter->netdev);
 
 	}
 	if (adapter->pshmem) {
-		DBG_MSG("FREE_SHMEM ");
-		DBG_MSG("adapter[%p] port %d pshmem[%p] FreeShmem ",
-			adapter, adapter->port, (void *) adapter->pshmem);
 		pci_free_consistent(adapter->pcidev,
 				    sizeof(struct slic_shmem),
 				    adapter->pshmem, adapter->phys_shmem);
 		adapter->pshmem = NULL;
 		adapter->phys_shmem = (dma_addr_t) NULL;
 	}
-#if SLIC_GET_STATS_TIMER_ENABLED
-	if (adapter->statstimerset) {
-		DBG_MSG("statstimer ");
-		adapter->statstimerset = 0;
-		del_timer(&adapter->statstimer);
-	}
-#endif
-#if !SLIC_DUMP_ENABLED && SLIC_PING_TIMER_ENABLED
-/*#if SLIC_DUMP_ENABLED && SLIC_PING_TIMER_ENABLED*/
+
 	if (adapter->pingtimerset) {
-		DBG_MSG("pingtimer ");
 		adapter->pingtimerset = 0;
 		del_timer(&adapter->pingtimer);
 	}
-#endif
+
 	slic_rspqueue_free(adapter);
 	slic_cmdq_free(adapter);
 	slic_rcvqueue_free(adapter);
-
-	DBG_MSG("\n");
 }
 
-#if SLIC_GET_STATS_ENABLED
 static struct net_device_stats *slic_get_stats(struct net_device *dev)
 {
 	struct adapter *adapter = (struct adapter *)netdev_priv(dev);
@@ -1470,7 +1240,6 @@
 	stats->rx_length_errors = 0;
 	return &adapter->stats;
 }
-#endif
 
 /*
  *  Allocate a mcast_address structure to hold the multicast address.
@@ -1491,7 +1260,7 @@
 	}
 
 	/* Doesn't already exist.  Allocate a structure to hold it */
-	mcaddr = kmalloc(sizeof(struct mcast_address), GFP_ATOMIC);
+	mcaddr = kmalloc(sizeof(struct mcast_address), GFP_KERNEL);
 	if (mcaddr == NULL)
 		return 1;
 
@@ -1608,8 +1377,6 @@
 		mc_list = mc_list->next;
 	}
 
-	DBG_MSG("%s a->devflags_prev[%x] dev->flags[%x] status[%x]\n",
-		__func__, adapter->devflags_prev, dev->flags, status);
 	if (adapter->devflags_prev != dev->flags) {
 		adapter->macopts = MAC_DIRECTED;
 		if (dev->flags) {
@@ -1623,9 +1390,7 @@
 				adapter->macopts |= MAC_MCAST;
 		}
 		adapter->devflags_prev = dev->flags;
-		DBG_MSG("%s call slic_config_set adapter->macopts[%x]\n",
-			__func__, adapter->macopts);
-		slic_config_set(adapter, TRUE);
+		slic_config_set(adapter, true);
 	} else {
 		if (status == STATUS_SUCCESS)
 			slic_mcast_set_mask(adapter);
@@ -1637,36 +1402,23 @@
 {
 	__iomem struct slic_regs *slic_regs = adapter->slic_regs;
 
-	DBG_MSG("%s ENTER (%s) macopts[%x] mask[%llx]\n", __func__,
-		adapter->netdev->name, (uint) adapter->macopts,
-		adapter->mcastmask);
-
 	if (adapter->macopts & (MAC_ALLMCAST | MAC_PROMISC)) {
 		/* Turn on all multicast addresses. We have to do this for
 		 * promiscuous mode as well as ALLMCAST mode.  It saves the
 		 * Microcode from having to keep state about the MAC
 		 * configuration.
 		 */
-/*              DBG_MSG("slicoss: %s macopts = MAC_ALLMCAST | MAC_PROMISC\n\
-		SLUT MODE!!!\n",__func__); */
-		WRITE_REG(slic_regs->slic_mcastlow, 0xFFFFFFFF, FLUSH);
-		WRITE_REG(slic_regs->slic_mcasthigh, 0xFFFFFFFF, FLUSH);
-/*        DBG_MSG("%s (%s) WRITE to slic_regs slic_mcastlow&high 0xFFFFFFFF\n",
-		_func__, adapter->netdev->name); */
+		slic_reg32_write(&slic_regs->slic_mcastlow, 0xFFFFFFFF, FLUSH);
+		slic_reg32_write(&slic_regs->slic_mcasthigh, 0xFFFFFFFF,
+				 FLUSH);
 	} else {
 		/* Commit our multicast mast to the SLIC by writing to the
 		 * multicast address mask registers
 		 */
-		DBG_MSG("%s (%s) WRITE mcastlow[%x] mcasthigh[%x]\n",
-			__func__, adapter->netdev->name,
-			((ulong) (adapter->mcastmask & 0xFFFFFFFF)),
-			((ulong) ((adapter->mcastmask >> 32) & 0xFFFFFFFF)));
-
-		WRITE_REG(slic_regs->slic_mcastlow,
-			  (u32) (adapter->mcastmask & 0xFFFFFFFF), FLUSH);
-		WRITE_REG(slic_regs->slic_mcasthigh,
-			  (u32) ((adapter->mcastmask >> 32) & 0xFFFFFFFF),
-			  FLUSH);
+		slic_reg32_write(&slic_regs->slic_mcastlow,
+			(u32)(adapter->mcastmask & 0xFFFFFFFF), FLUSH);
+		slic_reg32_write(&slic_regs->slic_mcasthigh,
+			(u32)((adapter->mcastmask >> 32) & 0xFFFFFFFF), FLUSH);
 	}
 }
 
@@ -1680,53 +1432,11 @@
 	ASSERT(adapter);
 	card = adapter->card;
 	ASSERT(card);
-#if !SLIC_DUMP_ENABLED
-/*#if SLIC_DUMP_ENABLED*/
-	if ((adapter->state == ADAPT_UP) && (card->state == CARD_UP)) {
-		int status;
 
-		if (card->pingstatus != ISR_PINGMASK) {
-			if (errormsg++ < 5) {
-				DBG_MSG
-				    ("%s (%s) CARD HAS CRASHED  PING_status == \
-				     %x ERRORMSG# %d\n",
-				     __func__, adapter->netdev->name,
-				     card->pingstatus, errormsg);
-			}
-			/*   ASSERT(card->pingstatus == ISR_PINGMASK); */
-		} else {
-			if (goodmsg++ < 5) {
-				DBG_MSG
-				    ("slicoss: %s (%s) PING_status == %x \
-				     GOOD!!!!!!!! msg# %d\n",
-				     __func__, adapter->netdev->name,
-				     card->pingstatus, errormsg);
-			}
-		}
-		card->pingstatus = 0;
-		status = slic_upr_request(adapter, SLIC_UPR_PING, 0, 0, 0, 0);
-
-		ASSERT(status == 0);
-	} else {
-		DBG_MSG("slicoss %s (%s) adapter[%p] NOT UP!!!!\n",
-			__func__, adapter->netdev->name, adapter);
-	}
-#endif
-	adapter->pingtimer.expires =
-	    jiffies + SLIC_SECS_TO_JIFFS(PING_TIMER_INTERVAL);
+	adapter->pingtimer.expires = jiffies + (PING_TIMER_INTERVAL * HZ);
 	add_timer(&adapter->pingtimer);
 }
 
-static void slic_if_stop_queue(struct adapter *adapter)
-{
-	netif_stop_queue(adapter->netdev);
-}
-
-static void slic_if_start_queue(struct adapter *adapter)
-{
-	netif_start_queue(adapter->netdev);
-}
-
 /*
  *  slic_if_init
  *
@@ -1742,14 +1452,11 @@
 	int status = 0;
 
 	ASSERT(card);
-	DBG_MSG("slicoss: %s (%s) ENTER states[%d:%d:%d:%d] flags[%x]\n",
-		__func__, adapter->netdev->name,
-		adapter->queues_initialized, adapter->state, adapter->linkstate,
-		card->state, dev->flags);
 
 	/* adapter should be down at this point */
 	if (adapter->state != ADAPT_DOWN) {
-		DBG_ERROR("slic_if_init adapter->state != ADAPT_DOWN\n");
+		dev_err(&dev->dev, "%s: adapter->state != ADAPT_DOWN\n",
+			__func__);
 		return -EIO;
 	}
 	ASSERT(adapter->linkstate == LINK_DOWN);
@@ -1757,54 +1464,35 @@
 	adapter->devflags_prev = dev->flags;
 	adapter->macopts = MAC_DIRECTED;
 	if (dev->flags) {
-		DBG_MSG("slicoss: %s (%s) Set MAC options: ", __func__,
-			adapter->netdev->name);
-		if (dev->flags & IFF_BROADCAST) {
+		if (dev->flags & IFF_BROADCAST)
 			adapter->macopts |= MAC_BCAST;
-			DBG_MSG("BCAST ");
-		}
-		if (dev->flags & IFF_PROMISC) {
+		if (dev->flags & IFF_PROMISC)
 			adapter->macopts |= MAC_PROMISC;
-			DBG_MSG("PROMISC ");
-		}
-		if (dev->flags & IFF_ALLMULTI) {
+		if (dev->flags & IFF_ALLMULTI)
 			adapter->macopts |= MAC_ALLMCAST;
-			DBG_MSG("ALL_MCAST ");
-		}
-		if (dev->flags & IFF_MULTICAST) {
+		if (dev->flags & IFF_MULTICAST)
 			adapter->macopts |= MAC_MCAST;
-			DBG_MSG("MCAST ");
-		}
-		DBG_MSG("\n");
 	}
 	status = slic_adapter_allocresources(adapter);
 	if (status != STATUS_SUCCESS) {
-		DBG_ERROR
-		    ("slic_if_init: slic_adapter_allocresources FAILED %x\n",
-		     status);
+		dev_err(&dev->dev,
+			"%s: slic_adapter_allocresources FAILED %x\n",
+			__func__, status);
 		slic_adapter_freeresources(adapter);
 		return status;
 	}
 
 	if (!adapter->queues_initialized) {
-		DBG_MSG("slicoss: %s call slic_rspqueue_init\n", __func__);
 		if (slic_rspqueue_init(adapter))
 			return -ENOMEM;
-		DBG_MSG
-		    ("slicoss: %s call slic_cmdq_init adapter[%p] port %d \n",
-		     __func__, adapter, adapter->port);
 		if (slic_cmdq_init(adapter))
 			return -ENOMEM;
-		DBG_MSG
-		    ("slicoss: %s call slic_rcvqueue_init adapter[%p] \
-		     port %d \n", __func__, adapter, adapter->port);
 		if (slic_rcvqueue_init(adapter))
 			return -ENOMEM;
 		adapter->queues_initialized = 1;
 	}
-	DBG_MSG("slicoss: %s disable interrupts(slic)\n", __func__);
 
-	WRITE_REG(slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
+	slic_reg32_write(&slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
 	mdelay(1);
 
 	if (!adapter->isp_initialized) {
@@ -1814,13 +1502,13 @@
 					adapter->bit64reglock.flags);
 
 #if defined(CONFIG_X86_64)
-		WRITE_REG(slic_regs->slic_addr_upper,
-			  SLIC_GET_ADDR_HIGH(&pshmem->isr), DONT_FLUSH);
-		WRITE_REG(slic_regs->slic_isp,
-			  SLIC_GET_ADDR_LOW(&pshmem->isr), FLUSH);
+		slic_reg32_write(&slic_regs->slic_addr_upper,
+				 SLIC_GET_ADDR_HIGH(&pshmem->isr), DONT_FLUSH);
+		slic_reg32_write(&slic_regs->slic_isp,
+				 SLIC_GET_ADDR_LOW(&pshmem->isr), FLUSH);
 #elif defined(CONFIG_X86)
-		WRITE_REG(slic_regs->slic_addr_upper, (u32) 0, DONT_FLUSH);
-		WRITE_REG(slic_regs->slic_isp, (u32) &pshmem->isr, FLUSH);
+		slic_reg32_write(&slic_regs->slic_addr_upper, 0, DONT_FLUSH);
+		slic_reg32_write(&slic_regs->slic_isp, (u32)&pshmem->isr, FLUSH);
 #else
 		Stop Compilations
 #endif
@@ -1833,66 +1521,44 @@
 	if (!card->loadtimerset) {
 		init_timer(&card->loadtimer);
 		card->loadtimer.expires =
-		    jiffies + SLIC_SECS_TO_JIFFS(SLIC_LOADTIMER_PERIOD);
+		    jiffies + (SLIC_LOADTIMER_PERIOD * HZ);
 		card->loadtimer.data = (ulong) card;
 		card->loadtimer.function = &slic_timer_load_check;
 		add_timer(&card->loadtimer);
 
 		card->loadtimerset = 1;
 	}
-#if SLIC_GET_STATS_TIMER_ENABLED
-	if (!adapter->statstimerset) {
-		DBG_MSG("slicoss: %s start getstats_timer(slic)\n",
-			__func__);
-		init_timer(&adapter->statstimer);
-		adapter->statstimer.expires =
-		    jiffies + SLIC_SECS_TO_JIFFS(STATS_TIMER_INTERVAL);
-		adapter->statstimer.data = (ulong) adapter->netdev;
-		adapter->statstimer.function = &slic_timer_get_stats;
-		add_timer(&adapter->statstimer);
-		adapter->statstimerset = 1;
-	}
-#endif
-#if !SLIC_DUMP_ENABLED && SLIC_PING_TIMER_ENABLED
-/*#if SLIC_DUMP_ENABLED && SLIC_PING_TIMER_ENABLED*/
+
 	if (!adapter->pingtimerset) {
-		DBG_MSG("slicoss: %s start card_ping_timer(slic)\n",
-			__func__);
 		init_timer(&adapter->pingtimer);
 		adapter->pingtimer.expires =
-		    jiffies + SLIC_SECS_TO_JIFFS(PING_TIMER_INTERVAL);
+		    jiffies + (PING_TIMER_INTERVAL * HZ);
 		adapter->pingtimer.data = (ulong) dev;
 		adapter->pingtimer.function = &slic_timer_ping;
 		add_timer(&adapter->pingtimer);
 		adapter->pingtimerset = 1;
 		adapter->card->pingstatus = ISR_PINGMASK;
 	}
-#endif
 
 	/*
 	 *    clear any pending events, then enable interrupts
 	 */
-	DBG_MSG("slicoss: %s ENABLE interrupts(slic)\n", __func__);
 	adapter->isrcopy = 0;
 	adapter->pshmem->isr = 0;
-	WRITE_REG(slic_regs->slic_isr, 0, FLUSH);
-	WRITE_REG(slic_regs->slic_icr, ICR_INT_ON, FLUSH);
+	slic_reg32_write(&slic_regs->slic_isr, 0, FLUSH);
+	slic_reg32_write(&slic_regs->slic_icr, ICR_INT_ON, FLUSH);
 
-	DBG_MSG("slicoss: %s call slic_link_config(slic)\n", __func__);
 	slic_link_config(adapter, LINK_AUTOSPEED, LINK_AUTOD);
 	slic_link_event_handler(adapter);
 
-	DBG_MSG("slicoss: %s EXIT\n", __func__);
 	return STATUS_SUCCESS;
 }
 
 static void slic_unmap_mmio_space(struct adapter *adapter)
 {
-#if LINUX_FREES_ADAPTER_RESOURCES
 	if (adapter->slic_regs)
 		iounmap(adapter->slic_regs);
 	adapter->slic_regs = NULL;
-#endif
 }
 
 static int slic_adapter_allocresources(struct adapter *adapter)
@@ -1900,13 +1566,6 @@
 	if (!adapter->intrregistered) {
 		int retval;
 
-		DBG_MSG
-		    ("slicoss: %s AllocAdaptRsrcs adapter[%p] shmem[%p] \
-		     phys_shmem[%p] dev->irq[%x] %x\n",
-		     __func__, adapter, adapter->pshmem,
-		     (void *)adapter->phys_shmem, adapter->netdev->irq,
-		     NR_IRQS);
-
 		spin_unlock_irqrestore(&slic_global.driver_lock.lock,
 					slic_global.driver_lock.flags);
 
@@ -1919,16 +1578,12 @@
 					slic_global.driver_lock.flags);
 
 		if (retval) {
-			DBG_ERROR("slicoss: request_irq (%s) FAILED [%x]\n",
-				  adapter->netdev->name, retval);
+			dev_err(&adapter->netdev->dev,
+				"request_irq (%s) FAILED [%x]\n",
+				adapter->netdev->name, retval);
 			return retval;
 		}
 		adapter->intrregistered = 1;
-		DBG_MSG
-		    ("slicoss: %s AllocAdaptRsrcs adapter[%p] shmem[%p] \
-		     pshmem[%p] dev->irq[%x]\n",
-		     __func__, adapter, adapter->pshmem,
-		     (void *)adapter->pshmem, adapter->netdev->irq);
 	}
 	return STATUS_SUCCESS;
 }
@@ -1939,22 +1594,17 @@
 	u16 new_command;
 
 	pci_read_config_word(pcidev, PCI_COMMAND, &pci_command);
-	DBG_MSG("slicoss: %s  PCI command[%4.4x]\n", __func__, pci_command);
 
 	new_command = pci_command | PCI_COMMAND_MASTER
 	    | PCI_COMMAND_MEMORY
 	    | PCI_COMMAND_INVALIDATE
 	    | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK;
-	if (pci_command != new_command) {
-		DBG_MSG("%s -- Updating PCI COMMAND register %4.4x->%4.4x.\n",
-			__func__, pci_command, new_command);
+	if (pci_command != new_command)
 		pci_write_config_word(pcidev, PCI_COMMAND, new_command);
-	}
 }
 
 static void slic_adapter_freeresources(struct adapter *adapter)
 {
-	DBG_MSG("slicoss: %s ENTER adapter[%p]\n", __func__, adapter);
 	slic_init_cleanup(adapter);
 	memset(&adapter->stats, 0, sizeof(struct net_device_stats));
 	adapter->error_interrupts = 0;
@@ -1967,7 +1617,6 @@
 	adapter->rcv_broadcasts = 0;
 	adapter->rcv_multicasts = 0;
 	adapter->rcv_unicasts = 0;
-	DBG_MSG("slicoss: %s EXIT\n", __func__);
 }
 
 /*
@@ -1979,21 +1628,15 @@
 static void slic_link_config(struct adapter *adapter,
 		      u32 linkspeed, u32 linkduplex)
 {
+	u32 __iomem *wphy;
 	u32 speed;
 	u32 duplex;
 	u32 phy_config;
 	u32 phy_advreg;
 	u32 phy_gctlreg;
 
-	if (adapter->state != ADAPT_UP) {
-		DBG_MSG
-		    ("%s (%s) ADAPT Not up yet, Return! speed[%x] duplex[%x]\n",
-		     __func__, adapter->netdev->name, linkspeed,
-		     linkduplex);
+	if (adapter->state != ADAPT_UP)
 		return;
-	}
-	DBG_MSG("slicoss: %s (%s) slic_link_config: speed[%x] duplex[%x]\n",
-		__func__, adapter->netdev->name, linkspeed, linkduplex);
 
 	ASSERT((adapter->devid == SLIC_1GB_DEVICE_ID)
 	       || (adapter->devid == SLIC_2GB_DEVICE_ID));
@@ -2003,6 +1646,8 @@
 	if (linkduplex > LINK_AUTOD)
 		linkduplex = LINK_AUTOD;
 
+	wphy = &adapter->slic_regs->slic_wphy;
+
 	if ((linkspeed == LINK_AUTOSPEED) || (linkspeed == LINK_1000MB)) {
 		if (adapter->flags & ADAPT_FLAGS_FIBERMEDIA) {
 			/*  We've got a fiber gigabit interface, and register
@@ -2013,8 +1658,7 @@
 			phy_advreg = (MIICR_REG_4 | (PAR_ADV1000XFD));
 			/* enable PAUSE frames        */
 			phy_advreg |= PAR_ASYMPAUSE_FIBER;
-			WRITE_REG(adapter->slic_regs->slic_wphy, phy_advreg,
-				  FLUSH);
+			slic_reg32_write(wphy, phy_advreg, FLUSH);
 
 			if (linkspeed == LINK_AUTOSPEED) {
 				/* reset phy, enable auto-neg  */
@@ -2022,14 +1666,12 @@
 				    (MIICR_REG_PCR |
 				     (PCR_RESET | PCR_AUTONEG |
 				      PCR_AUTONEG_RST));
-				WRITE_REG(adapter->slic_regs->slic_wphy,
-					  phy_config, FLUSH);
+				slic_reg32_write(wphy, phy_config, FLUSH);
 			} else {	/* forced 1000 Mb FD*/
 				/* power down phy to break link
 				   this may not work) */
 				phy_config = (MIICR_REG_PCR | PCR_POWERDOWN);
-				WRITE_REG(adapter->slic_regs->slic_wphy,
-					  phy_config, FLUSH);
+				slic_reg32_write(wphy, phy_config, FLUSH);
 				/* wait, Marvell says 1 sec,
 				   try to get away with 10 ms  */
 				mdelay(10);
@@ -2040,8 +1682,7 @@
 				    (MIICR_REG_PCR |
 				     (PCR_RESET | PCR_SPEED_1000 |
 				      PCR_DUPLEX_FULL));
-				WRITE_REG(adapter->slic_regs->slic_wphy,
-					  phy_config, FLUSH);
+				slic_reg32_write(wphy, phy_config, FLUSH);
 			}
 		} else {	/* copper gigabit */
 
@@ -2065,35 +1706,30 @@
 			phy_advreg |= PAR_ASYMPAUSE;
 			/* required by the Cicada PHY  */
 			phy_advreg |= PAR_802_3;
-			WRITE_REG(adapter->slic_regs->slic_wphy, phy_advreg,
-				  FLUSH);
+			slic_reg32_write(wphy, phy_advreg, FLUSH);
 			/* advertise FD only @1000 Mb  */
 			phy_gctlreg = (MIICR_REG_9 | (PGC_ADV1000FD));
-			WRITE_REG(adapter->slic_regs->slic_wphy, phy_gctlreg,
-				  FLUSH);
+			slic_reg32_write(wphy, phy_gctlreg, FLUSH);
 
 			if (adapter->subsysid != SLIC_1GB_CICADA_SUBSYS_ID) {
 				/* if a Marvell PHY
 				   enable auto crossover */
 				phy_config =
 				    (MIICR_REG_16 | (MRV_REG16_XOVERON));
-				WRITE_REG(adapter->slic_regs->slic_wphy,
-					  phy_config, FLUSH);
+				slic_reg32_write(wphy, phy_config, FLUSH);
 
 				/* reset phy, enable auto-neg  */
 				phy_config =
 				    (MIICR_REG_PCR |
 				     (PCR_RESET | PCR_AUTONEG |
 				      PCR_AUTONEG_RST));
-				WRITE_REG(adapter->slic_regs->slic_wphy,
-					  phy_config, FLUSH);
+				slic_reg32_write(wphy, phy_config, FLUSH);
 			} else {	/* it's a Cicada PHY  */
 				/* enable and restart auto-neg (don't reset)  */
 				phy_config =
 				    (MIICR_REG_PCR |
 				     (PCR_AUTONEG | PCR_AUTONEG_RST));
-				WRITE_REG(adapter->slic_regs->slic_wphy,
-					  phy_config, FLUSH);
+				slic_reg32_write(wphy, phy_config, FLUSH);
 			}
 		}
 	} else {
@@ -2111,13 +1747,12 @@
 			/* if a Marvell PHY
 			   disable auto crossover  */
 			phy_config = (MIICR_REG_16 | (MRV_REG16_XOVEROFF));
-			WRITE_REG(adapter->slic_regs->slic_wphy, phy_config,
-				  FLUSH);
+			slic_reg32_write(wphy, phy_config, FLUSH);
 		}
 
 		/* power down phy to break link (this may not work)  */
 		phy_config = (MIICR_REG_PCR | (PCR_POWERDOWN | speed | duplex));
-		WRITE_REG(adapter->slic_regs->slic_wphy, phy_config, FLUSH);
+		slic_reg32_write(wphy, phy_config, FLUSH);
 
 		/* wait, Marvell says 1 sec, try to get away with 10 ms */
 		mdelay(10);
@@ -2128,43 +1763,17 @@
 			   soft reset phy, powerup */
 			phy_config =
 			    (MIICR_REG_PCR | (PCR_RESET | speed | duplex));
-			WRITE_REG(adapter->slic_regs->slic_wphy, phy_config,
-				  FLUSH);
+			slic_reg32_write(wphy, phy_config, FLUSH);
 		} else {	/* it's a Cicada PHY  */
 			/* disable auto-neg, set speed, powerup  */
 			phy_config = (MIICR_REG_PCR | (speed | duplex));
-			WRITE_REG(adapter->slic_regs->slic_wphy, phy_config,
-				  FLUSH);
+			slic_reg32_write(wphy, phy_config, FLUSH);
 		}
 	}
-
-	DBG_MSG
-	    ("slicoss: %s (%s) EXIT slic_link_config : state[%d] \
-	    phy_config[%x]\n", __func__, adapter->netdev->name, adapter->state,
-	    phy_config);
 }
 
 static void slic_card_cleanup(struct sliccard *card)
 {
-	DBG_MSG("slicoss: %s ENTER\n", __func__);
-
-#if SLIC_DUMP_ENABLED
-	if (card->dumpbuffer) {
-		card->dumpbuffer_phys = 0;
-		card->dumpbuffer_physl = 0;
-		card->dumpbuffer_physh = 0;
-		kfree(card->dumpbuffer);
-		card->dumpbuffer = NULL;
-	}
-	if (card->cmdbuffer) {
-		card->cmdbuffer_phys = 0;
-		card->cmdbuffer_physl = 0;
-		card->cmdbuffer_physh = 0;
-		kfree(card->cmdbuffer);
-		card->cmdbuffer = NULL;
-	}
-#endif
-
 	if (card->loadtimerset) {
 		card->loadtimerset = 0;
 		del_timer(&card->loadtimer);
@@ -2173,7 +1782,6 @@
 	slic_debug_card_destroy(card);
 
 	kfree(card);
-	DBG_MSG("slicoss: %s EXIT\n", __func__);
 }
 
 static int slic_card_download_gbrcv(struct adapter *adapter)
@@ -2183,15 +1791,16 @@
 	int ret;
 	__iomem struct slic_regs *slic_regs = adapter->slic_regs;
 	u32 codeaddr;
-	unsigned char *instruction = NULL;
+	u32 instruction;
+	int index = 0;
 	u32 rcvucodelen = 0;
 
 	switch (adapter->devid) {
 	case SLIC_2GB_DEVICE_ID:
-		file = "oasis_rcv.bin";
+		file = "slicoss/oasisrcvucode.sys";
 		break;
 	case SLIC_1GB_DEVICE_ID:
-		file = "gb_rcv.bin";
+		file = "slicoss/gbrcvucode.sys";
 		break;
 	default:
 		ASSERT(0);
@@ -2200,12 +1809,13 @@
 
 	ret = request_firmware(&fw, file, &adapter->pcidev->dev);
 	if (ret) {
-		printk(KERN_ERR "SLICOSS: Failed to load firmware %s\n", file);
+		dev_err(&adapter->pcidev->dev,
+			"SLICOSS: Failed to load firmware %s\n", file);
 		return ret;
 	}
 
-	instruction = (unsigned char *)fw->data;
-	rcvucodelen = fw->size;
+	rcvucodelen = *(u32 *)(fw->data + index);
+	index += 4;
 	switch (adapter->devid) {
 	case SLIC_2GB_DEVICE_ID:
 		if (rcvucodelen != OasisRcvUCodeLen)
@@ -2219,29 +1829,28 @@
 		ASSERT(0);
 		break;
 	}
-
 	/* start download */
-	WRITE_REG(slic_regs->slic_rcv_wcs, SLIC_RCVWCS_BEGIN, FLUSH);
-
+	slic_reg32_write(&slic_regs->slic_rcv_wcs, SLIC_RCVWCS_BEGIN, FLUSH);
 	/* download the rcv sequencer ucode */
 	for (codeaddr = 0; codeaddr < rcvucodelen; codeaddr++) {
 		/* write out instruction address */
-		WRITE_REG(slic_regs->slic_rcv_wcs, codeaddr, FLUSH);
+		slic_reg32_write(&slic_regs->slic_rcv_wcs, codeaddr, FLUSH);
 
+		instruction = *(u32 *)(fw->data + index);
+		index += 4;
 		/* write out the instruction data low addr */
-		WRITE_REG(slic_regs->slic_rcv_wcs,
-			  (u32) *(u32 *) instruction, FLUSH);
-		instruction += 4;
+		slic_reg32_write(&slic_regs->slic_rcv_wcs, instruction, FLUSH);
 
+		instruction = *(u8 *)(fw->data + index);
+		index++;
 		/* write out the instruction data high addr */
-		WRITE_REG(slic_regs->slic_rcv_wcs, (u32) *instruction,
-			  FLUSH);
-		instruction += 1;
+		slic_reg32_write(&slic_regs->slic_rcv_wcs, (u8)instruction,
+				 FLUSH);
 	}
 
 	/* download finished */
 	release_firmware(fw);
-	WRITE_REG(slic_regs->slic_rcv_wcs, SLIC_RCVWCS_FINISH, FLUSH);
+	slic_reg32_write(&slic_regs->slic_rcv_wcs, SLIC_RCVWCS_FINISH, FLUSH);
 	return 0;
 }
 
@@ -2254,41 +1863,21 @@
 	int thissectionsize;
 	int codeaddr;
 	__iomem struct slic_regs *slic_regs = adapter->slic_regs;
-	u32 *instruction = NULL;
-	u32 *lastinstruct = NULL;
-	u32 *startinstruct = NULL;
-	unsigned char *nextinstruct;
+	u32 instruction;
 	u32 baseaddress;
 	u32 failure;
 	u32 i;
 	u32 numsects = 0;
 	u32 sectsize[3];
 	u32 sectstart[3];
-
-/*      DBG_MSG ("slicoss: %s (%s) adapter[%p] card[%p] devid[%x] \
-	jiffies[%lx] cpu %d\n", __func__, adapter->netdev->name, adapter,
-	    adapter->card, adapter->devid,jiffies, smp_processor_id()); */
+	int ucode_start, index = 0;
 
 	switch (adapter->devid) {
 	case SLIC_2GB_DEVICE_ID:
-/*      DBG_MSG ("slicoss: %s devid==SLIC_2GB_DEVICE_ID sections[%x]\n",
-	__func__, (uint) ONumSections); */
-		file = "slic_oasis.bin";
-		numsects = ONumSections;
-		for (i = 0; i < numsects; i++) {
-			sectsize[i] = OSectionSize[i];
-			sectstart[i] = OSectionStart[i];
-		}
+		file = "slicoss/oasisdownload.sys";
 		break;
 	case SLIC_1GB_DEVICE_ID:
-/*              DBG_MSG ("slicoss: %s devid==SLIC_1GB_DEVICE_ID sections[%x]\n",
-		__func__, (uint) MNumSections); */
-		file = "slic_mojave.bin";
-		numsects = MNumSections;
-		for (i = 0; i < numsects; i++) {
-			sectsize[i] = MSectionSize[i];
-			sectstart[i] = MSectionStart[i];
-		}
+		file = "slicoss/gbdownload.sys";
 		break;
 	default:
 		ASSERT(0);
@@ -2296,131 +1885,84 @@
 	}
 	ret = request_firmware(&fw, file, &adapter->pcidev->dev);
 	if (ret) {
-		printk(KERN_ERR "SLICOSS: Failed to load firmware %s\n", file);
+		dev_err(&adapter->pcidev->dev,
+			"SLICOSS: Failed to load firmware %s\n", file);
 		return ret;
 	}
-
+	numsects = *(u32 *)(fw->data + index);
+	index += 4;
 	ASSERT(numsects <= 3);
-
+	for (i = 0; i < numsects; i++) {
+		sectsize[i] = *(u32 *)(fw->data + index);
+		index += 4;
+	}
+	for (i = 0; i < numsects; i++) {
+		sectstart[i] = *(u32 *)(fw->data + index);
+		index += 4;
+	}
+	ucode_start = index;
+	instruction = *(u32 *)(fw->data + index);
+	index += 4;
 	for (section = 0; section < numsects; section++) {
-		switch (adapter->devid) {
-		case SLIC_2GB_DEVICE_ID:
-			instruction = (u32 *)(fw->data + (SECTION_SIZE *
-								section));
-			baseaddress = sectstart[section];
-			thissectionsize = sectsize[section] >> 3;
-			lastinstruct =
-			    (u32 *)(fw->data + (SECTION_SIZE * section) +
-					sectsize[section] - 8);
-			break;
-		case SLIC_1GB_DEVICE_ID:
-			instruction = (u32 *)(fw->data + (SECTION_SIZE *
-								section));
-			baseaddress = sectstart[section];
-			thissectionsize = sectsize[section] >> 3;
-			lastinstruct =
-			    (u32 *)(fw->data + (SECTION_SIZE * section) +
-					sectsize[section] - 8);
-			break;
-		default:
-			ASSERT(0);
-			break;
-		}
-
 		baseaddress = sectstart[section];
 		thissectionsize = sectsize[section] >> 3;
 
 		for (codeaddr = 0; codeaddr < thissectionsize; codeaddr++) {
-			startinstruct = instruction;
-			nextinstruct = ((unsigned char *)instruction) + 8;
 			/* Write out instruction address */
-			WRITE_REG(slic_regs->slic_wcs, baseaddress + codeaddr,
-				  FLUSH);
+			slic_reg32_write(&slic_regs->slic_wcs,
+					 baseaddress + codeaddr, FLUSH);
 			/* Write out instruction to low addr */
-			WRITE_REG(slic_regs->slic_wcs, *instruction, FLUSH);
-#ifdef CONFIG_X86_64
-			instruction = (u32 *)((unsigned char *)instruction + 4);
-#else
-			instruction++;
-#endif
+			slic_reg32_write(&slic_regs->slic_wcs, instruction, FLUSH);
+			instruction = *(u32 *)(fw->data + index);
+			index += 4;
+
 			/* Write out instruction to high addr */
-			WRITE_REG(slic_regs->slic_wcs, *instruction, FLUSH);
-#ifdef CONFIG_X86_64
-			instruction = (u32 *)((unsigned char *)instruction + 4);
-#else
-			instruction++;
-#endif
+			slic_reg32_write(&slic_regs->slic_wcs, instruction, FLUSH);
+			instruction = *(u32 *)(fw->data + index);
+			index += 4;
 		}
 	}
-
+	index = ucode_start;
 	for (section = 0; section < numsects; section++) {
-		switch (adapter->devid) {
-		case SLIC_2GB_DEVICE_ID:
-			instruction = (u32 *)fw->data + (SECTION_SIZE *
-								section);
-			break;
-		case SLIC_1GB_DEVICE_ID:
-			instruction = (u32 *)fw->data + (SECTION_SIZE *
-								section);
-			break;
-		default:
-			ASSERT(0);
-			break;
-		}
-
+		instruction = *(u32 *)(fw->data + index);
 		baseaddress = sectstart[section];
 		if (baseaddress < 0x8000)
 			continue;
 		thissectionsize = sectsize[section] >> 3;
 
-/*        DBG_MSG ("slicoss: COMPARE secton[%x] baseaddr[%x] sectnsize[%x]\n",
-		(uint)section,baseaddress,thissectionsize);*/
-
 		for (codeaddr = 0; codeaddr < thissectionsize; codeaddr++) {
 			/* Write out instruction address */
-			WRITE_REG(slic_regs->slic_wcs,
-				  SLIC_WCS_COMPARE | (baseaddress + codeaddr),
-				  FLUSH);
+			slic_reg32_write(&slic_regs->slic_wcs,
+				SLIC_WCS_COMPARE | (baseaddress + codeaddr),
+				FLUSH);
 			/* Write out instruction to low addr */
-			WRITE_REG(slic_regs->slic_wcs, *instruction, FLUSH);
-#ifdef CONFIG_X86_64
-			instruction = (u32 *)((unsigned char *)instruction + 4);
-#else
-			instruction++;
-#endif
+			slic_reg32_write(&slic_regs->slic_wcs, instruction,
+					 FLUSH);
+			instruction = *(u32 *)(fw->data + index);
+			index += 4;
 			/* Write out instruction to high addr */
-			WRITE_REG(slic_regs->slic_wcs, *instruction, FLUSH);
-#ifdef CONFIG_X86_64
-			instruction = (u32 *)((unsigned char *)instruction + 4);
-#else
-			instruction++;
-#endif
+			slic_reg32_write(&slic_regs->slic_wcs, instruction,
+					 FLUSH);
+			instruction = *(u32 *)(fw->data + index);
+			index += 4;
+
 			/* Check SRAM location zero. If it is non-zero. Abort.*/
-			failure = readl((u32 __iomem *)&slic_regs->slic_reset);
+/*			failure = readl((u32 __iomem *)&slic_regs->slic_reset);
 			if (failure) {
-				DBG_MSG
-				    ("slicoss: %s FAILURE EXIT codeaddr[%x] \
-				    thissectionsize[%x] failure[%x]\n",
-				     __func__, codeaddr, thissectionsize,
-				     failure);
 				release_firmware(fw);
 				return -EIO;
-			}
+			}*/
 		}
 	}
-/*    DBG_MSG ("slicoss: Compare done\n");*/
 	release_firmware(fw);
 	/* Everything OK, kick off the card */
 	mdelay(10);
-	WRITE_REG(slic_regs->slic_wcs, SLIC_WCS_START, FLUSH);
+	slic_reg32_write(&slic_regs->slic_wcs, SLIC_WCS_START, FLUSH);
 
 	/* stall for 20 ms, long enough for ucode to init card
 	   and reach mainloop */
 	mdelay(20);
 
-	DBG_MSG("slicoss: %s (%s) EXIT adapter[%p] card[%p]\n",
-		__func__, adapter->netdev->name, adapter, adapter->card);
-
 	return STATUS_SUCCESS;
 }
 
@@ -2428,19 +1970,10 @@
 {
 	struct sliccard *card = adapter->card;
 
-/*  DBG_MSG ("%s ENTER card->config_set[%x] port[%d] physport[%d] funct#[%d]\n",
-    __func__, card->config_set, adapter->port, adapter->physport,
-    adapter->functionnumber);
-
-    slic_dbg_macaddrs(adapter); */
-
 	if ((adapter->card) && (card->config_set)) {
 		memcpy(adapter->macaddr,
 		       card->config.MacInfo[adapter->functionnumber].macaddrA,
 		       sizeof(struct slic_config_mac));
-/*      DBG_MSG ("%s AFTER copying from config.macinfo into currmacaddr\n",
-	__func__);
-	slic_dbg_macaddrs(adapter);*/
 		if (!(adapter->currmacaddr[0] || adapter->currmacaddr[1] ||
 		      adapter->currmacaddr[2] || adapter->currmacaddr[3] ||
 		      adapter->currmacaddr[4] || adapter->currmacaddr[5])) {
@@ -2451,15 +1984,11 @@
 			       6);
 		}
 	}
-/*  DBG_MSG ("%s EXIT port %d\n", __func__, adapter->port);
-    slic_dbg_macaddrs(adapter); */
 }
 
 static void slic_intagg_set(struct adapter *adapter, u32 value)
 {
-	__iomem struct slic_regs *slic_regs = adapter->slic_regs;
-
-	WRITE_REG(slic_regs->slic_intagg, value, FLUSH);
+	slic_reg32_write(&adapter->slic_regs->slic_intagg, value, FLUSH);
 	adapter->card->loadlevel_current = value;
 }
 
@@ -2485,10 +2014,6 @@
 	struct atk_fru *patkfru;
 	union oemfru *poemfru;
 
-	DBG_MSG
-	    ("slicoss: %s ENTER card[%p] adapter[%p] card->state[%x] \
-	    size[%d]\n", __func__, card, adapter, card->state, card->card_size);
-
 	/* Reset everything except PCI configuration space */
 	slic_soft_reset(adapter);
 
@@ -2496,9 +2021,9 @@
 	status = slic_card_download(adapter);
 
 	if (status != STATUS_SUCCESS) {
-		DBG_ERROR("SLIC download failed bus %d slot %d\n",
-			  (uint) adapter->busnumber,
-			  (uint) adapter->slotnumber);
+		dev_err(&adapter->pcidev->dev,
+			"download failed bus %d slot %d\n",
+			adapter->busnumber, adapter->slotnumber);
 		return status;
 	}
 
@@ -2510,33 +2035,24 @@
 		phys_configl = SLIC_GET_ADDR_LOW(phys_config);
 		phys_configh = SLIC_GET_ADDR_HIGH(phys_config);
 
-		DBG_MSG("slicoss: %s Eeprom info  adapter [%p]\n    "
-			"size        [%x]\n    peeprom     [%p]\n    "
-			"phys_config [%p]\n    phys_configl[%x]\n    "
-			"phys_configh[%x]\n",
-			__func__, adapter,
-			(u32)sizeof(struct slic_eeprom),
-			peeprom, (void *) phys_config, phys_configl,
-			phys_configh);
 		if (!peeprom) {
-			DBG_ERROR
-			    ("SLIC eeprom read failed to get memory bus %d \
-			    slot %d\n",
-			     (uint) adapter->busnumber,
-			     (uint) adapter->slotnumber);
+			dev_err(&adapter->pcidev->dev,
+				"eeprom read failed to get memory "
+				"bus %d slot %d\n", adapter->busnumber,
+				adapter->slotnumber);
 			return -ENOMEM;
 		} else {
 			memset(peeprom, 0, sizeof(struct slic_eeprom));
 		}
-		WRITE_REG(slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
+		slic_reg32_write(&slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
 		mdelay(1);
 		pshmem = (struct slic_shmem *)adapter->phys_shmem;
 
 		spin_lock_irqsave(&adapter->bit64reglock.lock,
 					adapter->bit64reglock.flags);
-		WRITE_REG(slic_regs->slic_addr_upper, 0, DONT_FLUSH);
-		WRITE_REG(slic_regs->slic_isp,
-			  SLIC_GET_ADDR_LOW(&pshmem->isr), FLUSH);
+		slic_reg32_write(&slic_regs->slic_addr_upper, 0, DONT_FLUSH);
+		slic_reg32_write(&slic_regs->slic_isp,
+				 SLIC_GET_ADDR_LOW(&pshmem->isr), FLUSH);
 		spin_unlock_irqrestore(&adapter->bit64reglock.lock,
 					adapter->bit64reglock.flags);
 
@@ -2544,41 +2060,33 @@
 
 		for (;;) {
 			if (adapter->pshmem->isr) {
-				DBG_MSG("%s shmem[%p] shmem->isr[%x]\n",
-					__func__, adapter->pshmem,
-					adapter->pshmem->isr);
-
 				if (adapter->pshmem->isr & ISR_UPC) {
 					adapter->pshmem->isr = 0;
-					WRITE_REG64(adapter,
-						    slic_regs->slic_isp,
-						    0,
-						    slic_regs->slic_addr_upper,
-						    0, FLUSH);
-					WRITE_REG(slic_regs->slic_isr, 0,
-						  FLUSH);
+					slic_reg64_write(adapter,
+						&slic_regs->slic_isp, 0,
+						&slic_regs->slic_addr_upper,
+						0, FLUSH);
+					slic_reg32_write(&slic_regs->slic_isr,
+							 0, FLUSH);
 
 					slic_upr_request_complete(adapter, 0);
 					break;
 				} else {
 					adapter->pshmem->isr = 0;
-					WRITE_REG(slic_regs->slic_isr, 0,
-						  FLUSH);
+					slic_reg32_write(&slic_regs->slic_isr,
+							 0, FLUSH);
 				}
 			} else {
 				mdelay(1);
 				i++;
 				if (i > 5000) {
-					DBG_ERROR
-					    ("SLIC: %d config data fetch timed\
-					      out!\n", adapter->port);
-					DBG_MSG("%s shmem[%p] shmem->isr[%x]\n",
-						__func__, adapter->pshmem,
-						adapter->pshmem->isr);
-					WRITE_REG64(adapter,
-						    slic_regs->slic_isp, 0,
-						    slic_regs->slic_addr_upper,
-						    0, FLUSH);
+					dev_err(&adapter->pcidev->dev,
+						"%d config data fetch timed out!\n",
+						adapter->port);
+					slic_reg64_write(adapter,
+						&slic_regs->slic_isp, 0,
+						&slic_regs->slic_addr_upper,
+						0, FLUSH);
 					return -EINVAL;
 				}
 			}
@@ -2614,7 +2122,7 @@
 			break;
 		}
 
-		card->config.EepromValid = FALSE;
+		card->config.EepromValid = false;
 
 		/*  see if the EEPROM is valid by checking it's checksum */
 		if ((eecodesize <= MAX_EECODE_SIZE) &&
@@ -2633,7 +2141,7 @@
 			    we wouldn't need this shit
 			*/
 			if (ee_chksum == calc_chksum)
-				card->config.EepromValid = TRUE;
+				card->config.EepromValid = true;
 		}
 		/*  copy in the DRAM size */
 		card->config.DramSize = dramsize;
@@ -2643,8 +2151,6 @@
 			memcpy(&card->config.MacInfo[i],
 			       &pmac[i], sizeof(struct slic_config_mac));
 		}
-/*      DBG_MSG ("%s EEPROM Checksum Good? %d  MacAddress\n",__func__,
-		card->config.EepromValid); */
 
 		/*  copy the Alacritech FRU information */
 		card->config.FruFormat = fruformat;
@@ -2654,20 +2160,14 @@
 		pci_free_consistent(adapter->pcidev,
 				    sizeof(struct slic_eeprom),
 				    peeprom, phys_config);
-		DBG_MSG
-		    ("slicoss: %s adapter%d [%p] size[%x] FREE peeprom[%p] \
-		     phys_config[%p]\n",
-		     __func__, adapter->port, adapter,
-		     (u32) sizeof(struct slic_eeprom), peeprom,
-		     (void *) phys_config);
 
 		if ((!card->config.EepromValid) &&
 		    (adapter->reg_params.fail_on_bad_eeprom)) {
-			WRITE_REG64(adapter,
-				    slic_regs->slic_isp,
-				    0, slic_regs->slic_addr_upper, 0, FLUSH);
-			DBG_ERROR
-			    ("unsupported CONFIGURATION  EEPROM invalid\n");
+			slic_reg64_write(adapter, &slic_regs->slic_isp, 0,
+					 &slic_regs->slic_addr_upper,
+					 0, FLUSH);
+			dev_err(&adapter->pcidev->dev,
+				"unsupported CONFIGURATION EEPROM invalid\n");
 			return -EINVAL;
 		}
 
@@ -2675,74 +2175,26 @@
 	}
 
 	if (slic_card_download_gbrcv(adapter)) {
-		DBG_ERROR("%s unable to download GB receive microcode\n",
-			  __func__);
+		dev_err(&adapter->pcidev->dev,
+			"unable to download GB receive microcode\n");
 		return -EINVAL;
 	}
 
-	if (slic_global.dynamic_intagg) {
-		DBG_MSG
-		    ("Dynamic Interrupt Aggregation[ENABLED]: slic%d \
-		     SET intagg to %d\n",
-		     card->cardnum, 0);
+	if (slic_global.dynamic_intagg)
 		slic_intagg_set(adapter, 0);
-	} else {
+	else
 		slic_intagg_set(adapter, intagg_delay);
-		DBG_MSG
-		    ("Dynamic Interrupt Aggregation[DISABLED]: slic%d \
-		     SET intagg to %d\n",
-		     card->cardnum, intagg_delay);
-	}
 
 	/*
 	 *  Initialize ping status to "ok"
 	 */
 	card->pingstatus = ISR_PINGMASK;
 
-#if SLIC_DUMP_ENABLED
-	if (!card->dumpbuffer) {
-		card->dumpbuffer = kmalloc(DUMP_PAGE_SIZE, GFP_ATOMIC);
-
-		ASSERT(card->dumpbuffer);
-		if (card->dumpbuffer == NULL)
-			return -ENOMEM;
-	}
-	/*
-	 *  Smear the shared memory structure and then obtain
-	 *  the PHYSICAL address of this structure
-	 */
-	memset(card->dumpbuffer, 0, DUMP_PAGE_SIZE);
-	card->dumpbuffer_phys = virt_to_bus(card->dumpbuffer);
-	card->dumpbuffer_physh = SLIC_GET_ADDR_HIGH(card->dumpbuffer_phys);
-	card->dumpbuffer_physl = SLIC_GET_ADDR_LOW(card->dumpbuffer_phys);
-
-	/*
-	 *  Allocate COMMAND BUFFER
-	 */
-	if (!card->cmdbuffer) {
-		card->cmdbuffer = kmalloc(sizeof(struct dump_cmd), GFP_ATOMIC);
-
-		ASSERT(card->cmdbuffer);
-		if (card->cmdbuffer == NULL)
-			return -ENOMEM;
-	}
-	/*
-	 *  Smear the shared memory structure and then obtain
-	 *  the PHYSICAL address of this structure
-	 */
-	memset(card->cmdbuffer, 0, sizeof(struct dump_cmd));
-	card->cmdbuffer_phys = virt_to_bus(card->cmdbuffer);
-	card->cmdbuffer_physh = SLIC_GET_ADDR_HIGH(card->cmdbuffer_phys);
-	card->cmdbuffer_physl = SLIC_GET_ADDR_LOW(card->cmdbuffer_phys);
-#endif
-
 	/*
 	 * Lastly, mark our card state as up and return success
 	 */
 	card->state = CARD_UP;
 	card->reset_in_progress = 0;
-	DBG_MSG("slicoss: %s EXIT card[%p] adapter[%p] card->state[%x]\n",
-		__func__, card, adapter, card->state);
 
 	return STATUS_SUCCESS;
 }
@@ -2756,10 +2208,6 @@
 	uint i;
 	uint rdhostid_offset = 0;
 
-	DBG_MSG("slicoss: %s adapter[%p] slot[%x] bus[%x] port[%x]\n",
-		__func__, adapter, adapter->slotnumber, adapter->busnumber,
-		adapter->port);
-
 	switch (adapter->devid) {
 	case SLIC_2GB_DEVICE_ID:
 		rdhostid_offset = SLIC_RDHOSTID_2GB;
@@ -2775,11 +2223,9 @@
 	hostid_reg =
 	    (u16 __iomem *) (((u8 __iomem *) (adapter->slic_regs)) +
 	    rdhostid_offset);
-	DBG_MSG("slicoss: %s *hostid_reg[%p] == ", __func__, hostid_reg);
 
 	/* read the 16 bit hostid from SRAM */
 	card_hostid = (ushort) readw(hostid_reg);
-	DBG_MSG(" card_hostid[%x]\n", card_hostid);
 
 	/* Initialize a new card structure if need be */
 	if (card_hostid == SLIC_HOSTID_DEFAULT) {
@@ -2789,17 +2235,6 @@
 
 		card->next = slic_global.slic_card;
 		slic_global.slic_card = card;
-#if DBG
-		if (adapter->devid == SLIC_2GB_DEVICE_ID) {
-			DBG_MSG
-			    ("SLICOSS ==> Initialize 2 Port Gigabit Server \
-			     and Storage Accelerator\n");
-		} else {
-			DBG_MSG
-			    ("SLICOSS ==> Initialize 1 Port Gigabit Server \
-			     and Storage Accelerator\n");
-		}
-#endif
 		card->busnumber = adapter->busnumber;
 		card->slotnumber = adapter->slotnumber;
 
@@ -2812,23 +2247,11 @@
 			}
 		}
 		slic_global.num_slic_cards++;
-		DBG_MSG("\nCARDNUM == %d  Total %d  Card[%p]\n\n",
-			card->cardnum, slic_global.num_slic_cards, card);
 
 		slic_debug_card_create(card);
 	} else {
-		DBG_MSG
-		    ("slicoss: %s CARD already allocated, find the \
-		     correct card\n", __func__);
 		/* Card exists, find the card this adapter belongs to */
 		while (card) {
-			DBG_MSG
-			    ("slicoss: %s card[%p] slot[%x] bus[%x] \
-			      adaptport[%p] hostid[%x] cardnum[%x]\n",
-			     __func__, card, card->slotnumber,
-			     card->busnumber, card->adapter[adapter->port],
-			     card_hostid, card->cardnum);
-
 			if (card->cardnum == card_hostid)
 				break;
 			card = card->next;
@@ -2861,14 +2284,9 @@
 	}
 	if (!physcard) {
 		/* no structure allocated for this physical card yet */
-		physcard = kzalloc(sizeof(struct physcard), GFP_ATOMIC);
+		physcard = kzalloc(sizeof(struct physcard), GFP_KERNEL);
 		ASSERT(physcard);
 
-		DBG_MSG
-		    ("\n%s Allocate a PHYSICALcard:\n    PHYSICAL_Card[%p]\n\
-		     LogicalCard  [%p]\n    adapter      [%p]\n",
-		     __func__, physcard, card, adapter);
-
 		physcard->next = slic_global.phys_card;
 		slic_global.phys_card = physcard;
 		physcard->adapters_allocd = 1;
@@ -2881,8 +2299,6 @@
 	ASSERT(physcard->adapter[adapter->physport] == NULL);
 	physcard->adapter[adapter->physport] = adapter;
 	adapter->physcard = physcard;
-	DBG_MSG("    PHYSICAL_Port %d    Logical_Port  %d\n", adapter->physport,
-		adapter->port);
 
 	return 0;
 }
@@ -2890,16 +2306,12 @@
 static void slic_soft_reset(struct adapter *adapter)
 {
 	if (adapter->card->state == CARD_UP) {
-		DBG_MSG("slicoss: %s QUIESCE adapter[%p] card[%p] devid[%x]\n",
-			__func__, adapter, adapter->card, adapter->devid);
-		WRITE_REG(adapter->slic_regs->slic_quiesce, 0, FLUSH);
+		slic_reg32_write(&adapter->slic_regs->slic_quiesce, 0, FLUSH);
 		mdelay(1);
 	}
-/*      DBG_MSG ("slicoss: %s (%s) adapter[%p] card[%p] devid[%x]\n",
-	__func__, adapter->netdev->name, adapter, adapter->card,
-	   adapter->devid); */
 
-	WRITE_REG(adapter->slic_regs->slic_reset, SLIC_RESET_MAGIC, FLUSH);
+	slic_reg32_write(&adapter->slic_regs->slic_reset, SLIC_RESET_MAGIC,
+			 FLUSH);
 	mdelay(1);
 }
 
@@ -2909,10 +2321,6 @@
 	u32 RcrReset;
 	__iomem struct slic_regs *slic_regs = adapter->slic_regs;
 
-	DBG_MSG("slicoss: %s (%s) slic_interface_enable[%p](%d)\n",
-		__func__, adapter->netdev->name, adapter,
-		adapter->cardindex);
-
 	if (linkchange) {
 		/* Setup MAC */
 		slic_mac_config(adapter);
@@ -2928,9 +2336,7 @@
 			 GXCR_XMTEN |	/* Enable transmit  */
 			 GXCR_PAUSEEN);	/* Enable pause     */
 
-		DBG_MSG("slicoss: FDX adapt[%p] set xmtcfg to [%x]\n", adapter,
-			value);
-		WRITE_REG(slic_regs->slic_wxcfg, value, FLUSH);
+		slic_reg32_write(&slic_regs->slic_wxcfg, value, FLUSH);
 
 		/* Setup rcvcfg last */
 		value = (RcrReset |	/* Reset, if linkchange */
@@ -2943,9 +2349,7 @@
 		value = (GXCR_RESET |	/* Always reset     */
 			 GXCR_XMTEN);	/* Enable transmit  */
 
-		DBG_MSG("slicoss: HDX adapt[%p] set xmtcfg to [%x]\n", adapter,
-			value);
-		WRITE_REG(slic_regs->slic_wxcfg, value, FLUSH);
+		slic_reg32_write(&slic_regs->slic_wxcfg, value, FLUSH);
 
 		/* Setup rcvcfg last */
 		value = (RcrReset |	/* Reset, if linkchange */
@@ -2962,8 +2366,7 @@
 	if (adapter->macopts & MAC_PROMISC)
 		value |= GRCR_RCVALL;
 
-	DBG_MSG("slicoss: adapt[%p] set rcvcfg to [%x]\n", adapter, value);
-	WRITE_REG(slic_regs->slic_wrcfg, value, FLUSH);
+	slic_reg32_write(&slic_regs->slic_wrcfg, value, FLUSH);
 }
 
 /*
@@ -2979,18 +2382,18 @@
 	value = (GXCR_RESET |	/* Always reset */
 		 GXCR_PAUSEEN);	/* Enable pause */
 
-	WRITE_REG(slic_regs->slic_wxcfg, value, FLUSH);
+	slic_reg32_write(&slic_regs->slic_wxcfg, value, FLUSH);
 
 	value = (GRCR_RESET |	/* Always reset      */
 		 GRCR_CTLEN |	/* Enable CTL frames */
 		 GRCR_ADDRAEN |	/* Address A enable  */
 		 (GRCR_HASHSIZE << GRCR_HASHSIZE_SHIFT));
 
-	WRITE_REG(slic_regs->slic_wrcfg, value, FLUSH);
+	slic_reg32_write(&slic_regs->slic_wrcfg, value, FLUSH);
 
 	/* power down phy */
 	phy_config = (MIICR_REG_PCR | (PCR_POWERDOWN));
-	WRITE_REG(slic_regs->slic_wphy, phy_config, FLUSH);
+	slic_reg32_write(&slic_regs->slic_wphy, phy_config, FLUSH);
 }
 
 static void slic_config_get(struct adapter *adapter, u32 config,
@@ -3012,18 +2415,14 @@
 
 	value = *(u32 *) &adapter->currmacaddr[2];
 	value = ntohl(value);
-	WRITE_REG(slic_regs->slic_wraddral, value, FLUSH);
-	WRITE_REG(slic_regs->slic_wraddrbl, value, FLUSH);
+	slic_reg32_write(&slic_regs->slic_wraddral, value, FLUSH);
+	slic_reg32_write(&slic_regs->slic_wraddrbl, value, FLUSH);
 
 	value2 = (u32) ((adapter->currmacaddr[0] << 8 |
 			     adapter->currmacaddr[1]) & 0xFFFF);
 
-	WRITE_REG(slic_regs->slic_wraddrah, value2, FLUSH);
-	WRITE_REG(slic_regs->slic_wraddrbh, value2, FLUSH);
-
-	DBG_MSG("%s value1[%x] value2[%x] Call slic_mcast_set_mask\n",
-		__func__, value, value2);
-	slic_dbg_macaddrs(adapter);
+	slic_reg32_write(&slic_regs->slic_wraddrah, value2, FLUSH);
+	slic_reg32_write(&slic_regs->slic_wraddrbh, value2, FLUSH);
 
 	/* Write our multicast mask out to the card.  This is done */
 	/* here in addition to the slic_mcast_addr_set routine     */
@@ -3058,7 +2457,7 @@
 	}
 
 	/* write mac config */
-	WRITE_REG(slic_regs->slic_wmcfg, value, FLUSH);
+	slic_reg32_write(&slic_regs->slic_wmcfg, value, FLUSH);
 
 	/* setup mac addresses */
 	slic_mac_address_config(adapter);
@@ -3072,18 +2471,15 @@
 	u16 *dhost2 = (u16 *)&ether_frame->ether_dhost[4];
 	bool equaladdr;
 
-	if (opts & MAC_PROMISC) {
-		DBG_MSG("slicoss: %s (%s) PROMISCUOUS. Accept frame\n",
-			__func__, adapter->netdev->name);
-		return TRUE;
-	}
+	if (opts & MAC_PROMISC)
+		return true;
 
 	if ((*dhost4 == 0xFFFFFFFF) && (*dhost2 == 0xFFFF)) {
 		if (opts & MAC_BCAST) {
 			adapter->rcv_broadcasts++;
-			return TRUE;
+			return true;
 		} else {
-			return FALSE;
+			return false;
 		}
 	}
 
@@ -3091,7 +2487,7 @@
 		if (opts & MAC_ALLMCAST) {
 			adapter->rcv_multicasts++;
 			adapter->stats.multicast++;
-			return TRUE;
+			return true;
 		}
 		if (opts & MAC_MCAST) {
 			struct mcast_address *mcaddr = adapter->mcastaddrs;
@@ -3103,20 +2499,20 @@
 				if (equaladdr) {
 					adapter->rcv_multicasts++;
 					adapter->stats.multicast++;
-					return TRUE;
+					return true;
 				}
 				mcaddr = mcaddr->next;
 			}
-			return FALSE;
+			return false;
 		} else {
-			return FALSE;
+			return false;
 		}
 	}
 	if (opts & MAC_DIRECTED) {
 		adapter->rcv_unicasts++;
-		return TRUE;
+		return true;
 	}
-	return FALSE;
+	return false;
 
 }
 
@@ -3125,80 +2521,28 @@
 	struct adapter *adapter = (struct adapter *)netdev_priv(dev);
 	struct sockaddr *addr = ptr;
 
-	DBG_MSG("%s ENTER (%s)\n", __func__, adapter->netdev->name);
-
 	if (netif_running(dev))
 		return -EBUSY;
 	if (!adapter)
 		return -EBUSY;
-	DBG_MSG("slicoss: %s (%s) curr %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
-		__func__, adapter->netdev->name, adapter->currmacaddr[0],
-		adapter->currmacaddr[1], adapter->currmacaddr[2],
-		adapter->currmacaddr[3], adapter->currmacaddr[4],
-		adapter->currmacaddr[5]);
+
 	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
 	memcpy(adapter->currmacaddr, addr->sa_data, dev->addr_len);
-	DBG_MSG("slicoss: %s (%s) new %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
-		__func__, adapter->netdev->name, adapter->currmacaddr[0],
-		adapter->currmacaddr[1], adapter->currmacaddr[2],
-		adapter->currmacaddr[3], adapter->currmacaddr[4],
-		adapter->currmacaddr[5]);
 
-	slic_config_set(adapter, TRUE);
+	slic_config_set(adapter, true);
 	return 0;
 }
 
-/*
- *  slic_timer_get_stats
- *
- * Timer function used to suck the statistics out of the card every
- * 50 seconds or whatever STATS_TIMER_INTERVAL is set to.
- *
- */
-#if SLIC_GET_STATS_TIMER_ENABLED
-static void slic_timer_get_stats(ulong dev)
-{
-	struct adapter *adapter;
-	struct sliccard *card;
-	struct slic_shmem *pshmem;
-
-	ASSERT(dev);
-	adapter = netdev_priv((struct net_device *)dev);
-	ASSERT(adapter);
-	card = adapter->card;
-	ASSERT(card);
-
-	if ((card->state == CARD_UP) &&
-	    (adapter->state == ADAPT_UP) && (adapter->linkstate == LINK_UP)) {
-		pshmem = (struct slic_shmem *)adapter->phys_shmem;
-#ifdef CONFIG_X86_64
-		slic_upr_request(adapter,
-				 SLIC_UPR_STATS,
-				 SLIC_GET_ADDR_LOW(&pshmem->inicstats),
-				 SLIC_GET_ADDR_HIGH(&pshmem->inicstats), 0, 0);
-#elif defined(CONFIG_X86)
-		slic_upr_request(adapter,
-				 SLIC_UPR_STATS,
-				 (u32) &pshmem->inicstats, 0, 0, 0);
-#else
-		Stop compilation;
-#endif
-	} else {
-/*		DBG_MSG ("slicoss: %s adapter[%p] linkstate[%x] NOT UP!\n",
-			__func__, adapter, adapter->linkstate); */
-	}
-	adapter->statstimer.expires = jiffies +
-	    SLIC_SECS_TO_JIFFS(STATS_TIMER_INTERVAL);
-	add_timer(&adapter->statstimer);
-}
-#endif
 static void slic_timer_load_check(ulong cardaddr)
 {
 	struct sliccard *card = (struct sliccard *)cardaddr;
 	struct adapter *adapter = card->master;
+	u32 __iomem *intagg;
 	u32 load = card->events;
 	u32 level = 0;
 
+	intagg = &adapter->slic_regs->slic_intagg;
+
 	if ((adapter) && (adapter->state == ADAPT_UP) &&
 	    (card->state == CARD_UP) && (slic_global.dynamic_intagg)) {
 		if (adapter->devid == SLIC_1GB_DEVICE_ID) {
@@ -3220,8 +2564,7 @@
 			}
 			if (card->loadlevel_current != level) {
 				card->loadlevel_current = level;
-				WRITE_REG(adapter->slic_regs->slic_intagg,
-					  level, FLUSH);
+				slic_reg32_write(intagg, level, FLUSH);
 			}
 		} else {
 			if (load > SLIC_LOAD_5)
@@ -3238,14 +2581,12 @@
 				level = SLIC_INTAGG_0;
 			if (card->loadlevel_current != level) {
 				card->loadlevel_current = level;
-				WRITE_REG(adapter->slic_regs->slic_intagg,
-					  level, FLUSH);
+				slic_reg32_write(intagg, level, FLUSH);
 			}
 		}
 	}
 	card->events = 0;
-	card->loadtimer.expires =
-	    jiffies + SLIC_SECS_TO_JIFFS(SLIC_LOADTIMER_PERIOD);
+	card->loadtimer.expires = jiffies + (SLIC_LOADTIMER_PERIOD * HZ);
 	add_timer(&card->loadtimer);
 }
 
@@ -3256,7 +2597,8 @@
 	cpuid = smp_processor_id();
 	curr_pid = current->pid;
 
-	DBG_ERROR("%s CPU # %d ---- PID # %d\n", __func__, cpuid, curr_pid);
+	printk(KERN_ERR "%s CPU # %d ---- PID # %d\n",
+	       __func__, cpuid, curr_pid);
 }
 
 static int slic_upr_queue_request(struct adapter *adapter,
@@ -3269,11 +2611,9 @@
 	struct slic_upr *uprqueue;
 
 	upr = kmalloc(sizeof(struct slic_upr), GFP_ATOMIC);
-	if (!upr) {
-		DBG_MSG("%s COULD NOT ALLOCATE UPR MEM\n", __func__);
-
+	if (!upr)
 		return -ENOMEM;
-	}
+
 	upr->adapter = adapter->port;
 	upr->upr_request = upr_request;
 	upr->upr_data = upr_data;
@@ -3322,10 +2662,6 @@
 	struct sliccard *card = adapter->card;
 	struct slic_upr *upr;
 
-/*    if (card->dump_requested) {
-	DBG_MSG("ENTER slic_upr_request_complete Dump in progress ISR[%x]\n",
-		isr);
-      } */
 	spin_lock_irqsave(&adapter->upr_lock.lock, adapter->upr_lock.flags);
 	upr = adapter->upr_list;
 	if (!upr) {
@@ -3341,38 +2677,19 @@
 	switch (upr->upr_request) {
 	case SLIC_UPR_STATS:
 		{
-#if SLIC_GET_STATS_ENABLED
 			struct slic_stats *slicstats =
 			    (struct slic_stats *) &adapter->pshmem->inicstats;
 			struct slic_stats *newstats = slicstats;
 			struct slic_stats  *old = &adapter->inicstats_prev;
 			struct slicnet_stats *stst = &adapter->slic_stats;
-#endif
+
 			if (isr & ISR_UPCERR) {
-				DBG_ERROR
-				    ("SLIC_UPR_STATS command failed isr[%x]\n",
-				     isr);
+				dev_err(&adapter->netdev->dev,
+					"SLIC_UPR_STATS command failed isr[%x]\n",
+					isr);
 
 				break;
 			}
-#if SLIC_GET_STATS_ENABLED
-/*			DBG_MSG ("slicoss: %s rcv %lx:%lx:%lx:%lx:%lx %lx %lx "
-				"xmt %lx:%lx:%lx:%lx:%lx %lx %lx\n",
-				 __func__,
-			     slicstats->rcv_unicasts100,
-			     slicstats->rcv_bytes100,
-			     slicstats->rcv_bytes100,
-			     slicstats->rcv_tcp_bytes100,
-			     slicstats->rcv_tcp_segs100,
-			     slicstats->rcv_other_error100,
-			     slicstats->rcv_drops100,
-			     slicstats->xmit_unicasts100,
-			     slicstats->xmit_bytes100,
-			     slicstats->xmit_bytes100,
-			     slicstats->xmit_tcp_bytes100,
-			     slicstats->xmit_tcp_segs100,
-			     slicstats->xmit_other_error100,
-			     slicstats->xmit_collisions100);*/
 			UPDATE_STATS_GB(stst->tcp.xmit_tcp_segs,
 					newstats->xmit_tcp_segs_gb,
 					old->xmit_tcp_segs_gb);
@@ -3431,7 +2748,6 @@
 				     old->rcv_drops_gb);
 			}
 			memcpy(old, newstats, sizeof(struct slic_stats));
-#endif
 			break;
 		}
 	case SLIC_UPR_RLSR:
@@ -3454,11 +2770,6 @@
 	case SLIC_UPR_PING:
 		card->pingstatus |= (isr & ISR_PINGDSMASK);
 		break;
-#if SLIC_DUMP_ENABLED
-	case SLIC_UPR_DUMP:
-		card->dumpstatus |= (isr & ISR_UPCMASK);
-		break;
-#endif
 	default:
 		ASSERT(0);
 	}
@@ -3487,74 +2798,29 @@
 	switch (upr->upr_request) {
 	case SLIC_UPR_STATS:
 		if (upr->upr_data_h == 0) {
-			WRITE_REG(slic_regs->slic_stats, upr->upr_data, FLUSH);
+			slic_reg32_write(&slic_regs->slic_stats, upr->upr_data,
+					 FLUSH);
 		} else {
-			WRITE_REG64(adapter,
-				    slic_regs->slic_stats64,
-				    upr->upr_data,
-				    slic_regs->slic_addr_upper,
-				    upr->upr_data_h, FLUSH);
+			slic_reg64_write(adapter, &slic_regs->slic_stats64,
+					 upr->upr_data,
+					 &slic_regs->slic_addr_upper,
+					 upr->upr_data_h, FLUSH);
 		}
 		break;
 
 	case SLIC_UPR_RLSR:
-		WRITE_REG64(adapter,
-			    slic_regs->slic_rlsr,
-			    upr->upr_data,
-			    slic_regs->slic_addr_upper, upr->upr_data_h, FLUSH);
+		slic_reg64_write(adapter, &slic_regs->slic_rlsr, upr->upr_data,
+				 &slic_regs->slic_addr_upper, upr->upr_data_h,
+				 FLUSH);
 		break;
 
 	case SLIC_UPR_RCONFIG:
-		DBG_MSG("%s SLIC_UPR_RCONFIG!!!!\n", __func__);
-		DBG_MSG("WRITE_REG64 adapter[%p]\n"
-			"    a->slic_regs[%p] slic_regs[%p]\n"
-			"    &slic_rconfig[%p] &slic_addr_upper[%p]\n"
-			"    upr[%p]\n"
-			"    uprdata[%x] uprdatah[%x]\n",
-			adapter, adapter->slic_regs, slic_regs,
-			&slic_regs->slic_rconfig, &slic_regs->slic_addr_upper,
-			upr, upr->upr_data, upr->upr_data_h);
-		WRITE_REG64(adapter,
-			    slic_regs->slic_rconfig,
-			    upr->upr_data,
-			    slic_regs->slic_addr_upper, upr->upr_data_h, FLUSH);
+		slic_reg64_write(adapter, &slic_regs->slic_rconfig,
+				 upr->upr_data, &slic_regs->slic_addr_upper,
+				 upr->upr_data_h, FLUSH);
 		break;
-#if SLIC_DUMP_ENABLED
-	case SLIC_UPR_DUMP:
-#if 0
-		DBG_MSG("%s SLIC_UPR_DUMP!!!!\n", __func__);
-		DBG_MSG("WRITE_REG64 adapter[%p]\n"
-			 "    upr_buffer[%x]   upr_bufferh[%x]\n"
-			 "    upr_data[%x]     upr_datah[%x]\n"
-			 "    cmdbuff[%p] cmdbuffP[%p]\n"
-			 "    dumpbuff[%p] dumpbuffP[%p]\n",
-			 adapter, upr->upr_buffer, upr->upr_buffer_h,
-			 upr->upr_data, upr->upr_data_h,
-			 adapter->card->cmdbuffer,
-			 (void *)adapter->card->cmdbuffer_phys,
-			 adapter->card->dumpbuffer, (
-			 void *)adapter->card->dumpbuffer_phys);
-
-		ptr1 = (char *)slic_regs;
-		ptr2 = (char *)(&slic_regs->slic_dump_cmd);
-		cmdoffset = ptr2 - ptr1;
-		DBG_MSG("slic_dump_cmd register offset [%x]\n", cmdoffset);
-#endif
-		if (upr->upr_buffer || upr->upr_buffer_h) {
-			WRITE_REG64(adapter,
-				    slic_regs->slic_dump_data,
-				    upr->upr_buffer,
-				    slic_regs->slic_addr_upper,
-				    upr->upr_buffer_h, FLUSH);
-		}
-		WRITE_REG64(adapter,
-			    slic_regs->slic_dump_cmd,
-			    upr->upr_data,
-			    slic_regs->slic_addr_upper, upr->upr_data_h, FLUSH);
-		break;
-#endif
 	case SLIC_UPR_PING:
-		WRITE_REG(slic_regs->slic_ping, 1, FLUSH);
+		slic_reg32_write(&slic_regs->slic_ping, 1, FLUSH);
 		break;
 	default:
 		ASSERT(0);
@@ -3568,10 +2834,6 @@
 	unsigned char linkspeed;
 	unsigned char linkduplex;
 
-	DBG_MSG("%s: %s ISR[%x] linkstatus[%x]\n   adapter[%p](%d)\n",
-		__func__, adapter->netdev->name, isr, linkstatus, adapter,
-		adapter->cardindex);
-
 	if ((isr & ISR_UPCERR) || (isr & ISR_UPCBSY)) {
 		struct slic_shmem *pshmem;
 
@@ -3599,50 +2861,33 @@
 	       || (adapter->devid == SLIC_2GB_DEVICE_ID));
 
 	linkup = linkstatus & GIG_LINKUP ? LINK_UP : LINK_DOWN;
-	if (linkstatus & GIG_SPEED_1000) {
+	if (linkstatus & GIG_SPEED_1000)
 		linkspeed = LINK_1000MB;
-		DBG_MSG("slicoss: %s (%s) GIGABIT Speed==1000MB  ",
-			__func__, adapter->netdev->name);
-	} else if (linkstatus & GIG_SPEED_100) {
+	else if (linkstatus & GIG_SPEED_100)
 		linkspeed = LINK_100MB;
-		DBG_MSG("slicoss: %s (%s) GIGABIT Speed==100MB  ", __func__,
-			adapter->netdev->name);
-	} else {
+	else
 		linkspeed = LINK_10MB;
-		DBG_MSG("slicoss: %s (%s) GIGABIT Speed==10MB  ", __func__,
-			adapter->netdev->name);
-	}
-	if (linkstatus & GIG_FULLDUPLEX) {
-		linkduplex = LINK_FULLD;
-		DBG_MSG(" Duplex == FULL\n");
-	} else {
-		linkduplex = LINK_HALFD;
-		DBG_MSG(" Duplex == HALF\n");
-	}
 
-	if ((adapter->linkstate == LINK_DOWN) && (linkup == LINK_DOWN)) {
-		DBG_MSG("slicoss: %s (%s) physport(%d) link still down\n",
-			__func__, adapter->netdev->name, adapter->physport);
+	if (linkstatus & GIG_FULLDUPLEX)
+		linkduplex = LINK_FULLD;
+	else
+		linkduplex = LINK_HALFD;
+
+	if ((adapter->linkstate == LINK_DOWN) && (linkup == LINK_DOWN))
 		return;
-	}
 
 	/* link up event, but nothing has changed */
 	if ((adapter->linkstate == LINK_UP) &&
 	    (linkup == LINK_UP) &&
 	    (adapter->linkspeed == linkspeed) &&
-	    (adapter->linkduplex == linkduplex)) {
-		DBG_MSG("slicoss: %s (%s) port(%d) link still up\n",
-			__func__, adapter->netdev->name, adapter->physport);
+	    (adapter->linkduplex == linkduplex))
 		return;
-	}
 
 	/* link has changed at this point */
 
 	/* link has gone from up to down */
 	if (linkup == LINK_DOWN) {
 		adapter->linkstate = LINK_DOWN;
-		DBG_MSG("slicoss: %s %d LinkDown!\n", __func__,
-			adapter->physport);
 		return;
 	}
 
@@ -3652,30 +2897,10 @@
 
 	if (adapter->linkstate != LINK_UP) {
 		/* setup the mac */
-		DBG_MSG("%s call slic_config_set\n", __func__);
-		slic_config_set(adapter, TRUE);
+		slic_config_set(adapter, true);
 		adapter->linkstate = LINK_UP;
-		DBG_MSG("\n(%s) Link UP: CALL slic_if_start_queue",
-			adapter->netdev->name);
-		slic_if_start_queue(adapter);
+		netif_start_queue(adapter->netdev);
 	}
-#if 1
-	switch (linkspeed) {
-	case LINK_1000MB:
-		DBG_MSG
-		    ("\n(%s) LINK UP!: GIGABIT SPEED == 1000MB  duplex[%x]\n",
-		     adapter->netdev->name, adapter->linkduplex);
-		break;
-	case LINK_100MB:
-		DBG_MSG("\n(%s) LINK UP!: SPEED == 100MB  duplex[%x]\n",
-			adapter->netdev->name, adapter->linkduplex);
-		break;
-	default:
-		DBG_MSG("\n(%s) LINK UP!: SPEED == 10MB  duplex[%x]\n",
-			adapter->netdev->name, adapter->linkduplex);
-		break;
-	}
-#endif
 }
 
 /*
@@ -3787,20 +3012,18 @@
 	__iomem struct slic_regs *slic_regs = adapter->slic_regs;
 	u32 paddrh = 0;
 
-	DBG_MSG("slicoss: %s (%s) ENTER adapter[%p]\n", __func__,
-		adapter->netdev->name, adapter);
 	ASSERT(adapter->state == ADAPT_DOWN);
 	memset(rspq, 0, sizeof(struct slic_rspqueue));
 
 	rspq->num_pages = SLIC_RSPQ_PAGES_GB;
 
 	for (i = 0; i < rspq->num_pages; i++) {
-		rspq->vaddr[i] =
-		    pci_alloc_consistent(adapter->pcidev, PAGE_SIZE,
-					 &rspq->paddr[i]);
+		rspq->vaddr[i] = pci_alloc_consistent(adapter->pcidev,
+						      PAGE_SIZE,
+						      &rspq->paddr[i]);
 		if (!rspq->vaddr[i]) {
-			DBG_ERROR
-			    ("rspqueue_init_failed  pci_alloc_consistent\n");
+			dev_err(&adapter->pcidev->dev,
+				"pci_alloc_consistent failed\n");
 			slic_rspqueue_free(adapter);
 			return STATUS_FAILURE;
 		}
@@ -3811,47 +3034,21 @@
 		       (u32) rspq->paddr[i]);
 #endif
 		memset(rspq->vaddr[i], 0, PAGE_SIZE);
-/*              DBG_MSG("slicoss: %s UPLOAD RSPBUFF Page pageix[%x] paddr[%p] "
-			"vaddr[%p]\n",
-			__func__, i, (void *)rspq->paddr[i], rspq->vaddr[i]); */
 
 		if (paddrh == 0) {
-			WRITE_REG(slic_regs->slic_rbar,
-				  (rspq->paddr[i] | SLIC_RSPQ_BUFSINPAGE),
-				  DONT_FLUSH);
+			slic_reg32_write(&slic_regs->slic_rbar,
+				(rspq->paddr[i] | SLIC_RSPQ_BUFSINPAGE),
+				DONT_FLUSH);
 		} else {
-			WRITE_REG64(adapter,
-				    slic_regs->slic_rbar64,
-				    (rspq->paddr[i] | SLIC_RSPQ_BUFSINPAGE),
-				    slic_regs->slic_addr_upper,
-				    paddrh, DONT_FLUSH);
+			slic_reg64_write(adapter, &slic_regs->slic_rbar64,
+				(rspq->paddr[i] | SLIC_RSPQ_BUFSINPAGE),
+				&slic_regs->slic_addr_upper,
+				paddrh, DONT_FLUSH);
 		}
 	}
 	rspq->offset = 0;
 	rspq->pageindex = 0;
 	rspq->rspbuf = (struct slic_rspbuf *)rspq->vaddr[0];
-	DBG_MSG("slicoss: %s (%s) EXIT adapter[%p]\n", __func__,
-		adapter->netdev->name, adapter);
-	return STATUS_SUCCESS;
-}
-
-static int slic_rspqueue_reset(struct adapter *adapter)
-{
-	struct slic_rspqueue *rspq = &adapter->rspqueue;
-
-	DBG_MSG("slicoss: %s (%s) ENTER adapter[%p]\n", __func__,
-		adapter->netdev->name, adapter);
-	ASSERT(adapter->state == ADAPT_DOWN);
-	ASSERT(rspq);
-
-	DBG_MSG("slicoss: Nothing to do. rspq[%p]\n"
-		"                             offset[%x]\n"
-		"                             pageix[%x]\n"
-		"                             rspbuf[%p]\n",
-		rspq, rspq->offset, rspq->pageindex, rspq->rspbuf);
-
-	DBG_MSG("slicoss: %s (%s) EXIT adapter[%p]\n", __func__,
-		adapter->netdev->name, adapter);
 	return STATUS_SUCCESS;
 }
 
@@ -3860,14 +3057,8 @@
 	int i;
 	struct slic_rspqueue *rspq = &adapter->rspqueue;
 
-	DBG_MSG("slicoss: %s adapter[%p] port %d rspq[%p] FreeRSPQ\n",
-		__func__, adapter, adapter->physport, rspq);
 	for (i = 0; i < rspq->num_pages; i++) {
 		if (rspq->vaddr[i]) {
-			DBG_MSG
-			    ("slicoss:  pci_free_consistent rspq->vaddr[%p] \
-			    paddr[%p]\n",
-			     rspq->vaddr[i], (void *) rspq->paddr[i]);
 			pci_free_consistent(adapter->pcidev, PAGE_SIZE,
 					    rspq->vaddr[i], rspq->paddr[i]);
 		}
@@ -3900,11 +3091,9 @@
 #endif
 	} else {
 		ASSERT(rspq->offset == SLIC_RSPQ_BUFSINPAGE);
-		WRITE_REG64(adapter,
-			    adapter->slic_regs->slic_rbar64,
-			    (rspq->
-			     paddr[rspq->pageindex] | SLIC_RSPQ_BUFSINPAGE),
-			    adapter->slic_regs->slic_addr_upper, 0, DONT_FLUSH);
+		slic_reg64_write(adapter, &adapter->slic_regs->slic_rbar64,
+			(rspq->paddr[rspq->pageindex] | SLIC_RSPQ_BUFSINPAGE),
+			&adapter->slic_regs->slic_addr_upper, 0, DONT_FLUSH);
 		rspq->pageindex = (++rspq->pageindex) % rspq->num_pages;
 		rspq->offset = 0;
 		rspq->rspbuf = (struct slic_rspbuf *)
@@ -3932,12 +3121,8 @@
 	struct slic_cmdqmem *cmdqmem = &adapter->cmdqmem;
 	int i;
 
-	DBG_MSG("slicoss: (%s) adapter[%p] port %d rspq[%p] Free CMDQ Memory\n",
-		__func__, adapter, adapter->physport, cmdqmem);
 	for (i = 0; i < SLIC_CMDQ_MAXPAGES; i++) {
 		if (cmdqmem->pages[i]) {
-			DBG_MSG("slicoss: %s Deallocate page  CmdQPage[%p]\n",
-				__func__, (void *) cmdqmem->pages[i]);
 			pci_free_consistent(adapter->pcidev,
 					    PAGE_SIZE,
 					    (void *) cmdqmem->pages[i],
@@ -3972,7 +3157,6 @@
 	int i;
 	u32 *pageaddr;
 
-	DBG_MSG("slicoss: %s ENTER adapter[%p]\n", __func__, adapter);
 	ASSERT(adapter->state == ADAPT_DOWN);
 	memset(&adapter->cmdq_all, 0, sizeof(struct slic_cmdqueue));
 	memset(&adapter->cmdq_free, 0, sizeof(struct slic_cmdqueue));
@@ -3994,7 +3178,6 @@
 		slic_cmdq_addcmdpage(adapter, pageaddr);
 	}
 	adapter->slic_handle_ix = 1;
-	DBG_MSG("slicoss: %s reset slic_handle_ix to ONE\n", __func__);
 
 	return STATUS_SUCCESS;
 }
@@ -4003,8 +3186,6 @@
 {
 	struct slic_hostcmd *cmd;
 
-	DBG_MSG("slicoss: %s adapter[%p] port %d FreeCommandsFrom CMDQ\n",
-		__func__, adapter, adapter->physport);
 	cmd = adapter->cmdq_all.head;
 	while (cmd) {
 		if (cmd->busy) {
@@ -4030,7 +3211,6 @@
 	struct sk_buff *skb;
 	u32 outstanding;
 
-	DBG_MSG("%s ENTER adapter[%p]\n", __func__, adapter);
 	spin_lock_irqsave(&adapter->cmdq_free.lock.lock,
 			adapter->cmdq_free.lock.flags);
 	spin_lock_irqsave(&adapter->cmdq_done.lock.lock,
@@ -4042,11 +3222,8 @@
 		if (hcmd->busy) {
 			skb = hcmd->skb;
 			ASSERT(skb);
-			DBG_MSG("slicoss: %s hcmd[%p] skb[%p] ", __func__,
-				hcmd, skb);
 			hcmd->busy = 0;
 			hcmd->skb = NULL;
-			DBG_MSG(" Free SKB\n");
 			dev_kfree_skb_irq(skb);
 		}
 		hcmd = hcmd->next_all;
@@ -4065,14 +3242,14 @@
 		hcmd = hcmd->next_all;
 	}
 	if (adapter->cmdq_free.count != adapter->cmdq_all.count) {
-		DBG_ERROR("%s free_count %d != all count %d\n", __func__,
-			  adapter->cmdq_free.count, adapter->cmdq_all.count);
+		dev_err(&adapter->netdev->dev,
+			"free_count %d != all count %d\n",
+			adapter->cmdq_free.count, adapter->cmdq_all.count);
 	}
 	spin_unlock_irqrestore(&adapter->cmdq_done.lock.lock,
 				adapter->cmdq_done.lock.flags);
 	spin_unlock_irqrestore(&adapter->cmdq_free.lock.lock,
 				adapter->cmdq_free.lock.flags);
-	DBG_MSG("%s EXIT adapter[%p]\n", __func__, adapter);
 }
 
 static void slic_cmdq_addcmdpage(struct adapter *adapter, u32 *page)
@@ -4090,8 +3267,6 @@
 
 	cmdaddr = page;
 	cmd = (struct slic_hostcmd *)cmdaddr;
-/*  DBG_MSG("CMDQ Page addr[%p] ix[%d] pfree[%p]\n", cmdaddr, slic_handle_ix,
-    adapter->pfree_slic_handles); */
 	cmdcnt = 0;
 
 	phys_addr = virt_to_bus((void *)page);
@@ -4117,7 +3292,7 @@
 
 		cmd->pslic_handle = pslic_handle;
 		cmd->cmd64.hosthandle = pslic_handle->token.handle_token;
-		cmd->busy = FALSE;
+		cmd->busy = false;
 		cmd->paddrl = phys_addrl;
 		cmd->paddrh = phys_addrh;
 		cmd->next_all = prev;
@@ -4133,13 +3308,11 @@
 	cmdq = &adapter->cmdq_all;
 	cmdq->count += cmdcnt;	/*  SLIC_CMDQ_CMDSINPAGE;   mooktodo */
 	tail->next_all = cmdq->head;
-	ASSERT(VALID_ADDRESS(prev));
 	cmdq->head = prev;
 	cmdq = &adapter->cmdq_free;
 	spin_lock_irqsave(&cmdq->lock.lock, cmdq->lock.flags);
 	cmdq->count += cmdcnt;	/*  SLIC_CMDQ_CMDSINPAGE;   mooktodo */
 	tail->next = cmdq->head;
-	ASSERT(VALID_ADDRESS(prev));
 	cmdq->head = prev;
 	spin_unlock_irqrestore(&cmdq->lock.lock, cmdq->lock.flags);
 }
@@ -4184,7 +3357,6 @@
 
 	ASSERT(free_cmdq->head == NULL);
 	spin_lock_irqsave(&done_cmdq->lock.lock, done_cmdq->lock.flags);
-	ASSERT(VALID_ADDRESS(done_cmdq->head));
 
 	free_cmdq->head = done_cmdq->head;
 	free_cmdq->count = done_cmdq->count;
@@ -4201,9 +3373,7 @@
 
 	spin_lock(&cmdq->lock.lock);
 	cmd->busy = 0;
-	ASSERT(VALID_ADDRESS(cmdq->head));
 	cmd->next = cmdq->head;
-	ASSERT(VALID_ADDRESS(cmd));
 	cmdq->head = cmd;
 	cmdq->count++;
 	if ((adapter->xmitq_full) && (cmdq->count > 10))
@@ -4216,7 +3386,6 @@
 	int i, count;
 	struct slic_rcvqueue *rcvq = &adapter->rcvqueue;
 
-	DBG_MSG("slicoss: %s ENTER adapter[%p]\n", __func__, adapter);
 	ASSERT(adapter->state == ADAPT_DOWN);
 	rcvq->tail = NULL;
 	rcvq->head = NULL;
@@ -4233,25 +3402,6 @@
 		slic_rcvqueue_free(adapter);
 		return STATUS_FAILURE;
 	}
-	DBG_MSG("slicoss: %s EXIT adapter[%p]\n", __func__, adapter);
-	return STATUS_SUCCESS;
-}
-
-static int slic_rcvqueue_reset(struct adapter *adapter)
-{
-	struct slic_rcvqueue *rcvq = &adapter->rcvqueue;
-
-	DBG_MSG("slicoss: %s ENTER adapter[%p]\n", __func__, adapter);
-	ASSERT(adapter->state == ADAPT_DOWN);
-	ASSERT(rcvq);
-
-	DBG_MSG("slicoss: Nothing to do. rcvq[%p]\n"
-		"                             count[%x]\n"
-		"                             head[%p]\n"
-		"                             tail[%p]\n",
-		rcvq, rcvq->count, rcvq->head, rcvq->tail);
-
-	DBG_MSG("slicoss: %s EXIT adapter[%p]\n", __func__, adapter);
 	return STATUS_SUCCESS;
 }
 
@@ -4290,8 +3440,8 @@
 			skb = NULL;
 		}
 	} else {
-		DBG_ERROR("RcvQ Empty!! adapter[%p] rcvq[%p] count[%x]\n",
-			  adapter, rcvq, rcvq->count);
+		dev_err(&adapter->netdev->dev,
+			"RcvQ Empty!! rcvq[%p] count[%x]\n", rcvq, rcvq->count);
 		skb = NULL;
 	}
 	while (rcvq->count < SLIC_RCVQ_FILLTHRESH) {
@@ -4311,6 +3461,7 @@
 	u32 paddrh;
 	struct slic_rcvqueue *rcvq = &adapter->rcvqueue;
 	int i = 0;
+	struct device *dev = &adapter->netdev->dev;
 
 	while (i < SLIC_RCVQ_FILLENTRIES) {
 		struct slic_rcvbuf *rcvbuf;
@@ -4333,44 +3484,45 @@
 			skb->next = NULL;
 #ifdef KLUDGE_FOR_4GB_BOUNDARY
 			if (paddrl == 0) {
-				DBG_ERROR
-				    ("%s: LOW 32bits PHYSICAL ADDRESS == 0 "
-				     "skb[%p]   PROBLEM\n"
-				     "         skbdata[%p]\n"
-				     "         skblen[%x]\n"
-				     "         paddr[%p]\n"
-				     "         paddrl[%x]\n"
-				     "         paddrh[%x]\n", __func__, skb,
-				     skb->data, skb->len, paddr, paddrl,
-				     paddrh);
-				DBG_ERROR("         rcvq->head[%p]\n"
-					  "         rcvq->tail[%p]\n"
-					  "         rcvq->count[%x]\n",
-					  rcvq->head, rcvq->tail, rcvq->count);
-				DBG_ERROR("SKIP THIS SKB!!!!!!!!\n");
+				dev_err(dev, "%s: LOW 32bits PHYSICAL ADDRESS == 0\n",
+					__func__);
+				dev_err(dev, "skb[%p] PROBLEM\n", skb);
+				dev_err(dev, "         skbdata[%p]\n", skb->data);
+				dev_err(dev, "         skblen[%x]\n", skb->len);
+				dev_err(dev, "         paddr[%p]\n", paddr);
+				dev_err(dev, "         paddrl[%x]\n", paddrl);
+				dev_err(dev, "         paddrh[%x]\n", paddrh);
+				dev_err(dev, "         rcvq->head[%p]\n", rcvq->head);
+				dev_err(dev, "         rcvq->tail[%p]\n", rcvq->tail);
+				dev_err(dev, "         rcvq->count[%x]\n", rcvq->count);
+				dev_err(dev, "SKIP THIS SKB!!!!!!!!\n");
 				goto retry_rcvqfill;
 			}
 #else
 			if (paddrl == 0) {
-				DBG_ERROR
-				    ("\n\n%s: LOW 32bits PHYSICAL ADDRESS == 0 "
-				     "skb[%p]  GIVE TO CARD ANYWAY\n"
-				     "         skbdata[%p]\n"
-				     "         paddr[%p]\n"
-				     "         paddrl[%x]\n"
-				     "         paddrh[%x]\n", __func__, skb,
-				     skb->data, paddr, paddrl, paddrh);
+				dev_err(dev, "%s: LOW 32bits PHYSICAL ADDRESS == 0\n",
+					__func__);
+				dev_err(dev, "skb[%p] PROBLEM\n", skb);
+				dev_err(dev, "         skbdata[%p]\n", skb->data);
+				dev_err(dev, "         skblen[%x]\n", skb->len);
+				dev_err(dev, "         paddr[%p]\n", paddr);
+				dev_err(dev, "         paddrl[%x]\n", paddrl);
+				dev_err(dev, "         paddrh[%x]\n", paddrh);
+				dev_err(dev, "         rcvq->head[%p]\n", rcvq->head);
+				dev_err(dev, "         rcvq->tail[%p]\n", rcvq->tail);
+				dev_err(dev, "         rcvq->count[%x]\n", rcvq->count);
+				dev_err(dev, "GIVE TO CARD ANYWAY\n");
 			}
 #endif
 			if (paddrh == 0) {
-				WRITE_REG(adapter->slic_regs->slic_hbar,
-					  (u32) paddrl, DONT_FLUSH);
+				slic_reg32_write(&adapter->slic_regs->slic_hbar,
+						 (u32)paddrl, DONT_FLUSH);
 			} else {
-				WRITE_REG64(adapter,
-					    adapter->slic_regs->slic_hbar64,
-					    (u32) paddrl,
-					    adapter->slic_regs->slic_addr_upper,
-					    (u32) paddrh, DONT_FLUSH);
+				slic_reg64_write(adapter,
+					&adapter->slic_regs->slic_hbar64,
+					paddrl,
+					&adapter->slic_regs->slic_addr_upper,
+					paddrh, DONT_FLUSH);
 			}
 			if (rcvq->head)
 				rcvq->tail->next = skb;
@@ -4380,10 +3532,9 @@
 			rcvq->count++;
 			i++;
 		} else {
-			DBG_ERROR
-			    ("%s slic_rcvqueue_fill could only get [%d] "
-			     "skbuffs\n",
-			     adapter->netdev->name, i);
+			dev_err(&adapter->netdev->dev,
+				"slic_rcvqueue_fill could only get [%d] skbuffs\n",
+				i);
 			break;
 		}
 	}
@@ -4397,6 +3548,7 @@
 	u32 paddrl;
 	u32 paddrh;
 	struct slic_rcvbuf *rcvbuf = (struct slic_rcvbuf *)skb->head;
+	struct device *dev;
 
 	ASSERT(skb->len == SLIC_RCVBUF_HEADSIZE);
 
@@ -4409,26 +3561,26 @@
 	paddrh = SLIC_GET_ADDR_HIGH(paddr);
 
 	if (paddrl == 0) {
-		DBG_ERROR
-		    ("%s: LOW 32bits PHYSICAL ADDRESS == 0 skb[%p]   PROBLEM\n"
-		     "         skbdata[%p]\n" "         skblen[%x]\n"
-		     "         paddr[%p]\n" "         paddrl[%x]\n"
-		     "         paddrh[%x]\n", __func__, skb, skb->data,
-		     skb->len, paddr, paddrl, paddrh);
-		DBG_ERROR("         rcvq->head[%p]\n"
-			  "         rcvq->tail[%p]\n"
-			  "         rcvq->count[%x]\n", rcvq->head, rcvq->tail,
-			  rcvq->count);
+		dev = &adapter->netdev->dev;
+		dev_err(dev, "%s: LOW 32bits PHYSICAL ADDRESS == 0\n",
+			__func__);
+		dev_err(dev, "skb[%p] PROBLEM\n", skb);
+		dev_err(dev, "         skbdata[%p]\n", skb->data);
+		dev_err(dev, "         skblen[%x]\n", skb->len);
+		dev_err(dev, "         paddr[%p]\n", paddr);
+		dev_err(dev, "         paddrl[%x]\n", paddrl);
+		dev_err(dev, "         paddrh[%x]\n", paddrh);
+		dev_err(dev, "         rcvq->head[%p]\n", rcvq->head);
+		dev_err(dev, "         rcvq->tail[%p]\n", rcvq->tail);
+		dev_err(dev, "         rcvq->count[%x]\n", rcvq->count);
 	}
 	if (paddrh == 0) {
-		WRITE_REG(adapter->slic_regs->slic_hbar, (u32) paddrl,
-			  DONT_FLUSH);
+		slic_reg32_write(&adapter->slic_regs->slic_hbar, (u32)paddrl,
+				 DONT_FLUSH);
 	} else {
-		WRITE_REG64(adapter,
-			    adapter->slic_regs->slic_hbar64,
-			    paddrl,
-			    adapter->slic_regs->slic_addr_upper,
-			    paddrh, DONT_FLUSH);
+		slic_reg64_write(adapter, &adapter->slic_regs->slic_hbar64,
+				 paddrl, &adapter->slic_regs->slic_addr_upper,
+				 paddrh, DONT_FLUSH);
 	}
 	if (rcvq->head)
 		rcvq->tail->next = skb;
@@ -4449,7 +3601,7 @@
 	unsigned char *oemfru = (unsigned char *)(&card->config.OemFru);
 #endif
 
-	seq_printf(seq, "driver_version           : %s", slic_proc_version);
+	seq_printf(seq, "driver_version           : %s\n", slic_proc_version);
 	seq_printf(seq, "Microcode versions:           \n");
 	seq_printf(seq, "    Gigabit (gb)         : %s %s\n",
 		    MOJAVE_UCODE_VERS_STRING, MOJAVE_UCODE_VERS_DATE);
@@ -4882,1030 +4034,6 @@
 	}
 }
 
-/*=============================================================================
-  =============================================================================
-  ===                                                                       ===
-  ===       SLIC  DUMP  MANAGEMENT        SECTION                           ===
-  ===                                                                       ===
-  ===                                                                       ===
-  === Dump routines                                                         ===
-  ===                                                                       ===
-  ===                                                                       ===
-  =============================================================================
-  ============================================================================*/
-
-#if SLIC_DUMP_ENABLED
-
-#include <stdarg.h>
-
-void *slic_dump_handle;		/* thread handle */
-
-/*
- * These are the only things you should do on a core-file: use only these
- * functions to write out all the necessary info.
- */
-static int slic_dump_seek(struct file *SLIChandle, u32 file_offset)
-{
-	if (SLIChandle->f_pos != file_offset) {
-		/*DBG_MSG("slic_dump_seek  now needed [%x : %x]\n",
-			(u32)SLIChandle->f_pos, (u32)file_offset); */
-		if (SLIChandle->f_op->llseek) {
-			if (SLIChandle->f_op->
-			    llseek(SLIChandle, file_offset, 0) != file_offset)
-				return 0;
-		} else {
-			SLIChandle->f_pos = file_offset;
-		}
-	}
-	return 1;
-}
-
-static int slic_dump_write(struct sliccard *card,
-			   const void *addr, int size, u32 file_offset)
-{
-	int r = 1;
-	u32 result = 0;
-	struct file *SLIChandle = card->dumphandle;
-
-#ifdef HISTORICAL		/* legacy */
-	down(&SLIChandle->f_dentry->d_inode->i_sem);
-#endif
-	if (size) {
-		slic_dump_seek(SLIChandle, file_offset);
-
-		result =
-		    SLIChandle->f_op->write(SLIChandle, addr, size,
-					    &SLIChandle->f_pos);
-
-		r = result == size;
-	}
-
-	card->dumptime_complete = jiffies;
-	card->dumptime_delta = card->dumptime_complete - card->dumptime_start;
-	card->dumptime_start = jiffies;
-
-#ifdef HISTORICAL
-	up(&SLIChandle->f_dentry->d_inode->i_sem);
-#endif
-	if (!r) {
-		DBG_ERROR("%s: addr[%p] size[%x] result[%x] file_offset[%x]\n",
-			  __func__, addr, size, result, file_offset);
-	}
-	return r;
-}
-
-static uint slic_init_dump_thread(struct sliccard *card)
-{
-	card->dump_task_id = kthread_run(slic_dump_thread, (void *)card, 0);
-
-/*  DBG_MSG("create slic_dump_thread dump_pid[%x]\n", card->dump_pid); */
-	if (IS_ERR(card->dump_task_id)) {
-		DBG_MSG("create slic_dump_thread FAILED \n");
-		return STATUS_FAILURE;
-	}
-
-	return STATUS_SUCCESS;
-}
-
-static int slic_dump_thread(void *context)
-{
-	struct sliccard *card = (struct sliccard *)context;
-	struct adapter *adapter;
-	struct adapter *dump_adapter = NULL;
-	u32 dump_complete = 0;
-	u32 delay = SLIC_SECS_TO_JIFFS(PING_TIMER_INTERVAL);
-	struct slic_regs *pregs;
-	u32 i;
-	struct slic_upr *upr, *uprnext;
-	u32 dump_card;
-
-	ASSERT(card);
-
-	card->dumpthread_running = 1;
-
-#ifdef HISTORICAL
-	lock_kernel();
-	/*
-	 * This thread doesn't need any user-level access,
-	 * so get rid of all our resources
-	 */
-	exit_files(current);	/* daemonize doesn't do exit_files */
-	current->files = init_task.files;
-	atomic_inc(&current->files->count);
-#endif
-
-	daemonize("%s", "slicmon");
-
-	/* Setup a nice name */
-	strcpy(current->comm, "slicmon");
-	DBG_ERROR
-	    ("slic_dump_thread[slicmon] daemon is alive card[%p] pid[%x]\n",
-	     card, card->dump_task_id->pid);
-
-	/*
-	 *    Send me a signal to get me to die (for debugging)
-	 */
-	do {
-		/*
-		 * If card state is not set to up, skip
-		 */
-		if (card->state != CARD_UP) {
-			if (card->adapters_activated)
-				goto wait;
-			else
-				goto end_thread;
-		}
-		/*
-		 *    Check the results of our last ping.
-		 */
-		dump_card = 0;
-#ifdef SLIC_FAILURE_DUMP
-		if (card->pingstatus != ISR_PINGMASK) {
-			DBG_MSG
-			    ("\n[slicmon]  CARD #%d TIMED OUT - status "
-			     "%x: DUMP THE CARD!\n",
-			     card->cardnum, card->pingstatus);
-			dump_card = 1;
-		}
-#else
-		/*
-		 *  Cause a card RESET instead?
-		 */
-		if (card->pingstatus != ISR_PINGMASK) {
-			/* todo. do we want to reset the card in production */
-			/* DBG_MSG("\n[slicmon]  CARD #%d TIMED OUT - "
-			   status %x: RESET THE CARD!\n", card->cardnum,
-			   card->pingstatus); */
-			DBG_ERROR
-			    ("\n[slicmon]  CARD #%d TIMED OUT - status %x: "
-			     "DUMP THE CARD!\n",
-			     card->cardnum, card->pingstatus);
-			dump_card = 1;
-		}
-#endif
-		if ((dump_card)
-		    || (card->dump_requested == SLIC_DUMP_REQUESTED)) {
-			if (card->dump_requested == SLIC_DUMP_REQUESTED) {
-				DBG_ERROR
-			    ("[slicmon]: Dump card Requested: Card %x\n",
-				     card->cardnum);
-			}
-			if (card->pingstatus != ISR_PINGMASK) {
-				ushort cpuid = 0;
-				ushort crashpc = 0;
-
-				if (card->adapter[0]) {
-					if ((card->adapter[0])->memorylength >=
-					    CRASH_INFO_OFFSET +
-					    sizeof(slic_crash_info)) {
-						char *crashptr;
-						p_slic_crash_info crashinfo;
-
-						crashptr =
-						    ((char *)card->adapter[0]->
-						     slic_regs) +
-						    CRASH_INFO_OFFSET;
-						crashinfo =
-						    (p_slic_crash_info)
-						    crashptr;
-						cpuid = crashinfo->cpu_id;
-						crashpc = crashinfo->crash_pc;
-					}
-				}
-				DBG_ERROR
-				    ("[slicmon]: Dump card: Card %x crashed "
-				     "and failed to answer PING. "
-				     "CPUID[%x] PC[%x]\n ",
-				     card->cardnum, cpuid, crashpc);
-			}
-
-			card->dump_requested = SLIC_DUMP_IN_PROGRESS;
-
-			/*
-			 * Set the card state to DOWN and the adapter states
-			 * to RESET.They will check this in SimbaCheckForHang
-			 * and initiate interface reset (which in turn will
-			 * reinitialize the card).
-			 */
-			card->state = CARD_DOWN;
-
-			for (i = 0; i < card->card_size; i++) {
-				adapter = card->adapter[i];
-				if (adapter) {
-					slic_if_stop_queue(adapter);
-
-					if (adapter->state == ADAPT_UP) {
-						adapter->state = ADAPT_RESET;
-						adapter->linkstate = LINK_DOWN;
-						DBG_ERROR
-						    ("[slicmon]: SLIC Card[%d] "
-						     "Port[%d] adapter[%p] "
-						     "down\n",
-						     (uint) card->cardnum,
-						     (uint) i, adapter);
-					}
-#if SLIC_GET_STATS_TIMER_ENABLED
-					/* free stats timer */
-					if (adapter->statstimerset) {
-						adapter->statstimerset = 0;
-						del_timer(&adapter->statstimer);
-					}
-#endif
-				}
-			}
-
-			for (i = 0; i < card->card_size; i++) {
-				adapter = card->adapter[i];
-				if ((adapter) && (adapter->activated)) {
-					pregs = adapter->slic_regs;
-					dump_adapter = adapter;
-
-					/*
-					 * If the dump status is zero, then
-					 * the utility processor has crashed.
-					 * If this is the case, any pending
-					 * utilityprocessor requests will not
-					 * complete and our dump commands will
-					 * not be issued.
-					 *
-					 * To avoid this we will clear any
-					 * pending utility processor requests
-					 * now.
-					 */
-					if (!card->pingstatus) {
-						spin_lock_irqsave(
-						    &adapter->upr_lock.lock,
-						    adapter->upr_lock.flags);
-						upr = adapter->upr_list;
-						while (upr) {
-							uprnext = upr->next;
-							kfree(upr);
-							upr = uprnext;
-						}
-						adapter->upr_list = 0;
-						adapter->upr_busy = 0;
-						spin_unlock_irqrestore(
-						    &adapter->upr_lock.lock,
-						    adapter->upr_lock.flags);
-					}
-
-					slic_dump_card(card, FALSE);
-					dump_complete = 1;
-				}
-
-				if (dump_complete) {
-					DBG_ERROR("SLIC Dump Complete\n");
-					/*  Only dump the card one time */
-					break;
-				}
-			}
-
-			if (dump_adapter) {
-				DBG_ERROR
-				    ("slic dump completed. "
-				     "Reenable interfaces\n");
-				slic_card_init(card, dump_adapter);
-
-				/*
-				 *  Reenable the adapters that were reset
-				 */
-				for (i = 0; i < card->card_size; i++) {
-					adapter = card->adapter[i];
-					if (adapter) {
-						if (adapter->state ==
-						    ADAPT_RESET) {
-							DBG_ERROR
-							    ("slicdump: SLIC "
-					   "Card[%d] Port[%d] adapter[%p] "
-					   "bring UP\n",
-							     (uint) card->
-							     cardnum, (uint) i,
-							     adapter);
-							adapter->state =
-							    ADAPT_DOWN;
-							adapter->linkstate =
-							    LINK_DOWN;
-							slic_entry_open
-							    (adapter->netdev);
-						}
-					}
-				}
-
-				card->dump_requested = SLIC_DUMP_DONE;
-			}
-		} else {
-		/* if pingstatus != ISR_PINGMASK) || dump_requested...ELSE
-		 *    We received a valid ping response.
-		 *    Clear the Pingstatus field, find a valid adapter
-		 *    structure and send another ping.
-		 */
-			for (i = 0; i < card->card_size; i++) {
-				adapter = card->adapter[i];
-				if (adapter && (adapter->state == ADAPT_UP)) {
-					card->pingstatus = 0;
-					slic_upr_request(adapter, SLIC_UPR_PING,
-							 0, 0, 0, 0);
-					break;	/* Only issue one per card */
-				}
-			}
-		}
-wait:
-		SLIC_INTERRUPTIBLE_SLEEP_ON_TIMEOUT(card->dump_wq, delay);
-	} while (!signal_pending(current));
-
-end_thread:
-/*  DBG_MSG("[slicmon] slic_dump_thread card[%p] pid[%x] ENDING\n",
-    card, card->dump_pid); */
-	card->dumpthread_running = 0;
-
-	return 0;
-}
-
-/*
- * Read a single byte from our dump index file.  This
- * value is used as our suffix for our dump path.  The
- * value is incremented and written back to the file
- */
-static unsigned char slic_get_dump_index(char *path)
-{
-	unsigned char index = 0;
-#ifdef SLIC_DUMP_INDEX_SUPPORT
-	u32 status;
-	void *FileHandle;
-	u32 offset;
-
-	offset = 0;
-
-	/*
-	 * Open the index file.  If one doesn't exist, create it
-	 */
-	status = create_file(&FileHandle);
-
-	if (status != STATUS_SUCCESS)
-		return (unsigned char) 0;
-
-	status = read_file(FileHandle, &index, 1, &offset);
-
-	index++;
-
-	status = write_file(FileHandle, &index, 1, &offset);
-
-	close_file(FileHandle);
-#else
-	index = 0;
-#endif
-	return index;
-}
-
-static struct file *slic_dump_open_file(struct sliccard *card)
-{
-	struct file *SLIChandle = NULL;
-	struct dentry *dentry = NULL;
-	struct inode *inode = NULL;
-	char SLICfile[50];
-
-	card->dumpfile_fs = get_fs();
-
-	set_fs(KERNEL_DS);
-
-	memset(SLICfile, 0, sizeof(SLICfile));
-	sprintf(SLICfile, "/var/tmp/slic%d-dump-%d", card->cardnum,
-		(uint) card->dump_count);
-	card->dump_count++;
-
-	SLIChandle =
-	    filp_open(SLICfile, O_CREAT | O_RDWR | O_SYNC | O_LARGEFILE, 0666);
-
-	DBG_MSG("[slicmon]: Dump Card #%d to file: %s \n", card->cardnum,
-		SLICfile);
-
-/*  DBG_MSG("[slicmon] filp_open %s SLIChandle[%p]\n", SLICfile, SLIChandle);*/
-
-	if (IS_ERR(SLIChandle))
-		goto end_slicdump;
-
-	dentry = SLIChandle->f_dentry;
-	inode = dentry->d_inode;
-
-/*  DBG_MSG("[slicmon] inode[%p] i_nlink[%x] i_mode[%x] i_op[%p] i_fop[%p]\n"
-		"f_op->write[%p]\n",
-		inode, inode->i_nlink, inode->i_mode, inode->i_op,
-		inode->i_fop, SLIChandle->f_op->write); */
-	if (inode->i_nlink > 1)
-		goto close_slicdump;	/* multiple links - don't dump */
-#ifdef HISTORICAL
-	if (!S_ISREG(inode->i_mode))
-		goto close_slicdump;
-#endif
-	if (!inode->i_op || !inode->i_fop)
-		goto close_slicdump;
-
-	if (!SLIChandle->f_op->write)
-		goto close_slicdump;
-
-	/*
-	 *  If we got here we have SUCCESSFULLY OPENED the dump file
-	 */
-/*  DBG_MSG("opened %s SLIChandle[%p]\n", SLICfile, SLIChandle); */
-	return SLIChandle;
-
-close_slicdump:
-	DBG_MSG("[slicmon] slic_dump_open_file failed close SLIChandle[%p]\n",
-		SLIChandle);
-	filp_close(SLIChandle, NULL);
-
-end_slicdump:
-	set_fs(card->dumpfile_fs);
-
-	return NULL;
-}
-
-static void slic_dump_close_file(struct sliccard *card)
-{
-
-/*  DBG_MSG("[slicmon] slic_dump_CLOSE_file close SLIChandle[%p]\n",
-   card->dumphandle); */
-
-	filp_close(card->dumphandle, NULL);
-
-	set_fs(card->dumpfile_fs);
-}
-
-static u32 slic_dump_card(struct sliccard *card, bool resume)
-{
-	struct adapter *adapter = card->master;
-	u32 status;
-	u32 queue;
-	u32 len, offset;
-	u32 sram_size, dram_size, regs;
-	struct sliccore_hdr corehdr;
-	u32 file_offset;
-	char *namestr;
-	u32 i;
-	u32 max_queues = 0;
-	u32 result;
-
-	card->dumphandle = slic_dump_open_file(card);
-
-	if (card->dumphandle == NULL) {
-		DBG_MSG("[slicmon] Cant create Dump file - dump failed\n");
-		return -ENOMEM;
-	}
-	if (!card->dumpbuffer) {
-		DBG_MSG("[slicmon] Insufficient memory for dump\n");
-		return -ENOMEM;
-	}
-	if (!card->cmdbuffer) {
-		DBG_MSG("[slicmon] Insufficient cmd memory for dump\n");
-		return -ENOMEM;
-	}
-
-	/*
-	 * Write the file version to the core header.
-	 */
-	namestr = slic_proc_version;
-	for (i = 0; i < (DRIVER_NAME_SIZE - 1); i++, namestr++) {
-		if (!namestr)
-			break;
-		corehdr.driver_version[i] = *namestr;
-	}
-	corehdr.driver_version[i] = 0;
-
-	file_offset = sizeof(struct sliccore_hdr);
-
-	/*
-	 * Issue the following debug commands to the SLIC:
-	 *        - Halt both receive and transmit
-	 *        - Dump receive registers
-	 *        - Dump transmit registers
-	 *        - Dump sram
-	 *        - Dump dram
-	 *        - Dump queues
-	 */
-	DBG_MSG("slicDump HALT Receive Processor\n");
-	card->dumptime_start = jiffies;
-
-	status = slic_dump_halt(card, PROC_RECEIVE);
-	if (status != STATUS_SUCCESS) {
-		DBG_ERROR
-		    ("Cant halt receive sequencer - dump failed status[%x]\n",
-		     status);
-		goto done;
-	}
-
-	DBG_MSG("slicDump HALT Transmit Processor\n");
-	status = slic_dump_halt(card, PROC_TRANSMIT);
-	if (status != STATUS_SUCCESS) {
-		DBG_ERROR("Cant halt transmit sequencer - dump failed\n");
-		goto done;
-	}
-
-	/* Dump receive regs */
-	status = slic_dump_reg(card, PROC_RECEIVE);
-	if (status != STATUS_SUCCESS) {
-		DBG_ERROR("Cant dump receive registers - dump failed\n");
-		goto done;
-	}
-
-	DBG_MSG("slicDump Write Receive REGS len[%x] offset[%x]\n",
-		(SLIC_NUM_REG * 4), file_offset);
-
-	result =
-	    slic_dump_write(card, card->dumpbuffer, SLIC_NUM_REG * 4,
-			    file_offset);
-	if (!result) {
-		DBG_ERROR
-		    ("Cant write rcv registers to dump file - dump failed\n");
-		goto done;
-	}
-
-	corehdr.RcvRegOff = file_offset;
-	corehdr.RcvRegsize = SLIC_NUM_REG * 4;
-	file_offset += SLIC_NUM_REG * 4;
-
-	/* Dump transmit regs */
-	status = slic_dump_reg(card, PROC_TRANSMIT);
-	if (status != STATUS_SUCCESS) {
-		DBG_ERROR("Cant dump transmit registers - dump failed\n");
-		goto done;
-	}
-
-	DBG_MSG("slicDump Write XMIT REGS len[%x] offset[%x]\n",
-		(SLIC_NUM_REG * 4), file_offset);
-
-	result =
-	    slic_dump_write(card, card->dumpbuffer, SLIC_NUM_REG * 4,
-			    file_offset);
-	if (!result) {
-		DBG_ERROR
-		    ("Cant write xmt registers to dump file - dump failed\n");
-		goto done;
-	}
-
-	corehdr.XmtRegOff = file_offset;
-	corehdr.XmtRegsize = SLIC_NUM_REG * 4;
-	file_offset += SLIC_NUM_REG * 4;
-
-	regs = SLIC_GBMAX_REG;
-
-	corehdr.FileRegOff = file_offset;
-	corehdr.FileRegsize = regs * 4;
-
-	for (offset = 0; regs;) {
-		len = MIN(regs, 16);	/* Can only xfr 16 regs at a time */
-
-		status = slic_dump_data(card, offset, (ushort) len, DESC_RFILE);
-
-		if (status != STATUS_SUCCESS) {
-			DBG_ERROR("Cant dump register file - dump failed\n");
-			goto done;
-		}
-
-		DBG_MSG("slicDump Write RegisterFile len[%x] offset[%x]\n",
-			(len * 4), file_offset);
-
-		result =
-		    slic_dump_write(card, card->dumpbuffer, len * 4,
-				    file_offset);
-		if (!result) {
-			DBG_ERROR
-			    ("Cant write register file to dump file - "
-			     "dump failed\n");
-			goto done;
-		}
-
-		file_offset += len * 4;
-		offset += len;
-		regs -= len;
-	}
-
-	dram_size = card->config.DramSize * 0x10000;
-
-	switch (adapter->devid) {
-	case SLIC_2GB_DEVICE_ID:
-		sram_size = SLIC_SRAM_SIZE2GB;
-		break;
-	case SLIC_1GB_DEVICE_ID:
-		sram_size = SLIC_SRAM_SIZE1GB;
-		break;
-	default:
-		sram_size = 0;
-		ASSERT(0);
-		break;
-	}
-
-	corehdr.SramOff = file_offset;
-	corehdr.Sramsize = sram_size;
-
-	for (offset = 0; sram_size;) {
-		len = MIN(sram_size, DUMP_BUF_SIZE);
-		status = slic_dump_data(card, offset, (ushort) len, DESC_SRAM);
-		if (status != STATUS_SUCCESS) {
-			DBG_ERROR
-			    ("[slicmon] Cant dump SRAM at offset %x - "
-			     "dump failed\n", (uint) offset);
-			goto done;
-		}
-
-		DBG_MSG("[slicmon] slicDump Write SRAM  len[%x] offset[%x]\n",
-			len, file_offset);
-
-		result =
-		    slic_dump_write(card, card->dumpbuffer, len, file_offset);
-		if (!result) {
-			DBG_ERROR
-			    ("[slicmon] Cant write SRAM to dump file - "
-			     "dump failed\n");
-			goto done;
-		}
-
-		file_offset += len;
-		offset += len;
-		sram_size -= len;
-	}
-
-	corehdr.DramOff = file_offset;
-	corehdr.Dramsize = dram_size;
-
-	for (offset = 0; dram_size;) {
-		len = MIN(dram_size, DUMP_BUF_SIZE);
-
-		status = slic_dump_data(card, offset, (ushort) len, DESC_DRAM);
-		if (status != STATUS_SUCCESS) {
-			DBG_ERROR
-			    ("[slicmon] Cant dump dram at offset %x - "
-			     "dump failed\n", (uint) offset);
-			goto done;
-		}
-
-		DBG_MSG("slicDump Write DRAM  len[%x] offset[%x]\n", len,
-			file_offset);
-
-		result =
-		    slic_dump_write(card, card->dumpbuffer, len, file_offset);
-		if (!result) {
-			DBG_ERROR
-			    ("[slicmon] Cant write DRAM to dump file - "
-			     "dump failed\n");
-			goto done;
-		}
-
-		file_offset += len;
-		offset += len;
-		dram_size -= len;
-	}
-
-	max_queues = SLIC_MAX_QUEUE;
-
-	for (queue = 0; queue < max_queues; queue++) {
-		u32 *qarray = (u32 *) card->dumpbuffer;
-		u32 qarray_physl = card->dumpbuffer_physl;
-		u32 qarray_physh = card->dumpbuffer_physh;
-		u32 qstart;
-		u32 qdelta;
-		u32 qtotal = 0;
-
-		DBG_MSG("[slicmon] Start Dump of QUEUE #0x%x\n", (uint) queue);
-
-		for (offset = 0; offset < (DUMP_BUF_SIZE >> 2); offset++) {
-			qstart = jiffies;
-			qdelta = 0;
-
-			status = slic_dump_queue(card,
-						 qarray_physl,
-						 qarray_physh, queue);
-			qarray_physl += 4;
-
-			if (status != STATUS_SUCCESS)
-				break;
-
-			if (jiffies > qstart) {
-				qdelta = jiffies - qstart;
-				qtotal += qdelta;
-			}
-		}
-
-		if (offset)
-			qdelta = qtotal / offset;
-		else
-			qdelta = 0;
-
-/*        DBG_MSG("   slicDump Write QUEUE #0x%x len[%x] offset[%x] "
-		"avgjiffs[%x]\n", queue, (offset*4), file_offset, qdelta); */
-
-		result =
-		    slic_dump_write(card, card->dumpbuffer, offset * 4,
-				    file_offset);
-
-		if (!result) {
-			DBG_ERROR
-			    ("[slicmon] Cant write QUEUES to dump file - "
-			     "dump failed\n");
-			goto done;
-		}
-
-		corehdr.queues[queue].queueOff = file_offset;
-		corehdr.queues[queue].queuesize = offset * 4;
-		file_offset += offset * 4;
-
-/*      DBG_MSG("    Reload QUEUE #0x%x elements[%x]\n", (uint)queue, offset);*/
-		/*
-		 * Fill the queue back up
-		 */
-		for (i = 0; i < offset; i++) {
-			qstart = jiffies;
-			qdelta = 0;
-
-			status = slic_dump_load_queue(card, qarray[i], queue);
-			if (status != STATUS_SUCCESS)
-				break;
-
-			if (jiffies > qstart) {
-				qdelta = jiffies - qstart;
-				qtotal += qdelta;
-			}
-		}
-
-		if (offset)
-			qdelta = qtotal / offset;
-		else
-			qdelta = 0;
-
-/*      DBG_MSG("   Reload DONE avgjiffs[%x]\n", qdelta); */
-
-		resume = 1;
-	}
-
-	len = SLIC_GB_CAMAB_SZE * 4;
-	status = slic_dump_cam(card, 0, len, DUMP_CAM_A);
-	if (status != STATUS_SUCCESS) {
-		DBG_ERROR("[slicmon] Can't dump CAM_A - dump failed\n");
-		goto done;
-	}
-
-	result = slic_dump_write(card, card->dumpbuffer, len, file_offset);
-	if (result) {
-		DBG_ERROR
-		    ("[slicmon] Can't write CAM_A data to dump file - "
-		     "dump failed\n");
-		goto done;
-	}
-	corehdr.CamAMOff = file_offset;
-	corehdr.CamASize = len;
-	file_offset += len;
-
-	len = SLIC_GB_CAMCD_SZE * 4;
-	status = slic_dump_cam(card, 0, len, DUMP_CAM_C);
-	if (status) {
-		DBG_ERROR("[slicmon] Can't dump CAM_C - dump failed\n");
-		goto done;
-	}
-
-	result = slic_dump_write(card, card->dumpbuffer, len, file_offset);
-	if (result) {
-		DBG_ERROR
-		    ("[slicmon] Can't write CAM_C data to dump file - "
-		     "dump failed\n");
-		goto done;
-	}
-	corehdr.CamCMOff = file_offset;
-	corehdr.CamCSize = len;
-	file_offset += len;
-
-done:
-	/*
-	 * Write out the core header
-	 */
-	file_offset = 0;
-	DBG_MSG("[slicmon] Write CoreHeader len[%x] offset[%x]\n",
-		(uint) sizeof(struct sliccore_hdr), file_offset);
-
-	result =
-	    slic_dump_write(card, &corehdr, sizeof(struct sliccore_hdr),
-			    file_offset);
-	DBG_MSG("[slicmon] corehdr  xoff[%x] xsz[%x]\n"
-		"    roff[%x] rsz[%x] fileoff[%x] filesz[%x]\n"
-		"    sramoff[%x] sramsz[%x], dramoff[%x] dramsz[%x]\n"
-		"    corehdr_offset[%x]\n", corehdr.XmtRegOff,
-		corehdr.XmtRegsize, corehdr.RcvRegOff, corehdr.RcvRegsize,
-		corehdr.FileRegOff, corehdr.FileRegsize, corehdr.SramOff,
-		corehdr.Sramsize, corehdr.DramOff, corehdr.Dramsize,
-		(uint) sizeof(struct sliccore_hdr));
-	for (i = 0; i < max_queues; i++) {
-		DBG_MSG("[slicmon]  QUEUE 0x%x  offset[%x] size[%x]\n",
-			(uint) i, corehdr.queues[i].queueOff,
-			corehdr.queues[i].queuesize);
-
-	}
-
-	slic_dump_close_file(card);
-
-	if (resume) {
-		DBG_MSG("slicDump RESTART RECEIVE and XMIT PROCESSORS\n\n");
-		slic_dump_resume(card, PROC_RECEIVE);
-		slic_dump_resume(card, PROC_TRANSMIT);
-	}
-
-	return status;
-}
-
-static u32 slic_dump_halt(struct sliccard *card, unsigned char proc)
-{
-	unsigned char *cmd = card->cmdbuffer;
-
-	*cmd = COMMAND_BYTE(CMD_HALT, 0, proc);
-
-	return slic_dump_send_cmd(card,
-				   card->cmdbuffer_physl,
-				   card->cmdbuffer_physh, 0, 0);
-}
-
-static u32 slic_dump_resume(struct sliccard *card, unsigned char proc)
-{
-	unsigned char *cmd = card->cmdbuffer;
-
-	*cmd = COMMAND_BYTE(CMD_RUN, 0, proc);
-
-	return slic_dump_send_cmd(card,
-				   card->cmdbuffer_physl,
-				   card->cmdbuffer_physh, 0, 0);
-}
-
-static u32 slic_dump_reg(struct sliccard *card, unsigned char proc)
-{
-	struct dump_cmd *dump = (struct dump_cmd *)card->cmdbuffer;
-
-	dump->cmd = COMMAND_BYTE(CMD_DUMP, 0, proc);
-	dump->desc = DESC_REG;
-	dump->count = 0;
-	dump->addr = 0;
-
-	return slic_dump_send_cmd(card,
-				   card->cmdbuffer_physl,
-				   card->cmdbuffer_physh,
-				   card->dumpbuffer_physl,
-				   card->dumpbuffer_physh);
-}
-
-static u32 slic_dump_data(struct sliccard *card,
-		       u32 addr, ushort count, unsigned char desc)
-{
-	struct dump_cmd *dump = (struct dump_cmd *)card->cmdbuffer;
-
-	dump->cmd = COMMAND_BYTE(CMD_DUMP, 0, PROC_RECEIVE);
-	dump->desc = desc;
-	dump->count = count;
-	dump->addr = addr;
-
-	return slic_dump_send_cmd(card,
-				   card->cmdbuffer_physl,
-				   card->cmdbuffer_physh,
-				   card->dumpbuffer_physl,
-				   card->dumpbuffer_physh);
-}
-
-static u32 slic_dump_queue(struct sliccard *card,
-			u32 addr, u32 buf_physh, u32 queue)
-{
-	struct dump_cmd *dump = (struct dump_cmd *)card->cmdbuffer;
-
-	dump->cmd = COMMAND_BYTE(CMD_DUMP, 0, PROC_RECEIVE);
-	dump->desc = DESC_QUEUE;
-	dump->count = 1;
-	dump->addr = queue;
-
-	return slic_dump_send_cmd(card,
-				   card->cmdbuffer_physl,
-				   card->cmdbuffer_physh,
-				   addr, card->dumpbuffer_physh);
-}
-
-static u32 slic_dump_load_queue(struct sliccard *card, u32 data,
-				u32 queue)
-{
-	struct dump_cmd *load = (struct dump_cmd *) card->cmdbuffer;
-
-	load->cmd = COMMAND_BYTE(CMD_LOAD, 0, PROC_RECEIVE);
-	load->desc = DESC_QUEUE;
-	load->count = (ushort) queue;
-	load->addr = data;
-
-	return slic_dump_send_cmd(card,
-				   card->cmdbuffer_physl,
-				   card->cmdbuffer_physh, 0, 0);
-}
-
-static u32 slic_dump_cam(struct sliccard *card,
-		      u32 addr, u32 count, unsigned char desc)
-{
-	struct dump_cmd *dump = (struct dump_cmd *)card->cmdbuffer;
-
-	dump->cmd = COMMAND_BYTE(CMD_CAM_OPS, 0, PROC_NONE);
-	dump->desc = desc;
-	dump->count = count;
-	dump->addr = 0;
-
-	return slic_dump_send_cmd(card,
-				   card->cmdbuffer_physl,
-				   card->cmdbuffer_physh,
-				   addr, card->dumpbuffer_physh);
-}
-
-static u32 slic_dump_send_cmd(struct sliccard *card,
-			   u32 cmd_physl,
-			   u32 cmd_physh,
-			   u32 buf_physl, u32 buf_physh)
-{
-	ulong timeout = SLIC_MS_TO_JIFFIES(500);	/* 500 msec */
-	u32 attempts = 5;
-	u32 delay = SLIC_MS_TO_JIFFIES(10);	/* 10 msec */
-	struct adapter *adapter = card->master;
-
-	ASSERT(adapter);
-	do {
-		/*
-		 * Zero the Dumpstatus field of the adapter structure
-		 */
-		card->dumpstatus = 0;
-		/*
-		 * Issue the dump command via a utility processor request.
-		 *
-		 * Kludge: We use the Informationbuffer parameter to hold
-		 * the buffer address
-		 */
-		slic_upr_request(adapter, SLIC_UPR_DUMP, cmd_physl, cmd_physh,
-				 buf_physl, buf_physh);
-
-		timeout += jiffies;
-		/*
-		 * Spin until completion or timeout.
-		 */
-		while (!card->dumpstatus) {
-			int num_sleeps = 0;
-
-			if (jiffies > timeout) {
-				/*
-				 *  Complete the timed-out DUMP UPR request.
-				 */
-				slic_upr_request_complete(adapter, 0);
-				DBG_ERROR
-				    ("%s: TIMED OUT num_sleeps[%x] "
-				     "status[%x]\n",
-				     __func__, num_sleeps, STATUS_FAILURE);
-
-				return STATUS_FAILURE;
-			}
-			num_sleeps++;
-			SLIC_INTERRUPTIBLE_SLEEP_ON_TIMEOUT(card->dump_wq,
-							    delay);
-		}
-
-		if (card->dumpstatus & ISR_UPCERR) {
-			/*
-			 * Error (or queue empty)
-			 */
-/*          DBG_ERROR("[slicmon] %s: DUMP_STATUS & ISR_UPCERR status[%x]\n",
-		__func__, STATUS_FAILURE); */
-
-			return STATUS_FAILURE;
-		} else if (card->dumpstatus & ISR_UPCBSY) {
-			/*
-			 * Retry
-			 */
-			DBG_ERROR("%s: ISR_UPCBUSY attempt[%x]\n", __func__,
-				  attempts);
-
-			attempts--;
-		} else {
-			/*
-			 * success
-			 */
-			return STATUS_SUCCESS;
-		}
-
-	} while (attempts);
-
-	DBG_ERROR("%s: GAVE UP AFTER SEVERAL ATTEMPTS status[%x]\n",
-		  __func__, STATUS_FAILURE);
-
-	/*
-	 * Gave up after several attempts
-	 */
-	return STATUS_FAILURE;
-}
-
-#endif
-/*=============================================================================
-  =============================================================================
-  ===                                                                       ===
-  ===      *** END **** END **** END **** END ***                           ===
-  ===       SLIC  DUMP  MANAGEMENT        SECTION                           ===
-  ===                                                                       ===
-  ===                                                                       ===
-  ===                                                                       ===
-  =============================================================================
-  ============================================================================*/
-
 /******************************************************************************/
 /****************   MODULE INITIATION / TERMINATION FUNCTIONS   ***************/
 /******************************************************************************/
@@ -5915,46 +4043,25 @@
 	.id_table = slic_pci_tbl,
 	.probe = slic_entry_probe,
 	.remove = slic_entry_remove,
-#if SLIC_POWER_MANAGEMENT_ENABLED
-	.suspend = slicpm_suspend,
-	.resume = slicpm_resume,
-#endif
-/*    .shutdown   =     slic_shutdown,  MOOK_INVESTIGATE */
 };
 
 static int __init slic_module_init(void)
 {
-	struct pci_device_id *pcidev;
-	int ret;
-
-/*      DBG_MSG("slicoss: %s ENTER cpu %d\n", __func__, smp_processor_id()); */
-
 	slic_init_driver();
 
 	if (debug >= 0 && slic_debug != debug)
-		printk(SLICLEVEL "slicoss: debug level is %d.\n", debug);
+		printk(KERN_DEBUG KBUILD_MODNAME ": debug level is %d.\n",
+		       debug);
 	if (debug >= 0)
 		slic_debug = debug;
 
-	pcidev = (struct pci_device_id *)slic_driver.id_table;
-/*      DBG_MSG("slicoss: %s call pci_module_init jiffies[%lx] cpu #%d\n",
-	__func__, jiffies, smp_processor_id()); */
-
-	ret = pci_register_driver(&slic_driver);
-
-/*  DBG_MSG("slicoss: %s EXIT after call pci_module_init jiffies[%lx] "
-	    "cpu #%d status[%x]\n",__func__, jiffies,
-	    smp_processor_id(), ret); */
-
-	return ret;
+	return pci_register_driver(&slic_driver);
 }
 
 static void __exit slic_module_cleanup(void)
 {
-/*      DBG_MSG("slicoss: %s ENTER\n", __func__); */
 	pci_unregister_driver(&slic_driver);
 	slic_debug_cleanup();
-/*      DBG_MSG("slicoss: %s EXIT\n", __func__); */
 }
 
 module_init(slic_module_init);
diff --git a/drivers/staging/stlc45xx/Kconfig b/drivers/staging/stlc45xx/Kconfig
new file mode 100644
index 0000000..8d3f46f
--- /dev/null
+++ b/drivers/staging/stlc45xx/Kconfig
@@ -0,0 +1,8 @@
+config STLC45XX
+	tristate "stlc4550/4560 support"
+	depends on MAC80211 && WLAN_80211 && SPI_MASTER
+	---help---
+	  This is a driver for stlc4550 and stlc4560 chipsets.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called stlc45xx.  If unsure, say N.
diff --git a/drivers/staging/stlc45xx/Makefile b/drivers/staging/stlc45xx/Makefile
new file mode 100644
index 0000000..7ee3290
--- /dev/null
+++ b/drivers/staging/stlc45xx/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_STLC45XX)	+= stlc45xx.o
diff --git a/drivers/staging/stlc45xx/stlc45xx.c b/drivers/staging/stlc45xx/stlc45xx.c
new file mode 100644
index 0000000..3eced55
--- /dev/null
+++ b/drivers/staging/stlc45xx/stlc45xx.c
@@ -0,0 +1,2606 @@
+/*
+ * This file is part of stlc45xx
+ *
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "stlc45xx.h"
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/firmware.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/spi/spi.h>
+#include <linux/etherdevice.h>
+#include <linux/gpio.h>
+#include <linux/moduleparam.h>
+
+#include "stlc45xx_lmac.h"
+
+/*
+ * gpios should be handled in board files and provided via platform data,
+ * but because it's currently impossible for stlc45xx to have a header file
+ * in include/linux, let's use module paramaters for now
+ */
+static int stlc45xx_gpio_power = 97;
+module_param(stlc45xx_gpio_power, int, 0444);
+MODULE_PARM_DESC(stlc45xx_gpio_power, "stlc45xx gpio number for power line");
+
+static int stlc45xx_gpio_irq = 87;
+module_param(stlc45xx_gpio_irq, int, 0444);
+MODULE_PARM_DESC(stlc45xx_gpio_irq, "stlc45xx gpio number for irq line");
+
+static const u8 default_cal_channels[] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x09,
+	0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10,
+	0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xe0, 0x00, 0xe0, 0x00,
+	0xe0, 0x00, 0xe0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0,
+	0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42,
+	0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
+	0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9,
+	0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00,
+	0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
+	0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0,
+	0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
+	0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d,
+	0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa,
+	0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
+	0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17,
+	0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
+	0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00,
+	0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00,
+	0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
+	0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x71, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8,
+	0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+	0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0,
+	0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6,
+	0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00,
+	0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
+	0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0,
+	0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
+	0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca,
+	0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4,
+	0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
+	0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21,
+	0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
+	0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00,
+	0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00,
+	0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
+	0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0,
+	0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
+	0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76,
+	0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01,
+	0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0,
+	0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+	0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0,
+	0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
+	0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37,
+	0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc,
+	0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
+	0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b,
+	0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
+	0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00,
+	0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00,
+	0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
+	0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0,
+	0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
+	0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a,
+	0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d,
+	0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
+	0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x09, 0x00, 0x00, 0xc9, 0xff,
+	0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10,
+	0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+	0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab,
+	0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb,
+	0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
+	0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33,
+	0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
+	0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00,
+	0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00,
+	0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
+	0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0,
+	0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
+	0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7,
+	0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17,
+	0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
+	0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d,
+	0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00,
+	0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80,
+	0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x80, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00,
+	0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00,
+	0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0,
+	0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42,
+	0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
+	0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01,
+	0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00,
+	0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
+	0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0,
+	0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
+	0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0,
+	0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21,
+	0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
+	0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17,
+	0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00,
+	0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
+	0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0,
+	0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
+	0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x09, 0x00, 0x00, 0xc9,
+	0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01,
+	0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0,
+	0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01,
+	0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00,
+	0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
+	0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0,
+	0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
+	0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb,
+	0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b,
+	0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
+	0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21,
+	0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00,
+	0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
+	0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0,
+	0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
+	0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0,
+	0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96,
+	0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
+	0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+	0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x8a, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00,
+	0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0,
+	0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+	0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0,
+	0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
+	0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22,
+	0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33,
+	0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
+	0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b,
+	0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00,
+	0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
+	0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0,
+	0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
+	0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0,
+	0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0,
+	0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
+	0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d,
+	0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
+	0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x09, 0x00, 0x00,
+	0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10,
+	0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+	0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54,
+	0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42,
+	0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
+	0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33,
+	0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00,
+	0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
+	0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0,
+	0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
+	0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0,
+	0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa,
+	0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
+	0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17,
+	0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
+	0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c,
+	0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00,
+	0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
+	0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x94, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00,
+	0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+	0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0,
+	0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42,
+	0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00,
+	0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
+	0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0,
+	0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
+	0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0,
+	0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4,
+	0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
+	0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21,
+	0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
+	0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d,
+	0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00,
+	0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
+	0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0,
+	0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
+	0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x09, 0x00,
+	0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01,
+	0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0,
+	0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+	0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0,
+	0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
+	0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0,
+	0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc,
+	0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
+	0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b,
+	0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
+	0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54,
+	0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00,
+	0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
+	0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0,
+	0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
+	0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06,
+	0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96,
+	0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
+	0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x9e, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff,
+	0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10,
+	0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00,
+	0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0,
+	0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb,
+	0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
+	0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33,
+	0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
+	0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79,
+	0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00,
+	0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
+	0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0,
+	0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
+	0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9,
+	0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0,
+	0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
+	0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d,
+	0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
+	0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00 };
+
+static const u8 default_cal_rssi[] = {
+	0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72,
+	0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00,
+	0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a,
+	0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe,
+	0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00,
+	0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01,
+	0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a,
+	0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00 };
+
+static void stlc45xx_tx_edcf(struct stlc45xx *stlc);
+static void stlc45xx_tx_setup(struct stlc45xx *stlc);
+static void stlc45xx_tx_scan(struct stlc45xx *stlc);
+static void stlc45xx_tx_psm(struct stlc45xx *stlc, bool enable);
+static int stlc45xx_tx_nullfunc(struct stlc45xx *stlc, bool powersave);
+static int stlc45xx_tx_pspoll(struct stlc45xx *stlc, bool powersave);
+
+static ssize_t stlc45xx_sysfs_show_cal_rssi(struct device *dev,
+					    struct device_attribute *attr,
+					    char *buf)
+{
+	struct stlc45xx *stlc = dev_get_drvdata(dev);
+	ssize_t len;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	len = PAGE_SIZE;
+
+	mutex_lock(&stlc->mutex);
+
+	if (stlc->cal_rssi)
+		hex_dump_to_buffer(stlc->cal_rssi, RSSI_CAL_ARRAY_LEN, 16,
+				   2, buf, len, 0);
+	mutex_unlock(&stlc->mutex);
+
+	len = strlen(buf);
+
+	return len;
+}
+
+static ssize_t stlc45xx_sysfs_store_cal_rssi(struct device *dev,
+					     struct device_attribute *attr,
+					     const char *buf, size_t count)
+{
+	struct stlc45xx *stlc = dev_get_drvdata(dev);
+
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	mutex_lock(&stlc->mutex);
+
+	if (count != RSSI_CAL_ARRAY_LEN) {
+		stlc45xx_error("invalid cal_rssi length: %zu", count);
+		count = 0;
+		goto out_unlock;
+	}
+
+	kfree(stlc->cal_rssi);
+
+	stlc->cal_rssi = kmemdup(buf, RSSI_CAL_ARRAY_LEN, GFP_KERNEL);
+
+	if (!stlc->cal_rssi) {
+		stlc45xx_error("failed to allocate memory for cal_rssi");
+		count = 0;
+		goto out_unlock;
+	}
+
+ out_unlock:
+	mutex_unlock(&stlc->mutex);
+
+	return count;
+}
+
+static ssize_t stlc45xx_sysfs_show_cal_channels(struct device *dev,
+						struct device_attribute *attr,
+						char *buf)
+{
+	struct stlc45xx *stlc = dev_get_drvdata(dev);
+	ssize_t len;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	len = PAGE_SIZE;
+
+	mutex_lock(&stlc->mutex);
+
+	if (stlc->cal_channels)
+		hex_dump_to_buffer(stlc->cal_channels, CHANNEL_CAL_ARRAY_LEN,
+				   16, 2, buf, len, 0);
+
+	mutex_unlock(&stlc->mutex);
+
+	len = strlen(buf);
+
+	return len;
+}
+
+static ssize_t stlc45xx_sysfs_store_cal_channels(struct device *dev,
+						 struct device_attribute *attr,
+						 const char *buf, size_t count)
+{
+	struct stlc45xx *stlc = dev_get_drvdata(dev);
+
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	mutex_lock(&stlc->mutex);
+
+	if (count != CHANNEL_CAL_ARRAY_LEN) {
+		stlc45xx_error("invalid cal_channels size: %zu ", count);
+		count = 0;
+		goto out_unlock;
+	}
+
+	kfree(stlc->cal_channels);
+
+	stlc->cal_channels = kmemdup(buf, count, GFP_KERNEL);
+
+	if (!stlc->cal_channels) {
+		stlc45xx_error("failed to allocate memory for cal_channels");
+		count = 0;
+		goto out_unlock;
+	}
+
+out_unlock:
+	mutex_unlock(&stlc->mutex);
+
+	return count;
+}
+
+static ssize_t stlc45xx_sysfs_show_tx_buf(struct device *dev,
+					  struct device_attribute *attr,
+					  char *buf)
+{
+	struct stlc45xx *stlc = dev_get_drvdata(dev);
+	struct txbuffer *entry;
+	ssize_t len = 0;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
+
+	mutex_lock(&stlc->mutex);
+
+	list_for_each_entry(entry, &stlc->tx_sent, tx_list) {
+		len += sprintf(buf + len, "0x%x: 0x%x-0x%x\n",
+			       entry->handle, entry->start,
+			       entry->end);
+	}
+
+	mutex_unlock(&stlc->mutex);
+
+	return len;
+}
+
+static DEVICE_ATTR(cal_rssi, S_IRUGO | S_IWUSR,
+		   stlc45xx_sysfs_show_cal_rssi,
+		   stlc45xx_sysfs_store_cal_rssi);
+static DEVICE_ATTR(cal_channels, S_IRUGO | S_IWUSR,
+		   stlc45xx_sysfs_show_cal_channels,
+		   stlc45xx_sysfs_store_cal_channels);
+static DEVICE_ATTR(tx_buf, S_IRUGO, stlc45xx_sysfs_show_tx_buf, NULL);
+
+static void stlc45xx_spi_read(struct stlc45xx *stlc, unsigned long addr,
+			      void *buf, size_t len)
+{
+	struct spi_transfer t[2];
+	struct spi_message m;
+
+	/* We first push the address */
+	addr = (addr << 8) | ADDR_READ_BIT_15;
+
+	spi_message_init(&m);
+	memset(t, 0, sizeof(t));
+
+	t[0].tx_buf = &addr;
+	t[0].len = 2;
+	spi_message_add_tail(&t[0], &m);
+
+	t[1].rx_buf = buf;
+	t[1].len = len;
+	spi_message_add_tail(&t[1], &m);
+
+	spi_sync(stlc->spi, &m);
+}
+
+
+static void stlc45xx_spi_write(struct stlc45xx *stlc, unsigned long addr,
+			       void *buf, size_t len)
+{
+	struct spi_transfer t[3];
+	struct spi_message m;
+	u16 last_word;
+
+	/* We first push the address */
+	addr = addr << 8;
+
+	spi_message_init(&m);
+	memset(t, 0, sizeof(t));
+
+	t[0].tx_buf = &addr;
+	t[0].len = 2;
+	spi_message_add_tail(&t[0], &m);
+
+	t[1].tx_buf = buf;
+	t[1].len = len;
+	spi_message_add_tail(&t[1], &m);
+
+	if (len % 2) {
+		last_word = ((u8 *)buf)[len - 1];
+
+		t[2].tx_buf = &last_word;
+		t[2].len = 2;
+		spi_message_add_tail(&t[2], &m);
+	}
+
+	spi_sync(stlc->spi, &m);
+}
+
+static u16 stlc45xx_read16(struct stlc45xx *stlc, unsigned long addr)
+{
+	u16 val;
+
+	stlc45xx_spi_read(stlc, addr, &val, sizeof(val));
+
+	return val;
+}
+
+static u32 stlc45xx_read32(struct stlc45xx *stlc, unsigned long addr)
+{
+	u32 val;
+
+	stlc45xx_spi_read(stlc, addr, &val, sizeof(val));
+
+	return val;
+}
+
+static void stlc45xx_write16(struct stlc45xx *stlc, unsigned long addr, u16 val)
+{
+	stlc45xx_spi_write(stlc, addr, &val, sizeof(val));
+}
+
+static void stlc45xx_write32(struct stlc45xx *stlc, unsigned long addr, u32 val)
+{
+	stlc45xx_spi_write(stlc, addr, &val, sizeof(val));
+}
+
+struct stlc45xx_spi_reg {
+	u16 address;
+	u16 length;
+	char *name;
+};
+
+/* caller must hold tx_lock */
+static void stlc45xx_txbuffer_dump(struct stlc45xx *stlc)
+{
+	struct txbuffer *txbuffer;
+	char *buf, *pos;
+	int buf_len, l, count;
+
+	if (!(DEBUG_LEVEL & DEBUG_TXBUFFER))
+		return;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
+
+	buf_len = 500;
+	buf = kmalloc(buf_len, GFP_ATOMIC);
+	if (!buf)
+		return;
+
+	pos = buf;
+	count = 0;
+
+	list_for_each_entry(txbuffer, &stlc->txbuffer, buffer_list) {
+		l = snprintf(pos, buf_len, "0x%x-0x%x,",
+			     txbuffer->start, txbuffer->end);
+		/* drop the null byte */
+		pos += l;
+		buf_len -= l;
+		count++;
+	}
+
+	if (count == 0)
+		*pos = '\0';
+	else
+		*--pos = '\0';
+
+	stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: in buffer %d regions: %s",
+		       count, buf);
+
+	kfree(buf);
+}
+
+/* caller must hold tx_lock */
+static int stlc45xx_txbuffer_find(struct stlc45xx *stlc, size_t len)
+{
+	struct txbuffer *txbuffer;
+	int pos;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
+
+	pos = FIRMWARE_TXBUFFER_START;
+
+	if (list_empty(&stlc->txbuffer))
+		goto out;
+
+	/*
+	 * the entries in txbuffer must be in the same order as they are in
+	 * the real buffer
+	 */
+	list_for_each_entry(txbuffer, &stlc->txbuffer, buffer_list) {
+		if (pos + len < txbuffer->start)
+			break;
+		pos = ALIGN(txbuffer->end + 1, 4);
+	}
+
+	if (pos + len > FIRMWARE_TXBUFFER_END)
+		/* not enough room */
+		pos = -1;
+
+	stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: find %zu B: 0x%x", len, pos);
+
+out:
+	return pos;
+}
+
+static int stlc45xx_txbuffer_add(struct stlc45xx *stlc,
+				 struct txbuffer *txbuffer)
+{
+	struct txbuffer *r, *prev = NULL;
+
+	if (list_empty(&stlc->txbuffer)) {
+		list_add(&txbuffer->buffer_list, &stlc->txbuffer);
+		return 0;
+	}
+
+	r = list_first_entry(&stlc->txbuffer, struct txbuffer, buffer_list);
+
+	if (txbuffer->start < r->start) {
+		/* add to the beginning of the list */
+		list_add(&txbuffer->buffer_list, &stlc->txbuffer);
+		return 0;
+	}
+
+	prev = NULL;
+	list_for_each_entry(r, &stlc->txbuffer, buffer_list) {
+		/* skip first entry, we checked for that above */
+		if (!prev) {
+			prev = r;
+			continue;
+		}
+
+		/* double-check overlaps */
+		WARN_ON_ONCE(txbuffer->start >= r->start &&
+			     txbuffer->start <= r->end);
+		WARN_ON_ONCE(txbuffer->end >= r->start &&
+			     txbuffer->end <= r->end);
+
+		if (prev->end < txbuffer->start &&
+		    txbuffer->end < r->start) {
+			/* insert at this spot */
+			list_add_tail(&txbuffer->buffer_list, &r->buffer_list);
+			return 0;
+		}
+
+		prev = r;
+	}
+
+	/* not found */
+	list_add_tail(&txbuffer->buffer_list, &stlc->txbuffer);
+
+	return 0;
+
+}
+
+/* caller must hold tx_lock */
+static struct txbuffer *stlc45xx_txbuffer_alloc(struct stlc45xx *stlc,
+						 size_t frame_len)
+{
+	struct txbuffer *entry = NULL;
+	size_t len;
+	int pos;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
+
+	len = FIRMWARE_TXBUFFER_HEADER + frame_len + FIRMWARE_TXBUFFER_TRAILER;
+	pos = stlc45xx_txbuffer_find(stlc, len);
+
+	if (pos < 0)
+		return NULL;
+
+	WARN_ON_ONCE(pos + len > FIRMWARE_TXBUFFER_END);
+	WARN_ON_ONCE(pos < FIRMWARE_TXBUFFER_START);
+
+	entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
+	entry->start = pos;
+	entry->frame_start = pos + FIRMWARE_TXBUFFER_HEADER;
+	entry->end = entry->start + len - 1;
+
+	stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: allocated 0x%x-0x%x",
+		       entry->start, entry->end);
+
+	stlc45xx_txbuffer_add(stlc, entry);
+
+	stlc45xx_txbuffer_dump(stlc);
+
+	return entry;
+}
+
+/* caller must hold tx_lock */
+static void stlc45xx_txbuffer_free(struct stlc45xx *stlc,
+				   struct txbuffer *txbuffer)
+{
+	stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
+
+	stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: freed 0x%x-0x%x",
+		       txbuffer->start, txbuffer->end);
+
+	list_del(&txbuffer->buffer_list);
+	kfree(txbuffer);
+}
+
+
+static int stlc45xx_wait_bit(struct stlc45xx *stlc, u16 reg, u32 mask,
+			     u32 expected)
+{
+	int i;
+	char buffer[4];
+
+	for (i = 0; i < 2000; i++) {
+		stlc45xx_spi_read(stlc, reg, buffer, sizeof(buffer));
+		if (((*(u32 *)buffer) & mask) == expected)
+			return 1;
+		msleep(1);
+	}
+
+	return 0;
+}
+
+static int stlc45xx_request_firmware(struct stlc45xx *stlc)
+{
+	const struct firmware *fw;
+	int ret;
+
+	/* FIXME: should driver use it's own struct device? */
+	ret = request_firmware(&fw, "3826.arm", &stlc->spi->dev);
+
+	if (ret < 0) {
+		stlc45xx_error("request_firmware() failed: %d", ret);
+		return ret;
+	}
+
+	if (fw->size % 4) {
+		stlc45xx_error("firmware size is not multiple of 32bit: %zu",
+			       fw->size);
+		return -EILSEQ; /* Illegal byte sequence  */;
+	}
+
+	if (fw->size < 1000) {
+		stlc45xx_error("firmware is too small: %zu", fw->size);
+		return -EILSEQ;
+	}
+
+	stlc->fw = kmemdup(fw->data, fw->size, GFP_KERNEL);
+	if (!stlc->fw) {
+		stlc45xx_error("could not allocate memory for firmware");
+		return -ENOMEM;
+	}
+
+	stlc->fw_len = fw->size;
+
+	release_firmware(fw);
+
+	return 0;
+}
+
+static int stlc45xx_upload_firmware(struct stlc45xx *stlc)
+{
+	struct s_dma_regs dma_regs;
+	unsigned long fw_len, fw_addr;
+	long _fw_len;
+	int ret;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	if (!stlc->fw) {
+		ret = stlc45xx_request_firmware(stlc);
+		if (ret < 0)
+			return ret;
+	}
+
+	/* stop the device */
+	stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT,
+			 SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_HOST_RESET
+			 | SPI_CTRL_STAT_START_HALTED);
+
+	msleep(TARGET_BOOT_SLEEP);
+
+	stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT,
+			 SPI_CTRL_STAT_HOST_OVERRIDE
+			 | SPI_CTRL_STAT_START_HALTED);
+
+	msleep(TARGET_BOOT_SLEEP);
+
+	fw_addr = FIRMWARE_ADDRESS;
+	fw_len = stlc->fw_len;
+
+	while (fw_len > 0) {
+		_fw_len = (fw_len > SPI_MAX_PACKET_SIZE)
+			? SPI_MAX_PACKET_SIZE : fw_len;
+		dma_regs.cmd = SPI_DMA_WRITE_CTRL_ENABLE;
+		dma_regs.len = cpu_to_le16(_fw_len);
+		dma_regs.addr = cpu_to_le32(fw_addr);
+
+		fw_len -= _fw_len;
+		fw_addr += _fw_len;
+
+		stlc45xx_write16(stlc, SPI_ADRS_DMA_WRITE_CTRL, dma_regs.cmd);
+
+		if (stlc45xx_wait_bit(stlc, SPI_ADRS_DMA_WRITE_CTRL,
+				      HOST_ALLOWED, HOST_ALLOWED) == 0) {
+			stlc45xx_error("fw_upload not allowed to DMA write");
+			return -EAGAIN;
+		}
+
+		stlc45xx_write16(stlc, SPI_ADRS_DMA_WRITE_LEN, dma_regs.len);
+		stlc45xx_write32(stlc, SPI_ADRS_DMA_WRITE_BASE, dma_regs.addr);
+
+		stlc45xx_spi_write(stlc, SPI_ADRS_DMA_DATA, stlc->fw, _fw_len);
+
+		/* FIXME: I think this doesn't work if firmware is large,
+		 * this loop goes to second round. fw->data is not
+		 * increased at all! */
+	}
+
+	BUG_ON(fw_len != 0);
+
+	/* enable host interrupts */
+	stlc45xx_write32(stlc, SPI_ADRS_HOST_INT_EN, SPI_HOST_INTS_DEFAULT);
+
+	/* boot the device */
+	stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT,
+			 SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_HOST_RESET
+			 | SPI_CTRL_STAT_RAM_BOOT);
+
+	msleep(TARGET_BOOT_SLEEP);
+
+	stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT,
+			 SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_RAM_BOOT);
+	msleep(TARGET_BOOT_SLEEP);
+
+	return 0;
+}
+
+/* caller must hold tx_lock */
+static void stlc45xx_check_txsent(struct stlc45xx *stlc)
+{
+	struct txbuffer *entry, *n;
+
+	list_for_each_entry_safe(entry, n, &stlc->tx_sent, tx_list) {
+		if (time_after(jiffies, entry->lifetime)) {
+			if (net_ratelimit())
+				stlc45xx_warning("frame 0x%x lifetime exceeded",
+						 entry->start);
+			list_del(&entry->tx_list);
+			skb_pull(entry->skb, entry->header_len);
+			ieee80211_tx_status(stlc->hw, entry->skb);
+			stlc45xx_txbuffer_free(stlc, entry);
+		}
+	}
+}
+
+static void stlc45xx_power_off(struct stlc45xx *stlc)
+{
+	disable_irq(gpio_to_irq(stlc45xx_gpio_irq));
+	gpio_set_value(stlc45xx_gpio_power, 0);
+}
+
+static void stlc45xx_power_on(struct stlc45xx *stlc)
+{
+	gpio_set_value(stlc45xx_gpio_power, 1);
+	enable_irq(gpio_to_irq(stlc45xx_gpio_irq));
+
+	/*
+	 * need to wait a while before device can be accessed, the length
+	 * is just a guess
+	 */
+	msleep(10);
+}
+
+/* caller must hold tx_lock */
+static void stlc45xx_flush_queues(struct stlc45xx *stlc)
+{
+	struct txbuffer *entry;
+
+	while (!list_empty(&stlc->tx_sent)) {
+		entry = list_first_entry(&stlc->tx_sent,
+					 struct txbuffer, tx_list);
+		list_del(&entry->tx_list);
+		dev_kfree_skb(entry->skb);
+		stlc45xx_txbuffer_free(stlc, entry);
+	}
+
+	WARN_ON(!list_empty(&stlc->tx_sent));
+
+	while (!list_empty(&stlc->tx_pending)) {
+		entry = list_first_entry(&stlc->tx_pending,
+					 struct txbuffer, tx_list);
+		list_del(&entry->tx_list);
+		dev_kfree_skb(entry->skb);
+		stlc45xx_txbuffer_free(stlc, entry);
+	}
+
+	WARN_ON(!list_empty(&stlc->tx_pending));
+	WARN_ON(!list_empty(&stlc->txbuffer));
+}
+
+static void stlc45xx_work_reset(struct work_struct *work)
+{
+	struct stlc45xx *stlc = container_of(work, struct stlc45xx,
+					     work_reset);
+
+	mutex_lock(&stlc->mutex);
+
+	if (stlc->fw_state != FW_STATE_RESET)
+		goto out;
+
+	stlc45xx_power_off(stlc);
+
+	mutex_unlock(&stlc->mutex);
+
+	/* wait that all work_structs have finished, we can't hold
+	 * stlc->mutex to avoid deadlock */
+	cancel_work_sync(&stlc->work);
+
+	/* FIXME: find out good value to wait for chip power down */
+	msleep(100);
+
+	mutex_lock(&stlc->mutex);
+
+	/* FIXME: we should gracefully handle if the state has changed
+	 * after re-acquiring mutex */
+	WARN_ON(stlc->fw_state != FW_STATE_RESET);
+
+	spin_lock_bh(&stlc->tx_lock);
+	stlc45xx_flush_queues(stlc);
+	spin_unlock_bh(&stlc->tx_lock);
+
+	stlc->fw_state = FW_STATE_RESETTING;
+
+	stlc45xx_power_on(stlc);
+	stlc45xx_upload_firmware(stlc);
+
+out:
+	mutex_unlock(&stlc->mutex);
+}
+
+/* caller must hold mutex */
+static void stlc45xx_reset(struct stlc45xx *stlc)
+{
+	stlc45xx_warning("resetting firmware");
+	stlc->fw_state = FW_STATE_RESET;
+	ieee80211_stop_queues(stlc->hw);
+	queue_work(stlc->hw->workqueue, &stlc->work_reset);
+}
+
+static void stlc45xx_work_tx_timeout(struct work_struct *work)
+{
+	struct stlc45xx *stlc = container_of(work, struct stlc45xx,
+					     work_tx_timeout.work);
+
+	stlc45xx_warning("tx timeout");
+
+	mutex_lock(&stlc->mutex);
+
+	if (stlc->fw_state != FW_STATE_READY)
+		goto out;
+
+	stlc45xx_reset(stlc);
+
+out:
+	mutex_unlock(&stlc->mutex);
+}
+
+static void stlc45xx_int_ack(struct stlc45xx *stlc, u32 val)
+{
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	stlc45xx_write32(stlc, SPI_ADRS_HOST_INT_ACK, val);
+}
+
+static void stlc45xx_wakeup(struct stlc45xx *stlc)
+{
+	unsigned long timeout;
+	u32 ints;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	/* wake the chip */
+	stlc45xx_write32(stlc, SPI_ADRS_ARM_INTERRUPTS, SPI_TARGET_INT_WAKEUP);
+
+	/* And wait for the READY interrupt */
+	timeout = jiffies + HZ;
+
+	ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
+	while (!(ints & SPI_HOST_INT_READY)) {
+		if (time_after(jiffies, timeout))
+				goto out;
+		ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
+	}
+
+	stlc45xx_int_ack(stlc, SPI_HOST_INT_READY);
+
+out:
+	return;
+}
+
+static void stlc45xx_sleep(struct stlc45xx *stlc)
+{
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	stlc45xx_write32(stlc, SPI_ADRS_ARM_INTERRUPTS, SPI_TARGET_INT_SLEEP);
+}
+
+static void stlc45xx_int_ready(struct stlc45xx *stlc)
+{
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	stlc45xx_write32(stlc, SPI_ADRS_HOST_INT_EN,
+			 SPI_HOST_INT_UPDATE | SPI_HOST_INT_SW_UPDATE);
+
+	switch (stlc->fw_state) {
+	case FW_STATE_BOOTING:
+		stlc->fw_state = FW_STATE_READY;
+		complete(&stlc->fw_comp);
+		break;
+	case FW_STATE_RESETTING:
+		stlc->fw_state = FW_STATE_READY;
+
+		stlc45xx_tx_scan(stlc);
+		stlc45xx_tx_setup(stlc);
+		stlc45xx_tx_edcf(stlc);
+
+		ieee80211_wake_queues(stlc->hw);
+		break;
+	default:
+		break;
+	}
+}
+
+static int stlc45xx_rx_txack(struct stlc45xx *stlc, struct sk_buff *skb)
+{
+	struct ieee80211_tx_info *info;
+	struct s_lm_control *control;
+	struct s_lmo_tx *tx;
+	struct txbuffer *entry;
+	int found = 0;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	control = (struct s_lm_control *) skb->data;
+	tx = (struct s_lmo_tx *) (control + 1);
+
+	if (list_empty(&stlc->tx_sent)) {
+		if (net_ratelimit())
+			stlc45xx_warning("no frames waiting for "
+					 "acknowledgement");
+		return -1;
+	}
+
+	list_for_each_entry(entry, &stlc->tx_sent, tx_list) {
+		if (control->handle == entry->handle) {
+			found = 1;
+			break;
+		}
+	}
+
+	if (!found) {
+		if (net_ratelimit())
+			stlc45xx_warning("couldn't find frame for tx ack 0x%x",
+					 control->handle);
+		return -1;
+	}
+
+	stlc45xx_debug(DEBUG_TX, "TX ACK 0x%x", entry->handle);
+
+	if (entry->status_needed) {
+		info = IEEE80211_SKB_CB(entry->skb);
+
+		if (!(tx->flags & LM_TX_FAILED)) {
+			/* frame was acked */
+			info->flags |= IEEE80211_TX_STAT_ACK;
+			info->status.ack_signal = tx->rcpi / 2 - 110;
+		}
+
+		skb_pull(entry->skb, entry->header_len);
+
+		ieee80211_tx_status(stlc->hw, entry->skb);
+	}
+
+	list_del(&entry->tx_list);
+
+	stlc45xx_check_txsent(stlc);
+	if (list_empty(&stlc->tx_sent))
+		/* there are no pending frames, we can stop the tx timeout
+		 * timer */
+		cancel_delayed_work(&stlc->work_tx_timeout);
+
+	spin_lock_bh(&stlc->tx_lock);
+
+	stlc45xx_txbuffer_free(stlc, entry);
+
+	if (stlc->tx_queue_stopped &&
+	    stlc45xx_txbuffer_find(stlc, MAX_FRAME_LEN) != -1) {
+		stlc45xx_debug(DEBUG_QUEUE, "room in tx buffer, waking queues");
+		ieee80211_wake_queues(stlc->hw);
+		stlc->tx_queue_stopped = 0;
+	}
+
+	spin_unlock_bh(&stlc->tx_lock);
+
+	return 0;
+}
+
+static int stlc45xx_rx_control(struct stlc45xx *stlc, struct sk_buff *skb)
+{
+	struct s_lm_control *control;
+	int ret = 0;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	control = (struct s_lm_control *) skb->data;
+
+	switch (control->oid) {
+	case LM_OID_TX:
+		ret = stlc45xx_rx_txack(stlc, skb);
+		break;
+	case LM_OID_SETUP:
+	case LM_OID_SCAN:
+	case LM_OID_TRAP:
+	case LM_OID_EDCF:
+	case LM_OID_KEYCACHE:
+	case LM_OID_PSM:
+	case LM_OID_STATS:
+	case LM_OID_LED:
+	default:
+		stlc45xx_warning("unhandled rx control oid %d\n",
+				 control->oid);
+		break;
+	}
+
+	dev_kfree_skb(skb);
+
+	return ret;
+}
+
+/* copied from mac80211 */
+static void stlc45xx_parse_elems(u8 *start, size_t len,
+				 struct stlc45xx_ie_tim **tim,
+				 size_t *tim_len)
+{
+	size_t left = len;
+	u8 *pos = start;
+
+	while (left >= 2) {
+		u8 id, elen;
+
+		id = *pos++;
+		elen = *pos++;
+		left -= 2;
+
+		if (elen > left)
+			return;
+
+		switch (id) {
+		case WLAN_EID_TIM:
+			*tim = (struct stlc45xx_ie_tim *) pos;
+			*tim_len = elen;
+			break;
+		default:
+			break;
+		}
+
+		left -= elen;
+		pos += elen;
+	}
+}
+
+/*
+ * mac80211 doesn't have support for asking frames with PS-Poll, so let's
+ * implement in the driver for now. We have to add support to mac80211
+ * later.
+ */
+static int stlc45xx_check_more_data(struct stlc45xx *stlc, struct sk_buff *skb)
+{
+	struct s_lm_data_in *data = (struct s_lm_data_in *) skb->data;
+	struct ieee80211_hdr *hdr;
+	size_t len;
+	u16 fc;
+
+	hdr = (void *) skb->data + sizeof(*data);
+	len = skb->len - sizeof(*data);
+
+	/* minimum frame length is the null frame length 24 bytes */
+	if (len < 24) {
+		stlc45xx_warning("invalid frame length when checking for "
+				 "more data");
+		return -EINVAL;
+	}
+
+	fc = le16_to_cpu(hdr->frame_control);
+	if (!(fc & IEEE80211_FCTL_FROMDS))
+		/* this is not from DS */
+		return 0;
+
+	if (compare_ether_addr(hdr->addr1, stlc->mac_addr) != 0)
+		/* the frame was not for us */
+		return 0;
+
+	if (!(fc & IEEE80211_FCTL_MOREDATA)) {
+		/* AP has no more frames buffered for us */
+		stlc45xx_debug(DEBUG_PSM, "all buffered frames retrieved");
+		stlc->pspolling = false;
+		return 0;
+	}
+
+	/* MOREDATA bit is set, let's ask for a new frame from the AP */
+	stlc45xx_tx_pspoll(stlc, stlc->psm);
+
+	return 0;
+}
+
+/*
+ * mac80211 cannot read TIM from beacons, so let's add a hack to the
+ * driver. We have to add support to mac80211 later.
+ */
+static int stlc45xx_rx_data_beacon(struct stlc45xx *stlc, struct sk_buff *skb)
+{
+	struct s_lm_data_in *data = (struct s_lm_data_in *) skb->data;
+	size_t len = skb->len, tim_len = 0, baselen, pvbmap_len;
+	struct ieee80211_mgmt *mgmt;
+	struct stlc45xx_ie_tim *tim = NULL;
+	int bmap_offset, index, aid_bit;
+
+	mgmt = (void *) skb->data + sizeof(*data);
+
+	baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
+	if (baselen > len) {
+		stlc45xx_warning("invalid baselen in beacon");
+		return -EINVAL;
+	}
+
+	stlc45xx_parse_elems(mgmt->u.beacon.variable, len - baselen, &tim,
+			     &tim_len);
+
+	if (!tim) {
+		stlc45xx_warning("didn't find tim from a beacon");
+		return -EINVAL;
+	}
+
+	bmap_offset = tim->bmap_control & 0xfe;
+	index = stlc->aid / 8 - bmap_offset;
+
+	pvbmap_len = tim_len - 3;
+	if (index > pvbmap_len)
+		return -EINVAL;
+
+	aid_bit = !!(tim->pvbmap[index] & (1 << stlc->aid % 8));
+
+	stlc45xx_debug(DEBUG_PSM, "fc 0x%x duration %d seq %d dtim %u "
+		       "bmap_control 0x%x aid_bit %d",
+		       mgmt->frame_control, mgmt->duration, mgmt->seq_ctrl >> 4,
+		       tim->dtim_count, tim->bmap_control, aid_bit);
+
+	if (!aid_bit)
+		return 0;
+
+	stlc->pspolling = true;
+	stlc45xx_tx_pspoll(stlc, stlc->psm);
+
+	return 0;
+}
+
+static int stlc45xx_rx_data(struct stlc45xx *stlc, struct sk_buff *skb)
+{
+	struct ieee80211_rx_status status;
+	struct s_lm_data_in *data = (struct s_lm_data_in *) skb->data;
+	int align = 0;
+	u8 *p, align_len;
+	u16 len;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	if (stlc->psm) {
+		if (data->flags & LM_IN_BEACON)
+			stlc45xx_rx_data_beacon(stlc, skb);
+		else if (stlc->pspolling && (data->flags & LM_IN_DATA))
+			stlc45xx_check_more_data(stlc, skb);
+	}
+
+	memset(&status, 0, sizeof(status));
+
+	status.freq = data->frequency;
+	status.signal = data->rcpi / 2 - 110;
+
+	/* let's assume that maximum rcpi value is 140 (= 35 dBm) */
+	status.qual = data->rcpi * 100 / 140;
+
+	status.band = IEEE80211_BAND_2GHZ;
+
+	/*
+	 * FIXME: this gives warning from __ieee80211_rx()
+	 *
+	 * status.rate_idx = data->rate;
+	 */
+
+	len = data->length;
+
+	if (data->flags & LM_FLAG_ALIGN)
+		align = 1;
+
+	skb_pull(skb, sizeof(*data));
+
+	if (align) {
+		p = skb->data;
+		align_len = *p;
+		skb_pull(skb, align_len);
+	}
+
+	skb_trim(skb, len);
+
+	stlc45xx_debug(DEBUG_RX, "rx data 0x%p %d B", skb->data, skb->len);
+	stlc45xx_dump(DEBUG_RX_CONTENT, skb->data, skb->len);
+
+	ieee80211_rx(stlc->hw, skb, &status);
+
+	return 0;
+}
+
+
+
+static int stlc45xx_rx(struct stlc45xx *stlc)
+{
+	struct s_lm_control *control;
+	struct sk_buff *skb;
+	int ret;
+	u16 len;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	stlc45xx_wakeup(stlc);
+
+	/* dummy read to flush SPI DMA controller bug */
+	stlc45xx_read16(stlc, SPI_ADRS_GEN_PURP_1);
+
+	len = stlc45xx_read16(stlc, SPI_ADRS_DMA_DATA);
+
+	if (len == 0) {
+		stlc45xx_warning("rx request of zero bytes");
+		return 0;
+	}
+
+	skb = dev_alloc_skb(len);
+	if (!skb) {
+		stlc45xx_warning("could not alloc skb");
+		return 0;
+	}
+
+	stlc45xx_spi_read(stlc, SPI_ADRS_DMA_DATA, skb_put(skb, len), len);
+
+	stlc45xx_sleep(stlc);
+
+	stlc45xx_debug(DEBUG_RX, "rx frame 0x%p %d B", skb->data, skb->len);
+	stlc45xx_dump(DEBUG_RX_CONTENT, skb->data, skb->len);
+
+	control = (struct s_lm_control *) skb->data;
+
+	if (control->flags & LM_FLAG_CONTROL)
+		ret = stlc45xx_rx_control(stlc, skb);
+	else
+		ret = stlc45xx_rx_data(stlc, skb);
+
+	return ret;
+}
+
+
+static irqreturn_t stlc45xx_interrupt(int irq, void *config)
+{
+	struct spi_device *spi = config;
+	struct stlc45xx *stlc = dev_get_drvdata(&spi->dev);
+
+	stlc45xx_debug(DEBUG_IRQ, "IRQ");
+
+	queue_work(stlc->hw->workqueue, &stlc->work);
+
+	return IRQ_HANDLED;
+}
+
+static int stlc45xx_tx_frame(struct stlc45xx *stlc, u32 address,
+			     void *buf, size_t len)
+{
+	struct s_dma_regs dma_regs;
+	unsigned long timeout;
+	int ret = 0;
+	u32 ints;
+
+	stlc->tx_frames++;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	stlc45xx_debug(DEBUG_TX, "tx frame 0x%p %zu B", buf, len);
+	stlc45xx_dump(DEBUG_TX_CONTENT, buf, len);
+
+	stlc45xx_wakeup(stlc);
+
+	dma_regs.cmd  = SPI_DMA_WRITE_CTRL_ENABLE;
+	dma_regs.len  = cpu_to_le16(len);
+	dma_regs.addr = cpu_to_le32(address);
+
+	stlc45xx_spi_write(stlc, SPI_ADRS_DMA_WRITE_CTRL, &dma_regs,
+			   sizeof(dma_regs));
+
+	stlc45xx_spi_write(stlc, SPI_ADRS_DMA_DATA, buf, len);
+
+	timeout = jiffies + 2 * HZ;
+	ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
+	while (!(ints & SPI_HOST_INT_WR_READY)) {
+		if (time_after(jiffies, timeout)) {
+			stlc45xx_warning("WR_READY timeout");
+			ret = -1;
+			goto out;
+		}
+		ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
+	}
+
+	stlc45xx_int_ack(stlc, SPI_HOST_INT_WR_READY);
+
+	stlc45xx_sleep(stlc);
+
+out:
+	return ret;
+}
+
+static int stlc45xx_wq_tx(struct stlc45xx *stlc)
+{
+	struct txbuffer *entry;
+	int ret = 0;
+
+	spin_lock_bh(&stlc->tx_lock);
+
+	while (!list_empty(&stlc->tx_pending)) {
+		entry = list_entry(stlc->tx_pending.next,
+				   struct txbuffer, tx_list);
+
+		list_del_init(&entry->tx_list);
+
+		spin_unlock_bh(&stlc->tx_lock);
+
+		ret = stlc45xx_tx_frame(stlc, entry->frame_start,
+					entry->skb->data, entry->skb->len);
+
+		spin_lock_bh(&stlc->tx_lock);
+
+		if (ret < 0) {
+			/* frame transfer to firmware buffer failed */
+			/* FIXME: report this to mac80211 */
+			dev_kfree_skb(entry->skb);
+			stlc45xx_txbuffer_free(stlc, entry);
+			goto out;
+		}
+
+		list_add(&entry->tx_list, &stlc->tx_sent);
+		queue_delayed_work(stlc->hw->workqueue,
+				   &stlc->work_tx_timeout,
+				   msecs_to_jiffies(TX_TIMEOUT));
+	}
+
+out:
+	spin_unlock_bh(&stlc->tx_lock);
+	return ret;
+}
+
+static void stlc45xx_work(struct work_struct *work)
+{
+	struct stlc45xx *stlc = container_of(work, struct stlc45xx, work);
+	u32 ints;
+	int ret;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	mutex_lock(&stlc->mutex);
+
+	if (stlc->fw_state == FW_STATE_OFF &&
+	    stlc->fw_state == FW_STATE_RESET)
+		goto out;
+
+	ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
+	stlc45xx_debug(DEBUG_BH, "begin host_ints 0x%08x", ints);
+
+	if (ints & SPI_HOST_INT_READY) {
+		stlc45xx_int_ready(stlc);
+		stlc45xx_int_ack(stlc, SPI_HOST_INT_READY);
+	}
+
+	if (stlc->fw_state != FW_STATE_READY)
+		goto out;
+
+	if (ints & SPI_HOST_INT_UPDATE) {
+		stlc45xx_int_ack(stlc, SPI_HOST_INT_UPDATE);
+		ret = stlc45xx_rx(stlc);
+		if (ret < 0) {
+			stlc45xx_reset(stlc);
+			goto out;
+		}
+	}
+	if (ints & SPI_HOST_INT_SW_UPDATE) {
+		stlc45xx_int_ack(stlc, SPI_HOST_INT_SW_UPDATE);
+		ret = stlc45xx_rx(stlc);
+		if (ret < 0) {
+			stlc45xx_reset(stlc);
+			goto out;
+		}
+	}
+
+	ret = stlc45xx_wq_tx(stlc);
+	if (ret < 0) {
+		stlc45xx_reset(stlc);
+		goto out;
+	}
+
+	ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
+	stlc45xx_debug(DEBUG_BH, "end host_ints 0x%08x", ints);
+
+out:
+	mutex_unlock(&stlc->mutex);
+}
+
+static void stlc45xx_tx_edcf(struct stlc45xx *stlc)
+{
+	struct s_lm_control *control;
+	struct s_lmo_edcf *edcf;
+	size_t len, edcf_len;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	edcf_len = sizeof(*edcf);
+	len = sizeof(*control) + edcf_len;
+	control = kzalloc(len, GFP_KERNEL);
+	edcf = (struct s_lmo_edcf *) (control + 1);
+
+	control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET;
+	control->length = edcf_len;
+	control->oid = LM_OID_EDCF;
+
+	edcf->slottime = 0x14;
+	edcf->sifs = 10;
+	edcf->eofpad = 6;
+	edcf->maxburst = 1500;
+
+	edcf->queues[0].aifs = 2;
+	edcf->queues[0].pad0 = 1;
+	edcf->queues[0].cwmin = 3;
+	edcf->queues[0].cwmax = 7;
+	edcf->queues[0].txop = 47;
+	edcf->queues[1].aifs = 2;
+	edcf->queues[1].pad0 = 0;
+	edcf->queues[1].cwmin = 7;
+	edcf->queues[1].cwmax = 15;
+	edcf->queues[1].txop = 94;
+	edcf->queues[2].aifs = 3;
+	edcf->queues[2].pad0 = 0;
+	edcf->queues[2].cwmin = 15;
+	edcf->queues[2].cwmax = 1023;
+	edcf->queues[2].txop = 0;
+	edcf->queues[3].aifs = 7;
+	edcf->queues[3].pad0 = 0;
+	edcf->queues[3].cwmin = 15;
+	edcf->queues[3].cwmax = 1023;
+	edcf->queues[3].txop = 0;
+	edcf->queues[4].aifs = 13;
+	edcf->queues[4].pad0 = 99;
+	edcf->queues[4].cwmin = 3437;
+	edcf->queues[4].cwmax = 512;
+	edcf->queues[4].txop = 12;
+	edcf->queues[5].aifs = 142;
+	edcf->queues[5].pad0 = 109;
+	edcf->queues[5].cwmin = 8756;
+	edcf->queues[5].cwmax = 6;
+	edcf->queues[5].txop = 0;
+	edcf->queues[6].aifs = 4;
+	edcf->queues[6].pad0 = 0;
+	edcf->queues[6].cwmin = 0;
+	edcf->queues[6].cwmax = 58705;
+	edcf->queues[6].txop = 25716;
+	edcf->queues[7].aifs = 0;
+	edcf->queues[7].pad0 = 0;
+	edcf->queues[7].cwmin = 0;
+	edcf->queues[7].cwmax = 0;
+	edcf->queues[7].txop = 0;
+
+	stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len);
+
+	kfree(control);
+}
+
+static void stlc45xx_tx_setup(struct stlc45xx *stlc)
+{
+	struct s_lm_control *control;
+	struct s_lmo_setup *setup;
+	size_t len, setup_len;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	setup_len = sizeof(*setup);
+	len = sizeof(*control) + setup_len;
+	control = kzalloc(len, GFP_KERNEL);
+	setup = (struct s_lmo_setup *) (control + 1);
+
+	control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET;
+	control->length = setup_len;
+	control->oid = LM_OID_SETUP;
+
+	setup->flags = LM_SETUP_INFRA;
+	setup->antenna = 2;
+	setup->rx_align = 0;
+	setup->rx_buffer = FIRMWARE_RXBUFFER_START;
+	setup->rx_mtu = FIRMWARE_MTU;
+	setup->frontend = 5;
+	setup->timeout = 0;
+	setup->truncate = 48896;
+	setup->bratemask = 0xffffffff;
+	setup->ref_clock = 644245094;
+	setup->lpf_bandwidth = 65535;
+	setup->osc_start_delay = 65535;
+
+	memcpy(setup->macaddr, stlc->mac_addr, ETH_ALEN);
+	memcpy(setup->bssid, stlc->bssid, ETH_ALEN);
+
+	stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len);
+
+	kfree(control);
+}
+
+static void stlc45xx_tx_scan(struct stlc45xx *stlc)
+{
+	struct s_lm_control *control;
+	struct s_lmo_scan *scan;
+	size_t len, scan_len;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	scan_len = sizeof(*scan);
+	len = sizeof(*control) + scan_len;
+	control = kzalloc(len, GFP_KERNEL);
+	scan = (struct s_lmo_scan *) (control + 1);
+
+	control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET;
+	control->length = scan_len;
+	control->oid = LM_OID_SCAN;
+
+	scan->flags = LM_SCAN_EXIT;
+	scan->bratemask = 0x15f;
+	scan->aloft[0] = 3;
+	scan->aloft[1] = 3;
+	scan->aloft[2] = 1;
+	scan->aloft[3] = 0;
+	scan->aloft[4] = 0;
+	scan->aloft[5] = 0;
+	scan->aloft[6] = 0;
+	scan->aloft[7] = 0;
+
+	memcpy(&scan->rssical, &stlc->cal_rssi[(stlc->channel - 1) *
+					       RSSI_CAL_LEN],
+	       RSSI_CAL_LEN);
+	memcpy(&scan->channel, &stlc->cal_channels[(stlc->channel - 1) *
+						   CHANNEL_CAL_LEN],
+	       CHANNEL_CAL_LEN);
+
+	stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len);
+
+	kfree(control);
+}
+
+/*
+ * caller must hold mutex
+ */
+static int stlc45xx_tx_pspoll(struct stlc45xx *stlc, bool powersave)
+{
+	struct ieee80211_hdr *pspoll;
+	int payload_len, padding, i;
+	struct s_lm_data_out *data;
+	struct txbuffer *entry;
+	DECLARE_MAC_BUF(mac);
+	struct sk_buff *skb;
+	char *payload;
+	u16 fc;
+
+	skb = dev_alloc_skb(stlc->hw->extra_tx_headroom + 16);
+	if (!skb) {
+		stlc45xx_warning("failed to allocate pspoll frame");
+		return -ENOMEM;
+	}
+	skb_reserve(skb, stlc->hw->extra_tx_headroom);
+
+	pspoll = (struct ieee80211_hdr *) skb_put(skb, 16);
+	memset(pspoll, 0, 16);
+	fc = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL;
+	if (powersave)
+		fc |= IEEE80211_FCTL_PM;
+	pspoll->frame_control = cpu_to_le16(fc);
+	pspoll->duration_id = cpu_to_le16(stlc->aid);
+
+	/* aid in PS-Poll has its two MSBs each set to 1 */
+	pspoll->duration_id |= cpu_to_le16(1 << 15) | cpu_to_le16(1 << 14);
+
+	memcpy(pspoll->addr1, stlc->bssid, ETH_ALEN);
+	memcpy(pspoll->addr2, stlc->mac_addr, ETH_ALEN);
+
+	stlc45xx_debug(DEBUG_PSM, "sending PS-Poll frame to %s (powersave %d, "
+		       "fc 0x%x, aid %d)", print_mac(mac, pspoll->addr1),
+		       powersave, fc, stlc->aid);
+
+	spin_lock_bh(&stlc->tx_lock);
+
+	entry = stlc45xx_txbuffer_alloc(stlc, skb->len);
+
+	spin_unlock_bh(&stlc->tx_lock);
+
+	if (!entry) {
+		/*
+		 * The queue should be stopped before the firmware buffer
+		 * is full, so firmware buffer should always have enough
+		 * space.
+		 *
+		 * But I'm too lazy and omit it for now.
+		 */
+		if (net_ratelimit())
+			stlc45xx_warning("firmware tx buffer full is full "
+					 "for null frame");
+		return -ENOSPC;
+	}
+
+	payload = skb->data;
+	payload_len = skb->len;
+	padding = (int) (skb->data - sizeof(*data)) & 3;
+	entry->header_len = sizeof(*data) + padding;
+
+	entry->skb = skb;
+	entry->status_needed = false;
+	entry->handle = (u32) skb;
+	entry->lifetime = jiffies + msecs_to_jiffies(TX_FRAME_LIFETIME);
+
+	stlc45xx_debug(DEBUG_TX, "tx data 0x%x (0x%p payload %d B "
+		       "padding %d header_len %d)",
+		       entry->handle, payload, payload_len, padding,
+		       entry->header_len);
+	stlc45xx_dump(DEBUG_TX_CONTENT, payload, payload_len);
+
+	data = (struct s_lm_data_out *) skb_push(skb, entry->header_len);
+
+	memset(data, 0, entry->header_len);
+
+	if (padding)
+		data->flags = LM_FLAG_ALIGN;
+
+	data->flags = LM_OUT_BURST;
+	data->length = payload_len;
+	data->handle = entry->handle;
+	data->aid = 1;
+	data->rts_retries = 7;
+	data->retries = 7;
+	data->aloft_ctrl = 0;
+	data->crypt_offset = 58;
+	data->keytype = 0;
+	data->keylen = 0;
+	data->queue = LM_QUEUE_DATA3;
+	data->backlog = 32;
+	data->antenna = 2;
+	data->cts = 3;
+	data->power = 127;
+
+	for (i = 0; i < 8; i++)
+		data->aloft[i] = 0;
+
+	/*
+	 * check if there's enough space in tx buffer
+	 *
+	 * FIXME: ignored for now
+	 */
+
+	stlc45xx_tx_frame(stlc, entry->start, skb->data, skb->len);
+
+	list_add(&entry->tx_list, &stlc->tx_sent);
+
+	return 0;
+}
+
+/*
+ * caller must hold mutex
+ *
+ * shamelessly stolen from mac80211/ieee80211_send_nullfunc
+ */
+static int stlc45xx_tx_nullfunc(struct stlc45xx *stlc, bool powersave)
+{
+	struct ieee80211_hdr *nullfunc;
+	int payload_len, padding, i;
+	struct s_lm_data_out *data;
+	struct txbuffer *entry;
+	DECLARE_MAC_BUF(mac);
+	struct sk_buff *skb;
+	char *payload;
+	u16 fc;
+
+	skb = dev_alloc_skb(stlc->hw->extra_tx_headroom + 24);
+	if (!skb) {
+		stlc45xx_warning("failed to allocate buffer for null frame\n");
+		return -ENOMEM;
+	}
+	skb_reserve(skb, stlc->hw->extra_tx_headroom);
+
+	nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24);
+	memset(nullfunc, 0, 24);
+	fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
+	     IEEE80211_FCTL_TODS;
+
+	if (powersave)
+		fc |= IEEE80211_FCTL_PM;
+
+	nullfunc->frame_control = cpu_to_le16(fc);
+	memcpy(nullfunc->addr1, stlc->bssid, ETH_ALEN);
+	memcpy(nullfunc->addr2, stlc->mac_addr, ETH_ALEN);
+	memcpy(nullfunc->addr3, stlc->bssid, ETH_ALEN);
+
+	stlc45xx_debug(DEBUG_PSM, "sending Null frame to %s (powersave %d, "
+		       "fc 0x%x)",
+		       print_mac(mac, nullfunc->addr1), powersave, fc);
+
+	spin_lock_bh(&stlc->tx_lock);
+
+	entry = stlc45xx_txbuffer_alloc(stlc, skb->len);
+
+	spin_unlock_bh(&stlc->tx_lock);
+
+	if (!entry) {
+		/*
+		 * The queue should be stopped before the firmware buffer
+		 * is full, so firmware buffer should always have enough
+		 * space.
+		 *
+		 * But I'm too lazy and omit it for now.
+		 */
+		if (net_ratelimit())
+			stlc45xx_warning("firmware tx buffer full is full "
+					 "for null frame");
+		return -ENOSPC;
+	}
+
+	payload = skb->data;
+	payload_len = skb->len;
+	padding = (int) (skb->data - sizeof(*data)) & 3;
+	entry->header_len = sizeof(*data) + padding;
+
+	entry->skb = skb;
+	entry->status_needed = false;
+	entry->handle = (u32) skb;
+	entry->lifetime = jiffies + msecs_to_jiffies(TX_FRAME_LIFETIME);
+
+	stlc45xx_debug(DEBUG_TX, "tx data 0x%x (0x%p payload %d B "
+		       "padding %d header_len %d)",
+		       entry->handle, payload, payload_len, padding,
+		       entry->header_len);
+	stlc45xx_dump(DEBUG_TX_CONTENT, payload, payload_len);
+
+	data = (struct s_lm_data_out *) skb_push(skb, entry->header_len);
+
+	memset(data, 0, entry->header_len);
+
+	if (padding)
+		data->flags = LM_FLAG_ALIGN;
+
+	data->flags = LM_OUT_BURST;
+	data->length = payload_len;
+	data->handle = entry->handle;
+	data->aid = 1;
+	data->rts_retries = 7;
+	data->retries = 7;
+	data->aloft_ctrl = 0;
+	data->crypt_offset = 58;
+	data->keytype = 0;
+	data->keylen = 0;
+	data->queue = LM_QUEUE_DATA3;
+	data->backlog = 32;
+	data->antenna = 2;
+	data->cts = 3;
+	data->power = 127;
+
+	for (i = 0; i < 8; i++)
+		data->aloft[i] = 0;
+
+	/*
+	 * check if there's enough space in tx buffer
+	 *
+	 * FIXME: ignored for now
+	 */
+
+	stlc45xx_tx_frame(stlc, entry->start, skb->data, skb->len);
+
+	list_add(&entry->tx_list, &stlc->tx_sent);
+
+	return 0;
+}
+
+/* caller must hold mutex */
+static void stlc45xx_tx_psm(struct stlc45xx *stlc, bool enable)
+{
+	struct s_lm_control *control;
+	struct s_lmo_psm *psm;
+	size_t len, psm_len;
+
+	WARN_ON(!stlc->associated);
+	WARN_ON(stlc->aid < 1);
+	WARN_ON(stlc->aid > 2007);
+
+	psm_len = sizeof(*psm);
+	len = sizeof(*control) + psm_len;
+	control = kzalloc(len, GFP_KERNEL);
+	psm = (struct s_lmo_psm *) (control + 1);
+
+	control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET;
+	control->length = psm_len;
+	control->oid = LM_OID_PSM;
+
+	if (enable)
+		psm->flags |= LM_PSM;
+
+	psm->aid = stlc->aid;
+
+	psm->beacon_rcpi_skip_max = 60;
+
+	psm->intervals[0].interval = 1;
+	psm->intervals[0].periods = 1;
+	psm->intervals[1].interval = 1;
+	psm->intervals[1].periods = 1;
+	psm->intervals[2].interval = 1;
+	psm->intervals[2].periods = 1;
+	psm->intervals[3].interval = 1;
+	psm->intervals[3].periods = 1;
+
+	psm->nr = 0;
+	psm->exclude[0] = 0;
+
+	stlc45xx_debug(DEBUG_PSM, "sending LM_OID_PSM (aid %d, interval %d)",
+		       psm->aid, psm->intervals[0].interval);
+
+	stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len);
+
+	kfree(control);
+}
+
+static int stlc45xx_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+	struct stlc45xx *stlc = hw->priv;
+	struct ieee80211_tx_info *info;
+	struct ieee80211_rate *rate;
+	int payload_len, padding, i;
+	struct s_lm_data_out *data;
+	struct txbuffer *entry;
+	char *payload;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	spin_lock_bh(&stlc->tx_lock);
+
+	entry = stlc45xx_txbuffer_alloc(stlc, skb->len);
+	if (!entry) {
+		/* the queue should be stopped before the firmware buffer
+		 * is full, so firmware buffer should always have enough
+		 * space */
+		if (net_ratelimit())
+			stlc45xx_warning("firmware buffer full");
+		spin_unlock_bh(&stlc->tx_lock);
+		return NETDEV_TX_BUSY;
+	}
+
+	info = IEEE80211_SKB_CB(skb);
+
+	payload = skb->data;
+	payload_len = skb->len;
+	padding = (int) (skb->data - sizeof(*data)) & 3;
+	entry->header_len = sizeof(*data) + padding;
+
+	entry->skb = skb;
+	entry->status_needed = true;
+	entry->handle = (u32) skb;
+	entry->lifetime = jiffies + msecs_to_jiffies(TX_FRAME_LIFETIME);
+
+	stlc45xx_debug(DEBUG_TX, "tx data 0x%x (0x%p payload %d B "
+		       "padding %d header_len %d)",
+		       entry->handle, payload, payload_len, padding,
+		       entry->header_len);
+	stlc45xx_dump(DEBUG_TX_CONTENT, payload, payload_len);
+
+	data = (struct s_lm_data_out *) skb_push(skb, entry->header_len);
+
+	memset(data, 0, entry->header_len);
+
+	if (padding)
+		data->flags = LM_FLAG_ALIGN;
+
+	data->flags = LM_OUT_BURST;
+	data->length = payload_len;
+	data->handle = entry->handle;
+	data->aid = 1;
+	data->rts_retries = 7;
+	data->retries = 7;
+	data->aloft_ctrl = 0;
+	data->crypt_offset = 58;
+	data->keytype = 0;
+	data->keylen = 0;
+	data->queue = 2;
+	data->backlog = 32;
+	data->antenna = 2;
+	data->cts = 3;
+	data->power = 127;
+
+	for (i = 0; i < 8; i++) {
+		rate = ieee80211_get_tx_rate(stlc->hw, info);
+		data->aloft[i] = rate->hw_value;
+	}
+
+	list_add_tail(&entry->tx_list, &stlc->tx_pending);
+
+	/* check if there's enough space in tx buffer */
+	if (stlc45xx_txbuffer_find(stlc, MAX_FRAME_LEN) == -1) {
+		stlc45xx_debug(DEBUG_QUEUE, "tx buffer full, stopping queues");
+		stlc->tx_queue_stopped = 1;
+		ieee80211_stop_queues(stlc->hw);
+	}
+
+	queue_work(stlc->hw->workqueue, &stlc->work);
+
+	spin_unlock_bh(&stlc->tx_lock);
+
+	return NETDEV_TX_OK;
+}
+
+static int stlc45xx_op_start(struct ieee80211_hw *hw)
+{
+	struct stlc45xx *stlc = hw->priv;
+	unsigned long timeout;
+	int ret = 0;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	mutex_lock(&stlc->mutex);
+
+	stlc->fw_state = FW_STATE_BOOTING;
+	stlc->channel = 1;
+
+	stlc45xx_power_on(stlc);
+
+	ret = stlc45xx_upload_firmware(stlc);
+	if (ret < 0) {
+		stlc45xx_power_off(stlc);
+		goto out_unlock;
+	}
+
+	stlc->tx_queue_stopped = 0;
+
+	mutex_unlock(&stlc->mutex);
+
+	timeout = msecs_to_jiffies(2000);
+	timeout = wait_for_completion_interruptible_timeout(&stlc->fw_comp,
+							    timeout);
+	if (!timeout) {
+		stlc45xx_error("firmware boot failed");
+		stlc45xx_power_off(stlc);
+		ret = -1;
+		goto out;
+	}
+
+	stlc45xx_debug(DEBUG_BOOT, "firmware booted");
+
+	/* FIXME: should we take mutex just after wait_for_completion()? */
+	mutex_lock(&stlc->mutex);
+
+	WARN_ON(stlc->fw_state != FW_STATE_READY);
+
+out_unlock:
+	mutex_unlock(&stlc->mutex);
+
+out:
+	return ret;
+}
+
+static void stlc45xx_op_stop(struct ieee80211_hw *hw)
+{
+	struct stlc45xx *stlc = hw->priv;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	mutex_lock(&stlc->mutex);
+
+	WARN_ON(stlc->fw_state != FW_STATE_READY);
+
+	stlc45xx_power_off(stlc);
+
+	/* FIXME: make sure that all work_structs have completed */
+
+	spin_lock_bh(&stlc->tx_lock);
+	stlc45xx_flush_queues(stlc);
+	spin_unlock_bh(&stlc->tx_lock);
+
+	stlc->fw_state = FW_STATE_OFF;
+
+	mutex_unlock(&stlc->mutex);
+}
+
+static int stlc45xx_op_add_interface(struct ieee80211_hw *hw,
+				     struct ieee80211_if_init_conf *conf)
+{
+	struct stlc45xx *stlc = hw->priv;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	switch (conf->type) {
+	case NL80211_IFTYPE_STATION:
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	memcpy(stlc->mac_addr, conf->mac_addr, ETH_ALEN);
+
+	return 0;
+}
+
+static void stlc45xx_op_remove_interface(struct ieee80211_hw *hw,
+					 struct ieee80211_if_init_conf *conf)
+{
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+}
+
+static int stlc45xx_op_config_interface(struct ieee80211_hw *hw,
+					struct ieee80211_vif *vif,
+					struct ieee80211_if_conf *conf)
+{
+	struct stlc45xx *stlc = hw->priv;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	mutex_lock(&stlc->mutex);
+
+	memcpy(stlc->bssid, conf->bssid, ETH_ALEN);
+	stlc45xx_tx_setup(stlc);
+
+	mutex_unlock(&stlc->mutex);
+
+	return 0;
+}
+
+static int stlc45xx_op_config(struct ieee80211_hw *hw, u32 changed)
+{
+	struct stlc45xx *stlc = hw->priv;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	mutex_lock(&stlc->mutex);
+
+	stlc->channel = hw->conf.channel->hw_value;
+	stlc45xx_tx_scan(stlc);
+	stlc45xx_tx_setup(stlc);
+	stlc45xx_tx_edcf(stlc);
+
+	if ((hw->conf.flags & IEEE80211_CONF_PS) != stlc->psm) {
+		stlc->psm = hw->conf.flags & IEEE80211_CONF_PS;
+		if (stlc->associated) {
+			stlc45xx_tx_psm(stlc, stlc->psm);
+			stlc45xx_tx_nullfunc(stlc, stlc->psm);
+		}
+	}
+
+	mutex_unlock(&stlc->mutex);
+
+	return 0;
+}
+
+static void stlc45xx_op_configure_filter(struct ieee80211_hw *hw,
+				      unsigned int changed_flags,
+				      unsigned int *total_flags,
+				      int mc_count,
+				      struct dev_addr_list *mc_list)
+{
+	*total_flags = 0;
+}
+
+static void stlc45xx_op_bss_info_changed(struct ieee80211_hw *hw,
+					 struct ieee80211_vif *vif,
+					 struct ieee80211_bss_conf *info,
+					 u32 changed)
+{
+	struct stlc45xx *stlc = hw->priv;
+
+	if (changed & BSS_CHANGED_ASSOC) {
+		stlc->associated = info->assoc;
+		if (info->assoc)
+			stlc->aid = info->aid;
+		else
+			stlc->aid = -1;
+
+		if (stlc->psm) {
+			stlc45xx_tx_psm(stlc, stlc->psm);
+			stlc45xx_tx_nullfunc(stlc, stlc->psm);
+		}
+	}
+}
+
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_rate stlc45xx_rates[] = {
+	{ .bitrate = 10,  .hw_value = 0,    .hw_value_short = 0, },
+	{ .bitrate = 20,  .hw_value = 1,    .hw_value_short = 1, },
+	{ .bitrate = 55,  .hw_value = 2,    .hw_value_short = 2, },
+	{ .bitrate = 110, .hw_value = 3,    .hw_value_short = 3, },
+	{ .bitrate = 60,  .hw_value = 4,    .hw_value_short = 4, },
+	{ .bitrate = 90,  .hw_value = 5,    .hw_value_short = 5, },
+	{ .bitrate = 120, .hw_value = 6,    .hw_value_short = 6, },
+	{ .bitrate = 180, .hw_value = 7,    .hw_value_short = 7, },
+	{ .bitrate = 240, .hw_value = 8,    .hw_value_short = 8, },
+	{ .bitrate = 360, .hw_value = 9,    .hw_value_short = 9, },
+	{ .bitrate = 480, .hw_value = 10,   .hw_value_short = 10, },
+	{ .bitrate = 540, .hw_value = 11,   .hw_value_short = 11, },
+};
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_channel stlc45xx_channels[] = {
+	{ .hw_value = 1, .center_freq = 2412},
+	{ .hw_value = 2, .center_freq = 2417},
+	{ .hw_value = 3, .center_freq = 2422},
+	{ .hw_value = 4, .center_freq = 2427},
+	{ .hw_value = 5, .center_freq = 2432},
+	{ .hw_value = 6, .center_freq = 2437},
+	{ .hw_value = 7, .center_freq = 2442},
+	{ .hw_value = 8, .center_freq = 2447},
+	{ .hw_value = 9, .center_freq = 2452},
+	{ .hw_value = 10, .center_freq = 2457},
+	{ .hw_value = 11, .center_freq = 2462},
+	{ .hw_value = 12, .center_freq = 2467},
+	{ .hw_value = 13, .center_freq = 2472},
+};
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_supported_band stlc45xx_band_2ghz = {
+	.channels = stlc45xx_channels,
+	.n_channels = ARRAY_SIZE(stlc45xx_channels),
+	.bitrates = stlc45xx_rates,
+	.n_bitrates = ARRAY_SIZE(stlc45xx_rates),
+};
+
+static const struct ieee80211_ops stlc45xx_ops = {
+	.start = stlc45xx_op_start,
+	.stop = stlc45xx_op_stop,
+	.add_interface = stlc45xx_op_add_interface,
+	.remove_interface = stlc45xx_op_remove_interface,
+	.config = stlc45xx_op_config,
+	.config_interface = stlc45xx_op_config_interface,
+	.configure_filter = stlc45xx_op_configure_filter,
+	.tx = stlc45xx_op_tx,
+	.bss_info_changed = stlc45xx_op_bss_info_changed,
+};
+
+static int stlc45xx_register_mac80211(struct stlc45xx *stlc)
+{
+	/* FIXME: SET_IEEE80211_PERM_ADDR() requires default_mac_addr
+	   to be non-const for some strange reason */
+	static u8 default_mac_addr[ETH_ALEN] = {
+		0x00, 0x02, 0xee, 0xc0, 0xff, 0xee
+	};
+	int ret;
+
+	SET_IEEE80211_PERM_ADDR(stlc->hw, default_mac_addr);
+
+	ret = ieee80211_register_hw(stlc->hw);
+	if (ret) {
+		stlc45xx_error("unable to register mac80211 hw: %d", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void stlc45xx_device_release(struct device *dev)
+{
+
+}
+
+static struct platform_device stlc45xx_device = {
+	.name		= "stlc45xx",
+	.id		= -1,
+
+	/* device model insists to have a release function */
+	.dev            = {
+		.release = stlc45xx_device_release,
+	},
+};
+
+static int __devinit stlc45xx_probe(struct spi_device *spi)
+{
+	struct stlc45xx *stlc;
+	struct ieee80211_hw *hw;
+	int ret;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	/* mac80211 alloc */
+	hw = ieee80211_alloc_hw(sizeof(*stlc), &stlc45xx_ops);
+	if (!hw) {
+		stlc45xx_error("could not alloc ieee80211_hw");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* mac80211 clears hw->priv */
+	stlc = hw->priv;
+
+	stlc->hw = hw;
+	dev_set_drvdata(&spi->dev, stlc);
+	stlc->spi = spi;
+
+	spi->bits_per_word = 16;
+	spi->max_speed_hz = 24000000;
+
+	ret = spi_setup(spi);
+	if (ret < 0)
+		stlc45xx_error("spi_setup failed");
+
+	ret = gpio_request(stlc45xx_gpio_power, "stlc45xx power");
+	if (ret < 0) {
+		stlc45xx_error("power GPIO request failed: %d", ret);
+		return ret;
+	}
+
+	ret = gpio_request(stlc45xx_gpio_irq, "stlc45xx irq");
+	if (ret < 0) {
+		stlc45xx_error("irq GPIO request failed: %d", ret);
+		goto out;
+	}
+
+	gpio_direction_output(stlc45xx_gpio_power, 0);
+	gpio_direction_input(stlc45xx_gpio_irq);
+
+	ret = request_irq(gpio_to_irq(stlc45xx_gpio_irq),
+			  stlc45xx_interrupt, IRQF_DISABLED, "stlc45xx",
+			  stlc->spi);
+	if (ret < 0)
+		/* FIXME: handle the error */
+		stlc45xx_error("request_irq() failed");
+
+	set_irq_type(gpio_to_irq(stlc45xx_gpio_irq),
+		     IRQ_TYPE_EDGE_RISING);
+
+	disable_irq(gpio_to_irq(stlc45xx_gpio_irq));
+
+	ret = platform_device_register(&stlc45xx_device);
+	if (ret) {
+		stlc45xx_error("Couldn't register wlan_omap device.");
+		return ret;
+	}
+	dev_set_drvdata(&stlc45xx_device.dev, stlc);
+
+	INIT_WORK(&stlc->work, stlc45xx_work);
+	INIT_WORK(&stlc->work_reset, stlc45xx_work_reset);
+	INIT_DELAYED_WORK(&stlc->work_tx_timeout, stlc45xx_work_tx_timeout);
+	mutex_init(&stlc->mutex);
+	init_completion(&stlc->fw_comp);
+	spin_lock_init(&stlc->tx_lock);
+	INIT_LIST_HEAD(&stlc->txbuffer);
+	INIT_LIST_HEAD(&stlc->tx_pending);
+	INIT_LIST_HEAD(&stlc->tx_sent);
+
+	hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
+		IEEE80211_HW_SIGNAL_DBM |
+		IEEE80211_HW_NOISE_DBM;
+	/* four bytes for padding */
+	hw->extra_tx_headroom = sizeof(struct s_lm_data_out) + 4;
+
+	/* unit us */
+	hw->channel_change_time = 1000;
+
+	hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+	hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &stlc45xx_band_2ghz;
+
+	SET_IEEE80211_DEV(hw, &spi->dev);
+
+	BUILD_BUG_ON(sizeof(default_cal_rssi) != RSSI_CAL_ARRAY_LEN);
+	BUILD_BUG_ON(sizeof(default_cal_channels) != CHANNEL_CAL_ARRAY_LEN);
+
+	stlc->cal_rssi = kmemdup(default_cal_rssi, RSSI_CAL_ARRAY_LEN,
+				 GFP_KERNEL);
+	stlc->cal_channels = kmemdup(default_cal_channels,
+				     CHANNEL_CAL_ARRAY_LEN,
+				     GFP_KERNEL);
+
+	ret = device_create_file(&stlc45xx_device.dev, &dev_attr_cal_rssi);
+	if (ret < 0) {
+		stlc45xx_error("failed to create sysfs file cal_rssi");
+		goto out;
+	}
+
+	ret = device_create_file(&stlc45xx_device.dev, &dev_attr_cal_channels);
+	if (ret < 0) {
+		stlc45xx_error("failed to create sysfs file cal_channels");
+		goto out;
+	}
+
+	ret = device_create_file(&stlc45xx_device.dev, &dev_attr_tx_buf);
+	if (ret < 0) {
+		stlc45xx_error("failed to create sysfs file tx_buf");
+		goto out;
+	}
+
+	ret = stlc45xx_register_mac80211(stlc);
+	if (ret < 0)
+		goto out;
+
+	stlc45xx_info("v" DRIVER_VERSION " loaded");
+
+	stlc45xx_info("config buffer 0x%x-0x%x",
+		      FIRMWARE_CONFIG_START, FIRMWARE_CONFIG_END);
+	stlc45xx_info("tx 0x%x-0x%x, rx 0x%x-0x%x",
+		      FIRMWARE_TXBUFFER_START, FIRMWARE_TXBUFFER_END,
+		      FIRMWARE_RXBUFFER_START, FIRMWARE_RXBUFFER_END);
+
+out:
+	return ret;
+}
+
+static int __devexit stlc45xx_remove(struct spi_device *spi)
+{
+	struct stlc45xx *stlc = dev_get_drvdata(&spi->dev);
+
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	platform_device_unregister(&stlc45xx_device);
+
+	ieee80211_unregister_hw(stlc->hw);
+
+	free_irq(gpio_to_irq(stlc45xx_gpio_irq), spi);
+
+	gpio_free(stlc45xx_gpio_power);
+	gpio_free(stlc45xx_gpio_irq);
+
+	/* FIXME: free cal_channels and cal_rssi? */
+
+	kfree(stlc->fw);
+
+	mutex_destroy(&stlc->mutex);
+
+	/* frees also stlc */
+	ieee80211_free_hw(stlc->hw);
+	stlc = NULL;
+
+	return 0;
+}
+
+
+static struct spi_driver stlc45xx_spi_driver = {
+	.driver = {
+		/* use cx3110x name because board-n800.c uses that for the
+		 * SPI port */
+		.name		= "cx3110x",
+		.bus		= &spi_bus_type,
+		.owner		= THIS_MODULE,
+	},
+
+	.probe		= stlc45xx_probe,
+	.remove		= __devexit_p(stlc45xx_remove),
+};
+
+static int __init stlc45xx_init(void)
+{
+	int ret;
+
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	ret = spi_register_driver(&stlc45xx_spi_driver);
+	if (ret < 0) {
+		stlc45xx_error("failed to register SPI driver: %d", ret);
+		goto out;
+	}
+
+out:
+	return ret;
+}
+
+static void __exit stlc45xx_exit(void)
+{
+	stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+	spi_unregister_driver(&stlc45xx_spi_driver);
+
+	stlc45xx_info("unloaded");
+}
+
+module_init(stlc45xx_init);
+module_exit(stlc45xx_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>");
diff --git a/drivers/staging/stlc45xx/stlc45xx.h b/drivers/staging/stlc45xx/stlc45xx.h
new file mode 100644
index 0000000..ac96bbb
--- /dev/null
+++ b/drivers/staging/stlc45xx/stlc45xx.h
@@ -0,0 +1,283 @@
+/*
+ * This file is part of stlc45xx
+ *
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <net/mac80211.h>
+
+#include "stlc45xx_lmac.h"
+
+#define DRIVER_NAME "stlc45xx"
+#define DRIVER_VERSION "0.1.3"
+
+#define DRIVER_PREFIX DRIVER_NAME ": "
+
+enum {
+	DEBUG_NONE = 0,
+	DEBUG_FUNC = 1 << 0,
+	DEBUG_IRQ = 1 << 1,
+	DEBUG_BH = 1 << 2,
+	DEBUG_RX = 1 << 3,
+	DEBUG_RX_CONTENT = 1 << 5,
+	DEBUG_TX = 1 << 6,
+	DEBUG_TX_CONTENT = 1 << 8,
+	DEBUG_TXBUFFER = 1 << 9,
+	DEBUG_QUEUE = 1 << 10,
+	DEBUG_BOOT = 1 << 11,
+	DEBUG_PSM = 1 << 12,
+	DEBUG_ALL = ~0,
+};
+
+#define DEBUG_LEVEL DEBUG_NONE
+/* #define DEBUG_LEVEL DEBUG_ALL */
+/* #define DEBUG_LEVEL (DEBUG_TX | DEBUG_RX | DEBUG_IRQ) */
+/* #define DEBUG_LEVEL (DEBUG_TX | DEBUG_MEMREGION | DEBUG_QUEUE) */
+/* #define DEBUG_LEVEL (DEBUG_MEMREGION | DEBUG_QUEUE) */
+
+#define stlc45xx_error(fmt, arg...) \
+	printk(KERN_ERR DRIVER_PREFIX "ERROR " fmt "\n", ##arg)
+
+#define stlc45xx_warning(fmt, arg...) \
+	printk(KERN_WARNING DRIVER_PREFIX "WARNING " fmt "\n", ##arg)
+
+#define stlc45xx_info(fmt, arg...) \
+	printk(KERN_INFO DRIVER_PREFIX fmt "\n", ##arg)
+
+#define stlc45xx_debug(level, fmt, arg...) \
+	do { \
+		if (level & DEBUG_LEVEL) \
+			printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg); \
+	} while (0)
+
+#define stlc45xx_dump(level, buf, len)		\
+	do { \
+		if (level & DEBUG_LEVEL) \
+			print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, \
+				       16, 1, buf, len, 1);		\
+	} while (0)
+
+#define MAC2STR(a) ((a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5])
+#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
+
+/* Bit 15 is read/write bit; ON = READ, OFF = WRITE */
+#define ADDR_READ_BIT_15  0x8000
+
+#define SPI_ADRS_ARM_INTERRUPTS     0x00
+#define SPI_ADRS_ARM_INT_EN	    0x04
+
+#define SPI_ADRS_HOST_INTERRUPTS    0x08
+#define SPI_ADRS_HOST_INT_EN	    0x0c
+#define SPI_ADRS_HOST_INT_ACK	    0x10
+
+#define SPI_ADRS_GEN_PURP_1   	    0x14
+#define SPI_ADRS_GEN_PURP_2   	    0x18
+
+/* high word */
+#define SPI_ADRS_DEV_CTRL_STAT      0x26
+
+#define SPI_ADRS_DMA_DATA      	    0x28
+
+#define SPI_ADRS_DMA_WRITE_CTRL     0x2c
+#define SPI_ADRS_DMA_WRITE_LEN      0x2e
+#define SPI_ADRS_DMA_WRITE_BASE     0x30
+
+#define SPI_ADRS_DMA_READ_CTRL      0x34
+#define SPI_ADRS_DMA_READ_LEN       0x36
+#define SPI_ADRS_DMA_READ_BASE      0x38
+
+#define SPI_CTRL_STAT_HOST_OVERRIDE 0x8000
+#define SPI_CTRL_STAT_START_HALTED  0x4000
+#define SPI_CTRL_STAT_RAM_BOOT      0x2000
+#define SPI_CTRL_STAT_HOST_RESET    0x1000
+#define SPI_CTRL_STAT_HOST_CPU_EN   0x0800
+
+#define SPI_DMA_WRITE_CTRL_ENABLE   0x0001
+#define SPI_DMA_READ_CTRL_ENABLE    0x0001
+#define HOST_ALLOWED                (1 << 7)
+
+#define FIRMWARE_ADDRESS                        0x20000
+
+#define SPI_TIMEOUT                             100         /* msec */
+
+#define SPI_MAX_TX_PACKETS                      32
+
+#define SPI_MAX_PACKET_SIZE                     32767
+
+#define SPI_TARGET_INT_WAKEUP                   0x00000001
+#define SPI_TARGET_INT_SLEEP                    0x00000002
+#define SPI_TARGET_INT_RDDONE                   0x00000004
+
+#define SPI_TARGET_INT_CTS                      0x00004000
+#define SPI_TARGET_INT_DR                       0x00008000
+
+#define SPI_HOST_INT_READY                      0x00000001
+#define SPI_HOST_INT_WR_READY                   0x00000002
+#define SPI_HOST_INT_SW_UPDATE                  0x00000004
+#define SPI_HOST_INT_UPDATE                     0x10000000
+
+/* clear to send */
+#define SPI_HOST_INT_CTS	                0x00004000
+
+/* data ready */
+#define SPI_HOST_INT_DR	                        0x00008000
+
+#define SPI_HOST_INTS_DEFAULT \
+	(SPI_HOST_INT_READY | SPI_HOST_INT_UPDATE | SPI_HOST_INT_SW_UPDATE)
+
+#define TARGET_BOOT_SLEEP 50
+
+/* The firmware buffer is divided into three areas:
+ *
+ * o config area (for control commands)
+ * o tx buffer
+ * o rx buffer
+ */
+#define FIRMWARE_BUFFER_START 0x20200
+#define FIRMWARE_BUFFER_END 0x27c60
+#define FIRMWARE_BUFFER_LEN (FIRMWARE_BUFFER_END - FIRMWARE_BUFFER_START)
+#define FIRMWARE_MTU 3240
+#define FIRMWARE_CONFIG_PAYLOAD_LEN 1024
+#define FIRMWARE_CONFIG_START FIRMWARE_BUFFER_START
+#define FIRMWARE_CONFIG_LEN (sizeof(struct s_lm_control) + \
+			     FIRMWARE_CONFIG_PAYLOAD_LEN)
+#define FIRMWARE_CONFIG_END (FIRMWARE_CONFIG_START + FIRMWARE_CONFIG_LEN - 1)
+#define FIRMWARE_RXBUFFER_LEN (5 * FIRMWARE_MTU + 1024)
+#define FIRMWARE_RXBUFFER_START (FIRMWARE_BUFFER_END - FIRMWARE_RXBUFFER_LEN)
+#define FIRMWARE_RXBUFFER_END (FIRMWARE_RXBUFFER_START + \
+			       FIRMWARE_RXBUFFER_LEN - 1)
+#define FIRMWARE_TXBUFFER_START (FIRMWARE_BUFFER_START + FIRMWARE_CONFIG_LEN)
+#define FIRMWARE_TXBUFFER_LEN (FIRMWARE_BUFFER_LEN - FIRMWARE_CONFIG_LEN - \
+			       FIRMWARE_RXBUFFER_LEN)
+#define FIRMWARE_TXBUFFER_END (FIRMWARE_TXBUFFER_START + \
+			       FIRMWARE_TXBUFFER_LEN - 1)
+
+#define FIRMWARE_TXBUFFER_HEADER 100
+#define FIRMWARE_TXBUFFER_TRAILER 4
+
+/* FIXME: come up with a proper value */
+#define MAX_FRAME_LEN 2500
+
+/* unit is ms */
+#define TX_FRAME_LIFETIME 2000
+#define TX_TIMEOUT 4000
+
+#define SUPPORTED_CHANNELS 13
+
+/* FIXME */
+/* #define CHANNEL_CAL_LEN offsetof(struct s_lmo_scan, bratemask) - \ */
+/* 	offsetof(struct s_lmo_scan, channel) */
+#define CHANNEL_CAL_LEN 292
+#define CHANNEL_CAL_ARRAY_LEN (SUPPORTED_CHANNELS * CHANNEL_CAL_LEN)
+/* FIXME */
+/* #define RSSI_CAL_LEN sizeof(struct s_lmo_scan) - \ */
+/* 	offsetof(struct s_lmo_scan, rssical) */
+#define RSSI_CAL_LEN 8
+#define RSSI_CAL_ARRAY_LEN (SUPPORTED_CHANNELS * RSSI_CAL_LEN)
+
+struct s_dma_regs {
+	unsigned short cmd;
+	unsigned short len;
+	unsigned long addr;
+};
+
+struct stlc45xx_ie_tim {
+	u8 dtim_count;
+	u8 dtim_period;
+	u8 bmap_control;
+	u8 pvbmap[251];
+};
+
+struct txbuffer {
+	/* can be removed when switched to skb queue */
+	struct list_head tx_list;
+
+	struct list_head buffer_list;
+
+	int start;
+	int frame_start;
+	int end;
+
+	struct sk_buff *skb;
+	u32 handle;
+
+	bool status_needed;
+
+	int header_len;
+
+	/* unit jiffies */
+	unsigned long lifetime;
+};
+
+enum fw_state {
+	FW_STATE_OFF,
+	FW_STATE_BOOTING,
+	FW_STATE_READY,
+	FW_STATE_RESET,
+	FW_STATE_RESETTING,
+};
+
+struct stlc45xx {
+	struct ieee80211_hw *hw;
+	struct spi_device *spi;
+	struct work_struct work;
+	struct work_struct work_reset;
+	struct delayed_work work_tx_timeout;
+	struct mutex mutex;
+	struct completion fw_comp;
+
+
+	u8 bssid[ETH_ALEN];
+	u8 mac_addr[ETH_ALEN];
+	int channel;
+
+	u8 *cal_rssi;
+	u8 *cal_channels;
+
+	enum fw_state fw_state;
+
+	spinlock_t tx_lock;
+
+	/* protected by tx_lock */
+	struct list_head txbuffer;
+
+	/* protected by tx_lock */
+	struct list_head tx_pending;
+
+	/* protected by tx_lock */
+	int tx_queue_stopped;
+
+	/* protected by mutex */
+	struct list_head tx_sent;
+
+	int tx_frames;
+
+	u8 *fw;
+	int fw_len;
+
+	bool psm;
+	bool associated;
+	int aid;
+	bool pspolling;
+};
+
+
diff --git a/drivers/staging/stlc45xx/stlc45xx_lmac.h b/drivers/staging/stlc45xx/stlc45xx_lmac.h
new file mode 100644
index 0000000..af5db801
--- /dev/null
+++ b/drivers/staging/stlc45xx/stlc45xx_lmac.h
@@ -0,0 +1,434 @@
+/************************************************************************
+*  This is the LMAC API interface header file for STLC4560.        	*
+*  Copyright (C) 2007 Conexant Systems, 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	*
+*  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 __lmac_h__
+#define __lmac_h__
+
+#define LM_TOP_VARIANT      0x0506
+#define LM_BOTTOM_VARIANT   0x0506
+
+/*
+ * LMAC - UMAC interface definition:
+ */
+
+#define LM_FLAG_CONTROL     0x8000
+#define LM_FLAG_ALIGN       0x4000
+
+#define LM_CTRL_OPSET       0x0001
+
+#define LM_OUT_PROMISC      0x0001
+#define LM_OUT_TIMESTAMP    0x0002
+#define LM_OUT_SEQNR        0x0004
+#define LM_OUT_BURST        0x0010
+#define LM_OUT_NOCANCEL     0x0020
+#define LM_OUT_CLEARTIM     0x0040
+#define LM_OUT_HITCHHIKE    0x0080
+#define LM_OUT_COMPRESS     0x0100
+#define LM_OUT_CONCAT       0x0200
+#define LM_OUT_PCS_ACCEPT   0x0400
+#define LM_OUT_WAITEOSP     0x0800
+
+
+#define LM_ALOFT_SP         0x10
+#define LM_ALOFT_CTS        0x20
+#define LM_ALOFT_RTS        0x40
+#define LM_ALOFT_MASK       0x1f
+#define LM_ALOFT_RATE       0x0f
+
+#define LM_IN_FCS_GOOD      0x0001
+#define LM_IN_MATCH_MAC     0x0002
+#define LM_IN_MCBC          0x0004
+#define LM_IN_BEACON        0x0008
+#define LM_IN_MATCH_BSS     0x0010
+#define LM_IN_BCAST_BSS     0x0020
+#define LM_IN_DATA          0x0040
+#define LM_IN_TRUNCATED     0x0080
+
+#define LM_IN_TRANSPARENT   0x0200
+
+#define LM_QUEUE_BEACON     0
+#define LM_QUEUE_SCAN       1
+#define LM_QUEUE_MGT        2
+#define LM_QUEUE_MCBC       3
+#define LM_QUEUE_DATA       4
+#define LM_QUEUE_DATA0      4
+#define LM_QUEUE_DATA1      5
+#define LM_QUEUE_DATA2      6
+#define LM_QUEUE_DATA3      7
+
+#define LM_SETUP_INFRA          0x0001
+#define LM_SETUP_IBSS           0x0002
+#define LM_SETUP_TRANSPARENT    0x0008
+#define LM_SETUP_PROMISCUOUS    0x0010
+#define LM_SETUP_HIBERNATE      0x0020
+#define LM_SETUP_NOACK          0x0040
+#define LM_SETUP_RX_DISABLED    0x0080
+
+#define LM_ANTENNA_0            0
+#define LM_ANTENNA_1            1
+#define LM_ANTENNA_DIVERSITY    2
+
+#define LM_TX_FAILED            0x0001
+#define LM_TX_PSM               0x0002
+#define LM_TX_PSM_CANCELLED	0x0004
+
+#define LM_SCAN_EXIT            0x0001
+#define LM_SCAN_TRAP            0x0002
+#define LM_SCAN_ACTIVE          0x0004
+#define LM_SCAN_FILTER          0x0008
+
+#define LM_PSM                  0x0001
+#define LM_PSM_DTIM             0x0002
+#define LM_PSM_MCBC             0x0004
+#define LM_PSM_CHECKSUM         0x0008
+#define LM_PSM_SKIP_MORE_DATA   0x0010
+#define LM_PSM_BEACON_TIMEOUT   0x0020
+#define LM_PSM_HFOSLEEP         0x0040
+#define LM_PSM_AUTOSWITCH_SLEEP 0x0080
+#define	LM_PSM_LPIT		0x0100
+#define LM_PSM_BF_UCAST_SKIP    0x0200
+#define LM_PSM_BF_MCAST_SKIP    0x0400
+
+/* hfosleep */
+#define LM_PSM_SLEEP_OPTION_MASK (LM_PSM_AUTOSWITCH_SLEEP | LM_PSM_HFOSLEEP)
+#define LM_PSM_SLEEP_OPTION_SHIFT       6
+/* hfosleepend */
+#define LM_PSM_BF_OPTION_MASK (LM_PSM_BF_MCAST_SKIP | LM_PSM_BF_UCAST_SKIP)
+#define LM_PSM_BF_OPTION_SHIFT  9
+
+
+#define LM_PRIVACC_WEP          0x01
+#define LM_PRIVACC_TKIP         0x02
+#define LM_PRIVACC_MICHAEL      0x04
+#define LM_PRIVACC_CCX_KP       0x08
+#define LM_PRIVACC_CCX_MIC      0x10
+#define LM_PRIVACC_AES_CCMP     0x20
+
+/* size of s_lm_descr in words */
+#define LM_DESCR_SIZE_WORDS     11
+
+#ifndef __ASSEMBLER__
+
+enum {
+    LM_MODE_CLIENT = 0,
+    LM_MODE_AP
+};
+
+struct s_lm_descr {
+    uint16_t modes;
+    uint16_t flags;
+    uint32_t buffer_start;
+    uint32_t buffer_end;
+    uint8_t header;
+    uint8_t trailer;
+    uint8_t tx_queues;
+    uint8_t tx_depth;
+    uint8_t privacy;
+    uint8_t rx_keycache;
+    uint8_t tim_size;
+    uint8_t pad1;
+    uint8_t rates[16];
+    uint32_t link;
+	uint16_t mtu;
+};
+
+
+struct s_lm_control {
+    uint16_t flags;
+    uint16_t length;
+    uint32_t handle;
+    uint16_t oid;
+    uint16_t pad;
+    /* uint8_t data[]; */
+};
+
+enum {
+    LM_PRIV_NONE = 0,
+    LM_PRIV_WEP,
+    LM_PRIV_TKIP,
+    LM_PRIV_TKIPMICHAEL,
+    LM_PRIV_CCX_WEPMIC,
+    LM_PRIV_CCX_KPMIC,
+    LM_PRIV_CCX_KP,
+    LM_PRIV_AES_CCMP
+};
+
+enum {
+    LM_DECRYPT_NONE,
+    LM_DECRYPT_OK,
+    LM_DECRYPT_NOKEY,
+    LM_DECRYPT_NOMICHAEL,
+    LM_DECRYPT_NOCKIPMIC,
+    LM_DECRYPT_FAIL_WEP,
+    LM_DECRYPT_FAIL_TKIP,
+    LM_DECRYPT_FAIL_MICHAEL,
+    LM_DECRYPT_FAIL_CKIPKP,
+    LM_DECRYPT_FAIL_CKIPMIC,
+    LM_DECRYPT_FAIL_AESCCMP
+};
+
+struct s_lm_data_out {
+    uint16_t flags;
+    uint16_t length;
+    uint32_t handle;
+    uint16_t aid;
+    uint8_t rts_retries;
+    uint8_t retries;
+    uint8_t aloft[8];
+    uint8_t aloft_ctrl;
+    uint8_t crypt_offset;
+    uint8_t keytype;
+    uint8_t keylen;
+    uint8_t key[16];
+    uint8_t queue;
+    uint8_t backlog;
+    uint16_t durations[4];
+    uint8_t antenna;
+    uint8_t cts;
+    int16_t power;
+    uint8_t pad[2];
+    /*uint8_t data[];*/
+};
+
+#define LM_RCPI_INVALID         (0xff)
+
+struct s_lm_data_in {
+    uint16_t flags;
+    uint16_t length;
+    uint16_t frequency;
+    uint8_t antenna;
+    uint8_t rate;
+    uint8_t rcpi;
+    uint8_t sq;
+    uint8_t decrypt;
+    uint8_t rssi_raw;
+    uint32_t clock[2];
+    /*uint8_t data[];*/
+};
+
+union u_lm_data {
+    struct s_lm_data_out out;
+    struct s_lm_data_in in;
+};
+
+enum {
+    LM_OID_SETUP	= 0,
+    LM_OID_SCAN		= 1,
+    LM_OID_TRAP		= 2,
+    LM_OID_EDCF		= 3,
+    LM_OID_KEYCACHE	= 4,
+    LM_OID_PSM		= 6,
+    LM_OID_TXCANCEL	= 7,
+    LM_OID_TX		= 8,
+    LM_OID_BURST	= 9,
+    LM_OID_STATS	= 10,
+    LM_OID_LED		= 13,
+    LM_OID_TIMER	= 15,
+    LM_OID_NAV		= 20,
+    LM_OID_PCS		= 22,
+    LM_OID_BT_BALANCER  = 28,
+    LM_OID_GROUP_ADDRESS_TABLE	= 30,
+    LM_OID_ARPTABLE     = 31,
+    LM_OID_BT_OPTIONS = 35
+};
+
+enum {
+    LM_FRONTEND_UNKNOWN = 0,
+    LM_FRONTEND_DUETTE3,
+    LM_FRONTEND_DUETTE2,
+    LM_FRONTEND_FRISBEE,
+    LM_FRONTEND_CROSSBOW,
+    LM_FRONTEND_LONGBOW
+};
+
+
+#define INVALID_LPF_BANDWIDTH   0xffff
+#define INVALID_OSC_START_DELAY 0xffff
+
+struct s_lmo_setup {
+    uint16_t flags;
+    uint8_t  macaddr[6];
+    uint8_t  bssid[6];
+    uint8_t  antenna;
+    uint8_t  rx_align;
+    uint32_t rx_buffer;
+    uint16_t rx_mtu;
+    uint16_t frontend;
+    uint16_t timeout;
+    uint16_t truncate;
+    uint32_t bratemask;
+    uint8_t  sbss_offset;
+    uint8_t  mcast_window;
+    uint8_t  rx_rssi_threshold;
+    uint8_t  rx_ed_threshold;
+    uint32_t ref_clock;
+    uint16_t lpf_bandwidth;
+    uint16_t osc_start_delay;
+};
+
+
+struct s_lmo_scan {
+    uint16_t flags;
+    uint16_t dwell;
+    uint8_t channel[292];
+    uint32_t bratemask;
+    uint8_t  aloft[8];
+    uint8_t  rssical[8];
+};
+
+
+enum {
+    LM_TRAP_SCAN = 0,
+    LM_TRAP_TIMER,
+    LM_TRAP_BEACON_TX,
+    LM_TRAP_FAA_RADIO_ON,
+    LM_TRAP_FAA_RADIO_OFF,
+    LM_TRAP_RADAR,
+    LM_TRAP_NO_BEACON,
+    LM_TRAP_TBTT,
+    LM_TRAP_SCO_ENTER,
+    LM_TRAP_SCO_EXIT
+};
+
+struct s_lmo_trap {
+    uint16_t event;
+    uint16_t frequency;
+};
+
+struct s_lmo_timer {
+    uint32_t interval;
+};
+
+struct s_lmo_nav {
+    uint32_t period;
+};
+
+
+struct s_lmo_edcf_queue;
+
+struct s_lmo_edcf {
+    uint8_t  flags;
+    uint8_t  slottime;
+    uint8_t  sifs;
+    uint8_t  eofpad;
+    struct s_lmo_edcf_queue {
+	    uint8_t  aifs;
+	    uint8_t  pad0;
+	    uint16_t cwmin;
+	    uint16_t cwmax;
+	    uint16_t txop;
+    } queues[8];
+    uint8_t  mapping[4];
+    uint16_t maxburst;
+    uint16_t round_trip_delay;
+};
+
+struct s_lmo_keycache {
+    uint8_t entry;
+    uint8_t keyid;
+    uint8_t address[6];
+    uint8_t pad[2];
+    uint8_t keytype;
+    uint8_t keylen;
+    uint8_t key[24];
+};
+
+
+struct s_lm_interval;
+
+struct s_lmo_psm {
+    uint16_t    flags;
+    uint16_t    aid;
+    struct s_lm_interval {
+	    uint16_t interval;
+	    uint16_t periods;
+    } intervals[4];
+    /* uint16_t    pad; */
+    uint8_t     beacon_rcpi_skip_max;
+    uint8_t     rcpi_delta_threshold;
+    uint8_t     nr;
+    uint8_t     exclude[1];
+};
+
+#define MC_FILTER_ADDRESS_NUM   4
+
+struct s_lmo_group_address_table {
+    uint16_t    filter_enable;
+    uint16_t    num_address;
+    uint8_t     macaddr_list[MC_FILTER_ADDRESS_NUM][6];
+};
+
+struct s_lmo_txcancel {
+    uint32_t address[1];
+};
+
+
+struct s_lmo_tx {
+    uint8_t  flags;
+    uint8_t  retries;
+    uint8_t  rcpi;
+    uint8_t  sq;
+    uint16_t seqctrl;
+    uint8_t  antenna;
+    uint8_t  pad;
+};
+
+struct s_lmo_burst {
+    uint8_t  flags;
+    uint8_t  queue;
+    uint8_t  backlog;
+    uint8_t  pad;
+    uint16_t durations[32];
+};
+
+struct s_lmo_stats {
+    uint32_t valid;
+    uint32_t fcs;
+    uint32_t abort;
+    uint32_t phyabort;
+    uint32_t rts_success;
+    uint32_t rts_fail;
+    uint32_t timestamp;
+    uint32_t time_tx;
+    uint32_t noisefloor;
+    uint32_t sample_noise[8];
+    uint32_t sample_cca;
+    uint32_t sample_tx;
+};
+
+
+struct s_lmo_led {
+    uint16_t flags;
+    uint16_t mask[2];
+    uint16_t delay/*[2]*/;
+};
+
+
+struct s_lmo_bt_balancer {
+    uint16_t prio_thresh;
+    uint16_t acl_thresh;
+};
+
+
+struct s_lmo_arp_table {
+    uint16_t    filter_enable;
+    uint32_t    ipaddr;
+};
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __lmac_h__ */
diff --git a/drivers/staging/sxg/Kconfig b/drivers/staging/sxg/Kconfig
index 6e6cf0b..c5cbdaf 100644
--- a/drivers/staging/sxg/Kconfig
+++ b/drivers/staging/sxg/Kconfig
@@ -8,4 +8,4 @@
 	  10Gbe network cards.
 
 	  To compile this driver as a module, choose
-	  M here: the module will be called sxg.
+	  M here: the module will be called sxg_nic.
diff --git a/drivers/staging/sxg/Makefile b/drivers/staging/sxg/Makefile
index ec48faa..8e05322 100644
--- a/drivers/staging/sxg/Makefile
+++ b/drivers/staging/sxg/Makefile
@@ -1 +1,3 @@
-obj-$(CONFIG_SXG)	+= sxg.o
+obj-$(CONFIG_SXG)	+= sxg_nic.o
+
+sxg_nic-y := sxg.o sxg_ethtool.o
diff --git a/drivers/staging/sxg/saharadbgdownload.h b/drivers/staging/sxg/saharadbgdownload.h
deleted file mode 100644
index d8865ba..0000000
--- a/drivers/staging/sxg/saharadbgdownload.h
+++ /dev/null
@@ -1,4854 +0,0 @@
-#define SAHARA_UCODE_VERS_STRING	"$Revision: 1.1 $"
-#define SAHARA_UCODE_VERS_DATE  	"$Date: 2008/06/27 12:58:27 $"
-#define SAHARA_UCODE_HOSTIF_ID  	3
-
-static u32 SNumSections = 0x2;
-static u32 SSectionSize[] =
-{
-	0x0000e274, 0x0000000c,
-};
-
-static u32 SSectionStart[] =
-{
-	0x00000000, 0x00001fff,
-};
-
-static unsigned char SaharaUCode[2][57972] =
-{
-{
-	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x82, 0x4d, 0x29, 0x3a,
-	0x00, 0x00, 0xb2, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x02, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
-	0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
-	0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
-	0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x40, 0x2b, 0x92,
-	0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
-	0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
-	0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
-	0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
-	0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
-	0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
-	0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
-	0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x98, 0x1e, 0x80, 0xe9, 0x9a,
-	0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
-	0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
-	0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
-	0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
-	0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x40, 0x00, 0x92,
-	0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x80, 0x01, 0x92,
-	0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0xc0, 0x01, 0x92,
-	0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x00, 0x02, 0x92,
-	0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x40, 0x02, 0x92,
-	0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x80, 0x02, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x00, 0x03, 0x92,
-	0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x40, 0x03, 0x92,
-	0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x80, 0x03, 0x92,
-	0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0xc0, 0x03, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x5f, 0x3f, 0x00, 0x34,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x42, 0xff, 0xfc, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x12, 0x80, 0xfd, 0x3a,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x8a, 0x11, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0x8d, 0xfd, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x12, 0x80, 0xfd, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0xc0, 0x01, 0x32,
-	0x38, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x84, 0x82, 0x4d, 0x28, 0x1a,
-	0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x60, 0x5f, 0x0a, 0xf6, 0x94,
-	0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0e, 0x80, 0x18, 0x92,
-	0x00, 0x00, 0xd2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0x20, 0x92,
-	0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x21, 0x92,
-	0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x21, 0x92,
-	0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x85, 0x21, 0x90,
-	0x00, 0x00, 0x4b, 0x03, 0x00, 0x00, 0x00, 0xec, 0x02, 0xc0, 0x22, 0x92,
-	0x00, 0x00, 0x43, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x40, 0x18, 0x9d,
-	0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x8b, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
-	0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xc0, 0x21, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xe8, 0x02, 0x00, 0x90, 0x72,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xb2, 0x00, 0xe9, 0xb6,
-	0x00, 0x00, 0xb0, 0x03, 0x00, 0x00, 0x00, 0x7c, 0x1e, 0xc0, 0xe7, 0x9a,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x13, 0x40, 0x01, 0x39,
-	0x00, 0x00, 0xa4, 0x03, 0x00, 0x00, 0x00, 0x08, 0xb8, 0x01, 0x00, 0x94,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb3, 0x40, 0x01, 0x39,
-	0x00, 0x00, 0xb0, 0x03, 0xb2, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x17, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x69, 0x05, 0x00, 0x10, 0x01, 0xf8, 0x02, 0x00, 0x6e, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x0a, 0x00, 0x00, 0xcc, 0x02, 0x00, 0x00, 0xb2,
-	0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x40, 0x18, 0xd2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x01, 0x00, 0x2b, 0x32,
-	0x00, 0x00, 0x57, 0x00, 0x80, 0x01, 0x00, 0x80, 0x12, 0x81, 0xfc, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x2b, 0xbc,
-	0x02, 0x00, 0x57, 0x00, 0xb0, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0xb9,
-	0x00, 0x00, 0x5a, 0x00, 0x04, 0x01, 0x00, 0x80, 0x02, 0xc0, 0xb0, 0xbc,
-	0x00, 0x00, 0x60, 0x00, 0xa0, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x5c, 0x00, 0x80, 0x01, 0x00, 0x80, 0xc2, 0x4a, 0xd0, 0xb6,
-	0x00, 0x00, 0x60, 0x00, 0xa0, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x04, 0xcd, 0x4a, 0xd0, 0x34,
-	0x00, 0x00, 0xfa, 0x0f, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xd2,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x92, 0xbc,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x54, 0x00, 0x03, 0x01, 0x00, 0xb0, 0x02, 0x40, 0x18, 0xbd,
-	0x08, 0x00, 0xb0, 0x03, 0x00, 0x00, 0x00, 0xf8, 0xa3, 0x40, 0x01, 0x99,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x16, 0x32,
-	0x00, 0x00, 0x67, 0x00, 0x03, 0x01, 0x00, 0xd8, 0x02, 0x80, 0x80, 0xbd,
-	0x00, 0x00, 0x76, 0x00, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0x39,
-	0x76, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x6b, 0x00, 0x12, 0x01, 0x00, 0x5c, 0x08, 0x80, 0x22, 0xb2,
-	0x00, 0x00, 0x65, 0x00, 0x04, 0x01, 0x00, 0x80, 0x82, 0x85, 0x80, 0xbc,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x03, 0x39,
-	0x63, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x68, 0x8b, 0x80, 0x35,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xb8, 0xff, 0x85, 0x30,
-	0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x21, 0xff, 0x38,
-	0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x4d, 0x80, 0x3a,
-	0x2c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x0d, 0x80, 0x3a,
-	0x00, 0xc4, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x54, 0xf2, 0xc1, 0x38, 0xb4,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x12, 0x80, 0x2d, 0x37,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x48, 0x41, 0x80, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x86, 0x98, 0x67, 0xc0, 0x82, 0x3a,
-	0x00, 0x00, 0x63, 0x00, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x62, 0x8b, 0x80, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x12, 0x80, 0x2d, 0x37,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x08, 0x80, 0x70, 0x32,
-	0x00, 0x00, 0x7c, 0x00, 0x90, 0x99, 0x86, 0x2c, 0x28, 0xde, 0x82, 0xba,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x18, 0xc0, 0x82, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x08, 0xc5, 0x82, 0x30,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0xc5, 0x82, 0xbc,
-	0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00, 0x08, 0x68, 0x8b, 0x80, 0x94,
-	0x08, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x40, 0x01, 0x99,
-	0x08, 0x00, 0x38, 0x03, 0x0c, 0x00, 0x00, 0xf8, 0x53, 0x40, 0x01, 0xb9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x05, 0x80, 0x30,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x02, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x3d, 0x32,
-	0x00, 0x00, 0x7e, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x80, 0xd2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x59, 0x00, 0x80, 0xd7,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x62, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0x3a, 0x80, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0x3a, 0x80, 0xbc,
-	0x00, 0x90, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xa2, 0x0d, 0x80, 0xb0,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x32,
-	0x02, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa9, 0x0d, 0x80, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x54, 0x02, 0xa4, 0x38, 0xb2,
-	0x00, 0x02, 0x00, 0x80, 0x00, 0x00, 0x00, 0x2c, 0x08, 0x00, 0x37, 0x32,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x08, 0x80, 0x72, 0x32,
-	0x00, 0x00, 0x96, 0x00, 0x9f, 0x00, 0x00, 0x5c, 0x08, 0x00, 0x72, 0xb2,
-	0x87, 0x00, 0x95, 0x00, 0x80, 0x01, 0x00, 0x80, 0x82, 0xcd, 0x85, 0xb0,
-	0x00, 0x00, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xd8, 0xc1, 0x82, 0x94,
-	0x00, 0x00, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x88, 0xc1, 0x82, 0x94,
-	0x00, 0x00, 0x9e, 0x00, 0x06, 0x00, 0x00, 0x80, 0x52, 0x7d, 0x80, 0xbc,
-	0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x05, 0x80, 0xd0,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0x05, 0x80, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0xc0, 0xf5, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x02, 0x32,
-	0x00, 0x00, 0xa4, 0x03, 0x04, 0x00, 0x00, 0xdc, 0x43, 0x60, 0x3d, 0xb3,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x03, 0x39,
-	0x9a, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
-	0x00, 0x0f, 0x97, 0x00, 0x04, 0x00, 0x00, 0x80, 0x82, 0xcd, 0x85, 0xb0,
-	0x10, 0x00, 0xa5, 0x00, 0x87, 0x00, 0x00, 0x78, 0x79, 0x21, 0x16, 0xb8,
-	0x01, 0x00, 0xa5, 0x00, 0x04, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x97, 0xbc,
-	0x87, 0x00, 0xaf, 0x00, 0x87, 0x00, 0x00, 0x78, 0x89, 0xcd, 0x85, 0xb0,
-	0x00, 0x00, 0xa4, 0x00, 0x04, 0x01, 0x00, 0x80, 0x12, 0x80, 0x97, 0xbc,
-	0x00, 0x00, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xd8, 0xc1, 0x82, 0x94,
-	0x00, 0x00, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x88, 0xc1, 0x82, 0x94,
-	0x00, 0x00, 0xaf, 0x00, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc0, 0x85, 0xb6,
-	0x00, 0x00, 0xaf, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x98, 0xc1, 0x82, 0x94,
-	0x00, 0x00, 0xad, 0x00, 0x80, 0x01, 0x00, 0x80, 0xd2, 0xc1, 0x82, 0xb6,
-	0x00, 0x00, 0xaf, 0x00, 0x80, 0x01, 0x00, 0x80, 0x72, 0x80, 0xfc, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xa8, 0x42, 0x3d, 0x72, 0x30,
-	0x00, 0x00, 0x00, 0x00, 0x54, 0x18, 0x99, 0xb1, 0xf2, 0xc0, 0x7c, 0x30,
-	0x00, 0x00, 0xd6, 0x00, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
-	0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x82, 0xc1, 0x82, 0xb6,
-	0x00, 0x00, 0xa9, 0x00, 0x80, 0x00, 0x00, 0x80, 0x82, 0x80, 0xfc, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x32,
-	0x80, 0x00, 0x80, 0x20, 0x00, 0x00, 0x00, 0x80, 0xc2, 0xcd, 0x85, 0x30,
-	0x00, 0x00, 0xc6, 0x00, 0x0b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0xcd, 0x85, 0x30,
-	0x80, 0x00, 0xc6, 0x00, 0x04, 0x00, 0x00, 0x80, 0x82, 0x8d, 0x97, 0xbc,
-	0xa0, 0x00, 0xc6, 0x00, 0x04, 0x00, 0x00, 0x80, 0x82, 0x8d, 0x97, 0xbc,
-	0x00, 0x00, 0xbd, 0x00, 0x80, 0x01, 0x00, 0x80, 0x62, 0x80, 0xfc, 0xb6,
-	0x87, 0x00, 0xbd, 0x00, 0x87, 0x00, 0x00, 0x78, 0x89, 0xcd, 0x85, 0xb0,
-	0x00, 0x00, 0xb9, 0x00, 0x04, 0x00, 0x00, 0x80, 0x12, 0x80, 0x97, 0xbc,
-	0x00, 0x00, 0xbd, 0x00, 0x04, 0x01, 0x00, 0x80, 0x22, 0x80, 0x97, 0xbc,
-	0x00, 0x00, 0xbd, 0x00, 0x80, 0x01, 0x00, 0x80, 0x72, 0xc1, 0x85, 0xb6,
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x79, 0x61, 0x16, 0x38,
-	0x00, 0x00, 0xc4, 0x00, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
-	0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xb8, 0xc1, 0x82, 0x94,
-	0x00, 0x00, 0xc4, 0x00, 0x80, 0x01, 0x00, 0x80, 0x52, 0x80, 0xfc, 0xb6,
-	0x00, 0x00, 0xc4, 0x00, 0x80, 0x00, 0x00, 0x80, 0x72, 0xc1, 0x85, 0xb6,
-	0x00, 0x00, 0xc4, 0x00, 0x80, 0x01, 0x00, 0x80, 0x02, 0xc1, 0x85, 0xb6,
-	0x00, 0x00, 0xc4, 0x00, 0x80, 0x01, 0x00, 0x80, 0xd2, 0xc1, 0x85, 0xb6,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x79, 0xe1, 0x16, 0x38,
-	0x00, 0x00, 0xc4, 0x00, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
-	0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xc8, 0xc1, 0x82, 0x94,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0x00, 0x04, 0x32,
-	0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xa8, 0xc1, 0x82, 0x94,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x79, 0x21, 0x17, 0x38,
-	0x00, 0x00, 0xd6, 0x00, 0x04, 0x00, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
-	0x00, 0x00, 0xd6, 0x00, 0x04, 0x01, 0x00, 0x80, 0x22, 0x80, 0x97, 0xbc,
-	0x1f, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x89, 0x8d, 0x72, 0x30,
-	0x05, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xa9, 0xdc, 0x17, 0x38,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x22, 0x00, 0x90, 0x37,
-	0x00, 0x00, 0xd6, 0x00, 0x80, 0x00, 0x86, 0x80, 0x22, 0x24, 0x7c, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x05, 0x80, 0x30,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x05, 0x80, 0xd0,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0x05, 0x80, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x02, 0x32,
-	0x00, 0x00, 0xa4, 0x03, 0x04, 0x00, 0x00, 0xdc, 0x43, 0x60, 0x3d, 0xb3,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x03, 0x39,
-	0xd2, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
-	0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x59, 0x00, 0x80, 0xd7,
-	0x00, 0x00, 0xdd, 0x00, 0x12, 0x01, 0x00, 0x60, 0x08, 0x40, 0x23, 0xb2,
-	0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x80, 0xd2,
-	0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
-	0x00, 0x00, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0xc0, 0xf5, 0x9a,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x24, 0x08, 0x00, 0x23, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x20, 0x08, 0xc0, 0x23, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x18, 0x08, 0x80, 0x23, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x02, 0x32,
-	0x00, 0x00, 0xe4, 0x00, 0x04, 0x00, 0x00, 0xdc, 0x43, 0x60, 0x3d, 0xb3,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x03, 0x39,
-	0xe0, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0xc0, 0xf4, 0x00, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
-	0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0xc0, 0xf5, 0x3a,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x38, 0x02, 0x80, 0x81, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x02, 0x00, 0x82, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0x40, 0x82, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x02, 0x00, 0x86, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x05, 0x80, 0x30,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x05, 0x80, 0xd0,
-	0x00, 0x00, 0xa4, 0x03, 0x12, 0x01, 0x00, 0x68, 0x02, 0x05, 0x80, 0xb0,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x78, 0x09, 0x00, 0x72, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x29, 0xc1, 0x72, 0x3c,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x80, 0x81, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x07, 0x00, 0x82, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x07, 0x80, 0x97, 0x32,
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x17, 0x20, 0x90, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0xc0, 0x82, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x40, 0x80, 0x32,
-	0x00, 0x00, 0xff, 0x00, 0x80, 0x01, 0x00, 0x80, 0xa2, 0xc1, 0x82, 0xb6,
-	0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x57, 0x00, 0x80, 0x97,
-	0x05, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0xa0, 0x04, 0x39,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0x40, 0x82, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x86, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0x05, 0x80, 0xb0,
-	0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x05, 0x80, 0xd0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x05, 0x80, 0x30,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0x08, 0xe8, 0x81, 0x80, 0x34,
-	0x00, 0x00, 0xa4, 0x03, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x45, 0x90, 0x30,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x12, 0x00, 0x28, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x11, 0x01, 0xf0, 0x01, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x59, 0xc0, 0x6e, 0x37,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x78, 0x19, 0xc0, 0x6e, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x4e, 0x04, 0x01, 0xec, 0x06, 0xbd, 0x97, 0x30,
-	0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xf4, 0x1e, 0x40, 0xef, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x40, 0x09, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x36, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x77, 0xc0, 0x29, 0x37,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x17, 0x3d, 0x90, 0xba,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x80, 0xf4, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
-	0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x83, 0xd2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x72, 0x00, 0x2b, 0x30,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x3d, 0x32,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0xa4, 0x01, 0x80, 0x38, 0x00, 0x80, 0x22, 0xc0, 0x72, 0xb6,
-	0x00, 0x00, 0x27, 0x01, 0x12, 0x00, 0x00, 0xc8, 0x02, 0x00, 0x20, 0xb2,
-	0x00, 0x00, 0x2c, 0x01, 0x12, 0x01, 0x00, 0x5c, 0x08, 0x80, 0x20, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0x02, 0x80, 0x2c, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0x80, 0xff, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x72, 0x00, 0x85, 0x30,
-	0x00, 0x00, 0x89, 0x01, 0x04, 0x00, 0x00, 0xdc, 0x43, 0x60, 0x3d, 0xb3,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x03, 0x39,
-	0x28, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xcd, 0x85, 0x37,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x00, 0x72, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x24, 0x08, 0x00, 0x72, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x6c, 0x08, 0x00, 0x72, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4c, 0x08, 0x00, 0x72, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x20, 0x00, 0x18, 0x08, 0x00, 0x72, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x28, 0x08, 0x00, 0x72, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x00, 0x00, 0x80, 0x52, 0xbd, 0x82, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x30, 0x08, 0x00, 0x72, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x08, 0x80, 0x82, 0x32,
-	0x00, 0x00, 0x3d, 0x01, 0x06, 0x00, 0x00, 0x80, 0x62, 0xa0, 0x82, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x9f, 0x3c, 0x00, 0x14, 0x28, 0x80, 0x72, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x06, 0x32,
-	0x07, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x77, 0x4a, 0x09, 0x39,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0x00, 0x82, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0xca, 0x19, 0x00, 0x00, 0x07, 0x40, 0x82, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x32,
-	0x00, 0x00, 0x64, 0x01, 0x04, 0x38, 0x00, 0x78, 0xd9, 0xc5, 0x72, 0xb0,
-	0x00, 0x00, 0x41, 0x01, 0x80, 0x01, 0x00, 0x80, 0x02, 0x80, 0x97, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0x80, 0x2f, 0x34,
-	0x00, 0x00, 0x43, 0x01, 0x80, 0x01, 0x00, 0x80, 0x12, 0x80, 0x97, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x92, 0x80, 0x2f, 0x34,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x2d, 0xbc,
-	0x04, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x3c, 0xb8, 0x1c, 0x17, 0x38,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x28, 0xc0, 0x83, 0x37,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x2c, 0x08, 0xc0, 0x72, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xb8, 0xe0, 0x83, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0xcb, 0x29, 0x00, 0x20, 0x07, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x63, 0x01, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x81, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x78, 0xa0, 0x81, 0x3e,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xd8, 0xe0, 0x81, 0x3c,
-	0x00, 0x00, 0x51, 0x01, 0x06, 0x3a, 0x00, 0x80, 0xb2, 0x5c, 0x83, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x89, 0xc1, 0x72, 0x37,
-	0x07, 0x00, 0x50, 0x01, 0x2b, 0x01, 0x00, 0x04, 0x79, 0x0a, 0x04, 0xb9,
-	0x00, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x04, 0x19, 0x41, 0x90, 0x34,
-	0x00, 0x00, 0x54, 0x01, 0x00, 0x3a, 0x00, 0x2c, 0x07, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x2c, 0xd7, 0xe0, 0x72, 0x3c,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x64, 0x83, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
-	0x00, 0x00, 0x73, 0x01, 0x04, 0x00, 0x00, 0x28, 0xd8, 0xa0, 0x82, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x20, 0x80, 0x3a,
-	0x00, 0x00, 0x5e, 0x01, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0x12, 0xe4, 0x38, 0xb2,
-	0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x9a,
-	0x00, 0x00, 0xd7, 0x10, 0x00, 0x00, 0x00, 0x04, 0xf9, 0x41, 0x90, 0xf4,
-	0x00, 0x00, 0x61, 0x01, 0x04, 0x00, 0x00, 0x18, 0xd8, 0xa0, 0x81, 0xbc,
-	0x00, 0x00, 0x49, 0x01, 0x00, 0x00, 0x00, 0x6c, 0xd8, 0xe0, 0x86, 0x9a,
-	0x00, 0x00, 0x84, 0x10, 0x00, 0x00, 0x00, 0x44, 0x08, 0x80, 0x2d, 0xf2,
-	0x00, 0x00, 0x49, 0x01, 0x00, 0x00, 0x00, 0x30, 0x08, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0xcb, 0x19, 0x00, 0x20, 0x07, 0x00, 0x00, 0x32,
-	0x07, 0x00, 0x66, 0x01, 0x2b, 0x01, 0x00, 0x04, 0x79, 0x0a, 0x02, 0xb9,
-	0x00, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x04, 0x19, 0x41, 0x90, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0xa7, 0xa0, 0x81, 0x3e,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
-	0x00, 0x00, 0x73, 0x01, 0x04, 0x00, 0x00, 0x28, 0xd8, 0xa0, 0x82, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x62, 0x60, 0x83, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x20, 0x80, 0x3a,
-	0x00, 0x00, 0x70, 0x01, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0x12, 0xe4, 0x38, 0xb2,
-	0x00, 0x00, 0x71, 0x01, 0x00, 0x00, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x9a,
-	0x00, 0x00, 0xd7, 0x10, 0x00, 0x00, 0x00, 0x04, 0xf9, 0x41, 0x90, 0xf4,
-	0x00, 0x00, 0x84, 0x10, 0x00, 0x00, 0x00, 0x44, 0x08, 0x80, 0x2d, 0xf2,
-	0x00, 0x00, 0x64, 0x01, 0x00, 0x00, 0x00, 0x30, 0x08, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xf9, 0x41, 0x90, 0x34,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0x12, 0xe4, 0x38, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x04, 0x09, 0x80, 0x73, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x08, 0x89, 0x80, 0x73, 0x37,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x86, 0x32,
-	0x41, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x8c, 0x07, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x7f, 0x01, 0x29, 0x08, 0x00, 0x80, 0x07, 0xc0, 0x85, 0xb2,
-	0x00, 0x00, 0x82, 0x01, 0x28, 0x10, 0x00, 0x8c, 0x07, 0x00, 0x00, 0xb2,
-	0x00, 0x00, 0x83, 0x01, 0x00, 0x12, 0x00, 0x84, 0x07, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x8c, 0xf7, 0xe0, 0x82, 0x3a,
-	0x00, 0x00, 0x82, 0x01, 0x28, 0x18, 0x00, 0x80, 0x07, 0x40, 0x90, 0xb2,
-	0x00, 0x00, 0x83, 0x01, 0x00, 0x12, 0x00, 0x84, 0x07, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x84, 0x27, 0xe4, 0x82, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x72, 0x00, 0x85, 0x30,
-	0x00, 0x00, 0x87, 0x01, 0x04, 0x00, 0x00, 0xdc, 0x43, 0x60, 0x3d, 0xb3,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x03, 0x39,
-	0x83, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0x52, 0x81, 0x2c, 0xb4,
-	0x00, 0x00, 0x89, 0x01, 0xf2, 0x01, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xb4,
-	0x00, 0x00, 0x8a, 0x01, 0xf0, 0x01, 0x00, 0x08, 0x38, 0x81, 0x80, 0xb4,
-	0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xf4, 0x1e, 0x40, 0xef, 0x3c,
-	0x00, 0x00, 0x93, 0x01, 0x0b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x3b, 0x32,
-	0x00, 0x00, 0x8e, 0x01, 0xb9, 0x00, 0x00, 0x78, 0xc9, 0x3b, 0x3a, 0xbc,
-	0x00, 0x00, 0x92, 0x01, 0x02, 0x00, 0x00, 0x80, 0x82, 0x80, 0x97, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0xa9, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0xa4, 0x03, 0xe2, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0xa9, 0x00, 0x00, 0xf0, 0x0e, 0x00, 0x3a, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xba, 0x83, 0x3c,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xbd, 0x97, 0x30,
-	0x00, 0x00, 0x8a, 0x11, 0x03, 0x00, 0x00, 0x00, 0x09, 0x00, 0xf4, 0xbd,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x97, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0e, 0x80, 0x83, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x22, 0x7a, 0xe8, 0xba,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xe8, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0xc0, 0x29, 0x37,
-	0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x0d, 0x90, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x90, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x40, 0xe8, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x80, 0xe8, 0x32,
-	0x00, 0x00, 0xa4, 0x03, 0x12, 0x01, 0x00, 0x48, 0xf2, 0xc1, 0x38, 0xb4,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x2d, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x78, 0x08, 0x80, 0x72, 0x32,
-	0x04, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x54, 0xa8, 0x5c, 0x16, 0x38,
-	0x0b, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x2c, 0xa8, 0xdc, 0x16, 0x38,
-	0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x88, 0x4d, 0x85, 0x3a,
-	0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x10, 0x00, 0xe2, 0x10, 0x00, 0x38, 0x00, 0x14, 0xa9, 0x9c, 0x87, 0xd9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x00, 0x72, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x24, 0x08, 0x00, 0x72, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x6c, 0x08, 0x00, 0x72, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4c, 0x08, 0x00, 0x72, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x20, 0x00, 0x18, 0x08, 0x00, 0x72, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x30, 0x08, 0x00, 0x72, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x9f, 0x3c, 0x00, 0x14, 0x18, 0x80, 0x72, 0xbc,
-	0x00, 0x00, 0xbb, 0x01, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x81, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0x3c,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x06, 0x32,
-	0x07, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x77, 0x4a, 0x09, 0x39,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0x00, 0x82, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0xca, 0x19, 0x00, 0x00, 0x07, 0x40, 0x82, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x78, 0xc0, 0x29, 0x37,
-	0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x88, 0x4d, 0x86, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x77, 0xa0, 0x81, 0x3e,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x40, 0x86, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
-	0x00, 0x00, 0xd6, 0x01, 0x04, 0x00, 0x00, 0x1c, 0xd8, 0xe0, 0x81, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0xd8, 0x60, 0x86, 0x3a,
-	0x00, 0x00, 0xca, 0x01, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0x02, 0xc0, 0x38, 0xb2,
-	0x00, 0x00, 0xd2, 0x01, 0x00, 0x00, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x9a,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0xd0, 0x01, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0xcb, 0x01, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x32,
-	0x00, 0x00, 0xd4, 0x01, 0x04, 0x00, 0x00, 0x18, 0xd8, 0xa0, 0x81, 0xbc,
-	0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x6c, 0xd8, 0xe0, 0x86, 0x9a,
-	0x00, 0x00, 0x32, 0x0f, 0x00, 0x00, 0x00, 0x44, 0x08, 0x80, 0x2d, 0xf2,
-	0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x30, 0x08, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0xdc, 0x01, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0xd7, 0x01, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
-	0x00, 0x00, 0xe8, 0x01, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x84, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x40, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x22, 0x40, 0x85, 0x3a,
-	0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x40, 0x88, 0xcd, 0x74, 0x36,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x28, 0x00, 0x84, 0x37,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x32,
-	0x14, 0x00, 0xe8, 0x01, 0x04, 0x00, 0x00, 0x1c, 0x88, 0x0d, 0x84, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x61, 0x85, 0x3a,
-	0x80, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x97, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0xd8, 0x60, 0x86, 0x3a,
-	0x00, 0x00, 0xd2, 0x01, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x92,
-	0x00, 0x00, 0xea, 0x01, 0x04, 0x00, 0x00, 0x18, 0xd8, 0xa0, 0x81, 0xbc,
-	0x00, 0x00, 0xec, 0x01, 0x00, 0x00, 0x00, 0x6c, 0xd8, 0xe0, 0x86, 0x9a,
-	0x00, 0x00, 0x32, 0x0f, 0x00, 0x00, 0x00, 0x44, 0x08, 0x80, 0x2d, 0xf2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x08, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x40, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x22, 0xc0, 0x82, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xb8, 0x60, 0x85, 0x3c,
-	0x04, 0x00, 0xf2, 0x01, 0x81, 0x00, 0x00, 0x60, 0x88, 0xcd, 0x74, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x28, 0xf8, 0xa0, 0x75, 0x3c,
-	0x00, 0x00, 0xf3, 0x01, 0x00, 0x08, 0x00, 0x74, 0x08, 0x80, 0x75, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x28, 0xf8, 0xa0, 0x75, 0x3c,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x08, 0xa1, 0x82, 0x3c,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xf2, 0x60, 0x2a, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x48, 0x08, 0x00, 0x75, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x7c, 0x08, 0x80, 0x75, 0x32,
-	0x09, 0x00, 0xf9, 0x01, 0x04, 0x1a, 0x00, 0x70, 0x88, 0xcd, 0x74, 0xb0,
-	0x09, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x4c, 0x87, 0xcd, 0x74, 0x31,
-	0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x88, 0x4d, 0x86, 0x31,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x28, 0x40, 0x86, 0x3a,
-	0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x82, 0xd2,
-	0x00, 0x00, 0x00, 0x02, 0x12, 0x00, 0x00, 0xc8, 0x02, 0x00, 0x20, 0xb2,
-	0x00, 0x00, 0x01, 0x02, 0x12, 0x01, 0x00, 0x5c, 0x08, 0x80, 0x20, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0x02, 0x80, 0x2c, 0xb2,
-	0x00, 0x00, 0x27, 0x01, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x40, 0x00, 0x32,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xcd, 0x85, 0x37,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xe8, 0xa1, 0x82, 0x3e,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x22, 0xc0, 0x82, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x08, 0xe1, 0x81, 0x3a,
-	0x00, 0x00, 0x0b, 0x02, 0x04, 0x01, 0x00, 0x80, 0x42, 0x00, 0x86, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x58, 0x07, 0x40, 0x87, 0x32,
-	0x00, 0x00, 0x0a, 0x02, 0x8f, 0x01, 0x00, 0x74, 0x18, 0x40, 0x87, 0xba,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x08, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x0d, 0x02, 0x00, 0x04, 0x00, 0x58, 0xf7, 0xa0, 0x86, 0x9a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xf9, 0xa0, 0x86, 0x3a,
-	0x28, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x58, 0x87, 0x8d, 0x97, 0x3c,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x22, 0x40, 0x85, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x50, 0x07, 0x80, 0x84, 0x32,
-	0x00, 0x00, 0x11, 0x02, 0x04, 0x01, 0x00, 0x80, 0x72, 0xa0, 0x82, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x4c, 0xc7, 0xe1, 0x74, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x78, 0xa0, 0x84, 0x3a,
-	0x00, 0x00, 0x14, 0x02, 0x90, 0x01, 0x00, 0x78, 0xf9, 0xa1, 0x86, 0xba,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x19, 0x80, 0x97, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x58, 0x07, 0x80, 0x97, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x58, 0xa1, 0x86, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x32,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, 0x60, 0x85, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x40, 0x86, 0x32,
-	0x00, 0x00, 0x1a, 0x02, 0x12, 0x00, 0x00, 0x4c, 0x02, 0xc0, 0x38, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x84, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00, 0x57, 0x21, 0x80, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x57, 0x61, 0x86, 0x3a,
-	0x00, 0x00, 0x1f, 0x02, 0x12, 0x00, 0x00, 0x4c, 0xf2, 0xc1, 0x38, 0xb4,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x80, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0xc0, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0xcb, 0x19, 0x00, 0x20, 0x07, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x21, 0x80, 0x3a,
-	0x07, 0x00, 0x27, 0x02, 0x2b, 0x01, 0x00, 0x04, 0x79, 0x0a, 0x02, 0xb9,
-	0x00, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x04, 0x19, 0x41, 0x90, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x77, 0xa0, 0x81, 0x3e,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xd8, 0xa0, 0x82, 0x3c,
-	0x00, 0x00, 0x41, 0x02, 0x04, 0x00, 0x00, 0x1c, 0xd8, 0xe0, 0x81, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x62, 0x60, 0x83, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x20, 0x80, 0x3a,
-	0x00, 0x00, 0x32, 0x02, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0x12, 0xe4, 0x38, 0xb2,
-	0x00, 0x00, 0x3f, 0x02, 0x00, 0x00, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x9a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xf9, 0x41, 0x90, 0x34,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0x12, 0xe4, 0x38, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x3d, 0x02, 0x06, 0x01, 0x00, 0x80, 0x22, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x3a, 0x02, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x34, 0x02, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
-	0x00, 0x00, 0x35, 0x02, 0x00, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x22, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x34, 0x02, 0x67, 0x00, 0x00, 0x80, 0x18, 0x00, 0x88, 0xbc,
-	0x00, 0x00, 0x35, 0x02, 0x00, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0xc0, 0x00, 0x32,
-	0x00, 0x00, 0x32, 0x0f, 0x00, 0x00, 0x00, 0x44, 0x08, 0x80, 0x2d, 0xf2,
-	0x00, 0x00, 0x25, 0x02, 0x00, 0x00, 0x00, 0x30, 0x08, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xf9, 0x41, 0x90, 0x34,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0x12, 0xe4, 0x38, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x48, 0x02, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x43, 0x02, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
-	0x00, 0x00, 0x44, 0x02, 0x00, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0x92,
-	0x00, 0x00, 0x4b, 0x02, 0x04, 0x00, 0x00, 0x80, 0x18, 0x00, 0x88, 0xbc,
-	0x00, 0x00, 0x43, 0x02, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
-	0x00, 0x00, 0x44, 0x02, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x2d, 0xbc,
-	0x00, 0x00, 0x4f, 0x02, 0x04, 0x01, 0x00, 0x80, 0x42, 0x00, 0x86, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x89, 0x80, 0x71, 0x37,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0x80, 0x71, 0x32,
-	0x00, 0x00, 0x53, 0x02, 0x90, 0x19, 0x00, 0x04, 0xe9, 0x5c, 0x90, 0xba,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x19, 0x40, 0x90, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x80, 0x86, 0x32,
-	0x41, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x8c, 0x07, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x80, 0x07, 0xc0, 0x85, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x8c, 0x07, 0x40, 0x85, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x80, 0x07, 0x45, 0x90, 0x30,
-	0x00, 0x00, 0x5a, 0x02, 0x04, 0x01, 0x00, 0x80, 0x42, 0x00, 0x86, 0xbc,
-	0x00, 0x00, 0x5b, 0x02, 0x00, 0x12, 0x00, 0x84, 0x27, 0xe4, 0x82, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x84, 0x07, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x5f, 0x02, 0x27, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0xb2,
-	0x00, 0x00, 0x5f, 0x02, 0x04, 0x00, 0x00, 0x80, 0x42, 0x60, 0x3d, 0xb3,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x03, 0x39,
-	0x5b, 0x02, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x72, 0x80, 0x2f, 0x34,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0x52, 0x81, 0x2c, 0xb4,
-	0x00, 0x00, 0x64, 0x02, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x82, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x03, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x89, 0x01, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x67, 0x02, 0x04, 0x01, 0x00, 0x18, 0xd8, 0xa0, 0x81, 0xbc,
-	0x00, 0x00, 0x32, 0x0f, 0x00, 0x00, 0x00, 0x44, 0x08, 0x80, 0x2d, 0xf2,
-	0x00, 0x00, 0xfd, 0x01, 0x00, 0x00, 0x00, 0x30, 0x08, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0xfd, 0x01, 0x00, 0x00, 0x00, 0x6c, 0xd8, 0xe0, 0x86, 0x9a,
-	0x08, 0x00, 0x00, 0x00, 0xc6, 0x01, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
-	0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x40, 0x81, 0xd2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x45, 0x81, 0x30,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0xa4, 0x03, 0x80, 0x01, 0x80, 0x80, 0x32, 0x0b, 0x6a, 0xb6,
-	0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0x00, 0x3c, 0x03, 0x00, 0x38, 0xf2,
-	0x00, 0x00, 0x72, 0x02, 0x04, 0x06, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
-	0x00, 0x00, 0xa1, 0x03, 0x00, 0x06, 0x01, 0xec, 0x56, 0xe0, 0x6e, 0x9a,
-	0x00, 0x00, 0x00, 0x00, 0xc4, 0x07, 0x01, 0xec, 0x56, 0xe0, 0x6e, 0x3a,
-	0x08, 0xc0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0xcd, 0x39, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x8a, 0x11, 0x03, 0xb8, 0x00, 0x00, 0x09, 0xc0, 0x6e, 0xbd,
-	0x77, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x82, 0x0d, 0x90, 0x3a,
-	0x2e, 0x00, 0x93, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x2b, 0x00, 0x93, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x37, 0x00, 0x93, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x38, 0x00, 0x93, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x80, 0x80, 0x32, 0x0b, 0x6a, 0xb6,
-	0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0x00, 0x3c, 0x03, 0x00, 0x38, 0xf2,
-	0x00, 0x00, 0x86, 0x02, 0x04, 0x00, 0x00, 0x80, 0x52, 0x40, 0x82, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x62, 0x40, 0x82, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x05, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x42, 0x80, 0x2f, 0x34,
-	0x08, 0xc0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0xcd, 0x39, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x04, 0x01, 0x14, 0x59, 0xc0, 0x6e, 0xd7,
-	0x02, 0x00, 0x8f, 0x02, 0x04, 0xb8, 0x00, 0x80, 0x82, 0xcd, 0x6e, 0xbc,
-	0x08, 0x00, 0x8a, 0x11, 0x04, 0xb9, 0x00, 0x80, 0x82, 0xcd, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0xec, 0x06, 0x40, 0x00, 0x32,
-	0x00, 0x00, 0x91, 0x02, 0xb5, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x80, 0xa0, 0x36, 0x0b, 0x6a, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x01, 0xe8, 0x06, 0xc0, 0x2c, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0x85, 0x2f, 0x30,
-	0x00, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x60, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0xf8, 0x82, 0x8d, 0x2f, 0xb0,
-	0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x40, 0x81, 0xd2,
-	0x00, 0x00, 0xa1, 0x02, 0x80, 0x00, 0x80, 0x80, 0x32, 0x0b, 0x6a, 0xb6,
-	0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0xb8, 0x00, 0x14, 0x09, 0xc0, 0x6e, 0xd2,
-	0x00, 0x00, 0xa4, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0x00, 0x38, 0x03, 0x00, 0x38, 0xf2,
-	0x00, 0x00, 0xa4, 0x02, 0x04, 0x02, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
-	0x00, 0x00, 0xa1, 0x03, 0x00, 0x02, 0x01, 0xec, 0x56, 0xe0, 0x6e, 0x9a,
-	0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x01, 0xec, 0x56, 0xe0, 0x6e, 0x3a,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2f, 0xb6,
-	0x00, 0xc0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x20, 0x00, 0x8a, 0x11, 0x04, 0x39, 0x00, 0x80, 0x82, 0xcd, 0x6e, 0xbc,
-	0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x30, 0x00, 0x14, 0x09, 0x00, 0x6e, 0xd2,
-	0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x20, 0x01, 0x14, 0x09, 0x00, 0x6e, 0xd2,
-	0x1b, 0x00, 0xaf, 0x02, 0x38, 0x01, 0x00, 0x10, 0x09, 0x00, 0x36, 0xb2,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x30, 0x01, 0x14, 0x09, 0x00, 0x6e, 0xd2,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x79, 0x0b, 0x14, 0x38,
-	0x10, 0x00, 0xe2, 0x10, 0x00, 0x50, 0x01, 0x14, 0xa9, 0x5b, 0x91, 0xd9,
-	0x00, 0x00, 0xbe, 0x02, 0x38, 0x28, 0x00, 0x18, 0x09, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0xb6, 0x02, 0x04, 0x21, 0x01, 0x08, 0x69, 0x24, 0x6e, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x03, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0xba, 0x02, 0x02, 0x30, 0x00, 0x80, 0x82, 0x9b, 0x90, 0xbc,
-	0x00, 0x00, 0xb9, 0x02, 0x06, 0x03, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
-	0x04, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x05, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x30, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0xbd, 0x02, 0x06, 0x03, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
-	0x0a, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x0b, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0xc1, 0x02, 0x04, 0x21, 0x01, 0x08, 0x69, 0x24, 0x6e, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x03, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0xc3, 0x02, 0x02, 0x30, 0x00, 0x80, 0x82, 0x9b, 0x90, 0xbc,
-	0x04, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0xc5, 0x02, 0x9f, 0x31, 0x01, 0x0c, 0x69, 0x24, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x09, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0xc9, 0x02, 0x04, 0x31, 0x00, 0x80, 0x82, 0x9b, 0x90, 0xbc,
-	0x00, 0x00, 0xc8, 0x02, 0x06, 0x03, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
-	0x20, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x21, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0xcd, 0x02, 0x04, 0x00, 0x00, 0x80, 0x32, 0xa4, 0x90, 0xbc,
-	0x00, 0x00, 0xcc, 0x02, 0x06, 0x03, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
-	0x22, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x23, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0xcf, 0x02, 0x06, 0x03, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
-	0x20, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x21, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x08, 0x00, 0x8a, 0x11, 0x0c, 0x00, 0x00, 0xf8, 0x63, 0x40, 0x01, 0xb9,
-	0x10, 0x00, 0xd4, 0x02, 0xc5, 0x01, 0x00, 0xcc, 0x02, 0x20, 0x15, 0x98,
-	0x08, 0x00, 0x38, 0x03, 0x0c, 0x00, 0x00, 0xf8, 0x43, 0x40, 0x01, 0xb9,
-	0x10, 0x00, 0x00, 0x00, 0xc5, 0x01, 0x00, 0xcc, 0x02, 0x20, 0x15, 0x38,
-	0x00, 0x00, 0x7e, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x05, 0x80, 0xd0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x59, 0x00, 0x80, 0xd7,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
-	0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0x00, 0x3c, 0x03, 0x00, 0x38, 0xf2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x08, 0x05, 0x80, 0x30,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x2d, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xfa, 0x85, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xfa, 0x85, 0xbc,
-	0x00, 0x00, 0xdf, 0x02, 0x36, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x0e, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x02, 0x00, 0xa9, 0xdb, 0x85, 0x39,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x54, 0x02, 0xa4, 0x38, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x02, 0x8c, 0x08, 0xc0, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x94, 0x08, 0xc0, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x98, 0x28, 0x80, 0x6e, 0x37,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x38, 0x22, 0x14, 0x37,
-	0x00, 0x00, 0xeb, 0x02, 0x04, 0x30, 0x00, 0x28, 0x08, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x20, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x14, 0x08, 0x80, 0x6e, 0x32,
-	0x05, 0x00, 0xee, 0x02, 0x00, 0x30, 0x02, 0x00, 0x78, 0xe1, 0x6e, 0x99,
-	0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0x78, 0x09, 0xc0, 0x6e, 0x32,
-	0x05, 0x00, 0x00, 0x00, 0x68, 0x08, 0x00, 0x00, 0x77, 0xa1, 0x97, 0x39,
-	0x00, 0x00, 0xf0, 0x02, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
-	0x14, 0x10, 0xf4, 0x02, 0x04, 0x00, 0x00, 0x80, 0xa2, 0x0d, 0x72, 0xb0,
-	0x00, 0x00, 0x58, 0x10, 0x00, 0x00, 0x00, 0x28, 0x09, 0xc0, 0x02, 0xf2,
-	0x0d, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x09, 0x00, 0x80, 0x52, 0xbd, 0x72, 0xbc,
-	0x00, 0x00, 0xfb, 0x02, 0x33, 0x15, 0x00, 0xa4, 0x02, 0xc0, 0x72, 0xb2,
-	0x00, 0x00, 0x33, 0x03, 0x80, 0x01, 0x00, 0x80, 0xb2, 0x01, 0x72, 0xb6,
-	0x01, 0x01, 0x08, 0x0a, 0x00, 0x28, 0x00, 0x80, 0xc2, 0x0d, 0x74, 0x3c,
-	0x00, 0x00, 0x33, 0x03, 0x0b, 0x31, 0x00, 0x7c, 0x08, 0x00, 0x75, 0xb2,
-	0x00, 0x00, 0x33, 0x03, 0x9f, 0xf0, 0x01, 0x80, 0x82, 0xdb, 0x87, 0xbc,
-	0x00, 0x00, 0xfc, 0x02, 0x00, 0x38, 0x00, 0x88, 0x18, 0x00, 0x75, 0x9c,
-	0x00, 0x00, 0x33, 0x03, 0x80, 0x00, 0x00, 0x80, 0xb2, 0x01, 0x72, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x48, 0x08, 0x00, 0x75, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x70, 0x08, 0x00, 0x75, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x74, 0x38, 0xa2, 0x75, 0x37,
-	0x00, 0x00, 0x01, 0x03, 0x83, 0x1b, 0x00, 0x78, 0x08, 0xc0, 0x74, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xc2, 0x80, 0x2f, 0x34,
-	0x00, 0x00, 0xf2, 0x02, 0x80, 0x01, 0x00, 0x80, 0x42, 0x80, 0x87, 0xb6,
-	0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x84, 0xd2,
-	0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x87, 0xd2,
-	0x00, 0x00, 0x15, 0x03, 0x9f, 0x78, 0x01, 0x80, 0xc2, 0x21, 0x6e, 0xbc,
-	0x00, 0x00, 0x0a, 0x03, 0x9f, 0x99, 0x01, 0x64, 0x88, 0x1b, 0x87, 0xbc,
-	0x00, 0x00, 0x16, 0x03, 0x9f, 0x68, 0x01, 0x64, 0x88, 0x5b, 0x86, 0xba,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x08, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0xa4, 0x02, 0xc0, 0x72, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x02, 0xa4, 0xb2, 0x5b, 0x2a, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x02, 0x78, 0x09, 0xc0, 0x6e, 0x32,
-	0x00, 0x00, 0x17, 0x03, 0x08, 0x01, 0x00, 0x04, 0xe8, 0xa5, 0x75, 0xbc,
-	0x0f, 0x00, 0x33, 0x03, 0x0b, 0x01, 0x00, 0x1c, 0x08, 0x00, 0x36, 0xb2,
-	0x00, 0x00, 0x15, 0x03, 0x04, 0xa1, 0x01, 0x80, 0x82, 0x9b, 0x84, 0xbc,
-	0x00, 0x00, 0x9d, 0x05, 0x9f, 0x98, 0x01, 0x80, 0xc2, 0x21, 0x6e, 0xbc,
-	0x00, 0x00, 0x9d, 0x05, 0x06, 0xb1, 0x01, 0x80, 0x82, 0x5b, 0x87, 0xbc,
-	0x00, 0x00, 0x32, 0x03, 0x0b, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x30, 0x03, 0x02, 0xd4, 0x01, 0x80, 0x92, 0xfb, 0x6e, 0xbc,
-	0x15, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x16, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x1c, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x08, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x28, 0x72, 0x61, 0x80, 0xb9,
-	0x00, 0x00, 0x1a, 0x03, 0x04, 0xa1, 0x01, 0x80, 0x82, 0x9b, 0x84, 0xbc,
-	0x00, 0x00, 0x21, 0x03, 0x06, 0xa8, 0x01, 0x80, 0x82, 0x5b, 0x80, 0xbc,
-	0x00, 0x00, 0x1e, 0x03, 0x04, 0xa9, 0x01, 0x80, 0x02, 0x00, 0x6e, 0xbc,
-	0x00, 0x00, 0x31, 0x03, 0x04, 0xa9, 0x01, 0x80, 0x82, 0x9b, 0x84, 0xbc,
-	0x00, 0x00, 0x31, 0x03, 0x04, 0x01, 0x00, 0x80, 0x12, 0x40, 0x80, 0xbc,
-	0x13, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x31, 0x03, 0x9f, 0xa0, 0x01, 0x78, 0x29, 0x21, 0x6e, 0xbc,
-	0x00, 0x00, 0x31, 0x03, 0x02, 0x01, 0x00, 0x80, 0x12, 0xa0, 0x97, 0xbc,
-	0x00, 0x00, 0x15, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x2c, 0x03, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x82, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x02, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
-	0x00, 0x00, 0x27, 0x03, 0x02, 0x00, 0x00, 0x80, 0xa2, 0x60, 0x80, 0xbc,
-	0x06, 0x00, 0x9d, 0x05, 0x2c, 0x01, 0x00, 0x1c, 0x08, 0x00, 0x36, 0xb2,
-	0x00, 0xc0, 0x29, 0x03, 0x04, 0x01, 0x00, 0x80, 0xa2, 0x8d, 0x2f, 0xb0,
-	0x06, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x29, 0x03, 0x04, 0x00, 0x00, 0x80, 0xa2, 0x60, 0x80, 0xbc,
-	0x09, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x2b, 0x03, 0x06, 0x03, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
-	0x07, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x08, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x02, 0x00, 0x9d, 0x05, 0x38, 0x01, 0x00, 0x1c, 0x08, 0x00, 0x36, 0xb2,
-	0x00, 0x00, 0x2f, 0x03, 0x02, 0x0c, 0x02, 0x80, 0xa2, 0x5b, 0x80, 0xbc,
-	0x1f, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x1e, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x34, 0x03, 0x00, 0x00, 0x00, 0x28, 0x09, 0x40, 0x00, 0x92,
-	0x00, 0x00, 0x34, 0x03, 0x00, 0x00, 0x00, 0x28, 0x09, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0x34, 0x03, 0x00, 0x00, 0x00, 0x28, 0x09, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0x34, 0x03, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x01, 0x92,
-	0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x92, 0xd2,
-	0x0d, 0x00, 0x58, 0x10, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0xf2,
-	0x00, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x10, 0x00, 0x8a, 0x11, 0x2a, 0x00, 0x00, 0xcc, 0x02, 0x20, 0x15, 0xb8,
-	0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x80, 0xd2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
-	0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0x00, 0x3c, 0x03, 0x00, 0x38, 0xf2,
-	0x1d, 0x00, 0x49, 0x03, 0x80, 0x01, 0x00, 0x78, 0x09, 0xe0, 0x00, 0xb8,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
-	0x1d, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x22, 0x80, 0x97, 0xbc,
-	0x14, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xa8, 0x05, 0x28, 0x30,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x2c, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x60, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0xf8, 0x82, 0x8d, 0x2f, 0xb0,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x83, 0x40, 0x01, 0x39,
-	0x35, 0x00, 0x54, 0x03, 0x04, 0x00, 0x00, 0x80, 0x82, 0xcd, 0x81, 0xbc,
-	0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc0, 0x81, 0xd2,
-	0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0x00, 0x38, 0x03, 0x00, 0x38, 0xf2,
-	0x2b, 0x00, 0x9d, 0x05, 0x02, 0x01, 0x00, 0x80, 0x82, 0xcd, 0x81, 0xbc,
-	0x00, 0x00, 0x93, 0x05, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
-	0x00, 0x00, 0x5a, 0x03, 0x1d, 0x41, 0x02, 0x5c, 0xf8, 0x01, 0x68, 0xb4,
-	0x41, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0xf8, 0xa2, 0x8d, 0x2f, 0x91,
-	0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x59, 0xc0, 0x85, 0xd7,
-	0x10, 0x00, 0x00, 0x00, 0xd0, 0x2c, 0x02, 0x00, 0xa9, 0xdb, 0x85, 0x39,
-	0x00, 0x00, 0xe1, 0x02, 0x12, 0x01, 0x00, 0x54, 0x02, 0xa4, 0x38, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x64, 0x03, 0x04, 0xb0, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
-	0x00, 0x00, 0x60, 0x11, 0x00, 0x78, 0x01, 0x60, 0x08, 0x00, 0x6e, 0xf2,
-	0x2f, 0x00, 0x93, 0x05, 0xd7, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x65, 0x03, 0x06, 0xa9, 0x01, 0x08, 0x09, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x6d, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x70, 0x03, 0x04, 0xa8, 0x01, 0x08, 0x09, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x02, 0x08, 0x89, 0x9b, 0x90, 0x3e,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, 0x08, 0x89, 0x9b, 0x90, 0x3a,
-	0x00, 0x00, 0x70, 0x03, 0x9f, 0x88, 0x01, 0x08, 0x89, 0x9b, 0x90, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x04, 0xf9, 0xba, 0x6e, 0x37,
-	0x00, 0x00, 0x6c, 0x03, 0x02, 0x00, 0x00, 0x80, 0x12, 0xa4, 0x90, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x19, 0x80, 0x90, 0x37,
-	0x00, 0x00, 0x70, 0x03, 0x02, 0x01, 0x02, 0x80, 0x82, 0x9b, 0x90, 0xbc,
-	0x30, 0x00, 0x93, 0x05, 0xd7, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x70, 0x03, 0x04, 0xb0, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
-	0x00, 0x12, 0x70, 0x03, 0x04, 0x01, 0x00, 0x80, 0xa2, 0x8d, 0x2f, 0xb0,
-	0x31, 0x00, 0x93, 0x05, 0xd7, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x72, 0x81, 0x2f, 0x95,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x42, 0x80, 0x2f, 0x34,
-	0x08, 0xc0, 0x74, 0x02, 0x12, 0x01, 0x00, 0x40, 0xa2, 0xcd, 0x39, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc0, 0x81, 0xd2,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x2c, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x60, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0xf8, 0x82, 0x8d, 0x2f, 0xb0,
-	0x00, 0x00, 0xb0, 0x03, 0x80, 0x01, 0x80, 0x80, 0x32, 0x0b, 0x6a, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x40, 0x90, 0x32,
-	0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0x00, 0x38, 0x03, 0x00, 0x38, 0xf2,
-	0x2b, 0x00, 0x9d, 0x05, 0x02, 0x01, 0x00, 0x80, 0x82, 0xcd, 0x81, 0xbc,
-	0x00, 0x00, 0x93, 0x05, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x10, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x89, 0x4d, 0x81, 0xd7,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x2c, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x60, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0xf8, 0x82, 0x8d, 0x2f, 0xb0,
-	0x00, 0x00, 0xb0, 0x03, 0x80, 0x01, 0x80, 0x80, 0x32, 0x0b, 0x6a, 0xb6,
-	0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0x00, 0x38, 0x03, 0x00, 0x38, 0xf2,
-	0x00, 0x00, 0x8a, 0x03, 0x04, 0x20, 0x01, 0x80, 0x52, 0x20, 0x6e, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x25, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x24, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x93, 0x03, 0x04, 0x01, 0x00, 0xd8, 0x1e, 0x80, 0xed, 0xbc,
-	0x00, 0x00, 0x8c, 0x03, 0xb7, 0x00, 0x00, 0xd8, 0x0e, 0xc0, 0xed, 0xb2,
-	0x00, 0x00, 0x8f, 0x03, 0x04, 0x01, 0x00, 0x80, 0x42, 0x3b, 0xee, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1e, 0x00, 0xee, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0xa7, 0x00, 0x00, 0xd0, 0x0e, 0x00, 0xee, 0x32,
-	0x00, 0x00, 0x93, 0x03, 0x80, 0x01, 0x00, 0x80, 0x92, 0x80, 0xfc, 0xb6,
-	0x00, 0x00, 0x93, 0x03, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0xfc, 0xb6,
-	0x00, 0x00, 0x93, 0x03, 0x04, 0x01, 0x00, 0xb0, 0x1e, 0x00, 0xeb, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x86, 0xcc, 0x02, 0x80, 0x6c, 0x32,
-	0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x97, 0x03, 0x80, 0x01, 0x80, 0x80, 0x32, 0x0b, 0x6a, 0xb6,
-	0x35, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x99, 0x03, 0x04, 0x01, 0x00, 0x80, 0x42, 0xc5, 0x2c, 0xbc,
-	0x00, 0x00, 0x9a, 0x03, 0x00, 0x00, 0x00, 0xcc, 0x02, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x12, 0xc0, 0x2c, 0x3a,
-	0x00, 0x00, 0x95, 0x03, 0x04, 0x01, 0x00, 0x00, 0x19, 0x00, 0x90, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x86, 0xc8, 0x06, 0xc0, 0x2c, 0x32,
-	0x08, 0x00, 0xb0, 0x03, 0x00, 0x00, 0x00, 0xf8, 0xc3, 0x40, 0x01, 0x99,
-	0x00, 0x00, 0x9f, 0x03, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x80, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x55, 0x01, 0x80, 0xb2, 0x1b, 0x2b, 0xbc,
-	0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0x09, 0x00, 0x00, 0xf2,
-	0x00, 0x00, 0xa4, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa3, 0x03, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x80, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x55, 0x01, 0x80, 0xb2, 0x1b, 0x2b, 0xbc,
-	0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
-	0x00, 0x00, 0xad, 0x03, 0x04, 0x00, 0x00, 0x28, 0x09, 0x80, 0x80, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0xef, 0x0f, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0xd2,
-	0x00, 0x00, 0xad, 0x03, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x92, 0xbc,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0xb0, 0x03, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0xb0, 0x03, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0x39,
-	0xb0, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0xb0, 0x03, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0xb0, 0x03, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x00, 0x00, 0x32,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x02, 0x99,
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
-	0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
-	0x04, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
-	0x09, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x0f, 0x00, 0x00, 0x32,
-	0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
-	0x06, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
-	0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
-	0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
-	0x07, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0xc2, 0x03, 0x8b, 0x01, 0x00, 0xa0, 0x12, 0x00, 0x2a, 0xba,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0xc5, 0x03, 0x06, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2a, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0xc8, 0x03, 0x85, 0x01, 0x00, 0x9c, 0x12, 0xc0, 0x29, 0xba,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
-	0x0b, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
-	0x13, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
-	0x0c, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x06, 0x32,
-	0x0f, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
-	0x0d, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
-	0x14, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
-	0x15, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
-	0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
-	0x1d, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x04, 0x32,
-	0x1e, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
-	0x1f, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x00, 0x32,
-	0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0xe0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
-	0x17, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
-	0x1b, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
-	0x1c, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x40, 0x00, 0x32,
-	0x16, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
-	0x1a, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
-	0x19, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
-	0x0b, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
-	0x0c, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x02, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x32,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x64, 0x02, 0x39,
-	0x00, 0x00, 0xfb, 0x03, 0x85, 0x01, 0x00, 0x00, 0x19, 0x00, 0x90, 0xba,
-	0x25, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
-	0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x32,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf3, 0x40, 0x01, 0x39,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xe3, 0x40, 0x01, 0x39,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xc3, 0x40, 0x01, 0x39,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb3, 0x40, 0x01, 0x39,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa3, 0x40, 0x01, 0x39,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x83, 0x40, 0x01, 0x39,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x40, 0x01, 0x39,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x63, 0x40, 0x01, 0x39,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x53, 0x40, 0x01, 0x39,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x43, 0x40, 0x01, 0x39,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x33, 0x40, 0x01, 0x39,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x13, 0x40, 0x01, 0x39,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x23, 0x40, 0x01, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x80, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x3f, 0x80, 0xfc, 0x35,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x32,
-	0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x03, 0x40, 0x38, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xd2, 0x01, 0x30, 0xb6,
-	0x00, 0x00, 0x13, 0x04, 0x04, 0x01, 0x00, 0xd0, 0x12, 0x00, 0x2d, 0xbc,
-	0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
-	0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0xe4, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x01, 0xec, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x12, 0x00, 0x2d, 0x3a,
-	0x4c, 0x00, 0x1a, 0x04, 0x02, 0x01, 0x00, 0x80, 0x82, 0x0d, 0x2d, 0xbc,
-	0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0xae, 0x0d, 0x02, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0x32,
-	0x20, 0x00, 0x00, 0x00, 0x00, 0x88, 0x86, 0xcc, 0x07, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x86, 0xcc, 0x07, 0x80, 0x00, 0x3a,
-	0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0x80, 0x36, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x64, 0x02, 0x40, 0x90, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x29, 0x40, 0x90, 0x3a,
-	0x00, 0x00, 0x26, 0x04, 0x12, 0x00, 0x00, 0x78, 0x09, 0xc0, 0x20, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xf2, 0x81, 0x97, 0xb6,
-	0x1d, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x78, 0xe9, 0xe5, 0x00, 0xb8,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x45, 0x90, 0x30,
-	0x00, 0x00, 0x24, 0x04, 0x02, 0x01, 0x00, 0x80, 0xc2, 0x82, 0x97, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x03, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x2c, 0x04, 0x8e, 0x01, 0x00, 0x80, 0x02, 0x40, 0x28, 0xb2,
-	0x00, 0x00, 0x26, 0x0f, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xd2,
-	0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x0e, 0x00, 0x36, 0x32,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xb9, 0x05, 0x36, 0x30,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x73, 0x80, 0x97, 0x34,
-	0x09, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x00, 0x32,
-	0x0a, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x73, 0x80, 0x97, 0x34,
-	0x09, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0xfe, 0xca, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
-	0x0a, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x3b, 0x04, 0x12, 0x01, 0x00, 0x00, 0x09, 0x40, 0x20, 0xb2,
-	0x00, 0x00, 0x39, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x3b, 0x04, 0x12, 0x00, 0x00, 0x04, 0x09, 0x40, 0x20, 0xb2,
-	0x00, 0x00, 0x3e, 0x04, 0x9f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
-	0x00, 0x00, 0x3d, 0x04, 0x12, 0x00, 0x00, 0x08, 0x09, 0x40, 0x20, 0xb2,
-	0x02, 0x00, 0x39, 0x04, 0x04, 0x01, 0x00, 0x78, 0x09, 0x24, 0x17, 0xb8,
-	0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x64, 0x16, 0x38,
-	0x00, 0x00, 0x39, 0x04, 0x04, 0x01, 0x00, 0x80, 0x02, 0x81, 0x97, 0xbc,
-	0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x03, 0x00, 0x36, 0x32,
-	0xfe, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x48, 0x03, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x00, 0x09, 0x40, 0x20, 0xb2,
-	0x00, 0x00, 0x44, 0x04, 0x12, 0x00, 0x00, 0x04, 0x09, 0x40, 0x20, 0xb2,
-	0x00, 0x00, 0x47, 0x04, 0x9f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
-	0x00, 0x00, 0x46, 0x04, 0x12, 0x00, 0x00, 0x08, 0x09, 0x40, 0x20, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x02, 0x00, 0x90, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x06, 0x00, 0x59, 0x04, 0x00, 0x00, 0x00, 0x0c, 0x09, 0x64, 0x16, 0x98,
-	0x00, 0x00, 0x68, 0x02, 0x00, 0x00, 0x00, 0x14, 0x08, 0x40, 0x90, 0x92,
-	0x00, 0x00, 0x97, 0x02, 0x00, 0x00, 0x00, 0x14, 0x08, 0x40, 0x90, 0x92,
-	0x33, 0x00, 0x74, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x11, 0x00, 0x74, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x39, 0x00, 0x74, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x7f, 0x02, 0x00, 0x00, 0x00, 0x14, 0x08, 0x40, 0x90, 0x92,
-	0x00, 0x00, 0x7f, 0x03, 0x00, 0x00, 0x00, 0x14, 0x08, 0x40, 0x90, 0x92,
-	0x5a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x82, 0xcd, 0x90, 0x3a,
-	0x0d, 0x00, 0x7c, 0x04, 0x00, 0x00, 0x00, 0xb0, 0x02, 0xe4, 0x16, 0x98,
-	0x0d, 0x00, 0x8e, 0x04, 0x00, 0x00, 0x00, 0xb0, 0x02, 0xe4, 0x16, 0x98,
-	0x0d, 0x00, 0x97, 0x04, 0x00, 0x00, 0x00, 0xb0, 0x02, 0xe4, 0x16, 0x98,
-	0x00, 0x00, 0xa3, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xad, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x40, 0x90, 0x9d,
-	0x00, 0x00, 0xb3, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xbd, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xc7, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xd1, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x40, 0x90, 0x9d,
-	0x00, 0x00, 0xd8, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xe1, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x40, 0x90, 0x9d,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xf3, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0xf3, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x40, 0x00, 0x92,
-	0xd8, 0x00, 0xf5, 0x04, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0xff, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xdc, 0x0f, 0x40, 0x90, 0x92,
-	0x00, 0x00, 0xe8, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xed, 0x04, 0x00, 0x00, 0x00, 0x78, 0x39, 0x40, 0x90, 0x97,
-	0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xec, 0x0e, 0x40, 0x90, 0x92,
-	0x00, 0x00, 0xef, 0x04, 0x00, 0x00, 0x00, 0xe8, 0x0e, 0x40, 0x90, 0x92,
-	0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xd4, 0x0e, 0x40, 0x90, 0x92,
-	0x00, 0x00, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x85, 0x05, 0x00, 0x00, 0x00, 0xdc, 0x0e, 0x40, 0x90, 0x92,
-	0x00, 0x00, 0x10, 0x05, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x08, 0x00, 0x15, 0x05, 0x00, 0x00, 0x00, 0x50, 0x1f, 0x24, 0x16, 0x98,
-	0x00, 0x00, 0x27, 0x05, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x92,
-	0x0d, 0x00, 0x32, 0x05, 0x00, 0x00, 0x00, 0xb0, 0x02, 0xe4, 0x16, 0x98,
-	0x00, 0x00, 0x33, 0x05, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x89, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x45, 0x90, 0x30,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x22, 0x80, 0x97, 0xbc,
-	0x3f, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0x0d, 0x00, 0xb0,
-	0x02, 0x00, 0x80, 0x04, 0xb0, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0xb9,
-	0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x04, 0x6b, 0x41, 0x90, 0x34,
-	0x00, 0x00, 0xb0, 0x03, 0x80, 0x01, 0x00, 0x80, 0x02, 0x40, 0xb0, 0xb6,
-	0x00, 0x00, 0xb0, 0x03, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0xb0, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x22, 0x00, 0x2b, 0x37,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x01, 0x00, 0x34,
-	0x00, 0x42, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x2a, 0x3a,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0x00, 0xb0, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0xd0, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0xf2, 0xc1, 0x38, 0xb4,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0x39,
-	0xb0, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
-	0x08, 0x00, 0xb0, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x99,
-	0x00, 0x00, 0x91, 0x04, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0x90, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0xfd, 0x32,
-	0x02, 0x00, 0x91, 0x04, 0xb0, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0xb9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x80, 0x90, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x40, 0x90, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x04, 0x3b, 0x40, 0xb0, 0x31,
-	0x00, 0x00, 0x8d, 0x04, 0x04, 0x00, 0x00, 0x80, 0x02, 0x00, 0x2b, 0xbc,
-	0xf1, 0x0f, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x8c, 0x0e, 0x00, 0x36, 0x92,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
-	0x02, 0x00, 0x98, 0x04, 0xb0, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0xb9,
-	0x00, 0x00, 0x9b, 0x04, 0x80, 0x01, 0x00, 0x80, 0x12, 0x40, 0xb0, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x3b, 0x40, 0xb0, 0x33,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xcd, 0x4a, 0xd0, 0x35,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0b, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x0c, 0x1b, 0xe4, 0xb0, 0x32,
-	0x00, 0x00, 0xb0, 0x03, 0x0b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0xa1, 0x04, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x90, 0xb2,
-	0x1f, 0x00, 0xb0, 0x03, 0x00, 0x00, 0x00, 0x80, 0x11, 0x40, 0x00, 0x99,
-	0x00, 0x00, 0xa0, 0x04, 0x04, 0x00, 0x00, 0x80, 0x02, 0x00, 0xf8, 0xbc,
-	0x00, 0x00, 0xb0, 0x03, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0xf8, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0xfc, 0xb6,
-	0x00, 0x00, 0xa7, 0x04, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0x90, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0xfd, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x42, 0x85, 0x90, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x80, 0x90, 0x32,
-	0x09, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x40, 0x90, 0x32,
-	0x0a, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xc8, 0x0f, 0x81, 0xfc, 0x94,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x72, 0x42, 0x90, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0xe2, 0x42, 0x90, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x78, 0x09, 0x64, 0x90, 0xb5,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x73, 0x00, 0x90, 0x3c,
-	0x10, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xb6, 0x04, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0x90, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0xfd, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x42, 0x85, 0x90, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x80, 0x90, 0x32,
-	0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x80, 0x90, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x40, 0x90, 0x32,
-	0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xe4, 0x0f, 0x40, 0x90, 0x92,
-	0x00, 0x00, 0xc0, 0x04, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0x90, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0xfd, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x42, 0x85, 0x90, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x80, 0x90, 0x32,
-	0x03, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x0e, 0x80, 0x90, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x40, 0x90, 0x32,
-	0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xac, 0x0e, 0x40, 0x90, 0x92,
-	0x00, 0x00, 0xca, 0x04, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0x90, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0xfd, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x42, 0x85, 0x90, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x80, 0x90, 0x32,
-	0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x40, 0x90, 0x32,
-	0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x80, 0x90, 0x32,
-	0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x48, 0x0f, 0x40, 0x90, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x82, 0x42, 0x90, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x78, 0x09, 0x64, 0x90, 0xb5,
-	0x00, 0x00, 0xd5, 0x04, 0x04, 0x01, 0x00, 0x80, 0x82, 0x42, 0x90, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x90, 0x32,
-	0x12, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x40, 0x1f, 0x40, 0x90, 0x9c,
-	0x00, 0x00, 0xdb, 0x04, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0x90, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0xfd, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x42, 0x85, 0x90, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x80, 0x90, 0x32,
-	0x07, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x40, 0x90, 0x32,
-	0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x82, 0x42, 0x90, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x78, 0x09, 0x64, 0x90, 0xb5,
-	0x00, 0x00, 0xe5, 0x04, 0x04, 0x01, 0x00, 0x80, 0x82, 0x42, 0x90, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x90, 0x32,
-	0x11, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xfc, 0x1f, 0x40, 0x90, 0x9c,
-	0x00, 0x00, 0xeb, 0x04, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0x90, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0xfd, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x0e, 0x80, 0x90, 0x32,
-	0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x88, 0x0e, 0x40, 0x90, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x40, 0x90, 0x37,
-	0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x80, 0x0f, 0xa4, 0x97, 0x9a,
-	0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xbc, 0x0e, 0x80, 0xee, 0x9d,
-	0x00, 0x00, 0xf2, 0x04, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x90, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0x00, 0x32,
-	0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xe4, 0x1e, 0x40, 0x90, 0x9c,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x22, 0x00, 0x90, 0x37,
-	0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x86, 0xc0, 0x07, 0x40, 0x90, 0x92,
-	0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0xe4, 0x16, 0x38,
-	0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xfa, 0x04, 0x04, 0x00, 0x00, 0x80, 0x02, 0x24, 0xf6, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x3f, 0x80, 0xfc, 0x34,
-	0x40, 0x80, 0xfc, 0x04, 0x00, 0x00, 0x00, 0x28, 0x09, 0x80, 0x36, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0f, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x79, 0x01, 0x00, 0x34,
-	0x02, 0x00, 0xfc, 0x04, 0xb0, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0xb9,
-	0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x0c, 0xab, 0xe4, 0xb0, 0x32,
-	0x1f, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x40, 0x00, 0x99,
-	0xea, 0x05, 0x05, 0x05, 0x04, 0x01, 0x00, 0x80, 0x82, 0x4d, 0x90, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x0f, 0x00, 0x15, 0x32,
-	0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x37, 0x32,
-	0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x0f, 0x00, 0x36, 0x32,
-	0x98, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x0f, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x0b, 0x05, 0x00, 0x00, 0x00, 0xc8, 0x4f, 0x80, 0xfc, 0x95,
-	0x36, 0x23, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0x4d, 0x90, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x0f, 0x80, 0x14, 0x32,
-	0x00, 0xf8, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x37, 0x32,
-	0xc0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x0f, 0x00, 0x36, 0x32,
-	0x98, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x0f, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x4f, 0x80, 0xfc, 0x34,
-	0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x8f, 0x4d, 0x90, 0x3a,
-	0x00, 0x00, 0x8a, 0x11, 0x60, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x8a, 0x11, 0x7a, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0xa9, 0x0f, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
-	0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x12, 0x05, 0x80, 0x01, 0x00, 0x80, 0x02, 0x40, 0x90, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x6f, 0x80, 0xfc, 0x34,
-	0x00, 0x00, 0x14, 0x05, 0x80, 0x01, 0x00, 0x80, 0x12, 0x40, 0x90, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x5f, 0x80, 0xfc, 0x34,
-	0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x17, 0x05, 0x04, 0x01, 0x00, 0x80, 0x32, 0x40, 0x90, 0xb0,
-	0x80, 0x01, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xc8, 0x8f, 0x8d, 0xfc, 0x91,
-	0x00, 0x00, 0x19, 0x05, 0x80, 0x00, 0x00, 0x80, 0x12, 0x40, 0x90, 0xb6,
-	0x00, 0x00, 0x1a, 0x05, 0x00, 0x00, 0x00, 0xc8, 0x7f, 0x80, 0xfc, 0x95,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x7f, 0x80, 0xfc, 0x34,
-	0x00, 0x00, 0x1c, 0x05, 0x80, 0x00, 0x00, 0x80, 0x02, 0x40, 0x90, 0xb6,
-	0x00, 0x00, 0x1d, 0x05, 0x00, 0x00, 0x00, 0xc8, 0x8f, 0x80, 0xfc, 0x95,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x8f, 0x80, 0xfc, 0x34,
-	0x00, 0x00, 0x20, 0x05, 0x80, 0x00, 0x00, 0x80, 0x22, 0x40, 0x90, 0xb6,
-	0xf1, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x0e, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x22, 0x05, 0x00, 0x00, 0x00, 0xc8, 0x1f, 0x81, 0xfc, 0x95,
-	0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x0e, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x1f, 0x81, 0xfc, 0x34,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x82, 0x02, 0xf5, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x03, 0x00, 0x00, 0x78, 0x09, 0x00, 0xf5, 0xbd,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xe2, 0x25, 0xf5, 0xb5,
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x1f, 0x24, 0x16, 0x38,
-	0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x50, 0x1f, 0x00, 0xf5, 0x9c,
-	0x80, 0x01, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x82, 0x8d, 0xfc, 0xb0,
-	0x00, 0x00, 0x2b, 0x05, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0x90, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0xfd, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0xf5, 0x3a,
-	0x8c, 0xcc, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0x80, 0x90, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x40, 0x90, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xec, 0x03, 0x40, 0x90, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x90, 0xbc,
-	0x00, 0x00, 0x34, 0x05, 0xb2, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0xec, 0x16, 0xe4, 0x6e, 0x3a,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
-	0x00, 0x00, 0x69, 0x05, 0x17, 0x10, 0x01, 0xf8, 0x02, 0x00, 0x6e, 0xb2,
-	0x06, 0x00, 0x3f, 0x05, 0x04, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x2f, 0xb0,
-	0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0x8d, 0x2f, 0x32,
-	0x00, 0xc0, 0xd3, 0x0e, 0x00, 0x00, 0x00, 0x28, 0x09, 0x80, 0x36, 0xd2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0x3c,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x86, 0xc8, 0x06, 0x00, 0x00, 0x32,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x46, 0x05, 0x04, 0x19, 0x86, 0x80, 0x02, 0x80, 0x6c, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x12, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0xc1, 0x08, 0x00, 0x04, 0x09, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0xc0, 0x15, 0x86, 0x2c, 0x09, 0xc0, 0x6c, 0x32,
-	0x00, 0x00, 0x4c, 0x05, 0x22, 0x1d, 0x86, 0xc8, 0x06, 0xc0, 0x92, 0xb2,
-	0x00, 0x00, 0x4c, 0x05, 0x00, 0x18, 0x86, 0xc8, 0x06, 0x40, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x22, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x09, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0xc2, 0x48, 0x00, 0x04, 0x09, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0xc0, 0x16, 0x86, 0x2c, 0x09, 0xc0, 0x6c, 0x32,
-	0x00, 0x00, 0x4c, 0x05, 0x21, 0x1d, 0x86, 0xc8, 0x06, 0xc0, 0x92, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x86, 0xc8, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x09, 0x80, 0x36, 0x32,
-	0x00, 0x00, 0x54, 0x05, 0x04, 0x02, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
-	0x00, 0x00, 0xd3, 0x0e, 0x00, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xdc,
-	0x00, 0x00, 0x52, 0x05, 0x80, 0x00, 0x00, 0x80, 0x02, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x54, 0x05, 0x81, 0x00, 0x00, 0xf8, 0x22, 0x80, 0x2f, 0xb4,
-	0x00, 0x00, 0x54, 0x05, 0x00, 0x18, 0x86, 0xc8, 0x06, 0x40, 0x00, 0x92,
-	0x00, 0x00, 0x54, 0x05, 0x82, 0x00, 0x00, 0xf8, 0x12, 0x80, 0x2f, 0xb4,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x86, 0xc8, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x2d, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x86, 0xc8, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x0a, 0x32,
-	0x00, 0x38, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0x00, 0x90, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x40, 0x90, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x17, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0xc0, 0x69, 0x05, 0x18, 0x00, 0x00, 0x00, 0xa9, 0xcd, 0x3e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x86, 0x04, 0x19, 0x80, 0x6c, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x07, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0x00, 0x00, 0x32,
-	0x00, 0x01, 0x00, 0x80, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x0c, 0xf7, 0x7f, 0x90, 0x30,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0x00, 0x90, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0x34,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x10, 0x86, 0x80, 0x72, 0x82, 0x6c, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x86, 0xa8, 0x42, 0x80, 0x6c, 0x37,
-	0x00, 0x00, 0x78, 0x05, 0x12, 0x00, 0x70, 0x38, 0x02, 0x00, 0x7c, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x0b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xe0, 0x07, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x3c, 0x02, 0x00, 0x7e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x30, 0x02, 0x00, 0x7e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x34, 0x02, 0x00, 0x7e, 0x32,
-	0x00, 0x00, 0x6b, 0x05, 0x02, 0x01, 0x00, 0x80, 0xb2, 0x82, 0x2a, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x32,
-	0x06, 0x00, 0x3f, 0x05, 0x04, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x2f, 0xb0,
-	0x00, 0x00, 0x39, 0x05, 0x04, 0x03, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0xe0, 0x06, 0x80, 0x2f, 0x32,
-	0x00, 0x00, 0xa4, 0x03, 0xa2, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x7a, 0x05, 0x04, 0x03, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
-	0x00, 0x00, 0x83, 0x05, 0x00, 0x10, 0x86, 0xc8, 0x46, 0x80, 0x2a, 0x96,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x86, 0xc8, 0x46, 0x80, 0x2a, 0x36,
-	0x00, 0x00, 0x7e, 0x05, 0x80, 0x00, 0x00, 0x80, 0x12, 0x80, 0x2f, 0xb6,
-	0x03, 0x00, 0x80, 0x05, 0x22, 0x00, 0x00, 0xf8, 0x82, 0x8d, 0x2f, 0xb2,
-	0x00, 0x00, 0x80, 0x05, 0x00, 0x18, 0x86, 0xc8, 0x06, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x83, 0x05, 0x80, 0x00, 0x00, 0x80, 0x22, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0xc2, 0x01, 0x00, 0xf8, 0x02, 0x80, 0x2f, 0x35,
-	0x00, 0xc0, 0xd3, 0x0e, 0x00, 0x00, 0x00, 0x28, 0x09, 0x80, 0x36, 0xd2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0x3c,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0xe0, 0x06, 0x80, 0x2f, 0x32,
-	0x00, 0x00, 0xa4, 0x03, 0xa2, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x05, 0x04, 0x01, 0x00, 0x80, 0xa2, 0xc0, 0xed, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0e, 0x80, 0x02, 0x32,
-	0x40, 0x7e, 0x05, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x0e, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x0e, 0x80, 0x07, 0x32,
-	0x64, 0x00, 0x8f, 0x05, 0x00, 0x00, 0x00, 0xcc, 0x0e, 0x00, 0x36, 0x92,
-	0x64, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xed, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0e, 0x40, 0x00, 0x32,
-	0xa0, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x0e, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x0e, 0xc0, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x0e, 0x80, 0x02, 0x32,
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x33, 0x7b, 0xec, 0x39,
-	0x1e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x6e, 0xc0, 0xec, 0x37,
-	0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xd8, 0x0e, 0xc0, 0xed, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x65, 0x01, 0x80, 0xa2, 0xdb, 0x2c, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x80, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x1c, 0x01, 0x80, 0x52, 0xc0, 0x6e, 0xbc,
-	0x2b, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xcd, 0x81, 0xbc,
-	0x3d, 0x00, 0x8a, 0x11, 0x02, 0x00, 0x00, 0x80, 0x82, 0xcd, 0x81, 0xbc,
-	0x35, 0x00, 0x9c, 0x05, 0x04, 0x00, 0x00, 0x80, 0x82, 0xcd, 0x81, 0xbc,
-	0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x89, 0xcd, 0x81, 0x3c,
-	0x10, 0x00, 0xe2, 0x10, 0x00, 0x1c, 0x01, 0x14, 0x59, 0xe4, 0x6e, 0xd9,
-	0xa4, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x82, 0xcd, 0x81, 0x3a,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x80, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x65, 0x01, 0x80, 0xa2, 0xdb, 0x2c, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x18, 0x01, 0x80, 0x92, 0xc0, 0x6e, 0xbc,
-	0x2b, 0x00, 0x8a, 0x11, 0x02, 0x00, 0x00, 0x80, 0x82, 0xcd, 0x81, 0xbc,
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x10, 0x00, 0xe2, 0x10, 0x00, 0x18, 0x01, 0x14, 0x79, 0xe0, 0x6e, 0xd9,
-	0xa4, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x82, 0xcd, 0x81, 0x3a,
-	0xe1, 0x05, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0xea, 0x05, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0xf3, 0x05, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0xfc, 0x05, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x05, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x0e, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x17, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x20, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x29, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x32, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x3b, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x44, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x4d, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x56, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x5f, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x68, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x71, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x7a, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x83, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x8c, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x95, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x9e, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0xa7, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0xb0, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0xb9, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0xc2, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0xcb, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0xd4, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0xdd, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0xe6, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0xef, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0xf8, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x01, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x0a, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x13, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x1c, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x25, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x2e, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x37, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x40, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x49, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x00, 0x00, 0x57, 0x03, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x52, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x57, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x5c, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x61, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x66, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x6b, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x70, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x75, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x7a, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x7f, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x84, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x89, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x8e, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x93, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x98, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x9d, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
-	0x00, 0x00, 0x5f, 0x03, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x71, 0x03, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x3b, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x79, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x88, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xda, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xda, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xda, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xea, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xea, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xea, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xe8, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xe8, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xe8, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x86, 0x0a, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0xd7, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x7d, 0x0a, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0xd7, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x7d, 0x0a, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0xd7, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x0c, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xe9, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xe9, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xe9, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xe9, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xc1, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0xb8, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0xc1, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xc1, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x81, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x00, 0x92,
-	0x00, 0x00, 0x81, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0x81, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0x81, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0x86, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x81, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x01, 0x92,
-	0x00, 0x00, 0x81, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x76, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0x76, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0x76, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x76, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xc9, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x47, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x4b, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0xb0, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x4b, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x4b, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0xa3, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x02, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x4c, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0xb0, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x4c, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x4c, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x51, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0x51, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0x51, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x51, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x68, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x64, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0x64, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0x64, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x64, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x7e, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0x7e, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0x7e, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x7e, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0x8f, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0xa0, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0xa0, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xb5, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0xb5, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0xb5, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x75, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0x75, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0x75, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x75, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xcc, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x02, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x88, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xc4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x88, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xc4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
-	0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x2a, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x2a, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x34, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x34, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x31, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xab, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xf3, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xb6, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0xb6, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0xb6, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x0a, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x1a, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0xb4, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xc3, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0xc3, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xe5, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xe8, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0xe8, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xea, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0xea, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0xea, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x00, 0x92,
-	0x00, 0x00, 0xc2, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0xc2, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x00, 0x92,
-	0x00, 0x00, 0xf8, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0xf8, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x2e, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x22, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0x22, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xef, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
-	0x00, 0x00, 0xef, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
-	0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
-	0x08, 0x00, 0xa1, 0x03, 0x00, 0x18, 0x01, 0xe8, 0x76, 0x20, 0x81, 0x99,
-	0x08, 0x00, 0x9d, 0x03, 0x00, 0x18, 0x01, 0xe8, 0x76, 0x20, 0x81, 0x99,
-	0x00, 0x00, 0xb0, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x08, 0x00, 0xa7, 0x07, 0x1d, 0x19, 0x01, 0xe8, 0x76, 0x20, 0x81, 0xb9,
-	0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
-	0x00, 0x00, 0xa1, 0x03, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
-	0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x94,
-	0x08, 0x00, 0xa1, 0x03, 0x00, 0x1c, 0x01, 0xe8, 0x76, 0x20, 0x81, 0x99,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x0f, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x01, 0xec, 0x06, 0xc0, 0x6e, 0x35,
-	0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x00, 0x2d, 0x37,
-	0xb4, 0xcc, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x97, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x99, 0xc0, 0x2c, 0x37,
-	0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0x8d, 0x97, 0x3a,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x10, 0x00, 0x00, 0x87, 0xbf, 0x97, 0xba,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x40, 0xfe, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x78, 0x09, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0xb7, 0x07, 0xb7, 0x10, 0x02, 0xe0, 0x06, 0x80, 0x97, 0xb2,
-	0x00, 0x00, 0xba, 0x07, 0x80, 0x00, 0x00, 0x80, 0xf2, 0x80, 0xfc, 0xb6,
-	0x00, 0x00, 0xbb, 0x07, 0x00, 0x00, 0x00, 0xc8, 0xff, 0x80, 0xfc, 0x94,
-	0x00, 0x00, 0xbc, 0x07, 0x9f, 0x99, 0x00, 0x80, 0x82, 0x1b, 0xee, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0xe0, 0x0e, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0xa7, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x1c, 0x09, 0x00, 0x6e, 0x32,
-	0x40, 0x00, 0xc1, 0x07, 0x06, 0x01, 0x00, 0x80, 0x82, 0xcd, 0x91, 0xbc,
-	0x00, 0x40, 0xc2, 0x07, 0x00, 0x18, 0x02, 0xe0, 0xa6, 0xcd, 0x2c, 0x92,
-	0x00, 0x60, 0x00, 0x00, 0x00, 0x18, 0x02, 0xe0, 0xa6, 0xcd, 0x2c, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x09, 0x80, 0x03, 0x32,
-	0x00, 0x00, 0xc5, 0x07, 0x80, 0xd7, 0x01, 0x80, 0x32, 0xc0, 0x6e, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x49, 0x00, 0x92, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x01, 0x18, 0x09, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x02, 0x24, 0x09, 0xc0, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x28, 0x09, 0x80, 0x6e, 0x32,
-	0x00, 0x00, 0xd3, 0x07, 0x80, 0x0e, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xb6,
-	0x02, 0x00, 0x00, 0x00, 0x00, 0x34, 0x02, 0xec, 0x06, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x01, 0x92, 0x3a,
-	0x00, 0x00, 0xcf, 0x07, 0x80, 0xd6, 0x01, 0x80, 0x42, 0xc0, 0x6e, 0xb6,
-	0x00, 0x82, 0x00, 0x00, 0x00, 0x10, 0x02, 0xe0, 0xa6, 0xcd, 0x91, 0x32,
-	0x00, 0xa0, 0x00, 0x00, 0x00, 0x2c, 0x02, 0xe8, 0x06, 0x00, 0x36, 0x32,
-	0x28, 0x00, 0xdd, 0x07, 0x00, 0x32, 0x02, 0xec, 0x06, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0xd3, 0x01, 0x00, 0x1c, 0xd9, 0xc1, 0x91, 0x34,
-	0x00, 0x82, 0x00, 0x00, 0x00, 0x10, 0x02, 0xe0, 0xa6, 0xcd, 0x91, 0x32,
-	0x00, 0xa0, 0x00, 0x00, 0x00, 0x2c, 0x02, 0xe8, 0x06, 0x00, 0x36, 0x32,
-	0x34, 0x00, 0xdd, 0x07, 0x00, 0x32, 0x02, 0xec, 0x06, 0x00, 0x36, 0x92,
-	0x04, 0x00, 0x00, 0x00, 0x00, 0x34, 0x02, 0xec, 0x06, 0x00, 0x36, 0x32,
-	0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x0d, 0x92, 0x3a,
-	0x00, 0x00, 0xd9, 0x07, 0x80, 0xd6, 0x01, 0x80, 0x42, 0xc0, 0x6e, 0xb6,
-	0x00, 0x86, 0x00, 0x00, 0x00, 0x10, 0x02, 0xe0, 0xa6, 0xcd, 0x91, 0x32,
-	0x04, 0xa0, 0x00, 0x00, 0x00, 0x2c, 0x02, 0xe8, 0x06, 0x00, 0x36, 0x32,
-	0x14, 0x00, 0xdd, 0x07, 0x00, 0x32, 0x02, 0xec, 0x06, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0xd3, 0x01, 0x00, 0x1c, 0xd9, 0xc1, 0x91, 0x34,
-	0x00, 0x86, 0x00, 0x00, 0x00, 0x10, 0x02, 0xe0, 0xa6, 0xcd, 0x91, 0x32,
-	0x04, 0xa0, 0x00, 0x00, 0x00, 0x2c, 0x02, 0xe8, 0x06, 0x00, 0x36, 0x32,
-	0x20, 0x00, 0xdd, 0x07, 0x00, 0x32, 0x02, 0xec, 0x06, 0x00, 0x36, 0x92,
-	0x12, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0xec, 0x86, 0xcd, 0x91, 0x3a,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x28, 0x02, 0xe8, 0x86, 0x24, 0x90, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x02, 0xe0, 0x96, 0x24, 0x14, 0x37,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0xe0, 0x06, 0x80, 0x91, 0x32,
-	0x00, 0x00, 0xe3, 0x07, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x92, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0xe0, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0xe0, 0x06, 0x00, 0x00, 0x32,
-	0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x00, 0x2d, 0x37,
-	0x00, 0xcd, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x97, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x99, 0xc0, 0x2c, 0x37,
-	0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0x8d, 0x97, 0x3a,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x10, 0x00, 0x00, 0x87, 0xbf, 0x97, 0xba,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x40, 0xfe, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0xf2, 0xc1, 0x38, 0xb4,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0xc9, 0x01, 0x80, 0x02, 0x80, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x01, 0xec, 0x06, 0x80, 0x83, 0x32,
-	0x01, 0x00, 0xaa, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x00, 0xc0, 0xf9, 0x07, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
-	0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
-	0x2c, 0x00, 0x9d, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
-	0x00, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x50, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
-	0x00, 0x00, 0xff, 0x07, 0x80, 0xd7, 0x01, 0x2c, 0x09, 0xc0, 0x6e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0xda, 0xd7, 0x01, 0xec, 0x06, 0xc0, 0x6e, 0x35,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x01, 0xec, 0x06, 0x40, 0xed, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01, 0xec, 0x06, 0x80, 0xee, 0x32,
-	0x00, 0x00, 0x02, 0x08, 0x80, 0x01, 0x00, 0x80, 0x62, 0xc0, 0x92, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0x81, 0x2f, 0x34,
-	0x00, 0x00, 0xaa, 0x07, 0x04, 0x06, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
-	0x00, 0x00, 0xaa, 0x07, 0x80, 0x00, 0x00, 0x80, 0x72, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x72, 0x81, 0x2f, 0x34,
-	0x3b, 0x00, 0xaa, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x07, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xb2, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x0a, 0x08, 0x00, 0x00, 0x00, 0xf8, 0xb2, 0x81, 0x2f, 0x94,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0xa0, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x01, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0x60, 0x11, 0x00, 0x78, 0x01, 0x60, 0x08, 0x00, 0x6e, 0xf2,
-	0x00, 0x00, 0x0f, 0x08, 0x12, 0x01, 0x00, 0xc8, 0x02, 0x00, 0x20, 0xb2,
-	0x00, 0x00, 0x12, 0x08, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x1e, 0x08, 0x12, 0x01, 0x00, 0x5c, 0x08, 0x80, 0x20, 0xb2,
-	0x00, 0x00, 0x12, 0x08, 0x12, 0x01, 0x00, 0x60, 0x02, 0x80, 0x2c, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x14, 0x08, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x80, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0x80, 0xff, 0x3a,
-	0x00, 0x00, 0x17, 0x08, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0xaa, 0x07, 0x80, 0x00, 0x00, 0x80, 0x72, 0x81, 0x2f, 0xb6,
-	0x3b, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0xf8, 0x72, 0x81, 0x2f, 0x94,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x00, 0x14, 0x08, 0x80, 0x6e, 0x32,
-	0x00, 0x00, 0x12, 0x08, 0x12, 0x00, 0x00, 0xc8, 0x02, 0x00, 0x20, 0xb2,
-	0x00, 0x00, 0x10, 0x08, 0x12, 0x00, 0x00, 0x5c, 0x08, 0x80, 0x20, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0xa0, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x2d, 0xbc,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x78, 0xe1, 0x6e, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x20, 0x07, 0x00, 0x00, 0x32,
-	0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x78, 0xca, 0xe9, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x08, 0x40, 0x80, 0x32,
-	0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x79, 0x21, 0x2f, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x02, 0x44, 0xe2, 0x25, 0x6e, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x90, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x3e,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xd8, 0xa0, 0x81, 0x3c,
-	0x00, 0x00, 0x82, 0x08, 0x04, 0xb0, 0x00, 0xe0, 0xd6, 0x20, 0x6e, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x50, 0x08, 0x04, 0x00, 0x00, 0x3c, 0xd8, 0xe0, 0x83, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x81, 0xbc,
-	0x00, 0x00, 0x34, 0x08, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0xe2, 0xe0, 0x38, 0xb2,
-	0x00, 0x00, 0x41, 0x08, 0x51, 0x00, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x9a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xf9, 0x81, 0x83, 0x34,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0xe2, 0xe5, 0x38, 0xb2,
-	0x00, 0x00, 0x39, 0x08, 0x80, 0x00, 0x00, 0x80, 0x82, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x5c, 0x10, 0x00, 0xa0, 0x01, 0x50, 0x08, 0x00, 0x6e, 0xf2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0xe0, 0x06, 0x00, 0x85, 0x32,
-	0x00, 0x00, 0x3b, 0x08, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x3f, 0x08, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x3a, 0x08, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x46, 0x08, 0x2a, 0x01, 0x00, 0x00, 0xd8, 0x20, 0x80, 0xba,
-	0x00, 0x00, 0x45, 0x08, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x32,
-	0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
-	0x00, 0x00, 0x00, 0x00, 0xca, 0xe0, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0xf0, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x18, 0x81, 0x83, 0x35,
-	0x00, 0x00, 0x28, 0x08, 0x04, 0xb0, 0x00, 0x80, 0x82, 0x9b, 0x81, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x0d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xf8, 0x42, 0x80, 0x2f, 0x35,
-	0x08, 0xa0, 0x28, 0x08, 0x12, 0x01, 0x00, 0x40, 0xa2, 0xcd, 0x39, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xf9, 0x81, 0x83, 0x34,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0xe2, 0xe5, 0x38, 0xb2,
-	0x00, 0x00, 0x58, 0x08, 0x28, 0x00, 0x00, 0x6c, 0xd8, 0xe0, 0x86, 0xba,
-	0x00, 0x00, 0x5b, 0x10, 0x00, 0xa0, 0x01, 0x50, 0x08, 0x00, 0x6e, 0xf2,
-	0x00, 0x00, 0x58, 0x08, 0x1d, 0xf8, 0x01, 0xe0, 0x06, 0x00, 0x85, 0xb2,
-	0x00, 0x00, 0x58, 0x08, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
-	0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
-	0x00, 0x00, 0x5c, 0x08, 0x04, 0xa0, 0x00, 0xe0, 0x06, 0x80, 0x81, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x00, 0xe8, 0x06, 0x40, 0x81, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x90, 0x00, 0xe0, 0x06, 0xc0, 0x86, 0xb2,
-	0x00, 0x00, 0x6e, 0x08, 0x00, 0x98, 0x00, 0xe0, 0x06, 0xc0, 0x84, 0x92,
-	0x00, 0x00, 0x62, 0x08, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x5f, 0x08, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x1d, 0x00, 0x62, 0x08, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x5e, 0x08, 0x00, 0x00, 0x00, 0xf8, 0xe2, 0x80, 0x2f, 0x94,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0xe0, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0xca, 0xe8, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0xf0, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x6a, 0x08, 0x04, 0xb0, 0x00, 0x80, 0x82, 0x9b, 0x81, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x0d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xf8, 0x42, 0x80, 0x2f, 0x35,
-	0x08, 0xa0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0xcd, 0x39, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0xe0, 0x06, 0x80, 0x81, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0xe0, 0x06, 0xc0, 0x84, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x90, 0x00, 0xe0, 0x06, 0xc0, 0x86, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x00, 0xe8, 0x06, 0x40, 0x81, 0x32,
-	0x00, 0x00, 0x74, 0x08, 0x2a, 0x5d, 0x01, 0xec, 0x06, 0x80, 0xee, 0xb2,
-	0x00, 0x00, 0x71, 0x08, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x1d, 0x00, 0x74, 0x08, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x70, 0x08, 0x00, 0x00, 0x00, 0xf8, 0xe2, 0x80, 0x2f, 0x94,
-	0x10, 0x04, 0x77, 0x08, 0x37, 0x00, 0x00, 0xf8, 0xa2, 0x8d, 0x2f, 0xb1,
-	0x3b, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x72, 0x81, 0x2f, 0x34,
-	0x08, 0x00, 0x00, 0x00, 0xca, 0x1c, 0x01, 0xe8, 0x76, 0x20, 0x81, 0x39,
-	0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
-	0x00, 0x00, 0x7d, 0x08, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x7c, 0x08, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x1d, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x82, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xc2, 0x00, 0x03, 0xbc,
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x80, 0x67, 0xa1, 0x73, 0x39,
-	0x30, 0x00, 0xa4, 0x03, 0x12, 0x01, 0x00, 0x5c, 0xa2, 0x8d, 0x2c, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xd2, 0xe0, 0x83, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x2a, 0x00, 0x00, 0x78, 0xf9, 0x81, 0x83, 0xb4,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0xe2, 0xe5, 0x38, 0xb2,
-	0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
-	0x00, 0x00, 0x8a, 0x08, 0x1d, 0x00, 0x00, 0x38, 0x18, 0x81, 0x83, 0xb5,
-	0x00, 0x00, 0x8a, 0x08, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
-	0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
-	0x00, 0x00, 0x8d, 0x08, 0x04, 0x06, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xf8, 0x42, 0x80, 0x2f, 0x34,
-	0x08, 0xc0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0xcd, 0x39, 0xb2,
-	0x00, 0x00, 0x90, 0x08, 0x80, 0x00, 0x00, 0x80, 0x82, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x5c, 0x10, 0x00, 0xa0, 0x01, 0x50, 0x08, 0x00, 0x6e, 0xf2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0xe0, 0x06, 0x00, 0x85, 0x32,
-	0x00, 0x00, 0x92, 0x08, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0xae, 0x08, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x95, 0x08, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0x35,
-	0x00, 0x00, 0xac, 0x08, 0x04, 0x00, 0x00, 0x80, 0x02, 0x61, 0x80, 0xbc,
-	0x00, 0x00, 0xa4, 0x08, 0x80, 0xb8, 0x00, 0x00, 0x09, 0xc0, 0x6e, 0xb2,
-	0x40, 0x00, 0x9c, 0x08, 0x04, 0x00, 0x00, 0x80, 0x82, 0x0d, 0x90, 0xbc,
-	0x80, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0x0d, 0x90, 0xbc,
-	0x00, 0x00, 0x9c, 0x08, 0x02, 0xb0, 0x00, 0x80, 0x82, 0x1b, 0x84, 0xbc,
-	0x00, 0x00, 0xa4, 0x08, 0x00, 0x00, 0x00, 0xf8, 0xb2, 0x81, 0x2f, 0x94,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x07, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xb2, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0xd6, 0x01, 0x80, 0x52, 0xc0, 0x6e, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x01, 0xec, 0x56, 0xc0, 0x6e, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x18, 0x00, 0x86, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xb7, 0x01, 0x78, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x01, 0xe0, 0x06, 0x00, 0x86, 0x32,
-	0x40, 0x00, 0xae, 0x08, 0x04, 0x00, 0x00, 0x80, 0x82, 0x0d, 0x90, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0xa0, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x01, 0x11, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x20, 0x80, 0xfa,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x00, 0x00, 0x3c, 0x18, 0x20, 0x84, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0xb0, 0x00, 0x3c, 0x88, 0xdb, 0x83, 0xbe,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xc2, 0x01, 0x78, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xf7, 0x20, 0x78, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x58, 0x78, 0x01, 0xe0, 0xf6, 0x20, 0x86, 0x3a,
-	0x00, 0x00, 0x25, 0x08, 0x00, 0x00, 0x00, 0x04, 0xf8, 0x60, 0x80, 0x9a,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x72, 0x81, 0x2f, 0xb6,
-	0x2e, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x82, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xc2, 0x00, 0x03, 0xbc,
-	0x10, 0x00, 0x00, 0x00, 0xd4, 0x18, 0x00, 0x80, 0x67, 0xa1, 0x73, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0xda, 0x5c, 0x01, 0xec, 0x06, 0x80, 0xee, 0x32,
-	0x30, 0x00, 0xaa, 0x07, 0x12, 0x01, 0x00, 0x5c, 0xa2, 0x8d, 0x2c, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xc2, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x1a, 0x08, 0x00, 0x00, 0x00, 0xf8, 0xc2, 0x81, 0x2f, 0x95,
-	0x00, 0x00, 0xb8, 0x08, 0x80, 0x00, 0x00, 0x80, 0xc2, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0xbb, 0x08, 0x00, 0xd0, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xc2, 0x81, 0x2f, 0x35,
-	0x00, 0x00, 0xbb, 0x08, 0x04, 0xd1, 0x01, 0x80, 0x02, 0x80, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x01, 0xec, 0x26, 0xc0, 0x6e, 0x34,
-	0x00, 0x00, 0xbd, 0x08, 0x80, 0x00, 0x00, 0x80, 0x92, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0xc0, 0x08, 0x00, 0xc8, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x92, 0x81, 0x2f, 0x35,
-	0x00, 0x00, 0xc0, 0x08, 0x04, 0xc9, 0x01, 0x80, 0x02, 0x80, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0x34,
-	0x10, 0x00, 0xaa, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xaa, 0x07, 0x9a, 0x01, 0x00, 0xf8, 0x42, 0x81, 0x2f, 0xb5,
-	0x00, 0x00, 0xaa, 0x07, 0x12, 0x00, 0x00, 0xc8, 0x02, 0x00, 0x20, 0xb2,
-	0x00, 0x00, 0xc7, 0x08, 0x12, 0x01, 0x00, 0x5c, 0x08, 0x80, 0x20, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0x02, 0x80, 0x2c, 0xb2,
-	0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0x80, 0xff, 0x9a,
-	0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x79, 0x21, 0x2f, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xf9, 0x81, 0x97, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x02, 0x44, 0xe2, 0x25, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, 0x50, 0x08, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x01, 0x60, 0x08, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x0c, 0x09, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x1c, 0x09, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x77, 0x10, 0x00, 0xa8, 0x01, 0x08, 0x09, 0x00, 0x6e, 0xf2,
-	0x00, 0x00, 0x00, 0x00, 0xd4, 0xf8, 0x01, 0xe0, 0x06, 0x00, 0x85, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0xda, 0x5c, 0x01, 0xec, 0x06, 0x80, 0xee, 0x32,
-	0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
-	0x00, 0x00, 0xd4, 0x08, 0x23, 0x29, 0x02, 0x04, 0x09, 0x80, 0x6e, 0xb2,
-	0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x08, 0x00, 0xd8, 0x08, 0x1d, 0x1c, 0x01, 0xe8, 0x76, 0x20, 0x81, 0xb9,
-	0x00, 0x00, 0xd8, 0x08, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
-	0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
-	0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
-	0x00, 0x00, 0xdc, 0x08, 0x9d, 0x01, 0x00, 0x80, 0x07, 0xc0, 0x90, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x80, 0x07, 0xc0, 0x91, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x80, 0x07, 0x00, 0xee, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x80, 0x07, 0xc0, 0x85, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x07, 0x40, 0x90, 0x32,
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x80, 0x87, 0x8d, 0x85, 0x37,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x80, 0x07, 0x00, 0x86, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x80, 0x07, 0x00, 0x85, 0x32,
-	0x00, 0x00, 0xe3, 0x08, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x30, 0x00, 0xa4, 0x03, 0x12, 0x01, 0x00, 0x5c, 0xa2, 0x8d, 0x2c, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x12, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xa2, 0x8d, 0x2f, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x01, 0x78, 0x09, 0x80, 0x6e, 0x32,
-	0x00, 0x00, 0xaa, 0x07, 0xdc, 0xd1, 0x01, 0xe8, 0x06, 0x80, 0x97, 0x92,
-	0x12, 0x00, 0xaa, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x4f, 0x0e, 0x00, 0x00, 0x00, 0x18, 0x09, 0x40, 0x81, 0xf2,
-	0x00, 0x00, 0x2f, 0x0e, 0x00, 0xa8, 0x01, 0x20, 0x09, 0x00, 0x6e, 0xf2,
-	0x00, 0x00, 0xaa, 0x07, 0x80, 0x01, 0x00, 0x80, 0xf2, 0x80, 0x2f, 0xb6,
-	0x30, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0xf8, 0x42, 0x81, 0x2f, 0x94,
-	0x00, 0x00, 0xaa, 0x07, 0x35, 0x01, 0x00, 0xf8, 0x12, 0x81, 0x2f, 0xb5,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
-	0x00, 0xc0, 0xf6, 0x08, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
-	0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
-	0x00, 0x00, 0x9d, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x72, 0xe0, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x47, 0x10, 0x00, 0x98, 0x01, 0x28, 0x09, 0x00, 0x6e, 0xf2,
-	0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xff, 0x08, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0xff, 0x08, 0x80, 0x00, 0x00, 0x80, 0x42, 0x81, 0x2f, 0xb6,
-	0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x2f, 0xd2,
-	0x00, 0x00, 0xff, 0x08, 0x08, 0x5b, 0x01, 0xec, 0x06, 0xfb, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x01, 0xec, 0x06, 0x00, 0x00, 0x32,
-	0x34, 0x00, 0x00, 0x00, 0xd4, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0x32,
-	0x00, 0x00, 0x06, 0x09, 0x80, 0x01, 0x00, 0x80, 0x92, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xc2, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x0d, 0x09, 0x08, 0xc9, 0x01, 0xe8, 0x06, 0xbb, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x32,
-	0x32, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x58, 0x10, 0x00, 0x00, 0x00, 0x28, 0x09, 0x80, 0x01, 0xf2,
-	0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x0d, 0x09, 0x80, 0x01, 0x00, 0x80, 0xc2, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x92, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x0d, 0x09, 0x08, 0xd1, 0x01, 0xe8, 0x06, 0xbb, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x32,
-	0x32, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x58, 0x10, 0x00, 0x00, 0x00, 0x28, 0x09, 0xc0, 0x01, 0xf2,
-	0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xaa, 0x07, 0x80, 0x01, 0x00, 0x80, 0xf2, 0x81, 0x2f, 0xb6,
-	0x17, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x07, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
-	0x00, 0x00, 0x13, 0x09, 0x12, 0x00, 0x00, 0xc8, 0x02, 0x00, 0x20, 0xb2,
-	0x00, 0x00, 0x16, 0x09, 0x12, 0x01, 0x00, 0x5c, 0x08, 0x80, 0x20, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0x02, 0x80, 0x2c, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0x80, 0xff, 0x3a,
-	0x00, 0x00, 0x9d, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x72, 0xe0, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x79, 0x21, 0x2f, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xf9, 0x81, 0x97, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x02, 0x44, 0xe2, 0x25, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0xd4, 0xa0, 0x01, 0x50, 0x08, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0xdb, 0x79, 0x01, 0x60, 0x08, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x5c, 0x10, 0x00, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0xf2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0xe0, 0x06, 0x00, 0x85, 0x32,
-	0x00, 0x00, 0x1f, 0x09, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x30, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0xa2, 0x8d, 0x2c, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x07, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
-	0x00, 0x00, 0xaa, 0x07, 0xda, 0x5c, 0x01, 0xec, 0x06, 0x80, 0xee, 0x92,
-	0x00, 0x00, 0xaa, 0x07, 0x9f, 0x41, 0x01, 0x80, 0x52, 0x20, 0x6e, 0xbc,
-	0x00, 0x00, 0x2d, 0x09, 0x9f, 0x98, 0x01, 0x80, 0x52, 0x20, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
-	0x00, 0xc0, 0x2b, 0x09, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
-	0x20, 0x80, 0xaa, 0x07, 0x31, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x12, 0x81, 0x2f, 0x34,
-	0x3a, 0x00, 0xaa, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x47, 0x10, 0x00, 0x98, 0x01, 0x28, 0x09, 0x00, 0x6e, 0xf2,
-	0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xaa, 0x07, 0xd5, 0x41, 0x01, 0xe0, 0x06, 0x40, 0x81, 0x92,
-	0x00, 0x00, 0xaa, 0x07, 0x04, 0xb0, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x08, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x60, 0x11, 0x00, 0x78, 0x01, 0x60, 0x08, 0x00, 0x6e, 0xf2,
-	0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x78, 0x09, 0x80, 0x6e, 0x32,
-	0x00, 0x00, 0x35, 0x09, 0x04, 0xd4, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x19, 0x80, 0x97, 0x37,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0xe0, 0xe6, 0x25, 0x6e, 0x3a,
-	0x00, 0x00, 0x60, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0x39, 0x09, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xaa, 0x07, 0x00, 0x90, 0x01, 0xe0, 0x06, 0x00, 0x80, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0xe0, 0x06, 0x00, 0x80, 0x32,
-	0x00, 0x00, 0x1a, 0x08, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x00, 0x6e, 0x32,
-	0x02, 0x00, 0x3f, 0x09, 0x04, 0xb9, 0x00, 0x80, 0x82, 0xcd, 0x6e, 0xbc,
-	0x00, 0x00, 0x41, 0x09, 0x80, 0x00, 0x00, 0x80, 0x72, 0x80, 0xfc, 0xb6,
-	0x00, 0x00, 0x44, 0x09, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x41, 0x09, 0x80, 0x00, 0x00, 0x80, 0x82, 0x80, 0xfc, 0xb6,
-	0x00, 0x00, 0x44, 0x09, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x00, 0xf5, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x42, 0xbd, 0x97, 0x30,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x99, 0xb1, 0xf2, 0xc0, 0x7c, 0x30,
-	0x00, 0xc0, 0x48, 0x09, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
-	0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
-	0x00, 0x00, 0xa1, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x50, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x07, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xa2, 0x00, 0x2d, 0x37,
-	0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x99, 0xe1, 0x07, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x4d, 0x09, 0x04, 0x01, 0x00, 0x78, 0x19, 0x80, 0x97, 0xbc,
-	0x02, 0x00, 0x59, 0x09, 0x04, 0xb9, 0x00, 0x80, 0x82, 0xcd, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x48, 0xd6, 0x01, 0x00, 0x78, 0xc9, 0xcd, 0x2c, 0x32,
-	0x00, 0x00, 0x51, 0x09, 0xb6, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x64, 0x02, 0x80, 0x97, 0xb2,
-	0x00, 0x00, 0x53, 0x09, 0x12, 0x08, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x54, 0x09, 0x12, 0x18, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x55, 0x09, 0x12, 0x10, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0xa6, 0x54, 0x01, 0xec, 0x06, 0x00, 0x2b, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x01, 0xe8, 0x06, 0xc0, 0x2c, 0x32,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x0e, 0x01, 0xec, 0x06, 0x00, 0x00, 0x94,
-	0x00, 0x20, 0x00, 0x4c, 0xd6, 0x01, 0x00, 0x78, 0xc9, 0xcd, 0x2c, 0x32,
-	0x00, 0x00, 0x5a, 0x09, 0xb6, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x64, 0x02, 0x80, 0x97, 0xb2,
-	0x00, 0x00, 0x5c, 0x09, 0x12, 0x08, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x5d, 0x09, 0x12, 0x30, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x5e, 0x09, 0x12, 0x38, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x5f, 0x09, 0x12, 0x40, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x60, 0x09, 0x12, 0x48, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x61, 0x09, 0x12, 0x10, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x62, 0x09, 0x12, 0x18, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x63, 0x09, 0x12, 0x20, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x64, 0x09, 0x12, 0x28, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0xa6, 0x54, 0x01, 0xec, 0x06, 0x00, 0x2b, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x01, 0xe8, 0x06, 0xc0, 0x2c, 0x32,
-	0x03, 0x00, 0xa2, 0x07, 0x00, 0x0e, 0x01, 0xec, 0x06, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x02, 0x32,
-	0x00, 0x00, 0x6b, 0x09, 0x00, 0x00, 0x00, 0x14, 0x08, 0x80, 0x3d, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x02, 0x32,
-	0x00, 0x00, 0x6e, 0x09, 0x04, 0x00, 0x00, 0xdc, 0x53, 0x60, 0x3d, 0xb3,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x03, 0x39,
-	0x6a, 0x09, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x00, 0xc0, 0x74, 0x09, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
-	0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
-	0x14, 0x00, 0x9d, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x07, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xc0, 0x2c, 0x32,
-	0x00, 0x10, 0x00, 0x82, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
-	0x00, 0x00, 0xa2, 0x07, 0xca, 0x01, 0x00, 0x08, 0xe8, 0x01, 0x00, 0x94,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x62, 0x81, 0x2f, 0xb6,
-	0x2c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x7d, 0x09, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
-	0x29, 0x00, 0xa2, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x2c, 0x09, 0xc0, 0x85, 0xd2,
-	0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
-	0x00, 0x00, 0xa1, 0x03, 0x23, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
-	0x3c, 0x00, 0xa1, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x2c, 0x09, 0xc0, 0x85, 0xd2,
-	0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0x94,
-	0x00, 0x00, 0x8c, 0x09, 0x38, 0x01, 0x00, 0xd8, 0x02, 0x80, 0x01, 0xb2,
-	0x00, 0x00, 0x8c, 0x09, 0x1e, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x9c, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8f, 0x09, 0x12, 0x01, 0x00, 0x60, 0x08, 0x40, 0x23, 0xb2,
-	0x00, 0x82, 0x9c, 0x10, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0xf2,
-	0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x24, 0x08, 0x00, 0x23, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x20, 0x08, 0xc0, 0x23, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x18, 0x08, 0x80, 0x23, 0xb2,
-	0x00, 0xc0, 0x99, 0x09, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x38, 0x02, 0x80, 0x81, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x3c, 0x02, 0x00, 0x82, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x30, 0x02, 0x40, 0x82, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x34, 0x02, 0x00, 0x86, 0xb2,
-	0x20, 0x80, 0x9c, 0x10, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0xf2,
-	0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x40, 0x80, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x40, 0x82, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x86, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
-	0x00, 0x00, 0x01, 0x0e, 0x00, 0x30, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0xfa,
-	0x00, 0x00, 0xa2, 0x09, 0x38, 0x01, 0x00, 0x2c, 0xf8, 0x01, 0x0b, 0xb4,
-	0x00, 0x00, 0xa2, 0x09, 0x02, 0x0d, 0x02, 0x80, 0xa2, 0x5b, 0x80, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xc8, 0xc1, 0x82, 0x34,
-	0x00, 0x00, 0x8a, 0x11, 0x9f, 0xa8, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0xbc,
-	0x00, 0x00, 0x3b, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0xa7, 0x09, 0x27, 0x01, 0x00, 0xd8, 0x02, 0x80, 0x01, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x2c, 0xe8, 0xc0, 0x82, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0xd5, 0x40, 0x01, 0xe0, 0x06, 0x00, 0x87, 0x32,
-	0x08, 0x00, 0xb0, 0x10, 0x00, 0x18, 0x01, 0xe8, 0x76, 0x20, 0x81, 0xf9,
-	0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
-	0x00, 0x00, 0xab, 0x09, 0x23, 0x19, 0x00, 0x00, 0x07, 0x80, 0x81, 0xb2,
-	0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0xad, 0x09, 0x1d, 0x21, 0x00, 0x00, 0x07, 0x00, 0x82, 0xb2,
-	0x00, 0x00, 0xb0, 0x09, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
-	0x00, 0x00, 0xb0, 0x09, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
-	0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x62, 0x80, 0x2d, 0xbc,
-	0x10, 0x00, 0xb6, 0x09, 0x2c, 0x30, 0x00, 0x00, 0x17, 0xe0, 0x2c, 0xb9,
-	0x00, 0x00, 0xb8, 0x09, 0x8e, 0x39, 0x00, 0x00, 0x07, 0xc0, 0x82, 0xb2,
-	0x00, 0x00, 0xb8, 0x09, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x87, 0x92,
-	0x00, 0x00, 0xb8, 0x09, 0x8e, 0x39, 0x00, 0x00, 0xb7, 0xc1, 0x82, 0xb4,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x87, 0x32,
-	0x00, 0x00, 0xba, 0x09, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0xc0, 0x09, 0x04, 0x01, 0x00, 0x80, 0x12, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0xb8, 0x09, 0x9f, 0x01, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0x08, 0xe8, 0x01, 0x00, 0x34,
-	0x00, 0x00, 0xa4, 0x03, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0xc8, 0x09, 0x1e, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x9c, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x9f, 0xa8, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0xbc,
-	0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x00, 0x14, 0x08, 0x00, 0x00, 0xf2,
-	0x00, 0x00, 0x3b, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0xa4, 0x07, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x81, 0xbc,
-	0x00, 0x00, 0xce, 0x09, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
-	0x00, 0x00, 0xa4, 0x07, 0x12, 0x01, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa2, 0x07, 0x80, 0x00, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x1c, 0x40, 0x02, 0x80, 0x06, 0xc0, 0x85, 0xb2,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0x94,
-	0x00, 0x00, 0xa2, 0x07, 0x80, 0x00, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
-	0x00, 0x00, 0x2c, 0x10, 0xd6, 0x01, 0x00, 0x2c, 0x09, 0xc0, 0x85, 0xd2,
-	0x00, 0x00, 0xa1, 0x03, 0xd2, 0x01, 0x00, 0x94, 0x1e, 0x40, 0xe9, 0x9a,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x20, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xf2, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0xee, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x80, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x51, 0x01, 0x80, 0x02, 0x80, 0x6e, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x21, 0x01, 0x80, 0x02, 0x00, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0xe8, 0x06, 0x40, 0x81, 0x32,
-	0x00, 0x00, 0xe4, 0x09, 0x1f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0xe1, 0x09, 0x9e, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa4, 0x07, 0x2a, 0x31, 0x01, 0xe0, 0x06, 0x00, 0x00, 0xb2,
-	0x18, 0x00, 0x00, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0x39,
-	0xa4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x0c, 0x00, 0xeb, 0x09, 0x00, 0x00, 0x00, 0x58, 0x08, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0xeb, 0x09, 0x00, 0x00, 0x00, 0x58, 0x08, 0x00, 0x00, 0x92,
-	0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x08, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x20, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xf2, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0xee, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0x8a, 0x11, 0x1f, 0x30, 0x00, 0x28, 0x08, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
-	0x00, 0x00, 0x25, 0x0a, 0x38, 0x00, 0x00, 0xa4, 0x08, 0x80, 0x82, 0xb2,
-	0x00, 0x00, 0x25, 0x0a, 0x04, 0x28, 0x01, 0x04, 0x08, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x08, 0x50, 0x01, 0x04, 0xa8, 0x5b, 0x80, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x08, 0x20, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x0a, 0x0a, 0x08, 0x01, 0x00, 0x28, 0x18, 0xa0, 0x82, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0xe0, 0xa6, 0x20, 0x00, 0x3c,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x00, 0xc0, 0xfb, 0x09, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
-	0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x78, 0x09, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x80, 0x97, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x80, 0x97, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xc0, 0x2c, 0x32,
-	0x00, 0x20, 0x00, 0x80, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0xca, 0x3d, 0x00, 0x0c, 0x07, 0x80, 0x83, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x40, 0x00, 0x32,
-	0x00, 0x00, 0x08, 0x0a, 0x04, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x14, 0x18, 0x40, 0x81, 0x3a,
-	0x00, 0xc0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
-	0x00, 0x00, 0x66, 0x0a, 0x12, 0x01, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x6c, 0x18, 0x20, 0x6e, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x0f, 0x0a, 0x00, 0x38, 0x01, 0xe0, 0x06, 0x40, 0x80, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x6c, 0x18, 0x20, 0x6e, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x11, 0x0a, 0x9f, 0x01, 0x00, 0x04, 0x68, 0x60, 0x80, 0xbc,
-	0x00, 0x00, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x18, 0x18, 0x20, 0x00, 0x9c,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x14, 0x0a, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x00, 0x00, 0xca, 0x70, 0x00, 0x18, 0x08, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x0d, 0x0a, 0x02, 0x01, 0x00, 0x80, 0x62, 0x60, 0x80, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xf8, 0x02, 0x80, 0x2f, 0x35,
-	0x00, 0xa0, 0x0d, 0x0a, 0x12, 0x01, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x1f, 0x0a, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x1f, 0x0a, 0x04, 0x00, 0x00, 0x80, 0xa2, 0xa0, 0x81, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xf8, 0x02, 0x80, 0x2f, 0x35,
-	0x00, 0xa0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0xe8, 0x06, 0x40, 0x81, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0xe0, 0x06, 0x80, 0x82, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xe0, 0x06, 0x80, 0x81, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0xe0, 0x06, 0xc0, 0x86, 0xb2,
-	0x00, 0x00, 0x27, 0x0a, 0x00, 0x18, 0x00, 0xe0, 0x06, 0xc0, 0x84, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0xa3, 0x0e, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xf2,
-	0x00, 0x00, 0x2a, 0x0a, 0x00, 0x50, 0x01, 0x3c, 0xa8, 0x5b, 0x80, 0x9c,
-	0x00, 0x00, 0xa4, 0x07, 0x00, 0x30, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x2f, 0x0a, 0x3e, 0x51, 0x01, 0x00, 0xa8, 0x1b, 0x80, 0xba,
-	0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x00, 0xf8, 0xf2, 0x81, 0x2f, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xec, 0x06, 0xc0, 0xee, 0x32,
-	0x00, 0x00, 0x2f, 0x0a, 0x80, 0x01, 0x00, 0x80, 0x32, 0x80, 0x87, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xe2, 0x80, 0x2f, 0x34,
-	0x00, 0x00, 0x4c, 0x0f, 0x60, 0x30, 0x01, 0xe0, 0x06, 0x00, 0x00, 0xf2,
-	0x00, 0x00, 0x7b, 0x0a, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x3a, 0x0a, 0x04, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0xc9, 0x01, 0x00, 0x14, 0x18, 0x40, 0x81, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0xdf, 0x00, 0x00, 0xa4, 0xa8, 0x60, 0x8a, 0x3c,
-	0x00, 0x00, 0x8a, 0x11, 0x0f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0xc0, 0x3e, 0x0a, 0x12, 0x01, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0xe0, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0xdf, 0x00, 0x00, 0xa4, 0xa8, 0x60, 0x8a, 0x3c,
-	0x00, 0x00, 0x8a, 0x11, 0x0f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0xde, 0xa8, 0x01, 0x20, 0x99, 0x22, 0x6e, 0x3a,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x02, 0x80, 0x82, 0x1b, 0x92, 0xbc,
-	0x00, 0x00, 0x42, 0x0a, 0x2f, 0x20, 0x01, 0xe0, 0x96, 0x22, 0x6e, 0xbc,
-	0x00, 0x00, 0x2f, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0x4a, 0x0a, 0x1f, 0x50, 0x01, 0xe8, 0x06, 0x00, 0x00, 0xb2,
-	0x00, 0x00, 0x45, 0x0a, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x83, 0xbc,
-	0x00, 0x00, 0x4a, 0x0a, 0x00, 0x50, 0x01, 0xe8, 0xf6, 0x60, 0x80, 0x9c,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x78, 0x39, 0x9a, 0xfe, 0x38,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
-	0x08, 0x00, 0x73, 0x11, 0x00, 0x40, 0x02, 0x14, 0x39, 0x9a, 0xfe, 0xd8,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x68, 0x12, 0x9a, 0xfe, 0x38,
-	0x00, 0x00, 0x4f, 0x0a, 0x2a, 0xa9, 0x01, 0xe0, 0x06, 0x00, 0x92, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x1d, 0x00, 0x4f, 0x0a, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
-	0x00, 0x00, 0x4b, 0x0a, 0x04, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
-	0x00, 0x00, 0x52, 0x0a, 0x80, 0x01, 0x00, 0x80, 0x32, 0x80, 0x2f, 0xb6,
-	0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x32,
-	0x00, 0xc0, 0x61, 0x0a, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
-	0x18, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x82, 0xb6,
-	0x00, 0x00, 0x58, 0x0a, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x81, 0xbc,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x18, 0x00, 0x5a, 0x0a, 0x2e, 0x49, 0x01, 0xe0, 0xe6, 0xa0, 0x82, 0xb9,
-	0x00, 0x00, 0x5b, 0x0a, 0x00, 0x5e, 0x01, 0xec, 0x76, 0x00, 0x00, 0x94,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x01, 0xec, 0x06, 0x00, 0x00, 0x32,
-	0x20, 0x80, 0xb0, 0x10, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0xf2,
-	0x1b, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x0c, 0x00, 0xa1, 0x03, 0x04, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x85, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x30, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
-	0x00, 0x00, 0xc2, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0x9e, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x80, 0x85, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2f, 0xb6,
-	0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0xcb, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0x3a,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
-	0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
-	0x00, 0x00, 0x67, 0x0a, 0x0b, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x6e, 0x0a, 0x3d, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x85, 0xb2,
-	0x00, 0x00, 0x6e, 0x0a, 0x34, 0x00, 0x00, 0xf8, 0xd2, 0x81, 0x2f, 0xb5,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb2, 0x80, 0x2f, 0x34,
-	0x00, 0x00, 0xb0, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0x72, 0x0a, 0x80, 0x01, 0x00, 0x80, 0x92, 0x80, 0x2f, 0xb6,
-	0x2a, 0x00, 0x78, 0x0a, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x75, 0x0a, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x78, 0x0a, 0x80, 0x01, 0x00, 0x80, 0x62, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x78, 0x0a, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
-	0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
-	0x00, 0x00, 0xa2, 0x07, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x85, 0xbc,
-	0x00, 0x00, 0xc2, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0x9e, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x80, 0x85, 0x92,
-	0x00, 0x00, 0xa4, 0x07, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x80, 0x0a, 0x80, 0x01, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x31, 0x01, 0x80, 0x02, 0x00, 0x6e, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x31, 0x00, 0x80, 0x82, 0x9b, 0x82, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x12, 0xa0, 0x82, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0xce, 0x01, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x00, 0xc0, 0x86, 0x0a, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
-	0x20, 0x80, 0x9c, 0x10, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0xf2,
-	0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x82, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x82, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x8f, 0x0a, 0x3f, 0x00, 0x00, 0x3c, 0x08, 0x40, 0x80, 0xb2,
-	0x00, 0x00, 0x8f, 0x0a, 0x80, 0x01, 0x00, 0x80, 0xe2, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x00, 0xf8, 0xf2, 0x81, 0x2f, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xec, 0x06, 0xc0, 0xee, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x3e,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
-	0x00, 0x00, 0xda, 0x0a, 0x04, 0x00, 0x00, 0x28, 0xd8, 0xa0, 0x82, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xd8, 0xa0, 0x81, 0x3c,
-	0x00, 0x00, 0xb0, 0x0a, 0x04, 0x00, 0x00, 0x3c, 0xd8, 0xe0, 0x83, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x81, 0xbc,
-	0x00, 0x00, 0x9b, 0x0a, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0x02, 0xc0, 0x38, 0xb2,
-	0x00, 0x00, 0xae, 0x0a, 0x51, 0x00, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x9a,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
-	0x00, 0x00, 0xa7, 0x0a, 0x28, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xb2,
-	0x00, 0x00, 0xa5, 0x0a, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
-	0x00, 0x00, 0xa1, 0x0a, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
-	0x00, 0x00, 0xa5, 0x0a, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
-	0x00, 0x00, 0xa5, 0x0a, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
-	0x00, 0x00, 0xa3, 0x0a, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0xe0, 0x16, 0x20, 0x6e, 0x3c,
-	0x00, 0x00, 0x3c, 0x0e, 0xda, 0x5b, 0x01, 0xec, 0x06, 0x40, 0xed, 0xf2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0xac, 0x0a, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0xa7, 0x0a, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0xaf, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x20, 0x80, 0xfa,
-	0x00, 0x00, 0x90, 0x0a, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x9e,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
-	0x00, 0x00, 0xbc, 0x0a, 0x28, 0x00, 0x00, 0x80, 0x08, 0x40, 0x00, 0xb2,
-	0x00, 0x00, 0xba, 0x0a, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
-	0x00, 0x00, 0xb6, 0x0a, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
-	0x00, 0x00, 0xba, 0x0a, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
-	0x00, 0x00, 0xba, 0x0a, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
-	0x00, 0x00, 0xb8, 0x0a, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0xe0, 0x16, 0x20, 0x6e, 0x3c,
-	0x00, 0x00, 0x3c, 0x0e, 0xda, 0x5b, 0x01, 0xec, 0x06, 0x40, 0xed, 0xf2,
-	0x00, 0x00, 0xe0, 0x0a, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0xc0, 0x0a, 0x04, 0x21, 0x00, 0xe0, 0x06, 0x80, 0x81, 0xb2,
-	0x00, 0x00, 0xaf, 0x0e, 0x00, 0x00, 0x00, 0x34, 0x08, 0x00, 0x00, 0xf2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xe0, 0x06, 0x80, 0x81, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0xe8, 0x06, 0x40, 0x81, 0x32,
-	0x00, 0x00, 0xc6, 0x0a, 0x2a, 0x11, 0x00, 0xe0, 0xd6, 0xe0, 0x86, 0xba,
-	0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x1d, 0x00, 0xc6, 0x0a, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
-	0x00, 0x00, 0xc2, 0x0a, 0x9f, 0x01, 0x00, 0x80, 0x18, 0x00, 0x88, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xb0, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
-	0x08, 0x00, 0xca, 0x0a, 0x23, 0x19, 0x01, 0xe8, 0x76, 0x20, 0x81, 0xb9,
-	0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0xce, 0x0a, 0x1d, 0x18, 0x00, 0xe0, 0x06, 0xc0, 0x84, 0xb2,
-	0x00, 0x00, 0xce, 0x0a, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
-	0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
-	0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
-	0x00, 0x00, 0xd3, 0x0a, 0x04, 0x00, 0x00, 0x80, 0x02, 0x00, 0x88, 0xbc,
-	0x00, 0x00, 0xd2, 0x0a, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x1d, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x80, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
-	0x00, 0x00, 0xa4, 0x03, 0x12, 0x01, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x78, 0x19, 0x20, 0x6e, 0x3c,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xe2, 0xa5, 0x82, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x88, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x80, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
-	0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
-	0x00, 0x00, 0xe4, 0x0a, 0x04, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
-	0x00, 0xc0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
-	0x00, 0x00, 0xe5, 0x0a, 0xc9, 0x01, 0x00, 0x14, 0x08, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x45, 0x30, 0x00, 0xe0, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0xef, 0x0a, 0x28, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xb4,
-	0x00, 0x00, 0xee, 0x0a, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
-	0x00, 0x00, 0xea, 0x0a, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
-	0x00, 0x00, 0xee, 0x0a, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
-	0x00, 0x00, 0xee, 0x0a, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
-	0x00, 0x00, 0xec, 0x0a, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x3c, 0x0e, 0xda, 0x5b, 0x01, 0xec, 0x06, 0x40, 0xed, 0xf2,
-	0x00, 0x20, 0x00, 0x80, 0xdf, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0xf3, 0x0a, 0x3d, 0x01, 0x00, 0xd8, 0x02, 0x80, 0x01, 0xb2,
-	0x00, 0x00, 0xf3, 0x0a, 0x34, 0x00, 0x00, 0xf8, 0xd2, 0x81, 0x2f, 0xb5,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb2, 0x80, 0x2f, 0x34,
-	0x00, 0x00, 0xcb, 0x10, 0x00, 0x00, 0x00, 0xf8, 0xe2, 0x81, 0x2f, 0xf5,
-	0x08, 0x00, 0xb0, 0x10, 0x00, 0x18, 0x01, 0xe8, 0x76, 0x20, 0x81, 0xf9,
-	0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
-	0x00, 0x00, 0xf8, 0x0a, 0x80, 0x01, 0x00, 0x80, 0x32, 0x80, 0x2f, 0xb6,
-	0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0xfd, 0x0a, 0x29, 0x08, 0x01, 0xe4, 0x06, 0xc0, 0x2d, 0xb2,
-	0x00, 0x00, 0x02, 0x0b, 0x1d, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x02, 0x0b, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
-	0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x02, 0x0b, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x94,
-	0x00, 0x00, 0xff, 0x0a, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x1d, 0x00, 0x01, 0x0b, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
-	0x00, 0x00, 0xfe, 0x0a, 0x00, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0x9c,
-	0x2a, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0xc7, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
-	0x00, 0x00, 0x05, 0x0b, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x81, 0xbc,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
-	0x00, 0x00, 0xa4, 0x03, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x82, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x31, 0x00, 0x80, 0x82, 0x9b, 0x82, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x00, 0x00, 0x80, 0x12, 0xa0, 0x82, 0xbc,
-	0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x10, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0xa9, 0x60, 0x80, 0xd9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x00, 0xc0, 0x15, 0x0b, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
-	0x20, 0x80, 0x9c, 0x10, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0xf2,
-	0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa2, 0x8d, 0x2f, 0x31,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x81, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
-	0x00, 0x00, 0x20, 0x0b, 0x80, 0x00, 0x00, 0x80, 0x82, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0xa8, 0x60, 0x80, 0x3c,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x08, 0x40, 0x80, 0x32,
-	0x00, 0x00, 0x3b, 0x0e, 0x00, 0x00, 0x00, 0x04, 0x08, 0x80, 0x82, 0xf2,
-	0x00, 0x00, 0x21, 0x0b, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x20, 0x80, 0x3a,
-	0x00, 0x00, 0x26, 0x0b, 0x04, 0x00, 0x00, 0x28, 0x68, 0xa0, 0x82, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0xaf, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x81, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0xc7, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
-	0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x2e, 0x0b, 0x3d, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x85, 0xb2,
-	0x00, 0x00, 0x2e, 0x0b, 0x34, 0x00, 0x00, 0xf8, 0xd2, 0x81, 0x2f, 0xb5,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb2, 0x80, 0x2f, 0x34,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x04, 0x08, 0x80, 0x86, 0xb2,
-	0x00, 0x00, 0x3c, 0x0b, 0x04, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x28, 0x09, 0x80, 0x80, 0xb2,
-	0x00, 0x00, 0xef, 0x0f, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xd2,
-	0x00, 0x00, 0x34, 0x0b, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x92, 0xbc,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x3a, 0x10, 0x00, 0x00, 0x00, 0x78, 0x38, 0x80, 0x87, 0xf5,
-	0x00, 0x00, 0xb0, 0x10, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0xf2,
-	0x00, 0x00, 0xc2, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
-	0x00, 0x00, 0xa5, 0x02, 0x23, 0x01, 0x00, 0xf8, 0x02, 0x80, 0x2f, 0xb4,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x32, 0x80, 0x2f, 0x35,
-	0x3c, 0x00, 0xa5, 0x02, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x3f, 0x0b, 0x80, 0x01, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x31, 0x01, 0x80, 0x02, 0x00, 0x6e, 0xbc,
-	0x00, 0x00, 0x41, 0x0b, 0x12, 0x01, 0x00, 0x60, 0x08, 0x40, 0x23, 0xb2,
-	0x00, 0x82, 0x4b, 0x0b, 0x00, 0x00, 0x00, 0x08, 0xa8, 0x8d, 0x80, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x24, 0x08, 0x00, 0x23, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x20, 0x08, 0xc0, 0x23, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x18, 0x08, 0x80, 0x23, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x00, 0xc0, 0x5c, 0x0b, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
-	0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xa8, 0x8d, 0x80, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x38, 0x02, 0x80, 0x81, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x3c, 0x02, 0x00, 0x82, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x30, 0x02, 0x40, 0x82, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x34, 0x02, 0x00, 0x86, 0xb2,
-	0x00, 0x00, 0x53, 0x0b, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
-	0x00, 0x00, 0x4f, 0x0b, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
-	0x00, 0x00, 0x53, 0x0b, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
-	0x00, 0x00, 0x53, 0x0b, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
-	0x00, 0x00, 0x51, 0x0b, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x80, 0xd2,
-	0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0xc0, 0xf5, 0x3a,
-	0x00, 0x00, 0xa4, 0x07, 0x00, 0x30, 0x00, 0xe0, 0x06, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x40, 0x80, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x40, 0x82, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x86, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
-	0x00, 0x00, 0x39, 0x10, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0xf2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x80, 0x81, 0x32,
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x17, 0xe0, 0x2c, 0x39,
-	0x00, 0x10, 0x00, 0x80, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0xb0, 0x10, 0x00, 0x30, 0x00, 0xe0, 0x06, 0x00, 0x00, 0xf2,
-	0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
-	0x00, 0x00, 0x6a, 0x0b, 0x80, 0x01, 0x00, 0x80, 0x32, 0x80, 0x2f, 0xb6,
-	0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0xc3, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0x6e, 0x0b, 0x1d, 0x21, 0x00, 0x00, 0x07, 0x00, 0x82, 0xb2,
-	0x00, 0x00, 0x71, 0x0b, 0x80, 0x01, 0x00, 0x80, 0x62, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x71, 0x0b, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
-	0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
-	0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
-	0x00, 0x00, 0x74, 0x0b, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
-	0x00, 0x00, 0xa4, 0x03, 0xca, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x92,
-	0x00, 0x00, 0x7e, 0x0b, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
-	0x00, 0x00, 0x7a, 0x0b, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
-	0x00, 0x00, 0x7e, 0x0b, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
-	0x00, 0x00, 0x7e, 0x0b, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
-	0x00, 0x00, 0x7c, 0x0b, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x80, 0x0b, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x86, 0xbc,
-	0x00, 0x00, 0x0a, 0x11, 0x00, 0x90, 0x01, 0x08, 0x09, 0x00, 0x6e, 0xf2,
-	0x00, 0x00, 0x3f, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0x87, 0x0b, 0x33, 0x01, 0x00, 0xd8, 0x02, 0x80, 0x01, 0xb2,
-	0x00, 0x00, 0x87, 0x0b, 0x80, 0x01, 0x00, 0x80, 0xb2, 0x01, 0x72, 0xb6,
-	0x00, 0x00, 0x87, 0x0b, 0x9f, 0xf0, 0x01, 0x80, 0x82, 0xdb, 0x87, 0xbc,
-	0x00, 0x00, 0x87, 0x0b, 0x9f, 0xf8, 0x01, 0x80, 0x22, 0x21, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x01, 0xe0, 0x06, 0x00, 0xee, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0xe0, 0x06, 0xc0, 0x87, 0x32,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 0xe8, 0x76, 0x20, 0x81, 0x39,
-	0x00, 0x00, 0x8d, 0x0b, 0x80, 0x01, 0x00, 0x80, 0xd2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x8d, 0x0b, 0x04, 0xb0, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0xcd, 0x00, 0x00, 0xf8, 0x72, 0x81, 0x2f, 0x34,
-	0x3b, 0x00, 0x8d, 0x0b, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x9d, 0x0b, 0x27, 0x09, 0x01, 0xe4, 0x06, 0xc0, 0x2d, 0xb2,
-	0x00, 0xc0, 0x95, 0x0b, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
-	0x20, 0x80, 0xa4, 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x92,
-	0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x98, 0x01, 0x14, 0x09, 0x00, 0x6e, 0xd2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0xe0, 0x06, 0x40, 0x88, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0xd5, 0x08, 0x00, 0x00, 0x07, 0x40, 0x88, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xc0, 0x2c, 0x32,
-	0x00, 0x40, 0x00, 0x80, 0xca, 0x39, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0x34,
-	0x00, 0x00, 0xa1, 0x0b, 0x1d, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0xa1, 0x0b, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
-	0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
-	0x00, 0x00, 0xc7, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
-	0x00, 0x00, 0xa4, 0x03, 0x12, 0x01, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x00, 0xc0, 0xae, 0x0b, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
-	0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
-	0x00, 0x00, 0xa1, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x72, 0xe0, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0xee, 0x10, 0x00, 0x20, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xf2,
-	0x00, 0x00, 0x8a, 0x11, 0x1f, 0x30, 0x00, 0x28, 0x08, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x08, 0x80, 0x82, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0xa3, 0x0e, 0x00, 0x18, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0xf2,
-	0x00, 0x00, 0xb6, 0x0b, 0x00, 0x50, 0x01, 0x3c, 0xa8, 0x5b, 0x80, 0x9c,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0x00, 0xa8, 0x1b, 0x80, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x3e,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
-	0x00, 0x00, 0xee, 0x0b, 0x04, 0x00, 0x00, 0x28, 0xd8, 0xa0, 0x82, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xd8, 0xa0, 0x81, 0x3c,
-	0x00, 0x00, 0xd4, 0x0b, 0x04, 0x00, 0x00, 0x3c, 0xd8, 0xe0, 0x83, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x81, 0xbc,
-	0x00, 0x00, 0xc5, 0x0b, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0x02, 0xc0, 0x38, 0xb2,
-	0x00, 0x00, 0xcd, 0x0b, 0x51, 0x00, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x9a,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0xcb, 0x0b, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0xc6, 0x0b, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0xd2, 0x0b, 0x2a, 0x01, 0x00, 0x00, 0xd8, 0x20, 0x80, 0xba,
-	0x00, 0x00, 0xd1, 0x0b, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x32,
-	0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
-	0x00, 0x00, 0xb7, 0x0e, 0x00, 0x60, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xf2,
-	0x00, 0x00, 0xba, 0x0b, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x9e,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x1d, 0x00, 0xdb, 0x0b, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0xd5, 0x0b, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
-	0x1d, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x78, 0x39, 0x9a, 0xfe, 0x38,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
-	0x08, 0x00, 0x73, 0x11, 0x00, 0x40, 0x02, 0x14, 0x39, 0x9a, 0xfe, 0xd8,
-	0x08, 0x00, 0x8a, 0x11, 0x12, 0x40, 0x02, 0x68, 0x12, 0x9a, 0xfe, 0xb8,
-	0x00, 0x00, 0x8a, 0x11, 0x0b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
-	0x00, 0x00, 0x8a, 0x11, 0x1f, 0x00, 0x00, 0x6c, 0xd8, 0xe0, 0x86, 0xba,
-	0x00, 0x00, 0xa3, 0x0e, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xf2,
-	0x00, 0x00, 0xe6, 0x0b, 0x00, 0x00, 0x00, 0x3c, 0x08, 0x40, 0x80, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xb9, 0x0b, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x81, 0xbc,
-	0x00, 0x00, 0xec, 0x0b, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0xeb, 0x0b, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x32,
-	0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
-	0x00, 0x00, 0xb7, 0x0e, 0x00, 0x60, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xf2,
-	0x00, 0x00, 0xba, 0x0b, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x9e,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x45, 0x30, 0x00, 0xe0, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
-	0x00, 0x00, 0xf6, 0x0b, 0x04, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0xc9, 0x01, 0x00, 0x14, 0x18, 0x40, 0x81, 0x3a,
-	0x00, 0xc0, 0xf7, 0x0b, 0x12, 0x01, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0x20, 0x99, 0x22, 0x6e, 0x3a,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x02, 0x80, 0x82, 0x1b, 0x92, 0xbc,
-	0x00, 0x00, 0xfb, 0x0b, 0x2f, 0x20, 0x01, 0xe0, 0x96, 0x22, 0x6e, 0xbc,
-	0x00, 0x00, 0x2f, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0xff, 0x0b, 0x04, 0x00, 0x00, 0x3c, 0xd8, 0xe0, 0x83, 0xbc,
-	0x00, 0x00, 0xfe, 0x0b, 0x9f, 0x31, 0x01, 0xe0, 0x96, 0x22, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x07, 0x0c, 0x00, 0x50, 0x01, 0xe8, 0xf6, 0x60, 0x80, 0x9c,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x78, 0x39, 0x9a, 0xfe, 0x38,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
-	0x08, 0x00, 0x73, 0x11, 0x00, 0x40, 0x02, 0x14, 0x39, 0x9a, 0xfe, 0xd8,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x68, 0x12, 0x9a, 0xfe, 0x38,
-	0x00, 0x00, 0x06, 0x0c, 0x9f, 0x31, 0x01, 0xe0, 0x96, 0x22, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0xe0, 0x06, 0x00, 0x92, 0x32,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x1d, 0x00, 0x0c, 0x0c, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
-	0x00, 0x00, 0x08, 0x0c, 0x04, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0xcb, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
-	0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
-	0x00, 0x00, 0x14, 0x0c, 0x23, 0x01, 0x00, 0x14, 0x18, 0x40, 0x81, 0xba,
-	0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
-	0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
-	0x00, 0x00, 0x15, 0x0c, 0x0b, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x1c, 0x0c, 0x3d, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x85, 0xb2,
-	0x00, 0x00, 0x1c, 0x0c, 0x34, 0x00, 0x00, 0xf8, 0xd2, 0x81, 0x2f, 0xb5,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb2, 0x80, 0x2f, 0x34,
-	0x00, 0x00, 0xb0, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0x20, 0x0c, 0x29, 0x31, 0x01, 0x0c, 0x09, 0x00, 0x6e, 0xb2,
-	0x2a, 0x00, 0xa2, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x27, 0x0e, 0x00, 0x0c, 0x02, 0x00, 0x09, 0x80, 0x6e, 0xf2,
-	0x00, 0x00, 0x24, 0x0c, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa2, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x02, 0xe4, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x27, 0x0c, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0xa2, 0x07, 0x80, 0x01, 0x00, 0x80, 0x62, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa2, 0x07, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
-	0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x94,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x18, 0x09, 0x40, 0x81, 0xb2,
-	0x00, 0x00, 0x4f, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0x2f, 0x0e, 0x00, 0xa8, 0x01, 0x20, 0x09, 0x00, 0x6e, 0xf2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0x0c, 0x09, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x27, 0x0e, 0x00, 0x0c, 0x02, 0x00, 0x09, 0x80, 0x6e, 0xf2,
-	0x00, 0x00, 0xa4, 0x07, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xb0, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0xc2, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x90, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x1f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x78, 0x0b, 0x16, 0x38,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x78, 0x0b, 0x16, 0x38,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xa8, 0x00, 0x2d, 0x37,
-	0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x88, 0x0d, 0x8b, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0xb4, 0x08, 0x80, 0x6e, 0x32,
-	0x00, 0x00, 0x45, 0x0c, 0x04, 0x31, 0x01, 0x90, 0x08, 0x00, 0x6e, 0xb2,
-	0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x82, 0x8d, 0x8a, 0x37,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc2, 0xa2, 0x2c, 0x3a,
-	0x18, 0x00, 0x43, 0x0c, 0x86, 0x41, 0x02, 0x78, 0x88, 0x0d, 0x78, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0xa2, 0xe2, 0x8a, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x41, 0x02, 0x80, 0xb2, 0x3f, 0x78, 0xb0,
-	0x00, 0x00, 0x3c, 0x0c, 0x9f, 0x01, 0x00, 0xa8, 0x18, 0x80, 0x8a, 0xbc,
-	0xb7, 0x00, 0x3c, 0x0c, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x04, 0xb8, 0x3f, 0x78, 0x30,
-	0x00, 0x00, 0x58, 0x0c, 0x00, 0x00, 0x00, 0x04, 0xd8, 0x62, 0x80, 0x9c,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x0c, 0x02, 0x80, 0xa2, 0x1b, 0x89, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x82, 0x80, 0x2f, 0xb6,
-	0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x82, 0x8d, 0x8a, 0x37,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc2, 0xa2, 0x2c, 0x3a,
-	0x18, 0x00, 0x4e, 0x0c, 0x86, 0x41, 0x02, 0x78, 0x88, 0x0d, 0x78, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0xa2, 0xe2, 0x8a, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x41, 0x02, 0x80, 0xb2, 0x3f, 0x78, 0xb0,
-	0x00, 0x00, 0x47, 0x0c, 0x9f, 0x01, 0x00, 0xa8, 0x18, 0x80, 0x8a, 0xbc,
-	0xb7, 0x00, 0x47, 0x0c, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x51, 0x0c, 0x28, 0x40, 0x02, 0x04, 0xb8, 0x3f, 0x78, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00, 0x04, 0xd8, 0x62, 0x80, 0x3c,
-	0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x40, 0x80, 0xb2,
-	0x00, 0x00, 0x55, 0x0c, 0x02, 0x01, 0x00, 0x90, 0x18, 0x20, 0x89, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x08, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x47, 0x0c, 0x9f, 0x01, 0x00, 0xa8, 0x18, 0x80, 0x8a, 0xbc,
-	0xb7, 0x00, 0x47, 0x0c, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x58, 0x0c, 0x04, 0x00, 0x00, 0x90, 0x18, 0x20, 0x89, 0xba,
-	0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x04, 0x48, 0x62, 0x80, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x90, 0x00, 0x00, 0xb4, 0x48, 0x62, 0x8b, 0xba,
-	0x03, 0x00, 0x8a, 0x11, 0x04, 0x40, 0x02, 0x00, 0x08, 0x1e, 0xff, 0xb8,
-	0x00, 0x00, 0x60, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x22, 0x80, 0x9a,
-	0x00, 0x00, 0x89, 0x0c, 0x04, 0x00, 0x00, 0x80, 0xa2, 0xe2, 0x8a, 0xbc,
-	0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x82, 0x8d, 0x8a, 0x37,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc2, 0xa2, 0x2c, 0x3a,
-	0x18, 0x00, 0x87, 0x0c, 0x86, 0x40, 0x02, 0x78, 0x88, 0x0d, 0x78, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x40, 0x02, 0x04, 0xb8, 0x3f, 0x78, 0xb0,
-	0x03, 0x00, 0x8a, 0x11, 0x04, 0x40, 0x02, 0x00, 0x08, 0x1e, 0xff, 0xb8,
-	0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x80, 0xd2,
-	0x00, 0x00, 0x67, 0x0c, 0x12, 0x01, 0x00, 0x60, 0x08, 0x40, 0x23, 0xb2,
-	0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
-	0x00, 0x00, 0xa1, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x72, 0xe0, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x24, 0x08, 0x00, 0x23, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x20, 0x08, 0xc0, 0x23, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x18, 0x08, 0x80, 0x23, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x00, 0xc0, 0x72, 0x0c, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x38, 0x02, 0x80, 0x81, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x3c, 0x02, 0x00, 0x82, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x30, 0x02, 0x40, 0x82, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x34, 0x02, 0x00, 0x86, 0xb2,
-	0x20, 0x80, 0x64, 0x0c, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0x00, 0xb8, 0x1b, 0x80, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x64, 0x30, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x40, 0x80, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x40, 0x82, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x86, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x80, 0x81, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x07, 0x00, 0x82, 0x32,
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x17, 0xe0, 0x2c, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xf7, 0x01, 0x0b, 0x34,
-	0x00, 0x00, 0x81, 0x0c, 0x80, 0x01, 0x00, 0x80, 0x32, 0x80, 0x87, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xb7, 0x01, 0x70, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0x34,
-	0x00, 0x00, 0x93, 0x0c, 0x02, 0x0c, 0x02, 0x80, 0xa2, 0x1b, 0x89, 0xbc,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x5a, 0x0c, 0x9f, 0x01, 0x00, 0xa8, 0x18, 0x80, 0x8a, 0xbc,
-	0xb7, 0x00, 0x5a, 0x0c, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x36, 0x92,
-	0x27, 0x00, 0x8c, 0x0c, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0x81, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x78, 0x09, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x42, 0xa2, 0x97, 0xbc,
-	0x00, 0x00, 0x8e, 0x0c, 0x23, 0x55, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0xb2,
-	0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x90, 0x0c, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
-	0x00, 0x00, 0xa2, 0x07, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
-	0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x94,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xc7, 0x01, 0x70, 0x34,
-	0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
-	0x08, 0x00, 0x97, 0x0c, 0x23, 0x19, 0x01, 0xe8, 0x76, 0x20, 0x81, 0xb9,
-	0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x99, 0x0c, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x9c, 0x0c, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
-	0x00, 0x00, 0x9c, 0x0c, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
-	0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
-	0x00, 0x00, 0xa0, 0x0c, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
-	0x00, 0x00, 0xa4, 0x03, 0xca, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x28, 0x08, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
-	0x00, 0xc0, 0xad, 0x0c, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
-	0x18, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x82, 0xb6,
-	0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x01, 0xec, 0x66, 0x00, 0x00, 0x34,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x48, 0x01, 0xe0, 0xe6, 0xa0, 0x82, 0x39,
-	0x1b, 0x00, 0xa1, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x20, 0x00, 0x84, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0xc7, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
-	0x00, 0xc0, 0xb6, 0x0c, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
-	0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
-	0x00, 0x00, 0x9d, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x72, 0xe0, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x58, 0x10, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x02, 0xf2,
-	0x00, 0x00, 0xbd, 0x0c, 0x00, 0x00, 0x00, 0x5c, 0x08, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
-	0x00, 0xc0, 0xbd, 0x0c, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
-	0x20, 0x80, 0x9c, 0x10, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0xf2,
-	0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x28, 0x08, 0x00, 0x6e, 0x32,
-	0x00, 0x20, 0x00, 0x84, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0xc7, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
-	0x00, 0x00, 0xc2, 0x0c, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0xc6, 0x0c, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x85, 0xb2,
-	0x00, 0x00, 0xc6, 0x0c, 0x80, 0x00, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0xd2, 0x41, 0x02, 0x80, 0x06, 0xc0, 0x85, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x1c, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x4c, 0x0d, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x4c, 0x0d, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x92,
-	0x00, 0x00, 0x1a, 0x0d, 0x80, 0x01, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x22, 0x0d, 0x1f, 0x20, 0x01, 0x08, 0x09, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x1a, 0x0d, 0x04, 0x30, 0x01, 0x08, 0x89, 0x9b, 0x90, 0xbc,
-	0x00, 0x00, 0xd2, 0x0c, 0x04, 0x31, 0x01, 0x80, 0x02, 0x00, 0x6e, 0xbc,
-	0x00, 0x00, 0xa3, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0xd0, 0x0c, 0x00, 0x50, 0x01, 0x48, 0x08, 0x80, 0x6e, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x28, 0x61, 0x80, 0x3c,
-	0x00, 0x00, 0xeb, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x28, 0x21, 0x80, 0x9a,
-	0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x80, 0x90, 0xb2,
-	0x00, 0x00, 0xa3, 0x0e, 0x00, 0x30, 0x01, 0x48, 0x08, 0x00, 0x6e, 0xf2,
-	0x00, 0x00, 0xd6, 0x0c, 0x00, 0x50, 0x01, 0x04, 0xa8, 0x5b, 0x80, 0x9c,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0x00, 0xa8, 0x1b, 0x80, 0x3a,
-	0x00, 0x00, 0xe8, 0x0c, 0x07, 0x00, 0x00, 0x48, 0x18, 0xa0, 0x84, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
-	0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xa0, 0xfe, 0x38,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
-	0x05, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xa0, 0xfe, 0xd8,
-	0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x02, 0xa0, 0xfe, 0x38,
-	0x00, 0x00, 0xa3, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0xe1, 0x0c, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xe8, 0x0c, 0x07, 0x00, 0x00, 0x48, 0x18, 0xa0, 0x84, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
-	0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xa0, 0xfe, 0x38,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
-	0x05, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xa0, 0xfe, 0xd8,
-	0x05, 0x00, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x68, 0x02, 0xa0, 0xfe, 0x98,
-	0x00, 0x00, 0xeb, 0x0c, 0x04, 0x00, 0x00, 0x48, 0x18, 0xa0, 0x84, 0xba,
-	0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x04, 0x28, 0x61, 0x80, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x21, 0x80, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
-	0x00, 0x00, 0xf4, 0x0c, 0x12, 0x01, 0x00, 0x60, 0x08, 0x40, 0x23, 0xb2,
-	0x03, 0x00, 0x8a, 0x11, 0x04, 0x40, 0x02, 0x00, 0x38, 0x1a, 0xff, 0xb8,
-	0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x60, 0x80, 0x39,
-	0x18, 0x00, 0x00, 0x00, 0xd2, 0x41, 0x02, 0x8c, 0xe6, 0xa1, 0x97, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0xe8, 0x06, 0x80, 0x84, 0x32,
-	0x00, 0x82, 0x00, 0x00, 0xd6, 0x01, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
-	0x28, 0x00, 0xa1, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x24, 0x08, 0x00, 0x23, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x20, 0x08, 0xc0, 0x23, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x18, 0x08, 0x80, 0x23, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x00, 0xc0, 0xfe, 0x0c, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x38, 0x02, 0x80, 0x81, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x3c, 0x02, 0x00, 0x82, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x30, 0x02, 0x40, 0x82, 0xb2,
-	0x00, 0x00, 0xed, 0x0c, 0x12, 0x01, 0x00, 0x34, 0x02, 0x00, 0x86, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x08, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x40, 0x80, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x40, 0x82, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x86, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
-	0x00, 0x00, 0x00, 0x00, 0xd6, 0x01, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x80, 0x81, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x07, 0x00, 0x82, 0x32,
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x17, 0xe0, 0x2c, 0x39,
-	0x00, 0x00, 0x0d, 0x0d, 0x80, 0x00, 0x00, 0x80, 0x32, 0x80, 0x87, 0xb6,
-	0x00, 0x10, 0x00, 0x80, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x0e, 0x0d, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x10, 0x00, 0x88, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x05, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xa0, 0xfe, 0xd8,
-	0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x02, 0xa0, 0xfe, 0x38,
-	0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xa0, 0xfe, 0x38,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0x34,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0xa3, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0xeb, 0x0c, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x22, 0x0d, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa3, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x05, 0x00, 0x1d, 0x0d, 0x00, 0x00, 0x00, 0x68, 0x02, 0xa0, 0xfe, 0x98,
-	0x00, 0x00, 0x22, 0x0d, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x05, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xa0, 0xfe, 0xd8,
-	0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xa0, 0xfe, 0x38,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x1a, 0x0d, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
-	0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x00, 0x2d, 0x37,
-	0xb4, 0xcc, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x97, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x99, 0xc0, 0x2c, 0x37,
-	0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0x8d, 0x97, 0x3a,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x10, 0x00, 0x00, 0x87, 0xbf, 0x97, 0xba,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x40, 0xfe, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0xf2, 0xc1, 0x38, 0xb4,
-	0x00, 0x00, 0x2b, 0x0d, 0xb6, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x20, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x64, 0xa2, 0xcd, 0x2c, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
-	0x00, 0x00, 0x30, 0x0d, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0xa2, 0x07, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x62, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x1f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
-	0x00, 0x00, 0x39, 0x0d, 0x12, 0x01, 0x00, 0x60, 0x08, 0x40, 0x23, 0xb2,
-	0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
-	0x28, 0x00, 0xa1, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x24, 0x08, 0x00, 0x23, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x20, 0x08, 0xc0, 0x23, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x18, 0x08, 0x80, 0x23, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x00, 0xc0, 0x43, 0x0d, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x38, 0x02, 0x80, 0x81, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x3c, 0x02, 0x00, 0x82, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x30, 0x02, 0x40, 0x82, 0xb2,
-	0x00, 0x00, 0xed, 0x0c, 0x12, 0x01, 0x00, 0x34, 0x02, 0x00, 0x86, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa3, 0x0e, 0x00, 0x00, 0x00, 0x48, 0x08, 0x00, 0x00, 0xf2,
-	0x00, 0x00, 0x46, 0x0d, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x0d, 0x00, 0x50, 0x01, 0x00, 0xa8, 0x1b, 0x80, 0x9a,
-	0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
-	0x00, 0x00, 0x58, 0x10, 0x00, 0x00, 0x00, 0x28, 0x09, 0x80, 0x02, 0xf2,
-	0x00, 0x00, 0x2b, 0x0d, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x58, 0x10, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x02, 0xf2,
-	0x00, 0x00, 0x4f, 0x0d, 0x9a, 0x01, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0xb4,
-	0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa2, 0x8d, 0x2f, 0x31,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x01, 0xec, 0x06, 0xc0, 0x6e, 0x34,
-	0x2d, 0x00, 0xa2, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0xa9, 0x01, 0x80, 0x02, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x5a, 0x0d, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
-	0x00, 0x00, 0x56, 0x0d, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
-	0x00, 0x00, 0x5a, 0x0d, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
-	0x00, 0x00, 0x5a, 0x0d, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
-	0x00, 0x00, 0x58, 0x0d, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x5c, 0x0d, 0x04, 0x98, 0x01, 0x64, 0x88, 0x1b, 0x87, 0xbc,
-	0x00, 0x00, 0x0a, 0x11, 0x00, 0x90, 0x01, 0x08, 0x09, 0x80, 0x6e, 0xf2,
-	0x00, 0x00, 0x3f, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
-	0x30, 0x00, 0xa4, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x6c, 0x0d, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
-	0x00, 0x00, 0x68, 0x0d, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
-	0x00, 0x00, 0x6c, 0x0d, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
-	0x00, 0x00, 0x6c, 0x0d, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
-	0x00, 0x00, 0x6a, 0x0d, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
-	0x00, 0x00, 0xa4, 0x07, 0x04, 0xb0, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
-	0x36, 0x00, 0xa4, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x7d, 0x0d, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
-	0x00, 0x00, 0x79, 0x0d, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
-	0x00, 0x00, 0x7d, 0x0d, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
-	0x00, 0x00, 0x7d, 0x0d, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
-	0x00, 0x00, 0x7b, 0x0d, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x88, 0x0d, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x86, 0x0d, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
-	0x00, 0x00, 0x82, 0x0d, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
-	0x00, 0x00, 0x86, 0x0d, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
-	0x00, 0x00, 0x86, 0x0d, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
-	0x00, 0x00, 0x84, 0x0d, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x30, 0x00, 0x88, 0x0d, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0xd4, 0xd5, 0x01, 0xec, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
-	0x00, 0x00, 0xa4, 0x07, 0x12, 0x01, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xa2, 0x07, 0x80, 0x01, 0x00, 0x80, 0xf2, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0xa2, 0x07, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x93, 0x0d, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x58, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
-	0x00, 0x00, 0xa2, 0x07, 0x08, 0x59, 0x01, 0xec, 0x06, 0xfb, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
-	0x00, 0xc0, 0x9c, 0x0d, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xec, 0x06, 0xfb, 0x6e, 0x3a,
-	0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
-	0x00, 0x00, 0x9d, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x72, 0xe0, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xc2, 0x10, 0x00, 0x00, 0x00, 0xf8, 0xe2, 0x81, 0x2f, 0xf4,
-	0x00, 0x00, 0x9f, 0x0d, 0x06, 0x03, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
-	0x18, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x19, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xf2, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xe2, 0x81, 0x2f, 0xb6,
-	0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa2, 0x8d, 0x2f, 0x31,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x00, 0x20, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x28, 0x08, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x45, 0x30, 0x00, 0xe0, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0xc7, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
-	0x00, 0x00, 0xad, 0x0d, 0x04, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0xc9, 0x01, 0x00, 0x14, 0x18, 0x40, 0x81, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x80, 0x2f, 0x34,
-	0x00, 0xc0, 0xad, 0x0d, 0x12, 0x01, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0xad, 0x0d, 0x9f, 0x01, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
-	0x00, 0x00, 0xb2, 0x0d, 0x3d, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x85, 0xb2,
-	0x00, 0x00, 0xb2, 0x0d, 0x34, 0x00, 0x00, 0xf8, 0xd2, 0x81, 0x2f, 0xb5,
-	0x34, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0xa4, 0x07, 0x80, 0x01, 0x00, 0x80, 0x92, 0x80, 0x2f, 0xb6,
-	0x2a, 0x00, 0xa4, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x00, 0xc0, 0xbc, 0x0d, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
-	0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
-	0x00, 0x00, 0x9d, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x72, 0xe0, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x20, 0x00, 0x80, 0xdf, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x48, 0x01, 0x38, 0x88, 0x1b, 0x16, 0x38,
-	0x00, 0x00, 0x00, 0x00, 0xde, 0x48, 0x01, 0x28, 0x88, 0x04, 0x6e, 0x30,
-	0x00, 0x00, 0xc1, 0x0d, 0x80, 0x5f, 0x01, 0x80, 0x72, 0xc0, 0x6e, 0xb6,
-	0x00, 0x00, 0xc3, 0x0d, 0x00, 0x00, 0x00, 0xf8, 0xe2, 0x80, 0x2f, 0x94,
-	0x00, 0x00, 0xc3, 0x0d, 0x80, 0x5f, 0x01, 0x80, 0x62, 0xc0, 0x6e, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xa9, 0x81, 0x92, 0x34,
-	0x00, 0x00, 0xcb, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
-	0x00, 0x00, 0xc6, 0x0d, 0x12, 0x01, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xc9, 0x0d, 0x80, 0x01, 0x00, 0x80, 0xd2, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0xc9, 0x0d, 0x34, 0x00, 0x00, 0xf8, 0xd2, 0x81, 0x2f, 0xb5,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb2, 0x80, 0x2f, 0x34,
-	0x00, 0x00, 0xa4, 0x07, 0x04, 0x30, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
-	0x2a, 0x00, 0xa4, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0xd8, 0x02, 0x80, 0x01, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
-	0x00, 0xc0, 0xd2, 0x0d, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
-	0x00, 0x82, 0x00, 0x00, 0xd6, 0x01, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
-	0x1d, 0x00, 0xa1, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xc2, 0x10, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0xf2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x01, 0x78, 0x09, 0xc0, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xc0, 0x2c, 0x32,
-	0x00, 0x10, 0x00, 0xa0, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x07, 0x00, 0xee, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x0c, 0x07, 0x80, 0x97, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
-	0x00, 0xf0, 0xe1, 0x0d, 0x1d, 0x40, 0x02, 0x00, 0xa8, 0x0d, 0x68, 0xb1,
-	0x00, 0x00, 0x8a, 0x11, 0x0b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x8a, 0x11, 0x1e, 0x40, 0x02, 0x84, 0x06, 0x00, 0x00, 0xb2,
-	0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x05, 0x80, 0xd0,
-	0x00, 0x00, 0xde, 0x0d, 0xb6, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0xc0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x64, 0xa2, 0x0d, 0x80, 0xb2,
-	0x00, 0x00, 0xda, 0x0d, 0xa6, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xe1, 0x0d, 0xb5, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x80, 0xa0, 0x36, 0x0b, 0x6a, 0x35,
-	0x00, 0x00, 0xe6, 0x0d, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x80, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xe9, 0x01, 0x00, 0x34,
-	0x00, 0x00, 0xef, 0x0f, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xd2,
-	0x00, 0x00, 0xeb, 0x0d, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x92, 0xbc,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x39, 0x0b, 0x2e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xf3, 0x81, 0x97, 0x34,
-	0x00, 0x00, 0xf1, 0x0d, 0x04, 0x00, 0x00, 0x78, 0xd9, 0x01, 0x30, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x05, 0x30, 0x30,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0xa4, 0x03, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x33, 0x0b, 0x2f, 0x32,
-	0x00, 0x00, 0xa4, 0x03, 0x04, 0x00, 0x00, 0x78, 0xd9, 0x01, 0x30, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xb9, 0x05, 0x30, 0x30,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x00, 0x00, 0x32,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x02, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x80, 0x97, 0x32,
-	0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc0, 0x29, 0xd2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0xff, 0x0d, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x2f, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x00, 0x2c, 0x32,
-	0xd9, 0x02, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x82, 0x8d, 0x97, 0xbc,
-	0x46, 0x03, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x82, 0x8d, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0xf1, 0x0d, 0x00, 0x00, 0x00, 0xf4, 0x02, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x18, 0x0e, 0x02, 0x00, 0x00, 0x80, 0xa2, 0x42, 0x80, 0xbc,
-	0x00, 0x00, 0x18, 0x0e, 0x80, 0x00, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
-	0x00, 0x00, 0x18, 0x0e, 0x1f, 0x40, 0x02, 0x08, 0xb9, 0xbf, 0x68, 0xb0,
-	0x00, 0x00, 0x08, 0x0e, 0x80, 0x41, 0x02, 0x80, 0xe2, 0x81, 0x68, 0xb6,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x79, 0x61, 0x80, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0xd2, 0x21, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0x3a,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x41, 0x02, 0x88, 0xe6, 0x21, 0x91, 0x79,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x19, 0xa0, 0x90, 0x3a,
-	0x00, 0x00, 0x18, 0x0e, 0x06, 0x01, 0x00, 0x80, 0xd2, 0xff, 0x90, 0xbc,
-	0x00, 0x00, 0x0c, 0x0e, 0x2c, 0x41, 0x02, 0x78, 0xf9, 0x81, 0x68, 0xb4,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xb9, 0x81, 0x97, 0x34,
-	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x59, 0xc0, 0x85, 0xd7,
-	0x03, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x29, 0x1a, 0xff, 0x38,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0x00, 0xb9, 0x1b, 0x90, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0xd2, 0x41, 0x02, 0x88, 0x16, 0xa0, 0x97, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x40, 0x80, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x27, 0x24, 0x90, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x00, 0x8a, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x58, 0xf2, 0xc1, 0x38, 0x74,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x08, 0x00, 0x23, 0x0e, 0x1e, 0x01, 0x00, 0x34, 0x79, 0x61, 0x80, 0xb9,
-	0x00, 0x00, 0x8a, 0x11, 0x38, 0x00, 0x00, 0x54, 0x1f, 0x40, 0xf5, 0xba,
-	0x00, 0x00, 0x8a, 0x11, 0x1f, 0x40, 0x02, 0x00, 0x09, 0x40, 0x68, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xb9, 0x3f, 0x90, 0x30,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0xe0, 0x26, 0x24, 0x6e, 0x3a,
-	0x08, 0x00, 0x8a, 0x11, 0x1e, 0x00, 0x00, 0x00, 0x09, 0xa4, 0xfe, 0xb8,
-	0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x05, 0x90, 0xd0,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0x05, 0x90, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x05, 0x90, 0x30,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0xd2, 0x21, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0x3a,
-	0x18, 0x00, 0x00, 0x00, 0x1e, 0x41, 0x02, 0x84, 0xe6, 0x61, 0x93, 0x79,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x01, 0x80, 0x82, 0xdb, 0x90, 0x7c,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x20, 0x01, 0x80, 0x02, 0x00, 0x6e, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x1f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x02, 0x0c, 0x02, 0x80, 0xa2, 0xdb, 0x90, 0x7c,
-	0x00, 0x00, 0x2d, 0x0e, 0x06, 0x21, 0x01, 0x80, 0x82, 0x1b, 0x90, 0xbc,
-	0x26, 0x00, 0x2e, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x36, 0x92,
-	0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x12, 0x00, 0x2c, 0x3a,
-	0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x92, 0xd2,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x00, 0x92, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x2f, 0xa0, 0x01, 0x78, 0x89, 0x1b, 0x92, 0x7a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x01, 0x78, 0x89, 0x9b, 0x97, 0x3c,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x00, 0xf9, 0xba, 0x6e, 0x37,
-	0x00, 0x00, 0x39, 0x0e, 0x02, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x97, 0xbc,
-	0x00, 0x00, 0x39, 0x0e, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0x8d, 0x97, 0x37,
-	0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x02, 0x80, 0x82, 0x9b, 0x97, 0x7c,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0xf2, 0x80, 0x2f, 0x74,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0xda, 0x5b, 0x01, 0xec, 0x06, 0x40, 0xed, 0x32,
-	0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x40, 0x89, 0xd2,
-	0x00, 0x00, 0x42, 0x0e, 0x08, 0x5d, 0x01, 0xec, 0x16, 0x40, 0x89, 0xbc,
-	0x00, 0x00, 0x42, 0x0e, 0x0b, 0x5d, 0x01, 0xec, 0x06, 0x00, 0x00, 0xb2,
-	0x00, 0x00, 0x42, 0x0e, 0x80, 0x00, 0x00, 0x80, 0x42, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb2, 0x80, 0x2f, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x01, 0x78, 0x89, 0x1b, 0x87, 0x3c,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x92, 0xa1, 0x97, 0xbc,
-	0x00, 0x00, 0x47, 0x0e, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x86, 0xbc,
-	0x00, 0x00, 0x0a, 0x11, 0x00, 0x90, 0x01, 0x08, 0x09, 0x00, 0x6e, 0xf2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0x3a,
-	0x00, 0x00, 0x3f, 0x11, 0x33, 0x01, 0x00, 0xf8, 0x82, 0x80, 0x2f, 0xb4,
-	0x00, 0x00, 0x3f, 0x11, 0x9f, 0xf0, 0x01, 0x80, 0x82, 0xdb, 0x87, 0xbc,
-	0x00, 0x00, 0x3f, 0x11, 0x9f, 0xf8, 0x01, 0x80, 0x22, 0x21, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x01, 0xe0, 0x06, 0x00, 0xee, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0xe0, 0x06, 0xc0, 0x87, 0x32,
-	0x00, 0x00, 0x3f, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x08, 0x00, 0x00, 0x80, 0x02, 0x80, 0x91, 0xbc,
-	0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x10, 0x00, 0xe2, 0x10, 0x00, 0x50, 0x01, 0x14, 0xa9, 0x9b, 0x91, 0xd9,
-	0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x14, 0x89, 0x0d, 0x6e, 0x37,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x30, 0x01, 0x14, 0x89, 0x5b, 0x91, 0xd2,
-	0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc0, 0x2d, 0xd2,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x21, 0x01, 0x80, 0x82, 0x9b, 0x91, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0x78, 0x09, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x02, 0x80, 0x82, 0x9b, 0x97, 0xbc,
-	0x00, 0x00, 0x71, 0x0e, 0x04, 0x21, 0x01, 0x30, 0x69, 0x24, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0x00, 0xa9, 0x9b, 0x91, 0x3a,
-	0x00, 0x00, 0x66, 0x0e, 0x1f, 0x40, 0x02, 0x24, 0x09, 0x40, 0x68, 0xb2,
-	0x00, 0x00, 0x5c, 0x0e, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x41, 0x92, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xb9, 0x7f, 0x92, 0x30,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x24, 0x90, 0x3c,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x99, 0xa4, 0xfe, 0x38,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
-	0x08, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x99, 0xa4, 0xfe, 0xd8,
-	0x08, 0x00, 0x5c, 0x0e, 0x12, 0x01, 0x00, 0x68, 0x92, 0xa4, 0xfe, 0xb8,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x90, 0xbc,
-	0x00, 0x00, 0x6b, 0x0e, 0x38, 0x50, 0x01, 0x78, 0x09, 0x80, 0x6e, 0xb2,
-	0x00, 0x00, 0x6b, 0x0e, 0x04, 0x28, 0x01, 0x80, 0x02, 0x00, 0x6e, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x9f, 0x28, 0x01, 0x78, 0xe9, 0x25, 0x6e, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x08, 0x01, 0x00, 0x78, 0x69, 0xa4, 0x97, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0xe0, 0x66, 0x24, 0x6e, 0x3a,
-	0x00, 0x00, 0x6e, 0x0e, 0x38, 0x20, 0x01, 0xe0, 0x06, 0x00, 0x93, 0xb2,
-	0x00, 0x00, 0x6f, 0x0e, 0x00, 0x28, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
-	0x00, 0x00, 0x77, 0x0e, 0x38, 0x51, 0x01, 0x00, 0xa9, 0x9b, 0x91, 0xba,
-	0x00, 0x00, 0x75, 0x0e, 0x04, 0x41, 0x02, 0x08, 0xb9, 0xff, 0x68, 0xb0,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x41, 0x02, 0x80, 0xe2, 0xc1, 0x68, 0xb6,
-	0x00, 0x00, 0x72, 0x0e, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x92,
-	0x00, 0x00, 0x84, 0x0e, 0x9f, 0x31, 0x01, 0xe0, 0x66, 0x24, 0x6e, 0xbc,
-	0x00, 0x00, 0x84, 0x0e, 0x00, 0x30, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x92,
-	0x00, 0x00, 0x81, 0x0e, 0x04, 0x28, 0x01, 0x04, 0x09, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x50, 0x01, 0x80, 0xa2, 0x5b, 0x90, 0xbc,
-	0x00, 0x00, 0x7f, 0x0e, 0x9f, 0x01, 0x00, 0x00, 0x19, 0x24, 0x90, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0xe0, 0x66, 0x24, 0x6e, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0xe0, 0x06, 0x24, 0x00, 0x3c,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0xe0, 0x06, 0x00, 0x93, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x8e, 0x0e, 0x04, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xbc,
-	0x00, 0x00, 0x84, 0x0e, 0x04, 0x41, 0x02, 0x08, 0xb9, 0xff, 0x68, 0xb0,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x41, 0x02, 0x80, 0xe2, 0xc1, 0x68, 0xb6,
-	0x00, 0x00, 0x81, 0x0e, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x92,
-	0x00, 0x00, 0x88, 0x0e, 0x02, 0x00, 0x00, 0x80, 0x22, 0x24, 0x90, 0xbc,
-	0x00, 0x00, 0x8e, 0x0e, 0x80, 0x40, 0x02, 0x80, 0xf2, 0xc1, 0x68, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x8c, 0xb6, 0xc1, 0x68, 0x35,
-	0x00, 0x00, 0x8e, 0x0e, 0x00, 0x00, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0x94,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x78, 0x39, 0x9a, 0xfe, 0x38,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x97, 0xd2,
-	0x08, 0x00, 0x8a, 0x11, 0x12, 0x40, 0x02, 0x68, 0x12, 0x9a, 0xfe, 0xb8,
-	0x00, 0x00, 0x81, 0x0e, 0x04, 0x01, 0x00, 0x00, 0x29, 0x24, 0x90, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x32,
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x79, 0x0b, 0x16, 0x38,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x0b, 0x16, 0x38,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x42, 0xe4, 0x90, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xa9, 0x00, 0x2d, 0x37,
-	0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x89, 0x4d, 0x90, 0x3a,
-	0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x82, 0x0d, 0x91, 0x37,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x12, 0xa4, 0x2a, 0x3a,
-	0x00, 0x00, 0x99, 0x0e, 0x80, 0x40, 0x02, 0x80, 0xe2, 0x01, 0x7c, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x40, 0x02, 0x78, 0xb9, 0x3f, 0x7c, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe9, 0xa5, 0x90, 0x3a,
-	0x00, 0x00, 0x9b, 0x0e, 0x9f, 0x01, 0x00, 0x10, 0x19, 0x00, 0x91, 0xbc,
-	0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x94, 0x0e, 0x04, 0x01, 0x00, 0x80, 0x42, 0xe4, 0x90, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xc9, 0x24, 0x90, 0x3a,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x22, 0xa4, 0x97, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0xe0, 0x66, 0x24, 0x6e, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0xe8, 0x06, 0x00, 0x90, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0xe0, 0x06, 0x00, 0x93, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x18, 0x00, 0xa5, 0x0e, 0x1f, 0x41, 0x02, 0x78, 0x88, 0xcd, 0x68, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x12, 0x00, 0x2c, 0x3a,
-	0x00, 0x00, 0xa8, 0x0e, 0x80, 0x01, 0x00, 0x80, 0x62, 0x80, 0x87, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x41, 0x02, 0x80, 0xb2, 0xff, 0x68, 0xb0,
-	0x00, 0x00, 0xa3, 0x0e, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x92,
-	0x03, 0x00, 0x8a, 0x11, 0x04, 0x40, 0x02, 0x00, 0x38, 0x1a, 0xff, 0xb8,
-	0x00, 0x00, 0x8a, 0x11, 0x1f, 0x40, 0x02, 0x04, 0xb8, 0xff, 0x68, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0x00, 0xb8, 0x1b, 0x80, 0x3a,
-	0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x80, 0xd2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xb6, 0x0e, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0xb3, 0x0e, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x32,
-	0x1d, 0x00, 0xb6, 0x0e, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
-	0x00, 0x00, 0xb0, 0x0e, 0x9f, 0x01, 0x00, 0x80, 0x18, 0x00, 0x88, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0xca, 0x68, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x70, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
-	0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x10, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0xa9, 0x60, 0x81, 0xd9,
-	0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x80, 0xa2, 0xa0, 0x81, 0x7c,
-	0x00, 0x00, 0x8a, 0x11, 0x0d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0xc1, 0x0e, 0x80, 0x01, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0xc1, 0x0e, 0x1b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x80, 0x62, 0xe0, 0x83, 0x7c,
-	0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xf8, 0x02, 0x80, 0x2f, 0x35,
-	0x00, 0xa0, 0x00, 0x00, 0x12, 0x01, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0x72,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0xe4, 0x06, 0xc0, 0x2d, 0x32,
-	0xee, 0xff, 0x00, 0x00, 0x00, 0x10, 0x01, 0xe0, 0x86, 0x8d, 0x2f, 0x31,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xb3, 0xe4, 0x39, 0x32,
-	0x00, 0x00, 0xcd, 0x0e, 0x04, 0x00, 0x00, 0x78, 0xd9, 0x01, 0x30, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xb9, 0x05, 0x30, 0x30,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xe3, 0xa5, 0x03, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x33, 0x0b, 0x2f, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x78, 0xd9, 0x01, 0x30, 0x76,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xb9, 0x05, 0x30, 0x30,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0xe3, 0xa5, 0x03, 0x79,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x2d, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0xd8, 0x0e, 0x20, 0x00, 0x01, 0x2c, 0x09, 0xc0, 0x6e, 0xb2,
-	0x00, 0x00, 0xd9, 0x0e, 0x00, 0x16, 0x86, 0xcc, 0x06, 0xc0, 0x92, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x86, 0xcc, 0x06, 0xc0, 0x92, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x40, 0x62, 0x8e, 0x92, 0x52,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xdf, 0x0e, 0x04, 0x00, 0x00, 0x78, 0xd9, 0x01, 0x30, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x42, 0x80, 0x97, 0xbc,
-	0xdf, 0x0e, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
-	0x60, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x2f, 0xb1,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x03, 0x00, 0x38, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x02, 0x00, 0x30, 0x32,
-	0x00, 0x00, 0x22, 0x0f, 0x04, 0x00, 0x00, 0x24, 0xd8, 0x01, 0x30, 0xb6,
-	0xe4, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x82, 0x4d, 0x82, 0x3a,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0xdf, 0x0e, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xec, 0x0e, 0x00, 0x00, 0x00, 0x20, 0x48, 0x05, 0x30, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xf7, 0x0e, 0x32, 0x0f, 0x01, 0xbc, 0x08, 0xc0, 0x6e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0xdc, 0x02, 0x40, 0x6e, 0x32,
-	0x00, 0x00, 0xf0, 0x0e, 0x1f, 0x01, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xb2,
-	0x00, 0x00, 0xf6, 0x0e, 0x1d, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0xe0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x00, 0x2d, 0x37,
-	0x20, 0xcd, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x97, 0x3a,
-	0x0a, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x87, 0xa0, 0xea, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0xea, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x38, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0xe0, 0x26, 0x01, 0x6e, 0x35,
-	0x00, 0x00, 0xfb, 0x0e, 0x80, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x8b, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0e, 0x82, 0x32,
-	0x00, 0xe0, 0x03, 0x0f, 0x12, 0x01, 0x00, 0x48, 0xa2, 0x0d, 0x90, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x32,
-	0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x00, 0x2d, 0x37,
-	0x00, 0xcc, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x97, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x99, 0x00, 0x82, 0x37,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x10, 0x00, 0x00, 0x87, 0xbf, 0x97, 0xba,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x40, 0xfe, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0xf2, 0xc1, 0x38, 0xb4,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x89, 0x60, 0x38, 0x32,
-	0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xa4, 0x17, 0x38,
-	0x00, 0x00, 0x09, 0x0f, 0x80, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x8b, 0xb6,
-	0x00, 0x00, 0x0a, 0x0f, 0x04, 0x00, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x97, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf3, 0x41, 0x90, 0x34,
-	0x00, 0x00, 0x0f, 0x0f, 0x04, 0x00, 0x00, 0x78, 0xd9, 0x01, 0x30, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x05, 0x30, 0x30,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0xa4, 0x03, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xce, 0x2c, 0x32,
-	0x00, 0xe0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0x0d, 0x90, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0xdc, 0x02, 0x40, 0x6e, 0x32,
-	0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xa4, 0x17, 0x38,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x10, 0x01, 0x80, 0x22, 0x01, 0x6e, 0xb6,
-	0x00, 0x00, 0x18, 0x0f, 0x1f, 0x01, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xb2,
-	0x00, 0x00, 0x20, 0x0f, 0x1d, 0x10, 0x01, 0xf8, 0x02, 0x00, 0x6e, 0xb2,
-	0xe0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x00, 0x2d, 0x37,
-	0x20, 0xcd, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x97, 0x3a,
-	0x0a, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x37, 0x8b, 0xea, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0xea, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0xf8, 0x02, 0x00, 0x6e, 0x32,
-	0xee, 0xff, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x2f, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
-	0xee, 0xff, 0x8a, 0x11, 0x04, 0x11, 0x01, 0x80, 0x82, 0x0d, 0x6e, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0xf8, 0x02, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x01, 0xdc, 0x02, 0x40, 0x6e, 0x72,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x32,
-	0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x89, 0x4d, 0x0d, 0x36,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x0b, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x90, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x2b, 0x0f, 0x12, 0x00, 0x00, 0x4c, 0xf2, 0xc1, 0x38, 0xb4,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
-	0x00, 0x00, 0x2c, 0x0f, 0x12, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x21, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe9, 0x02, 0x90, 0x3a,
-	0x00, 0x00, 0x28, 0x0f, 0x04, 0x01, 0x00, 0x04, 0x19, 0x40, 0x90, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x3b, 0x0f, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x35, 0x0f, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x3a, 0x0f, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x22, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x80, 0x18, 0x00, 0x88, 0xbc,
-	0x00, 0x00, 0x35, 0x0f, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
-	0x00, 0x00, 0x34, 0x0f, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0xca, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x2d, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x6c, 0x88, 0x1c, 0x83, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4c, 0x08, 0x00, 0x72, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x08, 0x50, 0x00, 0x18, 0xc8, 0x20, 0x72, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x81, 0x7c,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0x3c,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x00, 0x00, 0x20, 0x88, 0x01, 0x82, 0xba,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x06, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x36, 0xbc,
-	0x07, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x77, 0x4a, 0x09, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x00, 0x82, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0xca, 0x19, 0x00, 0x00, 0x07, 0x40, 0x82, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x72,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x3e,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
-	0x00, 0x00, 0xa3, 0x0f, 0x04, 0x00, 0x00, 0x28, 0xd8, 0xa0, 0x82, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xd8, 0xa0, 0x81, 0x3c,
-	0x00, 0x00, 0x67, 0x0f, 0x04, 0x00, 0x00, 0x3c, 0xd8, 0xe0, 0x83, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x81, 0xbc,
-	0x00, 0x00, 0x58, 0x0f, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0x02, 0xc0, 0x38, 0xb2,
-	0x00, 0x00, 0x60, 0x0f, 0x51, 0x00, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x9a,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x5e, 0x0f, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x59, 0x0f, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x65, 0x0f, 0x2a, 0x01, 0x00, 0x00, 0xd8, 0x20, 0x80, 0xba,
-	0x00, 0x00, 0x64, 0x0f, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x32,
-	0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
-	0x00, 0x00, 0xb7, 0x0e, 0x00, 0x60, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xf2,
-	0x00, 0x00, 0x4d, 0x0f, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x9e,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x1d, 0x00, 0x6e, 0x0f, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x68, 0x0f, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
-	0x1d, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x78, 0x39, 0x9a, 0xfe, 0x38,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x97, 0xd2,
-	0x08, 0x00, 0x8a, 0x11, 0x12, 0x40, 0x02, 0x68, 0x12, 0x9a, 0xfe, 0xb8,
-	0x00, 0x00, 0x8a, 0x11, 0x0b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
-	0x00, 0x00, 0x86, 0x0f, 0x1f, 0x00, 0x00, 0x6c, 0xd8, 0xe0, 0x86, 0xba,
-	0x00, 0x00, 0xa3, 0x0e, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xf2,
-	0x00, 0x00, 0x79, 0x0f, 0x00, 0x00, 0x00, 0x3c, 0x08, 0x40, 0x80, 0x92,
-	0x00, 0x00, 0x86, 0x0f, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x7e, 0x0f, 0x80, 0x01, 0x00, 0x80, 0xf2, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x7e, 0x0f, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x7e, 0x0f, 0x80, 0x01, 0x00, 0x80, 0x32, 0x80, 0x87, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xe2, 0x80, 0x2f, 0x34,
-	0x00, 0x00, 0x4c, 0x0f, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x81, 0xbc,
-	0x00, 0x00, 0x84, 0x0f, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x83, 0x0f, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x32,
-	0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
-	0x00, 0x00, 0xb7, 0x0e, 0x00, 0x60, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xf2,
-	0x00, 0x00, 0x4d, 0x0f, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x9e,
-	0x00, 0x00, 0x89, 0x0f, 0x80, 0x01, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0xa7, 0x0f, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xa8, 0x60, 0x8a, 0x3c,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x21, 0x01, 0x80, 0x82, 0x5b, 0x8a, 0xbc,
-	0x00, 0x00, 0x8d, 0x0f, 0x2f, 0xa8, 0x01, 0x20, 0x99, 0x22, 0x6e, 0xba,
-	0x00, 0x00, 0x2f, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x02, 0x80, 0x82, 0x1b, 0x92, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0xe0, 0x06, 0x00, 0x92, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x92, 0x0f, 0x23, 0x21, 0x01, 0xe0, 0x06, 0x00, 0x00, 0xb2,
-	0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x30, 0x00, 0xe0, 0x06, 0x80, 0x82, 0xb2,
-	0x00, 0x00, 0x9c, 0x0f, 0x04, 0x21, 0x00, 0xe0, 0x06, 0x80, 0x81, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x9a, 0x0f, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x99, 0x0f, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x32,
-	0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
-	0x00, 0x00, 0xb7, 0x0e, 0x00, 0x60, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xf2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xe0, 0x06, 0x80, 0x81, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0xe8, 0x06, 0x40, 0x81, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0xe0, 0x06, 0xc0, 0x86, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x2a, 0x19, 0x00, 0xe0, 0x06, 0xc0, 0x84, 0x72,
-	0x00, 0x00, 0xa1, 0x0f, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0x75,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xd8, 0xe0, 0x83, 0x3c,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x12, 0x00, 0x2c, 0x3a,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0x32,
-	0xee, 0x05, 0xaf, 0x0f, 0x04, 0x01, 0x00, 0x80, 0x82, 0x4d, 0xf5, 0xbc,
-	0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xb1, 0x0f, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0x09, 0x92,
-	0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0x80, 0x09, 0x32,
-	0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x87, 0xcd, 0x00, 0x37,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x60, 0xc0, 0x07, 0x80, 0x97, 0x32,
-	0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0x8d, 0x2a, 0x3a,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0x52, 0x81, 0x97, 0xb4,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x24, 0x90, 0x3a,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0x0d, 0x90, 0x36,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x19, 0x40, 0x90, 0x3c,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x52, 0x82, 0x2a, 0x3a,
-	0x00, 0x08, 0xb1, 0x0f, 0x02, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x2a, 0xbc,
-	0x00, 0x00, 0xc2, 0x0f, 0x06, 0x00, 0x00, 0x80, 0x02, 0x40, 0x90, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x20, 0xb2,
-	0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x87, 0xcd, 0x00, 0x37,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xc0, 0x07, 0x80, 0x97, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0x52, 0x81, 0x2a, 0xb4,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x24, 0x90, 0x3a,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0x0d, 0x90, 0x36,
-	0x00, 0x00, 0xbb, 0x0f, 0x04, 0x01, 0x00, 0x04, 0x19, 0x40, 0x90, 0xbc,
-	0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0x0d, 0x90, 0x36,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0e, 0x80, 0x97, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0x80, 0x97, 0xb2,
-	0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x89, 0x0d, 0x90, 0x36,
-	0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x89, 0x4d, 0x92, 0x3c,
-	0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x82, 0x4d, 0x92, 0x36,
-	0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x89, 0x4d, 0x92, 0x30,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x18, 0x9b, 0x81, 0xb2, 0xe4, 0x78, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x9b, 0x8d, 0xb7, 0xe4, 0x78, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x0e, 0x80, 0x97, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x24, 0x90, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x59, 0x00, 0x90, 0x36,
-	0x00, 0x00, 0xc4, 0x0f, 0x95, 0x01, 0x00, 0x80, 0x22, 0x24, 0x90, 0xba,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xec, 0x0f, 0x04, 0x01, 0x00, 0x78, 0xd9, 0x01, 0x30, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x09, 0xc0, 0x29, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0xb2, 0x45, 0x28, 0x30,
-	0x00, 0x00, 0xdd, 0x0f, 0x86, 0x01, 0x00, 0x08, 0x09, 0x80, 0x2f, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x09, 0x40, 0x81, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x02, 0x00, 0x00, 0x32,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x02, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x80, 0x92, 0x32,
-	0x00, 0x00, 0xdc, 0x0f, 0x04, 0x07, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
-	0x00, 0x00, 0xe7, 0x0f, 0xc3, 0x07, 0x01, 0xec, 0xb6, 0xe4, 0x6e, 0x9a,
-	0x00, 0x00, 0xe7, 0x0f, 0x00, 0x06, 0x01, 0xec, 0xb6, 0xe4, 0x6e, 0x9a,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x52, 0x80, 0x90, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x09, 0x05, 0x80, 0x30,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x02, 0x00, 0x00, 0x32,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x02, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x80, 0x92, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xf2, 0xc1, 0x92, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xfa, 0x92, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xfa, 0x92, 0xbc,
-	0x44, 0x00, 0x2c, 0x10, 0x00, 0x00, 0x00, 0xf8, 0xa2, 0x8d, 0x2f, 0xd2,
-	0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc0, 0x92, 0xd2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0x32,
-	0x00, 0x00, 0xec, 0x0f, 0x04, 0x01, 0x00, 0x78, 0xd9, 0x01, 0x30, 0xb6,
-	0x00, 0x00, 0xd4, 0x0f, 0x00, 0x00, 0x00, 0x9c, 0xb2, 0x45, 0x28, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x80, 0x22, 0x80, 0x97, 0x7c,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0xe8, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x02, 0xc0, 0xe8, 0x32,
-	0x02, 0x00, 0xf1, 0x0f, 0xb0, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0xb9,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xab, 0xe4, 0xb0, 0x32,
-	0x00, 0x00, 0xf6, 0x0f, 0x80, 0x01, 0x00, 0x80, 0xc2, 0x4a, 0xd0, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x28, 0x09, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
-	0x00, 0x00, 0xf9, 0x0f, 0x04, 0x00, 0x00, 0x80, 0x02, 0x00, 0xf8, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x80, 0x01, 0x00, 0xf8, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x28, 0x09, 0x00, 0x00, 0x52,
-	0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x04, 0xcd, 0x4a, 0xd0, 0x34,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xc2, 0x4a, 0xd0, 0xb6,
-	0x00, 0x00, 0x00, 0x10, 0x04, 0x01, 0x00, 0x28, 0x09, 0x34, 0xb0, 0xba,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xc2, 0x4a, 0xd0, 0xb6,
-	0x00, 0x00, 0xfd, 0x0f, 0xb0, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x04, 0xcd, 0x4a, 0xd0, 0x35,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x28, 0x09, 0x00, 0x00, 0x52,
-	0x00, 0x00, 0x00, 0x10, 0xb0, 0x00, 0x00, 0xa8, 0x22, 0x00, 0x2b, 0xb7,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x84, 0xc0, 0x37, 0xac, 0xb0, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x0c, 0x0b, 0x00, 0x00, 0x32,
-	0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x4d, 0xb0, 0x30,
-	0x00, 0x00, 0x08, 0x10, 0x80, 0x00, 0x00, 0x80, 0x02, 0x40, 0xb0, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x12, 0x40, 0xb0, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x69, 0x81, 0x97, 0x35,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x08, 0x0b, 0x00, 0x7c, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x25, 0x01, 0x32,
-	0x00, 0x42, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x2a, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x00, 0xb0, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0xd0, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x48, 0xf2, 0xc1, 0x38, 0x54,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x0e, 0x10, 0xb0, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xab, 0xe4, 0xb0, 0x32,
-	0x00, 0x00, 0x13, 0x10, 0x80, 0x01, 0x00, 0x80, 0x02, 0x40, 0xd0, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x28, 0x09, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
-	0x00, 0x00, 0x16, 0x10, 0x04, 0x00, 0x00, 0x80, 0x02, 0x00, 0xf8, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x80, 0x01, 0x00, 0xf8, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x28, 0x09, 0x00, 0x00, 0x52,
-	0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x04, 0x0d, 0x40, 0xd0, 0x34,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x02, 0x40, 0xd0, 0xb6,
-	0x00, 0x00, 0x1d, 0x10, 0x04, 0x01, 0x00, 0x28, 0x09, 0x34, 0xb0, 0xba,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x02, 0x40, 0xd0, 0xb6,
-	0x00, 0x00, 0x1a, 0x10, 0xb0, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x04, 0x0d, 0x40, 0xd0, 0x35,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x28, 0x09, 0x00, 0x00, 0x52,
-	0x00, 0x00, 0x1d, 0x10, 0xb0, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x84, 0xc0, 0x37, 0xac, 0xb0, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x0c, 0x0b, 0x00, 0x00, 0x32,
-	0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x4d, 0xb0, 0x30,
-	0x00, 0x00, 0x25, 0x10, 0x80, 0x00, 0x00, 0x80, 0x02, 0x40, 0xb0, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x12, 0x40, 0xb0, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x69, 0x81, 0x97, 0x35,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x08, 0x0b, 0x00, 0x7c, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x25, 0x01, 0x32,
-	0x00, 0x42, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x2a, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x00, 0xb0, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0xd0, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x48, 0xf2, 0xc1, 0x38, 0x54,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x1c, 0x41, 0x02, 0x80, 0x06, 0xc0, 0x92, 0x52,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x92, 0x30,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x97, 0xd2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0xc5, 0x92, 0xb0,
-	0x00, 0x00, 0x8a, 0x11, 0x0b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0xc0, 0xf5, 0x3a,
-	0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc0, 0x92, 0xd2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
-	0x00, 0x82, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x08, 0x80, 0x36, 0x52,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x38, 0x80, 0x87, 0x35,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x72, 0x80, 0x87, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0x3c,
-	0x08, 0x00, 0x00, 0x00, 0xd2, 0x01, 0x00, 0x78, 0xe9, 0xe5, 0x83, 0x39,
-	0x18, 0x00, 0x8a, 0x11, 0x1f, 0x41, 0x02, 0x84, 0xe6, 0xa1, 0x97, 0xb9,
-	0x00, 0x00, 0x43, 0x10, 0x36, 0x51, 0x01, 0xe8, 0x16, 0xe0, 0x83, 0xbc,
-	0x00, 0x00, 0x43, 0x10, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
-	0x00, 0x00, 0x45, 0x10, 0x38, 0x21, 0x01, 0xe0, 0x06, 0x40, 0x80, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0xe0, 0x06, 0x40, 0x80, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xe0, 0x06, 0x00, 0x00, 0x72,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x92, 0xd2,
-	0x00, 0x00, 0x00, 0x00, 0xd5, 0x08, 0x00, 0x00, 0x07, 0x80, 0x92, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xc0, 0x2c, 0x32,
-	0x00, 0x40, 0x00, 0x80, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0xca, 0x41, 0x01, 0xe0, 0x06, 0x80, 0x92, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xe8, 0x01, 0x00, 0x74,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x62, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0x80, 0x92, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xc0, 0x2c, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0xca, 0x3d, 0x00, 0x0c, 0x07, 0x80, 0x83, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x48, 0x02, 0xc0, 0x80, 0x72,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x04, 0x57, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0x7c,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x01, 0xec, 0x06, 0x80, 0x92, 0x72,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
-	0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x10, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x19, 0xa0, 0x2c, 0xd9,
-	0x00, 0x00, 0x60, 0x10, 0x9d, 0x11, 0x02, 0x0c, 0x09, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x61, 0x10, 0x00, 0xf0, 0x01, 0x1c, 0x09, 0x00, 0x6e, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x01, 0x1c, 0x09, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x63, 0x10, 0x2c, 0xcd, 0x01, 0x18, 0x09, 0x80, 0x6e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xc9, 0xc1, 0x90, 0x34,
-	0x00, 0x00, 0x67, 0x10, 0x3b, 0x29, 0x02, 0x04, 0x09, 0x80, 0x6e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0xd6, 0x01, 0x80, 0x52, 0xc0, 0x6e, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x01, 0xec, 0x56, 0xc0, 0x6e, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xb9, 0xc1, 0x90, 0x34,
-	0x00, 0x00, 0x77, 0x10, 0x00, 0xa8, 0x01, 0x08, 0x09, 0x00, 0x6e, 0xf2,
-	0x00, 0x00, 0x6b, 0x10, 0x9d, 0x01, 0x00, 0x80, 0x17, 0xe0, 0x90, 0xba,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x80, 0x07, 0xc0, 0x91, 0x32,
-	0x00, 0x00, 0x6e, 0x10, 0x00, 0x38, 0x00, 0x80, 0x07, 0x00, 0xee, 0x92,
-	0x00, 0x00, 0x6e, 0x10, 0x04, 0x01, 0x00, 0x80, 0x02, 0xc0, 0x91, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x01, 0xe0, 0x06, 0x00, 0xee, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x01, 0xe0, 0x06, 0x00, 0x86, 0x32,
-	0x00, 0x00, 0x71, 0x10, 0x39, 0x08, 0x00, 0x80, 0x07, 0xc0, 0x85, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xc2, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0xd9, 0xc9, 0x01, 0xe8, 0x06, 0x80, 0x91, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0xc8, 0x11, 0x00, 0x80, 0x07, 0x40, 0x90, 0x32,
-	0x00, 0x00, 0x74, 0x10, 0x3b, 0x21, 0x00, 0x80, 0x07, 0x00, 0x86, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x60, 0x18, 0x00, 0x86, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x58, 0x78, 0x01, 0xe0, 0x16, 0x20, 0x86, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x80, 0x07, 0x00, 0x85, 0x72,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x7b, 0x10, 0x02, 0x0c, 0x02, 0x80, 0xa2, 0x9b, 0x90, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x78, 0x29, 0x00, 0x6e, 0x36,
-	0x00, 0x00, 0x7b, 0x10, 0x02, 0x00, 0x00, 0x80, 0xe2, 0xa5, 0x90, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x01, 0x78, 0x49, 0x21, 0x6e, 0x3c,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe9, 0xa5, 0x90, 0x3f,
-	0x00, 0x00, 0x82, 0x10, 0x04, 0x20, 0x02, 0x08, 0x89, 0x9b, 0x90, 0xbe,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x02, 0x58, 0xb8, 0x9b, 0x90, 0x36,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x49, 0xa1, 0x90, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x9f, 0x88, 0x01, 0x80, 0x82, 0x9b, 0x97, 0x7c,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x01, 0xe0, 0x06, 0x80, 0x97, 0x72,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x02, 0x58, 0xb8, 0x9b, 0x90, 0x76,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8b, 0x10, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x89, 0x10, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x8b, 0x10, 0xca, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x92,
-	0x15, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x78, 0xe9, 0x65, 0x17, 0xb8,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0x35,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x2d, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x6c, 0x88, 0x1c, 0x83, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4c, 0x08, 0x00, 0x72, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x08, 0x50, 0x00, 0x18, 0xc8, 0x20, 0x72, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x80, 0x62, 0xa0, 0x82, 0x7c,
-	0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x00, 0x00, 0x20, 0x88, 0x01, 0x82, 0xba,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x06, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x36, 0xbc,
-	0x07, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x77, 0x4a, 0x09, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x00, 0x82, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0xca, 0x19, 0x00, 0x00, 0x07, 0x40, 0x82, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x72,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc0, 0x85, 0xd2,
-	0x00, 0x00, 0xa6, 0x10, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
-	0x00, 0x00, 0xa2, 0x10, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
-	0x00, 0x00, 0xa6, 0x10, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
-	0x00, 0x00, 0xa6, 0x10, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
-	0x00, 0x00, 0xa4, 0x10, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
-	0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x5c, 0x1f, 0xc0, 0xf5, 0x7a,
-	0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x80, 0xa2, 0x8d, 0x2f, 0x70,
-	0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x74,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x80, 0xa8, 0x00, 0x00, 0x04, 0x00, 0x00, 0x80, 0x82, 0x8d, 0x2f, 0x70,
-	0x00, 0x00, 0xb7, 0x10, 0x80, 0x01, 0x00, 0x80, 0xd2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x72, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0xba, 0x10, 0x04, 0xb0, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x72, 0x81, 0x2f, 0x34,
-	0x3b, 0x00, 0xba, 0x10, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xba, 0x10, 0x80, 0x01, 0x00, 0x80, 0xf2, 0x80, 0x2f, 0xb6,
-	0x30, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0xbd, 0x10, 0x00, 0x00, 0x00, 0xf8, 0x42, 0x81, 0x2f, 0x94,
-	0x00, 0x00, 0xbd, 0x10, 0x80, 0x01, 0x00, 0x80, 0xb2, 0x80, 0x2f, 0xb6,
-	0x34, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x42, 0x81, 0x2f, 0x34,
-	0x80, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x80, 0x82, 0x8d, 0x2f, 0x70,
-	0x02, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x80, 0xa2, 0x8d, 0x2f, 0x70,
-	0x3a, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0x12, 0x81, 0x2f, 0x74,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x65, 0x01, 0x80, 0xa2, 0xdb, 0x2c, 0xbc,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 0xe8, 0x76, 0x20, 0x81, 0x39,
-	0xee, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0x82, 0x8d, 0x2f, 0x71,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xcb, 0x10, 0x00, 0x00, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0xf2,
-	0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x48, 0x02, 0xc0, 0x80, 0x72,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xcd, 0x10, 0x04, 0x38, 0x01, 0x78, 0x09, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0xca, 0x11, 0x00, 0x00, 0x07, 0x80, 0x82, 0x32,
-	0x00, 0x00, 0xd1, 0x10, 0x2e, 0x19, 0x00, 0x00, 0x07, 0x80, 0x97, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xe9, 0x81, 0x92, 0x34,
-	0x00, 0x00, 0xd5, 0x10, 0x27, 0x31, 0x00, 0x00, 0x07, 0xc0, 0x2c, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0xd5, 0x08, 0x00, 0x00, 0x07, 0x00, 0x87, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x28, 0xe9, 0x80, 0x92, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0xe0, 0x06, 0x00, 0x87, 0x32,
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0xe7, 0xa0, 0x92, 0x79,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x40, 0x90, 0xd2,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0x12, 0xe4, 0x38, 0xb2,
-	0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
-	0x00, 0x00, 0xdf, 0x10, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0xda, 0x10, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
-	0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x72,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x79, 0x0a, 0x91, 0x39,
-	0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x39, 0x0b, 0x91, 0x39,
-	0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x59, 0x0a, 0x91, 0x39,
-	0x09, 0x00, 0xe5, 0x10, 0xf1, 0x01, 0x00, 0x10, 0x69, 0x0b, 0x91, 0xb9,
-	0x03, 0x00, 0x00, 0x00, 0x00, 0x24, 0x86, 0xa8, 0x82, 0x8d, 0x6c, 0x37,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xe0, 0x07, 0x00, 0x91, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xe0, 0x07, 0x40, 0x91, 0x32,
-	0x00, 0x80, 0xeb, 0x10, 0x02, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x2a, 0xbc,
-	0x00, 0x00, 0xec, 0x10, 0xe1, 0x24, 0x86, 0xc8, 0x06, 0x00, 0x00, 0x92,
-	0x03, 0x00, 0x00, 0x00, 0xe1, 0x24, 0x86, 0xc8, 0x86, 0x8d, 0x2a, 0x36,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xf4, 0x10, 0x04, 0x30, 0x00, 0x80, 0x82, 0x9b, 0x81, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x0d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x8a, 0x11, 0x9f, 0x3c, 0x00, 0x14, 0x28, 0x80, 0x6e, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xf8, 0x02, 0x80, 0x2f, 0x35,
-	0x00, 0xa0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
-	0x00, 0x00, 0xf6, 0x10, 0x80, 0x39, 0x00, 0x80, 0xe2, 0x80, 0x6e, 0xb6,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x38, 0x00, 0x80, 0xf2, 0x80, 0x6e, 0xb6,
-	0x00, 0xe0, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xa2, 0x8d, 0x2f, 0xb0,
-	0x00, 0xe0, 0xfd, 0x10, 0x04, 0x38, 0x00, 0x78, 0x89, 0x8d, 0x6e, 0xb0,
-	0x10, 0x00, 0xfd, 0x10, 0x9f, 0x01, 0x00, 0xf8, 0xe2, 0xa5, 0x2f, 0xb9,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0xee, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xec, 0x06, 0xc0, 0xee, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
-	0x00, 0x00, 0x00, 0x00, 0x04, 0x28, 0x00, 0x18, 0x09, 0x00, 0x6e, 0x72,
-	0x00, 0x00, 0x4f, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
-	0x00, 0x00, 0x2f, 0x0e, 0x00, 0xa8, 0x01, 0x20, 0x09, 0x00, 0x6e, 0x92,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0xa9, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x04, 0xb0, 0x00, 0x80, 0x82, 0x9b, 0x81, 0x7c,
-	0x00, 0x00, 0x8a, 0x11, 0x0d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x8a, 0x11, 0x9f, 0xbc, 0x00, 0x14, 0x28, 0x80, 0x6e, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xf8, 0x42, 0x80, 0x2f, 0x35,
-	0x08, 0xa0, 0x00, 0x00, 0x12, 0x01, 0x00, 0x40, 0xa2, 0xcd, 0x39, 0x72,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x90, 0xd2,
-	0x00, 0x00, 0x0f, 0x11, 0x33, 0xcd, 0x01, 0xbc, 0x08, 0x80, 0x6e, 0xb2,
-	0x00, 0x00, 0x4e, 0x11, 0x00, 0x00, 0x00, 0x28, 0x29, 0x22, 0xee, 0xdc,
-	0x00, 0x00, 0x14, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x14, 0x11, 0x04, 0xb8, 0x01, 0x28, 0x09, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x14, 0x11, 0x9f, 0x71, 0x01, 0x80, 0xc2, 0x21, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xa9, 0x24, 0xee, 0x3c,
-	0x00, 0x00, 0x4e, 0x11, 0x00, 0x00, 0x00, 0x28, 0x19, 0x80, 0x92, 0xdf,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
-	0x00, 0x00, 0x28, 0x11, 0x06, 0x80, 0x01, 0x80, 0x82, 0x9b, 0x90, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x90, 0xbc,
-	0xee, 0x05, 0x20, 0x11, 0x06, 0x0c, 0x02, 0x80, 0x82, 0x8d, 0x6e, 0xbc,
-	0x00, 0x90, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x84, 0x02, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x1a, 0x11, 0xb8, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x18, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x03, 0x80, 0x90, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x01, 0xe0, 0x96, 0x21, 0x6e, 0x3c,
-	0x00, 0x00, 0x00, 0x00, 0x61, 0x98, 0x01, 0xe0, 0x06, 0x00, 0x87, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x01, 0xec, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x78, 0x49, 0x40, 0x3c, 0x37,
-	0x00, 0x00, 0x2d, 0x11, 0x00, 0x00, 0x00, 0x08, 0xe9, 0xa5, 0x90, 0x9a,
-	0x60, 0x89, 0x20, 0x00, 0x00, 0x00, 0x00, 0x84, 0x02, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x23, 0x11, 0xb8, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
-	0x00, 0x00, 0x21, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x03, 0x80, 0x90, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x01, 0xe0, 0x96, 0x21, 0x6e, 0x3c,
-	0x00, 0x00, 0x00, 0x00, 0x61, 0x98, 0x01, 0xe0, 0x06, 0x00, 0x87, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x01, 0xec, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x2d, 0x11, 0xa8, 0x00, 0x00, 0x08, 0x19, 0x8f, 0x90, 0x9a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x99, 0xa1, 0x89, 0x3e,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe9, 0xa5, 0x90, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x01, 0xe0, 0x96, 0x21, 0x6e, 0x3c,
-	0x00, 0x00, 0x00, 0x00, 0x61, 0x98, 0x01, 0xe0, 0x06, 0x00, 0x87, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x01, 0xec, 0x06, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x30, 0x11, 0x06, 0x00, 0x00, 0x80, 0x72, 0xa2, 0x90, 0xbc,
-	0x00, 0xc0, 0xff, 0x3f, 0x00, 0x80, 0x01, 0xe0, 0x06, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0xc0, 0x89, 0x32,
-	0x00, 0x00, 0x36, 0x11, 0x04, 0x79, 0x01, 0x80, 0x82, 0x1b, 0x87, 0xbc,
-	0x00, 0x00, 0x34, 0x11, 0x04, 0xb0, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0xe0, 0x06, 0x80, 0x90, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0x92, 0x81, 0x2f, 0x75,
-	0x00, 0x00, 0x3c, 0x11, 0x80, 0x00, 0x00, 0x80, 0x52, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x3c, 0x11, 0xd5, 0x41, 0x01, 0xe0, 0x06, 0x00, 0x87, 0x92,
-	0x00, 0x00, 0x39, 0x11, 0x3c, 0x90, 0x01, 0xe0, 0x06, 0x80, 0x90, 0xb2,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x92, 0x81, 0x2f, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0xe8, 0x06, 0xc0, 0x8b, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x95, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2f, 0x72,
-	0x00, 0x00, 0x3d, 0x11, 0x9f, 0x41, 0x01, 0x80, 0x82, 0x1b, 0x87, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
-	0x00, 0x00, 0x00, 0x00, 0xd9, 0x90, 0x01, 0xe0, 0x06, 0x80, 0x90, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0x72, 0x80, 0x2f, 0x74,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x40, 0x87, 0xd2,
-	0x00, 0x00, 0x47, 0x11, 0x9f, 0xd8, 0x01, 0x80, 0x22, 0x21, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
-	0x00, 0x00, 0x47, 0x11, 0x9f, 0xe0, 0x01, 0x80, 0xc2, 0x21, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
-	0x00, 0x00, 0x47, 0x11, 0x9f, 0xb0, 0x01, 0x80, 0xd2, 0x21, 0x6e, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
-	0x00, 0x00, 0x49, 0x11, 0x06, 0x68, 0x01, 0x80, 0x82, 0x5b, 0x87, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x01, 0xe0, 0x06, 0x40, 0x87, 0x32,
-	0x00, 0x00, 0x4b, 0x11, 0x37, 0xb0, 0x01, 0xe0, 0x06, 0x40, 0x87, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xd2, 0x80, 0x2f, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x01, 0xe0, 0x06, 0x80, 0x84, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x01, 0xe0, 0x06, 0x00, 0x87, 0x72,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x08, 0x00, 0x00, 0x80, 0x02, 0x80, 0x92, 0xbc,
-	0x00, 0x00, 0x5b, 0x11, 0x04, 0xc1, 0x01, 0x84, 0x02, 0x00, 0x6e, 0xb2,
-	0x05, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0xe8, 0x86, 0x8d, 0x92, 0x37,
-	0x03, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x01, 0xe8, 0x86, 0x8d, 0x92, 0x37,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
-	0x03, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x2c, 0x89, 0x8d, 0x6e, 0x36,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x01, 0x2c, 0xa9, 0xdb, 0x92, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x29, 0xc0, 0x92, 0x36,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x19, 0xfb, 0x92, 0x3f,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x29, 0x80, 0x92, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xa9, 0xe4, 0x92, 0x3f,
-	0x00, 0x00, 0x00, 0x00, 0x6f, 0xcc, 0x01, 0xe8, 0x26, 0xfb, 0x92, 0x3e,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x52,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0x02, 0x80, 0x92, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0xe0, 0x06, 0x40, 0x28, 0x32,
-	0x10, 0x00, 0x00, 0x00, 0x6f, 0xcc, 0x01, 0xe8, 0x86, 0xcd, 0x2a, 0x36,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x52,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0xb0, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0xbc, 0x08, 0x00, 0x6e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x01, 0xbc, 0x88, 0xdb, 0x8b, 0x3e,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x01, 0xbc, 0x88, 0xdb, 0x8b, 0x3a,
-	0x00, 0x00, 0x6a, 0x11, 0x9f, 0x00, 0x00, 0xbc, 0x88, 0xe1, 0x8b, 0xbc,
-	0x00, 0x00, 0x6a, 0x11, 0x04, 0x0c, 0x02, 0x40, 0xa8, 0xdb, 0x8b, 0xbe,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x04, 0x88, 0x1b, 0x84, 0x3e,
-	0x00, 0x00, 0x69, 0x11, 0x04, 0xb1, 0x00, 0x80, 0x82, 0x5b, 0x80, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0xc2, 0x80, 0x2f, 0x74,
-	0x00, 0x00, 0x00, 0x00, 0x04, 0x0c, 0x02, 0x80, 0xa2, 0x5b, 0x80, 0x7c,
-	0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc0, 0x8b, 0xd2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x12, 0x00, 0x2c, 0x3a,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x04, 0x65, 0x01, 0x80, 0xa2, 0xdb, 0x2c, 0xbc,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x01, 0xe8, 0x76, 0x20, 0x81, 0x39,
-	0xee, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0x82, 0x8d, 0x2f, 0x71,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xd9, 0x4a, 0x91, 0x39,
-	0x39, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0xd2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x09, 0x45, 0x91, 0x30,
-	0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x89, 0x4d, 0x91, 0x36,
-	0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x89, 0xcd, 0x93, 0x3c,
-	0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x82, 0xcd, 0x93, 0x36,
-	0x07, 0x00, 0x79, 0x11, 0xf3, 0x01, 0x00, 0x40, 0x89, 0xcd, 0x93, 0xb0,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x18, 0x9b, 0x81, 0x02, 0xe5, 0x78, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0xe3, 0x18, 0x9b, 0x8d, 0x07, 0xe5, 0x78, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xd9, 0x4a, 0x91, 0x39,
-	0x3a, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0xd2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x09, 0x45, 0x91, 0x30,
-	0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x89, 0x4d, 0x91, 0x36,
-	0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x89, 0xcd, 0x93, 0x3c,
-	0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x82, 0xcd, 0x93, 0x36,
-	0x07, 0x00, 0x84, 0x11, 0xf3, 0x01, 0x00, 0x40, 0x89, 0xcd, 0x93, 0xb0,
-	0x00, 0x00, 0x8a, 0x11, 0x80, 0x19, 0x9b, 0x81, 0x02, 0xe5, 0x78, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0xe3, 0x18, 0x9b, 0x8d, 0x07, 0xe5, 0x78, 0x35,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0xb4, 0x0f, 0x40, 0xfb, 0x94,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x0f, 0x40, 0x2b, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0f, 0x00, 0x28, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0x0f, 0x00, 0x29, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x0f, 0x40, 0x18, 0x32,
-	0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x5f, 0xca, 0xf9, 0x35,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x03, 0xc0, 0xf9, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x00, 0x32,
-	0x41, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x00, 0x32,
-	0x40, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x0f, 0x80, 0x2a, 0x32,
-	0x4c, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
-	0x98, 0x11, 0x97, 0x12, 0x00, 0x00, 0x00, 0xb0, 0x0f, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x01, 0x84, 0x12, 0x00, 0x00, 0x00, 0xac, 0x0f, 0x00, 0x36, 0xd2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x0f, 0x80, 0x2a, 0x32,
-	0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x7e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0f, 0x00, 0x7e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x0f, 0x00, 0x7e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x0f, 0x00, 0x7e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0xc0, 0xfa, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0xf9, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0xfa, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0xfa, 0x32,
-	0x00, 0x00, 0xac, 0x11, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0xfa, 0xd2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0xfb, 0x32,
-	0x01, 0x00, 0xcf, 0x11, 0x04, 0x01, 0x00, 0xb4, 0x8f, 0x4d, 0xfb, 0xb0,
-	0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xab, 0xcd, 0xb0, 0x32,
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5b, 0xca, 0xb0, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x2b, 0xfe, 0xb0, 0x32,
-	0x00, 0x00, 0xaa, 0x11, 0x12, 0x01, 0x00, 0x80, 0x02, 0x40, 0x20, 0xb2,
-	0x00, 0x00, 0xbe, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x01, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xe0, 0x07, 0x80, 0x3f, 0x52,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x02, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x53, 0x0a, 0x16, 0x35,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x90, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0f, 0x40, 0x90, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x0f, 0x80, 0x90, 0x32,
-	0xa2, 0x60, 0x03, 0x00, 0x00, 0x00, 0x00, 0x58, 0x03, 0x00, 0x37, 0x32,
-	0xb9, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x03, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x83, 0x0d, 0x00, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x83, 0x0d, 0x00, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x53, 0x0a, 0x00, 0x34,
-	0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xc0, 0xf9, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0x00, 0xfa, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0xfa, 0x32,
-	0x00, 0x00, 0xc9, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0x39,
-	0x00, 0x00, 0xc0, 0x11, 0x80, 0x01, 0x00, 0x80, 0x12, 0x40, 0xb0, 0xb6,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x3b, 0x40, 0xb0, 0x33,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xcd, 0x4a, 0xd0, 0x35,
-	0x00, 0x00, 0xc4, 0x11, 0x00, 0x00, 0x00, 0x0c, 0x0b, 0x40, 0x90, 0x92,
-	0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0x39,
-	0x00, 0x00, 0xc4, 0x11, 0x00, 0x00, 0x00, 0x04, 0x6b, 0x41, 0x90, 0x94,
-	0x00, 0x00, 0xc4, 0x11, 0x12, 0x00, 0x00, 0x00, 0x09, 0x40, 0x20, 0xb2,
-	0x00, 0x00, 0xc5, 0x11, 0x12, 0x00, 0x00, 0x04, 0x09, 0x40, 0x20, 0xb2,
-	0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0xe4, 0x16, 0x38,
-	0x00, 0x00, 0xc9, 0x11, 0x9f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
-	0x00, 0x00, 0xc8, 0x11, 0x12, 0x00, 0x00, 0x08, 0x09, 0x40, 0x20, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
-	0x02, 0x00, 0xc4, 0x11, 0x04, 0x01, 0x00, 0xbc, 0x0f, 0x24, 0x17, 0xb8,
-	0x06, 0x00, 0xc2, 0x11, 0x04, 0x00, 0x00, 0xbc, 0x0f, 0x64, 0x16, 0xb8,
-	0x00, 0x00, 0xbd, 0x11, 0x04, 0x00, 0x00, 0x80, 0x22, 0xc0, 0xfb, 0xbc,
-	0x20, 0x00, 0xc4, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xfb, 0xbc,
-	0x00, 0x00, 0xd7, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
-	0xd1, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x82, 0xcd, 0xf9, 0x3a,
-	0x00, 0x00, 0xb7, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xf7, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xf8, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xfc, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x04, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x03, 0x32,
-	0x40, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x80, 0x2a, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x40, 0x90, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0xde, 0x11, 0x9f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x80, 0x90, 0x32,
-	0x00, 0x00, 0xde, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0x01, 0x00, 0xb4,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0x32,
-	0x00, 0x00, 0xe0, 0x11, 0x12, 0x00, 0x00, 0x9c, 0x0f, 0xc0, 0x21, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x7e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0f, 0x00, 0x7e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x0f, 0x00, 0x7e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07, 0x00, 0xfa, 0x52,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
-	0x4c, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x80, 0x2a, 0x32,
-	0x00, 0x00, 0xad, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
-	0x00, 0x00, 0xb3, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xcb, 0xc1, 0xb0, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0xef, 0x0f, 0x00, 0x00, 0x00, 0x28, 0x09, 0xc0, 0xb0, 0xd2,
-	0x00, 0x00, 0xeb, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x92, 0xb2,
-	0x00, 0x00, 0xef, 0x11, 0x12, 0x00, 0x00, 0x9c, 0x0f, 0xc0, 0x21, 0xb2,
-	0x02, 0x00, 0xf2, 0x11, 0x04, 0x01, 0x00, 0xb4, 0x8f, 0x4d, 0xfb, 0xb0,
-	0x00, 0x00, 0xc4, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x1f, 0x40, 0xfb, 0x35,
-	0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x03, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x03, 0x00, 0x00, 0x34,
-	0x00, 0x00, 0xeb, 0x11, 0x00, 0x00, 0x00, 0x0c, 0x8b, 0xc1, 0xb0, 0x94,
-	0x00, 0x00, 0xbb, 0x12, 0x00, 0x08, 0x00, 0x00, 0x07, 0x40, 0xfa, 0x92,
-	0x00, 0x00, 0xad, 0x12, 0x00, 0x08, 0x00, 0x00, 0x07, 0x40, 0xfa, 0xd2,
-	0x00, 0x00, 0xf9, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0x01, 0x00, 0xb4,
-	0x00, 0x00, 0xb4, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
-	0x00, 0x00, 0xbd, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x36, 0x32,
-	0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0xb0, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x12, 0x00, 0x2a, 0x3a,
-	0x00, 0x00, 0xff, 0x11, 0x04, 0x01, 0x00, 0x9c, 0x1f, 0xc0, 0xf9, 0xbc,
-	0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xba, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x0c, 0x12, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0xfa, 0xb2,
-	0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x0e, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
-	0x00, 0x00, 0x1b, 0x12, 0x00, 0x00, 0x00, 0x84, 0x02, 0x00, 0x00, 0xd2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0x3c, 0x32,
-	0x00, 0x00, 0x08, 0x12, 0x8e, 0x01, 0x00, 0x80, 0x02, 0x40, 0x28, 0xb2,
-	0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x0f, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xf7, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x8f, 0x4d, 0xfa, 0x3a,
-	0x00, 0x00, 0xf7, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x00, 0x32,
-	0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xac, 0x0f, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x20, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
-	0x08, 0x00, 0x10, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xf9, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x00, 0x32,
-	0x0e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xac, 0x0f, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x20, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
-	0x0b, 0x00, 0x14, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xf9, 0xbc,
-	0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x36, 0x32,
-	0x0f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xac, 0x0f, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x20, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
-	0x27, 0x00, 0x18, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xf9, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x00, 0x32,
-	0x0f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xac, 0x0f, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x20, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
-	0x20, 0x00, 0x1d, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xf9, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0xc0, 0xf9, 0x32,
-	0x0d, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0xc0, 0xfa, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x3e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x9c, 0x1f, 0xc0, 0xf9, 0x5a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0xc0, 0xf9, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x3e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x1f, 0xc0, 0xf9, 0x3a,
-	0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xac, 0x8f, 0xcd, 0xf9, 0x50,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x2b, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x3e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x12, 0x00, 0x2b, 0x3a,
-	0x0f, 0x00, 0x2b, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0x0d, 0x2b, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x3e, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xb0, 0x02, 0xc0, 0xf9, 0x52,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x3a, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x3a, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x3a, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0x3a, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x2b, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x3d, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x3d, 0x32,
-	0x00, 0x00, 0x36, 0x12, 0x84, 0x01, 0x00, 0xb0, 0x12, 0x00, 0x2b, 0xba,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xb0, 0x02, 0xc0, 0xf9, 0x52,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x00, 0x32,
-	0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x73, 0x3e, 0x00, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x30, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x1f, 0xc0, 0xf9, 0x3a,
-	0x70, 0x00, 0x3b, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xf9, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x30, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x30, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0f, 0xc0, 0x29, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0xc0, 0xf9, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x0f, 0xc0, 0x2c, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0xfa, 0x32,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x73, 0x7e, 0xfa, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x30, 0x32,
-	0x00, 0x00, 0x44, 0x12, 0x85, 0x01, 0x00, 0x9c, 0x1f, 0xc0, 0xf9, 0xba,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
-	0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x25, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
-	0x0e, 0x00, 0x53, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xfa, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x4d, 0x12, 0x00, 0x00, 0x00, 0x9c, 0x3f, 0xc0, 0xf9, 0x9a,
-	0x1c, 0x00, 0x4d, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xfa, 0xbc,
-	0x02, 0x00, 0x25, 0x12, 0x00, 0x00, 0x00, 0x9c, 0x8f, 0xcd, 0xf9, 0xda,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
-	0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x37, 0x32,
-	0x00, 0x00, 0x25, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
-	0x0e, 0x00, 0x5b, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xfa, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x57, 0x12, 0x00, 0x00, 0x00, 0x9c, 0x1f, 0xc0, 0xf9, 0x9a,
-	0x26, 0x00, 0x57, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xfa, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x0f, 0x40, 0x29, 0x32,
-	0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x4c, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
-	0x00, 0x00, 0x56, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
-	0x00, 0x00, 0x29, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x18, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0f, 0x00, 0x00, 0x32,
-	0xa2, 0x60, 0x03, 0x00, 0x00, 0x00, 0x00, 0x58, 0x03, 0x00, 0x37, 0x32,
-	0x6b, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x03, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x80, 0x2a, 0x32,
-	0x00, 0x00, 0x6b, 0x12, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x29, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x83, 0x3e, 0x00, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x83, 0x3e, 0x00, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x53, 0x0a, 0x00, 0x34,
-	0x00, 0x00, 0x6c, 0x12, 0x00, 0x00, 0x00, 0x88, 0x0f, 0x40, 0x2b, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0f, 0x00, 0x28, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0x0f, 0x00, 0x29, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x0f, 0x80, 0x2a, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0xc0, 0xf9, 0x32,
-	0x71, 0x12, 0x97, 0x12, 0x00, 0x00, 0x00, 0xb0, 0x0f, 0x00, 0x36, 0x92,
-	0x07, 0x00, 0x74, 0x12, 0x04, 0x00, 0x00, 0x80, 0x82, 0x4d, 0x29, 0xbc,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x00, 0xfa, 0x3a,
-	0x00, 0x00, 0x68, 0x12, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x80, 0x2a, 0x92,
-	0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x0f, 0x00, 0x36, 0x32,
-	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x84, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
-	0x1f, 0x00, 0x7a, 0x12, 0x04, 0x00, 0x00, 0x80, 0x82, 0xcd, 0x29, 0xbc,
-	0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x8f, 0xcd, 0xfa, 0x3a,
-	0x00, 0x00, 0x76, 0x12, 0x00, 0x00, 0x00, 0x9c, 0x12, 0xc0, 0x29, 0x9a,
-	0x00, 0x00, 0x3a, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
-	0x00, 0x00, 0x30, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
-	0x00, 0x00, 0x82, 0x12, 0x04, 0x00, 0x00, 0x80, 0x52, 0x8a, 0xfa, 0xbc,
-	0xa2, 0x60, 0x03, 0x00, 0x00, 0x00, 0x00, 0x58, 0x03, 0x00, 0x37, 0x32,
-	0x82, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x03, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xa3, 0x3e, 0x00, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0xa3, 0x3e, 0x00, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x53, 0x0a, 0x00, 0x34,
-	0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x0f, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0xf7, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x02, 0xc0, 0xfa, 0x32,
-	0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x0f, 0x40, 0x2f, 0x32,
-	0x00, 0x00, 0x8b, 0x12, 0x04, 0x00, 0x00, 0x9c, 0x1f, 0xc0, 0xf9, 0xbc,
-	0x00, 0x00, 0x8a, 0x12, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x2f, 0xb2,
-	0x00, 0x00, 0x87, 0x12, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x2c, 0x92,
-	0x00, 0x00, 0x87, 0x12, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x2c, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x2c, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0x2c, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x2d, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x2d, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x2d, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0x2d, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0xfb, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x2f, 0x32,
-	0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x02, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xe0, 0x07, 0x80, 0x3f, 0x52,
-	0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x03, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0xf9, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x28, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0xf8, 0x32,
-	0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x0f, 0xc0, 0x2b, 0x32,
-	0x00, 0x00, 0xa0, 0x12, 0x04, 0x00, 0x00, 0x9c, 0x1f, 0xc0, 0xf9, 0xbc,
-	0x00, 0x00, 0x9f, 0x12, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x2b, 0xb2,
-	0x00, 0x00, 0x9c, 0x12, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0x28, 0x92,
-	0x00, 0x00, 0x9c, 0x12, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x36, 0x92,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0xf9, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x29, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x29, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0x29, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x2a, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x2a, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0xf9, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0x2a, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x2b, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x2b, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x2b, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0xfb, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x02, 0x00, 0xfb, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0xb1, 0x12, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x07, 0x40, 0x90, 0x52,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x80, 0x90, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x07, 0x40, 0x90, 0x52,
-	0x00, 0x00, 0xb3, 0x12, 0x12, 0x00, 0x00, 0x48, 0xf2, 0x01, 0x00, 0xb4,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0x32,
-	0x00, 0x00, 0xb5, 0x12, 0x12, 0x00, 0x00, 0x9c, 0x0f, 0xc0, 0x21, 0xb2,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x0f, 0x40, 0xfb, 0x35,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
-	0x4c, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x80, 0x2a, 0x32,
-	0x00, 0x00, 0xad, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
-	0x00, 0x00, 0xb3, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xcb, 0xc1, 0xb0, 0x34,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
-	0x00, 0x00, 0xc4, 0x12, 0x00, 0x00, 0x00, 0x28, 0x09, 0xc0, 0xb0, 0xd2,
-	0x00, 0x00, 0xbe, 0x12, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x92, 0xb2,
-	0x00, 0x00, 0xc2, 0x12, 0x12, 0x00, 0x00, 0x9c, 0x0f, 0xc0, 0x21, 0xb2,
-	0x00, 0x00, 0xc4, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x32,
-	0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0x39,
-	0x00, 0x00, 0xc8, 0x12, 0x04, 0x01, 0x00, 0x28, 0x09, 0x34, 0xb0, 0xba,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x28, 0x09, 0x00, 0x00, 0x52,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x22, 0x00, 0x2b, 0x37,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0xc0, 0x37, 0xac, 0xb0, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0b, 0x00, 0x00, 0x32,
-	0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x4d, 0xb0, 0x30,
-	0x00, 0x00, 0xd8, 0x12, 0x80, 0x00, 0x00, 0x80, 0x02, 0x40, 0xb0, 0xb6,
-	0x00, 0x00, 0xcd, 0x12, 0x12, 0x00, 0x00, 0x00, 0x09, 0x40, 0x20, 0xb2,
-	0x00, 0x00, 0xce, 0x12, 0x12, 0x00, 0x00, 0x04, 0x09, 0x40, 0x20, 0xb2,
-	0x00, 0x00, 0xd1, 0x12, 0x9f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
-	0x00, 0x00, 0xd0, 0x12, 0x12, 0x00, 0x00, 0x08, 0x09, 0x40, 0x20, 0xb2,
-	0x0d, 0x00, 0xcd, 0x12, 0x04, 0x01, 0x00, 0x80, 0x02, 0xe4, 0x16, 0xb8,
-	0x02, 0x00, 0xcd, 0x12, 0x04, 0x01, 0x00, 0xbc, 0x0f, 0x24, 0x17, 0xb8,
-	0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x0f, 0x64, 0x16, 0x38,
-	0x00, 0x00, 0xcd, 0x12, 0x04, 0x01, 0x00, 0x80, 0x22, 0xc0, 0xfb, 0xbc,
-	0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0x39,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x3b, 0x40, 0xb0, 0x33,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xcd, 0x4a, 0xd0, 0x35,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x25, 0x01, 0x32,
-	0x00, 0x42, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x2a, 0x3a,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x00, 0xb0, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0xd0, 0x32,
-	0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x48, 0xf2, 0xc1, 0x38, 0x54,
-	0x00, 0x00, 0xdc, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-},
-{
-	0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-},
-};
diff --git a/drivers/staging/sxg/sxg.c b/drivers/staging/sxg/sxg.c
index 1e0cfcd..0050a02 100644
--- a/drivers/staging/sxg/sxg.c
+++ b/drivers/staging/sxg/sxg.c
@@ -30,6 +30,8 @@
  * are those of the authors and should not be interpreted as representing
  * official policies, either expressed or implied, of Alacritech, Inc.
  *
+ * Parts developed by LinSysSoft Sahara team
+ *
  **************************************************************************/
 
 /*
@@ -46,6 +48,7 @@
 #include <linux/errno.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/firmware.h>
 #include <linux/ioport.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
@@ -61,101 +64,122 @@
 #include <linux/types.h>
 #include <linux/dma-mapping.h>
 #include <linux/mii.h>
+#include <linux/ip.h>
+#include <linux/in.h>
+#include <linux/tcp.h>
+#include <linux/ipv6.h>
 
-#define SLIC_DUMP_ENABLED		0
 #define SLIC_GET_STATS_ENABLED		0
 #define LINUX_FREES_ADAPTER_RESOURCES	1
 #define SXG_OFFLOAD_IP_CHECKSUM		0
 #define SXG_POWER_MANAGEMENT_ENABLED	0
 #define VPCI				0
-#define DBG				1
 #define ATK_DEBUG			1
+#define SXG_UCODE_DEBUG		0
+
 
 #include "sxg_os.h"
 #include "sxghw.h"
 #include "sxghif.h"
 #include "sxg.h"
 #include "sxgdbg.h"
-
-#include "sxgphycode.h"
-#include "saharadbgdownload.h"
+#include "sxgphycode-1.2.h"
 
 static int sxg_allocate_buffer_memory(struct adapter_t *adapter, u32 Size,
-				      enum SXG_BUFFER_TYPE BufferType);
-static void sxg_allocate_rcvblock_complete(struct adapter_t *adapter, void *RcvBlock,
-					   dma_addr_t PhysicalAddress,
-					   u32 Length);
+				      enum sxg_buffer_type BufferType);
+static int sxg_allocate_rcvblock_complete(struct adapter_t *adapter,
+						void *RcvBlock,
+						dma_addr_t PhysicalAddress,
+						u32 Length);
 static void sxg_allocate_sgl_buffer_complete(struct adapter_t *adapter,
-					     struct SXG_SCATTER_GATHER *SxgSgl,
+					     struct sxg_scatter_gather *SxgSgl,
 					     dma_addr_t PhysicalAddress,
 					     u32 Length);
 
 static void sxg_mcast_init_crc32(void);
-
-static int sxg_entry_open(p_net_device dev);
-static int sxg_entry_halt(p_net_device dev);
-static int sxg_ioctl(p_net_device dev, struct ifreq *rq, int cmd);
-static int sxg_send_packets(struct sk_buff *skb, p_net_device dev);
+static int sxg_entry_open(struct net_device *dev);
+static int sxg_second_open(struct net_device * dev);
+static int sxg_entry_halt(struct net_device *dev);
+static int sxg_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static int sxg_send_packets(struct sk_buff *skb, struct net_device *dev);
 static int sxg_transmit_packet(struct adapter_t *adapter, struct sk_buff *skb);
-static void sxg_dumb_sgl(struct SCATTER_GATHER_LIST *pSgl, struct SXG_SCATTER_GATHER *SxgSgl);
+static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl,
+				struct sxg_scatter_gather *SxgSgl);
 
-static void sxg_handle_interrupt(struct adapter_t *adapter);
+static void sxg_handle_interrupt(struct adapter_t *adapter, int *work_done,
+					 int budget);
+static void sxg_interrupt(struct adapter_t *adapter);
+static int sxg_poll(struct napi_struct *napi, int budget);
 static int sxg_process_isr(struct adapter_t *adapter, u32 MessageId);
-static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId);
+static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId,
+			 int *sxg_napi_continue, int *work_done, int budget);
 static void sxg_complete_slow_send(struct adapter_t *adapter);
-static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter, struct SXG_EVENT *Event);
+static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter,
+					struct sxg_event *Event);
 static void sxg_process_rcv_error(struct adapter_t *adapter, u32 ErrorStatus);
 static bool sxg_mac_filter(struct adapter_t *adapter,
 			   struct ether_header *EtherHdr, ushort length);
+static struct net_device_stats *sxg_get_stats(struct net_device * dev);
+void sxg_free_resources(struct adapter_t *adapter);
+void sxg_free_rcvblocks(struct adapter_t *adapter);
+void sxg_free_sgl_buffers(struct adapter_t *adapter);
+void sxg_unmap_resources(struct adapter_t *adapter);
+void sxg_free_mcast_addrs(struct adapter_t *adapter);
+void sxg_collect_statistics(struct adapter_t *adapter);
+static int sxg_register_interrupt(struct adapter_t *adapter);
+static void sxg_remove_isr(struct adapter_t *adapter);
+static irqreturn_t sxg_isr(int irq, void *dev_id);
 
-#if SLIC_GET_STATS_ENABLED
-static struct net_device_stats *sxg_get_stats(p_net_device dev);
-#endif
+static void sxg_watchdog(unsigned long data);
+static void sxg_update_link_status (struct work_struct *work);
 
 #define XXXTODO 0
 
 #if XXXTODO
-static int sxg_mac_set_address(p_net_device dev, void *ptr);
-static void sxg_mcast_set_list(p_net_device dev);
+static int sxg_mac_set_address(struct net_device *dev, void *ptr);
 #endif
+static void sxg_mcast_set_list(struct net_device *dev);
 
-static void sxg_adapter_set_hwaddr(struct adapter_t *adapter);
-
-static void sxg_unmap_mmio_space(struct adapter_t *adapter);
+static int sxg_adapter_set_hwaddr(struct adapter_t *adapter);
 
 static int sxg_initialize_adapter(struct adapter_t *adapter);
 static void sxg_stock_rcv_buffers(struct adapter_t *adapter);
 static void sxg_complete_descriptor_blocks(struct adapter_t *adapter,
 					   unsigned char Index);
+int sxg_change_mtu (struct net_device *netdev, int new_mtu);
 static int sxg_initialize_link(struct adapter_t *adapter);
 static int sxg_phy_init(struct adapter_t *adapter);
 static void sxg_link_event(struct adapter_t *adapter);
 static enum SXG_LINK_STATE sxg_get_link_state(struct adapter_t *adapter);
-static void sxg_link_state(struct adapter_t *adapter, enum SXG_LINK_STATE LinkState);
+static void sxg_link_state(struct adapter_t *adapter,
+				enum SXG_LINK_STATE LinkState);
 static int sxg_write_mdio_reg(struct adapter_t *adapter,
 			      u32 DevAddr, u32 RegAddr, u32 Value);
 static int sxg_read_mdio_reg(struct adapter_t *adapter,
 			     u32 DevAddr, u32 RegAddr, u32 *pValue);
+static void sxg_set_mcast_addr(struct adapter_t *adapter);
 
 static unsigned int sxg_first_init = 1;
 static char *sxg_banner =
-    "Alacritech SLIC Technology(tm) Server and Storage 10Gbe Accelerator (Non-Accelerated)\n";
+    "Alacritech SLIC Technology(tm) Server and Storage \
+	 10Gbe Accelerator (Non-Accelerated)\n";
 
 static int sxg_debug = 1;
 static int debug = -1;
-static p_net_device head_netdevice = NULL;
+static struct net_device *head_netdevice = NULL;
 
-static struct sxgbase_driver_t sxg_global = {
+static struct sxgbase_driver sxg_global = {
 	.dynamic_intagg = 1,
 };
 static int intagg_delay = 100;
 static u32 dynamic_intagg = 0;
 
-#define DRV_NAME	"sxg"
-#define DRV_VERSION	"1.0.1"
+char sxg_driver_name[] = "sxg_nic";
 #define DRV_AUTHOR	"Alacritech, Inc. Engineering"
-#define DRV_DESCRIPTION	"Alacritech SLIC Techonology(tm) Non-Accelerated 10Gbe Driver"
-#define DRV_COPYRIGHT	"Copyright 2000-2008 Alacritech, Inc.  All rights reserved."
+#define DRV_DESCRIPTION							\
+	"Alacritech SLIC Techonology(tm) Non-Accelerated 10Gbe Driver"
+#define DRV_COPYRIGHT							\
+	"Copyright 2000-2008 Alacritech, Inc.  All rights reserved."
 
 MODULE_AUTHOR(DRV_AUTHOR);
 MODULE_DESCRIPTION(DRV_DESCRIPTION);
@@ -173,12 +197,6 @@
 
 MODULE_DEVICE_TABLE(pci, sxg_pci_tbl);
 
-/***********************************************************************
-************************************************************************
-************************************************************************
-************************************************************************
-************************************************************************/
-
 static inline void sxg_reg32_write(void __iomem *reg, u32 value, bool flush)
 {
 	writel(value, reg);
@@ -225,17 +243,143 @@
 }
 
 /* SXG Globals */
-static struct SXG_DRIVER SxgDriver;
+static struct sxg_driver SxgDriver;
 
 #ifdef  ATKDBG
-static struct sxg_trace_buffer_t LSxgTraceBuffer;
+static struct sxg_trace_buffer LSxgTraceBuffer;
 #endif /* ATKDBG */
-static struct sxg_trace_buffer_t *SxgTraceBuffer = NULL;
+static struct sxg_trace_buffer *SxgTraceBuffer = NULL;
+
+/*
+ * MSI Related API's
+ */
+int sxg_register_intr(struct adapter_t *adapter);
+int sxg_enable_msi_x(struct adapter_t *adapter);
+int sxg_add_msi_isr(struct adapter_t *adapter);
+void sxg_remove_msix_isr(struct adapter_t *adapter);
+int sxg_set_interrupt_capability(struct adapter_t *adapter);
+
+int sxg_set_interrupt_capability(struct adapter_t *adapter)
+{
+	int ret;
+
+	ret = sxg_enable_msi_x(adapter);
+	if (ret != STATUS_SUCCESS) {
+		adapter->msi_enabled = FALSE;
+		DBG_ERROR("sxg_set_interrupt_capability MSI-X Disable\n");
+	} else {
+		adapter->msi_enabled = TRUE;
+		DBG_ERROR("sxg_set_interrupt_capability MSI-X Enable\n");
+	}
+	return ret;
+}
+
+int sxg_register_intr(struct adapter_t *adapter)
+{
+	int ret = 0;
+
+	if (adapter->msi_enabled) {
+		ret = sxg_add_msi_isr(adapter);
+	}
+	else {
+		DBG_ERROR("MSI-X Enable Failed. Using Pin INT\n");
+		ret = sxg_register_interrupt(adapter);
+		if (ret != STATUS_SUCCESS) {
+			DBG_ERROR("sxg_register_interrupt Failed\n");
+		}
+	}
+	return ret;
+}
+
+int sxg_enable_msi_x(struct adapter_t *adapter)
+{
+	int ret;
+
+	adapter->nr_msix_entries = 1;
+	adapter->msi_entries =  kmalloc(adapter->nr_msix_entries *
+					sizeof(struct msix_entry),GFP_KERNEL);
+	if (!adapter->msi_entries) {
+		DBG_ERROR("%s:MSI Entries memory allocation Failed\n",__func__);
+		return -ENOMEM;
+	}
+	memset(adapter->msi_entries, 0, adapter->nr_msix_entries *
+		sizeof(struct msix_entry));
+
+	ret = pci_enable_msix(adapter->pcidev, adapter->msi_entries,
+				adapter->nr_msix_entries);
+	if (ret) {
+		DBG_ERROR("Enabling MSI-X with %d vectors failed\n",
+				adapter->nr_msix_entries);
+		/*Should try with less vector returned.*/
+		kfree(adapter->msi_entries);
+		return STATUS_FAILURE; /*MSI-X Enable failed.*/
+	}
+	return (STATUS_SUCCESS);
+}
+
+int sxg_add_msi_isr(struct adapter_t *adapter)
+{
+	int ret,i;
+
+	if (!adapter->intrregistered) {
+		for (i=0; i<adapter->nr_msix_entries; i++) {
+			ret = request_irq (adapter->msi_entries[i].vector,
+					sxg_isr,
+					IRQF_SHARED,
+					adapter->netdev->name,
+					adapter->netdev);
+			if (ret) {
+				DBG_ERROR("sxg: MSI-X request_irq (%s) "
+					"FAILED [%x]\n", adapter->netdev->name,
+					 ret);
+				return (ret);
+			}
+		}
+	}
+	adapter->msi_enabled = TRUE;
+	adapter->intrregistered = 1;
+	adapter->IntRegistered = TRUE;
+	return (STATUS_SUCCESS);
+}
+
+void sxg_remove_msix_isr(struct adapter_t *adapter)
+{
+	int i,vector;
+	struct net_device *netdev = adapter->netdev;
+
+	for(i=0; i< adapter->nr_msix_entries;i++)
+	{
+		vector = adapter->msi_entries[i].vector;
+		DBG_ERROR("%s : Freeing IRQ vector#%d\n",__FUNCTION__,vector);
+		free_irq(vector,netdev);
+	}
+}
+
+
+static void sxg_remove_isr(struct adapter_t *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	if (adapter->msi_enabled)
+		sxg_remove_msix_isr(adapter);
+	else
+		free_irq(adapter->netdev->irq, netdev);
+}
+
+void sxg_reset_interrupt_capability(struct adapter_t *adapter)
+{
+	if (adapter->msi_enabled) {
+		pci_disable_msix(adapter->pcidev);
+		kfree(adapter->msi_entries);
+		adapter->msi_entries = NULL;
+	}
+	return;
+}
 
 /*
  * sxg_download_microcode
  *
- * Download Microcode to Sahara adapter
+ * Download Microcode to Sahara adapter using the Linux
+ * Firmware module to get the ucode.sys file.
  *
  * Arguments -
  *		adapter		- A pointer to our adapter structure
@@ -244,98 +388,141 @@
  * Return
  *	int
  */
-static bool sxg_download_microcode(struct adapter_t *adapter, enum SXG_UCODE_SEL UcodeSel)
+static bool sxg_download_microcode(struct adapter_t *adapter,
+						enum SXG_UCODE_SEL UcodeSel)
 {
-	struct SXG_HW_REGS *HwRegs = adapter->HwRegs;
+	const struct firmware *fw;
+	const char *file = "";
+	struct sxg_hw_regs *HwRegs = adapter->HwRegs;
+	int ret;
+	int ucode_start;
 	u32 Section;
 	u32 ThisSectionSize;
-	u32 *Instruction = NULL;
+	u32 instruction = 0;
 	u32 BaseAddress, AddressOffset, Address;
-/*      u32                         Failure; */
+	/* u32 Failure; */
 	u32 ValueRead;
 	u32 i;
-	u32 numSections = 0;
+	u32 index = 0;
+	u32 num_sections = 0;
 	u32 sectionSize[16];
 	u32 sectionStart[16];
 
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DnldUcod",
 		  adapter, 0, 0, 0);
-	DBG_ERROR("sxg: %s ENTER\n", __func__);
 
-	switch (UcodeSel) {
-	case SXG_UCODE_SAHARA:	/* Sahara operational ucode */
-		numSections = SNumSections;
-		for (i = 0; i < numSections; i++) {
-			sectionSize[i] = SSectionSize[i];
-			sectionStart[i] = SSectionStart[i];
-		}
-		break;
-	default:
-		printk(KERN_ERR KBUILD_MODNAME
-		       ": Woah, big error with the microcode!\n");
-		break;
+	/*
+	 *  This routine is only implemented to download the microcode
+	 *  for the Revision B Sahara chip.  Rev A and Diagnostic
+	 *  microcode is not supported at this time.  If Rev A or
+	 *  diagnostic ucode is required, this routine will obviously
+	 *  need to change.  Also, eventually need to add support for
+	 *  Rev B checked version of ucode.  That's easy enough once
+	 *  the free version of Rev B works.
+	 */
+	ASSERT(UcodeSel == SXG_UCODE_SYSTEM);
+	ASSERT(adapter->asictype == SAHARA_REV_B);
+#if SXG_UCODE_DEBUG
+	file = "sxg/saharadbgdownloadB.sys";
+#else
+	file = "sxg/saharadownloadB.sys";
+#endif
+	ret = request_firmware(&fw, file, &adapter->pcidev->dev);
+	if (ret) {
+		DBG_ERROR("%s SXG_NIC: Failed to load firmware %s\n", __func__,file);
+		return ret;
 	}
 
-	DBG_ERROR("sxg: RESET THE CARD\n");
+	/*
+	 *  The microcode .sys file contains starts with a 4 byte word containing
+	 *  the number of sections. That is followed by "num_sections" 4 byte
+	 *  words containing each "section" size.  That is followed num_sections
+	 *  4 byte words containing each section "start" address.
+	 *
+	 *  Following the above header, the .sys file contains num_sections,
+	 *  where each section size is specified, newline delineatetd 12 byte
+	 *  microcode instructions.
+	 */
+	num_sections = *(u32 *)(fw->data + index);
+	index += 4;
+	ASSERT(num_sections <= 3);
+	for (i = 0; i < num_sections; i++) {
+		sectionSize[i] = *(u32 *)(fw->data + index);
+		index += 4;
+	}
+	for (i = 0; i < num_sections; i++) {
+		sectionStart[i] = *(u32 *)(fw->data + index);
+		index += 4;
+	}
+
 	/* First, reset the card */
 	WRITE_REG(HwRegs->Reset, 0xDEAD, FLUSH);
+	udelay(50);
+	HwRegs = adapter->HwRegs;
 
-	/* Download each section of the microcode as specified in */
-	/* its download file.  The *download.c file is generated using */
-	/* the saharaobjtoc facility which converts the metastep .obj */
-	/* file to a .c file which contains a two dimentional array. */
-	for (Section = 0; Section < numSections; Section++) {
-		DBG_ERROR("sxg: SECTION # %d\n", Section);
-		switch (UcodeSel) {
-		case SXG_UCODE_SAHARA:
-			Instruction = (u32 *) & SaharaUCode[Section][0];
-			break;
-		default:
-			ASSERT(0);
-			break;
-		}
+	/*
+	 * Download each section of the microcode as specified in
+	 * sectionSize[index] to sectionStart[index] address.  As
+	 * described above, the .sys file contains 12 byte word
+	 * microcode instructions. The *download.sys file is generated
+	 * using the objtosys.exe utility that was built for Sahara
+	 * microcode.
+	 */
+	/* See usage of this below when we read back for parity */
+	ucode_start = index;
+	instruction = *(u32 *)(fw->data + index);
+	index += 4;
+
+	for (Section = 0; Section < num_sections; Section++) {
 		BaseAddress = sectionStart[Section];
-		ThisSectionSize = sectionSize[Section] / 12;	/* Size in instructions */
+		/* Size in instructions */
+		ThisSectionSize = sectionSize[Section] / 12;
 		for (AddressOffset = 0; AddressOffset < ThisSectionSize;
 		     AddressOffset++) {
+			u32 first_instr = 0;  /* See comment below */
+
 			Address = BaseAddress + AddressOffset;
 			ASSERT((Address & ~MICROCODE_ADDRESS_MASK) == 0);
-			/* Write instruction bits 31 - 0 */
-			WRITE_REG(HwRegs->UcodeDataLow, *Instruction, FLUSH);
-			/* Write instruction bits 63-32 */
-			WRITE_REG(HwRegs->UcodeDataMiddle, *(Instruction + 1),
-				  FLUSH);
-			/* Write instruction bits 95-64 */
-			WRITE_REG(HwRegs->UcodeDataHigh, *(Instruction + 2),
-				  FLUSH);
+			/* Write instruction bits 31 - 0 (low) */
+			first_instr = instruction;
+			WRITE_REG(HwRegs->UcodeDataLow, instruction, FLUSH);
+			instruction = *(u32 *)(fw->data + index);
+			index += 4;  /* Advance to the "next" instruction */
+
+			/* Write instruction bits 63-32 (middle) */
+			WRITE_REG(HwRegs->UcodeDataMiddle, instruction, FLUSH);
+			instruction = *(u32 *)(fw->data + index);
+			index += 4;  /* Advance to the "next" instruction */
+
+			/* Write instruction bits 95-64 (high) */
+			WRITE_REG(HwRegs->UcodeDataHigh, instruction, FLUSH);
+			instruction = *(u32 *)(fw->data + index);
+			index += 4;  /* Advance to the "next" instruction */
+
 			/* Write instruction address with the WRITE bit set */
 			WRITE_REG(HwRegs->UcodeAddr,
 				  (Address | MICROCODE_ADDRESS_WRITE), FLUSH);
-			/* Sahara bug in the ucode download logic - the write to DataLow */
-			/* for the next instruction could get corrupted.  To avoid this, */
-			/* write to DataLow again for this instruction (which may get */
-			/* corrupted, but it doesn't matter), then increment the address */
-			/* and write the data for the next instruction to DataLow.  That */
-			/* write should succeed. */
-			WRITE_REG(HwRegs->UcodeDataLow, *Instruction, TRUE);
-			/* Advance 3 u32S to start of next instruction */
-			Instruction += 3;
+			/*
+			 * Sahara bug in the ucode download logic - the write to DataLow
+			 * for the next instruction could get corrupted.  To avoid this,
+			 * write to DataLow again for this instruction (which may get
+			 * corrupted, but it doesn't matter), then increment the address
+			 * and write the data for the next instruction to DataLow.  That
+			 * write should succeed.
+			 */
+			WRITE_REG(HwRegs->UcodeDataLow, first_instr, FLUSH);
 		}
 	}
-	/* Now repeat the entire operation reading the instruction back and */
-	/* checking for parity errors */
-	for (Section = 0; Section < numSections; Section++) {
-		DBG_ERROR("sxg: check SECTION # %d\n", Section);
-		switch (UcodeSel) {
-		case SXG_UCODE_SAHARA:
-			Instruction = (u32 *) & SaharaUCode[Section][0];
-			break;
-		default:
-			ASSERT(0);
-			break;
-		}
+	/*
+	 * Now repeat the entire operation reading the instruction back and
+	 * checking for parity errors
+	 */
+	index = ucode_start;
+
+	for (Section = 0; Section < num_sections; Section++) {
 		BaseAddress = sectionStart[Section];
-		ThisSectionSize = sectionSize[Section] / 12;	/* Size in instructions */
+		/* Size in instructions */
+		ThisSectionSize = sectionSize[Section] / 12;
 		for (AddressOffset = 0; AddressOffset < ThisSectionSize;
 		     AddressOffset++) {
 			Address = BaseAddress + AddressOffset;
@@ -348,62 +535,70 @@
 				DBG_ERROR("sxg: %s PARITY ERROR\n",
 					  __func__);
 
-				return (FALSE);	/* Parity error */
+				return FALSE;	/* Parity error */
 			}
 			ASSERT((ValueRead & MICROCODE_ADDRESS_MASK) == Address);
 			/* Read the instruction back and compare */
+			/* First instruction */
+			instruction = *(u32 *)(fw->data + index);
+			index += 4;
 			READ_REG(HwRegs->UcodeDataLow, ValueRead);
-			if (ValueRead != *Instruction) {
+			if (ValueRead != instruction) {
 				DBG_ERROR("sxg: %s MISCOMPARE LOW\n",
 					  __func__);
-				return (FALSE);	/* Miscompare */
+				return FALSE;	/* Miscompare */
 			}
+			instruction = *(u32 *)(fw->data + index);
+			index += 4;
 			READ_REG(HwRegs->UcodeDataMiddle, ValueRead);
-			if (ValueRead != *(Instruction + 1)) {
+			if (ValueRead != instruction) {
 				DBG_ERROR("sxg: %s MISCOMPARE MIDDLE\n",
 					  __func__);
-				return (FALSE);	/* Miscompare */
+				return FALSE;	/* Miscompare */
 			}
+			instruction = *(u32 *)(fw->data + index);
+			index += 4;
 			READ_REG(HwRegs->UcodeDataHigh, ValueRead);
-			if (ValueRead != *(Instruction + 2)) {
+			if (ValueRead != instruction) {
 				DBG_ERROR("sxg: %s MISCOMPARE HIGH\n",
 					  __func__);
-				return (FALSE);	/* Miscompare */
+				return FALSE;	/* Miscompare */
 			}
-			/* Advance 3 u32S to start of next instruction */
-			Instruction += 3;
 		}
 	}
 
+	/* download finished */
+	release_firmware(fw);
 	/* Everything OK, Go. */
 	WRITE_REG(HwRegs->UcodeAddr, MICROCODE_ADDRESS_GO, FLUSH);
 
-	/* Poll the CardUp register to wait for microcode to initialize */
-	/* Give up after 10,000 attemps (500ms). */
+	/*
+	 * Poll the CardUp register to wait for microcode to initialize
+	 * Give up after 10,000 attemps (500ms).
+	 */
 	for (i = 0; i < 10000; i++) {
 		udelay(50);
 		READ_REG(adapter->UcodeRegs[0].CardUp, ValueRead);
 		if (ValueRead == 0xCAFE) {
-			DBG_ERROR("sxg: %s BOO YA 0xCAFE\n", __func__);
 			break;
 		}
 	}
 	if (i == 10000) {
-		DBG_ERROR("sxg: %s TIMEOUT\n", __func__);
+		DBG_ERROR("sxg: %s TIMEOUT bringing up card - verify MICROCODE\n", __func__);
 
-		return (FALSE);	/* Timeout */
+		return FALSE;	/* Timeout */
 	}
-	/* Now write the LoadSync register.  This is used to */
-	/* synchronize with the card so it can scribble on the memory */
-	/* that contained 0xCAFE from the "CardUp" step above */
-	if (UcodeSel == SXG_UCODE_SAHARA) {
+	/*
+	 * Now write the LoadSync register.  This is used to
+	 * synchronize with the card so it can scribble on the memory
+	 * that contained 0xCAFE from the "CardUp" step above
+	 */
+	if (UcodeSel == SXG_UCODE_SYSTEM) {
 		WRITE_REG(adapter->UcodeRegs[0].LoadSync, 0, FLUSH);
 	}
 
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDnldUcd",
 		  adapter, 0, 0, 0);
-	DBG_ERROR("sxg: %s EXIT\n", __func__);
-
 	return (TRUE);
 }
 
@@ -411,18 +606,16 @@
  * sxg_allocate_resources - Allocate memory and locks
  *
  * Arguments -
- *	adapter		- A pointer to our adapter structure
+ *	adapter	- A pointer to our adapter structure
  *
- * Return
- *	int
+ * Return - int
  */
 static int sxg_allocate_resources(struct adapter_t *adapter)
 {
-	int status;
-	u32 i;
+	int status = STATUS_SUCCESS;
 	u32 RssIds, IsrCount;
-/*      struct SXG_XMT_RING                                   *XmtRing; */
-/*      struct SXG_RCV_RING                                   *RcvRing; */
+	/* struct sxg_xmt_ring	*XmtRing; */
+	/* struct sxg_rcv_ring	*RcvRing; */
 
 	DBG_ERROR("%s ENTER\n", __func__);
 
@@ -432,7 +625,7 @@
 	/* Windows tells us how many CPUs it plans to use for */
 	/* RSS */
 	RssIds = SXG_RSS_CPU_COUNT(adapter);
-	IsrCount = adapter->MsiEnabled ? RssIds : 1;
+	IsrCount = adapter->msi_enabled ? RssIds : 1;
 
 	DBG_ERROR("%s Setup the spinlocks\n", __func__);
 
@@ -442,6 +635,7 @@
 	spin_lock_init(&adapter->XmtZeroLock);
 	spin_lock_init(&adapter->Bit64RegLock);
 	spin_lock_init(&adapter->AdapterLock);
+	atomic_set(&adapter->pending_allocations, 0);
 
 	DBG_ERROR("%s Setup the lists\n", __func__);
 
@@ -451,62 +645,82 @@
 	InitializeListHead(&adapter->FreeSglBuffers);
 	InitializeListHead(&adapter->AllSglBuffers);
 
-	/* Mark these basic allocations done.  This flags essentially */
-	/* tells the SxgFreeResources routine that it can grab spinlocks */
-	/* and reference listheads. */
+	/*
+	 * Mark these basic allocations done.  This flags essentially
+	 * tells the SxgFreeResources routine that it can grab spinlocks
+	 * and reference listheads.
+	 */
 	adapter->BasicAllocations = TRUE;
-	/* Main allocation loop.  Start with the maximum supported by */
-	/* the microcode and back off if memory allocation */
-	/* fails.  If we hit a minimum, fail. */
+	/*
+	 * Main allocation loop.  Start with the maximum supported by
+	 * the microcode and back off if memory allocation
+	 * fails.  If we hit a minimum, fail.
+	 */
 
 	for (;;) {
 		DBG_ERROR("%s Allocate XmtRings size[%x]\n", __func__,
-			  (unsigned int)(sizeof(struct SXG_XMT_RING) * 1));
+			  (unsigned int)(sizeof(struct sxg_xmt_ring) * 1));
 
-		/* Start with big items first - receive and transmit rings.  At the moment */
-		/* I'm going to keep the ring size fixed and adjust the number of */
-		/* TCBs if we fail.  Later we might consider reducing the ring size as well.. */
+		/*
+		 * Start with big items first - receive and transmit rings.
+		 * At the moment I'm going to keep the ring size fixed and
+		 * adjust the TCBs if we fail.  Later we might
+		 * consider reducing the ring size as well..
+		 */
 		adapter->XmtRings = pci_alloc_consistent(adapter->pcidev,
-							 sizeof(struct SXG_XMT_RING) *
-							 1,
-							 &adapter->PXmtRings);
+						 sizeof(struct sxg_xmt_ring) *
+						 1,
+						 &adapter->PXmtRings);
 		DBG_ERROR("%s XmtRings[%p]\n", __func__, adapter->XmtRings);
 
 		if (!adapter->XmtRings) {
 			goto per_tcb_allocation_failed;
 		}
-		memset(adapter->XmtRings, 0, sizeof(struct SXG_XMT_RING) * 1);
+		memset(adapter->XmtRings, 0, sizeof(struct sxg_xmt_ring) * 1);
 
 		DBG_ERROR("%s Allocate RcvRings size[%x]\n", __func__,
-			  (unsigned int)(sizeof(struct SXG_RCV_RING) * 1));
+			  (unsigned int)(sizeof(struct sxg_rcv_ring) * 1));
 		adapter->RcvRings =
 		    pci_alloc_consistent(adapter->pcidev,
-					 sizeof(struct SXG_RCV_RING) * 1,
+					 sizeof(struct sxg_rcv_ring) * 1,
 					 &adapter->PRcvRings);
 		DBG_ERROR("%s RcvRings[%p]\n", __func__, adapter->RcvRings);
 		if (!adapter->RcvRings) {
 			goto per_tcb_allocation_failed;
 		}
-		memset(adapter->RcvRings, 0, sizeof(struct SXG_RCV_RING) * 1);
+		memset(adapter->RcvRings, 0, sizeof(struct sxg_rcv_ring) * 1);
+		adapter->ucode_stats = kzalloc(sizeof(struct sxg_ucode_stats), GFP_ATOMIC);
+		adapter->pucode_stats = pci_map_single(adapter->pcidev,
+						adapter->ucode_stats,
+						sizeof(struct sxg_ucode_stats),
+						PCI_DMA_FROMDEVICE);
+//		memset(adapter->ucode_stats, 0, sizeof(struct sxg_ucode_stats));
 		break;
 
 	      per_tcb_allocation_failed:
 		/* an allocation failed.  Free any successful allocations. */
 		if (adapter->XmtRings) {
 			pci_free_consistent(adapter->pcidev,
-					    sizeof(struct SXG_XMT_RING) * 4096,
+					    sizeof(struct sxg_xmt_ring) * 1,
 					    adapter->XmtRings,
 					    adapter->PXmtRings);
 			adapter->XmtRings = NULL;
 		}
 		if (adapter->RcvRings) {
 			pci_free_consistent(adapter->pcidev,
-					    sizeof(struct SXG_RCV_RING) * 4096,
+					    sizeof(struct sxg_rcv_ring) * 1,
 					    adapter->RcvRings,
 					    adapter->PRcvRings);
 			adapter->RcvRings = NULL;
 		}
 		/* Loop around and try again.... */
+		if (adapter->ucode_stats) {
+			pci_unmap_single(adapter->pcidev,
+					sizeof(struct sxg_ucode_stats),
+					adapter->pucode_stats, PCI_DMA_FROMDEVICE);
+			adapter->ucode_stats = NULL;
+		}
+
 	}
 
 	DBG_ERROR("%s Initialize RCV ZERO and XMT ZERO rings\n", __func__);
@@ -515,53 +729,37 @@
 	SXG_INITIALIZE_RING(adapter->XmtRingZeroInfo, SXG_XMT_RING_SIZE);
 
 	/* Sanity check receive data structure format */
-	ASSERT((adapter->ReceiveBufferSize == SXG_RCV_DATA_BUFFER_SIZE) ||
-	       (adapter->ReceiveBufferSize == SXG_RCV_JUMBO_BUFFER_SIZE));
-	ASSERT(sizeof(struct SXG_RCV_DESCRIPTOR_BLOCK) ==
+	/* ASSERT((adapter->ReceiveBufferSize == SXG_RCV_DATA_BUFFER_SIZE) ||
+	       (adapter->ReceiveBufferSize == SXG_RCV_JUMBO_BUFFER_SIZE)); */
+	ASSERT(sizeof(struct sxg_rcv_descriptor_block) ==
 	       SXG_RCV_DESCRIPTOR_BLOCK_SIZE);
 
-	/* Allocate receive data buffers.  We allocate a block of buffers and */
-	/* a corresponding descriptor block at once.  See sxghw.h:SXG_RCV_BLOCK */
-	for (i = 0; i < SXG_INITIAL_RCV_DATA_BUFFERS;
-	     i += SXG_RCV_DESCRIPTORS_PER_BLOCK) {
-		sxg_allocate_buffer_memory(adapter,
-					   SXG_RCV_BLOCK_SIZE(adapter->
-							      ReceiveBufferSize),
-					   SXG_BUFFER_TYPE_RCV);
-	}
-	/* NBL resource allocation can fail in the 'AllocateComplete' routine, which */
-	/* doesn't return status.  Make sure we got the number of buffers we requested */
-	if (adapter->FreeRcvBufferCount < SXG_INITIAL_RCV_DATA_BUFFERS) {
-		SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF6",
-			  adapter, adapter->FreeRcvBufferCount, SXG_MAX_ENTRIES,
-			  0);
-		return (STATUS_RESOURCES);
-	}
-
 	DBG_ERROR("%s Allocate EventRings size[%x]\n", __func__,
-		  (unsigned int)(sizeof(struct SXG_EVENT_RING) * RssIds));
+		  (unsigned int)(sizeof(struct sxg_event_ring) * RssIds));
 
 	/* Allocate event queues. */
 	adapter->EventRings = pci_alloc_consistent(adapter->pcidev,
-						   sizeof(struct SXG_EVENT_RING) *
-						   RssIds,
-						   &adapter->PEventRings);
+					   sizeof(struct sxg_event_ring) *
+					   RssIds,
+					   &adapter->PEventRings);
 
 	if (!adapter->EventRings) {
-		/* Caller will call SxgFreeAdapter to clean up above allocations */
+		/* Caller will call SxgFreeAdapter to clean up above
+		 * allocations */
 		SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF8",
 			  adapter, SXG_MAX_ENTRIES, 0, 0);
 		status = STATUS_RESOURCES;
 		goto per_tcb_allocation_failed;
 	}
-	memset(adapter->EventRings, 0, sizeof(struct SXG_EVENT_RING) * RssIds);
+	memset(adapter->EventRings, 0, sizeof(struct sxg_event_ring) * RssIds);
 
 	DBG_ERROR("%s Allocate ISR size[%x]\n", __func__, IsrCount);
 	/* Allocate ISR */
 	adapter->Isr = pci_alloc_consistent(adapter->pcidev,
 					    IsrCount, &adapter->PIsr);
 	if (!adapter->Isr) {
-		/* Caller will call SxgFreeAdapter to clean up above allocations */
+		/* Caller will call SxgFreeAdapter to clean up above
+		 * allocations */
 		SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF9",
 			  adapter, SXG_MAX_ENTRIES, 0, 0);
 		status = STATUS_RESOURCES;
@@ -588,8 +786,7 @@
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlcResS",
 		  adapter, SXG_MAX_ENTRIES, 0, 0);
 
-	DBG_ERROR("%s EXIT\n", __func__);
-	return (STATUS_SUCCESS);
+	return status;
 }
 
 /*
@@ -599,7 +796,6 @@
  *
  * Arguments -
  *		pcidev			- A pointer to our adapter structure
- *
  */
 static void sxg_config_pci(struct pci_dev *pcidev)
 {
@@ -609,12 +805,19 @@
 	pci_read_config_word(pcidev, PCI_COMMAND, &pci_command);
 	DBG_ERROR("sxg: %s  PCI command[%4.4x]\n", __func__, pci_command);
 	/* Set the command register */
-	new_command = pci_command | (PCI_COMMAND_MEMORY |	/* Memory Space Enable */
-				     PCI_COMMAND_MASTER |	/* Bus master enable */
-				     PCI_COMMAND_INVALIDATE |	/* Memory write and invalidate */
-				     PCI_COMMAND_PARITY |	/* Parity error response */
-				     PCI_COMMAND_SERR |	/* System ERR */
-				     PCI_COMMAND_FAST_BACK);	/* Fast back-to-back */
+	new_command = pci_command | (
+				     /* Memory Space Enable */
+				     PCI_COMMAND_MEMORY |
+				     /* Bus master enable */
+				     PCI_COMMAND_MASTER |
+			     	     /* Memory write and invalidate */
+				     PCI_COMMAND_INVALIDATE |
+				     /* Parity error response */
+				     PCI_COMMAND_PARITY |
+				     /* System ERR */
+				     PCI_COMMAND_SERR |
+				     /* Fast back-to-back */
+				     PCI_COMMAND_FAST_BACK);
 	if (pci_command != new_command) {
 		DBG_ERROR("%s -- Updating PCI COMMAND register %4.4x->%4.4x.\n",
 			  __func__, pci_command, new_command);
@@ -622,6 +825,77 @@
 	}
 }
 
+/*
+ * sxg_read_config
+ * 	@adapter : Pointer to the adapter structure for the card
+ * This function will read the configuration data from EEPROM/FLASH
+ */
+static inline int sxg_read_config(struct adapter_t *adapter)
+{
+	/* struct sxg_config	data; */
+  	struct sxg_config	*config;
+	struct sw_cfg_data	*data;
+	dma_addr_t		p_addr;
+	unsigned long		status;
+	unsigned long		i;
+ 	config = pci_alloc_consistent(adapter->pcidev,
+ 					sizeof(struct sxg_config), &p_addr);
+
+  	if(!config) {
+		/*
+		 * We cant get even this much memory. Raise a hell
+ 		 * Get out of here
+ 		 */
+		printk(KERN_ERR"%s : Could not allocate memory for reading \
+				 EEPROM\n", __FUNCTION__);
+		return -ENOMEM;
+	}
+
+	data = &config->SwCfg;
+
+    /* Initialize (reflective memory) status register */
+	WRITE_REG(adapter->UcodeRegs[0].ConfigStat, SXG_CFG_TIMEOUT, TRUE);
+
+    /* Send request to fetch configuration data */
+	WRITE_REG64(adapter, adapter->UcodeRegs[0].Config, p_addr, 0);
+	for(i=0; i<1000; i++) {
+		READ_REG(adapter->UcodeRegs[0].ConfigStat, status);
+		if (status != SXG_CFG_TIMEOUT)
+			break;
+		mdelay(1);			/* Do we really need this */
+	}
+
+	switch(status) {
+	/* Config read from EEPROM succeeded */
+	case SXG_CFG_LOAD_EEPROM:
+	/* Config read from Flash succeeded */
+	case SXG_CFG_LOAD_FLASH:
+		/*
+		 * Copy the MAC address to adapter structure
+		 * TODO: We are not doing the remaining part : FRU, etc
+		 */
+		memcpy(adapter->macaddr, data->MacAddr[0].MacAddr,
+			sizeof(struct sxg_config_mac));
+		break;
+	case SXG_CFG_TIMEOUT:
+	case SXG_CFG_LOAD_INVALID:
+	case SXG_CFG_LOAD_ERROR:
+	default:	/* Fix default handler later */
+		printk(KERN_WARNING"%s  : We could not read the config \
+			word. Status = %ld\n", __FUNCTION__, status);
+		break;
+	}
+	pci_free_consistent(adapter->pcidev, sizeof(struct sw_cfg_data), data,
+				p_addr);
+	if (adapter->netdev) {
+		memcpy(adapter->netdev->dev_addr, adapter->currmacaddr, 6);
+		memcpy(adapter->netdev->perm_addr, adapter->currmacaddr, 6);
+	}
+	sxg_dbg_macaddrs(adapter);
+
+	return status;
+}
+
 static int sxg_entry_probe(struct pci_dev *pcidev,
 			   const struct pci_device_id *pci_tbl_entry)
 {
@@ -633,6 +907,7 @@
 	u32 status = 0;
 	ulong mmio_start = 0;
 	ulong mmio_len = 0;
+	unsigned char revision_id;
 
 	DBG_ERROR("sxg: %s 2.6 VERSION ENTER jiffies[%lx] cpu %d\n",
 		  __func__, jiffies, smp_processor_id());
@@ -654,9 +929,11 @@
 
 	if (sxg_debug > 0 && did_version++ == 0) {
 		printk(KERN_INFO "%s\n", sxg_banner);
-		printk(KERN_INFO "%s\n", DRV_VERSION);
+		printk(KERN_INFO "%s\n", SXG_DRV_VERSION);
 	}
 
+	pci_read_config_byte(pcidev, PCI_REVISION_ID, &revision_id);
+
 	if (!(err = pci_set_dma_mask(pcidev, DMA_64BIT_MASK))) {
 		DBG_ERROR("pci_set_dma_mask(DMA_64BIT_MASK) successful\n");
 	} else {
@@ -671,7 +948,7 @@
 
 	DBG_ERROR("Call pci_request_regions\n");
 
-	err = pci_request_regions(pcidev, DRV_NAME);
+	err = pci_request_regions(pcidev, sxg_driver_name);
 	if (err) {
 		DBG_ERROR("pci_request_regions FAILED err[%x]\n", err);
 		return err;
@@ -692,6 +969,15 @@
 
 	pci_set_drvdata(pcidev, netdev);
 	adapter = netdev_priv(netdev);
+	if (revision_id == 1) {
+		adapter->asictype = SAHARA_REV_A;
+	} else if (revision_id == 2) {
+		adapter->asictype = SAHARA_REV_B;
+	} else {
+		ASSERT(0);
+		DBG_ERROR("%s Unexpected revision ID %x\n", __FUNCTION__, revision_id);
+		goto err_out_exit_sxg_probe;
+	}
 	adapter->netdev = netdev;
 	adapter->pcidev = pcidev;
 
@@ -707,12 +993,12 @@
 	if (!memmapped_ioaddr) {
 		DBG_ERROR("%s cannot remap MMIO region %lx @ %lx\n",
 			  __func__, mmio_len, mmio_start);
-		goto err_out_free_mmio_region;
+		goto err_out_free_mmio_region_0;
 	}
 
-	DBG_ERROR
-	    ("sxg: %s found Alacritech SXG PCI, MMIO at %p, start[%lx] len[%lx], IRQ %d.\n",
-	     __func__, memmapped_ioaddr, mmio_start, mmio_len, pcidev->irq);
+	DBG_ERROR("sxg: %s found Alacritech SXG PCI, MMIO at %p, start[%lx] \
+	      len[%lx], IRQ %d.\n", __func__, memmapped_ioaddr, mmio_start,
+					      mmio_len, pcidev->irq);
 
 	adapter->HwRegs = (void *)memmapped_ioaddr;
 	adapter->base_addr = memmapped_ioaddr;
@@ -729,7 +1015,7 @@
 	if (!memmapped_ioaddr) {
 		DBG_ERROR("%s cannot remap MMIO region %lx @ %lx\n",
 			  __func__, mmio_len, mmio_start);
-		goto err_out_free_mmio_region;
+		goto err_out_free_mmio_region_2;
 	}
 
 	DBG_ERROR("sxg: %s found Alacritech SXG PCI, MMIO at %p, "
@@ -739,8 +1025,10 @@
 	adapter->UcodeRegs = (void *)memmapped_ioaddr;
 
 	adapter->State = SXG_STATE_INITIALIZING;
-	/* Maintain a list of all adapters anchored by */
-	/* the global SxgDriver structure. */
+	/*
+	 * Maintain a list of all adapters anchored by
+	 * the global SxgDriver structure.
+	 */
 	adapter->Next = SxgDriver.Adapters;
 	SxgDriver.Adapters = adapter;
 	adapter->AdapterID = ++SxgDriver.AdapterID;
@@ -758,10 +1046,12 @@
 		adapter->ReceiveBufferSize = SXG_RCV_DATA_BUFFER_SIZE;
 	}
 
-/*    status = SXG_READ_EEPROM(adapter); */
-/*    if (!status) { */
-/*        goto sxg_init_bad; */
-/*    } */
+	/*
+	 *    status = SXG_READ_EEPROM(adapter);
+	 *    if (!status) {
+	 *        goto sxg_init_bad;
+	 *    }
+	 */
 
 	DBG_ERROR("sxg: %s ENTER sxg_config_pci\n", __func__);
 	sxg_config_pci(pcidev);
@@ -774,16 +1064,13 @@
 	adapter->vendid = pci_tbl_entry->vendor;
 	adapter->devid = pci_tbl_entry->device;
 	adapter->subsysid = pci_tbl_entry->subdevice;
-	adapter->busnumber = pcidev->bus->number;
 	adapter->slotnumber = ((pcidev->devfn >> 3) & 0x1F);
 	adapter->functionnumber = (pcidev->devfn & 0x7);
 	adapter->memorylength = pci_resource_len(pcidev, 0);
 	adapter->irq = pcidev->irq;
 	adapter->next_netdevice = head_netdevice;
 	head_netdevice = netdev;
-/*      adapter->chipid = chip_idx; */
 	adapter->port = 0;	/*adapter->functionnumber; */
-	adapter->cardindex = adapter->port;
 
 	/* Allocate memory and other resources */
 	DBG_ERROR("sxg: %s ENTER sxg_allocate_resources\n", __func__);
@@ -795,10 +1082,11 @@
 	}
 
 	DBG_ERROR("sxg: %s ENTER sxg_download_microcode\n", __func__);
-	if (sxg_download_microcode(adapter, SXG_UCODE_SAHARA)) {
+	if (sxg_download_microcode(adapter, SXG_UCODE_SYSTEM)) {
 		DBG_ERROR("sxg: %s ENTER sxg_adapter_set_hwaddr\n",
 			  __func__);
-		sxg_adapter_set_hwaddr(adapter);
+		sxg_read_config(adapter);
+		status = sxg_adapter_set_hwaddr(adapter);
 	} else {
 		adapter->state = ADAPT_FAIL;
 		adapter->linkstate = LINK_DOWN;
@@ -811,40 +1099,63 @@
 	netdev->stop = sxg_entry_halt;
 	netdev->hard_start_xmit = sxg_send_packets;
 	netdev->do_ioctl = sxg_ioctl;
+	netdev->change_mtu = sxg_change_mtu;
 #if XXXTODO
 	netdev->set_mac_address = sxg_mac_set_address;
-#if SLIC_GET_STATS_ENABLED
+#endif
 	netdev->get_stats = sxg_get_stats;
-#endif
 	netdev->set_multicast_list = sxg_mcast_set_list;
-#endif
+	SET_ETHTOOL_OPS(netdev, &sxg_nic_ethtool_ops);
+ 	netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+	err = sxg_set_interrupt_capability(adapter);
+	if (err != STATUS_SUCCESS)
+		DBG_ERROR("Cannot enable MSI-X capability\n");
 
 	strcpy(netdev->name, "eth%d");
-/*  strcpy(netdev->name, pci_name(pcidev)); */
+	/*  strcpy(netdev->name, pci_name(pcidev)); */
 	if ((err = register_netdev(netdev))) {
 		DBG_ERROR("Cannot register net device, aborting. %s\n",
 			  netdev->name);
 		goto err_out_unmap;
 	}
 
+	netif_napi_add(netdev, &adapter->napi,
+		sxg_poll, SXG_NETDEV_WEIGHT);
+	netdev->watchdog_timeo = 2 * HZ;
+	init_timer(&adapter->watchdog_timer);
+	adapter->watchdog_timer.function = &sxg_watchdog;
+	adapter->watchdog_timer.data = (unsigned long) adapter;
+	INIT_WORK(&adapter->update_link_status, sxg_update_link_status);
+
 	DBG_ERROR
-	    ("sxg: %s addr 0x%lx, irq %d, MAC addr %02X:%02X:%02X:%02X:%02X:%02X\n",
+	    ("sxg: %s addr 0x%lx, irq %d, MAC addr \
+		%02X:%02X:%02X:%02X:%02X:%02X\n",
 	     netdev->name, netdev->base_addr, pcidev->irq, netdev->dev_addr[0],
 	     netdev->dev_addr[1], netdev->dev_addr[2], netdev->dev_addr[3],
 	     netdev->dev_addr[4], netdev->dev_addr[5]);
 
-/*sxg_init_bad: */
+	/* sxg_init_bad: */
 	ASSERT(status == FALSE);
-/*      sxg_free_adapter(adapter); */
+	/* sxg_free_adapter(adapter); */
 
 	DBG_ERROR("sxg: %s EXIT status[%x] jiffies[%lx] cpu %d\n", __func__,
 		  status, jiffies, smp_processor_id());
 	return status;
 
       err_out_unmap:
-	iounmap((void *)memmapped_ioaddr);
+	sxg_free_resources(adapter);
 
-      err_out_free_mmio_region:
+      err_out_free_mmio_region_2:
+
+	mmio_start = pci_resource_start(pcidev, 2);
+        mmio_len = pci_resource_len(pcidev, 2);
+	release_mem_region(mmio_start, mmio_len);
+
+      err_out_free_mmio_region_0:
+
+        mmio_start = pci_resource_start(pcidev, 0);
+        mmio_len = pci_resource_len(pcidev, 0);
+
 	release_mem_region(mmio_start, mmio_len);
 
       err_out_exit_sxg_probe:
@@ -852,13 +1163,16 @@
 	DBG_ERROR("%s EXIT jiffies[%lx] cpu %d\n", __func__, jiffies,
 		  smp_processor_id());
 
+	pci_disable_device(pcidev);
+        DBG_ERROR("sxg: %s deallocate device\n", __FUNCTION__);
+        kfree(netdev);
+	printk("Exit %s, Sxg driver loading failed..\n", __FUNCTION__);
+
 	return -ENODEV;
 }
 
-/***********************************************************************
- * LINE BASE Interrupt routines..
- ***********************************************************************/
 /*
+ * LINE BASE Interrupt routines..
  *
  * sxg_disable_interrupt
  *
@@ -877,10 +1191,7 @@
 		  adapter, adapter->InterruptsEnabled, 0, 0);
 	/* For now, RSS is disabled with line based interrupts */
 	ASSERT(adapter->RssEnabled == FALSE);
-	ASSERT(adapter->MsiEnabled == FALSE);
-	/* */
 	/* Turn off interrupts by writing to the icr register. */
-	/* */
 	WRITE_REG(adapter->UcodeRegs[0].Icr, SXG_ICR(0, SXG_ICR_DISABLE), TRUE);
 
 	adapter->InterruptsEnabled = 0;
@@ -890,7 +1201,6 @@
 }
 
 /*
- *
  * sxg_enable_interrupt
  *
  * EnableInterrupt Handler
@@ -908,10 +1218,7 @@
 		  adapter, adapter->InterruptsEnabled, 0, 0);
 	/* For now, RSS is disabled with line based interrupts */
 	ASSERT(adapter->RssEnabled == FALSE);
-	ASSERT(adapter->MsiEnabled == FALSE);
-	/* */
 	/* Turn on interrupts by writing to the icr register. */
-	/* */
 	WRITE_REG(adapter->UcodeRegs[0].Icr, SXG_ICR(0, SXG_ICR_ENABLE), TRUE);
 
 	adapter->InterruptsEnabled = 1;
@@ -921,50 +1228,51 @@
 }
 
 /*
- *
  * sxg_isr - Process an line-based interrupt
  *
  * Arguments:
- * 		Context			- Our adapter structure
+ * 		Context		- Our adapter structure
  *		QueueDefault 	- Output parameter to queue to default CPU
- *		TargetCpus		- Output bitmap to schedule DPC's
+ *		TargetCpus	- Output bitmap to schedule DPC's
  *
- * Return Value:
- * 	TRUE if our interrupt
+ * Return Value: TRUE if our interrupt
  */
 static irqreturn_t sxg_isr(int irq, void *dev_id)
 {
-	p_net_device dev = (p_net_device) dev_id;
+	struct net_device *dev = (struct net_device *) dev_id;
 	struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev);
-/*      u32                 CpuMask = 0, i; */
 
+	if(adapter->state != ADAPT_UP)
+		return IRQ_NONE;
 	adapter->Stats.NumInts++;
 	if (adapter->Isr[0] == 0) {
-		/* The SLIC driver used to experience a number of spurious interrupts */
-		/* due to the delay associated with the masking of the interrupt */
-		/* (we'd bounce back in here).  If we see that again with Sahara, */
-		/* add a READ_REG of the Icr register after the WRITE_REG below. */
+		/*
+		 * The SLIC driver used to experience a number of spurious
+		 * interrupts due to the delay associated with the masking of
+		 * the interrupt (we'd bounce back in here).  If we see that
+		 * again with Sahara,add a READ_REG of the Icr register after
+		 * the WRITE_REG below.
+		 */
 		adapter->Stats.FalseInts++;
 		return IRQ_NONE;
 	}
-	/* */
-	/* Move the Isr contents and clear the value in */
-	/* shared memory, and mask interrupts */
-	/* */
-	adapter->IsrCopy[0] = adapter->Isr[0];
-	adapter->Isr[0] = 0;
-	WRITE_REG(adapter->UcodeRegs[0].Icr, SXG_ICR(0, SXG_ICR_MASK), TRUE);
-/*      ASSERT(adapter->IsrDpcsPending == 0); */
+	/*
+	 * Move the Isr contents and clear the value in
+	 * shared memory, and mask interrupts
+	 */
+	/* ASSERT(adapter->IsrDpcsPending == 0); */
 #if XXXTODO			/* RSS Stuff */
-	/* If RSS is enabled and the ISR specifies */
-	/* SXG_ISR_EVENT, then schedule DPC's */
-	/* based on event queues. */
+	/*
+	 * If RSS is enabled and the ISR specifies SXG_ISR_EVENT, then
+	 * schedule DPC's based on event queues.
+	 */
 	if (adapter->RssEnabled && (adapter->IsrCopy[0] & SXG_ISR_EVENT)) {
 		for (i = 0;
 		     i < adapter->RssSystemInfo->ProcessorInfo.RssCpuCount;
 		     i++) {
-			struct XG_EVENT_RING *EventRing = &adapter->EventRings[i];
-			struct SXG_EVENT *Event =
+			struct sxg_event_ring *EventRing =
+						&adapter->EventRings[i];
+			struct sxg_event *Event =
 			    &EventRing->Ring[adapter->NextEvent[i]];
 			unsigned char Cpu =
 			    adapter->RssSystemInfo->RssIdToCpu[i];
@@ -974,8 +1282,10 @@
 			}
 		}
 	}
-	/* Now, either schedule the CPUs specified by the CpuMask, */
-	/* or queue default */
+	/*
+	 * Now, either schedule the CPUs specified by the CpuMask,
+	 * or queue default
+	 */
 	if (CpuMask) {
 		*QueueDefault = FALSE;
 	} else {
@@ -984,34 +1294,41 @@
 	}
 	*TargetCpus = CpuMask;
 #endif
-	/* */
-	/*  There are no DPCs in Linux, so call the handler now */
-	/* */
-	sxg_handle_interrupt(adapter);
+	sxg_interrupt(adapter);
 
 	return IRQ_HANDLED;
 }
 
-static void sxg_handle_interrupt(struct adapter_t *adapter)
+static void sxg_interrupt(struct adapter_t *adapter)
 {
-/*    unsigned char           RssId   = 0; */
-	u32 NewIsr;
+	WRITE_REG(adapter->UcodeRegs[0].Icr, SXG_ICR(0, SXG_ICR_MASK), TRUE);
 
-	if (adapter->Stats.RcvNoBuffer < 5) {
-		DBG_ERROR("Enter sxg_handle_interrupt ISR[%x]\n",
-			  adapter->IsrCopy[0]);
+	if (napi_schedule_prep(&adapter->napi)) {
+		__napi_schedule(&adapter->napi);
 	}
+}
+
+static void sxg_handle_interrupt(struct adapter_t *adapter, int *work_done,
+					 int budget)
+{
+	/* unsigned char           RssId   = 0; */
+	u32 NewIsr;
+	int sxg_napi_continue = 1;
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "HndlIntr",
 		  adapter, adapter->IsrCopy[0], 0, 0);
 	/* For now, RSS is disabled with line based interrupts */
 	ASSERT(adapter->RssEnabled == FALSE);
-	ASSERT(adapter->MsiEnabled == FALSE);
-	ASSERT(adapter->IsrCopy[0]);
-/*/////////////////////////// */
+
+	adapter->IsrCopy[0] = adapter->Isr[0];
+	adapter->Isr[0] = 0;
 
 	/* Always process the event queue. */
-	sxg_process_event_queue(adapter,
-				(adapter->RssEnabled ? /*RssId */ 0 : 0));
+	while (sxg_napi_continue)
+	{
+		sxg_process_event_queue(adapter,
+				(adapter->RssEnabled ? /*RssId */ 0 : 0),
+				 &sxg_napi_continue, work_done, budget);
+	}
 
 #if XXXTODO			/* RSS stuff */
 	if (--adapter->IsrDpcsPending) {
@@ -1022,30 +1339,31 @@
 		return;
 	}
 #endif
-	/* */
 	/* Last (or only) DPC processes the ISR and clears the interrupt. */
-	/* */
 	NewIsr = sxg_process_isr(adapter, 0);
-	/* */
 	/* Reenable interrupts */
-	/* */
 	adapter->IsrCopy[0] = 0;
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "ClearIsr",
 		  adapter, NewIsr, 0, 0);
 
-	if (adapter->Stats.RcvNoBuffer < 5) {
-		DBG_ERROR
-		    ("Exit sxg_handle_interrupt2 after enabling interrupt\n");
-	}
-
-	WRITE_REG(adapter->UcodeRegs[0].Isr, NewIsr, TRUE);
-
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XHndlInt",
 		  adapter, 0, 0, 0);
 }
+static int sxg_poll(struct napi_struct *napi, int budget)
+{
+	struct adapter_t *adapter = container_of(napi, struct adapter_t, napi);
+	int work_done = 0;
+
+	sxg_handle_interrupt(adapter, &work_done, budget);
+
+	if (work_done < budget) {
+		napi_complete(napi);
+		WRITE_REG(adapter->UcodeRegs[0].Isr, 0, TRUE);
+	}
+	return work_done;
+}
 
 /*
- *
  * sxg_process_isr - Process an interrupt.  Called from the line-based and
  *			message based interrupt DPC routines
  *
@@ -1072,24 +1390,28 @@
 		}
 		/* No host buffer */
 		if (Isr & SXG_ISR_RMISS) {
-			/* There is a bunch of code in the SLIC driver which */
-			/* attempts to process more receive events per DPC */
-			/* if we start to fall behind.  We'll probably */
-			/* need to do something similar here, but hold */
-			/* off for now.  I don't want to make the code more */
-			/* complicated than strictly needed. */
-			adapter->Stats.RcvNoBuffer++;
-			if (adapter->Stats.RcvNoBuffer < 5) {
+			/*
+			 * There is a bunch of code in the SLIC driver which
+			 * attempts to process more receive events per DPC
+			 * if we start to fall behind.  We'll probablyd
+			 * need to do something similar here, but hold
+			 * off for now.  I don't want to make the code more
+			 * complicated than strictly needed.
+			 */
+			adapter->stats.rx_missed_errors++;
+ 			if (adapter->stats.rx_missed_errors< 5) {
 				DBG_ERROR("%s: SXG_ISR_ERR  RMISS!!\n",
 					  __func__);
 			}
 		}
 		/* Card crash */
 		if (Isr & SXG_ISR_DEAD) {
-			/* Set aside the crash info and set the adapter state to RESET */
-			adapter->CrashCpu =
-			    (unsigned char)((Isr & SXG_ISR_CPU) >>
-					    SXG_ISR_CPU_SHIFT);
+			/*
+			 * Set aside the crash info and set the adapter state
+ 			 * to RESET
+ 			 */
+			adapter->CrashCpu = (unsigned char)
+				((Isr & SXG_ISR_CPU) >> SXG_ISR_CPU_SHIFT);
 			adapter->CrashLocation = (ushort) (Isr & SXG_ISR_CRASH);
 			adapter->Dead = TRUE;
 			DBG_ERROR("%s: ISR_DEAD %x, CPU: %d\n", __func__,
@@ -1097,18 +1419,18 @@
 		}
 		/* Event ring full */
 		if (Isr & SXG_ISR_ERFULL) {
-			/* Same issue as RMISS, really.  This means the */
-			/* host is falling behind the card.  Need to increase */
-			/* event ring size, process more events per interrupt, */
-			/* and/or reduce/remove interrupt aggregation. */
+			/*
+			 * Same issue as RMISS, really.  This means the
+			 * host is falling behind the card.  Need to increase
+			 * event ring size, process more events per interrupt,
+			 * and/or reduce/remove interrupt aggregation.
+			 */
 			adapter->Stats.EventRingFull++;
 			DBG_ERROR("%s: SXG_ISR_ERR  EVENT RING FULL!!\n",
 				  __func__);
 		}
 		/* Transmit drop - no DRAM buffers or XMT error */
 		if (Isr & SXG_ISR_XDROP) {
-			adapter->Stats.XmtDrops++;
-			adapter->Stats.XmtErrors++;
 			DBG_ERROR("%s: SXG_ISR_ERR  XDROP!!\n", __func__);
 		}
 	}
@@ -1118,18 +1440,24 @@
 	}
 	/* Dump */
 	if (Isr & SXG_ISR_UPC) {
-		ASSERT(adapter->DumpCmdRunning);	/* Maybe change when debug is added.. */
+		/* Maybe change when debug is added.. */
+//		ASSERT(adapter->DumpCmdRunning);
 		adapter->DumpCmdRunning = FALSE;
 	}
 	/* Link event */
 	if (Isr & SXG_ISR_LINK) {
-		sxg_link_event(adapter);
+		if (adapter->state != ADAPT_DOWN) {
+			adapter->link_status_changed = 1;
+			schedule_work(&adapter->update_link_status);
+		}
 	}
 	/* Debug - breakpoint hit */
 	if (Isr & SXG_ISR_BREAK) {
-		/* At the moment AGDB isn't written to support interactive */
-		/* debug sessions.  When it is, this interrupt will be used */
-		/* to signal AGDB that it has hit a breakpoint.  For now, ASSERT. */
+		/*
+		 * At the moment AGDB isn't written to support interactive
+		 * debug sessions.  When it is, this interrupt will be used to
+		 * signal AGDB that it has hit a breakpoint.  For now, ASSERT.
+		 */
 		ASSERT(0);
 	}
 	/* Heartbeat response */
@@ -1143,7 +1471,33 @@
 }
 
 /*
+ * sxg_rcv_checksum - Set the checksum for received packet
  *
+ * Arguements:
+ * 		@adapter - Adapter structure on which packet is received
+ * 		@skb - Packet which is receieved
+ * 		@Event - Event read from hardware
+ */
+
+void sxg_rcv_checksum(struct adapter_t *adapter, struct sk_buff *skb,
+			 struct sxg_event *Event)
+{
+	skb->ip_summed = CHECKSUM_NONE;
+	if (likely(adapter->flags & SXG_RCV_IP_CSUM_ENABLED)) {
+		if (likely(adapter->flags & SXG_RCV_TCP_CSUM_ENABLED)
+			&& (Event->Status & EVENT_STATUS_TCPIP)) {
+			if(!(Event->Status & EVENT_STATUS_TCPBAD))
+				skb->ip_summed = CHECKSUM_UNNECESSARY;
+		if(!(Event->Status & EVENT_STATUS_IPBAD))
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
+		} else if(Event->Status & EVENT_STATUS_IPONLY) {
+			if(!(Event->Status & EVENT_STATUS_IPBAD))
+				skb->ip_summed = CHECKSUM_UNNECESSARY;
+		}
+	}
+}
+
+/*
  * sxg_process_event_queue - Process our event queue
  *
  * Arguments:
@@ -1153,46 +1507,52 @@
  * Return Value:
  * 	None.
  */
-static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId)
+static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId,
+			 int *sxg_napi_continue, int *work_done, int budget)
 {
-	struct SXG_EVENT_RING *EventRing = &adapter->EventRings[RssId];
-	struct SXG_EVENT *Event = &EventRing->Ring[adapter->NextEvent[RssId]];
+	struct sxg_event_ring *EventRing = &adapter->EventRings[RssId];
+	struct sxg_event *Event = &EventRing->Ring[adapter->NextEvent[RssId]];
 	u32 EventsProcessed = 0, Batches = 0;
-	u32 num_skbs = 0;
 	struct sk_buff *skb;
 #ifdef LINUX_HANDLES_RCV_INDICATION_LISTS
 	struct sk_buff *prev_skb = NULL;
 	struct sk_buff *IndicationList[SXG_RCV_ARRAYSIZE];
 	u32 Index;
-	struct SXG_RCV_DATA_BUFFER_HDR *RcvDataBufferHdr;
+	struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr;
 #endif
 	u32 ReturnStatus = 0;
+	int sxg_rcv_data_buffers = SXG_RCV_DATA_BUFFERS;
 
 	ASSERT((adapter->State == SXG_STATE_RUNNING) ||
 	       (adapter->State == SXG_STATE_PAUSING) ||
 	       (adapter->State == SXG_STATE_PAUSED) ||
 	       (adapter->State == SXG_STATE_HALTING));
-	/* We may still have unprocessed events on the queue if */
-	/* the card crashed.  Don't process them. */
+	/*
+	 * We may still have unprocessed events on the queue if
+	 * the card crashed.  Don't process them.
+	 */
 	if (adapter->Dead) {
 		return (0);
 	}
-	/* In theory there should only be a single processor that */
-	/* accesses this queue, and only at interrupt-DPC time.  So */
-	/* we shouldn't need a lock for any of this. */
+	/*
+	 *  In theory there should only be a single processor that
+	 * accesses this queue, and only at interrupt-DPC time.  So/
+	 * we shouldn't need a lock for any of this.
+	 */
 	while (Event->Status & EVENT_STATUS_VALID) {
+		(*sxg_napi_continue) = 1;
 		SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "Event",
 			  Event, Event->Code, Event->Status,
 			  adapter->NextEvent);
 		switch (Event->Code) {
 		case EVENT_CODE_BUFFERS:
-			ASSERT(!(Event->CommandIndex & 0xFF00));	/* SXG_RING_INFO Head & Tail == unsigned char */
-			/* */
+			/* struct sxg_ring_info Head & Tail == unsigned char */
+			ASSERT(!(Event->CommandIndex & 0xFF00));
 			sxg_complete_descriptor_blocks(adapter,
 						       Event->CommandIndex);
-			/* */
 			break;
 		case EVENT_CODE_SLOWRCV:
+			(*work_done)++;
 			--adapter->RcvBuffersOnCard;
 			if ((skb = sxg_slow_receive(adapter, Event))) {
 				u32 rx_bytes;
@@ -1200,51 +1560,61 @@
 				/* Add it to our indication list */
 				SXG_ADD_RCV_PACKET(adapter, skb, prev_skb,
 						   IndicationList, num_skbs);
-				/*  In Linux, we just pass up each skb to the protocol above at this point, */
-				/*  there is no capability of an indication list. */
+				/*
+				 * Linux, we just pass up each skb to the
+				 * protocol above at this point, there is no
+				 * capability of an indication list.
+				 */
 #else
-/* CHECK            skb_pull(skb, INIC_RCVBUF_HEADSIZE); */
-				rx_bytes = Event->Length;	/* (rcvbuf->length & IRHDDR_FLEN_MSK); */
-				skb_put(skb, rx_bytes);
+				/* CHECK skb_pull(skb, INIC_RCVBUF_HEADSIZE); */
+				/* (rcvbuf->length & IRHDDR_FLEN_MSK); */
+				rx_bytes = Event->Length;
 				adapter->stats.rx_packets++;
 				adapter->stats.rx_bytes += rx_bytes;
-#if SXG_OFFLOAD_IP_CHECKSUM
-				skb->ip_summed = CHECKSUM_UNNECESSARY;
-#endif
+				sxg_rcv_checksum(adapter, skb, Event);
 				skb->dev = adapter->netdev;
-				skb->protocol = eth_type_trans(skb, skb->dev);
-				netif_rx(skb);
+				netif_receive_skb(skb);
 #endif
 			}
 			break;
 		default:
 			DBG_ERROR("%s: ERROR  Invalid EventCode %d\n",
 				  __func__, Event->Code);
-/*                      ASSERT(0); */
+		/* ASSERT(0); */
 		}
-		/* See if we need to restock card receive buffers. */
-		/* There are two things to note here: */
-		/*      First - This test is not SMP safe.  The */
-		/*              adapter->BuffersOnCard field is protected via atomic interlocked calls, but */
-		/*              we do not protect it with respect to these tests.  The only way to do that */
-		/*      is with a lock, and I don't want to grab a lock every time we adjust the */
-		/*      BuffersOnCard count.  Instead, we allow the buffer replenishment to be off */
-		/*      once in a while.  The worst that can happen is the card is given one */
-		/*      more-or-less descriptor block than the arbitrary value we've chosen. */
-		/*      No big deal */
-		/*      In short DO NOT ADD A LOCK HERE, OR WHERE RcvBuffersOnCard is adjusted. */
-		/*      Second - We expect this test to rarely evaluate to true.  We attempt to */
-		/*      refill descriptor blocks as they are returned to us */
-		/*      (sxg_complete_descriptor_blocks), so The only time this should evaluate */
-		/*      to true is when sxg_complete_descriptor_blocks failed to allocate */
-		/*              receive buffers. */
-		if (adapter->RcvBuffersOnCard < SXG_RCV_DATA_BUFFERS) {
+		/*
+		 * See if we need to restock card receive buffers.
+		 * There are two things to note here:
+		 *  First - This test is not SMP safe.  The
+		 *    adapter->BuffersOnCard field is protected via atomic
+		 *    interlocked calls, but we do not protect it with respect
+		 *    to these tests.  The only way to do that is with a lock,
+		 *    and I don't want to grab a lock every time we adjust the
+		 *    BuffersOnCard count.  Instead, we allow the buffer
+		 *    replenishment to be off once in a while. The worst that
+		 *    can happen is the card is given on more-or-less descriptor
+		 *    block than the arbitrary value we've chosen. No big deal
+		 *    In short DO NOT ADD A LOCK HERE, OR WHERE RcvBuffersOnCard
+		 *    is adjusted.
+		 *  Second - We expect this test to rarely
+		 *    evaluate to true.  We attempt to refill descriptor blocks
+		 *    as they are returned to us (sxg_complete_descriptor_blocks)
+		 *    so The only time this should evaluate to true is when
+		 *    sxg_complete_descriptor_blocks failed to allocate
+		 *    receive buffers.
+		 */
+		if (adapter->JumboEnabled)
+			sxg_rcv_data_buffers = SXG_JUMBO_RCV_DATA_BUFFERS;
+
+		if (adapter->RcvBuffersOnCard < sxg_rcv_data_buffers) {
 			sxg_stock_rcv_buffers(adapter);
 		}
-		/* It's more efficient to just set this to zero. */
-		/* But clearing the top bit saves potential debug info... */
+		/*
+		 * It's more efficient to just set this to zero.
+		 * But clearing the top bit saves potential debug info...
+		 */
 		Event->Status &= ~EVENT_STATUS_VALID;
-		/* Advanct to the next event */
+		/* Advance to the next event */
 		SXG_ADVANCE_INDEX(adapter->NextEvent[RssId], EVENT_RING_SIZE);
 		Event = &EventRing->Ring[adapter->NextEvent[RssId]];
 		EventsProcessed++;
@@ -1253,9 +1623,11 @@
 			WRITE_REG(adapter->UcodeRegs[RssId].EventRelease,
 				  EVENT_RING_BATCH, FALSE);
 			EventsProcessed = 0;
-			/* If we've processed our batch limit, break out of the */
-			/* loop and return SXG_ISR_EVENT to arrange for us to */
-			/* be called again */
+			/*
+			 * If we've processed our batch limit, break out of the
+			 * loop and return SXG_ISR_EVENT to arrange for us to
+			 * be called again
+			 */
 			if (Batches++ == EVENT_BATCH_LIMIT) {
 				SXG_TRACE(TRACE_SXG, SxgTraceBuffer,
 					  TRACE_NOISY, "EvtLimit", Batches,
@@ -1264,16 +1636,22 @@
 				break;
 			}
 		}
+		if (*work_done >= budget) {
+			WRITE_REG(adapter->UcodeRegs[RssId].EventRelease,
+				  EventsProcessed, FALSE);
+			EventsProcessed = 0;
+			(*sxg_napi_continue) = 0;
+			break;
+		}
 	}
+	if (!(Event->Status & EVENT_STATUS_VALID))
+		(*sxg_napi_continue) = 0;
+
 #ifdef LINUX_HANDLES_RCV_INDICATION_LISTS
-	/* */
 	/* Indicate any received dumb-nic frames */
-	/* */
 	SXG_INDICATE_PACKETS(adapter, IndicationList, num_skbs);
 #endif
-	/* */
 	/* Release events back to the card. */
-	/* */
 	if (EventsProcessed) {
 		WRITE_REG(adapter->UcodeRegs[RssId].EventRelease,
 			  EventsProcessed, FALSE);
@@ -1289,27 +1667,35 @@
  *
  * Arguments -
  *	adapter		- A pointer to our adapter structure
-
  * Return
  *	None
  */
 static void sxg_complete_slow_send(struct adapter_t *adapter)
 {
-	struct SXG_XMT_RING *XmtRing = &adapter->XmtRings[0];
-	struct SXG_RING_INFO *XmtRingInfo = &adapter->XmtRingZeroInfo;
+	struct sxg_xmt_ring *XmtRing = &adapter->XmtRings[0];
+	struct sxg_ring_info *XmtRingInfo = &adapter->XmtRingZeroInfo;
 	u32 *ContextType;
-	struct SXG_CMD *XmtCmd;
+	struct sxg_cmd *XmtCmd;
+	unsigned long flags = 0;
+	unsigned long sgl_flags = 0;
+	unsigned int processed_count = 0;
 
-	/* NOTE - This lock is dropped and regrabbed in this loop. */
-	/* This means two different processors can both be running */
-	/* through this loop. Be *very* careful. */
-	spin_lock(&adapter->XmtZeroLock);
+	/*
+	 * NOTE - This lock is dropped and regrabbed in this loop.
+	 * This means two different processors can both be running/
+	 * through this loop. Be *very* careful.
+	 */
+	spin_lock_irqsave(&adapter->XmtZeroLock, flags);
+
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnds",
 		  adapter, XmtRingInfo->Head, XmtRingInfo->Tail, 0);
 
-	while (XmtRingInfo->Tail != *adapter->XmtRingZeroIndex) {
-		/* Locate the current Cmd (ring descriptor entry), and */
-		/* associated SGL, and advance the tail */
+	while ((XmtRingInfo->Tail != *adapter->XmtRingZeroIndex)
+		&& processed_count++ < SXG_COMPLETE_SLOW_SEND_LIMIT)  {
+		/*
+		 * Locate the current Cmd (ring descriptor entry), and
+		 * associated SGL, and advance the tail
+		 */
 		SXG_RETURN_CMD(XmtRing, XmtRingInfo, XmtCmd, ContextType);
 		ASSERT(ContextType);
 		SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnd",
@@ -1321,30 +1707,45 @@
 		case SXG_SGL_DUMB:
 			{
 				struct sk_buff *skb;
+				struct sxg_scatter_gather *SxgSgl =
+					(struct sxg_scatter_gather *)ContextType;
+				dma64_addr_t FirstSgeAddress;
+				u32 FirstSgeLength;
+
 				/* Dumb-nic send.  Command context is the dumb-nic SGL */
 				skb = (struct sk_buff *)ContextType;
+				skb = SxgSgl->DumbPacket;
+				FirstSgeAddress = XmtCmd->Buffer.FirstSgeAddress;
+				FirstSgeLength = XmtCmd->Buffer.FirstSgeLength;
 				/* Complete the send */
 				SXG_TRACE(TRACE_SXG, SxgTraceBuffer,
 					  TRACE_IMPORTANT, "DmSndCmp", skb, 0,
 					  0, 0);
 				ASSERT(adapter->Stats.XmtQLen);
-				adapter->Stats.XmtQLen--;	/* within XmtZeroLock */
-				adapter->Stats.XmtOk++;
-				/* Now drop the lock and complete the send back to */
-				/* Microsoft.  We need to drop the lock because */
-				/* Microsoft can come back with a chimney send, which */
-				/* results in a double trip in SxgTcpOuput */
-				spin_unlock(&adapter->XmtZeroLock);
-				SXG_COMPLETE_DUMB_SEND(adapter, skb);
+				/*
+				 * Now drop the lock and complete the send
+				 * back to Microsoft.  We need to drop the lock
+				 * because Microsoft can come back with a
+				 * chimney send, which results in a double trip
+				 * in SxgTcpOuput
+				 */
+				spin_unlock_irqrestore(
+					&adapter->XmtZeroLock, flags);
+
+				SxgSgl->DumbPacket = NULL;
+				SXG_COMPLETE_DUMB_SEND(adapter, skb,
+							FirstSgeAddress,
+							FirstSgeLength);
+				SXG_FREE_SGL_BUFFER(adapter, SxgSgl, NULL);
 				/* and reacquire.. */
-				spin_lock(&adapter->XmtZeroLock);
+				spin_lock_irqsave(&adapter->XmtZeroLock, flags);
 			}
 			break;
 		default:
 			ASSERT(0);
 		}
 	}
-	spin_unlock(&adapter->XmtZeroLock);
+	spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnd",
 		  adapter, XmtRingInfo->Head, XmtRingInfo->Tail, 0);
 }
@@ -1356,22 +1757,27 @@
  *	adapter		- A pointer to our adapter structure
  *	Event		- Receive event
  *
- * Return
- *	 skb
+ * Return - skb
  */
-static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter, struct SXG_EVENT *Event)
+static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter,
+						struct sxg_event *Event)
 {
-	struct SXG_RCV_DATA_BUFFER_HDR *RcvDataBufferHdr;
+	u32 BufferSize = adapter->ReceiveBufferSize;
+	struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr;
 	struct sk_buff *Packet;
+	static int read_counter = 0;
 
-	RcvDataBufferHdr = (struct SXG_RCV_DATA_BUFFER_HDR*) Event->HostHandle;
+	RcvDataBufferHdr = (struct sxg_rcv_data_buffer_hdr *) Event->HostHandle;
+	if(read_counter++ & 0x100)
+	{
+		sxg_collect_statistics(adapter);
+		read_counter = 0;
+	}
 	ASSERT(RcvDataBufferHdr);
 	ASSERT(RcvDataBufferHdr->State == SXG_BUFFER_ONCARD);
-	ASSERT(SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr) ==
-	       RcvDataBufferHdr->VirtualAddress);
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "SlowRcv", Event,
 		  RcvDataBufferHdr, RcvDataBufferHdr->State,
-		  RcvDataBufferHdr->VirtualAddress);
+		  /*RcvDataBufferHdr->VirtualAddress*/ 0);
 	/* Drop rcv frames in non-running state */
 	switch (adapter->State) {
 	case SXG_STATE_RUNNING:
@@ -1385,14 +1791,16 @@
 		goto drop;
 	}
 
+	/*
+	 * memcpy(SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr),
+	 * 		RcvDataBufferHdr->VirtualAddress, Event->Length);
+	 */
+
 	/* Change buffer state to UPSTREAM */
 	RcvDataBufferHdr->State = SXG_BUFFER_UPSTREAM;
 	if (Event->Status & EVENT_STATUS_RCVERR) {
 		SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "RcvError",
 			  Event, Event->Status, Event->HostHandle, 0);
-		/* XXXTODO - Remove this print later */
-		DBG_ERROR("SXG: Receive error %x\n", *(u32 *)
-			  SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr));
 		sxg_process_rcv_error(adapter, *(u32 *)
 				      SXG_RECEIVE_DATA_LOCATION
 				      (RcvDataBufferHdr));
@@ -1400,8 +1808,9 @@
 	}
 #if XXXTODO			/* VLAN stuff */
 	/* If there's a VLAN tag, extract it and validate it */
-	if (((struct ether_header*) (SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr)))->
-	    EtherType == ETHERTYPE_VLAN) {
+	if (((struct ether_header *)
+		(SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr)))->EtherType
+							== ETHERTYPE_VLAN) {
 		if (SxgExtractVlanHeader(adapter, RcvDataBufferHdr, Event) !=
 		    STATUS_SUCCESS) {
 			SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY,
@@ -1412,33 +1821,41 @@
 		}
 	}
 #endif
-	/* */
 	/* Dumb-nic frame.  See if it passes our mac filter and update stats */
-	/* */
-	if (!sxg_mac_filter(adapter, (struct ether_header*)
-			    SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr),
-			    Event->Length)) {
+
+	if (!sxg_mac_filter(adapter,
+	    (struct ether_header *)(SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr)),
+	    Event->Length)) {
 		SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "RcvFiltr",
-			  Event, SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr),
-			  Event->Length, 0);
-		goto drop;
+			    Event, SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr),
+			    Event->Length, 0);
+	  goto drop;
 	}
 
 	Packet = RcvDataBufferHdr->SxgDumbRcvPacket;
+	SXG_ADJUST_RCV_PACKET(Packet, RcvDataBufferHdr, Event);
+	Packet->protocol = eth_type_trans(Packet, adapter->netdev);
 
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "DumbRcv",
 		  RcvDataBufferHdr, Packet, Event->Length, 0);
-	/* */
 	/* Lastly adjust the receive packet length. */
-	/* */
-	SXG_ADJUST_RCV_PACKET(Packet, RcvDataBufferHdr, Event);
-
+	RcvDataBufferHdr->SxgDumbRcvPacket = NULL;
+	RcvDataBufferHdr->PhysicalAddress = (dma_addr_t)NULL;
+	SXG_ALLOCATE_RCV_PACKET(adapter, RcvDataBufferHdr, BufferSize);
+	if (RcvDataBufferHdr->skb)
+	{
+		spin_lock(&adapter->RcvQLock);
+		SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
+		// adapter->RcvBuffersOnCard ++;
+		spin_unlock(&adapter->RcvQLock);
+	}
 	return (Packet);
 
       drop:
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DropRcv",
 		  RcvDataBufferHdr, Event->Length, 0, 0);
-	adapter->Stats.RcvDiscards++;
+	adapter->stats.rx_dropped++;
+//	adapter->Stats.RcvDiscards++;
 	spin_lock(&adapter->RcvQLock);
 	SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
 	spin_unlock(&adapter->RcvQLock);
@@ -1453,14 +1870,13 @@
  *		adapter		- Adapter structure
  *		ErrorStatus	- 4-byte receive error status
  *
- * Return Value:
- * 	None
+ * Return Value		: None
  */
 static void sxg_process_rcv_error(struct adapter_t *adapter, u32 ErrorStatus)
 {
 	u32 Error;
 
-	adapter->Stats.RcvErrors++;
+	adapter->stats.rx_errors++;
 
 	if (ErrorStatus & SXG_RCV_STATUS_TRANSPORT_ERROR) {
 		Error = ErrorStatus & SXG_RCV_STATUS_TRANSPORT_MASK;
@@ -1532,13 +1948,13 @@
  *		pether		- Ethernet header
  *		length		- Frame length
  *
- * Return Value:
- * 	TRUE if the frame is to be allowed
+ * Return Value : TRUE if the frame is to be allowed
  */
-static bool sxg_mac_filter(struct adapter_t *adapter, struct ether_header *EtherHdr,
-			   ushort length)
+static bool sxg_mac_filter(struct adapter_t *adapter,
+		struct ether_header *EtherHdr, ushort length)
 {
 	bool EqualAddr;
+	struct net_device *dev = adapter->netdev;
 
 	if (SXG_MULTICAST_PACKET(EtherHdr)) {
 		if (SXG_BROADCAST_PACKET(EtherHdr)) {
@@ -1546,8 +1962,6 @@
 			if (adapter->MacFilter & MAC_BCAST) {
 				adapter->Stats.DumbRcvBcastPkts++;
 				adapter->Stats.DumbRcvBcastBytes += length;
-				adapter->Stats.DumbRcvPkts++;
-				adapter->Stats.DumbRcvBytes += length;
 				return (TRUE);
 			}
 		} else {
@@ -1555,15 +1969,12 @@
 			if (adapter->MacFilter & MAC_ALLMCAST) {
 				adapter->Stats.DumbRcvMcastPkts++;
 				adapter->Stats.DumbRcvMcastBytes += length;
-				adapter->Stats.DumbRcvPkts++;
-				adapter->Stats.DumbRcvBytes += length;
 				return (TRUE);
 			}
 			if (adapter->MacFilter & MAC_MCAST) {
-				struct SXG_MULTICAST_ADDRESS *MulticastAddrs =
-				    adapter->MulticastAddrs;
-				while (MulticastAddrs) {
-					ETHER_EQ_ADDR(MulticastAddrs->Address,
+				struct dev_mc_list *mclist = dev->mc_list;
+				while (mclist) {
+					ETHER_EQ_ADDR(mclist->da_addr,
 						      EtherHdr->ether_dhost,
 						      EqualAddr);
 					if (EqualAddr) {
@@ -1571,32 +1982,26 @@
 						    DumbRcvMcastPkts++;
 						adapter->Stats.
 						    DumbRcvMcastBytes += length;
-						adapter->Stats.DumbRcvPkts++;
-						adapter->Stats.DumbRcvBytes +=
-						    length;
 						return (TRUE);
 					}
-					MulticastAddrs = MulticastAddrs->Next;
+					mclist = mclist->next;
 				}
 			}
 		}
 	} else if (adapter->MacFilter & MAC_DIRECTED) {
-		/* Not broadcast or multicast.  Must be directed at us or */
-		/* the card is in promiscuous mode.  Either way, consider it */
-		/* ours if MAC_DIRECTED is set */
+		/*
+		 * Not broadcast or multicast.  Must be directed at us or
+		 * the card is in promiscuous mode.  Either way, consider it
+		 * ours if MAC_DIRECTED is set
+		 */
 		adapter->Stats.DumbRcvUcastPkts++;
 		adapter->Stats.DumbRcvUcastBytes += length;
-		adapter->Stats.DumbRcvPkts++;
-		adapter->Stats.DumbRcvBytes += length;
 		return (TRUE);
 	}
 	if (adapter->MacFilter & MAC_PROMISC) {
 		/* Whatever it is, keep it. */
-		adapter->Stats.DumbRcvPkts++;
-		adapter->Stats.DumbRcvBytes += length;
 		return (TRUE);
 	}
-	adapter->Stats.RcvDiscards++;
 	return (FALSE);
 }
 
@@ -1627,7 +2032,6 @@
 		adapter->intrregistered = 1;
 		adapter->IntRegistered = TRUE;
 		/* Disable RSS with line-based interrupts */
-		adapter->MsiEnabled = FALSE;
 		adapter->RssEnabled = FALSE;
 		DBG_ERROR("sxg: %s AllocAdaptRsrcs adapter[%p] dev->irq[%x]\n",
 			  __func__, adapter, adapter->netdev->irq);
@@ -1663,12 +2067,12 @@
  */
 static int sxg_if_init(struct adapter_t *adapter)
 {
-	p_net_device dev = adapter->netdev;
+	struct net_device *dev = adapter->netdev;
 	int status = 0;
 
-	DBG_ERROR("sxg: %s (%s) ENTER states[%d:%d:%d] flags[%x]\n",
+	DBG_ERROR("sxg: %s (%s) ENTER states[%d:%d] flags[%x]\n",
 		  __func__, adapter->netdev->name,
-		  adapter->queues_initialized, adapter->state,
+		  adapter->state,
 		  adapter->linkstate, dev->flags);
 
 	/* adapter should be down at this point */
@@ -1679,31 +2083,31 @@
 	ASSERT(adapter->linkstate == LINK_DOWN);
 
 	adapter->devflags_prev = dev->flags;
-	adapter->macopts = MAC_DIRECTED;
+	adapter->MacFilter = MAC_DIRECTED;
 	if (dev->flags) {
 		DBG_ERROR("sxg: %s (%s) Set MAC options: ", __func__,
 			  adapter->netdev->name);
 		if (dev->flags & IFF_BROADCAST) {
-			adapter->macopts |= MAC_BCAST;
+			adapter->MacFilter |= MAC_BCAST;
 			DBG_ERROR("BCAST ");
 		}
 		if (dev->flags & IFF_PROMISC) {
-			adapter->macopts |= MAC_PROMISC;
+			adapter->MacFilter |= MAC_PROMISC;
 			DBG_ERROR("PROMISC ");
 		}
 		if (dev->flags & IFF_ALLMULTI) {
-			adapter->macopts |= MAC_ALLMCAST;
+			adapter->MacFilter |= MAC_ALLMCAST;
 			DBG_ERROR("ALL_MCAST ");
 		}
 		if (dev->flags & IFF_MULTICAST) {
-			adapter->macopts |= MAC_MCAST;
+			adapter->MacFilter |= MAC_MCAST;
 			DBG_ERROR("MCAST ");
 		}
 		DBG_ERROR("\n");
 	}
-	status = sxg_register_interrupt(adapter);
+	status = sxg_register_intr(adapter);
 	if (status != STATUS_SUCCESS) {
-		DBG_ERROR("sxg_if_init: sxg_register_interrupt FAILED %x\n",
+		DBG_ERROR("sxg_if_init: sxg_register_intr FAILED %x\n",
 			  status);
 		sxg_deregister_interrupt(adapter);
 		return (status);
@@ -1711,18 +2115,90 @@
 
 	adapter->state = ADAPT_UP;
 
-	/*
-	 *    clear any pending events, then enable interrupts
-	 */
+	/*    clear any pending events, then enable interrupts */
 	DBG_ERROR("sxg: %s ENABLE interrupts(slic)\n", __func__);
 
 	return (STATUS_SUCCESS);
 }
 
-static int sxg_entry_open(p_net_device dev)
+void sxg_set_interrupt_aggregation(struct adapter_t *adapter)
+{
+	/*
+	 * Top bit disables aggregation on xmt (SXG_AGG_XMT_DISABLE).
+	 * Make sure Max is less than 0x8000.
+	 */
+	adapter->max_aggregation = SXG_MAX_AGG_DEFAULT;
+	adapter->min_aggregation = SXG_MIN_AGG_DEFAULT;
+	WRITE_REG(adapter->UcodeRegs[0].Aggregation,
+		((adapter->max_aggregation << SXG_MAX_AGG_SHIFT) |
+			adapter->min_aggregation),
+			TRUE);
+}
+
+static int sxg_entry_open(struct net_device *dev)
 {
 	struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev);
 	int status;
+	static int turn;
+	int sxg_initial_rcv_data_buffers = SXG_INITIAL_RCV_DATA_BUFFERS;
+	int i;
+
+	if (adapter->JumboEnabled == TRUE) {
+		sxg_initial_rcv_data_buffers =
+					SXG_INITIAL_JUMBO_RCV_DATA_BUFFERS;
+		SXG_INITIALIZE_RING(adapter->RcvRingZeroInfo,
+					SXG_JUMBO_RCV_RING_SIZE);
+	}
+
+	/*
+	* Allocate receive data buffers.  We allocate a block of buffers and
+	* a corresponding descriptor block at once.  See sxghw.h:SXG_RCV_BLOCK
+	*/
+
+	for (i = 0; i < sxg_initial_rcv_data_buffers;
+			i += SXG_RCV_DESCRIPTORS_PER_BLOCK)
+	{
+		status = sxg_allocate_buffer_memory(adapter,
+		SXG_RCV_BLOCK_SIZE(SXG_RCV_DATA_HDR_SIZE),
+					SXG_BUFFER_TYPE_RCV);
+		if (status != STATUS_SUCCESS)
+			return status;
+	}
+	/*
+	 * NBL resource allocation can fail in the 'AllocateComplete' routine,
+	 * which doesn't return status.  Make sure we got the number of buffers
+	 * we requested
+	 */
+
+	if (adapter->FreeRcvBufferCount < sxg_initial_rcv_data_buffers) {
+		SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF6",
+			adapter, adapter->FreeRcvBufferCount, SXG_MAX_ENTRIES,
+			0);
+		return (STATUS_RESOURCES);
+	}
+	/*
+	 * The microcode expects it to be downloaded on every open.
+	 */
+	DBG_ERROR("sxg: %s ENTER sxg_download_microcode\n", __FUNCTION__);
+	if (sxg_download_microcode(adapter, SXG_UCODE_SYSTEM)) {
+		DBG_ERROR("sxg: %s ENTER sxg_adapter_set_hwaddr\n",
+				__FUNCTION__);
+		sxg_read_config(adapter);
+	} else {
+		adapter->state = ADAPT_FAIL;
+		adapter->linkstate = LINK_DOWN;
+		DBG_ERROR("sxg_download_microcode FAILED status[%x]\n",
+				status);
+	}
+	msleep(5);
+
+	if (turn) {
+		sxg_second_open(adapter->netdev);
+
+		return STATUS_SUCCESS;
+	}
+
+	turn++;
 
 	ASSERT(adapter);
 	DBG_ERROR("sxg: %s adapter->activated[%d]\n", __func__,
@@ -1762,6 +2238,8 @@
 		return (status);
 	}
 	DBG_ERROR("sxg: %s ENABLE ALL INTERRUPTS\n", __func__);
+	sxg_set_interrupt_aggregation(adapter);
+	napi_enable(&adapter->napi);
 
 	/* Enable interrupts */
 	SXG_ENABLE_ALL_INTERRUPTS(adapter);
@@ -1772,71 +2250,162 @@
 	return STATUS_SUCCESS;
 }
 
+int sxg_second_open(struct net_device * dev)
+{
+	struct adapter_t *adapter = (struct adapter_t*) netdev_priv(dev);
+	int status = 0;
+
+	spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags);
+	netif_start_queue(adapter->netdev);
+        adapter->state = ADAPT_UP;
+        adapter->linkstate = LINK_UP;
+
+	status = sxg_initialize_adapter(adapter);
+	sxg_set_interrupt_aggregation(adapter);
+	napi_enable(&adapter->napi);
+        /* Re-enable interrupts */
+        SXG_ENABLE_ALL_INTERRUPTS(adapter);
+
+	sxg_register_intr(adapter);
+	spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags);
+	mod_timer(&adapter->watchdog_timer, jiffies);
+	return (STATUS_SUCCESS);
+
+}
+
 static void __devexit sxg_entry_remove(struct pci_dev *pcidev)
 {
-	p_net_device dev = pci_get_drvdata(pcidev);
-	u32 mmio_start = 0;
-	unsigned int mmio_len = 0;
+        u32 mmio_start = 0;
+        u32 mmio_len = 0;
+
+	struct net_device *dev = pci_get_drvdata(pcidev);
 	struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev);
 
-	ASSERT(adapter);
-	DBG_ERROR("sxg: %s ENTER dev[%p] adapter[%p]\n", __func__, dev,
-		  adapter);
-	sxg_deregister_interrupt(adapter);
-	sxg_unmap_mmio_space(adapter);
-	DBG_ERROR("sxg: %s unregister_netdev\n", __func__);
+	flush_scheduled_work();
+
+	/* Deallocate Resources */
 	unregister_netdev(dev);
+	sxg_reset_interrupt_capability(adapter);
+	sxg_free_resources(adapter);
 
-	mmio_start = pci_resource_start(pcidev, 0);
-	mmio_len = pci_resource_len(pcidev, 0);
+	ASSERT(adapter);
 
-	DBG_ERROR("sxg: %s rel_region(0) start[%x] len[%x]\n", __func__,
-		  mmio_start, mmio_len);
-	release_mem_region(mmio_start, mmio_len);
+        mmio_start = pci_resource_start(pcidev, 0);
+        mmio_len = pci_resource_len(pcidev, 0);
 
-	DBG_ERROR("sxg: %s iounmap dev->base_addr[%x]\n", __func__,
-		  (unsigned int)dev->base_addr);
-	iounmap((char *)dev->base_addr);
+        DBG_ERROR("sxg: %s rel_region(0) start[%x] len[%x]\n", __FUNCTION__,
+                  mmio_start, mmio_len);
+        release_mem_region(mmio_start, mmio_len);
+
+        mmio_start = pci_resource_start(pcidev, 2);
+        mmio_len = pci_resource_len(pcidev, 2);
+
+        DBG_ERROR("sxg: %s rel_region(2) start[%x] len[%x]\n", __FUNCTION__,
+                  mmio_start, mmio_len);
+        release_mem_region(mmio_start, mmio_len);
+
+	pci_disable_device(pcidev);
 
 	DBG_ERROR("sxg: %s deallocate device\n", __func__);
 	kfree(dev);
 	DBG_ERROR("sxg: %s EXIT\n", __func__);
 }
 
-static int sxg_entry_halt(p_net_device dev)
+static int sxg_entry_halt(struct net_device *dev)
 {
 	struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev);
+	struct sxg_hw_regs *HwRegs = adapter->HwRegs;
+	int i;
+	u32 RssIds, IsrCount;
+	unsigned long flags;
 
+	RssIds = SXG_RSS_CPU_COUNT(adapter);
+	IsrCount = adapter->msi_enabled ? RssIds : 1;
+	/* Disable interrupts */
 	spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags);
-	DBG_ERROR("sxg: %s (%s) ENTER\n", __func__, dev->name);
-
-	netif_stop_queue(adapter->netdev);
+	SXG_DISABLE_ALL_INTERRUPTS(adapter);
 	adapter->state = ADAPT_DOWN;
 	adapter->linkstate = LINK_DOWN;
+
+	spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags);
+	sxg_deregister_interrupt(adapter);
+	WRITE_REG(HwRegs->Reset, 0xDEAD, FLUSH);
+	mdelay(5000);
+
+	del_timer_sync(&adapter->watchdog_timer);
+	netif_stop_queue(dev);
+	netif_carrier_off(dev);
+
+	napi_disable(&adapter->napi);
+
+	WRITE_REG(adapter->UcodeRegs[0].RcvCmd, 0, true);
 	adapter->devflags_prev = 0;
 	DBG_ERROR("sxg: %s (%s) set adapter[%p] state to ADAPT_DOWN(%d)\n",
 		  __func__, dev->name, adapter, adapter->state);
 
-	DBG_ERROR("sxg: %s (%s) EXIT\n", __func__, dev->name);
-	DBG_ERROR("sxg: %s EXIT\n", __func__);
-	spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags);
+	spin_lock(&adapter->RcvQLock);
+	/* Free all the blocks and the buffers, moved from remove() routine */
+	if (!(IsListEmpty(&adapter->AllRcvBlocks))) {
+		sxg_free_rcvblocks(adapter);
+	}
+
+
+	InitializeListHead(&adapter->FreeRcvBuffers);
+	InitializeListHead(&adapter->FreeRcvBlocks);
+	InitializeListHead(&adapter->AllRcvBlocks);
+	InitializeListHead(&adapter->FreeSglBuffers);
+	InitializeListHead(&adapter->AllSglBuffers);
+
+	adapter->FreeRcvBufferCount = 0;
+	adapter->FreeRcvBlockCount = 0;
+	adapter->AllRcvBlockCount = 0;
+	adapter->RcvBuffersOnCard = 0;
+	adapter->PendingRcvCount = 0;
+
+	memset(adapter->RcvRings, 0, sizeof(struct sxg_rcv_ring) * 1);
+	memset(adapter->EventRings, 0, sizeof(struct sxg_event_ring) * RssIds);
+	memset(adapter->Isr, 0, sizeof(u32) * IsrCount);
+	for (i = 0; i < SXG_MAX_RING_SIZE; i++)
+		adapter->RcvRingZeroInfo.Context[i] = NULL;
+	SXG_INITIALIZE_RING(adapter->RcvRingZeroInfo, SXG_RCV_RING_SIZE);
+	SXG_INITIALIZE_RING(adapter->XmtRingZeroInfo, SXG_XMT_RING_SIZE);
+
+	spin_unlock(&adapter->RcvQLock);
+
+	spin_lock_irqsave(&adapter->XmtZeroLock, flags);
+	adapter->AllSglBufferCount = 0;
+	adapter->FreeSglBufferCount = 0;
+	adapter->PendingXmtCount = 0;
+	memset(adapter->XmtRings, 0, sizeof(struct sxg_xmt_ring) * 1);
+	memset(adapter->XmtRingZeroIndex, 0, sizeof(u32));
+	spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
+
+	for (i = 0; i < SXG_MAX_RSS; i++) {
+		adapter->NextEvent[i] = 0;
+	}
+	atomic_set(&adapter->pending_allocations, 0);
+	adapter->intrregistered = 0;
+	sxg_remove_isr(adapter);
+	DBG_ERROR("sxg: %s (%s) EXIT\n", __FUNCTION__, dev->name);
 	return (STATUS_SUCCESS);
 }
 
-static int sxg_ioctl(p_net_device dev, struct ifreq *rq, int cmd)
+static int sxg_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	ASSERT(rq);
-/*      DBG_ERROR("sxg: %s cmd[%x] rq[%p] dev[%p]\n", __func__, cmd, rq, dev); */
+/*      DBG_ERROR("sxg: %s cmd[%x] rq[%p] dev[%p]\n", __func__, cmd, rq, dev);*/
 	switch (cmd) {
 	case SIOCSLICSETINTAGG:
 		{
-/*                      struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev); */
+			/* struct adapter_t *adapter = (struct adapter_t *)
+			 * netdev_priv(dev);
+			 */
 			u32 data[7];
 			u32 intagg;
 
 			if (copy_from_user(data, rq->ifr_data, 28)) {
-				DBG_ERROR
-				    ("copy_from_user FAILED  getting initial params\n");
+				DBG_ERROR("copy_from_user FAILED  getting \
+					 initial params\n");
 				return -EFAULT;
 			}
 			intagg = data[0];
@@ -1847,7 +2416,7 @@
 		}
 
 	default:
-/*              DBG_ERROR("sxg: %s UNSUPPORTED[%x]\n", __func__, cmd); */
+		/* DBG_ERROR("sxg: %s UNSUPPORTED[%x]\n", __func__, cmd); */
 		return -EOPNOTSUPP;
 	}
 	return 0;
@@ -1856,23 +2425,25 @@
 #define NORMAL_ETHFRAME     0
 
 /*
- *
  * sxg_send_packets - Send a skb packet
  *
  * Arguments:
- *			skb                     - The packet to send
- *			dev                     - Our linux net device that refs our adapter
+ *			skb - The packet to send
+ *			dev - Our linux net device that refs our adapter
  *
  * Return:
  *		0   regardless of outcome    XXXTODO refer to e1000 driver
  */
-static int sxg_send_packets(struct sk_buff *skb, p_net_device dev)
+static int sxg_send_packets(struct sk_buff *skb, struct net_device *dev)
 {
 	struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev);
 	u32 status = STATUS_SUCCESS;
 
-	DBG_ERROR("sxg: %s ENTER sxg_send_packets skb[%p]\n", __func__,
-		  skb);
+	/*
+	 * DBG_ERROR("sxg: %s ENTER sxg_send_packets skb[%p]\n", __FUNCTION__,
+	 *	  skb);
+	 */
+
 	/* Check the adapter state */
 	switch (adapter->State) {
 	case SXG_STATE_INITIALIZING:
@@ -1909,17 +2480,18 @@
 	/* reject & complete all the packets if they cant be sent */
 	if (status != STATUS_SUCCESS) {
 #if XXXTODO
-/*      sxg_send_packets_fail(adapter, skb, status); */
+	/* sxg_send_packets_fail(adapter, skb, status); */
 #else
 		SXG_DROP_DUMB_SEND(adapter, skb);
 		adapter->stats.tx_dropped++;
+		return NETDEV_TX_BUSY;
 #endif
 	}
 	DBG_ERROR("sxg: %s EXIT sxg_send_packets status[%x]\n", __func__,
 		  status);
 
       xmit_done:
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
@@ -1931,33 +2503,35 @@
  *		adapter			- Pointer to our adapter structure
  *      skb             - The packet to be sent
  *
- * Return -
- * 		STATUS of send
+ * Return - STATUS of send
  */
 static int sxg_transmit_packet(struct adapter_t *adapter, struct sk_buff *skb)
 {
-	struct SCATTER_GATHER_LIST *pSgl;
-	struct SXG_SCATTER_GATHER *SxgSgl;
-	void *SglBuffer;
-	u32 SglBufferLength;
+	struct sxg_x64_sgl         *pSgl;
+	struct sxg_scatter_gather  *SxgSgl;
+	unsigned long sgl_flags;
+	/* void *SglBuffer; */
+	/* u32 SglBufferLength; */
 
-	/* The vast majority of work is done in the shared */
-	/* sxg_dumb_sgl routine. */
+	/*
+	 * The vast majority of work is done in the shared
+	 * sxg_dumb_sgl routine.
+	 */
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbSend",
 		  adapter, skb, 0, 0);
 
 	/* Allocate a SGL buffer */
-	SXG_GET_SGL_BUFFER(adapter, SxgSgl);
+	SXG_GET_SGL_BUFFER(adapter, SxgSgl, 0);
 	if (!SxgSgl) {
 		adapter->Stats.NoSglBuf++;
-		adapter->Stats.XmtErrors++;
+		adapter->stats.tx_errors++;
 		SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "SndPktF1",
 			  adapter, skb, 0, 0);
 		return (STATUS_RESOURCES);
 	}
 	ASSERT(SxgSgl->adapter == adapter);
-	SglBuffer = SXG_SGL_BUFFER(SxgSgl);
-	SglBufferLength = SXG_SGL_BUF_SIZE;
+	/*SglBuffer = SXG_SGL_BUFFER(SxgSgl);
+	SglBufferLength = SXG_SGL_BUF_SIZE; */
 	SxgSgl->VlanTag.VlanTci = 0;
 	SxgSgl->VlanTag.VlanTpid = 0;
 	SxgSgl->Type = SXG_SGL_DUMB;
@@ -1965,9 +2539,7 @@
 	pSgl = NULL;
 
 	/* Call the common sxg_dumb_sgl routine to complete the send. */
-	sxg_dumb_sgl(pSgl, SxgSgl);
-	/* Return success   sxg_dumb_sgl (or something later) will complete it. */
-	return (STATUS_SUCCESS);
+	return (sxg_dumb_sgl(pSgl, SxgSgl));
 }
 
 /*
@@ -1975,24 +2547,27 @@
  *
  * Arguments:
  *		pSgl     -
- *		SxgSgl   - SXG_SCATTER_GATHER
+ *		SxgSgl   - struct sxg_scatter_gather
  *
  * Return Value:
- * 	None.
+ * 	Status of send operation.
  */
-static void sxg_dumb_sgl(struct SCATTER_GATHER_LIST *pSgl, struct SXG_SCATTER_GATHER *SxgSgl)
+static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl,
+				struct sxg_scatter_gather *SxgSgl)
 {
 	struct adapter_t *adapter = SxgSgl->adapter;
 	struct sk_buff *skb = SxgSgl->DumbPacket;
 	/* For now, all dumb-nic sends go on RSS queue zero */
-	struct SXG_XMT_RING *XmtRing = &adapter->XmtRings[0];
-	struct SXG_RING_INFO *XmtRingInfo = &adapter->XmtRingZeroInfo;
-	struct SXG_CMD *XmtCmd = NULL;
-/*      u32                         Index = 0; */
+	struct sxg_xmt_ring *XmtRing = &adapter->XmtRings[0];
+	struct sxg_ring_info *XmtRingInfo = &adapter->XmtRingZeroInfo;
+	struct sxg_cmd *XmtCmd = NULL;
+	/* u32 Index = 0; */
 	u32 DataLength = skb->len;
-/*  unsigned int                                BufLen; */
-/*      u32                         SglOffset; */
+	/* unsigned int BufLen; */
+	/* u32 SglOffset; */
 	u64 phys_addr;
+	unsigned long flags;
+	unsigned long queue_id=0;
 
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbSgl",
 		  pSgl, SxgSgl, 0, 0);
@@ -2001,25 +2576,67 @@
 	SxgSgl->pSgl = pSgl;
 
 	/* Sanity check that our SGL format is as we expect. */
-	ASSERT(sizeof(SXG_X64_SGE) == sizeof(SCATTER_GATHER_ELEMENT));
+	ASSERT(sizeof(struct sxg_x64_sge) == sizeof(struct sxg_x64_sge));
 	/* Shouldn't be a vlan tag on this frame */
 	ASSERT(SxgSgl->VlanTag.VlanTci == 0);
 	ASSERT(SxgSgl->VlanTag.VlanTpid == 0);
 
-	/* From here below we work with the SGL placed in our */
-	/* buffer. */
+	/*
+	 * From here below we work with the SGL placed in our
+	 * buffer.
+	 */
 
 	SxgSgl->Sgl.NumberOfElements = 1;
+	/*
+	 * Set ucode Queue ID based on bottom bits of destination TCP port.
+	 * This Queue ID splits slowpath/dumb-nic packet processing across
+	 * multiple threads on the card to improve performance.  It is split
+	 * using the TCP port to avoid out-of-order packets that can result
+         * from multithreaded processing.  We use the destination port because
+         * we expect to be run on a server, so in nearly all cases the local
+         * port is likely to be constant (well-known server port) and the
+         * remote port is likely to be random.  The exception to this is iSCSI,
+         * in which case we use the sport instead.  Note
+         * that original attempt at XOR'ing source and dest port resulted in
+         * poor balance on NTTTCP/iometer applications since they tend to
+         * line up (even-even, odd-odd..).
+         */
+
+	if (skb->protocol == htons(ETH_P_IP)) {
+                struct iphdr *ip;
+
+                ip = ip_hdr(skb);
+		if ((ip->protocol == IPPROTO_TCP)&&(DataLength >= sizeof(
+							struct tcphdr))){
+			queue_id = ((ntohs(tcp_hdr(skb)->dest) == ISCSI_PORT) ?
+					(ntohs (tcp_hdr(skb)->source) &
+						SXG_LARGE_SEND_QUEUE_MASK):
+						(ntohs(tcp_hdr(skb)->dest) &
+						SXG_LARGE_SEND_QUEUE_MASK));
+		}
+	} else if (skb->protocol == htons(ETH_P_IPV6)) {
+		if ((ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) && (DataLength >=
+						 sizeof(struct tcphdr)) ) {
+			queue_id = ((ntohs(tcp_hdr(skb)->dest) == ISCSI_PORT) ?
+					(ntohs (tcp_hdr(skb)->source) &
+					SXG_LARGE_SEND_QUEUE_MASK):
+                                        (ntohs(tcp_hdr(skb)->dest) &
+					SXG_LARGE_SEND_QUEUE_MASK));
+		}
+	}
 
 	/* Grab the spinlock and acquire a command */
-	spin_lock(&adapter->XmtZeroLock);
+	spin_lock_irqsave(&adapter->XmtZeroLock, flags);
 	SXG_GET_CMD(XmtRing, XmtRingInfo, XmtCmd, SxgSgl);
 	if (XmtCmd == NULL) {
-		/* Call sxg_complete_slow_send to see if we can */
-		/* free up any XmtRingZero entries and then try again */
-		spin_unlock(&adapter->XmtZeroLock);
+		/*
+		 * Call sxg_complete_slow_send to see if we can
+		 * free up any XmtRingZero entries and then try again
+		 */
+
+		spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
 		sxg_complete_slow_send(adapter);
-		spin_lock(&adapter->XmtZeroLock);
+		spin_lock_irqsave(&adapter->XmtZeroLock, flags);
 		SXG_GET_CMD(XmtRing, XmtRingInfo, XmtCmd, SxgSgl);
 		if (XmtCmd == NULL) {
 			adapter->Stats.XmtZeroFull++;
@@ -2029,8 +2646,8 @@
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbCmd",
 		  XmtCmd, XmtRingInfo->Head, XmtRingInfo->Tail, 0);
 	/* Update stats */
-	adapter->Stats.DumbXmtPkts++;
-	adapter->Stats.DumbXmtBytes += DataLength;
+	adapter->stats.tx_packets++;
+	adapter->stats.tx_bytes += DataLength;
 #if XXXTODO			/* Stats stuff */
 	if (SXG_MULTICAST_PACKET(EtherHdr)) {
 		if (SXG_BROADCAST_PACKET(EtherHdr)) {
@@ -2045,70 +2662,92 @@
 		adapter->Stats.DumbXmtUcastBytes += DataLength;
 	}
 #endif
-	/* Fill in the command */
-	/* Copy out the first SGE to the command and adjust for offset */
-	phys_addr =
-	    pci_map_single(adapter->pcidev, skb->data, skb->len,
+	/*
+	 * Fill in the command
+	 * Copy out the first SGE to the command and adjust for offset
+	 */
+	phys_addr = pci_map_single(adapter->pcidev, skb->data, skb->len,
 			   PCI_DMA_TODEVICE);
-	XmtCmd->Buffer.FirstSgeAddress = SXG_GET_ADDR_HIGH(phys_addr);
-	XmtCmd->Buffer.FirstSgeAddress = XmtCmd->Buffer.FirstSgeAddress << 32;
-	XmtCmd->Buffer.FirstSgeAddress =
-	    XmtCmd->Buffer.FirstSgeAddress | SXG_GET_ADDR_LOW(phys_addr);
-/*      XmtCmd->Buffer.FirstSgeAddress = SxgSgl->Sgl.Elements[Index].Address; */
-/*      XmtCmd->Buffer.FirstSgeAddress.LowPart += MdlOffset; */
+
+	/*
+	 * SAHARA SGL WORKAROUND
+	 * See if the SGL straddles a 64k boundary.  If so, skip to
+	 * the start of the next 64k boundary and continue
+ 	 */
+
+	if ((adapter->asictype == SAHARA_REV_A) &&
+		(SXG_INVALID_SGL(phys_addr,skb->data_len)))
+	{
+		spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
+		/* Silently drop this packet */
+		printk(KERN_EMERG"Dropped a packet for 64k boundary problem\n");
+		return STATUS_SUCCESS;
+	}
+	memset(XmtCmd, '\0', sizeof(*XmtCmd));
+	XmtCmd->Buffer.FirstSgeAddress = phys_addr;
 	XmtCmd->Buffer.FirstSgeLength = DataLength;
-	/* Set a pointer to the remaining SGL entries */
-/*      XmtCmd->Sgl = SxgSgl->PhysicalAddress; */
-	/* Advance the physical address of the SxgSgl structure to */
-	/* the second SGE */
-/*      SglOffset = (u32)((u32 *)(&SxgSgl->Sgl.Elements[Index+1]) - */
-/*                                              (u32 *)SxgSgl); */
-/*      XmtCmd->Sgl.LowPart += SglOffset; */
 	XmtCmd->Buffer.SgeOffset = 0;
-	/* Note - TotalLength might be overwritten with MSS below.. */
 	XmtCmd->Buffer.TotalLength = DataLength;
-	XmtCmd->SgEntries = 1;	/*(ushort)(SxgSgl->Sgl.NumberOfElements - Index); */
+	XmtCmd->SgEntries = 1;
 	XmtCmd->Flags = 0;
-	/* */
-	/* Advance transmit cmd descripter by 1. */
-	/* NOTE - See comments in SxgTcpOutput where we write */
-	/* to the XmtCmd register regarding CPU ID values and/or */
-	/* multiple commands. */
-	/* */
-	/* */
-	WRITE_REG(adapter->UcodeRegs[0].XmtCmd, 1, TRUE);
-	/* */
-	/* */
+
+	if (skb->ip_summed == CHECKSUM_PARTIAL) {
+		/*
+		 * We need to set the Checkum in IP  header to 0. This is
+		 * required by hardware.
+		 */
+		ip_hdr(skb)->check = 0x0;
+		XmtCmd->CsumFlags.Flags |= SXG_SLOWCMD_CSUM_IP;
+		XmtCmd->CsumFlags.Flags |= SXG_SLOWCMD_CSUM_TCP;
+		/* Dont know if length will require a change in case of VLAN */
+		XmtCmd->CsumFlags.MacLen = ETH_HLEN;
+		XmtCmd->CsumFlags.IpHl = skb_network_header_len(skb) >>
+							SXG_NW_HDR_LEN_SHIFT;
+	}
+	/*
+	 * Advance transmit cmd descripter by 1.
+	 * NOTE - See comments in SxgTcpOutput where we write
+	 * to the XmtCmd register regarding CPU ID values and/or
+	 * multiple commands.
+	 * Top 16 bits specify queue_id.  See comments about queue_id above
+	 */
+	/* Four queues at the moment */
+	ASSERT((queue_id & ~SXG_LARGE_SEND_QUEUE_MASK) == 0);
+	WRITE_REG(adapter->UcodeRegs[0].XmtCmd, ((queue_id << 16) | 1), TRUE);
 	adapter->Stats.XmtQLen++;	/* Stats within lock */
-	spin_unlock(&adapter->XmtZeroLock);
+	spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDumSgl2",
 		  XmtCmd, pSgl, SxgSgl, 0);
-	return;
+	return  STATUS_SUCCESS;
 
       abortcmd:
-	/* NOTE - Only jump to this label AFTER grabbing the */
-	/* XmtZeroLock, and DO NOT DROP IT between the */
-	/* command allocation and the following abort. */
+	/*
+	 * NOTE - Only jump to this label AFTER grabbing the
+	 * XmtZeroLock, and DO NOT DROP IT between the
+	 * command allocation and the following abort.
+	 */
 	if (XmtCmd) {
 		SXG_ABORT_CMD(XmtRingInfo);
 	}
-	spin_unlock(&adapter->XmtZeroLock);
-
-/* failsgl: */
-	/* Jump to this label if failure occurs before the */
-	/* XmtZeroLock is grabbed */
-	adapter->Stats.XmtErrors++;
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "DumSGFal",
-		  pSgl, SxgSgl, XmtRingInfo->Head, XmtRingInfo->Tail);
-
-	SXG_COMPLETE_DUMB_SEND(adapter, SxgSgl->DumbPacket);	/* SxgSgl->DumbPacket is the skb */
-}
-
-/***************************************************************
- * Link management functions
- ***************************************************************/
+	spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
 
 /*
+ * failsgl:
+ * 	Jump to this label if failure occurs before the
+ *	XmtZeroLock is grabbed
+ */
+	adapter->stats.tx_errors++;
+	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "DumSGFal",
+		  pSgl, SxgSgl, XmtRingInfo->Head, XmtRingInfo->Tail);
+	/* SxgSgl->DumbPacket is the skb */
+	// SXG_COMPLETE_DUMB_SEND(adapter, SxgSgl->DumbPacket);
+
+ 	return STATUS_FAILURE;
+}
+
+/*
+ * Link management functions
+ *
  * sxg_initialize_link - Initialize the link stuff
  *
  * Arguments -
@@ -2119,10 +2758,11 @@
  */
 static int sxg_initialize_link(struct adapter_t *adapter)
 {
-	struct SXG_HW_REGS *HwRegs = adapter->HwRegs;
+	struct sxg_hw_regs *HwRegs = adapter->HwRegs;
 	u32 Value;
 	u32 ConfigData;
 	u32 MaxFrame;
+	u32 AxgMacReg1;
 	int status;
 
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "InitLink",
@@ -2140,15 +2780,17 @@
 	/* Reset all MAC modules */
 	WRITE_REG(HwRegs->MacConfig0, AXGMAC_CFG0_SUB_RESET, TRUE);
 
-	/* Link address 0 */
-	/* XXXTODO - This assumes the MAC address (0a:0b:0c:0d:0e:0f) */
-	/* is stored with the first nibble (0a) in the byte 0 */
-	/* of the Mac address.  Possibly reverse? */
-	Value = *(u32 *) adapter->MacAddr;
+	/*
+	 * Link address 0
+	 * XXXTODO - This assumes the MAC address (0a:0b:0c:0d:0e:0f)
+	 * is stored with the first nibble (0a) in the byte 0
+	 * of the Mac address.  Possibly reverse?
+	 */
+	Value = *(u32 *) adapter->macaddr;
 	WRITE_REG(HwRegs->LinkAddress0Low, Value, TRUE);
 	/* also write the MAC address to the MAC.  Endian is reversed. */
 	WRITE_REG(HwRegs->MacAddressLow, ntohl(Value), TRUE);
-	Value = (*(u16 *) & adapter->MacAddr[4] & 0x0000FFFF);
+	Value = (*(u16 *) & adapter->macaddr[4] & 0x0000FFFF);
 	WRITE_REG(HwRegs->LinkAddress0High, Value | LINK_ADDRESS_ENABLE, TRUE);
 	/* endian swap for the MAC (put high bytes in bits [31:16], swapped) */
 	Value = ntohl(Value);
@@ -2167,47 +2809,76 @@
 	WRITE_REG(HwRegs->MacConfig0, 0, TRUE);
 
 	/* Configure MAC */
-	WRITE_REG(HwRegs->MacConfig1, (AXGMAC_CFG1_XMT_PAUSE |	/* Allow sending of pause */
-				       AXGMAC_CFG1_XMT_EN |	/* Enable XMT */
-				       AXGMAC_CFG1_RCV_PAUSE |	/* Enable detection of pause */
-				       AXGMAC_CFG1_RCV_EN |	/* Enable receive */
-				       AXGMAC_CFG1_SHORT_ASSERT |	/* short frame detection */
-				       AXGMAC_CFG1_CHECK_LEN |	/* Verify frame length */
-				       AXGMAC_CFG1_GEN_FCS |	/* Generate FCS */
-				       AXGMAC_CFG1_PAD_64),	/* Pad frames to 64 bytes */
-		  TRUE);
+	AxgMacReg1 = (  /* Enable XMT */
+			AXGMAC_CFG1_XMT_EN |
+			/* Enable receive */
+			AXGMAC_CFG1_RCV_EN |
+			/* short frame detection */
+			AXGMAC_CFG1_SHORT_ASSERT |
+			/* Verify frame length */
+			AXGMAC_CFG1_CHECK_LEN |
+			/* Generate FCS */
+			AXGMAC_CFG1_GEN_FCS |
+			/* Pad frames to 64 bytes */
+			AXGMAC_CFG1_PAD_64);
+
+ 	if (adapter->XmtFcEnabled) {
+		AxgMacReg1 |=  AXGMAC_CFG1_XMT_PAUSE;  /* Allow sending of pause */
+ 	}
+ 	if (adapter->RcvFcEnabled) {
+		AxgMacReg1 |=  AXGMAC_CFG1_RCV_PAUSE;  /* Enable detection of pause */
+ 	}
+
+ 	WRITE_REG(HwRegs->MacConfig1, AxgMacReg1, TRUE);
 
 	/* Set AXGMAC max frame length if jumbo.  Not needed for standard MTU */
 	if (adapter->JumboEnabled) {
 		WRITE_REG(HwRegs->MacMaxFrameLen, AXGMAC_MAXFRAME_JUMBO, TRUE);
 	}
-	/* AMIIM Configuration Register - */
-	/* The value placed in the AXGMAC_AMIIM_CFG_HALF_CLOCK portion */
-	/* (bottom bits) of this register is used to determine the */
-	/* MDC frequency as specified in the A-XGMAC Design Document. */
-	/* This value must not be zero.  The following value (62 or 0x3E) */
-	/* is based on our MAC transmit clock frequency (MTCLK) of 312.5 MHz. */
-	/* Given a maximum MDIO clock frequency of 2.5 MHz (see the PHY spec), */
-	/* we get:  312.5/(2*(X+1)) < 2.5  ==> X = 62. */
-	/* This value happens to be the default value for this register, */
-	/* so we really don't have to do this. */
-	WRITE_REG(HwRegs->MacAmiimConfig, 0x0000003E, TRUE);
+	/*
+	 * AMIIM Configuration Register -
+	 * The value placed in the AXGMAC_AMIIM_CFG_HALF_CLOCK portion
+	 * (bottom bits) of this register is used to determine the MDC frequency
+	 * as specified in the A-XGMAC Design Document. This value must not be
+	 * zero.  The following value (62 or 0x3E) is based on our MAC transmit
+	 * clock frequency (MTCLK) of 312.5 MHz. Given a maximum MDIO clock
+	 * frequency of 2.5 MHz (see the PHY spec), we get:
+	 * 	312.5/(2*(X+1)) < 2.5  ==> X = 62.
+	 * This value happens to be the default value for this register, so we
+	 * really don't have to do this.
+	 */
+	if (adapter->asictype == SAHARA_REV_B) {
+		WRITE_REG(HwRegs->MacAmiimConfig, 0x0000001F, TRUE);
+	} else {
+		WRITE_REG(HwRegs->MacAmiimConfig, 0x0000003E, TRUE);
+	}
 
 	/* Power up and enable PHY and XAUI/XGXS/Serdes logic */
 	WRITE_REG(HwRegs->LinkStatus,
-		  (LS_PHY_CLR_RESET |
-		   LS_XGXS_ENABLE |
-		   LS_XGXS_CTL | LS_PHY_CLK_EN | LS_ATTN_ALARM), TRUE);
+		   (LS_PHY_CLR_RESET |
+		    LS_XGXS_ENABLE |
+		    LS_XGXS_CTL |
+		    LS_PHY_CLK_EN |
+		    LS_ATTN_ALARM),
+		    TRUE);
 	DBG_ERROR("After Power Up and enable PHY in sxg_initialize_link\n");
 
-	/* Per information given by Aeluros, wait 100 ms after removing reset. */
-	/* It's not enough to wait for the self-clearing reset bit in reg 0 to clear. */
+	/*
+	 * Per information given by Aeluros, wait 100 ms after removing reset.
+	 * It's not enough to wait for the self-clearing reset bit in reg 0 to
+	 * clear.
+	 */
 	mdelay(100);
 
-	/* Verify the PHY has come up by checking that the Reset bit has cleared. */
-	status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,	/* PHY PMA/PMD module */
-				   PHY_PMA_CONTROL1,	/* PMA/PMD control register */
-				   &Value);
+	/* Verify the PHY has come up by checking that the Reset bit has
+	 * cleared.
+	 */
+	status = sxg_read_mdio_reg(adapter,
+				MIIM_DEV_PHY_PMA, /* PHY PMA/PMD module */
+				PHY_PMA_CONTROL1, /* PMA/PMD control register */
+				&Value);
+	DBG_ERROR("After sxg_read_mdio_reg Value[%x] fail=%x\n", Value,
+					 (Value & PMA_CONTROL1_RESET));
 	if (status != STATUS_SUCCESS)
 		return (STATUS_FAILURE);
 	if (Value & PMA_CONTROL1_RESET)	/* reset complete if bit is 0 */
@@ -2228,16 +2899,26 @@
 		return (STATUS_FAILURE);
 
 	/* Enable the Link Alarm */
-	status = sxg_write_mdio_reg(adapter, MIIM_DEV_PHY_PMA,	/* PHY PMA/PMD module */
-				    LASI_CONTROL,	/* LASI control register */
-				    LASI_CTL_LS_ALARM_ENABLE);	/* enable link alarm bit */
+
+	/* MIIM_DEV_PHY_PMA		- PHY PMA/PMD module
+	 * LASI_CONTROL			- LASI control register
+	 * LASI_CTL_LS_ALARM_ENABLE	- enable link alarm bit
+	 */
+	status = sxg_write_mdio_reg(adapter, MIIM_DEV_PHY_PMA,
+				    LASI_CONTROL,
+				    LASI_CTL_LS_ALARM_ENABLE);
 	if (status != STATUS_SUCCESS)
 		return (STATUS_FAILURE);
 
 	/* XXXTODO - temporary - verify bit is set */
-	status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,	/* PHY PMA/PMD module */
-				   LASI_CONTROL,	/* LASI control register */
+
+	/* MIIM_DEV_PHY_PMA		- PHY PMA/PMD module
+	 * LASI_CONTROL			- LASI control register
+	 */
+	status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,
+				   LASI_CONTROL,
 				   &Value);
+
 	if (status != STATUS_SUCCESS)
 		return (STATUS_FAILURE);
 	if (!(Value & LASI_CTL_LS_ALARM_ENABLE)) {
@@ -2253,6 +2934,11 @@
 		      RCV_CONFIG_TZIPV4 |
 		      RCV_CONFIG_HASH_16 |
 		      RCV_CONFIG_SOCKET | RCV_CONFIG_BUFSIZE(MaxFrame));
+
+	if (adapter->asictype == SAHARA_REV_B) {
+		ConfigData |= (RCV_CONFIG_HIPRICTL  |
+				RCV_CONFIG_NEWSTATUSFMT);
+	}
 	WRITE_REG(HwRegs->RcvConfig, ConfigData, TRUE);
 
 	WRITE_REG(HwRegs->XmtConfig, XMT_CONFIG_ENABLE, TRUE);
@@ -2277,21 +2963,25 @@
 static int sxg_phy_init(struct adapter_t *adapter)
 {
 	u32 Value;
-	struct PHY_UCODE *p;
+	struct phy_ucode *p;
 	int status;
 
 	DBG_ERROR("ENTER %s\n", __func__);
 
-	/* Read a register to identify the PHY type */
-	status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,	/* PHY PMA/PMD module */
-				   0xC205,	/* PHY ID register (?) */
-				   &Value);	/*    XXXTODO - add def */
+	/* MIIM_DEV_PHY_PMA - PHY PMA/PMD module
+	 * 0xC205 - PHY ID register (?)
+	 * &Value - XXXTODO - add def
+	 */
+	status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,
+				   0xC205,
+				   &Value);
 	if (status != STATUS_SUCCESS)
 		return (STATUS_FAILURE);
 
-	if (Value == 0x0012) {	/* 0x0012 == AEL2005C PHY(?) - XXXTODO - add def */
-		DBG_ERROR
-		    ("AEL2005C PHY detected.  Downloading PHY microcode.\n");
+	if (Value == 0x0012) {
+		/* 0x0012 == AEL2005C PHY(?) - XXXTODO - add def */
+		DBG_ERROR("AEL2005C PHY detected.  Downloading PHY \
+				 microcode.\n");
 
 		/* Initialize AEL2005C PHY and download PHY microcode */
 		for (p = PhyUcode; p->Addr != 0xFFFF; p++) {
@@ -2299,10 +2989,13 @@
 				/* if address == 0, data == sleep time in ms */
 				mdelay(p->Data);
 			} else {
-				/* write the given data to the specified address */
-				status = sxg_write_mdio_reg(adapter, MIIM_DEV_PHY_PMA,	/* PHY PMA/PMD module */
-							    p->Addr,	/* PHY address */
-							    p->Data);	/* PHY data */
+			/* write the given data to the specified address */
+				status = sxg_write_mdio_reg(adapter,
+							MIIM_DEV_PHY_PMA,
+							/* PHY address */
+							    p->Addr,
+							/* PHY data */
+							    p->Data);
 				if (status != STATUS_SUCCESS)
 					return (STATUS_FAILURE);
 			}
@@ -2324,11 +3017,14 @@
  */
 static void sxg_link_event(struct adapter_t *adapter)
 {
-	struct SXG_HW_REGS *HwRegs = adapter->HwRegs;
+	struct sxg_hw_regs *HwRegs = adapter->HwRegs;
+	struct net_device *netdev = adapter->netdev;
 	enum SXG_LINK_STATE LinkState;
 	int status;
 	u32 Value;
 
+	if (adapter->state == ADAPT_DOWN)
+		return;
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "LinkEvnt",
 		  adapter, 0, 0, 0);
 	DBG_ERROR("ENTER %s\n", __func__);
@@ -2336,35 +3032,57 @@
 	/* Check the Link Status register.  We should have a Link Alarm. */
 	READ_REG(HwRegs->LinkStatus, Value);
 	if (Value & LS_LINK_ALARM) {
-		/* We got a Link Status alarm.  First, pause to let the */
-		/* link state settle (it can bounce a number of times) */
+		/*
+		 * We got a Link Status alarm.  First, pause to let the
+		 * link state settle (it can bounce a number of times)
+		 */
 		mdelay(10);
 
 		/* Now clear the alarm by reading the LASI status register. */
-		status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,	/* PHY PMA/PMD module */
-					   LASI_STATUS,	/* LASI status register */
+		/* MIIM_DEV_PHY_PMA - PHY PMA/PMD module */
+		status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,
+					/* LASI status register */
+					   LASI_STATUS,
 					   &Value);
 		if (status != STATUS_SUCCESS) {
 			DBG_ERROR("Error reading LASI Status MDIO register!\n");
 			sxg_link_state(adapter, SXG_LINK_DOWN);
-/*                      ASSERT(0); */
+		/* ASSERT(0); */
 		}
-		ASSERT(Value & LASI_STATUS_LS_ALARM);
+		/*
+		 * We used to assert that the LASI_LS_ALARM bit was set, as
+		 * it should be.  But there appears to be cases during
+		 * initialization (when the PHY is reset and re-initialized)
+		 * when we get a link alarm, but the status bit is 0 when we
+		 * read it.  Rather than trying to assure this never happens
+		 * (and nver being certain), just ignore it.
+
+		 * ASSERT(Value & LASI_STATUS_LS_ALARM);
+		 */
 
 		/* Now get and set the link state */
 		LinkState = sxg_get_link_state(adapter);
 		sxg_link_state(adapter, LinkState);
 		DBG_ERROR("SXG: Link Alarm occurred.  Link is %s\n",
 			  ((LinkState == SXG_LINK_UP) ? "UP" : "DOWN"));
+		if (LinkState == SXG_LINK_UP) {
+			netif_carrier_on(netdev);
+			netif_tx_start_all_queues(netdev);
+		} else {
+			netif_tx_stop_all_queues(netdev);
+			netif_carrier_off(netdev);
+		}
 	} else {
-		/* XXXTODO - Assuming Link Attention is only being generated for the */
-		/* Link Alarm pin (and not for a XAUI Link Status change), then it's */
-		/* impossible to get here.  Yet we've gotten here twice (under extreme */
-		/* conditions - bouncing the link up and down many times a second). */
-		/* Needs further investigation. */
+		/*
+	 	 * XXXTODO - Assuming Link Attention is only being generated
+	 	 * for the Link Alarm pin (and not for a XAUI Link Status change)
+	 	 * , then it's impossible to get here.  Yet we've gotten here
+	 	 * twice (under extreme conditions - bouncing the link up and
+	 	 * down many times a second). Needs further investigation.
+	 	 */
 		DBG_ERROR("SXG: sxg_link_event: Can't get here!\n");
 		DBG_ERROR("SXG: Link Status == 0x%08X.\n", Value);
-/*              ASSERT(0); */
+		/* ASSERT(0); */
 	}
 	DBG_ERROR("EXIT %s\n", __func__);
 
@@ -2389,10 +3107,15 @@
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "GetLink",
 		  adapter, 0, 0, 0);
 
-	/* Per the Xenpak spec (and the IEEE 10Gb spec?), the link is up if */
-	/* the following 3 bits (from 3 different MDIO registers) are all true. */
-	status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,	/* PHY PMA/PMD module */
-				   PHY_PMA_RCV_DET,	/* PMA/PMD Receive Signal Detect register */
+	/*
+	 * Per the Xenpak spec (and the IEEE 10Gb spec?), the link is up if
+	 * the following 3 bits (from 3 different MDIO registers) are all true.
+	 */
+
+	/* MIIM_DEV_PHY_PMA -  PHY PMA/PMD module */
+	status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,
+				/* PMA/PMD Receive Signal Detect register */
+				   PHY_PMA_RCV_DET,
 				   &Value);
 	if (status != STATUS_SUCCESS)
 		goto bad;
@@ -2401,8 +3124,10 @@
 	if (!(Value & PMA_RCV_DETECT))
 		return (SXG_LINK_DOWN);
 
-	status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PCS,	/* PHY PCS module */
-				   PHY_PCS_10G_STATUS1,	/* PCS 10GBASE-R Status 1 register */
+	/* MIIM_DEV_PHY_PCS - PHY PCS module */
+	status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PCS,
+				/* PCS 10GBASE-R Status 1 register */
+				   PHY_PCS_10G_STATUS1,
 				   &Value);
 	if (status != STATUS_SUCCESS)
 		goto bad;
@@ -2411,8 +3136,9 @@
 	if (!(Value & PCS_10B_BLOCK_LOCK))
 		return (SXG_LINK_DOWN);
 
-	status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_XS,	/* PHY XS module */
-				   PHY_XS_LANE_STATUS,	/* XS Lane Status register */
+	status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_XS,/* PHY XS module */
+				/* XS Lane Status register */
+				   PHY_XS_LANE_STATUS,
 				   &Value);
 	if (status != STATUS_SUCCESS)
 		goto bad;
@@ -2427,7 +3153,7 @@
 	return (SXG_LINK_UP);
 
       bad:
-	/* An error occurred reading an MDIO register.  This shouldn't happen. */
+	/* An error occurred reading an MDIO register. This shouldn't happen. */
 	DBG_ERROR("Error reading an MDIO register!\n");
 	ASSERT(0);
 	return (SXG_LINK_DOWN);
@@ -2448,6 +3174,37 @@
 }
 
 /*
+ * sxg_change_mtu - Change the Maximum Transfer Unit
+ *  * @returns 0 on success, negative on failure
+ */
+int sxg_change_mtu (struct net_device *netdev, int new_mtu)
+{
+	struct adapter_t *adapter = (struct adapter_t *) netdev_priv(netdev);
+
+	if (!((new_mtu == SXG_DEFAULT_MTU) || (new_mtu == SXG_JUMBO_MTU)))
+		return -EINVAL;
+
+	if(new_mtu == netdev->mtu)
+		return 0;
+
+	netdev->mtu = new_mtu;
+
+	if (new_mtu == SXG_JUMBO_MTU) {
+		adapter->JumboEnabled = TRUE;
+		adapter->FrameSize = JUMBOMAXFRAME;
+		adapter->ReceiveBufferSize = SXG_RCV_JUMBO_BUFFER_SIZE;
+	} else {
+		adapter->JumboEnabled = FALSE;
+		adapter->FrameSize = ETHERMAXFRAME;
+		adapter->ReceiveBufferSize = SXG_RCV_DATA_BUFFER_SIZE;
+	}
+
+	sxg_entry_halt(netdev);
+	sxg_entry_open(netdev);
+	return 0;
+}
+
+/*
  * sxg_link_state - Set the link state and if necessary, indicate.
  *	This routine the central point of processing for all link state changes.
  *	Nothing else in the driver should alter the link state or perform
@@ -2460,27 +3217,32 @@
  * Return
  *	None
  */
-static void sxg_link_state(struct adapter_t *adapter, enum SXG_LINK_STATE LinkState)
+static void sxg_link_state(struct adapter_t *adapter,
+				enum SXG_LINK_STATE LinkState)
 {
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "LnkINDCT",
 		  adapter, LinkState, adapter->LinkState, adapter->State);
 
 	DBG_ERROR("ENTER %s\n", __func__);
 
-	/* Hold the adapter lock during this routine.  Maybe move */
-	/* the lock to the caller. */
-	spin_lock(&adapter->AdapterLock);
+	/*
+	 * Hold the adapter lock during this routine.  Maybe move
+	 * the lock to the caller.
+	 */
+	/* IMP TODO : Check if we can survive without taking this lock */
+//	spin_lock(&adapter->AdapterLock);
 	if (LinkState == adapter->LinkState) {
 		/* Nothing changed.. */
-		spin_unlock(&adapter->AdapterLock);
-		DBG_ERROR("EXIT #0 %s\n", __func__);
+//		spin_unlock(&adapter->AdapterLock);
+		DBG_ERROR("EXIT #0 %s. Link status = %d\n",
+					 __func__, LinkState);
 		return;
 	}
 	/* Save the adapter state */
 	adapter->LinkState = LinkState;
 
 	/* Drop the lock and indicate link state */
-	spin_unlock(&adapter->AdapterLock);
+//	spin_unlock(&adapter->AdapterLock);
 	DBG_ERROR("EXIT #1 %s\n", __func__);
 
 	sxg_indicate_link_state(adapter, LinkState);
@@ -2501,14 +3263,16 @@
 static int sxg_write_mdio_reg(struct adapter_t *adapter,
 			      u32 DevAddr, u32 RegAddr, u32 Value)
 {
-	struct SXG_HW_REGS *HwRegs = adapter->HwRegs;
-	u32 AddrOp;		/* Address operation (written to MIIM field reg) */
-	u32 WriteOp;		/* Write operation (written to MIIM field reg) */
-	u32 Cmd;		/* Command (written to MIIM command reg) */
+	struct sxg_hw_regs *HwRegs = adapter->HwRegs;
+	/* Address operation (written to MIIM field reg) */
+	u32 AddrOp;
+	/* Write operation (written to MIIM field reg) */
+	u32 WriteOp;
+	u32 Cmd;/* Command (written to MIIM command reg) */
 	u32 ValueRead;
 	u32 Timeout;
 
-/*  DBG_ERROR("ENTER %s\n", __func__); */
+	/* DBG_ERROR("ENTER %s\n", __func__); */
 
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "WrtMDIO",
 		  adapter, 0, 0, 0);
@@ -2571,7 +3335,7 @@
 		}
 	} while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
 
-/*  DBG_ERROR("EXIT %s\n", __func__); */
+	/* DBG_ERROR("EXIT %s\n", __func__); */
 
 	return (STATUS_SUCCESS);
 }
@@ -2583,7 +3347,7 @@
  *	adapter		- A pointer to our adapter structure
  *  DevAddr     - MDIO device number being addressed
  *  RegAddr     - register address for the specified MDIO device
- *  pValue		- pointer to where to put data read from the MDIO register
+ *  pValue	- pointer to where to put data read from the MDIO register
  *
  * Return
  *	status
@@ -2591,16 +3355,16 @@
 static int sxg_read_mdio_reg(struct adapter_t *adapter,
 			     u32 DevAddr, u32 RegAddr, u32 *pValue)
 {
-	struct SXG_HW_REGS *HwRegs = adapter->HwRegs;
-	u32 AddrOp;		/* Address operation (written to MIIM field reg) */
-	u32 ReadOp;		/* Read operation (written to MIIM field reg) */
-	u32 Cmd;		/* Command (written to MIIM command reg) */
+	struct sxg_hw_regs *HwRegs = adapter->HwRegs;
+	u32 AddrOp;	/* Address operation (written to MIIM field reg) */
+	u32 ReadOp;	/* Read operation (written to MIIM field reg) */
+	u32 Cmd;	/* Command (written to MIIM command reg) */
 	u32 ValueRead;
 	u32 Timeout;
 
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "WrtMDIO",
 		  adapter, 0, 0, 0);
-/*  DBG_ERROR("ENTER %s\n", __func__); */
+	DBG_ERROR("ENTER %s\n", __FUNCTION__);
 
 	/* Ensure values don't exceed field width */
 	DevAddr &= 0x001F;	/* 5-bit field */
@@ -2636,6 +3400,8 @@
 		udelay(100);	/* Timeout in 100us units */
 		READ_REG(HwRegs->MacAmiimIndicator, ValueRead);
 		if (--Timeout == 0) {
+            DBG_ERROR("EXIT %s with STATUS_FAILURE 1\n", __FUNCTION__);
+
 			return (STATUS_FAILURE);
 		}
 	} while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
@@ -2655,6 +3421,8 @@
 		udelay(100);	/* Timeout in 100us units */
 		READ_REG(HwRegs->MacAmiimIndicator, ValueRead);
 		if (--Timeout == 0) {
+            DBG_ERROR("EXIT %s with STATUS_FAILURE 2\n", __FUNCTION__);
+
 			return (STATUS_FAILURE);
 		}
 	} while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
@@ -2663,7 +3431,7 @@
 	READ_REG(HwRegs->MacAmiimField, *pValue);
 	*pValue &= 0xFFFF;	/* data is in the lower 16 bits */
 
-/*  DBG_ERROR("EXIT %s\n", __func__); */
+	DBG_ERROR("EXIT %s\n", __FUNCTION__);
 
 	return (STATUS_SUCCESS);
 }
@@ -2672,22 +3440,21 @@
  * Functions to obtain the CRC corresponding to the destination mac address.
  * This is a standard ethernet CRC in that it is a 32-bit, reflected CRC using
  * the polynomial:
- *   x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1.
+ *   x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5
+ *    + x^4 + x^2 + x^1.
  *
- * After the CRC for the 6 bytes is generated (but before the value is complemented),
- * we must then transpose the value and return bits 30-23.
- *
+ * After the CRC for the 6 bytes is generated (but before the value is
+ * complemented), we must then transpose the value and return bits 30-23.
  */
-static u32 sxg_crc_table[256];	/* Table of CRC's for all possible byte values */
+static u32 sxg_crc_table[256];/* Table of CRC's for all possible byte values */
+static u32 sxg_crc_init;	/* Is table initialized */
 
-/*
- *  Contruct the CRC32 table
- */
+/* Contruct the CRC32 table */
 static void sxg_mcast_init_crc32(void)
 {
-	u32 c;			/*  CRC shit reg                 */
-	u32 e = 0;		/*  Poly X-or pattern            */
-	int i;			/*  counter                      */
+	u32 c;			/*  CRC shit reg */
+	u32 e = 0;		/*  Poly X-or pattern */
+	int i;			/*  counter */
 	int k;			/*  byte being shifted into crc  */
 
 	static int p[] = { 0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26 };
@@ -2705,8 +3472,6 @@
 	}
 }
 
-#if XXXTODO
-static u32 sxg_crc_init;	/* Is table initialized */
 /*
  *  Return the MAC hast as described above.
  */
@@ -2737,25 +3502,31 @@
 
 static void sxg_mcast_set_mask(struct adapter_t *adapter)
 {
-	struct SXG_UCODE_REGS *sxg_regs = adapter->UcodeRegs;
+	struct sxg_ucode_regs *sxg_regs = adapter->UcodeRegs;
 
-	DBG_ERROR("%s ENTER (%s) macopts[%x] mask[%llx]\n", __func__,
+	DBG_ERROR("%s ENTER (%s) MacFilter[%x] mask[%llx]\n", __FUNCTION__,
 		  adapter->netdev->name, (unsigned int)adapter->MacFilter,
 		  adapter->MulticastMask);
 
 	if (adapter->MacFilter & (MAC_ALLMCAST | MAC_PROMISC)) {
-		/* Turn on all multicast addresses. We have to do this for promiscuous
-		 * mode as well as ALLMCAST mode.  It saves the Microcode from having
-		 * to keep state about the MAC configuration.
+		/*
+		 * Turn on all multicast addresses. We have to do this for
+		 * promiscuous mode as well as ALLMCAST mode.  It saves the
+		 * Microcode from having keep state about the MAC configuration
 		 */
-/*              DBG_ERROR("sxg: %s macopts = MAC_ALLMCAST | MAC_PROMISC\n      SLUT MODE!!!\n",__func__); */
+		/* DBG_ERROR("sxg: %s MacFilter = MAC_ALLMCAST | MAC_PROMISC\n \
+		 * 				SLUT MODE!!!\n",__func__);
+		 */
 		WRITE_REG(sxg_regs->McastLow, 0xFFFFFFFF, FLUSH);
 		WRITE_REG(sxg_regs->McastHigh, 0xFFFFFFFF, FLUSH);
-/*        DBG_ERROR("%s (%s) WRITE to slic_regs slic_mcastlow&high 0xFFFFFFFF\n",__func__, adapter->netdev->name); */
+		/* DBG_ERROR("%s (%s) WRITE to slic_regs slic_mcastlow&high \
+		 * 0xFFFFFFFF\n",__func__, adapter->netdev->name);
+		 */
 
 	} else {
-		/* Commit our multicast mast to the SLIC by writing to the multicast
-		 * address mask registers
+		/*
+		 * Commit our multicast mast to the SLIC by writing to the
+		 * multicast address mask registers
 		 */
 		DBG_ERROR("%s (%s) WRITE mcastlow[%lx] mcasthigh[%lx]\n",
 			  __func__, adapter->netdev->name,
@@ -2771,38 +3542,6 @@
 	}
 }
 
-/*
- *  Allocate a mcast_address structure to hold the multicast address.
- *  Link it in.
- */
-static int sxg_mcast_add_list(struct adapter_t *adapter, char *address)
-{
-	p_mcast_address_t mcaddr, mlist;
-	bool equaladdr;
-
-	/* Check to see if it already exists */
-	mlist = adapter->mcastaddrs;
-	while (mlist) {
-		ETHER_EQ_ADDR(mlist->address, address, equaladdr);
-		if (equaladdr) {
-			return (STATUS_SUCCESS);
-		}
-		mlist = mlist->next;
-	}
-
-	/* Doesn't already exist.  Allocate a structure to hold it */
-	mcaddr = kmalloc(sizeof(mcast_address_t), GFP_ATOMIC);
-	if (mcaddr == NULL)
-		return 1;
-
-	memcpy(mcaddr->address, address, 6);
-
-	mcaddr->next = adapter->mcastaddrs;
-	adapter->mcastaddrs = mcaddr;
-
-	return (STATUS_SUCCESS);
-}
-
 static void sxg_mcast_set_bit(struct adapter_t *adapter, char *address)
 {
 	unsigned char crcpoly;
@@ -2810,7 +3549,8 @@
 	/* Get the CRC polynomial for the mac address */
 	crcpoly = sxg_mcast_get_mac_hash(address);
 
-	/* We only have space on the SLIC for 64 entries.  Lop
+	/*
+	 * We only have space on the SLIC for 64 entries.  Lop
 	 * off the top two bits. (2^6 = 64)
 	 */
 	crcpoly &= 0x3F;
@@ -2819,76 +3559,119 @@
 	adapter->MulticastMask |= (u64) 1 << crcpoly;
 }
 
-static void sxg_mcast_set_list(p_net_device dev)
+/*
+ *   Function takes MAC addresses from dev_mc_list and generates the Mask
+ */
+
+static void sxg_set_mcast_addr(struct adapter_t *adapter)
+{
+        struct dev_mc_list *mclist;
+        struct net_device *dev = adapter->netdev;
+        int i;
+
+        if (adapter->MacFilter & (MAC_ALLMCAST | MAC_MCAST)) {
+               for (i = 0, mclist = dev->mc_list; i < dev->mc_count;
+                             i++, mclist = mclist->next) {
+                        sxg_mcast_set_bit(adapter,mclist->da_addr);
+                }
+        }
+        sxg_mcast_set_mask(adapter);
+}
+
+static void sxg_mcast_set_list(struct net_device *dev)
 {
 	struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev);
-	int status = STATUS_SUCCESS;
-	int i;
-	char *addresses;
-	struct dev_mc_list *mc_list = dev->mc_list;
-	int mc_count = dev->mc_count;
 
 	ASSERT(adapter);
+	if (dev->flags & IFF_PROMISC)
+		adapter->MacFilter |= MAC_PROMISC;
+        if (dev->flags & IFF_MULTICAST)
+                adapter->MacFilter |= MAC_MCAST;
+        if (dev->flags & IFF_ALLMULTI)
+                adapter->MacFilter |= MAC_ALLMCAST;
 
-	for (i = 1; i <= mc_count; i++) {
-		addresses = (char *)&mc_list->dmi_addr;
-		if (mc_list->dmi_addrlen == 6) {
-			status = sxg_mcast_add_list(adapter, addresses);
-			if (status != STATUS_SUCCESS) {
-				break;
-			}
-		} else {
-			status = -EINVAL;
-			break;
-		}
-		sxg_mcast_set_bit(adapter, addresses);
-		mc_list = mc_list->next;
-	}
-
-	DBG_ERROR("%s a->devflags_prev[%x] dev->flags[%x] status[%x]\n",
-		  __func__, adapter->devflags_prev, dev->flags, status);
-	if (adapter->devflags_prev != dev->flags) {
-		adapter->macopts = MAC_DIRECTED;
-		if (dev->flags) {
-			if (dev->flags & IFF_BROADCAST) {
-				adapter->macopts |= MAC_BCAST;
-			}
-			if (dev->flags & IFF_PROMISC) {
-				adapter->macopts |= MAC_PROMISC;
-			}
-			if (dev->flags & IFF_ALLMULTI) {
-				adapter->macopts |= MAC_ALLMCAST;
-			}
-			if (dev->flags & IFF_MULTICAST) {
-				adapter->macopts |= MAC_MCAST;
-			}
-		}
-		adapter->devflags_prev = dev->flags;
-		DBG_ERROR("%s call sxg_config_set adapter->macopts[%x]\n",
-			  __func__, adapter->macopts);
-		sxg_config_set(adapter, TRUE);
-	} else {
-		if (status == STATUS_SUCCESS) {
-			sxg_mcast_set_mask(adapter);
-		}
-	}
-	return;
+	//XXX handle other flags as well
+	sxg_set_mcast_addr(adapter);
 }
-#endif
 
-static void sxg_unmap_mmio_space(struct adapter_t *adapter)
+void sxg_free_sgl_buffers(struct adapter_t *adapter)
 {
-#if LINUX_FREES_ADAPTER_RESOURCES
-/*      if (adapter->Regs) { */
-/*              iounmap(adapter->Regs); */
-/*      } */
-/*      adapter->slic_regs = NULL; */
-#endif
+        struct list_entry               *ple;
+        struct sxg_scatter_gather       *Sgl;
+
+        while(!(IsListEmpty(&adapter->AllSglBuffers))) {
+ 		ple = RemoveHeadList(&adapter->AllSglBuffers);
+ 		Sgl = container_of(ple, struct sxg_scatter_gather, AllList);
+ 		kfree(Sgl);
+                adapter->AllSglBufferCount--;
+        }
 }
 
-#if XXXTODO
+void sxg_free_rcvblocks(struct adapter_t *adapter)
+{
+	u32				i;
+       	void                            *temp_RcvBlock;
+       	struct list_entry               *ple;
+       	struct sxg_rcv_block_hdr        *RcvBlockHdr;
+	struct sxg_rcv_data_buffer_hdr	*RcvDataBufferHdr;
+        ASSERT((adapter->state == SXG_STATE_INITIALIZING) ||
+                    (adapter->state == SXG_STATE_HALTING));
+        while(!(IsListEmpty(&adapter->AllRcvBlocks))) {
+
+                 ple = RemoveHeadList(&adapter->AllRcvBlocks);
+                 RcvBlockHdr = container_of(ple, struct sxg_rcv_block_hdr, AllList);
+
+                if(RcvBlockHdr->VirtualAddress) {
+                        temp_RcvBlock = RcvBlockHdr->VirtualAddress;
+
+                        for(i=0; i< SXG_RCV_DESCRIPTORS_PER_BLOCK;
+                             i++, temp_RcvBlock += SXG_RCV_DATA_HDR_SIZE) {
+                                RcvDataBufferHdr =
+                                        (struct sxg_rcv_data_buffer_hdr *)temp_RcvBlock;
+                                SXG_FREE_RCV_PACKET(RcvDataBufferHdr);
+                        }
+                }
+
+                pci_free_consistent(adapter->pcidev,
+                                         SXG_RCV_BLOCK_SIZE(SXG_RCV_DATA_HDR_SIZE),
+                                         RcvBlockHdr->VirtualAddress,
+                                         RcvBlockHdr->PhysicalAddress);
+                adapter->AllRcvBlockCount--;
+	}
+	ASSERT(adapter->AllRcvBlockCount == 0);
+	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFrRBlk",
+			adapter, 0, 0, 0);
+}
+void sxg_free_mcast_addrs(struct adapter_t *adapter)
+{
+	struct sxg_multicast_address    *address;
+        while(adapter->MulticastAddrs) {
+                address = adapter->MulticastAddrs;
+                adapter->MulticastAddrs = address->Next;
+		kfree(address);
+         }
+
+        adapter->MulticastMask= 0;
+}
+
+void sxg_unmap_resources(struct adapter_t *adapter)
+{
+	if(adapter->HwRegs) {
+        	iounmap((void *)adapter->HwRegs);
+         }
+        if(adapter->UcodeRegs) {
+		iounmap((void *)adapter->UcodeRegs);
+        }
+
+        ASSERT(adapter->AllRcvBlockCount == 0);
+        SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFrRBlk",
+                           adapter, 0, 0, 0);
+}
+
+
+
 /*
- * SxgFreeResources - Free everything allocated in SxgAllocateResources
+ * sxg_free_resources - Free everything allocated in SxgAllocateResources
  *
  * Arguments -
  *	adapter		- A pointer to our adapter structure
@@ -2896,94 +3679,76 @@
  * Return
  *	none
  */
-void SxgFreeResources(struct adapter_t *adapter)
+void sxg_free_resources(struct adapter_t *adapter)
 {
 	u32 RssIds, IsrCount;
-	PTCP_OBJECT TcpObject;
-	u32 i;
-	BOOLEAN TimerCancelled;
-
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "FreeRes",
-		  adapter, adapter->MaxTcbs, 0, 0);
-
 	RssIds = SXG_RSS_CPU_COUNT(adapter);
-	IsrCount = adapter->MsiEnabled ? RssIds : 1;
+	IsrCount = adapter->msi_enabled ? RssIds : 1;
 
 	if (adapter->BasicAllocations == FALSE) {
-		/* No allocations have been made, including spinlocks, */
-		/* or listhead initializations.  Return. */
+		/*
+		 * No allocations have been made, including spinlocks,
+		 * or listhead initializations.  Return.
+		 */
 		return;
 	}
 
 	if (!(IsListEmpty(&adapter->AllRcvBlocks))) {
-		SxgFreeRcvBlocks(adapter);
+		sxg_free_rcvblocks(adapter);
 	}
 	if (!(IsListEmpty(&adapter->AllSglBuffers))) {
-		SxgFreeSglBuffers(adapter);
+		sxg_free_sgl_buffers(adapter);
 	}
-	/* Free event queues. */
-	if (adapter->EventRings) {
-		pci_free_consistent(adapter->pcidev,
-				    sizeof(struct SXG_EVENT_RING) * RssIds,
-				    adapter->EventRings, adapter->PEventRings);
-	}
-	if (adapter->Isr) {
-		pci_free_consistent(adapter->pcidev,
-				    sizeof(u32) * IsrCount,
-				    adapter->Isr, adapter->PIsr);
-	}
+
 	if (adapter->XmtRingZeroIndex) {
 		pci_free_consistent(adapter->pcidev,
 				    sizeof(u32),
 				    adapter->XmtRingZeroIndex,
 				    adapter->PXmtRingZeroIndex);
 	}
-	if (adapter->IndirectionTable) {
-		pci_free_consistent(adapter->pcidev,
-				    SXG_MAX_RSS_TABLE_SIZE,
-				    adapter->IndirectionTable,
-				    adapter->PIndirectionTable);
+        if (adapter->Isr) {
+                pci_free_consistent(adapter->pcidev,
+                                    sizeof(u32) * IsrCount,
+                                    adapter->Isr, adapter->PIsr);
+        }
+
+        if (adapter->EventRings) {
+                pci_free_consistent(adapter->pcidev,
+                                    sizeof(struct sxg_event_ring) * RssIds,
+                                    adapter->EventRings, adapter->PEventRings);
+        }
+        if (adapter->RcvRings) {
+                pci_free_consistent(adapter->pcidev,
+                                   sizeof(struct sxg_rcv_ring) * 1,
+                                   adapter->RcvRings,
+                                   adapter->PRcvRings);
+                adapter->RcvRings = NULL;
+        }
+
+        if(adapter->XmtRings) {
+                pci_free_consistent(adapter->pcidev,
+                                            sizeof(struct sxg_xmt_ring) * 1,
+                                            adapter->XmtRings,
+                                            adapter->PXmtRings);
+                        adapter->XmtRings = NULL;
+        }
+
+	if (adapter->ucode_stats) {
+		pci_unmap_single(adapter->pcidev,
+				sizeof(struct sxg_ucode_stats),
+				 adapter->pucode_stats, PCI_DMA_FROMDEVICE);
+		adapter->ucode_stats = NULL;
 	}
 
-	SXG_FREE_PACKET_POOL(adapter->PacketPoolHandle);
-	SXG_FREE_BUFFER_POOL(adapter->BufferPoolHandle);
 
 	/* Unmap register spaces */
-	SxgUnmapResources(adapter);
+	sxg_unmap_resources(adapter);
 
-	/* Deregister DMA */
-	if (adapter->DmaHandle) {
-		SXG_DEREGISTER_DMA(adapter->DmaHandle);
-	}
-	/* Deregister interrupt */
-	SxgDeregisterInterrupt(adapter);
-
-	/* Possibly free system info (5.2 only) */
-	SXG_RELEASE_SYSTEM_INFO(adapter);
-
-	SxgDiagFreeResources(adapter);
-
-	SxgFreeMCastAddrs(adapter);
-
-	if (SXG_TIMER_ALLOCATED(adapter->ResetTimer)) {
-		SXG_CANCEL_TIMER(adapter->ResetTimer, TimerCancelled);
-		SXG_FREE_TIMER(adapter->ResetTimer);
-	}
-	if (SXG_TIMER_ALLOCATED(adapter->RssTimer)) {
-		SXG_CANCEL_TIMER(adapter->RssTimer, TimerCancelled);
-		SXG_FREE_TIMER(adapter->RssTimer);
-	}
-	if (SXG_TIMER_ALLOCATED(adapter->OffloadTimer)) {
-		SXG_CANCEL_TIMER(adapter->OffloadTimer, TimerCancelled);
-		SXG_FREE_TIMER(adapter->OffloadTimer);
-	}
+	sxg_free_mcast_addrs(adapter);
 
 	adapter->BasicAllocations = FALSE;
 
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFreeRes",
-		  adapter, adapter->MaxTcbs, 0, 0);
 }
-#endif
 
 /*
  * sxg_allocate_complete -
@@ -3000,31 +3765,34 @@
  * Return
  *	None.
  */
-static void sxg_allocate_complete(struct adapter_t *adapter,
+static int sxg_allocate_complete(struct adapter_t *adapter,
 				  void *VirtualAddress,
 				  dma_addr_t PhysicalAddress,
-				  u32 Length, enum SXG_BUFFER_TYPE Context)
+				  u32 Length, enum sxg_buffer_type Context)
 {
+	int status = 0;
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AllocCmp",
 		  adapter, VirtualAddress, Length, Context);
-	ASSERT(adapter->AllocationsPending);
-	--adapter->AllocationsPending;
+	ASSERT(atomic_read(&adapter->pending_allocations));
+	atomic_dec(&adapter->pending_allocations);
 
 	switch (Context) {
 
 	case SXG_BUFFER_TYPE_RCV:
-		sxg_allocate_rcvblock_complete(adapter,
+		status = sxg_allocate_rcvblock_complete(adapter,
 					       VirtualAddress,
 					       PhysicalAddress, Length);
 		break;
 	case SXG_BUFFER_TYPE_SGL:
-		sxg_allocate_sgl_buffer_complete(adapter, (struct SXG_SCATTER_GATHER*)
+		sxg_allocate_sgl_buffer_complete(adapter, (struct sxg_scatter_gather *)
 						 VirtualAddress,
 						 PhysicalAddress, Length);
 		break;
 	}
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlocCmp",
 		  adapter, VirtualAddress, Length, Context);
+
+	return status;
 }
 
 /*
@@ -3040,7 +3808,7 @@
  *	int
  */
 static int sxg_allocate_buffer_memory(struct adapter_t *adapter,
-				      u32 Size, enum SXG_BUFFER_TYPE BufferType)
+				      u32 Size, enum sxg_buffer_type BufferType)
 {
 	int status;
 	void *Buffer;
@@ -3048,39 +3816,40 @@
 
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AllocMem",
 		  adapter, Size, BufferType, 0);
-	/* Grab the adapter lock and check the state. */
-	/* If we're in anything other than INITIALIZING or */
-	/* RUNNING state, fail.  This is to prevent */
-	/* allocations in an improper driver state */
-	spin_lock(&adapter->AdapterLock);
+	/*
+	 * Grab the adapter lock and check the state. If we're in anything other
+	 * than INITIALIZING or RUNNING state, fail.  This is to prevent
+	 * allocations in an improper driver state
+	 */
 
-	/* Increment the AllocationsPending count while holding */
-	/* the lock.  Pause processing relies on this */
-	++adapter->AllocationsPending;
-	spin_unlock(&adapter->AdapterLock);
+ 	atomic_inc(&adapter->pending_allocations);
 
-	/* At initialization time allocate resources synchronously. */
-	Buffer = pci_alloc_consistent(adapter->pcidev, Size, &pBuffer);
+	if(BufferType != SXG_BUFFER_TYPE_SGL)
+		Buffer = pci_alloc_consistent(adapter->pcidev, Size, &pBuffer);
+	else {
+		Buffer = kzalloc(Size, GFP_ATOMIC);
+		pBuffer = (dma_addr_t)NULL;
+	}
 	if (Buffer == NULL) {
-		spin_lock(&adapter->AdapterLock);
-		/* Decrement the AllocationsPending count while holding */
-		/* the lock.  Pause processing relies on this */
-		--adapter->AllocationsPending;
-		spin_unlock(&adapter->AdapterLock);
+		/*
+		 * Decrement the AllocationsPending count while holding
+		 * the lock.  Pause processing relies on this
+		 */
+ 		atomic_dec(&adapter->pending_allocations);
 		SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AlcMemF1",
 			  adapter, Size, BufferType, 0);
 		return (STATUS_RESOURCES);
 	}
-	sxg_allocate_complete(adapter, Buffer, pBuffer, Size, BufferType);
-	status = STATUS_SUCCESS;
+	status = sxg_allocate_complete(adapter, Buffer, pBuffer, Size, BufferType);
 
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlocMem",
 		  adapter, Size, BufferType, status);
-	return (status);
+	return status;
 }
 
 /*
- * sxg_allocate_rcvblock_complete - Complete a receive descriptor block allocation
+ * sxg_allocate_rcvblock_complete - Complete a receive descriptor
+ * 					block allocation
  *
  * Arguments -
  *	adapter				- A pointer to our adapter structure
@@ -3089,9 +3858,8 @@
  *	Length				- Memory length
  *
  * Return
- *
  */
-static void sxg_allocate_rcvblock_complete(struct adapter_t *adapter,
+static int sxg_allocate_rcvblock_complete(struct adapter_t *adapter,
 					   void *RcvBlock,
 					   dma_addr_t PhysicalAddress,
 					   u32 Length)
@@ -3099,11 +3867,11 @@
 	u32 i;
 	u32 BufferSize = adapter->ReceiveBufferSize;
 	u64 Paddr;
-	struct SXG_RCV_BLOCK_HDR *RcvBlockHdr;
-	unsigned char *RcvDataBuffer;
-	struct SXG_RCV_DATA_BUFFER_HDR *RcvDataBufferHdr;
-	struct SXG_RCV_DESCRIPTOR_BLOCK *RcvDescriptorBlock;
-	struct SXG_RCV_DESCRIPTOR_BLOCK_HDR *RcvDescriptorBlockHdr;
+	void *temp_RcvBlock;
+	struct sxg_rcv_block_hdr *RcvBlockHdr;
+	struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr;
+	struct sxg_rcv_descriptor_block *RcvDescriptorBlock;
+	struct sxg_rcv_descriptor_block_hdr *RcvDescriptorBlockHdr;
 
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AlRcvBlk",
 		  adapter, RcvBlock, Length, 0);
@@ -3113,42 +3881,33 @@
 	memset(RcvBlock, 0, Length);
 	ASSERT((BufferSize == SXG_RCV_DATA_BUFFER_SIZE) ||
 	       (BufferSize == SXG_RCV_JUMBO_BUFFER_SIZE));
-	ASSERT(Length == SXG_RCV_BLOCK_SIZE(BufferSize));
-	/* First, initialize the contained pool of receive data */
-	/* buffers.  This initialization requires NBL/NB/MDL allocations, */
-	/* If any of them fail, free the block and return without */
-	/* queueing the shared memory */
-	RcvDataBuffer = RcvBlock;
-#if 0
-	for (i = 0, Paddr = *PhysicalAddress;
-	     i < SXG_RCV_DESCRIPTORS_PER_BLOCK;
-	     i++, Paddr.LowPart += BufferSize, RcvDataBuffer += BufferSize)
-#endif
-		for (i = 0, Paddr = PhysicalAddress;
-		     i < SXG_RCV_DESCRIPTORS_PER_BLOCK;
-		     i++, Paddr += BufferSize, RcvDataBuffer += BufferSize) {
-			/* */
-			RcvDataBufferHdr =
-			    (struct SXG_RCV_DATA_BUFFER_HDR*) (RcvDataBuffer +
-							SXG_RCV_DATA_BUFFER_HDR_OFFSET
-							(BufferSize));
-			RcvDataBufferHdr->VirtualAddress = RcvDataBuffer;
-			RcvDataBufferHdr->PhysicalAddress = Paddr;
-			RcvDataBufferHdr->State = SXG_BUFFER_UPSTREAM;	/* For FREE macro assertion */
-			RcvDataBufferHdr->Size =
-			    SXG_RCV_BUFFER_DATA_SIZE(BufferSize);
+	ASSERT(Length == SXG_RCV_BLOCK_SIZE(SXG_RCV_DATA_HDR_SIZE));
+	/*
+	 * First, initialize the contained pool of receive data buffers.
+	 * This initialization requires NBL/NB/MDL allocations, if any of them
+	 * fail, free the block and return without queueing the shared memory
+	 */
+	//RcvDataBuffer = RcvBlock;
+	temp_RcvBlock = RcvBlock;
+	for (i = 0; i < SXG_RCV_DESCRIPTORS_PER_BLOCK;
+		 i++, temp_RcvBlock += SXG_RCV_DATA_HDR_SIZE) {
+		RcvDataBufferHdr = (struct sxg_rcv_data_buffer_hdr *)
+					temp_RcvBlock;
+		/* For FREE macro assertion */
+		RcvDataBufferHdr->State = SXG_BUFFER_UPSTREAM;
+		SXG_ALLOCATE_RCV_PACKET(adapter, RcvDataBufferHdr, BufferSize);
+		if (RcvDataBufferHdr->SxgDumbRcvPacket == NULL)
+			goto fail;
 
-			SXG_ALLOCATE_RCV_PACKET(adapter, RcvDataBufferHdr);
-			if (RcvDataBufferHdr->SxgDumbRcvPacket == NULL)
-				goto fail;
+	}
 
-		}
+	/*
+	 * Place this entire block of memory on the AllRcvBlocks queue so it
+	 * can be free later
+	 */
 
-	/* Place this entire block of memory on the AllRcvBlocks queue so it can be */
-	/* free later */
-	RcvBlockHdr =
-	    (struct SXG_RCV_BLOCK_HDR*) ((unsigned char *)RcvBlock +
-				  SXG_RCV_BLOCK_HDR_OFFSET(BufferSize));
+	RcvBlockHdr = (struct sxg_rcv_block_hdr *) ((unsigned char *)RcvBlock +
+			SXG_RCV_BLOCK_HDR_OFFSET(SXG_RCV_DATA_HDR_SIZE));
 	RcvBlockHdr->VirtualAddress = RcvBlock;
 	RcvBlockHdr->PhysicalAddress = PhysicalAddress;
 	spin_lock(&adapter->RcvQLock);
@@ -3156,14 +3915,15 @@
 	InsertTailList(&adapter->AllRcvBlocks, &RcvBlockHdr->AllList);
 	spin_unlock(&adapter->RcvQLock);
 
-	/* Now free the contained receive data buffers that we initialized above */
-	RcvDataBuffer = RcvBlock;
+	/* Now free the contained receive data buffers that we
+	 * initialized above */
+	temp_RcvBlock = RcvBlock;
 	for (i = 0, Paddr = PhysicalAddress;
 	     i < SXG_RCV_DESCRIPTORS_PER_BLOCK;
-	     i++, Paddr += BufferSize, RcvDataBuffer += BufferSize) {
-		RcvDataBufferHdr = (struct SXG_RCV_DATA_BUFFER_HDR*) (RcvDataBuffer +
-							       SXG_RCV_DATA_BUFFER_HDR_OFFSET
-							       (BufferSize));
+	     i++, Paddr += SXG_RCV_DATA_HDR_SIZE,
+	     temp_RcvBlock += SXG_RCV_DATA_HDR_SIZE) {
+		RcvDataBufferHdr =
+			(struct sxg_rcv_data_buffer_hdr *)temp_RcvBlock;
 		spin_lock(&adapter->RcvQLock);
 		SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
 		spin_unlock(&adapter->RcvQLock);
@@ -3171,13 +3931,13 @@
 
 	/* Locate the descriptor block and put it on a separate free queue */
 	RcvDescriptorBlock =
-	    (struct SXG_RCV_DESCRIPTOR_BLOCK*) ((unsigned char *)RcvBlock +
+	    (struct sxg_rcv_descriptor_block *) ((unsigned char *)RcvBlock +
 					 SXG_RCV_DESCRIPTOR_BLOCK_OFFSET
-					 (BufferSize));
+					 (SXG_RCV_DATA_HDR_SIZE));
 	RcvDescriptorBlockHdr =
-	    (struct SXG_RCV_DESCRIPTOR_BLOCK_HDR*) ((unsigned char *)RcvBlock +
+	    (struct sxg_rcv_descriptor_block_hdr *) ((unsigned char *)RcvBlock +
 					     SXG_RCV_DESCRIPTOR_BLOCK_HDR_OFFSET
-					     (BufferSize));
+					     (SXG_RCV_DATA_HDR_SIZE));
 	RcvDescriptorBlockHdr->VirtualAddress = RcvDescriptorBlock;
 	RcvDescriptorBlockHdr->PhysicalAddress = Paddr;
 	spin_lock(&adapter->RcvQLock);
@@ -3185,17 +3945,15 @@
 	spin_unlock(&adapter->RcvQLock);
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlRBlk",
 		  adapter, RcvBlock, Length, 0);
-	return;
-      fail:
+	return STATUS_SUCCESS;
+fail:
 	/* Free any allocated resources */
 	if (RcvBlock) {
-		RcvDataBuffer = RcvBlock;
+		temp_RcvBlock = RcvBlock;
 		for (i = 0; i < SXG_RCV_DESCRIPTORS_PER_BLOCK;
-		     i++, RcvDataBuffer += BufferSize) {
+		     i++, temp_RcvBlock += SXG_RCV_DATA_HDR_SIZE) {
 			RcvDataBufferHdr =
-			    (struct SXG_RCV_DATA_BUFFER_HDR*) (RcvDataBuffer +
-							SXG_RCV_DATA_BUFFER_HDR_OFFSET
-							(BufferSize));
+			    (struct sxg_rcv_data_buffer_hdr *)temp_RcvBlock;
 			SXG_FREE_RCV_PACKET(RcvDataBufferHdr);
 		}
 		pci_free_consistent(adapter->pcidev,
@@ -3206,6 +3964,10 @@
 		  adapter, adapter->FreeRcvBufferCount,
 		  adapter->FreeRcvBlockCount, adapter->AllRcvBlockCount);
 	adapter->Stats.NoMem++;
+	/* As allocation failed, free all previously allocated blocks..*/
+	//sxg_free_rcvblocks(adapter);
+
+	return STATUS_RESOURCES;
 }
 
 /*
@@ -3213,46 +3975,65 @@
  *
  * Arguments -
  *	adapter				- A pointer to our adapter structure
- *	SxgSgl				- SXG_SCATTER_GATHER buffer
+ *	SxgSgl				- struct sxg_scatter_gather buffer
  *	PhysicalAddress		- Physical address
  *	Length				- Memory length
  *
  * Return
- *
  */
 static void sxg_allocate_sgl_buffer_complete(struct adapter_t *adapter,
-					     struct SXG_SCATTER_GATHER *SxgSgl,
+					     struct sxg_scatter_gather *SxgSgl,
 					     dma_addr_t PhysicalAddress,
 					     u32 Length)
 {
+	unsigned long sgl_flags;
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AlSglCmp",
 		  adapter, SxgSgl, Length, 0);
-	spin_lock(&adapter->SglQLock);
+	spin_lock_irqsave(&adapter->SglQLock, sgl_flags);
 	adapter->AllSglBufferCount++;
-	memset(SxgSgl, 0, sizeof(struct SXG_SCATTER_GATHER*));
-	SxgSgl->PhysicalAddress = PhysicalAddress;	/* *PhysicalAddress; */
-	SxgSgl->adapter = adapter;	/* Initialize backpointer once */
+	/* PhysicalAddress; */
+	SxgSgl->PhysicalAddress = PhysicalAddress;
+	/* Initialize backpointer once */
+	SxgSgl->adapter = adapter;
 	InsertTailList(&adapter->AllSglBuffers, &SxgSgl->AllList);
-	spin_unlock(&adapter->SglQLock);
+	spin_unlock_irqrestore(&adapter->SglQLock, sgl_flags);
 	SxgSgl->State = SXG_BUFFER_BUSY;
 	SXG_FREE_SGL_BUFFER(adapter, SxgSgl, NULL);
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlSgl",
 		  adapter, SxgSgl, Length, 0);
 }
 
-static unsigned char temp_mac_address[6] =
-    { 0x00, 0xab, 0xcd, 0xef, 0x12, 0x69 };
 
-static void sxg_adapter_set_hwaddr(struct adapter_t *adapter)
+static int sxg_adapter_set_hwaddr(struct adapter_t *adapter)
 {
-/*  DBG_ERROR ("%s ENTER card->config_set[%x] port[%d] physport[%d] funct#[%d]\n", __func__, */
-/*             card->config_set, adapter->port, adapter->physport, adapter->functionnumber); */
-/* */
-/*  sxg_dbg_macaddrs(adapter); */
+	/*
+	 *  DBG_ERROR ("%s ENTER card->config_set[%x] port[%d] physport[%d] \
+	 *  funct#[%d]\n", __func__, card->config_set,
+	 *  adapter->port, adapter->physport, adapter->functionnumber);
+	 *
+	 *  sxg_dbg_macaddrs(adapter);
+	 */
+	/* DBG_ERROR ("%s AFTER copying from config.macinfo into currmacaddr\n",
+	 *	   		__FUNCTION__);
+	 */
 
-	memcpy(adapter->macaddr, temp_mac_address, sizeof(struct SXG_CONFIG_MAC));
-/*      DBG_ERROR ("%s AFTER copying from config.macinfo into currmacaddr\n", __func__); */
-/*      sxg_dbg_macaddrs(adapter); */
+	/* sxg_dbg_macaddrs(adapter); */
+
+	struct net_device * dev = adapter->netdev;
+	if(!dev)
+	{
+		printk("sxg: Dev is Null\n");
+	}
+
+        DBG_ERROR("%s ENTER (%s)\n", __FUNCTION__, adapter->netdev->name);
+
+        if (netif_running(dev)) {
+                return -EBUSY;
+        }
+        if (!adapter) {
+                return -EBUSY;
+        }
+
 	if (!(adapter->currmacaddr[0] ||
 	      adapter->currmacaddr[1] ||
 	      adapter->currmacaddr[2] ||
@@ -3262,14 +4043,16 @@
 	}
 	if (adapter->netdev) {
 		memcpy(adapter->netdev->dev_addr, adapter->currmacaddr, 6);
+		memcpy(adapter->netdev->perm_addr, adapter->currmacaddr, 6);
 	}
-/*  DBG_ERROR ("%s EXIT port %d\n", __func__, adapter->port); */
+	/* DBG_ERROR ("%s EXIT port %d\n", __func__, adapter->port); */
 	sxg_dbg_macaddrs(adapter);
 
+	return 0;
 }
 
 #if XXXTODO
-static int sxg_mac_set_address(p_net_device dev, void *ptr)
+static int sxg_mac_set_address(struct net_device *dev, void *ptr)
 {
 	struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev);
 	struct sockaddr *addr = ptr;
@@ -3300,34 +4083,34 @@
 }
 #endif
 
-/*****************************************************************************/
-/*************  SXG DRIVER FUNCTIONS  (below) ********************************/
-/*****************************************************************************/
-
 /*
+ * SXG DRIVER FUNCTIONS  (below)
+ *
  * sxg_initialize_adapter - Initialize adapter
  *
  * Arguments -
  *	adapter		- A pointer to our adapter structure
  *
- * Return
- *	int
+ * Return - int
  */
 static int sxg_initialize_adapter(struct adapter_t *adapter)
 {
 	u32 RssIds, IsrCount;
 	u32 i;
 	int status;
+	int sxg_rcv_ring_size = SXG_RCV_RING_SIZE;
 
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "InitAdpt",
 		  adapter, 0, 0, 0);
 
 	RssIds = 1;		/*  XXXTODO  SXG_RSS_CPU_COUNT(adapter); */
-	IsrCount = adapter->MsiEnabled ? RssIds : 1;
+	IsrCount = adapter->msi_enabled ? RssIds : 1;
 
-	/* Sanity check SXG_UCODE_REGS structure definition to */
-	/* make sure the length is correct */
-	ASSERT(sizeof(struct SXG_UCODE_REGS) == SXG_REGISTER_SIZE_PER_CPU);
+	/*
+	 * Sanity check SXG_UCODE_REGS structure definition to
+	 * make sure the length is correct
+	 */
+	ASSERT(sizeof(struct sxg_ucode_regs) == SXG_REGISTER_SIZE_PER_CPU);
 
 	/* Disable interrupts */
 	SXG_DISABLE_ALL_INTERRUPTS(adapter);
@@ -3370,19 +4153,24 @@
 	/* Receive ring base and size */
 	WRITE_REG64(adapter,
 		    adapter->UcodeRegs[0].RcvBase, adapter->PRcvRings, 0);
-	WRITE_REG(adapter->UcodeRegs[0].RcvSize, SXG_RCV_RING_SIZE, TRUE);
+	if (adapter->JumboEnabled == TRUE)
+		sxg_rcv_ring_size = SXG_JUMBO_RCV_RING_SIZE;
+	WRITE_REG(adapter->UcodeRegs[0].RcvSize, sxg_rcv_ring_size, TRUE);
 
 	/* Populate the card with receive buffers */
 	sxg_stock_rcv_buffers(adapter);
 
-	/* Initialize checksum offload capabilities.  At the moment */
-	/* we always enable IP and TCP receive checksums on the card. */
-	/* Depending on the checksum configuration specified by the */
-	/* user, we can choose to report or ignore the checksum */
-	/* information provided by the card. */
+	/*
+	 * Initialize checksum offload capabilities.  At the moment we always
+	 * enable IP and TCP receive checksums on the card. Depending on the
+	 * checksum configuration specified by the user, we can choose to
+	 * report or ignore the checksum information provided by the card.
+	 */
 	WRITE_REG(adapter->UcodeRegs[0].ReceiveChecksum,
 		  SXG_RCV_TCP_CSUM_ENABLED | SXG_RCV_IP_CSUM_ENABLED, TRUE);
 
+	adapter->flags |= (SXG_RCV_TCP_CSUM_ENABLED | SXG_RCV_IP_CSUM_ENABLED );
+
 	/* Initialize the MAC, XAUI */
 	DBG_ERROR("sxg: %s ENTER sxg_initialize_link\n", __func__);
 	status = sxg_initialize_link(adapter);
@@ -3391,10 +4179,16 @@
 	if (status != STATUS_SUCCESS) {
 		return (status);
 	}
-	/* Initialize Dead to FALSE. */
-	/* SlicCheckForHang or SlicDumpThread will take it from here. */
+	/*
+	 * Initialize Dead to FALSE.
+	 * SlicCheckForHang or SlicDumpThread will take it from here.
+	 */
 	adapter->Dead = FALSE;
 	adapter->PingOutstanding = FALSE;
+	adapter->XmtFcEnabled = TRUE;
+	adapter->RcvFcEnabled = TRUE;
+
+	adapter->State = SXG_STATE_RUNNING;
 
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XInit",
 		  adapter, 0, 0, 0);
@@ -3413,15 +4207,14 @@
  *	status
  */
 static int sxg_fill_descriptor_block(struct adapter_t *adapter,
-				     struct SXG_RCV_DESCRIPTOR_BLOCK_HDR
-				     *RcvDescriptorBlockHdr)
+	     struct sxg_rcv_descriptor_block_hdr *RcvDescriptorBlockHdr)
 {
 	u32 i;
-	struct SXG_RING_INFO *RcvRingInfo = &adapter->RcvRingZeroInfo;
-	struct SXG_RCV_DATA_BUFFER_HDR *RcvDataBufferHdr;
-	struct SXG_RCV_DESCRIPTOR_BLOCK *RcvDescriptorBlock;
-	struct SXG_CMD *RingDescriptorCmd;
-	struct SXG_RCV_RING *RingZero = &adapter->RcvRings[0];
+	struct sxg_ring_info *RcvRingInfo = &adapter->RcvRingZeroInfo;
+	struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr;
+	struct sxg_rcv_descriptor_block *RcvDescriptorBlock;
+	struct sxg_cmd *RingDescriptorCmd;
+	struct sxg_rcv_ring *RingZero = &adapter->RcvRings[0];
 
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "FilBlk",
 		  adapter, adapter->RcvBuffersOnCard,
@@ -3429,8 +4222,10 @@
 
 	ASSERT(RcvDescriptorBlockHdr);
 
-	/* If we don't have the resources to fill the descriptor block, */
-	/* return failure */
+	/*
+	 * If we don't have the resources to fill the descriptor block,
+	 * return failure
+	 */
 	if ((adapter->FreeRcvBufferCount < SXG_RCV_DESCRIPTORS_PER_BLOCK) ||
 	    SXG_RING_FULL(RcvRingInfo)) {
 		adapter->Stats.NoMem++;
@@ -3441,27 +4236,40 @@
 		    RcvRingInfo, RingDescriptorCmd, RcvDescriptorBlockHdr);
 	ASSERT(RingDescriptorCmd);
 	RcvDescriptorBlockHdr->State = SXG_BUFFER_ONCARD;
-	RcvDescriptorBlock =
-	    (struct SXG_RCV_DESCRIPTOR_BLOCK*) RcvDescriptorBlockHdr->VirtualAddress;
+	RcvDescriptorBlock = (struct sxg_rcv_descriptor_block *)
+				 RcvDescriptorBlockHdr->VirtualAddress;
 
 	/* Fill in the descriptor block */
 	for (i = 0; i < SXG_RCV_DESCRIPTORS_PER_BLOCK; i++) {
 		SXG_GET_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
 		ASSERT(RcvDataBufferHdr);
+//		ASSERT(RcvDataBufferHdr->SxgDumbRcvPacket);
+		if (!RcvDataBufferHdr->SxgDumbRcvPacket) {
+			SXG_ALLOCATE_RCV_PACKET(adapter, RcvDataBufferHdr,
+						adapter->ReceiveBufferSize);
+			if(RcvDataBufferHdr->skb)
+				RcvDataBufferHdr->SxgDumbRcvPacket =
+						RcvDataBufferHdr->skb;
+			else
+				goto no_memory;
+		}
 		SXG_REINIATIALIZE_PACKET(RcvDataBufferHdr->SxgDumbRcvPacket);
 		RcvDataBufferHdr->State = SXG_BUFFER_ONCARD;
 		RcvDescriptorBlock->Descriptors[i].VirtualAddress =
-		    (void *)RcvDataBufferHdr;
+					    (void *)RcvDataBufferHdr;
+
 		RcvDescriptorBlock->Descriptors[i].PhysicalAddress =
 		    RcvDataBufferHdr->PhysicalAddress;
 	}
 	/* Add the descriptor block to receive descriptor ring 0 */
 	RingDescriptorCmd->Sgl = RcvDescriptorBlockHdr->PhysicalAddress;
 
-	/* RcvBuffersOnCard is not protected via the receive lock (see */
-	/* sxg_process_event_queue) We don't want to grap a lock every time a */
-	/* buffer is returned to us, so we use atomic interlocked functions */
-	/* instead. */
+	/*
+	 * RcvBuffersOnCard is not protected via the receive lock (see
+	 * sxg_process_event_queue) We don't want to grap a lock every time a
+	 * buffer is returned to us, so we use atomic interlocked functions
+	 * instead.
+	 */
 	adapter->RcvBuffersOnCard += SXG_RCV_DESCRIPTORS_PER_BLOCK;
 
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DscBlk",
@@ -3473,6 +4281,23 @@
 		  adapter, adapter->RcvBuffersOnCard,
 		  adapter->FreeRcvBufferCount, adapter->AllRcvBlockCount);
 	return (STATUS_SUCCESS);
+no_memory:
+	for (; i >= 0 ; i--) {
+		if (RcvDescriptorBlock->Descriptors[i].VirtualAddress) {
+			RcvDataBufferHdr = (struct sxg_rcv_data_buffer_hdr *)
+					    RcvDescriptorBlock->Descriptors[i].
+								VirtualAddress;
+			RcvDescriptorBlock->Descriptors[i].PhysicalAddress =
+					    (dma_addr_t)NULL;
+			RcvDescriptorBlock->Descriptors[i].VirtualAddress=NULL;
+		}
+		SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
+	}
+	RcvDescriptorBlockHdr->State = SXG_BUFFER_FREE;
+	SXG_RETURN_CMD(RingZero, RcvRingInfo, RingDescriptorCmd,
+			RcvDescriptorBlockHdr);
+
+	return (-ENOMEM);
 }
 
 /*
@@ -3486,34 +4311,42 @@
  */
 static void sxg_stock_rcv_buffers(struct adapter_t *adapter)
 {
-	struct SXG_RCV_DESCRIPTOR_BLOCK_HDR *RcvDescriptorBlockHdr;
+	struct sxg_rcv_descriptor_block_hdr *RcvDescriptorBlockHdr;
+	int sxg_rcv_data_buffers = SXG_RCV_DATA_BUFFERS;
+	int sxg_min_rcv_data_buffers = SXG_MIN_RCV_DATA_BUFFERS;
 
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "StockBuf",
 		  adapter, adapter->RcvBuffersOnCard,
 		  adapter->FreeRcvBufferCount, adapter->AllRcvBlockCount);
-	/* First, see if we've got less than our minimum threshold of */
-	/* receive buffers, there isn't an allocation in progress, and */
-	/* we haven't exceeded our maximum.. get another block of buffers */
-	/* None of this needs to be SMP safe.  It's round numbers. */
-	if ((adapter->FreeRcvBufferCount < SXG_MIN_RCV_DATA_BUFFERS) &&
+	/*
+	 * First, see if we've got less than our minimum threshold of
+	 * receive buffers, there isn't an allocation in progress, and
+	 * we haven't exceeded our maximum.. get another block of buffers
+	 * None of this needs to be SMP safe.  It's round numbers.
+	 */
+	if (adapter->JumboEnabled == TRUE)
+		sxg_min_rcv_data_buffers = SXG_MIN_JUMBO_RCV_DATA_BUFFERS;
+	if ((adapter->FreeRcvBufferCount < sxg_min_rcv_data_buffers) &&
 	    (adapter->AllRcvBlockCount < SXG_MAX_RCV_BLOCKS) &&
-	    (adapter->AllocationsPending == 0)) {
+	    (atomic_read(&adapter->pending_allocations) == 0)) {
 		sxg_allocate_buffer_memory(adapter,
-					   SXG_RCV_BLOCK_SIZE(adapter->
-							      ReceiveBufferSize),
+					   SXG_RCV_BLOCK_SIZE
+					   (SXG_RCV_DATA_HDR_SIZE),
 					   SXG_BUFFER_TYPE_RCV);
 	}
 	/* Now grab the RcvQLock lock and proceed */
 	spin_lock(&adapter->RcvQLock);
-	while (adapter->RcvBuffersOnCard < SXG_RCV_DATA_BUFFERS) {
-		struct LIST_ENTRY *_ple;
+	if (adapter->JumboEnabled)
+		sxg_rcv_data_buffers = SXG_JUMBO_RCV_DATA_BUFFERS;
+	while (adapter->RcvBuffersOnCard < sxg_rcv_data_buffers) {
+		struct list_entry *_ple;
 
 		/* Get a descriptor block */
 		RcvDescriptorBlockHdr = NULL;
 		if (adapter->FreeRcvBlockCount) {
 			_ple = RemoveHeadList(&adapter->FreeRcvBlocks);
 			RcvDescriptorBlockHdr =
-			    container_of(_ple, struct SXG_RCV_DESCRIPTOR_BLOCK_HDR,
+			    container_of(_ple, struct sxg_rcv_descriptor_block_hdr,
 					 FreeList);
 			adapter->FreeRcvBlockCount--;
 			RcvDescriptorBlockHdr->State = SXG_BUFFER_BUSY;
@@ -3553,10 +4386,10 @@
 static void sxg_complete_descriptor_blocks(struct adapter_t *adapter,
 					   unsigned char Index)
 {
-	struct SXG_RCV_RING *RingZero = &adapter->RcvRings[0];
-	struct SXG_RING_INFO *RcvRingInfo = &adapter->RcvRingZeroInfo;
-	struct SXG_RCV_DESCRIPTOR_BLOCK_HDR *RcvDescriptorBlockHdr;
-	struct SXG_CMD *RingDescriptorCmd;
+	struct sxg_rcv_ring *RingZero = &adapter->RcvRings[0];
+	struct sxg_ring_info *RcvRingInfo = &adapter->RcvRingZeroInfo;
+	struct sxg_rcv_descriptor_block_hdr *RcvDescriptorBlockHdr;
+	struct sxg_cmd *RingDescriptorCmd;
 
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpRBlks",
 		  adapter, Index, RcvRingInfo->Head, RcvRingInfo->Tail);
@@ -3564,12 +4397,13 @@
 	/* Now grab the RcvQLock lock and proceed */
 	spin_lock(&adapter->RcvQLock);
 	ASSERT(Index != RcvRingInfo->Tail);
-	while (RcvRingInfo->Tail != Index) {
-		/* */
-		/* Locate the current Cmd (ring descriptor entry), and */
-		/* associated receive descriptor block, and advance */
-		/* the tail */
-		/* */
+	while (sxg_ring_get_forward_diff(RcvRingInfo, Index,
+					RcvRingInfo->Tail) > 3) {
+		/*
+		 * Locate the current Cmd (ring descriptor entry), and
+		 * associated receive descriptor block, and advance
+		 * the tail
+		 */
 		SXG_RETURN_CMD(RingZero,
 			       RcvRingInfo,
 			       RingDescriptorCmd, RcvDescriptorBlockHdr);
@@ -3579,23 +4413,66 @@
 
 		/* Clear the SGL field */
 		RingDescriptorCmd->Sgl = 0;
-		/* Attempt to refill it and hand it right back to the */
-		/* card.  If we fail to refill it, free the descriptor block */
-		/* header.  The card will be restocked later via the */
-		/* RcvBuffersOnCard test */
-		if (sxg_fill_descriptor_block(adapter, RcvDescriptorBlockHdr) ==
-		    STATUS_FAILURE) {
+		/*
+		 * Attempt to refill it and hand it right back to the
+		 * card.  If we fail to refill it, free the descriptor block
+		 * header.  The card will be restocked later via the
+		 * RcvBuffersOnCard test
+		 */
+		if (sxg_fill_descriptor_block(adapter,
+			 RcvDescriptorBlockHdr) == STATUS_FAILURE)
 			SXG_FREE_RCV_DESCRIPTOR_BLOCK(adapter,
 						      RcvDescriptorBlockHdr);
-		}
 	}
 	spin_unlock(&adapter->RcvQLock);
 	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XCRBlks",
 		  adapter, Index, RcvRingInfo->Head, RcvRingInfo->Tail);
 }
 
+/*
+ * Read the statistics which the card has been maintaining.
+ */
+void sxg_collect_statistics(struct adapter_t *adapter)
+{
+	if(adapter->ucode_stats)
+		WRITE_REG64(adapter, adapter->UcodeRegs[0].GetUcodeStats,
+				adapter->pucode_stats, 0);
+	adapter->stats.rx_fifo_errors = adapter->ucode_stats->ERDrops;
+	adapter->stats.rx_over_errors = adapter->ucode_stats->NBDrops;
+	adapter->stats.tx_fifo_errors = adapter->ucode_stats->XDrops;
+}
+
+static struct net_device_stats *sxg_get_stats(struct net_device * dev)
+{
+	struct adapter_t *adapter = netdev_priv(dev);
+
+	sxg_collect_statistics(adapter);
+	return (&adapter->stats);
+}
+
+static void sxg_watchdog(unsigned long data)
+{
+	struct adapter_t *adapter = (struct adapter_t *) data;
+
+	if (adapter->state != ADAPT_DOWN) {
+		sxg_link_event(adapter);
+		/* Reset the timer */
+		mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 2 * HZ));
+	}
+}
+
+static void sxg_update_link_status (struct work_struct *work)
+{
+	struct adapter_t *adapter = (struct adapter_t *)container_of
+				(work, struct adapter_t, update_link_status);
+	if (likely(adapter->link_status_changed)) {
+		sxg_link_event(adapter);
+		adapter->link_status_changed = 0;
+	}
+}
+
 static struct pci_driver sxg_driver = {
-	.name = DRV_NAME,
+	.name = sxg_driver_name,
 	.id_table = sxg_pci_tbl,
 	.probe = sxg_entry_probe,
 	.remove = sxg_entry_remove,
@@ -3603,7 +4480,7 @@
 	.suspend = sxgpm_suspend,
 	.resume = sxgpm_resume,
 #endif
-/*    .shutdown   =     slic_shutdown,  MOOK_INVESTIGATE */
+	/* .shutdown   =     slic_shutdown,  MOOK_INVESTIGATE */
 };
 
 static int __init sxg_module_init(void)
diff --git a/drivers/staging/sxg/sxg.h b/drivers/staging/sxg/sxg.h
index 653cf3b..f07aa70 100644
--- a/drivers/staging/sxg/sxg.h
+++ b/drivers/staging/sxg/sxg.h
@@ -42,357 +42,369 @@
 #ifndef __SXG_DRIVER_H__
 #define __SXG_DRIVER_H__
 
-#define p_net_device struct net_device *
-// SXG_STATS - Probably move these to someplace where
-// the slicstat (sxgstat?) program can get them.
-struct SXG_STATS {
-	// Xmt
-	u32				XmtNBL;				// Offload send NBL count
-	u64				DumbXmtBytes;		// Dumbnic send bytes
-	u64				SlowXmtBytes;		// Slowpath send bytes
-	u64				FastXmtBytes;		// Fastpath send bytes
-	u64				DumbXmtPkts;		// Dumbnic send packets
-	u64				SlowXmtPkts;		// Slowpath send packets
-	u64				FastXmtPkts;		// Fastpath send packets
-    u64				DumbXmtUcastPkts;	// directed packets
-    u64				DumbXmtMcastPkts;	// Multicast packets
-    u64				DumbXmtBcastPkts;	// OID_GEN_BROADCAST_FRAMES_RCV
-    u64				DumbXmtUcastBytes;	// OID_GEN_DIRECTED_BYTES_XMIT
-    u64				DumbXmtMcastBytes;	// OID_GEN_MULTICAST_BYTES_XMIT
-    u64				DumbXmtBcastBytes;	// OID_GEN_BROADCAST_BYTES_XMIT
-    u64				XmtErrors;			// OID_GEN_XMIT_ERROR
-    u64				XmtDiscards;		// OID_GEN_XMIT_DISCARDS
-	u64				XmtOk;				// OID_GEN_XMIT_OK
-	u64				XmtQLen;			// OID_GEN_TRANSMIT_QUEUE_LENGTH
-	u64				XmtZeroFull;		// Transmit ring zero full
-	// Rcv
-	u32				RcvNBL;				// Offload recieve NBL count
-	u64				DumbRcvBytes;		// dumbnic recv bytes
-    u64             DumbRcvUcastBytes;	// OID_GEN_DIRECTED_BYTES_RCV
-    u64             DumbRcvMcastBytes;	// OID_GEN_MULTICAST_BYTES_RCV
-    u64             DumbRcvBcastBytes;	// OID_GEN_BROADCAST_BYTES_RCV
-	u64				SlowRcvBytes;		// Slowpath recv bytes
-	u64				FastRcvBytes;		// Fastpath recv bytes
-    u64				DumbRcvPkts;		// OID_GEN_DIRECTED_FRAMES_RCV
-	u64				DumbRcvTcpPkts;		// See SxgCollectStats
-    u64				DumbRcvUcastPkts;	// directed packets
-    u64				DumbRcvMcastPkts;	// Multicast packets
-    u64				DumbRcvBcastPkts;	// OID_GEN_BROADCAST_FRAMES_RCV
-	u64				SlowRcvPkts;		// OID_GEN_DIRECTED_FRAMES_RCV
-    u64				RcvErrors;			// OID_GEN_RCV_ERROR
-    u64				RcvDiscards;		// OID_GEN_RCV_DISCARDS
-	u64				RcvNoBuffer;		// OID_GEN_RCV_NO_BUFFER
-    u64 			PdqFull;			// Processed Data Queue Full
-	u64				EventRingFull;		// Event ring full
-	// Verbose stats
-	u64				MaxSends;			// Max sends outstanding
-	u64				NoSglBuf;			// SGL buffer allocation failure
-	u64				SglFail;			// NDIS SGL failure
-	u64				SglAsync;			// NDIS SGL failure
-	u64				NoMem;				// Memory allocation failure
-	u64				NumInts;			// Interrupts
-	u64				FalseInts;			// Interrupt with ISR == 0
-	u64				XmtDrops;			// No sahara DRAM buffer for xmt
-	// Sahara receive status
-	u64				TransportCsum;		// SXG_RCV_STATUS_TRANSPORT_CSUM
-	u64				TransportUflow;		// SXG_RCV_STATUS_TRANSPORT_UFLOW
-	u64				TransportHdrLen;	// SXG_RCV_STATUS_TRANSPORT_HDRLEN
-	u64				NetworkCsum;		// SXG_RCV_STATUS_NETWORK_CSUM:
-	u64				NetworkUflow;		// SXG_RCV_STATUS_NETWORK_UFLOW:
-	u64				NetworkHdrLen;		// SXG_RCV_STATUS_NETWORK_HDRLEN:
-	u64				Parity;				// SXG_RCV_STATUS_PARITY
-	u64				LinkParity;			// SXG_RCV_STATUS_LINK_PARITY:
-	u64				LinkEarly;			// SXG_RCV_STATUS_LINK_EARLY:
-	u64				LinkBufOflow;		// SXG_RCV_STATUS_LINK_BUFOFLOW:
-	u64				LinkCode;			// SXG_RCV_STATUS_LINK_CODE:
-	u64				LinkDribble;		// SXG_RCV_STATUS_LINK_DRIBBLE:
-	u64				LinkCrc;			// SXG_RCV_STATUS_LINK_CRC:
-	u64				LinkOflow;			// SXG_RCV_STATUS_LINK_OFLOW:
-	u64				LinkUflow;			// SXG_RCV_STATUS_LINK_UFLOW:
+#define SLIC_DUMP_ENABLED		0
+
+#define SXG_DRV_NAME	"sxg"		/* TBD: This might be removed eventually */
+#define SXG_DRV_VERSION	"1.0.1"
+
+extern char sxg_driver_name[];
+
+#define SXG_NETDEV_WEIGHT 64
+
+/*
+ * struct sxg_stats - Probably move these to someplace where
+ * the slicstat (sxgstat?) program can get them.
+ */
+struct sxg_stats {
+	/* Xmt */
+	u64	DumbXmtUcastPkts;	/* directed packets */
+	u64	DumbXmtMcastPkts;	/* Multicast packets */
+	u64	DumbXmtBcastPkts;	/* OID_GEN_BROADCAST_FRAMES_RCV */
+	u64	DumbXmtUcastBytes;	/* OID_GEN_DIRECTED_BYTES_XMIT */
+	u64	DumbXmtMcastBytes;	/* OID_GEN_MULTICAST_BYTES_XMIT */
+	u64	DumbXmtBcastBytes;	/* OID_GEN_BROADCAST_BYTES_XMIT */
+	u64	XmtQLen;		/* OID_GEN_TRANSMIT_QUEUE_LENGTH */
+	u64	XmtZeroFull;		/* Transmit ring zero full */
+	/* Rcv */
+	u64  	DumbRcvUcastBytes;	/* OID_GEN_DIRECTED_BYTES_RCV */
+	u64    	DumbRcvMcastBytes;	/* OID_GEN_MULTICAST_BYTES_RCV */
+	u64   	DumbRcvBcastBytes;	/* OID_GEN_BROADCAST_BYTES_RCV */
+	u64	DumbRcvUcastPkts;	/* directed packets */
+	u64	DumbRcvMcastPkts;	/* Multicast packets */
+	u64	DumbRcvBcastPkts;	/* OID_GEN_BROADCAST_FRAMES_RCV */
+	u64 	PdqFull;		/* Processed Data Queue Full */
+	u64	EventRingFull;		/* Event ring full */
+	/* Verbose stats */
+	u64	NoSglBuf;		/* SGL buffer allocation failure */
+	u64	NoMem;			/* Memory allocation failure */
+	u64	NumInts;		/* Interrupts */
+	u64	FalseInts;		/* Interrupt with ISR == 0 */
+	/* Sahara receive status */
+	u64	TransportCsum;		/* SXG_RCV_STATUS_TRANSPORT_CSUM */
+	u64	TransportUflow;		/* SXG_RCV_STATUS_TRANSPORT_UFLOW */
+	u64	TransportHdrLen;	/* SXG_RCV_STATUS_TRANSPORT_HDRLEN */
+	u64	NetworkCsum;		/* SXG_RCV_STATUS_NETWORK_CSUM: */
+	u64	NetworkUflow;		/* SXG_RCV_STATUS_NETWORK_UFLOW: */
+	u64	NetworkHdrLen;		/* SXG_RCV_STATUS_NETWORK_HDRLEN: */
+	u64	Parity;			/* SXG_RCV_STATUS_PARITY */
+	u64	LinkParity;		/* SXG_RCV_STATUS_LINK_PARITY: */
+	u64	LinkEarly;		/* SXG_RCV_STATUS_LINK_EARLY: */
+	u64	LinkBufOflow;		/* SXG_RCV_STATUS_LINK_BUFOFLOW: */
+	u64	LinkCode;		/* SXG_RCV_STATUS_LINK_CODE: */
+	u64	LinkDribble;		/* SXG_RCV_STATUS_LINK_DRIBBLE: */
+	u64	LinkCrc;		/* SXG_RCV_STATUS_LINK_CRC: */
+	u64	LinkOflow;		/* SXG_RCV_STATUS_LINK_OFLOW: */
+	u64	LinkUflow;		/* SXG_RCV_STATUS_LINK_UFLOW: */
 };
 
 
-/****************************************************************************
- * DUMB-NIC Send path definitions
- ****************************************************************************/
+/* DUMB-NIC Send path definitions */
 
-#define SXG_COMPLETE_DUMB_SEND(_pAdapt, _skb) {                     		    	\
-	ASSERT(_skb);													    			\
-    dev_kfree_skb_irq(_skb);                                                        \
+#define SXG_COMPLETE_DUMB_SEND(_pAdapt, _skb, _phys_addr, _size) {		\
+	ASSERT(_skb);								\
+	pci_unmap_single(_pAdapt->pcidev, _size, _phys_addr, PCI_DMA_TODEVICE);	\
+	dev_kfree_skb_irq(_skb);                    				\
 }
 
-#define SXG_DROP_DUMB_SEND(_pAdapt, _skb) {                           		    	\
-	ASSERT(_skb);													    			\
-    dev_kfree_skb(_skb);                                                            \
+#define SXG_DROP_DUMB_SEND(_pAdapt, _skb) {                            	\
+	ASSERT(_skb);							\
 }
 
-// Locate current receive header buffer location.  Use this
-// instead of RcvDataHdr->VirtualAddress since the data
-// may have been offset by SXG_ADVANCE_MDL_OFFSET
+/*
+ * Locate current receive header buffer location.  Use this
+ * instead of RcvDataHdr->VirtualAddress since the data
+ * may have been offset by SXG_ADVANCE_MDL_OFFSET
+ */
 #define SXG_RECEIVE_DATA_LOCATION(_RcvDataHdr)        (_RcvDataHdr)->skb->data
 
-/************************************************************************
- * Dumb-NIC receive processing
- ************************************************************************/
-// Define an SXG_PACKET as an NDIS_PACKET
+/* Dumb-NIC receive processing */
+/* Define an SXG_PACKET as an NDIS_PACKET */
 #define PSXG_PACKET       struct sk_buff *
-// Indications array size
+/* Indications array size */
 #define SXG_RCV_ARRAYSIZE	64
 
-#define SXG_ALLOCATE_RCV_PACKET(_pAdapt, _RcvDataBufferHdr) {				\
-	struct sk_buff * skb;												    \
-    skb = alloc_skb(2048, GFP_ATOMIC);                                      \
-    if (skb) {                                                              \
-    	(_RcvDataBufferHdr)->skb = skb;                                     \
-        skb->next = NULL;                                                   \
-    } else {                                                                \
-    	(_RcvDataBufferHdr)->skb = NULL;                                    \
-    }                                                                       \
+#define SXG_ALLOCATE_RCV_PACKET(_pAdapt, _RcvDataBufferHdr, BufferSize) {\
+    struct sk_buff * skb;						\
+    skb = netdev_alloc_skb(_pAdapt->netdev, BufferSize);                \
+    if (skb) {                                                          \
+    	(_RcvDataBufferHdr)->skb = skb;                                	\
+        skb->next = NULL;                                               \
+	_RcvDataBufferHdr->PhysicalAddress = pci_map_single(adapter->pcidev,\
+	    _RcvDataBufferHdr->skb->data, BufferSize, PCI_DMA_FROMDEVICE);	\
+	if (SXG_INVALID_SGL(_RcvDataBufferHdr->PhysicalAddress,BufferSize))  \
+		printk(KERN_EMERG "SXG_ALLOCATE_RCV_PACKET: RCV packet" \
+					"non-64k boundary aligned\n");	\
+    } else {                                                            \
+    	(_RcvDataBufferHdr)->skb = NULL;                                \
+    }                                                                  	\
 }
 
-#define SXG_FREE_RCV_PACKET(_RcvDataBufferHdr) {							\
-	if((_RcvDataBufferHdr)->skb) {											\
-		dev_kfree_skb((_RcvDataBufferHdr)->skb);						    \
-    }                                                                       \
+#define SXG_FREE_RCV_PACKET(_RcvDataBufferHdr) {			\
+	if((_RcvDataBufferHdr)->skb) {					\
+		dev_kfree_skb((_RcvDataBufferHdr)->skb);		\
+    }                                                                  	\
 }
 
-// Macro to add a NDIS_PACKET to an indication array
-// If we fill up our array of packet pointers, then indicate this
-// block up now and start on a new one.
-#define	SXG_ADD_RCV_PACKET(_pAdapt, _Packet, _PrevPacket, _IndicationList, _NumPackets) { \
-	(_IndicationList)[_NumPackets] = (_Packet);										\
-	(_NumPackets)++;																\
-	if((_NumPackets) == SXG_RCV_ARRAYSIZE) {										\
-		SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "IndicRcv",				\
-				   (_NumPackets), 0, 0, 0);											\
-        netif_rx((_IndicationList),(_NumPackets));                                  \
-		(_NumPackets) = 0;															\
-	}																				\
+/*
+ * Macro to add a NDIS_PACKET to an indication array
+ * If we fill up our array of packet pointers, then indicate this
+ * block up now and start on a new one.
+ */
+#define	SXG_ADD_RCV_PACKET(_pAdapt, _Packet, _PrevPacket, _IndicationList, \
+				_NumPackets) { 				\
+	(_IndicationList)[_NumPackets] = (_Packet);			\
+	(_NumPackets)++;						\
+	if((_NumPackets) == SXG_RCV_ARRAYSIZE) {			\
+		SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "IndicRcv",	\
+				   (_NumPackets), 0, 0, 0);		\
+        netif_rx((_IndicationList),(_NumPackets));                     	\
+		(_NumPackets) = 0;					\
+	}								\
 }
 
-#define SXG_INDICATE_PACKETS(_pAdapt, _IndicationList, _NumPackets) {			\
-	if(_NumPackets) {															\
-		SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "IndicRcv",			\
-				   (_NumPackets), 0, 0, 0);										\
-        netif_rx((_IndicationList),(_NumPackets));                              \
-		(_NumPackets) = 0;														\
-	}																			\
+#define SXG_INDICATE_PACKETS(_pAdapt, _IndicationList, _NumPackets) {	\
+	if(_NumPackets) {						\
+		SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "IndicRcv",	\
+				   (_NumPackets), 0, 0, 0);		\
+        netif_rx((_IndicationList),(_NumPackets));                     	\
+		(_NumPackets) = 0;					\
+	}								\
 }
 
-#define SXG_REINIATIALIZE_PACKET(_Packet)										\
-	{}  /*_NdisReinitializePacket(_Packet)*/  /*  this is not necessary with an skb */
+#define SXG_REINIATIALIZE_PACKET(_Packet)				\
+	{}  /*_NdisReinitializePacket(_Packet)*/
+		 /*  this is not necessary with an skb */
 
-// Definitions to initialize Dumb-nic Receive NBLs
-#define SXG_RCV_PACKET_BUFFER_HDR(_Packet) (((PSXG_RCV_NBL_RESERVED)((_Packet)->MiniportReservedEx))->RcvDataBufferHdr)
+/* Definitions to initialize Dumb-nic Receive NBLs */
+#define SXG_RCV_PACKET_BUFFER_HDR(_Packet) (((struct sxg_rcv_nbl_reserved *)\
+			((_Packet)->MiniportReservedEx))->RcvDataBufferHdr)
 
-#define SXG_RCV_SET_CHECKSUM_INFO(_Packet, _Cpi)	\
-	NDIS_PER_PACKET_INFO_FROM_PACKET((_Packet), TcpIpChecksumPacketInfo) = (PVOID)(_Cpi)
+#define SXG_RCV_SET_CHECKSUM_INFO(_Packet, _Cpi)				\
+	NDIS_PER_PACKET_INFO_FROM_PACKET((_Packet), 				\
+			TcpIpChecksumPacketInfo) = (PVOID)(_Cpi)
 
 #define SXG_RCV_SET_TOEPLITZ(_Packet, _Toeplitz, _Type, _Function) {		\
-	NDIS_PACKET_SET_HASH_VALUE((_Packet), (_Toeplitz));						\
-	NDIS_PACKET_SET_HASH_TYPE((_Packet), (_Type));							\
-	NDIS_PACKET_SET_HASH_FUNCTION((_Packet), (_Function));					\
+	NDIS_PACKET_SET_HASH_VALUE((_Packet), (_Toeplitz));			\
+	NDIS_PACKET_SET_HASH_TYPE((_Packet), (_Type));				\
+	NDIS_PACKET_SET_HASH_FUNCTION((_Packet), (_Function));			\
 }
 
-#define SXG_RCV_SET_VLAN_INFO(_Packet, _VlanId, _Priority) {					\
-	NDIS_PACKET_8021Q_INFO	_Packet8021qInfo;									\
-	_Packet8021qInfo.TagHeader.VlanId = (_VlanId);								\
-	_Packet8021qInfo.TagHeader.UserPriority = (_Priority);						\
+#define SXG_RCV_SET_VLAN_INFO(_Packet, _VlanId, _Priority) {			\
+	NDIS_PACKET_8021Q_INFO	_Packet8021qInfo;				\
+	_Packet8021qInfo.TagHeader.VlanId = (_VlanId);				\
+	_Packet8021qInfo.TagHeader.UserPriority = (_Priority);			\
 	NDIS_PER_PACKET_INFO_FROM_PACKET((_Packet), Ieee8021QNetBufferListInfo) = 	\
-		_Packet8021qInfo.Value;													\
+		_Packet8021qInfo.Value;						\
 }
 
-#define SXG_ADJUST_RCV_PACKET(_Packet, _RcvDataBufferHdr, _Event) {			\
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbRcv",			\
-			   (_RcvDataBufferHdr), (_Packet),								\
-			   (_Event)->Status, 0);	                    				\
-	ASSERT((_Event)->Length <= (_RcvDataBufferHdr)->Size);					\
-    Packet->len = (_Event)->Length;                                         \
+#define SXG_ADJUST_RCV_PACKET(_Packet, _RcvDataBufferHdr, _Event) {		\
+	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbRcv",		\
+			   (_RcvDataBufferHdr), (_Packet),			\
+			   (_Event)->Status, 0);	                    	\
+	/* ASSERT((_Event)->Length <= (_RcvDataBufferHdr)->Size); */		\
+	skb_put(Packet, (_Event)->Length);					\
 }
 
-///////////////////////////////////////////////////////////////////////////////
-// Macros to free a receive data buffer and receive data descriptor block
-///////////////////////////////////////////////////////////////////////////////
-// NOTE - Lock must be held with RCV macros
-#define SXG_GET_RCV_DATA_BUFFER(_pAdapt, _Hdr) {								\
-	struct LIST_ENTRY     				*_ple;										\
-	_Hdr = NULL;																\
-	if((_pAdapt)->FreeRcvBufferCount) {											\
-		ASSERT(!(IsListEmpty(&(_pAdapt)->FreeRcvBuffers)));						\
-		_ple = RemoveHeadList(&(_pAdapt)->FreeRcvBuffers);	    				\
-		(_Hdr) = container_of(_ple, struct SXG_RCV_DATA_BUFFER_HDR, FreeList);	        \
-		(_pAdapt)->FreeRcvBufferCount--;										\
-		ASSERT((_Hdr)->State == SXG_BUFFER_FREE);								\
-	}																			\
+/*
+ * Macros to free a receive data buffer and receive data descriptor block
+ * NOTE - Lock must be held with RCV macros
+ */
+#define SXG_GET_RCV_DATA_BUFFER(_pAdapt, _Hdr) {				\
+	struct list_entry *_ple;						\
+	_Hdr = NULL;								\
+	if((_pAdapt)->FreeRcvBufferCount) {					\
+		ASSERT(!(IsListEmpty(&(_pAdapt)->FreeRcvBuffers)));		\
+		_ple = RemoveHeadList(&(_pAdapt)->FreeRcvBuffers);	    	\
+		(_Hdr) = container_of(_ple, struct sxg_rcv_data_buffer_hdr, 	\
+						FreeList);	        	\
+		(_pAdapt)->FreeRcvBufferCount--;				\
+		ASSERT((_Hdr)->State == SXG_BUFFER_FREE);			\
+	}									\
 }
 
-#define SXG_FREE_RCV_DATA_BUFFER(_pAdapt, _Hdr) {							\
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "RtnDHdr",			\
-			   (_Hdr), (_pAdapt)->FreeRcvBufferCount,						\
-			   (_Hdr)->State, (_Hdr)->VirtualAddress);						\
-/*	SXG_RESTORE_MDL_OFFSET(_Hdr);	*/										\
-	(_pAdapt)->FreeRcvBufferCount++;										\
-	ASSERT(((_pAdapt)->AllRcvBlockCount * SXG_RCV_DESCRIPTORS_PER_BLOCK) >= (_pAdapt)->FreeRcvBufferCount); \
-	ASSERT((_Hdr)->State != SXG_BUFFER_FREE);								\
-	(_Hdr)->State = SXG_BUFFER_FREE;										\
-	InsertTailList(&(_pAdapt)->FreeRcvBuffers, &((_Hdr)->FreeList));		\
+#define SXG_FREE_RCV_DATA_BUFFER(_pAdapt, _Hdr) {				\
+	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "RtnDHdr",		\
+			   (_Hdr), (_pAdapt)->FreeRcvBufferCount,		\
+			   (_Hdr)->State, 0/*(_Hdr)->VirtualAddress*/);		\
+/*	SXG_RESTORE_MDL_OFFSET(_Hdr);	*/					\
+	(_pAdapt)->FreeRcvBufferCount++;					\
+	ASSERT(((_pAdapt)->AllRcvBlockCount * SXG_RCV_DESCRIPTORS_PER_BLOCK) 	\
+				>= (_pAdapt)->FreeRcvBufferCount); 		\
+	ASSERT((_Hdr)->State != SXG_BUFFER_FREE);				\
+	(_Hdr)->State = SXG_BUFFER_FREE;					\
+	InsertTailList(&(_pAdapt)->FreeRcvBuffers, &((_Hdr)->FreeList));	\
 }
 
-#define SXG_FREE_RCV_DESCRIPTOR_BLOCK(_pAdapt, _Hdr) {						\
-	ASSERT((_Hdr)->State != SXG_BUFFER_FREE);								\
-	(_Hdr)->State = SXG_BUFFER_FREE;										\
-	(_pAdapt)->FreeRcvBlockCount++;											\
+#define SXG_FREE_RCV_DESCRIPTOR_BLOCK(_pAdapt, _Hdr) {				\
+	ASSERT((_Hdr)->State != SXG_BUFFER_FREE);				\
+	(_Hdr)->State = SXG_BUFFER_FREE;					\
+	(_pAdapt)->FreeRcvBlockCount++;						\
 	ASSERT((_pAdapt)->AllRcvBlockCount >= (_pAdapt)->FreeRcvBlockCount);	\
-	InsertTailList(&(_pAdapt)->FreeRcvBlocks, &(_Hdr)->FreeList);			\
+	InsertTailList(&(_pAdapt)->FreeRcvBlocks, &(_Hdr)->FreeList);		\
 }
 
-// SGL macros
-#define SXG_FREE_SGL_BUFFER(_pAdapt, _Sgl, _NB) {	\
-	spin_lock(&(_pAdapt)->SglQLock);		\
-	(_pAdapt)->FreeSglBufferCount++;		\
-	ASSERT((_pAdapt)->AllSglBufferCount >= (_pAdapt)->FreeSglBufferCount);\
-	ASSERT(!((_Sgl)->State & SXG_BUFFER_FREE));	\
-	(_Sgl)->State = SXG_BUFFER_FREE;		\
-	InsertTailList(&(_pAdapt)->FreeSglBuffers, &(_Sgl)->FreeList);	\
-	spin_unlock(&(_pAdapt)->SglQLock);		\
+/* SGL macros */
+#define SXG_FREE_SGL_BUFFER(_pAdapt, _Sgl, _NB) {				\
+	spin_lock_irqsave(&(_pAdapt)->SglQLock, sgl_flags);			\
+	(_pAdapt)->FreeSglBufferCount++;					\
+	ASSERT((_pAdapt)->AllSglBufferCount >= (_pAdapt)->FreeSglBufferCount);	\
+	ASSERT(!((_Sgl)->State & SXG_BUFFER_FREE));				\
+	(_Sgl)->State = SXG_BUFFER_FREE;					\
+	InsertTailList(&(_pAdapt)->FreeSglBuffers, &(_Sgl)->FreeList);		\
+	spin_unlock_irqrestore(&(_pAdapt)->SglQLock, sgl_flags);		\
 }
 
-// Get an SGL buffer from the free queue.  The first part of this macro
-// attempts to keep ahead of buffer depletion by allocating more when
-// we hit a minimum threshold.  Note that we don't grab the lock
-// until after that.  We're dealing with round numbers here, so we don't need to,
-// and not grabbing it avoids a possible double-trip.
-#define SXG_GET_SGL_BUFFER(_pAdapt, _Sgl) {				\
-	struct LIST_ENTRY *_ple;						\
+/*
+ * Get an SGL buffer from the free queue.  The first part of this macro
+ * attempts to keep ahead of buffer depletion by allocating more when
+ * we hit a minimum threshold.  Note that we don't grab the lock
+ * until after that.  We're dealing with round numbers here, so we don't need to,
+ * and not grabbing it avoids a possible double-trip.
+ */
+#define SXG_GET_SGL_BUFFER(_pAdapt, _Sgl, _irq) {			\
+	struct list_entry *_ple;					\
 	if ((_pAdapt->FreeSglBufferCount < SXG_MIN_SGL_BUFFERS) &&	\
 	   (_pAdapt->AllSglBufferCount < SXG_MAX_SGL_BUFFERS) &&	\
-	   (_pAdapt->AllocationsPending == 0)) {			\
+	   (atomic_read(&_pAdapt->pending_allocations) == 0)) {		\
 		sxg_allocate_buffer_memory(_pAdapt,			\
-			(sizeof(struct SXG_SCATTER_GATHER) + SXG_SGL_BUF_SIZE),\
+			(sizeof(struct sxg_scatter_gather) + SXG_SGL_BUF_SIZE),\
 			SXG_BUFFER_TYPE_SGL);				\
 	}								\
 	_Sgl = NULL;							\
-	spin_lock(&(_pAdapt)->SglQLock);				\
+	if(!_irq)							\
+		spin_lock_irqsave(&(_pAdapt)->SglQLock, sgl_flags);	\
+	else								\
+		spin_lock_irqsave(&(_pAdapt)->SglQLock, sgl_flags);	\
 	if((_pAdapt)->FreeSglBufferCount) {				\
 		ASSERT(!(IsListEmpty(&(_pAdapt)->FreeSglBuffers)));	\
 		_ple = RemoveHeadList(&(_pAdapt)->FreeSglBuffers);	\
-		(_Sgl) = container_of(_ple, struct SXG_SCATTER_GATHER, FreeList); \
+		(_Sgl) = container_of(_ple, struct sxg_scatter_gather, 	\
+						FreeList); 		\
             (_pAdapt)->FreeSglBufferCount--;				\
 		ASSERT((_Sgl)->State == SXG_BUFFER_FREE);		\
 		(_Sgl)->State = SXG_BUFFER_BUSY;			\
 		(_Sgl)->pSgl = NULL;					\
 	}								\
-	spin_unlock(&(_pAdapt)->SglQLock);				\
+	if(!_irq)							\
+		spin_unlock_irqrestore(&(_pAdapt)->SglQLock, sgl_flags);\
+	else								\
+		spin_unlock_irqrestore(&(_pAdapt)->SglQLock, sgl_flags);\
 }
 
-//
-// SXG_MULTICAST_ADDRESS
-//
-// Linked list of multicast addresses.
-struct SXG_MULTICAST_ADDRESS {
-	unsigned char							Address[6];
-	struct SXG_MULTICAST_ADDRESS	*Next;
+/*
+ * struct sxg_multicast_address
+ * Linked list of multicast addresses.
+ */
+struct sxg_multicast_address {
+	unsigned char			Address[6];
+	struct sxg_multicast_address	*Next;
 };
 
-// Structure to maintain chimney send and receive buffer queues.
-// This structure maintains NET_BUFFER_LIST queues that are
-// given to us via the Chimney MiniportTcpOffloadSend and
-// MiniportTcpOffloadReceive routines.  This structure DOES NOT
-// manage our data buffer queue
-struct SXG_BUFFER_QUEUE {
-	u32						Type;			// Slow or fast - See below
-	u32						Direction;		// Xmt or Rcv
-	u32						Bytes;			// Byte count
-	u32 *        			Head;			// Send queue head
-	u32 *        			Tail;			// Send queue tail
-//	PNET_BUFFER_LIST			NextNBL;		// Short cut - next NBL
-//	PNET_BUFFER					NextNB;			// Short cut - next NB
+/*
+ * Structure to maintain chimney send and receive buffer queues.
+ * This structure maintains NET_BUFFER_LIST queues that are
+ * given to us via the Chimney MiniportTcpOffloadSend and
+ * MiniportTcpOffloadReceive routines.  This structure DOES NOT
+ * manage our data buffer queue
+ */
+struct sxg_buffer_queue {
+	u32	Type;			/* Slow or fast - See below */
+	u32	Direction;		/* Xmt or Rcv */
+	u32	Bytes;			/* Byte count */
+	u32 *  	Head;			/* Send queue head */
+	u32 *  	Tail;			/* Send queue tail */
+/*	PNET_BUFFER_LIST	NextNBL;*/	/* Short cut - next NBL */
+/*	PNET_BUFFER		NextNB;	*/	/* Short cut - next NB */
 };
 
 #define		SXG_SLOW_SEND_BUFFER	0
 #define		SXG_FAST_SEND_BUFFER	1
 #define 	SXG_RECEIVE_BUFFER		2
 
-#define SXG_INIT_BUFFER(_Buffer, _Type) { 						\
-	(_Buffer)->Type = (_Type);									\
-	if((_Type) == SXG_RECEIVE_BUFFER) {							\
-		(_Buffer)->Direction = 0;								\
-	} else {													\
+#define SXG_INIT_BUFFER(_Buffer, _Type) { 				\
+	(_Buffer)->Type = (_Type);					\
+	if((_Type) == SXG_RECEIVE_BUFFER) {				\
+		(_Buffer)->Direction = 0;				\
+	} else {							\
 		(_Buffer)->Direction = NDIS_SG_LIST_WRITE_TO_DEVICE;	\
-	}															\
-	(_Buffer)->Bytes = 0;										\
-	(_Buffer)->Head = NULL;										\
-	(_Buffer)->Tail = NULL;										\
+	}								\
+	(_Buffer)->Bytes = 0;						\
+	(_Buffer)->Head = NULL;						\
+	(_Buffer)->Tail = NULL;						\
 }
 
 
-#define SXG_RSS_CPU_COUNT(_pAdapt) 								\
+#define SXG_RSS_CPU_COUNT(_pAdapt) 					\
 	((_pAdapt)->RssEnabled 	?  NR_CPUS : 1)
 
-/****************************************************************************
- * DRIVER and ADAPTER structures
- ****************************************************************************/
+/* DRIVER and ADAPTER structures */
 
-// Adapter states - These states closely match the adapter states
-// documented in the DDK (with a few exceptions).
+/*
+ * Adapter states - These states closely match the adapter states
+ * documented in the DDK (with a few exceptions).
+ */
 enum SXG_STATE {
-	SXG_STATE_INITIALIZING,			// Initializing
-	SXG_STATE_BOOTDIAG,				// Boot-Diagnostic mode
-	SXG_STATE_PAUSING,				// Pausing
-	SXG_STATE_PAUSED,				// Paused
-	SXG_STATE_RUNNING,				// Running
-	SXG_STATE_RESETTING,			// Reset in progress
-	SXG_STATE_SLEEP,				// Sleeping
-	SXG_STATE_DIAG,					// Diagnostic mode
-	SXG_STATE_HALTING,				// Halting
-	SXG_STATE_HALTED,				// Down or not-initialized
-	SXG_STATE_SHUTDOWN				// shutdown
+	SXG_STATE_INITIALIZING,			/* Initializing */
+	SXG_STATE_BOOTDIAG,			/* Boot-Diagnostic mode */
+	SXG_STATE_PAUSING,			/* Pausing */
+	SXG_STATE_PAUSED,			/* Paused */
+	SXG_STATE_RUNNING,			/* Running */
+	SXG_STATE_RESETTING,			/* Reset in progress */
+	SXG_STATE_SLEEP,			/* Sleeping */
+	SXG_STATE_DIAG,				/* Diagnostic mode */
+	SXG_STATE_HALTING,			/* Halting */
+	SXG_STATE_HALTED,			/* Down or not-initialized */
+	SXG_STATE_SHUTDOWN			/* shutdown */
 };
 
-// Link state
+/* Link state */
 enum SXG_LINK_STATE {
 	SXG_LINK_DOWN,
 	SXG_LINK_UP
 };
 
-// Link initialization timeout in 100us units
-#define SXG_LINK_TIMEOUT	100000		// 10 Seconds - REDUCE!
+/* Link initialization timeout in 100us units */
+#define SXG_LINK_TIMEOUT	100000		/* 10 Seconds - REDUCE! */
 
 
-// Microcode file selection codes
+/* Microcode file selection codes */
 enum SXG_UCODE_SEL {
-	SXG_UCODE_SAHARA,				// Sahara ucode
-	SXG_UCODE_SDIAGCPU,				// Sahara CPU diagnostic ucode
-	SXG_UCODE_SDIAGSYS				// Sahara system diagnostic ucode
+	SXG_UCODE_SYSTEM,	/* System (operational) uucode */
+	SXG_UCODE_SDIAGCPU,	/* System CPU diagnostic ucode */
+	SXG_UCODE_SDIAGSYS	/* System diagnostic ucode */
 };
 
 
 #define SXG_DISABLE_ALL_INTERRUPTS(_padapt) sxg_disable_interrupt(_padapt)
 #define SXG_ENABLE_ALL_INTERRUPTS(_padapt) sxg_enable_interrupt(_padapt)
 
-// This probably lives in a proto.h file.  Move later
+/* This probably lives in a proto.h file.  Move later */
 #define SXG_MULTICAST_PACKET(_pether) ((_pether)->ether_dhost[0] & 0x01)
-#define SXG_BROADCAST_PACKET(_pether) ((*(u32 *)(_pether)->ether_dhost == 0xFFFFFFFF) && \
-				(*(u16 *)&(_pether)->ether_dhost[4] == 0xFFFF))
+#define SXG_BROADCAST_PACKET(_pether) 					\
+		((*(u32 *)(_pether)->ether_dhost == 0xFFFFFFFF) && 	\
+		(*(u16 *)&(_pether)->ether_dhost[4] == 0xFFFF))
 
-// For DbgPrints
+/* For DbgPrints */
 #define SXG_ID      DPFLTR_IHVNETWORK_ID
 #define SXG_ERROR   DPFLTR_ERROR_LEVEL
 
-//
-// SXG_DRIVER structure -
-//
-// contains information about the sxg driver.  There is only
-// one of these, and it is defined as a global.
-struct SXG_DRIVER {
-	struct adapter_t	*Adapters;		// Linked list of adapters
-	ushort				AdapterID;		// Maintain unique adapter ID
+/*
+ * struct sxg_driver structure -
+ *
+ * contains information about the sxg driver.  There is only
+ * one of these, and it is defined as a global.
+ */
+
+struct sxg_driver {
+	struct adapter_t	*Adapters;	/* Linked list of adapters */
+	ushort			AdapterID;	/* Maintain unique adapter ID */
 };
 
 #ifdef STATUS_SUCCESS
 #undef STATUS_SUCCESS
 #endif
 
+/* TODO: We need to try and use NETDEV_TX_* before posting this out */
 #define STATUS_SUCCESS              0
 #define STATUS_PENDING              0
 #define STATUS_FAILURE             -1
@@ -404,34 +416,36 @@
 #define SLIC_MAX_CARDS              32
 #define SLIC_MAX_PORTS              4        /* Max # of ports per card   */
 #if SLIC_DUMP_ENABLED
-// Dump buffer size
-//
-// This cannot be bigger than the max DMA size the card supports,
-// given the current code structure in the host and ucode.
-// Mojave supports 16K, Oasis supports 16K-1, so
-// just set this at 15K, shouldnt make that much of a diff.
-#define DUMP_BUF_SIZE               0x3C00
+
+/*
+ * Dump buffer size
+ * This cannot be bigger than the max DMA size the card supports,
+ * given the current code structure in the host and ucode.
+ * Mojave supports 16K, Oasis supports 16K-1, so
+ * just set this at 15K, shouldnt make that much of a diff.
+ */
+#define DUMP_BUF_SIZE	0x3C00
 #endif
 
 #define MIN(a, b) ((u32)(a) < (u32)(b) ? (a) : (b))
 #define MAX(a, b) ((u32)(a) > (u32)(b) ? (a) : (b))
 
-struct mcast_address_t {
-    unsigned char                     address[6];
-    struct mcast_address_t   *next;
+struct mcast_address {
+    unsigned char	   address[6];
+    struct mcast_address   *next;
 };
 
-#define CARD_DOWN        0x00000000
-#define CARD_UP          0x00000001
-#define CARD_FAIL        0x00000002
-#define CARD_DIAG        0x00000003
-#define CARD_SLEEP       0x00000004
+#define CARD_DOWN        		0x00000000
+#define CARD_UP          		0x00000001
+#define CARD_FAIL	        	0x00000002
+#define CARD_DIAG       		0x00000003
+#define CARD_SLEEP       		0x00000004
 
-#define ADAPT_DOWN             0x00
-#define ADAPT_UP               0x01
-#define ADAPT_FAIL             0x02
-#define ADAPT_RESET            0x03
-#define ADAPT_SLEEP            0x04
+#define ADAPT_DOWN	             	0x00
+#define ADAPT_UP        	       	0x01
+#define ADAPT_FAIL             		0x02
+#define ADAPT_RESET            		0x03
+#define ADAPT_SLEEP            		0x04
 
 #define ADAPT_FLAGS_BOOTTIME            0x0001
 #define ADAPT_FLAGS_IS64BIT             0x0002
@@ -443,29 +457,30 @@
 #define ADAPT_FLAGS_STATS_TIMER_SET     0x0080
 #define ADAPT_FLAGS_RESET_TIMER_SET     0x0100
 
-#define LINK_DOWN              0x00
-#define LINK_CONFIG            0x01
-#define LINK_UP                0x02
+#define LINK_DOWN			0x00
+#define LINK_CONFIG  			0x01
+#define LINK_UP    			0x02
 
-#define LINK_10MB              0x00
-#define LINK_100MB             0x01
-#define LINK_AUTOSPEED         0x02
-#define LINK_1000MB            0x03
-#define LINK_10000MB           0x04
+#define LINK_10MB    			0x00
+#define LINK_100MB         		0x01
+#define LINK_AUTOSPEED  		0x02
+#define LINK_1000MB        		0x03
+#define LINK_10000MB          		0x04
 
-#define LINK_HALFD             0x00
-#define LINK_FULLD             0x01
-#define LINK_AUTOD             0x02
+#define LINK_HALFD       		0x00
+#define LINK_FULLD     			0x01
+#define LINK_AUTOD 			0x02
 
-#define MAC_DIRECTED     0x00000001
-#define MAC_BCAST        0x00000002
-#define MAC_MCAST        0x00000004
-#define MAC_PROMISC      0x00000008
-#define MAC_LOOPBACK     0x00000010
-#define MAC_ALLMCAST     0x00000020
+#define MAC_DIRECTED 			0x00000001
+#define MAC_BCAST 			0x00000002
+#define MAC_MCAST  			0x00000004
+#define MAC_PROMISC  			0x00000008
+#define MAC_LOOPBACK   			0x00000010
+#define MAC_ALLMCAST  			0x00000020
 
 #define SLIC_DUPLEX(x)    ((x==LINK_FULLD) ? "FDX" : "HDX")
-#define SLIC_SPEED(x)     ((x==LINK_100MB) ? "100Mb" : ((x==LINK_1000MB) ? "1000Mb" : " 10Mb"))
+#define SLIC_SPEED(x)     ((x==LINK_100MB) ? "100Mb" : 			\
+				((x==LINK_1000MB) ? "1000Mb" : " 10Mb"))
 #define SLIC_LINKSTATE(x) ((x==LINK_DOWN) ? "Down" : "Up  ")
 #define SLIC_ADAPTER_STATE(x) ((x==ADAPT_UP) ? "UP" : "Down")
 #define SLIC_CARD_STATE(x)    ((x==CARD_UP) ? "UP" : "Down")
@@ -481,32 +496,36 @@
 #define NUM_CFG_SPACES      2
 #define NUM_CFG_REGS        64
 
-struct physcard_t {
-    struct adapter_t  *adapter[SLIC_MAX_PORTS];
-    struct physcard_t *next;
+/*
+ * We split LSS sends across four microcode queues derived from
+ * destination TCP port (if TCP/IP).
+ */
+#define SXG_LARGE_SEND_QUEUE_MASK    0x3
+#define ISCSI_PORT 	             0xbc0c                  /* 3260 */
+
+struct physcard {
+    struct adapter_t		*adapter[SLIC_MAX_PORTS];
+    struct physcard		*next;
     unsigned int                adapters_allocd;
 };
 
-struct sxgbase_driver_t {
+struct sxgbase_driver {
 	spinlock_t	driver_lock;
 	unsigned long	flags;	/* irqsave for spinlock */
 	u32		num_sxg_cards;
 	u32		num_sxg_ports;
 	u32		num_sxg_ports_active;
 	u32		dynamic_intagg;
-	struct physcard_t	*phys_card;
+	struct physcard	*phys_card;
 };
 
 
 struct adapter_t {
 	void *               ifp;
 	unsigned int                port;
-	struct physcard_t        *physcard;
+	struct napi_struct 	napi;
+	struct physcard        *physcard;
 	unsigned int                physport;
-	unsigned int                cardindex;
-	unsigned int                card_size;
-	unsigned int                chipid;
-	unsigned int                busnumber;
 	unsigned int                slotnumber;
 	unsigned int                functionnumber;
 	ushort              vendid;
@@ -514,32 +533,23 @@
 	ushort              subsysid;
 	u32             irq;
 
-	void *               sxg_adapter;
-	u32             nBusySend;
-
 	void __iomem *	base_addr;
 	u32             memorylength;
 	u32             drambase;
 	u32             dramlength;
-	unsigned int                queues_initialized;
-	unsigned int                allocated;
+	enum asic_type	asictype;      /* type of ASIC (chip) */
 	unsigned int                activated;
 	u32             intrregistered;
 	unsigned int                isp_initialized;
-	unsigned int                gennumber;
-	u32             curaddrupper;
-	u32             isrcopy;
 	unsigned char               state;
 	unsigned char               linkstate;
-	unsigned char               linkspeed;
-	unsigned char               linkduplex;
 	unsigned int                flags;
 	unsigned char               macaddr[6];
 	unsigned char               currmacaddr[6];
 	u32             macopts;
 	ushort              devflags_prev;
 	u64             mcastmask;
-	struct mcast_address_t   *mcastaddrs;
+	struct mcast_address   *mcastaddrs;
 	struct timer_list   pingtimer;
 	u32             pingtimerset;
 	struct timer_list   statstimer;
@@ -574,135 +584,140 @@
 	u32             rcv_interrupt_yields;
 	u32             intagg_period;
 	struct net_device_stats stats;
-	u32 *					MiniportHandle;		// Our miniport handle
-	enum SXG_STATE					State;				// Adapter state
-	enum SXG_LINK_STATE				LinkState;			// Link state
-	u64						LinkSpeed;			// Link Speed
-	u32						PowerState;			// NDIS power state
-	struct adapter_t   		*Next;				// Linked list
-	ushort						AdapterID;			// 1..n
-	unsigned char						MacAddr[6];			// Our permanent HW mac address
-	unsigned char						CurrMacAddr[6];		// Our Current mac address
-	p_net_device                netdev;
-	p_net_device                next_netdevice;
-	struct pci_dev            * pcidev;
+	u32 *			MiniportHandle;		/* Our miniport handle */
+	enum SXG_STATE 		State;			/* Adapter state */
+	enum SXG_LINK_STATE 	LinkState;		/* Link state */
+	u64			LinkSpeed;		/* Link Speed */
+	u32			PowerState;		/* NDIS power state */
+	struct adapter_t  	*Next;			/* Linked list */
+	ushort			AdapterID;		/* 1..n */
+	struct net_device *         netdev;
+	struct net_device *         next_netdevice;
+	struct pci_dev            *pcidev;
 
-	struct SXG_MULTICAST_ADDRESS		*MulticastAddrs;		// Multicast list
-	u64     				MulticastMask;		// Multicast mask
-	u32 *					InterruptHandle;	// Register Interrupt handle
-	u32						InterruptLevel;		// From Resource list
-	u32						InterruptVector;	// From Resource list
-	spinlock_t	AdapterLock;	/* Serialize access adapter routines */
-	spinlock_t	Bit64RegLock;	/* For writing 64-bit addresses */
-	struct SXG_HW_REGS			*HwRegs;				// Sahara HW Register Memory (BAR0/1)
-	struct SXG_UCODE_REGS			*UcodeRegs;			// Microcode Register Memory (BAR2/3)
-	struct SXG_TCB_REGS			*TcbRegs;			// Same as Ucode regs - See sxghw.h
-	ushort						ResetDpcCount;		// For timeout
-	ushort						RssDpcCount;		// For timeout
-	ushort						VendorID;			// Vendor ID
-	ushort						DeviceID;			// Device ID
-	ushort						SubSystemID;		// Sub-System ID
-	ushort						FrameSize;			// Maximum frame size
-	u32 *					DmaHandle;			// NDIS DMA handle
-	u32 *					PacketPoolHandle;	// Used with NDIS 5.2 only.  Don't ifdef out
-	u32 *					BufferPoolHandle;	// Used with NDIS 5.2 only.  Don't ifdef out
-	u32						MacFilter;			// NDIS MAC Filter
-	ushort						IpId;				// For slowpath
-	struct SXG_EVENT_RING			*EventRings;			// Host event rings.  1/CPU to 16 max
-	dma_addr_t              	PEventRings;		// Physical address
-	u32						NextEvent[SXG_MAX_RSS];	// Current location in ring
-	dma_addr_t          		PTcbBuffers;		// TCB Buffers - physical address
-	dma_addr_t	            	PTcbCompBuffers;	// TCB Composite Buffers - phys addr
-	struct SXG_XMT_RING				*XmtRings;			// Transmit rings
-	dma_addr_t		            PXmtRings;			// Transmit rings - physical address
-	struct SXG_RING_INFO				XmtRingZeroInfo;	// Transmit ring 0 info
+	struct sxg_multicast_address	*MulticastAddrs; /* Multicast list */
+	u64     		MulticastMask;		/* Multicast mask */
+	u32 			*InterruptHandle;	/* Register Interrupt handle */
+	u32			InterruptLevel;		/* From Resource list */
+	u32			InterruptVector;	/* From Resource list */
+	spinlock_t		AdapterLock;	/* Serialize access adapter routines */
+	spinlock_t		Bit64RegLock;	/* For writing 64-bit addresses */
+	struct sxg_hw_regs	*HwRegs;	/* Sahara HW Register Memory (BAR0/1) */
+	struct sxg_ucode_regs	*UcodeRegs;	/* Microcode Register Memory (BAR2/3) */
+	struct sxg_tcb_regs	*TcbRegs;	/* Same as Ucode regs - See sxghw.h */
+	ushort         	FrameSize;	/* Maximum frame size */
+	u32 *		DmaHandle;	/* NDIS DMA handle */
+	u32 *		PacketPoolHandle;	/* Used with NDIS 5.2 only.  Don't ifdef out */
+	u32 *		BufferPoolHandle;	/* Used with NDIS 5.2 only.  Don't ifdef out */
+	u32		MacFilter;		/* NDIS MAC Filter */
+	struct sxg_event_ring	*EventRings;	/* Host event rings.  1/CPU to 16 max */
+	dma_addr_t             	PEventRings;	/* Physical address */
+	u32		NextEvent[SXG_MAX_RSS];	/* Current location in ring */
+	dma_addr_t     	PTcbBuffers;		/* TCB Buffers - physical address */
+	dma_addr_t	PTcbCompBuffers;	/* TCB Composite Buffers - phys addr */
+	struct sxg_xmt_ring	*XmtRings;	/* Transmit rings */
+	dma_addr_t		PXmtRings;	/* Transmit rings - physical address */
+	struct sxg_ring_info	XmtRingZeroInfo;	/* Transmit ring 0 info */
+
 	spinlock_t	XmtZeroLock;	/* Transmit ring 0 lock */
-	u32 *					XmtRingZeroIndex;	// Shared XMT ring 0 index
-	dma_addr_t          		PXmtRingZeroIndex;	// Shared XMT ring 0 index - physical
-	struct LIST_ENTRY					FreeProtocolHeaders;// Free protocol headers
-	u32						FreeProtoHdrCount;	// Count
-	void *						ProtocolHeaders;	// Block of protocol header
-	dma_addr_t	            	PProtocolHeaders;	// Block of protocol headers - phys
+	u32 *		XmtRingZeroIndex;	/* Shared XMT ring 0 index */
+	dma_addr_t     	PXmtRingZeroIndex;	/* Shared XMT ring 0 index - physical */
+	struct list_entry	FreeProtocolHeaders;/* Free protocol headers */
+	u32		FreeProtoHdrCount;	/* Count */
+	void *		ProtocolHeaders;	/* Block of protocol header */
+	dma_addr_t	PProtocolHeaders;	/* Block of protocol headers - phys */
 
-	struct SXG_RCV_RING		*RcvRings;			// Receive rings
-	dma_addr_t	            	PRcvRings;			// Receive rings - physical address
-	struct SXG_RING_INFO				RcvRingZeroInfo;	// Receive ring 0 info
+	struct sxg_rcv_ring	*RcvRings;	/* Receive rings */
+	dma_addr_t	PRcvRings;		/* Receive rings - physical address */
+	struct sxg_ucode_stats	*ucode_stats;		/* Ucode Stats  */
+	/* Ucode Stats - physical address */
+	dma_addr_t	        pucode_stats;
 
-	u32 *					Isr;				// Interrupt status register
-	dma_addr_t	            	PIsr;				// ISR - physical address
-	u32						IsrCopy[SXG_MAX_RSS];	// Copy of ISR
-	ushort						InterruptsEnabled;	// Bitmask of enabled vectors
-	unsigned char *						IndirectionTable;	// RSS indirection table
-	dma_addr_t	            	PIndirectionTable;	// Physical address
-	ushort						RssTableSize;		// From NDIS_RECEIVE_SCALE_PARAMETERS
-	ushort						HashKeySize;		// From NDIS_RECEIVE_SCALE_PARAMETERS
-	unsigned char						HashSecretKey[40];	// rss key
-	u32						HashInformation;
-	// Receive buffer queues
-	spinlock_t	RcvQLock;	/* Receive Queue Lock */
-	struct LIST_ENTRY					FreeRcvBuffers;		// Free SXG_DATA_BUFFER queue
-	struct LIST_ENTRY					FreeRcvBlocks;		// Free SXG_RCV_DESCRIPTOR_BLOCK Q
-	struct LIST_ENTRY					AllRcvBlocks;		// All SXG_RCV_BLOCKs
-	ushort						FreeRcvBufferCount;	// Number of free rcv data buffers
-	ushort						FreeRcvBlockCount;	// # of free rcv descriptor blocks
-	ushort						AllRcvBlockCount;	// Number of total receive blocks
-	ushort						ReceiveBufferSize;	// SXG_RCV_DATA/JUMBO_BUFFER_SIZE only
-	u32						AllocationsPending;	// Receive allocation pending
-	u32						RcvBuffersOnCard;	// SXG_DATA_BUFFERS owned by card
-	// SGL buffers
+	struct sxg_ring_info	RcvRingZeroInfo;	/* Receive ring 0 info */
+
+	u32 *		Isr;		/* Interrupt status register */
+	dma_addr_t	PIsr;		/* ISR - physical address */
+	u32		IsrCopy[SXG_MAX_RSS];	/* Copy of ISR */
+	ushort		InterruptsEnabled;	/* Bitmask of enabled vectors */
+	unsigned char 	*IndirectionTable;	/* RSS indirection table */
+	dma_addr_t	PIndirectionTable;	/* Physical address */
+	ushort		RssTableSize;		/* From NDIS_RECEIVE_SCALE_PARAMETERS */
+	ushort		HashKeySize;		/* From NDIS_RECEIVE_SCALE_PARAMETERS */
+	unsigned char	HashSecretKey[40];	/* rss key */
+	u32		HashInformation;
+	/* Receive buffer queues */
+	spinlock_t      RcvQLock;       	/* Receive Queue Lock */
+	struct list_entry	FreeRcvBuffers;		/* Free SXG_DATA_BUFFER queue */
+	struct list_entry	FreeRcvBlocks;		/* Free SXG_RCV_DESCRIPTOR_BLOCK Q */
+	struct list_entry	AllRcvBlocks;		/* All SXG_RCV_BLOCKs */
+	ushort		FreeRcvBufferCount;	/* Number of free rcv data buffers */
+	ushort		FreeRcvBlockCount;	/* # of free rcv descriptor blocks */
+	ushort		AllRcvBlockCount;	/* Number of total receive blocks */
+	ushort		ReceiveBufferSize;	/* SXG_RCV_DATA/JUMBO_BUFFER_SIZE only */
+	/* Converted this to a atomic variable
+	u32			AllocationsPending;	*/
+	atomic_t		pending_allocations;
+	u32		AllocationsPending;	/* Receive allocation pending */
+	u32		RcvBuffersOnCard;	/* SXG_DATA_BUFFERS owned by card */
+	/* SGL buffers */
 	spinlock_t	SglQLock;	/* SGL Queue Lock */
-	struct LIST_ENTRY					FreeSglBuffers;		// Free SXG_SCATTER_GATHER
-	struct LIST_ENTRY					AllSglBuffers;		// All SXG_SCATTER_GATHER
-	ushort						FreeSglBufferCount;	// Number of free SGL buffers
-	ushort						AllSglBufferCount;	// Number of total SGL buffers
-	u32						CurrentTime;		// Tick count
-	u32						FastpathConnections;// # of fastpath connections
-	// Various single-bit flags:
-	u32						BasicAllocations:1;	// Locks and listheads
-	u32						IntRegistered:1;	// Interrupt registered
-	u32						PingOutstanding:1;	// Ping outstanding to card
-	u32						Dead:1;				// Card dead
-	u32						DumpDriver:1;		// OID_SLIC_DRIVER_DUMP request
-	u32						DumpCard:1;			// OID_SLIC_CARD_DUMP request
-	u32						DumpCmdRunning:1;	// Dump command in progress
-	u32						DebugRunning:1;		// AGDB debug in progress
-	u32						JumboEnabled:1;		// Jumbo frames enabled
-	u32						MsiEnabled:1;		// MSI interrupt enabled
-	u32						RssEnabled:1;		// RSS Enabled
-	u32						FailOnBadEeprom:1;	// Fail on Bad Eeprom
-	u32						DiagStart:1;		// Init adapter for diagnostic start
-	// Stats
-	u32						PendingRcvCount;	// Outstanding rcv indications
-	u32						PendingXmtCount;	// Outstanding send requests
-	struct SXG_STATS				Stats;				// Statistics
-	u32						ReassBufs;			// Number of reassembly buffers
-	// Card Crash Info
-	ushort						CrashLocation;		// Microcode crash location
-	unsigned char						CrashCpu;			// Sahara CPU ID
-	// Diagnostics
-	//	PDIAG_CMD					DiagCmds;			// List of free diagnostic commands
-	//	PDIAG_BUFFER				DiagBuffers;		// List of free diagnostic buffers
-	//	PDIAG_REQ					DiagReqQ;			// List of outstanding (asynchronous) diag requests
-	//	u32						DiagCmdTimeout;		// Time out for diag cmds (seconds) XXXTODO - replace with SXG_PARAM var?
-	//	unsigned char						DiagDmaDesc[DMA_CPU_CTXS];		// Free DMA descriptors bit field (32 CPU ctx * 8 DMA ctx)
-
-	/////////////////////////////////////////////////////////////////////
-	// Put preprocessor-conditional fields at the end so we don't
-	// have to recompile sxgdbg everytime we reconfigure the driver
-	/////////////////////////////////////////////////////////////////////
-	void *						PendingSetRss;		// Pending RSS parameter change
-	u32						IPv4HdrSize;		// Shared 5.2/6.0 encap param
-	unsigned char *          			InterruptInfo;		// Allocated by us during AddDevice
+	struct list_entry	FreeSglBuffers;		/* Free struct sxg_scatter_gather */
+	struct list_entry	AllSglBuffers;		/* All struct sxg_scatter_gather */
+	ushort		FreeSglBufferCount;	/* Number of free SGL buffers */
+	ushort		AllSglBufferCount;	/* Number of total SGL buffers */
+	u32		CurrentTime;		/* Tick count */
+	u32		FastpathConnections;/* # of fastpath connections */
+	/* Various single-bit flags: */
+	u32		BasicAllocations:1;	/* Locks and listheads */
+	u32		IntRegistered:1;	/* Interrupt registered */
+	u32		PingOutstanding:1;	/* Ping outstanding to card */
+	u32		Dead:1;				/* Card dead */
+	u32		DumpDriver:1;		/* OID_SLIC_DRIVER_DUMP request */
+	u32		DumpCard:1;			/* OID_SLIC_CARD_DUMP request */
+	u32		DumpCmdRunning:1;	/* Dump command in progress */
+	u32		DebugRunning:1;		/* AGDB debug in progress */
+	u32		JumboEnabled:1;		/* Jumbo frames enabled */
+	u32		msi_enabled:1;		/* MSI interrupt enabled */
+	u32		RssEnabled:1;		/* RSS Enabled */
+	u32		FailOnBadEeprom:1;	/* Fail on Bad Eeprom */
+	u32		DiagStart:1;		/* Init adapter for diagnostic start */
+ 	u32 		XmtFcEnabled:1;
+ 	u32 		RcvFcEnabled:1;
+	/* Stats */
+	u32		PendingRcvCount;	/* Outstanding rcv indications */
+	u32		PendingXmtCount;	/* Outstanding send requests */
+	struct sxg_stats	Stats;				/* Statistics */
+	u32		ReassBufs;			/* Number of reassembly buffers */
+	/* Card Crash Info */
+	ushort		CrashLocation;		/* Microcode crash location */
+	unsigned char	CrashCpu;			/* Sahara CPU ID */
+	/* Diagnostics */
+	/*	PDIAG_CMD	DiagCmds; */			/* List of free diagnostic commands */
+	/*	PDIAG_BUFFER	DiagBuffers; */		/* List of free diagnostic buffers */
+	/*	PDIAG_REQ	DiagReqQ; */			/* List of outstanding (asynchronous) diag requests */
+	/*	u32		DiagCmdTimeout; */		/* Time out for diag cmds (seconds) XXXTODO - replace with SXG_PARAM var? */
+	/*	unsigned char	DiagDmaDesc[DMA_CPU_CTXS]; */		/* Free DMA descriptors bit field (32 CPU ctx * 8 DMA ctx) */
+	/*
+	 * Put preprocessor-conditional fields at the end so we don't
+	 * have to recompile sxgdbg everytime we reconfigure the driver
+	 */
 #if defined(CONFIG_X86)
-	u32						AddrUpper;			// Upper 32 bits of 64-bit register
+	u32		AddrUpper;			/* Upper 32 bits of 64-bit register */
 #endif
-	//#if SXG_FAILURE_DUMP
-	//	NDIS_EVENT					DumpThreadEvent;	// syncronize dump thread
-	//	BOOLEAN						DumpThreadRunning;	// termination flag
-	//	PSXG_DUMP_CMD				DumpBuffer;			// 68k - Cmd and Buffer
-	//	dma_addr_t		PDumpBuffer;		// Physical address
-	//#endif // SXG_FAILURE_DUMP
-
+	unsigned short max_aggregation;
+	unsigned short min_aggregation;
+	/*#if SXG_FAILURE_DUMP */
+	/*	NDIS_EVENT	DumpThreadEvent; */	/* syncronize dump thread */
+	/*	BOOLEAN		DumpThreadRunning; */	/* termination flag */
+	/*	PSXG_DUMP_CMD	DumpBuffer; */			/* 68k - Cmd and Buffer */
+	/*	dma_addr_t	PDumpBuffer; */		/* Physical address */
+	/*#endif */ /* SXG_FAILURE_DUMP */
+	/*MSI-X related data elements*/
+	u32 nr_msix_entries;
+	struct msix_entry *msi_entries;
+	struct timer_list watchdog_timer;
+	struct work_struct update_link_status;
+	u32 	link_status_changed;
 };
 
 #if SLIC_DUMP_ENABLED
@@ -710,12 +725,10 @@
 #define SLIC_DUMP_IN_PROGRESS    2
 #define SLIC_DUMP_DONE           3
 
-/****************************************************************************
- *
+/*
  * Microcode crash information structure.  This
  * structure is written out to the card's SRAM when the microcode panic's.
- *
- ****************************************************************************/
+ */
 struct slic_crash_info {
     ushort  cpu_id;
     ushort  crash_pc;
@@ -738,21 +751,25 @@
     (largestat) += ((newstat) - (oldstat));                              \
 }
 
-#define ETHER_EQ_ADDR(_AddrA, _AddrB, _Result)                           \
-{                                                                        \
-    _Result = TRUE;                                                      \
-    if (*(u32 *)(_AddrA) != *(u32 *)(_AddrB))                      \
-        _Result = FALSE;                                                 \
-    if (*(u16 *)(&((_AddrA)[4])) != *(u16 *)(&((_AddrB)[4])))        \
-        _Result = FALSE;                                                 \
+#define ETHER_EQ_ADDR(_AddrA, _AddrB, _Result)                          \
+{                                                                       \
+    _Result = TRUE;                                                     \
+    if (*(u32 *)(_AddrA) != *(u32 *)(_AddrB))                      	\
+        _Result = FALSE;                                                \
+    if (*(u16 *)(&((_AddrA)[4])) != *(u16 *)(&((_AddrB)[4])))        	\
+        _Result = FALSE;                                                \
 }
 
 #define ETHERMAXFRAME   1514
 #define JUMBOMAXFRAME   9014
 
+#define SXG_JUMBO_MTU 9000
+#define SXG_DEFAULT_MTU 1500
+
 #if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
 #define   SXG_GET_ADDR_LOW(_addr)  (u32)((u64)(_addr) & 0x00000000FFFFFFFF)
-#define   SXG_GET_ADDR_HIGH(_addr)  (u32)(((u64)(_addr) >> 32) & 0x00000000FFFFFFFF)
+#define   SXG_GET_ADDR_HIGH(_addr)  					\
+			(u32)(((u64)(_addr) >> 32) & 0x00000000FFFFFFFF)
 #else
 #define   SXG_GET_ADDR_LOW(_addr)   (u32)_addr
 #define   SXG_GET_ADDR_HIGH(_addr)  (u32)0
@@ -761,8 +778,10 @@
 #define FLUSH       TRUE
 #define DONT_FLUSH  FALSE
 
-#define SIOCSLICDUMPCARD         SIOCDEVPRIVATE+9
-#define SIOCSLICSETINTAGG        SIOCDEVPRIVATE+10
-#define SIOCSLICTRACEDUMP        SIOCDEVPRIVATE+11
+#define SIOCSLICDUMPCARD         (SIOCDEVPRIVATE+9)
+#define SIOCSLICSETINTAGG        (SIOCDEVPRIVATE+10)
+#define SIOCSLICTRACEDUMP        (SIOCDEVPRIVATE+11)
 
+extern struct ethtool_ops sxg_nic_ethtool_ops;
+#define SXG_COMPLETE_SLOW_SEND_LIMIT	128
 #endif /*  __SXG_DRIVER_H__ */
diff --git a/drivers/staging/sxg/sxg_ethtool.c b/drivers/staging/sxg/sxg_ethtool.c
new file mode 100644
index 0000000..97f765d
--- /dev/null
+++ b/drivers/staging/sxg/sxg_ethtool.c
@@ -0,0 +1,328 @@
+/**************************************************************************
+ *
+ * Copyright (C) 2000-2008 Alacritech, 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:
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``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 ALACRITECH, INC. 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.
+ *
+ * The views and conclusions contained in the software and documentation
+ * are those of the authors and should not be interpreted as representing
+ * official policies, either expressed or implied, of Alacritech, Inc.
+ *
+ **************************************************************************/
+
+/*
+ * FILENAME: sxg_ethtool.c
+ *
+ * The ethtool support for SXG driver for Alacritech's 10Gbe products.
+ *
+ * NOTE: This is the standard, non-accelerated version of Alacritech's
+ *       IS-NIC driver.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/skbuff.h>
+#include <linux/pci.h>
+
+#include "sxg_os.h"
+#include "sxghw.h"
+#include "sxghif.h"
+#include "sxg.h"
+
+struct sxg_nic_stats {
+        char stat_string[ETH_GSTRING_LEN];
+        int sizeof_stat;
+        int stat_offset;
+};
+
+#define SXG_NIC_STATS(m) sizeof(((struct adapter_t *)0)->m), \
+				offsetof(struct adapter_t, m)
+
+#define USER_VIEWABLE_EEPROM_SIZE	28
+
+static struct sxg_nic_stats sxg_nic_gstrings_stats[] = {
+	{"xmit_ring_0_full", SXG_NIC_STATS(Stats.XmtZeroFull)},
+
+	/* May be will need in future */
+/*	{"dumb_xmit_broadcast_packets", SXG_NIC_STATS(Stats.DumbXmtBcastPkts)},
+	{"dumb_xmit_broadcast_bytes", SXG_NIC_STATS(Stats.DumbXmtBcastBytes)},
+	{"dumb_xmit_unicast_packets", SXG_NIC_STATS(Stats.DumbXmtUcastPkts)},
+	{"dumb_xmit_unicast_bytes", SXG_NIC_STATS(Stats.DumbXmtUcastBytes)},
+*/
+	{"xmit_queue_length", SXG_NIC_STATS(Stats.XmtQLen)},
+	{"memory_allocation_failure", SXG_NIC_STATS(Stats.NoMem)},
+	{"Interrupts", SXG_NIC_STATS(Stats.NumInts)},
+	{"false_interrupts", SXG_NIC_STATS(Stats.FalseInts)},
+	{"processed_data_queue_full", SXG_NIC_STATS(Stats.PdqFull)},
+	{"event_ring_full", SXG_NIC_STATS(Stats.EventRingFull)},
+	{"transport_checksum_error", SXG_NIC_STATS(Stats.TransportCsum)},
+	{"transport_underflow_error", SXG_NIC_STATS(Stats.TransportUflow)},
+	{"transport_header_length_error", SXG_NIC_STATS(Stats.TransportHdrLen)},
+	{"network_checksum_error", SXG_NIC_STATS(Stats.NetworkCsum)},
+	{"network_underflow_error", SXG_NIC_STATS(Stats.NetworkUflow)},
+	{"network_header_length_error", SXG_NIC_STATS(Stats.NetworkHdrLen)},
+	{"receive_parity_error", SXG_NIC_STATS(Stats.Parity)},
+	{"link_parity_error", SXG_NIC_STATS(Stats.LinkParity)},
+	{"link/data early_error", SXG_NIC_STATS(Stats.LinkEarly)},
+	{"buffer_overflow_error", SXG_NIC_STATS(Stats.LinkBufOflow)},
+	{"link_code_error", SXG_NIC_STATS(Stats.LinkCode)},
+	{"dribble nibble", SXG_NIC_STATS(Stats.LinkDribble)},
+	{"CRC_error", SXG_NIC_STATS(Stats.LinkCrc)},
+	{"link_overflow_error", SXG_NIC_STATS(Stats.LinkOflow)},
+	{"link_underflow_error", SXG_NIC_STATS(Stats.LinkUflow)},
+
+	/* May be need in future */
+/*	{"dumb_rcv_broadcast_packets", SXG_NIC_STATS(Stats.DumbRcvBcastPkts)},
+	{"dumb_rcv_broadcast_bytes", SXG_NIC_STATS(Stats.DumbRcvBcastBytes)},
+*/	{"dumb_rcv_multicast_packets", SXG_NIC_STATS(Stats.DumbRcvMcastPkts)},
+	{"dumb_rcv_multicast_bytes", SXG_NIC_STATS(Stats.DumbRcvMcastBytes)},
+/*	{"dumb_rcv_unicast_packets", SXG_NIC_STATS(Stats.DumbRcvUcastPkts)},
+	{"dumb_rcv_unicast_bytes", SXG_NIC_STATS(Stats.DumbRcvUcastBytes)},
+*/
+	{"no_sgl_buffer", SXG_NIC_STATS(Stats.NoSglBuf)},
+};
+
+#define SXG_NIC_STATS_LEN	ARRAY_SIZE(sxg_nic_gstrings_stats)
+
+static inline void sxg_reg32_write(void __iomem *reg, u32 value, bool flush)
+{
+        writel(value, reg);
+        if (flush)
+                mb();
+}
+
+static inline void sxg_reg64_write(struct adapter_t *adapter, void __iomem *reg,
+                                   u64 value, u32 cpu)
+{
+        u32 value_high = (u32) (value >> 32);
+        u32 value_low = (u32) (value & 0x00000000FFFFFFFF);
+        unsigned long flags;
+
+        spin_lock_irqsave(&adapter->Bit64RegLock, flags);
+        writel(value_high, (void __iomem *)(&adapter->UcodeRegs[cpu].Upper));
+        writel(value_low, reg);
+        spin_unlock_irqrestore(&adapter->Bit64RegLock, flags);
+}
+
+static void
+sxg_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
+{
+	struct adapter_t *adapter = netdev_priv(dev);
+	strncpy(drvinfo->driver, sxg_driver_name, 32);
+	strncpy(drvinfo->version, SXG_DRV_VERSION, 32);
+//	strncpy(drvinfo->fw_version, SAHARA_UCODE_VERS_STRING, 32);
+	strncpy(drvinfo->bus_info, pci_name(adapter->pcidev), 32);
+	/* TODO : Read the major and minor number of firmware. Is this
+ 	 * from the FLASH/EEPROM or download file ?
+ 	 */
+	/* LINSYS : Check if this is correct or if not find the right value
+ 	 * Also check what is the right EEPROM length : EEPROM_SIZE_XFMR or EEPROM_SIZE_NO_XFMR
+ 	 */
+}
+
+static int sxg_nic_set_settings(struct net_device *netdev,
+                              struct ethtool_cmd *ecmd)
+{
+	/* No settings are applicable as we support only 10Gb/FIBRE_media */
+	return -EOPNOTSUPP;
+}
+
+static void
+sxg_nic_get_strings(struct net_device *netdev, u32 stringset, u8 * data)
+{
+	int index;
+
+	switch(stringset) {
+	case ETH_SS_TEST:
+		break;
+	case ETH_SS_STATS:
+		for (index = 0; index < SXG_NIC_STATS_LEN; index++) {
+                	memcpy(data + index * ETH_GSTRING_LEN,
+                        	sxg_nic_gstrings_stats[index].stat_string,
+                               	ETH_GSTRING_LEN);
+                }
+                break;
+	}
+}
+
+static void
+sxg_nic_get_ethtool_stats(struct net_device *netdev,
+			struct ethtool_stats *stats, u64 * data)
+{
+        struct adapter_t *adapter = netdev_priv(netdev);
+        int index;
+        for (index = 0; index < SXG_NIC_STATS_LEN; index++) {
+                char *p = (char *)adapter +
+				sxg_nic_gstrings_stats[index].stat_offset;
+                data[index] = (sxg_nic_gstrings_stats[index].sizeof_stat ==
+		                     sizeof(u64)) ? *(u64 *) p : *(u32 *) p;
+        }
+}
+
+static int sxg_nic_get_sset_count(struct net_device *netdev, int sset)
+{
+        switch (sset) {
+        case ETH_SS_STATS:
+       		return SXG_NIC_STATS_LEN;
+	default:
+                return -EOPNOTSUPP;
+        }
+}
+
+static int sxg_nic_get_settings(struct net_device *netdev,
+				struct ethtool_cmd *ecmd)
+{
+	struct adapter_t *adapter = netdev_priv(netdev);
+
+        ecmd->supported = SUPPORTED_10000baseT_Full;
+        ecmd->autoneg = AUTONEG_ENABLE;		//VSS check This
+        ecmd->transceiver = XCVR_EXTERNAL;	//VSS check This
+
+	/* For Fibre Channel */
+	ecmd->supported |= SUPPORTED_FIBRE;
+        ecmd->advertising = (ADVERTISED_10000baseT_Full |
+                                ADVERTISED_FIBRE);
+	ecmd->port = PORT_FIBRE;
+
+
+	/* Link Speed */
+	if(adapter->LinkState & SXG_LINK_UP) {
+		ecmd->speed = SPEED_10000;	//adapter->LinkSpeed;
+		ecmd->duplex = DUPLEX_FULL;
+	}
+	return 0;
+}
+
+static u32 sxg_nic_get_rx_csum(struct net_device *netdev)
+{
+	struct adapter_t *adapter = netdev_priv(netdev);
+	return ((adapter->flags & SXG_RCV_IP_CSUM_ENABLED) &&
+		 (adapter->flags & SXG_RCV_TCP_CSUM_ENABLED));
+}
+
+static int sxg_nic_set_rx_csum(struct net_device *netdev, u32 data)
+{
+	struct adapter_t *adapter = netdev_priv(netdev);
+	if (data)
+		adapter->flags |= SXG_RCV_IP_CSUM_ENABLED;
+	else
+		adapter->flags &= ~SXG_RCV_IP_CSUM_ENABLED;
+	/*
+	 * We dont need to write to the card to do checksums.
+	 * It does it anyways.
+	 */
+	return 0;
+}
+
+static int sxg_nic_get_regs_len(struct net_device *dev)
+{
+	return (SXG_HWREG_MEMSIZE + SXG_UCODEREG_MEMSIZE);
+}
+
+static void sxg_nic_get_regs(struct net_device *netdev,
+			struct ethtool_regs *regs, void *p)
+{
+	struct adapter_t *adapter = netdev_priv(netdev);
+	struct sxg_hw_regs *HwRegs = adapter->HwRegs;
+	struct sxg_ucode_regs *UcodeRegs = adapter->UcodeRegs;
+	u32 *buff = p;
+
+	memset(p, 0, (sizeof(struct sxg_hw_regs)+sizeof(struct sxg_ucode_regs)));
+	memcpy(buff, HwRegs, sizeof(struct sxg_hw_regs));
+	memcpy((buff+sizeof(struct sxg_hw_regs)), UcodeRegs, sizeof(struct sxg_ucode_regs));
+}
+
+static int sxg_nic_get_eeprom_len(struct net_device *netdev)
+{
+	return (USER_VIEWABLE_EEPROM_SIZE);
+}
+
+static int sxg_nic_get_eeprom(struct net_device *netdev,
+				struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+	struct adapter_t *adapter = netdev_priv(netdev);
+	struct sw_cfg_data *data;
+	unsigned long           i, status;
+	dma_addr_t p_addr;
+
+	data = pci_alloc_consistent(adapter->pcidev, sizeof(struct sw_cfg_data),
+					 &p_addr);
+	if(!data) {
+                /*
+		 * We cant get even this much memory. Raise a hell
+                 * Get out of here
+                 */
+                printk(KERN_ERR"%s : Could not allocate memory for reading \
+                                EEPROM\n", __FUNCTION__);
+                return -ENOMEM;
+        }
+
+        WRITE_REG(adapter->UcodeRegs[0].ConfigStat, SXG_CFG_TIMEOUT, TRUE);
+        WRITE_REG64(adapter, adapter->UcodeRegs[0].Config, p_addr, 0);
+	for(i=0; i<1000; i++) {
+                READ_REG(adapter->UcodeRegs[0].ConfigStat, status);
+                if (status != SXG_CFG_TIMEOUT)
+                        break;
+                mdelay(1);      /* Do we really need this */
+        }
+
+	memset(bytes, 0, eeprom->len);
+        memcpy(bytes, data->MacAddr[0].MacAddr, sizeof(struct sxg_config_mac));
+        memcpy(bytes+6, data->AtkFru.PartNum, 6);
+        memcpy(bytes+12, data->AtkFru.Revision, 2);
+        memcpy(bytes+14, data->AtkFru.Serial, 14);
+
+	return 0;
+}
+
+struct ethtool_ops sxg_nic_ethtool_ops = {
+	.get_settings = sxg_nic_get_settings,
+	.set_settings = sxg_nic_set_settings,
+	.get_drvinfo = sxg_nic_get_drvinfo,
+	.get_regs_len = sxg_nic_get_regs_len,
+	.get_regs = sxg_nic_get_regs,
+	.get_link = ethtool_op_get_link,
+//	.get_wol = sxg_nic_get_wol,
+	.get_eeprom_len = sxg_nic_get_eeprom_len,
+	.get_eeprom = sxg_nic_get_eeprom,
+//	.get_pauseparam = sxg_nic_get_pauseparam,
+//	.set_pauseparam = sxg_nic_set_pauseparam,
+	.set_tx_csum = ethtool_op_set_tx_csum,
+	.get_sg = ethtool_op_get_sg,
+	.set_sg = ethtool_op_set_sg,
+//	.get_tso = sxg_nic_get_tso,
+//	.set_tso = sxg_nic_set_tso,
+//	.self_test = sxg_nic_diag_test,
+	.get_strings = sxg_nic_get_strings,
+	.get_ethtool_stats = sxg_nic_get_ethtool_stats,
+	.get_sset_count = sxg_nic_get_sset_count,
+	.get_rx_csum = sxg_nic_get_rx_csum,
+	.set_rx_csum = sxg_nic_set_rx_csum,
+//	.get_coalesce = sxg_nic_get_intr_coalesce,
+//	.set_coalesce = sxg_nic_set_intr_coalesce,
+};
diff --git a/drivers/staging/sxg/sxg_os.h b/drivers/staging/sxg/sxg_os.h
index 6d3f23f..68e1a04 100644
--- a/drivers/staging/sxg/sxg_os.h
+++ b/drivers/staging/sxg/sxg_os.h
@@ -44,34 +44,34 @@
 #define FALSE	(0)
 #define TRUE	(1)
 
-struct LIST_ENTRY {
-	struct LIST_ENTRY *nle_flink;
-	struct LIST_ENTRY *nle_blink;
+struct list_entry {
+	struct list_entry *nle_flink;
+	struct list_entry *nle_blink;
 };
 
-#define InitializeListHead(l)                   \
+#define InitializeListHead(l)                   			\
         (l)->nle_flink = (l)->nle_blink = (l)
 
-#define IsListEmpty(h)                          \
+#define IsListEmpty(h)                          			\
         ((h)->nle_flink == (h))
 
-#define RemoveEntryList(e)                      \
-        do {                                    \
-                list_entry              *b;     \
-                list_entry              *f;     \
-                                                \
-                f = (e)->nle_flink;             \
-                b = (e)->nle_blink;             \
-                b->nle_flink = f;               \
-                f->nle_blink = b;               \
+#define RemoveEntryList(e)                      			\
+        do {                                    			\
+                list_entry              *b;     			\
+                list_entry              *f;     			\
+                                                			\
+                f = (e)->nle_flink;             			\
+                b = (e)->nle_blink;             			\
+                b->nle_flink = f;               			\
+                f->nle_blink = b;               			\
         } while (0)
 
 /* These two have to be inlined since they return things. */
 
-static __inline struct LIST_ENTRY *RemoveHeadList(struct LIST_ENTRY *l)
+static inline struct list_entry *RemoveHeadList(struct list_entry *l)
 {
-	struct LIST_ENTRY *f;
-	struct LIST_ENTRY *e;
+	struct list_entry *f;
+	struct list_entry *e;
 
 	e = l->nle_flink;
 	f = e->nle_flink;
@@ -81,10 +81,10 @@
 	return (e);
 }
 
-static __inline struct LIST_ENTRY *RemoveTailList(struct LIST_ENTRY *l)
+static inline struct list_entry *RemoveTailList(struct list_entry *l)
 {
-	struct LIST_ENTRY *b;
-	struct LIST_ENTRY *e;
+	struct list_entry *b;
+	struct list_entry *e;
 
 	e = l->nle_blink;
 	b = e->nle_blink;
@@ -94,54 +94,56 @@
 	return (e);
 }
 
-#define InsertTailList(l, e)                    \
-        do {                                    \
-                struct LIST_ENTRY       *b;     \
-                                                \
-                b = (l)->nle_blink;             \
-                (e)->nle_flink = (l);           \
-                (e)->nle_blink = b;             \
-                b->nle_flink = (e);             \
-                (l)->nle_blink = (e);           \
+#define InsertTailList(l, e)                    			\
+        do {                                    			\
+                struct list_entry       *b;     			\
+                                                			\
+                b = (l)->nle_blink;             			\
+                (e)->nle_flink = (l);           			\
+                (e)->nle_blink = b;             			\
+                b->nle_flink = (e);             			\
+                (l)->nle_blink = (e);           			\
         } while (0)
 
-#define InsertHeadList(l, e)                    \
-        do {                                    \
-                struct LIST_ENTRY       *f;     \
-                                                \
-                f = (l)->nle_flink;             \
-                (e)->nle_flink = f;             \
-                (e)->nle_blink = l;             \
-                f->nle_blink = (e);             \
-                (l)->nle_flink = (e);           \
+#define InsertHeadList(l, e)                    			\
+        do {                                    			\
+                struct list_entry       *f;     			\
+                                                			\
+                f = (l)->nle_flink;             			\
+                (e)->nle_flink = f;             			\
+                (e)->nle_blink = l;             			\
+                f->nle_blink = (e);             			\
+                (l)->nle_flink = (e);           			\
         } while (0)
 
 #define ATK_DEBUG  1
 
 #if ATK_DEBUG
-#define SLIC_TIMESTAMP(value) {                                             \
-        struct timeval  timev;                                              \
-        do_gettimeofday(&timev);                                            \
-        value = timev.tv_sec*1000000 + timev.tv_usec;                       \
+#define SLIC_TIMESTAMP(value) {                                       	\
+        struct timeval  timev;                                         	\
+        do_gettimeofday(&timev);                                       	\
+        value = timev.tv_sec*1000000 + timev.tv_usec;                  	\
 }
 #else
 #define SLIC_TIMESTAMP(value)
 #endif
 
-/******************  SXG DEFINES  *****************************************/
+/* SXG DEFINES */
 
 #ifdef  ATKDBG
-#define SXG_TIMESTAMP(value) {                                             \
-        struct timeval  timev;                                              \
-        do_gettimeofday(&timev);                                            \
-        value = timev.tv_sec*1000000 + timev.tv_usec;                       \
+#define SXG_TIMESTAMP(value) {                                         	\
+        struct timeval  timev;                                         	\
+        do_gettimeofday(&timev);                                       	\
+        value = timev.tv_sec*1000000 + timev.tv_usec;                  	\
 }
 #else
 #define SXG_TIMESTAMP(value)
 #endif
 
-#define WRITE_REG(reg,value,flush)                  sxg_reg32_write((&reg), (value), (flush))
-#define WRITE_REG64(a,reg,value,cpu)                sxg_reg64_write((a),(&reg),(value),(cpu))
+#define WRITE_REG(reg,value,flush)					\
+				sxg_reg32_write((&reg), (value), (flush))
+#define WRITE_REG64(a,reg,value,cpu)					\
+				sxg_reg64_write((a),(&reg),(value),(cpu))
 #define READ_REG(reg,value)   (value) = readl((void __iomem *)(&reg))
 
 #endif /* _SLIC_OS_SPECIFIC_H_  */
diff --git a/drivers/staging/sxg/sxgdbg.h b/drivers/staging/sxg/sxgdbg.h
index bb58ddf..e613a97 100644
--- a/drivers/staging/sxg/sxgdbg.h
+++ b/drivers/staging/sxg/sxgdbg.h
@@ -44,22 +44,23 @@
 #define _SXG_DEBUG_H_
 
 #define ATKDBG  1
-#define ATK_TRACE_ENABLED 1
+#define ATK_TRACE_ENABLED 0
 
-#define DBG_ERROR(n, args...)	printk(KERN_EMERG n, ##args)
+#define DBG_ERROR(n, args...)	printk(KERN_WARNING n, ##args)
 
 #ifdef ASSERT
 #undef ASSERT
 #endif
 
+#define SXG_ASSERT_ENABLED
 #ifdef SXG_ASSERT_ENABLED
 #ifndef ASSERT
-#define ASSERT(a)                                                                 \
-    {                                                                             \
-        if (!(a)) {                                                               \
-            DBG_ERROR("ASSERT() Failure: file %s, function %s  line %d\n",\
-                __FILE__, __func__, __LINE__);                                \
-        }                                                                         \
+#define ASSERT(a)                                                          \
+    {                                                                      \
+        if (!(a)) {                                                        \
+            DBG_ERROR("ASSERT() Failure: file %s, function %s  line %d\n", \
+                __FILE__, __func__, __LINE__);                             \
+        }                                                                  \
     }
 #endif
 #else
@@ -78,7 +79,7 @@
 extern ulong ATKTimerDiv;
 
 /*
- * trace_entry_t -
+ * trace_entry -
  *
  * This structure defines an entry in the trace buffer.  The
  * first few fields mean the same from entry to entry, while
@@ -86,34 +87,34 @@
  * needs of the trace entry.  Typically they are function call
  * parameters.
  */
-struct trace_entry_t {
-        char      name[8];        /* 8 character name - like 's'i'm'b'a'r'c'v' */
-        u32   time;           /* Current clock tic */
-        unsigned char     cpu;            /* Current CPU */
-        unsigned char     irql;           /* Current IRQL */
-        unsigned char     driver;         /* The driver which added the trace call */
-        unsigned char     pad2;           /* pad to 4 byte boundary - will probably get used */
-        u32   arg1;           /* Caller arg1 */
-        u32   arg2;           /* Caller arg2 */
-        u32   arg3;           /* Caller arg3 */
-        u32   arg4;           /* Caller arg4 */
+struct trace_entry {
+        char      	name[8];/* 8 character name - like 's'i'm'b'a'r'c'v' */
+        u32   		time;  /* Current clock tic */
+        unsigned char   cpu;   /* Current CPU */
+        unsigned char   irql;  /* Current IRQL */
+        unsigned char   driver;/* The driver which added the trace call */
+	/* pad to 4 byte boundary - will probably get used */
+        unsigned char   pad2;
+        u32		arg1;           /* Caller arg1 */
+        u32		arg2;           /* Caller arg2 */
+        u32		arg3;           /* Caller arg3 */
+        u32		arg4;           /* Caller arg4 */
 };
 
-/*
- * Driver types for driver field in trace_entry_t
- */
+/* Driver types for driver field in struct trace_entry */
 #define TRACE_SXG             1
 #define TRACE_VPCI            2
 #define TRACE_SLIC            3
 
 #define TRACE_ENTRIES   1024
 
-struct sxg_trace_buffer_t {
-        unsigned int                    size;                  /* aid for windbg extension */
-        unsigned int                    in;                    /* Where to add */
-        unsigned int                    level;                 /* Current Trace level */
-	spinlock_t	lock;                  /* For MP tracing */
-        struct trace_entry_t           entries[TRACE_ENTRIES];/* The circular buffer */
+struct sxg_trace_buffer {
+	/* aid for windbg extension */
+	unsigned int            size;
+	unsigned int            in;                    /* Where to add */
+	unsigned int            level;                 /* Current Trace level */
+	spinlock_t		lock;                  /* For MP tracing */
+	struct trace_entry	entries[TRACE_ENTRIES];/* The circular buffer */
 };
 
 /*
@@ -128,15 +129,11 @@
 #define TRACE_NOISY             10  /* Everything in the world */
 
 
-/**********************************************************************
- *
- * The macros themselves -
- *
- *********************************************************************/
+/* The macros themselves */
 #if ATK_TRACE_ENABLED
 #define SXG_TRACE_INIT(buffer, tlevel)				\
 {								\
-	memset((buffer), 0, sizeof(struct sxg_trace_buffer_t));	\
+	memset((buffer), 0, sizeof(struct sxg_trace_buffer));	\
 	(buffer)->level = (tlevel);				\
 	(buffer)->size = TRACE_ENTRIES;				\
 	spin_lock_init(&(buffer)->lock);			\
@@ -145,40 +142,38 @@
 #define SXG_TRACE_INIT(buffer, tlevel)
 #endif
 
-/*
- * The trace macro.  This is active only if ATK_TRACE_ENABLED is set.
- */
+/*The trace macro.  This is active only if ATK_TRACE_ENABLED is set. */
 #if ATK_TRACE_ENABLED
 #define SXG_TRACE(tdriver, buffer, tlevel, tname, a1, a2, a3, a4) {        \
-        if ((buffer) && ((buffer)->level >= (tlevel))) {                      \
-                unsigned int            trace_irql = 0;    /* ?????? FIX THIS  */    \
-                unsigned int            trace_len;                                   \
-                struct trace_entry_t	*trace_entry;				\
-                struct timeval  timev;                                       \
-                                                                             \
-                spin_lock(&(buffer)->lock);                       \
-                trace_entry = &(buffer)->entries[(buffer)->in];              \
-                do_gettimeofday(&timev);                                     \
-                                                                             \
-                memset(trace_entry->name, 0, 8);                             \
-                trace_len = strlen(tname);                                   \
-                trace_len = trace_len > 8 ? 8 : trace_len;                   \
-                memcpy(trace_entry->name, (tname), trace_len);               \
-                trace_entry->time = timev.tv_usec;                           \
-                trace_entry->cpu = (unsigned char)(smp_processor_id() & 0xFF);       \
-                trace_entry->driver = (tdriver);                             \
-                trace_entry->irql = trace_irql;                              \
-                trace_entry->arg1 = (ulong)(a1);                             \
-                trace_entry->arg2 = (ulong)(a2);                             \
-                trace_entry->arg3 = (ulong)(a3);                             \
-                trace_entry->arg4 = (ulong)(a4);                             \
-                                                                             \
-                (buffer)->in++;                                              \
-                if ((buffer)->in == TRACE_ENTRIES)                           \
-                        (buffer)->in = 0;                                    \
-                                                                             \
-                spin_unlock(&(buffer)->lock);                       \
-        }                                                                    \
+        if ((buffer) && ((buffer)->level >= (tlevel))) {                   \
+                unsigned int            trace_irql = 0;/* ?????? FIX THIS */\
+                unsigned int            trace_len;                          \
+                struct trace_entry	*trace_entry;			    \
+                struct timeval  timev;                                      \
+		if(spin_trylock(&(buffer)->lock))	{		     \
+	                trace_entry = &(buffer)->entries[(buffer)->in];      \
+        	        do_gettimeofday(&timev);                             \
+                	                                                     \
+	                memset(trace_entry->name, 0, 8);                     \
+        	        trace_len = strlen(tname);                           \
+	                trace_len = trace_len > 8 ? 8 : trace_len;           \
+        	        memcpy(trace_entry->name, (tname), trace_len);       \
+	                trace_entry->time = timev.tv_usec;                   \
+			trace_entry->cpu = (unsigned char)(smp_processor_id() & 0xFF);\
+	                trace_entry->driver = (tdriver);                     \
+        	        trace_entry->irql = trace_irql;                      \
+	                trace_entry->arg1 = (ulong)(a1);                     \
+        	        trace_entry->arg2 = (ulong)(a2);                     \
+	                trace_entry->arg3 = (ulong)(a3);                     \
+        	        trace_entry->arg4 = (ulong)(a4);                     \
+	                                                                     \
+        	        (buffer)->in++;                                      \
+                	if ((buffer)->in == TRACE_ENTRIES)                   \
+	                        (buffer)->in = 0;                            \
+        	                                                             \
+			spin_unlock(&(buffer)->lock);                        \
+ 	       	}                                                            \
+	}								     \
 }
 #else
 #define SXG_TRACE(tdriver, buffer, tlevel, tname, a1, a2, a3, a4)
diff --git a/drivers/staging/sxg/sxghif.h b/drivers/staging/sxg/sxghif.h
index a4e9468..e190d6a 100644
--- a/drivers/staging/sxg/sxghif.h
+++ b/drivers/staging/sxg/sxghif.h
@@ -1,4 +1,4 @@
-/*
+/*******************************************************************
  * Copyright © 1997-2007 Alacritech, Inc. All rights reserved
  *
  * $Id: sxghif.h,v 1.5 2008/07/24 19:18:22 chris Exp $
@@ -7,129 +7,134 @@
  *
  * This file contains structures and definitions for the
  * Alacritech Sahara host interface
- */
+ ******************************************************************/
 
-/*******************************************************************************
- * UCODE Registers
- *******************************************************************************/
-struct SXG_UCODE_REGS {
-	// Address 0 - 0x3F = Command codes 0-15 for TCB 0.  Excode 0
-	u32 Icr;		// Code = 0 (extended), ExCode = 0 - Int control
-	u32 RsvdReg1;		// Code = 1 - TOE -NA
-	u32 RsvdReg2;		// Code = 2 - TOE -NA
-	u32 RsvdReg3;		// Code = 3 - TOE -NA
-	u32 RsvdReg4;		// Code = 4 - TOE -NA
-	u32 RsvdReg5;		// Code = 5 - TOE -NA
-	u32 CardUp;		// Code = 6 - Microcode initialized when 1
-	u32 RsvdReg7;		// Code = 7 - TOE -NA
-	u32 CodeNotUsed[8];	// Codes 8-15 not used.  ExCode = 0
-	// This brings us to ExCode 1 at address 0x40 = Interrupt status pointer
-	u32 Isp;		// Code = 0 (extended), ExCode = 1
-	u32 PadEx1[15];		// Codes 1-15 not used with extended codes
-	// ExCode 2 = Interrupt Status Register
-	u32 Isr;		// Code = 0 (extended), ExCode = 2
+#define DBG				1
+
+/* UCODE Registers */
+struct sxg_ucode_regs {
+	/* Address 0 - 0x3F = Command codes 0-15 for TCB 0.  Excode 0 */
+	u32	Icr;		/* Code = 0 (extended), ExCode = 0 - Int control */
+	u32	RsvdReg1;	/* Code = 1 - TOE -NA */
+	u32	RsvdReg2;	/* Code = 2 - TOE -NA */
+	u32	RsvdReg3;	/* Code = 3 - TOE -NA */
+	u32	RsvdReg4;	/* Code = 4 - TOE -NA */
+	u32	RsvdReg5;	/* Code = 5 - TOE -NA */
+	u32	CardUp;		/* Code = 6 - Microcode initialized when 1 */
+	u32	RsvdReg7;	/* Code = 7 - TOE -NA */
+	u32	ConfigStat;     /* Code = 8 - Configuration data load status */
+	u32  	RsvdReg9;	/* Code = 9 - TOE -NA */
+	u32	CodeNotUsed[6];	/* Codes 10-15 not used.  ExCode = 0 */
+	/* This brings us to ExCode 1 at address 0x40 = Interrupt status pointer */
+	u32	Isp;		/* Code = 0 (extended), ExCode = 1 */
+	u32	PadEx1[15];	/* Codes 1-15 not used with extended codes */
+	/* ExCode 2 = Interrupt Status Register */
+	u32	Isr;		/* Code = 0 (extended), ExCode = 2 */
 	u32 PadEx2[15];
-	// ExCode 3 = Event base register.  Location of event rings
-	u32 EventBase;		// Code = 0 (extended), ExCode = 3
+	/* ExCode 3 = Event base register.  Location of event rings */
+	u32	EventBase;	/* Code = 0 (extended), ExCode = 3 */
 	u32 PadEx3[15];
-	// ExCode 4 = Event ring size
-	u32 EventSize;		// Code = 0 (extended), ExCode = 4
+	/* ExCode 4 = Event ring size */
+	u32	EventSize;	/* Code = 0 (extended), ExCode = 4 */
 	u32 PadEx4[15];
-	// ExCode 5 = TCB Buffers base address
-	u32 TcbBase;		// Code = 0 (extended), ExCode = 5
+	/* ExCode 5 = TCB Buffers base address */
+	u32	TcbBase;	/* Code = 0 (extended), ExCode = 5 */
 	u32 PadEx5[15];
-	// ExCode 6 = TCB Composite Buffers base address
-	u32 TcbCompBase;	// Code = 0 (extended), ExCode = 6
+	/* ExCode 6 = TCB Composite Buffers base address */
+	u32	TcbCompBase;	/* Code = 0 (extended), ExCode = 6 */
 	u32 PadEx6[15];
-	// ExCode 7 = Transmit ring base address
-	u32 XmtBase;		// Code = 0 (extended), ExCode = 7
+	/* ExCode 7 = Transmit ring base address */
+	u32	XmtBase;	/* Code = 0 (extended), ExCode = 7 */
 	u32 PadEx7[15];
-	// ExCode 8 = Transmit ring size
-	u32 XmtSize;		// Code = 0 (extended), ExCode = 8
+	/* ExCode 8 = Transmit ring size */
+	u32	XmtSize;	/* Code = 0 (extended), ExCode = 8 */
 	u32 PadEx8[15];
-	// ExCode 9 = Receive ring base address
-	u32 RcvBase;		// Code = 0 (extended), ExCode = 9
+	/* ExCode 9 = Receive ring base address */
+	u32	RcvBase;	/* Code = 0 (extended), ExCode = 9 */
 	u32 PadEx9[15];
-	// ExCode 10 = Receive ring size
-	u32 RcvSize;		// Code = 0 (extended), ExCode = 10
+	/* ExCode 10 = Receive ring size */
+	u32	RcvSize;	/* Code = 0 (extended), ExCode = 10 */
 	u32 PadEx10[15];
-	// ExCode 11 = Read EEPROM Config
-	u32 Config;		// Code = 0 (extended), ExCode = 11
+	/* ExCode 11 = Read EEPROM/Flash Config */
+	u32	Config;		/* Code = 0 (extended), ExCode = 11 */
 	u32 PadEx11[15];
-	// ExCode 12 = Multicast bits 31:0
-	u32 McastLow;		// Code = 0 (extended), ExCode = 12
+	/* ExCode 12 = Multicast bits 31:0 */
+	u32	McastLow;	/* Code = 0 (extended), ExCode = 12 */
 	u32 PadEx12[15];
-	// ExCode 13 = Multicast bits 63:32
-	u32 McastHigh;		// Code = 0 (extended), ExCode = 13
+	/* ExCode 13 = Multicast bits 63:32 */
+	u32	McastHigh;	/* Code = 0 (extended), ExCode = 13 */
 	u32 PadEx13[15];
-	// ExCode 14 = Ping
-	u32 Ping;		// Code = 0 (extended), ExCode = 14
+	/* ExCode 14 = Ping */
+	u32	Ping;		/* Code = 0 (extended), ExCode = 14 */
 	u32 PadEx14[15];
-	// ExCode 15 = Link MTU
-	u32 LinkMtu;		// Code = 0 (extended), ExCode = 15
+	/* ExCode 15 = Link MTU */
+	u32	LinkMtu;	/* Code = 0 (extended), ExCode = 15 */
 	u32 PadEx15[15];
-	// ExCode 16 = Download synchronization
-	u32 LoadSync;		// Code = 0 (extended), ExCode = 16
+	/* ExCode 16 = Download synchronization */
+	u32	LoadSync;	/* Code = 0 (extended), ExCode = 16 */
 	u32 PadEx16[15];
-	// ExCode 17 = Upper DRAM address bits on 32-bit systems
-	u32 Upper;		// Code = 0 (extended), ExCode = 17
+	/* ExCode 17 = Upper DRAM address bits on 32-bit systems */
+	u32	Upper;		/* Code = 0 (extended), ExCode = 17 */
 	u32 PadEx17[15];
-	// ExCode 18 = Slowpath Send Index Address
-	u32 SPSendIndex;	// Code = 0 (extended), ExCode = 18
+	/* ExCode 18 = Slowpath Send Index Address */
+	u32	SPSendIndex;	/* Code = 0 (extended), ExCode = 18 */
 	u32 PadEx18[15];
-	u32 RsvdXF;		// Code = 0 (extended), ExCode = 19
+	/* ExCode 19 = Get ucode statistics */
+	u32	GetUcodeStats;	/* Code = 0 (extended), ExCode = 19 */
 	u32 PadEx19[15];
-	// ExCode 20 = Aggregation
-	u32 Aggregation;	// Code = 0 (extended), ExCode = 20
+	/* ExCode 20 = Aggregation - See sxgmisc.c:SxgSetInterruptAggregation */
+	u32	Aggregation;	/* Code = 0 (extended), ExCode = 20 */
 	u32 PadEx20[15];
-	// ExCode 21 = Receive MDL push timer
-	u32 PushTicks;		// Code = 0 (extended), ExCode = 21
+	/* ExCode 21 = Receive MDL push timer */
+	u32	PushTicks;	/* Code = 0 (extended), ExCode = 21 */
 	u32 PadEx21[15];
-	// ExCode 22 = TOE NA
-	u32 AckFrequency;	// Code = 0 (extended), ExCode = 22
+	/* ExCode 22 = ACK Frequency */
+	u32	AckFrequency;	/* Code = 0 (extended), ExCode = 22 */
 	u32 PadEx22[15];
-	// ExCode 23 = TOE NA
+	/* ExCode 23 = TOE NA */
 	u32 RsvdReg23;
 	u32 PadEx23[15];
-	// ExCode 24 = TOE NA
+	/* ExCode 24 = TOE NA */
 	u32 RsvdReg24;
 	u32 PadEx24[15];
-	// ExCode 25 = TOE NA
-	u32 RsvdReg25;		// Code = 0 (extended), ExCode = 25
+	/* ExCode 25 = TOE NA */
+	u32	RsvdReg25;	/* Code = 0 (extended), ExCode = 25 */
 	u32 PadEx25[15];
-	// ExCode 26 = Receive checksum requirements
-	u32 ReceiveChecksum;	// Code = 0 (extended), ExCode = 26
+	/* ExCode 26 = Receive checksum requirements */
+	u32	ReceiveChecksum;	/* Code = 0 (extended), ExCode = 26 */
 	u32 PadEx26[15];
-	// ExCode 27 = RSS Requirements
-	u32 Rss;		// Code = 0 (extended), ExCode = 27
+	/* ExCode 27 = RSS Requirements */
+	u32	Rss;		/* Code = 0 (extended), ExCode = 27 */
 	u32 PadEx27[15];
-	// ExCode 28 = RSS Table
-	u32 RssTable;		// Code = 0 (extended), ExCode = 28
+	/* ExCode 28 = RSS Table */
+	u32	RssTable;	/* Code = 0 (extended), ExCode = 28 */
 	u32 PadEx28[15];
-	// ExCode 29 = Event ring release entries
-	u32 EventRelease;	// Code = 0 (extended), ExCode = 29
+	/* ExCode 29 = Event ring release entries */
+	u32	EventRelease;	/* Code = 0 (extended), ExCode = 29 */
 	u32 PadEx29[15];
-	// ExCode 30 = Number of receive bufferlist commands on ring 0
-	u32 RcvCmd;		// Code = 0 (extended), ExCode = 30
+	/* ExCode 30 = Number of receive bufferlist commands on ring 0 */
+	u32	RcvCmd;		/* Code = 0 (extended), ExCode = 30 */
 	u32 PadEx30[15];
-	// ExCode 31 = slowpath transmit command - Data[31:0] = 1
-	u32 XmtCmd;		// Code = 0 (extended), ExCode = 31
+	/* ExCode 31 = slowpath transmit command - Data[31:0] = 1 */
+	u32	XmtCmd;		/* Code = 0 (extended), ExCode = 31 */
 	u32 PadEx31[15];
-	// ExCode 32 = Dump command
-	u32 DumpCmd;		// Code = 0 (extended), ExCode = 32
+	/* ExCode 32 = Dump command */
+	u32	DumpCmd;	/* Code = 0 (extended), ExCode = 32 */
 	u32 PadEx32[15];
-	// ExCode 33 = Debug command
-	u32 DebugCmd;		// Code = 0 (extended), ExCode = 33
+	/* ExCode 33 = Debug command */
+	u32	DebugCmd;	/* Code = 0 (extended), ExCode = 33 */
 	u32 PadEx33[15];
-	// There are 128 possible extended commands - each of account for 16
-	// words (including the non-relevent base command codes 1-15).
-	// Pad for the remainder of these here to bring us to the next CPU
-	// base.  As extended codes are added, reduce the first array value in
-	// the following field
-	u32 PadToNextCpu[94][16];	// 94 = 128 - 34 (34 = Excodes 0 - 33)
+	/*
+	 * There are 128 possible extended commands - each of account for 16
+	 * words (including the non-relevent base command codes 1-15).
+	 * Pad for the remainder of these here to bring us to the next CPU
+	 * base.  As extended codes are added, reduce the first array value in
+	 * the following field
+	 */
+	u32 PadToNextCpu[94][16];	/* 94 = 128 - 34 (34 = Excodes 0 - 33)*/
 };
 
-// Interrupt control register (0) values
+/* Interrupt control register (0) values */
 #define SXG_ICR_DISABLE					0x00000000
 #define SXG_ICR_ENABLE					0x00000001
 #define SXG_ICR_MASK					0x00000002
@@ -139,47 +144,65 @@
 	((((_MessageId) << SXG_ICR_MSGID_SHIFT) &	\
 	  SXG_ICR_MSGID_MASK) | (_Data))
 
-// The Microcode supports up to 16 RSS queues
-#define SXG_MAX_RSS				16
-#define SXG_MAX_RSS_TABLE_SIZE	256	// 256-byte max
+#define SXG_MIN_AGG_DEFAULT	0x0010	/* Minimum aggregation default */
+#define SXG_MAX_AGG_DEFAULT	0x0040	/* Maximum aggregation default */
+#define SXG_MAX_AGG_SHIFT	16	/* Maximum in top 16 bits of register */
+/* Disable interrupt aggregation on xmt */
+#define SXG_AGG_XMT_DISABLE	0x80000000
 
-#define SXG_RSS_TCP6				0x00000001	// RSS TCP over IPv6
-#define SXG_RSS_TCP4				0x00000002	// RSS TCP over IPv4
-#define SXG_RSS_LEGACY				0x00000004	// Line-base interrupts
-#define SXG_RSS_TABLE_SIZE			0x0000FF00	// Table size mask
+/* The Microcode supports up to 16 RSS queues (RevB) */
+#define SXG_MAX_RSS			16
+#define SXG_MAX_RSS_REVA		8
+
+#define SXG_MAX_RSS_TABLE_SIZE	256		/* 256-byte max */
+
+#define SXG_RSS_REVA_TCP6	0x00000001	/* RSS TCP over IPv6 */
+#define SXG_RSS_REVA_TCP4	0x00000002	/* RSS TCP over IPv4 */
+#define SXG_RSS_IP		0x00000001	/* RSS TCP over IPv6 */
+#define SXG_RSS_TCP		0x00000002	/* RSS TCP over IPv4 */
+#define SXG_RSS_LEGACY		0x00000004	/* Line-base interrupts */
+#define SXG_RSS_TABLE_SIZE	0x0000FF00	/* Table size mask */
+
 #define SXG_RSS_TABLE_SHIFT			8
-#define	SXG_RSS_BASE_CPU			0x00FF0000	// Base CPU (not used)
+#define	SXG_RSS_BASE_CPU	0x00FF0000	/* Base CPU (not used) */
 #define SXG_RSS_BASE_SHIFT			16
 
-#define SXG_RCV_IP_CSUM_ENABLED		0x00000001	// ExCode 26 (ReceiveChecksum)
-#define SXG_RCV_TCP_CSUM_ENABLED	0x00000002	// ExCode 26 (ReceiveChecksum)
+#define SXG_RCV_IP_CSUM_ENABLED		0x00000001	/* ExCode 26 (ReceiveChecksum) */
+#define SXG_RCV_TCP_CSUM_ENABLED	0x00000002	/* ExCode 26 (ReceiveChecksum) */
 
 #define SXG_XMT_CPUID_SHIFT			16
 
-#if VPCI
-#define SXG_CHECK_FOR_HANG_TIME		3000
-#else
+/*
+ * Status returned by ucode in the ConfigStat reg (see above) when attempted
+ * to load configuration data from the EEPROM/Flash.
+ */
+#define	SXG_CFG_TIMEOUT		1	/* init value - timeout if unchanged */
+#define	SXG_CFG_LOAD_EEPROM	2	/* config data loaded from EEPROM */
+#define	SXG_CFG_LOAD_FLASH	3	/* config data loaded from flash */
+#define	SXG_CFG_LOAD_INVALID	4	/* no valid config data found */
+#define	SXG_CFG_LOAD_ERROR	5	/* hardware error */
+
 #define SXG_CHECK_FOR_HANG_TIME		5
-#endif
 
 /*
  * TCB registers - This is really the same register memory area as UCODE_REGS
  * above, but defined differently.  Bits 17:06 of the address define the TCB,
  * which means each TCB area occupies 0x40 (64) bytes, or 16 u32S.  What really
  * is happening is that these registers occupy the "PadEx[15]" areas in the
- * SXG_UCODE_REGS definition above
+ * struct sxg_ucode_regs definition above
  */
-struct SXG_TCB_REGS {
-	u32 ExCode;		/* Extended codes - see SXG_UCODE_REGS */
-	u32 Xmt;		/* Code = 1 - # of Xmt descriptors added to ring */
-	u32 Rcv;		/* Code = 2 - # of Rcv descriptors added to ring */
-	u32 Rsvd1;		/* Code = 3 - TOE NA */
-	u32 Rsvd2;		/* Code = 4 - TOE NA */
-	u32 Rsvd3;		/* Code = 5 - TOE NA */
-	u32 Invalid;		/* Code = 6 - Reserved for "CardUp" see above */
-	u32 Rsvd4;		/* Code = 7 - TOE NA */
-	u32 Rsvd5;		/* Code = 8 - TOE NA */
-	u32 Pad[7];		/* Codes 8-15 - Not used. */
+struct sxg_tcb_regs {
+	u32 ExCode;	/* Extended codes - see SXG_UCODE_REGS */
+	u32 Xmt;	/* Code = 1 - # of Xmt descriptors added to ring */
+	u32 Rcv;	/* Code = 2 - # of Rcv descriptors added to ring */
+	u32 Rsvd1;	/* Code = 3 - TOE NA */
+	u32 Rsvd2;	/* Code = 4 - TOE NA */
+	u32 Rsvd3;	/* Code = 5 - TOE NA */
+	u32 Invalid1;	/* Code = 6 - Reserved for "CardUp" see above */
+	u32 Rsvd4;	/* Code = 7 - TOE NA */
+	u32 Invalid2;	/* Code = 8 - Reserved for "ConfigStat" see above */
+	u32 Rsvd5;	/* Code = 9 - TOE NA */
+	u32 Pad[6];	/* Codes 10-15 - Not used. */
 };
 
 /***************************************************************************
@@ -206,29 +229,26 @@
  *                                 ||---|-CpuId of crash
  *                                 |----/
  ***************************************************************************/
-#define SXG_ISR_ERR		0x80000000	// Error
-#define SXG_ISR_EVENT		0x40000000	// Event ring event
-#define SXG_ISR_NONE1		0x20000000	// Not used
-#define SXG_ISR_UPC		0x10000000	// Dump/debug command complete
-#define SXG_ISR_LINK		0x08000000	// Link event
-#define SXG_ISR_PDQF		0x04000000	// Processed data queue full
-#define SXG_ISR_RMISS		0x02000000	// Drop - no host buf
-#define SXG_ISR_BREAK		0x01000000	// Breakpoint hit
-#define SXG_ISR_PING		0x00800000	// Heartbeat response
-#define SXG_ISR_DEAD		0x00400000	// Card crash
-#define SXG_ISR_ERFULL		0x00200000	// Event ring full
-#define SXG_ISR_XDROP		0x00100000	// XMT Drop - no DRAM bufs or XMT err
-#define SXG_ISR_SPSEND		0x00080000	// Slow send complete
-#define SXG_ISR_CPU		0x00070000	// Dead CPU mask
-#define SXG_ISR_CPU_SHIFT		16	// Dead CPU shift
-#define SXG_ISR_CRASH		0x0000FFFF	// Crash address mask
+#define SXG_ISR_ERR		0x80000000	/* Error */
+#define SXG_ISR_EVENT		0x40000000	/* Event ring event */
+#define SXG_ISR_NONE1		0x20000000	/* Not used */
+#define SXG_ISR_UPC		0x10000000	/* Dump/debug command complete*/
+#define SXG_ISR_LINK		0x08000000	/* Link event */
+#define SXG_ISR_PDQF		0x04000000	/* Processed data queue full */
+#define SXG_ISR_RMISS		0x02000000	/* Drop - no host buf */
+#define SXG_ISR_BREAK		0x01000000	/* Breakpoint hit */
+#define SXG_ISR_PING		0x00800000	/* Heartbeat response */
+#define SXG_ISR_DEAD		0x00400000	/* Card crash */
+#define SXG_ISR_ERFULL		0x00200000	/* Event ring full */
+#define SXG_ISR_XDROP		0x00100000	/* XMT Drop - no DRAM bufs or XMT err */
+#define SXG_ISR_SPSEND		0x00080000	/* Slow send complete */
+#define SXG_ISR_CPU		0x00070000	/* Dead CPU mask */
+#define SXG_ISR_CPU_SHIFT	16		/* Dead CPU shift */
+#define SXG_ISR_CRASH		0x0000FFFF	/* Crash address mask */
 
 /***************************************************************************
- *
  * Event Ring entry
  *
- ***************************************************************************/
-/*
  *  31                  15                 0
  *  .___________________.___________________.
  *  |<------------    Pad 0    ------------>|
@@ -270,196 +290,223 @@
  *    ||------- ISTCPIP
  *    |-------- SCERR
  *
- */
+ ************************************************************************/
 #pragma pack(push, 1)
-struct SXG_EVENT {
-	u32 Pad[1];		// not used
-	u32 SndUna;		// SndUna value
-	u32 Resid;		// receive MDL resid
+struct sxg_event {
+	u32			Pad[1];		/* not used */
+	u32			SndUna;		/* SndUna value */
+	u32			Resid;		/* receive MDL resid */
 	union {
-		void *HostHandle;	// Receive host handle
-		u32 Rsvd1;	// TOE NA
+		void *		HostHandle;	/* Receive host handle */
+		u32		Rsvd1;		/* TOE NA */
 		struct {
 			u32 NotUsed;
-			u32 Rsvd2;	// TOE NA
+			u32	Rsvd2;		/* TOE NA */
 		} Flush;
 	};
-	u32 Toeplitz;		// RSS Toeplitz hash
+	u32			Toeplitz;	/* RSS Toeplitz hash */
 	union {
-		ushort Rsvd3;	// TOE NA
-		ushort HdrOffset;	// Slowpath
+		ushort		Rsvd3;		/* TOE NA */
+		ushort		HdrOffset;	/* Slowpath */
 	};
-	ushort Length;		//
-	unsigned char Rsvd4;	// TOE NA
-	unsigned char Code;	// Event code
-	unsigned char CommandIndex;	// New ring index
-	unsigned char Status;	// Event status
+	ushort			Length;
+	unsigned char 	Rsvd4;		/* TOE NA */
+	unsigned char 	Code;		/* Event code */
+	unsigned char	CommandIndex;	/* New ring index */
+	unsigned char	Status;		/* Event status */
 };
 #pragma pack(pop)
 
-// Event code definitions
-#define EVENT_CODE_BUFFERS	0x01	// Receive buffer list command (ring 0)
-#define EVENT_CODE_SLOWRCV	0x02	// Slowpath receive
-#define EVENT_CODE_UNUSED	0x04	// Was slowpath commands complete
+/* Event code definitions */
+#define EVENT_CODE_BUFFERS	0x01	/* Receive buffer list command (ring 0) */
+#define EVENT_CODE_SLOWRCV	0x02	/* Slowpath receive */
+#define EVENT_CODE_UNUSED	0x04	/* Was slowpath commands complete */
 
-// Status values
-#define EVENT_STATUS_VALID	0x80	// Entry valid
+/* Status values */
+#define EVENT_STATUS_VALID	0x80	/* Entry valid */
 
-// Slowpath status
-#define EVENT_STATUS_ERROR	0x40	// Completed with error. Index in next byte
-#define EVENT_STATUS_TCPIP4	0x20	// TCPIPv4 frame
-#define EVENT_STATUS_TCPBAD	0x10	// Bad TCP checksum
-#define EVENT_STATUS_IPBAD	0x08	// Bad IP checksum
-#define EVENT_STATUS_RCVERR	0x04	// Slowpath receive error
-#define EVENT_STATUS_IPONLY	0x02	// IP frame
-#define EVENT_STATUS_TCPIP6	0x01	// TCPIPv6 frame
-#define EVENT_STATUS_TCPIP	0x21	// Combination of v4 and v6
+/* Slowpath status */
+#define EVENT_STATUS_ERROR	0x40	/* Completed with error. Index in next byte */
+#define EVENT_STATUS_TCPIP4	0x20	/* TCPIPv4 frame */
+#define EVENT_STATUS_TCPBAD	0x10	/* Bad TCP checksum */
+#define EVENT_STATUS_IPBAD	0x08	/* Bad IP checksum */
+#define EVENT_STATUS_RCVERR	0x04	/* Slowpath receive error */
+#define EVENT_STATUS_IPONLY	0x02	/* IP frame */
+#define EVENT_STATUS_TCPIP6	0x01	/* TCPIPv6 frame */
+#define EVENT_STATUS_TCPIP	0x21	/* Combination of v4 and v6 */
 
-// Event ring
-// Size must be power of 2, between 128 and 16k
-#define EVENT_RING_SIZE		4096	// ??
-#define EVENT_RING_BATCH	16	// Hand entries back 16 at a time.
-#define EVENT_BATCH_LIMIT	256	// Stop processing events after 256 (16 * 16)
+/*
+ * Event ring
+ * Size must be power of 2, between 128 and 16k
+ */
+#define EVENT_RING_SIZE		4096
+#define EVENT_RING_BATCH	16	/* Hand entries back 16 at a time. */
+/* Stop processing events after 4096 (256 * 16) */
+#define EVENT_BATCH_LIMIT	256
 
-struct SXG_EVENT_RING {
-	struct SXG_EVENT Ring[EVENT_RING_SIZE];
+struct sxg_event_ring {
+	struct sxg_event Ring[EVENT_RING_SIZE];
 };
 
-/***************************************************************************
- *
- * TCB Buffers
- *
- ***************************************************************************/
-// Maximum number of TCBS supported by hardware/microcode
+/* TCB Buffers */
+/* Maximum number of TCBS supported by hardware/microcode */
 #define SXG_MAX_TCB		4096
-// Minimum TCBs before we fail initialization
+/* Minimum TCBs before we fail initialization */
 #define SXG_MIN_TCB		512
-// TCB Hash
-// The bucket is determined by bits 11:4 of the toeplitz if we support 4k
-// offloaded connections, 10:4 if we support 2k and so on.
+/*
+ * TCB Hash
+ * The bucket is determined by bits 11:4 of the toeplitz if we support 4k
+ * offloaded connections, 10:4 if we support 2k and so on.
+ */
 #define SXG_TCB_BUCKET_SHIFT	4
-#define SXG_TCB_PER_BUCKET		16
-#define SXG_TCB_BUCKET_MASK		0xFF0	// Bucket portion of TCB ID
-#define SXG_TCB_ELEMENT_MASK	0x00F	// Element within bucket
-#define SXG_TCB_BUCKETS			256	// 256 * 16 = 4k
+#define SXG_TCB_PER_BUCKET	16
+#define SXG_TCB_BUCKET_MASK	0xFF0	/* Bucket portion of TCB ID */
+#define SXG_TCB_ELEMENT_MASK	0x00F	/* Element within bucket */
+#define SXG_TCB_BUCKETS		256		/* 256 * 16 = 4k */
 
-#define SXG_TCB_BUFFER_SIZE	512	// ASSERT format is correct
+#define SXG_TCB_BUFFER_SIZE	512	/* ASSERT format is correct */
 
-#define SXG_TCB_RCVQ_SIZE		736
+#define SXG_TCB_RCVQ_SIZE	736
 
 #define SXG_TCB_COMPOSITE_BUFFER_SIZE	1024
 
-#define SXG_LOCATE_TCP_FRAME_HDR(_TcpObject, _IPv6)							\
-	(((_TcpObject)->VlanId) ?												\
-	 ((_IPv6) ?		/* Vlan frame header = yes */							\
-	  &(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp6.SxgTcp			:	\
-	  &(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp.SxgTcp)			: 	\
-	 ((_IPv6) ?		/* Vlan frame header = No */							\
-	  &(_TcpObject)->CompBuffer->Frame.NoVlan.TcpIp6.SxgTcp				: 	\
+#define SXG_LOCATE_TCP_FRAME_HDR(_TcpObject, _IPv6)			\
+	(((_TcpObject)->VlanId) ?					\
+	 ((_IPv6) ?		/* Vlan frame header = yes */		\
+	  &(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp6.SxgTcp:	\
+	  &(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp.SxgTcp): 	\
+	 ((_IPv6) ?		/* Vlan frame header = No */		\
+	  &(_TcpObject)->CompBuffer->Frame.NoVlan.TcpIp6.SxgTcp	: 	\
 	  &(_TcpObject)->CompBuffer->Frame.NoVlan.TcpIp.SxgTcp))
 
-#define SXG_LOCATE_IP_FRAME_HDR(_TcpObject)									\
-	(_TcpObject)->VlanId ?													\
-	&(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp.Ip				: 		\
+#define SXG_LOCATE_IP_FRAME_HDR(_TcpObject)				\
+	(_TcpObject)->VlanId ?						\
+	&(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp.Ip: 		\
 	&(_TcpObject)->CompBuffer->Frame.NoVlan.TcpIp.Ip
 
-#define SXG_LOCATE_IP6_FRAME_HDR(_TcpObject)								\
-	(_TcpObject)->VlanId ?													\
-	&(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp6.Ip				:		\
+#define SXG_LOCATE_IP6_FRAME_HDR(TcpObject)				\
+	(_TcpObject)->VlanId ?						\
+	&(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp6.Ip:		\
 	&(_TcpObject)->CompBuffer->Frame.NoVlan.TcpIp6.Ip
 
 #if DBG
-// Horrible kludge to distinguish dumb-nic, slowpath, and
-// fastpath traffic.  Decrement the HopLimit by one
-// for slowpath, two for fastpath.  This assumes the limit is measurably
-// greater than two, which I think is reasonable.
-// Obviously this is DBG only.  Maybe remove later, or #if 0 so we
-// can set it when needed
-#define SXG_DBG_HOP_LIMIT(_TcpObject, _FastPath) {								\
-	PIPV6_HDR		_Ip6FrameHdr;												\
-	if((_TcpObject)->IPv6) {													\
-		_Ip6FrameHdr = SXG_LOCATE_IP6_FRAME_HDR((_TcpObject));					\
-		if(_FastPath) {															\
-			_Ip6FrameHdr->HopLimit = (_TcpObject)->Cached.TtlOrHopLimit - 2;	\
-		} else {																\
-			_Ip6FrameHdr->HopLimit = (_TcpObject)->Cached.TtlOrHopLimit - 1;	\
-		}																		\
-	}																			\
+/*
+ * Horrible kludge to distinguish dumb-nic, slowpath, and
+ * fastpath traffic.  Decrement the HopLimit by one
+ * for slowpath, two for fastpath.  This assumes the limit is measurably
+ * greater than two, which I think is reasonable.
+ * Obviously this is DBG only.  Maybe remove later, or #if 0 so we
+ * can set it when needed
+ */
+#define SXG_DBG_HOP_LIMIT(_TcpObject, _FastPath) {			\
+	PIPV6_HDR		_Ip6FrameHdr;				\
+	if ((_TcpObject)->IPv6) {					\
+		_Ip6FrameHdr = SXG_LOCATE_IP6_FRAME_HDR((_TcpObject));	\
+		if (_FastPath) {					\
+			_Ip6FrameHdr->HopLimit = 			\
+				(_TcpObject)->Cached.TtlOrHopLimit - 2;	\
+		} else {						\
+			_Ip6FrameHdr->HopLimit = 			\
+				(_TcpObject)->Cached.TtlOrHopLimit - 1;	\
+		}							\
+	}								\
 }
 #else
-// Do nothing with free build
+/* Do nothing with free build */
 #define SXG_DBG_HOP_LIMIT(_TcpObject, _FastPath)
 #endif
 
-/***************************************************************************
- * Receive and transmit rings
- ***************************************************************************/
+/* Receive and transmit rings */
 #define SXG_MAX_RING_SIZE	256
-#define SXG_XMT_RING_SIZE	128	// Start with 128
-#define SXG_RCV_RING_SIZE	128	// Start with 128
+#define SXG_XMT_RING_SIZE	128		/* Start with 128 */
+#define SXG_RCV_RING_SIZE	128		/* Start with 128 */
 #define SXG_MAX_ENTRIES     4096
+#define SXG_JUMBO_RCV_RING_SIZE       32
 
-// Structure and macros to manage a ring
-struct SXG_RING_INFO {
-	unsigned char Head;	// Where we add entries - Note unsigned char:RING_SIZE
-	unsigned char Tail;	// Where we pull off completed entries
-	ushort Size;		// Ring size - Must be multiple of 2
-	void *Context[SXG_MAX_RING_SIZE];	// Shadow ring
+/* Structure and macros to manage a ring */
+struct sxg_ring_info {
+	/* Where we add entries - Note unsigned char:RING_SIZE */
+	unsigned char Head;
+	unsigned char Tail;	/* Where we pull off completed entries */
+	ushort	Size;		/* Ring size - Must be multiple of 2 */
+	void *	Context[SXG_MAX_RING_SIZE];	/* Shadow ring */
 };
 
-#define SXG_INITIALIZE_RING(_ring, _size) {							\
-	(_ring).Head = 0;												\
-	(_ring).Tail = 0;												\
-	(_ring).Size = (_size);											\
+#define SXG_INITIALIZE_RING(_ring, _size) {				\
+	(_ring).Head = 0;						\
+	(_ring).Tail = 0;						\
+	(_ring).Size = (_size);						\
 }
-#define SXG_ADVANCE_INDEX(_index, _size) ((_index) = ((_index) + 1) & ((_size) - 1))
-#define SXG_PREVIOUS_INDEX(_index, _size) (((_index) - 1) &((_size) - 1))
+
+#define SXG_ADVANCE_INDEX(_index, _size) 				\
+			((_index) = ((_index) + 1) & ((_size) - 1))
+#define SXG_PREVIOUS_INDEX(_index, _size) 				\
+			(((_index) - 1) &((_size) - 1))
 #define SXG_RING_EMPTY(_ring) ((_ring)->Head == (_ring)->Tail)
-#define SXG_RING_FULL(_ring) ((((_ring)->Head + 1) & ((_ring)->Size - 1)) == (_ring)->Tail)
-#define SXG_RING_ADVANCE_HEAD(_ring) SXG_ADVANCE_INDEX((_ring)->Head, ((_ring)->Size))
-#define SXG_RING_RETREAT_HEAD(_ring) ((_ring)->Head =				\
-									  SXG_PREVIOUS_INDEX((_ring)->Head, (_ring)->Size))
-#define SXG_RING_ADVANCE_TAIL(_ring) {								\
-	ASSERT((_ring)->Tail != (_ring)->Head);							\
-	SXG_ADVANCE_INDEX((_ring)->Tail, ((_ring)->Size));				\
+#define SXG_RING_FULL(_ring) 						\
+		((((_ring)->Head + 1) & ((_ring)->Size - 1)) == (_ring)->Tail)
+#define SXG_RING_ADVANCE_HEAD(_ring) 					\
+		SXG_ADVANCE_INDEX((_ring)->Head, ((_ring)->Size))
+#define SXG_RING_RETREAT_HEAD(_ring) ((_ring)->Head =			\
+		SXG_PREVIOUS_INDEX((_ring)->Head, (_ring)->Size))
+#define SXG_RING_ADVANCE_TAIL(_ring) {					\
+	ASSERT((_ring)->Tail != (_ring)->Head);				\
+	SXG_ADVANCE_INDEX((_ring)->Tail, ((_ring)->Size));		\
 }
-// Set cmd to the next available ring entry, set the shadow context
-// entry and advance the ring.
-// The appropriate lock must be held when calling this macro
-#define SXG_GET_CMD(_ring, _ringinfo, _cmd, _context) {				\
-	if(SXG_RING_FULL(_ringinfo)) {									\
-		(_cmd) = NULL;												\
-	} else {														\
-		(_cmd) = &(_ring)->Descriptors[(_ringinfo)->Head];			\
+/*
+ * Set cmd to the next available ring entry, set the shadow context
+ * entry and advance the ring.
+ * The appropriate lock must be held when calling this macro
+ */
+#define SXG_GET_CMD(_ring, _ringinfo, _cmd, _context) {			\
+	if(SXG_RING_FULL(_ringinfo)) {					\
+		(_cmd) = NULL;						\
+	} else {							\
+		(_cmd) = &(_ring)->Descriptors[(_ringinfo)->Head];	\
 		(_ringinfo)->Context[(_ringinfo)->Head] = (void *)(_context);\
-		SXG_RING_ADVANCE_HEAD(_ringinfo);							\
-	}																\
+		SXG_RING_ADVANCE_HEAD(_ringinfo);			\
+	}								\
 }
 
-// Abort the previously allocated command by retreating the head.
-// NOTE - The appopriate lock MUST NOT BE DROPPED between the SXG_GET_CMD
-// and SXG_ABORT_CMD calls.
-#define SXG_ABORT_CMD(_ringinfo) {									\
-	ASSERT(!(SXG_RING_EMPTY(_ringinfo)));							\
-	SXG_RING_RETREAT_HEAD(_ringinfo);								\
-	(_ringinfo)->Context[(_ringinfo)->Head] = NULL;					\
+/*
+ * Abort the previously allocated command by retreating the head.
+ * NOTE - The appopriate lock MUST NOT BE DROPPED between the SXG_GET_CMD
+ * and SXG_ABORT_CMD calls.
+ */
+#define SXG_ABORT_CMD(_ringinfo) {					\
+	ASSERT(!(SXG_RING_EMPTY(_ringinfo)));				\
+	SXG_RING_RETREAT_HEAD(_ringinfo);				\
+	(_ringinfo)->Context[(_ringinfo)->Head] = NULL;			\
 }
 
-// For the given ring, return a pointer to the tail cmd and context,
-// clear the context and advance the tail
-#define SXG_RETURN_CMD(_ring, _ringinfo, _cmd, _context) {			\
-	(_cmd) = &(_ring)->Descriptors[(_ringinfo)->Tail];				\
+/*
+ * For the given ring, return a pointer to the tail cmd and context,
+ * clear the context and advance the tail
+ */
+#define SXG_RETURN_CMD(_ring, _ringinfo, _cmd, _context) {		\
+	(_cmd) = &(_ring)->Descriptors[(_ringinfo)->Tail];		\
 	(_context) = (_ringinfo)->Context[(_ringinfo)->Tail];       	\
-	(_ringinfo)->Context[(_ringinfo)->Tail] = NULL;					\
-	SXG_RING_ADVANCE_TAIL(_ringinfo);								\
+	(_ringinfo)->Context[(_ringinfo)->Tail] = NULL;			\
+	SXG_RING_ADVANCE_TAIL(_ringinfo);				\
 }
 
-/***************************************************************************
- *
+/*
+ * For a given ring find out how much the first pointer is ahead of
+ * the second pointer. "ahead" recognises the fact that the ring can wrap
+ */
+static inline int sxg_ring_get_forward_diff (struct sxg_ring_info *ringinfo,
+						int a, int b) {
+	if ((a < 0 || a > ringinfo->Size ) || (b < 0 || b > ringinfo->Size))
+		return -1;
+	if (a > b)	/* _a is lagging _b and _b has not wrapped around */
+		return (a - b);
+	else
+		return ((ringinfo->Size - (b - a)));
+}
+
+/***************************************************************
  * Host Command Buffer - commands to INIC via the Cmd Rings
  *
- ***************************************************************************/
-/*
  *  31                  15                 0
  *  .___________________.___________________.
  *  |<-------------- Sgl Low -------------->|
@@ -479,42 +526,43 @@
  *  |_________|_________|_________|_________|24		0x18
  *  |<----- LCnt ------>|<----- Flags ----->|
  *  |_________|_________|_________|_________|28		0x1c
- */
+ ****************************************************************/
 #pragma pack(push, 1)
-struct SXG_CMD {
-	dma_addr_t Sgl;		// Physical address of SGL
+struct sxg_cmd {
+	dma64_addr_t	Sgl;		/* Physical address of SGL */
 	union {
 		struct {
-			dma64_addr_t FirstSgeAddress;	// Address of first SGE
-			u32 FirstSgeLength;	// Length of first SGE
+			dma64_addr_t FirstSgeAddress; /* Address of first SGE */
+			u32 	     FirstSgeLength;  /* Length of first SGE */
 			union {
-				u32 Rsvd1;	// TOE NA
-				u32 SgeOffset;	// Slowpath - 2nd SGE offset
-				u32 Resid;	// MDL completion - clobbers update
+				u32  Rsvd1;	   /* TOE NA */
+				u32  SgeOffset; /* Slowpath - 2nd SGE offset */
+				/* MDL completion - clobbers update */
+				u32  Resid;
 			};
 			union {
-				u32 TotalLength;	// Total transfer length
-				u32 Mss;	// LSO MSS
+				u32  TotalLength; /* Total transfer length */
+				u32  Mss;	  /* LSO MSS */
 			};
 		} Buffer;
 	};
 	union {
 		struct {
-			unsigned char Flags:4;	// slowpath flags
-			unsigned char IpHl:4;	// Ip header length (>>2)
-			unsigned char MacLen;	// Mac header len
+			unsigned char Flags:4;	/* slowpath flags */
+			unsigned char IpHl:4;	/* Ip header length (>>2) */
+			unsigned char MacLen;	/* Mac header len */
 		} CsumFlags;
 		struct {
-			ushort Flags:4;	// slowpath flags
-			ushort TcpHdrOff:7;	// TCP
-			ushort MacLen:5;	// Mac header len
+			ushort	Flags:4;	/* slowpath flags */
+			ushort	TcpHdrOff:7;	/* TCP */
+			ushort	MacLen:5;	/* Mac header len */
 		} LsoFlags;
-		ushort Flags;	// flags
+		ushort		Flags;		/* flags */
 	};
 	union {
-		ushort SgEntries;	// SG entry count including first sge
+		ushort	SgEntries;	/* SG entry count including first sge */
 		struct {
-			unsigned char Status;	// Copied from event status
+			unsigned char Status;	/* Copied from event status */
 			unsigned char NotUsed;
 		} Status;
 	};
@@ -522,13 +570,13 @@
 #pragma pack(pop)
 
 #pragma pack(push, 1)
-struct VLAN_HDR {
+struct vlan_hdr {
 	ushort VlanTci;
 	ushort VlanTpid;
 };
 #pragma pack(pop)
 
-/*
+/********************************************************************
  * Slowpath Flags:
  *
  *
@@ -558,36 +606,36 @@
  *  |      LCnt         |MAC hlen |Hlen|Flgs|
  *  |___________________|____|____|____|____|
  *
- */
-// Slowpath CMD flags
-#define SXG_SLOWCMD_CSUM_IP			0x01	// Checksum IP
-#define SXG_SLOWCMD_CSUM_TCP		0x02	// Checksum TCP
-#define SXG_SLOWCMD_LSO				0x04	// Large segment send
+ *****************************************************************/
+/* Slowpath CMD flags */
+#define SXG_SLOWCMD_CSUM_IP		0x01	/* Checksum IP */
+#define SXG_SLOWCMD_CSUM_TCP		0x02	/* Checksum TCP */
+#define SXG_SLOWCMD_LSO			0x04	/* Large segment send */
 
-struct SXG_XMT_RING {
-	struct SXG_CMD Descriptors[SXG_XMT_RING_SIZE];
+struct sxg_xmt_ring {
+	struct sxg_cmd Descriptors[SXG_XMT_RING_SIZE];
 };
 
-struct SXG_RCV_RING {
-	struct SXG_CMD Descriptors[SXG_RCV_RING_SIZE];
+struct sxg_rcv_ring {
+	struct sxg_cmd Descriptors[SXG_RCV_RING_SIZE];
 };
 
-/***************************************************************************
+/*
  * Share memory buffer types - Used to identify asynchronous
  * shared memory allocation
- ***************************************************************************/
-enum SXG_BUFFER_TYPE {
-	SXG_BUFFER_TYPE_RCV,	// Receive buffer
-	SXG_BUFFER_TYPE_SGL	// SGL buffer
+ */
+enum sxg_buffer_type {
+	SXG_BUFFER_TYPE_RCV,		/* Receive buffer */
+	SXG_BUFFER_TYPE_SGL		/* SGL buffer */
 };
 
-// State for SXG buffers
+/* State for SXG buffers */
 #define SXG_BUFFER_FREE		0x01
 #define SXG_BUFFER_BUSY		0x02
 #define SXG_BUFFER_ONCARD	0x04
 #define SXG_BUFFER_UPSTREAM	0x08
 
-/***************************************************************************
+/*
  * Receive data buffers
  *
  * Receive data buffers are given to the Sahara card 128 at a time.
@@ -597,262 +645,370 @@
  * DMA data into, and a virtual address, which is given back
  * to the host in the "HostHandle" portion of an event.
  * The receive descriptor data structure is defined below
- * as SXG_RCV_DATA_DESCRIPTOR, and the corresponding block
- * is defined as SXG_RCV_DESCRIPTOR_BLOCK.
+ * as sxg_rcv_data_descriptor, and the corresponding block
+ * is defined as sxg_rcv_descriptor_block.
  *
  * This receive descriptor block is given to the card by filling
- * in the Sgl field of a SXG_CMD entry from pAdapt->RcvRings[0]
+ * in the Sgl field of a sxg_cmd entry from pAdapt->RcvRings[0]
  * with the physical address of the receive descriptor block.
  *
  * Both the receive buffers and the receive descriptor blocks
  * require additional data structures to maintain them
  * on a free queue and contain other information associated with them.
- * Those data structures are defined as the SXG_RCV_DATA_BUFFER_HDR
- * and SXG_RCV_DESCRIPTOR_BLOCK_HDR respectively.
+ * Those data structures are defined as the sxg_rcv_data_buffer_hdr
+ * and sxg_rcv_descriptor_block_hdr respectively.
  *
  * Since both the receive buffers and the receive descriptor block
  * must be accessible by the card, both must be allocated out of
  * shared memory.  To ensure that we always have a descriptor
  * block available for every 128 buffers, we allocate all of
  * these resources together in a single block.  This entire
- * block is managed by a SXG_RCV_BLOCK_HDR, who's sole purpose
+ * block is managed by a struct sxg_rcv_block_hdr, who's sole purpose
  * is to maintain address information so that the entire block
  * can be free later.
  *
  * Further complicating matters is the fact that the receive
  * buffers must be variable in length in order to accomodate
  * jumbo frame configurations.  We configure the buffer
- * length so that the buffer and it's corresponding SXG_RCV_DATA_BUFFER_HDR
- * structure add up to an even boundary.  Then we place the
- * remaining data structures after 128 of them as shown in
- * the following diagram:
+ * length so that the buffer and it's corresponding struct
+ * sxg_rcv_data_buffer_hdr structure add up to an even
+ * boundary.  Then we place the remaining data structures after 128
+ *  of them as shown in the following diagram:
  *
  *  _________________________________________
  * |                                         |
  * |    Variable length receive buffer #1    |
  * |_________________________________________|
  * |                                         |
- * |       SXG_RCV_DATA_BUFFER_HDR #1        |
+ * |       sxg_rcv_data_buffer_hdr #1        |
  * |_________________________________________| <== Even 2k or 10k boundary
  * |                                         |
  * |         ... repeat 2-128 ..             |
  * |_________________________________________|
  * |                                         |
- * |      SXG_RCV_DESCRIPTOR_BLOCK           |
- * |  Contains SXG_RCV_DATA_DESCRIPTOR * 128 |
+ * |      struct sxg_rcv_descriptor_block    |
+ * |  Contains sxg_rcv_data_descriptor * 128 |
  * |_________________________________________|
  * |                                         |
- * |      SXG_RCV_DESCRIPTOR_BLOCK_HDR       |
+ * |   struct sxg_rcv_descriptor_block_hdr   |
  * |_________________________________________|
  * |                                         |
- * |          SXG_RCV_BLOCK_HDR              |
+ * |      struct sxg_rcv_block_hdr           |
  * |_________________________________________|
  *
  * Memory consumption:
  *	  Non-jumbo:
- *      Buffers and SXG_RCV_DATA_BUFFER_HDR = 2k * 128 = 256k
- *    + SXG_RCV_DESCRIPTOR_BLOCK = 2k
- *    + SXG_RCV_DESCRIPTOR_BLOCK_HDR = ~32
- *    + SXG_RCV_BLOCK_HDR = ~32
+ *      Buffers and sxg_rcv_data_buffer_hdr = 2k * 128 = 256k
+ *    + struct sxg_rcv_descriptor_block = 2k
+ *    + struct sxg_rcv_descriptor_block_hdr = ~32
+ *    + struct sxg_rcv_block_hdr = ~32
  *    => Total = ~258k/block
  *
  *	  Jumbo:
- *      Buffers and SXG_RCV_DATA_BUFFER_HDR = 10k * 128 = 1280k
- *    + SXG_RCV_DESCRIPTOR_BLOCK = 2k
- *    + SXG_RCV_DESCRIPTOR_BLOCK_HDR = ~32
- *    + SXG_RCV_BLOCK_HDR = ~32
+ *      Buffers and sxg_rcv_data_buffer_hdr = 10k * 128 = 1280k
+ *    + struct sxg_rcv_descriptor_block = 2k
+ *    + struct sxg_rcv_descriptor_block_hdr = ~32
+ *    + struct sxg_rcv_block_hdr = ~32
  *    => Total = ~1282k/block
  *
- ***************************************************************************/
-#define SXG_RCV_DATA_BUFFERS			4096	// Amount to give to the card
-#define SXG_INITIAL_RCV_DATA_BUFFERS	8192	// Initial pool of buffers
-#define SXG_MIN_RCV_DATA_BUFFERS		2048	// Minimum amount and when to get more
-#define SXG_MAX_RCV_BLOCKS				128	// = 16384 receive buffers
+ */
+#define SXG_RCV_DATA_BUFFERS		8192	/* Amount to give to the card */
+#define SXG_INITIAL_RCV_DATA_BUFFERS	16384	/* Initial pool of buffers */
+/* Minimum amount and when to get more */
+#define SXG_MIN_RCV_DATA_BUFFERS	4096
+#define SXG_MAX_RCV_BLOCKS		256	/* = 32k receive buffers */
+/* Amount to give to the card in case of jumbo frames */
+#define SXG_JUMBO_RCV_DATA_BUFFERS		2048
+/* Initial pool of buffers in case of jumbo buffers */
+#define SXG_INITIAL_JUMBO_RCV_DATA_BUFFERS	4096
+#define SXG_MIN_JUMBO_RCV_DATA_BUFFERS		1024
 
-// Receive buffer header
-struct SXG_RCV_DATA_BUFFER_HDR {
-	dma_addr_t PhysicalAddress;	// Buffer physical address
-	// Note - DO NOT USE the VirtualAddress field to locate data.
-	// Use the sxg.h:SXG_RECEIVE_DATA_LOCATION macro instead.
-	void *VirtualAddress;	// Start of buffer
-	struct LIST_ENTRY FreeList;	// Free queue of buffers
-	struct SXG_RCV_DATA_BUFFER_HDR *Next;	// Fastpath data buffer queue
-	u32 Size;		// Buffer size
-	u32 ByteOffset;		// See SXG_RESTORE_MDL_OFFSET
-	unsigned char State;	// See SXG_BUFFER state above
-	unsigned char Status;	// Event status (to log PUSH)
-	struct sk_buff *skb;	// Double mapped (nbl and pkt)
+/* Receive buffer header */
+struct sxg_rcv_data_buffer_hdr {
+	dma64_addr_t	PhysicalAddress;	/* Buffer physical address */
+	/*
+	 * Note - DO NOT USE the VirtualAddress field to locate data.
+	 * Use the sxg.h:SXG_RECEIVE_DATA_LOCATION macro instead.
+	 */
+	struct list_entry	FreeList;	/* Free queue of buffers */
+	unsigned char		State;		/* See SXG_BUFFER state above */
+	struct sk_buff          * skb;		/* Double mapped (nbl and pkt)*/
 };
 
-// SxgSlowReceive uses the PACKET (skb) contained
-// in the SXG_RCV_DATA_BUFFER_HDR when indicating dumb-nic data
+/*
+ * SxgSlowReceive uses the PACKET (skb) contained
+ * in the struct sxg_rcv_data_buffer_hdr when indicating dumb-nic data
+ */
 #define SxgDumbRcvPacket	        skb
 
-#define SXG_RCV_DATA_HDR_SIZE			256	// Space for SXG_RCV_DATA_BUFFER_HDR
-#define SXG_RCV_DATA_BUFFER_SIZE		2048	// Non jumbo = 2k including HDR
-#define SXG_RCV_JUMBO_BUFFER_SIZE		10240	// jumbo = 10k including HDR
+/* Space for struct sxg_rcv_data_buffer_hdr */
+#define SXG_RCV_DATA_HDR_SIZE		sizeof(struct sxg_rcv_data_buffer_hdr)
+/* Non jumbo = 2k including HDR */
+#define SXG_RCV_DATA_BUFFER_SIZE	2048
+/* jumbo = 10k including HDR */
+#define SXG_RCV_JUMBO_BUFFER_SIZE	10240
 
-// Receive data descriptor
-struct SXG_RCV_DATA_DESCRIPTOR {
+/* Receive data descriptor */
+struct sxg_rcv_data_descriptor {
 	union {
-		struct sk_buff *VirtualAddress;	// Host handle
-		u64 ForceTo8Bytes;	// Force x86 to 8-byte boundary
+		struct sk_buff *VirtualAddress;	/* Host handle */
+		u64		ForceTo8Bytes;	/*Force x86 to 8-byte boundary*/
 	};
-	dma_addr_t PhysicalAddress;
+	dma64_addr_t PhysicalAddress;
 };
 
-// Receive descriptor block
+/* Receive descriptor block */
 #define SXG_RCV_DESCRIPTORS_PER_BLOCK		128
-#define SXG_RCV_DESCRIPTOR_BLOCK_SIZE		2048	// For sanity check
+#define SXG_RCV_DESCRIPTOR_BLOCK_SIZE		2048	/* For sanity check */
 
-struct SXG_RCV_DESCRIPTOR_BLOCK {
-	struct SXG_RCV_DATA_DESCRIPTOR Descriptors[SXG_RCV_DESCRIPTORS_PER_BLOCK];
+struct sxg_rcv_descriptor_block {
+	struct sxg_rcv_data_descriptor Descriptors[SXG_RCV_DESCRIPTORS_PER_BLOCK];
 };
 
-// Receive descriptor block header
-struct SXG_RCV_DESCRIPTOR_BLOCK_HDR {
-	void *VirtualAddress;	// Start of 2k buffer
-	dma_addr_t PhysicalAddress;	// ..and it's physical address
-	struct LIST_ENTRY FreeList;	// Free queue of descriptor blocks
-	unsigned char State;	// See SXG_BUFFER state above
+/* Receive descriptor block header */
+struct sxg_rcv_descriptor_block_hdr {
+	void 		*VirtualAddress;	/* start of 2k buffer */
+	dma64_addr_t		PhysicalAddress;/* and it's physical address */
+	struct list_entry	FreeList;/* free queue of descriptor blocks */
+	unsigned char	State;	/* see sxg_buffer state above */
 };
 
-// Receive block header
-struct SXG_RCV_BLOCK_HDR {
-	void *VirtualAddress;	// Start of virtual memory
-	dma_addr_t PhysicalAddress;	// ..and it's physical address
-	struct LIST_ENTRY AllList;	// Queue of all SXG_RCV_BLOCKS
+/* Receive block header */
+struct sxg_rcv_block_hdr {
+	void		*VirtualAddress;	/* Start of virtual memory */
+	dma64_addr_t		PhysicalAddress;/* ..and it's physical address*/
+	struct list_entry	AllList;	/* Queue of all SXG_RCV_BLOCKS*/
 };
 
-// Macros to determine data structure offsets into receive block
-#define SXG_RCV_BLOCK_SIZE(_Buffersize) 					\
+/* Macros to determine data structure offsets into receive block */
+#define SXG_RCV_BLOCK_SIZE(_Buffersize) 				\
 	(((_Buffersize) * SXG_RCV_DESCRIPTORS_PER_BLOCK) +		\
-	 (sizeof(struct SXG_RCV_DESCRIPTOR_BLOCK))              +		\
-	 (sizeof(struct SXG_RCV_DESCRIPTOR_BLOCK_HDR))          +		\
-	 (sizeof(struct SXG_RCV_BLOCK_HDR)))
+	 (sizeof(struct sxg_rcv_descriptor_block))              +	\
+	 (sizeof(struct sxg_rcv_descriptor_block_hdr))          +	\
+	 (sizeof(struct sxg_rcv_block_hdr)))
 #define SXG_RCV_BUFFER_DATA_SIZE(_Buffersize)				\
 	((_Buffersize) - SXG_RCV_DATA_HDR_SIZE)
 #define SXG_RCV_DATA_BUFFER_HDR_OFFSET(_Buffersize)			\
 	((_Buffersize) - SXG_RCV_DATA_HDR_SIZE)
-#define SXG_RCV_DESCRIPTOR_BLOCK_OFFSET(_Buffersize)		\
+#define SXG_RCV_DESCRIPTOR_BLOCK_OFFSET(_Buffersize)			\
 	((_Buffersize) * SXG_RCV_DESCRIPTORS_PER_BLOCK)
-#define SXG_RCV_DESCRIPTOR_BLOCK_HDR_OFFSET(_Buffersize)	\
+#define SXG_RCV_DESCRIPTOR_BLOCK_HDR_OFFSET(_Buffersize)		\
 	(((_Buffersize) * SXG_RCV_DESCRIPTORS_PER_BLOCK) +		\
-	 (sizeof(struct SXG_RCV_DESCRIPTOR_BLOCK)))
+	 (sizeof(struct sxg_rcv_descriptor_block)))
 #define SXG_RCV_BLOCK_HDR_OFFSET(_Buffersize)				\
 	(((_Buffersize) * SXG_RCV_DESCRIPTORS_PER_BLOCK) +		\
-	 (sizeof(struct SXG_RCV_DESCRIPTOR_BLOCK))              +		\
-	 (sizeof(struct SXG_RCV_DESCRIPTOR_BLOCK_HDR)))
+	 (sizeof(struct sxg_rcv_descriptor_block))              +	\
+	 (sizeof(struct sxg_rcv_descriptor_block_hdr)))
 
-// Use the miniport reserved portion of the NBL to locate
-// our SXG_RCV_DATA_BUFFER_HDR structure.
-struct SXG_RCV_NBL_RESERVED {
-	struct SXG_RCV_DATA_BUFFER_HDR *RcvDataBufferHdr;
-	void *Available;
+/* Scatter gather list buffer */
+#define SXG_INITIAL_SGL_BUFFERS	8192	/* Initial pool of SGL buffers */
+#define SXG_MIN_SGL_BUFFERS	2048	/* Minimum amount and when to get more*/
+/* Maximum to allocate (note ADAPT:ushort) */
+#define SXG_MAX_SGL_BUFFERS	16384
+
+/*
+ * SXG_SGL_POOL_PROPERTIES - This structure is used to define a pool of SGL
+ * buffers. These buffers are allocated out of shared memory and used to
+ * contain a physical scatter gather list structure that is shared
+ * with the card.
+ *
+ * We split our SGL buffers into multiple pools based on size.  The motivation
+ * is that some applications perform very large I/Os (1MB for example), so
+ * we need to be able to allocate an SGL to accommodate such a request.
+ * But such an SGL would require 256 24-byte SG entries - ~6k.
+ * Given that the vast majority of I/Os are much smaller than 1M, allocating
+ * a single pool of SGL buffers would be a horribly inefficient use of
+ * memory.
+ *
+ * The following structure includes two fields relating to its size.
+ * The NBSize field specifies the largest NET_BUFFER that can be handled
+ * by the particular pool.  The SGEntries field defines the size, in
+ * entries, of the SGL for that pool.  The SGEntries is determined by
+ * dividing the NBSize by the expected page size (4k), and then padding
+ * it by some appropriate amount as insurance (20% or so..??).
+ */
+struct sxg_sgl_pool_properties {
+	u32	NBSize;		/* Largest NET_BUFFER size for this pool */
+	ushort	SGEntries;	/* Number of entries in SGL */
+	ushort	InitialBuffers;	/* Number to allocate at initializationtime */
+	ushort	MinBuffers;	/* When to get more */
+	ushort	MaxBuffers;	/* When to stop */
+	ushort	PerCpuThreshold;/* See sxgh.h:SXG_RESOURCES */
 };
 
-#define SXG_RCV_NBL_BUFFER_HDR(_NBL) (((PSXG_RCV_NBL_RESERVED)NET_BUFFER_LIST_MINIPORT_RESERVED(_NBL))->RcvDataBufferHdr)
+/*
+ * At the moment I'm going to statically initialize 4 pools:
+ *	100k buffer pool: The vast majority of the expected buffers are expected
+ *			to be less than or equal to 100k.  At 30 entries per and
+ * 			8k initial buffers amounts to ~4MB of memory
+ *                 NOTE - This used to be 64K with 20 entries, but during
+ *                        WHQL NDIS 6.0 Testing (2c_mini6stress) MS does their
+ *                        best to send absurd NBL's with ridiculous SGLs, we
+ *                        have received 400byte sends contained in SGL's that
+ *                        have 28 entries
+ *	  1M buffer pool: Buffers between 64k and 1M.  Allocate 256 initial
+ *	  		  buffers with 300 entries each => ~2MB of memory
+ *	  5M buffer pool: Not expected often, if at all.  32 initial buffers
+ *			  at 1500 entries each => ~1MB of memory
+ * 10M buffer pool: Not expected at all, except under pathelogical conditions.
+ * 		    Allocate one at initialization time.
+ * 		  Note - 10M is the current limit of what we can realistically
+ * 		  	 support due to the sahara SGL bug described in the
+ * 		  	 SAHARA SGL WORKAROUND below. We will likely adjust the
+ * 		  	 number of pools and/or pool properties over time.
+ */
+#define SXG_NUM_SGL_POOLS	4
+#define INITIALIZE_SGL_POOL_PROPERTIES					\
+struct sxg_sgl_pool_properties SxgSglPoolProperties[SXG_NUM_SGL_POOLS] =\
+{ 									\
+	{  102400,   30, 8192, 2048, 16384, 256},			\
+	{ 1048576,  300,  256,  128,  1024, 16},			\
+	{ 5252880, 1500,   32,   16,   512, 0},				\
+	{10485760, 2700,    2,    4,    32, 0},				\
+};
 
-/***************************************************************************
- * Scatter gather list buffer
- ***************************************************************************/
-#define SXG_INITIAL_SGL_BUFFERS		8192	// Initial pool of SGL buffers
-#define SXG_MIN_SGL_BUFFERS			2048	// Minimum amount and when to get more
-#define SXG_MAX_SGL_BUFFERS			16384	// Maximum to allocate (note ADAPT:ushort)
+extern struct sxg_sgl_pool_properties SxgSglPoolProperties[];
 
-// Self identifying structure type
+#define SXG_MAX_SGL_BUFFER_SIZE						\
+	SxgSglPoolProperties[SXG_NUM_SGL_POOLS - 1].NBSize
+
+/*
+ * SAHARA SGL WORKAROUND!!
+ * The current Sahara card uses a 16-bit counter when advancing
+ * SGL address locations.  This means that if an SGL crosses
+ * a 64k boundary, the hardware will actually skip back to
+ * the start of the previous 64k boundary, with obviously
+ * undesirable results.
+ *
+ * We currently workaround this issue by allocating SGL buffers
+ * in 64k blocks and skipping over buffers that straddle the boundary.
+ */
+#define SXG_INVALID_SGL(phys_addr,len) \
+	(((phys_addr >> 16) != ( (phys_addr + len) >> 16 )))
+
+/*
+ * Allocate SGLs in blocks so we can skip over invalid entries.
+ * We allocation 64k worth of SGL buffers, including the
+ * struct sxg_sgl_block_hdr, plus one for padding
+ */
+#define SXG_SGL_BLOCK_SIZE				65536
+#define SXG_SGL_ALLOCATION_SIZE(_Pool)					\
+	SXG_SGL_BLOCK_SIZE + SXG_SGL_SIZE(_Pool)
+
+struct sxg_sgl_block_hdr {
+	ushort			Pool;		/* Associated SGL pool */
+	/* struct sxg_scatter_gather blocks */
+	struct list_entry	List;
+	dma64_addr_t        	PhysicalAddress;/* physical address */
+};
+
+/*
+ * The following definition denotes the maximum block of memory that the
+ * card can DMA to.It is specified in the call to NdisMRegisterScatterGatherDma.
+ * For now, use the same value as used in the Slic/Oasis driver, which
+ * is 128M.  That should cover any expected MDL that I can think of.
+ */
+#define SXG_MAX_PHYS_MAP	(1024 * 1024 * 128)
+
+/* Self identifying structure type */
 enum SXG_SGL_TYPE {
-	SXG_SGL_DUMB,		// Dumb NIC SGL
-	SXG_SGL_SLOW,		// Slowpath protocol header - see below
-	SXG_SGL_CHIMNEY		// Chimney offload SGL
+	SXG_SGL_DUMB,		/* Dumb NIC SGL */
+	SXG_SGL_SLOW,		/* Slowpath protocol header - see below */
+	SXG_SGL_CHIMNEY		/* Chimney offload SGL */
 };
 
-// Note - the description below is Microsoft specific
-//
-// The following definition specifies the amount of shared memory to allocate
-// for the SCATTER_GATHER_LIST portion of the SXG_SCATTER_GATHER data structure.
-// The following considerations apply when setting this value:
-// - First, the Sahara card is designed to read the Microsoft SGL structure
-//       straight out of host memory.  This means that the SGL must reside in
-//       shared memory.  If the length here is smaller than the SGL for the
-//       NET_BUFFER, then NDIS will allocate its own buffer.  The buffer
-//       that NDIS allocates is not in shared memory, so when this happens,
-//       the SGL will need to be copied to a set of SXG_SCATTER_GATHER buffers.
-//       In other words.. we don't want this value to be too small.
-// - On the other hand.. we're allocating up to 16k of these things.  If
-//       we make this too big, we start to consume a ton of memory..
-// At the moment, I'm going to limit the number of SG entries to 150.
-// If each entry maps roughly 4k, then this should cover roughly 600kB
-// NET_BUFFERs.  Furthermore, since each entry is 24 bytes, the total
-// SGE portion of the structure consumes 3600 bytes, which should allow
-// the entire SXG_SCATTER_GATHER structure to reside comfortably within
-// a 4k block, providing the remaining fields stay under 500 bytes.
-//
-// So with 150 entries, the SXG_SCATTER_GATHER structure becomes roughly
-// 4k.  At 16k of them, that amounts to 64M of shared memory.  A ton, but
-// manageable.
-#define SXG_SGL_ENTRIES		150
-
-// The ucode expects an NDIS SGL structure that
-// is formatted for an x64 system.  When running
-// on an x64 system, we can simply hand the NDIS SGL
-// to the card directly.  For x86 systems we must reconstruct
-// the SGL.  The following structure defines an x64
-// formatted SGL entry
-struct SXG_X64_SGE {
-	dma64_addr_t Address;	// same as wdm.h
-	u32 Length;		// same as wdm.h
-	u32 CompilerPad;	// The compiler pads to 8-bytes
-	u64 Reserved;		// u32 * in wdm.h.  Force to 8 bytes
+/*
+ * The ucode expects an NDIS SGL structure that
+ * is formatted for an x64 system.  When running
+ * on an x64 system, we can simply hand the NDIS SGL
+ * to the card directly.  For x86 systems we must reconstruct
+ * the SGL.  The following structure defines an x64
+ * formatted SGL entry
+ */
+struct sxg_x64_sge {
+	dma64_addr_t    Address;	/* same as wdm.h */
+	u32		Length;		/* same as wdm.h */
+	u32		CompilerPad;	/* The compiler pads to 8-bytes */
+	u64		Reserved;	/* u32 * in wdm.h.  Force to 8 bytes */
 };
 
-struct SCATTER_GATHER_ELEMENT {
-	dma64_addr_t Address;	// same as wdm.h
-	u32 Length;		// same as wdm.h
-	u32 CompilerPad;	// The compiler pads to 8-bytes
-	u64 Reserved;		// u32 * in wdm.h.  Force to 8 bytes
-};
-
-struct SCATTER_GATHER_LIST {
+/*
+ * Our SGL structure - Essentially the same as
+ * wdm.h:SCATTER_GATHER_LIST.  Note the variable number of
+ * elements based on the pool specified above
+ */
+struct sxg_x64_sgl {
 	u32 NumberOfElements;
 	u32 *Reserved;
-	struct SCATTER_GATHER_ELEMENT Elements[];
+	struct sxg_x64_sge		Elements[1];   /* Variable */
 };
 
-// The card doesn't care about anything except elements, so
-// we can leave the u32 * reserved field alone in the following
-// SGL structure.  But redefine from wdm.h:SCATTER_GATHER_LIST so
-// we can specify SXG_X64_SGE and define a fixed number of elements
-struct SXG_X64_SGL {
-	u32 NumberOfElements;
-	u32 *Reserved;
-	struct SXG_X64_SGE Elements[SXG_SGL_ENTRIES];
+struct sxg_scatter_gather {
+	enum SXG_SGL_TYPE	Type;		/* FIRST! Dumb-nic or offload */
+	ushort			Pool;		/* Associated SGL pool */
+	ushort			Entries;	/* SGL total entries */
+	void *   		adapter;	/* Back pointer to adapter */
+	/* Free struct sxg_scatter_gather blocks */
+	struct list_entry	FreeList;
+	/* All struct sxg_scatter_gather blocks */
+	struct list_entry	AllList;
+	dma64_addr_t		PhysicalAddress;/* physical address */
+	unsigned char		State;		/* See SXG_BUFFER state above */
+	unsigned char		CmdIndex;	/* Command ring index */
+	struct sk_buff         	*DumbPacket;	/* Associated Packet */
+	/* For asynchronous completions */
+	u32			Direction;
+	u32			CurOffset;	/* Current SGL offset */
+	u32			SglRef;		/* SGL reference count */
+	struct vlan_hdr		VlanTag;	/* VLAN tag to be inserted into SGL */
+	struct sxg_x64_sgl     	*pSgl;		/* SGL Addr. Possibly &Sgl */
+	struct sxg_x64_sgl	Sgl;		/* SGL handed to card */
 };
 
-struct SXG_SCATTER_GATHER {
-	enum SXG_SGL_TYPE Type;	// FIRST! Dumb-nic or offload
-	void *adapter;		// Back pointer to adapter
-	struct LIST_ENTRY FreeList;	// Free SXG_SCATTER_GATHER blocks
-	struct LIST_ENTRY AllList;	// All SXG_SCATTER_GATHER blocks
-	dma_addr_t PhysicalAddress;	// physical address
-	unsigned char State;	// See SXG_BUFFER state above
-	unsigned char CmdIndex;	// Command ring index
-	struct sk_buff *DumbPacket;	// Associated Packet
-	u32 Direction;		// For asynchronous completions
-	u32 CurOffset;		// Current SGL offset
-	u32 SglRef;		// SGL reference count
-	struct VLAN_HDR VlanTag;	// VLAN tag to be inserted into SGL
-	struct SCATTER_GATHER_LIST *pSgl;	// SGL Addr. Possibly &Sgl
-	struct SXG_X64_SGL Sgl;	// SGL handed to card
-};
+/*
+ * Note - the "- 1" is because struct sxg_scatter_gather=>struct sxg_x64_sgl
+ * includes 1 SGE..
+ */
+#define SXG_SGL_SIZE(_Pool) 						\
+	(sizeof(struct sxg_scatter_gather) +				\
+	 ((SxgSglPoolProperties[_Pool].SGEntries - 1) * 		\
+				sizeof(struct sxg_x64_sge)))
 
+/* Force NDIS to give us it's own buffer so we can reformat to our own */
+#define SXG_SGL_BUFFER(_SxgSgl)                 NULL
+#define SXG_SGL_BUFFER_LENGTH(_SxgSgl)          0
+#define SXG_SGL_BUF_SIZE                        0
+
+/*
 #if defined(CONFIG_X86_64)
-#define SXG_SGL_BUFFER(_SxgSgl)		(&_SxgSgl->Sgl)
-#define SXG_SGL_BUF_SIZE			sizeof(struct SXG_X64_SGL)
+#define SXG_SGL_BUFFER(_SxgSgl)		    (&_SxgSgl->Sgl)
+#define SXG_SGL_BUFFER_LENGTH(_SxgSgl)	((_SxgSgl)->Entries * 		\
+					sizeof(struct sxg_x64_sge))
+#define SXG_SGL_BUF_SIZE			    sizeof(struct sxg_x64_sgl)
 #elif defined(CONFIG_X86)
 // Force NDIS to give us it's own buffer so we can reformat to our own
-#define SXG_SGL_BUFFER(_SxgSgl)		NULL
+#define SXG_SGL_BUFFER(_SxgSgl)		        NULL
+#define SXG_SGL_BUFFER_LENGTH(_SxgSgl)		0
 #define SXG_SGL_BUF_SIZE			0
 #else
 #error staging: sxg: driver is for X86 only!
 #endif
+*/
+/* Microcode statistics */
+struct sxg_ucode_stats {
+	u32  RPDQOflow;		/* PDQ overflow (unframed ie dq & drop 1st) */
+	u32  XDrops;		/* Xmt drops due to no xmt buffer */
+	u32  ERDrops;		/* Rcv drops due to ER full */
+	u32  NBDrops;		/* Rcv drops due to out of host buffers */
+	u32  PQDrops;		/* Rcv drops due to PDQ full */
+	/* Rcv drops due to bad frame: no link addr match, frlen > max */
+	u32  BFDrops;
+	u32  UPDrops;		/* Rcv drops due to UPFq full */
+	u32  XNoBufs;		/* Xmt drop due to no DRAM Xmit buffer or PxyBuf */
+};
+
+/*
+ * Macros for handling the Offload engine values
+ */
+/* Number of positions to shift Network Header Length before passing to card */
+#define SXG_NW_HDR_LEN_SHIFT		2
diff --git a/drivers/staging/sxg/sxghw.h b/drivers/staging/sxg/sxghw.h
index b0efff9..81f81d4 100644
--- a/drivers/staging/sxg/sxghw.h
+++ b/drivers/staging/sxg/sxghw.h
@@ -1,4 +1,4 @@
-/*
+/*************************************************************
  * Copyright © 1997-2007 Alacritech, Inc. All rights reserved
  *
  * $Id: sxghw.h,v 1.2 2008/07/24 17:24:23 chris Exp $
@@ -7,682 +7,894 @@
  *
  * This file contains structures and definitions for the
  * Alacritech Sahara hardware
- */
+ *
+ **********************************************************/
 
 
-/*******************************************************************************
- * Configuration space
- *******************************************************************************/
+/* PCI Configuration space */
 /*  PCI Vendor ID */
 #define SXG_VENDOR_ID			0x139A	/* Alacritech's Vendor ID */
 
-//  PCI Device ID
+/*  PCI Device ID */
 #define SXG_DEVICE_ID			0x0009	/* Sahara Device ID */
 
-//
-// Subsystem IDs.
-//
-// The subsystem ID value is broken into bit fields as follows:
-//		Bits [15:12] - Function
-//		Bits [11:8]  - OEM and/or operating system.
-//		Bits [7:0]   - Base SID.
-//
-// SSID field (bit) masks
-#define SSID_BASE_MASK					0x00FF	// Base subsystem ID mask
-#define SSID_OEM_MASK					0x0F00	// Subsystem OEM mask
-#define SSID_FUNC_MASK					0xF000	// Subsystem function mask
 
-// Base SSID's
-#define SSID_SAHARA_PROTO				0x0018	// 100022 Sahara prototype (XenPak) board
-#define SSID_SAHARA_FIBER				0x0019	// 100023 Sahara 1-port fiber board
-#define SSID_SAHARA_COPPER				0x001A	// 100024 Sahara 1-port copper board
+/* Type of ASIC in use */
+enum asic_type {
+	SAHARA_REV_A,
+	SAHARA_REV_B
+};
 
-// Useful SSID macros
-#define	SSID_BASE(ssid)			((ssid) & SSID_BASE_MASK)		// isolate base SSID bits
-#define	SSID_OEM(ssid)			((ssid) & SSID_OEM_MASK)		// isolate SSID OEM bits
-#define	SSID_FUNC(ssid)			((ssid) & SSID_FUNC_MASK)		// isolate SSID function bits
+/* Type of Xcvr in fiber card */
+enum xcvr_type {
+	XCVR_UNKNOWN,
+	XCVR_NONE,
+	XCVR_SR,
+	XCVR_LR,
+	XCVR_LRM,
+	XCVR_CR
+};
+/*
+ * Subsystem IDs.
+ *
+ * The subsystem ID value is broken into bit fields as follows:
+ *		Bits [15:12] - Function
+ *		Bits [11:8]  - OEM and/or operating system.
+ *		Bits [7:0]   - Base SID.
+ */
 
-/*******************************************************************************
- * HW Register Space
- *******************************************************************************/
-#define SXG_HWREG_MEMSIZE	0x4000		// 16k
+/* SSID field (bit) masks */
+#define SSID_BASE_MASK		0x00FF	/* Base subsystem ID mask */
+#define SSID_OEM_MASK		0x0F00	/* Subsystem OEM mask */
+#define SSID_FUNC_MASK		0xF000	/* Subsystem function mask */
+
+/* Base SSID's */
+/* 100022 Sahara prototype (XenPak) board */
+#define SSID_SAHARA_PROTO	0x0018
+#define SSID_SAHARA_FIBER	0x0019	/* 100023 Sahara 1-port fiber board */
+#define SSID_SAHARA_COPPER	0x001A	/* 100024 Sahara 1-port copper board */
+
+/* Useful SSID macros */
+/* isolate base SSID bits */
+#define	SSID_BASE(ssid)		((ssid) & SSID_BASE_MASK)
+/* isolate SSID OEM bits */
+#define	SSID_OEM(ssid)		((ssid) & SSID_OEM_MASK)
+/* isolate SSID function bits */
+#define	SSID_FUNC(ssid)		((ssid) & SSID_FUNC_MASK)
+
+
+/* HW Register Space */
+#define SXG_HWREG_MEMSIZE	0x4000		/* 16k */
 
 #pragma pack(push, 1)
-struct SXG_HW_REGS {
-	u32		Reset;				// Write 0xdead to invoke soft reset
-	u32		Pad1;				// No register defined at offset 4
-	u32		InterruptMask0;		// Deassert legacy interrupt on function 0
-	u32		InterruptMask1;		// Deassert legacy interrupt on function 1
-	u32		UcodeDataLow;		// Store microcode instruction bits 31-0
-	u32		UcodeDataMiddle;	// Store microcode instruction bits 63-32
-	u32		UcodeDataHigh;		// Store microcode instruction bits 95-64
-	u32		UcodeAddr;			// Store microcode address - See flags below
-	u32		PadTo0x80[24];		// Pad to Xcv configuration registers
-	u32		MacConfig0;			// 0x80 - AXGMAC Configuration Register 0
-	u32		MacConfig1;			// 0x84 - AXGMAC Configuration Register 1
-	u32		MacConfig2;			// 0x88 - AXGMAC Configuration Register 2
-	u32		MacConfig3;			// 0x8C - AXGMAC Configuration Register 3
-	u32		MacAddressLow;		// 0x90 - AXGMAC MAC Station Address - octets 1-4
-	u32		MacAddressHigh;		// 0x94 - AXGMAC MAC Station Address - octets 5-6
-	u32		MacReserved1[2];	// 0x98 - AXGMAC Reserved
-	u32		MacMaxFrameLen;		// 0xA0 - AXGMAC Maximum Frame Length
-	u32		MacReserved2[2];	// 0xA4 - AXGMAC Reserved
-	u32		MacRevision;		// 0xAC - AXGMAC Revision Level Register
-	u32		MacReserved3[4];	// 0xB0 - AXGMAC Reserved
-	u32		MacAmiimCmd;		// 0xC0 - AXGMAC AMIIM Command Register
-	u32		MacAmiimField;		// 0xC4 - AXGMAC AMIIM Field Register
-	u32		MacAmiimConfig;		// 0xC8 - AXGMAC AMIIM Configuration Register
-	u32		MacAmiimLink;		// 0xCC - AXGMAC AMIIM Link Fail Vector Register
-	u32		MacAmiimIndicator;	// 0xD0 - AXGMAC AMIIM Indicator Registor
-	u32		PadTo0x100[11];		// 0xD4 - 0x100 - Pad
-	u32		XmtConfig;			// 0x100 - Transmit Configuration Register
-	u32		RcvConfig;			// 0x104 - Receive Configuration Register 1
-	u32		LinkAddress0Low;	// 0x108 - Link address 0
-	u32		LinkAddress0High;	// 0x10C - Link address 0
-	u32		LinkAddress1Low;	// 0x110 - Link address 1
-	u32		LinkAddress1High;	// 0x114 - Link address 1
-	u32		LinkAddress2Low;	// 0x118 - Link address 2
-	u32		LinkAddress2High;	// 0x11C - Link address 2
-	u32		LinkAddress3Low;	// 0x120 - Link address 3
-	u32		LinkAddress3High;	// 0x124 - Link address 3
-	u32		ToeplitzKey[10];	// 0x128 - 0x150 - Toeplitz key
-	u32		SocketKey[10];		// 0x150 - 0x178 - Socket Key
-	u32		LinkStatus;			// 0x178 - Link status
-	u32		ClearStats;			// 0x17C - Clear Stats
-	u32		XmtErrorsLow;		// 0x180 - Transmit stats - errors
-	u32		XmtErrorsHigh;		// 0x184 - Transmit stats - errors
-	u32		XmtFramesLow;		// 0x188 - Transmit stats - frame count
-	u32		XmtFramesHigh;		// 0x18C - Transmit stats - frame count
-	u32		XmtBytesLow;		// 0x190 - Transmit stats - byte count
-	u32		XmtBytesHigh;		// 0x194 - Transmit stats - byte count
-	u32		XmtTcpSegmentsLow;	// 0x198 - Transmit stats - TCP segments
-	u32		XmtTcpSegmentsHigh;	// 0x19C - Transmit stats - TCP segments
-	u32		XmtTcpBytesLow;		// 0x1A0 - Transmit stats - TCP bytes
-	u32		XmtTcpBytesHigh;	// 0x1A4 - Transmit stats - TCP bytes
-	u32		RcvErrorsLow;		// 0x1A8 - Receive stats - errors
-	u32		RcvErrorsHigh;		// 0x1AC - Receive stats - errors
-	u32		RcvFramesLow;		// 0x1B0 - Receive stats - frame count
-	u32		RcvFramesHigh;		// 0x1B4 - Receive stats - frame count
-	u32		RcvBytesLow;		// 0x1B8 - Receive stats - byte count
-	u32		RcvBytesHigh;		// 0x1BC - Receive stats - byte count
-	u32		RcvTcpSegmentsLow;	// 0x1C0 - Receive stats - TCP segments
-	u32		RcvTcpSegmentsHigh;	// 0x1C4 - Receive stats - TCP segments
-	u32		RcvTcpBytesLow;		// 0x1C8 - Receive stats - TCP bytes
-	u32		RcvTcpBytesHigh;	// 0x1CC - Receive stats - TCP bytes
-	u32		PadTo0x200[12];		// 0x1D0 - 0x200 - Pad
-	u32		Software[1920];		// 0x200 - 0x2000 - Software defined (not used)
-	u32		MsixTable[1024];	// 0x2000 - 0x3000 - MSIX Table
-	u32		MsixBitArray[1024];	// 0x3000 - 0x4000 - MSIX Pending Bit Array
+struct sxg_hw_regs {
+	u32	Reset;		/* Write 0xdead to invoke soft reset */
+	u32	Pad1;		/* No register defined at offset 4 */
+	u32	InterruptMask0;	/* Deassert legacy interrupt on function 0 */
+	u32	InterruptMask1;	/* Deassert legacy interrupt on function 1 */
+	u32	UcodeDataLow;	/* Store microcode instruction bits 31-0 */
+	u32	UcodeDataMiddle;	/* Store microcode instruction bits 63-32 */
+	u32	UcodeDataHigh;	/* Store microcode instruction bits 95-64 */
+	u32	UcodeAddr;	/* Store microcode address - See flags below */
+	u32	PadTo0x80[24];	/* Pad to Xcv configuration registers */
+	u32	MacConfig0;	/* 0x80 - AXGMAC Configuration Register 0 */
+	u32	MacConfig1;	/* 0x84 - AXGMAC Configuration Register 1 */
+	u32	MacConfig2;	/* 0x88 - AXGMAC Configuration Register 2 */
+	u32	MacConfig3;	/* 0x8C - AXGMAC Configuration Register 3 */
+	u32	MacAddressLow;	/* 0x90 - AXGMAC MAC Station Address - octets 1-4 */
+	u32	MacAddressHigh;	/* 0x94 - AXGMAC MAC Station Address - octets 5-6 */
+	u32	MacReserved1[2];	/* 0x98 - AXGMAC Reserved */
+	u32	MacMaxFrameLen;	/* 0xA0 - AXGMAC Maximum Frame Length */
+	u32	MacReserved2[2];	/* 0xA4 - AXGMAC Reserved */
+	u32	MacRevision;	/* 0xAC - AXGMAC Revision Level Register */
+	u32	MacReserved3[4];	/* 0xB0 - AXGMAC Reserved */
+	u32	MacAmiimCmd;	/* 0xC0 - AXGMAC AMIIM Command Register */
+	u32	MacAmiimField;	/* 0xC4 - AXGMAC AMIIM Field Register */
+	u32	MacAmiimConfig;	/* 0xC8 - AXGMAC AMIIM Configuration Register */
+	u32	MacAmiimLink;	/* 0xCC - AXGMAC AMIIM Link Fail Vector Register */
+	u32	MacAmiimIndicator;	/* 0xD0 - AXGMAC AMIIM Indicator Registor */
+	u32	PadTo0x100[11];		/* 0xD4 - 0x100 - Pad */
+	u32	XmtConfig;	/* 0x100 - Transmit Configuration Register */
+	u32	RcvConfig;	/* 0x104 - Receive Configuration Register 1 */
+	u32	LinkAddress0Low;	/* 0x108 - Link address 0 */
+	u32	LinkAddress0High;	/* 0x10C - Link address 0 */
+	u32	LinkAddress1Low;	/* 0x110 - Link address 1 */
+	u32	LinkAddress1High;	/* 0x114 - Link address 1 */
+	u32	LinkAddress2Low;	/* 0x118 - Link address 2 */
+	u32	LinkAddress2High;	/* 0x11C - Link address 2 */
+	u32	LinkAddress3Low;	/* 0x120 - Link address 3 */
+	u32	LinkAddress3High;	/* 0x124 - Link address 3 */
+	u32	ToeplitzKey[10];	/* 0x128 - 0x150 - Toeplitz key */
+	u32	SocketKey[10];		/* 0x150 - 0x178 - Socket Key */
+	u32	LinkStatus;		/* 0x178 - Link status */
+	u32	ClearStats;		/* 0x17C - Clear Stats */
+	u32	XmtErrorsLow;		/* 0x180 - Transmit stats - errors */
+	u32	XmtErrorsHigh;		/* 0x184 - Transmit stats - errors */
+	u32	XmtFramesLow;	/* 0x188 - Transmit stats - frame count */
+	u32	XmtFramesHigh;	/* 0x18C - Transmit stats - frame count */
+	u32	XmtBytesLow;	/* 0x190 - Transmit stats - byte count */
+	u32	XmtBytesHigh;	/* 0x194 - Transmit stats - byte count */
+	u32	XmtTcpSegmentsLow;	/* 0x198 - Transmit stats - TCP segments */
+	u32	XmtTcpSegmentsHigh;	/* 0x19C - Transmit stats - TCP segments */
+	u32	XmtTcpBytesLow;		/* 0x1A0 - Transmit stats - TCP bytes */
+	u32	XmtTcpBytesHigh;	/* 0x1A4 - Transmit stats - TCP bytes */
+	u32	RcvErrorsLow;		/* 0x1A8 - Receive stats - errors */
+	u32	RcvErrorsHigh;		/* 0x1AC - Receive stats - errors */
+	u32	RcvFramesLow;		/* 0x1B0 - Receive stats - frame count */
+	u32	RcvFramesHigh;		/* 0x1B4 - Receive stats - frame count */
+	u32	RcvBytesLow;		/* 0x1B8 - Receive stats - byte count */
+	u32	RcvBytesHigh;		/* 0x1BC - Receive stats - byte count */
+	u32	RcvTcpSegmentsLow;	/* 0x1C0 - Receive stats - TCP segments */
+	u32	RcvTcpSegmentsHigh;	/* 0x1C4 - Receive stats - TCP segments */
+	u32	RcvTcpBytesLow;		/* 0x1C8 - Receive stats - TCP bytes */
+	u32	RcvTcpBytesHigh;	/* 0x1CC - Receive stats - TCP bytes */
+	u32	PadTo0x200[12];		/* 0x1D0 - 0x200 - Pad */
+	u32	Software[1920];		/* 0x200 - 0x2000 - Software defined (not used) */
+	u32	MsixTable[1024];	/* 0x2000 - 0x3000 - MSIX Table */
+	u32	MsixBitArray[1024];	/* 0x3000 - 0x4000 - MSIX Pending Bit Array */
 };
 #pragma pack(pop)
 
-// Microcode Address Flags
-#define	MICROCODE_ADDRESS_GO		0x80000000	// Start microcode
-#define	MICROCODE_ADDRESS_WRITE		0x40000000	// Store microcode
-#define	MICROCODE_ADDRESS_READ		0x20000000	// Read microcode
-#define	MICROCODE_ADDRESS_PARITY	0x10000000	// Parity error detected
-#define	MICROCODE_ADDRESS_MASK		0x00001FFF	// Address bits
+/* Microcode Address Flags */
+#define	MICROCODE_ADDRESS_GO		0x80000000	/* Start microcode */
+#define	MICROCODE_ADDRESS_WRITE		0x40000000	/* Store microcode */
+#define	MICROCODE_ADDRESS_READ		0x20000000	/* Read microcode */
+#define	MICROCODE_ADDRESS_PARITY	0x10000000/* Parity error detected */
+#define	MICROCODE_ADDRESS_MASK		0x00001FFF	/* Address bits */
 
-// Link Address Registers
-#define LINK_ADDRESS_ENABLE			0x80000000	// Applied to link address high
+/* Link Address Registers */
+/* Applied to link address high */
+#define LINK_ADDRESS_ENABLE	0x80000000
 
-// Microsoft register space size
-#define SXG_UCODEREG_MEMSIZE	0x40000		// 256k
+/* Microsoft register space size */
+#define SXG_UCODEREG_MEMSIZE	0x40000		/* 256k */
 
-// Sahara microcode register address format.  The command code,
-// extended command code, and associated processor are encoded in
-// the address bits as follows
-#define SXG_ADDRESS_CODE_SHIFT		2			// Base command code
+/*
+ * Sahara microcode register address format.  The command code,
+ * extended command code, and associated processor are encoded in
+ * the address bits as follows
+ */
+#define SXG_ADDRESS_CODE_SHIFT		2		/* Base command code */
 #define SXG_ADDRESS_CODE_MASK		0x0000003C
-#define SXG_ADDRESS_EXCODE_SHIFT	6			// Extended (or sub) command code
+/* Extended (or sub) command code */
+#define SXG_ADDRESS_EXCODE_SHIFT	6
 #define SXG_ADDRESS_EXCODE_MASK		0x00001FC0
-#define	SXG_ADDRESS_CPUID_SHIFT		13			// CPU
+#define	SXG_ADDRESS_CPUID_SHIFT		13		/* CPU */
 #define SXG_ADDRESS_CPUID_MASK		0x0003E000
-#define SXG_REGISTER_SIZE_PER_CPU	0x00002000	// Used to sanity check UCODE_REGS structure
+/* Used to sanity check UCODE_REGS structure */
+#define SXG_REGISTER_SIZE_PER_CPU	0x00002000
 
-// Sahara receive sequencer status values
-#define SXG_RCV_STATUS_ATTN			0x80000000	// Attention
-#define SXG_RCV_STATUS_TRANSPORT_MASK		0x3F000000	// Transport mask
-#define SXG_RCV_STATUS_TRANSPORT_ERROR		0x20000000	// Transport error
-#define SXG_RCV_STATUS_TRANSPORT_CSUM		0x23000000	// Transport cksum error
-#define SXG_RCV_STATUS_TRANSPORT_UFLOW		0x22000000	// Transport underflow
-#define SXG_RCV_STATUS_TRANSPORT_HDRLEN		0x20000000	// Transport header length
-#define SXG_RCV_STATUS_TRANSPORT_FLAGS		0x10000000	// Transport flags detected
-#define SXG_RCV_STATUS_TRANSPORT_OPTS		0x08000000	// Transport options detected
-#define SXG_RCV_STATUS_TRANSPORT_SESS_MASK	0x07000000	// Transport DDP
-#define SXG_RCV_STATUS_TRANSPORT_DDP		0x06000000	// Transport DDP
-#define SXG_RCV_STATUS_TRANSPORT_iSCSI		0x05000000	// Transport iSCSI
-#define SXG_RCV_STATUS_TRANSPORT_NFS		0x04000000	// Transport NFS
-#define SXG_RCV_STATUS_TRANSPORT_FTP		0x03000000	// Transport FTP
-#define SXG_RCV_STATUS_TRANSPORT_HTTP		0x02000000	// Transport HTTP
-#define SXG_RCV_STATUS_TRANSPORT_SMB		0x01000000	// Transport SMB
-#define SXG_RCV_STATUS_NETWORK_MASK		0x00FF0000	// Network mask
-#define SXG_RCV_STATUS_NETWORK_ERROR		0x00800000	// Network error
-#define SXG_RCV_STATUS_NETWORK_CSUM		0x00830000	// Network cksum error
-#define SXG_RCV_STATUS_NETWORK_UFLOW		0x00820000	// Network underflow error
-#define SXG_RCV_STATUS_NETWORK_HDRLEN		0x00800000	// Network header length
-#define SXG_RCV_STATUS_NETWORK_OFLOW		0x00400000	// Network overflow detected
-#define SXG_RCV_STATUS_NETWORK_MCAST		0x00200000	// Network multicast detected
-#define SXG_RCV_STATUS_NETWORK_OPTIONS		0x00100000	// Network options detected
-#define SXG_RCV_STATUS_NETWORK_OFFSET		0x00080000	// Network offset detected
-#define SXG_RCV_STATUS_NETWORK_FRAGMENT		0x00040000	// Network fragment detected
-#define SXG_RCV_STATUS_NETWORK_TRANS_MASK	0x00030000	// Network transport type mask
-#define SXG_RCV_STATUS_NETWORK_UDP		0x00020000	// UDP
-#define SXG_RCV_STATUS_NETWORK_TCP		0x00010000	// TCP
-#define SXG_RCV_STATUS_IPONLY			0x00008000	// IP-only not TCP
-#define SXG_RCV_STATUS_PKT_PRI			0x00006000	// Receive priority
-#define SXG_RCV_STATUS_PKT_PRI_SHFT			13	// Receive priority shift
-#define SXG_RCV_STATUS_PARITY			0x00001000	// MAC Receive RAM parity error
-#define SXG_RCV_STATUS_ADDRESS_MASK		0x00000F00	// Link address detection mask
-#define SXG_RCV_STATUS_ADDRESS_D		0x00000B00	// Link address D
-#define SXG_RCV_STATUS_ADDRESS_C		0x00000A00	// Link address C
-#define SXG_RCV_STATUS_ADDRESS_B		0x00000900	// Link address B
-#define SXG_RCV_STATUS_ADDRESS_A		0x00000800	// Link address A
-#define SXG_RCV_STATUS_ADDRESS_BCAST		0x00000300	// Link address broadcast
-#define SXG_RCV_STATUS_ADDRESS_MCAST		0x00000200	// Link address multicast
-#define SXG_RCV_STATUS_ADDRESS_CMCAST		0x00000100	// Link control multicast
-#define SXG_RCV_STATUS_LINK_MASK		0x000000FF	// Link status mask
-#define SXG_RCV_STATUS_LINK_ERROR		0x00000080	// Link error
-#define SXG_RCV_STATUS_LINK_MASK		0x000000FF	// Link status mask
-#define SXG_RCV_STATUS_LINK_PARITY		0x00000087	// RcvMacQ parity error
-#define SXG_RCV_STATUS_LINK_EARLY		0x00000086	// Data early
-#define SXG_RCV_STATUS_LINK_BUFOFLOW		0x00000085	// Buffer overflow
-#define SXG_RCV_STATUS_LINK_CODE		0x00000084	// Link code error
-#define SXG_RCV_STATUS_LINK_DRIBBLE		0x00000083	// Dribble nibble
-#define SXG_RCV_STATUS_LINK_CRC			0x00000082	// CRC error
-#define SXG_RCV_STATUS_LINK_OFLOW		0x00000081	// Link overflow
-#define SXG_RCV_STATUS_LINK_UFLOW		0x00000080	// Link underflow
-#define SXG_RCV_STATUS_LINK_8023		0x00000020	// 802.3
-#define SXG_RCV_STATUS_LINK_SNAP		0x00000010	// Snap
-#define SXG_RCV_STATUS_LINK_VLAN		0x00000008	// VLAN
-#define SXG_RCV_STATUS_LINK_TYPE_MASK		0x00000007	// Network type mask
-#define SXG_RCV_STATUS_LINK_CONTROL		0x00000003	// Control packet
-#define SXG_RCV_STATUS_LINK_IPV6		0x00000002	// IPv6 packet
-#define SXG_RCV_STATUS_LINK_IPV4		0x00000001	// IPv4 packet
+/* Sahara receive sequencer status values */
+#define SXG_RCV_STATUS_ATTN			0x80000000 /* Attention */
+#define SXG_RCV_STATUS_TRANSPORT_MASK		0x3F000000 /* Transport mask */
+#define SXG_RCV_STATUS_TRANSPORT_ERROR		0x20000000 /* Transport error */
+/* Transport cksum error */
+#define SXG_RCV_STATUS_TRANSPORT_CSUM		0x23000000
+/* Transport underflow */
+#define SXG_RCV_STATUS_TRANSPORT_UFLOW		0x22000000
+ /* Transport header length */
+#define SXG_RCV_STATUS_TRANSPORT_HDRLEN		0x20000000
+/* Transport flags detected */
+#define SXG_RCV_STATUS_TRANSPORT_FLAGS		0x10000000
+ /* Transport options detected */
+#define SXG_RCV_STATUS_TRANSPORT_OPTS		0x08000000
+#define SXG_RCV_STATUS_TRANSPORT_SESS_MASK	0x07000000 /* Transport DDP */
+#define SXG_RCV_STATUS_TRANSPORT_DDP		0x06000000 /* Transport DDP */
+#define SXG_RCV_STATUS_TRANSPORT_iSCSI		0x05000000 /* Transport iSCSI */
+#define SXG_RCV_STATUS_TRANSPORT_NFS		0x04000000 /* Transport NFS */
+#define SXG_RCV_STATUS_TRANSPORT_FTP		0x03000000 /* Transport FTP */
+#define SXG_RCV_STATUS_TRANSPORT_HTTP		0x02000000 /* Transport HTTP */
+#define SXG_RCV_STATUS_TRANSPORT_SMB		0x01000000 /* Transport SMB */
+#define SXG_RCV_STATUS_NETWORK_MASK		0x00FF0000 /* Network mask */
+#define SXG_RCV_STATUS_NETWORK_ERROR		0x00800000 /* Network error */
+/* Network cksum error */
+#define SXG_RCV_STATUS_NETWORK_CSUM		0x00830000
+/* Network underflow error */
+#define SXG_RCV_STATUS_NETWORK_UFLOW		0x00820000
+ /* Network header length */
+#define SXG_RCV_STATUS_NETWORK_HDRLEN		0x00800000
+ /* Network overflow detected */
+#define SXG_RCV_STATUS_NETWORK_OFLOW		0x00400000
+/* Network multicast detected */
+#define SXG_RCV_STATUS_NETWORK_MCAST		0x00200000
+/* Network options detected */
+#define SXG_RCV_STATUS_NETWORK_OPTIONS		0x00100000
+/* Network offset detected */
+#define SXG_RCV_STATUS_NETWORK_OFFSET		0x00080000
+/* Network fragment detected */
+#define SXG_RCV_STATUS_NETWORK_FRAGMENT		0x00040000
+/* Network transport type mask */
+#define SXG_RCV_STATUS_NETWORK_TRANS_MASK	0x00030000
+#define SXG_RCV_STATUS_NETWORK_UDP		0x00020000 /* UDP */
+#define SXG_RCV_STATUS_NETWORK_TCP		0x00010000 /* TCP */
+#define SXG_RCV_STATUS_IPONLY			0x00008000 /* IP-only not TCP */
+/* Receive priority */
+#define SXG_RCV_STATUS_PKT_PRI			0x00006000
+/* Receive priority shift */
+#define SXG_RCV_STATUS_PKT_PRI_SHFT		13
+/* MAC Receive RAM parity error */
+#define SXG_RCV_STATUS_PARITY			0x00001000
+/* Link address detection mask */
+#define SXG_RCV_STATUS_ADDRESS_MASK		0x00000F00
 
-/***************************************************************************
- * Sahara receive and transmit configuration registers
- ***************************************************************************/
-#define	RCV_CONFIG_RESET		0x80000000	// RcvConfig register reset
-#define	RCV_CONFIG_ENABLE		0x40000000	// Enable the receive logic
-#define	RCV_CONFIG_ENPARSE		0x20000000	// Enable the receive parser
-#define	RCV_CONFIG_SOCKET		0x10000000	// Enable the socket detector
-#define	RCV_CONFIG_RCVBAD		0x08000000	// Receive all bad frames
-#define	RCV_CONFIG_CONTROL		0x04000000	// Receive all control frames
-#define	RCV_CONFIG_RCVPAUSE		0x02000000	// Enable pause transmit when attn
-#define	RCV_CONFIG_TZIPV6		0x01000000	// Include TCP port w/ IPv6 toeplitz
-#define	RCV_CONFIG_TZIPV4		0x00800000	// Include TCP port w/ IPv4 toeplitz
-#define	RCV_CONFIG_FLUSH		0x00400000	// Flush buffers
-#define	RCV_CONFIG_PRIORITY_MASK	0x00300000	// Priority level
-#define	RCV_CONFIG_HASH_MASK		0x00030000	// Hash depth
-#define	RCV_CONFIG_HASH_8		0x00000000	// Hash depth 8
-#define	RCV_CONFIG_HASH_16		0x00010000	// Hash depth 16
-#define	RCV_CONFIG_HASH_4		0x00020000	// Hash depth 4
-#define	RCV_CONFIG_HASH_2		0x00030000	// Hash depth 2
-#define	RCV_CONFIG_BUFLEN_MASK		0x0000FFF0	// Buffer length bits 15:4. ie multiple of 16.
-#define RCV_CONFIG_SKT_DIS		0x00000008	// Disable socket detection on attn
-// Macro to determine RCV_CONFIG_BUFLEN based on maximum frame size.
-// We add 18 bytes for Sahara receive status and padding, plus 4 bytes for CRC,
-// and round up to nearest 16 byte boundary
-#define RCV_CONFIG_BUFSIZE(_MaxFrame) ((((_MaxFrame) + 22) + 15) & RCV_CONFIG_BUFLEN_MASK)
+#define SXG_RCV_STATUS_ADDRESS_D		0x00000B00 /* Link address D */
+#define SXG_RCV_STATUS_ADDRESS_C		0x00000A00 /* Link address C */
+#define SXG_RCV_STATUS_ADDRESS_B		0x00000900 /* Link address B */
+#define SXG_RCV_STATUS_ADDRESS_A		0x00000800 /* Link address A */
+/* Link address broadcast */
+#define SXG_RCV_STATUS_ADDRESS_BCAST		0x00000300
+ /* Link address multicast */
+#define SXG_RCV_STATUS_ADDRESS_MCAST		0x00000200
+/* Link control multicast */
+#define SXG_RCV_STATUS_ADDRESS_CMCAST		0x00000100
+/* Link status mask */
+#define SXG_RCV_STATUS_LINK_MASK		0x000000FF
+#define SXG_RCV_STATUS_LINK_ERROR		0x00000080 /* Link error */
+/* Link status mask */
+#define SXG_RCV_STATUS_LINK_MASK		0x000000FF
+/* RcvMacQ parity error */
+#define SXG_RCV_STATUS_LINK_PARITY		0x00000087
+#define SXG_RCV_STATUS_LINK_EARLY		0x00000086 /* Data early */
+#define SXG_RCV_STATUS_LINK_BUFOFLOW		0x00000085 /* Buffer overflow */
+#define SXG_RCV_STATUS_LINK_CODE		0x00000084 /* Link code error */
+#define SXG_RCV_STATUS_LINK_DRIBBLE		0x00000083 /* Dribble nibble */
+#define SXG_RCV_STATUS_LINK_CRC			0x00000082 /* CRC error */
+#define SXG_RCV_STATUS_LINK_OFLOW		0x00000081 /* Link overflow */
+#define SXG_RCV_STATUS_LINK_UFLOW		0x00000080 /* Link underflow */
+#define SXG_RCV_STATUS_LINK_8023		0x00000020 /* 802.3 */
+#define SXG_RCV_STATUS_LINK_SNAP		0x00000010 /* Snap */
+#define SXG_RCV_STATUS_LINK_VLAN		0x00000008 /* VLAN */
+/* Network type mask */
+#define SXG_RCV_STATUS_LINK_TYPE_MASK		0x00000007
+#define SXG_RCV_STATUS_LINK_CONTROL		0x00000003 /* Control packet */
+#define SXG_RCV_STATUS_LINK_IPV6		0x00000002 /* IPv6 packet */
+#define SXG_RCV_STATUS_LINK_IPV4		0x00000001 /* IPv4 packet */
 
-#define	XMT_CONFIG_RESET		0x80000000	// XmtConfig register reset
-#define	XMT_CONFIG_ENABLE		0x40000000	// Enable transmit logic
-#define	XMT_CONFIG_MAC_PARITY		0x20000000	// Inhibit MAC RAM parity error
-#define	XMT_CONFIG_BUF_PARITY		0x10000000	// Inhibit D2F buffer parity error
-#define	XMT_CONFIG_MEM_PARITY		0x08000000	// Inhibit 1T SRAM parity error
-#define	XMT_CONFIG_INVERT_PARITY	0x04000000	// Invert MAC RAM parity
-#define	XMT_CONFIG_INITIAL_IPID		0x0000FFFF	// Initial IPID
+/* Sahara receive and transmit configuration registers */
+/* RcvConfig register reset */
+#define	RCV_CONFIG_RESET		0x80000000
+/* Enable the receive logic */
+#define	RCV_CONFIG_ENABLE		0x40000000
+/* Enable the receive parser */
+#define	RCV_CONFIG_ENPARSE		0x20000000
+/* Enable the socket detector */
+#define	RCV_CONFIG_SOCKET		0x10000000
+#define	RCV_CONFIG_RCVBAD		0x08000000 /* Receive all bad frames */
+/* Receive all control frames */
+#define	RCV_CONFIG_CONTROL		0x04000000
+/* Enable pause transmit when attn */
+#define	RCV_CONFIG_RCVPAUSE		0x02000000
+/* Include TCP port w/ IPv6 toeplitz */
+#define	RCV_CONFIG_TZIPV6		0x01000000
+/* Include TCP port w/ IPv4 toeplitz */
+#define	RCV_CONFIG_TZIPV4		0x00800000
+#define	RCV_CONFIG_FLUSH		0x00400000 /* Flush buffers */
+#define	RCV_CONFIG_PRIORITY_MASK	0x00300000 /* Priority level */
+#define	RCV_CONFIG_CONN_MASK		0x000C0000 /* Number of connections */
+#define	RCV_CONFIG_CONN_4K		0x00000000 /* 4k connections */
+#define	RCV_CONFIG_CONN_2K		0x00040000 /* 2k connections */
+#define	RCV_CONFIG_CONN_1K		0x00080000 /* 1k connections */
+#define	RCV_CONFIG_CONN_512		0x000C0000 /* 512 connections */
+#define	RCV_CONFIG_HASH_MASK		0x00030000 /* Hash depth */
+#define	RCV_CONFIG_HASH_8		0x00000000 /* Hash depth 8 */
+#define	RCV_CONFIG_HASH_16		0x00010000 /* Hash depth 16 */
+#define	RCV_CONFIG_HASH_4		0x00020000 /* Hash depth 4 */
+#define	RCV_CONFIG_HASH_2		0x00030000 /* Hash depth 2 */
+/* Buffer length bits 15:4. ie multiple of 16. */
+#define	RCV_CONFIG_BUFLEN_MASK		0x0000FFE0
+/* Disable socket detection on attn */
+#define RCV_CONFIG_SKT_DIS		0x00000008
+#define RCV_CONFIG_HIPRICTL     0x00000002 /* Ctrl frames on high-prioirty RcvQ */
+#define RCV_CONFIG_NEWSTATUSFMT 0x00000001 /* Use RevB status format */
+/*
+ * Macro to determine RCV_CONFIG_BUFLEN based on maximum frame size.
+ * We add 18 bytes for Sahara receive status and padding, plus 4 bytes for CRC,
+ * and round up to nearest 32 byte boundary
+ */
+#define RCV_CONFIG_BUFSIZE(_MaxFrame)					\
+		((((_MaxFrame) + 22) + 31) & RCV_CONFIG_BUFLEN_MASK)
 
-/***************************************************************************
- * A-XGMAC Registers - Occupy 0x80 - 0xD4 of the SXG_HW_REGS
+/* XmtConfig register reset */
+#define	XMT_CONFIG_RESET		0x80000000
+#define	XMT_CONFIG_ENABLE		0x40000000 /* Enable transmit logic */
+/* Inhibit MAC RAM parity error */
+#define	XMT_CONFIG_MAC_PARITY		0x20000000
+/* Inhibit D2F buffer parity error */
+#define	XMT_CONFIG_BUF_PARITY		0x10000000
+/* Inhibit 1T SRAM parity error */
+#define	XMT_CONFIG_MEM_PARITY		0x08000000
+#define	XMT_CONFIG_INVERT_PARITY	0x04000000 /* Invert MAC RAM parity */
+#define	XMT_CONFIG_INITIAL_IPID		0x0000FFFF /* Initial IPID */
+
+/*
+ * A-XGMAC Registers - Occupy 0x80 - 0xD4 of the struct sxg_hw_regs
  *
  * Full register descriptions can be found in axgmac.pdf
- ***************************************************************************/
-// A-XGMAC Configuration Register 0
-#define AXGMAC_CFG0_SUB_RESET		0x80000000		// Sub module reset
-#define AXGMAC_CFG0_RCNTRL_RESET	0x00400000		// Receive control reset
-#define AXGMAC_CFG0_RFUNC_RESET		0x00200000		// Receive function reset
-#define AXGMAC_CFG0_TCNTRL_RESET	0x00040000		// Transmit control reset
-#define AXGMAC_CFG0_TFUNC_RESET		0x00020000		// Transmit function reset
-#define AXGMAC_CFG0_MII_RESET		0x00010000		// MII Management reset
+ */
+/* A-XGMAC Configuration Register 0 */
+#define AXGMAC_CFG0_SUB_RESET		0x80000000 /* Sub module reset */
+#define AXGMAC_CFG0_RCNTRL_RESET	0x00400000 /* Receive control reset */
+#define AXGMAC_CFG0_RFUNC_RESET		0x00200000 /* Receive function reset */
+#define AXGMAC_CFG0_TCNTRL_RESET	0x00040000 /* Transmit control reset */
+#define AXGMAC_CFG0_TFUNC_RESET		0x00020000 /* Transmit function reset */
+#define AXGMAC_CFG0_MII_RESET		0x00010000 /* MII Management reset */
 
-// A-XGMAC Configuration Register 1
-#define AXGMAC_CFG1_XMT_PAUSE		0x80000000		// Allow the sending of Pause frames
-#define AXGMAC_CFG1_XMT_EN		0x40000000		// Enable transmit
-#define AXGMAC_CFG1_RCV_PAUSE		0x20000000		// Allow the detection of Pause frames
-#define AXGMAC_CFG1_RCV_EN		0x10000000		// Enable receive
-#define AXGMAC_CFG1_XMT_STATE		0x04000000		// Current transmit state - READ ONLY
-#define AXGMAC_CFG1_RCV_STATE		0x01000000		// Current receive state - READ ONLY
-#define AXGMAC_CFG1_XOFF_SHORT		0x00001000		// Only pause for 64 slot on XOFF
-#define AXGMAC_CFG1_XMG_FCS1		0x00000400		// Delay transmit FCS 1 4-byte word
-#define AXGMAC_CFG1_XMG_FCS2		0x00000800		// Delay transmit FCS 2 4-byte words
-#define AXGMAC_CFG1_XMG_FCS3		0x00000C00		// Delay transmit FCS 3 4-byte words
-#define AXGMAC_CFG1_RCV_FCS1		0x00000100		// Delay receive FCS 1 4-byte word
-#define AXGMAC_CFG1_RCV_FCS2		0x00000200		// Delay receive FCS 2 4-byte words
-#define AXGMAC_CFG1_RCV_FCS3		0x00000300		// Delay receive FCS 3 4-byte words
-#define AXGMAC_CFG1_PKT_OVERRIDE	0x00000080		// Per-packet override enable
-#define AXGMAC_CFG1_SWAP		0x00000040		// Byte swap enable
-#define AXGMAC_CFG1_SHORT_ASSERT	0x00000020		// ASSERT srdrpfrm on short frame (<64)
-#define AXGMAC_CFG1_RCV_STRICT		0x00000010		// RCV only 802.3AE when CLEAR
-#define AXGMAC_CFG1_CHECK_LEN		0x00000008		// Verify frame length
-#define AXGMAC_CFG1_GEN_FCS		0x00000004		// Generate FCS
-#define AXGMAC_CFG1_PAD_MASK		0x00000003		// Mask for pad bits
-#define AXGMAC_CFG1_PAD_64		0x00000001		// Pad frames to 64 bytes
-#define AXGMAC_CFG1_PAD_VLAN		0x00000002		// Detect VLAN and pad to 68 bytes
-#define AXGMAC_CFG1_PAD_68		0x00000003		// Pad to 68 bytes
+/* A-XGMAC Configuration Register 1 */
+/* Allow the sending of Pause frames */
+#define AXGMAC_CFG1_XMT_PAUSE		0x80000000
+#define AXGMAC_CFG1_XMT_EN		0x40000000 /* Enable transmit */
+/* Allow the detection of Pause frames */
+#define AXGMAC_CFG1_RCV_PAUSE		0x20000000
+#define AXGMAC_CFG1_RCV_EN		0x10000000 /* Enable receive */
+/* Current transmit state - READ ONLY */
+#define AXGMAC_CFG1_XMT_STATE		0x04000000
+/* Current receive state - READ ONLY */
+#define AXGMAC_CFG1_RCV_STATE		0x01000000
+/* Only pause for 64 slot on XOFF */
+#define AXGMAC_CFG1_XOFF_SHORT		0x00001000
+/* Delay transmit FCS 1 4-byte word */
+#define AXGMAC_CFG1_XMG_FCS1		0x00000400
+/* Delay transmit FCS 2 4-byte words */
+#define AXGMAC_CFG1_XMG_FCS2		0x00000800
+/* Delay transmit FCS 3 4-byte words */
+#define AXGMAC_CFG1_XMG_FCS3		0x00000C00
+/* Delay receive FCS 1 4-byte word */
+#define AXGMAC_CFG1_RCV_FCS1		0x00000100
+/* Delay receive FCS 2 4-byte words */
+#define AXGMAC_CFG1_RCV_FCS2		0x00000200
+/* Delay receive FCS 3 4-byte words */
+#define AXGMAC_CFG1_RCV_FCS3		0x00000300
+/* Per-packet override enable */
+#define AXGMAC_CFG1_PKT_OVERRIDE	0x00000080
+#define AXGMAC_CFG1_SWAP		0x00000040 /* Byte swap enable */
+/* ASSERT srdrpfrm on short frame (<64) */
+#define AXGMAC_CFG1_SHORT_ASSERT	0x00000020
+/* RCV only 802.3AE when CLEAR */
+#define AXGMAC_CFG1_RCV_STRICT		0x00000010
+#define AXGMAC_CFG1_CHECK_LEN		0x00000008 /* Verify frame length */
+#define AXGMAC_CFG1_GEN_FCS		0x00000004 /* Generate FCS */
+#define AXGMAC_CFG1_PAD_MASK		0x00000003 /* Mask for pad bits */
+#define AXGMAC_CFG1_PAD_64		0x00000001 /* Pad frames to 64 bytes */
+/* Detect VLAN and pad to 68 bytes */
+#define AXGMAC_CFG1_PAD_VLAN		0x00000002
+#define AXGMAC_CFG1_PAD_68		0x00000003 /* Pad to 68 bytes */
 
-// A-XGMAC Configuration Register 2
-#define AXGMAC_CFG2_GEN_PAUSE		0x80000000		// Generate single pause frame (test)
-#define AXGMAC_CFG2_LF_MANUAL		0x08000000		// Manual link fault sequence
-#define AXGMAC_CFG2_LF_AUTO		0x04000000		// Auto link fault sequence
-#define AXGMAC_CFG2_LF_REMOTE		0x02000000		// Remote link fault (READ ONLY)
-#define AXGMAC_CFG2_LF_LOCAL		0x01000000		// Local link fault (READ ONLY)
-#define AXGMAC_CFG2_IPG_MASK		0x001F0000		// Inter packet gap
+/* A-XGMAC Configuration Register 2 */
+/* Generate single pause frame (test) */
+#define AXGMAC_CFG2_GEN_PAUSE		0x80000000
+/* Manual link fault sequence */
+#define AXGMAC_CFG2_LF_MANUAL		0x08000000
+/* Auto link fault sequence */
+#define AXGMAC_CFG2_LF_AUTO		0x04000000
+/* Remote link fault (READ ONLY) */
+#define AXGMAC_CFG2_LF_REMOTE		0x02000000
+/* Local link fault (READ ONLY) */
+#define AXGMAC_CFG2_LF_LOCAL		0x01000000
+#define AXGMAC_CFG2_IPG_MASK		0x001F0000 /* Inter packet gap */
 #define AXGMAC_CFG2_IPG_SHIFT			16
-#define AXGMAC_CFG2_PAUSE_XMT		0x00008000		// Pause transmit module
-#define AXGMAC_CFG2_IPG_EXTEN		0x00000020		// Enable IPG extension algorithm
-#define AXGMAC_CFG2_IPGEX_MASK		0x0000001F		// IPG extension
+#define AXGMAC_CFG2_PAUSE_XMT		0x00008000 /* Pause transmit module */
+/* Enable IPG extension algorithm */
+#define AXGMAC_CFG2_IPG_EXTEN		0x00000020
+#define AXGMAC_CFG2_IPGEX_MASK		0x0000001F /* IPG extension */
 
-// A-XGMAC Configuration Register 3
-#define AXGMAC_CFG3_RCV_DROP		0xFFFF0000		// Receive frame drop filter
-#define AXGMAC_CFG3_RCV_DONT_CARE	0x0000FFFF		// Receive frame don't care filter
+/* A-XGMAC Configuration Register 3 */
+/* Receive frame drop filter */
+#define AXGMAC_CFG3_RCV_DROP		0xFFFF0000
+/* Receive frame don't care filter */
+#define AXGMAC_CFG3_RCV_DONT_CARE	0x0000FFFF
 
-// A-XGMAC Station Address Register - Octets 1-4
-#define AXGMAC_SARLOW_OCTET_ONE		0xFF000000		// First octet
-#define AXGMAC_SARLOW_OCTET_TWO		0x00FF0000		// Second octet
-#define AXGMAC_SARLOW_OCTET_THREE	0x0000FF00		// Third octet
-#define AXGMAC_SARLOW_OCTET_FOUR	0x000000FF		// Fourth octet
+/* A-XGMAC Station Address Register - Octets 1-4 */
+#define AXGMAC_SARLOW_OCTET_ONE		0xFF000000	/* First octet */
+#define AXGMAC_SARLOW_OCTET_TWO		0x00FF0000	/* Second octet */
+#define AXGMAC_SARLOW_OCTET_THREE	0x0000FF00	/* Third octet */
+#define AXGMAC_SARLOW_OCTET_FOUR	0x000000FF	/* Fourth octet */
 
-// A-XGMAC Station Address Register - Octets 5-6
-#define AXGMAC_SARHIGH_OCTET_FIVE	0xFF000000		// Fifth octet
-#define AXGMAC_SARHIGH_OCTET_SIX	0x00FF0000		// Sixth octet
+/* A-XGMAC Station Address Register - Octets 5-6 */
+#define AXGMAC_SARHIGH_OCTET_FIVE	0xFF000000	/* Fifth octet */
+#define AXGMAC_SARHIGH_OCTET_SIX	0x00FF0000	/* Sixth octet */
 
-// A-XGMAC Maximum frame length register
-#define AXGMAC_MAXFRAME_XMT		0x3FFF0000		// Maximum transmit frame length
+/* A-XGMAC Maximum frame length register */
+/* Maximum transmit frame length */
+#define AXGMAC_MAXFRAME_XMT		0x3FFF0000
 #define AXGMAC_MAXFRAME_XMT_SHIFT	16
-#define AXGMAC_MAXFRAME_RCV		0x0000FFFF		// Maximum receive frame length
-// This register doesn't need to be written for standard MTU.
-// For jumbo, I'll just statically define the value here.  This
-// value sets the receive byte count to 9036 (0x234C) and the
-// transmit WORD count to 2259 (0x8D3).  These values include 22
-// bytes of padding beyond the jumbo MTU of 9014
+/* Maximum receive frame length */
+#define AXGMAC_MAXFRAME_RCV		0x0000FFFF
+/*
+ * This register doesn't need to be written for standard MTU.
+ * For jumbo, I'll just statically define the value here.  This
+ * value sets the receive byte count to 9036 (0x234C) and the
+ * transmit WORD count to 2259 (0x8D3).  These values include 22
+ * bytes of padding beyond the jumbo MTU of 9014
+ */
 #define AXGMAC_MAXFRAME_JUMBO		0x08D3234C
 
-// A-XGMAC Revision level
-#define AXGMAC_REVISION_MASK		0x0000FFFF		// Revision level
+/* A-XGMAC Revision level */
+#define AXGMAC_REVISION_MASK		0x0000FFFF	/* Revision level */
 
-// A-XGMAC AMIIM Command Register
-#define AXGMAC_AMIIM_CMD_START		0x00000008		// Command start
-#define AXGMAC_AMIIM_CMD_MASK		0x00000007		// Command
-#define AXGMAC_AMIIM_CMD_LEGACY_WRITE		1		// 10/100/1000 Mbps Phy Write
-#define AXGMAC_AMIIM_CMD_LEGACY_READ		2		// 10/100/1000 Mbps Phy Read
-#define AXGMAC_AMIIM_CMD_MONITOR_SINGLE		3		// Monitor single PHY
-#define AXGMAC_AMIIM_CMD_MONITOR_MULTIPLE	4		// Monitor multiple contiguous PHYs
-#define AXGMAC_AMIIM_CMD_10G_OPERATION		5		// Present AMIIM Field Reg
-#define AXGMAC_AMIIM_CMD_CLEAR_LINK_FAIL	6		// Clear Link Fail Bit in MIIM
+/* A-XGMAC AMIIM Command Register */
+#define AXGMAC_AMIIM_CMD_START		0x00000008	/* Command start */
+#define AXGMAC_AMIIM_CMD_MASK		0x00000007	/* Command */
+/* 10/100/1000 Mbps Phy Write */
+#define AXGMAC_AMIIM_CMD_LEGACY_WRITE		1
+/* 10/100/1000 Mbps Phy Read */
+#define AXGMAC_AMIIM_CMD_LEGACY_READ		2
+#define AXGMAC_AMIIM_CMD_MONITOR_SINGLE		3	/* Monitor single PHY */
+/* Monitor multiple contiguous PHYs */
+#define AXGMAC_AMIIM_CMD_MONITOR_MULTIPLE	4
+/* Present AMIIM Field Reg */
+#define AXGMAC_AMIIM_CMD_10G_OPERATION		5
+/* Clear Link Fail Bit in MIIM */
+#define AXGMAC_AMIIM_CMD_CLEAR_LINK_FAIL	6
 
-// A-XGMAC AMIIM Field Register
-#define AXGMAC_AMIIM_FIELD_ST		0xC0000000		// 2-bit ST field
+/* A-XGMAC AMIIM Field Register */
+#define AXGMAC_AMIIM_FIELD_ST		0xC0000000	/* 2-bit ST field */
 #define AXGMAC_AMIIM_FIELD_ST_SHIFT		30
-#define AXGMAC_AMIIM_FIELD_OP		0x30000000		// 2-bit OP field
+#define AXGMAC_AMIIM_FIELD_OP		0x30000000	/* 2-bit OP field */
 #define AXGMAC_AMIIM_FIELD_OP_SHIFT		28
-#define AXGMAC_AMIIM_FIELD_PORT_ADDR	0x0F800000		// Port address field (hstphyadx in spec)
+/* Port address field (hstphyadx in spec) */
+#define AXGMAC_AMIIM_FIELD_PORT_ADDR 	0x0F800000
 #define AXGMAC_AMIIM_FIELD_PORT_SHIFT		23
-#define AXGMAC_AMIIM_FIELD_DEV_ADDR	0x007C0000		// Device address field (hstregadx in spec)
+/* Device address field (hstregadx in spec) */
+#define AXGMAC_AMIIM_FIELD_DEV_ADDR	0x007C0000
 #define AXGMAC_AMIIM_FIELD_DEV_SHIFT		18
-#define AXGMAC_AMIIM_FIELD_TA		0x00030000		// 2-bit TA field
+#define AXGMAC_AMIIM_FIELD_TA		0x00030000	/* 2-bit TA field */
 #define AXGMAC_AMIIM_FIELD_TA_SHIFT		16
-#define AXGMAC_AMIIM_FIELD_DATA		0x0000FFFF		// Data field
+#define AXGMAC_AMIIM_FIELD_DATA		0x0000FFFF	/* Data field */
 
-// Values for the AXGMAC_AMIIM_FIELD_OP field in the A-XGMAC AMIIM Field Register
-#define	MIIM_OP_ADDR				0		// MIIM Address set operation
-#define	MIIM_OP_WRITE				1		// MIIM Write register operation
-#define	MIIM_OP_READ				2		// MIIM Read register operation
+/* Values for the AXGMAC_AMIIM_FIELD_OP field in the A-XGMAC AMIIM Field Register */
+#define	MIIM_OP_ADDR		0	/* MIIM Address set operation */
+#define	MIIM_OP_WRITE		1	/* MIIM Write register operation */
+#define	MIIM_OP_READ		2	/* MIIM Read register operation */
 #define	MIIM_OP_ADDR_SHIFT	(MIIM_OP_ADDR << AXGMAC_AMIIM_FIELD_OP_SHIFT)
 
-// Values for the AXGMAC_AMIIM_FIELD_PORT_ADDR field in the A-XGMAC AMIIM Field Register
-#define	MIIM_PORT_NUM				1		// All Sahara MIIM modules use port 1
+/*
+ * Values for the AXGMAC_AMIIM_FIELD_PORT_ADDR field in the A-XGMAC AMIIM
+ * Field Register
+ */
+#define	MIIM_PORT_NUM		1	/* All Sahara MIIM modules use port 1 */
 
-// Values for the AXGMAC_AMIIM_FIELD_DEV_ADDR field in the A-XGMAC AMIIM Field Register
-#define	MIIM_DEV_PHY_PMA			1		// PHY PMA/PMD module MIIM device number
-#define	MIIM_DEV_PHY_PCS			3		// PHY PCS module MIIM device number
-#define	MIIM_DEV_PHY_XS				4		// PHY XS module MIIM device number
-#define	MIIM_DEV_XGXS				5		// XGXS MIIM device number
+/*
+ * Values for the AXGMAC_AMIIM_FIELD_DEV_ADDR field in the A-XGMAC AMIIM
+ * Field Register
+ */
+/* PHY PMA/PMD module MIIM device number */
+#define	MIIM_DEV_PHY_PMA	1
+/* PHY PCS module MIIM device number */
+#define	MIIM_DEV_PHY_PCS	3
+/* PHY XS module MIIM device number */
+#define	MIIM_DEV_PHY_XS		4
+#define	MIIM_DEV_XGXS		5	/* XGXS MIIM device number */
 
-// Values for the AXGMAC_AMIIM_FIELD_TA field in the A-XGMAC AMIIM Field Register
-#define	MIIM_TA_10GB				2		// set to 2 for 10 GB operation
+/*
+ * Values for the AXGMAC_AMIIM_FIELD_TA field in the A-XGMAC AMIIM Field
+ * Register
+ */
+#define	MIIM_TA_10GB		2	/* set to 2 for 10 GB operation */
 
-// A-XGMAC AMIIM Configuration Register
-#define AXGMAC_AMIIM_CFG_NOPREAM	0x00000080		// Bypass preamble of mngmt frame
-#define AXGMAC_AMIIM_CFG_HALF_CLOCK	0x0000007F		// half-clock duration of MDC output
+/* A-XGMAC AMIIM Configuration Register */
+/* Bypass preamble of mngmt frame */
+#define AXGMAC_AMIIM_CFG_NOPREAM	0x00000080
+/* half-clock duration of MDC output */
+#define AXGMAC_AMIIM_CFG_HALF_CLOCK	0x0000007F
 
-// A-XGMAC AMIIM Indicator Register
-#define AXGMAC_AMIIM_INDC_LINK		0x00000010		// Link status from legacy PHY or MMD
-#define AXGMAC_AMIIM_INDC_MPHY		0x00000008		// Multiple phy operation in progress
-#define AXGMAC_AMIIM_INDC_SPHY		0x00000004		// Single phy operation in progress
-#define AXGMAC_AMIIM_INDC_MON		0x00000002		// Single or multiple monitor cmd
-#define AXGMAC_AMIIM_INDC_BUSY		0x00000001		// Set until cmd operation complete
+/* A-XGMAC AMIIM Indicator Register */
+/* Link status from legacy PHY or MMD */
+#define AXGMAC_AMIIM_INDC_LINK		0x00000010
+/* Multiple phy operation in progress */
+#define AXGMAC_AMIIM_INDC_MPHY		0x00000008
+/* Single phy operation in progress */
+#define AXGMAC_AMIIM_INDC_SPHY		0x00000004
+/* Single or multiple monitor cmd */
+#define AXGMAC_AMIIM_INDC_MON		0x00000002
+/* Set until cmd operation complete */
+#define AXGMAC_AMIIM_INDC_BUSY		0x00000001
 
-// Link Status and Control Register
-#define	LS_PHY_CLR_RESET		0x80000000		// Clear reset signal to PHY
-#define	LS_SERDES_POWER_DOWN		0x40000000		// Power down the Sahara Serdes
-#define	LS_XGXS_ENABLE			0x20000000		// Enable the XAUI XGXS logic
-#define	LS_XGXS_CTL			0x10000000		// Hold XAUI XGXS logic reset until Serdes is up
-#define	LS_SERDES_DOWN			0x08000000		// When 0, XAUI Serdes is up and initialization is complete
-#define	LS_TRACE_DOWN			0x04000000		// When 0, Trace Serdes is up and initialization is complete
-#define	LS_PHY_CLK_25MHZ		0x02000000		// Set PHY clock to 25 MHz (else 156.125 MHz)
-#define	LS_PHY_CLK_EN			0x01000000		// Enable clock to PHY
-#define	LS_XAUI_LINK_UP			0x00000010		// XAUI link is up
-#define	LS_XAUI_LINK_CHNG		0x00000008		// XAUI link status has changed
-#define	LS_LINK_ALARM			0x00000004		// Link alarm pin
-#define	LS_ATTN_CTRL_MASK		0x00000003		// Mask link attention control bits
-#define	LS_ATTN_ALARM			0x00000000		// 00 => Attn on link alarm
-#define	LS_ATTN_ALARM_OR_STAT_CHNG	0x00000001		// 01 => Attn on link alarm or status change
-#define	LS_ATTN_STAT_CHNG		0x00000002		// 10 => Attn on link status change
-#define	LS_ATTN_NONE			0x00000003		// 11 => no Attn
+/* Link Status and Control Register */
+#define	LS_PHY_CLR_RESET	0x80000000	/* Clear reset signal to PHY */
+#define	LS_SERDES_POWER_DOWN	0x40000000	/* Power down the Sahara Serdes */
+#define	LS_XGXS_ENABLE		0x20000000	/* Enable the XAUI XGXS logic */
+/* Hold XAUI XGXS logic reset until Serdes is up */
+#define	LS_XGXS_CTL		0x10000000
+/* When 0, XAUI Serdes is up and initialization is complete */
+#define	LS_SERDES_DOWN		0x08000000
+/* When 0, Trace Serdes is up and initialization is complete */
+#define	LS_TRACE_DOWN		0x04000000
+/* Set PHY clock to 25 MHz (else 156.125 MHz) */
+#define	LS_PHY_CLK_25MHZ	0x02000000
+#define	LS_PHY_CLK_EN		0x01000000	/* Enable clock to PHY */
+#define	LS_XAUI_LINK_UP		0x00000010	/* XAUI link is up */
+/* XAUI link status has changed */
+#define	LS_XAUI_LINK_CHNG	0x00000008
+#define	LS_LINK_ALARM		0x00000004	/* Link alarm pin */
+/* Mask link attention control bits */
+#define	LS_ATTN_CTRL_MASK	0x00000003
+#define	LS_ATTN_ALARM		0x00000000	/* 00 => Attn on link alarm */
+/* 01 => Attn on link alarm or status change */
+#define	LS_ATTN_ALARM_OR_STAT_CHNG	0x00000001
+/* 10 => Attn on link status change */
+#define	LS_ATTN_STAT_CHNG	0x00000002
+#define	LS_ATTN_NONE		0x00000003	/* 11 => no Attn */
 
-// Link Address High Registers
-#define	LINK_ADDR_ENABLE		0x80000000		// Enable this link address
+/* Link Address High Registers */
+#define	LINK_ADDR_ENABLE	0x80000000	/* Enable this link address */
 
 
-/***************************************************************************
+/*
  * XGXS XAUI XGMII Extender registers
  *
  * Full register descriptions can be found in mxgxs.pdf
- ***************************************************************************/
-// XGXS Register Map
-#define XGXS_ADDRESS_CONTROL1		0x0000			// XS Control 1
-#define XGXS_ADDRESS_STATUS1		0x0001			// XS Status 1
-#define XGXS_ADDRESS_DEVID_LOW		0x0002			// XS Device ID (low)
-#define XGXS_ADDRESS_DEVID_HIGH		0x0003			// XS Device ID (high)
-#define XGXS_ADDRESS_SPEED		0x0004			// XS Speed ability
-#define XGXS_ADDRESS_DEV_LOW		0x0005			// XS Devices in package
-#define XGXS_ADDRESS_DEV_HIGH		0x0006			// XS Devices in package
-#define XGXS_ADDRESS_STATUS2		0x0008			// XS Status 2
-#define XGXS_ADDRESS_PKGID_lOW		0x000E			// XS Package Identifier
-#define XGXS_ADDRESS_PKGID_HIGH		0x000F			// XS Package Identifier
-#define XGXS_ADDRESS_LANE_STATUS	0x0018			// 10G XGXS Lane Status
-#define XGXS_ADDRESS_TEST_CTRL		0x0019			// 10G XGXS Test Control
-#define XGXS_ADDRESS_RESET_LO1		0x8000			// Vendor-Specific Reset Lo 1
-#define XGXS_ADDRESS_RESET_LO2		0x8001			// Vendor-Specific Reset Lo 2
-#define XGXS_ADDRESS_RESET_HI1		0x8002			// Vendor-Specific Reset Hi 1
-#define XGXS_ADDRESS_RESET_HI2		0x8003			// Vendor-Specific Reset Hi 2
+ */
+/* XGXS Register Map */
+#define XGXS_ADDRESS_CONTROL1	0x0000		/* XS Control 1 */
+#define XGXS_ADDRESS_STATUS1	0x0001		/* XS Status 1 */
+#define XGXS_ADDRESS_DEVID_LOW	0x0002		/* XS Device ID (low) */
+#define XGXS_ADDRESS_DEVID_HIGH	0x0003		/* XS Device ID (high) */
+#define XGXS_ADDRESS_SPEED	0x0004		/* XS Speed ability */
+#define XGXS_ADDRESS_DEV_LOW	0x0005		/* XS Devices in package */
+#define XGXS_ADDRESS_DEV_HIGH	0x0006		/* XS Devices in package */
+#define XGXS_ADDRESS_STATUS2	0x0008		/* XS Status 2 */
+#define XGXS_ADDRESS_PKGID_lOW	0x000E		/* XS Package Identifier */
+#define XGXS_ADDRESS_PKGID_HIGH	0x000F		/* XS Package Identifier */
+#define XGXS_ADDRESS_LANE_STATUS	0x0018	/* 10G XGXS Lane Status */
+#define XGXS_ADDRESS_TEST_CTRL	0x0019		/* 10G XGXS Test Control */
+#define XGXS_ADDRESS_RESET_LO1	0x8000		/* Vendor-Specific Reset Lo 1 */
+#define XGXS_ADDRESS_RESET_LO2	0x8001		/* Vendor-Specific Reset Lo 2 */
+#define XGXS_ADDRESS_RESET_HI1	0x8002		/* Vendor-Specific Reset Hi 1 */
+#define XGXS_ADDRESS_RESET_HI2	0x8003		/* Vendor-Specific Reset Hi 2 */
 
-// XS Control 1 register bit definitions
-#define XGXS_CONTROL1_RESET		0x8000			// Reset - self clearing
-#define XGXS_CONTROL1_LOOPBACK		0x4000			// Enable loopback
-#define XGXS_CONTROL1_SPEED1		0x2000			// 0 = unspecified, 1 = 10Gb+
-#define XGXS_CONTROL1_LOWPOWER		0x0400			// 1 = Low power mode
-#define XGXS_CONTROL1_SPEED2		0x0040			// Same as SPEED1 (?)
-#define XGXS_CONTROL1_SPEED		0x003C			// Everything reserved except zero (?)
+/* XS Control 1 register bit definitions */
+#define XGXS_CONTROL1_RESET	0x8000		/* Reset - self clearing */
+#define XGXS_CONTROL1_LOOPBACK	0x4000		/* Enable loopback */
+#define XGXS_CONTROL1_SPEED1	0x2000		/* 0 = unspecified, 1 = 10Gb+ */
+#define XGXS_CONTROL1_LOWPOWER	0x0400		/* 1 = Low power mode */
+#define XGXS_CONTROL1_SPEED2	0x0040		/* Same as SPEED1 (?) */
+/* Everything reserved except zero (?) */
+#define XGXS_CONTROL1_SPEED	0x003C
 
-// XS Status 1 register bit definitions
-#define XGXS_STATUS1_FAULT		0x0080			// Fault detected
-#define XGXS_STATUS1_LINK		0x0004			// 1 = Link up
-#define XGXS_STATUS1_LOWPOWER		0x0002			// 1 = Low power supported
+/* XS Status 1 register bit definitions */
+#define XGXS_STATUS1_FAULT	0x0080		/* Fault detected */
+#define XGXS_STATUS1_LINK	0x0004		/* 1 = Link up */
+#define XGXS_STATUS1_LOWPOWER	0x0002		/* 1 = Low power supported */
 
-// XS Speed register bit definitions
-#define XGXS_SPEED_10G			0x0001			// 1 = 10G capable
+/* XS Speed register bit definitions */
+#define XGXS_SPEED_10G		0x0001		/* 1 = 10G capable */
 
-// XS Devices register bit definitions
-#define XGXS_DEVICES_DTE		0x0020			// DTE XS Present
-#define XGXS_DEVICES_PHY		0x0010			// PHY XS Present
-#define XGXS_DEVICES_PCS		0x0008			// PCS Present
-#define XGXS_DEVICES_WIS		0x0004			// WIS Present
-#define XGXS_DEVICES_PMD		0x0002			// PMD/PMA Present
-#define XGXS_DEVICES_CLAUSE22		0x0001			// Clause 22 registers present
+/* XS Devices register bit definitions */
+#define XGXS_DEVICES_DTE	0x0020		/* DTE XS Present */
+#define XGXS_DEVICES_PHY	0x0010		/* PHY XS Present */
+#define XGXS_DEVICES_PCS	0x0008		/* PCS Present */
+#define XGXS_DEVICES_WIS	0x0004		/* WIS Present */
+#define XGXS_DEVICES_PMD	0x0002		/* PMD/PMA Present */
+#define XGXS_DEVICES_CLAUSE22	0x0001		/* Clause 22 registers present*/
 
-// XS Devices High register bit definitions
-#define XGXS_DEVICES_VENDOR2		0x8000			// Vendor specific device 2
-#define XGXS_DEVICES_VENDOR1		0x4000			// Vendor specific device 1
+/* XS Devices High register bit definitions */
+#define XGXS_DEVICES_VENDOR2	0x8000		/* Vendor specific device 2 */
+#define XGXS_DEVICES_VENDOR1	0x4000		/* Vendor specific device 1 */
 
-// XS Status 2 register bit definitions
-#define XGXS_STATUS2_DEV_MASK		0xC000			// Device present mask
-#define XGXS_STATUS2_DEV_RESPOND	0x8000			// Device responding
-#define XGXS_STATUS2_XMT_FAULT		0x0800			// Transmit fault
-#define XGXS_STATUS2_RCV_FAULT		0x0400			// Receive fault
+/* XS Status 2 register bit definitions */
+#define XGXS_STATUS2_DEV_MASK	0xC000		/* Device present mask */
+#define XGXS_STATUS2_DEV_RESPOND	0x8000	/* Device responding */
+#define XGXS_STATUS2_XMT_FAULT	0x0800		/* Transmit fault */
+#define XGXS_STATUS2_RCV_FAULT	0x0400		/* Receive fault */
 
-// XS Package ID High register bit definitions
-#define XGXS_PKGID_HIGH_ORG		0xFC00			// Organizationally Unique
-#define XGXS_PKGID_HIGH_MFG		0x03F0			// Manufacturer Model
-#define XGXS_PKGID_HIGH_REV		0x000F			// Revision Number
+/* XS Package ID High register bit definitions */
+#define XGXS_PKGID_HIGH_ORG	0xFC00		/* Organizationally Unique */
+#define XGXS_PKGID_HIGH_MFG	0x03F0		/* Manufacturer Model */
+#define XGXS_PKGID_HIGH_REV	0x000F		/* Revision Number */
 
-// XS Lane Status register bit definitions
-#define XGXS_LANE_PHY			0x1000			// PHY/DTE lane alignment status
-#define XGXS_LANE_PATTERN		0x0800			// Pattern testing ability
-#define XGXS_LANE_LOOPBACK		0x0400			// PHY loopback ability
-#define XGXS_LANE_SYNC3			0x0008			// Lane 3 sync
-#define XGXS_LANE_SYNC2			0x0004			// Lane 2 sync
-#define XGXS_LANE_SYNC1			0x0002			// Lane 1 sync
-#define XGXS_LANE_SYNC0			0x0001			// Lane 0 sync
+/* XS Lane Status register bit definitions */
+#define XGXS_LANE_PHY		0x1000	/* PHY/DTE lane alignment status */
+#define XGXS_LANE_PATTERN	0x0800		/* Pattern testing ability */
+#define XGXS_LANE_LOOPBACK	0x0400		/* PHY loopback ability */
+#define XGXS_LANE_SYNC3		0x0008		/* Lane 3 sync */
+#define XGXS_LANE_SYNC2		0x0004		/* Lane 2 sync */
+#define XGXS_LANE_SYNC1		0x0002		/* Lane 1 sync */
+#define XGXS_LANE_SYNC0		0x0001		/* Lane 0 sync */
 
-// XS Test Control register bit definitions
-#define XGXS_TEST_PATTERN_ENABLE	0x0004			// Test pattern enabled
-#define XGXS_TEST_PATTERN_MASK		0x0003			// Test patterns
-#define XGXS_TEST_PATTERN_RSVD		0x0003			// Test pattern - reserved
-#define XGXS_TEST_PATTERN_MIX		0x0002			// Test pattern - mixed
-#define XGXS_TEST_PATTERN_LOW		0x0001			// Test pattern - low
-#define XGXS_TEST_PATTERN_HIGH		0x0001			// Test pattern - high
+/* XS Test Control register bit definitions */
+#define XGXS_TEST_PATTERN_ENABLE	0x0004	/* Test pattern enabled */
+#define XGXS_TEST_PATTERN_MASK	0x0003		/* Test patterns */
+#define XGXS_TEST_PATTERN_RSVD	0x0003		/* Test pattern - reserved */
+#define XGXS_TEST_PATTERN_MIX	0x0002		/* Test pattern - mixed */
+#define XGXS_TEST_PATTERN_LOW	0x0001		/* Test pattern - low */
+#define XGXS_TEST_PATTERN_HIGH	0x0001		/* Test pattern - high */
 
-/***************************************************************************
+/*
  * External MDIO Bus Registers
  *
  * Full register descriptions can be found in PHY/XENPAK/IEEE specs
- ***************************************************************************/
-// LASI (Link Alarm Status Interrupt) Registers (located in MIIM_DEV_PHY_PMA device)
-#define LASI_RX_ALARM_CONTROL		0x9000			// LASI RX_ALARM Control
-#define LASI_TX_ALARM_CONTROL		0x9001			// LASI TX_ALARM Control
-#define LASI_CONTROL			0x9002			// LASI Control
-#define LASI_RX_ALARM_STATUS		0x9003			// LASI RX_ALARM Status
-#define LASI_TX_ALARM_STATUS		0x9004			// LASI TX_ALARM Status
-#define LASI_STATUS			0x9005			// LASI Status
+ */
+/*
+ * LASI (Link Alarm Status Interrupt) Registers (located in
+ * MIIM_DEV_PHY_PMA device)
+ */
+#define LASI_RX_ALARM_CONTROL	0x9000		/* LASI RX_ALARM Control */
+#define LASI_TX_ALARM_CONTROL	0x9001		/* LASI TX_ALARM Control */
+#define LASI_CONTROL		0x9002		/* LASI Control */
+#define LASI_RX_ALARM_STATUS	0x9003		/* LASI RX_ALARM Status */
+#define LASI_TX_ALARM_STATUS	0x9004		/* LASI TX_ALARM Status */
+#define LASI_STATUS		0x9005		/* LASI Status */
 
-// LASI_CONTROL bit definitions
-#define	LASI_CTL_RX_ALARM_ENABLE	0x0004			// Enable RX_ALARM interrupts
-#define	LASI_CTL_TX_ALARM_ENABLE	0x0002			// Enable TX_ALARM interrupts
-#define	LASI_CTL_LS_ALARM_ENABLE	0x0001			// Enable Link Status interrupts
+/* LASI_CONTROL bit definitions */
+/* Enable RX_ALARM interrupts */
+#define	LASI_CTL_RX_ALARM_ENABLE	0x0004
+/* Enable TX_ALARM interrupts */
+#define	LASI_CTL_TX_ALARM_ENABLE	0x0002
+/* Enable Link Status interrupts */
+#define	LASI_CTL_LS_ALARM_ENABLE	0x0001
 
-// LASI_STATUS bit definitions
-#define	LASI_STATUS_RX_ALARM		0x0004			// RX_ALARM status
-#define	LASI_STATUS_TX_ALARM		0x0002			// TX_ALARM status
-#define	LASI_STATUS_LS_ALARM		0x0001			// Link Status
+/* LASI_STATUS bit definitions */
+#define	LASI_STATUS_RX_ALARM	0x0004		/* RX_ALARM status */
+#define	LASI_STATUS_TX_ALARM	0x0002		/* TX_ALARM status */
+#define	LASI_STATUS_LS_ALARM	0x0001		/* Link Status */
 
-// PHY registers - PMA/PMD (device 1)
-#define	PHY_PMA_CONTROL1		0x0000			// PMA/PMD Control 1
-#define	PHY_PMA_STATUS1			0x0001			// PMA/PMD Status 1
-#define	PHY_PMA_RCV_DET			0x000A			// PMA/PMD Receive Signal Detect
-		// other PMA/PMD registers exist and can be defined as needed
+/* PHY registers - PMA/PMD (device 1) */
+#define	PHY_PMA_CONTROL1	0x0000		/* PMA/PMD Control 1 */
+#define	PHY_PMA_STATUS1		0x0001		/* PMA/PMD Status 1 */
+#define	PHY_PMA_RCV_DET		0x000A	/* PMA/PMD Receive Signal Detect */
+		/* other PMA/PMD registers exist and can be defined as needed */
 
-// PHY registers - PCS (device 3)
-#define	PHY_PCS_CONTROL1		0x0000			// PCS Control 1
-#define	PHY_PCS_STATUS1			0x0001			// PCS Status 1
-#define	PHY_PCS_10G_STATUS1		0x0020			// PCS 10GBASE-R Status 1
-		// other PCS registers exist and can be defined as needed
+/* PHY registers - PCS (device 3) */
+#define	PHY_PCS_CONTROL1	0x0000		/* PCS Control 1 */
+#define	PHY_PCS_STATUS1		0x0001		/* PCS Status 1 */
+#define	PHY_PCS_10G_STATUS1	0x0020		/* PCS 10GBASE-R Status 1 */
+		/* other PCS registers exist and can be defined as needed */
 
-// PHY registers - XS (device 4)
-#define	PHY_XS_CONTROL1			0x0000			// XS Control 1
-#define	PHY_XS_STATUS1			0x0001			// XS Status 1
-#define	PHY_XS_LANE_STATUS		0x0018			// XS Lane Status
-		// other XS registers exist and can be defined as needed
+/* PHY registers - XS (device 4) */
+#define	PHY_XS_CONTROL1		0x0000		/* XS Control 1 */
+#define	PHY_XS_STATUS1		0x0001		/* XS Status 1 */
+#define	PHY_XS_LANE_STATUS	0x0018		/* XS Lane Status */
+		/* other XS registers exist and can be defined as needed */
 
-// PHY_PMA_CONTROL1 register bit definitions
-#define	PMA_CONTROL1_RESET		0x8000			// PMA/PMD reset
+/* PHY_PMA_CONTROL1 register bit definitions */
+#define	PMA_CONTROL1_RESET	0x8000		/* PMA/PMD reset */
 
-// PHY_PMA_RCV_DET register bit definitions
-#define	PMA_RCV_DETECT			0x0001			// PMA/PMD receive signal detect
+/* PHY_PMA_RCV_DET register bit definitions */
+#define	PMA_RCV_DETECT		0x0001	/* PMA/PMD receive signal detect */
 
-// PHY_PCS_10G_STATUS1 register bit definitions
-#define	PCS_10B_BLOCK_LOCK		0x0001			// PCS 10GBASE-R locked to receive blocks
+/* PHY_PCS_10G_STATUS1 register bit definitions */
+#define	PCS_10B_BLOCK_LOCK	0x0001	/* PCS 10GBASE-R locked to receive blocks */
 
-// PHY_XS_LANE_STATUS register bit definitions
-#define	XS_LANE_ALIGN			0x1000			// XS transmit lanes aligned
+/* PHY_XS_LANE_STATUS register bit definitions */
+#define	XS_LANE_ALIGN		0x1000		/* XS transmit lanes aligned */
 
-// PHY Microcode download data structure
-struct PHY_UCODE {
+#define XCVR_VENDOR_LEN		16  /* xcvr vendor len */
+#define XCVR_MODEL_LEN		16  /* xcvr model len */
+
+/* PHY Microcode download data structure */
+struct phy_ucode {
 	ushort	Addr;
 	ushort	Data;
 };
 
+/* Slow Bus Register Definitions */
 
-/*****************************************************************************
+/* Module 0 registers */
+#define GPIO_L_IN		0x15		/* GPIO input (low) */
+#define GPIO_L_OUT		0x16		/* GPIO output (low) */
+#define GPIO_L_DIR		0x17		/* GPIO direction (low) */
+#define GPIO_H_IN		0x19		/* GPIO input (high) */
+#define GPIO_H_OUT		0x1A		/* GPIO output (high) */
+#define GPIO_H_DIR		0x1B		/* GPIO direction (high) */
+
+/* Definitions for other slow bus registers can be added as needed */
+
+
+/*
  * Transmit Sequencer Command Descriptor definitions
- *****************************************************************************/
-
-// This descriptor must be placed in GRAM.  The address of this descriptor
-// (along with a couple of control bits) is pushed onto the PxhCmdQ or PxlCmdQ
-// (Proxy high or low command queue).  This data is read by the Proxy Sequencer,
-// which pushes it onto the XmtCmdQ, which is (eventually) read by the Transmit
-// Sequencer, causing a packet to be transmitted.  Not all fields are valid for
-// all commands - see the Sahara spec for details.  Note that this structure is
-// only valid when compiled on a little endian machine.
+ *
+ * This descriptor must be placed in GRAM.  The address of this descriptor
+ * (along with a couple of control bits) is pushed onto the PxhCmdQ or PxlCmdQ
+ * (Proxy high or low command queue).  This data is read by the Proxy Sequencer,
+ * which pushes it onto the XmtCmdQ, which is (eventually) read by the Transmit
+ * Sequencer, causing a packet to be transmitted.  Not all fields are valid for
+ * all commands - see the Sahara spec for details.  Note that this structure is
+ * only valid when compiled on a little endian machine.
+ */
 #pragma pack(push, 1)
-struct XMT_DESC {
-	ushort	XmtLen;			// word 0, bits [15:0] -  transmit length
-	unsigned char	XmtCtl;			// word 0, bits [23:16] - transmit control byte
-	unsigned char	Cmd;			// word 0, bits [31:24] - transmit command plus misc.
-	u32	XmtBufId;		// word 1, bits [31:0] -  transmit buffer ID
-	unsigned char	TcpStrt;		// word 2, bits [7:0] -   byte address of TCP header
-	unsigned char	IpStrt;			// word 2, bits [15:8] -  byte address of IP header
-	ushort	IpCkSum;		// word 2, bits [31:16] - partial IP checksum
-	ushort	TcpCkSum;		// word 3, bits [15:0] -  partial TCP checksum
-	ushort	Rsvd1;			// word 3, bits [31:16] - PAD
-	u32	Rsvd2;			// word 4, bits [31:0] -  PAD
-	u32	Rsvd3;			// word 5, bits [31:0] -  PAD
-	u32	Rsvd4;		    // word 6, bits [31:0] -  PAD
-	u32	Rsvd5;		    // word 7, bits [31:0] -  PAD
+struct xmt_desc {
+	ushort	        XmtLen;	    /* word 0, bits [15:0] -  transmit length */
+	/* word 0, bits [23:16] - transmit control byte */
+	unsigned char	XmtCtl;
+	/* word 0, bits [31:24] - transmit command plus misc. */
+	unsigned char	Cmd;
+	/* word 1, bits [31:0] -  transmit buffer ID */
+	u32	XmtBufId;
+	/* word 2, bits [7:0] -   byte address of TCP header */
+	unsigned char	TcpStrt;
+	/* word 2, bits [15:8] -  byte address of IP header */
+	unsigned char	IpStrt;
+	/* word 2, bits [31:16] - partial IP checksum */
+	ushort	IpCkSum;
+	/* word 3, bits [15:0] -  partial TCP checksum */
+	ushort	TcpCkSum;
+	ushort	Rsvd1;		    /* word 3, bits [31:16] - PAD */
+	u32	Rsvd2;		    /* word 4, bits [31:0] -  PAD */
+	u32	Rsvd3;		    /* word 5, bits [31:0] -  PAD */
+	u32	Rsvd4;		    /* word 6, bits [31:0] -  PAD */
+	u32	Rsvd5;		    /* word 7, bits [31:0] -  PAD */
 };
 #pragma pack(pop)
 
-// XMT_DESC Cmd byte definitions
-		// command codes
-#define XMT_DESC_CMD_RAW_SEND		0		// raw send descriptor
-#define XMT_DESC_CMD_CSUM_INSERT	1		// checksum insert descriptor
-#define XMT_DESC_CMD_FORMAT		2		// format descriptor
-#define XMT_DESC_CMD_PRIME		3		// prime descriptor
-#define XMT_DESC_CMD_CODE_SHFT		6		// comand code shift (shift to bits [31:30] in word 0)
-		// shifted command codes
-#define XMT_RAW_SEND		(XMT_DESC_CMD_RAW_SEND    << XMT_DESC_CMD_CODE_SHFT)
-#define XMT_CSUM_INSERT		(XMT_DESC_CMD_CSUM_INSERT << XMT_DESC_CMD_CODE_SHFT)
-#define XMT_FORMAT			(XMT_DESC_CMD_FORMAT      << XMT_DESC_CMD_CODE_SHFT)
-#define XMT_PRIME			(XMT_DESC_CMD_PRIME       << XMT_DESC_CMD_CODE_SHFT)
+/* struct xmt_desc Cmd byte definitions */
+		/* command codes */
+#define XMT_DESC_CMD_RAW_SEND		0	/* raw send descriptor */
+#define XMT_DESC_CMD_CSUM_INSERT	1	/* checksum insert descriptor */
+#define XMT_DESC_CMD_FORMAT		2	/* format descriptor */
+#define XMT_DESC_CMD_PRIME		3	/* prime descriptor */
+/* comand code shift (shift to bits [31:30] in word 0) */
+#define XMT_DESC_CMD_CODE_SHFT		6
+		/* shifted command codes */
+#define XMT_RAW_SEND	(XMT_DESC_CMD_RAW_SEND    << XMT_DESC_CMD_CODE_SHFT)
+#define XMT_CSUM_INSERT	(XMT_DESC_CMD_CSUM_INSERT << XMT_DESC_CMD_CODE_SHFT)
+#define XMT_FORMAT	(XMT_DESC_CMD_FORMAT      << XMT_DESC_CMD_CODE_SHFT)
+#define XMT_PRIME	(XMT_DESC_CMD_PRIME       << XMT_DESC_CMD_CODE_SHFT)
 
-// XMT_DESC Control Byte (XmtCtl) definitions
-// NOTE:  These bits do not work on Sahara (Rev A)!
-#define	XMT_CTL_PAUSE_FRAME		0x80	// current frame is a pause control frame (for statistics)
-#define	XMT_CTL_CONTROL_FRAME		0x40	// current frame is a control frame (for statistics)
-#define	XMT_CTL_PER_PKT_QUAL		0x20	// per packet qualifier
-#define	XMT_CTL_PAD_MODE_NONE		0x00	// do not pad frame
-#define	XMT_CTL_PAD_MODE_64		0x08	// pad frame to 64 bytes
-#define	XMT_CTL_PAD_MODE_VLAN_68	0x10	// pad frame to 64 bytes, and VLAN frames to 68 bytes
-#define	XMT_CTL_PAD_MODE_68		0x18	// pad frame to 68 bytes
-#define	XMT_CTL_GEN_FCS			0x04	// generate FCS (CRC) for this frame
-#define	XMT_CTL_DELAY_FCS_0		0x00	// do not delay FCS calcution
-#define	XMT_CTL_DELAY_FCS_1		0x01	// delay FCS calculation by 1 (4-byte) word
-#define	XMT_CTL_DELAY_FCS_2		0x02	// delay FCS calculation by 2 (4-byte) words
-#define	XMT_CTL_DELAY_FCS_3		0x03	// delay FCS calculation by 3 (4-byte) words
+/*
+ * struct xmt_desc Control Byte (XmtCtl) definitions
+ * NOTE:  These bits do not work on Sahara (Rev A)!
+ */
+/* current frame is a pause control frame (for statistics) */
+#define	XMT_CTL_PAUSE_FRAME		0x80
+/* current frame is a control frame (for statistics) */
+#define	XMT_CTL_CONTROL_FRAME		0x40
+#define	XMT_CTL_PER_PKT_QUAL		0x20	/* per packet qualifier */
+#define	XMT_CTL_PAD_MODE_NONE		0x00	/* do not pad frame */
+#define	XMT_CTL_PAD_MODE_64		0x08	/* pad frame to 64 bytes */
+/* pad frame to 64 bytes, and VLAN frames to 68 bytes */
+#define	XMT_CTL_PAD_MODE_VLAN_68	0x10
+#define	XMT_CTL_PAD_MODE_68		0x18	/* pad frame to 68 bytes */
+/* generate FCS (CRC) for this frame */
+#define	XMT_CTL_GEN_FCS			0x04
+#define	XMT_CTL_DELAY_FCS_0		0x00	/* do not delay FCS calcution */
+/* delay FCS calculation by 1 (4-byte) word */
+#define	XMT_CTL_DELAY_FCS_1		0x01
+/* delay FCS calculation by 2 (4-byte) words */
+#define	XMT_CTL_DELAY_FCS_2		0x02
+/* delay FCS calculation by 3 (4-byte) words */
+#define	XMT_CTL_DELAY_FCS_3		0x03
 
-// XMT_DESC XmtBufId definition
-#define XMT_BUF_ID_SHFT		8	// The Xmt buffer ID is formed by dividing
-					// the buffer (DRAM) address by 256 (or << 8)
+/* struct xmt_desc XmtBufId definition */
+/*
+ * The Xmt buffer ID is formed by dividing the buffer (DRAM) address
+ * by 256 (or << 8)
+ */
 
-/*****************************************************************************
- * Receiver Sequencer Definitions
- *****************************************************************************/
+#define XMT_BUF_ID_SHFT		8
 
-// Receive Event Queue (queues 3 - 6) bit definitions
-#define	RCV_EVTQ_RBFID_MASK		0x0000FFFF	// bit mask for the Receive Buffer ID
+/* Receiver Sequencer Definitions */
 
-// Receive Buffer ID definition
-#define RCV_BUF_ID_SHFT		5	// The Rcv buffer ID is formed by dividing
-					// the buffer (DRAM) address by 32 (or << 5)
+/* Receive Event Queue (queues 3 - 6) bit definitions */
+/* bit mask for the Receive Buffer ID */
+#define	RCV_EVTQ_RBFID_MASK	0x0000FFFF
 
-// Format of the 18 byte Receive Buffer returned by the
-// Receive Sequencer for received packets
+/* Receive Buffer ID definition */
+/*
+ * The Rcv buffer ID is formed by dividing the buffer (DRAM) address
+ * by 32 (or << 5)
+ */
+#define RCV_BUF_ID_SHFT		5
+
+/*
+ * Format of the 18 byte Receive Buffer returned by the
+ * Receive Sequencer for received packets
+ */
 #pragma pack(push, 1)
-struct RCV_BUF_HDR {
-	u32	Status;				// Status word from Rcv Seq Parser
-	ushort	Length;				// Rcv packet byte count
+struct rcv_buf_hdr {
+	u32	Status;		/* Status word from Rcv Seq Parser */
+	ushort	Length;		/* Rcv packet byte count */
 	union {
-		ushort		TcpCsum;	// TCP checksum
+		ushort		TcpCsum;	/* TCP checksum */
 		struct {
-			unsigned char	TcpCsumL;	// lower 8 bits of the TCP checksum
-			unsigned char	LinkHash;	// Link hash (multicast frames only)
+			/* lower 8 bits of the TCP checksum */
+			unsigned char	TcpCsumL;
+			/* Link hash (multicast frames only) */
+			unsigned char	LinkHash;
 		};
 	};
-	ushort	SktHash;			// Socket hash
-	unsigned char	TcpHdrOffset;		// TCP header offset into packet
-	unsigned char	IpHdrOffset;		// IP header offset into packet
-	u32	TpzHash;			// Toeplitz hash
-	ushort	Reserved;			// Reserved
+	ushort	SktHash;		/* Socket hash */
+	unsigned char	TcpHdrOffset;	/* TCP header offset into packet */
+	unsigned char	IpHdrOffset;	/* IP header offset into packet */
+	u32	       	TpzHash;	/* Toeplitz hash */
+	ushort	        Reserved;	/* Reserved */
 };
 #pragma pack(pop)
 
-
-/*****************************************************************************
- * Queue definitions
- *****************************************************************************/
+/* Queue definitions */
 
 /* Ingress (read only) queue numbers */
-#define PXY_BUF_Q		0		/* Proxy Buffer Queue */
-#define HST_EVT_Q		1		/* Host Event Queue */
-#define XMT_BUF_Q		2		/* Transmit Buffer Queue */
-#define SKT_EVL_Q		3		/* RcvSqr Socket Event Low Priority Queue */
-#define RCV_EVL_Q		4		/* RcvSqr Rcv Event Low Priority Queue */
-#define SKT_EVH_Q		5		/* RcvSqr Socket Event High Priority Queue */
-#define RCV_EVH_Q		6		/* RcvSqr Rcv Event High Priority Queue */
-#define DMA_RSP_Q		7		/* Dma Response Queue - one per CPU context */
+#define PXY_BUF_Q	0	/* Proxy Buffer Queue */
+#define HST_EVT_Q	1	/* Host Event Queue */
+#define XMT_BUF_Q	2	/* Transmit Buffer Queue */
+#define SKT_EVL_Q	3	/* RcvSqr Socket Event Low Priority Queue */
+#define RCV_EVL_Q	4	/* RcvSqr Rcv Event Low Priority Queue */
+#define SKT_EVH_Q	5	/* RcvSqr Socket Event High Priority Queue */
+#define RCV_EVH_Q	6	/* RcvSqr Rcv Event High Priority Queue */
+#define DMA_RSP_Q	7	/* Dma Response Queue - one per CPU context */
 /* Local (read/write) queue numbers */
-#define LOCAL_A_Q		8		/* Spare local Queue */
-#define LOCAL_B_Q		9		/* Spare local Queue */
-#define LOCAL_C_Q		10		/* Spare local Queue */
-#define FSM_EVT_Q		11		/* Finite-State-Machine Event Queue */
-#define SBF_PAL_Q		12		/* System Buffer Physical Address (low) Queue */
-#define SBF_PAH_Q		13		/* System Buffer Physical Address (high) Queue */
-#define SBF_VAL_Q		14		/* System Buffer Virtual Address (low) Queue */
-#define SBF_VAH_Q		15		/* System Buffer Virtual Address (high) Queue */
+#define LOCAL_A_Q	8	/* Spare local Queue */
+#define LOCAL_B_Q	9	/* Spare local Queue */
+#define LOCAL_C_Q	10	/* Spare local Queue */
+#define FSM_EVT_Q	11	/* Finite-State-Machine Event Queue */
+#define SBF_PAL_Q	12	/* System Buffer Physical Address (low) Queue */
+#define SBF_PAH_Q	13	/* System Buffer Physical Address (high) Queue*/
+#define SBF_VAL_Q	14	/* System Buffer Virtual Address (low) Queue */
+#define SBF_VAH_Q	15	/* System Buffer Virtual Address (high) Queue */
 /* Egress (write only) queue numbers */
-#define H2G_CMD_Q		16		/* Host to GlbRam DMA Command Queue */
-#define H2D_CMD_Q		17		/* Host to DRAM DMA Command Queue */
-#define G2H_CMD_Q		18		/* GlbRam to Host DMA Command Queue */
-#define G2D_CMD_Q		19		/* GlbRam to DRAM DMA Command Queue */
-#define D2H_CMD_Q		20		/* DRAM to Host DMA Command Queue */
-#define D2G_CMD_Q		21		/* DRAM to GlbRam DMA Command Queue */
-#define D2D_CMD_Q		22		/* DRAM to DRAM DMA Command Queue */
-#define PXL_CMD_Q		23		/* Low Priority Proxy Command Queue */
-#define PXH_CMD_Q		24		/* High Priority Proxy Command Queue */
-#define RSQ_CMD_Q		25		/* Receive Sequencer Command Queue */
-#define RCV_BUF_Q		26		/* Receive Buffer Queue */
+#define H2G_CMD_Q	16	/* Host to GlbRam DMA Command Queue */
+#define H2D_CMD_Q	17	/* Host to DRAM DMA Command Queue */
+#define G2H_CMD_Q	18	/* GlbRam to Host DMA Command Queue */
+#define G2D_CMD_Q	19	/* GlbRam to DRAM DMA Command Queue */
+#define D2H_CMD_Q	20	/* DRAM to Host DMA Command Queue */
+#define D2G_CMD_Q	21	/* DRAM to GlbRam DMA Command Queue */
+#define D2D_CMD_Q	22	/* DRAM to DRAM DMA Command Queue */
+#define PXL_CMD_Q	23	/* Low Priority Proxy Command Queue */
+#define PXH_CMD_Q	24	/* High Priority Proxy Command Queue */
+#define RSQ_CMD_Q	25	/* Receive Sequencer Command Queue */
+#define RCV_BUF_Q	26	/* Receive Buffer Queue */
 
 /* Bit definitions for the Proxy Command queues (PXL_CMD_Q and PXH_CMD_Q) */
-#define PXY_COPY_EN		0x00200000		/* enable copy of xmt descriptor to xmt command queue */
-#define PXY_SIZE_16		0x00000000		/* copy 16 bytes */
-#define PXY_SIZE_32		0x00100000		/* copy 32 bytes */
+/* enable copy of xmt descriptor to xmt command queue */
+#define PXY_COPY_EN	0x00200000
+#define PXY_SIZE_16	0x00000000	/* copy 16 bytes */
+#define PXY_SIZE_32	0x00100000	/* copy 32 bytes */
 
-/*****************************************************************************
- * SXG EEPROM/Flash Configuration Definitions
- *****************************************************************************/
+/* SXG EEPROM/Flash Configuration Definitions */
+
+/* Location of configuration data in EEPROM or Flash */
+/* start addr for config info in EEPROM */
+#define	EEPROM_CONFIG_START_ADDR	0x00
+/* start addr for config info in Flash */
+#define	FLASH_CONFIG_START_ADDR		0x80
+
+/* Configuration data section defines */
+#define	HW_CFG_SECTION_SIZE	512	/* size of H/W section */
+#define	HW_CFG_SECTION_SIZE_A	256	/* size of H/W section (Sahara rev A) */
+/* starting location (offset) of S/W section */
+#define	SW_CFG_SECTION_START	512
+/* starting location (offset) of S/W section (Sahara rev A) */
+#define	SW_CFG_SECTION_START_A	256
+#define	SW_CFG_SECTION_SIZE	128	/* size of S/W section */
+/*
+ * H/W configuration data magic word Goes in Addr field of first
+ * struct hw_cfg_data entry
+ */
+#define	HW_CFG_MAGIC_WORD	0xA5A5
+/*
+ * H/W configuration data terminator  Goes in Addr field of last
+ * struct hw_cfg_data entry
+ */
+#define	HW_CFG_TERMINATOR	0xFFFF
+
+#define	SW_CFG_MAGIC_WORD	0x5A5A	/* S/W configuration data magic word */
+
 #pragma pack(push, 1)
-
-/* */
-struct HW_CFG_DATA {
-	ushort		Addr;
-	union {
-		ushort	Data;
-		ushort	Checksum;
-	};
+/*
+ * Structure for an element of H/W configuration data.
+ * Read by the Sahara hardware
+ */
+struct hw_cfg_data {
+	ushort	Addr;
+	ushort	Data;
 };
 
-/* */
-#define	NUM_HW_CFG_ENTRIES	((128/sizeof(struct HW_CFG_DATA)) - 4)
+/*
+ * Number of struct hw_cfg_data structures to put in the configuration data
+ * data structure (struct sxg_config or struct sxg_config_a).  The number is
+ * computed to fill the entire H/W config section of the structure.
+ */
+#define	NUM_HW_CFG_ENTRIES						\
+			(HW_CFG_SECTION_SIZE / sizeof(struct hw_cfg_data))
+#define	NUM_HW_CFG_ENTRIES_A						\
+			(HW_CFG_SECTION_SIZE_A / sizeof(struct hw_cfg_data))
 
-/* MAC address */
-struct SXG_CONFIG_MAC {
-	unsigned char		MacAddr[6];			/* MAC Address */
+/* MAC address structure */
+struct sxg_config_mac {
+	unsigned char	MacAddr[6];	/* MAC Address */
 };
 
-/* */
-struct ATK_FRU {
+/* FRU data structure */
+struct atk_fru {
 	unsigned char		PartNum[6];
 	unsigned char		Revision[2];
 	unsigned char		Serial[14];
@@ -697,38 +909,112 @@
 #define EMC_FRU_FORMAT		0x0005
 #define NO_FRU_FORMAT		0xFFFF
 
-/* EEPROM/Flash Format */
-struct SXG_CONFIG {
-	/* */
-	/* Section 1 (128 bytes) */
-	/* */
-	ushort			MagicWord;			/* EEPROM/FLASH Magic code 'A5A5' */
-	ushort			SpiClks;			/* SPI bus clock dividers */
-	struct HW_CFG_DATA		HwCfg[NUM_HW_CFG_ENTRIES];
-	/* */
-	/* */
-	/* */
-	ushort			Version;			/* EEPROM format version */
-	struct SXG_CONFIG_MAC	MacAddr[4];			/* space for 4 MAC addresses */
-	struct ATK_FRU			AtkFru;				/* FRU information */
-	ushort			OemFruFormat;		/* OEM FRU format type */
-	unsigned char			OemFru[76];			/* OEM FRU information (optional) */
-	ushort			Checksum;			/* Checksum of section 2 */
-	/* CS info XXXTODO */
+#define	ATK_OEM_ASSY_SIZE	10	/* assy num is 9 chars plus \0 */
+
+/* OEM FRU structure for Alacritech */
+struct atk_oem {
+	unsigned char Assy[ATK_OEM_ASSY_SIZE];
 };
+
+#define	OEM_EEPROM_FRUSIZE	74	/* size of OEM fru info - size */
+/* chosen to fill out the S/W section */
+
+union oem_fru {			/* OEM FRU information */
+	unsigned char OemFru[OEM_EEPROM_FRUSIZE];
+	struct atk_oem AtkOem;
+};
+
+/* Structure to hold the S/W configuration data. */
+struct sw_cfg_data {
+	ushort			MagicWord;	/* Magic word for section 2 */
+	ushort			Version;	/* Format version */
+	struct sxg_config_mac	MacAddr[4];	/* space for 4 MAC addresses */
+	struct atk_fru		AtkFru;		/* FRU information */
+	ushort			OemFruFormat;	/* OEM FRU format type */
+	union oem_fru		OemFru;		/* OEM FRU information */
+	ushort			Checksum;	/* Checksum of section 2 */
+};
+
+
+/* EEPROM/Flash Format */
+struct sxg_config {
+	/* H/W Section - Read by Sahara hardware (512 bytes) */
+	struct hw_cfg_data		HwCfg[NUM_HW_CFG_ENTRIES];
+	/* S/W Section - Other configuration data (128 bytes) */
+	struct sw_cfg_data	SwCfg;
+};
+
+#ifdef WINDOWS_COMPILER
+/*
+ *  The following macro is something of a kludge, but it is the only way
+ * that I could find to catch certain programming errors at compile time.
+ * If the asserted condition is true, then nothing happens.  If false, then
+ * the compiler tries to typedef an array with -1 members, which generates
+ * an error.  Unfortunately, the error message is meaningless, but at least
+ * it catches the problem.  This macro would be unnecessary if the compiler
+ * allowed the sizeof and offsetof macros to be used in the #if directive.
+ */
+#define compile_time_assert(cond) \
+    typedef char comp_error[(cond) ? 1 : -1]
+
+/*
+ * A compiler error on either of the next two lines indicates that the struct sxg_config
+ * structure was built incorrectly.  Unfortunately, the error message produced
+ * is meaningless.  But this is apparently the only way to catch this problem
+ * at compile time.
+ */
+compile_time_assert (offsetof(struct sxg_config, SwCfg) == SW_CFG_SECTION_START);
+compile_time_assert (sizeof(struct sxg_config) == HW_CFG_SECTION_SIZE
+							+ SW_CFG_SECTION_SIZE);
+
+compile_time_assert (offsetof(struct sxg_config_a, SwCfg)
+						 == SW_CFG_SECTION_START_A);
+compile_time_assert (sizeof(struct sxg_config_a) == HW_CFG_SECTION_SIZE_A
+						 + SW_CFG_SECTION_SIZE);
+#endif
+/*
+ * Structure used to pass information between driver and user-mode
+ * control application
+ */
+struct adapt_userinfo {
+	bool		    LinkUp;
+	/* use LinkUp - any need for other states? */
+	/* u32  	    LinkState; */
+	u32 		    LinkSpeed;		/* not currently needed */
+	u32 		    LinkDuplex;		/* not currently needed */
+ 	enum xcvr_type	    XcvrType;		/* type of xcvr on fiber card */
+	/* fiber card xcvr vendor */
+	unsigned char		XcvrVendor[XCVR_VENDOR_LEN];
+	unsigned char		XcvrMode[XCVR_MODEL_LEN];
+	u32 		    Port;		/* not currently needed */
+	u32 		    PhysPort;		/* not currently needed */
+	ushort		    PciLanes;
+	unsigned char	MacAddr[6];
+	unsigned char   CurrMacAddr[6];
+	struct atk_fru	    AtkFru;
+	ushort  	    OemFruFormat;
+	union oem_fru	    OemFru;
+};
+
 #pragma pack(pop)
 
-/*****************************************************************************
- * Miscellaneous Hardware definitions
- *****************************************************************************/
+/* Miscellaneous Hardware definitions */
 
-// Sahara (ASIC level) defines
-#define SAHARA_GRAM_SIZE		0x020000		// GRAM size - 128 KB
-#define SAHARA_DRAM_SIZE		0x200000		// DRAM size - 2 MB
-#define SAHARA_QRAM_SIZE		0x004000		// QRAM size - 16K entries (64 KB)
-#define SAHARA_WCS_SIZE			0x002000		// WCS - 8K instructions (x 108 bits)
+/* Hardware Type definitions  */
 
-// Arabia (board level) defines
-#define	FLASH_SIZE			0x080000		// 512 KB (4 Mb)
-#define	EEPROM_SIZE_XFMR		512			// true EEPROM size (bytes), including xfmr area
-#define	EEPROM_SIZE_NO_XFMR		256			// EEPROM size excluding xfmr area
+/* Sahara (ASIC level) defines */
+#define SAHARA_GRAM_SIZE	0x020000	/* GRAM size - 128 KB */
+#define SAHARA_DRAM_SIZE	0x200000	/* DRAM size - 2 MB */
+/* QRAM size - 16K entries (64 KB) */
+#define SAHARA_QRAM_SIZE	0x004000
+/* WCS - 8K instructions (x 108 bits) */
+#define SAHARA_WCS_SIZE		0x002000
+
+/* Arabia (board level) defines */
+#define	FLASH_SIZE		0x080000	/* 512 KB (4 Mb) */
+/* EEPROM size (bytes), including xfmr area */
+#define	EEPROM_SIZE_XFMR	1024
+/* EEPROM size excluding xfmr area (512 + 128) */
+#define	EEPROM_SIZE_NO_XFMR	640
+/* EEPROM size for Sahara rev A */
+#define	EEPROM_SIZE_REV_A	512
diff --git a/drivers/staging/sxg/sxgphycode-1.2.h b/drivers/staging/sxg/sxgphycode-1.2.h
new file mode 100644
index 0000000..b5448b9
--- /dev/null
+++ b/drivers/staging/sxg/sxgphycode-1.2.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright ? 1997-2008 Alacritech, Inc. All rights reserved
+ *
+ * $Id: sxgphycode.h,v 1.2 2008/10/02 01:44:07 Exp $
+ *
+ * sxgphycode.h:
+ *
+ * This file PHY microcode and register initialization data.
+ */
+
+/**********************************************************************
+ * PHY Microcode
+ **********************************************************************/
+//
+// The following contains both PHY microcode and PHY register
+// initialization data.  It is specific to both the PHY and the
+// type of transceiver.
+//
+
+// Download for AEL2005C PHY with SR/LR transceiver (10GBASE-SR or 10GBASE-LR)
+// AEL2005 SR firmware rev 18 (microInit_mdio_SR_AEL2005C_18.tx).
+static struct phy_ucode	PhyUcode[] = {
+	// NOTE:  An address of 0 is a special case.  When the download routine
+	// sees an address of 0, it does not write to the PHY.  Instead, it delays
+	// the download.  The length of the delay (in ms) is given in the data field.
+	// Delays are required at certain points.
+
+	// Platform-specific MDIO Patches:
+	// (include patches for 10G RX polarity flip, 50Mhz Synth, etc)
+	// Addr		Data
+	{0xc017,	0xfeb0},	// flip RX_LOS polarity (mandatory patch for SFP+ applications)
+	{0xC001,	0x0428},	// flip RX serial polarity
+
+	{0xc013,	0xf341},	// invert lxmit clock (mandatory patch)
+	{0xc210,	0x8000},	// reset datapath (mandatory patch)
+	{0xc210,	0x8100},	// reset datapath (mandatory patch)
+	{0xc210,	0x8000},	// reset datapath (mandatory patch)
+	{0xc210,	0x0000},	// reset datapath (mandatory patch)
+	{0x0000,	0x0032},	// wait for 50ms for datapath reset to complete. (mandatory patch)
+
+	// Transceiver-specific MDIO Patches:
+	{0xc003,	0x0181},	// (bit 7) enable the CDR inc setting in 1.C005 (mandatory patch for SR code)
+	{0xc010,	0x448a},	// (bit 14) mask out high BER input from the LOS signal in 1.000A (mandatory patch for SR code)
+
+	// Transceiver-specific Microcontroller Initialization:
+	{0xc04a,	0x5200},	// activate microcontroller and pause
+	{0x0000,	0x0032},	// wait 50ms for microcontroller before writing in code.
+
+	// code block starts here:
+	{0xcc00,	0x2ff4},	{0xcc01,	0x3cd4},	{0xcc02,	0x2015},	{0xcc03,	0x3125},
+	{0xcc04,	0x6524},	{0xcc05,	0x27ff},	{0xcc06,	0x300f},	{0xcc07,	0x2c8b},
+	{0xcc08,	0x300b},	{0xcc09,	0x4009},	{0xcc0a,	0x400e},	{0xcc0b,	0x2f12},
+	{0xcc0c,	0x3002},	{0xcc0d,	0x1002},	{0xcc0e,	0x2112},	{0xcc0f,	0x3012},
+	{0xcc10,	0x1002},	{0xcc11,	0x2572},	{0xcc12,	0x3012},	{0xcc13,	0x1002},
+	{0xcc14,	0xd01e},	{0xcc15,	0x2772},	{0xcc16,	0x3012},	{0xcc17,	0x1002},
+	{0xcc18,	0x2004},	{0xcc19,	0x3c84},	{0xcc1a,	0x6436},	{0xcc1b,	0x2007},
+	{0xcc1c,	0x3f87},	{0xcc1d,	0x8676},	{0xcc1e,	0x40b7},	{0xcc1f,	0xa746},
+	{0xcc20,	0x4047},	{0xcc21,	0x5673},	{0xcc22,	0x2982},	{0xcc23,	0x3002},
+	{0xcc24,	0x13d2},	{0xcc25,	0x8bbd},	{0xcc26,	0x2802},	{0xcc27,	0x3012},
+	{0xcc28,	0x1002},	{0xcc29,	0x2032},	{0xcc2a,	0x3012},	{0xcc2b,	0x1002},
+	{0xcc2c,	0x5cc3},	{0xcc2d,	0x0314},	{0xcc2e,	0x2942},	{0xcc2f,	0x3002},
+	{0xcc30,	0x1002},	{0xcc31,	0xd019},	{0xcc32,	0x2fd2},	{0xcc33,	0x3002},
+	{0xcc34,	0x1002},	{0xcc35,	0x2a04},	{0xcc36,	0x3c74},	{0xcc37,	0x6435},
+	{0xcc38,	0x2fa4},	{0xcc39,	0x3cd4},	{0xcc3a,	0x6624},	{0xcc3b,	0x5563},
+	{0xcc3c,	0x2d42},	{0xcc3d,	0x3002},	{0xcc3e,	0x13d2},	{0xcc3f,	0x464d},
+	{0xcc40,	0x2802},	{0xcc41,	0x3012},	{0xcc42,	0x1002},	{0xcc43,	0x2fd2},
+	{0xcc44,	0x3002},	{0xcc45,	0x1002},	{0xcc46,	0x2fb4},	{0xcc47,	0x3cd4},
+	{0xcc48,	0x6624},	{0xcc49,	0x5563},	{0xcc4a,	0x2d42},	{0xcc4b,	0x3002},
+	{0xcc4c,	0x13d2},	{0xcc4d,	0x2e72},	{0xcc4e,	0x3002},	{0xcc4f,	0x1002},
+	{0xcc50,	0x2f72},	{0xcc51,	0x3002},	{0xcc52,	0x1002},	{0xcc53,	0x0004},
+	{0xcc54,	0x2942},	{0xcc55,	0x3002},	{0xcc56,	0x1002},	{0xcc57,	0x2032},
+	{0xcc58,	0x3012},	{0xcc59,	0x1002},	{0xcc5a,	0x5cc3},	{0xcc5b,	0x0317},
+	{0xcc5c,	0x2f12},	{0xcc5d,	0x3002},	{0xcc5e,	0x1002},	{0xcc5f,	0x2942},
+	{0xcc60,	0x3002},	{0xcc61,	0x1002},	{0xcc62,	0x22cd},	{0xcc63,	0x301d},
+	{0xcc64,	0x2802},	{0xcc65,	0x3012},	{0xcc66,	0x1002},	{0xcc67,	0x20b2},
+	{0xcc68,	0x3012},	{0xcc69,	0x1002},	{0xcc6a,	0x5aa3},	{0xcc6b,	0x2dc2},
+	{0xcc6c,	0x3002},	{0xcc6d,	0x1312},	{0xcc6e,	0x2d02},	{0xcc6f,	0x3002},
+	{0xcc70,	0x1002},	{0xcc71,	0x2807},	{0xcc72,	0x31a7},	{0xcc73,	0x20c4},
+	{0xcc74,	0x3c24},	{0xcc75,	0x6724},	{0xcc76,	0x1002},	{0xcc77,	0x2807},
+	{0xcc78,	0x3187},	{0xcc79,	0x20c4},	{0xcc7a,	0x3c24},	{0xcc7b,	0x6724},
+	{0xcc7c,	0x1002},	{0xcc7d,	0x2514},	{0xcc7e,	0x3c64},	{0xcc7f,	0x6436},
+	{0xcc80,	0xdff4},	{0xcc81,	0x6436},	{0xcc82,	0x1002},	{0xcc83,	0x40a4},
+	{0xcc84,	0x643c},	{0xcc85,	0x4016},	{0xcc86,	0x8c6c},	{0xcc87,	0x2b24},
+	{0xcc88,	0x3c24},	{0xcc89,	0x6435},	{0xcc8a,	0x1002},	{0xcc8b,	0x2b24},
+	{0xcc8c,	0x3c24},	{0xcc8d,	0x643a},	{0xcc8e,	0x4025},	{0xcc8f,	0x8a5a},
+	{0xcc90,	0x1002},	{0xcc91,	0x26d1},	{0xcc92,	0x3011},	{0xcc93,	0x1001},
+	{0xcc94,	0xc7a0},	{0xcc95,	0x0100},	{0xcc96,	0xc502},	{0xcc97,	0x53ac},
+	{0xcc98,	0xc503},	{0xcc99,	0xd5d5},	{0xcc9a,	0xc600},	{0xcc9b,	0x2a6d},
+	{0xcc9c,	0xc601},	{0xcc9d,	0x2a4c},	{0xcc9e,	0xc602},	{0xcc9f,	0x0111},
+	{0xcca0,	0xc60c},	{0xcca1,	0x5900},	{0xcca2,	0xc710},	{0xcca3,	0x0700},
+	{0xcca4,	0xc718},	{0xcca5,	0x0700},	{0xcca6,	0xc720},	{0xcca7,	0x4700},
+	{0xcca8,	0xc801},	{0xcca9,	0x7f50},	{0xccaa,	0xc802},	{0xccab,	0x7760},
+	{0xccac,	0xc803},	{0xccad,	0x7fce},	{0xccae,	0xc804},	{0xccaf,	0x5700},
+	{0xccb0,	0xc805},	{0xccb1,	0x5f11},	{0xccb2,	0xc806},	{0xccb3,	0x4751},
+	{0xccb4,	0xc807},	{0xccb5,	0x57e1},	{0xccb6,	0xc808},	{0xccb7,	0x2700},
+	{0xccb8,	0xc809},	{0xccb9,	0x0000},	{0xccba,	0xc821},	{0xccbb,	0x0002},
+	{0xccbc,	0xc822},	{0xccbd,	0x0014},	{0xccbe,	0xc832},	{0xccbf,	0x1186},
+	{0xccc0,	0xc847},	{0xccc1,	0x1e02},	{0xccc2,	0xc013},	{0xccc3,	0xf341},
+	{0xccc4,	0xc01a},	{0xccc5,	0x0446},	{0xccc6,	0xc024},	{0xccc7,	0x1000},
+	{0xccc8,	0xc025},	{0xccc9,	0x0a00},	{0xccca,	0xc026},	{0xcccb,	0x0c0c},
+	{0xcccc,	0xc027},	{0xcccd,	0x0c0c},	{0xccce,	0xc029},	{0xcccf,	0x00a0},
+	{0xccd0,	0xc030},	{0xccd1,	0x0a00},	{0xccd2,	0xc03c},	{0xccd3,	0x001c},
+	{0xccd4,	0xc005},	{0xccd5,	0x7a06},	{0xccd6,	0x0000},	{0xccd7,	0x26d1},
+	{0xccd8,	0x3011},	{0xccd9,	0x1001},	{0xccda,	0xc620},	{0xccdb,	0x0000},
+	{0xccdc,	0xc621},	{0xccdd,	0x003f},	{0xccde,	0xc622},	{0xccdf,	0x0000},
+	{0xcce0,	0xc623},	{0xcce1,	0x0000},	{0xcce2,	0xc624},	{0xcce3,	0x0000},
+	{0xcce4,	0xc625},	{0xcce5,	0x0000},	{0xcce6,	0xc627},	{0xcce7,	0x0000},
+	{0xcce8,	0xc628},	{0xcce9,	0x0000},	{0xccea,	0xc62c},	{0xcceb,	0x0000},
+	{0xccec,	0x0000},	{0xcced,	0x2806},	{0xccee,	0x3cb6},	{0xccef,	0xc161},
+	{0xccf0,	0x6134},	{0xccf1,	0x6135},	{0xccf2,	0x5443},	{0xccf3,	0x0303},
+	{0xccf4,	0x6524},	{0xccf5,	0x000b},	{0xccf6,	0x1002},	{0xccf7,	0x2104},
+	{0xccf8,	0x3c24},	{0xccf9,	0x2105},	{0xccfa,	0x3805},	{0xccfb,	0x6524},
+	{0xccfc,	0xdff4},	{0xccfd,	0x4005},	{0xccfe,	0x6524},	{0xccff,	0x1002},
+	{0xcd00,	0x5dd3},	{0xcd01,	0x0306},	{0xcd02,	0x2ff7},	{0xcd03,	0x38f7},
+	{0xcd04,	0x60b7},	{0xcd05,	0xdffd},	{0xcd06,	0x000a},	{0xcd07,	0x1002},
+	{0xcd08,	0x0000},
+	// end of code block
+
+	// Unpause the microcontroller to start program
+	{0xca00,	0x0080},
+	{0xca12,	0x0000},
+	{0x0000,	0x000A},	// wait 10ms just to be safe
+
+	// Configure the LED's
+	{0xc214,	0x0099},	// configure the LED drivers (for Sahara rev B)
+	{0xc216,	0x0400},	// configure the one LED
+	{0xc217,	0x0000},	// don't drive the 2nd LED (if it exists)
+
+	{0xffff,	0xffff}		// table terminator
+};
diff --git a/drivers/staging/sxg/sxgphycode.h b/drivers/staging/sxg/sxgphycode.h
deleted file mode 100644
index 167f356e..0000000
--- a/drivers/staging/sxg/sxgphycode.h
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * Copyright (C) 1997-2008 Alacritech, Inc. All rights reserved
- *
- * sxgphycode.h:
- *
- * This file PHY microcode and register initialization data.
- */
-
-/**********************************************************************
- * PHY Microcode
- *
- * The following contains both PHY microcode and PHY register
- * initialization data.  It is specific to both the PHY and the
- * type of transceiver.
- *
- **********************************************************************/
-
-/*
- * Download for AEL2005C PHY with SR/LR transceiver (10GBASE-SR or 10GBASE-LR)
- */
-static struct PHY_UCODE PhyUcode[] = {
-	/*
-	 * NOTE:  An address of 0 is a special case.  When the download routine
-	 * sees an address of 0, it does not write to the PHY.  Instead, it
-	 * delays the download.  The length of the delay (in ms) is given in
-	 * the data field.
-	 *
-	 * Delays are required at certain points.
-	 */
-
-	/*
-	 * Platform-specific MDIO Patches:
-	 * (include patches for 10G RX polarity flip, 50Mhz Synth, etc)
-	 */
-	/* Addr, Data */
-	{0xc017, 0xfeb0},	/* flip RX_LOS polarity (mandatory */
-	/*  patch for SFP+ applications) */
-	{0xC001, 0x0428},	/* flip RX serial polarity */
-
-	{0xc013, 0xf341},	/* invert lxmit clock (mandatory patch) */
-	{0xc210, 0x8000},	/* reset datapath (mandatory patch) */
-	{0xc210, 0x8100},	/* reset datapath (mandatory patch) */
-	{0xc210, 0x8000},	/* reset datapath (mandatory patch) */
-	{0xc210, 0x0000},	/* reset datapath (mandatory patch) */
-	{0x0000, 0x0032},	/* wait for 50ms for datapath reset to */
-	/* complete. (mandatory patch) */
-
-	/* Configure the LED's */
-	{0xc214, 0x0099},	/* configure the LED drivers */
-	{0xc216, 0x5f5f},	/* configure the Activity LED */
-	{0xc217, 0x33ff},	/* configure the Link LED */
-
-	/* Transceiver-specific MDIO Patches: */
-	{0xc010, 0x448a},	/* (bit 14) mask out high BER input from the */
-	/* LOS signal in 1.000A */
-	/* (mandatory patch for SR code) */
-	{0xc003, 0x0181},	/* (bit 7) enable the CDR inc setting in */
-	/* 1.C005 (mandatory patch for SR code) */
-
-	/* Transceiver-specific Microcontroller Initialization: */
-	{0xc04a, 0x5200},	/* activate microcontroller and pause */
-	{0x0000, 0x0032},	/* wait 50ms for microcontroller before */
-	/* writing in code. */
-
-	/* code block starts here: */
-	{0xcc00, 0x2009},
-	{0xcc01, 0x3009},
-	{0xcc02, 0x27ff},
-	{0xcc03, 0x300f},
-	{0xcc04, 0x200c},
-	{0xcc05, 0x300c},
-	{0xcc06, 0x20c4},
-	{0xcc07, 0x3c04},
-	{0xcc08, 0x6437},
-	{0xcc09, 0x20c4},
-	{0xcc0a, 0x3c04},
-	{0xcc0b, 0x6437},
-	{0xcc0c, 0x25c4},
-	{0xcc0d, 0x3c54},
-	{0xcc0e, 0x6724},
-	{0xcc0f, 0x25c4},
-	{0xcc10, 0x3c54},
-	{0xcc11, 0x6724},
-	{0xcc12, 0x2042},
-	{0xcc13, 0x3012},
-	{0xcc14, 0x1002},
-	{0xcc15, 0x2482},
-	{0xcc16, 0x3012},
-	{0xcc17, 0x1002},
-	{0xcc18, 0x2a32},
-	{0xcc19, 0x3002},
-	{0xcc1a, 0x1002},
-	{0xcc1b, 0x200d},
-	{0xcc1c, 0x304d},
-	{0xcc1d, 0x2862},
-	{0xcc1e, 0x3012},
-	{0xcc1f, 0x1002},
-	{0xcc20, 0x2982},
-	{0xcc21, 0x3002},
-	{0xcc22, 0x1002},
-	{0xcc23, 0x628f},
-	{0xcc24, 0x20a4},
-	{0xcc25, 0x3004},
-	{0xcc26, 0x6438},
-	{0xcc27, 0x20a4},
-	{0xcc28, 0x3004},
-	{0xcc29, 0x6438},
-	{0xcc2a, 0x2015},
-	{0xcc2b, 0x3005},
-	{0xcc2c, 0x5853},
-	{0xcc2d, 0x2bd2},
-	{0xcc2e, 0x3002},
-	{0xcc2f, 0x1342},
-	{0xcc30, 0x200c},
-	{0xcc31, 0x300c},
-	{0xcc32, 0x2ff7},
-	{0xcc33, 0x30f7},
-	{0xcc34, 0x20c4},
-	{0xcc35, 0x3c04},
-	{0xcc36, 0x6724},
-	{0xcc37, 0x20c4},
-	{0xcc38, 0x3c04},
-	{0xcc39, 0x6724},
-	{0xcc3a, 0x2d32},
-	{0xcc3b, 0x3002},
-	{0xcc3c, 0x1002},
-	{0xcc3d, 0x2008},
-	{0xcc3e, 0x3008},
-	{0xcc3f, 0x5c83},
-	{0xcc40, 0x2d52},
-	{0xcc41, 0x3002},
-	{0xcc42, 0x1352},
-	{0xcc43, 0x2008},
-	{0xcc44, 0x3008},
-	{0xcc45, 0x5c83},
-	{0xcc46, 0x2d32},
-	{0xcc47, 0x3002},
-	{0xcc48, 0x1352},
-	{0xcc49, 0x201c},
-	{0xcc4a, 0x300c},
-	{0xcc4b, 0x200d},
-	{0xcc4c, 0x310d},
-	{0xcc4d, 0x2862},
-	{0xcc4e, 0x3012},
-	{0xcc4f, 0x1002},
-	{0xcc50, 0x2ed2},
-	{0xcc51, 0x3002},
-	{0xcc52, 0x1342},
-	{0xcc53, 0x6f72},
-	{0xcc54, 0x1002},
-	{0xcc55, 0x628f},
-	{0xcc56, 0x2514},
-	{0xcc57, 0x3c64},
-	{0xcc58, 0x6436},
-	{0xcc59, 0x2514},
-	{0xcc5a, 0x3c64},
-	{0xcc5b, 0x6436},
-	{0xcc5c, 0x2fa4},
-	{0xcc5d, 0x3cd4},
-	{0xcc5e, 0x6624},
-	{0xcc5f, 0x2fa4},
-	{0xcc60, 0x3cd4},
-	{0xcc61, 0x6624},
-	{0xcc62, 0x2f45},
-	{0xcc63, 0x3015},
-	{0xcc64, 0x5653},
-	{0xcc65, 0x2eb2},
-	{0xcc66, 0x3002},
-	{0xcc67, 0x13d2},
-	{0xcc68, 0x2ed2},
-	{0xcc69, 0x3002},
-	{0xcc6a, 0x1002},
-	{0xcc6b, 0x6f72},
-	{0xcc6c, 0x1002},
-	{0xcc6d, 0x628f},
-	{0xcc6e, 0x2602},
-	{0xcc6f, 0x3012},
-	{0xcc70, 0x1002},
-	{0xcc71, 0x200d},
-	{0xcc72, 0x320d},
-	{0xcc73, 0x2862},
-	{0xcc74, 0x3012},
-	{0xcc75, 0x1002},
-	{0xcc76, 0x25c4},
-	{0xcc77, 0x3c54},
-	{0xcc78, 0x6437},
-	{0xcc79, 0x25c4},
-	{0xcc7a, 0x3c54},
-	{0xcc7b, 0x6437},
-	{0xcc7c, 0x20c4},
-	{0xcc7d, 0x3c04},
-	{0xcc7e, 0x6724},
-	{0xcc7f, 0x20c4},
-	{0xcc80, 0x3c04},
-	{0xcc81, 0x6724},
-	{0xcc82, 0x6f72},
-	{0xcc83, 0x1002},
-	{0xcc84, 0x628f},
-	{0xcc85, 0x26f2},
-	{0xcc86, 0x3012},
-	{0xcc87, 0x1002},
-	{0xcc88, 0xc503},
-	{0xcc89, 0xd5d5},
-	{0xcc8a, 0xc600},
-	{0xcc8b, 0x2a6d},
-	{0xcc8c, 0xc601},
-	{0xcc8d, 0x2a4c},
-	{0xcc8e, 0xc602},
-	{0xcc8f, 0x0111},
-	{0xcc90, 0xc60c},
-	{0xcc91, 0x5900},
-	{0xcc92, 0xc710},
-	{0xcc93, 0x0700},
-	{0xcc94, 0xc718},
-	{0xcc95, 0x0700},
-	{0xcc96, 0xc720},
-	{0xcc97, 0x4700},
-	{0xcc98, 0xc801},
-	{0xcc99, 0x7f50},
-	{0xcc9a, 0xc802},
-	{0xcc9b, 0x7760},
-	{0xcc9c, 0xc803},
-	{0xcc9d, 0x7fce},
-	{0xcc9e, 0xc804},
-	{0xcc9f, 0x5700},
-	{0xcca0, 0xc805},
-	{0xcca1, 0x5f11},
-	{0xcca2, 0xc806},
-	{0xcca3, 0x4751},
-	{0xcca4, 0xc807},
-	{0xcca5, 0x57e1},
-	{0xcca6, 0xc808},
-	{0xcca7, 0x2700},
-	{0xcca8, 0xc809},
-	{0xcca9, 0x0000},
-	{0xccaa, 0xc821},
-	{0xccab, 0x0002},
-	{0xccac, 0xc822},
-	{0xccad, 0x0014},
-	{0xccae, 0xc832},
-	{0xccaf, 0x1186},
-	{0xccb0, 0xc847},
-	{0xccb1, 0x1e02},
-	{0xccb2, 0xc013},
-	{0xccb3, 0xf341},
-	{0xccb4, 0xc01a},
-	{0xccb5, 0x0446},
-	{0xccb6, 0xc024},
-	{0xccb7, 0x1000},
-	{0xccb8, 0xc025},
-	{0xccb9, 0x0a00},
-	{0xccba, 0xc026},
-	{0xccbb, 0x0c0c},
-	{0xccbc, 0xc027},
-	{0xccbd, 0x0c0c},
-	{0xccbe, 0xc029},
-	{0xccbf, 0x00a0},
-	{0xccc0, 0xc030},
-	{0xccc1, 0x0a00},
-	{0xccc2, 0xc03c},
-	{0xccc3, 0x001c},
-	{0xccc4, 0xc005},
-	{0xccc5, 0x7a06},
-	{0xccc6, 0x0000},
-	{0xccc7, 0x0000},
-	{0xccc8, 0x628f},
-	{0xccc9, 0x26f2},
-	{0xccca, 0x3012},
-	{0xcccb, 0x1002},
-	{0xcccc, 0xc620},
-	{0xcccd, 0x0000},
-	{0xccce, 0xc621},
-	{0xcccf, 0x003f},
-	{0xccd0, 0xc622},
-	{0xccd1, 0x0000},
-	{0xccd2, 0xc623},
-	{0xccd3, 0x0000},
-	{0xccd4, 0xc624},
-	{0xccd5, 0x0000},
-	{0xccd6, 0xc625},
-	{0xccd7, 0x0000},
-	{0xccd8, 0xc627},
-	{0xccd9, 0x0000},
-	{0xccda, 0xc628},
-	{0xccdb, 0x0000},
-	{0xccdc, 0xc62c},
-	{0xccdd, 0x0000},
-	{0xccde, 0x0000},
-	{0xccdf, 0x0000},
-	{0xcce0, 0x628f},
-	{0xcce1, 0xd019},
-	{0xcce2, 0x26f2},
-	{0xcce3, 0x3012},
-	{0xcce4, 0x1002},
-	{0xcce5, 0xc210},
-	{0xcce6, 0x8000},
-	{0xcce7, 0xc210},
-	{0xcce8, 0x8010},
-	{0xcce9, 0xc210},
-	{0xccea, 0x8000},
-	{0xcceb, 0xc210},
-	{0xccec, 0x0000},
-	{0xcced, 0x0000},
-	{0xccee, 0x0000},
-	{0xccef, 0x8221},
-	{0xccf0, 0x2752},
-	{0xccf1, 0x3012},
-	{0xccf2, 0x1002},
-	{0xccf3, 0x6f72},
-	{0xccf4, 0x1002},
-	{0xccf5, 0x2806},
-	{0xccf6, 0x3006},
-	{0xccf7, 0x2007},
-	{0xccf8, 0x3cc7},
-	{0xccf9, 0xe161},
-	{0xccfa, 0xc171},
-	{0xccfb, 0x6134},
-	{0xccfc, 0x6135},
-	{0xccfd, 0x5453},
-	{0xccfe, 0x2858},
-	{0xccff, 0x3018},
-	{0xcd00, 0x1348},
-	{0xcd01, 0x6524},
-	{0xcd02, 0x27b8},
-	{0xcd03, 0x3018},
-	{0xcd04, 0x1008},
-	{0xcd05, 0x1002},
-	{0xcd06, 0x628f},
-	{0xcd07, 0x5dd3},
-	{0xcd08, 0x2906},
-	{0xcd09, 0x3016},
-	{0xcd0a, 0x1306},
-	{0xcd0b, 0x2ff7},
-	{0xcd0c, 0x30f7},
-	{0xcd0d, 0x60b7},
-	{0xcd0e, 0xdffd},
-	{0xcd0f, 0x0008},
-	{0xcd10, 0x6f72},
-	{0xcd11, 0x1002},
-	{0xcd12, 0x0000},
-	{0xcdff, 0x0a01},
-	/* end of code block */
-
-	/* Unpause the microcontroller to start program */
-	{0xca00, 0x0080},
-	{0xca12, 0x0000},
-	{0x0000, 0x000A},	/* wait 10ms just to be safe */
-	{0xffff, 0xffff}	/* table terminator */
-};
diff --git a/drivers/staging/uc2322/Kconfig b/drivers/staging/uc2322/Kconfig
new file mode 100644
index 0000000..2e0c6e79
--- /dev/null
+++ b/drivers/staging/uc2322/Kconfig
@@ -0,0 +1,10 @@
+config USB_SERIAL_ATEN2011
+	tristate "ATEN 2011 USB to serial device support"
+	depends on USB_SERIAL
+	default N
+	---help---
+	  Say Y here if you want to use a ATEN 2011 dual port USB to serial
+	  adapter.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called aten2011.
diff --git a/drivers/staging/uc2322/Makefile b/drivers/staging/uc2322/Makefile
new file mode 100644
index 0000000..49c18d6
--- /dev/null
+++ b/drivers/staging/uc2322/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_USB_SERIAL_ATEN2011)	+= aten2011.o
diff --git a/drivers/staging/uc2322/TODO b/drivers/staging/uc2322/TODO
new file mode 100644
index 0000000..c189a64
--- /dev/null
+++ b/drivers/staging/uc2322/TODO
@@ -0,0 +1,7 @@
+TODO:
+	- checkpatch.pl cleanups
+	- remove dead and useless code (auditing the tty ioctls to
+	  verify that they really are correct and needed.)
+
+Please send any patches to Greg Kroah-Hartman <greg@kroah.com> and
+Russell Lang <gsview@ghostgum.com.au>.
diff --git a/drivers/staging/uc2322/aten2011.c b/drivers/staging/uc2322/aten2011.c
new file mode 100644
index 0000000..85b7054
--- /dev/null
+++ b/drivers/staging/uc2322/aten2011.c
@@ -0,0 +1,2452 @@
+/*
+ * Aten 2011 USB serial driver for 4 port devices
+ *
+ * Copyright (C) 2000 Inside Out Networks
+ * Copyright (C) 2001-2002, 2009 Greg Kroah-Hartman <greg@kroah.com>
+ * Copyright (C) 2009 Novell 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 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/module.h>
+#include <linux/serial.h>
+#include <linux/uaccess.h>
+#include <linux/usb.h>
+#include <linux/usb/serial.h>
+
+
+#define ZLP_REG1		0x3A	/* Zero_Flag_Reg1 58 */
+#define ZLP_REG2		0x3B	/* Zero_Flag_Reg2 59 */
+#define ZLP_REG3		0x3C	/* Zero_Flag_Reg3 60 */
+#define ZLP_REG4		0x3D	/* Zero_Flag_Reg4 61 */
+#define ZLP_REG5		0x3E	/* Zero_Flag_Reg5 62 */
+
+/* Interrupt Rotinue Defines	*/
+#define SERIAL_IIR_RLS		0x06
+#define SERIAL_IIR_RDA		0x04
+#define SERIAL_IIR_CTI		0x0c
+#define SERIAL_IIR_THR		0x02
+#define SERIAL_IIR_MS		0x00
+
+/* Emulation of the bit mask on the LINE STATUS REGISTER.  */
+#define SERIAL_LSR_DR		0x0001
+#define SERIAL_LSR_OE		0x0002
+#define SERIAL_LSR_PE		0x0004
+#define SERIAL_LSR_FE		0x0008
+#define SERIAL_LSR_BI		0x0010
+#define SERIAL_LSR_THRE		0x0020
+#define SERIAL_LSR_TEMT		0x0040
+#define SERIAL_LSR_FIFOERR	0x0080
+
+/* MSR bit defines(place holders) */
+#define ATEN_MSR_DELTA_CTS	0x10
+#define ATEN_MSR_DELTA_DSR	0x20
+#define ATEN_MSR_DELTA_RI	0x40
+#define ATEN_MSR_DELTA_CD	0x80
+
+/* Serial Port register Address */
+#define RECEIVE_BUFFER_REGISTER		((__u16)(0x00))
+#define TRANSMIT_HOLDING_REGISTER	((__u16)(0x00))
+#define INTERRUPT_ENABLE_REGISTER	((__u16)(0x01))
+#define INTERRUPT_IDENT_REGISTER	((__u16)(0x02))
+#define FIFO_CONTROL_REGISTER		((__u16)(0x02))
+#define LINE_CONTROL_REGISTER		((__u16)(0x03))
+#define MODEM_CONTROL_REGISTER		((__u16)(0x04))
+#define LINE_STATUS_REGISTER		((__u16)(0x05))
+#define MODEM_STATUS_REGISTER		((__u16)(0x06))
+#define SCRATCH_PAD_REGISTER		((__u16)(0x07))
+#define DIVISOR_LATCH_LSB		((__u16)(0x00))
+#define DIVISOR_LATCH_MSB		((__u16)(0x01))
+
+#define SP1_REGISTER			((__u16)(0x00))
+#define CONTROL1_REGISTER		((__u16)(0x01))
+#define CLK_MULTI_REGISTER		((__u16)(0x02))
+#define CLK_START_VALUE_REGISTER	((__u16)(0x03))
+#define DCR1_REGISTER			((__u16)(0x04))
+#define GPIO_REGISTER			((__u16)(0x07))
+
+#define SERIAL_LCR_DLAB			((__u16)(0x0080))
+
+/*
+ * URB POOL related defines
+ */
+#define NUM_URBS			16	/* URB Count */
+#define URB_TRANSFER_BUFFER_SIZE	32	/* URB Size  */
+
+#define USB_VENDOR_ID_ATENINTL		0x0557
+#define ATENINTL_DEVICE_ID_2011		0x2011
+#define ATENINTL_DEVICE_ID_7820		0x7820
+
+static struct usb_device_id id_table[] = {
+	{ USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_2011) },
+	{ USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_7820) },
+	{ } /* terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+/* This structure holds all of the local port information */
+struct ATENINTL_port {
+	int		port_num;          /*Actual port number in the device(1,2,etc)*/
+	__u8		bulk_out_endpoint;   	/* the bulk out endpoint handle */
+	unsigned char	*bulk_out_buffer;     	/* buffer used for the bulk out endpoint */
+	struct urb	*write_urb;	     	/* write URB for this port */
+	__u8		bulk_in_endpoint;	/* the bulk in endpoint handle */
+	unsigned char	*bulk_in_buffer;	/* the buffer we use for the bulk in endpoint */
+	struct urb	*read_urb;	     	/* read URB for this port */
+	__u8		shadowLCR;		/* last LCR value received */
+	__u8		shadowMCR;		/* last MCR value received */
+	char		open;
+	char		chaseResponsePending;
+	wait_queue_head_t	wait_chase;		/* for handling sleeping while waiting for chase to finish */
+	wait_queue_head_t	wait_command;		/* for handling sleeping while waiting for command to finish */
+	struct async_icount	icount;
+	struct usb_serial_port	*port;			/* loop back to the owner of this object */
+	/*Offsets*/
+	__u8		SpRegOffset;
+	__u8		ControlRegOffset;
+	__u8		DcrRegOffset;
+	/* for processing control URBS in interrupt context */
+	struct urb 	*control_urb;
+	char		*ctrl_buf;
+	int		MsrLsr;
+
+	struct urb	*write_urb_pool[NUM_URBS];
+	/* we pass a pointer to this as the arguement sent to cypress_set_termios old_termios */
+	struct ktermios	tmp_termios;        /* stores the old termios settings */
+	spinlock_t 	lock;                   /* private lock */
+};
+
+/* This structure holds all of the individual serial device information */
+struct ATENINTL_serial {
+	__u8		interrupt_in_endpoint;		/* the interrupt endpoint handle */
+	unsigned char	*interrupt_in_buffer;		/* the buffer we use for the interrupt endpoint */
+	struct urb	*interrupt_read_urb;	/* our interrupt urb */
+	__u8		bulk_in_endpoint;	/* the bulk in endpoint handle */
+	unsigned char	*bulk_in_buffer;		/* the buffer we use for the bulk in endpoint */
+	struct urb 	*read_urb;		/* our bulk read urb */
+	__u8		bulk_out_endpoint;	/* the bulk out endpoint handle */
+	struct usb_serial	*serial;	/* loop back to the owner of this object */
+	int	ATEN2011_spectrum_2or4ports; 	/* this says the number of ports in the device */
+	/* Indicates about the no.of opened ports of an individual USB-serial adapater. */
+	unsigned int	NoOfOpenPorts;
+	/* a flag for Status endpoint polling */
+	unsigned char	status_polling_started;
+};
+
+static void ATEN2011_set_termios(struct tty_struct *tty,
+				 struct usb_serial_port *port,
+				 struct ktermios *old_termios);
+static void ATEN2011_change_port_settings(struct tty_struct *tty,
+					  struct ATENINTL_port *ATEN2011_port,
+					  struct ktermios *old_termios);
+
+/*************************************
+ * Bit definitions for each register *
+ *************************************/
+#define LCR_BITS_5		0x00	/* 5 bits/char */
+#define LCR_BITS_6		0x01	/* 6 bits/char */
+#define LCR_BITS_7		0x02	/* 7 bits/char */
+#define LCR_BITS_8		0x03	/* 8 bits/char */
+#define LCR_BITS_MASK		0x03	/* Mask for bits/char field */
+
+#define LCR_STOP_1		0x00	/* 1 stop bit */
+#define LCR_STOP_1_5		0x04	/* 1.5 stop bits (if 5   bits/char) */
+#define LCR_STOP_2		0x04	/* 2 stop bits   (if 6-8 bits/char) */
+#define LCR_STOP_MASK		0x04	/* Mask for stop bits field */
+
+#define LCR_PAR_NONE		0x00	/* No parity */
+#define LCR_PAR_ODD		0x08	/* Odd parity */
+#define LCR_PAR_EVEN		0x18	/* Even parity */
+#define LCR_PAR_MARK		0x28	/* Force parity bit to 1 */
+#define LCR_PAR_SPACE		0x38	/* Force parity bit to 0 */
+#define LCR_PAR_MASK		0x38	/* Mask for parity field */
+
+#define LCR_SET_BREAK		0x40	/* Set Break condition */
+#define LCR_DL_ENABLE		0x80	/* Enable access to divisor latch */
+
+#define MCR_DTR			0x01	/* Assert DTR */
+#define MCR_RTS			0x02	/* Assert RTS */
+#define MCR_OUT1		0x04	/* Loopback only: Sets state of RI */
+#define MCR_MASTER_IE		0x08	/* Enable interrupt outputs */
+#define MCR_LOOPBACK		0x10	/* Set internal (digital) loopback mode */
+#define MCR_XON_ANY		0x20	/* Enable any char to exit XOFF mode */
+
+#define ATEN2011_MSR_CTS	0x10	/* Current state of CTS */
+#define ATEN2011_MSR_DSR	0x20	/* Current state of DSR */
+#define ATEN2011_MSR_RI		0x40	/* Current state of RI */
+#define ATEN2011_MSR_CD		0x80	/* Current state of CD */
+
+
+static int debug;
+
+/*
+ * Version Information
+ */
+#define DRIVER_VERSION "2.0"
+#define DRIVER_DESC "ATENINTL 2011 USB Serial Adapter"
+
+/*
+ * Defines used for sending commands to port
+ */
+
+#define ATEN_WDR_TIMEOUT	(50)	/* default urb timeout */
+
+/* Requests */
+#define ATEN_RD_RTYPE		0xC0
+#define ATEN_WR_RTYPE		0x40
+#define ATEN_RDREQ		0x0D
+#define ATEN_WRREQ		0x0E
+#define ATEN_CTRL_TIMEOUT	500
+#define VENDOR_READ_LENGTH	(0x01)
+
+/* set to 1 for RS485 mode and 0 for RS232 mode */
+/* FIXME make this somehow dynamic and not build time specific */
+static int RS485mode;
+
+static int set_reg_sync(struct usb_serial_port *port, __u16 reg, __u16 val)
+{
+	struct usb_device *dev = port->serial->dev;
+	val = val & 0x00ff;
+
+	dbg("%s: is %x, value %x", __func__, reg, val);
+
+	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ATEN_WRREQ,
+			       ATEN_WR_RTYPE, val, reg, NULL, 0,
+			       ATEN_WDR_TIMEOUT);
+}
+
+static int get_reg_sync(struct usb_serial_port *port, __u16 reg, __u16 *val)
+{
+	struct usb_device *dev = port->serial->dev;
+	int ret;
+
+	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ATEN_RDREQ,
+			      ATEN_RD_RTYPE, 0, reg, val, VENDOR_READ_LENGTH,
+			      ATEN_WDR_TIMEOUT);
+	dbg("%s: offset is %x, return val %x", __func__, reg, *val);
+	*val = (*val) & 0x00ff;
+	return ret;
+}
+
+static int set_uart_reg(struct usb_serial_port *port, __u16 reg, __u16 val)
+{
+	struct usb_device *dev = port->serial->dev;
+	struct ATENINTL_serial *a_serial;
+	__u16 minor;
+
+	a_serial = usb_get_serial_data(port->serial);
+	minor = port->serial->minor;
+	if (minor == SERIAL_TTY_NO_MINOR)
+		minor = 0;
+	val = val & 0x00ff;
+
+	/*
+	 * For the UART control registers,
+	 * the application number need to be Or'ed
+	 */
+	if (a_serial->ATEN2011_spectrum_2or4ports == 4)
+		val |= (((__u16)port->number - minor) + 1) << 8;
+	else {
+		if (((__u16) port->number - minor) == 0)
+			val |= (((__u16)port->number - minor) + 1) << 8;
+		else
+			val |= (((__u16)port->number - minor) + 2) << 8;
+	}
+	dbg("%s: application number is %x", __func__, val);
+
+	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ATEN_WRREQ,
+			       ATEN_WR_RTYPE, val, reg, NULL, 0,
+			       ATEN_WDR_TIMEOUT);
+}
+
+static int get_uart_reg(struct usb_serial_port *port, __u16 reg, __u16 *val)
+{
+	struct usb_device *dev = port->serial->dev;
+	int ret = 0;
+	__u16 wval;
+	struct ATENINTL_serial *a_serial;
+	__u16 minor = port->serial->minor;
+
+	a_serial = usb_get_serial_data(port->serial);
+	if (minor == SERIAL_TTY_NO_MINOR)
+		minor = 0;
+
+	/* wval is same as application number */
+	if (a_serial->ATEN2011_spectrum_2or4ports == 4)
+		wval = (((__u16)port->number - minor) + 1) << 8;
+	else {
+		if (((__u16) port->number - minor) == 0)
+			wval = (((__u16) port->number - minor) + 1) << 8;
+		else
+			wval = (((__u16) port->number - minor) + 2) << 8;
+	}
+	dbg("%s: application number is %x", __func__, wval);
+	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ATEN_RDREQ,
+			      ATEN_RD_RTYPE, wval, reg, val, VENDOR_READ_LENGTH,
+			      ATEN_WDR_TIMEOUT);
+	*val = (*val) & 0x00ff;
+	return ret;
+}
+
+static int handle_newMsr(struct ATENINTL_port *port, __u8 newMsr)
+{
+	struct ATENINTL_port *ATEN2011_port;
+	struct async_icount *icount;
+	ATEN2011_port = port;
+	icount = &ATEN2011_port->icount;
+	if (newMsr &
+	    (ATEN_MSR_DELTA_CTS | ATEN_MSR_DELTA_DSR | ATEN_MSR_DELTA_RI |
+	     ATEN_MSR_DELTA_CD)) {
+		icount = &ATEN2011_port->icount;
+
+		/* update input line counters */
+		if (newMsr & ATEN_MSR_DELTA_CTS)
+			icount->cts++;
+		if (newMsr & ATEN_MSR_DELTA_DSR)
+			icount->dsr++;
+		if (newMsr & ATEN_MSR_DELTA_CD)
+			icount->dcd++;
+		if (newMsr & ATEN_MSR_DELTA_RI)
+			icount->rng++;
+	}
+
+	return 0;
+}
+
+static int handle_newLsr(struct ATENINTL_port *port, __u8 newLsr)
+{
+	struct async_icount *icount;
+
+	dbg("%s - %02x", __func__, newLsr);
+
+	if (newLsr & SERIAL_LSR_BI) {
+		/*
+		 * Parity and Framing errors only count if they occur exclusive
+		 * of a break being received.
+		 */
+		newLsr &= (__u8) (SERIAL_LSR_OE | SERIAL_LSR_BI);
+	}
+
+	/* update input line counters */
+	icount = &port->icount;
+	if (newLsr & SERIAL_LSR_BI)
+		icount->brk++;
+	if (newLsr & SERIAL_LSR_OE)
+		icount->overrun++;
+	if (newLsr & SERIAL_LSR_PE)
+		icount->parity++;
+	if (newLsr & SERIAL_LSR_FE)
+		icount->frame++;
+
+	return 0;
+}
+
+static void ATEN2011_control_callback(struct urb *urb)
+{
+	unsigned char *data;
+	struct ATENINTL_port *ATEN2011_port;
+	__u8 regval = 0x0;
+
+	switch (urb->status) {
+	case 0:
+		/* success */
+		break;
+	case -ECONNRESET:
+	case -ENOENT:
+	case -ESHUTDOWN:
+		/* this urb is terminated, clean up */
+		dbg("%s - urb shutting down with status: %d", __func__,
+		    urb->status);
+		return;
+	default:
+		dbg("%s - nonzero urb status received: %d", __func__,
+		    urb->status);
+		goto exit;
+	}
+
+	ATEN2011_port = (struct ATENINTL_port *)urb->context;
+
+	dbg("%s urb buffer size is %d", __func__, urb->actual_length);
+	dbg("%s ATEN2011_port->MsrLsr is %d port %d", __func__,
+		ATEN2011_port->MsrLsr, ATEN2011_port->port_num);
+	data = urb->transfer_buffer;
+	regval = (__u8) data[0];
+	dbg("%s data is %x", __func__, regval);
+	if (ATEN2011_port->MsrLsr == 0)
+		handle_newMsr(ATEN2011_port, regval);
+	else if (ATEN2011_port->MsrLsr == 1)
+		handle_newLsr(ATEN2011_port, regval);
+
+exit:
+	return;
+}
+
+static int ATEN2011_get_reg(struct ATENINTL_port *ATEN, __u16 Wval, __u16 reg,
+			    __u16 *val)
+{
+	struct usb_device *dev = ATEN->port->serial->dev;
+	struct usb_ctrlrequest *dr = NULL;
+	unsigned char *buffer = NULL;
+	int ret = 0;
+	buffer = (__u8 *) ATEN->ctrl_buf;
+
+	dr = (void *)(buffer + 2);
+	dr->bRequestType = ATEN_RD_RTYPE;
+	dr->bRequest = ATEN_RDREQ;
+	dr->wValue = cpu_to_le16(Wval);
+	dr->wIndex = cpu_to_le16(reg);
+	dr->wLength = cpu_to_le16(2);
+
+	usb_fill_control_urb(ATEN->control_urb, dev, usb_rcvctrlpipe(dev, 0),
+			     (unsigned char *)dr, buffer, 2,
+			     ATEN2011_control_callback, ATEN);
+	ATEN->control_urb->transfer_buffer_length = 2;
+	ret = usb_submit_urb(ATEN->control_urb, GFP_ATOMIC);
+	return ret;
+}
+
+static void ATEN2011_interrupt_callback(struct urb *urb)
+{
+	int result;
+	int length;
+	struct ATENINTL_port *ATEN2011_port;
+	struct ATENINTL_serial *ATEN2011_serial;
+	struct usb_serial *serial;
+	__u16 Data;
+	unsigned char *data;
+	__u8 sp[5], st;
+	int i;
+	__u16 wval;
+	int minor;
+
+	dbg("%s", " : Entering");
+
+	ATEN2011_serial = (struct ATENINTL_serial *)urb->context;
+
+	switch (urb->status) {
+	case 0:
+		/* success */
+		break;
+	case -ECONNRESET:
+	case -ENOENT:
+	case -ESHUTDOWN:
+		/* this urb is terminated, clean up */
+		dbg("%s - urb shutting down with status: %d", __func__,
+		    urb->status);
+		return;
+	default:
+		dbg("%s - nonzero urb status received: %d", __func__,
+		    urb->status);
+		goto exit;
+	}
+	length = urb->actual_length;
+	data = urb->transfer_buffer;
+
+	serial = ATEN2011_serial->serial;
+
+	/* ATENINTL get 5 bytes
+	 * Byte 1 IIR Port 1 (port.number is 0)
+	 * Byte 2 IIR Port 2 (port.number is 1)
+	 * Byte 3 IIR Port 3 (port.number is 2)
+	 * Byte 4 IIR Port 4 (port.number is 3)
+	 * Byte 5 FIFO status for both */
+
+	if (length && length > 5) {
+		dbg("%s", "Wrong data !!!");
+		return;
+	}
+
+	/* MATRIX */
+	if (ATEN2011_serial->ATEN2011_spectrum_2or4ports == 4) {
+		sp[0] = (__u8) data[0];
+		sp[1] = (__u8) data[1];
+		sp[2] = (__u8) data[2];
+		sp[3] = (__u8) data[3];
+		st = (__u8) data[4];
+	} else {
+		sp[0] = (__u8) data[0];
+		sp[1] = (__u8) data[2];
+		/* sp[2]=(__u8)data[2]; */
+		/* sp[3]=(__u8)data[3]; */
+		st = (__u8) data[4];
+
+	}
+	for (i = 0; i < serial->num_ports; i++) {
+		ATEN2011_port = usb_get_serial_port_data(serial->port[i]);
+		minor = serial->minor;
+		if (minor == SERIAL_TTY_NO_MINOR)
+			minor = 0;
+		if ((ATEN2011_serial->ATEN2011_spectrum_2or4ports == 2)
+		    && (i != 0))
+			wval =
+			    (((__u16) serial->port[i]->number -
+			      (__u16) (minor)) + 2) << 8;
+		else
+			wval =
+			    (((__u16) serial->port[i]->number -
+			      (__u16) (minor)) + 1) << 8;
+		if (ATEN2011_port->open != 0) {
+			if (sp[i] & 0x01) {
+				dbg("SP%d No Interrupt !!!", i);
+			} else {
+				switch (sp[i] & 0x0f) {
+				case SERIAL_IIR_RLS:
+					dbg("Serial Port %d: Receiver status error or address bit detected in 9-bit mode", i);
+					ATEN2011_port->MsrLsr = 1;
+					ATEN2011_get_reg(ATEN2011_port, wval,
+							 LINE_STATUS_REGISTER,
+							 &Data);
+					break;
+				case SERIAL_IIR_MS:
+					dbg("Serial Port %d: Modem status change", i);
+					ATEN2011_port->MsrLsr = 0;
+					ATEN2011_get_reg(ATEN2011_port, wval,
+							 MODEM_STATUS_REGISTER,
+							 &Data);
+					break;
+				}
+			}
+		}
+
+	}
+exit:
+	if (ATEN2011_serial->status_polling_started == 0)
+		return;
+
+	result = usb_submit_urb(urb, GFP_ATOMIC);
+	if (result) {
+		dev_err(&urb->dev->dev,
+			"%s - Error %d submitting interrupt urb\n",
+			__func__, result);
+	}
+
+	return;
+}
+
+static void ATEN2011_bulk_in_callback(struct urb *urb)
+{
+	int status;
+	unsigned char *data;
+	struct usb_serial *serial;
+	struct usb_serial_port *port;
+	struct ATENINTL_serial *ATEN2011_serial;
+	struct ATENINTL_port *ATEN2011_port;
+	struct tty_struct *tty;
+
+	if (urb->status) {
+		dbg("nonzero read bulk status received: %d", urb->status);
+		return;
+	}
+
+	ATEN2011_port = (struct ATENINTL_port *)urb->context;
+
+	port = (struct usb_serial_port *)ATEN2011_port->port;
+	serial = port->serial;
+
+	dbg("%s", "Entering...");
+
+	data = urb->transfer_buffer;
+	ATEN2011_serial = usb_get_serial_data(serial);
+
+	if (urb->actual_length) {
+		tty = tty_port_tty_get(&ATEN2011_port->port->port);
+		if (tty) {
+			tty_buffer_request_room(tty, urb->actual_length);
+			tty_insert_flip_string(tty, data, urb->actual_length);
+			tty_flip_buffer_push(tty);
+			tty_kref_put(tty);
+		}
+
+		ATEN2011_port->icount.rx += urb->actual_length;
+		dbg("ATEN2011_port->icount.rx is %d:",
+			ATEN2011_port->icount.rx);
+	}
+
+	if (!ATEN2011_port->read_urb) {
+		dbg("%s", "URB KILLED !!!");
+		return;
+	}
+
+	if (ATEN2011_port->read_urb->status != -EINPROGRESS) {
+		ATEN2011_port->read_urb->dev = serial->dev;
+
+		status = usb_submit_urb(ATEN2011_port->read_urb, GFP_ATOMIC);
+		if (status)
+			dbg("usb_submit_urb(read bulk) failed, status = %d", status);
+	}
+}
+
+static void ATEN2011_bulk_out_data_callback(struct urb *urb)
+{
+	struct ATENINTL_port *ATEN2011_port;
+	struct tty_struct *tty;
+
+	if (urb->status) {
+		dbg("nonzero write bulk status received:%d", urb->status);
+		return;
+	}
+
+	ATEN2011_port = (struct ATENINTL_port *)urb->context;
+
+	dbg("%s", "Entering .........");
+
+	tty = tty_port_tty_get(&ATEN2011_port->port->port);
+
+	if (tty && ATEN2011_port->open) {
+		/* tell the tty driver that something has changed */
+		wake_up_interruptible(&tty->write_wait);
+	}
+
+	/* schedule_work(&ATEN2011_port->port->work); */
+	tty_kref_put(tty);
+
+}
+
+#ifdef ATENSerialProbe
+static int ATEN2011_serial_probe(struct usb_serial *serial,
+				 const struct usb_device_id *id)
+{
+
+	/*need to implement the mode_reg reading and updating\
+	   structures usb_serial_ device_type\
+	   (i.e num_ports, num_bulkin,bulkout etc) */
+	/* Also we can update the changes  attach */
+	return 1;
+}
+#endif
+
+static int ATEN2011_open(struct tty_struct *tty, struct usb_serial_port *port,
+			 struct file *filp)
+{
+	int response;
+	int j;
+	struct usb_serial *serial;
+	struct urb *urb;
+	__u16 Data;
+	int status;
+	struct ATENINTL_serial *ATEN2011_serial;
+	struct ATENINTL_port *ATEN2011_port;
+	struct ktermios tmp_termios;
+	int minor;
+
+	serial = port->serial;
+
+	ATEN2011_port = usb_get_serial_port_data(port);
+
+	if (ATEN2011_port == NULL)
+		return -ENODEV;
+
+	ATEN2011_serial = usb_get_serial_data(serial);
+	if (ATEN2011_serial == NULL)
+		return -ENODEV;
+
+	/* increment the number of opened ports counter here */
+	ATEN2011_serial->NoOfOpenPorts++;
+
+	usb_clear_halt(serial->dev, port->write_urb->pipe);
+	usb_clear_halt(serial->dev, port->read_urb->pipe);
+
+	/* Initialising the write urb pool */
+	for (j = 0; j < NUM_URBS; ++j) {
+		urb = usb_alloc_urb(0, GFP_ATOMIC);
+		ATEN2011_port->write_urb_pool[j] = urb;
+
+		if (urb == NULL) {
+			err("No more urbs???");
+			continue;
+		}
+
+		urb->transfer_buffer = NULL;
+		urb->transfer_buffer =
+		    kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
+		if (!urb->transfer_buffer) {
+			err("%s-out of memory for urb buffers.", __func__);
+			continue;
+		}
+	}
+
+/*****************************************************************************
+ * Initialize ATEN2011 -- Write Init values to corresponding Registers
+ *
+ * Register Index
+ * 1 : IER
+ * 2 : FCR
+ * 3 : LCR
+ * 4 : MCR
+ *
+ * 0x08 : SP1/2 Control Reg
+ *****************************************************************************/
+
+/* NEED to check the fallowing Block */
+
+	Data = 0x0;
+	status = get_reg_sync(port, ATEN2011_port->SpRegOffset, &Data);
+	if (status < 0) {
+		dbg("Reading Spreg failed");
+		return -1;
+	}
+	Data |= 0x80;
+	status = set_reg_sync(port, ATEN2011_port->SpRegOffset, Data);
+	if (status < 0) {
+		dbg("writing Spreg failed");
+		return -1;
+	}
+
+	Data &= ~0x80;
+	status = set_reg_sync(port, ATEN2011_port->SpRegOffset, Data);
+	if (status < 0) {
+		dbg("writing Spreg failed");
+		return -1;
+	}
+
+/* End of block to be checked */
+/**************************CHECK***************************/
+
+	if (RS485mode == 0)
+		Data = 0xC0;
+	else
+		Data = 0x00;
+	status = set_uart_reg(port, SCRATCH_PAD_REGISTER, Data);
+	if (status < 0) {
+		dbg("Writing SCRATCH_PAD_REGISTER failed status-0x%x", status);
+		return -1;
+	} else
+		dbg("SCRATCH_PAD_REGISTER Writing success status%d", status);
+
+/**************************CHECK***************************/
+
+	Data = 0x0;
+	status = get_reg_sync(port, ATEN2011_port->ControlRegOffset, &Data);
+	if (status < 0) {
+		dbg("Reading Controlreg failed");
+		return -1;
+	}
+	Data |= 0x08;		/* Driver done bit */
+	Data |= 0x20;		/* rx_disable */
+	status = 0;
+	status =
+	    set_reg_sync(port, ATEN2011_port->ControlRegOffset, Data);
+	if (status < 0) {
+		dbg("writing Controlreg failed");
+		return -1;
+	}
+	/*
+	 * do register settings here
+	 * Set all regs to the device default values.
+	 * First Disable all interrupts.
+	 */
+
+	Data = 0x00;
+	status = set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
+	if (status < 0) {
+		dbg("disableing interrupts failed");
+		return -1;
+	}
+	/* Set FIFO_CONTROL_REGISTER to the default value */
+	Data = 0x00;
+	status = set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
+	if (status < 0) {
+		dbg("Writing FIFO_CONTROL_REGISTER  failed");
+		return -1;
+	}
+
+	Data = 0xcf;		/* chk */
+	status = set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
+	if (status < 0) {
+		dbg("Writing FIFO_CONTROL_REGISTER  failed");
+		return -1;
+	}
+
+	Data = 0x03;		/* LCR_BITS_8 */
+	status = set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
+	ATEN2011_port->shadowLCR = Data;
+
+	Data = 0x0b;		/* MCR_DTR|MCR_RTS|MCR_MASTER_IE */
+	status = set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+	ATEN2011_port->shadowMCR = Data;
+
+#ifdef Check
+	Data = 0x00;
+	status = get_uart_reg(port, LINE_CONTROL_REGISTER, &Data);
+	ATEN2011_port->shadowLCR = Data;
+
+	Data |= SERIAL_LCR_DLAB;	/* data latch enable in LCR 0x80 */
+	status = set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
+
+	Data = 0x0c;
+	status = set_uart_reg(port, DIVISOR_LATCH_LSB, Data);
+
+	Data = 0x0;
+	status = set_uart_reg(port, DIVISOR_LATCH_MSB, Data);
+
+	Data = 0x00;
+	status = get_uart_reg(port, LINE_CONTROL_REGISTER, &Data);
+
+/*      Data = ATEN2011_port->shadowLCR; */	/* data latch disable */
+	Data = Data & ~SERIAL_LCR_DLAB;
+	status = set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
+	ATEN2011_port->shadowLCR = Data;
+#endif
+	/* clearing Bulkin and Bulkout Fifo */
+	Data = 0x0;
+	status = get_reg_sync(port, ATEN2011_port->SpRegOffset, &Data);
+
+	Data = Data | 0x0c;
+	status = set_reg_sync(port, ATEN2011_port->SpRegOffset, Data);
+
+	Data = Data & ~0x0c;
+	status = set_reg_sync(port, ATEN2011_port->SpRegOffset, Data);
+	/* Finally enable all interrupts */
+	Data = 0x0;
+	Data = 0x0c;
+	status = set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
+
+	/* clearing rx_disable */
+	Data = 0x0;
+	status = get_reg_sync(port, ATEN2011_port->ControlRegOffset, &Data);
+	Data = Data & ~0x20;
+	status = set_reg_sync(port, ATEN2011_port->ControlRegOffset, Data);
+
+	/* rx_negate */
+	Data = 0x0;
+	status = get_reg_sync(port, ATEN2011_port->ControlRegOffset, &Data);
+	Data = Data | 0x10;
+	status = 0;
+	status = set_reg_sync(port, ATEN2011_port->ControlRegOffset, Data);
+
+	/* force low_latency on so that our tty_push actually forces *
+	 * the data through,otherwise it is scheduled, and with      *
+	 * high data rates (like with OHCI) data can get lost.       */
+
+	if (tty)
+		tty->low_latency = 1;
+	/*
+	 * Check to see if we've set up our endpoint info yet
+	 * (can't set it up in ATEN2011_startup as the structures
+	 * were not set up at that time.)
+	 */
+	if (ATEN2011_serial->NoOfOpenPorts == 1) {
+		/* start the status polling here */
+		ATEN2011_serial->status_polling_started = 1;
+		/* If not yet set, Set here */
+		ATEN2011_serial->interrupt_in_buffer =
+		    serial->port[0]->interrupt_in_buffer;
+		ATEN2011_serial->interrupt_in_endpoint =
+		    serial->port[0]->interrupt_in_endpointAddress;
+		ATEN2011_serial->interrupt_read_urb =
+		    serial->port[0]->interrupt_in_urb;
+
+		/* set up interrupt urb */
+		usb_fill_int_urb(ATEN2011_serial->interrupt_read_urb,
+				 serial->dev,
+				 usb_rcvintpipe(serial->dev,
+						ATEN2011_serial->
+						interrupt_in_endpoint),
+				 ATEN2011_serial->interrupt_in_buffer,
+				 ATEN2011_serial->interrupt_read_urb->
+				 transfer_buffer_length,
+				 ATEN2011_interrupt_callback, ATEN2011_serial,
+				 ATEN2011_serial->interrupt_read_urb->interval);
+
+		/* start interrupt read for ATEN2011               *
+		 * will continue as long as ATEN2011 is connected  */
+
+		response =
+		    usb_submit_urb(ATEN2011_serial->interrupt_read_urb,
+				   GFP_KERNEL);
+		if (response) {
+			dbg("%s - Error %d submitting interrupt urb",
+				__func__, response);
+		}
+
+	}
+
+	/*
+	 * See if we've set up our endpoint info yet
+	 * (can't set it up in ATEN2011_startup as the
+	 * structures were not set up at that time.)
+	 */
+
+	dbg("port number is %d", port->number);
+	dbg("serial number is %d", port->serial->minor);
+	dbg("Bulkin endpoint is %d", port->bulk_in_endpointAddress);
+	dbg("BulkOut endpoint is %d", port->bulk_out_endpointAddress);
+	dbg("Interrupt endpoint is %d",
+		port->interrupt_in_endpointAddress);
+	dbg("port's number in the device is %d", ATEN2011_port->port_num);
+	ATEN2011_port->bulk_in_buffer = port->bulk_in_buffer;
+	ATEN2011_port->bulk_in_endpoint = port->bulk_in_endpointAddress;
+	ATEN2011_port->read_urb = port->read_urb;
+	ATEN2011_port->bulk_out_endpoint = port->bulk_out_endpointAddress;
+
+	minor = port->serial->minor;
+	if (minor == SERIAL_TTY_NO_MINOR)
+		minor = 0;
+
+	/* set up our bulk in urb */
+	if ((ATEN2011_serial->ATEN2011_spectrum_2or4ports == 2)
+	    && (((__u16) port->number - (__u16) (minor)) != 0)) {
+		usb_fill_bulk_urb(ATEN2011_port->read_urb, serial->dev,
+				  usb_rcvbulkpipe(serial->dev,
+						  (port->
+						   bulk_in_endpointAddress +
+						   2)), port->bulk_in_buffer,
+				  ATEN2011_port->read_urb->
+				  transfer_buffer_length,
+				  ATEN2011_bulk_in_callback, ATEN2011_port);
+	} else
+		usb_fill_bulk_urb(ATEN2011_port->read_urb,
+				  serial->dev,
+				  usb_rcvbulkpipe(serial->dev,
+						  port->
+						  bulk_in_endpointAddress),
+				  port->bulk_in_buffer,
+				  ATEN2011_port->read_urb->
+				  transfer_buffer_length,
+				  ATEN2011_bulk_in_callback, ATEN2011_port);
+
+	dbg("ATEN2011_open: bulkin endpoint is %d",
+		port->bulk_in_endpointAddress);
+	response = usb_submit_urb(ATEN2011_port->read_urb, GFP_KERNEL);
+	if (response) {
+		err("%s - Error %d submitting control urb", __func__,
+		    response);
+	}
+
+	/* initialize our wait queues */
+	init_waitqueue_head(&ATEN2011_port->wait_chase);
+	init_waitqueue_head(&ATEN2011_port->wait_command);
+
+	/* initialize our icount structure */
+	memset(&(ATEN2011_port->icount), 0x00, sizeof(ATEN2011_port->icount));
+
+	/* initialize our port settings */
+	ATEN2011_port->shadowMCR = MCR_MASTER_IE;	/* Must set to enable ints! */
+	ATEN2011_port->chaseResponsePending = 0;
+	/* send a open port command */
+	ATEN2011_port->open = 1;
+	/* ATEN2011_change_port_settings(ATEN2011_port,old_termios); */
+	/* Setup termios */
+	ATEN2011_set_termios(tty, port, &tmp_termios);
+	ATEN2011_port->icount.tx = 0;
+	ATEN2011_port->icount.rx = 0;
+
+	dbg("usb_serial serial:%x       ATEN2011_port:%x\nATEN2011_serial:%x      usb_serial_port port:%x",
+	     (unsigned int)serial, (unsigned int)ATEN2011_port,
+	     (unsigned int)ATEN2011_serial, (unsigned int)port);
+
+	return 0;
+
+}
+
+static int ATEN2011_chars_in_buffer(struct tty_struct *tty)
+{
+	struct usb_serial_port *port = tty->driver_data;
+	int i;
+	int chars = 0;
+	struct ATENINTL_port *ATEN2011_port;
+
+	/* dbg("%s"," ATEN2011_chars_in_buffer:entering ..........."); */
+
+	ATEN2011_port = usb_get_serial_port_data(port);
+	if (ATEN2011_port == NULL) {
+		dbg("%s", "ATEN2011_break:leaving ...........");
+		return -1;
+	}
+
+	for (i = 0; i < NUM_URBS; ++i)
+		if (ATEN2011_port->write_urb_pool[i]->status == -EINPROGRESS)
+			chars += URB_TRANSFER_BUFFER_SIZE;
+
+	dbg("%s - returns %d", __func__, chars);
+	return chars;
+
+}
+
+static void ATEN2011_block_until_tx_empty(struct tty_struct *tty,
+					  struct ATENINTL_port *ATEN2011_port)
+{
+	int timeout = HZ / 10;
+	int wait = 30;
+	int count;
+
+	while (1) {
+		count = ATEN2011_chars_in_buffer(tty);
+
+		/* Check for Buffer status */
+		if (count <= 0)
+			return;
+
+		/* Block the thread for a while */
+		interruptible_sleep_on_timeout(&ATEN2011_port->wait_chase,
+					       timeout);
+
+		/* No activity.. count down section */
+		wait--;
+		if (wait == 0) {
+			dbg("%s - TIMEOUT", __func__);
+			return;
+		} else {
+			/* Reset timout value back to seconds */
+			wait = 30;
+		}
+	}
+}
+
+static void ATEN2011_close(struct tty_struct *tty, struct usb_serial_port *port,
+			   struct file *filp)
+{
+	struct usb_serial *serial;
+	struct ATENINTL_serial *ATEN2011_serial;
+	struct ATENINTL_port *ATEN2011_port;
+	int no_urbs;
+	__u16 Data;
+
+	dbg("%s", "ATEN2011_close:entering...");
+	serial = port->serial;
+
+	/* take the Adpater and port's private data */
+	ATEN2011_serial = usb_get_serial_data(serial);
+	ATEN2011_port = usb_get_serial_port_data(port);
+	if ((ATEN2011_serial == NULL) || (ATEN2011_port == NULL))
+		return;
+
+	if (serial->dev) {
+		/* flush and block(wait) until tx is empty */
+		ATEN2011_block_until_tx_empty(tty, ATEN2011_port);
+	}
+	/* kill the ports URB's */
+	for (no_urbs = 0; no_urbs < NUM_URBS; no_urbs++)
+		usb_kill_urb(ATEN2011_port->write_urb_pool[no_urbs]);
+	/* Freeing Write URBs */
+	for (no_urbs = 0; no_urbs < NUM_URBS; ++no_urbs) {
+		kfree(ATEN2011_port->write_urb_pool[no_urbs]->transfer_buffer);
+		usb_free_urb(ATEN2011_port->write_urb_pool[no_urbs]);
+	}
+	/* While closing port, shutdown all bulk read, write  *
+	 * and interrupt read if they exists                  */
+	if (serial->dev) {
+		if (ATEN2011_port->write_urb) {
+			dbg("%s", "Shutdown bulk write");
+			usb_kill_urb(ATEN2011_port->write_urb);
+		}
+		if (ATEN2011_port->read_urb) {
+			dbg("%s", "Shutdown bulk read");
+			usb_kill_urb(ATEN2011_port->read_urb);
+		}
+		if ((&ATEN2011_port->control_urb)) {
+			dbg("%s", "Shutdown control read");
+			/* usb_kill_urb (ATEN2011_port->control_urb); */
+
+		}
+	}
+	/* if(ATEN2011_port->ctrl_buf != NULL) */
+		/* kfree(ATEN2011_port->ctrl_buf); */
+	/* decrement the no.of open ports counter of an individual USB-serial adapter. */
+	ATEN2011_serial->NoOfOpenPorts--;
+	dbg("NoOfOpenPorts in close%d:in port%d",
+		ATEN2011_serial->NoOfOpenPorts, port->number);
+	if (ATEN2011_serial->NoOfOpenPorts == 0) {
+		/* stop the stus polling here */
+		ATEN2011_serial->status_polling_started = 0;
+		if (ATEN2011_serial->interrupt_read_urb) {
+			dbg("%s", "Shutdown interrupt_read_urb");
+			/* ATEN2011_serial->interrupt_in_buffer=NULL; */
+			/* usb_kill_urb (ATEN2011_serial->interrupt_read_urb); */
+		}
+	}
+	if (ATEN2011_port->write_urb) {
+		/* if this urb had a transfer buffer already (old tx) free it */
+		kfree(ATEN2011_port->write_urb->transfer_buffer);
+		usb_free_urb(ATEN2011_port->write_urb);
+	}
+
+	/* clear the MCR & IER */
+	Data = 0x00;
+	set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+	Data = 0x00;
+	set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
+
+	ATEN2011_port->open = 0;
+	dbg("%s", "Leaving ............");
+
+}
+
+static void ATEN2011_block_until_chase_response(struct tty_struct *tty,
+						struct ATENINTL_port
+						*ATEN2011_port)
+{
+	int timeout = 1 * HZ;
+	int wait = 10;
+	int count;
+
+	while (1) {
+		count = ATEN2011_chars_in_buffer(tty);
+
+		/* Check for Buffer status */
+		if (count <= 0) {
+			ATEN2011_port->chaseResponsePending = 0;
+			return;
+		}
+
+		/* Block the thread for a while */
+		interruptible_sleep_on_timeout(&ATEN2011_port->wait_chase,
+					       timeout);
+		/* No activity.. count down section */
+		wait--;
+		if (wait == 0) {
+			dbg("%s - TIMEOUT", __func__);
+			return;
+		} else {
+			/* Reset timout value back to seconds */
+			wait = 10;
+		}
+	}
+
+}
+
+static void ATEN2011_break(struct tty_struct *tty, int break_state)
+{
+	struct usb_serial_port *port = tty->driver_data;
+	unsigned char data;
+	struct usb_serial *serial;
+	struct ATENINTL_serial *ATEN2011_serial;
+	struct ATENINTL_port *ATEN2011_port;
+
+	dbg("%s", "Entering ...........");
+	dbg("ATEN2011_break: Start");
+
+	serial = port->serial;
+
+	ATEN2011_serial = usb_get_serial_data(serial);
+	ATEN2011_port = usb_get_serial_port_data(port);
+
+	if ((ATEN2011_serial == NULL) || (ATEN2011_port == NULL))
+		return;
+
+	/* flush and chase */
+	ATEN2011_port->chaseResponsePending = 1;
+
+	if (serial->dev) {
+		/* flush and block until tx is empty */
+		ATEN2011_block_until_chase_response(tty, ATEN2011_port);
+	}
+
+	if (break_state == -1)
+		data = ATEN2011_port->shadowLCR | LCR_SET_BREAK;
+	else
+		data = ATEN2011_port->shadowLCR & ~LCR_SET_BREAK;
+
+	ATEN2011_port->shadowLCR = data;
+	dbg("ATEN2011_break ATEN2011_port->shadowLCR is %x",
+		ATEN2011_port->shadowLCR);
+	set_uart_reg(port, LINE_CONTROL_REGISTER, ATEN2011_port->shadowLCR);
+
+	return;
+}
+
+static int ATEN2011_write_room(struct tty_struct *tty)
+{
+	struct usb_serial_port *port = tty->driver_data;
+	int i;
+	int room = 0;
+	struct ATENINTL_port *ATEN2011_port;
+
+	ATEN2011_port = usb_get_serial_port_data(port);
+	if (ATEN2011_port == NULL) {
+		dbg("%s", "ATEN2011_break:leaving ...........");
+		return -1;
+	}
+
+	for (i = 0; i < NUM_URBS; ++i)
+		if (ATEN2011_port->write_urb_pool[i]->status != -EINPROGRESS)
+			room += URB_TRANSFER_BUFFER_SIZE;
+
+	dbg("%s - returns %d", __func__, room);
+	return room;
+
+}
+
+static int ATEN2011_write(struct tty_struct *tty, struct usb_serial_port *port,
+			  const unsigned char *data, int count)
+{
+	int status;
+	int i;
+	int bytes_sent = 0;
+	int transfer_size;
+	int minor;
+
+	struct ATENINTL_port *ATEN2011_port;
+	struct usb_serial *serial;
+	struct ATENINTL_serial *ATEN2011_serial;
+	struct urb *urb;
+	const unsigned char *current_position = data;
+	unsigned char *data1;
+	dbg("%s", "entering ...........");
+
+	serial = port->serial;
+
+	ATEN2011_port = usb_get_serial_port_data(port);
+	if (ATEN2011_port == NULL) {
+		dbg("%s", "ATEN2011_port is NULL");
+		return -1;
+	}
+
+	ATEN2011_serial = usb_get_serial_data(serial);
+	if (ATEN2011_serial == NULL) {
+		dbg("%s", "ATEN2011_serial is NULL");
+		return -1;
+	}
+
+	/* try to find a free urb in the list */
+	urb = NULL;
+
+	for (i = 0; i < NUM_URBS; ++i) {
+		if (ATEN2011_port->write_urb_pool[i]->status != -EINPROGRESS) {
+			urb = ATEN2011_port->write_urb_pool[i];
+			dbg("URB:%d", i);
+			break;
+		}
+	}
+
+	if (urb == NULL) {
+		dbg("%s - no more free urbs", __func__);
+		goto exit;
+	}
+
+	if (urb->transfer_buffer == NULL) {
+		urb->transfer_buffer =
+		    kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
+
+		if (urb->transfer_buffer == NULL) {
+			err("%s no more kernel memory...", __func__);
+			goto exit;
+		}
+	}
+	transfer_size = min(count, URB_TRANSFER_BUFFER_SIZE);
+
+	memcpy(urb->transfer_buffer, current_position, transfer_size);
+	/* usb_serial_debug_data (__FILE__, __func__, transfer_size, urb->transfer_buffer); */
+
+	/* fill urb with data and submit  */
+	minor = port->serial->minor;
+	if (minor == SERIAL_TTY_NO_MINOR)
+		minor = 0;
+	if ((ATEN2011_serial->ATEN2011_spectrum_2or4ports == 2)
+	    && (((__u16) port->number - (__u16) (minor)) != 0)) {
+		usb_fill_bulk_urb(urb, ATEN2011_serial->serial->dev,
+				  usb_sndbulkpipe(ATEN2011_serial->serial->dev,
+						  (port->
+						   bulk_out_endpointAddress) +
+						  2), urb->transfer_buffer,
+				  transfer_size,
+				  ATEN2011_bulk_out_data_callback,
+				  ATEN2011_port);
+	} else
+
+		usb_fill_bulk_urb(urb,
+				  ATEN2011_serial->serial->dev,
+				  usb_sndbulkpipe(ATEN2011_serial->serial->dev,
+						  port->
+						  bulk_out_endpointAddress),
+				  urb->transfer_buffer, transfer_size,
+				  ATEN2011_bulk_out_data_callback,
+				  ATEN2011_port);
+
+	data1 = urb->transfer_buffer;
+	dbg("bulkout endpoint is %d", port->bulk_out_endpointAddress);
+	/* for(i=0;i < urb->actual_length;i++) */
+		/* dbg("Data is %c ",data1[i]); */
+
+	/* send it down the pipe */
+	status = usb_submit_urb(urb, GFP_ATOMIC);
+
+	if (status) {
+		err("%s - usb_submit_urb(write bulk) failed with status = %d",
+		    __func__, status);
+		bytes_sent = status;
+		goto exit;
+	}
+	bytes_sent = transfer_size;
+	ATEN2011_port->icount.tx += transfer_size;
+	dbg("ATEN2011_port->icount.tx is %d:", ATEN2011_port->icount.tx);
+
+exit:
+	return bytes_sent;
+}
+
+static void ATEN2011_throttle(struct tty_struct *tty)
+{
+	struct usb_serial_port *port = tty->driver_data;
+	struct ATENINTL_port *ATEN2011_port;
+	int status;
+
+	dbg("- port %d", port->number);
+
+	ATEN2011_port = usb_get_serial_port_data(port);
+
+	if (ATEN2011_port == NULL)
+		return;
+
+	if (!ATEN2011_port->open) {
+		dbg("%s", "port not opened");
+		return;
+	}
+
+	dbg("%s", "Entering .......... ");
+
+	if (!tty) {
+		dbg("%s - no tty available", __func__);
+		return;
+	}
+
+	/* if we are implementing XON/XOFF, send the stop character */
+	if (I_IXOFF(tty)) {
+		unsigned char stop_char = STOP_CHAR(tty);
+		status = ATEN2011_write(tty, port, &stop_char, 1);
+		if (status <= 0)
+			return;
+	}
+
+	/* if we are implementing RTS/CTS, toggle that line */
+	if (tty->termios->c_cflag & CRTSCTS) {
+		ATEN2011_port->shadowMCR &= ~MCR_RTS;
+		status = set_uart_reg(port, MODEM_CONTROL_REGISTER,
+				      ATEN2011_port->shadowMCR);
+		if (status < 0)
+			return;
+	}
+
+	return;
+}
+
+static void ATEN2011_unthrottle(struct tty_struct *tty)
+{
+	struct usb_serial_port *port = tty->driver_data;
+	int status;
+	struct ATENINTL_port *ATEN2011_port = usb_get_serial_port_data(port);
+
+	if (ATEN2011_port == NULL)
+		return;
+
+	if (!ATEN2011_port->open) {
+		dbg("%s - port not opened", __func__);
+		return;
+	}
+
+	dbg("%s", "Entering .......... ");
+
+	if (!tty) {
+		dbg("%s - no tty available", __func__);
+		return;
+	}
+
+	/* if we are implementing XON/XOFF, send the start character */
+	if (I_IXOFF(tty)) {
+		unsigned char start_char = START_CHAR(tty);
+		status = ATEN2011_write(tty, port, &start_char, 1);
+		if (status <= 0)
+			return;
+	}
+
+	/* if we are implementing RTS/CTS, toggle that line */
+	if (tty->termios->c_cflag & CRTSCTS) {
+		ATEN2011_port->shadowMCR |= MCR_RTS;
+		status = set_uart_reg(port, MODEM_CONTROL_REGISTER,
+				      ATEN2011_port->shadowMCR);
+		if (status < 0)
+			return;
+	}
+
+	return;
+}
+
+static int ATEN2011_tiocmget(struct tty_struct *tty, struct file *file)
+{
+	struct usb_serial_port *port = tty->driver_data;
+	struct ATENINTL_port *ATEN2011_port;
+	unsigned int result;
+	__u16 msr;
+	__u16 mcr;
+	/* unsigned int mcr; */
+	int status = 0;
+	ATEN2011_port = usb_get_serial_port_data(port);
+
+	dbg("%s - port %d", __func__, port->number);
+
+	if (ATEN2011_port == NULL)
+		return -ENODEV;
+
+	status = get_uart_reg(port, MODEM_STATUS_REGISTER, &msr);
+	status = get_uart_reg(port, MODEM_CONTROL_REGISTER, &mcr);
+	/* mcr = ATEN2011_port->shadowMCR; */
+	/* COMMENT2: the Fallowing three line are commented for updating only MSR values */
+	result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0)
+	    | ((mcr & MCR_RTS) ? TIOCM_RTS : 0)
+	    | ((mcr & MCR_LOOPBACK) ? TIOCM_LOOP : 0)
+	    | ((msr & ATEN2011_MSR_CTS) ? TIOCM_CTS : 0)
+	    | ((msr & ATEN2011_MSR_CD) ? TIOCM_CAR : 0)
+	    | ((msr & ATEN2011_MSR_RI) ? TIOCM_RI : 0)
+	    | ((msr & ATEN2011_MSR_DSR) ? TIOCM_DSR : 0);
+
+	dbg("%s - 0x%04X", __func__, result);
+
+	return result;
+}
+
+static int ATEN2011_tiocmset(struct tty_struct *tty, struct file *file,
+			     unsigned int set, unsigned int clear)
+{
+	struct usb_serial_port *port = tty->driver_data;
+	struct ATENINTL_port *ATEN2011_port;
+	unsigned int mcr;
+	unsigned int status;
+
+	dbg("%s - port %d", __func__, port->number);
+
+	ATEN2011_port = usb_get_serial_port_data(port);
+
+	if (ATEN2011_port == NULL)
+		return -ENODEV;
+
+	mcr = ATEN2011_port->shadowMCR;
+	if (clear & TIOCM_RTS)
+		mcr &= ~MCR_RTS;
+	if (clear & TIOCM_DTR)
+		mcr &= ~MCR_DTR;
+	if (clear & TIOCM_LOOP)
+		mcr &= ~MCR_LOOPBACK;
+
+	if (set & TIOCM_RTS)
+		mcr |= MCR_RTS;
+	if (set & TIOCM_DTR)
+		mcr |= MCR_DTR;
+	if (set & TIOCM_LOOP)
+		mcr |= MCR_LOOPBACK;
+
+	ATEN2011_port->shadowMCR = mcr;
+
+	status = set_uart_reg(port, MODEM_CONTROL_REGISTER, mcr);
+	if (status < 0) {
+		dbg("setting MODEM_CONTROL_REGISTER Failed");
+		return -1;
+	}
+
+	return 0;
+}
+
+static void ATEN2011_set_termios(struct tty_struct *tty,
+				 struct usb_serial_port *port,
+				 struct ktermios *old_termios)
+{
+	int status;
+	unsigned int cflag;
+	struct usb_serial *serial;
+	struct ATENINTL_port *ATEN2011_port;
+
+	dbg("ATEN2011_set_termios: START");
+
+	serial = port->serial;
+
+	ATEN2011_port = usb_get_serial_port_data(port);
+
+	if (ATEN2011_port == NULL)
+		return;
+
+	if (!ATEN2011_port->open) {
+		dbg("%s - port not opened", __func__);
+		return;
+	}
+
+	dbg("%s", "setting termios - ");
+
+	cflag = tty->termios->c_cflag;
+
+	if (!cflag) {
+		dbg("%s %s", __func__, "cflag is NULL");
+		return;
+	}
+
+	/* check that they really want us to change something */
+	if (old_termios) {
+		if ((cflag == old_termios->c_cflag) &&
+		    (RELEVANT_IFLAG(tty->termios->c_iflag) ==
+		     RELEVANT_IFLAG(old_termios->c_iflag))) {
+			dbg("%s", "Nothing to change");
+			return;
+		}
+	}
+
+	dbg("%s - clfag %08x iflag %08x", __func__,
+	    tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag));
+
+	if (old_termios) {
+		dbg("%s - old clfag %08x old iflag %08x", __func__,
+		    old_termios->c_cflag, RELEVANT_IFLAG(old_termios->c_iflag));
+	}
+
+	dbg("%s - port %d", __func__, port->number);
+
+	/* change the port settings to the new ones specified */
+
+	ATEN2011_change_port_settings(tty, ATEN2011_port, old_termios);
+
+	if (!ATEN2011_port->read_urb) {
+		dbg("%s", "URB KILLED !!!!!");
+		return;
+	}
+
+	if (ATEN2011_port->read_urb->status != -EINPROGRESS) {
+		ATEN2011_port->read_urb->dev = serial->dev;
+		status = usb_submit_urb(ATEN2011_port->read_urb, GFP_ATOMIC);
+		if (status) {
+			dbg
+			    (" usb_submit_urb(read bulk) failed, status = %d",
+			     status);
+		}
+	}
+	return;
+}
+
+static int get_lsr_info(struct tty_struct *tty,
+			struct ATENINTL_port *ATEN2011_port,
+			unsigned int __user *value)
+{
+	int count;
+	unsigned int result = 0;
+
+	count = ATEN2011_chars_in_buffer(tty);
+	if (count == 0) {
+		dbg("%s -- Empty", __func__);
+		result = TIOCSER_TEMT;
+	}
+
+	if (copy_to_user(value, &result, sizeof(int)))
+		return -EFAULT;
+	return 0;
+}
+
+static int get_number_bytes_avail(struct tty_struct *tty,
+				  struct ATENINTL_port *ATEN2011_port,
+				  unsigned int __user *value)
+{
+	unsigned int result = 0;
+
+	if (!tty)
+		return -ENOIOCTLCMD;
+
+	result = tty->read_cnt;
+
+	dbg("%s(%d) = %d", __func__, ATEN2011_port->port->number, result);
+	if (copy_to_user(value, &result, sizeof(int)))
+		return -EFAULT;
+
+	return -ENOIOCTLCMD;
+}
+
+static int set_modem_info(struct ATENINTL_port *ATEN2011_port, unsigned int cmd,
+			  unsigned int __user *value)
+{
+	unsigned int mcr;
+	unsigned int arg;
+	__u16 Data;
+	int status;
+	struct usb_serial_port *port;
+
+	if (ATEN2011_port == NULL)
+		return -1;
+
+	port = (struct usb_serial_port *)ATEN2011_port->port;
+
+	mcr = ATEN2011_port->shadowMCR;
+
+	if (copy_from_user(&arg, value, sizeof(int)))
+		return -EFAULT;
+
+	switch (cmd) {
+	case TIOCMBIS:
+		if (arg & TIOCM_RTS)
+			mcr |= MCR_RTS;
+		if (arg & TIOCM_DTR)
+			mcr |= MCR_RTS;
+		if (arg & TIOCM_LOOP)
+			mcr |= MCR_LOOPBACK;
+		break;
+
+	case TIOCMBIC:
+		if (arg & TIOCM_RTS)
+			mcr &= ~MCR_RTS;
+		if (arg & TIOCM_DTR)
+			mcr &= ~MCR_RTS;
+		if (arg & TIOCM_LOOP)
+			mcr &= ~MCR_LOOPBACK;
+		break;
+
+	case TIOCMSET:
+		/* turn off the RTS and DTR and LOOPBACK
+		 * and then only turn on what was asked to */
+		mcr &= ~(MCR_RTS | MCR_DTR | MCR_LOOPBACK);
+		mcr |= ((arg & TIOCM_RTS) ? MCR_RTS : 0);
+		mcr |= ((arg & TIOCM_DTR) ? MCR_DTR : 0);
+		mcr |= ((arg & TIOCM_LOOP) ? MCR_LOOPBACK : 0);
+		break;
+	}
+
+	ATEN2011_port->shadowMCR = mcr;
+
+	Data = ATEN2011_port->shadowMCR;
+	status = set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+	if (status < 0) {
+		dbg("setting MODEM_CONTROL_REGISTER Failed");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int get_modem_info(struct ATENINTL_port *ATEN2011_port,
+			  unsigned int __user *value)
+{
+	unsigned int result = 0;
+	__u16 msr;
+	unsigned int mcr = ATEN2011_port->shadowMCR;
+	int status;
+
+	status = get_uart_reg(ATEN2011_port->port, MODEM_STATUS_REGISTER, &msr);
+	result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0)	/* 0x002 */
+	    |((mcr & MCR_RTS) ? TIOCM_RTS : 0)	/* 0x004 */
+	    |((msr & ATEN2011_MSR_CTS) ? TIOCM_CTS : 0)	/* 0x020 */
+	    |((msr & ATEN2011_MSR_CD) ? TIOCM_CAR : 0)	/* 0x040 */
+	    |((msr & ATEN2011_MSR_RI) ? TIOCM_RI : 0)	/* 0x080 */
+	    |((msr & ATEN2011_MSR_DSR) ? TIOCM_DSR : 0);	/* 0x100 */
+
+	dbg("%s -- %x", __func__, result);
+
+	if (copy_to_user(value, &result, sizeof(int)))
+		return -EFAULT;
+	return 0;
+}
+
+static int get_serial_info(struct ATENINTL_port *ATEN2011_port,
+			   struct serial_struct __user *retinfo)
+{
+	struct serial_struct tmp;
+
+	if (ATEN2011_port == NULL)
+		return -1;
+
+	if (!retinfo)
+		return -EFAULT;
+
+	memset(&tmp, 0, sizeof(tmp));
+
+	tmp.type = PORT_16550A;
+	tmp.line = ATEN2011_port->port->serial->minor;
+	if (tmp.line == SERIAL_TTY_NO_MINOR)
+		tmp.line = 0;
+	tmp.port = ATEN2011_port->port->number;
+	tmp.irq = 0;
+	tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
+	tmp.xmit_fifo_size = NUM_URBS * URB_TRANSFER_BUFFER_SIZE;
+	tmp.baud_base = 9600;
+	tmp.close_delay = 5 * HZ;
+	tmp.closing_wait = 30 * HZ;
+
+	if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
+		return -EFAULT;
+	return 0;
+}
+
+static int ATEN2011_ioctl(struct tty_struct *tty, struct file *file,
+			  unsigned int cmd, unsigned long arg)
+{
+	struct usb_serial_port *port = tty->driver_data;
+	struct ATENINTL_port *ATEN2011_port;
+	struct async_icount cnow;
+	struct async_icount cprev;
+	struct serial_icounter_struct icount;
+	int ATENret = 0;
+	unsigned int __user *user_arg = (unsigned int __user *)arg;
+
+	ATEN2011_port = usb_get_serial_port_data(port);
+
+	if (ATEN2011_port == NULL)
+		return -1;
+
+	dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd);
+
+	switch (cmd) {
+		/* return number of bytes available */
+
+	case TIOCINQ:
+		dbg("%s (%d) TIOCINQ", __func__, port->number);
+		return get_number_bytes_avail(tty, ATEN2011_port, user_arg);
+		break;
+
+	case TIOCOUTQ:
+		dbg("%s (%d) TIOCOUTQ", __func__, port->number);
+		return put_user(ATEN2011_chars_in_buffer(tty), user_arg);
+		break;
+
+	case TIOCSERGETLSR:
+		dbg("%s (%d) TIOCSERGETLSR", __func__, port->number);
+		return get_lsr_info(tty, ATEN2011_port, user_arg);
+		return 0;
+
+	case TIOCMBIS:
+	case TIOCMBIC:
+	case TIOCMSET:
+		dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET", __func__,
+		    port->number);
+		ATENret = set_modem_info(ATEN2011_port, cmd, user_arg);
+		return ATENret;
+
+	case TIOCMGET:
+		dbg("%s (%d) TIOCMGET", __func__, port->number);
+		return get_modem_info(ATEN2011_port, user_arg);
+
+	case TIOCGSERIAL:
+		dbg("%s (%d) TIOCGSERIAL", __func__, port->number);
+		return get_serial_info(ATEN2011_port,
+				       (struct serial_struct __user *)arg);
+
+	case TIOCSSERIAL:
+		dbg("%s (%d) TIOCSSERIAL", __func__, port->number);
+		break;
+
+	case TIOCMIWAIT:
+		dbg("%s (%d) TIOCMIWAIT", __func__, port->number);
+		cprev = ATEN2011_port->icount;
+		while (1) {
+			/* see if a signal did it */
+			if (signal_pending(current))
+				return -ERESTARTSYS;
+			cnow = ATEN2011_port->icount;
+			if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
+			    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
+				return -EIO;	/* no change => error */
+			if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+			    ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+			    ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
+			    ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
+				return 0;
+			}
+			cprev = cnow;
+		}
+		/* NOTREACHED */
+		break;
+
+	case TIOCGICOUNT:
+		cnow = ATEN2011_port->icount;
+		icount.cts = cnow.cts;
+		icount.dsr = cnow.dsr;
+		icount.rng = cnow.rng;
+		icount.dcd = cnow.dcd;
+		icount.rx = cnow.rx;
+		icount.tx = cnow.tx;
+		icount.frame = cnow.frame;
+		icount.overrun = cnow.overrun;
+		icount.parity = cnow.parity;
+		icount.brk = cnow.brk;
+		icount.buf_overrun = cnow.buf_overrun;
+
+		dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __func__,
+		    port->number, icount.rx, icount.tx);
+		if (copy_to_user((void __user *)arg, &icount, sizeof(icount)))
+			return -EFAULT;
+		return 0;
+
+	default:
+		break;
+	}
+
+	return -ENOIOCTLCMD;
+}
+
+static int ATEN2011_calc_baud_rate_divisor(int baudRate, int *divisor,
+					   __u16 *clk_sel_val)
+{
+	dbg("%s - %d", __func__, baudRate);
+
+	if (baudRate <= 115200) {
+		*divisor = 115200 / baudRate;
+		*clk_sel_val = 0x0;
+	}
+	if ((baudRate > 115200) && (baudRate <= 230400)) {
+		*divisor = 230400 / baudRate;
+		*clk_sel_val = 0x10;
+	} else if ((baudRate > 230400) && (baudRate <= 403200)) {
+		*divisor = 403200 / baudRate;
+		*clk_sel_val = 0x20;
+	} else if ((baudRate > 403200) && (baudRate <= 460800)) {
+		*divisor = 460800 / baudRate;
+		*clk_sel_val = 0x30;
+	} else if ((baudRate > 460800) && (baudRate <= 806400)) {
+		*divisor = 806400 / baudRate;
+		*clk_sel_val = 0x40;
+	} else if ((baudRate > 806400) && (baudRate <= 921600)) {
+		*divisor = 921600 / baudRate;
+		*clk_sel_val = 0x50;
+	} else if ((baudRate > 921600) && (baudRate <= 1572864)) {
+		*divisor = 1572864 / baudRate;
+		*clk_sel_val = 0x60;
+	} else if ((baudRate > 1572864) && (baudRate <= 3145728)) {
+		*divisor = 3145728 / baudRate;
+		*clk_sel_val = 0x70;
+	}
+	return 0;
+}
+
+static int ATEN2011_send_cmd_write_baud_rate(struct ATENINTL_port
+					     *ATEN2011_port, int baudRate)
+{
+	int divisor = 0;
+	int status;
+	__u16 Data;
+	unsigned char number;
+	__u16 clk_sel_val;
+	struct usb_serial_port *port;
+	int minor;
+
+	if (ATEN2011_port == NULL)
+		return -1;
+
+	port = (struct usb_serial_port *)ATEN2011_port->port;
+
+	dbg("%s", "Entering .......... ");
+
+	minor = ATEN2011_port->port->serial->minor;
+	if (minor == SERIAL_TTY_NO_MINOR)
+		minor = 0;
+	number = ATEN2011_port->port->number - minor;
+
+	dbg("%s - port = %d, baud = %d", __func__,
+	    ATEN2011_port->port->number, baudRate);
+	/* reset clk_uart_sel in spregOffset */
+	if (baudRate > 115200) {
+#ifdef HW_flow_control
+		/*
+		 * NOTE: need to see the pther register to modify
+		 * setting h/w flow control bit to 1;
+		 */
+		/* Data = ATEN2011_port->shadowMCR; */
+		Data = 0x2b;
+		ATEN2011_port->shadowMCR = Data;
+		status = set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+		if (status < 0) {
+			dbg("Writing spreg failed in set_serial_baud");
+			return -1;
+		}
+#endif
+
+	} else {
+#ifdef HW_flow_control
+		/* setting h/w flow control bit to 0; */
+		/* Data = ATEN2011_port->shadowMCR; */
+		Data = 0xb;
+		ATEN2011_port->shadowMCR = Data;
+		status = set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+		if (status < 0) {
+			dbg("Writing spreg failed in set_serial_baud");
+			return -1;
+		}
+#endif
+
+	}
+
+	if (1)			/* baudRate <= 115200) */ {
+		clk_sel_val = 0x0;
+		Data = 0x0;
+		status =
+		    ATEN2011_calc_baud_rate_divisor(baudRate, &divisor,
+						    &clk_sel_val);
+		status = get_reg_sync(port, ATEN2011_port->SpRegOffset, &Data);
+		if (status < 0) {
+			dbg("reading spreg failed in set_serial_baud");
+			return -1;
+		}
+		Data = (Data & 0x8f) | clk_sel_val;
+		status = set_reg_sync(port, ATEN2011_port->SpRegOffset, Data);
+		if (status < 0) {
+			dbg("Writing spreg failed in set_serial_baud");
+			return -1;
+		}
+		/* Calculate the Divisor */
+
+		if (status) {
+			err("%s - bad baud rate", __func__);
+			dbg("%s", "bad baud rate");
+			return status;
+		}
+		/* Enable access to divisor latch */
+		Data = ATEN2011_port->shadowLCR | SERIAL_LCR_DLAB;
+		ATEN2011_port->shadowLCR = Data;
+		set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
+
+		/* Write the divisor */
+		Data = (unsigned char)(divisor & 0xff);
+		dbg("set_serial_baud Value to write DLL is %x", Data);
+		set_uart_reg(port, DIVISOR_LATCH_LSB, Data);
+
+		Data = (unsigned char)((divisor & 0xff00) >> 8);
+		dbg("set_serial_baud Value to write DLM is %x", Data);
+		set_uart_reg(port, DIVISOR_LATCH_MSB, Data);
+
+		/* Disable access to divisor latch */
+		Data = ATEN2011_port->shadowLCR & ~SERIAL_LCR_DLAB;
+		ATEN2011_port->shadowLCR = Data;
+		set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
+
+	}
+
+	return status;
+}
+
+static void ATEN2011_change_port_settings(struct tty_struct *tty,
+					  struct ATENINTL_port *ATEN2011_port,
+					  struct ktermios *old_termios)
+{
+	int baud;
+	unsigned cflag;
+	unsigned iflag;
+	__u8 lData;
+	__u8 lParity;
+	__u8 lStop;
+	int status;
+	__u16 Data;
+	struct usb_serial_port *port;
+	struct usb_serial *serial;
+
+	if (ATEN2011_port == NULL)
+		return;
+
+	port = (struct usb_serial_port *)ATEN2011_port->port;
+
+	serial = port->serial;
+
+	dbg("%s - port %d", __func__, ATEN2011_port->port->number);
+
+	if (!ATEN2011_port->open) {
+		dbg("%s - port not opened", __func__);
+		return;
+	}
+
+	if ((!tty) || (!tty->termios)) {
+		dbg("%s - no tty structures", __func__);
+		return;
+	}
+
+	dbg("%s", "Entering .......... ");
+
+	lData = LCR_BITS_8;
+	lStop = LCR_STOP_1;
+	lParity = LCR_PAR_NONE;
+
+	cflag = tty->termios->c_cflag;
+	iflag = tty->termios->c_iflag;
+
+	/* Change the number of bits */
+
+	/* COMMENT1: the below Line"if(cflag & CSIZE)" is added for the errors we get for serial loop data test i.e serial_loopback.pl -v */
+	/* if(cflag & CSIZE) */
+	{
+		switch (cflag & CSIZE) {
+		case CS5:
+			lData = LCR_BITS_5;
+			break;
+
+		case CS6:
+			lData = LCR_BITS_6;
+			break;
+
+		case CS7:
+			lData = LCR_BITS_7;
+			break;
+		default:
+		case CS8:
+			lData = LCR_BITS_8;
+			break;
+		}
+	}
+	/* Change the Parity bit */
+	if (cflag & PARENB) {
+		if (cflag & PARODD) {
+			lParity = LCR_PAR_ODD;
+			dbg("%s - parity = odd", __func__);
+		} else {
+			lParity = LCR_PAR_EVEN;
+			dbg("%s - parity = even", __func__);
+		}
+
+	} else {
+		dbg("%s - parity = none", __func__);
+	}
+
+	if (cflag & CMSPAR)
+		lParity = lParity | 0x20;
+
+	/* Change the Stop bit */
+	if (cflag & CSTOPB) {
+		lStop = LCR_STOP_2;
+		dbg("%s - stop bits = 2", __func__);
+	} else {
+		lStop = LCR_STOP_1;
+		dbg("%s - stop bits = 1", __func__);
+	}
+
+	/* Update the LCR with the correct value */
+	ATEN2011_port->shadowLCR &=
+	    ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK);
+	ATEN2011_port->shadowLCR |= (lData | lParity | lStop);
+
+	dbg
+	    ("ATEN2011_change_port_settings ATEN2011_port->shadowLCR is %x",
+	     ATEN2011_port->shadowLCR);
+	/* Disable Interrupts */
+	Data = 0x00;
+	set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
+
+	Data = 0x00;
+	set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
+
+	Data = 0xcf;
+	set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
+
+	/* Send the updated LCR value to the ATEN2011 */
+	Data = ATEN2011_port->shadowLCR;
+
+	set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
+
+	Data = 0x00b;
+	ATEN2011_port->shadowMCR = Data;
+	set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+	Data = 0x00b;
+	set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+
+	/* set up the MCR register and send it to the ATEN2011 */
+
+	ATEN2011_port->shadowMCR = MCR_MASTER_IE;
+	if (cflag & CBAUD)
+		ATEN2011_port->shadowMCR |= (MCR_DTR | MCR_RTS);
+
+	if (cflag & CRTSCTS)
+		ATEN2011_port->shadowMCR |= (MCR_XON_ANY);
+	else
+		ATEN2011_port->shadowMCR &= ~(MCR_XON_ANY);
+
+	Data = ATEN2011_port->shadowMCR;
+	set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+
+	/* Determine divisor based on baud rate */
+	baud = tty_get_baud_rate(tty);
+
+	if (!baud) {
+		/* pick a default, any default... */
+		dbg("%s", "Picked default baud...");
+		baud = 9600;
+	}
+
+	dbg("%s - baud rate = %d", __func__, baud);
+	status = ATEN2011_send_cmd_write_baud_rate(ATEN2011_port, baud);
+
+	/* Enable Interrupts */
+	Data = 0x0c;
+	set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
+
+	if (ATEN2011_port->read_urb->status != -EINPROGRESS) {
+		ATEN2011_port->read_urb->dev = serial->dev;
+
+		status = usb_submit_urb(ATEN2011_port->read_urb, GFP_ATOMIC);
+
+		if (status) {
+			dbg
+			    (" usb_submit_urb(read bulk) failed, status = %d",
+			     status);
+		}
+	}
+	dbg
+	    ("ATEN2011_change_port_settings ATEN2011_port->shadowLCR is End %x",
+	     ATEN2011_port->shadowLCR);
+
+	return;
+}
+
+static int ATEN2011_calc_num_ports(struct usb_serial *serial)
+{
+
+	__u16 Data = 0x00;
+	int ret = 0;
+	int ATEN2011_2or4ports;
+	ret = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+			      ATEN_RDREQ, ATEN_RD_RTYPE, 0, GPIO_REGISTER,
+			      &Data, VENDOR_READ_LENGTH, ATEN_WDR_TIMEOUT);
+
+/* ghostgum: here is where the problem appears to bet */
+/* Which of the following are needed? */
+/* Greg used the serial->type->num_ports=2 */
+/* But the code in the ATEN2011_open relies on serial->num_ports=2 */
+	if ((Data & 0x01) == 0) {
+		ATEN2011_2or4ports = 2;
+		serial->type->num_ports = 2;
+		serial->num_ports = 2;
+	}
+	/* else if(serial->interface->cur_altsetting->desc.bNumEndpoints == 9) */
+	else {
+		ATEN2011_2or4ports = 4;
+		serial->type->num_ports = 4;
+		serial->num_ports = 4;
+
+	}
+
+	return ATEN2011_2or4ports;
+}
+
+static int ATEN2011_startup(struct usb_serial *serial)
+{
+	struct ATENINTL_serial *ATEN2011_serial;
+	struct ATENINTL_port *ATEN2011_port;
+	struct usb_device *dev;
+	int i, status;
+	int minor;
+
+	__u16 Data;
+	dbg("%s", " ATEN2011_startup :entering..........");
+
+	if (!serial) {
+		dbg("%s", "Invalid Handler");
+		return -1;
+	}
+
+	dev = serial->dev;
+
+	dbg("%s", "Entering...");
+
+	/* create our private serial structure */
+	ATEN2011_serial = kzalloc(sizeof(struct ATENINTL_serial), GFP_KERNEL);
+	if (ATEN2011_serial == NULL) {
+		err("%s - Out of memory", __func__);
+		return -ENOMEM;
+	}
+
+	/* resetting the private structure field values to zero */
+	memset(ATEN2011_serial, 0, sizeof(struct ATENINTL_serial));
+
+	ATEN2011_serial->serial = serial;
+	/* initilize status polling flag to 0 */
+	ATEN2011_serial->status_polling_started = 0;
+
+	usb_set_serial_data(serial, ATEN2011_serial);
+	ATEN2011_serial->ATEN2011_spectrum_2or4ports =
+	    ATEN2011_calc_num_ports(serial);
+	/* we set up the pointers to the endpoints in the ATEN2011_open *
+	 * function, as the structures aren't created yet.             */
+
+	/* set up port private structures */
+	for (i = 0; i < serial->num_ports; ++i) {
+		ATEN2011_port =
+		    kmalloc(sizeof(struct ATENINTL_port), GFP_KERNEL);
+		if (ATEN2011_port == NULL) {
+			err("%s - Out of memory", __func__);
+			usb_set_serial_data(serial, NULL);
+			kfree(ATEN2011_serial);
+			return -ENOMEM;
+		}
+		memset(ATEN2011_port, 0, sizeof(struct ATENINTL_port));
+
+		/*
+		 * Initialize all port interrupt end point to port 0
+		 * int endpoint. Our device has only one interrupt end point
+		 * comman to all port
+		 */
+		/* serial->port[i]->interrupt_in_endpointAddress = serial->port[0]->interrupt_in_endpointAddress; */
+
+		ATEN2011_port->port = serial->port[i];
+		usb_set_serial_port_data(serial->port[i], ATEN2011_port);
+
+		minor = serial->port[i]->serial->minor;
+		if (minor == SERIAL_TTY_NO_MINOR)
+			minor = 0;
+		ATEN2011_port->port_num =
+		    ((serial->port[i]->number - minor) + 1);
+
+		if (ATEN2011_port->port_num == 1) {
+			ATEN2011_port->SpRegOffset = 0x0;
+			ATEN2011_port->ControlRegOffset = 0x1;
+			ATEN2011_port->DcrRegOffset = 0x4;
+		} else if ((ATEN2011_port->port_num == 2)
+			   && (ATEN2011_serial->ATEN2011_spectrum_2or4ports ==
+			       4)) {
+			ATEN2011_port->SpRegOffset = 0x8;
+			ATEN2011_port->ControlRegOffset = 0x9;
+			ATEN2011_port->DcrRegOffset = 0x16;
+		} else if ((ATEN2011_port->port_num == 2)
+			   && (ATEN2011_serial->ATEN2011_spectrum_2or4ports ==
+			       2)) {
+			ATEN2011_port->SpRegOffset = 0xa;
+			ATEN2011_port->ControlRegOffset = 0xb;
+			ATEN2011_port->DcrRegOffset = 0x19;
+		} else if ((ATEN2011_port->port_num == 3)
+			   && (ATEN2011_serial->ATEN2011_spectrum_2or4ports ==
+			       4)) {
+			ATEN2011_port->SpRegOffset = 0xa;
+			ATEN2011_port->ControlRegOffset = 0xb;
+			ATEN2011_port->DcrRegOffset = 0x19;
+		} else if ((ATEN2011_port->port_num == 4)
+			   && (ATEN2011_serial->ATEN2011_spectrum_2or4ports ==
+			       4)) {
+			ATEN2011_port->SpRegOffset = 0xc;
+			ATEN2011_port->ControlRegOffset = 0xd;
+			ATEN2011_port->DcrRegOffset = 0x1c;
+		}
+
+		usb_set_serial_port_data(serial->port[i], ATEN2011_port);
+
+		/* enable rx_disable bit in control register */
+
+		status = get_reg_sync(serial->port[i],
+				      ATEN2011_port->ControlRegOffset, &Data);
+		if (status < 0) {
+			dbg("Reading ControlReg failed status-0x%x",
+				status);
+			break;
+		} else
+			dbg
+			    ("ControlReg Reading success val is %x, status%d",
+			     Data, status);
+		Data |= 0x08;	/* setting driver done bit */
+		Data |= 0x04;	/* sp1_bit to have cts change reflect in modem status reg */
+
+		/* Data |= 0x20; */	/* rx_disable bit */
+		status = set_reg_sync(serial->port[i],
+				      ATEN2011_port->ControlRegOffset, Data);
+		if (status < 0) {
+			dbg
+			    ("Writing ControlReg failed(rx_disable) status-0x%x",
+			     status);
+			break;
+		} else
+			dbg
+			    ("ControlReg Writing success(rx_disable) status%d",
+			     status);
+
+		/*
+		 * Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2
+		 * and 0x24 in DCR3
+		 */
+		Data = 0x01;
+		status = set_reg_sync(serial->port[i],
+				      (__u16)(ATEN2011_port->DcrRegOffset + 0),
+				      Data);
+		if (status < 0) {
+			dbg("Writing DCR0 failed status-0x%x", status);
+			break;
+		} else
+			dbg("DCR0 Writing success status%d", status);
+
+		Data = 0x05;
+		status = set_reg_sync(serial->port[i],
+				      (__u16)(ATEN2011_port->DcrRegOffset + 1),
+				      Data);
+		if (status < 0) {
+			dbg("Writing DCR1 failed status-0x%x", status);
+			break;
+		} else
+			dbg("DCR1 Writing success status%d", status);
+
+		Data = 0x24;
+		status = set_reg_sync(serial->port[i],
+				      (__u16)(ATEN2011_port->DcrRegOffset + 2),
+				      Data);
+		if (status < 0) {
+			dbg("Writing DCR2 failed status-0x%x", status);
+			break;
+		} else
+			dbg("DCR2 Writing success status%d", status);
+
+		/* write values in clkstart0x0 and clkmulti 0x20 */
+		Data = 0x0;
+		status = set_reg_sync(serial->port[i], CLK_START_VALUE_REGISTER,
+				      Data);
+		if (status < 0) {
+			dbg
+			    ("Writing CLK_START_VALUE_REGISTER failed status-0x%x",
+			     status);
+			break;
+		} else
+			dbg
+			    ("CLK_START_VALUE_REGISTER Writing success status%d",
+			     status);
+
+		Data = 0x20;
+		status = set_reg_sync(serial->port[i], CLK_MULTI_REGISTER,
+				      Data);
+		if (status < 0) {
+			dbg
+			    ("Writing CLK_MULTI_REGISTER failed status-0x%x",
+			     status);
+			break;
+		} else
+			dbg("CLK_MULTI_REGISTER Writing success status%d",
+				status);
+
+		/* Zero Length flag register */
+		if ((ATEN2011_port->port_num != 1)
+		    && (ATEN2011_serial->ATEN2011_spectrum_2or4ports == 2)) {
+
+			Data = 0xff;
+			status = set_reg_sync(serial->port[i],
+					      (__u16)(ZLP_REG1 + ((__u16)ATEN2011_port->port_num)),
+					      Data);
+			dbg("ZLIP offset%x",
+				(__u16) (ZLP_REG1 +
+					 ((__u16) ATEN2011_port->port_num)));
+			if (status < 0) {
+				dbg
+				    ("Writing ZLP_REG%d failed status-0x%x",
+				     i + 2, status);
+				break;
+			} else
+				dbg("ZLP_REG%d Writing success status%d",
+					i + 2, status);
+		} else {
+			Data = 0xff;
+			status = set_reg_sync(serial->port[i],
+					      (__u16)(ZLP_REG1 + ((__u16)ATEN2011_port->port_num) - 0x1),
+					      Data);
+			dbg("ZLIP offset%x",
+				(__u16) (ZLP_REG1 +
+					 ((__u16) ATEN2011_port->port_num) -
+					 0x1));
+			if (status < 0) {
+				dbg
+				    ("Writing ZLP_REG%d failed status-0x%x",
+				     i + 1, status);
+				break;
+			} else
+				dbg("ZLP_REG%d Writing success status%d",
+					i + 1, status);
+
+		}
+		ATEN2011_port->control_urb = usb_alloc_urb(0, GFP_ATOMIC);
+		ATEN2011_port->ctrl_buf = kmalloc(16, GFP_KERNEL);
+
+	}
+
+	/* Zero Length flag enable */
+	Data = 0x0f;
+	status = set_reg_sync(serial->port[0], ZLP_REG5, Data);
+	if (status < 0) {
+		dbg("Writing ZLP_REG5 failed status-0x%x", status);
+		return -1;
+	} else
+		dbg("ZLP_REG5 Writing success status%d", status);
+
+	/* setting configuration feature to one */
+	usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			(__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5 * HZ);
+	return 0;
+}
+
+static void ATEN2011_shutdown(struct usb_serial *serial)
+{
+	int i;
+	struct ATENINTL_port *ATEN2011_port;
+
+	/* check for the ports to be closed,close the ports and disconnect */
+
+	/* free private structure allocated for serial port  *
+	 * stop reads and writes on all ports                */
+
+	for (i = 0; i < serial->num_ports; ++i) {
+		ATEN2011_port = usb_get_serial_port_data(serial->port[i]);
+		kfree(ATEN2011_port->ctrl_buf);
+		usb_kill_urb(ATEN2011_port->control_urb);
+		kfree(ATEN2011_port);
+		usb_set_serial_port_data(serial->port[i], NULL);
+	}
+
+	/* free private structure allocated for serial device */
+
+	kfree(usb_get_serial_data(serial));
+	usb_set_serial_data(serial, NULL);
+}
+
+static struct usb_serial_driver aten_serial_driver = {
+	.driver = {
+		.owner =	THIS_MODULE,
+		.name =		"aten2011",
+		},
+	.description =		DRIVER_DESC,
+	.id_table =		id_table,
+	.open =			ATEN2011_open,
+	.close =		ATEN2011_close,
+	.write =		ATEN2011_write,
+	.write_room =		ATEN2011_write_room,
+	.chars_in_buffer =	ATEN2011_chars_in_buffer,
+	.throttle =		ATEN2011_throttle,
+	.unthrottle =		ATEN2011_unthrottle,
+	.calc_num_ports =	ATEN2011_calc_num_ports,
+
+	.ioctl =		ATEN2011_ioctl,
+	.set_termios =		ATEN2011_set_termios,
+	.break_ctl =		ATEN2011_break,
+	.tiocmget =		ATEN2011_tiocmget,
+	.tiocmset =		ATEN2011_tiocmset,
+	.attach =		ATEN2011_startup,
+	.shutdown =		ATEN2011_shutdown,
+	.read_bulk_callback =	ATEN2011_bulk_in_callback,
+	.read_int_callback =	ATEN2011_interrupt_callback,
+};
+
+static struct usb_driver aten_driver = {
+	.name =		"aten2011",
+	.probe =	usb_serial_probe,
+	.disconnect =	usb_serial_disconnect,
+	.id_table =	id_table,
+};
+
+static int __init aten_init(void)
+{
+	int retval;
+
+	/* Register with the usb serial */
+	retval = usb_serial_register(&aten_serial_driver);
+	if (retval)
+		return retval;
+
+	printk(KERN_INFO KBUILD_MODNAME ":"
+	       DRIVER_DESC " " DRIVER_VERSION "\n");
+
+	/* Register with the usb */
+	retval = usb_register(&aten_driver);
+	if (retval)
+		usb_serial_deregister(&aten_serial_driver);
+
+	return retval;
+}
+
+static void __exit aten_exit(void)
+{
+	usb_deregister(&aten_driver);
+	usb_serial_deregister(&aten_serial_driver);
+}
+
+module_init(aten_init);
+module_exit(aten_exit);
+
+/* Module information */
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+MODULE_PARM_DESC(debug, "Debug enabled or not");
diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c
index 2eb6137..1c71062 100644
--- a/drivers/staging/usbip/stub_rx.c
+++ b/drivers/staging/usbip/stub_rx.c
@@ -334,7 +334,7 @@
 
 	spin_lock_irqsave(&sdev->priv_lock, flags);
 
-	priv = kmem_cache_alloc(stub_priv_cache, GFP_ATOMIC);
+	priv = kmem_cache_zalloc(stub_priv_cache, GFP_ATOMIC);
 	if (!priv) {
 		dev_err(&sdev->interface->dev, "alloc stub_priv\n");
 		spin_unlock_irqrestore(&sdev->priv_lock, flags);
@@ -342,8 +342,6 @@
 		return NULL;
 	}
 
-	memset(priv, 0, sizeof(struct stub_priv));
-
 	priv->seqnum = pdu->base.seqnum;
 	priv->sdev = sdev;
 
diff --git a/drivers/staging/usbip/vhci_sysfs.c b/drivers/staging/usbip/vhci_sysfs.c
index 0fd33a6..e4c7143 100644
--- a/drivers/staging/usbip/vhci_sysfs.c
+++ b/drivers/staging/usbip/vhci_sysfs.c
@@ -31,8 +31,7 @@
 	char *s = out;
 	int i = 0;
 
-	if (!the_controller || !out)
-		BUG();
+	BUG_ON(!the_controller || !out);
 
 	spin_lock(&the_controller->lock);
 
diff --git a/drivers/staging/winbond/bss_f.h b/drivers/staging/winbond/bss_f.h
deleted file mode 100644
index a433b5a..0000000
--- a/drivers/staging/winbond/bss_f.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef __WINBOND_BSS_F_H
-#define __WINBOND_BSS_F_H
-
-#include "core.h"
-
-struct PMKID_Information_Element;
-
-//
-// BSS descriptor DataBase management global function
-//
-
-void vBSSdescriptionInit(struct wbsoft_priv * adapter);
-void vBSSfoundList(struct wbsoft_priv * adapter);
-u8 boChanFilter(struct wbsoft_priv * adapter, u8 ChanNo);
-u16 wBSSallocateEntry(struct wbsoft_priv * adapter);
-u16 wBSSGetEntry(struct wbsoft_priv * adapter);
-void vSimpleHouseKeeping(struct wbsoft_priv * adapter);
-u16 wBSShouseKeeping(struct wbsoft_priv * adapter);
-void ClearBSSdescpt(struct wbsoft_priv * adapter, u16 i);
-u16 wBSSfindBssID(struct wbsoft_priv * adapter, u8 *pbBssid);
-u16 wBSSfindDedicateCandidate(struct wbsoft_priv * adapter, struct SSID_Element *psSsid, u8 *pbBssid);
-u16 wBSSfindMACaddr(struct wbsoft_priv * adapter, u8 *pbMacAddr);
-u16 wBSSsearchMACaddr(struct wbsoft_priv * adapter, u8 *pbMacAddr, u8 band);
-u16 wBSSaddScanData(struct wbsoft_priv *, u16, psRXDATA);
-u16 wBSSUpdateScanData(struct wbsoft_priv * adapter, u16 wBssIdx, psRXDATA psRcvData);
-u16 wBSScreateIBSSdata(struct wbsoft_priv * adapter, PWB_BSSDESCRIPTION psDesData);
-void DesiredRate2BSSdescriptor(struct wbsoft_priv * adapter, PWB_BSSDESCRIPTION psDesData,
-							 u8 *pBasicRateSet, u8 BasicRateCount,
-							 u8 *pOperationRateSet, u8 OperationRateCount);
-void DesiredRate2InfoElement(struct wbsoft_priv * adapter, u8	*addr, u16 *iFildOffset,
-							 u8 *pBasicRateSet, u8 BasicRateCount,
-							 u8 *pOperationRateSet, u8 OperationRateCount);
-void BSSAddIBSSdata(struct wbsoft_priv * adapter, PWB_BSSDESCRIPTION psDesData);
-unsigned char boCmpMacAddr( u8 *, u8 *);
-unsigned char boCmpSSID(struct SSID_Element *psSSID1, struct SSID_Element *psSSID2);
-u16 wBSSfindSSID(struct wbsoft_priv * adapter, struct SSID_Element *psSsid);
-u16 wRoamingQuery(struct wbsoft_priv * adapter);
-void vRateToBitmap(struct wbsoft_priv * adapter, u16 index);
-u8 bRateToBitmapIndex(struct wbsoft_priv * adapter, u8 bRate);
-u8 bBitmapToRate(u8 i);
-unsigned char boIsERPsta(struct wbsoft_priv * adapter, u16 i);
-unsigned char boCheckConnect(struct wbsoft_priv * adapter);
-unsigned char boCheckSignal(struct wbsoft_priv * adapter);
-void AddIBSSIe(struct wbsoft_priv * adapter,PWB_BSSDESCRIPTION psDesData );//added by ws for WPA_None06/01/04
-void BssScanUpToDate(struct wbsoft_priv * adapter);
-void BssUpToDate(struct wbsoft_priv * adapter);
-void RateSort(u8 *RateArray, u8 num, u8 mode);
-void RateReSortForSRate(struct wbsoft_priv * adapter, u8 *RateArray, u8 num);
-void Assemble_IE(struct wbsoft_priv * adapter, u16 wBssIdx);
-void SetMaxTxRate(struct wbsoft_priv * adapter);
-
-void CreateWpaIE(struct wbsoft_priv * adapter, u16* iFildOffset, u8 *msg, struct  Management_Frame* msgHeader,
-				 struct Association_Request_Frame_Body* msgBody, u16 iMSindex); //added by WS 05/14/05
-
-#ifdef _WPA2_
-void CreateRsnIE(struct wbsoft_priv * adapter, u16* iFildOffset, u8 *msg, struct  Management_Frame* msgHeader,
-				 struct Association_Request_Frame_Body* msgBody, u16 iMSindex);//added by WS 05/14/05
-
-u16 SearchPmkid(struct wbsoft_priv * adapter, struct  Management_Frame* msgHeader,
-				   struct PMKID_Information_Element * AssoReq_PMKID );
-#endif
-
-#endif
diff --git a/drivers/staging/winbond/bssdscpt.h b/drivers/staging/winbond/bssdscpt.h
deleted file mode 100644
index 3a71d4e..0000000
--- a/drivers/staging/winbond/bssdscpt.h
+++ /dev/null
@@ -1,164 +0,0 @@
-#ifndef __WINBOND_BSSDSCPT_H
-#define __WINBOND_BSSDSCPT_H
-
-#include <linux/types.h>
-
-#include "mds_s.h"
-#include "mlme_s.h"
-
-//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-//	bssdscpt.c
-//		BSS descriptor data base
-//	history :
-//
-//	Description:
-//		BSS descriptor data base will store the information of the stations at the
-//		surrounding environment. The first entry( psBSS(0) ) will not be used and the
-//		second one( psBSS(1) ) will be used for the broadcast address.
-//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-//#define MAX_ACC_RSSI_COUNT		10
-#define MAX_ACC_RSSI_COUNT		6
-
-///////////////////////////////////////////////////////////////////////////
-//
-// BSS Description set Element , to store scan received Beacon information
-//
-// Our's differs slightly from the specs. The specify a PHY_Parameter_Set.
-// Since we're only doing a DS design right now, we just have a DS structure.
-//////////////////////////////////////////////////////////////////////////////
-typedef struct BSSDescriptionElement
-{
-	u32		SlotValid;
-	u32		PowerSaveMode;
-	RXLAYER1	RxLayer1;
-
-    u8		abPeerAddress[ MAC_ADDR_LENGTH + 2 ]; // peer MAC Address associated with this session. 6-OCTET value
-    u32		dwBgScanStamp;		// BgScan Sequence Counter stamp, record psROAM->dwScanCounter.
-
-	u16		Beacon_Period;
-	u16		wATIM_Window;
-
-    u8		abBssID[ MAC_ADDR_LENGTH + 2 ];				// 6B
-
-    u8		bBssType;
-    u8		DTIM_Period;        // 1 octet usually from TIM element, if present
-	u8		boInTimerHandler;
-	u8		boERP;			// analysis ERP or (extended) supported rate element
-
-	u8		Timestamp[8];
-	u8		BasicRate[32];
-	u8		OperationalRate[32];
-	u32		dwBasicRateBitmap;			//bit map, retrieve from SupportedRateSet
-	u32		dwOperationalRateBitmap;	//bit map, retrieve from SupportedRateSet and
-										// ExtendedSupportedRateSet
-	// For RSSI calculating
-	u32		HalRssi[MAX_ACC_RSSI_COUNT]; // Encode. It must use MACRO of HAL to get the LNA and AGC data
-	u32		HalRssiIndex;
-
-	////From beacon/probe response
-    struct SSID_Element SSID;				// 34B
-	u8	reserved_1[ 2 ];
-
-    struct Capability_Information_Element   CapabilityInformation;  // 2B
-	u8	reserved_2[ 2 ];
-
-    struct CF_Parameter_Set_Element    CF_Parameter_Set;		// 8B
-    struct IBSS_Parameter_Set_Element  IBSS_Parameter_Set;		// 4B
-    struct TIM_Element                 TIM_Element_Set; 			// 256B
-
-    struct DS_Parameter_Set_Element    DS_Parameter_Set;		// 3B
-	u8	reserved_3;
-
-	struct ERP_Information_Element		ERP_Information_Set;	// 3B
-	u8	reserved_4;
-
-    struct Supported_Rates_Element     SupportedRateSet;			// 10B
-	u8	reserved_5[2];
-
-	struct Extended_Supported_Rates_Element	ExtendedSupportedRateSet;	// 257B
-	u8	reserved_6[3];
-
-	u8	band;
-	u8	reserved_7[3];
-
-	// for MLME module
-    u16		wState;			// the current state of the system
-	u16		wIndex;			// THIS BSS element entry index
-
-	void*	psadapter;		// pointer to THIS adapter
-	struct timer_list timer;  // MLME timer
-
-    // Authentication
-    u16		wAuthAlgo;      // peer MAC MLME use Auth algorithm, default OPEN_AUTH
-    u16		wAuthSeqNum;    // current local MAC sendout AuthReq sequence number
-
-	u8		auth_challengeText[128];
-
-	////For XP:
-    u32		ies_len;		// information element length
-    u8		ies[256];		// information element
-
-	////For WPA
-	u8	RsnIe_Type[2];		//added by ws for distinguish WPA and WPA2 05/14/04
-	u8	RsnIe_len;
-    u8	Rsn_Num;
-
-    // to record the rsn cipher suites,addded by ws 09/05/04
-	SUITE_SELECTOR			group_cipher; // 4B
-	SUITE_SELECTOR			pairwise_key_cipher_suites[WLAN_MAX_PAIRWISE_CIPHER_SUITE_COUNT];
-	SUITE_SELECTOR			auth_key_mgt_suites[WLAN_MAX_AUTH_KEY_MGT_SUITE_LIST_COUNT];
-
-	u16					pairwise_key_cipher_suite_count;
-	u16					auth_key_mgt_suite_count;
-
-	u8					pairwise_key_cipher_suite_selected;
-	u8					auth_key_mgt_suite_selected;
-	u8					reserved_8[2];
-
-	struct RSN_Capability_Element  rsn_capabilities; // 2B
-	u8					reserved_9[2];
-
-    //to record the rsn cipher suites for WPA2
-    #ifdef _WPA2_
-	u32					pre_auth;		//added by WS for distinguish for 05/04/04
-    SUITE_SELECTOR			wpa2_group_cipher; // 4B
-	SUITE_SELECTOR			wpa2_pairwise_key_cipher_suites[WLAN_MAX_PAIRWISE_CIPHER_SUITE_COUNT];
-	SUITE_SELECTOR			wpa2_auth_key_mgt_suites[WLAN_MAX_AUTH_KEY_MGT_SUITE_LIST_COUNT];
-
-	u16					wpa2_pairwise_key_cipher_suite_count;
-	u16					wpa2_auth_key_mgt_suite_count;
-
-	u8					wpa2_pairwise_key_cipher_suite_selected;
-	u8					wpa2_auth_key_mgt_suite_selected;
-	u8					reserved_10[2];
-
-	struct RSN_Capability_Element  wpa2_rsn_capabilities; // 2B
-	u8					reserved_11[2];
-    #endif //endif _WPA2_
-
-	//For Replay protection
-//	u8		PairwiseTSC[6];
-//	u8		GroupTSC[6];
-
-	////For up-to-date
-	u32		ScanTimeStamp;	//for the decision whether the station/AP(may exist at
-							//different channels) has left. It must be detected by
-							//scanning. Local device may connected or disconnected.
-	u32		BssTimeStamp;	//Only for the decision whether the station/AP(exist in
-							//the same channel, and no scanning) if local device has
-							//connected successfully.
-
-	// 20061108 Add for storing WPS_IE. [E id][Length][OUI][Data]
-	u8		WPS_IE_Data[MAX_IE_APPEND_SIZE];
-	u16		WPS_IE_length;
-	u16		WPS_IE_length_tmp; // For verify there is an WPS_IE in Beacon or probe response
-
-} WB_BSSDESCRIPTION, *PWB_BSSDESCRIPTION;
-
-#define wBSSConnectedSTA(adapter)             \
-    ((u16)(adapter)->sLocalPara.wConnectedSTAindex)
-
-#define psBSS(i)			(&(adapter->asBSSDescriptElement[(i)]))
-
-#endif
diff --git a/drivers/staging/winbond/common.h b/drivers/staging/winbond/common.h
deleted file mode 100644
index c4d9604..0000000
--- a/drivers/staging/winbond/common.h
+++ /dev/null
@@ -1,27 +0,0 @@
-//
-// common.h
-//
-// This file contains the OS dependant definition and function.
-// Every OS has this file individual.
-//
-
-#define DebugUsbdStatusInformation( _A )
-
-#ifndef COMMON_DEF
-#define COMMON_DEF
-
-//#define DEBUG_ENABLED  1
-
-//==================================================================================================
-// Common function definition
-//==================================================================================================
-#define DEBUG_ENABLED
-#define ETH_LENGTH_OF_ADDRESS	6
-#ifdef DEBUG_ENABLED
-#define WBDEBUG( _M )	printk _M
-#else
-#define WBDEBUG( _M )	0
-#endif
-
-#endif // COMMON_DEF
-
diff --git a/drivers/staging/winbond/core.h b/drivers/staging/winbond/core.h
index fe142a1..eb4c090 100644
--- a/drivers/staging/winbond/core.h
+++ b/drivers/staging/winbond/core.h
@@ -3,9 +3,9 @@
 
 #include <linux/wireless.h>
 
-#include "bssdscpt.h"
-#include "mto.h"
+#include "mlme_s.h"
 #include "wbhal_s.h"
+#include "mto.h"
 
 #define WBLINUX_PACKET_ARRAY_SIZE (ETHERNET_TX_DESCRIPTORS*4)
 
@@ -15,12 +15,11 @@
 	u32 adapterIndex;	// 20060703.4 Add for using padapterContext global adapter point
 
 	WB_LOCALDESCRIPT sLocalPara;	// Myself connected parameters
-	PWB_BSSDESCRIPTION asBSSDescriptElement;
 
 	MLME_FRAME sMlmeFrame;	// connect to peerSTA parameters
 
 	MTO_PARAMETERS sMtoPara;	// MTO_struct ...
-	hw_data_t sHwData;	//For HAL
+	struct hw_data sHwData;	//For HAL
 	MDS Mds;
 
 	spinlock_t SpinLock;
diff --git a/drivers/staging/winbond/ds_tkip.h b/drivers/staging/winbond/ds_tkip.h
deleted file mode 100644
index 9c5c4e7..0000000
--- a/drivers/staging/winbond/ds_tkip.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef __WINBOND_DS_TKIP_H
-#define __WINBOND_DS_TKIP_H
-
-#include <linux/types.h>
-
-// Rotation functions on 32 bit values
-#define ROL32( A, n ) \
-    ( ((A) << (n)) | ( ((A)>>(32-(n)))  & ( (1UL << (n)) - 1 ) ) )
-
-#define ROR32( A, n )   ROL32( (A), 32-(n) )
-
-
-typedef struct tkip
-{
-    u32	K0, K1;		// Key
-	union
-	{
-		struct // Current state
-		{
-			u32	L;
-			u32	R;
-		};
-		u8	LR[8];
-	};
-	union
-	{
-		u32	M;		// Message accumulator (single word)
-		u8	Mb[4];
-	};
-	s32		bytes_in_M;	// # bytes in M
-} tkip_t;
-
-//void _append_data( u8 *pData, u16 size, tkip_t *p );
-void Mds_MicGet(  void* adapter,  void* pRxLayer1,  u8 *pKey,  u8 *pMic );
-void Mds_MicFill(  void* adapter,  void* pDes,  u8 *XmitBufAddress );
-
-#endif
diff --git a/drivers/staging/winbond/gl_80211.h b/drivers/staging/winbond/gl_80211.h
deleted file mode 100644
index 5a244c4..0000000
--- a/drivers/staging/winbond/gl_80211.h
+++ /dev/null
@@ -1,126 +0,0 @@
-#ifndef __GL_80211_H__
-#define __GL_80211_H__
-
-#include <linux/types.h>
-
-/****************** CONSTANT AND MACRO SECTION ******************************/
-
-/* BSS Type */
-enum {
-    WLAN_BSSTYPE_INFRASTRUCTURE         = 0,
-    WLAN_BSSTYPE_INDEPENDENT,
-    WLAN_BSSTYPE_ANY_BSS,
-};
-
-
-
-/* Preamble_Type, see <SFS-802.11G-MIB-203> */
-typedef enum preamble_type {
-    WLAN_PREAMBLE_TYPE_SHORT,
-    WLAN_PREAMBLE_TYPE_LONG,
-}    preamble_type_e;
-
-
-/* Slot_Time_Type, see <SFS-802.11G-MIB-208> */
-typedef enum slot_time_type {
-    WLAN_SLOT_TIME_TYPE_LONG,
-    WLAN_SLOT_TIME_TYPE_SHORT,
-}    slot_time_type_e;
-
-/*--------------------------------------------------------------------------*/
-/* Encryption Mode */
-typedef enum {
-    WEP_DISABLE                                         = 0,
-    WEP_64,
-    WEP_128,
-
-    ENCRYPT_DISABLE,
-    ENCRYPT_WEP,
-    ENCRYPT_WEP_NOKEY,
-    ENCRYPT_TKIP,
-    ENCRYPT_TKIP_NOKEY,
-    ENCRYPT_CCMP,
-    ENCRYPT_CCMP_NOKEY,
-}    encryption_mode_e;
-
-typedef enum _WLAN_RADIO {
-    WLAN_RADIO_ON,
-    WLAN_RADIO_OFF,
-    WLAN_RADIO_MAX, // not a real type, defined as an upper bound
-} WLAN_RADIO;
-
-typedef struct _WLAN_RADIO_STATUS {
-	WLAN_RADIO HWStatus;
-	WLAN_RADIO SWStatus;
-} WLAN_RADIO_STATUS;
-
-//----------------------------------------------------------------------------
-// 20041021 1.1.81.1000 ybjiang
-// add for radio notification
-typedef
-void (*RADIO_NOTIFICATION_HANDLER)(
-	void *Data,
-	void *RadioStatusBuffer,
-	u32 RadioStatusBufferLen
-	);
-
-typedef struct _WLAN_RADIO_NOTIFICATION
-{
-    RADIO_NOTIFICATION_HANDLER RadioChangeHandler;
-    void *Data;
-} WLAN_RADIO_NOTIFICATION;
-
-//----------------------------------------------------------------------------
-// 20041102 1.1.91.1000 ybjiang
-// add for OID_802_11_CUST_REGION_CAPABILITIES and OID_802_11_OID_REGION
-typedef enum _WLAN_REGION_CODE
-{
-	WLAN_REGION_UNKNOWN,
-	WLAN_REGION_EUROPE,
-	WLAN_REGION_JAPAN,
-	WLAN_REGION_USA,
-	WLAN_REGION_FRANCE,
-	WLAN_REGION_SPAIN,
-	WLAN_REGION_ISRAEL,
-	WLAN_REGION_MAX, // not a real type, defined as an upper bound
-} WLAN_REGION_CODE;
-
-#define REGION_NAME_MAX_LENGTH   256
-
-typedef struct _WLAN_REGION_CHANNELS
-{
-	u32 Length;
-	u32 NameLength;
-	u8 Name[REGION_NAME_MAX_LENGTH];
-	WLAN_REGION_CODE Code;
-	u32 Frequency[1];
-} WLAN_REGION_CHANNELS;
-
-typedef struct _WLAN_REGION_CAPABILITIES
-{
-	u32 NumberOfItems;
-	WLAN_REGION_CHANNELS Region[1];
-} WLAN_REGION_CAPABILITIES;
-
-typedef struct _region_name_map {
-	WLAN_REGION_CODE region;
-	u8 *name;
-	u32 *channels;
-} region_name_map;
-
-/*--------------------------------------------------------------------------*/
-#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
-#define MACSTR "%02X:%02X:%02X:%02X:%02X:%02X"
-
-// TODO: 0627 kevin
-#define MIC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5], (a)[6], (a)[7]
-#define MICSTR "%02X %02X %02X %02X %02X %02X %02X %02X"
-
-#define MICKEY2STR(a)   MIC2STR(a)
-#define MICKEYSTR       MICSTR
-
-
-#endif /* __GL_80211_H__ */
-/*** end of file ***/
-
-
diff --git a/drivers/staging/winbond/ioctls.h b/drivers/staging/winbond/ioctls.h
deleted file mode 100644
index e8b35dc..0000000
--- a/drivers/staging/winbond/ioctls.h
+++ /dev/null
@@ -1,678 +0,0 @@
-//============================================================================
-//  IOCTLS.H -
-//
-//  Description:
-//    Define the IOCTL codes.
-//
-//  Revision history:
-//  --------------------------------------------------------------------------
-//
-//  Copyright (c) 2002-2004 Winbond Electronics Corp. All rights reserved.
-//=============================================================================
-
-#ifndef _IOCTLS_H
-#define _IOCTLS_H
-
-// PD43 Keep it - Used with the Win33 application
-// #include <winioctl.h>
-
-//========================================================
-// 20040108 ADD the follow for test
-//========================================================
-#define INFORMATION_LENGTH sizeof(unsigned int)
-
-#define WB32_IOCTL_INDEX  0x0900 //­×§ďĽHŤKŹŰŽe//
-
-#define Wb32_RegisterRead			CTL_CODE(	\
-			FILE_DEVICE_UNKNOWN,				\
-            WB32_IOCTL_INDEX + 0,				\
-            METHOD_BUFFERED,					\
-            FILE_ANY_ACCESS)
-
-#define Wb32_RegisterWrite			CTL_CODE(	\
-            FILE_DEVICE_UNKNOWN,				\
-            WB32_IOCTL_INDEX + 1,				\
-            METHOD_BUFFERED,					\
-            FILE_ANY_ACCESS)
-
-#define Wb32_SendPacket				CTL_CODE(	\
-            FILE_DEVICE_UNKNOWN,				\
-            WB32_IOCTL_INDEX + 2,				\
-            METHOD_BUFFERED,					\
-            FILE_ANY_ACCESS)
-
-#define Wb32_QuerySendResult		CTL_CODE(	\
-            FILE_DEVICE_UNKNOWN,				\
-            WB32_IOCTL_INDEX + 3,				\
-            METHOD_BUFFERED,					\
-            FILE_ANY_ACCESS)
-
-#define Wb32_SetFragmentThreshold	CTL_CODE(	\
-            FILE_DEVICE_UNKNOWN,				\
-            WB32_IOCTL_INDEX + 4,				\
-            METHOD_BUFFERED,					\
-            FILE_ANY_ACCESS)
-
-#define Wb32_SetLinkStatus		CTL_CODE(	\
-            FILE_DEVICE_UNKNOWN,				\
-            WB32_IOCTL_INDEX + 5,				\
-            METHOD_BUFFERED,					\
-            FILE_ANY_ACCESS)
-
-#define Wb32_SetBulkIn			CTL_CODE(	\
-            FILE_DEVICE_UNKNOWN,				\
-            WB32_IOCTL_INDEX + 6,				\
-            METHOD_BUFFERED,					\
-            FILE_ANY_ACCESS)
-
-#define Wb32_LoopbackTest			CTL_CODE(	\
-            FILE_DEVICE_UNKNOWN,				\
-            WB32_IOCTL_INDEX + 7,				\
-            METHOD_BUFFERED,					\
-            FILE_ANY_ACCESS)
-
-#define Wb35_EEPromRead				CTL_CODE(	\
-            FILE_DEVICE_UNKNOWN,				\
-            WB32_IOCTL_INDEX + 8,				\
-            METHOD_BUFFERED,					\
-            FILE_ANY_ACCESS)
-
-#define Wb35_EEPromWrite			CTL_CODE(	\
-            FILE_DEVICE_UNKNOWN,				\
-            WB32_IOCTL_INDEX + 9,				\
-            METHOD_BUFFERED,					\
-            FILE_ANY_ACCESS)
-
-#define Wb35_FlashReadData			CTL_CODE(	\
-            FILE_DEVICE_UNKNOWN,				\
-            WB32_IOCTL_INDEX + 10,				\
-            METHOD_BUFFERED,					\
-            FILE_ANY_ACCESS)
-
-#define Wb35_FlashWrite				CTL_CODE(	\
-            FILE_DEVICE_UNKNOWN,				\
-            WB32_IOCTL_INDEX + 11,				\
-            METHOD_BUFFERED,					\
-            FILE_ANY_ACCESS)
-
-#define Wb35_FlashWriteBurst		CTL_CODE(	\
-            FILE_DEVICE_UNKNOWN,				\
-            WB32_IOCTL_INDEX + 12,				\
-            METHOD_BUFFERED,					\
-            FILE_ANY_ACCESS)
-
-#define Wb35_TxBurstStart			CTL_CODE(	\
-            FILE_DEVICE_UNKNOWN,				\
-            WB32_IOCTL_INDEX + 13,				\
-            METHOD_BUFFERED,					\
-            FILE_ANY_ACCESS)
-
-#define Wb35_TxBurstStop			CTL_CODE(	\
-            FILE_DEVICE_UNKNOWN,				\
-            WB32_IOCTL_INDEX + 14,				\
-            METHOD_BUFFERED,					\
-            FILE_ANY_ACCESS)
-
-#define Wb35_TxBurstStatus			CTL_CODE(	\
-            FILE_DEVICE_UNKNOWN,				\
-            WB32_IOCTL_INDEX + 15,				\
-            METHOD_BUFFERED,					\
-            FILE_ANY_ACCESS)
-
-// For IOCTL interface
-//================================================
-#define LINKNAME_STRING     "\\DosDevices\\W35UND"
-#define NTDEVICE_STRING     "\\Device\\W35UND"
-#define APPLICATION_LINK	"\\\\.\\W35UND"
-
-#define WB_IOCTL_INDEX      0x0800
-#define WB_IOCTL_TS_INDEX   WB_IOCTL_INDEX + 60
-#define WB_IOCTL_DUT_INDEX  WB_IOCTL_TS_INDEX + 40
-
-//=============================================================================
-// IOCTLS defined for DUT (Device Under Test)
-
-// IOCTL_WB_802_11_DUT_MAC_ADDRESS
-// Query: Return the dot11StationID
-// Set  : Set the dot11StationID. Demo only.
-//
-#define IOCTL_WB_802_11_DUT_MAC_ADDRESS     CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                        \
-            WB_IOCTL_DUT_INDEX + 1,                     \
-            METHOD_BUFFERED,                            \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_BSS_DESCRIPTION
-// Query: Return the info. of the current connected BSS.
-// Set  : None.
-//
-#define IOCTL_WB_802_11_DUT_BSS_DESCRIPTION   CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                          \
-            WB_IOCTL_DUT_INDEX + 2,                       \
-            METHOD_BUFFERED,                              \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_TX_RATE
-// Query: Return the current transmission rate.
-// Set  : Set the transmission rate of the Tx packets.
-//
-#define IOCTL_WB_802_11_DUT_TX_RATE             CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 3,                         \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_CURRENT_STA_STATE
-// Query: Return the current STA state. (WB_STASTATE type)
-// Set  : None.
-//
-#define IOCTL_WB_802_11_DUT_CURRENT_STA_STATE   CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 4,                         \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-/////////// 10/31/02' Added /////////////////////
-
-// IOCTL_WB_802_11_DUT_START_IBSS_REQUEST
-// Query: None.
-// Set  : Start a new IBSS
-//
-#define IOCTL_WB_802_11_DUT_START_IBSS_REQUEST  CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 5,                         \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_JOIN_REQUEST
-// Query: None.
-// Set  : Synchronize with the selected BSS
-//
-#define IOCTL_WB_802_11_DUT_JOIN_REQUEST        CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 6,                         \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_AUTHEN_REQUEST
-// Query: None.
-// Set  : Authenticate with the BSS
-//
-#define IOCTL_WB_802_11_DUT_AUTHEN_REQUEST      CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 7,                         \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_DEAUTHEN_REQUEST
-// Query: None.
-// Set  : DeAuthenticate withe the BSS
-//
-#define IOCTL_WB_802_11_DUT_DEAUTHEN_REQUEST    CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 8,                         \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_ASSOC_REQUEST
-// Query: None.
-// Set  : Associate withe the BSS
-//
-#define IOCTL_WB_802_11_DUT_ASSOC_REQUEST       CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 9,                         \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_REASSOC_REQUEST
-// Query: None.
-// Set  : ReAssociate withe the BSS
-//
-#define IOCTL_WB_802_11_DUT_REASSOC_REQUEST     CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 10,                        \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-
-// IOCTL_WB_802_11_DUT_DISASSOC_REQUEST
-// Query: None.
-// Set  : DisAssociate withe the BSS
-//
-#define IOCTL_WB_802_11_DUT_DISASSOC_REQUEST    CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 11,                        \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_FRAG_THRESHOLD
-// Query: Return the dot11FragmentThreshold
-// Set  : Set the dot11FragmentThreshold
-//
-#define IOCTL_WB_802_11_DUT_FRAG_THRESHOLD      CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 12,                        \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_RTS_THRESHOLD
-// Query: Return the dot11RTSThreshold
-// Set  : Set the dot11RTSThresold
-//
-#define IOCTL_WB_802_11_DUT_RTS_THRESHOLD       CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 13,                        \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_WEP_KEYMODE
-// Query: Get the WEP key mode.
-// Set  : Set the WEP key mode: disable/64 bits/128 bits
-//
-#define IOCTL_WB_802_11_DUT_WEP_KEYMODE         CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 14,                        \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_WEP_KEYVALUE
-// Query: None.
-// Set  : fill in the WEP key value
-//
-#define IOCTL_WB_802_11_DUT_WEP_KEYVALUE        CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 15,                        \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_RESET
-// Query: None.
-// Set  : Reset S/W and H/W
-//
-#define IOCTL_WB_802_11_DUT_RESET          CTL_CODE(       \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 16,                        \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_POWER_SAVE
-// Query: None.
-// Set  : Set Power Save Mode
-//
-#define IOCTL_WB_802_11_DUT_POWER_SAVE    CTL_CODE(        \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 17,                        \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_BSSID_LIST_SCAN
-// Query: None.
-// Set  :
-//
-#define IOCTL_WB_802_11_DUT_BSSID_LIST_SCAN CTL_CODE(      \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 18,                        \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_BSSID_LIST
-// Query: Return the BSS info of BSSs in the last scanning process
-// Set  : None.
-//
-#define IOCTL_WB_802_11_DUT_BSSID_LIST    CTL_CODE(        \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 19,                        \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_STATISTICS
-// Query: Return the statistics of Tx/Rx.
-// Set  : None.
-//
-#define IOCTL_WB_802_11_DUT_STATISTICS    CTL_CODE(        \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 20,                        \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_ACCEPT_BEACON
-// Query: Return the current mode to accept beacon or not.
-// Set  : Enable or disable allowing the HW-MAC to pass the beacon to the SW-MAC
-// Arguments: unsigned char
-//
-#define IOCTL_WB_802_11_DUT_ACCEPT_BEACON  CTL_CODE(       \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 21,                        \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_ROAMING
-// Query: Return the roaming function status
-// Set  : Enable/Disable the roaming function.
-#define IOCTL_WB_802_11_DUT_ROAMING        CTL_CODE(       \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 22,                        \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_DTO
-// Query: Return the DTO(Data Throughput Optimization)
-//        function status (TRUE or FALSE)
-// Set  : Enable/Disable the DTO function.
-//
-#define IOCTL_WB_802_11_DUT_DTO            CTL_CODE(       \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 23,                        \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_ANTENNA_DIVERSITY
-// Query: Return the antenna diversity status. (TRUE/ON or FALSE/OFF)
-// Set  : Enable/Disable the antenna diversity.
-//
-#define IOCTL_WB_802_11_DUT_ANTENNA_DIVERSITY CTL_CODE(    \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 24,                        \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-//-------------- new added for a+b+g ---------------------
-// IOCTL_WB_802_11_DUT_MAC_OPERATION_MODE
-// Query: Return the MAC operation mode. (MODE_802_11_BG, MODE_802_11_A,
-//			 MODE_802_11_ABG, MODE_802_11_BG_IBSS)
-// Set  : Set the MAC operation mode.
-//
-#define IOCTL_WB_802_11_DUT_MAC_OPERATION_MODE CTL_CODE(    \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 25,                        \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_TX_RATE_REDEFINED
-// Query: Return the current tx rate which follows the definition in spec. (for
-//			example, 5.5M => 0x0b)
-// Set  : None
-//
-#define IOCTL_WB_802_11_DUT_TX_RATE_REDEFINED CTL_CODE(    \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 26,                        \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_PREAMBLE_MODE
-// Query: Return the preamble mode. (auto or long)
-// Set  : Set the preamble mode.
-//
-#define IOCTL_WB_802_11_DUT_PREAMBLE_MODE CTL_CODE(    \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 27,                        \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_SLOT_TIME_MODE
-// Query: Return the slot time mode. (auto or long)
-// Set  : Set the slot time mode.
-//
-#define IOCTL_WB_802_11_DUT_SLOT_TIME_MODE CTL_CODE(    \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 28,                        \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-//------------------------------------------------------------------
-
-// IOCTL_WB_802_11_DUT_ADVANCE_STATUS
-// Query:
-// Set  : NONE
-//
-#define IOCTL_WB_802_11_DUT_ADVANCE_STATUS CTL_CODE(    \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 29,                        \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_TX_RATE_MODE
-// Query: Return the tx rate mode. (RATE_AUTO, RATE_1M, .., RATE_54M, RATE_MAX)
-// Set  : Set the tx rate mode.  (RATE_AUTO, RATE_1M, .., RATE_54M, RATE_MAX)
-//
-#define IOCTL_WB_802_11_DUT_TX_RATE_MODE CTL_CODE(    \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 30,                        \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_DTO_PARA
-// Query: Return the DTO parameters
-// Set  : Set the DTO parameters
-//
-#define IOCTL_WB_802_11_DUT_DTO_PARA CTL_CODE(    \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 31,                        \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_EVENT_LOG
-// Query: Return event log
-// Set  : Reset event log
-//
-#define IOCTL_WB_802_11_DUT_EVENT_LOG CTL_CODE(    \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 32,                        \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_CWMIN
-// Query: NONE(It will be obtained by IOCTL_WB_802_11_DUT_ADVANCE_STATUS)
-// Set  : Set CWMin value
-//
-#define IOCTL_WB_802_11_DUT_CWMIN CTL_CODE(    \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 33,                        \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_CWMAX
-// Query: NONE(It will be obtained by IOCTL_WB_802_11_DUT_ADVANCE_STATUS)
-// Set  : Set CWMax value
-//
-#define IOCTL_WB_802_11_DUT_CWMAX CTL_CODE(    \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_DUT_INDEX + 34,                        \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-
-//==========================================================
-// IOCTLs for Testing
-
-// IOCTL_WB_802_11_TS_SET_CXX_REG
-// Query: None
-// Set  : Write the value to one of Cxx register.
-//
-#define IOCTL_WB_802_11_TS_SET_CXX_REG  CTL_CODE(          \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 0,                          \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_TS_GET_CXX_REG
-// Query: Return the value of the Cxx register.
-// Set  : Write the reg no. (0x00, 0x04, 0x08 etc)
-//
-#define IOCTL_WB_802_11_TS_GET_CXX_REG  CTL_CODE(          \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 1,                          \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_TS_SET_DXX_REG
-// Query: None
-// Set  : Write the value to one of Dxx register.
-//
-#define IOCTL_WB_802_11_TS_SET_DXX_REG  CTL_CODE(          \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 2,                          \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_TS_GET_DXX_REG
-// Query: Return the value of the Dxx register.
-// Set  : Write the reg no. (0x00, 0x04, 0x08 etc)
-//
-#define IOCTL_WB_802_11_TS_GET_DXX_REG  CTL_CODE(          \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 3,                          \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-//============================================================
-// [TS]
-
-#define IOCTL_WB_802_11_TS_TX_RATE              CTL_CODE(   \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 4,                          \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_CURRENT_CHANNEL      CTL_CODE(   \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 5,                          \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_ENABLE_SEQNO         CTL_CODE(   \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 6,                          \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_ENALBE_ACKEDPACKET   CTL_CODE(   \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 7,                          \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_INHIBIT_CRC          CTL_CODE(   \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 8,                          \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_RESET_RCV_COUNTER    CTL_CODE(   \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 9,                          \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_SET_TX_TRIGGER       CTL_CODE(   \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 10,                         \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_FAILED_TX_COUNT       CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 11,                         \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// [TS1]
-#define IOCTL_WB_802_11_TS_TX_POWER             CTL_CODE(   \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 12,                         \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_MODE_ENABLE			 CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 13,                         \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_MODE_DISABLE			 CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 14,                         \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_ANTENNA				 CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 15,                         \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_ADAPTER_INFO			 CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 16,                         \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_MAC_ADDRESS			 CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 17,                         \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_BSSID				 CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 18,                         \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_RF_PARAMETER			 CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 19,                         \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_FILTER				 CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 20,                         \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_CALIBRATION			 CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 21,                         \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_BSS_MODE				 CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 22,                         \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_SET_SSID				 CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 23,                         \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_IBSS_CHANNEL			 CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 24,                         \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-// set/query the slot time value(short or long slot time)
-#define IOCTL_WB_802_11_TS_SLOT_TIME			 CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 25,                         \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_SLOT_TIME			 CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 25,                         \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_RX_STATISTICS		 CTL_CODE(  \
-            FILE_DEVICE_UNKNOWN,                            \
-            WB_IOCTL_TS_INDEX + 26,                         \
-            METHOD_BUFFERED,                                \
-            FILE_ANY_ACCESS)
-
-#endif  // #ifndef _IOCTLS_H
-
-
diff --git a/drivers/staging/winbond/mds.c b/drivers/staging/winbond/mds.c
index e431406..c7af092 100644
--- a/drivers/staging/winbond/mds.c
+++ b/drivers/staging/winbond/mds.c
@@ -1,9 +1,7 @@
-#include "ds_tkip.h"
-#include "gl_80211.h"
 #include "mds_f.h"
 #include "mlmetxrx_f.h"
-#include "mto_f.h"
-#include "os_common.h"
+#include "mto.h"
+#include "sysdef.h"
 #include "wbhal_f.h"
 #include "wblinux_f.h"
 
@@ -374,7 +372,7 @@
 
 	pDes->TxRate = ctmp1;
 	#ifdef _PE_TX_DUMP_
-	WBDEBUG(("Tx rate =%x\n", ctmp1));
+	printk("Tx rate =%x\n", ctmp1);
 	#endif
 
 	pT01->T01_modulation_type = (ctmp1%3) ? 0 : 1;
@@ -418,14 +416,14 @@
 void
 Mds_Tx(struct wbsoft_priv * adapter)
 {
-	phw_data_t	pHwData = &adapter->sHwData;
+	struct hw_data *	pHwData = &adapter->sHwData;
 	PMDS		pMds = &adapter->Mds;
 	DESCRIPTOR	TxDes;
 	PDESCRIPTOR	pTxDes = &TxDes;
 	u8		*XmitBufAddress;
 	u16		XmitBufSize, PacketSize, stmp, CurrentSize, FragmentThreshold;
 	u8		FillIndex, TxDesIndex, FragmentCount, FillCount;
-	unsigned char	BufferFilled = false, MICAdd = 0;
+	unsigned char	BufferFilled = false;
 
 
 	if (pMds->TxPause)
@@ -442,7 +440,7 @@
 		FillIndex = pMds->TxFillIndex;
 		if (pMds->TxOwner[FillIndex]) { // Is owned by software 0:Yes 1:No
 #ifdef _PE_TX_DUMP_
-			WBDEBUG(("[Mds_Tx] Tx Owner is H/W.\n"));
+			printk("[Mds_Tx] Tx Owner is H/W.\n");
 #endif
 			break;
 		}
@@ -488,7 +486,7 @@
 			// For speed up Key setting
 			if (pTxDes->EapFix) {
 #ifdef _PE_TX_DUMP_
-				WBDEBUG(("35: EPA 4th frame detected. Size = %d\n", PacketSize));
+				printk("35: EPA 4th frame detected. Size = %d\n", PacketSize);
 #endif
 				pHwData->IsKeyPreSet = 1;
 			}
@@ -499,12 +497,6 @@
 			// Set RTS/CTS and Normal duration field into buffer
 			Mds_DurationSet(adapter, pTxDes, XmitBufAddress);
 
-			//
-			// Calculation MIC from buffer which maybe fragment, then fill into temporary address 8 byte
-			// 931130.5.e
-			if (MICAdd)
-				Mds_MicFill( adapter, pTxDes, XmitBufAddress );
-
 			//Shift to the next address
 			XmitBufSize += CurrentSize;
 			XmitBufAddress += CurrentSize;
@@ -561,7 +553,7 @@
 Mds_SendComplete(struct wbsoft_priv * adapter, PT02_DESCRIPTOR pT02)
 {
 	PMDS	pMds = &adapter->Mds;
-	phw_data_t	pHwData = &adapter->sHwData;
+	struct hw_data *	pHwData = &adapter->sHwData;
 	u8	PacketId = (u8)pT02->T02_Tx_PktID;
 	unsigned char	SendOK = true;
 	u8	RetryCount, TxRate;
@@ -585,7 +577,7 @@
 				else
 					pHwData->tx_retry_count[7] += RetryCount;
 				#ifdef _PE_STATE_DUMP_
-				WBDEBUG(("dto_tx_retry_count =%d\n", pHwData->dto_tx_retry_count));
+				printk("dto_tx_retry_count =%d\n", pHwData->dto_tx_retry_count);
 				#endif
 				MTO_SetTxCount(adapter, TxRate, RetryCount);
 			}
diff --git a/drivers/staging/winbond/mds_s.h b/drivers/staging/winbond/mds_s.h
index ebf61e3..9ffec17 100644
--- a/drivers/staging/winbond/mds_s.h
+++ b/drivers/staging/winbond/mds_s.h
@@ -9,6 +9,12 @@
 #include "mac_structures.h"
 #include "scan_s.h"
 
+/* Preamble_Type, see <SFS-802.11G-MIB-203> */
+enum {
+	WLAN_PREAMBLE_TYPE_SHORT,
+	WLAN_PREAMBLE_TYPE_LONG,
+};
+
 ////////////////////////////////////////////////////////////////////////////////////////////////////////
 #define MAX_USB_TX_DESCRIPTOR		15		// IS89C35 ability
 #define MAX_USB_TX_BUFFER_NUMBER	4		// Virtual pre-buffer number of MAX_USB_TX_BUFFER
@@ -17,26 +23,8 @@
 #define AUTH_REQUEST_PAIRWISE_ERROR			0		// _F flag setting
 #define AUTH_REQUEST_GROUP_ERROR			1		// _F flag setting
 
-// For variable setting
-#define CURRENT_BSS_TYPE				psBSS(psLOCAL->wConnectedSTAindex)->bBssType
-#define CURRENT_WEP_MODE				psSME->_dot11PrivacyInvoked
-#define CURRENT_BSSID					psBSS(psLOCAL->wConnectedSTAindex)->abBssID
-#define CURRENT_DESIRED_WPA_ENABLE		((psSME->bDesiredAuthMode==WPA_AUTH)||(psSME->bDesiredAuthMode==WPAPSK_AUTH))
-#ifdef _WPA2_
-#define CURRENT_DESIRED_WPA2_ENABLE		((psSME->bDesiredAuthMode==WPA2_AUTH)||(psSME->bDesiredAuthMode==WPA2PSK_AUTH))
-#endif //end def _WPA2_
-#define CURRENT_PAIRWISE_KEY_OK			psSME->pairwise_key_ok
-//[20040712 WS]
-#define CURRENT_GROUP_KEY_OK			psSME->group_key_ok
-#define CURRENT_PAIRWISE_KEY			psSME->tx_mic_key
-#define CURRENT_GROUP_KEY				psSME->group_tx_mic_key
-#define CURRENT_ENCRYPT_STATUS			psSME->encrypt_status
-#define CURRENT_WEP_ID					adapter->sSmePara._dot11WEPDefaultKeyID
-#define CURRENT_CONTROL_PORT_BLOCK		( psSME->wpa_ok!=1 || (adapter->Mds.boCounterMeasureBlock==1 && (CURRENT_ENCRYPT_STATUS==ENCRYPT_TKIP)) )
 #define CURRENT_FRAGMENT_THRESHOLD		(adapter->Mds.TxFragmentThreshold & ~0x1)
 #define CURRENT_PREAMBLE_MODE			psLOCAL->boShortPreamble?WLAN_PREAMBLE_TYPE_SHORT:WLAN_PREAMBLE_TYPE_LONG
-#define CURRENT_TX_RATE					adapter->sLocalPara.CurrentTxRate
-#define CURRENT_FALL_BACK_TX_RATE		adapter->sLocalPara.CurrentTxFallbackRate
 #define CURRENT_TX_RATE_FOR_MNG			adapter->sLocalPara.CurrentTxRateForMng
 #define CURRENT_PROTECT_MECHANISM		psLOCAL->boProtectMechanism
 #define CURRENT_RTS_THRESHOLD			adapter->Mds.TxRTSThreshold
diff --git a/drivers/staging/winbond/mlme_mib.h b/drivers/staging/winbond/mlme_mib.h
deleted file mode 100644
index ca8922e..0000000
--- a/drivers/staging/winbond/mlme_mib.h
+++ /dev/null
@@ -1,84 +0,0 @@
-//============================================================================
-//  MLMEMIB.H -
-//
-//  Description:
-//    Get and Set some of MLME MIB attributes.
-//
-//  Revision history:
-//  --------------------------------------------------------------------------
-//           20030117  PD43 Austin Liu
-//                     Initial release
-//
-//  Copyright (c) 2003 Winbond Electronics Corp. All rights reserved.
-//============================================================================
-
-#ifndef _MLME_MIB_H
-#define _MLME_MIB_H
-
-//============================================================================
-// MLMESetExcludeUnencrypted --
-//
-// Description:
-//   Set the dot11ExcludeUnencrypted value.
-//
-// Arguments:
-//   adapter        - The pointer to the miniport adapter context.
-//   ExUnencrypted  - unsigned char type. The value to be set.
-//
-// Return values:
-//   None.
-//============================================================================
-#define MLMESetExcludeUnencrypted(adapter, ExUnencrypted)     \
-{                                                              \
-    (adapter)->sLocalPara.ExcludeUnencrypted = ExUnencrypted;             \
-}
-
-//============================================================================
-// MLMEGetExcludeUnencrypted --
-//
-// Description:
-//   Get the dot11ExcludeUnencrypted value.
-//
-// Arguments:
-//   adapter        - The pointer to the miniport adapter context.
-//
-// Return values:
-//   unsigned char type. The current dot11ExcludeUnencrypted value.
-//============================================================================
-#define MLMEGetExcludeUnencrypted(adapter) ((unsigned char) (adapter)->sLocalPara.ExcludeUnencrypted)
-
-//============================================================================
-// MLMESetMaxReceiveLifeTime --
-//
-// Description:
-//   Set the dot11MaxReceiveLifeTime value.
-//
-// Arguments:
-//   adapter        - The pointer to the miniport adapter context.
-//   ReceiveLifeTime- u32 type. The value to be set.
-//
-// Return values:
-//   None.
-//============================================================================
-#define MLMESetMaxReceiveLifeTime(adapter, ReceiveLifeTime)    \
-{                                                               \
-    (adapter)->Mds.MaxReceiveTime = ReceiveLifeTime;                \
-}
-
-//============================================================================
-// MLMESetMaxReceiveLifeTime --
-//
-// Description:
-//   Get the dot11MaxReceiveLifeTime value.
-//
-// Arguments:
-//   adapter        - The pointer to the miniport adapter context.
-//
-// Return values:
-//   u32 type. The current dot11MaxReceiveLifeTime value.
-//============================================================================
-#define MLMEGetMaxReceiveLifeTime(adapter) ((u32) (adapter)->Mds.MaxReceiveTime)
-
-#endif
-
-
diff --git a/drivers/staging/winbond/mlmetxrx.c b/drivers/staging/winbond/mlmetxrx.c
index 07802af..643ceb0 100644
--- a/drivers/staging/winbond/mlmetxrx.c
+++ b/drivers/staging/winbond/mlmetxrx.c
@@ -15,7 +15,7 @@
 //
 //  Copyright (c) 1996-2002 Winbond Electronics Corp. All Rights Reserved.
 //============================================================================
-#include "os_common.h"
+#include "sysdef.h"
 
 #include "mds_f.h"
 
diff --git a/drivers/staging/winbond/mto.c b/drivers/staging/winbond/mto.c
index de11a05..94a060b 100644
--- a/drivers/staging/winbond/mto.c
+++ b/drivers/staging/winbond/mto.c
@@ -22,9 +22,8 @@
 //============================================================================
 
 // LA20040210_DTO kevin
-#include "os_common.h"
+#include "sysdef.h"
 #include "sme_api.h"
-#include "gl_80211.h"
 #include "wbhal_f.h"
 
 // Declare SQ3 to rate and fragmentation threshold table
@@ -51,20 +50,14 @@
 static int PeriodTotalTxPkt = 0;
 static int PeriodTotalTxPktRetry = 0;
 
-typedef struct
-{
-	s32 RSSI;
-	u8  TxRate;
-}RSSI2RATE;
-
 static u8 boSparseTxTraffic = false;
 
-void MTO_Init(MTO_FUNC_INPUT);
-void TxRateReductionCtrl(MTO_FUNC_INPUT);
+void MTO_Init(struct wbsoft_priv *adapter);
+void TxRateReductionCtrl(struct wbsoft_priv *adapter);
 /** 1.1.31.1000 Turbo modify */
-void MTO_SetTxCount(MTO_FUNC_INPUT, u8 t0, u8 index);
-void MTO_TxFailed(MTO_FUNC_INPUT);
-void hal_get_dto_para(MTO_FUNC_INPUT, char *buffer);
+void MTO_SetTxCount(struct wbsoft_priv *adapter, u8 t0, u8 index);
+void MTO_TxFailed(struct wbsoft_priv *adapter);
+void hal_get_dto_para(struct wbsoft_priv *adapter, char *buffer);
 
 //===========================================================================
 //  MTO_Init --
@@ -80,10 +73,9 @@
 //  Return Value:
 //    None
 //============================================================================
-void MTO_Init(MTO_FUNC_INPUT)
+void MTO_Init(struct wbsoft_priv *adapter)
 {
     int i;
-	//WBDEBUG(("[MTO] -> MTO_Init()\n"));
 	//[WKCHEN]pMTOcore_data = pcore_data;
 // 20040510 Turbo add for global variable
     MTO_TMR_CNT()       = 0;
@@ -196,7 +188,7 @@
 //      If we enable DTO, we will ignore the tx count with different tx rate from
 //      DTO rate. This is because when we adjust DTO tx rate, there could be some
 //      packets in the tx queue with previous tx rate
-void MTO_SetTxCount(MTO_FUNC_INPUT, u8 tx_rate, u8 index)
+void MTO_SetTxCount(struct wbsoft_priv *adapter, u8 tx_rate, u8 index)
 {
 	MTO_TXFLOWCOUNT()++;
 	if ((MTO_ENABLE==1) && (MTO_RATE_CHANGE_ENABLE()==1))
diff --git a/drivers/staging/winbond/mto.h b/drivers/staging/winbond/mto.h
index 0d3775e..56f2465 100644
--- a/drivers/staging/winbond/mto.h
+++ b/drivers/staging/winbond/mto.h
@@ -13,6 +13,8 @@
 
 #include <linux/types.h>
 
+struct wbsoft_priv;
+
 #define MTO_DEFAULT_TH_CNT              5
 #define MTO_DEFAULT_TH_SQ3              112  //OLD IS 13 reference JohnXu
 #define MTO_DEFAULT_TH_IDLE_SLOT        15
@@ -131,8 +133,6 @@
 } MTO_PARAMETERS, *PMTO_PARAMETERS;
 
 
-#define MTO_FUNC_INPUT              struct wbsoft_priv *	adapter
-#define MTO_FUNC_INPUT_DATA         adapter
 #define MTO_DATA()                  (adapter->sMtoPara)
 #define MTO_HAL()                   (&adapter->sHwData)
 #define MTO_SET_PREAMBLE_TYPE(x)    // 20040511 Turbo mark LM_PREAMBLE_TYPE(&pcore_data->lm_data) = (x)
@@ -140,7 +140,6 @@
 #define MTO_TXPOWER_FROM_EEPROM		(adapter->sHwData.PowerIndexFromEEPROM)
 #define LOCAL_ANTENNA_NO()			(adapter->sLocalPara.bAntennaNo)
 #define LOCAL_IS_CONNECTED()		(adapter->sLocalPara.wConnectedSTAindex != 0)
-#define LOCAL_IS_IBSS_MODE()		(adapter->asBSSDescriptElement[adapter->sLocalPara.wConnectedSTAindex].bBssType == IBSS_NET)
 #define MTO_INITTXRATE_MODE			(adapter->sHwData.SoftwareSet&0x2)	//bit 1
 // 20040510 Turbo add
 #define MTO_TMR_CNT()               MTO_DATA().TmrCnt
@@ -259,6 +258,13 @@
 	s32   Antenna;
 } STATISTICS_INFO, *PSTATISTICS_INFO;
 
+extern void MTO_Init(struct wbsoft_priv *);
+extern void MTO_PeriodicTimerExpired(struct wbsoft_priv *);
+extern void MTO_SetDTORateRange(struct wbsoft_priv *, u8 *, u8);
+extern u8 MTO_GetTxRate(struct wbsoft_priv *adapter, u32 fpdu_len);
+extern u8 MTO_GetTxFallbackRate(struct wbsoft_priv *adapter);
+extern void MTO_SetTxCount(struct wbsoft_priv *adapter, u8 t0, u8 index);
+
 #endif //__MTO_H__
 
 
diff --git a/drivers/staging/winbond/mto_f.h b/drivers/staging/winbond/mto_f.h
deleted file mode 100644
index 81f5913..0000000
--- a/drivers/staging/winbond/mto_f.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef __WINBOND_MTO_F_H
-#define __WINBOND_MTO_F_H
-
-#include "core.h"
-
-extern void MTO_Init(struct wbsoft_priv *);
-extern void MTO_PeriodicTimerExpired(struct wbsoft_priv *);
-extern void MTO_SetDTORateRange(struct wbsoft_priv *, u8 *, u8);
-extern u8 MTO_GetTxRate(MTO_FUNC_INPUT, u32 fpdu_len);
-extern u8 MTO_GetTxFallbackRate(MTO_FUNC_INPUT);
-extern void MTO_SetTxCount(MTO_FUNC_INPUT, u8 t0, u8 index);
-
-#endif
diff --git a/drivers/staging/winbond/os_common.h b/drivers/staging/winbond/os_common.h
deleted file mode 100644
index 2c276e3..0000000
--- a/drivers/staging/winbond/os_common.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "sysdef.h"
-
diff --git a/drivers/staging/winbond/phy_calibration.c b/drivers/staging/winbond/phy_calibration.c
index 6782552..af8c01e 100644
--- a/drivers/staging/winbond/phy_calibration.c
+++ b/drivers/staging/winbond/phy_calibration.c
@@ -10,7 +10,7 @@
  */
 
 /****************** INCLUDE FILES SECTION ***********************************/
-#include "os_common.h"
+#include "sysdef.h"
 #include "phy_calibration.h"
 #include "wbhal_f.h"
 
@@ -37,8 +37,8 @@
 };
 
 /****************** LOCAL FUNCTION DECLARATION SECTION **********************/
-//void    _phy_rf_write_delay(hw_data_t *phw_data);
-//void    phy_init_rf(hw_data_t *phw_data);
+//void    _phy_rf_write_delay(struct hw_data *phw_data);
+//void    phy_init_rf(struct hw_data *phw_data);
 
 /****************** FUNCTION DEFINITION SECTION *****************************/
 
@@ -341,7 +341,7 @@
 }
 
 
-void _reset_rx_cal(hw_data_t *phw_data)
+void _reset_rx_cal(struct hw_data *phw_data)
 {
 	u32     val;
 
@@ -366,7 +366,7 @@
 //
 //
 // *********************************************
-void _rxadc_dc_offset_cancellation_winbond(hw_data_t *phw_data, u32 frequency)
+void _rxadc_dc_offset_cancellation_winbond(struct hw_data *phw_data, u32 frequency)
 {
     u32     reg_agc_ctrl3;
     u32     reg_a_acq_ctrl;
@@ -465,7 +465,7 @@
 }
 
 ////////////////////////////////////////////////////////
-void _txidac_dc_offset_cancellation_winbond(hw_data_t *phw_data)
+void _txidac_dc_offset_cancellation_winbond(struct hw_data *phw_data)
 {
 	u32     reg_agc_ctrl3;
 	u32     reg_mode_ctrl;
@@ -600,7 +600,7 @@
 }
 
 ///////////////////////////////////////////////////////
-void _txqdac_dc_offset_cacellation_winbond(hw_data_t *phw_data)
+void _txqdac_dc_offset_cacellation_winbond(struct hw_data *phw_data)
 {
 	u32     reg_agc_ctrl3;
 	u32     reg_mode_ctrl;
@@ -726,7 +726,7 @@
 }
 
 //20060612.1.a 20060718.1 Modify
-u8 _tx_iq_calibration_loop_winbond(hw_data_t *phw_data,
+u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
 						   s32 a_2_threshold,
 						   s32 b_2_threshold)
 {
@@ -1032,7 +1032,7 @@
 	return 1;
 }
 
-void _tx_iq_calibration_winbond(hw_data_t *phw_data)
+void _tx_iq_calibration_winbond(struct hw_data *phw_data)
 {
 	u32     reg_agc_ctrl3;
 #ifdef _DEBUG
@@ -1195,7 +1195,7 @@
 }
 
 /////////////////////////////////////////////////////////////////////////////////////////
-u8 _rx_iq_calibration_loop_winbond(hw_data_t *phw_data, u16 factor, u32 frequency)
+u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 frequency)
 {
 	u32     reg_mode_ctrl;
 	s32     iqcal_tone_i;
@@ -1501,7 +1501,7 @@
 //////////////////////////////////////////////////////////
 
 //////////////////////////////////////////////////////////////////////////
-void _rx_iq_calibration_winbond(hw_data_t *phw_data, u32 frequency)
+void _rx_iq_calibration_winbond(struct hw_data *phw_data, u32 frequency)
 {
 // figo 20050523 marked thsi flag for can't compile for relesase
 #ifdef _DEBUG
@@ -1579,7 +1579,7 @@
 }
 
 ////////////////////////////////////////////////////////////////////////
-void phy_calibration_winbond(hw_data_t *phw_data, u32 frequency)
+void phy_calibration_winbond(struct hw_data *phw_data, u32 frequency)
 {
 	u32     reg_mode_ctrl;
 	u32     iq_alpha;
@@ -1618,7 +1618,7 @@
 }
 
 //===========================
-void phy_set_rf_data(  phw_data_t pHwData,  u32 index,  u32 value )
+void phy_set_rf_data(  struct hw_data * pHwData,  u32 index,  u32 value )
 {
    u32 ltmp=0;
 
@@ -1660,7 +1660,7 @@
 }
 
 // 20060717 modify as Bruce's mail
-unsigned char adjust_TXVGA_for_iq_mag(hw_data_t *phw_data)
+unsigned char adjust_TXVGA_for_iq_mag(struct hw_data *phw_data)
 {
 	int init_txvga = 0;
 	u32     reg_mode_ctrl;
diff --git a/drivers/staging/winbond/phy_calibration.h b/drivers/staging/winbond/phy_calibration.h
index 03b820c..51c8fde 100644
--- a/drivers/staging/winbond/phy_calibration.h
+++ b/drivers/staging/winbond/phy_calibration.h
@@ -101,7 +101,7 @@
 //#define MASK_IQCAL_IMAGE_Q         0x03FFE000
 //#define SHIFT_IQCAL_IMAGE_Q(x)     ((x)>>13)
 
-void phy_set_rf_data(  phw_data_t pHwData,  u32 index,  u32 value );
+void phy_set_rf_data(  struct hw_data * pHwData,  u32 index,  u32 value );
 #define phy_init_rf( _A )	//RFSynthesizer_initial( _A )
 
 #endif
diff --git a/drivers/staging/winbond/reg.c b/drivers/staging/winbond/reg.c
index cd21272..d915cbd 100644
--- a/drivers/staging/winbond/reg.c
+++ b/drivers/staging/winbond/reg.c
@@ -1,4 +1,4 @@
-#include "os_common.h"
+#include "sysdef.h"
 #include "wbhal_f.h"
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -915,7 +915,7 @@
 //    The address is stored in EthernetIDAddr.
 //=============================================================================================================
 void
-Uxx_ReadEthernetAddress(  phw_data_t pHwData )
+Uxx_ReadEthernetAddress(  struct hw_data * pHwData )
 {
 	u32	ltmp;
 
@@ -948,14 +948,13 @@
 //  Return Value:
 //    None.
 //==============================================================================================================
-void CardGetMulticastBit(   u8 Address[ETH_LENGTH_OF_ADDRESS],
-						   u8 *Byte,  u8 *Value )
+void CardGetMulticastBit( u8 Address[ETH_ALEN], u8 *Byte, u8 *Value )
 {
     u32 Crc;
     u32 BitNumber;
 
     // First compute the CRC.
-    Crc = CardComputeCrc(Address, ETH_LENGTH_OF_ADDRESS);
+    Crc = CardComputeCrc(Address, ETH_ALEN);
 
 	// The computed CRC is bit0~31 from left to right
 	//At first we should do right shift 25bits, and read 7bits by using '&', 2^7=128
@@ -965,7 +964,7 @@
 	*Value = (u8) ((u8)1 << (BitNumber % 8));
 }
 
-void Uxx_power_on_procedure(  phw_data_t pHwData )
+void Uxx_power_on_procedure(  struct hw_data * pHwData )
 {
 	u32	ltmp, loop;
 
@@ -1009,7 +1008,7 @@
 	Wb35Reg_WriteSync( pHwData, 0x03f8, 0x7ff );
 }
 
-void Set_ChanIndep_RfData_al7230_24(  phw_data_t pHwData, u32 *pltmp ,char number)
+void Set_ChanIndep_RfData_al7230_24(  struct hw_data * pHwData, u32 *pltmp ,char number)
 {
 	u8	i;
 
@@ -1020,7 +1019,7 @@
 	}
 }
 
-void Set_ChanIndep_RfData_al7230_50(  phw_data_t pHwData, u32 *pltmp, char number)
+void Set_ChanIndep_RfData_al7230_50(  struct hw_data * pHwData, u32 *pltmp, char number)
 {
 	u8	i;
 
@@ -1036,7 +1035,7 @@
 // RFSynthesizer_initial --
 //=============================================================================================================
 void
-RFSynthesizer_initial(phw_data_t pHwData)
+RFSynthesizer_initial(struct hw_data * pHwData)
 {
 	u32	altmp[32];
 	u32 *	pltmp = altmp;
@@ -1115,7 +1114,7 @@
 		//Start to fill RF parameters, PLL_ON should be pulled low.
 		Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000000 );
 #ifdef _PE_STATE_DUMP_
-		WBDEBUG(("* PLL_ON    low\n"));
+		printk("* PLL_ON    low\n");
 #endif
 
 		number = sizeof(al7230_rf_data_24)/sizeof(al7230_rf_data_24[0]);
@@ -1224,7 +1223,7 @@
 			//pulled high
 			Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000080 );
 			#ifdef _PE_STATE_DUMP_
-			WBDEBUG(("* PLL_ON    high\n"));
+			printk("* PLL_ON    high\n");
 			#endif
 
 			//2.4GHz
@@ -1244,7 +1243,7 @@
 			//5GHz
 			Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000000 );
 			#ifdef _PE_STATE_DUMP_
-			WBDEBUG(("* PLL_ON    low\n"));
+			printk("* PLL_ON    low\n");
 			#endif
 
 			number = sizeof(al7230_rf_data_50)/sizeof(al7230_rf_data_50[0]);
@@ -1256,7 +1255,7 @@
 
 			Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000080 );
 			#ifdef _PE_STATE_DUMP_
-			WBDEBUG(("* PLL_ON    high\n"));
+			printk("* PLL_ON    high\n");
 			#endif
 
 			//ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x12BACF;
@@ -1272,7 +1271,7 @@
 			msleep(5);
 
 			//Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000080 );
-			//WBDEBUG(("* PLL_ON    high\n"));
+			//printk("* PLL_ON    high\n");
 			break;
 
 		case RF_WB_242:
@@ -1414,7 +1413,7 @@
 	}
 }
 
-void BBProcessor_AL7230_2400(  phw_data_t pHwData)
+void BBProcessor_AL7230_2400(  struct hw_data * pHwData)
 {
 	struct wb35_reg *reg = &pHwData->reg;
 	u32	pltmp[12];
@@ -1456,7 +1455,7 @@
 
 }
 
-void BBProcessor_AL7230_5000(  phw_data_t pHwData)
+void BBProcessor_AL7230_5000(  struct hw_data * pHwData)
 {
 	struct wb35_reg *reg = &pHwData->reg;
 	u32	pltmp[12];
@@ -1510,7 +1509,7 @@
 //    None.
 //=============================================================================================================
 void
-BBProcessor_initial(  phw_data_t pHwData )
+BBProcessor_initial(  struct hw_data * pHwData )
 {
 	struct wb35_reg *reg = &pHwData->reg;
 	u32	i, pltmp[12];
@@ -1824,12 +1823,12 @@
 		reg->SQ3_filter[i] = 0x2f; // half of Bit 0 ~ 6
 }
 
-void set_tx_power_per_channel_max2829(  phw_data_t pHwData,  ChanInfo Channel)
+void set_tx_power_per_channel_max2829(  struct hw_data * pHwData,  ChanInfo Channel)
 {
 	RFSynthesizer_SetPowerIndex( pHwData, 100 ); // 20060620.1 Modify
 }
 
-void set_tx_power_per_channel_al2230(  phw_data_t pHwData,  ChanInfo Channel )
+void set_tx_power_per_channel_al2230(  struct hw_data * pHwData,  ChanInfo Channel )
 {
 	u8	index = 100;
 
@@ -1839,7 +1838,7 @@
 	RFSynthesizer_SetPowerIndex( pHwData, index );
 }
 
-void set_tx_power_per_channel_al7230(  phw_data_t pHwData,  ChanInfo Channel)
+void set_tx_power_per_channel_al7230(  struct hw_data * pHwData,  ChanInfo Channel)
 {
 	u8	i, index = 100;
 
@@ -1869,7 +1868,7 @@
 	RFSynthesizer_SetPowerIndex( pHwData, index );
 }
 
-void set_tx_power_per_channel_wb242(  phw_data_t pHwData,  ChanInfo Channel)
+void set_tx_power_per_channel_wb242(  struct hw_data * pHwData,  ChanInfo Channel)
 {
 	u8	index = 100;
 
@@ -1902,7 +1901,7 @@
 //   None.
 //=============================================================================================================
 void
-RFSynthesizer_SwitchingChannel(  phw_data_t pHwData,  ChanInfo Channel )
+RFSynthesizer_SwitchingChannel(  struct hw_data * pHwData,  ChanInfo Channel )
 {
 	struct wb35_reg *reg = &pHwData->reg;
 	u32	pltmp[16]; // The 16 is the maximum capability of hardware
@@ -2012,7 +2011,7 @@
 
 			//Start to fill RF parameters, PLL_ON should be pulled low.
 			//Wb35Reg_Write( pHwData, 0x03dc, 0x00000000 );
-			//WBDEBUG(("* PLL_ON    low\n"));
+			//printk("* PLL_ON    low\n");
 
 			//Channel independent registers
 			if( Channel.band != pHwData->band)
@@ -2037,7 +2036,7 @@
 				// Write to register. number must less and equal than 16
 				Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, number, NO_INCREMENT );
 				#ifdef _PE_STATE_DUMP_
-				WBDEBUG(("Band changed\n"));
+				printk("Band changed\n");
 				#endif
 			}
 
@@ -2130,7 +2129,7 @@
 }
 
 //Set the tx power directly from DUT GUI, not from the EEPROM. Return the current setting
-u8 RFSynthesizer_SetPowerIndex(  phw_data_t pHwData,  u8 PowerIndex )
+u8 RFSynthesizer_SetPowerIndex(  struct hw_data * pHwData,  u8 PowerIndex )
 {
 	u32	Band = pHwData->band;
 	u8	index=0;
@@ -2188,7 +2187,7 @@
 }
 
 //-- Sub function
-u8 RFSynthesizer_SetMaxim2828_24Power(  phw_data_t pHwData, u8 index )
+u8 RFSynthesizer_SetMaxim2828_24Power(  struct hw_data * pHwData, u8 index )
 {
 	u32		PowerData;
 	if( index > 1 ) index = 1;
@@ -2197,7 +2196,7 @@
 	return index;
 }
 //--
-u8 RFSynthesizer_SetMaxim2828_50Power(  phw_data_t pHwData, u8 index )
+u8 RFSynthesizer_SetMaxim2828_50Power(  struct hw_data * pHwData, u8 index )
 {
 	u32		PowerData;
 	if( index > 1 ) index = 1;
@@ -2206,7 +2205,7 @@
 	return index;
 }
 //--
-u8 RFSynthesizer_SetMaxim2827_24Power(  phw_data_t pHwData, u8 index )
+u8 RFSynthesizer_SetMaxim2827_24Power(  struct hw_data * pHwData, u8 index )
 {
 	u32		PowerData;
 	if( index > 1 ) index = 1;
@@ -2215,7 +2214,7 @@
 	return index;
 }
 //--
-u8 RFSynthesizer_SetMaxim2827_50Power(  phw_data_t pHwData, u8 index )
+u8 RFSynthesizer_SetMaxim2827_50Power(  struct hw_data * pHwData, u8 index )
 {
 	u32		PowerData;
 	if( index > 1 ) index = 1;
@@ -2224,7 +2223,7 @@
 	return index;
 }
 //--
-u8 RFSynthesizer_SetMaxim2825Power(  phw_data_t pHwData, u8 index )
+u8 RFSynthesizer_SetMaxim2825Power(  struct hw_data * pHwData, u8 index )
 {
 	u32		PowerData;
 	if( index > 1 ) index = 1;
@@ -2233,7 +2232,7 @@
 	return index;
 }
 //--
-u8 RFSynthesizer_SetAiroha2230Power(  phw_data_t pHwData, u8 index )
+u8 RFSynthesizer_SetAiroha2230Power(  struct hw_data * pHwData, u8 index )
 {
 	u32		PowerData;
 	u8		i,count;
@@ -2252,7 +2251,7 @@
 	return i;
 }
 //--
-u8 RFSynthesizer_SetAiroha7230Power(  phw_data_t pHwData, u8 index )
+u8 RFSynthesizer_SetAiroha7230Power(  struct hw_data * pHwData, u8 index )
 {
 	u32		PowerData;
 	u8		i,count;
@@ -2271,7 +2270,7 @@
 	return i;
 }
 
-u8 RFSynthesizer_SetWinbond242Power(  phw_data_t pHwData, u8 index )
+u8 RFSynthesizer_SetWinbond242Power(  struct hw_data * pHwData, u8 index )
 {
 	u32		PowerData;
 	u8		i,count;
@@ -2312,7 +2311,7 @@
 //		Initial the hardware setting and module variable
 	//
 //===========================================================================================================
-void Dxx_initial(  phw_data_t pHwData )
+void Dxx_initial(  struct hw_data * pHwData )
 {
 	struct wb35_reg *reg = &pHwData->reg;
 
@@ -2326,7 +2325,7 @@
 	Wb35Reg_WriteSync( pHwData, 0x0400, reg->D00_DmaControl );
 }
 
-void Mxx_initial(  phw_data_t pHwData )
+void Mxx_initial(  struct hw_data * pHwData )
 {
 	struct wb35_reg *reg = &pHwData->reg;
 	u32		tmp;
@@ -2417,7 +2416,7 @@
 }
 
 
-void Uxx_power_off_procedure(  phw_data_t pHwData )
+void Uxx_power_off_procedure(  struct hw_data * pHwData )
 {
 	// SW, PMU reset and turn off clock
 	Wb35Reg_WriteSync( pHwData, 0x03b0, 3 );
@@ -2425,7 +2424,7 @@
 }
 
 //Decide the TxVga of every channel
-void GetTxVgaFromEEPROM(  phw_data_t pHwData )
+void GetTxVgaFromEEPROM(  struct hw_data * pHwData )
 {
 	u32		i, j, ltmp;
 	u16		Value[MAX_TXVGA_EEPROM];
@@ -2479,7 +2478,7 @@
 // or RFSynthesizer_SetPowerIndex be called, new TxVga will take effect.
 // TxVgaSettingInEEPROM of sHwData is an u8 array point to EEPROM contain for IS89C35
 // This function will use default TxVgaSettingInEEPROM data to calculate new TxVga.
-void EEPROMTxVgaAdjust(  phw_data_t pHwData ) // 20060619.5 Add
+void EEPROMTxVgaAdjust(  struct hw_data * pHwData ) // 20060619.5 Add
 {
 	u8	*	pTxVga = pHwData->TxVgaSettingInEEPROM;
 	s16		i, stmp;
@@ -2612,14 +2611,14 @@
 	}
 
 	#ifdef _PE_STATE_DUMP_
-	WBDEBUG((" TxVgaFor24 : \n"));
+	printk(" TxVgaFor24 : \n");
 	DataDmp((u8 *)pHwData->TxVgaFor24, 14 ,0);
-	WBDEBUG((" TxVgaFor50 : \n"));
+	printk(" TxVgaFor50 : \n");
 	DataDmp((u8 *)pHwData->TxVgaFor50, 70 ,0);
 	#endif
 }
 
-void BBProcessor_RateChanging(  phw_data_t pHwData,  u8 rate ) // 20060613.1
+void BBProcessor_RateChanging(  struct hw_data * pHwData,  u8 rate ) // 20060613.1
 {
 	struct wb35_reg *reg = &pHwData->reg;
 	unsigned char		Is11bRate;
diff --git a/drivers/staging/winbond/sme_api.h b/drivers/staging/winbond/sme_api.h
index 188a253..5498783 100644
--- a/drivers/staging/winbond/sme_api.h
+++ b/drivers/staging/winbond/sme_api.h
@@ -17,9 +17,6 @@
 
 #include "localpara.h"
 
-/****************** INCLUDE FILES SECTION ***********************************/
-//#include "GL\gl_core.h"
-
 /****************** CONSTANT AND MACRO SECTION ******************************/
 #define _INLINE      __inline
 
diff --git a/drivers/staging/winbond/sme_s.h b/drivers/staging/winbond/sme_s.h
deleted file mode 100644
index 1bd118f..0000000
--- a/drivers/staging/winbond/sme_s.h
+++ /dev/null
@@ -1,236 +0,0 @@
-#ifndef __WINBOND_SME_S_H
-#define __WINBOND_SME_S_H
-
-#include <linux/types.h>
-
-#include "mac_structures.h"
-#include "localpara.h"
-
-//
-// SME_S.H -
-// SME task global CONSTANTS, STRUCTURES, variables
-//
-
-//////////////////////////////////////////////////////////////////////////
-//define the msg type of SME module
-// 0x00~0x1F : MSG from GUI dispatch
-// 0x20~0x3F : MSG from MLME
-// 0x40~0x5F : MSG from SCAN
-// 0x60~0x6F : MSG from TX/RX
-// 0x70~0x7F : MSG from ROAMING
-// 0x80~0x8F : MSG from ISR
-// 0x90		 : MSG TimeOut
-
-// from GUI
-#define SMEMSG_SCAN_REQ					0x01
-//#define SMEMSG_PASSIVE_SCAN_REQ			0x02
-#define SMEMSG_JOIN_REQ					0x03
-#define SMEMSG_START_IBSS				0x04
-#define SMEMSG_DISCONNECT_REQ			0x05
-#define SMEMSG_AUTHEN_REQ				0x06
-#define SMEMSG_DEAUTHEN_REQ				0x07
-#define SMEMSG_ASSOC_REQ				0x08
-#define SMEMSG_REASSOC_REQ				0x09
-#define SMEMSG_DISASSOC_REQ				0x0a
-#define SMEMSG_POWERSAVE_REQ			0x0b
-
-
-// from MLME
-#define SMEMSG_AUTHEN_CFM				0x21
-#define SMEMSG_AUTHEN_IND				0x22
-#define SMEMSG_ASSOC_CFM				0x23
-#define SMEMSG_DEAUTHEN_IND				0x24
-#define SMEMSG_DISASSOC_IND				0x25
-// from SCAN
-#define SMEMSG_SCAN_CFM					0x41
-#define SMEMSG_START_IBSS_CFM			0x42
-// from MTO, function call to set SME parameters
-
-// 0x60~0x6F : MSG from TX/RX
-//#define SMEMSG_IBSS_JOIN_UPDATE_BSSID	0x61
-#define SMEMSG_COUNTERMEASURE_MICFAIL_TIMEOUT		0x62
-#define SMEMSG_COUNTERMEASURE_BLOCK_TIMEOUT	0x63
-// from ROAMING
-#define SMEMSG_HANDOVER_JOIN_REQ		0x71
-#define SMEMSG_END_ROAMING				0x72
-#define SMEMSG_SCAN_JOIN_REQ			0x73
-// from ISR
-#define SMEMSG_TSF_SYNC_IND				0x81
-// from TimeOut
-#define SMEMSG_TIMEOUT					0x91
-
-
-
-#define MAX_PMKID_Accunt                16
-//@added by ws 04/22/05
-#define Cipher_Disabled                 0
-#define Cipher_Wep                      1
-#define Cipher_Tkip                     2
-#define Cipher_Ccmp                     4
-
-
-///////////////////////////////////////////////////////////////////////////
-//Constants
-
-///////////////////////////////////////////////////////////////////////////
-//Global data structures
-
-#define NUMOFWEPENTRIES     64
-
-typedef enum _WEPKeyMode
-{
-    WEPKEY_DISABLED = 0,
-    WEPKEY_64       = 1,
-    WEPKEY_128      = 2
-
-} WEPKEYMODE, *pWEPKEYMODE;
-
-#ifdef _WPA2_
-
-typedef struct _BSSInfo
-{
-  u8        PreAuthBssID[6];
-  PMKID        pmkid_value;
-}BSSID_Info;
-
-typedef struct _PMKID_Table //added by ws 05/05/04
-{
-   u32  Length;
-   u32  BSSIDInfoCount;
-   BSSID_Info BSSIDInfo[16];
-
-} PMKID_Table;
-
-#endif //end def _WPA2_
-
-#define MAX_BASIC_RATE_SET          15
-#define MAX_OPT_RATE_SET            MAX_BASIC_RATE_SET
-
-
-typedef struct _SME_PARAMETERS
-{
-    u16				wState;
-	u8				boDUTmode;
-	u8				bDesiredPowerSave;
-
-	// SME timer and timeout value
-	struct timer_list timer;
-
-	u8				boInTimerHandler;
-	u8 				boAuthRetryActive;
-	u8				reserved_0[2];
-
-	u32				AuthenRetryTimerVal;	// NOTE: Assoc don't fail timeout
-	u32				JoinFailTimerVal;		// 10*Beacon-Interval
-
-	//Rates
-	u8				BSSBasicRateSet[(MAX_BASIC_RATE_SET + 3) & ~0x03 ];    // BSS basic rate set
-	u8				OperationalRateSet[(MAX_OPT_RATE_SET + 3) & ~0x03 ]; // Operational rate set
-
-	u8				NumOfBSSBasicRate;
-	u8				NumOfOperationalRate;
-	u8				reserved_1[2];
-
-	u32				BasicRateBitmap;
-	u32				OpRateBitmap;
-
-	// System parameters Set by GUI
-	//-------------------- start IBSS parameter ---------------------------//
-	u32				boStartIBSS;			//Start IBSS toggle
-
-	u16				wBeaconPeriod;
-	u16				wATIM_Window;
-
-	ChanInfo			IbssChan; // 2B	//channel setting when start IBSS
-	u8				reserved_2[2];
-
-    // Join related
-	u16				wDesiredJoinBSS;		// BSS index which desire to join
-	u8				boJoinReq;				//Join request toggle
-	u8				bDesiredBSSType;		//for Join request
-
-    u16				wCapabilityInfo;        // Used when invoking the MLME_Associate_request().
-	u16				wNonERPcapabilityInfo;
-
-    struct SSID_Element sDesiredSSID; // 34 B
-	u8				reserved_3[2];
-
-	u8    			abDesiredBSSID[MAC_ADDR_LENGTH + 2];
-
-	u8				bJoinScanCount;			// the time of scan-join action need to do
-	u8				bDesiredAuthMode;       // AUTH_OPEN_SYSTEM or AUTH_SHARED_KEY
-	u8				reserved_4[2];
-
-    // Encryption parameters
-	u8     			_dot11PrivacyInvoked;
-    u8             	_dot11PrivacyOptionImplemented;
-	u8				reserved_5[2];
-
-    //@ ws added
-    u8				DesiredEncrypt;
-	u8				encrypt_status;	//ENCRYPT_DISABLE, ENCRYPT_WEP, ENCRYPT_WEP_NOKEY, ENCRYPT_TKIP, ...
-	u8				key_length;
-	u8				pairwise_key_ok;
-
-	u8				group_key_ok;
-    u8				wpa_ok;             // indicate the control port of 802.1x is open or close
-	u8				pairwise_key_type;
-	u8				group_key_type;
-
-    u32               _dot11WEPDefaultKeyID;
-
-	u8              	tx_mic_key[8];      // TODO: 0627 kevin-TKIP
-	u8              	rx_mic_key[8];      // TODO: 0627 kevin-TKIP
-	u8				group_tx_mic_key[8];
-	u8				group_rx_mic_key[8];
-
-//	#ifdef _WPA_
-	u8				AssocReqVarIE[200];
-	u8				AssocRespVarIE[200];
-
-	u16				AssocReqVarLen;
-	u16				AssocRespVarLen;
-	u8				boReassoc;				//use assoc. or reassoc.
-	u8				reserved_6[3];
-	u16				AssocRespCapability;
-	u16				AssocRespStatus;
-//	#endif
-
-	#ifdef _WPA2_
-    u8               PmkIdTable[256];
-    u32               PmkidTableIndex;
-	#endif //end def _WPA2_
-
-} SME_PARAMETERS, *PSME_PARAMETERS;
-
-#define psSME			(&(adapter->sSmePara))
-
-#define wSMEGetCurrentSTAState(adapter)		((u16)(adapter)->sSmePara.wState)
-
-
-
-//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-//	SmeModule.h
-//		Define the related definitions of SME module
-//	history -- 01/14/03' created
-//
-//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-//Define the state of SME module
-#define DISABLED						0
-#define INIT_SCAN						1
-#define SCAN_READY						2
-#define START_IBSS						3
-#define JOIN_PENDING					4
-#define JOIN_CFM						5
-#define AUTHENTICATE_PENDING			6
-#define AUTHENTICATED					7
-#define CONNECTED						8
-//#define EAP_STARTING					9
-//#define EAPOL_AUTHEN_PENDING			10
-//#define SECURE_CONNECTED				11
-
-
-// Static function
-
-#endif
diff --git a/drivers/staging/winbond/wb35_ver.h b/drivers/staging/winbond/wb35_ver.h
deleted file mode 100644
index 2433bc0..0000000
--- a/drivers/staging/winbond/wb35_ver.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-// Only define one of follow
-//
-
-#ifdef WB_WIN
-	#define VER_FILEVERSION             1,00,47,00
-	#define VER_FILEVERSION_STR         "1.00.47.00"
-	#define WB32_DRIVER_MAJOR_VERSION   0x0100
-	#define WB32_DRIVER_MINOR_VERSION   0x4700
-#endif
-
-#ifdef WB_CE
-	#define VER_FILEVERSION             2,00,47,00
-	#define VER_FILEVERSION_STR         "2.00.47.00"
-	#define WB32_DRIVER_MAJOR_VERSION   0x0200
-	#define WB32_DRIVER_MINOR_VERSION   0x4700
-#endif
-
-#ifdef WB_LINUX
-	#define VER_FILEVERSION             3,00,47,00
-	#define VER_FILEVERSION_STR         "3.00.47.00"
-	#define WB32_DRIVER_MAJOR_VERSION   0x0300
-	#define WB32_DRIVER_MINOR_VERSION   0x4700
-#endif
-
-
-
-
-
-
diff --git a/drivers/staging/winbond/wb35reg.c b/drivers/staging/winbond/wb35reg.c
index c74b3fd..f5608ad9 100644
--- a/drivers/staging/winbond/wb35reg.c
+++ b/drivers/staging/winbond/wb35reg.c
@@ -3,7 +3,7 @@
 
 #include <linux/usb.h>
 
-extern void phy_calibration_winbond(hw_data_t *phw_data, u32 frequency);
+extern void phy_calibration_winbond(struct hw_data *phw_data, u32 frequency);
 
 // true  : read command process successfully
 // false : register not support
@@ -13,7 +13,7 @@
 // Flag : AUTO_INCREMENT - RegisterNo will auto increment 4
 //		  NO_INCREMENT - Function will write data into the same register
 unsigned char
-Wb35Reg_BurstWrite(phw_data_t pHwData, u16 RegisterNo, u32 * pRegisterData, u8 NumberOfData, u8 Flag)
+Wb35Reg_BurstWrite(struct hw_data * pHwData, u16 RegisterNo, u32 * pRegisterData, u8 NumberOfData, u8 Flag)
 {
 	struct wb35_reg *reg = &pHwData->reg;
 	struct urb	*urb = NULL;
@@ -73,7 +73,7 @@
 }
 
 void
-Wb35Reg_Update(phw_data_t pHwData,  u16 RegisterNo,  u32 RegisterValue)
+Wb35Reg_Update(struct hw_data * pHwData,  u16 RegisterNo,  u32 RegisterValue)
 {
 	struct wb35_reg *reg = &pHwData->reg;
 	switch (RegisterNo) {
@@ -118,7 +118,7 @@
 // true  : read command process successfully
 // false : register not support
 unsigned char
-Wb35Reg_WriteSync(  phw_data_t pHwData,  u16 RegisterNo,  u32 RegisterValue )
+Wb35Reg_WriteSync(  struct hw_data * pHwData,  u16 RegisterNo,  u32 RegisterValue )
 {
 	struct wb35_reg *reg = &pHwData->reg;
 	int ret = -1;
@@ -149,7 +149,7 @@
 
 	if (ret < 0) {
 		#ifdef _PE_REG_DUMP_
-		WBDEBUG(("EP0 Write register usb message sending error\n"));
+		printk("EP0 Write register usb message sending error\n");
 		#endif
 
 		pHwData->SurpriseRemove = 1; // 20060704.2
@@ -162,7 +162,7 @@
 // true  : read command process successfully
 // false : register not support
 unsigned char
-Wb35Reg_Write(  phw_data_t pHwData,  u16 RegisterNo,  u32 RegisterValue )
+Wb35Reg_Write(  struct hw_data * pHwData,  u16 RegisterNo,  u32 RegisterValue )
 {
 	struct wb35_reg *reg = &pHwData->reg;
 	struct usb_ctrlrequest *dr;
@@ -222,7 +222,7 @@
 // true  : read command process successfully
 // false : register not support
 unsigned char
-Wb35Reg_WriteWithCallbackValue( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue,
+Wb35Reg_WriteWithCallbackValue( struct hw_data * pHwData, u16 RegisterNo, u32 RegisterValue,
 				s8 *pValue, s8 Len)
 {
 	struct wb35_reg *reg = &pHwData->reg;
@@ -281,7 +281,7 @@
 // false : register not support
 // pRegisterValue : It must be a resident buffer due to asynchronous read register.
 unsigned char
-Wb35Reg_ReadSync(  phw_data_t pHwData,  u16 RegisterNo,   u32 * pRegisterValue )
+Wb35Reg_ReadSync(  struct hw_data * pHwData,  u16 RegisterNo,   u32 * pRegisterValue )
 {
 	struct wb35_reg *reg = &pHwData->reg;
 	u32 *	pltmp = pRegisterValue;
@@ -316,7 +316,7 @@
 
 	if (ret < 0) {
 		#ifdef _PE_REG_DUMP_
-		WBDEBUG(("EP0 Read register usb message sending error\n"));
+		printk("EP0 Read register usb message sending error\n");
 		#endif
 
 		pHwData->SurpriseRemove = 1; // 20060704.2
@@ -330,7 +330,7 @@
 // false : register not support
 // pRegisterValue : It must be a resident buffer due to asynchronous read register.
 unsigned char
-Wb35Reg_Read(phw_data_t pHwData, u16 RegisterNo,  u32 * pRegisterValue )
+Wb35Reg_Read(struct hw_data * pHwData, u16 RegisterNo,  u32 * pRegisterValue )
 {
 	struct wb35_reg *reg = &pHwData->reg;
 	struct usb_ctrlrequest * dr;
@@ -385,7 +385,7 @@
 
 
 void
-Wb35Reg_EP0VM_start(  phw_data_t pHwData )
+Wb35Reg_EP0VM_start(  struct hw_data * pHwData )
 {
 	struct wb35_reg *reg = &pHwData->reg;
 
@@ -397,7 +397,7 @@
 }
 
 void
-Wb35Reg_EP0VM(phw_data_t pHwData )
+Wb35Reg_EP0VM(struct hw_data * pHwData )
 {
 	struct wb35_reg *reg = &pHwData->reg;
 	struct urb	*urb;
@@ -441,7 +441,7 @@
 
 	if (ret < 0) {
 #ifdef _PE_REG_DUMP_
-		WBDEBUG(("EP0 Irp sending error\n"));
+		printk("EP0 Irp sending error\n");
 #endif
 		goto cleanup;
 	}
@@ -457,7 +457,7 @@
 void
 Wb35Reg_EP0VM_complete(struct urb *urb)
 {
-	phw_data_t  pHwData = (phw_data_t)urb->context;
+	struct hw_data *  pHwData = (struct hw_data *)urb->context;
 	struct wb35_reg *reg = &pHwData->reg;
 	struct wb35_reg_queue *reg_queue;
 
@@ -480,8 +480,7 @@
 
 		if (reg->EP0VM_status) {
 #ifdef _PE_REG_DUMP_
-			WBDEBUG(("EP0 IoCompleteRoutine return error\n"));
-			DebugUsbdStatusInformation( reg->EP0VM_status );
+			printk("EP0 IoCompleteRoutine return error\n");
 #endif
 			reg->EP0vm_state = VM_STOP;
 			pHwData->SurpriseRemove = 1;
@@ -500,7 +499,7 @@
 
 
 void
-Wb35Reg_destroy(phw_data_t pHwData)
+Wb35Reg_destroy(struct hw_data * pHwData)
 {
 	struct wb35_reg *reg = &pHwData->reg;
 	struct urb	*urb;
@@ -530,7 +529,7 @@
 			kfree(reg_queue);
 		} else {
 			#ifdef _PE_REG_DUMP_
-			WBDEBUG(("EP0 queue release error\n"));
+			printk("EP0 queue release error\n");
 			#endif
 		}
 		spin_lock_irq( &reg->EP0VM_spin_lock );
@@ -543,7 +542,7 @@
 //====================================================================================
 // The function can be run in passive-level only.
 //====================================================================================
-unsigned char Wb35Reg_initial(phw_data_t pHwData)
+unsigned char Wb35Reg_initial(struct hw_data * pHwData)
 {
 	struct wb35_reg *reg=&pHwData->reg;
 	u32 ltmp;
@@ -599,7 +598,7 @@
 	Wb35Reg_ReadSync( pHwData, 0x03b4, &Region_ScanInterval );
 
 	// Update Ethernet address
-	memcpy( pHwData->CurrentMacAddress, pHwData->PermanentMacAddress, ETH_LENGTH_OF_ADDRESS );
+	memcpy( pHwData->CurrentMacAddress, pHwData->PermanentMacAddress, ETH_ALEN );
 
 	// Update software variable
 	pHwData->SoftwareSet = (u16)(SoftwareSet & 0xffff);
@@ -723,7 +722,7 @@
 	return dwData;
 }
 
-void Wb35Reg_phy_calibration(  phw_data_t pHwData )
+void Wb35Reg_phy_calibration(  struct hw_data * pHwData )
 {
 	u32 BB3c, BB54;
 
diff --git a/drivers/staging/winbond/wb35reg_f.h b/drivers/staging/winbond/wb35reg_f.h
index d97215a..30f5b5a 100644
--- a/drivers/staging/winbond/wb35reg_f.h
+++ b/drivers/staging/winbond/wb35reg_f.h
@@ -6,47 +6,47 @@
 //====================================
 // Interface function declare
 //====================================
-unsigned char Wb35Reg_initial(  phw_data_t pHwData );
-void Uxx_power_on_procedure(  phw_data_t pHwData );
-void Uxx_power_off_procedure(  phw_data_t pHwData );
-void Uxx_ReadEthernetAddress(  phw_data_t pHwData );
-void Dxx_initial(  phw_data_t pHwData );
-void Mxx_initial(  phw_data_t pHwData );
-void RFSynthesizer_initial(  phw_data_t pHwData );
-//void RFSynthesizer_SwitchingChannel(  phw_data_t pHwData,  s8 Channel );
-void RFSynthesizer_SwitchingChannel(  phw_data_t pHwData,  ChanInfo Channel );
-void BBProcessor_initial(  phw_data_t pHwData );
-void BBProcessor_RateChanging(  phw_data_t pHwData,  u8 rate ); // 20060613.1
-//void RF_RateChanging(  phw_data_t pHwData,  u8 rate ); // 20060626.5.c Add
-u8 RFSynthesizer_SetPowerIndex(  phw_data_t pHwData,  u8 PowerIndex );
-u8 RFSynthesizer_SetMaxim2828_24Power(  phw_data_t,  u8 index );
-u8 RFSynthesizer_SetMaxim2828_50Power(  phw_data_t,  u8 index );
-u8 RFSynthesizer_SetMaxim2827_24Power(  phw_data_t,  u8 index );
-u8 RFSynthesizer_SetMaxim2827_50Power(  phw_data_t,  u8 index );
-u8 RFSynthesizer_SetMaxim2825Power(  phw_data_t,  u8 index );
-u8 RFSynthesizer_SetAiroha2230Power(  phw_data_t,  u8 index );
-u8 RFSynthesizer_SetAiroha7230Power(  phw_data_t,  u8 index );
-u8 RFSynthesizer_SetWinbond242Power(  phw_data_t,  u8 index );
-void GetTxVgaFromEEPROM(  phw_data_t pHwData );
-void EEPROMTxVgaAdjust(  phw_data_t pHwData ); // 20060619.5 Add
+unsigned char Wb35Reg_initial(  struct hw_data * pHwData );
+void Uxx_power_on_procedure(  struct hw_data * pHwData );
+void Uxx_power_off_procedure(  struct hw_data * pHwData );
+void Uxx_ReadEthernetAddress(  struct hw_data * pHwData );
+void Dxx_initial(  struct hw_data * pHwData );
+void Mxx_initial(  struct hw_data * pHwData );
+void RFSynthesizer_initial(  struct hw_data * pHwData );
+//void RFSynthesizer_SwitchingChannel(  struct hw_data * pHwData,  s8 Channel );
+void RFSynthesizer_SwitchingChannel(  struct hw_data * pHwData,  ChanInfo Channel );
+void BBProcessor_initial(  struct hw_data * pHwData );
+void BBProcessor_RateChanging(  struct hw_data * pHwData,  u8 rate ); // 20060613.1
+//void RF_RateChanging(  struct hw_data * pHwData,  u8 rate ); // 20060626.5.c Add
+u8 RFSynthesizer_SetPowerIndex(  struct hw_data * pHwData,  u8 PowerIndex );
+u8 RFSynthesizer_SetMaxim2828_24Power(  struct hw_data *,  u8 index );
+u8 RFSynthesizer_SetMaxim2828_50Power(  struct hw_data *,  u8 index );
+u8 RFSynthesizer_SetMaxim2827_24Power(  struct hw_data *,  u8 index );
+u8 RFSynthesizer_SetMaxim2827_50Power(  struct hw_data *,  u8 index );
+u8 RFSynthesizer_SetMaxim2825Power(  struct hw_data *,  u8 index );
+u8 RFSynthesizer_SetAiroha2230Power(  struct hw_data *,  u8 index );
+u8 RFSynthesizer_SetAiroha7230Power(  struct hw_data *,  u8 index );
+u8 RFSynthesizer_SetWinbond242Power(  struct hw_data *,  u8 index );
+void GetTxVgaFromEEPROM(  struct hw_data * pHwData );
+void EEPROMTxVgaAdjust(  struct hw_data * pHwData ); // 20060619.5 Add
 
 #define RFWriteControlData( _A, _V ) Wb35Reg_Write( _A, 0x0864, _V )
 
-void Wb35Reg_destroy(  phw_data_t pHwData );
+void Wb35Reg_destroy(  struct hw_data * pHwData );
 
-unsigned char Wb35Reg_Read(  phw_data_t pHwData,  u16 RegisterNo,   u32 * pRegisterValue );
-unsigned char Wb35Reg_ReadSync(  phw_data_t pHwData,  u16 RegisterNo,   u32 * pRegisterValue );
-unsigned char Wb35Reg_Write(  phw_data_t pHwData,  u16 RegisterNo,  u32 RegisterValue );
-unsigned char Wb35Reg_WriteSync(  phw_data_t pHwData,  u16 RegisterNo,  u32 RegisterValue );
-unsigned char Wb35Reg_WriteWithCallbackValue(  phw_data_t pHwData,
+unsigned char Wb35Reg_Read(  struct hw_data * pHwData,  u16 RegisterNo,   u32 * pRegisterValue );
+unsigned char Wb35Reg_ReadSync(  struct hw_data * pHwData,  u16 RegisterNo,   u32 * pRegisterValue );
+unsigned char Wb35Reg_Write(  struct hw_data * pHwData,  u16 RegisterNo,  u32 RegisterValue );
+unsigned char Wb35Reg_WriteSync(  struct hw_data * pHwData,  u16 RegisterNo,  u32 RegisterValue );
+unsigned char Wb35Reg_WriteWithCallbackValue(  struct hw_data * pHwData,
 								 u16 RegisterNo,
 								 u32 RegisterValue,
 								 s8 *pValue,
 								 s8 Len);
-unsigned char Wb35Reg_BurstWrite(  phw_data_t pHwData,  u16 RegisterNo,  u32 * pRegisterData,  u8 NumberOfData,  u8 Flag );
+unsigned char Wb35Reg_BurstWrite(  struct hw_data * pHwData,  u16 RegisterNo,  u32 * pRegisterData,  u8 NumberOfData,  u8 Flag );
 
-void Wb35Reg_EP0VM(  phw_data_t pHwData );
-void Wb35Reg_EP0VM_start(  phw_data_t pHwData );
+void Wb35Reg_EP0VM(  struct hw_data * pHwData );
+void Wb35Reg_EP0VM_start(  struct hw_data * pHwData );
 void Wb35Reg_EP0VM_complete(struct urb *urb);
 
 u32 BitReverse( u32 dwData, u32 DataLength);
@@ -54,8 +54,8 @@
 void CardGetMulticastBit(   u8 Address[MAC_ADDR_LENGTH],  u8 *Byte,  u8 *Value );
 u32 CardComputeCrc(  u8 * Buffer,  u32 Length );
 
-void Wb35Reg_phy_calibration(  phw_data_t pHwData );
-void Wb35Reg_Update(  phw_data_t pHwData,  u16 RegisterNo,  u32 RegisterValue );
-unsigned char adjust_TXVGA_for_iq_mag(  phw_data_t pHwData );
+void Wb35Reg_phy_calibration(  struct hw_data * pHwData );
+void Wb35Reg_Update(  struct hw_data * pHwData,  u16 RegisterNo,  u32 RegisterValue );
+unsigned char adjust_TXVGA_for_iq_mag(  struct hw_data * pHwData );
 
 #endif
diff --git a/drivers/staging/winbond/wb35rx.c b/drivers/staging/winbond/wb35rx.c
index 7f8b6d7..3e8cf08 100644
--- a/drivers/staging/winbond/wb35rx.c
+++ b/drivers/staging/winbond/wb35rx.c
@@ -82,9 +82,9 @@
 static u16 Wb35Rx_indicate(struct ieee80211_hw *hw)
 {
 	struct wbsoft_priv *priv = hw->priv;
-	phw_data_t pHwData = &priv->sHwData;
+	struct hw_data * pHwData = &priv->sHwData;
 	DESCRIPTOR	RxDes;
-	PWB35RX	pWb35Rx = &pHwData->Wb35Rx;
+	struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
 	u8 *		pRxBufferAddress;
 	u16		PacketSize;
 	u16		stmp, BufferSize, stmp2 = 0;
@@ -118,7 +118,7 @@
 			// Basic check for Rx length. Is length valid?
 			if (PacketSize > MAX_PACKET_SIZE) {
 				#ifdef _PE_RX_DUMP_
-				WBDEBUG(("Serious ERROR : Rx data size too long, size =%d\n", PacketSize));
+				printk("Serious ERROR : Rx data size too long, size =%d\n", PacketSize);
 				#endif
 
 				pWb35Rx->EP3vm_state = VM_STOP;
@@ -161,8 +161,8 @@
 {
 	struct ieee80211_hw *hw = urb->context;
 	struct wbsoft_priv *priv = hw->priv;
-	phw_data_t pHwData = &priv->sHwData;
-	PWB35RX		pWb35Rx = &pHwData->Wb35Rx;
+	struct hw_data * pHwData = &priv->sHwData;
+	struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
 	u8 *		pRxBufferAddress;
 	u32		SizeCheck;
 	u16		BulkLength;
@@ -194,8 +194,7 @@
 	// The URB is completed, check the result
 	if (pWb35Rx->EP3VM_status != 0) {
 		#ifdef _PE_USB_STATE_DUMP_
-		WBDEBUG(("EP3 IoCompleteRoutine return error\n"));
-		DebugUsbdStatusInformation( pWb35Rx->EP3VM_status );
+		printk("EP3 IoCompleteRoutine return error\n");
 		#endif
 		pWb35Rx->EP3vm_state = VM_STOP;
 		goto error;
@@ -239,8 +238,8 @@
 static void Wb35Rx(struct ieee80211_hw *hw)
 {
 	struct wbsoft_priv *priv = hw->priv;
-	phw_data_t pHwData = &priv->sHwData;
-	PWB35RX	pWb35Rx = &pHwData->Wb35Rx;
+	struct hw_data * pHwData = &priv->sHwData;
+	struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
 	u8 *	pRxBufferAddress;
 	struct urb *urb = pWb35Rx->RxUrb;
 	int	retv;
@@ -260,7 +259,7 @@
 	if (!pWb35Rx->RxOwner[RxBufferId]) {
 		// It's impossible to run here.
 		#ifdef _PE_RX_DUMP_
-		WBDEBUG(("Rx driver fifo unavailable\n"));
+		printk("Rx driver fifo unavailable\n");
 		#endif
 		goto error;
 	}
@@ -302,8 +301,8 @@
 void Wb35Rx_start(struct ieee80211_hw *hw)
 {
 	struct wbsoft_priv *priv = hw->priv;
-	phw_data_t pHwData = &priv->sHwData;
-	PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+	struct hw_data * pHwData = &priv->sHwData;
+	struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
 
 	// Allow only one thread to run into the Wb35Rx() function
 	if (atomic_inc_return(&pWb35Rx->RxFireCounter) == 1) {
@@ -314,9 +313,9 @@
 }
 
 //=====================================================================================
-static void Wb35Rx_reset_descriptor(  phw_data_t pHwData )
+static void Wb35Rx_reset_descriptor(  struct hw_data * pHwData )
 {
-	PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+	struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
 	u32	i;
 
 	pWb35Rx->ByteReceived = 0;
@@ -330,9 +329,9 @@
 		pWb35Rx->RxOwner[i] = 1;
 }
 
-unsigned char Wb35Rx_initial(phw_data_t pHwData)
+unsigned char Wb35Rx_initial(struct hw_data * pHwData)
 {
-	PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+	struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
 
 	// Initial the Buffer Queue
 	Wb35Rx_reset_descriptor( pHwData );
@@ -341,23 +340,23 @@
 	return (!!pWb35Rx->RxUrb);
 }
 
-void Wb35Rx_stop(phw_data_t pHwData)
+void Wb35Rx_stop(struct hw_data * pHwData)
 {
-	PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+	struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
 
 	// Canceling the Irp if already sends it out.
 	if (pWb35Rx->EP3vm_state == VM_RUNNING) {
 		usb_unlink_urb( pWb35Rx->RxUrb ); // Only use unlink, let Wb35Rx_destroy to free them
 		#ifdef _PE_RX_DUMP_
-		WBDEBUG(("EP3 Rx stop\n"));
+		printk("EP3 Rx stop\n");
 		#endif
 	}
 }
 
 // Needs process context
-void Wb35Rx_destroy(phw_data_t pHwData)
+void Wb35Rx_destroy(struct hw_data * pHwData)
 {
-	PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+	struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
 
 	do {
 		msleep(10); // Delay for waiting function enter 940623.1.a
@@ -367,7 +366,7 @@
 	if (pWb35Rx->RxUrb)
 		usb_free_urb( pWb35Rx->RxUrb );
 	#ifdef _PE_RX_DUMP_
-	WBDEBUG(("Wb35Rx_destroy OK\n"));
+	printk("Wb35Rx_destroy OK\n");
 	#endif
 }
 
diff --git a/drivers/staging/winbond/wb35rx_f.h b/drivers/staging/winbond/wb35rx_f.h
index d993041..98acce5 100644
--- a/drivers/staging/winbond/wb35rx_f.h
+++ b/drivers/staging/winbond/wb35rx_f.h
@@ -7,9 +7,9 @@
 //====================================
 // Interface function declare
 //====================================
-unsigned char		Wb35Rx_initial(  phw_data_t pHwData );
-void		Wb35Rx_destroy(  phw_data_t pHwData );
-void		Wb35Rx_stop(  phw_data_t pHwData );
+unsigned char		Wb35Rx_initial(  struct hw_data * pHwData );
+void		Wb35Rx_destroy(  struct hw_data * pHwData );
+void		Wb35Rx_stop(  struct hw_data * pHwData );
 void		Wb35Rx_start(struct ieee80211_hw *hw);
 
 #endif
diff --git a/drivers/staging/winbond/wb35rx_s.h b/drivers/staging/winbond/wb35rx_s.h
index f18350b..4b03274 100644
--- a/drivers/staging/winbond/wb35rx_s.h
+++ b/drivers/staging/winbond/wb35rx_s.h
@@ -15,8 +15,7 @@
 //====================================
 // Internal variable for module
 //====================================
-typedef struct _WB35RX
-{
+struct wb35_rx {
 	u32			ByteReceived;// For calculating throughput of BulkIn
 	atomic_t		RxFireCounter;// Does Wb35Rx module fire?
 
@@ -42,7 +41,4 @@
 
 	int		EP3VM_status;
 	u8 *	pDRx;
-
-} WB35RX, *PWB35RX;
-
-
+};
diff --git a/drivers/staging/winbond/wb35tx.c b/drivers/staging/winbond/wb35tx.c
index b9b4456..1e4169d 100644
--- a/drivers/staging/winbond/wb35tx.c
+++ b/drivers/staging/winbond/wb35tx.c
@@ -15,9 +15,9 @@
 #include "sysdef.h"
 
 unsigned char
-Wb35Tx_get_tx_buffer(phw_data_t pHwData, u8 **pBuffer)
+Wb35Tx_get_tx_buffer(struct hw_data * pHwData, u8 **pBuffer)
 {
-	PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+	struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
 
 	*pBuffer = pWb35Tx->TxBuffer[0];
 	return true;
@@ -28,8 +28,8 @@
 static void Wb35Tx_complete(struct urb * pUrb)
 {
 	struct wbsoft_priv *adapter = pUrb->context;
-	phw_data_t	pHwData = &adapter->sHwData;
-	PWB35TX		pWb35Tx = &pHwData->Wb35Tx;
+	struct hw_data *	pHwData = &adapter->sHwData;
+	struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
 	PMDS		pMds = &adapter->Mds;
 
 	printk("wb35: tx complete\n");
@@ -64,8 +64,8 @@
 
 static void Wb35Tx(struct wbsoft_priv *adapter)
 {
-	phw_data_t	pHwData = &adapter->sHwData;
-	PWB35TX		pWb35Tx = &pHwData->Wb35Tx;
+	struct hw_data *	pHwData = &adapter->sHwData;
+	struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
 	u8		*pTxBufferAddress;
 	PMDS		pMds = &adapter->Mds;
 	struct urb *	pUrb = (struct urb *)pWb35Tx->Tx4Urb;
@@ -115,8 +115,8 @@
 
 void Wb35Tx_start(struct wbsoft_priv *adapter)
 {
-	phw_data_t pHwData = &adapter->sHwData;
-	PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+	struct hw_data * pHwData = &adapter->sHwData;
+	struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
 
 	// Allow only one thread to run into function
 	if (atomic_inc_return(&pWb35Tx->TxFireCounter) == 1) {
@@ -126,9 +126,9 @@
 		atomic_dec(&pWb35Tx->TxFireCounter);
 }
 
-unsigned char Wb35Tx_initial(phw_data_t pHwData)
+unsigned char Wb35Tx_initial(struct hw_data * pHwData)
 {
-	PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+	struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
 
 	pWb35Tx->Tx4Urb = usb_alloc_urb(0, GFP_ATOMIC);
 	if (!pWb35Tx->Tx4Urb)
@@ -145,29 +145,29 @@
 }
 
 //======================================================
-void Wb35Tx_stop(phw_data_t pHwData)
+void Wb35Tx_stop(struct hw_data * pHwData)
 {
-	PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+	struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
 
 	// Trying to canceling the Trp of EP2
 	if (pWb35Tx->EP2vm_state == VM_RUNNING)
 		usb_unlink_urb( pWb35Tx->Tx2Urb ); // Only use unlink, let Wb35Tx_destrot to free them
 	#ifdef _PE_TX_DUMP_
-	WBDEBUG(("EP2 Tx stop\n"));
+	printk("EP2 Tx stop\n");
 	#endif
 
 	// Trying to canceling the Irp of EP4
 	if (pWb35Tx->EP4vm_state == VM_RUNNING)
 		usb_unlink_urb( pWb35Tx->Tx4Urb ); // Only use unlink, let Wb35Tx_destrot to free them
 	#ifdef _PE_TX_DUMP_
-	WBDEBUG(("EP4 Tx stop\n"));
+	printk("EP4 Tx stop\n");
 	#endif
 }
 
 //======================================================
-void Wb35Tx_destroy(phw_data_t pHwData)
+void Wb35Tx_destroy(struct hw_data * pHwData)
 {
-	PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+	struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
 
 	// Wait for VM stop
 	do {
@@ -182,14 +182,14 @@
 		usb_free_urb( pWb35Tx->Tx2Urb );
 
 	#ifdef _PE_TX_DUMP_
-	WBDEBUG(("Wb35Tx_destroy OK\n"));
+	printk("Wb35Tx_destroy OK\n");
 	#endif
 }
 
 void Wb35Tx_CurrentTime(struct wbsoft_priv *adapter, u32 TimeCount)
 {
-	phw_data_t pHwData = &adapter->sHwData;
-	PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+	struct hw_data * pHwData = &adapter->sHwData;
+	struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
 	unsigned char Trigger = false;
 
 	if (pWb35Tx->TxTimer > TimeCount)
@@ -208,9 +208,9 @@
 static void Wb35Tx_EP2VM_complete(struct urb * pUrb)
 {
 	struct wbsoft_priv *adapter = pUrb->context;
-	phw_data_t	pHwData = &adapter->sHwData;
+	struct hw_data *	pHwData = &adapter->sHwData;
 	T02_DESCRIPTOR	T02, TSTATUS;
-	PWB35TX		pWb35Tx = &pHwData->Wb35Tx;
+	struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
 	u32 *		pltmp = (u32 *)pWb35Tx->EP2_buf;
 	u32		i;
 	u16		InterruptInLength;
@@ -229,7 +229,7 @@
 
 	//The Urb is completed, check the result
 	if (pWb35Tx->EP2VM_status != 0) {
-		WBDEBUG(("EP2 IoCompleteRoutine return error\n"));
+		printk("EP2 IoCompleteRoutine return error\n");
 		pWb35Tx->EP2vm_state= VM_STOP;
 		goto error;
 	}
@@ -256,8 +256,8 @@
 
 static void Wb35Tx_EP2VM(struct wbsoft_priv *adapter)
 {
-	phw_data_t	pHwData = &adapter->sHwData;
-	PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+	struct hw_data *	pHwData = &adapter->sHwData;
+	struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
 	struct urb *	pUrb = (struct urb *)pWb35Tx->Tx2Urb;
 	u32 *	pltmp = (u32 *)pWb35Tx->EP2_buf;
 	int		retv;
@@ -279,7 +279,7 @@
 
 	if (retv < 0) {
 		#ifdef _PE_TX_DUMP_
-		WBDEBUG(("EP2 Tx Irp sending error\n"));
+		printk("EP2 Tx Irp sending error\n");
 		#endif
 		goto error;
 	}
@@ -292,8 +292,8 @@
 
 void Wb35Tx_EP2VM_start(struct wbsoft_priv *adapter)
 {
-	phw_data_t pHwData = &adapter->sHwData;
-	PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+	struct hw_data * pHwData = &adapter->sHwData;
+	struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
 
 	// Allow only one thread to run into function
 	if (atomic_inc_return(&pWb35Tx->TxResultCount) == 1) {
diff --git a/drivers/staging/winbond/wb35tx_f.h b/drivers/staging/winbond/wb35tx_f.h
index 4222fa8..a7af9cb 100644
--- a/drivers/staging/winbond/wb35tx_f.h
+++ b/drivers/staging/winbond/wb35tx_f.h
@@ -7,14 +7,14 @@
 //====================================
 // Interface function declare
 //====================================
-unsigned char Wb35Tx_initial(	 phw_data_t pHwData );
-void Wb35Tx_destroy(  phw_data_t pHwData );
-unsigned char Wb35Tx_get_tx_buffer(  phw_data_t pHwData,  u8 **pBuffer );
+unsigned char Wb35Tx_initial(	 struct hw_data * pHwData );
+void Wb35Tx_destroy(  struct hw_data * pHwData );
+unsigned char Wb35Tx_get_tx_buffer(  struct hw_data * pHwData,  u8 **pBuffer );
 
 void Wb35Tx_EP2VM_start(struct wbsoft_priv *adapter);
 
 void Wb35Tx_start(struct wbsoft_priv *adapter);
-void Wb35Tx_stop(  phw_data_t pHwData );
+void Wb35Tx_stop(  struct hw_data * pHwData );
 
 void Wb35Tx_CurrentTime(struct wbsoft_priv *adapter,  u32 TimeCount);
 
diff --git a/drivers/staging/winbond/wb35tx_s.h b/drivers/staging/winbond/wb35tx_s.h
index 3960276..f70f433 100644
--- a/drivers/staging/winbond/wb35tx_s.h
+++ b/drivers/staging/winbond/wb35tx_s.h
@@ -18,8 +18,7 @@
 //====================================
 
 
-typedef struct _WB35TX
-{
+struct wb35_tx {
 	// For Tx buffer
 	u8	TxBuffer[ MAX_USB_TX_BUFFER_NUMBER ][ MAX_USB_TX_BUFFER ];
 
@@ -43,7 +42,6 @@
 
 	u32	TxFillCount; // 20060928
 	u32	TxTimer; // 20060928 Add if sending packet not great than 13
-
-} WB35TX, *PWB35TX;
+};
 
 #endif
diff --git a/drivers/staging/winbond/wbhal.c b/drivers/staging/winbond/wbhal.c
index 8a9d21c..c985ad0 100644
--- a/drivers/staging/winbond/wbhal.c
+++ b/drivers/staging/winbond/wbhal.c
@@ -1,14 +1,14 @@
-#include "os_common.h"
+#include "sysdef.h"
 #include "wbhal_f.h"
 #include "wblinux_f.h"
 
-void hal_set_ethernet_address( phw_data_t pHwData, u8 *current_address )
+void hal_set_ethernet_address( struct hw_data * pHwData, u8 *current_address )
 {
 	u32 ltmp[2];
 
 	if( pHwData->SurpriseRemove ) return;
 
-	memcpy( pHwData->CurrentMacAddress, current_address, ETH_LENGTH_OF_ADDRESS );
+	memcpy( pHwData->CurrentMacAddress, current_address, ETH_ALEN );
 
 	ltmp[0]= cpu_to_le32( *(u32 *)pHwData->CurrentMacAddress );
 	ltmp[1]= cpu_to_le32( *(u32 *)(pHwData->CurrentMacAddress + 4) ) & 0xffff;
@@ -16,7 +16,7 @@
 	Wb35Reg_BurstWrite( pHwData, 0x03e8, ltmp, 2, AUTO_INCREMENT );
 }
 
-void hal_get_permanent_address( phw_data_t pHwData, u8 *pethernet_address )
+void hal_get_permanent_address( struct hw_data * pHwData, u8 *pethernet_address )
 {
 	if( pHwData->SurpriseRemove ) return;
 
@@ -26,7 +26,7 @@
 static void hal_led_control(unsigned long data)
 {
 	struct wbsoft_priv *adapter = (struct wbsoft_priv *) data;
-	phw_data_t pHwData = &adapter->sHwData;
+	struct hw_data * pHwData = &adapter->sHwData;
 	struct wb35_reg *reg = &pHwData->reg;
 	u32	LEDSet = (pHwData->SoftwareSet & HAL_LED_SET_MASK) >> HAL_LED_SET_SHIFT;
 	u8	LEDgray[20] = { 0,3,4,6,8,10,11,12,13,14,15,14,13,12,11,10,8,6,4,2 };
@@ -311,7 +311,7 @@
 u8 hal_init_hardware(struct ieee80211_hw *hw)
 {
 	struct wbsoft_priv *priv = hw->priv;
-	phw_data_t pHwData = &priv->sHwData;
+	struct hw_data * pHwData = &priv->sHwData;
 	u16 SoftwareSet;
 
 	// Initial the variable
@@ -356,7 +356,7 @@
 }
 
 
-void hal_halt(phw_data_t pHwData, void *ppa_data)
+void hal_halt(struct hw_data * pHwData, void *ppa_data)
 {
 	switch( pHwData->InitialResource )
 	{
@@ -370,7 +370,7 @@
 }
 
 //---------------------------------------------------------------------------------------------------
-void hal_set_beacon_period(  phw_data_t pHwData,  u16 beacon_period )
+void hal_set_beacon_period(  struct hw_data * pHwData,  u16 beacon_period )
 {
 	u32	tmp;
 
@@ -383,7 +383,7 @@
 }
 
 
-static void hal_set_current_channel_ex(  phw_data_t pHwData,  ChanInfo channel )
+static void hal_set_current_channel_ex(  struct hw_data * pHwData,  ChanInfo channel )
 {
 	struct wb35_reg *reg = &pHwData->reg;
 
@@ -396,7 +396,7 @@
 	pHwData->Channel = channel.ChanNo;
 	pHwData->band = channel.band;
 	#ifdef _PE_STATE_DUMP_
-	WBDEBUG(("Set channel is %d, band =%d\n", pHwData->Channel, pHwData->band));
+	printk("Set channel is %d, band =%d\n", pHwData->Channel, pHwData->band);
 	#endif
 	reg->M28_MacControl &= ~0xff; // Clean channel information field
 	reg->M28_MacControl |= channel.ChanNo;
@@ -404,12 +404,12 @@
 					(s8 *)&channel, sizeof(ChanInfo));
 }
 //---------------------------------------------------------------------------------------------------
-void hal_set_current_channel(  phw_data_t pHwData,  ChanInfo channel )
+void hal_set_current_channel(  struct hw_data * pHwData,  ChanInfo channel )
 {
 	hal_set_current_channel_ex( pHwData, channel );
 }
 //---------------------------------------------------------------------------------------------------
-void hal_set_accept_broadcast(  phw_data_t pHwData,  u8 enable )
+void hal_set_accept_broadcast(  struct hw_data * pHwData,  u8 enable )
 {
 	struct wb35_reg *reg = &pHwData->reg;
 
@@ -424,7 +424,7 @@
 }
 
 //for wep key error detection, we need to accept broadcast packets to be received temporary.
-void hal_set_accept_promiscuous( phw_data_t pHwData,  u8 enable)
+void hal_set_accept_promiscuous( struct hw_data * pHwData,  u8 enable)
 {
 	struct wb35_reg *reg = &pHwData->reg;
 
@@ -438,7 +438,7 @@
 	}
 }
 
-void hal_set_accept_multicast(  phw_data_t pHwData,  u8 enable )
+void hal_set_accept_multicast(  struct hw_data * pHwData,  u8 enable )
 {
 	struct wb35_reg *reg = &pHwData->reg;
 
@@ -449,7 +449,7 @@
 	Wb35Reg_Write( pHwData, 0x0800, reg->M00_MacControl );
 }
 
-void hal_set_accept_beacon(  phw_data_t pHwData,  u8 enable )
+void hal_set_accept_beacon(  struct hw_data * pHwData,  u8 enable )
 {
 	struct wb35_reg *reg = &pHwData->reg;
 
@@ -467,7 +467,7 @@
 }
 //---------------------------------------------------------------------------------------------------
 
-void hal_stop(  phw_data_t pHwData )
+void hal_stop(  struct hw_data * pHwData )
 {
 	struct wb35_reg *reg = &pHwData->reg;
 
@@ -481,10 +481,10 @@
 	Wb35Reg_Write( pHwData, 0x0400, reg->D00_DmaControl );
 }
 
-unsigned char hal_idle(phw_data_t pHwData)
+unsigned char hal_idle(struct hw_data * pHwData)
 {
 	struct wb35_reg *reg = &pHwData->reg;
-	PWBUSB	pWbUsb = &pHwData->WbUsb;
+	struct wb_usb *pWbUsb = &pHwData->WbUsb;
 
 	if( !pHwData->SurpriseRemove && ( pWbUsb->DetectCount || reg->EP0vm_state!=VM_STOP ) )
 		return false;
@@ -492,12 +492,12 @@
 	return true;
 }
 //---------------------------------------------------------------------------------------------------
-void hal_set_phy_type(  phw_data_t pHwData,  u8 PhyType )
+void hal_set_phy_type(  struct hw_data * pHwData,  u8 PhyType )
 {
 	pHwData->phy_type = PhyType;
 }
 
-void hal_set_radio_mode( phw_data_t pHwData,  unsigned char radio_off)
+void hal_set_radio_mode( struct hw_data * pHwData,  unsigned char radio_off)
 {
 	struct wb35_reg *reg = &pHwData->reg;
 
@@ -516,7 +516,7 @@
 	Wb35Reg_Write( pHwData, 0x0824, reg->M24_MacControl );
 }
 
-u8 hal_get_antenna_number(  phw_data_t pHwData )
+u8 hal_get_antenna_number(  struct hw_data * pHwData )
 {
 	struct wb35_reg *reg = &pHwData->reg;
 
@@ -528,7 +528,7 @@
 
 //----------------------------------------------------------------------------------------------------
 //0 : radio on; 1: radio off
-u8 hal_get_hw_radio_off(  phw_data_t pHwData )
+u8 hal_get_hw_radio_off(  struct hw_data * pHwData )
 {
 	struct wb35_reg *reg = &pHwData->reg;
 
@@ -545,14 +545,14 @@
 	}
 }
 
-unsigned char hal_get_dxx_reg(  phw_data_t pHwData,  u16 number,  u32 * pValue )
+unsigned char hal_get_dxx_reg(  struct hw_data * pHwData,  u16 number,  u32 * pValue )
 {
 	if( number < 0x1000 )
 		number += 0x1000;
 	return Wb35Reg_ReadSync( pHwData, number, pValue );
 }
 
-unsigned char hal_set_dxx_reg(  phw_data_t pHwData,  u16 number,  u32 value )
+unsigned char hal_set_dxx_reg(  struct hw_data * pHwData,  u16 number,  u32 value )
 {
 	unsigned char	ret;
 
@@ -562,7 +562,7 @@
 	return ret;
 }
 
-void hal_set_rf_power(phw_data_t pHwData, u8 PowerIndex)
+void hal_set_rf_power(struct hw_data * pHwData, u8 PowerIndex)
 {
 	RFSynthesizer_SetPowerIndex( pHwData, PowerIndex );
 }
diff --git a/drivers/staging/winbond/wbhal_f.h b/drivers/staging/winbond/wbhal_f.h
index e805f40..efcaefb 100644
--- a/drivers/staging/winbond/wbhal_f.h
+++ b/drivers/staging/winbond/wbhal_f.h
@@ -10,56 +10,56 @@
 //====================================================================================
 // Function declaration
 //====================================================================================
-void hal_remove_mapping_key(  phw_data_t pHwData,  u8 *pmac_addr );
-void hal_remove_default_key(  phw_data_t pHwData,  u32 index );
-unsigned char hal_set_mapping_key(  phw_data_t adapter,  u8 *pmac_addr,  u8 null_key,  u8 wep_on,  u8 *ptx_tsc,  u8 *prx_tsc,  u8 key_type,  u8 key_len,  u8 *pkey_data );
-unsigned char hal_set_default_key(  phw_data_t adapter,  u8 index,  u8 null_key,  u8 wep_on,  u8 *ptx_tsc,  u8 *prx_tsc,  u8 key_type,  u8 key_len,  u8 *pkey_data );
-void hal_clear_all_default_key(  phw_data_t pHwData );
-void hal_clear_all_group_key(  phw_data_t pHwData );
-void hal_clear_all_mapping_key(  phw_data_t pHwData );
-void hal_clear_all_key(  phw_data_t pHwData );
-void hal_get_ethernet_address(  phw_data_t pHwData,  u8 *current_address );
-void hal_set_ethernet_address(  phw_data_t pHwData,  u8 *current_address );
-void hal_get_permanent_address(  phw_data_t pHwData,  u8 *pethernet_address );
+void hal_remove_mapping_key(  struct hw_data * pHwData,  u8 *pmac_addr );
+void hal_remove_default_key(  struct hw_data * pHwData,  u32 index );
+unsigned char hal_set_mapping_key(  struct hw_data * adapter,  u8 *pmac_addr,  u8 null_key,  u8 wep_on,  u8 *ptx_tsc,  u8 *prx_tsc,  u8 key_type,  u8 key_len,  u8 *pkey_data );
+unsigned char hal_set_default_key(  struct hw_data * adapter,  u8 index,  u8 null_key,  u8 wep_on,  u8 *ptx_tsc,  u8 *prx_tsc,  u8 key_type,  u8 key_len,  u8 *pkey_data );
+void hal_clear_all_default_key(  struct hw_data * pHwData );
+void hal_clear_all_group_key(  struct hw_data * pHwData );
+void hal_clear_all_mapping_key(  struct hw_data * pHwData );
+void hal_clear_all_key(  struct hw_data * pHwData );
+void hal_get_ethernet_address(  struct hw_data * pHwData,  u8 *current_address );
+void hal_set_ethernet_address(  struct hw_data * pHwData,  u8 *current_address );
+void hal_get_permanent_address(  struct hw_data * pHwData,  u8 *pethernet_address );
 u8 hal_init_hardware(struct ieee80211_hw *hw);
-void hal_set_power_save_mode(  phw_data_t pHwData,  unsigned char power_save,  unsigned char wakeup,  unsigned char dtim );
-void hal_get_power_save_mode(  phw_data_t pHwData,   u8 *pin_pwr_save );
-void hal_set_slot_time(  phw_data_t pHwData,  u8 type );
+void hal_set_power_save_mode(  struct hw_data * pHwData,  unsigned char power_save,  unsigned char wakeup,  unsigned char dtim );
+void hal_get_power_save_mode(  struct hw_data * pHwData,   u8 *pin_pwr_save );
+void hal_set_slot_time(  struct hw_data * pHwData,  u8 type );
 #define hal_set_atim_window( _A, _ATM )
-void hal_start_bss(  phw_data_t pHwData,  u8 mac_op_mode );
-void hal_join_request(  phw_data_t pHwData,  u8 bss_type ); // 0:BSS STA 1:IBSS STA//
-void hal_stop_sync_bss(  phw_data_t pHwData );
-void hal_resume_sync_bss(  phw_data_t pHwData);
-void hal_set_aid(  phw_data_t pHwData,  u16 aid );
-void hal_set_bssid(  phw_data_t pHwData,  u8 *pbssid );
-void hal_get_bssid(  phw_data_t pHwData,  u8 *pbssid );
-void hal_set_beacon_period(  phw_data_t pHwData,  u16 beacon_period );
-void hal_set_listen_interval(  phw_data_t pHwData,  u16 listen_interval );
-void hal_set_cap_info(  phw_data_t pHwData,  u16 capability_info );
-void hal_set_ssid(  phw_data_t pHwData,  u8 *pssid,  u8 ssid_len );
-void hal_set_current_channel(  phw_data_t pHwData,  ChanInfo channel );
-void hal_set_accept_broadcast(  phw_data_t pHwData,  u8 enable );
-void hal_set_accept_multicast(  phw_data_t pHwData,  u8 enable );
-void hal_set_accept_beacon(  phw_data_t pHwData,  u8 enable );
-void hal_stop(  phw_data_t pHwData );
-void hal_halt(  phw_data_t pHwData, void *ppa_data );
-void hal_start_tx0(  phw_data_t pHwData );
-void hal_set_phy_type(  phw_data_t pHwData,  u8 PhyType );
+void hal_start_bss(  struct hw_data * pHwData,  u8 mac_op_mode );
+void hal_join_request(  struct hw_data * pHwData,  u8 bss_type ); // 0:BSS STA 1:IBSS STA//
+void hal_stop_sync_bss(  struct hw_data * pHwData );
+void hal_resume_sync_bss(  struct hw_data * pHwData);
+void hal_set_aid(  struct hw_data * pHwData,  u16 aid );
+void hal_set_bssid(  struct hw_data * pHwData,  u8 *pbssid );
+void hal_get_bssid(  struct hw_data * pHwData,  u8 *pbssid );
+void hal_set_beacon_period(  struct hw_data * pHwData,  u16 beacon_period );
+void hal_set_listen_interval(  struct hw_data * pHwData,  u16 listen_interval );
+void hal_set_cap_info(  struct hw_data * pHwData,  u16 capability_info );
+void hal_set_ssid(  struct hw_data * pHwData,  u8 *pssid,  u8 ssid_len );
+void hal_set_current_channel(  struct hw_data * pHwData,  ChanInfo channel );
+void hal_set_accept_broadcast(  struct hw_data * pHwData,  u8 enable );
+void hal_set_accept_multicast(  struct hw_data * pHwData,  u8 enable );
+void hal_set_accept_beacon(  struct hw_data * pHwData,  u8 enable );
+void hal_stop(  struct hw_data * pHwData );
+void hal_halt(  struct hw_data * pHwData, void *ppa_data );
+void hal_start_tx0(  struct hw_data * pHwData );
+void hal_set_phy_type(  struct hw_data * pHwData,  u8 PhyType );
 #define hal_get_cwmin( _A ) ( (_A)->cwmin )
-void hal_set_cwmax(  phw_data_t pHwData,  u16 cwin_max );
+void hal_set_cwmax(  struct hw_data * pHwData,  u16 cwin_max );
 #define hal_get_cwmax( _A ) ( (_A)->cwmax )
-void hal_set_rsn_wpa(  phw_data_t pHwData,  u32 * RSN_IE_Bitmap , u32 * RSN_OUI_type , unsigned char bDesiredAuthMode);
-void hal_set_connect_info(  phw_data_t pHwData,  unsigned char boConnect );
-u8 hal_get_est_sq3(  phw_data_t pHwData,  u8 Count );
-void hal_set_rf_power(  phw_data_t pHwData,  u8 PowerIndex ); // 20060621 Modify
-void hal_set_radio_mode(  phw_data_t pHwData,  unsigned char boValue);
-void hal_descriptor_indicate(  phw_data_t pHwData,  PDESCRIPTOR pDes );
-u8 hal_get_antenna_number(  phw_data_t pHwData );
-u32 hal_get_bss_pk_cnt(  phw_data_t pHwData );
+void hal_set_rsn_wpa(  struct hw_data * pHwData,  u32 * RSN_IE_Bitmap , u32 * RSN_OUI_type , unsigned char bDesiredAuthMode);
+void hal_set_connect_info(  struct hw_data * pHwData,  unsigned char boConnect );
+u8 hal_get_est_sq3(  struct hw_data * pHwData,  u8 Count );
+void hal_set_rf_power(  struct hw_data * pHwData,  u8 PowerIndex ); // 20060621 Modify
+void hal_set_radio_mode(  struct hw_data * pHwData,  unsigned char boValue);
+void hal_descriptor_indicate(  struct hw_data * pHwData,  PDESCRIPTOR pDes );
+u8 hal_get_antenna_number(  struct hw_data * pHwData );
+u32 hal_get_bss_pk_cnt(  struct hw_data * pHwData );
 #define hal_get_region_from_EEPROM( _A ) ( (_A)->reg.EEPROMRegion )
-void hal_set_accept_promiscuous		(  phw_data_t pHwData,  u8 enable);
+void hal_set_accept_promiscuous		(  struct hw_data * pHwData,  u8 enable);
 #define hal_get_tx_buffer( _A, _B ) Wb35Tx_get_tx_buffer( _A, _B )
-u8 hal_get_hw_radio_off			(  phw_data_t pHwData );
+u8 hal_get_hw_radio_off			(  struct hw_data * pHwData );
 #define hal_software_set( _A )		(_A->SoftwareSet)
 #define hal_driver_init_OK( _A )	(_A->IsInitOK)
 #define hal_rssi_boundary_high( _A ) (_A->RSSI_high)
@@ -68,8 +68,8 @@
 
 #define PHY_DEBUG( msg, args... )
 
-unsigned char hal_get_dxx_reg(  phw_data_t pHwData,  u16 number,  u32 * pValue );
-unsigned char hal_set_dxx_reg(  phw_data_t pHwData,  u16 number,  u32 value );
+unsigned char hal_get_dxx_reg(  struct hw_data * pHwData,  u16 number,  u32 * pValue );
+unsigned char hal_set_dxx_reg(  struct hw_data * pHwData,  u16 number,  u32 value );
 #define hal_get_time_count( _P )	(_P->time_count/10)	// return 100ms count
 #define hal_detect_error( _P )		(_P->WbUsb.DetectCount)
 
@@ -82,7 +82,7 @@
 #define hal_get_clear_interrupt(_A)
 #define hal_ibss_disconnect(_A) hal_stop_sync_bss(_A)
 #define hal_join_request_stop(_A)
-unsigned char	hal_idle(  phw_data_t pHwData );
+unsigned char	hal_idle(  struct hw_data * pHwData );
 #define hw_get_cxx_reg( _A, _B, _C )
 #define hw_set_cxx_reg( _A, _B, _C )
 #define hw_get_dxx_reg( _A, _B, _C )	hal_get_dxx_reg( _A, _B, (u32 *)_C )
diff --git a/drivers/staging/winbond/wbhal_s.h b/drivers/staging/winbond/wbhal_s.h
index 276d2b1..acfebf0 100644
--- a/drivers/staging/winbond/wbhal_s.h
+++ b/drivers/staging/winbond/wbhal_s.h
@@ -2,8 +2,7 @@
 #define __WINBOND_WBHAL_S_H
 
 #include <linux/types.h>
-
-#include "common.h"
+#include <linux/if_ether.h> /* for ETH_ALEN */
 
 //[20040722 WK]
 #define HAL_LED_SET_MASK		0x001c	//20060901 Extend
@@ -86,19 +85,6 @@
 	VM_COMPLETED
 };
 
-// Be used for 802.11 mac header
-typedef struct _MAC_FRAME_CONTROL {
-	u8	mac_frame_info; // this is a combination of the protovl version, type and subtype
-	u8	to_ds:1;
-	u8	from_ds:1;
-	u8	more_frag:1;
-	u8	retry:1;
-	u8	pwr_mgt:1;
-	u8	more_data:1;
-	u8	WEP:1;
-	u8	order:1;
-} MAC_FRAME_CONTROL, *PMAC_FRAME_CONTROL;
-
 //-----------------------------------------------------
 // Normal Key table format
 //-----------------------------------------------------
@@ -106,28 +92,6 @@
 #define MAX_KEY_TABLE				24	// 24 entry for storing key data
 #define GROUP_KEY_START_INDEX		4
 #define MAPPING_KEY_START_INDEX		8
-typedef struct _KEY_TABLE
-{
-	u32	DW0_Valid:1;
-	u32	DW0_NullKey:1;
-	u32	DW0_Security_Mode:2;//0:WEP 40 bit 1:WEP 104 bit 2:TKIP 128 bit 3:CCMP 128 bit
-	u32	DW0_WEPON:1;
-	u32	DW0_RESERVED:11;
-	u32	DW0_Address1:16;
-
-	u32	DW1_Address2;
-
-	u32	DW2_RxSequenceCount1;
-
-	u32	DW3_RxSequenceCount2:16;
-	u32	DW3_RESERVED:16;
-
-	u32	DW4_TxSequenceCount1;
-
-	u32	DW5_TxSequenceCount2:16;
-	u32	DW5_RESERVED:16;
-
-} KEY_TABLE, *PKEY_TABLE;
 
 //--------------------------------------------------------
 // 			 Descriptor
@@ -413,8 +377,8 @@
 #define MAX_RF_PARAMETER	32
 
 typedef struct _TXVGA_FOR_50 {
-	u8	ChanNo;
-	u8	TxVgaValue;
+	u8      ChanNo;
+	u8      TxVgaValue;
 } TXVGA_FOR_50;
 
 
@@ -427,10 +391,8 @@
 #include "wb35tx_s.h"
 #include "wb35rx_s.h"
 
-
 // For Hal using ==================================================================
-typedef struct _HW_DATA_T
-{
+struct hw_data {
 	// For compatible with 33
 	u32	revision;
 	u32	BB3c_cal; // The value for Tx calibration comes from EEPROM
@@ -452,8 +414,8 @@
 	//===============================================
 	// Definition for MAC address
 	//===============================================
-	u8		PermanentMacAddress[ETH_LENGTH_OF_ADDRESS + 2]; // The Enthernet addr that are stored in EEPROM.  + 2 to 8-byte alignment
-	u8		CurrentMacAddress[ETH_LENGTH_OF_ADDRESS + 2]; // The Enthernet addr that are in used.  + 2 to 8-byte alignment
+	u8		PermanentMacAddress[ETH_ALEN + 2]; // The Enthernet addr that are stored in EEPROM.  + 2 to 8-byte alignment
+	u8		CurrentMacAddress[ETH_ALEN + 2]; // The Enthernet addr that are in used.  + 2 to 8-byte alignment
 
 	//=====================================================================
 	// Definition for 802.11
@@ -502,10 +464,10 @@
 	//========================================================================
 	// Variable for each module
 	//========================================================================
-	WBUSB		WbUsb; // Need WbUsb.h
+	struct wb_usb	WbUsb; // Need WbUsb.h
 	struct wb35_reg	reg; // Need Wb35Reg.h
-	WB35TX		Wb35Tx; // Need Wb35Tx.h
-	WB35RX		Wb35Rx; // Need Wb35Rx.h
+	struct wb35_tx	Wb35Tx; // Need Wb35Tx.h
+	struct wb35_rx	Wb35Rx; // Need Wb35Rx.h
 
 	struct timer_list	LEDTimer;// For LED
 
@@ -578,35 +540,6 @@
 	// 20060828.1 for avoid AP disconnect
 	u32		NullPacketCount;
 
-} hw_data_t, *phw_data_t;
-
-// The mapping of Rx and Tx descriptor field
-typedef struct _HAL_RATE
-{
-	// DSSS
-	u32	RESERVED_0;
-	u32   NumRate2MS;
-	u32   NumRate55MS;
-	u32   NumRate11MS;
-
-	u32	RESERVED_1[4];
-
-	u32   NumRate1M;
-	u32   NumRate2ML;
-	u32   NumRate55ML;
-	u32   NumRate11ML;
-
-	u32	RESERVED_2[4];
-
-	// OFDM
-	u32   NumRate6M;
-	u32   NumRate9M;
-	u32   NumRate12M;
-	u32   NumRate18M;
-	u32   NumRate24M;
-	u32   NumRate36M;
-	u32   NumRate48M;
-	u32   NumRate54M;
-} HAL_RATE, *PHAL_RATE;
+};
 
 #endif
diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c
index f716b2e..9c3f9439 100644
--- a/drivers/staging/winbond/wbusb.c
+++ b/drivers/staging/winbond/wbusb.c
@@ -9,7 +9,7 @@
 #include "core.h"
 #include "mds_f.h"
 #include "mlmetxrx_f.h"
-#include "mto_f.h"
+#include "mto.h"
 #include "wbhal_f.h"
 #include "wblinux_f.h"
 
@@ -149,19 +149,19 @@
 	hal_set_current_channel(&priv->sHwData, ch);
 	hal_set_beacon_period(&priv->sHwData, conf->beacon_int);
 //	hal_set_cap_info(&priv->sHwData, ?? );
-// hal_set_ssid(phw_data_t pHwData,  u8 * pssid,  u8 ssid_len); ??
+// hal_set_ssid(struct hw_data * pHwData,  u8 * pssid,  u8 ssid_len); ??
 	hal_set_accept_broadcast(&priv->sHwData, 1);
 	hal_set_accept_promiscuous(&priv->sHwData,  1);
 	hal_set_accept_multicast(&priv->sHwData,  1);
 	hal_set_accept_beacon(&priv->sHwData,  1);
 	hal_set_radio_mode(&priv->sHwData,  0);
-	//hal_set_antenna_number(  phw_data_t pHwData, u8 number )
-	//hal_set_rf_power(phw_data_t pHwData, u8 PowerIndex)
+	//hal_set_antenna_number(  struct hw_data * pHwData, u8 number )
+	//hal_set_rf_power(struct hw_data * pHwData, u8 PowerIndex)
 
 
 //	hal_start_bss(&priv->sHwData, WLAN_BSSTYPE_INFRASTRUCTURE);	??
 
-//void hal_set_rates(phw_data_t pHwData, u8 * pbss_rates,
+//void hal_set_rates(struct hw_data * pHwData, u8 * pbss_rates,
 //		   u8 length, unsigned char basic_rate_set)
 
 	return 0;
@@ -199,7 +199,7 @@
 static unsigned char wb35_hw_init(struct ieee80211_hw *hw)
 {
 	struct wbsoft_priv *priv = hw->priv;
-	phw_data_t	pHwData;
+	struct hw_data *	pHwData;
 	u8		*pMacAddr;
 	u8		*pMacAddr2;
 	u32		InitStep = 0;
@@ -277,7 +277,7 @@
 	//get current antenna
 	priv->sLocalPara.bAntennaNo = hal_get_antenna_number(pHwData);
 #ifdef _PE_STATE_DUMP_
-	WBDEBUG(("Driver init, antenna no = %d\n", psLOCAL->bAntennaNo));
+	printk("Driver init, antenna no = %d\n", psLOCAL->bAntennaNo);
 #endif
 	hal_get_hw_radio_off( pHwData );
 
@@ -312,7 +312,7 @@
 
 static int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id_table)
 {
-	PWBUSB		pWbUsb;
+	struct wb_usb *pWbUsb;
         struct usb_host_interface *interface;
 	struct usb_endpoint_descriptor *endpoint;
 	u32	ltmp;
@@ -366,7 +366,7 @@
 
 	SET_IEEE80211_DEV(dev, &udev->dev);
 	{
-		phw_data_t pHwData = &priv->sHwData;
+		struct hw_data * pHwData = &priv->sHwData;
 		unsigned char		dev_addr[MAX_ADDR_LEN];
 		hal_get_permanent_address(pHwData, dev_addr);
 		SET_IEEE80211_PERM_ADDR(dev, dev_addr);
@@ -404,7 +404,7 @@
 	// Turn off Rx and Tx hardware ability
 	hal_stop( &adapter->sHwData );
 #ifdef _PE_USB_INI_DUMP_
-	WBDEBUG(("[w35und] Hal_stop O.K.\n"));
+	printk("[w35und] Hal_stop O.K.\n");
 #endif
 	msleep(100);// Waiting Irp completed
 
diff --git a/drivers/staging/winbond/wbusb_s.h b/drivers/staging/winbond/wbusb_s.h
index 1de9360..0c7e6a3 100644
--- a/drivers/staging/winbond/wbusb_s.h
+++ b/drivers/staging/winbond/wbusb_s.h
@@ -16,22 +16,10 @@
 
 #include <linux/types.h>
 
-//---------------------------------------------------------------------------
-//  RW_CONTEXT --
-//
-//  Used to track driver-generated io irps
-//---------------------------------------------------------------------------
-typedef struct _RW_CONTEXT
-{
-	void*			pHwData;
-	struct urb		*urb;
-	void*			pCallBackFunctionParameter;
-} RW_CONTEXT, *PRW_CONTEXT;
-
-typedef struct _WBUSB {
+struct wb_usb {
 	u32	IsUsb20;
 	struct usb_device *udev;
 	u32	DetectCount;
-} WBUSB, *PWBUSB;
+};
 
 #endif
diff --git a/drivers/staging/wlan-ng/README b/drivers/staging/wlan-ng/README
index 9c10dbb..028c299 100644
--- a/drivers/staging/wlan-ng/README
+++ b/drivers/staging/wlan-ng/README
@@ -4,4 +4,6 @@
 	- Lindent cleanups
 	- move to use the in-kernel wireless stack
 
-Please send all patches to Greg Kroah-Hartman <greg@kroah.com>
+Please send any patches or complaints about this driver to Greg
+Kroah-Hartman <greg@kroah.com> and don't bother the upstream wireless
+kernel developers about it, they want nothing to do with it.
diff --git a/drivers/staging/wlan-ng/hfa384x.h b/drivers/staging/wlan-ng/hfa384x.h
index 9b74665..f3e8717 100644
--- a/drivers/staging/wlan-ng/hfa384x.h
+++ b/drivers/staging/wlan-ng/hfa384x.h
@@ -56,75 +56,37 @@
 #ifndef _HFA384x_H
 #define _HFA384x_H
 
-/*=============================================================*/
-#define HFA384x_FIRMWARE_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+#define HFA384x_FIRMWARE_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))
 
-#define HFA384x_LEVEL_TO_dBm(v)   (0x100 + (v) * 100 / 255 - 100)
+#include <linux/if_ether.h>
 
-/*------ Constants --------------------------------------------*/
 /*--- Mins & Maxs -----------------------------------*/
-#define		HFA384x_CMD_ALLOC_LEN_MIN	((u16)4)
-#define		HFA384x_CMD_ALLOC_LEN_MAX	((u16)2400)
-#define		HFA384x_BAP_DATALEN_MAX		((u16)4096)
-#define		HFA384x_BAP_OFFSET_MAX		((u16)4096)
 #define		HFA384x_PORTID_MAX		((u16)7)
 #define		HFA384x_NUMPORTS_MAX		((u16)(HFA384x_PORTID_MAX+1))
-#define		HFA384x_PDR_LEN_MAX		((u16)512)	/* in bytes, from EK */
-#define		HFA384x_PDA_RECS_MAX		((u16)200)	/* a guess */
-#define		HFA384x_PDA_LEN_MAX		((u16)1024)	/* in bytes, from EK */
+#define		HFA384x_PDR_LEN_MAX		((u16)512) /* in bytes, from EK */
+#define		HFA384x_PDA_LEN_MAX		((u16)1024) /* in bytes, from EK */
 #define		HFA384x_SCANRESULT_MAX		((u16)31)
 #define		HFA384x_HSCANRESULT_MAX		((u16)31)
 #define		HFA384x_CHINFORESULT_MAX	((u16)16)
-#define		HFA384x_DRVR_FIDSTACKLEN_MAX	(10)
-#define		HFA384x_DRVR_TXBUF_MAX		(sizeof(hfa384x_tx_frame_t) + \
-						WLAN_DATA_MAXLEN - \
-						WLAN_WEP_IV_LEN - \
-						WLAN_WEP_ICV_LEN + 2)
-#define		HFA384x_DRVR_MAGIC		(0x4a2d)
-#define		HFA384x_INFODATA_MAXLEN		(sizeof(hfa384x_infodata_t))
-#define		HFA384x_INFOFRM_MAXLEN		(sizeof(hfa384x_InfFrame_t))
-#define		HFA384x_RID_GUESSING_MAXLEN	2048  /* I'm not really sure */
+#define		HFA384x_RID_GUESSING_MAXLEN	2048	/* I'm not really sure */
 #define		HFA384x_RIDDATA_MAXLEN		HFA384x_RID_GUESSING_MAXLEN
 #define		HFA384x_USB_RWMEM_MAXLEN	2048
 
 /*--- Support Constants -----------------------------*/
-#define		HFA384x_BAP_PROC			((u16)0)
-#define		HFA384x_BAP_int				((u16)1)
 #define		HFA384x_PORTTYPE_IBSS			((u16)0)
 #define		HFA384x_PORTTYPE_BSS			((u16)1)
-#define		HFA384x_PORTTYPE_WDS			((u16)2)
 #define		HFA384x_PORTTYPE_PSUEDOIBSS		((u16)3)
-#define		HFA384x_PORTTYPE_HOSTAP    		((u16)6)
-#define		HFA384x_WEPFLAGS_PRIVINVOKED		((u16)BIT0)
-#define		HFA384x_WEPFLAGS_EXCLUDE		((u16)BIT1)
-#define		HFA384x_WEPFLAGS_DISABLE_TXCRYPT	((u16)BIT4)
-#define		HFA384x_WEPFLAGS_DISABLE_RXCRYPT	((u16)BIT7)
-#define		HFA384x_WEPFLAGS_DISALLOW_MIXED 	((u16)BIT11)
-#define		HFA384x_WEPFLAGS_IV_intERVAL1		((u16)0)
-#define		HFA384x_WEPFLAGS_IV_intERVAL10		((u16)BIT5)
-#define		HFA384x_WEPFLAGS_IV_intERVAL50		((u16)BIT6)
-#define		HFA384x_WEPFLAGS_IV_intERVAL100		((u16)(BIT5 | BIT6))
-#define		HFA384x_WEPFLAGS_FIRMWARE_WPA  		((u16)BIT8)
-#define		HFA384x_WEPFLAGS_HOST_MIC      		((u16)BIT9)
-#define 	HFA384x_ROAMMODE_FWSCAN_FWROAM		((u16)1)
-#define 	HFA384x_ROAMMODE_FWSCAN_HOSTROAM	((u16)2)
+#define		HFA384x_WEPFLAGS_PRIVINVOKED		((u16)BIT(0))
+#define		HFA384x_WEPFLAGS_EXCLUDE		((u16)BIT(1))
+#define		HFA384x_WEPFLAGS_DISABLE_TXCRYPT	((u16)BIT(4))
+#define		HFA384x_WEPFLAGS_DISABLE_RXCRYPT	((u16)BIT(7))
 #define 	HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM	((u16)3)
 #define 	HFA384x_PORTSTATUS_DISABLED		((u16)1)
-#define 	HFA384x_PORTSTATUS_INITSRCH		((u16)2)
-#define 	HFA384x_PORTSTATUS_CONN_IBSS		((u16)3)
-#define 	HFA384x_PORTSTATUS_CONN_ESS		((u16)4)
-#define 	HFA384x_PORTSTATUS_OOR_ESS		((u16)5)
-#define 	HFA384x_PORTSTATUS_CONN_WDS		((u16)6)
-#define 	HFA384x_PORTSTATUS_HOSTAP		((u16)8)
 #define		HFA384x_RATEBIT_1			((u16)1)
 #define		HFA384x_RATEBIT_2			((u16)2)
 #define		HFA384x_RATEBIT_5dot5			((u16)4)
 #define		HFA384x_RATEBIT_11			((u16)8)
 
-/*--- Just some symbolic names for legibility -------*/
-#define		HFA384x_TXCMD_NORECL		((u16)0)
-#define		HFA384x_TXCMD_RECL		((u16)1)
-
 /*--- MAC Internal memory constants and macros ------*/
 /* masks and macros used to manipulate MAC internal memory addresses. */
 /* MAC internal memory addresses are 23 bit quantities.  The MAC uses
@@ -139,59 +101,28 @@
  * macros below help handle some of this.
  */
 
-/* Handy constant */
-#define		HFA384x_ADDR_AUX_OFF_MAX	((u16)0x007f)
-
 /* Mask bits for discarding unwanted pieces in a flat address */
 #define		HFA384x_ADDR_FLAT_AUX_PAGE_MASK	(0x007fff80)
 #define		HFA384x_ADDR_FLAT_AUX_OFF_MASK	(0x0000007f)
 #define		HFA384x_ADDR_FLAT_CMD_PAGE_MASK	(0xffff0000)
 #define		HFA384x_ADDR_FLAT_CMD_OFF_MASK	(0x0000ffff)
 
-/* Mask bits for discarding unwanted pieces in AUX format 16-bit address parts */
+/* Mask bits for discarding unwanted pieces in AUX format
+   16-bit address parts */
 #define		HFA384x_ADDR_AUX_PAGE_MASK	(0xffff)
 #define		HFA384x_ADDR_AUX_OFF_MASK	(0x007f)
 
-/* Mask bits for discarding unwanted pieces in CMD format 16-bit address parts */
-#define		HFA384x_ADDR_CMD_PAGE_MASK	(0x007f)
-#define		HFA384x_ADDR_CMD_OFF_MASK	(0xffff)
-
 /* Make a 32-bit flat address from AUX format 16-bit page and offset */
-#define		HFA384x_ADDR_AUX_MKFLAT(p,o)	\
-		(((u32)(((u16)(p))&HFA384x_ADDR_AUX_PAGE_MASK)) <<7) | \
+#define		HFA384x_ADDR_AUX_MKFLAT(p, o)	\
+		(((u32)(((u16)(p))&HFA384x_ADDR_AUX_PAGE_MASK)) << 7) | \
 		((u32)(((u16)(o))&HFA384x_ADDR_AUX_OFF_MASK))
 
-/* Make a 32-bit flat address from CMD format 16-bit page and offset */
-#define		HFA384x_ADDR_CMD_MKFLAT(p,o)	\
-		(((u32)(((u16)(p))&HFA384x_ADDR_CMD_PAGE_MASK)) <<16) | \
-		((u32)(((u16)(o))&HFA384x_ADDR_CMD_OFF_MASK))
-
-/* Make AUX format offset and page from a 32-bit flat address */
-#define		HFA384x_ADDR_AUX_MKPAGE(f) \
-		((u16)((((u32)(f))&HFA384x_ADDR_FLAT_AUX_PAGE_MASK)>>7))
-#define		HFA384x_ADDR_AUX_MKOFF(f) \
-		((u16)(((u32)(f))&HFA384x_ADDR_FLAT_AUX_OFF_MASK))
-
 /* Make CMD format offset and page from a 32-bit flat address */
 #define		HFA384x_ADDR_CMD_MKPAGE(f) \
 		((u16)((((u32)(f))&HFA384x_ADDR_FLAT_CMD_PAGE_MASK)>>16))
 #define		HFA384x_ADDR_CMD_MKOFF(f) \
 		((u16)(((u32)(f))&HFA384x_ADDR_FLAT_CMD_OFF_MASK))
 
-/*--- Aux register masks/tests ----------------------*/
-/* Some of the upper bits of the AUX offset register are used to */
-/*  select address space. */
-#define		HFA384x_AUX_CTL_EXTDS	(0x00)
-#define		HFA384x_AUX_CTL_NV	(0x01)
-#define		HFA384x_AUX_CTL_PHY	(0x02)
-#define		HFA384x_AUX_CTL_ICSRAM	(0x03)
-
-/* Make AUX register offset and page values from a flat address */
-#define		HFA384x_AUX_MKOFF(f, c) \
-	(HFA384x_ADDR_AUX_MKOFF(f) | (((u16)(c))<<12))
-#define		HFA384x_AUX_MKPAGE(f)	HFA384x_ADDR_AUX_MKPAGE(f)
-
-
 /*--- Controller Memory addresses -------------------*/
 #define		HFA3842_PDA_BASE	(0x007f0000UL)
 #define		HFA3841_PDA_BASE	(0x003f0000UL)
@@ -201,124 +132,25 @@
 #define		HFA384x_DLSTATE_DISABLED		0
 #define		HFA384x_DLSTATE_RAMENABLED		1
 #define		HFA384x_DLSTATE_FLASHENABLED		2
-#define		HFA384x_DLSTATE_FLASHWRITTEN		3
-#define		HFA384x_DLSTATE_FLASHWRITEPENDING	4
-#define		HFA384x_DLSTATE_GENESIS 		5
-
-#define		HFA384x_CMD_OFF			(0x00)
-#define		HFA384x_PARAM0_OFF		(0x04)
-#define		HFA384x_PARAM1_OFF		(0x08)
-#define		HFA384x_PARAM2_OFF		(0x0c)
-#define		HFA384x_STATUS_OFF		(0x10)
-#define		HFA384x_RESP0_OFF		(0x14)
-#define		HFA384x_RESP1_OFF		(0x18)
-#define		HFA384x_RESP2_OFF		(0x1c)
-#define		HFA384x_INFOFID_OFF		(0x20)
-#define		HFA384x_RXFID_OFF		(0x40)
-#define		HFA384x_ALLOCFID_OFF		(0x44)
-#define		HFA384x_TXCOMPLFID_OFF		(0x48)
-#define		HFA384x_SELECT0_OFF		(0x30)
-#define		HFA384x_OFFSET0_OFF		(0x38)
-#define		HFA384x_DATA0_OFF		(0x6c)
-#define		HFA384x_SELECT1_OFF		(0x34)
-#define		HFA384x_OFFSET1_OFF		(0x3c)
-#define		HFA384x_DATA1_OFF		(0x70)
-#define		HFA384x_EVSTAT_OFF		(0x60)
-#define		HFA384x_intEN_OFF		(0x64)
-#define		HFA384x_EVACK_OFF		(0x68)
-#define		HFA384x_CONTROL_OFF		(0x28)
-#define		HFA384x_SWSUPPORT0_OFF		(0x50)
-#define		HFA384x_SWSUPPORT1_OFF		(0x54)
-#define		HFA384x_SWSUPPORT2_OFF		(0x58)
-#define		HFA384x_AUXPAGE_OFF		(0x74)
-#define		HFA384x_AUXOFFSET_OFF		(0x78)
-#define		HFA384x_AUXDATA_OFF		(0x7c)
-#define		HFA384x_PCICOR_OFF		(0x4c)
-#define		HFA384x_PCIHCR_OFF		(0x5c)
-#define		HFA384x_PCI_M0_ADDRH_OFF	(0x80)
-#define		HFA384x_PCI_M0_ADDRL_OFF	(0x84)
-#define		HFA384x_PCI_M0_LEN_OFF		(0x88)
-#define		HFA384x_PCI_M0_CTL_OFF		(0x8c)
-#define		HFA384x_PCI_STATUS_OFF		(0x98)
-#define		HFA384x_PCI_M1_ADDRH_OFF	(0xa0)
-#define		HFA384x_PCI_M1_ADDRL_OFF	(0xa4)
-#define		HFA384x_PCI_M1_LEN_OFF		(0xa8)
-#define		HFA384x_PCI_M1_CTL_OFF		(0xac)
 
 /*--- Register Field Masks --------------------------*/
-#define		HFA384x_CMD_BUSY		((u16)BIT15)
-#define		HFA384x_CMD_AINFO		((u16)(BIT14 | BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8))
-#define		HFA384x_CMD_MACPORT		((u16)(BIT10 | BIT9 | BIT8))
-#define		HFA384x_CMD_RECL		((u16)BIT8)
-#define		HFA384x_CMD_WRITE		((u16)BIT8)
-#define		HFA384x_CMD_PROGMODE		((u16)(BIT9 | BIT8))
-#define		HFA384x_CMD_CMDCODE		((u16)(BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0))
+#define		HFA384x_CMD_AINFO		((u16)(BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10) | BIT(9) | BIT(8)))
+#define		HFA384x_CMD_MACPORT		((u16)(BIT(10) | BIT(9) | BIT(8)))
+#define		HFA384x_CMD_PROGMODE		((u16)(BIT(9) | BIT(8)))
+#define		HFA384x_CMD_CMDCODE		((u16)(BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)))
 
-#define		HFA384x_STATUS_RESULT		((u16)(BIT14 | BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8))
-#define		HFA384x_STATUS_CMDCODE		((u16)(BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0))
-
-#define		HFA384x_OFFSET_BUSY		((u16)BIT15)
-#define		HFA384x_OFFSET_ERR		((u16)BIT14)
-#define		HFA384x_OFFSET_DATAOFF		((u16)(BIT11 | BIT10 | BIT9 | BIT8 | BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1))
-
-#define		HFA384x_EVSTAT_TICK		((u16)BIT15)
-#define		HFA384x_EVSTAT_WTERR		((u16)BIT14)
-#define		HFA384x_EVSTAT_INFDROP		((u16)BIT13)
-#define		HFA384x_EVSTAT_INFO		((u16)BIT7)
-#define		HFA384x_EVSTAT_DTIM		((u16)BIT5)
-#define		HFA384x_EVSTAT_CMD		((u16)BIT4)
-#define		HFA384x_EVSTAT_ALLOC		((u16)BIT3)
-#define		HFA384x_EVSTAT_TXEXC		((u16)BIT2)
-#define		HFA384x_EVSTAT_TX		((u16)BIT1)
-#define		HFA384x_EVSTAT_RX		((u16)BIT0)
-
-#define         HFA384x_int_BAP_OP           (HFA384x_EVSTAT_INFO|HFA384x_EVSTAT_RX|HFA384x_EVSTAT_TX|HFA384x_EVSTAT_TXEXC)
-
-#define         HFA384x_int_NORMAL           (HFA384x_EVSTAT_INFO|HFA384x_EVSTAT_RX|HFA384x_EVSTAT_TX|HFA384x_EVSTAT_TXEXC|HFA384x_EVSTAT_INFDROP|HFA384x_EVSTAT_ALLOC|HFA384x_EVSTAT_DTIM)
-
-#define		HFA384x_intEN_TICK		((u16)BIT15)
-#define		HFA384x_intEN_WTERR		((u16)BIT14)
-#define		HFA384x_intEN_INFDROP		((u16)BIT13)
-#define		HFA384x_intEN_INFO		((u16)BIT7)
-#define		HFA384x_intEN_DTIM		((u16)BIT5)
-#define		HFA384x_intEN_CMD		((u16)BIT4)
-#define		HFA384x_intEN_ALLOC		((u16)BIT3)
-#define		HFA384x_intEN_TXEXC		((u16)BIT2)
-#define		HFA384x_intEN_TX		((u16)BIT1)
-#define		HFA384x_intEN_RX		((u16)BIT0)
-
-#define		HFA384x_EVACK_TICK		((u16)BIT15)
-#define		HFA384x_EVACK_WTERR		((u16)BIT14)
-#define		HFA384x_EVACK_INFDROP		((u16)BIT13)
-#define		HFA384x_EVACK_INFO		((u16)BIT7)
-#define		HFA384x_EVACK_DTIM		((u16)BIT5)
-#define		HFA384x_EVACK_CMD		((u16)BIT4)
-#define		HFA384x_EVACK_ALLOC		((u16)BIT3)
-#define		HFA384x_EVACK_TXEXC		((u16)BIT2)
-#define		HFA384x_EVACK_TX		((u16)BIT1)
-#define		HFA384x_EVACK_RX		((u16)BIT0)
-
-#define		HFA384x_CONTROL_AUXEN		((u16)(BIT15 | BIT14))
-
+#define		HFA384x_STATUS_RESULT		((u16)(BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10) | BIT(9) | BIT(8)))
 
 /*--- Command Code Constants --------------------------*/
 /*--- Controller Commands --------------------------*/
 #define		HFA384x_CMDCODE_INIT		((u16)0x00)
 #define		HFA384x_CMDCODE_ENABLE		((u16)0x01)
 #define		HFA384x_CMDCODE_DISABLE		((u16)0x02)
-#define		HFA384x_CMDCODE_DIAG		((u16)0x03)
-
-/*--- Buffer Mgmt Commands --------------------------*/
-#define		HFA384x_CMDCODE_ALLOC		((u16)0x0A)
-#define		HFA384x_CMDCODE_TX		((u16)0x0B)
-#define		HFA384x_CMDCODE_CLRPRST		((u16)0x12)
 
 /*--- Regulate Commands --------------------------*/
-#define		HFA384x_CMDCODE_NOTIFY		((u16)0x10)
 #define		HFA384x_CMDCODE_INQ		((u16)0x11)
 
 /*--- Configure Commands --------------------------*/
-#define		HFA384x_CMDCODE_ACCESS		((u16)0x21)
 #define		HFA384x_CMDCODE_DOWNLD		((u16)0x22)
 
 /*--- Debugging Commands -----------------------------*/
@@ -327,9 +159,6 @@
 #define		HFA384x_MONITOR_DISABLE		((u16)(0x0f))
 
 /*--- Result Codes --------------------------*/
-#define		HFA384x_SUCCESS			((u16)(0x00))
-#define		HFA384x_CARD_FAIL		((u16)(0x01))
-#define		HFA384x_NO_BUFF			((u16)(0x05))
 #define		HFA384x_CMD_ERR			((u16)(0x7F))
 
 /*--- Programming Modes --------------------------
@@ -343,16 +172,6 @@
 #define		HFA384x_PROGMODE_NV		((u16)0x02)
 #define		HFA384x_PROGMODE_NVWRITE	((u16)0x03)
 
-/*--- AUX register enable --------------------------*/
-#define		HFA384x_AUXPW0			((u16)0xfe01)
-#define		HFA384x_AUXPW1			((u16)0xdc23)
-#define		HFA384x_AUXPW2			((u16)0xba45)
-
-#define		HFA384x_CONTROL_AUX_ISDISABLED	((u16)0x0000)
-#define		HFA384x_CONTROL_AUX_ISENABLED	((u16)0xc000)
-#define		HFA384x_CONTROL_AUX_DOENABLE	((u16)0x8000)
-#define		HFA384x_CONTROL_AUX_DODISABLE	((u16)0x4000)
-
 /*--- Record ID Constants --------------------------*/
 /*--------------------------------------------------------------------
 Configuration RIDs: Network Parameters, Static Configuration Entities
@@ -362,133 +181,25 @@
 #define		HFA384x_RID_CNFDESIREDSSID	((u16)0xFC02)
 #define		HFA384x_RID_CNFOWNCHANNEL	((u16)0xFC03)
 #define		HFA384x_RID_CNFOWNSSID		((u16)0xFC04)
-#define		HFA384x_RID_CNFOWNATIMWIN	((u16)0xFC05)
-#define		HFA384x_RID_CNFSYSSCALE		((u16)0xFC06)
 #define		HFA384x_RID_CNFMAXDATALEN	((u16)0xFC07)
-#define		HFA384x_RID_CNFWDSADDR		((u16)0xFC08)
-#define		HFA384x_RID_CNFPMENABLED	((u16)0xFC09)
-#define		HFA384x_RID_CNFPMEPS		((u16)0xFC0A)
-#define		HFA384x_RID_CNFMULTICASTRX	((u16)0xFC0B)
-#define		HFA384x_RID_CNFMAXSLEEPDUR	((u16)0xFC0C)
-#define		HFA384x_RID_CNFPMHOLDDUR	((u16)0xFC0D)
-#define		HFA384x_RID_CNFOWNNAME		((u16)0xFC0E)
-#define		HFA384x_RID_CNFOWNDTIMPER	((u16)0xFC10)
-#define		HFA384x_RID_CNFWDSADDR1		((u16)0xFC11)
-#define		HFA384x_RID_CNFWDSADDR2		((u16)0xFC12)
-#define		HFA384x_RID_CNFWDSADDR3		((u16)0xFC13)
-#define		HFA384x_RID_CNFWDSADDR4		((u16)0xFC14)
-#define		HFA384x_RID_CNFWDSADDR5		((u16)0xFC15)
-#define		HFA384x_RID_CNFWDSADDR6		((u16)0xFC16)
-#define		HFA384x_RID_CNFMCASTPMBUFF	((u16)0xFC17)
 
 /*--------------------------------------------------------------------
 Configuration RID lengths: Network Params, Static Config Entities
   This is the length of JUST the DATA part of the RID (does not
   include the len or code fields)
 --------------------------------------------------------------------*/
-/* TODO: fill in the rest of these */
-#define		HFA384x_RID_CNFPORTTYPE_LEN	((u16)2)
 #define		HFA384x_RID_CNFOWNMACADDR_LEN	((u16)6)
 #define		HFA384x_RID_CNFDESIREDSSID_LEN	((u16)34)
-#define		HFA384x_RID_CNFOWNCHANNEL_LEN	((u16)2)
 #define		HFA384x_RID_CNFOWNSSID_LEN	((u16)34)
-#define		HFA384x_RID_CNFOWNATIMWIN_LEN	((u16)2)
-#define		HFA384x_RID_CNFSYSSCALE_LEN	((u16)0)
-#define		HFA384x_RID_CNFMAXDATALEN_LEN	((u16)0)
-#define		HFA384x_RID_CNFWDSADDR_LEN	((u16)6)
-#define		HFA384x_RID_CNFPMENABLED_LEN	((u16)0)
-#define		HFA384x_RID_CNFPMEPS_LEN	((u16)0)
-#define		HFA384x_RID_CNFMULTICASTRX_LEN	((u16)0)
-#define		HFA384x_RID_CNFMAXSLEEPDUR_LEN	((u16)0)
-#define		HFA384x_RID_CNFPMHOLDDUR_LEN	((u16)0)
-#define		HFA384x_RID_CNFOWNNAME_LEN	((u16)34)
-#define		HFA384x_RID_CNFOWNDTIMPER_LEN	((u16)0)
-#define		HFA384x_RID_CNFWDSADDR1_LEN	((u16)6)
-#define		HFA384x_RID_CNFWDSADDR2_LEN	((u16)6)
-#define		HFA384x_RID_CNFWDSADDR3_LEN	((u16)6)
-#define		HFA384x_RID_CNFWDSADDR4_LEN	((u16)6)
-#define		HFA384x_RID_CNFWDSADDR5_LEN	((u16)6)
-#define		HFA384x_RID_CNFWDSADDR6_LEN	((u16)6)
-#define		HFA384x_RID_CNFMCASTPMBUFF_LEN	((u16)0)
-#define		HFA384x_RID_CNFAUTHENTICATION_LEN ((u16)sizeof(u16))
-#define		HFA384x_RID_CNFMAXSLEEPDUR_LEN	((u16)0)
 
 /*--------------------------------------------------------------------
 Configuration RIDs: Network Parameters, Dynamic Configuration Entities
 --------------------------------------------------------------------*/
-#define		HFA384x_RID_GROUPADDR		((u16)0xFC80)
 #define		HFA384x_RID_CREATEIBSS		((u16)0xFC81)
 #define		HFA384x_RID_FRAGTHRESH		((u16)0xFC82)
 #define		HFA384x_RID_RTSTHRESH		((u16)0xFC83)
 #define		HFA384x_RID_TXRATECNTL		((u16)0xFC84)
 #define		HFA384x_RID_PROMISCMODE		((u16)0xFC85)
-#define		HFA384x_RID_FRAGTHRESH0		((u16)0xFC90)
-#define		HFA384x_RID_FRAGTHRESH1		((u16)0xFC91)
-#define		HFA384x_RID_FRAGTHRESH2		((u16)0xFC92)
-#define		HFA384x_RID_FRAGTHRESH3		((u16)0xFC93)
-#define		HFA384x_RID_FRAGTHRESH4		((u16)0xFC94)
-#define		HFA384x_RID_FRAGTHRESH5		((u16)0xFC95)
-#define		HFA384x_RID_FRAGTHRESH6		((u16)0xFC96)
-#define		HFA384x_RID_RTSTHRESH0		((u16)0xFC97)
-#define		HFA384x_RID_RTSTHRESH1		((u16)0xFC98)
-#define		HFA384x_RID_RTSTHRESH2		((u16)0xFC99)
-#define		HFA384x_RID_RTSTHRESH3		((u16)0xFC9A)
-#define		HFA384x_RID_RTSTHRESH4		((u16)0xFC9B)
-#define		HFA384x_RID_RTSTHRESH5		((u16)0xFC9C)
-#define		HFA384x_RID_RTSTHRESH6		((u16)0xFC9D)
-#define		HFA384x_RID_TXRATECNTL0		((u16)0xFC9E)
-#define		HFA384x_RID_TXRATECNTL1		((u16)0xFC9F)
-#define		HFA384x_RID_TXRATECNTL2		((u16)0xFCA0)
-#define		HFA384x_RID_TXRATECNTL3		((u16)0xFCA1)
-#define		HFA384x_RID_TXRATECNTL4		((u16)0xFCA2)
-#define		HFA384x_RID_TXRATECNTL5		((u16)0xFCA3)
-#define		HFA384x_RID_TXRATECNTL6		((u16)0xFCA4)
-
-/*--------------------------------------------------------------------
-Configuration RID Lengths: Network Param, Dynamic Config Entities
-  This is the length of JUST the DATA part of the RID (does not
-  include the len or code fields)
---------------------------------------------------------------------*/
-/* TODO: fill in the rest of these */
-#define		HFA384x_RID_GROUPADDR_LEN	((u16)16 * WLAN_ADDR_LEN)
-#define		HFA384x_RID_CREATEIBSS_LEN	((u16)0)
-#define		HFA384x_RID_FRAGTHRESH_LEN	((u16)0)
-#define		HFA384x_RID_RTSTHRESH_LEN	((u16)0)
-#define		HFA384x_RID_TXRATECNTL_LEN	((u16)4)
-#define		HFA384x_RID_PROMISCMODE_LEN	((u16)2)
-#define		HFA384x_RID_FRAGTHRESH0_LEN	((u16)0)
-#define		HFA384x_RID_FRAGTHRESH1_LEN	((u16)0)
-#define		HFA384x_RID_FRAGTHRESH2_LEN	((u16)0)
-#define		HFA384x_RID_FRAGTHRESH3_LEN	((u16)0)
-#define		HFA384x_RID_FRAGTHRESH4_LEN	((u16)0)
-#define		HFA384x_RID_FRAGTHRESH5_LEN	((u16)0)
-#define		HFA384x_RID_FRAGTHRESH6_LEN	((u16)0)
-#define		HFA384x_RID_RTSTHRESH0_LEN	((u16)0)
-#define		HFA384x_RID_RTSTHRESH1_LEN	((u16)0)
-#define		HFA384x_RID_RTSTHRESH2_LEN	((u16)0)
-#define		HFA384x_RID_RTSTHRESH3_LEN	((u16)0)
-#define		HFA384x_RID_RTSTHRESH4_LEN	((u16)0)
-#define		HFA384x_RID_RTSTHRESH5_LEN	((u16)0)
-#define		HFA384x_RID_RTSTHRESH6_LEN	((u16)0)
-#define		HFA384x_RID_TXRATECNTL0_LEN	((u16)0)
-#define		HFA384x_RID_TXRATECNTL1_LEN	((u16)0)
-#define		HFA384x_RID_TXRATECNTL2_LEN	((u16)0)
-#define		HFA384x_RID_TXRATECNTL3_LEN	((u16)0)
-#define		HFA384x_RID_TXRATECNTL4_LEN	((u16)0)
-#define		HFA384x_RID_TXRATECNTL5_LEN	((u16)0)
-#define		HFA384x_RID_TXRATECNTL6_LEN	((u16)0)
-
-/*--------------------------------------------------------------------
-Configuration RIDs: Behavior Parameters
---------------------------------------------------------------------*/
-#define		HFA384x_RID_ITICKTIME		((u16)0xFCE0)
-
-/*--------------------------------------------------------------------
-Configuration RID Lengths: Behavior Parameters
-  This is the length of JUST the DATA part of the RID (does not
-  include the len or code fields)
---------------------------------------------------------------------*/
-#define		HFA384x_RID_ITICKTIME_LEN	((u16)2)
 
 /*----------------------------------------------------------------------
 Information RIDs: NIC Information
@@ -502,41 +213,17 @@
 #define		HFA384x_RID_NICIDENTITY		((u16)0xFD0B)
 #define		HFA384x_RID_MFISUPRANGE		((u16)0xFD0C)
 #define		HFA384x_RID_CFISUPRANGE		((u16)0xFD0D)
-#define		HFA384x_RID_CHANNELLIST		((u16)0xFD10)
-#define		HFA384x_RID_REGULATORYDOMAINS	((u16)0xFD11)
-#define		HFA384x_RID_TEMPTYPE		((u16)0xFD12)
-#define		HFA384x_RID_CIS			((u16)0xFD13)
 #define		HFA384x_RID_STAIDENTITY		((u16)0xFD20)
 #define		HFA384x_RID_STASUPRANGE		((u16)0xFD21)
 #define		HFA384x_RID_STA_MFIACTRANGES	((u16)0xFD22)
 #define		HFA384x_RID_STA_CFIACTRANGES	((u16)0xFD23)
-#define		HFA384x_RID_BUILDSEQ		((u16)0xFFFE)
-#define		HFA384x_RID_FWID		((u16)0xFFFF)
 
 /*----------------------------------------------------------------------
 Information RID Lengths: NIC Information
   This is the length of JUST the DATA part of the RID (does not
   include the len or code fields)
 --------------------------------------------------------------------*/
-#define		HFA384x_RID_MAXLOADTIME_LEN		((u16)0)
-#define		HFA384x_RID_DOWNLOADBUFFER_LEN		((u16)sizeof(hfa384x_downloadbuffer_t))
-#define		HFA384x_RID_PRIIDENTITY_LEN		((u16)8)
-#define		HFA384x_RID_PRISUPRANGE_LEN		((u16)10)
-#define		HFA384x_RID_CFIACTRANGES_LEN		((u16)10)
 #define		HFA384x_RID_NICSERIALNUMBER_LEN		((u16)12)
-#define		HFA384x_RID_NICIDENTITY_LEN		((u16)8)
-#define		HFA384x_RID_MFISUPRANGE_LEN		((u16)10)
-#define		HFA384x_RID_CFISUPRANGE_LEN		((u16)10)
-#define		HFA384x_RID_CHANNELLIST_LEN		((u16)0)
-#define		HFA384x_RID_REGULATORYDOMAINS_LEN	((u16)12)
-#define		HFA384x_RID_TEMPTYPE_LEN		((u16)0)
-#define		HFA384x_RID_CIS_LEN			((u16)480)
-#define		HFA384x_RID_STAIDENTITY_LEN		((u16)8)
-#define		HFA384x_RID_STASUPRANGE_LEN		((u16)10)
-#define		HFA384x_RID_MFIACTRANGES_LEN		((u16)10)
-#define		HFA384x_RID_CFIACTRANGES2_LEN		((u16)10)
-#define		HFA384x_RID_BUILDSEQ_LEN		((u16)sizeof(hfa384x_BuildSeq_t))
-#define		HFA384x_RID_FWID_LEN			((u16)sizeof(hfa384x_FWID_t))
 
 /*--------------------------------------------------------------------
 Information RIDs:  MAC Information
@@ -544,87 +231,25 @@
 #define		HFA384x_RID_PORTSTATUS		((u16)0xFD40)
 #define		HFA384x_RID_CURRENTSSID		((u16)0xFD41)
 #define		HFA384x_RID_CURRENTBSSID	((u16)0xFD42)
-#define		HFA384x_RID_COMMSQUALITY	((u16)0xFD43)
 #define		HFA384x_RID_CURRENTTXRATE	((u16)0xFD44)
-#define		HFA384x_RID_CURRENTBCNint	((u16)0xFD45)
-#define		HFA384x_RID_CURRENTSCALETHRESH	((u16)0xFD46)
-#define		HFA384x_RID_PROTOCOLRSPTIME	((u16)0xFD47)
 #define		HFA384x_RID_SHORTRETRYLIMIT	((u16)0xFD48)
 #define		HFA384x_RID_LONGRETRYLIMIT	((u16)0xFD49)
 #define		HFA384x_RID_MAXTXLIFETIME	((u16)0xFD4A)
-#define		HFA384x_RID_MAXRXLIFETIME	((u16)0xFD4B)
-#define		HFA384x_RID_CFPOLLABLE		((u16)0xFD4C)
-#define		HFA384x_RID_AUTHALGORITHMS	((u16)0xFD4D)
 #define		HFA384x_RID_PRIVACYOPTIMP	((u16)0xFD4F)
 #define		HFA384x_RID_DBMCOMMSQUALITY	((u16)0xFD51)
-#define		HFA384x_RID_CURRENTTXRATE1	((u16)0xFD80)
-#define		HFA384x_RID_CURRENTTXRATE2	((u16)0xFD81)
-#define		HFA384x_RID_CURRENTTXRATE3	((u16)0xFD82)
-#define		HFA384x_RID_CURRENTTXRATE4	((u16)0xFD83)
-#define		HFA384x_RID_CURRENTTXRATE5	((u16)0xFD84)
-#define		HFA384x_RID_CURRENTTXRATE6	((u16)0xFD85)
-#define		HFA384x_RID_OWNMACADDRESS	((u16)0xFD86)
-// #define	HFA384x_RID_PCFINFO		((u16)0xFD87)
-#define		HFA384x_RID_SCANRESULTS       	((u16)0xFD88) // NEW
-#define		HFA384x_RID_HOSTSCANRESULTS   	((u16)0xFD89) // NEW
-#define		HFA384x_RID_AUTHENTICATIONUSED	((u16)0xFD8A) // NEW
-#define		HFA384x_RID_ASSOCIATEFAILURE  	((u16)0xFD8D) // 1.8.0
 
 /*--------------------------------------------------------------------
 Information RID Lengths:  MAC Information
   This is the length of JUST the DATA part of the RID (does not
   include the len or code fields)
 --------------------------------------------------------------------*/
-#define		HFA384x_RID_PORTSTATUS_LEN		((u16)0)
-#define		HFA384x_RID_CURRENTSSID_LEN		((u16)34)
-#define		HFA384x_RID_CURRENTBSSID_LEN		((u16)WLAN_BSSID_LEN)
-#define		HFA384x_RID_COMMSQUALITY_LEN		((u16)sizeof(hfa384x_commsquality_t))
 #define		HFA384x_RID_DBMCOMMSQUALITY_LEN		((u16)sizeof(hfa384x_dbmcommsquality_t))
-#define		HFA384x_RID_CURRENTTXRATE_LEN		((u16)0)
-#define		HFA384x_RID_CURRENTBCNint_LEN		((u16)0)
-#define		HFA384x_RID_STACURSCALETHRESH_LEN	((u16)12)
-#define		HFA384x_RID_APCURSCALETHRESH_LEN	((u16)6)
-#define		HFA384x_RID_PROTOCOLRSPTIME_LEN		((u16)0)
-#define		HFA384x_RID_SHORTRETRYLIMIT_LEN		((u16)0)
-#define		HFA384x_RID_LONGRETRYLIMIT_LEN		((u16)0)
-#define		HFA384x_RID_MAXTXLIFETIME_LEN		((u16)0)
-#define		HFA384x_RID_MAXRXLIFETIME_LEN		((u16)0)
-#define		HFA384x_RID_CFPOLLABLE_LEN		((u16)0)
-#define		HFA384x_RID_AUTHALGORITHMS_LEN		((u16)4)
-#define		HFA384x_RID_PRIVACYOPTIMP_LEN		((u16)0)
-#define		HFA384x_RID_CURRENTTXRATE1_LEN		((u16)0)
-#define		HFA384x_RID_CURRENTTXRATE2_LEN		((u16)0)
-#define		HFA384x_RID_CURRENTTXRATE3_LEN		((u16)0)
-#define		HFA384x_RID_CURRENTTXRATE4_LEN		((u16)0)
-#define		HFA384x_RID_CURRENTTXRATE5_LEN		((u16)0)
-#define		HFA384x_RID_CURRENTTXRATE6_LEN		((u16)0)
-#define		HFA384x_RID_OWNMACADDRESS_LEN		((u16)6)
-#define		HFA384x_RID_PCFINFO_LEN			((u16)6)
-#define		HFA384x_RID_CNFAPPCFINFO_LEN		((u16)sizeof(hfa384x_PCFInfo_data_t))
-#define		HFA384x_RID_SCANREQUEST_LEN		((u16)sizeof(hfa384x_ScanRequest_data_t))
 #define		HFA384x_RID_JOINREQUEST_LEN		((u16)sizeof(hfa384x_JoinRequest_data_t))
-#define		HFA384x_RID_AUTHENTICATESTA_LEN		((u16)sizeof(hfa384x_authenticateStation_data_t))
-#define		HFA384x_RID_CHANNELINFOREQUEST_LEN	((u16)sizeof(hfa384x_ChannelInfoRequest_data_t))
+
 /*--------------------------------------------------------------------
 Information RIDs:  Modem Information
 --------------------------------------------------------------------*/
-#define		HFA384x_RID_PHYTYPE		((u16)0xFDC0)
 #define		HFA384x_RID_CURRENTCHANNEL	((u16)0xFDC1)
-#define		HFA384x_RID_CURRENTPOWERSTATE	((u16)0xFDC2)
-#define		HFA384x_RID_CCAMODE		((u16)0xFDC3)
-#define		HFA384x_RID_SUPPORTEDDATARATES	((u16)0xFDC6)
-#define		HFA384x_RID_LFOSTATUS           ((u16)0xFDC7) // 1.7.1
-
-/*--------------------------------------------------------------------
-Information RID Lengths:  Modem Information
-  This is the length of JUST the DATA part of the RID (does not
-  include the len or code fields)
---------------------------------------------------------------------*/
-#define		HFA384x_RID_PHYTYPE_LEN			((u16)0)
-#define		HFA384x_RID_CURRENTCHANNEL_LEN		((u16)0)
-#define		HFA384x_RID_CURRENTPOWERSTATE_LEN	((u16)0)
-#define		HFA384x_RID_CCAMODE_LEN			((u16)0)
-#define		HFA384x_RID_SUPPORTEDDATARATES_LEN	((u16)10)
 
 /*--------------------------------------------------------------------
 API ENHANCEMENTS (NOT ALREADY IMPLEMENTED)
@@ -635,57 +260,22 @@
 #define		HFA384x_RID_CNFWEPDEFAULTKEY2	((u16)0xFC26)
 #define		HFA384x_RID_CNFWEPDEFAULTKEY3	((u16)0xFC27)
 #define		HFA384x_RID_CNFWEPFLAGS		((u16)0xFC28)
-#define		HFA384x_RID_CNFWEPKEYMAPTABLE	((u16)0xFC29)
 #define		HFA384x_RID_CNFAUTHENTICATION	((u16)0xFC2A)
-#define		HFA384x_RID_CNFMAXASSOCSTATIONS	((u16)0xFC2B)
-#define		HFA384x_RID_CNFTXCONTROL	((u16)0xFC2C)
 #define		HFA384x_RID_CNFROAMINGMODE	((u16)0xFC2D)
-#define		HFA384x_RID_CNFHOSTAUTHASSOC	((u16)0xFC2E)
-#define		HFA384x_RID_CNFRCVCRCERROR	((u16)0xFC30)
-// #define		HFA384x_RID_CNFMMLIFE		((u16)0xFC31)
-#define		HFA384x_RID_CNFALTRETRYCNT	((u16)0xFC32)
 #define		HFA384x_RID_CNFAPBCNint		((u16)0xFC33)
-#define		HFA384x_RID_CNFAPPCFINFO	((u16)0xFC34)
-#define		HFA384x_RID_CNFSTAPCFINFO	((u16)0xFC35)
-#define		HFA384x_RID_CNFPRIORITYQUSAGE	((u16)0xFC37)
-#define		HFA384x_RID_CNFTIMCTRL		((u16)0xFC40)
-#define		HFA384x_RID_CNFTHIRTY2TALLY	((u16)0xFC42)
-#define		HFA384x_RID_CNFENHSECURITY	((u16)0xFC43)
-#define		HFA384x_RID_CNFDBMADJUST  	((u16)0xFC46) // NEW
-#define		HFA384x_RID_CNFWPADATA       	((u16)0xFC48) // 1.7.0
-#define		HFA384x_RID_CNFPROPOGATIONDELAY	((u16)0xFC49) // 1.7.6
-#define		HFA384x_RID_CNFSHORTPREAMBLE	((u16)0xFCB0)
-#define		HFA384x_RID_CNFEXCLONGPREAMBLE	((u16)0xFCB1)
-#define		HFA384x_RID_CNFAUTHRSPTIMEOUT	((u16)0xFCB2)
+#define		HFA384x_RID_CNFDBMADJUST  	((u16)0xFC46)
+#define		HFA384x_RID_CNFWPADATA       	((u16)0xFC48)
 #define		HFA384x_RID_CNFBASICRATES	((u16)0xFCB3)
 #define		HFA384x_RID_CNFSUPPRATES	((u16)0xFCB4)
-#define		HFA384x_RID_CNFFALLBACKCTRL	((u16)0xFCB5) // NEW
-#define		HFA384x_RID_WEPKEYSTATUS   	((u16)0xFCB6) // NEW
-#define		HFA384x_RID_WEPKEYMAPINDEX 	((u16)0xFCB7) // NEW
-#define		HFA384x_RID_BROADCASTKEYID 	((u16)0xFCB8) // NEW
-#define		HFA384x_RID_ENTSECFLAGEYID 	((u16)0xFCB9) // NEW
-#define		HFA384x_RID_CNFPASSIVESCANCTRL	((u16)0xFCBA) // NEW STA
-#define		HFA384x_RID_CNFWPAHANDLING	((u16)0xFCBB) // 1.7.0
-#define		HFA384x_RID_MDCCONTROL        	((u16)0xFCBC) // 1.7.0/1.4.0
-#define		HFA384x_RID_MDCCOUNTRY        	((u16)0xFCBD) // 1.7.0/1.4.0
-#define		HFA384x_RID_TXPOWERMAX        	((u16)0xFCBE) // 1.7.0/1.4.0
-#define		HFA384x_RID_CNFLFOENBLED      	((u16)0xFCBF) // 1.6.3
-#define         HFA384x_RID_CAPINFO             ((u16)0xFCC0) // 1.7.0/1.3.7
-#define         HFA384x_RID_LISTENintERVAL      ((u16)0xFCC1) // 1.7.0/1.3.7
-#define         HFA384x_RID_DIVERSITYENABLED    ((u16)0xFCC2) // 1.7.0/1.3.7
-#define         HFA384x_RID_LED_CONTROL         ((u16)0xFCC4) // 1.7.6
-#define         HFA384x_RID_HFO_DELAY           ((u16)0xFCC5) // 1.7.6
-#define         HFA384x_RID_DISSALOWEDBSSID     ((u16)0xFCC6) // 1.8.0
-#define		HFA384x_RID_SCANREQUEST		((u16)0xFCE1)
+#define		HFA384x_RID_CNFPASSIVESCANCTRL	((u16)0xFCBA)
+#define		HFA384x_RID_TXPOWERMAX        	((u16)0xFCBE)
 #define		HFA384x_RID_JOINREQUEST		((u16)0xFCE2)
 #define		HFA384x_RID_AUTHENTICATESTA	((u16)0xFCE3)
-#define		HFA384x_RID_CHANNELINFOREQUEST	((u16)0xFCE4)
-#define		HFA384x_RID_HOSTSCAN          	((u16)0xFCE5) // NEW STA
-#define		HFA384x_RID_ASSOCIATESTA	((u16)0xFCE6)
+#define		HFA384x_RID_HOSTSCAN          	((u16)0xFCE5)
 
 #define		HFA384x_RID_CNFWEPDEFAULTKEY_LEN	((u16)6)
 #define		HFA384x_RID_CNFWEP128DEFAULTKEY_LEN	((u16)14)
-#define		HFA384x_RID_CNFPRIOQUSAGE_LEN		((u16)4)
+
 /*--------------------------------------------------------------------
 PD Record codes
 --------------------------------------------------------------------*/
@@ -697,22 +287,11 @@
 #define HFA384x_PDR_MFISUPRANGE		((u16)0x0006)
 #define HFA384x_PDR_CFISUPRANGE		((u16)0x0007)
 #define HFA384x_PDR_NICID		((u16)0x0008)
-//#define HFA384x_PDR_REFDAC_MEASUREMENTS	((u16)0x0010)
-//#define HFA384x_PDR_VGDAC_MEASUREMENTS	((u16)0x0020)
-//#define HFA384x_PDR_LEVEL_COMP_MEASUREMENTS	((u16)0x0030)
-//#define HFA384x_PDR_MODEM_TRIMDAC_MEASUREMENTS	((u16)0x0040)
-//#define HFA384x_PDR_COREGA_HACK		((u16)0x00ff)
 #define HFA384x_PDR_MAC_ADDRESS		((u16)0x0101)
-//#define HFA384x_PDR_MKK_CALLNAME	((u16)0x0102)
 #define HFA384x_PDR_REGDOMAIN		((u16)0x0103)
 #define HFA384x_PDR_ALLOWED_CHANNEL	((u16)0x0104)
 #define HFA384x_PDR_DEFAULT_CHANNEL	((u16)0x0105)
-//#define HFA384x_PDR_PRIVACY_OPTION	((u16)0x0106)
 #define HFA384x_PDR_TEMPTYPE		((u16)0x0107)
-//#define HFA384x_PDR_REFDAC_SETUP	((u16)0x0110)
-//#define HFA384x_PDR_VGDAC_SETUP		((u16)0x0120)
-//#define HFA384x_PDR_LEVEL_COMP_SETUP	((u16)0x0130)
-//#define HFA384x_PDR_TRIMDAC_SETUP	((u16)0x0140)
 #define HFA384x_PDR_IFR_SETTING		((u16)0x0200)
 #define HFA384x_PDR_RFR_SETTING		((u16)0x0201)
 #define HFA384x_PDR_HFA3861_BASELINE	((u16)0x0202)
@@ -729,7 +308,6 @@
 #define HFA384x_PDR_PCI_PMCONF		((u16)0x0404)
 #define HFA384x_PDR_RFENRGY		((u16)0x0406)
 #define HFA384x_PDR_USB_POWER_TYPE      ((u16)0x0407)
-//#define HFA384x_PDR_UNKNOWN408		((u16)0x0408)
 #define HFA384x_PDR_USB_MAX_POWER	((u16)0x0409)
 #define HFA384x_PDR_USB_MANUFACTURER	((u16)0x0410)
 #define HFA384x_PDR_USB_PRODUCT  	((u16)0x0411)
@@ -741,831 +319,122 @@
 #define HFA384x_PDR_HFA3861_MANF_TESTI	((u16)0x0901)
 #define HFA384x_PDR_END_OF_PDA		((u16)0x0000)
 
-
-/*=============================================================*/
-/*------ Macros -----------------------------------------------*/
-
-/*--- Register ID macros ------------------------*/
-
-#define		HFA384x_CMD		HFA384x_CMD_OFF
-#define		HFA384x_PARAM0		HFA384x_PARAM0_OFF
-#define		HFA384x_PARAM1		HFA384x_PARAM1_OFF
-#define		HFA384x_PARAM2		HFA384x_PARAM2_OFF
-#define		HFA384x_STATUS		HFA384x_STATUS_OFF
-#define		HFA384x_RESP0		HFA384x_RESP0_OFF
-#define		HFA384x_RESP1		HFA384x_RESP1_OFF
-#define		HFA384x_RESP2		HFA384x_RESP2_OFF
-#define		HFA384x_INFOFID		HFA384x_INFOFID_OFF
-#define		HFA384x_RXFID		HFA384x_RXFID_OFF
-#define		HFA384x_ALLOCFID	HFA384x_ALLOCFID_OFF
-#define		HFA384x_TXCOMPLFID	HFA384x_TXCOMPLFID_OFF
-#define		HFA384x_SELECT0		HFA384x_SELECT0_OFF
-#define		HFA384x_OFFSET0		HFA384x_OFFSET0_OFF
-#define		HFA384x_DATA0		HFA384x_DATA0_OFF
-#define		HFA384x_SELECT1		HFA384x_SELECT1_OFF
-#define		HFA384x_OFFSET1		HFA384x_OFFSET1_OFF
-#define		HFA384x_DATA1		HFA384x_DATA1_OFF
-#define		HFA384x_EVSTAT		HFA384x_EVSTAT_OFF
-#define		HFA384x_intEN		HFA384x_INTEN_OFF
-#define		HFA384x_EVACK		HFA384x_EVACK_OFF
-#define		HFA384x_CONTROL		HFA384x_CONTROL_OFF
-#define		HFA384x_SWSUPPORT0	HFA384x_SWSUPPORT0_OFF
-#define		HFA384x_SWSUPPORT1	HFA384x_SWSUPPORT1_OFF
-#define		HFA384x_SWSUPPORT2	HFA384x_SWSUPPORT2_OFF
-#define		HFA384x_AUXPAGE		HFA384x_AUXPAGE_OFF
-#define		HFA384x_AUXOFFSET	HFA384x_AUXOFFSET_OFF
-#define		HFA384x_AUXDATA		HFA384x_AUXDATA_OFF
-#define		HFA384x_PCICOR		HFA384x_PCICOR_OFF
-#define		HFA384x_PCIHCR		HFA384x_PCIHCR_OFF
-
-
 /*--- Register Test/Get/Set Field macros ------------------------*/
 
-#define		HFA384x_CMD_ISBUSY(value)		((u16)(((u16)value) & HFA384x_CMD_BUSY))
-#define		HFA384x_CMD_AINFO_GET(value)		((u16)(((u16)(value) & HFA384x_CMD_AINFO) >> 8))
 #define		HFA384x_CMD_AINFO_SET(value)		((u16)((u16)(value) << 8))
-#define		HFA384x_CMD_MACPORT_GET(value)		((u16)(HFA384x_CMD_AINFO_GET((u16)(value) & HFA384x_CMD_MACPORT)))
 #define		HFA384x_CMD_MACPORT_SET(value)		((u16)HFA384x_CMD_AINFO_SET(value))
-#define		HFA384x_CMD_ISRECL(value)		((u16)(HFA384x_CMD_AINFO_GET((u16)(value) & HFA384x_CMD_RECL)))
-#define		HFA384x_CMD_RECL_SET(value)		((u16)HFA384x_CMD_AINFO_SET(value))
-#define		HFA384x_CMD_QOS_GET(value)		((u16)((((u16)(value))&((u16)0x3000)) >> 12))
-#define		HFA384x_CMD_QOS_SET(value)		((u16)((((u16)(value)) << 12) & 0x3000))
-#define		HFA384x_CMD_ISWRITE(value)		((u16)(HFA384x_CMD_AINFO_GET((u16)(value) & HFA384x_CMD_WRITE)))
-#define		HFA384x_CMD_WRITE_SET(value)		((u16)HFA384x_CMD_AINFO_SET((u16)value))
-#define		HFA384x_CMD_PROGMODE_GET(value)		((u16)(HFA384x_CMD_AINFO_GET((u16)(value) & HFA384x_CMD_PROGMODE)))
 #define		HFA384x_CMD_PROGMODE_SET(value)		((u16)HFA384x_CMD_AINFO_SET((u16)value))
-#define		HFA384x_CMD_CMDCODE_GET(value)		((u16)(((u16)(value)) & HFA384x_CMD_CMDCODE))
 #define		HFA384x_CMD_CMDCODE_SET(value)		((u16)(value))
 
-#define		HFA384x_STATUS_RESULT_GET(value)	((u16)((((u16)(value)) & HFA384x_STATUS_RESULT) >> 8))
 #define		HFA384x_STATUS_RESULT_SET(value)	(((u16)(value)) << 8)
-#define		HFA384x_STATUS_CMDCODE_GET(value)	(((u16)(value)) & HFA384x_STATUS_CMDCODE)
-#define		HFA384x_STATUS_CMDCODE_SET(value)	((u16)(value))
-
-#define		HFA384x_OFFSET_ISBUSY(value)		((u16)(((u16)(value)) & HFA384x_OFFSET_BUSY))
-#define		HFA384x_OFFSET_ISERR(value)		((u16)(((u16)(value)) & HFA384x_OFFSET_ERR))
-#define		HFA384x_OFFSET_DATAOFF_GET(value)	((u16)(((u16)(value)) & HFA384x_OFFSET_DATAOFF))
-#define		HFA384x_OFFSET_DATAOFF_SET(value)	((u16)(value))
-
-#define		HFA384x_EVSTAT_ISTICK(value)		((u16)(((u16)(value)) & HFA384x_EVSTAT_TICK))
-#define		HFA384x_EVSTAT_ISWTERR(value)		((u16)(((u16)(value)) & HFA384x_EVSTAT_WTERR))
-#define		HFA384x_EVSTAT_ISINFDROP(value)		((u16)(((u16)(value)) & HFA384x_EVSTAT_INFDROP))
-#define		HFA384x_EVSTAT_ISINFO(value)		((u16)(((u16)(value)) & HFA384x_EVSTAT_INFO))
-#define		HFA384x_EVSTAT_ISDTIM(value)		((u16)(((u16)(value)) & HFA384x_EVSTAT_DTIM))
-#define		HFA384x_EVSTAT_ISCMD(value)		((u16)(((u16)(value)) & HFA384x_EVSTAT_CMD))
-#define		HFA384x_EVSTAT_ISALLOC(value)		((u16)(((u16)(value)) & HFA384x_EVSTAT_ALLOC))
-#define		HFA384x_EVSTAT_ISTXEXC(value)		((u16)(((u16)(value)) & HFA384x_EVSTAT_TXEXC))
-#define		HFA384x_EVSTAT_ISTX(value)		((u16)(((u16)(value)) & HFA384x_EVSTAT_TX))
-#define		HFA384x_EVSTAT_ISRX(value)		((u16)(((u16)(value)) & HFA384x_EVSTAT_RX))
-
-#define		HFA384x_EVSTAT_ISBAP_OP(value)		((u16)(((u16)(value)) & HFA384x_int_BAP_OP))
-
-#define		HFA384x_intEN_ISTICK(value)		((u16)(((u16)(value)) & HFA384x_INTEN_TICK))
-#define		HFA384x_intEN_TICK_SET(value)		((u16)(((u16)(value)) << 15))
-#define		HFA384x_intEN_ISWTERR(value)		((u16)(((u16)(value)) & HFA384x_INTEN_WTERR))
-#define		HFA384x_intEN_WTERR_SET(value)		((u16)(((u16)(value)) << 14))
-#define		HFA384x_intEN_ISINFDROP(value)		((u16)(((u16)(value)) & HFA384x_INTEN_INFDROP))
-#define		HFA384x_intEN_INFDROP_SET(value)	((u16)(((u16)(value)) << 13))
-#define		HFA384x_intEN_ISINFO(value)		((u16)(((u16)(value)) & HFA384x_INTEN_INFO))
-#define		HFA384x_intEN_INFO_SET(value)		((u16)(((u16)(value)) << 7))
-#define		HFA384x_intEN_ISDTIM(value)		((u16)(((u16)(value)) & HFA384x_INTEN_DTIM))
-#define		HFA384x_intEN_DTIM_SET(value)		((u16)(((u16)(value)) << 5))
-#define		HFA384x_intEN_ISCMD(value)		((u16)(((u16)(value)) & HFA384x_INTEN_CMD))
-#define		HFA384x_intEN_CMD_SET(value)		((u16)(((u16)(value)) << 4))
-#define		HFA384x_intEN_ISALLOC(value)		((u16)(((u16)(value)) & HFA384x_INTEN_ALLOC))
-#define		HFA384x_intEN_ALLOC_SET(value)		((u16)(((u16)(value)) << 3))
-#define		HFA384x_intEN_ISTXEXC(value)		((u16)(((u16)(value)) & HFA384x_INTEN_TXEXC))
-#define		HFA384x_intEN_TXEXC_SET(value)		((u16)(((u16)(value)) << 2))
-#define		HFA384x_intEN_ISTX(value)		((u16)(((u16)(value)) & HFA384x_INTEN_TX))
-#define		HFA384x_intEN_TX_SET(value)		((u16)(((u16)(value)) << 1))
-#define		HFA384x_intEN_ISRX(value)		((u16)(((u16)(value)) & HFA384x_INTEN_RX))
-#define		HFA384x_intEN_RX_SET(value)		((u16)(((u16)(value)) << 0))
-
-#define		HFA384x_EVACK_ISTICK(value)		((u16)(((u16)(value)) & HFA384x_EVACK_TICK))
-#define		HFA384x_EVACK_TICK_SET(value)		((u16)(((u16)(value)) << 15))
-#define		HFA384x_EVACK_ISWTERR(value)		((u16)(((u16)(value)) & HFA384x_EVACK_WTERR))
-#define		HFA384x_EVACK_WTERR_SET(value)		((u16)(((u16)(value)) << 14))
-#define		HFA384x_EVACK_ISINFDROP(value)		((u16)(((u16)(value)) & HFA384x_EVACK_INFDROP))
-#define		HFA384x_EVACK_INFDROP_SET(value)	((u16)(((u16)(value)) << 13))
-#define		HFA384x_EVACK_ISINFO(value)		((u16)(((u16)(value)) & HFA384x_EVACK_INFO))
-#define		HFA384x_EVACK_INFO_SET(value)		((u16)(((u16)(value)) << 7))
-#define		HFA384x_EVACK_ISDTIM(value)		((u16)(((u16)(value)) & HFA384x_EVACK_DTIM))
-#define		HFA384x_EVACK_DTIM_SET(value)		((u16)(((u16)(value)) << 5))
-#define		HFA384x_EVACK_ISCMD(value)		((u16)(((u16)(value)) & HFA384x_EVACK_CMD))
-#define		HFA384x_EVACK_CMD_SET(value)		((u16)(((u16)(value)) << 4))
-#define		HFA384x_EVACK_ISALLOC(value)		((u16)(((u16)(value)) & HFA384x_EVACK_ALLOC))
-#define		HFA384x_EVACK_ALLOC_SET(value)		((u16)(((u16)(value)) << 3))
-#define		HFA384x_EVACK_ISTXEXC(value)		((u16)(((u16)(value)) & HFA384x_EVACK_TXEXC))
-#define		HFA384x_EVACK_TXEXC_SET(value)		((u16)(((u16)(value)) << 2))
-#define		HFA384x_EVACK_ISTX(value)		((u16)(((u16)(value)) & HFA384x_EVACK_TX))
-#define		HFA384x_EVACK_TX_SET(value)		((u16)(((u16)(value)) << 1))
-#define		HFA384x_EVACK_ISRX(value)		((u16)(((u16)(value)) & HFA384x_EVACK_RX))
-#define		HFA384x_EVACK_RX_SET(value)		((u16)(((u16)(value)) << 0))
-
-#define		HFA384x_CONTROL_AUXEN_SET(value)	((u16)(((u16)(value)) << 14))
-#define		HFA384x_CONTROL_AUXEN_GET(value)	((u16)(((u16)(value)) >> 14))
-
-/* Byte Order */
-#ifdef __KERNEL__
-#define hfa384x2host_16(n)	(__le16_to_cpu((u16)(n)))
-#define hfa384x2host_32(n)	(__le32_to_cpu((u32)(n)))
-#define host2hfa384x_16(n)	(__cpu_to_le16((u16)(n)))
-#define host2hfa384x_32(n)	(__cpu_to_le32((u32)(n)))
-#endif
 
 /* Host Maintained State Info */
 #define HFA384x_STATE_PREINIT	0
 #define HFA384x_STATE_INIT	1
 #define HFA384x_STATE_RUNNING	2
 
-/*=============================================================*/
-/*------ Types and their related constants --------------------*/
-
-#define HFA384x_HOSTAUTHASSOC_HOSTAUTH   BIT0
-#define HFA384x_HOSTAUTHASSOC_HOSTASSOC  BIT1
-
-#define HFA384x_WHAHANDLING_DISABLED     0
-#define HFA384x_WHAHANDLING_PASSTHROUGH  BIT1
-
 /*-------------------------------------------------------------*/
 /* Commonly used basic types */
-typedef struct hfa384x_bytestr
-{
-	u16	len;
-	u8	data[0];
-} __WLAN_ATTRIB_PACK__ hfa384x_bytestr_t;
+typedef struct hfa384x_bytestr {
+	u16 len;
+	u8 data[0];
+} __attribute__ ((packed)) hfa384x_bytestr_t;
 
-typedef struct hfa384x_bytestr32
-{
-	u16	len;
-	u8	data[32];
-} __WLAN_ATTRIB_PACK__ hfa384x_bytestr32_t;
+typedef struct hfa384x_bytestr32 {
+	u16 len;
+	u8 data[32];
+} __attribute__ ((packed)) hfa384x_bytestr32_t;
 
 /*--------------------------------------------------------------------
 Configuration Record Structures:
 	Network Parameters, Static Configuration Entities
 --------------------------------------------------------------------*/
-/* Prototype structure: all configuration record structures start with
-these members */
-
-typedef struct hfa384x_record
-{
-	u16	reclen;
-	u16	rid;
-} __WLAN_ATTRIB_PACK__ hfa384x_rec_t;
-
-typedef struct hfa384x_record16
-{
-	u16	reclen;
-	u16	rid;
-	u16	val;
-} __WLAN_ATTRIB_PACK__ hfa384x_rec16_t;
-
-typedef struct hfa384x_record32
-{
-	u16	reclen;
-	u16	rid;
-	u32	val;
-} __WLAN_ATTRIB_PACK__ hfa384x_rec32;
 
 /*-- Hardware/Firmware Component Information ----------*/
-typedef struct hfa384x_compident
-{
-	u16	id;
-	u16	variant;
-	u16	major;
-	u16	minor;
-} __WLAN_ATTRIB_PACK__ hfa384x_compident_t;
+typedef struct hfa384x_compident {
+	u16 id;
+	u16 variant;
+	u16 major;
+	u16 minor;
+} __attribute__ ((packed)) hfa384x_compident_t;
 
-typedef struct hfa384x_caplevel
-{
-	u16	role;
-	u16	id;
-	u16	variant;
-	u16	bottom;
-	u16	top;
-} __WLAN_ATTRIB_PACK__ hfa384x_caplevel_t;
-
-/*-- Configuration Record: cnfPortType --*/
-typedef struct hfa384x_cnfPortType
-{
-	u16	cnfPortType;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfPortType_t;
-
-/*-- Configuration Record: cnfOwnMACAddress --*/
-typedef struct hfa384x_cnfOwnMACAddress
-{
-	u8	cnfOwnMACAddress[6];
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnMACAddress_t;
-
-/*-- Configuration Record: cnfDesiredSSID --*/
-typedef struct hfa384x_cnfDesiredSSID
-{
-	u8	cnfDesiredSSID[34];
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfDesiredSSID_t;
-
-/*-- Configuration Record: cnfOwnChannel --*/
-typedef struct hfa384x_cnfOwnChannel
-{
-	u16	cnfOwnChannel;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnChannel_t;
-
-/*-- Configuration Record: cnfOwnSSID --*/
-typedef struct hfa384x_cnfOwnSSID
-{
-	u8	cnfOwnSSID[34];
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnSSID_t;
-
-/*-- Configuration Record: cnfOwnATIMWindow --*/
-typedef struct hfa384x_cnfOwnATIMWindow
-{
-	u16	cnfOwnATIMWindow;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnATIMWindow_t;
-
-/*-- Configuration Record: cnfSystemScale --*/
-typedef struct hfa384x_cnfSystemScale
-{
-	u16	cnfSystemScale;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfSystemScale_t;
-
-/*-- Configuration Record: cnfMaxDataLength --*/
-typedef struct hfa384x_cnfMaxDataLength
-{
-	u16	cnfMaxDataLength;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfMaxDataLength_t;
-
-/*-- Configuration Record: cnfWDSAddress --*/
-typedef struct hfa384x_cnfWDSAddress
-{
-	u8	cnfWDSAddress[6];
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfWDSAddress_t;
-
-/*-- Configuration Record: cnfPMEnabled --*/
-typedef struct hfa384x_cnfPMEnabled
-{
-	u16	cnfPMEnabled;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfPMEnabled_t;
-
-/*-- Configuration Record: cnfPMEPS --*/
-typedef struct hfa384x_cnfPMEPS
-{
-	u16	cnfPMEPS;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfPMEPS_t;
-
-/*-- Configuration Record: cnfMulticastReceive --*/
-typedef struct hfa384x_cnfMulticastReceive
-{
-	u16	cnfMulticastReceive;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfMulticastReceive_t;
+typedef struct hfa384x_caplevel {
+	u16 role;
+	u16 id;
+	u16 variant;
+	u16 bottom;
+	u16 top;
+} __attribute__ ((packed)) hfa384x_caplevel_t;
 
 /*-- Configuration Record: cnfAuthentication --*/
 #define HFA384x_CNFAUTHENTICATION_OPENSYSTEM	0x0001
 #define HFA384x_CNFAUTHENTICATION_SHAREDKEY	0x0002
 #define HFA384x_CNFAUTHENTICATION_LEAP     	0x0004
 
-/*-- Configuration Record: cnfMaxSleepDuration --*/
-typedef struct hfa384x_cnfMaxSleepDuration
-{
-	u16	cnfMaxSleepDuration;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfMaxSleepDuration_t;
-
-/*-- Configuration Record: cnfPMHoldoverDuration --*/
-typedef struct hfa384x_cnfPMHoldoverDuration
-{
-	u16	cnfPMHoldoverDuration;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfPMHoldoverDuration_t;
-
-/*-- Configuration Record: cnfOwnName --*/
-typedef struct hfa384x_cnfOwnName
-{
-	u8	cnfOwnName[34];
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnName_t;
-
-/*-- Configuration Record: cnfOwnDTIMPeriod --*/
-typedef struct hfa384x_cnfOwnDTIMPeriod
-{
-	u16	cnfOwnDTIMPeriod;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnDTIMPeriod_t;
-
-/*-- Configuration Record: cnfWDSAddress --*/
-typedef struct hfa384x_cnfWDSAddressN
-{
-	u8	cnfWDSAddress[6];
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfWDSAddressN_t;
-
-/*-- Configuration Record: cnfMulticastPMBuffering --*/
-typedef struct hfa384x_cnfMulticastPMBuffering
-{
-	u16	cnfMulticastPMBuffering;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfMulticastPMBuffering_t;
-
 /*--------------------------------------------------------------------
 Configuration Record Structures:
 	Network Parameters, Dynamic Configuration Entities
 --------------------------------------------------------------------*/
 
-/*-- Configuration Record: GroupAddresses --*/
-typedef struct hfa384x_GroupAddresses
-{
-	u8	MACAddress[16][6];
-} __WLAN_ATTRIB_PACK__ hfa384x_GroupAddresses_t;
-
-/*-- Configuration Record: CreateIBSS --*/
-typedef struct hfa384x_CreateIBSS
-{
-	u16	CreateIBSS;
-} __WLAN_ATTRIB_PACK__ hfa384x_CreateIBSS_t;
-
 #define HFA384x_CREATEIBSS_JOINCREATEIBSS          0
-#define HFA384x_CREATEIBSS_JOINESS_JOINCREATEIBSS  1
-#define HFA384x_CREATEIBSS_JOINIBSS                2
-#define HFA384x_CREATEIBSS_JOINESS_JOINIBSS        3
-
-/*-- Configuration Record: FragmentationThreshold --*/
-typedef struct hfa384x_FragmentationThreshold
-{
-	u16	FragmentationThreshold;
-} __WLAN_ATTRIB_PACK__ hfa384x_FragmentationThreshold_t;
-
-/*-- Configuration Record: RTSThreshold --*/
-typedef struct hfa384x_RTSThreshold
-{
-	u16	RTSThreshold;
-} __WLAN_ATTRIB_PACK__ hfa384x_RTSThreshold_t;
-
-/*-- Configuration Record: TxRateControl --*/
-typedef struct hfa384x_TxRateControl
-{
-	u16	TxRateControl;
-} __WLAN_ATTRIB_PACK__ hfa384x_TxRateControl_t;
-
-/*-- Configuration Record: PromiscuousMode --*/
-typedef struct hfa384x_PromiscuousMode
-{
-	u16	PromiscuousMode;
-} __WLAN_ATTRIB_PACK__ hfa384x_PromiscuousMode_t;
-
-/*-- Configuration Record: ScanRequest (data portion only) --*/
-typedef struct hfa384x_ScanRequest_data
-{
-	u16	channelList;
-	u16	txRate;
-} __WLAN_ATTRIB_PACK__ hfa384x_ScanRequest_data_t;
 
 /*-- Configuration Record: HostScanRequest (data portion only) --*/
-typedef struct hfa384x_HostScanRequest_data
-{
-	u16	channelList;
-	u16	txRate;
+typedef struct hfa384x_HostScanRequest_data {
+	u16 channelList;
+	u16 txRate;
 	hfa384x_bytestr32_t ssid;
-} __WLAN_ATTRIB_PACK__ hfa384x_HostScanRequest_data_t;
+} __attribute__ ((packed)) hfa384x_HostScanRequest_data_t;
 
 /*-- Configuration Record: JoinRequest (data portion only) --*/
-typedef struct hfa384x_JoinRequest_data
-{
-	u8	bssid[WLAN_BSSID_LEN];
-	u16	channel;
-} __WLAN_ATTRIB_PACK__ hfa384x_JoinRequest_data_t;
+typedef struct hfa384x_JoinRequest_data {
+	u8 bssid[WLAN_BSSID_LEN];
+	u16 channel;
+} __attribute__ ((packed)) hfa384x_JoinRequest_data_t;
 
 /*-- Configuration Record: authenticateStation (data portion only) --*/
-typedef struct hfa384x_authenticateStation_data
-{
-	u8	address[WLAN_ADDR_LEN];
-	u16	status;
-	u16	algorithm;
-} __WLAN_ATTRIB_PACK__ hfa384x_authenticateStation_data_t;
-
-/*-- Configuration Record: associateStation (data portion only) --*/
-typedef struct hfa384x_associateStation_data
-{
-	u8	address[WLAN_ADDR_LEN];
-	u16	status;
-	u16	type;
-} __WLAN_ATTRIB_PACK__ hfa384x_associateStation_data_t;
-
-/*-- Configuration Record: ChannelInfoRequest (data portion only) --*/
-typedef struct hfa384x_ChannelInfoRequest_data
-{
-	u16	channelList;
-	u16	channelDwellTime;
-} __WLAN_ATTRIB_PACK__ hfa384x_ChannelInfoRequest_data_t;
-
-/*-- Configuration Record: WEPKeyMapping (data portion only) --*/
-typedef struct hfa384x_WEPKeyMapping
-{
-	u8	address[WLAN_ADDR_LEN];
-	u16	key_index;
-	u8 	key[16];
-	u8 	mic_transmit_key[4];
-	u8 	mic_receive_key[4];
-} __WLAN_ATTRIB_PACK__ hfa384x_WEPKeyMapping_t;
+typedef struct hfa384x_authenticateStation_data {
+	u8 address[ETH_ALEN];
+	u16 status;
+	u16 algorithm;
+} __attribute__ ((packed)) hfa384x_authenticateStation_data_t;
 
 /*-- Configuration Record: WPAData       (data portion only) --*/
-typedef struct hfa384x_WPAData
-{
-	u16	datalen;
-        u8 	data[0]; // max 80
-} __WLAN_ATTRIB_PACK__ hfa384x_WPAData_t;
-
-/*--------------------------------------------------------------------
-Configuration Record Structures: Behavior Parameters
---------------------------------------------------------------------*/
-
-/*-- Configuration Record: TickTime --*/
-typedef struct hfa384x_TickTime
-{
-	u16	TickTime;
-} __WLAN_ATTRIB_PACK__ hfa384x_TickTime_t;
+typedef struct hfa384x_WPAData {
+	u16 datalen;
+	u8 data[0];		// max 80
+} __attribute__ ((packed)) hfa384x_WPAData_t;
 
 /*--------------------------------------------------------------------
 Information Record Structures: NIC Information
 --------------------------------------------------------------------*/
 
-/*-- Information Record: MaxLoadTime --*/
-typedef struct hfa384x_MaxLoadTime
-{
-	u16	MaxLoadTime;
-} __WLAN_ATTRIB_PACK__ hfa384x_MaxLoadTime_t;
-
 /*-- Information Record: DownLoadBuffer --*/
 /* NOTE: The page and offset are in AUX format */
-typedef struct hfa384x_downloadbuffer
-{
-	u16	page;
-	u16	offset;
-	u16	len;
-} __WLAN_ATTRIB_PACK__ hfa384x_downloadbuffer_t;
-
-/*-- Information Record: PRIIdentity --*/
-typedef struct hfa384x_PRIIdentity
-{
-	u16	PRICompID;
-	u16	PRIVariant;
-	u16	PRIMajorVersion;
-	u16	PRIMinorVersion;
-} __WLAN_ATTRIB_PACK__ hfa384x_PRIIdentity_t;
-
-/*-- Information Record: PRISupRange --*/
-typedef struct hfa384x_PRISupRange
-{
-	u16	PRIRole;
-	u16	PRIID;
-	u16	PRIVariant;
-	u16	PRIBottom;
-	u16	PRITop;
-} __WLAN_ATTRIB_PACK__ hfa384x_PRISupRange_t;
-
-/*-- Information Record: CFIActRanges --*/
-typedef struct hfa384x_CFIActRanges
-{
-	u16	CFIRole;
-	u16	CFIID;
-	u16	CFIVariant;
-	u16	CFIBottom;
-	u16	CFITop;
-} __WLAN_ATTRIB_PACK__ hfa384x_CFIActRanges_t;
-
-/*-- Information Record: NICSerialNumber --*/
-typedef struct hfa384x_NICSerialNumber
-{
-	u8	NICSerialNumber[12];
-} __WLAN_ATTRIB_PACK__ hfa384x_NICSerialNumber_t;
-
-/*-- Information Record: NICIdentity --*/
-typedef struct hfa384x_NICIdentity
-{
-	u16	NICCompID;
-	u16	NICVariant;
-	u16	NICMajorVersion;
-	u16	NICMinorVersion;
-} __WLAN_ATTRIB_PACK__ hfa384x_NICIdentity_t;
-
-/*-- Information Record: MFISupRange --*/
-typedef struct hfa384x_MFISupRange
-{
-	u16	MFIRole;
-	u16	MFIID;
-	u16	MFIVariant;
-	u16	MFIBottom;
-	u16	MFITop;
-} __WLAN_ATTRIB_PACK__ hfa384x_MFISupRange_t;
-
-/*-- Information Record: CFISupRange --*/
-typedef struct hfa384x_CFISupRange
-{
-	u16	CFIRole;
-	u16	CFIID;
-	u16	CFIVariant;
-	u16	CFIBottom;
-	u16	CFITop;
-} __WLAN_ATTRIB_PACK__ hfa384x_CFISupRange_t;
-
-/*-- Information Record: BUILDSEQ:BuildSeq --*/
-typedef struct hfa384x_BuildSeq {
-	u16	primary;
-	u16	secondary;
-} __WLAN_ATTRIB_PACK__ hfa384x_BuildSeq_t;
-
-/*-- Information Record: FWID --*/
-#define HFA384x_FWID_LEN	14
-typedef struct hfa384x_FWID {
-	u8	primary[HFA384x_FWID_LEN];
-	u8	secondary[HFA384x_FWID_LEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_FWID_t;
-
-/*-- Information Record: ChannelList --*/
-typedef struct hfa384x_ChannelList
-{
-	u16	ChannelList;
-} __WLAN_ATTRIB_PACK__ hfa384x_ChannelList_t;
-
-/*-- Information Record: RegulatoryDomains --*/
-typedef struct hfa384x_RegulatoryDomains
-{
-	u8	RegulatoryDomains[12];
-} __WLAN_ATTRIB_PACK__ hfa384x_RegulatoryDomains_t;
-
-/*-- Information Record: TempType --*/
-typedef struct hfa384x_TempType
-{
-	u16	TempType;
-} __WLAN_ATTRIB_PACK__ hfa384x_TempType_t;
-
-/*-- Information Record: CIS --*/
-typedef struct hfa384x_CIS
-{
-	u8	CIS[480];
-} __WLAN_ATTRIB_PACK__ hfa384x_CIS_t;
-
-/*-- Information Record: STAIdentity --*/
-typedef struct hfa384x_STAIdentity
-{
-	u16	STACompID;
-	u16	STAVariant;
-	u16	STAMajorVersion;
-	u16	STAMinorVersion;
-} __WLAN_ATTRIB_PACK__ hfa384x_STAIdentity_t;
-
-/*-- Information Record: STASupRange --*/
-typedef struct hfa384x_STASupRange
-{
-	u16	STARole;
-	u16	STAID;
-	u16	STAVariant;
-	u16	STABottom;
-	u16	STATop;
-} __WLAN_ATTRIB_PACK__ hfa384x_STASupRange_t;
-
-/*-- Information Record: MFIActRanges --*/
-typedef struct hfa384x_MFIActRanges
-{
-	u16	MFIRole;
-	u16	MFIID;
-	u16	MFIVariant;
-	u16	MFIBottom;
-	u16	MFITop;
-} __WLAN_ATTRIB_PACK__ hfa384x_MFIActRanges_t;
+typedef struct hfa384x_downloadbuffer {
+	u16 page;
+	u16 offset;
+	u16 len;
+} __attribute__ ((packed)) hfa384x_downloadbuffer_t;
 
 /*--------------------------------------------------------------------
 Information Record Structures: NIC Information
 --------------------------------------------------------------------*/
 
-/*-- Information Record: PortStatus --*/
-typedef struct hfa384x_PortStatus
-{
-	u16	PortStatus;
-} __WLAN_ATTRIB_PACK__ hfa384x_PortStatus_t;
-
-#define HFA384x_PSTATUS_DISABLED	((u16)1)
-#define HFA384x_PSTATUS_SEARCHING	((u16)2)
 #define HFA384x_PSTATUS_CONN_IBSS	((u16)3)
-#define HFA384x_PSTATUS_CONN_ESS	((u16)4)
-#define HFA384x_PSTATUS_OUTOFRANGE	((u16)5)
-#define HFA384x_PSTATUS_CONN_WDS	((u16)6)
-
-/*-- Information Record: CurrentSSID --*/
-typedef struct hfa384x_CurrentSSID
-{
-	u8	CurrentSSID[34];
-} __WLAN_ATTRIB_PACK__ hfa384x_CurrentSSID_t;
-
-/*-- Information Record: CurrentBSSID --*/
-typedef struct hfa384x_CurrentBSSID
-{
-	u8	CurrentBSSID[6];
-} __WLAN_ATTRIB_PACK__ hfa384x_CurrentBSSID_t;
 
 /*-- Information Record: commsquality --*/
-typedef struct hfa384x_commsquality
-{
-	u16	CQ_currBSS;
-	u16	ASL_currBSS;
-	u16	ANL_currFC;
-} __WLAN_ATTRIB_PACK__ hfa384x_commsquality_t;
+typedef struct hfa384x_commsquality {
+	u16 CQ_currBSS;
+	u16 ASL_currBSS;
+	u16 ANL_currFC;
+} __attribute__ ((packed)) hfa384x_commsquality_t;
 
 /*-- Information Record: dmbcommsquality --*/
-typedef struct hfa384x_dbmcommsquality
-{
-	u16	CQdbm_currBSS;
-	u16	ASLdbm_currBSS;
-	u16	ANLdbm_currFC;
-} __WLAN_ATTRIB_PACK__ hfa384x_dbmcommsquality_t;
-
-/*-- Information Record: CurrentTxRate --*/
-typedef struct hfa384x_CurrentTxRate
-{
-	u16	CurrentTxRate;
-} __WLAN_ATTRIB_PACK__ hfa384x_CurrentTxRate_t;
-
-/*-- Information Record: CurrentBeaconInterval --*/
-typedef struct hfa384x_CurrentBeaconInterval
-{
-	u16	CurrentBeaconInterval;
-} __WLAN_ATTRIB_PACK__ hfa384x_CurrentBeaconInterval_t;
-
-/*-- Information Record: CurrentScaleThresholds --*/
-typedef struct hfa384x_CurrentScaleThresholds
-{
-	u16	EnergyDetectThreshold;
-	u16	CarrierDetectThreshold;
-	u16	DeferDetectThreshold;
-	u16	CellSearchThreshold; /* Stations only */
-	u16	DeadSpotThreshold; /* Stations only */
-} __WLAN_ATTRIB_PACK__ hfa384x_CurrentScaleThresholds_t;
-
-/*-- Information Record: ProtocolRspTime --*/
-typedef struct hfa384x_ProtocolRspTime
-{
-	u16	ProtocolRspTime;
-} __WLAN_ATTRIB_PACK__ hfa384x_ProtocolRspTime_t;
-
-/*-- Information Record: ShortRetryLimit --*/
-typedef struct hfa384x_ShortRetryLimit
-{
-	u16	ShortRetryLimit;
-} __WLAN_ATTRIB_PACK__ hfa384x_ShortRetryLimit_t;
-
-/*-- Information Record: LongRetryLimit --*/
-typedef struct hfa384x_LongRetryLimit
-{
-	u16	LongRetryLimit;
-} __WLAN_ATTRIB_PACK__ hfa384x_LongRetryLimit_t;
-
-/*-- Information Record: MaxTransmitLifetime --*/
-typedef struct hfa384x_MaxTransmitLifetime
-{
-	u16	MaxTransmitLifetime;
-} __WLAN_ATTRIB_PACK__ hfa384x_MaxTransmitLifetime_t;
-
-/*-- Information Record: MaxReceiveLifetime --*/
-typedef struct hfa384x_MaxReceiveLifetime
-{
-	u16	MaxReceiveLifetime;
-} __WLAN_ATTRIB_PACK__ hfa384x_MaxReceiveLifetime_t;
-
-/*-- Information Record: CFPollable --*/
-typedef struct hfa384x_CFPollable
-{
-	u16	CFPollable;
-} __WLAN_ATTRIB_PACK__ hfa384x_CFPollable_t;
-
-/*-- Information Record: AuthenticationAlgorithms --*/
-typedef struct hfa384x_AuthenticationAlgorithms
-{
-	u16	AuthenticationType;
-	u16	TypeEnabled;
-} __WLAN_ATTRIB_PACK__ hfa384x_AuthenticationAlgorithms_t;
-
-/*-- Information Record: AuthenticationAlgorithms
-(data only --*/
-typedef struct hfa384x_AuthenticationAlgorithms_data
-{
-	u16	AuthenticationType;
-	u16	TypeEnabled;
-} __WLAN_ATTRIB_PACK__ hfa384x_AuthenticationAlgorithms_data_t;
-
-/*-- Information Record: PrivacyOptionImplemented --*/
-typedef struct hfa384x_PrivacyOptionImplemented
-{
-	u16	PrivacyOptionImplemented;
-} __WLAN_ATTRIB_PACK__ hfa384x_PrivacyOptionImplemented_t;
-
-/*-- Information Record: OwnMACAddress --*/
-typedef struct hfa384x_OwnMACAddress
-{
-	u8	OwnMACAddress[6];
-} __WLAN_ATTRIB_PACK__ hfa384x_OwnMACAddress_t;
-
-/*-- Information Record: PCFInfo --*/
-typedef struct hfa384x_PCFInfo
-{
-	u16	MediumOccupancyLimit;
-	u16	CFPPeriod;
-	u16	CFPMaxDuration;
-	u16	CFPFlags;
-} __WLAN_ATTRIB_PACK__ hfa384x_PCFInfo_t;
-
-/*-- Information Record: PCFInfo (data portion only) --*/
-typedef struct hfa384x_PCFInfo_data
-{
-	u16	MediumOccupancyLimit;
-	u16	CFPPeriod;
-	u16	CFPMaxDuration;
-	u16	CFPFlags;
-} __WLAN_ATTRIB_PACK__ hfa384x_PCFInfo_data_t;
-
-/*--------------------------------------------------------------------
-Information Record Structures: Modem Information Records
---------------------------------------------------------------------*/
-
-/*-- Information Record: PHYType --*/
-typedef struct hfa384x_PHYType
-{
-	u16	PHYType;
-} __WLAN_ATTRIB_PACK__ hfa384x_PHYType_t;
-
-/*-- Information Record: CurrentChannel --*/
-typedef struct hfa384x_CurrentChannel
-{
-	u16	CurrentChannel;
-} __WLAN_ATTRIB_PACK__ hfa384x_CurrentChannel_t;
-
-/*-- Information Record: CurrentPowerState --*/
-typedef struct hfa384x_CurrentPowerState
-{
-	u16	CurrentPowerState;
-} __WLAN_ATTRIB_PACK__ hfa384x_CurrentPowerState_t;
-
-/*-- Information Record: CCAMode --*/
-typedef struct hfa384x_CCAMode
-{
-	u16	CCAMode;
-} __WLAN_ATTRIB_PACK__ hfa384x_CCAMode_t;
-
-/*-- Information Record: SupportedDataRates --*/
-typedef struct hfa384x_SupportedDataRates
-{
-	u8	SupportedDataRates[10];
-} __WLAN_ATTRIB_PACK__ hfa384x_SupportedDataRates_t;
-
-/*-- Information Record: LFOStatus --*/
-typedef struct hfa384x_LFOStatus
-{
-	u16  TestResults;
-	u16  LFOResult;
-	u16  VRHFOResult;
-} __WLAN_ATTRIB_PACK__ hfa384x_LFOStatus_t;
-
-#define HFA384x_TESTRESULT_ALLPASSED    BIT0
-#define HFA384x_TESTRESULT_LFO_FAIL     BIT1
-#define HFA384x_TESTRESULT_VR_HF0_FAIL  BIT2
-#define HFA384x_HOST_FIRM_COORDINATE    BIT7
-#define HFA384x_TESTRESULT_COORDINATE   BIT15
-
-/*-- Information Record: LEDControl --*/
-typedef struct hfa384x_LEDControl
-{
-	u16  searching_on;
-	u16  searching_off;
-	u16  assoc_on;
-	u16  assoc_off;
-	u16  activity;
-} __WLAN_ATTRIB_PACK__ hfa384x_LEDControl_t;
-
-/*--------------------------------------------------------------------
-                 FRAME DESCRIPTORS AND FRAME STRUCTURES
-
-FRAME DESCRIPTORS: Offsets
-
-----------------------------------------------------------------------
-Control Info (offset 44-51)
---------------------------------------------------------------------*/
-#define		HFA384x_FD_STATUS_OFF			((u16)0x44)
-#define		HFA384x_FD_TIME_OFF			((u16)0x46)
-#define		HFA384x_FD_SWSUPPORT_OFF		((u16)0x4A)
-#define		HFA384x_FD_SILENCE_OFF			((u16)0x4A)
-#define		HFA384x_FD_SIGNAL_OFF			((u16)0x4B)
-#define		HFA384x_FD_RATE_OFF			((u16)0x4C)
-#define		HFA384x_FD_RXFLOW_OFF			((u16)0x4D)
-#define		HFA384x_FD_RESERVED_OFF			((u16)0x4E)
-#define		HFA384x_FD_TXCONTROL_OFF		((u16)0x50)
-/*--------------------------------------------------------------------
-802.11 Header (offset 52-6B)
---------------------------------------------------------------------*/
-#define		HFA384x_FD_FRAMECONTROL_OFF		((u16)0x52)
-#define		HFA384x_FD_DURATIONID_OFF		((u16)0x54)
-#define		HFA384x_FD_ADDRESS1_OFF			((u16)0x56)
-#define		HFA384x_FD_ADDRESS2_OFF			((u16)0x5C)
-#define		HFA384x_FD_ADDRESS3_OFF			((u16)0x62)
-#define		HFA384x_FD_SEQCONTROL_OFF		((u16)0x68)
-#define		HFA384x_FD_ADDRESS4_OFF			((u16)0x6A)
-#define		HFA384x_FD_DATALEN_OFF			((u16)0x70)
-/*--------------------------------------------------------------------
-802.3 Header (offset 72-7F)
---------------------------------------------------------------------*/
-#define		HFA384x_FD_DESTADDRESS_OFF		((u16)0x72)
-#define		HFA384x_FD_SRCADDRESS_OFF		((u16)0x78)
-#define		HFA384x_FD_DATALENGTH_OFF		((u16)0x7E)
+typedef struct hfa384x_dbmcommsquality {
+	u16 CQdbm_currBSS;
+	u16 ASLdbm_currBSS;
+	u16 ANLdbm_currFC;
+} __attribute__ ((packed)) hfa384x_dbmcommsquality_t;
 
 /*--------------------------------------------------------------------
 FRAME STRUCTURES: Communication Frames
@@ -1573,51 +442,46 @@
 Communication Frames: Transmit Frames
 --------------------------------------------------------------------*/
 /*-- Communication Frame: Transmit Frame Structure --*/
-typedef struct hfa384x_tx_frame
-{
-	u16	status;
-	u16	reserved1;
-	u16	reserved2;
-	u32	sw_support;
-	u8	tx_retrycount;
-	u8   tx_rate;
-	u16	tx_control;
+typedef struct hfa384x_tx_frame {
+	u16 status;
+	u16 reserved1;
+	u16 reserved2;
+	u32 sw_support;
+	u8 tx_retrycount;
+	u8 tx_rate;
+	u16 tx_control;
 
 	/*-- 802.11 Header Information --*/
 
-	u16	frame_control;
-	u16	duration_id;
-	u8	address1[6];
-	u8	address2[6];
-	u8	address3[6];
-	u16	sequence_control;
-	u8	address4[6];
-	u16	data_len; /* little endian format */
+	u16 frame_control;
+	u16 duration_id;
+	u8 address1[6];
+	u8 address2[6];
+	u8 address3[6];
+	u16 sequence_control;
+	u8 address4[6];
+	u16 data_len;		/* little endian format */
 
 	/*-- 802.3 Header Information --*/
 
-	u8	dest_addr[6];
-	u8	src_addr[6];
-	u16	data_length; /* big endian format */
-} __WLAN_ATTRIB_PACK__ hfa384x_tx_frame_t;
+	u8 dest_addr[6];
+	u8 src_addr[6];
+	u16 data_length;	/* big endian format */
+} __attribute__ ((packed)) hfa384x_tx_frame_t;
 /*--------------------------------------------------------------------
 Communication Frames: Field Masks for Transmit Frames
 --------------------------------------------------------------------*/
 /*-- Status Field --*/
-#define		HFA384x_TXSTATUS_ACKERR			((u16)BIT5)
-#define		HFA384x_TXSTATUS_FORMERR		((u16)BIT3)
-#define		HFA384x_TXSTATUS_DISCON			((u16)BIT2)
-#define		HFA384x_TXSTATUS_AGEDERR		((u16)BIT1)
-#define		HFA384x_TXSTATUS_RETRYERR		((u16)BIT0)
+#define		HFA384x_TXSTATUS_ACKERR			((u16)BIT(5))
+#define		HFA384x_TXSTATUS_FORMERR		((u16)BIT(3))
+#define		HFA384x_TXSTATUS_DISCON			((u16)BIT(2))
+#define		HFA384x_TXSTATUS_AGEDERR		((u16)BIT(1))
+#define		HFA384x_TXSTATUS_RETRYERR		((u16)BIT(0))
 /*-- Transmit Control Field --*/
-#define		HFA384x_TX_CFPOLL			((u16)BIT12)
-#define		HFA384x_TX_PRST				((u16)BIT11)
-#define		HFA384x_TX_MACPORT			((u16)(BIT10 | BIT9 | BIT8))
-#define		HFA384x_TX_NOENCRYPT			((u16)BIT7)
-#define		HFA384x_TX_RETRYSTRAT			((u16)(BIT6 | BIT5))
-#define		HFA384x_TX_STRUCTYPE			((u16)(BIT4 | BIT3))
-#define		HFA384x_TX_TXEX				((u16)BIT2)
-#define		HFA384x_TX_TXOK				((u16)BIT1)
+#define		HFA384x_TX_MACPORT			((u16)(BIT(10) | BIT(9) | BIT(8)))
+#define		HFA384x_TX_STRUCTYPE			((u16)(BIT(4) | BIT(3)))
+#define		HFA384x_TX_TXEX				((u16)BIT(2))
+#define		HFA384x_TX_TXOK				((u16)BIT(1))
 /*--------------------------------------------------------------------
 Communication Frames: Test/Get/Set Field Values for Transmit Frames
 --------------------------------------------------------------------*/
@@ -1628,83 +492,53 @@
 	HFA384x_TXSTATUS_DISCON|HFA384x_TXSTATUS_AGEDERR|\
 	HFA384x_TXSTATUS_RETRYERR))
 
-#define	HFA384x_TXSTATUS_ISACKERR(v)	((u16)(((u16)(v)) & HFA384x_TXSTATUS_ACKERR))
-#define	HFA384x_TXSTATUS_ISFORMERR(v)	((u16)(((u16)(v)) & HFA384x_TXSTATUS_FORMERR))
-#define	HFA384x_TXSTATUS_ISDISCON(v)	((u16)(((u16)(v)) & HFA384x_TXSTATUS_DISCON))
-#define	HFA384x_TXSTATUS_ISAGEDERR(v)	((u16)(((u16)(v)) & HFA384x_TXSTATUS_AGEDERR))
-#define	HFA384x_TXSTATUS_ISRETRYERR(v)	((u16)(((u16)(v)) & HFA384x_TXSTATUS_RETRYERR))
+#define	HFA384x_TX_SET(v, m, s)		((((u16)(v))<<((u16)(s)))&((u16)(m)))
 
-#define	HFA384x_TX_GET(v,m,s)		((((u16)(v))&((u16)(m)))>>((u16)(s)))
-#define	HFA384x_TX_SET(v,m,s)		((((u16)(v))<<((u16)(s)))&((u16)(m)))
-
-#define	HFA384x_TX_CFPOLL_GET(v)	HFA384x_TX_GET(v, HFA384x_TX_CFPOLL,12)
-#define	HFA384x_TX_CFPOLL_SET(v)	HFA384x_TX_SET(v, HFA384x_TX_CFPOLL,12)
-#define	HFA384x_TX_PRST_GET(v)		HFA384x_TX_GET(v, HFA384x_TX_PRST,11)
-#define	HFA384x_TX_PRST_SET(v)		HFA384x_TX_SET(v, HFA384x_TX_PRST,11)
-#define	HFA384x_TX_MACPORT_GET(v)	HFA384x_TX_GET(v, HFA384x_TX_MACPORT, 8)
 #define	HFA384x_TX_MACPORT_SET(v)	HFA384x_TX_SET(v, HFA384x_TX_MACPORT, 8)
-#define	HFA384x_TX_NOENCRYPT_GET(v)	HFA384x_TX_GET(v, HFA384x_TX_NOENCRYPT, 7)
-#define	HFA384x_TX_NOENCRYPT_SET(v)	HFA384x_TX_SET(v, HFA384x_TX_NOENCRYPT, 7)
-#define	HFA384x_TX_RETRYSTRAT_GET(v)	HFA384x_TX_GET(v, HFA384x_TX_RETRYSTRAT, 5)
-#define	HFA384x_TX_RETRYSTRAT_SET(v)	HFA384x_TX_SET(v, HFA384x_TX_RETRYSTRAT, 5)
-#define	HFA384x_TX_STRUCTYPE_GET(v)	HFA384x_TX_GET(v, HFA384x_TX_STRUCTYPE, 3)
 #define	HFA384x_TX_STRUCTYPE_SET(v)	HFA384x_TX_SET(v, HFA384x_TX_STRUCTYPE, 3)
-#define	HFA384x_TX_TXEX_GET(v)		HFA384x_TX_GET(v, HFA384x_TX_TXEX, 2)
 #define	HFA384x_TX_TXEX_SET(v)		HFA384x_TX_SET(v, HFA384x_TX_TXEX, 2)
-#define	HFA384x_TX_TXOK_GET(v)		HFA384x_TX_GET(v, HFA384x_TX_TXOK, 1)
 #define	HFA384x_TX_TXOK_SET(v)		HFA384x_TX_SET(v, HFA384x_TX_TXOK, 1)
 /*--------------------------------------------------------------------
 Communication Frames: Receive Frames
 --------------------------------------------------------------------*/
 /*-- Communication Frame: Receive Frame Structure --*/
-typedef struct hfa384x_rx_frame
-{
+typedef struct hfa384x_rx_frame {
 	/*-- MAC rx descriptor (hfa384x byte order) --*/
-	u16	status;
-	u32	time;
-	u8	silence;
-	u8	signal;
-	u8	rate;
-	u8	rx_flow;
-	u16	reserved1;
-	u16	reserved2;
+	u16 status;
+	u32 time;
+	u8 silence;
+	u8 signal;
+	u8 rate;
+	u8 rx_flow;
+	u16 reserved1;
+	u16 reserved2;
 
 	/*-- 802.11 Header Information (802.11 byte order) --*/
-	u16	frame_control;
-	u16	duration_id;
-	u8	address1[6];
-	u8	address2[6];
-	u8	address3[6];
-	u16	sequence_control;
-	u8	address4[6];
-	u16	data_len; /* hfa384x (little endian) format */
+	u16 frame_control;
+	u16 duration_id;
+	u8 address1[6];
+	u8 address2[6];
+	u8 address3[6];
+	u16 sequence_control;
+	u8 address4[6];
+	u16 data_len;		/* hfa384x (little endian) format */
 
 	/*-- 802.3 Header Information --*/
-	u8	dest_addr[6];
-	u8	src_addr[6];
-	u16	data_length; /* IEEE? (big endian) format */
-} __WLAN_ATTRIB_PACK__ hfa384x_rx_frame_t;
+	u8 dest_addr[6];
+	u8 src_addr[6];
+	u16 data_length;	/* IEEE? (big endian) format */
+} __attribute__ ((packed)) hfa384x_rx_frame_t;
 /*--------------------------------------------------------------------
 Communication Frames: Field Masks for Receive Frames
 --------------------------------------------------------------------*/
-/*-- Offsets --------*/
-#define		HFA384x_RX_DATA_LEN_OFF			((u16)44)
-#define		HFA384x_RX_80211HDR_OFF			((u16)14)
-#define		HFA384x_RX_DATA_OFF			((u16)60)
 
 /*-- Status Fields --*/
-#define		HFA384x_RXSTATUS_MSGTYPE		((u16)(BIT15 | BIT14 | BIT13))
-#define		HFA384x_RXSTATUS_MACPORT		((u16)(BIT10 | BIT9 | BIT8))
-#define		HFA384x_RXSTATUS_UNDECR			((u16)BIT1)
-#define		HFA384x_RXSTATUS_FCSERR			((u16)BIT0)
+#define		HFA384x_RXSTATUS_MACPORT		((u16)(BIT(10) | BIT(9) | BIT(8)))
+#define		HFA384x_RXSTATUS_FCSERR			((u16)BIT(0))
 /*--------------------------------------------------------------------
 Communication Frames: Test/Get/Set Field Values for Receive Frames
 --------------------------------------------------------------------*/
-#define		HFA384x_RXSTATUS_MSGTYPE_GET(value)	((u16)((((u16)(value)) & HFA384x_RXSTATUS_MSGTYPE) >> 13))
-#define		HFA384x_RXSTATUS_MSGTYPE_SET(value)	((u16)(((u16)(value)) << 13))
 #define		HFA384x_RXSTATUS_MACPORT_GET(value)	((u16)((((u16)(value)) & HFA384x_RXSTATUS_MACPORT) >> 8))
-#define		HFA384x_RXSTATUS_MACPORT_SET(value)	((u16)(((u16)(value)) << 8))
-#define		HFA384x_RXSTATUS_ISUNDECR(value)	((u16)(((u16)(value)) & HFA384x_RXSTATUS_UNDECR))
 #define		HFA384x_RXSTATUS_ISFCSERR(value)	((u16)(((u16)(value)) & HFA384x_RXSTATUS_FCSERR))
 /*--------------------------------------------------------------------
  FRAME STRUCTURES: Information Types and Information Frame Structures
@@ -1712,7 +546,6 @@
 Information Types
 --------------------------------------------------------------------*/
 #define		HFA384x_IT_HANDOVERADDR			((u16)0xF000UL)
-#define		HFA384x_IT_HANDOVERDEAUTHADDRESS	((u16)0xF001UL)//AP 1.3.7
 #define		HFA384x_IT_COMMTALLIES			((u16)0xF100UL)
 #define		HFA384x_IT_SCANRESULTS			((u16)0xF101UL)
 #define		HFA384x_IT_CHINFORESULTS		((u16)0xF102UL)
@@ -1730,128 +563,110 @@
 ----------------------------------------------------------------------
 Information Frames: Notification Frame Structures
 --------------------------------------------------------------------*/
-/*--  Notification Frame,MAC Mgmt: Handover Address --*/
-typedef struct hfa384x_HandoverAddr
-{
-	u16	framelen;
-	u16	infotype;
-	u8	handover_addr[WLAN_BSSID_LEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_HandoverAddr_t;
 
 /*--  Inquiry Frame, Diagnose: Communication Tallies --*/
-typedef struct hfa384x_CommTallies16
-{
-	u16	txunicastframes;
-	u16	txmulticastframes;
-	u16	txfragments;
-	u16	txunicastoctets;
-	u16	txmulticastoctets;
-	u16	txdeferredtrans;
-	u16	txsingleretryframes;
-	u16	txmultipleretryframes;
-	u16	txretrylimitexceeded;
-	u16	txdiscards;
-	u16	rxunicastframes;
-	u16	rxmulticastframes;
-	u16	rxfragments;
-	u16	rxunicastoctets;
-	u16	rxmulticastoctets;
-	u16	rxfcserrors;
-	u16	rxdiscardsnobuffer;
-	u16	txdiscardswrongsa;
-	u16	rxdiscardswepundecr;
-	u16	rxmsginmsgfrag;
-	u16	rxmsginbadmsgfrag;
-} __WLAN_ATTRIB_PACK__ hfa384x_CommTallies16_t;
+typedef struct hfa384x_CommTallies16 {
+	u16 txunicastframes;
+	u16 txmulticastframes;
+	u16 txfragments;
+	u16 txunicastoctets;
+	u16 txmulticastoctets;
+	u16 txdeferredtrans;
+	u16 txsingleretryframes;
+	u16 txmultipleretryframes;
+	u16 txretrylimitexceeded;
+	u16 txdiscards;
+	u16 rxunicastframes;
+	u16 rxmulticastframes;
+	u16 rxfragments;
+	u16 rxunicastoctets;
+	u16 rxmulticastoctets;
+	u16 rxfcserrors;
+	u16 rxdiscardsnobuffer;
+	u16 txdiscardswrongsa;
+	u16 rxdiscardswepundecr;
+	u16 rxmsginmsgfrag;
+	u16 rxmsginbadmsgfrag;
+} __attribute__ ((packed)) hfa384x_CommTallies16_t;
 
-typedef struct hfa384x_CommTallies32
-{
-	u32	txunicastframes;
-	u32	txmulticastframes;
-	u32	txfragments;
-	u32	txunicastoctets;
-	u32	txmulticastoctets;
-	u32	txdeferredtrans;
-	u32	txsingleretryframes;
-	u32	txmultipleretryframes;
-	u32	txretrylimitexceeded;
-	u32	txdiscards;
-	u32	rxunicastframes;
-	u32	rxmulticastframes;
-	u32	rxfragments;
-	u32	rxunicastoctets;
-	u32	rxmulticastoctets;
-	u32	rxfcserrors;
-	u32	rxdiscardsnobuffer;
-	u32	txdiscardswrongsa;
-	u32	rxdiscardswepundecr;
-	u32	rxmsginmsgfrag;
-	u32	rxmsginbadmsgfrag;
-} __WLAN_ATTRIB_PACK__ hfa384x_CommTallies32_t;
+typedef struct hfa384x_CommTallies32 {
+	u32 txunicastframes;
+	u32 txmulticastframes;
+	u32 txfragments;
+	u32 txunicastoctets;
+	u32 txmulticastoctets;
+	u32 txdeferredtrans;
+	u32 txsingleretryframes;
+	u32 txmultipleretryframes;
+	u32 txretrylimitexceeded;
+	u32 txdiscards;
+	u32 rxunicastframes;
+	u32 rxmulticastframes;
+	u32 rxfragments;
+	u32 rxunicastoctets;
+	u32 rxmulticastoctets;
+	u32 rxfcserrors;
+	u32 rxdiscardsnobuffer;
+	u32 txdiscardswrongsa;
+	u32 rxdiscardswepundecr;
+	u32 rxmsginmsgfrag;
+	u32 rxmsginbadmsgfrag;
+} __attribute__ ((packed)) hfa384x_CommTallies32_t;
 
 /*--  Inquiry Frame, Diagnose: Scan Results & Subfields--*/
-typedef struct hfa384x_ScanResultSub
-{
-	u16	chid;
-	u16	anl;
-	u16	sl;
-	u8	bssid[WLAN_BSSID_LEN];
-	u16	bcnint;
-	u16	capinfo;
-	hfa384x_bytestr32_t	ssid;
-	u8	supprates[10]; /* 802.11 info element */
-	u16	proberesp_rate;
-} __WLAN_ATTRIB_PACK__ hfa384x_ScanResultSub_t;
+typedef struct hfa384x_ScanResultSub {
+	u16 chid;
+	u16 anl;
+	u16 sl;
+	u8 bssid[WLAN_BSSID_LEN];
+	u16 bcnint;
+	u16 capinfo;
+	hfa384x_bytestr32_t ssid;
+	u8 supprates[10];	/* 802.11 info element */
+	u16 proberesp_rate;
+} __attribute__ ((packed)) hfa384x_ScanResultSub_t;
 
-typedef struct hfa384x_ScanResult
-{
-	u16	rsvd;
-	u16	scanreason;
-	hfa384x_ScanResultSub_t
-		result[HFA384x_SCANRESULT_MAX];
-} __WLAN_ATTRIB_PACK__ hfa384x_ScanResult_t;
+typedef struct hfa384x_ScanResult {
+	u16 rsvd;
+	u16 scanreason;
+	 hfa384x_ScanResultSub_t result[HFA384x_SCANRESULT_MAX];
+} __attribute__ ((packed)) hfa384x_ScanResult_t;
 
 /*--  Inquiry Frame, Diagnose: ChInfo Results & Subfields--*/
-typedef struct hfa384x_ChInfoResultSub
-{
-	u16	chid;
-	u16	anl;
-	u16	pnl;
-	u16	active;
-} __WLAN_ATTRIB_PACK__ hfa384x_ChInfoResultSub_t;
+typedef struct hfa384x_ChInfoResultSub {
+	u16 chid;
+	u16 anl;
+	u16 pnl;
+	u16 active;
+} __attribute__ ((packed)) hfa384x_ChInfoResultSub_t;
 
-#define HFA384x_CHINFORESULT_BSSACTIVE	BIT0
-#define HFA384x_CHINFORESULT_PCFACTIVE	BIT1
+#define HFA384x_CHINFORESULT_BSSACTIVE	BIT(0)
+#define HFA384x_CHINFORESULT_PCFACTIVE	BIT(1)
 
-typedef struct hfa384x_ChInfoResult
-{
-	u16	scanchannels;
-	hfa384x_ChInfoResultSub_t
-		result[HFA384x_CHINFORESULT_MAX];
-} __WLAN_ATTRIB_PACK__ hfa384x_ChInfoResult_t;
+typedef struct hfa384x_ChInfoResult {
+	u16 scanchannels;
+	 hfa384x_ChInfoResultSub_t result[HFA384x_CHINFORESULT_MAX];
+} __attribute__ ((packed)) hfa384x_ChInfoResult_t;
 
 /*--  Inquiry Frame, Diagnose: Host Scan Results & Subfields--*/
-typedef struct hfa384x_HScanResultSub
-{
-	u16	chid;
-	u16	anl;
-	u16	sl;
-	u8	bssid[WLAN_BSSID_LEN];
-	u16	bcnint;
-	u16	capinfo;
-	hfa384x_bytestr32_t	ssid;
-	u8	supprates[10]; /* 802.11 info element */
-	u16	proberesp_rate;
-	u16	atim;
-} __WLAN_ATTRIB_PACK__ hfa384x_HScanResultSub_t;
+typedef struct hfa384x_HScanResultSub {
+	u16 chid;
+	u16 anl;
+	u16 sl;
+	u8 bssid[WLAN_BSSID_LEN];
+	u16 bcnint;
+	u16 capinfo;
+	hfa384x_bytestr32_t ssid;
+	u8 supprates[10];	/* 802.11 info element */
+	u16 proberesp_rate;
+	u16 atim;
+} __attribute__ ((packed)) hfa384x_HScanResultSub_t;
 
-typedef struct hfa384x_HScanResult
-{
-	u16	nresult;
-	u16	rsvd;
-	hfa384x_HScanResultSub_t
-		result[HFA384x_HSCANRESULT_MAX];
-} __WLAN_ATTRIB_PACK__ hfa384x_HScanResult_t;
+typedef struct hfa384x_HScanResult {
+	u16 nresult;
+	u16 rsvd;
+	 hfa384x_HScanResultSub_t result[HFA384x_HSCANRESULT_MAX];
+} __attribute__ ((packed)) hfa384x_HScanResult_t;
 
 /*--  Unsolicited Frame, MAC Mgmt: LinkStatus --*/
 
@@ -1863,100 +678,67 @@
 #define HFA384x_LINK_AP_INRANGE		((u16)5)
 #define HFA384x_LINK_ASSOCFAIL		((u16)6)
 
-typedef struct hfa384x_LinkStatus
-{
-	u16	linkstatus;
-} __WLAN_ATTRIB_PACK__ hfa384x_LinkStatus_t;
-
+typedef struct hfa384x_LinkStatus {
+	u16 linkstatus;
+} __attribute__ ((packed)) hfa384x_LinkStatus_t;
 
 /*--  Unsolicited Frame, MAC Mgmt: AssociationStatus (--*/
 
 #define HFA384x_ASSOCSTATUS_STAASSOC	((u16)1)
 #define HFA384x_ASSOCSTATUS_REASSOC	((u16)2)
-#define HFA384x_ASSOCSTATUS_DISASSOC	((u16)3)
-#define HFA384x_ASSOCSTATUS_ASSOCFAIL	((u16)4)
 #define HFA384x_ASSOCSTATUS_AUTHFAIL	((u16)5)
 
-typedef struct hfa384x_AssocStatus
-{
-	u16	assocstatus;
-	u8	sta_addr[WLAN_ADDR_LEN];
+typedef struct hfa384x_AssocStatus {
+	u16 assocstatus;
+	u8 sta_addr[ETH_ALEN];
 	/* old_ap_addr is only valid if assocstatus == 2 */
-	u8	old_ap_addr[WLAN_ADDR_LEN];
-	u16	reason;
-	u16	reserved;
-} __WLAN_ATTRIB_PACK__ hfa384x_AssocStatus_t;
+	u8 old_ap_addr[ETH_ALEN];
+	u16 reason;
+	u16 reserved;
+} __attribute__ ((packed)) hfa384x_AssocStatus_t;
 
 /*--  Unsolicited Frame, MAC Mgmt: AuthRequest (AP Only) --*/
 
-typedef struct hfa384x_AuthRequest
-{
-	u8	sta_addr[WLAN_ADDR_LEN];
-	u16	algorithm;
-} __WLAN_ATTRIB_PACK__ hfa384x_AuthReq_t;
-
-/*--  Unsolicited Frame, MAC Mgmt: AssocRequest (AP Only) --*/
-
-typedef struct hfa384x_AssocRequest
-{
-	u8	sta_addr[WLAN_ADDR_LEN];
-	u16	type;
-	u8   wpa_data[80];
-} __WLAN_ATTRIB_PACK__ hfa384x_AssocReq_t;
-
-
-#define HFA384x_ASSOCREQ_TYPE_ASSOC     0
-#define HFA384x_ASSOCREQ_TYPE_REASSOC   1
-
-/*--  Unsolicited Frame, MAC Mgmt: MIC Failure  (AP Only) --*/
-
-typedef struct hfa384x_MicFailure
-{
-	u8	sender[WLAN_ADDR_LEN];
-	u8	dest[WLAN_ADDR_LEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_MicFailure_t;
+typedef struct hfa384x_AuthRequest {
+	u8 sta_addr[ETH_ALEN];
+	u16 algorithm;
+} __attribute__ ((packed)) hfa384x_AuthReq_t;
 
 /*--  Unsolicited Frame, MAC Mgmt: PSUserCount (AP Only) --*/
 
-typedef struct hfa384x_PSUserCount
-{
-	u16	usercnt;
-} __WLAN_ATTRIB_PACK__ hfa384x_PSUserCount_t;
+typedef struct hfa384x_PSUserCount {
+	u16 usercnt;
+} __attribute__ ((packed)) hfa384x_PSUserCount_t;
 
-typedef struct hfa384x_KeyIDChanged
-{
-	u8	sta_addr[WLAN_ADDR_LEN];
-	u16	keyid;
-} __WLAN_ATTRIB_PACK__ hfa384x_KeyIDChanged_t;
+typedef struct hfa384x_KeyIDChanged {
+	u8 sta_addr[ETH_ALEN];
+	u16 keyid;
+} __attribute__ ((packed)) hfa384x_KeyIDChanged_t;
 
 /*--  Collection of all Inf frames ---------------*/
 typedef union hfa384x_infodata {
-	hfa384x_CommTallies16_t	commtallies16;
-	hfa384x_CommTallies32_t	commtallies32;
-	hfa384x_ScanResult_t	scanresult;
-	hfa384x_ChInfoResult_t	chinforesult;
-	hfa384x_HScanResult_t	hscanresult;
-	hfa384x_LinkStatus_t	linkstatus;
-	hfa384x_AssocStatus_t	assocstatus;
-	hfa384x_AuthReq_t	authreq;
-	hfa384x_PSUserCount_t	psusercnt;
-	hfa384x_KeyIDChanged_t  keyidchanged;
-} __WLAN_ATTRIB_PACK__ hfa384x_infodata_t;
+	hfa384x_CommTallies16_t commtallies16;
+	hfa384x_CommTallies32_t commtallies32;
+	hfa384x_ScanResult_t scanresult;
+	hfa384x_ChInfoResult_t chinforesult;
+	hfa384x_HScanResult_t hscanresult;
+	hfa384x_LinkStatus_t linkstatus;
+	hfa384x_AssocStatus_t assocstatus;
+	hfa384x_AuthReq_t authreq;
+	hfa384x_PSUserCount_t psusercnt;
+	hfa384x_KeyIDChanged_t keyidchanged;
+} __attribute__ ((packed)) hfa384x_infodata_t;
 
-typedef struct hfa384x_InfFrame
-{
-	u16			framelen;
-	u16			infotype;
-	hfa384x_infodata_t	info;
-} __WLAN_ATTRIB_PACK__ hfa384x_InfFrame_t;
+typedef struct hfa384x_InfFrame {
+	u16 framelen;
+	u16 infotype;
+	hfa384x_infodata_t info;
+} __attribute__ ((packed)) hfa384x_InfFrame_t;
 
 /*--------------------------------------------------------------------
 USB Packet structures and constants.
 --------------------------------------------------------------------*/
 
-/* Should be sent to the ctrlout endpoint */
-#define HFA384x_USB_ENBULKIN	6
-
 /* Should be sent to the bulkout endpoint */
 #define HFA384x_USB_TXFRM	0
 #define HFA384x_USB_CMDREQ	1
@@ -1966,7 +748,6 @@
 #define HFA384x_USB_RMEMREQ	5
 
 /* Received from the bulkin endpoint */
-#define HFA384x_USB_ISFRM(a)	(!((a) & 0x8000))
 #define HFA384x_USB_ISTXFRM(a)	(((a) & 0x9000) == 0x1000)
 #define HFA384x_USB_ISRXFRM(a)	(!((a) & 0x9000))
 #define HFA384x_USB_INFOFRM	0x8000
@@ -1982,380 +763,135 @@
 /* Request (bulk OUT) packet contents */
 
 typedef struct hfa384x_usb_txfrm {
-	hfa384x_tx_frame_t	desc;
-	u8			data[WLAN_DATA_MAXLEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_txfrm_t;
+	hfa384x_tx_frame_t desc;
+	u8 data[WLAN_DATA_MAXLEN];
+} __attribute__ ((packed)) hfa384x_usb_txfrm_t;
 
 typedef struct hfa384x_usb_cmdreq {
-	u16		type;
-	u16		cmd;
-	u16		parm0;
-	u16		parm1;
-	u16		parm2;
-	u8		pad[54];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_cmdreq_t;
+	u16 type;
+	u16 cmd;
+	u16 parm0;
+	u16 parm1;
+	u16 parm2;
+	u8 pad[54];
+} __attribute__ ((packed)) hfa384x_usb_cmdreq_t;
 
 typedef struct hfa384x_usb_wridreq {
-	u16		type;
-	u16		frmlen;
-	u16		rid;
-	u8		data[HFA384x_RIDDATA_MAXLEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_wridreq_t;
+	u16 type;
+	u16 frmlen;
+	u16 rid;
+	u8 data[HFA384x_RIDDATA_MAXLEN];
+} __attribute__ ((packed)) hfa384x_usb_wridreq_t;
 
 typedef struct hfa384x_usb_rridreq {
-	u16		type;
-	u16		frmlen;
-	u16		rid;
-	u8		pad[58];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_rridreq_t;
+	u16 type;
+	u16 frmlen;
+	u16 rid;
+	u8 pad[58];
+} __attribute__ ((packed)) hfa384x_usb_rridreq_t;
 
 typedef struct hfa384x_usb_wmemreq {
-	u16		type;
-	u16		frmlen;
-	u16		offset;
-	u16		page;
-	u8		data[HFA384x_USB_RWMEM_MAXLEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_wmemreq_t;
+	u16 type;
+	u16 frmlen;
+	u16 offset;
+	u16 page;
+	u8 data[HFA384x_USB_RWMEM_MAXLEN];
+} __attribute__ ((packed)) hfa384x_usb_wmemreq_t;
 
 typedef struct hfa384x_usb_rmemreq {
-	u16		type;
-	u16		frmlen;
-	u16		offset;
-	u16		page;
-	u8		pad[56];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_rmemreq_t;
+	u16 type;
+	u16 frmlen;
+	u16 offset;
+	u16 page;
+	u8 pad[56];
+} __attribute__ ((packed)) hfa384x_usb_rmemreq_t;
 
 /*------------------------------------*/
 /* Response (bulk IN) packet contents */
 
 typedef struct hfa384x_usb_rxfrm {
-	hfa384x_rx_frame_t	desc;
-	u8			data[WLAN_DATA_MAXLEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_rxfrm_t;
+	hfa384x_rx_frame_t desc;
+	u8 data[WLAN_DATA_MAXLEN];
+} __attribute__ ((packed)) hfa384x_usb_rxfrm_t;
 
 typedef struct hfa384x_usb_infofrm {
-	u16			type;
-	hfa384x_InfFrame_t	info;
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_infofrm_t;
+	u16 type;
+	hfa384x_InfFrame_t info;
+} __attribute__ ((packed)) hfa384x_usb_infofrm_t;
 
 typedef struct hfa384x_usb_statusresp {
-	u16		type;
-	u16		status;
-	u16		resp0;
-	u16		resp1;
-	u16		resp2;
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_cmdresp_t;
+	u16 type;
+	u16 status;
+	u16 resp0;
+	u16 resp1;
+	u16 resp2;
+} __attribute__ ((packed)) hfa384x_usb_cmdresp_t;
 
 typedef hfa384x_usb_cmdresp_t hfa384x_usb_wridresp_t;
 
 typedef struct hfa384x_usb_rridresp {
-	u16		type;
-	u16		frmlen;
-	u16		rid;
-	u8		data[HFA384x_RIDDATA_MAXLEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_rridresp_t;
+	u16 type;
+	u16 frmlen;
+	u16 rid;
+	u8 data[HFA384x_RIDDATA_MAXLEN];
+} __attribute__ ((packed)) hfa384x_usb_rridresp_t;
 
 typedef hfa384x_usb_cmdresp_t hfa384x_usb_wmemresp_t;
 
 typedef struct hfa384x_usb_rmemresp {
-	u16		type;
-	u16		frmlen;
-	u8		data[HFA384x_USB_RWMEM_MAXLEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_rmemresp_t;
+	u16 type;
+	u16 frmlen;
+	u8 data[HFA384x_USB_RWMEM_MAXLEN];
+} __attribute__ ((packed)) hfa384x_usb_rmemresp_t;
 
 typedef struct hfa384x_usb_bufavail {
-	u16		type;
-	u16		frmlen;
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_bufavail_t;
+	u16 type;
+	u16 frmlen;
+} __attribute__ ((packed)) hfa384x_usb_bufavail_t;
 
 typedef struct hfa384x_usb_error {
-	u16		type;
-	u16		errortype;
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_error_t;
+	u16 type;
+	u16 errortype;
+} __attribute__ ((packed)) hfa384x_usb_error_t;
 
 /*----------------------------------------------------------*/
 /* Unions for packaging all the known packet types together */
 
 typedef union hfa384x_usbout {
-	u16			type;
-	hfa384x_usb_txfrm_t	txfrm;
-	hfa384x_usb_cmdreq_t	cmdreq;
-	hfa384x_usb_wridreq_t	wridreq;
-	hfa384x_usb_rridreq_t	rridreq;
-	hfa384x_usb_wmemreq_t	wmemreq;
-	hfa384x_usb_rmemreq_t	rmemreq;
-} __WLAN_ATTRIB_PACK__ hfa384x_usbout_t;
+	u16 type;
+	hfa384x_usb_txfrm_t txfrm;
+	hfa384x_usb_cmdreq_t cmdreq;
+	hfa384x_usb_wridreq_t wridreq;
+	hfa384x_usb_rridreq_t rridreq;
+	hfa384x_usb_wmemreq_t wmemreq;
+	hfa384x_usb_rmemreq_t rmemreq;
+} __attribute__ ((packed)) hfa384x_usbout_t;
 
 typedef union hfa384x_usbin {
-	u16			type;
-	hfa384x_usb_rxfrm_t	rxfrm;
-	hfa384x_usb_txfrm_t	txfrm;
-	hfa384x_usb_infofrm_t	infofrm;
-	hfa384x_usb_cmdresp_t	cmdresp;
-	hfa384x_usb_wridresp_t	wridresp;
-	hfa384x_usb_rridresp_t	rridresp;
-	hfa384x_usb_wmemresp_t	wmemresp;
-	hfa384x_usb_rmemresp_t	rmemresp;
-	hfa384x_usb_bufavail_t	bufavail;
-	hfa384x_usb_error_t	usberror;
-	u8			boguspad[3000];
-} __WLAN_ATTRIB_PACK__ hfa384x_usbin_t;
-
-/*--------------------------------------------------------------------
-PD record structures.
---------------------------------------------------------------------*/
-
-typedef struct hfa384x_pdr_pcb_partnum
-{
-	u8	num[8];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_pcb_partnum_t;
-
-typedef struct hfa384x_pdr_pcb_tracenum
-{
-	u8	num[8];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_pcb_tracenum_t;
-
-typedef struct hfa384x_pdr_nic_serial
-{
-	u8	num[12];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nic_serial_t;
-
-typedef struct hfa384x_pdr_mkk_measurements
-{
-	double	carrier_freq;
-	double	occupied_band;
-	double	power_density;
-	double	tx_spur_f1;
-	double	tx_spur_f2;
-	double	tx_spur_f3;
-	double	tx_spur_f4;
-	double	tx_spur_l1;
-	double	tx_spur_l2;
-	double	tx_spur_l3;
-	double	tx_spur_l4;
-	double	rx_spur_f1;
-	double	rx_spur_f2;
-	double	rx_spur_l1;
-	double	rx_spur_l2;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mkk_measurements_t;
-
-typedef struct hfa384x_pdr_nic_ramsize
-{
-	u8	size[12]; /* units of KB */
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nic_ramsize_t;
-
-typedef struct hfa384x_pdr_mfisuprange
-{
-	u16	id;
-	u16	variant;
-	u16	bottom;
-	u16	top;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mfisuprange_t;
-
-typedef struct hfa384x_pdr_cfisuprange
-{
-	u16	id;
-	u16	variant;
-	u16	bottom;
-	u16	top;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_cfisuprange_t;
-
-typedef struct hfa384x_pdr_nicid
-{
-	u16	id;
-	u16	variant;
-	u16	major;
-	u16	minor;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nicid_t;
-
-
-typedef struct hfa384x_pdr_refdac_measurements
-{
-	u16	value[0];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_refdac_measurements_t;
-
-typedef struct hfa384x_pdr_vgdac_measurements
-{
-	u16	value[0];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_vgdac_measurements_t;
-
-typedef struct hfa384x_pdr_level_comp_measurements
-{
-	u16	value[0];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_level_compc_measurements_t;
-
-typedef struct hfa384x_pdr_mac_address
-{
-	u8	addr[6];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mac_address_t;
-
-typedef struct hfa384x_pdr_mkk_callname
-{
-	u8	callname[8];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mkk_callname_t;
-
-typedef struct hfa384x_pdr_regdomain
-{
-	u16	numdomains;
-	u16	domain[5];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_regdomain_t;
-
-typedef struct hfa384x_pdr_allowed_channel
-{
-	u16	ch_bitmap;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_allowed_channel_t;
-
-typedef struct hfa384x_pdr_default_channel
-{
-	u16	channel;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_default_channel_t;
-
-typedef struct hfa384x_pdr_privacy_option
-{
-	u16	available;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_privacy_option_t;
-
-typedef struct hfa384x_pdr_temptype
-{
-	u16	type;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_temptype_t;
-
-typedef struct hfa384x_pdr_refdac_setup
-{
-	u16	ch_value[14];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_refdac_setup_t;
-
-typedef struct hfa384x_pdr_vgdac_setup
-{
-	u16	ch_value[14];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_vgdac_setup_t;
-
-typedef struct hfa384x_pdr_level_comp_setup
-{
-	u16	ch_value[14];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_level_comp_setup_t;
-
-typedef struct hfa384x_pdr_trimdac_setup
-{
-	u16	trimidac;
-	u16	trimqdac;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_trimdac_setup_t;
-
-typedef struct hfa384x_pdr_ifr_setting
-{
-	u16	value[3];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_ifr_setting_t;
-
-typedef struct hfa384x_pdr_rfr_setting
-{
-	u16	value[3];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_rfr_setting_t;
-
-typedef struct hfa384x_pdr_hfa3861_baseline
-{
-	u16	value[50];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_baseline_t;
-
-typedef struct hfa384x_pdr_hfa3861_shadow
-{
-	u32	value[32];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_shadow_t;
-
-typedef struct hfa384x_pdr_hfa3861_ifrf
-{
-	u32	value[20];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_ifrf_t;
-
-typedef struct hfa384x_pdr_hfa3861_chcalsp
-{
-	u16	value[14];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_chcalsp_t;
-
-typedef struct hfa384x_pdr_hfa3861_chcali
-{
-	u16	value[17];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_chcali_t;
-
-typedef struct hfa384x_pdr_hfa3861_nic_config
-{
-	u16	config_bitmap;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nic_config_t;
-
-typedef struct hfa384x_pdr_hfo_delay
-{
-	u8   hfo_delay;
-} __WLAN_ATTRIB_PACK__ hfa384x_hfo_delay_t;
-
-typedef struct hfa384x_pdr_hfa3861_manf_testsp
-{
-	u16	value[30];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_manf_testsp_t;
-
-typedef struct hfa384x_pdr_hfa3861_manf_testi
-{
-	u16	value[30];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_manf_testi_t;
-
-typedef struct hfa384x_end_of_pda
-{
-	u16	crc;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_end_of_pda_t;
-
-typedef struct hfa384x_pdrec
-{
-	u16	len; /* in words */
-	u16	code;
-	union pdr {
-	hfa384x_pdr_pcb_partnum_t	pcb_partnum;
-	hfa384x_pdr_pcb_tracenum_t	pcb_tracenum;
-	hfa384x_pdr_nic_serial_t	nic_serial;
-	hfa384x_pdr_mkk_measurements_t	mkk_measurements;
-	hfa384x_pdr_nic_ramsize_t	nic_ramsize;
-	hfa384x_pdr_mfisuprange_t	mfisuprange;
-	hfa384x_pdr_cfisuprange_t	cfisuprange;
-	hfa384x_pdr_nicid_t		nicid;
-	hfa384x_pdr_refdac_measurements_t	refdac_measurements;
-	hfa384x_pdr_vgdac_measurements_t	vgdac_measurements;
-	hfa384x_pdr_level_compc_measurements_t	level_compc_measurements;
-	hfa384x_pdr_mac_address_t	mac_address;
-	hfa384x_pdr_mkk_callname_t	mkk_callname;
-	hfa384x_pdr_regdomain_t		regdomain;
-	hfa384x_pdr_allowed_channel_t	allowed_channel;
-	hfa384x_pdr_default_channel_t	default_channel;
-	hfa384x_pdr_privacy_option_t	privacy_option;
-	hfa384x_pdr_temptype_t		temptype;
-	hfa384x_pdr_refdac_setup_t	refdac_setup;
-	hfa384x_pdr_vgdac_setup_t	vgdac_setup;
-	hfa384x_pdr_level_comp_setup_t	level_comp_setup;
-	hfa384x_pdr_trimdac_setup_t	trimdac_setup;
-	hfa384x_pdr_ifr_setting_t	ifr_setting;
-	hfa384x_pdr_rfr_setting_t	rfr_setting;
-	hfa384x_pdr_hfa3861_baseline_t	hfa3861_baseline;
-	hfa384x_pdr_hfa3861_shadow_t	hfa3861_shadow;
-	hfa384x_pdr_hfa3861_ifrf_t	hfa3861_ifrf;
-	hfa384x_pdr_hfa3861_chcalsp_t	hfa3861_chcalsp;
-	hfa384x_pdr_hfa3861_chcali_t	hfa3861_chcali;
-	hfa384x_pdr_nic_config_t	nic_config;
-	hfa384x_hfo_delay_t             hfo_delay;
-	hfa384x_pdr_hfa3861_manf_testsp_t	hfa3861_manf_testsp;
-	hfa384x_pdr_hfa3861_manf_testi_t	hfa3861_manf_testi;
-	hfa384x_pdr_end_of_pda_t	end_of_pda;
-
-	} data;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdrec_t;
-
+	u16 type;
+	hfa384x_usb_rxfrm_t rxfrm;
+	hfa384x_usb_txfrm_t txfrm;
+	hfa384x_usb_infofrm_t infofrm;
+	hfa384x_usb_cmdresp_t cmdresp;
+	hfa384x_usb_wridresp_t wridresp;
+	hfa384x_usb_rridresp_t rridresp;
+	hfa384x_usb_wmemresp_t wmemresp;
+	hfa384x_usb_rmemresp_t rmemresp;
+	hfa384x_usb_bufavail_t bufavail;
+	hfa384x_usb_error_t usberror;
+	u8 boguspad[3000];
+} __attribute__ ((packed)) hfa384x_usbin_t;
 
 #ifdef __KERNEL__
 /*--------------------------------------------------------------------
 ---  MAC state structure, argument to all functions --
 ---  Also, a collection of support types --
 --------------------------------------------------------------------*/
-typedef struct hfa384x_statusresult
-{
-	u16	status;
-	u16	resp0;
-	u16	resp1;
-	u16	resp2;
+typedef struct hfa384x_statusresult {
+	u16 status;
+	u16 resp0;
+	u16 resp1;
+	u16 resp2;
 } hfa384x_cmdresult_t;
 
 /* USB Control Exchange (CTLX):
@@ -2365,20 +901,16 @@
 /* The following hfa384x_* structures are arguments to
  * the usercb() for the different CTLX types.
  */
-typedef hfa384x_cmdresult_t hfa384x_wridresult_t;
-typedef hfa384x_cmdresult_t hfa384x_wmemresult_t;
-
-typedef struct hfa384x_rridresult
-{
-	u16		rid;
-	const void	*riddata;
-	unsigned int		riddata_len;
+typedef struct hfa384x_rridresult {
+	u16 rid;
+	const void *riddata;
+	unsigned int riddata_len;
 } hfa384x_rridresult_t;
 
 enum ctlx_state {
-	CTLX_START = 0,	/* Start state, not queued */
+	CTLX_START = 0,		/* Start state, not queued */
 
-	CTLX_COMPLETE,	/* CTLX successfully completed */
+	CTLX_COMPLETE,		/* CTLX successfully completed */
 	CTLX_REQ_FAILED,	/* OUT URB completed w/ error */
 
 	CTLX_PENDING,		/* Queued, data valid */
@@ -2386,114 +918,98 @@
 	CTLX_REQ_COMPLETE,	/* OUT URB complete */
 	CTLX_RESP_COMPLETE	/* IN URB received */
 };
-typedef enum ctlx_state  CTLX_STATE;
+typedef enum ctlx_state CTLX_STATE;
 
 struct hfa384x_usbctlx;
 struct hfa384x;
 
-typedef void (*ctlx_cmdcb_t)( struct hfa384x*, const struct hfa384x_usbctlx* );
+typedef void (*ctlx_cmdcb_t) (struct hfa384x *, const struct hfa384x_usbctlx *);
 
-typedef void (*ctlx_usercb_t)(
-	struct hfa384x	*hw,
-	void		*ctlxresult,
-	void		*usercb_data);
+typedef void (*ctlx_usercb_t) (struct hfa384x *hw,
+			       void *ctlxresult, void *usercb_data);
 
-typedef struct hfa384x_usbctlx
-{
-	struct list_head	list;
+typedef struct hfa384x_usbctlx {
+	struct list_head list;
 
-	size_t			outbufsize;
-	hfa384x_usbout_t	outbuf;		/* pkt buf for OUT */
-	hfa384x_usbin_t		inbuf;		/* pkt buf for IN(a copy) */
+	size_t outbufsize;
+	hfa384x_usbout_t outbuf;	/* pkt buf for OUT */
+	hfa384x_usbin_t inbuf;	/* pkt buf for IN(a copy) */
 
-	CTLX_STATE		state;		/* Tracks running state */
+	CTLX_STATE state;	/* Tracks running state */
 
-	struct completion	done;
-	volatile int		reapable;	/* Food for the reaper task */
+	struct completion done;
+	volatile int reapable;	/* Food for the reaper task */
 
-	ctlx_cmdcb_t		cmdcb;		/* Async command callback */
-	ctlx_usercb_t		usercb;		/* Async user callback, */
-	void			*usercb_data;	/*  at CTLX completion  */
+	ctlx_cmdcb_t cmdcb;	/* Async command callback */
+	ctlx_usercb_t usercb;	/* Async user callback, */
+	void *usercb_data;	/*  at CTLX completion  */
 
-	int			variant;	/* Identifies cmd variant */
+	int variant;		/* Identifies cmd variant */
 } hfa384x_usbctlx_t;
 
-typedef struct hfa384x_usbctlxq
-{
-	spinlock_t		lock;
-	struct list_head	pending;
-	struct list_head	active;
-	struct list_head	completing;
-	struct list_head	reapable;
+typedef struct hfa384x_usbctlxq {
+	spinlock_t lock;
+	struct list_head pending;
+	struct list_head active;
+	struct list_head completing;
+	struct list_head reapable;
 } hfa384x_usbctlxq_t;
 
-typedef struct hfa484x_metacmd
-{
-	u16		cmd;
+typedef struct hfa484x_metacmd {
+	u16 cmd;
 
-	u16          parm0;
-	u16          parm1;
-	u16          parm2;
+	u16 parm0;
+	u16 parm1;
+	u16 parm2;
 
 	hfa384x_cmdresult_t result;
 } hfa384x_metacmd_t;
 
-#define	MAX_PRISM2_GRP_ADDR	16
 #define	MAX_GRP_ADDR		32
-#define WLAN_COMMENT_MAX	80  /* Max. length of user comment string. */
+#define WLAN_COMMENT_MAX	80	/* Max. length of user comment string. */
 
-#define MM_SAT_PCF		(BIT14)
-#define MM_GCSD_PCF		(BIT15)
-#define MM_GCSD_PCF_EB		(BIT14 | BIT15)
-
-#define WLAN_STATE_STOPPED	0   /* Network is not active. */
-#define WLAN_STATE_STARTED	1   /* Network has been started. */
-
-#define WLAN_AUTH_MAX           60  /* Max. # of authenticated stations. */
-#define WLAN_ACCESS_MAX		60  /* Max. # of stations in an access list. */
-#define WLAN_ACCESS_NONE	0   /* No stations may be authenticated. */
-#define WLAN_ACCESS_ALL		1   /* All stations may be authenticated. */
-#define WLAN_ACCESS_ALLOW	2   /* Authenticate only "allowed" stations. */
-#define WLAN_ACCESS_DENY	3   /* Do not authenticate "denied" stations. */
+#define WLAN_AUTH_MAX           60	/* Max. # of authenticated stations. */
+#define WLAN_ACCESS_MAX		60	/* Max. # of stations in an access list. */
+#define WLAN_ACCESS_NONE	0	/* No stations may be authenticated. */
+#define WLAN_ACCESS_ALL		1	/* All stations may be authenticated. */
+#define WLAN_ACCESS_ALLOW	2	/* Authenticate only "allowed" stations. */
+#define WLAN_ACCESS_DENY	3	/* Do not authenticate "denied" stations. */
 
 /* XXX These are going away ASAP */
-typedef struct prism2sta_authlist
-{
-	unsigned int	cnt;
-	u8	addr[WLAN_AUTH_MAX][WLAN_ADDR_LEN];
-	u8	assoc[WLAN_AUTH_MAX];
+typedef struct prism2sta_authlist {
+	unsigned int cnt;
+	u8 addr[WLAN_AUTH_MAX][ETH_ALEN];
+	u8 assoc[WLAN_AUTH_MAX];
 } prism2sta_authlist_t;
 
-typedef struct prism2sta_accesslist
-{
-	unsigned int	modify;
-	unsigned int	cnt;
-	u8	addr[WLAN_ACCESS_MAX][WLAN_ADDR_LEN];
-	unsigned int	cnt1;
-	u8	addr1[WLAN_ACCESS_MAX][WLAN_ADDR_LEN];
+typedef struct prism2sta_accesslist {
+	unsigned int modify;
+	unsigned int cnt;
+	u8 addr[WLAN_ACCESS_MAX][ETH_ALEN];
+	unsigned int cnt1;
+	u8 addr1[WLAN_ACCESS_MAX][ETH_ALEN];
 } prism2sta_accesslist_t;
 
-typedef struct hfa384x
-{
+typedef struct hfa384x {
 	/* USB support data */
-	struct usb_device	*usb;
-	struct urb		rx_urb;
-	struct sk_buff		*rx_urb_skb;
-	struct urb		tx_urb;
-	struct urb		ctlx_urb;
-	hfa384x_usbout_t	txbuff;
-	hfa384x_usbctlxq_t	ctlxq;
-	struct timer_list	reqtimer;
-	struct timer_list	resptimer;
+	struct usb_device *usb;
+	struct urb rx_urb;
+	struct sk_buff *rx_urb_skb;
+	struct urb tx_urb;
+	struct urb ctlx_urb;
+	hfa384x_usbout_t txbuff;
+	hfa384x_usbctlxq_t ctlxq;
+	struct timer_list reqtimer;
+	struct timer_list resptimer;
 
-	struct timer_list	throttle;
+	struct timer_list throttle;
 
-	struct tasklet_struct	reaper_bh;
-	struct tasklet_struct	completion_bh;
+	struct tasklet_struct reaper_bh;
+	struct tasklet_struct completion_bh;
 
-	struct work_struct	usb_work;
+	struct work_struct usb_work;
 
-	unsigned long		usb_flags;
+	unsigned long usb_flags;
 #define THROTTLE_RX	0
 #define THROTTLE_TX	1
 #define WORK_RX_HALT	2
@@ -2501,292 +1017,168 @@
 #define WORK_RX_RESUME	4
 #define WORK_TX_RESUME	5
 
-	unsigned short		req_timer_done:1;
-	unsigned short		resp_timer_done:1;
+	unsigned short req_timer_done:1;
+	unsigned short resp_timer_done:1;
 
-	int                     endp_in;
-	int                     endp_out;
+	int endp_in;
+	int endp_out;
 
-	int                     sniff_fcs;
-	int                     sniff_channel;
-	int                     sniff_truncate;
-	int                     sniffhdr;
+	int sniff_fcs;
+	int sniff_channel;
+	int sniff_truncate;
+	int sniffhdr;
 
-	wait_queue_head_t cmdq;	        /* wait queue itself */
+	wait_queue_head_t cmdq;	/* wait queue itself */
 
 	/* Controller state */
-	u32		state;
-	u32		isap;
-	u8		port_enabled[HFA384x_NUMPORTS_MAX];
+	u32 state;
+	u32 isap;
+	u8 port_enabled[HFA384x_NUMPORTS_MAX];
 
 	/* Download support */
-	unsigned int				dlstate;
-	hfa384x_downloadbuffer_t	bufinfo;
-	u16				dltimeout;
+	unsigned int dlstate;
+	hfa384x_downloadbuffer_t bufinfo;
+	u16 dltimeout;
 
-	int                          scanflag;    /* to signal scan comlete */
-	int                          join_ap;        /* are we joined to a specific ap */
-	int                          join_retries;   /* number of join retries till we fail */
-	hfa384x_JoinRequest_data_t   joinreq;        /* join request saved data */
+	int scanflag;		/* to signal scan comlete */
+	int join_ap;		/* are we joined to a specific ap */
+	int join_retries;	/* number of join retries till we fail */
+	hfa384x_JoinRequest_data_t joinreq;	/* join request saved data */
 
-	wlandevice_t            *wlandev;
+	wlandevice_t *wlandev;
 	/* Timer to allow for the deferred processing of linkstatus messages */
-	struct work_struct 	link_bh;
+	struct work_struct link_bh;
 
-        struct work_struct      commsqual_bh;
-	hfa384x_commsquality_t  qual;
-	struct timer_list	commsqual_timer;
+	struct work_struct commsqual_bh;
+	hfa384x_commsquality_t qual;
+	struct timer_list commsqual_timer;
 
 	u16 link_status;
 	u16 link_status_new;
-	struct sk_buff_head        authq;
+	struct sk_buff_head authq;
 
 	/* And here we have stuff that used to be in priv */
 
 	/* State variables */
-	unsigned int		presniff_port_type;
-	u16		presniff_wepflags;
-	u32		dot11_desired_bss_type;
+	unsigned int presniff_port_type;
+	u16 presniff_wepflags;
+	u32 dot11_desired_bss_type;
 
-	int             dbmadjust;
+	int dbmadjust;
 
 	/* Group Addresses - right now, there are up to a total
-	of MAX_GRP_ADDR group addresses */
-	u8		dot11_grp_addr[MAX_GRP_ADDR][WLAN_ADDR_LEN];
-	unsigned int		dot11_grpcnt;
+	   of MAX_GRP_ADDR group addresses */
+	u8 dot11_grp_addr[MAX_GRP_ADDR][ETH_ALEN];
+	unsigned int dot11_grpcnt;
 
 	/* Component Identities */
-	hfa384x_compident_t	ident_nic;
-	hfa384x_compident_t	ident_pri_fw;
-	hfa384x_compident_t	ident_sta_fw;
-	hfa384x_compident_t	ident_ap_fw;
-	u16			mm_mods;
+	hfa384x_compident_t ident_nic;
+	hfa384x_compident_t ident_pri_fw;
+	hfa384x_compident_t ident_sta_fw;
+	hfa384x_compident_t ident_ap_fw;
+	u16 mm_mods;
 
 	/* Supplier compatibility ranges */
-	hfa384x_caplevel_t	cap_sup_mfi;
-	hfa384x_caplevel_t	cap_sup_cfi;
-	hfa384x_caplevel_t	cap_sup_pri;
-	hfa384x_caplevel_t	cap_sup_sta;
-	hfa384x_caplevel_t	cap_sup_ap;
+	hfa384x_caplevel_t cap_sup_mfi;
+	hfa384x_caplevel_t cap_sup_cfi;
+	hfa384x_caplevel_t cap_sup_pri;
+	hfa384x_caplevel_t cap_sup_sta;
+	hfa384x_caplevel_t cap_sup_ap;
 
 	/* Actor compatibility ranges */
-	hfa384x_caplevel_t	cap_act_pri_cfi; /* pri f/w to controller interface */
-	hfa384x_caplevel_t	cap_act_sta_cfi; /* sta f/w to controller interface */
-	hfa384x_caplevel_t	cap_act_sta_mfi; /* sta f/w to modem interface */
-	hfa384x_caplevel_t	cap_act_ap_cfi;  /* ap f/w to controller interface */
-	hfa384x_caplevel_t	cap_act_ap_mfi;  /* ap f/w to modem interface */
+	hfa384x_caplevel_t cap_act_pri_cfi;	/* pri f/w to controller interface */
+	hfa384x_caplevel_t cap_act_sta_cfi;	/* sta f/w to controller interface */
+	hfa384x_caplevel_t cap_act_sta_mfi;	/* sta f/w to modem interface */
+	hfa384x_caplevel_t cap_act_ap_cfi;	/* ap f/w to controller interface */
+	hfa384x_caplevel_t cap_act_ap_mfi;	/* ap f/w to modem interface */
 
-	u32			psusercount;  /* Power save user count. */
-	hfa384x_CommTallies32_t	tallies;      /* Communication tallies. */
-	u8			comment[WLAN_COMMENT_MAX+1]; /* User comment */
+	u32 psusercount;	/* Power save user count. */
+	hfa384x_CommTallies32_t tallies;	/* Communication tallies. */
+	u8 comment[WLAN_COMMENT_MAX + 1];	/* User comment */
 
 	/* Channel Info request results (AP only) */
 	struct {
-		atomic_t		done;
-		u8			count;
-		hfa384x_ChInfoResult_t	results;
+		atomic_t done;
+		u8 count;
+		hfa384x_ChInfoResult_t results;
 	} channel_info;
 
-	hfa384x_InfFrame_t      *scanresults;
+	hfa384x_InfFrame_t *scanresults;
 
-
-        prism2sta_authlist_t	authlist;     /* Authenticated station list. */
-	unsigned int			accessmode;   /* Access mode. */
-        prism2sta_accesslist_t	allow;        /* Allowed station list. */
-        prism2sta_accesslist_t	deny;         /* Denied station list. */
+	prism2sta_authlist_t authlist;	/* Authenticated station list. */
+	unsigned int accessmode;	/* Access mode. */
+	prism2sta_accesslist_t allow;	/* Allowed station list. */
+	prism2sta_accesslist_t deny;	/* Denied station list. */
 
 } hfa384x_t;
 
-/*=============================================================*/
-/*--- Function Declarations -----------------------------------*/
-/*=============================================================*/
-void
-hfa384x_create(
-	hfa384x_t *hw,
-	struct usb_device *usb);
-
+void hfa384x_create(hfa384x_t *hw, struct usb_device *usb);
 void hfa384x_destroy(hfa384x_t *hw);
 
 int
-hfa384x_corereset( hfa384x_t *hw, int holdtime, int settletime, int genesis);
-int
-hfa384x_drvr_chinforesults( hfa384x_t *hw);
-int
-hfa384x_drvr_commtallies( hfa384x_t *hw);
-int
-hfa384x_drvr_disable(hfa384x_t *hw, u16 macport);
-int
-hfa384x_drvr_enable(hfa384x_t *hw, u16 macport);
-int
-hfa384x_drvr_flashdl_enable(hfa384x_t *hw);
-int
-hfa384x_drvr_flashdl_disable(hfa384x_t *hw);
-int
-hfa384x_drvr_flashdl_write(hfa384x_t *hw, u32 daddr, void* buf, u32 len);
-int
-hfa384x_drvr_getconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len);
-int
-hfa384x_drvr_handover( hfa384x_t *hw, u8 *addr);
-int
-hfa384x_drvr_hostscanresults( hfa384x_t *hw);
-int
-hfa384x_drvr_low_level(hfa384x_t *hw, hfa384x_metacmd_t *cmd);
-int
-hfa384x_drvr_mmi_read(hfa384x_t *hw, u32 address, u32 *result);
-int
-hfa384x_drvr_mmi_write(hfa384x_t *hw, u32 address, u32 data);
-int
-hfa384x_drvr_ramdl_enable(hfa384x_t *hw, u32 exeaddr);
-int
-hfa384x_drvr_ramdl_disable(hfa384x_t *hw);
-int
-hfa384x_drvr_ramdl_write(hfa384x_t *hw, u32 daddr, void* buf, u32 len);
-int
-hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, unsigned int len);
-int
-hfa384x_drvr_scanresults( hfa384x_t *hw);
+hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis);
+int hfa384x_drvr_commtallies(hfa384x_t *hw);
+int hfa384x_drvr_disable(hfa384x_t *hw, u16 macport);
+int hfa384x_drvr_enable(hfa384x_t *hw, u16 macport);
+int hfa384x_drvr_flashdl_enable(hfa384x_t *hw);
+int hfa384x_drvr_flashdl_disable(hfa384x_t *hw);
+int hfa384x_drvr_flashdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len);
+int hfa384x_drvr_getconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len);
+int hfa384x_drvr_ramdl_enable(hfa384x_t *hw, u32 exeaddr);
+int hfa384x_drvr_ramdl_disable(hfa384x_t *hw);
+int hfa384x_drvr_ramdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len);
+int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, unsigned int len);
+int hfa384x_drvr_setconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len);
 
-int
-hfa384x_drvr_setconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len);
-
-static inline int
-hfa384x_drvr_getconfig16(hfa384x_t *hw, u16 rid, void *val)
+static inline int hfa384x_drvr_getconfig16(hfa384x_t *hw, u16 rid, void *val)
 {
-	int		result = 0;
+	int result = 0;
 	result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(u16));
-	if ( result == 0 ) {
-		*((u16*)val) = hfa384x2host_16(*((u16*)val));
-	}
+	if (result == 0)
+		*((u16 *) val) = le16_to_cpu(*((u16 *) val));
 	return result;
 }
 
-static inline int
-hfa384x_drvr_getconfig32(hfa384x_t *hw, u16 rid, void *val)
+static inline int hfa384x_drvr_setconfig16(hfa384x_t *hw, u16 rid, u16 val)
 {
-	int		result = 0;
-
-	result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(u32));
-	if ( result == 0 ) {
-		*((u32*)val) = hfa384x2host_32(*((u32*)val));
-	}
-
-	return result;
-}
-
-static inline int
-hfa384x_drvr_setconfig16(hfa384x_t *hw, u16 rid, u16 val)
-{
-	u16 value = host2hfa384x_16(val);
-	return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(value));
-}
-
-static inline int
-hfa384x_drvr_setconfig32(hfa384x_t *hw, u16 rid, u32 val)
-{
-	u32 value = host2hfa384x_32(val);
+	u16 value = cpu_to_le16(val);
 	return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(value));
 }
 
 int
-hfa384x_drvr_getconfig_async(hfa384x_t     *hw,
-                              u16        rid,
-                              ctlx_usercb_t usercb,
-                              void          *usercb_data);
+hfa384x_drvr_getconfig_async(hfa384x_t *hw,
+			     u16 rid, ctlx_usercb_t usercb, void *usercb_data);
 
 int
 hfa384x_drvr_setconfig_async(hfa384x_t *hw,
-                              u16 rid,
-                              void *buf,
-                              u16 len,
-                              ctlx_usercb_t usercb,
-                              void *usercb_data);
+			     u16 rid,
+			     void *buf,
+			     u16 len, ctlx_usercb_t usercb, void *usercb_data);
 
 static inline int
 hfa384x_drvr_setconfig16_async(hfa384x_t *hw, u16 rid, u16 val)
 {
-	u16 value = host2hfa384x_16(val);
+	u16 value = cpu_to_le16(val);
 	return hfa384x_drvr_setconfig_async(hw, rid, &value, sizeof(value),
-					    NULL , NULL);
+					    NULL, NULL);
 }
 
-static inline int
-hfa384x_drvr_setconfig32_async(hfa384x_t *hw, u16 rid, u32 val)
-{
-	u32 value = host2hfa384x_32(val);
-	return hfa384x_drvr_setconfig_async(hw, rid, &value, sizeof(value),
-					    NULL , NULL);
-}
+int hfa384x_drvr_start(hfa384x_t *hw);
+int hfa384x_drvr_stop(hfa384x_t *hw);
+int
+hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb,
+		     p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep);
+void hfa384x_tx_timeout(wlandevice_t *wlandev);
 
-
+int hfa384x_cmd_initialize(hfa384x_t *hw);
+int hfa384x_cmd_enable(hfa384x_t *hw, u16 macport);
+int hfa384x_cmd_disable(hfa384x_t *hw, u16 macport);
+int hfa384x_cmd_allocate(hfa384x_t *hw, u16 len);
+int hfa384x_cmd_monitor(hfa384x_t *hw, u16 enable);
 int
-hfa384x_drvr_start(hfa384x_t *hw);
-int
-hfa384x_drvr_stop(hfa384x_t *hw);
-int
-hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep);
-void
-hfa384x_tx_timeout(wlandevice_t *wlandev);
-
-int
-hfa384x_cmd_initialize(hfa384x_t *hw);
-int
-hfa384x_cmd_enable(hfa384x_t *hw, u16 macport);
-int
-hfa384x_cmd_disable(hfa384x_t *hw, u16 macport);
-int
-hfa384x_cmd_diagnose(hfa384x_t *hw);
-int
-hfa384x_cmd_allocate(hfa384x_t *hw, u16 len);
-int
-hfa384x_cmd_transmit(hfa384x_t *hw, u16 reclaim, u16 qos, u16 fid);
-int
-hfa384x_cmd_clearpersist(hfa384x_t *hw, u16 fid);
-int
-hfa384x_cmd_access(hfa384x_t *hw, u16 write, u16 rid, void *buf, u16 len);
-int
-hfa384x_cmd_monitor(hfa384x_t *hw, u16 enable);
-int
-hfa384x_cmd_download(
-	hfa384x_t *hw,
-	u16 mode,
-	u16 lowaddr,
-	u16 highaddr,
-	u16 codelen);
-int
-hfa384x_cmd_aux_enable(hfa384x_t *hw, int force);
-int
-hfa384x_cmd_aux_disable(hfa384x_t *hw);
-int
-hfa384x_copy_from_bap(
-	hfa384x_t *hw,
-	u16	bap,
-	u16	id,
-	u16	offset,
-	void	*buf,
-	unsigned int	len);
-int
-hfa384x_copy_to_bap(
-	hfa384x_t *hw,
-	u16	bap,
-	u16	id,
-	u16	offset,
-	void	*buf,
-	unsigned int	len);
-void
-hfa384x_copy_from_aux(
-	hfa384x_t *hw,
-	u32	cardaddr,
-	u32	auxctl,
-	void	*buf,
-	unsigned int	len);
-void
-hfa384x_copy_to_aux(
-	hfa384x_t *hw,
-	u32	cardaddr,
-	u32	auxctl,
-	void	*buf,
-	unsigned int	len);
+hfa384x_cmd_download(hfa384x_t *hw,
+		     u16 mode, u16 lowaddr, u16 highaddr, u16 codelen);
 
 #endif /* __KERNEL__ */
 
-#endif  /* _HFA384x_H */
+#endif /* _HFA384x_H */
diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c
index 8a75b50..888198c 100644
--- a/drivers/staging/wlan-ng/hfa384x_usb.c
+++ b/drivers/staging/wlan-ng/hfa384x_usb.c
@@ -110,10 +110,6 @@
 * --------------------------------------------------------------------
 */
 
-/*================================================================*/
-/* System Includes */
-#define WLAN_DBVAR	prism2_debug
-
 #include <linux/version.h>
 
 #include <linux/module.h>
@@ -130,8 +126,7 @@
 #include <asm/bitops.h>
 #include <linux/list.h>
 #include <linux/usb.h>
-
-#include "wlan_compat.h"
+#include <linux/byteorder/generic.h>
 
 #define SUBMIT_URB(u,f)  usb_submit_urb(u,f)
 
@@ -150,69 +145,43 @@
 #include "hfa384x.h"
 #include "prism2mgmt.h"
 
-/*================================================================*/
-/* Local Constants */
-
-enum cmd_mode
-{
-  DOWAIT = 0,
-  DOASYNC
+enum cmd_mode {
+	DOWAIT = 0,
+	DOASYNC
 };
 typedef enum cmd_mode CMD_MODE;
 
 #define THROTTLE_JIFFIES	(HZ/8)
-
-/*================================================================*/
-/* Local Macros */
+#define URB_ASYNC_UNLINK 0
+#define USB_QUEUE_BULK 0
 
 #define ROUNDUP64(a) (((a)+63)&~63)
 
-/*================================================================*/
-/* Local Types */
-
-/*================================================================*/
-/* Local Static Definitions */
-extern int prism2_debug;
-
-/*================================================================*/
-/* Local Function Declarations */
-
 #ifdef DEBUG_USB
-static void
-dbprint_urb(struct urb* urb);
+static void dbprint_urb(struct urb *urb);
 #endif
 
 static void
-hfa384x_int_rxmonitor(
-	wlandevice_t *wlandev,
-	hfa384x_usb_rxfrm_t *rxfrm);
+hfa384x_int_rxmonitor(wlandevice_t *wlandev, hfa384x_usb_rxfrm_t *rxfrm);
 
-static void
-hfa384x_usb_defer(struct work_struct *data);
+static void hfa384x_usb_defer(struct work_struct *data);
 
-static int
-submit_rx_urb(hfa384x_t *hw, gfp_t flags);
+static int submit_rx_urb(hfa384x_t *hw, gfp_t flags);
 
-static int
-submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t flags);
+static int submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t flags);
 
 /*---------------------------------------------------*/
 /* Callbacks */
-static void
-hfa384x_usbout_callback(struct urb *urb);
-static void
-hfa384x_ctlxout_callback(struct urb *urb);
-static void
-hfa384x_usbin_callback(struct urb *urb);
+static void hfa384x_usbout_callback(struct urb *urb);
+static void hfa384x_ctlxout_callback(struct urb *urb);
+static void hfa384x_usbin_callback(struct urb *urb);
 
 static void
 hfa384x_usbin_txcompl(wlandevice_t *wlandev, hfa384x_usbin_t *usbin);
 
-static void
-hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb);
+static void hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb);
 
-static void
-hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin);
+static void hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin);
 
 static void
 hfa384x_usbout_tx(wlandevice_t *wlandev, hfa384x_usbout_t *usbout);
@@ -223,123 +192,94 @@
 /*---------------------------------------------------*/
 /* Functions to support the prism2 usb command queue */
 
-static void
-hfa384x_usbctlxq_run(hfa384x_t *hw);
+static void hfa384x_usbctlxq_run(hfa384x_t *hw);
 
-static void
-hfa384x_usbctlx_reqtimerfn(unsigned long data);
+static void hfa384x_usbctlx_reqtimerfn(unsigned long data);
 
-static void
-hfa384x_usbctlx_resptimerfn(unsigned long data);
+static void hfa384x_usbctlx_resptimerfn(unsigned long data);
 
-static void
-hfa384x_usb_throttlefn(unsigned long data);
+static void hfa384x_usb_throttlefn(unsigned long data);
 
-static void
-hfa384x_usbctlx_completion_task(unsigned long data);
+static void hfa384x_usbctlx_completion_task(unsigned long data);
 
-static void
-hfa384x_usbctlx_reaper_task(unsigned long data);
+static void hfa384x_usbctlx_reaper_task(unsigned long data);
 
-static int
-hfa384x_usbctlx_submit(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx);
+static int hfa384x_usbctlx_submit(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx);
 
-static void
-unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx);
+static void unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx);
 
-struct usbctlx_completor
-{
-	int (*complete)(struct usbctlx_completor*);
+struct usbctlx_completor {
+	int (*complete) (struct usbctlx_completor *);
 };
 typedef struct usbctlx_completor usbctlx_completor_t;
 
 static int
 hfa384x_usbctlx_complete_sync(hfa384x_t *hw,
-                              hfa384x_usbctlx_t *ctlx,
-                              usbctlx_completor_t *completor);
+			      hfa384x_usbctlx_t *ctlx,
+			      usbctlx_completor_t *completor);
 
 static int
 unlocked_usbctlx_cancel_async(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx);
 
-static void
-hfa384x_cb_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx);
+static void hfa384x_cb_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx);
 
-static void
-hfa384x_cb_rrid(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx);
+static void hfa384x_cb_rrid(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx);
 
 static int
 usbctlx_get_status(const hfa384x_usb_cmdresp_t *cmdresp,
-                   hfa384x_cmdresult_t *result);
+		   hfa384x_cmdresult_t *result);
 
 static void
 usbctlx_get_rridresult(const hfa384x_usb_rridresp_t *rridresp,
-                       hfa384x_rridresult_t *result);
+		       hfa384x_rridresult_t *result);
 
 /*---------------------------------------------------*/
 /* Low level req/resp CTLX formatters and submitters */
 static int
-hfa384x_docmd(
-	hfa384x_t *hw,
-	CMD_MODE mode,
-	hfa384x_metacmd_t *cmd,
-	ctlx_cmdcb_t cmdcb,
-	ctlx_usercb_t usercb,
-	void	*usercb_data);
+hfa384x_docmd(hfa384x_t *hw,
+	      CMD_MODE mode,
+	      hfa384x_metacmd_t *cmd,
+	      ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
 
 static int
-hfa384x_dorrid(
-	hfa384x_t *hw,
-	CMD_MODE mode,
-	u16	rid,
-	void	*riddata,
-	unsigned int	riddatalen,
-	ctlx_cmdcb_t cmdcb,
-	ctlx_usercb_t usercb,
-	void	*usercb_data);
+hfa384x_dorrid(hfa384x_t *hw,
+	       CMD_MODE mode,
+	       u16 rid,
+	       void *riddata,
+	       unsigned int riddatalen,
+	       ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
 
 static int
-hfa384x_dowrid(
-	hfa384x_t *hw,
-	CMD_MODE mode,
-	u16	rid,
-	void	*riddata,
-	unsigned int	riddatalen,
-	ctlx_cmdcb_t cmdcb,
-	ctlx_usercb_t usercb,
-	void	*usercb_data);
+hfa384x_dowrid(hfa384x_t *hw,
+	       CMD_MODE mode,
+	       u16 rid,
+	       void *riddata,
+	       unsigned int riddatalen,
+	       ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
 
 static int
-hfa384x_dormem(
-	hfa384x_t *hw,
-	CMD_MODE mode,
-	u16	page,
-	u16	offset,
-	void	*data,
-	unsigned int	len,
-	ctlx_cmdcb_t cmdcb,
-	ctlx_usercb_t usercb,
-	void	*usercb_data);
+hfa384x_dormem(hfa384x_t *hw,
+	       CMD_MODE mode,
+	       u16 page,
+	       u16 offset,
+	       void *data,
+	       unsigned int len,
+	       ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
 
 static int
-hfa384x_dowmem(
-	hfa384x_t *hw,
-	CMD_MODE mode,
-	u16	page,
-	u16	offset,
-	void	*data,
-	unsigned int	len,
-	ctlx_cmdcb_t cmdcb,
-	ctlx_usercb_t usercb,
-	void	*usercb_data);
+hfa384x_dowmem(hfa384x_t *hw,
+	       CMD_MODE mode,
+	       u16 page,
+	       u16 offset,
+	       void *data,
+	       unsigned int len,
+	       ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
 
-static int
-hfa384x_isgood_pdrcode(u16 pdrcode);
+static int hfa384x_isgood_pdrcode(u16 pdrcode);
 
-/*================================================================*/
-/* Function Definitions */
-static inline const char* ctlxstr(CTLX_STATE s)
+static inline const char *ctlxstr(CTLX_STATE s)
 {
-	static const char* ctlx_str[] = {
+	static const char *ctlx_str[] = {
 		"Initial state",
 		"Complete",
 		"Request failed",
@@ -352,36 +292,36 @@
 	return ctlx_str[s];
 };
 
-
-static inline hfa384x_usbctlx_t*
-get_active_ctlx(hfa384x_t *hw)
+static inline hfa384x_usbctlx_t *get_active_ctlx(hfa384x_t *hw)
 {
 	return list_entry(hw->ctlxq.active.next, hfa384x_usbctlx_t, list);
 }
 
-
 #ifdef DEBUG_USB
-void
-dbprint_urb(struct urb* urb)
+void dbprint_urb(struct urb *urb)
 {
-	WLAN_LOG_DEBUG(3,"urb->pipe=0x%08x\n", urb->pipe);
-	WLAN_LOG_DEBUG(3,"urb->status=0x%08x\n", urb->status);
-	WLAN_LOG_DEBUG(3,"urb->transfer_flags=0x%08x\n", urb->transfer_flags);
-	WLAN_LOG_DEBUG(3,"urb->transfer_buffer=0x%08x\n", (unsigned int)urb->transfer_buffer);
-	WLAN_LOG_DEBUG(3,"urb->transfer_buffer_length=0x%08x\n", urb->transfer_buffer_length);
-	WLAN_LOG_DEBUG(3,"urb->actual_length=0x%08x\n", urb->actual_length);
-	WLAN_LOG_DEBUG(3,"urb->bandwidth=0x%08x\n", urb->bandwidth);
-	WLAN_LOG_DEBUG(3,"urb->setup_packet(ctl)=0x%08x\n", (unsigned int)urb->setup_packet);
-	WLAN_LOG_DEBUG(3,"urb->start_frame(iso/irq)=0x%08x\n", urb->start_frame);
-	WLAN_LOG_DEBUG(3,"urb->interval(irq)=0x%08x\n", urb->interval);
-	WLAN_LOG_DEBUG(3,"urb->error_count(iso)=0x%08x\n", urb->error_count);
-	WLAN_LOG_DEBUG(3,"urb->timeout=0x%08x\n", urb->timeout);
-	WLAN_LOG_DEBUG(3,"urb->context=0x%08x\n", (unsigned int)urb->context);
-	WLAN_LOG_DEBUG(3,"urb->complete=0x%08x\n", (unsigned int)urb->complete);
+	pr_debug("urb->pipe=0x%08x\n", urb->pipe);
+	pr_debug("urb->status=0x%08x\n", urb->status);
+	pr_debug("urb->transfer_flags=0x%08x\n", urb->transfer_flags);
+	pr_debug("urb->transfer_buffer=0x%08x\n",
+	       (unsigned int)urb->transfer_buffer);
+	pr_debug("urb->transfer_buffer_length=0x%08x\n",
+	       urb->transfer_buffer_length);
+	pr_debug("urb->actual_length=0x%08x\n", urb->actual_length);
+	pr_debug("urb->bandwidth=0x%08x\n", urb->bandwidth);
+	pr_debug("urb->setup_packet(ctl)=0x%08x\n",
+	       (unsigned int)urb->setup_packet);
+	pr_debug("urb->start_frame(iso/irq)=0x%08x\n",
+	       urb->start_frame);
+	pr_debug("urb->interval(irq)=0x%08x\n", urb->interval);
+	pr_debug("urb->error_count(iso)=0x%08x\n", urb->error_count);
+	pr_debug("urb->timeout=0x%08x\n", urb->timeout);
+	pr_debug("urb->context=0x%08x\n", (unsigned int)urb->context);
+	pr_debug("urb->complete=0x%08x\n",
+	       (unsigned int)urb->complete);
 }
 #endif
 
-
 /*----------------------------------------------------------------
 * submit_rx_urb
 *
@@ -398,14 +338,11 @@
 * Call context:
 *	Any
 ----------------------------------------------------------------*/
-static int
-submit_rx_urb(hfa384x_t *hw, gfp_t memflags)
+static int submit_rx_urb(hfa384x_t *hw, gfp_t memflags)
 {
 	struct sk_buff *skb;
 	int result;
 
-	DBFENTER;
-
 	skb = dev_alloc_skb(sizeof(hfa384x_usbin_t));
 	if (skb == NULL) {
 		result = -ENOMEM;
@@ -414,21 +351,22 @@
 
 	/* Post the IN urb */
 	usb_fill_bulk_urb(&hw->rx_urb, hw->usb,
-	              hw->endp_in,
-	              skb->data, sizeof(hfa384x_usbin_t),
-	              hfa384x_usbin_callback, hw->wlandev);
+			  hw->endp_in,
+			  skb->data, sizeof(hfa384x_usbin_t),
+			  hfa384x_usbin_callback, hw->wlandev);
 
 	hw->rx_urb_skb = skb;
 
 	result = -ENOLINK;
-	if ( !hw->wlandev->hwremoved && !test_bit(WORK_RX_HALT, &hw->usb_flags)) {
+	if (!hw->wlandev->hwremoved && !test_bit(WORK_RX_HALT, &hw->usb_flags)) {
 		result = SUBMIT_URB(&hw->rx_urb, memflags);
 
 		/* Check whether we need to reset the RX pipe */
 		if (result == -EPIPE) {
-			WLAN_LOG_WARNING("%s rx pipe stalled: requesting reset\n",
-			                 hw->wlandev->netdev->name);
-			if ( !test_and_set_bit(WORK_RX_HALT, &hw->usb_flags) )
+			printk(KERN_WARNING
+			       "%s rx pipe stalled: requesting reset\n",
+			       hw->wlandev->netdev->name);
+			if (!test_and_set_bit(WORK_RX_HALT, &hw->usb_flags))
 				schedule_work(&hw->usb_work);
 		}
 	}
@@ -439,9 +377,7 @@
 		hw->rx_urb_skb = NULL;
 	}
 
- done:
-
-	DBFEXIT;
+done:
 	return result;
 }
 
@@ -463,24 +399,23 @@
 * Call context:
 *	Any
 ----------------------------------------------------------------*/
-static int
-submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t memflags)
+static int submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t memflags)
 {
 	struct net_device *netdev = hw->wlandev->netdev;
 	int result;
 
-	DBFENTER;
-
 	result = -ENOLINK;
-	if ( netif_running(netdev) ) {
+	if (netif_running(netdev)) {
 
-		if ( !hw->wlandev->hwremoved && !test_bit(WORK_TX_HALT, &hw->usb_flags) ) {
+		if (!hw->wlandev->hwremoved
+		    && !test_bit(WORK_TX_HALT, &hw->usb_flags)) {
 			result = SUBMIT_URB(tx_urb, memflags);
 
 			/* Test whether we need to reset the TX pipe */
 			if (result == -EPIPE) {
-				WLAN_LOG_WARNING("%s tx pipe stalled: requesting reset\n",
-				                 netdev->name);
+				printk(KERN_WARNING
+				       "%s tx pipe stalled: requesting reset\n",
+				       netdev->name);
 				set_bit(WORK_TX_HALT, &hw->usb_flags);
 				schedule_work(&hw->usb_work);
 			} else if (result == 0) {
@@ -489,8 +424,6 @@
 		}
 	}
 
-	DBFEXIT;
-
 	return result;
 }
 
@@ -510,27 +443,22 @@
 * Call context:
 *	process (by design)
 ----------------------------------------------------------------*/
-static void
-hfa384x_usb_defer(struct work_struct *data)
+static void hfa384x_usb_defer(struct work_struct *data)
 {
 	hfa384x_t *hw = container_of(data, struct hfa384x, usb_work);
 	struct net_device *netdev = hw->wlandev->netdev;
 
-	DBFENTER;
-
 	/* Don't bother trying to reset anything if the plug
 	 * has been pulled ...
 	 */
-	if ( hw->wlandev->hwremoved ) {
-		DBFEXIT;
+	if (hw->wlandev->hwremoved)
 		return;
-	}
 
 	/* Reception has stopped: try to reset the input pipe */
 	if (test_bit(WORK_RX_HALT, &hw->usb_flags)) {
 		int ret;
 
-		usb_kill_urb(&hw->rx_urb);  /* Cannot be holding spinlock! */
+		usb_kill_urb(&hw->rx_urb);	/* Cannot be holding spinlock! */
 
 		ret = usb_clear_halt(hw->usb, hw->endp_in);
 		if (ret != 0) {
@@ -539,14 +467,14 @@
 			       netdev->name, ret);
 		} else {
 			printk(KERN_INFO "%s rx pipe reset complete.\n",
-			                 netdev->name);
+			       netdev->name);
 			clear_bit(WORK_RX_HALT, &hw->usb_flags);
 			set_bit(WORK_RX_RESUME, &hw->usb_flags);
 		}
 	}
 
 	/* Resume receiving data back from the device. */
-	if ( test_bit(WORK_RX_RESUME, &hw->usb_flags) ) {
+	if (test_bit(WORK_RX_RESUME, &hw->usb_flags)) {
 		int ret;
 
 		ret = submit_rx_urb(hw, GFP_KERNEL);
@@ -570,7 +498,7 @@
 			       netdev->name, ret);
 		} else {
 			printk(KERN_INFO "%s tx pipe reset complete.\n",
-			                 netdev->name);
+			       netdev->name);
 			clear_bit(WORK_TX_HALT, &hw->usb_flags);
 			set_bit(WORK_TX_RESUME, &hw->usb_flags);
 
@@ -583,14 +511,10 @@
 	}
 
 	/* Resume transmitting. */
-	if ( test_and_clear_bit(WORK_TX_RESUME, &hw->usb_flags) ) {
+	if (test_and_clear_bit(WORK_TX_RESUME, &hw->usb_flags))
 		netif_wake_queue(hw->wlandev->netdev);
-	}
-
-	DBFEXIT;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_create
 *
@@ -612,11 +536,8 @@
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-void
-hfa384x_create( hfa384x_t *hw, struct usb_device *usb)
+void hfa384x_create(hfa384x_t *hw, struct usb_device *usb)
 {
-	DBFENTER;
-
 	memset(hw, 0, sizeof(hfa384x_t));
 	hw->usb = usb;
 
@@ -638,11 +559,9 @@
 	skb_queue_head_init(&hw->authq);
 
 	tasklet_init(&hw->reaper_bh,
-	             hfa384x_usbctlx_reaper_task,
-	             (unsigned long)hw);
+		     hfa384x_usbctlx_reaper_task, (unsigned long)hw);
 	tasklet_init(&hw->completion_bh,
-	             hfa384x_usbctlx_completion_task,
-	             (unsigned long)hw);
+		     hfa384x_usbctlx_completion_task, (unsigned long)hw);
 	INIT_WORK(&hw->link_bh, prism2sta_processing_defer);
 	INIT_WORK(&hw->usb_work, hfa384x_usb_defer);
 
@@ -665,15 +584,12 @@
 	hw->link_status = HFA384x_LINK_NOTCONNECTED;
 	hw->state = HFA384x_STATE_INIT;
 
-        INIT_WORK(&hw->commsqual_bh, prism2sta_commsqual_defer);
+	INIT_WORK(&hw->commsqual_bh, prism2sta_commsqual_defer);
 	init_timer(&hw->commsqual_timer);
-	hw->commsqual_timer.data = (unsigned long) hw;
+	hw->commsqual_timer.data = (unsigned long)hw;
 	hw->commsqual_timer.function = prism2sta_commsqual_timer;
-
-	DBFEXIT;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_destroy
 *
@@ -696,16 +612,12 @@
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-void
-hfa384x_destroy( hfa384x_t *hw)
+void hfa384x_destroy(hfa384x_t *hw)
 {
 	struct sk_buff *skb;
 
-	DBFENTER;
-
-	if ( hw->state == HFA384x_STATE_RUNNING ) {
+	if (hw->state == HFA384x_STATE_RUNNING)
 		hfa384x_drvr_stop(hw);
-	}
 	hw->state = HFA384x_STATE_PREINIT;
 
 	if (hw->scanresults) {
@@ -714,23 +626,16 @@
 	}
 
 	/* Now to clean out the auth queue */
-        while ( (skb = skb_dequeue(&hw->authq)) ) {
-                dev_kfree_skb(skb);
-        }
-
-	DBFEXIT;
+	while ((skb = skb_dequeue(&hw->authq)))
+		dev_kfree_skb(skb);
 }
 
-
-/*----------------------------------------------------------------
- */
-static hfa384x_usbctlx_t* usbctlx_alloc(void)
+static hfa384x_usbctlx_t *usbctlx_alloc(void)
 {
 	hfa384x_usbctlx_t *ctlx;
 
 	ctlx = kmalloc(sizeof(*ctlx), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
-	if (ctlx != NULL)
-	{
+	if (ctlx != NULL) {
 		memset(ctlx, 0, sizeof(*ctlx));
 		init_completion(&ctlx->done);
 	}
@@ -738,70 +643,58 @@
 	return ctlx;
 }
 
-
-/*----------------------------------------------------------------
- *
-----------------------------------------------------------------*/
 static int
 usbctlx_get_status(const hfa384x_usb_cmdresp_t *cmdresp,
-                   hfa384x_cmdresult_t *result)
+		   hfa384x_cmdresult_t *result)
 {
-	DBFENTER;
+	result->status = le16_to_cpu(cmdresp->status);
+	result->resp0 = le16_to_cpu(cmdresp->resp0);
+	result->resp1 = le16_to_cpu(cmdresp->resp1);
+	result->resp2 = le16_to_cpu(cmdresp->resp2);
 
-	result->status = hfa384x2host_16(cmdresp->status);
-	result->resp0 = hfa384x2host_16(cmdresp->resp0);
-	result->resp1 = hfa384x2host_16(cmdresp->resp1);
-	result->resp2 = hfa384x2host_16(cmdresp->resp2);
+	pr_debug("cmdresult:status=0x%04x "
+	       "resp0=0x%04x resp1=0x%04x resp2=0x%04x\n",
+	       result->status, result->resp0, result->resp1, result->resp2);
 
-	WLAN_LOG_DEBUG(4, "cmdresult:status=0x%04x "
-	                  "resp0=0x%04x resp1=0x%04x resp2=0x%04x\n",
-	                result->status,
-	                result->resp0,
-	                result->resp1,
-	                result->resp2);
-
-	DBFEXIT;
-	return (result->status & HFA384x_STATUS_RESULT);
+	return result->status & HFA384x_STATUS_RESULT;
 }
 
 static void
 usbctlx_get_rridresult(const hfa384x_usb_rridresp_t *rridresp,
-                       hfa384x_rridresult_t *result)
+		       hfa384x_rridresult_t *result)
 {
-	DBFENTER;
-
-	result->rid = hfa384x2host_16(rridresp->rid);
+	result->rid = le16_to_cpu(rridresp->rid);
 	result->riddata = rridresp->data;
-	result->riddata_len = ((hfa384x2host_16(rridresp->frmlen) - 1) * 2);
+	result->riddata_len = ((le16_to_cpu(rridresp->frmlen) - 1) * 2);
 
-	DBFEXIT;
 }
 
-
 /*----------------------------------------------------------------
 * Completor object:
 * This completor must be passed to hfa384x_usbctlx_complete_sync()
 * when processing a CTLX that returns a hfa384x_cmdresult_t structure.
 ----------------------------------------------------------------*/
-struct usbctlx_cmd_completor
-{
-	usbctlx_completor_t	head;
+struct usbctlx_cmd_completor {
+	usbctlx_completor_t head;
 
-	const hfa384x_usb_cmdresp_t	*cmdresp;
-	hfa384x_cmdresult_t	*result;
+	const hfa384x_usb_cmdresp_t *cmdresp;
+	hfa384x_cmdresult_t *result;
 };
 typedef struct usbctlx_cmd_completor usbctlx_cmd_completor_t;
 
 static int usbctlx_cmd_completor_fn(usbctlx_completor_t *head)
 {
-	usbctlx_cmd_completor_t *complete = (usbctlx_cmd_completor_t*)head;
+	usbctlx_cmd_completor_t *complete = (usbctlx_cmd_completor_t *) head;
 	return usbctlx_get_status(complete->cmdresp, complete->result);
 }
 
-static inline usbctlx_completor_t*
-init_cmd_completor(usbctlx_cmd_completor_t *completor,
-                   const hfa384x_usb_cmdresp_t *cmdresp,
-                   hfa384x_cmdresult_t *result)
+static inline usbctlx_completor_t *init_cmd_completor(usbctlx_cmd_completor_t *
+						      completor,
+						      const
+						      hfa384x_usb_cmdresp_t *
+						      cmdresp,
+						      hfa384x_cmdresult_t *
+						      result)
 {
 	completor->head.complete = usbctlx_cmd_completor_fn;
 	completor->cmdresp = cmdresp;
@@ -814,44 +707,41 @@
 * This completor must be passed to hfa384x_usbctlx_complete_sync()
 * when processing a CTLX that reads a RID.
 ----------------------------------------------------------------*/
-struct usbctlx_rrid_completor
-{
-	usbctlx_completor_t	head;
+struct usbctlx_rrid_completor {
+	usbctlx_completor_t head;
 
-	const hfa384x_usb_rridresp_t	*rridresp;
-	void			*riddata;
-	unsigned int			riddatalen;
+	const hfa384x_usb_rridresp_t *rridresp;
+	void *riddata;
+	unsigned int riddatalen;
 };
 typedef struct usbctlx_rrid_completor usbctlx_rrid_completor_t;
 
 static int usbctlx_rrid_completor_fn(usbctlx_completor_t *head)
 {
-	usbctlx_rrid_completor_t *complete = (usbctlx_rrid_completor_t*)head;
+	usbctlx_rrid_completor_t *complete = (usbctlx_rrid_completor_t *) head;
 	hfa384x_rridresult_t rridresult;
 
 	usbctlx_get_rridresult(complete->rridresp, &rridresult);
 
 	/* Validate the length, note body len calculation in bytes */
-	if ( rridresult.riddata_len != complete->riddatalen ) {
-		WLAN_LOG_WARNING(
-			"RID len mismatch, rid=0x%04x hlen=%d fwlen=%d\n",
-		        rridresult.rid,
-		        complete->riddatalen,
-		        rridresult.riddata_len);
+	if (rridresult.riddata_len != complete->riddatalen) {
+		printk(KERN_WARNING
+		       "RID len mismatch, rid=0x%04x hlen=%d fwlen=%d\n",
+		       rridresult.rid,
+		       complete->riddatalen, rridresult.riddata_len);
 		return -ENODATA;
 	}
 
-	memcpy(complete->riddata,
-	       rridresult.riddata,
-	       complete->riddatalen);
+	memcpy(complete->riddata, rridresult.riddata, complete->riddatalen);
 	return 0;
 }
 
-static inline usbctlx_completor_t*
-init_rrid_completor(usbctlx_rrid_completor_t *completor,
-                    const hfa384x_usb_rridresp_t *rridresp,
-                    void *riddata,
-                    unsigned int riddatalen)
+static inline usbctlx_completor_t *init_rrid_completor(usbctlx_rrid_completor_t
+						       *completor,
+						       const
+						       hfa384x_usb_rridresp_t *
+						       rridresp, void *riddata,
+						       unsigned int riddatalen)
 {
 	completor->head.complete = usbctlx_rrid_completor_fn;
 	completor->rridresp = rridresp;
@@ -878,30 +768,29 @@
 * Completor object:
 * Interprets the results of a synchronous memory-read
 ----------------------------------------------------------------*/
-struct usbctlx_rmem_completor
-{
-        usbctlx_completor_t           head;
+struct usbctlx_rmem_completor {
+	usbctlx_completor_t head;
 
-        const hfa384x_usb_rmemresp_t  *rmemresp;
-        void                          *data;
-        unsigned int                          len;
+	const hfa384x_usb_rmemresp_t *rmemresp;
+	void *data;
+	unsigned int len;
 };
 typedef struct usbctlx_rmem_completor usbctlx_rmem_completor_t;
 
 static int usbctlx_rmem_completor_fn(usbctlx_completor_t *head)
 {
-	usbctlx_rmem_completor_t *complete = (usbctlx_rmem_completor_t*)head;
+	usbctlx_rmem_completor_t *complete = (usbctlx_rmem_completor_t *) head;
 
-	WLAN_LOG_DEBUG(4,"rmemresp:len=%d\n", complete->rmemresp->frmlen);
+	pr_debug("rmemresp:len=%d\n", complete->rmemresp->frmlen);
 	memcpy(complete->data, complete->rmemresp->data, complete->len);
 	return 0;
 }
 
-static inline usbctlx_completor_t*
-init_rmem_completor(usbctlx_rmem_completor_t *completor,
-                    hfa384x_usb_rmemresp_t *rmemresp,
-                    void *data,
-                    unsigned int len)
+static inline usbctlx_completor_t *init_rmem_completor(usbctlx_rmem_completor_t
+						       *completor,
+						       hfa384x_usb_rmemresp_t
+                                                       *rmemresp, void *data,
+						       unsigned int len)
 {
 	completor->head.complete = usbctlx_rmem_completor_fn;
 	completor->rmemresp = rmemresp;
@@ -931,28 +820,23 @@
 * Call context:
 *	interrupt
 ----------------------------------------------------------------*/
-static void
-hfa384x_cb_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx)
+static void hfa384x_cb_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx)
 {
-	DBFENTER;
-
-	if ( ctlx->usercb != NULL ) {
+	if (ctlx->usercb != NULL) {
 		hfa384x_cmdresult_t cmdresult;
 
 		if (ctlx->state != CTLX_COMPLETE) {
 			memset(&cmdresult, 0, sizeof(cmdresult));
-			cmdresult.status = HFA384x_STATUS_RESULT_SET(HFA384x_CMD_ERR);
+			cmdresult.status =
+			    HFA384x_STATUS_RESULT_SET(HFA384x_CMD_ERR);
 		} else {
 			usbctlx_get_status(&ctlx->inbuf.cmdresp, &cmdresult);
 		}
 
 		ctlx->usercb(hw, &cmdresult, ctlx->usercb_data);
 	}
-
-	DBFEXIT;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_cb_rrid
 *
@@ -973,132 +857,114 @@
 * Call context:
 *	interrupt
 ----------------------------------------------------------------*/
-static void
-hfa384x_cb_rrid(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx)
+static void hfa384x_cb_rrid(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx)
 {
-	DBFENTER;
-
-	if ( ctlx->usercb != NULL ) {
+	if (ctlx->usercb != NULL) {
 		hfa384x_rridresult_t rridresult;
 
 		if (ctlx->state != CTLX_COMPLETE) {
 			memset(&rridresult, 0, sizeof(rridresult));
-			rridresult.rid = hfa384x2host_16(ctlx->outbuf.rridreq.rid);
+			rridresult.rid =
+			    le16_to_cpu(ctlx->outbuf.rridreq.rid);
 		} else {
-			usbctlx_get_rridresult(&ctlx->inbuf.rridresp, &rridresult);
+			usbctlx_get_rridresult(&ctlx->inbuf.rridresp,
+					       &rridresult);
 		}
 
 		ctlx->usercb(hw, &rridresult, ctlx->usercb_data);
 	}
-
-	DBFEXIT;
 }
 
-static inline int
-hfa384x_docmd_wait(hfa384x_t *hw, hfa384x_metacmd_t *cmd)
+static inline int hfa384x_docmd_wait(hfa384x_t *hw, hfa384x_metacmd_t *cmd)
 {
 	return hfa384x_docmd(hw, DOWAIT, cmd, NULL, NULL, NULL);
 }
 
 static inline int
 hfa384x_docmd_async(hfa384x_t *hw,
-                    hfa384x_metacmd_t *cmd,
-                    ctlx_cmdcb_t cmdcb,
-                    ctlx_usercb_t usercb,
-                    void *usercb_data)
+		    hfa384x_metacmd_t *cmd,
+		    ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
 {
-	return hfa384x_docmd(hw, DOASYNC, cmd,
-	                        cmdcb, usercb, usercb_data);
+	return hfa384x_docmd(hw, DOASYNC, cmd, cmdcb, usercb, usercb_data);
 }
 
 static inline int
-hfa384x_dorrid_wait(hfa384x_t *hw, u16 rid, void *riddata, unsigned int riddatalen)
+hfa384x_dorrid_wait(hfa384x_t *hw, u16 rid, void *riddata,
+		    unsigned int riddatalen)
 {
 	return hfa384x_dorrid(hw, DOWAIT,
-	                      rid, riddata, riddatalen,
-	                      NULL, NULL, NULL);
+			      rid, riddata, riddatalen, NULL, NULL, NULL);
 }
 
 static inline int
 hfa384x_dorrid_async(hfa384x_t *hw,
-                     u16 rid, void *riddata, unsigned int riddatalen,
-                     ctlx_cmdcb_t cmdcb,
-                     ctlx_usercb_t usercb,
-                     void *usercb_data)
+		     u16 rid, void *riddata, unsigned int riddatalen,
+		     ctlx_cmdcb_t cmdcb,
+		     ctlx_usercb_t usercb, void *usercb_data)
 {
 	return hfa384x_dorrid(hw, DOASYNC,
-	                      rid, riddata, riddatalen,
-	                      cmdcb, usercb, usercb_data);
+			      rid, riddata, riddatalen,
+			      cmdcb, usercb, usercb_data);
 }
 
 static inline int
-hfa384x_dowrid_wait(hfa384x_t *hw, u16 rid, void *riddata, unsigned int riddatalen)
+hfa384x_dowrid_wait(hfa384x_t *hw, u16 rid, void *riddata,
+		    unsigned int riddatalen)
 {
 	return hfa384x_dowrid(hw, DOWAIT,
-	                      rid, riddata, riddatalen,
-	                      NULL, NULL, NULL);
+			      rid, riddata, riddatalen, NULL, NULL, NULL);
 }
 
 static inline int
 hfa384x_dowrid_async(hfa384x_t *hw,
-                     u16 rid, void *riddata, unsigned int riddatalen,
-                     ctlx_cmdcb_t cmdcb,
-                     ctlx_usercb_t usercb,
-                     void *usercb_data)
+		     u16 rid, void *riddata, unsigned int riddatalen,
+		     ctlx_cmdcb_t cmdcb,
+		     ctlx_usercb_t usercb, void *usercb_data)
 {
 	return hfa384x_dowrid(hw, DOASYNC,
-	                      rid, riddata, riddatalen,
-	                      cmdcb, usercb, usercb_data);
+			      rid, riddata, riddatalen,
+			      cmdcb, usercb, usercb_data);
 }
 
 static inline int
 hfa384x_dormem_wait(hfa384x_t *hw,
-                    u16 page, u16 offset, void *data, unsigned int len)
+		    u16 page, u16 offset, void *data, unsigned int len)
 {
 	return hfa384x_dormem(hw, DOWAIT,
-	                      page, offset, data, len,
-	                      NULL, NULL, NULL);
+			      page, offset, data, len, NULL, NULL, NULL);
 }
 
 static inline int
 hfa384x_dormem_async(hfa384x_t *hw,
-                     u16 page, u16 offset, void *data, unsigned int len,
-                     ctlx_cmdcb_t cmdcb,
-                     ctlx_usercb_t usercb,
-                     void *usercb_data)
+		     u16 page, u16 offset, void *data, unsigned int len,
+		     ctlx_cmdcb_t cmdcb,
+		     ctlx_usercb_t usercb, void *usercb_data)
 {
 	return hfa384x_dormem(hw, DOASYNC,
-	                      page, offset, data, len,
-	                      cmdcb, usercb, usercb_data);
+			      page, offset, data, len,
+			      cmdcb, usercb, usercb_data);
 }
 
 static inline int
-hfa384x_dowmem_wait(
-        hfa384x_t *hw,
-        u16  page,
-        u16  offset,
-        void    *data,
-        unsigned int    len)
+hfa384x_dowmem_wait(hfa384x_t *hw,
+		    u16 page, u16 offset, void *data, unsigned int len)
 {
 	return hfa384x_dowmem(hw, DOWAIT,
-                                  page, offset, data, len,
-	                          NULL, NULL, NULL);
+			      page, offset, data, len, NULL, NULL, NULL);
 }
 
 static inline int
-hfa384x_dowmem_async(
-        hfa384x_t *hw,
-        u16  page,
-        u16  offset,
-        void    *data,
-        unsigned int    len,
-        ctlx_cmdcb_t cmdcb,
-        ctlx_usercb_t usercb,
-        void    *usercb_data)
+hfa384x_dowmem_async(hfa384x_t *hw,
+		     u16 page,
+		     u16 offset,
+		     void *data,
+		     unsigned int len,
+		     ctlx_cmdcb_t cmdcb,
+		     ctlx_usercb_t usercb, void *usercb_data)
 {
 	return hfa384x_dowmem(hw, DOASYNC,
-                                  page, offset, data, len,
-	                          cmdcb, usercb, usercb_data);
+			      page, offset, data, len,
+			      cmdcb, usercb, usercb_data);
 }
 
 /*----------------------------------------------------------------
@@ -1120,16 +986,12 @@
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-int
-hfa384x_cmd_initialize(hfa384x_t *hw)
+int hfa384x_cmd_initialize(hfa384x_t *hw)
 {
-	int	result = 0;
-	int	i;
+	int result = 0;
+	int i;
 	hfa384x_metacmd_t cmd;
 
-	DBFENTER;
-
-
 	cmd.cmd = HFA384x_CMDCODE_INIT;
 	cmd.parm0 = 0;
 	cmd.parm1 = 0;
@@ -1137,27 +999,21 @@
 
 	result = hfa384x_docmd_wait(hw, &cmd);
 
-
-	WLAN_LOG_DEBUG(3,"cmdresp.init: "
-		"status=0x%04x, resp0=0x%04x, "
-		"resp1=0x%04x, resp2=0x%04x\n",
-		cmd.result.status,
-		cmd.result.resp0,
-		cmd.result.resp1,
-		cmd.result.resp2);
-	if ( result == 0 ) {
-		for ( i = 0; i < HFA384x_NUMPORTS_MAX; i++) {
+	pr_debug("cmdresp.init: "
+	       "status=0x%04x, resp0=0x%04x, "
+	       "resp1=0x%04x, resp2=0x%04x\n",
+	       cmd.result.status,
+	       cmd.result.resp0, cmd.result.resp1, cmd.result.resp2);
+	if (result == 0) {
+		for (i = 0; i < HFA384x_NUMPORTS_MAX; i++)
 			hw->port_enabled[i] = 0;
-		}
 	}
 
-        hw->link_status = HFA384x_LINK_NOTCONNECTED;
+	hw->link_status = HFA384x_LINK_NOTCONNECTED;
 
-	DBFEXIT;
 	return result;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_cmd_disable
 *
@@ -1180,24 +1036,20 @@
 ----------------------------------------------------------------*/
 int hfa384x_cmd_disable(hfa384x_t *hw, u16 macport)
 {
-	int	result = 0;
+	int result = 0;
 	hfa384x_metacmd_t cmd;
 
-	DBFENTER;
-
 	cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DISABLE) |
-		  HFA384x_CMD_MACPORT_SET(macport);
+	    HFA384x_CMD_MACPORT_SET(macport);
 	cmd.parm0 = 0;
 	cmd.parm1 = 0;
 	cmd.parm2 = 0;
 
 	result = hfa384x_docmd_wait(hw, &cmd);
 
-	DBFEXIT;
 	return result;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_cmd_enable
 *
@@ -1220,20 +1072,17 @@
 ----------------------------------------------------------------*/
 int hfa384x_cmd_enable(hfa384x_t *hw, u16 macport)
 {
-	int	result = 0;
+	int result = 0;
 	hfa384x_metacmd_t cmd;
 
-	DBFENTER;
-
 	cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ENABLE) |
-		  HFA384x_CMD_MACPORT_SET(macport);
+	    HFA384x_CMD_MACPORT_SET(macport);
 	cmd.parm0 = 0;
 	cmd.parm1 = 0;
 	cmd.parm2 = 0;
 
 	result = hfa384x_docmd_wait(hw, &cmd);
 
-	DBFEXIT;
 	return result;
 }
 
@@ -1268,24 +1117,20 @@
 ----------------------------------------------------------------*/
 int hfa384x_cmd_monitor(hfa384x_t *hw, u16 enable)
 {
-	int	result = 0;
+	int result = 0;
 	hfa384x_metacmd_t cmd;
 
-	DBFENTER;
-
 	cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_MONITOR) |
-		HFA384x_CMD_AINFO_SET(enable);
+	    HFA384x_CMD_AINFO_SET(enable);
 	cmd.parm0 = 0;
 	cmd.parm1 = 0;
 	cmd.parm2 = 0;
 
 	result = hfa384x_docmd_wait(hw, &cmd);
 
-	DBFEXIT;
 	return result;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_cmd_download
 *
@@ -1325,15 +1170,14 @@
 *	process
 ----------------------------------------------------------------*/
 int hfa384x_cmd_download(hfa384x_t *hw, u16 mode, u16 lowaddr,
-				u16 highaddr, u16 codelen)
+			 u16 highaddr, u16 codelen)
 {
-	int	result = 0;
+	int result = 0;
 	hfa384x_metacmd_t cmd;
 
-	DBFENTER;
-	WLAN_LOG_DEBUG(5,
-		"mode=%d, lowaddr=0x%04x, highaddr=0x%04x, codelen=%d\n",
-		mode, lowaddr, highaddr, codelen);
+	printk(KERN_DEBUG
+	       "mode=%d, lowaddr=0x%04x, highaddr=0x%04x, codelen=%d\n",
+	       mode, lowaddr, highaddr, codelen);
 
 	cmd.cmd = (HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DOWNLD) |
 		   HFA384x_CMD_PROGMODE_SET(mode));
@@ -1344,79 +1188,9 @@
 
 	result = hfa384x_docmd_wait(hw, &cmd);
 
-	DBFEXIT;
 	return result;
 }
 
-
-/*----------------------------------------------------------------
-* hfa384x_copy_from_aux
-*
-* Copies a collection of bytes from the controller memory.  The
-* Auxiliary port MUST be enabled prior to calling this function.
-* We _might_ be in a download state.
-*
-* Arguments:
-*	hw		device structure
-*	cardaddr	address in hfa384x data space to read
-*	auxctl		address space select
-*	buf		ptr to destination host buffer
-*	len		length of data to transfer (in bytes)
-*
-* Returns:
-*	nothing
-*
-* Side effects:
-*	buf contains the data copied
-*
-* Call context:
-*	process
-*	interrupt
-----------------------------------------------------------------*/
-void
-hfa384x_copy_from_aux(
-	hfa384x_t *hw, u32 cardaddr, u32 auxctl, void *buf, unsigned int len)
-{
-	DBFENTER;
-	WLAN_LOG_ERROR("not used in USB.\n");
-	DBFEXIT;
-}
-
-
-/*----------------------------------------------------------------
-* hfa384x_copy_to_aux
-*
-* Copies a collection of bytes to the controller memory.  The
-* Auxiliary port MUST be enabled prior to calling this function.
-* We _might_ be in a download state.
-*
-* Arguments:
-*	hw		device structure
-*	cardaddr	address in hfa384x data space to read
-*	auxctl		address space select
-*	buf		ptr to destination host buffer
-*	len		length of data to transfer (in bytes)
-*
-* Returns:
-*	nothing
-*
-* Side effects:
-*	Controller memory now contains a copy of buf
-*
-* Call context:
-*	process
-*	interrupt
-----------------------------------------------------------------*/
-void
-hfa384x_copy_to_aux(
-	hfa384x_t *hw, u32 cardaddr, u32 auxctl, void *buf, unsigned int len)
-{
-	DBFENTER;
-	WLAN_LOG_ERROR("not used in USB.\n");
-	DBFEXIT;
-}
-
-
 /*----------------------------------------------------------------
 * hfa384x_corereset
 *
@@ -1442,20 +1216,17 @@
 ----------------------------------------------------------------*/
 int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis)
 {
-	int 			result = 0;
+	int result = 0;
 
-	DBFENTER;
-
-	result=usb_reset_device(hw->usb);
-	if(result<0) {
-		WLAN_LOG_ERROR("usb_reset_device() failed, result=%d.\n",result);
+	result = usb_reset_device(hw->usb);
+	if (result < 0) {
+		printk(KERN_ERR "usb_reset_device() failed, result=%d.\n",
+		       result);
 	}
 
-	DBFEXIT;
 	return result;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_usbctlx_complete_sync
 *
@@ -1487,8 +1258,6 @@
 	unsigned long flags;
 	int result;
 
-	DBFENTER;
-
 	result = wait_for_completion_interruptible(&ctlx->done);
 
 	spin_lock_irqsave(&hw->ctlxq.lock, flags);
@@ -1497,14 +1266,11 @@
 	 * We can only handle the CTLX if the USB disconnect
 	 * function has not run yet ...
 	 */
-	cleanup:
-	if ( hw->wlandev->hwremoved )
-	{
+cleanup:
+	if (hw->wlandev->hwremoved) {
 		spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
 		result = -ENODEV;
-	}
-	else if ( result != 0 )
-	{
+	} else if (result != 0) {
 		int runqueue = 0;
 
 		/*
@@ -1516,8 +1282,7 @@
 		 * NOTE: We can only delete the timers and
 		 *       the URB if this CTLX is active.
 		 */
-		if (ctlx == get_active_ctlx(hw))
-		{
+		if (ctlx == get_active_ctlx(hw)) {
 			spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
 
 			del_singleshot_timer_sync(&hw->reqtimer);
@@ -1534,7 +1299,7 @@
 			 * This scenario is so unlikely that I'm
 			 * happy with a grubby "goto" solution ...
 			 */
-			if ( hw->wlandev->hwremoved )
+			if (hw->wlandev->hwremoved)
 				goto cleanup;
 		}
 
@@ -1555,9 +1320,9 @@
 		if (ctlx->state == CTLX_COMPLETE) {
 			result = completor->complete(completor);
 		} else {
-			WLAN_LOG_WARNING("CTLX[%d] error: state(%s)\n",
-			                 hfa384x2host_16(ctlx->outbuf.type),
-			                 ctlxstr(ctlx->state));
+			printk(KERN_WARNING "CTLX[%d] error: state(%s)\n",
+			       le16_to_cpu(ctlx->outbuf.type),
+			       ctlxstr(ctlx->state));
 			result = -EIO;
 		}
 
@@ -1566,7 +1331,6 @@
 		kfree(ctlx);
 	}
 
-	DBFEXIT;
 	return result;
 }
 
@@ -1603,39 +1367,32 @@
 *	process
 ----------------------------------------------------------------*/
 static int
-hfa384x_docmd(
-	hfa384x_t *hw,
-	CMD_MODE mode,
-	hfa384x_metacmd_t *cmd,
-	ctlx_cmdcb_t	cmdcb,
-	ctlx_usercb_t	usercb,
-	void	*usercb_data)
+hfa384x_docmd(hfa384x_t *hw,
+	      CMD_MODE mode,
+	      hfa384x_metacmd_t *cmd,
+	      ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
 {
-	int			result;
-	hfa384x_usbctlx_t	*ctlx;
+	int result;
+	hfa384x_usbctlx_t *ctlx;
 
-	DBFENTER;
 	ctlx = usbctlx_alloc();
-	if ( ctlx == NULL ) {
+	if (ctlx == NULL) {
 		result = -ENOMEM;
 		goto done;
 	}
 
 	/* Initialize the command */
-	ctlx->outbuf.cmdreq.type = 	host2hfa384x_16(HFA384x_USB_CMDREQ);
-	ctlx->outbuf.cmdreq.cmd =	host2hfa384x_16(cmd->cmd);
-	ctlx->outbuf.cmdreq.parm0 =	host2hfa384x_16(cmd->parm0);
-	ctlx->outbuf.cmdreq.parm1 =	host2hfa384x_16(cmd->parm1);
-	ctlx->outbuf.cmdreq.parm2 =	host2hfa384x_16(cmd->parm2);
+	ctlx->outbuf.cmdreq.type = cpu_to_le16(HFA384x_USB_CMDREQ);
+	ctlx->outbuf.cmdreq.cmd = cpu_to_le16(cmd->cmd);
+	ctlx->outbuf.cmdreq.parm0 = cpu_to_le16(cmd->parm0);
+	ctlx->outbuf.cmdreq.parm1 = cpu_to_le16(cmd->parm1);
+	ctlx->outbuf.cmdreq.parm2 = cpu_to_le16(cmd->parm2);
 
 	ctlx->outbufsize = sizeof(ctlx->outbuf.cmdreq);
 
-	WLAN_LOG_DEBUG(4, "cmdreq: cmd=0x%04x "
-		"parm0=0x%04x parm1=0x%04x parm2=0x%04x\n",
-		cmd->cmd,
-		cmd->parm0,
-		cmd->parm1,
-		cmd->parm2);
+	pr_debug("cmdreq: cmd=0x%04x "
+	       "parm0=0x%04x parm1=0x%04x parm2=0x%04x\n",
+	       cmd->cmd, cmd->parm0, cmd->parm1, cmd->parm2);
 
 	ctlx->reapable = mode;
 	ctlx->cmdcb = cmdcb;
@@ -1648,18 +1405,20 @@
 	} else if (mode == DOWAIT) {
 		usbctlx_cmd_completor_t completor;
 
-		result = hfa384x_usbctlx_complete_sync(
-		             hw, ctlx, init_cmd_completor(&completor,
-		                                          &ctlx->inbuf.cmdresp,
-		                                          &cmd->result) );
+		result =
+		    hfa384x_usbctlx_complete_sync(hw, ctlx,
+						  init_cmd_completor(&completor,
+								     &ctlx->
+								     inbuf.
+								     cmdresp,
+								     &cmd->
+								     result));
 	}
 
 done:
-	DBFEXIT;
 	return result;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_dorrid
 *
@@ -1697,31 +1456,27 @@
 *	process (DOWAIT or DOASYNC)
 ----------------------------------------------------------------*/
 static int
-hfa384x_dorrid(
-	hfa384x_t *hw,
-	CMD_MODE mode,
-	u16	rid,
-	void	*riddata,
-	unsigned int	riddatalen,
-        ctlx_cmdcb_t cmdcb,
-	ctlx_usercb_t usercb,
-	void	*usercb_data)
+hfa384x_dorrid(hfa384x_t *hw,
+	       CMD_MODE mode,
+	       u16 rid,
+	       void *riddata,
+	       unsigned int riddatalen,
+	       ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
 {
-	int			result;
-	hfa384x_usbctlx_t	*ctlx;
+	int result;
+	hfa384x_usbctlx_t *ctlx;
 
-	DBFENTER;
 	ctlx = usbctlx_alloc();
-	if ( ctlx == NULL ) {
+	if (ctlx == NULL) {
 		result = -ENOMEM;
 		goto done;
 	}
 
 	/* Initialize the command */
-	ctlx->outbuf.rridreq.type =   host2hfa384x_16(HFA384x_USB_RRIDREQ);
+	ctlx->outbuf.rridreq.type = cpu_to_le16(HFA384x_USB_RRIDREQ);
 	ctlx->outbuf.rridreq.frmlen =
-		host2hfa384x_16(sizeof(ctlx->outbuf.rridreq.rid));
-	ctlx->outbuf.rridreq.rid =    host2hfa384x_16(rid);
+	    cpu_to_le16(sizeof(ctlx->outbuf.rridreq.rid));
+	ctlx->outbuf.rridreq.rid = cpu_to_le16(rid);
 
 	ctlx->outbufsize = sizeof(ctlx->outbuf.rridreq);
 
@@ -1737,19 +1492,18 @@
 	} else if (mode == DOWAIT) {
 		usbctlx_rrid_completor_t completor;
 
-		result = hfa384x_usbctlx_complete_sync(
-		           hw, ctlx, init_rrid_completor(&completor,
-		                                         &ctlx->inbuf.rridresp,
-		                                         riddata,
-		                                         riddatalen) );
+		result =
+		    hfa384x_usbctlx_complete_sync(hw, ctlx,
+						  init_rrid_completor
+						  (&completor,
+						   &ctlx->inbuf.rridresp,
+						   riddata, riddatalen));
 	}
 
 done:
-	DBFEXIT;
 	return result;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_dowrid
 *
@@ -1783,38 +1537,34 @@
 *	process (DOWAIT or DOASYNC)
 ----------------------------------------------------------------*/
 static int
-hfa384x_dowrid(
-	hfa384x_t *hw,
-	CMD_MODE mode,
-	u16	rid,
-	void	*riddata,
-	unsigned int	riddatalen,
-	ctlx_cmdcb_t cmdcb,
-	ctlx_usercb_t usercb,
-	void	*usercb_data)
+hfa384x_dowrid(hfa384x_t *hw,
+	       CMD_MODE mode,
+	       u16 rid,
+	       void *riddata,
+	       unsigned int riddatalen,
+	       ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
 {
-	int			result;
-	hfa384x_usbctlx_t	*ctlx;
+	int result;
+	hfa384x_usbctlx_t *ctlx;
 
-	DBFENTER;
 	ctlx = usbctlx_alloc();
-	if ( ctlx == NULL ) {
+	if (ctlx == NULL) {
 		result = -ENOMEM;
 		goto done;
 	}
 
 	/* Initialize the command */
-	ctlx->outbuf.wridreq.type =   host2hfa384x_16(HFA384x_USB_WRIDREQ);
-	ctlx->outbuf.wridreq.frmlen = host2hfa384x_16(
-					(sizeof(ctlx->outbuf.wridreq.rid) +
-					riddatalen + 1) / 2);
-	ctlx->outbuf.wridreq.rid =    host2hfa384x_16(rid);
+	ctlx->outbuf.wridreq.type = cpu_to_le16(HFA384x_USB_WRIDREQ);
+	ctlx->outbuf.wridreq.frmlen = cpu_to_le16((sizeof
+						       (ctlx->outbuf.wridreq.
+							rid) + riddatalen +
+						       1) / 2);
+	ctlx->outbuf.wridreq.rid = cpu_to_le16(rid);
 	memcpy(ctlx->outbuf.wridreq.data, riddata, riddatalen);
 
 	ctlx->outbufsize = sizeof(ctlx->outbuf.wridreq.type) +
-	                   sizeof(ctlx->outbuf.wridreq.frmlen) +
-	                   sizeof(ctlx->outbuf.wridreq.rid) +
-	                   riddatalen;
+	    sizeof(ctlx->outbuf.wridreq.frmlen) +
+	    sizeof(ctlx->outbuf.wridreq.rid) + riddatalen;
 
 	ctlx->reapable = mode;
 	ctlx->cmdcb = cmdcb;
@@ -1829,16 +1579,15 @@
 		usbctlx_wrid_completor_t completor;
 		hfa384x_cmdresult_t wridresult;
 
-		result = hfa384x_usbctlx_complete_sync(
-		               hw,
-		               ctlx,
-		               init_wrid_completor(&completor,
-		                                   &ctlx->inbuf.wridresp,
-		                                   &wridresult) );
+		result = hfa384x_usbctlx_complete_sync(hw,
+						       ctlx,
+						       init_wrid_completor
+						       (&completor,
+							&ctlx->inbuf.wridresp,
+							&wridresult));
 	}
 
 done:
-	DBFEXIT;
 	return result;
 }
 
@@ -1876,47 +1625,41 @@
 *	process (DOWAIT or DOASYNC)
 ----------------------------------------------------------------*/
 static int
-hfa384x_dormem(
-	hfa384x_t *hw,
-	CMD_MODE mode,
-	u16	page,
-	u16	offset,
-	void	*data,
-	unsigned int	len,
-	ctlx_cmdcb_t cmdcb,
-	ctlx_usercb_t usercb,
-	void	*usercb_data)
+hfa384x_dormem(hfa384x_t *hw,
+	       CMD_MODE mode,
+	       u16 page,
+	       u16 offset,
+	       void *data,
+	       unsigned int len,
+	       ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
 {
-	int			result;
-	hfa384x_usbctlx_t	*ctlx;
+	int result;
+	hfa384x_usbctlx_t *ctlx;
 
-	DBFENTER;
 	ctlx = usbctlx_alloc();
-	if ( ctlx == NULL ) {
+	if (ctlx == NULL) {
 		result = -ENOMEM;
 		goto done;
 	}
 
 	/* Initialize the command */
-	ctlx->outbuf.rmemreq.type =    host2hfa384x_16(HFA384x_USB_RMEMREQ);
-	ctlx->outbuf.rmemreq.frmlen =  host2hfa384x_16(
-					sizeof(ctlx->outbuf.rmemreq.offset) +
-					sizeof(ctlx->outbuf.rmemreq.page) +
-					len);
-	ctlx->outbuf.rmemreq.offset =	host2hfa384x_16(offset);
-	ctlx->outbuf.rmemreq.page =	host2hfa384x_16(page);
+	ctlx->outbuf.rmemreq.type = cpu_to_le16(HFA384x_USB_RMEMREQ);
+	ctlx->outbuf.rmemreq.frmlen =
+	    cpu_to_le16(sizeof(ctlx->outbuf.rmemreq.offset) +
+			    sizeof(ctlx->outbuf.rmemreq.page) + len);
+	ctlx->outbuf.rmemreq.offset = cpu_to_le16(offset);
+	ctlx->outbuf.rmemreq.page = cpu_to_le16(page);
 
 	ctlx->outbufsize = sizeof(ctlx->outbuf.rmemreq);
 
-	WLAN_LOG_DEBUG(4,
-		"type=0x%04x frmlen=%d offset=0x%04x page=0x%04x\n",
-		ctlx->outbuf.rmemreq.type,
-		ctlx->outbuf.rmemreq.frmlen,
-		ctlx->outbuf.rmemreq.offset,
-		ctlx->outbuf.rmemreq.page);
+	printk(KERN_DEBUG
+	       "type=0x%04x frmlen=%d offset=0x%04x page=0x%04x\n",
+	       ctlx->outbuf.rmemreq.type,
+	       ctlx->outbuf.rmemreq.frmlen,
+	       ctlx->outbuf.rmemreq.offset, ctlx->outbuf.rmemreq.page);
 
-	WLAN_LOG_DEBUG(4,"pktsize=%zd\n",
-		ROUNDUP64(sizeof(ctlx->outbuf.rmemreq)));
+	pr_debug("pktsize=%zd\n",
+	       ROUNDUP64(sizeof(ctlx->outbuf.rmemreq)));
 
 	ctlx->reapable = mode;
 	ctlx->cmdcb = cmdcb;
@@ -1926,23 +1669,21 @@
 	result = hfa384x_usbctlx_submit(hw, ctlx);
 	if (result != 0) {
 		kfree(ctlx);
-	} else if ( mode == DOWAIT ) {
-                usbctlx_rmem_completor_t completor;
+	} else if (mode == DOWAIT) {
+		usbctlx_rmem_completor_t completor;
 
-                result = hfa384x_usbctlx_complete_sync(
-                           hw, ctlx, init_rmem_completor(&completor,
-                                                         &ctlx->inbuf.rmemresp,
-                                                         data,
-                                                         len) );
+		result =
+		    hfa384x_usbctlx_complete_sync(hw, ctlx,
+						  init_rmem_completor
+						  (&completor,
+						   &ctlx->inbuf.rmemresp, data,
+						   len));
 	}
 
 done:
-	DBFEXIT;
 	return result;
 }
 
-
-
 /*----------------------------------------------------------------
 * hfa384x_dowmem
 *
@@ -1977,45 +1718,39 @@
 *	process (DOWAIT or DOASYNC)
 ----------------------------------------------------------------*/
 static int
-hfa384x_dowmem(
-	hfa384x_t *hw,
-	CMD_MODE mode,
-	u16	page,
-	u16	offset,
-	void	*data,
-	unsigned int	len,
-	ctlx_cmdcb_t cmdcb,
-	ctlx_usercb_t usercb,
-	void	*usercb_data)
+hfa384x_dowmem(hfa384x_t *hw,
+	       CMD_MODE mode,
+	       u16 page,
+	       u16 offset,
+	       void *data,
+	       unsigned int len,
+	       ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
 {
-	int			result;
-	hfa384x_usbctlx_t	*ctlx;
+	int result;
+	hfa384x_usbctlx_t *ctlx;
 
-	DBFENTER;
-	WLAN_LOG_DEBUG(5, "page=0x%04x offset=0x%04x len=%d\n",
-		page,offset,len);
+	pr_debug("page=0x%04x offset=0x%04x len=%d\n",
+	       page, offset, len);
 
 	ctlx = usbctlx_alloc();
-	if ( ctlx == NULL ) {
+	if (ctlx == NULL) {
 		result = -ENOMEM;
 		goto done;
 	}
 
 	/* Initialize the command */
-	ctlx->outbuf.wmemreq.type =   host2hfa384x_16(HFA384x_USB_WMEMREQ);
-	ctlx->outbuf.wmemreq.frmlen = host2hfa384x_16(
-					sizeof(ctlx->outbuf.wmemreq.offset) +
-					sizeof(ctlx->outbuf.wmemreq.page) +
-					len);
-	ctlx->outbuf.wmemreq.offset = host2hfa384x_16(offset);
-	ctlx->outbuf.wmemreq.page =   host2hfa384x_16(page);
+	ctlx->outbuf.wmemreq.type = cpu_to_le16(HFA384x_USB_WMEMREQ);
+	ctlx->outbuf.wmemreq.frmlen =
+	    cpu_to_le16(sizeof(ctlx->outbuf.wmemreq.offset) +
+			    sizeof(ctlx->outbuf.wmemreq.page) + len);
+	ctlx->outbuf.wmemreq.offset = cpu_to_le16(offset);
+	ctlx->outbuf.wmemreq.page = cpu_to_le16(page);
 	memcpy(ctlx->outbuf.wmemreq.data, data, len);
 
 	ctlx->outbufsize = sizeof(ctlx->outbuf.wmemreq.type) +
-	                   sizeof(ctlx->outbuf.wmemreq.frmlen) +
-	                   sizeof(ctlx->outbuf.wmemreq.offset) +
-	                   sizeof(ctlx->outbuf.wmemreq.page) +
-	                   len;
+	    sizeof(ctlx->outbuf.wmemreq.frmlen) +
+	    sizeof(ctlx->outbuf.wmemreq.offset) +
+	    sizeof(ctlx->outbuf.wmemreq.page) + len;
 
 	ctlx->reapable = mode;
 	ctlx->cmdcb = cmdcb;
@@ -2025,24 +1760,22 @@
 	result = hfa384x_usbctlx_submit(hw, ctlx);
 	if (result != 0) {
 		kfree(ctlx);
-	} else if ( mode == DOWAIT ) {
-                usbctlx_wmem_completor_t completor;
-                hfa384x_cmdresult_t wmemresult;
+	} else if (mode == DOWAIT) {
+		usbctlx_wmem_completor_t completor;
+		hfa384x_cmdresult_t wmemresult;
 
-                result = hfa384x_usbctlx_complete_sync(
-                               hw,
-                               ctlx,
-                               init_wmem_completor(&completor,
-                                                   &ctlx->inbuf.wmemresp,
-                                                   &wmemresult) );
+		result = hfa384x_usbctlx_complete_sync(hw,
+						       ctlx,
+						       init_wmem_completor
+						       (&completor,
+							&ctlx->inbuf.wmemresp,
+							&wmemresult));
 	}
 
 done:
-	DBFEXIT;
 	return result;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_drvr_commtallies
 *
@@ -2060,12 +1793,10 @@
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-int hfa384x_drvr_commtallies( hfa384x_t *hw )
+int hfa384x_drvr_commtallies(hfa384x_t *hw)
 {
 	hfa384x_metacmd_t cmd;
 
-	DBFENTER;
-
 	cmd.cmd = HFA384x_CMDCODE_INQ;
 	cmd.parm0 = HFA384x_IT_COMMTALLIES;
 	cmd.parm1 = 0;
@@ -2073,11 +1804,9 @@
 
 	hfa384x_docmd_async(hw, &cmd, NULL, NULL, NULL);
 
-	DBFEXIT;
 	return 0;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_drvr_disable
 *
@@ -2102,24 +1831,20 @@
 ----------------------------------------------------------------*/
 int hfa384x_drvr_disable(hfa384x_t *hw, u16 macport)
 {
-	int	result = 0;
+	int result = 0;
 
-	DBFENTER;
 	if ((!hw->isap && macport != 0) ||
 	    (hw->isap && !(macport <= HFA384x_PORTID_MAX)) ||
-	    !(hw->port_enabled[macport]) ){
+	    !(hw->port_enabled[macport])) {
 		result = -EINVAL;
 	} else {
 		result = hfa384x_cmd_disable(hw, macport);
-		if ( result == 0 ) {
+		if (result == 0)
 			hw->port_enabled[macport] = 0;
-		}
 	}
-	DBFEXIT;
 	return result;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_drvr_enable
 *
@@ -2144,24 +1869,20 @@
 ----------------------------------------------------------------*/
 int hfa384x_drvr_enable(hfa384x_t *hw, u16 macport)
 {
-	int	result = 0;
+	int result = 0;
 
-	DBFENTER;
 	if ((!hw->isap && macport != 0) ||
 	    (hw->isap && !(macport <= HFA384x_PORTID_MAX)) ||
-	    (hw->port_enabled[macport]) ){
+	    (hw->port_enabled[macport])) {
 		result = -EINVAL;
 	} else {
 		result = hfa384x_cmd_enable(hw, macport);
-		if ( result == 0 ) {
+		if (result == 0)
 			hw->port_enabled[macport] = 1;
-		}
 	}
-	DBFEXIT;
 	return result;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_drvr_flashdl_enable
 *
@@ -2185,45 +1906,43 @@
 ----------------------------------------------------------------*/
 int hfa384x_drvr_flashdl_enable(hfa384x_t *hw)
 {
-	int		result = 0;
-	int		i;
+	int result = 0;
+	int i;
 
-	DBFENTER;
 	/* Check that a port isn't active */
-	for ( i = 0; i < HFA384x_PORTID_MAX; i++) {
-		if ( hw->port_enabled[i] ) {
-			WLAN_LOG_DEBUG(1,"called when port enabled.\n");
+	for (i = 0; i < HFA384x_PORTID_MAX; i++) {
+		if (hw->port_enabled[i]) {
+			pr_debug("called when port enabled.\n");
 			return -EINVAL;
 		}
 	}
 
 	/* Check that we're not already in a download state */
-	if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) {
+	if (hw->dlstate != HFA384x_DLSTATE_DISABLED)
 		return -EINVAL;
-	}
 
 	/* Retrieve the buffer loc&size and timeout */
-	if ( (result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER,
-				&(hw->bufinfo), sizeof(hw->bufinfo))) ) {
+	if ((result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER,
+					     &(hw->bufinfo),
+					     sizeof(hw->bufinfo)))) {
 		return result;
 	}
-	hw->bufinfo.page = hfa384x2host_16(hw->bufinfo.page);
-	hw->bufinfo.offset = hfa384x2host_16(hw->bufinfo.offset);
-	hw->bufinfo.len = hfa384x2host_16(hw->bufinfo.len);
-	if ( (result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME,
-				&(hw->dltimeout))) ) {
+	hw->bufinfo.page = le16_to_cpu(hw->bufinfo.page);
+	hw->bufinfo.offset = le16_to_cpu(hw->bufinfo.offset);
+	hw->bufinfo.len = le16_to_cpu(hw->bufinfo.len);
+	if ((result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME,
+					       &(hw->dltimeout)))) {
 		return result;
 	}
-	hw->dltimeout = hfa384x2host_16(hw->dltimeout);
+	hw->dltimeout = le16_to_cpu(hw->dltimeout);
 
-	WLAN_LOG_DEBUG(1,"flashdl_enable\n");
+	pr_debug("flashdl_enable\n");
 
 	hw->dlstate = HFA384x_DLSTATE_FLASHENABLED;
-	DBFEXIT;
+
 	return result;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_drvr_flashdl_disable
 *
@@ -2245,24 +1964,20 @@
 ----------------------------------------------------------------*/
 int hfa384x_drvr_flashdl_disable(hfa384x_t *hw)
 {
-	DBFENTER;
 	/* Check that we're already in the download state */
-	if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) {
+	if (hw->dlstate != HFA384x_DLSTATE_FLASHENABLED)
 		return -EINVAL;
-	}
 
-	WLAN_LOG_DEBUG(1,"flashdl_enable\n");
+	pr_debug("flashdl_enable\n");
 
 	/* There isn't much we can do at this point, so I don't */
 	/*  bother  w/ the return value */
-	hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0);
+	hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0, 0);
 	hw->dlstate = HFA384x_DLSTATE_DISABLED;
 
-	DBFEXIT;
 	return 0;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_drvr_flashdl_write
 *
@@ -2292,48 +2007,42 @@
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-int
-hfa384x_drvr_flashdl_write(
-	hfa384x_t	*hw,
-	u32		daddr,
-	void		*buf,
-	u32		len)
+int hfa384x_drvr_flashdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len)
 {
-	int		result = 0;
-	u32		dlbufaddr;
-	int		nburns;
-	u32		burnlen;
-	u32		burndaddr;
-	u16		burnlo;
-	u16		burnhi;
-	int		nwrites;
-	u8		*writebuf;
-	u16		writepage;
-	u16		writeoffset;
-	u32		writelen;
-	int		i;
-	int		j;
+	int result = 0;
+	u32 dlbufaddr;
+	int nburns;
+	u32 burnlen;
+	u32 burndaddr;
+	u16 burnlo;
+	u16 burnhi;
+	int nwrites;
+	u8 *writebuf;
+	u16 writepage;
+	u16 writeoffset;
+	u32 writelen;
+	int i;
+	int j;
 
-	DBFENTER;
-	WLAN_LOG_DEBUG(5,"daddr=0x%08x len=%d\n", daddr, len);
+	pr_debug("daddr=0x%08x len=%d\n", daddr, len);
 
 	/* Check that we're in the flash download state */
-	if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) {
+	if (hw->dlstate != HFA384x_DLSTATE_FLASHENABLED)
 		return -EINVAL;
-	}
 
-	WLAN_LOG_INFO("Download %d bytes to flash @0x%06x\n", len, daddr);
+	printk(KERN_INFO "Download %d bytes to flash @0x%06x\n", len, daddr);
 
 	/* Convert to flat address for arithmetic */
 	/* NOTE: dlbuffer RID stores the address in AUX format */
-	dlbufaddr = HFA384x_ADDR_AUX_MKFLAT(
-			hw->bufinfo.page, hw->bufinfo.offset);
-	WLAN_LOG_DEBUG(5,
-		"dlbuf.page=0x%04x dlbuf.offset=0x%04x dlbufaddr=0x%08x\n",
-		hw->bufinfo.page, hw->bufinfo.offset, dlbufaddr);
+	dlbufaddr =
+	    HFA384x_ADDR_AUX_MKFLAT(hw->bufinfo.page, hw->bufinfo.offset);
+	printk(KERN_DEBUG
+	       "dlbuf.page=0x%04x dlbuf.offset=0x%04x dlbufaddr=0x%08x\n",
+	       hw->bufinfo.page, hw->bufinfo.offset, dlbufaddr);
 
 #if 0
-WLAN_LOG_WARNING("dlbuf@0x%06lx len=%d to=%d\n", dlbufaddr, hw->bufinfo.len, hw->dltimeout);
+	printk(KERN_WARNING "dlbuf@0x%06lx len=%d to=%d\n", dlbufaddr,
+	       hw->bufinfo.len, hw->dltimeout);
 #endif
 	/* Calculations to determine how many fills of the dlbuffer to do
 	 * and how many USB wmemreq's to do for each fill.  At this point
@@ -2351,74 +2060,60 @@
 	nwrites += (hw->bufinfo.len % HFA384x_USB_RWMEM_MAXLEN) ? 1 : 0;
 
 	/* For each burn */
-	for ( i = 0; i < nburns; i++) {
+	for (i = 0; i < nburns; i++) {
 		/* Get the dest address and len */
 		burnlen = (len - (hw->bufinfo.len * i)) > hw->bufinfo.len ?
-				hw->bufinfo.len :
-				(len - (hw->bufinfo.len * i));
+		    hw->bufinfo.len : (len - (hw->bufinfo.len * i));
 		burndaddr = daddr + (hw->bufinfo.len * i);
 		burnlo = HFA384x_ADDR_CMD_MKOFF(burndaddr);
 		burnhi = HFA384x_ADDR_CMD_MKPAGE(burndaddr);
 
-		WLAN_LOG_INFO("Writing %d bytes to flash @0x%06x\n",
-			burnlen, burndaddr);
+		printk(KERN_INFO "Writing %d bytes to flash @0x%06x\n",
+		       burnlen, burndaddr);
 
 		/* Set the download mode */
 		result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NV,
-				burnlo, burnhi, burnlen);
-		if ( result ) {
-			WLAN_LOG_ERROR("download(NV,lo=%x,hi=%x,len=%x) "
-				"cmd failed, result=%d. Aborting d/l\n",
-				burnlo, burnhi, burnlen, result);
+					      burnlo, burnhi, burnlen);
+		if (result) {
+			printk(KERN_ERR "download(NV,lo=%x,hi=%x,len=%x) "
+			       "cmd failed, result=%d. Aborting d/l\n",
+			       burnlo, burnhi, burnlen, result);
 			goto exit_proc;
 		}
 
 		/* copy the data to the flash download buffer */
-		for ( j=0; j < nwrites; j++) {
+		for (j = 0; j < nwrites; j++) {
 			writebuf = buf +
-				(i*hw->bufinfo.len) +
-				(j*HFA384x_USB_RWMEM_MAXLEN);
+			    (i * hw->bufinfo.len) +
+			    (j * HFA384x_USB_RWMEM_MAXLEN);
 
-			writepage = HFA384x_ADDR_CMD_MKPAGE(
-					dlbufaddr +
-					(j*HFA384x_USB_RWMEM_MAXLEN));
-			writeoffset = HFA384x_ADDR_CMD_MKOFF(
-					dlbufaddr +
-					(j*HFA384x_USB_RWMEM_MAXLEN));
+			writepage = HFA384x_ADDR_CMD_MKPAGE(dlbufaddr +
+							    (j *
+							     HFA384x_USB_RWMEM_MAXLEN));
+			writeoffset =
+			    HFA384x_ADDR_CMD_MKOFF(dlbufaddr +
+						   (j *
+						    HFA384x_USB_RWMEM_MAXLEN));
 
-			writelen = burnlen-(j*HFA384x_USB_RWMEM_MAXLEN);
-			writelen = writelen  > HFA384x_USB_RWMEM_MAXLEN ?
-					HFA384x_USB_RWMEM_MAXLEN :
-					writelen;
+			writelen = burnlen - (j * HFA384x_USB_RWMEM_MAXLEN);
+			writelen = writelen > HFA384x_USB_RWMEM_MAXLEN ?
+			    HFA384x_USB_RWMEM_MAXLEN : writelen;
 
-			result = hfa384x_dowmem_wait( hw,
-					writepage,
-					writeoffset,
-					writebuf,
-					writelen );
-#if 0
-
-Comment out for debugging, assume the write was successful.
-			if (result) {
-				WLAN_LOG_ERROR(
-					"Write to dl buffer failed, "
-					"result=0x%04x. Aborting.\n",
-					result);
-				goto exit_proc;
-			}
-#endif
-
+			result = hfa384x_dowmem_wait(hw,
+						     writepage,
+						     writeoffset,
+						     writebuf, writelen);
 		}
 
 		/* set the download 'write flash' mode */
 		result = hfa384x_cmd_download(hw,
-				HFA384x_PROGMODE_NVWRITE,
-				0,0,0);
-		if ( result ) {
-			WLAN_LOG_ERROR(
-				"download(NVWRITE,lo=%x,hi=%x,len=%x) "
-				"cmd failed, result=%d. Aborting d/l\n",
-				burnlo, burnhi, burnlen, result);
+					      HFA384x_PROGMODE_NVWRITE,
+					      0, 0, 0);
+		if (result) {
+			printk(KERN_ERR
+			       "download(NVWRITE,lo=%x,hi=%x,len=%x) "
+			       "cmd failed, result=%d. Aborting d/l\n",
+			       burnlo, burnhi, burnlen, result);
 			goto exit_proc;
 		}
 
@@ -2431,11 +2126,9 @@
 	/*  actually disable programming mode.  Remember, that will cause the */
 	/*  the firmware to effectively reset itself. */
 
-	DBFEXIT;
 	return result;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_drvr_getconfig
 *
@@ -2463,12 +2156,10 @@
 ----------------------------------------------------------------*/
 int hfa384x_drvr_getconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len)
 {
-	int 			result;
-	DBFENTER;
+	int result;
 
 	result = hfa384x_dorrid_wait(hw, rid, buf, len);
 
-	DBFEXIT;
 	return result;
 }
 
@@ -2500,14 +2191,11 @@
  *       Any
  ----------------------------------------------------------------*/
 int
-hfa384x_drvr_getconfig_async(
-         hfa384x_t               *hw,
-         u16                  rid,
-         ctlx_usercb_t           usercb,
-         void                    *usercb_data)
+hfa384x_drvr_getconfig_async(hfa384x_t *hw,
+			     u16 rid, ctlx_usercb_t usercb, void *usercb_data)
 {
-         return hfa384x_dorrid_async(hw, rid, NULL, 0,
-				     hfa384x_cb_rrid, usercb, usercb_data);
+	return hfa384x_dorrid_async(hw, rid, NULL, 0,
+				    hfa384x_cb_rrid, usercb, usercb_data);
 }
 
 /*----------------------------------------------------------------
@@ -2534,71 +2222,16 @@
  *       process
  ----------------------------------------------------------------*/
 int
-hfa384x_drvr_setconfig_async(
-         hfa384x_t       *hw,
-         u16          rid,
-         void            *buf,
-         u16          len,
-         ctlx_usercb_t   usercb,
-         void            *usercb_data)
+hfa384x_drvr_setconfig_async(hfa384x_t *hw,
+			     u16 rid,
+			     void *buf,
+			     u16 len, ctlx_usercb_t usercb, void *usercb_data)
 {
 	return hfa384x_dowrid_async(hw, rid, buf, len,
 				    hfa384x_cb_status, usercb, usercb_data);
 }
 
 /*----------------------------------------------------------------
-* hfa384x_drvr_handover
-*
-* Sends a handover notification to the MAC.
-*
-* Arguments:
-*	hw		device structure
-*	addr		address of station that's left
-*
-* Returns:
-*	zero		success.
-*	-ERESTARTSYS	received signal while waiting for semaphore.
-*	-EIO		failed to write to bap, or failed in cmd.
-*
-* Side effects:
-*
-* Call context:
-*	process
-----------------------------------------------------------------*/
-int hfa384x_drvr_handover( hfa384x_t *hw, u8 *addr)
-{
-        DBFENTER;
-	WLAN_LOG_ERROR("Not currently supported in USB!\n");
-	DBFEXIT;
-	return -EIO;
-}
-
-/*----------------------------------------------------------------
-* hfa384x_drvr_low_level
-*
-* Write test commands to the card.  Some test commands don't make
-* sense without prior set-up.  For example, continous TX isn't very
-* useful until you set the channel.  That functionality should be
-*
-* Side effects:
-*
-* Call context:
-*      process thread
-* -----------------------------------------------------------------*/
-int hfa384x_drvr_low_level(hfa384x_t *hw, hfa384x_metacmd_t *cmd)
-{
-	int             result;
-	DBFENTER;
-
-	/* Do i need a host2hfa... conversion ? */
-
-	result = hfa384x_docmd_wait(hw, cmd);
-
-	DBFEXIT;
-	return result;
-}
-
-/*----------------------------------------------------------------
 * hfa384x_drvr_ramdl_disable
 *
 * Ends the ram download state.
@@ -2616,27 +2249,22 @@
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-int
-hfa384x_drvr_ramdl_disable(hfa384x_t *hw)
+int hfa384x_drvr_ramdl_disable(hfa384x_t *hw)
 {
-	DBFENTER;
 	/* Check that we're already in the download state */
-	if ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) {
+	if (hw->dlstate != HFA384x_DLSTATE_RAMENABLED)
 		return -EINVAL;
-	}
 
-	WLAN_LOG_DEBUG(3,"ramdl_disable()\n");
+	pr_debug("ramdl_disable()\n");
 
 	/* There isn't much we can do at this point, so I don't */
 	/*  bother  w/ the return value */
-	hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0);
+	hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0, 0);
 	hw->dlstate = HFA384x_DLSTATE_DISABLED;
 
-	DBFEXIT;
 	return 0;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_drvr_ramdl_enable
 *
@@ -2661,55 +2289,49 @@
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-int
-hfa384x_drvr_ramdl_enable(hfa384x_t *hw, u32 exeaddr)
+int hfa384x_drvr_ramdl_enable(hfa384x_t *hw, u32 exeaddr)
 {
-	int		result = 0;
-	u16		lowaddr;
-	u16		hiaddr;
-	int		i;
-	DBFENTER;
+	int result = 0;
+	u16 lowaddr;
+	u16 hiaddr;
+	int i;
+
 	/* Check that a port isn't active */
-	for ( i = 0; i < HFA384x_PORTID_MAX; i++) {
-		if ( hw->port_enabled[i] ) {
-			WLAN_LOG_ERROR(
-				"Can't download with a macport enabled.\n");
+	for (i = 0; i < HFA384x_PORTID_MAX; i++) {
+		if (hw->port_enabled[i]) {
+			printk(KERN_ERR
+			       "Can't download with a macport enabled.\n");
 			return -EINVAL;
 		}
 	}
 
 	/* Check that we're not already in a download state */
-	if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) {
-		WLAN_LOG_ERROR(
-			"Download state not disabled.\n");
+	if (hw->dlstate != HFA384x_DLSTATE_DISABLED) {
+		printk(KERN_ERR "Download state not disabled.\n");
 		return -EINVAL;
 	}
 
-	WLAN_LOG_DEBUG(3,"ramdl_enable, exeaddr=0x%08x\n", exeaddr);
+	pr_debug("ramdl_enable, exeaddr=0x%08x\n", exeaddr);
 
 	/* Call the download(1,addr) function */
 	lowaddr = HFA384x_ADDR_CMD_MKOFF(exeaddr);
-	hiaddr =  HFA384x_ADDR_CMD_MKPAGE(exeaddr);
+	hiaddr = HFA384x_ADDR_CMD_MKPAGE(exeaddr);
 
 	result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_RAM,
-			lowaddr, hiaddr, 0);
+				      lowaddr, hiaddr, 0);
 
-	if ( result == 0) {
+	if (result == 0) {
 		/* Set the download state */
 		hw->dlstate = HFA384x_DLSTATE_RAMENABLED;
 	} else {
-		WLAN_LOG_DEBUG(1,
-			"cmd_download(0x%04x, 0x%04x) failed, result=%d.\n",
-			lowaddr,
-			hiaddr,
-			result);
+		printk(KERN_DEBUG
+		       "cmd_download(0x%04x, 0x%04x) failed, result=%d.\n",
+		       lowaddr, hiaddr, result);
 	}
 
-	DBFEXIT;
 	return result;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_drvr_ramdl_write
 *
@@ -2736,57 +2358,54 @@
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-int
-hfa384x_drvr_ramdl_write(hfa384x_t *hw, u32 daddr, void* buf, u32 len)
+int hfa384x_drvr_ramdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len)
 {
-	int		result = 0;
-	int		nwrites;
-	u8		*data = buf;
-	int		i;
-	u32		curraddr;
-	u16		currpage;
-	u16		curroffset;
-	u16		currlen;
-	DBFENTER;
-	/* Check that we're in the ram download state */
-	if ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) {
-		return -EINVAL;
-	}
+	int result = 0;
+	int nwrites;
+	u8 *data = buf;
+	int i;
+	u32 curraddr;
+	u16 currpage;
+	u16 curroffset;
+	u16 currlen;
 
-	WLAN_LOG_INFO("Writing %d bytes to ram @0x%06x\n", len, daddr);
+	/* Check that we're in the ram download state */
+	if (hw->dlstate != HFA384x_DLSTATE_RAMENABLED)
+		return -EINVAL;
+
+	printk(KERN_INFO "Writing %d bytes to ram @0x%06x\n", len, daddr);
 
 	/* How many dowmem calls?  */
 	nwrites = len / HFA384x_USB_RWMEM_MAXLEN;
 	nwrites += len % HFA384x_USB_RWMEM_MAXLEN ? 1 : 0;
 
 	/* Do blocking wmem's */
-	for(i=0; i < nwrites; i++) {
+	for (i = 0; i < nwrites; i++) {
 		/* make address args */
 		curraddr = daddr + (i * HFA384x_USB_RWMEM_MAXLEN);
 		currpage = HFA384x_ADDR_CMD_MKPAGE(curraddr);
 		curroffset = HFA384x_ADDR_CMD_MKOFF(curraddr);
 		currlen = len - (i * HFA384x_USB_RWMEM_MAXLEN);
-		if ( currlen > HFA384x_USB_RWMEM_MAXLEN) {
+		if (currlen > HFA384x_USB_RWMEM_MAXLEN)
 			currlen = HFA384x_USB_RWMEM_MAXLEN;
-		}
 
-	 	/* Do blocking ctlx */
-		result = hfa384x_dowmem_wait( hw,
-				currpage,
-				curroffset,
-				data + (i*HFA384x_USB_RWMEM_MAXLEN),
-				currlen );
+		/* Do blocking ctlx */
+		result = hfa384x_dowmem_wait(hw,
+					     currpage,
+					     curroffset,
+					     data +
+					     (i * HFA384x_USB_RWMEM_MAXLEN),
+					     currlen);
 
-		if (result) break;
+		if (result)
+			break;
 
 		/* TODO: We really should have a readback. */
 	}
 
-	DBFEXIT;
 	return result;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_drvr_readpda
 *
@@ -2820,101 +2439,89 @@
 ----------------------------------------------------------------*/
 int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, unsigned int len)
 {
-	int		result = 0;
-	u16		*pda = buf;
-	int		pdaok = 0;
-	int		morepdrs = 1;
-	int		currpdr = 0;	/* word offset of the current pdr */
-	size_t		i;
-	u16		pdrlen;		/* pdr length in bytes, host order */
-	u16		pdrcode;	/* pdr code, host order */
-	u16		currpage;
-	u16		curroffset;
+	int result = 0;
+	u16 *pda = buf;
+	int pdaok = 0;
+	int morepdrs = 1;
+	int currpdr = 0;	/* word offset of the current pdr */
+	size_t i;
+	u16 pdrlen;		/* pdr length in bytes, host order */
+	u16 pdrcode;		/* pdr code, host order */
+	u16 currpage;
+	u16 curroffset;
 	struct pdaloc {
-		u32	cardaddr;
-		u16	auxctl;
-	} pdaloc[] =
-	{
-		{ HFA3842_PDA_BASE,		0},
-		{ HFA3841_PDA_BASE,		0},
-		{ HFA3841_PDA_BOGUS_BASE,	0}
+		u32 cardaddr;
+		u16 auxctl;
+	} pdaloc[] = {
+		{
+		HFA3842_PDA_BASE, 0}, {
+		HFA3841_PDA_BASE, 0}, {
+		HFA3841_PDA_BOGUS_BASE, 0}
 	};
 
-	DBFENTER;
-
 	/* Read the pda from each known address.  */
-	for ( i = 0; i < ARRAY_SIZE(pdaloc); i++) {
+	for (i = 0; i < ARRAY_SIZE(pdaloc); i++) {
 		/* Make address */
 		currpage = HFA384x_ADDR_CMD_MKPAGE(pdaloc[i].cardaddr);
 		curroffset = HFA384x_ADDR_CMD_MKOFF(pdaloc[i].cardaddr);
 
-		result = hfa384x_dormem_wait(hw,
-			currpage,
-			curroffset,
-			buf,
-			len);		/* units of bytes */
+		result = hfa384x_dormem_wait(hw, currpage, curroffset, buf, len);	/* units of bytes */
 
 		if (result) {
-			WLAN_LOG_WARNING(
-					  "Read from index %zd failed, continuing\n",
-				i );
+			printk(KERN_WARNING
+			       "Read from index %zd failed, continuing\n", i);
 			continue;
 		}
 
 		/* Test for garbage */
 		pdaok = 1;	/* initially assume good */
 		morepdrs = 1;
-		while ( pdaok && morepdrs ) {
-			pdrlen = hfa384x2host_16(pda[currpdr]) * 2;
-			pdrcode = hfa384x2host_16(pda[currpdr+1]);
+		while (pdaok && morepdrs) {
+			pdrlen = le16_to_cpu(pda[currpdr]) * 2;
+			pdrcode = le16_to_cpu(pda[currpdr + 1]);
 			/* Test the record length */
-			if ( pdrlen > HFA384x_PDR_LEN_MAX || pdrlen == 0) {
-				WLAN_LOG_ERROR("pdrlen invalid=%d\n",
-					pdrlen);
+			if (pdrlen > HFA384x_PDR_LEN_MAX || pdrlen == 0) {
+				printk(KERN_ERR "pdrlen invalid=%d\n", pdrlen);
 				pdaok = 0;
 				break;
 			}
 			/* Test the code */
-			if ( !hfa384x_isgood_pdrcode(pdrcode) ) {
-				WLAN_LOG_ERROR("pdrcode invalid=%d\n",
-					pdrcode);
+			if (!hfa384x_isgood_pdrcode(pdrcode)) {
+				printk(KERN_ERR "pdrcode invalid=%d\n",
+				       pdrcode);
 				pdaok = 0;
 				break;
 			}
 			/* Test for completion */
-			if ( pdrcode == HFA384x_PDR_END_OF_PDA) {
+			if (pdrcode == HFA384x_PDR_END_OF_PDA)
 				morepdrs = 0;
-			}
 
 			/* Move to the next pdr (if necessary) */
-			if ( morepdrs ) {
+			if (morepdrs) {
 				/* note the access to pda[], need words here */
-				currpdr += hfa384x2host_16(pda[currpdr]) + 1;
+				currpdr += le16_to_cpu(pda[currpdr]) + 1;
 			}
 		}
-		if ( pdaok ) {
-			WLAN_LOG_INFO(
-				"PDA Read from 0x%08x in %s space.\n",
-				pdaloc[i].cardaddr,
-				pdaloc[i].auxctl == 0 ? "EXTDS" :
-				pdaloc[i].auxctl == 1 ? "NV" :
-				pdaloc[i].auxctl == 2 ? "PHY" :
-				pdaloc[i].auxctl == 3 ? "ICSRAM" :
-				"<bogus auxctl>");
+		if (pdaok) {
+			printk(KERN_INFO
+			       "PDA Read from 0x%08x in %s space.\n",
+			       pdaloc[i].cardaddr,
+			       pdaloc[i].auxctl == 0 ? "EXTDS" :
+			       pdaloc[i].auxctl == 1 ? "NV" :
+			       pdaloc[i].auxctl == 2 ? "PHY" :
+			       pdaloc[i].auxctl == 3 ? "ICSRAM" :
+			       "<bogus auxctl>");
 			break;
 		}
 	}
 	result = pdaok ? 0 : -ENODATA;
 
-	if ( result ) {
-		WLAN_LOG_DEBUG(3,"Failure: pda is not okay\n");
-	}
+	if (result)
+		pr_debug("Failure: pda is not okay\n");
 
-	DBFEXIT;
 	return result;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_drvr_setconfig
 *
@@ -2963,9 +2570,8 @@
 
 int hfa384x_drvr_start(hfa384x_t *hw)
 {
-	int		result, result1, result2;
-	u16		status;
-	DBFENTER;
+	int result, result1, result2;
+	u16 status;
 
 	might_sleep();
 
@@ -2974,27 +2580,23 @@
 	 * badly if a clear_halt is called when the endpoint is already
 	 * ok
 	 */
-	result = usb_get_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_in, &status);
+	result =
+	    usb_get_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_in, &status);
 	if (result < 0) {
-		WLAN_LOG_ERROR(
-			"Cannot get bulk in endpoint status.\n");
+		printk(KERN_ERR "Cannot get bulk in endpoint status.\n");
 		goto done;
 	}
-	if ((status == 1) && usb_clear_halt(hw->usb, hw->endp_in)) {
-		WLAN_LOG_ERROR(
-			"Failed to reset bulk in endpoint.\n");
-	}
+	if ((status == 1) && usb_clear_halt(hw->usb, hw->endp_in))
+		printk(KERN_ERR "Failed to reset bulk in endpoint.\n");
 
-	result = usb_get_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_out, &status);
+	result =
+	    usb_get_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_out, &status);
 	if (result < 0) {
-		WLAN_LOG_ERROR(
-			"Cannot get bulk out endpoint status.\n");
+		printk(KERN_ERR "Cannot get bulk out endpoint status.\n");
 		goto done;
 	}
-	if ((status == 1) && usb_clear_halt(hw->usb, hw->endp_out)) {
-		WLAN_LOG_ERROR(
-			"Failed to reset bulk out endpoint.\n");
-	}
+	if ((status == 1) && usb_clear_halt(hw->usb, hw->endp_out))
+		printk(KERN_ERR "Failed to reset bulk out endpoint.\n");
 
 	/* Synchronous unlink, in case we're trying to restart the driver */
 	usb_kill_urb(&hw->rx_urb);
@@ -3002,9 +2604,8 @@
 	/* Post the IN urb */
 	result = submit_rx_urb(hw, GFP_KERNEL);
 	if (result != 0) {
-		WLAN_LOG_ERROR(
-			"Fatal, failed to submit RX URB, result=%d\n",
-			result);
+		printk(KERN_ERR
+		       "Fatal, failed to submit RX URB, result=%d\n", result);
 		goto done;
 	}
 
@@ -3023,32 +2624,33 @@
 	result = result2 = hfa384x_cmd_initialize(hw);
 	if (result1 != 0) {
 		if (result2 != 0) {
-			WLAN_LOG_ERROR(
-				"cmd_initialize() failed on two attempts, results %d and %d\n",
-				result1, result2);
+			printk(KERN_ERR
+			       "cmd_initialize() failed on two attempts, results %d and %d\n",
+			       result1, result2);
 			usb_kill_urb(&hw->rx_urb);
 			goto done;
 		} else {
-			WLAN_LOG_DEBUG(0, "First cmd_initialize() failed (result %d),\n",
-				result1);
-			WLAN_LOG_DEBUG(0, "but second attempt succeeded. All should be ok\n");
+			printk(KERN_DEBUG
+			       "First cmd_initialize() failed (result %d),\n",
+			       result1);
+			printk(KERN_DEBUG
+			       "but second attempt succeeded. All should be ok\n");
 		}
 	} else if (result2 != 0) {
-		WLAN_LOG_WARNING(
-			"First cmd_initialize() succeeded, but second attempt failed (result=%d)\n",
-			result2);
-		WLAN_LOG_WARNING("Most likely the card will be functional\n");
-			goto done;
+		printk(KERN_WARNING
+		       "First cmd_initialize() succeeded, but second attempt failed (result=%d)\n",
+		       result2);
+		printk(KERN_WARNING
+		       "Most likely the card will be functional\n");
+		goto done;
 	}
 
 	hw->state = HFA384x_STATE_RUNNING;
 
 done:
-	DBFEXIT;
 	return result;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_drvr_stop
 *
@@ -3068,19 +2670,17 @@
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-int
-hfa384x_drvr_stop(hfa384x_t *hw)
+int hfa384x_drvr_stop(hfa384x_t *hw)
 {
-	int	result = 0;
-	int	i;
-	DBFENTER;
+	int result = 0;
+	int i;
 
 	might_sleep();
 
 	/* There's no need for spinlocks here. The USB "disconnect"
 	 * function sets this "removed" flag and then calls us.
 	 */
-	if ( !hw->wlandev->hwremoved ) {
+	if (!hw->wlandev->hwremoved) {
 		/* Call initialize to leave the MAC in its 'reset' state */
 		hfa384x_cmd_initialize(hw);
 
@@ -3094,11 +2694,9 @@
 	del_timer_sync(&hw->commsqual_timer);
 
 	/* Clear all the port status */
-	for ( i = 0; i < HFA384x_NUMPORTS_MAX; i++) {
+	for (i = 0; i < HFA384x_NUMPORTS_MAX; i++)
 		hw->port_enabled[i] = 0;
-	}
 
-	DBFEXIT;
 	return result;
 }
 
@@ -3123,18 +2721,17 @@
 * Call context:
 *	interrupt
 ----------------------------------------------------------------*/
-int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep)
-
+int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb,
+			 p80211_hdr_t *p80211_hdr,
+			 p80211_metawep_t *p80211_wep)
 {
-	int		usbpktlen = sizeof(hfa384x_tx_frame_t);
-	int		result;
-	int		ret;
-	char		*ptr;
-
-	DBFENTER;
+	int usbpktlen = sizeof(hfa384x_tx_frame_t);
+	int result;
+	int ret;
+	char *ptr;
 
 	if (hw->tx_urb.status == -EINPROGRESS) {
-		WLAN_LOG_WARNING("TX URB already in use\n");
+		printk(KERN_WARNING "TX URB already in use\n");
 		result = 3;
 		goto exit;
 	}
@@ -3144,7 +2741,7 @@
 	memset(&hw->txbuff.txfrm.desc, 0, sizeof(hw->txbuff.txfrm.desc));
 
 	/* Setup the usb type field */
-	hw->txbuff.type = host2hfa384x_16(HFA384x_USB_TXFRM);
+	hw->txbuff.type = cpu_to_le16(HFA384x_USB_TXFRM);
 
 	/* Set up the sw_support field to identify this frame */
 	hw->txbuff.txfrm.desc.sw_support = 0x0123;
@@ -3152,33 +2749,33 @@
 /* Tx complete and Tx exception disable per dleach.  Might be causing
  * buf depletion
  */
-//#define DOEXC  SLP -- doboth breaks horribly under load, doexc less so.
+/* #define DOEXC  SLP -- doboth breaks horribly under load, doexc less so. */
 #if defined(DOBOTH)
 	hw->txbuff.txfrm.desc.tx_control =
-		HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
-		HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(1);
+	    HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
+	    HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(1);
 #elif defined(DOEXC)
 	hw->txbuff.txfrm.desc.tx_control =
-		HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
-		HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(0);
+	    HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
+	    HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(0);
 #else
 	hw->txbuff.txfrm.desc.tx_control =
-		HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
-		HFA384x_TX_TXEX_SET(0) | HFA384x_TX_TXOK_SET(0);
+	    HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
+	    HFA384x_TX_TXEX_SET(0) | HFA384x_TX_TXOK_SET(0);
 #endif
 	hw->txbuff.txfrm.desc.tx_control =
-		host2hfa384x_16(hw->txbuff.txfrm.desc.tx_control);
+	    cpu_to_le16(hw->txbuff.txfrm.desc.tx_control);
 
 	/* copy the header over to the txdesc */
-	memcpy(&(hw->txbuff.txfrm.desc.frame_control), p80211_hdr, sizeof(p80211_hdr_t));
+	memcpy(&(hw->txbuff.txfrm.desc.frame_control), p80211_hdr,
+	       sizeof(p80211_hdr_t));
 
 	/* if we're using host WEP, increase size by IV+ICV */
 	if (p80211_wep->data) {
-		hw->txbuff.txfrm.desc.data_len = host2hfa384x_16(skb->len+8);
-		// hw->txbuff.txfrm.desc.tx_control |= HFA384x_TX_NOENCRYPT_SET(1);
-		usbpktlen+=8;
+		hw->txbuff.txfrm.desc.data_len = cpu_to_le16(skb->len + 8);
+		usbpktlen += 8;
 	} else {
-		hw->txbuff.txfrm.desc.data_len = host2hfa384x_16(skb->len);
+		hw->txbuff.txfrm.desc.data_len = cpu_to_le16(skb->len);
 	}
 
 	usbpktlen += skb->len;
@@ -3187,59 +2784,51 @@
 	ptr = hw->txbuff.txfrm.data;
 	if (p80211_wep->data) {
 		memcpy(ptr, p80211_wep->iv, sizeof(p80211_wep->iv));
-		ptr+= sizeof(p80211_wep->iv);
+		ptr += sizeof(p80211_wep->iv);
 		memcpy(ptr, p80211_wep->data, skb->len);
 	} else {
 		memcpy(ptr, skb->data, skb->len);
 	}
 	/* copy over the packet data */
-	ptr+= skb->len;
+	ptr += skb->len;
 
 	/* copy over the WEP ICV if we are using host WEP */
-	if (p80211_wep->data) {
+	if (p80211_wep->data)
 		memcpy(ptr, p80211_wep->icv, sizeof(p80211_wep->icv));
-	}
 
 	/* Send the USB packet */
-	usb_fill_bulk_urb( &(hw->tx_urb), hw->usb,
-	               hw->endp_out,
-	               &(hw->txbuff), ROUNDUP64(usbpktlen),
-	               hfa384x_usbout_callback, hw->wlandev );
+	usb_fill_bulk_urb(&(hw->tx_urb), hw->usb,
+			  hw->endp_out,
+			  &(hw->txbuff), ROUNDUP64(usbpktlen),
+			  hfa384x_usbout_callback, hw->wlandev);
 	hw->tx_urb.transfer_flags |= USB_QUEUE_BULK;
 
 	result = 1;
 	ret = submit_tx_urb(hw, &hw->tx_urb, GFP_ATOMIC);
-	if ( ret != 0 ) {
-		WLAN_LOG_ERROR(
-			"submit_tx_urb() failed, error=%d\n", ret);
+	if (ret != 0) {
+		printk(KERN_ERR "submit_tx_urb() failed, error=%d\n", ret);
 		result = 3;
 	}
 
- exit:
-	DBFEXIT;
+exit:
 	return result;
 }
 
 void hfa384x_tx_timeout(wlandevice_t *wlandev)
 {
-	hfa384x_t	*hw = wlandev->priv;
+	hfa384x_t *hw = wlandev->priv;
 	unsigned long flags;
 
-	DBFENTER;
-
 	spin_lock_irqsave(&hw->ctlxq.lock, flags);
 
-	if ( !hw->wlandev->hwremoved &&
-	     /* Note the bitwise OR, not the logical OR. */
-	     ( !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags) |
-	       !test_and_set_bit(WORK_RX_HALT, &hw->usb_flags) ) )
-	{
+	if (!hw->wlandev->hwremoved &&
+	    /* Note the bitwise OR, not the logical OR. */
+	    (!test_and_set_bit(WORK_TX_HALT, &hw->usb_flags) |
+	     !test_and_set_bit(WORK_RX_HALT, &hw->usb_flags))) {
 		schedule_work(&hw->usb_work);
 	}
 
 	spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
-
-	DBFEXIT;
 }
 
 /*----------------------------------------------------------------
@@ -3257,12 +2846,10 @@
 ----------------------------------------------------------------*/
 static void hfa384x_usbctlx_reaper_task(unsigned long data)
 {
-	hfa384x_t	*hw = (hfa384x_t*)data;
+	hfa384x_t *hw = (hfa384x_t *) data;
 	struct list_head *entry;
 	struct list_head *temp;
-	unsigned long	flags;
-
-	DBFENTER;
+	unsigned long flags;
 
 	spin_lock_irqsave(&hw->ctlxq.lock, flags);
 
@@ -3270,7 +2857,7 @@
 	 * has unplugged the adapter.
 	 */
 	list_for_each_safe(entry, temp, &hw->ctlxq.reapable) {
-		hfa384x_usbctlx_t	*ctlx;
+		hfa384x_usbctlx_t *ctlx;
 
 		ctlx = list_entry(entry, hfa384x_usbctlx_t, list);
 		list_del(&ctlx->list);
@@ -3279,7 +2866,6 @@
 
 	spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
 
-	DBFEXIT;
 }
 
 /*----------------------------------------------------------------
@@ -3298,15 +2884,13 @@
 ----------------------------------------------------------------*/
 static void hfa384x_usbctlx_completion_task(unsigned long data)
 {
-	hfa384x_t *hw = (hfa384x_t*)data;
+	hfa384x_t *hw = (hfa384x_t *) data;
 	struct list_head *entry;
 	struct list_head *temp;
 	unsigned long flags;
 
 	int reap = 0;
 
-	DBFENTER;
-
 	spin_lock_irqsave(&hw->ctlxq.lock, flags);
 
 	/* This list is guaranteed to be empty if someone
@@ -3320,7 +2904,7 @@
 		/* Call the completion function that this
 		 * command was assigned, assuming it has one.
 		 */
-		if ( ctlx->cmdcb != NULL ) {
+		if (ctlx->cmdcb != NULL) {
 			spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
 			ctlx->cmdcb(hw, ctlx);
 			spin_lock_irqsave(&hw->ctlxq.lock, flags);
@@ -3333,8 +2917,7 @@
 			/* Did someone yank the adapter out
 			 * while our list was (briefly) unlocked?
 			 */
-			if ( hw->wlandev->hwremoved )
-			{
+			if (hw->wlandev->hwremoved) {
 				reap = 0;
 				break;
 			}
@@ -3345,7 +2928,7 @@
 		 * threads waiting for them to die. Hence they must
 		 * be delivered to The Reaper!
 		 */
-		if ( ctlx->reapable ) {
+		if (ctlx->reapable) {
 			/* Move the CTLX off the "completing" list (hopefully)
 			 * on to the "reapable" list where the reaper task
 			 * can find it. And "reapable" means that this CTLX
@@ -3361,8 +2944,6 @@
 
 	if (reap)
 		tasklet_schedule(&hw->reaper_bh);
-
-	DBFEXIT;
 }
 
 /*----------------------------------------------------------------
@@ -3382,12 +2963,11 @@
 * Call context:
 *	Either process or interrupt, but presumably interrupt
 ----------------------------------------------------------------*/
-static int unlocked_usbctlx_cancel_async(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
+static int unlocked_usbctlx_cancel_async(hfa384x_t *hw,
+					 hfa384x_usbctlx_t *ctlx)
 {
 	int ret;
 
-	DBFENTER;
-
 	/*
 	 * Try to delete the URB containing our request packet.
 	 * If we succeed, then its completion handler will be
@@ -3408,8 +2988,6 @@
 		ret = 0;
 	}
 
-	DBFEXIT;
-
 	return ret;
 }
 
@@ -3437,8 +3015,6 @@
 ----------------------------------------------------------------*/
 static void unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
 {
-	DBFENTER;
-
 	/* Timers have been stopped, and ctlx should be in
 	 * a terminal state. Retire it from the "active"
 	 * queue.
@@ -3453,13 +3029,11 @@
 		break;
 
 	default:
-		WLAN_LOG_ERROR("CTLX[%d] not in a terminating state(%s)\n",
-		               hfa384x2host_16(ctlx->outbuf.type),
-		               ctlxstr(ctlx->state));
+		printk(KERN_ERR "CTLX[%d] not in a terminating state(%s)\n",
+		       le16_to_cpu(ctlx->outbuf.type),
+		       ctlxstr(ctlx->state));
 		break;
-	} /* switch */
-
-	DBFEXIT;
+	}			/* switch */
 }
 
 /*----------------------------------------------------------------
@@ -3478,11 +3052,9 @@
 * Call context:
 *	any
 ----------------------------------------------------------------*/
-static void
-hfa384x_usbctlxq_run(hfa384x_t	*hw)
+static void hfa384x_usbctlxq_run(hfa384x_t *hw)
 {
-	unsigned long		flags;
-	DBFENTER;
+	unsigned long flags;
 
 	/* acquire lock */
 	spin_lock_irqsave(&hw->ctlxq.lock, flags);
@@ -3494,28 +3066,26 @@
 	 * Don't touch any of these CTLXs if the hardware
 	 * has been removed or the USB subsystem is stalled.
 	 */
-	if ( !list_empty(&hw->ctlxq.active) ||
-	     test_bit(WORK_TX_HALT, &hw->usb_flags) ||
-	     hw->wlandev->hwremoved )
+	if (!list_empty(&hw->ctlxq.active) ||
+	    test_bit(WORK_TX_HALT, &hw->usb_flags) || hw->wlandev->hwremoved)
 		goto unlock;
 
-	while ( !list_empty(&hw->ctlxq.pending) ) {
-		hfa384x_usbctlx_t	*head;
-		int			result;
+	while (!list_empty(&hw->ctlxq.pending)) {
+		hfa384x_usbctlx_t *head;
+		int result;
 
 		/* This is the first pending command */
 		head = list_entry(hw->ctlxq.pending.next,
-		                  hfa384x_usbctlx_t,
-		                  list);
+				  hfa384x_usbctlx_t, list);
 
 		/* We need to split this off to avoid a race condition */
 		list_move_tail(&head->list, &hw->ctlxq.active);
 
 		/* Fill the out packet */
-		usb_fill_bulk_urb( &(hw->ctlx_urb), hw->usb,
-		                   hw->endp_out,
-		                   &(head->outbuf), ROUNDUP64(head->outbufsize),
-		                   hfa384x_ctlxout_callback, hw);
+		usb_fill_bulk_urb(&(hw->ctlx_urb), hw->usb,
+				  hw->endp_out,
+				  &(head->outbuf), ROUNDUP64(head->outbufsize),
+				  hfa384x_ctlxout_callback, hw);
 		hw->ctlx_urb.transfer_flags |= USB_QUEUE_BULK;
 
 		/* Now submit the URB and update the CTLX's state
@@ -3531,7 +3101,7 @@
 
 			/* Start the IN wait timer */
 			hw->resp_timer_done = 0;
-			hw->resptimer.expires = jiffies + 2*HZ;
+			hw->resptimer.expires = jiffies + 2 * HZ;
 			add_timer(&hw->resptimer);
 
 			break;
@@ -3542,8 +3112,9 @@
 			 * this CTLX back in the "pending" queue
 			 * and schedule a reset ...
 			 */
-			WLAN_LOG_WARNING("%s tx pipe stalled: requesting reset\n",
-			                 hw->wlandev->netdev->name);
+			printk(KERN_WARNING
+			       "%s tx pipe stalled: requesting reset\n",
+			       hw->wlandev->netdev->name);
 			list_move(&head->list, &hw->ctlxq.pending);
 			set_bit(WORK_TX_HALT, &hw->usb_flags);
 			schedule_work(&hw->usb_work);
@@ -3551,23 +3122,20 @@
 		}
 
 		if (result == -ESHUTDOWN) {
-			WLAN_LOG_WARNING("%s urb shutdown!\n",
-					 hw->wlandev->netdev->name);
+			printk(KERN_WARNING "%s urb shutdown!\n",
+			       hw->wlandev->netdev->name);
 			break;
 		}
 
-		WLAN_LOG_ERROR("Failed to submit CTLX[%d]: error=%d\n",
-		               hfa384x2host_16(head->outbuf.type), result);
+		printk(KERN_ERR "Failed to submit CTLX[%d]: error=%d\n",
+		       le16_to_cpu(head->outbuf.type), result);
 		unlocked_usbctlx_complete(hw, head);
-	} /* while */
+	}			/* while */
 
-	unlock:
+unlock:
 	spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
-
-	DBFEXIT;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_usbin_callback
 *
@@ -3586,13 +3154,13 @@
 ----------------------------------------------------------------*/
 static void hfa384x_usbin_callback(struct urb *urb)
 {
-	wlandevice_t		*wlandev = urb->context;
-	hfa384x_t		*hw;
-	hfa384x_usbin_t		*usbin = (hfa384x_usbin_t *) urb->transfer_buffer;
-	struct sk_buff          *skb = NULL;
-	int			result;
-	int                     urb_status;
-	u16			type;
+	wlandevice_t *wlandev = urb->context;
+	hfa384x_t *hw;
+	hfa384x_usbin_t *usbin = (hfa384x_usbin_t *) urb->transfer_buffer;
+	struct sk_buff *skb = NULL;
+	int result;
+	int urb_status;
+	u16 type;
 
 	enum USBIN_ACTION {
 		HANDLE,
@@ -3600,11 +3168,7 @@
 		ABORT
 	} action;
 
-	DBFENTER;
-
-	if ( !wlandev ||
-	     !wlandev->netdev ||
-	     wlandev->hwremoved )
+	if (!wlandev || !wlandev->netdev || wlandev->hwremoved)
 		goto exit;
 
 	hw = wlandev->priv;
@@ -3612,9 +3176,8 @@
 		goto exit;
 
 	skb = hw->rx_urb_skb;
-	if (!skb || (skb->data != urb->transfer_buffer)) {
-		BUG();
-	}
+	BUG_ON(!skb || (skb->data != urb->transfer_buffer));
+
 	hw->rx_urb_skb = NULL;
 
 	/* Check for error conditions within the URB */
@@ -3623,7 +3186,7 @@
 		action = HANDLE;
 
 		/* Check for short packet */
-		if ( urb->actual_length == 0 ) {
+		if (urb->actual_length == 0) {
 			++(wlandev->linux_stats.rx_errors);
 			++(wlandev->linux_stats.rx_length_errors);
 			action = RESUBMIT;
@@ -3631,9 +3194,9 @@
 		break;
 
 	case -EPIPE:
-		WLAN_LOG_WARNING("%s rx pipe stalled: requesting reset\n",
-		                 wlandev->netdev->name);
-		if ( !test_and_set_bit(WORK_RX_HALT, &hw->usb_flags) )
+		printk(KERN_WARNING "%s rx pipe stalled: requesting reset\n",
+		       wlandev->netdev->name);
+		if (!test_and_set_bit(WORK_RX_HALT, &hw->usb_flags))
 			schedule_work(&hw->usb_work);
 		++(wlandev->linux_stats.rx_errors);
 		action = ABORT;
@@ -3642,8 +3205,8 @@
 	case -EILSEQ:
 	case -ETIMEDOUT:
 	case -EPROTO:
-		if ( !test_and_set_bit(THROTTLE_RX, &hw->usb_flags) &&
-		     !timer_pending(&hw->throttle) ) {
+		if (!test_and_set_bit(THROTTLE_RX, &hw->usb_flags) &&
+		    !timer_pending(&hw->throttle)) {
 			mod_timer(&hw->throttle, jiffies + THROTTLE_JIFFIES);
 		}
 		++(wlandev->linux_stats.rx_errors);
@@ -3657,19 +3220,20 @@
 
 	case -ENODEV:
 	case -ESHUTDOWN:
-		WLAN_LOG_DEBUG(3,"status=%d, device removed.\n", urb->status);
+		pr_debug("status=%d, device removed.\n", urb->status);
 		action = ABORT;
 		break;
 
 	case -ENOENT:
 	case -ECONNRESET:
-		WLAN_LOG_DEBUG(3,"status=%d, urb explicitly unlinked.\n", urb->status);
+		pr_debug("status=%d, urb explicitly unlinked.\n",
+		       urb->status);
 		action = ABORT;
 		break;
 
 	default:
-		WLAN_LOG_DEBUG(3,"urb status=%d, transfer flags=0x%x\n",
-		                 urb->status, urb->transfer_flags);
+		pr_debug("urb status=%d, transfer flags=0x%x\n",
+		       urb->status, urb->transfer_flags);
 		++(wlandev->linux_stats.rx_errors);
 		action = RESUBMIT;
 		break;
@@ -3682,9 +3246,9 @@
 		result = submit_rx_urb(hw, GFP_ATOMIC);
 
 		if (result != 0) {
-			WLAN_LOG_ERROR(
-				"Fatal, failed to resubmit rx_urb. error=%d\n",
-				result);
+			printk(KERN_ERR
+			       "Fatal, failed to resubmit rx_urb. error=%d\n",
+			       result);
 		}
 	}
 
@@ -3692,7 +3256,7 @@
 	/* Note: the check of the sw_support field, the type field doesn't
 	 *       have bit 12 set like the docs suggest.
 	 */
-	type = hfa384x2host_16(usbin->type);
+	type = le16_to_cpu(usbin->type);
 	if (HFA384x_USB_ISRXFRM(type)) {
 		if (action == HANDLE) {
 			if (usbin->txfrm.desc.sw_support == 0x0123) {
@@ -3728,30 +3292,28 @@
 		break;
 
 	case HFA384x_USB_BUFAVAIL:
-		WLAN_LOG_DEBUG(3,"Received BUFAVAIL packet, frmlen=%d\n",
-			usbin->bufavail.frmlen);
+		pr_debug("Received BUFAVAIL packet, frmlen=%d\n",
+		       usbin->bufavail.frmlen);
 		break;
 
 	case HFA384x_USB_ERROR:
-		WLAN_LOG_DEBUG(3,"Received USB_ERROR packet, errortype=%d\n",
-			usbin->usberror.errortype);
+		pr_debug("Received USB_ERROR packet, errortype=%d\n",
+		       usbin->usberror.errortype);
 		break;
 
 	default:
-		WLAN_LOG_DEBUG(3,"Unrecognized USBIN packet, type=%x, status=%d\n",
-			usbin->type, urb_status);
+		printk(KERN_DEBUG
+		       "Unrecognized USBIN packet, type=%x, status=%d\n",
+		       usbin->type, urb_status);
 		break;
-	} /* switch */
+	}			/* switch */
 
 exit:
 
 	if (skb)
 		dev_kfree_skb(skb);
-
-	DBFEXIT;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_usbin_ctlx
 *
@@ -3775,11 +3337,9 @@
 static void hfa384x_usbin_ctlx(hfa384x_t *hw, hfa384x_usbin_t *usbin,
 			       int urb_status)
 {
-	hfa384x_usbctlx_t	*ctlx;
-	int			run_queue = 0;
-	unsigned long		flags;
-
-	DBFENTER;
+	hfa384x_usbctlx_t *ctlx;
+	int run_queue = 0;
+	unsigned long flags;
 
 retry:
 	spin_lock_irqsave(&hw->ctlxq.lock, flags);
@@ -3788,9 +3348,8 @@
 	 * at any one time, and this is the CTLX that the
 	 * timers are waiting for.
 	 */
-	if ( list_empty(&hw->ctlxq.active) ) {
+	if (list_empty(&hw->ctlxq.active))
 		goto unlock;
-	}
 
 	/* Remove the "response timeout". It's possible that
 	 * we are already too late, and that the timeout is
@@ -3803,8 +3362,7 @@
 			spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
 			goto retry;
 		}
-	}
-	else {
+	} else {
 		hw->resp_timer_done = 1;
 	}
 
@@ -3819,15 +3377,16 @@
 		if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0)
 			run_queue = 1;
 	} else {
-		const u16 intype = (usbin->type&~host2hfa384x_16(0x8000));
+		const u16 intype = (usbin->type & ~cpu_to_le16(0x8000));
 
 		/*
 		 * Check that our message is what we're expecting ...
 		 */
 		if (ctlx->outbuf.type != intype) {
-			WLAN_LOG_WARNING("Expected IN[%d], received IN[%d] - ignored.\n",
-			                 hfa384x2host_16(ctlx->outbuf.type),
-			                 hfa384x2host_16(intype));
+			printk(KERN_WARNING
+			       "Expected IN[%d], received IN[%d] - ignored.\n",
+			       le16_to_cpu(ctlx->outbuf.type),
+			       le16_to_cpu(intype));
 			goto unlock;
 		}
 
@@ -3841,7 +3400,8 @@
 			 * our request has been acknowledged. Odd,
 			 * but our OUT URB is still alive...
 			 */
-			WLAN_LOG_DEBUG(0, "Causality violation: please reboot Universe, or email linux-wlan-devel@lists.linux-wlan.com\n");
+			printk(KERN_DEBUG
+			       "Causality violation: please reboot Universe, or email linux-wlan-devel@lists.linux-wlan.com\n");
 			ctlx->state = CTLX_RESP_COMPLETE;
 			break;
 
@@ -3860,14 +3420,15 @@
 			/*
 			 * Throw this CTLX away ...
 			 */
-			WLAN_LOG_ERROR("Matched IN URB, CTLX[%d] in invalid state(%s)."
-			               " Discarded.\n",
-			               hfa384x2host_16(ctlx->outbuf.type),
-			               ctlxstr(ctlx->state));
+			printk(KERN_ERR
+			       "Matched IN URB, CTLX[%d] in invalid state(%s)."
+			       " Discarded.\n",
+			       le16_to_cpu(ctlx->outbuf.type),
+			       ctlxstr(ctlx->state));
 			if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0)
 				run_queue = 1;
 			break;
-		} /* switch */
+		}		/* switch */
 	}
 
 unlock:
@@ -3875,11 +3436,8 @@
 
 	if (run_queue)
 		hfa384x_usbctlxq_run(hw);
-
-	DBFEXIT;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_usbin_txcompl
 *
@@ -3897,25 +3455,20 @@
 * Call context:
 *	interrupt
 ----------------------------------------------------------------*/
-static void hfa384x_usbin_txcompl(wlandevice_t *wlandev, hfa384x_usbin_t *usbin)
+static void hfa384x_usbin_txcompl(wlandevice_t *wlandev,
+				  hfa384x_usbin_t *usbin)
 {
-	u16			status;
-	DBFENTER;
+	u16 status;
 
-	status = hfa384x2host_16(usbin->type); /* yeah I know it says type...*/
+	status = le16_to_cpu(usbin->type);	/* yeah I know it says type... */
 
 	/* Was there an error? */
-	if (HFA384x_TXSTATUS_ISERROR(status)) {
+	if (HFA384x_TXSTATUS_ISERROR(status))
 		prism2sta_ev_txexc(wlandev, status);
-	} else {
+	else
 		prism2sta_ev_tx(wlandev, status);
-	}
-	// prism2sta_ev_alloc(wlandev);
-
-	DBFEXIT;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_usbin_rx
 *
@@ -3935,34 +3488,29 @@
 ----------------------------------------------------------------*/
 static void hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb)
 {
-	hfa384x_usbin_t         *usbin = (hfa384x_usbin_t *) skb->data;
-	hfa384x_t               *hw = wlandev->priv;
-	int                     hdrlen;
-	p80211_rxmeta_t         *rxmeta;
-	u16                  data_len;
-	u16                  fc;
-
-	DBFENTER;
+	hfa384x_usbin_t *usbin = (hfa384x_usbin_t *) skb->data;
+	hfa384x_t *hw = wlandev->priv;
+	int hdrlen;
+	p80211_rxmeta_t *rxmeta;
+	u16 data_len;
+	u16 fc;
 
 	/* Byte order convert once up front. */
-	usbin->rxfrm.desc.status =
-		hfa384x2host_16(usbin->rxfrm.desc.status);
-	usbin->rxfrm.desc.time =
-		hfa384x2host_32(usbin->rxfrm.desc.time);
+	usbin->rxfrm.desc.status = le16_to_cpu(usbin->rxfrm.desc.status);
+	usbin->rxfrm.desc.time = le32_to_cpu(usbin->rxfrm.desc.time);
 
 	/* Now handle frame based on port# */
-	switch( HFA384x_RXSTATUS_MACPORT_GET(usbin->rxfrm.desc.status) )
-	{
+	switch (HFA384x_RXSTATUS_MACPORT_GET(usbin->rxfrm.desc.status)) {
 	case 0:
-		fc = ieee2host16(usbin->rxfrm.desc.frame_control);
+		fc = le16_to_cpu(usbin->rxfrm.desc.frame_control);
 
 		/* If exclude and we receive an unencrypted, drop it */
-		if ( (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED) &&
-		     !WLAN_GET_FC_ISWEP(fc)){
+		if ((wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED) &&
+		    !WLAN_GET_FC_ISWEP(fc)) {
 			goto done;
 		}
 
-		data_len = hfa384x2host_16(usbin->rxfrm.desc.data_len);
+		data_len = le16_to_cpu(usbin->rxfrm.desc.data_len);
 
 		/* How much header data do we have? */
 		hdrlen = p80211_headerlen(fc);
@@ -3974,8 +3522,7 @@
 		 * with an "overlapping" copy
 		 */
 		memmove(skb_push(skb, hdrlen),
-		        &usbin->rxfrm.desc.frame_control,
-		        hdrlen);
+			&usbin->rxfrm.desc.frame_control, hdrlen);
 
 		skb->dev = wlandev->netdev;
 		skb->dev->last_rx = jiffies;
@@ -4001,24 +3548,24 @@
 		break;
 
 	case 7:
-		if ( ! HFA384x_RXSTATUS_ISFCSERR(usbin->rxfrm.desc.status) ) {
+		if (!HFA384x_RXSTATUS_ISFCSERR(usbin->rxfrm.desc.status)) {
 			/* Copy to wlansnif skb */
-			hfa384x_int_rxmonitor( wlandev, &usbin->rxfrm);
+			hfa384x_int_rxmonitor(wlandev, &usbin->rxfrm);
 			dev_kfree_skb(skb);
 		} else {
-			WLAN_LOG_DEBUG(3,"Received monitor frame: FCSerr set\n");
+			printk(KERN_DEBUG
+			       "Received monitor frame: FCSerr set\n");
 		}
 		break;
 
 	default:
-		WLAN_LOG_WARNING("Received frame on unsupported port=%d\n",
-			HFA384x_RXSTATUS_MACPORT_GET(usbin->rxfrm.desc.status) );
+		printk(KERN_WARNING "Received frame on unsupported port=%d\n",
+		       HFA384x_RXSTATUS_MACPORT_GET(usbin->rxfrm.desc.status));
 		goto done;
 		break;
 	}
 
 done:
-	DBFEXIT;
 	return;
 }
 
@@ -4043,97 +3590,93 @@
 * Call context:
 *	interrupt
 ----------------------------------------------------------------*/
-static void hfa384x_int_rxmonitor( wlandevice_t *wlandev, hfa384x_usb_rxfrm_t *rxfrm)
+static void hfa384x_int_rxmonitor(wlandevice_t *wlandev,
+				  hfa384x_usb_rxfrm_t *rxfrm)
 {
-	hfa384x_rx_frame_t              *rxdesc = &(rxfrm->desc);
-	unsigned int				hdrlen = 0;
-	unsigned int				datalen = 0;
-	unsigned int				skblen = 0;
-	u8				*datap;
-	u16				fc;
-	struct sk_buff			*skb;
-	hfa384x_t		        *hw = wlandev->priv;
+	hfa384x_rx_frame_t *rxdesc = &(rxfrm->desc);
+	unsigned int hdrlen = 0;
+	unsigned int datalen = 0;
+	unsigned int skblen = 0;
+	u8 *datap;
+	u16 fc;
+	struct sk_buff *skb;
+	hfa384x_t *hw = wlandev->priv;
 
-
-	DBFENTER;
 	/* Don't forget the status, time, and data_len fields are in host order */
 	/* Figure out how big the frame is */
-	fc = ieee2host16(rxdesc->frame_control);
+	fc = le16_to_cpu(rxdesc->frame_control);
 	hdrlen = p80211_headerlen(fc);
-	datalen = hfa384x2host_16(rxdesc->data_len);
+	datalen = le16_to_cpu(rxdesc->data_len);
 
 	/* Allocate an ind message+framesize skb */
-	skblen = sizeof(p80211_caphdr_t) +
-		hdrlen + datalen + WLAN_CRC_LEN;
+	skblen = sizeof(p80211_caphdr_t) + hdrlen + datalen + WLAN_CRC_LEN;
 
 	/* sanity check the length */
-	if ( skblen >
-	     (sizeof(p80211_caphdr_t) +
-	      WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN) ) {
-		WLAN_LOG_DEBUG(1, "overlen frm: len=%zd\n",
-			       skblen - sizeof(p80211_caphdr_t));
+	if (skblen >
+	    (sizeof(p80211_caphdr_t) +
+	     WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN)) {
+		pr_debug("overlen frm: len=%zd\n",
+		       skblen - sizeof(p80211_caphdr_t));
 	}
 
-	if ( (skb = dev_alloc_skb(skblen)) == NULL ) {
-		WLAN_LOG_ERROR("alloc_skb failed trying to allocate %d bytes\n", skblen);
+	if ((skb = dev_alloc_skb(skblen)) == NULL) {
+		printk(KERN_ERR
+		       "alloc_skb failed trying to allocate %d bytes\n",
+		       skblen);
 		return;
 	}
 
 	/* only prepend the prism header if in the right mode */
 	if ((wlandev->netdev->type == ARPHRD_IEEE80211_PRISM) &&
 	    (hw->sniffhdr != 0)) {
-		p80211_caphdr_t		*caphdr;
+		p80211_caphdr_t *caphdr;
 		/* The NEW header format! */
 		datap = skb_put(skb, sizeof(p80211_caphdr_t));
-		caphdr = (p80211_caphdr_t*) datap;
+		caphdr = (p80211_caphdr_t *) datap;
 
-		caphdr->version =	htonl(P80211CAPTURE_VERSION);
-		caphdr->length =	htonl(sizeof(p80211_caphdr_t));
-		caphdr->mactime =	__cpu_to_be64(rxdesc->time) * 1000;
-		caphdr->hosttime =	__cpu_to_be64(jiffies);
-		caphdr->phytype =	htonl(4); /* dss_dot11_b */
-		caphdr->channel =	htonl(hw->sniff_channel);
-		caphdr->datarate =	htonl(rxdesc->rate);
-		caphdr->antenna =	htonl(0); /* unknown */
-		caphdr->priority =	htonl(0); /* unknown */
-		caphdr->ssi_type =	htonl(3); /* rssi_raw */
-		caphdr->ssi_signal =	htonl(rxdesc->signal);
-		caphdr->ssi_noise =	htonl(rxdesc->silence);
-		caphdr->preamble =	htonl(0); /* unknown */
-		caphdr->encoding =	htonl(1); /* cck */
+		caphdr->version = htonl(P80211CAPTURE_VERSION);
+		caphdr->length = htonl(sizeof(p80211_caphdr_t));
+		caphdr->mactime = __cpu_to_be64(rxdesc->time) * 1000;
+		caphdr->hosttime = __cpu_to_be64(jiffies);
+		caphdr->phytype = htonl(4);	/* dss_dot11_b */
+		caphdr->channel = htonl(hw->sniff_channel);
+		caphdr->datarate = htonl(rxdesc->rate);
+		caphdr->antenna = htonl(0);	/* unknown */
+		caphdr->priority = htonl(0);	/* unknown */
+		caphdr->ssi_type = htonl(3);	/* rssi_raw */
+		caphdr->ssi_signal = htonl(rxdesc->signal);
+		caphdr->ssi_noise = htonl(rxdesc->silence);
+		caphdr->preamble = htonl(0);	/* unknown */
+		caphdr->encoding = htonl(1);	/* cck */
 	}
 
 	/* Copy the 802.11 header to the skb (ctl frames may be less than a full header) */
 	datap = skb_put(skb, hdrlen);
-	memcpy( datap, &(rxdesc->frame_control), hdrlen);
+	memcpy(datap, &(rxdesc->frame_control), hdrlen);
 
 	/* If any, copy the data from the card to the skb */
-	if ( datalen > 0 )
-	{
+	if (datalen > 0) {
 		datap = skb_put(skb, datalen);
 		memcpy(datap, rxfrm->data, datalen);
 
 		/* check for unencrypted stuff if WEP bit set. */
-		if (*(datap - hdrlen + 1) & 0x40) // wep set
-		  if ((*(datap) == 0xaa) && (*(datap+1) == 0xaa))
-		    *(datap - hdrlen + 1) &= 0xbf; // clear wep; it's the 802.2 header!
+		if (*(datap - hdrlen + 1) & 0x40)	/* wep set */
+			if ((*(datap) == 0xaa) && (*(datap + 1) == 0xaa))
+				*(datap - hdrlen + 1) &= 0xbf;	// clear wep; it's the 802.2 header!
 	}
 
 	if (hw->sniff_fcs) {
 		/* Set the FCS */
 		datap = skb_put(skb, WLAN_CRC_LEN);
-		memset( datap, 0xff, WLAN_CRC_LEN);
+		memset(datap, 0xff, WLAN_CRC_LEN);
 	}
 
 	/* pass it back up */
 	prism2sta_ev_rx(wlandev, skb);
 
-	DBFEXIT;
 	return;
 }
 
-
-
 /*----------------------------------------------------------------
 * hfa384x_usbin_info
 *
@@ -4151,18 +3694,13 @@
 * Call context:
 *	interrupt
 ----------------------------------------------------------------*/
-static void hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin)
+static void hfa384x_usbin_info(wlandevice_t * wlandev, hfa384x_usbin_t * usbin)
 {
-	DBFENTER;
-
-	usbin->infofrm.info.framelen = hfa384x2host_16(usbin->infofrm.info.framelen);
+	usbin->infofrm.info.framelen =
+	    le16_to_cpu(usbin->infofrm.info.framelen);
 	prism2sta_ev_info(wlandev, &usbin->infofrm.info);
-
-	DBFEXIT;
 }
 
-
-
 /*----------------------------------------------------------------
 * hfa384x_usbout_callback
 *
@@ -4181,48 +3719,49 @@
 ----------------------------------------------------------------*/
 static void hfa384x_usbout_callback(struct urb *urb)
 {
-	wlandevice_t		*wlandev = urb->context;
-	hfa384x_usbout_t	*usbout = urb->transfer_buffer;
-	DBFENTER;
+	wlandevice_t *wlandev = urb->context;
+	hfa384x_usbout_t *usbout = urb->transfer_buffer;
 
 #ifdef DEBUG_USB
 	dbprint_urb(urb);
 #endif
 
-	if ( wlandev &&
-	     wlandev->netdev ) {
+	if (wlandev && wlandev->netdev) {
 
-		switch(urb->status) {
+		switch (urb->status) {
 		case 0:
 			hfa384x_usbout_tx(wlandev, usbout);
 			break;
 
 		case -EPIPE:
-		{
-			hfa384x_t *hw = wlandev->priv;
-			WLAN_LOG_WARNING("%s tx pipe stalled: requesting reset\n",
-			                 wlandev->netdev->name);
-			if ( !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags) )
-				schedule_work(&hw->usb_work);
-			++(wlandev->linux_stats.tx_errors);
-			break;
-		}
+			{
+				hfa384x_t *hw = wlandev->priv;
+				printk(KERN_WARNING
+				       "%s tx pipe stalled: requesting reset\n",
+				       wlandev->netdev->name);
+				if (!test_and_set_bit
+				    (WORK_TX_HALT, &hw->usb_flags))
+					schedule_work(&hw->usb_work);
+				++(wlandev->linux_stats.tx_errors);
+				break;
+			}
 
 		case -EPROTO:
 		case -ETIMEDOUT:
 		case -EILSEQ:
-		{
-			hfa384x_t *hw = wlandev->priv;
+			{
+				hfa384x_t *hw = wlandev->priv;
 
-			if ( !test_and_set_bit(THROTTLE_TX, &hw->usb_flags)
-			     && !timer_pending(&hw->throttle) ) {
-				mod_timer(&hw->throttle,
-				          jiffies + THROTTLE_JIFFIES);
+				if (!test_and_set_bit
+				    (THROTTLE_TX, &hw->usb_flags)
+				    && !timer_pending(&hw->throttle)) {
+					mod_timer(&hw->throttle,
+						  jiffies + THROTTLE_JIFFIES);
+				}
+				++(wlandev->linux_stats.tx_errors);
+				netif_stop_queue(wlandev->netdev);
+				break;
 			}
-			++(wlandev->linux_stats.tx_errors);
-			netif_stop_queue(wlandev->netdev);
-			break;
-		}
 
 		case -ENOENT:
 		case -ESHUTDOWN:
@@ -4230,16 +3769,14 @@
 			break;
 
 		default:
-			WLAN_LOG_INFO("unknown urb->status=%d\n", urb->status);
+			printk(KERN_INFO "unknown urb->status=%d\n",
+			       urb->status);
 			++(wlandev->linux_stats.tx_errors);
 			break;
-		} /* switch */
+		}		/* switch */
 	}
-
-	DBFEXIT;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_ctlxout_callback
 *
@@ -4258,22 +3795,19 @@
 ----------------------------------------------------------------*/
 static void hfa384x_ctlxout_callback(struct urb *urb)
 {
-	hfa384x_t	*hw = urb->context;
-	int             delete_resptimer = 0;
-	int             timer_ok = 1;
-	int		run_queue = 0;
-	hfa384x_usbctlx_t	*ctlx;
-	unsigned long	flags;
+	hfa384x_t *hw = urb->context;
+	int delete_resptimer = 0;
+	int timer_ok = 1;
+	int run_queue = 0;
+	hfa384x_usbctlx_t *ctlx;
+	unsigned long flags;
 
-	DBFENTER;
-
-	WLAN_LOG_DEBUG(3,"urb->status=%d\n", urb->status);
+	pr_debug("urb->status=%d\n", urb->status);
 #ifdef DEBUG_USB
 	dbprint_urb(urb);
 #endif
-	if ( (urb->status == -ESHUTDOWN) ||
-	     (urb->status == -ENODEV) ||
-	     (hw == NULL) )
+	if ((urb->status == -ESHUTDOWN) ||
+	    (urb->status == -ENODEV) || (hw == NULL))
 		goto done;
 
 retry:
@@ -4285,7 +3819,7 @@
 	 * rely on the disconnect function to clean everything
 	 * up if someone unplugged the adapter.
 	 */
-	if ( list_empty(&hw->ctlxq.active) ) {
+	if (list_empty(&hw->ctlxq.active)) {
 		spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
 		goto done;
 	}
@@ -4304,16 +3838,15 @@
 			spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
 			goto retry;
 		}
-	}
-	else {
+	} else {
 		hw->req_timer_done = 1;
 	}
 
 	ctlx = get_active_ctlx(hw);
 
-	if ( urb->status == 0 ) {
+	if (urb->status == 0) {
 		/* Request portion of a CTLX is successful */
-		switch ( ctlx->state ) {
+		switch (ctlx->state) {
 		case CTLX_REQ_SUBMITTED:
 			/* This OUT-ACK received before IN */
 			ctlx->state = CTLX_REQ_COMPLETE;
@@ -4330,18 +3863,19 @@
 
 		default:
 			/* This is NOT a valid CTLX "success" state! */
-			WLAN_LOG_ERROR(
-			    "Illegal CTLX[%d] success state(%s, %d) in OUT URB\n",
-			    hfa384x2host_16(ctlx->outbuf.type),
-			    ctlxstr(ctlx->state), urb->status);
+			printk(KERN_ERR
+			       "Illegal CTLX[%d] success state(%s, %d) in OUT URB\n",
+			       le16_to_cpu(ctlx->outbuf.type),
+			       ctlxstr(ctlx->state), urb->status);
 			break;
-		} /* switch */
+		}		/* switch */
 	} else {
 		/* If the pipe has stalled then we need to reset it */
-		if ( (urb->status == -EPIPE) &&
-		      !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags) ) {
-			WLAN_LOG_WARNING("%s tx pipe stalled: requesting reset\n",
-			                 hw->wlandev->netdev->name);
+		if ((urb->status == -EPIPE) &&
+		    !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags)) {
+			printk(KERN_WARNING
+			       "%s tx pipe stalled: requesting reset\n",
+			       hw->wlandev->netdev->name);
 			schedule_work(&hw->usb_work);
 		}
 
@@ -4354,7 +3888,7 @@
 		run_queue = 1;
 	}
 
- delresp:
+delresp:
 	if (delete_resptimer) {
 		if ((timer_ok = del_timer(&hw->resptimer)) != 0) {
 			hw->resp_timer_done = 1;
@@ -4363,7 +3897,7 @@
 
 	spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
 
-	if ( !timer_ok && (hw->resp_timer_done == 0) ) {
+	if (!timer_ok && (hw->resp_timer_done == 0)) {
 		spin_lock_irqsave(&hw->ctlxq.lock, flags);
 		goto delresp;
 	}
@@ -4371,11 +3905,10 @@
 	if (run_queue)
 		hfa384x_usbctlxq_run(hw);
 
- done:
-	DBFEXIT;
+done:
+	;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_usbctlx_reqtimerfn
 *
@@ -4394,12 +3927,10 @@
 * Call context:
 *	interrupt
 ----------------------------------------------------------------*/
-static void
-hfa384x_usbctlx_reqtimerfn(unsigned long data)
+static void hfa384x_usbctlx_reqtimerfn(unsigned long data)
 {
-	hfa384x_t	*hw = (hfa384x_t*)data;
-	unsigned long   flags;
-	DBFENTER;
+	hfa384x_t *hw = (hfa384x_t *) data;
+	unsigned long flags;
 
 	spin_lock_irqsave(&hw->ctlxq.lock, flags);
 
@@ -4408,15 +3939,13 @@
 	/* Removing the hardware automatically empties
 	 * the active list ...
 	 */
-	if ( !list_empty(&hw->ctlxq.active) )
-	{
+	if (!list_empty(&hw->ctlxq.active)) {
 		/*
 		 * We must ensure that our URB is removed from
 		 * the system, if it hasn't already expired.
 		 */
 		hw->ctlx_urb.transfer_flags |= URB_ASYNC_UNLINK;
-		if (usb_unlink_urb(&hw->ctlx_urb) == -EINPROGRESS)
-		{
+		if (usb_unlink_urb(&hw->ctlx_urb) == -EINPROGRESS) {
 			hfa384x_usbctlx_t *ctlx = get_active_ctlx(hw);
 
 			ctlx->state = CTLX_REQ_FAILED;
@@ -4436,11 +3965,8 @@
 	}
 
 	spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
-
-	DBFEXIT;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_usbctlx_resptimerfn
 *
@@ -4459,13 +3985,10 @@
 * Call context:
 *	interrupt
 ----------------------------------------------------------------*/
-static void
-hfa384x_usbctlx_resptimerfn(unsigned long data)
+static void hfa384x_usbctlx_resptimerfn(unsigned long data)
 {
-	hfa384x_t *hw = (hfa384x_t*)data;
-	unsigned long   flags;
-
-	DBFENTER;
+	hfa384x_t *hw = (hfa384x_t *) data;
+	unsigned long flags;
 
 	spin_lock_irqsave(&hw->ctlxq.lock, flags);
 
@@ -4474,12 +3997,10 @@
 	/* The active list will be empty if the
 	 * adapter has been unplugged ...
 	 */
-	if ( !list_empty(&hw->ctlxq.active) )
-	{
+	if (!list_empty(&hw->ctlxq.active)) {
 		hfa384x_usbctlx_t *ctlx = get_active_ctlx(hw);
 
-		if ( unlocked_usbctlx_cancel_async(hw, ctlx) == 0 )
-		{
+		if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0) {
 			spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
 			hfa384x_usbctlxq_run(hw);
 			goto done;
@@ -4488,8 +4009,9 @@
 
 	spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
 
- done:
-	DBFEXIT;
+done:
+	;
+
 }
 
 /*----------------------------------------------------------------
@@ -4507,13 +4029,10 @@
 * Call context:
 *	Interrupt
 ----------------------------------------------------------------*/
-static void
-hfa384x_usb_throttlefn(unsigned long data)
+static void hfa384x_usb_throttlefn(unsigned long data)
 {
-	hfa384x_t *hw = (hfa384x_t*)data;
-	unsigned long   flags;
-
-	DBFENTER;
+	hfa384x_t *hw = (hfa384x_t *) data;
+	unsigned long flags;
 
 	spin_lock_irqsave(&hw->ctlxq.lock, flags);
 
@@ -4521,25 +4040,20 @@
 	 * We need to check BOTH the RX and the TX throttle controls,
 	 * so we use the bitwise OR instead of the logical OR.
 	 */
-	WLAN_LOG_DEBUG(3, "flags=0x%lx\n", hw->usb_flags);
-	if ( !hw->wlandev->hwremoved &&
-	     (
-	       (test_and_clear_bit(THROTTLE_RX, &hw->usb_flags) &&
-	       !test_and_set_bit(WORK_RX_RESUME, &hw->usb_flags))
-	       |
-	       (test_and_clear_bit(THROTTLE_TX, &hw->usb_flags) &&
-	        !test_and_set_bit(WORK_TX_RESUME, &hw->usb_flags))
-	     ) )
-	{
+	pr_debug("flags=0x%lx\n", hw->usb_flags);
+	if (!hw->wlandev->hwremoved &&
+	    ((test_and_clear_bit(THROTTLE_RX, &hw->usb_flags) &&
+	      !test_and_set_bit(WORK_RX_RESUME, &hw->usb_flags))
+	     |
+	     (test_and_clear_bit(THROTTLE_TX, &hw->usb_flags) &&
+	      !test_and_set_bit(WORK_TX_RESUME, &hw->usb_flags))
+	    )) {
 		schedule_work(&hw->usb_work);
 	}
 
 	spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
-
-	DBFEXIT;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_usbctlx_submit
 *
@@ -4558,16 +4072,11 @@
 * Call context:
 *	process or interrupt
 ----------------------------------------------------------------*/
-static int
-hfa384x_usbctlx_submit(
-	hfa384x_t		*hw,
-	hfa384x_usbctlx_t	*ctlx)
+static int hfa384x_usbctlx_submit(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
 {
 	unsigned long flags;
 	int ret;
 
-	DBFENTER;
-
 	spin_lock_irqsave(&hw->ctlxq.lock, flags);
 
 	if (hw->wlandev->hwremoved) {
@@ -4582,11 +4091,9 @@
 		ret = 0;
 	}
 
-	DBFEXIT;
 	return ret;
 }
 
-
 /*----------------------------------------------------------------
 * hfa384x_usbout_tx
 *
@@ -4608,11 +4115,7 @@
 ----------------------------------------------------------------*/
 static void hfa384x_usbout_tx(wlandevice_t *wlandev, hfa384x_usbout_t *usbout)
 {
-	DBFENTER;
-
 	prism2sta_ev_alloc(wlandev);
-
-	DBFEXIT;
 }
 
 /*----------------------------------------------------------------
@@ -4631,10 +4134,9 @@
 *
 * Call context:
 ----------------------------------------------------------------*/
-static int
-hfa384x_isgood_pdrcode(u16 pdrcode)
+static int hfa384x_isgood_pdrcode(u16 pdrcode)
 {
-	switch(pdrcode) {
+	switch (pdrcode) {
 	case HFA384x_PDR_END_OF_PDA:
 	case HFA384x_PDR_PCB_PARTNUM:
 	case HFA384x_PDR_PDAVER:
@@ -4668,23 +4170,20 @@
 		return 1;
 		break;
 	default:
-		if ( pdrcode < 0x1000 ) {
+		if (pdrcode < 0x1000) {
 			/* code is OK, but we don't know exactly what it is */
-			WLAN_LOG_DEBUG(3,
-				"Encountered unknown PDR#=0x%04x, "
-				"assuming it's ok.\n",
-				pdrcode);
+			printk(KERN_DEBUG
+			       "Encountered unknown PDR#=0x%04x, "
+			       "assuming it's ok.\n", pdrcode);
 			return 1;
 		} else {
 			/* bad code */
-			WLAN_LOG_DEBUG(3,
-				"Encountered unknown PDR#=0x%04x, "
-				"(>=0x1000), assuming it's bad.\n",
-				pdrcode);
+			printk(KERN_DEBUG
+			       "Encountered unknown PDR#=0x%04x, "
+			       "(>=0x1000), assuming it's bad.\n", pdrcode);
 			return 0;
 		}
 		break;
 	}
-	return 0; /* avoid compiler warnings */
+	return 0;		/* avoid compiler warnings */
 }
-
diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c
index dfc7b3a..2abce0c 100644
--- a/drivers/staging/wlan-ng/p80211conv.c
+++ b/drivers/staging/wlan-ng/p80211conv.c
@@ -48,10 +48,8 @@
 * 802.11 frame conversions.
 *
 * --------------------------------------------------------------------
-*/
-/*================================================================*/
-/* System Includes */
-
+*
+*================================================================ */
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -63,14 +61,10 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/if_ether.h>
+#include <linux/byteorder/generic.h>
 
 #include <asm/byteorder.h>
 
-#include "wlan_compat.h"
-
-/*================================================================*/
-/* Project Includes */
-
 #include "p80211types.h"
 #include "p80211hdr.h"
 #include "p80211conv.h"
@@ -80,30 +74,8 @@
 #include "p80211ioctl.h"
 #include "p80211req.h"
 
-
-/*================================================================*/
-/* Local Constants */
-
-/*================================================================*/
-/* Local Macros */
-
-
-/*================================================================*/
-/* Local Types */
-
-
-/*================================================================*/
-/* Local Static Definitions */
-
-static u8	oui_rfc1042[] = {0x00, 0x00, 0x00};
-static u8	oui_8021h[] = {0x00, 0x00, 0xf8};
-
-/*================================================================*/
-/* Local Function Declarations */
-
-
-/*================================================================*/
-/* Function Definitions */
+static u8 oui_rfc1042[] = { 0x00, 0x00, 0x00 };
+static u8 oui_8021h[] = { 0x00, 0x00, 0xf8 };
 
 /*----------------------------------------------------------------
 * p80211pb_ether_to_80211
@@ -130,35 +102,36 @@
 * Call context:
 *	May be called in interrupt or non-interrupt context
 ----------------------------------------------------------------*/
-int skb_ether_to_p80211( wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep)
+int skb_ether_to_p80211(wlandevice_t *wlandev, u32 ethconv,
+			struct sk_buff *skb, p80211_hdr_t *p80211_hdr,
+			p80211_metawep_t *p80211_wep)
 {
 
-	u16          fc;
-	u16          proto;
-	wlan_ethhdr_t   e_hdr;
-	wlan_llc_t      *e_llc;
-	wlan_snap_t     *e_snap;
+	u16 fc;
+	u16 proto;
+	wlan_ethhdr_t e_hdr;
+	wlan_llc_t *e_llc;
+	wlan_snap_t *e_snap;
 	int foo;
 
-	DBFENTER;
 	memcpy(&e_hdr, skb->data, sizeof(e_hdr));
 
 	if (skb->len <= 0) {
-		WLAN_LOG_DEBUG(1, "zero-length skb!\n");
+		pr_debug("zero-length skb!\n");
 		return 1;
 	}
 
-	if ( ethconv == WLAN_ETHCONV_ENCAP ) { /* simplest case */
-	        WLAN_LOG_DEBUG(3, "ENCAP len: %d\n", skb->len);
+	if (ethconv == WLAN_ETHCONV_ENCAP) {	/* simplest case */
+		pr_debug("ENCAP len: %d\n", skb->len);
 		/* here, we don't care what kind of ether frm. Just stick it */
 		/*  in the 80211 payload */
 		/* which is to say, leave the skb alone. */
 	} else {
 		/* step 1: classify ether frame, DIX or 802.3? */
 		proto = ntohs(e_hdr.type);
-		if ( proto <= 1500 ) {
-		        WLAN_LOG_DEBUG(3, "802.3 len: %d\n", skb->len);
-                        /* codes <= 1500 reserved for 802.3 lengths */
+		if (proto <= 1500) {
+			pr_debug("802.3 len: %d\n", skb->len);
+			/* codes <= 1500 reserved for 802.3 lengths */
 			/* it's 802.3, pass ether payload unchanged,  */
 
 			/* trim off ethernet header */
@@ -167,23 +140,28 @@
 			/*   leave off any PAD octets.  */
 			skb_trim(skb, proto);
 		} else {
-		        WLAN_LOG_DEBUG(3, "DIXII len: %d\n", skb->len);
+			pr_debug("DIXII len: %d\n", skb->len);
 			/* it's DIXII, time for some conversion */
 
 			/* trim off ethernet header */
 			skb_pull(skb, WLAN_ETHHDR_LEN);
 
 			/* tack on SNAP */
-			e_snap = (wlan_snap_t *) skb_push(skb, sizeof(wlan_snap_t));
+			e_snap =
+			    (wlan_snap_t *) skb_push(skb, sizeof(wlan_snap_t));
 			e_snap->type = htons(proto);
-			if ( ethconv == WLAN_ETHCONV_8021h && p80211_stt_findproto(proto) ) {
-				memcpy( e_snap->oui, oui_8021h, WLAN_IEEE_OUI_LEN);
+			if (ethconv == WLAN_ETHCONV_8021h
+			    && p80211_stt_findproto(proto)) {
+				memcpy(e_snap->oui, oui_8021h,
+				       WLAN_IEEE_OUI_LEN);
 			} else {
-				memcpy( e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN);
+				memcpy(e_snap->oui, oui_rfc1042,
+				       WLAN_IEEE_OUI_LEN);
 			}
 
 			/* tack on llc */
-			e_llc = (wlan_llc_t *) skb_push(skb, sizeof(wlan_llc_t));
+			e_llc =
+			    (wlan_llc_t *) skb_push(skb, sizeof(wlan_llc_t));
 			e_llc->dsap = 0xAA;	/* SNAP, see IEEE 802 */
 			e_llc->ssap = 0xAA;
 			e_llc->ctl = 0x03;
@@ -193,62 +171,61 @@
 
 	/* Set up the 802.11 header */
 	/* It's a data frame */
-	fc = host2ieee16( WLAN_SET_FC_FTYPE(WLAN_FTYPE_DATA) |
-			  WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DATAONLY));
+	fc = cpu_to_le16(WLAN_SET_FC_FTYPE(WLAN_FTYPE_DATA) |
+			 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DATAONLY));
 
-	switch ( wlandev->macmode ) {
+	switch (wlandev->macmode) {
 	case WLAN_MACMODE_IBSS_STA:
-		memcpy(p80211_hdr->a3.a1, &e_hdr.daddr, WLAN_ADDR_LEN);
-		memcpy(p80211_hdr->a3.a2, wlandev->netdev->dev_addr, WLAN_ADDR_LEN);
-		memcpy(p80211_hdr->a3.a3, wlandev->bssid, WLAN_ADDR_LEN);
+		memcpy(p80211_hdr->a3.a1, &e_hdr.daddr, ETH_ALEN);
+		memcpy(p80211_hdr->a3.a2, wlandev->netdev->dev_addr, ETH_ALEN);
+		memcpy(p80211_hdr->a3.a3, wlandev->bssid, ETH_ALEN);
 		break;
 	case WLAN_MACMODE_ESS_STA:
-		fc |= host2ieee16(WLAN_SET_FC_TODS(1));
-		memcpy(p80211_hdr->a3.a1, wlandev->bssid, WLAN_ADDR_LEN);
-		memcpy(p80211_hdr->a3.a2, wlandev->netdev->dev_addr, WLAN_ADDR_LEN);
-		memcpy(p80211_hdr->a3.a3, &e_hdr.daddr, WLAN_ADDR_LEN);
+		fc |= cpu_to_le16(WLAN_SET_FC_TODS(1));
+		memcpy(p80211_hdr->a3.a1, wlandev->bssid, ETH_ALEN);
+		memcpy(p80211_hdr->a3.a2, wlandev->netdev->dev_addr, ETH_ALEN);
+		memcpy(p80211_hdr->a3.a3, &e_hdr.daddr, ETH_ALEN);
 		break;
 	case WLAN_MACMODE_ESS_AP:
-		fc |= host2ieee16(WLAN_SET_FC_FROMDS(1));
-		memcpy(p80211_hdr->a3.a1, &e_hdr.daddr, WLAN_ADDR_LEN);
-		memcpy(p80211_hdr->a3.a2, wlandev->bssid, WLAN_ADDR_LEN);
-		memcpy(p80211_hdr->a3.a3, &e_hdr.saddr, WLAN_ADDR_LEN);
+		fc |= cpu_to_le16(WLAN_SET_FC_FROMDS(1));
+		memcpy(p80211_hdr->a3.a1, &e_hdr.daddr, ETH_ALEN);
+		memcpy(p80211_hdr->a3.a2, wlandev->bssid, ETH_ALEN);
+		memcpy(p80211_hdr->a3.a3, &e_hdr.saddr, ETH_ALEN);
 		break;
 	default:
-		WLAN_LOG_ERROR("Error: Converting eth to wlan in unknown mode.\n");
+		printk(KERN_ERR
+		       "Error: Converting eth to wlan in unknown mode.\n");
 		return 1;
 		break;
 	}
 
 	p80211_wep->data = NULL;
 
-	if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) && (wlandev->hostwep & HOSTWEP_ENCRYPT)) {
-		// XXXX need to pick keynum other than default?
+	if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED)
+	    && (wlandev->hostwep & HOSTWEP_ENCRYPT)) {
+		/* XXXX need to pick keynum other than default? */
 
-#if 1
 		p80211_wep->data = kmalloc(skb->len, GFP_ATOMIC);
-#else
-		p80211_wep->data = skb->data;
-#endif
 
 		if ((foo = wep_encrypt(wlandev, skb->data, p80211_wep->data,
 				       skb->len,
-				(wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK),
-				p80211_wep->iv, p80211_wep->icv))) {
-			WLAN_LOG_WARNING("Host en-WEP failed, dropping frame (%d).\n", foo);
+				       (wlandev->
+					hostwep & HOSTWEP_DEFAULTKEY_MASK),
+				       p80211_wep->iv, p80211_wep->icv))) {
+			printk(KERN_WARNING
+			       "Host en-WEP failed, dropping frame (%d).\n",
+			       foo);
 			return 2;
 		}
-		fc |= host2ieee16(WLAN_SET_FC_ISWEP(1));
+		fc |= cpu_to_le16(WLAN_SET_FC_ISWEP(1));
 	}
 
-
-	//	skb->nh.raw = skb->data;
+	/*      skb->nh.raw = skb->data; */
 
 	p80211_hdr->a3.fc = fc;
 	p80211_hdr->a3.dur = 0;
 	p80211_hdr->a3.seq = 0;
 
-	DBFEXIT;
 	return 0;
 }
 
@@ -256,22 +233,24 @@
 static void orinoco_spy_gather(wlandevice_t *wlandev, char *mac,
 			       p80211_rxmeta_t *rxmeta)
 {
-        int i;
+	int i;
 
-        /* Gather wireless spy statistics: for each packet, compare the
-         * source address with out list, and if match, get the stats... */
+	/* Gather wireless spy statistics: for each packet, compare the
+	 * source address with out list, and if match, get the stats... */
 
-        for (i = 0; i < wlandev->spy_number; i++) {
+	for (i = 0; i < wlandev->spy_number; i++) {
 
-                if (!memcmp(wlandev->spy_address[i], mac, ETH_ALEN)) {
+		if (!memcmp(wlandev->spy_address[i], mac, ETH_ALEN)) {
 			memcpy(wlandev->spy_address[i], mac, ETH_ALEN);
-                        wlandev->spy_stat[i].level = rxmeta->signal;
-                        wlandev->spy_stat[i].noise = rxmeta->noise;
-                        wlandev->spy_stat[i].qual = (rxmeta->signal > rxmeta->noise) ? \
-                                                     (rxmeta->signal - rxmeta->noise) : 0;
-                        wlandev->spy_stat[i].updated = 0x7;
-                }
-        }
+			wlandev->spy_stat[i].level = rxmeta->signal;
+			wlandev->spy_stat[i].noise = rxmeta->noise;
+			wlandev->spy_stat[i].qual =
+			    (rxmeta->signal >
+			     rxmeta->noise) ? (rxmeta->signal -
+					       rxmeta->noise) : 0;
+			wlandev->spy_stat[i].updated = 0x7;
+		}
+	}
 }
 
 /*----------------------------------------------------------------
@@ -293,43 +272,42 @@
 * Call context:
 *	May be called in interrupt or non-interrupt context
 ----------------------------------------------------------------*/
-int skb_p80211_to_ether( wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb)
+int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv,
+			struct sk_buff *skb)
 {
-	netdevice_t     *netdev = wlandev->netdev;
-	u16          fc;
-	unsigned int            payload_length;
-	unsigned int            payload_offset;
-	u8		daddr[WLAN_ETHADDR_LEN];
-	u8		saddr[WLAN_ETHADDR_LEN];
-	p80211_hdr_t    *w_hdr;
-	wlan_ethhdr_t   *e_hdr;
-	wlan_llc_t      *e_llc;
-	wlan_snap_t     *e_snap;
+	netdevice_t *netdev = wlandev->netdev;
+	u16 fc;
+	unsigned int payload_length;
+	unsigned int payload_offset;
+	u8 daddr[WLAN_ETHADDR_LEN];
+	u8 saddr[WLAN_ETHADDR_LEN];
+	p80211_hdr_t *w_hdr;
+	wlan_ethhdr_t *e_hdr;
+	wlan_llc_t *e_llc;
+	wlan_snap_t *e_snap;
 
 	int foo;
 
-	DBFENTER;
-
 	payload_length = skb->len - WLAN_HDR_A3_LEN - WLAN_CRC_LEN;
 	payload_offset = WLAN_HDR_A3_LEN;
 
 	w_hdr = (p80211_hdr_t *) skb->data;
 
-        /* setup some vars for convenience */
-	fc = ieee2host16(w_hdr->a3.fc);
-	if ( (WLAN_GET_FC_TODS(fc) == 0) && (WLAN_GET_FC_FROMDS(fc) == 0) ) {
+	/* setup some vars for convenience */
+	fc = le16_to_cpu(w_hdr->a3.fc);
+	if ((WLAN_GET_FC_TODS(fc) == 0) && (WLAN_GET_FC_FROMDS(fc) == 0)) {
 		memcpy(daddr, w_hdr->a3.a1, WLAN_ETHADDR_LEN);
 		memcpy(saddr, w_hdr->a3.a2, WLAN_ETHADDR_LEN);
-	} else if( (WLAN_GET_FC_TODS(fc) == 0) && (WLAN_GET_FC_FROMDS(fc) == 1) ) {
+	} else if ((WLAN_GET_FC_TODS(fc) == 0) && (WLAN_GET_FC_FROMDS(fc) == 1)) {
 		memcpy(daddr, w_hdr->a3.a1, WLAN_ETHADDR_LEN);
 		memcpy(saddr, w_hdr->a3.a3, WLAN_ETHADDR_LEN);
-	} else if( (WLAN_GET_FC_TODS(fc) == 1) && (WLAN_GET_FC_FROMDS(fc) == 0) ) {
+	} else if ((WLAN_GET_FC_TODS(fc) == 1) && (WLAN_GET_FC_FROMDS(fc) == 0)) {
 		memcpy(daddr, w_hdr->a3.a3, WLAN_ETHADDR_LEN);
 		memcpy(saddr, w_hdr->a3.a2, WLAN_ETHADDR_LEN);
 	} else {
 		payload_offset = WLAN_HDR_A4_LEN;
 		if (payload_length < WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN) {
-			WLAN_LOG_ERROR("A4 frame too short!\n");
+			printk(KERN_ERR "A4 frame too short!\n");
 			return 1;
 		}
 		payload_length -= (WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN);
@@ -338,18 +316,22 @@
 	}
 
 	/* perform de-wep if necessary.. */
-	if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) && WLAN_GET_FC_ISWEP(fc) && (wlandev->hostwep & HOSTWEP_DECRYPT)) {
+	if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) && WLAN_GET_FC_ISWEP(fc)
+	    && (wlandev->hostwep & HOSTWEP_DECRYPT)) {
 		if (payload_length <= 8) {
-			WLAN_LOG_ERROR("WEP frame too short (%u).\n",
-					skb->len);
+			printk(KERN_ERR "WEP frame too short (%u).\n",
+			       skb->len);
 			return 1;
 		}
 		if ((foo = wep_decrypt(wlandev, skb->data + payload_offset + 4,
 				       payload_length - 8, -1,
 				       skb->data + payload_offset,
-				       skb->data + payload_offset + payload_length - 4))) {
+				       skb->data + payload_offset +
+				       payload_length - 4))) {
 			/* de-wep failed, drop skb. */
-			WLAN_LOG_DEBUG(1, "Host de-WEP failed, dropping frame (%d).\n", foo);
+			printk(KERN_DEBUG
+			       "Host de-WEP failed, dropping frame (%d).\n",
+			       foo);
 			wlandev->rx.decrypt_err++;
 			return 2;
 		}
@@ -367,21 +349,22 @@
 	e_hdr = (wlan_ethhdr_t *) (skb->data + payload_offset);
 
 	e_llc = (wlan_llc_t *) (skb->data + payload_offset);
-	e_snap = (wlan_snap_t *) (skb->data + payload_offset + sizeof(wlan_llc_t));
+	e_snap =
+	    (wlan_snap_t *) (skb->data + payload_offset + sizeof(wlan_llc_t));
 
 	/* Test for the various encodings */
-	if ( (payload_length >= sizeof(wlan_ethhdr_t)) &&
-	     ( e_llc->dsap != 0xaa || e_llc->ssap != 0xaa ) &&
-	     ((memcmp(daddr, e_hdr->daddr, WLAN_ETHADDR_LEN) == 0) ||
+	if ((payload_length >= sizeof(wlan_ethhdr_t)) &&
+	    (e_llc->dsap != 0xaa || e_llc->ssap != 0xaa) &&
+	    ((memcmp(daddr, e_hdr->daddr, WLAN_ETHADDR_LEN) == 0) ||
 	     (memcmp(saddr, e_hdr->saddr, WLAN_ETHADDR_LEN) == 0))) {
-		WLAN_LOG_DEBUG(3, "802.3 ENCAP len: %d\n", payload_length);
+		pr_debug("802.3 ENCAP len: %d\n", payload_length);
 		/* 802.3 Encapsulated */
 		/* Test for an overlength frame */
-		if ( payload_length > (netdev->mtu + WLAN_ETHHDR_LEN)) {
+		if (payload_length > (netdev->mtu + WLAN_ETHHDR_LEN)) {
 			/* A bogus length ethfrm has been encap'd. */
 			/* Is someone trying an oflow attack? */
-			WLAN_LOG_ERROR("ENCAP frame too large (%d > %d)\n",
-				payload_length, netdev->mtu + WLAN_ETHHDR_LEN);
+			printk(KERN_ERR "ENCAP frame too large (%d > %d)\n",
+			       payload_length, netdev->mtu + WLAN_ETHHDR_LEN);
 			return 1;
 		}
 
@@ -390,25 +373,25 @@
 		/* chop off the 802.11 CRC */
 		skb_trim(skb, skb->len - WLAN_CRC_LEN);
 
-	} else if ((payload_length >= sizeof(wlan_llc_t) + sizeof(wlan_snap_t)) &&
-		   (e_llc->dsap == 0xaa) &&
-		   (e_llc->ssap == 0xaa) &&
-		   (e_llc->ctl == 0x03) &&
-		   (((memcmp( e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN)==0) &&
-		    (ethconv == WLAN_ETHCONV_8021h) &&
-		    (p80211_stt_findproto(ieee2host16(e_snap->type)))) ||
-		    (memcmp( e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN)!=0)))
-	{
-		WLAN_LOG_DEBUG(3, "SNAP+RFC1042 len: %d\n", payload_length);
+	} else if ((payload_length >= sizeof(wlan_llc_t) + sizeof(wlan_snap_t))
+		   && (e_llc->dsap == 0xaa) && (e_llc->ssap == 0xaa)
+		   && (e_llc->ctl == 0x03)
+		   &&
+		   (((memcmp(e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN) == 0)
+		     && (ethconv == WLAN_ETHCONV_8021h)
+		     && (p80211_stt_findproto(le16_to_cpu(e_snap->type))))
+		    || (memcmp(e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN) !=
+			0))) {
+		pr_debug("SNAP+RFC1042 len: %d\n", payload_length);
 		/* it's a SNAP + RFC1042 frame && protocol is in STT */
 		/* build 802.3 + RFC1042 */
 
 		/* Test for an overlength frame */
-		if ( payload_length > netdev->mtu ) {
+		if (payload_length > netdev->mtu) {
 			/* A bogus length ethfrm has been sent. */
 			/* Is someone trying an oflow attack? */
-			WLAN_LOG_ERROR("SNAP frame too large (%d > %d)\n",
-				payload_length, netdev->mtu);
+			printk(KERN_ERR "SNAP frame too large (%d > %d)\n",
+			       payload_length, netdev->mtu);
 			return 1;
 		}
 
@@ -424,11 +407,10 @@
 		/* chop off the 802.11 CRC */
 		skb_trim(skb, skb->len - WLAN_CRC_LEN);
 
-	}  else if ((payload_length >= sizeof(wlan_llc_t) + sizeof(wlan_snap_t)) &&
-		    (e_llc->dsap == 0xaa) &&
-		    (e_llc->ssap == 0xaa) &&
-		    (e_llc->ctl == 0x03) ) {
-		WLAN_LOG_DEBUG(3, "802.1h/RFC1042 len: %d\n", payload_length);
+	} else if ((payload_length >= sizeof(wlan_llc_t) + sizeof(wlan_snap_t))
+		   && (e_llc->dsap == 0xaa) && (e_llc->ssap == 0xaa)
+		   && (e_llc->ctl == 0x03)) {
+		pr_debug("802.1h/RFC1042 len: %d\n", payload_length);
 		/* it's an 802.1h frame || (an RFC1042 && protocol is not in STT) */
 		/* build a DIXII + RFC894 */
 
@@ -437,10 +419,9 @@
 		    > netdev->mtu) {
 			/* A bogus length ethfrm has been sent. */
 			/* Is someone trying an oflow attack? */
-			WLAN_LOG_ERROR("DIXII frame too large (%ld > %d)\n",
-					(long int) (payload_length - sizeof(wlan_llc_t) -
-						    sizeof(wlan_snap_t)),
-					netdev->mtu);
+			printk(KERN_ERR "DIXII frame too large (%ld > %d)\n",
+			       (long int)(payload_length - sizeof(wlan_llc_t) -
+					  sizeof(wlan_snap_t)), netdev->mtu);
 			return 1;
 		}
 
@@ -462,19 +443,18 @@
 		/* chop off the 802.11 CRC */
 		skb_trim(skb, skb->len - WLAN_CRC_LEN);
 	} else {
-		WLAN_LOG_DEBUG(3, "NON-ENCAP len: %d\n", payload_length);
+		pr_debug("NON-ENCAP len: %d\n", payload_length);
 		/* any NON-ENCAP */
 		/* it's a generic 80211+LLC or IPX 'Raw 802.3' */
 		/*  build an 802.3 frame */
 		/* allocate space and setup hostbuf */
 
 		/* Test for an overlength frame */
-		if ( payload_length > netdev->mtu ) {
+		if (payload_length > netdev->mtu) {
 			/* A bogus length ethfrm has been sent. */
 			/* Is someone trying an oflow attack? */
-			WLAN_LOG_ERROR("OTHER frame too large (%d > %d)\n",
-				payload_length,
-				netdev->mtu);
+			printk(KERN_ERR "OTHER frame too large (%d > %d)\n",
+			       payload_length, netdev->mtu);
 			return 1;
 		}
 
@@ -492,26 +472,26 @@
 
 	}
 
-        /*
-         * Note that eth_type_trans() expects an skb w/ skb->data pointing
-         * at the MAC header, it then sets the following skb members:
-         * skb->mac_header,
-         * skb->data, and
-         * skb->pkt_type.
-         * It then _returns_ the value that _we're_ supposed to stuff in
-         * skb->protocol.  This is nuts.
-         */
+	/*
+	 * Note that eth_type_trans() expects an skb w/ skb->data pointing
+	 * at the MAC header, it then sets the following skb members:
+	 * skb->mac_header,
+	 * skb->data, and
+	 * skb->pkt_type.
+	 * It then _returns_ the value that _we're_ supposed to stuff in
+	 * skb->protocol.  This is nuts.
+	 */
 	skb->protocol = eth_type_trans(skb, netdev);
 
-        /* jkriegl: process signal and noise as set in hfa384x_int_rx() */
+	/* jkriegl: process signal and noise as set in hfa384x_int_rx() */
 	/* jkriegl: only process signal/noise if requested by iwspy */
-        if (wlandev->spy_number)
-                orinoco_spy_gather(wlandev, eth_hdr(skb)->h_source, P80211SKB_RXMETA(skb));
+	if (wlandev->spy_number)
+		orinoco_spy_gather(wlandev, eth_hdr(skb)->h_source,
+				   P80211SKB_RXMETA(skb));
 
 	/* Free the metadata */
 	p80211skb_rxmeta_detach(skb);
 
-	DBFEXIT;
 	return 0;
 }
 
@@ -536,11 +516,11 @@
 	/* Always return found for now.  This is the behavior used by the */
 	/*  Zoom Win95 driver when 802.1h mode is selected */
 	/* TODO: If necessary, add an actual search we'll probably
-		 need this to match the CMAC's way of doing things.
-		 Need to do some testing to confirm.
-	*/
+	   need this to match the CMAC's way of doing things.
+	   Need to do some testing to confirm.
+	 */
 
-	if (proto == 0x80f3)  /* APPLETALK */
+	if (proto == 0x80f3)	/* APPLETALK */
 		return 1;
 
 	return 0;
@@ -561,26 +541,24 @@
 * Call context:
 *	May be called in interrupt or non-interrupt context
 ----------------------------------------------------------------*/
-void
-p80211skb_rxmeta_detach(struct sk_buff *skb)
+void p80211skb_rxmeta_detach(struct sk_buff *skb)
 {
-	p80211_rxmeta_t		*rxmeta;
-	p80211_frmmeta_t	*frmmeta;
+	p80211_rxmeta_t *rxmeta;
+	p80211_frmmeta_t *frmmeta;
 
-	DBFENTER;
 	/* Sanity checks */
-	if ( skb==NULL ) {			/* bad skb */
-		WLAN_LOG_DEBUG(1, "Called w/ null skb.\n");
+	if (skb == NULL) {	/* bad skb */
+		pr_debug("Called w/ null skb.\n");
 		goto exit;
 	}
 	frmmeta = P80211SKB_FRMMETA(skb);
-	if ( frmmeta == NULL ) { 		/* no magic */
-		WLAN_LOG_DEBUG(1, "Called w/ bad frmmeta magic.\n");
+	if (frmmeta == NULL) {	/* no magic */
+		pr_debug("Called w/ bad frmmeta magic.\n");
 		goto exit;
 	}
 	rxmeta = frmmeta->rx;
-	if ( rxmeta == NULL ) {			/* bad meta ptr */
-		WLAN_LOG_DEBUG(1, "Called w/ bad rxmeta ptr.\n");
+	if (rxmeta == NULL) {	/* bad meta ptr */
+		pr_debug("Called w/ bad rxmeta ptr.\n");
 		goto exit;
 	}
 
@@ -590,7 +568,6 @@
 	/* Clear skb->cb */
 	memset(skb->cb, 0, sizeof(skb->cb));
 exit:
-	DBFEXIT;
 	return;
 }
 
@@ -610,19 +587,16 @@
 * Call context:
 *	May be called in interrupt or non-interrupt context
 ----------------------------------------------------------------*/
-int
-p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb)
+int p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb)
 {
-	int			result = 0;
-	p80211_rxmeta_t		*rxmeta;
-	p80211_frmmeta_t	*frmmeta;
-
-	DBFENTER;
+	int result = 0;
+	p80211_rxmeta_t *rxmeta;
+	p80211_frmmeta_t *frmmeta;
 
 	/* If these already have metadata, we error out! */
 	if (P80211SKB_RXMETA(skb) != NULL) {
-		WLAN_LOG_ERROR("%s: RXmeta already attached!\n",
-				wlandev->name);
+		printk(KERN_ERR "%s: RXmeta already attached!\n",
+		       wlandev->name);
 		result = 0;
 		goto exit;
 	}
@@ -630,9 +604,9 @@
 	/* Allocate the rxmeta */
 	rxmeta = kmalloc(sizeof(p80211_rxmeta_t), GFP_ATOMIC);
 
-	if ( rxmeta == NULL ) {
-		WLAN_LOG_ERROR("%s: Failed to allocate rxmeta.\n",
-				wlandev->name);
+	if (rxmeta == NULL) {
+		printk(KERN_ERR "%s: Failed to allocate rxmeta.\n",
+		       wlandev->name);
 		result = 1;
 		goto exit;
 	}
@@ -644,11 +618,10 @@
 
 	/* Overlay a frmmeta_t onto skb->cb */
 	memset(skb->cb, 0, sizeof(p80211_frmmeta_t));
-	frmmeta = (p80211_frmmeta_t*)(skb->cb);
+	frmmeta = (p80211_frmmeta_t *) (skb->cb);
 	frmmeta->magic = P80211_FRMMETA_MAGIC;
 	frmmeta->rx = rxmeta;
 exit:
-	DBFEXIT;
 	return result;
 }
 
@@ -668,19 +641,15 @@
 * Call context:
 *	May be called in interrupt or non-interrupt context
 ----------------------------------------------------------------*/
-void
-p80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb)
+void p80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb)
 {
-	p80211_frmmeta_t	*meta;
-	DBFENTER;
-	meta = P80211SKB_FRMMETA(skb);
-	if ( meta && meta->rx) {
-		p80211skb_rxmeta_detach(skb);
-	} else {
-		WLAN_LOG_ERROR("Freeing an skb (%p) w/ no frmmeta.\n", skb);
-	}
+	p80211_frmmeta_t *meta;
 
+	meta = P80211SKB_FRMMETA(skb);
+	if (meta && meta->rx)
+		p80211skb_rxmeta_detach(skb);
+	else
+		printk(KERN_ERR "Freeing an skb (%p) w/ no frmmeta.\n", skb);
 	dev_kfree_skb(skb);
-	DBFEXIT;
 	return;
 }
diff --git a/drivers/staging/wlan-ng/p80211conv.h b/drivers/staging/wlan-ng/p80211conv.h
index 538e9bd..6fe163b 100644
--- a/drivers/staging/wlan-ng/p80211conv.h
+++ b/drivers/staging/wlan-ng/p80211conv.h
@@ -53,134 +53,109 @@
 #ifndef _LINUX_P80211CONV_H
 #define _LINUX_P80211CONV_H
 
-/*================================================================*/
-/* Constants */
-
 #define WLAN_ETHADDR_LEN	6
 #define WLAN_IEEE_OUI_LEN	3
 
 #define WLAN_ETHCONV_ENCAP	1
-#define WLAN_ETHCONV_RFC1042	2
 #define WLAN_ETHCONV_8021h	3
 
-#define WLAN_MIN_ETHFRM_LEN	60
-#define WLAN_MAX_ETHFRM_LEN	1514
 #define WLAN_ETHHDR_LEN		14
 
 #define P80211CAPTURE_VERSION	0x80211001
 
-/*================================================================*/
-/* Macros */
-
 #define	P80211_FRMMETA_MAGIC		0x802110
 
 #define P80211SKB_FRMMETA(s) \
-	(((((p80211_frmmeta_t*)((s)->cb))->magic)==P80211_FRMMETA_MAGIC) ? \
-		((p80211_frmmeta_t*)((s)->cb)) : \
+	(((((p80211_frmmeta_t *)((s)->cb))->magic) == P80211_FRMMETA_MAGIC) ? \
+		((p80211_frmmeta_t *)((s)->cb)) : \
 		(NULL))
 
 #define P80211SKB_RXMETA(s) \
-	(P80211SKB_FRMMETA((s)) ?  P80211SKB_FRMMETA((s))->rx : ((p80211_rxmeta_t*)(NULL)))
+	(P80211SKB_FRMMETA((s)) ?  P80211SKB_FRMMETA((s))->rx : ((p80211_rxmeta_t *)(NULL)))
 
-typedef struct p80211_rxmeta
-{
-	struct wlandevice	*wlandev;
+typedef struct p80211_rxmeta {
+	struct wlandevice *wlandev;
 
-	u64	mactime;	/* Hi-rez MAC-supplied time value */
-	u64	hosttime;	/* Best-rez host supplied time value */
+	u64 mactime;		/* Hi-rez MAC-supplied time value */
+	u64 hosttime;		/* Best-rez host supplied time value */
 
-	unsigned int	rxrate;		/* Receive data rate in 100kbps */
-	unsigned int	priority;	/* 0-15, 0=contention, 6=CF */
-	int	signal;		/* An SSI, see p80211netdev.h */
-	int	noise;		/* An SSI, see p80211netdev.h */
-	unsigned int	channel;	/* Receive channel (mostly for snifs) */
-	unsigned int	preamble;	/* P80211ENUM_preambletype_* */
-	unsigned int	encoding;	/* P80211ENUM_encoding_* */
+	unsigned int rxrate;	/* Receive data rate in 100kbps */
+	unsigned int priority;	/* 0-15, 0=contention, 6=CF */
+	int signal;		/* An SSI, see p80211netdev.h */
+	int noise;		/* An SSI, see p80211netdev.h */
+	unsigned int channel;	/* Receive channel (mostly for snifs) */
+	unsigned int preamble;	/* P80211ENUM_preambletype_* */
+	unsigned int encoding;	/* P80211ENUM_encoding_* */
 
 } p80211_rxmeta_t;
 
-typedef struct p80211_frmmeta
-{
-	unsigned int			magic;
-	p80211_rxmeta_t		*rx;
+typedef struct p80211_frmmeta {
+	unsigned int magic;
+	p80211_rxmeta_t *rx;
 } p80211_frmmeta_t;
 
 void p80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb);
 int p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb);
 void p80211skb_rxmeta_detach(struct sk_buff *skb);
 
-/*================================================================*/
-/* Types */
-
 /*
  * Frame capture header.  (See doc/capturefrm.txt)
  */
-typedef struct p80211_caphdr
-{
-	u32		version;
-	u32		length;
-	u64		mactime;
-	u64		hosttime;
-	u32		phytype;
-	u32		channel;
-	u32		datarate;
-	u32		antenna;
-	u32		priority;
-	u32		ssi_type;
-	s32		ssi_signal;
-	s32		ssi_noise;
-	u32		preamble;
-	u32		encoding;
+typedef struct p80211_caphdr {
+	u32 version;
+	u32 length;
+	u64 mactime;
+	u64 hosttime;
+	u32 phytype;
+	u32 channel;
+	u32 datarate;
+	u32 antenna;
+	u32 priority;
+	u32 ssi_type;
+	s32 ssi_signal;
+	s32 ssi_noise;
+	u32 preamble;
+	u32 encoding;
 } p80211_caphdr_t;
 
 /* buffer free method pointer type */
-typedef void (* freebuf_method_t)(void *buf, int size);
+typedef void (*freebuf_method_t) (void *buf, int size);
 
 typedef struct p80211_metawep {
-	void  *data;
+	void *data;
 	u8 iv[4];
 	u8 icv[4];
 } p80211_metawep_t;
 
 /* local ether header type */
-typedef struct wlan_ethhdr
-{
-	u8	daddr[WLAN_ETHADDR_LEN];
-	u8	saddr[WLAN_ETHADDR_LEN];
-	u16	type;
-} __WLAN_ATTRIB_PACK__ wlan_ethhdr_t;
+typedef struct wlan_ethhdr {
+	u8 daddr[WLAN_ETHADDR_LEN];
+	u8 saddr[WLAN_ETHADDR_LEN];
+	u16 type;
+} __attribute__ ((packed)) wlan_ethhdr_t;
 
 /* local llc header type */
-typedef struct wlan_llc
-{
-	u8	dsap;
-	u8	ssap;
-	u8	ctl;
-} __WLAN_ATTRIB_PACK__ wlan_llc_t;
+typedef struct wlan_llc {
+	u8 dsap;
+	u8 ssap;
+	u8 ctl;
+} __attribute__ ((packed)) wlan_llc_t;
 
 /* local snap header type */
-typedef struct wlan_snap
-{
-	u8	oui[WLAN_IEEE_OUI_LEN];
-	u16	type;
-} __WLAN_ATTRIB_PACK__ wlan_snap_t;
+typedef struct wlan_snap {
+	u8 oui[WLAN_IEEE_OUI_LEN];
+	u16 type;
+} __attribute__ ((packed)) wlan_snap_t;
 
 /* Circular include trick */
 struct wlandevice;
 
-/*================================================================*/
-/* Externs */
-
-/*================================================================*/
-/*Function Declarations */
-
-int skb_p80211_to_ether( struct wlandevice *wlandev, u32 ethconv,
-			 struct sk_buff *skb);
-int skb_ether_to_p80211( struct wlandevice *wlandev, u32 ethconv,
-			 struct sk_buff *skb, p80211_hdr_t *p80211_hdr,
-			 p80211_metawep_t *p80211_wep );
+int skb_p80211_to_ether(struct wlandevice *wlandev, u32 ethconv,
+			struct sk_buff *skb);
+int skb_ether_to_p80211(struct wlandevice *wlandev, u32 ethconv,
+			struct sk_buff *skb, p80211_hdr_t *p80211_hdr,
+			p80211_metawep_t *p80211_wep);
 
 int p80211_stt_findproto(u16 proto);
-int p80211_stt_addproto(u16 proto);
 
 #endif
diff --git a/drivers/staging/wlan-ng/p80211hdr.h b/drivers/staging/wlan-ng/p80211hdr.h
index 72f12af..ded4775 100644
--- a/drivers/staging/wlan-ng/p80211hdr.h
+++ b/drivers/staging/wlan-ng/p80211hdr.h
@@ -63,43 +63,23 @@
 /*================================================================*/
 /* System Includes */
 
+#include <linux/if_ether.h>
+
 /*================================================================*/
 /* Project Includes */
 
-#ifndef  _WLAN_COMPAT_H
-#include "wlan_compat.h"
-#endif
 
 
 /*================================================================*/
 /* Constants */
 
 /*--- Sizes -----------------------------------------------*/
-#define WLAN_ADDR_LEN			6
 #define WLAN_CRC_LEN			4
 #define WLAN_BSSID_LEN			6
-#define WLAN_BSS_TS_LEN			8
 #define WLAN_HDR_A3_LEN			24
 #define WLAN_HDR_A4_LEN			30
 #define WLAN_SSID_MAXLEN		32
 #define WLAN_DATA_MAXLEN		2312
-#define WLAN_A3FR_MAXLEN		(WLAN_HDR_A3_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN)
-#define WLAN_A4FR_MAXLEN		(WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN)
-#define WLAN_BEACON_FR_MAXLEN		(WLAN_HDR_A3_LEN + 334)
-#define WLAN_ATIM_FR_MAXLEN		(WLAN_HDR_A3_LEN + 0)
-#define WLAN_DISASSOC_FR_MAXLEN		(WLAN_HDR_A3_LEN + 2)
-#define WLAN_ASSOCREQ_FR_MAXLEN		(WLAN_HDR_A3_LEN + 48)
-#define WLAN_ASSOCRESP_FR_MAXLEN	(WLAN_HDR_A3_LEN + 16)
-#define WLAN_REASSOCREQ_FR_MAXLEN	(WLAN_HDR_A3_LEN + 54)
-#define WLAN_REASSOCRESP_FR_MAXLEN	(WLAN_HDR_A3_LEN + 16)
-#define WLAN_PROBEREQ_FR_MAXLEN		(WLAN_HDR_A3_LEN + 44)
-#define WLAN_PROBERESP_FR_MAXLEN	(WLAN_HDR_A3_LEN + 78)
-#define WLAN_AUTHEN_FR_MAXLEN		(WLAN_HDR_A3_LEN + 261)
-#define WLAN_DEAUTHEN_FR_MAXLEN		(WLAN_HDR_A3_LEN + 2)
-#define WLAN_WEP_NKEYS			4
-#define WLAN_WEP_MAXKEYLEN		13
-#define WLAN_CHALLENGE_IE_LEN		130
-#define WLAN_CHALLENGE_LEN		128
 #define WLAN_WEP_IV_LEN			4
 #define WLAN_WEP_ICV_LEN		4
 
@@ -143,7 +123,6 @@
 #define WLAN_FSTYPE_CFPOLL		0x06
 #define WLAN_FSTYPE_CFACK_CFPOLL	0x07
 
-
 /*================================================================*/
 /* Macros */
 
@@ -166,97 +145,51 @@
 /*                        SET_FC_FSTYPE(WLAN_FSTYPE_RTS) );   */
 /*------------------------------------------------------------*/
 
-#define WLAN_GET_FC_PVER(n)	 (((u16)(n)) & (BIT0 | BIT1))
-#define WLAN_GET_FC_FTYPE(n)	((((u16)(n)) & (BIT2 | BIT3)) >> 2)
-#define WLAN_GET_FC_FSTYPE(n)	((((u16)(n)) & (BIT4|BIT5|BIT6|BIT7)) >> 4)
-#define WLAN_GET_FC_TODS(n) 	((((u16)(n)) & (BIT8)) >> 8)
-#define WLAN_GET_FC_FROMDS(n)	((((u16)(n)) & (BIT9)) >> 9)
-#define WLAN_GET_FC_MOREFRAG(n) ((((u16)(n)) & (BIT10)) >> 10)
-#define WLAN_GET_FC_RETRY(n)	((((u16)(n)) & (BIT11)) >> 11)
-#define WLAN_GET_FC_PWRMGT(n)	((((u16)(n)) & (BIT12)) >> 12)
-#define WLAN_GET_FC_MOREDATA(n) ((((u16)(n)) & (BIT13)) >> 13)
-#define WLAN_GET_FC_ISWEP(n)	((((u16)(n)) & (BIT14)) >> 14)
-#define WLAN_GET_FC_ORDER(n)	((((u16)(n)) & (BIT15)) >> 15)
+#define WLAN_GET_FC_FTYPE(n)	((((u16)(n)) & (BIT(2) | BIT(3))) >> 2)
+#define WLAN_GET_FC_FSTYPE(n)	((((u16)(n)) & (BIT(4)|BIT(5)|BIT(6)|BIT(7))) >> 4)
+#define WLAN_GET_FC_TODS(n) 	((((u16)(n)) & (BIT(8))) >> 8)
+#define WLAN_GET_FC_FROMDS(n)	((((u16)(n)) & (BIT(9))) >> 9)
+#define WLAN_GET_FC_ISWEP(n)	((((u16)(n)) & (BIT(14))) >> 14)
 
-#define WLAN_SET_FC_PVER(n)	((u16)(n))
 #define WLAN_SET_FC_FTYPE(n)	(((u16)(n)) << 2)
 #define WLAN_SET_FC_FSTYPE(n)	(((u16)(n)) << 4)
 #define WLAN_SET_FC_TODS(n) 	(((u16)(n)) << 8)
 #define WLAN_SET_FC_FROMDS(n)	(((u16)(n)) << 9)
-#define WLAN_SET_FC_MOREFRAG(n) (((u16)(n)) << 10)
-#define WLAN_SET_FC_RETRY(n)	(((u16)(n)) << 11)
-#define WLAN_SET_FC_PWRMGT(n)	(((u16)(n)) << 12)
-#define WLAN_SET_FC_MOREDATA(n) (((u16)(n)) << 13)
 #define WLAN_SET_FC_ISWEP(n)	(((u16)(n)) << 14)
-#define WLAN_SET_FC_ORDER(n)	(((u16)(n)) << 15)
 
-/*--- Duration Macros ----------------------------------------*/
-/* Macros to get/set the bitfields of the Duration Field      */
-/*  - the duration value is only valid when bit15 is zero     */
-/*  - the firmware handles these values, so I'm not going     */
-/*    these macros right now.                                 */
-/*------------------------------------------------------------*/
-
-/*--- Sequence Control  Macros -------------------------------*/
-/* Macros to get/set the bitfields of the Sequence Control    */
-/* Field.                                                     */
-/*------------------------------------------------------------*/
-#define WLAN_GET_SEQ_FRGNUM(n) (((u16)(n)) & (BIT0|BIT1|BIT2|BIT3))
-#define WLAN_GET_SEQ_SEQNUM(n) ((((u16)(n)) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4)
-
-/*--- Data ptr macro -----------------------------------------*/
-/* Creates a u8* to the data portion of a frame            */
-/* Assumes you're passing in a ptr to the beginning of the hdr*/
-/*------------------------------------------------------------*/
-#define WLAN_HDR_A3_DATAP(p) (((u8*)(p)) + WLAN_HDR_A3_LEN)
-#define WLAN_HDR_A4_DATAP(p) (((u8*)(p)) + WLAN_HDR_A4_LEN)
-
-#define DOT11_RATE5_ISBASIC_GET(r)     (((u8)(r)) & BIT7)
+#define DOT11_RATE5_ISBASIC_GET(r)     (((u8)(r)) & BIT(7))
 
 /*================================================================*/
 /* Types */
 
-/* BSS Timestamp */
-typedef u8 wlan_bss_ts_t[WLAN_BSS_TS_LEN];
-
 /* Generic 802.11 Header types */
 
-typedef struct p80211_hdr_a3
-{
-	u16	fc;
-	u16	dur;
-	u8	a1[WLAN_ADDR_LEN];
-	u8	a2[WLAN_ADDR_LEN];
-	u8	a3[WLAN_ADDR_LEN];
-	u16	seq;
-} __WLAN_ATTRIB_PACK__ p80211_hdr_a3_t;
+typedef struct p80211_hdr_a3 {
+	u16 fc;
+	u16 dur;
+	u8 a1[ETH_ALEN];
+	u8 a2[ETH_ALEN];
+	u8 a3[ETH_ALEN];
+	u16 seq;
+} __attribute__ ((packed)) p80211_hdr_a3_t;
 
-typedef struct p80211_hdr_a4
-{
-	u16	fc;
-	u16	dur;
-	u8	a1[WLAN_ADDR_LEN];
-	u8	a2[WLAN_ADDR_LEN];
-	u8	a3[WLAN_ADDR_LEN];
-	u16	seq;
-	u8	a4[WLAN_ADDR_LEN];
-} __WLAN_ATTRIB_PACK__ p80211_hdr_a4_t;
+typedef struct p80211_hdr_a4 {
+	u16 fc;
+	u16 dur;
+	u8 a1[ETH_ALEN];
+	u8 a2[ETH_ALEN];
+	u8 a3[ETH_ALEN];
+	u16 seq;
+	u8 a4[ETH_ALEN];
+} __attribute__ ((packed)) p80211_hdr_a4_t;
 
-typedef union p80211_hdr
-{
-	p80211_hdr_a3_t		a3;
-	p80211_hdr_a4_t		a4;
-} __WLAN_ATTRIB_PACK__ p80211_hdr_t;
+typedef union p80211_hdr {
+	p80211_hdr_a3_t a3;
+	p80211_hdr_a4_t a4;
+} __attribute__ ((packed)) p80211_hdr_t;
 
 
-/*================================================================*/
-/* Extern Declarations */
-
-
-/*================================================================*/
-/* Function Declarations */
-
-/* Frame and header lenght macros */
+/* Frame and header length macros */
 
 #define WLAN_CTL_FRAMELEN(fstype) (\
 	(fstype) == WLAN_FSTYPE_BLOCKACKREQ	? 24 : \
@@ -271,23 +204,22 @@
 #define WLAN_FCS_LEN			4
 
 /* ftcl in HOST order */
-inline static u16 p80211_headerlen(u16 fctl)
+static inline u16 p80211_headerlen(u16 fctl)
 {
 	u16 hdrlen = 0;
 
-	switch ( WLAN_GET_FC_FTYPE(fctl) ) {
+	switch (WLAN_GET_FC_FTYPE(fctl)) {
 	case WLAN_FTYPE_MGMT:
 		hdrlen = WLAN_HDR_A3_LEN;
 		break;
 	case WLAN_FTYPE_DATA:
 		hdrlen = WLAN_HDR_A3_LEN;
-		if ( WLAN_GET_FC_TODS(fctl) && WLAN_GET_FC_FROMDS(fctl) ) {
-			hdrlen += WLAN_ADDR_LEN;
-		}
+		if (WLAN_GET_FC_TODS(fctl) && WLAN_GET_FC_FROMDS(fctl))
+			hdrlen += ETH_ALEN;
 		break;
 	case WLAN_FTYPE_CTL:
 		hdrlen = WLAN_CTL_FRAMELEN(WLAN_GET_FC_FSTYPE(fctl)) -
-			WLAN_FCS_LEN;
+		    WLAN_FCS_LEN;
 		break;
 	default:
 		hdrlen = WLAN_HDR_A3_LEN;
diff --git a/drivers/staging/wlan-ng/p80211ioctl.h b/drivers/staging/wlan-ng/p80211ioctl.h
index ad67b69..64ca7f9 100644
--- a/drivers/staging/wlan-ng/p80211ioctl.h
+++ b/drivers/staging/wlan-ng/p80211ioctl.h
@@ -60,14 +60,9 @@
 * --------------------------------------------------------------------
 */
 
-
 #ifndef _P80211IOCTL_H
 #define _P80211IOCTL_H
 
-/*================================================================*/
-/* Constants */
-
-/*----------------------------------------------------------------*/
 /* p80211 ioctl "request" codes.  See argument 2 of ioctl(2). */
 
 #define P80211_IFTEST		(SIOCDEVPRIVATE + 0)
@@ -79,45 +74,16 @@
 #define P80211_IOCTL_MAGIC	(0x4a2d464dUL)
 
 /*----------------------------------------------------------------*/
-/* Netlink protocol numbers for the indication interface */
-
-#define P80211_NL_SOCK_IND	NETLINK_USERSOCK
-
-/*----------------------------------------------------------------*/
-/* Netlink multicast bits for different types of messages */
-
-#define P80211_NL_MCAST_GRP_MLME	BIT0	/* Local station messages */
-#define P80211_NL_MCAST_GRP_SNIFF	BIT1	/* Sniffer messages */
-#define P80211_NL_MCAST_GRP_DIST	BIT2	/* Distribution system messages */
-
-/*================================================================*/
-/* Macros */
-
-
-/*================================================================*/
-/* Types */
-
-/*----------------------------------------------------------------*/
 /* A ptr to the following structure type is passed as the third */
 /*  argument to the ioctl system call when issuing a request to */
 /*  the p80211 module. */
 
-typedef struct p80211ioctl_req
-{
-	char 	name[WLAN_DEVNAMELEN_MAX];
+typedef struct p80211ioctl_req {
+	char name[WLAN_DEVNAMELEN_MAX];
 	caddr_t data;
-	u32	magic;
-	u16	len;
-	u32	result;
-} __WLAN_ATTRIB_PACK__ p80211ioctl_req_t;
-
-
-/*================================================================*/
-/* Extern Declarations */
-
-
-/*================================================================*/
-/* Function Declarations */
-
+	u32 magic;
+	u16 len;
+	u32 result;
+} __attribute__ ((packed)) p80211ioctl_req_t;
 
 #endif /* _P80211IOCTL_H */
diff --git a/drivers/staging/wlan-ng/p80211meta.h b/drivers/staging/wlan-ng/p80211meta.h
index 8b61e5f..2f3c9fc 100644
--- a/drivers/staging/wlan-ng/p80211meta.h
+++ b/drivers/staging/wlan-ng/p80211meta.h
@@ -58,50 +58,8 @@
 #define _P80211META_H
 
 /*================================================================*/
-/* System Includes */
-
-/*================================================================*/
 /* Project Includes */
 
-#ifndef _WLAN_COMPAT_H
-#include "wlan_compat.h"
-#endif
-
-/*================================================================*/
-/* Constants */
-
-/*----------------------------------------------------------------*/
-/* */
-
-/*================================================================*/
-/* Macros */
-
-/*----------------------------------------------------------------*/
-/* The following macros are used to ensure consistent naming */
-/*  conventions for all the different metadata lists. */
-
-#define MKREQMETANAME(name)		p80211meta_ ## req ## _ ## name
-#define MKINDMETANAME(name)		p80211meta_ ## ind ## _ ## name
-#define MKMIBMETANAME(name)		p80211meta_ ## mib ## _ ## name
-#define MKGRPMETANAME(name)		p80211meta_ ## grp ## _ ## name
-
-#define MKREQMETASIZE(name)		p80211meta_ ## req ## _ ## name ## _ ## size
-#define MKINDMETASIZE(name)		p80211meta_ ## ind ## _ ## name ## _ ## size
-#define MKMIBMETASIZE(name)		p80211meta_ ## mib ## _ ## name ## _ ## size
-#define MKGRPMETASIZE(name)		p80211meta_ ## grp ## _ ## name ## _ ## size
-
-#define GETMETASIZE(aptr)		(**((u32**)(aptr)))
-
-/*----------------------------------------------------------------*/
-/* The following ifdef depends on the following defines: */
-/*  P80211_NOINCLUDESTRINGS - if defined, all metadata name fields */
-/*                               are empty strings */
-
-#ifdef P80211_NOINCLUDESTRINGS
-	#define	MKITEMNAME(s)	("")
-#else
-	#define	MKITEMNAME(s)	(s)
-#endif
 
 /*================================================================*/
 /* Types */
@@ -111,59 +69,29 @@
 /* representation of category list metadata, group list metadata, */
 /* and data item metadata for both Mib and Messages. */
 
-typedef struct p80211meta
-{
-	char			*name;		/* data item name */
-	u32			did;		/* partial did */
-	u32			flags;		/* set of various flag bits */
-	u32			min;		/* min value of a BOUNDEDint */
-	u32			max;		/* max value of a BOUNDEDint */
+typedef struct p80211meta {
+	char *name;		/* data item name */
+	u32 did;		/* partial did */
+	u32 flags;		/* set of various flag bits */
+	u32 min;		/* min value of a BOUNDEDint */
+	u32 max;		/* max value of a BOUNDEDint */
 
-	u32			maxlen;		/* maxlen of a OCTETSTR or DISPLAYSTR */
-	u32			minlen;		/* minlen of a OCTETSTR or DISPLAYSTR */
-	p80211enum_t		*enumptr;	/* ptr to the enum type for ENUMint */
-	p80211_totext_t		totextptr;	/* ptr to totext conversion function */
-	p80211_fromtext_t	fromtextptr;	/* ptr to totext conversion function */
-	p80211_valid_t		validfunptr;	/* ptr to totext conversion function */
+	u32 maxlen;		/* maxlen of a OCTETSTR or DISPLAYSTR */
+	u32 minlen;		/* minlen of a OCTETSTR or DISPLAYSTR */
+	p80211enum_t *enumptr;	/* ptr to the enum type for ENUMint */
+	p80211_totext_t totextptr;	/* ptr to totext conversion function */
+	p80211_fromtext_t fromtextptr;	/* ptr to totext conversion function */
+	p80211_valid_t validfunptr;	/* ptr to totext conversion function */
 } p80211meta_t;
 
-typedef struct grplistitem
-{
-	char		*name;
-	p80211meta_t	*itemlist;
+typedef struct grplistitem {
+	char *name;
+	p80211meta_t *itemlist;
 } grplistitem_t;
 
-typedef struct catlistitem
-{
-	char		*name;
-	grplistitem_t	*grplist;
+typedef struct catlistitem {
+	char *name;
+	grplistitem_t *grplist;
 } catlistitem_t;
 
-/*================================================================*/
-/* Extern Declarations */
-
-/*----------------------------------------------------------------*/
-/* */
-
-/*================================================================*/
-/* Function Declarations */
-
-/*----------------------------------------------------------------*/
-/* */
-u32 p80211_text2did(catlistitem_t *catlist, char *catname, char *grpname, char *itemname);
-u32 p80211_text2catdid(catlistitem_t *list, char *name );
-u32 p80211_text2grpdid(grplistitem_t *list, char *name );
-u32 p80211_text2itemdid(p80211meta_t *list, char *name );
-u32 p80211_isvalid_did( catlistitem_t *catlist, u32 did );
-u32 p80211_isvalid_catdid( catlistitem_t *catlist, u32 did );
-u32 p80211_isvalid_grpdid( catlistitem_t *catlist, u32 did );
-u32 p80211_isvalid_itemdid( catlistitem_t *catlist, u32 did );
-catlistitem_t *p80211_did2cat( catlistitem_t *catlist, u32 did );
-grplistitem_t *p80211_did2grp( catlistitem_t *catlist, u32 did );
-p80211meta_t *p80211_did2item( catlistitem_t *catlist, u32 did );
-u32 p80211item_maxdatalen( struct catlistitem *metalist, u32 did );
-u32 p80211_metaname2did(struct catlistitem *metalist, char *itemname);
-u32 p80211item_getoffset( struct catlistitem *metalist, u32 did );
-int p80211item_gettype(p80211meta_t *meta);
-
 #endif /* _P80211META_H */
diff --git a/drivers/staging/wlan-ng/p80211metadef.h b/drivers/staging/wlan-ng/p80211metadef.h
index ce4fdd5..a29d6ae 100644
--- a/drivers/staging/wlan-ng/p80211metadef.h
+++ b/drivers/staging/wlan-ng/p80211metadef.h
@@ -47,20 +47,9 @@
 #ifndef _P80211MKMETADEF_H
 #define _P80211MKMETADEF_H
 
-
-#define DIDmsg_cat_dot11req \
-			P80211DID_MKSECTION(1)
 #define DIDmsg_dot11req_mibget \
 			(P80211DID_MKSECTION(1) | \
 			P80211DID_MKGROUP(1))
-#define DIDmsg_dot11req_mibget_mibattribute \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(1) | \
-			P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_dot11req_mibget_resultcode \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(1) | \
-			P80211DID_MKITEM(2) | 0x00000000)
 #define DIDmsg_dot11req_mibset \
 			(P80211DID_MKSECTION(1) | \
 			P80211DID_MKGROUP(2))
@@ -75,579 +64,48 @@
 #define DIDmsg_dot11req_scan \
 			(P80211DID_MKSECTION(1) | \
 			P80211DID_MKGROUP(4))
-#define DIDmsg_dot11req_scan_bsstype \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(4) | \
-			P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_dot11req_scan_bssid \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(4) | \
-			P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_dot11req_scan_ssid \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(4) | \
-			P80211DID_MKITEM(3) | 0x00000000)
-#define DIDmsg_dot11req_scan_scantype \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(4) | \
-			P80211DID_MKITEM(4) | 0x00000000)
-#define DIDmsg_dot11req_scan_probedelay \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(4) | \
-			P80211DID_MKITEM(5) | 0x00000000)
-#define DIDmsg_dot11req_scan_channellist \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(4) | \
-			P80211DID_MKITEM(6) | 0x00000000)
-#define DIDmsg_dot11req_scan_minchanneltime \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(4) | \
-			P80211DID_MKITEM(7) | 0x00000000)
-#define DIDmsg_dot11req_scan_maxchanneltime \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(4) | \
-			P80211DID_MKITEM(8) | 0x00000000)
-#define DIDmsg_dot11req_scan_resultcode \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(4) | \
-			P80211DID_MKITEM(9) | 0x00000000)
-#define DIDmsg_dot11req_scan_numbss \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(4) | \
-			P80211DID_MKITEM(10) | 0x00000000)
-#define DIDmsg_dot11req_scan_append \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(4) | \
-			P80211DID_MKITEM(11) | 0x00000000)
 #define DIDmsg_dot11req_scan_results \
 			(P80211DID_MKSECTION(1) | \
 			P80211DID_MKGROUP(5))
-#define DIDmsg_dot11req_scan_results_bssindex \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_resultcode \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_signal \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(3) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_noise \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(4) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_bssid \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(5) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_ssid \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(6) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_bsstype \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(7) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_beaconperiod \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(8) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_dtimperiod \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(9) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_timestamp \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(10) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_localtime \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(11) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_fhdwelltime \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(12) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_fhhopset \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(13) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_fhhoppattern \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(14) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_fhhopindex \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(15) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_dschannel \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(16) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_cfpcount \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(17) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_cfpperiod \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(18) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_cfpmaxduration \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(19) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_cfpdurremaining \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(20) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_ibssatimwindow \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(21) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_cfpollable \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(22) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_cfpollreq \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(23) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_privacy \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(24) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_basicrate1 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(25) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_basicrate2 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(26) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_basicrate3 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(27) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_basicrate4 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(28) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_basicrate5 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(29) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_basicrate6 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(30) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_basicrate7 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(31) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_basicrate8 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(32) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_supprate1 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(33) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_supprate2 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(34) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_supprate3 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(35) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_supprate4 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(36) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_supprate5 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(37) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_supprate6 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(38) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_supprate7 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(39) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_supprate8 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(40) | 0x00000000)
 #define DIDmsg_dot11req_start \
 			(P80211DID_MKSECTION(1) | \
 			P80211DID_MKGROUP(13))
-#define DIDmsg_dot11req_start_ssid \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_dot11req_start_bsstype \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_dot11req_start_beaconperiod \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(3) | 0x00000000)
-#define DIDmsg_dot11req_start_dtimperiod \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(4) | 0x00000000)
-#define DIDmsg_dot11req_start_cfpperiod \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(5) | 0x00000000)
-#define DIDmsg_dot11req_start_cfpmaxduration \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(6) | 0x00000000)
-#define DIDmsg_dot11req_start_fhdwelltime \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(7) | 0x00000000)
-#define DIDmsg_dot11req_start_fhhopset \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(8) | 0x00000000)
-#define DIDmsg_dot11req_start_fhhoppattern \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(9) | 0x00000000)
-#define DIDmsg_dot11req_start_dschannel \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(10) | 0x00000000)
-#define DIDmsg_dot11req_start_ibssatimwindow \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(11) | 0x00000000)
-#define DIDmsg_dot11req_start_probedelay \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(12) | 0x00000000)
-#define DIDmsg_dot11req_start_cfpollable \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(13) | 0x00000000)
-#define DIDmsg_dot11req_start_cfpollreq \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(14) | 0x00000000)
-#define DIDmsg_dot11req_start_basicrate1 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(15) | 0x00000000)
-#define DIDmsg_dot11req_start_basicrate2 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(16) | 0x00000000)
-#define DIDmsg_dot11req_start_basicrate3 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(17) | 0x00000000)
-#define DIDmsg_dot11req_start_basicrate4 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(18) | 0x00000000)
-#define DIDmsg_dot11req_start_basicrate5 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(19) | 0x00000000)
-#define DIDmsg_dot11req_start_basicrate6 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(20) | 0x00000000)
-#define DIDmsg_dot11req_start_basicrate7 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(21) | 0x00000000)
-#define DIDmsg_dot11req_start_basicrate8 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(22) | 0x00000000)
-#define DIDmsg_dot11req_start_operationalrate1 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(23) | 0x00000000)
-#define DIDmsg_dot11req_start_operationalrate2 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(24) | 0x00000000)
-#define DIDmsg_dot11req_start_operationalrate3 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(25) | 0x00000000)
-#define DIDmsg_dot11req_start_operationalrate4 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(26) | 0x00000000)
-#define DIDmsg_dot11req_start_operationalrate5 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(27) | 0x00000000)
-#define DIDmsg_dot11req_start_operationalrate6 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(28) | 0x00000000)
-#define DIDmsg_dot11req_start_operationalrate7 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(29) | 0x00000000)
-#define DIDmsg_dot11req_start_operationalrate8 \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(30) | 0x00000000)
-#define DIDmsg_dot11req_start_resultcode \
-			(P80211DID_MKSECTION(1) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(31) | 0x00000000)
-#define DIDmsg_cat_dot11ind \
-			P80211DID_MKSECTION(2)
 #define DIDmsg_dot11ind_authenticate \
 			(P80211DID_MKSECTION(2) | \
 			P80211DID_MKGROUP(1))
-#define DIDmsg_dot11ind_authenticate_peerstaaddress \
-			(P80211DID_MKSECTION(2) | \
-			P80211DID_MKGROUP(1) | \
-			P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_dot11ind_authenticate_authenticationtype \
-			(P80211DID_MKSECTION(2) | \
-			P80211DID_MKGROUP(1) | \
-			P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_dot11ind_deauthenticate \
-			(P80211DID_MKSECTION(2) | \
-			P80211DID_MKGROUP(2))
-#define DIDmsg_dot11ind_deauthenticate_peerstaaddress \
-			(P80211DID_MKSECTION(2) | \
-			P80211DID_MKGROUP(2) | \
-			P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_dot11ind_deauthenticate_reasoncode \
-			(P80211DID_MKSECTION(2) | \
-			P80211DID_MKGROUP(2) | \
-			P80211DID_MKITEM(2) | 0x00000000)
 #define DIDmsg_dot11ind_associate \
 			(P80211DID_MKSECTION(2) | \
 			P80211DID_MKGROUP(3))
-#define DIDmsg_dot11ind_associate_peerstaaddress \
-			(P80211DID_MKSECTION(2) | \
-			P80211DID_MKGROUP(3) | \
-			P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_dot11ind_associate_aid \
-			(P80211DID_MKSECTION(2) | \
-			P80211DID_MKGROUP(3) | \
-			P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_dot11ind_reassociate \
-			(P80211DID_MKSECTION(2) | \
-			P80211DID_MKGROUP(4))
-#define DIDmsg_dot11ind_reassociate_peerstaaddress \
-			(P80211DID_MKSECTION(2) | \
-			P80211DID_MKGROUP(4) | \
-			P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_dot11ind_reassociate_aid \
-			(P80211DID_MKSECTION(2) | \
-			P80211DID_MKGROUP(4) | \
-			P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_dot11ind_reassociate_oldapaddress \
-			(P80211DID_MKSECTION(2) | \
-			P80211DID_MKGROUP(4) | \
-			P80211DID_MKITEM(3) | 0x00000000)
-#define DIDmsg_dot11ind_disassociate \
-			(P80211DID_MKSECTION(2) | \
-			P80211DID_MKGROUP(5))
-#define DIDmsg_dot11ind_disassociate_peerstaaddress \
-			(P80211DID_MKSECTION(2) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_dot11ind_disassociate_reasoncode \
-			(P80211DID_MKSECTION(2) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_cat_lnxreq \
-			P80211DID_MKSECTION(3)
 #define DIDmsg_lnxreq_ifstate \
 			(P80211DID_MKSECTION(3) | \
 			P80211DID_MKGROUP(1))
-#define DIDmsg_lnxreq_ifstate_ifstate \
-			(P80211DID_MKSECTION(3) | \
-			P80211DID_MKGROUP(1) | \
-			P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_lnxreq_ifstate_resultcode \
-			(P80211DID_MKSECTION(3) | \
-			P80211DID_MKGROUP(1) | \
-			P80211DID_MKITEM(2) | 0x00000000)
 #define DIDmsg_lnxreq_wlansniff \
 			(P80211DID_MKSECTION(3) | \
 			P80211DID_MKGROUP(2))
-#define DIDmsg_lnxreq_wlansniff_enable \
-			(P80211DID_MKSECTION(3) | \
-			P80211DID_MKGROUP(2) | \
-			P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_lnxreq_wlansniff_channel \
-			(P80211DID_MKSECTION(3) | \
-			P80211DID_MKGROUP(2) | \
-			P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_lnxreq_wlansniff_prismheader \
-			(P80211DID_MKSECTION(3) | \
-			P80211DID_MKGROUP(2) | \
-			P80211DID_MKITEM(3) | 0x00000000)
-#define DIDmsg_lnxreq_wlansniff_wlanheader \
-			(P80211DID_MKSECTION(3) | \
-			P80211DID_MKGROUP(2) | \
-			P80211DID_MKITEM(4) | 0x00000000)
-#define DIDmsg_lnxreq_wlansniff_keepwepflags \
-			(P80211DID_MKSECTION(3) | \
-			P80211DID_MKGROUP(2) | \
-			P80211DID_MKITEM(5) | 0x00000000)
-#define DIDmsg_lnxreq_wlansniff_stripfcs \
-			(P80211DID_MKSECTION(3) | \
-			P80211DID_MKGROUP(2) | \
-			P80211DID_MKITEM(6) | 0x00000000)
-#define DIDmsg_lnxreq_wlansniff_packet_trunc \
-			(P80211DID_MKSECTION(3) | \
-			P80211DID_MKGROUP(2) | \
-			P80211DID_MKITEM(7) | 0x00000000)
-#define DIDmsg_lnxreq_wlansniff_resultcode \
-			(P80211DID_MKSECTION(3) | \
-			P80211DID_MKGROUP(2) | \
-			P80211DID_MKITEM(8) | 0x00000000)
 #define DIDmsg_lnxreq_hostwep \
 			(P80211DID_MKSECTION(3) | \
 			P80211DID_MKGROUP(3))
-#define DIDmsg_lnxreq_hostwep_resultcode \
-			(P80211DID_MKSECTION(3) | \
-			P80211DID_MKGROUP(3) | \
-			P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_lnxreq_hostwep_decrypt \
-			(P80211DID_MKSECTION(3) | \
-			P80211DID_MKGROUP(3) | \
-			P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_lnxreq_hostwep_encrypt \
-			(P80211DID_MKSECTION(3) | \
-			P80211DID_MKGROUP(3) | \
-			P80211DID_MKITEM(3) | 0x00000000)
 #define DIDmsg_lnxreq_commsquality \
 			(P80211DID_MKSECTION(3) | \
 			P80211DID_MKGROUP(4))
-#define DIDmsg_lnxreq_commsquality_resultcode \
-			(P80211DID_MKSECTION(3) | \
-			P80211DID_MKGROUP(4) | \
-			P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_lnxreq_commsquality_dbm \
-			(P80211DID_MKSECTION(3) | \
-			P80211DID_MKGROUP(4) | \
-			P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_lnxreq_commsquality_link \
-			(P80211DID_MKSECTION(3) | \
-			P80211DID_MKGROUP(4) | \
-			P80211DID_MKITEM(3) | 0x00000000)
-#define DIDmsg_lnxreq_commsquality_level \
-			(P80211DID_MKSECTION(3) | \
-			P80211DID_MKGROUP(4) | \
-			P80211DID_MKITEM(4) | 0x00000000)
-#define DIDmsg_lnxreq_commsquality_noise \
-			(P80211DID_MKSECTION(3) | \
-			P80211DID_MKGROUP(4) | \
-			P80211DID_MKITEM(5) | 0x00000000)
 #define DIDmsg_lnxreq_autojoin \
 			(P80211DID_MKSECTION(3) | \
 			P80211DID_MKGROUP(5))
-#define DIDmsg_lnxreq_autojoin_ssid \
-			(P80211DID_MKSECTION(3) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_lnxreq_autojoin_authtype \
-			(P80211DID_MKSECTION(3) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_lnxreq_autojoin_resultcode \
-			(P80211DID_MKSECTION(3) | \
-			P80211DID_MKGROUP(5) | \
-			P80211DID_MKITEM(3) | 0x00000000)
-#define DIDmsg_cat_p2req \
-			P80211DID_MKSECTION(5)
 #define DIDmsg_p2req_readpda \
 			(P80211DID_MKSECTION(5) | \
 			P80211DID_MKGROUP(2))
-#define DIDmsg_p2req_readpda_pda \
-			(P80211DID_MKSECTION(5) | \
-			P80211DID_MKGROUP(2) | \
-			P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_p2req_readpda_resultcode \
-			(P80211DID_MKSECTION(5) | \
-			P80211DID_MKGROUP(2) | \
-			P80211DID_MKITEM(2) | 0x00000000)
 #define DIDmsg_p2req_ramdl_state \
 			(P80211DID_MKSECTION(5) | \
 			P80211DID_MKGROUP(11))
-#define DIDmsg_p2req_ramdl_state_enable \
-			(P80211DID_MKSECTION(5) | \
-			P80211DID_MKGROUP(11) | \
-			P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_p2req_ramdl_state_exeaddr \
-			(P80211DID_MKSECTION(5) | \
-			P80211DID_MKGROUP(11) | \
-			P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_p2req_ramdl_state_resultcode \
-			(P80211DID_MKSECTION(5) | \
-			P80211DID_MKGROUP(11) | \
-			P80211DID_MKITEM(3) | 0x00000000)
 #define DIDmsg_p2req_ramdl_write \
 			(P80211DID_MKSECTION(5) | \
 			P80211DID_MKGROUP(12))
-#define DIDmsg_p2req_ramdl_write_addr \
-			(P80211DID_MKSECTION(5) | \
-			P80211DID_MKGROUP(12) | \
-			P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_p2req_ramdl_write_len \
-			(P80211DID_MKSECTION(5) | \
-			P80211DID_MKGROUP(12) | \
-			P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_p2req_ramdl_write_data \
-			(P80211DID_MKSECTION(5) | \
-			P80211DID_MKGROUP(12) | \
-			P80211DID_MKITEM(3) | 0x00000000)
-#define DIDmsg_p2req_ramdl_write_resultcode \
-			(P80211DID_MKSECTION(5) | \
-			P80211DID_MKGROUP(12) | \
-			P80211DID_MKITEM(4) | 0x00000000)
 #define DIDmsg_p2req_flashdl_state \
 			(P80211DID_MKSECTION(5) | \
 			P80211DID_MKGROUP(13))
-#define DIDmsg_p2req_flashdl_state_enable \
-			(P80211DID_MKSECTION(5) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_p2req_flashdl_state_resultcode \
-			(P80211DID_MKSECTION(5) | \
-			P80211DID_MKGROUP(13) | \
-			P80211DID_MKITEM(2) | 0x00000000)
 #define DIDmsg_p2req_flashdl_write \
 			(P80211DID_MKSECTION(5) | \
 			P80211DID_MKGROUP(14))
-#define DIDmsg_p2req_flashdl_write_addr \
-			(P80211DID_MKSECTION(5) | \
-			P80211DID_MKGROUP(14) | \
-			P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_p2req_flashdl_write_len \
-			(P80211DID_MKSECTION(5) | \
-			P80211DID_MKGROUP(14) | \
-			P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_p2req_flashdl_write_data \
-			(P80211DID_MKSECTION(5) | \
-			P80211DID_MKGROUP(14) | \
-			P80211DID_MKITEM(3) | 0x00000000)
-#define DIDmsg_p2req_flashdl_write_resultcode \
-			(P80211DID_MKSECTION(5) | \
-			P80211DID_MKGROUP(14) | \
-			P80211DID_MKITEM(4) | 0x00000000)
 #define DIDmib_cat_dot11smt \
 			P80211DID_MKSECTION(1)
 #define DIDmib_dot11smt_dot11WEPDefaultKeysTable \
@@ -684,8 +142,6 @@
 			(P80211DID_MKSECTION(1) | \
 			P80211DID_MKGROUP(6) | \
 			P80211DID_MKITEM(4) | 0x18000000)
-#define DIDmib_cat_dot11mac \
-			P80211DID_MKSECTION(2)
 #define DIDmib_dot11mac_dot11OperationTable \
 			(P80211DID_MKSECTION(2) | \
 			P80211DID_MKGROUP(1))
diff --git a/drivers/staging/wlan-ng/p80211metamib.h b/drivers/staging/wlan-ng/p80211metamib.h
deleted file mode 100644
index 9cd72ed..0000000
--- a/drivers/staging/wlan-ng/p80211metamib.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* p80211metamib.h
-*
-* Macros, const, types, and funcs for p80211 mib metadata
-*
-* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
-* --------------------------------------------------------------------
-*
-* linux-wlan
-*
-*   The contents of this file are subject to the Mozilla Public
-*   License Version 1.1 (the "License"); you may not use this file
-*   except in compliance with the License. You may obtain a copy of
-*   the License at http://www.mozilla.org/MPL/
-*
-*   Software distributed under the License is distributed on an "AS
-*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-*   implied. See the License for the specific language governing
-*   rights and limitations under the License.
-*
-*   Alternatively, the contents of this file may be used under the
-*   terms of the GNU Public License version 2 (the "GPL"), in which
-*   case the provisions of the GPL are applicable instead of the
-*   above.  If you wish to allow the use of your version of this file
-*   only under the terms of the GPL and not to allow others to use
-*   your version of this file under the MPL, indicate your decision
-*   by deleting the provisions above and replace them with the notice
-*   and other provisions required by the GPL.  If you do not delete
-*   the provisions above, a recipient may use your version of this
-*   file under either the MPL or the GPL.
-*
-* --------------------------------------------------------------------
-*
-* Inquiries regarding the linux-wlan Open Source project can be
-* made directly to:
-*
-* AbsoluteValue Systems Inc.
-* info@linux-wlan.com
-* http://www.linux-wlan.com
-*
-* --------------------------------------------------------------------
-*
-* Portions of the development of this software were funded by
-* Intersil Corporation as part of PRISM(R) chipset product development.
-*
-* --------------------------------------------------------------------
-*
-* This file declares some of the constants and types used in various
-* parts of the linux-wlan system.
-*
-* Notes:
-*   - Constant values are always in HOST byte order.
-*
-* All functions and statics declared here are implemented in p80211types.c
-*   --------------------------------------------------------------------
-*/
-
-#ifndef _P80211METAMIB_H
-#define _P80211METAMIB_H
-
-/*================================================================*/
-/* System Includes */
-
-/*================================================================*/
-/* Project Includes */
-
-#ifndef _WLAN_COMPAT_H
-#include "wlan_compat.h"
-#endif
-
-/*================================================================*/
-/* Constants */
-
-/*----------------------------------------------------------------*/
-/* */
-
-/*================================================================*/
-/* Macros */
-
-/*----------------------------------------------------------------*/
-/* */
-
-/*================================================================*/
-/* Types */
-
-/*----------------------------------------------------------------*/
-/* */
-
-/*================================================================*/
-/* Extern Declarations */
-
-/*----------------------------------------------------------------*/
-/* The following is the external declaration for the mib */
-/* category metadata list */
-
-extern catlistitem_t mib_catlist[];
-extern u32 mib_catlist_size;
-
-
-/*================================================================*/
-/* Function Declarations */
-
-/*----------------------------------------------------------------*/
-/* */
-
-#endif /* _P80211METAMIB_H */
diff --git a/drivers/staging/wlan-ng/p80211metamsg.h b/drivers/staging/wlan-ng/p80211metamsg.h
deleted file mode 100644
index 6e659ea..0000000
--- a/drivers/staging/wlan-ng/p80211metamsg.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* p80211metamsg.h
-*
-* Macros, const, types, and funcs for p80211 msg metadata
-*
-* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
-* --------------------------------------------------------------------
-*
-* linux-wlan
-*
-*   The contents of this file are subject to the Mozilla Public
-*   License Version 1.1 (the "License"); you may not use this file
-*   except in compliance with the License. You may obtain a copy of
-*   the License at http://www.mozilla.org/MPL/
-*
-*   Software distributed under the License is distributed on an "AS
-*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-*   implied. See the License for the specific language governing
-*   rights and limitations under the License.
-*
-*   Alternatively, the contents of this file may be used under the
-*   terms of the GNU Public License version 2 (the "GPL"), in which
-*   case the provisions of the GPL are applicable instead of the
-*   above.  If you wish to allow the use of your version of this file
-*   only under the terms of the GPL and not to allow others to use
-*   your version of this file under the MPL, indicate your decision
-*   by deleting the provisions above and replace them with the notice
-*   and other provisions required by the GPL.  If you do not delete
-*   the provisions above, a recipient may use your version of this
-*   file under either the MPL or the GPL.
-*
-* --------------------------------------------------------------------
-*
-* Inquiries regarding the linux-wlan Open Source project can be
-* made directly to:
-*
-* AbsoluteValue Systems Inc.
-* info@linux-wlan.com
-* http://www.linux-wlan.com
-*
-* --------------------------------------------------------------------
-*
-* Portions of the development of this software were funded by
-* Intersil Corporation as part of PRISM(R) chipset product development.
-*
-* --------------------------------------------------------------------
-*
-* This file declares some of the constants and types used in various
-* parts of the linux-wlan system.
-*
-* Notes:
-*   - Constant values are always in HOST byte order.
-*
-* All functions and statics declared here are implemented in p80211types.c
-*   --------------------------------------------------------------------
-*/
-
-#ifndef _P80211METAMSG_H
-#define _P80211METAMSG_H
-
-/*================================================================*/
-/* System Includes */
-
-/*================================================================*/
-/* Project Includes */
-
-#ifndef _WLAN_COMPAT_H
-#include "wlan_compat.h"
-#endif
-
-/*================================================================*/
-/* Constants */
-
-/*----------------------------------------------------------------*/
-/* */
-
-/*================================================================*/
-/* Macros */
-
-/*----------------------------------------------------------------*/
-/* */
-
-/*================================================================*/
-/* Types */
-
-/*----------------------------------------------------------------*/
-/* */
-
-/*================================================================*/
-/* Extern Declarations */
-
-/*----------------------------------------------------------------*/
-/* The following is the external declaration for the message */
-/* category metadata list */
-
-extern catlistitem_t msg_catlist[];
-extern u32 msg_catlist_size;
-
-
-/*================================================================*/
-/* Function Declarations */
-
-/*----------------------------------------------------------------*/
-/* */
-
-#endif /* _P80211METAMSG_H */
diff --git a/drivers/staging/wlan-ng/p80211metastruct.h b/drivers/staging/wlan-ng/p80211metastruct.h
index d2258b0..db12713 100644
--- a/drivers/staging/wlan-ng/p80211metastruct.h
+++ b/drivers/staging/wlan-ng/p80211metastruct.h
@@ -47,239 +47,223 @@
 #ifndef _P80211MKMETASTRUCT_H
 #define _P80211MKMETASTRUCT_H
 
+typedef struct p80211msg_dot11req_mibget {
+	u32 msgcode;
+	u32 msglen;
+	u8 devname[WLAN_DEVNAMELEN_MAX];
+	p80211item_unk392_t mibattribute;
+	p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_dot11req_mibget_t;
 
-typedef struct p80211msg_dot11req_mibget
-{
-	u32		msgcode	;
-	u32		msglen	;
-	u8		devname[WLAN_DEVNAMELEN_MAX]	;
-	p80211item_unk392_t	mibattribute	;
-	p80211item_uint32_t	resultcode	;
-} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_mibget_t;
+typedef struct p80211msg_dot11req_mibset {
+	u32 msgcode;
+	u32 msglen;
+	u8 devname[WLAN_DEVNAMELEN_MAX];
+	p80211item_unk392_t mibattribute;
+	p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_dot11req_mibset_t;
 
-typedef struct p80211msg_dot11req_mibset
-{
-	u32		msgcode	;
-	u32		msglen	;
-	u8		devname[WLAN_DEVNAMELEN_MAX]	;
-	p80211item_unk392_t	mibattribute	;
-	p80211item_uint32_t	resultcode	;
-} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_mibset_t;
+typedef struct p80211msg_dot11req_scan {
+	u32 msgcode;
+	u32 msglen;
+	u8 devname[WLAN_DEVNAMELEN_MAX];
+	p80211item_uint32_t bsstype;
+	p80211item_pstr6_t bssid;
+	u8 pad_0C[1];
+	p80211item_pstr32_t ssid;
+	u8 pad_1D[3];
+	p80211item_uint32_t scantype;
+	p80211item_uint32_t probedelay;
+	p80211item_pstr14_t channellist;
+	u8 pad_2C[1];
+	p80211item_uint32_t minchanneltime;
+	p80211item_uint32_t maxchanneltime;
+	p80211item_uint32_t resultcode;
+	p80211item_uint32_t numbss;
+	p80211item_uint32_t append;
+} __attribute__ ((packed)) p80211msg_dot11req_scan_t;
 
-typedef struct p80211msg_dot11req_scan
-{
-	u32		msgcode	;
-	u32		msglen	;
-	u8		devname[WLAN_DEVNAMELEN_MAX]	;
-	p80211item_uint32_t	bsstype	;
-	p80211item_pstr6_t	bssid	;
-	u8	pad_0C[1]	;
-	p80211item_pstr32_t	ssid	;
-	u8	pad_1D[3]	;
-	p80211item_uint32_t	scantype	;
-	p80211item_uint32_t	probedelay	;
-	p80211item_pstr14_t	channellist	;
-	u8	pad_2C[1]	;
-	p80211item_uint32_t	minchanneltime	;
-	p80211item_uint32_t	maxchanneltime	;
-	p80211item_uint32_t	resultcode	;
-	p80211item_uint32_t	numbss	;
-	p80211item_uint32_t	append	;
-} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_scan_t;
+typedef struct p80211msg_dot11req_scan_results {
+	u32 msgcode;
+	u32 msglen;
+	u8 devname[WLAN_DEVNAMELEN_MAX];
+	p80211item_uint32_t bssindex;
+	p80211item_uint32_t resultcode;
+	p80211item_uint32_t signal;
+	p80211item_uint32_t noise;
+	p80211item_pstr6_t bssid;
+	u8 pad_3C[1];
+	p80211item_pstr32_t ssid;
+	u8 pad_4D[3];
+	p80211item_uint32_t bsstype;
+	p80211item_uint32_t beaconperiod;
+	p80211item_uint32_t dtimperiod;
+	p80211item_uint32_t timestamp;
+	p80211item_uint32_t localtime;
+	p80211item_uint32_t fhdwelltime;
+	p80211item_uint32_t fhhopset;
+	p80211item_uint32_t fhhoppattern;
+	p80211item_uint32_t fhhopindex;
+	p80211item_uint32_t dschannel;
+	p80211item_uint32_t cfpcount;
+	p80211item_uint32_t cfpperiod;
+	p80211item_uint32_t cfpmaxduration;
+	p80211item_uint32_t cfpdurremaining;
+	p80211item_uint32_t ibssatimwindow;
+	p80211item_uint32_t cfpollable;
+	p80211item_uint32_t cfpollreq;
+	p80211item_uint32_t privacy;
+	p80211item_uint32_t basicrate1;
+	p80211item_uint32_t basicrate2;
+	p80211item_uint32_t basicrate3;
+	p80211item_uint32_t basicrate4;
+	p80211item_uint32_t basicrate5;
+	p80211item_uint32_t basicrate6;
+	p80211item_uint32_t basicrate7;
+	p80211item_uint32_t basicrate8;
+	p80211item_uint32_t supprate1;
+	p80211item_uint32_t supprate2;
+	p80211item_uint32_t supprate3;
+	p80211item_uint32_t supprate4;
+	p80211item_uint32_t supprate5;
+	p80211item_uint32_t supprate6;
+	p80211item_uint32_t supprate7;
+	p80211item_uint32_t supprate8;
+} __attribute__ ((packed)) p80211msg_dot11req_scan_results_t;
 
-typedef struct p80211msg_dot11req_scan_results
-{
-	u32		msgcode	;
-	u32		msglen	;
-	u8		devname[WLAN_DEVNAMELEN_MAX]	;
-	p80211item_uint32_t	bssindex	;
-	p80211item_uint32_t	resultcode	;
-	p80211item_uint32_t	signal	;
-	p80211item_uint32_t	noise	;
-	p80211item_pstr6_t	bssid	;
-	u8	pad_3C[1]	;
-	p80211item_pstr32_t	ssid	;
-	u8	pad_4D[3]	;
-	p80211item_uint32_t	bsstype	;
-	p80211item_uint32_t	beaconperiod	;
-	p80211item_uint32_t	dtimperiod	;
-	p80211item_uint32_t	timestamp	;
-	p80211item_uint32_t	localtime	;
-	p80211item_uint32_t	fhdwelltime	;
-	p80211item_uint32_t	fhhopset	;
-	p80211item_uint32_t	fhhoppattern	;
-	p80211item_uint32_t	fhhopindex	;
-	p80211item_uint32_t	dschannel	;
-	p80211item_uint32_t	cfpcount	;
-	p80211item_uint32_t	cfpperiod	;
-	p80211item_uint32_t	cfpmaxduration	;
-	p80211item_uint32_t	cfpdurremaining	;
-	p80211item_uint32_t	ibssatimwindow	;
-	p80211item_uint32_t	cfpollable	;
-	p80211item_uint32_t	cfpollreq	;
-	p80211item_uint32_t	privacy	;
-	p80211item_uint32_t	basicrate1	;
-	p80211item_uint32_t	basicrate2	;
-	p80211item_uint32_t	basicrate3	;
-	p80211item_uint32_t	basicrate4	;
-	p80211item_uint32_t	basicrate5	;
-	p80211item_uint32_t	basicrate6	;
-	p80211item_uint32_t	basicrate7	;
-	p80211item_uint32_t	basicrate8	;
-	p80211item_uint32_t	supprate1	;
-	p80211item_uint32_t	supprate2	;
-	p80211item_uint32_t	supprate3	;
-	p80211item_uint32_t	supprate4	;
-	p80211item_uint32_t	supprate5	;
-	p80211item_uint32_t	supprate6	;
-	p80211item_uint32_t	supprate7	;
-	p80211item_uint32_t	supprate8	;
-} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_scan_results_t;
+typedef struct p80211msg_dot11req_start {
+	u32 msgcode;
+	u32 msglen;
+	u8 devname[WLAN_DEVNAMELEN_MAX];
+	p80211item_pstr32_t ssid;
+	u8 pad_12D[3];
+	p80211item_uint32_t bsstype;
+	p80211item_uint32_t beaconperiod;
+	p80211item_uint32_t dtimperiod;
+	p80211item_uint32_t cfpperiod;
+	p80211item_uint32_t cfpmaxduration;
+	p80211item_uint32_t fhdwelltime;
+	p80211item_uint32_t fhhopset;
+	p80211item_uint32_t fhhoppattern;
+	p80211item_uint32_t dschannel;
+	p80211item_uint32_t ibssatimwindow;
+	p80211item_uint32_t probedelay;
+	p80211item_uint32_t cfpollable;
+	p80211item_uint32_t cfpollreq;
+	p80211item_uint32_t basicrate1;
+	p80211item_uint32_t basicrate2;
+	p80211item_uint32_t basicrate3;
+	p80211item_uint32_t basicrate4;
+	p80211item_uint32_t basicrate5;
+	p80211item_uint32_t basicrate6;
+	p80211item_uint32_t basicrate7;
+	p80211item_uint32_t basicrate8;
+	p80211item_uint32_t operationalrate1;
+	p80211item_uint32_t operationalrate2;
+	p80211item_uint32_t operationalrate3;
+	p80211item_uint32_t operationalrate4;
+	p80211item_uint32_t operationalrate5;
+	p80211item_uint32_t operationalrate6;
+	p80211item_uint32_t operationalrate7;
+	p80211item_uint32_t operationalrate8;
+	p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_dot11req_start_t;
 
-typedef struct p80211msg_dot11req_start
-{
-	u32		msgcode	;
-	u32		msglen	;
-	u8		devname[WLAN_DEVNAMELEN_MAX]	;
-	p80211item_pstr32_t	ssid	;
-	u8	pad_12D[3]	;
-	p80211item_uint32_t	bsstype	;
-	p80211item_uint32_t	beaconperiod	;
-	p80211item_uint32_t	dtimperiod	;
-	p80211item_uint32_t	cfpperiod	;
-	p80211item_uint32_t	cfpmaxduration	;
-	p80211item_uint32_t	fhdwelltime	;
-	p80211item_uint32_t	fhhopset	;
-	p80211item_uint32_t	fhhoppattern	;
-	p80211item_uint32_t	dschannel	;
-	p80211item_uint32_t	ibssatimwindow	;
-	p80211item_uint32_t	probedelay	;
-	p80211item_uint32_t	cfpollable	;
-	p80211item_uint32_t	cfpollreq	;
-	p80211item_uint32_t	basicrate1	;
-	p80211item_uint32_t	basicrate2	;
-	p80211item_uint32_t	basicrate3	;
-	p80211item_uint32_t	basicrate4	;
-	p80211item_uint32_t	basicrate5	;
-	p80211item_uint32_t	basicrate6	;
-	p80211item_uint32_t	basicrate7	;
-	p80211item_uint32_t	basicrate8	;
-	p80211item_uint32_t	operationalrate1	;
-	p80211item_uint32_t	operationalrate2	;
-	p80211item_uint32_t	operationalrate3	;
-	p80211item_uint32_t	operationalrate4	;
-	p80211item_uint32_t	operationalrate5	;
-	p80211item_uint32_t	operationalrate6	;
-	p80211item_uint32_t	operationalrate7	;
-	p80211item_uint32_t	operationalrate8	;
-	p80211item_uint32_t	resultcode	;
-} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_start_t;
+typedef struct p80211msg_lnxreq_ifstate {
+	u32 msgcode;
+	u32 msglen;
+	u8 devname[WLAN_DEVNAMELEN_MAX];
+	p80211item_uint32_t ifstate;
+	p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_lnxreq_ifstate_t;
 
-typedef struct p80211msg_lnxreq_ifstate
-{
-	u32		msgcode	;
-	u32		msglen	;
-	u8		devname[WLAN_DEVNAMELEN_MAX]	;
-	p80211item_uint32_t	ifstate	;
-	p80211item_uint32_t	resultcode	;
-} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_ifstate_t;
+typedef struct p80211msg_lnxreq_wlansniff {
+	u32 msgcode;
+	u32 msglen;
+	u8 devname[WLAN_DEVNAMELEN_MAX];
+	p80211item_uint32_t enable;
+	p80211item_uint32_t channel;
+	p80211item_uint32_t prismheader;
+	p80211item_uint32_t wlanheader;
+	p80211item_uint32_t keepwepflags;
+	p80211item_uint32_t stripfcs;
+	p80211item_uint32_t packet_trunc;
+	p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_lnxreq_wlansniff_t;
 
-typedef struct p80211msg_lnxreq_wlansniff
-{
-	u32		msgcode	;
-	u32		msglen	;
-	u8		devname[WLAN_DEVNAMELEN_MAX]	;
-	p80211item_uint32_t	enable	;
-	p80211item_uint32_t	channel	;
-	p80211item_uint32_t	prismheader	;
-	p80211item_uint32_t	wlanheader	;
-	p80211item_uint32_t	keepwepflags	;
-	p80211item_uint32_t	stripfcs	;
-	p80211item_uint32_t	packet_trunc	;
-	p80211item_uint32_t	resultcode	;
-} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_wlansniff_t;
+typedef struct p80211msg_lnxreq_hostwep {
+	u32 msgcode;
+	u32 msglen;
+	u8 devname[WLAN_DEVNAMELEN_MAX];
+	p80211item_uint32_t resultcode;
+	p80211item_uint32_t decrypt;
+	p80211item_uint32_t encrypt;
+} __attribute__ ((packed)) p80211msg_lnxreq_hostwep_t;
 
-typedef struct p80211msg_lnxreq_hostwep
-{
-	u32		msgcode	;
-	u32		msglen	;
-	u8		devname[WLAN_DEVNAMELEN_MAX]	;
-	p80211item_uint32_t	resultcode	;
-	p80211item_uint32_t	decrypt	;
-	p80211item_uint32_t	encrypt	;
-} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_hostwep_t;
+typedef struct p80211msg_lnxreq_commsquality {
+	u32 msgcode;
+	u32 msglen;
+	u8 devname[WLAN_DEVNAMELEN_MAX];
+	p80211item_uint32_t resultcode;
+	p80211item_uint32_t dbm;
+	p80211item_uint32_t link;
+	p80211item_uint32_t level;
+	p80211item_uint32_t noise;
+} __attribute__ ((packed)) p80211msg_lnxreq_commsquality_t;
 
-typedef struct p80211msg_lnxreq_commsquality
-{
-	u32		msgcode	;
-	u32		msglen	;
-	u8		devname[WLAN_DEVNAMELEN_MAX]	;
-	p80211item_uint32_t	resultcode	;
-	p80211item_uint32_t	dbm	;
-	p80211item_uint32_t	link	;
-	p80211item_uint32_t	level	;
-	p80211item_uint32_t	noise	;
-} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_commsquality_t;
+typedef struct p80211msg_lnxreq_autojoin {
+	u32 msgcode;
+	u32 msglen;
+	u8 devname[WLAN_DEVNAMELEN_MAX];
+	p80211item_pstr32_t ssid;
+	u8 pad_19D[3];
+	p80211item_uint32_t authtype;
+	p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_lnxreq_autojoin_t;
 
-typedef struct p80211msg_lnxreq_autojoin
-{
-	u32		msgcode	;
-	u32		msglen	;
-	u8		devname[WLAN_DEVNAMELEN_MAX]	;
-	p80211item_pstr32_t	ssid	;
-	u8	pad_19D[3]	;
-	p80211item_uint32_t	authtype	;
-	p80211item_uint32_t	resultcode	;
-} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_autojoin_t;
+typedef struct p80211msg_p2req_readpda {
+	u32 msgcode;
+	u32 msglen;
+	u8 devname[WLAN_DEVNAMELEN_MAX];
+	p80211item_unk1024_t pda;
+	p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_p2req_readpda_t;
 
-typedef struct p80211msg_p2req_readpda
-{
-	u32		msgcode	;
-	u32		msglen	;
-	u8		devname[WLAN_DEVNAMELEN_MAX]	;
-	p80211item_unk1024_t	pda	;
-	p80211item_uint32_t	resultcode	;
-} __WLAN_ATTRIB_PACK__ p80211msg_p2req_readpda_t;
+typedef struct p80211msg_p2req_ramdl_state {
+	u32 msgcode;
+	u32 msglen;
+	u8 devname[WLAN_DEVNAMELEN_MAX];
+	p80211item_uint32_t enable;
+	p80211item_uint32_t exeaddr;
+	p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_p2req_ramdl_state_t;
 
-typedef struct p80211msg_p2req_ramdl_state
-{
-	u32		msgcode	;
-	u32		msglen	;
-	u8		devname[WLAN_DEVNAMELEN_MAX]	;
-	p80211item_uint32_t	enable	;
-	p80211item_uint32_t	exeaddr	;
-	p80211item_uint32_t	resultcode	;
-} __WLAN_ATTRIB_PACK__ p80211msg_p2req_ramdl_state_t;
+typedef struct p80211msg_p2req_ramdl_write {
+	u32 msgcode;
+	u32 msglen;
+	u8 devname[WLAN_DEVNAMELEN_MAX];
+	p80211item_uint32_t addr;
+	p80211item_uint32_t len;
+	p80211item_unk4096_t data;
+	p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_p2req_ramdl_write_t;
 
-typedef struct p80211msg_p2req_ramdl_write
-{
-	u32		msgcode	;
-	u32		msglen	;
-	u8		devname[WLAN_DEVNAMELEN_MAX]	;
-	p80211item_uint32_t	addr	;
-	p80211item_uint32_t	len	;
-	p80211item_unk4096_t	data	;
-	p80211item_uint32_t	resultcode	;
-} __WLAN_ATTRIB_PACK__ p80211msg_p2req_ramdl_write_t;
+typedef struct p80211msg_p2req_flashdl_state {
+	u32 msgcode;
+	u32 msglen;
+	u8 devname[WLAN_DEVNAMELEN_MAX];
+	p80211item_uint32_t enable;
+	p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_p2req_flashdl_state_t;
 
-typedef struct p80211msg_p2req_flashdl_state
-{
-	u32		msgcode	;
-	u32		msglen	;
-	u8		devname[WLAN_DEVNAMELEN_MAX]	;
-	p80211item_uint32_t	enable	;
-	p80211item_uint32_t	resultcode	;
-} __WLAN_ATTRIB_PACK__ p80211msg_p2req_flashdl_state_t;
-
-typedef struct p80211msg_p2req_flashdl_write
-{
-	u32		msgcode	;
-	u32		msglen	;
-	u8		devname[WLAN_DEVNAMELEN_MAX]	;
-	p80211item_uint32_t	addr	;
-	p80211item_uint32_t	len	;
-	p80211item_unk4096_t	data	;
-	p80211item_uint32_t	resultcode	;
-} __WLAN_ATTRIB_PACK__ p80211msg_p2req_flashdl_write_t;
+typedef struct p80211msg_p2req_flashdl_write {
+	u32 msgcode;
+	u32 msglen;
+	u8 devname[WLAN_DEVNAMELEN_MAX];
+	p80211item_uint32_t addr;
+	p80211item_uint32_t len;
+	p80211item_unk4096_t data;
+	p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_p2req_flashdl_write_t;
 
 #endif
diff --git a/drivers/staging/wlan-ng/p80211mgmt.h b/drivers/staging/wlan-ng/p80211mgmt.h
index 6cc16c3..6235fe7 100644
--- a/drivers/staging/wlan-ng/p80211mgmt.h
+++ b/drivers/staging/wlan-ng/p80211mgmt.h
@@ -101,14 +101,8 @@
 #define _P80211MGMT_H
 
 /*================================================================*/
-/* System Includes */
-
-/*================================================================*/
 /* Project Includes */
 
-#ifndef  _WLAN_COMPAT_H
-#include "wlan_compat.h"
-#endif
 
 #ifndef  _P80211HDR_H
 #include "p80211hdr.h"
@@ -160,8 +154,6 @@
 #define WLAN_MGMT_STATUS_ASSOC_DENIED_NOPBCC	20
 #define WLAN_MGMT_STATUS_ASSOC_DENIED_NOAGILITY	21
 
-
-
 /*-- Auth Algorithm Field ---------------------------*/
 #define WLAN_AUTH_ALG_OPENSYSTEM		0
 #define WLAN_AUTH_ALG_SHAREDKEY			1
@@ -211,20 +203,16 @@
 
 #define WLAN_DEAUTHEN_OFF_REASON		0
 
-
-/*================================================================*/
-/* Macros */
-
 /*-- Capability Field ---------------------------*/
-#define WLAN_GET_MGMT_CAP_INFO_ESS(n)		((n) & BIT0)
-#define WLAN_GET_MGMT_CAP_INFO_IBSS(n)		(((n) & BIT1) >> 1)
-#define WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(n)	(((n) & BIT2) >> 2)
-#define WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(n)	(((n) & BIT3) >> 3)
-#define WLAN_GET_MGMT_CAP_INFO_PRIVACY(n)	(((n) & BIT4) >> 4)
+#define WLAN_GET_MGMT_CAP_INFO_ESS(n)		((n) & BIT(0))
+#define WLAN_GET_MGMT_CAP_INFO_IBSS(n)		(((n) & BIT(1)) >> 1)
+#define WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(n)	(((n) & BIT(2)) >> 2)
+#define WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(n)	(((n) & BIT(3)) >> 3)
+#define WLAN_GET_MGMT_CAP_INFO_PRIVACY(n)	(((n) & BIT(4)) >> 4)
   /* p80211b additions */
-#define WLAN_GET_MGMT_CAP_INFO_SHORT(n)		(((n) & BIT5) >> 5)
-#define WLAN_GET_MGMT_CAP_INFO_PBCC(n)		(((n) & BIT6) >> 6)
-#define WLAN_GET_MGMT_CAP_INFO_AGILITY(n)	(((n) & BIT7) >> 7)
+#define WLAN_GET_MGMT_CAP_INFO_SHORT(n)		(((n) & BIT(5)) >> 5)
+#define WLAN_GET_MGMT_CAP_INFO_PBCC(n)		(((n) & BIT(6)) >> 6)
+#define WLAN_GET_MGMT_CAP_INFO_AGILITY(n)	(((n) & BIT(7)) >> 7)
 
 #define WLAN_SET_MGMT_CAP_INFO_ESS(n)		(n)
 #define WLAN_SET_MGMT_CAP_INFO_IBSS(n)		((n) << 1)
@@ -236,143 +224,126 @@
 #define WLAN_SET_MGMT_CAP_INFO_PBCC(n)		((n) << 6)
 #define WLAN_SET_MGMT_CAP_INFO_AGILITY(n)	((n) << 7)
 
-
-/*================================================================*/
-/* Types */
-
 /*-- Information Element Types --------------------*/
 /* prototype structure, all IEs start with these members */
 
-typedef struct wlan_ie
-{
-	u8	eid;
-	u8	len;
-} __WLAN_ATTRIB_PACK__ wlan_ie_t;
+typedef struct wlan_ie {
+	u8 eid;
+	u8 len;
+} __attribute__ ((packed)) wlan_ie_t;
 
 /*-- Service Set Identity (SSID)  -----------------*/
-typedef struct wlan_ie_ssid
-{
-	u8	eid;
-	u8	len;
-	u8	ssid[1];  /* may be zero, ptrs may overlap */
-} __WLAN_ATTRIB_PACK__ wlan_ie_ssid_t;
+typedef struct wlan_ie_ssid {
+	u8 eid;
+	u8 len;
+	u8 ssid[1];		/* may be zero, ptrs may overlap */
+} __attribute__ ((packed)) wlan_ie_ssid_t;
 
 /*-- Supported Rates  -----------------------------*/
-typedef struct wlan_ie_supp_rates
-{
-	u8	eid;
-	u8	len;
-	u8	rates[1];  /* had better be at LEAST one! */
-} __WLAN_ATTRIB_PACK__ wlan_ie_supp_rates_t;
+typedef struct wlan_ie_supp_rates {
+	u8 eid;
+	u8 len;
+	u8 rates[1];		/* had better be at LEAST one! */
+} __attribute__ ((packed)) wlan_ie_supp_rates_t;
 
 /*-- FH Parameter Set  ----------------------------*/
-typedef struct wlan_ie_fh_parms
-{
-	u8	eid;
-	u8	len;
-	u16	dwell;
-	u8	hopset;
-	u8	hoppattern;
-	u8	hopindex;
-} __WLAN_ATTRIB_PACK__ wlan_ie_fh_parms_t;
+typedef struct wlan_ie_fh_parms {
+	u8 eid;
+	u8 len;
+	u16 dwell;
+	u8 hopset;
+	u8 hoppattern;
+	u8 hopindex;
+} __attribute__ ((packed)) wlan_ie_fh_parms_t;
 
 /*-- DS Parameter Set  ----------------------------*/
-typedef struct wlan_ie_ds_parms
-{
-	u8	eid;
-	u8	len;
-	u8	curr_ch;
-} __WLAN_ATTRIB_PACK__ wlan_ie_ds_parms_t;
+typedef struct wlan_ie_ds_parms {
+	u8 eid;
+	u8 len;
+	u8 curr_ch;
+} __attribute__ ((packed)) wlan_ie_ds_parms_t;
 
 /*-- CF Parameter Set  ----------------------------*/
 
-typedef struct wlan_ie_cf_parms
-{
-	u8	eid;
-	u8	len;
-	u8	cfp_cnt;
-	u8	cfp_period;
-	u16	cfp_maxdur;
-	u16	cfp_durremaining;
-} __WLAN_ATTRIB_PACK__ wlan_ie_cf_parms_t;
+typedef struct wlan_ie_cf_parms {
+	u8 eid;
+	u8 len;
+	u8 cfp_cnt;
+	u8 cfp_period;
+	u16 cfp_maxdur;
+	u16 cfp_durremaining;
+} __attribute__ ((packed)) wlan_ie_cf_parms_t;
 
 /*-- TIM ------------------------------------------*/
-typedef struct wlan_ie_tim
-{
-	u8	eid;
-	u8	len;
-	u8	dtim_cnt;
-	u8	dtim_period;
-	u8	bitmap_ctl;
-	u8	virt_bm[1];
-} __WLAN_ATTRIB_PACK__ wlan_ie_tim_t;
+typedef struct wlan_ie_tim {
+	u8 eid;
+	u8 len;
+	u8 dtim_cnt;
+	u8 dtim_period;
+	u8 bitmap_ctl;
+	u8 virt_bm[1];
+} __attribute__ ((packed)) wlan_ie_tim_t;
 
 /*-- IBSS Parameter Set ---------------------------*/
-typedef struct wlan_ie_ibss_parms
-{
-	u8	eid;
-	u8	len;
-	u16	atim_win;
-} __WLAN_ATTRIB_PACK__ wlan_ie_ibss_parms_t;
+typedef struct wlan_ie_ibss_parms {
+	u8 eid;
+	u8 len;
+	u16 atim_win;
+} __attribute__ ((packed)) wlan_ie_ibss_parms_t;
 
 /*-- Challenge Text  ------------------------------*/
-typedef struct wlan_ie_challenge
-{
-	u8	eid;
-	u8	len;
-	u8	challenge[1];
-} __WLAN_ATTRIB_PACK__ wlan_ie_challenge_t;
+typedef struct wlan_ie_challenge {
+	u8 eid;
+	u8 len;
+	u8 challenge[1];
+} __attribute__ ((packed)) wlan_ie_challenge_t;
 
 /*-------------------------------------------------*/
 /*  Frame Types  */
 
 /* prototype structure, all mgmt frame types will start with these members */
-typedef struct wlan_fr_mgmt
-{
-	u16			type;
-	u16			len;	/* DOES NOT include CRC !!!!*/
-	u8			*buf;
-	p80211_hdr_t		*hdr;
+typedef struct wlan_fr_mgmt {
+	u16 type;
+	u16 len;		/* DOES NOT include CRC !!!! */
+	u8 *buf;
+	p80211_hdr_t *hdr;
 	/* used for target specific data, skb in Linux */
-	void			*priv;
+	void *priv;
 	/*-- fixed fields -----------*/
 	/*-- info elements ----------*/
 } wlan_fr_mgmt_t;
 
 /*-- Beacon ---------------------------------------*/
-typedef struct wlan_fr_beacon
-{
-	u16			type;
-	u16			len;
-	u8			*buf;
-	p80211_hdr_t		*hdr;
+typedef struct wlan_fr_beacon {
+	u16 type;
+	u16 len;
+	u8 *buf;
+	p80211_hdr_t *hdr;
 	/* used for target specific data, skb in Linux */
-	void			*priv;
+	void *priv;
 	/*-- fixed fields -----------*/
-	u64			*ts;
-	u16			*bcn_int;
-	u16			*cap_info;
+	u64 *ts;
+	u16 *bcn_int;
+	u16 *cap_info;
 	/*-- info elements ----------*/
-	wlan_ie_ssid_t		*ssid;
-	wlan_ie_supp_rates_t	*supp_rates;
-	wlan_ie_fh_parms_t	*fh_parms;
-	wlan_ie_ds_parms_t	*ds_parms;
-	wlan_ie_cf_parms_t	*cf_parms;
-	wlan_ie_ibss_parms_t	*ibss_parms;
-	wlan_ie_tim_t		*tim;
+	wlan_ie_ssid_t *ssid;
+	wlan_ie_supp_rates_t *supp_rates;
+	wlan_ie_fh_parms_t *fh_parms;
+	wlan_ie_ds_parms_t *ds_parms;
+	wlan_ie_cf_parms_t *cf_parms;
+	wlan_ie_ibss_parms_t *ibss_parms;
+	wlan_ie_tim_t *tim;
 
 } wlan_fr_beacon_t;
 
-
 /*-- IBSS ATIM ------------------------------------*/
-typedef struct wlan_fr_ibssatim
-{
-	u16			type;
-	u16			len;
-	u8*			buf;
-	p80211_hdr_t		*hdr;
+typedef struct wlan_fr_ibssatim {
+	u16 type;
+	u16 len;
+	u8 *buf;
+	p80211_hdr_t *hdr;
 	/* used for target specific data, skb in Linux */
-	void			*priv;
+	void *priv;
 
 	/*-- fixed fields -----------*/
 	/*-- info elements ----------*/
@@ -382,194 +353,176 @@
 } wlan_fr_ibssatim_t;
 
 /*-- Disassociation -------------------------------*/
-typedef struct wlan_fr_disassoc
-{
-	u16			type;
-	u16			len;
-	u8			*buf;
-	p80211_hdr_t		*hdr;
+typedef struct wlan_fr_disassoc {
+	u16 type;
+	u16 len;
+	u8 *buf;
+	p80211_hdr_t *hdr;
 	/* used for target specific data, skb in Linux */
-	void			*priv;
+	void *priv;
 	/*-- fixed fields -----------*/
-	u16			*reason;
+	u16 *reason;
 
 	/*-- info elements ----------*/
 
 } wlan_fr_disassoc_t;
 
 /*-- Association Request --------------------------*/
-typedef struct wlan_fr_assocreq
-{
-	u16			type;
-	u16			len;
-	u8*			buf;
-	p80211_hdr_t		*hdr;
+typedef struct wlan_fr_assocreq {
+	u16 type;
+	u16 len;
+	u8 *buf;
+	p80211_hdr_t *hdr;
 	/* used for target specific data, skb in Linux */
-	void			*priv;
+	void *priv;
 	/*-- fixed fields -----------*/
-	u16			*cap_info;
-	u16			*listen_int;
+	u16 *cap_info;
+	u16 *listen_int;
 	/*-- info elements ----------*/
-	wlan_ie_ssid_t		*ssid;
-	wlan_ie_supp_rates_t	*supp_rates;
+	wlan_ie_ssid_t *ssid;
+	wlan_ie_supp_rates_t *supp_rates;
 
 } wlan_fr_assocreq_t;
 
 /*-- Association Response -------------------------*/
-typedef struct wlan_fr_assocresp
-{
-	u16			type;
-	u16			len;
-	u8			*buf;
-	p80211_hdr_t		*hdr;
+typedef struct wlan_fr_assocresp {
+	u16 type;
+	u16 len;
+	u8 *buf;
+	p80211_hdr_t *hdr;
 	/* used for target specific data, skb in Linux */
-	void			*priv;
+	void *priv;
 	/*-- fixed fields -----------*/
-	u16			*cap_info;
-	u16			*status;
-	u16			*aid;
+	u16 *cap_info;
+	u16 *status;
+	u16 *aid;
 	/*-- info elements ----------*/
-	wlan_ie_supp_rates_t	*supp_rates;
+	wlan_ie_supp_rates_t *supp_rates;
 
 } wlan_fr_assocresp_t;
 
 /*-- Reassociation Request ------------------------*/
-typedef struct wlan_fr_reassocreq
-{
-	u16			type;
-	u16			len;
-	u8			*buf;
-	p80211_hdr_t		*hdr;
+typedef struct wlan_fr_reassocreq {
+	u16 type;
+	u16 len;
+	u8 *buf;
+	p80211_hdr_t *hdr;
 	/* used for target specific data, skb in Linux */
-	void			*priv;
+	void *priv;
 	/*-- fixed fields -----------*/
-	u16			*cap_info;
-	u16			*listen_int;
-	u8			*curr_ap;
+	u16 *cap_info;
+	u16 *listen_int;
+	u8 *curr_ap;
 	/*-- info elements ----------*/
-	wlan_ie_ssid_t		*ssid;
-	wlan_ie_supp_rates_t	*supp_rates;
+	wlan_ie_ssid_t *ssid;
+	wlan_ie_supp_rates_t *supp_rates;
 
 } wlan_fr_reassocreq_t;
 
 /*-- Reassociation Response -----------------------*/
-typedef struct wlan_fr_reassocresp
-{
-	u16			type;
-	u16			len;
-	u8			*buf;
-	p80211_hdr_t		*hdr;
+typedef struct wlan_fr_reassocresp {
+	u16 type;
+	u16 len;
+	u8 *buf;
+	p80211_hdr_t *hdr;
 	/* used for target specific data, skb in Linux */
-	void			*priv;
+	void *priv;
 	/*-- fixed fields -----------*/
-	u16			*cap_info;
-	u16			*status;
-	u16			*aid;
+	u16 *cap_info;
+	u16 *status;
+	u16 *aid;
 	/*-- info elements ----------*/
-	wlan_ie_supp_rates_t	*supp_rates;
+	wlan_ie_supp_rates_t *supp_rates;
 
 } wlan_fr_reassocresp_t;
 
 /*-- Probe Request --------------------------------*/
-typedef struct wlan_fr_probereq
-{
-	u16			type;
-	u16			len;
-	u8			*buf;
-	p80211_hdr_t		*hdr;
+typedef struct wlan_fr_probereq {
+	u16 type;
+	u16 len;
+	u8 *buf;
+	p80211_hdr_t *hdr;
 	/* used for target specific data, skb in Linux */
-	void			*priv;
+	void *priv;
 	/*-- fixed fields -----------*/
 	/*-- info elements ----------*/
-	wlan_ie_ssid_t		*ssid;
-	wlan_ie_supp_rates_t	*supp_rates;
+	wlan_ie_ssid_t *ssid;
+	wlan_ie_supp_rates_t *supp_rates;
 
 } wlan_fr_probereq_t;
 
 /*-- Probe Response -------------------------------*/
-typedef struct wlan_fr_proberesp
-{
-	u16			type;
-	u16			len;
-	u8			*buf;
-	p80211_hdr_t		*hdr;
+typedef struct wlan_fr_proberesp {
+	u16 type;
+	u16 len;
+	u8 *buf;
+	p80211_hdr_t *hdr;
 	/* used for target specific data, skb in Linux */
-	void			*priv;
+	void *priv;
 	/*-- fixed fields -----------*/
-	u64			*ts;
-	u16			*bcn_int;
-	u16			*cap_info;
+	u64 *ts;
+	u16 *bcn_int;
+	u16 *cap_info;
 	/*-- info elements ----------*/
-	wlan_ie_ssid_t		*ssid;
-	wlan_ie_supp_rates_t	*supp_rates;
-	wlan_ie_fh_parms_t	*fh_parms;
-	wlan_ie_ds_parms_t	*ds_parms;
-	wlan_ie_cf_parms_t	*cf_parms;
-	wlan_ie_ibss_parms_t	*ibss_parms;
+	wlan_ie_ssid_t *ssid;
+	wlan_ie_supp_rates_t *supp_rates;
+	wlan_ie_fh_parms_t *fh_parms;
+	wlan_ie_ds_parms_t *ds_parms;
+	wlan_ie_cf_parms_t *cf_parms;
+	wlan_ie_ibss_parms_t *ibss_parms;
 } wlan_fr_proberesp_t;
 
 /*-- Authentication -------------------------------*/
-typedef struct wlan_fr_authen
-{
-	u16			type;
-	u16			len;
-	u8			*buf;
-	p80211_hdr_t		*hdr;
+typedef struct wlan_fr_authen {
+	u16 type;
+	u16 len;
+	u8 *buf;
+	p80211_hdr_t *hdr;
 	/* used for target specific data, skb in Linux */
-	void			*priv;
+	void *priv;
 	/*-- fixed fields -----------*/
-	u16			*auth_alg;
-	u16			*auth_seq;
-	u16			*status;
+	u16 *auth_alg;
+	u16 *auth_seq;
+	u16 *status;
 	/*-- info elements ----------*/
-	wlan_ie_challenge_t	*challenge;
+	wlan_ie_challenge_t *challenge;
 
 } wlan_fr_authen_t;
 
 /*-- Deauthenication -----------------------------*/
-typedef struct wlan_fr_deauthen
-{
-	u16			type;
-	u16			len;
-	u8			*buf;
-	p80211_hdr_t		*hdr;
+typedef struct wlan_fr_deauthen {
+	u16 type;
+	u16 len;
+	u8 *buf;
+	p80211_hdr_t *hdr;
 	/* used for target specific data, skb in Linux */
-	void			*priv;
+	void *priv;
 	/*-- fixed fields -----------*/
-	u16			*reason;
+	u16 *reason;
 
 	/*-- info elements ----------*/
 
 } wlan_fr_deauthen_t;
 
-
-/*================================================================*/
-/* Extern Declarations */
-
-
-/*================================================================*/
-/* Function Declarations */
-
-void wlan_mgmt_encode_beacon( wlan_fr_beacon_t  *f );
-void wlan_mgmt_decode_beacon( wlan_fr_beacon_t  *f );
-void wlan_mgmt_encode_disassoc( wlan_fr_disassoc_t  *f );
-void wlan_mgmt_decode_disassoc( wlan_fr_disassoc_t  *f );
-void wlan_mgmt_encode_assocreq( wlan_fr_assocreq_t  *f );
-void wlan_mgmt_decode_assocreq( wlan_fr_assocreq_t  *f );
-void wlan_mgmt_encode_assocresp( wlan_fr_assocresp_t  *f );
-void wlan_mgmt_decode_assocresp( wlan_fr_assocresp_t  *f );
-void wlan_mgmt_encode_reassocreq( wlan_fr_reassocreq_t  *f );
-void wlan_mgmt_decode_reassocreq( wlan_fr_reassocreq_t  *f );
-void wlan_mgmt_encode_reassocresp( wlan_fr_reassocresp_t  *f );
-void wlan_mgmt_decode_reassocresp( wlan_fr_reassocresp_t  *f );
-void wlan_mgmt_encode_probereq( wlan_fr_probereq_t  *f );
-void wlan_mgmt_decode_probereq( wlan_fr_probereq_t  *f );
-void wlan_mgmt_encode_proberesp( wlan_fr_proberesp_t  *f );
-void wlan_mgmt_decode_proberesp( wlan_fr_proberesp_t  *f );
-void wlan_mgmt_encode_authen( wlan_fr_authen_t  *f );
-void wlan_mgmt_decode_authen( wlan_fr_authen_t  *f );
-void wlan_mgmt_encode_deauthen( wlan_fr_deauthen_t  *f );
-void wlan_mgmt_decode_deauthen( wlan_fr_deauthen_t  *f );
-
+void wlan_mgmt_encode_beacon(wlan_fr_beacon_t *f);
+void wlan_mgmt_decode_beacon(wlan_fr_beacon_t *f);
+void wlan_mgmt_encode_disassoc(wlan_fr_disassoc_t *f);
+void wlan_mgmt_decode_disassoc(wlan_fr_disassoc_t *f);
+void wlan_mgmt_encode_assocreq(wlan_fr_assocreq_t *f);
+void wlan_mgmt_decode_assocreq(wlan_fr_assocreq_t *f);
+void wlan_mgmt_encode_assocresp(wlan_fr_assocresp_t *f);
+void wlan_mgmt_decode_assocresp(wlan_fr_assocresp_t *f);
+void wlan_mgmt_encode_reassocreq(wlan_fr_reassocreq_t *f);
+void wlan_mgmt_decode_reassocreq(wlan_fr_reassocreq_t *f);
+void wlan_mgmt_encode_reassocresp(wlan_fr_reassocresp_t *f);
+void wlan_mgmt_decode_reassocresp(wlan_fr_reassocresp_t *f);
+void wlan_mgmt_encode_probereq(wlan_fr_probereq_t *f);
+void wlan_mgmt_decode_probereq(wlan_fr_probereq_t *f);
+void wlan_mgmt_encode_proberesp(wlan_fr_proberesp_t *f);
+void wlan_mgmt_decode_proberesp(wlan_fr_proberesp_t *f);
+void wlan_mgmt_encode_authen(wlan_fr_authen_t *f);
+void wlan_mgmt_decode_authen(wlan_fr_authen_t *f);
+void wlan_mgmt_encode_deauthen(wlan_fr_deauthen_t *f);
+void wlan_mgmt_decode_deauthen(wlan_fr_deauthen_t *f);
 
 #endif /* _P80211MGMT_H */
diff --git a/drivers/staging/wlan-ng/p80211msg.h b/drivers/staging/wlan-ng/p80211msg.h
index 3a575d8..f15a5d9 100644
--- a/drivers/staging/wlan-ng/p80211msg.h
+++ b/drivers/staging/wlan-ng/p80211msg.h
@@ -49,54 +49,18 @@
 #define _P80211MSG_H
 
 /*================================================================*/
-/* System Includes */
-
-/*================================================================*/
 /* Project Includes */
 
-#ifndef _WLAN_COMPAT_H
-#include "wlan_compat.h"
-#endif
 
-/*================================================================*/
-/* Constants */
-
-#define MSG_BUFF_LEN		4000
 #define WLAN_DEVNAMELEN_MAX	16
 
-/*================================================================*/
-/* Macros */
-
-/*================================================================*/
-/* Types */
-
-/*--------------------------------------------------------------------*/
-/*----- Message Structure Types --------------------------------------*/
-
 /*--------------------------------------------------------------------*/
 /* Prototype msg type */
 
-typedef struct p80211msg
-{
-	u32	msgcode;
-	u32	msglen;
-	u8	devname[WLAN_DEVNAMELEN_MAX];
-} __WLAN_ATTRIB_PACK__ p80211msg_t;
+typedef struct p80211msg {
+	u32 msgcode;
+	u32 msglen;
+	u8 devname[WLAN_DEVNAMELEN_MAX];
+} __attribute__ ((packed)) p80211msg_t;
 
-typedef struct p80211msgd
-{
-	u32	msgcode;
-	u32	msglen;
-	u8	devname[WLAN_DEVNAMELEN_MAX];
-	u8	args[0];
-} __WLAN_ATTRIB_PACK__ p80211msgd_t;
-
-/*================================================================*/
-/* Extern Declarations */
-
-
-/*================================================================*/
-/* Function Declarations */
-
-#endif  /* _P80211MSG_H */
-
+#endif /* _P80211MSG_H */
diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c
index 59e5ad1..b2a606a 100644
--- a/drivers/staging/wlan-ng/p80211netdev.c
+++ b/drivers/staging/wlan-ng/p80211netdev.c
@@ -49,13 +49,7 @@
 * --------------------------------------------------------------------
 */
 
-
-/*================================================================*/
-/* System Includes */
-
-
 #include <linux/version.h>
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -70,9 +64,10 @@
 #include <linux/wireless.h>
 #include <linux/sockios.h>
 #include <linux/etherdevice.h>
-
-#include <asm/bitops.h>
-#include <asm/uaccess.h>
+#include <linux/if_ether.h>
+#include <linux/byteorder/generic.h>
+#include <linux/bitops.h>
+#include <linux/uaccess.h>
 #include <asm/byteorder.h>
 
 #ifdef SIOCETHTOOL
@@ -85,7 +80,6 @@
 /*================================================================*/
 /* Project Includes */
 
-#include "wlan_compat.h"
 #include "p80211types.h"
 #include "p80211hdr.h"
 #include "p80211conv.h"
@@ -97,33 +91,22 @@
 #include "p80211metastruct.h"
 #include "p80211metadef.h"
 
-/*================================================================*/
-/* Local Constants */
-
-/*================================================================*/
-/* Local Macros */
-
-
-/*================================================================*/
-/* Local Types */
-
-/*================================================================*/
-/* Local Function Declarations */
-
 /* Support functions */
 static void p80211netdev_rx_bh(unsigned long arg);
 
 /* netdevice method functions */
-static int p80211knetdev_init( netdevice_t *netdev);
-static struct net_device_stats* p80211knetdev_get_stats(netdevice_t *netdev);
-static int p80211knetdev_open( netdevice_t *netdev);
-static int p80211knetdev_stop( netdevice_t *netdev );
-static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netdev);
+static int p80211knetdev_init(netdevice_t *netdev);
+static struct net_device_stats *p80211knetdev_get_stats(netdevice_t *netdev);
+static int p80211knetdev_open(netdevice_t *netdev);
+static int p80211knetdev_stop(netdevice_t *netdev);
+static int p80211knetdev_hard_start_xmit(struct sk_buff *skb,
+					 netdevice_t *netdev);
 static void p80211knetdev_set_multicast_list(netdevice_t *dev);
-static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd);
+static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr,
+				  int cmd);
 static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr);
 static void p80211knetdev_tx_timeout(netdevice_t *netdev);
-static int p80211_rx_typedrop( wlandevice_t *wlandev, u16 fc);
+static int p80211_rx_typedrop(wlandevice_t *wlandev, u16 fc);
 
 int wlan_watchdog = 5000;
 module_param(wlan_watchdog, int, 0644);
@@ -133,15 +116,6 @@
 module_param(wlan_wext_write, int, 0644);
 MODULE_PARM_DESC(wlan_wext_write, "enable write wireless extensions");
 
-#ifdef WLAN_INCLUDE_DEBUG
-int wlan_debug=0;
-module_param(wlan_debug, int, 0644);
-MODULE_PARM_DESC(wlan_debug, "p80211 debug level");
-#endif
-
-/*================================================================*/
-/* Function Definitions */
-
 /*----------------------------------------------------------------
 * p80211knetdev_init
 *
@@ -154,18 +128,15 @@
 * Returns:
 *	nothing
 ----------------------------------------------------------------*/
-static int p80211knetdev_init( netdevice_t *netdev)
+static int p80211knetdev_init(netdevice_t *netdev)
 {
-	DBFENTER;
 	/* Called in response to register_netdev */
 	/* This is usually the probe function, but the probe has */
 	/* already been done by the MSD and the create_kdev */
 	/* function.  All we do here is return success */
-	DBFEXIT;
 	return 0;
 }
 
-
 /*----------------------------------------------------------------
 * p80211knetdev_get_stats
 *
@@ -180,20 +151,16 @@
 * Returns:
 *	the address of the statistics structure
 ----------------------------------------------------------------*/
-static struct net_device_stats*
-p80211knetdev_get_stats(netdevice_t *netdev)
+static struct net_device_stats *p80211knetdev_get_stats(netdevice_t *netdev)
 {
-	wlandevice_t	*wlandev = netdev->ml_priv;
-	DBFENTER;
+	wlandevice_t *wlandev = netdev->ml_priv;
 
 	/* TODO: review the MIB stats for items that correspond to
-		linux stats */
+	   linux stats */
 
-	DBFEXIT;
 	return &(wlandev->linux_stats);
 }
 
-
 /*----------------------------------------------------------------
 * p80211knetdev_open
 *
@@ -208,22 +175,19 @@
 * Returns:
 *	zero on success, non-zero otherwise
 ----------------------------------------------------------------*/
-static int p80211knetdev_open( netdevice_t *netdev )
+static int p80211knetdev_open(netdevice_t *netdev)
 {
-	int 		result = 0; /* success */
-	wlandevice_t	*wlandev = netdev->ml_priv;
-
-	DBFENTER;
+	int result = 0;		/* success */
+	wlandevice_t *wlandev = netdev->ml_priv;
 
 	/* Check to make sure the MSD is running */
-	if ( wlandev->msdstate != WLAN_MSD_RUNNING ) {
+	if (wlandev->msdstate != WLAN_MSD_RUNNING)
 		return -ENODEV;
-	}
 
 	/* Tell the MSD to open */
-	if ( wlandev->open != NULL) {
+	if (wlandev->open != NULL) {
 		result = wlandev->open(wlandev);
-		if ( result == 0 ) {
+		if (result == 0) {
 			netif_start_queue(wlandev->netdev);
 			wlandev->state = WLAN_DEVICE_OPEN;
 		}
@@ -231,11 +195,9 @@
 		result = -EAGAIN;
 	}
 
-	DBFEXIT;
 	return result;
 }
 
-
 /*----------------------------------------------------------------
 * p80211knetdev_stop
 *
@@ -248,21 +210,17 @@
 * Returns:
 *	zero on success, non-zero otherwise
 ----------------------------------------------------------------*/
-static int p80211knetdev_stop( netdevice_t *netdev )
+static int p80211knetdev_stop(netdevice_t *netdev)
 {
-	int		result = 0;
-	wlandevice_t	*wlandev = netdev->ml_priv;
+	int result = 0;
+	wlandevice_t *wlandev = netdev->ml_priv;
 
-	DBFENTER;
-
-	if ( wlandev->close != NULL ) {
+	if (wlandev->close != NULL)
 		result = wlandev->close(wlandev);
-	}
 
 	netif_stop_queue(wlandev->netdev);
 	wlandev->state = WLAN_DEVICE_CLOSED;
 
-	DBFEXIT;
 	return result;
 }
 
@@ -279,17 +237,13 @@
 * Side effects:
 *
 ----------------------------------------------------------------*/
-void
-p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb )
+void p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb)
 {
-	DBFENTER;
-
 	/* Enqueue for post-irq processing */
 	skb_queue_tail(&wlandev->nsd_rxq, skb);
 
 	tasklet_schedule(&wlandev->rx_bh);
 
-        DBFEXIT;
 	return;
 }
 
@@ -310,19 +264,17 @@
 {
 	wlandevice_t *wlandev = (wlandevice_t *) arg;
 	struct sk_buff *skb = NULL;
-	netdevice_t     *dev = wlandev->netdev;
+	netdevice_t *dev = wlandev->netdev;
 	p80211_hdr_a3_t *hdr;
 	u16 fc;
 
-        DBFENTER;
-
 	/* Let's empty our our queue */
-	while ( (skb = skb_dequeue(&wlandev->nsd_rxq)) ) {
+	while ((skb = skb_dequeue(&wlandev->nsd_rxq))) {
 		if (wlandev->state == WLAN_DEVICE_OPEN) {
 
 			if (dev->type != ARPHRD_ETHER) {
 				/* RAW frame; we shouldn't convert it */
-				// XXX Append the Prism Header here instead.
+				/* XXX Append the Prism Header here instead. */
 
 				/* set up various data fields */
 				skb->dev = dev;
@@ -337,8 +289,8 @@
 				netif_rx_ni(skb);
 				continue;
 			} else {
-				hdr = (p80211_hdr_a3_t *)skb->data;
-				fc = ieee2host16(hdr->fc);
+				hdr = (p80211_hdr_a3_t *) skb->data;
+				fc = le16_to_cpu(hdr->fc);
 				if (p80211_rx_typedrop(wlandev, fc)) {
 					dev_kfree_skb(skb);
 					continue;
@@ -347,7 +299,9 @@
 				/* perform mcast filtering */
 				if (wlandev->netdev->flags & IFF_ALLMULTI) {
 					/* allow my local address through */
-					if (memcmp(hdr->a1, wlandev->netdev->dev_addr, WLAN_ADDR_LEN) != 0) {
+					if (memcmp
+					    (hdr->a1, wlandev->netdev->dev_addr,
+					     ETH_ALEN) != 0) {
 						/* but reject anything else that isn't multicast */
 						if (!(hdr->a1[0] & 0x01)) {
 							dev_kfree_skb(skb);
@@ -356,23 +310,22 @@
 					}
 				}
 
-				if ( skb_p80211_to_ether(wlandev, wlandev->ethconv, skb) == 0 ) {
+				if (skb_p80211_to_ether
+				    (wlandev, wlandev->ethconv, skb) == 0) {
 					skb->dev->last_rx = jiffies;
 					wlandev->linux_stats.rx_packets++;
-					wlandev->linux_stats.rx_bytes += skb->len;
+					wlandev->linux_stats.rx_bytes +=
+					    skb->len;
 					netif_rx_ni(skb);
 					continue;
 				}
-				WLAN_LOG_DEBUG(1, "p80211_to_ether failed.\n");
+				pr_debug("p80211_to_ether failed.\n");
 			}
 		}
 		dev_kfree_skb(skb);
 	}
-
-        DBFEXIT;
 }
 
-
 /*----------------------------------------------------------------
 * p80211knetdev_hard_start_xmit
 *
@@ -392,21 +345,19 @@
 * Returns:
 *	zero on success, non-zero on failure.
 ----------------------------------------------------------------*/
-static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netdev)
+static int p80211knetdev_hard_start_xmit(struct sk_buff *skb,
+					 netdevice_t *netdev)
 {
-	int		result = 0;
-	int		txresult = -1;
-	wlandevice_t	*wlandev = netdev->ml_priv;
-	p80211_hdr_t    p80211_hdr;
+	int result = 0;
+	int txresult = -1;
+	wlandevice_t *wlandev = netdev->ml_priv;
+	p80211_hdr_t p80211_hdr;
 	p80211_metawep_t p80211_wep;
 
-	DBFENTER;
-
-	if (skb == NULL) {
+	if (skb == NULL)
 		return 0;
-	}
 
-        if (wlandev->state != WLAN_DEVICE_OPEN) {
+	if (wlandev->state != WLAN_DEVICE_OPEN) {
 		result = 1;
 		goto failed;
 	}
@@ -414,8 +365,8 @@
 	memset(&p80211_hdr, 0, sizeof(p80211_hdr_t));
 	memset(&p80211_wep, 0, sizeof(p80211_metawep_t));
 
-	if ( netif_queue_stopped(netdev) ) {
-		WLAN_LOG_DEBUG(1, "called when queue stopped.\n");
+	if (netif_queue_stopped(netdev)) {
+		pr_debug("called when queue stopped.\n");
 		result = 1;
 		goto failed;
 	}
@@ -423,7 +374,7 @@
 	netif_stop_queue(netdev);
 
 	/* Check to see that a valid mode is set */
-	switch( wlandev->macmode ) {
+	switch (wlandev->macmode) {
 	case WLAN_MACMODE_IBSS_STA:
 	case WLAN_MACMODE_ESS_STA:
 	case WLAN_MACMODE_ESS_AP:
@@ -433,10 +384,10 @@
 		 * and return success .
 		 * TODO: we need a saner way to handle this
 		 */
-		if(skb->protocol != ETH_P_80211_RAW) {
+		if (skb->protocol != ETH_P_80211_RAW) {
 			netif_start_queue(wlandev->netdev);
-			WLAN_LOG_NOTICE(
-				"Tx attempt prior to association, frame dropped.\n");
+			printk(KERN_NOTICE
+			       "Tx attempt prior to association, frame dropped.\n");
 			wlandev->linux_stats.tx_dropped++;
 			result = 0;
 			goto failed;
@@ -445,7 +396,7 @@
 	}
 
 	/* Check for raw transmits */
-	if(skb->protocol == ETH_P_80211_RAW) {
+	if (skb->protocol == ETH_P_80211_RAW) {
 		if (!capable(CAP_NET_ADMIN)) {
 			result = 1;
 			goto failed;
@@ -454,15 +405,17 @@
 		memcpy(&p80211_hdr, skb->data, sizeof(p80211_hdr_t));
 		skb_pull(skb, sizeof(p80211_hdr_t));
 	} else {
-		if ( skb_ether_to_p80211(wlandev, wlandev->ethconv, skb, &p80211_hdr, &p80211_wep) != 0 ) {
+		if (skb_ether_to_p80211
+		    (wlandev, wlandev->ethconv, skb, &p80211_hdr,
+		     &p80211_wep) != 0) {
 			/* convert failed */
-			WLAN_LOG_DEBUG(1, "ether_to_80211(%d) failed.\n",
-					wlandev->ethconv);
+			pr_debug("ether_to_80211(%d) failed.\n",
+			       wlandev->ethconv);
 			result = 1;
 			goto failed;
 		}
 	}
-	if ( wlandev->txframe == NULL ) {
+	if (wlandev->txframe == NULL) {
 		result = 1;
 		goto failed;
 	}
@@ -475,28 +428,28 @@
 
 	txresult = wlandev->txframe(wlandev, skb, &p80211_hdr, &p80211_wep);
 
-	if ( txresult == 0) {
+	if (txresult == 0) {
 		/* success and more buf */
 		/* avail, re: hw_txdata */
 		netif_wake_queue(wlandev->netdev);
 		result = 0;
-	} else if ( txresult == 1 ) {
+	} else if (txresult == 1) {
 		/* success, no more avail */
-		WLAN_LOG_DEBUG(3, "txframe success, no more bufs\n");
+		pr_debug("txframe success, no more bufs\n");
 		/* netdev->tbusy = 1;  don't set here, irqhdlr */
 		/*   may have already cleared it */
 		result = 0;
-	} else if ( txresult == 2 ) {
+	} else if (txresult == 2) {
 		/* alloc failure, drop frame */
-		WLAN_LOG_DEBUG(3, "txframe returned alloc_fail\n");
+		pr_debug("txframe returned alloc_fail\n");
 		result = 1;
 	} else {
 		/* buffer full or queue busy, drop frame. */
-		WLAN_LOG_DEBUG(3, "txframe returned full or busy\n");
+		pr_debug("txframe returned full or busy\n");
 		result = 1;
 	}
 
- failed:
+failed:
 	/* Free up the WEP buffer if it's not the same as the skb */
 	if ((p80211_wep.data) && (p80211_wep.data != skb->data))
 		kfree(p80211_wep.data);
@@ -505,11 +458,9 @@
 	if (!result)
 		dev_kfree_skb(skb);
 
-	DBFEXIT;
 	return result;
 }
 
-
 /*----------------------------------------------------------------
 * p80211knetdev_set_multicast_list
 *
@@ -524,16 +475,13 @@
 ----------------------------------------------------------------*/
 static void p80211knetdev_set_multicast_list(netdevice_t *dev)
 {
-	wlandevice_t	*wlandev = dev->ml_priv;
-
-	DBFENTER;
+	wlandevice_t *wlandev = dev->ml_priv;
 
 	/* TODO:  real multicast support as well */
 
 	if (wlandev->set_multicast_list)
 		wlandev->set_multicast_list(wlandev, dev);
 
-	DBFEXIT;
 }
 
 #ifdef SIOCETHTOOL
@@ -558,9 +506,6 @@
 		snprintf(info.version, sizeof(info.version), "%s",
 			 WLAN_RELEASE);
 
-		// info.fw_version
-		// info.bus_info
-
 		if (copy_to_user(useraddr, &info, sizeof(info)))
 			return -EFAULT;
 		return 0;
@@ -576,7 +521,7 @@
 		}
 
 		if (copy_to_user(useraddr, &edata, sizeof(edata)))
-                        return -EFAULT;
+			return -EFAULT;
 		return 0;
 	}
 #endif
@@ -615,45 +560,47 @@
 ----------------------------------------------------------------*/
 static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd)
 {
-	int			result = 0;
-	p80211ioctl_req_t	*req = (p80211ioctl_req_t*)ifr;
-	wlandevice_t		*wlandev = dev->ml_priv;
-	u8			*msgbuf;
-	DBFENTER;
+	int result = 0;
+	p80211ioctl_req_t *req = (p80211ioctl_req_t *) ifr;
+	wlandevice_t *wlandev = dev->ml_priv;
+	u8 *msgbuf;
 
-	WLAN_LOG_DEBUG(2, "rx'd ioctl, cmd=%d, len=%d\n", cmd, req->len);
+	pr_debug("rx'd ioctl, cmd=%d, len=%d\n", cmd, req->len);
+
+	mutex_lock(&wlandev->ioctl_lock);
 
 #ifdef SIOCETHTOOL
 	if (cmd == SIOCETHTOOL) {
-		result = p80211netdev_ethtool(wlandev, (void __user *) ifr->ifr_data);
+		result =
+		    p80211netdev_ethtool(wlandev, (void __user *)ifr->ifr_data);
 		goto bail;
 	}
 #endif
 
 	/* Test the magic, assume ifr is good if it's there */
-	if ( req->magic != P80211_IOCTL_MAGIC ) {
+	if (req->magic != P80211_IOCTL_MAGIC) {
 		result = -ENOSYS;
 		goto bail;
 	}
 
-	if ( cmd == P80211_IFTEST ) {
+	if (cmd == P80211_IFTEST) {
 		result = 0;
 		goto bail;
-	} else if ( cmd != P80211_IFREQ ) {
+	} else if (cmd != P80211_IFREQ) {
 		result = -ENOSYS;
 		goto bail;
 	}
 
 	/* Allocate a buf of size req->len */
-	if ((msgbuf = kmalloc( req->len, GFP_KERNEL))) {
-		if ( copy_from_user( msgbuf, (void __user *) req->data, req->len) ) {
+	if ((msgbuf = kmalloc(req->len, GFP_KERNEL))) {
+		if (copy_from_user(msgbuf, (void __user *)req->data, req->len))
 			result = -EFAULT;
-		} else {
-			result = p80211req_dorequest( wlandev, msgbuf);
-		}
+		else
+			result = p80211req_dorequest(wlandev, msgbuf);
 
-		if ( result == 0 ) {
-			if ( copy_to_user( (void __user *) req->data, msgbuf, req->len)) {
+		if (result == 0) {
+			if (copy_to_user
+			    ((void __user *)req->data, msgbuf, req->len)) {
 				result = -EFAULT;
 			}
 		}
@@ -662,9 +609,9 @@
 		result = -ENOMEM;
 	}
 bail:
-	DBFEXIT;
+	mutex_unlock(&wlandev->ioctl_lock);
 
-	return result; /* If allocate,copyfrom or copyto fails, return errno */
+	return result;		/* If allocate,copyfrom or copyto fails, return errno */
 }
 
 /*----------------------------------------------------------------
@@ -694,22 +641,20 @@
 ----------------------------------------------------------------*/
 static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr)
 {
-	struct sockaddr			*new_addr = addr;
-	p80211msg_dot11req_mibset_t	dot11req;
-	p80211item_unk392_t		*mibattr;
-	p80211item_pstr6_t		*macaddr;
-	p80211item_uint32_t		*resultcode;
+	struct sockaddr *new_addr = addr;
+	p80211msg_dot11req_mibset_t dot11req;
+	p80211item_unk392_t *mibattr;
+	p80211item_pstr6_t *macaddr;
+	p80211item_uint32_t *resultcode;
 	int result = 0;
 
-	DBFENTER;
 	/* If we're running, we don't allow MAC address changes */
-	if (netif_running(dev)) {
+	if (netif_running(dev))
 		return -EBUSY;
-	}
 
 	/* Set up some convenience pointers. */
 	mibattr = &dot11req.mibattribute;
-	macaddr = (p80211item_pstr6_t*)&mibattr->data;
+	macaddr = (p80211item_pstr6_t *)&mibattr->data;
 	resultcode = &dot11req.resultcode;
 
 	/* Set up a dot11req_mibset */
@@ -717,8 +662,7 @@
 	dot11req.msgcode = DIDmsg_dot11req_mibset;
 	dot11req.msglen = sizeof(p80211msg_dot11req_mibset_t);
 	memcpy(dot11req.devname,
-		((wlandevice_t *)dev->ml_priv)->name,
-		WLAN_DEVNAMELEN_MAX - 1);
+	       ((wlandevice_t *) dev->ml_priv)->name, WLAN_DEVNAMELEN_MAX - 1);
 
 	/* Set up the mibattribute argument */
 	mibattr->did = DIDmsg_dot11req_mibset_mibattribute;
@@ -728,8 +672,8 @@
 	macaddr->did = DIDmib_dot11mac_dot11OperationTable_dot11MACAddress;
 	macaddr->status = P80211ENUM_msgitem_status_data_ok;
 	macaddr->len = sizeof(macaddr->data);
-	macaddr->data.len = WLAN_ADDR_LEN;
-	memcpy(&macaddr->data.data, new_addr->sa_data, WLAN_ADDR_LEN);
+	macaddr->data.len = ETH_ALEN;
+	memcpy(&macaddr->data.data, new_addr->sa_data, ETH_ALEN);
 
 	/* Set up the resultcode argument */
 	resultcode->did = DIDmsg_dot11req_mibset_resultcode;
@@ -743,36 +687,30 @@
 	/* If the request wasn't successful, report an error and don't
 	 * change the netdev address
 	 */
-	if ( result != 0 || resultcode->data != P80211ENUM_resultcode_success) {
-		WLAN_LOG_ERROR(
-		"Low-level driver failed dot11req_mibset(dot11MACAddress).\n");
+	if (result != 0 || resultcode->data != P80211ENUM_resultcode_success) {
+		printk(KERN_ERR
+		       "Low-level driver failed dot11req_mibset(dot11MACAddress).\n");
 		result = -EADDRNOTAVAIL;
 	} else {
 		/* everything's ok, change the addr in netdev */
 		memcpy(dev->dev_addr, new_addr->sa_data, dev->addr_len);
 	}
 
-	DBFEXIT;
 	return result;
 }
 
 static int wlan_change_mtu(netdevice_t *dev, int new_mtu)
 {
-	DBFENTER;
-	// 2312 is max 802.11 payload, 20 is overhead, (ether + llc +snap)
-	// and another 8 for wep.
-        if ( (new_mtu < 68) || (new_mtu > (2312 - 20 - 8)))
-                return -EINVAL;
+	/* 2312 is max 802.11 payload, 20 is overhead, (ether + llc +snap)
+	   and another 8 for wep. */
+	if ((new_mtu < 68) || (new_mtu > (2312 - 20 - 8)))
+		return -EINVAL;
 
-        dev->mtu = new_mtu;
+	dev->mtu = new_mtu;
 
-	DBFEXIT;
-
-        return 0;
+	return 0;
 }
 
-
-
 /*----------------------------------------------------------------
 * wlan_setup
 *
@@ -797,10 +735,8 @@
 ----------------------------------------------------------------*/
 int wlan_setup(wlandevice_t *wlandev)
 {
-	int		result = 0;
-	netdevice_t	*dev;
-
-	DBFENTER;
+	int result = 0;
+	netdevice_t *dev;
 
 	/* Set up the wlandev */
 	wlandev->state = WLAN_DEVICE_CLOSED;
@@ -810,28 +746,26 @@
 	/* Set up the rx queue */
 	skb_queue_head_init(&wlandev->nsd_rxq);
 	tasklet_init(&wlandev->rx_bh,
-		     p80211netdev_rx_bh,
-		     (unsigned long)wlandev);
+		     p80211netdev_rx_bh, (unsigned long)wlandev);
 
 	/* Allocate and initialize the struct device */
-	dev = alloc_netdev(0,"wlan%d",ether_setup);
-	if ( dev == NULL ) {
-		WLAN_LOG_ERROR("Failed to alloc netdev.\n");
+	dev = alloc_netdev(0, "wlan%d", ether_setup);
+	if (dev == NULL) {
+		printk(KERN_ERR "Failed to alloc netdev.\n");
 		result = 1;
 	} else {
 		wlandev->netdev = dev;
 		dev->ml_priv = wlandev;
-		dev->hard_start_xmit =	p80211knetdev_hard_start_xmit;
-		dev->get_stats =	p80211knetdev_get_stats;
-#ifdef HAVE_PRIVATE_IOCTL
-		dev->do_ioctl = 	p80211knetdev_do_ioctl;
-#endif
-#ifdef HAVE_MULTICAST
-		dev->set_multicast_list = p80211knetdev_set_multicast_list;
-#endif
-		dev->init =		p80211knetdev_init;
-		dev->open =		p80211knetdev_open;
-		dev->stop =		p80211knetdev_stop;
+		dev->hard_start_xmit = p80211knetdev_hard_start_xmit;
+		dev->get_stats = p80211knetdev_get_stats;
+		dev->init = p80211knetdev_init;
+		dev->open = p80211knetdev_open;
+		dev->stop = p80211knetdev_stop;
+
+		mutex_init(&wlandev->ioctl_lock);
+		/* block ioctls until fully initialised. Don't forget to call
+		   allow_ioctls at some point!*/
+		mutex_lock(&wlandev->ioctl_lock);
 
 #if (WIRELESS_EXT < 21)
 		dev->get_wireless_stats = p80211wext_get_wireless_stats;
@@ -839,20 +773,9 @@
 		dev->wireless_handlers = &p80211wext_handler_def;
 
 		netif_stop_queue(dev);
-#ifdef HAVE_CHANGE_MTU
-		dev->change_mtu = wlan_change_mtu;
-#endif
-#ifdef HAVE_SET_MAC_ADDR
-		dev->set_mac_address =	p80211knetdev_set_mac_address;
-#endif
-#ifdef HAVE_TX_TIMEOUT
-		dev->tx_timeout      =  &p80211knetdev_tx_timeout;
-		dev->watchdog_timeo  =  (wlan_watchdog * HZ) / 1000;
-#endif
 		netif_carrier_off(dev);
 	}
 
-	DBFEXIT;
 	return result;
 }
 
@@ -879,26 +802,21 @@
 ----------------------------------------------------------------*/
 int wlan_unsetup(wlandevice_t *wlandev)
 {
-	int		result = 0;
-
-	DBFENTER;
+	int result = 0;
 
 	tasklet_kill(&wlandev->rx_bh);
 
-	if (wlandev->netdev == NULL ) {
-		WLAN_LOG_ERROR("called without wlandev->netdev set.\n");
+	if (wlandev->netdev == NULL) {
+		printk(KERN_ERR "called without wlandev->netdev set.\n");
 		result = 1;
 	} else {
 		free_netdev(wlandev->netdev);
 		wlandev->netdev = NULL;
 	}
 
-	DBFEXIT;
 	return 0;
 }
 
-
-
 /*----------------------------------------------------------------
 * register_wlandev
 *
@@ -920,19 +838,15 @@
 ----------------------------------------------------------------*/
 int register_wlandev(wlandevice_t *wlandev)
 {
-	int		i = 0;
-
-	DBFENTER;
+	int i = 0;
 
 	i = register_netdev(wlandev->netdev);
 	if (i)
 		return i;
 
-	DBFEXIT;
 	return 0;
 }
 
-
 /*----------------------------------------------------------------
 * unregister_wlandev
 *
@@ -954,20 +868,15 @@
 {
 	struct sk_buff *skb;
 
-	DBFENTER;
-
 	unregister_netdev(wlandev->netdev);
 
 	/* Now to clean out the rx queue */
-	while ( (skb = skb_dequeue(&wlandev->nsd_rxq)) ) {
+	while ((skb = skb_dequeue(&wlandev->nsd_rxq)))
 		dev_kfree_skb(skb);
-	}
 
-	DBFEXIT;
 	return 0;
 }
 
-
 /*----------------------------------------------------------------
 * p80211netdev_hwremoved
 *
@@ -1000,18 +909,13 @@
 ----------------------------------------------------------------*/
 void p80211netdev_hwremoved(wlandevice_t *wlandev)
 {
-	DBFENTER;
 	wlandev->hwremoved = 1;
-	if ( wlandev->state == WLAN_DEVICE_OPEN) {
+	if (wlandev->state == WLAN_DEVICE_OPEN)
 		netif_stop_queue(wlandev->netdev);
-	}
 
 	netif_device_detach(wlandev->netdev);
-
-	DBFEXIT;
 }
 
-
 /*----------------------------------------------------------------
 * p80211_rx_typedrop
 *
@@ -1033,28 +937,27 @@
 * Call context:
 *	interrupt
 ----------------------------------------------------------------*/
-static int p80211_rx_typedrop( wlandevice_t *wlandev, u16 fc)
+static int p80211_rx_typedrop(wlandevice_t *wlandev, u16 fc)
 {
-	u16	ftype;
-	u16	fstype;
-	int	drop = 0;
+	u16 ftype;
+	u16 fstype;
+	int drop = 0;
 	/* Classify frame, increment counter */
 	ftype = WLAN_GET_FC_FTYPE(fc);
 	fstype = WLAN_GET_FC_FSTYPE(fc);
 #if 0
-	WLAN_LOG_DEBUG(4,
-		"rx_typedrop : ftype=%d fstype=%d.\n", ftype, fstype);
+	pr_debug("rx_typedrop : ftype=%d fstype=%d.\n", ftype, fstype);
 #endif
-	switch ( ftype ) {
+	switch (ftype) {
 	case WLAN_FTYPE_MGMT:
 		if ((wlandev->netdev->flags & IFF_PROMISC) ||
-			(wlandev->netdev->flags & IFF_ALLMULTI)) {
+		    (wlandev->netdev->flags & IFF_ALLMULTI)) {
 			drop = 1;
 			break;
 		}
-		WLAN_LOG_DEBUG(3, "rx'd mgmt:\n");
+		pr_debug("rx'd mgmt:\n");
 		wlandev->rx.mgmt++;
-		switch( fstype ) {
+		switch (fstype) {
 		case WLAN_FSTYPE_ASSOCREQ:
 			/* printk("assocreq"); */
 			wlandev->rx.assocreq++;
@@ -1110,13 +1013,13 @@
 
 	case WLAN_FTYPE_CTL:
 		if ((wlandev->netdev->flags & IFF_PROMISC) ||
-			(wlandev->netdev->flags & IFF_ALLMULTI)) {
+		    (wlandev->netdev->flags & IFF_ALLMULTI)) {
 			drop = 1;
 			break;
 		}
-		WLAN_LOG_DEBUG(3, "rx'd ctl:\n");
+		pr_debug("rx'd ctl:\n");
 		wlandev->rx.ctl++;
-		switch( fstype ) {
+		switch (fstype) {
 		case WLAN_FSTYPE_PSPOLL:
 			/* printk("pspoll"); */
 			wlandev->rx.pspoll++;
@@ -1152,7 +1055,7 @@
 
 	case WLAN_FTYPE_DATA:
 		wlandev->rx.data++;
-		switch( fstype ) {
+		switch (fstype) {
 		case WLAN_FSTYPE_DATAONLY:
 			wlandev->rx.dataonly++;
 			break;
@@ -1166,19 +1069,19 @@
 			wlandev->rx.data__cfack_cfpoll++;
 			break;
 		case WLAN_FSTYPE_NULL:
-			WLAN_LOG_DEBUG(3, "rx'd data:null\n");
+			pr_debug("rx'd data:null\n");
 			wlandev->rx.null++;
 			break;
 		case WLAN_FSTYPE_CFACK:
-			WLAN_LOG_DEBUG(3, "rx'd data:cfack\n");
+			pr_debug("rx'd data:cfack\n");
 			wlandev->rx.cfack++;
 			break;
 		case WLAN_FSTYPE_CFPOLL:
-			WLAN_LOG_DEBUG(3, "rx'd data:cfpoll\n");
+			pr_debug("rx'd data:cfpoll\n");
 			wlandev->rx.cfpoll++;
 			break;
 		case WLAN_FSTYPE_CFACK_CFPOLL:
-			WLAN_LOG_DEBUG(3, "rx'd data:cfack_cfpoll\n");
+			pr_debug("rx'd data:cfack_cfpoll\n");
 			wlandev->rx.cfack_cfpoll++;
 			break;
 		default:
@@ -1192,18 +1095,20 @@
 	return drop;
 }
 
-static void p80211knetdev_tx_timeout( netdevice_t *netdev)
+static void p80211knetdev_tx_timeout(netdevice_t *netdev)
 {
-	wlandevice_t	*wlandev = netdev->ml_priv;
-	DBFENTER;
+	wlandevice_t *wlandev = netdev->ml_priv;
 
 	if (wlandev->tx_timeout) {
 		wlandev->tx_timeout(wlandev);
 	} else {
-		WLAN_LOG_WARNING("Implement tx_timeout for %s\n",
-				 wlandev->nsdname);
+		printk(KERN_WARNING "Implement tx_timeout for %s\n",
+		       wlandev->nsdname);
 		netif_wake_queue(wlandev->netdev);
 	}
+}
 
-	DBFEXIT;
+void p80211_allow_ioctls(wlandevice_t *wlandev)
+{
+	mutex_unlock(&wlandev->ioctl_lock);
 }
diff --git a/drivers/staging/wlan-ng/p80211netdev.h b/drivers/staging/wlan-ng/p80211netdev.h
index 940146f..b96090d 100644
--- a/drivers/staging/wlan-ng/p80211netdev.h
+++ b/drivers/staging/wlan-ng/p80211netdev.h
@@ -55,10 +55,16 @@
 
 #include <linux/interrupt.h>
 #include <linux/wireless.h>
+#include <linux/netdevice.h>
 
 /*================================================================*/
 /* Constants */
 
+#undef netdevice_t
+typedef struct net_device netdevice_t;
+
+#define WLAN_RELEASE	"0.3.0-staging"
+
 #define WLAN_DEVICE_CLOSED	0
 #define WLAN_DEVICE_OPEN	1
 
@@ -68,8 +74,6 @@
 #define WLAN_MACMODE_ESS_AP	3
 
 /* MSD States */
-#define WLAN_MSD_START			-1
-#define WLAN_MSD_DRIVERLOADED		0
 #define WLAN_MSD_HWPRESENT_PENDING	1
 #define WLAN_MSD_HWFAIL			2
 #define WLAN_MSD_HWPRESENT		3
@@ -79,79 +83,66 @@
 #define WLAN_MSD_RUNNING		7
 
 #ifndef ETH_P_ECONET
-#define ETH_P_ECONET   0x0018    /* needed for 2.2.x kernels */
+#define ETH_P_ECONET   0x0018	/* needed for 2.2.x kernels */
 #endif
 
 #define ETH_P_80211_RAW        (ETH_P_ECONET + 1)
 
 #ifndef ARPHRD_IEEE80211
-#define ARPHRD_IEEE80211 801     /* kernel 2.4.6 */
+#define ARPHRD_IEEE80211 801	/* kernel 2.4.6 */
 #endif
 
-#ifndef ARPHRD_IEEE80211_PRISM  /* kernel 2.4.18 */
+#ifndef ARPHRD_IEEE80211_PRISM	/* kernel 2.4.18 */
 #define ARPHRD_IEEE80211_PRISM 802
 #endif
 
 /*--- NSD Capabilities Flags ------------------------------*/
-#define P80211_NSDCAP_HARDWAREWEP           0x01  /* hardware wep engine */
-#define P80211_NSDCAP_TIEDWEP               0x02  /* can't decouple en/de */
-#define P80211_NSDCAP_NOHOSTWEP             0x04  /* must use hardware wep */
-#define P80211_NSDCAP_PBCC                  0x08  /* hardware supports PBCC */
-#define P80211_NSDCAP_SHORT_PREAMBLE        0x10  /* hardware supports */
-#define P80211_NSDCAP_AGILITY               0x20  /* hardware supports */
-#define P80211_NSDCAP_AP_RETRANSMIT         0x40  /* nsd handles retransmits */
-#define P80211_NSDCAP_HWFRAGMENT            0x80  /* nsd handles frag/defrag */
-#define P80211_NSDCAP_AUTOJOIN              0x100  /* nsd does autojoin */
-#define P80211_NSDCAP_NOSCAN                0x200  /* nsd can scan */
-
-/*================================================================*/
-/* Macros */
-
-/*================================================================*/
-/* Types */
+#define P80211_NSDCAP_HARDWAREWEP           0x01	/* hardware wep engine */
+#define P80211_NSDCAP_SHORT_PREAMBLE        0x10	/* hardware supports */
+#define P80211_NSDCAP_HWFRAGMENT            0x80	/* nsd handles frag/defrag */
+#define P80211_NSDCAP_AUTOJOIN              0x100	/* nsd does autojoin */
+#define P80211_NSDCAP_NOSCAN                0x200	/* nsd can scan */
 
 /* Received frame statistics */
-typedef struct p80211_frmrx_t
-{
-	u32	mgmt;
-	u32	assocreq;
-	u32	assocresp;
-	u32	reassocreq;
-	u32	reassocresp;
-	u32	probereq;
-	u32	proberesp;
-	u32	beacon;
-	u32	atim;
-	u32	disassoc;
-	u32	authen;
-	u32	deauthen;
-	u32	mgmt_unknown;
-	u32	ctl;
-	u32	pspoll;
-	u32	rts;
-	u32	cts;
-	u32	ack;
-	u32	cfend;
-	u32	cfendcfack;
-	u32	ctl_unknown;
-	u32	data;
-	u32	dataonly;
-	u32	data_cfack;
-	u32	data_cfpoll;
-	u32	data__cfack_cfpoll;
-	u32	null;
-	u32	cfack;
-	u32	cfpoll;
-	u32	cfack_cfpoll;
-	u32	data_unknown;
-	u32  decrypt;
-	u32  decrypt_err;
+typedef struct p80211_frmrx_t {
+	u32 mgmt;
+	u32 assocreq;
+	u32 assocresp;
+	u32 reassocreq;
+	u32 reassocresp;
+	u32 probereq;
+	u32 proberesp;
+	u32 beacon;
+	u32 atim;
+	u32 disassoc;
+	u32 authen;
+	u32 deauthen;
+	u32 mgmt_unknown;
+	u32 ctl;
+	u32 pspoll;
+	u32 rts;
+	u32 cts;
+	u32 ack;
+	u32 cfend;
+	u32 cfendcfack;
+	u32 ctl_unknown;
+	u32 data;
+	u32 dataonly;
+	u32 data_cfack;
+	u32 data_cfpoll;
+	u32 data__cfack_cfpoll;
+	u32 null;
+	u32 cfack;
+	u32 cfpoll;
+	u32 cfack_cfpoll;
+	u32 data_unknown;
+	u32 decrypt;
+	u32 decrypt_err;
 } p80211_frmrx_t;
 
 /* called by /proc/net/wireless */
-struct iw_statistics* p80211wext_get_wireless_stats(netdevice_t *dev);
+struct iw_statistics *p80211wext_get_wireless_stats(netdevice_t * dev);
 /* wireless extensions' ioctls */
-int p80211wext_support_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd);
 extern struct iw_handler_def p80211wext_handler_def;
 int p80211wext_event_associated(struct wlandevice *wlandev, int assoc);
 
@@ -159,96 +150,99 @@
 #define NUM_WEPKEYS 4
 #define MAX_KEYLEN 32
 
-#define HOSTWEP_DEFAULTKEY_MASK (BIT1|BIT0)
-#define HOSTWEP_DECRYPT  BIT4
-#define HOSTWEP_ENCRYPT  BIT5
-#define HOSTWEP_PRIVACYINVOKED BIT6
-#define HOSTWEP_EXCLUDEUNENCRYPTED BIT7
+#define HOSTWEP_DEFAULTKEY_MASK (BIT(1)|BIT(0))
+#define HOSTWEP_DECRYPT  BIT(4)
+#define HOSTWEP_ENCRYPT  BIT(5)
+#define HOSTWEP_PRIVACYINVOKED BIT(6)
+#define HOSTWEP_EXCLUDEUNENCRYPTED BIT(7)
 
 extern int wlan_watchdog;
 extern int wlan_wext_write;
 
 /* WLAN device type */
-typedef struct wlandevice
-{
-	struct wlandevice	*next;		/* link for list of devices */
-	void			*priv;		/* private data for MSD */
+typedef struct wlandevice {
+	struct wlandevice *next;	/* link for list of devices */
+	void *priv;		/* private data for MSD */
 
 	/* Subsystem State */
-	char		name[WLAN_DEVNAMELEN_MAX]; /* Dev name, from register_wlandev()*/
-	char		*nsdname;
+	char name[WLAN_DEVNAMELEN_MAX];	/* Dev name, from register_wlandev() */
+	char *nsdname;
 
-	u32          state;          /* Device I/F state (open/closed) */
-	u32		msdstate;	/* state of underlying driver */
-	u32		hwremoved;	/* Has the hw been yanked out? */
+	u32 state;		/* Device I/F state (open/closed) */
+	u32 msdstate;		/* state of underlying driver */
+	u32 hwremoved;		/* Has the hw been yanked out? */
 
 	/* Hardware config */
-	unsigned int		irq;
-	unsigned int		iobase;
-	unsigned int		membase;
-	u32          nsdcaps;  /* NSD Capabilities flags */
+	unsigned int irq;
+	unsigned int iobase;
+	unsigned int membase;
+	u32 nsdcaps;		/* NSD Capabilities flags */
 
 	/* Config vars */
-	unsigned int		ethconv;
+	unsigned int ethconv;
 
 	/* device methods (init by MSD, used by p80211 */
-	int		(*open)(struct wlandevice *wlandev);
-	int		(*close)(struct wlandevice *wlandev);
-	void		(*reset)(struct wlandevice *wlandev );
-	int		(*txframe)(struct wlandevice *wlandev, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep);
-	int		(*mlmerequest)(struct wlandevice *wlandev, p80211msg_t *msg);
-	int             (*set_multicast_list)(struct wlandevice *wlandev,
-					      netdevice_t *dev);
-	void		(*tx_timeout)(struct wlandevice *wlandev);
+	int (*open) (struct wlandevice *wlandev);
+	int (*close) (struct wlandevice *wlandev);
+	void (*reset) (struct wlandevice *wlandev);
+	int (*txframe) (struct wlandevice *wlandev, struct sk_buff *skb,
+			p80211_hdr_t *p80211_hdr,
+			p80211_metawep_t *p80211_wep);
+	int (*mlmerequest) (struct wlandevice *wlandev, p80211msg_t *msg);
+	int (*set_multicast_list) (struct wlandevice *wlandev,
+				   netdevice_t *dev);
+	void (*tx_timeout) (struct wlandevice *wlandev);
 
 	/* 802.11 State */
-	u8		bssid[WLAN_BSSID_LEN];
-	p80211pstr32_t	ssid;
-	u32		macmode;
-	int             linkstatus;
+	u8 bssid[WLAN_BSSID_LEN];
+	p80211pstr32_t ssid;
+	u32 macmode;
+	int linkstatus;
 
 	/* WEP State */
 	u8 wep_keys[NUM_WEPKEYS][MAX_KEYLEN];
 	u8 wep_keylens[NUM_WEPKEYS];
-	int   hostwep;
+	int hostwep;
 
 	/* Request/Confirm i/f state (used by p80211) */
-	unsigned long		request_pending; /* flag, access atomically */
+	unsigned long request_pending;	/* flag, access atomically */
 
 	/* netlink socket */
 	/* queue for indications waiting for cmd completion */
 	/* Linux netdevice and support */
-	netdevice_t		*netdev;	/* ptr to linux netdevice */
+	netdevice_t *netdev;	/* ptr to linux netdevice */
 	struct net_device_stats linux_stats;
 
 	/* Rx bottom half */
-	struct tasklet_struct	rx_bh;
+	struct tasklet_struct rx_bh;
 
-	struct sk_buff_head	nsd_rxq;
+	struct sk_buff_head nsd_rxq;
 
 	/* 802.11 device statistics */
-	struct p80211_frmrx_t	rx;
+	struct p80211_frmrx_t rx;
 
-	struct iw_statistics	wstats;
+	struct iw_statistics wstats;
 
 	/* jkriegl: iwspy fields */
-        u8			spy_number;
-        char			spy_address[IW_MAX_SPY][ETH_ALEN];
-        struct iw_quality       spy_stat[IW_MAX_SPY];
+	u8 spy_number;
+	char spy_address[IW_MAX_SPY][ETH_ALEN];
+	struct iw_quality spy_stat[IW_MAX_SPY];
+
+	struct mutex ioctl_lock;
 } wlandevice_t;
 
 /* WEP stuff */
-int wep_change_key(wlandevice_t *wlandev, int keynum, u8* key, int keylen);
-int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override, u8 *iv, u8 *icv);
-int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum, u8 *iv, u8 *icv);
+int wep_change_key(wlandevice_t *wlandev, int keynum, u8 *key, int keylen);
+int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override,
+		u8 *iv, u8 *icv);
+int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum,
+		u8 *iv, u8 *icv);
 
-void	p80211netdev_startup(void);
-void	p80211netdev_shutdown(void);
-int	wlan_setup(wlandevice_t *wlandev);
-int	wlan_unsetup(wlandevice_t *wlandev);
-int	register_wlandev(wlandevice_t *wlandev);
-int	unregister_wlandev(wlandevice_t *wlandev);
-void	p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb);
-void	p80211netdev_hwremoved(wlandevice_t *wlandev);
-
+int wlan_setup(wlandevice_t *wlandev);
+int wlan_unsetup(wlandevice_t *wlandev);
+int register_wlandev(wlandevice_t *wlandev);
+int unregister_wlandev(wlandevice_t *wlandev);
+void p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb);
+void p80211netdev_hwremoved(wlandevice_t *wlandev);
+void p80211_allow_ioctls(wlandevice_t *wlandev);
 #endif
diff --git a/drivers/staging/wlan-ng/p80211req.c b/drivers/staging/wlan-ng/p80211req.c
index 6e20bff..15ecba6 100644
--- a/drivers/staging/wlan-ng/p80211req.c
+++ b/drivers/staging/wlan-ng/p80211req.c
@@ -50,11 +50,6 @@
 * --------------------------------------------------------------------
 */
 
-/*================================================================*/
-/* System Includes */
-
-
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -67,11 +62,6 @@
 #include <net/sock.h>
 #include <linux/netlink.h>
 
-#include "wlan_compat.h"
-
-/*================================================================*/
-/* Project Includes */
-
 #include "p80211types.h"
 #include "p80211hdr.h"
 #include "p80211mgmt.h"
@@ -83,30 +73,10 @@
 #include "p80211metastruct.h"
 #include "p80211req.h"
 
-/*================================================================*/
-/* Local Constants */
-
-/* Maximum amount of time we'll wait for a request to complete */
-#define P80211REQ_MAXTIME	3*HZ	/* 3 seconds */
-
-/*================================================================*/
-/* Local Macros */
-
-/*================================================================*/
-/* Local Types */
-
-/*================================================================*/
-/* Local Static Definitions */
-
-/*================================================================*/
-/* Local Function Declarations */
-
-static void p80211req_handlemsg( wlandevice_t *wlandev, p80211msg_t *msg);
-static int p80211req_mibset_mibget(wlandevice_t *wlandev, p80211msg_dot11req_mibget_t *mib_msg, int isget);
-
-/*================================================================*/
-/* Function Definitions */
-
+static void p80211req_handlemsg(wlandevice_t *wlandev, p80211msg_t *msg);
+static int p80211req_mibset_mibget(wlandevice_t *wlandev,
+				   p80211msg_dot11req_mibget_t *mib_msg,
+				   int isget);
 
 /*----------------------------------------------------------------
 * p80211req_dorequest
@@ -124,33 +94,30 @@
 *	Potentially blocks the caller, so it's a good idea to
 *	not call this function from an interrupt context.
 ----------------------------------------------------------------*/
-int p80211req_dorequest( wlandevice_t *wlandev, u8 *msgbuf)
+int p80211req_dorequest(wlandevice_t *wlandev, u8 *msgbuf)
 {
-	int		result = 0;
-	p80211msg_t	*msg = (p80211msg_t*)msgbuf;
-
-	DBFENTER;
+	int result = 0;
+	p80211msg_t *msg = (p80211msg_t *) msgbuf;
 
 	/* Check to make sure the MSD is running */
-	if (
-	!((wlandev->msdstate == WLAN_MSD_HWPRESENT &&
-	msg->msgcode == DIDmsg_lnxreq_ifstate) ||
-	wlandev->msdstate == WLAN_MSD_RUNNING ||
-	wlandev->msdstate == WLAN_MSD_FWLOAD) ) {
+	if (!((wlandev->msdstate == WLAN_MSD_HWPRESENT &&
+	       msg->msgcode == DIDmsg_lnxreq_ifstate) ||
+	      wlandev->msdstate == WLAN_MSD_RUNNING ||
+	      wlandev->msdstate == WLAN_MSD_FWLOAD)) {
 		return -ENODEV;
 	}
 
 	/* Check Permissions */
-	if (!capable(CAP_NET_ADMIN) &&
-	    (msg->msgcode != DIDmsg_dot11req_mibget)) {
-		WLAN_LOG_ERROR("%s: only dot11req_mibget allowed for non-root.\n", wlandev->name);
+	if (!capable(CAP_NET_ADMIN) && (msg->msgcode != DIDmsg_dot11req_mibget)) {
+		printk(KERN_ERR
+		       "%s: only dot11req_mibget allowed for non-root.\n",
+		       wlandev->name);
 		return -EPERM;
 	}
 
 	/* Check for busy status */
-	if ( test_and_set_bit(1, &(wlandev->request_pending))) {
+	if (test_and_set_bit(1, &(wlandev->request_pending)))
 		return -EBUSY;
-	}
 
 	/* Allow p80211 to look at msg and handle if desired. */
 	/* So far, all p80211 msgs are immediate, no waitq/timer necessary */
@@ -158,12 +125,11 @@
 	p80211req_handlemsg(wlandev, msg);
 
 	/* Pass it down to wlandev via wlandev->mlmerequest */
-	if ( wlandev->mlmerequest != NULL )
+	if (wlandev->mlmerequest != NULL)
 		wlandev->mlmerequest(wlandev, msg);
 
-	clear_bit( 1, &(wlandev->request_pending));
-	DBFEXIT;
-	return result;	/* if result==0, msg->status still may contain an err */
+	clear_bit(1, &(wlandev->request_pending));
+	return result; /* if result==0, msg->status still may contain an err */
 }
 
 /*----------------------------------------------------------------
@@ -184,34 +150,32 @@
 * Call context:
 *	Process thread
 ----------------------------------------------------------------*/
-static void p80211req_handlemsg( wlandevice_t *wlandev, p80211msg_t *msg)
+static void p80211req_handlemsg(wlandevice_t *wlandev, p80211msg_t *msg)
 {
-        DBFENTER;
-
 	switch (msg->msgcode) {
 
-	case DIDmsg_lnxreq_hostwep: {
-		p80211msg_lnxreq_hostwep_t *req = (p80211msg_lnxreq_hostwep_t*) msg;
-		wlandev->hostwep &= ~(HOSTWEP_DECRYPT|HOSTWEP_ENCRYPT);
-		if (req->decrypt.data == P80211ENUM_truth_true)
-			wlandev->hostwep |= HOSTWEP_DECRYPT;
-		if (req->encrypt.data == P80211ENUM_truth_true)
-			wlandev->hostwep |= HOSTWEP_ENCRYPT;
+	case DIDmsg_lnxreq_hostwep:{
+			p80211msg_lnxreq_hostwep_t *req =
+			    (p80211msg_lnxreq_hostwep_t *) msg;
+			wlandev->hostwep &=
+			    ~(HOSTWEP_DECRYPT | HOSTWEP_ENCRYPT);
+			if (req->decrypt.data == P80211ENUM_truth_true)
+				wlandev->hostwep |= HOSTWEP_DECRYPT;
+			if (req->encrypt.data == P80211ENUM_truth_true)
+				wlandev->hostwep |= HOSTWEP_ENCRYPT;
 
-		break;
-	}
+			break;
+		}
 	case DIDmsg_dot11req_mibget:
-	case DIDmsg_dot11req_mibset: {
-		int isget = (msg->msgcode == DIDmsg_dot11req_mibget);
-		p80211msg_dot11req_mibget_t  *mib_msg = (p80211msg_dot11req_mibget_t *) msg;
-		p80211req_mibset_mibget (wlandev, mib_msg, isget);
-	}
+	case DIDmsg_dot11req_mibset:{
+			int isget = (msg->msgcode == DIDmsg_dot11req_mibget);
+			p80211msg_dot11req_mibget_t *mib_msg =
+			    (p80211msg_dot11req_mibget_t *) msg;
+			p80211req_mibset_mibget(wlandev, mib_msg, isget);
+		}
 	default:
-		// XXX do nothing!
 		;
-	} /* switch msg->msgcode */
-
-	DBFEXIT;
+	}			/* switch msg->msgcode */
 
 	return;
 }
@@ -220,81 +184,82 @@
 				   p80211msg_dot11req_mibget_t *mib_msg,
 				   int isget)
 {
-	p80211itemd_t   *mibitem = (p80211itemd_t *) mib_msg->mibattribute.data;
-	p80211pstrd_t  *pstr = (p80211pstrd_t*) mibitem->data;
+	p80211itemd_t *mibitem = (p80211itemd_t *) mib_msg->mibattribute.data;
+	p80211pstrd_t *pstr = (p80211pstrd_t *) mibitem->data;
 	u8 *key = mibitem->data + sizeof(p80211pstrd_t);
 
-	DBFENTER;
-
 	switch (mibitem->did) {
-	case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0: {
-		if (!isget)
-			wep_change_key(wlandev, 0, key, pstr->len);
-		break;
-	}
-	case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1: {
-		if (!isget)
-			wep_change_key(wlandev, 1, key, pstr->len);
-		break;
-	}
-	case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2: {
-		if (!isget)
-			wep_change_key(wlandev, 2, key, pstr->len);
-		break;
-	}
-	case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3: {
-		if (!isget)
-			wep_change_key(wlandev, 3, key, pstr->len);
-		break;
-	}
-	case DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID: {
-		u32 *data = (u32 *) mibitem->data;
+	case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0:{
+			if (!isget)
+				wep_change_key(wlandev, 0, key, pstr->len);
+			break;
+		}
+	case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1:{
+			if (!isget)
+				wep_change_key(wlandev, 1, key, pstr->len);
+			break;
+		}
+	case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2:{
+			if (!isget)
+				wep_change_key(wlandev, 2, key, pstr->len);
+			break;
+		}
+	case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3:{
+			if (!isget)
+				wep_change_key(wlandev, 3, key, pstr->len);
+			break;
+		}
+	case DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID:{
+			u32 *data = (u32 *) mibitem->data;
 
-		if (isget) {
-			*data = wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK;
+			if (isget) {
+				*data =
+				    wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK;
 			} else {
 				wlandev->hostwep &= ~(HOSTWEP_DEFAULTKEY_MASK);
 
-				wlandev->hostwep |= (*data & HOSTWEP_DEFAULTKEY_MASK);
+				wlandev->hostwep |=
+				    (*data & HOSTWEP_DEFAULTKEY_MASK);
 			}
-		break;
-	}
-	case DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked: {
-		u32 *data = (u32 *) mibitem->data;
+			break;
+		}
+	case DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked:{
+			u32 *data = (u32 *) mibitem->data;
 
-		if (isget) {
-			if (wlandev->hostwep & HOSTWEP_PRIVACYINVOKED)
-				*data = P80211ENUM_truth_true;
-			else
-				*data = P80211ENUM_truth_false;
-		} else {
+			if (isget) {
+				if (wlandev->hostwep & HOSTWEP_PRIVACYINVOKED)
+					*data = P80211ENUM_truth_true;
+				else
+					*data = P80211ENUM_truth_false;
+			} else {
 				wlandev->hostwep &= ~(HOSTWEP_PRIVACYINVOKED);
 				if (*data == P80211ENUM_truth_true)
-					wlandev->hostwep |= HOSTWEP_PRIVACYINVOKED;
+					wlandev->hostwep |=
+					    HOSTWEP_PRIVACYINVOKED;
+			}
+			break;
 		}
-		break;
-	}
-	case DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted: {
-		u32 *data = (u32 *) mibitem->data;
+	case DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted:{
+			u32 *data = (u32 *) mibitem->data;
 
-		if (isget) {
-			if (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED)
-				*data = P80211ENUM_truth_true;
-			else
-				*data = P80211ENUM_truth_false;
-		} else {
-			wlandev->hostwep &= ~(HOSTWEP_EXCLUDEUNENCRYPTED);
-			if (*data == P80211ENUM_truth_true)
-				wlandev->hostwep |= HOSTWEP_EXCLUDEUNENCRYPTED;
+			if (isget) {
+				if (wlandev->
+				    hostwep & HOSTWEP_EXCLUDEUNENCRYPTED)
+					*data = P80211ENUM_truth_true;
+				else
+					*data = P80211ENUM_truth_false;
+			} else {
+				wlandev->hostwep &=
+				    ~(HOSTWEP_EXCLUDEUNENCRYPTED);
+				if (*data == P80211ENUM_truth_true)
+					wlandev->hostwep |=
+					    HOSTWEP_EXCLUDEUNENCRYPTED;
+			}
+			break;
 		}
-		break;
-	}
 	default:
-		// XXXX do nothing!
 		;
 	}
 
-	DBFEXIT;
 	return 0;
 }
-
diff --git a/drivers/staging/wlan-ng/p80211req.h b/drivers/staging/wlan-ng/p80211req.h
index 497a4d6..a95a45a 100644
--- a/drivers/staging/wlan-ng/p80211req.h
+++ b/drivers/staging/wlan-ng/p80211req.h
@@ -48,21 +48,6 @@
 #ifndef _LINUX_P80211REQ_H
 #define _LINUX_P80211REQ_H
 
-/*================================================================*/
-/* Constants */
-
-/*================================================================*/
-/* Macros */
-
-/*================================================================*/
-/* Types */
-
-/*================================================================*/
-/* Externs */
-
-/*================================================================*/
-/* Function Declarations */
-
-int	p80211req_dorequest(wlandevice_t *wlandev, u8 *msgbuf);
+int p80211req_dorequest(wlandevice_t *wlandev, u8 *msgbuf);
 
 #endif
diff --git a/drivers/staging/wlan-ng/p80211types.h b/drivers/staging/wlan-ng/p80211types.h
index 5be6737..a22437c 100644
--- a/drivers/staging/wlan-ng/p80211types.h
+++ b/drivers/staging/wlan-ng/p80211types.h
@@ -58,37 +58,9 @@
 #define _P80211TYPES_H
 
 /*================================================================*/
-/* System Includes */
-/*================================================================*/
-
-/*================================================================*/
 /* Project Includes */
 /*================================================================*/
 
-#ifndef _WLAN_COMPAT_H
-#include "wlan_compat.h"
-#endif
-
-/*================================================================*/
-/* Constants */
-/*================================================================*/
-
-/*----------------------------------------------------------------*/
-/* p80211 data type codes used for MIB items and message */
-/* arguments. The various metadata structures provide additional */
-/* information about these types. */
-
-#define P80211_TYPE_OCTETSTR		1	/* pascal array of bytes */
-#define P80211_TYPE_DISPLAYSTR		2	/* pascal array of bytes containing ascii */
-#define P80211_TYPE_int			4	/* u32 min and max limited by 32 bits */
-#define P80211_TYPE_ENUMint		5	/* u32 holding a numeric
-						   code that can be mapped
-						   to a textual name */
-#define P80211_TYPE_UNKDATA		6	/* Data item containing an
-						   unknown data type */
-#define P80211_TYPE_intARRAY		7	/* Array of 32-bit integers. */
-#define P80211_TYPE_BITARRAY		8	/* Array of bits. */
-#define P80211_TYPE_MACARRAY		9	/* Array of MAC addresses. */
 
 /*----------------------------------------------------------------*/
 /* The following constants are indexes into the Mib Category List */
@@ -106,25 +78,6 @@
 /* Message Category List */
 #define P80211_MSG_CAT_DOT11REQ		1
 #define P80211_MSG_CAT_DOT11IND		2
-/* #define P80211_MSG_CAT_DOT11CFM		3 (doesn't exist at this time) */
-
-#define P80211SEC_DOT11REQ		P80211_MSG_CAT_DOT11REQ
-#define P80211SEC_DOT11IND		P80211_MSG_CAT_DOT11IND
-/* #define P80211SEC_DOT11CFM		P80211_MSG_CAT_DOT11CFM  (doesn't exist at this time */
-
-
-
-/*----------------------------------------------------------------*/
-/* p80211 DID field codes that represent access type and */
-/* is_table status. */
-
-#define P80211DID_ACCESS_READ		0x10000000
-#define P80211DID_ACCESS_WRITE		0x08000000
-#define P80211DID_WRITEONLY		0x00000001
-#define P80211DID_READONLY		0x00000002
-#define P80211DID_READWRITE		0x00000003
-#define P80211DID_ISTABLE_FALSE		0
-#define P80211DID_ISTABLE_TRUE		1
 
 /*----------------------------------------------------------------*/
 /* p80211 enumeration constants.  The value to text mappings for */
@@ -132,104 +85,30 @@
 /*  from the mappings. */
 
 /* error codes for lookups */
-#define P80211ENUM_BAD				0xffffffffUL
-#define P80211ENUM_BADSTR			"P80211ENUM_BAD"
 
 #define P80211ENUM_truth_false			0
 #define P80211ENUM_truth_true			1
 #define P80211ENUM_ifstate_disable		0
 #define P80211ENUM_ifstate_fwload		1
 #define P80211ENUM_ifstate_enable		2
-#define P80211ENUM_powermgmt_active		1
-#define P80211ENUM_powermgmt_powersave		2
 #define P80211ENUM_bsstype_infrastructure	1
 #define P80211ENUM_bsstype_independent		2
 #define P80211ENUM_bsstype_any			3
 #define P80211ENUM_authalg_opensystem		1
 #define P80211ENUM_authalg_sharedkey		2
-#define P80211ENUM_phytype_fhss			1
-#define P80211ENUM_phytype_dsss			2
-#define P80211ENUM_phytype_irbaseband		3
-#define P80211ENUM_temptype_commercial		1
-#define P80211ENUM_temptype_industrial		2
-#define P80211ENUM_regdomain_fcc		16
-#define P80211ENUM_regdomain_doc		32
-#define P80211ENUM_regdomain_etsi		48
-#define P80211ENUM_regdomain_spain		49
-#define P80211ENUM_regdomain_france		50
-#define P80211ENUM_regdomain_mkk		64
-#define P80211ENUM_ccamode_edonly		1
-#define P80211ENUM_ccamode_csonly		2
-#define P80211ENUM_ccamode_edandcs		4
-#define P80211ENUM_ccamode_cswithtimer		8
-#define P80211ENUM_ccamode_hrcsanded		16
-#define P80211ENUM_diversity_fixedlist		1
-#define P80211ENUM_diversity_notsupported	2
-#define P80211ENUM_diversity_dynamic		3
 #define P80211ENUM_scantype_active		1
-#define P80211ENUM_scantype_passive		2
-#define P80211ENUM_scantype_both		3
 #define P80211ENUM_resultcode_success		1
 #define P80211ENUM_resultcode_invalid_parameters	2
 #define P80211ENUM_resultcode_not_supported	3
-#define P80211ENUM_resultcode_timeout		4
-#define P80211ENUM_resultcode_too_many_req	5
 #define P80211ENUM_resultcode_refused		6
-#define P80211ENUM_resultcode_bss_already	7
-#define P80211ENUM_resultcode_invalid_access	8
-#define P80211ENUM_resultcode_invalid_mibattribute	9
 #define P80211ENUM_resultcode_cant_set_readonly_mib	10
 #define P80211ENUM_resultcode_implementation_failure	11
 #define P80211ENUM_resultcode_cant_get_writeonly_mib	12
-#define P80211ENUM_reason_unspec_reason		1
-#define P80211ENUM_reason_auth_not_valid	2
-#define P80211ENUM_reason_deauth_lv_ss		3
-#define P80211ENUM_reason_inactivity		4
-#define P80211ENUM_reason_ap_overload		5
-#define P80211ENUM_reason_class23_err		6
-#define P80211ENUM_reason_class3_err		7
-#define P80211ENUM_reason_disas_lv_ss		8
-#define P80211ENUM_reason_asoc_not_auth		9
 #define P80211ENUM_status_successful		0
 #define P80211ENUM_status_unspec_failure	1
-#define P80211ENUM_status_unsup_cap		10
-#define P80211ENUM_status_reasoc_no_asoc	11
-#define P80211ENUM_status_fail_other		12
-#define P80211ENUM_status_unspt_alg		13
-#define P80211ENUM_status_auth_seq_fail		14
-#define P80211ENUM_status_chlng_fail		15
-#define P80211ENUM_status_auth_timeout		16
 #define P80211ENUM_status_ap_full		17
-#define P80211ENUM_status_unsup_rate		18
-#define P80211ENUM_status_unsup_shortpreamble	19
-#define P80211ENUM_status_unsup_pbcc		20
-#define P80211ENUM_status_unsup_agility		21
 #define P80211ENUM_msgitem_status_data_ok		0
 #define P80211ENUM_msgitem_status_no_value		1
-#define P80211ENUM_msgitem_status_invalid_itemname	2
-#define P80211ENUM_msgitem_status_invalid_itemdata	3
-#define P80211ENUM_msgitem_status_missing_itemdata	4
-#define P80211ENUM_msgitem_status_incomplete_itemdata	5
-#define P80211ENUM_msgitem_status_invalid_msg_did	6
-#define P80211ENUM_msgitem_status_invalid_mib_did	7
-#define P80211ENUM_msgitem_status_missing_conv_func	8
-#define P80211ENUM_msgitem_status_string_too_long	9
-#define P80211ENUM_msgitem_status_data_out_of_range	10
-#define P80211ENUM_msgitem_status_string_too_short	11
-#define P80211ENUM_msgitem_status_missing_valid_func	12
-#define P80211ENUM_msgitem_status_unknown		13
-#define P80211ENUM_msgitem_status_invalid_did		14
-#define P80211ENUM_msgitem_status_missing_print_func	15
-
-#define P80211ENUM_lnxroam_reason_unknown        0
-#define P80211ENUM_lnxroam_reason_beacon         1
-#define P80211ENUM_lnxroam_reason_signal         2
-#define P80211ENUM_lnxroam_reason_txretry        3
-#define P80211ENUM_lnxroam_reason_notjoined      4
-
-#define P80211ENUM_p2preamble_long               0
-#define P80211ENUM_p2preamble_short              2
-#define P80211ENUM_p2preamble_mixed              3
 
 /*----------------------------------------------------------------*/
 /* p80211 max length constants for the different pascal strings. */
@@ -243,46 +122,6 @@
 					/* is a DID-LEN-DATA triple */
 					/* with a max size of 4+4+384 */
 
-#define P80211_SET_int(item, value) do { \
-	(item).data   = (value); \
-	(item).status = P80211ENUM_msgitem_status_data_ok; \
-	} while(0)
-/*----------------------------------------------------------------*/
-/* string constants */
-
-#define NOT_SET			"NOT_SET"
-#define NOT_SUPPORTED		"NOT_SUPPORTED"
-#define UNKNOWN_DATA		"UNKNOWN_DATA"
-
-
-/*--------------------------------------------------------------------*/
-/*  Metadata flags  */
-
-/* MSM: Do these belong in p80211meta.h? I'm not sure. */
-
-#define ISREQUIRED		(0x80000000UL)
-#define ISREQUEST		(0x40000000UL)
-#define ISCONFIRM		(0x20000000UL)
-
-
-/*================================================================*/
-/* Macros */
-
-/*--------------------------------------------------------------------*/
-/* The following macros are used to manipulate the 'flags' field in   */
-/*  the metadata.  These are only used when the metadata is for       */
-/*  command arguments to determine if the data item is required, and  */
-/*  whether the metadata item is for a request command, confirm       */
-/*  command or both.                                                  */
-/*--------------------------------------------------------------------*/
-/* MSM: Do these belong in p80211meta.h?  I'm not sure */
-
-#define P80211ITEM_SETFLAGS(q, r, c)	( q | r | c )
-
-#define P80211ITEM_ISREQUIRED(flags)	(((u32)(flags & ISREQUIRED)) >> 31 )
-#define P80211ITEM_ISREQUEST(flags)	(((u32)(flags & ISREQUEST)) >> 30 )
-#define P80211ITEM_ISCONFIRM(flags)	(((u32)(flags & ISCONFIRM)) >> 29 )
-
 /*----------------------------------------------------------------*/
 /* The following macro creates a name for an enum */
 
@@ -302,9 +141,6 @@
 *                                           . - Unused
 */
 
-#define P80211DID_INVALID		0xffffffffUL
-#define P80211DID_VALID			0x00000000UL
-
 #define P80211DID_LSB_SECTION		(0)
 #define P80211DID_LSB_GROUP		(6)
 #define P80211DID_LSB_ITEM		(12)
@@ -319,35 +155,32 @@
 #define P80211DID_MASK_ISTABLE		(0x00000001UL)
 #define P80211DID_MASK_ACCESS 		(0x00000003UL)
 
-
-#define P80211DID_MK(a,m,l)	((((u32)(a)) & (m)) << (l))
+#define P80211DID_MK(a, m, l)	((((u32)(a)) & (m)) << (l))
 
 #define P80211DID_MKSECTION(a)	P80211DID_MK(a, \
 					P80211DID_MASK_SECTION, \
-					P80211DID_LSB_SECTION )
+					P80211DID_LSB_SECTION)
 #define P80211DID_MKGROUP(a)	P80211DID_MK(a, \
 					P80211DID_MASK_GROUP, \
-					P80211DID_LSB_GROUP )
+					P80211DID_LSB_GROUP)
 #define P80211DID_MKITEM(a)	P80211DID_MK(a, \
 					P80211DID_MASK_ITEM, \
-					P80211DID_LSB_ITEM )
+					P80211DID_LSB_ITEM)
 #define P80211DID_MKINDEX(a)	P80211DID_MK(a, \
 					P80211DID_MASK_INDEX, \
-					P80211DID_LSB_INDEX )
+					P80211DID_LSB_INDEX)
 #define P80211DID_MKISTABLE(a)	P80211DID_MK(a, \
 					P80211DID_MASK_ISTABLE, \
-					P80211DID_LSB_ISTABLE )
-
+					P80211DID_LSB_ISTABLE)
 
 #define P80211DID_MKID(s,g,i,n,t,a)	(P80211DID_MKSECTION(s) | \
 						P80211DID_MKGROUP(g) | \
 				 		P80211DID_MKITEM(i) | \
 				 		P80211DID_MKINDEX(n) | \
 						P80211DID_MKISTABLE(t) | \
-						(a) )
+						(a))
 
-
-#define P80211DID_GET(a,m,l)	((((u32)(a)) >> (l)) & (m))
+#define P80211DID_GET(a, m, l)	((((u32)(a)) >> (l)) & (m))
 
 #define P80211DID_SECTION(a)	P80211DID_GET(a, \
 					P80211DID_MASK_SECTION, \
@@ -368,23 +201,18 @@
 					P80211DID_MASK_ACCESS, \
 					P80211DID_LSB_ACCESS)
 
-/*================================================================*/
-/* Types */
-
 /*----------------------------------------------------------------*/
 /* The following structure types are used for the represenation */
 /*  of ENUMint type metadata. */
 
-typedef struct p80211enumpair
-{
-	u32			val;
-	char			*name;
+typedef struct p80211enumpair {
+	u32 val;
+	char *name;
 } p80211enumpair_t;
 
-typedef struct p80211enum
-{
-	int			nitems;
-	p80211enumpair_t	*list;
+typedef struct p80211enum {
+	int nitems;
+	p80211enumpair_t *list;
 } p80211enum_t;
 
 /*----------------------------------------------------------------*/
@@ -392,140 +220,123 @@
 /*  messages. */
 
 /* Template pascal string */
-typedef struct p80211pstr
-{
-	u8		len;
-} __WLAN_ATTRIB_PACK__ p80211pstr_t;
+typedef struct p80211pstr {
+	u8 len;
+} __attribute__ ((packed)) p80211pstr_t;
 
-typedef struct p80211pstrd
-{
-	u8		len;
-	u8		data[0];
-} __WLAN_ATTRIB_PACK__ p80211pstrd_t;
+typedef struct p80211pstrd {
+	u8 len;
+	u8 data[0];
+} __attribute__ ((packed)) p80211pstrd_t;
 
 /* Maximum pascal string */
-typedef struct p80211pstr255
-{
-	u8		len;
-	u8		data[MAXLEN_PSTR255];
-} __WLAN_ATTRIB_PACK__ p80211pstr255_t;
+typedef struct p80211pstr255 {
+	u8 len;
+	u8 data[MAXLEN_PSTR255];
+} __attribute__ ((packed)) p80211pstr255_t;
 
 /* pascal string for macaddress and bssid */
-typedef struct p80211pstr6
-{
-	u8		len;
-	u8		data[MAXLEN_PSTR6];
-} __WLAN_ATTRIB_PACK__ p80211pstr6_t;
+typedef struct p80211pstr6 {
+	u8 len;
+	u8 data[MAXLEN_PSTR6];
+} __attribute__ ((packed)) p80211pstr6_t;
 
 /* pascal string for channel list */
-typedef struct p80211pstr14
-{
-	u8		len;
-	u8		data[MAXLEN_PSTR14];
-} __WLAN_ATTRIB_PACK__ p80211pstr14_t;
+typedef struct p80211pstr14 {
+	u8 len;
+	u8 data[MAXLEN_PSTR14];
+} __attribute__ ((packed)) p80211pstr14_t;
 
 /* pascal string for ssid */
-typedef struct p80211pstr32
-{
-	u8		len;
-	u8		data[MAXLEN_PSTR32];
-} __WLAN_ATTRIB_PACK__ p80211pstr32_t;
+typedef struct p80211pstr32 {
+	u8 len;
+	u8 data[MAXLEN_PSTR32];
+} __attribute__ ((packed)) p80211pstr32_t;
 
 /* MAC address array */
-typedef struct p80211macarray
-{
-	u32		cnt;
-	u8		data[1][MAXLEN_PSTR6];
-} __WLAN_ATTRIB_PACK__ p80211macarray_t;
+typedef struct p80211macarray {
+	u32 cnt;
+	u8 data[1][MAXLEN_PSTR6];
+} __attribute__ ((packed)) p80211macarray_t;
 
 /* prototype template */
-typedef struct p80211item
-{
-	u32		did;
-	u16		status;
-	u16		len;
-} __WLAN_ATTRIB_PACK__ p80211item_t;
+typedef struct p80211item {
+	u32 did;
+	u16 status;
+	u16 len;
+} __attribute__ ((packed)) p80211item_t;
 
 /* prototype template w/ data item */
-typedef struct p80211itemd
-{
-	u32		did;
-	u16		status;
-	u16		len;
-	u8		data[0];
-} __WLAN_ATTRIB_PACK__ p80211itemd_t;
+typedef struct p80211itemd {
+	u32 did;
+	u16 status;
+	u16 len;
+	u8 data[0];
+} __attribute__ ((packed)) p80211itemd_t;
 
 /* message data item for int, BOUNDEDINT, ENUMINT */
-typedef struct p80211item_uint32
-{
-	u32		did;
-	u16		status;
-	u16		len;
-	u32		data;
-} __WLAN_ATTRIB_PACK__ p80211item_uint32_t;
+typedef struct p80211item_uint32 {
+	u32 did;
+	u16 status;
+	u16 len;
+	u32 data;
+} __attribute__ ((packed)) p80211item_uint32_t;
 
 /* message data item for OCTETSTR, DISPLAYSTR */
-typedef struct p80211item_pstr6
-{
-	u32		did;
-	u16		status;
-	u16		len;
-	p80211pstr6_t	data;
-} __WLAN_ATTRIB_PACK__ p80211item_pstr6_t;
+typedef struct p80211item_pstr6 {
+	u32 did;
+	u16 status;
+	u16 len;
+	p80211pstr6_t data;
+} __attribute__ ((packed)) p80211item_pstr6_t;
 
 /* message data item for OCTETSTR, DISPLAYSTR */
-typedef struct p80211item_pstr14
-{
-	u32			did;
-	u16			status;
-	u16			len;
-	p80211pstr14_t		data;
-} __WLAN_ATTRIB_PACK__ p80211item_pstr14_t;
+typedef struct p80211item_pstr14 {
+	u32 did;
+	u16 status;
+	u16 len;
+	p80211pstr14_t data;
+} __attribute__ ((packed)) p80211item_pstr14_t;
 
 /* message data item for OCTETSTR, DISPLAYSTR */
-typedef struct p80211item_pstr32
-{
-	u32			did;
-	u16			status;
-	u16			len;
-	p80211pstr32_t		data;
-} __WLAN_ATTRIB_PACK__ p80211item_pstr32_t;
+typedef struct p80211item_pstr32 {
+	u32 did;
+	u16 status;
+	u16 len;
+	p80211pstr32_t data;
+} __attribute__ ((packed)) p80211item_pstr32_t;
 
 /* message data item for OCTETSTR, DISPLAYSTR */
-typedef struct p80211item_pstr255
-{
-	u32			did;
-	u16			status;
-	u16			len;
-	p80211pstr255_t		data;
-} __WLAN_ATTRIB_PACK__ p80211item_pstr255_t;
+typedef struct p80211item_pstr255 {
+	u32 did;
+	u16 status;
+	u16 len;
+	p80211pstr255_t data;
+} __attribute__ ((packed)) p80211item_pstr255_t;
 
 /* message data item for UNK 392, namely mib items */
-typedef struct  p80211item_unk392
-{
-	u32		did;
-	u16		status;
-	u16		len;
-	u8		data[MAXLEN_MIBATTRIBUTE];
-} __WLAN_ATTRIB_PACK__ p80211item_unk392_t;
+typedef struct p80211item_unk392 {
+	u32 did;
+	u16 status;
+	u16 len;
+	u8 data[MAXLEN_MIBATTRIBUTE];
+} __attribute__ ((packed)) p80211item_unk392_t;
 
 /* message data item for UNK 1025, namely p2 pdas */
-typedef struct  p80211item_unk1024
-{
-	u32		did;
-	u16		status;
-	u16		len;
-	u8		data[1024];
-}  __WLAN_ATTRIB_PACK__ p80211item_unk1024_t;
+typedef struct p80211item_unk1024 {
+	u32 did;
+	u16 status;
+	u16 len;
+	u8 data[1024];
+} __attribute__ ((packed)) p80211item_unk1024_t;
 
 /* message data item for UNK 4096, namely p2 download chunks */
-typedef struct  p80211item_unk4096
-{
-	u32		did;
-	u16		status;
-	u16		len;
-	u8		data[4096];
-}  __WLAN_ATTRIB_PACK__ p80211item_unk4096_t;
+typedef struct p80211item_unk4096 {
+	u32 did;
+	u16 status;
+	u16 len;
+	u8 data[4096];
+} __attribute__ ((packed)) p80211item_unk4096_t;
 
 struct catlistitem;
 
@@ -534,13 +345,11 @@
 /*  metadata items.  Some components may choose to use more, */
 /*  less or different metadata items. */
 
-typedef void (*p80211_totext_t)( struct catlistitem *, u32 did, u8* itembuf, char *textbuf);
-typedef void (*p80211_fromtext_t)( struct catlistitem *, u32 did, u8* itembuf, char *textbuf);
-typedef u32 (*p80211_valid_t)( struct catlistitem *, u32 did, u8* itembuf);
-
-
-/*================================================================*/
-/* Extern Declarations */
+typedef void (*p80211_totext_t) (struct catlistitem *, u32 did, u8 *itembuf,
+				 char *textbuf);
+typedef void (*p80211_fromtext_t) (struct catlistitem *, u32 did, u8 *itembuf,
+				   char *textbuf);
+typedef u32(*p80211_valid_t) (struct catlistitem *, u32 did, u8 *itembuf);
 
 /*----------------------------------------------------------------*/
 /* Enumeration Lists */
@@ -568,108 +377,4 @@
 
 extern p80211enum_t MKENUMNAME(p2preamble);
 
-/*================================================================*/
-/* Function Declarations */
-
-/*----------------------------------------------------------------*/
-/* The following declare some utility functions for use with the */
-/*  p80211enum_t type. */
-
-u32 p80211enum_text2int(p80211enum_t *ep, char *text);
-u32 p80211enum_int2text(p80211enum_t *ep, u32 val, char *text);
-void p80211_error2text(int err_code, char *err_str);
-
-/*----------------------------------------------------------------*/
-/* The following declare some utility functions for use with the */
-/*  p80211item_t and p80211meta_t types. */
-
-/*----------------------------------------------------------------*/
-/* The following declare functions that perform validation and    */
-/* text to binary conversions based on the metadata for interface */
-/* and MIB data items.                                            */
-/*----------------------------------------------------------------*/
-
-/*-- DISPLAYSTR ------------------------------------------------------*/
-/* pstr ==> cstr */
-void p80211_totext_displaystr( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* cstr ==> pstr */
-void p80211_fromtext_displaystr( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* function that checks validity of a displaystr binary value */
-u32 p80211_isvalid_displaystr( struct catlistitem *metalist, u32 did, u8 *itembuf );
-
-/*-- OCTETSTR --------------------------------------------------------*/
-/* pstr ==> "xx:xx:...." */
-void p80211_totext_octetstr( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* "xx:xx:...." ==> pstr */
-void p80211_fromtext_octetstr( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* function that checks validity of an octetstr binary value */
-u32 p80211_isvalid_octetstr( struct catlistitem *metalist, u32 did, u8 *itembuf );
-
-/*-- int -------------------------------------------------------------*/
-/* u32 ==> %d */
-void p80211_totext_int( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* %d ==> u32 */
-void p80211_fromtext_int( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* function that checks validity of an int's binary value (always successful) */
-u32 p80211_isvalid_int( struct catlistitem *metalist, u32 did, u8 *itembuf );
-
-/*-- ENUMint ---------------------------------------------------------*/
-/* u32 ==> <valuename> */
-void p80211_totext_enumint( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* <valuename> ==> u32 */
-void p80211_fromtext_enumint( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* function that checks validity of an enum's binary value */
-u32 p80211_isvalid_enumint( struct catlistitem *metalist, u32 did, u8 *itembuf );
-
-/*-- intARRAY --------------------------------------------------------*/
-/* u32[] => %d,%d,%d,... */
-void p80211_totext_intarray( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* %d,%d,%d,... ==> u32[] */
-void p80211_fromtext_intarray( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* function that checks validity of an integer array's value */
-u32 p80211_isvalid_intarray( struct catlistitem *metalist, u32 did, u8 *itembuf );
-
-/*-- BITARRAY --------------------------------------------------------*/
-/* u32 ==> %d,%d,%d,... */
-void p80211_totext_bitarray( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* %d,%d,%d,... ==> u32 */
-void p80211_fromtext_bitarray( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* function that checks validity of a bit array's value */
-u32 p80211_isvalid_bitarray( struct catlistitem *metalist, u32 did, u8 *itembuf );
-
-/*-- MACARRAY --------------------------------------------------------*/
-void p80211_totext_macarray( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-void p80211_fromtext_macarray( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* function that checks validity of a MAC address array's value */
-u32 p80211_isvalid_macarray( struct catlistitem *metalist, u32 did, u8 *itembuf );
-
-/*-- MIBATTRIUBTE ------------------------------------------------------*/
-/* <mibvalue> ==> <textual representation identified in MIB metadata> */
-void p80211_totext_getmibattribute( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-void p80211_totext_setmibattribute( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-
-/* <textual representation identified in MIB metadata> ==> <mibvalue> */
-void p80211_fromtext_getmibattribute( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-void p80211_fromtext_setmibattribute( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* function that checks validity of a mibitem's binary value */
-u32 p80211_isvalid_getmibattribute( struct catlistitem *metalist, u32 did, u8 *itembuf );
-u32 p80211_isvalid_setmibattribute( struct catlistitem *metalist, u32 did, u8 *itembuf );
-
 #endif /* _P80211TYPES_H */
-
diff --git a/drivers/staging/wlan-ng/p80211wep.c b/drivers/staging/wlan-ng/p80211wep.c
index 46a2a6b..405ce89 100644
--- a/drivers/staging/wlan-ng/p80211wep.c
+++ b/drivers/staging/wlan-ng/p80211wep.c
@@ -55,8 +55,7 @@
 #include <linux/wireless.h>
 #include <linux/slab.h>
 #include <linux/random.h>
-
-#include "wlan_compat.h"
+#include <linux/kernel.h>
 
 // #define WEP_DEBUG
 
@@ -72,18 +71,9 @@
 /*================================================================*/
 /* Local Constants */
 
-#define SSWAP(a,b) {u8 tmp = s[a]; s[a] = s[b]; s[b] = tmp;}
 #define WEP_KEY(x)       (((x) & 0xC0) >> 6)
 
 /*================================================================*/
-/* Local Macros */
-
-
-/*================================================================*/
-/* Local Types */
-
-
-/*================================================================*/
 /* Local Static Definitions */
 
 static const u32 wep_crc32_table[256] = {
@@ -211,7 +201,7 @@
 	j = 0;
 	for (i = 0; i < 256; i++) {
 		j = (j + s[i] + key[i % keylen]) & 0xff;
-		SSWAP(i,j);
+		swap(i,j);
 	}
 
 	/* Apply the RC4 to the data, update the CRC32 */
@@ -220,7 +210,7 @@
 	for (k = 0; k < len; k++) {
 		i = (i+1) & 0xff;
 		j = (j+s[i]) & 0xff;
-		SSWAP(i,j);
+		swap(i,j);
 		buf[k] ^= s[(s[i] + s[j]) & 0xff];
 		crc = wep_crc32_table[(crc ^ buf[k]) & 0xff] ^ (crc >> 8);
 	}
@@ -235,7 +225,7 @@
 	for (k = 0; k < 4; k++) {
 		i = (i + 1) & 0xff;
 		j = (j+s[i]) & 0xff;
-		SSWAP(i,j);
+		swap(i,j);
 		if ((c_crc[k] ^ s[(s[i] + s[j]) & 0xff]) != icv[k])
 			return -(4 | (k << 4)) ; /* ICV mismatch */
 	}
@@ -283,7 +273,7 @@
 	j = 0;
 	for (i = 0; i < 256; i++) {
 		j = (j + s[i] + key[i % keylen]) & 0xff;
-		SSWAP(i,j);
+		swap(i,j);
 	}
 
 	/* Update CRC32 then apply RC4 to the data */
@@ -293,7 +283,7 @@
 		crc = wep_crc32_table[(crc ^ buf[k]) & 0xff] ^ (crc >> 8);
 		i = (i+1) & 0xff;
 		j = (j+s[i]) & 0xff;
-		SSWAP(i,j);
+		swap(i,j);
 		dst[k] = buf[k] ^ s[(s[i] + s[j]) & 0xff];
 	}
 	crc = ~crc;
@@ -307,7 +297,7 @@
 	for (k = 0; k < 4; k++) {
 		i = (i + 1) & 0xff;
 		j = (j+s[i]) & 0xff;
-		SSWAP(i,j);
+		swap(i,j);
 		icv[k] ^= s[(s[i] + s[j]) & 0xff];
 	}
 
diff --git a/drivers/staging/wlan-ng/p80211wext.c b/drivers/staging/wlan-ng/p80211wext.c
index 0d570f1..96078b0 100644
--- a/drivers/staging/wlan-ng/p80211wext.c
+++ b/drivers/staging/wlan-ng/p80211wext.c
@@ -51,12 +51,12 @@
 #include <asm/bitops.h>
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
+#include <linux/if_ether.h>
+#include <linux/bitops.h>
 
 /*================================================================*/
 /* Project Includes */
 
-#include "wlan_compat.h"
-
 #include "p80211types.h"
 #include "p80211hdr.h"
 #include "p80211conv.h"
@@ -77,16 +77,14 @@
 
 static u8 p80211_mhz_to_channel(u16 mhz)
 {
-	if (mhz >= 5000) {
-		return ((mhz - 5000) / 5);
-	}
+	if (mhz >= 5000)
+		return (mhz - 5000) / 5;
 
 	if (mhz == 2482)
 		return 14;
 
-	if (mhz >= 2407) {
-		return ((mhz - 2407) / 5);
-	}
+	if (mhz >= 2407)
+		return (mhz - 2407) / 5;
 
 	return 0;
 }
@@ -100,19 +98,15 @@
 		return 0;
 
 	/* 5G */
-
-	if (dot11a) {
-		return (5000 + (5 * ch));
-	}
+	if (dot11a)
+		return 5000 + (5 * ch);
 
 	/* 2.4G */
-
 	if (ch == 14)
 		return 2484;
 
-	if ((ch < 14) && (ch > 0)) {
-		return (2407 + (5 * ch));
-	}
+	if ((ch < 14) && (ch > 0))
+		return 2407 + (5 * ch);
 
 	return 0;
 }
@@ -122,54 +116,46 @@
 	2412, 2417, 2422, 2427, 2432, 2437, 2442,
 	2447, 2452, 2457, 2462, 2467, 2472, 2484
 };
+
 #define NUM_CHANNELS ARRAY_SIZE(p80211wext_channel_freq)
 
-/* steal a spare bit to store the shared/opensystems state. should default to open if not set */
-#define HOSTWEP_SHAREDKEY BIT3
+/* steal a spare bit to store the shared/opensystems state.
+   should default to open if not set */
+#define HOSTWEP_SHAREDKEY BIT(3)
 
-
-/** function declarations =============== */
-
-static int qual_as_percent(int snr ) {
-  if ( snr <= 0 )
-    return 0;
-  if ( snr <= 40 )
-    return snr*5/2;
-  return 100;
+static int qual_as_percent(int snr)
+{
+	if (snr <= 0)
+		return 0;
+	if (snr <= 40)
+		return snr * 5 / 2;
+	return 100;
 }
 
-
-
-
 static int p80211wext_dorequest(wlandevice_t *wlandev, u32 did, u32 data)
 {
-	p80211msg_dot11req_mibset_t	msg;
-	p80211item_uint32_t		mibitem;
-	int	result;
-
-	DBFENTER;
+	p80211msg_dot11req_mibset_t msg;
+	p80211item_uint32_t mibitem;
+	int result;
 
 	msg.msgcode = DIDmsg_dot11req_mibset;
 	mibitem.did = did;
 	mibitem.data = data;
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8*)&msg);
+	result = p80211req_dorequest(wlandev, (u8 *)&msg);
 
-	DBFEXIT;
 	return result;
 }
 
 static int p80211wext_autojoin(wlandevice_t *wlandev)
 {
-	p80211msg_lnxreq_autojoin_t     msg;
-	struct iw_point			data;
+	p80211msg_lnxreq_autojoin_t msg;
+	struct iw_point data;
 	char ssid[IW_ESSID_MAX_SIZE];
 
 	int result;
 	int err = 0;
 
-	DBFENTER;
-
 	/* Get ESSID */
 	result = p80211wext_giwessid(wlandev->netdev, NULL, &data, ssid);
 
@@ -178,23 +164,22 @@
 		goto exit;
 	}
 
-	if ( wlandev->hostwep & HOSTWEP_SHAREDKEY )
-	  msg.authtype.data = P80211ENUM_authalg_sharedkey;
+	if (wlandev->hostwep & HOSTWEP_SHAREDKEY)
+		msg.authtype.data = P80211ENUM_authalg_sharedkey;
 	else
-	  msg.authtype.data = P80211ENUM_authalg_opensystem;
+		msg.authtype.data = P80211ENUM_authalg_opensystem;
 
 	msg.msgcode = DIDmsg_lnxreq_autojoin;
 
 	/* Trim the last '\0' to fit the SSID format */
 
-	if (data.length && ssid[data.length-1] == '\0') {
+	if (data.length && ssid[data.length - 1] == '\0')
 		data.length = data.length - 1;
-	}
 
 	memcpy(msg.ssid.data.data, ssid, data.length);
 	msg.ssid.data.len = data.length;
 
-	result = p80211req_dorequest(wlandev, (u8*)&msg);
+	result = p80211req_dorequest(wlandev, (u8 *)&msg);
 
 	if (result) {
 		err = -EFAULT;
@@ -203,22 +188,20 @@
 
 exit:
 
-	DBFEXIT;
 	return err;
 
 }
 
 /* called by /proc/net/wireless */
-struct iw_statistics* p80211wext_get_wireless_stats (netdevice_t *dev)
+struct iw_statistics *p80211wext_get_wireless_stats(netdevice_t * dev)
 {
-	p80211msg_lnxreq_commsquality_t  quality;
+	p80211msg_lnxreq_commsquality_t quality;
 	wlandevice_t *wlandev = dev->ml_priv;
-	struct iw_statistics* wstats = &wlandev->wstats;
+	struct iw_statistics *wstats = &wlandev->wstats;
 	int retval;
 
-	DBFENTER;
 	/* Check */
-	if ( (wlandev == NULL) || (wlandev->msdstate != WLAN_MSD_RUNNING) )
+	if ((wlandev == NULL) || (wlandev->msdstate != WLAN_MSD_RUNNING))
 		return NULL;
 
 	/* XXX Only valid in station mode */
@@ -230,26 +213,24 @@
 	quality.dbm.status = P80211ENUM_msgitem_status_data_ok;
 
 	/* send message to nsd */
-	if ( wlandev->mlmerequest == NULL )
+	if (wlandev->mlmerequest == NULL)
 		return NULL;
 
-	retval = wlandev->mlmerequest(wlandev, (p80211msg_t*) &quality);
+	retval = wlandev->mlmerequest(wlandev, (p80211msg_t *)&quality);
 
-	wstats->qual.qual = qual_as_percent(quality.link.data);    /* overall link quality */
-	wstats->qual.level = quality.level.data;  /* instant signal level */
-	wstats->qual.noise = quality.noise.data;  /* instant noise level */
+	wstats->qual.qual = qual_as_percent(quality.link.data);	/* overall link quality */
+	wstats->qual.level = quality.level.data;	/* instant signal level */
+	wstats->qual.noise = quality.noise.data;	/* instant noise level */
 
 	wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
 	wstats->discard.code = wlandev->rx.decrypt_err;
 	wstats->discard.nwid = 0;
 	wstats->discard.misc = 0;
 
-	wstats->discard.fragment = 0;  // incomplete fragments
-	wstats->discard.retries = 0;   // tx retries.
+	wstats->discard.fragment = 0;	/* incomplete fragments */
+	wstats->discard.retries = 0;	/* tx retries. */
 	wstats->miss.beacon = 0;
 
-	DBFEXIT;
-
 	return wstats;
 }
 
@@ -261,8 +242,6 @@
 	int result;
 	int err = 0;
 
-	DBFENTER;
-
 	result = p80211wext_giwrate(dev, NULL, &rate, NULL);
 
 	if (result) {
@@ -281,7 +260,6 @@
 		break;
 	}
 exit:
-	DBFEXIT;
 	return err;
 }
 
@@ -290,17 +268,15 @@
 			      struct iw_freq *freq, char *extra)
 {
 	wlandevice_t *wlandev = dev->ml_priv;
-	p80211item_uint32_t             mibitem;
-	p80211msg_dot11req_mibset_t     msg;
+	p80211item_uint32_t mibitem;
+	p80211msg_dot11req_mibset_t msg;
 	int result;
 	int err = 0;
 
-	DBFENTER;
-
 	msg.msgcode = DIDmsg_dot11req_mibget;
 	mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel;
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8*)&msg);
+	result = p80211req_dorequest(wlandev, (u8 *)&msg);
 
 	if (result) {
 		err = -EFAULT;
@@ -318,8 +294,7 @@
 	freq->e = 1;
 	freq->m = p80211_channel_to_mhz(mibitem.data, 0) * 100000;
 
- exit:
-	DBFEXIT;
+exit:
 	return err;
 }
 
@@ -328,13 +303,11 @@
 			      struct iw_freq *freq, char *extra)
 {
 	wlandevice_t *wlandev = dev->ml_priv;
-	p80211item_uint32_t             mibitem;
-	p80211msg_dot11req_mibset_t     msg;
+	p80211item_uint32_t mibitem;
+	p80211msg_dot11req_mibset_t msg;
 	int result;
 	int err = 0;
 
-	DBFENTER;
-
 	if (!wlan_wext_write) {
 		err = (-EOPNOTSUPP);
 		goto exit;
@@ -344,21 +317,20 @@
 	mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel;
 	mibitem.status = P80211ENUM_msgitem_status_data_ok;
 
-	if ( (freq->e == 0) && (freq->m <= 1000) )
+	if ((freq->e == 0) && (freq->m <= 1000))
 		mibitem.data = freq->m;
 	else
 		mibitem.data = p80211_mhz_to_channel(freq->m);
 
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8*)&msg);
+	result = p80211req_dorequest(wlandev, (u8 *)&msg);
 
 	if (result) {
 		err = -EFAULT;
 		goto exit;
 	}
 
- exit:
-	DBFEXIT;
+exit:
 	return err;
 }
 
@@ -368,8 +340,6 @@
 {
 	wlandevice_t *wlandev = dev->ml_priv;
 
-	DBFENTER;
-
 	switch (wlandev->macmode) {
 	case WLAN_MACMODE_IBSS_STA:
 		*mode = IW_MODE_ADHOC;
@@ -385,7 +355,6 @@
 		*mode = IW_MODE_AUTO;
 	}
 
-	DBFEXIT;
 	return 0;
 }
 
@@ -394,12 +363,10 @@
 			      __u32 *mode, char *extra)
 {
 	wlandevice_t *wlandev = dev->ml_priv;
-	p80211item_uint32_t             mibitem;
-	p80211msg_dot11req_mibset_t     msg;
-	int 	result;
-	int     err = 0;
-
-	DBFENTER;
+	p80211item_uint32_t mibitem;
+	p80211msg_dot11req_mibset_t msg;
+	int result;
+	int err = 0;
 
 	if (!wlan_wext_write) {
 		err = (-EOPNOTSUPP);
@@ -428,7 +395,7 @@
 		break;
 	default:
 		/* Not set yet. */
-		WLAN_LOG_INFO("Operation mode: %d not support\n", *mode);
+		printk(KERN_INFO "Operation mode: %d not support\n", *mode);
 		return -EOPNOTSUPP;
 	}
 
@@ -437,33 +404,28 @@
 	mibitem.did = DIDmib_p2_p2Static_p2CnfPortType;
 	mibitem.data = (*mode == IW_MODE_ADHOC) ? 0 : 1;
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8*)&msg);
+	result = p80211req_dorequest(wlandev, (u8 *)&msg);
 
 	if (result)
 		err = -EFAULT;
 
- exit:
-	DBFEXIT;
-
+exit:
 	return err;
 }
 
-
 static int p80211wext_giwrange(netdevice_t *dev,
 			       struct iw_request_info *info,
 			       struct iw_point *data, char *extra)
 {
-        struct iw_range *range = (struct iw_range *) extra;
+	struct iw_range *range = (struct iw_range *)extra;
 	int i, val;
 
-	DBFENTER;
-
-	// for backward compatability set size & zero everything we don't understand
+	/* for backward compatability set size and zero everything we don't understand */
 	data->length = sizeof(*range);
-	memset(range,0,sizeof(*range));
+	memset(range, 0, sizeof(*range));
 
 	range->txpower_capa = IW_TXPOW_DBM;
-	// XXX what about min/max_pmp, min/max_pmt, etc.
+	/* XXX what about min/max_pmp, min/max_pmt, etc. */
 
 	range->we_version_compiled = WIRELESS_EXT;
 	range->we_version_source = 13;
@@ -473,18 +435,18 @@
 	range->min_retry = 0;
 	range->max_retry = 255;
 
-        range->event_capa[0] = (IW_EVENT_CAPA_K_0 |  //mode/freq/ssid
-                                IW_EVENT_CAPA_MASK(SIOCGIWAP) |
-                                IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
-        range->event_capa[1] = IW_EVENT_CAPA_K_1;  //encode
-        range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVQUAL) |
-                                IW_EVENT_CAPA_MASK(IWEVCUSTOM) );
+	range->event_capa[0] = (IW_EVENT_CAPA_K_0 |	/* mode/freq/ssid */
+				IW_EVENT_CAPA_MASK(SIOCGIWAP) |
+				IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
+	range->event_capa[1] = IW_EVENT_CAPA_K_1;	/* encode */
+	range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVQUAL) |
+				IW_EVENT_CAPA_MASK(IWEVCUSTOM));
 
 	range->num_channels = NUM_CHANNELS;
 
 	/* XXX need to filter against the regulatory domain &| active set */
 	val = 0;
-	for (i = 0; i < NUM_CHANNELS ; i++) {
+	for (i = 0; i < NUM_CHANNELS; i++) {
 		range->freq[val].i = i + 1;
 		range->freq[val].m = p80211wext_channel_freq[i] * 100000;
 		range->freq[val].e = 1;
@@ -498,7 +460,7 @@
 	range->max_qual.level = 0;
 	range->max_qual.noise = 0;
 	range->sensitivity = 3;
-	// XXX these need to be nsd-specific!
+	/* XXX these need to be nsd-specific! */
 
 	range->min_rts = 0;
 	range->max_rts = 2347;
@@ -510,14 +472,13 @@
 	range->encoding_size[0] = 5;
 	range->encoding_size[1] = 13;
 
-	// XXX what about num_bitrates/throughput?
+	/* XXX what about num_bitrates/throughput? */
 	range->num_bitrates = 0;
 
 	/* estimated max throughput */
-	// XXX need to cap it if we're running at ~2Mbps..
+	/* XXX need to cap it if we're running at ~2Mbps.. */
 	range->throughput = 5500000;
 
-	DBFEXIT;
 	return 0;
 }
 
@@ -528,12 +489,9 @@
 
 	wlandevice_t *wlandev = dev->ml_priv;
 
-	DBFENTER;
-
 	memcpy(ap_addr->sa_data, wlandev->bssid, WLAN_BSSID_LEN);
 	ap_addr->sa_family = ARPHRD_ETHER;
 
-	DBFEXIT;
 	return 0;
 }
 
@@ -545,8 +503,6 @@
 	int err = 0;
 	int i;
 
-	DBFENTER;
-
 	i = (erq->flags & IW_ENCODE_INDEX) - 1;
 	erq->flags = 0;
 
@@ -576,8 +532,7 @@
 	erq->length = wlandev->wep_keylens[i];
 	memcpy(key, wlandev->wep_keys[i], erq->length);
 
- exit:
-	DBFEXIT;
+exit:
 	return err;
 }
 
@@ -586,32 +541,33 @@
 				struct iw_point *erq, char *key)
 {
 	wlandevice_t *wlandev = dev->ml_priv;
-	p80211msg_dot11req_mibset_t	msg;
-	p80211item_pstr32_t		pstr;
+	p80211msg_dot11req_mibset_t msg;
+	p80211item_pstr32_t pstr;
 
 	int err = 0;
 	int result = 0;
 	int i;
 
-	DBFENTER;
 	if (!wlan_wext_write) {
 		err = (-EOPNOTSUPP);
 		goto exit;
 	}
 
 	/* Check the Key index first. */
-	if((i = (erq->flags & IW_ENCODE_INDEX))) {
+	if ((i = (erq->flags & IW_ENCODE_INDEX))) {
 
 		if ((i < 1) || (i > NUM_WEPKEYS)) {
 			err = -EINVAL;
 			goto exit;
-		}
-		else
+		} else
 			i--;
 
 		/* Set current key number only if no keys are given */
 		if (erq->flags & IW_ENCODE_NOKEY) {
-			result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID, i);
+			result =
+			    p80211wext_dorequest(wlandev,
+						 DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
+						 i);
 
 			if (result) {
 				err = -EFAULT;
@@ -620,12 +576,12 @@
 		}
 
 	} else {
-		// Use defaultkey if no Key Index
+		/* Use defaultkey if no Key Index */
 		i = wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK;
 	}
 
 	/* Check if there is no key information in the iwconfig request */
-	if((erq->flags & IW_ENCODE_NOKEY) == 0 ) {
+	if ((erq->flags & IW_ENCODE_NOKEY) == 0) {
 
 		/*------------------------------------------------------------
 		 * If there is WEP Key for setting, check the Key Information
@@ -642,32 +598,35 @@
 			memcpy(pstr.data.data, key, erq->length);
 			pstr.data.len = erq->length;
 
-			switch(i)
-			{
-				case 0:
-					pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
-					break;
+			switch (i) {
+			case 0:
+				pstr.did =
+				    DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
+				break;
 
-				case 1:
-					pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
-					break;
+			case 1:
+				pstr.did =
+				    DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
+				break;
 
-				case 2:
-					pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
-					break;
+			case 2:
+				pstr.did =
+				    DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
+				break;
 
-				case 3:
-					pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
-					break;
+			case 3:
+				pstr.did =
+				    DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
+				break;
 
-				default:
-					err = -EINVAL;
-					goto exit;
+			default:
+				err = -EINVAL;
+				goto exit;
 			}
 
 			msg.msgcode = DIDmsg_dot11req_mibset;
 			memcpy(&msg.mibattribute.data, &pstr, sizeof(pstr));
-			result = p80211req_dorequest(wlandev, (u8*)&msg);
+			result = p80211req_dorequest(wlandev, (u8 *)&msg);
 
 			if (result) {
 				err = -EFAULT;
@@ -679,9 +638,15 @@
 
 	/* Check the PrivacyInvoked flag */
 	if (erq->flags & IW_ENCODE_DISABLED) {
-		result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_false);
+		result =
+		    p80211wext_dorequest(wlandev,
+					 DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
+					 P80211ENUM_truth_false);
 	} else {
-		result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_true);
+		result =
+		    p80211wext_dorequest(wlandev,
+					 DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
+					 P80211ENUM_truth_true);
 	}
 
 	if (result) {
@@ -690,17 +655,22 @@
 	}
 
 	/*  The  security  mode  may  be open or restricted, and its meaning
-	    depends on the card used. With  most  cards,  in  open  mode  no
-	    authentication  is  used  and  the  card  may  also  accept non-
-	    encrypted sessions, whereas in restricted  mode  only  encrypted
-	    sessions  are  accepted  and the card will use authentication if
-	    available.
-	*/
+	   depends on the card used. With  most  cards,  in  open  mode  no
+	   authentication  is  used  and  the  card  may  also  accept non-
+	   encrypted sessions, whereas in restricted  mode  only  encrypted
+	   sessions  are  accepted  and the card will use authentication if
+	   available.
+	 */
 	if (erq->flags & IW_ENCODE_RESTRICTED) {
-		result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_true);
-	}
-	else if (erq->flags & IW_ENCODE_OPEN) {
-		result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_false);
+		result =
+		    p80211wext_dorequest(wlandev,
+					 DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
+					 P80211ENUM_truth_true);
+	} else if (erq->flags & IW_ENCODE_OPEN) {
+		result =
+		    p80211wext_dorequest(wlandev,
+					 DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
+					 P80211ENUM_truth_false);
 	}
 
 	if (result) {
@@ -708,9 +678,8 @@
 		goto exit;
 	}
 
- exit:
+exit:
 
-	DBFEXIT;
 	return err;
 }
 
@@ -720,8 +689,6 @@
 {
 	wlandevice_t *wlandev = dev->ml_priv;
 
-	DBFENTER;
-
 	if (wlandev->ssid.len) {
 		data->length = wlandev->ssid.len;
 		data->flags = 1;
@@ -731,12 +698,11 @@
 		data->length++;
 #endif
 	} else {
-	  	memset(essid, 0, sizeof(wlandev->ssid.data));
+		memset(essid, 0, sizeof(wlandev->ssid.data));
 		data->length = 0;
 		data->flags = 0;
 	}
 
-	DBFEXIT;
 	return 0;
 }
 
@@ -745,55 +711,49 @@
 			       struct iw_point *data, char *essid)
 {
 	wlandevice_t *wlandev = dev->ml_priv;
-	p80211msg_lnxreq_autojoin_t     msg;
+	p80211msg_lnxreq_autojoin_t msg;
 
 	int result;
 	int err = 0;
 	int length = data->length;
 
-	DBFENTER;
-
 	if (!wlan_wext_write) {
 		err = (-EOPNOTSUPP);
 		goto exit;
 	}
 
-
-	if ( wlandev->hostwep & HOSTWEP_SHAREDKEY )
-	  msg.authtype.data = P80211ENUM_authalg_sharedkey;
+	if (wlandev->hostwep & HOSTWEP_SHAREDKEY)
+		msg.authtype.data = P80211ENUM_authalg_sharedkey;
 	else
-	  msg.authtype.data = P80211ENUM_authalg_opensystem;
+		msg.authtype.data = P80211ENUM_authalg_opensystem;
 
 	msg.msgcode = DIDmsg_lnxreq_autojoin;
 
 #if (WIRELESS_EXT < 21)
-	if (length) length--;
+	if (length)
+		length--;
 #endif
 
 	/* Trim the last '\0' to fit the SSID format */
-
-	if (length && essid[length-1] == '\0') {
-	  length--;
-	}
+	if (length && essid[length - 1] == '\0')
+		length--;
 
 	memcpy(msg.ssid.data.data, essid, length);
 	msg.ssid.data.len = length;
 
-	WLAN_LOG_DEBUG(1,"autojoin_ssid for %s \n",essid);
-	result = p80211req_dorequest(wlandev, (u8*)&msg);
-        WLAN_LOG_DEBUG(1,"autojoin_ssid %d\n",result);
+	pr_debug("autojoin_ssid for %s \n", essid);
+	result = p80211req_dorequest(wlandev, (u8 *)&msg);
+	pr_debug("autojoin_ssid %d\n", result);
 
 	if (result) {
 		err = -EFAULT;
 		goto exit;
 	}
 
- exit:
-	DBFEXIT;
+exit:
 	return err;
 }
 
-
 static int p80211wext_siwcommit(netdevice_t *dev,
 				struct iw_request_info *info,
 				struct iw_point *data, char *essid)
@@ -801,8 +761,6 @@
 	wlandevice_t *wlandev = dev->ml_priv;
 	int err = 0;
 
-	DBFENTER;
-
 	if (!wlan_wext_write) {
 		err = (-EOPNOTSUPP);
 		goto exit;
@@ -811,28 +769,24 @@
 	/* Auto Join */
 	err = p80211wext_autojoin(wlandev);
 
- exit:
- 	DBFEXIT;
+exit:
 	return err;
 }
 
-
 static int p80211wext_giwrate(netdevice_t *dev,
 			      struct iw_request_info *info,
 			      struct iw_param *rrq, char *extra)
 {
 	wlandevice_t *wlandev = dev->ml_priv;
-	p80211item_uint32_t             mibitem;
-	p80211msg_dot11req_mibset_t     msg;
+	p80211item_uint32_t mibitem;
+	p80211msg_dot11req_mibset_t msg;
 	int result;
 	int err = 0;
 
-	DBFENTER;
-
 	msg.msgcode = DIDmsg_dot11req_mibget;
 	mibitem.did = DIDmib_p2_p2MAC_p2CurrentTxRate;
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8*)&msg);
+	result = p80211req_dorequest(wlandev, (u8 *)&msg);
 
 	if (result) {
 		err = -EFAULT;
@@ -841,7 +795,7 @@
 
 	memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
 
-	rrq->fixed = 0;   /* can it change? */
+	rrq->fixed = 0;		/* can it change? */
 	rrq->disabled = 0;
 	rrq->value = 0;
 
@@ -866,8 +820,7 @@
 	default:
 		err = -EINVAL;
 	}
- exit:
-	DBFEXIT;
+exit:
 	return err;
 }
 
@@ -876,17 +829,15 @@
 			     struct iw_param *rts, char *extra)
 {
 	wlandevice_t *wlandev = dev->ml_priv;
-	p80211item_uint32_t             mibitem;
-	p80211msg_dot11req_mibset_t     msg;
+	p80211item_uint32_t mibitem;
+	p80211msg_dot11req_mibset_t msg;
 	int result;
 	int err = 0;
 
-	DBFENTER;
-
 	msg.msgcode = DIDmsg_dot11req_mibget;
 	mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold;
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8*)&msg);
+	result = p80211req_dorequest(wlandev, (u8 *)&msg);
 
 	if (result) {
 		err = -EFAULT;
@@ -899,24 +850,20 @@
 	rts->disabled = (rts->value == 2347);
 	rts->fixed = 1;
 
- exit:
-	DBFEXIT;
+exit:
 	return err;
 }
 
-
 static int p80211wext_siwrts(netdevice_t *dev,
 			     struct iw_request_info *info,
 			     struct iw_param *rts, char *extra)
 {
 	wlandevice_t *wlandev = dev->ml_priv;
-	p80211item_uint32_t             mibitem;
-	p80211msg_dot11req_mibset_t     msg;
+	p80211item_uint32_t mibitem;
+	p80211msg_dot11req_mibset_t msg;
 	int result;
 	int err = 0;
 
-	DBFENTER;
-
 	if (!wlan_wext_write) {
 		err = (-EOPNOTSUPP);
 		goto exit;
@@ -930,15 +877,14 @@
 		mibitem.data = rts->value;
 
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8*)&msg);
+	result = p80211req_dorequest(wlandev, (u8 *)&msg);
 
 	if (result) {
 		err = -EFAULT;
 		goto exit;
 	}
 
- exit:
-	DBFEXIT;
+exit:
 	return err;
 }
 
@@ -947,17 +893,16 @@
 			      struct iw_param *frag, char *extra)
 {
 	wlandevice_t *wlandev = dev->ml_priv;
-	p80211item_uint32_t             mibitem;
-	p80211msg_dot11req_mibset_t     msg;
+	p80211item_uint32_t mibitem;
+	p80211msg_dot11req_mibset_t msg;
 	int result;
 	int err = 0;
 
-	DBFENTER;
-
 	msg.msgcode = DIDmsg_dot11req_mibget;
-	mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold;
+	mibitem.did =
+	    DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold;
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8*)&msg);
+	result = p80211req_dorequest(wlandev, (u8 *)&msg);
 
 	if (result) {
 		err = -EFAULT;
@@ -970,8 +915,7 @@
 	frag->disabled = (frag->value == 2346);
 	frag->fixed = 1;
 
- exit:
-	DBFEXIT;
+exit:
 	return err;
 }
 
@@ -980,20 +924,19 @@
 			      struct iw_param *frag, char *extra)
 {
 	wlandevice_t *wlandev = dev->ml_priv;
-	p80211item_uint32_t             mibitem;
-	p80211msg_dot11req_mibset_t     msg;
+	p80211item_uint32_t mibitem;
+	p80211msg_dot11req_mibset_t msg;
 	int result;
 	int err = 0;
 
-	DBFENTER;
-
 	if (!wlan_wext_write) {
 		err = (-EOPNOTSUPP);
 		goto exit;
 	}
 
 	msg.msgcode = DIDmsg_dot11req_mibset;
-	mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold;
+	mibitem.did =
+	    DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold;
 
 	if (frag->disabled)
 		mibitem.data = 2346;
@@ -1001,15 +944,14 @@
 		mibitem.data = frag->value;
 
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8*)&msg);
+	result = p80211req_dorequest(wlandev, (u8 *)&msg);
 
 	if (result) {
 		err = -EFAULT;
 		goto exit;
 	}
 
- exit:
-	DBFEXIT;
+exit:
 	return err;
 }
 
@@ -1026,19 +968,17 @@
 			       struct iw_param *rrq, char *extra)
 {
 	wlandevice_t *wlandev = dev->ml_priv;
-	p80211item_uint32_t             mibitem;
-	p80211msg_dot11req_mibset_t     msg;
+	p80211item_uint32_t mibitem;
+	p80211msg_dot11req_mibset_t msg;
 	int result;
 	int err = 0;
 	u16 shortretry, longretry, lifetime;
 
-	DBFENTER;
-
 	msg.msgcode = DIDmsg_dot11req_mibget;
 	mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit;
 
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8*)&msg);
+	result = p80211req_dorequest(wlandev, (u8 *)&msg);
 
 	if (result) {
 		err = -EFAULT;
@@ -1052,7 +992,7 @@
 	mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit;
 
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8*)&msg);
+	result = p80211req_dorequest(wlandev, (u8 *)&msg);
 
 	if (result) {
 		err = -EFAULT;
@@ -1063,10 +1003,11 @@
 
 	longretry = mibitem.data;
 
-	mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime;
+	mibitem.did =
+	    DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime;
 
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8*)&msg);
+	result = p80211req_dorequest(wlandev, (u8 *)&msg);
 
 	if (result) {
 		err = -EFAULT;
@@ -1094,8 +1035,7 @@
 		}
 	}
 
- exit:
-	DBFEXIT;
+exit:
 	return err;
 
 }
@@ -1105,13 +1045,11 @@
 			       struct iw_param *rrq, char *extra)
 {
 	wlandevice_t *wlandev = dev->ml_priv;
-	p80211item_uint32_t             mibitem;
-	p80211msg_dot11req_mibset_t     msg;
+	p80211item_uint32_t mibitem;
+	p80211msg_dot11req_mibset_t msg;
 	int result;
 	int err = 0;
 
-	DBFENTER;
-
 	if (!wlan_wext_write) {
 		err = (-EOPNOTSUPP);
 		goto exit;
@@ -1125,11 +1063,12 @@
 	msg.msgcode = DIDmsg_dot11req_mibset;
 
 	if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
-		mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime;
-		mibitem.data =  rrq->value /= 1024;
+		mibitem.did =
+		    DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime;
+		mibitem.data = rrq->value /= 1024;
 
 		memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-		result = p80211req_dorequest(wlandev, (u8*)&msg);
+		result = p80211req_dorequest(wlandev, (u8 *)&msg);
 
 		if (result) {
 			err = -EFAULT;
@@ -1137,11 +1076,13 @@
 		}
 	} else {
 		if (rrq->flags & IW_RETRY_LONG) {
-			mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit;
+			mibitem.did =
+			    DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit;
 			mibitem.data = rrq->value;
 
-			memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-			result = p80211req_dorequest(wlandev, (u8*)&msg);
+			memcpy(&msg.mibattribute.data, &mibitem,
+			       sizeof(mibitem));
+			result = p80211req_dorequest(wlandev, (u8 *)&msg);
 
 			if (result) {
 				err = -EFAULT;
@@ -1150,11 +1091,13 @@
 		}
 
 		if (rrq->flags & IW_RETRY_SHORT) {
-			mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit;
+			mibitem.did =
+			    DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit;
 			mibitem.data = rrq->value;
 
-			memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-			result = p80211req_dorequest(wlandev, (u8*)&msg);
+			memcpy(&msg.mibattribute.data, &mibitem,
+			       sizeof(mibitem));
+			result = p80211req_dorequest(wlandev, (u8 *)&msg);
 
 			if (result) {
 				err = -EFAULT;
@@ -1163,46 +1106,43 @@
 		}
 	}
 
- exit:
-	DBFEXIT;
+exit:
 	return err;
 
 }
 
 static int p80211wext_siwtxpow(netdevice_t *dev,
-                               struct iw_request_info *info,
-                               struct iw_param *rrq, char *extra)
+			       struct iw_request_info *info,
+			       struct iw_param *rrq, char *extra)
 {
 	wlandevice_t *wlandev = dev->ml_priv;
-        p80211item_uint32_t             mibitem;
-        p80211msg_dot11req_mibset_t     msg;
-        int result;
-        int err = 0;
+	p80211item_uint32_t mibitem;
+	p80211msg_dot11req_mibset_t msg;
+	int result;
+	int err = 0;
 
-        DBFENTER;
+	if (!wlan_wext_write) {
+		err = (-EOPNOTSUPP);
+		goto exit;
+	}
 
-       if (!wlan_wext_write) {
-                err = (-EOPNOTSUPP);
-                goto exit;
-        }
-
-        msg.msgcode = DIDmsg_dot11req_mibset;
-	mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;
+	msg.msgcode = DIDmsg_dot11req_mibset;
+	mibitem.did =
+	    DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;
 	if (rrq->fixed == 0)
-	  mibitem.data = 30;
+		mibitem.data = 30;
 	else
-	  mibitem.data = rrq->value;
-        memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-        result = p80211req_dorequest(wlandev, (u8*)&msg);
+		mibitem.data = rrq->value;
+	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+	result = p80211req_dorequest(wlandev, (u8 *)&msg);
 
-        if (result) {
-                err = -EFAULT;
-                goto exit;
-        }
+	if (result) {
+		err = -EFAULT;
+		goto exit;
+	}
 
- exit:
-        DBFEXIT;
-        return err;
+exit:
+	return err;
 }
 
 static int p80211wext_giwtxpow(netdevice_t *dev,
@@ -1210,18 +1150,17 @@
 			       struct iw_param *rrq, char *extra)
 {
 	wlandevice_t *wlandev = dev->ml_priv;
-	p80211item_uint32_t             mibitem;
-	p80211msg_dot11req_mibset_t     msg;
+	p80211item_uint32_t mibitem;
+	p80211msg_dot11req_mibset_t msg;
 	int result;
 	int err = 0;
 
-	DBFENTER;
-
 	msg.msgcode = DIDmsg_dot11req_mibget;
-	mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;
+	mibitem.did =
+	    DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;
 
 	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
-	result = p80211req_dorequest(wlandev, (u8*)&msg);
+	result = p80211req_dorequest(wlandev, (u8 *)&msg);
 
 	if (result) {
 		err = -EFAULT;
@@ -1230,15 +1169,14 @@
 
 	memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
 
-	// XXX handle OFF by setting disabled = 1;
+	/* XXX handle OFF by setting disabled = 1; */
 
-	rrq->flags = 0; // IW_TXPOW_DBM;
+	rrq->flags = 0;		/* IW_TXPOW_DBM; */
 	rrq->disabled = 0;
 	rrq->fixed = 0;
 	rrq->value = mibitem.data;
 
- exit:
-	DBFEXIT;
+exit:
 	return err;
 }
 
@@ -1247,33 +1185,32 @@
 			     struct iw_point *srq, char *extra)
 {
 	wlandevice_t *wlandev = dev->ml_priv;
-        struct sockaddr address[IW_MAX_SPY];
-        int number = srq->length;
-        int i;
-
-	DBFENTER;
+	struct sockaddr address[IW_MAX_SPY];
+	int number = srq->length;
+	int i;
 
 	/* Copy the data from the input buffer */
-	memcpy(address, extra, sizeof(struct sockaddr)*number);
+	memcpy(address, extra, sizeof(struct sockaddr) * number);
 
-        wlandev->spy_number = 0;
+	wlandev->spy_number = 0;
 
-        if (number > 0) {
+	if (number > 0) {
 
-                /* extract the addresses */
-                for (i = 0; i < number; i++) {
+		/* extract the addresses */
+		for (i = 0; i < number; i++) {
 
-                        memcpy(wlandev->spy_address[i], address[i].sa_data, ETH_ALEN);
+			memcpy(wlandev->spy_address[i], address[i].sa_data,
+			       ETH_ALEN);
 		}
 
-                /* reset stats */
-                memset(wlandev->spy_stat, 0, sizeof(struct iw_quality) * IW_MAX_SPY);
+		/* reset stats */
+		memset(wlandev->spy_stat, 0,
+		       sizeof(struct iw_quality) * IW_MAX_SPY);
 
-                /* set number of addresses */
-                wlandev->spy_number = number;
-        }
+		/* set number of addresses */
+		wlandev->spy_number = number;
+	}
 
-	DBFEXIT;
 	return 0;
 }
 
@@ -1284,74 +1221,72 @@
 {
 	wlandevice_t *wlandev = dev->ml_priv;
 
-        struct sockaddr address[IW_MAX_SPY];
-        struct iw_quality spy_stat[IW_MAX_SPY];
-        int number;
-        int i;
+	struct sockaddr address[IW_MAX_SPY];
+	struct iw_quality spy_stat[IW_MAX_SPY];
+	int number;
+	int i;
 
-	DBFENTER;
+	number = wlandev->spy_number;
 
-        number = wlandev->spy_number;
+	if (number > 0) {
 
-        if (number > 0) {
-
-                /* populate address and spy struct's */
-                for (i = 0; i < number; i++) {
-                        memcpy(address[i].sa_data, wlandev->spy_address[i], ETH_ALEN);
-                        address[i].sa_family = AF_UNIX;
-                	memcpy(&spy_stat[i], &wlandev->spy_stat[i], sizeof(struct iw_quality));
-                }
+		/* populate address and spy struct's */
+		for (i = 0; i < number; i++) {
+			memcpy(address[i].sa_data, wlandev->spy_address[i],
+			       ETH_ALEN);
+			address[i].sa_family = AF_UNIX;
+			memcpy(&spy_stat[i], &wlandev->spy_stat[i],
+			       sizeof(struct iw_quality));
+		}
 
 		/* reset update flag */
-                for (i=0; i < number; i++)
-                        wlandev->spy_stat[i].updated = 0;
-        }
+		for (i = 0; i < number; i++)
+			wlandev->spy_stat[i].updated = 0;
+	}
 
-        /* push stuff to user space */
-        srq->length = number;
-	memcpy(extra, address, sizeof(struct sockaddr)*number);
-	memcpy(extra+sizeof(struct sockaddr)*number, spy_stat, sizeof(struct iw_quality)*number);
+	/* push stuff to user space */
+	srq->length = number;
+	memcpy(extra, address, sizeof(struct sockaddr) * number);
+	memcpy(extra + sizeof(struct sockaddr) * number, spy_stat,
+	       sizeof(struct iw_quality) * number);
 
-	DBFEXIT;
 	return 0;
 }
 
-static int prism2_result2err (int prism2_result)
+static int prism2_result2err(int prism2_result)
 {
 	int err = 0;
 
 	switch (prism2_result) {
-		case P80211ENUM_resultcode_invalid_parameters:
-			err = -EINVAL;
-			break;
-		case P80211ENUM_resultcode_implementation_failure:
-			err = -EIO;
-			break;
-		case P80211ENUM_resultcode_not_supported:
-			err = -EOPNOTSUPP;
-			break;
-		default:
-			err = 0;
-			break;
+	case P80211ENUM_resultcode_invalid_parameters:
+		err = -EINVAL;
+		break;
+	case P80211ENUM_resultcode_implementation_failure:
+		err = -EIO;
+		break;
+	case P80211ENUM_resultcode_not_supported:
+		err = -EOPNOTSUPP;
+		break;
+	default:
+		err = 0;
+		break;
 	}
 
 	return err;
 }
 
 static int p80211wext_siwscan(netdevice_t *dev,
-			     struct iw_request_info *info,
-			     struct iw_point *srq, char *extra)
+			      struct iw_request_info *info,
+			      struct iw_point *srq, char *extra)
 {
 	wlandevice_t *wlandev = dev->ml_priv;
-	p80211msg_dot11req_scan_t	msg;
+	p80211msg_dot11req_scan_t msg;
 	int result;
 	int err = 0;
 	int i = 0;
 
-	DBFENTER;
-
 	if (wlandev->macmode == WLAN_MACMODE_ESS_AP) {
-		WLAN_LOG_ERROR("Can't scan in AP mode\n");
+		printk(KERN_ERR "Can't scan in AP mode\n");
 		err = (-EOPNOTSUPP);
 		goto exit;
 	}
@@ -1360,36 +1295,34 @@
 	msg.msgcode = DIDmsg_dot11req_scan;
 	msg.bsstype.data = P80211ENUM_bsstype_any;
 
-	memset(&(msg.bssid.data), 0xFF, sizeof (p80211item_pstr6_t));
+	memset(&(msg.bssid.data), 0xFF, sizeof(p80211item_pstr6_t));
 	msg.bssid.data.len = 6;
 
 	msg.scantype.data = P80211ENUM_scantype_active;
 	msg.probedelay.data = 0;
 
 	for (i = 1; i <= 14; i++)
-		msg.channellist.data.data[i-1] = i;
+		msg.channellist.data.data[i - 1] = i;
 	msg.channellist.data.len = 14;
 
 	msg.maxchanneltime.data = 250;
 	msg.minchanneltime.data = 200;
 
-	result = p80211req_dorequest(wlandev, (u8*)&msg);
+	result = p80211req_dorequest(wlandev, (u8 *)&msg);
 	if (result)
-		err = prism2_result2err (msg.resultcode.data);
+		err = prism2_result2err(msg.resultcode.data);
 
- exit:
-	DBFEXIT;
+exit:
 	return err;
 }
 
-
 /* Helper to translate scan into Wireless Extensions scan results.
  * Inspired by the prism54 code, which was in turn inspired by the
  * airo driver code.
  */
-static char *
-wext_translate_bss(struct iw_request_info *info, char *current_ev,
-		   char *end_buf, p80211msg_dot11req_scan_results_t *bss)
+static char *wext_translate_bss(struct iw_request_info *info, char *current_ev,
+				char *end_buf,
+				p80211msg_dot11req_scan_results_t *bss)
 {
 	struct iw_event iwe;	/* Temporary buffer */
 
@@ -1397,7 +1330,9 @@
 	memcpy(iwe.u.ap_addr.sa_data, bss->bssid.data.data, WLAN_BSSID_LEN);
 	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
 	iwe.cmd = SIOCGIWAP;
-	current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+	current_ev =
+	    iwe_stream_add_event(info, current_ev, end_buf, &iwe,
+				 IW_EV_ADDR_LEN);
 
 	/* The following entries will be displayed in the same order we give them */
 
@@ -1406,33 +1341,39 @@
 		char essid[IW_ESSID_MAX_SIZE + 1];
 		int size;
 
-		size = wlan_min(IW_ESSID_MAX_SIZE, bss->ssid.data.len);
-		memset(&essid, 0, sizeof (essid));
+		size =
+		    min_t(unsigned short, IW_ESSID_MAX_SIZE,
+			  bss->ssid.data.len);
+		memset(&essid, 0, sizeof(essid));
 		memcpy(&essid, bss->ssid.data.data, size);
-		WLAN_LOG_DEBUG(1, " essid size = %d\n", size);
+		pr_debug(" essid size = %d\n", size);
 		iwe.u.data.length = size;
 		iwe.u.data.flags = 1;
 		iwe.cmd = SIOCGIWESSID;
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, &essid[0]);
-		WLAN_LOG_DEBUG(1, " essid size OK.\n");
+		current_ev =
+		    iwe_stream_add_point(info, current_ev, end_buf, &iwe,
+					 &essid[0]);
+		pr_debug(" essid size OK.\n");
 	}
 
 	switch (bss->bsstype.data) {
-		case P80211ENUM_bsstype_infrastructure:
-			iwe.u.mode = IW_MODE_MASTER;
-			break;
+	case P80211ENUM_bsstype_infrastructure:
+		iwe.u.mode = IW_MODE_MASTER;
+		break;
 
-		case P80211ENUM_bsstype_independent:
-			iwe.u.mode = IW_MODE_ADHOC;
-			break;
+	case P80211ENUM_bsstype_independent:
+		iwe.u.mode = IW_MODE_ADHOC;
+		break;
 
-		default:
-			iwe.u.mode = 0;
-			break;
+	default:
+		iwe.u.mode = 0;
+		break;
 	}
 	iwe.cmd = SIOCGIWMODE;
 	if (iwe.u.mode)
-		current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
+		current_ev =
+		    iwe_stream_add_event(info, current_ev, end_buf, &iwe,
+					 IW_EV_UINT_LEN);
 
 	/* Encryption capability */
 	if (bss->privacy.data == P80211ENUM_truth_true)
@@ -1441,13 +1382,16 @@
 		iwe.u.data.flags = IW_ENCODE_DISABLED;
 	iwe.u.data.length = 0;
 	iwe.cmd = SIOCGIWENCODE;
-	current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, NULL);
+	current_ev =
+	    iwe_stream_add_point(info, current_ev, end_buf, &iwe, NULL);
 
 	/* Add frequency. (short) bss->channel is the frequency in MHz */
 	iwe.u.freq.m = bss->dschannel.data;
 	iwe.u.freq.e = 0;
 	iwe.cmd = SIOCGIWFREQ;
-	current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
+	current_ev =
+	    iwe_stream_add_event(info, current_ev, end_buf, &iwe,
+				 IW_EV_FREQ_LEN);
 
 	/* Add quality statistics */
 	iwe.u.qual.level = bss->signal.data;
@@ -1455,26 +1399,25 @@
 	/* do a simple SNR for quality */
 	iwe.u.qual.qual = qual_as_percent(bss->signal.data - bss->noise.data);
 	iwe.cmd = IWEVQUAL;
-	current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+	current_ev =
+	    iwe_stream_add_event(info, current_ev, end_buf, &iwe,
+				 IW_EV_QUAL_LEN);
 
 	return current_ev;
 }
 
-
 static int p80211wext_giwscan(netdevice_t *dev,
-			     struct iw_request_info *info,
-			     struct iw_point *srq, char *extra)
+			      struct iw_request_info *info,
+			      struct iw_point *srq, char *extra)
 {
 	wlandevice_t *wlandev = dev->ml_priv;
-	p80211msg_dot11req_scan_results_t	msg;
+	p80211msg_dot11req_scan_results_t msg;
 	int result = 0;
 	int err = 0;
 	int i = 0;
 	int scan_good = 0;
 	char *current_ev = extra;
 
-	DBFENTER;
-
 	/* Since wireless tools doesn't really have a way of passing how
 	 * many scan results results there were back here, keep grabbing them
 	 * until we fail.
@@ -1484,110 +1427,115 @@
 		msg.msgcode = DIDmsg_dot11req_scan_results;
 		msg.bssindex.data = i;
 
-		result = p80211req_dorequest(wlandev, (u8*)&msg);
+		result = p80211req_dorequest(wlandev, (u8 *)&msg);
 		if ((result != 0) ||
 		    (msg.resultcode.data != P80211ENUM_resultcode_success)) {
 			break;
 		}
 
-		current_ev = wext_translate_bss(info, current_ev, extra + IW_SCAN_MAX_DATA, &msg);
+		current_ev =
+		    wext_translate_bss(info, current_ev,
+				       extra + IW_SCAN_MAX_DATA, &msg);
 		scan_good = 1;
 		i++;
 	} while (i < IW_MAX_AP);
 
 	srq->length = (current_ev - extra);
-	srq->flags = 0;	/* todo */
+	srq->flags = 0;		/* todo */
 
 	if (result && !scan_good)
-		err = prism2_result2err (msg.resultcode.data);
+		err = prism2_result2err(msg.resultcode.data);
 
-	DBFEXIT;
 	return err;
 }
 
-/*****************************************************/
-//extra wireless extensions stuff to support NetworkManager (I hope)
+/* extra wireless extensions stuff to support NetworkManager (I hope) */
 
 /* SIOCSIWENCODEEXT */
 static int p80211wext_set_encodeext(struct net_device *dev,
-				struct iw_request_info *info,
-				union iwreq_data *wrqu, char *extra)
+				    struct iw_request_info *info,
+				    union iwreq_data *wrqu, char *extra)
 {
-  wlandevice_t *wlandev = dev->ml_priv;
-  struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
-	p80211msg_dot11req_mibset_t	msg;
-	p80211item_pstr32_t		*pstr;
+	wlandevice_t *wlandev = dev->ml_priv;
+	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+	p80211msg_dot11req_mibset_t msg;
+	p80211item_pstr32_t *pstr;
 
-  int result = 0;
-  struct iw_point *encoding = &wrqu->encoding;
-  int idx = encoding->flags & IW_ENCODE_INDEX;
+	int result = 0;
+	struct iw_point *encoding = &wrqu->encoding;
+	int idx = encoding->flags & IW_ENCODE_INDEX;
 
-  WLAN_LOG_DEBUG(1,"set_encode_ext flags[%d] alg[%d] keylen[%d]\n",ext->ext_flags,(int)ext->alg,(int)ext->key_len);
+	pr_debug("set_encode_ext flags[%d] alg[%d] keylen[%d]\n",
+	       ext->ext_flags, (int)ext->alg, (int)ext->key_len);
 
+	if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
+		/* set default key ? I'm not sure if this the the correct thing to do here */
 
-  if ( ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY ) {
-    // set default key ? I'm not sure if this the the correct thing to do here
+		if (idx) {
+			if (idx < 1 || idx > NUM_WEPKEYS)
+				return -EINVAL;
+			else
+				idx--;
+		}
+		pr_debug("setting default key (%d)\n", idx);
+		result =
+		    p80211wext_dorequest(wlandev,
+					 DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
+					 idx);
+		if (result)
+			return -EFAULT;
+	}
 
-    if ( idx ) {
-      if (idx < 1 || idx > NUM_WEPKEYS) {
-	return -EINVAL;
-      } else
-	idx--;
-    }
-    WLAN_LOG_DEBUG(1,"setting default key (%d)\n",idx);
-    result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID, idx);
-    if ( result )
-      return -EFAULT;
-  }
+	if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+		if (!(ext->alg & IW_ENCODE_ALG_WEP)) {
+			pr_debug("asked to set a non wep key :(");
+			return -EINVAL;
+		}
+		if (idx) {
+			if (idx < 1 || idx > NUM_WEPKEYS)
+				return -EINVAL;
+			else
+				idx--;
+		}
+		pr_debug("Set WEP key (%d)\n", idx);
+		wlandev->wep_keylens[idx] = ext->key_len;
+		memcpy(wlandev->wep_keys[idx], ext->key, ext->key_len);
 
-
-  if ( ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY ) {
-    if (!(ext->alg & IW_ENCODE_ALG_WEP)) {
-      WLAN_LOG_DEBUG(1,"asked to set a non wep key :(");
-      return -EINVAL;
-    }
-    if (idx) {
-      if (idx <1 || idx > NUM_WEPKEYS)
-	return -EINVAL;
-      else
-	idx--;
-    }
-    WLAN_LOG_DEBUG(1,"Set WEP key (%d)\n",idx);
-    wlandev->wep_keylens[idx] = ext->key_len;
-    memcpy(wlandev->wep_keys[idx], ext->key, ext->key_len);
-
-    memset( &msg,0,sizeof(msg));
-    pstr = (p80211item_pstr32_t*)&msg.mibattribute.data;
-    memcpy(pstr->data.data, ext->key,ext->key_len);
-    pstr->data.len = ext->key_len;
-    switch (idx) {
-    case 0:
-      pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
-      break;
-    case 1:
-      pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
-      break;
-    case 2:
-      pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
-      break;
-    case 3:
-      pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
-      break;
-    default:
-      break;
-    }
-    msg.msgcode = DIDmsg_dot11req_mibset;
-    result = p80211req_dorequest(wlandev,(u8*)&msg);
-    WLAN_LOG_DEBUG(1,"result (%d)\n",result);
-  }
-  return result;
+		memset(&msg, 0, sizeof(msg));
+		pstr = (p80211item_pstr32_t *)&msg.mibattribute.data;
+		memcpy(pstr->data.data, ext->key, ext->key_len);
+		pstr->data.len = ext->key_len;
+		switch (idx) {
+		case 0:
+			pstr->did =
+			    DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
+			break;
+		case 1:
+			pstr->did =
+			    DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
+			break;
+		case 2:
+			pstr->did =
+			    DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
+			break;
+		case 3:
+			pstr->did =
+			    DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
+			break;
+		default:
+			break;
+		}
+		msg.msgcode = DIDmsg_dot11req_mibset;
+		result = p80211req_dorequest(wlandev, (u8 *)&msg);
+		pr_debug("result (%d)\n", result);
+	}
+	return result;
 }
 
 /* SIOCGIWENCODEEXT */
 static int p80211wext_get_encodeext(struct net_device *dev,
-				struct iw_request_info *info,
-				union iwreq_data *wrqu, char *extra)
-
+				    struct iw_request_info *info,
+				    union iwreq_data *wrqu, char *extra)
 {
 	wlandevice_t *wlandev = dev->ml_priv;
 	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
@@ -1597,24 +1545,24 @@
 	int max_len;
 	int idx;
 
-	DBFENTER;
-
-	WLAN_LOG_DEBUG(1,"get_encode_ext flags[%d] alg[%d] keylen[%d]\n",ext->ext_flags,(int)ext->alg,(int)ext->key_len);
-
+	pr_debug("get_encode_ext flags[%d] alg[%d] keylen[%d]\n",
+	       ext->ext_flags, (int)ext->alg, (int)ext->key_len);
 
 	max_len = encoding->length - sizeof(*ext);
-	if ( max_len <= 0) {
-		WLAN_LOG_DEBUG(1,"get_encodeext max_len [%d] invalid\n",max_len);
+	if (max_len <= 0) {
+		pr_debug("get_encodeext max_len [%d] invalid\n",
+		       max_len);
 		result = -EINVAL;
 		goto exit;
 	}
 	idx = encoding->flags & IW_ENCODE_INDEX;
 
-	WLAN_LOG_DEBUG(1,"get_encode_ext index [%d]\n",idx);
+	pr_debug("get_encode_ext index [%d]\n", idx);
 
 	if (idx) {
-		if (idx < 1 || idx > NUM_WEPKEYS ) {
-			WLAN_LOG_DEBUG(1,"get_encode_ext invalid key index [%d]\n",idx);
+		if (idx < 1 || idx > NUM_WEPKEYS) {
+			printk(KERN_DEBUG
+			       "get_encode_ext invalid key index [%d]\n", idx);
 			result = -EINVAL;
 			goto exit;
 		}
@@ -1625,203 +1573,207 @@
 	}
 
 	encoding->flags = idx + 1;
-	memset(ext,0,sizeof(*ext));
+	memset(ext, 0, sizeof(*ext));
 
 	ext->alg = IW_ENCODE_ALG_WEP;
 	ext->key_len = wlandev->wep_keylens[idx];
-	memcpy( ext->key, wlandev->wep_keys[idx] , ext->key_len );
+	memcpy(ext->key, wlandev->wep_keys[idx], ext->key_len);
 
 	encoding->flags |= IW_ENCODE_ENABLED;
 exit:
-	DBFEXIT;
+	return result;
+}
+
+/* SIOCSIWAUTH */
+static int p80211_wext_set_iwauth(struct net_device *dev,
+				  struct iw_request_info *info,
+				  union iwreq_data *wrqu, char *extra)
+{
+	wlandevice_t *wlandev = dev->ml_priv;
+	struct iw_param *param = &wrqu->param;
+	int result = 0;
+
+	pr_debug("set_iwauth flags[%d]\n",
+	       (int)param->flags & IW_AUTH_INDEX);
+
+	switch (param->flags & IW_AUTH_INDEX) {
+	case IW_AUTH_DROP_UNENCRYPTED:
+		pr_debug("drop_unencrypted %d\n", param->value);
+		if (param->value)
+			result =
+			    p80211wext_dorequest(wlandev,
+						 DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
+						 P80211ENUM_truth_true);
+		else
+			result =
+			    p80211wext_dorequest(wlandev,
+						 DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
+						 P80211ENUM_truth_false);
+		break;
+
+	case IW_AUTH_PRIVACY_INVOKED:
+		pr_debug("privacy invoked %d\n", param->value);
+		if (param->value)
+			result =
+			    p80211wext_dorequest(wlandev,
+						 DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
+						 P80211ENUM_truth_true);
+		else
+			result =
+			    p80211wext_dorequest(wlandev,
+						 DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
+						 P80211ENUM_truth_false);
+
+		break;
+
+	case IW_AUTH_80211_AUTH_ALG:
+		if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
+			pr_debug("set open_system\n");
+			wlandev->hostwep &= ~HOSTWEP_SHAREDKEY;
+		} else if (param->value & IW_AUTH_ALG_SHARED_KEY) {
+			pr_debug("set shared key\n");
+			wlandev->hostwep |= HOSTWEP_SHAREDKEY;
+		} else {
+			/* don't know what to do know  */
+			pr_debug("unknown AUTH_ALG (%d)\n",
+			       param->value);
+			result = -EINVAL;
+		}
+		break;
+
+	default:
+		break;
+	}
 
 	return result;
 }
 
-
 /* SIOCSIWAUTH */
-static int p80211_wext_set_iwauth (struct net_device *dev,
-				   struct iw_request_info *info,
-				   union iwreq_data *wrqu, char *extra)
+static int p80211_wext_get_iwauth(struct net_device *dev,
+				  struct iw_request_info *info,
+				  union iwreq_data *wrqu, char *extra)
 {
-  wlandevice_t *wlandev = dev->ml_priv;
-  struct iw_param *param = &wrqu->param;
-  int result =0;
+	wlandevice_t *wlandev = dev->ml_priv;
+	struct iw_param *param = &wrqu->param;
+	int result = 0;
 
-  WLAN_LOG_DEBUG(1,"set_iwauth flags[%d]\n",(int)param->flags & IW_AUTH_INDEX );
+	pr_debug("get_iwauth flags[%d]\n",
+	       (int)param->flags & IW_AUTH_INDEX);
 
-  switch (param->flags & IW_AUTH_INDEX) {
-  case IW_AUTH_DROP_UNENCRYPTED:
-    WLAN_LOG_DEBUG(1,"drop_unencrypted %d\n",param->value);
-    if (param->value)
-      result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_true);
-    else
-      result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_false);
-    break;
+	switch (param->flags & IW_AUTH_INDEX) {
+	case IW_AUTH_DROP_UNENCRYPTED:
+		param->value =
+		    wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED ? 1 : 0;
+		break;
 
-  case IW_AUTH_PRIVACY_INVOKED:
-    WLAN_LOG_DEBUG(1,"privacy invoked %d\n",param->value);
-    if ( param->value)
-      result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_true);
-    else
-      result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_false);
+	case IW_AUTH_PRIVACY_INVOKED:
+		param->value =
+		    wlandev->hostwep & HOSTWEP_PRIVACYINVOKED ? 1 : 0;
+		break;
 
-    break;
+	case IW_AUTH_80211_AUTH_ALG:
+		param->value =
+		    wlandev->
+		    hostwep & HOSTWEP_SHAREDKEY ? IW_AUTH_ALG_SHARED_KEY :
+		    IW_AUTH_ALG_OPEN_SYSTEM;
+		break;
 
-  case IW_AUTH_80211_AUTH_ALG:
-    if ( param->value & IW_AUTH_ALG_OPEN_SYSTEM ) {
-      WLAN_LOG_DEBUG(1,"set open_system\n");
-      wlandev->hostwep &= ~HOSTWEP_SHAREDKEY;
-    } else if ( param->value & IW_AUTH_ALG_SHARED_KEY) {
-      WLAN_LOG_DEBUG(1,"set shared key\n");
-      wlandev->hostwep |= HOSTWEP_SHAREDKEY;
-    } else {
-      /* don't know what to do know :( */
-      WLAN_LOG_DEBUG(1,"unknown AUTH_ALG (%d)\n",param->value);
-      result = -EINVAL;
-    }
-    break;
+	default:
+		break;
+	}
 
-  default:
-    break;
-  }
-
-
-
-  return result;
+	return result;
 }
 
-/* SIOCSIWAUTH */
-static int p80211_wext_get_iwauth (struct net_device *dev,
-				   struct iw_request_info *info,
-				   union iwreq_data *wrqu, char *extra)
-{
-  wlandevice_t *wlandev = dev->ml_priv;
-  struct iw_param *param = &wrqu->param;
-  int result =0;
-
-  WLAN_LOG_DEBUG(1,"get_iwauth flags[%d]\n",(int)param->flags & IW_AUTH_INDEX );
-
-  switch (param->flags & IW_AUTH_INDEX) {
-  case IW_AUTH_DROP_UNENCRYPTED:
-    param->value = wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED?1:0;
-    break;
-
-  case IW_AUTH_PRIVACY_INVOKED:
-    param->value = wlandev->hostwep & HOSTWEP_PRIVACYINVOKED?1:0;
-    break;
-
-  case IW_AUTH_80211_AUTH_ALG:
-    param->value = wlandev->hostwep & HOSTWEP_SHAREDKEY?IW_AUTH_ALG_SHARED_KEY:IW_AUTH_ALG_OPEN_SYSTEM;
-    break;
-
-
-  default:
-    break;
-  }
-
-
-
-  return result;
-}
-
-static iw_handler p80211wext_handlers[] =  {
-	(iw_handler) p80211wext_siwcommit,		/* SIOCSIWCOMMIT */
-	(iw_handler) p80211wext_giwname,		/* SIOCGIWNAME */
-	(iw_handler) NULL,				/* SIOCSIWNWID */
-	(iw_handler) NULL,				/* SIOCGIWNWID */
-	(iw_handler) p80211wext_siwfreq,  		/* SIOCSIWFREQ */
-	(iw_handler) p80211wext_giwfreq,  		/* SIOCGIWFREQ */
-	(iw_handler) p80211wext_siwmode,       		/* SIOCSIWMODE */
-	(iw_handler) p80211wext_giwmode,       		/* SIOCGIWMODE */
-	(iw_handler) NULL,                 		/* SIOCSIWSENS */
-	(iw_handler) NULL,                		/* SIOCGIWSENS */
-	(iw_handler) NULL, /* not used */     		/* SIOCSIWRANGE */
-	(iw_handler) p80211wext_giwrange,      		/* SIOCGIWRANGE */
-	(iw_handler) NULL, /* not used */     		/* SIOCSIWPRIV */
-	(iw_handler) NULL, /* kernel code */   		/* SIOCGIWPRIV */
-	(iw_handler) NULL, /* not used */     		/* SIOCSIWSTATS */
-	(iw_handler) NULL, /* kernel code */   		/* SIOCGIWSTATS */
-	(iw_handler) p80211wext_siwspy,			/* SIOCSIWSPY */
-	(iw_handler) p80211wext_giwspy,			/* SIOCGIWSPY */
-	(iw_handler) NULL,				/* -- hole -- */
-	(iw_handler) NULL,				/* -- hole -- */
-	(iw_handler) NULL,              		/* SIOCSIWAP */
-	(iw_handler) p80211wext_giwap,         		/* SIOCGIWAP */
-	(iw_handler) NULL,				/* -- hole -- */
-	(iw_handler) NULL,                  		/* SIOCGIWAPLIST */
-	(iw_handler) p80211wext_siwscan,		/* SIOCSIWSCAN */
-	(iw_handler) p80211wext_giwscan,		/* SIOCGIWSCAN */
-	(iw_handler) p80211wext_siwessid,  		/* SIOCSIWESSID */
-	(iw_handler) p80211wext_giwessid,      		/* SIOCGIWESSID */
-	(iw_handler) NULL,                 		/* SIOCSIWNICKN */
-	(iw_handler) p80211wext_giwessid,      		/* SIOCGIWNICKN */
-	(iw_handler) NULL,				/* -- hole -- */
-	(iw_handler) NULL,				/* -- hole -- */
-	(iw_handler) NULL,                		/* SIOCSIWRATE */
-	(iw_handler) p80211wext_giwrate,      		/* SIOCGIWRATE */
-	(iw_handler) p80211wext_siwrts,  		/* SIOCSIWRTS */
-	(iw_handler) p80211wext_giwrts,        		/* SIOCGIWRTS */
-	(iw_handler) p80211wext_siwfrag,      		/* SIOCSIWFRAG */
-	(iw_handler) p80211wext_giwfrag,   		/* SIOCGIWFRAG */
-	(iw_handler) p80211wext_siwtxpow,           	/* SIOCSIWTXPOW */
-	(iw_handler) p80211wext_giwtxpow,  		/* SIOCGIWTXPOW */
-	(iw_handler) p80211wext_siwretry,     		/* SIOCSIWRETRY */
-	(iw_handler) p80211wext_giwretry,  		/* SIOCGIWRETRY */
-	(iw_handler) p80211wext_siwencode,     		/* SIOCSIWENCODE */
-	(iw_handler) p80211wext_giwencode,  		/* SIOCGIWENCODE */
-	(iw_handler) NULL,                 		/* SIOCSIWPOWER */
-	(iw_handler) NULL,                  		/* SIOCGIWPOWER */
+static iw_handler p80211wext_handlers[] = {
+	(iw_handler) p80211wext_siwcommit,	/* SIOCSIWCOMMIT */
+	(iw_handler) p80211wext_giwname,	/* SIOCGIWNAME */
+	(iw_handler) NULL,	/* SIOCSIWNWID */
+	(iw_handler) NULL,	/* SIOCGIWNWID */
+	(iw_handler) p80211wext_siwfreq,	/* SIOCSIWFREQ */
+	(iw_handler) p80211wext_giwfreq,	/* SIOCGIWFREQ */
+	(iw_handler) p80211wext_siwmode,	/* SIOCSIWMODE */
+	(iw_handler) p80211wext_giwmode,	/* SIOCGIWMODE */
+	(iw_handler) NULL,	/* SIOCSIWSENS */
+	(iw_handler) NULL,	/* SIOCGIWSENS */
+	(iw_handler) NULL,	/* not used *//* SIOCSIWRANGE */
+	(iw_handler) p80211wext_giwrange,	/* SIOCGIWRANGE */
+	(iw_handler) NULL,	/* not used *//* SIOCSIWPRIV */
+	(iw_handler) NULL,	/* kernel code *//* SIOCGIWPRIV */
+	(iw_handler) NULL,	/* not used *//* SIOCSIWSTATS */
+	(iw_handler) NULL,	/* kernel code *//* SIOCGIWSTATS */
+	(iw_handler) p80211wext_siwspy,	/* SIOCSIWSPY */
+	(iw_handler) p80211wext_giwspy,	/* SIOCGIWSPY */
+	(iw_handler) NULL,	/* -- hole -- */
+	(iw_handler) NULL,	/* -- hole -- */
+	(iw_handler) NULL,	/* SIOCSIWAP */
+	(iw_handler) p80211wext_giwap,	/* SIOCGIWAP */
+	(iw_handler) NULL,	/* -- hole -- */
+	(iw_handler) NULL,	/* SIOCGIWAPLIST */
+	(iw_handler) p80211wext_siwscan,	/* SIOCSIWSCAN */
+	(iw_handler) p80211wext_giwscan,	/* SIOCGIWSCAN */
+	(iw_handler) p80211wext_siwessid,	/* SIOCSIWESSID */
+	(iw_handler) p80211wext_giwessid,	/* SIOCGIWESSID */
+	(iw_handler) NULL,	/* SIOCSIWNICKN */
+	(iw_handler) p80211wext_giwessid,	/* SIOCGIWNICKN */
+	(iw_handler) NULL,	/* -- hole -- */
+	(iw_handler) NULL,	/* -- hole -- */
+	(iw_handler) NULL,	/* SIOCSIWRATE */
+	(iw_handler) p80211wext_giwrate,	/* SIOCGIWRATE */
+	(iw_handler) p80211wext_siwrts,	/* SIOCSIWRTS */
+	(iw_handler) p80211wext_giwrts,	/* SIOCGIWRTS */
+	(iw_handler) p80211wext_siwfrag,	/* SIOCSIWFRAG */
+	(iw_handler) p80211wext_giwfrag,	/* SIOCGIWFRAG */
+	(iw_handler) p80211wext_siwtxpow,	/* SIOCSIWTXPOW */
+	(iw_handler) p80211wext_giwtxpow,	/* SIOCGIWTXPOW */
+	(iw_handler) p80211wext_siwretry,	/* SIOCSIWRETRY */
+	(iw_handler) p80211wext_giwretry,	/* SIOCGIWRETRY */
+	(iw_handler) p80211wext_siwencode,	/* SIOCSIWENCODE */
+	(iw_handler) p80211wext_giwencode,	/* SIOCGIWENCODE */
+	(iw_handler) NULL,	/* SIOCSIWPOWER */
+	(iw_handler) NULL,	/* SIOCGIWPOWER */
 /* WPA operations */
-	(iw_handler) NULL,				/* -- hole -- */
-	(iw_handler) NULL,				/* -- hole -- */
-	(iw_handler) NULL, /* SIOCSIWGENIE	set generic IE */
-	(iw_handler) NULL, /* SIOCGIWGENIE	get generic IE */
-	(iw_handler) p80211_wext_set_iwauth, /* SIOCSIWAUTH	set authentication mode params */
-	(iw_handler) p80211_wext_get_iwauth, /* SIOCGIWAUTH	get authentication mode params */
+	(iw_handler) NULL,	/* -- hole -- */
+	(iw_handler) NULL,	/* -- hole -- */
+	(iw_handler) NULL,	/* SIOCSIWGENIE      set generic IE */
+	(iw_handler) NULL,	/* SIOCGIWGENIE      get generic IE */
+	(iw_handler) p80211_wext_set_iwauth,	/* SIOCSIWAUTH     set authentication mode params */
+	(iw_handler) p80211_wext_get_iwauth,	/* SIOCGIWAUTH     get authentication mode params */
 
-	(iw_handler) p80211wext_set_encodeext, /* SIOCSIWENCODEEXT  set encoding token & mode */
-	(iw_handler) p80211wext_get_encodeext, /* SIOCGIWENCODEEXT  get encoding token & mode */
-	(iw_handler) NULL, /* SIOCSIWPMKSA	PMKSA cache operation */
+	(iw_handler) p80211wext_set_encodeext,	/* SIOCSIWENCODEEXT  set encoding token & mode */
+	(iw_handler) p80211wext_get_encodeext,	/* SIOCGIWENCODEEXT  get encoding token & mode */
+	(iw_handler) NULL,	/* SIOCSIWPMKSA      PMKSA cache operation */
 };
 
 struct iw_handler_def p80211wext_handler_def = {
 	.num_standard = ARRAY_SIZE(p80211wext_handlers),
 	.num_private = 0,
 	.num_private_args = 0,
-        .standard = p80211wext_handlers,
+	.standard = p80211wext_handlers,
 	.private = NULL,
 	.private_args = NULL,
 	.get_wireless_stats = p80211wext_get_wireless_stats
 };
 
-
 int p80211wext_event_associated(wlandevice_t *wlandev, int assoc)
 {
-        union iwreq_data data;
+	union iwreq_data data;
 
-        DBFENTER;
+	/* Send the association state first */
+	data.ap_addr.sa_family = ARPHRD_ETHER;
+	if (assoc)
+		memcpy(data.ap_addr.sa_data, wlandev->bssid, ETH_ALEN);
+	else
+		memset(data.ap_addr.sa_data, 0, ETH_ALEN);
 
-        /* Send the association state first */
-        data.ap_addr.sa_family = ARPHRD_ETHER;
-        if (assoc) {
-                memcpy(data.ap_addr.sa_data, wlandev->bssid, WLAN_ADDR_LEN);
-        } else {
-                memset(data.ap_addr.sa_data, 0, WLAN_ADDR_LEN);
-        }
+	if (wlan_wext_write)
+		wireless_send_event(wlandev->netdev, SIOCGIWAP, &data, NULL);
 
-        if (wlan_wext_write)
-                wireless_send_event(wlandev->netdev, SIOCGIWAP, &data, NULL);
+	if (!assoc)
+		goto done;
 
-        if (!assoc) goto done;
+	/* XXX send association data, like IEs, etc etc. */
 
-        // XXX send association data, like IEs, etc etc.
-
- done:
-        DBFEXIT;
-        return 0;
+done:
+	return 0;
 }
-
-
-
-
diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c
index f1727ba6..e7a7939b 100644
--- a/drivers/staging/wlan-ng/prism2mgmt.c
+++ b/drivers/staging/wlan-ng/prism2mgmt.c
@@ -57,11 +57,6 @@
 * --------------------------------------------------------------------
 */
 
-/*================================================================*/
-/* System Includes */
-#define WLAN_DBVAR	prism2_debug
-
-
 #include <linux/if_arp.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -76,8 +71,7 @@
 #include <asm/byteorder.h>
 #include <linux/random.h>
 #include <linux/usb.h>
-
-#include "wlan_compat.h"
+#include <linux/bitops.h>
 
 /*================================================================*/
 /* Project Includes */
@@ -94,10 +88,10 @@
 #include "prism2mgmt.h"
 
 /* Converts 802.11 format rate specifications to prism2 */
-#define p80211rate_to_p2bit(n)	((((n)&~BIT7) == 2) ? BIT0 : \
-				 (((n)&~BIT7) == 4) ? BIT1 : \
-				 (((n)&~BIT7) == 11) ? BIT2 : \
-				 (((n)&~BIT7) == 22) ? BIT3 : 0)
+#define p80211rate_to_p2bit(n)	((((n)&~BIT(7)) == 2) ? BIT(0) :  \
+				 (((n)&~BIT(7)) == 4) ? BIT(1) : \
+				 (((n)&~BIT(7)) == 11) ? BIT(2) : \
+				 (((n)&~BIT(7)) == 22) ? BIT(3) : 0)
 
 /*----------------------------------------------------------------
 * prism2mgmt_scan
@@ -125,183 +119,188 @@
 ----------------------------------------------------------------*/
 int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp)
 {
-	int 			result = 0;
-	hfa384x_t		*hw = wlandev->priv;
-	p80211msg_dot11req_scan_t	*msg = msgp;
-        u16                  roamingmode, word;
-	int                     i, timeout;
-	int                     istmpenable = 0;
+	int result = 0;
+	hfa384x_t *hw = wlandev->priv;
+	p80211msg_dot11req_scan_t *msg = msgp;
+	u16 roamingmode, word;
+	int i, timeout;
+	int istmpenable = 0;
 
-        hfa384x_HostScanRequest_data_t  scanreq;
+	hfa384x_HostScanRequest_data_t scanreq;
 
-	DBFENTER;
-
-        /* gatekeeper check */
-        if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
-                                     hw->ident_sta_fw.minor,
-                                     hw->ident_sta_fw.variant) <
-            HFA384x_FIRMWARE_VERSION(1,3,2)) {
-		WLAN_LOG_ERROR("HostScan not supported with current firmware (<1.3.2).\n");
-                result = 1;
-                msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+	/* gatekeeper check */
+	if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
+				     hw->ident_sta_fw.minor,
+				     hw->ident_sta_fw.variant) <
+	    HFA384x_FIRMWARE_VERSION(1, 3, 2)) {
+		printk(KERN_ERR
+		       "HostScan not supported with current firmware (<1.3.2).\n");
+		result = 1;
+		msg->resultcode.data = P80211ENUM_resultcode_not_supported;
 		goto exit;
 	}
 
-        memset(&scanreq, 0, sizeof(scanreq));
+	memset(&scanreq, 0, sizeof(scanreq));
 
-        /* save current roaming mode */
-        result = hfa384x_drvr_getconfig16(hw,
-                        HFA384x_RID_CNFROAMINGMODE, &roamingmode);
-        if ( result ) {
-                WLAN_LOG_ERROR("getconfig(ROAMMODE) failed. result=%d\n",
-                                result);
-                msg->resultcode.data =
-                        P80211ENUM_resultcode_implementation_failure;
-                goto exit;
-        }
+	/* save current roaming mode */
+	result = hfa384x_drvr_getconfig16(hw,
+					  HFA384x_RID_CNFROAMINGMODE,
+					  &roamingmode);
+	if (result) {
+		printk(KERN_ERR "getconfig(ROAMMODE) failed. result=%d\n",
+		       result);
+		msg->resultcode.data =
+		    P80211ENUM_resultcode_implementation_failure;
+		goto exit;
+	}
 
-        /* drop into mode 3 for the scan */
-        result = hfa384x_drvr_setconfig16(hw,
-                        HFA384x_RID_CNFROAMINGMODE,
-			HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM);
-        if ( result ) {
-                WLAN_LOG_ERROR("setconfig(ROAMINGMODE) failed. result=%d\n",
-                                result);
-                msg->resultcode.data =
-                        P80211ENUM_resultcode_implementation_failure;
-                goto exit;
-        }
+	/* drop into mode 3 for the scan */
+	result = hfa384x_drvr_setconfig16(hw,
+					  HFA384x_RID_CNFROAMINGMODE,
+					  HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM);
+	if (result) {
+		printk(KERN_ERR "setconfig(ROAMINGMODE) failed. result=%d\n",
+		       result);
+		msg->resultcode.data =
+		    P80211ENUM_resultcode_implementation_failure;
+		goto exit;
+	}
 
-        /* active or passive? */
-        if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
-                                     hw->ident_sta_fw.minor,
-                                     hw->ident_sta_fw.variant) >
-            HFA384x_FIRMWARE_VERSION(1,5,0)) {
-                if (msg->scantype.data != P80211ENUM_scantype_active) {
-                        word = host2hfa384x_16(msg->maxchanneltime.data);
-                } else {
-                        word = 0;
-                }
-                result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPASSIVESCANCTRL, word);
-                if ( result ) {
-                        WLAN_LOG_WARNING("Passive scan not supported with "
-					  "current firmware.  (<1.5.1)\n");
-                }
-        }
+	/* active or passive? */
+	if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
+				     hw->ident_sta_fw.minor,
+				     hw->ident_sta_fw.variant) >
+	    HFA384x_FIRMWARE_VERSION(1, 5, 0)) {
+		if (msg->scantype.data != P80211ENUM_scantype_active)
+			word = cpu_to_le16(msg->maxchanneltime.data);
+		else
+			word = 0;
+
+		result =
+		    hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPASSIVESCANCTRL,
+					     word);
+		if (result) {
+			printk(KERN_WARNING "Passive scan not supported with "
+			       "current firmware.  (<1.5.1)\n");
+		}
+	}
 
 	/* set up the txrate to be 2MBPS. Should be fastest basicrate... */
 	word = HFA384x_RATEBIT_2;
-	scanreq.txRate = host2hfa384x_16(word);
+	scanreq.txRate = cpu_to_le16(word);
 
-        /* set up the channel list */
-        word = 0;
-        for (i = 0; i < msg->channellist.data.len; i++) {
-                u8 channel = msg->channellist.data.data[i];
-                if (channel > 14) continue;
-                /* channel 1 is BIT0 ... channel 14 is BIT13 */
-                word |= (1 << (channel-1));
-        }
-        scanreq.channelList = host2hfa384x_16(word);
+	/* set up the channel list */
+	word = 0;
+	for (i = 0; i < msg->channellist.data.len; i++) {
+		u8 channel = msg->channellist.data.data[i];
+		if (channel > 14)
+			continue;
+		/* channel 1 is BIT 0 ... channel 14 is BIT 13 */
+		word |= (1 << (channel - 1));
+	}
+	scanreq.channelList = cpu_to_le16(word);
 
-        /* set up the ssid, if present. */
-        scanreq.ssid.len = host2hfa384x_16(msg->ssid.data.len);
-        memcpy(scanreq.ssid.data, msg->ssid.data.data, msg->ssid.data.len);
+	/* set up the ssid, if present. */
+	scanreq.ssid.len = cpu_to_le16(msg->ssid.data.len);
+	memcpy(scanreq.ssid.data, msg->ssid.data.data, msg->ssid.data.len);
 
 	/* Enable the MAC port if it's not already enabled  */
 	result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_PORTSTATUS, &word);
-	if ( result ) {
-		WLAN_LOG_ERROR("getconfig(PORTSTATUS) failed. "
-				"result=%d\n", result);
+	if (result) {
+		printk(KERN_ERR "getconfig(PORTSTATUS) failed. "
+		       "result=%d\n", result);
 		msg->resultcode.data =
-			P80211ENUM_resultcode_implementation_failure;
+		    P80211ENUM_resultcode_implementation_failure;
 		goto exit;
 	}
 	if (word == HFA384x_PORTSTATUS_DISABLED) {
 		u16 wordbuf[17];
 
 		result = hfa384x_drvr_setconfig16(hw,
-			HFA384x_RID_CNFROAMINGMODE,
-			HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM);
-		if ( result ) {
-			WLAN_LOG_ERROR("setconfig(ROAMINGMODE) failed. result=%d\n", result);
+						  HFA384x_RID_CNFROAMINGMODE,
+						  HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM);
+		if (result) {
+			printk(KERN_ERR
+			       "setconfig(ROAMINGMODE) failed. result=%d\n",
+			       result);
 			msg->resultcode.data =
-				P80211ENUM_resultcode_implementation_failure;
+			    P80211ENUM_resultcode_implementation_failure;
 			goto exit;
 		}
 		/* Construct a bogus SSID and assign it to OwnSSID and
 		 * DesiredSSID
 		 */
-		wordbuf[0] = host2hfa384x_16(WLAN_SSID_MAXLEN);
+		wordbuf[0] = cpu_to_le16(WLAN_SSID_MAXLEN);
 		get_random_bytes(&wordbuf[1], WLAN_SSID_MAXLEN);
-		result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFOWNSSID,
-				wordbuf, HFA384x_RID_CNFOWNSSID_LEN);
-		if ( result ) {
-			WLAN_LOG_ERROR("Failed to set OwnSSID.\n");
+		result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFOWNSSID,
+						wordbuf,
+						HFA384x_RID_CNFOWNSSID_LEN);
+		if (result) {
+			printk(KERN_ERR "Failed to set OwnSSID.\n");
 			msg->resultcode.data =
-				P80211ENUM_resultcode_implementation_failure;
+			    P80211ENUM_resultcode_implementation_failure;
 			goto exit;
 		}
-		result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFDESIREDSSID,
-				wordbuf, HFA384x_RID_CNFDESIREDSSID_LEN);
-		if ( result ) {
-			WLAN_LOG_ERROR("Failed to set DesiredSSID.\n");
+		result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID,
+						wordbuf,
+						HFA384x_RID_CNFDESIREDSSID_LEN);
+		if (result) {
+			printk(KERN_ERR "Failed to set DesiredSSID.\n");
 			msg->resultcode.data =
-				P80211ENUM_resultcode_implementation_failure;
+			    P80211ENUM_resultcode_implementation_failure;
 			goto exit;
 		}
 		/* bsstype */
 		result = hfa384x_drvr_setconfig16(hw,
-				HFA384x_RID_CNFPORTTYPE,
-				HFA384x_PORTTYPE_IBSS);
-		if ( result ) {
-			WLAN_LOG_ERROR("Failed to set CNFPORTTYPE.\n");
+						  HFA384x_RID_CNFPORTTYPE,
+						  HFA384x_PORTTYPE_IBSS);
+		if (result) {
+			printk(KERN_ERR "Failed to set CNFPORTTYPE.\n");
 			msg->resultcode.data =
-				P80211ENUM_resultcode_implementation_failure;
+			    P80211ENUM_resultcode_implementation_failure;
 			goto exit;
 		}
 		/* ibss options */
 		result = hfa384x_drvr_setconfig16(hw,
-				HFA384x_RID_CREATEIBSS,
-				HFA384x_CREATEIBSS_JOINCREATEIBSS);
-		if ( result ) {
-			WLAN_LOG_ERROR("Failed to set CREATEIBSS.\n");
+						  HFA384x_RID_CREATEIBSS,
+						  HFA384x_CREATEIBSS_JOINCREATEIBSS);
+		if (result) {
+			printk(KERN_ERR "Failed to set CREATEIBSS.\n");
 			msg->resultcode.data =
-				P80211ENUM_resultcode_implementation_failure;
+			    P80211ENUM_resultcode_implementation_failure;
 			goto exit;
 		}
 		result = hfa384x_drvr_enable(hw, 0);
-		if ( result ) {
-			WLAN_LOG_ERROR("drvr_enable(0) failed. "
-					"result=%d\n", result);
+		if (result) {
+			printk(KERN_ERR "drvr_enable(0) failed. "
+			       "result=%d\n", result);
 			msg->resultcode.data =
-			P80211ENUM_resultcode_implementation_failure;
+			    P80211ENUM_resultcode_implementation_failure;
 			goto exit;
 		}
 		istmpenable = 1;
 	}
 
-        /* Figure out our timeout first Kus, then HZ */
-        timeout = msg->channellist.data.len * msg->maxchanneltime.data;
-	timeout = (timeout * HZ)/1000;
+	/* Figure out our timeout first Kus, then HZ */
+	timeout = msg->channellist.data.len * msg->maxchanneltime.data;
+	timeout = (timeout * HZ) / 1000;
 
-        /* Issue the scan request */
-        hw->scanflag = 0;
+	/* Issue the scan request */
+	hw->scanflag = 0;
 
-	WLAN_HEX_DUMP(5,"hscanreq", &scanreq, sizeof(scanreq));
+	result = hfa384x_drvr_setconfig(hw,
+					HFA384x_RID_HOSTSCAN, &scanreq,
+					sizeof(hfa384x_HostScanRequest_data_t));
+	if (result) {
+		printk(KERN_ERR "setconfig(SCANREQUEST) failed. result=%d\n",
+		       result);
+		msg->resultcode.data =
+		    P80211ENUM_resultcode_implementation_failure;
+		goto exit;
+	}
 
-        result = hfa384x_drvr_setconfig( hw,
-                        HFA384x_RID_HOSTSCAN, &scanreq,
-                        sizeof(hfa384x_HostScanRequest_data_t));
-        if ( result ) {
-                WLAN_LOG_ERROR("setconfig(SCANREQUEST) failed. result=%d\n",
-                                result);
-                msg->resultcode.data =
-                        P80211ENUM_resultcode_implementation_failure;
-                goto exit;
-        }
-
-        /* sleep until info frame arrives */
-        wait_event_interruptible_timeout(hw->cmdq, hw->scanflag, timeout);
+	/* sleep until info frame arrives */
+	wait_event_interruptible_timeout(hw->cmdq, hw->scanflag, timeout);
 
 	msg->numbss.status = P80211ENUM_msgitem_status_data_ok;
 	if (hw->scanflag == -1)
@@ -309,16 +308,16 @@
 
 	msg->numbss.data = hw->scanflag;
 
-        hw->scanflag = 0;
+	hw->scanflag = 0;
 
 	/* Disable port if we temporarily enabled it. */
 	if (istmpenable) {
 		result = hfa384x_drvr_disable(hw, 0);
-		if ( result ) {
-			WLAN_LOG_ERROR("drvr_disable(0) failed. "
-					"result=%d\n", result);
+		if (result) {
+			printk(KERN_ERR "drvr_disable(0) failed. "
+			       "result=%d\n", result);
 			msg->resultcode.data =
-			P80211ENUM_resultcode_implementation_failure;
+			    P80211ENUM_resultcode_implementation_failure;
 			goto exit;
 		}
 	}
@@ -326,25 +325,23 @@
 	/* restore original roaming mode */
 	result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFROAMINGMODE,
 					  roamingmode);
-        if ( result ) {
-                WLAN_LOG_ERROR("setconfig(ROAMMODE) failed. result=%d\n",
-                                result);
-                msg->resultcode.data =
-                        P80211ENUM_resultcode_implementation_failure;
-                goto exit;
-        }
+	if (result) {
+		printk(KERN_ERR "setconfig(ROAMMODE) failed. result=%d\n",
+		       result);
+		msg->resultcode.data =
+		    P80211ENUM_resultcode_implementation_failure;
+		goto exit;
+	}
 
-        result = 0;
-        msg->resultcode.data = P80211ENUM_resultcode_success;
+	result = 0;
+	msg->resultcode.data = P80211ENUM_resultcode_success;
 
- exit:
+exit:
 	msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
 
-	DBFEXIT;
 	return result;
 }
 
-
 /*----------------------------------------------------------------
 * prism2mgmt_scan_results
 *
@@ -367,32 +364,32 @@
 ----------------------------------------------------------------*/
 int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
 {
-	int 			result = 0;
-        p80211msg_dot11req_scan_results_t       *req;
-	hfa384x_t		*hw = wlandev->priv;
+	int result = 0;
+	p80211msg_dot11req_scan_results_t *req;
+	hfa384x_t *hw = wlandev->priv;
 	hfa384x_HScanResultSub_t *item = NULL;
 
 	int count;
 
-	DBFENTER;
-
-        req = (p80211msg_dot11req_scan_results_t *) msgp;
+	req = (p80211msg_dot11req_scan_results_t *) msgp;
 
 	req->resultcode.status = P80211ENUM_msgitem_status_data_ok;
 
-	if (! hw->scanresults) {
-		WLAN_LOG_ERROR("dot11req_scan_results can only be used after a successful dot11req_scan.\n");
+	if (!hw->scanresults) {
+		printk(KERN_ERR
+		       "dot11req_scan_results can only be used after a successful dot11req_scan.\n");
 		result = 2;
 		req->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
 		goto exit;
 	}
 
-        count = (hw->scanresults->framelen - 3) / 32;
-	if (count > 32)  count = 32;
+	count = (hw->scanresults->framelen - 3) / 32;
+	if (count > 32)
+		count = 32;
 
 	if (req->bssindex.data >= count) {
-		WLAN_LOG_DEBUG(0, "requested index (%d) out of range (%d)\n",
-				req->bssindex.data, count);
+		pr_debug("requested index (%d) out of range (%d)\n",
+		       req->bssindex.data, count);
 		result = 2;
 		req->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
 		goto exit;
@@ -402,8 +399,8 @@
 	/* signal and noise */
 	req->signal.status = P80211ENUM_msgitem_status_data_ok;
 	req->noise.status = P80211ENUM_msgitem_status_data_ok;
-	req->signal.data = hfa384x2host_16(item->sl);
-	req->noise.data = hfa384x2host_16(item->anl);
+	req->signal.data = le16_to_cpu(item->sl);
+	req->noise.data = le16_to_cpu(item->anl);
 
 	/* BSSID */
 	req->bssid.status = P80211ENUM_msgitem_status_data_ok;
@@ -412,13 +409,13 @@
 
 	/* SSID */
 	req->ssid.status = P80211ENUM_msgitem_status_data_ok;
-	req->ssid.data.len = hfa384x2host_16(item->ssid.len);
+	req->ssid.data.len = le16_to_cpu(item->ssid.len);
 	memcpy(req->ssid.data.data, item->ssid.data, req->ssid.data.len);
 
 	/* supported rates */
-        for (count = 0; count < 10 ; count++)
-                if (item->supprates[count] == 0)
-                        break;
+	for (count = 0; count < 10; count++)
+		if (item->supprates[count] == 0)
+			break;
 
 #define REQBASICRATE(N) \
 	if ((count >= N) && DOT11_RATE5_ISBASIC_GET(item->supprates[(N)-1])) { \
@@ -452,7 +449,7 @@
 
 	/* beacon period */
 	req->beaconperiod.status = P80211ENUM_msgitem_status_data_ok;
-	req->beaconperiod.data = hfa384x2host_16(item->bcnint);
+	req->beaconperiod.data = le16_to_cpu(item->bcnint);
 
 	/* timestamps */
 	req->timestamp.status = P80211ENUM_msgitem_status_data_ok;
@@ -462,14 +459,14 @@
 
 	/* atim window */
 	req->ibssatimwindow.status = P80211ENUM_msgitem_status_data_ok;
-	req->ibssatimwindow.data = hfa384x2host_16(item->atim);
+	req->ibssatimwindow.data = le16_to_cpu(item->atim);
 
 	/* Channel */
 	req->dschannel.status = P80211ENUM_msgitem_status_data_ok;
-	req->dschannel.data = hfa384x2host_16(item->chid);
+	req->dschannel.data = le16_to_cpu(item->chid);
 
 	/* capinfo bits */
-	count = hfa384x2host_16(item->capinfo);
+	count = le16_to_cpu(item->capinfo);
 
 	/* privacy flag */
 	req->privacy.status = P80211ENUM_msgitem_status_data_ok;
@@ -484,25 +481,14 @@
 	req->cfpollreq.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(count);
 
 	/* bsstype */
-	req->bsstype.status =  P80211ENUM_msgitem_status_data_ok;
+	req->bsstype.status = P80211ENUM_msgitem_status_data_ok;
 	req->bsstype.data = (WLAN_GET_MGMT_CAP_INFO_ESS(count)) ?
-		P80211ENUM_bsstype_infrastructure :
-		P80211ENUM_bsstype_independent;
-
-	// item->proberesp_rate
-/*
-	req->fhdwelltime
-	req->fhhopset
-	req->fhhoppattern
-	req->fhhopindex
-        req->cfpdurremaining
-*/
+	    P80211ENUM_bsstype_infrastructure : P80211ENUM_bsstype_independent;
 
 	result = 0;
 	req->resultcode.data = P80211ENUM_resultcode_success;
 
- exit:
-	DBFEXIT;
+exit:
 	return result;
 }
 
@@ -527,15 +513,14 @@
 ----------------------------------------------------------------*/
 int prism2mgmt_start(wlandevice_t *wlandev, void *msgp)
 {
-	int 			result = 0;
-	hfa384x_t		*hw = wlandev->priv;
-	p80211msg_dot11req_start_t	*msg = msgp;
+	int result = 0;
+	hfa384x_t *hw = wlandev->priv;
+	p80211msg_dot11req_start_t *msg = msgp;
 
-	p80211pstrd_t		*pstr;
-	u8			bytebuf[80];
-	hfa384x_bytestr_t	*p2bytestr = (hfa384x_bytestr_t*)bytebuf;
-	u16			word;
-	DBFENTER;
+	p80211pstrd_t *pstr;
+	u8 bytebuf[80];
+	hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t *) bytebuf;
+	u16 word;
 
 	wlandev->macmode = WLAN_MACMODE_NONE;
 
@@ -547,7 +532,7 @@
 	if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
 				     hw->ident_sta_fw.minor,
 				     hw->ident_sta_fw.variant) <
-	    HFA384x_FIRMWARE_VERSION(0,8,3)) {
+	    HFA384x_FIRMWARE_VERSION(0, 8, 3)) {
 		/* Ad-Hoc not quite supported on Prism2 */
 		msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
 		msg->resultcode.data = P80211ENUM_resultcode_not_supported;
@@ -559,18 +544,19 @@
 	/*** STATION ***/
 	/* Set the REQUIRED config items */
 	/* SSID */
-	pstr = (p80211pstrd_t*)&(msg->ssid.data);
+	pstr = (p80211pstrd_t *)&(msg->ssid.data);
 	prism2mgmt_pstr2bytestr(p2bytestr, pstr);
-	result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFOWNSSID,
-					 bytebuf, HFA384x_RID_CNFOWNSSID_LEN);
-	if ( result ) {
-		WLAN_LOG_ERROR("Failed to set CnfOwnSSID\n");
+	result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFOWNSSID,
+					bytebuf, HFA384x_RID_CNFOWNSSID_LEN);
+	if (result) {
+		printk(KERN_ERR "Failed to set CnfOwnSSID\n");
 		goto failed;
 	}
-	result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFDESIREDSSID,
-					 bytebuf, HFA384x_RID_CNFDESIREDSSID_LEN);
-	if ( result ) {
-		WLAN_LOG_ERROR("Failed to set CnfDesiredSSID\n");
+	result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID,
+					bytebuf,
+					HFA384x_RID_CNFDESIREDSSID_LEN);
+	if (result) {
+		printk(KERN_ERR "Failed to set CnfDesiredSSID\n");
 		goto failed;
 	}
 
@@ -581,84 +567,84 @@
 	/* beacon period */
 	word = msg->beaconperiod.data;
 	result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAPBCNint, word);
-	if ( result ) {
-		WLAN_LOG_ERROR("Failed to set beacon period=%d.\n", word);
+	if (result) {
+		printk(KERN_ERR "Failed to set beacon period=%d.\n", word);
 		goto failed;
 	}
 
 	/* dschannel */
 	word = msg->dschannel.data;
 	result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFOWNCHANNEL, word);
-	if ( result ) {
-		WLAN_LOG_ERROR("Failed to set channel=%d.\n", word);
+	if (result) {
+		printk(KERN_ERR "Failed to set channel=%d.\n", word);
 		goto failed;
 	}
 	/* Basic rates */
 	word = p80211rate_to_p2bit(msg->basicrate1.data);
-	if ( msg->basicrate2.status == P80211ENUM_msgitem_status_data_ok ) {
+	if (msg->basicrate2.status == P80211ENUM_msgitem_status_data_ok)
 		word |= p80211rate_to_p2bit(msg->basicrate2.data);
-	}
-	if ( msg->basicrate3.status == P80211ENUM_msgitem_status_data_ok ) {
+
+	if (msg->basicrate3.status == P80211ENUM_msgitem_status_data_ok)
 		word |= p80211rate_to_p2bit(msg->basicrate3.data);
-	}
-	if ( msg->basicrate4.status == P80211ENUM_msgitem_status_data_ok ) {
+
+	if (msg->basicrate4.status == P80211ENUM_msgitem_status_data_ok)
 		word |= p80211rate_to_p2bit(msg->basicrate4.data);
-	}
-	if ( msg->basicrate5.status == P80211ENUM_msgitem_status_data_ok ) {
+
+	if (msg->basicrate5.status == P80211ENUM_msgitem_status_data_ok)
 		word |= p80211rate_to_p2bit(msg->basicrate5.data);
-	}
-	if ( msg->basicrate6.status == P80211ENUM_msgitem_status_data_ok ) {
+
+	if (msg->basicrate6.status == P80211ENUM_msgitem_status_data_ok)
 		word |= p80211rate_to_p2bit(msg->basicrate6.data);
-	}
-	if ( msg->basicrate7.status == P80211ENUM_msgitem_status_data_ok ) {
+
+	if (msg->basicrate7.status == P80211ENUM_msgitem_status_data_ok)
 		word |= p80211rate_to_p2bit(msg->basicrate7.data);
-	}
-	if ( msg->basicrate8.status == P80211ENUM_msgitem_status_data_ok ) {
+
+	if (msg->basicrate8.status == P80211ENUM_msgitem_status_data_ok)
 		word |= p80211rate_to_p2bit(msg->basicrate8.data);
-	}
+
 	result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFBASICRATES, word);
-	if ( result ) {
-		WLAN_LOG_ERROR("Failed to set basicrates=%d.\n", word);
+	if (result) {
+		printk(KERN_ERR "Failed to set basicrates=%d.\n", word);
 		goto failed;
 	}
 
 	/* Operational rates (supprates and txratecontrol) */
 	word = p80211rate_to_p2bit(msg->operationalrate1.data);
-	if ( msg->operationalrate2.status == P80211ENUM_msgitem_status_data_ok ) {
+	if (msg->operationalrate2.status == P80211ENUM_msgitem_status_data_ok)
 		word |= p80211rate_to_p2bit(msg->operationalrate2.data);
-	}
-	if ( msg->operationalrate3.status == P80211ENUM_msgitem_status_data_ok ) {
+
+	if (msg->operationalrate3.status == P80211ENUM_msgitem_status_data_ok)
 		word |= p80211rate_to_p2bit(msg->operationalrate3.data);
-	}
-	if ( msg->operationalrate4.status == P80211ENUM_msgitem_status_data_ok ) {
+
+	if (msg->operationalrate4.status == P80211ENUM_msgitem_status_data_ok)
 		word |= p80211rate_to_p2bit(msg->operationalrate4.data);
-	}
-	if ( msg->operationalrate5.status == P80211ENUM_msgitem_status_data_ok ) {
+
+	if (msg->operationalrate5.status == P80211ENUM_msgitem_status_data_ok)
 		word |= p80211rate_to_p2bit(msg->operationalrate5.data);
-	}
-	if ( msg->operationalrate6.status == P80211ENUM_msgitem_status_data_ok ) {
+
+	if (msg->operationalrate6.status == P80211ENUM_msgitem_status_data_ok)
 		word |= p80211rate_to_p2bit(msg->operationalrate6.data);
-	}
-	if ( msg->operationalrate7.status == P80211ENUM_msgitem_status_data_ok ) {
+
+	if (msg->operationalrate7.status == P80211ENUM_msgitem_status_data_ok)
 		word |= p80211rate_to_p2bit(msg->operationalrate7.data);
-	}
-	if ( msg->operationalrate8.status == P80211ENUM_msgitem_status_data_ok ) {
+
+	if (msg->operationalrate8.status == P80211ENUM_msgitem_status_data_ok)
 		word |= p80211rate_to_p2bit(msg->operationalrate8.data);
-	}
+
 	result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, word);
-	if ( result ) {
-		WLAN_LOG_ERROR("Failed to set supprates=%d.\n", word);
+	if (result) {
+		printk(KERN_ERR "Failed to set supprates=%d.\n", word);
 		goto failed;
 	}
 
 	result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, word);
-	if ( result ) {
-		WLAN_LOG_ERROR("Failed to set txrates=%d.\n", word);
+	if (result) {
+		printk(KERN_ERR "Failed to set txrates=%d.\n", word);
 		goto failed;
 	}
 
 	/* Set the macmode so the frame setup code knows what to do */
-	if ( msg->bsstype.data == P80211ENUM_bsstype_independent ) {
+	if (msg->bsstype.data == P80211ENUM_bsstype_independent) {
 		wlandev->macmode = WLAN_MACMODE_IBSS_STA;
 		/* lets extend the data length a bit */
 		hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN, 2304);
@@ -666,8 +652,8 @@
 
 	/* Enable the Port */
 	result = hfa384x_drvr_enable(hw, 0);
-	if ( result ) {
-		WLAN_LOG_ERROR("Enable macport failed, result=%d.\n", result);
+	if (result) {
+		printk(KERN_ERR "Enable macport failed, result=%d.\n", result);
 		goto failed;
 	}
 
@@ -675,13 +661,12 @@
 
 	goto done;
 failed:
-	WLAN_LOG_DEBUG(1, "Failed to set a config option, result=%d\n", result);
+	pr_debug("Failed to set a config option, result=%d\n", result);
 	msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
 
 done:
 	result = 0;
 
-	DBFEXIT;
 	return result;
 }
 
@@ -705,40 +690,35 @@
 ----------------------------------------------------------------*/
 int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp)
 {
-	hfa384x_t		*hw = wlandev->priv;
-	p80211msg_p2req_readpda_t	*msg = msgp;
-	int				result;
-	DBFENTER;
+	hfa384x_t *hw = wlandev->priv;
+	p80211msg_p2req_readpda_t *msg = msgp;
+	int result;
 
 	/* We only support collecting the PDA when in the FWLOAD
 	 * state.
 	 */
 	if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
-		WLAN_LOG_ERROR(
-			"PDA may only be read "
-			"in the fwload state.\n");
+		printk(KERN_ERR
+		       "PDA may only be read " "in the fwload state.\n");
 		msg->resultcode.data =
-			P80211ENUM_resultcode_implementation_failure;
+		    P80211ENUM_resultcode_implementation_failure;
 		msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
 	} else {
 		/*  Call drvr_readpda(), it handles the auxport enable
 		 *  and validating the returned PDA.
 		 */
-		result = hfa384x_drvr_readpda(
-			hw,
-			msg->pda.data,
-			HFA384x_PDA_LEN_MAX);
+		result = hfa384x_drvr_readpda(hw,
+					      msg->pda.data,
+					      HFA384x_PDA_LEN_MAX);
 		if (result) {
-			WLAN_LOG_ERROR(
-				"hfa384x_drvr_readpda() failed, "
-				"result=%d\n",
-				result);
+			printk(KERN_ERR
+			       "hfa384x_drvr_readpda() failed, "
+			       "result=%d\n", result);
 
 			msg->resultcode.data =
-				P80211ENUM_resultcode_implementation_failure;
+			    P80211ENUM_resultcode_implementation_failure;
 			msg->resultcode.status =
-				P80211ENUM_msgitem_status_data_ok;
-			DBFEXIT;
+			    P80211ENUM_msgitem_status_data_ok;
 			return 0;
 		}
 		msg->pda.status = P80211ENUM_msgitem_status_data_ok;
@@ -746,7 +726,6 @@
 		msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
 	}
 
-	DBFEXIT;
 	return 0;
 }
 
@@ -777,30 +756,29 @@
 ----------------------------------------------------------------*/
 int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp)
 {
-	hfa384x_t		*hw = wlandev->priv;
-	p80211msg_p2req_ramdl_state_t	*msg = msgp;
-	DBFENTER;
+	hfa384x_t *hw = wlandev->priv;
+	p80211msg_p2req_ramdl_state_t *msg = msgp;
 
 	if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
-		WLAN_LOG_ERROR(
-			"ramdl_state(): may only be called "
-			"in the fwload state.\n");
+		printk(KERN_ERR
+		       "ramdl_state(): may only be called "
+		       "in the fwload state.\n");
 		msg->resultcode.data =
-			P80211ENUM_resultcode_implementation_failure;
+		    P80211ENUM_resultcode_implementation_failure;
 		msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
-		DBFEXIT;
 		return 0;
 	}
 
 	/*
-	** Note: Interrupts are locked out if this is an AP and are NOT
-	** locked out if this is a station.
-	*/
+	 ** Note: Interrupts are locked out if this is an AP and are NOT
+	 ** locked out if this is a station.
+	 */
 
 	msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
-	if  ( msg->enable.data == P80211ENUM_truth_true ) {
-		if ( hfa384x_drvr_ramdl_enable(hw, msg->exeaddr.data) ) {
-			msg->resultcode.data = P80211ENUM_resultcode_implementation_failure;
+	if (msg->enable.data == P80211ENUM_truth_true) {
+		if (hfa384x_drvr_ramdl_enable(hw, msg->exeaddr.data)) {
+			msg->resultcode.data =
+			    P80211ENUM_resultcode_implementation_failure;
 		} else {
 			msg->resultcode.data = P80211ENUM_resultcode_success;
 		}
@@ -809,11 +787,9 @@
 		msg->resultcode.data = P80211ENUM_resultcode_success;
 	}
 
-	DBFEXIT;
 	return 0;
 }
 
-
 /*----------------------------------------------------------------
 * prism2mgmt_ramdl_write
 *
@@ -836,45 +812,41 @@
 ----------------------------------------------------------------*/
 int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp)
 {
-	hfa384x_t		*hw = wlandev->priv;
-	p80211msg_p2req_ramdl_write_t	*msg = msgp;
-	u32			addr;
-	u32			len;
-	u8			*buf;
-	DBFENTER;
+	hfa384x_t *hw = wlandev->priv;
+	p80211msg_p2req_ramdl_write_t *msg = msgp;
+	u32 addr;
+	u32 len;
+	u8 *buf;
 
 	if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
-		WLAN_LOG_ERROR(
-			"ramdl_write(): may only be called "
-			"in the fwload state.\n");
+		printk(KERN_ERR
+		       "ramdl_write(): may only be called "
+		       "in the fwload state.\n");
 		msg->resultcode.data =
-			P80211ENUM_resultcode_implementation_failure;
+		    P80211ENUM_resultcode_implementation_failure;
 		msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
-		DBFEXIT;
 		return 0;
 	}
 
 	msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
 	/* first validate the length */
-	if  ( msg->len.data > sizeof(msg->data.data) ) {
-		msg->resultcode.status = P80211ENUM_resultcode_invalid_parameters;
+	if (msg->len.data > sizeof(msg->data.data)) {
+		msg->resultcode.status =
+		    P80211ENUM_resultcode_invalid_parameters;
 		return 0;
 	}
 	/* call the hfa384x function to do the write */
 	addr = msg->addr.data;
 	len = msg->len.data;
 	buf = msg->data.data;
-	if ( hfa384x_drvr_ramdl_write(hw, addr, buf, len) ) {
+	if (hfa384x_drvr_ramdl_write(hw, addr, buf, len))
 		msg->resultcode.data = P80211ENUM_resultcode_refused;
 
-	}
 	msg->resultcode.data = P80211ENUM_resultcode_success;
 
-	DBFEXIT;
 	return 0;
 }
 
-
 /*----------------------------------------------------------------
 * prism2mgmt_flashdl_state
 *
@@ -902,31 +874,30 @@
 ----------------------------------------------------------------*/
 int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp)
 {
-	int			result = 0;
-	hfa384x_t		*hw = wlandev->priv;
-	p80211msg_p2req_flashdl_state_t	*msg = msgp;
-	DBFENTER;
+	int result = 0;
+	hfa384x_t *hw = wlandev->priv;
+	p80211msg_p2req_flashdl_state_t *msg = msgp;
 
 	if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
-		WLAN_LOG_ERROR(
-			"flashdl_state(): may only be called "
-			"in the fwload state.\n");
+		printk(KERN_ERR
+		       "flashdl_state(): may only be called "
+		       "in the fwload state.\n");
 		msg->resultcode.data =
-			P80211ENUM_resultcode_implementation_failure;
+		    P80211ENUM_resultcode_implementation_failure;
 		msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
-		DBFEXIT;
 		return 0;
 	}
 
 	/*
-	** Note: Interrupts are locked out if this is an AP and are NOT
-	** locked out if this is a station.
-	*/
+	 ** Note: Interrupts are locked out if this is an AP and are NOT
+	 ** locked out if this is a station.
+	 */
 
 	msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
-	if  ( msg->enable.data == P80211ENUM_truth_true ) {
-		if ( hfa384x_drvr_flashdl_enable(hw) ) {
-			msg->resultcode.data = P80211ENUM_resultcode_implementation_failure;
+	if (msg->enable.data == P80211ENUM_truth_true) {
+		if (hfa384x_drvr_flashdl_enable(hw)) {
+			msg->resultcode.data =
+			    P80211ENUM_resultcode_implementation_failure;
 		} else {
 			msg->resultcode.data = P80211ENUM_resultcode_success;
 		}
@@ -943,19 +914,17 @@
 		wlandev->msdstate = WLAN_MSD_HWPRESENT;
 		result = prism2sta_ifstate(wlandev, P80211ENUM_ifstate_fwload);
 		if (result != P80211ENUM_resultcode_success) {
-			WLAN_LOG_ERROR("prism2sta_ifstate(fwload) failed,"
-				"P80211ENUM_resultcode=%d\n", result);
+			printk(KERN_ERR "prism2sta_ifstate(fwload) failed,"
+			       "P80211ENUM_resultcode=%d\n", result);
 			msg->resultcode.data =
-				P80211ENUM_resultcode_implementation_failure;
+			    P80211ENUM_resultcode_implementation_failure;
 			result = -1;
 		}
 	}
 
-	DBFEXIT;
 	return 0;
 }
 
-
 /*----------------------------------------------------------------
 * prism2mgmt_flashdl_write
 *
@@ -976,47 +945,43 @@
 ----------------------------------------------------------------*/
 int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp)
 {
-	hfa384x_t		*hw = wlandev->priv;
-	p80211msg_p2req_flashdl_write_t	*msg = msgp;
-	u32			addr;
-	u32			len;
-	u8			*buf;
-	DBFENTER;
+	hfa384x_t *hw = wlandev->priv;
+	p80211msg_p2req_flashdl_write_t *msg = msgp;
+	u32 addr;
+	u32 len;
+	u8 *buf;
 
 	if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
-		WLAN_LOG_ERROR(
-			"flashdl_write(): may only be called "
-			"in the fwload state.\n");
+		printk(KERN_ERR
+		       "flashdl_write(): may only be called "
+		       "in the fwload state.\n");
 		msg->resultcode.data =
-			P80211ENUM_resultcode_implementation_failure;
+		    P80211ENUM_resultcode_implementation_failure;
 		msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
-		DBFEXIT;
 		return 0;
 	}
 
 	/*
-	** Note: Interrupts are locked out if this is an AP and are NOT
-	** locked out if this is a station.
-	*/
+	 ** Note: Interrupts are locked out if this is an AP and are NOT
+	 ** locked out if this is a station.
+	 */
 
 	msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
 	/* first validate the length */
-	if  ( msg->len.data > sizeof(msg->data.data) ) {
+	if (msg->len.data > sizeof(msg->data.data)) {
 		msg->resultcode.status =
-			P80211ENUM_resultcode_invalid_parameters;
+		    P80211ENUM_resultcode_invalid_parameters;
 		return 0;
 	}
 	/* call the hfa384x function to do the write */
 	addr = msg->addr.data;
 	len = msg->len.data;
 	buf = msg->data.data;
-	if ( hfa384x_drvr_flashdl_write(hw, addr, buf, len) ) {
+	if (hfa384x_drvr_flashdl_write(hw, addr, buf, len))
 		msg->resultcode.data = P80211ENUM_resultcode_refused;
 
-	}
 	msg->resultcode.data = P80211ENUM_resultcode_success;
 
-	DBFEXIT;
 	return 0;
 }
 
@@ -1041,15 +1006,14 @@
 ----------------------------------------------------------------*/
 int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp)
 {
-	hfa384x_t			*hw = wlandev->priv;
-	int 			result = 0;
-	u16			reg;
-	u16			port_type;
-	p80211msg_lnxreq_autojoin_t	*msg = msgp;
-	p80211pstrd_t		*pstr;
-	u8			bytebuf[256];
-	hfa384x_bytestr_t	*p2bytestr = (hfa384x_bytestr_t*)bytebuf;
-	DBFENTER;
+	hfa384x_t *hw = wlandev->priv;
+	int result = 0;
+	u16 reg;
+	u16 port_type;
+	p80211msg_lnxreq_autojoin_t *msg = msgp;
+	p80211pstrd_t *pstr;
+	u8 bytebuf[256];
+	hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t *) bytebuf;
 
 	wlandev->macmode = WLAN_MACMODE_NONE;
 
@@ -1064,39 +1028,21 @@
 	hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, 0x000f);
 
 	/* Set the auth type */
-	if ( msg->authtype.data == P80211ENUM_authalg_sharedkey ) {
+	if (msg->authtype.data == P80211ENUM_authalg_sharedkey)
 		reg = HFA384x_CNFAUTHENTICATION_SHAREDKEY;
-	} else {
+	else
 		reg = HFA384x_CNFAUTHENTICATION_OPENSYSTEM;
-	}
+
 	hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAUTHENTICATION, reg);
 
 	/* Set the ssid */
 	memset(bytebuf, 0, 256);
-	pstr = (p80211pstrd_t*)&(msg->ssid.data);
+	pstr = (p80211pstrd_t *)&(msg->ssid.data);
 	prism2mgmt_pstr2bytestr(p2bytestr, pstr);
-        result = hfa384x_drvr_setconfig(
-			hw, HFA384x_RID_CNFDESIREDSSID,
-			bytebuf, HFA384x_RID_CNFDESIREDSSID_LEN);
-#if 0
-	/* we can use the new-fangled auto-unknown mode if the firmware
-	   is 1.3.3 or newer */
-	if (HFA384x_FIRMARE_VERSION(hw->ident_sta_fw.major,
-				    hw->ident_sta_fw.minor,
-				    hw->ident_sta_fw.variant) >=
-	    HFA384x_FIRMWARE_VERSION(1,3,3)) {
-		/* Set up the IBSS options */
-		reg =  HFA384x_CREATEIBSS_JOINESS_JOINCREATEIBSS;
-		hfa384x_drvr_setconfig16(hw, HFA384x_RID_CREATEIBSS, reg);
-
-		/* Set the PortType */
-		port_type = HFA384x_PORTTYPE_IBSS;
-	} else {
-		port_type = HFA384x_PORTTYPE_BSS;
-	}
-#else
+	result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID,
+					bytebuf,
+					HFA384x_RID_CNFDESIREDSSID_LEN);
 	port_type = HFA384x_PORTTYPE_BSS;
-#endif
 	/* Set the PortType */
 	hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, port_type);
 
@@ -1107,11 +1053,9 @@
 	msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
 	msg->resultcode.data = P80211ENUM_resultcode_success;
 
-	DBFEXIT;
 	return result;
 }
 
-
 /*----------------------------------------------------------------
 * prism2mgmt_wlansniff
 *
@@ -1133,38 +1077,36 @@
 ----------------------------------------------------------------*/
 int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
 {
-	int 			result = 0;
-	p80211msg_lnxreq_wlansniff_t	*msg = msgp;
+	int result = 0;
+	p80211msg_lnxreq_wlansniff_t *msg = msgp;
 
-	hfa384x_t			*hw = wlandev->priv;
-	u16			word;
-
-	DBFENTER;
+	hfa384x_t *hw = wlandev->priv;
+	u16 word;
 
 	msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
-	switch (msg->enable.data)
-	{
+	switch (msg->enable.data) {
 	case P80211ENUM_truth_false:
 		/* Confirm that we're in monitor mode */
-		if ( wlandev->netdev->type == ARPHRD_ETHER ) {
-			msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
+		if (wlandev->netdev->type == ARPHRD_ETHER) {
+			msg->resultcode.data =
+			    P80211ENUM_resultcode_invalid_parameters;
 			result = 0;
 			goto exit;
 		}
 		/* Disable monitor mode */
 		result = hfa384x_cmd_monitor(hw, HFA384x_MONITOR_DISABLE);
-		if ( result ) {
-			WLAN_LOG_DEBUG(1,
-				"failed to disable monitor mode, result=%d\n",
-				result);
+		if (result) {
+			printk(KERN_DEBUG
+			       "failed to disable monitor mode, result=%d\n",
+			       result);
 			goto failed;
 		}
 		/* Disable port 0 */
 		result = hfa384x_drvr_disable(hw, 0);
-		if ( result ) {
-			WLAN_LOG_DEBUG(1,
-			"failed to disable port 0 after sniffing, result=%d\n",
-			result);
+		if (result) {
+			printk(KERN_DEBUG
+			       "failed to disable port 0 after sniffing, result=%d\n",
+			       result);
 			goto failed;
 		}
 		/* Clear the driver state */
@@ -1172,32 +1114,34 @@
 
 		/* Restore the wepflags */
 		result = hfa384x_drvr_setconfig16(hw,
-				HFA384x_RID_CNFWEPFLAGS,
-				hw->presniff_wepflags);
-		if ( result ) {
-			WLAN_LOG_DEBUG(1,
-			"failed to restore wepflags=0x%04x, result=%d\n",
-			hw->presniff_wepflags,
-			result);
+						  HFA384x_RID_CNFWEPFLAGS,
+						  hw->presniff_wepflags);
+		if (result) {
+			printk(KERN_DEBUG
+			       "failed to restore wepflags=0x%04x, result=%d\n",
+			       hw->presniff_wepflags, result);
 			goto failed;
 		}
 
 		/* Set the port to its prior type and enable (if necessary) */
-		if (hw->presniff_port_type != 0 ) {
+		if (hw->presniff_port_type != 0) {
 			word = hw->presniff_port_type;
 			result = hfa384x_drvr_setconfig16(hw,
-				HFA384x_RID_CNFPORTTYPE, word);
-			if ( result ) {
-				WLAN_LOG_DEBUG(1,
-				"failed to restore porttype, result=%d\n",
-				result);
+							  HFA384x_RID_CNFPORTTYPE,
+							  word);
+			if (result) {
+				printk(KERN_DEBUG
+				       "failed to restore porttype, result=%d\n",
+				       result);
 				goto failed;
 			}
 
 			/* Enable the port */
 			result = hfa384x_drvr_enable(hw, 0);
-			if ( result ) {
-				WLAN_LOG_DEBUG(1, "failed to enable port to presniff setting, result=%d\n", result);
+			if (result) {
+				printk(KERN_DEBUG
+				       "failed to enable port to presniff setting, result=%d\n",
+				       result);
 				goto failed;
 			}
 		} else {
@@ -1205,46 +1149,52 @@
 
 		}
 
-		WLAN_LOG_INFO("monitor mode disabled\n");
+		printk(KERN_INFO "monitor mode disabled\n");
 		msg->resultcode.data = P80211ENUM_resultcode_success;
 		result = 0;
 		goto exit;
 		break;
 	case P80211ENUM_truth_true:
 		/* Disable the port (if enabled), only check Port 0 */
-		if ( hw->port_enabled[0]) {
+		if (hw->port_enabled[0]) {
 			if (wlandev->netdev->type == ARPHRD_ETHER) {
 				/* Save macport 0 state */
 				result = hfa384x_drvr_getconfig16(hw,
 								  HFA384x_RID_CNFPORTTYPE,
-								  &(hw->presniff_port_type));
-				if ( result ) {
-					WLAN_LOG_DEBUG(1,"failed to read porttype, result=%d\n", result);
+								  &(hw->
+								    presniff_port_type));
+				if (result) {
+					printk(KERN_DEBUG
+					       "failed to read porttype, result=%d\n",
+					       result);
 					goto failed;
 				}
 				/* Save the wepflags state */
 				result = hfa384x_drvr_getconfig16(hw,
 								  HFA384x_RID_CNFWEPFLAGS,
-								  &(hw->presniff_wepflags));
-				if ( result ) {
-					WLAN_LOG_DEBUG(1,"failed to read wepflags, result=%d\n", result);
+								  &(hw->
+								    presniff_wepflags));
+				if (result) {
+					printk(KERN_DEBUG
+					       "failed to read wepflags, result=%d\n",
+					       result);
 					goto failed;
 				}
 				hfa384x_drvr_stop(hw);
 				result = hfa384x_drvr_start(hw);
-				if ( result ) {
-					WLAN_LOG_DEBUG(1,
-						       "failed to restart the card for sniffing, result=%d\n",
-						       result);
+				if (result) {
+					printk(KERN_DEBUG
+					       "failed to restart the card for sniffing, result=%d\n",
+					       result);
 					goto failed;
 				}
 			} else {
 				/* Disable the port */
 				result = hfa384x_drvr_disable(hw, 0);
-				if ( result ) {
-					WLAN_LOG_DEBUG(1,
-						       "failed to enable port for sniffing, result=%d\n",
-						       result);
+				if (result) {
+					printk(KERN_DEBUG
+					       "failed to enable port for sniffing, result=%d\n",
+					       result);
 					goto failed;
 				}
 			}
@@ -1255,14 +1205,14 @@
 		/* Set the channel we wish to sniff  */
 		word = msg->channel.data;
 		result = hfa384x_drvr_setconfig16(hw,
-						  HFA384x_RID_CNFOWNCHANNEL, word);
-		hw->sniff_channel=word;
+						  HFA384x_RID_CNFOWNCHANNEL,
+						  word);
+		hw->sniff_channel = word;
 
-		if ( result ) {
-			WLAN_LOG_DEBUG(1,
-				       "failed to set channel %d, result=%d\n",
-					       word,
-				       result);
+		if (result) {
+			printk(KERN_DEBUG
+			       "failed to set channel %d, result=%d\n",
+			       word, result);
 			goto failed;
 		}
 
@@ -1271,39 +1221,46 @@
 			/* Set the port type to pIbss */
 			word = HFA384x_PORTTYPE_PSUEDOIBSS;
 			result = hfa384x_drvr_setconfig16(hw,
-							  HFA384x_RID_CNFPORTTYPE, word);
-			if ( result ) {
-				WLAN_LOG_DEBUG(1,
-					       "failed to set porttype %d, result=%d\n",
-					       word,
-					       result);
+							  HFA384x_RID_CNFPORTTYPE,
+							  word);
+			if (result) {
+				printk(KERN_DEBUG
+				       "failed to set porttype %d, result=%d\n",
+				       word, result);
 				goto failed;
 			}
-			if ((msg->keepwepflags.status == P80211ENUM_msgitem_status_data_ok) && (msg->keepwepflags.data != P80211ENUM_truth_true)) {
+			if ((msg->keepwepflags.status ==
+			     P80211ENUM_msgitem_status_data_ok)
+			    && (msg->keepwepflags.data !=
+				P80211ENUM_truth_true)) {
 				/* Set the wepflags for no decryption */
 				word = HFA384x_WEPFLAGS_DISABLE_TXCRYPT |
-					HFA384x_WEPFLAGS_DISABLE_RXCRYPT;
-				result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFWEPFLAGS, word);
+				    HFA384x_WEPFLAGS_DISABLE_RXCRYPT;
+				result =
+				    hfa384x_drvr_setconfig16(hw,
+							     HFA384x_RID_CNFWEPFLAGS,
+							     word);
 			}
 
-			if ( result ) {
-				WLAN_LOG_DEBUG(1,
-					       "failed to set wepflags=0x%04x, result=%d\n",
-					       word,
-					       result);
+			if (result) {
+				printk(KERN_DEBUG
+				       "failed to set wepflags=0x%04x, result=%d\n",
+				       word, result);
 				goto failed;
 			}
 		}
 
 		/* Do we want to strip the FCS in monitor mode? */
-		if ((msg->stripfcs.status == P80211ENUM_msgitem_status_data_ok) && (msg->stripfcs.data == P80211ENUM_truth_true)) {
+		if ((msg->stripfcs.status == P80211ENUM_msgitem_status_data_ok)
+		    && (msg->stripfcs.data == P80211ENUM_truth_true)) {
 			hw->sniff_fcs = 0;
 		} else {
 			hw->sniff_fcs = 1;
 		}
 
 		/* Do we want to truncate the packets? */
-		if (msg->packet_trunc.status == P80211ENUM_msgitem_status_data_ok) {
+		if (msg->packet_trunc.status ==
+		    P80211ENUM_msgitem_status_data_ok) {
 			hw->sniff_truncate = msg->packet_trunc.data;
 		} else {
 			hw->sniff_truncate = 0;
@@ -1311,31 +1268,35 @@
 
 		/* Enable the port */
 		result = hfa384x_drvr_enable(hw, 0);
-		if ( result ) {
-			WLAN_LOG_DEBUG(1,
-			"failed to enable port for sniffing, result=%d\n",
-			result);
+		if (result) {
+			printk(KERN_DEBUG
+			       "failed to enable port for sniffing, result=%d\n",
+			       result);
 			goto failed;
 		}
 		/* Enable monitor mode */
 		result = hfa384x_cmd_monitor(hw, HFA384x_MONITOR_ENABLE);
-		if ( result ) {
-			WLAN_LOG_DEBUG(1,
-			"failed to enable monitor mode, result=%d\n",
-			result);
+		if (result) {
+			printk(KERN_DEBUG
+			       "failed to enable monitor mode, result=%d\n",
+			       result);
 			goto failed;
 		}
 
-		if (wlandev->netdev->type == ARPHRD_ETHER) {
-			WLAN_LOG_INFO("monitor mode enabled\n");
-		}
+		if (wlandev->netdev->type == ARPHRD_ETHER)
+			printk(KERN_INFO "monitor mode enabled\n");
 
 		/* Set the driver state */
 		/* Do we want the prism2 header? */
-		if ((msg->prismheader.status == P80211ENUM_msgitem_status_data_ok) && (msg->prismheader.data == P80211ENUM_truth_true)) {
+		if ((msg->prismheader.status ==
+		     P80211ENUM_msgitem_status_data_ok)
+		    && (msg->prismheader.data == P80211ENUM_truth_true)) {
 			hw->sniffhdr = 0;
 			wlandev->netdev->type = ARPHRD_IEEE80211_PRISM;
-		} else if ((msg->wlanheader.status == P80211ENUM_msgitem_status_data_ok) && (msg->wlanheader.data == P80211ENUM_truth_true)) {
+		} else
+		    if ((msg->wlanheader.status ==
+			 P80211ENUM_msgitem_status_data_ok)
+			&& (msg->wlanheader.data == P80211ENUM_truth_true)) {
 			hw->sniffhdr = 1;
 			wlandev->netdev->type = ARPHRD_IEEE80211_PRISM;
 		} else {
@@ -1357,7 +1318,5 @@
 	msg->resultcode.data = P80211ENUM_resultcode_refused;
 	result = 0;
 exit:
-
-	DBFEXIT;
 	return result;
 }
diff --git a/drivers/staging/wlan-ng/prism2mgmt.h b/drivers/staging/wlan-ng/prism2mgmt.h
index caf808d..07eeceb 100644
--- a/drivers/staging/wlan-ng/prism2mgmt.h
+++ b/drivers/staging/wlan-ng/prism2mgmt.h
@@ -60,43 +60,16 @@
 #ifndef _PRISM2MGMT_H
 #define _PRISM2MGMT_H
 
+extern int prism2_reset_holdtime;
+extern int prism2_reset_settletime;
 
-/*=============================================================*/
-/*------ Constants --------------------------------------------*/
+u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate);
 
-/*=============================================================*/
-/*------ Macros -----------------------------------------------*/
-
-/*=============================================================*/
-/*------ Types and their related constants --------------------*/
-
-/*=============================================================*/
-/*------ Static variable externs ------------------------------*/
-
-extern int	prism2_debug;
-extern int      prism2_reset_holdtime;
-extern int      prism2_reset_settletime;
-/*=============================================================*/
-/*--- Function Declarations -----------------------------------*/
-/*=============================================================*/
-
-u32
-prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate);
-
-void
-prism2sta_ev_dtim(wlandevice_t *wlandev);
-void
-prism2sta_ev_infdrop(wlandevice_t *wlandev);
-void
-prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
-void
-prism2sta_ev_txexc(wlandevice_t *wlandev, u16 status);
-void
-prism2sta_ev_tx(wlandevice_t *wlandev, u16 status);
-void
-prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb);
-void
-prism2sta_ev_alloc(wlandevice_t *wlandev);
+void prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+void prism2sta_ev_txexc(wlandevice_t *wlandev, u16 status);
+void prism2sta_ev_tx(wlandevice_t *wlandev, u16 status);
+void prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb);
+void prism2sta_ev_alloc(wlandevice_t *wlandev);
 
 int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp);
 int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp);
@@ -122,34 +95,16 @@
 void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr);
 void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr);
 
-/* integer conversion functions */
-void prism2mgmt_prism2int2p80211int(u16 *prism2int, u32 *wlanint);
-void prism2mgmt_p80211int2prism2int(u16 *prism2int, u32 *wlanint);
-
-/* enumerated integer conversion functions */
-void prism2mgmt_prism2enum2p80211enum(u16 *prism2enum, u32 *wlanenum, u16 rid);
-void prism2mgmt_p80211enum2prism2enum(u16 *prism2enum, u32 *wlanenum, u16 rid);
-
-/* functions to convert a bit area to/from an Operational Rate Set */
-void prism2mgmt_get_oprateset(u16 *rate, p80211pstrd_t *pstr);
-void prism2mgmt_set_oprateset(u16 *rate, p80211pstrd_t *pstr);
-
 /* functions to convert Group Addresses */
-void prism2mgmt_get_grpaddr(u32 did,
-	p80211pstrd_t *pstr, hfa384x_t *priv );
+void prism2mgmt_get_grpaddr(u32 did, p80211pstrd_t *pstr, hfa384x_t *priv);
 int prism2mgmt_set_grpaddr(u32 did,
-	u8 *prism2buf, p80211pstrd_t *pstr, hfa384x_t *priv );
-int prism2mgmt_get_grpaddr_index( u32 did );
+			   u8 *prism2buf, p80211pstrd_t *pstr,
+			   hfa384x_t *priv);
+int prism2mgmt_get_grpaddr_index(u32 did);
 
 void prism2sta_processing_defer(struct work_struct *data);
 
 void prism2sta_commsqual_defer(struct work_struct *data);
 void prism2sta_commsqual_timer(unsigned long data);
 
-/*=============================================================*/
-/*--- Inline Function Definitions (if supported) --------------*/
-/*=============================================================*/
-
-
-
 #endif
diff --git a/drivers/staging/wlan-ng/prism2mib.c b/drivers/staging/wlan-ng/prism2mib.c
index 539c447..5a6ba86 100644
--- a/drivers/staging/wlan-ng/prism2mib.c
+++ b/drivers/staging/wlan-ng/prism2mib.c
@@ -50,12 +50,7 @@
 * --------------------------------------------------------------------
 */
 
-/*================================================================*/
-/* System Includes */
-#define WLAN_DBVAR	prism2_debug
-
 #include <linux/version.h>
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -63,13 +58,11 @@
 #include <linux/slab.h>
 #include <linux/wireless.h>
 #include <linux/netdevice.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <asm/byteorder.h>
 #include <linux/usb.h>
-
-/*================================================================*/
-/* Project Includes */
+#include <linux/bitops.h>
 
 #include "p80211types.h"
 #include "p80211hdr.h"
@@ -82,196 +75,169 @@
 #include "hfa384x.h"
 #include "prism2mgmt.h"
 
-/*================================================================*/
-/* Local Constants */
+#define MIB_TMP_MAXLEN    200	/* Max length of RID record (in bytes). */
 
-#define MIB_TMP_MAXLEN    200    /* Max length of RID record (in bytes). */
+#define  F_STA        0x1	/* MIB is supported on stations. */
+#define  F_READ       0x2	/* MIB may be read. */
+#define  F_WRITE      0x4	/* MIB may be written. */
 
-/*================================================================*/
-/* Local Types */
-
-#define  F_STA        0x1        /* MIB is supported on stations. */
-#define  F_READ       0x2        /* MIB may be read. */
-#define  F_WRITE      0x4        /* MIB may be written. */
-
-typedef struct mibrec
-{
-    u32   did;
-    u16   flag;
-    u16   parm1;
-    u16   parm2;
-    u16   parm3;
-    int      (*func)(struct mibrec                *mib,
-                     int                          isget,
-                     wlandevice_t                 *wlandev,
-                     hfa384x_t                    *hw,
-                     p80211msg_dot11req_mibset_t  *msg,
-                     void                         *data);
+typedef struct mibrec {
+	u32 did;
+	u16 flag;
+	u16 parm1;
+	u16 parm2;
+	u16 parm3;
+	int (*func) (struct mibrec *mib,
+		     int isget,
+		     wlandevice_t *wlandev,
+		     hfa384x_t *hw,
+		     p80211msg_dot11req_mibset_t *msg, void *data);
 } mibrec_t;
 
-/*================================================================*/
-/* Local Function Declarations */
+static int prism2mib_bytearea2pstr(mibrec_t *mib,
+				   int isget,
+				   wlandevice_t *wlandev,
+				   hfa384x_t *hw,
+				   p80211msg_dot11req_mibset_t *msg,
+				   void *data);
 
-static int prism2mib_bytearea2pstr(
-mibrec_t                     *mib,
-int                          isget,
-wlandevice_t                 *wlandev,
-hfa384x_t                    *hw,
-p80211msg_dot11req_mibset_t  *msg,
-void                         *data);
+static int prism2mib_uint32(mibrec_t *mib,
+			    int isget,
+			    wlandevice_t *wlandev,
+			    hfa384x_t *hw,
+			    p80211msg_dot11req_mibset_t *msg, void *data);
 
-static int prism2mib_uint32(
-mibrec_t                     *mib,
-int                          isget,
-wlandevice_t                 *wlandev,
-hfa384x_t                    *hw,
-p80211msg_dot11req_mibset_t  *msg,
-void                         *data);
+static int prism2mib_flag(mibrec_t *mib,
+			  int isget,
+			  wlandevice_t *wlandev,
+			  hfa384x_t *hw,
+			  p80211msg_dot11req_mibset_t *msg, void *data);
 
-static int prism2mib_flag(
-mibrec_t                     *mib,
-int                          isget,
-wlandevice_t                 *wlandev,
-hfa384x_t                    *hw,
-p80211msg_dot11req_mibset_t  *msg,
-void                         *data);
+static int prism2mib_wepdefaultkey(mibrec_t *mib,
+				   int isget,
+				   wlandevice_t *wlandev,
+				   hfa384x_t *hw,
+				   p80211msg_dot11req_mibset_t *msg,
+				   void *data);
 
-static int prism2mib_wepdefaultkey(
-mibrec_t                     *mib,
-int                          isget,
-wlandevice_t                 *wlandev,
-hfa384x_t                    *hw,
-p80211msg_dot11req_mibset_t  *msg,
-void                         *data);
+static int prism2mib_privacyinvoked(mibrec_t *mib,
+				    int isget,
+				    wlandevice_t *wlandev,
+				    hfa384x_t *hw,
+				    p80211msg_dot11req_mibset_t *msg,
+				    void *data);
 
-static int prism2mib_privacyinvoked(
-mibrec_t                     *mib,
-int                          isget,
-wlandevice_t                 *wlandev,
-hfa384x_t                    *hw,
-p80211msg_dot11req_mibset_t  *msg,
-void                         *data);
+static int prism2mib_excludeunencrypted(mibrec_t *mib,
+					int isget,
+					wlandevice_t *wlandev,
+					hfa384x_t *hw,
+					p80211msg_dot11req_mibset_t *msg,
+					void *data);
 
-static int prism2mib_excludeunencrypted(
-mibrec_t                     *mib,
-int                          isget,
-wlandevice_t                 *wlandev,
-hfa384x_t                    *hw,
-p80211msg_dot11req_mibset_t  *msg,
-void                         *data);
+static int prism2mib_fragmentationthreshold(mibrec_t *mib,
+					    int isget,
+					    wlandevice_t *wlandev,
+					    hfa384x_t *hw,
+					    p80211msg_dot11req_mibset_t *msg,
+					    void *data);
 
-static int prism2mib_fragmentationthreshold(
-mibrec_t                     *mib,
-int                          isget,
-wlandevice_t                 *wlandev,
-hfa384x_t                    *hw,
-p80211msg_dot11req_mibset_t  *msg,
-void                         *data);
-
-static int prism2mib_priv(
-mibrec_t                     *mib,
-int                          isget,
-wlandevice_t                 *wlandev,
-hfa384x_t                    *hw,
-p80211msg_dot11req_mibset_t  *msg,
-void                         *data);
-
-/*================================================================*/
-/* Local Static Definitions */
+static int prism2mib_priv(mibrec_t *mib,
+			  int isget,
+			  wlandevice_t *wlandev,
+			  hfa384x_t *hw,
+			  p80211msg_dot11req_mibset_t *msg, void *data);
 
 static mibrec_t mibtab[] = {
 
-    /* dot11smt MIB's */
-    { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0,
-          F_STA | F_WRITE,
-          HFA384x_RID_CNFWEPDEFAULTKEY0, 0, 0,
-          prism2mib_wepdefaultkey },
-    { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1,
-          F_STA | F_WRITE,
-          HFA384x_RID_CNFWEPDEFAULTKEY1, 0, 0,
-          prism2mib_wepdefaultkey },
-    { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2,
-          F_STA | F_WRITE,
-          HFA384x_RID_CNFWEPDEFAULTKEY2, 0, 0,
-          prism2mib_wepdefaultkey },
-    { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3,
-          F_STA | F_WRITE,
-          HFA384x_RID_CNFWEPDEFAULTKEY3, 0, 0,
-          prism2mib_wepdefaultkey },
-    { DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
-          F_STA | F_READ | F_WRITE,
-          HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_PRIVINVOKED, 0,
-          prism2mib_privacyinvoked },
-    { DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
-          F_STA | F_READ | F_WRITE,
-          HFA384x_RID_CNFWEPDEFAULTKEYID, 0, 0,
-          prism2mib_uint32 },
-    { DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
-          F_STA | F_READ | F_WRITE,
-          HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_EXCLUDE, 0,
-          prism2mib_excludeunencrypted },
+	/* dot11smt MIB's */
+	{DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0,
+	 F_STA | F_WRITE,
+	 HFA384x_RID_CNFWEPDEFAULTKEY0, 0, 0,
+	 prism2mib_wepdefaultkey},
+	{DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1,
+	 F_STA | F_WRITE,
+	 HFA384x_RID_CNFWEPDEFAULTKEY1, 0, 0,
+	 prism2mib_wepdefaultkey},
+	{DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2,
+	 F_STA | F_WRITE,
+	 HFA384x_RID_CNFWEPDEFAULTKEY2, 0, 0,
+	 prism2mib_wepdefaultkey},
+	{DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3,
+	 F_STA | F_WRITE,
+	 HFA384x_RID_CNFWEPDEFAULTKEY3, 0, 0,
+	 prism2mib_wepdefaultkey},
+	{DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
+	 F_STA | F_READ | F_WRITE,
+	 HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_PRIVINVOKED, 0,
+	 prism2mib_privacyinvoked},
+	{DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
+	 F_STA | F_READ | F_WRITE,
+	 HFA384x_RID_CNFWEPDEFAULTKEYID, 0, 0,
+	 prism2mib_uint32},
+	{DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
+	 F_STA | F_READ | F_WRITE,
+	 HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_EXCLUDE, 0,
+	 prism2mib_excludeunencrypted},
 
-    /* dot11mac MIB's */
+	/* dot11mac MIB's */
 
-    { DIDmib_dot11mac_dot11OperationTable_dot11MACAddress,
-          F_STA | F_READ | F_WRITE,
-          HFA384x_RID_CNFOWNMACADDR, HFA384x_RID_CNFOWNMACADDR_LEN, 0,
-          prism2mib_bytearea2pstr },
-    { DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold,
-          F_STA | F_READ | F_WRITE,
-          HFA384x_RID_RTSTHRESH, 0, 0,
-          prism2mib_uint32 },
-    { DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit,
-          F_STA | F_READ,
-          HFA384x_RID_SHORTRETRYLIMIT, 0, 0,
-          prism2mib_uint32 },
-    { DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit,
-          F_STA | F_READ,
-          HFA384x_RID_LONGRETRYLIMIT, 0, 0,
-          prism2mib_uint32 },
-    { DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold,
-          F_STA | F_READ | F_WRITE,
-          HFA384x_RID_FRAGTHRESH, 0, 0,
-          prism2mib_fragmentationthreshold },
-    { DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime,
-          F_STA | F_READ,
-          HFA384x_RID_MAXTXLIFETIME, 0, 0,
-          prism2mib_uint32 },
+	{DIDmib_dot11mac_dot11OperationTable_dot11MACAddress,
+	 F_STA | F_READ | F_WRITE,
+	 HFA384x_RID_CNFOWNMACADDR, HFA384x_RID_CNFOWNMACADDR_LEN, 0,
+	 prism2mib_bytearea2pstr},
+	{DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold,
+	 F_STA | F_READ | F_WRITE,
+	 HFA384x_RID_RTSTHRESH, 0, 0,
+	 prism2mib_uint32},
+	{DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit,
+	 F_STA | F_READ,
+	 HFA384x_RID_SHORTRETRYLIMIT, 0, 0,
+	 prism2mib_uint32},
+	{DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit,
+	 F_STA | F_READ,
+	 HFA384x_RID_LONGRETRYLIMIT, 0, 0,
+	 prism2mib_uint32},
+	{DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold,
+	 F_STA | F_READ | F_WRITE,
+	 HFA384x_RID_FRAGTHRESH, 0, 0,
+	 prism2mib_fragmentationthreshold},
+	{DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime,
+	 F_STA | F_READ,
+	 HFA384x_RID_MAXTXLIFETIME, 0, 0,
+	 prism2mib_uint32},
 
-    /* dot11phy MIB's */
+	/* dot11phy MIB's */
 
-    { DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel,
-          F_STA | F_READ,
-          HFA384x_RID_CURRENTCHANNEL, 0, 0,
-          prism2mib_uint32 },
-    { DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel,
-          F_STA | F_READ | F_WRITE,
-          HFA384x_RID_TXPOWERMAX, 0, 0,
-          prism2mib_uint32 },
+	{DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel,
+	 F_STA | F_READ,
+	 HFA384x_RID_CURRENTCHANNEL, 0, 0,
+	 prism2mib_uint32},
+	{DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel,
+	 F_STA | F_READ | F_WRITE,
+	 HFA384x_RID_TXPOWERMAX, 0, 0,
+	 prism2mib_uint32},
 
-    /* p2Static MIB's */
+	/* p2Static MIB's */
 
-    { DIDmib_p2_p2Static_p2CnfPortType,
-          F_STA | F_READ | F_WRITE,
-          HFA384x_RID_CNFPORTTYPE, 0, 0,
-          prism2mib_uint32 },
+	{DIDmib_p2_p2Static_p2CnfPortType,
+	 F_STA | F_READ | F_WRITE,
+	 HFA384x_RID_CNFPORTTYPE, 0, 0,
+	 prism2mib_uint32},
 
-    /* p2MAC MIB's */
+	/* p2MAC MIB's */
 
-    { DIDmib_p2_p2MAC_p2CurrentTxRate,
-          F_STA | F_READ,
-          HFA384x_RID_CURRENTTXRATE, 0, 0,
-          prism2mib_uint32 },
+	{DIDmib_p2_p2MAC_p2CurrentTxRate,
+	 F_STA | F_READ,
+	 HFA384x_RID_CURRENTTXRATE, 0, 0,
+	 prism2mib_uint32},
 
-    /* And finally, lnx mibs */
-    { DIDmib_lnx_lnxConfigTable_lnxRSNAIE,
-          F_STA | F_READ | F_WRITE,
-          HFA384x_RID_CNFWPADATA, 0, 0,
-          prism2mib_priv },
-    { 0, 0, 0, 0, 0, NULL}};
-
-/*================================================================*/
-/* Function Definitions */
+	/* And finally, lnx mibs */
+	{DIDmib_lnx_lnxConfigTable_lnxRSNAIE,
+	 F_STA | F_READ | F_WRITE,
+	 HFA384x_RID_CNFWPADATA, 0, 0,
+	 prism2mib_priv},
+	{0, 0, 0, 0, 0, NULL}
+};
 
 /*----------------------------------------------------------------
 * prism2mgmt_mibset_mibget
@@ -295,32 +261,30 @@
 
 int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp)
 {
-	hfa384x_t		*hw = wlandev->priv;
-	int			result, isget;
-	mibrec_t		*mib;
+	hfa384x_t *hw = wlandev->priv;
+	int result, isget;
+	mibrec_t *mib;
 
-	u16			which;
+	u16 which;
 
-	p80211msg_dot11req_mibset_t	*msg = msgp;
-	p80211itemd_t			*mibitem;
-
-	DBFENTER;
+	p80211msg_dot11req_mibset_t *msg = msgp;
+	p80211itemd_t *mibitem;
 
 	msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
 	msg->resultcode.data = P80211ENUM_resultcode_success;
 
 	/*
-	** Determine if this is an Access Point or a station.
-	*/
+	 ** Determine if this is an Access Point or a station.
+	 */
 
 	which = F_STA;
 
 	/*
-	** Find the MIB in the MIB table.  Note that a MIB may be in the
-	** table twice...once for an AP and once for a station.  Make sure
-	** to get the correct one.  Note that DID=0 marks the end of the
-	** MIB table.
-	*/
+	 ** Find the MIB in the MIB table.  Note that a MIB may be in the
+	 ** table twice...once for an AP and once for a station.  Make sure
+	 ** to get the correct one.  Note that DID=0 marks the end of the
+	 ** MIB table.
+	 */
 
 	mibitem = (p80211itemd_t *) msg->mibattribute.data;
 
@@ -334,58 +298,55 @@
 	}
 
 	/*
-	** Determine if this is a "mibget" or a "mibset".  If this is a
-	** "mibget", then make sure that the MIB may be read.  Otherwise,
-	** this is a "mibset" so make make sure that the MIB may be written.
-	*/
+	 ** Determine if this is a "mibget" or a "mibset".  If this is a
+	 ** "mibget", then make sure that the MIB may be read.  Otherwise,
+	 ** this is a "mibset" so make make sure that the MIB may be written.
+	 */
 
 	isget = (msg->msgcode == DIDmsg_dot11req_mibget);
 
 	if (isget) {
 		if (!(mib->flag & F_READ)) {
 			msg->resultcode.data =
-				P80211ENUM_resultcode_cant_get_writeonly_mib;
+			    P80211ENUM_resultcode_cant_get_writeonly_mib;
 			goto done;
 		}
 	} else {
 		if (!(mib->flag & F_WRITE)) {
 			msg->resultcode.data =
-				P80211ENUM_resultcode_cant_set_readonly_mib;
+			    P80211ENUM_resultcode_cant_set_readonly_mib;
 			goto done;
 		}
 	}
 
 	/*
-	** Execute the MIB function.  If things worked okay, then make
-	** sure that the MIB function also worked okay.  If so, and this
-	** is a "mibget", then the status value must be set for both the
-	** "mibattribute" parameter and the mib item within the data
-	** portion of the "mibattribute".
-	*/
+	 ** Execute the MIB function.  If things worked okay, then make
+	 ** sure that the MIB function also worked okay.  If so, and this
+	 ** is a "mibget", then the status value must be set for both the
+	 ** "mibattribute" parameter and the mib item within the data
+	 ** portion of the "mibattribute".
+	 */
 
-	result = mib->func(mib, isget, wlandev, hw, msg,
-			   (void *) mibitem->data);
+	result = mib->func(mib, isget, wlandev, hw, msg, (void *)mibitem->data);
 
 	if (msg->resultcode.data == P80211ENUM_resultcode_success) {
 		if (result != 0) {
-			WLAN_LOG_DEBUG(1, "get/set failure, result=%d\n",
-					result);
+			pr_debug("get/set failure, result=%d\n",
+			       result);
 			msg->resultcode.data =
-				 P80211ENUM_resultcode_implementation_failure;
+			    P80211ENUM_resultcode_implementation_failure;
 		} else {
 			if (isget) {
 				msg->mibattribute.status =
-					P80211ENUM_msgitem_status_data_ok;
+				    P80211ENUM_msgitem_status_data_ok;
 				mibitem->status =
-					P80211ENUM_msgitem_status_data_ok;
+				    P80211ENUM_msgitem_status_data_ok;
 			}
 		}
 	}
 
 done:
-	DBFEXIT;
-
-	return(0);
+	return 0;
 }
 
 /*----------------------------------------------------------------
@@ -413,31 +374,29 @@
 *
 ----------------------------------------------------------------*/
 
-static int prism2mib_bytearea2pstr(
-mibrec_t                     *mib,
-int                          isget,
-wlandevice_t                 *wlandev,
-hfa384x_t                    *hw,
-p80211msg_dot11req_mibset_t  *msg,
-void                         *data)
+static int prism2mib_bytearea2pstr(mibrec_t *mib,
+				   int isget,
+				   wlandevice_t *wlandev,
+				   hfa384x_t *hw,
+				   p80211msg_dot11req_mibset_t *msg,
+				   void *data)
 {
-	int            result;
-	p80211pstrd_t  *pstr = (p80211pstrd_t*) data;
-	u8          bytebuf[MIB_TMP_MAXLEN];
-
-	DBFENTER;
+	int result;
+	p80211pstrd_t *pstr = (p80211pstrd_t *) data;
+	u8 bytebuf[MIB_TMP_MAXLEN];
 
 	if (isget) {
-		result = hfa384x_drvr_getconfig(hw, mib->parm1, bytebuf, mib->parm2);
+		result =
+		    hfa384x_drvr_getconfig(hw, mib->parm1, bytebuf, mib->parm2);
 		prism2mgmt_bytearea2pstr(bytebuf, pstr, mib->parm2);
 	} else {
 		memset(bytebuf, 0, mib->parm2);
 		prism2mgmt_pstr2bytearea(bytebuf, pstr);
-		result = hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, mib->parm2);
+		result =
+		    hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, mib->parm2);
 	}
 
-	DBFEXIT;
-	return(result);
+	return result;
 }
 
 /*----------------------------------------------------------------
@@ -465,37 +424,26 @@
 *
 ----------------------------------------------------------------*/
 
-static int prism2mib_uint32(
-mibrec_t                     *mib,
-int                          isget,
-wlandevice_t                 *wlandev,
-hfa384x_t                    *hw,
-p80211msg_dot11req_mibset_t  *msg,
-void                         *data)
+static int prism2mib_uint32(mibrec_t *mib,
+			    int isget,
+			    wlandevice_t *wlandev,
+			    hfa384x_t *hw,
+			    p80211msg_dot11req_mibset_t *msg, void *data)
 {
-	int     result;
-	u32  *uint32 = (u32*) data;
-	u8   bytebuf[MIB_TMP_MAXLEN];
-	u16  *wordbuf = (u16*) bytebuf;
-
-	DBFENTER;
+	int result;
+	u32 *uint32 = (u32 *) data;
+	u8 bytebuf[MIB_TMP_MAXLEN];
+	u16 *wordbuf = (u16 *) bytebuf;
 
 	if (isget) {
 		result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf);
 		*uint32 = *wordbuf;
-		/* [MSM] Removed, getconfig16 returns the value in host order.
-		 * prism2mgmt_prism2int2p80211int(wordbuf, uint32);
-		 */
 	} else {
-		/* [MSM] Removed, setconfig16 expects host order.
-		 * prism2mgmt_p80211int2prism2int(wordbuf, uint32);
-		 */
 		*wordbuf = *uint32;
 		result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf);
 	}
 
-	DBFEXIT;
-	return(result);
+	return result;
 }
 
 /*----------------------------------------------------------------
@@ -523,46 +471,36 @@
 *
 ----------------------------------------------------------------*/
 
-static int prism2mib_flag(
-mibrec_t                     *mib,
-int                          isget,
-wlandevice_t                 *wlandev,
-hfa384x_t                    *hw,
-p80211msg_dot11req_mibset_t  *msg,
-void                         *data)
+static int prism2mib_flag(mibrec_t *mib,
+			  int isget,
+			  wlandevice_t *wlandev,
+			  hfa384x_t *hw,
+			  p80211msg_dot11req_mibset_t *msg, void *data)
 {
-	int     result;
-	u32  *uint32 = (u32*) data;
-	u8   bytebuf[MIB_TMP_MAXLEN];
-	u16  *wordbuf = (u16*) bytebuf;
-	u32  flags;
-
-	DBFENTER;
+	int result;
+	u32 *uint32 = (u32 *) data;
+	u8 bytebuf[MIB_TMP_MAXLEN];
+	u16 *wordbuf = (u16 *) bytebuf;
+	u32 flags;
 
 	result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf);
 	if (result == 0) {
-		/* [MSM] Removed, getconfig16 returns the value in host order.
-		 * prism2mgmt_prism2int2p80211int(wordbuf, &flags);
-		 */
 		flags = *wordbuf;
 		if (isget) {
 			*uint32 = (flags & mib->parm2) ?
-				P80211ENUM_truth_true : P80211ENUM_truth_false;
+			    P80211ENUM_truth_true : P80211ENUM_truth_false;
 		} else {
 			if ((*uint32) == P80211ENUM_truth_true)
 				flags |= mib->parm2;
 			else
 				flags &= ~mib->parm2;
-			/* [MSM] Removed, setconfig16 expects host order.
-			 * prism2mgmt_p80211int2prism2int(wordbuf, &flags);
-			 */
 			*wordbuf = flags;
-			result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf);
+			result =
+			    hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf);
 		}
 	}
 
-	DBFEXIT;
-	return(result);
+	return result;
 }
 
 /*----------------------------------------------------------------
@@ -590,33 +528,29 @@
 *
 ----------------------------------------------------------------*/
 
-static int prism2mib_wepdefaultkey(
-mibrec_t                     *mib,
-int                          isget,
-wlandevice_t                 *wlandev,
-hfa384x_t                    *hw,
-p80211msg_dot11req_mibset_t  *msg,
-void                         *data)
+static int prism2mib_wepdefaultkey(mibrec_t *mib,
+				   int isget,
+				   wlandevice_t *wlandev,
+				   hfa384x_t *hw,
+				   p80211msg_dot11req_mibset_t *msg,
+				   void *data)
 {
-	int            result;
-	p80211pstrd_t  *pstr = (p80211pstrd_t*) data;
-	u8          bytebuf[MIB_TMP_MAXLEN];
-	u16         len;
-
-	DBFENTER;
+	int result;
+	p80211pstrd_t *pstr = (p80211pstrd_t *) data;
+	u8 bytebuf[MIB_TMP_MAXLEN];
+	u16 len;
 
 	if (isget) {
-		result = 0;    /* Should never happen. */
+		result = 0;	/* Should never happen. */
 	} else {
 		len = (pstr->len > 5) ? HFA384x_RID_CNFWEP128DEFAULTKEY_LEN :
-					HFA384x_RID_CNFWEPDEFAULTKEY_LEN;
+		    HFA384x_RID_CNFWEPDEFAULTKEY_LEN;
 		memset(bytebuf, 0, len);
 		prism2mgmt_pstr2bytearea(bytebuf, pstr);
 		result = hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, len);
 	}
 
-	DBFEXIT;
-	return(result);
+	return result;
 }
 
 /*----------------------------------------------------------------
@@ -644,17 +578,14 @@
 *
 ----------------------------------------------------------------*/
 
-static int prism2mib_privacyinvoked(
-mibrec_t                     *mib,
-int                          isget,
-wlandevice_t                 *wlandev,
-hfa384x_t                    *hw,
-p80211msg_dot11req_mibset_t  *msg,
-void                         *data)
+static int prism2mib_privacyinvoked(mibrec_t *mib,
+				    int isget,
+				    wlandevice_t *wlandev,
+				    hfa384x_t *hw,
+				    p80211msg_dot11req_mibset_t *msg,
+				    void *data)
 {
-	int     result;
-
-	DBFENTER;
+	int result;
 
 	if (wlandev->hostwep & HOSTWEP_DECRYPT) {
 		if (wlandev->hostwep & HOSTWEP_DECRYPT)
@@ -665,8 +596,7 @@
 
 	result = prism2mib_flag(mib, isget, wlandev, hw, msg, data);
 
-	DBFEXIT;
-	return(result);
+	return result;
 }
 
 /*----------------------------------------------------------------
@@ -694,22 +624,18 @@
 *
 ----------------------------------------------------------------*/
 
-static int prism2mib_excludeunencrypted(
-mibrec_t                     *mib,
-int                          isget,
-wlandevice_t                 *wlandev,
-hfa384x_t                    *hw,
-p80211msg_dot11req_mibset_t  *msg,
-void                         *data)
+static int prism2mib_excludeunencrypted(mibrec_t *mib,
+					int isget,
+					wlandevice_t *wlandev,
+					hfa384x_t *hw,
+					p80211msg_dot11req_mibset_t *msg,
+					void *data)
 {
-	int     result;
-
-	DBFENTER;
+	int result;
 
 	result = prism2mib_flag(mib, isget, wlandev, hw, msg, data);
 
-	DBFEXIT;
-	return(result);
+	return result;
 }
 
 /*----------------------------------------------------------------
@@ -737,31 +663,28 @@
 *
 ----------------------------------------------------------------*/
 
-static int prism2mib_fragmentationthreshold(
-mibrec_t                     *mib,
-int                          isget,
-wlandevice_t                 *wlandev,
-hfa384x_t                    *hw,
-p80211msg_dot11req_mibset_t  *msg,
-void                         *data)
+static int prism2mib_fragmentationthreshold(mibrec_t *mib,
+					    int isget,
+					    wlandevice_t *wlandev,
+					    hfa384x_t *hw,
+					    p80211msg_dot11req_mibset_t *msg,
+					    void *data)
 {
-	int     result;
-	u32  *uint32 = (u32*) data;
-
-	DBFENTER;
+	int result;
+	u32 *uint32 = (u32 *) data;
 
 	if (!isget)
 		if ((*uint32) % 2) {
-			WLAN_LOG_WARNING("Attempt to set odd number "
-					  "FragmentationThreshold\n");
-			msg->resultcode.data = P80211ENUM_resultcode_not_supported;
-			return(0);
+			printk(KERN_WARNING "Attempt to set odd number "
+			       "FragmentationThreshold\n");
+			msg->resultcode.data =
+			    P80211ENUM_resultcode_not_supported;
+			return 0;
 		}
 
 	result = prism2mib_uint32(mib, isget, wlandev, hw, msg, data);
 
-	DBFEXIT;
-	return(result);
+	return result;
 }
 
 /*----------------------------------------------------------------
@@ -789,43 +712,43 @@
 *
 ----------------------------------------------------------------*/
 
-static int prism2mib_priv(
-mibrec_t                     *mib,
-int                          isget,
-wlandevice_t                 *wlandev,
-hfa384x_t                    *hw,
-p80211msg_dot11req_mibset_t  *msg,
-void                         *data)
+static int prism2mib_priv(mibrec_t *mib,
+			  int isget,
+			  wlandevice_t *wlandev,
+			  hfa384x_t *hw,
+			  p80211msg_dot11req_mibset_t *msg, void *data)
 {
-	p80211pstrd_t     *pstr = (p80211pstrd_t*) data;
+	p80211pstrd_t *pstr = (p80211pstrd_t *) data;
 
-	int  result;
-
-	DBFENTER;
+	int result;
 
 	switch (mib->did) {
-	case DIDmib_lnx_lnxConfigTable_lnxRSNAIE: {
-		hfa384x_WPAData_t wpa;
-		if (isget) {
-			hfa384x_drvr_getconfig( hw, HFA384x_RID_CNFWPADATA,
-						(u8 *) &wpa, sizeof(wpa));
-			pstr->len = hfa384x2host_16(wpa.datalen);
-			memcpy(pstr->data, wpa.data, pstr->len);
-		} else {
-			wpa.datalen = host2hfa384x_16(pstr->len);
-			memcpy(wpa.data, pstr->data, pstr->len);
+	case DIDmib_lnx_lnxConfigTable_lnxRSNAIE:{
+			hfa384x_WPAData_t wpa;
+			if (isget) {
+				hfa384x_drvr_getconfig(hw,
+						       HFA384x_RID_CNFWPADATA,
+						       (u8 *)&wpa,
+						       sizeof(wpa));
+				pstr->len = le16_to_cpu(wpa.datalen);
+				memcpy(pstr->data, wpa.data, pstr->len);
+			} else {
+				wpa.datalen = cpu_to_le16(pstr->len);
+				memcpy(wpa.data, pstr->data, pstr->len);
 
-			result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFWPADATA,
-				(u8 *) &wpa, sizeof(wpa));
+				result =
+				    hfa384x_drvr_setconfig(hw,
+							   HFA384x_RID_CNFWPADATA,
+							   (u8 *)&wpa,
+							   sizeof(wpa));
+			}
+			break;
 		}
-		break;
-	}
 	default:
-		WLAN_LOG_ERROR("Unhandled DID 0x%08x\n", mib->did);
+		printk(KERN_ERR "Unhandled DID 0x%08x\n", mib->did);
 	}
 
-	DBFEXIT;
-	return(0);
+	return 0;
 }
 
 /*----------------------------------------------------------------
@@ -845,14 +768,10 @@
 
 void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr)
 {
-	DBFENTER;
-
-	bytestr->len = host2hfa384x_16((u16)(pstr->len));
+	bytestr->len = cpu_to_le16((u16) (pstr->len));
 	memcpy(bytestr->data, pstr->data, pstr->len);
-	DBFEXIT;
 }
 
-
 /*----------------------------------------------------------------
 * prism2mgmt_pstr2bytearea
 *
@@ -870,13 +789,9 @@
 
 void prism2mgmt_pstr2bytearea(u8 *bytearea, p80211pstrd_t *pstr)
 {
-	DBFENTER;
-
 	memcpy(bytearea, pstr->data, pstr->len);
-	DBFEXIT;
 }
 
-
 /*----------------------------------------------------------------
 * prism2mgmt_bytestr2pstr
 *
@@ -894,14 +809,10 @@
 
 void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr)
 {
-	DBFENTER;
-
-	pstr->len = (u8)(hfa384x2host_16((u16)(bytestr->len)));
+	pstr->len = (u8) (le16_to_cpu((u16) (bytestr->len)));
 	memcpy(pstr->data, bytestr->data, pstr->len);
-	DBFEXIT;
 }
 
-
 /*----------------------------------------------------------------
 * prism2mgmt_bytearea2pstr
 *
@@ -919,217 +830,11 @@
 
 void prism2mgmt_bytearea2pstr(u8 *bytearea, p80211pstrd_t *pstr, int len)
 {
-	DBFENTER;
-
-	pstr->len = (u8)len;
+	pstr->len = (u8) len;
 	memcpy(pstr->data, bytearea, len);
-	DBFEXIT;
-}
-
-
-/*----------------------------------------------------------------
-* prism2mgmt_prism2int2p80211int
-*
-* Convert an hfa384x integer into a wlan integer
-*
-* Arguments:
-*	prism2enum	pointer to hfa384x integer
-*	wlanenum	pointer to p80211 integer
-*
-* Returns:
-*	Nothing
-*
-----------------------------------------------------------------*/
-
-void prism2mgmt_prism2int2p80211int(u16 *prism2int, u32 *wlanint)
-{
-	DBFENTER;
-
-	*wlanint = (u32)hfa384x2host_16(*prism2int);
-	DBFEXIT;
-}
-
-
-/*----------------------------------------------------------------
-* prism2mgmt_p80211int2prism2int
-*
-* Convert a wlan integer into an hfa384x integer
-*
-* Arguments:
-*	prism2enum	pointer to hfa384x integer
-*	wlanenum	pointer to p80211 integer
-*
-* Returns:
-*	Nothing
-*
-----------------------------------------------------------------*/
-
-void prism2mgmt_p80211int2prism2int(u16 *prism2int, u32 *wlanint)
-{
-	DBFENTER;
-
-	*prism2int = host2hfa384x_16((u16)(*wlanint));
-	DBFEXIT;
-}
-
-
-/*----------------------------------------------------------------
-* prism2mgmt_prism2enum2p80211enum
-*
-* Convert the hfa384x enumerated int into a p80211 enumerated int
-*
-* Arguments:
-*	prism2enum	pointer to hfa384x integer
-*	wlanenum	pointer to p80211 integer
-*	rid		hfa384x record id
-*
-* Returns:
-*	Nothing
-*
-----------------------------------------------------------------*/
-void prism2mgmt_prism2enum2p80211enum(u16 *prism2enum, u32 *wlanenum, u16 rid)
-{
-	DBFENTER;
-
-	/* At the moment, the need for this functionality hasn't
-	presented itself. All the wlan enumerated values are
-	a 1-to-1 match against the Prism2 enumerated values*/
-	DBFEXIT;
-	return;
-}
-
-
-/*----------------------------------------------------------------
-* prism2mgmt_p80211enum2prism2enum
-*
-* Convert the p80211 enumerated int into an hfa384x enumerated int
-*
-* Arguments:
-*	prism2enum	pointer to hfa384x integer
-*	wlanenum	pointer to p80211 integer
-*	rid		hfa384x record id
-*
-* Returns:
-*	Nothing
-*
-----------------------------------------------------------------*/
-void prism2mgmt_p80211enum2prism2enum(u16 *prism2enum, u32 *wlanenum, u16 rid)
-{
-	DBFENTER;
-
-	/* At the moment, the need for this functionality hasn't
-	presented itself. All the wlan enumerated values are
-	a 1-to-1 match against the Prism2 enumerated values*/
-	DBFEXIT;
-	return;
 }
 
 
 
-/*----------------------------------------------------------------
-* prism2mgmt_get_oprateset
-*
-* Convert the hfa384x bit area into a wlan octet string.
-*
-* Arguments:
-*	rate		Prism2 bit area
-*	pstr		wlan octet string
-*
-* Returns:
-*	Nothing
-*
-----------------------------------------------------------------*/
-void prism2mgmt_get_oprateset(u16 *rate, p80211pstrd_t *pstr)
-{
-	u8	len;
-	u8	*datarate;
-
-	DBFENTER;
-
-	len = 0;
-	datarate = pstr->data;
-
- 	/* 1 Mbps */
-	if ( BIT0 & (*rate) ) {
-		len += (u8)1;
-		*datarate = (u8)2;
-		datarate++;
-	}
-
- 	/* 2 Mbps */
-	if ( BIT1 & (*rate) ) {
-		len += (u8)1;
-		*datarate = (u8)4;
-		datarate++;
-	}
-
- 	/* 5.5 Mbps */
-	if ( BIT2 & (*rate) ) {
-		len += (u8)1;
-		*datarate = (u8)11;
-		datarate++;
-	}
-
- 	/* 11 Mbps */
-	if ( BIT3 & (*rate) ) {
-		len += (u8)1;
-		*datarate = (u8)22;
-		datarate++;
-	}
-
-	pstr->len = len;
-
-	DBFEXIT;
-	return;
-}
 
 
-
-/*----------------------------------------------------------------
-* prism2mgmt_set_oprateset
-*
-* Convert the wlan octet string into an hfa384x bit area.
-*
-* Arguments:
-*	rate		Prism2 bit area
-*	pstr		wlan octet string
-*
-* Returns:
-*	Nothing
-*
-----------------------------------------------------------------*/
-void prism2mgmt_set_oprateset(u16 *rate, p80211pstrd_t *pstr)
-{
-	u8	*datarate;
-	int	i;
-
-	DBFENTER;
-
-	*rate = 0;
-
-	datarate = pstr->data;
-
-	for ( i=0; i < pstr->len; i++, datarate++ ) {
-		switch (*datarate) {
-		case 2: /* 1 Mbps */
-			*rate |= BIT0;
-			break;
-		case 4: /* 2 Mbps */
-			*rate |= BIT1;
-			break;
-		case 11: /* 5.5 Mbps */
-			*rate |= BIT2;
-			break;
-		case 22: /* 11 Mbps */
-			*rate |= BIT3;
-			break;
-		default:
-			WLAN_LOG_DEBUG(1, "Unrecoginzed Rate of %d\n",
-				*datarate);
-			break;
-		}
-	}
-
-	DBFEXIT;
-	return;
-}
diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c
index b279c97..9d57f82 100644
--- a/drivers/staging/wlan-ng/prism2sta.c
+++ b/drivers/staging/wlan-ng/prism2sta.c
@@ -50,10 +50,6 @@
 * --------------------------------------------------------------------
 */
 
-/*================================================================*/
-/* System Includes */
-#define WLAN_DBVAR	prism2_debug
-
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -65,13 +61,15 @@
 #include <linux/wireless.h>
 #include <linux/netdevice.h>
 #include <linux/workqueue.h>
+#include <linux/byteorder/generic.h>
+#include <linux/ctype.h>
 
 #include <asm/io.h>
 #include <linux/delay.h>
 #include <asm/byteorder.h>
 #include <linux/if_arp.h>
-
-#include "wlan_compat.h"
+#include <linux/if_ether.h>
+#include <linux/bitops.h>
 
 /*================================================================*/
 /* Project Includes */
@@ -88,111 +86,78 @@
 #include "hfa384x.h"
 #include "prism2mgmt.h"
 
-/*================================================================*/
-/* Local Constants */
+#define wlan_hexchar(x) (((x) < 0x0a) ? ('0' + (x)) : ('a' + ((x) - 0x0a)))
 
-/*================================================================*/
-/* Local Macros */
-
-/*================================================================*/
-/* Local Types */
-
-/*================================================================*/
-/* Local Static Definitions */
+/* Create a string of printable chars from something that might not be */
+/* It's recommended that the str be 4*len + 1 bytes long */
+#define wlan_mkprintstr(buf, buflen, str, strlen) \
+{ \
+	int i = 0; \
+	int j = 0; \
+	memset(str, 0, (strlen)); \
+	for (i = 0; i < (buflen); i++) { \
+		if (isprint((buf)[i])) { \
+			(str)[j] = (buf)[i]; \
+			j++; \
+		} else { \
+			(str)[j] = '\\'; \
+			(str)[j+1] = 'x'; \
+			(str)[j+2] = wlan_hexchar(((buf)[i] & 0xf0) >> 4); \
+			(str)[j+3] = wlan_hexchar(((buf)[i] & 0x0f)); \
+			j += 4; \
+		} \
+	} \
+}
 
 static char *dev_info = "prism2_usb";
-
 static wlandevice_t *create_wlan(void);
 
-/*----------------------------------------------------------------*/
-/* --Module Parameters */
+int prism2_reset_holdtime = 30;	/* Reset hold time in ms */
+int prism2_reset_settletime = 100;	/* Reset settle time in ms */
 
-int      prism2_reset_holdtime=30;	/* Reset hold time in ms */
-int	 prism2_reset_settletime=100;	/* Reset settle time in ms */
+static int prism2_doreset = 0;	/* Do a reset at init? */
 
-static int	prism2_doreset=0;		/* Do a reset at init? */
-
-#ifdef WLAN_INCLUDE_DEBUG
-int prism2_debug=0;
-module_param( prism2_debug, int, 0644);
-MODULE_PARM_DESC(prism2_debug, "prism2 debugging");
-#endif
-
-module_param( prism2_doreset, int, 0644);
+module_param(prism2_doreset, int, 0644);
 MODULE_PARM_DESC(prism2_doreset, "Issue a reset on initialization");
 
-module_param( prism2_reset_holdtime, int, 0644);
-MODULE_PARM_DESC( prism2_reset_holdtime, "reset hold time in ms");
-module_param( prism2_reset_settletime, int, 0644);
-MODULE_PARM_DESC( prism2_reset_settletime, "reset settle time in ms");
+module_param(prism2_reset_holdtime, int, 0644);
+MODULE_PARM_DESC(prism2_reset_holdtime, "reset hold time in ms");
+module_param(prism2_reset_settletime, int, 0644);
+MODULE_PARM_DESC(prism2_reset_settletime, "reset settle time in ms");
 
 MODULE_LICENSE("Dual MPL/GPL");
 
-/*================================================================*/
-/* Local Function Declarations */
+static int prism2sta_open(wlandevice_t *wlandev);
+static int prism2sta_close(wlandevice_t *wlandev);
+static void prism2sta_reset(wlandevice_t *wlandev);
+static int prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb,
+			     p80211_hdr_t *p80211_hdr,
+			     p80211_metawep_t *p80211_wep);
+static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg);
+static int prism2sta_getcardinfo(wlandevice_t *wlandev);
+static int prism2sta_globalsetup(wlandevice_t *wlandev);
+static int prism2sta_setmulticast(wlandevice_t *wlandev, netdevice_t *dev);
 
-static int	prism2sta_open(wlandevice_t *wlandev);
-static int	prism2sta_close(wlandevice_t *wlandev);
-static void	prism2sta_reset(wlandevice_t *wlandev );
-static int      prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep);
-static int	prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg);
-static int	prism2sta_getcardinfo(wlandevice_t *wlandev);
-static int	prism2sta_globalsetup(wlandevice_t *wlandev);
-static int      prism2sta_setmulticast(wlandevice_t *wlandev,
-				       netdevice_t *dev);
-
-static void	prism2sta_inf_handover(
-			wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
-static void	prism2sta_inf_tallies(
-			wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
-static void     prism2sta_inf_hostscanresults(
-			wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
-static void	prism2sta_inf_scanresults(
-			wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
-static void	prism2sta_inf_chinforesults(
-			wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
-static void	prism2sta_inf_linkstatus(
-			wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
-static void	prism2sta_inf_assocstatus(
-			wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
-static void	prism2sta_inf_authreq(
-			wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
-static void	prism2sta_inf_authreq_defer(
-			wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
-static void	prism2sta_inf_psusercnt(
-			wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
-
-/*================================================================*/
-/* Function Definitions */
-
-/*----------------------------------------------------------------
-* dmpmem
-*
-* Debug utility function to dump memory to the kernel debug log.
-*
-* Arguments:
-*	buf	ptr data we want dumped
-*	len	length of data
-*
-* Returns:
-*	nothing
-* Side effects:
-*
-* Call context:
-*	process thread
-*	interrupt
-----------------------------------------------------------------*/
-inline void dmpmem(void *buf, int n)
-{
-	int c;
-	for ( c= 0; c < n; c++) {
-		if ( (c % 16) == 0 ) printk(KERN_DEBUG"dmp[%d]: ", c);
-		printk("%02x ", ((u8*)buf)[c]);
-		if ( (c % 16) == 15 ) printk("\n");
-	}
-	if ( (c % 16) != 0 ) printk("\n");
-}
-
+static void prism2sta_inf_handover(wlandevice_t *wlandev,
+				   hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_tallies(wlandevice_t *wlandev,
+				  hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_hostscanresults(wlandevice_t *wlandev,
+					  hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_scanresults(wlandevice_t *wlandev,
+				      hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_chinforesults(wlandevice_t *wlandev,
+					hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_linkstatus(wlandevice_t *wlandev,
+				     hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_assocstatus(wlandevice_t *wlandev,
+				      hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_authreq(wlandevice_t *wlandev,
+				  hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_authreq_defer(wlandevice_t *wlandev,
+					hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_psusercnt(wlandevice_t *wlandev,
+				    hfa384x_InfFrame_t *inf);
 
 /*----------------------------------------------------------------
 * prism2sta_open
@@ -217,8 +182,6 @@
 ----------------------------------------------------------------*/
 static int prism2sta_open(wlandevice_t *wlandev)
 {
-	DBFENTER;
-
 	/* We don't currently have to do anything else.
 	 * The setup of the MAC should be subsequently completed via
 	 * the mlme commands.
@@ -227,11 +190,9 @@
 	 * frames because of dev->flags&IFF_UP is true.
 	 */
 
-	DBFEXIT;
 	return 0;
 }
 
-
 /*----------------------------------------------------------------
 * prism2sta_close
 *
@@ -255,19 +216,15 @@
 ----------------------------------------------------------------*/
 static int prism2sta_close(wlandevice_t *wlandev)
 {
-	DBFENTER;
-
 	/* We don't currently have to do anything else.
 	 * Higher layers know we're not ready from dev->start==0 and
 	 * dev->tbusy==1.  Our rx path knows to not pass up received
 	 * frames because of dev->flags&IFF_UP is false.
 	 */
 
-	DBFEXIT;
 	return 0;
 }
 
-
 /*----------------------------------------------------------------
 * prism2sta_reset
 *
@@ -285,14 +242,11 @@
 * Call context:
 *	process thread
 ----------------------------------------------------------------*/
-static void prism2sta_reset(wlandevice_t *wlandev )
+static void prism2sta_reset(wlandevice_t *wlandev)
 {
-	DBFENTER;
-	DBFEXIT;
 	return;
 }
 
-
 /*----------------------------------------------------------------
 * prism2sta_txframe
 *
@@ -318,22 +272,20 @@
 			     p80211_hdr_t *p80211_hdr,
 			     p80211_metawep_t *p80211_wep)
 {
-	hfa384x_t		*hw = (hfa384x_t *)wlandev->priv;
-	int			result;
-	DBFENTER;
+	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+	int result;
 
 	/* If necessary, set the 802.11 WEP bit */
-	if ((wlandev->hostwep & (HOSTWEP_PRIVACYINVOKED | HOSTWEP_ENCRYPT)) == HOSTWEP_PRIVACYINVOKED) {
-		p80211_hdr->a3.fc |= host2ieee16(WLAN_SET_FC_ISWEP(1));
+	if ((wlandev->hostwep & (HOSTWEP_PRIVACYINVOKED | HOSTWEP_ENCRYPT)) ==
+	    HOSTWEP_PRIVACYINVOKED) {
+		p80211_hdr->a3.fc |= cpu_to_le16(WLAN_SET_FC_ISWEP(1));
 	}
 
 	result = hfa384x_drvr_txframe(hw, skb, p80211_hdr, p80211_wep);
 
-	DBFEXIT;
 	return result;
 }
 
-
 /*----------------------------------------------------------------
 * prism2sta_mlmerequest
 *
@@ -360,109 +312,113 @@
 ----------------------------------------------------------------*/
 static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg)
 {
-        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
+	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
 
 	int result = 0;
-	DBFENTER;
 
-	switch( msg->msgcode )
-	{
-	case DIDmsg_dot11req_mibget :
-		WLAN_LOG_DEBUG(2,"Received mibget request\n");
+	switch (msg->msgcode) {
+	case DIDmsg_dot11req_mibget:
+		pr_debug("Received mibget request\n");
 		result = prism2mgmt_mibset_mibget(wlandev, msg);
 		break;
-	case DIDmsg_dot11req_mibset :
-		WLAN_LOG_DEBUG(2,"Received mibset request\n");
+	case DIDmsg_dot11req_mibset:
+		pr_debug("Received mibset request\n");
 		result = prism2mgmt_mibset_mibget(wlandev, msg);
 		break;
-	case DIDmsg_dot11req_scan :
-		WLAN_LOG_DEBUG(2,"Received scan request\n");
+	case DIDmsg_dot11req_scan:
+		pr_debug("Received scan request\n");
 		result = prism2mgmt_scan(wlandev, msg);
 		break;
-	case DIDmsg_dot11req_scan_results :
-		WLAN_LOG_DEBUG(2,"Received scan_results request\n");
+	case DIDmsg_dot11req_scan_results:
+		pr_debug("Received scan_results request\n");
 		result = prism2mgmt_scan_results(wlandev, msg);
 		break;
-	case DIDmsg_dot11req_start :
-		WLAN_LOG_DEBUG(2,"Received mlme start request\n");
+	case DIDmsg_dot11req_start:
+		pr_debug("Received mlme start request\n");
 		result = prism2mgmt_start(wlandev, msg);
 		break;
-	/*
-	 * Prism2 specific messages
-	 */
-       	case DIDmsg_p2req_readpda :
-		WLAN_LOG_DEBUG(2,"Received mlme readpda request\n");
+		/*
+		 * Prism2 specific messages
+		 */
+	case DIDmsg_p2req_readpda:
+		pr_debug("Received mlme readpda request\n");
 		result = prism2mgmt_readpda(wlandev, msg);
 		break;
-	case DIDmsg_p2req_ramdl_state :
-		WLAN_LOG_DEBUG(2,"Received mlme ramdl_state request\n");
+	case DIDmsg_p2req_ramdl_state:
+		pr_debug("Received mlme ramdl_state request\n");
 		result = prism2mgmt_ramdl_state(wlandev, msg);
 		break;
-	case DIDmsg_p2req_ramdl_write :
-		WLAN_LOG_DEBUG(2,"Received mlme ramdl_write request\n");
+	case DIDmsg_p2req_ramdl_write:
+		pr_debug("Received mlme ramdl_write request\n");
 		result = prism2mgmt_ramdl_write(wlandev, msg);
 		break;
-	case DIDmsg_p2req_flashdl_state :
-		WLAN_LOG_DEBUG(2,"Received mlme flashdl_state request\n");
+	case DIDmsg_p2req_flashdl_state:
+		pr_debug("Received mlme flashdl_state request\n");
 		result = prism2mgmt_flashdl_state(wlandev, msg);
 		break;
-	case DIDmsg_p2req_flashdl_write :
-		WLAN_LOG_DEBUG(2,"Received mlme flashdl_write request\n");
+	case DIDmsg_p2req_flashdl_write:
+		pr_debug("Received mlme flashdl_write request\n");
 		result = prism2mgmt_flashdl_write(wlandev, msg);
 		break;
-	/*
-	 * Linux specific messages
-	 */
-	case DIDmsg_lnxreq_hostwep :
-		break;   // ignore me.
-        case DIDmsg_lnxreq_ifstate :
+		/*
+		 * Linux specific messages
+		 */
+	case DIDmsg_lnxreq_hostwep:
+		break;		/* ignore me. */
+	case DIDmsg_lnxreq_ifstate:
 		{
-		p80211msg_lnxreq_ifstate_t	*ifstatemsg;
-                WLAN_LOG_DEBUG(2,"Received mlme ifstate request\n");
-		ifstatemsg = (p80211msg_lnxreq_ifstate_t*)msg;
-                result = prism2sta_ifstate(wlandev, ifstatemsg->ifstate.data);
-		ifstatemsg->resultcode.status =
-			P80211ENUM_msgitem_status_data_ok;
-		ifstatemsg->resultcode.data = result;
-		result = 0;
+			p80211msg_lnxreq_ifstate_t *ifstatemsg;
+			pr_debug("Received mlme ifstate request\n");
+			ifstatemsg = (p80211msg_lnxreq_ifstate_t *) msg;
+			result =
+			    prism2sta_ifstate(wlandev,
+					      ifstatemsg->ifstate.data);
+			ifstatemsg->resultcode.status =
+			    P80211ENUM_msgitem_status_data_ok;
+			ifstatemsg->resultcode.data = result;
+			result = 0;
 		}
-                break;
-        case DIDmsg_lnxreq_wlansniff :
-                WLAN_LOG_DEBUG(2,"Received mlme wlansniff request\n");
-                result = prism2mgmt_wlansniff(wlandev, msg);
-                break;
-	case DIDmsg_lnxreq_autojoin :
-		WLAN_LOG_DEBUG(2,"Received mlme autojoin request\n");
+		break;
+	case DIDmsg_lnxreq_wlansniff:
+		pr_debug("Received mlme wlansniff request\n");
+		result = prism2mgmt_wlansniff(wlandev, msg);
+		break;
+	case DIDmsg_lnxreq_autojoin:
+		pr_debug("Received mlme autojoin request\n");
 		result = prism2mgmt_autojoin(wlandev, msg);
 		break;
-	case DIDmsg_lnxreq_commsquality: {
-		p80211msg_lnxreq_commsquality_t *qualmsg;
+	case DIDmsg_lnxreq_commsquality:{
+			p80211msg_lnxreq_commsquality_t *qualmsg;
 
-		WLAN_LOG_DEBUG(2,"Received commsquality request\n");
+			pr_debug("Received commsquality request\n");
 
-		qualmsg = (p80211msg_lnxreq_commsquality_t*) msg;
+			qualmsg = (p80211msg_lnxreq_commsquality_t *) msg;
 
-		qualmsg->link.status = P80211ENUM_msgitem_status_data_ok;
-		qualmsg->level.status = P80211ENUM_msgitem_status_data_ok;
-		qualmsg->noise.status = P80211ENUM_msgitem_status_data_ok;
+			qualmsg->link.status =
+			    P80211ENUM_msgitem_status_data_ok;
+			qualmsg->level.status =
+			    P80211ENUM_msgitem_status_data_ok;
+			qualmsg->noise.status =
+			    P80211ENUM_msgitem_status_data_ok;
 
+			qualmsg->link.data =
+			    le16_to_cpu(hw->qual.CQ_currBSS);
+			qualmsg->level.data =
+			    le16_to_cpu(hw->qual.ASL_currBSS);
+			qualmsg->noise.data =
+			    le16_to_cpu(hw->qual.ANL_currFC);
 
-		qualmsg->link.data = hfa384x2host_16(hw->qual.CQ_currBSS);
-		qualmsg->level.data = hfa384x2host_16(hw->qual.ASL_currBSS);
-		qualmsg->noise.data = hfa384x2host_16(hw->qual.ANL_currFC);
-
-		break;
-	}
+			break;
+		}
 	default:
-		WLAN_LOG_WARNING("Unknown mgmt request message 0x%08x", msg->msgcode);
+		printk(KERN_WARNING "Unknown mgmt request message 0x%08x",
+		       msg->msgcode);
 		break;
 	}
 
-	DBFEXIT;
 	return result;
 }
 
-
 /*----------------------------------------------------------------
 * prism2sta_ifstate
 *
@@ -486,16 +442,14 @@
 ----------------------------------------------------------------*/
 u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate)
 {
-        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
-	u32 			result;
-	DBFENTER;
+	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+	u32 result;
 
 	result = P80211ENUM_resultcode_implementation_failure;
 
-	WLAN_LOG_DEBUG(2, "Current MSD state(%d), requesting(%d)\n",
-	                  wlandev->msdstate, ifstate);
-	switch (ifstate)
-	{
+	pr_debug("Current MSD state(%d), requesting(%d)\n",
+	       wlandev->msdstate, ifstate);
+	switch (ifstate) {
 	case P80211ENUM_ifstate_fwload:
 		switch (wlandev->msdstate) {
 		case WLAN_MSD_HWPRESENT:
@@ -504,12 +458,12 @@
 			 * Initialize the device+driver sufficiently
 			 * for firmware loading.
 			 */
-			if ((result=hfa384x_drvr_start(hw))) {
-				WLAN_LOG_ERROR(
-					"hfa384x_drvr_start() failed,"
-					"result=%d\n", (int)result);
+			if ((result = hfa384x_drvr_start(hw))) {
+				printk(KERN_ERR
+				       "hfa384x_drvr_start() failed,"
+				       "result=%d\n", (int)result);
 				result =
-				P80211ENUM_resultcode_implementation_failure;
+				    P80211ENUM_resultcode_implementation_failure;
 				wlandev->msdstate = WLAN_MSD_HWPRESENT;
 				break;
 			}
@@ -521,9 +475,9 @@
 			result = P80211ENUM_resultcode_success;
 			break;
 		case WLAN_MSD_RUNNING:
-			WLAN_LOG_WARNING(
-				"Cannot enter fwload state from enable state,"
-				"you must disable first.\n");
+			printk(KERN_WARNING
+			       "Cannot enter fwload state from enable state,"
+			       "you must disable first.\n");
 			result = P80211ENUM_resultcode_invalid_parameters;
 			break;
 		case WLAN_MSD_HWFAIL:
@@ -548,32 +502,32 @@
 			 * can't make any assumptions about the state
 			 * of the hardware or a previous firmware load.
 			 */
-			if ((result=hfa384x_drvr_start(hw))) {
-				WLAN_LOG_ERROR(
-					"hfa384x_drvr_start() failed,"
-					"result=%d\n", (int)result);
+			if ((result = hfa384x_drvr_start(hw))) {
+				printk(KERN_ERR
+				       "hfa384x_drvr_start() failed,"
+				       "result=%d\n", (int)result);
 				result =
-				P80211ENUM_resultcode_implementation_failure;
+				    P80211ENUM_resultcode_implementation_failure;
 				wlandev->msdstate = WLAN_MSD_HWPRESENT;
 				break;
 			}
 
-			if ((result=prism2sta_getcardinfo(wlandev))) {
-				WLAN_LOG_ERROR(
-					"prism2sta_getcardinfo() failed,"
-					"result=%d\n", (int)result);
+			if ((result = prism2sta_getcardinfo(wlandev))) {
+				printk(KERN_ERR
+				       "prism2sta_getcardinfo() failed,"
+				       "result=%d\n", (int)result);
 				result =
-				P80211ENUM_resultcode_implementation_failure;
+				    P80211ENUM_resultcode_implementation_failure;
 				hfa384x_drvr_stop(hw);
 				wlandev->msdstate = WLAN_MSD_HWPRESENT;
 				break;
 			}
-			if ((result=prism2sta_globalsetup(wlandev))) {
-				WLAN_LOG_ERROR(
-					"prism2sta_globalsetup() failed,"
-					"result=%d\n", (int)result);
+			if ((result = prism2sta_globalsetup(wlandev))) {
+				printk(KERN_ERR
+				       "prism2sta_globalsetup() failed,"
+				       "result=%d\n", (int)result);
 				result =
-				P80211ENUM_resultcode_implementation_failure;
+				    P80211ENUM_resultcode_implementation_failure;
 				hfa384x_drvr_stop(hw);
 				wlandev->msdstate = WLAN_MSD_HWPRESENT;
 				break;
@@ -584,7 +538,7 @@
 			result = P80211ENUM_resultcode_success;
 			break;
 		case WLAN_MSD_RUNNING:
-			/* Do nothing, we're already in this state.*/
+			/* Do nothing, we're already in this state. */
 			result = P80211ENUM_resultcode_success;
 			break;
 		case WLAN_MSD_HWFAIL:
@@ -599,7 +553,7 @@
 	case P80211ENUM_ifstate_disable:
 		switch (wlandev->msdstate) {
 		case WLAN_MSD_HWPRESENT:
-			/* Do nothing, we're already in this state.*/
+			/* Do nothing, we're already in this state. */
 			result = P80211ENUM_resultcode_success;
 			break;
 		case WLAN_MSD_FWLOAD:
@@ -634,11 +588,9 @@
 		break;
 	}
 
-	DBFEXIT;
 	return result;
 }
 
-
 /*----------------------------------------------------------------
 * prism2sta_getcardinfo
 *
@@ -660,269 +612,284 @@
 ----------------------------------------------------------------*/
 static int prism2sta_getcardinfo(wlandevice_t *wlandev)
 {
-	int 			result = 0;
-        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
-	u16                  temp;
-	u8			snum[HFA384x_RID_NICSERIALNUMBER_LEN];
-	char			pstr[(HFA384x_RID_NICSERIALNUMBER_LEN * 4) + 1];
-
-	DBFENTER;
+	int result = 0;
+	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+	u16 temp;
+	u8 snum[HFA384x_RID_NICSERIALNUMBER_LEN];
+	char pstr[(HFA384x_RID_NICSERIALNUMBER_LEN * 4) + 1];
 
 	/* Collect version and compatibility info */
 	/*  Some are critical, some are not */
 	/* NIC identity */
 	result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICIDENTITY,
-			&hw->ident_nic, sizeof(hfa384x_compident_t));
-	if ( result ) {
-		WLAN_LOG_ERROR("Failed to retrieve NICIDENTITY\n");
+					&hw->ident_nic,
+					sizeof(hfa384x_compident_t));
+	if (result) {
+		printk(KERN_ERR "Failed to retrieve NICIDENTITY\n");
 		goto failed;
 	}
 
 	/* get all the nic id fields in host byte order */
-	hw->ident_nic.id = hfa384x2host_16(hw->ident_nic.id);
-	hw->ident_nic.variant = hfa384x2host_16(hw->ident_nic.variant);
-	hw->ident_nic.major = hfa384x2host_16(hw->ident_nic.major);
-	hw->ident_nic.minor = hfa384x2host_16(hw->ident_nic.minor);
+	hw->ident_nic.id = le16_to_cpu(hw->ident_nic.id);
+	hw->ident_nic.variant = le16_to_cpu(hw->ident_nic.variant);
+	hw->ident_nic.major = le16_to_cpu(hw->ident_nic.major);
+	hw->ident_nic.minor = le16_to_cpu(hw->ident_nic.minor);
 
-	WLAN_LOG_INFO( "ident: nic h/w: id=0x%02x %d.%d.%d\n",
-			hw->ident_nic.id, hw->ident_nic.major,
-			hw->ident_nic.minor, hw->ident_nic.variant);
+	printk(KERN_INFO "ident: nic h/w: id=0x%02x %d.%d.%d\n",
+	       hw->ident_nic.id, hw->ident_nic.major,
+	       hw->ident_nic.minor, hw->ident_nic.variant);
 
 	/* Primary f/w identity */
 	result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRIIDENTITY,
-			&hw->ident_pri_fw, sizeof(hfa384x_compident_t));
-	if ( result ) {
-		WLAN_LOG_ERROR("Failed to retrieve PRIIDENTITY\n");
+					&hw->ident_pri_fw,
+					sizeof(hfa384x_compident_t));
+	if (result) {
+		printk(KERN_ERR "Failed to retrieve PRIIDENTITY\n");
 		goto failed;
 	}
 
 	/* get all the private fw id fields in host byte order */
-	hw->ident_pri_fw.id = hfa384x2host_16(hw->ident_pri_fw.id);
-	hw->ident_pri_fw.variant = hfa384x2host_16(hw->ident_pri_fw.variant);
-	hw->ident_pri_fw.major = hfa384x2host_16(hw->ident_pri_fw.major);
-	hw->ident_pri_fw.minor = hfa384x2host_16(hw->ident_pri_fw.minor);
+	hw->ident_pri_fw.id = le16_to_cpu(hw->ident_pri_fw.id);
+	hw->ident_pri_fw.variant = le16_to_cpu(hw->ident_pri_fw.variant);
+	hw->ident_pri_fw.major = le16_to_cpu(hw->ident_pri_fw.major);
+	hw->ident_pri_fw.minor = le16_to_cpu(hw->ident_pri_fw.minor);
 
-	WLAN_LOG_INFO( "ident: pri f/w: id=0x%02x %d.%d.%d\n",
-			hw->ident_pri_fw.id, hw->ident_pri_fw.major,
-			hw->ident_pri_fw.minor, hw->ident_pri_fw.variant);
+	printk(KERN_INFO "ident: pri f/w: id=0x%02x %d.%d.%d\n",
+	       hw->ident_pri_fw.id, hw->ident_pri_fw.major,
+	       hw->ident_pri_fw.minor, hw->ident_pri_fw.variant);
 
 	/* Station (Secondary?) f/w identity */
 	result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STAIDENTITY,
-			&hw->ident_sta_fw, sizeof(hfa384x_compident_t));
-	if ( result ) {
-		WLAN_LOG_ERROR("Failed to retrieve STAIDENTITY\n");
+					&hw->ident_sta_fw,
+					sizeof(hfa384x_compident_t));
+	if (result) {
+		printk(KERN_ERR "Failed to retrieve STAIDENTITY\n");
 		goto failed;
 	}
 
 	if (hw->ident_nic.id < 0x8000) {
-		WLAN_LOG_ERROR("FATAL: Card is not an Intersil Prism2/2.5/3\n");
+		printk(KERN_ERR
+		       "FATAL: Card is not an Intersil Prism2/2.5/3\n");
 		result = -1;
 		goto failed;
 	}
 
 	/* get all the station fw id fields in host byte order */
-	hw->ident_sta_fw.id = hfa384x2host_16(hw->ident_sta_fw.id);
-	hw->ident_sta_fw.variant = hfa384x2host_16(hw->ident_sta_fw.variant);
-	hw->ident_sta_fw.major = hfa384x2host_16(hw->ident_sta_fw.major);
-	hw->ident_sta_fw.minor = hfa384x2host_16(hw->ident_sta_fw.minor);
+	hw->ident_sta_fw.id = le16_to_cpu(hw->ident_sta_fw.id);
+	hw->ident_sta_fw.variant = le16_to_cpu(hw->ident_sta_fw.variant);
+	hw->ident_sta_fw.major = le16_to_cpu(hw->ident_sta_fw.major);
+	hw->ident_sta_fw.minor = le16_to_cpu(hw->ident_sta_fw.minor);
 
 	/* strip out the 'special' variant bits */
-	hw->mm_mods = hw->ident_sta_fw.variant & (BIT14 | BIT15);
-	hw->ident_sta_fw.variant &= ~((u16)(BIT14 | BIT15));
+	hw->mm_mods = hw->ident_sta_fw.variant & (BIT(14) | BIT(15));
+	hw->ident_sta_fw.variant &= ~((u16) (BIT(14) | BIT(15)));
 
-	if  ( hw->ident_sta_fw.id == 0x1f ) {
-		WLAN_LOG_INFO(
-			"ident: sta f/w: id=0x%02x %d.%d.%d\n",
-			hw->ident_sta_fw.id, hw->ident_sta_fw.major,
-			hw->ident_sta_fw.minor, hw->ident_sta_fw.variant);
+	if (hw->ident_sta_fw.id == 0x1f) {
+		printk(KERN_INFO
+		       "ident: sta f/w: id=0x%02x %d.%d.%d\n",
+		       hw->ident_sta_fw.id, hw->ident_sta_fw.major,
+		       hw->ident_sta_fw.minor, hw->ident_sta_fw.variant);
 	} else {
-		WLAN_LOG_INFO(
-			"ident:  ap f/w: id=0x%02x %d.%d.%d\n",
-			hw->ident_sta_fw.id, hw->ident_sta_fw.major,
-			hw->ident_sta_fw.minor, hw->ident_sta_fw.variant);
-		WLAN_LOG_ERROR("Unsupported Tertiary AP firmeare loaded!\n");
+		printk(KERN_INFO
+		       "ident:  ap f/w: id=0x%02x %d.%d.%d\n",
+		       hw->ident_sta_fw.id, hw->ident_sta_fw.major,
+		       hw->ident_sta_fw.minor, hw->ident_sta_fw.variant);
+		printk(KERN_ERR "Unsupported Tertiary AP firmeare loaded!\n");
 		goto failed;
 	}
 
 	/* Compatibility range, Modem supplier */
 	result = hfa384x_drvr_getconfig(hw, HFA384x_RID_MFISUPRANGE,
-			&hw->cap_sup_mfi, sizeof(hfa384x_caplevel_t));
-	if ( result ) {
-		WLAN_LOG_ERROR("Failed to retrieve MFISUPRANGE\n");
+					&hw->cap_sup_mfi,
+					sizeof(hfa384x_caplevel_t));
+	if (result) {
+		printk(KERN_ERR "Failed to retrieve MFISUPRANGE\n");
 		goto failed;
 	}
 
 	/* get all the Compatibility range, modem interface supplier
-	fields in byte order */
-	hw->cap_sup_mfi.role = hfa384x2host_16(hw->cap_sup_mfi.role);
-	hw->cap_sup_mfi.id = hfa384x2host_16(hw->cap_sup_mfi.id);
-	hw->cap_sup_mfi.variant = hfa384x2host_16(hw->cap_sup_mfi.variant);
-	hw->cap_sup_mfi.bottom = hfa384x2host_16(hw->cap_sup_mfi.bottom);
-	hw->cap_sup_mfi.top = hfa384x2host_16(hw->cap_sup_mfi.top);
+	   fields in byte order */
+	hw->cap_sup_mfi.role = le16_to_cpu(hw->cap_sup_mfi.role);
+	hw->cap_sup_mfi.id = le16_to_cpu(hw->cap_sup_mfi.id);
+	hw->cap_sup_mfi.variant = le16_to_cpu(hw->cap_sup_mfi.variant);
+	hw->cap_sup_mfi.bottom = le16_to_cpu(hw->cap_sup_mfi.bottom);
+	hw->cap_sup_mfi.top = le16_to_cpu(hw->cap_sup_mfi.top);
 
-	WLAN_LOG_INFO(
-		"MFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
-		hw->cap_sup_mfi.role, hw->cap_sup_mfi.id,
-		hw->cap_sup_mfi.variant, hw->cap_sup_mfi.bottom,
-		hw->cap_sup_mfi.top);
+	printk(KERN_INFO
+	       "MFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+	       hw->cap_sup_mfi.role, hw->cap_sup_mfi.id,
+	       hw->cap_sup_mfi.variant, hw->cap_sup_mfi.bottom,
+	       hw->cap_sup_mfi.top);
 
 	/* Compatibility range, Controller supplier */
 	result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CFISUPRANGE,
-			&hw->cap_sup_cfi, sizeof(hfa384x_caplevel_t));
-	if ( result ) {
-		WLAN_LOG_ERROR("Failed to retrieve CFISUPRANGE\n");
+					&hw->cap_sup_cfi,
+					sizeof(hfa384x_caplevel_t));
+	if (result) {
+		printk(KERN_ERR "Failed to retrieve CFISUPRANGE\n");
 		goto failed;
 	}
 
 	/* get all the Compatibility range, controller interface supplier
-	fields in byte order */
-	hw->cap_sup_cfi.role = hfa384x2host_16(hw->cap_sup_cfi.role);
-	hw->cap_sup_cfi.id = hfa384x2host_16(hw->cap_sup_cfi.id);
-	hw->cap_sup_cfi.variant = hfa384x2host_16(hw->cap_sup_cfi.variant);
-	hw->cap_sup_cfi.bottom = hfa384x2host_16(hw->cap_sup_cfi.bottom);
-	hw->cap_sup_cfi.top = hfa384x2host_16(hw->cap_sup_cfi.top);
+	   fields in byte order */
+	hw->cap_sup_cfi.role = le16_to_cpu(hw->cap_sup_cfi.role);
+	hw->cap_sup_cfi.id = le16_to_cpu(hw->cap_sup_cfi.id);
+	hw->cap_sup_cfi.variant = le16_to_cpu(hw->cap_sup_cfi.variant);
+	hw->cap_sup_cfi.bottom = le16_to_cpu(hw->cap_sup_cfi.bottom);
+	hw->cap_sup_cfi.top = le16_to_cpu(hw->cap_sup_cfi.top);
 
-	WLAN_LOG_INFO(
-		"CFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
-		hw->cap_sup_cfi.role, hw->cap_sup_cfi.id,
-		hw->cap_sup_cfi.variant, hw->cap_sup_cfi.bottom,
-		hw->cap_sup_cfi.top);
+	printk(KERN_INFO
+	       "CFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+	       hw->cap_sup_cfi.role, hw->cap_sup_cfi.id,
+	       hw->cap_sup_cfi.variant, hw->cap_sup_cfi.bottom,
+	       hw->cap_sup_cfi.top);
 
 	/* Compatibility range, Primary f/w supplier */
 	result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRISUPRANGE,
-			&hw->cap_sup_pri, sizeof(hfa384x_caplevel_t));
-	if ( result ) {
-		WLAN_LOG_ERROR("Failed to retrieve PRISUPRANGE\n");
+					&hw->cap_sup_pri,
+					sizeof(hfa384x_caplevel_t));
+	if (result) {
+		printk(KERN_ERR "Failed to retrieve PRISUPRANGE\n");
 		goto failed;
 	}
 
 	/* get all the Compatibility range, primary firmware supplier
-	fields in byte order */
-	hw->cap_sup_pri.role = hfa384x2host_16(hw->cap_sup_pri.role);
-	hw->cap_sup_pri.id = hfa384x2host_16(hw->cap_sup_pri.id);
-	hw->cap_sup_pri.variant = hfa384x2host_16(hw->cap_sup_pri.variant);
-	hw->cap_sup_pri.bottom = hfa384x2host_16(hw->cap_sup_pri.bottom);
-	hw->cap_sup_pri.top = hfa384x2host_16(hw->cap_sup_pri.top);
+	   fields in byte order */
+	hw->cap_sup_pri.role = le16_to_cpu(hw->cap_sup_pri.role);
+	hw->cap_sup_pri.id = le16_to_cpu(hw->cap_sup_pri.id);
+	hw->cap_sup_pri.variant = le16_to_cpu(hw->cap_sup_pri.variant);
+	hw->cap_sup_pri.bottom = le16_to_cpu(hw->cap_sup_pri.bottom);
+	hw->cap_sup_pri.top = le16_to_cpu(hw->cap_sup_pri.top);
 
-	WLAN_LOG_INFO(
-		"PRI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
-		hw->cap_sup_pri.role, hw->cap_sup_pri.id,
-		hw->cap_sup_pri.variant, hw->cap_sup_pri.bottom,
-		hw->cap_sup_pri.top);
+	printk(KERN_INFO
+	       "PRI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+	       hw->cap_sup_pri.role, hw->cap_sup_pri.id,
+	       hw->cap_sup_pri.variant, hw->cap_sup_pri.bottom,
+	       hw->cap_sup_pri.top);
 
 	/* Compatibility range, Station f/w supplier */
 	result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STASUPRANGE,
-			&hw->cap_sup_sta, sizeof(hfa384x_caplevel_t));
-	if ( result ) {
-		WLAN_LOG_ERROR("Failed to retrieve STASUPRANGE\n");
+					&hw->cap_sup_sta,
+					sizeof(hfa384x_caplevel_t));
+	if (result) {
+		printk(KERN_ERR "Failed to retrieve STASUPRANGE\n");
 		goto failed;
 	}
 
 	/* get all the Compatibility range, station firmware supplier
-	fields in byte order */
-	hw->cap_sup_sta.role = hfa384x2host_16(hw->cap_sup_sta.role);
-	hw->cap_sup_sta.id = hfa384x2host_16(hw->cap_sup_sta.id);
-	hw->cap_sup_sta.variant = hfa384x2host_16(hw->cap_sup_sta.variant);
-	hw->cap_sup_sta.bottom = hfa384x2host_16(hw->cap_sup_sta.bottom);
-	hw->cap_sup_sta.top = hfa384x2host_16(hw->cap_sup_sta.top);
+	   fields in byte order */
+	hw->cap_sup_sta.role = le16_to_cpu(hw->cap_sup_sta.role);
+	hw->cap_sup_sta.id = le16_to_cpu(hw->cap_sup_sta.id);
+	hw->cap_sup_sta.variant = le16_to_cpu(hw->cap_sup_sta.variant);
+	hw->cap_sup_sta.bottom = le16_to_cpu(hw->cap_sup_sta.bottom);
+	hw->cap_sup_sta.top = le16_to_cpu(hw->cap_sup_sta.top);
 
-	if ( hw->cap_sup_sta.id == 0x04 ) {
-		WLAN_LOG_INFO(
-		"STA:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
-		hw->cap_sup_sta.role, hw->cap_sup_sta.id,
-		hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom,
-		hw->cap_sup_sta.top);
+	if (hw->cap_sup_sta.id == 0x04) {
+		printk(KERN_INFO
+		       "STA:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+		       hw->cap_sup_sta.role, hw->cap_sup_sta.id,
+		       hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom,
+		       hw->cap_sup_sta.top);
 	} else {
-		WLAN_LOG_INFO(
-		"AP:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
-		hw->cap_sup_sta.role, hw->cap_sup_sta.id,
-		hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom,
-		hw->cap_sup_sta.top);
+		printk(KERN_INFO
+		       "AP:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+		       hw->cap_sup_sta.role, hw->cap_sup_sta.id,
+		       hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom,
+		       hw->cap_sup_sta.top);
 	}
 
 	/* Compatibility range, primary f/w actor, CFI supplier */
 	result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRI_CFIACTRANGES,
-			&hw->cap_act_pri_cfi, sizeof(hfa384x_caplevel_t));
-	if ( result ) {
-		WLAN_LOG_ERROR("Failed to retrieve PRI_CFIACTRANGES\n");
+					&hw->cap_act_pri_cfi,
+					sizeof(hfa384x_caplevel_t));
+	if (result) {
+		printk(KERN_ERR "Failed to retrieve PRI_CFIACTRANGES\n");
 		goto failed;
 	}
 
 	/* get all the Compatibility range, primary f/w actor, CFI supplier
-	fields in byte order */
-	hw->cap_act_pri_cfi.role = hfa384x2host_16(hw->cap_act_pri_cfi.role);
-	hw->cap_act_pri_cfi.id = hfa384x2host_16(hw->cap_act_pri_cfi.id);
-	hw->cap_act_pri_cfi.variant = hfa384x2host_16(hw->cap_act_pri_cfi.variant);
-	hw->cap_act_pri_cfi.bottom = hfa384x2host_16(hw->cap_act_pri_cfi.bottom);
-	hw->cap_act_pri_cfi.top = hfa384x2host_16(hw->cap_act_pri_cfi.top);
+	   fields in byte order */
+	hw->cap_act_pri_cfi.role = le16_to_cpu(hw->cap_act_pri_cfi.role);
+	hw->cap_act_pri_cfi.id = le16_to_cpu(hw->cap_act_pri_cfi.id);
+	hw->cap_act_pri_cfi.variant =
+	    le16_to_cpu(hw->cap_act_pri_cfi.variant);
+	hw->cap_act_pri_cfi.bottom =
+	    le16_to_cpu(hw->cap_act_pri_cfi.bottom);
+	hw->cap_act_pri_cfi.top = le16_to_cpu(hw->cap_act_pri_cfi.top);
 
-	WLAN_LOG_INFO(
-		"PRI-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
-		hw->cap_act_pri_cfi.role, hw->cap_act_pri_cfi.id,
-		hw->cap_act_pri_cfi.variant, hw->cap_act_pri_cfi.bottom,
-		hw->cap_act_pri_cfi.top);
+	printk(KERN_INFO
+	       "PRI-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+	       hw->cap_act_pri_cfi.role, hw->cap_act_pri_cfi.id,
+	       hw->cap_act_pri_cfi.variant, hw->cap_act_pri_cfi.bottom,
+	       hw->cap_act_pri_cfi.top);
 
 	/* Compatibility range, sta f/w actor, CFI supplier */
 	result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STA_CFIACTRANGES,
-			&hw->cap_act_sta_cfi, sizeof(hfa384x_caplevel_t));
-	if ( result ) {
-		WLAN_LOG_ERROR("Failed to retrieve STA_CFIACTRANGES\n");
+					&hw->cap_act_sta_cfi,
+					sizeof(hfa384x_caplevel_t));
+	if (result) {
+		printk(KERN_ERR "Failed to retrieve STA_CFIACTRANGES\n");
 		goto failed;
 	}
 
 	/* get all the Compatibility range, station f/w actor, CFI supplier
-	fields in byte order */
-	hw->cap_act_sta_cfi.role = hfa384x2host_16(hw->cap_act_sta_cfi.role);
-	hw->cap_act_sta_cfi.id = hfa384x2host_16(hw->cap_act_sta_cfi.id);
-	hw->cap_act_sta_cfi.variant = hfa384x2host_16(hw->cap_act_sta_cfi.variant);
-	hw->cap_act_sta_cfi.bottom = hfa384x2host_16(hw->cap_act_sta_cfi.bottom);
-	hw->cap_act_sta_cfi.top = hfa384x2host_16(hw->cap_act_sta_cfi.top);
+	   fields in byte order */
+	hw->cap_act_sta_cfi.role = le16_to_cpu(hw->cap_act_sta_cfi.role);
+	hw->cap_act_sta_cfi.id = le16_to_cpu(hw->cap_act_sta_cfi.id);
+	hw->cap_act_sta_cfi.variant =
+	    le16_to_cpu(hw->cap_act_sta_cfi.variant);
+	hw->cap_act_sta_cfi.bottom =
+	    le16_to_cpu(hw->cap_act_sta_cfi.bottom);
+	hw->cap_act_sta_cfi.top = le16_to_cpu(hw->cap_act_sta_cfi.top);
 
-	WLAN_LOG_INFO(
-		"STA-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
-		hw->cap_act_sta_cfi.role, hw->cap_act_sta_cfi.id,
-		hw->cap_act_sta_cfi.variant, hw->cap_act_sta_cfi.bottom,
-		hw->cap_act_sta_cfi.top);
+	printk(KERN_INFO
+	       "STA-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+	       hw->cap_act_sta_cfi.role, hw->cap_act_sta_cfi.id,
+	       hw->cap_act_sta_cfi.variant, hw->cap_act_sta_cfi.bottom,
+	       hw->cap_act_sta_cfi.top);
 
 	/* Compatibility range, sta f/w actor, MFI supplier */
 	result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STA_MFIACTRANGES,
-			&hw->cap_act_sta_mfi, sizeof(hfa384x_caplevel_t));
-	if ( result ) {
-		WLAN_LOG_ERROR("Failed to retrieve STA_MFIACTRANGES\n");
+					&hw->cap_act_sta_mfi,
+					sizeof(hfa384x_caplevel_t));
+	if (result) {
+		printk(KERN_ERR "Failed to retrieve STA_MFIACTRANGES\n");
 		goto failed;
 	}
 
 	/* get all the Compatibility range, station f/w actor, MFI supplier
-	fields in byte order */
-	hw->cap_act_sta_mfi.role = hfa384x2host_16(hw->cap_act_sta_mfi.role);
-	hw->cap_act_sta_mfi.id = hfa384x2host_16(hw->cap_act_sta_mfi.id);
-	hw->cap_act_sta_mfi.variant = hfa384x2host_16(hw->cap_act_sta_mfi.variant);
-	hw->cap_act_sta_mfi.bottom = hfa384x2host_16(hw->cap_act_sta_mfi.bottom);
-	hw->cap_act_sta_mfi.top = hfa384x2host_16(hw->cap_act_sta_mfi.top);
+	   fields in byte order */
+	hw->cap_act_sta_mfi.role = le16_to_cpu(hw->cap_act_sta_mfi.role);
+	hw->cap_act_sta_mfi.id = le16_to_cpu(hw->cap_act_sta_mfi.id);
+	hw->cap_act_sta_mfi.variant =
+	    le16_to_cpu(hw->cap_act_sta_mfi.variant);
+	hw->cap_act_sta_mfi.bottom =
+	    le16_to_cpu(hw->cap_act_sta_mfi.bottom);
+	hw->cap_act_sta_mfi.top = le16_to_cpu(hw->cap_act_sta_mfi.top);
 
-	WLAN_LOG_INFO(
-		"STA-MFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
-		hw->cap_act_sta_mfi.role, hw->cap_act_sta_mfi.id,
-		hw->cap_act_sta_mfi.variant, hw->cap_act_sta_mfi.bottom,
-		hw->cap_act_sta_mfi.top);
+	printk(KERN_INFO
+	       "STA-MFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+	       hw->cap_act_sta_mfi.role, hw->cap_act_sta_mfi.id,
+	       hw->cap_act_sta_mfi.variant, hw->cap_act_sta_mfi.bottom,
+	       hw->cap_act_sta_mfi.top);
 
 	/* Serial Number */
 	result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICSERIALNUMBER,
-			snum, HFA384x_RID_NICSERIALNUMBER_LEN);
-	if ( !result ) {
+					snum, HFA384x_RID_NICSERIALNUMBER_LEN);
+	if (!result) {
 		wlan_mkprintstr(snum, HFA384x_RID_NICSERIALNUMBER_LEN,
 				pstr, sizeof(pstr));
-		WLAN_LOG_INFO("Prism2 card SN: %s\n", pstr);
+		printk(KERN_INFO "Prism2 card SN: %s\n", pstr);
 	} else {
-		WLAN_LOG_ERROR("Failed to retrieve Prism2 Card SN\n");
+		printk(KERN_ERR "Failed to retrieve Prism2 Card SN\n");
 		goto failed;
 	}
 
 	/* Collect the MAC address */
 	result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CNFOWNMACADDR,
-		wlandev->netdev->dev_addr, WLAN_ADDR_LEN);
-	if ( result != 0 ) {
-		WLAN_LOG_ERROR("Failed to retrieve mac address\n");
+					wlandev->netdev->dev_addr, ETH_ALEN);
+	if (result != 0) {
+		printk(KERN_ERR "Failed to retrieve mac address\n");
 		goto failed;
 	}
 
@@ -939,10 +906,10 @@
 	hw->dbmadjust = temp;
 
 	/* Only enable scan by default on newer firmware */
-        if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
-                                     hw->ident_sta_fw.minor,
-                                     hw->ident_sta_fw.variant) <
-	    HFA384x_FIRMWARE_VERSION(1,5,5)) {
+	if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
+				     hw->ident_sta_fw.minor,
+				     hw->ident_sta_fw.variant) <
+	    HFA384x_FIRMWARE_VERSION(1, 5, 5)) {
 		wlandev->nsdcaps |= P80211_NSDCAP_NOSCAN;
 	}
 
@@ -950,13 +917,11 @@
 
 	goto done;
 failed:
-	WLAN_LOG_ERROR("Failed, result=%d\n", result);
+	printk(KERN_ERR "Failed, result=%d\n", result);
 done:
-	DBFEXIT;
 	return result;
 }
 
-
 /*----------------------------------------------------------------
 * prism2sta_globalsetup
 *
@@ -977,43 +942,33 @@
 ----------------------------------------------------------------*/
 static int prism2sta_globalsetup(wlandevice_t *wlandev)
 {
-	hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
+	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
 
 	/* Set the maximum frame size */
 	return hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN,
-	                                    WLAN_DATA_MAXLEN);
+					WLAN_DATA_MAXLEN);
 }
 
 static int prism2sta_setmulticast(wlandevice_t *wlandev, netdevice_t *dev)
 {
 	int result = 0;
-	hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
+	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
 
-	u16  promisc;
-
-	DBFENTER;
+	u16 promisc;
 
 	/* If we're not ready, what's the point? */
-	if ( hw->state != HFA384x_STATE_RUNNING )
+	if (hw->state != HFA384x_STATE_RUNNING)
 		goto exit;
 
-	if ( (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0 )
+	if ((dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0)
 		promisc = P80211ENUM_truth_true;
 	else
 		promisc = P80211ENUM_truth_false;
 
-	result = hfa384x_drvr_setconfig16_async(hw, HFA384x_RID_PROMISCMODE, promisc);
-
-	/* XXX TODO: configure the multicast list */
-	// CLEAR_HW_MULTICAST_LIST
-	// struct dev_mc_list element = dev->mc_list;
-	// while (element != null) {
-	//  HW_ADD_MULTICAST_ADDR(element->dmi_addr, dmi_addrlen)
-	//  element = element->next;
-	// }
-
- exit:
-	DBFEXIT;
+	result =
+	    hfa384x_drvr_setconfig16_async(hw, HFA384x_RID_PROMISCMODE,
+					   promisc);
+exit:
 	return result;
 }
 
@@ -1035,15 +990,13 @@
 * Call context:
 *	interrupt
 ----------------------------------------------------------------*/
-static void prism2sta_inf_handover(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf)
+static void prism2sta_inf_handover(wlandevice_t *wlandev,
+				   hfa384x_InfFrame_t *inf)
 {
-	DBFENTER;
-	WLAN_LOG_DEBUG(2,"received infoframe:HANDOVER (unhandled)\n");
-	DBFEXIT;
+	pr_debug("received infoframe:HANDOVER (unhandled)\n");
 	return;
 }
 
-
 /*----------------------------------------------------------------
 * prism2sta_inf_tallies
 *
@@ -1061,37 +1014,34 @@
 * Call context:
 *	interrupt
 ----------------------------------------------------------------*/
-static void prism2sta_inf_tallies(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf)
+static void prism2sta_inf_tallies(wlandevice_t *wlandev,
+				  hfa384x_InfFrame_t *inf)
 {
-        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
-	u16			*src16;
-	u32			*dst;
-	u32			*src32;
-	int			i;
-	int			cnt;
-
-	DBFENTER;
+	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+	u16 *src16;
+	u32 *dst;
+	u32 *src32;
+	int i;
+	int cnt;
 
 	/*
-	** Determine if these are 16-bit or 32-bit tallies, based on the
-	** record length of the info record.
-	*/
+	 ** Determine if these are 16-bit or 32-bit tallies, based on the
+	 ** record length of the info record.
+	 */
 
 	cnt = sizeof(hfa384x_CommTallies32_t) / sizeof(u32);
 	if (inf->framelen > 22) {
-		dst   = (u32 *) &hw->tallies;
-		src32 = (u32 *) &inf->info.commtallies32;
+		dst = (u32 *)&hw->tallies;
+		src32 = (u32 *)&inf->info.commtallies32;
 		for (i = 0; i < cnt; i++, dst++, src32++)
-			*dst += hfa384x2host_32(*src32);
+			*dst += le32_to_cpu(*src32);
 	} else {
-		dst   = (u32 *) &hw->tallies;
-		src16 = (u16 *) &inf->info.commtallies16;
+		dst = (u32 *)&hw->tallies;
+		src16 = (u16 *)&inf->info.commtallies16;
 		for (i = 0; i < cnt; i++, dst++, src16++)
-			*dst += hfa384x2host_16(*src16);
+			*dst += le16_to_cpu(*src16);
 	}
 
-	DBFEXIT;
-
 	return;
 }
 
@@ -1116,44 +1066,40 @@
 				      hfa384x_InfFrame_t *inf)
 {
 
-        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
-	int			nbss;
-	hfa384x_ScanResult_t	*sr = &(inf->info.scanresult);
-	int			i;
-	hfa384x_JoinRequest_data_t	joinreq;
-	int			result;
-	DBFENTER;
+	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+	int nbss;
+	hfa384x_ScanResult_t *sr = &(inf->info.scanresult);
+	int i;
+	hfa384x_JoinRequest_data_t joinreq;
+	int result;
 
 	/* Get the number of results, first in bytes, then in results */
 	nbss = (inf->framelen * sizeof(u16)) -
-		sizeof(inf->infotype) -
-		sizeof(inf->info.scanresult.scanreason);
+	    sizeof(inf->infotype) - sizeof(inf->info.scanresult.scanreason);
 	nbss /= sizeof(hfa384x_ScanResultSub_t);
 
 	/* Print em */
-	WLAN_LOG_DEBUG(1,"rx scanresults, reason=%d, nbss=%d:\n",
-		inf->info.scanresult.scanreason, nbss);
-	for ( i = 0; i < nbss; i++) {
-		WLAN_LOG_DEBUG(1, "chid=%d anl=%d sl=%d bcnint=%d\n",
-			sr->result[i].chid,
-			sr->result[i].anl,
-			sr->result[i].sl,
-			sr->result[i].bcnint);
-		WLAN_LOG_DEBUG(1, "  capinfo=0x%04x proberesp_rate=%d\n",
-			sr->result[i].capinfo,
-			sr->result[i].proberesp_rate);
+	pr_debug("rx scanresults, reason=%d, nbss=%d:\n",
+	       inf->info.scanresult.scanreason, nbss);
+	for (i = 0; i < nbss; i++) {
+		pr_debug("chid=%d anl=%d sl=%d bcnint=%d\n",
+		       sr->result[i].chid,
+		       sr->result[i].anl,
+		       sr->result[i].sl, sr->result[i].bcnint);
+		pr_debug("  capinfo=0x%04x proberesp_rate=%d\n",
+		       sr->result[i].capinfo, sr->result[i].proberesp_rate);
 	}
 	/* issue a join request */
 	joinreq.channel = sr->result[0].chid;
-	memcpy( joinreq.bssid, sr->result[0].bssid, WLAN_BSSID_LEN);
-	result = hfa384x_drvr_setconfig( hw,
-			HFA384x_RID_JOINREQUEST,
-			&joinreq, HFA384x_RID_JOINREQUEST_LEN);
+	memcpy(joinreq.bssid, sr->result[0].bssid, WLAN_BSSID_LEN);
+	result = hfa384x_drvr_setconfig(hw,
+					HFA384x_RID_JOINREQUEST,
+					&joinreq, HFA384x_RID_JOINREQUEST_LEN);
 	if (result) {
-		WLAN_LOG_ERROR("setconfig(joinreq) failed, result=%d\n", result);
+		printk(KERN_ERR "setconfig(joinreq) failed, result=%d\n",
+		       result);
 	}
 
-	DBFEXIT;
 	return;
 }
 
@@ -1177,18 +1123,16 @@
 static void prism2sta_inf_hostscanresults(wlandevice_t *wlandev,
 					  hfa384x_InfFrame_t *inf)
 {
-        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
-	int			nbss;
-	DBFENTER;
+	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+	int nbss;
 
 	nbss = (inf->framelen - 3) / 32;
-	WLAN_LOG_DEBUG(1, "Received %d hostscan results\n", nbss);
+	pr_debug("Received %d hostscan results\n", nbss);
 
 	if (nbss > 32)
 		nbss = 32;
 
-	if (hw->scanresults)
-		kfree(hw->scanresults);
+	kfree(hw->scanresults);
 
 	hw->scanresults = kmalloc(sizeof(hfa384x_InfFrame_t), GFP_ATOMIC);
 	memcpy(hw->scanresults, inf, sizeof(hfa384x_InfFrame_t));
@@ -1196,11 +1140,9 @@
 	if (nbss == 0)
 		nbss = -1;
 
-        /* Notify/wake the sleeping caller. */
-        hw->scanflag = nbss;
-        wake_up_interruptible(&hw->cmdq);
-
-	DBFEXIT;
+	/* Notify/wake the sleeping caller. */
+	hw->scanflag = nbss;
+	wake_up_interruptible(&hw->cmdq);
 };
 
 /*----------------------------------------------------------------
@@ -1223,55 +1165,60 @@
 static void prism2sta_inf_chinforesults(wlandevice_t *wlandev,
 					hfa384x_InfFrame_t *inf)
 {
-        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
-	unsigned int		i, n;
+	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+	unsigned int i, n;
 
-	DBFENTER;
 	hw->channel_info.results.scanchannels =
-		hfa384x2host_16(inf->info.chinforesult.scanchannels);
-#if 0
-	memcpy(&inf->info.chinforesult, &hw->channel_info.results, sizeof(hfa384x_ChInfoResult_t));
-#endif
+	    le16_to_cpu(inf->info.chinforesult.scanchannels);
 
-	for (i=0, n=0; i<HFA384x_CHINFORESULT_MAX; i++) {
-		if (hw->channel_info.results.scanchannels & (1<<i)) {
-			int 	channel=hfa384x2host_16(inf->info.chinforesult.result[n].chid)-1;
-			hfa384x_ChInfoResultSub_t *chinforesult=&hw->channel_info.results.result[channel];
-			chinforesult->chid   = channel;
-			chinforesult->anl    = hfa384x2host_16(inf->info.chinforesult.result[n].anl);
-			chinforesult->pnl    = hfa384x2host_16(inf->info.chinforesult.result[n].pnl);
-			chinforesult->active = hfa384x2host_16(inf->info.chinforesult.result[n].active);
-			WLAN_LOG_DEBUG(2, "chinfo: channel %d, %s level (avg/peak)=%d/%d dB, pcf %d\n",
-					channel+1,
-					chinforesult->active &
-					HFA384x_CHINFORESULT_BSSACTIVE ? "signal" : "noise",
-					chinforesult->anl, chinforesult->pnl,
-					chinforesult->active & HFA384x_CHINFORESULT_PCFACTIVE ? 1 : 0
-			);
+	for (i = 0, n = 0; i < HFA384x_CHINFORESULT_MAX; i++) {
+		if (hw->channel_info.results.scanchannels & (1 << i)) {
+			int channel =
+			    le16_to_cpu(inf->info.chinforesult.result[n].
+					    chid) - 1;
+			hfa384x_ChInfoResultSub_t *chinforesult =
+			    &hw->channel_info.results.result[channel];
+			chinforesult->chid = channel;
+			chinforesult->anl =
+			    le16_to_cpu(inf->info.chinforesult.result[n].
+					    anl);
+			chinforesult->pnl =
+			    le16_to_cpu(inf->info.chinforesult.result[n].
+					    pnl);
+			chinforesult->active =
+			    le16_to_cpu(inf->info.chinforesult.result[n].
+					    active);
+			printk(KERN_DEBUG
+			       "chinfo: channel %d, %s level (avg/peak)=%d/%d dB, pcf %d\n",
+			       channel + 1,
+			       chinforesult->
+			       active & HFA384x_CHINFORESULT_BSSACTIVE ?
+			       "signal" : "noise", chinforesult->anl,
+			       chinforesult->pnl,
+			       chinforesult->
+			       active & HFA384x_CHINFORESULT_PCFACTIVE ? 1 : 0);
 			n++;
 		}
 	}
 	atomic_set(&hw->channel_info.done, 2);
 
 	hw->channel_info.count = n;
-	DBFEXIT;
 	return;
 }
 
 void prism2sta_processing_defer(struct work_struct *data)
 {
-	hfa384x_t		*hw = container_of(data, struct hfa384x, link_bh);
-	wlandevice_t            *wlandev = hw->wlandev;
+	hfa384x_t *hw = container_of(data, struct hfa384x, link_bh);
+	wlandevice_t *wlandev = hw->wlandev;
 	hfa384x_bytestr32_t ssid;
-	int			result;
+	int result;
 
-	DBFENTER;
 	/* First let's process the auth frames */
 	{
-		struct sk_buff          *skb;
+		struct sk_buff *skb;
 		hfa384x_InfFrame_t *inf;
 
-		while ( (skb = skb_dequeue(&hw->authq)) ) {
+		while ((skb = skb_dequeue(&hw->authq))) {
 			inf = (hfa384x_InfFrame_t *) skb->data;
 			prism2sta_inf_authreq_defer(wlandev, inf);
 		}
@@ -1284,7 +1231,7 @@
 
 	hw->link_status = hw->link_status_new;
 
-	switch(hw->link_status) {
+	switch (hw->link_status) {
 	case HFA384x_LINK_NOTCONNECTED:
 		/* I'm currently assuming that this is the initial link
 		 * state.  It should only be possible immediately
@@ -1294,7 +1241,7 @@
 		 */
 		netif_carrier_off(wlandev->netdev);
 
-		WLAN_LOG_INFO("linkstatus=NOTCONNECTED (unhandled)\n");
+		printk(KERN_INFO "linkstatus=NOTCONNECTED (unhandled)\n");
 		break;
 
 	case HFA384x_LINK_CONNECTED:
@@ -1311,53 +1258,56 @@
 		netif_carrier_on(wlandev->netdev);
 
 		/* If we are joining a specific AP, set our state and reset retries */
-		if(hw->join_ap == 1)
+		if (hw->join_ap == 1)
 			hw->join_ap = 2;
 		hw->join_retries = 60;
 
 		/* Don't call this in monitor mode */
-		if ( wlandev->netdev->type == ARPHRD_ETHER ) {
-			u16			portstatus;
+		if (wlandev->netdev->type == ARPHRD_ETHER) {
+			u16 portstatus;
 
-			WLAN_LOG_INFO("linkstatus=CONNECTED\n");
+			printk(KERN_INFO "linkstatus=CONNECTED\n");
 
 			/* For non-usb devices, we can use the sync versions */
 			/* Collect the BSSID, and set state to allow tx */
 
 			result = hfa384x_drvr_getconfig(hw,
 							HFA384x_RID_CURRENTBSSID,
-							wlandev->bssid, WLAN_BSSID_LEN);
-			if ( result ) {
-				WLAN_LOG_DEBUG(1,
-					       "getconfig(0x%02x) failed, result = %d\n",
-					       HFA384x_RID_CURRENTBSSID, result);
+							wlandev->bssid,
+							WLAN_BSSID_LEN);
+			if (result) {
+				printk(KERN_DEBUG
+				       "getconfig(0x%02x) failed, result = %d\n",
+				       HFA384x_RID_CURRENTBSSID, result);
 				goto failed;
 			}
 
 			result = hfa384x_drvr_getconfig(hw,
 							HFA384x_RID_CURRENTSSID,
 							&ssid, sizeof(ssid));
-			if ( result ) {
-				WLAN_LOG_DEBUG(1,
-					       "getconfig(0x%02x) failed, result = %d\n",
-					       HFA384x_RID_CURRENTSSID, result);
+			if (result) {
+				printk(KERN_DEBUG
+				       "getconfig(0x%02x) failed, result = %d\n",
+				       HFA384x_RID_CURRENTSSID, result);
 				goto failed;
 			}
 			prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *)&ssid,
-						(p80211pstrd_t *) &wlandev->ssid);
+						(p80211pstrd_t *)&wlandev->
+						ssid);
 
 			/* Collect the port status */
 			result = hfa384x_drvr_getconfig16(hw,
-							  HFA384x_RID_PORTSTATUS, &portstatus);
-			if ( result ) {
-				WLAN_LOG_DEBUG(1,
-					       "getconfig(0x%02x) failed, result = %d\n",
-					       HFA384x_RID_PORTSTATUS, result);
+							  HFA384x_RID_PORTSTATUS,
+							  &portstatus);
+			if (result) {
+				printk(KERN_DEBUG
+				       "getconfig(0x%02x) failed, result = %d\n",
+				       HFA384x_RID_PORTSTATUS, result);
 				goto failed;
 			}
 			wlandev->macmode =
-				(portstatus == HFA384x_PSTATUS_CONN_IBSS) ?
-				WLAN_MACMODE_IBSS_STA : WLAN_MACMODE_ESS_STA;
+			    (portstatus == HFA384x_PSTATUS_CONN_IBSS) ?
+			    WLAN_MACMODE_IBSS_STA : WLAN_MACMODE_ESS_STA;
 
 			/* Get the ball rolling on the comms quality stuff */
 			prism2sta_commsqual_defer(&hw->commsqual_bh);
@@ -1374,18 +1324,20 @@
 		 * Indicate Deauthentication
 		 * Block Transmits, Ignore receives of data frames
 		 */
-		if(hw->join_ap == 2)
-		{
-			hfa384x_JoinRequest_data_t      joinreq;
+		if (hw->join_ap == 2) {
+			hfa384x_JoinRequest_data_t joinreq;
 			joinreq = hw->joinreq;
 			/* Send the join request */
-			hfa384x_drvr_setconfig( hw,
-				HFA384x_RID_JOINREQUEST,
-				&joinreq, HFA384x_RID_JOINREQUEST_LEN);
-			WLAN_LOG_INFO("linkstatus=DISCONNECTED (re-submitting join)\n");
+			hfa384x_drvr_setconfig(hw,
+					       HFA384x_RID_JOINREQUEST,
+					       &joinreq,
+					       HFA384x_RID_JOINREQUEST_LEN);
+			printk(KERN_INFO
+			       "linkstatus=DISCONNECTED (re-submitting join)\n");
 		} else {
 			if (wlandev->netdev->type == ARPHRD_ETHER)
-				WLAN_LOG_INFO("linkstatus=DISCONNECTED (unhandled)\n");
+				printk(KERN_INFO
+				       "linkstatus=DISCONNECTED (unhandled)\n");
 		}
 		wlandev->macmode = WLAN_MACMODE_NONE;
 
@@ -1408,30 +1360,29 @@
 		 * Indicate Reassociation
 		 * Enable Transmits, Receives and pass up data frames
 		 */
-		WLAN_LOG_INFO("linkstatus=AP_CHANGE\n");
+		printk(KERN_INFO "linkstatus=AP_CHANGE\n");
 
 		result = hfa384x_drvr_getconfig(hw,
 						HFA384x_RID_CURRENTBSSID,
 						wlandev->bssid, WLAN_BSSID_LEN);
-		if ( result ) {
-			WLAN_LOG_DEBUG(1,
-				       "getconfig(0x%02x) failed, result = %d\n",
-				       HFA384x_RID_CURRENTBSSID, result);
+		if (result) {
+			printk(KERN_DEBUG
+			       "getconfig(0x%02x) failed, result = %d\n",
+			       HFA384x_RID_CURRENTBSSID, result);
 			goto failed;
 		}
 
 		result = hfa384x_drvr_getconfig(hw,
 						HFA384x_RID_CURRENTSSID,
 						&ssid, sizeof(ssid));
-		if ( result ) {
-			WLAN_LOG_DEBUG(1,
-				       "getconfig(0x%02x) failed, result = %d\n",
-				       HFA384x_RID_CURRENTSSID, result);
+		if (result) {
+			printk(KERN_DEBUG
+			       "getconfig(0x%02x) failed, result = %d\n",
+			       HFA384x_RID_CURRENTSSID, result);
 			goto failed;
 		}
 		prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *)&ssid,
-					(p80211pstrd_t *) &wlandev->ssid);
-
+					(p80211pstrd_t *)&wlandev->ssid);
 
 		hw->link_status = HFA384x_LINK_CONNECTED;
 		netif_carrier_on(wlandev->netdev);
@@ -1450,7 +1401,7 @@
 		 * Response:
 		 * Block Transmits, Ignore receives of data frames
 		 */
-		WLAN_LOG_INFO("linkstatus=AP_OUTOFRANGE (unhandled)\n");
+		printk(KERN_INFO "linkstatus=AP_OUTOFRANGE (unhandled)\n");
 
 		netif_carrier_off(wlandev->netdev);
 
@@ -1463,7 +1414,7 @@
 		 * Response:
 		 * Enable Transmits, Receives and pass up data frames
 		 */
-		WLAN_LOG_INFO("linkstatus=AP_INRANGE\n");
+		printk(KERN_INFO "linkstatus=AP_INRANGE\n");
 
 		hw->link_status = HFA384x_LINK_CONNECTED;
 		netif_carrier_on(wlandev->netdev);
@@ -1479,17 +1430,18 @@
 		 * Response:
 		 * Disable Transmits, Ignore receives of data frames
 		 */
-		if(hw->join_ap && --hw->join_retries > 0)
-		{
-			hfa384x_JoinRequest_data_t      joinreq;
+		if (hw->join_ap && --hw->join_retries > 0) {
+			hfa384x_JoinRequest_data_t joinreq;
 			joinreq = hw->joinreq;
 			/* Send the join request */
-			hfa384x_drvr_setconfig( hw,
-				HFA384x_RID_JOINREQUEST,
-				&joinreq, HFA384x_RID_JOINREQUEST_LEN);
-			WLAN_LOG_INFO("linkstatus=ASSOCFAIL (re-submitting join)\n");
+			hfa384x_drvr_setconfig(hw,
+					       HFA384x_RID_JOINREQUEST,
+					       &joinreq,
+					       HFA384x_RID_JOINREQUEST_LEN);
+			printk(KERN_INFO
+			       "linkstatus=ASSOCFAIL (re-submitting join)\n");
 		} else {
-			WLAN_LOG_INFO("linkstatus=ASSOCFAIL (unhandled)\n");
+			printk(KERN_INFO "linkstatus=ASSOCFAIL (unhandled)\n");
 		}
 
 		netif_carrier_off(wlandev->netdev);
@@ -1498,8 +1450,8 @@
 
 	default:
 		/* This is bad, IO port problems? */
-		WLAN_LOG_WARNING(
-			"unknown linkstatus=0x%02x\n", hw->link_status);
+		printk(KERN_WARNING
+		       "unknown linkstatus=0x%02x\n", hw->link_status);
 		goto failed;
 		break;
 	}
@@ -1509,8 +1461,8 @@
 	p80211wext_event_associated(wlandev, wlandev->linkstatus);
 #endif
 
- failed:
-	DBFEXIT;
+failed:
+	return;
 }
 
 /*----------------------------------------------------------------
@@ -1533,15 +1485,12 @@
 static void prism2sta_inf_linkstatus(wlandevice_t *wlandev,
 				     hfa384x_InfFrame_t *inf)
 {
-        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
+	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
 
-	DBFENTER;
-
-	hw->link_status_new = hfa384x2host_16(inf->info.linkstatus.linkstatus);
+	hw->link_status_new = le16_to_cpu(inf->info.linkstatus.linkstatus);
 
 	schedule_work(&hw->link_bh);
 
-	DBFEXIT;
 	return;
 }
 
@@ -1566,45 +1515,43 @@
 static void prism2sta_inf_assocstatus(wlandevice_t *wlandev,
 				      hfa384x_InfFrame_t *inf)
 {
-        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
-	hfa384x_AssocStatus_t	rec;
-	int			i;
-
-	DBFENTER;
+	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+	hfa384x_AssocStatus_t rec;
+	int i;
 
 	memcpy(&rec, &inf->info.assocstatus, sizeof(rec));
-	rec.assocstatus = hfa384x2host_16(rec.assocstatus);
-	rec.reason      = hfa384x2host_16(rec.reason);
+	rec.assocstatus = le16_to_cpu(rec.assocstatus);
+	rec.reason = le16_to_cpu(rec.reason);
 
 	/*
-	** Find the address in the list of authenticated stations.  If it wasn't
-	** found, then this address has not been previously authenticated and
-	** something weird has happened if this is anything other than an
-	** "authentication failed" message.  If the address was found, then
-	** set the "associated" flag for that station, based on whether the
-	** station is associating or losing its association.  Something weird
-	** has also happened if we find the address in the list of authenticated
-	** stations but we are getting an "authentication failed" message.
-	*/
+	 ** Find the address in the list of authenticated stations.  If it wasn't
+	 ** found, then this address has not been previously authenticated and
+	 ** something weird has happened if this is anything other than an
+	 ** "authentication failed" message.  If the address was found, then
+	 ** set the "associated" flag for that station, based on whether the
+	 ** station is associating or losing its association.  Something weird
+	 ** has also happened if we find the address in the list of authenticated
+	 ** stations but we are getting an "authentication failed" message.
+	 */
 
 	for (i = 0; i < hw->authlist.cnt; i++)
-		if (memcmp(rec.sta_addr, hw->authlist.addr[i], WLAN_ADDR_LEN) == 0)
+		if (memcmp(rec.sta_addr, hw->authlist.addr[i], ETH_ALEN) == 0)
 			break;
 
 	if (i >= hw->authlist.cnt) {
 		if (rec.assocstatus != HFA384x_ASSOCSTATUS_AUTHFAIL)
-			WLAN_LOG_WARNING("assocstatus info frame received for non-authenticated station.\n");
+			printk(KERN_WARNING
+			       "assocstatus info frame received for non-authenticated station.\n");
 	} else {
 		hw->authlist.assoc[i] =
-			(rec.assocstatus == HFA384x_ASSOCSTATUS_STAASSOC ||
-			 rec.assocstatus == HFA384x_ASSOCSTATUS_REASSOC);
+		    (rec.assocstatus == HFA384x_ASSOCSTATUS_STAASSOC ||
+		     rec.assocstatus == HFA384x_ASSOCSTATUS_REASSOC);
 
 		if (rec.assocstatus == HFA384x_ASSOCSTATUS_AUTHFAIL)
-			WLAN_LOG_WARNING("authfail assocstatus info frame received for authenticated station.\n");
+			printk(KERN_WARNING
+			       "authfail assocstatus info frame received for authenticated station.\n");
 	}
 
-	DBFEXIT;
-
 	return;
 }
 
@@ -1630,11 +1577,9 @@
 static void prism2sta_inf_authreq(wlandevice_t *wlandev,
 				  hfa384x_InfFrame_t *inf)
 {
-        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
+	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
 	struct sk_buff *skb;
 
-	DBFENTER;
-
 	skb = dev_alloc_skb(sizeof(*inf));
 	if (skb) {
 		skb_put(skb, sizeof(*inf));
@@ -1642,132 +1587,129 @@
 		skb_queue_tail(&hw->authq, skb);
 		schedule_work(&hw->link_bh);
 	}
-
-	DBFEXIT;
 }
 
 static void prism2sta_inf_authreq_defer(wlandevice_t *wlandev,
 					hfa384x_InfFrame_t *inf)
 {
-        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
-	hfa384x_authenticateStation_data_t  rec;
+	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+	hfa384x_authenticateStation_data_t rec;
 
-	int    i, added, result, cnt;
-	u8  *addr;
-
-	DBFENTER;
+	int i, added, result, cnt;
+	u8 *addr;
 
 	/*
-	** Build the AuthenticateStation record.  Initialize it for denying
-	** authentication.
-	*/
+	 ** Build the AuthenticateStation record.  Initialize it for denying
+	 ** authentication.
+	 */
 
-	memcpy(rec.address, inf->info.authreq.sta_addr, WLAN_ADDR_LEN);
+	memcpy(rec.address, inf->info.authreq.sta_addr, ETH_ALEN);
 	rec.status = P80211ENUM_status_unspec_failure;
 
 	/*
-	** Authenticate based on the access mode.
-	*/
+	 ** Authenticate based on the access mode.
+	 */
 
 	switch (hw->accessmode) {
-		case WLAN_ACCESS_NONE:
+	case WLAN_ACCESS_NONE:
 
-			/*
-			** Deny all new authentications.  However, if a station
-			** is ALREADY authenticated, then accept it.
-			*/
+		/*
+		 ** Deny all new authentications.  However, if a station
+		 ** is ALREADY authenticated, then accept it.
+		 */
 
-			for (i = 0; i < hw->authlist.cnt; i++)
-				if (memcmp(rec.address, hw->authlist.addr[i],
-						WLAN_ADDR_LEN) == 0) {
-					rec.status = P80211ENUM_status_successful;
-					break;
-				}
-
-			break;
-
-		case WLAN_ACCESS_ALL:
-
-			/*
-			** Allow all authentications.
-			*/
-
-			rec.status = P80211ENUM_status_successful;
-			break;
-
-		case WLAN_ACCESS_ALLOW:
-
-			/*
-			** Only allow the authentication if the MAC address
-			** is in the list of allowed addresses.
-			**
-			** Since this is the interrupt handler, we may be here
-			** while the access list is in the middle of being
-			** updated.  Choose the list which is currently okay.
-			** See "prism2mib_priv_accessallow()" for details.
-			*/
-
-			if (hw->allow.modify == 0) {
-				cnt  = hw->allow.cnt;
-				addr = hw->allow.addr[0];
-			} else {
-				cnt  = hw->allow.cnt1;
-				addr = hw->allow.addr1[0];
+		for (i = 0; i < hw->authlist.cnt; i++)
+			if (memcmp(rec.address, hw->authlist.addr[i],
+				   ETH_ALEN) == 0) {
+				rec.status = P80211ENUM_status_successful;
+				break;
 			}
 
-			for (i = 0; i < cnt; i++, addr += WLAN_ADDR_LEN)
-				if (memcmp(rec.address, addr, WLAN_ADDR_LEN) == 0) {
-					rec.status = P80211ENUM_status_successful;
-					break;
-				}
+		break;
 
-			break;
+	case WLAN_ACCESS_ALL:
 
-		case WLAN_ACCESS_DENY:
+		/*
+		 ** Allow all authentications.
+		 */
 
-			/*
-			** Allow the authentication UNLESS the MAC address is
-			** in the list of denied addresses.
-			**
-			** Since this is the interrupt handler, we may be here
-			** while the access list is in the middle of being
-			** updated.  Choose the list which is currently okay.
-			** See "prism2mib_priv_accessdeny()" for details.
-			*/
+		rec.status = P80211ENUM_status_successful;
+		break;
 
-			if (hw->deny.modify == 0) {
-				cnt  = hw->deny.cnt;
-				addr = hw->deny.addr[0];
-			} else {
-				cnt  = hw->deny.cnt1;
-				addr = hw->deny.addr1[0];
+	case WLAN_ACCESS_ALLOW:
+
+		/*
+		 ** Only allow the authentication if the MAC address
+		 ** is in the list of allowed addresses.
+		 **
+		 ** Since this is the interrupt handler, we may be here
+		 ** while the access list is in the middle of being
+		 ** updated.  Choose the list which is currently okay.
+		 ** See "prism2mib_priv_accessallow()" for details.
+		 */
+
+		if (hw->allow.modify == 0) {
+			cnt = hw->allow.cnt;
+			addr = hw->allow.addr[0];
+		} else {
+			cnt = hw->allow.cnt1;
+			addr = hw->allow.addr1[0];
+		}
+
+		for (i = 0; i < cnt; i++, addr += ETH_ALEN)
+			if (memcmp(rec.address, addr, ETH_ALEN) == 0) {
+				rec.status = P80211ENUM_status_successful;
+				break;
 			}
 
-			rec.status = P80211ENUM_status_successful;
+		break;
 
-			for (i = 0; i < cnt; i++, addr += WLAN_ADDR_LEN)
-				if (memcmp(rec.address, addr, WLAN_ADDR_LEN) == 0) {
-					rec.status = P80211ENUM_status_unspec_failure;
-					break;
-				}
+	case WLAN_ACCESS_DENY:
 
-			break;
+		/*
+		 ** Allow the authentication UNLESS the MAC address is
+		 ** in the list of denied addresses.
+		 **
+		 ** Since this is the interrupt handler, we may be here
+		 ** while the access list is in the middle of being
+		 ** updated.  Choose the list which is currently okay.
+		 ** See "prism2mib_priv_accessdeny()" for details.
+		 */
+
+		if (hw->deny.modify == 0) {
+			cnt = hw->deny.cnt;
+			addr = hw->deny.addr[0];
+		} else {
+			cnt = hw->deny.cnt1;
+			addr = hw->deny.addr1[0];
+		}
+
+		rec.status = P80211ENUM_status_successful;
+
+		for (i = 0; i < cnt; i++, addr += ETH_ALEN)
+			if (memcmp(rec.address, addr, ETH_ALEN) == 0) {
+				rec.status = P80211ENUM_status_unspec_failure;
+				break;
+			}
+
+		break;
 	}
 
 	/*
-	** If the authentication is okay, then add the MAC address to the list
-	** of authenticated stations.  Don't add the address if it is already in
-	** the list.  (802.11b does not seem to disallow a station from issuing
-	** an authentication request when the station is already authenticated.
-	** Does this sort of thing ever happen?  We might as well do the check
-	** just in case.)
-	*/
+	 ** If the authentication is okay, then add the MAC address to the list
+	 ** of authenticated stations.  Don't add the address if it is already in
+	 ** the list.  (802.11b does not seem to disallow a station from issuing
+	 ** an authentication request when the station is already authenticated.
+	 ** Does this sort of thing ever happen?  We might as well do the check
+	 ** just in case.)
+	 */
 
 	added = 0;
 
 	if (rec.status == P80211ENUM_status_successful) {
 		for (i = 0; i < hw->authlist.cnt; i++)
-			if (memcmp(rec.address, hw->authlist.addr[i], WLAN_ADDR_LEN) == 0)
+			if (memcmp(rec.address, hw->authlist.addr[i], ETH_ALEN)
+			    == 0)
 				break;
 
 		if (i >= hw->authlist.cnt) {
@@ -1775,7 +1717,7 @@
 				rec.status = P80211ENUM_status_ap_full;
 			} else {
 				memcpy(hw->authlist.addr[hw->authlist.cnt],
-					rec.address, WLAN_ADDR_LEN);
+				       rec.address, ETH_ALEN);
 				hw->authlist.cnt++;
 				added = 1;
 			}
@@ -1783,27 +1725,26 @@
 	}
 
 	/*
-	** Send back the results of the authentication.  If this doesn't work,
-	** then make sure to remove the address from the authenticated list if
-	** it was added.
-	*/
+	 ** Send back the results of the authentication.  If this doesn't work,
+	 ** then make sure to remove the address from the authenticated list if
+	 ** it was added.
+	 */
 
-	rec.status = host2hfa384x_16(rec.status);
+	rec.status = cpu_to_le16(rec.status);
 	rec.algorithm = inf->info.authreq.algorithm;
 
 	result = hfa384x_drvr_setconfig(hw, HFA384x_RID_AUTHENTICATESTA,
-							&rec, sizeof(rec));
+					&rec, sizeof(rec));
 	if (result) {
-		if (added) hw->authlist.cnt--;
-		WLAN_LOG_ERROR("setconfig(authenticatestation) failed, result=%d\n", result);
+		if (added)
+			hw->authlist.cnt--;
+		printk(KERN_ERR
+		       "setconfig(authenticatestation) failed, result=%d\n",
+		       result);
 	}
-
-	DBFEXIT;
-
 	return;
 }
 
-
 /*----------------------------------------------------------------
 * prism2sta_inf_psusercnt
 *
@@ -1825,74 +1766,14 @@
 static void prism2sta_inf_psusercnt(wlandevice_t *wlandev,
 				    hfa384x_InfFrame_t *inf)
 {
-        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
+	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
 
-	DBFENTER;
-
-	hw->psusercount = hfa384x2host_16(inf->info.psusercnt.usercnt);
-
-	DBFEXIT;
+	hw->psusercount = le16_to_cpu(inf->info.psusercnt.usercnt);
 
 	return;
 }
 
 /*----------------------------------------------------------------
-* prism2sta_ev_dtim
-*
-* Handles the DTIM early warning event.
-*
-* Arguments:
-*	wlandev		wlan device structure
-*
-* Returns:
-*	nothing
-*
-* Side effects:
-*
-* Call context:
-*	interrupt
-----------------------------------------------------------------*/
-void prism2sta_ev_dtim(wlandevice_t *wlandev)
-{
-#if 0
-        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
-#endif
-	DBFENTER;
-	WLAN_LOG_DEBUG(3, "DTIM event, currently unhandled.\n");
-	DBFEXIT;
-	return;
-}
-
-
-/*----------------------------------------------------------------
-* prism2sta_ev_infdrop
-*
-* Handles the InfDrop event.
-*
-* Arguments:
-*	wlandev		wlan device structure
-*
-* Returns:
-*	nothing
-*
-* Side effects:
-*
-* Call context:
-*	interrupt
-----------------------------------------------------------------*/
-void prism2sta_ev_infdrop(wlandevice_t *wlandev)
-{
-#if 0
-        hfa384x_t               *hw = (hfa384x_t *)wlandev->priv;
-#endif
-	DBFENTER;
-	WLAN_LOG_DEBUG(3, "Info frame dropped due to card mem low.\n");
-	DBFEXIT;
-	return;
-}
-
-
-/*----------------------------------------------------------------
 * prism2sta_ev_info
 *
 * Handles the Info event.
@@ -1911,56 +1792,53 @@
 ----------------------------------------------------------------*/
 void prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf)
 {
-	DBFENTER;
-	inf->infotype = hfa384x2host_16(inf->infotype);
+	inf->infotype = le16_to_cpu(inf->infotype);
 	/* Dispatch */
-	switch ( inf->infotype ) {
-		case HFA384x_IT_HANDOVERADDR:
-			prism2sta_inf_handover(wlandev, inf);
-			break;
-		case HFA384x_IT_COMMTALLIES:
-			prism2sta_inf_tallies(wlandev, inf);
-			break;
-               case HFA384x_IT_HOSTSCANRESULTS:
-                        prism2sta_inf_hostscanresults(wlandev, inf);
-                        break;
-		case HFA384x_IT_SCANRESULTS:
-			prism2sta_inf_scanresults(wlandev, inf);
-			break;
-		case HFA384x_IT_CHINFORESULTS:
-			prism2sta_inf_chinforesults(wlandev, inf);
-			break;
-		case HFA384x_IT_LINKSTATUS:
-			prism2sta_inf_linkstatus(wlandev, inf);
-			break;
-		case HFA384x_IT_ASSOCSTATUS:
-			prism2sta_inf_assocstatus(wlandev, inf);
-			break;
-		case HFA384x_IT_AUTHREQ:
-			prism2sta_inf_authreq(wlandev, inf);
-			break;
-		case HFA384x_IT_PSUSERCNT:
-			prism2sta_inf_psusercnt(wlandev, inf);
-			break;
-	        case HFA384x_IT_KEYIDCHANGED:
-			WLAN_LOG_WARNING("Unhandled IT_KEYIDCHANGED\n");
-			break;
-	        case HFA384x_IT_ASSOCREQ:
-			WLAN_LOG_WARNING("Unhandled IT_ASSOCREQ\n");
-			break;
-	        case HFA384x_IT_MICFAILURE:
-			WLAN_LOG_WARNING("Unhandled IT_MICFAILURE\n");
-			break;
-		default:
-			WLAN_LOG_WARNING(
-				"Unknown info type=0x%02x\n", inf->infotype);
-			break;
+	switch (inf->infotype) {
+	case HFA384x_IT_HANDOVERADDR:
+		prism2sta_inf_handover(wlandev, inf);
+		break;
+	case HFA384x_IT_COMMTALLIES:
+		prism2sta_inf_tallies(wlandev, inf);
+		break;
+	case HFA384x_IT_HOSTSCANRESULTS:
+		prism2sta_inf_hostscanresults(wlandev, inf);
+		break;
+	case HFA384x_IT_SCANRESULTS:
+		prism2sta_inf_scanresults(wlandev, inf);
+		break;
+	case HFA384x_IT_CHINFORESULTS:
+		prism2sta_inf_chinforesults(wlandev, inf);
+		break;
+	case HFA384x_IT_LINKSTATUS:
+		prism2sta_inf_linkstatus(wlandev, inf);
+		break;
+	case HFA384x_IT_ASSOCSTATUS:
+		prism2sta_inf_assocstatus(wlandev, inf);
+		break;
+	case HFA384x_IT_AUTHREQ:
+		prism2sta_inf_authreq(wlandev, inf);
+		break;
+	case HFA384x_IT_PSUSERCNT:
+		prism2sta_inf_psusercnt(wlandev, inf);
+		break;
+	case HFA384x_IT_KEYIDCHANGED:
+		printk(KERN_WARNING "Unhandled IT_KEYIDCHANGED\n");
+		break;
+	case HFA384x_IT_ASSOCREQ:
+		printk(KERN_WARNING "Unhandled IT_ASSOCREQ\n");
+		break;
+	case HFA384x_IT_MICFAILURE:
+		printk(KERN_WARNING "Unhandled IT_MICFAILURE\n");
+		break;
+	default:
+		printk(KERN_WARNING
+		       "Unknown info type=0x%02x\n", inf->infotype);
+		break;
 	}
-	DBFEXIT;
 	return;
 }
 
-
 /*----------------------------------------------------------------
 * prism2sta_ev_txexc
 *
@@ -1982,15 +1860,11 @@
 ----------------------------------------------------------------*/
 void prism2sta_ev_txexc(wlandevice_t *wlandev, u16 status)
 {
-	DBFENTER;
+	pr_debug("TxExc status=0x%x.\n", status);
 
-	WLAN_LOG_DEBUG(3, "TxExc status=0x%x.\n", status);
-
-	DBFEXIT;
 	return;
 }
 
-
 /*----------------------------------------------------------------
 * prism2sta_ev_tx
 *
@@ -2009,15 +1883,12 @@
 ----------------------------------------------------------------*/
 void prism2sta_ev_tx(wlandevice_t *wlandev, u16 status)
 {
-	DBFENTER;
-	WLAN_LOG_DEBUG(4, "Tx Complete, status=0x%04x\n", status);
+	pr_debug("Tx Complete, status=0x%04x\n", status);
 	/* update linux network stats */
 	wlandev->linux_stats.tx_packets++;
-	DBFEXIT;
 	return;
 }
 
-
 /*----------------------------------------------------------------
 * prism2sta_ev_rx
 *
@@ -2036,11 +1907,7 @@
 ----------------------------------------------------------------*/
 void prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb)
 {
-	DBFENTER;
-
 	p80211netdev_rx(wlandev, skb);
-
-	DBFEXIT;
 	return;
 }
 
@@ -2062,11 +1929,7 @@
 ----------------------------------------------------------------*/
 void prism2sta_ev_alloc(wlandevice_t *wlandev)
 {
-	DBFENTER;
-
 	netif_wake_queue(wlandev->netdev);
-
-	DBFEXIT;
 	return;
 }
 
@@ -2091,17 +1954,17 @@
 ----------------------------------------------------------------*/
 static wlandevice_t *create_wlan(void)
 {
-        wlandevice_t    *wlandev = NULL;
-	hfa384x_t	*hw = NULL;
+	wlandevice_t *wlandev = NULL;
+	hfa384x_t *hw = NULL;
 
-      	/* Alloc our structures */
-	wlandev =	kmalloc(sizeof(wlandevice_t), GFP_KERNEL);
-	hw =		kmalloc(sizeof(hfa384x_t), GFP_KERNEL);
+	/* Alloc our structures */
+	wlandev = kmalloc(sizeof(wlandevice_t), GFP_KERNEL);
+	hw = kmalloc(sizeof(hfa384x_t), GFP_KERNEL);
 
 	if (!wlandev || !hw) {
-		WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info);
-		if (wlandev)	kfree(wlandev);
-		if (hw)		kfree(hw);
+		printk(KERN_ERR "%s: Memory allocation failure.\n", dev_info);
+		kfree(wlandev);
+		kfree(hw);
 		return NULL;
 	}
 
@@ -2121,24 +1984,21 @@
 	wlandev->set_multicast_list = prism2sta_setmulticast;
 	wlandev->tx_timeout = hfa384x_tx_timeout;
 
-	wlandev->nsdcaps = P80211_NSDCAP_HWFRAGMENT |
-	                   P80211_NSDCAP_AUTOJOIN;
+	wlandev->nsdcaps = P80211_NSDCAP_HWFRAGMENT | P80211_NSDCAP_AUTOJOIN;
 
 	/* Initialize the device private data stucture. */
-        hw->dot11_desired_bss_type = 1;
+	hw->dot11_desired_bss_type = 1;
 
 	return wlandev;
 }
 
 void prism2sta_commsqual_defer(struct work_struct *data)
 {
-	hfa384x_t		*hw = container_of(data, struct hfa384x, commsqual_bh);
-        wlandevice_t            *wlandev = hw->wlandev;
+	hfa384x_t *hw = container_of(data, struct hfa384x, commsqual_bh);
+	wlandevice_t *wlandev = hw->wlandev;
 	hfa384x_bytestr32_t ssid;
 	int result = 0;
 
-	DBFENTER;
-
 	if (hw->wlandev->hwremoved)
 		goto done;
 
@@ -2155,58 +2015,49 @@
 						HFA384x_RID_DBMCOMMSQUALITY_LEN);
 
 		if (result) {
-			WLAN_LOG_ERROR("error fetching commsqual\n");
+			printk(KERN_ERR "error fetching commsqual\n");
 			goto done;
 		}
 
-		// qual.CQ_currBSS; // link
-		// ASL_currBSS;  // level
-		// qual.ANL_currFC; // noise
-
-		WLAN_LOG_DEBUG(3, "commsqual %d %d %d\n",
-			       hfa384x2host_16(hw->qual.CQ_currBSS),
-			       hfa384x2host_16(hw->qual.ASL_currBSS),
-			       hfa384x2host_16(hw->qual.ANL_currFC));
+		pr_debug("commsqual %d %d %d\n",
+		       le16_to_cpu(hw->qual.CQ_currBSS),
+		       le16_to_cpu(hw->qual.ASL_currBSS),
+		       le16_to_cpu(hw->qual.ANL_currFC));
 	}
 
 	/* Lastly, we need to make sure the BSSID didn't change on us */
 	result = hfa384x_drvr_getconfig(hw,
 					HFA384x_RID_CURRENTBSSID,
 					wlandev->bssid, WLAN_BSSID_LEN);
-	if ( result ) {
-		WLAN_LOG_DEBUG(1,
-			       "getconfig(0x%02x) failed, result = %d\n",
-			       HFA384x_RID_CURRENTBSSID, result);
+	if (result) {
+		printk(KERN_DEBUG
+		       "getconfig(0x%02x) failed, result = %d\n",
+		       HFA384x_RID_CURRENTBSSID, result);
 		goto done;
 	}
 
 	result = hfa384x_drvr_getconfig(hw,
 					HFA384x_RID_CURRENTSSID,
 					&ssid, sizeof(ssid));
-	if ( result ) {
-		WLAN_LOG_DEBUG(1,
-			       "getconfig(0x%02x) failed, result = %d\n",
-			       HFA384x_RID_CURRENTSSID, result);
+	if (result) {
+		printk(KERN_DEBUG
+		       "getconfig(0x%02x) failed, result = %d\n",
+		       HFA384x_RID_CURRENTSSID, result);
 		goto done;
 	}
 	prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *)&ssid,
-				(p80211pstrd_t *) &wlandev->ssid);
-
+				(p80211pstrd_t *)&wlandev->ssid);
 
 	/* Reschedule timer */
 	mod_timer(&hw->commsqual_timer, jiffies + HZ);
 
- done:
-	DBFEXIT;
+done:
+	;
 }
 
 void prism2sta_commsqual_timer(unsigned long data)
 {
-        hfa384x_t               *hw = (hfa384x_t *) data;
-
-	DBFENTER;
+	hfa384x_t *hw = (hfa384x_t *) data;
 
 	schedule_work(&hw->commsqual_bh);
-
-	DBFEXIT;
 }
diff --git a/drivers/staging/wlan-ng/prism2usb.c b/drivers/staging/wlan-ng/prism2usb.c
index 8f7b1f2..d8a1298 100644
--- a/drivers/staging/wlan-ng/prism2usb.c
+++ b/drivers/staging/wlan-ng/prism2usb.c
@@ -11,44 +11,70 @@
 	{PRISM_USB_DEVICE(0x04bb, 0x0922, "IOData AirPort WN-B11/USBS")},
 	{PRISM_USB_DEVICE(0x07aa, 0x0012, "Corega Wireless LAN USB Stick-11")},
 	{PRISM_USB_DEVICE(0x09aa, 0x3642, "Prism2.x 11Mbps WLAN USB Adapter")},
-	{PRISM_USB_DEVICE(0x1668, 0x0408, "Actiontec Prism2.5 11Mbps WLAN USB Adapter")},
-	{PRISM_USB_DEVICE(0x1668, 0x0421, "Actiontec Prism2.5 11Mbps WLAN USB Adapter")},
-	{PRISM_USB_DEVICE(0x1915, 0x2236, "Linksys WUSB11v3.0 11Mbps WLAN USB Adapter")},
-	{PRISM_USB_DEVICE(0x066b, 0x2212, "Linksys WUSB11v2.5 11Mbps WLAN USB Adapter")},
-	{PRISM_USB_DEVICE(0x066b, 0x2213, "Linksys WUSB12v1.1 11Mbps WLAN USB Adapter")},
-	{PRISM_USB_DEVICE(0x067c, 0x1022, "Siemens SpeedStream 1022 11Mbps WLAN USB Adapter")},
-	{PRISM_USB_DEVICE(0x049f, 0x0033, "Compaq/Intel W100 PRO/Wireless 11Mbps multiport WLAN Adapter")},
-	{PRISM_USB_DEVICE(0x0411, 0x0016, "Melco WLI-USB-S11 11Mbps WLAN Adapter")},
-	{PRISM_USB_DEVICE(0x08de, 0x7a01, "PRISM25 IEEE 802.11 Mini USB Adapter")},
-	{PRISM_USB_DEVICE(0x8086, 0x1111, "Intel PRO/Wireless 2011B LAN USB Adapter")},
-	{PRISM_USB_DEVICE(0x0d8e, 0x7a01, "PRISM25 IEEE 802.11 Mini USB Adapter")},
-	{PRISM_USB_DEVICE(0x045e, 0x006e, "Microsoft MN510 Wireless USB Adapter")},
+	{PRISM_USB_DEVICE
+	 (0x1668, 0x0408, "Actiontec Prism2.5 11Mbps WLAN USB Adapter")},
+	{PRISM_USB_DEVICE
+	 (0x1668, 0x0421, "Actiontec Prism2.5 11Mbps WLAN USB Adapter")},
+	{PRISM_USB_DEVICE
+	 (0x1915, 0x2236, "Linksys WUSB11v3.0 11Mbps WLAN USB Adapter")},
+	{PRISM_USB_DEVICE
+	 (0x066b, 0x2212, "Linksys WUSB11v2.5 11Mbps WLAN USB Adapter")},
+	{PRISM_USB_DEVICE
+	 (0x066b, 0x2213, "Linksys WUSB12v1.1 11Mbps WLAN USB Adapter")},
+	{PRISM_USB_DEVICE
+	 (0x067c, 0x1022, "Siemens SpeedStream 1022 11Mbps WLAN USB Adapter")},
+	{PRISM_USB_DEVICE
+	 (0x049f, 0x0033,
+	  "Compaq/Intel W100 PRO/Wireless 11Mbps multiport WLAN Adapter")},
+	{PRISM_USB_DEVICE
+	 (0x0411, 0x0016, "Melco WLI-USB-S11 11Mbps WLAN Adapter")},
+	{PRISM_USB_DEVICE
+	 (0x08de, 0x7a01, "PRISM25 IEEE 802.11 Mini USB Adapter")},
+	{PRISM_USB_DEVICE
+	 (0x8086, 0x1111, "Intel PRO/Wireless 2011B LAN USB Adapter")},
+	{PRISM_USB_DEVICE
+	 (0x0d8e, 0x7a01, "PRISM25 IEEE 802.11 Mini USB Adapter")},
+	{PRISM_USB_DEVICE
+	 (0x045e, 0x006e, "Microsoft MN510 Wireless USB Adapter")},
 	{PRISM_USB_DEVICE(0x0967, 0x0204, "Acer Warplink USB Adapter")},
-	{PRISM_USB_DEVICE(0x0cde, 0x0002, "Z-Com 725/726 Prism2.5 USB/USB Integrated")},
-	{PRISM_USB_DEVICE(0x0cde, 0x0005, "Z-Com Xl735 Wireless 802.11b USB Adapter")},
-	{PRISM_USB_DEVICE(0x413c, 0x8100, "Dell TrueMobile 1180 Wireless USB Adapter")},
-	{PRISM_USB_DEVICE(0x0b3b, 0x1601, "ALLNET 0193 11Mbps WLAN USB Adapter")},
-	{PRISM_USB_DEVICE(0x0b3b, 0x1602, "ZyXEL ZyAIR B200 Wireless USB Adapter")},
-	{PRISM_USB_DEVICE(0x0baf, 0x00eb, "USRobotics USR1120 Wireless USB Adapter")},
-	{PRISM_USB_DEVICE(0x0411, 0x0027, "Melco WLI-USB-KS11G 11Mbps WLAN Adapter")},
-        {PRISM_USB_DEVICE(0x04f1, 0x3009, "JVC MP-XP7250 Builtin USB WLAN Adapter")},
+	{PRISM_USB_DEVICE
+	 (0x0cde, 0x0002, "Z-Com 725/726 Prism2.5 USB/USB Integrated")},
+	{PRISM_USB_DEVICE
+	 (0x0cde, 0x0005, "Z-Com Xl735 Wireless 802.11b USB Adapter")},
+	{PRISM_USB_DEVICE
+	 (0x413c, 0x8100, "Dell TrueMobile 1180 Wireless USB Adapter")},
+	{PRISM_USB_DEVICE
+	 (0x0b3b, 0x1601, "ALLNET 0193 11Mbps WLAN USB Adapter")},
+	{PRISM_USB_DEVICE
+	 (0x0b3b, 0x1602, "ZyXEL ZyAIR B200 Wireless USB Adapter")},
+	{PRISM_USB_DEVICE
+	 (0x0baf, 0x00eb, "USRobotics USR1120 Wireless USB Adapter")},
+	{PRISM_USB_DEVICE
+	 (0x0411, 0x0027, "Melco WLI-USB-KS11G 11Mbps WLAN Adapter")},
+	{PRISM_USB_DEVICE
+	 (0x04f1, 0x3009, "JVC MP-XP7250 Builtin USB WLAN Adapter")},
 	{PRISM_USB_DEVICE(0x0846, 0x4110, "NetGear MA111")},
-        {PRISM_USB_DEVICE(0x03f3, 0x0020, "Adaptec AWN-8020 USB WLAN Adapter")},
-//	{PRISM_USB_DEVICE(0x0ace, 0x1201, "ZyDAS ZD1201 Wireless USB Adapter")},
+	{PRISM_USB_DEVICE(0x03f3, 0x0020, "Adaptec AWN-8020 USB WLAN Adapter")},
+/*      {PRISM_USB_DEVICE(0x0ace, 0x1201, "ZyDAS ZD1201 Wireless USB Adapter")}, */
 	{PRISM_USB_DEVICE(0x2821, 0x3300, "ASUS-WL140 Wireless USB Adapter")},
 	{PRISM_USB_DEVICE(0x2001, 0x3700, "DWL-122 Wireless USB Adapter")},
-	{PRISM_USB_DEVICE(0x2001, 0x3702, "DWL-120 Rev F Wireless USB Adapter")},
+	{PRISM_USB_DEVICE
+	 (0x2001, 0x3702, "DWL-120 Rev F Wireless USB Adapter")},
 	{PRISM_USB_DEVICE(0x50c2, 0x4013, "Averatec USB WLAN Adapter")},
 	{PRISM_USB_DEVICE(0x2c02, 0x14ea, "Planex GW-US11H WLAN USB Adapter")},
 	{PRISM_USB_DEVICE(0x124a, 0x168b, "Airvast PRISM3 WLAN USB Adapter")},
 	{PRISM_USB_DEVICE(0x083a, 0x3503, "T-Sinus 111 USB WLAN Adapter")},
 	{PRISM_USB_DEVICE(0x2821, 0x3300, "Hawking HighDB USB Adapter")},
-	{PRISM_USB_DEVICE(0x0411, 0x0044, "Melco WLI-USB-KB11 11Mbps WLAN Adapter")},
+	{PRISM_USB_DEVICE
+	 (0x0411, 0x0044, "Melco WLI-USB-KB11 11Mbps WLAN Adapter")},
 	{PRISM_USB_DEVICE(0x1668, 0x6106, "ROPEX FreeLan 802.11b USB Adapter")},
-	{PRISM_USB_DEVICE(0x124a, 0x4017, "Pheenet WL-503IA 802.11b USB Adapter")},
+	{PRISM_USB_DEVICE
+	 (0x124a, 0x4017, "Pheenet WL-503IA 802.11b USB Adapter")},
 	{PRISM_USB_DEVICE(0x0bb2, 0x0302, "Ambit Microsystems Corp.")},
-	{PRISM_USB_DEVICE(0x9016, 0x182d, "Sitecom WL-022 802.11b USB Adapter")},
-	{PRISM_USB_DEVICE(0x0543, 0x0f01, "ViewSonic Airsync USB Adapter 11Mbps (Prism2.5)")},
+	{PRISM_USB_DEVICE
+	 (0x9016, 0x182d, "Sitecom WL-022 802.11b USB Adapter")},
+	{PRISM_USB_DEVICE
+	 (0x0543, 0x0f01, "ViewSonic Airsync USB Adapter 11Mbps (Prism2.5)")},
 	{ /* terminator */ }
 };
 
@@ -75,29 +101,26 @@
 *	I'm not sure, assume it's interrupt.
 *
 ----------------------------------------------------------------*/
-static int prism2sta_probe_usb(
-	struct usb_interface *interface,
-	const struct usb_device_id *id)
+static int prism2sta_probe_usb(struct usb_interface *interface,
+			       const struct usb_device_id *id)
 {
 	struct usb_device *dev;
 
-	wlandevice_t	*wlandev = NULL;
-	hfa384x_t	*hw = NULL;
-	int              result = 0;
-
-	DBFENTER;
+	wlandevice_t *wlandev = NULL;
+	hfa384x_t *hw = NULL;
+	int result = 0;
 
 	dev = interface_to_usbdev(interface);
 
 	if ((wlandev = create_wlan()) == NULL) {
-		WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info);
+		printk(KERN_ERR "%s: Memory allocation failure.\n", dev_info);
 		result = -EIO;
 		goto failed;
 	}
 	hw = wlandev->priv;
 
-	if ( wlan_setup(wlandev) != 0 ) {
-		WLAN_LOG_ERROR("%s: wlan_setup() failed.\n", dev_info);
+	if (wlan_setup(wlandev) != 0) {
+		printk(KERN_ERR "%s: wlan_setup() failed.\n", dev_info);
 		result = -EIO;
 		goto failed;
 	}
@@ -114,15 +137,14 @@
 	/* Do a chip-level reset on the MAC */
 	if (prism2_doreset) {
 		result = hfa384x_corereset(hw,
-				prism2_reset_holdtime,
-				prism2_reset_settletime, 0);
+					   prism2_reset_holdtime,
+					   prism2_reset_settletime, 0);
 		if (result != 0) {
 			unregister_wlandev(wlandev);
 			hfa384x_destroy(hw);
 			result = -EIO;
-			WLAN_LOG_ERROR(
-				"%s: hfa384x_corereset() failed.\n",
-				dev_info);
+			printk(KERN_ERR
+			       "%s: hfa384x_corereset() failed.\n", dev_info);
 			goto failed;
 		}
 	}
@@ -131,30 +153,28 @@
 
 	wlandev->msdstate = WLAN_MSD_HWPRESENT;
 
-        if ( register_wlandev(wlandev) != 0 ) {
-		WLAN_LOG_ERROR("%s: register_wlandev() failed.\n", dev_info);
+	if (register_wlandev(wlandev) != 0) {
+		printk(KERN_ERR "%s: register_wlandev() failed.\n", dev_info);
 		result = -EIO;
 		goto failed;
-        }
+	}
 
 /* enable the card */
 	prism2sta_ifstate(wlandev, P80211ENUM_ifstate_enable);
 
 	goto done;
 
- failed:
-	if (wlandev)	kfree(wlandev);
-	if (hw)		kfree(hw);
+failed:
+	kfree(wlandev);
+	kfree(hw);
 	wlandev = NULL;
 
- done:
-	DBFEXIT;
-
+done:
+	p80211_allow_ioctls(wlandev);
 	usb_set_intfdata(interface, wlandev);
 	return result;
 }
 
-
 /*----------------------------------------------------------------
 * prism2sta_disconnect_usb
 *
@@ -174,22 +194,19 @@
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-static void
-prism2sta_disconnect_usb(struct usb_interface *interface)
+static void prism2sta_disconnect_usb(struct usb_interface *interface)
 {
-	wlandevice_t		*wlandev;
-
-        DBFENTER;
+	wlandevice_t *wlandev;
 
 	wlandev = (wlandevice_t *) usb_get_intfdata(interface);
 
-	if ( wlandev != NULL ) {
+	if (wlandev != NULL) {
 		LIST_HEAD(cleanlist);
-		struct list_head	*entry;
-		struct list_head	*temp;
-		unsigned long		flags;
+		struct list_head *entry;
+		struct list_head *temp;
+		unsigned long flags;
 
-		hfa384x_t		*hw = wlandev->priv;
+		hfa384x_t *hw = wlandev->priv;
 
 		if (!hw)
 			goto exit;
@@ -231,7 +248,7 @@
 		 * responses that we have shut down.
 		 */
 		list_for_each(entry, &cleanlist) {
-			hfa384x_usbctlx_t	*ctlx;
+			hfa384x_usbctlx_t *ctlx;
 
 			ctlx = list_entry(entry, hfa384x_usbctlx_t, list);
 			complete(&ctlx->done);
@@ -264,13 +281,10 @@
 		kfree(wlandev);
 	}
 
- exit:
-
+exit:
 	usb_set_intfdata(interface, NULL);
-	DBFEXIT;
 }
 
-
 static struct usb_driver prism2_usb_driver = {
 	.name = "prism2_usb",
 	.probe = prism2sta_probe_usb,
@@ -281,21 +295,13 @@
 
 static int __init prism2usb_init(void)
 {
-        DBFENTER;
-
 	/* This call will result in calls to prism2sta_probe_usb. */
 	return usb_register(&prism2_usb_driver);
-
-	DBFEXIT;
 };
 
 static void __exit prism2usb_cleanup(void)
 {
-        DBFENTER;
-
 	usb_deregister(&prism2_usb_driver);
-
-	DBFEXIT;
 };
 
 module_init(prism2usb_init);
diff --git a/drivers/staging/wlan-ng/wlan_compat.h b/drivers/staging/wlan-ng/wlan_compat.h
deleted file mode 100644
index 8b8a510..0000000
--- a/drivers/staging/wlan-ng/wlan_compat.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/* wlan_compat.h
-*
-* Types and macros to aid in portability
-*
-* Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
-* --------------------------------------------------------------------
-*
-* linux-wlan
-*
-*   The contents of this file are subject to the Mozilla Public
-*   License Version 1.1 (the "License"); you may not use this file
-*   except in compliance with the License. You may obtain a copy of
-*   the License at http://www.mozilla.org/MPL/
-*
-*   Software distributed under the License is distributed on an "AS
-*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-*   implied. See the License for the specific language governing
-*   rights and limitations under the License.
-*
-*   Alternatively, the contents of this file may be used under the
-*   terms of the GNU Public License version 2 (the "GPL"), in which
-*   case the provisions of the GPL are applicable instead of the
-*   above.  If you wish to allow the use of your version of this file
-*   only under the terms of the GPL and not to allow others to use
-*   your version of this file under the MPL, indicate your decision
-*   by deleting the provisions above and replace them with the notice
-*   and other provisions required by the GPL.  If you do not delete
-*   the provisions above, a recipient may use your version of this
-*   file under either the MPL or the GPL.
-*
-* --------------------------------------------------------------------
-*
-* Inquiries regarding the linux-wlan Open Source project can be
-* made directly to:
-*
-* AbsoluteValue Systems Inc.
-* info@linux-wlan.com
-* http://www.linux-wlan.com
-*
-* --------------------------------------------------------------------
-*
-* Portions of the development of this software were funded by
-* Intersil Corporation as part of PRISM(R) chipset product development.
-*
-* --------------------------------------------------------------------
-*/
-
-#ifndef _WLAN_COMPAT_H
-#define _WLAN_COMPAT_H
-
-/*=============================================================*/
-/*------ Bit settings -----------------------------------------*/
-/*=============================================================*/
-
-#define BIT0	0x00000001
-#define BIT1	0x00000002
-#define BIT2	0x00000004
-#define BIT3	0x00000008
-#define BIT4	0x00000010
-#define BIT5	0x00000020
-#define BIT6	0x00000040
-#define BIT7	0x00000080
-#define BIT8	0x00000100
-#define BIT9	0x00000200
-#define BIT10	0x00000400
-#define BIT11	0x00000800
-#define BIT12	0x00001000
-#define BIT13	0x00002000
-#define BIT14	0x00004000
-#define BIT15	0x00008000
-#define BIT16	0x00010000
-#define BIT17	0x00020000
-#define BIT18	0x00040000
-#define BIT19	0x00080000
-#define BIT20	0x00100000
-#define BIT21	0x00200000
-#define BIT22	0x00400000
-#define BIT23	0x00800000
-#define BIT24	0x01000000
-#define BIT25	0x02000000
-#define BIT26	0x04000000
-#define BIT27	0x08000000
-#define BIT28	0x10000000
-#define BIT29	0x20000000
-#define BIT30	0x40000000
-#define BIT31	0x80000000
-
-/*=============================================================*/
-/*------ Compiler Portability Macros --------------------------*/
-/*=============================================================*/
-#define __WLAN_ATTRIB_PACK__		__attribute__ ((packed))
-
-/*=============================================================*/
-/*------ OS Portability Macros --------------------------------*/
-/*=============================================================*/
-
-#ifndef WLAN_DBVAR
-#define WLAN_DBVAR	wlan_debug
-#endif
-
-#define WLAN_RELEASE	"0.3.0-lkml"
-
-#include <linux/hardirq.h>
-
-#define WLAN_LOG_ERROR(x,args...) printk(KERN_ERR "%s: " x , __func__ , ##args);
-
-#define WLAN_LOG_WARNING(x,args...) printk(KERN_WARNING "%s: " x , __func__ , ##args);
-
-#define WLAN_LOG_NOTICE(x,args...) printk(KERN_NOTICE "%s: " x , __func__ , ##args);
-
-#define WLAN_LOG_INFO(args... ) printk(KERN_INFO args)
-
-#if defined(WLAN_INCLUDE_DEBUG)
-	#define WLAN_HEX_DUMP( l, x, p, n)	if( WLAN_DBVAR >= (l) ){ \
-		int __i__; \
-		printk(KERN_DEBUG x ":"); \
-		for( __i__=0; __i__ < (n); __i__++) \
-			printk( " %02x", ((u8*)(p))[__i__]); \
-		printk("\n"); }
-	#define DBFENTER { if ( WLAN_DBVAR >= 5 ){ WLAN_LOG_DEBUG(3,"---->\n"); } }
-	#define DBFEXIT  { if ( WLAN_DBVAR >= 5 ){ WLAN_LOG_DEBUG(3,"<----\n"); } }
-
-	#define WLAN_LOG_DEBUG(l,x,args...) if ( WLAN_DBVAR >= (l)) printk(KERN_DEBUG "%s(%lu): " x ,  __func__, (preempt_count() & PREEMPT_MASK), ##args );
-#else
-	#define WLAN_HEX_DUMP( l, s, p, n)
-	#define DBFENTER
-	#define DBFEXIT
-
-	#define WLAN_LOG_DEBUG(l, s, args...)
-#endif
-
-#undef netdevice_t
-typedef struct net_device netdevice_t;
-
-#define URB_ASYNC_UNLINK 0
-#define USB_QUEUE_BULK 0
-
-/*=============================================================*/
-/*------ Hardware Portability Macros --------------------------*/
-/*=============================================================*/
-
-#define ieee2host16(n)	__le16_to_cpu(n)
-#define ieee2host32(n)	__le32_to_cpu(n)
-#define host2ieee16(n)	__cpu_to_le16(n)
-#define host2ieee32(n)	__cpu_to_le32(n)
-
-/*=============================================================*/
-/*--- General Macros ------------------------------------------*/
-/*=============================================================*/
-
-#define wlan_max(a, b) (((a) > (b)) ? (a) : (b))
-#define wlan_min(a, b) (((a) < (b)) ? (a) : (b))
-
-#define wlan_isprint(c)	(((c) > (0x19)) && ((c) < (0x7f)))
-
-#define wlan_hexchar(x) (((x) < 0x0a) ? ('0' + (x)) : ('a' + ((x) - 0x0a)))
-
-/* Create a string of printable chars from something that might not be */
-/* It's recommended that the str be 4*len + 1 bytes long */
-#define wlan_mkprintstr(buf, buflen, str, strlen) \
-{ \
-	int i = 0; \
-	int j = 0; \
-	memset(str, 0, (strlen)); \
-	for (i = 0; i < (buflen); i++) { \
-		if ( wlan_isprint((buf)[i]) ) { \
-			(str)[j] = (buf)[i]; \
-			j++; \
-		} else { \
-			(str)[j] = '\\'; \
-			(str)[j+1] = 'x'; \
-			(str)[j+2] = wlan_hexchar(((buf)[i] & 0xf0) >> 4); \
-			(str)[j+3] = wlan_hexchar(((buf)[i] & 0x0f)); \
-			j += 4; \
-		} \
-	} \
-}
-
-/*=============================================================*/
-/*--- Variables -----------------------------------------------*/
-/*=============================================================*/
-
-#ifdef WLAN_INCLUDE_DEBUG
-extern int wlan_debug;
-#endif
-
-extern int wlan_ethconv;		/* What's the default ethconv? */
-
-/*=============================================================*/
-/*--- Functions -----------------------------------------------*/
-/*=============================================================*/
-#endif /* _WLAN_COMPAT_H */
-
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 8171ca1..d0b093b 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -30,6 +30,7 @@
 #include <linux/idr.h>
 #include <linux/thermal.h>
 #include <linux/spinlock.h>
+#include <linux/reboot.h>
 
 MODULE_AUTHOR("Zhang Rui");
 MODULE_DESCRIPTION("Generic thermal management sysfs support");
@@ -104,22 +105,36 @@
 temp_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct thermal_zone_device *tz = to_thermal_zone(dev);
+	long temperature;
+	int ret;
 
 	if (!tz->ops->get_temp)
 		return -EPERM;
 
-	return tz->ops->get_temp(tz, buf);
+	ret = tz->ops->get_temp(tz, &temperature);
+
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%ld\n", temperature);
 }
 
 static ssize_t
 mode_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct thermal_zone_device *tz = to_thermal_zone(dev);
+	enum thermal_device_mode mode;
+	int result;
 
 	if (!tz->ops->get_mode)
 		return -EPERM;
 
-	return tz->ops->get_mode(tz, buf);
+	result = tz->ops->get_mode(tz, &mode);
+	if (result)
+		return result;
+
+	return sprintf(buf, "%s\n", mode == THERMAL_DEVICE_ENABLED ? "enabled"
+		       : "disabled");
 }
 
 static ssize_t
@@ -132,7 +147,13 @@
 	if (!tz->ops->set_mode)
 		return -EPERM;
 
-	result = tz->ops->set_mode(tz, buf);
+	if (!strncmp(buf, "enabled", sizeof("enabled")))
+		result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED);
+	else if (!strncmp(buf, "disabled", sizeof("disabled")))
+		result = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED);
+	else
+		result = -EINVAL;
+
 	if (result)
 		return result;
 
@@ -144,7 +165,8 @@
 		     char *buf)
 {
 	struct thermal_zone_device *tz = to_thermal_zone(dev);
-	int trip;
+	enum thermal_trip_type type;
+	int trip, result;
 
 	if (!tz->ops->get_trip_type)
 		return -EPERM;
@@ -152,7 +174,22 @@
 	if (!sscanf(attr->attr.name, "trip_point_%d_type", &trip))
 		return -EINVAL;
 
-	return tz->ops->get_trip_type(tz, trip, buf);
+	result = tz->ops->get_trip_type(tz, trip, &type);
+	if (result)
+		return result;
+
+	switch (type) {
+	case THERMAL_TRIP_CRITICAL:
+		return sprintf(buf, "critical");
+	case THERMAL_TRIP_HOT:
+		return sprintf(buf, "hot");
+	case THERMAL_TRIP_PASSIVE:
+		return sprintf(buf, "passive");
+	case THERMAL_TRIP_ACTIVE:
+		return sprintf(buf, "active");
+	default:
+		return sprintf(buf, "unknown");
+	}
 }
 
 static ssize_t
@@ -160,7 +197,8 @@
 		     char *buf)
 {
 	struct thermal_zone_device *tz = to_thermal_zone(dev);
-	int trip;
+	int trip, ret;
+	long temperature;
 
 	if (!tz->ops->get_trip_temp)
 		return -EPERM;
@@ -168,12 +206,77 @@
 	if (!sscanf(attr->attr.name, "trip_point_%d_temp", &trip))
 		return -EINVAL;
 
-	return tz->ops->get_trip_temp(tz, trip, buf);
+	ret = tz->ops->get_trip_temp(tz, trip, &temperature);
+
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%ld\n", temperature);
+}
+
+static ssize_t
+passive_store(struct device *dev, struct device_attribute *attr,
+		    const char *buf, size_t count)
+{
+	struct thermal_zone_device *tz = to_thermal_zone(dev);
+	struct thermal_cooling_device *cdev = NULL;
+	int state;
+
+	if (!sscanf(buf, "%d\n", &state))
+		return -EINVAL;
+
+	if (state && !tz->forced_passive) {
+		mutex_lock(&thermal_list_lock);
+		list_for_each_entry(cdev, &thermal_cdev_list, node) {
+			if (!strncmp("Processor", cdev->type,
+				     sizeof("Processor")))
+				thermal_zone_bind_cooling_device(tz,
+								 THERMAL_TRIPS_NONE,
+								 cdev);
+		}
+		mutex_unlock(&thermal_list_lock);
+	} else if (!state && tz->forced_passive) {
+		mutex_lock(&thermal_list_lock);
+		list_for_each_entry(cdev, &thermal_cdev_list, node) {
+			if (!strncmp("Processor", cdev->type,
+				     sizeof("Processor")))
+				thermal_zone_unbind_cooling_device(tz,
+								   THERMAL_TRIPS_NONE,
+								   cdev);
+		}
+		mutex_unlock(&thermal_list_lock);
+	}
+
+	tz->tc1 = 1;
+	tz->tc2 = 1;
+
+	if (!tz->passive_delay)
+		tz->passive_delay = 1000;
+
+	if (!tz->polling_delay)
+		tz->polling_delay = 10000;
+
+	tz->forced_passive = state;
+
+	thermal_zone_device_update(tz);
+
+	return count;
+}
+
+static ssize_t
+passive_show(struct device *dev, struct device_attribute *attr,
+		   char *buf)
+{
+	struct thermal_zone_device *tz = to_thermal_zone(dev);
+
+	return sprintf(buf, "%d\n", tz->forced_passive);
 }
 
 static DEVICE_ATTR(type, 0444, type_show, NULL);
 static DEVICE_ATTR(temp, 0444, temp_show, NULL);
 static DEVICE_ATTR(mode, 0644, mode_show, mode_store);
+static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, \
+		   passive_store);
 
 static struct device_attribute trip_point_attrs[] = {
 	__ATTR(trip_point_0_type, 0444, trip_point_type_show, NULL),
@@ -236,8 +339,13 @@
 				      struct device_attribute *attr, char *buf)
 {
 	struct thermal_cooling_device *cdev = to_cooling_device(dev);
+	unsigned long state;
+	int ret;
 
-	return cdev->ops->get_max_state(cdev, buf);
+	ret = cdev->ops->get_max_state(cdev, &state);
+	if (ret)
+		return ret;
+	return sprintf(buf, "%ld\n", state);
 }
 
 static ssize_t
@@ -245,8 +353,13 @@
 				      struct device_attribute *attr, char *buf)
 {
 	struct thermal_cooling_device *cdev = to_cooling_device(dev);
+	unsigned long state;
+	int ret;
 
-	return cdev->ops->get_cur_state(cdev, buf);
+	ret = cdev->ops->get_cur_state(cdev, &state);
+	if (ret)
+		return ret;
+	return sprintf(buf, "%ld\n", state);
 }
 
 static ssize_t
@@ -255,10 +368,10 @@
 				       const char *buf, size_t count)
 {
 	struct thermal_cooling_device *cdev = to_cooling_device(dev);
-	int state;
+	unsigned long state;
 	int result;
 
-	if (!sscanf(buf, "%d\n", &state))
+	if (!sscanf(buf, "%ld\n", &state))
 		return -EINVAL;
 
 	if (state < 0)
@@ -312,13 +425,20 @@
 static ssize_t
 temp_input_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
+	long temperature;
+	int ret;
 	struct thermal_hwmon_attr *hwmon_attr
 			= container_of(attr, struct thermal_hwmon_attr, attr);
 	struct thermal_zone_device *tz
 			= container_of(hwmon_attr, struct thermal_zone_device,
 				       temp_input);
 
-	return tz->ops->get_temp(tz, buf);
+	ret = tz->ops->get_temp(tz, &temperature);
+
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%ld\n", temperature);
 }
 
 static ssize_t
@@ -330,8 +450,14 @@
 	struct thermal_zone_device *tz
 			= container_of(hwmon_attr, struct thermal_zone_device,
 				       temp_crit);
+	long temperature;
+	int ret;
 
-	return tz->ops->get_trip_temp(tz, 0, buf);
+	ret = tz->ops->get_trip_temp(tz, 0, &temperature);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%ld\n", temperature);
 }
 
 
@@ -452,6 +578,97 @@
 }
 #endif
 
+static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
+					    int delay)
+{
+	cancel_delayed_work(&(tz->poll_queue));
+
+	if (!delay)
+		return;
+
+	if (delay > 1000)
+		schedule_delayed_work(&(tz->poll_queue),
+				      round_jiffies(msecs_to_jiffies(delay)));
+	else
+		schedule_delayed_work(&(tz->poll_queue),
+				      msecs_to_jiffies(delay));
+}
+
+static void thermal_zone_device_passive(struct thermal_zone_device *tz,
+					int temp, int trip_temp, int trip)
+{
+	int trend = 0;
+	struct thermal_cooling_device_instance *instance;
+	struct thermal_cooling_device *cdev;
+	long state, max_state;
+
+	/*
+	 * Above Trip?
+	 * -----------
+	 * Calculate the thermal trend (using the passive cooling equation)
+	 * and modify the performance limit for all passive cooling devices
+	 * accordingly.  Note that we assume symmetry.
+	 */
+	if (temp >= trip_temp) {
+		tz->passive = true;
+
+		trend = (tz->tc1 * (temp - tz->last_temperature)) +
+			(tz->tc2 * (temp - trip_temp));
+
+		/* Heating up? */
+		if (trend > 0) {
+			list_for_each_entry(instance, &tz->cooling_devices,
+					    node) {
+				if (instance->trip != trip)
+					continue;
+				cdev = instance->cdev;
+				cdev->ops->get_cur_state(cdev, &state);
+				cdev->ops->get_max_state(cdev, &max_state);
+				if (state++ < max_state)
+					cdev->ops->set_cur_state(cdev, state);
+			}
+		} else if (trend < 0) { /* Cooling off? */
+			list_for_each_entry(instance, &tz->cooling_devices,
+					    node) {
+				if (instance->trip != trip)
+					continue;
+				cdev = instance->cdev;
+				cdev->ops->get_cur_state(cdev, &state);
+				cdev->ops->get_max_state(cdev, &max_state);
+				if (state > 0)
+					cdev->ops->set_cur_state(cdev, --state);
+			}
+		}
+		return;
+	}
+
+	/*
+	 * Below Trip?
+	 * -----------
+	 * Implement passive cooling hysteresis to slowly increase performance
+	 * and avoid thrashing around the passive trip point.  Note that we
+	 * assume symmetry.
+	 */
+	list_for_each_entry(instance, &tz->cooling_devices, node) {
+		if (instance->trip != trip)
+			continue;
+		cdev = instance->cdev;
+		cdev->ops->get_cur_state(cdev, &state);
+		cdev->ops->get_max_state(cdev, &max_state);
+		if (state > 0)
+			cdev->ops->set_cur_state(cdev, --state);
+		if (state == 0)
+			tz->passive = false;
+	}
+}
+
+static void thermal_zone_device_check(struct work_struct *work)
+{
+	struct thermal_zone_device *tz = container_of(work, struct
+						      thermal_zone_device,
+						      poll_queue.work);
+	thermal_zone_device_update(tz);
+}
 
 /**
  * thermal_zone_bind_cooling_device - bind a cooling device to a thermal zone
@@ -722,25 +939,113 @@
 EXPORT_SYMBOL(thermal_cooling_device_unregister);
 
 /**
+ * thermal_zone_device_update - force an update of a thermal zone's state
+ * @ttz:	the thermal zone to update
+ */
+
+void thermal_zone_device_update(struct thermal_zone_device *tz)
+{
+	int count, ret = 0;
+	long temp, trip_temp;
+	enum thermal_trip_type trip_type;
+	struct thermal_cooling_device_instance *instance;
+	struct thermal_cooling_device *cdev;
+
+	mutex_lock(&tz->lock);
+
+	tz->ops->get_temp(tz, &temp);
+
+	for (count = 0; count < tz->trips; count++) {
+		tz->ops->get_trip_type(tz, count, &trip_type);
+		tz->ops->get_trip_temp(tz, count, &trip_temp);
+
+		switch (trip_type) {
+		case THERMAL_TRIP_CRITICAL:
+			if (temp > trip_temp) {
+				if (tz->ops->notify)
+					ret = tz->ops->notify(tz, count,
+							      trip_type);
+				if (!ret) {
+					printk(KERN_EMERG
+					       "Critical temperature reached (%ld C), shutting down.\n",
+					       temp/1000);
+					orderly_poweroff(true);
+				}
+			}
+			break;
+		case THERMAL_TRIP_HOT:
+			if (temp > trip_temp)
+				if (tz->ops->notify)
+					tz->ops->notify(tz, count, trip_type);
+			break;
+		case THERMAL_TRIP_ACTIVE:
+			list_for_each_entry(instance, &tz->cooling_devices,
+					    node) {
+				if (instance->trip != count)
+					continue;
+
+				cdev = instance->cdev;
+
+				if (temp > trip_temp)
+					cdev->ops->set_cur_state(cdev, 1);
+				else
+					cdev->ops->set_cur_state(cdev, 0);
+			}
+			break;
+		case THERMAL_TRIP_PASSIVE:
+			if (temp > trip_temp || tz->passive)
+				thermal_zone_device_passive(tz, temp,
+							    trip_temp, count);
+			break;
+		}
+	}
+
+	if (tz->forced_passive)
+		thermal_zone_device_passive(tz, temp, tz->forced_passive,
+					    THERMAL_TRIPS_NONE);
+
+	tz->last_temperature = temp;
+	if (tz->passive)
+		thermal_zone_device_set_polling(tz, tz->passive_delay);
+	else if (tz->polling_delay)
+		thermal_zone_device_set_polling(tz, tz->polling_delay);
+	mutex_unlock(&tz->lock);
+}
+EXPORT_SYMBOL(thermal_zone_device_update);
+
+/**
  * thermal_zone_device_register - register a new thermal zone device
  * @type:	the thermal zone device type
  * @trips:	the number of trip points the thermal zone support
  * @devdata:	private device data
  * @ops:	standard thermal zone device callbacks
+ * @tc1:	thermal coefficient 1 for passive calculations
+ * @tc2:	thermal coefficient 2 for passive calculations
+ * @passive_delay: number of milliseconds to wait between polls when
+ *		   performing passive cooling
+ * @polling_delay: number of milliseconds to wait between polls when checking
+ *		   whether trip points have been crossed (0 for interrupt
+ *		   driven systems)
  *
  * thermal_zone_device_unregister() must be called when the device is no
- * longer needed.
+ * longer needed. The passive cooling formula uses tc1 and tc2 as described in
+ * section 11.1.5.1 of the ACPI specification 3.0.
  */
 struct thermal_zone_device *thermal_zone_device_register(char *type,
 							 int trips,
 							 void *devdata, struct
 							 thermal_zone_device_ops
-							 *ops)
+							 *ops, int tc1, int
+							 tc2,
+							 int passive_delay,
+							 int polling_delay)
 {
 	struct thermal_zone_device *tz;
 	struct thermal_cooling_device *pos;
+	enum thermal_trip_type trip_type;
 	int result;
 	int count;
+	int passive = 0;
 
 	if (strlen(type) >= THERMAL_NAME_LENGTH)
 		return ERR_PTR(-EINVAL);
@@ -769,6 +1074,11 @@
 	tz->device.class = &thermal_class;
 	tz->devdata = devdata;
 	tz->trips = trips;
+	tz->tc1 = tc1;
+	tz->tc2 = tc2;
+	tz->passive_delay = passive_delay;
+	tz->polling_delay = polling_delay;
+
 	dev_set_name(&tz->device, "thermal_zone%d", tz->id);
 	result = device_register(&tz->device);
 	if (result) {
@@ -798,8 +1108,18 @@
 		TRIP_POINT_ATTR_ADD(&tz->device, count, result);
 		if (result)
 			goto unregister;
+		tz->ops->get_trip_type(tz, count, &trip_type);
+		if (trip_type == THERMAL_TRIP_PASSIVE)
+			passive = 1;
 	}
 
+	if (!passive)
+		result = device_create_file(&tz->device,
+					    &dev_attr_passive);
+
+	if (result)
+		goto unregister;
+
 	result = thermal_add_hwmon_sysfs(tz);
 	if (result)
 		goto unregister;
@@ -814,6 +1134,10 @@
 		}
 	mutex_unlock(&thermal_list_lock);
 
+	INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check);
+
+	thermal_zone_device_update(tz);
+
 	if (!result)
 		return tz;
 
@@ -853,6 +1177,8 @@
 		    tz->ops->unbind(tz, cdev);
 	mutex_unlock(&thermal_list_lock);
 
+	thermal_zone_device_set_polling(tz, 0);
+
 	if (tz->type[0])
 		device_remove_file(&tz->device, &dev_attr_type);
 	device_remove_file(&tz->device, &dev_attr_temp);
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
index b6483dd..9cf9ff6 100644
--- a/drivers/usb/atm/ueagle-atm.c
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -626,7 +626,7 @@
 		goto err_fw_corrupted;
 
 	/*
-	 * Start to upload formware : send reset
+	 * Start to upload firmware : send reset
 	 */
 	value = 1;
 	ret = uea_send_modem_cmd(usb, F8051_USBCS, sizeof(value), &value);
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 770b3ea..080bb1e 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -392,7 +392,7 @@
 	   controllers having QE or CPM2, given minor tweaks.
 
 	   Set CONFIG_USB_GADGET to "m" to build this driver as a
-	   dynmically linked module called "fsl_qe_udc".
+	   dynamically linked module called "fsl_qe_udc".
 
 config USB_FSL_QE
 	tristate
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
index c22fab1..563d572 100644
--- a/drivers/usb/gadget/atmel_usba_udc.c
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -319,7 +319,7 @@
 
 static int vbus_is_present(struct usba_udc *udc)
 {
-	if (udc->vbus_pin != -1)
+	if (gpio_is_valid(udc->vbus_pin))
 		return gpio_get_value(udc->vbus_pin);
 
 	/* No Vbus detection: Assume always present */
@@ -1821,7 +1821,7 @@
 	DBG(DBG_GADGET, "registered driver `%s'\n", driver->driver.name);
 
 	udc->vbus_prev = 0;
-	if (udc->vbus_pin != -1)
+	if (gpio_is_valid(udc->vbus_pin))
 		enable_irq(gpio_to_irq(udc->vbus_pin));
 
 	/* If Vbus is present, enable the controller and wait for reset */
@@ -1852,7 +1852,7 @@
 	if (driver != udc->driver || !driver->unbind)
 		return -EINVAL;
 
-	if (udc->vbus_pin != -1)
+	if (gpio_is_valid(udc->vbus_pin))
 		disable_irq(gpio_to_irq(udc->vbus_pin));
 
 	spin_lock_irqsave(&udc->lock, flags);
@@ -1910,7 +1910,7 @@
 	udc->pdev = pdev;
 	udc->pclk = pclk;
 	udc->hclk = hclk;
-	udc->vbus_pin = -1;
+	udc->vbus_pin = -ENODEV;
 
 	ret = -ENOMEM;
 	udc->regs = ioremap(regs->start, regs->end - regs->start + 1);
@@ -1996,7 +1996,7 @@
 		goto err_device_add;
 	}
 
-	if (pdata->vbus_pin >= 0) {
+	if (gpio_is_valid(pdata->vbus_pin)) {
 		if (!gpio_request(pdata->vbus_pin, "atmel_usba_udc")) {
 			udc->vbus_pin = pdata->vbus_pin;
 
@@ -2005,7 +2005,7 @@
 					"atmel_usba_udc", udc);
 			if (ret) {
 				gpio_free(udc->vbus_pin);
-				udc->vbus_pin = -1;
+				udc->vbus_pin = -ENODEV;
 				dev_warn(&udc->pdev->dev,
 					 "failed to request vbus irq; "
 					 "assuming always on\n");
@@ -2051,7 +2051,7 @@
 		usba_ep_cleanup_debugfs(&usba_ep[i]);
 	usba_cleanup_debugfs(udc);
 
-	if (udc->vbus_pin != -1)
+	if (gpio_is_valid(udc->vbus_pin))
 		gpio_free(udc->vbus_pin);
 
 	free_irq(udc->irq, udc);
diff --git a/drivers/usb/serial/ChangeLog.history b/drivers/usb/serial/ChangeLog.history
index c1b2799..f13fd48 100644
--- a/drivers/usb/serial/ChangeLog.history
+++ b/drivers/usb/serial/ChangeLog.history
@@ -715,7 +715,7 @@
 
  0.2 (01/30/2000) greg kroah-hartman
 	Milestone 1 release.
-	Device is found by USB subsystem, enumerated, fimware is downloaded
+	Device is found by USB subsystem, enumerated, firmware is downloaded
 	and the descriptors are printed to the debug log, config is set, and
 	green light starts to blink. Open port works, and data can be sent
 	and received at the default settings of the UART. Loopback connector
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index a65f919..c480ea4 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -518,8 +518,8 @@
 	help
 	  Say M here if you want to use Sierra Wireless devices.
 
-	  Many deviecs have a feature known as TRU-Install, for those devices
-	  to work properly the USB Storage Sierra feature must be enabled.
+	  Many devices have a feature known as TRU-Install. For those devices
+	  to work properly, the USB Storage Sierra feature must be enabled.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called sierra.
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
index 882c57b..fdba2f6 100644
--- a/drivers/usb/storage/isd200.c
+++ b/drivers/usb/storage/isd200.c
@@ -46,6 +46,7 @@
 #include <linux/errno.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/ata.h>
 #include <linux/hdreg.h>
 #include <linux/scatterlist.h>
 
@@ -328,7 +329,7 @@
 
 struct isd200_info {
 	struct inquiry_data InquiryData;
-	struct hd_driveid *id;
+	u16 *id;
 	struct isd200_config ConfigData;
 	unsigned char *RegsBuf;
 	unsigned char ATARegs[8];
@@ -419,19 +420,19 @@
 		buf->Flags = UNIT_ATTENTION;
 		buf->AdditionalSenseCode = 0;
 		buf->AdditionalSenseCodeQualifier = 0;
-	} else if(error & MCR_ERR) {
+	} else if (error & ATA_MCR) {
 		buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID;
 		buf->AdditionalSenseLength = 0xb;
 		buf->Flags =  UNIT_ATTENTION;
 		buf->AdditionalSenseCode = 0;
 		buf->AdditionalSenseCodeQualifier = 0;
-	} else if(error & TRK0_ERR) {
+	} else if (error & ATA_TRK0NF) {
 		buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID;
 		buf->AdditionalSenseLength = 0xb;
 		buf->Flags =  NOT_READY;
 		buf->AdditionalSenseCode = 0;
 		buf->AdditionalSenseCodeQualifier = 0;
-	} else if(error & ECC_ERR) {
+	} else if (error & ATA_UNC) {
 		buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID;
 		buf->AdditionalSenseLength = 0xb;
 		buf->Flags =  DATA_PROTECT;
@@ -547,16 +548,16 @@
 		ata.generic.ActionSelect = ACTION_SELECT_1|ACTION_SELECT_5;
 		ata.generic.RegisterSelect = REG_DEVICE_HEAD | REG_COMMAND;
 		ata.write.DeviceHeadByte = info->DeviceHead;
-		ata.write.CommandByte = WIN_SRST;
+		ata.write.CommandByte = ATA_CMD_DEV_RESET;
 		isd200_set_srb(info, DMA_NONE, NULL, 0);
 		break;
 
 	case ACTION_IDENTIFY:
 		US_DEBUGP("   isd200_action(IDENTIFY)\n");
 		ata.generic.RegisterSelect = REG_COMMAND;
-		ata.write.CommandByte = WIN_IDENTIFY;
+		ata.write.CommandByte = ATA_CMD_ID_ATA;
 		isd200_set_srb(info, DMA_FROM_DEVICE, info->id,
-		                                sizeof(struct hd_driveid));
+				ATA_ID_WORDS * 2);
 		break;
 
 	default:
@@ -944,22 +945,22 @@
 			break;
 
 		if (!detect) {
-			if (regs[ATA_REG_STATUS_OFFSET] & BUSY_STAT) {
+			if (regs[ATA_REG_STATUS_OFFSET] & ATA_BUSY) {
 				US_DEBUGP("   %s status is still BSY, try again...\n",mstr);
 			} else {
 				US_DEBUGP("   %s status !BSY, continue with next operation\n",mstr);
 				break;
 			}
 		}
-		/* check for BUSY_STAT and */
-		/* WRERR_STAT (workaround ATA Zip drive) and */ 
-		/* ERR_STAT (workaround for Archos CD-ROM) */
+		/* check for ATA_BUSY and */
+		/* ATA_DF (workaround ATA Zip drive) and */
+		/* ATA_ERR (workaround for Archos CD-ROM) */
 		else if (regs[ATA_REG_STATUS_OFFSET] &
-			 (BUSY_STAT | WRERR_STAT | ERR_STAT )) {
+			 (ATA_BUSY | ATA_DF | ATA_ERR)) {
 			US_DEBUGP("   Status indicates it is not ready, try again...\n");
 		}
 		/* check for DRDY, ATA devices set DRDY after SRST */
-		else if (regs[ATA_REG_STATUS_OFFSET] & READY_STAT) {
+		else if (regs[ATA_REG_STATUS_OFFSET] & ATA_DRDY) {
 			US_DEBUGP("   Identified ATA device\n");
 			info->DeviceFlags |= DF_ATA_DEVICE;
 			info->DeviceHead = master_slave;
@@ -1053,103 +1054,50 @@
 	return(retStatus);
 }
 
-static void isd200_fix_driveid (struct hd_driveid *id)
+static void isd200_fix_driveid(u16 *id)
 {
 #ifndef __LITTLE_ENDIAN
 # ifdef __BIG_ENDIAN
 	int i;
-	u16 *stringcast;
 
-	id->config         = __le16_to_cpu(id->config);
-	id->cyls           = __le16_to_cpu(id->cyls);
-	id->reserved2      = __le16_to_cpu(id->reserved2);
-	id->heads          = __le16_to_cpu(id->heads);
-	id->track_bytes    = __le16_to_cpu(id->track_bytes);
-	id->sector_bytes   = __le16_to_cpu(id->sector_bytes);
-	id->sectors        = __le16_to_cpu(id->sectors);
-	id->vendor0        = __le16_to_cpu(id->vendor0);
-	id->vendor1        = __le16_to_cpu(id->vendor1);
-	id->vendor2        = __le16_to_cpu(id->vendor2);
-	stringcast = (u16 *)&id->serial_no[0];
-	for (i = 0; i < (20/2); i++)
-		stringcast[i] = __le16_to_cpu(stringcast[i]);
-	id->buf_type       = __le16_to_cpu(id->buf_type);
-	id->buf_size       = __le16_to_cpu(id->buf_size);
-	id->ecc_bytes      = __le16_to_cpu(id->ecc_bytes);
-	stringcast = (u16 *)&id->fw_rev[0];
-	for (i = 0; i < (8/2); i++)
-		stringcast[i] = __le16_to_cpu(stringcast[i]);
-	stringcast = (u16 *)&id->model[0];
-	for (i = 0; i < (40/2); i++)
-		stringcast[i] = __le16_to_cpu(stringcast[i]);
-	id->dword_io       = __le16_to_cpu(id->dword_io);
-	id->reserved50     = __le16_to_cpu(id->reserved50);
-	id->field_valid    = __le16_to_cpu(id->field_valid);
-	id->cur_cyls       = __le16_to_cpu(id->cur_cyls);
-	id->cur_heads      = __le16_to_cpu(id->cur_heads);
-	id->cur_sectors    = __le16_to_cpu(id->cur_sectors);
-	id->cur_capacity0  = __le16_to_cpu(id->cur_capacity0);
-	id->cur_capacity1  = __le16_to_cpu(id->cur_capacity1);
-	id->lba_capacity   = __le32_to_cpu(id->lba_capacity);
-	id->dma_1word      = __le16_to_cpu(id->dma_1word);
-	id->dma_mword      = __le16_to_cpu(id->dma_mword);
-	id->eide_pio_modes = __le16_to_cpu(id->eide_pio_modes);
-	id->eide_dma_min   = __le16_to_cpu(id->eide_dma_min);
-	id->eide_dma_time  = __le16_to_cpu(id->eide_dma_time);
-	id->eide_pio       = __le16_to_cpu(id->eide_pio);
-	id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy);
-	for (i = 0; i < 2; ++i)
-		id->words69_70[i] = __le16_to_cpu(id->words69_70[i]);
-	for (i = 0; i < 4; ++i)
-		id->words71_74[i] = __le16_to_cpu(id->words71_74[i]);
-	id->queue_depth    = __le16_to_cpu(id->queue_depth);
-	for (i = 0; i < 4; ++i)
-		id->words76_79[i] = __le16_to_cpu(id->words76_79[i]);
-	id->major_rev_num  = __le16_to_cpu(id->major_rev_num);
-	id->minor_rev_num  = __le16_to_cpu(id->minor_rev_num);
-	id->command_set_1  = __le16_to_cpu(id->command_set_1);
-	id->command_set_2  = __le16_to_cpu(id->command_set_2);
-	id->cfsse          = __le16_to_cpu(id->cfsse);
-	id->cfs_enable_1   = __le16_to_cpu(id->cfs_enable_1);
-	id->cfs_enable_2   = __le16_to_cpu(id->cfs_enable_2);
-	id->csf_default    = __le16_to_cpu(id->csf_default);
-	id->dma_ultra      = __le16_to_cpu(id->dma_ultra);
-	id->trseuc         = __le16_to_cpu(id->trseuc);
-	id->trsEuc         = __le16_to_cpu(id->trsEuc);
-	id->CurAPMvalues   = __le16_to_cpu(id->CurAPMvalues);
-	id->mprc           = __le16_to_cpu(id->mprc);
-	id->hw_config      = __le16_to_cpu(id->hw_config);
-	id->acoustic       = __le16_to_cpu(id->acoustic);
-	id->msrqs          = __le16_to_cpu(id->msrqs);
-	id->sxfert         = __le16_to_cpu(id->sxfert);
-	id->sal            = __le16_to_cpu(id->sal);
-	id->spg            = __le32_to_cpu(id->spg);
-	id->lba_capacity_2 = __le64_to_cpu(id->lba_capacity_2);
-	for (i = 0; i < 22; i++)
-		id->words104_125[i]   = __le16_to_cpu(id->words104_125[i]);
-	id->last_lun       = __le16_to_cpu(id->last_lun);
-	id->word127        = __le16_to_cpu(id->word127);
-	id->dlf            = __le16_to_cpu(id->dlf);
-	id->csfo           = __le16_to_cpu(id->csfo);
-	for (i = 0; i < 26; i++)
-		id->words130_155[i] = __le16_to_cpu(id->words130_155[i]);
-	id->word156        = __le16_to_cpu(id->word156);
-	for (i = 0; i < 3; i++)
-		id->words157_159[i] = __le16_to_cpu(id->words157_159[i]);
-	id->cfa_power      = __le16_to_cpu(id->cfa_power);
-	for (i = 0; i < 14; i++)
-		id->words161_175[i] = __le16_to_cpu(id->words161_175[i]);
-	for (i = 0; i < 31; i++)
-		id->words176_205[i] = __le16_to_cpu(id->words176_205[i]);
-	for (i = 0; i < 48; i++)
-		id->words206_254[i] = __le16_to_cpu(id->words206_254[i]);
-	id->integrity_word  = __le16_to_cpu(id->integrity_word);
+	for (i = 0; i < ATA_ID_WORDS; i++)
+		id[i] = __le16_to_cpu(id[i]);
 # else
 #  error "Please fix <asm/byteorder.h>"
 # endif
 #endif
 }
 
+static void isd200_dump_driveid(u16 *id)
+{
+	US_DEBUGP("   Identify Data Structure:\n");
+	US_DEBUGP("      config = 0x%x\n",	  id[ATA_ID_CONFIG]);
+	US_DEBUGP("      cyls = 0x%x\n",	  id[ATA_ID_CYLS]);
+	US_DEBUGP("      heads = 0x%x\n",	  id[ATA_ID_HEADS]);
+	US_DEBUGP("      track_bytes = 0x%x\n",	  id[4]);
+	US_DEBUGP("      sector_bytes = 0x%x\n",  id[5]);
+	US_DEBUGP("      sectors = 0x%x\n",	  id[ATA_ID_SECTORS]);
+	US_DEBUGP("      serial_no[0] = 0x%x\n",  *(char *)&id[ATA_ID_SERNO]);
+	US_DEBUGP("      buf_type = 0x%x\n",	  id[20]);
+	US_DEBUGP("      buf_size = 0x%x\n",	  id[ATA_ID_BUF_SIZE]);
+	US_DEBUGP("      ecc_bytes = 0x%x\n",	  id[22]);
+	US_DEBUGP("      fw_rev[0] = 0x%x\n",	  *(char *)&id[ATA_ID_FW_REV]);
+	US_DEBUGP("      model[0] = 0x%x\n",	  *(char *)&id[ATA_ID_PROD]);
+	US_DEBUGP("      max_multsect = 0x%x\n",  id[ATA_ID_MAX_MULTSECT] & 0xff);
+	US_DEBUGP("      dword_io = 0x%x\n",	  id[ATA_ID_DWORD_IO]);
+	US_DEBUGP("      capability = 0x%x\n",	  id[ATA_ID_CAPABILITY] >> 8);
+	US_DEBUGP("      tPIO = 0x%x\n",	  id[ATA_ID_OLD_PIO_MODES] >> 8);
+	US_DEBUGP("      tDMA = 0x%x\n",	  id[ATA_ID_OLD_DMA_MODES] >> 8);
+	US_DEBUGP("      field_valid = 0x%x\n",	  id[ATA_ID_FIELD_VALID]);
+	US_DEBUGP("      cur_cyls = 0x%x\n",	  id[ATA_ID_CUR_CYLS]);
+	US_DEBUGP("      cur_heads = 0x%x\n",	  id[ATA_ID_CUR_HEADS]);
+	US_DEBUGP("      cur_sectors = 0x%x\n",	  id[ATA_ID_CUR_SECTORS]);
+	US_DEBUGP("      cur_capacity = 0x%x\n",  ata_id_u32(id, 57));
+	US_DEBUGP("      multsect = 0x%x\n",	  id[ATA_ID_MULTSECT] & 0xff);
+	US_DEBUGP("      lba_capacity = 0x%x\n",  ata_id_u32(id, ATA_ID_LBA_CAPACITY));
+	US_DEBUGP("      command_set_1 = 0x%x\n", id[ATA_ID_COMMAND_SET_1]);
+	US_DEBUGP("      command_set_2 = 0x%x\n", id[ATA_ID_COMMAND_SET_2]);
+}
 
 /**************************************************************************
  * isd200_get_inquiry_data
@@ -1163,7 +1111,7 @@
 {
 	struct isd200_info *info = (struct isd200_info *)us->extra;
 	int retStatus = ISD200_GOOD;
-	struct hd_driveid *id = info->id;
+	u16 *id = info->id;
 
 	US_DEBUGP("Entering isd200_get_inquiry_data\n");
 
@@ -1180,8 +1128,7 @@
 			/* this must be an ATA device */
 			/* perform an ATA Command Identify */
 			transferStatus = isd200_action( us, ACTION_IDENTIFY,
-							id, 
-							sizeof(struct hd_driveid) );
+							id, ATA_ID_WORDS * 2);
 			if (transferStatus != ISD200_TRANSPORT_GOOD) {
 				/* Error issuing ATA Command Identify */
 				US_DEBUGP("   Error issuing ATA Command Identify\n");
@@ -1191,35 +1138,9 @@
 				int i;
 				__be16 *src;
 				__u16 *dest;
-				isd200_fix_driveid(id);
 
-				US_DEBUGP("   Identify Data Structure:\n");
-				US_DEBUGP("      config = 0x%x\n", id->config);
-				US_DEBUGP("      cyls = 0x%x\n", id->cyls);
-				US_DEBUGP("      heads = 0x%x\n", id->heads);
-				US_DEBUGP("      track_bytes = 0x%x\n", id->track_bytes);
-				US_DEBUGP("      sector_bytes = 0x%x\n", id->sector_bytes);
-				US_DEBUGP("      sectors = 0x%x\n", id->sectors);
-				US_DEBUGP("      serial_no[0] = 0x%x\n", id->serial_no[0]);
-				US_DEBUGP("      buf_type = 0x%x\n", id->buf_type);
-				US_DEBUGP("      buf_size = 0x%x\n", id->buf_size);
-				US_DEBUGP("      ecc_bytes = 0x%x\n", id->ecc_bytes);
-				US_DEBUGP("      fw_rev[0] = 0x%x\n", id->fw_rev[0]);
-				US_DEBUGP("      model[0] = 0x%x\n", id->model[0]);
-				US_DEBUGP("      max_multsect = 0x%x\n", id->max_multsect);
-				US_DEBUGP("      dword_io = 0x%x\n", id->dword_io);
-				US_DEBUGP("      capability = 0x%x\n", id->capability);
-				US_DEBUGP("      tPIO = 0x%x\n", id->tPIO);
-				US_DEBUGP("      tDMA = 0x%x\n", id->tDMA);
-				US_DEBUGP("      field_valid = 0x%x\n", id->field_valid);
-				US_DEBUGP("      cur_cyls = 0x%x\n", id->cur_cyls);
-				US_DEBUGP("      cur_heads = 0x%x\n", id->cur_heads);
-				US_DEBUGP("      cur_sectors = 0x%x\n", id->cur_sectors);
-				US_DEBUGP("      cur_capacity = 0x%x\n", (id->cur_capacity1 << 16) + id->cur_capacity0 );
-				US_DEBUGP("      multsect = 0x%x\n", id->multsect);
-				US_DEBUGP("      lba_capacity = 0x%x\n", id->lba_capacity);
-				US_DEBUGP("      command_set_1 = 0x%x\n", id->command_set_1);
-				US_DEBUGP("      command_set_2 = 0x%x\n", id->command_set_2);
+				isd200_fix_driveid(id);
+				isd200_dump_driveid(id);
 
 				memset(&info->InquiryData, 0, sizeof(info->InquiryData));
 
@@ -1229,30 +1150,30 @@
 				/* The length must be at least 36 (5 + 31) */
 				info->InquiryData.AdditionalLength = 0x1F;
 
-				if (id->command_set_1 & COMMANDSET_MEDIA_STATUS) {
+				if (id[ATA_ID_COMMAND_SET_1] & COMMANDSET_MEDIA_STATUS) {
 					/* set the removable bit */
 					info->InquiryData.DeviceTypeModifier = DEVICE_REMOVABLE;
 					info->DeviceFlags |= DF_REMOVABLE_MEDIA;
 				}
 
 				/* Fill in vendor identification fields */
-				src = (__be16*)id->model;
+				src = (__be16 *)&id[ATA_ID_PROD];
 				dest = (__u16*)info->InquiryData.VendorId;
 				for (i=0;i<4;i++)
 					dest[i] = be16_to_cpu(src[i]);
 
-				src = (__be16*)(id->model+8);
+				src = (__be16 *)&id[ATA_ID_PROD + 8/2];
 				dest = (__u16*)info->InquiryData.ProductId;
 				for (i=0;i<8;i++)
 					dest[i] = be16_to_cpu(src[i]);
 
-				src = (__be16*)id->fw_rev;
+				src = (__be16 *)&id[ATA_ID_FW_REV];
 				dest = (__u16*)info->InquiryData.ProductRevisionLevel;
 				for (i=0;i<2;i++)
 					dest[i] = be16_to_cpu(src[i]);
 
 				/* determine if it supports Media Status Notification */
-				if (id->command_set_2 & COMMANDSET_MEDIA_STATUS) {
+				if (id[ATA_ID_COMMAND_SET_2] & COMMANDSET_MEDIA_STATUS) {
 					US_DEBUGP("   Device supports Media Status Notification\n");
 
 					/* Indicate that it is enabled, even though it is not
@@ -1301,7 +1222,7 @@
 			      union ata_cdb * ataCdb)
 {
 	struct isd200_info *info = (struct isd200_info *)us->extra;
-	struct hd_driveid *id = info->id;
+	u16 *id = info->id;
 	int sendToTransport = 1;
 	unsigned char sectnum, head;
 	unsigned short cylinder;
@@ -1369,13 +1290,12 @@
 
 		US_DEBUGP("   ATA OUT - SCSIOP_READ_CAPACITY\n");
 
-		if (id->capability & CAPABILITY_LBA ) {
-			capacity = id->lba_capacity - 1;
-		} else {
-			capacity = (id->heads *
-				    id->cyls *
-				    id->sectors) - 1;
-		}
+		if (ata_id_has_lba(id))
+			capacity = ata_id_u32(id, ATA_ID_LBA_CAPACITY) - 1;
+		else
+			capacity = (id[ATA_ID_HEADS] * id[ATA_ID_CYLS] *
+				    id[ATA_ID_SECTORS]) - 1;
+
 		readCapacityData.LogicalBlockAddress = cpu_to_be32(capacity);
 		readCapacityData.BytesPerBlock = cpu_to_be32(0x200);
 
@@ -1392,16 +1312,16 @@
 		lba = be32_to_cpu(*(__be32 *)&srb->cmnd[2]);
 		blockCount = (unsigned long)srb->cmnd[7]<<8 | (unsigned long)srb->cmnd[8];
 
-		if (id->capability & CAPABILITY_LBA) {
+		if (ata_id_has_lba(id)) {
 			sectnum = (unsigned char)(lba);
 			cylinder = (unsigned short)(lba>>8);
 			head = ATA_ADDRESS_DEVHEAD_LBA_MODE | (unsigned char)(lba>>24 & 0x0F);
 		} else {
-			sectnum = (unsigned char)((lba % id->sectors) + 1);
-			cylinder = (unsigned short)(lba / (id->sectors *
-							   id->heads));
-			head = (unsigned char)((lba / id->sectors) %
-					       id->heads);
+			sectnum = (u8)((lba % id[ATA_ID_SECTORS]) + 1);
+			cylinder = (u16)(lba / (id[ATA_ID_SECTORS] *
+					id[ATA_ID_HEADS]));
+			head = (u8)((lba / id[ATA_ID_SECTORS]) %
+					id[ATA_ID_HEADS]);
 		}
 		ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;
 		ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand;
@@ -1415,7 +1335,7 @@
 		ataCdb->write.CylinderHighByte = (unsigned char)(cylinder>>8);
 		ataCdb->write.CylinderLowByte = (unsigned char)cylinder;
 		ataCdb->write.DeviceHeadByte = (head | ATA_ADDRESS_DEVHEAD_STD);
-		ataCdb->write.CommandByte = WIN_READ;
+		ataCdb->write.CommandByte = ATA_CMD_PIO_READ;
 		break;
 
 	case WRITE_10:
@@ -1424,14 +1344,16 @@
 		lba = be32_to_cpu(*(__be32 *)&srb->cmnd[2]);
 		blockCount = (unsigned long)srb->cmnd[7]<<8 | (unsigned long)srb->cmnd[8];
 
-		if (id->capability & CAPABILITY_LBA) {
+		if (ata_id_has_lba(id)) {
 			sectnum = (unsigned char)(lba);
 			cylinder = (unsigned short)(lba>>8);
 			head = ATA_ADDRESS_DEVHEAD_LBA_MODE | (unsigned char)(lba>>24 & 0x0F);
 		} else {
-			sectnum = (unsigned char)((lba % id->sectors) + 1);
-			cylinder = (unsigned short)(lba / (id->sectors * id->heads));
-			head = (unsigned char)((lba / id->sectors) % id->heads);
+			sectnum = (u8)((lba % id[ATA_ID_SECTORS]) + 1);
+			cylinder = (u16)(lba / (id[ATA_ID_SECTORS] *
+					id[ATA_ID_HEADS]));
+			head = (u8)((lba / id[ATA_ID_SECTORS]) %
+					id[ATA_ID_HEADS]);
 		}
 		ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;
 		ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand;
@@ -1445,7 +1367,7 @@
 		ataCdb->write.CylinderHighByte = (unsigned char)(cylinder>>8);
 		ataCdb->write.CylinderLowByte = (unsigned char)cylinder;
 		ataCdb->write.DeviceHeadByte = (head | ATA_ADDRESS_DEVHEAD_STD);
-		ataCdb->write.CommandByte = WIN_WRITE;
+		ataCdb->write.CommandByte = ATA_CMD_PIO_WRITE;
 		break;
 
 	case ALLOW_MEDIUM_REMOVAL:
@@ -1459,7 +1381,7 @@
 			ataCdb->generic.TransferBlockSize = 1;
 			ataCdb->generic.RegisterSelect = REG_COMMAND;
 			ataCdb->write.CommandByte = (srb->cmnd[4] & 0x1) ?
-				WIN_DOORLOCK : WIN_DOORUNLOCK;
+				ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK;
 			isd200_srb_set_bufflen(srb, 0);
 		} else {
 			US_DEBUGP("   Not removeable media, just report okay\n");
@@ -1539,8 +1461,7 @@
 	if (!info)
 		retStatus = ISD200_ERROR;
 	else {
-		info->id = (struct hd_driveid *)
-				kzalloc(sizeof(struct hd_driveid), GFP_KERNEL);
+		info->id = kzalloc(ATA_ID_WORDS * 2, GFP_KERNEL);
 		info->RegsBuf = (unsigned char *)
 				kmalloc(sizeof(info->ATARegs), GFP_KERNEL);
 		info->srb.sense_buffer =
diff --git a/drivers/usb/wusbcore/security.c b/drivers/usb/wusbcore/security.c
index 8118db7..b2f149f 100644
--- a/drivers/usb/wusbcore/security.c
+++ b/drivers/usb/wusbcore/security.c
@@ -562,7 +562,7 @@
 		struct wusb_dev *wusb_dev;
 
 		wusb_dev = wusbhc->port[p].wusb_dev;
-		if (!wusb_dev || !wusb_dev->usb_dev | !wusb_dev->usb_dev->authenticated)
+		if (!wusb_dev || !wusb_dev->usb_dev || !wusb_dev->usb_dev->authenticated)
 			continue;
 
 		usb_fill_control_urb(wusb_dev->set_gtk_urb, wusb_dev->usb_dev,
diff --git a/drivers/uwb/Kconfig b/drivers/uwb/Kconfig
index ca78312..bac8e7a 100644
--- a/drivers/uwb/Kconfig
+++ b/drivers/uwb/Kconfig
@@ -48,10 +48,10 @@
         help
           This driver enables the radio controller for WHCI cards.
 
-          WHCI is an specification developed by Intel
+          WHCI is a specification developed by Intel
           (http://www.intel.com/technology/comms/wusb/whci.htm) much
           in the spirit of USB's EHCI, but for UWB and Wireless USB
-          radio/host controllers connected via memmory mapping (eg:
+          radio/host controllers connected via memory mapping (eg:
           PCI). Most of these cards come also with a Wireless USB host
           controller.
 
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 72facb9..f9d19be 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -84,6 +84,15 @@
 	  If you have an Sharp SL-6000 Zaurus say Y to enable a driver
 	  for its LCD.
 
+config LCD_HP700
+	tristate "HP Jornada 700 series LCD Driver"
+	depends on LCD_CLASS_DEVICE
+	depends on SA1100_JORNADA720_SSP && !PREEMPT
+	default y
+	help
+	  If you have an HP Jornada 700 series handheld (710/720/728)
+	  say Y to enable LCD control driver.
+
 #
 # Backlight
 #
@@ -157,6 +166,15 @@
 	  If you have a HP Jornada 680, say y to enable the
 	  backlight driver.
 
+config BACKLIGHT_HP700
+	tristate "HP Jornada 700 series Backlight Driver"
+	depends on BACKLIGHT_CLASS_DEVICE
+	depends on SA1100_JORNADA720_SSP && !PREEMPT
+	default y
+	help
+	  If you have an HP Jornada 700 series,
+	  say Y to include backlight control driver.
+
 config BACKLIGHT_PROGEAR
 	tristate "Frontpath ProGear Backlight Driver"
 	depends on BACKLIGHT_CLASS_DEVICE && PCI && X86
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 63d7594..4eb178c 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -2,6 +2,7 @@
 
 obj-$(CONFIG_LCD_CLASS_DEVICE)     += lcd.o
 obj-$(CONFIG_LCD_CORGI)		   += corgi_lcd.o
+obj-$(CONFIG_LCD_HP700)		   += jornada720_lcd.o
 obj-$(CONFIG_LCD_LTV350QV)	   += ltv350qv.o
 obj-$(CONFIG_LCD_ILI9320)	   += ili9320.o
 obj-$(CONFIG_LCD_PLATFORM)	   += platform_lcd.o
@@ -12,6 +13,7 @@
 obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
 obj-$(CONFIG_BACKLIGHT_ATMEL_PWM)    += atmel-pwm-bl.o
 obj-$(CONFIG_BACKLIGHT_GENERIC)	+= generic_bl.o
+obj-$(CONFIG_BACKLIGHT_HP700)	+= jornada720_bl.o
 obj-$(CONFIG_BACKLIGHT_HP680)	+= hp680_bl.o
 obj-$(CONFIG_BACKLIGHT_LOCOMO)	+= locomolcd.o
 obj-$(CONFIG_BACKLIGHT_OMAP1)	+= omap1_bl.o
diff --git a/drivers/video/backlight/jornada720_bl.c b/drivers/video/backlight/jornada720_bl.c
new file mode 100644
index 0000000..c3ebb6b
--- /dev/null
+++ b/drivers/video/backlight/jornada720_bl.c
@@ -0,0 +1,161 @@
+/*
+ *
+ * Backlight driver for HP Jornada 700 series (710/720/728)
+ * Copyright (C) 2006-2009 Kristoffer Ericson <kristoffer.ericson@gmail.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 or any later version as published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/backlight.h>
+#include <linux/device.h>
+#include <linux/fb.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <mach/jornada720.h>
+#include <mach/hardware.h>
+
+#include <video/s1d13xxxfb.h>
+
+#define BL_MAX_BRIGHT	255
+#define BL_DEF_BRIGHT	25
+
+static int jornada_bl_get_brightness(struct backlight_device *bd)
+{
+	int ret;
+
+	/* check if backlight is on */
+	if (!(PPSR & PPC_LDD1))
+		return 0;
+
+	jornada_ssp_start();
+
+	/* cmd should return txdummy */
+	ret = jornada_ssp_byte(GETBRIGHTNESS);
+
+	if (jornada_ssp_byte(GETBRIGHTNESS) != TXDUMMY) {
+		printk(KERN_ERR "bl : get brightness timeout\n");
+		jornada_ssp_end();
+		return -ETIMEDOUT;
+	} else /* exchange txdummy for value */
+		ret = jornada_ssp_byte(TXDUMMY);
+
+	jornada_ssp_end();
+
+	return (BL_MAX_BRIGHT - ret);
+}
+
+static int jornada_bl_update_status(struct backlight_device *bd)
+{
+	int ret = 0;
+
+	jornada_ssp_start();
+
+	/* If backlight is off then really turn it off */
+	if ((bd->props.power != FB_BLANK_UNBLANK) || (bd->props.fb_blank != FB_BLANK_UNBLANK)) {
+		ret = jornada_ssp_byte(BRIGHTNESSOFF);
+		if (ret != TXDUMMY) {
+			printk(KERN_INFO "bl : brightness off timeout\n");
+			/* turn off backlight */
+			PPSR &= ~PPC_LDD1;
+			PPDR |= PPC_LDD1;
+			ret = -ETIMEDOUT;
+		}
+	} else  /* turn on backlight */
+		PPSR |= PPC_LDD1;
+
+		/* send command to our mcu */
+		if (jornada_ssp_byte(SETBRIGHTNESS) != TXDUMMY) {
+			printk(KERN_INFO "bl : failed to set brightness\n");
+			ret = -ETIMEDOUT;
+			goto out
+		}
+
+		/* at this point we expect that the mcu has accepted
+		   our command and is waiting for our new value
+		   please note that maximum brightness is 255,
+		   but due to physical layout it is equal to 0, so we simply
+		   invert the value (MAX VALUE - NEW VALUE). */
+		if (jornada_ssp_byte(BL_MAX_BRIGHT - bd->props.brightness) != TXDUMMY) {
+			printk(KERN_ERR "bl : set brightness failed\n");
+			ret = -ETIMEDOUT;
+		}
+
+		/* If infact we get an TXDUMMY as output we are happy and dont
+		   make any further comments about it */
+out:
+	jornada_ssp_end();
+
+	return ret;
+}
+
+static struct backlight_ops jornada_bl_ops = {
+	.get_brightness = jornada_bl_get_brightness,
+	.update_status = jornada_bl_update_status,
+	.options = BL_CORE_SUSPENDRESUME,
+};
+
+static int jornada_bl_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct backlight_device *bd;
+
+	bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL, &jornada_bl_ops);
+
+	if (IS_ERR(bd)) {
+		ret = PTR_ERR(bd);
+		printk(KERN_ERR "bl : failed to register device, err=%x\n", ret);
+		return ret;
+	}
+
+	bd->props.power = FB_BLANK_UNBLANK;
+	bd->props.brightness = BL_DEF_BRIGHT;
+	/* note. make sure max brightness is set otherwise
+	   you will get seemingly non-related errors when
+	   trying to change brightness */
+	bd->props.max_brightness = BL_MAX_BRIGHT;
+	jornada_bl_update_status(bd);
+
+	platform_set_drvdata(pdev, bd);
+	printk(KERN_INFO "HP Jornada 700 series backlight driver\n");
+
+	return 0;
+}
+
+static int jornada_bl_remove(struct platform_device *pdev)
+{
+	struct backlight_device *bd = platform_get_drvdata(pdev);
+
+	backlight_device_unregister(bd);
+
+	return 0;
+}
+
+static struct platform_driver jornada_bl_driver = {
+	.probe		= jornada_bl_probe,
+	.remove		= jornada_bl_remove,
+	.driver	= {
+		.name	= "jornada_bl",
+	},
+};
+
+int __init jornada_bl_init(void)
+{
+	return platform_driver_register(&jornada_bl_driver);
+}
+
+void __exit jornada_bl_exit(void)
+{
+	platform_driver_unregister(&jornada_bl_driver);
+}
+
+MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson>");
+MODULE_DESCRIPTION("HP Jornada 710/720/728 Backlight driver");
+MODULE_LICENSE("GPL");
+
+module_init(jornada_bl_init);
+module_exit(jornada_bl_exit);
diff --git a/drivers/video/backlight/jornada720_lcd.c b/drivers/video/backlight/jornada720_lcd.c
new file mode 100644
index 0000000..cbbb167
--- /dev/null
+++ b/drivers/video/backlight/jornada720_lcd.c
@@ -0,0 +1,153 @@
+/*
+ *
+ * LCD driver for HP Jornada 700 series (710/720/728)
+ * Copyright (C) 2006-2009 Kristoffer Ericson <kristoffer.ericson@gmail.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 or any later version as published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/fb.h>
+#include <linux/kernel.h>
+#include <linux/lcd.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+
+#include <mach/jornada720.h>
+#include <mach/hardware.h>
+
+#include <video/s1d13xxxfb.h>
+
+#define LCD_MAX_CONTRAST	0xff
+#define LCD_DEF_CONTRAST	0x80
+
+static int jornada_lcd_get_power(struct lcd_device *dev)
+{
+	/* LDD2 in PPC = LCD POWER */
+	if (PPSR & PPC_LDD2)
+		return FB_BLANK_UNBLANK;	/* PW ON */
+	else
+		return FB_BLANK_POWERDOWN;	/* PW OFF */
+}
+
+static int jornada_lcd_get_contrast(struct lcd_device *dev)
+{
+	int ret;
+
+	if (jornada_lcd_get_power(dev) != FB_BLANK_UNBLANK)
+		return 0;
+
+	jornada_ssp_start();
+
+	if (jornada_ssp_byte(GETCONTRAST) != TXDUMMY) {
+		printk(KERN_ERR "lcd: get contrast failed\n");
+		jornada_ssp_end();
+		return -ETIMEDOUT;
+	} else {
+		ret = jornada_ssp_byte(TXDUMMY);
+		jornada_ssp_end();
+		return ret;
+	}
+}
+
+static int jornada_lcd_set_contrast(struct lcd_device *dev, int value)
+{
+	int ret;
+
+	jornada_ssp_start();
+
+	/* start by sending our set contrast cmd to mcu */
+	ret = jornada_ssp_byte(SETCONTRAST);
+
+	/* push the new value */
+	if (jornada_ssp_byte(value) != TXDUMMY) {
+		printk(KERN_ERR "lcd : set contrast failed\n");
+		jornada_ssp_end();
+		return -ETIMEDOUT;
+	}
+
+	/* if we get here we can assume everything went well */
+	jornada_ssp_end();
+
+	return 0;
+}
+
+static int jornada_lcd_set_power(struct lcd_device *dev, int power)
+{
+	if (power != FB_BLANK_UNBLANK) {
+		PPSR &= ~PPC_LDD2;
+		PPDR |= PPC_LDD2;
+	} else
+		PPSR |= PPC_LDD2;
+
+	return 0;
+}
+
+static struct lcd_ops jornada_lcd_props = {
+	.get_contrast = jornada_lcd_get_contrast,
+	.set_contrast = jornada_lcd_set_contrast,
+	.get_power = jornada_lcd_get_power,
+	.set_power = jornada_lcd_set_power,
+};
+
+static int jornada_lcd_probe(struct platform_device *pdev)
+{
+	struct lcd_device *lcd_device;
+	int ret;
+
+	lcd_device = lcd_device_register(S1D_DEVICENAME, &pdev->dev, NULL, &jornada_lcd_props);
+
+	if (IS_ERR(lcd_device)) {
+		ret = PTR_ERR(lcd_device);
+		printk(KERN_ERR "lcd : failed to register device\n");
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, lcd_device);
+
+	/* lets set our default values */
+	jornada_lcd_set_contrast(lcd_device, LCD_DEF_CONTRAST);
+	jornada_lcd_set_power(lcd_device, FB_BLANK_UNBLANK);
+	/* give it some time to startup */
+	msleep(100);
+
+	return 0;
+}
+
+static int jornada_lcd_remove(struct platform_device *pdev)
+{
+	struct lcd_device *lcd_device = platform_get_drvdata(pdev);
+
+	lcd_device_unregister(lcd_device);
+
+	return 0;
+}
+
+static struct platform_driver jornada_lcd_driver = {
+	.probe	= jornada_lcd_probe,
+	.remove	= jornada_lcd_remove,
+	.driver	= {
+		.name	= "jornada_lcd",
+	},
+};
+
+int __init jornada_lcd_init(void)
+{
+	return platform_driver_register(&jornada_lcd_driver);
+}
+
+void __exit jornada_lcd_exit(void)
+{
+	platform_driver_unregister(&jornada_lcd_driver);
+}
+
+MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>");
+MODULE_DESCRIPTION("HP Jornada 710/720/728 LCD driver");
+MODULE_LICENSE("GPL");
+
+module_init(jornada_lcd_init);
+module_exit(jornada_lcd_exit);
diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c
index 65864c5..3bb4c0a 100644
--- a/drivers/video/backlight/mbp_nvidia_bl.c
+++ b/drivers/video/backlight/mbp_nvidia_bl.c
@@ -27,52 +27,171 @@
 
 static struct backlight_device *mbp_backlight_device;
 
-static struct dmi_system_id __initdata mbp_device_table[] = {
-	{
-		.ident = "3,1",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,1"),
-		},
-	},
-	{
-		.ident = "3,2",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,2"),
-		},
-	},
-	{
-		.ident = "4,1",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4,1"),
-		},
-	},
-	{ }
+/* Structure to be passed to the DMI_MATCH function. */
+struct dmi_match_data {
+	/* I/O resource to allocate. */
+	unsigned long iostart;
+	unsigned long iolen;
+	/* Backlight operations structure. */
+	struct backlight_ops backlight_ops;
 };
 
-static int mbp_send_intensity(struct backlight_device *bd)
+/* Module parameters. */
+static int debug;
+module_param_named(debug, debug, int, 0644);
+MODULE_PARM_DESC(debug, "Set to one to enable debugging messages.");
+
+/*
+ * Implementation for MacBooks with Intel chipset.
+ */
+static int intel_chipset_send_intensity(struct backlight_device *bd)
 {
 	int intensity = bd->props.brightness;
 
+	if (debug)
+		printk(KERN_DEBUG "mbp_nvidia_bl: setting brightness to %d\n",
+		       intensity);
+
 	outb(0x04 | (intensity << 4), 0xb3);
 	outb(0xbf, 0xb2);
-
 	return 0;
 }
 
-static int mbp_get_intensity(struct backlight_device *bd)
+static int intel_chipset_get_intensity(struct backlight_device *bd)
 {
+	int intensity;
+
 	outb(0x03, 0xb3);
 	outb(0xbf, 0xb2);
-	return inb(0xb3) >> 4;
+	intensity = inb(0xb3) >> 4;
+
+	if (debug)
+		printk(KERN_DEBUG "mbp_nvidia_bl: read brightness of %d\n",
+		       intensity);
+
+	return intensity;
 }
 
-static struct backlight_ops mbp_ops = {
-	.options = BL_CORE_SUSPENDRESUME,
-	.get_brightness = mbp_get_intensity,
-	.update_status  = mbp_send_intensity,
+static const struct dmi_match_data intel_chipset_data = {
+	.iostart = 0xb2,
+	.iolen = 2,
+	.backlight_ops	= {
+		.options	= BL_CORE_SUSPENDRESUME,
+		.get_brightness	= intel_chipset_get_intensity,
+		.update_status	= intel_chipset_send_intensity,
+	}
+};
+
+/*
+ * Implementation for MacBooks with Nvidia chipset.
+ */
+static int nvidia_chipset_send_intensity(struct backlight_device *bd)
+{
+	int intensity = bd->props.brightness;
+
+	if (debug)
+		printk(KERN_DEBUG "mbp_nvidia_bl: setting brightness to %d\n",
+		       intensity);
+
+	outb(0x04 | (intensity << 4), 0x52f);
+	outb(0xbf, 0x52e);
+	return 0;
+}
+
+static int nvidia_chipset_get_intensity(struct backlight_device *bd)
+{
+	int intensity;
+
+	outb(0x03, 0x52f);
+	outb(0xbf, 0x52e);
+	intensity = inb(0x52f) >> 4;
+
+	if (debug)
+		printk(KERN_DEBUG "mbp_nvidia_bl: read brightness of %d\n",
+		       intensity);
+
+	return intensity;
+}
+
+static const struct dmi_match_data nvidia_chipset_data = {
+	.iostart = 0x52e,
+	.iolen = 2,
+	.backlight_ops		= {
+		.options	= BL_CORE_SUSPENDRESUME,
+		.get_brightness	= nvidia_chipset_get_intensity,
+		.update_status	= nvidia_chipset_send_intensity
+	}
+};
+
+/*
+ * DMI matching.
+ */
+static /* const */ struct dmi_match_data *driver_data;
+
+static int mbp_dmi_match(const struct dmi_system_id *id)
+{
+	driver_data = id->driver_data;
+
+	printk(KERN_INFO "mbp_nvidia_bl: %s detected\n", id->ident);
+	return 1;
+}
+
+static const struct dmi_system_id __initdata mbp_device_table[] = {
+	{
+		.callback	= mbp_dmi_match,
+		.ident		= "MacBookPro 3,1",
+		.matches	= {
+			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,1"),
+		},
+		.driver_data	= (void *)&intel_chipset_data,
+	},
+	{
+		.callback	= mbp_dmi_match,
+		.ident		= "MacBookPro 3,2",
+		.matches	= {
+			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,2"),
+		},
+		.driver_data	= (void *)&intel_chipset_data,
+	},
+	{
+		.callback	= mbp_dmi_match,
+		.ident		= "MacBookPro 4,1",
+		.matches	= {
+			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4,1"),
+		},
+		.driver_data	= (void *)&intel_chipset_data,
+	},
+	{
+		.callback	= mbp_dmi_match,
+		.ident		= "MacBook 5,1",
+		.matches	= {
+			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5,1"),
+		},
+		.driver_data	= (void *)&nvidia_chipset_data,
+	},
+	{
+		.callback	= mbp_dmi_match,
+		.ident		= "MacBookAir 2,1",
+		.matches	= {
+			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir2,1"),
+		},
+		.driver_data	= (void *)&nvidia_chipset_data,
+	},
+	{
+		.callback	= mbp_dmi_match,
+		.ident		= "MacBookPro 5,1",
+		.matches	= {
+			DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,1"),
+		},
+		.driver_data	= (void *)&nvidia_chipset_data,
+	},
+	{ }
 };
 
 static int __init mbp_init(void)
@@ -80,20 +199,20 @@
 	if (!dmi_check_system(mbp_device_table))
 		return -ENODEV;
 
-	if (!request_region(0xb2, 2, "Macbook Pro backlight"))
+	if (!request_region(driver_data->iostart, driver_data->iolen, 
+						"Macbook Pro backlight"))
 		return -ENXIO;
 
 	mbp_backlight_device = backlight_device_register("mbp_backlight",
-							 NULL, NULL,
-							 &mbp_ops);
+					NULL, NULL, &driver_data->backlight_ops);
 	if (IS_ERR(mbp_backlight_device)) {
-		release_region(0xb2, 2);
+		release_region(driver_data->iostart, driver_data->iolen);
 		return PTR_ERR(mbp_backlight_device);
 	}
 
 	mbp_backlight_device->props.max_brightness = 15;
 	mbp_backlight_device->props.brightness =
-		mbp_get_intensity(mbp_backlight_device);
+		driver_data->backlight_ops.get_brightness(mbp_backlight_device);
 	backlight_update_status(mbp_backlight_device);
 
 	return 0;
@@ -103,7 +222,7 @@
 {
 	backlight_device_unregister(mbp_backlight_device);
 
-	release_region(0xb2, 2);
+	release_region(driver_data->iostart, driver_data->iolen);
 }
 
 module_init(mbp_init);
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index ea07258..e641584 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -3,7 +3,7 @@
  *
  * simple PWM based backlight control, board code has to setup
  * 1) pin configuration so PWM waveforms can output
- * 2) platform_data casts to the PWM id (0/1/2/3 on PXA)
+ * 2) platform_data being correctly configured
  *
  * 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
@@ -97,7 +97,7 @@
 	} else
 		dev_dbg(&pdev->dev, "got pwm for backlight\n");
 
-	bl = backlight_device_register(pdev->name, &pdev->dev,
+	bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev,
 			pb, &pwm_backlight_ops);
 	if (IS_ERR(bl)) {
 		dev_err(&pdev->dev, "failed to register backlight\n");
diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c
index 29e144f..37f08c8 100644
--- a/drivers/w1/masters/ds1wm.c
+++ b/drivers/w1/masters/ds1wm.c
@@ -16,10 +16,10 @@
 #include <linux/irq.h>
 #include <linux/pm.h>
 #include <linux/platform_device.h>
-#include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/delay.h>
-#include <linux/ds1wm.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/ds1wm.h>
 
 #include <asm/io.h>
 
@@ -89,10 +89,9 @@
 	void		__iomem *map;
 	int		bus_shift; /* # of shifts to calc register offsets */
 	struct platform_device *pdev;
-	struct ds1wm_platform_data *pdata;
+	struct mfd_cell	*cell;
 	int		irq;
 	int		active_high;
-	struct clk	*clk;
 	int		slave_present;
 	void		*reset_complete;
 	void		*read_complete;
@@ -215,17 +214,17 @@
 
 static void ds1wm_up(struct ds1wm_data *ds1wm_data)
 {
-	int gclk, divisor;
+	int divisor;
+	struct ds1wm_driver_data *plat = ds1wm_data->cell->driver_data;
 
-	if (ds1wm_data->pdata->enable)
-		ds1wm_data->pdata->enable(ds1wm_data->pdev);
+	if (ds1wm_data->cell->enable)
+		ds1wm_data->cell->enable(ds1wm_data->pdev);
 
-	gclk = clk_get_rate(ds1wm_data->clk);
-	clk_enable(ds1wm_data->clk);
-	divisor = ds1wm_find_divisor(gclk);
+	divisor = ds1wm_find_divisor(plat->clock_rate);
 	if (divisor == 0) {
 		dev_err(&ds1wm_data->pdev->dev,
-			"no suitable divisor for %dHz clock\n", gclk);
+			"no suitable divisor for %dHz clock\n",
+			plat->clock_rate);
 		return;
 	}
 	ds1wm_write_register(ds1wm_data, DS1WM_CLKDIV, divisor);
@@ -244,10 +243,8 @@
 	ds1wm_write_register(ds1wm_data, DS1WM_INT_EN,
 			     ds1wm_data->active_high ? DS1WM_INTEN_IAS : 0);
 
-	if (ds1wm_data->pdata->disable)
-		ds1wm_data->pdata->disable(ds1wm_data->pdev);
-
-	clk_disable(ds1wm_data->clk);
+	if (ds1wm_data->cell->disable)
+		ds1wm_data->cell->disable(ds1wm_data->pdev);
 }
 
 /* --------------------------------------------------------------------- */
@@ -330,13 +327,18 @@
 static int ds1wm_probe(struct platform_device *pdev)
 {
 	struct ds1wm_data *ds1wm_data;
-	struct ds1wm_platform_data *plat;
+	struct ds1wm_driver_data *plat;
 	struct resource *res;
+	struct mfd_cell *cell;
 	int ret;
 
 	if (!pdev)
 		return -ENODEV;
 
+	cell = pdev->dev.platform_data;
+	if (!cell)
+		return -ENODEV;
+
 	ds1wm_data = kzalloc(sizeof(*ds1wm_data), GFP_KERNEL);
 	if (!ds1wm_data)
 		return -ENOMEM;
@@ -348,15 +350,18 @@
 		ret = -ENXIO;
 		goto err0;
 	}
-	ds1wm_data->map = ioremap(res->start, res->end - res->start + 1);
+	ds1wm_data->map = ioremap(res->start, resource_size(res));
 	if (!ds1wm_data->map) {
 		ret = -ENOMEM;
 		goto err0;
 	}
-	plat = pdev->dev.platform_data;
-	ds1wm_data->bus_shift = plat->bus_shift;
+	plat = cell->driver_data;
+
+	/* calculate bus shift from mem resource */
+	ds1wm_data->bus_shift = resource_size(res) >> 3;
+
 	ds1wm_data->pdev = pdev;
-	ds1wm_data->pdata = plat;
+	ds1wm_data->cell = cell;
 
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (!res) {
@@ -376,26 +381,18 @@
 	if (ret)
 		goto err1;
 
-	ds1wm_data->clk = clk_get(&pdev->dev, "ds1wm");
-	if (IS_ERR(ds1wm_data->clk)) {
-		ret = PTR_ERR(ds1wm_data->clk);
-		goto err2;
-	}
-
 	ds1wm_up(ds1wm_data);
 
 	ds1wm_master.data = (void *)ds1wm_data;
 
 	ret = w1_add_master_device(&ds1wm_master);
 	if (ret)
-		goto err3;
+		goto err2;
 
 	return 0;
 
-err3:
-	ds1wm_down(ds1wm_data);
-	clk_put(ds1wm_data->clk);
 err2:
+	ds1wm_down(ds1wm_data);
 	free_irq(ds1wm_data->irq, ds1wm_data);
 err1:
 	iounmap(ds1wm_data->map);
@@ -434,7 +431,6 @@
 
 	w1_remove_master_device(&ds1wm_master);
 	ds1wm_down(ds1wm_data);
-	clk_put(ds1wm_data->clk);
 	free_irq(ds1wm_data->irq, ds1wm_data);
 	iounmap(ds1wm_data->map);
 	kfree(ds1wm_data);
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index 526187c..8ac9cdd 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -37,7 +37,7 @@
          The old xenstore userspace tools expect to find "xenbus"
          under /proc/xen, but "xenbus" is now found at the root of the
          xenfs filesystem.  Selecting this causes the kernel to create
-         the compatibilty mount point /proc/xen if it is running on
+         the compatibility mount point /proc/xen if it is running on
          a xen platform.
          If in doubt, say yes.
 
diff --git a/drivers/xen/cpu_hotplug.c b/drivers/xen/cpu_hotplug.c
index 974f56d..5f54c01 100644
--- a/drivers/xen/cpu_hotplug.c
+++ b/drivers/xen/cpu_hotplug.c
@@ -10,7 +10,7 @@
 	if (!cpu_present(cpu))
 		arch_register_cpu(cpu);
 
-	cpu_set(cpu, cpu_present_map);
+	set_cpu_present(cpu, true);
 }
 
 static void disable_hotplug_cpu(int cpu)
@@ -18,7 +18,7 @@
 	if (cpu_present(cpu))
 		arch_unregister_cpu(cpu);
 
-	cpu_clear(cpu, cpu_present_map);
+	set_cpu_present(cpu, false);
 }
 
 static void vcpu_hotplug(unsigned int cpu)
diff --git a/firmware/Makefile b/firmware/Makefile
index f1ffa21..14fdd07 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -54,6 +54,12 @@
 				     sb16/ima_adpcm_init.csp \
 				     sb16/ima_adpcm_playback.csp \
 				     sb16/ima_adpcm_capture.csp
+fw-shipped-$(CONFIG_SLICOSS) += slicoss/gbdownload.sys slicoss/gbrcvucode.sys \
+				slicoss/oasisdbgdownload.sys \
+				slicoss/oasisdownload.sys \
+				slicoss/oasisrcvucode.sys
+fw-shipped-$(CONFIG_SXG) += sxg/saharadownloadB.sys \
+				sxg/saharadbgdownloadB.sys
 fw-shipped-$(CONFIG_SND_YMFPCI) += yamaha/ds1_ctrl.fw yamaha/ds1_dsp.fw \
 				   yamaha/ds1e_ctrl.fw
 fw-shipped-$(CONFIG_TEHUTI) += tehuti/bdx.bin
diff --git a/firmware/WHENCE b/firmware/WHENCE
index 441929f..c006af8 100644
--- a/firmware/WHENCE
+++ b/firmware/WHENCE
@@ -390,6 +390,59 @@
 
 --------------------------------------------------------------------------
 
+Driver: SLICOSS - Alacritech IS-NIC products
+
+File: slicoss/gbdownload.sys.ihex
+File: slicoss/gbrcvucode.sys.ihex
+File: slicoss/oasisdbgdownload.sys.ihex
+File: slicoss/oasisdownload.sys.ihex
+File: slicoss/oasisrcvucode.sys.ihex
+
+Licence:
+		Copyright (C) 1999-2009 Alacritech, Inc.
+
+	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
+	Alacritech'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
+	Alacritech hardware.
+
+Found in hex form in kernel source.
+
+--------------------------------------------------------------------------
+
+Driver: SXG - Alacritech IS-NIC products
+
+File: sxg/saharadownloadB.sys.ihex
+File: sxg/saharadbgdownloadB.sys.ihex
+
+Licence:
+		Copyright (C) 1999-2009 Alacritech, Inc.
+
+	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
+	Alacritech'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
+	Alacritech hardware.
+
+Found in hex form in kernel source.
+
+--------------------------------------------------------------------------
+
 Driver: cxgb3 - Chelsio Terminator 3 1G/10G Ethernet adapter
 
 File: cxgb3/t3b_psram-1.1.0.bin.ihex
diff --git a/firmware/slicoss/gbdownload.sys.ihex b/firmware/slicoss/gbdownload.sys.ihex
new file mode 100644
index 0000000..dc17e63
--- /dev/null
+++ b/firmware/slicoss/gbdownload.sys.ihex
@@ -0,0 +1,6148 @@
+:10000000020000000080000000000100000000006D
+:10001000008000001200004081B200001800004083
+:1000200081B200001E00004081B2000003000040C9
+:1000300081B20000000000A898B001000480A24036
+:10004000FD7F00000900A249DD7D00000000004C9A
+:1000500080B2010007000040D1B100000000004C58
+:1000600080B201000900A240757D000060000040E0
+:10007000619901000B00A8B17E3100000900004029
+:1000800081B200001100004081B2000000801FE931
+:1000900018310000000041E980B201000F0040E982
+:1000A00080B2000000000040A59901001600294020
+:1000B00081320000160014BC803200000F0093BC97
+:1000C000803200000000504081B2010000800040FA
+:1000D00081B2000010000040A59901001C002940D9
+:1000E000813200001C0014BC80320000110093BC5F
+:1000F000803200000000504081B2010001800040C9
+:1001000081B2000020000040A59901002200294092
+:1001100081320000220014BC803200000E0093BC2B
+:100120008032000000000049DD8101002B01004009
+:10013000813201003C01004081320100270014BCE3
+:1001400080320000140113BC80320000549500403E
+:1001500045990100FFFF0040E599010000002F4094
+:1001600049B1010000000040E1B101000000004B76
+:10017000B7B3010000000040B5B30100D900004052
+:10018000B333010000000040B6D30100320095E80F
+:1001900080320000FFFF00E880880100B8002640A0
+:1001A0008132000000000040FDB30100000000406B
+:1001B000FFB301003C002250836C000000000045AA
+:1001C000FD930100A5A500A6B4A701003C00A25024
+:1001D000B573000000010040813201003C00A245DF
+:1001E0008032000000000046FD9301004100004005
+:1001F00081B200007F000020F5CF01001C0100FA51
+:10020000B3330100A5A500DAB5AB01009900A250F7
+:10021000B563000000000044FD930100D5000044D8
+:10022000B333010000000040D5990100000000DA5E
+:10023000D7B10100FFFF00DAED8B0100D5000046C9
+:10024000B333010008000040D5990100000000DA36
+:10025000D7B10100FF0000DAEF8B0100FF0000DAE8
+:10026000E38F0100D5000048B33301003C0000409B
+:10027000D5990100FF0000DAD78D0100FFFF00DAF9
+:10028000F1DB0100FF0000DAE98B0100000000480B
+:10029000E9E30100D500004BB33301002C0000401E
+:1002A000D5990100000000DAD7B10100D500004C5B
+:1002B000B3330100FFFF00DAEBDB0100D500004E95
+:1002C000B3330100030000DA818801000000005C04
+:1002D00081E00100FFFF00DAB5DB01005C00264091
+:1002E00081320000010000DAB5CF010000F000A764
+:1002F000B4870100000000DA819401000000004092
+:10030000D8B10100D5000050B3330100FFFF00DA7F
+:10031000B58B01006200264CB5630000010000DAD5
+:10032000B5CF0100000000DADFB10100D5000052B6
+:10033000B3330100FF0000DA4B890100080000DA46
+:10034000DFF70100FF0000EFDF8B010069002240B2
+:10035000DF7F000000000047FD9301002000004007
+:10036000B39B0100D500004081320100060000402F
+:10037000D5990100080000DAD7E50100F80000DA9D
+:10038000B38B010034000040D5990100000000D972
+:10039000D7B10100020000D9D5C90100000000DA80
+:1003A000D7B1010022000040B39B0100D5000040FE
+:1003B0008132010000000048B5F30100030000DABB
+:1003C0007B89010000010040DD9B0100D500005D3C
+:1003D000B3330100FFFF00DAE78B01008A002640FB
+:1003E0008132000000000041FD9301000000005038
+:1003F000E7E3010000010040D5990100000000F68C
+:10040000E7970100000000F3D7B10100D500005EBE
+:10041000B3330100FF0000DAE58B01000000004863
+:10042000E5E3010008010040D5990100FF0000DA72
+:10043000B58F0100000000F7B5970100000000DA59
+:10044000D7B101003C010040D5990100000000F83F
+:10045000E5970100000000F2D7B101000002004062
+:10046000DD9B0100960022F5813200000000004271
+:10047000FD930100000000EED5B10100000000F680
+:10048000EB970100000000F5D7B10100080000EA79
+:10049000D4C90100000000F7E3970100000000F15B
+:1004A000D7B101003C0000EEDDCB0100000000EE02
+:1004B000D5B10100000000F8E9970100000000F448
+:1004C000D7B10100D500004AB3330100FFFF00DAC5
+:1004D000DD890100B700004081B20000000000404B
+:1004E000D5990100050000A6D6B101009A1300EBD2
+:1004F000D699010008000040D5990100000200A62D
+:10050000D6B10100010000EBD69901002C0000409B
+:10051000D5990100050000A6D6B101009A1300EBA1
+:10052000D69901003C010040D5990100000200402D
+:10053000D799010000000042FD9301003C000040FB
+:10054000D5990100000000A6D6B10100000100EB22
+:10055000D699010000010040D5990100060000A6CF
+:10056000D6B101009A1300EBD699010008010040B2
+:10057000D5990100000200A6D6B10100010000EBF0
+:10058000D699010000000040D9B1010000000040F0
+:10059000DFB1010006000040D5990100A00000A6CF
+:1005A000D6B10100640000404B99010000000040FA
+:1005B0007B99010002040040DD990100B70013BCE3
+:1005C0008032000002080040DD9901000000004C6C
+:1005D000DD910100B80095E88430000000002FE9AB
+:1005E000FAB3010000000040D1B10100FF00004259
+:1005F000808801003400004080CE0100B800A64091
+:1006000081320000C100004081320100028022409E
+:1006100080320000B800004081B200000000004FAE
+:1006200081B00100CA0009F981320000C80008F950
+:1006300081320000D4001FFDF9330000C7009EFD89
+:10064000813200000000004AF3930100000080485E
+:10065000F3930100000000FDF7B3010000008049A2
+:10066000F3930100000000FC19B10100CF000AF96A
+:1006700081320000000040FB81B20100000041FD1A
+:1006800081B20100000780F9F38F0100000742F9F1
+:10069000F38F0100D300A2FFF76F0000000043407A
+:1006A00081B201000000A2FFFBEF0000000080FC0F
+:1006B000E1B101000000804081B00100D80006FED9
+:1006C0008132000000000041B3E301001C0100FA88
+:1006D000B3C30000DA0000428DB00000000000410A
+:1006E0008DB001000004004083980100EB00004041
+:1006F000813201000000005083B0010000008496A8
+:1007000080B2000026010040813201002501004036
+:100710002D110100000000402D810100000000DAD1
+:10072000B5EB0100E400849680320000E500004053
+:10073000B593000000000040B5830100DE00A24137
+:1007400083500000000000422D810100260100417D
+:100750002D01010000000041B3C30100DA00A241F5
+:100760008D500000000080DAB5BF01000000004B92
+:1007700081B00100000000DB81D00100000000D941
+:10078000B9B3010000000040B8E30100000000DC44
+:10079000B9EB010000000041B8970100150000DC32
+:1007A000B9E70100000000412D810100000000DBDD
+:1007B00081B00100270100422D11010025010040F8
+:1007C0002D110100280100402D0101000000004111
+:1007D0002D910100260100408132010025010040D9
+:1007E0002D110100000000402D8101000000A241F8
+:1007F00081D000000000849680320100FF00A0DC60
+:10080000B96B0000F80000412D910000F800004194
+:100810002D810000D8000040B3330100000090DAC1
+:100820008BB000001100004588F401004000004436
+:1008300080CE01000000A44081B200000000A3446B
+:1008400089EC00000000004289D001000000004255
+:1008500087B00100D9000043B2330100000000500E
+:10086000B5F301000C01A0DA8B400000000000414C
+:100870008BC001000000004187C001000801A241B7
+:1008800089500000FFFF00458888010010000045E6
+:100890008AF40100120190448A40000000000041E7
+:1008A0008BC00100FFFF00458AA8010000008050B6
+:1008B0008BE0010000800040F99B010000C0004077
+:1008C000B3CF01001C0100FC193101001C0140DA0A
+:1008D00081320100000041DA81B2010000000041D4
+:1008E000F9C3010016019FDA813200000280004046
+:1008F00081B200000000004491B00100000000D966
+:100900002BB101001E019F9480320000180000945A
+:1009100092E4010000000048B5F301000000004926
+:10092000B497010000000041B3C301001D01A241C2
+:1009300091500000000080402BB1010029010051BE
+:1009400093B000002901004D93B000002901004937
+:1009500093B000000000004293B001002901A241C1
+:10096000935000000000804081B201000000104060
+:1009700081B201000000114081B20100000012406C
+:1009800081B201000000134081B201000000144058
+:1009900081B201000000154081B201000000164044
+:1009A00081B201000000174081B201000000184030
+:1009B00081B201000000194081B2010000001A401C
+:1009C00081B2010000001B4081B2010000001C4008
+:1009D00081B2010000001D4081B2010000001E40F4
+:1009E00081B2010000001F4081B201000000804080
+:1009F00081B2010000040040A199010000000050F4
+:100A0000A1D10100000000401BB001000000004027
+:100A100019B001000000004017B0010000000040C4
+:100A200015B001000000004013B0010000000040BC
+:100A300011B00100000000400FB0010000000040B4
+:100A40000DB00100000000400BB0010000000040AC
+:100A500009B001000000004007B0010000000040A4
+:100A600005B001000000004003B00100000000409C
+:100A700001B0010044012048A15100000000804065
+:100A800081B201005001224B747D000000008040C3
+:100A900081B201006000004B60990100000000B1CC
+:100AA0007EB101005101A840813200004E0100409A
+:100AB00081B20000040080409798010000000058B7
+:100AC00007900100F39F004081B200000000004445
+:100AD000A5B30100AF02004081320100C502004011
+:100AE000813201000000005C07900100F39F00408C
+:100AF000BFB300005F0122CC857F000000000051E1
+:100B000007900100F39F004081B200000000004008
+:100B100049B10100AE0300CBA3C90100D0140040CD
+:100B2000A19B01000000002046B101000000004828
+:100B3000F1B10100000000D0F1B10100000000CAD5
+:100B4000F1B10100000000D5E1B101000700004053
+:100B5000619901002000002062DD01006801A840C9
+:100B600081320000000000CC85930100C5020040E6
+:100B700081320100D014004043990100000000FAC6
+:100B8000BAB30100000000FAA4B30100000000F8AD
+:100B9000BCB3010000142F4081B00100000000E749
+:100BA000A7B30100000000D8A9B30100FF0000DDD9
+:100BB000818801000200004080F4010078010040BB
+:100BC00080C80100880100DD813200000000004083
+:100BD00010B100008901004081B200008A0100408C
+:100BE00081B200008B01004081B200008C01004006
+:100BF00081B200008D01004081B200008F010040F1
+:100C000081B200009101004081B200005501004016
+:100C100081B20000D201004081B2000055010040C5
+:100C200081B20000E001004081B20000E10100401B
+:100C300081B200007F02004081B2000080020040CB
+:100C400081B20000F19F004081B20000F29F00409D
+:100C500081B200007701004181C01A005A01514061
+:100C600081B21A005A01524081B21A005A0155400D
+:100C700081B21A005A01564081B21A005501918181
+:100C800080301A005A01454081B21A005501918204
+:100C900080301A005A01464081B200000000004036
+:100CA00089B0010000002F4081B001000014004015
+:100CB00049990100B50122DEE16D00000000004C01
+:100CC00049C101000000004181C001009401A2441B
+:100CD000816C00000000004C49D101009C012240C1
+:100CE000E16D00009801A2418150000055010041D2
+:100CF000BFB3000000000042BFB301005501A00FC8
+:100D0000BD6F0000000000DEE1B101000000004402
+:100D100049C10100B701004019990100000042409B
+:100D200081B20100000043FF85B00100000000DE39
+:100D300019B10100000042FF87B00100000043FF2D
+:100D4000E1B101000000004449C1010000002FFF93
+:100D5000E1B10100081400A480CC0100AC012640E0
+:100D6000813200000000004185C00100AA01A24CB0
+:100D700081500000B60122D281320000B10122412F
+:100D8000A56F00005501A2E081320000000000D2F2
+:100D9000C1B301000000005C8990010000004042E6
+:100DA00080B201000000414380B20100000000F069
+:100DB000889401005A010044E0B10000B3010048EA
+:100DC00049C10000B101005B89900000B09F00A004
+:100DD0009EB000000000004D81B001000000004303
+:100DE000CB8301000000454081B20100BA01A2415D
+:100DF000815000000000454081B2010000004540E4
+:100E000081B20100C4019182823000000000008A9A
+:100E100080B00100B69F004080CE0100C301A64013
+:100E200081320000C401564081B20000000000532E
+:100E30006F930100F39F00526F9300000000004D7C
+:100E400081B0010000000042CD8301000000464057
+:100E500081B20100C701A24181500000000046405C
+:100E600081B201000000464081B20100D1019181B0
+:100E7000823000000000008980B00100B69F004071
+:100E800080CE0100D001A64081320000D101554042
+:100E900081B20000000000526F930100F39F0053E5
+:100EA0006F9300000000004083B001000014004078
+:100EB000499901000000234081B00100DA0122DEDF
+:100EC000E16D00000000004C49C10100000000413C
+:100ED00081C00100D501A244816C0000550100438E
+:100EE000BFB30000000000F818B10100000040F896
+:100EF00080B20100000041F080B20100000000401B
+:100F0000F1B1010000000040F1B101005A010040C0
+:100F1000E1B10000E201004091B00000000000419A
+:100F200091B00100D0142E4049B1010005000040ED
+:100F3000A39B0100080000DD81F40100E7010040EF
+:100F400080C801000000004010B10000ED01004029
+:100F500081B00000580100DEA1B30000FF01004095
+:100F600081B200000102004081B000000702004091
+:100F700081B20000570100DFE1B10000000000D0A5
+:100F8000BAB30100000000DEA1B10100020000D2EE
+:100F9000A5E70100000000D2C1B30100000000007D
+:100FA000F0B10100F7012244C1530000F601844171
+:100FB00081400000FA01004081320100000000D0B1
+:100FC00045B10100F1010041A1C10000B1020040A2
+:100FD00081320100C5020040813201005A0100DD6A
+:100FE000A1B100000000004081B0010040000040BD
+:100FF000A59B0100B102004081320100400000D3F6
+:10100000A7CB0100C50200E0A5B30000030000402B
+:10101000A39B0100580100DEA1B3000000000044C2
+:10102000BFB30100000000DE819001005501A2BAAB
+:1010300080040000600000DE619901000402A8B194
+:101040008030000057010040E0B10000000000D0F7
+:10105000BAB3010068020040819801005D02004DB2
+:101060008330010000000044E1B3010000000044AF
+:10107000E3B3010000000044E5B3010000000044B8
+:10108000E9B3010000000044EBB30100000000449C
+:10109000F5B3010000000044F7B301000000004474
+:1010A000F9B30100150222408F6F00007502004065
+:1010B000819801005D0200C7833001007D0200407D
+:1010C000819801005D02004283300100000000E8C9
+:1010D000F1B10100000000E9F1B10100000000EAF7
+:1010E000F1B10100000000EBF1B10100000000854A
+:1010F000F0B10100000000ECF1B10100000000EDD2
+:10110000F1B10100000000B2F0B10100E09F004029
+:101110008132010000000040F0B1010000000040F9
+:10112000F1B10100000000ABF0B10100000000B817
+:10113000F0B10100000000B9F0B10100000000BAF8
+:10114000F0B10100000000BBF0B101002902B8407D
+:101150008130000000000040819001002B02B94066
+:101160008132000000000041819001002D02BA4050
+:101170008132000000000042819001002F02BB403C
+:101180008132000000000043819001003102BC4028
+:101190008132000000000044819001003302BD4014
+:1011A0008132000000000045819001003502BE4000
+:1011B0008132000000000046819001003702BF40EC
+:1011C0008132000000000047819001003902C840D0
+:1011D0008132000000000048819001003B02C940BC
+:1011E0008132000000000049819001003D02CA40A8
+:1011F000813200000000004A819001003F02CB4094
+:10120000813200000000004B819001004102CC407F
+:10121000813200000000004C819001004302CD406B
+:10122000813200000000004D819001004502CE4057
+:10123000813200000000004E819001004702CF4043
+:10124000813200000000004F81900100000000404A
+:10125000F0B1010040000040A59B0100AF0200403A
+:1012600081320100C502004081320100D0142E06F7
+:10127000A5B30100400000D3A7CB0100000000F09F
+:10128000F1B10100000000F1F1B10100000000F235
+:10129000F1B10100000000F4F1B10100000000F51F
+:1012A000F1B10100000000FAF1B10100000000FB03
+:1012B000F1B10100000000FCF1B10100000000EB01
+:1012C000F1B10100000000EEF1B10100000000EFFB
+:1012D000F1B10100000000F3F1B10100000000F6DF
+:1012E000F1B10100000000FDF1B10100F70100C7FC
+:1012F000E1B100000000804081B2010063020048BB
+:1013000080320000000051401AB1010000004D4041
+:1013100081B201000000454081B201006002A2419B
+:10132000835000005C02494081B20000000052403E
+:101330001CB1010000004E4081B201000000464097
+:1013400081B201006502A241835000005C024A4064
+:1013500081B20000000000A09EB0010000000080EB
+:10136000D8B30100000000A1D0B30100000000A22A
+:10137000D2B30100000000A4D4B30100000000D0EB
+:10138000D6B30100000000D1DCB30100000000D2A0
+:10139000DEB3010000000088DAB30100000000D4D1
+:1013A0008EB30100000000D3E6B30100000000ACE2
+:1013B000ECB3010000000099FAB30100000000D571
+:1013C000E0B30100000000D5E2B30100000000D549
+:1013D000E4B30100000000D5E8B30100000000D52F
+:1013E000EAB30100000000D5F4B30100000000D50D
+:1013F000F6B30100000000D5F8B30100000000C7FB
+:10140000A9B101000000004F40B10100810200407D
+:1014100091B000000000004191B0010007000040C1
+:10142000A39B0100080000DD81F40100850200405B
+:1014300080C801000000004010B100008A02004096
+:1014400081B200009502004081B200009502004682
+:10145000A3B300009802004081B200009E02004049
+:1014600081B200008C022350A56F000000000050E4
+:10147000A5B30100BC020042A5630100C502004003
+:1014800081320100D0142D4049B10100000000D08C
+:10149000BAB30100000000DEA1B10100000000F8B5
+:1014A00000B0010094022244A553000091020041C3
+:1014B000A1C100005A0100DDA1B10000BC0200DEA4
+:1014C000A1330100C5020040813201005A010040F1
+:1014D00081B2000000000045BFB301005501A2D257
+:1014E000777D0000000000D261B10100000000DE45
+:1014F00063B101009B02A840813200005A01004004
+:1015000081B20000BC020054A5330100C5020040B6
+:1015100081320100D0142D4049B10100000000F8D3
+:10152000D0B30100000000F8D2B30100000000F8C1
+:10153000D4B30100000000F8D6B30100000000F8A9
+:1015400008B10100A9020040819801005D02004637
+:10155000833001005A01004081B20000000000A069
+:101560009EB00100000000E843B10100000000E966
+:1015700045B10100000000EA49B10100000000EBA4
+:10158000A1B101000000004F40B10100000000E7E0
+:10159000A7B30100000000D8A9B30100000000407B
+:1015A00049B10100AE0300CBA3C901000000002037
+:1015B00046B10100000000D2F1B10100000000D3EB
+:1015C000F1B10100000000D4F1B10100000000D031
+:1015D000E1B10100000000D161B101002000002054
+:1015E00062DD0100B902A84081320000000080CC19
+:1015F00085930100000000E7A7B30100000000D8B8
+:10160000A9B301000000004049B10100AE0300CBC6
+:10161000A3C901000000002046B10100000000D273
+:10162000F1B10100000000D0F1B10100000000D3D1
+:10163000F1B10100B80200D4E1B100000000A2CC79
+:1016400085FF00000000005081B00100C702A241E8
+:1016500081500000C602A2F280300000000080CC61
+:10166000858301000000004081B00100CB0280A50D
+:1016700080320000CC0200A5803200000000004152
+:1016800081C00100CD0280A58032000080010040B1
+:1016900083980100D602204F816C000000010040B9
+:1016A00083980100D602204B816C0000800000402E
+:1016B00083980100D6022047816C000000000040A2
+:1016C000839801000000004182DC0100039000418A
+:1016D000209901000000004049B1010000142F4C86
+:1016E00083B0010000000040F1B10100DA02A24124
+:1016F00083500000020000A580C80100DD02A2A501
+:10170000806C000020000090209901000000005F24
+:1017100023910100E0021F91803200003000009010
+:10172000209901000000005F23910100E3021F9156
+:10173000803200007000009020A901000000005FCE
+:1017400023910100E6021F91803200000000005F3B
+:1017500023910100E8021F91803200004068009050
+:1017600020A90100E0000040619901002100004033
+:1017700061990100220000406199010023000040AE
+:10178000619901002400004061990100250000409A
+:101790006199010026000040619901002700004086
+:1017A00061990100C000004061990100D01400401F
+:1017B00045990100020100A680B001000403004029
+:1017C00080980100060500A682B0010008070041CC
+:1017D0008298010000000040F0B1010000000041CB
+:1017E000E0B10100300300408530010039030040C2
+:1017F00081320100D814004043990100FF02A2F891
+:10180000806C0000000322F0826C000000000042A7
+:1018100021910100D0142040E1B101003003000CFF
+:10182000853001003003004D851001003003004E6B
+:1018300085100100D014204FE1B101003003004FAA
+:10184000851001003903000C85300100D8142043B5
+:1018500081B001000F0322F09E6E00003903004D9D
+:1018600085100100D814204281B001000F0322F03E
+:101870009E6E00003903004E85100100D8142041EF
+:1018800081B001001103A2F09E6E0000000000492B
+:1018900081E001000000004020950100030000905D
+:1018A000208D010000000043219501000000001B75
+:1018B00089B00100D0142040E1B1010030030017CD
+:1018C00085300100300300588510010030030059B5
+:1018D00085100100D014204FE1B101003003005AFF
+:1018E000851001003903001785300100D81420400D
+:1018F00081B00100230322F09E6E000039030058DE
+:1019000085100100D814204181B00100230322F08A
+:101910009E6E00003903005985100100D814204242
+:1019200081B001002703A2F09E6E0000030000902A
+:10193000208D0100000000402095010000000018EB
+:1019400089B001000000004088E001002F03A2429E
+:10195000217D0000A5A5004081980100D014204001
+:10196000E0B101003003004484300100390300403D
+:1019700081320100D814204081B201002F03A2F06F
+:10198000806C00000000004189E00100E000804020
+:10199000619901007015004047990100000000485E
+:1019A000F1B1010000000042F0B10100D01400408C
+:1019B000F19901000000005587B4010004000040C7
+:1019C0006199010070150043629901003603A84037
+:1019D000813200004103004081B2000070150040D8
+:1019E0004799010000000048F1B10100D8140040FF
+:1019F000F199010000000042F0B101000000005523
+:101A000087B4010002000040619901007015004395
+:101A1000629901003F03A8408132000000000048A5
+:101A200087B001004203A241875000000000A2F2EB
+:101A300086B00000100000F186F40100410326404A
+:101A4000813200000400004081B200000000004725
+:101A500084B001000000A248848400000000005F00
+:101A600061B101000000005C8F90010000000047A0
+:101A700062B101004903A84081320000F59F004790
+:101A800098300100000800478EC801004703005C41
+:101A90008F800000E00000406199010058152D4042
+:101AA0008DB00100D0142DF088B00100000000FAC4
+:101AB0008AB001000000004581B001000700004528
+:101AC00082880100000000438BF001000000004804
+:101AD00083E00100000000468294010020000041E4
+:101AE00060990100000000418DC001006403225F85
+:101AF0008D6C00005503A24181500000530300404B
+:101B000081B20000080000408598010000000044F8
+:101B100082B001000000004186B00100001C0043BB
+:101B200086D801000000A6418550010060030041F5
+:101B300083E000005E0300408132010000000048A5
+:101B400085E00100D0142F4684940100200000425B
+:101B500060990100C00000406199010000008040D0
+:101B600081B20100070000458088010000000043A9
+:101B70008BF0010000040040839801006F03A04136
+:101B8000815000006D03004182E8000000008041A8
+:101B90008EC00100AE030040A39901000000005474
+:101BA00081B00100601500408598010008000040E8
+:101BB00040E401000000005A419401000000005080
+:101BC00041E001000000004240940100000000419B
+:101BD00081C001000000A355816C0100000000419C
+:101BE000A3C101007303005085C000000000004045
+:101BF00049B1010000020040839801000016004036
+:101C00004599010000000040F1B101007E03A241AE
+:101C1000835000000000004085B001000B0000442C
+:101C200082F401001A1500A686B00100701500406C
+:101C30004599010000080040F199010000000042B0
+:101C4000F0B1010000160040E199010004000040DD
+:101C50006199010070150043629901008803A84052
+:101C6000813200008A03225A737D00007A0000400E
+:101C7000619901008B03A8B17E3100000008004289
+:101C800084C801008303A24183500000000080400B
+:101C900081B201000400004081B200000400004055
+:101CA00081B200000400004081B200000400004046
+:101CB00081B200000400004081B200000400004036
+:101CC00081B200000400004081B200000400004026
+:101CD00081B200000400004081B200000400004016
+:101CE00081B200000400004081B200000400004006
+:101CF00081B200000400004081B2000004000040F6
+:101D000081B200000400004081B2000004000040E5
+:101D100081B200000400004081B2000004000040D5
+:101D200081B200000400004081B2000004000040C5
+:101D300081B200000400004081B2000004000040B5
+:101D400081B200000400004081B2000004000040A5
+:101D500081B200000400004081B200000400004095
+:101D600081B200000400004081B200000400004085
+:101D700081B200000400004081B200000400004075
+:101D800081B200000400004081B200000400004065
+:101D900081B200000400004081B200000400004055
+:101DA00081B200000400004081B200000400004045
+:101DB00081B200000400004081B200000400004035
+:101DC00081B200000400004081B200000400004025
+:101DD00081B200000400004081B200000400004015
+:101DE00081B200000400004081B200000400004005
+:101DF00081B200000400004081B2000004000040F5
+:101E000081B200000400004081B2000004000040E4
+:101E100081B200000400004081B2000004000040D4
+:101E200081B200000400004081B2000004000040C4
+:101E300081B200000400004081B2000004000040B4
+:101E400081B200000400004081B2000004000040A4
+:101E500081B200000400004081B200000400004094
+:101E600081B200000400004081B200000400004084
+:101E700081B200000400004081B200000400004074
+:101E800081B200000400004081B200000400004064
+:101E900081B200000400004081B200000400004054
+:101EA00081B200000400004081B200000400004044
+:101EB00081B200000400004081B200000400004034
+:101EC00081B200000400004081B200000400004024
+:101ED00081B200000400004081B200000400004014
+:101EE00081B200000400004081B200000400004004
+:101EF00081B200000400004081B2000004000040F4
+:101F000081B200000400004081B2000004000040E3
+:101F100081B200000400004081B2000004000040D3
+:101F200081B200000400004081B2000004000040C3
+:101F300081B200000400004081B2000004000040B3
+:101F400081B200000400004081B2000004000040A3
+:101F500081B200000400004081B200000400004093
+:101F600081B200000400004081B200000400004083
+:101F700081B200000400004081B200000400004073
+:101F800081B200000400004081B200000400004063
+:101F900081B200000400004081B200000400004053
+:101FA00081B200000400004081B200000400004043
+:101FB00081B200000400004081B200000400004033
+:101FC00081B200000400004081B200000400004023
+:101FD00081B200000400004081B200000400004013
+:101FE00081B200000400004081B200000400004003
+:101FF00081B200000400004081B2000004000040F3
+:1020000081B200000400004081B2000004000040E2
+:1020100081B200000400004081B2000004000040D2
+:1020200081B200000400004081B2000004000040C2
+:1020300081B200000400004081B2000004000040B2
+:1020400081B200000400004081B2000004000040A2
+:1020500081B200000400004081B200000400004092
+:1020600081B200000400004081B200000400004082
+:1020700081B200000400004081B200000400004072
+:1020800081B200000400004081B200000400004062
+:1020900081B200000400004081B200000400004052
+:1020A00081B200000400004081B200000400004042
+:1020B00081B200000400004081B200000400004032
+:1020C00081B200000400004081B200000400004022
+:1020D00081B200000400004081B200000400004012
+:1020E00081B200000400004081B200000400004002
+:1020F00081B200000400004081B2000004000040F2
+:1021000081B200000400004081B2000004000040E1
+:1021100081B200000400004081B2000004000040D1
+:1021200081B200000400004081B2000004000040C1
+:1021300081B200000400004081B2000004000040B1
+:1021400081B200000400004081B2000004000040A1
+:1021500081B200000400004081B200000400004091
+:1021600081B200000400004081B200000400004081
+:1021700081B200000400004081B200000400004071
+:1021800081B200000400004081B200000400004061
+:1021900081B200000400004081B200000400004051
+:1021A00081B200000400004081B200000400004041
+:1021B00081B200000400004081B200000400004031
+:1021C00081B200000400004081B200000400004021
+:1021D00081B200000400004081B200000400004011
+:1021E00081B200000400004081B200000400004001
+:1021F00081B200000400004081B2000004000040F1
+:1022000081B200000400004081B2000004000040E0
+:1022100081B200000400004081B2000004000040D0
+:1022200081B200000400004081B2000004000040C0
+:1022300081B200000400004081B2000004000040B0
+:1022400081B200000400004081B2000004000040A0
+:1022500081B200000400004081B200000400004090
+:1022600081B200000400004081B200000400004080
+:1022700081B200000400004081B200000400004070
+:1022800081B200000400004081B200000400004060
+:1022900081B200000400004081B200000400004050
+:1022A00081B200000400004081B200000400004040
+:1022B00081B200000400004081B200000400004030
+:1022C00081B200000400004081B200000400004020
+:1022D00081B200000400004081B200000400004010
+:1022E00081B200000400004081B200000400004000
+:1022F00081B200000400004081B2000004000040F0
+:1023000081B200000400004081B2000004000040DF
+:1023100081B200000400004081B2000004000040CF
+:1023200081B200000400004081B2000004000040BF
+:1023300081B200000400004081B2000004000040AF
+:1023400081B200000400004081B20000040000409F
+:1023500081B200000400004081B20000040000408F
+:1023600081B200000400004081B20000040000407F
+:1023700081B200000400004081B20000040000406F
+:1023800081B200000400004081B20000040000405F
+:1023900081B200000400004081B20000040000404F
+:1023A00081B200000400004081B20000040000403F
+:1023B00081B200000400004081B20000040000402F
+:1023C00081B200000400004081B20000040000401F
+:1023D00081B200000400004081B20000040000400F
+:1023E00081B200000400004081B2000004000040FF
+:1023F00081B200000400004081B2000004000040EF
+:1024000081B200000400004081B2000004000040DE
+:1024100081B200000400004081B2000004000040CE
+:1024200081B200000400004081B2000004000040BE
+:1024300081B200000400004081B2000004000040AE
+:1024400081B200000400004081B20000040000409E
+:1024500081B200000400004081B20000040000408E
+:1024600081B200000400004081B20000040000407E
+:1024700081B200000400004081B20000040000406E
+:1024800081B200000400004081B20000040000405E
+:1024900081B200000400004081B20000040000404E
+:1024A00081B200000400004081B20000040000403E
+:1024B00081B200000400004081B20000040000402E
+:1024C00081B200000400004081B20000040000401E
+:1024D00081B200000400004081B20000040000400E
+:1024E00081B200000400004081B2000004000040FE
+:1024F00081B200000400004081B2000004000040EE
+:1025000081B200000400004081B2000004000040DD
+:1025100081B200000400004081B2000004000040CD
+:1025200081B200000400004081B2000004000040BD
+:1025300081B200000400004081B2000004000040AD
+:1025400081B200000400004081B20000040000409D
+:1025500081B200000400004081B20000040000408D
+:1025600081B200000400004081B20000040000407D
+:1025700081B200000400004081B20000040000406D
+:1025800081B200000400004081B20000040000405D
+:1025900081B200000400004081B20000040000404D
+:1025A00081B200000400004081B20000040000403D
+:1025B00081B200000400004081B20000040000402D
+:1025C00081B200000400004081B20000040000401D
+:1025D00081B200000400004081B20000040000400D
+:1025E00081B200000400004081B2000004000040FD
+:1025F00081B200000400004081B2000004000040ED
+:1026000081B200000400004081B2000004000040DC
+:1026100081B200000400004081B2000004000040CC
+:1026200081B200000400004081B2000004000040BC
+:1026300081B200000400004081B2000004000040AC
+:1026400081B200000400004081B20000040000409C
+:1026500081B200000400004081B20000040000408C
+:1026600081B200000400004081B20000040000407C
+:1026700081B200000400004081B20000040000406C
+:1026800081B200000400004081B20000040000405C
+:1026900081B200000400004081B20000040000404C
+:1026A00081B200000400004081B20000040000403C
+:1026B00081B200000400004081B20000040000402C
+:1026C00081B200000400004081B20000040000401C
+:1026D00081B200000400004081B20000040000400C
+:1026E00081B200000400004081B2000004000040FC
+:1026F00081B200000400004081B2000004000040EC
+:1027000081B200000400004081B2000004000040DB
+:1027100081B200000400004081B2000004000040CB
+:1027200081B200000400004081B2000004000040BB
+:1027300081B200000400004081B2000004000040AB
+:1027400081B200000400004081B20000040000409B
+:1027500081B200000400004081B20000040000408B
+:1027600081B200000400004081B20000040000407B
+:1027700081B200000400004081B20000040000406B
+:1027800081B200000400004081B20000040000405B
+:1027900081B200000400004081B20000040000404B
+:1027A00081B200000400004081B20000040000403B
+:1027B00081B200000400004081B20000040000402B
+:1027C00081B200000400004081B20000040000401B
+:1027D00081B200000400004081B20000040000400B
+:1027E00081B200000400004081B2000004000040FB
+:1027F00081B200000400004081B2000004000040EB
+:1028000081B200000400004081B2000004000040DA
+:1028100081B200000400004081B2000004000040CA
+:1028200081B200000400004081B2000004000040BA
+:1028300081B200000400004081B2000004000040AA
+:1028400081B200000400004081B20000040000409A
+:1028500081B200000400004081B20000040000408A
+:1028600081B200000400004081B20000040000407A
+:1028700081B200000400004081B20000040000406A
+:1028800081B200000400004081B20000040000405A
+:1028900081B200000400004081B20000040000404A
+:1028A00081B200000400004081B20000040000403A
+:1028B00081B200000400004081B20000040000402A
+:1028C00081B200000400004081B20000040000401A
+:1028D00081B200000400004081B20000040000400A
+:1028E00081B200000400004081B2000004000040FA
+:1028F00081B200000400004081B2000004000040EA
+:1029000081B200000400004081B2000004000040D9
+:1029100081B200000400004081B2000004000040C9
+:1029200081B200000400004081B2000004000040B9
+:1029300081B200000400004081B2000004000040A9
+:1029400081B200000400004081B200000400004099
+:1029500081B200000400004081B200000400004089
+:1029600081B200000400004081B200000400004079
+:1029700081B200000400004081B200000400004069
+:1029800081B200000400004081B200000400004059
+:1029900081B200000400004081B200000400004049
+:1029A00081B200000400004081B200000400004039
+:1029B00081B200000400004081B200000400004029
+:1029C00081B200000400004081B200000400004019
+:1029D00081B200000400004081B200000400004009
+:1029E00081B200000400004081B2000004000040F9
+:1029F00081B200000400004081B2000004000040E9
+:102A000081B200000400004081B2000004000040D8
+:102A100081B200000400004081B2000004000040C8
+:102A200081B200000400004081B2000004000040B8
+:102A300081B200000400004081B2000004000040A8
+:102A400081B200000400004081B200000400004098
+:102A500081B200000400004081B200000400004088
+:102A600081B200000400004081B200000400004078
+:102A700081B200000400004081B200000400004068
+:102A800081B200000400004081B200000400004058
+:102A900081B200000400004081B200000400004048
+:102AA00081B200000400004081B200000400004038
+:102AB00081B200000400004081B200000400004028
+:102AC00081B200000400004081B200000400004018
+:102AD00081B200000400004081B200000400004008
+:102AE00081B200000400004081B2000004000040F8
+:102AF00081B200000400004081B2000004000040E8
+:102B000081B200000400004081B2000004000040D7
+:102B100081B200000400004081B2000004000040C7
+:102B200081B200000400004081B2000004000040B7
+:102B300081B200000400004081B2000004000040A7
+:102B400081B200000400004081B200000400004097
+:102B500081B200000400004081B200000400004087
+:102B600081B200000400004081B200000400004077
+:102B700081B200000400004081B200000400004067
+:102B800081B200000400004081B200000400004057
+:102B900081B200000400004081B200000400004047
+:102BA00081B200000400004081B200000400004037
+:102BB00081B200000400004081B200000400004027
+:102BC00081B200000400004081B200000400004017
+:102BD00081B200000400004081B200000400004007
+:102BE00081B200000400004081B2000004000040F7
+:102BF00081B200000400004081B2000004000040E7
+:102C000081B200000400004081B2000004000040D6
+:102C100081B200000400004081B2000004000040C6
+:102C200081B200000400004081B2000004000040B6
+:102C300081B200000400004081B2000004000040A6
+:102C400081B200000400004081B200000400004096
+:102C500081B200000400004081B200000400004086
+:102C600081B200000400004081B200000400004076
+:102C700081B200000400004081B200000400004066
+:102C800081B200000400004081B200000400004056
+:102C900081B200000400004081B200000400004046
+:102CA00081B200000400004081B200000400004036
+:102CB00081B200000400004081B200000400004026
+:102CC00081B200000400004081B200000400004016
+:102CD00081B200000400004081B200000400004006
+:102CE00081B200000400004081B2000004000040F6
+:102CF00081B200000400004081B2000004000040E6
+:102D000081B200000400004081B2000004000040D5
+:102D100081B200000400004081B2000004000040C5
+:102D200081B200000400004081B2000004000040B5
+:102D300081B200000400004081B2000004000040A5
+:102D400081B200000400004081B200000400004095
+:102D500081B200000400004081B200000400004085
+:102D600081B200000400004081B200000400004075
+:102D700081B200000400004081B200000400004065
+:102D800081B200000400004081B200000400004055
+:102D900081B200000400004081B200000400004045
+:102DA00081B200000400004081B200000400004035
+:102DB00081B200000400004081B200000400004025
+:102DC00081B200000400004081B200000400004015
+:102DD00081B200000400004081B200000400004005
+:102DE00081B200000400004081B2000004000040F5
+:102DF00081B200000400004081B2000004000040E5
+:102E000081B200000400004081B2000004000040D4
+:102E100081B200000400004081B2000004000040C4
+:102E200081B200000400004081B2000004000040B4
+:102E300081B200000400004081B2000004000040A4
+:102E400081B200000400004081B200000400004094
+:102E500081B200000400004081B200000400004084
+:102E600081B200000400004081B200000400004074
+:102E700081B200000400004081B200000400004064
+:102E800081B200000400004081B200000400004054
+:102E900081B200000400004081B200000400004044
+:102EA00081B200000400004081B200000400004034
+:102EB00081B200000400004081B200000400004024
+:102EC00081B200000400004081B200000400004014
+:102ED00081B200000400004081B200000400004004
+:102EE00081B200000400004081B2000004000040F4
+:102EF00081B200000400004081B2000004000040E4
+:102F000081B200000400004081B2000004000040D3
+:102F100081B200000400004081B2000004000040C3
+:102F200081B200000400004081B2000004000040B3
+:102F300081B200000400004081B2000004000040A3
+:102F400081B200000400004081B200000400004093
+:102F500081B200000400004081B200000400004083
+:102F600081B200000400004081B200000400004073
+:102F700081B200000400004081B200000400004063
+:102F800081B200000400004081B200000400004053
+:102F900081B200000400004081B200000400004043
+:102FA00081B200000400004081B200000400004033
+:102FB00081B200000400004081B200000400004023
+:102FC00081B200000400004081B200000400004013
+:102FD00081B200000400004081B200000400004003
+:102FE00081B200000400004081B2000004000040F3
+:102FF00081B200000400004081B2000004000040E3
+:1030000081B200000400004081B2000004000040D2
+:1030100081B200000400004081B2000004000040C2
+:1030200081B200000400004081B2000004000040B2
+:1030300081B200000400004081B2000004000040A2
+:1030400081B200000400004081B200000400004092
+:1030500081B200000400004081B200000400004082
+:1030600081B200000400004081B200000400004072
+:1030700081B200000400004081B200000400004062
+:1030800081B200000400004081B200000400004052
+:1030900081B200000400004081B200000400004042
+:1030A00081B200000400004081B200000400004032
+:1030B00081B200000400004081B200000400004022
+:1030C00081B200000400004081B200000400004012
+:1030D00081B200000400004081B200000400004002
+:1030E00081B200000400004081B2000004000040F2
+:1030F00081B200000400004081B2000004000040E2
+:1031000081B200000400004081B2000004000040D1
+:1031100081B200000400004081B2000004000040C1
+:1031200081B200000400004081B2000004000040B1
+:1031300081B200000400004081B2000004000040A1
+:1031400081B200000400004081B200000400004091
+:1031500081B200000400004081B200000400004081
+:1031600081B200000400004081B200000400004071
+:1031700081B200000400004081B200000400004061
+:1031800081B200000400004081B200000400004051
+:1031900081B200000400004081B200000400004041
+:1031A00081B200000400004081B200000400004031
+:1031B00081B200000400004081B200000400004021
+:1031C00081B200000400004081B200000400004011
+:1031D00081B200000400004081B200000400004001
+:1031E00081B200000400004081B2000004000040F1
+:1031F00081B200000400004081B2000004000040E1
+:1032000081B200000400004081B2000004000040D0
+:1032100081B200000400004081B2000004000040C0
+:1032200081B200000400004081B2000004000040B0
+:1032300081B200000400004081B2000004000040A0
+:1032400081B200000400004081B200000400004090
+:1032500081B200000400004081B200000400004080
+:1032600081B200000400004081B200000400004070
+:1032700081B200000400004081B200000400004060
+:1032800081B200000400004081B200000400004050
+:1032900081B200000400004081B200000400004040
+:1032A00081B200000400004081B200000400004030
+:1032B00081B200000400004081B200000400004020
+:1032C00081B200000400004081B200000400004010
+:1032D00081B200000400004081B200000400004000
+:1032E00081B200000400004081B2000004000040F0
+:1032F00081B200000400004081B2000004000040E0
+:1033000081B200000400004081B2000004000040CF
+:1033100081B200000400004081B2000004000040BF
+:1033200081B200000400004081B2000004000040AF
+:1033300081B200000400004081B20000040000409F
+:1033400081B200000400004081B20000040000408F
+:1033500081B200000400004081B20000040000407F
+:1033600081B200000400004081B20000040000406F
+:1033700081B200000400004081B20000040000405F
+:1033800081B200000400004081B20000040000404F
+:1033900081B200000400004081B20000040000403F
+:1033A00081B200000400004081B20000040000402F
+:1033B00081B200000400004081B20000040000401F
+:1033C00081B200000400004081B20000040000400F
+:1033D00081B200000400004081B2000004000040FF
+:1033E00081B200000400004081B2000004000040EF
+:1033F00081B200000400004081B2000004000040DF
+:1034000081B200000400004081B2000004000040CE
+:1034100081B200000400004081B2000004000040BE
+:1034200081B200000400004081B2000004000040AE
+:1034300081B200000400004081B20000040000409E
+:1034400081B200000400004081B20000040000408E
+:1034500081B200000400004081B20000040000407E
+:1034600081B200000400004081B20000040000406E
+:1034700081B200000400004081B20000040000405E
+:1034800081B200000400004081B20000040000404E
+:1034900081B200000400004081B20000040000403E
+:1034A00081B200000400004081B20000040000402E
+:1034B00081B200000400004081B20000040000401E
+:1034C00081B200000400004081B20000040000400E
+:1034D00081B200000400004081B2000004000040FE
+:1034E00081B200000400004081B2000004000040EE
+:1034F00081B200000400004081B2000004000040DE
+:1035000081B200000400004081B2000004000040CD
+:1035100081B200000400004081B2000004000040BD
+:1035200081B200000400004081B2000004000040AD
+:1035300081B200000400004081B20000040000409D
+:1035400081B200000400004081B20000040000408D
+:1035500081B200000400004081B20000040000407D
+:1035600081B200000400004081B20000040000406D
+:1035700081B200000400004081B20000040000405D
+:1035800081B200000400004081B20000040000404D
+:1035900081B200000400004081B20000040000403D
+:1035A00081B200000400004081B20000040000402D
+:1035B00081B200000400004081B20000040000401D
+:1035C00081B200000400004081B20000040000400D
+:1035D00081B200000400004081B2000004000040FD
+:1035E00081B200000400004081B2000004000040ED
+:1035F00081B200000400004081B2000004000040DD
+:1036000081B200000400004081B2000004000040CC
+:1036100081B200000400004081B2000004000040BC
+:1036200081B200000400004081B2000004000040AC
+:1036300081B200000400004081B20000040000409C
+:1036400081B200000400004081B20000040000408C
+:1036500081B200000400004081B20000040000407C
+:1036600081B200000400004081B20000040000406C
+:1036700081B200000400004081B20000040000405C
+:1036800081B200000400004081B20000040000404C
+:1036900081B200000400004081B20000040000403C
+:1036A00081B200000400004081B20000040000402C
+:1036B00081B200000400004081B20000040000401C
+:1036C00081B200000400004081B20000040000400C
+:1036D00081B200000400004081B2000004000040FC
+:1036E00081B200000400004081B2000004000040EC
+:1036F00081B200000400004081B2000004000040DC
+:1037000081B200000400004081B2000004000040CB
+:1037100081B200000400004081B2000004000040BB
+:1037200081B200000400004081B2000004000040AB
+:1037300081B200000400004081B20000040000409B
+:1037400081B200000400004081B20000040000408B
+:1037500081B200000400004081B20000040000407B
+:1037600081B200000400004081B20000040000406B
+:1037700081B200000400004081B20000040000405B
+:1037800081B200000400004081B20000040000404B
+:1037900081B200000400004081B20000040000403B
+:1037A00081B200000400004081B20000040000402B
+:1037B00081B200000400004081B20000040000401B
+:1037C00081B200000400004081B20000040000400B
+:1037D00081B200000400004081B2000004000040FB
+:1037E00081B200000400004081B2000004000040EB
+:1037F00081B200000400004081B2000004000040DB
+:1038000081B200000400004081B2000004000040CA
+:1038100081B200000400004081B2000004000040BA
+:1038200081B200000400004081B2000004000040AA
+:1038300081B200000400004081B20000040000409A
+:1038400081B200000400004081B20000040000408A
+:1038500081B200000400004081B20000040000407A
+:1038600081B200000400004081B20000040000406A
+:1038700081B200000400004081B20000040000405A
+:1038800081B200000400004081B20000040000404A
+:1038900081B200000400004081B20000040000403A
+:1038A00081B200000400004081B20000040000402A
+:1038B00081B200000400004081B20000040000401A
+:1038C00081B200000400004081B20000040000400A
+:1038D00081B200000400004081B2000004000040FA
+:1038E00081B200000400004081B2000004000040EA
+:1038F00081B200000400004081B2000004000040DA
+:1039000081B200000400004081B2000004000040C9
+:1039100081B200000400004081B2000004000040B9
+:1039200081B200000400004081B2000004000040A9
+:1039300081B200000400004081B200000400004099
+:1039400081B200000400004081B200000400004089
+:1039500081B200000400004081B200000400004079
+:1039600081B200000400004081B200000400004069
+:1039700081B200000400004081B200000400004059
+:1039800081B200000400004081B200000400004049
+:1039900081B200000400004081B200000400004039
+:1039A00081B200000400004081B200000400004029
+:1039B00081B200000400004081B200000400004019
+:1039C00081B200000400004081B200000400004009
+:1039D00081B200000400004081B2000004000040F9
+:1039E00081B200000400004081B2000004000040E9
+:1039F00081B200000400004081B2000004000040D9
+:103A000081B200000400004081B2000004000040C8
+:103A100081B200000400004081B2000004000040B8
+:103A200081B200000400004081B2000004000040A8
+:103A300081B200000400004081B200000400004098
+:103A400081B200000400004081B200000400004088
+:103A500081B200000400004081B200000400004078
+:103A600081B200000400004081B200000400004068
+:103A700081B200000400004081B200000400004058
+:103A800081B200000400004081B200000400004048
+:103A900081B200000400004081B200000400004038
+:103AA00081B200000400004081B200000400004028
+:103AB00081B200000400004081B200000400004018
+:103AC00081B200000400004081B200000400004008
+:103AD00081B200000400004081B2000004000040F8
+:103AE00081B200000400004081B2000004000040E8
+:103AF00081B200000400004081B2000004000040D8
+:103B000081B200000400004081B2000004000040C7
+:103B100081B200000400004081B2000004000040B7
+:103B200081B200000400004081B2000004000040A7
+:103B300081B200000400004081B200000400004097
+:103B400081B200000400004081B200000400004087
+:103B500081B200000400004081B200000400004077
+:103B600081B200000400004081B200000400004067
+:103B700081B200000400004081B200000400004057
+:103B800081B200000400004081B200000400004047
+:103B900081B200000400004081B200000400004037
+:103BA00081B200000400004081B200000400004027
+:103BB00081B200000400004081B200000400004017
+:103BC00081B200000400004081B200000400004007
+:103BD00081B200000400004081B2000004000040F7
+:103BE00081B200000400004081B2000004000040E7
+:103BF00081B200000400004081B2000004000040D7
+:103C000081B200000400004081B2000004000040C6
+:103C100081B200000400004081B2000004000040B6
+:103C200081B200000400004081B2000004000040A6
+:103C300081B200000400004081B200000400004096
+:103C400081B200000400004081B200000400004086
+:103C500081B200000400004081B200000400004076
+:103C600081B200000400004081B200000400004066
+:103C700081B200000400004081B200000400004056
+:103C800081B200000400004081B200000400004046
+:103C900081B200000400004081B200000400004036
+:103CA00081B200000400004081B200000400004026
+:103CB00081B200000400004081B200000400004016
+:103CC00081B200000400004081B200000400004006
+:103CD00081B200000400004081B2000004000040F6
+:103CE00081B200000400004081B2000004000040E6
+:103CF00081B200000400004081B2000004000040D6
+:103D000081B200000400004081B2000004000040C5
+:103D100081B200000400004081B2000004000040B5
+:103D200081B200000400004081B2000004000040A5
+:103D300081B200000400004081B200000400004095
+:103D400081B200000400004081B200000400004085
+:103D500081B200000400004081B200000400004075
+:103D600081B200000400004081B200000400004065
+:103D700081B200000400004081B200000400004055
+:103D800081B200000400004081B200000400004045
+:103D900081B200000400004081B200000400004035
+:103DA00081B200000400004081B200000400004025
+:103DB00081B200000400004081B200000400004015
+:103DC00081B200000400004081B200000400004005
+:103DD00081B200000400004081B2000004000040F5
+:103DE00081B200000400004081B2000004000040E5
+:103DF00081B200000400004081B2000004000040D5
+:103E000081B200000400004081B2000004000040C4
+:103E100081B200000400004081B2000004000040B4
+:103E200081B200000400004081B2000004000040A4
+:103E300081B200000400004081B200000400004094
+:103E400081B200000400004081B200000400004084
+:103E500081B200000400004081B200000400004074
+:103E600081B200000400004081B200000400004064
+:103E700081B200000400004081B200000400004054
+:103E800081B200000400004081B200000400004044
+:103E900081B200000400004081B200000400004034
+:103EA00081B200000400004081B200000400004024
+:103EB00081B200000400004081B200000400004014
+:103EC00081B200000400004081B200000400004004
+:103ED00081B200000400004081B2000004000040F4
+:103EE00081B200000400004081B2000004000040E4
+:103EF00081B200000400004081B2000004000040D4
+:103F000081B200000400004081B2000004000040C3
+:103F100081B200000400004081B2000004000040B3
+:103F200081B200000400004081B2000004000040A3
+:103F300081B200000400004081B200000400004093
+:103F400081B200000400004081B200000400004083
+:103F500081B200000400004081B200000400004073
+:103F600081B200000400004081B200000400004063
+:103F700081B200000400004081B200000400004053
+:103F800081B200000400004081B200000400004043
+:103F900081B200000400004081B200000400004033
+:103FA00081B200000400004081B200000400004023
+:103FB00081B200000400004081B200000400004013
+:103FC00081B200000400004081B200000400004003
+:103FD00081B200000400004081B2000004000040F3
+:103FE00081B200000400004081B2000004000040E3
+:103FF00081B200000400004081B2000004000040D3
+:1040000081B200000400004081B2000004000040C2
+:1040100081B200000400004081B2000004000040B2
+:1040200081B200000400004081B2000004000040A2
+:1040300081B200000400004081B200000400004092
+:1040400081B200000400004081B200000400004082
+:1040500081B200000400004081B200000400004072
+:1040600081B200000400004081B200000400004062
+:1040700081B200000400004081B200000400004052
+:1040800081B200000400004081B200000400004042
+:1040900081B200000400004081B200000400004032
+:1040A00081B200000400004081B200000400004022
+:1040B00081B200000400004081B200000400004012
+:1040C00081B200000400004081B200000400004002
+:1040D00081B200000400004081B2000004000040F2
+:1040E00081B200000400004081B2000004000040E2
+:1040F00081B200000400004081B2000004000040D2
+:1041000081B200000400004081B2000004000040C1
+:1041100081B200000400004081B2000004000040B1
+:1041200081B200000400004081B2000004000040A1
+:1041300081B200000400004081B200000400004091
+:1041400081B200000400004081B200000400004081
+:1041500081B200000400004081B200000400004071
+:1041600081B200000400004081B200000400004061
+:1041700081B200000400004081B200000400004051
+:1041800081B200000400004081B200000400004041
+:1041900081B200000400004081B200000400004031
+:1041A00081B200000400004081B200000400004021
+:1041B00081B200000400004081B200000400004011
+:1041C00081B200000400004081B200000400004001
+:1041D00081B200000400004081B2000004000040F1
+:1041E00081B200000400004081B2000004000040E1
+:1041F00081B200000400004081B2000004000040D1
+:1042000081B200000400004081B2000004000040C0
+:1042100081B200000400004081B2000004000040B0
+:1042200081B200000400004081B2000004000040A0
+:1042300081B200000400004081B200000400004090
+:1042400081B200000400004081B200000400004080
+:1042500081B200000400004081B200000400004070
+:1042600081B200000400004081B200000400004060
+:1042700081B200000400004081B200000400004050
+:1042800081B200000400004081B200000400004040
+:1042900081B200000400004081B200000400004030
+:1042A00081B200000400004081B200000400004020
+:1042B00081B200000400004081B200000400004010
+:1042C00081B200000400004081B200000400004000
+:1042D00081B200000400004081B2000004000040F0
+:1042E00081B200000400004081B2000004000040E0
+:1042F00081B200000400004081B2000004000040D0
+:1043000081B200000400004081B2000004000040BF
+:1043100081B200000400004081B2000004000040AF
+:1043200081B200000400004081B20000040000409F
+:1043300081B200000400004081B20000040000408F
+:1043400081B200000400004081B20000040000407F
+:1043500081B200000400004081B20000040000406F
+:1043600081B200000400004081B20000040000405F
+:1043700081B200000400004081B20000040000404F
+:1043800081B200000400004081B20000040000403F
+:1043900081B200000400004081B20000040000402F
+:1043A00081B200000400004081B20000040000401F
+:1043B00081B200000400004081B20000040000400F
+:1043C00081B200000400004081B2000004000040FF
+:1043D00081B200000400004081B2000004000040EF
+:1043E00081B200000400004081B2000004000040DF
+:1043F00081B200000400004081B2000004000040CF
+:1044000081B200000400004081B2000004000040BE
+:1044100081B200000400004081B2000004000040AE
+:1044200081B200000400004081B20000040000409E
+:1044300081B200000400004081B20000040000408E
+:1044400081B200000400004081B20000040000407E
+:1044500081B200000400004081B20000040000406E
+:1044600081B200000400004081B20000040000405E
+:1044700081B200000400004081B20000040000404E
+:1044800081B200000400004081B20000040000403E
+:1044900081B200000400004081B20000040000402E
+:1044A00081B200000400004081B20000040000401E
+:1044B00081B200000400004081B20000040000400E
+:1044C00081B200000400004081B2000004000040FE
+:1044D00081B200000400004081B2000004000040EE
+:1044E00081B200000400004081B2000004000040DE
+:1044F00081B200000400004081B2000004000040CE
+:1045000081B200000400004081B2000004000040BD
+:1045100081B200000400004081B2000004000040AD
+:1045200081B200000400004081B20000040000409D
+:1045300081B200000400004081B20000040000408D
+:1045400081B200000400004081B20000040000407D
+:1045500081B200000400004081B20000040000406D
+:1045600081B200000400004081B20000040000405D
+:1045700081B200000400004081B20000040000404D
+:1045800081B200000400004081B20000040000403D
+:1045900081B200000400004081B20000040000402D
+:1045A00081B200000400004081B20000040000401D
+:1045B00081B200000400004081B20000040000400D
+:1045C00081B200000400004081B2000004000040FD
+:1045D00081B200000400004081B2000004000040ED
+:1045E00081B200000400004081B2000004000040DD
+:1045F00081B200000400004081B2000004000040CD
+:1046000081B200000400004081B2000004000040BC
+:1046100081B200000400004081B2000004000040AC
+:1046200081B200000400004081B20000040000409C
+:1046300081B200000400004081B20000040000408C
+:1046400081B200000400004081B20000040000407C
+:1046500081B200000400004081B20000040000406C
+:1046600081B200000400004081B20000040000405C
+:1046700081B200000400004081B20000040000404C
+:1046800081B200000400004081B20000040000403C
+:1046900081B200000400004081B20000040000402C
+:1046A00081B200000400004081B20000040000401C
+:1046B00081B200000400004081B20000040000400C
+:1046C00081B200000400004081B2000004000040FC
+:1046D00081B200000400004081B2000004000040EC
+:1046E00081B200000400004081B2000004000040DC
+:1046F00081B200000400004081B2000004000040CC
+:1047000081B200000400004081B2000004000040BB
+:1047100081B200000400004081B2000004000040AB
+:1047200081B200000400004081B20000040000409B
+:1047300081B200000400004081B20000040000408B
+:1047400081B200000400004081B20000040000407B
+:1047500081B200000400004081B20000040000406B
+:1047600081B200000400004081B20000040000405B
+:1047700081B200000400004081B20000040000404B
+:1047800081B200000400004081B20000040000403B
+:1047900081B200000400004081B20000040000402B
+:1047A00081B200000400004081B20000040000401B
+:1047B00081B200000400004081B20000040000400B
+:1047C00081B200000400004081B2000004000040FB
+:1047D00081B200000400004081B2000004000040EB
+:1047E00081B200000400004081B2000004000040DB
+:1047F00081B200000400004081B2000004000040CB
+:1048000081B200000400004081B2000004000040BA
+:1048100081B200000400004081B2000004000040AA
+:1048200081B200000400004081B20000040000409A
+:1048300081B200000400004081B20000040000408A
+:1048400081B200000400004081B20000040000407A
+:1048500081B200000400004081B20000040000406A
+:1048600081B200000400004081B20000040000405A
+:1048700081B200000400004081B20000040000404A
+:1048800081B200000400004081B20000040000403A
+:1048900081B200000400004081B20000040000402A
+:1048A00081B200000400004081B20000040000401A
+:1048B00081B200000400004081B20000040000400A
+:1048C00081B200000400004081B2000004000040FA
+:1048D00081B200000400004081B2000004000040EA
+:1048E00081B200000400004081B2000004000040DA
+:1048F00081B200000400004081B2000004000040CA
+:1049000081B200000400004081B2000004000040B9
+:1049100081B200000400004081B2000004000040A9
+:1049200081B200000400004081B200000400004099
+:1049300081B200000400004081B200000400004089
+:1049400081B200000400004081B200000400004079
+:1049500081B200000400004081B200000400004069
+:1049600081B200000400004081B200000400004059
+:1049700081B200000400004081B200000400004049
+:1049800081B200000400004081B200000400004039
+:1049900081B200000400004081B200000400004029
+:1049A00081B200000400004081B200000400004019
+:1049B00081B200000400004081B200000400004009
+:1049C00081B200000400004081B2000004000040F9
+:1049D00081B200000400004081B2000004000040E9
+:1049E00081B200000400004081B2000004000040D9
+:1049F00081B200000400004081B2000004000040C9
+:104A000081B200000400004081B2000004000040B8
+:104A100081B200000400004081B2000004000040A8
+:104A200081B200000400004081B200000400004098
+:104A300081B200000400004081B200000400004088
+:104A400081B200000400004081B200000400004078
+:104A500081B200000400004081B200000400004068
+:104A600081B200000400004081B200000400004058
+:104A700081B200000400004081B200000400004048
+:104A800081B200000400004081B200000400004038
+:104A900081B200000400004081B200000400004028
+:104AA00081B200000400004081B200000400004018
+:104AB00081B200000400004081B200000400004008
+:104AC00081B200000400004081B2000004000040F8
+:104AD00081B200000400004081B2000004000040E8
+:104AE00081B200000400004081B2000004000040D8
+:104AF00081B200000400004081B2000004000040C8
+:104B000081B200000400004081B2000004000040B7
+:104B100081B200000400004081B2000004000040A7
+:104B200081B200000400004081B200000400004097
+:104B300081B200000400004081B200000400004087
+:104B400081B200000400004081B200000400004077
+:104B500081B200000400004081B200000400004067
+:104B600081B200000400004081B200000400004057
+:104B700081B200000400004081B200000400004047
+:104B800081B200000400004081B200000400004037
+:104B900081B200000400004081B200000400004027
+:104BA00081B200000400004081B200000400004017
+:104BB00081B200000400004081B200000400004007
+:104BC00081B200000400004081B2000004000040F7
+:104BD00081B200000400004081B2000004000040E7
+:104BE00081B200000400004081B2000004000040D7
+:104BF00081B200000400004081B2000004000040C7
+:104C000081B200000400004081B2000004000040B6
+:104C100081B200000400004081B2000004000040A6
+:104C200081B200000400004081B200000400004096
+:104C300081B200000400004081B200000400004086
+:104C400081B200000400004081B200000400004076
+:104C500081B200000400004081B200000400004066
+:104C600081B200000400004081B200000400004056
+:104C700081B200000400004081B200000400004046
+:104C800081B200000400004081B200000400004036
+:104C900081B200000400004081B200000400004026
+:104CA00081B200000400004081B200000400004016
+:104CB00081B200000400004081B200000400004006
+:104CC00081B200000400004081B2000004000040F6
+:104CD00081B200000400004081B2000004000040E6
+:104CE00081B200000400004081B2000004000040D6
+:104CF00081B200000400004081B2000004000040C6
+:104D000081B200000400004081B2000004000040B5
+:104D100081B200000400004081B2000004000040A5
+:104D200081B200000400004081B200000400004095
+:104D300081B200000400004081B200000400004085
+:104D400081B200000400004081B200000400004075
+:104D500081B200000400004081B200000400004065
+:104D600081B200000400004081B200000400004055
+:104D700081B200000400004081B200000400004045
+:104D800081B200000400004081B200000400004035
+:104D900081B200000400004081B200000400004025
+:104DA00081B200000400004081B200000400004015
+:104DB00081B200000400004081B200000400004005
+:104DC00081B200000400004081B2000004000040F5
+:104DD00081B200000400004081B2000004000040E5
+:104DE00081B200000400004081B2000004000040D5
+:104DF00081B200000400004081B2000004000040C5
+:104E000081B200000400004081B2000004000040B4
+:104E100081B200000400004081B2000004000040A4
+:104E200081B200000400004081B200000400004094
+:104E300081B200000400004081B200000400004084
+:104E400081B200000400004081B200000400004074
+:104E500081B200000400004081B200000400004064
+:104E600081B200000400004081B200000400004054
+:104E700081B200000400004081B200000400004044
+:104E800081B200000400004081B200000400004034
+:104E900081B200000400004081B200000400004024
+:104EA00081B200000400004081B200000400004014
+:104EB00081B200000400004081B200000400004004
+:104EC00081B200000400004081B2000004000040F4
+:104ED00081B200000400004081B2000004000040E4
+:104EE00081B200000400004081B2000004000040D4
+:104EF00081B200000400004081B2000004000040C4
+:104F000081B200000400004081B2000004000040B3
+:104F100081B200000400004081B2000004000040A3
+:104F200081B200000400004081B200000400004093
+:104F300081B200000400004081B200000400004083
+:104F400081B200000400004081B200000400004073
+:104F500081B200000400004081B200000400004063
+:104F600081B200000400004081B200000400004053
+:104F700081B200000400004081B200000400004043
+:104F800081B200000400004081B200000400004033
+:104F900081B200000400004081B200000400004023
+:104FA00081B200000400004081B200000400004013
+:104FB00081B200000400004081B200000400004003
+:104FC00081B200000400004081B2000004000040F3
+:104FD00081B200000400004081B2000004000040E3
+:104FE00081B200000400004081B2000004000040D3
+:104FF00081B200000400004081B2000004000040C3
+:1050000081B200000400004081B2000004000040B2
+:1050100081B200000400004081B2000004000040A2
+:1050200081B200000400004081B200000400004092
+:1050300081B200000400004081B200000400004082
+:1050400081B200000400004081B200000400004072
+:1050500081B200000400004081B200000400004062
+:1050600081B200000400004081B200000400004052
+:1050700081B200000400004081B200000400004042
+:1050800081B200000400004081B200000400004032
+:1050900081B200000400004081B200000400004022
+:1050A00081B200000400004081B200000400004012
+:1050B00081B200000400004081B200000400004002
+:1050C00081B200000400004081B2000004000040F2
+:1050D00081B200000400004081B2000004000040E2
+:1050E00081B200000400004081B2000004000040D2
+:1050F00081B200000400004081B2000004000040C2
+:1051000081B200000400004081B2000004000040B1
+:1051100081B200000400004081B2000004000040A1
+:1051200081B200000400004081B200000400004091
+:1051300081B200000400004081B200000400004081
+:1051400081B200000400004081B200000400004071
+:1051500081B200000400004081B200000400004061
+:1051600081B200000400004081B200000400004051
+:1051700081B200000400004081B200000400004041
+:1051800081B200000400004081B200000400004031
+:1051900081B200000400004081B200000400004021
+:1051A00081B200000400004081B200000400004011
+:1051B00081B200000400004081B200000400004001
+:1051C00081B200000400004081B2000004000040F1
+:1051D00081B200000400004081B2000004000040E1
+:1051E00081B200000400004081B2000004000040D1
+:1051F00081B200000400004081B2000004000040C1
+:1052000081B200000400004081B2000004000040B0
+:1052100081B200000400004081B2000004000040A0
+:1052200081B200000400004081B200000400004090
+:1052300081B200000400004081B200000400004080
+:1052400081B200000400004081B200000400004070
+:1052500081B200000400004081B200000400004060
+:1052600081B200000400004081B200000400004050
+:1052700081B200000400004081B200000400004040
+:1052800081B200000400004081B200000400004030
+:1052900081B200000400004081B200000400004020
+:1052A00081B200000400004081B200000400004010
+:1052B00081B200000400004081B200000400004000
+:1052C00081B200000400004081B2000004000040F0
+:1052D00081B200000400004081B2000004000040E0
+:1052E00081B200000400004081B2000004000040D0
+:1052F00081B200000400004081B2000004000040C0
+:1053000081B200000400004081B2000004000040AF
+:1053100081B200000400004081B20000040000409F
+:1053200081B200000400004081B20000040000408F
+:1053300081B200000400004081B20000040000407F
+:1053400081B200000400004081B20000040000406F
+:1053500081B200000400004081B20000040000405F
+:1053600081B200000400004081B20000040000404F
+:1053700081B200000400004081B20000040000403F
+:1053800081B200000400004081B20000040000402F
+:1053900081B200000400004081B20000040000401F
+:1053A00081B200000400004081B20000040000400F
+:1053B00081B200000400004081B2000004000040FF
+:1053C00081B200000400004081B2000004000040EF
+:1053D00081B200000400004081B2000004000040DF
+:1053E00081B200000400004081B2000004000040CF
+:1053F00081B200000400004081B2000004000040BF
+:1054000081B200000400004081B2000004000040AE
+:1054100081B200000400004081B20000040000409E
+:1054200081B200000400004081B20000040000408E
+:1054300081B200000400004081B20000040000407E
+:1054400081B200000400004081B20000040000406E
+:1054500081B200000400004081B20000040000405E
+:1054600081B200000400004081B20000040000404E
+:1054700081B200000400004081B20000040000403E
+:1054800081B200000400004081B20000040000402E
+:1054900081B200000400004081B20000040000401E
+:1054A00081B200000400004081B20000040000400E
+:1054B00081B200000400004081B2000004000040FE
+:1054C00081B200000400004081B2000004000040EE
+:1054D00081B200000400004081B2000004000040DE
+:1054E00081B200000400004081B2000004000040CE
+:1054F00081B200000400004081B2000004000040BE
+:1055000081B200000400004081B2000004000040AD
+:1055100081B200000400004081B20000040000409D
+:1055200081B200000400004081B20000040000408D
+:1055300081B200000400004081B20000040000407D
+:1055400081B200000400004081B20000040000406D
+:1055500081B200000400004081B20000040000405D
+:1055600081B200000400004081B20000040000404D
+:1055700081B200000400004081B20000040000403D
+:1055800081B200000400004081B20000040000402D
+:1055900081B200000400004081B20000040000401D
+:1055A00081B200000400004081B20000040000400D
+:1055B00081B200000400004081B2000004000040FD
+:1055C00081B200000400004081B2000004000040ED
+:1055D00081B200000400004081B2000004000040DD
+:1055E00081B200000400004081B2000004000040CD
+:1055F00081B200000400004081B2000004000040BD
+:1056000081B200000400004081B2000004000040AC
+:1056100081B200000400004081B20000040000409C
+:1056200081B200000400004081B20000040000408C
+:1056300081B200000400004081B20000040000407C
+:1056400081B200000400004081B20000040000406C
+:1056500081B200000400004081B20000040000405C
+:1056600081B200000400004081B20000040000404C
+:1056700081B200000400004081B20000040000403C
+:1056800081B200000400004081B20000040000402C
+:1056900081B200000400004081B20000040000401C
+:1056A00081B200000400004081B20000040000400C
+:1056B00081B200000400004081B2000004000040FC
+:1056C00081B200000400004081B2000004000040EC
+:1056D00081B200000400004081B2000004000040DC
+:1056E00081B200000400004081B2000004000040CC
+:1056F00081B200000400004081B2000004000040BC
+:1057000081B200000400004081B2000004000040AB
+:1057100081B200000400004081B20000040000409B
+:1057200081B200000400004081B20000040000408B
+:1057300081B200000400004081B20000040000407B
+:1057400081B200000400004081B20000040000406B
+:1057500081B200000400004081B20000040000405B
+:1057600081B200000400004081B20000040000404B
+:1057700081B200000400004081B20000040000403B
+:1057800081B200000400004081B20000040000402B
+:1057900081B200000400004081B20000040000401B
+:1057A00081B200000400004081B20000040000400B
+:1057B00081B200000400004081B2000004000040FB
+:1057C00081B200000400004081B2000004000040EB
+:1057D00081B200000400004081B2000004000040DB
+:1057E00081B200000400004081B2000004000040CB
+:1057F00081B200000400004081B2000004000040BB
+:1058000081B200000400004081B2000004000040AA
+:1058100081B200000400004081B20000040000409A
+:1058200081B200000400004081B20000040000408A
+:1058300081B200000400004081B20000040000407A
+:1058400081B200000400004081B20000040000406A
+:1058500081B200000400004081B20000040000405A
+:1058600081B200000400004081B20000040000404A
+:1058700081B200000400004081B20000040000403A
+:1058800081B200000400004081B20000040000402A
+:1058900081B200000400004081B20000040000401A
+:1058A00081B200000400004081B20000040000400A
+:1058B00081B200000400004081B2000004000040FA
+:1058C00081B200000400004081B2000004000040EA
+:1058D00081B200000400004081B2000004000040DA
+:1058E00081B200000400004081B2000004000040CA
+:1058F00081B200000400004081B2000004000040BA
+:1059000081B200000400004081B2000004000040A9
+:1059100081B200000400004081B200000400004099
+:1059200081B200000400004081B200000400004089
+:1059300081B200000400004081B200000400004079
+:1059400081B200000400004081B200000400004069
+:1059500081B200000400004081B200000400004059
+:1059600081B200000400004081B200000400004049
+:1059700081B200000400004081B200000400004039
+:1059800081B200000400004081B200000400004029
+:1059900081B200000400004081B200000400004019
+:1059A00081B200000400004081B200000400004009
+:1059B00081B200000400004081B2000004000040F9
+:1059C00081B200000400004081B2000004000040E9
+:1059D00081B200000400004081B2000004000040D9
+:1059E00081B200000400004081B2000004000040C9
+:1059F00081B200000400004081B2000004000040B9
+:105A000081B200000400004081B2000004000040A8
+:105A100081B200000400004081B200000400004098
+:105A200081B200000400004081B200000400004088
+:105A300081B200000400004081B200000400004078
+:105A400081B200000400004081B200000400004068
+:105A500081B200000400004081B200000400004058
+:105A600081B200000400004081B200000400004048
+:105A700081B200000400004081B200000400004038
+:105A800081B200000400004081B200000400004028
+:105A900081B200000400004081B200000400004018
+:105AA00081B200000400004081B200000400004008
+:105AB00081B200000400004081B2000004000040F8
+:105AC00081B200000400004081B2000004000040E8
+:105AD00081B200000400004081B2000004000040D8
+:105AE00081B200000400004081B2000004000040C8
+:105AF00081B200000400004081B2000004000040B8
+:105B000081B200000400004081B2000004000040A7
+:105B100081B200000400004081B200000400004097
+:105B200081B200000400004081B200000400004087
+:105B300081B200000400004081B200000400004077
+:105B400081B200000400004081B200000400004067
+:105B500081B200000400004081B200000400004057
+:105B600081B200000400004081B200000400004047
+:105B700081B200000400004081B200000400004037
+:105B800081B200000400004081B200000400004027
+:105B900081B200000400004081B200000400004017
+:105BA00081B200000400004081B200000400004007
+:105BB00081B200000400004081B2000004000040F7
+:105BC00081B200000400004081B2000004000040E7
+:105BD00081B200000400004081B2000004000040D7
+:105BE00081B200000400004081B2000004000040C7
+:105BF00081B200000400004081B2000004000040B7
+:105C000081B200000400004081B2000004000040A6
+:105C100081B200000400004081B200000400004096
+:105C200081B200000400004081B200000400004086
+:105C300081B200000400004081B200000400004076
+:105C400081B200000400004081B200000400004066
+:105C500081B200000400004081B200000400004056
+:105C600081B200000400004081B200000400004046
+:105C700081B200000400004081B200000400004036
+:105C800081B200000400004081B200000400004026
+:105C900081B200000400004081B200000400004016
+:105CA00081B200000400004081B200000400004006
+:105CB00081B200000400004081B2000004000040F6
+:105CC00081B200000400004081B2000004000040E6
+:105CD00081B200000400004081B2000004000040D6
+:105CE00081B200000400004081B2000004000040C6
+:105CF00081B200000400004081B2000004000040B6
+:105D000081B200000400004081B2000004000040A5
+:105D100081B200000400004081B200000400004095
+:105D200081B200000400004081B200000400004085
+:105D300081B200000400004081B200000400004075
+:105D400081B200000400004081B200000400004065
+:105D500081B200000400004081B200000400004055
+:105D600081B200000400004081B200000400004045
+:105D700081B200000400004081B200000400004035
+:105D800081B200000400004081B200000400004025
+:105D900081B200000400004081B200000400004015
+:105DA00081B200000400004081B200000400004005
+:105DB00081B200000400004081B2000004000040F5
+:105DC00081B200000400004081B2000004000040E5
+:105DD00081B200000400004081B2000004000040D5
+:105DE00081B200000400004081B2000004000040C5
+:105DF00081B200000400004081B2000004000040B5
+:105E000081B200000400004081B2000004000040A4
+:105E100081B200000400004081B200000400004094
+:105E200081B200000400004081B200000400004084
+:105E300081B200000400004081B200000400004074
+:105E400081B200000400004081B200000400004064
+:105E500081B200000400004081B200000400004054
+:105E600081B200000400004081B200000400004044
+:105E700081B200000400004081B200000400004034
+:105E800081B200000400004081B200000400004024
+:105E900081B200000400004081B200000400004014
+:105EA00081B200000400004081B200000400004004
+:105EB00081B200000400004081B2000004000040F4
+:105EC00081B200000400004081B2000004000040E4
+:105ED00081B200000400004081B2000004000040D4
+:105EE00081B200000400004081B2000004000040C4
+:105EF00081B200000400004081B2000004000040B4
+:105F000081B200000400004081B2000004000040A3
+:105F100081B200000400004081B200000400004093
+:105F200081B200000400004081B200000400004083
+:105F300081B200000400004081B200000400004073
+:105F400081B200000400004081B200000400004063
+:105F500081B200000400004081B200000400004053
+:105F600081B200000400004081B200000400004043
+:105F700081B200000400004081B200000400004033
+:105F800081B200000400004081B200000400004023
+:105F900081B200000400004081B200000400004013
+:105FA00081B200000400004081B200000400004003
+:105FB00081B200000400004081B2000004000040F3
+:105FC00081B200000400004081B2000004000040E3
+:105FD00081B200000400004081B2000004000040D3
+:105FE00081B200000400004081B2000004000040C3
+:105FF00081B200000400004081B2000004000040B3
+:1060000081B200000400004081B2000004000040A2
+:1060100081B200000400004081B200000400004092
+:1060200081B200000400004081B200000400004082
+:1060300081B200000400004081B200000400004072
+:1060400081B200000400004081B200000400004062
+:1060500081B200000400004081B200000400004052
+:1060600081B200000400004081B200000400004042
+:1060700081B200000400004081B200000400004032
+:1060800081B200000400004081B200000400004022
+:1060900081B200000400004081B200000400004012
+:1060A00081B200000400004081B200000400004002
+:1060B00081B200000400004081B2000004000040F2
+:1060C00081B200000400004081B2000004000040E2
+:1060D00081B200000400004081B2000004000040D2
+:1060E00081B200000400004081B2000004000040C2
+:1060F00081B200000400004081B2000004000040B2
+:1061000081B200000400004081B2000004000040A1
+:1061100081B200000400004081B200000400004091
+:1061200081B200000400004081B200000400004081
+:1061300081B200000400004081B200000400004071
+:1061400081B200000400004081B200000400004061
+:1061500081B200000400004081B200000400004051
+:1061600081B200000400004081B200000400004041
+:1061700081B200000400004081B200000400004031
+:1061800081B200000400004081B200000400004021
+:1061900081B200000400004081B200000400004011
+:1061A00081B200000400004081B200000400004001
+:1061B00081B200000400004081B2000004000040F1
+:1061C00081B200000400004081B2000004000040E1
+:1061D00081B200000400004081B2000004000040D1
+:1061E00081B200000400004081B2000004000040C1
+:1061F00081B200000400004081B2000004000040B1
+:1062000081B200000400004081B2000004000040A0
+:1062100081B200000400004081B200000400004090
+:1062200081B200000400004081B200000400004080
+:1062300081B200000400004081B200000400004070
+:1062400081B200000400004081B200000400004060
+:1062500081B200000400004081B200000400004050
+:1062600081B200000400004081B200000400004040
+:1062700081B200000400004081B200000400004030
+:1062800081B200000400004081B200000400004020
+:1062900081B200000400004081B200000400004010
+:1062A00081B200000400004081B200000400004000
+:1062B00081B200000400004081B2000004000040F0
+:1062C00081B200000400004081B2000004000040E0
+:1062D00081B200000400004081B2000004000040D0
+:1062E00081B200000400004081B2000004000040C0
+:1062F00081B200000400004081B2000004000040B0
+:1063000081B200000400004081B20000040000409F
+:1063100081B200000400004081B20000040000408F
+:1063200081B200000400004081B20000040000407F
+:1063300081B200000400004081B20000040000406F
+:1063400081B200000400004081B20000040000405F
+:1063500081B200000400004081B20000040000404F
+:1063600081B200000400004081B20000040000403F
+:1063700081B200000400004081B20000040000402F
+:1063800081B200000400004081B20000040000401F
+:1063900081B200000400004081B20000040000400F
+:1063A00081B200000400004081B2000004000040FF
+:1063B00081B200000400004081B2000004000040EF
+:1063C00081B200000400004081B2000004000040DF
+:1063D00081B200000400004081B2000004000040CF
+:1063E00081B200000400004081B2000004000040BF
+:1063F00081B200000400004081B2000004000040AF
+:1064000081B200000400004081B20000040000409E
+:1064100081B200000400004081B20000040000408E
+:1064200081B200000400004081B20000040000407E
+:1064300081B200000400004081B20000040000406E
+:1064400081B200000400004081B20000040000405E
+:1064500081B200000400004081B20000040000404E
+:1064600081B200000400004081B20000040000403E
+:1064700081B200000400004081B20000040000402E
+:1064800081B200000400004081B20000040000401E
+:1064900081B200000400004081B20000040000400E
+:1064A00081B200000400004081B2000004000040FE
+:1064B00081B200000400004081B2000004000040EE
+:1064C00081B200000400004081B2000004000040DE
+:1064D00081B200000400004081B2000004000040CE
+:1064E00081B200000400004081B2000004000040BE
+:1064F00081B200000400004081B2000004000040AE
+:1065000081B200000400004081B20000040000409D
+:1065100081B200000400004081B20000040000408D
+:1065200081B200000400004081B20000040000407D
+:1065300081B200000400004081B20000040000406D
+:1065400081B200000400004081B20000040000405D
+:1065500081B200000400004081B20000040000404D
+:1065600081B200000400004081B20000040000403D
+:1065700081B200000400004081B20000040000402D
+:1065800081B200000400004081B20000040000401D
+:1065900081B200000400004081B20000040000400D
+:1065A00081B200000400004081B2000004000040FD
+:1065B00081B200000400004081B2000004000040ED
+:1065C00081B200000400004081B2000004000040DD
+:1065D00081B200000400004081B2000004000040CD
+:1065E00081B200000400004081B2000004000040BD
+:1065F00081B200000400004081B2000004000040AD
+:1066000081B200000400004081B20000040000409C
+:1066100081B200000400004081B20000040000408C
+:1066200081B200000400004081B20000040000407C
+:1066300081B200000400004081B20000040000406C
+:1066400081B200000400004081B20000040000405C
+:1066500081B200000400004081B20000040000404C
+:1066600081B200000400004081B20000040000403C
+:1066700081B200000400004081B20000040000402C
+:1066800081B200000400004081B20000040000401C
+:1066900081B200000400004081B20000040000400C
+:1066A00081B200000400004081B2000004000040FC
+:1066B00081B200000400004081B2000004000040EC
+:1066C00081B200000400004081B2000004000040DC
+:1066D00081B200000400004081B2000004000040CC
+:1066E00081B200000400004081B2000004000040BC
+:1066F00081B200000400004081B2000004000040AC
+:1067000081B200000400004081B20000040000409B
+:1067100081B200000400004081B20000040000408B
+:1067200081B200000400004081B20000040000407B
+:1067300081B200000400004081B20000040000406B
+:1067400081B200000400004081B20000040000405B
+:1067500081B200000400004081B20000040000404B
+:1067600081B200000400004081B20000040000403B
+:1067700081B200000400004081B20000040000402B
+:1067800081B200000400004081B20000040000401B
+:1067900081B200000400004081B20000040000400B
+:1067A00081B200000400004081B2000004000040FB
+:1067B00081B200000400004081B2000004000040EB
+:1067C00081B200000400004081B2000004000040DB
+:1067D00081B200000400004081B2000004000040CB
+:1067E00081B200000400004081B2000004000040BB
+:1067F00081B200000400004081B2000004000040AB
+:1068000081B200000400004081B20000040000409A
+:1068100081B200000400004081B20000040000408A
+:1068200081B200000400004081B20000040000407A
+:1068300081B200000400004081B20000040000406A
+:1068400081B200000400004081B20000040000405A
+:1068500081B200000400004081B20000040000404A
+:1068600081B200000400004081B20000040000403A
+:1068700081B200000400004081B20000040000402A
+:1068800081B200000400004081B20000040000401A
+:1068900081B200000400004081B20000040000400A
+:1068A00081B200000400004081B2000004000040FA
+:1068B00081B200000400004081B2000004000040EA
+:1068C00081B200000400004081B2000004000040DA
+:1068D00081B200000400004081B2000004000040CA
+:1068E00081B200000400004081B2000004000040BA
+:1068F00081B200000400004081B2000004000040AA
+:1069000081B200000400004081B200000400004099
+:1069100081B200000400004081B200000400004089
+:1069200081B200000400004081B200000400004079
+:1069300081B200000400004081B200000400004069
+:1069400081B200000400004081B200000400004059
+:1069500081B200000400004081B200000400004049
+:1069600081B200000400004081B200000400004039
+:1069700081B200000400004081B200000400004029
+:1069800081B200000400004081B200000400004019
+:1069900081B200000400004081B200000400004009
+:1069A00081B200000400004081B2000004000040F9
+:1069B00081B200000400004081B2000004000040E9
+:1069C00081B200000400004081B2000004000040D9
+:1069D00081B200000400004081B2000004000040C9
+:1069E00081B200000400004081B2000004000040B9
+:1069F00081B200000400004081B2000004000040A9
+:106A000081B200000400004081B200000400004098
+:106A100081B200000400004081B200000400004088
+:106A200081B200000400004081B200000400004078
+:106A300081B200000400004081B200000400004068
+:106A400081B200000400004081B200000400004058
+:106A500081B200000400004081B200000400004048
+:106A600081B200000400004081B200000400004038
+:106A700081B200000400004081B200000400004028
+:106A800081B200000400004081B200000400004018
+:106A900081B200000400004081B200000400004008
+:106AA00081B200000400004081B2000004000040F8
+:106AB00081B200000400004081B2000004000040E8
+:106AC00081B200000400004081B2000004000040D8
+:106AD00081B200000400004081B2000004000040C8
+:106AE00081B200000400004081B2000004000040B8
+:106AF00081B200000400004081B2000004000040A8
+:106B000081B200000400004081B200000400004097
+:106B100081B200000400004081B200000400004087
+:106B200081B200000400004081B200000400004077
+:106B300081B200000400004081B200000400004067
+:106B400081B200000400004081B200000400004057
+:106B500081B200000400004081B200000400004047
+:106B600081B200000400004081B200000400004037
+:106B700081B200000400004081B200000400004027
+:106B800081B200000400004081B200000400004017
+:106B900081B200000400004081B200000400004007
+:106BA00081B200000400004081B2000004000040F7
+:106BB00081B200000400004081B2000004000040E7
+:106BC00081B200000400004081B2000004000040D7
+:106BD00081B200000400004081B2000004000040C7
+:106BE00081B200000400004081B2000004000040B7
+:106BF00081B200000400004081B2000004000040A7
+:106C000081B200000400004081B200000400004096
+:106C100081B200000400004081B200000400004086
+:106C200081B200000400004081B200000400004076
+:106C300081B200000400004081B200000400004066
+:106C400081B200000400004081B200000400004056
+:106C500081B200000400004081B200000400004046
+:106C600081B200000400004081B200000400004036
+:106C700081B200000400004081B200000400004026
+:106C800081B200000400004081B200000400004016
+:106C900081B200000400004081B200000400004006
+:106CA00081B200000400004081B2000004000040F6
+:106CB00081B200000400004081B2000004000040E6
+:106CC00081B200000400004081B2000004000040D6
+:106CD00081B200000400004081B2000004000040C6
+:106CE00081B200000400004081B2000004000040B6
+:106CF00081B200000400004081B2000004000040A6
+:106D000081B200000400004081B200000400004095
+:106D100081B200000400004081B200000400004085
+:106D200081B200000400004081B200000400004075
+:106D300081B200000400004081B200000400004065
+:106D400081B200000400004081B200000400004055
+:106D500081B200000400004081B200000400004045
+:106D600081B200000400004081B200000400004035
+:106D700081B200000400004081B200000400004025
+:106D800081B200000400004081B200000400004015
+:106D900081B200000400004081B200000400004005
+:106DA00081B200000400004081B2000004000040F5
+:106DB00081B200000400004081B2000004000040E5
+:106DC00081B200000400004081B2000004000040D5
+:106DD00081B200000400004081B2000004000040C5
+:106DE00081B200000400004081B2000004000040B5
+:106DF00081B200000400004081B2000004000040A5
+:106E000081B200000400004081B200000400004094
+:106E100081B200000400004081B200000400004084
+:106E200081B200000400004081B200000400004074
+:106E300081B200000400004081B200000400004064
+:106E400081B200000400004081B200000400004054
+:106E500081B200000400004081B200000400004044
+:106E600081B200000400004081B200000400004034
+:106E700081B200000400004081B200000400004024
+:106E800081B200000400004081B200000400004014
+:106E900081B200000400004081B200000400004004
+:106EA00081B200000400004081B2000004000040F4
+:106EB00081B200000400004081B2000004000040E4
+:106EC00081B200000400004081B2000004000040D4
+:106ED00081B200000400004081B2000004000040C4
+:106EE00081B200000400004081B2000004000040B4
+:106EF00081B200000400004081B2000004000040A4
+:106F000081B200000400004081B200000400004093
+:106F100081B200000400004081B200000400004083
+:106F200081B200000400004081B200000400004073
+:106F300081B200000400004081B200000400004063
+:106F400081B200000400004081B200000400004053
+:106F500081B200000400004081B200000400004043
+:106F600081B200000400004081B200000400004033
+:106F700081B200000400004081B200000400004023
+:106F800081B200000400004081B200000400004013
+:106F900081B200000400004081B200000400004003
+:106FA00081B200000400004081B2000004000040F3
+:106FB00081B200000400004081B2000004000040E3
+:106FC00081B200000400004081B2000004000040D3
+:106FD00081B200000400004081B2000004000040C3
+:106FE00081B200000400004081B2000004000040B3
+:106FF00081B200000400004081B2000004000040A3
+:1070000081B200000400004081B200000400004092
+:1070100081B200000400004081B200000400004082
+:1070200081B200000400004081B200000400004072
+:1070300081B200000400004081B200000400004062
+:1070400081B200000400004081B200000400004052
+:1070500081B200000400004081B200000400004042
+:1070600081B200000400004081B200000400004032
+:1070700081B200000400004081B200000400004022
+:1070800081B200000400004081B200000400004012
+:1070900081B200000400004081B200000400004002
+:1070A00081B200000400004081B2000004000040F2
+:1070B00081B200000400004081B2000004000040E2
+:1070C00081B200000400004081B2000004000040D2
+:1070D00081B200000400004081B2000004000040C2
+:1070E00081B200000400004081B2000004000040B2
+:1070F00081B200000400004081B2000004000040A2
+:1071000081B200000400004081B200000400004091
+:1071100081B200000400004081B200000400004081
+:1071200081B200000400004081B200000400004071
+:1071300081B200000400004081B200000400004061
+:1071400081B200000400004081B200000400004051
+:1071500081B200000400004081B200000400004041
+:1071600081B200000400004081B200000400004031
+:1071700081B200000400004081B200000400004021
+:1071800081B200000400004081B200000400004011
+:1071900081B200000400004081B200000400004001
+:1071A00081B200000400004081B2000004000040F1
+:1071B00081B200000400004081B2000004000040E1
+:1071C00081B200000400004081B2000004000040D1
+:1071D00081B200000400004081B2000004000040C1
+:1071E00081B200000400004081B2000004000040B1
+:1071F00081B200000400004081B2000004000040A1
+:1072000081B200000400004081B200000400004090
+:1072100081B200000400004081B200000400004080
+:1072200081B200000400004081B200000400004070
+:1072300081B200000400004081B200000400004060
+:1072400081B200000400004081B200000400004050
+:1072500081B200000400004081B200000400004040
+:1072600081B200000400004081B200000400004030
+:1072700081B200000400004081B200000400004020
+:1072800081B200000400004081B200000400004010
+:1072900081B200000400004081B200000400004000
+:1072A00081B200000400004081B2000004000040F0
+:1072B00081B200000400004081B2000004000040E0
+:1072C00081B200000400004081B2000004000040D0
+:1072D00081B200000400004081B2000004000040C0
+:1072E00081B200000400004081B2000004000040B0
+:1072F00081B200000400004081B2000004000040A0
+:1073000081B200000400004081B20000040000408F
+:1073100081B200000400004081B20000040000407F
+:1073200081B200000400004081B20000040000406F
+:1073300081B200000400004081B20000040000405F
+:1073400081B200000400004081B20000040000404F
+:1073500081B200000400004081B20000040000403F
+:1073600081B200000400004081B20000040000402F
+:1073700081B200000400004081B20000040000401F
+:1073800081B200000400004081B20000040000400F
+:1073900081B200000400004081B2000004000040FF
+:1073A00081B200000400004081B2000004000040EF
+:1073B00081B200000400004081B2000004000040DF
+:1073C00081B200000400004081B2000004000040CF
+:1073D00081B200000400004081B2000004000040BF
+:1073E00081B200000400004081B2000004000040AF
+:1073F00081B200000400004081B20000040000409F
+:1074000081B200000400004081B20000040000408E
+:1074100081B200000400004081B20000040000407E
+:1074200081B200000400004081B20000040000406E
+:1074300081B200000400004081B20000040000405E
+:1074400081B200000400004081B20000040000404E
+:1074500081B200000400004081B20000040000403E
+:1074600081B200000400004081B20000040000402E
+:1074700081B200000400004081B20000040000401E
+:1074800081B200000400004081B20000040000400E
+:1074900081B200000400004081B2000004000040FE
+:1074A00081B200000400004081B2000004000040EE
+:1074B00081B200000400004081B2000004000040DE
+:1074C00081B200000400004081B2000004000040CE
+:1074D00081B200000400004081B2000004000040BE
+:1074E00081B200000400004081B2000004000040AE
+:1074F00081B200000400004081B20000040000409E
+:1075000081B200000400004081B20000040000408D
+:1075100081B200000400004081B20000040000407D
+:1075200081B200000400004081B20000040000406D
+:1075300081B200000400004081B20000040000405D
+:1075400081B200000400004081B20000040000404D
+:1075500081B200000400004081B20000040000403D
+:1075600081B200000400004081B20000040000402D
+:1075700081B200000400004081B20000040000401D
+:1075800081B200000400004081B20000040000400D
+:1075900081B200000400004081B2000004000040FD
+:1075A00081B200000400004081B2000004000040ED
+:1075B00081B200000400004081B2000004000040DD
+:1075C00081B200000400004081B2000004000040CD
+:1075D00081B200000400004081B2000004000040BD
+:1075E00081B200000400004081B2000004000040AD
+:1075F00081B200000400004081B20000040000409D
+:1076000081B200000400004081B20000040000408C
+:1076100081B200000400004081B20000040000407C
+:1076200081B200000400004081B20000040000406C
+:1076300081B200000400004081B20000040000405C
+:1076400081B200000400004081B20000040000404C
+:1076500081B200000400004081B20000040000403C
+:1076600081B200000400004081B20000040000402C
+:1076700081B200000400004081B20000040000401C
+:1076800081B200000400004081B20000040000400C
+:1076900081B200000400004081B2000004000040FC
+:1076A00081B200000400004081B2000004000040EC
+:1076B00081B200000400004081B2000004000040DC
+:1076C00081B200000400004081B2000004000040CC
+:1076D00081B200000400004081B2000004000040BC
+:1076E00081B200000400004081B2000004000040AC
+:1076F00081B200000400004081B20000040000409C
+:1077000081B200000400004081B20000040000408B
+:1077100081B200000400004081B20000040000407B
+:1077200081B200000400004081B20000040000406B
+:1077300081B200000400004081B20000040000405B
+:1077400081B200000400004081B20000040000404B
+:1077500081B200000400004081B20000040000403B
+:1077600081B200000400004081B20000040000402B
+:1077700081B200000400004081B20000040000401B
+:1077800081B200000400004081B20000040000400B
+:1077900081B200000400004081B2000004000040FB
+:1077A00081B200000400004081B2000004000040EB
+:1077B00081B200000400004081B2000004000040DB
+:1077C00081B200000400004081B2000004000040CB
+:1077D00081B200000400004081B2000004000040BB
+:1077E00081B200000400004081B2000004000040AB
+:1077F00081B200000400004081B20000040000409B
+:1078000081B200000400004081B20000040000408A
+:1078100081B200000400004081B20000040000407A
+:1078200081B200000400004081B20000040000406A
+:1078300081B200000400004081B20000040000405A
+:1078400081B200000400004081B20000040000404A
+:1078500081B200000400004081B20000040000403A
+:1078600081B200000400004081B20000040000402A
+:1078700081B200000400004081B20000040000401A
+:1078800081B200000400004081B20000040000400A
+:1078900081B200000400004081B2000004000040FA
+:1078A00081B200000400004081B2000004000040EA
+:1078B00081B200000400004081B2000004000040DA
+:1078C00081B200000400004081B2000004000040CA
+:1078D00081B200000400004081B2000004000040BA
+:1078E00081B200000400004081B2000004000040AA
+:1078F00081B200000400004081B20000040000409A
+:1079000081B200000400004081B200000400004089
+:1079100081B200000400004081B200000400004079
+:1079200081B200000400004081B200000400004069
+:1079300081B200000400004081B200000400004059
+:1079400081B200000400004081B200000400004049
+:1079500081B200000400004081B200000400004039
+:1079600081B200000400004081B200000400004029
+:1079700081B200000400004081B200000400004019
+:1079800081B200000400004081B200000400004009
+:1079900081B200000400004081B2000004000040F9
+:1079A00081B200000400004081B2000004000040E9
+:1079B00081B200000400004081B2000004000040D9
+:1079C00081B200000400004081B2000004000040C9
+:1079D00081B200000400004081B2000004000040B9
+:1079E00081B200000400004081B2000004000040A9
+:1079F00081B200000400004081B200000400004099
+:107A000081B200000400004081B200000400004088
+:107A100081B200000400004081B200000400004078
+:107A200081B200000400004081B200000400004068
+:107A300081B200000400004081B200000400004058
+:107A400081B200000400004081B200000400004048
+:107A500081B200000400004081B200000400004038
+:107A600081B200000400004081B200000400004028
+:107A700081B200000400004081B200000400004018
+:107A800081B200000400004081B200000400004008
+:107A900081B200000400004081B2000004000040F8
+:107AA00081B200000400004081B2000004000040E8
+:107AB00081B200000400004081B2000004000040D8
+:107AC00081B200000400004081B2000004000040C8
+:107AD00081B200000400004081B2000004000040B8
+:107AE00081B200000400004081B2000004000040A8
+:107AF00081B200000400004081B200000400004098
+:107B000081B200000400004081B200000400004087
+:107B100081B200000400004081B200000400004077
+:107B200081B200000400004081B200000400004067
+:107B300081B200000400004081B200000400004057
+:107B400081B200000400004081B200000400004047
+:107B500081B200000400004081B200000400004037
+:107B600081B200000400004081B200000400004027
+:107B700081B200000400004081B200000400004017
+:107B800081B200000400004081B200000400004007
+:107B900081B200000400004081B2000004000040F7
+:107BA00081B200000400004081B2000004000040E7
+:107BB00081B200000400004081B2000004000040D7
+:107BC00081B200000400004081B2000004000040C7
+:107BD00081B200000400004081B2000004000040B7
+:107BE00081B200000400004081B2000004000040A7
+:107BF00081B200000400004081B200000400004097
+:107C000081B200000400004081B200000400004086
+:107C100081B200000400004081B200000400004076
+:107C200081B200000400004081B200000400004066
+:107C300081B200000400004081B200000400004056
+:107C400081B200000400004081B200000400004046
+:107C500081B200000400004081B200000400004036
+:107C600081B200000400004081B200000400004026
+:107C700081B200000400004081B200000400004016
+:107C800081B200000400004081B200000400004006
+:107C900081B200000400004081B2000004000040F6
+:107CA00081B200000400004081B2000004000040E6
+:107CB00081B200000400004081B2000004000040D6
+:107CC00081B200000400004081B2000004000040C6
+:107CD00081B200000400004081B2000004000040B6
+:107CE00081B200000400004081B2000004000040A6
+:107CF00081B200000400004081B200000400004096
+:107D000081B200000400004081B200000400004085
+:107D100081B200000400004081B200000400004075
+:107D200081B200000400004081B200000400004065
+:107D300081B200000400004081B200000400004055
+:107D400081B200000400004081B200000400004045
+:107D500081B200000400004081B200000400004035
+:107D600081B200000400004081B200000400004025
+:107D700081B200000400004081B200000400004015
+:107D800081B200000400004081B200000400004005
+:107D900081B200000400004081B2000004000040F5
+:107DA00081B200000400004081B2000004000040E5
+:107DB00081B200000400004081B2000004000040D5
+:107DC00081B200000400004081B2000004000040C5
+:107DD00081B200000400004081B2000004000040B5
+:107DE00081B200000400004081B2000004000040A5
+:107DF00081B200000400004081B200000400004095
+:107E000081B200000400004081B200000400004084
+:107E100081B200000400004081B200000400004074
+:107E200081B200000400004081B200000400004064
+:107E300081B200000400004081B200000400004054
+:107E400081B200000400004081B200000400004044
+:107E500081B200000400004081B200000400004034
+:107E600081B200000400004081B200000400004024
+:107E700081B200000400004081B200000400004014
+:107E800081B200000400004081B200000400004004
+:107E900081B200000400004081B2000004000040F4
+:107EA00081B200000400004081B2000004000040E4
+:107EB00081B200000400004081B2000004000040D4
+:107EC00081B200000400004081B2000004000040C4
+:107ED00081B200000400004081B2000004000040B4
+:107EE00081B200000400004081B2000004000040A4
+:107EF00081B200000400004081B200000400004094
+:107F000081B200000400004081B200000400004083
+:107F100081B200000400004081B200000400004073
+:107F200081B200000400004081B200000400004063
+:107F300081B200000400004081B200000400004053
+:107F400081B200000400004081B200000400004043
+:107F500081B200000400004081B200000400004033
+:107F600081B200000400004081B200000400004023
+:107F700081B200000400004081B200000400004013
+:107F800081B200000400004081B200000400004003
+:107F900081B200000400004081B2000004000040F3
+:107FA00081B200000400004081B2000004000040E3
+:107FB00081B200000400004081B2000004000040D3
+:107FC00081B200000400004081B20000F70F00BC45
+:107FD00080B200000380004081B2000003800040B6
+:107FE00081B200000380004081B2000003800040A5
+:107FF00081B200000380004081B200000380004095
+:1080000081B200000380004081B200000380004084
+:1080100081B200003180004081B200003480004015
+:1080200081B200003580004081B2000004000040B1
+:1080300081B200001B80818080320000EC89A24068
+:10804000916F00000000004C90B301005C952EA2DF
+:1080500080B00100FF000080F489010090952AC8DB
+:10806000E5B10100000000A1F0B1010000000040F6
+:10807000F0B10100000000A4F0B10100000000D048
+:10808000F0B10100000000D1F0B10100000000D209
+:10809000F0B101000000004CF0B10100000000D47C
+:1080A000F0B10100000000D3F0B10100000000EECB
+:1080B000F0B101000000004EF0B1010000000040EE
+:1080C00044B1010018801181983000000000514037
+:1080D00081B201001A8011829830000000005240E5
+:1080E00081B20100EC890048FD930000B603004016
+:1080F000A19901002380A242FD7F00002080008022
+:1081000080320000228011818230000022805140A4
+:1081100081B2000022801182823000002280524011
+:1081200081B200002C800048FD9300002780008071
+:10813000803200002680A253077C000000005153CB
+:10814000079001002A800052079000002980A25267
+:10815000077C00000000525207900100000000530D
+:108160000790010000000048FD9301000000004559
+:10817000F39301005C952EA252B30100FF00008032
+:10818000F48901000000004CE4B10100000000A9E6
+:1081900045B101003080004C80B200000000454035
+:1081A00081B201000000554081B201001B840540EE
+:1081B00049B100001B84054049B1000000000540A2
+:1081C00049B10100E1800040813201000000004B14
+:1081D000DEB20100770000404B9901000000004032
+:1081E000FD93010000000048FD83010002000040F3
+:1081F0009B9B0100000000A59CB30100F699004084
+:108200008132010058952044E0B1010000C000A671
+:1082100036B10100D014004047990100050000402C
+:10822000F599010000380040F59901000006004072
+:10823000F599010000000040F59901000518004083
+:10824000F599010002090040F59901000400004081
+:10825000F599010050030040813201007B0300408A
+:1082600081320100E083004081320100108400402F
+:108270008132010008840040813201006095204075
+:10828000E1B1010070952040E1B10100000000491A
+:10829000DD9101000000004091B3010000000040AA
+:1082A00085B301005C952040E1B101001A820040D5
+:1082B0008132010071830040813201000200009789
+:1082C00080980100000000402EB101000200004033
+:1082D0002EDD01009001004093980100290100402B
+:1082E000813201005C810040AF3301007999004088
+:1082F000813201000000454081B20100000055407C
+:1083000081B201004984004081B2000004000040B5
+:1083100081B200000400004081B20000040000406F
+:1083200081B200000400004081B20000040000405F
+:1083300081B200000400004081B20000040000404F
+:1083400081B200000400004081B20000040000403F
+:1083500081B200007701004181C00000718051406E
+:1083600081B200007280524081B20000738055409B
+:1083700081B200007480564081B2000055019181A5
+:10838000803000005A01454081B2000055019182C1
+:10839000803000005A01464081B200005A01004876
+:1083A000FD9300005A010048FD9300005A01004966
+:1083B000FD8300005A01004AFD83000000000040D8
+:1083C00049B10100AE0300CBA3C9010000000020A9
+:1083D00046B10100000000D2F1B10100000000D35D
+:1083E000F1B1010000000042F0B1010000000045C1
+:1083F00061B101002000002062DD01000000A8D072
+:10840000E1B100007C80004081B20000000000A8C3
+:1084100098B00100048000408BB30000B10300401D
+:10842000A19901008480A241976F000000000045DF
+:10843000A1C101000000000080B001000000A20402
+:108440008094000080153F4297E301000000004047
+:1084500049B10100000060030294010000000040E7
+:1084600007B00100040000CB99CB0100000000CC54
+:10847000F38301008E80A241976F0000000000CBC3
+:10848000F3930100AE0300CBA3C90100000000205C
+:1084900044B1010000000044F1B1010000000000FF
+:1084A000F0B1010000000004F0B10100000000A1E3
+:1084B000E0B10100050000406199010020000020AA
+:1084C00062DD01009580A84081320000C6020020D4
+:1084D000423101000000A241056C0100000080CB88
+:1084E000DB910100000019418BB3010060000040E6
+:1084F000619901009B80A8B18C33000060000040AE
+:10850000619901009D80A8B194330000A38014C636
+:1085100081320000180000C683F401006A84224FF3
+:10852000830400007F80004081B20000FF0100C68C
+:1085300081880100000000C697A301007F801F5CB6
+:10854000975300009E831DC68132000000002F4318
+:1085500081F00100A980004010C9000005810040A1
+:1085600081B200003681004081B20000DA8100CA89
+:1085700063B300002D81004081B200001481004DE2
+:1085800083B000001E81004E61B100000D810040EB
+:1085900085B000001481004C83B00000F0800040E2
+:1085A00085B000009181004049B100003D8100404C
+:1085B000C1B100008D81004081B200000D810040FA
+:1085C00085B00000DD81004049B100006A8400CA26
+:1085D0009BB3000046810040C1B100004E810040C5
+:1085E000C1B1000055810040C1B10000568100407A
+:1085F000C1B1000057810040C1B100005881004066
+:10860000C1B100005981004081B000005981004192
+:1086100081B00000CE81004081B20000DD8300BB4C
+:10862000ABB30000DB8100CACFB30000D3800040B1
+:1086300049B10000DF80004081B20000DC810040D1
+:1086400081B200006A84004081B20000DA800040FC
+:1086500081B200006A8400CA77B300001581004D22
+:1086600083B000001C81004E61B100000D8100BB91
+:1086700085B000001581004C83B000000D8100BB67
+:1086800085B00000F08000BB85B00000E2800040B3
+:1086900081B200006A8400CA4DB3000064820040C9
+:1086A00049B100008F82004049B10000C8142EBBC0
+:1086B00085B00100000000EE82B001000000004122
+:1086C000E0B10100FF7F00A2A08B01000000004488
+:1086D000A5B30100758000CAA733010002810040E4
+:1086E00081B200004E01004D933001004E01004E5A
+:1086F000933001004E01004C93300100088400408B
+:10870000813201006A84004081B20000549500402B
+:10871000459901006A8400CAE5B10000000080406C
+:1087200097B00100E88022428F6F0000EA8022416A
+:108730008F6F0000EC801ECA81320000EE801FCADD
+:1087400081320000000000CAC9B101006A84004201
+:108750008FB30000000000CACDB101006A8400415F
+:108760008FB30000000000CACFB101006A8400404E
+:108770008FB30000008100A6C6B101006A840040EA
+:1087800081B20000008000A6C6B101006A840040EA
+:108790008FB30000781800404999010010002F9C09
+:1087A00089B00100078100403933010018002F9B78
+:1087B00089B00100078100403733010000002F9A83
+:1087C00089B00100078100403533010008002F996E
+:1087D00089B001000781004033330100008000AE02
+:1087E00047C9010080000040F1990100000000CA63
+:1087F000F1B1010000000042F0B10100401800405A
+:10880000E19901000000004561B10100200000AEC7
+:1088100063DD01000281284081320000FF800040BA
+:1088200081B2000002814240813200000000005C01
+:10883000699301006A841A449393000005814240C1
+:108840008132000004810058699300000000004458
+:10885000F0D101000000A44081B200000C81A240D0
+:10886000E16D00000000004445D10100000080409F
+:10887000E1B1010000008041E1D101000D81375CD0
+:10888000613100000000004262B101001181284006
+:10889000813200000E81004081B20000000000CA59
+:1088A00063B101001181A840813200006A84174041
+:1088B00081B200001681004081B00000168100BB2B
+:1088C00081B000000000004160B1010000000040E4
+:1088D00062B101001781A84081320000000000CA87
+:1088E00063B101006A842840813200001981004090
+:1088F00081B2000050950040479901001F8100BBE4
+:1089000087B0000050952F4087B0010021812240A0
+:10891000957F00006A8460409583000002002DF07E
+:1089200084B0010022813640813200000000004204
+:1089300062B101002381A8408132000000000043A1
+:1089400062B101002581A84081320000000000CA08
+:1089500063B101002781A840813200000000164069
+:1089600081B201006A84224143510000000800CA1C
+:1089700095CB01002281004185C000002F81A242D9
+:10898000676F00000000004167B301002F81424083
+:10899000813200000000004065B30100000000408B
+:1089A0009383010000001ACA699701006A84264077
+:1089B0008132000034814240813200006A841A44CE
+:1089C000939300006A842043956F00006A8480CAF4
+:1089D000673300006A842240656F00006A84006F7C
+:1089E000DB910000C100004081320100358022404F
+:1089F000803200006A84004081B200000000005F05
+:108A0000959301004281A244216F00000000005FA5
+:108A1000958301000000005E95930100000000575F
+:108A200095930100000000CAC3B101004581225B9B
+:108A3000957F00000000004BFD9301006A84004018
+:108A400081B2000049812240AF6F00001BF500CACF
+:108A5000959B01004A81004081B200001BFD00CAC5
+:108A6000959B0100000000CA7FB30100260100CAE7
+:108A7000C53101000000005F958301006A8400CACF
+:108A8000C5B10000DF6F00CA959B010000000055D2
+:108A900095930100000000CAC7B101006A84225FFB
+:108AA000957F000026010040813201000000005F38
+:108AB000958301006A8400CAC7B100006A8400CAB5
+:108AC000C9B100006A8400CACBB100006A8400CA40
+:108AD000CDB100006A8400CACFB1000000002E4270
+:108AE00081E001009814004048C901006A8400CA6E
+:108AF000E1B100000000004009B10100200000A623
+:108B000082B001005E81A25E0B7D0000008000410A
+:108B1000089901006081A25E0B7D0000208000A604
+:108B200008B1010062819F85823000006181A24FFF
+:108B30000B7D00000000004121B30100028000A66F
+:108B400082B00100C9810040813201001000004163
+:108B500084E40100038000A682B00100C9810040C6
+:108B600081320100F0FF00418688010000000043CF
+:108B7000849401000F0000A686B0010010C40043D9
+:108B8000869801007581A243846C000000000043B8
+:108B900021B30100200000A682B001001C000041AA
+:108BA00082DC01007281A25E0B7D000004000041A6
+:108BB000089901007E81004081B20000410100A6B9
+:108BC00086B00100500C0043869801007A81A243D0
+:108BD000846C00000000004121B301007E81004050
+:108BE00081B20000410100A686B00100600C004384
+:108BF000869801007E81A243846C00000000004240
+:108C000021B30100200000A682B001007F81A25E96
+:108C10000B7D000040130041089901008781224329
+:108C2000216F0000200000A682B001001200004168
+:108C300082DC01008481A25E0B7D00000004004103
+:108C4000089901008C81004081B20000200000A63C
+:108C500082B001001900004182DC01008981A25E1E
+:108C60000B7D000000A00041089901008C810040AC
+:108C700081B200000000804081B20100200000A607
+:108C800080B00100000000CA819401008F81A25EC3
+:108C90000B7D00006A84004008B10000C8142EBBA0
+:108CA00085B001009281A25E0B7D000000000040B3
+:108CB00087B00100A1812243216F0000B0812244CE
+:108CC000216F0000118000A682B00100C981004020
+:108CD00081320100B881224A837C000000000040FC
+:108CE000879001009C81224D837C000000000041A0
+:108CF000879001009E81224F837C0000000000438A
+:108D000087900100A081224E837C00000000004279
+:108D100087900100B881004081B20000018000A668
+:108D200082B00100C981004081320100018000A6AB
+:108D300082B00100C981004081320100B881224225
+:108D4000837C000000000040879001001C8000A68A
+:108D500082B00100C981004081320100AB8122450F
+:108D6000837C00000000004187900100AD81224417
+:108D7000837C00000000004387900100AF81224304
+:108D8000837C00000000004287900100B881004011
+:108D900081B20000018000A682B00100C9810040BC
+:108DA00081320100018000A682B00100C98100402B
+:108DB00081320100B8812242837C00000000004023
+:108DC00087900100000000438790010000000041EF
+:108DD00087900100008000A682B00100C981004098
+:108DE00081320100BC81224B837C000000000040E6
+:108DF0008780010000000043E0B101000000004056
+:108E0000AFB30100C5812240877C0000C581A2412B
+:108E1000877C000000000041AEB30100000000406C
+:108E200081B30100C4812242877C0000C581000B10
+:108E30007DB300000000000F7DB30100FF7F00A2A2
+:108E4000A08B010000000044A5B30100758000CA9A
+:108E5000A73301000281004081B2000020000041E0
+:108E600082DC0100CA81A25E0B7D0000000000418F
+:108E700008B10100CC819F85823000000000804055
+:108E800081B20100D18114F781300000D181A24963
+:108E9000FD7F000000000048FD930100D48115F81B
+:108EA00081140000D481A24AFD7F00000000004828
+:108EB000FD930100D681A2C881320000400000402D
+:108EC00080DC01000010004080DC01000000004058
+:108ED000EFB30100D8814240F1330000048100402B
+:108EE000689700006A8400BB6BB300006A8400BB13
+:108EF000B1B300006A84004081B20000CC142E405F
+:108F000087B00100FF7F00A2A08B0100D8000043C2
+:108F1000B2330100000068DA89B001007C00004033
+:108F20008B9801000000005089F001000000004112
+:108F300089D0010003000044888C01000000004239
+:108F400087C0010000000041A5B30100D800004324
+:108F5000B2330100000000DAF1B10100000000426C
+:108F600087C0010000000041A5C30100F881224430
+:108F700089500000F88122448B500000E781A25004
+:108F8000A56F000000000042A5E30100000000CA38
+:108F9000A7B30100758000BB85300100CC142ED230
+:108FA00095C30100AE0300CBA3C90100000000205F
+:108FB00042B101000000005081B00100F581A241E2
+:108FC00081500000F481A2F280300000E78100406F
+:108FD000A5B3000000000042A5E30100000000CAA4
+:108FE000A7B30100758000BB8530010002810040FD
+:108FF00081B20000D9000041B3730100000080502D
+:10900000B5F30100D8000041B3F30000000000D91F
+:10901000B3FB0100003000A6B8B30100F20000402D
+:1090200081320100250100422D01010000020040B3
+:1090300083980100EB0000408132010000000050E5
+:1090400081B001002601004081320100098210DA5E
+:10905000B56B00000A8200412D8100000000004134
+:109060002D910100280100408132010025010040BE
+:109070002D110100000000402D8101000682A24157
+:1090800081500000260100422D0101002501004011
+:1090900081320100260100422D110100250100400E
+:1090A0002D110100158204402D0100002501004012
+:1090B000813201001182004081B20000280100408D
+:1090C00081320100250100422D010100F200004023
+:1090D000B9330100000000422D81010000008041F1
+:1090E0002D8101000000804081B20100000300409A
+:1090F000819801000000004018B10100800000408C
+:109100008398010000190040459901000000424089
+:1091100081B20100000043FFF1B10100000000FF37
+:10912000F1B101000000004181C0010000000040D9
+:1091300018B101001F82A2418350000000160040B8
+:1091400045990100001900404399010000000047C3
+:1091500043C101000000004083B00100000000F3A3
+:1091600080B001000000005B81D0010000000041E0
+:1091700080D0010000000040F6B101000000005B5B
+:1091800043C101000000004183C001002982A254B4
+:10919000836C000000000040F7B1010000000041B6
+:1091A00083C001003082A206836C00000000804072
+:1091B00081B201000000800791B00100E180004011
+:1091C000813201003982A240976C000028000040E3
+:1091D000B39B01003A82004081B2000028000040A9
+:1091E000B39B0100FC81004081320100000000DAE5
+:1091F000F5B10100FC810042B3430100000000DA38
+:10920000F5B10100FC810042B3430100000000DA27
+:10921000F5B101004E000040B39B0100FC8100400D
+:1092200081320100080000DAF7F50100500000402B
+:1092300091980100000000478FB00100FC810048B8
+:10924000B2330100000000DAF7B10100080000DAD3
+:10925000F7F501000000004291C001004582A241E3
+:109260008F5000000000004145D10100080000407F
+:10927000B39B0100FC81004081320100000000DA54
+:10928000FDB101000A000040B39B0100FC810040D9
+:1092900081320100000000DAFDB101001800004039
+:1092A000B39B0100FC81004081320100000000DA24
+:1092B000FDB1010016000040B39B0100FC8100409D
+:1092C00081320100000000DAFDB10100348200406B
+:1092D000813201001E000048B2CB0100FC81004039
+:1092E00081320100000000DA91C001000000004856
+:1092F000B2CB0100FC8100408132010000006EDA37
+:109300008FB0010002000048B2CB0100FC81004098
+:1093100081320100000000DAFDB1010004000048C4
+:10932000B2CB0100FC81004081320100000080DAF4
+:10933000FDB101006F822250FD7F00006F82224547
+:10934000FD7F000040160040459901003582004035
+:109350004931010008000048B2CB0100FE81004005
+:10936000813201006D82A2408F6C00007282222047
+:10937000B56F00006F82004081B20000DB820040C8
+:109380008132010072822240976C00006F8242405D
+:10939000813200000000004F6993010004810058F1
+:1093A000699300005416004047990100000000FE38
+:1093B000F4B101000000004081B20100000000FE95
+:1093C000F4B101000000004081B20100000000FE85
+:1093D000F4B101000000004081B20100000000FE75
+:1093E000F4B101000000004081B20100000000FE65
+:1093F000F4B101000000004081B20100000000FE55
+:10940000F4B101000000004081B20100000000FE44
+:10941000F4B1010046000040B39B0100FC81004014
+:1094200081320100080000DAF7F501004800004031
+:10943000959801000000004497B00100FC81004AAB
+:10944000B2330100000000DAF7B10100080000DAD1
+:10945000F7F501000000004295C001008582A2419D
+:10946000975000002A000040A59B010040160040D4
+:10947000A19B0100000000CAA7B30100758000BBDA
+:10948000853001000281004081B20000A7822245A0
+:10949000FD7F0000E0150040479901001A0000A27E
+:1094A00080DC010000000050F1B10100F015004027
+:1094B000F1990100000000CAF1B10100070000406D
+:1094C00061990100A000004062DD01009682A8BB06
+:1094D000E13100000000005083B001009982A241F8
+:1094E000835000009882A2F282300000E1800040A8
+:1094F000813201009F82A240976C0000280000404A
+:10950000B39B0100A082004081B20000280000400F
+:10951000B39B0100F015004043990100FC8100401D
+:1095200081320100A782A2FAB46F0000FC810042E0
+:10953000B3430100A782A2FAB46F0000FC8100428D
+:10954000B3430100AA8222FAB46F0000A78242400E
+:10955000813200000000004E699301000481005830
+:109560006993000040160040459901003582004093
+:1095700049310100F6150040439901005C16004096
+:109580004599010000006EFA8EB001000000004015
+:1095900081B20100000000FEF4B1010000000040B3
+:1095A00081B20100000000FEF4B1010000000040A3
+:1095B00081B20100000000F0B4B30100B882A24003
+:1095C0008F6C0000FC152020E1B10100BD8200403D
+:1095D00081B20000DB82004081320100BD82224066
+:1095E000976C0000BA824240813200000000004FB8
+:1095F000699301000481005869930000348200409F
+:10960000813201001E000048B2CB0100FC81004005
+:1096100081320100C2822250B56F0000000000506C
+:1096200091C0010000000048B2CB0100F6150040D7
+:1096300043990100FF8100F2B433010002000048A9
+:10964000B2CB0100F815004043990100FF8100F200
+:10965000B433010004000048B2CB0100FA15004009
+:1096600043990100FF8100F2B43301000800004873
+:10967000B2CB0100FC15004043990100000000F04E
+:1096800094B00100FFFF004AB48B0100FF8100404D
+:10969000813201000A000048B2CB01001000004AEC
+:1096A000B4F70100FF8100408132010034820040A4
+:1096B000813201001E000048B2CB0100FC81004055
+:1096C00081320100D8822250B56F0000D98200504B
+:1096D000B5B3000000000040B5B30100FF810040B9
+:1096E000813201000281004081B20000001600407A
+:1096F0004799010030310040F599010032330040B4
+:10970000F599010034350040F599010036370040E5
+:10971000F599010038390040F599010041420040B7
+:10972000F599010043440040F59901004546004089
+:10973000F599010047480040F5990100494A004069
+:10974000F59901002C0000408398010000000040C2
+:10975000F7B10100E782A2418350000080162E0677
+:1097600083B00100360000FBF6A90100EA82A241A5
+:10977000835000002200004083980100000000FB9D
+:10978000F6B10100ED82A24183500000620000406A
+:1097900095980100008300408132010000162D06DB
+:1097A00083B0010080160040459901005C0000FB79
+:1097B000F6A90100F382A24183500000000000706E
+:1097C000F9B1010000000071F9B101000000007260
+:1097D000F9B1010000000073F9B10100000000744C
+:1097E000F9B1010054000040959801000083004049
+:1097F000813201000000007095B00100FF822270EC
+:10980000B56F00000000804197B00100000080406B
+:1098100097B00100456700A6E0B201000123007087
+:10982000E19A0100CDEF00A6E2B2010089AB007120
+:10983000E39A0100BA9800A6E4B20100FEDC0072CF
+:10984000E59A0100321000A6E6B2010076540073DA
+:10985000E79A0100D2C300A6E8B20100F0E100746B
+:10986000E99A01008016004A44C90100000000077F
+:1098700081B001000000004A80D0010000000040DB
+:10988000F7B101000D83A241815000008016004A0B
+:1098900044C90100FC162A47E7B501000300004A4D
+:1098A000E8E50100000000408DB0010050030040D9
+:1098B000A399010080163D468DE001000000005094
+:1098C00089B00100000000FC40B001000000004130
+:1098D000A3C101001683A24189500000000000705E
+:1098E000EBB2010000000071EDB201000000007257
+:1098F000EFB2010000000073F1B20100000000743B
+:10990000F3B201000000004083B001000F000041ED
+:109910008088010050030040A2C901003383A05099
+:10992000836C00000D00004098C801000000004F4B
+:10993000998401005003004CA2C9010000000020DE
+:1099400086B001000800004098C801000000004FE8
+:10995000998401005003004CA2C9010000000020BE
+:1099600086A401000200004098C801000000004FDA
+:10997000998401005003004CA2C90100000000209E
+:1099800086A4010050030040A2C90100000000436A
+:1099900040A401000100002088E401000000005FF5
+:1099A00041F00100000000444094010005000075F2
+:1099B00089E401001B00007585F4010000000044EB
+:1099C000849401003D83A353836C00000000007663
+:1099D00089B0010000000077898401000000007652
+:1099E0008BB00100000000208BA401000000007873
+:1099F0008B8401004C8300458894000027000041BF
+:109A000080CE01004283AA4081320000000000762F
+:109A100089B001000000007789A401004C83007820
+:109A200089A400003B00004180CE01003F83AA4092
+:109A3000813200000000007689B00100000000774C
+:109A400089840100000000768BB0010000000078DE
+:109A50008B8401000000004588940100000000771D
+:109A60008BB00100000000788B8401004C8300451E
+:109A7000889400000000004484C0010000000079C8
+:109A800085C001000000002084C001005383A3535F
+:109A9000836C0000825A00A684C0010099790042BC
+:109AA00084C801006083004081B2000027000041AB
+:109AB00080CE01005883AA4081320000D96E00A6F2
+:109AC00084C00100A1EB004284C801006083004013
+:109AD00081B200003B00004180CE01005D83AA40BE
+:109AE000813200001B8F00A684C00100DCBC004254
+:109AF00084C801006083004081B2000062CA00A6F1
+:109B000084C00100D6C1004284C8010060830040C7
+:109B100081B2000000000078F3B20100000000777D
+:109B2000F1B201001E00007689E401000200007617
+:109B3000EFF6010000000044EE9601000000007501
+:109B4000EDB2010000000042EAB201000000004155
+:109B500083C001004F00004180CE01001F832A40D6
+:109B60008132000000000075E1C2010000000076B3
+:109B7000E3C2010000000077E5C2010000000078A8
+:109B8000E7C2010000000079E9C2010013838141AE
+:109B90008D4000000000804081B201009D83A24BF7
+:109BA000B76F00009D83A2412F7D00000000005090
+:109BB000FD930100401600404599010035820040A8
+:109BC000493101009C8322408F6C0000080000484E
+:109BD000B2CB0100FE81004081320100DB820040F7
+:109BE000813201009C83A240976C00005E16004009
+:109BF000439901007C1620F6E0B10100000000400E
+:109C000031B301008083224F8F7C0000000000519F
+:109C1000FD930100828322408F7C000086830054E4
+:109C2000FD930000848322428F7C000000000052DC
+:109C3000FD930100868322418F7C000000000053C9
+:109C4000FD9301009A832251FD7F00003482004081
+:109C5000813201000C000048B2CB0100FC810040C1
+:109C6000813201009583A240B56F00001E000048BC
+:109C7000B2CB0100FC81004896300100000000DA00
+:109C800097C001000400004BB2CB0100FC810040F2
+:109C9000813201000E000048B2CB0100FF8100407C
+:109CA000813201000C000048B2CB010000000030FE
+:109CB000B5B30100FF810040813201000E00004871
+:109CC000B2CB0100FC810040813201009983224027
+:109CD000B56F00009D830054FD930000000000510B
+:109CE000FD8301001C0000FE7FD901009D83A6407A
+:109CF0008132000000000055FD930100000080400B
+:109D000081B20100B6030040A199010000002F417B
+:109D100099B30100A8832244816C0000B0832248DB
+:109D2000816C0000AA83224C816C0000B483225015
+:109D3000816C0000B5832254816C0000B7832258E7
+:109D4000816C0000BC83225C816C000055010040E6
+:109D500081B20000000000BC09B001006A8400CAA2
+:109D600001B000000000004003B00100000000410D
+:109D7000F3830100AE83A242056C000000000041A5
+:109D800005B001006A8422CA071400006A840045F5
+:109D9000F39300006A842043956F00006A8480CAB0
+:109DA000053000006A842201803000006A8400CB04
+:109DB000DB9100005C0100BCABB30000000000BC04
+:109DC000B1B301006A8400CACFB30000FF0000CA2B
+:109DD000818801006A84A240747D000060002040F8
+:109DE00060990100B983A8B182300000B8830040B7
+:109DF00081B200006A8400CA79B300000000004EFE
+:109E000081B0010000000043CB8301000000454009
+:109E100081B20100BF83A241815000000000454093
+:109E200081B201000000454081B20100CA839182E5
+:109E3000823000000000008A80B00100B69F004020
+:109E400080CE0100C883A64081320000CA835640FC
+:109E500081B20000B6030040A19901000000005348
+:109E600007900100B6030040A199010000000052D4
+:109E700007900100F39F00418BB300000000004EEB
+:109E800081B0010000000042CD8301000000464087
+:109E900081B20100CF83A241815000000000464002
+:109EA00081B201000000464081B20100DA83918155
+:109EB000823000000000008980B00100B69F0040A1
+:109EC00080CE0100D883A64081320000DA8355405D
+:109ED00081B20000B6030040A199010000000052C9
+:109EE00007900100B6030040A19901000000005353
+:109EF00007900100F39F00418BB30000B1030040C5
+:109F0000A1990100C4142F4099B301005C010040E5
+:109F100049B1000058152D408DB00100D0142DF02E
+:109F200088B00100000000408FB00100010000A6D1
+:109F300090B0010000F80048909801000000004532
+:109F400093B00100000000FA8AB001006A030040EB
+:109F500081320100020000A680B00100EC832240A3
+:109F6000826C0000F0830040813201004703004012
+:109F700081320100000000418DC00100F583225FA5
+:109F80008D6C0000E783A24193500000E583004000
+:109F900081B20000FF070047848801000000A6404E
+:109FA00081B20000F59F00478030010000020047A9
+:109FB0008EC80100F083004081B200000000004420
+:109FC00050B30100FB832018896C0000040000A638
+:109FD00084B00100200000A686B0010000100040FF
+:109FE000559B0100FE83004081B20000040000A6E2
+:109FF00084B00100200000A686B0010000100040DF
+:10A00000559B01000000004250D30100000000A851
+:10A010004FB30100000000434ED301005E03004037
+:10A02000813201006C03004280300100F083004067
+:10A0300081320100078422A78F6C00004903004091
+:10A04000813201000484004081B2000000008040A1
+:10A0500081B20100A0942E4397B00100000000409F
+:10A06000F1B101000984A2419750000050952040B1
+:10A07000E1B10100AC942E4397B001000000004014
+:10A08000F1B101000D84A241975000000000804012
+:10A0900081B20100AE030040A3990100000000401E
+:10A0A00081B0010060150040859801000800004063
+:10A0B00040E40100000000594194010000000050FC
+:10A0C00041E0010000000042409401000000004116
+:10A0D00081C001000000A341816C0100000000412B
+:10A0E000A3C101001384005085C000004984A2412F
+:10A0F000017D000021842258737D0000780000401B
+:10A10000619901001C84A8B19C30000030003845E2
+:10A110009DE001000100000E10C90000218433C43D
+:10A12000813000002484A1AD9D2000001B841340D9
+:10A1300081B200000000134E5A8301003000384500
+:10A140009DE001002C8422AB800400002A84A24000
+:10A15000017D00002C84225F577D0000278A00408B
+:10A1600081B200002C84225E577D00008A8A004064
+:10A1700081B2000031842254737D000074000040DD
+:10A18000619901002C84A8B1003000000086A25F14
+:10A19000017C00006289004081B200003384A25F2C
+:10A1A000592700003584A25C737D00003C84A25EC8
+:10A1B000737D00004684225C737D00004784374035
+:10A1C000813200007C000040619901003684A8B112
+:10A1D000363000007C000040619901003884A8B14D
+:10A1E000003000001F000000028801002F86174089
+:10A1F00081B2000047843440813200007E0000407C
+:10A20000619901003D84A8B11230000044845221BC
+:10A2100013040000000014412FC30100FF3F000998
+:10A22000008C01000000004301F00100878400342D
+:10A2300013840000FF3F1409008C0100E7840043F1
+:10A2400001F000000000004081B20100478433406B
+:10A25000813200001B84134E5A930000EC89A248FF
+:10A26000FD7F00004E842259737D0000790000407C
+:10A27000619901004A8428B17E3100004B8400407E
+:10A2800081B20000528421AC9C20000000000041FB
+:10A290001FC301000400A05F9D6C00000000004E81
+:10A2A000589101005684225A737D00007A000040C4
+:10A2B000619901005384A8B17E310000010000CFF4
+:10A2C00011C900005C84A240937F00005C8422449A
+:10A2D000937F0000588442A5803000005B84A24038
+:10A2E000937F000071841A409393000000001A408D
+:10A2F00081B201009A80A240737D0000A1892244AE
+:10A30000216F000098892240657D0000A689A25B2C
+:10A31000737D00000400A249337D0000668422485A
+:10A32000337D0000FF01009980D80100000000503B
+:10A3300081E00100A8982F4033B1010000000040E7
+:10A34000E0C1010069842240AF6F000069842240AF
+:10A35000816F0000F5891FA5826F000049840040CD
+:10A3600081B200001B8400408BB300000000005845
+:10A3700061B101000000004E62B101001B84284061
+:10A38000813200006C84004081B200006F84334051
+:10A390001F3000001B84134E5A9300007384A0CE1C
+:10A3A000815000008584A0CD816C0000000000A5D4
+:10A3B0009CB30100000000B181B00100858422B58A
+:10A3C0008114000080152F4049B10100778442407C
+:10A3D00081320000000060B465970100D0152E4066
+:10A3E00069B3010000001A44938301001A0000A21F
+:10A3F00080DC010000000044F1B10100000000B168
+:10A40000F1B10100000000B5F1B10100050000400C
+:10A41000619901000000004062B101008084A8A1A0
+:10A42000E03100005C8400889EB300005C84A2419F
+:10A43000676F00005C84006FDB9100008584424000
+:10A44000813200005C841A40938300000099000967
+:10A4500046C901003F0000F30C8801009084A64229
+:10A460001360000055970095033001008B84454030
+:10A470008132000075000040619901008C84A8B110
+:10A480000C3000005C971D1094300100918400583E
+:10A490001F9000004E970095033001001B84008838
+:10A4A0001CB0000000002D0348B1010004002DF095
+:10A4B0002EB00100EE070040979801009884234BCE
+:10A4C000E46D00009884224BFD7F000000000040F6
+:10A4D0001F90010022002F4081B201009B8483174E
+:10A4E0008032000026000040479901009D848517B6
+:10A4F000803200000000004847C10100A3842255BB
+:10A500002F7C00000000004243D101000F0000FA40
+:10A51000968801000000004297E001000000004220
+:10A5200097D00100A484004B44C10000120000A297
+:10A5300044C90100280000F602CC01000A0000A175
+:10A5400042C90100000000F816B00100000028F028
+:10A5500010B00100000000F01AB00100000000A2DD
+:10A560002AB00100C0283C460DE0010000002D4447
+:10A5700095B00100B084A2F80E300000C0842241E2
+:10A580009550000000002D5049C10100AC840040EE
+:10A5900081B20000AD84A2F8166C0000AD84A2F870
+:10A5A000106C0000AD84A2F01A6C0000BE8422582A
+:10A5B0001F7C000000993F4213F00100B584474022
+:10A5C00081320000B984A2F3740600000000000686
+:10A5D000E6950100BE841F4081B200000000000625
+:10A5E00096B001003F001FF30C88010000000055E9
+:10A5F00061B101000000004B62B10100BC84A840C1
+:10A6000081320000BE84474081320000C6841F4171
+:10A610002DC30000C48422581F7C00000000005598
+:10A6200061B101000000000662B10100C284A840CF
+:10A6300081320000C484474081320000EE841F4113
+:10A640002DC30000030000071AF401002196000743
+:10A6500016300100D5842241816C0000CC84224256
+:10A66000816C00001B8400881CB00000D484225F31
+:10A670000F7C00001597005F01100100D28422407A
+:10A68000956C00000480000342C90100000000F244
+:10A6900002B001008A960052953001009196004B5D
+:10A6A00002B000006797000996300100058A00405B
+:10A6B0000FB00000DD84A25A1F7C00009B95004073
+:10A6C00081320100DD842220856C0000DA849C0F39
+:10A6D000803200001B8400881CB000007C96005C67
+:10A6E0001F0001009B980042613101001B8400881B
+:10A6F0001CB00000E69900079630010000002D050F
+:10A7000048B10100E08482F0183000006C8B0045F5
+:10A710008FB00000282000A696B00100E484221724
+:10A72000960400000B98004B953001006C8B004B99
+:10A730008FB000002197000348310100FC940040D5
+:10A74000813001006C8B004081B2000000002E10AF
+:10A7500048B101000000685003B001000000000390
+:10A76000F0B101000000004261B1010000000010E2
+:10A7700062B10100EB84A800E03100001B84008876
+:10A780001CB0000000002D0348B101000000004093
+:10A790000FB00100000000F82EB00100000000F230
+:10A7A00002B001000000004017B00100004100A607
+:10A7B00096B00100EE072E47979001000185221701
+:10A7C00096040000FF84224BFD7F0000FF8423A23B
+:10A7D000026C00008A96005295300100040022416C
+:10A7E000975000000C002D0012B00100000000F096
+:10A7F00000B001000000005C018001009196004B58
+:10A8000002B000000000000900B00100000000508C
+:10A8100003B001001E85005C1790000013852243E1
+:10A820002F7C0000000000451F9001000C85225F76
+:10A830002F7C000000002E1048B1010000000058DD
+:10A84000F1B1010010000003F0C901001000000088
+:10A85000E0C9010008854542613100000000001098
+:10A8600062B101000985A840813200001B841D8867
+:10A870001CB0000020002D0348B10100FF0F00F6BE
+:10A88000808801001085A2A6816C0000138500F26B
+:10A890003AB00000FD85A24BFD7F0000E29500402C
+:10A8A000813201001B8A004081B200001E85224ACD
+:10A8B0002F7C00001E8522482F7C00000A002D03FB
+:10A8C00048B101003F0000F2868801001F000043EC
+:10A8D000848801000500004380F4010098943D4203
+:10A8E00081E001001E85A242E07D0000FD85A24BB3
+:10A8F000FD7F0000E2950040813201001B8A00408C
+:10A9000081B200001E85474081320000000000A394
+:10A9100009B0010000001F4147C30100248522A1A6
+:10A92000096C00006B8400881CB0000021850003C6
+:10A9300048B100005E85A392036C00000A990040B4
+:10A94000953001000000004143C3010000000016E3
+:10A9500080B201001B8A2708803200002B85225C10
+:10A96000177C00002C8500002AB0000012000000B7
+:10A970002AC801000200000880C801003085A243F7
+:10A980002F7C00000E980040813201004C85005E53
+:10A9900017900000040000018CCC01000E98004CC0
+:10A9A0000330010000002E4602B00100100000102C
+:10A9B00048C901000C000001F0CD01002C0000404E
+:10A9C000F0C9010000000016F0B1010010000015F0
+:10A9D000E0C901000000004361B10100A00000A433
+:10A9E00062DD01003985A854171000004C85005E17
+:10A9F00017900000120000002AC801004B85224376
+:10AA00002F7C0000040000018CCC01000000004CF1
+:10AA100003B001002F9800436131010000002E4671
+:10AA200002B001001000001048C901000C00000134
+:10AA3000F0CD01000C000009F0C901000000001871
+:10AA4000F0B1010010000015E0C901000000004352
+:10AA500061B10100A00000A462DD01004C85285412
+:10AA6000171000004885004081B200002F98004375
+:10AA7000613101004E8522502F7C000000000056FD
+:10AA80001790010007000017988801005185A24126
+:10AA9000996C000000000055179001000000004371
+:10AAA00061B101004000001062DD01005285A84044
+:10AAB000813200001B8400881CB000001698004002
+:10AAC00081320100598522432F7C0000168000034B
+:10AAD00044C901000000001DE4B10100B797005E09
+:10AAE000051001005C85A25F2F7C0000CE94000160
+:10AAF00038430100E2950040813201001B8A00408A
+:10AB000081B200006085A24BFD7F0000FA85004104
+:10AB100043C300000000004027B0010000000040D7
+:10AB20002DB001000000004011B001006385350127
+:10AB3000863000006D000040619901006B8528B1EE
+:10AB4000303000006485224D757D00000000001645
+:10AB500080B20100EA85A740116C000000000041AE
+:10AB600043C30100F985004081B200006D00004040
+:10AB7000619901006B85A8B1123000000000001639
+:10AB800080B201007585A740116C000000000041F3
+:10AB900043C301000000000910B0010000000018CC
+:10ABA0002CB00100DE07004380CE01006485AA407E
+:10ABB000813200007A85004081B2000040003E43AF
+:10ABC00027E0010000000009F0B1010000000018BA
+:10ABD000E0B101000000004127C001006485A30B23
+:10ABE00087500000000015401BB00100000000402D
+:10ABF00023B00100120000002AC8010040002D40CF
+:10AC000039B001008285A240276C000022000008B4
+:10AC100012C80100DE07004025980100858500402C
+:10AC200081B20000000000F812B00100000000F046
+:10AC300030B001000000000B25B001000000001042
+:10AC400032B0010014002001E0B10100EE07004025
+:10AC5000379801008A852301366C0000000000014E
+:10AC600036B001009585824123400000208000100D
+:10AC700042C9010091852240E36D000000000043BD
+:10AC800061B101004000001062DD01008E85A84026
+:10AC9000813200001B8400881CB000000196004334
+:10ACA000233001000000001032B00100000000411C
+:10ACB00023B001000000000348B10100008000192A
+:10ACC00044C90100A48522451F7C00000000004CFF
+:10ACD000F1B1010000000009F0B10100000000180E
+:10ACE000F0B101000000004361B101002000001933
+:10ACF00062DD01009B85A815E031000000000050D6
+:10AD000003D001000000005033C001000000004CDF
+:10AD100025D001000C002D4C13C001000000005094
+:10AD200037D00100000000502BC001008A8500458B
+:10AD30001F800000A685A312366C0000A785681B43
+:10AD400028B000000000681228B0010000000009CF
+:10AD5000F0B1010000000018F0B101000000004354
+:10AD600061B101002000001962DD0100AA85A8156B
+:10AD7000E0310000D0852214025000000000005095
+:10AD800033C001000000001424D001000C002D1479
+:10AD900012C00100C985A21436500000BA85225C99
+:10ADA0001F7C00003080001042C90100B88522409D
+:10ADB000E36D00000000004261B10100400000109E
+:10ADC00062DD0100B585A840813200001B84008847
+:10ADD0001CB000000000000348B101000C002D5C15
+:10ADE0001F800100100000F02AC801000000005C74
+:10ADF0002B800100F007004037980100BF85230138
+:10AE0000366C00000000000136B00100CA85221B2C
+:10AE1000026C00003000001048C9010000002E5CE8
+:10AE20001F90010000000050F1B10100000000037C
+:10AE3000F0B10100FF070015E08D010000000042A5
+:10AE400061B10100A00000A462DD0100C685A84038
+:10AE500081320000CA85000348B1000000000014E0
+:10AE60002AC001008A85A240256C00000000004134
+:10AE700039C0010040003D4339E001000000000BF3
+:10AE800025B00100000000F812B001008A8500F032
+:10AE900030B000000080001942C90100D685224070
+:10AEA000E36D00000000004361B1010040000019A3
+:10AEB00062DD0100D385A840813200001B84008838
+:10AEC0001CB00000019600402B30010018002E033A
+:10AED00048B10100DA8522502F7C000000000056A6
+:10AEE000179001000700001798880100DD85A24136
+:10AEF000996C00000000005517900100E085224386
+:10AF00002F7C000000000054179001001600201D47
+:10AF1000E4B10100E285A340276C0000E485605F96
+:10AF2000179000000084000B16DC01000000601385
+:10AF300016940100B797005E051001001B8AA25FFE
+:10AF40002F7C00001480000342C90100000000F2C1
+:10AF500002B00100CE940001384301001B8A00407A
+:10AF600081B200000000004083B001000000004DED
+:10AF700061B101000000001662B10100EC85A8403B
+:10AF8000813200000000000862B10100EE85A84097
+:10AF900081320000F9852213826C000040003D439D
+:10AFA00083E00100000000F810B00100000000F094
+:10AFB0002CB001000000001662B10100F485A84029
+:10AFC000813200000000000862B10100F685A8404F
+:10AFD00081320000F085004183C000000000154070
+:10AFE00081B20100008200A604B00100A0980040D8
+:10AFF00047990100E9890041893001008A96005291
+:10B00000953001009196004B02B000001B8A004071
+:10B010000FB000000000005F018001001000000080
+:10B020000EF401003F00000000880100030000074B
+:10B030001AF4010021960007163001000B86224108
+:10B04000816C000009862242816C00001B8400880C
+:10B050001CB000000A86225F0F7C0000058A0040B9
+:10B060000FB000001386A25A1F7C00009B95004081
+:10B070008132010013862220856C000010869C0F0F
+:10B08000803200001B8400881CB000007C96005CAD
+:10B090001F0001009B980042613101001B84008861
+:10B0A0001CB00000E69900079630010000002D0555
+:10B0B00048B10100000000F018B001001986223AE2
+:10B0C000016C0000000000008EB001006C8B00409D
+:10B0D00001B000000000004081B201002E002D05EB
+:10B0E00048B101001D86A240E76D00000A00004043
+:10B0F0008F9801006C8B004001B000006695004005
+:10B10000813201004E970095033001001B840088B6
+:10B110001CB0000000002D0348B1010022002DF0FA
+:10B120002EB00100282000A696B001002686221726
+:10B13000960400000B98004B953001006C8B004C7E
+:10B140008FB0000028868317803200000000004482
+:10B1500043C101002A8685178032000000000048A4
+:10B1600043C10100280000F602CC0100120000A13A
+:10B170002AC801002197004081320100FC9400415F
+:10B18000813001006C8B004081B2000000000001A2
+:10B1900000D0010000002E1048B10100280000403E
+:10B1A000F199010000000003F0B10100000000006F
+:10B1B000F0B1010034864647613100000000001004
+:10B1C00062B101003586A81BE03100001B841E8897
+:10B1D0001CB000000000004503E0010008002D0342
+:10B1E00048B101005A8601FB08300000AD8687FB9C
+:10B1F00022300000000000FA0EB00100000000F84C
+:10B2000014B00100030000071AF4010021960007A2
+:10B210001630010050862241816C00004486224293
+:10B22000816C00001B8400881CB000004F86225FE8
+:10B230000F7C0000380000047E8901004886A65F6C
+:10B240000F00000074950040053001004D8600405D
+:10B2500081B20000130000408798010000002D0318
+:10B2600048B101000C002DF082B00100000000F098
+:10B2700084B0010000970040053001000000005C30
+:10B280001F900100058A00400FB000005886A25AA6
+:10B290001F7C00009B9500408132010058862220CF
+:10B2A000856C000055869C0F803200001B8400884E
+:10B2B0001CB000007C96005C1F0001009B980042BF
+:10B2C000613101001B8400881CB00000E699000772
+:10B2D0009630010000002D0548B10100000000F08B
+:10B2E00018B001005C862104802000005D860040CB
+:10B2F00010C90000AE8A004B81B000007C8600437C
+:10B3000081B00000808600FB22B00000AE8A0041C0
+:10B3100081B000006C8B004E8FB000007886005A20
+:10B320008FB00000658600478FB00000AE8A0053E2
+:10B3300081B00000AE8A005681B0000032002D05B9
+:10B3400048B101006C8BA00AE46D00006B86A2413D
+:10B35000197C00006A86220A803200006C8B005340
+:10B360008FB000006C8B00548FB000007486220AEE
+:10B37000803200006E86A20AE46D00006C8B005DD6
+:10B380008FB00000000000F280B001000000000A51
+:10B3900080D001007286A091816C00006C8B005EF1
+:10B3A0008FB00000250000408F9801006C8B00409A
+:10B3B00081B2000076862091E56D00006C8B005410
+:10B3C0008FB00000210000408F9801006C8B00407E
+:10B3D00081B2000032002D0548B101006C8BA00A3B
+:10B3E000E46D0000240000408F9801006C8B004049
+:10B3F00081B2000037002D0548B10100040000F3C0
+:10B4000082F40100AE8AA042836C0000AE8A005430
+:10B4100081B00000000000F20EB001000300000740
+:10B420001AF4010000B5000D42C901000700000731
+:10B43000168801008986220BE67D00000A00004084
+:10B4400087980100559900408132010000000040BA
+:10B450000FB00100058A005C1F9000009B862250FF
+:10B46000FD7F00009686A254FD7F00008E86225547
+:10B47000FD7F000082000040879801008686004022
+:10B4800081B2000086862253FD7F000014800003F5
+:10B4900042C90100000000F096B001001000004B0E
+:10B4A00080F401000CBC004087980100968622437E
+:10B4B000806C0000FFFF004B808801008686A2435D
+:10B4C000806C00007C9600404799010097864340BD
+:10B4D000813200009A86A0F0306F00008C861B40FD
+:10B4E00081B2000000001B4131C30100A59500405E
+:10B4F000253001009F869C0F803200001B8400884D
+:10B500001CB000007C96005C1F000100148000034A
+:10B5100042C90100000000F096B0010000002F05B4
+:10B5200048B101001000000718E401000008000CF9
+:10B53000E0990100E69900079630010000B5000D82
+:10B5400046C90100A6863040813200000000000B91
+:10B55000E6910100000200A146C901000000000BB5
+:10B56000E691010004002E0548B1010000001040E2
+:10B57000E1B10100AE8A004081B00000000000FB94
+:10B5800028B00100000000FB86B00100000000F8B8
+:10B5900014B00100B7862246237C0000B386224007
+:10B5A000877C0000000000481F900100B586224102
+:10B5B000877C0000000000471F900100B7862242F0
+:10B5C000877C0000000000451F900100B786471BE4
+:10B5D0002C300000000000A013B0010000001F414B
+:10B5E00041C30100E6862392156C0000E686A24561
+:10B5F0001F7C0000EA86224BFD7F0000170000D070
+:10B60000A2C901000000004027B001000200000AAA
+:10B6100024C80100DD9500400F300100E4862208B7
+:10B620004030000000000041A3C10100F0070012FB
+:10B6300024CC0100C086AA4127400000010000136D
+:10B6400080CC0100E086264023300000000000404E
+:10B6500083B001006000000384C8010010000010E6
+:10B6600048CD0100170000D0A2C90100CD86A2403C
+:10B67000836C0000D986004183B000000080004246
+:10B6800044990100000068213896010000002E5006
+:10B6900049C10100D286A244236C0000300000039F
+:10B6A00048C9010000000044F1B101000C00002075
+:10B6B000F0C901000000004461B10100A00000A435
+:10B6C00062DD0100D586A842E031000000000044A0
+:10B6D00085C001000000004123C0010000000041BE
+:10B6E000A3C10100CB86A24181500000E086224028
+:10B6F000236C00000000004461B101004000001014
+:10B7000062DD0100DD86A840813200001B840088D4
+:10B710001CB000000000000348B10100EE0700402B
+:10B7200025980100170000D02AC80100F3860017F1
+:10B7300010B00000C097004081320100EA8600404E
+:10B7400081B20000DD95009225300100000000402C
+:10B7500031B00100EA8622082E300000F386004155
+:10B7600027B00000808000A604B001000600004061
+:10B77000879801005599000A8C30010000000040B4
+:10B780000FB001000000005C1F900100F286229FB4
+:10B79000136C0000020000881CCC01006B84004088
+:10B7A00081B20000058A00413FC300000000004054
+:10B7B0000FB001002800000180CE010007872A4059
+:10B7C000813000000080001044C9010040000040AA
+:10B7D00081980100FC86A2481F7C0000FC86A247DD
+:10B7E0001F7C0000FC86A307036C00008000004063
+:10B7F00081980100FF86A340026C00002800000130
+:10B80000F0CD0100018700400FB00000280000408B
+:10B81000F0CD0100040000400ECC01002800000320
+:10B82000F0C9010028000000F0C901000000001666
+:10B83000E0B101000000004761B1010020000010EC
+:10B8400062DD01000587A85C1F10000000000040B9
+:10B8500043990100000000F008B00100A0012D4054
+:10B8600000C00100ED88220F4205000018879C0FE0
+:10B87000803200000000005C1F800100008000108A
+:10B8800042C9010013872240E36D00000000004719
+:10B8900061B101004000001062DD01001087A84086
+:10B8A000813200001B8400881CB00000188722072A
+:10B8B000803200000000000342B1010000000007D8
+:10B8C00042C10100008000A1469901000000005F14
+:10B8D000E1910100D787A2451F7C00001000000302
+:10B8E00048C9010000002D5429C00100000000F8E3
+:10B8F00018B00100000000F804B00100000000F8DA
+:10B900000EB00100420000030AC801000C0000A4B0
+:10B910000CC801000000004017B001000000001436
+:10B9200002B001000000001424D001000000001447
+:10B9300010C001001200000810C801000000004003
+:10B9400023B00100FE7F000544C90100298720942F
+:10B95000156C00002A870094E5B100000000000A81
+:10B96000E4B10100438722018032000000003C4422
+:10B9700023E0010000002EA480B0010000000010B0
+:10B9800048C101003087A307026C000031876801BD
+:10B990001AB00000000068071AB001000000000D96
+:10B9A00002D0010000000005F0B101000000000C11
+:10B9B000F0B1010000000002E0B101000000000D44
+:10B9C0000AC001003D872240036C00003D872242EF
+:10B9D000236C00000000004123C00100000000476C
+:10B9E00061B10100A00000A462DD0100658728406C
+:10B9F000813200003A87004081B200000000001050
+:10BA000080C001000000004761B10100000000405B
+:10BA100062B101003F87A840233000001B840088EA
+:10BA20001CB000006587004081B2000000003C446B
+:10BA300023E00100000000A486B0010000002E10E9
+:10BA400048C101004887A3120E6C000049876807AF
+:10BA50001AB00000000068121AB001004C8780087C
+:10BA6000F03100000100001198C801000000004CF6
+:10BA70001E9001000000000CF0B101000000000267
+:10BA8000E0B101000000001086C001000000004687
+:10BA900061B10100011F004362DD01005087A85C15
+:10BAA0001F1000008387220D146C00005687220DA2
+:10BAB000246C00000000000D10C001005A87000D2A
+:10BAC00024D00000000000412BC001000000001540
+:10BAD000A2B101001000002010C80100F0070040D2
+:10BAE000259801005C872242236C00006587004195
+:10BAF00023C000000000004661B1010040000010BA
+:10BB000062DD01005D87A85C1F0000001B840088C7
+:10BB10001CB000000000001048B1010063872247FC
+:10BB20001F7C000011960043233001000E00000F1F
+:10BB30001E8C01000000004023B001008387220D0D
+:10BB4000145000008287A20D0E500000718722461B
+:10BB50001F7C0000000000461F80010030800010A4
+:10BB600042C901006F872240E36D000000000047DA
+:10BB700061B101004000001062DD01006C87A84047
+:10BB8000813200001B8400881CB00000208000036C
+:10BB9000469901000000005FE191010000002D06C0
+:10BBA00048B10100000000F818B00100000000F8E2
+:10BBB00004B0010076871FF00E3000002A87004C89
+:10BBC0000DC0000000002E5F0F8001002A872307B0
+:10BBD000146C00003000001048C90100240000402F
+:10BBE000F199010000000003F0B101000000000025
+:10BBF000F0B1010000000016F0B1010024000000C7
+:10BC000000C801000000004761B10100A00000A4CD
+:10BC100062DD01007F87A8461F1000002A8700030D
+:10BC20000CB000002A87000D18C0000004002E147C
+:10BC30000AD001001200000548CD0100FE7F00057A
+:10BC400042C901000C002AF2E0B1010089872240BC
+:10BC5000316C000000006018389601001E000040A2
+:10BC600043990100008100F680CE01008D87A64037
+:10BC7000813200000000004443C101008F87220B85
+:10BC8000ED6D0000080000A142C90100020000A102
+:10BC900046C901000F0000FA948801000200004A22
+:10BCA00086E40100000000F60EB0010097872247ED
+:10BCB0001F7C000004001F430E5000009787A04621
+:10BCC0000F400000000000410FC001009B87224888
+:10BCD0001F7C00000000004091B0010004000FA292
+:10BCE000423100009E87004089B000000C0000A295
+:10BCF00042C901000000004389B001000000004378
+:10BD000095D00100000000FC82B00100A187A04195
+:10BD1000904000000000004191C00100A68722472A
+:10BD20001F7C0000A687A043896C0000A6872045E1
+:10BD3000896C0000A687A0410E4000000000004171
+:10BD40000FC001000000004189C001009E87A24190
+:10BD500095500000AF8722481F7C0000100000486B
+:10BD600092F40100FFFF004890880100AD879048E1
+:10BD7000924000000000004193C001000A0000A2B0
+:10BD800044C901000000662093A401003080001027
+:10BD900044C9010012000014F0C90100000000179E
+:10BDA000F0B1010012000005E0CD010030000010EC
+:10BDB00080C801000000004461B101002000004083
+:10BDC00062DD0100B587A84081320000C287225C95
+:10BDD0001F7C000000003C4423E0010000002D1007
+:10BDE00048C10100BF872240E36D0000000000460B
+:10BDF00061B101004000001062DD0100BC87A84075
+:10BE0000813200001B8400881CB00000C287875C60
+:10BE10001F0000000000001048B101001196004111
+:10BE200023400100C487A2471F7C000058890017E7
+:10BE300010B0000000002F0348B10100C787A00721
+:10BE4000164000000000004117C001000000000B78
+:10BE5000E4B101000000005017F00100CB8790F220
+:10BE6000164000000000004117C0010000006620DD
+:10BE700017A40100100000142AC80100000000509F
+:10BE80002BE00100000000F22A9401003080001035
+:10BE900042C90100D5872240E36D00000000004444
+:10BEA00061B101004000001062DD0100D287A840AE
+:10BEB000813200001B8400881CB000000080001745
+:10BEC00010DC01005889004081B20000A5950040B7
+:10BED00081320100DB87225C1F7C00001B8400880C
+:10BEE0001CB000007C96005C1F0001000080000573
+:10BEF00044C9010000000040E1B1010004002D032D
+:10BF000048B10100000000F03CB00100280000141E
+:10BF100002C801000000000134B0010000002D053E
+:10BF200032B00100220000050AC801001000000321
+:10BF300048C90100000000F818B00100000000F836
+:10BF400004B00100000000F80EB001000C0000A4D5
+:10BF50000CC801000000004017B0010000000040C4
+:10BF600023B00100218822018032000000003C44FF
+:10BF700023E0010000002EA480B0010000000010AA
+:10BF800048C10100F087A307026C0000F187680137
+:10BF90001AB00000000068071AB001000000000D90
+:10BFA00002D0010000000005F0B101000000000C0B
+:10BFB000F0B1010000000002E0B101000000000D3E
+:10BFC0000AC0010003882240036C0000FD87224262
+:10BFD000236C00000000004123C001000000004766
+:10BFE00061B10100A00000A462DD01003D8828408D
+:10BFF00081320000FA87004081B20000000000108A
+:10C0000080C001000000004761B101000000004055
+:10C0100062B10100FF87A840233000001B84008824
+:10C020001CB000003D88004081B2000000000010FC
+:10C0300080C001000000004761B101000000004025
+:10C0400062B101000588A840233000001B840088ED
+:10C050001CB000002200001948C9010000002D1486
+:10C0600048C101000F0000F23A88010000000042C0
+:10C070003BE001000E00001402C801000000001D9A
+:10C0800002C001001188231A02500000000000467F
+:10C0900003C001003D88000134C000000C002D1DCC
+:10C0A00048C10100F00000F23088010000000042A9
+:10C0B00031F001000000001402B001000000001D7A
+:10C0C00002C001000000001802C001001988221AF5
+:10C0D000025000003D88000134C000002200001919
+:10C0E00048C9010002002D1448C10100000000F6FB
+:10C0F00014B001000000001D14D001000000001861
+:10C1000014D001000000001E24B00100120000172E
+:10C1100010C801003D88001A10C0000000003C4417
+:10C1200023E00100000000A486B0010000002E10F2
+:10C1300048C101002688A3120E6C000027886807FA
+:10C140001AB00000000068121AB001002A888008A6
+:10C15000F03100000100001198C801000000004CFF
+:10C160001E9001000000000CF0B101000000000270
+:10C17000E0B101000000001086C001000000004690
+:10C1800061B10100011F004362DD01002E88A85C3F
+:10C190001F1000005A88220D145000005A88220DEA
+:10C1A000245000000000000D10C00100358822421C
+:10C1B000236C00003D88004123C0000000000046C1
+:10C1C00061B101004000001062DD01003688A85C0A
+:10C1D0001F0000001B8400881CB00000000000103D
+:10C1E00048B1010011960043233001000E00000FFA
+:10C1F0001E8C01000000004023B001005988A20DF0
+:10C200000E500000488822461F7C000000000046B7
+:10C210001F8001003080001042C901004688224082
+:10C22000E36D00000000004761B101004000001014
+:10C2300062DD01004388A840813200001B84008831
+:10C240001CB0000020800003469901000000005F40
+:10C25000E191010000002D0648B10100000000F846
+:10C2600018B00100000000F804B001004D881FF074
+:10C270000E300000EA87004C0DC0000000002E5F69
+:10C280000F800100EA872307146C000030000010C3
+:10C2900048C9010024000040F1990100000000039A
+:10C2A000F0B1010000000000F0B101000000001634
+:10C2B000F0B101002400000000C8010000000047A8
+:10C2C00061B10100A00000A462DD01005688A8460B
+:10C2D0001F100000EA8700030CB00000EA87000D81
+:10C2E00018C000007788A2441F7C000000000019DD
+:10C2F0000AB001002200000548C901000A002D14FF
+:10C3000048C1010002002040E5B1010004002040C6
+:10C31000E5B101000D002D1D48C10100090000F329
+:10C32000388801000D002050E7B1010004002D40C5
+:10C330003FB00100000000F432B0010004002040D2
+:10C34000E1B101002200000548C9010000002D14E0
+:10C3500048C101000200001D94F4010000000040EB
+:10C3600091B001006C88A0FC9040000000000041EA
+:10C3700091C001006A88A241955000000480000528
+:10C3800044C9010000000048F0B10100000000189D
+:10C3900048C101000200001894F4010000002D18AB
+:10C3A00090B001007488A0FC9040000000000041A3
+:10C3B00091C001007288A241955000000000004821
+:10C3C000E0B1010010002040E5B1010022000005AD
+:10C3D00048C901000000001448C1010004800005A4
+:10C3E00042C90100000000F880B00100000000F028
+:10C3F00016C001007C8842303D0700000000009E0E
+:10C4000085B0010000001A413DC301000400204234
+:10C41000ECB101000000001E82B0010002002E1DE0
+:10C4200082C001000000661882C0010000000042C6
+:10C4300080C001008688A0418044000000000041C7
+:10C4400081C001001000004092F401000A002E306B
+:10C45000818401008A8890409240000000000041E1
+:10C4600093C001000000662093A401000000001D9D
+:10C4700048C1010004002019E8B101000000001EBD
+:10C4800016C001009088A019164400000000004169
+:10C4900017C001000D002F1E32C001009588A24078
+:10C4A000156C00009488A01C16400000000000419C
+:10C4B00017C00100000063F338940100100000056C
+:10C4C00048C9010004002E1E98B001000000601A47
+:10C4D00098C001000C002040E1B10100A388224671
+:10C4E0001F7C0000000000461F800100308000100B
+:10C4F00042C90100A1882240E36D0000000000470E
+:10C5000061B101004000001062DD01009E88A8407A
+:10C51000813200001B8400881CB0000020800003D2
+:10C52000469901000000005FE19101003080001099
+:10C5300044C901001200001AF0C9010000000017F0
+:10C54000F0B1010010000005E0C90100300000104A
+:10C5500080C801000000004461B1010020000040DB
+:10C5600062DD0100A988A84081320000B788225C02
+:10C570001F7C000000003C4423E0010000002D105F
+:10C5800048C10100B3882240E36D0000000000466E
+:10C5900061B101004000001062DD0100B088A840D8
+:10C5A000813200001B8400881CB000000000005C89
+:10C5B0001F8001000000001048B1010011960041E9
+:10C5C000234001000E00000F1E8C010020002F05EB
+:10C5D00048B101000000000BE4B101000000005070
+:10C5E00017F00100BC8890F21640000000000041E6
+:10C5F00017C001000000662017A4010010000014FD
+:10C600002AC801000000001D2AC0010000000050DF
+:10C610002BE00100000000F22A940100308000109D
+:10C6200042C90100C7882240E36D000000000044B9
+:10C6300061B101004000001062DD0100C488A84023
+:10C64000813200001B8400881CB0000000800017AD
+:10C6500010DC0100E4882240156C0000CF88A24461
+:10C660001F7C0000000000441F900100CE88229F24
+:10C67000136C0000020000881CCC01006B84004099
+:10C6800081B20000000000413FC3010066990040F4
+:10C6900081320100D288A241877C00000000001E88
+:10C6A0003EC00100E4882240156C0000D588201EA1
+:10C6B000146C00000000000A3CB00100DD95001E73
+:10C6C00024300100DA8822082E30000000000052D9
+:10C6D00011C001000000001A10C001003D88004098
+:10C6E00017B000006B8400881CB00000DD9500408E
+:10C6F00081320100D788A2082E300000808000A679
+:10C7000004B001000600004087980100008000038B
+:10C710004499010004002204E03100005599001FF3
+:10C720008C300100000000400FB00100058A005C61
+:10C730001F900000008000034499010004002204BF
+:10C74000E03100006699004081320100E988A24191
+:10C75000877C0000EA88001E3EC000000000001F29
+:10C760008CB001000000004005B001005599004068
+:10C770000F300100058A005C1F900000F5889C0FB7
+:10C78000803200000000005C1F800100008000106B
+:10C7900042C90100F5882240E36D00000000004717
+:10C7A00061B101004000001062DD0100F288A84084
+:10C7B000813200001B8400881CB00000FA88220728
+:10C7C000803200000000000342B1010000000007B9
+:10C7D00042C10100008000A1469901000000005FF5
+:10C7E000E191010004002E0348B10100FD8820946E
+:10C7F000156C0000FE880094E1B100000000000A02
+:10C80000E0B1010001892240316C00000C000040C1
+:10C8100045990100000060183896010000002E10B4
+:10C8200048B1010000000050F1B101000000000813
+:10C83000F0B1010000000003E0B10100000000447D
+:10C8400061B101000000001062B101000689A8403A
+:10C85000233000001B8400881CB0000000002D5213
+:10C8600011C001001000000348C90100000000F8D9
+:10C8700018B00100000000F804B00100000000F84A
+:10C880000EB001000C0000A40CC8010000003C44E4
+:10C8900023E00100000000A486B0010000002E107B
+:10C8A00048C101001489A3120E6C000015896807A5
+:10C8B0001AB00000000068121AB001000000001059
+:10C8C00086C0010000000008F0B101000000000C6B
+:10C8D000F0B1010000000002E0B1010000000046DC
+:10C8E00061B10100011F004362DD01001A89A85CEB
+:10C8F0001F1000004B89220D146C00002089220DAE
+:10C90000246C00000000000D10C001002489000DFF
+:10C9100024D00000000000412BC0010000000015E1
+:10C92000A2B101001000002010C80100F007004073
+:10C930002598010026892242236C00002D890041A0
+:10C9400023C000000000004661B10100400000105B
+:10C9500062DD01002789A85C1F0000001B8400889D
+:10C960001CB000000000001048B10100D794004343
+:10C97000233001000000004023B001000400220D1C
+:10C98000145000004A89A20D0E5000003989224639
+:10C990001F7C0000000000461F8001003080001056
+:10C9A00042C9010037892240E36D000000000047C2
+:10C9B00061B101004000001062DD01003489A8402F
+:10C9C000813200001B8400881CB00000208000031E
+:10C9D000469901000000005FE191010000002D0672
+:10C9E00048B10100000000F818B00100000000F894
+:10C9F00004B001003E891FF00E3000000F89004C8A
+:10CA00000DC0000000002E5F0F8001000F8923077A
+:10CA1000146C00003000001048C9010024000040E0
+:10CA2000F199010000000003F0B1010000000000D6
+:10CA3000F0B1010000000016F0B101002400000078
+:10CA400000C801000000004761B10100A00000A47F
+:10CA500062DD01004789A8461F1000000F8900030E
+:10CA60000CB000000F89000D18C000005489225C32
+:10CA70001F7C00000000005C1F80010000003C449F
+:10CA800023E0010000002D1048C10100548922401C
+:10CA9000E36D00000000004661B10100400000109D
+:10CAA00062DD01005189A840813200001B840088AA
+:10CAB0001CB000000000001048B10100D7940041F4
+:10CAC000234001000000001710B001005889004009
+:10CAD0002BB0000000800003449901000000000416
+:10CAE000E0B101005D89229F136C00000200008804
+:10CAF0001CCC01006B84004081B2000066990041AB
+:10CB00003F430100000000408DB0010000000040E4
+:10CB100005B00100559900400F3001001B8A005CF0
+:10CB20001F900000100000000EF401000000003A09
+:10CB300001840100030000071AF401002196000798
+:10CB4000163001006C892241816C00006A89224202
+:10CB5000816C00001B8400881CB000006B89225F80
+:10CB60000F7C0000058A00400FB000007489A25AB3
+:10CB70001F7C00009B9500408132010074892220B7
+:10CB8000856C000071899C0F803200001B84008836
+:10CB90001CB000007C96005C1F0001009B980042C6
+:10CBA000613101001B8400881CB00000E699000779
+:10CBB0009630010000002D0548B10100000000F092
+:10CBC00018B001000000000080B00100AE8AA25F32
+:10CBD000816C0000A8002D431980010037002DF062
+:10CBE00024B00100040000F38EF401000F0000F3F4
+:10CBF00090880100838922488E6C00003600004036
+:10CC00004399010058003D43E7E1010083891FF08B
+:10CC1000246C0000828923418F6C0000AE8A00479B
+:10CC200081B00000AE8A004881B0000040000040A2
+:10CC300043990100B0002DF014B001008889220A48
+:10CC4000904000003999004091300100AE8AA24026
+:10CC500080320000B0002D4581B00100948922F09F
+:10CC60002C300000A3002D3083B00100AC002DF368
+:10CC700082E001008E89A3412C6C000000000016A8
+:10CC800082B0010098002DF082C0010088002DF0D4
+:10CC900082D00100000000F298E80100AE8A204C2A
+:10CCA000826C00007C002D4198E80100AE8A20F0E3
+:10CCB000986C0000058A220A803200004002000CB5
+:10CCC0007E890100058AA64081320000AE8A0049B3
+:10CCD00081B00000200000A680B001009C892243A2
+:10CCE000216F00001380004080DC01009D8900401E
+:10CCF00081B200001A80004080DC01009D89A25EA4
+:10CD00000B7D00000000004008B101009F899F8555
+:10CD100080320000A389004081B200005F8422407D
+:10CD2000577D00000100004057990100A38942404F
+:10CD300081320000000000449393010049841A5B93
+:10CD4000699300007B00004061990100A689A8B1A9
+:10CD500080300000CF891D4080320000C089224011
+:10CD6000AF6F0000C089225B817C00000400225D5F
+:10CD7000737D00007D00004061990100AC89A8B17D
+:10CD8000943000000000005F61B101000000004A23
+:10CD900062B10100AF89A84081320000B1894340EF
+:10CDA00081320000BF892257737D00007700004068
+:10CDB00061990100B389A8B1943000007700004068
+:10CDC00061990100B589A8B19630000000000048C3
+:10CDD00061B101000000004A62B10100B889A84AAF
+:10CDE00080330000BD89225F957C00000000004B6D
+:10CDF00062B10100BB89A84BAC33000000001BA549
+:10CE000082B30100C08900BE83C3000000001B4044
+:10CE100081B301004018004049990100040000A6B8
+:10CE200086B00100CD89A240860400001B849C408E
+:10CE300080320000FFFF004088880100E98900502F
+:10CE4000473101003600004488CC0100C9895240B6
+:10CE500081320000E98900404731010000000041B3
+:10CE600089B00100E989004847310100E9890005DE
+:10CE7000473101001B84004081B2000028000040BF
+:10CE8000479901001B840041E1C10000781800406F
+:10CE900049990100D6892254817C0000D189424001
+:10CEA00081320000008200B469DF010000001A44F2
+:10CEB000939301002800004047990100E98900414F
+:10CEC00089300100E4890F4080320000FF7F00407C
+:10CED00088880100E989005047310100360000448C
+:10CEE00088CC0100DC8999408032000000000048B5
+:10CEF00089D00100DE899B40803200000000004C98
+:10CF000089D00100E0891F4480320000E989004097
+:10CF1000473101000000004189B00100E989004863
+:10CF200047310100E9890058473101001B84004066
+:10CF300081B200001000004086F401006F00004341
+:10CF4000868801001B84260547310000E9890041DD
+:10CF5000893001001B84004081B200000000A04421
+:10CF6000F04101000000004081B20100000080415A
+:10CF7000E1C10100040000CB81C80100EF8922401B
+:10CF8000F27F00008180006F97330100F189224019
+:10CF9000737D00009B8000418BB30000EC89225917
+:10CFA000737D00007900004061990100EC8928B18F
+:10CFB0007E310000F289004081B20000040022C0EE
+:10CFC00095300000000000D697B00100FA89225D7C
+:10CFD000737D00007D00004061990100F889A8B1CF
+:10CFE000803000000000005E7F830100000000BF71
+:10CFF000C5B10100040000408198010025010040F6
+:10D0000081320100FD89A24181500000FF89435F08
+:10D010007F130000260100BFC53101000000005F42
+:10D020007F8301000000005E7F9301008B9800BFAA
+:10D03000C53101001B84004081B200000C8A9C0FA6
+:10D04000803200000080001042C901000C8A22409A
+:10D05000E36D00000000004561B1010040000010D8
+:10D0600062DD0100098AA840813200001B8400882B
+:10D070001CB0000077952202803200000D8A4240E9
+:10D0800081320000000000449393010077951A025A
+:10D0900068970000178A9C0F803200000080001003
+:10D0A00042C90100178A2240E36D000000000045DC
+:10D0B00061B101004000001062DD0100148AA84047
+:10D0C000813200001B8400881CB000008195220280
+:10D0D00080320000188A4240813200000000004483
+:10D0E0009393010081951A0268970000228A9C0F91
+:10D0F000803200000080001042C90100228A2240D4
+:10D10000E36D00000000004561B101004000001027
+:10D1100062DD01001F8AA840813200001B84008864
+:10D120001CB000006F84220280320000238A42403B
+:10D1300081320000000000449393010000001A02B5
+:10D14000689701006F84004005B00000008000A6D1
+:10D1500056B1010056952F4005B00100738AA240D8
+:10D16000E76D0000B8942941E7B1010000000054C8
+:10D17000EF930100000000F20EB001002900004012
+:10D180000D9801000900000712E40100000000A74B
+:10D1900013C00100030000071AF401000700000794
+:10D1A00016880100FFFF001034D8010000000003C2
+:10D1B000349401000000004023B00100201800401A
+:10D1C0001198010000B5000D42C90100578A220BD9
+:10D1D000E67D0000388A444081320000FFFF0007EE
+:10D1E000848901003F8A05C224300000679800400E
+:10D1F0008132010000002D0548B10100748A1CF045
+:10D2000018300100578A004081B2000000001C4025
+:10D2100081B201004E8AA048236C0000000000503B
+:10D2200035D001000080001A42C90100488A22401E
+:10D23000E36D00000000004261B101004000001AEF
+:10D2400062DD0100458AA840813200001B8400880D
+:10D250001CB000002098004043990100748A00F837
+:10D2600018300100498AA24123500000FFFF00103E
+:10D2700034D801000000000334940100201800405D
+:10D280001198010000002E1A48B10100000000446E
+:10D29000F1B1010000000008F0B1010000000042FF
+:10D2A00061B101002000001A62DD0100528AA80964
+:10D2B000E03100000000004123C0010000000050E8
+:10D2C00035C001000000004411C00100638A224102
+:10D2D0000D500000000000410FC001005F8AA0AAAD
+:10D2E0000F6C0000000000410FB0010009000007B2
+:10D2F00012E40100000000A713C00100000000407C
+:10D300001BB00100368A004117B00000000200097E
+:10D3100012C80100368A8341174000000000004017
+:10D3200017B00100368A00411BC000006E8A2340FE
+:10D33000236C00000000005035D001000080001A6E
+:10D3400042C901006B8A2240E36D000000000042E8
+:10D3500061B101004000001A62DD0100688AA84046
+:10D36000813200001B8400881CB00000209800401F
+:10D3700043990100748A00F8183001006C8AA241B8
+:10D3800023500000000000410FC00100718AA0AAD4
+:10D390000F6C0000000000410FB00100B89420079E
+:10D3A000E4B1010056952040E7B10100058A004034
+:10D3B0000FB00000FFFF000C80D80100C002000C7D
+:10D3C0007E890100868A2654613100007C8A870CA0
+:10D3D000803200000F000040629901007C8A2840E2
+:10D3E000813200007C8AA254777D0000788A004058
+:10D3F00081B20000818A2246197C00000D000040A5
+:10D40000629901000000A84081B200000000A2540F
+:10D41000777D01007D8A004081B20000868A224922
+:10D42000197C00000E000040629901000000A84035
+:10D4300081B200000000A254777D0100818A004083
+:10D4400081B2000010000040629901000000A84075
+:10D4500081B200000000A254777D0100868A00405E
+:10D4600081B2000030942F55F1930100004000A6D6
+:10D4700056B101006F84A241E551000064000040F4
+:10D48000E59901008E8A424081320000918AA29380
+:10D49000576F00000000004157C3010000001AABA5
+:10D4A00027B301006F842250FD7F00006F8422515A
+:10D4B000FD7F00006F84A2411D53000050460040D4
+:10D4C0001D9B010034820040813201000E000048A3
+:10D4D000B2CB0100FC810040493101009D8A22400D
+:10D4E000B56F00000E000048B2CB0100FF81004183
+:10D4F000B55301006F84004081B20000000000516C
+:10D50000FD8301004016004045990100358200402E
+:10D51000493101001E000048B2CB0100FC810040EF
+:10D5200081320100000000DA91C0010004000048CF
+:10D53000B2CB0100FF810040B533010060162040EE
+:10D54000E5B10100DB820040B5330100080000486E
+:10D55000B2CB0100FFFF004AB48B0100FF81004005
+:10D56000813201000A000048B2CB01001000004ADD
+:10D57000B4F70100FF810040813201006F84004058
+:10D5800081B200000500004043990100000000F353
+:10D5900008B0010004002040E6B101000300004093
+:10D5A00096E401000000000496C00100B48A004B1C
+:10D5B00010C90000D78D004109B000000400002010
+:10D5C0008FB00000040000208FB000000400002095
+:10D5D0008FB00000040000208FB000000400002085
+:10D5E0008FB00000040000208FB000000400002075
+:10D5F0008FB00000040000208FB000000B8E0041AF
+:10D6000009B00000040000208FB0000004000020DA
+:10D610008FB00000040000208FB000000400002044
+:10D620008FB00000040000208FB000000400002034
+:10D630008FB00000040000208FB000000400002024
+:10D640008FB000003D8E004509B000003D8E0045C2
+:10D6500009B000003D8E004509B000003D8E004538
+:10D6600009B00000040000208FB00000040000207A
+:10D670008FB00000040000208FB0000004000020E4
+:10D680008FB000007C8E004309B00000A58E0043DF
+:10D6900009B00000A98E004409B0000011900045B7
+:10D6A00009B00000040000208FB00000040000203A
+:10D6B0008FB00000040000208FB0000004000020A4
+:10D6C0008FB00000040000208FB00000B58E004332
+:10D6D00009B00000B48E004309B00000D58D0045AC
+:10D6E00009B00000040000208FB0000004000020FA
+:10D6F0008FB00000040000208FB000000400002064
+:10D700008FB00000758F004209B00000758F004394
+:10D7100009B00000758F004409B00000D58D0045A8
+:10D7200009B00000040000208FB0000004000020B9
+:10D730008FB00000040000208FB000000400002023
+:10D740008FB00000040000208FB00000A18F0043C4
+:10D7500009B00000040000208FB00000D58D004506
+:10D7600009B00000040000208FB000000400002079
+:10D770008FB00000040000208FB0000004000020E3
+:10D780008FB00000040000208FB00000BF8F004366
+:10D7900009B00000BF8F004409B00000D58D0045DE
+:10D7A00009B00000040000208FB000000400002039
+:10D7B0008FB00000040000208FB0000004000020A3
+:10D7C0008FB00000040000208FB00000BF8F004227
+:10D7D00009B00000040000208FB00000D58D004586
+:10D7E00009B00000040000208FB0000004000020F9
+:10D7F0008FB00000040000208FB000000400002063
+:10D800008FB00000040000208FB00000E78F0044BC
+:10D8100009B00000040000208FB00000D58D004545
+:10D8200009B00000040000208FB0000004000020B8
+:10D830008FB00000040000208FB000000400002022
+:10D840008FB00000D58D004209B00000F88F004570
+:10D8500009B00000F88F004509B00000D58D0045E3
+:10D8600009B00000040000208FB000000400002078
+:10D870008FB00000040000208FB0000004000020E2
+:10D880008FB00000FA8F004209B00000FA8F004309
+:10D8900009B00000FA8F004409B00000FA8F00457B
+:10D8A00009B00000040000208FB000000400002038
+:10D8B0008FB00000040000208FB0000004000020A2
+:10D8C0008FB00000040000208FB000000400002092
+:10D8D0008FB000000290004409B00000D58D0045D3
+:10D8E00009B00000040000208FB0000004000020F8
+:10D8F0008FB00000040000208FB000000400002062
+:10D900008FB000001390004209B000000390004364
+:10D9100009B000001390004409B00000D58D004507
+:10D9200009B00000040000208FB0000004000020B7
+:10D930008FB00000040000208FB000000400002021
+:10D940008FB00000040000208FB00000149000434E
+:10D9500009B000000A90004409B00000D58D0045D0
+:10D9600009B00000040000208FB000000400002077
+:10D970008FB00000040000208FB00000D58D004162
+:10D9800009B00000738F004209B00000738F00439C
+:10D9900009B00000738F004409B00000D58D004528
+:10D9A00009B00000040000208FB000000400002037
+:10D9B0008FB00000040000208FB00000D58D004122
+:10D9C00009B000001590004209B000001590004316
+:10D9D00009B000001590004409B00000D58D004545
+:10D9E00009B00000040000208FB0000004000020F7
+:10D9F0008FB00000040000208FB000000400002061
+:10DA00008FB00000040000208FB000000400002050
+:10DA10008FB00000040000208FB000001C90004573
+:10DA200009B00000040000208FB0000004000020B6
+:10DA30008FB00000040000208FB000001E90004254
+:10DA400009B00000040000208FB000000400002096
+:10DA50008FB00000040000208FB000000400002000
+:10DA60008FB00000040000208FB0000004000020F0
+:10DA70008FB00000040000208FB0000004000020E0
+:10DA80008FB000002A90004309B00000939000433B
+:10DA900009B00000A98E004409B0000011900045B3
+:10DAA00009B00000040000208FB000000400002036
+:10DAB0008FB00000040000208FB0000004000020A0
+:10DAC0008FB00000040000208FB000009B90004346
+:10DAD00009B00000A98E004409B000001190004573
+:10DAE00009B00000040000208FB0000004000020F6
+:10DAF0008FB00000040000208FB000000400002060
+:10DB00008FB00000040000208FB00000AC900043F4
+:10DB100009B00000040000208FB00000D58D004542
+:10DB200009B00000040000208FB0000004000020B5
+:10DB30008FB00000040000208FB00000040000201F
+:10DB40008FB00000798E004309B000009790004329
+:10DB500009B00000A98E004409B0000011900045F2
+:10DB600009B00000040000208FB000000400002075
+:10DB70008FB0000007002D0548B10100000000F340
+:10DB800008B0010006002047E6B10100040000478C
+:10DB900096E401000000004796D001000000004715
+:10DBA00096D001000000000496C00100748B004B69
+:10DBB00010C90000C490004909B000000400002012
+:10DBC00085B000000400002085B0000004000020A3
+:10DBD00085B000000400002085B000000400002093
+:10DBE00085B000000400002085B000000400002083
+:10DBF00085B000000400002085B000000400002073
+:10DC000085B000000400002085B000000400002062
+:10DC100085B000000400002085B000000400002052
+:10DC200085B000000400002085B00000FD90004297
+:10DC300009B000000400002085B0000004000020AE
+:10DC400085B000000400002085B000000400002022
+:10DC500085B000000400002085B000000400002012
+:10DC600085B000000400002085B000000400002002
+:10DC700085B000000400002085B0000004000020F2
+:10DC800085B000000400002085B0000004000020E2
+:10DC900085B000000400002085B00000039100461C
+:10DCA00009B000000400002085B00000040000203E
+:10DCB00085B000000400002085B0000004000020B2
+:10DCC00085B000000400002085B0000004000020A2
+:10DCD00085B000000400002085B000000400002092
+:10DCE00085B000000400002085B000000400002082
+:10DCF00085B000000400002085B000000400002072
+:10DD000085B000000400002085B000000400002061
+:10DD100085B000001191004209B00000040000200D
+:10DD200085B000003391004209B0000004000020DB
+:10DD300085B000000400002085B000000400002031
+:10DD400085B000000400002085B000000400002021
+:10DD500085B000000400002085B000002E91004A2C
+:10DD600009B000000400002085B00000040000207D
+:10DD700085B000000400002085B0000004000020F1
+:10DD800085B000003691004309B000000400002077
+:10DD900085B000008F91004409B00000040000200D
+:10DDA00085B000000400002085B0000004000020C1
+:10DDB00085B000000400002085B0000004000020B1
+:10DDC00085B000000400002085B000008E91004B5B
+:10DDD00009B000000400002085B00000040000200D
+:10DDE00085B000000400002085B0000006910041CD
+:10DDF00009B000000400002085B000000691004337
+:10DE000009B000000691004409B0000006910045E9
+:10DE100009B000000691004609B0000006910047D5
+:10DE200009B000000691004809B0000006910049C1
+:10DE300009B000000691004A09B000000691004BAD
+:10DE400009B000000691004C09B000000691004D99
+:10DE500009B000000400002085B00000040000208C
+:10DE600085B00000EE91004209B0000004000020DF
+:10DE700085B00000EE91004409B0000004000020CD
+:10DE800085B000000400002085B0000004000020E0
+:10DE900085B000000400002085B0000004000020D0
+:10DEA00085B000000400002085B00000EE91004B1A
+:10DEB00009B000000400002085B00000040000202C
+:10DEC00085B000000400002085B0000004000020A0
+:10DED00085B000000400002085B0000006920045D7
+:10DEE00009B000000400002085B0000004000020FC
+:10DEF00085B000000400002085B000000400002070
+:10DF000085B000001D92004709B000000400002009
+:10DF100085B00000FA91004509B00000040000201F
+:10DF200085B000000400002085B000007C9400460D
+:10DF300009B000000400002085B0000004000020AB
+:10DF400085B000000400002085B00000040000201F
+:10DF500085B000000400002085B000003391004629
+:10DF600009B000001191004609B000002C91004753
+:10DF700009B000002C91004809B000000400002006
+:10DF800085B000000400002085B0000004000020DF
+:10DF900085B000002E91004A09B000000400002066
+:10DFA00085B000000400002085B0000004000020BF
+:10DFB00085B000000400002085B0000004000020AF
+:10DFC00085B000000400002085B000008F9100455E
+:10DFD00009B000003691004309B000002C910047C1
+:10DFE00009B000002C91004809B000000400002096
+:10DFF00085B000000400002085B00000040000206F
+:10E0000085B000008E91004C09B000000400002093
+:10E0100085B000000400002085B00000040000204E
+:10E0200085B000000400002085B00000040000203E
+:10E0300085B000000400002085B000002392004459
+:10E0400009B000002392004209B00000C08D0047D3
+:10E0500009B00000C08D004809B000000400002095
+:10E0600085B000000400002085B0000004000020FE
+:10E0700085B000002392004B09B00000040000208E
+:10E0800085B000000400002085B00000069100412A
+:10E0900009B000004692004709B0000004000020CB
+:10E0A00085B000002E92004709B000000400002057
+:10E0B00085B000000400002085B0000004000020AE
+:10E0C00085B000000400002085B00000040000209E
+:10E0D00085B000000400002085B000002E920047AB
+:10E0E00009B000000400002085B0000004000020FA
+:10E0F00085B000000400002085B00000040000206E
+:10E1000085B000000400002085B00000040000205D
+:10E1100085B000000400002085B000002E9200476A
+:10E1200009B000004692004709B000002C9100475A
+:10E1300009B000002C91004809B000000400002044
+:10E1400085B000000400002085B00000040000201D
+:10E1500085B000002E92004709B0000004000020A6
+:10E1600085B000000400002085B0000004000020FD
+:10E1700085B000000400002085B0000004000020ED
+:10E1800085B000000400002085B0000004000020DD
+:10E1900085B000000400002085B0000055920047C3
+:10E1A00009B000005592004809B0000004000020AA
+:10E1B00085B000000400002085B0000004000020AD
+:10E1C00085B000000400002085B00000040000209D
+:10E1D00085B000000400002085B00000B892004027
+:10E1E00009B00000D692004709B00000CA9200486A
+:10E1F00009B000002692004709B0000026920047AF
+:10E2000009B00000D692004709B00000DD92004737
+:10E2100009B00000DD92004809B0000004000020B1
+:10E2200085B00000CA92004809B00000269200475D
+:10E2300009B000002692004709B00000CA920048C9
+:10E2400009B000000400002085B000000400002098
+:10E2500085B000000400002085B00000EE9100436E
+:10E2600009B000000400002085B00000EE910045D8
+:10E2700009B00000EE91004609B000002C91004763
+:10E2800009B000002C91004809B0000004000020F3
+:10E2900085B00000EE91004A09B0000004000020A3
+:10E2A00085B00000EE91004C09B000000400002091
+:10E2B00085B000000400002085B0000004000020AC
+:10E2C00085B000004592004709B00000399200482F
+:10E2D00009B000002D92004709B000002D920047C0
+:10E2E00009B000004592004709B00000C08D00470A
+:10E2F00009B00000C08D004809B0000004000020F3
+:10E3000085B000003992004809B000002D92004706
+:10E3100009B000002D92004709B000003992004872
+:10E3200009B000000400002085B0000004000020B7
+:10E3300085B00000DF92004209B000000400002018
+:10E3400085B00000DF92004409B000000400002006
+:10E3500085B000000400002085B00000040000200B
+:10E3600085B000000400002085B0000004000020FB
+:10E3700085B000000400002085B00000DF92004B53
+:10E3800009B000000400002085B000000400002057
+:10E3900085B000000400002085B0000004000020CB
+:10E3A00085B000000400002085B00000DF9200432B
+:10E3B00009B000000400002085B00000DF92004595
+:10E3C00009B00000DF92004609B00000DF9200476C
+:10E3D00009B00000DF92004809B0000004000020EE
+:10E3E00085B00000DF92004A09B000000400002060
+:10E3F00085B00000DF92004C09B00000DF92004CB5
+:10E4000009B000000400002085B0000004000020D6
+:10E4100085B000000400002085B00000FA9200469C
+:10E4200009B000000400002085B0000004000020B6
+:10E4300085B000000400002085B00000040000202A
+:10E4400085B000001D92004709B0000004000020C4
+:10E4500085B00000FA92004609B0000004000020D8
+:10E4600085B000000400002085B0000004000020FA
+:10E4700085B000000400002085B0000004000020EA
+:10E4800085B000000400002085B00000069400461E
+:10E4900009B000000400002085B000000400002046
+:10E4A00085B000000400002085B0000004000020BA
+:10E4B00085B000001D92004709B000000400002054
+:10E4C00085B000000694004609B00000040000205A
+:10E4D00085B000000400002085B0000006940046CE
+:10E4E00009B000000400002085B0000004000020F6
+:10E4F00085B000000400002085B00000040000206A
+:10E5000085B000002B94004209B0000004000020F8
+:10E5100085B000000400002085B000000400002049
+:10E5200085B000000400002085B000000400002039
+:10E5300085B000000400002085B000002A94004A45
+:10E5400009B000000400002085B000000400002095
+:10E5500085B000000400002085B000000400002009
+:10E5600085B000000400002085B0000004000020F9
+:10E5700085B000000400002085B000002B94004608
+:10E5800009B000000400002085B000002C91004775
+:10E5900009B000002C91004809B0000004000020E0
+:10E5A00085B000000400002085B0000004000020B9
+:10E5B00085B000002A94004A09B000000400002041
+:10E5C00085B000000400002085B000000400002099
+:10E5D00085B000000400002085B000000400002089
+:10E5E00085B000000400002085B000000400002079
+:10E5F00085B000000400002085B000000400002069
+:10E6000085B000000400002085B00000EA920041BF
+:10E6100009B000000400002085B0000004000020C4
+:10E6200085B000000400002085B000000400002038
+:10E6300085B000000400002085B000000400002028
+:10E6400085B00000F792004209B0000004000020ED
+:10E6500085B00000F792004409B0000004000020DB
+:10E6600085B000000400002085B0000004000020F8
+:10E6700085B000000400002085B0000004000020E8
+:10E6800085B000000400002085B00000F792004B28
+:10E6900009B000000400002085B000000400002044
+:10E6A00085B000000400002085B0000004000020B8
+:10E6B00085B000000400002085B00000F792004300
+:10E6C00009B000000400002085B00000F79200456A
+:10E6D00009B00000F792004609B00000F792004729
+:10E6E00009B00000F792004809B0000004000020C3
+:10E6F00085B000000400002085B000000400002068
+:10E7000085B00000F792004C09B000000400002022
+:10E7100085B000000400002085B000000400002047
+:10E7200085B000000400002085B000000692004C77
+:10E7300009B000000400002085B0000004000020A3
+:10E7400085B000000400002085B000000400002017
+:10E7500085B000001D92004709B0000004000020B1
+:10E7600085B00000FA91004C09B0000004000020C0
+:10E7700085B000000400002085B00000CD94004664
+:10E7800009B000000400002085B000000400002053
+:10E7900085B000007194004209B000000400002020
+:10E7A00085B000007194004409B00000040000200E
+:10E7B00085B000000400002085B0000004000020A7
+:10E7C00085B000000400002085B000000400002097
+:10E7D00085B000000400002085B000007194004B5B
+:10E7E00009B000000400002085B0000004000020F3
+:10E7F00085B000000400002085B000000400002067
+:10E8000085B000000400002085B000000400002056
+:10E8100085B000000400002085B000007194004520
+:10E8200009B000007194004609B000002C91004727
+:10E8300009B000002C91004809B00000040000203D
+:10E8400085B000000400002085B000000400002016
+:10E8500085B000007194004C09B000000400002055
+:10E8600085B000000400002085B0000004000020F6
+:10E8700085B00000FA91004209B000007C94004687
+:10E8800009B000000400002085B000000400002052
+:10E8900085B00000FA91004609B000000400002095
+:10E8A00085B000001D92004709B000000400002060
+:10E8B00085B000007C94004609B0000004000020F0
+:10E8C00085B000000400002085B000007C94004664
+:10E8D00009B000000400002085B000000400002002
+:10E8E00085B000000400002085B000008094004343
+:10E8F00009B000000400002085B0000004000020E2
+:10E9000085B000000400002085B000000400002055
+:10E9100085B000001D92004709B0000004000020EF
+:10E9200085B000008094004309B00000040000207E
+:10E9300085B000000400002085B000008094004DE8
+:10E9400009B000000400002085B000000400002091
+:10E9500085B000000400002085B000000400002005
+:10E9600085B000009294004309B00000040000202C
+:10E9700085B000000400002085B0000004000020E5
+:10E9800085B000000400002085B0000004000020D5
+:10E9900085B000000400002085B000006F94004A9C
+:10E9A00009B000000400002085B000000400002031
+:10E9B00085B000000400002085B0000004000020A5
+:10E9C00085B000000400002085B000000400002095
+:10E9D00085B000000400002085B000009294004340
+:10E9E00009B000000400002085B000002C91004711
+:10E9F00009B000002C91004809B00000040000207C
+:10EA000085B000000400002085B000000400002054
+:10EA100085B000006F94004A09B000000400002097
+:10EA200085B000000400002085B000000400002034
+:10EA300085B000000400002085B00000A4940043CD
+:10EA400009B000000400002085B000000400002090
+:10EA500085B000000400002085B000000400002004
+:10EA600085B000001D92004709B00000040000209E
+:10EA700085B00000A494004309B000000400002009
+:10EA800085B000000400002085B00000A494004D73
+:10EA900009B000000400002085B000000400002040
+:10EAA00085B000001191004209B000000400002070
+:10EAB00085B000003391004209B00000040000203E
+:10EAC00085B000000400002085B000000400002094
+:10EAD00085B000000400002085B000000400002084
+:10EAE00085B000000400002085B00000C3940042FF
+:10EAF00009B000000400002085B0000004000020E0
+:10EB000085B000000400002085B000000400002053
+:10EB100085B000000400002085B000000400002043
+:10EB200085B000000400002085B00000339100464D
+:10EB300009B000001191004609B000002C91004777
+:10EB400009B000002C91004809B00000040000202A
+:10EB500085B000000400002085B000000400002003
+:10EB600085B00000C394004609B0000004000020F6
+:10EB700085B000000400002085B0000004000020E3
+:10EB800085B000000400002085B00000C594004A54
+:10EB900009B000000400002085B00000040000203F
+:10EBA00085B000000400002085B0000004000020B3
+:10EBB00085B000001D92004709B00000040000204D
+:10EBC00085B00000C594004A09B000000400002090
+:10EBD00085B000000400002085B000007D94004650
+:10EBE00009B000000400002085B0000004000020EF
+:10EBF00085B000000400002085B000007D94004630
+:10EC000009B000000400002085B0000004000020CE
+:10EC100085B000000400002085B000000400002042
+:10EC200085B000001D92004709B0000004000020DC
+:10EC300085B000007D94004609B00000040000206B
+:10EC400085B000000400002085B000007D940046DF
+:10EC500009B000000400002085B00000040000207E
+:10EC600085B000000400002085B0000004000020F2
+:10EC700085B00000CB94004209B0000004000020E1
+:10EC800085B000000400002085B0000004000020D2
+:10EC900085B000000400002085B0000004000020C2
+:10ECA00085B000000400002085B000006F94004A89
+:10ECB00009B000000400002085B00000040000201E
+:10ECC00085B000000400002085B000000400002092
+:10ECD00085B000000400002085B000000400002082
+:10ECE00085B000000400002085B00000CB940046F1
+:10ECF00009B000000400002085B000002C910047FE
+:10ED000009B000002C91004809B000000400002068
+:10ED100085B000000400002085B000000400002041
+:10ED200085B000006F94004A09B000000400002084
+:10ED300085B000000400002085B000000400002021
+:10ED400085B000003691004D09B00000040000209D
+:10ED500085B000000400002085B000000400002001
+:10ED600085B000000400002085B0000004000020F1
+:10ED700085B000000400002085B0000004000020E1
+:10ED800085B000000400002085B0000004000020D1
+:10ED900085B000000400002085B0000004000020C1
+:10EDA00085B000000400002085B0000004000020B1
+:10EDB00085B000000400002085B0000004000020A1
+:10EDC00085B000000400002085B000000400002091
+:10EDD00085B000003691004D09B000002C9100472D
+:10EDE00009B000002C91004809B000000400002088
+:10EDF00085B000000400002085B000000400002061
+:10EE000085B000000400002085B000000400002050
+:10EE100085B0000007002E4B19900100108A0004F5
+:10EE2000E6B10000C08D2242197C0000C597003A6F
+:10EE300081300100C08D004081B20000C08D2242AF
+:10EE4000197C0000FF1F000F1E8C01003797004047
+:10EE500081320100D08D9C0F803200000000005CE8
+:10EE60001F8001000080001042C90100D08D2240A7
+:10EE7000E36D00000000004561B10100400000109A
+:10EE800062DD0100CD8DA840813200001B84008826
+:10EE90001CB000001986220280320000D18D424051
+:10EEA00081320000000000449393010000001A0228
+:10EEB000689701001986004005B0000005002E4B40
+:10EEC00019900100108A0004E6B100000000004023
+:10EED00087B00100000000408DB0010000800003F9
+:10EEE00042C90100400000A144C90100000000F037
+:10EEF000E0B101005599000607400100000000063E
+:10EF000007D00100D4002E5C1F9001000000000714
+:10EF1000F0B101000C80000342C90100000000F0C4
+:10EF2000F0B101000000004081B20100000000FECD
+:10EF300096B00100000000FE96C00100000000F045
+:10EF4000F0B101000000004081B20100000000FEAD
+:10EF500096C00100000000FE96C00100000000F015
+:10EF6000F0B101000000004081B20100000000FA91
+:10EF700096C00100000000FE96C001000030004B6A
+:10EF8000948801000000004695F001000000004A4E
+:10EF900096C001005E012E34978401000200004BF0
+:10EFA000E4E5010064012040E1B10100090000072F
+:10EFB00086E4010000002EA787C0010010000010A9
+:10EFC00048C9010010000040F199010058010043B8
+:10EFD000F0C9010058010005E0C90100000000442B
+:10EFE00061B10100A00000A462DD0100FA8DA8401B
+:10EFF000813200000000000548B101001A00004005
+:10F000009798010008002E4095B00100028E204B19
+:10F01000946C000000000040F1B10100FF8D004140
+:10F0200095C000001080001042C90100098E2240E6
+:10F03000E36D00000000004461B1010040000010D9
+:10F0400062DD0100058EA840813200001B8400882B
+:10F050001CB000000000000548B10100C597004049
+:10F0600081300100D58D004081B200000C8000038A
+:10F0700042C90100000000F886B00100000000F85D
+:10F0800088B001000E8E424081320000118EA24CE9
+:10F09000FD7F0000128E004CFD930000138E20F0C7
+:10F0A000566F0000000000F056B3010000001A4047
+:10F0B00081B201000080001044C9010064000040DA
+:10F0C000F199010070000005F0C901000000004343
+:10F0D000F0B101000000004761B101002000001004
+:10F0E00062DD0100198EA844E0310000100000101C
+:10F0F0008CC801000080004644C901004000004067
+:10F10000F199010068010005F0C9010064000043A5
+:10F11000F0C901000000004761B101000000004695
+:10F1200062B10100218EA844E03100001B840088F8
+:10F130001CB000000900000786E4010038002EA77B
+:10F1400087C001008B002D0548B10100298E2243A4
+:10F15000E77D00000000004445C101002C8E2244E0
+:10F16000E77D00000000004C45C101000000004A9E
+:10F1700019900100680120A2E4B10100880000405C
+:10F1800043990100308E230BE56D00000000004123
+:10F19000199001000080001044C901005000004097
+:10F1A000F199010058010043F0C901005801000520
+:10F1B000E0C901000000004461B10100000000103E
+:10F1C00062B10100358EA840813200001B840088A6
+:10F1D0001CB000005C002E0548B101000080000357
+:10F1E00042C90100000060F096B00100C5970041DF
+:10F1F00081300100D58D004081B20000408EA249CF
+:10F20000197C00008600004047990100448E0040B0
+:10F21000E5B1000086002F4919800100448EA2F25A
+:10F22000803200008B00004047990100000000423E
+:10F23000E7910100478EA246197C0000A000004023
+:10F24000479901004B8E0040E5B10000A0002F4619
+:10F25000198001004B8EA2F2803200008B0000402A
+:10F260004799010000000041E7910100A80000401B
+:10F270004399010034002DF024B00100000000FB90
+:10F280000CB00100000000FB10B00100000000FB0A
+:10F2900012B001000F0000F316880100040000F313
+:10F2A00014F40100768E2640813200005E8E220A20
+:10F2B000166C000058003D4313E00100000000F808
+:10F2C00082B00100040022F084300000FD9800406C
+:10F2D000813201001B8400881CB000000000000582
+:10F2E00048B101000000004113C001005D8EA04341
+:10F2F000136C00000000004013B00100538E004169
+:10F3000015D00000768E220A8032000058003D435E
+:10F3100013E00100000000F882B00100040022F0B8
+:10F3200084300000FD980040813201004000204000
+:10F33000E1B101001B8400881CB000000000000542
+:10F3400048B10100768E22411550000000000041B6
+:10F3500011C001006A8EA043116C00000000004043
+:10F3600011B0010058003D4311E00100000000F819
+:10F3700036B00100040022F0003000000000005010
+:10F3800083B0010004980047613101001B840088AC
+:10F390001CB00000749500054831010000000045D4
+:10F3A00061B101004000001062DD0100728EA840D2
+:10F3B000813200001B8400881CB00000668E0005AE
+:10F3C00048B1000037002040E7B1010036980051F5
+:10F3D00081300100D58D004081B2000034002E4103
+:10F3E000F5B1010000110040E59901007E8E004852
+:10F3F0001990000034002E41F5B1010000110040C9
+:10F40000E59901000080000342C90100000000F8F6
+:10F4100094B00100838E2245237C0000B0002FF0C1
+:10F420008CB00100000060F08CC001009000004032
+:10F430004399010035002DF08CB0010058003E4387
+:10F44000E7E10100888E2248197C0000000000419D
+:10F450008DC001000000680A8CC0010038002A4AF3
+:10F46000E0B1010028000000E0C901003C00201BC1
+:10F47000E0B101001080000342C90100000000F863
+:10F4800038B00100000000F826B00100040022F8A6
+:10F4900002300000968E2301146C0000000000F87A
+:10F4A00080B00100000000F882B001004C0020F0A4
+:10F4B000E4B1010044002040E0B1010048002041D7
+:10F4C000E0B10100A8002D1032B00100399900F020
+:10F4D000243001009F8EA244816C00009D8E224149
+:10F4E000197C0000A09600403B300100C38EA208AA
+:10F4F0003C3000009F8E004081B20000DD9500404E
+:10F5000081320100C38EA2083C3000005000201C54
+:10F51000E0B1010054002013E0B101004E002001D1
+:10F52000E4B101004000200AE0B101003698005F1C
+:10F5300081300100D58D004081B2000037000040CD
+:10F54000479901007F9600F3943001007E8E224A95
+:10F5500080320000AB8E004081B2000037000040D6
+:10F56000479901007F9600F39430010058003E4314
+:10F5700097E001000000001BF0B101001F006000D7
+:10F58000008C0100D58D85118032000004800003BD
+:10F5900042C90100B0002FF08CB00100000060F003
+:10F5A0008CC001003698005F81300100D58D00408D
+:10F5B00081B20000B58E004919800000BA8E224148
+:10F5C000197C0000A09600403B300100BE8EA208CE
+:10F5D0003C3000003698005F81300100D58D00403E
+:10F5E00081B20000DD95004081320100BE8EA2088C
+:10F5F0003C3000003698005F81300100D58D00401E
+:10F6000081B2000050002D1032B0010054002DF0E6
+:10F6100038B001004E002DF026B0010040002DF260
+:10F6200002B00100000000F014B001003000001032
+:10F630008CC801000080004644C9010068012D44C7
+:10F6400061B10100100068F280C8010000000008EC
+:10F65000F0B1010058010005E0C901000000000BF5
+:10F6600037B001000000004036D001005C012E40A0
+:10F6700010C001000000000680C001000000005220
+:10F6800081D00100D18E2094816C0000CB97009432
+:10F69000E5310100D28E004081B20000CB970040DE
+:10F6A000E43101002000004662DD0100D28EA84056
+:10F6B000233000000E00000F1E8C0100E28E8241FC
+:10F6C000234000002080001042C90100DC8E22404F
+:10F6D000E36D00000000004661B101004000001031
+:10F6E00062DD0100D98EA840813200001B840088B1
+:10F6F0001CB000000000001048B10100119600434A
+:10F70000233001000000000548B101000000001096
+:10F7100032B001000000004123B001000E00000FD4
+:10F720001E8C01000080001944C90100EA8E2241AC
+:10F73000197C0000E68EA3010C6C0000E78E000629
+:10F7400004B000000000000104B00100E98E2002B6
+:10F75000366C00000000001B04B00100ED8E0002BA
+:10F76000F0B10000EC8EA3010C6C0000ED8E680679
+:10F7700004B000000000680104B00100EF8E8008B2
+:10F78000F0310000000000111E9001000000001C7C
+:10F79000F0B101000000004661B10100011F001935
+:10F7A00062DD0100F18EA813E0310000288F2202F3
+:10F7B0001450000044002D020CD00100188FA2024A
+:10F7C00002500000FF8E225C1F7C0000208000039E
+:10F7D00042C90100FE8E2240E36D00000000004798
+:10F7E00061B101004000001062DD0100FA8EA84006
+:10F7F000813200001B8400881CB00000000000055E
+:10F8000048B1010044002D5C1F80010048002DF02C
+:10F8100038B001004C002DF026B0010038002FF266
+:10F8200002B00100198F2201146C00000C8F2246D7
+:10F830001F7C0000000000461F80010020002D03F7
+:10F8400048B101000B8F2240E36D0000000000442E
+:10F8500061B101004000001062DD0100088FA84086
+:10F86000813200001B8400881CB0000038002F0586
+:10F8700048B10100000000F894B0010038002DF0FC
+:10F8800096B001000000004CE1C10100200000031F
+:10F8900048C901000000224AF1B1010044000005FE
+:10F8A000F0C901000000004AF0B101000000004B67
+:10F8B000E0B101000000004761B10100A00000A418
+:10F8C00062DD0100158FA85C1F100000198F000574
+:10F8D00048B100000000000238C00100238F22065A
+:10F8E000803200000000005033C00100218FA202CE
+:10F8F000366C000004008F0D42310000100000F84B
+:10F9000010C801000000005C11800100F0070040F9
+:10F9100037980100D58E00A11AB000000000000247
+:10F9200010C00100D58E000236D000005000201C0F
+:10F93000E0B1010054002013E0B101004E002001AD
+:10F94000E4B101004000200AE0B101002D8F005F0A
+:10F9500001B0000037002D4601B00100040000F3A3
+:10F9600080F401002C8FA043816C00000000005542
+:10F9700001B0010040002040E1B101000080001909
+:10F9800042C90100338F2240E36D000000000046B1
+:10F9900061B101004000001962DD0100308FA84014
+:10F9A000813200001B8400881CB0000011960010FA
+:10F9B000483101003080001042C901003A8F2240D6
+:10F9C000E36D00000000004461B101004000001040
+:10F9D00062DD0100378FA840813200001B8400885F
+:10F9E0001CB0000060012F0548B101000000000BB1
+:10F9F000E4B101000000005017F001003F8F90F2C9
+:10FA0000164000000000004117C001000000662001
+:10FA100017A40100320000A62AC00100000000F275
+:10FA20002A940100488F22491F7C000000000049F1
+:10FA30001F8001000000004005B0010000F0000C34
+:10FA4000188C01000B98004C95300100588F000075
+:10FA500092B000004F8F2240AF6F000000C0001E28
+:10FA600094DC01000000001596B001008898004069
+:10FA7000053001004E8FA240976C0000618F004757
+:10FA800019800000588F000092B000004F8F43484B
+:10FA90006131000000D0001E62DD0100548F28405B
+:10FAA00005300000508F2248777D0000578F0040BE
+:10FAB00081B200000000001562B10100608F284093
+:10FAC00081320000548F004081B2000000001B0012
+:10FAD00092B001005D8F2241197C0000008000037C
+:10FAE00042C90100E29500F8003001005A8FA2419E
+:10FAF0003B500000618F004900B00000FF07001E6E
+:10FB0000008C0100E295004081320100618F0049C4
+:10FB100000B0000000001B4719800100648F225FC5
+:10FB2000016C00006399004081320100B08A00003E
+:10FB300080B000006B8F225C1F7C000020800003DF
+:10FB400042C901006B8F2240E36D000000000047B6
+:10FB500061B101004000001062DD0100688FA84023
+:10FB6000813200001B8400881CB000006B8F4005B0
+:10FB700048310000FFFF000794890100718F85CA9A
+:10FB8000943000006399185C1F0001000E00000F04
+:10FB90001E8C01007889004081B200003698180060
+:10FBA00080300100D58D0047198000000000004022
+:10FBB00019800100D58D2247197C0000DD95004099
+:10FBC00081320100788FA20880320000D58D00407C
+:10FBD00081B20000CB9700400D3001009C01004035
+:10FBE00045990100FFFF000B988801008B002D5004
+:10FBF00017F001007E8F904C16400000000000417D
+:10FC000017C00100808F2243E77D00000000004400
+:10FC100045C101000000662017A4010068010040F2
+:10FC2000439901005C012EF280B001003E000040CB
+:10FC300080CE0100878F2440813200000000004602
+:10FC400081C00100888F0094E5B10000020062408D
+:10FC50007ECD01000000005781C0010000002E1081
+:10FC600048B1010003000040F08D010000000008D1
+:10FC7000F0B1010058010005E0C901000000004496
+:10FC800061B101000000001062B101008E8FA84038
+:10FC9000813200001B8400881CB0000000000005B9
+:10FCA00048B101009A8F2240AF6F00000040000869
+:10FCB00094DC01008898004081320100988F224036
+:10FCC000976C0000E295000800300100D58D0040DF
+:10FCD00081B200000000004005B00100D58D004752
+:10FCE000198000009A8F43486131000000500008DD
+:10FCF00062DD0100A08F2840053000009B8F224864
+:10FD0000777D0000E2951B0800300100D58D004092
+:10FD100081B20000D58D1B471980000035000040DE
+:10FD200047990100010063F384C80100A58FA04337
+:10FD3000856C00000000634085B00100A800004011
+:10FD40004399010037002FF024B00100010063F354
+:10FD500082CC0100B08FA2419E060000D58D2244C6
+:10FD600083700000360000404399010058003D4375
+:10FD7000E7E10100D58D1FF0246C00006399004875
+:10FD800081300100B08A2341836C0000B08A0047B3
+:10FD900081B0000058003D4385E00100000000F8FC
+:10FDA00036B00100000000F000B001002800004063
+:10FDB0008398010004980047613101001B8400888A
+:10FDC0001CB0000000002D0348B1010008002DF018
+:10FDD00094B00100000000F88EB0010090002DF0FA
+:10FDE00014B001000000000548B10100848EA2405B
+:10FDF0008F7C0000BE8F22478F7C0000848E0048DD
+:10FE0000199000002D90004081B2000036002D5D59
+:10FE100005B4010037002DF380B00100000000F3AD
+:10FE20008EB001005C003D4381E00100A8002DF090
+:10FE300094B00100000000F024B001002000001088
+:10FE400086DC01004080000344C90100E394004ABD
+:10FE5000F031010036002F5C1F900100CC8FA250C2
+:10FE60008F50000034002040E1B10100D58D0040EA
+:10FE700081B200000000634181C00100CF8FA04328
+:10FE8000816C00000000634081B001003700204712
+:10FE9000E6B10100D58D2247803200000400004702
+:10FEA0000CF401000000004F8F840100E48F224712
+:10FEB0000C6C000058003D4381E00100E48F1FF00E
+:10FEC000246C00000000005C1F8001000080001016
+:10FED00042C90100DD8F2240E36D000000000045B3
+:10FEE00061B101004000001062DD0100DA8FA8401E
+:10FEF000813200001B8400881CB00000DD8F42406E
+:10FF000005300000000000449393010000001A5DDA
+:10FF100069930100E28F23410D6C0000BF8F000543
+:10FF200048B100006399000548310100B08A0048DB
+:10FF300081B00000D58D22408F6C00003698005FA4
+:10FF400081300100D58D004081B20000A200004048
+:10FF500043990100000000F384B00100A6002D4980
+:10FF600019900100020000F280F40100B8002D4059
+:10FF700081B20100000000F280C0010000000040DA
+:10FF800082F801001900004081980100F38FA04021
+:10FF9000826C00002C01004081980100F38FA34087
+:10FFA000826C00000000004180B00100F58F204C01
+:10FFB000856C00000000004185C0010086002040E3
+:10FFC000E4B10100A2002042E6B10100D58D00405D
+:10FFD00081B20000C597005081300100D58D0040EE
+:10FFE00081B200000480000342C90100040022F035
+:10FFF00080300000000000408DB0010055990040A5
+:020000021000EC
+:1000000087300100B0002F5C1F900100000060F0FD
+:1000100080C001003698005F81300100D58D00401E
+:1000200081B200000400004081B20000D58D22465C
+:10003000197C0000A000004047990100010062F215
+:1000400096CC0100D58DA640813200003698004A3A
+:10005000813001000B98004695300100D58D00409D
+:1000600081B20000D58D2249197C00008600004035
+:1000700047990100010062F280CC0100D58DA640B5
+:10008000813200003698004A813001000B98004709
+:1000900095300100D58D004081B20000749500407C
+:1000A00081320100D58D005C1F900000D58D00408D
+:1000B00081B20000D58D004081B20000BA0000403E
+:1000C00047990100010062F280C801001990904038
+:1000D00080320000FFFF624081980100A4000040D0
+:1000E00047990100D58D2240E56D0000D58D004176
+:1000F000E5C10000C597004D81300100D58D00405D
+:1001000081B200005C00004047990100040022F029
+:100110009630000000000040E1B1010000800003C3
+:1001200044C901000000004BE0B1010000000040A4
+:100130008DB0010055990040873001008B000040D0
+:1001400047990100299080F396300000000000409C
+:10015000E78101000000004719900100D58D005C87
+:100160001F9000003400004045990100010000404C
+:10017000F599010000110040E5990100DD9500406E
+:10018000813201003E90A20880320000370000401A
+:1001900047990100000000F382B0010000006351A4
+:1001A00083D001003400004047990100010063F34F
+:1001B00084CC010036909F428032000000006342F0
+:1001C00085B001000000004503F0010000000001BF
+:1001D00000C001003890375C613100000000001B56
+:1001E00062B101003990A84B191000000000000016
+:1001F00062B101003B90A84081320000058A17409F
+:1002000081B200000080000342C9010090002DF07F
+:1002100094B00100AC002DF030B0010035002DF09D
+:1002200028B0010058003E43E7E10100010000183A
+:10023000F0C901000000004AE0B1010038002000D0
+:10024000E0B101003C00201BE0B101004000204073
+:10025000E1B10100000000402BB001001A980040FD
+:100260000D3001000000001816C001004D90A014D0
+:10027000164400000000004117C001000E0000A25B
+:1002800044C9010000000018F8B10100B0002D14AD
+:10029000F8B1010010500040879801005690224AA2
+:1002A000197C00000030004386C801000030000BBC
+:1002B00016C801005690A4408132000000000041A1
+:1002C00017C0010001006E4386980100519800306C
+:1002D000813001005A90A041174000000000004109
+:1002E00017C001006190224A197C0000080000A29A
+:1002F00044C90100CC002DABF9B10100000000ABF6
+:1003000017C001006090A0F01644000000000041FA
+:1003100017C00100000064F082B0010090000040AE
+:10032000459901000000604131C00100BC0000405F
+:10033000439901006790060C80320000A00020F273
+:10034000E4B1010004000946191000009C010040BE
+:1003500045990100FFFF000B988801008B002D508C
+:1003600017F001006C90904C164000000000004116
+:1003700017C001006E902243E77D0000000000449A
+:1003800045C101000000662017A40100680100407B
+:10039000439901005C012EF280B001003E00004054
+:1003A00080CE01007590244081320000000000469C
+:1003B00081C0010076900094E5B100000200624027
+:1003C0007ECD01000000005781C0010000002E100A
+:1003D00048B1010003000040F08D0100000000085A
+:1003E000F0B1010058010005E0C90100000000441F
+:1003F00061B101000000001062B101007C90A840D2
+:10040000813200001B8400881CB000000000000541
+:1004100048B1010086902240AF6F00000040000804
+:1004200094DC010088980040813201008190A24054
+:10043000976C000035000040479901008A90004009
+:1004400005B000008690434861310000005000086C
+:1004500062DD01008790A8400530000035001B4098
+:1004600047990100010063F384C801008D90A04307
+:10047000856C00000000634085B00100370000403B
+:1004800047990100010063F382CC01008B0000401A
+:100490004799010000000045E79101003698005F90
+:1004A00081300100D58D004081B20000370000404E
+:1004B000479901007F9600F3943001002D90224A65
+:1004C00080320000AB8E004081B200003700004057
+:1004D000479901007F9600F3943001007B8E224AF9
+:1004E00080320000AB8E004081B200003600004038
+:1004F00043990100000000FB12B001000F0000F35F
+:1005000090880100040000F30CF40100A58E22067F
+:10051000906C00005C003D4313E00100A8002DF04A
+:1005200094B0010037002FF024B0010036002A50AB
+:10053000E7D101000000634113C00100A790A04370
+:10054000136C000000000040E7B10100E1940010CE
+:10055000863001001B8400881CB00000A990420571
+:10056000483100000000004493930100A58E1A5DFD
+:100570006993000036002D1086B001005C003D43F9
+:10058000E7E10100A8002DF094B0010035002FF044
+:1005900024B0010001006BFB84C80100B490A043AB
+:1005A000856C000035002040E7B1010000000040EC
+:1005B00081B20100010063F312C80100B790A043AB
+:1005C000136C000000000040E7B101004080000310
+:1005D00044C90100E394004AF03101001B84008803
+:1005E0001CB00000BA9042054831000000000044F1
+:1005F0009393010000001A5D6993010037000040E9
+:1006000047990100110063F382CC0100A98F2241B8
+:100610009E060000350000404399010058003D430C
+:10062000E7E10100000000F836B00100B38F00F0F0
+:1006300000B000005E012D0548B10100C59047F2F1
+:100640001230000000993F4213F00100CA90224787
+:10065000E77D00006B841F881CB00000C490004040
+:1006600081B2000000000047E791010000001F4236
+:10067000199001007500004061990100CC90A8B16B
+:100680000C3000005C970010943001001B8400883F
+:100690001CB000005E012E0548B10100C0A83D4617
+:1006A0000DE001000000004097B00100D69022400C
+:1006B000E16D00000400024197400000D39000501B
+:1006C00043C10000E290224B803200000000624BE8
+:1006D000129401000900000796E40100000000A741
+:1006E00097C001003000001094C801000080004A4B
+:1006F0004499010000000042F1B101005E01004B8D
+:10070000F0C901005E010005E0C9010000000044DD
+:1007100061B101002000004A62DD0100E090A840C4
+:10072000813200000080001044C901000000005028
+:10073000F1B101000400000996E40100000068A87E
+:1007400097C00100D4000005E0C90100000000448A
+:1007500061B101000000001062B10100E890A84002
+:10076000813200001B8400881CB0000000993F42C9
+:1007700013F00100EC904740813200003F0000F38D
+:100780009688010000000040E7B1010000001F55FD
+:1007900061B101000000000662B10100F090A840C4
+:1007A00081320000F590224B803200000000004BA7
+:1007B00062B10100F390A840813200000000009770
+:1007C00013B001000000009697B00100FB902009D3
+:1007D000966C0000FB901F09962400006B84008833
+:1007E0001CB00000F690004081B20000C597005791
+:1007F00081300100C08D000548B100002E0000408E
+:1008000043990100019122F380320000C597004214
+:1008100081300100058A004081B200003698005204
+:1008200081300100C08D004219800000C597003A58
+:10083000813001003698005281300100C08D0040A7
+:1008400081B200000000004005B00100DF960040CA
+:1008500095300100C08D2240956C00000C91A240A3
+:100860001F7C0000E295004081320100058A0040B3
+:1008700081B200000480000342C90100000000F2C0
+:1008800002B001008A960052953001009196004B0B
+:1008900002B00000058A004081B200000A990040C1
+:1008A000953001001891A208803200001891A2161C
+:1008B00080320000058A2242197C00000000004BB3
+:1008C00019900100C597003A81300100058A004067
+:1008D00081B20000002300A616B001001B91831E08
+:1008E000803200000008000B16DC01000000000050
+:1008F0002AC001000E980008803001001F91005EA0
+:10090000179000002F98004361310100EF940040E0
+:100910008D300100169800071614010000800010A9
+:1009200042C9010027912240E36D0000000000430E
+:1009300061B101004000001062DD01002491A84077
+:10094000813200001B8400881CB00000B797005E55
+:1009500005100100E2950040813201002B9122092F
+:10096000803000003698004013300100C58D00052E
+:1009700048B100000F97004081320100C08D004057
+:1009800081B200000000004A1F9001003291224312
+:100990003D7C00000000004419900100000000436D
+:1009A0003D800100339100421990000014002D4554
+:1009B0001F9001008F91831E803200008F910044B0
+:1009C00019900000D4950040813201004791A2089F
+:1009D000803200004791A216803200004391A2426B
+:1009E000197C00000082000204DC0100A098004095
+:1009F00047990100E9890041893001004091A241F5
+:100A0000197C0000E295004081320100058A004017
+:100A100081B200008A960015943001009196004B37
+:100A200002B00000058A004081B200000F9700402C
+:100A3000813201000000004B19900100C597003A77
+:100A400081300100058A004081B200004A912242B3
+:100A5000197C00000F970040813201004B9100404B
+:100A600081B20000DF96004081320100779122417F
+:100A7000197C0000C000001598C801007791A00BF8
+:100A8000996C00003000001080C801000080004018
+:100A90004499010000000050F1B101000000000382
+:100AA000F0B101000000004261B10100000000400F
+:100AB00062B101005391A800E03100001B8400885E
+:100AC0001CB000000000000548B10100C000001586
+:100AD00098C8010030002E0B99D0010000006A5028
+:100AE00099C00100C000620180CC01000C800003AD
+:100AF00042C901002D002DF022B001000000004C81
+:100B000080C001000000005C23800100D4003F4150
+:100B1000E7E101000B000011E4F501002F00204780
+:100B2000E7B501006491230B816C00000000004FC9
+:100B3000E59101000000000880B001000000000BFA
+:100B400003B001000000001502D001000E98000063
+:100B50002A4001000000004361B101004000001084
+:100B600062DD01006991A840813200001B84008889
+:100B70001CB00000E295000548310100C0000001F2
+:100B800080CE010075912611003000001000000099
+:100B90002AC801000000000880B001000000000128
+:100BA00080C00100C00000409998010000000001D1
+:100BB00098D001000E98004C02300100C0000040A7
+:100BC000039801007C91004081B2000030002F08A2
+:100BD00080B00100C0000015F4C90100C000000190
+:100BE000E4CD0100C0000040039801000E98000011
+:100BF0002A400100819122441F7C0000AC002F405C
+:100C000013B0010000000001E0C10100B00000408D
+:100C10004799010082910001E0D10000EF9400406B
+:100C20008D300100806300A616B001001698000701
+:100C3000161401000080001042C901008A91224070
+:100C4000E36D00000000004361B1010040000010AE
+:100C500062DD01008791A840813200001B8400887A
+:100C60001CB00000B797005E051001008D912209AD
+:100C7000803000003698004081320100C08D0005B0
+:100C800048B100008F91004A1F9000000000000052
+:100C900010B0010024002D1510C0010028002DF017
+:100CA00016B0010022002DF026B0010014002FF232
+:100CB0000CB0010000000001E0D1010000000010B4
+:100CC00032B001000000000B1BB0010004001F1532
+:100CD0001A5000000000004023B001000000000195
+:100CE0002AB001007197004035B000002F0020406D
+:100CF000E7B10100D391A2451F7C00002400200B26
+:100D0000E0B1010028002013E0B10100220020061C
+:100D1000E4B10100A991225C1F7C00000000005C8E
+:100D20001F8001003080001042C90100A9912240BB
+:100D3000E36D00000000004761B1010040000010B9
+:100D400062DD0100A591A840813200001B8400886B
+:100D50001CB000000000000548B10100008000192F
+:100D600042C90100CC912240E36D0000BA912242B9
+:100D7000197C0000379700408132010089950040BE
+:100D800081320100C791224B8032000000000043F5
+:100D900061B101004000001062DD0100B091A84087
+:100DA000813200001B8400881CB00000B6912241F3
+:100DB000197C0000F895004011300100B791000542
+:100DC00048B10000E295004081320100B99122094A
+:100DD0008030000036980040813201006F8400406E
+:100DE00005B0000037970040813201008595004032
+:100DF000813201000000004361B101004000001099
+:100E000062DD0100BD91A840813200001B84008892
+:100E10001CB00000C3912241197C0000F8950040ED
+:100E200011300100C491000548B10000E295004076
+:100E300081320100C69122098030000036980040BE
+:100E4000813201006F84004005B0000000000043C3
+:100E500061B101004000001062DD0100C891A840AE
+:100E6000813200001B8400881CB0000000000005D7
+:100E700048B10100CF912241197C0000F895004053
+:100E800011300100D091000548B10000E29500400A
+:100E900081320100D2912209803000003698004052
+:100EA00013300100C58D004005B00000008000191E
+:100EB00042C90100DA912240E36D000000000043C6
+:100EC00061B101004000001062DD0100D691A84030
+:100ED000813200001B8400881CB000000000000567
+:100EE00048B101000000004005B00100DE91224140
+:100EF000197C0000F895004011300100DF910005D9
+:100F000048B10000E29500408132010008002D0A3E
+:100F100084B00100000000F082B001001400204005
+:100F2000E1B10100E491031E80320000E59100412F
+:100F300087B0000021000040879801000097004022
+:100F4000813201000000005C1F900100E99122093C
+:100F5000803000003698004013300100EC912244AC
+:100F6000197C00003698004F8130010000000044D9
+:100F700019800100C08DA24A1F7C0000C58D004071
+:100F800081B20000BA002040E5B10100F2919C1747
+:100F900080320000CC0000404399010013990040CA
+:100FA00081320100A398004013300100C0000040CE
+:100FB00043990100C4002DF082B00100EE9800F0CA
+:100FC00084300100E295004081320100C58D220984
+:100FD000803000003698004013300100C58D00407D
+:100FE00081B200002E00004043990100FE91224092
+:100FF000E76D000032000040439901000692A240D4
+:10100000E56D0000CC960040813201002400200BE9
+:10101000E0B1010028002013E0B101002200200609
+:10102000E4B101001400200AE0B10100C58D2209DD
+:10103000803000003698004013300100C58D00401C
+:1010400081B20000CC9600408132010085960040BC
+:101050008132010014922241197C00000000000B33
+:1010600099B0010004001F1598500000149220014F
+:10107000986C00007000000348C9010000002E4673
+:101080001F90010000000050F1B1010000000003BA
+:10109000F0B101000000004261B10100A00000A415
+:1010A00062DD01001192A800E0310000000000059F
+:1010B00048B10100AC002F0010B001000000000199
+:1010C000E0C1010014002F1510C001000000000A4B
+:1010D00080B001000000600180D0010000000047E6
+:1010E000199001009691220980320000369800097B
+:1010F000803001009691004013B000000080000392
+:1011000042C90100000000F082B00100130000405D
+:10111000879801000000004C43C10100009700F0D7
+:1011200084300100C08D005C1F9000002C00204026
+:10113000E7B101002D002040E7B10100C08D004261
+:1011400019800000F2960040813201000B9800489F
+:10115000953001000000004561B101004000001021
+:1011600062DD01002992A840133000001B84008832
+:101170001CB000002F92000548B100002E920040E4
+:1011800013B000000000000012B001000800004091
+:101190004399010014002DF082B00100040022F0F8
+:1011A0008430000013000040879801000097004041
+:1011B000813201000000005C1F900100479200098D
+:1011C00000B00000C08D8742191000008B002F472F
+:1011D00019800100C08D0040E79100002F00004001
+:1011E0004799010045922247E77D0000669500403F
+:1011F000E731010045922200803200004092A24077
+:101200001F7C0000E29500408132010045920040C1
+:1012100081B20000300000404399010032002DF2FD
+:1012200094B001008A9600F2023001009196004BC2
+:1012300002B000000000000548B1010046920040E5
+:1012400001B000000000004005B001004C922200F7
+:10125000803200004B92A242197C0000DF960040D1
+:10126000813201004C92004081B200000F97004093
+:1012700081320100D892225C1F7C00000000005CDB
+:101280001F8001000080001042C9010054922240DA
+:10129000E36D00000000004561B101004000001056
+:1012A00062DD01005192A840813200001B84008859
+:1012B0001CB00000D892000548B10000D495004051
+:1012C000813201005B92A208803200005B92A2167C
+:1012D00080320000C597004D81300100008200027D
+:1012E00004DC0100058A004081B200007400004067
+:1012F00043990100000000F882B00100000000F0F6
+:1013000084B001000000004196B0010069922242C1
+:10131000961400000080001044C901006400684079
+:101320009798010000000041F0B101000000004268
+:10133000F0B1010070000005E0C9010000000045A7
+:1013400061B101002000001062DD01006692A8403A
+:10135000813200000000005C1F9001000000004589
+:1013600061B101004000001062DD01006A92A85CDA
+:101370001F0000001B8400881CB000005E012D05CA
+:1013800048B101006E9247F21230000000993F42CE
+:1013900013F0010073922247E77D00006B841F88E1
+:1013A0001CB000006D92004081B2000000000047B8
+:1013B000E791010004001F0996E40100008000107D
+:1013C00044C9010000000044F1B10100000068A818
+:1013D00097C0010000000003E0B10100008000039D
+:1013E000449901000000004461B1010000000010B8
+:1013F00062B101007B92A840E13100001B840088AB
+:101400001CB0000000993F4213F001007F92470595
+:10141000483100003F0000F39688010000000040C2
+:10142000E7B1010000001F4081B201008792224B0A
+:10143000803200000000005561B101000000004B47
+:1014400062B101008592A8408132000000000007CF
+:1014500016B001000062000B16DC0100669500402A
+:10146000813201009F922200803200001597005FB8
+:101470000110010089922240956C0000008000104C
+:1014800044C9010000000050F1B101000000000358
+:10149000F0B101000000004261B101000000001045
+:1014A00062B101009192A800E03100001B84008825
+:1014B0001CB000000000000548B1010004800003DA
+:1014C00042C90100000000F202B001008A960052F9
+:1014D00095300100E295004081320100899222415D
+:1014E000975000000C80000342C90100000000F08A
+:1014F00000B001000000005C018001009196004BEB
+:1015000002B000008992000548B100001698004022
+:10151000033001001780000344C9010000F0000CF3
+:10152000968801000000634C97F0010010800003D2
+:1015300044C90100000000ABE1B10100B797005EB3
+:1015400005100100030000071AF40100070000075E
+:101550001688010000B5000D46C90100A99230406F
+:10156000813200000000000BE681010000B7000D91
+:1015700046C901000000000BE68101001000100FB9
+:1015800094F40100E999005F950401006B96004016
+:1015900081320100B3922250FD7F0000B19243409E
+:1015A0008132000000001B4131D3010000002E05F4
+:1015B00048B1010000000040E1B10100000000401E
+:1015C0000FB00100CD95004181300100058A004037
+:1015D00081B20000D495004081320100C592A2087A
+:1015E00080320000C592A216803200000082000204
+:1015F00004DC01000000004503F0010000000001D0
+:1016000000C00100BE92375C613100000000001B89
+:1016100062B10100C292284081320000BF920040B6
+:1016200081B200000000000062B10100C292A84037
+:1016300081320000058A174081B200007400224008
+:10164000F1B1010000000040E1B101000B98004A37
+:1016500095300100F296005C1F1001005B92004083
+:1016600081B200002F00004047990100D692224726
+:10167000E77D000066950040E7310100D692220028
+:1016800080320000D192A2401F7C0000E295004011
+:1016900081320100D692004081B20000300000404B
+:1016A0004399010032002DF294B001008A9600F2B5
+:1016B000023001009196004B02B0000000000005CE
+:1016C00048B101000B98004895300100F296005C8B
+:1016D0001F100100DB928742191000008B002F477A
+:1016E0001980010000000040E79101003698004297
+:1016F00081300100C08D004081B20000F2960040B0
+:1017000081320100C08D005C1F900000BA002040B3
+:10171000E5B10100A398004081320100C000004003
+:1017200043990100C4002DF082B00100EE9800F052
+:1017300084300100E2950040813201003698004576
+:1017400081300100C08D2242197C0000C597003A0B
+:1017500081300100C08D004081B2000004000040D3
+:1017600081B20000D495004081320100F092A208BD
+:1017700080320000F092A21680320000C597004728
+:10178000803001000082000204DC0100058A004074
+:1017900081B200001080000344C9010000E100A6EE
+:1017A00084B0010000000040F1B1010000000040E1
+:1017B000F1B101000000600784940100B797005E5A
+:1017C00005100100C08D004081B200008A00004079
+:1017D00047990100E2950041E7410100C58D0040B5
+:1017E00081B20000CC960040813201008596004015
+:1017F00081320100000000012CB001000000001542
+:1018000010B001000000000010C0010004001F0A19
+:101810002C5000000000001032B001000700000B47
+:10182000968801000C932647972400000000004191
+:1018300097C001000C93234B0C6C00004998004B9F
+:10184000043001000000005033C00100000000021D
+:1018500010C001000000000216C0010000000006D8
+:1018600004B001004998004B045001000D93004062
+:1018700081B2000049980006043001001393A24889
+:101880001F7C0000119384481F100000AC00004032
+:10189000479901001393000AE0C100000000000A0C
+:1018A00002B00100EF9400018C3001000000004301
+:1018B00061B101004000001062DD01001493A840F6
+:1018C000813200001B8400881CB00000000000056D
+:1018D00048B101000000000210C00100219322065F
+:1018E000145000003A9700451F0001000093225C4D
+:1018F0001F7C00000000004761B1010040000010A3
+:1019000062DD01001D93A85C1F0000001B8400889D
+:101910001CB000000093000548B100000000000B5F
+:101920001BB0010008002D4085B00100000000F050
+:1019300082B001000000004005B0010000970041A6
+:10194000873001000000004561B101004000001037
+:1019500062DD01002793A840813200001B840088CB
+:101960001CB000000000000548B101002D932209C1
+:10197000803000003698004013300100319322443B
+:10198000197C00003698004F813001003193A24746
+:101990001F7C00000000004419800100FF070008C0
+:1019A000008C01003F93224A1F7C00003793A2164F
+:1019B00002300000E2950040813201002F002040FB
+:1019C000E7B10100C08D004081B200002D002D085C
+:1019D0002AB001003B932242197C00000F9700407F
+:1019E000813201003C93004081B20000DF9600404C
+:1019F0008132010030002E002AD0010032002A1569
+:101A0000E4B10100C08D0016E4B10000529322162B
+:101A100002300000000000082AB001000A990040CE
+:101A2000953001004493A240116C00005393224072
+:101A30002D6C0000AC00004047990100B0002B0164
+:101A4000E0C10100002B00A616B00100000000015B
+:101A5000E0D101000E980008803001004B93005E39
+:101A6000179000002F9800436131010000000043EF
+:101A700061B101004000001062DD01004C93A840FC
+:101A8000813200001B8400881CB0000000000005AB
+:101A900048B101001698000716140100B797005EC0
+:101AA00005100100E2950040813201002F00204026
+:101AB000E7B10100C58D004081B200000000000BBD
+:101AC0001BB0010004001F151A500000609320167F
+:101AD0001A6C00007000000348C901000000225089
+:101AE000F1B1010000000003F0B1010000000000AE
+:101AF000E0B101000000004261B10100A00000A4BB
+:101B000062DD01005D93A8461F1000000000000583
+:101B100048B101000000000010B0010000000015F5
+:101B200010C001000000000A2AB001000000000AF5
+:101B30002CD00100AC002F4023B0010067938445F6
+:101B40001F1000006893000AE0C100000000000AB6
+:101B500002B001007197004035B00000008000190C
+:101B600042C9010070932240E36D00000000004371
+:101B700061B101004000001062DD01006C93A840DB
+:101B8000813200001B8400881CB0000000000005AA
+:101B900048B101008093A2021A50000081932240B4
+:101BA0002D6C00000080001044C9010000000050AE
+:101BB000F1B1010000000003F0B10100FF070008CF
+:101BC000E08D01000000004261B101000000001042
+:101BD00062B101007793A840813200001B84008825
+:101BE0001CB000000000000548B101002F00204794
+:101BF000E7B501000C80000342C90100100000F0AD
+:101C000010C80100F00700401B9801008193005CA0
+:101C1000118000000000000210C00100F895004093
+:101C20001F0001000000000548B101008593230D4D
+:101C30002C6C0000000000401F9001008E93224693
+:101C40001F7C0000000000461F8001007080000320
+:101C500042C901008E932240E36D00000000004263
+:101C600061B101004000001062DD01008A93A840CC
+:101C7000813200001B8400881CB0000000000005B9
+:101C800048B1010008002D4085B00100000000F0BF
+:101C900082B001000000004005B001000097004143
+:101CA000873001000000004561B1010040000010D4
+:101CB00062DD01009393A840813200001B840088FC
+:101CC0001CB000000000000548B1010099932209F2
+:101CD0008030000036980040133001009D9322446C
+:101CE000197C00003698004F813001009D93A24777
+:101CF0001F7C00000000004419800100FF0700085D
+:101D0000008C0100B293224A1F7C0000A393A2160C
+:101D100002300000E2950040813201002F00204097
+:101D2000E7B10100C08D004081B200002D002D08F8
+:101D30002AB00100AE932242197C0000A793A2F3BF
+:101D400084300000000000A585B0010000000041C3
+:101D500085D00100D4003E4185E00100AB932240D4
+:101D60001F7C00000000005A119001000B000008C9
+:101D7000E4F501000F97004081320100AF9300406D
+:101D800081B20000DF9600408132010030002E0059
+:101D90002AD0010032002A15E4B10100C08D0016DE
+:101DA000E4B10000B593A21602300000E2950040B5
+:101DB000813201000494004081B200002D002D0802
+:101DC0002AB00100C39322471F7C0000BF93224228
+:101DD000197C0000BA93A2F384300000000000A533
+:101DE00085B001000000004185D00100D4003E41D3
+:101DF00085E00100BE9322401F7C00000000005AD5
+:101E0000119001000B000008E4F5010058012D00BD
+:101E10002AD0010060012DF010B00100000000F098
+:101E20002CB001004791004081B200000A990041A6
+:101E300095300100CB93A20880320000CB93A2160C
+:101E4000803200000000004197B00100C993230DCB
+:101E5000026C00000000004197C001009196004B09
+:101E600002B000000494000548B10000AC002F014E
+:101E700014B00100B0002B01E0C10100002B00A64E
+:101E800016B0010000000001E0D10100DB93230D3A
+:101E9000026C00000080001044C9010000000050E6
+:101EA000F1B1010000000003F0B1010000000042A8
+:101EB00061B101000000001062B10100D493A800DC
+:101EC000E03100001B8400881CB000000000000509
+:101ED00048B101000C80000342C90100100000F06D
+:101EE00022C801000000005C238001000000000106
+:101EF00084B00100DE93230D026C00000000000D91
+:101F000002B001000000000880B00100E39322400D
+:101F10001B6C00000E98000184500100EB932240DE
+:101F2000856C00000000000180C0010010800010DE
+:101F300046C901000000004F43810100000000423B
+:101F4000F0B1010020000040F0C9010000000016BF
+:101F5000F0B101000000004361B10100A00000A148
+:101F600062DD0100E993A811E0310000FA93005E00
+:101F700017900000EE93230D026C00000000000D8E
+:101F800002B001000000000184D00100F393224060
+:101F90001B6C00002F98004361310100FA9322402E
+:101FA000856C00000000000112C0010010800010CC
+:101FB00046C901000000004F4381010000000042BB
+:101FC000F0B1010000000009F0B1010000000018AC
+:101FD000F0B10100A00000A162DD0100F893A8119A
+:101FE000E03100000000004361B10100400000103A
+:101FF00062DD0100FB93A80A023000001B84008808
+:102000001CB00000E2950005483101000294230D48
+:10201000026C0000FF070011008C0100E2950040F7
+:10202000813201001698000716140100B797005E70
+:10203000051001002F002040E7B10100C58D0040D0
+:1020400081B200000080000342C90100000000F8D6
+:1020500082B00100000000F88CB00100000000F028
+:102060008EB00100C996004013300100000000400E
+:1020700085B001000097004187300100859600403F
+:10208000813201000080001042C9010015942240F5
+:10209000E36D00000000004561B101004000001048
+:1020A00062DD01001194A840813200001B84008889
+:1020B0001CB000000000000548B10100179422097F
+:1020C0008030000036980040133001000000000B03
+:1020D0001BB00100000000151AD001001E94A2419F
+:1020E000197C00000A99004095300100000000169C
+:1020F00080B201002794270880320000449300003A
+:102100002AC000000A990041953001000000001625
+:1021100080B201002294270880320000CB93000097
+:102120002AC000000000004197B001002594230D53
+:10213000026C00000000004197C001009196004B26
+:1021400002B000000000000548B10100C08D22422D
+:10215000197C0000C597003A81300100C08D004015
+:1021600081B200002B94004A1F9000000A960000E4
+:10217000103001000000001510C001000000001028
+:1021800032B001000700000B968801003994264701
+:10219000972400000000004197C001003994234BB0
+:1021A0000C6C00004998004B043001000000005006
+:1021B00033C001000000000210C001000000000256
+:1021C00016C001000000000604B001004998004B51
+:1021D000045001003A94004081B200004998000682
+:1021E000043001003F94A2441F7C00000000000B5B
+:1021F0001BB001000000000A2CD001000000000A02
+:1022000002B00100EF9400018C3001000080001941
+:1022100042C9010046942240E36D000000000043E3
+:1022200061B101004000001062DD01004294A8404D
+:10223000813200001B8400881CB0000000000005F3
+:1022400048B101000000000210C001004F942206B6
+:10225000145000003A9700451F0001002D94225CA5
+:102260001F7C00000000004761B101004000001029
+:1022700062DD01004B94A85C1F0000001B840088F5
+:102280001CB000002D94000548B1000008002D404E
+:1022900085B00100000000F082B0010000000040A5
+:1022A00005B00100009700418730010000000045A3
+:1022B00061B101004000001062DD01005494A840AB
+:1022C000813200001B8400881CB000000000000563
+:1022D00048B101005A94220980300000369800402D
+:1022E000133001005D942244197C00003698004FA1
+:1022F000813001000000004419800100FF07000840
+:10230000008C01006B94224A1F7C00006394A2168B
+:1023100002300000E2950040813201002F00204091
+:10232000E7B10100C08D004081B200002D002D08F2
+:102330002AB0010067942242197C00000F970040E8
+:10234000813201006894004081B20000DF960040B5
+:102350008132010030002E002AD0010032002A15FF
+:10236000E4B10100C08D0016E4B100004093A21654
+:1023700002300000E2950040813201002F00204031
+:10238000E7B10100C58D004081B200000A96004A05
+:102390001F1001005593001032B000008A00204049
+:1023A000E7B101007594A241197C0000E29500405C
+:1023B000813201007894004081B200008A960015B5
+:1023C000943001009196004B02B00000000000051F
+:1023D00048B101007A942242197C0000C597003A66
+:1023E000813001003698004581300100C08D0040E9
+:1023F00081B20000069200451F900000CC9600407C
+:102400008132010085960040813201005593000120
+:102410002CB00000D4950040813201008D94A208B8
+:10242000803200008D94A2168032000000820002EB
+:1024300004DC01000000004503F001000000000181
+:1024400000C001008694375C613100000000001B71
+:1024500062B101008A9428408132000087940040D4
+:1024600081B200000000000062B101008A94A8401F
+:1024700081320000058A174081B20000580120080F
+:10248000E0B1010060012016E0B10100CC960047E8
+:102490001F10010085960040813201005593000114
+:1024A0002CB00000D49500471F100100A094A20892
+:1024B00080320000A094A216803200009C94A242B8
+:1024C000197C00000082000204DC0100A09800409A
+:1024D00047990100E9890041893001008A96001579
+:1024E000943001009196004B02B00000058A004034
+:1024F00081B200000F970040813201000000004BC4
+:1025000019900100C597003A81300100058A00400A
+:1025100081B2000058012008E0B1010060012016DE
+:10252000E0B101000A9600103230010055930040DE
+:1025300013B00000D495004081320100B194A2088C
+:1025400080320000B194A2168032000000820002A6
+:1025500004DC01000000004503F001000000000160
+:1025600000C00100AA94375C613100000000001B2C
+:1025700062B10100AE94284081320000AB9400406B
+:1025800081B200000000000062B10100AE94A840DA
+:1025900081320000058A174081B2000000800003EC
+:1025A00042C90100000000F882B00100000000F8FC
+:1025B0008CB00100000000F08EB00100C996004010
+:1025C000133001000000004085B001000097004179
+:1025D00087300100859600408132010000800010A4
+:1025E00042C90100C0942240E36D00000000004594
+:1025F00061B101004000001062DD0100BC94A84000
+:10260000813200001B8400881CB00000000000051F
+:1026100048B10100479122098030000036980040FF
+:10262000133001004791004081B2000014002D4595
+:102630001F9001008F91004419900000C894A2419E
+:10264000197C00000000004A1F900100FA9200402F
+:1026500081B20000CC96004A1F1001008596004010
+:1026600081320100559300012CB000000A96004011
+:10267000813201005593001032B0000006920045EF
+:102680001F9000000000004137C30100000000411E
+:1026900033C301003600000102CC01000000D2402B
+:1026A00081B20000D49485178032000000009F485A
+:1026B00003D00000D6949C178032000000009F4C8D
+:1026C00003D000000000800134C3010002002D117E
+:1026D00010C10000DB94004043C10000DB940050B7
+:1026E00043C10000200000A142C90100DF94224044
+:1026F000E56D00000400A240E57D00000000004000
+:1027000023B00100000080491F9001000000A24199
+:1027100023D00000DB94005043D100004080000330
+:1027200044C901000000004AF0B10100000000406F
+:10273000F1B1010000000012F0B10100E695004186
+:10274000E13101000080004344C901001000004055
+:10275000F199010000000048F0B1010000000049BB
+:10276000F0B1010040000003E0C901000000004595
+:1027700061B101000000004362B101000000A84007
+:1027800081B20000EC94004081B20000BA00204009
+:10279000E5B10100B0002F018CD00100000000461F
+:1027A000E0C10100AC002F4013B00100CC002D01AE
+:1027B000E0C10100F6949C1780320000139900409C
+:1027C00081320100F8942247197C00000000005F6C
+:1027D00013900100A398004719100100C0002D4478
+:1027E0001F900100C4002DF082B00100EE9800F0AF
+:1027F00084B0000090002D0548B101000D95A24B5A
+:102800001F7C00006095A24C1F7C00000D951F1CD2
+:10281000E06D00001095A20180320000A8002D4656
+:102820008FB0010006951F1CE06D0000B400004051
+:1028300043990100089522F03A6C00005D951FF065
+:102840003A6C00000000A24080B200000000804FFF
+:102850008FB001008A000040439901005E9520423C
+:10286000E76D00000C952240803200000000805986
+:102870008FB00100000080588FB001000F952240FA
+:10288000803200000000805C8FB001000000805B9F
+:102890008FB00100AC00004043990100B0002DF062
+:1028A00084B001001495A242246C00001D9523F011
+:1028B000026C00001A95A2F0803200005F95A242DF
+:1028C000246C00005F95A241036C00001995A240A2
+:1028D00080320000000080518FB001000000805263
+:1028E0008FB001005F951F12845000005F95A0011A
+:1028F000846C00000D95004081B200008B00004008
+:10290000439901004895A246E77D0000140000406D
+:10291000439901003A9522F0143000002695200AD0
+:10292000026C00003795031E803200002595A240FE
+:1029300080320000000080448FB001000000804918
+:102940008FB001002B95220A026C00002E95A24147
+:10295000197C00002A95A2408032000000008055BA
+:102960008FB00100000080568FB001002D95A2406D
+:1029700080320000000080438FB0010000008048DA
+:102980008FB001000000000182B001000000000AC9
+:1029900082D0010034952091836C00003395A240D1
+:1029A00080320000260080408F9801002700804080
+:1029B0008F9801003695A240803200001F008040B1
+:1029C0008F980100200080408F9801003995A24027
+:1029D00080320000220080408F9801002300804058
+:1029E0008F98010088002D448FB001004395A241CB
+:1029F000197C00004095A2433D7C00004095A2F266
+:102A0000026C00000000A24080B20000000080497B
+:102A10008FB001004295A240803200000000804348
+:102A20008FB00100000080488FB001004095A09158
+:102A3000036C00003E9522433D7C00004795A24078
+:102A400080320000280080408F98010029008040DB
+:102A50008F98010014000040439901005195A2F0A5
+:102A60001430000088002D448FB001004E95A2F272
+:102A7000026C00000000A24080B20000000080490B
+:102A80008FB0010040952241197C00003E952091B5
+:102A9000036C00004095004081B200005595200A6B
+:102AA000026C00005495A240803200000000804477
+:102AB0008FB00100000080498FB001005A95220AB2
+:102AC000026C00002E95A241197C00005995A2408D
+:102AD00080320000000080558FB001000000805659
+:102AE0008FB001005C95A24080320000000080435E
+:102AF0008FB00100000080488FB001006295004354
+:102B000095B000006295004195B0000062950042CA
+:102B100095B000006295004495B000006295004CAD
+:102B200095B000000B980040813201006595A240ED
+:102B3000803200000000804B8FB001000000804C0C
+:102B40008FB001002D000040439901002E002FF3AB
+:102B500084B001006A95A2F3963000000000804026
+:102B600001B001002D002A41E7D10100D4003D4110
+:102B700085E001000B0000F200E401007095225A8C
+:102B8000017C0000000000401F9001007195005A78
+:102B900001800000000000401F8001000000634130
+:102BA00085C001000000A0A5856C01000000E34085
+:102BB00085B001000C80000342C9010012000040F2
+:102BC00087980100559900F08CB000007E95224056
+:102BD0000F6C000000002F0548B101007B95A24B4F
+:102BE000197C00007C9522F0186C00000000604BFE
+:102BF0001990010048960007103001006F840040D2
+:102C000005B000008095225A1F7C0000CD95004041
+:102C1000813001006F84004005B0000000002F05E6
+:102C200048B101000000604B199001004896000770
+:102C3000103001006F84004005B0000000002F0537
+:102C400048B101000000604B199001004896000750
+:102C5000103001000000804005B00100899533402C
+:102C6000813200008C95A1AD952000009A9513400B
+:102C700081B200000000134A5A8301003000394538
+:102C800095E001001F00000F5ED801000000005A0F
+:102C90005F9001000000004045B00100000000040A
+:102CA00048B00100000000054AB001000000000C1F
+:102CB00058B00100000000074EB001001886004027
+:102CC0005D9801000000005861B101000000004A59
+:102CD00062B101000000A84197B000009795004044
+:102CE00081B200000000804097B001009B9544072E
+:102CF00096300000FFFF004B8489010000001CC2D9
+:102D000024B00100A595A245257C00009F953120A7
+:102D100085300000A6952212487F000067981112A6
+:102D2000480301001000001296E401000000004B6F
+:102D30001E9401000000805A1F900100A5953140AB
+:102D400081320000000000B424B00100A6952212D8
+:102D5000487F0000679800408132010000002F0585
+:102D600048B10100B3950BF084300000000011124F
+:102D700048830100B0952250857000005E0100403C
+:102D800043990100679700F296300100E99900121B
+:102D9000943001000000005A1F9001001000001242
+:102DA00096E401000000804B1E94010010000042D8
+:102DB00010F4010000B73F4311F0010007000008C4
+:102DC0008A880100B69530A10C300000B9952245E3
+:102DD000E67D0000A695104081B2000000002A4563
+:102DE000E69101000000101248830100000011402C
+:102DF00081B201000000604B858001005E0100404F
+:102E000043990100679700F296300100008000109E
+:102E100044C90100D8000040819801002E002D0512
+:102E200048B10100C4952240E76D000080000040D9
+:102E300080C8010000000040F0B101000900000856
+:102E400086E40100000068A787C00100000000447C
+:102E500061B101000000001062B10100C895A80531
+:102E6000E03100001000001296E401000014004B55
+:102E700096DC01000000804B1E9401001000000F42
+:102E800084F401001F00004284880100D195224093
+:102E900080320000D295004268B10000000000427C
+:102EA0006AB10100D295315A1F0000000000914222
+:102EB00048930100D4953540813200006D000040F8
+:102EC00061990100DA9528B12C300000D595224D8A
+:102ED000757D0000000000402DB00100000095400D
+:102EE00011B001006D00004061990100DA95A8B1B0
+:102EF000103000000000954081B201007F000040CA
+:102F000061990100E19528B110300000DD959FBA6C
+:102F1000803200000000804011B0010000008024D9
+:102F2000118401000000005F61B101000010000089
+:102F300062DD01000000A84081B20000E39500407E
+:102F400081B20000AC94004047990100E7953240FF
+:102F500081320000ED9522F896300000000000F864
+:102F600090B00100000000F092B001000100004BA1
+:102F7000F0CD010020009248E0C901006C00004043
+:102F800061990100F19528B192300000ED95224C35
+:102F9000757D00000400124091B000006C000040FC
+:102FA00061990100F195A8B190300000FF00004840
+:102FB000968801000000004B90D001000100004BFA
+:102FC000F0CD010020000048F0C901000000924946
+:102FD000E0B101000C002D1048B10100FF0700080E
+:102FE000828C0100FF0700F0008C01000000A2416C
+:102FF00000EC0000FE95221A006C0000E295000033
+:10300000343001000000005049C10100FA95A2418E
+:10301000235000000000804081B201000C002D1000
+:1030200048B10100FF070015828C0100FF0700F086
+:10303000008C01000000A24100EC00000796220D68
+:10304000006C0000E29500001A3001000000005002
+:1030500049C101000396A2412350000000008040B6
+:1030600081B201000C96831E8032000000000044F3
+:103070001990010024002D012CB0010028002DF032
+:1030800016B0010022002DF026B0010014002FF22E
+:103090000CB0010000008040E1B1010002002D11E0
+:1030A00010C100001596004043C100001596005065
+:1030B00043C10000200000A142C901001A9622402D
+:1030C000F56D00000000004243D101000400A24061
+:1030D000E57D00000000004023B0010000008049B1
+:1030E0001F9001001D9622111E7C00001F96A0F06B
+:1030F000164000001F96004117C000001F96A0F464
+:10310000164000000000004117C001000000A2416D
+:1031100023D000001596005243D1000000B5000DE9
+:1031200042C9010022963047170400002596A20BE1
+:10313000E67D00000000904281B0010000B7000D64
+:1031400046C901002996A20BE67D00000000000B95
+:10315000E69101000000904181B0010000001040A4
+:1031600081B201002A96400796300000F399004092
+:10317000813201003496A245957C000001973F41C1
+:1031800095E00100000000F396B001000000004E41
+:10319000E6B1010040973E4097E001000000004E7C
+:1031A000E6B1010040973E409DE001004796003B9C
+:1031B000E7B1000034963040813200003E96A20B09
+:1031C000E67D000000B5000D46C901003A96A20B4D
+:1031D000E67D00000000104081B20100000098422E
+:1031E00081B0010000B7000D46C901000000000BCE
+:1031F000E69101000000104081B2010000009841FA
+:1032000081B00100040021A2952000000000104AB6
+:103210004483010000973E4195E001000000004E0C
+:10322000F6B101000000004EE6B1010040973E40BB
+:103230009DE001000000003BE7B101000000004AF2
+:1032400090B10100FFFF0007928901000000984043
+:1032500081B001000300000886F4010000B70043BC
+:1032600046C9010007000008828801004B9640080B
+:1032700096300000F39900408132010057962245B4
+:10328000957C00005396225A1F7C00001000000F0E
+:1032900096F401005096315F970400000000114B36
+:1032A000489301000000004B6AB101005396304082
+:1032B0008132000000000041E68101000000104062
+:1032C00081B201000000984081B2010000973F41A7
+:1032D00095E00100000000F396B0010040973D40EA
+:1032E00097E00100000063F388B001005F96A23B05
+:1032F000896C00000000004A90B10100010000A6A6
+:1033000092B101006096184A4493000000001840F2
+:1033100081B201003000394597E001006596225ADC
+:103320001F7C00001F04000F98D801000000004C13
+:103330005E940100679600054AB000001F0400A7D4
+:103340005E840100000000404BB001000000005806
+:1033500061B101000000004B62B101000000A84013
+:1033600081B200006896004081B200006B96400771
+:1033700096300000F3990040813201006F9622459B
+:10338000957C00000000984081B20100F199004A4C
+:103390004413010000973F4195E00100000000F355
+:1033A00096B0010040973D4097E00100000063F3B4
+:1033B00088B001003000384597E001000000005F50
+:1033C0000F9001000000005861B101000000004BA7
+:1033D00062B101007796A840813200007096A23B4E
+:1033E000896C0000300038459DE0010000009840E5
+:1033F00081B20100E9990012943001004896005A08
+:103400001F0001000000805A1F9001001100004AB7
+:10341000E6C9010034002F4F95840100000000F33D
+:1034200096B001000100634B84C801000000A04376
+:10343000856C01000000E34085B0010030002D44A0
+:103440001F90010032002DF22AB00100040022F288
+:103450000230000066950010323001003200A040BA
+:10346000E5B101000000004097B00100F007004006
+:10347000999801000000004A02C0010000000050BD
+:1034800003D001000000004197C001000000A34CE0
+:1034900002D000008E96004081B20000000000A81B
+:1034A00036B001009E9622410350000000800010BB
+:1034B00044C9010000000050F1B101007000000398
+:1034C000F0C901000000004261B1010000000010DD
+:1034D00062B101009796A800E03100001B840088CB
+:1034E0001CB00000E2950040813201007C800003A6
+:1034F00042C90100000000F000B001009296005C9B
+:1035000001800000E2950040813201000000001BB4
+:1035100010B1000068012D0682B00100000000F229
+:1035200082C001000080000346C90100DD95004013
+:1035300081320100C5962240116C0000000068082D
+:1035400038960100F007004182CC0100A396AA4101
+:103550003B400000000000F810B001000000005CDB
+:10356000118001000100001D04CC0100C496264614
+:10357000233000000800000312C80100640120F09D
+:10358000E0B10100C3962241055000002000000375
+:1035900048C901000C0000F886C801000000224460
+:1035A000F1B1010000000043F0B10100000000098A
+:1035B000E0B101000000004461B10100A00000A4DE
+:1035C00062DD0100B596A8461F100000C296224198
+:1035D00005500000C096A24123500000000000A149
+:1035E0001AB001000000004461B101004000001069
+:1035F00062DD0100BB96A846233000001B840088D2
+:103600001CB000001000000348C901000000000DBC
+:1036100042B101000000004413C00100B096005008
+:1036200049C100000000000548B10100048000030A
+:103630001AC801000000804081B20100C4962240F7
+:103640003B6C0000000000F800B00100E295005C57
+:1036500001000100C59600413BD0000000008D47ED
+:1036600080320100B0002F5F13B001000000E0F0D5
+:103670008CC001000080000342C90100000000F876
+:1036800094B00100000000F88CB00100D1968CF8D5
+:103690008E3000000000004419900100040022F860
+:1036A00014300000000000F816B00100000000F81F
+:1036B00026B0010008002EF80CB001000C002A4AC8
+:1036C000E0B1010028000000E0C901001000201B4B
+:1036D000E0B10100DE96200A0C6C0000000000F84A
+:1036E00094B00100000000F896B00100200020F026
+:1036F000E4B101001800204AE0B101001C00204B99
+:10370000E0B10100C996004013B000002C002D422A
+:10371000199001002E002FF382B00100000000F389
+:1037200096B00100E496A2A5976C000000008041CD
+:1037300095B00100E796A240976C000000000040A1
+:1037400083B001002D002040E7B10100000063417B
+:1037500097C00100D4003E4183E001000000004119
+:1037600083C00100EC96A0A5836C0000000000401F
+:1037700083B001002C002041E6B10100F196224007
+:103780001F7C00000004000098DC01000B00004CCE
+:10379000E4F50100000080401F8001000B00800064
+:1037A000E4F50100E6950040813201000480000349
+:1037B00044C9010000000040F1B1010000000040D8
+:1037C000F1B101000000604187B0010000800010ED
+:1037D00044C9010000000050F1B1010000000048A0
+:1037E000F0B1010000000049F0B101000000000349
+:1037F000E0B101000000004561B1010020000010AF
+:1038000062DD01000000A85D05900000FD9600400B
+:1038100081B20000E6950040813201000080000383
+:1038200044C9010000000041F0B101000000004265
+:10383000F0B1010000000040F1B1010000000043C0
+:10384000F0B101000080001044C9010000000050E8
+:10385000F1B1010000000048F0B101000000004992
+:10386000F0B1010000000003E0B1010000000045DC
+:1038700061B101002000001062DD01000000A85DC0
+:10388000059000000C97004081B200002D00004020
+:10389000439901002E002FF384B00100010063F36F
+:1038A00096C8010014979F4185500000010000A5B3
+:1038B00085CC01002D00A042E6B101005E012D0083
+:1038C00080B001001997524381600000020000F2AD
+:1038D00082F401001A970041809400000000005F0C
+:1038E000819001000000005E61B101000000004015
+:1038F00062B101000000A84095B000001B979EBB7C
+:10390000803200002097A2401F7C0000E29500401A
+:1039100081B200000000804195B001000400001554
+:1039200042C90100000000542BC00100000000FC4F
+:1039300024B00100000000FC38B00100000000FECF
+:103940003CB00100000000FE3AB0010035979C1722
+:10395000803200002A97A24A197C00000000804CA7
+:103960001F9001000C00001E98F401002997A24846
+:10397000996C00000000001542B101002997A28A4D
+:10398000F16D00000C00000102CC0100000000FC01
+:103990003EB00100010000F428CC0100CC002D0550
+:1039A00048B10100349720F03E6C00000000004B4D
+:1039B0001F9001000000004C2BC00100BF002D052E
+:1039C00048B10100000080F33AE0010000002E4BF6
+:1039D0001990010007002A0CE4B1010000008004E6
+:1039E000E6B1010018000040439901001C002DF0D1
+:1039F00016B0010020002DF026B001000C002FF2BF
+:103A00000CB001000000A20614EC00004197224512
+:103A10001F7C00000000A3062AEC0000000000F854
+:103A200094B00100000000F096B001000C002D40A1
+:103A300081B2010000002A4CE1C1010030000010F9
+:103A400048C901000A000040F19901001800000572
+:103A5000F0C901000000004AF0B101000000004B75
+:103A6000E0B101000000004761B10100A00000A426
+:103A700062DD01004B97A85C1F100000000080056C
+:103A800048B1010000002E1048B10100000068019B
+:103A900096B0010000000003F0B1010051974542CB
+:103AA000613100000000001062B101005297A800CF
+:103AB000E031000000009D4081B2010000002E10A6
+:103AC00048B101000000680196B001000000000349
+:103AD000F0B101005897454261310000200000100C
+:103AE00062DD01005997A800E031000000009D4010
+:103AF00081B201003080004A44C901000000000684
+:103B0000F1B10100C0A83D460DE00100FF7F00A11A
+:103B1000F08901000200000996F40100000000464F
+:103B200097E00100000060A897C00100639746423B
+:103B3000613100003000004A62C901006497A8406A
+:103B40008132000000009E4081B2010000993F4296
+:103B500097F001006897474081320000709722F388
+:103B6000740600003F0000F3948801000000000785
+:103B7000E785010000001F5561B101000000004A07
+:103B800062B101000000A84081B200006D970040C2
+:103B900081B2000000009F4081B20100000000A837
+:103BA00036B0010080978241234000007597A244FF
+:103BB0001F7C0000EF9400018C3001002080001079
+:103BC00042C901007B972240E36D000000000043E2
+:103BD00061B101004000001062DD01007897A8404B
+:103BE000813200001B8400881CB0000000000041EE
+:103BF00023B001000000001032B001008097224184
+:103C0000197C0000F89500432330010000000041BA
+:103C100023B001008297A3150C6C00008397000667
+:103C200004B000000000001504B0010085972002D8
+:103C30001A6C00000000000D04B001000700000B2A
+:103C4000968801008A9726479724000000000041CB
+:103C500097C001008A97234B046C00000000004BC2
+:103C600004B001004998000548310100B4972202D0
+:103C7000145000008E97A2022A500000B497A2456B
+:103C80001F7C0000909722020C50000099970002C0
+:103C900016C000009897225C1F7C00003080001046
+:103CA00042C9010098972240E36D000000000047E0
+:103CB00061B101004000001062DD01009497A8404E
+:103CC000813200001B8400881CB000000000000549
+:103CD00048B101003A97005C1F000100B49722151B
+:103CE000803200000000005033C00100B397A202F0
+:103CF0001A500000A59722461F7C00007080000328
+:103D000042C90100000000461F800100A597224023
+:103D1000E36D00000000004261B1010040000010AE
+:103D200062DD0100A197A840813200001B84008859
+:103D30001CB000000000000548B101000C80000329
+:103D400042C90100100000F010C801002F002F5CD4
+:103D50001180010000000047E7910100F0070040DA
+:103D60001B980100729720151A6C00007000000368
+:103D700048C9010000002250F1B101000000000319
+:103D8000F0B10100FF070008E08D010000000042D3
+:103D900061B10100A00000A462DD0100B097A84657
+:103DA0001F1000007297000548B1000072970002D2
+:103DB00010C00000B697A2441F7C0000EF940001E1
+:103DC0008C3001000000001B10B1000000800010CA
+:103DD00044C901000C000040F199010010000008E6
+:103DE000F0C9010000000016F0B10100100000034E
+:103DF000E0C901000000004561B101002000001091
+:103E000062DD01000000A85C1F900000BD9700402B
+:103E100081B20000170000D0A2C901000000A2403A
+:103E200027EC00000000002000B00100E2950041F6
+:103E3000A3410100C197004127D0000010000007F6
+:103E400096E401000000004B809401000000005443
+:103E500061B101000080004062DD01000000A84067
+:103E600081B20000C897004081B200001A9800405B
+:103E70002B300100AC002D0616C0010090002DF083
+:103E800016C40100D097A0F01644000000000041C5
+:103E900017C001000E0000A244C9010000006CF030
+:103EA00030B00100AC002D4087B0010000006CF084
+:103EB00028B00100D997224A197C00000030004345
+:103EC00086C801000030000B16C80100D997A44035
+:103ED000813200000000004117C00100FA9722065D
+:103EE00080320000E697A206146C0000E397224897
+:103EF000197C0000DE97A04117400000000000413F
+:103F000017C001000000004131C0010090002018DE
+:103F1000E0B101008B002D48198001008B00204585
+:103F2000E7910100E69700408790000008000043F9
+:103F300086980100E697A048174000000000004165
+:103F400017C00100B0000040439901001050004329
+:103F5000FCC9010051980030813001000000004090
+:103F6000E5B10100F197224A197C0000080000A287
+:103F700044C90100CC002DABF9B10100000000AB39
+:103F800017C00100F097A0F01644000000000041A7
+:103F900017C00100F59764F082B00000A400004053
+:103FA00047990100F597A2F280320000000000411D
+:103FB000E5B101008C002018E0B101009000004044
+:103FC000459901000000600630C001000000860C29
+:103FD00080B20000BC002D4619900100A000A0F2A4
+:103FE000E4B10100B00000404399010010500043CB
+:103FF000FCC9010051980030813001000000A24A44
+:1040000019FC0000080000A244C90100CC002DAB3F
+:10401000F9B10100000000AB17C001000398A0F047
+:10402000164400000000004117C001000000E4F049
+:1040300082B001000080001044C90100000000416E
+:10404000F0B1010000000003F0B101000000000029
+:10405000F0B101000000001062B101000000A81BD7
+:10406000E0B100000898004081B2000000F0000CB0
+:104070007E8901000000A64C956001000000804A86
+:10408000189401000080001044C9010004002201BE
+:10409000F031000020000040F0C9010000000016CF
+:1040A000F0B101000000004361B1010020000010E8
+:1040B00062DD01000000A815E0B100001398004087
+:1040C00081B200001080000344C901000000000616
+:1040D000F0B1010000000001F0B101000000E85F54
+:1040E0001790010070000040439901007A012EFEF4
+:1040F00092B001008B002DF616B0010020982243EB
+:10410000E77D00000000004445C10100040000A656
+:104110002AB0010028006E0682C801002498224AB5
+:10412000197C00000000004245D1010000006E4CE7
+:1041300083C001000000004192C001002598423078
+:104140003D0700000000669E83B0010000001A4198
+:104150003DC301000000004192C00100060000A222
+:1041600044C901001000004998F401002E9826303F
+:10417000930400002E98904C9240000000000041F3
+:1041800093C00100FFFF8049ECA9010000800010EE
+:1041900044C9010004002201F031000000000009C0
+:1041A000F0B1010000000018F0B101002000001083
+:1041B00062DD01000000A815E0B100003398004066
+:1041C00081B200004098225F817C00003F98A240AD
+:1041D000197C00000000004019900100000000540C
+:1041E00061B101001000000796E401000000004FDB
+:1041F000979401000000004B62B101003F982840F5
+:10420000813200003C98004081B200000000A221F1
+:10421000818400004398A25F816C00000000A243EB
+:10422000197C0100000000431990010000000054B7
+:1042300061B101001000000796E401000000004099
+:10424000969401000000004B62B101000000A840FC
+:1042500081B200004698004081B200000080001941
+:1042600044C9010004002202F03100000000000BEC
+:10427000F0B1010000000013F0B1010000000043A4
+:1042800061B101002000001962DD01000000A808F2
+:10429000E0B100004E98004081B200007C002DF09B
+:1042A00084B00100020000F098F401005798204CFF
+:1042B000846C00008800004043990100579820F268
+:1042C000846C00000000004085B0010098002D14AF
+:1042D00082B00100000000F098B00100A3002D148E
+:1042E00098D001005C98204C846C00000000004CC9
+:1042F00084B00100000000F380E001005F982340DB
+:10430000846C00000000004084B00100D000201444
+:10431000E0B101009800254280B0010000006EF37A
+:1043200080F001000000A64282C000006598A04015
+:10433000164000000000004117C0010000009FF07F
+:1043400082EC00009800A041E0B1010068980012E2
+:1043500010C90000004880400B980100C04980400F
+:104360000B980100804B80400B980100404D80402D
+:104370000B980100004F80400B980100C050804016
+:104380000B980100805280400B98010040548040FF
+:104390000B980100005680400B980100C0578040E8
+:1043A0000B980100805980400B980100405B8040D1
+:1043B0000B980100005D80400B980100C05E8040BA
+:1043C0000B980100806080400B98010040628040A3
+:1043D0000B980100006480400B980100C06580408C
+:1043E0000B980100806780400B9801004069804075
+:1043F0000B980100006B80400B980100C06C80405E
+:104400000B980100806E80400B9801004070804046
+:104410000B980100007280400B980100C07380402F
+:104420000B980100807580400B9801004077804018
+:104430000B980100007980400B980100C07A804001
+:104440000B980100807C80400B980100407E8040EA
+:104450000B98010088984357613100009498A25747
+:10446000737D00009498A240816F00000000004816
+:1044700061B101000010004A62DD01008C98A84A79
+:10448000803300009198225F957C00000000004B73
+:1044900062B101008F98A84BAC33000000001BA54F
+:1044A00082B30100000000BE83C301000000804011
+:1044B00097B001000010004A62DD01009898284082
+:1044C0008132000094982257777D000000009B20E5
+:1044D00097B001000000004B62B101009898A8401D
+:1044E0008132000000009B4097B0010000002E10B8
+:1044F00048B10100A8010040F19901000000000549
+:10450000F0B101000900000796E40100000060A777
+:1045100097C001000000001062B101000000A84037
+:1045200081B20000A098004081B20000A8002D1CBC
+:104530008AB0010000009FF08AD000000000A24075
+:104540008BEC00008A002040E7B10100B40000407D
+:1045500047990100A4002D45E0D10100AD989C17BA
+:1045600080320000BE002FAB83B001001799001409
+:1045700082500100B298004081B20000B29822F24D
+:10458000823000008C00004043990100B2989F1CCB
+:10459000E06D0000BE0000404799010017990040FF
+:1045A00081320100A800201CE0B101009C002D30E8
+:1045B00081B0010088002DF084B0010094002DF23C
+:1045C00086B00100DC9823F0846C00000C000042EF
+:1045D00088F40100DC982050896C0000CB98A392ED
+:1045E000876C0000BB98004410C90000DC98000AEA
+:1045F00087B00000DC98000987B00000DC98000854
+:1046000087B00000DC98000787B00000DC98000746
+:1046100087B00000DC98000787B00000DC98000637
+:1046200087B00000DC98000687B00000DC98000628
+:1046300087B00000DC98000687B00000DC98000618
+:1046400087B00000DC98000587B00000DC9800050A
+:1046500087B00000DC98000587B00000DC980005FA
+:1046600087B00000DC98000587B00000CC980044BB
+:1046700010C90000DC98000F87B00000DC98000E25
+:1046800087B00000DC98000D87B00000DC98000CBB
+:1046900087B00000DC98000C87B00000DC98000CAC
+:1046A00087B00000DC98000C87B00000DC98000C9C
+:1046B00087B00000DC98000C87B00000DC98000B8D
+:1046C00087B00000DC98000B87B00000DC98000B7E
+:1046D00087B00000DC98000B87B00000DC98000B6E
+:1046E00087B00000DC98000B87B00000DC98000B5E
+:1046F00087B00000BF002D4384C0010090002DF35F
+:1047000080E00100E1982340846C00009400209D2B
+:10471000E1B101000000004084B00100E598A2F082
+:10472000386C00009C002042E0B101000000005FF6
+:104730001394010000008046198001009C00204273
+:10474000E0B101003700004043990100040000F38C
+:1047500080F401000F0000F382880100EB982341F0
+:10476000806C00000000005F139401000000890CC1
+:1047700080B20000BC00004043990100A000A0F2FC
+:10478000E4B1010000009F4124EC0000F598A64030
+:104790008132000000009F4238EC0000F598A640EE
+:1047A00081320000B400004043990100F798A3F063
+:1047B0003A6C00000000804081B20100B40000406B
+:1047C00043990100FB9822F03A6C0000B400201DD0
+:1047D000E0B1010080002D5F13940100FB9823F0ED
+:1047E0003A6C00008000201DE0B10100C0002012E2
+:1047F000E0B10100C400A01CE0B101000080000392
+:1048000044C9010000000042E0B101001200004074
+:104810008798010004999F41246C0000000000412A
+:104820008CB00100000000128CD0010005990041FD
+:1048300024B00000000000408DB0010055990040F8
+:10484000813201000000004561B10100400000100C
+:1048500062DD01000000A84081B20000079900401D
+:1048600081B20000D49500408132010000000016A2
+:1048700080B201000000A708803201000F99A24019
+:10488000956C0000E295004081320100008200A694
+:1048900004B00100000000402DB00100A0982F409E
+:1048A00011B00100E989004189B0000000009FF8C3
+:1048B0003EEC000000009F12E0ED0000C80020ABBD
+:1048C000E1B10100CC00A01FE0B101001999A35F84
+:1048D000E76D000000000041E7C10100A6000040B4
+:1048E000479901002D9922F2863000000300004311
+:1048F00084F401000100004180CC0100B8002D4289
+:1049000080D001000000624086C0010021991F4351
+:10491000803200002299A240876C000000006241B2
+:1049200087B0010026999F408032000000000040BF
+:1049300085B001000000004084D00100000000426A
+:1049400080B00100000000F288B0010002000044C5
+:1049500084F40100B8002E4280D0010000006240C3
+:1049600088C001002C991F44803200003099A24079
+:10497000896C00003099624189B0000003006241F7
+:1049800086E40100B8000040459901000100624141
+:1049900088E40100A4002040E5B10100A20020400D
+:1049A000E7B10100BC002E4387F001000000004485
+:1049B00086C0010036992043876C000000008043C8
+:1049C000E5B101004001004380CE01000000A44396
+:1049D000E43101004001E2408798010088002D4445
+:1049E00081B0010090002DF22EB001009C002DF04E
+:1049F00086B0010090002DF082B00100BA002DF0C9
+:104A000098B001004399A212986C0000BC002DF2EE
+:104A100098B001004399A0F2986C000000000017C4
+:104A200082B001009C002041E0B10100B4002D12D1
+:104A300086D001004699A341E06D0000479900F03F
+:104A400084B000000000004184B0010080002D43CC
+:104A500084D001004A999F4280320000000000404B
+:104A600085B001004C99A342146C00004D99000AD6
+:104A70000CB00000000000420CB001004F99A017DC
+:104A80000C6C0000000080170CB00100549922400B
+:104A90000D6C00000000A00A0CEC0000010000F00A
+:104AA00082F401005499A0410C6C00000000A2F0B7
+:104AB000803201000000804081B00100E695004096
+:104AC000813201000480000344C901000000004657
+:104AD000F0B1010000000040F1B1010000006041B0
+:104AE000879401000080001044C9010000000050BC
+:104AF000F1B1010000000048F0B1010000000049E0
+:104B0000F0B1010000000003E0B101000000004529
+:104B100061B101002000001062DD01000000A85D0D
+:104B2000059000006099004081B2000000002E4B0B
+:104B30001990010005002A0CE4B101000000800476
+:104B4000E6B101006A9922491F7C00004200004042
+:104B500087980100000000491F800100C0970040B5
+:104B60008DB0000070992240AF6F0000000000156A
+:104B700096B0010088980008943001006F99224097
+:104B8000976C0000C097004687B00000000080408E
+:104B900087B001007099434861310000001000089F
+:104BA00062DD010075992840873000007199224824
+:104BB000777D0000C0971B4687B000007899225F80
+:104BC000117C000004002215623100007699A84093
+:104BD0008132000000009B4081B2010000000040D3
+:104BE00049B1010030000040A199010000000040DF
+:104BF00093B00100000000401FB00100C9990049B6
+:104C0000963001000700004906E401000039000366
+:104C100006C801000000004005B00100200000D0DF
+:104C2000A0C901000000004193C001007D99A0547B
+:104C3000936C000000002E0597B001000048004072
+:104C40004999010000000040E1B10100C00100A24B
+:104C500044C901008699A24197500000000000203D
+:104C600049B30100CE9900404931010000B52E083A
+:104C700097B0010000000040F1B101008C99A24101
+:104C800097500000180000409798010000972E40B0
+:104C900081B2010000000040F1B101009099A241F1
+:104CA000975000000000004049B1010040182E0557
+:104CB00097B0010000000040F1B101009499A241B9
+:104CC0009750000057952040E7B101003094004014
+:104CD0004599010064000040E59901005695204087
+:104CE000E7B10100B8942041E5B10100BA94204138
+:104CF000E5B1010098940040459901000200004090
+:104D00009798010000000040F1B101009E99A24176
+:104D1000975000000000004097B0010000000040E4
+:104D20006FB101000000004B68B10100A2998541FC
+:104D300097400000DB9900408132010000000040F4
+:104D400039B301000000004037B30100000000400B
+:104D500035B301000000004033B301000000004003
+:104D600041B30100000000403FB301003C0000409F
+:104D7000299B0100EE050040259B010042000040F8
+:104D80004B9B0100000000402FB3010000000040D9
+:104D90002DB301000000004047B3010000000040B7
+:104DA00043B30100600000402B9B01000000005451
+:104DB000EF93010000000055F1930100FFFF00A5F3
+:104DC0003C8B01000000002C5BB301000000002CB4
+:104DD00045B301000000004059B30100000000404D
+:104DE00057B301000000004027B30100000000405D
+:104DF00053B30100BF99A250FD7F0000BF99A2519B
+:104E0000FD7F0000C09900401DB3000050460040E7
+:104E10001D9B010000C000A688B30100FF3F00A653
+:104E20003AB3010000C0009D3B9B0100B405004067
+:104E3000239B0100000000404DB30100080A00A6BA
+:104E400014B301000101008A159B0100008000A637
+:104E500056B101000000805E57B501001800004BFC
+:104E600020E401000600004B96E401000043004BE3
+:104E700096C801001800001020DC01000000804BE3
+:104E80002094010000992E0A97B001000000004014
+:104E9000F1B10100CF99A2419750000000030040FA
+:104EA0009798010000A900404599010000000040CA
+:104EB000F1B10100D399A2419750000030000040A9
+:104EC000979801000000005561B101000000004BFF
+:104ED00062B10100D799A84081320000D799A24160
+:104EE000975000000000804081B2010000000040A7
+:104EF00087B101000000004097B001000000004BA6
+:104F000080B10100010000A682B10100DD99854158
+:104F1000974000000000004097B1010000000040F1
+:104F200097B001000000004B90B10100010000A605
+:104F300092B10100E2998541974000000000804055
+:104F400081B20100E6994440813200000000001265
+:104F500080B10100FFFF9C4B82890100E999444028
+:104F6000813200000000004A80B1010001009CA6CF
+:104F700082B10100EC99444081320000FFFF004BF8
+:104F80008489010000009CC224B001000000004A96
+:104F900090B10100FFFF804B928901000000004AA0
+:104FA00090B10100010080A692B10100FFFF004B0B
+:104FB00094890100000080CA94B001000000804084
+:104FC00081B201000000004081B00100F79980A586
+:104FD00080320000F89900A58032000000000041F6
+:104FE00081C00100F99980A5803200008001004055
+:104FF00083980100029A204F816C0000000100405C
+:1050000083980100029A204B816C000080000040D0
+:1050100083980100029A2047816C00000000004044
+:10502000839801000000004182DC010003900041F0
+:10503000209901000000004049B1010000142F4CEC
+:1050400083B0010000000040F1B10100069AA241C6
+:1050500083500000640000A580C80100099AA2A541
+:10506000806C000020000090209901000000005F8B
+:10507000239101000C9A1F918032000030000090B3
+:10508000209901000000005F239101000F9A1F91F9
+:10509000803200007000009020A901000000005F35
+:1050A00023910100129A1F91803200000000005FDE
+:1050B00023910100149A1F918032000040680090F3
+:1050C00020A90100E000004061990100210000409A
+:1050D0006199010022000040619901002300004015
+:1050E0006199010024000040619901002500004001
+:1050F00061990100260000406199010027000040ED
+:1051000061990100C000004061990100D014004085
+:105110004599010000000040F1B10100000000408D
+:10512000E1B101003003004085300100D01400409F
+:1051300045990100020100A680B00100040300406F
+:1051400080980100060500A682B001000807004112
+:105150008298010000000040F0B101000000004111
+:10516000E0B10100080000408598010030030040D4
+:10517000813201003903004081320100D81400401F
+:1051800043990100FF02A2F8806C0000000322F0A6
+:10519000826C0000FF02004081B20000D0142E405B
+:1051A00049B1010005000040A39B01000000004040
+:1051B000C1B30100080000DD81F40100369A00400F
+:1051C00010C900003C9A000581B000005501004064
+:1051D00081B20000449A000581B0000055010040F2
+:1051E00081B20000499A0044A5B300004B9A0044E4
+:1051F000A5B3000002000040A4E70100000000E0A9
+:1052000081B10100FFFF00C1F0890100419A2241F4
+:10521000815000003D9A0041C1C30000B10200402E
+:1052200081320100C5020040813201005A01004074
+:1052300081B2000002000040A4E70100000000E08D
+:1052400091B10100FFFF00C9F0890100419A22419C
+:1052500081500000459A0041C1C30000FFFF00DEFD
+:1052600085890100419A00C2E0B10000FFFF00DE25
+:1052700095890100419A00CAE0B10000040000CB0A
+:1052800081C801006A840040F293000004000040DD
+:1052900081B200000400004081B200000400004020
+:1052A00081B200000400004081B200000400004010
+:1052B00081B200000400004081B200000400004000
+:1052C00081B200000400004081B2000004000040F0
+:1052D00081B200000400004081B2000004000040E0
+:1052E00081B200000400004081B2000004000040D0
+:1052F00081B200000400004081B2000004000040C0
+:1053000081B200000400004081B2000004000040AF
+:1053100081B200000400004081B20000040000409F
+:1053200081B200000400004081B20000040000408F
+:1053300081B200000400004081B20000040000407F
+:1053400081B200000400004081B20000040000406F
+:1053500081B200000400004081B20000040000405F
+:1053600081B200000400004081B20000040000404F
+:1053700081B200000400004081B20000040000403F
+:1053800081B200000400004081B20000040000402F
+:1053900081B200000400004081B20000040000401F
+:1053A00081B200000400004081B20000040000400F
+:1053B00081B200000400004081B2000004000040FF
+:1053C00081B200000400004081B2000004000040EF
+:1053D00081B200000400004081B2000004000040DF
+:1053E00081B200000400004081B2000004000040CF
+:1053F00081B200000400004081B2000004000040BF
+:1054000081B200000400004081B2000004000040AE
+:1054100081B200000400004081B20000040000409E
+:1054200081B200000400004081B20000040000408E
+:1054300081B200000400004081B20000040000407E
+:1054400081B200000400004081B20000040000406E
+:1054500081B200000400004081B20000040000405E
+:1054600081B200000400004081B20000040000404E
+:1054700081B200000400004081B20000040000403E
+:1054800081B200000400004081B20000040000402E
+:1054900081B200000400004081B20000040000401E
+:1054A00081B200000400004081B20000040000400E
+:1054B00081B200000400004081B2000004000040FE
+:1054C00081B200000400004081B2000004000040EE
+:1054D00081B200000400004081B2000004000040DE
+:1054E00081B200000400004081B2000004000040CE
+:1054F00081B200000400004081B2000004000040BE
+:1055000081B200000400004081B2000004000040AD
+:1055100081B200000400004081B20000040000409D
+:1055200081B200000400004081B20000040000408D
+:1055300081B200000400004081B20000040000407D
+:1055400081B200000400004081B20000040000406D
+:1055500081B200000400004081B20000040000405D
+:1055600081B200000400004081B20000040000404D
+:1055700081B200000400004081B20000040000403D
+:1055800081B200000400004081B20000040000402D
+:1055900081B200000400004081B20000040000401D
+:1055A00081B200000400004081B20000040000400D
+:1055B00081B200000400004081B2000004000040FD
+:1055C00081B200000400004081B2000004000040ED
+:1055D00081B200000400004081B2000004000040DD
+:1055E00081B200000400004081B2000004000040CD
+:1055F00081B200000400004081B2000004000040BD
+:1056000081B200000400004081B2000004000040AC
+:1056100081B200000400004081B20000040000409C
+:1056200081B200000400004081B20000040000408C
+:1056300081B200000400004081B20000040000407C
+:1056400081B200000400004081B20000040000406C
+:1056500081B200000400004081B20000040000405C
+:1056600081B200000400004081B20000040000404C
+:1056700081B200000400004081B20000040000403C
+:1056800081B200000400004081B20000040000402C
+:1056900081B200000400004081B20000040000401C
+:1056A00081B200000400004081B20000040000400C
+:1056B00081B200000400004081B2000004000040FC
+:1056C00081B200000400004081B2000004000040EC
+:1056D00081B200000400004081B2000004000040DC
+:1056E00081B200000400004081B2000004000040CC
+:1056F00081B200000400004081B2000004000040BC
+:1057000081B200000400004081B2000004000040AB
+:1057100081B200000400004081B20000040000409B
+:1057200081B200000400004081B20000040000408B
+:1057300081B200000400004081B20000040000407B
+:1057400081B200000400004081B20000040000406B
+:1057500081B200000400004081B20000040000405B
+:1057600081B200000400004081B20000040000404B
+:1057700081B200000400004081B20000040000403B
+:1057800081B200000400004081B20000040000402B
+:1057900081B200000400004081B20000040000401B
+:1057A00081B200000400004081B20000040000400B
+:1057B00081B200000400004081B2000004000040FB
+:1057C00081B200000400004081B2000004000040EB
+:1057D00081B200000400004081B2000004000040DB
+:1057E00081B200000400004081B2000004000040CB
+:1057F00081B200000400004081B2000004000040BB
+:1058000081B200000400004081B2000004000040AA
+:1058100081B200000400004081B20000040000409A
+:1058200081B200000400004081B20000040000408A
+:1058300081B200000400004081B20000040000407A
+:1058400081B200000400004081B20000040000406A
+:1058500081B200000400004081B20000040000405A
+:1058600081B200000400004081B20000040000404A
+:1058700081B200000400004081B20000040000403A
+:1058800081B200000400004081B20000040000402A
+:1058900081B200000400004081B20000040000401A
+:1058A00081B200000400004081B20000040000400A
+:1058B00081B200000400004081B2000004000040FA
+:1058C00081B200000400004081B2000004000040EA
+:1058D00081B200000400004081B2000004000040DA
+:1058E00081B200000400004081B2000004000040CA
+:1058F00081B200000400004081B2000004000040BA
+:1059000081B200000400004081B2000004000040A9
+:1059100081B200000400004081B200000400004099
+:1059200081B200000400004081B200000400004089
+:1059300081B200000400004081B200000400004079
+:1059400081B200000400004081B200000400004069
+:1059500081B200000400004081B200000400004059
+:1059600081B200000400004081B200000400004049
+:1059700081B200000400004081B200000400004039
+:1059800081B200000400004081B200000400004029
+:1059900081B200000400004081B200000400004019
+:1059A00081B200000400004081B200000400004009
+:1059B00081B200000400004081B2000004000040F9
+:1059C00081B200000400004081B2000004000040E9
+:1059D00081B200000400004081B2000004000040D9
+:1059E00081B200000400004081B2000004000040C9
+:1059F00081B200000400004081B2000004000040B9
+:105A000081B200000400004081B2000004000040A8
+:105A100081B200000400004081B200000400004098
+:105A200081B200000400004081B200000400004088
+:105A300081B200000400004081B200000400004078
+:105A400081B200000400004081B200000400004068
+:105A500081B200000400004081B200000400004058
+:105A600081B200000400004081B200000400004048
+:105A700081B200000400004081B200000400004038
+:105A800081B200000400004081B200000400004028
+:105A900081B200000400004081B200000400004018
+:105AA00081B200000400004081B200000400004008
+:105AB00081B200000400004081B2000004000040F8
+:105AC00081B200000400004081B2000004000040E8
+:105AD00081B200000400004081B2000004000040D8
+:105AE00081B200000400004081B2000004000040C8
+:105AF00081B200000400004081B2000004000040B8
+:105B000081B200000400004081B2000004000040A7
+:105B100081B200000400004081B200000400004097
+:105B200081B200000400004081B200000400004087
+:105B300081B200000400004081B200000400004077
+:105B400081B200000400004081B200000400004067
+:105B500081B200000400004081B200000400004057
+:105B600081B200000400004081B200000400004047
+:105B700081B200000400004081B200000400004037
+:105B800081B200000400004081B200000400004027
+:105B900081B200000400004081B200000400004017
+:105BA00081B200000400004081B200000400004007
+:105BB00081B200000400004081B2000004000040F7
+:105BC00081B200000400004081B2000004000040E7
+:105BD00081B200000400004081B2000004000040D7
+:105BE00081B200000400004081B2000004000040C7
+:105BF00081B200000400004081B2000004000040B7
+:105C000081B200000400004081B2000004000040A6
+:105C100081B200000400004081B200000400004096
+:105C200081B200000400004081B200000400004086
+:105C300081B200000400004081B200000400004076
+:105C400081B200000400004081B200000400004066
+:105C500081B200000400004081B200000400004056
+:105C600081B200000400004081B200000400004046
+:105C700081B200000400004081B200000400004036
+:105C800081B200000400004081B200000400004026
+:105C900081B200000400004081B200000400004016
+:105CA00081B200000400004081B200000400004006
+:105CB00081B200000400004081B2000004000040F6
+:105CC00081B200000400004081B2000004000040E6
+:105CD00081B200000400004081B2000004000040D6
+:105CE00081B200000400004081B2000004000040C6
+:105CF00081B200000400004081B2000004000040B6
+:105D000081B200000400004081B2000004000040A5
+:105D100081B200000400004081B200000400004095
+:105D200081B200000400004081B200000400004085
+:105D300081B200000400004081B200000400004075
+:105D400081B200000400004081B200000400004065
+:105D500081B200000400004081B200000400004055
+:105D600081B200000400004081B200000400004045
+:105D700081B200000400004081B200000400004035
+:105D800081B200000400004081B200000400004025
+:105D900081B200000400004081B200000400004015
+:105DA00081B200000400004081B200000400004005
+:105DB00081B200000400004081B2000004000040F5
+:105DC00081B200000400004081B2000004000040E5
+:105DD00081B200000400004081B2000004000040D5
+:105DE00081B200000400004081B2000004000040C5
+:105DF00081B200000400004081B2000004000040B5
+:105E000081B200000400004081B2000004000040A4
+:105E100081B200000400004081B200000400004094
+:105E200081B200000400004081B200000400004084
+:105E300081B200000400004081B200000400004074
+:105E400081B200000400004081B200000400004064
+:105E500081B200000400004081B200000400004054
+:105E600081B200000400004081B200000400004044
+:105E700081B200000400004081B200000400004034
+:105E800081B200000400004081B200000400004024
+:105E900081B200000400004081B200000400004014
+:105EA00081B200000400004081B200000400004004
+:105EB00081B200000400004081B2000004000040F4
+:105EC00081B200000400004081B2000004000040E4
+:105ED00081B200000400004081B2000004000040D4
+:105EE00081B200000400004081B2000004000040C4
+:105EF00081B200000400004081B2000004000040B4
+:105F000081B200000400004081B2000004000040A3
+:105F100081B200000400004081B200000400004093
+:105F200081B200000400004081B200000400004083
+:105F300081B200000400004081B200000400004073
+:105F400081B200000400004081B200000400004063
+:105F500081B200000400004081B200000400004053
+:105F600081B200000400004081B200000400004043
+:105F700081B200000400004081B200000400004033
+:105F800081B200000400004081B200000400004023
+:105F900081B200000400004081B200000400004013
+:105FA00081B200000400004081B200000400004003
+:105FB00081B200000400004081B2000004000040F3
+:105FC00081B200000400004081B2000004000040E3
+:105FD00081B200000400004081B2000004000040D3
+:105FE00081B200000400004081B2000004000040C3
+:105FF00081B200000400004081B2000004000040B3
+:1060000081B200000400004081B2000004000040A2
+:1060100081B200000400004081B200000400004092
+:1060200081B200000400004081B200000400004082
+:1060300081B200000400004081B200000400004072
+:1060400081B200000400004081B200000400004062
+:1060500081B200000400004081B200000400004052
+:1060600081B200000400004081B200000400004042
+:1060700081B200000400004081B200000400004032
+:1060800081B200000400004081B200000400004022
+:1060900081B200000400004081B200000400004012
+:1060A00081B200000400004081B200000400004002
+:1060B00081B200000400004081B2000004000040F2
+:1060C00081B200000400004081B2000004000040E2
+:1060D00081B200000400004081B2000004000040D2
+:1060E00081B200000400004081B2000004000040C2
+:1060F00081B200000400004081B2000004000040B2
+:1061000081B200000400004081B2000004000040A1
+:1061100081B200000400004081B200000400004091
+:1061200081B200000400004081B200000400004081
+:1061300081B200000400004081B200000400004071
+:1061400081B200000400004081B200000400004061
+:1061500081B200000400004081B200000400004051
+:1061600081B200000400004081B200000400004041
+:1061700081B200000400004081B200000400004031
+:1061800081B200000400004081B200000400004021
+:1061900081B200000400004081B200000400004011
+:1061A00081B200000400004081B200000400004001
+:1061B00081B200000400004081B2000004000040F1
+:1061C00081B200000400004081B2000004000040E1
+:1061D00081B200000400004081B2000004000040D1
+:1061E00081B200000400004081B2000004000040C1
+:1061F00081B200000400004081B2000004000040B1
+:1062000081B200000400004081B2000004000040A0
+:1062100081B200000400004081B200000400004090
+:1062200081B200000400004081B200000400004080
+:1062300081B200000400004081B200000400004070
+:1062400081B200000400004081B200000400004060
+:1062500081B200000400004081B200000400004050
+:1062600081B200000400004081B200000400004040
+:1062700081B200000400004081B200000400004030
+:1062800081B200000400004081B200000400004020
+:1062900081B200000400004081B200000400004010
+:1062A00081B200000400004081B200000400004000
+:1062B00081B200000400004081B2000004000040F0
+:1062C00081B200000400004081B2000004000040E0
+:1062D00081B200000400004081B2000004000040D0
+:1062E00081B200000400004081B2000004000040C0
+:1062F00081B200000400004081B2000004000040B0
+:1063000081B200000400004081B20000040000409F
+:1063100081B200000400004081B20000040000408F
+:1063200081B200000400004081B20000040000407F
+:1063300081B200000400004081B20000040000406F
+:1063400081B200000400004081B20000040000405F
+:1063500081B200000400004081B20000040000404F
+:1063600081B200000400004081B20000040000403F
+:1063700081B200000400004081B20000040000402F
+:1063800081B200000400004081B20000040000401F
+:1063900081B200000400004081B20000040000400F
+:1063A00081B200000400004081B2000004000040FF
+:1063B00081B200000400004081B2000004000040EF
+:1063C00081B200000400004081B2000004000040DF
+:1063D00081B200000400004081B2000004000040CF
+:1063E00081B200000400004081B2000004000040BF
+:1063F00081B200000400004081B2000004000040AF
+:1064000081B200000400004081B20000040000409E
+:1064100081B200000400004081B20000040000408E
+:1064200081B200000400004081B20000040000407E
+:1064300081B200000400004081B20000040000406E
+:1064400081B200000400004081B20000040000405E
+:1064500081B200000400004081B20000040000404E
+:1064600081B200000400004081B20000040000403E
+:1064700081B200000400004081B20000040000402E
+:1064800081B200000400004081B20000040000401E
+:1064900081B200000400004081B20000040000400E
+:1064A00081B200000400004081B2000004000040FE
+:1064B00081B200000400004081B2000004000040EE
+:1064C00081B200000400004081B2000004000040DE
+:1064D00081B200000400004081B2000004000040CE
+:1064E00081B200000400004081B2000004000040BE
+:1064F00081B200000400004081B2000004000040AE
+:1065000081B200000400004081B20000040000409D
+:1065100081B200000400004081B20000040000408D
+:1065200081B200000400004081B20000040000407D
+:1065300081B200000400004081B20000040000406D
+:1065400081B200000400004081B20000040000405D
+:1065500081B200000400004081B20000040000404D
+:1065600081B200000400004081B20000040000403D
+:1065700081B200000400004081B20000040000402D
+:1065800081B200000400004081B20000040000401D
+:1065900081B200000400004081B20000040000400D
+:1065A00081B200000400004081B2000004000040FD
+:1065B00081B200000400004081B2000004000040ED
+:1065C00081B200000400004081B2000004000040DD
+:1065D00081B200000400004081B2000004000040CD
+:1065E00081B200000400004081B2000004000040BD
+:1065F00081B200000400004081B2000004000040AD
+:1066000081B200000400004081B20000040000409C
+:1066100081B200000400004081B20000040000408C
+:1066200081B200000400004081B20000040000407C
+:1066300081B200000400004081B20000040000406C
+:1066400081B200000400004081B20000040000405C
+:1066500081B200000400004081B20000040000404C
+:1066600081B200000400004081B20000040000403C
+:1066700081B200000400004081B20000040000402C
+:1066800081B200000400004081B20000040000401C
+:1066900081B200000400004081B20000040000400C
+:1066A00081B200000400004081B2000004000040FC
+:1066B00081B200000400004081B2000004000040EC
+:1066C00081B200000400004081B2000004000040DC
+:1066D00081B200000400004081B2000004000040CC
+:1066E00081B200000400004081B2000004000040BC
+:1066F00081B200000400004081B2000004000040AC
+:1067000081B200000400004081B20000040000409B
+:1067100081B200000400004081B20000040000408B
+:1067200081B200000400004081B20000040000407B
+:1067300081B200000400004081B20000040000406B
+:1067400081B200000400004081B20000040000405B
+:1067500081B200000400004081B20000040000404B
+:1067600081B200000400004081B20000040000403B
+:1067700081B200000400004081B20000040000402B
+:1067800081B200000400004081B20000040000401B
+:1067900081B200000400004081B20000040000400B
+:1067A00081B200000400004081B2000004000040FB
+:1067B00081B200000400004081B2000004000040EB
+:1067C00081B200000400004081B2000004000040DB
+:1067D00081B200000400004081B2000004000040CB
+:1067E00081B200000400004081B2000004000040BB
+:1067F00081B200000400004081B2000004000040AB
+:1068000081B200000400004081B20000040000409A
+:1068100081B200000400004081B20000040000408A
+:1068200081B200000400004081B20000040000407A
+:1068300081B200000400004081B20000040000406A
+:1068400081B200000400004081B20000040000405A
+:1068500081B200000400004081B20000040000404A
+:1068600081B200000400004081B20000040000403A
+:1068700081B200000400004081B20000040000402A
+:1068800081B200000400004081B20000040000401A
+:1068900081B200000400004081B20000040000400A
+:1068A00081B200000400004081B2000004000040FA
+:1068B00081B200000400004081B2000004000040EA
+:1068C00081B200000400004081B2000004000040DA
+:1068D00081B200000400004081B2000004000040CA
+:1068E00081B200000400004081B2000004000040BA
+:1068F00081B200000400004081B2000004000040AA
+:1069000081B200000400004081B200000400004099
+:1069100081B200000400004081B200000400004089
+:1069200081B200000400004081B200000400004079
+:1069300081B200000400004081B200000400004069
+:1069400081B200000400004081B200000400004059
+:1069500081B200000400004081B200000400004049
+:1069600081B200000400004081B200000400004039
+:1069700081B200000400004081B200000400004029
+:1069800081B200000400004081B200000400004019
+:1069900081B200000400004081B200000400004009
+:1069A00081B200000400004081B2000004000040F9
+:1069B00081B200000400004081B2000004000040E9
+:1069C00081B200000400004081B2000004000040D9
+:1069D00081B200000400004081B2000004000040C9
+:1069E00081B200000400004081B2000004000040B9
+:1069F00081B200000400004081B2000004000040A9
+:106A000081B200000400004081B200000400004098
+:106A100081B200000400004081B200000400004088
+:106A200081B200000400004081B200000400004078
+:106A300081B200000400004081B200000400004068
+:106A400081B200000400004081B200000400004058
+:106A500081B200000400004081B200000400004048
+:106A600081B200000400004081B200000400004038
+:106A700081B200000400004081B200000400004028
+:106A800081B200000400004081B200000400004018
+:106A900081B200000400004081B200000400004008
+:106AA00081B200000400004081B2000004000040F8
+:106AB00081B200000400004081B2000004000040E8
+:106AC00081B200000400004081B2000004000040D8
+:106AD00081B200000400004081B2000004000040C8
+:106AE00081B200000400004081B2000004000040B8
+:106AF00081B200000400004081B2000004000040A8
+:106B000081B200000400004081B200000400004097
+:106B100081B200000400004081B200000400004087
+:106B200081B200000400004081B200000400004077
+:106B300081B200000400004081B200000400004067
+:106B400081B200000400004081B200000400004057
+:106B500081B200000400004081B200000400004047
+:106B600081B200000400004081B200000400004037
+:106B700081B200000400004081B200000400004027
+:106B800081B200000400004081B200000400004017
+:106B900081B200000400004081B200000400004007
+:106BA00081B200000400004081B2000004000040F7
+:106BB00081B200000400004081B2000004000040E7
+:106BC00081B200000400004081B2000004000040D7
+:106BD00081B200000400004081B2000004000040C7
+:106BE00081B200000400004081B2000004000040B7
+:106BF00081B200000400004081B2000004000040A7
+:106C000081B200000400004081B200000400004096
+:106C100081B200000400004081B200000400004086
+:106C200081B200000400004081B200000400004076
+:106C300081B200000400004081B200000400004066
+:106C400081B200000400004081B200000400004056
+:106C500081B200000400004081B200000400004046
+:106C600081B200000400004081B200000400004036
+:106C700081B200000400004081B200000400004026
+:106C800081B200000400004081B200000400004016
+:106C900081B200000400004081B200000400004006
+:106CA00081B200000400004081B2000004000040F6
+:106CB00081B200000400004081B2000004000040E6
+:106CC00081B200000400004081B2000004000040D6
+:106CD00081B200000400004081B2000004000040C6
+:106CE00081B200000400004081B2000004000040B6
+:106CF00081B200000400004081B2000004000040A6
+:106D000081B200000400004081B200000400004095
+:106D100081B200000400004081B200000400004085
+:106D200081B200000400004081B200000400004075
+:106D300081B200000400004081B200000400004065
+:106D400081B200000400004081B200000400004055
+:106D500081B200000400004081B200000400004045
+:106D600081B200000400004081B200000400004035
+:106D700081B200000400004081B200000400004025
+:106D800081B200000400004081B200000400004015
+:106D900081B200000400004081B200000400004005
+:106DA00081B200000400004081B2000004000040F5
+:106DB00081B200000400004081B2000004000040E5
+:106DC00081B200000400004081B2000004000040D5
+:106DD00081B200000400004081B2000004000040C5
+:106DE00081B200000400004081B2000004000040B5
+:106DF00081B200000400004081B2000004000040A5
+:106E000081B200000400004081B200000400004094
+:106E100081B200000400004081B200000400004084
+:106E200081B200000400004081B200000400004074
+:106E300081B200000400004081B200000400004064
+:106E400081B200000400004081B200000400004054
+:106E500081B200000400004081B200000400004044
+:106E600081B200000400004081B200000400004034
+:106E700081B200000400004081B200000400004024
+:106E800081B200000400004081B200000400004014
+:106E900081B200000400004081B200000400004004
+:106EA00081B200000400004081B2000004000040F4
+:106EB00081B200000400004081B2000004000040E4
+:106EC00081B200000400004081B2000004000040D4
+:106ED00081B200000400004081B2000004000040C4
+:106EE00081B200000400004081B2000004000040B4
+:106EF00081B200000400004081B2000004000040A4
+:106F000081B200000400004081B200000400004093
+:106F100081B200000400004081B200000400004083
+:106F200081B200000400004081B200000400004073
+:106F300081B200000400004081B200000400004063
+:106F400081B200000400004081B200000400004053
+:106F500081B200000400004081B200000400004043
+:106F600081B200000400004081B200000400004033
+:106F700081B200000400004081B200000400004023
+:106F800081B200000400004081B200000400004013
+:106F900081B200000400004081B200000400004003
+:106FA00081B200000400004081B2000004000040F3
+:106FB00081B200000400004081B2000004000040E3
+:106FC00081B200000400004081B2000004000040D3
+:106FD00081B200000400004081B2000004000040C3
+:106FE00081B200000400004081B2000004000040B3
+:106FF00081B200000400004081B2000004000040A3
+:1070000081B200000400004081B200000400004092
+:1070100081B200000400004081B200000400004082
+:1070200081B200000400004081B200000400004072
+:1070300081B200000400004081B200000400004062
+:1070400081B200000400004081B200000400004052
+:1070500081B200000400004081B200000400004042
+:1070600081B200000400004081B200000400004032
+:1070700081B200000400004081B200000400004022
+:1070800081B200000400004081B200000400004012
+:1070900081B200000400004081B200000400004002
+:1070A00081B200000400004081B2000004000040F2
+:1070B00081B200000400004081B2000004000040E2
+:1070C00081B200000400004081B2000004000040D2
+:1070D00081B200000400004081B2000004000040C2
+:1070E00081B200000400004081B2000004000040B2
+:1070F00081B200000400004081B2000004000040A2
+:1071000081B200000400004081B200000400004091
+:1071100081B200000400004081B200000400004081
+:1071200081B200000400004081B200000400004071
+:1071300081B200000400004081B200000400004061
+:1071400081B200000400004081B200000400004051
+:1071500081B200000400004081B200000400004041
+:1071600081B200000400004081B200000400004031
+:1071700081B200000400004081B200000400004021
+:1071800081B200000400004081B200000400004011
+:1071900081B200000400004081B200000400004001
+:1071A00081B200000400004081B2000004000040F1
+:1071B00081B200000400004081B2000004000040E1
+:1071C00081B200000400004081B2000004000040D1
+:1071D00081B200000400004081B2000004000040C1
+:1071E00081B200000400004081B2000004000040B1
+:1071F00081B200000400004081B2000004000040A1
+:1072000081B200000400004081B200000400004090
+:1072100081B200000400004081B200000400004080
+:1072200081B200000400004081B200000400004070
+:1072300081B200000400004081B200000400004060
+:1072400081B200000400004081B200000400004050
+:1072500081B200000400004081B200000400004040
+:1072600081B200000400004081B200000400004030
+:1072700081B200000400004081B200000400004020
+:1072800081B200000400004081B200000400004010
+:1072900081B200000400004081B200000400004000
+:1072A00081B200000400004081B2000004000040F0
+:1072B00081B200000400004081B2000004000040E0
+:1072C00081B200000400004081B2000004000040D0
+:1072D00081B200000400004081B2000004000040C0
+:1072E00081B200000400004081B2000004000040B0
+:1072F00081B200000400004081B2000004000040A0
+:1073000081B200000400004081B20000040000408F
+:1073100081B200000400004081B20000040000407F
+:1073200081B200000400004081B20000040000406F
+:1073300081B200000400004081B20000040000405F
+:1073400081B200000400004081B20000040000404F
+:1073500081B200000400004081B20000040000403F
+:1073600081B200000400004081B20000040000402F
+:1073700081B200000400004081B20000040000401F
+:1073800081B200000400004081B20000040000400F
+:1073900081B200000400004081B2000004000040FF
+:1073A00081B200000400004081B2000004000040EF
+:1073B00081B200000400004081B2000004000040DF
+:1073C00081B200000400004081B2000004000040CF
+:1073D00081B200000400004081B2000004000040BF
+:1073E00081B200000400004081B2000004000040AF
+:1073F00081B200000400004081B20000040000409F
+:1074000081B200000400004081B20000040000408E
+:1074100081B200000400004081B20000040000407E
+:1074200081B200000400004081B20000040000406E
+:1074300081B200000400004081B20000040000405E
+:1074400081B200000400004081B20000040000404E
+:1074500081B200000400004081B20000040000403E
+:1074600081B200000400004081B20000040000402E
+:1074700081B200000400004081B20000040000401E
+:1074800081B200000400004081B20000040000400E
+:1074900081B200000400004081B2000004000040FE
+:1074A00081B200000400004081B2000004000040EE
+:1074B00081B200000400004081B2000004000040DE
+:1074C00081B200000400004081B2000004000040CE
+:1074D00081B200000400004081B2000004000040BE
+:1074E00081B200000400004081B2000004000040AE
+:1074F00081B200000400004081B20000040000409E
+:1075000081B200000400004081B20000040000408D
+:1075100081B200000400004081B20000040000407D
+:1075200081B200000400004081B20000040000406D
+:1075300081B200000400004081B20000040000405D
+:1075400081B200000400004081B20000040000404D
+:1075500081B200000400004081B20000040000403D
+:1075600081B200000400004081B20000040000402D
+:1075700081B200000400004081B20000040000401D
+:1075800081B200000400004081B20000040000400D
+:1075900081B200000400004081B2000004000040FD
+:1075A00081B200000400004081B2000004000040ED
+:1075B00081B200000400004081B2000004000040DD
+:1075C00081B200000400004081B2000004000040CD
+:1075D00081B200000400004081B2000004000040BD
+:1075E00081B200000400004081B2000004000040AD
+:1075F00081B200000400004081B20000040000409D
+:1076000081B200000400004081B20000040000408C
+:1076100081B200000400004081B20000040000407C
+:1076200081B200000400004081B20000040000406C
+:1076300081B200000400004081B20000040000405C
+:1076400081B200000400004081B20000040000404C
+:1076500081B200000400004081B20000040000403C
+:1076600081B200000400004081B20000040000402C
+:1076700081B200000400004081B20000040000401C
+:1076800081B200000400004081B20000040000400C
+:1076900081B200000400004081B2000004000040FC
+:1076A00081B200000400004081B2000004000040EC
+:1076B00081B200000400004081B2000004000040DC
+:1076C00081B200000400004081B2000004000040CC
+:1076D00081B200000400004081B2000004000040BC
+:1076E00081B200000400004081B2000004000040AC
+:1076F00081B200000400004081B20000040000409C
+:1077000081B200000400004081B20000040000408B
+:1077100081B200000400004081B20000040000407B
+:1077200081B200000400004081B20000040000406B
+:1077300081B200000400004081B20000040000405B
+:1077400081B200000400004081B20000040000404B
+:1077500081B200000400004081B20000040000403B
+:1077600081B200000400004081B20000040000402B
+:1077700081B200000400004081B20000040000401B
+:1077800081B200000400004081B20000040000400B
+:1077900081B200000400004081B2000004000040FB
+:1077A00081B200000400004081B2000004000040EB
+:1077B00081B200000400004081B2000004000040DB
+:1077C00081B200000400004081B2000004000040CB
+:1077D00081B200000400004081B2000004000040BB
+:1077E00081B200000400004081B2000004000040AB
+:1077F00081B200000400004081B20000040000409B
+:1078000081B200000400004081B20000040000408A
+:1078100081B200000400004081B20000040000407A
+:1078200081B200000400004081B20000040000406A
+:1078300081B200000400004081B20000040000405A
+:1078400081B200000400004081B20000040000404A
+:1078500081B200000400004081B20000040000403A
+:1078600081B200000400004081B20000040000402A
+:1078700081B200000400004081B20000040000401A
+:1078800081B200000400004081B20000040000400A
+:1078900081B200000400004081B2000004000040FA
+:1078A00081B200000400004081B2000004000040EA
+:1078B00081B200000400004081B2000004000040DA
+:1078C00081B200000400004081B2000004000040CA
+:1078D00081B200000400004081B2000004000040BA
+:1078E00081B200000400004081B2000004000040AA
+:1078F00081B200000400004081B20000040000409A
+:1079000081B200000400004081B200000400004089
+:1079100081B200000400004081B200000400004079
+:1079200081B200000400004081B200000400004069
+:1079300081B200000400004081B200000400004059
+:1079400081B200000400004081B200000400004049
+:1079500081B200000400004081B200000400004039
+:1079600081B200000400004081B200000400004029
+:1079700081B200000400004081B200000400004019
+:1079800081B200000400004081B200000400004009
+:1079900081B200000400004081B2000004000040F9
+:1079A00081B200000400004081B2000004000040E9
+:1079B00081B200000400004081B2000004000040D9
+:1079C00081B200000400004081B2000004000040C9
+:1079D00081B200000400004081B2000004000040B9
+:1079E00081B200000400004081B2000004000040A9
+:1079F00081B200000400004081B200000400004099
+:107A000081B200000400004081B200000400004088
+:107A100081B200000400004081B200000400004078
+:107A200081B200000400004081B200000400004068
+:107A300081B200000400004081B200000400004058
+:107A400081B200000400004081B200000400004048
+:107A500081B200000400004081B200000400004038
+:107A600081B200000400004081B200000400004028
+:107A700081B200000400004081B200000400004018
+:107A800081B200000400004081B200000400004008
+:107A900081B200000400004081B2000004000040F8
+:107AA00081B200000400004081B2000004000040E8
+:107AB00081B200000400004081B2000004000040D8
+:107AC00081B200000400004081B2000004000040C8
+:107AD00081B200000400004081B2000004000040B8
+:107AE00081B200000400004081B2000004000040A8
+:107AF00081B200000400004081B200000400004098
+:107B000081B200000400004081B200000400004087
+:107B100081B200000400004081B200000400004077
+:107B200081B200000400004081B200000400004067
+:107B300081B200000400004081B200000400004057
+:107B400081B200000400004081B200000400004047
+:107B500081B200000400004081B200000400004037
+:107B600081B200000400004081B200000400004027
+:107B700081B200000400004081B200000400004017
+:107B800081B200000400004081B200000400004007
+:107B900081B200000400004081B2000004000040F7
+:107BA00081B200000400004081B2000004000040E7
+:107BB00081B200000400004081B2000004000040D7
+:107BC00081B200000400004081B2000004000040C7
+:107BD00081B200000400004081B2000004000040B7
+:107BE00081B200000400004081B2000004000040A7
+:107BF00081B200000400004081B200000400004097
+:107C000081B200000400004081B200000400004086
+:107C100081B200000400004081B200000400004076
+:107C200081B200000400004081B200000400004066
+:107C300081B200000400004081B200000400004056
+:107C400081B200000400004081B200000400004046
+:107C500081B200000400004081B200000400004036
+:107C600081B200000400004081B200000400004026
+:107C700081B200000400004081B200000400004016
+:107C800081B200000400004081B200000400004006
+:107C900081B200000400004081B2000004000040F6
+:107CA00081B200000400004081B2000004000040E6
+:107CB00081B200000400004081B2000004000040D6
+:107CC00081B200000400004081B2000004000040C6
+:107CD00081B200000400004081B2000004000040B6
+:107CE00081B200000400004081B2000004000040A6
+:107CF00081B200000400004081B200000400004096
+:107D000081B200000400004081B200000400004085
+:107D100081B200000400004081B200000400004075
+:107D200081B200000400004081B200000400004065
+:107D300081B200000400004081B200000400004055
+:107D400081B200000400004081B200000400004045
+:107D500081B200000400004081B200000400004035
+:107D600081B200000400004081B200000400004025
+:107D700081B200000400004081B200000400004015
+:107D800081B200000400004081B200000400004005
+:107D900081B20000B69F00889AB00000B69F0088AC
+:107DA0009AB00000B69F00889AB00000B69F008885
+:107DB0009AB00000B69F00889AB0000000000088CA
+:107DC0009AB00100B69F414081320000B99F224025
+:107DD0007B6F0000B69F194081B20000000019417E
+:107DE0007BB30100000000A4C4B30100000000A1A7
+:107DF000C6B3010000002FA2C8B301000814004060
+:107E000049990100B09F004D9ACC0100C29F2640C5
+:107E1000813200000000004C49C10100C09FA24116
+:107E20009B500000C69F80808032000000005249B5
+:107E3000FD9301000000004AFD930100C99F00422C
+:107E4000CD9300000000514AFD930100000000495D
+:107E5000FD930100C99F0043CB93000000005040F8
+:107E600081B20100D99F004019990100000000F083
+:107E70009AB001000000004449D10100000040F028
+:107E800080B201000000414D80B20100D19F00404E
+:107E90001999010000004C4081B20100000000442B
+:107EA00049D10100000000F09AB001000000004D2F
+:107EB00010B10000000000E249B10100000000E341
+:107EC00043B10100000000E445B1010000000040A2
+:107ED0007BB301000000484F40B10100D99F004032
+:107EE00081B200000400004081B2000004000040A4
+:107EF00081B200000400004081B200000400004094
+:107F000081B200000400004081B200000400004083
+:107F100081B200000000804081B0010004000040F8
+:107F200081B200000400004081B200000400004063
+:107F300081B200000400004081B200000400004053
+:107F400081B200000400004081B200000400004043
+:107F500081B200000400004081B200000400004033
+:107F600081B200000400004081B200000400004023
+:107F700081B200000400004081B200000400004013
+:107F800081B200000400004081B200000400004003
+:107F900081B200006A84004081B20000319A004042
+:107FA00081B200000400004081B200004D9A004000
+:107FB00081B200000400004081B200000000804057
+:107FC00081B20100000000A810B1000004000040D0
+:107FD00081B200000400004081B2000004000040B3
+:107FE00081B200000400004081B2000004000040A3
+:107FF00081B200000400004081B200000400004093
+:1080000081B200000400004081B200000400004082
+:0480100081B2000039
+:00000001FF
diff --git a/firmware/slicoss/gbrcvucode.sys.ihex b/firmware/slicoss/gbrcvucode.sys.ihex
new file mode 100644
index 0000000..bc7a839
--- /dev/null
+++ b/firmware/slicoss/gbrcvucode.sys.ihex
@@ -0,0 +1,162 @@
+:10000000000200004775010004A01301001CB75B4B
+:10001000093000B65F01001C00000020183B783A50
+:10002000001CA27701001C071D017018AD7BF1FFB9
+:100030001CB37BA9AA1EB47B010C1CB57B29061C32
+:1000400000005064080C315A70040C315A80040CC2
+:10005000314E90040C314AA000092555C0040C31E2
+:1000600052B000E92455C004CCB3001C1CEB2D0198
+:10007000001C065652D408079D00001C7BB70200E6
+:1000800010A00F51540906565EC004A0307403003E
+:10009000AC30750300CD033A001C7BB702001C6036
+:1000A0008E5154092925750300808E5154098C30D6
+:1000B000910004471C01001CA00F5154090000646A
+:1000C0000004471C65C004471C7503006C30010028
+:1000D0001C4D3402001C7BB702001CA00F515409B8
+:1000E000C88337001C800100001C0000640004A0CD
+:1000F0000F505409000074C3047BFBF2001CCC3386
+:100100000D001CB47BFD031C800E505409E0FB0560
+:10011000001C0000AC0300B30F5154090000EC7048
+:10012000040000EC80040000AC93006176ADC304D1
+:10013000C08D515409E07B00C01FA0FDC50100CC5B
+:100140003305001CD403003C1CD4D31B001CC0D3BB
+:1001500052001C00007C13048E8E5254095B807E7A
+:100160001304000000001C0000940100A00F515473
+:1001700009A00F515409C003FC7F1CA001A001007D
+:100180000000A40100A00F515409C003FC031CF59A
+:100190007701001C267A02061CA00F515409B30FE8
+:1001A000515409B50202001CA00F5154097A7E0275
+:1001B000001CB50202001C530F525409AF0301008A
+:1001C0001C7A0E525409B50202001C000002001CE9
+:1001D000A03DAA11040000AC1104D4D352001CB5F8
+:1001E0003EB2010020FBFDFF1F802C8C0300B93ABA
+:1001F0009E0100753B02001CA71C010010DB83164A
+:10020000001CC71D21C104B93B8DC1048B2C01000A
+:100210001C6B2C35C1040000781100CB2C79C10473
+:10022000A00F515409A00F51540954D002001C4989
+:1002300025B10100AB2C81C104A71D750300CC338F
+:1002400009001CEB2D01001CEA2901001CA00F5124
+:100250005409AE0F515409A00F515409D407FC039F
+:100260001C993A02001CBB3802001C003800001C1C
+:100270000000FC0104DB3B7E001CC71D01001C26A6
+:100280007A16061C271D01001CB30F5154097A0E63
+:10029000525409530F5254097A0E525409530F52B3
+:1002A00054097A0E525409530F525409A00F515455
+:1002B000097A0602001C530F525409AF0301001CB7
+:1002C0007A0E525409530F5254097A0E525409535C
+:1002D0000F5254097A0E525409530F5254097A0E90
+:1002E000525409003D02001C0000581200CB2C01A2
+:1002F000001C753B02001CA71C010010A67BFD051D
+:100300001C000090C204A67BFD051C0000A8C204CE
+:10031000CB2F05001C602C00001CC71CE90200A0AC
+:100320000F515409530702001CC083F1321C000016
+:10033000600204467AE6051C7A0E525409C083F125
+:10034000321C000068020440FA15001C0000A802DC
+:1003500004467AE6051CA00F515409A00F51540918
+:10036000A00F515409A00F515409B37B01C01F7451
+:100370000E505409C0039C001C8000F802000000CD
+:10038000F802040000CC1205071D01001CD4D32B79
+:10039000001CD4D352001C80769D1304000000037F
+:1003A00000A67BB50310C79C00001C802C00001C1D
+:1003B00000007C0204000074C304AB2DF912050791
+:1003C0001DD5C2048B2D01001C692501001CA67BD4
+:1003D000B50310CB2F09001C602C00001C00006826
+:1003E0000300530F525409467AE6051C7A0E525404
+:1003F0000940FA15001C0000300304467AE6051C8B
+:10040000B50F515409A00F51540973EC4A0304600D
+:100410002C00001C0000480300C71C01001C000049
+:10042000481305071D01001CC0D722001C75569EED
+:100430001304602C00001CE71C650304E79C00000B
+:100440001CA67BB50310802C00001C0000180304C0
+:10045000000074C304B97B01001C0000ACC304CBD2
+:10046000AFFC071CCB2F01041CC79F80031C00009E
+:10047000ACC304CBAFFC071CCB2F0D041CC79F8063
+:10048000031C0000ACC304CBAF00F81DCB2F010050
+:100490001DA67BB5031CC79CACC3040000AC1305B0
+:1004A000071D01001CC01DFCD308279D040400A0EB
+:1004B000EE66D400FB75291404207B06001CC01CCA
+:1004C0003C04000000D0D308000020F400C0EFF28C
+:1004D000001C20257C140460B7F2030000002C15DA
+:1004E00000CCB3FC031CCC3305021C00002CC5045B
+:1004F00060B72E050400002C150400007CC404C065
+:100500001DB8F304000088C404079D00001C1B7480
+:100510001DF404A67B11041CA00F895409E07B0084
+:10052000FC1F397F02001C071DBDC304A67BCD0341
+:100530001C000088C404E01C00001C0000C403046C
+:10054000CBAF00F81DCB2F01101D0000CCC3040061
+:1005500000CC0304CBAF00F81DCB2F01181DC79FA3
+:10056000000B1C0000CCC304FB7501001C071D011F
+:10057000001CCCB3FC031CCC3301021C0000CCC318
+:1005800004A01C00001CA0EEC20304CBAFFC071C9F
+:10059000CB2F09041CFB7501001C0000CCC304CC4C
+:1005A000B3FC031CCC3301021C00002CC50400006A
+:1005B000983405CCB3FC031CCC3315021C479D7446
+:1005C000C4040000984400801D9C5404871DAD04A1
+:1005D00000CE7601001CEF76BDC404A477AD2409DB
+:1005E000E47601001CC47601001C0000B85404D756
+:1005F00076015018F67601001C000000301800004B
+:10060000000010CC3061C504EB2D01001CEA29016B
+:10061000001CC05901001CF57749C504E030FC04FA
+:1006200000004CD00400204C140500000008050018
+:10063000CCB3FC031CCC3309021CEB2DD5C404CC79
+:10064000B3FC031CCC3319021CEB2DD5C404CCB372
+:10065000FC031CCC330D021CEB2DD5C404CCB3FC25
+:10066000031CCC3311021CEB2DD5C404007B00808D
+:100670001CAE77610500000004C004D38B00FC1F92
+:10068000607A3C001C604CE00400C02F20051FE095
+:1006900030D004008025D00400B55BD10404692665
+:1006A00001001C6A2B01001C801D00001CA9256193
+:1006B0000500EE3000001CAF77210500B45F01405B
+:1006C00018079D645504B77601001C967601001C3E
+:1006D000471D01001CA433016018A42F0160186499
+:1006E000770160182477016018447701001C648842
+:1006F00003001CA43F01001CA43B01001C537B0011
+:10070000C01CD3CF1B001C534F02001CDACF00C00B
+:100710001FD5570F001CD3D337001CD4530F001C18
+:10072000E02900001CF5D5CC05000000B855047781
+:100730005601001C565301001C0000001018000058
+:1007400004C004F55501001C0000D0550477560183
+:10075000001C565301001C0000001018000004C0CB
+:1007600004CB2F011810CB2F011010CB2F01081034
+:10077000CB2F010810CB2F012010CB2F010010CB65
+:100780002F012810892571C20400000CC304000049
+:1007900074C304000074C304000074C30400007038
+:1007A000C20400000CC304000074C304000074C33E
+:1007B00004000074C304401C6CC004401C9CC004B2
+:1007C000A77775C3040000C4C004271DF1C004004E
+:1007D0000074C304000074C304000074C304000068
+:1007E00048C604000048C604000048C6040000488B
+:1007F000C604000048C604000048C604000048C6FD
+:1008000004000048C604000048C604000048C604AE
+:10081000000048C604000048C604000048C60400A2
+:100820000048C604000048C604000048C604000092
+:1008300048C604000048C604000048C6040000483A
+:10084000C604000048C604000048C604000048C6AC
+:1008500004000048C604000048C604000048C6045E
+:10086000000048C604000048C604000048C6040052
+:100870000048C604000048C604000048C604000042
+:1008800048C604000048C604000048C604000048EA
+:10089000C604000048C604000048C604000048C65C
+:1008A00004000048C604000048C604000048C6040E
+:1008B000000048C604000048C604000048C6040002
+:1008C0000048C604000048C604000048C6040000F2
+:1008D00048C604000048C604000048C6040000489A
+:1008E000C604000048C604000048C604000048C60C
+:1008F00004000048C604000048C604000048C604BE
+:10090000000048C604000048C604000048C60400B1
+:100910000048C604000048C604000048C6040000A1
+:1009200048C604000048C604000048C60400004849
+:10093000C604000048C604000048C604000048C6BB
+:1009400004000048C604000048C604000048C6046D
+:10095000000048C604000048C604000048C6040061
+:100960000048C604000048C604000048C604000051
+:1009700048C604000048C604000048C604000048F9
+:10098000C604000048C604000048C604000048C66B
+:1009900004000048C604000048C604000048C6041D
+:1009A000000048C604000048C604000048C6040011
+:1009B0000048C604000048C604000048C604000001
+:1009C00048C604000048C604000048C604000048A9
+:1009D000C604000048C604000048C604000048C61B
+:1009E00004000048C604000048C604000048C604CD
+:1009F000000048C604000048C604000048C60400C1
+:040A00000048C604E0
+:00000001FF
diff --git a/firmware/slicoss/oasisdbgdownload.sys.ihex b/firmware/slicoss/oasisdbgdownload.sys.ihex
new file mode 100644
index 0000000..18b376a
--- /dev/null
+++ b/firmware/slicoss/oasisdbgdownload.sys.ihex
@@ -0,0 +1,5124 @@
+:1000000002000000004000000000010000000000AD
+:10001000008000001500004081B200001B0000407D
+:1000200081B200002100004081B2000003000040C6
+:1000300081B20000000000A898B001000480A24036
+:10004000FD7F00000900A249DD7D00000000004C9A
+:1000500080B2010007000040D1B100000000004C58
+:1000600080B201000900A240757D000060000040E0
+:10007000619901000B00A8B17E3100000900004029
+:1000800081B2000000808F981831000010000098A5
+:1000900080E40100000041988094010000000040CD
+:1000A00081B201001000009880E401000E00409829
+:1000B000809400001100004081B200000000004068
+:1000C000A59901001900294081320000190014BCD3
+:1000D000803200000E0093BC8032000000005040CF
+:1000E00081B201000080004081B200001000004099
+:1000F000A59901001F002940813200001F0014BC97
+:1001000080320000120093BC80320000000050409A
+:1001100081B201000180004081B200002000004057
+:10012000A59901002500294081320000250014BC5A
+:1001300080320000140093BC8032000000000049AF
+:10014000DD810100120100408132010033010040D5
+:10015000813201002A0014BC80320000FE0013BC72
+:10016000803200005495004045990100FFFF004097
+:10017000E599010000002F4049B101000000004056
+:10018000E1B1010000000040FDB3010000000040AB
+:10019000FFB30100330018EE803200000000005071
+:1001A00089B001003200A24189500000990000404E
+:1001B000813201003094004043990100000000F8B2
+:1001C00020B10100000000FAE0B30100390098EE10
+:1001D00080320000000000FB80B001003B0080F393
+:1001E000DE33000000000047FD9301003E0083F372
+:1001F00080320000F00000F38088010001800040A0
+:100200002EDD0100009400404399010000000046EB
+:1002100043C10100000000FA24B101007C0018EE87
+:1002200080320000450095E880320000FFFF00E8C2
+:10023000808801007C0026408132000000000040E0
+:10024000D5990100000000F2ECB30100000000F8B5
+:10025000D6B1010008000040D5990100000000F06F
+:10026000D6B10100FF0000F8EE8B0100080100404C
+:10027000D5990100FF0000F0808C0100000000F71C
+:100280008194010000000040D6B10100FF0000F899
+:10029000808801003C000040D5990100FF0000F07B
+:1002A000D68D0100FFFF00F0F0DB010000000048E8
+:1002B00081E00100000000F8819401003C01004051
+:1002C000D599010000000040D6B10100FF0000F800
+:1002D000808801000000004881E00100000000F873
+:1002E000819401003C020040D599010000000040CB
+:1002F000D6B101002C000040D5990100000000F8A3
+:10030000D6B101001E0000F082F40100FF3F00F8AA
+:1003100080D80100640026408132000000000041C6
+:1003200081D00100FFFF004080D8010000000041A3
+:100330008094010000000040D8B10100680022FA5A
+:10034000803000000000004C81E00100010000400E
+:1003500080CC010000000040DEB10100000100403F
+:10036000D5990100100000FA80E40100000000F6B9
+:100370008194010000000040D6B10100000200405D
+:10038000D5990100100000FA80E40100000000F699
+:100390008194010000000040D6B101000600004039
+:1003A000D5990100100000FBD6E5010007000040D0
+:1003B000D5990100180000FBD6E501004800004077
+:1003C000D5990100100000FAD6E501005000004068
+:1003D000D5990100100000FBD6E50100030000FBE9
+:1003E0007A890100000000F0DCB101007C00004CC3
+:1003F000DD9100007C0095E88430000000002FE9CA
+:10040000FAB3010000000040D1B10100FF0000423A
+:10041000808801003400004080CE01007C00A640AE
+:1004200081320000850000408132010002802240BC
+:10043000803200007C00004081B200000000004FCC
+:1004400081B001008E0009F9813200008C0008F9AA
+:100450008132000098001FFDF93300008B009EFDE3
+:10046000813200000000004AF39301000000804840
+:10047000F3930100000000FDF7B301000000804984
+:10048000F3930100000000FC19B1010093000AF988
+:1004900081320000000040FB81B20100000041FDFC
+:1004A00081B20100000780F9F38F0100000742F9D3
+:1004B000F38F01009700A2FFF76F00000000434098
+:1004C00081B201000000A2FFFBEF0000000080FCF1
+:1004D000E1B101000000804081B0010000940040C3
+:1004E00047990100BB000040813201000000A24694
+:1004F000FD7F01000094004047990100CE000040BC
+:10050000813201000000A244FD7F01000094004000
+:100510004599010000000040F1B10100FF7F00405B
+:10052000F5990100FF7F0040F59901009A13004002
+:10053000F599010007000040F59901000100004015
+:10054000F599010000020040F59901000200004009
+:10055000F599010000020040F599010003010040F7
+:10056000F599010000000040F59901009A13004040
+:10057000F59901000B000040F59901008000004052
+:10058000F599010000000040F599010000000040CD
+:10059000F599010007000040F599010008000040AE
+:1005A000F5990100B0020040F599010000000040FB
+:1005B000F599010000000040F59901000229004072
+:1005C000F599010000000040F59901000067004026
+:1005D000F599010000000040F599010080000040FD
+:1005E000F599010000008040F599010000000045E8
+:1005F000FD83010000000046FD830100FF7F0040F5
+:1006000025990100C4000040813201000000A2448D
+:1006100080B2000000000045FD930100E2000040B0
+:10062000833001000000A2458032010000008046B6
+:10063000FD9301000010004083980100DD000040A0
+:100640002B3101000000A24688B0000000000041EC
+:1006500089B00100000000948CB00100FFFF00464B
+:1006600080880100A5A5A24080CE000000000048BF
+:100670008DF00100C90082418940000000008040E7
+:1006800089B0010000000044FD830100D400004057
+:10069000813201000000A24480B20000E2000008A4
+:1006A000833001000000A245803201000000804438
+:1006B000FD93010000300008839801008000004095
+:1006C0002B990100DB000040893001000000A246A8
+:1006D00080B20000FFFF009480880100A5A5A24021
+:1006E000804E01000000804389B001000384004176
+:1006F0002C990100DE00004081B200000388004117
+:100700002C990100000000208DB0010000009F9690
+:1007100080B20000DF00A2418D5000000000804048
+:1007200081B20100FF7F0040259901000000004CCC
+:1007300089E00100DD000044821401000000909473
+:100740008AB0000000000045F0B101001000004533
+:1007500088F401000000004489D00100DD0000445D
+:100760002B410100EC00084180320000ED000094B4
+:1007700024B100001000009424F501000000009452
+:10078000F0B10100F200A04489500000DD000044F7
+:100790002B41010000000094F0B10100EF00204463
+:1007A000895000001000004588F40100000000FAA4
+:1007B0008AB001000000A34289D00000F700A0FA2F
+:1007C0008A400000000000418BC00100F500A342F8
+:1007D00089500000FFFF0045888801001000004597
+:1007E0008AF40100FC0090448A40000000000041AF
+:1007F0008BC00100FFFF00458AA801000000805067
+:100800008BE00100FF7F0040259901007C00004043
+:100810002B9901000030004083980100DD000008A2
+:1008200083140100000000942AB101000080004000
+:10083000F99B0100DD0000FC19310100000040942B
+:1008400080B20100DD0000442B4101000000419412
+:1008500080B2010000000041F9C301000000004423
+:100860002BC1010004019F948032000002800040EF
+:1008700081B200001001005193B000001001004D42
+:1008800093B000001001004993B000000000004246
+:1008900093B001001001A24193500000000080407D
+:1008A00081B201000000104081B20100000011403F
+:1008B00081B201000000124081B20100000013402B
+:1008C00081B201000000144081B201000000154017
+:1008D00081B201000000164081B201000000174003
+:1008E00081B201000000184081B2010000001940EF
+:1008F00081B2010000001A4081B2010000001B40DB
+:1009000081B2010000001C4081B2010000001D40C6
+:1009100081B2010000001E4081B2010000001F40B2
+:1009200081B201000000704081B2010000007140FE
+:1009300081B201000000724081B2010000007340EA
+:1009400081B201000000744081B2010000007540D6
+:1009500081B201000000764081B2010000007740C2
+:1009600081B201000000784081B2010000007940AE
+:1009700081B2010000007A4081B2010000007B409A
+:1009800081B2010000007C4081B2010000007D4086
+:1009900081B2010000007E4081B2010000007F4072
+:1009A00081B201000000804081B2010000040040DB
+:1009B000A199010000000050A1D1010000000040F9
+:1009C0001BB001000000004019B001000000004011
+:1009D00017B001000000004015B001000000004009
+:1009E00013B001000000004011B001000000004001
+:1009F0000FB00100000000400DB0010000000040F9
+:100A00000BB001000000004009B0010000000040F0
+:100A100007B001000000004005B0010000000040E8
+:100A200003B001000000004001B001003B0120487C
+:100A3000A15100000000804081B201004701224B1B
+:100A4000747D00000000804081B201006000004B16
+:100A500060990100000000B17EB101004801A8408A
+:100A6000813200004501004081B200000500804055
+:100A700097980100180000AA9688010000008043A2
+:100A800097F00100070000AA96880100000080404E
+:100A900081B201000000005807900100D89F00407B
+:100AA00081B2000000000044A5B30100D80200405C
+:100AB00081320100F8020040813201000000005C38
+:100AC00007900100D89F0040BFB300005A0122CC1C
+:100AD000857F00000000005107900100D89F004072
+:100AE00081B200000000004049B10100AE0300CB1C
+:100AF000A3C90100D0140040A19B01000000002008
+:100B000046B1010000000048F1B10100000000D032
+:100B1000F1B10100000000CAF1B10100000000D5F0
+:100B2000E1B10100070000406199010020000020B0
+:100B300062DD01006301A84081320000000000CCAA
+:100B400085930100F802004081320100D01400407A
+:100B500043990100000000FABAB30100000000FA56
+:100B6000A4B30100000000F8BCB3010000142F4042
+:100B700081B00100000000E7A7B30100000000D829
+:100B8000A9B30100FF0000DD8188010002000040E0
+:100B900080F401007301004080C80100860100DD7F
+:100BA000813200000000004010B1000087010040C9
+:100BB00081B200008801004081B20000890100403C
+:100BC00081B200008A01004081B200008B01004028
+:100BD00081B200008D01004081B200008F01004011
+:100BE00081B200005001004081B20000B601004017
+:100BF00081B200005001004081B20000C4010040F9
+:100C000081B20000C501004081B2000082020040B4
+:100C100081B200008302004081B22800B802004087
+:100C200081B22800D49F004081B22800D59F0040A7
+:100C300081B22800D69F004081B22800D79F004093
+:100C400081B228007201004181C02800550151493C
+:100C5000FD9328005501524AFD932A00550155493C
+:100C6000FD832A005501564AFD832A0050019181D7
+:100C700080302A005501454081B22A0050019182FE
+:100C800080302A005501464081B22A000000004011
+:100C900089B02B0000002F4081B0010000140040FB
+:100CA00049990100B30122DEE16D00000000004C13
+:100CB00049C101000000004181C001009201A2442D
+:100CC000816C00000000004C49D101009A012240D3
+:100CD000E16D00009601A2418150000050010041E9
+:100CE000BFB3000000000042BFB301005001A00FDD
+:100CF000BD6F0000000000DEE1B101000000004413
+:100D000049C10100B50100401999010000004240AD
+:100D100081B20100000043FF85B00100000000DE49
+:100D200019B10100000042FF87B00100000043FF3D
+:100D3000E1B101000000004449C1010000002FFFA3
+:100D4000E1B10100081400A480CC0100AA012640F2
+:100D5000813200000000004185C00100A801A24CC2
+:100D600081500000B40122D281320000AF01224143
+:100D7000A56F00005001A2E081320000000000D207
+:100D8000C1B301000000005C8990010000004042F6
+:100D900080B201000000414380B20100000000F079
+:100DA0008894010055010044E0B10000B101004801
+:100DB00049C10000AF01005B89900000A89F00A01E
+:100DC0009EB000000000004083B00100001400400D
+:100DD000499901000000234081B00100BE0122DEDC
+:100DE000E16D00000000004C49C10100000000411D
+:100DF00081C00100B901A244816C00005001004390
+:100E0000BFB30000000000F818B10100000040F876
+:100E100080B20100000041F080B2010000000040FB
+:100E2000F1B1010000000040F1B1010055010040A6
+:100E3000E1B10000C601004091B000000000004197
+:100E400091B00100D0142E4049B1010005000040CE
+:100E5000A39B0100080000DD81F40100CB010040EC
+:100E600080C801000000004010B10000D101004026
+:100E700081B00000530100DEA1B30000E301004097
+:100E800081B20000E501004081B00000EB010040AC
+:100E900081B20000520100DFE1B10000000000D08B
+:100EA000BAB30100000000DEA1B10100020000D2CF
+:100EB000A5E70100000000D2C1B30100000000005E
+:100EC000F0B10100DB012244C1530000DA0184418A
+:100ED00081400000DE01004081320100000000D0AE
+:100EE00045B10100D5010041A1C10000DA02004076
+:100EF00081320100F802004081320100550100DD1D
+:100F0000A1B100000000004081B00100400000409D
+:100F1000A59B0100DA02004081320100400000D3AD
+:100F2000A7CB0100F80200E0A5B3000003000040D9
+:100F3000A39B0100530100DEA1B3000000000044A8
+:100F4000BFB30100000000DE819001005001A2BA91
+:100F500080040000600000DE61990100E801A8B192
+:100F60008030000052010040E0B10000000000D0DD
+:100F7000BAB301006B020040819801006002004D8D
+:100F80008330010000000044E1B301000000004490
+:100F9000E3B3010000000044E5B301000000004499
+:100FA000E9B3010000000044EBB30100000000447D
+:100FB000F5B3010000000044F7B301000000004455
+:100FC000F9B30100F90122408F6F00007802004060
+:100FD00081980100600200C7833001008002004058
+:100FE000819801006002004283300100000000E8A7
+:100FF000F1B10100000000E9F1B10100000000EAD8
+:10100000F1B10100000000EBF1B10100000000852A
+:10101000F0B10100000000ECF1B10100000000EDB2
+:10102000F1B10100000000B2F0B10100000000A920
+:10103000F0B10100000000ACF0B10100000000AB15
+:10104000F0B10100000000B8F0B10100000000B9EB
+:10105000F0B10100000000BAF0B10100000000BBD7
+:10106000F0B101000C02B8408130000000000040E7
+:10107000819001000E02B940813200000000004161
+:10108000819001001002BA4081320000000000424D
+:10109000819001001202BB40813200000000004339
+:1010A000819001001402BC40813200000000004425
+:1010B000819001001602BD40813200000000004511
+:1010C000819001001802BE408132000000000046FD
+:1010D000819001001A02BF408132000000000047E9
+:1010E000819001001C02C8408132000000000048CD
+:1010F000819001001E02C9408132000000000049B9
+:10110000819001002002CA40813200000000004AA4
+:10111000819001002202CB40813200000000004B90
+:10112000819001002402CC40813200000000004C7C
+:10113000819001002602CD40813200000000004D68
+:10114000819001002802CE40813200000000004E54
+:10115000819001002A02CF40813200000000004F40
+:10116000819001002C02F04081320000000000500C
+:10117000819001002E02F1408132000000000051F8
+:10118000819001003002F2408132000000000052E4
+:10119000819001003202F3408132000000000053D0
+:1011A000819001003402F4408132000000000054BC
+:1011B000819001003602F5408132000000000055A8
+:1011C000819001003802F640813200000000005694
+:1011D000819001003A02F740813200000000005780
+:1011E000819001003C02F84081320000000000586C
+:1011F000819001003E02F940813200000000005958
+:10120000819001004002FA40813200000000005A43
+:10121000819001004202FB40813200000000005B2F
+:10122000819001004402FC40813200000000005C1B
+:10123000819001004602FD40813200000000005D07
+:10124000819001004802FE40813200000000005EF3
+:10125000819001004A02FF40813200000000005FDF
+:101260008190010000000040F0B10100400000400A
+:10127000A59B0100D802004081320100F802004025
+:1012800081320100D0142E06A5B30100400000D326
+:10129000A7CB0100000000F0F1B10100000000F157
+:1012A000F1B10100000000F2F1B10100000000F412
+:1012B000F1B10100000000F5F1B10100000000FAF9
+:1012C000F1B10100000000FBF1B10100000000FCE1
+:1012D000F1B10100000000EBF1B10100000000EEEF
+:1012E000F1B10100000000EFF1B10100000000F3D6
+:1012F000F1B10100000000F6F1B10100000000FDB5
+:10130000F1B10100DB0100C7E1B100000000804045
+:1013100081B20100660200488032000000005140A6
+:101320001AB1010000004D4081B2010000004540AB
+:1013300081B201006302A241835000005F02494074
+:1013400081B20000000052401CB1010000004E407C
+:1013500081B201000000464081B201006802A24152
+:10136000835000005F024A4081B20000000000A0EC
+:101370009EB0010000000080D8B30100000000A171
+:10138000D0B30100000000A2D2B30100000000A40D
+:10139000D4B30100000000D0D6B30100000000D19A
+:1013A000DCB30100000000D2DEB3010000000088C1
+:1013B000DAB30100000000D48EB30100000000D3B6
+:1013C000E6B30100000000ACECB30100000000999E
+:1013D000FAB30100000000D5E0B30100000000D521
+:1013E000E2B30100000000D5E4B30100000000D525
+:1013F000E8B30100000000D5EAB30100000000D509
+:10140000F4B30100000000D5F6B30100000000D5E0
+:10141000F8B30100000000C7A9B101000000004FAF
+:1014200040B101008402004091B000000000004182
+:1014300091B0010007000040A39B0100080000DDFF
+:1014400081F401008802004080C8010000000040D3
+:1014500010B100008D02004081B2000098020040EF
+:1014600081B2000098020046A3B300009B02004036
+:1014700081B20000A102004081B200008F0223501F
+:10148000A56F000000000050A5B30100E802004273
+:10149000A5630100F802004081320100D0142D4004
+:1014A00049B10100000000D0BAB30100000000DE25
+:1014B000A1B10100000000F800B001009702224431
+:1014C000A553000094020041A1C10000550100DDB8
+:1014D000A1B10000E80200DEA1330100F8020040E3
+:1014E000813201005501004081B20000000000453A
+:1014F000BFB301005001A2D2777D0000000000D2EE
+:1015000061B10100000000DE63B101009E02A8404D
+:10151000813200005501004081B20000E802005411
+:10152000A5330100F802004081320100D0142D40A3
+:1015300049B10100000000F8D0B30100000000F83C
+:10154000D2B30100000000F8D4B30100000000F89D
+:10155000D6B30100000000F808B10100AC02004061
+:10156000819801006002004683300100550100406F
+:1015700081B20000000000A09EB00100000000E861
+:1015800043B10100000000E945B10100000000EA9C
+:1015900049B10100000000EBA1B101000000004FC3
+:1015A00040B101000400004081B20000040000408E
+:1015B00081B200000400004081B20000040000403D
+:1015C00081B200000400004081B20000040000402D
+:1015D00081B20000D0142E4049B101000500004046
+:1015E000A39B010000000040C1B30100080000DD22
+:1015F00081F40100BD02004010C90000C3020005D3
+:1016000081B000005001004081B20000CB02000513
+:1016100081B000005001004081B20000D0020044BF
+:10162000A5B30000D2020044A5B3000002000040B0
+:10163000A4E70100000000E081B10100FFFF00C14C
+:10164000F0890100C802224181500000C40200411B
+:10165000C1C30000DA02004081320100F8020040FC
+:10166000813201005501004081B2000002000040BB
+:10167000A4E70100000000E091B10100FFFF00C9F4
+:10168000F0890100C802224181500000CC020041D3
+:10169000C1C30000FFFF00DE85890100C80200C24F
+:1016A000E0B10000FFFF00DE95890100C80200CA1A
+:1016B000E0B100000400004081B2000004000040DE
+:1016C00081B200000400004081B20000040000402C
+:1016D00081B20000000000E7A7B30100000000D8BD
+:1016E000A9B301000000004049B10100AE0300CBE6
+:1016F000A3C901000000002046B10100000000D293
+:10170000F1B10100000000D3F1B10100000000D4EC
+:10171000F1B10100000000D0E1B10100000000D1F2
+:1017200061B101002000002062DD0100E202A8405A
+:1017300081320000000080CC85930100040000404D
+:1017400081B200000400004081B2000004000040AB
+:1017500081B20000000000E7A7B30100000000D83C
+:10176000A9B301000000004049B10100AE0300CB65
+:10177000A3C901000000002046B10100000000D212
+:10178000F1B10100000000D0F1B10100000000D370
+:10179000F1B10100E10200D4E1B100000400004019
+:1017A00081B200000400004081B20000040000404B
+:1017B00081B200000400004081B20000040000403B
+:1017C00081B200000400004081B20000040000402B
+:1017D00081B200000000A2CC85FF00000000005094
+:1017E00081B00100FA02A24181500000F902A2F288
+:1017F00080300000000080CC8583010004000040A0
+:1018000081B200000400004081B2000004000040EA
+:1018100081B20000B5030040A199010000002F41F2
+:1018200099B301000A032244816C0000120322488C
+:10183000816C00000C03224C816C000016032250C6
+:10184000816C000017032254816C00001903225898
+:10185000816C00001E03225C816C0000500100407E
+:1018600081B20000000000BC09B00100DD9F00CA89
+:1018700001B000000000004003B001000000004182
+:10188000F38301001003A242056C00000000004138
+:1018900005B00100DD9F22CA07140000DD9F00454E
+:1018A000F3930000DD9F2043956F0000DD9F80CA09
+:1018B00005300000DD9F220180300000DD9F00CB5D
+:1018C000DB910000570100BCABB30000000000BC7E
+:1018D000B1B30100DD9F00CACFB30000FF0000CA12
+:1018E00081880100DD9FA240747D000060002040DF
+:1018F000609901001B03A8B1823000001A03004068
+:1019000081B20000DD9F00CA79B3000004000040EE
+:1019100081B200000000004E81B0010000000043D1
+:10192000CB8301000000454081B201002203A241A7
+:10193000815000000000454081B201000000454098
+:1019400081B201002D039182823000000000008AE4
+:1019500080B00100AE9F004080CE01002B03A64066
+:10196000813200002D03564081B20000B5030040D3
+:10197000A19901000000005307900100B503004049
+:10198000A19901000000005207900100D89F00417A
+:101990008BB300000000004E81B001000000004247
+:1019A000CD8301000000464081B201003203A24114
+:1019B000815000000000464081B201000000464016
+:1019C00081B201003D039181823000000000008956
+:1019D00080B00100AE9F004080CE01003B03A640D6
+:1019E000813200003D03554081B20000B503004044
+:1019F000A19901000000005207900100B5030040CA
+:101A0000A19901000000005307900100D89F0041F8
+:101A10008BB30000B0030040A1990100C4142F4013
+:101A200099B301005701004049B100000400004093
+:101A300081B200000400004081B2000004000040B8
+:101A400081B200000400004081B2000004000040A8
+:101A500081B200003094004043990100009000F8EA
+:101A600080980100100000F288E40100200000408E
+:101A7000209901000000005F239101004D031F9198
+:101A80008032000030000040209901000000005F1B
+:101A90002391010050031F9180320000400000405C
+:101AA000209901000000005F2391010053031F9162
+:101AB000803200000000005F2391010055031F9158
+:101AC000803200000008804020990100040000409E
+:101AD00081B200000000004784B001000000A2486D
+:101AE000848400000000005F61B101000000005C20
+:101AF0008F9001000000004762B101005A03A84026
+:101B000081320000000800478EC801005803005CC5
+:101B10008F800000E00000406199010058152D40C1
+:101B20008DB00100D0142DF088B00100000000FA43
+:101B30008AB001000000004581B0010007000045A7
+:101B400082880100000000438BF001000000004883
+:101B500083E0010000000046829401002000004163
+:101B600060990100000000418DC001007403225FF4
+:101B70008D6C00006503A2418150000063030040AA
+:101B800081B2000008000040859801000000004478
+:101B900082B001000000004186B00100001C00433B
+:101BA00086D801000000A641855001007003004165
+:101BB00083E000006E030040813201000000004815
+:101BC00085E00100D0142F468494010020000042DB
+:101BD00060990100C0000040619901000000804050
+:101BE00081B201000400004081B200000400004006
+:101BF00081B200000400004081B2000004000040F7
+:101C000081B200000400004081B2000004000040E6
+:101C100081B20000070000458088010000000043F9
+:101C20008BF0010000040040839801008503A0416F
+:101C3000815000008303004182E8000000008041E1
+:101C40008EC001000400004081B20000040000408A
+:101C500081B200000000004049B1010000020040D4
+:101C600083980100003900404599010000000040C0
+:101C7000F1B101008B03A24183500000000000403D
+:101C800085B001000B00004482F401001A1500A683
+:101C900086B0010070150040459901000008004021
+:101CA000F199010000000042F0B10100003900404C
+:101CB000E1990100040000406199010070150043A2
+:101CC000629901009503A840813200009703225ACF
+:101CD000737D00007A000040619901009803A8B16B
+:101CE0007E3100000008004284C801009003A24138
+:101CF000835000000000804081B2010004000040D9
+:101D000081B200000400004081B2000004000040E5
+:101D100081B2000058152D408DB00100D0142DF077
+:101D200088B00100000000408FB00100010000A653
+:101D300090B0010000F800489098010000000045B4
+:101D400093B00100000000FA8AB001008003004057
+:101D500081320100020000A680B00100AC032240E5
+:101D6000826C0000B0030040813201005803004043
+:101D700081320100000000418DC00100B503225FE7
+:101D80008D6C0000A703A24193500000A503004002
+:101D900081B20000FF070047848801000000A640D0
+:101DA00081B20000ED9F0047803001000002004733
+:101DB0008EC80100B003004081B200000000004462
+:101DC00050B30100BB032018896C0000040000A67A
+:101DD00084B00100200000A686B001000010004081
+:101DE000559B0100BE03004081B20000040000A624
+:101DF00084B00100200000A686B001000010004061
+:101E0000559B01000000004250D30100000000A8D3
+:101E10004FB30100000000434ED301006E030040A9
+:101E2000813201008203004280300100B003004093
+:101E300081320100C70322A78F6C00005A030040C3
+:101E400081320100C403004081B2000000008040E4
+:101E500081B20100C8142EBB85B00100000000EE65
+:101E600082B0010000000041E0B10100000000A2CA
+:101E7000A0B3010000000044A5B30100E19F00CA27
+:101E8000A7330100E09F004081B200000400004041
+:101E900081B20000D6032242756F0000D8032241B0
+:101EA000756F0000DA031ECA81320000DC031FCA0E
+:101EB00081320000000000CAC9B10100DD9F00426C
+:101EC00075B30000000000CACDB10100DD9F0041E4
+:101ED00075B30000000000CACFB10100DD9F0040D3
+:101EE00075B30000008100A6C6B10100DD9F00406F
+:101EF00081B20000008000A6C6B10100DD9F004055
+:101F000075B300000400004081B2000004000040EE
+:101F100081B200004501004D933001004501004EA3
+:101F2000933001004501004C93300100EC9F0040CC
+:101F300081320100DD9F004081B2000004000040BA
+:101F400081B200000400004081B2000004000040A3
+:101F500081B200005495004045990100DD9F00CA00
+:101F6000E5B100000400004081B200000400004020
+:101F700081B200000400004081B200000400004073
+:101F800081B200000400004081B200000400004063
+:101F900081B20000CC142E4087B00100000000A2E6
+:101FA000A0B3010015040043B2330100000068DA59
+:101FB00089B001007C0000408B98010000000050B7
+:101FC00089F001000000004189D0010003000044B5
+:101FD000888C01000000004487C00100000000411F
+:101FE000A5B3010015040043B2330100000000DA7C
+:101FF000F1B101000000004487C001000000004171
+:10200000A5C301000B042244895000000B042244A4
+:102010008B500000FA03A250A56F000000000042A0
+:10202000A5E30100000000CAA7B30100E19F00BBC7
+:1020300085300100CC142ED295C30100AE0300CB35
+:10204000A3C901000000002042B1010000000050BF
+:1020500081B001000804A241815000000704A2F2EF
+:1020600080300000FA030040A5B3000000000042E9
+:10207000A5E30100000000CAA7B30100E19F00BB77
+:1020800085300100E09F004081B200000400004064
+:1020900081B20000000000D92BB101000010004007
+:1020A00083980100DB00004081320100FFFF0094B3
+:1020B000B48B01000000804081B20100000000D913
+:1020C0002BB101000010004083980100DD000040AA
+:1020D0008132010000008094B4B30100040000408C
+:1020E00081B200000400004081B200000400004002
+:1020F00081B200000400004081B2000004000040F2
+:1021000081B200000400004081B2000004000040E1
+:1021100081B20000000000D92BB10100000000DAFC
+:1021200027B1010006C000402D990100DE000040EB
+:1021300081320100001000408398010002C4004178
+:102140002C990100DE000040813201000040004077
+:1021500083980100058200412C990100DE000040B7
+:10216000813201002D048094803200000C01004077
+:10217000813201002804004081B200000480004048
+:102180002D990100DE0000408132010000008040F6
+:1021900081B201003104001210C9000000488040E3
+:1021A0000B980100C04980400B980100804B804093
+:1021B0000B980100404D80400B980100004F80407B
+:1021C0000B980100C05080400B9801008052804065
+:1021D0000B980100405480400B980100005680404D
+:1021E0000B980100C05780400B9801008059804037
+:1021F0000B980100405B80400B980100005D80401F
+:102200000B980100C05E80400B9801008060804008
+:102210000B980100406280400B98010000648040F0
+:102220000B980100C06580400B98010080678040DA
+:102230000B980100406980400B980100006B8040C2
+:102240000B980100C06C80400B980100806E8040AC
+:102250000B980100407080400B9801000072804094
+:102260000B980100C07380400B980100807580407E
+:102270000B980100407780400B9801000079804066
+:102280000B980100C07A80400B980100807C804050
+:102290000B980100407E80400B9801000400004034
+:1022A00081B200000400004081B200000400004040
+:1022B00081B200000400004081B200000400004030
+:1022C00081B200000400004081B200000400004020
+:1022D00081B200005904001210C900000080804043
+:1022E0000B980100008280400B9801000084804020
+:1022F0000B980100008680400B9801000088804008
+:102300000B980100008A80400B980100008C8040EF
+:102310000B980100008E80400B98010000908040D7
+:102320000B980100009280400B98010000948040BF
+:102330000B980100009680400B98010000988040A7
+:102340000B980100009A80400B980100009C80408F
+:102350000B980100009E80400B98010000A0804077
+:102360000B98010000A280400B98010000A480405F
+:102370000B98010000A680400B98010000A8804047
+:102380000B98010000AA80400B98010000AC80402F
+:102390000B98010000AE80400B98010000B0804017
+:1023A0000B98010000B280400B98010000B48040FF
+:1023B0000B98010000B680400B98010000B88040E7
+:1023C0000B98010000BA80400B98010000BC8040CF
+:1023D0000B98010000BE80400B98010004000040F3
+:1023E00081B200000400004081B2000004000040FF
+:1023F00081B200000400004081B2000004000040EF
+:1024000081B200000400004081B2000004000040DE
+:1024100081B200000000004087B1010000000040D0
+:1024200097B001000000004B80B10100010000A640
+:1024300082B1010082048541974000000000004005
+:1024400097B101000000004097B001000000004B70
+:1024500090B10100010000A692B1010087048541FE
+:10246000974000000000804081B20100040000405D
+:1024700081B200000400004081B20000040000406E
+:1024800081B200000400004081B20000040000405E
+:1024900081B2000090046040813200000000001210
+:1024A00080B10100FFFFF04B82890100930460407E
+:1024B000813200000000004A80B101000100F0A656
+:1024C00082B101009604604081320000FFFF004BA2
+:1024D000848901000000F0C224B001000000004A1D
+:1024E00090B10100FFFF804B928901000000004A7B
+:1024F00090B10100010080A692B10100FFFF004BE6
+:1025000094890100000080CA94B0010004000040DA
+:1025100081B200001000004E98E4010000000007A6
+:10252000989401000000004399E001000000008041
+:10253000989401000000004999E001000000004C5F
+:1025400088940100A604474081320000AD04222097
+:10255000876F000000001F4081B2010000000040B2
+:1025600081B201000000004081B201000000004083
+:1025700081B20100A604004081B2000000001F806B
+:1025800086B30100B004224F777D0000C0040040F4
+:10259000813201000000004F61B1010000000044E1
+:1025A00062B10100B104A84081320000B804224B9E
+:1025B000897C0000B604224F777D0000C0040040F3
+:1025C000813201000000004562B10100B604A8405C
+:1025D000813200000000802087B301000400004029
+:1025E00081B200000400004081B2000004000040FD
+:1025F00081B200000400004081B2000004000040ED
+:1026000081B200000400004081B2000004000040DC
+:1026100081B200000000005099B001006F0000403E
+:1026200061990100C104A8B152330000C604224BD5
+:10263000537F00006F00004061990100C404A8B1FD
+:102640007E310000C104A241995000000000A24F59
+:1026500077FD00000400004081B20000040000404B
+:1026600081B200000400004081B20000040000407C
+:1026700081B200000400004081B20000040000406C
+:1026800081B200000400004081B20000040000405C
+:1026900081B200001000004E98E401000000000725
+:1026A000989401000000004399E0010000000080C0
+:1026B000989401000000004899E00100D604004C05
+:1026C00088940000D604474081320000DD042220B7
+:1026D000876F000000001F4081B201000000004031
+:1026E00081B201000000004081B201000000004002
+:1026F00081B20100D604004081B2000000001F80BA
+:1027000086B30100E004224F777D0000F004004012
+:10271000813201000000004F61B10100000000445F
+:1027200062B10100E104A84081320000E804224ABD
+:10273000897C0000E604224F777D0000F004004011
+:10274000813201000000004562B10100E604A840AA
+:10275000813200000000802087B3010004000040A7
+:1027600081B200000400004081B20000040000407B
+:1027700081B200000400004081B20000040000406B
+:1027800081B200000400004081B20000040000405B
+:1027900081B200000000005099B001006F000040BD
+:1027A00061990100F104A8B152330000F604224AF5
+:1027B000537F00006F00004061990100F404A8B14C
+:1027C0007E310000F104A241995000000000A24FA8
+:1027D00077FD00000400004081B2000004000040CA
+:1027E00081B200000400004081B2000004000040FB
+:1027F00081B200000400004081B2000004000040EB
+:1028000081B200000400004081B2000004000040DA
+:1028100081B200007B000040619901000005A8B171
+:102820008030000012051D4080320000401800403A
+:1028300049990100040000A686B001001005A240DD
+:1028400086040000DE9F9C4080320000FFFF0040B5
+:1028500088880100300500504731010036000044EF
+:1028600088CC01000C055240813200003005004048
+:10287000473101000000004189B0010030050048E7
+:10288000473101003005000547310100DE9F00405F
+:1028900081B200002800004047991B00DE9F0041E4
+:1028A000E1C11A007818004049991B00190522540B
+:1028B000817C1A001405424081321A00008200B364
+:1028C00067DF1B0000001A4493931B0028000040A0
+:1028D00047991B00300500418930010027050F4052
+:1028E00080320000FF7F00408888010030050050E2
+:1028F000473101003600004488CC01001F05994093
+:10290000803200000000004889D0010021059B4072
+:10291000803200000000004C89D0010023051F44D4
+:1029200080320000300500404731010000000041C6
+:1029300089B00100300500484731010030050058DA
+:1029400047310100DE9F004081B2000010000040CE
+:1029500086F401006F00004386880100DE9F260593
+:10296000473100003005004189300100DE9F004002
+:1029700081B200000400004081B200000400004069
+:1029800081B200000400004081B200000400004059
+:1029900081B200000000A044F041010000000040AE
+:1029A00081B2010000008041E1C10100040000404B
+:1029B00081B200000400004081B200000400004029
+:1029C00081B200000400004081B200000400004019
+:1029D00081B200004C010007913001000000A240CC
+:1029E00097EC00000000800591C001000400004049
+:1029F00081B200000400004081B2000004000040E9
+:102A000081B200000400004081B2000004000040D8
+:102A100081B200004C010040813201004405A24017
+:102A2000976C00003A000040B39B01004505004050
+:102A300081B2000040000040B39B01001004004040
+:102A400081320100000000DAF5B1010010040042FB
+:102A5000B3430100000000DAF5B1010010040042A8
+:102A6000B3430100000000DAF5B101004E00004060
+:102A7000B39B01001004004081320100080000DA1D
+:102A8000F7F5010050000040919801000000004758
+:102A90008FB0010010040048B2330100000000DADA
+:102AA000F7B10100080000DAF7F50100000000426C
+:102AB00091C001005005A2418F500000000000416C
+:102AC00045D1010008000040B39B01001004004004
+:102AD00081320100000000DAFDB101000A0000406F
+:102AE000B39B01001004004081320100000000DAB5
+:102AF000FDB101001A000040B39B0100100400402A
+:102B000081320100000000DAFDB101001800004030
+:102B1000B39B01001004004081320100000000DA84
+:102B2000FDB1010038050040813201001E0000485F
+:102B3000B2CB01001004004081320100000000DA35
+:102B400091C0010000000048B2CB01001004004019
+:102B50008132010000006EDA8FB0010002000048EF
+:102B6000B2CB01001004004081320100000000DA05
+:102B7000FDB1010004000048B2CB01001004004088
+:102B800081320100000080DAFDB101000400004044
+:102B900081B200007A052245FD7F0000401600400A
+:102BA00045990100DB9F00404931010008000048C1
+:102BB000B2CB010015040040813201007805A2402B
+:102BC0008F6C00007D052220B56F00007A05004063
+:102BD00081B20000DA9F004081321F007D05224053
+:102BE000976C1E007A05424081321E000000004FA3
+:102BF00067931F00DF9F005867931E005416004024
+:102C000047991F00000000FEF4B11F0000000040C3
+:102C100081B21F00000000FEF4B10100000000407E
+:102C200081B20100000000FEF4B10100000000408C
+:102C300081B20100000000FEF4B10100000000407C
+:102C400081B20100000000FEF4B10100000000406C
+:102C500081B20100000000FEF4B10100000000405C
+:102C600081B20100000000FEF4B101004600004006
+:102C7000B39B01001004004081320100080000DA1B
+:102C8000F7F501004800004095980100000000445D
+:102C900097B001001004004AB2330100000000DACE
+:102CA000F7B10100080000DAF7F50100000000426A
+:102CB00095C001009005A241975000002A000040F5
+:102CC000A59B010040160040A19B0100000000CA26
+:102CD000A7B30100E19F00BB85300100E09F0040E9
+:102CE00081B200000400004081B2000004000040F6
+:102CF00081B200000400004081B2000004000040E6
+:102D000081B200000400004081B2000004000040D5
+:102D100081B20000B8052245FD7F0000E0150040AB
+:102D2000479901001A0000A280DC01000000005059
+:102D3000F1B10100F0150040F1990100000000CA56
+:102D4000F1B101000700004061990100200000403E
+:102D500062DD0100A705A8BBE131000000000050C2
+:102D600083B00100AA05A24183500000A905A2F288
+:102D7000823000004C01004081320100B005A240C9
+:102D8000976C00003A000040B39B0100B105004081
+:102D900081B2000040000040B39B0100F0150040EC
+:102DA000439901001004004081320100B805A2FAE5
+:102DB000B46F000010040042B3430100B805A2FA4A
+:102DC000B46F000010040042B3430100BB0522FAB7
+:102DD000B46F0000B8054240813220000000004E70
+:102DE00067932100DF9F0058679320004016004042
+:102DF00045992100DB9F004049312100F615004034
+:102E0000439921005C1600404599210000006EFAAC
+:102E10008EB021000000004081B20100000000FEE1
+:102E2000F4B101000000004081B20100000000FE8A
+:102E3000F4B101000000004081B20100000000F088
+:102E4000B4B30100C905A2408F6C0000FC1520201E
+:102E5000E1B10100CE05004081B22400DA9F0040BC
+:102E600081322500CE052240976C2400CB054240DC
+:102E7000813224000000004F67932500DF9F005837
+:102E80006793240038050040813225001E00004869
+:102E9000B2CB25001004004081320100D30522503E
+:102EA000B56F00000000005091C001000000004814
+:102EB000B2CB0100F615004043990100200400F256
+:102EC000B433010002000048B2CB0100F815004005
+:102ED00043990100200400F2B433010004000048CB
+:102EE000B2CB0100FA15004043990100200400F222
+:102EF000B433010008000048B2CB0100FC150040CB
+:102F000043990100000000F094B00100FFFF004A67
+:102F1000B48B010020040040813201000A00004807
+:102F2000B2CB01001000004AB4F7010020040040B9
+:102F30008132010038050040813201001E00004846
+:102F4000B2CB01001004004081320100E90522509B
+:102F5000B56F0000EA050050B5B300000000004066
+:102F6000B5B301002004004081320100E09F004021
+:102F700081B200000400004081B200000400004063
+:102F800081B200000400004081B200000400004053
+:102F900081B2000000160040479901003031004026
+:102FA000F599010032330040F599010034350040B5
+:102FB000F599010036370040F59901003839004095
+:102FC000F599010041420040F59901004344004059
+:102FD000F599010045460040F59901004748004039
+:102FE000F5990100494A0040F59901002C00004084
+:102FF0008398010000000040F7B10100FC05A241E8
+:103000008350000080162E0683B00100360000FBBE
+:10301000F6A90100FF05A2418350000022000040F4
+:1030200083980100000000FBF6B101000206A241F6
+:10303000835000006200004095980100DC9F004032
+:103040008132010000162D0683B001008016004079
+:10305000459901005C0000FBF6A901000806A241A9
+:103060008350000000000070F9B101000000007101
+:10307000F9B1010000000072F9B101000000007315
+:10308000F9B1010000000074F9B1010054000040E2
+:1030900095980100DC9F0040813201000000007023
+:1030A00095B0010014062270B56F00000000804149
+:1030B00097B001000000804097B00100040000407C
+:1030C00081B200000400004081B200000400004012
+:1030D00081B20000456700A6E0B201000123007044
+:1030E000E19A0100CDEF00A6E2B2010089AB0071C8
+:1030F000E39A0100BA9800A6E4B20100FEDC007277
+:10310000E59A0100321000A6E6B201007654007381
+:10311000E79A0100D2C300A6E8B20100F0E1007412
+:10312000E99A01008016004A44C901000000000726
+:1031300081B001000000004A80D001000000004082
+:10314000F7B101002506A241815000008016004A17
+:1031500044C90100FC162A47E7B501000300004AF4
+:10316000E8E50100000000408DB001005003004080
+:10317000A399010080163D468DE00100000000503B
+:1031800089B00100000000FC40B0010000000041D7
+:10319000A3C101002E06A24189500000000000706A
+:1031A000EBB2010000000071EDB2010000000072FE
+:1031B000EFB2010000000073F1B2010000000074E2
+:1031C000F3B201000000004083B001000F00004195
+:1031D0008088010050030040A2C901004B06A050A6
+:1031E000836C00000D00004098C801000000004FF3
+:1031F000998401005003004CA2C901000000002086
+:1032000086B001000800004098C801000000004F8F
+:10321000998401005003004CA2C901000000002065
+:1032200086A401000200004098C801000000004F81
+:10323000998401005003004CA2C901000000002045
+:1032400086A4010050030040A2C901000000004311
+:1032500040A401000100002088E401000000005F9C
+:1032600041F0010000000044409401000500007599
+:1032700089E401001B00007585F401000000004492
+:10328000849401005506A353836C0000000000766F
+:1032900089B00100000000778984010000000076F9
+:1032A0008BB00100000000208BA40100000000781A
+:1032B0008B840100640600458894000027000041CB
+:1032C00080CE01005A06AA4081320000000000763C
+:1032D00089B001000000007789A40100640600782D
+:1032E00089A400003B00004180CE01005706AA409F
+:1032F000813200000000007689B0010000000077F4
+:1033000089840100000000768BB001000000007885
+:103310008B840100000000458894010000000077C4
+:103320008BB00100000000788B840100640600452A
+:10333000889400000000004484C00100000000796F
+:1033400085C001000000002084C001006B06A3536B
+:10335000836C0000825A00A684C001009979004263
+:1033600084C801007806004081B2000027000041B7
+:1033700080CE01007006AA4081320000D96E00A6FE
+:1033800084C00100A1EB004284C80100780600401F
+:1033900081B200003B00004180CE01007506AA40CA
+:1033A000813200001B8F00A684C00100DCBC0042FB
+:1033B00084C801007806004081B2000062CA00A6FD
+:1033C00084C00100D6C1004284C8010078060040D4
+:1033D00081B2000000000078F3B201000000007725
+:1033E000F1B201001E00007689E4010002000076BF
+:1033F000EFF6010000000044EE96010000000075A9
+:10340000EDB2010000000042EAB2010000000041FC
+:1034100083C001004F00004180CE010037062A40E2
+:103420008132000000000075E1C20100000000765A
+:10343000E3C2010000000077E5C20100000000784F
+:10344000E7C2010000000079E9C201002B068141BA
+:103450008D4000000000804081B201000400004067
+:1034600081B200000400004081B20000040000406E
+:1034700081B200000400004081B20000040000405E
+:1034800081B200000400004081B20000040000404E
+:1034900081B2000000000050FD9301004016004082
+:1034A00045990100DB9F00404931010008000048B8
+:1034B000B2CB01001504004081320100B906224060
+:1034C0008F6C0000DA9F004081320100B906A240F3
+:1034D000976C00005E160040439901007C1620F6B0
+:1034E000E0B101000000004031B301009D06224F11
+:1034F0008F7C000000000051FD9301009F062240D8
+:103500008F7C0000A3060054FD930000A106224218
+:103510008F7C000000000052FD930100A3062241B1
+:103520008F7C000000000053FD930100B70622517C
+:10353000FD7F000038050040813201000C0000488A
+:10354000B2CB01001004004081320100B206A2405B
+:10355000B56F00001E000048B2CB01001004004807
+:1035600096300100000000DA97C001000400004B13
+:10357000B2CB010010040040813201000E0000486F
+:10358000B2CB010020040040813201000C00004851
+:10359000B2CB010000000030B5B3010020040040B0
+:1035A000813201000E000048B2CB0100100400403F
+:1035B00081320100B6062240B56F0000BA06005401
+:1035C000FD93000000000051FD8301001C0000FE7F
+:1035D0007FD90100BA06A6408132000000000055E4
+:1035E000FD9301000000804081B201000400004012
+:1035F00081B200000400004081B2000004000040DD
+:1036000081B200000400004081B2000004000040CC
+:1036100081B20000E79F004081320100C406225CB5
+:103620001F7C0000E39F00881CB00000E99F005C45
+:103630001F00010000002E0548B1010000000040FD
+:10364000E1B1010004002D0348B10100000000F0C9
+:103650003CB001002800001402C801000000000175
+:1036600034B0010000002D0532B001002200000539
+:103670000AC801001000000348C90100000000F85A
+:1036800018B00100000000F804B00100000000F8CC
+:103690000EB001000C0000A40CC80100EA9F00401D
+:1036A000813201000000004023B001000A0722011E
+:1036B0008032000000003C4423E0010000002EA402
+:1036C00080B001000000001048C10100D906A30726
+:1036D000026C0000DA0668011AB0000000006807FA
+:1036E0001AB001000000000D02D00100000000052A
+:1036F000F0B101000000000CF0B101000000000278
+:10370000E0B101000000000D0AC00100EC062240FB
+:10371000036C0000E6062242236C0000000000411A
+:1037200023C001000000004761B10100200000A497
+:1037300062DD01002307284081320000E3060040DB
+:1037400081B200000000001080C0010000000047AE
+:1037500061B101000000004062B10100E806A8402C
+:1037600023300000E39F00881CB0000023070040C6
+:1037700081B200000000001080C00100000000477E
+:1037800061B101000000004062B10100EE06A840F6
+:1037900023300000E39F00881CB0000022000019C5
+:1037A00048C9010000002D1448C101000F0000F2BB
+:1037B0003A880100000000423BE001000E000014C6
+:1037C00002C801000000001D02C00100FA06231A11
+:1037D000025000000000004603C001002307000162
+:1037E00034C000000C002D1D48C10100F00000F2A3
+:1037F000308801000000004231F001000000001498
+:1038000002B001000000001D02C00100000000180D
+:1038100002C001000207221A025000002307000123
+:1038200034C000002200001948C9010002002D1414
+:1038300048C10100000000F614B001000000001DA6
+:1038400014D001000000001814D001000000001E78
+:1038500024B001001200001710C801002307001A4D
+:1038600010C0000000003C4423E00100000000A460
+:1038700086B0010000002E1048C101000F07A312FE
+:103880000E6C0000100760071AB000000000601204
+:103890001AB001000000680D16940100FFFF000B34
+:1038A00016D8010000000008F0B101000000000C73
+:1038B000F0B1010000000002E0B1010000000010C2
+:1038C00086C001000000004661B1010020000043F5
+:1038D00062DD01001707A85C1F1000004007220DE1
+:1038E000145000004007220D245000000000000D7D
+:1038F00010C001001E072242236C00002307004174
+:1039000023C000000000004661B10100400000102B
+:1039100062DD01001F07A85C1F000000E39F008814
+:103920001CB000000000004023B001003F07A20DC2
+:103930000E5000002E0722461F7C000000000046AB
+:103940001F8001003080001042C901002C0722F2C4
+:10395000640600000000004761B101004000001053
+:1039600062DD01002907A84081320000E39F008842
+:103970001CB0000020800003469901000000005F99
+:10398000E191010000002D0648B10100000000F89F
+:1039900018B00100000000F804B0010033071FF068
+:1039A0000E300000D306004C0DC0000000002E5F5A
+:1039B0000F800100D3062307146C000030000010B4
+:1039C00048C9010024000040F199010000000003F3
+:1039D000F0B1010000000000F0B10100000000168D
+:1039E000F0B101002400000000C801000000004701
+:1039F00061B10100200000A462DD01003C07A8467F
+:103A00001F100000D30600030CB00000D306000D09
+:103A100018C000005F07A2441F7C000000000019CE
+:103A20000AB001002200000548C901000A002D1457
+:103A300048C1010002002040E5B10100040020401F
+:103A4000E5B101000D002D1D48C10100090000F382
+:103A5000388801000D002050E7B1010004002D401E
+:103A60003FB00100000000F432B00100040020402B
+:103A7000E1B101002200000548C9010000002D1439
+:103A800048C101000200001D94F401000000004044
+:103A900091B001005207A0FC9040000000000041DE
+:103AA00091C001005007A24195500000000000A401
+:103AB00096B0010004002E0548B101000000004846
+:103AC000F0B101000000004B48B1010000000018F7
+:103AD00048C101000200001894F4010000002D18F4
+:103AE00090B001005C07A0FC904000000000004185
+:103AF00091C001005A07A241955000000000004803
+:103B0000E0B1010010002040E5B1010004002D05E6
+:103B100048B10100000000F880B02D00000000F066
+:103B200016B02D002200000548C92D000000001429
+:103B300048C12D00640743303D072C000000009E63
+:103B400085B02D0000001B413DC32D000400204224
+:103B5000ECB12D000000001E82B0010002002E1DFD
+:103B600082C001000000661882C00100000000420F
+:103B700080C001006E07A0418044000000000041A9
+:103B800081C001001000004092F401000A002E30B4
+:103B900081840100720790409240000000000041C3
+:103BA00093C001000000662093A401000000001DE6
+:103BB00048C1010004002019E8B101000000001E06
+:103BC00016C001007807A01916440000000000414B
+:103BD00017C001000D002F1E32C001007D07A2405A
+:103BE000156C00007C07A01C16400000000000417E
+:103BF00017C00100000063F33894010010000005B5
+:103C000048C9010004002E1E98B001000000601A8F
+:103C100098C001000C002040E1B101008B07224652
+:103C20001F7C0000000000461F8001003080001053
+:103C300042C90100890722F2640600000000004723
+:103C400061B101004000001062DD01008607A8405C
+:103C500081320000E39F00881CB000002080000338
+:103C6000469901000000005FE191010030800010E2
+:103C700044C901001200001AF0C901000000001739
+:103C8000F0B1010010000005E0C901003000001093
+:103C900080C801000000004461B101002000004024
+:103CA00062DD01009107A840813200009B07225C81
+:103CB0001F7C000000003C4423E0010000002D10A8
+:103CC00048C101009B0722F2640600000000004684
+:103CD00061B101004000001062DD01009807A840BA
+:103CE00081320000E39F00881CB00000EB9F005C65
+:103CF0001F00010020002F0548B101000000000B4B
+:103D0000E4B101000000005017F00100A10790F29B
+:103D1000164000000000004117C0010000006620AE
+:103D200017A40100100000142AC801000000001DA3
+:103D30002AC00100000000502BE00100000000F24A
+:103D40002A9401003080001042C90100AC0722F221
+:103D5000640600000000004461B101004000001052
+:103D600062DD0100A907A84081320000E39F0088BE
+:103D70001CB000000080001710DC0100C9072240C1
+:103D8000156C0000B407A2441F7C00000000004432
+:103D90001F900100B307229F136C000002000088EF
+:103DA0001CCC0100E49F004081B2000000000041F3
+:103DB0003FC30100E69F004081320100B707A241E6
+:103DC000877C00000000001E3EC00100C9072240A1
+:103DD000156C0000BA07201E146C00000000000AD9
+:103DE0003CB00100E59F001E24300100BF072208FF
+:103DF0002E3000000000005211C001000000001A27
+:103E000010C001002307004017B00000E49F0088A5
+:103E10001CB00000E59F004081320100BC07A208F1
+:103E20002E300000808000A604B001000600004093
+:103E300087980100008000034499010004002204D7
+:103E4000E0310000E89F001F8C30010000000040BE
+:103E50000FB00100E29F005C1F9000000080000393
+:103E60004499010004002204E0310000E69F004074
+:103E700081320100CE07A241877C0000CF07001EDF
+:103E80003EC000000000001F8CB001000000004098
+:103E900005B00100E89F00400F300100E29F005C88
+:103EA0001F9000000400004081B2000004000040A8
+:103EB00081B200000400004081B200000400004014
+:103EC00081B200000400004081B200000400004004
+:103ED00081B200000400004081B2000004000040F4
+:103EE00081B200000400004081B2000004000040E4
+:103EF00081B200000400004081B2000004000040D4
+:103F000081B200000400004081B2000004000040C3
+:103F100081B200000400004081B2000004000040B3
+:103F200081B200000400004081B2000004000040A3
+:103F300081B200000400004081B200000400004093
+:103F400081B200000400004081B200000400004083
+:103F500081B200000400004081B200000400004073
+:103F600081B200000400004081B200000400004063
+:103F700081B200000400004081B200000400004053
+:103F800081B200000400004081B200000400004043
+:103F900081B200000400004081B200000400004033
+:103FA00081B200000400004081B200000400004023
+:103FB00081B200000400004081B200000400004013
+:103FC00081B200000400004081B20000F70700BC8D
+:103FD00080B200000380004081B2000003800040F6
+:103FE00081B200000380004081B2000003800040E5
+:103FF00081B200000380004081B2000003800040D5
+:1040000081B200000380004081B2000003800040C4
+:1040100081B200003180004081B200003480004055
+:1040200081B200003580004081B2000004000040F1
+:1040300081B200001B80818080320000E787A240AF
+:10404000916F00000000004C90B301005C952EA21F
+:1040500080B00100FF000080F489010090952AC81B
+:10406000E5B10100000000A1F0B101000000004036
+:10407000F0B10100000000A4F0B10100000000D088
+:10408000F0B10100000000D1F0B10100000000D249
+:10409000F0B101000000004CF0B10100000000D4BC
+:1040A000F0B10100000000D3F0B10100000000EE0B
+:1040B000F0B101000000004EF0B10100000000402E
+:1040C00044B1010018801181983000000000514077
+:1040D00081B201001A801182983000000000524025
+:1040E00081B20100E7870048FD930000B60300405D
+:1040F000A19901002380A242FD7F00002080008062
+:1041000080320000228011818230000022805140E4
+:1041100081B2000022801182823000002280524051
+:1041200081B200002C800048FD93000027800080B1
+:10413000803200002680A253077C0000000051530B
+:10414000079001002A800052079000002980A252A7
+:10415000077C00000000525207900100000000534D
+:104160000790010000000048FD9301000000004698
+:10417000F39301005C952EA252B30100FF00008072
+:10418000F48901000000004CE4B10100000000A926
+:1041900045B101003080004C80B200000000454075
+:1041A00081B201000000554081B20100C682054085
+:1041B00049B10000C682054049B100000000054039
+:1041C00049B101004C010040813201000000004B68
+:1041D000DEB2010000000040FD9301000000004835
+:1041E000FD830100020000409B9B0100000000A530
+:1041F0009CB30100480300408132010058952044DF
+:10420000E0B101000494004043990100000000F275
+:1042100024B10100000C00EE968801000000004A65
+:1042200097F001004480A243976C00000000004218
+:10423000FD93010000C000A636B10100D01400407B
+:104240004799010005000040F59901000038004041
+:10425000F599010000060040F599010003000040B7
+:10426000F599010005100040F59901000209004090
+:10427000F599010004000040F59901006003004039
+:10428000813201008803004081320100A003004018
+:1042900081320100B982004081320100B1820040C8
+:1042A0008132010060952040E1B10100709520400D
+:1042B000E1B1010000000049DD9101000000004073
+:1042C00091B30100000000407BB30100A0980040C2
+:1042D000813201000000004085B301005C95204060
+:1042E000E1B101003C8200408132010090060040B3
+:1042F000813201000000005F2F810100A281004097
+:1043000081320100A5980040813201000000454043
+:1043100081B201000000554081B2010001830040DC
+:1043200081B200000400004081B20000040000409F
+:1043300081B200000400004081B20000040000408F
+:1043400081B200000400004081B20000040000407F
+:1043500081B200002800004047990100C682004158
+:10436000E1C1000078180040499901001905225464
+:10437000817C00006C80424081320000008200B4E9
+:1043800069DF010000001A449393010028000040F7
+:10439000479901001805004081B200000400004068
+:1043A00081B200000400004081B20000040000401F
+:1043B00081B200000400004081B20000040000400F
+:1043C00081B200000400004081B2000004000040FF
+:1043D00081B2000055820040813201007D80224080
+:1043E000976C00007A804240813200000000004F4C
+:1043F00069930100438100586993000054160040FE
+:1044000047990100000000FEF4B101008005004062
+:1044100081B2000080804240813200000000004EE6
+:1044200069930100438100586993000040160040E1
+:10443000459901004005004049310100F615004052
+:10444000439901005C1600404599010000006EFA96
+:104450008EB00100C105004081B2000004000040A0
+:1044600081B200000400004081B20000040000405E
+:1044700081B200000400004081B20000040000404E
+:1044800081B200000400004081B20000040000403E
+:1044900081B200009680004081B200005582004049
+:1044A0008132010096802240976C00009380424048
+:1044B000813200000000004F6993010043810058E1
+:1044C0006993000038050040813201001E00004859
+:1044D000B2CB0100D005004081B2000004000040D2
+:1044E00081B200000400004081B2000004000040DE
+:1044F00081B200000400004081B2000004000040CE
+:1045000081B200000400004081B2000004000040BD
+:1045100081B200008302004081B20000B802004076
+:1045200081B20000D49F004081B20000D59F0040BE
+:1045300081B20000D69F004081B20000D79F0040AA
+:1045400081B200007201004181C000005501514953
+:10455000FD9300005501524AFD9300005501554955
+:10456000FD8300005501564AFD83000050019181F2
+:10457000803000005501454081B200005001918219
+:10458000803000005501464081B20000000000402C
+:1045900089B00100000000F880B00100000000F0C8
+:1045A00016B001002200000548C9010000000014F7
+:1045B00048C10100B48043303D0700000000009E68
+:1045C00085B0010000001B413DC3010004002042F2
+:1045D000ECB101000000A240916F0100000000401A
+:1045E00049B10100AE0300CBA3C9010000000020C7
+:1045F00046B10100C480A240E16D0000000000D27D
+:10460000F1B10100000000D3F1B10100000000424F
+:10461000F0B101000000004561B101002000002060
+:1046200062DD01000000A8D0E1B10000C1800040BF
+:1046300081B20000000000A898B001000480004092
+:104640008BB30000B1030040A1990100C980A242D0
+:10465000976F000000000045A1C1010000000000AC
+:1046600080B001000000A2048094000080153F4249
+:1046700097E301000000004049B101000000600321
+:10468000029401000000004007B00100040000CBCC
+:1046900099CB0100000000CCF3830100D380A2423B
+:1046A000976F0000000000CBF3930100AE0300CB36
+:1046B000A3C901000000002044B101000000004433
+:1046C000F1B1010000000000F0B1010000000004A1
+:1046D000F0B10100000000A1E0B1010005000040C0
+:1046E000619901002000002062DD0100DA80A8400D
+:1046F00081320000F9020020423101000000A24195
+:10470000056C0100000080CBDB9101000000194125
+:104710008BB301006000004061990100E080A8B106
+:104720008C3300006000004061990100E280A8B174
+:1047300094330000E88014C681320000180000C6DF
+:1047400083F401002283224F83040000C4800040D0
+:1047500081B20000FF0100C681880100000000C690
+:1047600097A30100C4801F5C975300006D821EC692
+:1047700081320000F2802248FD7F0000F280225842
+:10478000816C0000F2802248816C0000C000004073
+:1047900084CC0100F2809F428032000022830040DE
+:1047A00081B20000C480A2C68F060000C4801EC66D
+:1047B0008132000000002F4381F00100F6800040AC
+:1047C00010C900004481004081B200007E81004099
+:1047D00081B20000398200CA63B3000075810040D5
+:1047E00081B200005581004D83B000006081004E11
+:1047F00061B100004C81004085B000005581004C43
+:1048000083B000002E81004085B00000F881004098
+:1048100049B1000086810040C1B10000F481004030
+:1048200081B200004C81004085B00000F0030040E0
+:1048300049B10000228300CA9BB300009081004070
+:10484000C1B1000094810040C1B100009B810040D3
+:10485000C1B100009C810040C1B100009D810040B9
+:10486000C1B100009E810040C1B100009F810040A5
+:1048700081B000009F81004181B000002D82004086
+:1048800081B20000AE8200BBABB300003A8200CA26
+:10489000CFB30000C803004049B10000E803004066
+:1048A00081B20000C480004081B200002283004039
+:1048B00081B20000E003004081B20000228300CA00
+:1048C00077B300005681004D83B000005E81004E3A
+:1048D00061B100004C8100BB85B000005681004CE6
+:1048E00083B000004C8100BB85B000002E8100BB6E
+:1048F00085B000002081004081B20000228300CA00
+:104900004DB300007005004049B10000A005004013
+:1049100049B10000268122428F6F00002881224188
+:104920008F6F00002A811ECA813200002C811FCAAD
+:1049300081320000000000CAC9B101002283004298
+:104940008FB30000000000CACDB1010022830041F6
+:104950008FB30000000000CACFB1010022830040E5
+:104960008FB30000008100A6C6B101002283004081
+:1049700081B20000008000A6C6B101002283004081
+:104980008FB30000781800404999010010002F9C57
+:1049900089B00100468100403933010018002F9B87
+:1049A00089B00100468100403733010000002F9A92
+:1049B00089B00100468100403533010008002F997D
+:1049C00089B001004681004033330100008000AE11
+:1049D00047C90100C480A240E16D00008000004092
+:1049E000F1990100000000CAF1B10100000000428D
+:1049F000F0B1010040180040E199010000000045BD
+:104A000061B10100200000AE63DD0100418128405A
+:104A1000813200003E81004081B20000418142406D
+:104A2000813200000000005C6993010022831A4477
+:104A3000939300004481424081320000438100583A
+:104A40006993000000000044F0D101000000A44080
+:104A500081B200004B81A240E16D000000000044E3
+:104A600045D1010000008040E1B10100000080411B
+:104A7000E1D101004C81375C61310000000000424F
+:104A800062B1010052812840813200004D81225CD8
+:104A9000777D0000C480174081B200004D81004046
+:104AA00081B20000000000CA63B101005281A84039
+:104AB000813200002283174081B2000057810040FC
+:104AC00081B00000578100BB81B0000000000041B0
+:104AD00060B10100C480A241767D0000000000406A
+:104AE00062B101005981A84081320000000000CA73
+:104AF00063B1010022832840813200005B810040C5
+:104B000081B200005095004047990100618100BBCF
+:104B100087B0000050952F4087B00100658122408A
+:104B2000957F0000C480A240E16D0000C480224057
+:104B3000956F0000228360409583000002002DF0F5
+:104B400084B00100C4802240856C0000C480A24073
+:104B5000857C0000C480A24E777D000069813640CC
+:104B6000813200000000004262B101006A81A84069
+:104B7000813200000000004362B101006C81A84056
+:104B800081320000000000CA63B101006E81A840BC
+:104B9000813200000000164081B201007481224180
+:104BA00043510000000800CA95CB01006881004114
+:104BB00085C0000022830040E1B100007781A2425D
+:104BC000676F00000000004167B301007781424039
+:104BD000813200000000004065B301000000004089
+:104BE0009383010000001ACA6997010022832640BE
+:104BF000813200007C8142408132000022831A44CD
+:104C000093930000C4802043956F0000228380CAE4
+:104C10006733000022832240656F0000C480A248F1
+:104C2000DB7D00002283006FDB91000085000040E7
+:104C30008132010035802240803200002283004012
+:104C400081B2000000000058959301000000005F51
+:104C5000959301008C81A244216F00000000005F49
+:104C6000958301000000005E95930100000000574D
+:104C700095930100000000CAC3B101008F81225B3F
+:104C8000957F00000000004BFD930100228300404F
+:104C900081B200001BFD00CA959B01000D0100CAF6
+:104CA000C53101000000005F95830100228300CA26
+:104CB000C5B10000DF6F00CA959B010000000055E0
+:104CC00095930100000000CAC7B101002283225F52
+:104CD000957F00000D010040813201000000005F5F
+:104CE00095830100228300CAC7B10000228300CA55
+:104CF000C9B10000228300CACBB10000228300CAE0
+:104D0000CDB10000228300CACFB1000000002E42C6
+:104D100081E001009814004048C90100228300CAC4
+:104D2000E1B100000000004009B10100200000A630
+:104D300082B00100A481A25E0B7D000000800041D2
+:104D400008990100A681A25E0B7D0000208000A6CC
+:104D500008B10100A8819F8582300000000000306A
+:104D600083840100DD812230836C0000A781A24F83
+:104D70000B7D00000000004121B30100028000A66D
+:104D800082B0010028820040813201001000004101
+:104D900084E40100038000A682B001002882004064
+:104DA00081320100F0FF00418688010000000043CD
+:104DB000849401000F0000A686B0010010C40043D7
+:104DC00086980100BD81A243846C0000000000436E
+:104DD00021B30100200000A682B001001C000041A8
+:104DE00082DC0100BA81A25E0B7D0000040000415C
+:104DF00008990100CF81004081B20000410100A666
+:104E000086B00100500C004386980100C281A24385
+:104E1000846C00000000004121B30100CF810040FC
+:104E200081B20000410100A686B00100600C004381
+:104E300086980100CF81A243846C000000000042EC
+:104E400021B30100188000A682B001002882004032
+:104E500081320100FFFF004182880100007700419C
+:104E6000828C010001020041829801002000004173
+:104E700082DC01001800004182DC0100CD81A25ECD
+:104E80000B7D00000000004108B10100200000A6D9
+:104E900082B00100D081A25E0B7D00004013004172
+:104EA00008990100D8812243216F0000200000A64C
+:104EB00082B001001200004182DC0100D581A25EB7
+:104EC0000B7D00000004004108990100F3810040BF
+:104ED00081B20000200000A682B00100190000414C
+:104EE00082DC0100DA81A25E0B7D000000A000419F
+:104EF00008990100F381004081B2000000000044E5
+:104F000021B301000000004083B001000000005FF9
+:104F1000839001000000005E8390010000000057B4
+:104F20008390010000000041C2B101000C0100406B
+:104F3000813201000000005F838001000000004119
+:104F4000C2B101000C01004081320100200000A626
+:104F500082B001000400004182DC01002000004119
+:104F600008990100200000A682B001001100004154
+:104F700082DC0100EC81A25E0B7D0000010000419B
+:104F800008990100200000A682B00100EF81A25E16
+:104F90000B7D00004013004108990100010000A6AC
+:104FA00082B00100400000412E99010000008040C5
+:104FB00081B20100200000A680B00100000000CAFC
+:104FC00081940100F681A25E0B7D000022830040E7
+:104FD00008B10000C8142EBB85B00100F981A25EA3
+:104FE0000B7D00000000004087B0010008822243D2
+:104FF000216F000017822244216F0000118000A65B
+:1050000082B0010028820040813201001F82224AC2
+:10501000837C000000000040879001000382224D45
+:10502000837C000000000041879001000582224F30
+:10503000837C000000000043879001000782224E1D
+:10504000837C000000000042879001001F82004026
+:1050500081B20000018000A682B0010028820040D9
+:1050600081320100018000A682B001002882004048
+:10507000813201001F822242837C00000000004038
+:10508000879001001C8000A682B0010028820040A9
+:105090008132010012822245837C00000000004121
+:1050A0008790010014822244837C000000000043AA
+:1050B0008790010016822243837C0000000000429A
+:1050C000879001001F82004081B20000018000A68D
+:1050D00082B001002882004081320100018000A6D8
+:1050E00082B0010028820040813201001F822242EA
+:1050F000837C000000000040879001000000004316
+:10510000879001000000004187900100008000A608
+:1051100082B0010028820040813201002382224BAC
+:10512000837C0000000000408780010000000043F5
+:10513000E0B10100FF7F00A2A08B0100000000444D
+:10514000A5B30100B88000CAA73301004181004027
+:1051500081B200002000004182DC01002982A25EB1
+:105160000B7D00000000004108B101002B829F85EB
+:10517000823000000000804081B20100308214F7CC
+:10518000813000003082A249FD7F0000000000480D
+:10519000FD930100338215F8811400003382A24A86
+:1051A000FD7F000000000048FD9301003582A2C889
+:1051B000813200004000004080DC0100001000400F
+:1051C00080DC010000000040EFB301003782424064
+:1051D000F13300004381004068970000228300BB48
+:1051E0006BB30000228300BBB1B3000022830040F8
+:1051F00081B20000000300408198010000000040DF
+:1052000018B101008000004083980100001900409F
+:10521000459901000000424081B20100000043FFB7
+:10522000F1B10100000000FFF1B1010000000041F8
+:1052300081C001000000004018B101004082A2417D
+:1052400083500000001600404599010000190040FD
+:10525000439901000000004743C1010000000040E5
+:1052600083B00100000000F380B001000000005B8B
+:1052700081D001000000004180D00100000000400A
+:10528000F6B101000000005B43C1010000000041D5
+:1052900083C001004A82A254836C000000000040D9
+:1052A000F7B101000000004183C001005182A20655
+:1052B000836C00000000804081B2010000160040B5
+:1052C0004399010080162E0683B00100360000FBD2
+:1052D000F6A901005782A24183500000220000403D
+:1052E00083980100000000FBF6B101005A82A24140
+:1052F000835000006200004095980100DC9F004050
+:105300008132010000162D0683B001008016004096
+:10531000459901005C0000FBF6A901006082A241F2
+:105320008350000000000070F9B10100000000711E
+:10533000F9B1010000000072F9B101000000007332
+:10534000F9B1010000000074F9B1010054000040FF
+:1053500095980100DC9F0040813201000000007040
+:1053600095B001006C822270B56F00000000804192
+:1053700097B001000000804097B00100C480A242B5
+:10538000976F0000B6030040A199010000002F4272
+:1053900099B3010078822244816C00008082224807
+:1053A000816C00007A82224C816C00008582225040
+:1053B000816C000086822254816C00008882225811
+:1053C000816C00008D82225C816C000050010040E5
+:1053D00081B20000000000BC09B00100228300CAB5
+:1053E00001B000000000004003B0010000000041D7
+:1053F000F38301007E82A242056C000000000041A0
+:1054000005B00100228322CA07140000228300464F
+:10541000F393000022832043956F0000228380CA0B
+:10542000053000002283220180300000C480A248A1
+:10543000DB7D0000228300CBDB910000570100BC24
+:10544000ABB30000000000BCB1B30100228300CA6E
+:10545000CFB30000FF0000CA818801002283A24070
+:10546000747D000060002040609901008A82A8B12C
+:10547000823000008982004081B20000228300CA8D
+:1054800079B300000000004E81B00100000000432D
+:10549000CB8301000000454081B201009082A2410F
+:1054A000815000000000454081B2010000004540ED
+:1054B00081B201009B829182823000000000008A4C
+:1054C00080B00100AE9F004080CE01009982A640CE
+:1054D000813200009B82564081B20000B60300403A
+:1054E000A19901000000005307900100B60300409D
+:1054F000A19901000000005207900100D89F0041CF
+:105500008BB300000000004E81B00100000000429B
+:10551000CD8301000000464081B20100A082A2417B
+:10552000815000000000464081B20100000046406A
+:1055300081B20100AB8291818230000000000089BD
+:1055400080B00100AE9F004080CE0100A982A6403D
+:1055500081320000AB82554081B20000B6030040AA
+:10556000A19901000000005207900100B60300401D
+:10557000A19901000000005307900100D89F00414D
+:105580008BB30000B1030040A1990100C4142F4067
+:1055900099B301005701004049B10000A0942E4387
+:1055A00097B0010000000040F1B10100B282A241B9
+:1055B0009750000050952040E1B10100AC942E437B
+:1055C00097B0010000000040F1B10100B682A24195
+:1055D000975000000000804081B20100AE030040FF
+:1055E000A39901000000004081B001006015004057
+:1055F000859801000800004040E4010000000059C7
+:10560000419401000000005041E001000000004210
+:10561000409401000000005741900100000000414B
+:1056200081C001000000A342816C01000000004124
+:10563000A3C10100BC82A042816C0000BC8200506A
+:1056400085C000000183A241017D0000CF82225865
+:10565000737D00007800004061990100C782A8B105
+:105660009C300000300038459DE001000400A25F3E
+:105670001F7C00000400225E1F7C000000C000A60A
+:105680001EA401000100000E10C90000CF8233C427
+:1056900081300000D282A1AD9D200000C68213405F
+:1056A00081B200000000134E5A83010030003845DB
+:1056B0009DE001000400A25F1F7C00000400A25EC8
+:1056C0001F7C00000400A240056C0000DD8222ABBC
+:1056D00080040000DB82A240017D0000DD82225FA9
+:1056E000577D00001288005F1FB40000DD82225E3B
+:1056F000577D00008088005F1FB40000E3822254C1
+:10570000737D00007400004061990100DD82A8B142
+:10571000003000000000005F1FB40100F784A25FAA
+:10572000017C00009587004081B20000E582A25F05
+:1057300059270000E782A25C737D0000EE82A25E22
+:10574000737D0000FA82225C737D0000FB8237408B
+:10575000813200007C00004061990100E882A8B11C
+:10576000363000007C00004061990100EA82A8B157
+:10577000003000001F000000028801003785175F1D
+:105780001FB40000FB823440813200007E000040E4
+:1057900061990100EF82A8B112300000F782522116
+:1057A00013040000000014412FC301000000005F3B
+:1057B0001FB40100FF3F0009008C010000000043FE
+:1057C00001F001004F83003413840000FF3F1409EF
+:1057D000008C01000000005F1FB40100C48300437F
+:1057E00001F000000000004081B20100FB82334064
+:1057F000813200000400A24E5A7F00000700004ED4
+:1058000080E401000039004080C801000400A2408B
+:10581000066C0000C682134E5A930000E787A24828
+:10582000FD7F0000058302E681320000068383E5E8
+:10583000813200008E82004297B300009E820042B7
+:1058400097B3000009832246F37F00000C83A24136
+:10585000F37F0000C6800042973301000C8322448E
+:10586000F37F00000C83A241F37F0000C680006F2D
+:10587000973301000400A2AC803200001183225A49
+:10588000737D00007A000040619901000E83A8B189
+:105890007E310000010000CF11C900001783A24033
+:1058A000937F000017832244937F0000138342A557
+:1058B000803000001683A240937F000038831A4096
+:1058C0009393000000001A4081B20100DF80A240E3
+:1058D000737D0000E2872244216F0000D9872240B7
+:1058E000657D00000005A25B737D00000400A249F5
+:1058F000337D000021832248337D0000FF010099A1
+:1059000080D801000000005081E00100A8982F40DD
+:1059100033B1010000000040E0C1010001830040FC
+:1059200081B20000C68200408BB300000400A25E7A
+:105930001F7C00000400225F1F7C00000000005E4E
+:105940001F900100C682005F1F8000000400A25E5D
+:105950001F7C00000400225F1F7C00000000005E2E
+:105960001F9001000000005F1F8001000000005830
+:1059700061B101000000004E62B10100C682284002
+:10598000813200002C83004081B200000000004002
+:105990000FB001000400A25E1F7C00000400225F23
+:1059A0001F7C0000328333401F3000000400A24EF1
+:1059B0005A7F00000700004E80E4010000390040DB
+:1059C00080C801000400A240066C0000C682134E8D
+:1059D0005A9300003A83A0CE815000004D83A0CDA1
+:1059E000816C0000000000A59CB30100000000B124
+:1059F00081B001004D8322B58114000080152F4035
+:105A000049B101003E83424081320000000060B491
+:105A100065970100D0152E4069B3010000001A44BB
+:105A20009383010004002240E16D00001A0000A2EF
+:105A300080DC010000000044F1B10100000000B171
+:105A4000F1B10100000000B5F1B101000500004016
+:105A5000619901008000004062DD01004883A8A137
+:105A6000E0310000178300889EB300001783A24135
+:105A7000676F00001783006FDB9100004D83424089
+:105A80008132000017831A40938300000004004015
+:105A900089980100099900008A3001000400A25A87
+:105AA000017C000004002240016C00000099000904
+:105AB00046C901003F0000F30C8801005C83A64248
+:105AC000136000009B9600950330010057836140EE
+:105AD0008132000075000040619901005883A8B12F
+:105AE0000C300000A9967110943001005D830058BD
+:105AF0001F9000008D9600950330010023830088DD
+:105B00001CB0000000002D0348B1010004002DF07E
+:105B10002EB0010080040017968801000400A64002
+:105B2000813200004AC1001796D801000400A64047
+:105B300081320000EE070040979801006883234BF4
+:105B4000E46D00006883224BFD7F000000000040F0
+:105B50001F90010022002F4081B201006B83831748
+:105B60008032000026000040479901006D838517B0
+:105B7000803200000000004847C1010073832255B5
+:105B80002F7C00000000004243D101000F0000FA0A
+:105B9000968801000000004297E0010000000042EA
+:105BA00097D001007483004B44C10000120000A292
+:105BB00044C90100280000F602CC01000A0000A13F
+:105BC00042C90100000000F816B00100000028F0F2
+:105BD00010B00100000000F01AB00100000000A2A7
+:105BE0002AB00100C0283C460DE0010000002D4411
+:105BF00095B001008083A2F80E300000908322410E
+:105C00009550000000002D5049C101007C830040E8
+:105C100081B200007D83A2F8166C00007D83A2F89B
+:105C2000106C00007D83A2F01A6C00008E83225855
+:105C30001F7C000000993F4213F0010085836540FE
+:105C4000813200008983A2F3740600000000000680
+:105C5000E69501008E83754081B2000000000006C9
+:105C600096B001003F0075F30C880100000000555C
+:105C700061B101000000004B62B101008C83A840BB
+:105C8000813200008E836740813200009683774125
+:105C90002DC30000948322581F7C00000000005593
+:105CA00061B101000000000662B101009283A840CA
+:105CB000813200009483674081320000D5837741B0
+:105CC0002DC30000030000071AF401001895000717
+:105CD00016300100A8832241816C00009C8322427F
+:105CE000816C0000238300881CB00000A783225F22
+:105CF0000F7C00004E96005F01100100A28322403D
+:105D0000956C00000480000342C90100000000F20D
+:105D100002B00100A595005295300100AC95004BF2
+:105D200002B000000000005F0F800100010400408D
+:105D300089980100099900008A300100B496000991
+:105D400096300100F08700400FB00000B783A25AE0
+:105D50001F7C00000400A25A1F7C000000B5000D4B
+:105D600042C901000400220BE67D000000B7000DCF
+:105D700042C901000400220BE67D0000709400403F
+:105D800081320100B7832220856C0000B2839C0F12
+:105D900080320000238300881CB000008D95005CD9
+:105DA0001F000100C8970042613101002383008871
+:105DB0001CB00000900400079630010000002D0583
+:105DC00048B101000400A24BE17D00000400A25C88
+:105DD0001F7C000000002D0548B10100BB8382F04C
+:105DE000183000006C8900458FB00000282000A604
+:105DF00096B00100C18322179604000034040040CD
+:105E000089980100099900008A3001005B97004BD6
+:105E1000953001006C89004B8FB000005D96000347
+:105E200048310100AF930040813001006C8900408F
+:105E300081B20000000000400FB0010000040040EB
+:105E400089980100099900008A300100040022406D
+:105E5000016C000000002E1048B1010000006850E5
+:105E600003B0010000000003F0B101004000000099
+:105E7000E0C9010000002E5049C10100000000509F
+:105E8000F1B1010000000003F0B101000000004288
+:105E900061B101002000001062DD0100D083A84044
+:105EA000813200001000001062C90100D283A800F6
+:105EB000E0310000238300881CB0000000002D03A7
+:105EC00048B10100000000400FB00100000000F8E0
+:105ED0002EB00100000000F202B0010000000040FE
+:105EE00017B00100004100A696B00100EE072E4752
+:105EF00097900100E883221796040000E683224B66
+:105F0000FD7F0000E68323A2026C0000A5950052ED
+:105F10009530010004002241975000000C002D0034
+:105F200012B00100000000F000B001000000005CB1
+:105F300001800100AC95004B02B000000000000998
+:105F400000B001000000005003B001000584005CB7
+:105F500017900000FA8322432F7C000000000045C8
+:105F60001F900100F383225F2F7C000000002E10A1
+:105F700048B1010000000058F1B101001000000319
+:105F8000F0C9010010000000E0C90100EF83624287
+:105F9000613100000000001062B10100F083A840F0
+:105FA00081320000238372881CB0000020002D0382
+:105FB00048B10100FF0F00F680880100F783A2A618
+:105FC000816C0000FA8300F23AB00000F484A24B26
+:105FD000FD7F0000C9940040813201000688004026
+:105FE00081B200000584224A2F7C000005842248EB
+:105FF0002F7C00000A002D0348B101003F0000F291
+:10600000868801001F0000438488010005000043CA
+:1060100080F4010098943D4281E001000584A24291
+:10602000E07D0000F484A24BFD7F0000C994004095
+:10603000813201000688004081B200000204004065
+:1060400089980100099900008A300100078469409D
+:1060500081320000000000A309B001000000794176
+:1060600047C301000400A0A1096C00000E8422A116
+:10607000096C0000278300881CB000000A8400031C
+:1060800048B100004884A392036C00002B980040A4
+:10609000953001000000004143C3010000000016DC
+:1060A00080B2010006882708803200001584225C37
+:1060B000177C0000168400002AB0000012000000C7
+:1060C0002AC801000200000880C801001A84A24307
+:1060D0002F7C00005E970040813201003684005E14
+:1060E00017900000040000018CCC01005E97004C6A
+:1060F0000330010000002E4602B001001000001025
+:1061000048C901000C000001F0CD01002C00004046
+:10611000F0C9010000000016F0B1010010000015E8
+:10612000E0C901000000004361B10100A00000A42B
+:1061300062DD01002384A854171000003684005E3D
+:1061400017900000120000002AC801003584224385
+:106150002F7C0000040000018CCC01000000004CEA
+:1061600003B001007F9700436131010000002E461B
+:1061700002B001001000001048C901000C0000012D
+:10618000F0CD01000C000009F0C90100000000186A
+:10619000F0B1010010000015E0C90100000000434B
+:1061A00061B10100A00000A462DD01003684285422
+:1061B000171000003284004081B200007F97004336
+:1061C00061310100388422502F7C0000000000560D
+:1061D0001790010007000017988801003B84A24136
+:1061E000996C00000000005517900100000000436A
+:1061F00061B101004000001062DD01003C84A84054
+:1062000081320000238300881CB0000066970040A4
+:1062100081320100438422432F7C0000168000035A
+:1062200044C901000000001DE4B101000097005EB8
+:10623000051001004684A25F2F7C000086930001B8
+:1062400038430100C99400408132010006880040B3
+:1062500081B200004A84A24BFD7F0000F18400411E
+:1062600043C300000000004027B0010000000040D0
+:106270002DB001000000004011B001004D84350137
+:10628000863000006D00004061990100568428B1FD
+:10629000303000004E84224D757D00000000001655
+:1062A00080B20100DD84A740116C000000000041B5
+:1062B00043C301000400A240276C0000F0840040AA
+:1062C00081B200006D000040619901005684A8B1C0
+:1062D000123000000000001680B201006084A74068
+:1062E000116C00000000004143C3010000000009E0
+:1062F00010B00100000000182CB00100DE070043C0
+:1063000080CE01004E84AA408132000065840040A6
+:1063100081B2000040003E4327E001000000000978
+:10632000F0B1010000000018E0B1010000000041E0
+:1063300027C001004E84A30B8750000000001540C9
+:106340001BB001000000004023B001000400A203C4
+:10635000486D0000120000002AC8010040002D40D6
+:1063600039B001006F84A240276C000022000008B1
+:1063700012C801000400A216306C0000DE070040C5
+:10638000259801007284004081B20000000000F8EE
+:1063900012B00100000000F030B001000000000B5E
+:1063A00025B001000000001032B0010014002001EF
+:1063B000E0B10100EE070040379801007784230127
+:1063C000366C00000000000136B00100828482417A
+:1063D000234000002080001042C901007E8422403A
+:1063E000E36D00000000004361B1010040000010B7
+:1063F00062DD01007B84A840813200002383008895
+:106400001CB00000F3940043233001000000001092
+:1064100032B001000000004123B001000000000381
+:1064200048B101000080001944C90100938422454D
+:106430001F7C00000400A241236C00000400A20B9A
+:10644000256C00000000004CF1B1010000000009C3
+:10645000F0B1010000000018F0B10100000000439D
+:1064600061B101002000001962DD01008A84A815D5
+:10647000E03100000000005003D001000000005097
+:1064800033C001000000004C25D001000C002D4C51
+:1064900013C001000000005037D001000000005080
+:1064A0002BC00100778400451F8000009584A31253
+:1064B000366C00009684681B28B00000000068124B
+:1064C00028B0010000000009F0B101000000001830
+:1064D000F0B101000000004361B10100200000198B
+:1064E00062DD01009984A815E0310000C184221406
+:1064F000025000000000005033C0010000000014F2
+:1065000024D001000C002D1412C00100B984A21483
+:1065100036500000A984225C1F7C000030800010EF
+:1065200042C90100A7842240E36D00000000004240
+:1065300061B101004000001062DD0100A484A840A8
+:1065400081320000238300881CB00000000000039B
+:1065500048B101000C002D5C1F800100100000F00C
+:106560002AC801000000005C2B80010004002250BA
+:106570002B6C0000F007004037980100AF84230126
+:10658000366C00000000000136B00100BA84221B06
+:10659000026C00003000001048C9010000002E5CB1
+:1065A0001F90010000000050F1B101000000000345
+:1065B000F0B10100FF070015E08D0100000000426E
+:1065C00061B10100A00000A462DD0100B684A84012
+:1065D00081320000BA84000348B1000000000014BA
+:1065E0002AC001007784A240256C00000000004111
+:1065F00039C0010004002013386C000040003D4306
+:1066000039E001000000000B25B00100000000F897
+:1066100012B00100778400F030B000000400A25CEA
+:106620001F7C00000080001942C90100C88422407C
+:10663000E36D00000000004361B10100400000195B
+:1066400062DD0100C584A8408132000023830088F8
+:106650001CB00000F39400402B30010018002E0302
+:1066600048B10100CC8422502F7C0000000000566D
+:10667000179001000700001798880100CF84A241FD
+:10668000996C00000000005517900100D28422434D
+:106690002F7C000000000054179001001600201D00
+:1066A000E4B10100D484A340276C0000D684605F6D
+:1066B000179000000084000B16DC0100000060133E
+:1066C000169401000097005E051001000400A2402E
+:1066D0000F6C00000688A25F2F7C0000148000036E
+:1066E00042C90100000000F202B0010086930001DF
+:1066F000384301000688004081B200000400A20374
+:10670000486D00000400224D757D0000000000402F
+:1067100083B001000000004D61B1010000000016CF
+:1067200080B2010004002740116C00000000001638
+:1067300062B10100E384A84081320000000000083B
+:1067400062B10100E584A84081320000F084221388
+:10675000826C000040003D4383E00100000000F82F
+:1067600010B00100000000F02CB001000000001685
+:1067700062B10100EB84A8408132000000000008F3
+:1067800062B10100ED84A84081320000E78400413D
+:1067900083C000000000154081B20100008200A605
+:1067A00004B00100A0980040479901003005004165
+:1067B00089300100A595005295300100AC95004B41
+:1067C00002B00000068800400FB000000000005F2B
+:1067D00001800100100000000EF4010004002640BA
+:1067E000813200003F0000000088010005040040E5
+:1067F00089980100099900008A3001000300000710
+:106800001AF401001895000716300100088522418E
+:10681000816C000003852242816C00002383008884
+:106820001CB000000785225F0F7C00000000005FA5
+:106830000F800100060400408998010009990000BA
+:106840008A300100F08700400FB000001785A25A7F
+:106850001F7C00000400A25A1F7C000000B5000D40
+:1068600042C901000400220BE67D000000B7000DC4
+:1068700042C901000400220BE67D00007094004034
+:106880008132010017852220856C000012859C0F43
+:1068900080320000238300881CB000008D95005CCE
+:1068A0001F000100C8970042613101002383008866
+:1068B0001CB00000900400079630010000002D0578
+:1068C00048B101000400A24BE17D000000002D054D
+:1068D00048B10100000000F018B001001C85223A08
+:1068E000016C0000000000008EB001006C890040C7
+:1068F00001B000000000004081B201002E002D0513
+:1069000048B101002185A240E76D00000A00004067
+:106910008F9801006C89004001B000001D94004078
+:106920008132010004002200803200003504004062
+:1069300089980100099900008A3001008D96009520
+:1069400003300100238300881CB0000000002D03E9
+:1069500048B1010022002DF02EB0010004001F17E5
+:1069600080320000282000A696B001002E85221754
+:10697000960400005B97004B953001006C89004C39
+:106980008FB0000030858317803200000000004483
+:1069900043C10100328585178032000000000048A5
+:1069A00043C10100280000F602CC0100120000A142
+:1069B0002AC801005D96004081320100AF9300417A
+:1069C000813001006C89004081B2000000000001AC
+:1069D00000D0010000002E1048B101002800004046
+:1069E000F199010000000003F0B101000000000077
+:1069F000F0B101003C8564476131000000000010E7
+:106A000062B101003D85A81BE0310000238374883A
+:106A10001CB000000000004503E001000400A005D8
+:106A2000036C00000400A309036C000008002D03A0
+:106A300048B101006E8501FB08300000D88587FB56
+:106A400022300000000000FA0EB00100000000F843
+:106A500014B00100030000071AF4010018950007A4
+:106A6000163001005F852241816C00004E85224274
+:106A7000816C0000238300881CB000005E85225FCB
+:106A80000F7C0000380000047E8901005485A65F59
+:106A90000F00000031940040053001000A0400405E
+:106AA00089980100099900008A3001005B85004047
+:106AB00081B20000130000408798010000002D0300
+:106AC00048B101000C002DF082B00100000000F080
+:106AD00084B001002C9600400530010008040040FD
+:106AE00089980100099900008A3001000400A25C25
+:106AF0001F7C00000000005C1F900100F087004038
+:106B00000FB000006C85A25A1F7C00000400A25A3E
+:106B10001F7C000000B5000D42C901000400220BDB
+:106B2000E67D000000B7000D42C901000400220B01
+:106B3000E67D000070940040813201006C852220C7
+:106B4000856C000069859C0F8032000023830088DB
+:106B50001CB000008D95005C1F000100C89700422A
+:106B600061310100238300881CB0000090040007FD
+:106B70009630010000002D0548B10100000000F032
+:106B800018B001007085210480200000718500404C
+:106B900010C90000A488004B81B000009F8500430D
+:106BA00081B00000A38500FB22B00000A488004152
+:106BB00081B000006C89004E8FB000009485005AAF
+:106BC0008FB00000798500478FB00000A488005383
+:106BD00081B00000A488005681B0000032002D056D
+:106BE00048B101000704004089980100099900009C
+:106BF0008A3001003C040040899801000999000A8C
+:106C00008A3001003D0400408998010018000011FD
+:106C10008AE40100099900F28A1401000000004092
+:106C200081B201006C89A00AE46D00008785A24151
+:106C3000197C00008685220A803200006C8900538E
+:106C40008FB000006C8900548FB000009085220A3C
+:106C5000803200008A85A20AE46D00006C89005D24
+:106C60008FB00000000000F280B001000000000AB8
+:106C700080D001008E85A091816C00006C89005E3F
+:106C80008FB00000250000408F9801006C89004003
+:106C900081B2000092852091E56D00006C8900545E
+:106CA0008FB00000210000408F9801006C890040E7
+:106CB00081B2000032002D0548B1010007040040F8
+:106CC00089980100099900008A3001003C040040C5
+:106CD000899801000999000A8A3001003D040040AA
+:106CE00089980100099900F28A30010000000040F3
+:106CF00081B201006C89A00AE46D0000240000400C
+:106D00008F9801006C89004081B2000037002D058A
+:106D100048B10100040000F382F40100A488A042FD
+:106D2000836C0000A488005481B00000000000F2D1
+:106D30000EB00100040023400F6C0000040020AAE4
+:106D40000F6C0000090400408998010009990000B7
+:106D50008A300100030000071AF4010000B5000D9D
+:106D600042C901000700000716880100B185220B07
+:106D7000E67D00000A000040879801007F980040EF
+:106D80008132010004001C0F80320000000000402E
+:106D90000FB00100F087005C1F900000C3852250F7
+:106DA000FD7F0000BE85A254FD7F0000B685225500
+:106DB000FD7F00008200004087980100AD85004003
+:106DC00081B2000004002253FD7F00001480000304
+:106DD00042C90100000000F096B001001000004B15
+:106DE00080F401000CBC004087980100BE8522435E
+:106DF000806C0000FFFF004B80880100AD85A2433E
+:106E0000806C00007C96004047990100BF85464099
+:106E100081320000C285A0F0306F0000B4851E40B2
+:106E200081B2000000001E4131C301007F94004088
+:106E300025300100C7859C0F803200002383008825
+:106E40001CB000008D95005C1F0001001480000341
+:106E500042C901000400225A1F7C0000000000F01B
+:106E600096B0010000002F0548B101001000000796
+:106E700018E401000008000CE099010090040007EC
+:106E80009630010000B5000D46C90100CF853040A5
+:106E9000813200000400A20BE67D00000000000B20
+:106EA000E6910100000200A146C901000400A20B06
+:106EB000E67D00000000000BE691010004002E05B5
+:106EC00048B1010000001040E1B10100A488004079
+:106ED00081B00000000000FB28B00100000000FBB2
+:106EE00086B00100000000F814B00100E3852246DE
+:106EF000237C000004002240876C0000DF852240D4
+:106F0000877C0000000000481F900100E1852241BD
+:106F1000877C0000000000471F900100E3852242AB
+:106F2000877C0000000000451F9001000400224003
+:106F3000097C0000E485661B2C300000000000A0E6
+:106F400013B001000000764141C301001686239270
+:106F5000156C00001686A2451F7C00001C86224B83
+:106F6000FD7F0000170000D0A2C901000000004012
+:106F700027B001000200000A24C80100BF940040AD
+:106F80000F3001001486220840300000000000414C
+:106F9000A3C10100F007001224CC0100ED85AA4135
+:106FA000274000000400A349276C000001000013E3
+:106FB00080CC01000E8626402330000000000040F7
+:106FC00083B001006000000384C8010010000010BD
+:106FD00048CD0100170000D0A2C90100FB85A240E6
+:106FE000836C00000786004183B0000000800042EF
+:106FF00044990100000068213896010000002E50DD
+:1070000049C101000086A244236C00003000000347
+:1070100048C9010000000044F1B101000C0000204B
+:10702000F0C901000000004461B10100A00000A40B
+:1070300062DD01000386A842E03100000000004448
+:1070400085C001000000004123C001000000004194
+:10705000A3C10100F985A241815000000E862240A3
+:10706000236C00000000004461B1010040000010EA
+:1070700062DD01000B86A840813200002383008876
+:107080001CB000000B040040899801000999000021
+:107090008A3001000000000348B10100EE07004003
+:1070A00025980100170000D02AC801002786001784
+:1070B00010B000000A970040813201001C86004099
+:1070C00081B20000BF940092253001000000004012
+:1070D00031B001000B0400408998010009990000BB
+:1070E0008A3001001C8622082E30000027860041CD
+:1070F00027B00000808000A604B001000600004018
+:10710000879801007F98000A8C30010004001C0F52
+:1071100080320000000000400FB001000000005C61
+:107120001F9001000400A09F136C00002686229F80
+:10713000136C0000020000881CCC01002783004073
+:1071400081B20000F08700413FC300000000004012
+:107150000FB001002800000180CE01003B862A40CC
+:10716000813000000080001044C901004000004050
+:10717000819801003086A2481F7C00003086A2471B
+:107180001F7C00003086A307036C000080000040D5
+:10719000819801003386A340026C000028000001A2
+:1071A000F0CD0100358600400FB0000028000040FF
+:1071B000F0CD0100040000400ECC010028000003C7
+:1071C000F0C9010028000000F0C90100000000160D
+:1071D000E0B101000000004761B101002000001093
+:1071E00062DD01003986A85C1F1000000400220A3D
+:1071F000803200000400A203486D0000000000403F
+:1072000043990100000000F008B00100A0012D40EA
+:1072100000C001001C87220F420500004E869C0F13
+:10722000803200000000005C1F8001000080001020
+:1072300042C9010049862240E36D0000000000477A
+:1072400061B101004000001062DD01004686A840E7
+:1072500081320000238300881CB000004E86220784
+:10726000803200000000000342B10100000000076E
+:1072700042C10100008000A1469901000000005FAA
+:10728000E1910100C006A2451F7C00001000000330
+:1072900048C9010000002D5429C00100000000F879
+:1072A00018B00100000000F804B00100000000F870
+:1072B0000EB0010004002640813200000400A25FED
+:1072C0000F7C00003E00001480CE01000400AA40A4
+:1072D00081320000420000030AC801000C0000A433
+:1072E0000CC8010016950040813201000000001416
+:1072F00002B001000000001424D0010000000014BE
+:1073000010C001001200000810C801000000004079
+:1073100023B00100FE7F000544C901000400A2A2C1
+:10732000860600000000000AE4B101007C8622010C
+:107330008032000000003C4423E0010000002EA445
+:1073400080B001000000001048C101006986A30759
+:10735000026C00006A8668011AB00000000068072D
+:107360001AB001000000000D02D00100000000056D
+:10737000F0B101000000000CF0B1010000000002BB
+:10738000E0B101000000000D0AC001007686224035
+:10739000036C000076862242236C0000000000414E
+:1073A00023C001000000004761B10100A00000A45B
+:1073B00062DD01009C862840813200007386004017
+:1073C00081B200000000001080C0010000000047F2
+:1073D00061B101000000004062B101007886A84060
+:1073E00023300000238300881CB000009C860040EE
+:1073F00081B2000000003C4423E00100000000A432
+:1074000086B0010000002E1048C101008186A31241
+:107410000E6C0000828660071AB000000000601247
+:107420001AB001000000680D16940100FFFF000B68
+:1074300016D801001B990008983001000000680868
+:107440003E9601000000000CF0B1010000000002B7
+:10745000E0B101000000001086C0010000000046FD
+:1074600061B101002000004362DD01008A86A85C52
+:107470001F100000BC86220D146C00009086220DA7
+:10748000246C00000000000D10C001009586000D66
+:1074900024D000000400224BFD7F000000000041CA
+:1074A0002BC0010000000015A2B101001000002057
+:1074B00010C80100F007004025980100978622427D
+:1074C000236C00009C86004123C0000000000046A1
+:1074D00061B101004000001062DD01009886A85CE7
+:1074E0001F000000238300881CB000000000004043
+:1074F00023B00100BC86220D14500000BB86A20DF3
+:107500000E500000A88622461F7C000000000046A6
+:107510001F8001003080001042C90100A686224071
+:10752000E36D00000000004761B101004000001061
+:1075300062DD0100A386A840813200002383008819
+:107540001CB0000020800003469901000000005F8D
+:10755000E191010000002D0648B10100000000F893
+:1075600018B00100000000F804B00100040022F08F
+:107570000E300000AE86A25F0F7C00006386004CD8
+:107580000DC0000000002E5F0F80010063862307FE
+:10759000146C00000400A2461F7C000030000010A4
+:1075A00048C9010024000040F199010000000003D7
+:1075B000F0B1010000000000F0B101000000001671
+:1075C000F0B101002400000000C8010000000047E5
+:1075D00061B10100A00000A462DD0100B886A846E8
+:1075E0001F100000638600030CB000006386000DCE
+:1075F00018C0000004002E140AD00100120000057B
+:1076000048CD0100FE7F000542C901000400A2A48C
+:10761000860600000400A2A1860600000C002AF2E3
+:10762000E0B10100C4862240316C00000000601807
+:10763000389601001E00004043990100008100F6C9
+:1076400080CE0100C886A6408132000000000044C0
+:1076500043C10100CA86220BED6D0000080000A1A5
+:1076600042C90100020000A146C901000400A2A114
+:10767000860600000F0000FA948801000400A2456D
+:10768000956C00000200004A86E40100000000F64C
+:107690000EB00100D48622471F7C000004001F4367
+:1076A0000E500000D486A0460F40000000000041AC
+:1076B0000FC00100D88622481F7C00000000004057
+:1076C00091B0010004000FA242310000DB860040AF
+:1076D00089B000000C0000A242C901000000004374
+:1076E00089B001000000004395D00100000000FCBB
+:1076F00082B00100DE86A041904000000000004101
+:1077000091C00100E38622471F7C0000E386A0436E
+:10771000896C0000E3862045896C0000E386A04167
+:107720000E400000000000410FC0010000000041B9
+:1077300089C00100DB86A24195500000F0862248F6
+:107740001F7C00001000004892F40100FFFF004879
+:1077500090880100EA8690489240000000000041B5
+:1077600093C001000A0000A244C901000000662085
+:1077700093A401000A00004380CC0100000000A295
+:1077800080C001000400A240426D00000400A2A1DC
+:10779000860600000400A2461F7C00001B9900170B
+:1077A00098300100FF0700177E8901000400A64001
+:1077B000813200003080001044C901001200001422
+:1077C000F0C9010000000017F0B10100120000052F
+:1077D000E0CD01003000001080C80100000000442E
+:1077E00061B101002000004062DD0100FA86A8407E
+:1077F000813200000587225C1F7C000000003C44B1
+:1078000023E0010000002D1048C101000487224040
+:10781000E36D00000000004661B10100400000106F
+:1078200062DD01000187A8408132000023830088C7
+:107830001CB000000000005C1F8001000887A24708
+:107840001F7C00000C9500408132010088870017E2
+:1078500010B00000139500408132010000002F039A
+:1078600048B101000C87A00716400000000000414D
+:1078700017C001000000000BE4B10100000000503F
+:1078800017F00100108790F2164000000000004140
+:1078900017C001000000662017A4010010000014AA
+:1078A0002AC80100000000502BE00100000000F297
+:1078B0002A9401003080001042C901001A8722403A
+:1078C000E36D00000000004461B1010040000010C1
+:1078D00062DD01001787A840813200002383008801
+:1078E0001CB000000080001710DC010088870040F9
+:1078F00081B2000024879C0F803200000000005CF1
+:107900001F8001000080001042C90100248722402E
+:10791000E36D00000000004761B10100400000106D
+:1079200062DD01002187A8408132000023830088A6
+:107930001CB00000298722078032000000000003ED
+:1079400042B101000000000742C10100008000A117
+:10795000469901000000005FE191010004002E0340
+:1079600048B101000000000AE0B101002E8722406A
+:10797000316C00000C0000404599010000006018C7
+:107980003896010000002E1048B1010000000050A0
+:10799000F1B1010000000008F0B101000000000397
+:1079A000E0B101000000004461B1010000000010DE
+:1079B00062B101003387A840233000002383008890
+:1079C0001CB0000000002D5211C001001000000387
+:1079D00048C90100000000F818B00100000000F8DC
+:1079E00004B00100000000F80EB001000C0000A47B
+:1079F0000CC8010004002240156C000000003C444B
+:107A000023E00100000000A486B0010000002E1059
+:107A100048C101004287A3120E6C0000438768072B
+:107A20001AB00000000068121AB001001B9900088B
+:107A3000983001000000004081B2010000000010F9
+:107A400086C00100000068083E9601000000000C9E
+:107A5000F0B1010000000002E0B1010000000046AA
+:107A600061B101002000004362DD01004A87A85C8B
+:107A70001F1000007C87220D146C00005087220D1F
+:107A8000246C00000000000D10C001005587000D9F
+:107A900024D000000400224BFD7F000000000041C4
+:107AA0002BC0010000000015A2B101001000002051
+:107AB00010C80100F00700402598010057872242B6
+:107AC000236C00005C87004123C0000000000046DA
+:107AD00061B101004000001062DD01005887A85C20
+:107AE0001F000000238300881CB00000000000403D
+:107AF00023B001000400220D145000007B87A20D6A
+:107B00000E500000688722461F7C000000000046DF
+:107B10001F8001003080001042C9010066872240AA
+:107B2000E36D00000000004761B10100400000105B
+:107B300062DD01006387A840813200002383008852
+:107B40001CB0000020800003469901000000005F87
+:107B5000E191010000002D0648B10100000000F88D
+:107B600018B00100000000F804B00100040022F089
+:107B70000E3000006E87A25F0F7C00003C87004C37
+:107B80000DC0000000002E5F0F8001003C8723071E
+:107B9000146C00000400A2461F7C0000300000109E
+:107BA00048C9010024000040F199010000000003D1
+:107BB000F0B1010000000000F0B10100000000166B
+:107BC000F0B101002400000000C8010000000047DF
+:107BD00061B10100A00000A462DD01007887A84621
+:107BE0001F1000003C8700030CB000003C87000D14
+:107BF00018C000000400A2461F7C00008687225C9B
+:107C00001F7C00000000005C1F80010000003C445D
+:107C100023E0010000002D1048C1010086872240AA
+:107C2000E36D00000000004661B10100400000105B
+:107C300062DD01008387A840813200002383008831
+:107C40001CB000000000001710B001008887004041
+:107C50002BB00000008000034499010000000004E4
+:107C6000E0B1010004002640813200000400A09F22
+:107C7000136C00008F87229F136C000002000088A5
+:107C80001CCC01002783004081B200009498004181
+:107C90003F430100000000408DB0010000000040A3
+:107CA00005B001007F9800400F3001000400A25C85
+:107CB0001F7C00000688005C1F9000001000000080
+:107CC0000EF4010004002640813200000000003A5A
+:107CD000018401009B872250016C00000D040040CC
+:107CE00089980100099900008A300100030000070B
+:107CF0001AF401001895000716300100A6872241EA
+:107D0000816C0000A1872242816C000023830088DF
+:107D10001CB00000A587225F0F7C00000000005F00
+:107D20000F8001000E0400408998010009990000AD
+:107D30008A300100F08700400FB00000B387A25ADC
+:107D40001F7C00000400A25A1F7C000000B5000D3B
+:107D500042C901000400220BE67D000000B7000DBF
+:107D600042C901000400220BE67D0000709400402F
+:107D700081320100B3872220856C0000B0879C0F00
+:107D800080320000238300881CB000008D95005CC9
+:107D90001F000100C8970042613101002383008861
+:107DA0001CB00000900400079630010000002D0573
+:107DB00048B10100000000F018B001000000000010
+:107DC00080B00100A488A25F816C0000A8002D4350
+:107DD0001980010037002DF024B00100040000F3E9
+:107DE0008EF401000F0000F3908801000400A3430B
+:107DF0008F6C00000400A343916C0000C4872248EC
+:107E00008E6C0000360000404399010058003D434D
+:107E1000E7E10100C4871FF0246C0000C387234101
+:107E20008F6C0000A488004781B00000A48800483F
+:107E300081B000004000004043990100B0002DF0E7
+:107E400014B00100C987220A904000005F980040EA
+:107E500091300100A488A24080320000B0002D457E
+:107E600081B00100D58722F02C300000A3002D3016
+:107E700083B00100AC002DF382E00100CF87A34165
+:107E80002C6C00000000001682B0010098002DF05C
+:107E900082C0010088002DF082D00100000000F2B5
+:107EA00098E80100A488204C826C00007C002D41E1
+:107EB00098E80100A48820F0986C0000F087220A5E
+:107EC000803200004002000C7E890100F087A6404D
+:107ED00081320000A488004981B00000200000A683
+:107EE00080B00100DD872243216F00001380004035
+:107EF00080DC0100DE87004081B200001A80004073
+:107F000080DC0100DE87A25E0B7D000000000040E7
+:107F100008B10100E0879F8580320000E4870040BF
+:107F200081B200001A832240577D0000010000400A
+:107F300057990100E487424081320000000000446C
+:107F40009393010001831A5B69930000EA8722463C
+:107F5000F37F0000EA87A241F37F0000C680004261
+:107F600097330100040000CB81C80100ED87224057
+:107F7000F27F0000C680006F97330100EF87224038
+:107F8000737D0000E08000418BB30000E787004074
+:107F900081B20000F7879C0F803200000080001043
+:107FA00042C90100F7872240E36D00000000004550
+:107FB00061B101004000001062DD0100F487A840BB
+:107FC00081320000238300881CB000003494220218
+:107FD00080320000F88742408132000000000044F7
+:107FE0009393010034941A026897000002889C0F52
+:107FF000803200000080001042C901000288224047
+:10800000E36D00000000004561B101004000001078
+:1080100062DD0100FF87A8408132000023830088D1
+:108020001CB00000449422028032000003884240C9
+:1080300081320000000000449393010044941A022E
+:10804000689700000D889C0F8032000000800010AF
+:1080500042C901000D882240E36D00000000004588
+:1080600061B101004000001062DD01000A88A840F3
+:1080700081320000238300881CB000002F8322027D
+:10808000803200000E88424081320000000000442F
+:108090009393010000001A02689701002F830040AB
+:1080A00005B00000008000A656B1010056952F4093
+:1080B00005B001000400A240E76D0000B89429411A
+:1080C000E7B1010000000054EF930100000000F24E
+:1080D0000EB001000400A30C556F00002900004001
+:1080E0000D9801000900000712E40100000000A73C
+:1080F00013C00100030000071AF401000700000785
+:1081000016880100FFFF001034D8010000000003B2
+:10811000349401000000004023B00100201800400A
+:1081200011980100040020AA0F6C000000B5000D9A
+:1081300042C901004688220BE67D00002588604088
+:1081400081320000FFFF0007848901002E8805C2EC
+:1081500024300000580400408132010000002D0549
+:1081600048B10100638870F0183001001000000C65
+:1081700082F401000400A2410E6C00004688004019
+:1081800081B200000000704081B201003D88A0482B
+:10819000236C00000000005035D001000080001A60
+:1081A00042C9010037882240E36D00000000004210
+:1081B00061B101004000001A62DD01003488A8406E
+:1081C00081320000238300881CB00000209800400A
+:1081D00043990100638800F8183001003888A241F3
+:1081E00023500000FFFF001034D8010000000003FE
+:1081F00034940100201800401198010000002E1A4C
+:1082000048B1010000000044F1B101000000000885
+:10821000F0B101000000004261B101002000001A2D
+:1082200062DD01004188A809E03100000000004142
+:1082300023C001000000005035C0010000000044D0
+:1082400011C00100528822410D5000000000004181
+:108250000FC001004E88A0AA0F6C00000000004172
+:108260000FB001000900000712E40100000000A7A0
+:1082700013C00100000000401BB001002288004133
+:1082800017B000000002000912C8010022888341D3
+:10829000174000000000004017B001002288004194
+:1082A0001BC000005D882340236C000000000050CC
+:1082B00035D001000080001A42C901005A882240CE
+:1082C000E36D00000000004261B101004000001AAF
+:1082D00062DD01005788A8408132000023830088B6
+:1082E0001CB000002098004043990100638800F80A
+:1082F000183001005B88A2412350000000000041BB
+:108300000FC001006088A0AA0F6C000000000041AF
+:108310000FB00100B8942007E4B101005695204049
+:10832000E7B10100F08700400FB00000FFFF000C34
+:1083300080D801000400264081320000C002000CF9
+:108340007E8901007C882654613100006F88870C8B
+:10835000803200001F040040899801000999000C38
+:108360008A3001000000005461B101000F0000409C
+:10837000629901006F882840813200000400A254F5
+:10838000777D00006B88004081B20000778822462C
+:10839000197C00002A040040899801000999000C0A
+:1083A0008A3001000000005461B101000D0000405E
+:1083B000629901000000A84081B200000400A254AC
+:1083C000777D00007088004081B200007C882249DF
+:1083D000197C00000E000040629901000000A840D6
+:1083E00081B200000400A254777D0000778800402D
+:1083F00081B2000010000040629901000000A84016
+:1084000081B200000400A254777D00007C88004007
+:1084100081B2000030942F55F1930100004000A676
+:1084200056B101002F83A241E551000064000040D5
+:10843000E599010084884440813200008788A29336
+:10844000576F00000000004157C3010000001CAB43
+:1084500027B301002F832250FD7F00002F8322517C
+:10846000FD7F00002F83A2411D53000050460040B5
+:108470001D9B010038050040813201000E000048BC
+:10848000B2CB010010040040493101009388224022
+:10849000B56F00000E000048B2CB0100200400417F
+:1084A000B55301002F83004081B20000000000514D
+:1084B000FD83010040160040459901004005004041
+:1084C000493101001E000048B2CB010010040040F9
+:1084D00081320100000000DA91C001000400004870
+:1084E000B2CB010020040040B533010060162040EB
+:1084F000E5B1010055820040B53301000800004895
+:10850000B2CB0100FFFF004AB48B01002004004001
+:10851000813201000A000048B2CB01001000004A7D
+:10852000B4F7010020040040813201002F83004095
+:1085300081B200000400A205486D00000200004066
+:10854000439901000400A2F20E6C00000400A20294
+:10855000803200000500004043990100000000F354
+:1085600008B00100AE882250816C00000F0400406A
+:1085700089980100100000408AE401000999000474
+:108580008A14010004002048096C000004002057F0
+:10859000816C000004002040E6B1010003000040AF
+:1085A00096E401000000000496C00100B488004B6E
+:1085B00010C90000E48B004109B000000400002055
+:1085C0008FB00000040000208FB0000004000020E5
+:1085D0008FB00000040000208FB0000004000020D5
+:1085E0008FB00000040000208FB0000004000020C5
+:1085F0008FB00000040000208FB00000198C0041F3
+:1086000009B00000040000208FB00000040000202A
+:108610008FB00000040000208FB000000400002094
+:108620008FB00000040000208FB000000400002084
+:108630008FB00000040000208FB000000400002074
+:108640008FB00000558C004509B00000558C0045E6
+:1086500009B00000558C004509B00000558C00455C
+:1086600009B00000040000208FB0000004000020CA
+:108670008FB00000040000208FB000000400002034
+:108680008FB000009C8C004309B00000CB8C0043ED
+:1086900009B00000CF8C004409B000003E8E0045B8
+:1086A00009B00000040000208FB00000040000208A
+:1086B0008FB00000040000208FB0000004000020F4
+:1086C0008FB00000040000208FB00000DF8C00435A
+:1086D00009B00000DD8C004309B00000E08B0045CC
+:1086E00009B00000040000208FB00000040000204A
+:1086F0008FB00000040000208FB0000004000020B4
+:108700008FB00000988D004209B00000988D0043A2
+:1087100009B00000988D004409B00000E08B0045CE
+:1087200009B00000040000208FB000000400002009
+:108730008FB00000040000208FB000000400002073
+:108740008FB00000040000208FB00000B88D0043FF
+:1087500009B00000040000208FB00000E08B00454D
+:1087600009B00000040000208FB0000004000020C9
+:108770008FB00000040000208FB000000400002033
+:108780008FB00000040000208FB00000E08D004397
+:1087900009B00000E08D004409B00000E08B004506
+:1087A00009B00000040000208FB000000400002089
+:1087B0008FB00000040000208FB0000004000020F3
+:1087C0008FB00000040000208FB00000E08D004258
+:1087D00009B00000040000208FB00000E08B0045CD
+:1087E00009B00000040000208FB000000400002049
+:1087F0008FB00000040000208FB0000004000020B3
+:108800008FB00000040000208FB000000F8E0044E5
+:1088100009B00000040000208FB00000E08B00458C
+:1088200009B00000040000208FB000000400002008
+:108830008FB00000040000208FB000000400002072
+:108840008FB00000E08B004209B00000228E00458E
+:1088500009B00000228E004509B00000E08B004501
+:1088600009B00000040000208FB0000004000020C8
+:108870008FB00000040000208FB000000400002032
+:108880008FB00000248E004209B00000248E004307
+:1088900009B00000248E004409B00000248E004579
+:1088A00009B00000040000208FB000000400002088
+:1088B0008FB00000040000208FB0000004000020F2
+:1088C0008FB00000040000208FB0000004000020E2
+:1088D0008FB000002F8E004409B00000E08B0045EF
+:1088E00009B00000040000208FB000000400002048
+:1088F0008FB00000040000208FB0000004000020B2
+:108900008FB00000418E004209B00000308E00435D
+:1089100009B00000418E004409B00000E08B004522
+:1089200009B00000040000208FB000000400002007
+:108930008FB00000040000208FB000000400002071
+:108940008FB00000040000208FB00000438E004371
+:1089500009B00000378E004409B00000E08B0045EC
+:1089600009B00000040000208FB0000004000020C7
+:108970008FB00000040000208FB00000E08B0041A9
+:1089800009B00000968D004209B00000968D0043AA
+:1089900009B00000968D004409B00000E08B00454E
+:1089A00009B00000040000208FB000000400002087
+:1089B0008FB00000040000208FB00000E08B004169
+:1089C00009B00000458E004209B00000458E00430A
+:1089D00009B00000458E004409B00000E08B00455E
+:1089E00009B00000040000208FB000000400002047
+:1089F0008FB00000040000208FB0000004000020B1
+:108A00008FB00000040000208FB0000004000020A0
+:108A10008FB00000040000208FB000004C8E004595
+:108A200009B00000040000208FB000000400002006
+:108A30008FB00000040000208FB000004E8E004276
+:108A400009B00000040000208FB0000004000020E6
+:108A50008FB00000040000208FB000000400002050
+:108A60008FB00000040000208FB000000400002040
+:108A70008FB00000040000208FB000000400002030
+:108A80008FB000005B8E004309B00000C18E004330
+:108A900009B00000CF8C004409B000003E8E0045B4
+:108AA00009B00000040000208FB000000400002086
+:108AB0008FB00000040000208FB0000004000020F0
+:108AC0008FB00000040000208FB00000C98E00436A
+:108AD00009B00000CF8C004409B000003E8E004574
+:108AE00009B00000040000208FB000000400002046
+:108AF0008FB00000040000208FB0000004000020B0
+:108B00008FB00000040000208FB00000DD8E004315
+:108B100009B00000040000208FB00000E08B004589
+:108B200009B00000040000208FB000000400002005
+:108B30008FB00000040000208FB00000040000206F
+:108B40008FB00000968C004309B00000C58E004332
+:108B500009B00000CF8C004409B000003E8E0045F3
+:108B600009B00000040000208FB0000004000020C5
+:108B70008FB0000002002D0548B101000400A2F2F0
+:108B80000E6C00000400A2028032000007002D409D
+:108B900081B20100000000F308B0010010040040A1
+:108BA00089980100100000478AE401000999000437
+:108BB0008A1401000400204E096C00002A000047BE
+:108BC00080CE0100040024408132000006002047CE
+:108BD000E6B101000400004796E4010000000047F0
+:108BE00096D001000000004796D00100000000046C
+:108BF00096C001007D89004B10C90000F98E004924
+:108C000009B000000400002085B00000040000202E
+:108C100085B000000400002085B0000004000020A2
+:108C200085B000000400002085B000000400002092
+:108C300085B000000400002085B000000400002082
+:108C400085B000000400002085B000000400002072
+:108C500085B000000400002085B000000400002062
+:108C600085B000000400002085B000000400002052
+:108C700085B00000328F004209B0000004000020DF
+:108C800085B000000400002085B000000400002032
+:108C900085B000000400002085B000000400002022
+:108CA00085B000000400002085B000000400002012
+:108CB00085B000000400002085B000000400002002
+:108CC00085B000000400002085B0000004000020F2
+:108CD00085B000000400002085B0000004000020E2
+:108CE00085B00000398F004609B000000400002064
+:108CF00085B000000400002085B0000004000020C2
+:108D000085B000000400002085B0000004000020B1
+:108D100085B000000400002085B0000004000020A1
+:108D200085B000000400002085B000000400002091
+:108D300085B000000400002085B000000400002081
+:108D400085B000000400002085B000000400002071
+:108D500085B000000400002085B000004A8F00426A
+:108D600009B000000400002085B000006D8F0042B3
+:108D700009B000000400002085B0000004000020BD
+:108D800085B000000400002085B000000400002031
+:108D900085B000000400002085B000000400002021
+:108DA00085B00000678F004A09B000000400002071
+:108DB00085B000000400002085B000000400002001
+:108DC00085B000000400002085B00000748F0043CF
+:108DD00009B000000400002085B00000DF8F0044CF
+:108DE00009B000000400002085B00000040000204D
+:108DF00085B000000400002085B0000004000020C1
+:108E000085B000000400002085B0000004000020B0
+:108E100085B00000DD8F004B09B000000400002089
+:108E200085B000000400002085B000000400002090
+:108E300085B000003D8F004109B000000400002013
+:108E400085B000003D8F004309B000003D8F004415
+:108E500009B000003D8F004509B000003D8F00467D
+:108E600009B000003D8F004709B000003D8F004869
+:108E700009B000003D8F004909B000003D8F004A55
+:108E800009B000003D8F004B09B000003D8F004C41
+:108E900009B000003D8F004D09B000000400002023
+:108EA00085B000000400002085B00000489000421A
+:108EB00009B000000400002085B000004890004484
+:108EC00009B000000400002085B00000040000206C
+:108ED00085B000000400002085B0000004000020E0
+:108EE00085B000000400002085B0000004000020D0
+:108EF00085B000004890004B09B00000040000203D
+:108F000085B000000400002085B0000004000020AF
+:108F100085B000000400002085B00000040000209F
+:108F200085B000006590004509B0000004000020F5
+:108F300085B000000400002085B00000040000207F
+:108F400085B000000400002085B000007D9000473F
+:108F500009B000000400002085B0000056900045D4
+:108F600009B000000400002085B0000004000020CB
+:108F700085B000001593004609B0000004000020F1
+:108F800085B000000400002085B00000040000202F
+:108F900085B000000400002085B00000040000201F
+:108FA00085B000006D8F004609B000004A8F004672
+:108FB00009B00000658F004709B00000658F0048C8
+:108FC00009B000000400002085B00000040000206B
+:108FD00085B000000400002085B00000678F004AC3
+:108FE00009B000000400002085B00000040000204B
+:108FF00085B000000400002085B0000004000020BF
+:1090000085B000000400002085B0000004000020AE
+:1090100085B00000DF8F004509B00000748F004369
+:1090200009B00000658F004709B00000658F004857
+:1090300009B000000400002085B0000004000020FA
+:1090400085B000000400002085B00000DD8F004CDA
+:1090500009B000000400002085B0000004000020DA
+:1090600085B000000400002085B00000040000204E
+:1090700085B000000400002085B00000040000203E
+:1090800085B000008490004409B000008490004244
+:1090900009B00000C98B004709B00000C98B004827
+:1090A00009B000000400002085B00000040000208A
+:1090B00085B000000400002085B000008490004BC3
+:1090C00009B000000400002085B00000040000206A
+:1090D00085B000003D8F004109B00000AF9000470F
+:1090E00009B000000400002085B000009290004705
+:1090F00009B000000400002085B00000040000203A
+:1091000085B000000400002085B0000004000020AD
+:1091100085B000000400002085B00000040000209D
+:1091200085B000009290004709B0000004000020C4
+:1091300085B000000400002085B00000040000207D
+:1091400085B000000400002085B00000040000206D
+:1091500085B000000400002085B00000040000205D
+:1091600085B000009290004709B00000AF90004722
+:1091700009B00000658F004709B00000658F004806
+:1091800009B000000400002085B0000004000020A9
+:1091900085B000000400002085B0000092900047D8
+:1091A00009B000000400002085B000000400002089
+:1091B00085B000000400002085B0000004000020FD
+:1091C00085B000000400002085B0000004000020ED
+:1091D00085B000000400002085B0000004000020DD
+:1091E00085B00000BE90004709B00000BE90004866
+:1091F00009B000000400002085B000000400002039
+:1092000085B000000400002085B0000004000020AC
+:1092100085B000000400002085B00000040000209C
+:1092200085B000002F91004009B000005191004727
+:1092300009B000004391004809B000008A9000473F
+:1092400009B000008A90004709B000005191004722
+:1092500009B000005A91004709B000005A91004837
+:1092600009B000000400002085B0000043910048D0
+:1092700009B000008A90004709B000008A900047BA
+:1092800009B000004391004809B00000040000202C
+:1092900085B000000400002085B00000040000201C
+:1092A00085B000004890004309B000000400002091
+:1092B00085B000004890004509B000004890004685
+:1092C00009B00000658F004709B00000658F0048B5
+:1092D00009B000000400002085B000004890004A5A
+:1092E00009B000000400002085B000004890004C48
+:1092F00009B000000400002085B000000400002038
+:1093000085B000000400002085B00000AE9000474A
+:1093100009B00000A090004809B0000091900047FB
+:1093200009B000009190004709B00000AE900047DE
+:1093300009B00000C98B004709B00000C98B004884
+:1093400009B000000400002085B00000A090004893
+:1093500009B000009190004709B0000091900047CB
+:1093600009B00000A090004809B0000004000020EF
+:1093700085B000000400002085B000005D9100422F
+:1093800009B000000400002085B000005D91004499
+:1093900009B000000400002085B000000400002097
+:1093A00085B000000400002085B00000040000200B
+:1093B00085B000000400002085B0000004000020FB
+:1093C00085B000005D91004B09B000000400002052
+:1093D00085B000000400002085B0000004000020DB
+:1093E00085B000000400002085B0000004000020CB
+:1093F00085B000005D91004309B00000040000202A
+:1094000085B000005D91004509B000005D91004607
+:1094100009B000005D91004709B000005D9100486F
+:1094200009B000000400002085B000005D91004AF2
+:1094300009B000000400002085B000005D91004CE0
+:1094400009B000005D91004C09B00000040000204C
+:1094500085B000000400002085B00000040000205A
+:1094600085B000007A91004609B000000400002099
+:1094700085B000000400002085B00000040000203A
+:1094800085B000000400002085B000007D900047FA
+:1094900009B000000400002085B000007A91004669
+:1094A00009B000000400002085B000000400002086
+:1094B00085B000000400002085B0000004000020FA
+:1094C00085B000000400002085B0000004000020EA
+:1094D00085B000009C92004609B000000400002006
+:1094E00085B000000400002085B0000004000020CA
+:1094F00085B000000400002085B000007D9000478A
+:1095000009B000000400002085B000009C920046D5
+:1095100009B000000400002085B000000400002015
+:1095200085B000009C92004609B0000004000020B5
+:1095300085B000000400002085B000000400002079
+:1095400085B000000400002085B00000C5920042F4
+:1095500009B000000400002085B0000004000020D5
+:1095600085B000000400002085B000000400002049
+:1095700085B000000400002085B000000400002039
+:1095800085B00000C392004A09B00000040000202A
+:1095900085B000000400002085B000000400002019
+:1095A00085B000000400002085B000000400002009
+:1095B00085B000000400002085B0000004000020F9
+:1095C00085B00000C592004609B0000004000020EC
+:1095D00085B00000658F004709B00000658F004826
+:1095E00009B000000400002085B000000400002045
+:1095F00085B000000400002085B00000C392004A3E
+:1096000009B000000400002085B000000400002024
+:1096100085B000000400002085B000000400002098
+:1096200085B000000400002085B000000400002088
+:1096300085B000000400002085B000000400002078
+:1096400085B000000400002085B000000400002068
+:1096500085B000006A91004109B0000004000020BC
+:1096600085B000000400002085B000000400002048
+:1096700085B000000400002085B000000400002038
+:1096800085B000000400002085B000007791004202
+:1096900009B000000400002085B00000779100446C
+:1096A00009B000000400002085B000000400002084
+:1096B00085B000000400002085B0000004000020F8
+:1096C00085B000000400002085B0000004000020E8
+:1096D00085B000007791004B09B000000400002025
+:1096E00085B000000400002085B0000004000020C8
+:1096F00085B000000400002085B0000004000020B8
+:1097000085B000007791004309B0000004000020FC
+:1097100085B000007791004509B0000077910046C0
+:1097200009B000007791004709B000007791004828
+:1097300009B000000400002085B0000004000020F3
+:1097400085B000000400002085B000007791004C37
+:1097500009B000000400002085B0000004000020D3
+:1097600085B000000400002085B000000400002047
+:1097700085B000006590004C09B000000400002096
+:1097800085B000000400002085B000000400002027
+:1097900085B000000400002085B000007D900047E7
+:1097A00009B000000400002085B000005690004C75
+:1097B00009B000000400002085B000000400002073
+:1097C00085B000008393004609B00000040000202B
+:1097D00085B000000400002085B000000A9300421C
+:1097E00009B000000400002085B000000A93004486
+:1097F00009B000000400002085B000000400002033
+:1098000085B000000400002085B0000004000020A6
+:1098100085B000000400002085B000000400002096
+:1098200085B000000A93004B09B00000040000203E
+:1098300085B000000400002085B000000400002076
+:1098400085B000000400002085B000000400002066
+:1098500085B000000400002085B000000400002056
+:1098600085B000000A93004509B000000A93004645
+:1098700009B00000658F004709B00000658F0048FF
+:1098800009B000000400002085B0000004000020A2
+:1098900085B000000400002085B000000A93004C51
+:1098A00009B000000400002085B000000400002082
+:1098B00085B000000400002085B0000056900042F2
+:1098C00009B000001593004609B000000400002014
+:1098D00085B000000400002085B0000056900046CE
+:1098E00009B000000400002085B000007D90004712
+:1098F00009B000000400002085B000001593004668
+:1099000009B000000400002085B000000400002021
+:1099100085B000001593004609B000000400002047
+:1099200085B000000400002085B000000400002085
+:1099300085B000001C93004309B000000400002023
+:1099400085B000000400002085B000000400002065
+:1099500085B000000400002085B000007D90004725
+:1099600009B000000400002085B000001C930043F3
+:1099700009B000000400002085B0000004000020B1
+:1099800085B000001C93004D09B0000004000020C9
+:1099900085B000000400002085B000000400002015
+:1099A00085B000000400002085B000003293004321
+:1099B00009B000000400002085B000000400002071
+:1099C00085B000000400002085B0000004000020E5
+:1099D00085B000000400002085B0000004000020D5
+:1099E00085B000000393004A09B000000400002085
+:1099F00085B000000400002085B0000004000020B5
+:109A000085B000000400002085B0000004000020A4
+:109A100085B000000400002085B000000400002094
+:109A200085B000003293004309B00000040000201C
+:109A300085B00000658F004709B00000658F0048C1
+:109A400009B000000400002085B0000004000020E0
+:109A500085B000000400002085B000000393004A98
+:109A600009B000000400002085B0000004000020C0
+:109A700085B000000400002085B000000400002034
+:109A800085B000004A93004309B0000004000020A4
+:109A900085B000000400002085B000000400002014
+:109AA00085B000000400002085B000007D900047D4
+:109AB00009B000000400002085B000004A93004374
+:109AC00009B000000400002085B000000400002060
+:109AD00085B000004A93004D09B00000040000204A
+:109AE00085B000000400002085B000004A8F0042CD
+:109AF00009B000000400002085B000006D8F004216
+:109B000009B000000400002085B00000040000201F
+:109B100085B000000400002085B000000400002093
+:109B200085B000000400002085B000000400002083
+:109B300085B000006D93004209B0000004000020D1
+:109B400085B000000400002085B000000400002063
+:109B500085B000000400002085B000000400002053
+:109B600085B000000400002085B000000400002043
+:109B700085B000006D8F004609B000004A8F004696
+:109B800009B00000658F004709B00000658F0048EC
+:109B900009B000000400002085B00000040000208F
+:109BA00085B000000400002085B000006D930046E1
+:109BB00009B000000400002085B00000040000206F
+:109BC00085B000000400002085B0000004000020E3
+:109BD00085B000007493004A09B000000400002022
+:109BE00085B000000400002085B0000004000020C3
+:109BF00085B000000400002085B000007D90004783
+:109C000009B000000400002085B000007493004AF1
+:109C100009B000000400002085B00000040000200E
+:109C200085B000001693004609B000000400002033
+:109C300085B000000400002085B000000400002072
+:109C400085B000001693004609B000000400002013
+:109C500085B000000400002085B000000400002052
+:109C600085B000000400002085B000007D90004712
+:109C700009B000000400002085B0000016930046E3
+:109C800009B000000400002085B00000040000209E
+:109C900085B000001693004609B0000004000020C3
+:109CA00085B000000400002085B000000400002002
+:109CB00085B000000400002085B000007D930042C4
+:109CC00009B000000400002085B00000040000205E
+:109CD00085B000000400002085B0000004000020D2
+:109CE00085B000000400002085B0000004000020C2
+:109CF00085B000000393004A09B000000400002072
+:109D000085B000000400002085B0000004000020A1
+:109D100085B000000400002085B000000400002091
+:109D200085B000000400002085B000000400002081
+:109D300085B000007D93004609B0000004000020BB
+:109D400085B00000658F004709B00000658F0048AE
+:109D500009B000000400002085B0000004000020CD
+:109D600085B000000400002085B000000393004A85
+:109D700009B000000400002085B0000004000020AD
+:109D800085B000000400002085B00000748F004DF5
+:109D900009B000000400002085B00000040000208D
+:109DA00085B000000400002085B000000400002001
+:109DB00085B000000400002085B0000004000020F1
+:109DC00085B000000400002085B0000004000020E1
+:109DD00085B000000400002085B0000004000020D1
+:109DE00085B000000400002085B0000004000020C1
+:109DF00085B000000400002085B0000004000020B1
+:109E000085B000000400002085B0000004000020A0
+:109E100085B000000400002085B00000748F004D64
+:109E200009B00000658F004709B00000658F004849
+:109E300009B000000400002085B0000004000020EC
+:109E400085B000000400002085B000000400002060
+:109E500085B000000400002085B000000400A205C9
+:109E6000486D0000040022078032000007002E4BDE
+:109E700019900100FB870004E6B10000C98B224263
+:109E8000197C00000F97003A81300100C98B004017
+:109E900081B20000C98B2242197C0000FF1F000F15
+:109EA0001E8C01007396004081320100DB8B9C0FF9
+:109EB000803200000000005C1F8001000080001064
+:109EC00042C90100DB8B2240E36D00000000004529
+:109ED00061B101004000001062DD0100D88BA84094
+:109EE00081320000238300881CB000001D852202FF
+:109EF00080320000DC8B42408132000000000044D0
+:109F00009393010000001A02689701001D8500402C
+:109F100005B000000400A205486D000004002207FF
+:109F20008032000005002E4B19900100FB870004D1
+:109F3000E6B100000000004087B0010000000040D2
+:109F40008DB001000080000342C90100400000A163
+:109F500044C90100000000F0E0B101007F98000654
+:109F6000074001000400A25C1F7C00000000000606
+:109F700007D00100D4002E5C1F90010000000007F4
+:109F8000F0B101000C80000342C90100000000F0A4
+:109F9000F0B101000000004081B20100000000FEAD
+:109FA00096B00100000000FE96C00100000000F025
+:109FB000F0B101000000004081B20100000000FE8D
+:109FC00096C00100000000FE96C00100000000F0F5
+:109FD000F0B101000000004081B20100000000FA71
+:109FE00096C00100000000FE96C001000030004B4A
+:109FF000948801000000004695F001000000004A2E
+:10A0000096C001005E012E34978401000200004BCF
+:10A01000E4E5010064012040E1B10100090000070E
+:10A0200086E4010000002EA787C001001000001088
+:10A0300048C9010010000040F19901005801004397
+:10A04000F0C9010058010005E0C90100000000440A
+:10A0500061B10100A00000A462DD0100088CA840ED
+:10A06000813200000000000548B101001A000040E4
+:10A070009798010008002E4095B00100108C204BED
+:10A08000946C000000000040F1B101000D8C004113
+:10A0900095C000001080001042C90100178C2240BA
+:10A0A000E36D00000000004461B1010040000010B9
+:10A0B00062DD0100138CA8408132000023830088F8
+:10A0C0001CB000000000000548B101000F970040DF
+:10A0D00081300100E08B004081B200000C80000361
+:10A0E00042C90100000000F886B00100000000F83D
+:10A0F00088B001001480000398C801000400A2A1E8
+:10A10000986C00001E8C444081320000218CA24CCF
+:10A11000FD7F0000228C004CFD930000238C20F07A
+:10A12000566F0000000000F056B3010000001C4014
+:10A1300081B2010064000040819801006400004089
+:10A1400080CC01000400A64081320000D80000400D
+:10A15000819801000400A2438104000000800010E7
+:10A1600044C9010064000040F1990100700000053D
+:10A17000F0C9010000000043F0B1010000000047F9
+:10A1800061B101002000001062DD01002E8CA844A6
+:10A19000E0310000100000108CC801000080004673
+:10A1A00044C9010040000040F19901006801000528
+:10A1B000F0C9010064000043F0C90100040024401C
+:10A1C000813200000000004761B10100000000463C
+:10A1D00062B10100378CA844E0310000238300887D
+:10A1E0001CB000000900000786E4010038002EA71B
+:10A1F00087C001008B002D0548B101003F8C224330
+:10A20000E77D00000000004445C10100428C22446B
+:10A21000E77D00000000004C45C101000000004A3D
+:10A2200019900100680120A2E4B1010088000040FB
+:10A2300043990100468C230BE56D000000000041AE
+:10A24000199001000080001044C901005000004036
+:10A25000F199010058010043F0C9010058010005BF
+:10A26000E0C901000000004461B1010000000010DD
+:10A2700062B101004B8CA84081320000238300882A
+:10A280001CB000005C002E0548B1010000800003F6
+:10A2900042C90100000060F096B00100A00000403B
+:10A2A000439901000400A2F2803200000F970041A0
+:10A2B00081300100E08B004081B20000588CA2493F
+:10A2C000197C000086000040479901005C8C00402A
+:10A2D000E5B1000086002F49198001005C8CA2F2D4
+:10A2E000803200008B0000404799010000000042CE
+:10A2F000E79101005F8CA246197C0000A00000409D
+:10A3000047990100638C0040E5B10000A0002F4692
+:10A3100019800100638CA2F2803200008B000040A3
+:10A320004799010000000041E79101000700004E3D
+:10A3300080E401000039004080C801000400A24010
+:10A34000066C0000A80000404399010034002DF085
+:10A3500024B00100000000FB0CB00100000000FB75
+:10A3600010B00100000000FB12B001000F0000F36C
+:10A3700016880100040000F314F40100938C2640B9
+:10A3800081320000798C220A166C000058003D438F
+:10A3900013E00100000000F882B00100040022F088
+:10A3A000843000001B980040813201002383008824
+:10A3B0001CB000000000000548B101000000004191
+:10A3C00013C00100788CA043136C00000000004013
+:10A3D00013B001006E8C004115D00000938C220A4E
+:10A3E000803200000400A208126C000058003D43B7
+:10A3F00013E00100000000F882B00100040022F028
+:10A40000843000001B980040813201004000204051
+:10A41000E1B10100238300881CB0000000000005AA
+:10A4200048B10100938C224115500000000000410A
+:10A4300011C00100868CA043116C00000000004098
+:10A4400011B0010004002206106C000058003D43CA
+:10A4500011E00100000000F836B00100040022F015
+:10A46000003000000000005083B001005497004706
+:10A4700061310100238300881CB000003194000585
+:10A48000483101000000004561B1010040000010AA
+:10A4900062DD01008F8CA840813200002383008898
+:10A4A0001CB00000828C000548B10000370020403D
+:10A4B000E7B101008697005181300100E08B004038
+:10A4C00081B2000037000040439901000400A2F36C
+:10A4D0008032000034002E41F5B10100001100402F
+:10A4E000E59901000400A248197C0000A08C0048F6
+:10A4F0001990000037000040439901000400A2F3C6
+:10A500008032000034002E41F5B1010000110040FE
+:10A51000E59901000080000342C90100000000F835
+:10A5200094B00100A78C2245237C0000B0002FF0DE
+:10A530008CB00100000060F08CC001007C00004085
+:10A54000439901000400A3F08C6C000090000040CF
+:10A550004399010035002DF08CB0010034002DF33B
+:10A5600084B00100040022F3846C000058003E43D4
+:10A5700085E00100AE8C2248197C000000000041FB
+:10A580008DC001000000680A8CC0010038002A4A12
+:10A59000E0B1010028000000E0C901003C00201BE0
+:10A5A000E0B101001080000342C90100000000F882
+:10A5B00038B00100000000F826B00100040022F8C5
+:10A5C00002300000BC8C2301146C0000000000F875
+:10A5D00080B00100000000F882B001004C0020F0C3
+:10A5E000E4B1010044002040E0B1010048002041F6
+:10A5F000E0B10100A8002D1032B001005F9800F01A
+:10A6000024300100C58CA244816C0000C38C22411F
+:10A61000197C0000BC9500403B300100ED8CA20885
+:10A620003C300000C58C004081B20000BF94004067
+:10A6300081320100ED8CA2083C3000005000201C4B
+:10A64000E0B1010054002013E0B101004E002001F0
+:10A65000E4B101004000200AE0B101008697005FEC
+:10A6600081300100E08B004081B2000037000040E3
+:10A6700047990100959500F394300100A08C224A7F
+:10A6800080320000D18C004081B2000037000040D1
+:10A6900047990100959500F3943001000400204390
+:10A6A000976C000058003E4397E001000000001B3B
+:10A6B000F0B101001F006000008C0100E08B8511EB
+:10A6C000803200000480000342C90100B0002FF076
+:10A6D0008CB00100000060F08CC001007C000040E4
+:10A6E000439901000400A3F08C6C00008697005F82
+:10A6F00081300100E08B004081B20000040022495B
+:10A70000197C0000DF8C004919800000E48C224194
+:10A71000197C0000BC9500403B300100E88CA20889
+:10A720003C3000008697005F81300100E08B0040E4
+:10A7300081B20000BF94004081320100E88CA20881
+:10A740003C3000008697005F81300100E08B0040C4
+:10A7500081B2000050002D1032B0010054002DF0E5
+:10A7600038B001004E002DF026B0010040002DF25F
+:10A7700002B00100000000F014B001003000001031
+:10A780008CC801000080004644C9010068012D44C6
+:10A7900061B10100100068F280C8010000000008EB
+:10A7A000F0B1010058010005E0C901000000000BF4
+:10A7B00037B001000000004036D001005C012E409F
+:10A7C00010C001000000000680C00100000000521F
+:10A7D00081D0010018970040E431010020000046BC
+:10A7E00062DD0100F98CA840233000000E95004086
+:10A7F000813201001695004081320100078D8241AF
+:10A80000234000002080001042C90100048D224036
+:10A81000E36D00000000004661B10100400000103F
+:10A8200062DD0100018DA840813200002383008891
+:10A830001CB000000000000548B10100000000103D
+:10A8400032B001000000004123B001000080001977
+:10A8500044C901000F8D2241197C00000B8DA3011A
+:10A860000C6C00000C8D000604B00000000000011C
+:10A8700004B001000E8D2002366C00000000001BA9
+:10A8800004B00100128D0002E0B10000118DA3019F
+:10A890000C6C0000128D000604B0000000000001E6
+:10A8A00004B001000000680216940100FFFF000BD5
+:10A8B00016D80100000068083E9601000000001C48
+:10A8C000F0B101000000004661B101002000001954
+:10A8D00062DD0100178DA813E0310000548D2202C3
+:10A8E0001450000044002D020CD001003F8DA20244
+:10A8F00002500000258D225C1F7C00002080000398
+:10A9000042C90100248D2240E36D00000000004791
+:10A9100061B101004000001062DD0100208DA840FF
+:10A9200081320000238300881CB000000000000575
+:10A9300048B1010044002D5C1F80010048002DF04B
+:10A9400038B001004C002DF026B0010038002FF285
+:10A9500002B00100418D2201146C00000400A440EB
+:10A9600081320000338D22461F7C0000000000462B
+:10A970001F80010020002D0348B10100328D2240CC
+:10A98000E36D00000000004461B1010040000010D0
+:10A9900062DD01002F8DA8408132000023830088F2
+:10A9A0001CB0000038002F0548B10100000000F87D
+:10A9B00094B0010038002DF096B001000000004C6A
+:10A9C000E1C101002000000348C901000000224A43
+:10A9D000F1B1010044000005F0C901000000004A87
+:10A9E000F0B101000000004BE0B1010000000047A1
+:10A9F00061B10100A00000A462DD01003C8DA85CF3
+:10AA00001F100000418D000548B100000000000249
+:10AA100038C0010004002440813200004F8D22061E
+:10AA2000803200000000005033C001004D8DA202B2
+:10AA3000366C000004002241197C000004008F0DD8
+:10AA400042310000040022F0803200000400225C49
+:10AA5000E17D00000400A2F06A060000100000F88A
+:10AA600010C801000000005C11800100F0070040E8
+:10AA700037980100FD8C00A11AB000000000000210
+:10AA800010C00100FD8C000236D000005000201CD8
+:10AA9000E0B1010054002013E0B101004E0020019C
+:10AAA000E4B101004000200AE0B101005B8D005FCD
+:10AAB00001B000000400A202026C00000400A20227
+:10AAC0000C6C000037002D4601B00100040000F3BB
+:10AAD00080F401005A8DA043816C000000000055F5
+:10AAE00001B0010040002040E1B1010000800019E8
+:10AAF00042C90100618D2240E36D00000000004664
+:10AB000061B101004000001962DD01005E8DA840C6
+:10AB100081320000238300881CB0000013950040A0
+:10AB2000813201003080001042C90100688D22404E
+:10AB3000E36D00000000004461B10100400000101E
+:10AB400062DD0100658DA84081320000238300880A
+:10AB50001CB0000060012F0548B101000000000B8F
+:10AB6000E4B101000000005017F001006D8D90F27B
+:10AB7000164000000000004117C0010000006620E0
+:10AB800017A40100320000A62AC00100000000F254
+:10AB90002A940100708D45486131000000D0001EEC
+:10ABA00062DD0100758D284005300000718D22485E
+:10ABB000777D0000788D004081B200000000001514
+:10ABC00062B10100838D284081320000758D004004
+:10ABD00081B2000000001D0092B00100808D224172
+:10ABE000197C0000040022403B6C00000400A348D4
+:10ABF0003B6C00000080000342C90100C99400F8CA
+:10AC0000003001007D8DA2413B500000848D004941
+:10AC100000B00000FF07001E008C0100C994004036
+:10AC200081320100848D004900B0000000001D4702
+:10AC300019800100878D225F016C00008E98004012
+:10AC400081320100AA88000080B000008E8D225C55
+:10AC50001F7C00002080000342C901008E8D22402D
+:10AC6000E36D00000000004761B1010040000010EA
+:10AC700062DD01008B8DA8408132000023830088B3
+:10AC80001CB000008E8D400548310000FFFF00071A
+:10AC900094890100948D85CA943000008E98185CC8
+:10ACA0001F0001000E00000F1E8C0100B78700403E
+:10ACB00081B200008697180080300100E08B0047C9
+:10ACC000198000000000004019800100E08B22473D
+:10ACD000197C0000BF940040813201009B8DA208C6
+:10ACE00080320000E08B004081B2000018970040E5
+:10ACF0000D3001009C01004045990100FFFF000B51
+:10AD0000988801008B002D5017F00100A18D904C08
+:10AD1000164000000000004117C00100A38D22432F
+:10AD2000E77D00000000004445C1010000006620EE
+:10AD300017A4010068010040439901005C012EF254
+:10AD400080B00100020062407ECD0100000000578B
+:10AD500081C0010000002E1048B101000300004036
+:10AD6000F08D010000000008F0B10100580100055D
+:10AD7000E0C901000000004461B1010000000010C2
+:10AD800062B10100AD8DA8408132000023830088AC
+:10AD90001CB000000000000548B10100B18D45481D
+:10ADA000613100000050000862DD0100B78D2840CD
+:10ADB00005300000B28D2248777D0000C9941D083F
+:10ADC00000300100E08B004081B20000E08B1D47A5
+:10ADD000198000000400A205486D00003500004005
+:10ADE00047990100010063F384C80100BD8DA043B1
+:10ADF000856C00000000634085B00100A8000040A1
+:10AE00004399010037002FF024B00100040022F321
+:10AE10009E060000010063F382CC0100CB8DA241AD
+:10AE20009E060000E08B224483700000A8000040D2
+:10AE3000439901000400A2F0246C00003600004099
+:10AE40004399010058003D43E7E10100E08B1FF00A
+:10AE5000246C00008E98004881300100AA882341AC
+:10AE6000836C0000AA88004781B0000034000040D5
+:10AE70004399010004002242E66D000058003D4362
+:10AE800085E00100000000F836B00100000000F08D
+:10AE900000B0010004002200803200000400A20083
+:10AEA000BE06000028000040839801005497004728
+:10AEB00061310100238300881CB0000000002D03D5
+:10AEC00048B1010008002DF094B00100000000F826
+:10AED0008EB0010090002DF014B0010000000005BC
+:10AEE00048B10100A88CA2408F7C0000DE8D224773
+:10AEF0008F7C00000400A248197C0000A88C004848
+:10AF000019900000040022468F7C0000608E0040F3
+:10AF100081B200000400A205486D000036002D5DDE
+:10AF200005B4010037002DF380B00100000000F3EC
+:10AF30008EB00100F00000477E8901000400264029
+:10AF4000813200005C003D4381E00100A8002DF04B
+:10AF500094B001000400224A80320000000000F09A
+:10AF600024B001002000001086DC010040800003B6
+:10AF700044C901009293004AF03101000400A25C30
+:10AF80001F7C000036002F5C1F900100F28DA25044
+:10AF90008F50000034002040E1B10100E08B004000
+:10AFA00081B20000F00000477E89010004002640C5
+:10AFB000813200000000634181C00100F78DA04391
+:10AFC000816C00000000634081B001003700204721
+:10AFD000E6B10100E08B2247803200000400004708
+:10AFE0000CF401000000004F8F8401000C8E2247FA
+:10AFF0000C6C000058003D4381E001000C8E1FF0F6
+:10B00000246C00000000005C1F8001000080001024
+:10B0100042C90100058E2240E36D0000000000459A
+:10B0200061B101004000001062DD0100028EA84005
+:10B0300081320000238300881CB00000058E42404E
+:10B0400005300000000000449393010000001A5DE9
+:10B05000699301000A8E23410D6C0000E08D00050C
+:10B0600048B100008E98000548310100AA880048C8
+:10B0700081B00000E08B22408F6C00008697005F5B
+:10B0800081300100E08B004081B200004002000CE2
+:10B090007E8901000400A64081320000A200004029
+:10B0A00043990100000000F384B00100A6002D497F
+:10B0B00019900100020000F280F40100B8002D4058
+:10B0C00081B20100000000F280C0010000000040D9
+:10B0D00082F8010019000040819801001D8EA040F7
+:10B0E000826C00002C010040819801001D8EA3405D
+:10B0F000826C00000000004180B001001F8E204CD7
+:10B10000856C00000000004185C0010086002040E1
+:10B11000E4B10100A2002042E6B10100E08B004052
+:10B1200081B200000F97005081300100E08B004099
+:10B1300081B200000480000342C90100040022F033
+:10B1400080300000000000408DB001007F9800407A
+:10B15000873001000400A25C1F7C0000B0002F5C5F
+:10B160001F900100000060F080C001007C000040E2
+:10B17000439901000400A3F0806C00008697005FF3
+:10B1800081300100E08B004081B2000004000040EB
+:10B1900081B20000E08B2246197C0000A000004034
+:10B1A00047990100010062F296CC0100E08BA640B5
+:10B1B000813200008697004A813001005B9700468B
+:10B1C00095300100E08B004081B20000E08B224905
+:10B1D000197C00008600004047990100010062F2DE
+:10B1E00080CC0100E08BA640813200008697004AA7
+:10B1F000813001005B97004795300100E08B0040F3
+:10B2000081B2000031940040813201000400A25C50
+:10B210001F7C0000E08B005C1F9000000400A24631
+:10B22000197C0000E08B004081B200000400A249BC
+:10B23000197C0000E08B004081B20000BA000040A1
+:10B2400047990100010062F280C80100498E9040D8
+:10B2500080320000FFFF624081980100A40000409E
+:10B2600047990100E08B2240E56D0000E08B004132
+:10B27000E5C100000F97004D81300100E08B0040D8
+:10B2800081B200005C00004047990100040022F0F8
+:10B290009630000000000040E1B101000080000392
+:10B2A00044C901000000004BE0B101000000004073
+:10B2B0008DB001007F980040873001008B00004076
+:10B2C00047990100598E80F396300000000000403D
+:10B2D000E781010000000047199001000400A25C12
+:10B2E0001F7C0000E08B005C1F90000037000040D6
+:10B2F000439901000400A2F38032000034000040B2
+:10B300004599010001000040F5990100001100403D
+:10B31000E5990100BF94004081320100718EA208BE
+:10B32000803200003700004047990100000000F320
+:10B3300082B001000000635183D00100340000405E
+:10B3400047990100010063F384CC0100698E9F429C
+:10B35000803200000000634285B00100000000451B
+:10B3600003F001000000000100C001006B8E375C9B
+:10B37000613100000000001B62B101006C8EA84B1F
+:10B38000191000000000000062B101006E8EA8409C
+:10B3900081320000F087174081B200000080000376
+:10B3A00042C9010090002DF094B00100AC002DF0D6
+:10B3B00030B0010035002DF028B0010034002DF32D
+:10B3C00084B00100040022F3846C000058003E4366
+:10B3D00085E0010001000018F0C901000000004AEA
+:10B3E000E0B1010038002000E0B101003C00201B6A
+:10B3F000E0B1010040002040E1B101000000004048
+:10B400002BB001006A9700400D30010000000018C9
+:10B4100016C00100828EA0141644000000000041F6
+:10B4200017C001000E0000A244C90100000000186E
+:10B43000F8B10100B0002D14F8B101001050004027
+:10B44000879801008B8E224A197C0000003000434F
+:10B4500086C801000030000B16C801008B8EA44086
+:10B46000813200000000004117C0010001006E435E
+:10B4700086980100AE970030813001008F8EA04188
+:10B48000174000000000004117C00100968E224ABC
+:10B49000197C0000080000A244C90100CC002DABBB
+:10B4A000F9B10100000000AB17C00100958EA0F0BB
+:10B4B000164400000000004117C00100000064F0C5
+:10B4C00082B00100900000404599010000006041F9
+:10B4D00031C00100BC000040439901009C8E060C65
+:10B4E00080320000A00020F2E4B10100040009460F
+:10B4F000191000009C01004045990100FFFF000B5E
+:10B50000988801008B002D5017F00100A18E904CFF
+:10B51000164000000000004117C00100A38E224326
+:10B52000E77D00000000004445C1010000006620E6
+:10B5300017A4010068010040439901005C012EF24C
+:10B5400080B00100020062407ECD01000000005783
+:10B5500081C0010000002E1048B10100030000402E
+:10B56000F08D010000000008F0B101005801000555
+:10B57000E0C901000000004461B1010000000010BA
+:10B5800062B10100AD8EA8408132000023830088A3
+:10B590001CB000000000000548B10100B18E454814
+:10B5A000613100000050000862DD0100B28EA84049
+:10B5B0000530000035001D4047990100010063F38C
+:10B5C00084C80100B88EA043856C00000000634071
+:10B5D00085B001003700004047990100040022F3C4
+:10B5E0009E060000010063F382CC01000400A2412A
+:10B5F0009E0600008B000040479901000400A24510
+:10B60000E77D000000000045E79101008697005F9C
+:10B6100081300100E08B004081B200003700004023
+:10B6200047990100959500F394300100608E224AFD
+:10B6300080320000D18C004081B200003700004011
+:10B6400047990100959500F3943001009A8C224AA5
+:10B6500080320000D18C004081B2000036000040F2
+:10B6600043990100000000FB12B001000F0000F33D
+:10B6700090880100040000F30CF40100040026404F
+:10B6800081320000CB8C2206906C00000400AA409E
+:10B69000813200005C003D4313E00100A8002DF062
+:10B6A00094B0010004002240956C000037002FF098
+:10B6B00024B0010036002A50E7D1010000006341A8
+:10B6C00013C00100D88EA043136C0000000000409E
+:10B6D000E7B101008F9300108630010023830088BA
+:10B6E0001CB00000DA8E4205483100000000004422
+:10B6F00093930100CB8C1A5D699300000400A205AE
+:10B70000486D000036002D1086B001005C003D43FE
+:10B71000E7E10100A8002DF094B001000400224AE6
+:10B720008032000035002FF024B0010001006BFBD7
+:10B7300084C80100E78EA043856C000035002040DE
+:10B74000E7B101000000004081B20100010063F395
+:10B7500012C80100EA8EA043136C000000000040F4
+:10B76000E7B101004080000344C901009293004A00
+:10B77000F0310100238300881CB00000ED8E4205EB
+:10B7800048310000000000449393010000001A5D5E
+:10B79000699301003700004047990100040022F33B
+:10B7A0009E060000110063F382CC010004001F41DB
+:10B7B00080320000C28D22419E060000350000400C
+:10B7C0004399010058003D43E7E10100000000F803
+:10B7D00036B00100D08D00F000B000005E012D05F4
+:10B7E00048B10100FA8E65F21230000000993F4224
+:10B7F00013F00100FF8E2247E77D00002783758844
+:10B800001CB00000F98E004081B20000000000472B
+:10B81000E791010000007542199001007500004099
+:10B8200061990100018FA8B10C300000A9960010A9
+:10B8300094300100238300881CB000005E012E05B7
+:10B8400048B10100C0A83D460DE0010000000040E5
+:10B8500097B001000B8F2240E16D0000040002410F
+:10B8600097400000088F005043C10000178F224B03
+:10B87000803200000000624B1294010009000007B2
+:10B8800096E40100000000A797C0010030000010FE
+:10B8900094C801000080004A449901000000004261
+:10B8A000F1B101005E01004BF0C901005E0100052D
+:10B8B000E0C901000000004461B101002000004A1D
+:10B8C00062DD0100158FA840813200000080001069
+:10B8D00044C9010000000050F1B10100040000095A
+:10B8E00096E40100000068A897C00100D40000059C
+:10B8F000E0C901000000004461B101000000001037
+:10B9000062B101001D8FA8408132000023830088AE
+:10B910001CB0000000993F4213F00100218F6540E8
+:10B92000813200003F0000F39688010000000040D3
+:10B93000E7B101000000755561B10100000000068B
+:10B9400062B10100258FA840813200002A8F224B6E
+:10B95000803200000000004B62B10100288FA84037
+:10B96000813200000000009713B001000000009633
+:10B9700097B00100308F2009966C0000308F1F09AE
+:10B9800096240000278300881CB000002B8F004005
+:10B9900081B200000F97005781300100C98B00056C
+:10B9A00048B1000004002242197C00002E00004033
+:10B9B00043990100378F22F3803200000F97004235
+:10B9C00081300100F087004081B20000869700526C
+:10B9D00081300100C98B004219800000040022421E
+:10B9E000197C00000F97003A8130010086970052C1
+:10B9F00081300100C98B004081B20000000000408E
+:10BA000005B001000596004095300100C98B224029
+:10BA1000956C0000240400408998010009990000F9
+:10BA20008A300100458FA2401F7C0000C99400406D
+:10BA300081320100F087004081B2000004800003E1
+:10BA400042C90100000000F202B00100A5950052B9
+:10BA500095300100AC95004B02B00000F08700402B
+:10BA600081B200002B98004095300100518FA20850
+:10BA700080320000518FA21680320000F0872242EF
+:10BA8000197C00000000004B199001000F97003A4C
+:10BA900081300100F087004081B20000002300A641
+:10BAA00016B00100548F831E803200000008000B86
+:10BAB00016DC0100000000002AC001005E970008AB
+:10BAC00080300100588F005E179000007F97004380
+:10BAD000613101009E9300408D30010066970007A0
+:10BAE000161401000080001042C90100608F22403E
+:10BAF000E36D00000000004361B101004000001050
+:10BB000062DD01005D8FA840813200002383008840
+:10BB10001CB000000097005E05100100C9940040B1
+:10BB200081320100648F2209803000008697004036
+:10BB300013300100D08B000548B100003C96004056
+:10BB400081320100C98B004081B200000400A24A8A
+:10BB50001F7C00000000004A1F9001006C8F2243F0
+:10BB60003D7C0000000000441990010000000043EB
+:10BB70003D8001006D8F0042199000000400A24F2B
+:10BB80002B7C00000400A2451F7C000014002D4502
+:10BB90001F9001000400A2F0146C00000400A0013A
+:10BBA000146C0000DF8F831E80320000DF8F0044A2
+:10BBB000199000002F000040439901000400A247A3
+:10BBC000E77D0000B494004081320100878FA20815
+:10BBD00080320000878FA21680320000838FA2423D
+:10BBE000197C00000082000204DC0100A0980040E3
+:10BBF000479901003005004189300100808FA24142
+:10BC0000197C0000C994004081320100F087004097
+:10BC100081B20000A595001594300100AC95004B51
+:10BC200002B00000F087004081B200003C96004066
+:10BC3000813201000000004B199001000F97003A7B
+:10BC400081300100F087004081B200008A8F2242DB
+:10BC5000197C00003C960040813201008B8F00402F
+:10BC600081B200000596004081320100C38F22415D
+:10BC7000197C0000C000001598C80100C38FA00BFC
+:10BC8000996C0000040022441F7C0000FF070000A4
+:10BC90007E8901000400A6408132000030000010BF
+:10BCA00080C801000080004044990100000000505D
+:10BCB000F1B1010000000003F0B1010000000042FA
+:10BCC00061B101000000004062B10100968FA80040
+:10BCD000E0310000238300881CB000000000000554
+:10BCE00048B10100C000001598C8010030002E0BBB
+:10BCF00099D0010000006A5099C001000400200B97
+:10BD0000996C0000C000620180CC01000C8000032F
+:10BD100042C901002D002DF022B001000000004CAE
+:10BD200080C001000000005C23800100D4003F417E
+:10BD3000E7E1010004002242197C00000B0000F240
+:10BD400098E401000000005A998001000400A2005C
+:10BD5000986C0000200400408998010009990011A6
+:10BD60008A3001000B000011E4F501002F0020478C
+:10BD7000E7B50100AE8F230B816C00000000004F7F
+:10BD8000E59101000000000880B00100C100000141
+:10BD900080CE01000400A440813200000000000BAE
+:10BDA00003B001000000001502D001005E97000002
+:10BDB0002A4001000000004361B101004000001072
+:10BDC00062DD0100B58FA840813200002383008826
+:10BDD0001CB00000C994000548310100C0000001FA
+:10BDE00080CE0100C18F261100300000100000003D
+:10BDF0002AC801000000000880B001000000000116
+:10BE000080C00100C00000409998010000000001BE
+:10BE100098D001005E97004C02300100C000004045
+:10BE200003980100CB8F004081B2000030002F0842
+:10BE300080B00100C0000015F4C90100C00000017D
+:10BE4000E4CD0100C100000180CE01000400A44047
+:10BE5000813200000400200BE56D0000C0000040AE
+:10BE6000039801005E9700002A400100D08F224411
+:10BE70001F7C0000AC002F4013B001000000000147
+:10BE8000E0C10100B000004047990100D18F0001DE
+:10BE9000E0D100009E9300408D300100806300A639
+:10BEA00016B001006697000716140100008000100C
+:10BEB00042C90100D98F2240E36D00000000004319
+:10BEC00061B101004000001062DD0100D68FA84082
+:10BED00081320000238300881CB000000097005EC0
+:10BEE00005100100DC8F2209803000008697004099
+:10BEF00081320100C98B000548B100000400A24A4C
+:10BF00001F7C0000DF8F004A1F9000000400A24F3A
+:10BF10002B7C00000400A25C1F7C00000400A244F3
+:10BF20001F7C00000000000010B0010024002D154F
+:10BF300010C0010028002DF016B0010022002DF0E5
+:10BF400026B0010014002FF20CB001000000000127
+:10BF5000E0D101000000001032B001000000000B31
+:10BF60001BB0010004001F151A5000000000004023
+:10BF700023B00100000000012AB00100BE9600407D
+:10BF800035B000002F002040E7B101002990A24504
+:10BF90001F7C00000400A205486D00002400200B57
+:10BFA000E0B1010028002013E0B1010022002006CA
+:10BFB000E4B10100FD8F225C1F7C00000000005CEA
+:10BFC0001F8001003080001042C90100FD8F224017
+:10BFD000E36D00000000004761B101004000001067
+:10BFE00062DD0100F98FA8408132000023830088C0
+:10BFF0001CB000000000000548B101001400004022
+:10C00000439901000400A2F0146C000000800019A4
+:10C0100042C9010022902240E36D000010902242AC
+:10C02000197C000073960040813201005A94004050
+:10C03000813201001D90224B80320000000000433D
+:10C0400061B101004000001062DD01000690A840CF
+:10C0500081320000238300881CB000000C90224134
+:10C06000197C0000E7940040113001000D9000059C
+:10C0700048B10000C9940040813201000F902209AC
+:10C080008030000086970040813201002F830040FD
+:10C0900005B0000073960040813201004F940040CB
+:10C0A000813201000000004361B101004000001036
+:10C0B00062DD01001390A8408132000023830088D4
+:10C0C0001CB0000019902241197C0000E794004048
+:10C0D000113001001A90000548B10000C9940040D9
+:10C0E000813201001C9022098030000086970040B8
+:10C0F000813201002F83004005B0000000000043A2
+:10C1000061B101004000001062DD01001E90A840F6
+:10C1100081320000238300881CB00000000000056D
+:10C1200048B1010025902241197C0000E7940040AD
+:10C13000113001002690000548B10000C99400406C
+:10C14000813201002890220980300000869700404B
+:10C1500013300100D08B004005B0000014000040F7
+:10C16000439901000400A2F0146C00000080001943
+:10C1700042C9010032902240E36D000000000043FC
+:10C1800061B101004000001062DD01002E90A84066
+:10C1900081320000238300881CB0000000000005ED
+:10C1A00048B101000000004005B001003690224176
+:10C1B000197C0000E7940040113001003790000521
+:10C1C00048B10000C99400408132010008002D0AE6
+:10C1D00084B00100000000F082B00100040026409D
+:10C1E0008132000014002040E1B101003D90031EA7
+:10C1F000803200003E90004187B0000021000040E6
+:10C20000879801002C960040813201000400A25C56
+:10C210001F7C00000000005C1F9001004390220979
+:10C220008030000086970040133001004690224481
+:10C23000197C00008697004F813001000000004407
+:10C2400019800100C98BA24A1F7C0000D08B0040DE
+:10C2500081B200000400A205486D0000BA00204031
+:10C26000E5B101004E909C17803200000400224A84
+:10C27000197C0000CC000040439901003698004032
+:10C2800081320100D497004013300100C00000400B
+:10C2900043990100C4002DF082B001000B9800F01A
+:10C2A00084300100C994004081320100D08B220902
+:10C2B000803000008697004013300100D08B004092
+:10C2C00081B200002E000040439901005A902240A4
+:10C2D000E76D000032000040439901006590A240E4
+:10C2E000E56D0000F2950040813201002400200B32
+:10C2F000E0B1010028002013E0B101002200200677
+:10C30000E4B1010004002242197C00001400004046
+:10C31000439901000400A2F0803200001400200ABA
+:10C32000E0B10100D08B22098030000086970040E8
+:10C3300013300100D08B004081B20000F295004024
+:10C34000813201009D9500408132010073902241AD
+:10C35000197C00000000000B99B0010004001F15BB
+:10C360009850000073902001986C0000700000034A
+:10C3700048C9010000002E461F9001000000005037
+:10C38000F1B1010000000003F0B101000000004223
+:10C3900061B10100A00000A462DD01007090A8005E
+:10C3A000E03100000000000548B10100AC002F00A2
+:10C3B00010B0010000000001E0C1010014002F15C1
+:10C3C00010C001000400A2F0803200000000000A4A
+:10C3D00080B001000000600180D001000000004733
+:10C3E00019900100E98F2209803200008697000928
+:10C3F00080300100E98F004013B00000008000038E
+:10C4000042C90100000000F082B0010013000040AA
+:10C41000879801000000004C43C101002C9600F0F9
+:10C42000843001000400A25C1F7C0000C98B005C0A
+:10C430001F9000002C002040E7B101002D0020409B
+:10C44000E7B101002E000040439901000400A2F36F
+:10C450008032000004002242197C0000C98B004297
+:10C46000198000001C960040813201005B97004853
+:10C47000953001000000004561B10100400000104E
+:10C4800062DD01008D90A8401330000023830088F6
+:10C490001CB000009390000548B10000929000404D
+:10C4A00013B000000000000012B0010008000040BE
+:10C4B0004399010014002DF082B0010004002640D1
+:10C4C00081320000040022F084300000130000409C
+:10C4D000879801002C960040813201000400A25C84
+:10C4E0001F7C00000000005C1F900100B09000095C
+:10C4F00000B000000400A205486D0000C98B87420F
+:10C50000191000008B002F4719800100C98B0040D3
+:10C51000E79100000400A2401F7C00002F000040B3
+:10C5200047990100AE902247E77D000004002241B8
+:10C53000197C00001D940040E7310100AE902200FC
+:10C5400080320000A990A2401F7C0000C9940040E6
+:10C5500081320100AE90004081B200003000004006
+:10C560004399010032002DF294B00100A59500F22C
+:10C5700002300100AC95004B02B000000000000545
+:10C5800048B10100AF90004001B000000000004041
+:10C5900005B00100B590220080320000B490A242A4
+:10C5A000197C00000596004081320100B5900040E2
+:10C5B00081B200003C960040813201005491225C1F
+:10C5C0001F7C00000000005C1F8001000080001044
+:10C5D00042C90100BD902240E36D0000000000450B
+:10C5E00061B101004000001062DD0100BA90A84076
+:10C5F00081320000238300881CB0000054910005A4
+:10C6000048B10000B494004081320100C490A208F7
+:10C6100080320000C490A216803200000F97004DB7
+:10C62000813001000082000204DC0100F08700403C
+:10C6300081B200007400004043990100000000F83E
+:10C6400082B00100000000F084B001000000004151
+:10C6500096B00100D5902242961400000080001090
+:10C6600044C9010064006840979801006400004BD1
+:10C6700080CE01000400A64081320000000000418D
+:10C68000F0B1010000000042F0B1010070000005AF
+:10C69000E0C901000000004561B101002000001068
+:10C6A00062DD0100D190A840813200000400A25C4C
+:10C6B0001F7C00000000005C1F900100000000458E
+:10C6C00061B101004000001062DD0100D690A85C5D
+:10C6D0001F000000238300881CB000005E012D05B0
+:10C6E00048B10100DA9065F21230000000993F4233
+:10C6F00013F00100DF902247E77D00002783758853
+:10C700001CB00000D990004081B20000000000473A
+:10C71000E79101000400750996E401000080001013
+:10C7200044C9010000000044F1B10100000068A804
+:10C7300097C0010000000003E0B101000080000389
+:10C74000449901000000004461B1010000000010A4
+:10C7500062B10100E790A840E13100002383008826
+:10C760001CB0000000993F4213F00100EB906505FA
+:10C77000483100003F0000F39688010000000040AF
+:10C78000E7B101000000754081B20100F390224B37
+:10C79000803200000000005561B101000000004B34
+:10C7A00062B10100F190A840813200000000000752
+:10C7B00016B001000062000B16DC01002F000040E3
+:10C7C000439901000400A247E77D00001D9400404A
+:10C7D0008132010010912200803200004E96005FED
+:10C7E00001100100F7902240956C000004002241E6
+:10C7F000197C0000040022401F7C00000080001013
+:10C8000044C9010000000050F1B101000000000324
+:10C81000F0B101000000004261B101000000001011
+:10C8200062B101000191A800E0310000238300887B
+:10C830001CB000000000000548B1010004800003A6
+:10C8400042C90100000000F202B0010004002031E2
+:10C85000036C0000A595005295300100C99400407A
+:10C8600081320100F7902241975000000C800003B4
+:10C8700042C90100000000F000B001000000005CAF
+:10C8800001800100AC95004B02B00000F79000055C
+:10C8900048B1000066970040033001001780000394
+:10C8A00044C9010000F0000C968801000000634CB0
+:10C8B00097F001000400204D976C00000400224016
+:10C8C000976C00001080000344C90100000000AB19
+:10C8D000E1B101000097005E0510010003000007B0
+:10C8E0001AF40100070000071688010000B5000DCA
+:10C8F00046C901001C913040813200000400220B27
+:10C90000E67D00000000000BE681010000B7000D8D
+:10C9100046C901000400220BE67D00000000000B68
+:10C92000E68101001000100F94F401009304005FF1
+:10C930009504010076950040813201002A91225031
+:10C94000FD7F000026914640813200002991A240DF
+:10C95000316F000004001E4081B2000000001E4143
+:10C9600031D3010000002E0548B101000000004055
+:10C97000E1B10100000000400FB00100AB940041A4
+:10C9800081300100F087004081B20000B494004083
+:10C99000813201003D91A208803200003D91A21633
+:10C9A000803200000082000204DC0100000000452B
+:10C9B00003F001000000000100C001003591375C68
+:10C9C000613100000000001B62B101003A91284073
+:10C9D000813200000400A25C777D000036910040A7
+:10C9E00081B200000000000062B101003A91A8404D
+:10C9F00081320000F087174081B2000074002240AD
+:10CA0000F1B1010000000040E1B101005B97004A74
+:10CA1000953001000400A25C1F7C00001C96005CA5
+:10CA20001F100100C490004081B200000400A24029
+:10CA30001F7C00002F0000404799010051912247C0
+:10CA4000E77D000004002241197C00001D94004095
+:10CA5000E731010051912200803200004C91A24048
+:10CA60001F7C0000C99400408132010051910040B8
+:10CA700081B20000300000404399010032002DF2E5
+:10CA800094B00100A59500F202300100AC95004B76
+:10CA900002B000000000000548B101005B970048AB
+:10CAA000953001000400A25C1F7C00001C96005C15
+:10CAB0001F1001000400A205486D00005891874234
+:10CAC000191000008B002F47198001000000004062
+:10CAD000E79101008697004281300100C98B004038
+:10CAE00081B200001C960040813201000400A25C6B
+:10CAF0001F7C0000C98B005C1F900000B00000404C
+:10CB0000439901000400A2F080320000BA002040E6
+:10CB1000E5B10100D497004081320100C00000401F
+:10CB200043990100C4002DF082B001000B9800F081
+:10CB300084300100C994004081320100869700458D
+:10CB400081300100C98B2242197C00000F97003A06
+:10CB500081300100C98B004081B200000400004018
+:10CB600081B20000B4940040813201007091A208AB
+:10CB7000803200007091A216803200000F970047AB
+:10CB8000803001000082000204DC0100F0870040D8
+:10CB900081B200001080000344C9010000E100A63A
+:10CBA00084B0010000000040F1B10100000000402D
+:10CBB000F1B1010000006007849401000097005E5D
+:10CBC00005100100C98B004081B200008A000040BE
+:10CBD00047990100C9940041E7410100D08B004012
+:10CBE00081B200000400A205486D00000400A241CB
+:10CBF000197C00000400A2481F7C0000F295004050
+:10CC0000813201000400A30A0C6C00009D950040D5
+:10CC100081320100000000012CB00100000000156D
+:10CC200010B001000000000010C0010004001F0A45
+:10CC30002C50000014000040439901000400A2F0B1
+:10CC4000803200000000001032B00100A197000601
+:10CC5000043001008E91A2481F7C00008C91844812
+:10CC60001F100000AC000040479901008E91000A9F
+:10CC7000E0C100000000000A02B001009E93000124
+:10CC80008C3001000000004361B101004000001041
+:10CC900062DD01008F91A84081320000238300886B
+:10CCA0001CB000000000000548B1010000000002B7
+:10CCB00010C001009C91220214500000799600459A
+:10CCC0001F0001008691225C1F7C000000000047CD
+:10CCD00061B101004000001062DD01009891A85C84
+:10CCE0001F000000238300881CB00000869100050F
+:10CCF00048B100000000000B1BB0010008002D40EF
+:10CD000085B00100000000F082B00100000000408A
+:10CD100005B001002C96004187300100000000455D
+:10CD200061B101004000001062DD0100A291A84045
+:10CD300081320000238300881CB000000000000541
+:10CD400048B10100A8912209803000008697004078
+:10CD500013300100AC912244197C00008697004FEB
+:10CD600081300100AC91A2471F7C0000000000440C
+:10CD700019800100FF070008008C01000400264014
+:10CD800081320000BB91224A1F7C0000B391A216A1
+:10CD900002300000C9940040813201002F00204081
+:10CDA000E7B10100C98B004081B200002D002D08C1
+:10CDB0002AB00100B7912242197C00003C96004045
+:10CDC00081320100B891004081B200000596004018
+:10CDD0008132010030002E002AD0010032002A15D5
+:10CDE000E4B10100C98B0016E4B10000D191221614
+:10CDF000023000000400A2471F7C00000000000871
+:10CE00002AB001002B98004095300100C191A2404A
+:10CE1000116C0000D29122402D6C00000400A2058C
+:10CE2000486D0000040022441F7C0000AC0000405C
+:10CE300047990100B0002B01E0C10100002B00A6C2
+:10CE400016B0010000000001E0D101005E9700086B
+:10CE500080300100CA91005E179000007F97004368
+:10CE6000613101000000004361B101004000001089
+:10CE700062DD0100CB91A84081320000238300884D
+:10CE80001CB000000000000548B1010066970007D3
+:10CE9000161401000097005E05100100C9940040BF
+:10CEA000813201002F002040E7B10100D08B00400B
+:10CEB00081B200000000000B1BB0010004001F1530
+:10CEC0001A500000E09120161A6C00000400224065
+:10CED0001F7C00007000000348C9010000002250C0
+:10CEE000F1B1010000000003F0B1010000000000FA
+:10CEF000E0B101000000004261B10100A00000A407
+:10CF000062DD0100DD91A8461F1000000000000551
+:10CF100048B101000000000010B001000000001541
+:10CF200010C001000000000A2AB001000000000A41
+:10CF30002CD0010004001F168032000014000040B5
+:10CF4000439901000400A2F080320000AC002F40A1
+:10CF500023B00100EA9184451F100000EB91000A04
+:10CF6000E0C100000000000A02B00100BE960040CF
+:10CF700035B000000400A25C1F7C00000080001996
+:10CF800042C90100F4912240E36D0000000000431B
+:10CF900061B101004000001062DD0100F091A84085
+:10CFA00081320000238300881CB0000000000005CF
+:10CFB00048B101000592A2021A5000000A922240D4
+:10CFC0002D6C0000040022401F7C00000080001037
+:10CFD00044C9010000000050F1B10100000000034D
+:10CFE000F0B10100FF070008E08D010000000042E1
+:10CFF00061B101000000001062B10100FC91A84085
+:10D0000081320000238300881CB00000000000056E
+:10D0100048B101002F002047E7B501000C80000354
+:10D0200042C90100100000F010C80100F0070040E4
+:10D030001B9801000A92005C118000000400A25FAE
+:10D040001B7C0000FF070008988801000000000218
+:10D0500098C001000400200B996C00000000000241
+:10D0600010C0010004002240236C00000400A34310
+:10D07000236C0000E79400401F0001000000000541
+:10D0800048B101001092230D2C6C000000000040FC
+:10D090001F900100199222461F7C000000000046EC
+:10D0A0001F8001007080000342C9010019922240D4
+:10D0B000E36D00000000004261B10100400000107B
+:10D0C00062DD01001592A8408132000023830088B0
+:10D0D0001CB000000000000548B1010008002D4010
+:10D0E00085B00100000000F082B0010000000040A7
+:10D0F00005B001002C96004187300100000000457A
+:10D1000061B101004000001062DD01001E92A840E4
+:10D1100081320000238300881CB00000000000055D
+:10D1200048B1010024922209803000008697004017
+:10D130001330010028922244197C00008697004F8A
+:10D14000813001002892A2471F7C000000000044AB
+:10D1500019800100FF070008008C01000400264030
+:10D16000813200003E92224A1F7C00002F92A216BC
+:10D1700002300000C9940040813201002F0020409D
+:10D18000E7B10100C98B004081B200002D002D08DD
+:10D190002AB001003A922242197C00003392A2F395
+:10D1A00084300000000000A585B0010000000041AF
+:10D1B00085D00100D4003E4185E001003792224035
+:10D1C0001F7C00000000005A119001000B000008B5
+:10D1D000E4F501003C960040813201003B920040A2
+:10D1E00081B20000059600408132010030002E001F
+:10D1F0002AD0010032002A15E4B10100C98B0016C3
+:10D20000E4B100004192A21602300000C99400402F
+:10D21000813201009A92004081B200002D002D0859
+:10D220002AB00100549222471F7C00000400A09104
+:10D23000036C00004E922242197C00004792A2F338
+:10D2400084300000000000A585B00100000000410E
+:10D2500085D00100D4003E4185E001004B92224080
+:10D260001F7C00000000005A119001000B00000814
+:10D27000E4F50100200400408998010009990008A4
+:10D280008A30010058012D002AD0010060012DF0E4
+:10D2900010B00100000000F02CB0010000000016EA
+:10D2A00080B2010004002740116C0000878F00400D
+:10D2B00081B200000400A391036C00002B98004190
+:10D2C000953001005D92A208803200005D92A216A6
+:10D2D000803200000000004197B001005B92230DF6
+:10D2E000026C00000000004197C00100AC95004BAB
+:10D2F00002B000009A92000548B100000400A205A7
+:10D30000486D0000040022441F7C0000AC002F0187
+:10D3100014B00100B0002B01E0C10100002B00A6F9
+:10D3200016B0010004002241197C00000000000139
+:10D33000E0D101007092230D026C0000008000100B
+:10D3400044C9010000000050F1B1010000000003D9
+:10D35000F0B101000000004261B1010000000010C6
+:10D3600062B101006992A800E031000023830088C7
+:10D370001CB000000000000548B101000C80000353
+:10D3800042C90100100000F022C801000000005C4A
+:10D39000238001000000000184B001007392230D7E
+:10D3A000026C00000000000D02B001000000000847
+:10D3B00080B00100789222401B6C00005E97000153
+:10D3C0008450010081922240856C00000000000121
+:10D3D00080C001001080001046C901000000004F0D
+:10D3E0004381010000000042F0B101002000004034
+:10D3F000F0C9010000000016F0B101000000004378
+:10D4000061B10100A00000A162DD01007E92A811BF
+:10D41000E031000004002240236C00009092005E86
+:10D42000179000008492230D026C00000000000D94
+:10D4300002B001000000000184D001008992224066
+:10D440001B6C00007F9700436131010090922240E5
+:10D45000856C00000000000112C001001080001067
+:10D4600046C901000000004F438101000000004256
+:10D47000F0B1010000000009F0B101000000001847
+:10D48000F0B10100A00000A162DD01008E92A811A0
+:10D49000E03100000000004361B1010040000010D5
+:10D4A00062DD01009192A80A023000002383008807
+:10D4B0001CB00000C9940005483101009892230D6A
+:10D4C000026C0000FF070011008C0100C9940040AD
+:10D4D0008132010066970007161401000097005E74
+:10D4E000051001002F002040E7B10100D08B004063
+:10D4F00081B200000080000342C90100000000F872
+:10D5000082B001000400264081320000000000F8D3
+:10D510008CB00100000000F08EB00100EC950040DE
+:10D520001330010004000C4780320000000000406E
+:10D5300085B001002C960041873001009D95004088
+:10D540008132010004002091036C00000080001073
+:10D5500042C90100AE922240E36D00000000004588
+:10D5600061B101004000001062DD0100AA92A840F4
+:10D5700081320000238300881CB0000000000005F9
+:10D5800048B10100B0922209803000008697004027
+:10D59000133001000000000B1BB00100000000155B
+:10D5A0001AD00100B792A241197C00002B980040CC
+:10D5B000953001000000001680B20100C0922708DB
+:10D5C00080320000C19100002AC000002B98004169
+:10D5D000953001000000001680B20100BB922708C0
+:10D5E000803200005D9200002AC00000000000416F
+:10D5F00097B00100BE92230D026C000000000041B4
+:10D6000097C00100AC95004B02B00000000000057F
+:10D6100048B10100C98B2242197C00000F97003AE3
+:10D6200081300100C98B004081B200000400A24A91
+:10D630001F7C0000C592004A1F9000000400A24118
+:10D64000197C00000400A24F2B7C00000400A244BF
+:10D650001F7C00000400A2451F7C0000FF94000016
+:10D66000103001000000001510C001000000001083
+:10D6700032B00100A197000604300100D292A2440A
+:10D680001F7C00000000000B1BB001000000000A1E
+:10D690002CD001000000000A02B001009E9300019E
+:10D6A0008C3001000080001942C90100D99222404B
+:10D6B000E36D00000000004361B101004000001074
+:10D6C00062DD0100D592A8408132000023830088EA
+:10D6D0001CB000000000000548B10100000000027D
+:10D6E00010C00100E2922202145000007996004519
+:10D6F0001F000100CB92225C1F7C0000000000474D
+:10D7000061B101004000001062DD0100DE92A85C02
+:10D710001F000000238300881CB00000CB9200058E
+:10D7200048B1000008002D4085B00100000000F065
+:10D7300082B001000000004005B001002C960041BD
+:10D74000873001000000004561B101004000001079
+:10D7500062DD0100E792A840813200002383008847
+:10D760001CB000000000000548B10100ED92220944
+:10D77000803000008697004013300100F092224470
+:10D78000197C00008697004F8130010000000044A2
+:10D7900019800100FF070008008C010004002640EA
+:10D7A00081320000FF92224A1F7C0000F792A216ED
+:10D7B00002300000C9940040813201002F00204057
+:10D7C000E7B10100C98B004081B200002D002D0897
+:10D7D0002AB00100FB922242197C00003C960040D6
+:10D7E00081320100FC92004081B2000005960040A9
+:10D7F0008132010030002E002AD0010032002A15AB
+:10D80000E4B10100C98B0016E4B10000BC91A2167E
+:10D8100002300000C9940040813201002F002040F6
+:10D82000E7B10100D08B004081B20000040022412A
+:10D83000197C00000400A24F2B7C00000400A244CD
+:10D840001F7C00000400A2451F7C00000400A24AC7
+:10D850001F7C0000FF94004A1F100100D4910010AB
+:10D8600032B000008A002040E7B101000E93A241CF
+:10D87000197C0000C99400408132010011930040DE
+:10D8800081B20000A595001594300100AC95004BC5
+:10D8900002B000000000000548B1010013932242CD
+:10D8A000197C00000F97003A8130010086970045EF
+:10D8B00081300100C98B004081B2000065900045B5
+:10D8C0001F90000004002241197C00000400A247C0
+:10D8D0001F7C0000F2950040813201000400A30A81
+:10D8E0000C6C00009D95004081320100D491000134
+:10D8F0002CB0000004002241197C00000400A24862
+:10D900001F7C0000B4940040813201002C93A208D7
+:10D91000803200002C93A2168032000000820002A8
+:10D9200004DC01000000004503F0010000000001DC
+:10D9300000C001002493375C613100000000001B2F
+:10D9400062B1010029932840813200000400A25CEA
+:10D95000777D00002593004081B2000000000000A8
+:10D9600062B101002993A84081320000F08717407E
+:10D9700081B2000058012008E0B1010060012016CA
+:10D98000E0B10100F29500471F1001000400A30A56
+:10D990000C6C00009D95004081320100D491000183
+:10D9A0002CB0000004002241197C00000400A247B2
+:10D9B0001F7C0000B49400471F1001004393A2088D
+:10D9C000803200004393A216803200003F93A242AF
+:10D9D000197C00000082000204DC0100A0980040D5
+:10D9E00047990100300500418930010004002241BF
+:10D9F000197C0000A595001594300100AC95004BF2
+:10DA000002B00000F087004081B200003C96004068
+:10DA1000813201000000004B199001000F97003A7D
+:10DA200081300100F087004081B2000058012008D9
+:10DA3000E0B1010060012016E0B101000400A24F36
+:10DA40002B7C00000400A2441F7C00000400A245BF
+:10DA50001F7C0000FF94001032300100D491004080
+:10DA600013B00000B4940040813201005893A20822
+:10DA7000803200005893A21680320000008200021B
+:10DA800004DC01000000004503F00100000000017B
+:10DA900000C001005093375C613100000000001BA2
+:10DAA00062B1010055932840813200000400A25C5D
+:10DAB000777D00005193004081B20000000000001B
+:10DAC00062B101005593A84081320000F0871740F1
+:10DAD00081B200000080000342C90100000000F88C
+:10DAE00082B001000400264081320000000000F8EE
+:10DAF0008CB00100000000F08EB00100EC950040F9
+:10DB00001330010004000C47803200000000004088
+:10DB100085B001002C960041873001009D950040A2
+:10DB2000813201000400A091036C0000008000100D
+:10DB300042C901006A932240E36D000000000045E5
+:10DB400061B101004000001062DD01006693A84051
+:10DB500081320000238300881CB000000000000513
+:10DB600048B10100878F220980300000869700406D
+:10DB700013300100878F004081B200000400831E33
+:10DB8000803200000400A24F2B7C00000400A2455C
+:10DB90001F7C000014002D451F9001000400A2F01E
+:10DBA000146C00000400A001146C0000DF8F00441E
+:10DBB000199000000400A24A1F7C00007893A24143
+:10DBC000197C00000000004A1F9001007A9100407B
+:10DBD00081B200000400A2481F7C0000F295004AB8
+:10DBE0001F1001000400A30A0C6C00009D9500406A
+:10DBF00081320100D49100012CB0000004002241C8
+:10DC0000197C00000400A24F2B7C00000400A244F9
+:10DC10001F7C00000400A2451F7C0000FF94004010
+:10DC200081320100D491001032B000008B0000401E
+:10DC3000439901000400A246E77D0000659000457D
+:10DC40001F9000000000004137C3010000000041A8
+:10DC500033C301003600000102CC01000000D240B5
+:10DC600081B200008C9385178032000000009F482D
+:10DC700003D000008E939C178032000000009F4C60
+:10DC800003D000000000800134C301004080000385
+:10DC900044C901000000004AF0B101000400264020
+:10DCA0008132000000000040F1B1010000000012CC
+:10DCB000F0B10100D1940041E13101000080004346
+:10DCC00044C9010010000040F19901000000004823
+:10DCD000F0B1010000000049F0B101004000000374
+:10DCE000E0C901000000004561B1010000000043EF
+:10DCF00062B101000000A84081B200009B93004087
+:10DD000081B200002D04004089980100099900A506
+:10DD10008A300100BA002040E5B10100B0002F01B7
+:10DD20008CD0010004001FF080320000000000468B
+:10DD3000E0C10100AC002F4013B00100CC002D0168
+:10DD4000E0C10100A9939C17803200000400224A20
+:10DD5000197C00003698004081320100AB932247C5
+:10DD6000197C00000000005F13900100D497004769
+:10DD700019100100C0002D441F900100C4002DF0B7
+:10DD800082B001000B9800F084B0000090002D05D7
+:10DD900048B10100C093A24B1F7C00001594A24C17
+:10DDA0001F7C0000C0931F1CE06D0000C393A20104
+:10DDB00080320000A8002D468FB00100B9931F1CCF
+:10DDC000E06D0000B400004043990100BB9322F0D5
+:10DDD0003A6C000012941FF03A6C00000000A24060
+:10DDE00080B200000000804F8FB001008A00004028
+:10DDF0004399010013942042E76D0000BF93224035
+:10DE000080320000000080598FB00100000080586F
+:10DE10008FB00100C2932240803200000000805C7D
+:10DE20008FB001000000805B8FB00100AC000040AB
+:10DE300043990100B0002DF084B00100C793A242C5
+:10DE4000246C0000D29323F0026C0000B00000A10B
+:10DE500080CE01000400A64081320000CF93A2F0E2
+:10DE6000803200001494A242246C00001494A24159
+:10DE7000036C0000CE93A24080320000000080516D
+:10DE80008FB00100000080528FB0010014941F1267
+:10DE9000845000001494A001846C0000C0930040E2
+:10DEA00081B200008B00004043990100FD93A2461F
+:10DEB000E77D00001400004043990100EF9322F039
+:10DEC00014300000DB93200A026C0000EC93031E68
+:10DED00080320000DA93A2408032000000008044CB
+:10DEE0008FB00100000080498FB00100E093220A4A
+:10DEF000026C0000E393A241197C0000DF93A24072
+:10DF000080320000000080558FB001000000805674
+:10DF10008FB00100E293A2408032000000008043F5
+:10DF20008FB00100000080488FB0010000000001A8
+:10DF300082B001000000000A82D00100E993209124
+:10DF4000836C0000E893A2408032000026008040ED
+:10DF50008F980100270080408F980100EB93A2402A
+:10DF6000803200001F0080408F9801002000804018
+:10DF70008F980100EE93A240803200002200804082
+:10DF80008F980100230080408F98010088002D4465
+:10DF90008FB00100F893A241197C0000F593A243D1
+:10DFA0003D7C0000F593A2F2026C00000000A2404C
+:10DFB00080B20000000080498FB00100F793A240BA
+:10DFC00080320000000080438FB0010000008048D4
+:10DFD0008FB00100F593A091036C0000F3932243EE
+:10DFE0003D7C0000FC93A24080320000280080406D
+:10DFF0008F980100290080408F9801001400004094
+:10E00000439901000694A2F01430000088002D44CA
+:10E010008FB001000394A2F2026C00000000A24045
+:10E0200080B20000000080498FB00100F5932241CA
+:10E03000197C0000F3932091036C0000F5930040DD
+:10E0400081B200000A94200A026C00000994A240E8
+:10E0500080320000000080448FB001000000804941
+:10E060008FB001000F94220A026C0000E393A241DA
+:10E07000197C00000E94A240803200000000805500
+:10E080008FB00100000080568FB001001194A240B3
+:10E0900080320000000080438FB001000000804803
+:10E0A0008FB001001794004395B000001794004111
+:10E0B00095B000001794004295B0000017940044FA
+:10E0C00095B000001794004C95B00000300400405B
+:10E0D000899801000999004A8A3001005B97004045
+:10E0E000813201001C94A240803200000000804B6D
+:10E0F0008FB001000000804C8FB001000400A20529
+:10E10000486D00002D000040439901002E002FF3C0
+:10E1100084B001002294A2F39630000000008040F9
+:10E1200001B001002D002A41E7D10100D4003D419A
+:10E1300085E001000B0000F200E401002894225A5F
+:10E14000017C0000000000401F9001002994005A4B
+:10E1500001800000000000401F80010000006341BA
+:10E1600085C001002C94A0A5856C000000006340D0
+:10E1700085B001001204004089980100099900004F
+:10E180008A3001000000804081B201000000A0A59B
+:10E19000856C01000000E34085B001000C800003A5
+:10E1A00042C9010012000040879801007F9800F0EA
+:10E1B0008CB000000400225F1F7C000041942240CC
+:10E1C0000F6C000000002F0548B101000400225A26
+:10E1D0001F7C0000100000F098F401000400A2076A
+:10E1E000986C00001000000C98F401000400A207D5
+:10E1F000986C00003E94A24B197C00003F9422F0E2
+:10E20000186C00000000604B199001004395000756
+:10E21000103001002F83004005B000004394225AC3
+:10E220001F7C0000AB940040813001002F83004030
+:10E2300005B000000400225F1F7C000000002F05D5
+:10E2400048B101000000604B199001000400225AFF
+:10E250001F7C0000040022400F6C0000100000F042
+:10E2600096F401000400A207966C00001000000C58
+:10E2700096F401000400A207966C00004395000785
+:10E28000103001002F83004005B000000400225F21
+:10E290001F7C000000002F0548B101000000604B0A
+:10E2A000199001000400225A1F7C00000400224043
+:10E2B0000F6C0000100000F096F401000400A207AB
+:10E2C000966C00001000000C96F401000400A207F8
+:10E2D000966C00004395000710300100000080405C
+:10E2E00005B001005A943340813200005D94A1AD25
+:10E2F000952000006F94134081B200000000134A83
+:10E300005A8301003000394595E001000400A25F06
+:10E310005F7C00000400A25E5F7C00001F00000F15
+:10E320005ED801000000005A5F9001000000005E0E
+:10E330005F9001000000004045B0010000000004B3
+:10E3400048B00100000000054AB001000000000CC8
+:10E3500058B00100000000074EB001001C850040CD
+:10E360005D9801000400A2445F7C0000000000589A
+:10E3700061B101000000004A62B101000000A84143
+:10E3800097B000006C94004081B200000000804013
+:10E3900097B001000400A240056C00001C990040E9
+:10E3A000813201007294600796300000FFFF004B3D
+:10E3B00084890100000070C224B001007F94A2454E
+:10E3C000257C000076943120853000008094221254
+:10E3D000487F000058041112480301001000001289
+:10E3E00096E401000000004B1E9401001704004059
+:10E3F00089980100000000128AB001000999005FAD
+:10E400008B1001000000805A1F9001007F94314062
+:10E4100081320000000000B424B001008094221278
+:10E42000487F00005804004081320100170400407A
+:10E4300089980100099900128A30010000002F0517
+:10E4400048B101008F940BF08430000000001112DD
+:10E45000488301008C942250857000005E010040CA
+:10E4600043990100B49600F2963001009304001223
+:10E47000943001000000005A1F90010010000012AB
+:10E4800096E401000000804B1E9401001000004241
+:10E4900010F40100040022088032000000B73F435E
+:10E4A00011F00100070000088A880100939430A150
+:10E4B0000C30000096942245E67D000080941040C8
+:10E4C00081B2000000002A45E69101000000101210
+:10E4D000488301000400A205486D000000001140BF
+:10E4E00081B201000000604B858001005E010040A8
+:10E4F00043990100B49600F29630010000800010AC
+:10E5000044C90100D8000040819801002E002D056B
+:10E5100048B10100A2942240E76D00008000004055
+:10E5200080C8010000000040F0B1010009000008AF
+:10E5300086E40100000068A787C0010000000044D5
+:10E5400061B101000000001062B10100A694A805AD
+:10E55000E03100001000001296E401000014004BAE
+:10E5600096DC01000000804B1E9401000400225A3A
+:10E570001F7C00001000000F84F401001F00004207
+:10E5800084880100B094224080320000B19400429F
+:10E5900068B10000000000426AB10100B194315A34
+:10E5A0001F0000000400A242487F000000009142CA
+:10E5B00048930100B4943540813200006D00004062
+:10E5C00061990100BA9428B12C300000B594224D15
+:10E5D000757D0000000000402DB001000000954056
+:10E5E00011B001006D00004061990100BA94A8B11A
+:10E5F000103000000000001680B20100040027085F
+:10E60000803200000000954081B201007F00004090
+:10E6100061990100C59428B110300000BF949FBAE1
+:10E6200080320000150000408998010009990040DF
+:10E63000813201000000804011B001000400225C22
+:10E64000117C00000400A25A117C00000400220882
+:10E650004806000000008024118401000400A25C30
+:10E66000017C00000400A25A017C0000040022008A
+:10E670004806000004001FBB803200000000005F5D
+:10E6800061B101000010000062DD01000000A8403F
+:10E6900081B20000CE94004081B20000AC940040F2
+:10E6A00047990100D294324081320000DA9422F876
+:10E6B00096300000000000F890B00100000000F06B
+:10E6C00092B001000000004880B201000400274918
+:10E6D000803200000100004BF0CD01002000924884
+:10E6E000E0C901006C00004061990100DE9428B18E
+:10E6F00092300000DA94224C757D00000400124034
+:10E7000091B000006C00004061990100DE94A8B156
+:10E71000903000000000004980B20100040027484A
+:10E7200080320000FF000048968801000000004B86
+:10E7300090D001000100004BF0CD01002000004806
+:10E74000F0C9010000009249E0B101000C002D1059
+:10E7500048B10100FF070008828C01000400A25CA0
+:10E76000837C0000FF0700F0008C01000400A25C25
+:10E77000017C000004002240016C00000000A24166
+:10E7800000EC0000F094221A006C0000C994000014
+:10E79000343001000000005049C10100EA94A24158
+:10E7A000235000000000804081B201000C002D10B9
+:10E7B00048B10100FF070015828C01000400A25C33
+:10E7C000837C0000FF0700F0008C01000400A25CC5
+:10E7D000017C000004002240016C00000000A24106
+:10E7E00000EC0000FC94220D006C0000C9940000B5
+:10E7F0001A3001000000005049C10100F694A24106
+:10E80000235000000000804081B201000195831E6A
+:10E8100080320000000000441990010024002D0106
+:10E820002CB0010028002DF016B0010022002DF0C0
+:10E8300026B0010014002FF20CB001000400A2F079
+:10E84000146C000004002001146C000000008040E3
+:10E85000E1B10100300000409798010060972E4020
+:10E8600081B2010000000040F1B101000A95A2410F
+:10E870009750000064973E439DE0010000008040F7
+:10E88000E1B1010064973E439DE001000000800B70
+:10E89000E8B1010064973F439DE00100000000F0F3
+:10E8A00016C0010000008040E1B1010064973F43C1
+:10E8B0009DE00100000000F416B00100000080405F
+:10E8C000E1B1010060173D439DE00100100080A10F
+:10E8D00016E401000400A207166C00001A040040B0
+:10E8E000899801001000000B8AE401000999000DCD
+:10E8F0008A14010000B5000D42C901001D95304782
+:10E90000170400002095A20BE67D00000000904255
+:10E9100081B0010000B7000D46C901002495A20B8B
+:10E92000E67D00000000000BE69101000000904130
+:10E9300081B001000000104081B201002595400720
+:10E94000963000009D040040813201002F95A245C1
+:10E95000957C000001973F4195E00100000000F325
+:10E9600096B001000000004EE6B1010040973E4025
+:10E9700097E001000000004EE6B1010040973E40E4
+:10E980009DE001004295003BE7B100002F9530402B
+:10E99000813200003995A20BE67D000000B5000D24
+:10E9A00046C901003595A20BE67D0000000010402D
+:10E9B00081B201000000984281B0010000B7000D53
+:10E9C00046C901000000000BE69101000000104064
+:10E9D00081B201000000984181B00100040021A231
+:10E9E000952000000000104A4483010000973E413A
+:10E9F00095E001000000004EF6B101000000004E5D
+:10EA0000E6B1010040973E409DE001000000003B60
+:10EA1000E7B101000000004A90B10100FFFF0007CC
+:10EA2000928901000000984081B00100110400406B
+:10EA300089980100099900088A3001000300000844
+:10EA400086F4010000B7004346C901000700000832
+:10EA50008288010004002208803200000400224164
+:10EA6000E67D00004A954008963000009D04004075
+:10EA70008132010058952245957C00005395225A19
+:10EA80001F7C00001000000F96F401004F95315FCD
+:10EA9000970400000400A24B487F00000000114BC7
+:10EAA000489301000000004B6AB1010053953040CB
+:10EAB0008132000004002241E67D00000000004198
+:10EAC000E68101000000104081B201000000984082
+:10EAD00081B2010000973F4195E00100000000F382
+:10EAE00096B0010040973D4097E00100000063F3BD
+:10EAF00088B001006195A23B896C00000000004ACB
+:10EB000090B10100010000A692B101000400A24AE8
+:10EB1000447F00006295184A4493000000001840AA
+:10EB200081B201003F0400408998010016000012E4
+:10EB30008AE401000999004B8A140100300039452C
+:10EB400097E001000400A25F5F7C00000400225EE9
+:10EB50005F7C00001F04002F7ED901000400A64046
+:10EB6000813200006E95225A1F7C00001F04000FA6
+:10EB700098D801000000004C5E94010070950005DB
+:10EB80004AB000001F0400A75E840100000000409E
+:10EB90004BB001000000005E5F9001000400A2087D
+:10EBA0004E6C00000000005861B101000000004BF5
+:10EBB00062B101000000A84081B2000073950040DE
+:10EBC00081B20000330400408998010009990007D0
+:10EBD0008A30010078954007963000009D0400407F
+:10EBE000813201007C952245957C00000000984010
+:10EBF00081B201000400A24A447F00009B04004A45
+:10EC00004413010000973F4195E00100000000F32C
+:10EC100096B0010040973D4097E00100000063F38B
+:10EC200088B001003000384597E001000400A25F81
+:10EC30001F7C00000400225E1F7C0000040020AA4C
+:10EC40000F6C00000000005F0F90010000000058F2
+:10EC500061B101000000004B62B101008895A8403D
+:10EC6000813200007E95A23B896C0000300038455F
+:10EC70009DE001000000984081B2010004002208DC
+:10EC8000803200000300000894F4010000B7004A3D
+:10EC900046C9010007000008968801000400224BC5
+:10ECA000E67D000093040012943001004395005A61
+:10ECB0001F0001000000805A1F9001001100004A4F
+:10ECC000E6C901003000004A80CE01000400244063
+:10ECD0008132000034002F4F95840100000000F3C2
+:10ECE00096B001000100634B84C801000000A043FE
+:10ECF000856C01000000E34085B0010030002D4428
+:10ED00001F90010032002DF22AB0010004002640BD
+:10ED100081320000040022F2023000001D94001035
+:10ED20003230010004002200803200000400224240
+:10ED3000197C00003200A040E5B101000000004055
+:10ED400097B00100F0070040999801000000004AC8
+:10ED500002C001000000005003D00100000000418B
+:10ED600097C001000000A34C02D00000A99500400C
+:10ED700081B20000000000A836B00100BA9522411F
+:10ED8000035000000080001044C901000000005042
+:10ED9000F1B1010070000003F0C901000000004261
+:10EDA00061B101000000001062B10100B295A8003D
+:10EDB000E0310000238300881CB00000C9940040AB
+:10EDC000813201007C80000342C90100040022401E
+:10EDD000E16D0000000000F000B00100AD95005CA6
+:10EDE00001800000C9940040813201000000001B36
+:10EDF00010B1000068012D0682B00100000000F291
+:10EE000082C001000080000346C90100BF94004099
+:10EE100081320100E8952240116C00000000680872
+:10EE2000389601003A0400408998010009990008C9
+:10EE30008A300100F007004182CC0100BF95AA4151
+:10EE40003B400000000000F810B001000000005C32
+:10EE5000118001000400A3483B6C00000100001D6C
+:10EE600004CC0100E695264623300000080000038C
+:10EE700012C801000480000398C801000400A24CDD
+:10EE8000426D00000400A205486D0000640120F0FE
+:10EE9000E0B10100E595224105500000200000038B
+:10EEA00048C901000C0000F886C801000000224497
+:10EEB000F1B1010000000043F0B1010000000009C1
+:10EEC000E0B101000000004461B10100A00000A415
+:10EED00062DD0100D795A8461F100000E49522418D
+:10EEE00005500000E295A24123500000000000A15F
+:10EEF0001AB001000000004461B1010040000010A0
+:10EF000062DD0100DD95A8462330000023830088E0
+:10EF10001CB000001000000348C901000000000DF3
+:10EF200042B101000000004413C00100D29500501E
+:10EF300049C100000000000548B101000480000341
+:10EF40001AC801000400A205486D000000008040BE
+:10EF500081B20100E69522403B6C0000000000F801
+:10EF600000B00100C994005C01000100E895004177
+:10EF70003BD0000000008D4780320100B0002F5FC1
+:10EF800013B00100000060F08CC001007C00004064
+:10EF9000439901000400A3F08C6C00000000804045
+:10EFA00081B201000080000342C90100000000F8A6
+:10EFB00094B00100000000F88CB00100F7958CF8C7
+:10EFC0008E3000000000004419900100040022F877
+:10EFD00014300000000000F816B00100000000F836
+:10EFE00026B0010008002EF80CB001000C002A4ADF
+:10EFF000E0B1010028000000E0C901001000201B62
+:10F00000E0B101000496200A0C6C0000000000F83A
+:10F0100094B00100000000F896B00100200020F03C
+:10F02000E4B101001800204AE0B101001C00204BAF
+:10F03000E0B10100EC95004013B000000400A2050F
+:10F04000486D00002C002D42199001002E002FF376
+:10F0500082B00100000000F396B001000B96A2A55B
+:10F06000976C00000000804195B001000E96A24010
+:10F07000976C00000000004083B001002D0020408C
+:10F08000E7B101000000634197C00100D4003E4198
+:10F0900083E001000000004183C001001396A0A599
+:10F0A000836C00000000004083B001002C00204170
+:10F0B000E6B10100189622401F7C00000004000009
+:10F0C00098DC01000B00004CE4F5010019960040AB
+:10F0D0001F8000000B000000E4F501001E0400404A
+:10F0E00089980100099900008A30010000008040E1
+:10F0F00081B20100D1940040813201000080000300
+:10F1000042C9010004002240E16D000004800003B8
+:10F1100044C9010000000040F1B1010000000040BE
+:10F12000F1B101000000604187B0010000800010D3
+:10F1300044C9010000000050F1B101000000004886
+:10F14000F0B1010000000049F0B10100000000032F
+:10F15000E0B101000000004561B101002000001095
+:10F1600062DD01000000A85D0590000029960040C6
+:10F1700081B20000D1940040813201000080000380
+:10F1800044C9010000000041F0B101000400264024
+:10F190008132000000000042F0B101000000004098
+:10F1A000F1B1010000000043F0B101000080001047
+:10F1B00044C9010000000050F1B101000000004806
+:10F1C000F0B1010000000049F0B1010000000003AF
+:10F1D000E0B101000000004561B101002000001015
+:10F1E00062DD01000000A85D059000003996004036
+:10F1F00081B200000400A205486D00000400820CEA
+:10F20000803200002D000040439901002E002FF3B2
+:10F2100084B00100010063F396C8010043969F414A
+:10F2200085500000010000A585CC01002D00204282
+:10F23000E6B101000400A3A5976C0000D4003D4195
+:10F2400085E001000B0000F298E401004A9622409C
+:10F250001F7C00000400225A997C00000000005A24
+:10F26000998001000400A200986C00002004004076
+:10F2700089980100099900008A300100000080404F
+:10F2800081B2010021040040899801000999000021
+:10F290008A3001000400A2006A0600005E012D0011
+:10F2A00080B001005596524381600000020000F2D8
+:10F2B00082F4010056960041809400000000005F37
+:10F2C000819001000000005E61B10100000000407B
+:10F2D00062B101000000A84095B0000057969EBBA7
+:10F2E000803200005C96A2401F7C0000C994004060
+:10F2F00081B200000000804195B0010004000015BB
+:10F3000042C90100000000542BC00100000000FCB5
+:10F3100024B00100000000FC38B00100000000FE35
+:10F320003CB00100000000FE3AB0010071969C174D
+:10F33000803200006696A24A197C00000000804CD2
+:10F340001F9001000C00001E98F401006596A24871
+:10F35000996C00000000001542B101006596A28A78
+:10F36000F16D00000C00000102CC0100000000FC67
+:10F370003EB00100010000F428CC0100CC002D05B6
+:10F3800048B10100709620F03E6C00000000004B78
+:10F390001F9001000000004C2BC00100BF002D0594
+:10F3A00048B10100000080F33AE001000400A2052A
+:10F3B000486D00001000000C96F401000400A20744
+:10F3C000966C000000002E4B1990010007002A0CDB
+:10F3D000E4B1010000008004E6B101001800004023
+:10F3E000439901001C002DF016B0010020002DF003
+:10F3F00026B001000C002FF20CB001000000A206A4
+:10F4000014EC0000809622451F7C00000000A3063B
+:10F410002AEC0000000000F894B00100000000F0A9
+:10F4200096B001000C002D4081B2010000002A4C72
+:10F43000E1C101003000001048C901000A0000408D
+:10F44000F199010018000005F0C901000000004A10
+:10F45000F0B101000000004BE0B1010000000047E6
+:10F4600061B10100A00000A462DD01008A96A85CE1
+:10F470001F1000000000800548B101000400A295A3
+:10F48000036C000000002E1048B101004000000194
+:10F49000F0CD010040000003F0C901004000000071
+:10F4A000E0C9010000002E5049C101000000000623
+:10F4B000F1B1010000000003F0B101009596624235
+:10F4C000613100002000001062DD01009696A84026
+:10F4D000813200001000001062C901009896A80057
+:10F4E000E03100000000F24081B201000400A2956A
+:10F4F000036C000000002E1048B101004000000124
+:10F50000F0CD010040000003F0C901004000000000
+:10F51000E0C9010000002E5049C1010000000006B2
+:10F52000F1B1010000000003F0B10100A3966242B6
+:10F53000613100002000001062DD0100A496A840A7
+:10F5400081320000A00000A462DD0100A696A800A0
+:10F55000E03100000000F24081B201003080004A3A
+:10F5600044C9010000000006F1B10100C0A83D46F9
+:10F570000DE00100FF7F00A1F089010002000009F9
+:10F5800096F401000000004697E00100000060A82A
+:10F5900097C00100B0966342613100003000004A1C
+:10F5A00062C90100B196A840813200000000F3401A
+:10F5B00081B2010000993F4297F00100B596654085
+:10F5C00081320000BD9622F3740600003F0000F374
+:10F5D0009488010000000007E785010000007555D0
+:10F5E00061B101000000004A62B101000000A840C2
+:10F5F00081B20000BA96004081B200000000F540E0
+:10F6000081B20100000000A836B00100CD96824111
+:10F6100023400000C296A2441F7C00009E9300017C
+:10F620008C3001002080001042C90100C8962240A1
+:10F63000E36D00000000004361B1010040000010D4
+:10F6400062DD0100C596A840813200002383008856
+:10F650001CB000000000004123B0010000000010B9
+:10F6600032B00100CD962241197C0000E79400439E
+:10F67000233001000000004123B00100CF96A31504
+:10F680000C6C0000D096000604B0000000000015CD
+:10F6900004B00100D29620021A6C00000000000D98
+:10F6A00004B00100A197000548310100FD96220237
+:10F6B00014500000D696A2022A500000FD96A245E2
+:10F6C0001F7C0000D89622020C500000E196000238
+:10F6D00016C00000E096225C1F7C00003080001005
+:10F6E00042C90100E0962240E36D0000000000479F
+:10F6F00061B101004000001062DD0100DC96A8400D
+:10F7000081320000238300881CB000000000000547
+:10F7100048B101007996005C1F000100FD9622159A
+:10F72000803200000000005033C00100FC96A202AD
+:10F730001A500000ED9622461F7C000070800003E6
+:10F7400042C90100000000461F800100ED962240E2
+:10F75000E36D00000000004261B1010040000010B4
+:10F7600062DD0100E996A840813200002383008811
+:10F770001CB000000000000548B101000C8000032F
+:10F7800042C90100040022F080320000100000F0A5
+:10F7900010C801002F002F5C1180010000000047FD
+:10F7A000E7910100F00700401B980100BF9620156B
+:10F7B0001A6C00007000000348C9010000002250CC
+:10F7C000F1B1010000000003F0B10100FF070008E3
+:10F7D000E08D01000000004261B10100A00000A422
+:10F7E00062DD0100F996A8461F100000BF960005D3
+:10F7F00048B10000BF96000210C00000FF96A2446E
+:10F800001F7C00009E9300018C3001000000001B53
+:10F8100010B100000080001044C901000C0000403D
+:10F82000F199010010000008F0C901000000001665
+:10F83000F0B1010010000003E0C901000400A25C67
+:10F840001F7C00000000004561B101002000001095
+:10F8500062DD01000000A85C1F90000007970040D7
+:10F8600081B20000170000D0A2C901000000A24030
+:10F8700027EC00000000002000B00100C994004106
+:10F88000A34101000B97004127D00000360400403F
+:10F8900089980100099900408A3001001000000792
+:10F8A00096E401000000004B809401000000005429
+:10F8B00061B101000080004062DD01000000A8404D
+:10F8C00081B20000040014BB803200001497004095
+:10F8D00081B200000400A205486D00006A97004054
+:10F8E0002B300100AC002D0616C0010090002DF059
+:10F8F00016C401001E97A0F016440000000000414D
+:10F9000017C001000E0000A244C9010000006CF005
+:10F9100030B00100AC002D4087B0010000006CF059
+:10F9200028B001002797224A197C000000300043CC
+:10F9300086C801000030000B16C801002797A440BC
+:10F94000813200000000004117C001004A972206E2
+:10F95000803200003597A206146C000032972248CE
+:10F96000197C00002C97A0411740000000000041C6
+:10F9700017C001000000004131C0010090002018B4
+:10F98000E0B101008B002D48198001000400A24560
+:10F99000E77D00008B002045E7910100359700408E
+:10F9A0008790000008000043869801003597A04822
+:10F9B000174000000000004117C00100B0000040E7
+:10F9C0004399010010500043FCC90100AE9700307C
+:10F9D0008130010000000040E5B101004097224A5B
+:10F9E000197C0000080000A244C90100CC002DAB26
+:10F9F000F9B10100000000AB17C001003F97A0F073
+:10FA0000164400000000004117C00100449764F054
+:10FA100082B00000A4000040479901004497A2F280
+:10FA20008032000000000041E5B101008C00201888
+:10FA3000E0B101009000004045990100000060061F
+:10FA400030C001000000860C80B200000400A24912
+:10FA5000197C0000BC002D4619900100A000A0F206
+:10FA6000E4B10100B0000040439901001050004390
+:10FA7000FCC90100AE970030813001000000A24AAD
+:10FA800019FC0000080000A244C90100CC002DAB05
+:10FA9000F9B10100000000AB17C001005397A0F0BE
+:10FAA000164400000000004117C001000000E4F00F
+:10FAB00082B001000080001044C901000000004134
+:10FAC000F0B1010000000003F0B1010000000000EF
+:10FAD000F0B101000000001062B101000000A81B9D
+:10FAE000E0B100005897004081B2000000F0000C27
+:10FAF0007E8901000000A64C956001000000804A4C
+:10FB0000189401000080001044C901000400220183
+:10FB1000F031000020000040F0C901000000001694
+:10FB2000F0B101000000004361B1010020000010AD
+:10FB300062DD01000000A815E0B1000063970040FD
+:10FB400081B200001080000344C9010000000006DB
+:10FB5000F0B1010000000001F0B101000000E85F19
+:10FB60001790010070000040439901007A012EFEB9
+:10FB700092B001008B002DF616B001007097224361
+:10FB8000E77D00000000004445C10100040000A61C
+:10FB90002AB0010028006E0682C801007497224A2C
+:10FBA000197C00000000004245D1010000006E4CAD
+:10FBB00083C001000000004192C0010075974330EE
+:10FBC0003D0700000000669E83B0010000001B415D
+:10FBD0003DC301000000004192C00100060000A2E8
+:10FBE00044C901001000004998F401007E972630B6
+:10FBF000930400007E97904C92400000000000416A
+:10FC000093C00100FFFF8049ECA9010000800010B3
+:10FC100044C9010004002201F03100000000000985
+:10FC2000F0B1010000000018F0B101002000001048
+:10FC300062DD01000000A815E0B1000083970040DC
+:10FC400081B2000004002220816C000004002240E8
+:10FC5000816C00009597225F817C00009297A24002
+:10FC6000197C0000000000401990010000000054C1
+:10FC700061B101001000000796E401000000004F90
+:10FC8000979401000000004B62B101009297284058
+:10FC9000813200000400A254777D00008E9700405E
+:10FCA00081B20000250400408998010009990040B4
+:10FCB0008A3001000000A221818400009897A25F91
+:10FCC000816C00000000A243197C01000000004389
+:10FCD000199001002504004089980100099900400D
+:10FCE0008A3001000000005461B1010010000007DB
+:10FCF00096E4010000000040969401000000004BD3
+:10FD000062B101000000A84081B200000400A254CA
+:10FD1000777D00009D97004081B20000040022081A
+:10FD2000803200000400220280320000A697A24B1D
+:10FD3000FD7F0000B405000280CE01000400AA404F
+:10FD4000813200000080001944C901000400220231
+:10FD5000F03100000000000BF0B1010000000013C2
+:10FD6000F0B101000000004361B101002000001962
+:10FD700062DD01000000A808E0B10000AB97004080
+:10FD800081B200000400A205486D0000B00000A18F
+:10FD900080CE01000400A640813200007C002DF0DE
+:10FDA00084B00100020000F098F40100B797204CE5
+:10FDB000846C00008800004043990100B79720F24E
+:10FDC000846C00000000004085B0010098002D14F4
+:10FDD00082B00100000000F098B00100A3002D14D3
+:10FDE00098D00100BC97204C846C00000000004CAF
+:10FDF00084B001000400A230816C0000000000F318
+:10FE000080E00100C0972340846C000000000040A7
+:10FE100084B00100D0002014E0B101009800254218
+:10FE200080B0010000006EF380F001000000A642E7
+:10FE300082C00000C697A0401640000000000041AC
+:10FE400017C0010000009FF082EC00009800A04164
+:10FE5000E0B101000400A25C1F7C000037040040F8
+:10FE600089980100099900058A30010000000042CC
+:10FE700061B1010000002E1048B10100A80100404E
+:10FE8000F199010000000005F0B101000900000730
+:10FE900096E40100000060A797C001000000001078
+:10FEA00062B101000000A84081B20000D19700407B
+:10FEB00081B20000A8002D1C8AB0010000009FF054
+:10FEC0008AD000000000A2408BEC00008A00204095
+:10FED000E7B10100B400004047990100A4002D459E
+:10FEE000E0D10100DF979C17803200000400224A15
+:10FEF000197C0000BE002FAB83B001003C980014B9
+:10FF000082500100E497004081B20000E49722F2A1
+:10FF1000823000008C00004043990100E4979F1C50
+:10FF2000E06D0000BE000040479901003C98004091
+:10FF300081320100A800201CE0B101009C002D309E
+:10FF400081B0010088002DF084B0010094002DF2F2
+:10FF500086B00100F89723F0846C0000EC972392A0
+:10FF6000876C0000C90400A694B00100EE97004021
+:10FF700081B20000200000A694B001006089004A10
+:10FF800094980100EE9768408132000004002240FE
+:10FF9000BD7D00000000004AB0B10100BF002D424D
+:10FFA000B2B1010090002DF380E00100F397D4403E
+:10FFB00081320000000078DA84C00100FD97234000
+:10FFC000846C00009400209DE1B10100FD97004089
+:10FFD00084B00000BF002D4384C0010090002DF3C9
+:10FFE00080E00100FD972340846C00009400209D78
+:10FFF000E1B101000000004084B001000198A2F0CE
+:020000021000EC
+:10000000386C00009C002042E0B101000000005F5D
+:100010001394010000008046198001009C002042DA
+:10002000E0B101003700004043990100040000F3F3
+:1000300080F401000F0000F382880100079823413B
+:10004000806C00000000005F139401000000890C28
+:1000500080B200000400860C80320000BC0000402A
+:1000600043990100A000A0F2E4B1010000009F410B
+:1000700024EC00001398A6408132000000009F424B
+:1000800038EC00001398A64081320000B400004014
+:10009000439901001598A3F03A6C00000400A440B5
+:1000A000813200000000804081B20100B4000040B5
+:1000B00043990100199822F03A6C0000B400201D09
+:1000C000E0B1010080002D5F13940100199823F026
+:1000D0003A6C00008000201DE0B10100C000201239
+:1000E000E0B10100C400A01CE0B101002704004001
+:1000F00089980100099900428A3001000400A20594
+:10010000486D00000080000344C901000000004267
+:10011000E0B10100120000408798010025989F413E
+:10012000246C0000000000418CB0010000000012AF
+:100130008CD001002698004124B00000000000404F
+:100140008DB001007F980040813201000000004521
+:1001500061B101004000001062DD01000000A84014
+:1001600081B200002898004081B20000B4940040A1
+:10017000813201000000001680B201000000A708D3
+:10018000803201003204004089980100099900087A
+:100190008A3001003298A240956C0000C99400405A
+:1001A00081320100008200A604B00100000000407E
+:1001B0002DB00100A0982F4011B001003005004182
+:1001C00089B00000CC0000A180CE01000400A64050
+:1001D0008132000000009FF83EEC000000009F12FA
+:1001E000E0ED0000C80020ABE1B10100CC00A01F91
+:1001F000E0B101000400A205486D00003F98A35F34
+:10020000E76D000000000041E7C10100A6000040CA
+:1002100047990100539822F2863000000300004302
+:1002200084F401000100004180CC0100B8002D429F
+:1002300080D001000000624086C0010047981F4343
+:10024000803200004898A240876C000000006241A4
+:1002500087B001004C989F408032000000000040B1
+:1002600085B001000000004084D001000000004281
+:1002700080B00100000000F288B0010002000044DC
+:1002800084F40100B8002E4280D0010000006240DA
+:1002900088C0010052981F44803200005698A24046
+:1002A000896C00005698624189B0000003006241E9
+:1002B00086E40100B8000040459901000100624158
+:1002C00088E40100A4002040E5B10100A200204024
+:1002D000E7B10100BC002E4387F00100000000449C
+:1002E00086C001005C982043876C000000008043BA
+:1002F000E5B101004001004380CE01000000A443AD
+:10030000E43101004001E240879801000400A205A9
+:10031000486D00000400220A8032000088002D444D
+:1003200081B0010090002DF22EB001009C002DF054
+:1003300086B0010090002DF082B00100BA002DF0CF
+:1003400098B001006B98A212986C0000BC002DF2CE
+:1003500098B001006B98A0F2986C000000000017A4
+:1003600082B001009C002041E0B10100B4002D12D8
+:1003700086D001006E98A341E06D00006F9800F0F8
+:1003800084B000000000004184B0010080002D43D3
+:1003900084D0010072989F4280320000000000402B
+:1003A00085B001007498A342146C00007598000A8F
+:1003B0000CB00000000000420CB001007798A017BC
+:1003C0000C6C0000000080170CB001007C982240EB
+:1003D0000D6C00000000A00A0CEC0000010000F011
+:1003E00082F401007C98A0410C6C00000000A2F097
+:1003F00080320100290000408998010009990040DD
+:10040000813201000000804081B00100D1940040A1
+:1004100081320100040022038032000004800003C6
+:1004200044C9010000000046F0B101000000004096
+:10043000F1B10100000060418794010000800010CC
+:1004400044C9010000000050F1B101000000004863
+:10045000F0B1010000000049F0B10100000000030C
+:10046000E0B101000000004561B101002000001072
+:1004700062DD01000000A85D059000008B9800403F
+:1004800081B200000400A205486D00001000000CBD
+:1004900096F401000400A207966C000000002E4BA9
+:1004A0001990010005002A0CE4B10100000080044D
+:1004B000E6B101003E040040899801000999000856
+:1004C0008A3001009698454861310000001000080C
+:1004D00062DD01009C9828408730000097982248F0
+:1004E000777D000004002240276C00000A971D461B
+:1004F00087B000009F98225F117C00000400221545
+:10050000623100009D98A8408132000000009D40AB
+:1005100081B201000000004049B1010000142F4CDD
+:1005200083B0010000000040F1B10100A298A24197
+:10053000835000000000804081B2010000000040B4
+:1005400049B1010030000040A199010000000040C5
+:1005500093B00100000000401FB00100F698004970
+:10056000963001000700004906E40100003900034D
+:1005700006C801000000004005B00100200000D0C6
+:10058000A0C901000000004193C00100A998A05437
+:10059000936C000000002E0597B001000080004021
+:1005A0004999010000000040E1B10100000200A2F1
+:1005B00044C90100B298A2419750000000000020F9
+:1005C00049B30100FC980040493101000895004002
+:1005D0008132010000B52E0897B0010000000040F4
+:1005E000F1B10100B998A2419750000018000040F5
+:1005F0009798010000972E4081B201000000004052
+:10060000F1B10100BD98A2419750000000000040E8
+:1006100049B1010040182E0597B0010000000040CC
+:10062000F1B10100C198A2419750000057952040B8
+:10063000E7B101003094004045990100640000409A
+:10064000E599010056952040E7B10100B89420419A
+:10065000E5B10100BA942041E5B101009894004051
+:1006600045990100020000409798010000000040F9
+:10067000F1B10100CB98A24197500000000000406A
+:1006800097B00100000000406FB101000000004B76
+:1006900068B10100CF988541974000008004004078
+:1006A000813201000000004039B301000000004029
+:1006B00037B301000000004035B3010000000040E6
+:1006C00033B301000000004041B3010000000040CE
+:1006D0003FB30100EE050040259B010042000040B1
+:1006E0004B9B0100000000402FB3010000000040C0
+:1006F0002DB301000000004047B30100000000409E
+:1007000043B30100600000402B9B01000000005437
+:10071000EF93010000000055F1930100FFFF00A5D9
+:100720003C8B01000000002C5BB301000000002C9A
+:1007300045B301000000004059B301000000004033
+:1007400057B301000000004027B301000000004043
+:1007500053B30100EB98A250FD7F0000EB98A2512B
+:10076000FD7F0000EC9800401DB3000050460040A3
+:100770001D9B010000C000A688B30100FF3F00A63A
+:100780003AB3010000C0009D3B9B0100B40500404E
+:10079000239B0100000000404DB30100080A00A6A1
+:1007A00014B301000101008A159B01000000002024
+:1007B00087B30100008000A656B101000000805EF2
+:1007C00057B501001800004B20E401000600004B63
+:1007D00096E401000043004B96C801001800001089
+:1007E00020DC01000000004B209401000000805735
+:1007F0002190010000992E0A97B0010000000040EE
+:10080000F1B10100FD98A2419750000000030040A3
+:100810009798010000A900404599010000000040A0
+:10082000F1B101000199A241975000003000004051
+:10083000979801000000005561B101000000004BD5
+:1008400062B101000599A840813200000599A241DA
+:10085000975000000000804081B201001000004E5F
+:1008600098E4010000000007989401000000004394
+:1008700099E0010000000080989401000000004809
+:1008800099E001000000004C889401000F996A4033
+:10089000813200001299224F777D0000F004004061
+:1008A000813201000000004F61B1010000000044EE
+:1008B00062B101001399A840813200001A99224ABE
+:1008C000897C00001899224F777D0000F0040040D9
+:1008D000813201000000004562B101001899A84072
+:1008E000813200000000FA4081B201000000804027
+:1008F00081B201000400A25A1F7C00001000000F0A
+:1009000098F401000400A25F9904000000008040F8
+:1009100081B201000000804081B20100040000406B
+:1009200081B200000400004081B2000004000040D9
+:1009300081B200000400004081B2000004000040C9
+:1009400081B200000400004081B2000004000040B9
+:1009500081B200000400004081B2000004000040A9
+:1009600081B200000400004081B200000400004099
+:1009700081B200000400004081B200000400004089
+:1009800081B200000400004081B200000400004079
+:1009900081B200000400004081B200000400004069
+:1009A00081B200000400004081B200000400004059
+:1009B00081B200000400004081B200000400004049
+:1009C00081B200000400004081B200000400004039
+:1009D00081B200000400004081B200000400004029
+:1009E00081B200000400004081B200000400004019
+:1009F00081B200000400004081B200000400004009
+:100A000081B200000400004081B2000004000040F8
+:100A100081B200000400004081B2000004000040E8
+:100A200081B200000400004081B2000004000040D8
+:100A300081B200000400004081B2000004000040C8
+:100A400081B200000400004081B2000004000040B8
+:100A500081B200000400004081B2000004000040A8
+:100A600081B200000400004081B200000400004098
+:100A700081B200000400004081B200000400004088
+:100A800081B200000400004081B200000400004078
+:100A900081B200000400004081B200000400004068
+:100AA00081B200000400004081B200000400004058
+:100AB00081B200000400004081B200000400004048
+:100AC00081B200000400004081B200000400004038
+:100AD00081B200000400004081B200000400004028
+:100AE00081B200000400004081B200000400004018
+:100AF00081B200000400004081B200000400004008
+:100B000081B200000400004081B2000004000040F7
+:100B100081B200000400004081B2000004000040E7
+:100B200081B200000400004081B2000004000040D7
+:100B300081B200000400004081B2000004000040C7
+:100B400081B200000400004081B2000004000040B7
+:100B500081B200000400004081B2000004000040A7
+:100B600081B200000400004081B200000400004097
+:100B700081B200000400004081B200000400004087
+:100B800081B200000400004081B200000400004077
+:100B900081B200000400004081B200000400004067
+:100BA00081B200000400004081B200000400004057
+:100BB00081B200000400004081B200000400004047
+:100BC00081B200000400004081B200000400004037
+:100BD00081B200000400004081B200000400004027
+:100BE00081B200000400004081B200000400004017
+:100BF00081B200000400004081B200000400004007
+:100C000081B200000400004081B2000004000040F6
+:100C100081B200000400004081B2000004000040E6
+:100C200081B200000400004081B2000004000040D6
+:100C300081B200000400004081B2000004000040C6
+:100C400081B200000400004081B2000004000040B6
+:100C500081B200000400004081B2000004000040A6
+:100C600081B200000400004081B200000400004096
+:100C700081B200000400004081B200000400004086
+:100C800081B200000400004081B200000400004076
+:100C900081B200000400004081B200000400004066
+:100CA00081B200000400004081B200000400004056
+:100CB00081B200000400004081B200000400004046
+:100CC00081B200000400004081B200000400004036
+:100CD00081B200000400004081B200000400004026
+:100CE00081B200000400004081B200000400004016
+:100CF00081B200000400004081B200000400004006
+:100D000081B200000400004081B2000004000040F5
+:100D100081B200000400004081B2000004000040E5
+:100D200081B200000400004081B2000004000040D5
+:100D300081B200000400004081B2000004000040C5
+:100D400081B200000400004081B2000004000040B5
+:100D500081B200000400004081B2000004000040A5
+:100D600081B200000400004081B200000400004095
+:100D700081B200000400004081B200000400004085
+:100D800081B200000400004081B200000400004075
+:100D900081B200000400004081B200000400004065
+:100DA00081B200000400004081B200000400004055
+:100DB00081B200000400004081B200000400004045
+:100DC00081B200000400004081B200000400004035
+:100DD00081B200000400004081B200000400004025
+:100DE00081B200000400004081B200000400004015
+:100DF00081B200000400004081B200000400004005
+:100E000081B200000400004081B2000004000040F4
+:100E100081B200000400004081B2000004000040E4
+:100E200081B200000400004081B2000004000040D4
+:100E300081B200000400004081B2000004000040C4
+:100E400081B200000400004081B2000004000040B4
+:100E500081B200000400004081B2000004000040A4
+:100E600081B200000400004081B200000400004094
+:100E700081B200000400004081B200000400004084
+:100E800081B200000400004081B200000400004074
+:100E900081B200000400004081B200000400004064
+:100EA00081B200000400004081B200000400004054
+:100EB00081B200000400004081B200000400004044
+:100EC00081B200000400004081B200000400004034
+:100ED00081B200000400004081B200000400004024
+:100EE00081B200000400004081B200000400004014
+:100EF00081B200000400004081B200000400004004
+:100F000081B200000400004081B2000004000040F3
+:100F100081B200000400004081B2000004000040E3
+:100F200081B200000400004081B2000004000040D3
+:100F300081B200000400004081B2000004000040C3
+:100F400081B200000400004081B2000004000040B3
+:100F500081B200000400004081B2000004000040A3
+:100F600081B200000400004081B200000400004093
+:100F700081B200000400004081B200000400004083
+:100F800081B200000400004081B200000400004073
+:100F900081B200000400004081B200000400004063
+:100FA00081B200000400004081B200000400004053
+:100FB00081B200000400004081B200000400004043
+:100FC00081B200000400004081B200000400004033
+:100FD00081B200000400004081B200000400004023
+:100FE00081B200000400004081B200000400004013
+:100FF00081B200000400004081B200000400004003
+:1010000081B200000400004081B2000004000040F2
+:1010100081B200000400004081B2000004000040E2
+:1010200081B200000400004081B2000004000040D2
+:1010300081B200000400004081B2000004000040C2
+:1010400081B200000400004081B2000004000040B2
+:1010500081B200000400004081B2000004000040A2
+:1010600081B200000400004081B200000400004092
+:1010700081B200000400004081B200000400004082
+:1010800081B200000400004081B200000400004072
+:1010900081B200000400004081B200000400004062
+:1010A00081B200000400004081B200000400004052
+:1010B00081B200000400004081B200000400004042
+:1010C00081B200000400004081B200000400004032
+:1010D00081B200000400004081B200000400004022
+:1010E00081B200000400004081B200000400004012
+:1010F00081B200000400004081B200000400004002
+:1011000081B200000400004081B2000004000040F1
+:1011100081B200000400004081B2000004000040E1
+:1011200081B200000400004081B2000004000040D1
+:1011300081B200000400004081B2000004000040C1
+:1011400081B200000400004081B2000004000040B1
+:1011500081B200000400004081B2000004000040A1
+:1011600081B200000400004081B200000400004091
+:1011700081B200000400004081B200000400004081
+:1011800081B200000400004081B200000400004071
+:1011900081B200000400004081B200000400004061
+:1011A00081B200000400004081B200000400004051
+:1011B00081B200000400004081B200000400004041
+:1011C00081B200000400004081B200000400004031
+:1011D00081B200000400004081B200000400004021
+:1011E00081B200000400004081B200000400004011
+:1011F00081B200000400004081B200000400004001
+:1012000081B200000400004081B2000004000040F0
+:1012100081B200000400004081B2000004000040E0
+:1012200081B200000400004081B2000004000040D0
+:1012300081B200000400004081B2000004000040C0
+:1012400081B200000400004081B2000004000040B0
+:1012500081B200000400004081B2000004000040A0
+:1012600081B200000400004081B200000400004090
+:1012700081B200000400004081B200000400004080
+:1012800081B200000400004081B200000400004070
+:1012900081B200000400004081B200000400004060
+:1012A00081B200000400004081B200000400004050
+:1012B00081B200000400004081B200000400004040
+:1012C00081B200000400004081B200000400004030
+:1012D00081B200000400004081B200000400004020
+:1012E00081B200000400004081B200000400004010
+:1012F00081B200000400004081B200000400004000
+:1013000081B200000400004081B2000004000040EF
+:1013100081B200000400004081B2000004000040DF
+:1013200081B200000400004081B2000004000040CF
+:1013300081B200000400004081B2000004000040BF
+:1013400081B200000400004081B2000004000040AF
+:1013500081B200000400004081B20000040000409F
+:1013600081B200000400004081B20000040000408F
+:1013700081B200000400004081B20000040000407F
+:1013800081B200000400004081B20000040000406F
+:1013900081B200000400004081B20000040000405F
+:1013A00081B200000400004081B20000040000404F
+:1013B00081B200000400004081B20000040000403F
+:1013C00081B200000400004081B20000040000402F
+:1013D00081B200000400004081B20000040000401F
+:1013E00081B200000400004081B20000040000400F
+:1013F00081B200000400004081B2000004000040FF
+:1014000081B200000400004081B2000004000040EE
+:1014100081B200000400004081B2000004000040DE
+:1014200081B200000400004081B2000004000040CE
+:1014300081B200000400004081B2000004000040BE
+:1014400081B200000400004081B2000004000040AE
+:1014500081B200000400004081B20000040000409E
+:1014600081B200000400004081B20000040000408E
+:1014700081B200000400004081B20000040000407E
+:1014800081B200000400004081B20000040000406E
+:1014900081B200000400004081B20000040000405E
+:1014A00081B200000400004081B20000040000404E
+:1014B00081B200000400004081B20000040000403E
+:1014C00081B200000400004081B20000040000402E
+:1014D00081B200000400004081B20000040000401E
+:1014E00081B200000400004081B20000040000400E
+:1014F00081B200000400004081B2000004000040FE
+:1015000081B200000400004081B2000004000040ED
+:1015100081B200000400004081B2000004000040DD
+:1015200081B200000400004081B2000004000040CD
+:1015300081B200000400004081B2000004000040BD
+:1015400081B200000400004081B2000004000040AD
+:1015500081B200000400004081B20000040000409D
+:1015600081B200000400004081B20000040000408D
+:1015700081B200000400004081B20000040000407D
+:1015800081B200000400004081B20000040000406D
+:1015900081B200000400004081B20000040000405D
+:1015A00081B200000400004081B20000040000404D
+:1015B00081B200000400004081B20000040000403D
+:1015C00081B200000400004081B20000040000402D
+:1015D00081B200000400004081B20000040000401D
+:1015E00081B200000400004081B20000040000400D
+:1015F00081B200000400004081B2000004000040FD
+:1016000081B200000400004081B2000004000040EC
+:1016100081B200000400004081B2000004000040DC
+:1016200081B200000400004081B2000004000040CC
+:1016300081B200000400004081B2000004000040BC
+:1016400081B200000400004081B2000004000040AC
+:1016500081B200000400004081B20000040000409C
+:1016600081B200000400004081B20000040000408C
+:1016700081B200000400004081B20000040000407C
+:1016800081B200000400004081B20000040000406C
+:1016900081B200000400004081B20000040000405C
+:1016A00081B200000400004081B20000040000404C
+:1016B00081B200000400004081B20000040000403C
+:1016C00081B200000400004081B20000040000402C
+:1016D00081B200000400004081B20000040000401C
+:1016E00081B200000400004081B20000040000400C
+:1016F00081B200000400004081B2000004000040FC
+:1017000081B200000400004081B2000004000040EB
+:1017100081B200000400004081B2000004000040DB
+:1017200081B200000400004081B2000004000040CB
+:1017300081B200000400004081B2000004000040BB
+:1017400081B200000400004081B2000004000040AB
+:1017500081B200000400004081B20000040000409B
+:1017600081B200000400004081B20000040000408B
+:1017700081B200000400004081B20000040000407B
+:1017800081B200000400004081B20000040000406B
+:1017900081B200000400004081B20000040000405B
+:1017A00081B200000400004081B20000040000404B
+:1017B00081B200000400004081B20000040000403B
+:1017C00081B200000400004081B20000040000402B
+:1017D00081B200000400004081B20000040000401B
+:1017E00081B200000400004081B20000040000400B
+:1017F00081B200000400004081B2000004000040FB
+:1018000081B200000400004081B2000004000040EA
+:1018100081B200000400004081B2000004000040DA
+:1018200081B200000400004081B2000004000040CA
+:1018300081B200000400004081B2000004000040BA
+:1018400081B200000400004081B2000004000040AA
+:1018500081B200000400004081B20000040000409A
+:1018600081B200000400004081B20000040000408A
+:1018700081B200000400004081B20000040000407A
+:1018800081B200000400004081B20000040000406A
+:1018900081B200000400004081B20000040000405A
+:1018A00081B200000400004081B20000040000404A
+:1018B00081B200000400004081B20000040000403A
+:1018C00081B200000400004081B20000040000402A
+:1018D00081B200000400004081B20000040000401A
+:1018E00081B200000400004081B20000040000400A
+:1018F00081B200000400004081B2000004000040FA
+:1019000081B200000400004081B2000004000040E9
+:1019100081B200000400004081B2000004000040D9
+:1019200081B200000400004081B2000004000040C9
+:1019300081B200000400004081B2000004000040B9
+:1019400081B200000400004081B2000004000040A9
+:1019500081B200000400004081B200000400004099
+:1019600081B200000400004081B200000400004089
+:1019700081B200000400004081B200000400004079
+:1019800081B200000400004081B200000400004069
+:1019900081B200000400004081B200000400004059
+:1019A00081B200000400004081B200000400004049
+:1019B00081B200000400004081B200000400004039
+:1019C00081B200000400004081B200000400004029
+:1019D00081B200000400004081B200000400004019
+:1019E00081B200000400004081B200000400004009
+:1019F00081B200000400004081B2000004000040F9
+:101A000081B200000400004081B2000004000040E8
+:101A100081B200000400004081B2000004000040D8
+:101A200081B200000400004081B2000004000040C8
+:101A300081B200000400004081B2000004000040B8
+:101A400081B200000400004081B2000004000040A8
+:101A500081B200000400004081B200000400004098
+:101A600081B200000400004081B200000400004088
+:101A700081B200000400004081B200000400004078
+:101A800081B200000400004081B200000400004068
+:101A900081B200000400004081B200000400004058
+:101AA00081B200000400004081B200000400004048
+:101AB00081B200000400004081B200000400004038
+:101AC00081B200000400004081B200000400004028
+:101AD00081B200000400004081B200000400004018
+:101AE00081B200000400004081B200000400004008
+:101AF00081B200000400004081B2000004000040F8
+:101B000081B200000400004081B2000004000040E7
+:101B100081B200000400004081B2000004000040D7
+:101B200081B200000400004081B2000004000040C7
+:101B300081B200000400004081B2000004000040B7
+:101B400081B200000400004081B2000004000040A7
+:101B500081B200000400004081B200000400004097
+:101B600081B200000400004081B200000400004087
+:101B700081B200000400004081B200000400004077
+:101B800081B200000400004081B200000400004067
+:101B900081B200000400004081B200000400004057
+:101BA00081B200000400004081B200000400004047
+:101BB00081B200000400004081B200000400004037
+:101BC00081B200000400004081B200000400004027
+:101BD00081B200000400004081B200000400004017
+:101BE00081B200000400004081B200000400004007
+:101BF00081B200000400004081B2000004000040F7
+:101C000081B200000400004081B2000004000040E6
+:101C100081B200000400004081B2000004000040D6
+:101C200081B200000400004081B2000004000040C6
+:101C300081B200000400004081B2000004000040B6
+:101C400081B200000400004081B2000004000040A6
+:101C500081B200000400004081B200000400004096
+:101C600081B200000400004081B200000400004086
+:101C700081B200000400004081B200000400004076
+:101C800081B200000400004081B200000400004066
+:101C900081B200000400004081B200000400004056
+:101CA00081B200000400004081B200000400004046
+:101CB00081B200000400004081B200000400004036
+:101CC00081B200000400004081B200000400004026
+:101CD00081B200000400004081B200000400004016
+:101CE00081B200000400004081B200000400004006
+:101CF00081B200000400004081B2000004000040F6
+:101D000081B200000400004081B2000004000040E5
+:101D100081B200000400004081B2000004000040D5
+:101D200081B200000400004081B2000004000040C5
+:101D300081B200000400004081B2000004000040B5
+:101D400081B200000400004081B2000004000040A5
+:101D500081B200000400004081B200000400004095
+:101D600081B200000400004081B200000400004085
+:101D700081B200000400004081B200000400004075
+:101D800081B200000400004081B200000400004065
+:101D900081B200000400004081B200000400004055
+:101DA00081B200000400004081B200000400004045
+:101DB00081B200000400004081B200000400004035
+:101DC00081B200000400004081B200000400004025
+:101DD00081B200000400004081B200000400004015
+:101DE00081B200000400004081B200000400004005
+:101DF00081B200000400004081B2000004000040F5
+:101E000081B200000400004081B2000004000040E4
+:101E100081B200000400004081B2000004000040D4
+:101E200081B200000400004081B2000004000040C4
+:101E300081B200000400004081B2000004000040B4
+:101E400081B200000400004081B2000004000040A4
+:101E500081B200000400004081B200000400004094
+:101E600081B200000400004081B200000400004084
+:101E700081B200000400004081B200000400004074
+:101E800081B200000400004081B200000400004064
+:101E900081B200000400004081B200000400004054
+:101EA00081B200000400004081B200000400004044
+:101EB00081B200000400004081B200000400004034
+:101EC00081B200000400004081B200000400004024
+:101ED00081B200000400004081B200000400004014
+:101EE00081B200000400004081B200000400004004
+:101EF00081B200000400004081B2000004000040F4
+:101F000081B200000400004081B2000004000040E3
+:101F100081B200000400004081B2000004000040D3
+:101F200081B200000400004081B2000004000040C3
+:101F300081B200000400004081B2000004000040B3
+:101F400081B200000400004081B2000004000040A3
+:101F500081B200000400004081B200000400004093
+:101F600081B200000400004081B200000400004083
+:101F700081B200000400004081B200000400004073
+:101F800081B200000400004081B200000400004063
+:101F900081B200000400004081B200000400004053
+:101FA00081B200000400004081B200000400004043
+:101FB00081B200000400004081B200000400004033
+:101FC00081B200000400004081B200000400004023
+:101FD00081B200000400004081B200000400004013
+:101FE00081B200000400004081B200000400004003
+:101FF00081B200000400004081B2000004000040F3
+:1020000081B200000400004081B2000004000040E2
+:1020100081B200000400004081B2000004000040D2
+:1020200081B200000400004081B2000004000040C2
+:1020300081B200000400004081B2000004000040B2
+:1020400081B200000400004081B2000004000040A2
+:1020500081B200000400004081B200000400004092
+:1020600081B200000400004081B200000400004082
+:1020700081B200000400004081B200000400004072
+:1020800081B200000400004081B200000400004062
+:1020900081B200000400004081B200000400004052
+:1020A00081B200000400004081B200000400004042
+:1020B00081B200000400004081B200000400004032
+:1020C00081B200000400004081B200000400004022
+:1020D00081B200000400004081B200000400004012
+:1020E00081B200000400004081B200000400004002
+:1020F00081B200000400004081B2000004000040F2
+:1021000081B200000400004081B2000004000040E1
+:1021100081B200000400004081B2000004000040D1
+:1021200081B200000400004081B2000004000040C1
+:1021300081B200000400004081B2000004000040B1
+:1021400081B200000400004081B2000004000040A1
+:1021500081B200000400004081B200000400004091
+:1021600081B200000400004081B200000400004081
+:1021700081B200000400004081B200000400004071
+:1021800081B200000400004081B200000400004061
+:1021900081B200000400004081B200000400004051
+:1021A00081B200000400004081B200000400004041
+:1021B00081B200000400004081B200000400004031
+:1021C00081B200000400004081B200000400004021
+:1021D00081B200000400004081B200000400004011
+:1021E00081B200000400004081B200000400004001
+:1021F00081B200000400004081B2000004000040F1
+:1022000081B200000400004081B2000004000040E0
+:1022100081B200000400004081B2000004000040D0
+:1022200081B200000400004081B2000004000040C0
+:1022300081B200000400004081B2000004000040B0
+:1022400081B200000400004081B2000004000040A0
+:1022500081B200000400004081B200000400004090
+:1022600081B200000400004081B200000400004080
+:1022700081B200000400004081B200000400004070
+:1022800081B200000400004081B200000400004060
+:1022900081B200000400004081B200000400004050
+:1022A00081B200000400004081B200000400004040
+:1022B00081B200000400004081B200000400004030
+:1022C00081B200000400004081B200000400004020
+:1022D00081B200000400004081B200000400004010
+:1022E00081B200000400004081B200000400004000
+:1022F00081B200000400004081B2000004000040F0
+:1023000081B200000400004081B2000004000040DF
+:1023100081B200000400004081B2000004000040CF
+:1023200081B200000400004081B2000004000040BF
+:1023300081B200000400004081B2000004000040AF
+:1023400081B200000400004081B20000040000409F
+:1023500081B200000400004081B20000040000408F
+:1023600081B200000400004081B20000040000407F
+:1023700081B200000400004081B20000040000406F
+:1023800081B200000400004081B20000040000405F
+:1023900081B200000400004081B20000040000404F
+:1023A00081B200000400004081B20000040000403F
+:1023B00081B200000400004081B20000040000402F
+:1023C00081B200000400004081B20000040000401F
+:1023D00081B200000400004081B20000040000400F
+:1023E00081B200000400004081B2000004000040FF
+:1023F00081B200000400004081B2000004000040EF
+:1024000081B200000400004081B2000004000040DE
+:1024100081B200000400004081B2000004000040CE
+:1024200081B200000400004081B2000004000040BE
+:1024300081B200000400004081B2000004000040AE
+:1024400081B200000400004081B20000040000409E
+:1024500081B200000400004081B20000040000408E
+:1024600081B200000400004081B20000040000407E
+:1024700081B200000400004081B20000040000406E
+:1024800081B200000400004081B20000040000405E
+:1024900081B200000400004081B20000040000404E
+:1024A00081B200000400004081B20000040000403E
+:1024B00081B200000400004081B20000040000402E
+:1024C00081B200000400004081B20000040000401E
+:1024D00081B200000400004081B20000040000400E
+:1024E00081B200000400004081B2000004000040FE
+:1024F00081B200000400004081B2000004000040EE
+:1025000081B200000400004081B2000004000040DD
+:1025100081B200000400004081B2000004000040CD
+:1025200081B200000400004081B2000004000040BD
+:1025300081B200000400004081B2000004000040AD
+:1025400081B200000400004081B20000040000409D
+:1025500081B200000400004081B20000040000408D
+:1025600081B200000400004081B20000040000407D
+:1025700081B200000400004081B20000040000406D
+:1025800081B200000400004081B20000040000405D
+:1025900081B200000400004081B20000040000404D
+:1025A00081B200000400004081B20000040000403D
+:1025B00081B200000400004081B20000040000402D
+:1025C00081B200000400004081B20000040000401D
+:1025D00081B200000400004081B20000040000400D
+:1025E00081B200000400004081B2000004000040FD
+:1025F00081B200000400004081B2000004000040ED
+:1026000081B200000400004081B2000004000040DC
+:1026100081B200000400004081B2000004000040CC
+:1026200081B200000400004081B2000004000040BC
+:1026300081B200000400004081B2000004000040AC
+:1026400081B200000400004081B20000040000409C
+:1026500081B200000400004081B20000040000408C
+:1026600081B200000400004081B20000040000407C
+:1026700081B200000400004081B20000040000406C
+:1026800081B200000400004081B20000040000405C
+:1026900081B200000400004081B20000040000404C
+:1026A00081B200000400004081B20000040000403C
+:1026B00081B200000400004081B20000040000402C
+:1026C00081B200000400004081B20000040000401C
+:1026D00081B200000400004081B20000040000400C
+:1026E00081B200000400004081B2000004000040FC
+:1026F00081B200000400004081B2000004000040EC
+:1027000081B200000400004081B2000004000040DB
+:1027100081B200000400004081B2000004000040CB
+:1027200081B200000400004081B2000004000040BB
+:1027300081B200000400004081B2000004000040AB
+:1027400081B200000400004081B20000040000409B
+:1027500081B200000400004081B20000040000408B
+:1027600081B200000400004081B20000040000407B
+:1027700081B200000400004081B20000040000406B
+:1027800081B200000400004081B20000040000405B
+:1027900081B200000400004081B20000040000404B
+:1027A00081B200000400004081B20000040000403B
+:1027B00081B200000400004081B20000040000402B
+:1027C00081B200000400004081B20000040000401B
+:1027D00081B200000400004081B20000040000400B
+:1027E00081B200000400004081B2000004000040FB
+:1027F00081B200000400004081B2000004000040EB
+:1028000081B200000400004081B2000004000040DA
+:1028100081B200000400004081B2000004000040CA
+:1028200081B200000400004081B2000004000040BA
+:1028300081B200000400004081B2000004000040AA
+:1028400081B200000400004081B20000040000409A
+:1028500081B200000400004081B20000040000408A
+:1028600081B200000400004081B20000040000407A
+:1028700081B200000400004081B20000040000406A
+:1028800081B200000400004081B20000040000405A
+:1028900081B200000400004081B20000040000404A
+:1028A00081B200000400004081B20000040000403A
+:1028B00081B200000400004081B20000040000402A
+:1028C00081B200000400004081B20000040000401A
+:1028D00081B200000400004081B20000040000400A
+:1028E00081B200000400004081B2000004000040FA
+:1028F00081B200000400004081B2000004000040EA
+:1029000081B200000400004081B2000004000040D9
+:1029100081B200000400004081B2000004000040C9
+:1029200081B200000400004081B2000004000040B9
+:1029300081B200000400004081B2000004000040A9
+:1029400081B200000400004081B200000400004099
+:1029500081B200000400004081B200000400004089
+:1029600081B200000400004081B200000400004079
+:1029700081B200000400004081B200000400004069
+:1029800081B200000400004081B200000400004059
+:1029900081B200000400004081B200000400004049
+:1029A00081B200000400004081B200000400004039
+:1029B00081B200000400004081B200000400004029
+:1029C00081B200000400004081B200000400004019
+:1029D00081B200000400004081B200000400004009
+:1029E00081B200000400004081B2000004000040F9
+:1029F00081B200000400004081B2000004000040E9
+:102A000081B200000400004081B2000004000040D8
+:102A100081B200000400004081B2000004000040C8
+:102A200081B200000400004081B2000004000040B8
+:102A300081B200000400004081B2000004000040A8
+:102A400081B200000400004081B200000400004098
+:102A500081B200000400004081B200000400004088
+:102A600081B200000400004081B200000400004078
+:102A700081B200000400004081B200000400004068
+:102A800081B200000400004081B200000400004058
+:102A900081B200000400004081B200000400004048
+:102AA00081B200000400004081B200000400004038
+:102AB00081B200000400004081B200000400004028
+:102AC00081B200000400004081B200000400004018
+:102AD00081B200000400004081B200000400004008
+:102AE00081B200000400004081B2000004000040F8
+:102AF00081B200000400004081B2000004000040E8
+:102B000081B200000400004081B2000004000040D7
+:102B100081B200000400004081B2000004000040C7
+:102B200081B200000400004081B2000004000040B7
+:102B300081B200000400004081B2000004000040A7
+:102B400081B200000400004081B200000400004097
+:102B500081B200000400004081B200000400004087
+:102B600081B200000400004081B200000400004077
+:102B700081B200000400004081B200000400004067
+:102B800081B200000400004081B200000400004057
+:102B900081B200000400004081B200000400004047
+:102BA00081B200000400004081B200000400004037
+:102BB00081B200000400004081B200000400004027
+:102BC00081B200000400004081B200000400004017
+:102BD00081B200000400004081B200000400004007
+:102BE00081B200000400004081B2000004000040F7
+:102BF00081B200000400004081B2000004000040E7
+:102C000081B200000400004081B2000004000040D6
+:102C100081B200000400004081B2000004000040C6
+:102C200081B200000400004081B2000004000040B6
+:102C300081B200000400004081B2000004000040A6
+:102C400081B200000400004081B200000400004096
+:102C500081B200000400004081B200000400004086
+:102C600081B200000400004081B200000400004076
+:102C700081B200000400004081B200000400004066
+:102C800081B200000400004081B200000400004056
+:102C900081B200000400004081B200000400004046
+:102CA00081B200000400004081B200000400004036
+:102CB00081B200000400004081B200000400004026
+:102CC00081B200000400004081B200000400004016
+:102CD00081B200000400004081B200000400004006
+:102CE00081B200000400004081B2000004000040F6
+:102CF00081B200000400004081B2000004000040E6
+:102D000081B200000400004081B2000004000040D5
+:102D100081B200000400004081B2000004000040C5
+:102D200081B200000400004081B2000004000040B5
+:102D300081B200000400004081B2000004000040A5
+:102D400081B200000400004081B200000400004095
+:102D500081B200000400004081B200000400004085
+:102D600081B200000400004081B200000400004075
+:102D700081B200000400004081B200000400004065
+:102D800081B200000400004081B200000400004055
+:102D900081B200000400004081B200000400004045
+:102DA00081B200000400004081B200000400004035
+:102DB00081B200000400004081B200000400004025
+:102DC00081B200000400004081B200000400004015
+:102DD00081B200000400004081B200000400004005
+:102DE00081B200000400004081B2000004000040F5
+:102DF00081B200000400004081B2000004000040E5
+:102E000081B200000400004081B2000004000040D4
+:102E100081B200000400004081B2000004000040C4
+:102E200081B200000400004081B2000004000040B4
+:102E300081B200000400004081B2000004000040A4
+:102E400081B200000400004081B200000400004094
+:102E500081B200000400004081B200000400004084
+:102E600081B200000400004081B200000400004074
+:102E700081B200000400004081B200000400004064
+:102E800081B200000400004081B200000400004054
+:102E900081B200000400004081B200000400004044
+:102EA00081B200000400004081B200000400004034
+:102EB00081B200000400004081B200000400004024
+:102EC00081B200000400004081B200000400004014
+:102ED00081B200000400004081B200000400004004
+:102EE00081B200000400004081B2000004000040F4
+:102EF00081B200000400004081B2000004000040E4
+:102F000081B200000400004081B2000004000040D3
+:102F100081B200000400004081B2000004000040C3
+:102F200081B200000400004081B2000004000040B3
+:102F300081B200000400004081B2000004000040A3
+:102F400081B200000400004081B200000400004093
+:102F500081B200000400004081B200000400004083
+:102F600081B200000400004081B200000400004073
+:102F700081B200000400004081B200000400004063
+:102F800081B200000400004081B200000400004053
+:102F900081B200000400004081B200000400004043
+:102FA00081B200000400004081B200000400004033
+:102FB00081B200000400004081B200000400004023
+:102FC00081B200000400004081B200000400004013
+:102FD00081B200000400004081B200000400004003
+:102FE00081B200000400004081B2000004000040F3
+:102FF00081B200000400004081B2000004000040E3
+:1030000081B200000400004081B2000004000040D2
+:1030100081B200000400004081B2000004000040C2
+:1030200081B200000400004081B2000004000040B2
+:1030300081B200000400004081B2000004000040A2
+:1030400081B200000400004081B200000400004092
+:1030500081B200000400004081B200000400004082
+:1030600081B200000400004081B200000400004072
+:1030700081B200000400004081B200000400004062
+:1030800081B200000400004081B200000400004052
+:1030900081B200000400004081B200000400004042
+:1030A00081B200000400004081B200000400004032
+:1030B00081B200000400004081B200000400004022
+:1030C00081B200000400004081B200000400004012
+:1030D00081B200000400004081B200000400004002
+:1030E00081B200000400004081B2000004000040F2
+:1030F00081B200000400004081B2000004000040E2
+:1031000081B200000400004081B2000004000040D1
+:1031100081B200000400004081B2000004000040C1
+:1031200081B200000400004081B2000004000040B1
+:1031300081B200000400004081B2000004000040A1
+:1031400081B200000400004081B200000400004091
+:1031500081B200000400004081B200000400004081
+:1031600081B200000400004081B200000400004071
+:1031700081B200000400004081B200000400004061
+:1031800081B200000400004081B200000400004051
+:1031900081B200000400004081B200000400004041
+:1031A00081B200000400004081B200000400004031
+:1031B00081B200000400004081B200000400004021
+:1031C00081B200000400004081B200000400004011
+:1031D00081B200000400004081B200000400004001
+:1031E00081B200000400004081B2000004000040F1
+:1031F00081B200000400004081B2000004000040E1
+:1032000081B200000400004081B2000004000040D0
+:1032100081B200000400004081B2000004000040C0
+:1032200081B200000400004081B2000004000040B0
+:1032300081B200000400004081B2000004000040A0
+:1032400081B200000400004081B200000400004090
+:1032500081B200000400004081B200000400004080
+:1032600081B200000400004081B200000400004070
+:1032700081B200000400004081B200000400004060
+:1032800081B200000400004081B200000400004050
+:1032900081B200000400004081B200000400004040
+:1032A00081B200000400004081B200000400004030
+:1032B00081B200000400004081B200000400004020
+:1032C00081B200000400004081B200000400004010
+:1032D00081B200000400004081B200000400004000
+:1032E00081B200000400004081B2000004000040F0
+:1032F00081B200000400004081B2000004000040E0
+:1033000081B200000400004081B2000004000040CF
+:1033100081B200000400004081B2000004000040BF
+:1033200081B200000400004081B2000004000040AF
+:1033300081B200000400004081B20000040000409F
+:1033400081B200000400004081B20000040000408F
+:1033500081B200000400004081B20000040000407F
+:1033600081B200000400004081B20000040000406F
+:1033700081B200000400004081B20000040000405F
+:1033800081B200000400004081B20000040000404F
+:1033900081B200000400004081B20000040000403F
+:1033A00081B200000400004081B20000040000402F
+:1033B00081B200000400004081B20000040000401F
+:1033C00081B200000400004081B20000040000400F
+:1033D00081B200000400004081B2000004000040FF
+:1033E00081B200000400004081B2000004000040EF
+:1033F00081B200000400004081B2000004000040DF
+:1034000081B200000400004081B2000004000040CE
+:1034100081B200000400004081B2000004000040BE
+:1034200081B200000400004081B2000004000040AE
+:1034300081B200000400004081B20000040000409E
+:1034400081B200000400004081B20000040000408E
+:1034500081B200000400004081B20000040000407E
+:1034600081B200000400004081B20000040000406E
+:1034700081B200000400004081B20000040000405E
+:1034800081B200000400004081B20000040000404E
+:1034900081B200000400004081B20000040000403E
+:1034A00081B200000400004081B20000040000402E
+:1034B00081B200000400004081B20000040000401E
+:1034C00081B200000400004081B20000040000400E
+:1034D00081B200000400004081B2000004000040FE
+:1034E00081B200000400004081B2000004000040EE
+:1034F00081B200000400004081B2000004000040DE
+:1035000081B200000400004081B2000004000040CD
+:1035100081B200000400004081B2000004000040BD
+:1035200081B200000400004081B2000004000040AD
+:1035300081B200000400004081B20000040000409D
+:1035400081B200000400004081B20000040000408D
+:1035500081B200000400004081B20000040000407D
+:1035600081B200000400004081B20000040000406D
+:1035700081B200000400004081B20000040000405D
+:1035800081B200000400004081B20000040000404D
+:1035900081B200000400004081B20000040000403D
+:1035A00081B200000400004081B20000040000402D
+:1035B00081B200000400004081B20000040000401D
+:1035C00081B200000400004081B20000040000400D
+:1035D00081B200000400004081B2000004000040FD
+:1035E00081B200000400004081B2000004000040ED
+:1035F00081B200000400004081B2000004000040DD
+:1036000081B200000400004081B2000004000040CC
+:1036100081B200000400004081B2000004000040BC
+:1036200081B200000400004081B2000004000040AC
+:1036300081B200000400004081B20000040000409C
+:1036400081B200000400004081B20000040000408C
+:1036500081B200000400004081B20000040000407C
+:1036600081B200000400004081B20000040000406C
+:1036700081B200000400004081B20000040000405C
+:1036800081B200000400004081B20000040000404C
+:1036900081B200000400004081B20000040000403C
+:1036A00081B200000400004081B20000040000402C
+:1036B00081B200000400004081B20000040000401C
+:1036C00081B200000400004081B20000040000400C
+:1036D00081B200000400004081B2000004000040FC
+:1036E00081B200000400004081B2000004000040EC
+:1036F00081B200000400004081B2000004000040DC
+:1037000081B200000400004081B2000004000040CB
+:1037100081B200000400004081B2000004000040BB
+:1037200081B200000400004081B2000004000040AB
+:1037300081B200000400004081B20000040000409B
+:1037400081B200000400004081B20000040000408B
+:1037500081B200000400004081B20000040000407B
+:1037600081B200000400004081B20000040000406B
+:1037700081B200000400004081B20000040000405B
+:1037800081B200000400004081B20000040000404B
+:1037900081B200000400004081B20000040000403B
+:1037A00081B200000400004081B20000040000402B
+:1037B00081B200000400004081B20000040000401B
+:1037C00081B200000400004081B20000040000400B
+:1037D00081B200000400004081B2000004000040FB
+:1037E00081B200000400004081B2000004000040EB
+:1037F00081B200000400004081B2000004000040DB
+:1038000081B200000400004081B2000004000040CA
+:1038100081B200000400004081B2000004000040BA
+:1038200081B200000400004081B2000004000040AA
+:1038300081B200000400004081B20000040000409A
+:1038400081B200000400004081B20000040000408A
+:1038500081B200000400004081B20000040000407A
+:1038600081B200000400004081B20000040000406A
+:1038700081B200000400004081B20000040000405A
+:1038800081B200000400004081B20000040000404A
+:1038900081B200000400004081B20000040000403A
+:1038A00081B200000400004081B20000040000402A
+:1038B00081B200000400004081B20000040000401A
+:1038C00081B200000400004081B20000040000400A
+:1038D00081B200000400004081B2000004000040FA
+:1038E00081B200000400004081B2000004000040EA
+:1038F00081B200000400004081B2000004000040DA
+:1039000081B200000400004081B2000004000040C9
+:1039100081B200000400004081B2000004000040B9
+:1039200081B200000400004081B2000004000040A9
+:1039300081B200000400004081B200000400004099
+:1039400081B200000400004081B200000400004089
+:1039500081B200000400004081B200000400004079
+:1039600081B200000400004081B200000400004069
+:1039700081B200000400004081B200000400004059
+:1039800081B200000400004081B200000400004049
+:1039900081B200000400004081B200000400004039
+:1039A00081B200000400004081B200000400004029
+:1039B00081B200000400004081B200000400004019
+:1039C00081B200000400004081B200000400004009
+:1039D00081B200000400004081B2000004000040F9
+:1039E00081B200000400004081B2000004000040E9
+:1039F00081B200000400004081B2000004000040D9
+:103A000081B200000400004081B2000004000040C8
+:103A100081B200000400004081B2000004000040B8
+:103A200081B200000400004081B2000004000040A8
+:103A300081B200000400004081B200000400004098
+:103A400081B200000400004081B200000400004088
+:103A500081B200000400004081B200000400004078
+:103A600081B200000400004081B200000400004068
+:103A700081B200000400004081B200000400004058
+:103A800081B200000400004081B200000400004048
+:103A900081B200000400004081B200000400004038
+:103AA00081B200000400004081B200000400004028
+:103AB00081B200000400004081B200000400004018
+:103AC00081B200000400004081B200000400004008
+:103AD00081B200000400004081B2000004000040F8
+:103AE00081B200000400004081B2000004000040E8
+:103AF00081B200000400004081B2000004000040D8
+:103B000081B200000400004081B2000004000040C7
+:103B100081B200000400004081B2000004000040B7
+:103B200081B200000400004081B2000004000040A7
+:103B300081B200000400004081B200000400004097
+:103B400081B200000400004081B200000400004087
+:103B500081B200000400004081B200000400004077
+:103B600081B200000400004081B200000400004067
+:103B700081B200000400004081B200000400004057
+:103B800081B200000400004081B200000400004047
+:103B900081B200000400004081B200000400004037
+:103BA00081B200000400004081B200000400004027
+:103BB00081B200000400004081B200000400004017
+:103BC00081B200000400004081B200000400004007
+:103BD00081B200000400004081B2000004000040F7
+:103BE00081B200000400004081B2000004000040E7
+:103BF00081B200000400004081B2000004000040D7
+:103C000081B200000400004081B2000004000040C6
+:103C100081B200000400004081B2000004000040B6
+:103C200081B200000400004081B2000004000040A6
+:103C300081B200000400004081B200000400004096
+:103C400081B200000400004081B200000400004086
+:103C500081B200000400004081B200000400004076
+:103C600081B200000400004081B200000400004066
+:103C700081B200000400004081B200000400004056
+:103C800081B200000400004081B200000400004046
+:103C900081B200000400004081B200000400004036
+:103CA00081B200000400004081B200000400004026
+:103CB00081B200000400004081B200000400004016
+:103CC00081B200000400004081B200000400004006
+:103CD00081B200000400004081B2000004000040F6
+:103CE00081B200000400004081B2000004000040E6
+:103CF00081B200000400004081B2000004000040D6
+:103D000081B200000400004081B2000004000040C5
+:103D100081B200000400004081B2000004000040B5
+:103D200081B200000400004081B2000004000040A5
+:103D300081B200000400004081B200000400004095
+:103D400081B200000400004081B200000400004085
+:103D500081B20000AE9F00889AB00000AE9F00883C
+:103D60009AB00000AE9F00889AB00000AE9F008815
+:103D70009AB00000AE9F00889AB000000000008852
+:103D80009AB00100AE9F414081320000B29F2240B4
+:103D90007B6F00000000194081B20100AE9F00401F
+:103DA00081B20000000019417BB30100000000A4B3
+:103DB000C4B30100000000A1C6B3010000002FA29F
+:103DC000C8B301000814004049990100A89F004DA4
+:103DD0009ACC0100BB9F2640813200000000004CBD
+:103DE00049C10100B99FA2419B500000BF9F808044
+:103DF0008032000000005249FD9301000000004A9B
+:103E0000FD930100C29F0042CD9300000000514A83
+:103E1000FD93010000000049FD930100C29F004393
+:103E2000CB9300000000504081B20100D29F0040BF
+:103E300019990100000000F09AB001000000004450
+:103E400049D10100000040F080B201000000414D66
+:103E500080B20100CA9F00401999010000004C4047
+:103E600081B201000000004449D10100000000F0CF
+:103E70009AB001000000004D10B10000000000E207
+:103E800049B10100000000E343B10100000000E47B
+:103E900045B10100000000407BB301000000484F25
+:103EA00040B10100D29F004081B2000004000040F8
+:103EB00081B200000400004081B200000400004014
+:103EC00081B200000400004081B200000400004004
+:103ED00081B20000040000CB81C8010022830040B1
+:103EE000F29300005582004081B20000400500407E
+:103EF00081B200001806004081B200002283004019
+:103F000081B20000C682004081B2000043810040BF
+:103F100081B200004181004081B20000B8800040C1
+:103F200081B20000F087004081B20000238300408E
+:103F300081B200002783004081B20000BF9400409E
+:103F400081B200009498004081B200007F9400404C
+:103F500081B200007F98004081B200008D95004042
+:103F600081B200001695004081B20000109500401B
+:103F700081B20000B182004081B20000209900406F
+:103F800081B200000400004081B200000400004043
+:103F900081B200000400004081B200000400004033
+:103FA00081B200000400004081B200000400004023
+:103FB00081B200000400004081B200000400004013
+:103FC00081B200000400004081B200000400004003
+:103FD00081B200000400004081B2000004000040F3
+:103FE00081B200000400004081B2000004000040E3
+:103FF00081B200000400004081B2000004000040D3
+:1040000081B200000400004081B2000004000040C2
+:0440100081B2000079
+:00000001FF
diff --git a/firmware/slicoss/oasisdownload.sys.ihex b/firmware/slicoss/oasisdownload.sys.ihex
new file mode 100644
index 0000000..82026c2
--- /dev/null
+++ b/firmware/slicoss/oasisdownload.sys.ihex
@@ -0,0 +1,5124 @@
+:1000000002000000004000000000010000000000AD
+:10001000008000001500004081B200001B0000407D
+:1000200081B200002100004081B2000003000040C6
+:1000300081B20000000000A898B001000480A24036
+:10004000FD7F00000900A249DD7D00000000004C9A
+:1000500080B2010007000040D1B100000000004C58
+:1000600080B201000900A240757D000060000040E0
+:10007000619901000B00A8B17E3100000900004029
+:1000800081B2000000808F981831000010000098A5
+:1000900080E40100000041988094010000000040CD
+:1000A00081B201001000009880E401000E00409829
+:1000B000809400001100004081B200000000004068
+:1000C000A59901001900294081320000190014BCD3
+:1000D000803200000E0093BC8032000000005040CF
+:1000E00081B201000080004081B200001000004099
+:1000F000A59901001F002940813200001F0014BC97
+:1001000080320000120093BC80320000000050409A
+:1001100081B201000180004081B200002000004057
+:10012000A59901002500294081320000250014BC5A
+:1001300080320000140093BC8032000000000049AF
+:10014000DD810100120100408132010033010040D5
+:10015000813201002A0014BC80320000FE0013BC72
+:10016000803200005495004045990100FFFF004097
+:10017000E599010000002F4049B101000000004056
+:10018000E1B1010000000040FDB3010000000040AB
+:10019000FFB30100330018EE803200000000005071
+:1001A00089B001003200A24189500000990000404E
+:1001B000813201003094004043990100000000F8B2
+:1001C00020B10100000000FAE0B30100390098EE10
+:1001D00080320000000000FB80B001003B0080F393
+:1001E000DE33000000000047FD9301003E0083F372
+:1001F00080320000F00000F38088010001800040A0
+:100200002EDD0100009400404399010000000046EB
+:1002100043C10100000000FA24B101007C0018EE87
+:1002200080320000450095E880320000FFFF00E8C2
+:10023000808801007C0026408132000000000040E0
+:10024000D5990100000000F2ECB30100000000F8B5
+:10025000D6B1010008000040D5990100000000F06F
+:10026000D6B10100FF0000F8EE8B0100080100404C
+:10027000D5990100FF0000F0808C0100000000F71C
+:100280008194010000000040D6B10100FF0000F899
+:10029000808801003C000040D5990100FF0000F07B
+:1002A000D68D0100FFFF00F0F0DB010000000048E8
+:1002B00081E00100000000F8819401003C01004051
+:1002C000D599010000000040D6B10100FF0000F800
+:1002D000808801000000004881E00100000000F873
+:1002E000819401003C020040D599010000000040CB
+:1002F000D6B101002C000040D5990100000000F8A3
+:10030000D6B101001E0000F082F40100FF3F00F8AA
+:1003100080D80100640026408132000000000041C6
+:1003200081D00100FFFF004080D8010000000041A3
+:100330008094010000000040D8B10100680022FA5A
+:10034000803000000000004C81E00100010000400E
+:1003500080CC010000000040DEB10100000100403F
+:10036000D5990100100000FA80E40100000000F6B9
+:100370008194010000000040D6B10100000200405D
+:10038000D5990100100000FA80E40100000000F699
+:100390008194010000000040D6B101000600004039
+:1003A000D5990100100000FBD6E5010007000040D0
+:1003B000D5990100180000FBD6E501004800004077
+:1003C000D5990100100000FAD6E501005000004068
+:1003D000D5990100100000FBD6E50100030000FBE9
+:1003E0007A890100000000F0DCB101007C00004CC3
+:1003F000DD9100007C0095E88430000000002FE9CA
+:10040000FAB3010000000040D1B10100FF0000423A
+:10041000808801003400004080CE01007C00A640AE
+:1004200081320000850000408132010002802240BC
+:10043000803200007C00004081B200000000004FCC
+:1004400081B001008E0009F9813200008C0008F9AA
+:100450008132000098001FFDF93300008B009EFDE3
+:10046000813200000000004AF39301000000804840
+:10047000F3930100000000FDF7B301000000804984
+:10048000F3930100000000FC19B1010093000AF988
+:1004900081320000000040FB81B20100000041FDFC
+:1004A00081B20100000780F9F38F0100000742F9D3
+:1004B000F38F01009700A2FFF76F00000000434098
+:1004C00081B201000000A2FFFBEF0000000080FCF1
+:1004D000E1B101000000804081B0010000940040C3
+:1004E00047990100BB000040813201000000A24694
+:1004F000FD7F01000094004047990100CE000040BC
+:10050000813201000000A244FD7F01000094004000
+:100510004599010000000040F1B10100FF7F00405B
+:10052000F5990100FF7F0040F59901009A13004002
+:10053000F599010007000040F59901000100004015
+:10054000F599010000020040F59901000200004009
+:10055000F599010000020040F599010003010040F7
+:10056000F599010000000040F59901009A13004040
+:10057000F59901000B000040F59901008000004052
+:10058000F599010000000040F599010000000040CD
+:10059000F599010007000040F599010008000040AE
+:1005A000F5990100B0020040F599010000000040FB
+:1005B000F599010000000040F59901000229004072
+:1005C000F599010000000040F59901000067004026
+:1005D000F599010000000040F599010080000040FD
+:1005E000F599010000008040F599010000000045E8
+:1005F000FD83010000000046FD830100FF7F0040F5
+:1006000025990100C4000040813201000000A2448D
+:1006100080B2000000000045FD930100E2000040B0
+:10062000833001000000A2458032010000008046B6
+:10063000FD9301000010004083980100DD000040A0
+:100640002B3101000000A24688B0000000000041EC
+:1006500089B00100000000948CB00100FFFF00464B
+:1006600080880100A5A5A24080CE000000000048BF
+:100670008DF00100C90082418940000000008040E7
+:1006800089B0010000000044FD830100D400004057
+:10069000813201000000A24480B20000E2000008A4
+:1006A000833001000000A245803201000000804438
+:1006B000FD93010000300008839801008000004095
+:1006C0002B990100DB000040893001000000A246A8
+:1006D00080B20000FFFF009480880100A5A5A24021
+:1006E000804E01000000804389B001000384004176
+:1006F0002C990100DE00004081B200000388004117
+:100700002C990100000000208DB0010000009F9690
+:1007100080B20000DF00A2418D5000000000804048
+:1007200081B20100FF7F0040259901000000004CCC
+:1007300089E00100DD000044821401000000909473
+:100740008AB0000000000045F0B101001000004533
+:1007500088F401000000004489D00100DD0000445D
+:100760002B410100EC00084180320000ED000094B4
+:1007700024B100001000009424F501000000009452
+:10078000F0B10100F200A04489500000DD000044F7
+:100790002B41010000000094F0B10100EF00204463
+:1007A000895000001000004588F40100000000FAA4
+:1007B0008AB001000000A34289D00000F700A0FA2F
+:1007C0008A400000000000418BC00100F500A342F8
+:1007D00089500000FFFF0045888801001000004597
+:1007E0008AF40100FC0090448A40000000000041AF
+:1007F0008BC00100FFFF00458AA801000000805067
+:100800008BE00100FF7F0040259901007C00004043
+:100810002B9901000030004083980100DD000008A2
+:1008200083140100000000942AB101000080004000
+:10083000F99B0100DD0000FC19310100000040942B
+:1008400080B20100DD0000442B4101000000419412
+:1008500080B2010000000041F9C301000000004423
+:100860002BC1010004019F948032000002800040EF
+:1008700081B200001001005193B000001001004D42
+:1008800093B000001001004993B000000000004246
+:1008900093B001001001A24193500000000080407D
+:1008A00081B201000000104081B20100000011403F
+:1008B00081B201000000124081B20100000013402B
+:1008C00081B201000000144081B201000000154017
+:1008D00081B201000000164081B201000000174003
+:1008E00081B201000000184081B2010000001940EF
+:1008F00081B2010000001A4081B2010000001B40DB
+:1009000081B2010000001C4081B2010000001D40C6
+:1009100081B2010000001E4081B2010000001F40B2
+:1009200081B201000000704081B2010000007140FE
+:1009300081B201000000724081B2010000007340EA
+:1009400081B201000000744081B2010000007540D6
+:1009500081B201000000764081B2010000007740C2
+:1009600081B201000000784081B2010000007940AE
+:1009700081B2010000007A4081B2010000007B409A
+:1009800081B2010000007C4081B2010000007D4086
+:1009900081B2010000007E4081B2010000007F4072
+:1009A00081B201000000804081B2010000040040DB
+:1009B000A199010000000050A1D1010000000040F9
+:1009C0001BB001000000004019B001000000004011
+:1009D00017B001000000004015B001000000004009
+:1009E00013B001000000004011B001000000004001
+:1009F0000FB00100000000400DB0010000000040F9
+:100A00000BB001000000004009B0010000000040F0
+:100A100007B001000000004005B0010000000040E8
+:100A200003B001000000004001B001003B0120487C
+:100A3000A15100000000804081B201004701224B1B
+:100A4000747D00000000804081B201006000004B16
+:100A500060990100000000B17EB101004801A8408A
+:100A6000813200004501004081B200000500804055
+:100A700097980100180000AA9688010000008043A2
+:100A800097F00100070000AA96880100000080404E
+:100A900081B201000000005807900100D89F00407B
+:100AA00081B2000000000044A5B30100D80200405C
+:100AB00081320100F8020040813201000000005C38
+:100AC00007900100D89F0040BFB300005A0122CC1C
+:100AD000857F00000000005107900100D89F004072
+:100AE00081B200000000004049B10100AE0300CB1C
+:100AF000A3C90100D0140040A19B01000000002008
+:100B000046B1010000000048F1B10100000000D032
+:100B1000F1B10100000000CAF1B10100000000D5F0
+:100B2000E1B10100070000406199010020000020B0
+:100B300062DD01006301A84081320000000000CCAA
+:100B400085930100F802004081320100D01400407A
+:100B500043990100000000FABAB30100000000FA56
+:100B6000A4B30100000000F8BCB3010000142F4042
+:100B700081B00100000000E7A7B30100000000D829
+:100B8000A9B30100FF0000DD8188010002000040E0
+:100B900080F401007301004080C80100860100DD7F
+:100BA000813200000000004010B1000087010040C9
+:100BB00081B200008801004081B20000890100403C
+:100BC00081B200008A01004081B200008B01004028
+:100BD00081B200008D01004081B200008F01004011
+:100BE00081B200005001004081B20000B601004017
+:100BF00081B200005001004081B20000C4010040F9
+:100C000081B20000C501004081B2000082020040B4
+:100C100081B200008302004081B22800B802004087
+:100C200081B22800D49F004081B22800D59F0040A7
+:100C300081B22800D69F004081B22800D79F004093
+:100C400081B228007201004181C02800550151493C
+:100C5000FD9328005501524AFD932A00550155493C
+:100C6000FD832A005501564AFD832A0050019181D7
+:100C700080302A005501454081B22A0050019182FE
+:100C800080302A005501464081B22A000000004011
+:100C900089B02B0000002F4081B0010000140040FB
+:100CA00049990100B30122DEE16D00000000004C13
+:100CB00049C101000000004181C001009201A2442D
+:100CC000816C00000000004C49D101009A012240D3
+:100CD000E16D00009601A2418150000050010041E9
+:100CE000BFB3000000000042BFB301005001A00FDD
+:100CF000BD6F0000000000DEE1B101000000004413
+:100D000049C10100B50100401999010000004240AD
+:100D100081B20100000043FF85B00100000000DE49
+:100D200019B10100000042FF87B00100000043FF3D
+:100D3000E1B101000000004449C1010000002FFFA3
+:100D4000E1B10100081400A480CC0100AA012640F2
+:100D5000813200000000004185C00100A801A24CC2
+:100D600081500000B40122D281320000AF01224143
+:100D7000A56F00005001A2E081320000000000D207
+:100D8000C1B301000000005C8990010000004042F6
+:100D900080B201000000414380B20100000000F079
+:100DA0008894010055010044E0B10000B101004801
+:100DB00049C10000AF01005B89900000A89F00A01E
+:100DC0009EB000000000004083B00100001400400D
+:100DD000499901000000234081B00100BE0122DEDC
+:100DE000E16D00000000004C49C10100000000411D
+:100DF00081C00100B901A244816C00005001004390
+:100E0000BFB30000000000F818B10100000040F876
+:100E100080B20100000041F080B2010000000040FB
+:100E2000F1B1010000000040F1B1010055010040A6
+:100E3000E1B10000C601004091B000000000004197
+:100E400091B00100D0142E4049B1010005000040CE
+:100E5000A39B0100080000DD81F40100CB010040EC
+:100E600080C801000000004010B10000D101004026
+:100E700081B00000530100DEA1B30000E301004097
+:100E800081B20000E501004081B00000EB010040AC
+:100E900081B20000520100DFE1B10000000000D08B
+:100EA000BAB30100000000DEA1B10100020000D2CF
+:100EB000A5E70100000000D2C1B30100000000005E
+:100EC000F0B10100DB012244C1530000DA0184418A
+:100ED00081400000DE01004081320100000000D0AE
+:100EE00045B10100D5010041A1C10000DA02004076
+:100EF00081320100F802004081320100550100DD1D
+:100F0000A1B100000000004081B00100400000409D
+:100F1000A59B0100DA02004081320100400000D3AD
+:100F2000A7CB0100F80200E0A5B3000003000040D9
+:100F3000A39B0100530100DEA1B3000000000044A8
+:100F4000BFB30100000000DE819001005001A2BA91
+:100F500080040000600000DE61990100E801A8B192
+:100F60008030000052010040E0B10000000000D0DD
+:100F7000BAB301006B020040819801006002004D8D
+:100F80008330010000000044E1B301000000004490
+:100F9000E3B3010000000044E5B301000000004499
+:100FA000E9B3010000000044EBB30100000000447D
+:100FB000F5B3010000000044F7B301000000004455
+:100FC000F9B30100F90122408F6F00007802004060
+:100FD00081980100600200C7833001008002004058
+:100FE000819801006002004283300100000000E8A7
+:100FF000F1B10100000000E9F1B10100000000EAD8
+:10100000F1B10100000000EBF1B10100000000852A
+:10101000F0B10100000000ECF1B10100000000EDB2
+:10102000F1B10100000000B2F0B10100000000A920
+:10103000F0B10100000000ACF0B10100000000AB15
+:10104000F0B10100000000B8F0B10100000000B9EB
+:10105000F0B10100000000BAF0B10100000000BBD7
+:10106000F0B101000C02B8408130000000000040E7
+:10107000819001000E02B940813200000000004161
+:10108000819001001002BA4081320000000000424D
+:10109000819001001202BB40813200000000004339
+:1010A000819001001402BC40813200000000004425
+:1010B000819001001602BD40813200000000004511
+:1010C000819001001802BE408132000000000046FD
+:1010D000819001001A02BF408132000000000047E9
+:1010E000819001001C02C8408132000000000048CD
+:1010F000819001001E02C9408132000000000049B9
+:10110000819001002002CA40813200000000004AA4
+:10111000819001002202CB40813200000000004B90
+:10112000819001002402CC40813200000000004C7C
+:10113000819001002602CD40813200000000004D68
+:10114000819001002802CE40813200000000004E54
+:10115000819001002A02CF40813200000000004F40
+:10116000819001002C02F04081320000000000500C
+:10117000819001002E02F1408132000000000051F8
+:10118000819001003002F2408132000000000052E4
+:10119000819001003202F3408132000000000053D0
+:1011A000819001003402F4408132000000000054BC
+:1011B000819001003602F5408132000000000055A8
+:1011C000819001003802F640813200000000005694
+:1011D000819001003A02F740813200000000005780
+:1011E000819001003C02F84081320000000000586C
+:1011F000819001003E02F940813200000000005958
+:10120000819001004002FA40813200000000005A43
+:10121000819001004202FB40813200000000005B2F
+:10122000819001004402FC40813200000000005C1B
+:10123000819001004602FD40813200000000005D07
+:10124000819001004802FE40813200000000005EF3
+:10125000819001004A02FF40813200000000005FDF
+:101260008190010000000040F0B10100400000400A
+:10127000A59B0100D802004081320100F802004025
+:1012800081320100D0142E06A5B30100400000D326
+:10129000A7CB0100000000F0F1B10100000000F157
+:1012A000F1B10100000000F2F1B10100000000F412
+:1012B000F1B10100000000F5F1B10100000000FAF9
+:1012C000F1B10100000000FBF1B10100000000FCE1
+:1012D000F1B10100000000EBF1B10100000000EEEF
+:1012E000F1B10100000000EFF1B10100000000F3D6
+:1012F000F1B10100000000F6F1B10100000000FDB5
+:10130000F1B10100DB0100C7E1B100000000804045
+:1013100081B20100660200488032000000005140A6
+:101320001AB1010000004D4081B2010000004540AB
+:1013300081B201006302A241835000005F02494074
+:1013400081B20000000052401CB1010000004E407C
+:1013500081B201000000464081B201006802A24152
+:10136000835000005F024A4081B20000000000A0EC
+:101370009EB0010000000080D8B30100000000A171
+:10138000D0B30100000000A2D2B30100000000A40D
+:10139000D4B30100000000D0D6B30100000000D19A
+:1013A000DCB30100000000D2DEB3010000000088C1
+:1013B000DAB30100000000D48EB30100000000D3B6
+:1013C000E6B30100000000ACECB30100000000999E
+:1013D000FAB30100000000D5E0B30100000000D521
+:1013E000E2B30100000000D5E4B30100000000D525
+:1013F000E8B30100000000D5EAB30100000000D509
+:10140000F4B30100000000D5F6B30100000000D5E0
+:10141000F8B30100000000C7A9B101000000004FAF
+:1014200040B101008402004091B000000000004182
+:1014300091B0010007000040A39B0100080000DDFF
+:1014400081F401008802004080C8010000000040D3
+:1014500010B100008D02004081B2000098020040EF
+:1014600081B2000098020046A3B300009B02004036
+:1014700081B20000A102004081B200008F0223501F
+:10148000A56F000000000050A5B30100E802004273
+:10149000A5630100F802004081320100D0142D4004
+:1014A00049B10100000000D0BAB30100000000DE25
+:1014B000A1B10100000000F800B001009702224431
+:1014C000A553000094020041A1C10000550100DDB8
+:1014D000A1B10000E80200DEA1330100F8020040E3
+:1014E000813201005501004081B20000000000453A
+:1014F000BFB301005001A2D2777D0000000000D2EE
+:1015000061B10100000000DE63B101009E02A8404D
+:10151000813200005501004081B20000E802005411
+:10152000A5330100F802004081320100D0142D40A3
+:1015300049B10100000000F8D0B30100000000F83C
+:10154000D2B30100000000F8D4B30100000000F89D
+:10155000D6B30100000000F808B10100AC02004061
+:10156000819801006002004683300100550100406F
+:1015700081B20000000000A09EB00100000000E861
+:1015800043B10100000000E945B10100000000EA9C
+:1015900049B10100000000EBA1B101000000004FC3
+:1015A00040B101000400004081B20000040000408E
+:1015B00081B200000400004081B20000040000403D
+:1015C00081B200000400004081B20000040000402D
+:1015D00081B20000D0142E4049B101000500004046
+:1015E000A39B010000000040C1B30100080000DD22
+:1015F00081F40100BD02004010C90000C3020005D3
+:1016000081B000005001004081B20000CB02000513
+:1016100081B000005001004081B20000D0020044BF
+:10162000A5B30000D2020044A5B3000002000040B0
+:10163000A4E70100000000E081B10100FFFF00C14C
+:10164000F0890100C802224181500000C40200411B
+:10165000C1C30000DA02004081320100F8020040FC
+:10166000813201005501004081B2000002000040BB
+:10167000A4E70100000000E091B10100FFFF00C9F4
+:10168000F0890100C802224181500000CC020041D3
+:10169000C1C30000FFFF00DE85890100C80200C24F
+:1016A000E0B10000FFFF00DE95890100C80200CA1A
+:1016B000E0B100000400004081B2000004000040DE
+:1016C00081B200000400004081B20000040000402C
+:1016D00081B20000000000E7A7B30100000000D8BD
+:1016E000A9B301000000004049B10100AE0300CBE6
+:1016F000A3C901000000002046B10100000000D293
+:10170000F1B10100000000D3F1B10100000000D4EC
+:10171000F1B10100000000D0E1B10100000000D1F2
+:1017200061B101002000002062DD0100E202A8405A
+:1017300081320000000080CC85930100040000404D
+:1017400081B200000400004081B2000004000040AB
+:1017500081B20000000000E7A7B30100000000D83C
+:10176000A9B301000000004049B10100AE0300CB65
+:10177000A3C901000000002046B10100000000D212
+:10178000F1B10100000000D0F1B10100000000D370
+:10179000F1B10100E10200D4E1B100000400004019
+:1017A00081B200000400004081B20000040000404B
+:1017B00081B200000400004081B20000040000403B
+:1017C00081B200000400004081B20000040000402B
+:1017D00081B200000000A2CC85FF00000000005094
+:1017E00081B00100FA02A24181500000F902A2F288
+:1017F00080300000000080CC8583010004000040A0
+:1018000081B200000400004081B2000004000040EA
+:1018100081B20000B5030040A199010000002F41F2
+:1018200099B301000A032244816C0000120322488C
+:10183000816C00000C03224C816C000016032250C6
+:10184000816C000017032254816C00001903225898
+:10185000816C00001E03225C816C0000500100407E
+:1018600081B20000000000BC09B00100DD9F00CA89
+:1018700001B000000000004003B001000000004182
+:10188000F38301001003A242056C00000000004138
+:1018900005B00100DD9F22CA07140000DD9F00454E
+:1018A000F3930000DD9F2043956F0000DD9F80CA09
+:1018B00005300000DD9F220180300000DD9F00CB5D
+:1018C000DB910000570100BCABB30000000000BC7E
+:1018D000B1B30100DD9F00CACFB30000FF0000CA12
+:1018E00081880100DD9FA240747D000060002040DF
+:1018F000609901001B03A8B1823000001A03004068
+:1019000081B20000DD9F00CA79B3000004000040EE
+:1019100081B200000000004E81B0010000000043D1
+:10192000CB8301000000454081B201002203A241A7
+:10193000815000000000454081B201000000454098
+:1019400081B201002D039182823000000000008AE4
+:1019500080B00100AE9F004080CE01002B03A64066
+:10196000813200002D03564081B20000B5030040D3
+:10197000A19901000000005307900100B503004049
+:10198000A19901000000005207900100D89F00417A
+:101990008BB300000000004E81B001000000004247
+:1019A000CD8301000000464081B201003203A24114
+:1019B000815000000000464081B201000000464016
+:1019C00081B201003D039181823000000000008956
+:1019D00080B00100AE9F004080CE01003B03A640D6
+:1019E000813200003D03554081B20000B503004044
+:1019F000A19901000000005207900100B5030040CA
+:101A0000A19901000000005307900100D89F0041F8
+:101A10008BB30000B0030040A1990100C4142F4013
+:101A200099B301005701004049B100000400004093
+:101A300081B200000400004081B2000004000040B8
+:101A400081B200000400004081B2000004000040A8
+:101A500081B200003094004043990100009000F8EA
+:101A600080980100100000F288E40100200000408E
+:101A7000209901000000005F239101004D031F9198
+:101A80008032000030000040209901000000005F1B
+:101A90002391010050031F9180320000400000405C
+:101AA000209901000000005F2391010053031F9162
+:101AB000803200000000005F2391010055031F9158
+:101AC000803200000008804020990100040000409E
+:101AD00081B200000000004784B001000000A2486D
+:101AE000848400000000005F61B101000000005C20
+:101AF0008F9001000000004762B101005A03A84026
+:101B000081320000000800478EC801005803005CC5
+:101B10008F800000E00000406199010058152D40C1
+:101B20008DB00100D0142DF088B00100000000FA43
+:101B30008AB001000000004581B0010007000045A7
+:101B400082880100000000438BF001000000004883
+:101B500083E0010000000046829401002000004163
+:101B600060990100000000418DC001007403225FF4
+:101B70008D6C00006503A2418150000063030040AA
+:101B800081B2000008000040859801000000004478
+:101B900082B001000000004186B00100001C00433B
+:101BA00086D801000000A641855001007003004165
+:101BB00083E000006E030040813201000000004815
+:101BC00085E00100D0142F468494010020000042DB
+:101BD00060990100C0000040619901000000804050
+:101BE00081B201000400004081B200000400004006
+:101BF00081B200000400004081B2000004000040F7
+:101C000081B200000400004081B2000004000040E6
+:101C100081B20000070000458088010000000043F9
+:101C20008BF0010000040040839801008503A0416F
+:101C3000815000008303004182E8000000008041E1
+:101C40008EC001000400004081B20000040000408A
+:101C500081B200000000004049B1010000020040D4
+:101C600083980100003900404599010000000040C0
+:101C7000F1B101008B03A24183500000000000403D
+:101C800085B001000B00004482F401001A1500A683
+:101C900086B0010070150040459901000008004021
+:101CA000F199010000000042F0B10100003900404C
+:101CB000E1990100040000406199010070150043A2
+:101CC000629901009503A840813200009703225ACF
+:101CD000737D00007A000040619901009803A8B16B
+:101CE0007E3100000008004284C801009003A24138
+:101CF000835000000000804081B2010004000040D9
+:101D000081B200000400004081B2000004000040E5
+:101D100081B2000058152D408DB00100D0142DF077
+:101D200088B00100000000408FB00100010000A653
+:101D300090B0010000F800489098010000000045B4
+:101D400093B00100000000FA8AB001008003004057
+:101D500081320100020000A680B00100AC032240E5
+:101D6000826C0000B0030040813201005803004043
+:101D700081320100000000418DC00100B503225FE7
+:101D80008D6C0000A703A24193500000A503004002
+:101D900081B20000FF070047848801000000A640D0
+:101DA00081B20000ED9F0047803001000002004733
+:101DB0008EC80100B003004081B200000000004462
+:101DC00050B30100BB032018896C0000040000A67A
+:101DD00084B00100200000A686B001000010004081
+:101DE000559B0100BE03004081B20000040000A624
+:101DF00084B00100200000A686B001000010004061
+:101E0000559B01000000004250D30100000000A8D3
+:101E10004FB30100000000434ED301006E030040A9
+:101E2000813201008203004280300100B003004093
+:101E300081320100C70322A78F6C00005A030040C3
+:101E400081320100C403004081B2000000008040E4
+:101E500081B20100C8142EBB85B00100000000EE65
+:101E600082B0010000000041E0B10100000000A2CA
+:101E7000A0B3010000000044A5B30100E19F00CA27
+:101E8000A7330100E09F004081B200000400004041
+:101E900081B20000D6032242756F0000D8032241B0
+:101EA000756F0000DA031ECA81320000DC031FCA0E
+:101EB00081320000000000CAC9B10100DD9F00426C
+:101EC00075B30000000000CACDB10100DD9F0041E4
+:101ED00075B30000000000CACFB10100DD9F0040D3
+:101EE00075B30000008100A6C6B10100DD9F00406F
+:101EF00081B20000008000A6C6B10100DD9F004055
+:101F000075B300000400004081B2000004000040EE
+:101F100081B200004501004D933001004501004EA3
+:101F2000933001004501004C93300100EC9F0040CC
+:101F300081320100DD9F004081B2000004000040BA
+:101F400081B200000400004081B2000004000040A3
+:101F500081B200005495004045990100DD9F00CA00
+:101F6000E5B100000400004081B200000400004020
+:101F700081B200000400004081B200000400004073
+:101F800081B200000400004081B200000400004063
+:101F900081B20000CC142E4087B00100000000A2E6
+:101FA000A0B3010015040043B2330100000068DA59
+:101FB00089B001007C0000408B98010000000050B7
+:101FC00089F001000000004189D0010003000044B5
+:101FD000888C01000000004487C00100000000411F
+:101FE000A5B3010015040043B2330100000000DA7C
+:101FF000F1B101000000004487C001000000004171
+:10200000A5C301000B042244895000000B042244A4
+:102010008B500000FA03A250A56F000000000042A0
+:10202000A5E30100000000CAA7B30100E19F00BBC7
+:1020300085300100CC142ED295C30100AE0300CB35
+:10204000A3C901000000002042B1010000000050BF
+:1020500081B001000804A241815000000704A2F2EF
+:1020600080300000FA030040A5B3000000000042E9
+:10207000A5E30100000000CAA7B30100E19F00BB77
+:1020800085300100E09F004081B200000400004064
+:1020900081B20000000000D92BB101000010004007
+:1020A00083980100DB00004081320100FFFF0094B3
+:1020B000B48B01000000804081B20100000000D913
+:1020C0002BB101000010004083980100DD000040AA
+:1020D0008132010000008094B4B30100040000408C
+:1020E00081B200000400004081B200000400004002
+:1020F00081B200000400004081B2000004000040F2
+:1021000081B200000400004081B2000004000040E1
+:1021100081B20000000000D92BB10100000000DAFC
+:1021200027B1010006C000402D990100DE000040EB
+:1021300081320100001000408398010002C4004178
+:102140002C990100DE000040813201000040004077
+:1021500083980100058200412C990100DE000040B7
+:10216000813201002D048094803200000C01004077
+:10217000813201002804004081B200000480004048
+:102180002D990100DE0000408132010000008040F6
+:1021900081B201003104001210C9000000488040E3
+:1021A0000B980100C04980400B980100804B804093
+:1021B0000B980100404D80400B980100004F80407B
+:1021C0000B980100C05080400B9801008052804065
+:1021D0000B980100405480400B980100005680404D
+:1021E0000B980100C05780400B9801008059804037
+:1021F0000B980100405B80400B980100005D80401F
+:102200000B980100C05E80400B9801008060804008
+:102210000B980100406280400B98010000648040F0
+:102220000B980100C06580400B98010080678040DA
+:102230000B980100406980400B980100006B8040C2
+:102240000B980100C06C80400B980100806E8040AC
+:102250000B980100407080400B9801000072804094
+:102260000B980100C07380400B980100807580407E
+:102270000B980100407780400B9801000079804066
+:102280000B980100C07A80400B980100807C804050
+:102290000B980100407E80400B9801000400004034
+:1022A00081B200000400004081B200000400004040
+:1022B00081B200000400004081B200000400004030
+:1022C00081B200000400004081B200000400004020
+:1022D00081B200005904001210C900000080804043
+:1022E0000B980100008280400B9801000084804020
+:1022F0000B980100008680400B9801000088804008
+:102300000B980100008A80400B980100008C8040EF
+:102310000B980100008E80400B98010000908040D7
+:102320000B980100009280400B98010000948040BF
+:102330000B980100009680400B98010000988040A7
+:102340000B980100009A80400B980100009C80408F
+:102350000B980100009E80400B98010000A0804077
+:102360000B98010000A280400B98010000A480405F
+:102370000B98010000A680400B98010000A8804047
+:102380000B98010000AA80400B98010000AC80402F
+:102390000B98010000AE80400B98010000B0804017
+:1023A0000B98010000B280400B98010000B48040FF
+:1023B0000B98010000B680400B98010000B88040E7
+:1023C0000B98010000BA80400B98010000BC8040CF
+:1023D0000B98010000BE80400B98010004000040F3
+:1023E00081B200000400004081B2000004000040FF
+:1023F00081B200000400004081B2000004000040EF
+:1024000081B200000400004081B2000004000040DE
+:1024100081B200000000004087B1010000000040D0
+:1024200097B001000000004B80B10100010000A640
+:1024300082B1010082048541974000000000004005
+:1024400097B101000000004097B001000000004B70
+:1024500090B10100010000A692B1010087048541FE
+:10246000974000000000804081B20100040000405D
+:1024700081B200000400004081B20000040000406E
+:1024800081B200000400004081B20000040000405E
+:1024900081B2000090046040813200000000001210
+:1024A00080B10100FFFFF04B82890100930460407E
+:1024B000813200000000004A80B101000100F0A656
+:1024C00082B101009604604081320000FFFF004BA2
+:1024D000848901000000F0C224B001000000004A1D
+:1024E00090B10100FFFF804B928901000000004A7B
+:1024F00090B10100010080A692B10100FFFF004BE6
+:1025000094890100000080CA94B0010004000040DA
+:1025100081B200001000004E98E4010000000007A6
+:10252000989401000000004399E001000000008041
+:10253000989401000000004999E001000000004C5F
+:1025400088940100A604474081320000AD04222097
+:10255000876F000000001F4081B2010000000040B2
+:1025600081B201000000004081B201000000004083
+:1025700081B20100A604004081B2000000001F806B
+:1025800086B30100B004224F777D0000C0040040F4
+:10259000813201000000004F61B1010000000044E1
+:1025A00062B10100B104A84081320000B804224B9E
+:1025B000897C0000B604224F777D0000C0040040F3
+:1025C000813201000000004562B10100B604A8405C
+:1025D000813200000000802087B301000400004029
+:1025E00081B200000400004081B2000004000040FD
+:1025F00081B200000400004081B2000004000040ED
+:1026000081B200000400004081B2000004000040DC
+:1026100081B200000000005099B001006F0000403E
+:1026200061990100C104A8B152330000C604224BD5
+:10263000537F00006F00004061990100C404A8B1FD
+:102640007E310000C104A241995000000000A24F59
+:1026500077FD00000400004081B20000040000404B
+:1026600081B200000400004081B20000040000407C
+:1026700081B200000400004081B20000040000406C
+:1026800081B200000400004081B20000040000405C
+:1026900081B200001000004E98E401000000000725
+:1026A000989401000000004399E0010000000080C0
+:1026B000989401000000004899E00100D604004C05
+:1026C00088940000D604474081320000DD042220B7
+:1026D000876F000000001F4081B201000000004031
+:1026E00081B201000000004081B201000000004002
+:1026F00081B20100D604004081B2000000001F80BA
+:1027000086B30100E004224F777D0000F004004012
+:10271000813201000000004F61B10100000000445F
+:1027200062B10100E104A84081320000E804224ABD
+:10273000897C0000E604224F777D0000F004004011
+:10274000813201000000004562B10100E604A840AA
+:10275000813200000000802087B3010004000040A7
+:1027600081B200000400004081B20000040000407B
+:1027700081B200000400004081B20000040000406B
+:1027800081B200000400004081B20000040000405B
+:1027900081B200000000005099B001006F000040BD
+:1027A00061990100F104A8B152330000F604224AF5
+:1027B000537F00006F00004061990100F404A8B14C
+:1027C0007E310000F104A241995000000000A24FA8
+:1027D00077FD00000400004081B2000004000040CA
+:1027E00081B200000400004081B2000004000040FB
+:1027F00081B200000400004081B2000004000040EB
+:1028000081B200000400004081B2000004000040DA
+:1028100081B200007B000040619901000005A8B171
+:102820008030000012051D4080320000401800403A
+:1028300049990100040000A686B001001005A240DD
+:1028400086040000DE9F9C4080320000FFFF0040B5
+:1028500088880100300500504731010036000044EF
+:1028600088CC01000C055240813200003005004048
+:10287000473101000000004189B0010030050048E7
+:10288000473101003005000547310100DE9F00405F
+:1028900081B200002800004047991B00DE9F0041E4
+:1028A000E1C11A007818004049991B00190522540B
+:1028B000817C1A001405424081321A00008200B364
+:1028C00067DF1B0000001A4493931B0028000040A0
+:1028D00047991B00300500418930010027050F4052
+:1028E00080320000FF7F00408888010030050050E2
+:1028F000473101003600004488CC01001F05994093
+:10290000803200000000004889D0010021059B4072
+:10291000803200000000004C89D0010023051F44D4
+:1029200080320000300500404731010000000041C6
+:1029300089B00100300500484731010030050058DA
+:1029400047310100DE9F004081B2000010000040CE
+:1029500086F401006F00004386880100DE9F260593
+:10296000473100003005004189300100DE9F004002
+:1029700081B200000400004081B200000400004069
+:1029800081B200000400004081B200000400004059
+:1029900081B200000000A044F041010000000040AE
+:1029A00081B2010000008041E1C10100040000404B
+:1029B00081B200000400004081B200000400004029
+:1029C00081B200000400004081B200000400004019
+:1029D00081B200004C010007913001000000A240CC
+:1029E00097EC00000000800591C001000400004049
+:1029F00081B200000400004081B2000004000040E9
+:102A000081B200000400004081B2000004000040D8
+:102A100081B200004C010040813201004405A24017
+:102A2000976C00003A000040B39B01004505004050
+:102A300081B2000040000040B39B01001004004040
+:102A400081320100000000DAF5B1010010040042FB
+:102A5000B3430100000000DAF5B1010010040042A8
+:102A6000B3430100000000DAF5B101004E00004060
+:102A7000B39B01001004004081320100080000DA1D
+:102A8000F7F5010050000040919801000000004758
+:102A90008FB0010010040048B2330100000000DADA
+:102AA000F7B10100080000DAF7F50100000000426C
+:102AB00091C001005005A2418F500000000000416C
+:102AC00045D1010008000040B39B01001004004004
+:102AD00081320100000000DAFDB101000A0000406F
+:102AE000B39B01001004004081320100000000DAB5
+:102AF000FDB101001A000040B39B0100100400402A
+:102B000081320100000000DAFDB101001800004030
+:102B1000B39B01001004004081320100000000DA84
+:102B2000FDB1010038050040813201001E0000485F
+:102B3000B2CB01001004004081320100000000DA35
+:102B400091C0010000000048B2CB01001004004019
+:102B50008132010000006EDA8FB0010002000048EF
+:102B6000B2CB01001004004081320100000000DA05
+:102B7000FDB1010004000048B2CB01001004004088
+:102B800081320100000080DAFDB101000400004044
+:102B900081B200007A052245FD7F0000401600400A
+:102BA00045990100DB9F00404931010008000048C1
+:102BB000B2CB010015040040813201007805A2402B
+:102BC0008F6C00007D052220B56F00007A05004063
+:102BD00081B20000DA9F004081321F007D05224053
+:102BE000976C1E007A05424081321E000000004FA3
+:102BF00067931F00DF9F005867931E005416004024
+:102C000047991F00000000FEF4B11F0000000040C3
+:102C100081B21F00000000FEF4B10100000000407E
+:102C200081B20100000000FEF4B10100000000408C
+:102C300081B20100000000FEF4B10100000000407C
+:102C400081B20100000000FEF4B10100000000406C
+:102C500081B20100000000FEF4B10100000000405C
+:102C600081B20100000000FEF4B101004600004006
+:102C7000B39B01001004004081320100080000DA1B
+:102C8000F7F501004800004095980100000000445D
+:102C900097B001001004004AB2330100000000DACE
+:102CA000F7B10100080000DAF7F50100000000426A
+:102CB00095C001009005A241975000002A000040F5
+:102CC000A59B010040160040A19B0100000000CA26
+:102CD000A7B30100E19F00BB85300100E09F0040E9
+:102CE00081B200000400004081B2000004000040F6
+:102CF00081B200000400004081B2000004000040E6
+:102D000081B200000400004081B2000004000040D5
+:102D100081B20000B8052245FD7F0000E0150040AB
+:102D2000479901001A0000A280DC01000000005059
+:102D3000F1B10100F0150040F1990100000000CA56
+:102D4000F1B101000700004061990100200000403E
+:102D500062DD0100A705A8BBE131000000000050C2
+:102D600083B00100AA05A24183500000A905A2F288
+:102D7000823000004C01004081320100B005A240C9
+:102D8000976C00003A000040B39B0100B105004081
+:102D900081B2000040000040B39B0100F0150040EC
+:102DA000439901001004004081320100B805A2FAE5
+:102DB000B46F000010040042B3430100B805A2FA4A
+:102DC000B46F000010040042B3430100BB0522FAB7
+:102DD000B46F0000B8054240813220000000004E70
+:102DE00067932100DF9F0058679320004016004042
+:102DF00045992100DB9F004049312100F615004034
+:102E0000439921005C1600404599210000006EFAAC
+:102E10008EB021000000004081B20100000000FEE1
+:102E2000F4B101000000004081B20100000000FE8A
+:102E3000F4B101000000004081B20100000000F088
+:102E4000B4B30100C905A2408F6C0000FC1520201E
+:102E5000E1B10100CE05004081B22400DA9F0040BC
+:102E600081322500CE052240976C2400CB054240DC
+:102E7000813224000000004F67932500DF9F005837
+:102E80006793240038050040813225001E00004869
+:102E9000B2CB25001004004081320100D30522503E
+:102EA000B56F00000000005091C001000000004814
+:102EB000B2CB0100F615004043990100200400F256
+:102EC000B433010002000048B2CB0100F815004005
+:102ED00043990100200400F2B433010004000048CB
+:102EE000B2CB0100FA15004043990100200400F222
+:102EF000B433010008000048B2CB0100FC150040CB
+:102F000043990100000000F094B00100FFFF004A67
+:102F1000B48B010020040040813201000A00004807
+:102F2000B2CB01001000004AB4F7010020040040B9
+:102F30008132010038050040813201001E00004846
+:102F4000B2CB01001004004081320100E90522509B
+:102F5000B56F0000EA050050B5B300000000004066
+:102F6000B5B301002004004081320100E09F004021
+:102F700081B200000400004081B200000400004063
+:102F800081B200000400004081B200000400004053
+:102F900081B2000000160040479901003031004026
+:102FA000F599010032330040F599010034350040B5
+:102FB000F599010036370040F59901003839004095
+:102FC000F599010041420040F59901004344004059
+:102FD000F599010045460040F59901004748004039
+:102FE000F5990100494A0040F59901002C00004084
+:102FF0008398010000000040F7B10100FC05A241E8
+:103000008350000080162E0683B00100360000FBBE
+:10301000F6A90100FF05A2418350000022000040F4
+:1030200083980100000000FBF6B101000206A241F6
+:10303000835000006200004095980100DC9F004032
+:103040008132010000162D0683B001008016004079
+:10305000459901005C0000FBF6A901000806A241A9
+:103060008350000000000070F9B101000000007101
+:10307000F9B1010000000072F9B101000000007315
+:10308000F9B1010000000074F9B1010054000040E2
+:1030900095980100DC9F0040813201000000007023
+:1030A00095B0010014062270B56F00000000804149
+:1030B00097B001000000804097B00100040000407C
+:1030C00081B200000400004081B200000400004012
+:1030D00081B20000456700A6E0B201000123007044
+:1030E000E19A0100CDEF00A6E2B2010089AB0071C8
+:1030F000E39A0100BA9800A6E4B20100FEDC007277
+:10310000E59A0100321000A6E6B201007654007381
+:10311000E79A0100D2C300A6E8B20100F0E1007412
+:10312000E99A01008016004A44C901000000000726
+:1031300081B001000000004A80D001000000004082
+:10314000F7B101002506A241815000008016004A17
+:1031500044C90100FC162A47E7B501000300004AF4
+:10316000E8E50100000000408DB001005003004080
+:10317000A399010080163D468DE00100000000503B
+:1031800089B00100000000FC40B0010000000041D7
+:10319000A3C101002E06A24189500000000000706A
+:1031A000EBB2010000000071EDB2010000000072FE
+:1031B000EFB2010000000073F1B2010000000074E2
+:1031C000F3B201000000004083B001000F00004195
+:1031D0008088010050030040A2C901004B06A050A6
+:1031E000836C00000D00004098C801000000004FF3
+:1031F000998401005003004CA2C901000000002086
+:1032000086B001000800004098C801000000004F8F
+:10321000998401005003004CA2C901000000002065
+:1032200086A401000200004098C801000000004F81
+:10323000998401005003004CA2C901000000002045
+:1032400086A4010050030040A2C901000000004311
+:1032500040A401000100002088E401000000005F9C
+:1032600041F0010000000044409401000500007599
+:1032700089E401001B00007585F401000000004492
+:10328000849401005506A353836C0000000000766F
+:1032900089B00100000000778984010000000076F9
+:1032A0008BB00100000000208BA40100000000781A
+:1032B0008B840100640600458894000027000041CB
+:1032C00080CE01005A06AA4081320000000000763C
+:1032D00089B001000000007789A40100640600782D
+:1032E00089A400003B00004180CE01005706AA409F
+:1032F000813200000000007689B0010000000077F4
+:1033000089840100000000768BB001000000007885
+:103310008B840100000000458894010000000077C4
+:103320008BB00100000000788B840100640600452A
+:10333000889400000000004484C00100000000796F
+:1033400085C001000000002084C001006B06A3536B
+:10335000836C0000825A00A684C001009979004263
+:1033600084C801007806004081B2000027000041B7
+:1033700080CE01007006AA4081320000D96E00A6FE
+:1033800084C00100A1EB004284C80100780600401F
+:1033900081B200003B00004180CE01007506AA40CA
+:1033A000813200001B8F00A684C00100DCBC0042FB
+:1033B00084C801007806004081B2000062CA00A6FD
+:1033C00084C00100D6C1004284C8010078060040D4
+:1033D00081B2000000000078F3B201000000007725
+:1033E000F1B201001E00007689E4010002000076BF
+:1033F000EFF6010000000044EE96010000000075A9
+:10340000EDB2010000000042EAB2010000000041FC
+:1034100083C001004F00004180CE010037062A40E2
+:103420008132000000000075E1C20100000000765A
+:10343000E3C2010000000077E5C20100000000784F
+:10344000E7C2010000000079E9C201002B068141BA
+:103450008D4000000000804081B201000400004067
+:1034600081B200000400004081B20000040000406E
+:1034700081B200000400004081B20000040000405E
+:1034800081B200000400004081B20000040000404E
+:1034900081B2000000000050FD9301004016004082
+:1034A00045990100DB9F00404931010008000048B8
+:1034B000B2CB01001504004081320100B906224060
+:1034C0008F6C0000DA9F004081320100B906A240F3
+:1034D000976C00005E160040439901007C1620F6B0
+:1034E000E0B101000000004031B301009D06224F11
+:1034F0008F7C000000000051FD9301009F062240D8
+:103500008F7C0000A3060054FD930000A106224218
+:103510008F7C000000000052FD930100A3062241B1
+:103520008F7C000000000053FD930100B70622517C
+:10353000FD7F000038050040813201000C0000488A
+:10354000B2CB01001004004081320100B206A2405B
+:10355000B56F00001E000048B2CB01001004004807
+:1035600096300100000000DA97C001000400004B13
+:10357000B2CB010010040040813201000E0000486F
+:10358000B2CB010020040040813201000C00004851
+:10359000B2CB010000000030B5B3010020040040B0
+:1035A000813201000E000048B2CB0100100400403F
+:1035B00081320100B6062240B56F0000BA06005401
+:1035C000FD93000000000051FD8301001C0000FE7F
+:1035D0007FD90100BA06A6408132000000000055E4
+:1035E000FD9301000000804081B201000400004012
+:1035F00081B200000400004081B2000004000040DD
+:1036000081B200000400004081B2000004000040CC
+:1036100081B20000E79F004081320100C406225CB5
+:103620001F7C0000E39F00881CB00000E99F005C45
+:103630001F00010000002E0548B1010000000040FD
+:10364000E1B1010004002D0348B10100000000F0C9
+:103650003CB001002800001402C801000000000175
+:1036600034B0010000002D0532B001002200000539
+:103670000AC801001000000348C90100000000F85A
+:1036800018B00100000000F804B00100000000F8CC
+:103690000EB001000C0000A40CC80100EA9F00401D
+:1036A000813201000000004023B001000A0722011E
+:1036B0008032000000003C4423E0010000002EA402
+:1036C00080B001000000001048C10100D906A30726
+:1036D000026C0000DA0668011AB0000000006807FA
+:1036E0001AB001000000000D02D00100000000052A
+:1036F000F0B101000000000CF0B101000000000278
+:10370000E0B101000000000D0AC00100EC062240FB
+:10371000036C0000E6062242236C0000000000411A
+:1037200023C001000000004761B10100200000A497
+:1037300062DD01002307284081320000E3060040DB
+:1037400081B200000000001080C0010000000047AE
+:1037500061B101000000004062B10100E806A8402C
+:1037600023300000E39F00881CB0000023070040C6
+:1037700081B200000000001080C00100000000477E
+:1037800061B101000000004062B10100EE06A840F6
+:1037900023300000E39F00881CB0000022000019C5
+:1037A00048C9010000002D1448C101000F0000F2BB
+:1037B0003A880100000000423BE001000E000014C6
+:1037C00002C801000000001D02C00100FA06231A11
+:1037D000025000000000004603C001002307000162
+:1037E00034C000000C002D1D48C10100F00000F2A3
+:1037F000308801000000004231F001000000001498
+:1038000002B001000000001D02C00100000000180D
+:1038100002C001000207221A025000002307000123
+:1038200034C000002200001948C9010002002D1414
+:1038300048C10100000000F614B001000000001DA6
+:1038400014D001000000001814D001000000001E78
+:1038500024B001001200001710C801002307001A4D
+:1038600010C0000000003C4423E00100000000A460
+:1038700086B0010000002E1048C101000F07A312FE
+:103880000E6C0000100760071AB000000000601204
+:103890001AB001000000680D16940100FFFF000B34
+:1038A00016D8010000000008F0B101000000000C73
+:1038B000F0B1010000000002E0B1010000000010C2
+:1038C00086C001000000004661B1010020000043F5
+:1038D00062DD01001707A85C1F1000004007220DE1
+:1038E000145000004007220D245000000000000D7D
+:1038F00010C001001E072242236C00002307004174
+:1039000023C000000000004661B10100400000102B
+:1039100062DD01001F07A85C1F000000E39F008814
+:103920001CB000000000004023B001003F07A20DC2
+:103930000E5000002E0722461F7C000000000046AB
+:103940001F8001003080001042C901002C0722F2C4
+:10395000640600000000004761B101004000001053
+:1039600062DD01002907A84081320000E39F008842
+:103970001CB0000020800003469901000000005F99
+:10398000E191010000002D0648B10100000000F89F
+:1039900018B00100000000F804B0010033071FF068
+:1039A0000E300000D306004C0DC0000000002E5F5A
+:1039B0000F800100D3062307146C000030000010B4
+:1039C00048C9010024000040F199010000000003F3
+:1039D000F0B1010000000000F0B10100000000168D
+:1039E000F0B101002400000000C801000000004701
+:1039F00061B10100200000A462DD01003C07A8467F
+:103A00001F100000D30600030CB00000D306000D09
+:103A100018C000005F07A2441F7C000000000019CE
+:103A20000AB001002200000548C901000A002D1457
+:103A300048C1010002002040E5B10100040020401F
+:103A4000E5B101000D002D1D48C10100090000F382
+:103A5000388801000D002050E7B1010004002D401E
+:103A60003FB00100000000F432B00100040020402B
+:103A7000E1B101002200000548C9010000002D1439
+:103A800048C101000200001D94F401000000004044
+:103A900091B001005207A0FC9040000000000041DE
+:103AA00091C001005007A24195500000000000A401
+:103AB00096B0010004002E0548B101000000004846
+:103AC000F0B101000000004B48B1010000000018F7
+:103AD00048C101000200001894F4010000002D18F4
+:103AE00090B001005C07A0FC904000000000004185
+:103AF00091C001005A07A241955000000000004803
+:103B0000E0B1010010002040E5B1010004002D05E6
+:103B100048B10100000000F880B02D00000000F066
+:103B200016B02D002200000548C92D000000001429
+:103B300048C12D00640743303D072C000000009E63
+:103B400085B02D0000001B413DC32D000400204224
+:103B5000ECB12D000000001E82B0010002002E1DFD
+:103B600082C001000000661882C00100000000420F
+:103B700080C001006E07A0418044000000000041A9
+:103B800081C001001000004092F401000A002E30B4
+:103B900081840100720790409240000000000041C3
+:103BA00093C001000000662093A401000000001DE6
+:103BB00048C1010004002019E8B101000000001E06
+:103BC00016C001007807A01916440000000000414B
+:103BD00017C001000D002F1E32C001007D07A2405A
+:103BE000156C00007C07A01C16400000000000417E
+:103BF00017C00100000063F33894010010000005B5
+:103C000048C9010004002E1E98B001000000601A8F
+:103C100098C001000C002040E1B101008B07224652
+:103C20001F7C0000000000461F8001003080001053
+:103C300042C90100890722F2640600000000004723
+:103C400061B101004000001062DD01008607A8405C
+:103C500081320000E39F00881CB000002080000338
+:103C6000469901000000005FE191010030800010E2
+:103C700044C901001200001AF0C901000000001739
+:103C8000F0B1010010000005E0C901003000001093
+:103C900080C801000000004461B101002000004024
+:103CA00062DD01009107A840813200009B07225C81
+:103CB0001F7C000000003C4423E0010000002D10A8
+:103CC00048C101009B0722F2640600000000004684
+:103CD00061B101004000001062DD01009807A840BA
+:103CE00081320000E39F00881CB00000EB9F005C65
+:103CF0001F00010020002F0548B101000000000B4B
+:103D0000E4B101000000005017F00100A10790F29B
+:103D1000164000000000004117C0010000006620AE
+:103D200017A40100100000142AC801000000001DA3
+:103D30002AC00100000000502BE00100000000F24A
+:103D40002A9401003080001042C90100AC0722F221
+:103D5000640600000000004461B101004000001052
+:103D600062DD0100A907A84081320000E39F0088BE
+:103D70001CB000000080001710DC0100C9072240C1
+:103D8000156C0000B407A2441F7C00000000004432
+:103D90001F900100B307229F136C000002000088EF
+:103DA0001CCC0100E49F004081B2000000000041F3
+:103DB0003FC30100E69F004081320100B707A241E6
+:103DC000877C00000000001E3EC00100C9072240A1
+:103DD000156C0000BA07201E146C00000000000AD9
+:103DE0003CB00100E59F001E24300100BF072208FF
+:103DF0002E3000000000005211C001000000001A27
+:103E000010C001002307004017B00000E49F0088A5
+:103E10001CB00000E59F004081320100BC07A208F1
+:103E20002E300000808000A604B001000600004093
+:103E300087980100008000034499010004002204D7
+:103E4000E0310000E89F001F8C30010000000040BE
+:103E50000FB00100E29F005C1F9000000080000393
+:103E60004499010004002204E0310000E69F004074
+:103E700081320100CE07A241877C0000CF07001EDF
+:103E80003EC000000000001F8CB001000000004098
+:103E900005B00100E89F00400F300100E29F005C88
+:103EA0001F9000000400004081B2000004000040A8
+:103EB00081B200000400004081B200000400004014
+:103EC00081B200000400004081B200000400004004
+:103ED00081B200000400004081B2000004000040F4
+:103EE00081B200000400004081B2000004000040E4
+:103EF00081B200000400004081B2000004000040D4
+:103F000081B200000400004081B2000004000040C3
+:103F100081B200000400004081B2000004000040B3
+:103F200081B200000400004081B2000004000040A3
+:103F300081B200000400004081B200000400004093
+:103F400081B200000400004081B200000400004083
+:103F500081B200000400004081B200000400004073
+:103F600081B200000400004081B200000400004063
+:103F700081B200000400004081B200000400004053
+:103F800081B200000400004081B200000400004043
+:103F900081B200000400004081B200000400004033
+:103FA00081B200000400004081B200000400004023
+:103FB00081B200000400004081B200000400004013
+:103FC00081B200000400004081B20000F70700BC8D
+:103FD00080B200000380004081B2000003800040F6
+:103FE00081B200000380004081B2000003800040E5
+:103FF00081B200000380004081B2000003800040D5
+:1040000081B200000380004081B2000003800040C4
+:1040100081B200003180004081B200003480004055
+:1040200081B200003580004081B2000004000040F1
+:1040300081B200001B808180803200001487A24082
+:10404000916F00000000004C90B301005C952EA21F
+:1040500080B00100FF000080F489010090952AC81B
+:10406000E5B10100000000A1F0B101000000004036
+:10407000F0B10100000000A4F0B10100000000D088
+:10408000F0B10100000000D1F0B10100000000D249
+:10409000F0B101000000004CF0B10100000000D4BC
+:1040A000F0B10100000000D3F0B10100000000EE0B
+:1040B000F0B101000000004EF0B10100000000402E
+:1040C00044B1010018801181983000000000514077
+:1040D00081B201001A801182983000000000524025
+:1040E00081B2010014870048FD930000B603004030
+:1040F000A19901002380A242FD7F00002080008062
+:1041000080320000228011818230000022805140E4
+:1041100081B2000022801182823000002280524051
+:1041200081B200002C800048FD93000027800080B1
+:10413000803200002680A253077C0000000051530B
+:10414000079001002A800052079000002980A252A7
+:10415000077C00000000525207900100000000534D
+:104160000790010000000048FD9301000000004698
+:10417000F39301005C952EA252B30100FF00008072
+:10418000F48901000000004CE4B10100000000A926
+:1041900045B101003080004C80B200000000454075
+:1041A00081B201000000554081B20100AF8205409C
+:1041B00049B10000AF82054049B100000000054050
+:1041C00049B101004C010040813201000000004B68
+:1041D000DEB2010000000040FD9301000000004835
+:1041E000FD830100020000409B9B0100000000A530
+:1041F0009CB30100480300408132010058952044DF
+:10420000E0B101000494004043990100000000F275
+:1042100024B10100000C00EE968801000000004A65
+:1042200097F001004480A243976C00000000004218
+:10423000FD93010000C000A636B10100D01400407B
+:104240004799010005000040F59901000038004041
+:10425000F599010000060040F599010000000040BA
+:10426000F599010005100040F59901000209004090
+:10427000F599010004000040F59901006003004039
+:10428000813201008803004081320100A003004018
+:1042900081320100A2820040813201009A820040F6
+:1042A0008132010060952040E1B10100709520400D
+:1042B000E1B1010000000049DD9101000000004073
+:1042C00091B30100F99500408132010000000040E7
+:1042D00085B301005C952040E1B1010027820040D8
+:1042E0008132010090060040813201000000005F31
+:1042F0002F8101008D81004081320100FE95004038
+:10430000813201000000454081B2010000005540AB
+:1043100081B20100DD82004081B200000400004053
+:1043200081B200000400004081B20000040000409F
+:1043300081B200000400004081B20000040000408F
+:1043400081B200000400004081B20000040000407F
+:1043500081B200002800004047990100AF8200416F
+:10436000E1C1000078180040499901001905225464
+:10437000817C00006C80424081320000008200B4E9
+:1043800069DF010000001A449393010028000040F7
+:10439000479901001805004081B200000400004068
+:1043A00081B200000400004081B20000040000401F
+:1043B00081B200000400004081B20000040000400F
+:1043C00081B200000400004081B2000004000040FF
+:1043D00081B2000040820040813201007D80224095
+:1043E000976C00007A804240813200000000004F4C
+:1043F0006993010038810058699300005416004009
+:1044000047990100000000FEF4B101008005004062
+:1044100081B2000080804240813200000000004EE6
+:1044200069930100388100586993000040160040EC
+:10443000459901004005004049310100F615004052
+:10444000439901005C1600404599010000006EFA96
+:104450008EB00100C105004081B2000004000040A0
+:1044600081B200000400004081B20000040000405E
+:1044700081B200000400004081B20000040000404E
+:1044800081B200000400004081B20000040000403E
+:1044900081B200009680004081B20000408200405E
+:1044A0008132010096802240976C00009380424048
+:1044B000813200000000004F6993010038810058EC
+:1044C0006993000038050040813201001E00004859
+:1044D000B2CB0100D005004081B2000004000040D2
+:1044E00081B200000400004081B2000004000040DE
+:1044F00081B200000400004081B2000004000040CE
+:1045000081B200000400004081B2000004000040BD
+:1045100081B200008302004081B20000B802004076
+:1045200081B20000D49F004081B20000D59F0040BE
+:1045300081B20000D69F004081B20000D79F0040AA
+:1045400081B200007201004181C000005501514854
+:10455000FD93000055015248FD9300005501554957
+:10456000FD8300005501564AFD83000050019181F2
+:10457000803000005501454081B200005001918219
+:10458000803000005501464081B20000000000402C
+:1045900089B00100000000F880B00100000000F0C8
+:1045A00016B001002200000548C9010000000014F7
+:1045B00048C10100B48043303D0700000000009E68
+:1045C00085B0010000001B413DC3010004002042F2
+:1045D000ECB101000000004049B10100AE0300CB86
+:1045E000A3C901000000002046B10100000000D274
+:1045F000F1B10100000000D3F1B101000000004260
+:10460000F0B101000000004561B101002000002070
+:1046100062DD01000000A8D0E1B10000BF800040D1
+:1046200081B20000000000A898B0010004800040A2
+:104630008BB30000B1030040A1990100C780A242E2
+:10464000976F000000000045A1C1010000000000BC
+:1046500080B001000000A2048094000080153F4259
+:1046600097E301000000004049B101000000600331
+:10467000029401000000004007B00100040000CBDC
+:1046800099CB0100000000CCF3830100D180A2424D
+:10469000976F0000000000CBF3930100AE0300CB46
+:1046A000A3C901000000002044B101000000004443
+:1046B000F1B1010000000000F0B1010000000004B1
+:1046C000F0B10100000000A1E0B1010005000040D0
+:1046D000619901002000002062DD0100D880A8401F
+:1046E00081320000F9020020423101000000A241A5
+:1046F000056C0100000080CBDB9101000000194136
+:104700008BB301006000004061990100DE80A8B118
+:104710008C3300006000004061990100E080A8B186
+:1047200094330000E68014C681320000180000C6F1
+:1047300083F40100F482224F83040000C280004011
+:1047400081B20000FF0100C681880100000000C6A0
+:1047500097A30100C2801F5C9753000058821EC6B9
+:104760008132000000002F4381F00100EC80004006
+:1047700010C900003981004081B200006A81004008
+:1047800081B20000248200CA63B30000618100404E
+:1047900081B200004881004D83B000005281004E7C
+:1047A00061B100004181004085B000004881004CAB
+:1047B00083B000002481004085B00000E381004008
+:1047C00049B1000071810040C1B10000DF810040AB
+:1047D00081B200004181004085B00000F00300403C
+:1047E00049B10000F48200CA9BB300007B81004005
+:1047F000C1B100007F810040C1B10000868100404E
+:10480000C1B1000087810040C1B100008881004033
+:10481000C1B1000089810040C1B100008A8100401F
+:1048200081B000008A81004181B000001882004000
+:1048300081B20000978200BBABB30000258200CAA2
+:10484000CFB30000C803004049B10000E8030040B6
+:1048500081B200002682004081B20000F482004054
+:1048600081B20000E003004081B20000F48200CA7F
+:1048700077B300004981004D83B000005081004EA5
+:1048800061B10000418100BB85B000004981004C4E
+:1048900083B00000418100BB85B00000248100BBD3
+:1048A00085B000001681004081B20000F48200CA89
+:1048B0004DB300007005004049B10000A005004064
+:1048C00049B100001C8122428F6F00001E812241ED
+:1048D0008F6F000020811ECA8132000022811FCA12
+:1048E00081320000000000CAC9B10100F482004218
+:1048F0008FB30000000000CACDB10100F482004176
+:104900008FB30000000000CACFB10100F482004064
+:104910008FB30000008100A6C6B10100F482004000
+:1049200081B20000008000A6C6B10100F482004000
+:104930008FB30000781800404999010010002F9CA7
+:1049400089B001003B8100403933010018002F9BE2
+:1049500089B001003B8100403733010000002F9AED
+:1049600089B001003B8100403533010008002F99D8
+:1049700089B001003B81004033330100008000AE6C
+:1049800047C9010080000040F1990100000000CA01
+:10499000F1B1010000000042F0B1010040180040F8
+:1049A000E19901000000004561B10100200000AE66
+:1049B00063DD0100368128408132000033810040F0
+:1049C00081B2000036814240813200000000005C6C
+:1049D00069930100F4821A449393000039814240A4
+:1049E00081320000388100586993000000000044C3
+:1049F000F0D101000000A44081B200004081A2403B
+:104A0000E16D00000000004445D10100000080403D
+:104A1000E1B1010000008041E1D101004181375C3A
+:104A2000613100000000004262B101004581284070
+:104A3000813200004281004081B20000000000CAC3
+:104A400063B101004581A84081320000F482174023
+:104A500081B200004A81004081B000004A8100BB61
+:104A600081B000000000004160B101000000004082
+:104A700062B101004B81A84081320000000000CAF1
+:104A800063B10100F4822840813200004D81004072
+:104A900081B200005095004047990100538100BB4E
+:104AA00087B0000050952F4087B00100558122400B
+:104AB000957F0000F48260409583000002002DF095
+:104AC00084B001005681364081320000000000426F
+:104AD00062B101005781A84081320000000000430C
+:104AE00062B101005981A84081320000000000CA73
+:104AF00063B101005B81A8408132000000001640D4
+:104B000081B20100F482224143510000000800CA32
+:104B100095CB01005681004185C000006381A2420F
+:104B2000676F00000000004167B3010063814240ED
+:104B3000813200000000004065B301000000004029
+:104B40009383010000001ACA69970100F48226408D
+:104B5000813200006881424081320000F4821A44B0
+:104B600093930000F4822043956F0000F48280CA82
+:104B700067330000F4822240656F0000F482006F0A
+:104B8000DB91000085000040813201003580224029
+:104B900080320000F482004081B200000000005822
+:104BA000959301000000005F959301007781A24476
+:104BB000216F00000000005F958301000000005E8F
+:104BC000959301000000005795930100000000CA72
+:104BD000C3B101007A81225B957F00000000004B89
+:104BE000FD930100F482004081B200001BFD00CA69
+:104BF000959B01000D0100CAC53101000000005F56
+:104C000095830100F48200CAC5B10000DF6F00CABD
+:104C1000959B01000000005595930100000000CA1B
+:104C2000C7B10100F482225F957F00000D010040B2
+:104C3000813201000000005F95830100F48200CA08
+:104C4000C7B10000F48200CAC9B10000F48200CAF2
+:104C5000CBB10000F48200CACDB10000F48200CADA
+:104C6000CFB1000000002E4281E001009814004006
+:104C700048C90100F48200CAE1B100000000004010
+:104C800009B10100200000A682B001008F81A25E60
+:104C90000B7D000000800041089901009181A25E17
+:104CA0000B7D0000208000A608B1010093819F8544
+:104CB000823000000000003083840100C88122306F
+:104CC000836C00009281A24F0B7D00000000004128
+:104CD00021B30100028000A682B0010013820040CF
+:104CE000813201001000004184E40100038000A62D
+:104CF00082B001001382004081320100F0FF0041C8
+:104D00008688010000000043849401000F0000A683
+:104D100086B0010010C4004386980100A881A24318
+:104D2000846C00000000004321B30100200000A6B5
+:104D300082B001001C00004182DC0100A581A25E5E
+:104D40000B7D00000400004108990100BA81004079
+:104D500081B20000410100A686B00100500C004362
+:104D600086980100AD81A243846C000000000041E0
+:104D700021B30100BA81004081B20000410100A6C8
+:104D800086B00100600C004386980100BA81A243FE
+:104D9000846C00000000004221B30100188000A6CE
+:104DA00082B001001382004081320100FFFF004108
+:104DB0008288010000770041828C010001020041DD
+:104DC000829801002000004182DC010018000041AF
+:104DD00082DC0100B881A25E0B7D00000000004172
+:104DE00008B10100200000A682B00100BB81A25ED4
+:104DF0000B7D00004013004108990100C38122434C
+:104E0000216F0000200000A682B0010012000041C6
+:104E100082DC0100C081A25E0B7D00000004004125
+:104E200008990100DE81004081B20000200000A648
+:104E300082B001001900004182DC0100C581A25E40
+:104E40000B7D000000A0004108990100DE810040B8
+:104E500081B200000000004421B3010000000040C6
+:104E600083B001000000005F839001000000005E3D
+:104E70008390010000000057839001000000004172
+:104E8000C2B101000C010040813201000000005F4E
+:104E90008380010000000041C2B101000C0100400C
+:104EA00081320100200000A682B001000400004110
+:104EB00082DC01002000004108990100200000A6CA
+:104EC00082B001001100004182DC0100D781A25EA6
+:104ED0000B7D00000100004108990100200000A6A0
+:104EE00082B00100DA81A25E0B7D00004013004118
+:104EF00008990100010000A682B0010040000041B5
+:104F00002E9901000000804081B20100200000A61F
+:104F100080B00100000000CA81940100E181A25E1E
+:104F20000B7D0000F482004008B10000C8142EBBC5
+:104F300085B00100E481A25E0B7D0000000000400E
+:104F400087B00100F3812243216F000002822244D6
+:104F5000216F0000118000A682B001001382004082
+:104F6000813201000A82224A837C00000000004056
+:104F700087900100EE81224D837C000000000041FB
+:104F800087900100F081224F837C000000000043E5
+:104F900087900100F281224E837C000000000042D5
+:104FA000879001000A82004081B20000018000A6C3
+:104FB00082B001001382004081320100018000A60E
+:104FC00082B0010013820040813201000A82224235
+:104FD000837C000000000040879001001C8000A638
+:104FE00082B001001382004081320100FD81224520
+:104FF000837C00000000004187900100FF81224473
+:10500000837C00000000004387900100018222435E
+:10501000837C000000000042879001000A8200406B
+:1050200081B20000018000A682B00100138200401E
+:1050300081320100018000A682B00100138200408D
+:10504000813201000A822242837C0000000000407D
+:10505000879001000000004387900100000000419C
+:1050600087900100008000A682B0010013820040FA
+:10507000813201000E82224B837C00000000004040
+:105080008780010000000043E0B10100FF7F00A223
+:10509000A08B010000000044A5B30100B88000CA45
+:1050A000A73301003681004081B20000200000419A
+:1050B00082DC01001482A25E0B7D00000000004132
+:1050C00008B1010016829F858230000000008040F8
+:1050D00081B201001B8214F7813000001B82A249BB
+:1050E000FD7F000000000048FD9301001E8215F8BE
+:1050F000811400001E82A24AFD7F000000000048CB
+:10510000FD9301002082A2C88132000040000040CF
+:1051100080DC01000010004080DC01000000004045
+:10512000EFB3010022824240F13300003881004099
+:1051300068970000F48200BB6BB30000F48200BBF0
+:10514000B1B30000F482004081B2000000030040CF
+:10515000819801000000004018B10100800000406B
+:105160008398010000190040459901000000424069
+:1051700081B20100000043FFF1B10100000000FF17
+:10518000F1B101000000004181C0010000000040B9
+:1051900018B101002B82A24183500000001600408C
+:1051A00045990100001900404399010000000047A3
+:1051B00043C101000000004083B00100000000F383
+:1051C00080B001000000005B81D0010000000041C0
+:1051D00080D0010000000040F6B101000000005B3B
+:1051E00043C101000000004183C001003582A25488
+:1051F000836C000000000040F7B101000000004196
+:1052000083C001003C82A206836C00000000804045
+:1052100081B20100001600404399010080162E065D
+:1052200083B00100360000FBF6A901004282A241D2
+:10523000835000002200004083980100000000FB22
+:10524000F6B101004582A241835000006200004097
+:1052500095980100DC9F00408132010000162D0668
+:1052600083B0010080160040459901005C0000FBFE
+:10527000F6A901004B82A24183500000000000709B
+:10528000F9B1010000000071F9B1010000000072E5
+:10529000F9B1010000000073F9B1010000000074D1
+:1052A000F9B101005400004095980100DC9F0040D6
+:1052B000813201000000007095B001005782227019
+:1052C000B56F00000000804197B0010000008040F1
+:1052D00097B00100B6030040A199010000002F42E1
+:1052E00099B3010062822244816C00006A822248E4
+:1052F000816C00006482224C816C00006E8222501E
+:10530000816C00006F822254816C000071822258EF
+:10531000816C00007682225C816C000050010040AC
+:1053200081B20000000000BC09B00100F48200CA94
+:1053300001B000000000004003B001000000004187
+:10534000F38301006882A242056C00000000004166
+:1053500005B00100F48222CA07140000F48200465E
+:10536000F3930000F4822043956F0000F48280CA1A
+:1053700005300000F482220180300000F48200CB6E
+:10538000DB910000570100BCABB30000000000BC83
+:10539000B1B30100F48200CACFB30000FF0000CA1D
+:1053A00081880100F482A240747D000060002040EA
+:1053B000609901007382A8B18230000072820040BF
+:1053C00081B20000F48200CA79B300000000004EF0
+:1053D00081B0010000000043CB8301000000454084
+:1053E00081B201007982A241815000000000454055
+:1053F00081B201000000454081B2010084829182A7
+:10540000823000000000008A80B00100AE9F0040A2
+:1054100080CE01008282A640813200008482564004
+:1054200081B20000B6030040A199010000000053C2
+:1054300007900100B6030040A1990100000000524E
+:1054400007900100D89F00418BB300000000004E80
+:1054500081B0010000000042CD8301000000464001
+:1054600081B201008982A2418150000000004640C3
+:1054700081B201000000464081B201009482918116
+:10548000823000000000008980B00100AE9F004023
+:1054900080CE01009282A640813200009482554065
+:1054A00081B20000B6030040A19901000000005243
+:1054B00007900100B6030040A199010000000053CD
+:1054C00007900100D89F00418BB30000B10300405A
+:1054D000A1990100C4142F4099B301005701004065
+:1054E00049B10000A0942E4397B001000000004095
+:1054F000F1B101009B82A2419750000050952040DD
+:10550000E1B10100AC942E4397B0010000000040CF
+:10551000F1B101009F82A24197500000000080403D
+:1055200081B20100AE030040A399010000000040D9
+:1055300081B001006015004085980100080000401E
+:1055400040E40100000000594194010000000050B7
+:1055500041E00100000000424094010000000057BB
+:10556000419001000000004181C001000000A34201
+:10557000816C010000000041A3C10100A582A0428E
+:10558000816C0000A582005085C00000DD82A24130
+:10559000017D0000B5822258737D00007800004034
+:1055A00061990100B082A8B19C30000030003845FC
+:1055B0009DE001000100000E10C90000B58233C457
+:1055C00081300000B882A1AD9D200000AF82134061
+:1055D00081B200000000134E5A83010030003845AC
+:1055E0009DE00100C08222AB80040000BE82A24088
+:1055F000017D0000C082225F577D00003C87004093
+:1056000081B20000C082225E577D00009F8700406B
+:1056100081B20000C5822254737D000074000040F6
+:1056200061990100C082A8B1003000009084A25F9F
+:10563000017C0000D086004081B20000C782A25FDA
+:1056400059270000C982A25C737D0000D082A25E4F
+:10565000737D0000DA82225C737D0000DB823740BC
+:10566000813200007C00004061990100CA82A8B12B
+:10567000363000007C00004061990100CC82A8B166
+:10568000003000001F00000002880100BF841740A6
+:1056900081B20000DB823440813200007E00004095
+:1056A00061990100D182A8B112300000D882522144
+:1056B00013040000000014412FC30100FF3F000944
+:1056C000008C01000000004301F001001183003450
+:1056D00013840000FF3F1409008C01007183004314
+:1056E00001F000000000004081B20100DB82334085
+:1056F00081320000AF82134E5A9300001487A248F3
+:10570000FD7F00000400A2AC80320000E382225A38
+:10571000737D00007A00004061990100E082A8B129
+:105720007E310000010000CF11C90000E982A240D3
+:10573000937F0000E9822244937F0000E58242A526
+:1057400080300000E882A240937F0000FB821A4074
+:105750009393000000001A4081B20100DD80A24056
+:10576000737D00000F872244216F000006872240CE
+:10577000657D00000005A25B737D00000400A24966
+:10578000337D0000F3822248337D0000FF01009941
+:1057900080D801000000005081E00100A8982F404F
+:1057A00033B1010000000040E0C10100DD82004093
+:1057B00081B20000AF8200408BB3000000000058AF
+:1057C00061B101000000004E62B10100AF822840CB
+:1057D00081320000F682004081B20000F98233403D
+:1057E0001F300000AF82134E5A930000FD82A0CEFE
+:1057F000815000000F83A0CD816C0000000000A547
+:105800009CB30100000000B181B001000F8322B5FC
+:105810008114000080152F4049B1010001834240EE
+:1058200081320000000060B465970100D0152E4061
+:1058300069B3010000001A44938301001A0000A21A
+:1058400080DC010000000044F1B10100000000B163
+:10585000F1B10100000000B5F1B101000500004008
+:10586000619901008000004062DD01000A83A8A167
+:10587000E0310000E98200889EB30000E982A24185
+:10588000676F0000E982006FDB9100000F834240E8
+:1058900081320000E9821A409383000000990009D8
+:1058A00046C901003F0000F30C8801001A83A6429C
+:1058B00013600000299400950330010015836140B6
+:1058C0008132000075000040619901001683A8B183
+:1058D0000C30000036947110943001001B83005886
+:1058E0001F9000001C94009503300100AF820088D7
+:1058F0001CB0000000002D0348B1010004002DF091
+:105900002EB00100EE070040979801002283234B40
+:10591000E46D00002283224BFD7F00000000004068
+:105920001F90010022002F4081B2010025838317C0
+:105930008032000026000040479901002783851728
+:10594000803200000000004847C101002D8322552D
+:105950002F7C00000000004243D101000F0000FA3C
+:10596000968801000000004297E00100000000421C
+:1059700097D001002E83004B44C10000120000A20A
+:1059800044C90100280000F602CC01000A0000A171
+:1059900042C90100000000F816B00100000028F024
+:1059A00010B00100000000F01AB00100000000A2D9
+:1059B0002AB00100C0283C460DE0010000002D4443
+:1059C00095B001003A83A2F80E3000004A832241CC
+:1059D0009550000000002D5049C101003683004061
+:1059E00081B200003783A2F8166C00003783A2F85A
+:1059F000106C00003783A2F01A6C00004883225814
+:105A00001F7C000000993F4213F001003F83654076
+:105A1000813200004383A2F37406000000000006F8
+:105A2000E69501004883754081B200000000000641
+:105A300096B001003F0075F30C880100000000558E
+:105A400061B101000000004B62B101004683A84033
+:105A500081320000488367408132000050837741E3
+:105A60002DC300004E8322581F7C0000000000550B
+:105A700061B101000000000662B101004C83A84042
+:105A8000813200004E836740813200007E8377417F
+:105A90002DC30000030000071AF40100EF92000775
+:105AA000163001005F832241816C00005683224240
+:105AB000816C0000AF8200881CB000005E83225F12
+:105AC0000F7C0000E393005F011001005C83224023
+:105AD000956C00000480000342C90100000000F240
+:105AE00002B0010058930052953001005F93004BC3
+:105AF00002B0000041940009963001001A8700406E
+:105B00000FB000006783A25A1F7C0000699200401A
+:105B10008132010067832220856C000064839C0F22
+:105B200080320000AF8200881CB000004A93005C05
+:105B30001F0001003C95004261310100AF820088E6
+:105B40001CB00000900400079630010000002D05F5
+:105B500048B101006A8382F0183000008188004556
+:105B60008FB00000282000A696B001006E83221797
+:105B700096040000E094004B953001008188004BB2
+:105B80008FB00000EF93000348310100CA9100403C
+:105B9000813001008188004081B2000000002E1099
+:105BA00048B101000000685003B00100000000038C
+:105BB000F0B1010040000000E0C9010000002E50DB
+:105BC00049C1010000000050F1B1010000000003D4
+:105BD000F0B101000000004261B10100200000109E
+:105BE00062DD01007983A8408132000010000010BE
+:105BF00062C901007B83A800E0310000AF82008809
+:105C00001CB0000000002D0348B10100000000405E
+:105C10000FB00100000000F82EB00100000000F2FB
+:105C200002B001000000004017B00100004100A6D2
+:105C300096B00100EE072E4797900100918322173E
+:105C4000960400008F83224BFD7F00008F8323A2E8
+:105C5000026C00005893005295300100040022416C
+:105C6000975000000C002D0012B00100000000F061
+:105C700000B001000000005C018001005F93004B58
+:105C800002B000000000000900B001000000005058
+:105C900003B00100AE83005C17900000A383224391
+:105CA0002F7C0000000000451F9001009C83225FB4
+:105CB0002F7C000000002E1048B1010000000058A9
+:105CC000F1B1010010000003F0C901001000000054
+:105CD000E0C90100988362426131000000000010B9
+:105CE00062B101009983A84081320000AF827288BE
+:105CF0001CB0000020002D0348B10100FF0F00F68A
+:105D000080880100A083A2A6816C0000A38300F21A
+:105D10003AB000008D84A24BFD7F0000B09200409D
+:105D2000813201003087004081B20000AE83224AF8
+:105D30002F7C0000AE8322482F7C00000A002D0338
+:105D400048B101003F0000F2868801001F000043B7
+:105D5000848801000500004380F4010098943D42CE
+:105D600081E00100AE83A242E07D00008D84A24B61
+:105D7000FD7F0000B092004081320100308700407A
+:105D800081B20000AE83694081320000000000A3B0
+:105D900009B001000000794147C30100B48322A18A
+:105DA000096C0000F58200881CB00000B18300037C
+:105DB00048B10000EE83A392036C0000949500406C
+:105DC000953001000000004143C3010000000016AF
+:105DD00080B201003087270880320000BB83225C3C
+:105DE000177C0000BC8300002AB0000012000000F5
+:105DF0002AC801000200000880C80100C083A24335
+:105E00002F7C0000E394004081320100DC83005EBF
+:105E100017900000040000018CCC0100E394004CBA
+:105E20000330010000002E4602B0010010000010F7
+:105E300048C901000C000001F0CD01002C00004019
+:105E4000F0C9010000000016F0B1010010000015BB
+:105E5000E0C901000000004361B10100A00000A4FE
+:105E600062DD0100C983A85417100000DC83005EC6
+:105E700017900000120000002AC80100DB832243B3
+:105E80002F7C0000040000018CCC01000000004CBD
+:105E900003B00100049500436131010000002E466B
+:105EA00002B001001000001048C901000C00000100
+:105EB000F0CD01000C000009F0C90100000000183D
+:105EC000F0B1010010000015E0C90100000000431E
+:105ED00061B10100A00000A462DD0100DC83285450
+:105EE00017100000D883004081B2000004950043E1
+:105EF00061310100DE8322502F7C0000000000563B
+:105F0000179001000700001798880100E183A24163
+:105F1000996C00000000005517900100000000433C
+:105F200061B101004000001062DD0100E283A84081
+:105F300081320000AF8200881CB00000EB9400406A
+:105F400081320100E98322432F7C00001680000388
+:105F500044C901000000001DE4B101008C94005E02
+:105F600005100100EC83A25F2F7C0000A6910001C8
+:105F700038430100B0920040813201003087004078
+:105F800081B20000F083A24BFD7F00008A840041B3
+:105F900043C300000000004027B0010000000040A3
+:105FA0002DB001000000004011B00100F383350165
+:105FB000863000006D00004061990100FB8328B12C
+:105FC00030300000F483224D757D00000000001683
+:105FD00080B201007A84A740116C000000000041EB
+:105FE00043C301008984004081B200006D0000407D
+:105FF00061990100FB83A8B1123000000000001677
+:1060000080B201000584A740116C0000000000412F
+:1060100043C301000000000910B001000000001897
+:106020002CB00100DE07004380CE0100F483AA40BB
+:10603000813200000A84004081B2000040003E43EB
+:1060400027E0010000000009F0B101000000001885
+:10605000E0B101000000004127C00100F483A30B60
+:1060600087500000000015401BB0010000000040F8
+:1060700023B00100120000002AC8010040002D409A
+:1060800039B001001284A240276C000022000008F1
+:1060900012C80100DE070040259801001584004069
+:1060A00081B20000000000F812B00100000000F012
+:1060B00030B001000000000B25B00100000000100E
+:1060C00032B0010014002001E0B10100EE070040F1
+:1060D000379801001A842301366C0000000000018B
+:1060E00036B001002584824123400000208000104A
+:1060F00042C9010021842240E36D000000000043FA
+:1061000061B101004000001062DD01001E84A84062
+:1061100081320000AF8200881CB00000CF920043A3
+:10612000233001000000001032B0010000000041E7
+:1061300023B001000000000348B1010000800019F5
+:1061400044C90100348422451F7C00000000004C3B
+:10615000F1B1010000000009F0B1010000000018D9
+:10616000F0B101000000004361B1010020000019FE
+:1061700062DD01002B84A815E03100000000005012
+:1061800003D001000000005033C001000000004CAB
+:1061900025D001000C002D4C13C001000000005060
+:1061A00037D00100000000502BC001001A840045C8
+:1061B0001F8000003684A312366C00003784681BF1
+:1061C00028B000000000681228B00100000000099B
+:1061D000F0B1010000000018F0B101000000004320
+:1061E00061B101002000001962DD01003A84A815A8
+:1061F000E0310000608422140250000000000050D2
+:1062000033C001000000001424D001000C002D1444
+:1062100012C001005984A214365000004A84225C46
+:106220001F7C00003080001042C9010048842240D9
+:10623000E36D00000000004261B101004000001069
+:1062400062DD01004584A84081320000AF820088F1
+:106250001CB000000000000348B101000C002D5CE0
+:106260001F800100100000F02AC801000000005C3F
+:106270002B800100F0070040379801004F84230174
+:10628000366C00000000000136B001005A84221B69
+:10629000026C00003000001048C9010000002E5CB4
+:1062A0001F90010000000050F1B101000000000348
+:1062B000F0B10100FF070015E08D01000000004271
+:1062C00061B10100A00000A462DD01005684A84075
+:1062D000813200005A84000348B10000000000141D
+:1062E0002AC001001A84A240256C00000000004171
+:1062F00039C0010040003D4339E001000000000BBF
+:1063000025B00100000000F812B001001A8400F06E
+:1063100030B000000080001942C9010066842240AC
+:10632000E36D00000000004361B10100400000196E
+:1063300062DD01006384A84081320000AF820088E2
+:106340001CB00000CF9200402B30010018002E033B
+:1063500048B101006A8422502F7C000000000056E2
+:106360001790010007000017988801006D84A24172
+:10637000996C0000000000551790010070842243C2
+:106380002F7C000000000054179001001600201D13
+:10639000E4B101007284A340276C00007484605F44
+:1063A000179000000084000B16DC01000000601351
+:1063B000169401008C94005E051001003087A25FE6
+:1063C0002F7C00001480000342C90100000000F28D
+:1063D00002B00100A691000138430100308700405F
+:1063E00081B200000000004083B001000000004DB9
+:1063F00061B101000000001662B101007C84A84078
+:10640000813200000000000862B101007E84A840D3
+:106410008132000089842213826C000040003D43D9
+:1064200083E00100000000F810B00100000000F05F
+:106430002CB001000000001662B101008484A84065
+:10644000813200000000000862B101008684A8408B
+:10645000813200008084004183C0000000001540AC
+:1064600081B20100008200A604B00100A0980040A3
+:1064700047990100300500418930010058930052CE
+:10648000953001005F93004B02B000003087004060
+:106490000FB000000000005F01800100100000004C
+:1064A0000EF401003F000000008801000300000717
+:1064B0001AF40100EF920007163001009B8422417C
+:1064C000816C000099842242816C0000AF820088B8
+:1064D0001CB000009A84225F0F7C00001A870040E5
+:1064E0000FB00000A384A25A1F7C000069920040F4
+:1064F00081320100A3842220856C0000A0849C0FBF
+:1065000080320000AF8200881CB000004A93005C1B
+:106510001F0001003C95004261310100AF820088FC
+:106520001CB00000900400079630010000002D050B
+:1065300048B10100000000F018B00100A984223A1F
+:10654000016C0000000000008EB001008188004056
+:1065500001B000000000004081B201002E002D05B6
+:1065600048B10100AD84A240E76D00000A00004080
+:106570008F9801008188004001B0000034920040F3
+:10658000813201001C94009503300100AF82008825
+:106590001CB0000000002D0348B1010022002DF0C6
+:1065A0002EB00100282000A696B00100B684221764
+:1065B00096040000E094004B953001008188004C67
+:1065C0008FB00000B88483178032000000000044C0
+:1065D00043C10100BA8485178032000000000048E2
+:1065E00043C10100280000F602CC0100120000A106
+:1065F0002AC80100EF93004081320100CA91004196
+:10660000813001008188004081B20000000000015B
+:1066100000D0010000002E1048B101002800004009
+:10662000F199010000000003F0B10100000000003A
+:10663000F0B10100C4846447613100000000001023
+:1066400062B10100C584A81BE0310000AF827488EC
+:106650001CB000000000004503E0010008002D030D
+:1066600048B10100EA8401FB083000003D8587FB4A
+:1066700022300000000000FA0EB00100000000F817
+:1066800014B00100030000071AF40100EF920007A4
+:1066900016300100E0842241816C0000D484224243
+:1066A000816C0000AF8200881CB00000DF84225F94
+:1066B0000F7C0000380000047E890100D884A65FAA
+:1066C0000F0000004292004005300100DD840040D0
+:1066D00081B20000130000408798010000002D03E4
+:1066E00048B101000C002DF082B00100000000F064
+:1066F00084B00100CE930040053001000000005C32
+:106700001F9001001A8700400FB00000E884A25AD1
+:106710001F7C00006992004081320100E884222041
+:10672000856C0000E5849C0F80320000AF820088F9
+:106730001CB000004A93005C1F0001003C95004221
+:1067400061310100AF8200881CB000009004000796
+:106750009630010000002D0548B10100000000F056
+:1067600018B00100EC84210480200000ED8400407A
+:1067700010C90000C387004B81B000000C850043A6
+:1067800081B00000108500FB22B00000C3870041EB
+:1067900081B000008188004E8FB000000885005A4B
+:1067A0008FB00000F58400478FB00000C38700530E
+:1067B00081B00000C387005681B0000032002D0573
+:1067C00048B101008188A00AE46D0000FB84A24169
+:1067D000197C0000FA84220A80320000818800536C
+:1067E0008FB00000818800548FB000000485220A19
+:1067F00080320000FE84A20AE46D00008188005D02
+:106800008FB00000000000F280B001000000000A1C
+:1068100080D001000285A091816C00008188005E1B
+:106820008FB00000250000408F9801008188004053
+:1068300081B2000006852091E56D0000818800543A
+:106840008FB00000210000408F9801008188004037
+:1068500081B2000032002D0548B101008188A00AF4
+:10686000E46D0000240000408F9801008188004002
+:1068700081B2000037002D0548B10100040000F38B
+:1068800082F40100C387A042836C0000C3870054D8
+:1068900081B00000000000F20EB00100030000070C
+:1068A0001AF4010000B5000D42C9010007000007FD
+:1068B000168801001985220BE67D00000A000040C1
+:1068C00087980100DF950040813201000000004000
+:1068D0000FB001001A87005C1F9000002B8522502A
+:1068E000FD7F00002685A254FD7F00001E852255F5
+:1068F000FD7F00008200004087980100168500405F
+:1069000081B2000016852253FD7F00001480000331
+:1069100042C90100000000F096B001001000004BD9
+:1069200080F401000CBC00408798010026852243BA
+:10693000806C0000FFFF004B808801001685A24399
+:10694000806C00007C9600404799010027854640F6
+:10695000813200002A85A0F0306F00001C851E40A7
+:1069600081B2000000001E4131C30100739200405B
+:10697000253001002F859C0F80320000AF820088F7
+:106980001CB000004A93005C1F000100148000034B
+:1069900042C90100000000F096B0010000002F0580
+:1069A00048B101001000000718E401000008000CC5
+:1069B000E0990100900400079630010000B5000D39
+:1069C00046C9010036853040813200000000000BCE
+:1069D000E6910100000200A146C901000000000B81
+:1069E000E691010004002E0548B1010000001040AE
+:1069F000E1B10100C387004081B00000000000FB4E
+:106A000028B00100000000FB86B00100000000F883
+:106A100014B0010047852246237C000043852240B4
+:106A2000877C0000000000481F900100458522413E
+:106A3000877C0000000000471F900100478522422C
+:106A4000877C0000000000451F9001004785661B01
+:106A50002C300000000000A013B0010000007641BF
+:106A600041C3010076852392156C00007685A2450E
+:106A70001F7C00007A85224BFD7F0000170000D0AC
+:106A8000A2C901000000004027B001000200000A76
+:106A900024C80100AB9200400F3001007485220829
+:106AA0004030000000000041A3C10100F0070012C7
+:106AB00024CC01005085AA412740000001000013AA
+:106AC00080CC01007085264023300000000000408B
+:106AD00083B001006000000384C8010010000010B2
+:106AE00048CD0100170000D0A2C901005D85A24079
+:106AF000836C00006985004183B000000080004283
+:106B000044990100000068213896010000002E50D1
+:106B100049C101006285A244236C000030000003DB
+:106B200048C9010000000044F1B101000C00002040
+:106B3000F0C901000000004461B10100A00000A400
+:106B400062DD01006585A842E031000000000044DC
+:106B500085C001000000004123C001000000004189
+:106B6000A3C101005B85A2418150000070852240D5
+:106B7000236C00000000004461B1010040000010DF
+:106B800062DD01006D85A84081320000AF8200887F
+:106B90001CB000000000000348B10100EE070040F7
+:106BA00025980100170000D02AC80100838500172E
+:106BB00010B0000095940040813201007A850040B9
+:106BC00081B20000AB92009225300100000000402D
+:106BD00031B001007A8522082E3000008385004103
+:106BE00027B00000808000A604B00100060000402D
+:106BF00087980100DF95000A8C30010000000040FA
+:106C00000FB001000000005C1F9001008285229FF0
+:106C1000136C0000020000881CCC0100F5820040CB
+:106C200081B200001A8700413FC30000000000400D
+:106C30000FB001002800000180CE010097852A4096
+:106C4000813000000080001044C901004000004075
+:106C5000819801008C85A2481F7C00008C85A2478A
+:106C60001F7C00008C85A307036C0000800000409F
+:106C7000819801008F85A340026C0000280000016C
+:106C8000F0CD0100918500400FB0000028000040C9
+:106C9000F0CD0100040000400ECC010028000003EC
+:106CA000F0C9010028000000F0C901000000001632
+:106CB000E0B101000000004761B1010020000010B8
+:106CC00062DD01009585A85C1F10000000000040F7
+:106CD00043990100000000F008B00100A0012D4020
+:106CE00000C001006186220F42050000A8859C0FAC
+:106CF000803200000000005C1F8001000080001056
+:106D000042C90100A3852240E36D00000000004756
+:106D100061B101004000001062DD0100A085A840C3
+:106D200081320000AF8200881CB00000A8852207D5
+:106D3000803200000000000342B1010000000007A3
+:106D400042C10100008000A1469901000000005FDF
+:106D5000E1910100C006A2451F7C00001000000365
+:106D600048C9010000002D5429C00100000000F8AE
+:106D700018B00100000000F804B00100000000F8A5
+:106D80000EB00100420000030AC801000C0000A47C
+:106D90000CC80100ED920040813201000000001497
+:106DA00002B001000000001424D001000000001413
+:106DB00010C001001200000810C8010000000040CF
+:106DC00023B00100FE7F000544C901000000000A55
+:106DD000E4B10100D18522018032000000003C4472
+:106DE00023E0010000002EA480B00100000000108C
+:106DF00048C10100BE85A307026C0000BF85680181
+:106E00001AB00000000068071AB001000000000D71
+:106E100002D0010000000005F0B101000000000CEC
+:106E2000F0B1010000000002E0B101000000000D1F
+:106E30000AC00100CB852240036C0000CB852242B2
+:106E4000236C00000000004123C001000000004747
+:106E500061B10100A00000A462DD0100EF852840BF
+:106E600081320000C885004081B20000000000109F
+:106E700080C001000000004761B101000000004037
+:106E800062B10100CD85A84023300000AF820088A8
+:106E90001CB00000EF85004081B2000000003C44BF
+:106EA00023E00100000000A486B0010000002E10C5
+:106EB00048C10100D685A3120E6C0000D78560077B
+:106EC0001AB00000000060121AB001000000680D46
+:106ED00016940100FFFF000B16D80100000068089F
+:106EE0003E9601000000000CF0B10100000000021D
+:106EF000E0B101000000001086C001000000004663
+:106F000061B101002000004362DD0100DE85A85C64
+:106F10001F1000000D86220D146C0000E485220D68
+:106F2000246C00000000000D10C00100E885000D79
+:106F300024D00000000000412BC00100000000151B
+:106F4000A2B101001000002010C80100F0070040AD
+:106F500025980100EA852242236C0000EF8500415C
+:106F600023C000000000004661B101004000001095
+:106F700062DD0100EB85A85C1F000000AF82008885
+:106F80001CB000000000004023B001000D86220D5F
+:106F9000145000000C86A20D0E500000FB85224606
+:106FA0001F7C0000000000461F80010030800010A0
+:106FB00042C90100F9852240E36D0000000000474E
+:106FC00061B101004000001062DD0100F685A840BB
+:106FD00081320000AF8200881CB0000020800003D6
+:106FE000469901000000005FE191010000002D06BC
+:106FF00048B10100000000F818B00100000000F8DE
+:1070000004B0010000861FF00E300000B885004C6F
+:107010000DC0000000002E5F0F800100B88523071F
+:10702000146C00003000001048C90100240000402A
+:10703000F199010000000003F0B101000000000020
+:10704000F0B1010000000016F0B1010024000000C2
+:1070500000C801000000004761B10100A00000A4C9
+:1070600062DD01000986A8461F100000B8850003F4
+:107070000CB00000B885000D18C0000004002E14EC
+:107080000AD001001200000548CD0100FE7F000576
+:1070900042C901000C002AF2E0B10100138622402F
+:1070A000316C000000006018389601001E0000409E
+:1070B00043990100008100F680CE01001786A640AA
+:1070C000813200000000004443C101001986220BF8
+:1070D000ED6D0000080000A142C90100020000A1FE
+:1070E00046C901000F0000FA948801000200004A1E
+:1070F00086E40100000000F60EB001002186224760
+:107100001F7C000004001F430E5000002186A04693
+:107110000F400000000000410FC0010025862248FA
+:107120001F7C00000000004091B0010004000FA28D
+:10713000423100002886004089B000000C0000A207
+:1071400042C901000000004389B001000000004373
+:1071500095D00100000000FC82B001002B86A04108
+:10716000904000000000004191C00100308622479D
+:107170001F7C00003086A043896C000030862045CB
+:10718000896C00003086A0410E40000000000041E4
+:107190000FC001000000004189C001002886A24103
+:1071A00095500000398622481F7C000010000048DE
+:1071B00092F40100FFFF0048908801003786904854
+:1071C000924000000000004193C001000A0000A2AC
+:1071D00044C901000000662093A401003080001023
+:1071E00044C9010012000014F0C90100000000179A
+:1071F000F0B1010012000005E0CD010030000010E8
+:1072000080C801000000004461B10100200000407E
+:1072100062DD01003F86A840813200004A86225C80
+:107220001F7C000000003C4423E0010000002D1002
+:1072300048C1010049862240E36D0000000000467D
+:1072400061B101004000001062DD01004686A840E7
+:1072500081320000AF8200881CB000000000005C9A
+:107260001F8001004D86A2471F7C0000E392004072
+:1072700081320100C686001710B00000EA9200407B
+:107280008132010000002F0348B101005186A007A0
+:10729000164000000000004117C001000000000B74
+:1072A000E4B101000000005017F00100558690F293
+:1072B000164000000000004117C0010000006620D9
+:1072C00017A40100100000142AC80100000000509B
+:1072D0002BE00100000000F22A9401003080001031
+:1072E00042C901005F862240E36D000000000044B7
+:1072F00061B101004000001062DD01005C86A84021
+:1073000081320000AF8200881CB0000000800017AE
+:1073100010DC0100C686004081B2000069869C0F27
+:10732000803200000000005C1F800100008000101F
+:1073300042C9010069862240E36D00000000004759
+:1073400061B101004000001062DD01006686A840C6
+:1073500081320000AF8200881CB000006E862207D8
+:10736000803200000000000342B10100000000076D
+:1073700042C10100008000A1469901000000005FA9
+:10738000E191010004002E0348B101000000000A51
+:10739000E0B1010073862240316C00000C00004017
+:1073A00045990100000060183896010000002E1079
+:1073B00048B1010000000050F1B1010000000008D8
+:1073C000F0B1010000000003E0B101000000004442
+:1073D00061B101000000001062B101007886A84090
+:1073E00023300000AF8200881CB0000000002D5246
+:1073F00011C001001000000348C90100000000F89E
+:1074000018B00100000000F804B00100000000F80E
+:107410000EB001000C0000A40CC8010000003C44A8
+:1074200023E00100000000A486B0010000002E103F
+:1074300048C101008686A3120E6C0000878668078B
+:107440001AB00000000068121AB00100000000101D
+:1074500086C00100000068083E9601000000000C94
+:10746000F0B1010000000002E0B1010000000046A0
+:1074700061B101002000004362DD01008C86A85C40
+:107480001F100000BB86220D146C00009286220D96
+:10749000246C00000000000D10C001009686000D55
+:1074A00024D00000000000412BC0010000000015A6
+:1074B000A2B101001000002010C80100F007004038
+:1074C0002598010098862242236C00009D86004189
+:1074D00023C000000000004661B101004000001020
+:1074E00062DD01009986A85C1F000000AF82008861
+:1074F0001CB000000000004023B001000400220D79
+:1075000014500000BA86A20D0E500000A986224633
+:107510001F7C0000000000461F800100308000102A
+:1075200042C90100A7862240E36D00000000004729
+:1075300061B101004000001062DD0100A486A84096
+:1075400081320000AF8200881CB000002080000360
+:10755000469901000000005FE191010000002D0646
+:1075600048B10100000000F818B00100000000F868
+:1075700004B00100AE861FF00E3000008186004C82
+:107580000DC0000000002E5F0F80010081862307E0
+:10759000146C00003000001048C9010024000040B5
+:1075A000F199010000000003F0B1010000000000AB
+:1075B000F0B1010000000016F0B10100240000004D
+:1075C00000C801000000004761B10100A00000A454
+:1075D00062DD0100B786A8461F1000008186000307
+:1075E0000CB000008186000D18C00000C486225C2B
+:1075F0001F7C00000000005C1F80010000003C4474
+:1076000023E0010000002D1048C10100C486224083
+:10761000E36D00000000004661B101004000001071
+:1076200062DD0100C186A84081320000AF8200887F
+:107630001CB000000000001710B00100C68600401A
+:107640002BB00000008000034499010000000004FA
+:10765000E0B10100CB86229F136C0000020000887D
+:107660001CCC0100F582004081B20000F095004181
+:107670003F430100000000408DB0010000000040C9
+:1076800005B00100DF9500400F3001003087005C3D
+:107690001F900000100000000EF401000000003AEE
+:1076A00001840100030000071AF40100EF920007B3
+:1076B00016300100DA862241816C0000D886224211
+:1076C000816C0000AF8200881CB00000D986225F68
+:1076D0000F7C00001A8700400FB00000E286A25A1B
+:1076E0001F7C00006992004081320100E286222066
+:1076F000856C0000DF869C0F80320000AF8200881E
+:107700001CB000004A93005C1F0001003C95004241
+:1077100061310100AF8200881CB0000090040007B6
+:107720009630010000002D0548B10100000000F076
+:1077300018B001000000000080B00100C387A25F04
+:10774000816C0000A8002D431980010037002DF046
+:1077500024B00100040000F38EF401000F0000F3D8
+:1077600090880100F18622488E6C000036000040AF
+:107770004399010058003D43E7E10100F1861FF005
+:10778000246C0000F08623418F6C0000C387004703
+:1077900081B00000C387004881B000004000004075
+:1077A00043990100B0002DF014B00100F686220AC2
+:1077B00090400000C395004091300100C387A24073
+:1077C00080320000B0002D4581B00100028722F018
+:1077D0002C300000A3002D3083B00100AC002DF34D
+:1077E00082E00100FC86A3412C6C00000000001622
+:1077F00082B0010098002DF082C0010088002DF0B9
+:1078000082D00100000000F298E80100C387204CFC
+:10781000826C00007C002D4198E80100C38720F0B5
+:10782000986C00001A87220A803200004002000C87
+:107830007E8901001A87A64081320000C387004973
+:1078400081B00000200000A680B001000A8722431A
+:10785000216F00001380004080DC01000B87004096
+:1078600081B200001A80004080DC01000B87A25E1C
+:107870000B7D00000000004008B101000D879F85CE
+:10788000803200001187004081B20000EC8222406B
+:10789000577D0000010000405799010011874240C8
+:1078A000813200000000004493930100DD821A5BE6
+:1078B00069930000040000CB81C8010017872240B3
+:1078C000F27F0000C480006F9733010019872240C7
+:1078D000737D0000DE8000418BB300001487004000
+:1078E00081B2000021879C0F8032000000800010D0
+:1078F00042C9010021872240E36D000000000045DD
+:1079000061B101004000001062DD01001E87A84047
+:1079100081320000AF8200881CB000004592220234
+:107920008032000022874240813200000000004483
+:107930009393010045921A02689700002C879C0FD0
+:10794000803200000080001042C901002C872240D4
+:10795000E36D00000000004561B10100400000102F
+:1079600062DD01002987A84081320000AF820088D3
+:107970001CB000004F922202803200002D8742404E
+:107980008132000000000044939301004F921A02DC
+:107990006897000037879C0F80320000008000103D
+:1079A00042C9010037872240E36D00000000004516
+:1079B00061B101004000001062DD01003487A84081
+:1079C00081320000AF8200881CB00000F9822202E0
+:1079D00080320000388742408132000000000044BD
+:1079E0009393010000001A0268970100F982004099
+:1079F00005B00000008000A656B1010056952F404A
+:107A000005B001008887A240E76D0000B8942941C5
+:107A1000E7B1010000000054EF930100000000F204
+:107A20000EB00100290000400D9801000900000778
+:107A300012E40100000000A713C0010003000007CA
+:107A40001AF401000700000716880100FFFF00106C
+:107A500034D801000000000334940100000000400D
+:107A600023B00100201800401198010000B5000D5E
+:107A700042C901006C87220BE67D00004D87604003
+:107A800081320000FFFF000784890100548705C28E
+:107A900024300000580400408132010000002D0510
+:107AA00048B10100898770F0183001006C870040F0
+:107AB00081B200000000704081B201006387A048DD
+:107AC000236C00000000005035D001000080001A37
+:107AD00042C901005D872240E36D000000000042C2
+:107AE00061B101004000001A62DD01005A87A84020
+:107AF00081320000AF8200881CB000002098004056
+:107B000043990100898700F8183001005E87A2417F
+:107B100023500000FFFF001034D8010000000003D4
+:107B200034940100201800401198010000002E1A22
+:107B300048B1010000000044F1B10100000000085C
+:107B4000F0B101000000004261B101002000001A04
+:107B500062DD01006787A809E031000000000041F4
+:107B600023C001000000005035C0010000000044A7
+:107B700011C00100788722410D5000000000004133
+:107B80000FC001007487A0AA0F6C00000000004124
+:107B90000FB001000900000712E40100000000A777
+:107BA00013C00100000000401BB001004B870041E2
+:107BB00017B000000002000912C801004B87834182
+:107BC000174000000000004017B001004B87004143
+:107BD0001BC0000083872340236C0000000000507E
+:107BE00035D001000080001A42C901008087224080
+:107BF000E36D00000000004261B101004000001A86
+:107C000062DD01007D87A84081320000AF820088DC
+:107C10001CB000002098004043990100898700F8BB
+:107C2000183001008187A24123500000000000416C
+:107C30000FC001008687A0AA0F6C00000000004161
+:107C40000FB00100B8942007E4B101005695204020
+:107C5000E7B101001A8700400FB00000FFFF000CE1
+:107C600080D80100C002000C7E8901009B87265449
+:107C7000613100009187870C803200000F000040C6
+:107C80006299010091872840813200009187A254B7
+:107C9000777D00008D87004081B2000096872246E4
+:107CA000197C00000D000040629901000000A8400E
+:107CB00081B200000000A254777D0100928700404D
+:107CC00081B200009B872249197C00000E00004011
+:107CD000629901000000A84081B200000000A25497
+:107CE000777D01009687004081B2000010000040BF
+:107CF000629901000000A84081B200000000A25477
+:107D0000777D01009B87004081B2000030942F55A1
+:107D1000F1930100004000A656B10100F982A24192
+:107D2000E551000064000040E5990100A38744404C
+:107D300081320000A687A293576F00000000004127
+:107D400057C3010000001CAB27B30100F982225089
+:107D5000FD7F0000F9822251FD7F0000F982A241DF
+:107D60001D530000504600401D9B01003805004097
+:107D7000813201000E000048B2CB01001004004027
+:107D800049310100B2872240B56F00000E00004863
+:107D9000B2CB010020040041B5530100F98200403C
+:107DA00081B2000000000051FD8301004016004038
+:107DB0004599010040050040493101001E0000487E
+:107DC000B2CB01001004004081320100000000DA53
+:107DD00091C0010004000048B2CB01002004004023
+:107DE000B533010060162040E5B10100408200403B
+:107DF000B533010008000048B2CB0100FFFF004A84
+:107E0000B48B010020040040813201000A000048C8
+:107E1000B2CB01001000004AB4F70100200400407A
+:107E200081320100F982004081B20000050000406B
+:107E300043990100000000F308B001000400204055
+:107E4000E6B101000300004096E4010000000004D8
+:107E500096C00100C987004B10C90000EC8A0041A0
+:107E600009B00000040000208FB0000004000020D2
+:107E70008FB00000040000208FB00000040000203C
+:107E80008FB00000040000208FB00000040000202C
+:107E90008FB00000040000208FB00000040000201C
+:107EA0008FB00000208B004109B0000004000020CA
+:107EB0008FB00000040000208FB0000004000020FC
+:107EC0008FB00000040000208FB0000004000020EC
+:107ED0008FB00000040000208FB0000004000020DC
+:107EE0008FB00000040000208FB00000528B0045CE
+:107EF00009B00000528B004509B00000528B0045CC
+:107F000009B00000528B004509B0000004000020B9
+:107F10008FB00000040000208FB00000040000209B
+:107F20008FB00000040000208FB00000918B004350
+:107F300009B00000BA8B004309B00000BE8B0044BA
+:107F400009B00000098D004509B0000004000020C0
+:107F50008FB00000040000208FB00000040000205B
+:107F60008FB00000040000208FB00000040000204B
+:107F70008FB00000CA8B004309B00000C98B0043DA
+:107F800009B00000EA8A004509B0000004000020A2
+:107F90008FB00000040000208FB00000040000201B
+:107FA0008FB00000040000208FB00000798C0042E8
+:107FB00009B00000798C004309B00000798C0044BE
+:107FC00009B00000EA8A004509B000000400002062
+:107FD0008FB00000040000208FB0000004000020DB
+:107FE0008FB00000040000208FB0000004000020CB
+:107FF0008FB00000998C004309B0000004000020FD
+:108000008FB00000EA8A004509B00000040000209B
+:108010008FB00000040000208FB00000040000209A
+:108020008FB00000040000208FB00000040000208A
+:108030008FB00000B78C004309B00000B78C00443B
+:1080400009B00000EA8A004509B0000004000020E1
+:108050008FB00000040000208FB00000040000205A
+:108060008FB00000040000208FB00000040000204A
+:108070008FB00000B78C004209B00000040000205F
+:108080008FB00000EA8A004509B00000040000201B
+:108090008FB00000040000208FB00000040000201A
+:1080A0008FB00000040000208FB00000040000200A
+:1080B0008FB00000DF8C004409B0000004000020F5
+:1080C0008FB00000EA8A004509B0000004000020DB
+:1080D0008FB00000040000208FB0000004000020DA
+:1080E0008FB00000040000208FB00000EA8A004238
+:1080F00009B00000F08C004509B00000F08C00458C
+:1081000009B00000EA8A004509B000000400002020
+:108110008FB00000040000208FB000000400002099
+:108120008FB00000040000208FB00000F28C0042ED
+:1081300009B00000F28C004309B00000F28C00444A
+:1081400009B00000F28C004509B0000004000020D6
+:108150008FB00000040000208FB000000400002059
+:108160008FB00000040000208FB000000400002049
+:108170008FB00000040000208FB00000FA8C004493
+:1081800009B00000EA8A004509B0000004000020A0
+:108190008FB00000040000208FB000000400002019
+:1081A0008FB00000040000208FB000000B8D004253
+:1081B00009B00000FB8C004309B000000B8D0044A7
+:1081C00009B00000EA8A004509B000000400002060
+:1081D0008FB00000040000208FB0000004000020D9
+:1081E0008FB00000040000208FB0000004000020C9
+:1081F0008FB000000C8D004309B00000028D0044D8
+:1082000009B00000EA8A004509B00000040000201F
+:108210008FB00000040000208FB000000400002098
+:108220008FB00000EA8A004109B00000778C00425C
+:1082300009B00000778C004309B00000778C00443F
+:1082400009B00000EA8A004509B0000004000020DF
+:108250008FB00000040000208FB000000400002058
+:108260008FB00000EA8A004109B000000D8D004285
+:1082700009B000000D8D004309B000000D8D0044D1
+:1082800009B00000EA8A004509B00000040000209F
+:108290008FB00000040000208FB000000400002018
+:1082A0008FB00000040000208FB000000400002008
+:1082B0008FB00000040000208FB0000004000020F8
+:1082C0008FB00000148D004509B0000004000020AC
+:1082D0008FB00000040000208FB0000004000020D8
+:1082E0008FB00000168D004209B00000040000208D
+:1082F0008FB00000040000208FB0000004000020B8
+:108300008FB00000040000208FB0000004000020A7
+:108310008FB00000040000208FB000000400002097
+:108320008FB00000040000208FB00000228D0043B9
+:1083300009B00000818D004309B00000BE8B0044ED
+:1083400009B00000098D004509B0000004000020BC
+:108350008FB00000040000208FB000000400002057
+:108360008FB00000040000208FB000000400002047
+:108370008FB00000898D004309B00000BE8B00441F
+:1083800009B00000098D004509B00000040000207C
+:108390008FB00000040000208FB000000400002017
+:1083A0008FB00000040000208FB000000400002007
+:1083B0008FB000009A8D004309B000000400002037
+:1083C0008FB00000EA8A004509B0000004000020D8
+:1083D0008FB00000040000208FB0000004000020D7
+:1083E0008FB00000040000208FB000008E8B00438F
+:1083F00009B00000858D004309B00000BE8B004429
+:1084000009B00000098D004509B0000004000020FB
+:108410008FB00000040000208FB0000007002D0581
+:1084200048B10100000000F308B001000600204739
+:10843000E6B101000400004796E401000000004797
+:1084400096D001000000004796D001000000000413
+:1084500096C001008988004B10C90000B28D004908
+:1084600009B000000400002085B0000004000020D6
+:1084700085B000000400002085B00000040000204A
+:1084800085B000000400002085B00000040000203A
+:1084900085B000000400002085B00000040000202A
+:1084A00085B000000400002085B00000040000201A
+:1084B00085B000000400002085B00000040000200A
+:1084C00085B000000400002085B0000004000020FA
+:1084D00085B00000EB8D004209B0000004000020D0
+:1084E00085B000000400002085B0000004000020DA
+:1084F00085B000000400002085B0000004000020CA
+:1085000085B000000400002085B0000004000020B9
+:1085100085B000000400002085B0000004000020A9
+:1085200085B000000400002085B000000400002099
+:1085300085B000000400002085B000000400002089
+:1085400085B00000F18D004609B000000400002055
+:1085500085B000000400002085B000000400002069
+:1085600085B000000400002085B000000400002059
+:1085700085B000000400002085B000000400002049
+:1085800085B000000400002085B000000400002039
+:1085900085B000000400002085B000000400002029
+:1085A00085B000000400002085B000000400002019
+:1085B00085B000000400002085B00000FF8D00425F
+:1085C00009B000000400002085B00000218E0042A8
+:1085D00009B000000400002085B000000400002065
+:1085E00085B000000400002085B0000004000020D9
+:1085F00085B000000400002085B0000004000020C9
+:1086000085B000001C8E004A09B000000400002064
+:1086100085B000000400002085B0000004000020A8
+:1086200085B000000400002085B00000248E0043C7
+:1086300009B000000400002085B000007D8E0044D9
+:1086400009B000000400002085B0000004000020F4
+:1086500085B000000400002085B000000400002068
+:1086600085B000000400002085B000000400002058
+:1086700085B000007C8E004B09B000000400002093
+:1086800085B000000400002085B000000400002038
+:1086900085B00000F48D004109B000000400002006
+:1086A00085B00000F48D004309B00000F48D004453
+:1086B00009B00000F48D004509B00000F48D0046BB
+:1086C00009B00000F48D004709B00000F48D0048A7
+:1086D00009B00000F48D004909B00000F48D004A93
+:1086E00009B00000F48D004B09B00000F48D004C7F
+:1086F00009B00000F48D004D09B000000400002016
+:1087000085B000000400002085B00000DC8E00422F
+:1087100009B000000400002085B00000DC8E004499
+:1087200009B000000400002085B000000400002013
+:1087300085B000000400002085B000000400002087
+:1087400085B000000400002085B000000400002077
+:1087500085B00000DC8E004B09B000000400002052
+:1087600085B000000400002085B000000400002057
+:1087700085B000000400002085B000000400002047
+:1087800085B00000F48E004509B000000400002010
+:1087900085B000000400002085B000000400002027
+:1087A00085B000000400002085B000000B8F00475A
+:1087B00009B000000400002085B00000E88E0045EC
+:1087C00009B000000400002085B000000400002073
+:1087D00085B000005491004609B00000040000205C
+:1087E00085B000000400002085B0000004000020D7
+:1087F00085B000000400002085B0000004000020C7
+:1088000085B00000218E004609B00000FF8D0046B3
+:1088100009B000001A8E004709B000001A8E004807
+:1088200009B000000400002085B000000400002012
+:1088300085B000000400002085B000001C8E004AB6
+:1088400009B000000400002085B0000004000020F2
+:1088500085B000000400002085B000000400002066
+:1088600085B000000400002085B000000400002056
+:1088700085B000007D8E004509B00000248E0043C5
+:1088800009B000001A8E004709B000001A8E004897
+:1088900009B000000400002085B0000004000020A2
+:1088A00085B000000400002085B000007C8E004CE4
+:1088B00009B000000400002085B000000400002082
+:1088C00085B000000400002085B0000004000020F6
+:1088D00085B000000400002085B0000004000020E6
+:1088E00085B00000118F004409B00000118F0042D4
+:1088F00009B00000D58A004709B00000D58A0048B9
+:1089000009B000000400002085B000000400002031
+:1089100085B000000400002085B00000118F004BDE
+:1089200009B000000400002085B000000400002011
+:1089300085B00000F48D004109B00000348F00477D
+:1089400009B000000400002085B000001C8F004723
+:1089500009B000000400002085B0000004000020E1
+:1089600085B000000400002085B000000400002055
+:1089700085B000000400002085B000000400002045
+:1089800085B000001C8F004709B0000004000020E3
+:1089900085B000000400002085B000000400002025
+:1089A00085B000000400002085B000000400002015
+:1089B00085B000000400002085B000000400002005
+:1089C00085B000001C8F004709B00000348F0047BD
+:1089D00009B000001A8E004709B000001A8E004846
+:1089E00009B000000400002085B000000400002051
+:1089F00085B000000400002085B000001C8F0047F7
+:108A000009B000000400002085B000000400002030
+:108A100085B000000400002085B0000004000020A4
+:108A200085B000000400002085B000000400002094
+:108A300085B000000400002085B000000400002084
+:108A400085B00000438F004709B00000438F004805
+:108A500009B000000400002085B0000004000020E0
+:108A600085B000000400002085B000000400002054
+:108A700085B000000400002085B000000400002044
+:108A800085B00000A68F004009B00000C48F0047E9
+:108A900009B00000B88F004809B00000148F0047EB
+:108AA00009B00000148F004709B00000C48F0047D0
+:108AB00009B00000CB8F004709B00000CB8F004801
+:108AC00009B000000400002085B00000B88F004805
+:108AD00009B00000148F004709B00000148F004750
+:108AE00009B00000B88F004809B000000400002061
+:108AF00085B000000400002085B0000004000020C4
+:108B000085B00000DC8E004309B0000004000020A6
+:108B100085B00000DC8E004509B00000DC8E004608
+:108B200009B000001A8E004709B000001A8E0048F4
+:108B300009B000000400002085B00000DC8E004A6F
+:108B400009B000000400002085B00000DC8E004C5D
+:108B500009B000000400002085B0000004000020DF
+:108B600085B000000400002085B00000338F00476E
+:108B700009B00000278F004809B000001B8F004794
+:108B800009B000001B8F004709B00000338F004779
+:108B900009B00000D58A004709B00000D58A004816
+:108BA00009B000000400002085B00000278F0048B5
+:108BB00009B000001B8F004709B000001B8F004761
+:108BC00009B00000278F004809B000000400002011
+:108BD00085B000000400002085B00000CD8F004269
+:108BE00009B000000400002085B00000CD8F0044D3
+:108BF00009B000000400002085B00000040000203F
+:108C000085B000000400002085B0000004000020B2
+:108C100085B000000400002085B0000004000020A2
+:108C200085B00000CD8F004B09B00000040000208B
+:108C300085B000000400002085B000000400002082
+:108C400085B000000400002085B000000400002072
+:108C500085B00000CD8F004309B000000400002063
+:108C600085B00000CD8F004509B00000CD8F0046D3
+:108C700009B00000CD8F004709B00000CD8F00483B
+:108C800009B000000400002085B00000CD8F004A2C
+:108C900009B000000400002085B00000CD8F004C1A
+:108CA00009B00000CD8F004C09B000000400002086
+:108CB00085B000000400002085B000000400002002
+:108CC00085B00000E88F004609B0000004000020D5
+:108CD00085B000000400002085B0000004000020E2
+:108CE00085B000000400002085B000000B8F004715
+:108CF00009B000000400002085B00000E88F0046A5
+:108D000009B000000400002085B00000040000202D
+:108D100085B000000400002085B0000004000020A1
+:108D200085B000000400002085B000000400002091
+:108D300085B00000E990004609B000000400002062
+:108D400085B000000400002085B000000400002071
+:108D500085B000000400002085B000000B8F0047A4
+:108D600009B000000400002085B00000E990004632
+:108D700009B000000400002085B0000004000020BD
+:108D800085B00000E990004609B000000400002012
+:108D900085B000000400002085B000000400002021
+:108DA00085B000000400002085B000000E91004254
+:108DB00009B000000400002085B00000040000207D
+:108DC00085B000000400002085B0000004000020F1
+:108DD00085B000000400002085B0000004000020E1
+:108DE00085B000000D91004A09B000000400002089
+:108DF00085B000000400002085B0000004000020C1
+:108E000085B000000400002085B0000004000020B0
+:108E100085B000000400002085B0000004000020A0
+:108E200085B000000E91004609B00000040000204B
+:108E300085B000001A8E004709B000001A8E004865
+:108E400009B000000400002085B0000004000020EC
+:108E500085B000000400002085B000000D91004A9C
+:108E600009B000000400002085B0000004000020CC
+:108E700085B000000400002085B000000400002040
+:108E800085B000000400002085B000000400002030
+:108E900085B000000400002085B000000400002020
+:108EA00085B000000400002085B000000400002010
+:108EB00085B00000D88F004109B0000004000020F8
+:108EC00085B000000400002085B0000004000020F0
+:108ED00085B000000400002085B0000004000020E0
+:108EE00085B000000400002085B00000E58F00423E
+:108EF00009B000000400002085B00000E58F0044A8
+:108F000009B000000400002085B00000040000202B
+:108F100085B000000400002085B00000040000209F
+:108F200085B000000400002085B00000040000208F
+:108F300085B00000E58F004B09B000000400002060
+:108F400085B000000400002085B00000040000206F
+:108F500085B000000400002085B00000040000205F
+:108F600085B00000E58F004309B000000400002038
+:108F700085B00000E58F004509B00000E58F004690
+:108F800009B00000E58F004709B00000E58F0048F8
+:108F900009B000000400002085B00000040000209B
+:108FA00085B000000400002085B00000E58F004C73
+:108FB00009B000000400002085B00000040000207B
+:108FC00085B000000400002085B0000004000020EF
+:108FD00085B00000F48E004C09B0000004000020B1
+:108FE00085B000000400002085B0000004000020CF
+:108FF00085B000000400002085B000000B8F004702
+:1090000009B000000400002085B00000E88E004C8C
+:1090100009B000000400002085B00000040000201A
+:1090200085B00000A591004609B0000004000020B2
+:1090300085B000000400002085B000004991004286
+:1090400009B000000400002085B0000049910044F0
+:1090500009B000000400002085B0000004000020DA
+:1090600085B000000400002085B00000040000204E
+:1090700085B000000400002085B00000040000203E
+:1090800085B000004991004B09B0000004000020A9
+:1090900085B000000400002085B00000040000201E
+:1090A00085B000000400002085B00000040000200E
+:1090B00085B000000400002085B0000004000020FE
+:1090C00085B000004991004509B000004991004673
+:1090D00009B000001A8E004709B000001A8E00483F
+:1090E00009B000000400002085B00000040000204A
+:1090F00085B000000400002085B000004991004CBC
+:1091000009B000000400002085B000000400002029
+:1091100085B000000400002085B00000E88E004209
+:1091200009B000005491004609B00000040000207E
+:1091300085B000000400002085B00000E88E0046E5
+:1091400009B000000400002085B000000B8F00472C
+:1091500009B000000400002085B0000054910046D2
+:1091600009B000000400002085B0000004000020C9
+:1091700085B000005491004609B0000004000020B2
+:1091800085B000000400002085B00000040000202D
+:1091900085B000005891004309B000000400002091
+:1091A00085B000000400002085B00000040000200D
+:1091B00085B000000400002085B000000B8F004740
+:1091C00009B000000400002085B000005891004361
+:1091D00009B000000400002085B000000400002059
+:1091E00085B000005891004D09B000000400002037
+:1091F00085B000000400002085B0000004000020BD
+:1092000085B000000400002085B000006A91004392
+:1092100009B000000400002085B000000400002018
+:1092200085B000000400002085B00000040000208C
+:1092300085B000000400002085B00000040000207C
+:1092400085B000004791004A09B0000004000020EA
+:1092500085B000000400002085B00000040000205C
+:1092600085B000000400002085B00000040000204C
+:1092700085B000000400002085B00000040000203C
+:1092800085B000006A91004309B00000040000208E
+:1092900085B000001A8E004709B000001A8E004801
+:1092A00009B000000400002085B000000400002088
+:1092B00085B000000400002085B000004791004AFE
+:1092C00009B000000400002085B000000400002068
+:1092D00085B000000400002085B0000004000020DC
+:1092E00085B000007C91004309B00000040000201C
+:1092F00085B000000400002085B0000004000020BC
+:1093000085B000000400002085B000000B8F0047EE
+:1093100009B000000400002085B000007C910043EB
+:1093200009B000000400002085B000000400002007
+:1093300085B000007C91004D09B0000004000020C1
+:1093400085B000000400002085B00000FF8D0042C1
+:1093500009B000000400002085B00000218E00420A
+:1093600009B000000400002085B0000004000020C7
+:1093700085B000000400002085B00000040000203B
+:1093800085B000000400002085B00000040000202B
+:1093900085B000009B91004209B00000040000204D
+:1093A00085B000000400002085B00000040000200B
+:1093B00085B000000400002085B0000004000020FB
+:1093C00085B000000400002085B0000004000020EB
+:1093D00085B00000218E004609B00000FF8D0046D8
+:1093E00009B000001A8E004709B000001A8E00482C
+:1093F00009B000000400002085B000000400002037
+:1094000085B000000400002085B000009B9100465C
+:1094100009B000000400002085B000000400002016
+:1094200085B000000400002085B00000040000208A
+:1094300085B000009D91004A09B0000004000020A2
+:1094400085B000000400002085B00000040000206A
+:1094500085B000000400002085B000000B8F00479D
+:1094600009B000000400002085B000009D91004A72
+:1094700009B000000400002085B0000004000020B6
+:1094800085B000005591004609B00000040000209E
+:1094900085B000000400002085B00000040000201A
+:1094A00085B000005591004609B00000040000207E
+:1094B00085B000000400002085B0000004000020FA
+:1094C00085B000000400002085B000000B8F00472D
+:1094D00009B000000400002085B00000559100464E
+:1094E00009B000000400002085B000000400002046
+:1094F00085B000005591004609B00000040000202E
+:1095000085B000000400002085B0000004000020A9
+:1095100085B000000400002085B00000A391004247
+:1095200009B000000400002085B000000400002005
+:1095300085B000000400002085B000000400002079
+:1095400085B000000400002085B000000400002069
+:1095500085B000004791004A09B0000004000020D7
+:1095600085B000000400002085B000000400002049
+:1095700085B000000400002085B000000400002039
+:1095800085B000000400002085B000000400002029
+:1095900085B00000A391004609B00000040000203F
+:1095A00085B000001A8E004709B000001A8E0048EE
+:1095B00009B000000400002085B000000400002075
+:1095C00085B000000400002085B000004791004AEB
+:1095D00009B000000400002085B000000400002055
+:1095E00085B000000400002085B00000248E004DEE
+:1095F00009B000000400002085B000000400002035
+:1096000085B000000400002085B0000004000020A8
+:1096100085B000000400002085B000000400002098
+:1096200085B000000400002085B000000400002088
+:1096300085B000000400002085B000000400002078
+:1096400085B000000400002085B000000400002068
+:1096500085B000000400002085B000000400002058
+:1096600085B000000400002085B000000400002048
+:1096700085B000000400002085B00000248E004D5D
+:1096800009B000001A8E004709B000001A8E004889
+:1096900009B000000400002085B000000400002094
+:1096A00085B000000400002085B000000400002008
+:1096B00085B000000400002085B0000007002E4B9C
+:1096C0001990010025870004E6B10000D58A2242E6
+:1096D000197C00009A94003A81300100D58A00403C
+:1096E00081B20000D58A2242197C0000FF1F000FC2
+:1096F0001E8C01000594004081320100E58A9C0F18
+:10970000803200000000005C1F800100008000101B
+:1097100042C90100E58A2240E36D000000000045D7
+:1097200061B101004000001062DD0100E28AA84042
+:1097300081320000AF8200881CB00000A9842202A0
+:1097400080320000E68A424081320000000000447E
+:109750009393010000001A0268970100A984004059
+:1097600005B0000005002E4B19900100258700046C
+:10977000E6B100000000004087B00100000000409A
+:109780008DB001000080000342C90100400000A12B
+:1097900044C90100000000F0E0B10100DF950006BF
+:1097A000074001000000000607D00100D4002E5C35
+:1097B0001F90010000000007F0B101000C800003C1
+:1097C00042C90100000000F0F0B1010000000040BB
+:1097D00081B20100000000FE96B00100000000FE12
+:1097E00096C00100000000F0F0B101000000004050
+:1097F00081B20100000000FE96C00100000000FEE2
+:1098000096C00100000000F0F0B10100000000402F
+:1098100081B20100000000FA96C00100000000FEC5
+:1098200096C001000030004B948801000000004603
+:1098300095F001000000004A96C001005E012E3440
+:10984000978401000200004BE4E501006401204020
+:10985000E1B101000900000786E4010000002EA725
+:1098600087C001001000001048C90100100000402E
+:10987000F199010058010043F0C9010058010005A9
+:10988000E0C901000000004461B10100A00000A493
+:1098900062DD01000F8BA84081320000000000054E
+:1098A00048B101001A0000409798010008002E40BE
+:1098B00095B00100178B204B946C00000000004015
+:1098C000F1B10100148B004195C000001080001020
+:1098D00042C901001E8B2240E36D000000000044DD
+:1098E00061B101004000001062DD01001A8BA84048
+:1098F00081320000AF8200881CB00000000000052B
+:1099000048B101009A94004081300100EA8A004089
+:1099100081B200000C80000342C90100000000F881
+:1099200086B00100000000F888B00100238B44409D
+:1099300081320000268BA24CFD7F0000278B004C5B
+:10994000FD930000288B20F0566F0000000000F00F
+:1099500056B3010000001C4081B2010000800010DD
+:1099600044C9010064000040F19901007000000545
+:10997000F0C9010000000043F0B101000000004701
+:1099800061B101002000001062DD01002E8BA844AF
+:10999000E0310000100000108CC80100008000467B
+:1099A00044C9010040000040F19901006801000530
+:1099B000F0C9010064000043F0C901000000004745
+:1099C00061B101000000004662B10100368BA8447D
+:1099D000E0310000AF8200881CB0000009000007E1
+:1099E00086E4010038002EA787C001008B002D05FA
+:1099F00048B101003E8B2243E77D00000000004497
+:109A000045C10100418B2244E77D00000000004C6D
+:109A100045C101000000004A19900100680120A220
+:109A2000E4B101008800004043990100458B230BFD
+:109A3000E56D000000000041199001000080001059
+:109A400044C9010050000040F19901005801004351
+:109A5000F0C9010058010005E0C901000000004400
+:109A600061B101000000001062B101004A8BA84002
+:109A700081320000AF8200881CB000005C002E051F
+:109A800048B101000080000342C90100000060F0FD
+:109A900096B001009A94004181300100EA8A0040AA
+:109AA00081B20000558BA249197C0000860000405D
+:109AB00047990100598B0040E5B1000086002F490D
+:109AC00019800100598BA2F2803200008B00004007
+:109AD0004799010000000042E79101005C8BA2461B
+:109AE000197C0000A000004047990100608B0040F5
+:109AF000E5B10000A0002F4619800100608BA2F2A2
+:109B0000803200008B0000404799010000000041B6
+:109B1000E7910100A80000404399010034002DF0B6
+:109B200024B00100000000FB0CB00100000000FBAD
+:109B300010B00100000000FB12B001000F0000F3A4
+:109B400016880100040000F314F401008B8B2640FA
+:109B500081320000738B220A166C000058003D43CE
+:109B600013E00100000000F882B00100040022F0C0
+:109B7000843000008795004081320100AF82008868
+:109B80001CB000000000000548B1010000000041C9
+:109B900013C00100728BA043136C00000000004052
+:109BA00013B00100688B004115D000008B8B220A96
+:109BB0008032000058003D4313E00100000000F82F
+:109BC00082B00100040022F084300000879500403C
+:109BD0008132010040002040E1B10100AF820088E5
+:109BE0001CB000000000000548B101008B8B224131
+:109BF000155000000000004111C001007F8BA04300
+:109C0000116C00000000004011B0010058003D43FD
+:109C100011E00100000000F836B00100040022F05D
+:109C2000003000000000005083B00100D9940047CC
+:109C300061310100AF8200881CB000004292000533
+:109C4000483101000000004561B1010040000010F2
+:109C500062DD0100878BA84081320000AF8200885E
+:109C60001CB000007B8B000548B10000370020408D
+:109C7000E7B101000B95005181300100EA8A0040F4
+:109C800081B2000034002E41F5B101000011004006
+:109C9000E5990100938B00481990000034002E4193
+:109CA000F5B1010000110040E599010000800003BA
+:109CB00042C90100000000F894B00100988B2245D1
+:109CC000237C0000B0002FF08CB00100000060F099
+:109CD0008CC00100900000404399010035002DF038
+:109CE0008CB0010058003E43E7E101009D8B224803
+:109CF000197C0000000000418DC001000000680ACE
+:109D00008CC0010038002A4AE0B1010028000000A0
+:109D1000E0C901003C00201BE0B1010010800003FD
+:109D200042C90100000000F838B00100000000F84E
+:109D300026B00100040022F802300000AB8B2301A2
+:109D4000146C0000000000F880B00100000000F872
+:109D500082B001004C0020F0E4B10100440020403A
+:109D6000E0B1010048002041E0B10100A8002D1041
+:109D700032B00100C39500F024300100B48BA2443E
+:109D8000816C0000B28B2241197C00006E93004070
+:109D90003B300100D88BA2083C300000B48B00405F
+:109DA00081B20000AB92004081320100D88BA20842
+:109DB0003C3000005000201CE0B101005400201392
+:109DC000E0B101004E002001E4B101004000200A92
+:109DD000E0B101000B95005F81300100EA8A00408C
+:109DE00081B2000037000040479901004D9300F315
+:109DF00094300100938B224A80320000C08B0040D7
+:109E000081B2000037000040479901004D9300F3F4
+:109E10009430010058003E4397E001000000001B11
+:109E2000F0B101001F006000008C0100EA8A85117A
+:109E3000803200000480000342C90100B0002FF00E
+:109E40008CB00100000060F08CC001000B95005F39
+:109E500081300100EA8A004081B20000CA8B0049CB
+:109E600019800000CF8B2241197C00006E930040C6
+:109E70003B300100D38BA2083C3000000B95005F03
+:109E800081300100EA8A004081B20000AB920040BC
+:109E900081320100D38BA2083C3000000B95005F9B
+:109EA00081300100EA8A004081B2000050002D108C
+:109EB00032B0010054002DF038B001004E002DF0FA
+:109EC00026B0010040002DF202B00100000000F0B9
+:109ED00014B00100300000108CC801000080004662
+:109EE00044C9010068012D4461B10100100068F20D
+:109EF00080C8010000000008F0B101005801000511
+:109F0000E0C901000000000B37B001000000004074
+:109F100036D001005C012E4010C001000000000698
+:109F200080C001000000005281D00100A0940040D8
+:109F3000E43101002000004662DD0100E48BA8400E
+:109F400023300000E592004081320100ED92004094
+:109F500081320100F28B82412340000020800010FA
+:109F600042C90100EF8B2240E36D00000000004673
+:109F700061B101004000001062DD0100EC8BA840DF
+:109F800081320000AF8200881CB000000000000594
+:109F900048B101000000001032B001000000004193
+:109FA00023B001000080001944C90100FA8B22414E
+:109FB000197C0000F68BA3010C6C0000F78B0006E7
+:109FC00004B000000000000104B00100F98B200281
+:109FD000366C00000000001B04B00100FD8B000285
+:109FE000E0B10000FC8BA3010C6C0000FD8B0006AF
+:109FF00004B000000000000104B00100000068028D
+:10A0000016940100FFFF000B16D80100000068083D
+:10A010003E9601000000001CF0B101000000004667
+:10A0200061B101002000001962DD0100028CA8135B
+:10A03000E0310000398C22021450000044002D024F
+:10A040000CD00100298CA20202500000108C225C6E
+:10A050001F7C00002080000342C901000F8C2240B9
+:10A06000E36D00000000004761B1010040000010F6
+:10A0700062DD01000B8CA84081320000AF820088B5
+:10A080001CB000000000000548B1010044002D5C38
+:10A090001F80010048002DF038B001004C002DF069
+:10A0A00026B0010038002FF202B001002A8C2201F4
+:10A0B000146C00001D8C22461F7C0000000000462E
+:10A0C0001F80010020002D0348B101001C8C22409C
+:10A0D000E36D00000000004461B101004000001089
+:10A0E00062DD0100198CA84081320000AF82008837
+:10A0F0001CB0000038002F0548B10100000000F836
+:10A1000094B0010038002DF096B001000000004C22
+:10A11000E1C101002000000348C901000000224AFB
+:10A12000F1B1010044000005F0C901000000004A3F
+:10A13000F0B101000000004BE0B101000000004759
+:10A1400061B10100A00000A462DD0100268CA85CC2
+:10A150001F1000002A8C000548B10000000000021A
+:10A1600038C00100348C220680320000000000500C
+:10A1700033C00100328CA202366C000004008F0D47
+:10A1800042310000100000F810C801000000005C1F
+:10A1900011800100F007004037980100E88B00A112
+:10A1A0001AB000000000000210C00100E88B00029D
+:10A1B00036D000005000201CE0B1010054002013F4
+:10A1C000E0B101004E002001E4B101004000200A8E
+:10A1D000E0B101003E8C005F01B0000037002D4669
+:10A1E00001B00100040000F380F401003D8CA043A5
+:10A1F000816C00000000005501B0010040002040CB
+:10A20000E1B101000080001942C90100448C2240E4
+:10A21000E36D00000000004661B10100400000193C
+:10A2200062DD0100418CA84081320000AF820088CD
+:10A230001CB00000EA920040813201003080001022
+:10A2400042C901004B8C2240E36D00000000004435
+:10A2500061B101004000001062DD0100488CA8409F
+:10A2600081320000AF8200881CB0000060012F0521
+:10A2700048B101000000000BE4B1010000000050F3
+:10A2800017F00100508C90F21640000000000041D1
+:10A2900017C001000000662017A40100320000A6CC
+:10A2A0002AC00100000000F22A940100538C4548A6
+:10A2B0006131000000D0001E62DD0100588C284092
+:10A2C00005300000548C2248777D00005B8C0040F4
+:10A2D00081B200000000001562B10100648C2840CA
+:10A2E00081320000588C004081B2000000001D0047
+:10A2F00092B00100618C2241197C000000800003B3
+:10A3000042C90100B09200F8003001005E8CA24109
+:10A310003B500000658C004900B00000FF07001EA4
+:10A32000008C0100B092004081320100658C004930
+:10A3300000B0000000001D4719800100688C225FFA
+:10A34000016C0000ED95004081320100C5870000DE
+:10A3500080B000006F8C225C1F7C00002080000316
+:10A3600042C901006F8C2240E36D000000000047ED
+:10A3700061B101004000001062DD01006C8CA8405A
+:10A3800081320000AF8200881CB000006F8C400555
+:10A3900048310000FFFF000794890100758C85CAD1
+:10A3A00094300000ED95185C1F0001000E00000FB6
+:10A3B0001E8C0100E686004081B200000B9518005B
+:10A3C00080300100EA8A0047198000000000004048
+:10A3D00019800100EA8A2247197C0000AB920040F4
+:10A3E000813201007C8CA20880320000EA8A0040A1
+:10A3F00081B20000A09400400D3001009C0100409B
+:10A4000045990100FFFF000B988801008B002D503B
+:10A4100017F00100828C904C1640000000000041B3
+:10A4200017C00100848C2243E77D00000000004437
+:10A4300045C101000000662017A40100680100402A
+:10A44000439901005C012EF280B0010002006240DD
+:10A450007ECD01000000005781C0010000002E10D9
+:10A4600048B1010003000040F08D01000000000829
+:10A47000F0B1010058010005E0C9010000000044EE
+:10A4800061B101000000001062B101008E8CA84093
+:10A4900081320000AF8200881CB00000000000057F
+:10A4A00048B10100928C454861310000005000081D
+:10A4B00062DD0100988C284005300000938C224812
+:10A4C000777D0000B0921D0800300100EA8A00404C
+:10A4D00081B20000EA8A1D47198000003500004063
+:10A4E00047990100010063F384C801009D8CA043DB
+:10A4F000856C00000000634085B00100A8000040AA
+:10A500004399010037002FF024B00100010063F3EC
+:10A5100082CC0100A88CA2419E060000EA8A224457
+:10A5200083700000360000404399010058003D430D
+:10A53000E7E10100EA8A1FF0246C0000ED95004875
+:10A5400081300100C5872341836C0000C587004727
+:10A5500081B0000058003D4385E00100000000F894
+:10A5600036B00100000000F000B0010028000040FB
+:10A5700083980100D994004761310100AF820088BF
+:10A580001CB0000000002D0348B1010008002DF0B0
+:10A5900094B00100000000F88EB0010090002DF092
+:10A5A00014B001000000000548B10100998BA240E1
+:10A5B0008F7C0000B68C22478F7C0000998B00486E
+:10A5C00019900000258D004081B2000036002D5DFD
+:10A5D00005B4010037002DF380B00100000000F346
+:10A5E0008EB001005C003D4381E00100A8002DF029
+:10A5F00094B00100000000F024B001002000001021
+:10A6000086DC01004080000344C90100B191004A8A
+:10A61000F031010036002F5C1F900100C48CA25065
+:10A620008F50000034002040E1B10100EA8A004070
+:10A6300081B200000000634181C00100C78CA043CB
+:10A64000816C00000000634081B0010037002047AA
+:10A65000E6B10100EA8A2247803200000400004788
+:10A660000CF401000000004F8F840100DC8C2247B5
+:10A670000C6C000058003D4381E00100DC8C1FF0B1
+:10A68000246C00000000005C1F80010000800010AE
+:10A6900042C90100D58C2240E36D00000000004556
+:10A6A00061B101004000001062DD0100D28CA840C1
+:10A6B00081320000AF8200881CB00000D58C42407F
+:10A6C00005300000000000449393010000001A5D73
+:10A6D00069930100DA8C23410D6C0000B78C0005F2
+:10A6E00048B10000ED95000548310100C5870048DC
+:10A6F00081B00000EA8A22408F6C00000B95005F59
+:10A7000081300100EA8A004081B20000A2000040CE
+:10A7100043990100000000F384B00100A6002D4918
+:10A7200019900100020000F280F40100B8002D40F1
+:10A7300081B20100000000F280C001000000004072
+:10A7400082F801001900004081980100EB8CA040C4
+:10A75000826C00002C01004081980100EB8CA3402A
+:10A76000826C00000000004180B00100ED8C204CA4
+:10A77000856C00000000004185C00100860020407B
+:10A78000E4B10100A2002042E6B10100EA8A0040E3
+:10A7900081B200009A94005081300100EA8A0040A2
+:10A7A00081B200000480000342C90100040022F0CD
+:10A7B00080300000000000408DB00100DF950040B7
+:10A7C00087300100B0002F5C1F900100000060F096
+:10A7D00080C001000B95005F81300100EA8A0040D3
+:10A7E00081B200000400004081B20000EA8A2246E3
+:10A7F000197C0000A000004047990100010062F2AE
+:10A8000096CC0100EA8AA640813200000B95004AEE
+:10A8100081300100E094004695300100EA8A004052
+:10A8200081B20000EA8A2249197C000086000040BB
+:10A8300047990100010062F280CC0100EA8AA6403B
+:10A84000813200000B95004A81300100E0940047FE
+:10A8500095300100EA8A004081B200004292004037
+:10A8600081320100EA8A005C1F900000EA8A004001
+:10A8700081B20000EA8A004081B20000BA000040C4
+:10A8800047990100010062F280C80100118D9040DB
+:10A8900080320000FFFF624081980100A400004068
+:10A8A00047990100EA8A2240E56D0000EA8A0041EA
+:10A8B000E5C100009A94004D81300100EA8A004011
+:10A8C00081B200005C00004047990100040022F0C2
+:10A8D0009630000000000040E1B10100008000035C
+:10A8E00044C901000000004BE0B10100000000403D
+:10A8F0008DB00100DF950040873001008B000040E3
+:10A9000047990100218D80F396300000000000403F
+:10A91000E78101000000004719900100EA8A005C0D
+:10A920001F900000340000404599010001000040E4
+:10A93000F599010000110040E5990100AB9200403B
+:10A9400081320100368DA2088032000037000040BD
+:10A9500047990100000000F382B00100000063513C
+:10A9600083D001003400004047990100010063F3E7
+:10A9700084CC01002E8D9F42803200000000634293
+:10A9800085B001000000004503F001000000000157
+:10A9900000C00100308D375C613100000000001BF9
+:10A9A00062B10100318DA84B1910000000000000B9
+:10A9B00062B10100338DA840813200001A87174030
+:10A9C00081B200000080000342C9010090002DF018
+:10A9D00094B00100AC002DF030B0010035002DF036
+:10A9E00028B0010058003E43E7E1010001000018D3
+:10A9F000F0C901000000004AE0B101003800200069
+:10AA0000E0B101003C00201BE0B10100400020400B
+:10AA1000E1B10100000000402BB00100EF940040C4
+:10AA20000D3001000000001816C00100458DA01473
+:10AA3000164400000000004117C001000E0000A2F3
+:10AA400044C9010000000018F8B10100B0002D1445
+:10AA5000F8B1010010500040879801004E8D224A45
+:10AA6000197C00000030004386C801000030000B54
+:10AA700016C801004E8DA440813200000000004144
+:10AA800017C0010001006E43869801002695003032
+:10AA900081300100528DA0411740000000000041AC
+:10AAA00017C00100598D224A197C0000080000A23D
+:10AAB00044C90100CC002DABF9B10100000000AB8E
+:10AAC00017C00100588DA0F016440000000000419E
+:10AAD00017C00100000064F082B001009000004047
+:10AAE000459901000000604131C00100BC000040F8
+:10AAF000439901005F8D060C80320000A00020F217
+:10AB0000E4B1010004000946191000009C01004056
+:10AB100045990100FFFF000B988801008B002D5024
+:10AB200017F00100648D904C1640000000000041B9
+:10AB300017C00100668D2243E77D0000000000443D
+:10AB400045C101000000662017A401006801004013
+:10AB5000439901005C012EF280B0010002006240C6
+:10AB60007ECD01000000005781C0010000002E10C2
+:10AB700048B1010003000040F08D01000000000812
+:10AB8000F0B1010058010005E0C9010000000044D7
+:10AB900061B101000000001062B10100708DA84099
+:10ABA00081320000AF8200881CB000000000000568
+:10ABB00048B10100748D4548613100000050000823
+:10ABC00062DD0100758DA8400530000035001D4094
+:10ABD00047990100010063F384C801007B8DA04305
+:10ABE000856C00000000634085B001003700004024
+:10ABF00047990100010063F382CC01008B00004003
+:10AC00004799010000000045E79101000B95005FA6
+:10AC100081300100EA8A004081B200003700004024
+:10AC2000479901004D9300F394300100258D224A8D
+:10AC300080320000C08B004081B20000370000402D
+:10AC4000479901004D9300F394300100908B224A04
+:10AC500080320000C08B004081B20000360000400E
+:10AC600043990100000000FB12B001000F0000F347
+:10AC700090880100040000F30CF40100BA8B220656
+:10AC8000906C00005C003D4313E00100A8002DF033
+:10AC900094B0010037002FF024B0010036002A5094
+:10ACA000E7D101000000634113C00100958DA0436E
+:10ACB000136C000000000040E7B10100AF910010EC
+:10ACC00086300100AF8200881CB00000978D4205DD
+:10ACD000483100000000004493930100BA8B1A5DD4
+:10ACE0006993000036002D1086B001005C003D43E2
+:10ACF000E7E10100A8002DF094B0010035002FF02D
+:10AD000024B0010001006BFB84C80100A28DA043A8
+:10AD1000856C000035002040E7B1010000000040D4
+:10AD200081B20100010063F312C80100A58DA043A8
+:10AD3000136C000000000040E7B1010040800003F8
+:10AD400044C90100B191004AF0310100AF8200888E
+:10AD50001CB00000A88D42054831000000000044EE
+:10AD60009393010000001A5D6993010037000040D1
+:10AD700047990100110063F382CC0100A18C2241AC
+:10AD80009E060000350000404399010058003D43F5
+:10AD9000E7E10100000000F836B00100AB8C00F0E4
+:10ADA00000B000005E012D0548B10100B38D65F2D1
+:10ADB0001230000000993F4213F00100B88D224785
+:10ADC000E77D0000F58275881CB00000B28D004060
+:10ADD00081B2000000000047E791010000007542C9
+:10ADE000199001007500004061990100BA8DA8B169
+:10ADF0000C3000003694001094300100AF820088BF
+:10AE00001CB000005E012E0548B10100C0A83D46FF
+:10AE10000DE001000000004097B00100C48D224009
+:10AE2000E16D00000400024197400000C18D005018
+:10AE300043C10000D08D224B803200000000624BE5
+:10AE4000129401000900000796E40100000000A729
+:10AE500097C001003000001094C801000080004A33
+:10AE60004499010000000042F1B101005E01004B75
+:10AE7000F0C901005E010005E0C9010000000044C6
+:10AE800061B101002000004A62DD0100CE8DA840C2
+:10AE9000813200000080001044C901000000005011
+:10AEA000F1B101000400000996E40100000068A867
+:10AEB00097C00100D4000005E0C901000000004473
+:10AEC00061B101000000001062B10100D68DA84000
+:10AED00081320000AF8200881CB0000000993F4220
+:10AEE00013F00100DA8D6540813200003F0000F36D
+:10AEF0009688010000000040E7B101000000755590
+:10AF000061B101000000000662B10100DE8DA840C1
+:10AF100081320000E38D224B803200000000004BA4
+:10AF200062B10100E18DA84081320000000000976D
+:10AF300013B001000000009697B00100E98D2009D0
+:10AF4000966C0000E98D1F0996240000F5820088A8
+:10AF50001CB00000E48D004081B200009A940057BC
+:10AF600081300100D58A000548B100002E00004064
+:10AF700043990100EF8D22F3803200009A94004241
+:10AF8000813001001A87004081B200000B95005209
+:10AF900081300100D58A0042198000009A94003A5D
+:10AFA000813001000B95005281300100D58A0040AC
+:10AFB00081B200000000004005B00100AD930040E8
+:10AFC00095300100D58A2240956C0000FA8DA24090
+:10AFD0001F7C0000B0920040813201001A870040BF
+:10AFE00081B200000480000342C90100000000F2A9
+:10AFF00002B0010058930052953001005F93004B5E
+:10B0000002B000001A87004081B200009495004011
+:10B0100095300100068EA20880320000068EA2162E
+:10B02000803200001A872242197C00000000004B89
+:10B03000199001009A94003A813001001A8700406B
+:10B0400081B20000002300A616B00100098E831E05
+:10B05000803200000008000B16DC01000000000038
+:10B060002AC00100E3940008803001000D8E005ECC
+:10B07000179000000495004361310100BD9100402C
+:10B080008D300100EB9400071614010000800010C1
+:10B0900042C90100158E2240E36D0000000000430C
+:10B0A00061B101004000001062DD0100128EA84075
+:10B0B00081320000AF8200881CB000008C94005EDA
+:10B0C00005100100B092004081320100198E220962
+:10B0D000803000000B95004013300100DA8A000533
+:10B0E00048B10000DD93004081320100D58A004064
+:10B0F00081B200000000004A1F900100208E224310
+:10B100003D7C000000000044199001000000004355
+:10B110003D800100218E00421990000014002D4551
+:10B120001F9001007D8E831E803200007D8E0044C2
+:10B1300019900000A292004081320100358EA208D1
+:10B1400080320000358EA21680320000318EA2427D
+:10B15000197C00000082000204DC0100A09800407D
+:10B160004799010030050041893001002E8EA2412F
+:10B17000197C0000B0920040813201001A87004023
+:10B1800081B2000058930015943001005F93004B8A
+:10B1900002B000001A87004081B20000DD93004039
+:10B1A000813201000000004B199001009A94003A8E
+:10B1B000813001001A87004081B20000388E22429F
+:10B1C000197C0000DD93004081320100398E00407F
+:10B1D00081B20000AD93004081320100658E2241B2
+:10B1E000197C0000C000001598C80100658EA00BF6
+:10B1F000996C00003000001080C801000080004001
+:10B200004499010000000050F1B10100000000036A
+:10B21000F0B101000000004261B1010000000040F7
+:10B2200062B10100418EA800E0310000AF820088C9
+:10B230001CB000000000000548B10100C00000156E
+:10B2400098C8010030002E0B99D0010000006A5010
+:10B2500099C00100C000620180CC01000C80000395
+:10B2600042C901002D002DF022B001000000004C69
+:10B2700080C001000000005C23800100D4003F4139
+:10B28000E7E101000B000011E4F501002F00204769
+:10B29000E7B50100528E230B816C00000000004FC7
+:10B2A000E59101000000000880B001000000000BE3
+:10B2B00003B001000000001502D00100E39400007B
+:10B2C0002A4001000000004361B10100400000106D
+:10B2D00062DD0100578EA84081320000AF820088F5
+:10B2E0001CB00000B092000548310100C000000110
+:10B2F00080CE0100638E2611003000001000000097
+:10B300002AC801000000000880B001000000000110
+:10B3100080C00100C00000409998010000000001B9
+:10B3200098D00100E394004C02300100C0000040BE
+:10B33000039801006A8E004081B2000030002F089F
+:10B3400080B00100C0000015F4C90100C000000178
+:10B35000E4CD0100C000004003980100E394000028
+:10B360002A4001006F8E22441F7C0000AC002F4059
+:10B3700013B0010000000001E0C10100B000004076
+:10B3800047990100708E0001E0D10000BD9100409E
+:10B390008D300100806300A616B00100EB94000719
+:10B3A000161401000080001042C90100788E22406E
+:10B3B000E36D00000000004361B101004000001097
+:10B3C00062DD0100758EA84081320000AF820088E6
+:10B3D0001CB000008C94005E051001007B8E2209D9
+:10B3E000803000000B95004081320100D58A0005B5
+:10B3F00048B100007D8E004A1F9000000000000050
+:10B4000010B0010024002D1510C0010028002DF0FF
+:10B4100016B0010022002DF026B0010014002FF21A
+:10B420000CB0010000000001E0D10100000000109C
+:10B4300032B001000000000B1BB0010004001F151A
+:10B440001A5000000000004023B00100000000017D
+:10B450002AB001004B94004035B000002F0020407E
+:10B46000E7B10100C18EA2451F7C00002400200B23
+:10B47000E0B1010028002013E0B101002200200605
+:10B48000E4B10100978E225C1F7C00000000005C8C
+:10B490001F8001003080001042C90100978E2240B9
+:10B4A000E36D00000000004761B1010040000010A2
+:10B4B00062DD0100938EA84081320000AF820088D7
+:10B4C0001CB000000000000548B101000080001918
+:10B4D00042C90100BA8E2240E36D0000A88E2242CC
+:10B4E000197C000005940040813201005792004011
+:10B4F00081320100B58E224B8032000000000043F3
+:10B5000061B101004000001062DD01009E8EA84084
+:10B5100081320000AF8200881CB00000A48E22415E
+:10B52000197C0000C692004011300100A58E000574
+:10B5300048B10000B092004081320100A78E22097C
+:10B54000803000000B95004081320100F9820040FC
+:10B5500005B0000005940040813201005392004084
+:10B56000813201000000004361B101004000001081
+:10B5700062DD0100AB8EA84081320000AF820088FE
+:10B580001CB00000B18E2241197C0000C692004020
+:10B5900011300100B28E000548B10000B0920040A9
+:10B5A00081320100B48E2209803000000B950040EA
+:10B5B00081320100F982004005B000000000004324
+:10B5C00061B101004000001062DD0100B68EA840AC
+:10B5D00081320000AF8200881CB00000000000052E
+:10B5E00048B10100BD8E2241197C0000C692004086
+:10B5F00011300100BE8E000548B10000B09200403D
+:10B6000081320100C08E2209803000000B9500407D
+:10B6100013300100DA8A004005B0000000800019F4
+:10B6200042C90100C88E2240E36D000000000043C3
+:10B6300061B101004000001062DD0100C48EA8402D
+:10B6400081320000AF8200881CB0000000000005BD
+:10B6500048B101000000004005B00100CC8E22413D
+:10B66000197C0000C692004011300100CD8E00050B
+:10B6700048B10000B09200408132010008002D0A5C
+:10B6800084B00100000000F082B0010014002040EE
+:10B69000E1B10100D28E031E80320000D38E004142
+:10B6A00087B000002100004087980100CE93004041
+:10B6B000813201000000005C1F900100D78E22093A
+:10B6C000803000000B95004013300100DA8E2244D8
+:10B6D000197C00000B95004F8130010000000044F0
+:10B6E00019800100D58AA24A1F7C0000DA8A004036
+:10B6F00081B20000BA002040E5B10100E08E9C1745
+:10B7000080320000CC000040439901009D9500402C
+:10B71000813201004495004013300100C000004018
+:10B7200043990100C4002DF082B00100789500F02B
+:10B7300084300100B092004081320100DA8A22098F
+:10B74000803000000B95004013300100DA8A004081
+:10B7500081B200002E00004043990100EC8E22408F
+:10B76000E76D00003200004043990100F48EA240D2
+:10B77000E56D00009A930040813201002400200B07
+:10B78000E0B1010028002013E0B1010022002006F2
+:10B79000E4B101001400200AE0B10100DA8A2209B4
+:10B7A000803000000B95004013300100DA8A004021
+:10B7B00081B200009A93004081320100539300400F
+:10B7C00081320100028F2241197C00000000000B31
+:10B7D00099B0010004001F1598500000028F20014D
+:10B7E000986C00007000000348C9010000002E465C
+:10B7F0001F90010000000050F1B1010000000003A3
+:10B80000F0B101000000004261B10100A00000A4FD
+:10B8100062DD0100FF8EA800E0310000000000059D
+:10B8200048B10100AC002F0010B001000000000181
+:10B83000E0C1010014002F1510C001000000000A33
+:10B8400080B001000000600180D0010000000047CE
+:10B8500019900100848E2209803200000B950009A6
+:10B8600080300100848E004013B00000008000038F
+:10B8700042C90100000000F082B001001300004046
+:10B88000879801000000004C43C10100CE9300F0F6
+:10B8900084300100D58A005C1F9000002C002040FD
+:10B8A000E7B101002D002040E7B10100D58A004238
+:10B8B00019800000C093004081320100E0940048EC
+:10B8C000953001000000004561B10100400000100A
+:10B8D00062DD0100178FA84013300000AF8200889E
+:10B8E0001CB000001D8F000548B100001C8F0040F7
+:10B8F00013B000000000000012B00100080000407A
+:10B900004399010014002DF082B00100040022F0E0
+:10B91000843000001300004087980100CE9300405F
+:10B92000813201000000005C1F900100358F00098A
+:10B9300000B00000D58A8742191000008B002F4705
+:10B9400019800100D58A0040E79100002F000040D7
+:10B9500047990100338F2247E77D00003492004071
+:10B96000E7310100338F2200803200002E8FA24089
+:10B970001F7C0000B092004081320100338F0040F4
+:10B9800081B20000300000404399010032002DF2E6
+:10B9900094B00100589300F2023001005F93004B15
+:10B9A00002B000000000000548B10100348F0040E3
+:10B9B00001B000000000004005B001003A8F2200F5
+:10B9C00080320000398FA242197C0000AD93004004
+:10B9D000813201003A8F004081B20000DD930040C7
+:10B9E00081320100C68F225C1F7C00000000005CD9
+:10B9F0001F8001000080001042C90100428F2240D8
+:10BA0000E36D00000000004561B10100400000103E
+:10BA100062DD01003F8FA84081320000AF820088C4
+:10BA20001CB00000C68F000548B10000A292004083
+:10BA300081320100498FA20880320000498FA2168E
+:10BA4000803200009A94004D813001000082000293
+:10BA500004DC01001A87004081B20000740000403D
+:10BA600043990100000000F882B00100000000F0DE
+:10BA700084B001000000004196B00100578F2242BF
+:10BA8000961400000080001044C901006400684062
+:10BA90009798010000000041F0B101000000004251
+:10BAA000F0B1010070000005E0C901000000004590
+:10BAB00061B101002000001062DD0100548FA84038
+:10BAC000813200000000005C1F9001000000004572
+:10BAD00061B101004000001062DD0100588FA85CD8
+:10BAE0001F000000AF8200881CB000005E012D0521
+:10BAF00048B101005C8F65F21230000000993F42AE
+:10BB000013F00100618F2247E77D0000F582758800
+:10BB10001CB000005B8F004081B2000000000047B5
+:10BB2000E79101000400750996E40100008000100F
+:10BB300044C9010000000044F1B10100000068A800
+:10BB400097C0010000000003E0B101000080000385
+:10BB5000449901000000004461B1010000000010A0
+:10BB600062B10100698FA840E1310000AF82008816
+:10BB70001CB0000000993F4213F001006D8F650575
+:10BB8000483100003F0000F39688010000000040AB
+:10BB9000E7B101000000754081B20100758F224BB2
+:10BBA000803200000000005561B101000000004B30
+:10BBB00062B10100738FA8408132000000000007CD
+:10BBC00016B001000062000B16DC01003492004048
+:10BBD000813201008D8F220080320000E393005FEC
+:10BBE00001100100778F2240956C0000008000104A
+:10BBF00044C9010000000050F1B101000000000341
+:10BC0000F0B101000000004261B10100000000102D
+:10BC100062B101007F8FA800E0310000AF82008890
+:10BC20001CB000000000000548B1010004800003C2
+:10BC300042C90100000000F202B001005893005216
+:10BC400095300100B092004081320100778F22418F
+:10BC5000975000000C80000342C90100000000F072
+:10BC600000B001000000005C018001005F93004B08
+:10BC700002B00000778F000548B10000EB9400404F
+:10BC8000033001001780000344C9010000F0000CDC
+:10BC9000968801000000634C97F0010010800003BB
+:10BCA00044C90100000000ABE1B101008C94005ECA
+:10BCB00005100100030000071AF401000700000747
+:10BCC0001688010000B5000D46C90100978F30406D
+:10BCD000813200000000000BE681010000B7000D7A
+:10BCE00046C901000000000BE68101001000100FA2
+:10BCF00094F401009304005F95040100399300401F
+:10BD000081320100A18F2250FD7F00009F8F4640AD
+:10BD10008132000000001E4131D3010000002E05D9
+:10BD200048B1010000000040E1B101000000004006
+:10BD30000FB001009B920041813001001A87004042
+:10BD400081B20000A292004081320100B38FA208AC
+:10BD500080320000B38FA216803200000082000201
+:10BD600004DC01000000004503F0010000000001B8
+:10BD700000C00100AC8F375C613100000000001B87
+:10BD800062B10100B08F284081320000AD8F0040C9
+:10BD900081B200000000000062B10100B08FA84035
+:10BDA000813200001A87174081B2000074002240DF
+:10BDB000F1B1010000000040E1B10100E094004A4F
+:10BDC00095300100C093005C1F100100498F0040B6
+:10BDD00081B200002F00004047990100C48F224724
+:10BDE000E77D000034920040E7310100C48F22005B
+:10BDF00080320000BF8FA2401F7C0000B092004044
+:10BE000081320100C48F004081B200003000004048
+:10BE10004399010032002DF294B00100589300F2D2
+:10BE2000023001005F93004B02B0000000000005EB
+:10BE300048B10100E094004895300100C093005CD7
+:10BE40001F100100C98F8742191000008B002F4777
+:10BE50001980010000000040E79101000B950042AD
+:10BE600081300100D58A004081B20000C0930040BB
+:10BE700081320100D58A005C1F900000BA0020408A
+:10BE8000E5B101004495004081320100C00000404E
+:10BE900043990100C4002DF082B00100789500F0B4
+:10BEA00084300100B0920040813201000B950045C2
+:10BEB00081300100D58A2242197C00009A94003A10
+:10BEC00081300100D58A004081B2000004000040AA
+:10BED00081B20000A292004081320100DE8FA208F0
+:10BEE00080320000DE8FA216803200009A94004754
+:10BEF000803001000082000204DC01001A8700404B
+:10BF000081B200001080000344C9010000E100A6D6
+:10BF100084B0010000000040F1B1010000000040C9
+:10BF2000F1B1010000006007849401008C94005E70
+:10BF300005100100D58A004081B200008A0000404F
+:10BF400047990100B0920041E7410100DA8A0040C0
+:10BF500081B200009A930040813201005393004067
+:10BF600081320100000000012CB00100000000152A
+:10BF700010B001000000000010C0010004001F0A02
+:10BF80002C5000000000001032B001001E95000689
+:10BF900004300100F68FA2481F7C0000F48F844813
+:10BFA0001F100000AC00004047990100F68F000A06
+:10BFB000E0C100000000000A02B00100BD910001D4
+:10BFC0008C3001000000004361B10100400000100E
+:10BFD00062DD0100F78FA84081320000AF82008847
+:10BFE0001CB000000000000548B101000000000284
+:10BFF00010C0010004902202145000000894004573
+:10C000001F000100EE8F225C1F7C00000000004733
+:10C0100061B101004000001062DD01000090A85CE9
+:10C020001F000000AF8200881CB00000EE8F0005EA
+:10C0300048B100000000000B1BB0010008002D40BB
+:10C0400085B00100000000F082B001000000004057
+:10C0500005B00100CE93004187300100000000458B
+:10C0600061B101004000001062DD01000A90A840AB
+:10C0700081320000AF8200881CB000000000000583
+:10C0800048B1010010902209803000000B9500405B
+:10C090001330010014902244197C00000B95004FCE
+:10C0A000813001001490A2471F7C00000000004472
+:10C0B00019800100FF070008008C01002290224A2D
+:10C0C0001F7C00001A90A21602300000B0920040BF
+:10C0D000813201002F002040E7B10100D58A0040E5
+:10C0E00081B200002D002D082AB001001E902242CE
+:10C0F000197C0000DD930040813201001F90004058
+:10C1000081B20000AD9300408132010030002E006A
+:10C110002AD0010032002A15E4B10100D58A0016A8
+:10C12000E4B1000035902216023000000000000843
+:10C130002AB0010094950040953001002790A2405C
+:10C14000116C0000369022402D6C0000AC000040C5
+:10C1500047990100B0002B01E0C10100002B00A6AF
+:10C1600016B0010000000001E0D10100E3940008D6
+:10C17000803001002E90005E17900000049500436F
+:10C18000613101000000004361B101004000001076
+:10C1900062DD01002F90A84081320000AF8200884C
+:10C1A0001CB000000000000548B10100EB9400073E
+:10C1B000161401008C94005E05100100B09200403E
+:10C1C000813201002F002040E7B10100DA8A0040EF
+:10C1D00081B200000000000B1BB0010004001F151D
+:10C1E0001A500000439020161A6C000070000003E3
+:10C1F00048C9010000002250F1B101000000000315
+:10C20000F0B1010000000000E0B1010000000042B8
+:10C2100061B10100A00000A462DD01004090A846C9
+:10C220001F1000000000000548B1010000000000E0
+:10C2300010B001000000001510C001000000000A4D
+:10C240002AB001000000000A2CD00100AC002F40F1
+:10C2500023B001004A9084451F1000004B90000A53
+:10C26000E0C100000000000A02B001004B94004051
+:10C2700035B000000080001942C9010053902240EF
+:10C28000E36D00000000004361B1010040000010B8
+:10C2900062DD01004F90A84081320000AF8200882B
+:10C2A0001CB000000000000548B101006390A2022C
+:10C2B0001A500000649022402D6C00000080001095
+:10C2C00044C9010000000050F1B10100000000036A
+:10C2D000F0B10100FF070008E08D010000000042FE
+:10C2E00061B101000000001062B101005A90A84045
+:10C2F00081320000AF8200881CB000000000000501
+:10C3000048B101002F002047E7B501000C80000371
+:10C3100042C90100100000F010C80100F007004001
+:10C320001B9801006490005C118000000000000276
+:10C3300010C00100C69200401F000100000000056F
+:10C3400048B101006890230D2C6C000000000040F3
+:10C350001F900100719022461F7C000000000046E3
+:10C360001F8001007080000342C9010071902240CB
+:10C37000E36D00000000004261B1010040000010C8
+:10C3800062DD01006D90A84081320000AF8200881C
+:10C390001CB000000000000548B1010008002D405D
+:10C3A00085B00100000000F082B0010000000040F4
+:10C3B00005B00100CE930041873001000000004528
+:10C3C00061B101004000001062DD01007690A840DC
+:10C3D00081320000AF8200881CB000000000000520
+:10C3E00048B101007C902209803000000B9500408C
+:10C3F0001330010080902244197C00000B95004FFF
+:10C40000813001008090A2471F7C000000000044A2
+:10C4100019800100FF070008008C01009590224A56
+:10C420001F7C00008690A21602300000B0920040EF
+:10C43000813201002F002040E7B10100D58A004081
+:10C4400081B200002D002D082AB0010091902242F7
+:10C45000197C00008A90A2F384300000000000A53F
+:10C4600085B001000000004185D00100D4003E41AC
+:10C4700085E001008E9022401F7C00000000005AE1
+:10C48000119001000B000008E4F50100DD9300406D
+:10C49000813201009290004081B20000AD930040D3
+:10C4A0008132010030002E002AD0010032002A150E
+:10C4B000E4B10100D58A0016E4B100009890A216FC
+:10C4C00002300000B092004081320100E79000404D
+:10C4D00081B200002D002D082AB00100A69022474D
+:10C4E0001F7C0000A2902242197C00009D90A2F3C4
+:10C4F00084300000000000A585B00100000000416C
+:10C5000085D00100D4003E4185E00100A190224089
+:10C510001F7C00000000005A119001000B00000871
+:10C52000E4F5010058012D002AD0010060012DF032
+:10C5300010B00100000000F02CB00100358E00406A
+:10C5400081B200009495004195300100AE90A208A0
+:10C5500080320000AE90A216803200000000004140
+:10C5600097B00100AC90230D026C00000000004168
+:10C5700097C001005F93004B02B00000E7900005F8
+:10C5800048B10000AC002F0114B00100B0002B0135
+:10C59000E0C10100002B00A616B001000000000160
+:10C5A000E0D10100BE90230D026C0000008000105D
+:10C5B00044C9010000000050F1B101000000000377
+:10C5C000F0B101000000004261B101000000001064
+:10C5D00062B10100B790A800E0310000AF8200888E
+:10C5E0001CB000000000000548B101000C800003F1
+:10C5F00042C90100100000F022C801000000005CE8
+:10C60000238001000000000184B00100C190230DCF
+:10C61000026C00000000000D02B0010000000008E4
+:10C6200080B00100C69022401B6C0000E394000122
+:10C6300084500100CE902240856C00000000000173
+:10C6400080C001001080001046C901000000004FAA
+:10C650004381010000000042F0B1010020000040D1
+:10C66000F0C9010000000016F0B101000000004315
+:10C6700061B10100A00000A162DD0100CC90A81111
+:10C68000E0310000DD90005E17900000D190230D96
+:10C69000026C00000000000D02B00100000000016B
+:10C6A00084D00100D69022401B6C0000049500430A
+:10C6B00061310100DD902240856C00000000000126
+:10C6C00012C001001080001046C901000000004F98
+:10C6D0004381010000000042F0B1010000000009A8
+:10C6E000F0B1010000000018F0B10100A00000A1AD
+:10C6F00062DD0100DB90A811E03100000000004382
+:10C7000061B101004000001062DD0100DE90A80A66
+:10C7100002300000AF8200881CB00000B09200051B
+:10C7200048310100E590230D026C0000FF07001165
+:10C73000008C0100B092004081320100EB940007B0
+:10C74000161401008C94005E051001002F0020409B
+:10C75000E7B10100DA8A004081B2000000800003E6
+:10C7600042C90100000000F882B00100000000F89A
+:10C770008CB00100000000F08EB0010097930040E3
+:10C78000133001000000004085B00100CE9300414D
+:10C790008730010053930040813201000080001077
+:10C7A00042C90100F8902240E36D000000000045FE
+:10C7B00061B101004000001062DD0100F490A8406A
+:10C7C00081320000AF8200881CB00000000000052C
+:10C7D00048B10100FA902209803000000B9500401A
+:10C7E000133001000000000B1BB001000000001519
+:10C7F0001AD001000191A241197C000094950040DB
+:10C80000953001000000001680B201000A9127084F
+:10C8100080320000279000002AC00000949500415B
+:10C82000953001000000001680B201000591270834
+:10C8300080320000AE9000002AC0000000000041DD
+:10C8400097B001000891230D026C00000000004128
+:10C8500097C001005F93004B02B00000000000058C
+:10C8600048B10100D58A2242197C00009A94003A0E
+:10C8700081300100D58A004081B200000E91004A4B
+:10C880001F900000D8920000103001000000001539
+:10C8900010C001000000001032B001001E9500061B
+:10C8A000043001001791A2441F7C00000000000B1F
+:10C8B0001BB001000000000A2CD001000000000A9B
+:10C8C00002B00100BD9100018C3001000080001910
+:10C8D00042C901001E912240E36D000000000043A8
+:10C8E00061B101004000001062DD01001A91A84012
+:10C8F00081320000AF8200881CB0000000000005FB
+:10C9000048B101000000000210C00100279122027E
+:10C9100014500000089400451F0001001091225C93
+:10C920001F7C00000000004761B1010040000010C2
+:10C9300062DD01002391A85C1F000000AF82008827
+:10C940001CB000001091000548B1000008002D4007
+:10C9500085B00100000000F082B00100000000403E
+:10C9600005B00100CE930041873001000000004572
+:10C9700061B101004000001062DD01002C91A8406F
+:10C9800081320000AF8200881CB00000000000056A
+:10C9900048B1010032912209803000000B9500401F
+:10C9A0001330010035912244197C00000B95004F93
+:10C9B000813001000000004419800100FF070008D9
+:10C9C000008C01004391224A1F7C00003B91A2167B
+:10C9D00002300000B0920040813201002F00204060
+:10C9E000E7B10100D58A004081B200002D002D087A
+:10C9F0002AB001003F912242197C0000DD930040E3
+:10CA0000813201004091004081B20000AD930040AE
+:10CA10008132010030002E002AD0010032002A1598
+:10CA2000E4B10100D58A0016E4B100002390A216FB
+:10CA300002300000B0920040813201002F002040FF
+:10CA4000E7B10100DA8A004081B20000D892004AC2
+:10CA50001F1001003890001032B000008A00204002
+:10CA6000E7B101004D91A241197C0000B092004055
+:10CA7000813201005091004081B2000058930015AE
+:10CA8000943001005F93004B02B0000000000005ED
+:10CA900048B1010052912242197C00009A94003A58
+:10CAA000813001000B95004581300100D58A00409E
+:10CAB00081B20000F48E00451F9000009A93004060
+:10CAC000813201005393004081320100389000010F
+:10CAD0002CB00000A2920040813201006591A208B2
+:10CAE000803200006591A2168032000000820002B0
+:10CAF00004DC01000000004503F00100000000011B
+:10CB000000C001005E91375C613100000000001B35
+:10CB100062B1010062912840813200005F910040C3
+:10CB200081B200000000000062B101006291A840E3
+:10CB3000813200001A87174081B200005801200896
+:10CB4000E0B1010060012016E0B101009A930047B6
+:10CB50001F10010053930040813201003890000102
+:10CB60002CB00000A29200471F1001007891A2088B
+:10CB7000803200007891A216803200007491A242A7
+:10CB8000197C00000082000204DC0100A098004033
+:10CB90004799010030050041893001005893001584
+:10CBA000943001005F93004B02B000001A870040F0
+:10CBB00081B20000DD930040813201000000004B93
+:10CBC000199001009A94003A813001001A870040C0
+:10CBD00081B2000058012008E0B101006001201678
+:10CBE000E0B10100D89200103230010038900040CE
+:10CBF00013B00000A2920040813201008991A20886
+:10CC0000803200008991A21680320000008200026A
+:10CC100004DC01000000004503F0010000000001F9
+:10CC200000C001008291375C613100000000001BF0
+:10CC300062B101008691284081320000839100405A
+:10CC400081B200000000000062B101008691A8409E
+:10CC5000813200001A87174081B200000080000373
+:10CC600042C90100000000F882B00100000000F895
+:10CC70008CB00100000000F08EB0010097930040DE
+:10CC8000133001000000004085B00100CE93004148
+:10CC90008730010053930040813201000080001072
+:10CCA00042C9010098912240E36D00000000004558
+:10CCB00061B101004000001062DD01009491A840C4
+:10CCC00081320000AF8200881CB000000000000527
+:10CCD00048B10100358E2209803000000B950040DC
+:10CCE00013300100358E004081B2000014002D4544
+:10CCF0001F9001007D8E004419900000A091A24178
+:10CD0000197C00000000004A1F900100E88F0040DD
+:10CD100081B200009A93004A1F1001005393004013
+:10CD200081320100389000012CB00000D892004000
+:10CD3000813201003890001032B00000F48E0045BE
+:10CD40001F9000000000004137C3010000000041B7
+:10CD500033C301003600000102CC01000000D240C4
+:10CD600081B20000AC9185178032000000009F481E
+:10CD700003D00000AE919C178032000000009F4C51
+:10CD800003D000000000800134C301004080000394
+:10CD900044C901000000004AF0B101000000004059
+:10CDA000F1B1010000000012F0B10100B4920041A5
+:10CDB000E13101000080004344C90100100000403F
+:10CDC000F199010000000048F0B1010000000049A5
+:10CDD000F0B1010040000003E0C90100000000457F
+:10CDE00061B101000000004362B101000000A840F1
+:10CDF00081B20000BA91004081B20000BA00204028
+:10CE0000E5B10100B0002F018CD001000000004608
+:10CE1000E0C10100AC002F4013B00100CC002D0197
+:10CE2000E0C10100C4919C17803200009D95004034
+:10CE300081320100C6912247197C00000000005F8A
+:10CE4000139001004495004719100100C0002D44C3
+:10CE50001F900100C4002DF082B00100789500F011
+:10CE600084B0000090002D0548B10100DB91A24B79
+:10CE70001F7C00002E92A24C1F7C0000DB911F1C27
+:10CE8000E06D0000DE91A20180320000A8002D4676
+:10CE90008FB00100D4911F1CE06D0000B400004071
+:10CEA00043990100D69122F03A6C00002B921FF0BA
+:10CEB0003A6C00000000A24080B200000000804FE9
+:10CEC0008FB001008A000040439901002C9220425B
+:10CED000E76D0000DA9122408032000000008059A6
+:10CEE0008FB00100000080588FB00100DD9122401A
+:10CEF000803200000000805C8FB001000000805B89
+:10CF00008FB00100AC00004043990100B0002DF04B
+:10CF100084B00100E291A242246C0000EB9123F066
+:10CF2000026C0000E891A2F0803200002D92A24233
+:10CF3000246C00002D92A241036C0000E791A240F6
+:10CF400080320000000080518FB00100000080524C
+:10CF50008FB001002D921F12845000002D92A0016D
+:10CF6000846C0000DB91004081B200008B00004027
+:10CF7000439901001692A246E77D0000140000408C
+:10CF800043990100089222F014300000F491200A25
+:10CF9000026C00000592031E80320000F391A24053
+:10CFA00080320000000080448FB001000000804902
+:10CFB0008FB00100F991220A026C0000FC91A2419D
+:10CFC000197C0000F891A2408032000000008055DA
+:10CFD0008FB00100000080568FB00100FB91A2408D
+:10CFE00080320000000080438FB0010000008048C4
+:10CFF0008FB001000000000182B001000000000AB3
+:10D0000082D0010002922091836C00000192A24024
+:10D0100080320000260080408F9801002700804069
+:10D020008F9801000492A240803200001F008040CF
+:10D030008F980100200080408F9801000792A24045
+:10D0400080320000220080408F9801002300804041
+:10D050008F98010088002D448FB001001192A241E9
+:10D06000197C00000E92A2433D7C00000E92A2F2B9
+:10D07000026C00000000A24080B200000000804965
+:10D080008FB001001092A240803200000000804367
+:10D090008FB00100000080488FB001000E92A09177
+:10D0A000036C00000C9222433D7C00001592A240CC
+:10D0B00080320000280080408F98010029008040C5
+:10D0C0008F98010014000040439901001F92A2F0C4
+:10D0D0001430000088002D448FB001001C92A2F291
+:10D0E000026C00000000A24080B2000000008049F5
+:10D0F0008FB001000E922241197C00000C92209109
+:10D10000036C00000E92004081B200002392200ABE
+:10D11000026C00002292A240803200000000804495
+:10D120008FB00100000080498FB001002892220AD0
+:10D13000026C0000FC91A241197C00002792A240E1
+:10D1400080320000000080558FB001000000805642
+:10D150008FB001002A92A24080320000000080437C
+:10D160008FB00100000080488FB001003092004372
+:10D1700095B000003092004195B00000309200421E
+:10D1800095B000003092004495B000003092004C01
+:10D1900095B00000E0940040813201003392A2403B
+:10D1A000803200000000804B8FB001000000804CF6
+:10D1B0008FB001002D000040439901002E002FF395
+:10D1C00084B001003892A2F3963000000000804045
+:10D1D00001B001002D002A41E7D10100D4003D41FA
+:10D1E00085E001000B0000F200E401003E92225AAB
+:10D1F000017C0000000000401F9001003F92005A97
+:10D2000001800000000000401F8001000000634119
+:10D2100085C001000000A0A5856C01000000E3406E
+:10D2200085B001000C80000342C9010012000040DB
+:10D2300087980100DF9500F08CB000004C922240EE
+:10D240000F6C000000002F0548B101004992A24B6D
+:10D25000197C00004A9222F0186C00000000604B1C
+:10D26000199001001693000710300100F982004068
+:10D2700005B000004E92225A1F7C00009B92004095
+:10D2800081300100F982004005B0000000002F0548
+:10D2900048B101000000604B19900100169300078F
+:10D2A00010300100F982004005B0000000002F0599
+:10D2B00048B101000000604B19900100169300076F
+:10D2C000103001000000804005B00100579233404B
+:10D2D000813200005A92A1AD95200000689213405F
+:10D2E00081B200000000134A5A8301003000394522
+:10D2F00095E001001F00000F5ED801000000005AF9
+:10D300005F9001000000004045B0010000000004F3
+:10D3100048B00100000000054AB001000000000C08
+:10D3200058B00100000000074EB00100A884004082
+:10D330005D9801000000005861B101000000004A42
+:10D3400062B101000000A84197B000006592004062
+:10D3500081B200000000804097B001006992600730
+:10D3600096300000FFFF004B84890100000070C26E
+:10D3700024B001007392A245257C00006D923120FB
+:10D380008530000074922212487F00005804111268
+:10D39000480301001000001296E401000000004B59
+:10D3A0001E9401000000805A1F90010073923140CA
+:10D3B00081320000000000B424B0010074922212F7
+:10D3C000487F0000580400408132010000002F0512
+:10D3D00048B1010081920BF084300000000011126E
+:10D3E000488301007E922250857000005E0100405B
+:10D3F00043990100419400F2963001009304001219
+:10D40000943001000000005A1F900100100000122B
+:10D4100096E401000000804B1E94010010000042C1
+:10D4200010F4010000B73F4311F0010007000008AD
+:10D430008A880100849230A10C3000008792224536
+:10D44000E67D00007492104081B2000000002A4581
+:10D45000E691010000001012488301000000114015
+:10D4600081B201000000604B858001005E01004038
+:10D4700043990100419400F29630010000800010B1
+:10D4800044C90100D8000040819801002E002D05FC
+:10D4900048B1010092922240E76D000080000040F8
+:10D4A00080C8010000000040F0B101000900000840
+:10D4B00086E40100000068A787C001000000004466
+:10D4C00061B101000000001062B101009692A80550
+:10D4D000E03100001000001296E401000014004B3F
+:10D4E00096DC01000000804B1E9401001000000F2C
+:10D4F00084F401001F000042848801009F922240B2
+:10D5000080320000A092004268B10000000000429A
+:10D510006AB10100A092315A1F0000000000914240
+:10D5200048930100A2923540813200006D00004016
+:10D5300061990100A89228B12C300000A392224DDD
+:10D54000757D0000000000402DB0010000009540F6
+:10D5500011B001006D00004061990100A892A8B1CE
+:10D56000103000000000954081B201007F000040B3
+:10D5700061990100AF9228B110300000AB929FBAC0
+:10D58000803200000000804011B0010000008024C3
+:10D59000118401000000005F61B101000010000073
+:10D5A00062DD01000000A84081B20000B19200409D
+:10D5B00081B20000AC94004047990100B59232401E
+:10D5C00081320000BB9222F896300000000000F883
+:10D5D00090B00100000000F092B001000100004B8B
+:10D5E000F0CD010020009248E0C901006C0000402D
+:10D5F00061990100BF9228B192300000BB92224C89
+:10D60000757D00000400124091B000006C000040E5
+:10D6100061990100BF92A8B190300000FF0000485E
+:10D62000968801000000004B90D001000100004BE3
+:10D63000F0CD010020000048F0C90100000092492F
+:10D64000E0B101000C002D1048B10100FF070008F7
+:10D65000828C0100FF0700F0008C01000000A24155
+:10D6600000EC0000CC92221A006C0000B092000086
+:10D67000343001000000005049C10100C892A241AD
+:10D68000235000000000804081B201000C002D10EA
+:10D6900048B10100FF070015828C0100FF0700F070
+:10D6A000008C01000000A24100EC0000D592220D88
+:10D6B000006C0000B09200001A3001000000005021
+:10D6C00049C10100D192A2412350000000008040D6
+:10D6D00081B20100DA92831E803200000000004413
+:10D6E0001990010024002D012CB0010028002DF01C
+:10D6F00016B0010022002DF026B0010014002FF218
+:10D700000CB0010000008040E1B101003000004099
+:10D710009798010060972E4081B201000000004000
+:10D72000F1B10100E192A2419750000064973E439D
+:10D730009DE0010000008040E1B1010064973E439C
+:10D740009DE001000000800BE8B1010064973F43B9
+:10D750009DE00100000000F016C0010000008040C4
+:10D76000E1B1010064973F439DE00100000000F437
+:10D7700016B0010000008040E1B1010060173D4398
+:10D780009DE00100100080A116E4010000B5000D2D
+:10D7900042C90100F092304717040000F392A20B37
+:10D7A000E67D00000000904281B0010000B7000D4E
+:10D7B00046C90100F792A20BE67D00000000000BB5
+:10D7C000E69101000000904181B00100000010408E
+:10D7D00081B20100F8924007963000009D0400409D
+:10D7E000813201000293A245957C000001973F41E0
+:10D7F00095E00100000000F396B001000000004E2B
+:10D80000E6B1010040973E4097E001000000004E65
+:10D81000E6B1010040973E409DE001001593003BBA
+:10D82000E7B1000002933040813200000C93A20B5C
+:10D83000E67D000000B5000D46C901000893A20B6B
+:10D84000E67D00000000104081B201000000984217
+:10D8500081B0010000B7000D46C901000000000BB7
+:10D86000E69101000000104081B2010000009841E3
+:10D8700081B00100040021A2952000000000104AA0
+:10D880004483010000973E4195E001000000004EF6
+:10D89000F6B101000000004EE6B1010040973E40A5
+:10D8A0009DE001000000003BE7B101000000004ADC
+:10D8B00090B10100FFFF000792890100000098402D
+:10D8C00081B001000300000886F4010000B70043A6
+:10D8D00046C901000700000882880100199340082A
+:10D8E000963000009D0400408132010025932245BE
+:10D8F000957C00002193225A1F7C00001000000F2D
+:10D9000096F401001E93315F970400000000114B54
+:10D91000489301000000004B6AB1010021933040A0
+:10D920008132000000000041E6810100000010404B
+:10D9300081B201000000984081B2010000973F4190
+:10D9400095E00100000000F396B0010040973D40D3
+:10D9500097E00100000063F388B001002D93A23B23
+:10D96000896C00000000004A90B10100010000A68F
+:10D9700092B101002E93184A449300000000184011
+:10D9800081B201003000394597E001003393225AFB
+:10D990001F7C00001F04000F98D801000000004CFD
+:10D9A0005E940100359300054AB000001F0400A7F3
+:10D9B0005E840100000000404BB0010000000058F0
+:10D9C00061B101000000004B62B101000000A840FD
+:10D9D00081B200003693004081B2000039934007C5
+:10D9E000963000009D040040813201003D932245A5
+:10D9F000957C00000000984081B201009B04004A21
+:10DA00004413010000973F4195E00100000000F33E
+:10DA100096B0010040973D4097E00100000063F39D
+:10DA200088B001003000384597E001000000005F39
+:10DA30000F9001000000005861B101000000004B90
+:10DA400062B101004593A840813200003E93A23BA1
+:10DA5000896C0000300038459DE0010000009840CE
+:10DA600081B2010093040012943001001693005A11
+:10DA70001F0001000000805A1F9001001100004AA1
+:10DA8000E6C9010034002F4F95840100000000F327
+:10DA900096B001000100634B84C801000000A04360
+:10DAA000856C01000000E34085B0010030002D448A
+:10DAB0001F90010032002DF22AB00100040022F272
+:10DAC0000230000034920010323001003200A040D9
+:10DAD000E5B101000000004097B00100F0070040F0
+:10DAE000999801000000004A02C0010000000050A7
+:10DAF00003D001000000004197C001000000A34CCA
+:10DB000002D000005C93004081B20000000000A839
+:10DB100036B001006C9322410350000000800010D9
+:10DB200044C9010000000050F1B101007000000381
+:10DB3000F0C901000000004261B1010000000010C6
+:10DB400062B101006593A800E0310000AF82008857
+:10DB50001CB00000B0920040813201007C800003C4
+:10DB600042C90100000000F000B001006093005CB9
+:10DB700001800000B0920040813201000000001BD3
+:10DB800010B1000068012D0682B00100000000F213
+:10DB900082C001000080000346C90100AB92004032
+:10DBA0008132010093932240116C0000000068084C
+:10DBB00038960100F007004182CC01007193AA4120
+:10DBC0003B400000000000F810B001000000005CC5
+:10DBD000118001000100001D04CC01009293264633
+:10DBE000233000000800000312C80100640120F087
+:10DBF000E0B1010091932241055000002000000394
+:10DC000048C901000C0000F886C801000000224449
+:10DC1000F1B1010000000043F0B101000000000973
+:10DC2000E0B101000000004461B10100A00000A4C7
+:10DC300062DD01008393A8461F10000090932241EB
+:10DC4000055000008E93A24123500000000000A167
+:10DC50001AB001000000004461B101004000001052
+:10DC600062DD01008993A84623300000AF8200885E
+:10DC70001CB000001000000348C901000000000DA6
+:10DC800042B101000000004413C001007E93005027
+:10DC900049C100000000000548B1010004800003F4
+:10DCA0001AC801000000804081B201009293224016
+:10DCB0003B6C0000000000F800B00100B092005C76
+:10DCC00001000100939300413BD0000000008D470C
+:10DCD00080320100B0002F5F13B001000000E0F0BF
+:10DCE0008CC001000080000342C90100000000F860
+:10DCF00094B00100000000F88CB001009F938CF8F4
+:10DD00008E3000000000004419900100040022F849
+:10DD100014300000000000F816B00100000000F808
+:10DD200026B0010008002EF80CB001000C002A4AB1
+:10DD3000E0B1010028000000E0C901001000201B34
+:10DD4000E0B10100AC93200A0C6C0000000000F868
+:10DD500094B00100000000F896B00100200020F00F
+:10DD6000E4B101001800204AE0B101001C00204B82
+:10DD7000E0B101009793004013B000002C002D4249
+:10DD8000199001002E002FF382B00100000000F373
+:10DD900096B00100B293A2A5976C000000008041EC
+:10DDA00095B00100B593A240976C000000000040C0
+:10DDB00083B001002D002040E7B101000000634165
+:10DDC00097C00100D4003E4183E001000000004103
+:10DDD00083C00100BA93A0A5836C0000000000403E
+:10DDE00083B001002C002041E6B10100BF93224026
+:10DDF0001F7C00000004000098DC01000B00004CB8
+:10DE0000E4F50100000080401F8001000B0080004D
+:10DE1000E4F50100B4920040813201000480000367
+:10DE200044C9010000000040F1B1010000000040C1
+:10DE3000F1B101000000604187B0010000800010D6
+:10DE400044C9010000000050F1B101000000004889
+:10DE5000F0B1010000000049F0B101000000000332
+:10DE6000E0B101000000004561B101002000001098
+:10DE700062DD01000000A85D05900000CB9300402A
+:10DE800081B20000B49200408132010000800003A2
+:10DE900044C9010000000041F0B10100000000424F
+:10DEA000F0B1010000000040F1B1010000000043AA
+:10DEB000F0B101000080001044C9010000000050D2
+:10DEC000F1B1010000000048F0B10100000000497C
+:10DED000F0B1010000000003E0B1010000000045C6
+:10DEE00061B101002000001062DD01000000A85DAA
+:10DEF00005900000DA93004081B200002D00004040
+:10DF0000439901002E002FF384B00100010063F358
+:10DF100096C80100E2939F4185500000010000A5D2
+:10DF200085CC01002D00A042E6B101005E012D006C
+:10DF300080B00100E793524381600000020000F2CC
+:10DF400082F40100E8930041809400000000005F2B
+:10DF5000819001000000005E61B1010000000040FE
+:10DF600062B101000000A84095B00000E9939EBB9B
+:10DF700080320000EE93A2401F7C0000B09200406F
+:10DF800081B200000000804195B00100040000153E
+:10DF900042C90100000000542BC00100000000FC39
+:10DFA00024B00100000000FC38B00100000000FEB9
+:10DFB0003CB00100000000FE3AB0010003949C1741
+:10DFC00080320000F893A24A197C00000000804CC7
+:10DFD0001F9001000C00001E98F40100F793A24866
+:10DFE000996C00000000001542B10100F793A28A6D
+:10DFF000F16D00000C00000102CC0100000000FCEB
+:10E000003EB00100010000F428CC0100CC002D0539
+:10E0100048B10100029420F03E6C00000000004B6B
+:10E020001F9001000000004C2BC00100BF002D0517
+:10E0300048B10100000080F33AE0010000002E4BDF
+:10E040001990010007002A0CE4B1010000008004CF
+:10E05000E6B1010018000040439901001C002DF0BA
+:10E0600016B0010020002DF026B001000C002FF2A8
+:10E070000CB001000000A20614EC00000F94224531
+:10E080001F7C00000000A3062AEC0000000000F83E
+:10E0900094B00100000000F096B001000C002D408B
+:10E0A00081B2010000002A4CE1C1010030000010E3
+:10E0B00048C901000A000040F1990100180000055C
+:10E0C000F0C901000000004AF0B101000000004B5F
+:10E0D000E0B101000000004761B10100A00000A410
+:10E0E00062DD01001994A85C1F100000000080058B
+:10E0F00048B1010000002E1048B1010040000001AD
+:10E10000F0CD010040000003F0C901004000000014
+:10E11000E0C9010000002E5049C1010000000006C6
+:10E12000F1B1010000000003F0B10100239462424C
+:10E13000613100002000001062DD01002494A8403D
+:10E14000813200001000001062C901002694A8006E
+:10E15000E03100000000F24081B2010000002E100A
+:10E1600048B1010040000001F0CD01004000000373
+:10E17000F0C9010040000000E0C9010000002E507D
+:10E1800049C1010000000006F1B1010000000003D8
+:10E19000F0B10100309462426131000020000010B3
+:10E1A00062DD01003194A84081320000A00000A48B
+:10E1B00062DD01003394A800E03100000000F2406D
+:10E1C00081B201003080004A44C90100000000060D
+:10E1D000F1B10100C0A83D460DE00100FF7F00A1A4
+:10E1E000F08901000200000996F4010000000046D9
+:10E1F00097E00100000060A897C001003D946342D1
+:10E20000613100003000004A62C901003E94A8401C
+:10E21000813200000000F34081B2010000993F42CA
+:10E2200097F0010042946540813200004A9422F345
+:10E23000740600003F0000F394880100000000070E
+:10E24000E78501000000755561B101000000004A3A
+:10E2500062B101000000A84081B200004794004074
+:10E2600081B200000000F54081B20100000000A86A
+:10E2700036B001005A948241234000004F94A244DA
+:10E280001F7C0000BD9100018C3001002080001037
+:10E2900042C9010055942240E36D00000000004394
+:10E2A00061B101004000001062DD01005294A840FD
+:10E2B00081320000AF8200881CB0000000000041E5
+:10E2C00023B001000000001032B001005A94224136
+:10E2D000197C0000C6920043233001000000004179
+:10E2E00023B001005C94A3150C6C00005D94000643
+:10E2F00004B000000000001504B001005F9420028B
+:10E300001A6C00000000000D04B001001E9500050D
+:10E310004831010089942202145000006394A20243
+:10E320002A5000008994A2451F7C000065942202B7
+:10E330000C5000006E94000216C000006D94225C28
+:10E340001F7C00003080001042C901006D94224003
+:10E35000E36D00000000004761B1010040000010C3
+:10E3600062DD01006994A84081320000AF8200881C
+:10E370001CB000000000000548B101000894005CDA
+:10E380001F00010089942215803200000000005017
+:10E3900033C001008894A2021A5000007A942246E9
+:10E3A0001F7C00007080000342C90100000000468D
+:10E3B0001F8001007A942240E36D000000000042BB
+:10E3C00061B101004000001062DD01007694A840B8
+:10E3D00081320000AF8200881CB000000000000500
+:10E3E00048B101000C80000342C90100100000F098
+:10E3F00010C801002F002F5C1180010000000047B1
+:10E40000E7910100F00700401B9801004C94201593
+:10E410001A6C00007000000348C90100000022507F
+:10E42000F1B1010000000003F0B10100FF07000896
+:10E43000E08D01000000004261B10100A00000A4D5
+:10E4400062DD01008594A8461F1000004C94000571
+:10E4500048B100004C94000210C000008B94A2440C
+:10E460001F7C0000BD9100018C3001000000001BEA
+:10E4700010B100000080001044C901000C000040F1
+:10E48000F199010010000008F0C901000000001619
+:10E49000F0B1010010000003E0C9010000000045D8
+:10E4A00061B101002000001062DD01000000A85CE5
+:10E4B0001F9000009294004081B20000170000D02D
+:10E4C000A2C901000000A24027EC000000000020CB
+:10E4D00000B00100B0920041A341010096940041B8
+:10E4E00027D000001000000796E401000000004B58
+:10E4F000809401000000005461B1010000800040E0
+:10E5000062DD01000000A84081B200009D9400403F
+:10E5100081B20000EF9400402B300100AC002D06CA
+:10E5200016C0010090002DF016C40100A594A0F0C3
+:10E53000164400000000004117C001000E0000A2B8
+:10E5400044C9010000006CF030B00100AC002D4067
+:10E5500087B0010000006CF028B00100AE94224AA0
+:10E56000197C00000030004386C801000030000B19
+:10E5700016C80100AE94A4408132000000000041A2
+:10E5800017C00100CF94220680320000BB94A2067F
+:10E59000146C0000B8942248197C0000B394A04188
+:10E5A000174000000000004117C0010000000041BA
+:10E5B00031C0010090002018E0B101008B002D480F
+:10E5C000198001008B002045E7910100BB940040B9
+:10E5D000879000000800004386980100BB94A04883
+:10E5E000174000000000004117C00100B0000040CB
+:10E5F0004399010010500043FCC9010026950030EA
+:10E600008130010000000040E5B10100C694224ABB
+:10E61000197C0000080000A244C90100CC002DAB09
+:10E62000F9B10100000000AB17C00100C594A0F0D3
+:10E63000164400000000004117C00100CA9464F0B5
+:10E6400082B00000A400004047990100CA94A2F2E1
+:10E650008032000000000041E5B101008C0020186C
+:10E66000E0B1010090000040459901000000600603
+:10E6700030C001000000860C80B20000BC002D46B6
+:10E6800019900100A000A0F2E4B10100B000004028
+:10E690004399010010500043FCC901002695003049
+:10E6A000813001000000A24A19FC0000080000A20D
+:10E6B00044C90100CC002DABF9B10100000000AB52
+:10E6C00017C00100D894A0F01644000000000041DB
+:10E6D00017C001000000E4F082B0010000800010CB
+:10E6E00044C9010000000041F0B101000000000336
+:10E6F000F0B1010000000000F0B1010000000010C6
+:10E7000062B101000000A81BE0B10000DD940040F0
+:10E7100081B2000000F0000C7E8901000000A64CD0
+:10E72000956001000000804A1894010000800010EC
+:10E7300044C9010004002201F03100002000004023
+:10E74000F0C9010000000016F0B101000000004314
+:10E7500061B101002000001062DD01000000A81579
+:10E76000E0B10000E894004081B200001080000396
+:10E7700044C9010000000006F0B1010000000001E2
+:10E78000F0B101000000E85F179001007000004048
+:10E79000439901007A012EFE92B001008B002DF604
+:10E7A00016B00100F5942243E77D0000000000440C
+:10E7B00045C10100040000A62AB0010028006E0631
+:10E7C00082C80100F994224A197C0000000000422E
+:10E7D00045D1010000006E4C83C0010000000041E3
+:10E7E00092C00100FA9443303D0700000000669E8D
+:10E7F00083B0010000001B413DC301000000004147
+:10E8000092C00100060000A244C9010010000049A6
+:10E8100098F4010003952630930400000395904C72
+:10E82000924000000000004193C00100FFFF8049BA
+:10E83000ECA901000080001044C90100040022017D
+:10E84000F031000000000009F0B1010000000018E4
+:10E85000F0B101002000001062DD01000000A815E9
+:10E86000E0B100000895004081B200001595225FDC
+:10E87000817C00001495A240197C0000000000403B
+:10E88000199001000000005461B101001000000760
+:10E8900096E401000000004F979401000000004B37
+:10E8A00062B10100149528408132000011950040AA
+:10E8B00081B200000000A221818400001895A25FAF
+:10E8C000816C00000000A243197C0100000000439D
+:10E8D000199001000000005461B101001000000710
+:10E8E00096E4010000000040969401000000004BF7
+:10E8F00062B101000000A84081B200001B950040F9
+:10E9000081B200000080001944C901000400220205
+:10E91000F03100000000000BF0B101000000001316
+:10E92000F0B101000000004361B1010020000019B6
+:10E9300062DD01000000A808E0B10000239500405E
+:10E9400081B200007C002DF084B00100020000F0D4
+:10E9500098F401002C95204C846C00008800004045
+:10E96000439901002C9520F2846C000000000040C7
+:10E9700085B0010098002D1482B00100000000F065
+:10E9800098B00100A3002D1498D001003195204CBF
+:10E99000846C00000000004C84B00100000000F313
+:10E9A00080E0010034952340846C000000000040AA
+:10E9B00084B00100D0002014E0B10100980025428D
+:10E9C00080B0010000006EF380F001000000A6425C
+:10E9D00082C000003A95A0401640000000000041AF
+:10E9E00017C0010000009FF082EC00009800A041D9
+:10E9F000E0B1010000002E1048B10100A801004064
+:10EA0000F199010000000005F0B1010009000007C4
+:10EA100096E40100000060A797C00100000000100C
+:10EA200062B101000000A84081B2000041950040A1
+:10EA300081B20000A8002D1C8AB0010000009FF0E8
+:10EA40008AD000000000A2408BEC00008A00204029
+:10EA5000E7B10100B400004047990100A4002D4532
+:10EA6000E0D101004E959C1780320000BE002FAB14
+:10EA700083B00100A195001482500100539500401D
+:10EA800081B20000539522F2823000008C000040D9
+:10EA90004399010053959F1CE06D0000BE000040AB
+:10EAA00047990100A195004081320100A800201C77
+:10EAB000E0B101009C002D3081B0010088002DF0F4
+:10EAC00084B0010094002DF286B00100669523F019
+:10EAD000846C00005B952392876C0000C90400A63B
+:10EAE00094B001005D95004081B20000200000A6B6
+:10EAF00094B001006089004A949801005D956840D7
+:10EB0000813200000000004AB0B10100BF002D4278
+:10EB1000B2B1010090002DF380E001006195D44076
+:10EB200081320000000078DA84C001006B95234038
+:10EB3000846C00009400209DE1B101006B950040C1
+:10EB400084B00000BF002D4384C0010090002DF36D
+:10EB500080E001006B952340846C00009400209DB0
+:10EB6000E1B101000000004084B001006F95A2F007
+:10EB7000386C00009C002042E0B101000000005F02
+:10EB80001394010000008046198001009C0020427F
+:10EB9000E0B101003700004043990100040000F398
+:10EBA00080F401000F0000F3828801007595234175
+:10EBB000806C00000000005F139401000000890CCD
+:10EBC00080B20000BC00004043990100A000A0F208
+:10EBD000E4B1010000009F4124EC00007F95A640B5
+:10EBE0008132000000009F4238EC00007F95A64073
+:10EBF00081320000B4000040439901008195A3F0E8
+:10EC00003A6C00000000804081B20100B400004076
+:10EC100043990100859522F03A6C0000B400201D54
+:10EC2000E0B1010080002D5F13940100859523F071
+:10EC30003A6C00008000201DE0B10100C0002012ED
+:10EC4000E0B10100C400A01CE0B10100008000039D
+:10EC500044C9010000000042E0B101001200004080
+:10EC6000879801008E959F41246C000000000041B0
+:10EC70008CB00100000000128CD001008F95004183
+:10EC800024B00000000000408DB00100DF9500407E
+:10EC9000813201000000004561B101004000001018
+:10ECA00062DD01000000A84081B2000091950040A3
+:10ECB00081B20000A29200408132010000000016E3
+:10ECC00080B201000000A708803201009995A2409F
+:10ECD000956C0000B092004081320100008200A6D5
+:10ECE00004B00100000000402DB00100A0982F40AA
+:10ECF00011B001003005004189B0000000009FF80C
+:10ED00003EEC000000009F12E0ED0000C80020ABC8
+:10ED1000E1B10100CC00A01FE0B10100A395A35F09
+:10ED2000E76D000000000041E7C10100A6000040BF
+:10ED300047990100B79522F2863000000300004396
+:10ED400084F401000100004180CC0100B8002D4294
+:10ED500080D001000000624086C00100AB951F43D7
+:10ED600080320000AC95A240876C00000000624138
+:10ED700087B00100B0959F40803200000000004045
+:10ED800085B001000000004084D001000000004276
+:10ED900080B00100000000F288B0010002000044D1
+:10EDA00084F40100B8002E4280D0010000006240CF
+:10EDB00088C00100B6951F4480320000BA95A24079
+:10EDC000896C0000BA95624189B00000030062417D
+:10EDD00086E40100B800004045990100010062414D
+:10EDE00088E40100A4002040E5B10100A200204019
+:10EDF000E7B10100BC002E4387F001000000004491
+:10EE000086C00100C0952043876C0000000080434D
+:10EE1000E5B101004001004380CE01000000A443A1
+:10EE2000E43101004001E2408798010088002D4450
+:10EE300081B0010090002DF22EB001009C002DF059
+:10EE400086B0010090002DF082B00100BA002DF0D4
+:10EE500098B00100CD95A212986C0000BC002DF274
+:10EE600098B00100CD95A0F2986C0000000000174A
+:10EE700082B001009C002041E0B10100B4002D12DD
+:10EE800086D00100D095A341E06D0000D19500F03F
+:10EE900084B000000000004184B0010080002D43D8
+:10EEA00084D00100D4959F428032000000000040D1
+:10EEB00085B00100D695A342146C0000D795000AD6
+:10EEC0000CB00000000000420CB00100D995A01762
+:10EED0000C6C0000000080170CB00100DE95224091
+:10EEE0000D6C00000000A00A0CEC0000010000F016
+:10EEF00082F40100DE95A0410C6C00000000A2F03D
+:10EF0000803201000000804081B00100B4920040D6
+:10EF1000813201000480000344C901000000004662
+:10EF2000F0B1010000000040F1B1010000006041BB
+:10EF3000879401000080001044C9010000000050C7
+:10EF4000F1B1010000000048F0B1010000000049EB
+:10EF5000F0B1010000000003E0B101000000004535
+:10EF600061B101002000001062DD01000000A85D19
+:10EF700005900000EA95004081B2000000002E4B91
+:10EF80001990010005002A0CE4B101000000800482
+:10EF9000E6B10100F095454861310000001000081D
+:10EFA00062DD0100F595284087300000F195224888
+:10EFB000777D000095941D4687B00000F895225F8C
+:10EFC000117C00000400221562310000F695A84073
+:10EFD0008132000000009D4081B20100000000402D
+:10EFE00049B1010000142F4C83B001000000004023
+:10EFF000F1B10100FB95A241835000000000804068
+:10F0000081B201000000004049B101003000004021
+:10F01000A19901000000004093B0010000000040F1
+:10F020001FB001004E9600499630010007000049CC
+:10F0300006E401000039000306C80100000000409A
+:10F0400005B00100200000D0A0C90100000000416F
+:10F0500093C001000296A054936C000000002E059E
+:10F0600097B0010000800040499901000000004075
+:10F07000E1B10100000200A244C901000B96A241C7
+:10F08000975000000000002049B301005496004052
+:10F0900049310100DF9200408132010000B52E08A5
+:10F0A00097B0010000000040F1B101001296A241AA
+:10F0B00097500000180000409798010000972E40DC
+:10F0C00081B2010000000040F1B101001696A2419A
+:10F0D000975000000000004049B1010040182E0583
+:10F0E00097B0010000000040F1B101001A96A24162
+:10F0F0009750000057952040E7B101003094004040
+:10F100004599010064000040E599010056952040B2
+:10F11000E7B10100B8942041E5B10100BA94204163
+:10F12000E5B10100989400404599010002000040BB
+:10F130009798010000000040F1B101002496A2411F
+:10F14000975000000000004097B001000000004010
+:10F150006FB101000000004B68B1010028968541A5
+:10F160009740000080040040813201000000004010
+:10F1700039B301000000004037B301000000004037
+:10F1800035B301000000004033B30100000000402F
+:10F1900041B30100000000403FB30100EE05004014
+:10F1A000259B0100420000404B9B010000000040F5
+:10F1B0002FB30100000000402DB30100000000400B
+:10F1C00047B301000000004043B30100600000406D
+:10F1D0002B9B010000000054EF930100000000553C
+:10F1E000F1930100FFFF00A53C8B01000000002C03
+:10F1F0005BB301000000002C45B30100000000409B
+:10F2000059B301000000004057B301000000004066
+:10F2100027B301000000004053B301004496A25000
+:10F22000FD7F00004496A251FD7F000045960040FE
+:10F230001DB30000504600401D9B010000C000A609
+:10F2400088B30100FF3F00A63AB3010000C0009D53
+:10F250003B9B0100B4050040239B010000000040DF
+:10F260004DB30100080A00A614B301000101008A91
+:10F27000159B0100008000A656B101000000805ED1
+:10F2800057B501001800004B20E401000600004BB8
+:10F2900096E401000043004B96C8010018000010DE
+:10F2A00020DC01000000004B20940100000080578A
+:10F2B0002190010000992E0A97B001000000004043
+:10F2C000F1B101005596A2419750000000030040A3
+:10F2D0009798010000A900404599010000000040F6
+:10F2E000F1B101005996A241975000003000004052
+:10F2F000979801000000005561B101000000004B2B
+:10F3000062B101005D96A840813200005D96A24185
+:10F31000975000000000804081B201000000804052
+:10F3200081B201000400004081B2000004000040EE
+:10F3300081B200000400004081B2000004000040DF
+:10F3400081B200000400004081B2000004000040CF
+:10F3500081B200000400004081B2000004000040BF
+:10F3600081B200000400004081B2000004000040AF
+:10F3700081B200000400004081B20000040000409F
+:10F3800081B200000400004081B20000040000408F
+:10F3900081B200000400004081B20000040000407F
+:10F3A00081B200000400004081B20000040000406F
+:10F3B00081B200000400004081B20000040000405F
+:10F3C00081B200000400004081B20000040000404F
+:10F3D00081B200000400004081B20000040000403F
+:10F3E00081B200000400004081B20000040000402F
+:10F3F00081B200000400004081B20000040000401F
+:10F4000081B200000400004081B20000040000400E
+:10F4100081B200000400004081B2000004000040FE
+:10F4200081B200000400004081B2000004000040EE
+:10F4300081B200000400004081B2000004000040DE
+:10F4400081B200000400004081B2000004000040CE
+:10F4500081B200000400004081B2000004000040BE
+:10F4600081B200000400004081B2000004000040AE
+:10F4700081B200000400004081B20000040000409E
+:10F4800081B200000400004081B20000040000408E
+:10F4900081B200000400004081B20000040000407E
+:10F4A00081B200000400004081B20000040000406E
+:10F4B00081B200000400004081B20000040000405E
+:10F4C00081B200000400004081B20000040000404E
+:10F4D00081B200000400004081B20000040000403E
+:10F4E00081B200000400004081B20000040000402E
+:10F4F00081B200000400004081B20000040000401E
+:10F5000081B200000400004081B20000040000400D
+:10F5100081B200000400004081B2000004000040FD
+:10F5200081B200000400004081B2000004000040ED
+:10F5300081B200000400004081B2000004000040DD
+:10F5400081B200000400004081B2000004000040CD
+:10F5500081B200000400004081B2000004000040BD
+:10F5600081B200000400004081B2000004000040AD
+:10F5700081B200000400004081B20000040000409D
+:10F5800081B200000400004081B20000040000408D
+:10F5900081B200000400004081B20000040000407D
+:10F5A00081B200000400004081B20000040000406D
+:10F5B00081B200000400004081B20000040000405D
+:10F5C00081B200000400004081B20000040000404D
+:10F5D00081B200000400004081B20000040000403D
+:10F5E00081B200000400004081B20000040000402D
+:10F5F00081B200000400004081B20000040000401D
+:10F6000081B200000400004081B20000040000400C
+:10F6100081B200000400004081B2000004000040FC
+:10F6200081B200000400004081B2000004000040EC
+:10F6300081B200000400004081B2000004000040DC
+:10F6400081B200000400004081B2000004000040CC
+:10F6500081B200000400004081B2000004000040BC
+:10F6600081B200000400004081B2000004000040AC
+:10F6700081B200000400004081B20000040000409C
+:10F6800081B200000400004081B20000040000408C
+:10F6900081B200000400004081B20000040000407C
+:10F6A00081B200000400004081B20000040000406C
+:10F6B00081B200000400004081B20000040000405C
+:10F6C00081B200000400004081B20000040000404C
+:10F6D00081B200000400004081B20000040000403C
+:10F6E00081B200000400004081B20000040000402C
+:10F6F00081B200000400004081B20000040000401C
+:10F7000081B200000400004081B20000040000400B
+:10F7100081B200000400004081B2000004000040FB
+:10F7200081B200000400004081B2000004000040EB
+:10F7300081B200000400004081B2000004000040DB
+:10F7400081B200000400004081B2000004000040CB
+:10F7500081B200000400004081B2000004000040BB
+:10F7600081B200000400004081B2000004000040AB
+:10F7700081B200000400004081B20000040000409B
+:10F7800081B200000400004081B20000040000408B
+:10F7900081B200000400004081B20000040000407B
+:10F7A00081B200000400004081B20000040000406B
+:10F7B00081B200000400004081B20000040000405B
+:10F7C00081B200000400004081B20000040000404B
+:10F7D00081B200000400004081B20000040000403B
+:10F7E00081B200000400004081B20000040000402B
+:10F7F00081B200000400004081B20000040000401B
+:10F8000081B200000400004081B20000040000400A
+:10F8100081B200000400004081B2000004000040FA
+:10F8200081B200000400004081B2000004000040EA
+:10F8300081B200000400004081B2000004000040DA
+:10F8400081B200000400004081B2000004000040CA
+:10F8500081B200000400004081B2000004000040BA
+:10F8600081B200000400004081B2000004000040AA
+:10F8700081B200000400004081B20000040000409A
+:10F8800081B200000400004081B20000040000408A
+:10F8900081B200000400004081B20000040000407A
+:10F8A00081B200000400004081B20000040000406A
+:10F8B00081B200000400004081B20000040000405A
+:10F8C00081B200000400004081B20000040000404A
+:10F8D00081B200000400004081B20000040000403A
+:10F8E00081B200000400004081B20000040000402A
+:10F8F00081B200000400004081B20000040000401A
+:10F9000081B200000400004081B200000400004009
+:10F9100081B200000400004081B2000004000040F9
+:10F9200081B200000400004081B2000004000040E9
+:10F9300081B200000400004081B2000004000040D9
+:10F9400081B200000400004081B2000004000040C9
+:10F9500081B200000400004081B2000004000040B9
+:10F9600081B200000400004081B2000004000040A9
+:10F9700081B200000400004081B200000400004099
+:10F9800081B200000400004081B200000400004089
+:10F9900081B200000400004081B200000400004079
+:10F9A00081B200000400004081B200000400004069
+:10F9B00081B200000400004081B200000400004059
+:10F9C00081B200000400004081B200000400004049
+:10F9D00081B200000400004081B200000400004039
+:10F9E00081B200000400004081B200000400004029
+:10F9F00081B200000400004081B200000400004019
+:10FA000081B200000400004081B200000400004008
+:10FA100081B200000400004081B2000004000040F8
+:10FA200081B200000400004081B2000004000040E8
+:10FA300081B200000400004081B2000004000040D8
+:10FA400081B200000400004081B2000004000040C8
+:10FA500081B200000400004081B2000004000040B8
+:10FA600081B200000400004081B2000004000040A8
+:10FA700081B200000400004081B200000400004098
+:10FA800081B200000400004081B200000400004088
+:10FA900081B200000400004081B200000400004078
+:10FAA00081B200000400004081B200000400004068
+:10FAB00081B200000400004081B200000400004058
+:10FAC00081B200000400004081B200000400004048
+:10FAD00081B200000400004081B200000400004038
+:10FAE00081B200000400004081B200000400004028
+:10FAF00081B200000400004081B200000400004018
+:10FB000081B200000400004081B200000400004007
+:10FB100081B200000400004081B2000004000040F7
+:10FB200081B200000400004081B2000004000040E7
+:10FB300081B200000400004081B2000004000040D7
+:10FB400081B200000400004081B2000004000040C7
+:10FB500081B200000400004081B2000004000040B7
+:10FB600081B200000400004081B2000004000040A7
+:10FB700081B200000400004081B200000400004097
+:10FB800081B200000400004081B200000400004087
+:10FB900081B200000400004081B200000400004077
+:10FBA00081B200000400004081B200000400004067
+:10FBB00081B200000400004081B200000400004057
+:10FBC00081B200000400004081B200000400004047
+:10FBD00081B200000400004081B200000400004037
+:10FBE00081B200000400004081B200000400004027
+:10FBF00081B200000400004081B200000400004017
+:10FC000081B200000400004081B200000400004006
+:10FC100081B200000400004081B2000004000040F6
+:10FC200081B200000400004081B2000004000040E6
+:10FC300081B200000400004081B2000004000040D6
+:10FC400081B200000400004081B2000004000040C6
+:10FC500081B200000400004081B2000004000040B6
+:10FC600081B200000400004081B2000004000040A6
+:10FC700081B200000400004081B200000400004096
+:10FC800081B200000400004081B200000400004086
+:10FC900081B200000400004081B200000400004076
+:10FCA00081B200000400004081B200000400004066
+:10FCB00081B200000400004081B200000400004056
+:10FCC00081B200000400004081B200000400004046
+:10FCD00081B200000400004081B200000400004036
+:10FCE00081B200000400004081B200000400004026
+:10FCF00081B200000400004081B200000400004016
+:10FD000081B200000400004081B200000400004005
+:10FD100081B200000400004081B2000004000040F5
+:10FD200081B200000400004081B2000004000040E5
+:10FD300081B200000400004081B2000004000040D5
+:10FD400081B200000400004081B2000004000040C5
+:10FD500081B200000400004081B2000004000040B5
+:10FD600081B200000400004081B2000004000040A5
+:10FD700081B200000400004081B200000400004095
+:10FD800081B200000400004081B200000400004085
+:10FD900081B200000400004081B200000400004075
+:10FDA00081B200000400004081B200000400004065
+:10FDB00081B200000400004081B200000400004055
+:10FDC00081B200000400004081B200000400004045
+:10FDD00081B200000400004081B200000400004035
+:10FDE00081B200000400004081B200000400004025
+:10FDF00081B200000400004081B200000400004015
+:10FE000081B200000400004081B200000400004004
+:10FE100081B200000400004081B2000004000040F4
+:10FE200081B200000400004081B2000004000040E4
+:10FE300081B200000400004081B2000004000040D4
+:10FE400081B200000400004081B2000004000040C4
+:10FE500081B200000400004081B2000004000040B4
+:10FE600081B200000400004081B2000004000040A4
+:10FE700081B200000400004081B200000400004094
+:10FE800081B200000400004081B200000400004084
+:10FE900081B200000400004081B200000400004074
+:10FEA00081B200000400004081B200000400004064
+:10FEB00081B200000400004081B200000400004054
+:10FEC00081B200000400004081B200000400004044
+:10FED00081B200000400004081B200000400004034
+:10FEE00081B200000400004081B200000400004024
+:10FEF00081B200000400004081B200000400004014
+:10FF000081B200000400004081B200000400004003
+:10FF100081B200000400004081B2000004000040F3
+:10FF200081B200000400004081B2000004000040E3
+:10FF300081B200000400004081B2000004000040D3
+:10FF400081B200000400004081B2000004000040C3
+:10FF500081B200000400004081B2000004000040B3
+:10FF600081B200000400004081B2000004000040A3
+:10FF700081B200000400004081B200000400004093
+:10FF800081B200000400004081B200000400004083
+:10FF900081B200000400004081B200000400004073
+:10FFA00081B200000400004081B200000400004063
+:10FFB00081B200000400004081B200000400004053
+:10FFC00081B200000400004081B200000400004043
+:10FFD00081B200000400004081B200000400004033
+:10FFE00081B200000400004081B200000400004023
+:10FFF00081B200000400004081B200000400004013
+:020000021000EC
+:1000000081B200000400004081B200000400004002
+:1000100081B200000400004081B2000004000040F2
+:1000200081B200000400004081B2000004000040E2
+:1000300081B200000400004081B2000004000040D2
+:1000400081B200000400004081B2000004000040C2
+:1000500081B200000400004081B2000004000040B2
+:1000600081B200000400004081B2000004000040A2
+:1000700081B200000400004081B200000400004092
+:1000800081B200000400004081B200000400004082
+:1000900081B200000400004081B200000400004072
+:1000A00081B200000400004081B200000400004062
+:1000B00081B200000400004081B200000400004052
+:1000C00081B200000400004081B200000400004042
+:1000D00081B200000400004081B200000400004032
+:1000E00081B200000400004081B200000400004022
+:1000F00081B200000400004081B200000400004012
+:1001000081B200000400004081B200000400004001
+:1001100081B200000400004081B2000004000040F1
+:1001200081B200000400004081B2000004000040E1
+:1001300081B200000400004081B2000004000040D1
+:1001400081B200000400004081B2000004000040C1
+:1001500081B200000400004081B2000004000040B1
+:1001600081B200000400004081B2000004000040A1
+:1001700081B200000400004081B200000400004091
+:1001800081B200000400004081B200000400004081
+:1001900081B200000400004081B200000400004071
+:1001A00081B200000400004081B200000400004061
+:1001B00081B200000400004081B200000400004051
+:1001C00081B200000400004081B200000400004041
+:1001D00081B200000400004081B200000400004031
+:1001E00081B200000400004081B200000400004021
+:1001F00081B200000400004081B200000400004011
+:1002000081B200000400004081B200000400004000
+:1002100081B200000400004081B2000004000040F0
+:1002200081B200000400004081B2000004000040E0
+:1002300081B200000400004081B2000004000040D0
+:1002400081B200000400004081B2000004000040C0
+:1002500081B200000400004081B2000004000040B0
+:1002600081B200000400004081B2000004000040A0
+:1002700081B200000400004081B200000400004090
+:1002800081B200000400004081B200000400004080
+:1002900081B200000400004081B200000400004070
+:1002A00081B200000400004081B200000400004060
+:1002B00081B200000400004081B200000400004050
+:1002C00081B200000400004081B200000400004040
+:1002D00081B200000400004081B200000400004030
+:1002E00081B200000400004081B200000400004020
+:1002F00081B200000400004081B200000400004010
+:1003000081B200000400004081B2000004000040FF
+:1003100081B200000400004081B2000004000040EF
+:1003200081B200000400004081B2000004000040DF
+:1003300081B200000400004081B2000004000040CF
+:1003400081B200000400004081B2000004000040BF
+:1003500081B200000400004081B2000004000040AF
+:1003600081B200000400004081B20000040000409F
+:1003700081B200000400004081B20000040000408F
+:1003800081B200000400004081B20000040000407F
+:1003900081B200000400004081B20000040000406F
+:1003A00081B200000400004081B20000040000405F
+:1003B00081B200000400004081B20000040000404F
+:1003C00081B200000400004081B20000040000403F
+:1003D00081B200000400004081B20000040000402F
+:1003E00081B200000400004081B20000040000401F
+:1003F00081B200000400004081B20000040000400F
+:1004000081B200000400004081B2000004000040FE
+:1004100081B200000400004081B2000004000040EE
+:1004200081B200000400004081B2000004000040DE
+:1004300081B200000400004081B2000004000040CE
+:1004400081B200000400004081B2000004000040BE
+:1004500081B200000400004081B2000004000040AE
+:1004600081B200000400004081B20000040000409E
+:1004700081B200000400004081B20000040000408E
+:1004800081B200000400004081B20000040000407E
+:1004900081B200000400004081B20000040000406E
+:1004A00081B200000400004081B20000040000405E
+:1004B00081B200000400004081B20000040000404E
+:1004C00081B200000400004081B20000040000403E
+:1004D00081B200000400004081B20000040000402E
+:1004E00081B200000400004081B20000040000401E
+:1004F00081B200000400004081B20000040000400E
+:1005000081B200000400004081B2000004000040FD
+:1005100081B200000400004081B2000004000040ED
+:1005200081B200000400004081B2000004000040DD
+:1005300081B200000400004081B2000004000040CD
+:1005400081B200000400004081B2000004000040BD
+:1005500081B200000400004081B2000004000040AD
+:1005600081B200000400004081B20000040000409D
+:1005700081B200000400004081B20000040000408D
+:1005800081B200000400004081B20000040000407D
+:1005900081B200000400004081B20000040000406D
+:1005A00081B200000400004081B20000040000405D
+:1005B00081B200000400004081B20000040000404D
+:1005C00081B200000400004081B20000040000403D
+:1005D00081B200000400004081B20000040000402D
+:1005E00081B200000400004081B20000040000401D
+:1005F00081B200000400004081B20000040000400D
+:1006000081B200000400004081B2000004000040FC
+:1006100081B200000400004081B2000004000040EC
+:1006200081B200000400004081B2000004000040DC
+:1006300081B200000400004081B2000004000040CC
+:1006400081B200000400004081B2000004000040BC
+:1006500081B200000400004081B2000004000040AC
+:1006600081B200000400004081B20000040000409C
+:1006700081B200000400004081B20000040000408C
+:1006800081B200000400004081B20000040000407C
+:1006900081B200000400004081B20000040000406C
+:1006A00081B200000400004081B20000040000405C
+:1006B00081B200000400004081B20000040000404C
+:1006C00081B200000400004081B20000040000403C
+:1006D00081B200000400004081B20000040000402C
+:1006E00081B200000400004081B20000040000401C
+:1006F00081B200000400004081B20000040000400C
+:1007000081B200000400004081B2000004000040FB
+:1007100081B200000400004081B2000004000040EB
+:1007200081B200000400004081B2000004000040DB
+:1007300081B200000400004081B2000004000040CB
+:1007400081B200000400004081B2000004000040BB
+:1007500081B200000400004081B2000004000040AB
+:1007600081B200000400004081B20000040000409B
+:1007700081B200000400004081B20000040000408B
+:1007800081B200000400004081B20000040000407B
+:1007900081B200000400004081B20000040000406B
+:1007A00081B200000400004081B20000040000405B
+:1007B00081B200000400004081B20000040000404B
+:1007C00081B200000400004081B20000040000403B
+:1007D00081B200000400004081B20000040000402B
+:1007E00081B200000400004081B20000040000401B
+:1007F00081B200000400004081B20000040000400B
+:1008000081B200000400004081B2000004000040FA
+:1008100081B200000400004081B2000004000040EA
+:1008200081B200000400004081B2000004000040DA
+:1008300081B200000400004081B2000004000040CA
+:1008400081B200000400004081B2000004000040BA
+:1008500081B200000400004081B2000004000040AA
+:1008600081B200000400004081B20000040000409A
+:1008700081B200000400004081B20000040000408A
+:1008800081B200000400004081B20000040000407A
+:1008900081B200000400004081B20000040000406A
+:1008A00081B200000400004081B20000040000405A
+:1008B00081B200000400004081B20000040000404A
+:1008C00081B200000400004081B20000040000403A
+:1008D00081B200000400004081B20000040000402A
+:1008E00081B200000400004081B20000040000401A
+:1008F00081B200000400004081B20000040000400A
+:1009000081B200000400004081B2000004000040F9
+:1009100081B200000400004081B2000004000040E9
+:1009200081B200000400004081B2000004000040D9
+:1009300081B200000400004081B2000004000040C9
+:1009400081B200000400004081B2000004000040B9
+:1009500081B200000400004081B2000004000040A9
+:1009600081B200000400004081B200000400004099
+:1009700081B200000400004081B200000400004089
+:1009800081B200000400004081B200000400004079
+:1009900081B200000400004081B200000400004069
+:1009A00081B200000400004081B200000400004059
+:1009B00081B200000400004081B200000400004049
+:1009C00081B200000400004081B200000400004039
+:1009D00081B200000400004081B200000400004029
+:1009E00081B200000400004081B200000400004019
+:1009F00081B200000400004081B200000400004009
+:100A000081B200000400004081B2000004000040F8
+:100A100081B200000400004081B2000004000040E8
+:100A200081B200000400004081B2000004000040D8
+:100A300081B200000400004081B2000004000040C8
+:100A400081B200000400004081B2000004000040B8
+:100A500081B200000400004081B2000004000040A8
+:100A600081B200000400004081B200000400004098
+:100A700081B200000400004081B200000400004088
+:100A800081B200000400004081B200000400004078
+:100A900081B200000400004081B200000400004068
+:100AA00081B200000400004081B200000400004058
+:100AB00081B200000400004081B200000400004048
+:100AC00081B200000400004081B200000400004038
+:100AD00081B200000400004081B200000400004028
+:100AE00081B200000400004081B200000400004018
+:100AF00081B200000400004081B200000400004008
+:100B000081B200000400004081B2000004000040F7
+:100B100081B200000400004081B2000004000040E7
+:100B200081B200000400004081B2000004000040D7
+:100B300081B200000400004081B2000004000040C7
+:100B400081B200000400004081B2000004000040B7
+:100B500081B200000400004081B2000004000040A7
+:100B600081B200000400004081B200000400004097
+:100B700081B200000400004081B200000400004087
+:100B800081B200000400004081B200000400004077
+:100B900081B200000400004081B200000400004067
+:100BA00081B200000400004081B200000400004057
+:100BB00081B200000400004081B200000400004047
+:100BC00081B200000400004081B200000400004037
+:100BD00081B200000400004081B200000400004027
+:100BE00081B200000400004081B200000400004017
+:100BF00081B200000400004081B200000400004007
+:100C000081B200000400004081B2000004000040F6
+:100C100081B200000400004081B2000004000040E6
+:100C200081B200000400004081B2000004000040D6
+:100C300081B200000400004081B2000004000040C6
+:100C400081B200000400004081B2000004000040B6
+:100C500081B200000400004081B2000004000040A6
+:100C600081B200000400004081B200000400004096
+:100C700081B200000400004081B200000400004086
+:100C800081B200000400004081B200000400004076
+:100C900081B200000400004081B200000400004066
+:100CA00081B200000400004081B200000400004056
+:100CB00081B200000400004081B200000400004046
+:100CC00081B200000400004081B200000400004036
+:100CD00081B200000400004081B200000400004026
+:100CE00081B200000400004081B200000400004016
+:100CF00081B200000400004081B200000400004006
+:100D000081B200000400004081B2000004000040F5
+:100D100081B200000400004081B2000004000040E5
+:100D200081B200000400004081B2000004000040D5
+:100D300081B200000400004081B2000004000040C5
+:100D400081B200000400004081B2000004000040B5
+:100D500081B200000400004081B2000004000040A5
+:100D600081B200000400004081B200000400004095
+:100D700081B200000400004081B200000400004085
+:100D800081B200000400004081B200000400004075
+:100D900081B200000400004081B200000400004065
+:100DA00081B200000400004081B200000400004055
+:100DB00081B200000400004081B200000400004045
+:100DC00081B200000400004081B200000400004035
+:100DD00081B200000400004081B200000400004025
+:100DE00081B200000400004081B200000400004015
+:100DF00081B200000400004081B200000400004005
+:100E000081B200000400004081B2000004000040F4
+:100E100081B200000400004081B2000004000040E4
+:100E200081B200000400004081B2000004000040D4
+:100E300081B200000400004081B2000004000040C4
+:100E400081B200000400004081B2000004000040B4
+:100E500081B200000400004081B2000004000040A4
+:100E600081B200000400004081B200000400004094
+:100E700081B200000400004081B200000400004084
+:100E800081B200000400004081B200000400004074
+:100E900081B200000400004081B200000400004064
+:100EA00081B200000400004081B200000400004054
+:100EB00081B200000400004081B200000400004044
+:100EC00081B200000400004081B200000400004034
+:100ED00081B200000400004081B200000400004024
+:100EE00081B200000400004081B200000400004014
+:100EF00081B200000400004081B200000400004004
+:100F000081B200000400004081B2000004000040F3
+:100F100081B200000400004081B2000004000040E3
+:100F200081B200000400004081B2000004000040D3
+:100F300081B200000400004081B2000004000040C3
+:100F400081B200000400004081B2000004000040B3
+:100F500081B200000400004081B2000004000040A3
+:100F600081B200000400004081B200000400004093
+:100F700081B200000400004081B200000400004083
+:100F800081B200000400004081B200000400004073
+:100F900081B200000400004081B200000400004063
+:100FA00081B200000400004081B200000400004053
+:100FB00081B200000400004081B200000400004043
+:100FC00081B200000400004081B200000400004033
+:100FD00081B200000400004081B200000400004023
+:100FE00081B200000400004081B200000400004013
+:100FF00081B200000400004081B200000400004003
+:1010000081B200000400004081B2000004000040F2
+:1010100081B200000400004081B2000004000040E2
+:1010200081B200000400004081B2000004000040D2
+:1010300081B200000400004081B2000004000040C2
+:1010400081B200000400004081B2000004000040B2
+:1010500081B200000400004081B2000004000040A2
+:1010600081B200000400004081B200000400004092
+:1010700081B200000400004081B200000400004082
+:1010800081B200000400004081B200000400004072
+:1010900081B200000400004081B200000400004062
+:1010A00081B200000400004081B200000400004052
+:1010B00081B200000400004081B200000400004042
+:1010C00081B200000400004081B200000400004032
+:1010D00081B200000400004081B200000400004022
+:1010E00081B200000400004081B200000400004012
+:1010F00081B200000400004081B200000400004002
+:1011000081B200000400004081B2000004000040F1
+:1011100081B200000400004081B2000004000040E1
+:1011200081B200000400004081B2000004000040D1
+:1011300081B200000400004081B2000004000040C1
+:1011400081B200000400004081B2000004000040B1
+:1011500081B200000400004081B2000004000040A1
+:1011600081B200000400004081B200000400004091
+:1011700081B200000400004081B200000400004081
+:1011800081B200000400004081B200000400004071
+:1011900081B200000400004081B200000400004061
+:1011A00081B200000400004081B200000400004051
+:1011B00081B200000400004081B200000400004041
+:1011C00081B200000400004081B200000400004031
+:1011D00081B200000400004081B200000400004021
+:1011E00081B200000400004081B200000400004011
+:1011F00081B200000400004081B200000400004001
+:1012000081B200000400004081B2000004000040F0
+:1012100081B200000400004081B2000004000040E0
+:1012200081B200000400004081B2000004000040D0
+:1012300081B200000400004081B2000004000040C0
+:1012400081B200000400004081B2000004000040B0
+:1012500081B200000400004081B2000004000040A0
+:1012600081B200000400004081B200000400004090
+:1012700081B200000400004081B200000400004080
+:1012800081B200000400004081B200000400004070
+:1012900081B200000400004081B200000400004060
+:1012A00081B200000400004081B200000400004050
+:1012B00081B200000400004081B200000400004040
+:1012C00081B200000400004081B200000400004030
+:1012D00081B200000400004081B200000400004020
+:1012E00081B200000400004081B200000400004010
+:1012F00081B200000400004081B200000400004000
+:1013000081B200000400004081B2000004000040EF
+:1013100081B200000400004081B2000004000040DF
+:1013200081B200000400004081B2000004000040CF
+:1013300081B200000400004081B2000004000040BF
+:1013400081B200000400004081B2000004000040AF
+:1013500081B200000400004081B20000040000409F
+:1013600081B200000400004081B20000040000408F
+:1013700081B200000400004081B20000040000407F
+:1013800081B200000400004081B20000040000406F
+:1013900081B200000400004081B20000040000405F
+:1013A00081B200000400004081B20000040000404F
+:1013B00081B200000400004081B20000040000403F
+:1013C00081B200000400004081B20000040000402F
+:1013D00081B200000400004081B20000040000401F
+:1013E00081B200000400004081B20000040000400F
+:1013F00081B200000400004081B2000004000040FF
+:1014000081B200000400004081B2000004000040EE
+:1014100081B200000400004081B2000004000040DE
+:1014200081B200000400004081B2000004000040CE
+:1014300081B200000400004081B2000004000040BE
+:1014400081B200000400004081B2000004000040AE
+:1014500081B200000400004081B20000040000409E
+:1014600081B200000400004081B20000040000408E
+:1014700081B200000400004081B20000040000407E
+:1014800081B200000400004081B20000040000406E
+:1014900081B200000400004081B20000040000405E
+:1014A00081B200000400004081B20000040000404E
+:1014B00081B200000400004081B20000040000403E
+:1014C00081B200000400004081B20000040000402E
+:1014D00081B200000400004081B20000040000401E
+:1014E00081B200000400004081B20000040000400E
+:1014F00081B200000400004081B2000004000040FE
+:1015000081B200000400004081B2000004000040ED
+:1015100081B200000400004081B2000004000040DD
+:1015200081B200000400004081B2000004000040CD
+:1015300081B200000400004081B2000004000040BD
+:1015400081B200000400004081B2000004000040AD
+:1015500081B200000400004081B20000040000409D
+:1015600081B200000400004081B20000040000408D
+:1015700081B200000400004081B20000040000407D
+:1015800081B200000400004081B20000040000406D
+:1015900081B200000400004081B20000040000405D
+:1015A00081B200000400004081B20000040000404D
+:1015B00081B200000400004081B20000040000403D
+:1015C00081B200000400004081B20000040000402D
+:1015D00081B200000400004081B20000040000401D
+:1015E00081B200000400004081B20000040000400D
+:1015F00081B200000400004081B2000004000040FD
+:1016000081B200000400004081B2000004000040EC
+:1016100081B200000400004081B2000004000040DC
+:1016200081B200000400004081B2000004000040CC
+:1016300081B200000400004081B2000004000040BC
+:1016400081B200000400004081B2000004000040AC
+:1016500081B200000400004081B20000040000409C
+:1016600081B200000400004081B20000040000408C
+:1016700081B200000400004081B20000040000407C
+:1016800081B200000400004081B20000040000406C
+:1016900081B200000400004081B20000040000405C
+:1016A00081B200000400004081B20000040000404C
+:1016B00081B200000400004081B20000040000403C
+:1016C00081B200000400004081B20000040000402C
+:1016D00081B200000400004081B20000040000401C
+:1016E00081B200000400004081B20000040000400C
+:1016F00081B200000400004081B2000004000040FC
+:1017000081B200000400004081B2000004000040EB
+:1017100081B200000400004081B2000004000040DB
+:1017200081B200000400004081B2000004000040CB
+:1017300081B200000400004081B2000004000040BB
+:1017400081B200000400004081B2000004000040AB
+:1017500081B200000400004081B20000040000409B
+:1017600081B200000400004081B20000040000408B
+:1017700081B200000400004081B20000040000407B
+:1017800081B200000400004081B20000040000406B
+:1017900081B200000400004081B20000040000405B
+:1017A00081B200000400004081B20000040000404B
+:1017B00081B200000400004081B20000040000403B
+:1017C00081B200000400004081B20000040000402B
+:1017D00081B200000400004081B20000040000401B
+:1017E00081B200000400004081B20000040000400B
+:1017F00081B200000400004081B2000004000040FB
+:1018000081B200000400004081B2000004000040EA
+:1018100081B200000400004081B2000004000040DA
+:1018200081B200000400004081B2000004000040CA
+:1018300081B200000400004081B2000004000040BA
+:1018400081B200000400004081B2000004000040AA
+:1018500081B200000400004081B20000040000409A
+:1018600081B200000400004081B20000040000408A
+:1018700081B200000400004081B20000040000407A
+:1018800081B200000400004081B20000040000406A
+:1018900081B200000400004081B20000040000405A
+:1018A00081B200000400004081B20000040000404A
+:1018B00081B200000400004081B20000040000403A
+:1018C00081B200000400004081B20000040000402A
+:1018D00081B200000400004081B20000040000401A
+:1018E00081B200000400004081B20000040000400A
+:1018F00081B200000400004081B2000004000040FA
+:1019000081B200000400004081B2000004000040E9
+:1019100081B200000400004081B2000004000040D9
+:1019200081B200000400004081B2000004000040C9
+:1019300081B200000400004081B2000004000040B9
+:1019400081B200000400004081B2000004000040A9
+:1019500081B200000400004081B200000400004099
+:1019600081B200000400004081B200000400004089
+:1019700081B200000400004081B200000400004079
+:1019800081B200000400004081B200000400004069
+:1019900081B200000400004081B200000400004059
+:1019A00081B200000400004081B200000400004049
+:1019B00081B200000400004081B200000400004039
+:1019C00081B200000400004081B200000400004029
+:1019D00081B200000400004081B200000400004019
+:1019E00081B200000400004081B200000400004009
+:1019F00081B200000400004081B2000004000040F9
+:101A000081B200000400004081B2000004000040E8
+:101A100081B200000400004081B2000004000040D8
+:101A200081B200000400004081B2000004000040C8
+:101A300081B200000400004081B2000004000040B8
+:101A400081B200000400004081B2000004000040A8
+:101A500081B200000400004081B200000400004098
+:101A600081B200000400004081B200000400004088
+:101A700081B200000400004081B200000400004078
+:101A800081B200000400004081B200000400004068
+:101A900081B200000400004081B200000400004058
+:101AA00081B200000400004081B200000400004048
+:101AB00081B200000400004081B200000400004038
+:101AC00081B200000400004081B200000400004028
+:101AD00081B200000400004081B200000400004018
+:101AE00081B200000400004081B200000400004008
+:101AF00081B200000400004081B2000004000040F8
+:101B000081B200000400004081B2000004000040E7
+:101B100081B200000400004081B2000004000040D7
+:101B200081B200000400004081B2000004000040C7
+:101B300081B200000400004081B2000004000040B7
+:101B400081B200000400004081B2000004000040A7
+:101B500081B200000400004081B200000400004097
+:101B600081B200000400004081B200000400004087
+:101B700081B200000400004081B200000400004077
+:101B800081B200000400004081B200000400004067
+:101B900081B200000400004081B200000400004057
+:101BA00081B200000400004081B200000400004047
+:101BB00081B200000400004081B200000400004037
+:101BC00081B200000400004081B200000400004027
+:101BD00081B200000400004081B200000400004017
+:101BE00081B200000400004081B200000400004007
+:101BF00081B200000400004081B2000004000040F7
+:101C000081B200000400004081B2000004000040E6
+:101C100081B200000400004081B2000004000040D6
+:101C200081B200000400004081B2000004000040C6
+:101C300081B200000400004081B2000004000040B6
+:101C400081B200000400004081B2000004000040A6
+:101C500081B200000400004081B200000400004096
+:101C600081B200000400004081B200000400004086
+:101C700081B200000400004081B200000400004076
+:101C800081B200000400004081B200000400004066
+:101C900081B200000400004081B200000400004056
+:101CA00081B200000400004081B200000400004046
+:101CB00081B200000400004081B200000400004036
+:101CC00081B200000400004081B200000400004026
+:101CD00081B200000400004081B200000400004016
+:101CE00081B200000400004081B200000400004006
+:101CF00081B200000400004081B2000004000040F6
+:101D000081B200000400004081B2000004000040E5
+:101D100081B200000400004081B2000004000040D5
+:101D200081B200000400004081B2000004000040C5
+:101D300081B200000400004081B2000004000040B5
+:101D400081B200000400004081B2000004000040A5
+:101D500081B200000400004081B200000400004095
+:101D600081B200000400004081B200000400004085
+:101D700081B200000400004081B200000400004075
+:101D800081B200000400004081B200000400004065
+:101D900081B200000400004081B200000400004055
+:101DA00081B200000400004081B200000400004045
+:101DB00081B200000400004081B200000400004035
+:101DC00081B200000400004081B200000400004025
+:101DD00081B200000400004081B200000400004015
+:101DE00081B200000400004081B200000400004005
+:101DF00081B200000400004081B2000004000040F5
+:101E000081B200000400004081B2000004000040E4
+:101E100081B200000400004081B2000004000040D4
+:101E200081B200000400004081B2000004000040C4
+:101E300081B200000400004081B2000004000040B4
+:101E400081B200000400004081B2000004000040A4
+:101E500081B200000400004081B200000400004094
+:101E600081B200000400004081B200000400004084
+:101E700081B200000400004081B200000400004074
+:101E800081B200000400004081B200000400004064
+:101E900081B200000400004081B200000400004054
+:101EA00081B200000400004081B200000400004044
+:101EB00081B200000400004081B200000400004034
+:101EC00081B200000400004081B200000400004024
+:101ED00081B200000400004081B200000400004014
+:101EE00081B200000400004081B200000400004004
+:101EF00081B200000400004081B2000004000040F4
+:101F000081B200000400004081B2000004000040E3
+:101F100081B200000400004081B2000004000040D3
+:101F200081B200000400004081B2000004000040C3
+:101F300081B200000400004081B2000004000040B3
+:101F400081B200000400004081B2000004000040A3
+:101F500081B200000400004081B200000400004093
+:101F600081B200000400004081B200000400004083
+:101F700081B200000400004081B200000400004073
+:101F800081B200000400004081B200000400004063
+:101F900081B200000400004081B200000400004053
+:101FA00081B200000400004081B200000400004043
+:101FB00081B200000400004081B200000400004033
+:101FC00081B200000400004081B200000400004023
+:101FD00081B200000400004081B200000400004013
+:101FE00081B200000400004081B200000400004003
+:101FF00081B200000400004081B2000004000040F3
+:1020000081B200000400004081B2000004000040E2
+:1020100081B200000400004081B2000004000040D2
+:1020200081B200000400004081B2000004000040C2
+:1020300081B200000400004081B2000004000040B2
+:1020400081B200000400004081B2000004000040A2
+:1020500081B200000400004081B200000400004092
+:1020600081B200000400004081B200000400004082
+:1020700081B200000400004081B200000400004072
+:1020800081B200000400004081B200000400004062
+:1020900081B200000400004081B200000400004052
+:1020A00081B200000400004081B200000400004042
+:1020B00081B200000400004081B200000400004032
+:1020C00081B200000400004081B200000400004022
+:1020D00081B200000400004081B200000400004012
+:1020E00081B200000400004081B200000400004002
+:1020F00081B200000400004081B2000004000040F2
+:1021000081B200000400004081B2000004000040E1
+:1021100081B200000400004081B2000004000040D1
+:1021200081B200000400004081B2000004000040C1
+:1021300081B200000400004081B2000004000040B1
+:1021400081B200000400004081B2000004000040A1
+:1021500081B200000400004081B200000400004091
+:1021600081B200000400004081B200000400004081
+:1021700081B200000400004081B200000400004071
+:1021800081B200000400004081B200000400004061
+:1021900081B200000400004081B200000400004051
+:1021A00081B200000400004081B200000400004041
+:1021B00081B200000400004081B200000400004031
+:1021C00081B200000400004081B200000400004021
+:1021D00081B200000400004081B200000400004011
+:1021E00081B200000400004081B200000400004001
+:1021F00081B200000400004081B2000004000040F1
+:1022000081B200000400004081B2000004000040E0
+:1022100081B200000400004081B2000004000040D0
+:1022200081B200000400004081B2000004000040C0
+:1022300081B200000400004081B2000004000040B0
+:1022400081B200000400004081B2000004000040A0
+:1022500081B200000400004081B200000400004090
+:1022600081B200000400004081B200000400004080
+:1022700081B200000400004081B200000400004070
+:1022800081B200000400004081B200000400004060
+:1022900081B200000400004081B200000400004050
+:1022A00081B200000400004081B200000400004040
+:1022B00081B200000400004081B200000400004030
+:1022C00081B200000400004081B200000400004020
+:1022D00081B200000400004081B200000400004010
+:1022E00081B200000400004081B200000400004000
+:1022F00081B200000400004081B2000004000040F0
+:1023000081B200000400004081B2000004000040DF
+:1023100081B200000400004081B2000004000040CF
+:1023200081B200000400004081B2000004000040BF
+:1023300081B200000400004081B2000004000040AF
+:1023400081B200000400004081B20000040000409F
+:1023500081B200000400004081B20000040000408F
+:1023600081B200000400004081B20000040000407F
+:1023700081B200000400004081B20000040000406F
+:1023800081B200000400004081B20000040000405F
+:1023900081B200000400004081B20000040000404F
+:1023A00081B200000400004081B20000040000403F
+:1023B00081B200000400004081B20000040000402F
+:1023C00081B200000400004081B20000040000401F
+:1023D00081B200000400004081B20000040000400F
+:1023E00081B200000400004081B2000004000040FF
+:1023F00081B200000400004081B2000004000040EF
+:1024000081B200000400004081B2000004000040DE
+:1024100081B200000400004081B2000004000040CE
+:1024200081B200000400004081B2000004000040BE
+:1024300081B200000400004081B2000004000040AE
+:1024400081B200000400004081B20000040000409E
+:1024500081B200000400004081B20000040000408E
+:1024600081B200000400004081B20000040000407E
+:1024700081B200000400004081B20000040000406E
+:1024800081B200000400004081B20000040000405E
+:1024900081B200000400004081B20000040000404E
+:1024A00081B200000400004081B20000040000403E
+:1024B00081B200000400004081B20000040000402E
+:1024C00081B200000400004081B20000040000401E
+:1024D00081B200000400004081B20000040000400E
+:1024E00081B200000400004081B2000004000040FE
+:1024F00081B200000400004081B2000004000040EE
+:1025000081B200000400004081B2000004000040DD
+:1025100081B200000400004081B2000004000040CD
+:1025200081B200000400004081B2000004000040BD
+:1025300081B200000400004081B2000004000040AD
+:1025400081B200000400004081B20000040000409D
+:1025500081B200000400004081B20000040000408D
+:1025600081B200000400004081B20000040000407D
+:1025700081B200000400004081B20000040000406D
+:1025800081B200000400004081B20000040000405D
+:1025900081B200000400004081B20000040000404D
+:1025A00081B200000400004081B20000040000403D
+:1025B00081B200000400004081B20000040000402D
+:1025C00081B200000400004081B20000040000401D
+:1025D00081B200000400004081B20000040000400D
+:1025E00081B200000400004081B2000004000040FD
+:1025F00081B200000400004081B2000004000040ED
+:1026000081B200000400004081B2000004000040DC
+:1026100081B200000400004081B2000004000040CC
+:1026200081B200000400004081B2000004000040BC
+:1026300081B200000400004081B2000004000040AC
+:1026400081B200000400004081B20000040000409C
+:1026500081B200000400004081B20000040000408C
+:1026600081B200000400004081B20000040000407C
+:1026700081B200000400004081B20000040000406C
+:1026800081B200000400004081B20000040000405C
+:1026900081B200000400004081B20000040000404C
+:1026A00081B200000400004081B20000040000403C
+:1026B00081B200000400004081B20000040000402C
+:1026C00081B200000400004081B20000040000401C
+:1026D00081B200000400004081B20000040000400C
+:1026E00081B200000400004081B2000004000040FC
+:1026F00081B200000400004081B2000004000040EC
+:1027000081B200000400004081B2000004000040DB
+:1027100081B200000400004081B2000004000040CB
+:1027200081B200000400004081B2000004000040BB
+:1027300081B200000400004081B2000004000040AB
+:1027400081B200000400004081B20000040000409B
+:1027500081B200000400004081B20000040000408B
+:1027600081B200000400004081B20000040000407B
+:1027700081B200000400004081B20000040000406B
+:1027800081B200000400004081B20000040000405B
+:1027900081B200000400004081B20000040000404B
+:1027A00081B200000400004081B20000040000403B
+:1027B00081B200000400004081B20000040000402B
+:1027C00081B200000400004081B20000040000401B
+:1027D00081B200000400004081B20000040000400B
+:1027E00081B200000400004081B2000004000040FB
+:1027F00081B200000400004081B2000004000040EB
+:1028000081B200000400004081B2000004000040DA
+:1028100081B200000400004081B2000004000040CA
+:1028200081B200000400004081B2000004000040BA
+:1028300081B200000400004081B2000004000040AA
+:1028400081B200000400004081B20000040000409A
+:1028500081B200000400004081B20000040000408A
+:1028600081B200000400004081B20000040000407A
+:1028700081B200000400004081B20000040000406A
+:1028800081B200000400004081B20000040000405A
+:1028900081B200000400004081B20000040000404A
+:1028A00081B200000400004081B20000040000403A
+:1028B00081B200000400004081B20000040000402A
+:1028C00081B200000400004081B20000040000401A
+:1028D00081B200000400004081B20000040000400A
+:1028E00081B200000400004081B2000004000040FA
+:1028F00081B200000400004081B2000004000040EA
+:1029000081B200000400004081B2000004000040D9
+:1029100081B200000400004081B2000004000040C9
+:1029200081B200000400004081B2000004000040B9
+:1029300081B200000400004081B2000004000040A9
+:1029400081B200000400004081B200000400004099
+:1029500081B200000400004081B200000400004089
+:1029600081B200000400004081B200000400004079
+:1029700081B200000400004081B200000400004069
+:1029800081B200000400004081B200000400004059
+:1029900081B200000400004081B200000400004049
+:1029A00081B200000400004081B200000400004039
+:1029B00081B200000400004081B200000400004029
+:1029C00081B200000400004081B200000400004019
+:1029D00081B200000400004081B200000400004009
+:1029E00081B200000400004081B2000004000040F9
+:1029F00081B200000400004081B2000004000040E9
+:102A000081B200000400004081B2000004000040D8
+:102A100081B200000400004081B2000004000040C8
+:102A200081B200000400004081B2000004000040B8
+:102A300081B200000400004081B2000004000040A8
+:102A400081B200000400004081B200000400004098
+:102A500081B200000400004081B200000400004088
+:102A600081B200000400004081B200000400004078
+:102A700081B200000400004081B200000400004068
+:102A800081B200000400004081B200000400004058
+:102A900081B200000400004081B200000400004048
+:102AA00081B200000400004081B200000400004038
+:102AB00081B200000400004081B200000400004028
+:102AC00081B200000400004081B200000400004018
+:102AD00081B200000400004081B200000400004008
+:102AE00081B200000400004081B2000004000040F8
+:102AF00081B200000400004081B2000004000040E8
+:102B000081B200000400004081B2000004000040D7
+:102B100081B200000400004081B2000004000040C7
+:102B200081B200000400004081B2000004000040B7
+:102B300081B200000400004081B2000004000040A7
+:102B400081B200000400004081B200000400004097
+:102B500081B200000400004081B200000400004087
+:102B600081B200000400004081B200000400004077
+:102B700081B200000400004081B200000400004067
+:102B800081B200000400004081B200000400004057
+:102B900081B200000400004081B200000400004047
+:102BA00081B200000400004081B200000400004037
+:102BB00081B200000400004081B200000400004027
+:102BC00081B200000400004081B200000400004017
+:102BD00081B200000400004081B200000400004007
+:102BE00081B200000400004081B2000004000040F7
+:102BF00081B200000400004081B2000004000040E7
+:102C000081B200000400004081B2000004000040D6
+:102C100081B200000400004081B2000004000040C6
+:102C200081B200000400004081B2000004000040B6
+:102C300081B200000400004081B2000004000040A6
+:102C400081B200000400004081B200000400004096
+:102C500081B200000400004081B200000400004086
+:102C600081B200000400004081B200000400004076
+:102C700081B200000400004081B200000400004066
+:102C800081B200000400004081B200000400004056
+:102C900081B200000400004081B200000400004046
+:102CA00081B200000400004081B200000400004036
+:102CB00081B200000400004081B200000400004026
+:102CC00081B200000400004081B200000400004016
+:102CD00081B200000400004081B200000400004006
+:102CE00081B200000400004081B2000004000040F6
+:102CF00081B200000400004081B2000004000040E6
+:102D000081B200000400004081B2000004000040D5
+:102D100081B200000400004081B2000004000040C5
+:102D200081B200000400004081B2000004000040B5
+:102D300081B200000400004081B2000004000040A5
+:102D400081B200000400004081B200000400004095
+:102D500081B200000400004081B200000400004085
+:102D600081B200000400004081B200000400004075
+:102D700081B200000400004081B200000400004065
+:102D800081B200000400004081B200000400004055
+:102D900081B200000400004081B200000400004045
+:102DA00081B200000400004081B200000400004035
+:102DB00081B200000400004081B200000400004025
+:102DC00081B200000400004081B200000400004015
+:102DD00081B200000400004081B200000400004005
+:102DE00081B200000400004081B2000004000040F5
+:102DF00081B200000400004081B2000004000040E5
+:102E000081B200000400004081B2000004000040D4
+:102E100081B200000400004081B2000004000040C4
+:102E200081B200000400004081B2000004000040B4
+:102E300081B200000400004081B2000004000040A4
+:102E400081B200000400004081B200000400004094
+:102E500081B200000400004081B200000400004084
+:102E600081B200000400004081B200000400004074
+:102E700081B200000400004081B200000400004064
+:102E800081B200000400004081B200000400004054
+:102E900081B200000400004081B200000400004044
+:102EA00081B200000400004081B200000400004034
+:102EB00081B200000400004081B200000400004024
+:102EC00081B200000400004081B200000400004014
+:102ED00081B200000400004081B200000400004004
+:102EE00081B200000400004081B2000004000040F4
+:102EF00081B200000400004081B2000004000040E4
+:102F000081B200000400004081B2000004000040D3
+:102F100081B200000400004081B2000004000040C3
+:102F200081B200000400004081B2000004000040B3
+:102F300081B200000400004081B2000004000040A3
+:102F400081B200000400004081B200000400004093
+:102F500081B200000400004081B200000400004083
+:102F600081B200000400004081B200000400004073
+:102F700081B200000400004081B200000400004063
+:102F800081B200000400004081B200000400004053
+:102F900081B200000400004081B200000400004043
+:102FA00081B200000400004081B200000400004033
+:102FB00081B200000400004081B200000400004023
+:102FC00081B200000400004081B200000400004013
+:102FD00081B200000400004081B200000400004003
+:102FE00081B200000400004081B2000004000040F3
+:102FF00081B200000400004081B2000004000040E3
+:1030000081B200000400004081B2000004000040D2
+:1030100081B200000400004081B2000004000040C2
+:1030200081B200000400004081B2000004000040B2
+:1030300081B200000400004081B2000004000040A2
+:1030400081B200000400004081B200000400004092
+:1030500081B200000400004081B200000400004082
+:1030600081B200000400004081B200000400004072
+:1030700081B200000400004081B200000400004062
+:1030800081B200000400004081B200000400004052
+:1030900081B200000400004081B200000400004042
+:1030A00081B200000400004081B200000400004032
+:1030B00081B200000400004081B200000400004022
+:1030C00081B200000400004081B200000400004012
+:1030D00081B200000400004081B200000400004002
+:1030E00081B200000400004081B2000004000040F2
+:1030F00081B200000400004081B2000004000040E2
+:1031000081B200000400004081B2000004000040D1
+:1031100081B200000400004081B2000004000040C1
+:1031200081B200000400004081B2000004000040B1
+:1031300081B200000400004081B2000004000040A1
+:1031400081B200000400004081B200000400004091
+:1031500081B200000400004081B200000400004081
+:1031600081B200000400004081B200000400004071
+:1031700081B200000400004081B200000400004061
+:1031800081B200000400004081B200000400004051
+:1031900081B200000400004081B200000400004041
+:1031A00081B200000400004081B200000400004031
+:1031B00081B200000400004081B200000400004021
+:1031C00081B200000400004081B200000400004011
+:1031D00081B200000400004081B200000400004001
+:1031E00081B200000400004081B2000004000040F1
+:1031F00081B200000400004081B2000004000040E1
+:1032000081B200000400004081B2000004000040D0
+:1032100081B200000400004081B2000004000040C0
+:1032200081B200000400004081B2000004000040B0
+:1032300081B200000400004081B2000004000040A0
+:1032400081B200000400004081B200000400004090
+:1032500081B200000400004081B200000400004080
+:1032600081B200000400004081B200000400004070
+:1032700081B200000400004081B200000400004060
+:1032800081B200000400004081B200000400004050
+:1032900081B200000400004081B200000400004040
+:1032A00081B200000400004081B200000400004030
+:1032B00081B200000400004081B200000400004020
+:1032C00081B200000400004081B200000400004010
+:1032D00081B200000400004081B200000400004000
+:1032E00081B200000400004081B2000004000040F0
+:1032F00081B200000400004081B2000004000040E0
+:1033000081B200000400004081B2000004000040CF
+:1033100081B200000400004081B2000004000040BF
+:1033200081B200000400004081B2000004000040AF
+:1033300081B200000400004081B20000040000409F
+:1033400081B200000400004081B20000040000408F
+:1033500081B200000400004081B20000040000407F
+:1033600081B200000400004081B20000040000406F
+:1033700081B200000400004081B20000040000405F
+:1033800081B200000400004081B20000040000404F
+:1033900081B200000400004081B20000040000403F
+:1033A00081B200000400004081B20000040000402F
+:1033B00081B200000400004081B20000040000401F
+:1033C00081B200000400004081B20000040000400F
+:1033D00081B200000400004081B2000004000040FF
+:1033E00081B200000400004081B2000004000040EF
+:1033F00081B200000400004081B2000004000040DF
+:1034000081B200000400004081B2000004000040CE
+:1034100081B200000400004081B2000004000040BE
+:1034200081B200000400004081B2000004000040AE
+:1034300081B200000400004081B20000040000409E
+:1034400081B200000400004081B20000040000408E
+:1034500081B200000400004081B20000040000407E
+:1034600081B200000400004081B20000040000406E
+:1034700081B200000400004081B20000040000405E
+:1034800081B200000400004081B20000040000404E
+:1034900081B200000400004081B20000040000403E
+:1034A00081B200000400004081B20000040000402E
+:1034B00081B200000400004081B20000040000401E
+:1034C00081B200000400004081B20000040000400E
+:1034D00081B200000400004081B2000004000040FE
+:1034E00081B200000400004081B2000004000040EE
+:1034F00081B200000400004081B2000004000040DE
+:1035000081B200000400004081B2000004000040CD
+:1035100081B200000400004081B2000004000040BD
+:1035200081B200000400004081B2000004000040AD
+:1035300081B200000400004081B20000040000409D
+:1035400081B200000400004081B20000040000408D
+:1035500081B200000400004081B20000040000407D
+:1035600081B200000400004081B20000040000406D
+:1035700081B200000400004081B20000040000405D
+:1035800081B200000400004081B20000040000404D
+:1035900081B200000400004081B20000040000403D
+:1035A00081B200000400004081B20000040000402D
+:1035B00081B200000400004081B20000040000401D
+:1035C00081B200000400004081B20000040000400D
+:1035D00081B200000400004081B2000004000040FD
+:1035E00081B200000400004081B2000004000040ED
+:1035F00081B200000400004081B2000004000040DD
+:1036000081B200000400004081B2000004000040CC
+:1036100081B200000400004081B2000004000040BC
+:1036200081B200000400004081B2000004000040AC
+:1036300081B200000400004081B20000040000409C
+:1036400081B200000400004081B20000040000408C
+:1036500081B200000400004081B20000040000407C
+:1036600081B200000400004081B20000040000406C
+:1036700081B200000400004081B20000040000405C
+:1036800081B200000400004081B20000040000404C
+:1036900081B200000400004081B20000040000403C
+:1036A00081B200000400004081B20000040000402C
+:1036B00081B200000400004081B20000040000401C
+:1036C00081B200000400004081B20000040000400C
+:1036D00081B200000400004081B2000004000040FC
+:1036E00081B200000400004081B2000004000040EC
+:1036F00081B200000400004081B2000004000040DC
+:1037000081B200000400004081B2000004000040CB
+:1037100081B200000400004081B2000004000040BB
+:1037200081B200000400004081B2000004000040AB
+:1037300081B200000400004081B20000040000409B
+:1037400081B200000400004081B20000040000408B
+:1037500081B200000400004081B20000040000407B
+:1037600081B200000400004081B20000040000406B
+:1037700081B200000400004081B20000040000405B
+:1037800081B200000400004081B20000040000404B
+:1037900081B200000400004081B20000040000403B
+:1037A00081B200000400004081B20000040000402B
+:1037B00081B200000400004081B20000040000401B
+:1037C00081B200000400004081B20000040000400B
+:1037D00081B200000400004081B2000004000040FB
+:1037E00081B200000400004081B2000004000040EB
+:1037F00081B200000400004081B2000004000040DB
+:1038000081B200000400004081B2000004000040CA
+:1038100081B200000400004081B2000004000040BA
+:1038200081B200000400004081B2000004000040AA
+:1038300081B200000400004081B20000040000409A
+:1038400081B200000400004081B20000040000408A
+:1038500081B200000400004081B20000040000407A
+:1038600081B200000400004081B20000040000406A
+:1038700081B200000400004081B20000040000405A
+:1038800081B200000400004081B20000040000404A
+:1038900081B200000400004081B20000040000403A
+:1038A00081B200000400004081B20000040000402A
+:1038B00081B200000400004081B20000040000401A
+:1038C00081B200000400004081B20000040000400A
+:1038D00081B200000400004081B2000004000040FA
+:1038E00081B200000400004081B2000004000040EA
+:1038F00081B200000400004081B2000004000040DA
+:1039000081B200000400004081B2000004000040C9
+:1039100081B200000400004081B2000004000040B9
+:1039200081B200000400004081B2000004000040A9
+:1039300081B200000400004081B200000400004099
+:1039400081B200000400004081B200000400004089
+:1039500081B200000400004081B200000400004079
+:1039600081B200000400004081B200000400004069
+:1039700081B200000400004081B200000400004059
+:1039800081B200000400004081B200000400004049
+:1039900081B200000400004081B200000400004039
+:1039A00081B200000400004081B200000400004029
+:1039B00081B200000400004081B200000400004019
+:1039C00081B200000400004081B200000400004009
+:1039D00081B200000400004081B2000004000040F9
+:1039E00081B200000400004081B2000004000040E9
+:1039F00081B200000400004081B2000004000040D9
+:103A000081B200000400004081B2000004000040C8
+:103A100081B200000400004081B2000004000040B8
+:103A200081B200000400004081B2000004000040A8
+:103A300081B200000400004081B200000400004098
+:103A400081B200000400004081B200000400004088
+:103A500081B200000400004081B200000400004078
+:103A600081B200000400004081B200000400004068
+:103A700081B200000400004081B200000400004058
+:103A800081B200000400004081B200000400004048
+:103A900081B200000400004081B200000400004038
+:103AA00081B200000400004081B200000400004028
+:103AB00081B200000400004081B200000400004018
+:103AC00081B200000400004081B200000400004008
+:103AD00081B200000400004081B2000004000040F8
+:103AE00081B200000400004081B2000004000040E8
+:103AF00081B200000400004081B2000004000040D8
+:103B000081B200000400004081B2000004000040C7
+:103B100081B200000400004081B2000004000040B7
+:103B200081B200000400004081B2000004000040A7
+:103B300081B200000400004081B200000400004097
+:103B400081B200000400004081B200000400004087
+:103B500081B200000400004081B200000400004077
+:103B600081B200000400004081B200000400004067
+:103B700081B200000400004081B200000400004057
+:103B800081B200000400004081B200000400004047
+:103B900081B200000400004081B200000400004037
+:103BA00081B200000400004081B200000400004027
+:103BB00081B200000400004081B200000400004017
+:103BC00081B200000400004081B200000400004007
+:103BD00081B200000400004081B2000004000040F7
+:103BE00081B200000400004081B2000004000040E7
+:103BF00081B200000400004081B2000004000040D7
+:103C000081B200000400004081B2000004000040C6
+:103C100081B200000400004081B2000004000040B6
+:103C200081B200000400004081B2000004000040A6
+:103C300081B200000400004081B200000400004096
+:103C400081B200000400004081B200000400004086
+:103C500081B200000400004081B200000400004076
+:103C600081B200000400004081B200000400004066
+:103C700081B200000400004081B200000400004056
+:103C800081B200000400004081B200000400004046
+:103C900081B200000400004081B200000400004036
+:103CA00081B200000400004081B200000400004026
+:103CB00081B200000400004081B200000400004016
+:103CC00081B200000400004081B200000400004006
+:103CD00081B200000400004081B2000004000040F6
+:103CE00081B200000400004081B2000004000040E6
+:103CF00081B200000400004081B2000004000040D6
+:103D000081B200000400004081B2000004000040C5
+:103D100081B200000400004081B2000004000040B5
+:103D200081B200000400004081B2000004000040A5
+:103D300081B200000400004081B200000400004095
+:103D400081B200000400004081B200000400004085
+:103D500081B20000AE9F00889AB00000AE9F00883C
+:103D60009AB00000AE9F00889AB00000AE9F008815
+:103D70009AB00000AE9F00889AB000000000008852
+:103D80009AB00100AE9F414081320000B29F2240B4
+:103D90007B6F00000000194081B20100AE9F00401F
+:103DA00081B20000000019417BB30100000000A4B3
+:103DB000C4B30100000000A1C6B3010000002FA29F
+:103DC000C8B301000814004049990100A89F004DA4
+:103DD0009ACC0100BB9F2640813200000000004CBD
+:103DE00049C10100B99FA2419B500000BF9F808044
+:103DF0008032000000005249FD9301000000004A9B
+:103E0000FD930100C29F0042CD9300000000514A83
+:103E1000FD93010000000049FD930100C29F004393
+:103E2000CB9300000000504081B20100D29F0040BF
+:103E300019990100000000F09AB001000000004450
+:103E400049D10100000040F080B201000000414D66
+:103E500080B20100CA9F00401999010000004C4047
+:103E600081B201000000004449D10100000000F0CF
+:103E70009AB001000000004D10B10000000000E207
+:103E800049B10100000000E343B10100000000E47B
+:103E900045B10100000000407BB301000000484F25
+:103EA00040B10100D29F004081B2000004000040F8
+:103EB00081B200000400004081B200000400004014
+:103EC00081B200000400004081B200000400004004
+:103ED00081B20000040000CB81C80100F4820040E0
+:103EE000F29300004082004081B200004005004093
+:103EF00081B200001806004081B20000F482004048
+:103F000081B20000AF82004081B2000038810040E1
+:103F100081B200003681004081B20000B8800040CC
+:103F200081B200001A87004081B20000AF820040D9
+:103F300081B20000F582004081B20000AB920040E7
+:103F400081B20000F095004081B200007392004001
+:103F500081B20000DF95004081B200004A9300402A
+:103F600081B20000ED92004081B20000E792004073
+:103F700081B200009A82004081B2000000008040BF
+:103F800081B201000400004081B200000400004042
+:103F900081B200000400004081B200000400004033
+:103FA00081B200000400004081B200000400004023
+:103FB00081B200000400004081B200000400004013
+:103FC00081B200000400004081B200000400004003
+:103FD00081B200000400004081B2000004000040F3
+:103FE00081B200000400004081B2000004000040E3
+:103FF00081B200000400004081B2000004000040D3
+:1040000081B200000400004081B2000004000040C2
+:0440100081B2000079
+:00000001FF
diff --git a/firmware/slicoss/oasisrcvucode.sys.ihex b/firmware/slicoss/oasisrcvucode.sys.ihex
new file mode 100644
index 0000000..813bea4
--- /dev/null
+++ b/firmware/slicoss/oasisrcvucode.sys.ihex
@@ -0,0 +1,162 @@
+:10000000000200004775010004A01301001CB75B4B
+:10001000093000B65F01001C00000020183B783A50
+:10002000001CA27701001C071D017018AD7BF1FFB9
+:100030001CB37BA9AA1EB47B010C1CB57B0D061C4E
+:1000400000003064080C315A70040C315A80040CE2
+:10005000314E90040C314AA000092555C0040C31E2
+:1000600052B000E92455C004CCB3001C1CEB2D0198
+:10007000001C065632D408079D00001C7BB7020006
+:1000800010A00F31540906565EC004A0305403007E
+:10009000AC30550300CD033A001C7BB702001C6056
+:1000A0008E3154092925550300808E3154098C3036
+:1000B000910004471C01001CA00F3154090000648A
+:1000C0000004471C65C004471C5503006C30010048
+:1000D0001C4D3402001C7BB702001CA00F315409D8
+:1000E000C88337001C800100001C0000640004A0CD
+:1000F0000F305409000054C3047BFBF2001CCC33C6
+:100100000D001CB47BFD031C800E305409E0FB0580
+:10011000001C00008C0300B30F3154090000EC7088
+:10012000040000EC800400008C930061768DC30411
+:10013000C08D315409E07B00C01FA0FDC50100CC7B
+:100140003305001CD403003C1CD4D31B001CC0D3BB
+:1001500052001C00005C13048E8E3254095B805EDA
+:100160001304000000001C0000940100A00F315493
+:1001700009A00F315409C003FC7F1CA001A001009D
+:100180000000A40100A00F315409C003FC031CF5BA
+:100190007701001C267AE6051CA00F315409B30F25
+:1001A000315409B50202001CA00F3154097A7E02B5
+:1001B000001CB50202001C530F325409AF030100AA
+:1001C0001C7A0E325409B50202001C000002001C09
+:1001D000A03DAA11040000AC1104D4D352001CB5F8
+:1001E0003EB2010020FBFDFF1F802C6C0300B93ADA
+:1001F0009E0100753B02001CA71C010010DB83164A
+:10020000001CC71D21C104B93B8DC1048B2C01000A
+:100210001C6B2C35C1040000781100CB2C79C10473
+:10022000A00F315409A00F31540954D002001C49C9
+:1002300025B10100AB2C81C104A71D550300CC33AF
+:1002400009001CEB2D01001CEA2901001CA00F3144
+:100250005409AE0F315409A00F315409D407FC03DF
+:100260001C993A02001CBB3802001C003800001C1C
+:100270000000FC0104DB3B7E001CC71D01001C26A6
+:100280007AFA051C271D01001CB30F3154097A0EA0
+:10029000325409530F3254097A0E325409530F3233
+:1002A00054097A0E325409530F325409A00F3154B5
+:1002B000097A0602001C530F325409AF0301001CD7
+:1002C0007A0E325409530F3254097A0E32540953BC
+:1002D0000F3254097A0E325409530F3254097A0EF0
+:1002E000325409003D02001C0000581200CB2C01C2
+:1002F000001C753B02001CA71C010010CB2F050041
+:100300001C602C00001CC71CC90200A00F3154093E
+:10031000530702001C467ACA051C7A0E3254094063
+:10032000FA19001C0000880204467ACA051CA00FB6
+:10033000315409A00F315409A00F315409A00F31D5
+:100340005409B37B01C01F740E305409C0039C00D4
+:100350001C8000D802000000D802040000AC120586
+:10036000071D01001CD4D32B001CD4D352001C80C9
+:10037000767D13040000E00200A67B950310C79C65
+:1003800000001C802C00001C00006C0204000054C3
+:10039000C304AB2DD91205071DB5C2048B2D010076
+:1003A0001C692501001CA67B950310CB2F09001C9E
+:1003B000602C00001C0000480300530F3254094613
+:1003C0007ACA051C7A0E32540940FA19001C000042
+:1003D000100304467ACA051CB50F315409A00F3129
+:1003E000540973EC2A0304602C00001C000028034D
+:1003F00000C71C01001C0000281305071D01001C7C
+:10040000C0D722001C75567E1304602C00001CE728
+:100410001C450304E79C00001CA67B950310802C60
+:1004200000001C0000F80204000054C304B97B0162
+:10043000001C00008CC304CBAFFC071CCB2F0104B5
+:100440001CC79F80031C00008CC304CBAFFC071C9F
+:10045000CB2F0D041CC79F80031C00008CC304CB52
+:10046000AF00F81DCB2F01001DA67B95031CC79C78
+:100470008CC30400008C1305071D01001CC01DDC8B
+:10048000D308279DE40300A0EE46D400FB750914B1
+:1004900004207B06001CC01C1C04000000B0D30814
+:1004A000000000F400C0EFF2001C20255C14046082
+:1004B000B7D2030000000C1500CCB3FC031CCC33F6
+:1004C00005021C00000CC50460B70E050400000CFA
+:1004D000150400005CC404C01D98F304000068C447
+:1004E00004079D00001C1B74FDF304A67BF1031C94
+:1004F000A00F695409E07B00FC1F397F02001C0734
+:100500001D9DC304A67BAD031C000068C404E01C51
+:1005100000001C0000A40304CBAF00F81DCB2F018A
+:10052000101D0000ACC3040000AC0304CBAF00F806
+:100530001DCB2F01181DC79F000B1C0000ACC3046E
+:10054000FB7501001C071D01001CCCB3FC031CCC77
+:100550003301021C0000ACC304A01C00001CA0EE70
+:10056000A20304CBAFFC071CCB2F09041CFB7501B5
+:10057000001C0000ACC304CCB3FC031CCC33010250
+:100580001C00000CC5040000783405CCB3FC031C2F
+:10059000CC3315021C479D54C404000078440080ED
+:1005A0001D7C5404871D8D0400CE7601001CEF765F
+:1005B0009DC404A4778D2409E47601001CC476014F
+:1005C000001C0000985404D776015018F6760100FC
+:1005D0001C00000030180000000010CC3045C5049D
+:1005E000EB2D01001CEA2901001CC05901001CF57B
+:1005F0007729C504E030DC0400004CB00400204C36
+:10060000F404000000E80400CCB3FC031CCC330964
+:10061000021CEB2DB5C404CCB3FC031CCC33190273
+:100620001CEB2DB5C404CCB3FC031CCC330D021C55
+:10063000EB2DB5C404CCB3FC031CCC3311021CEB72
+:100640002DB5C404007B00801CAE7745050000007A
+:1006500004C004D38B00FC1F607A3C001C604CC0BB
+:100660000400C02F20051FE030B004008025B00436
+:1006700000B55BB10404692601001C6A2B01001C53
+:10068000801D00001CA925450500EE3000001CAFB0
+:10069000770105000000AC2404B45F014018079DF9
+:1006A000485504B77601001C967601001C471D01D1
+:1006B000001CA433016018A42F0160186477016046
+:1006C000182477016018447701001C648803001C1B
+:1006D000A43F01001CA43B01001C537B00C01CD3A1
+:1006E000CF1B001C534F02001CDACF00C01FD55790
+:1006F0000F001CD3D337001CD4530F001CE029007B
+:10070000001CF5D5B0050000009C5504775601008B
+:100710001C565301001C0000001018000004C00407
+:10072000F55501001C0000B45504775601001C5615
+:100730005301001C0000001018000004C004CB2F5F
+:10074000011810CB2F011010CB2F010810CB2F0157
+:100750000810CB2F012010CB2F012810CB2F010028
+:1007600010892561C2040000ECC204000054C304D7
+:10077000000054C304000054C304000060C204001D
+:1007800000ECC204000054C304000054C304000081
+:1007900054C304401C6CC004401C9CC004A7775583
+:1007A000C3040000C4C004271DF1C004000054C3EA
+:1007B00004000054C304000054C30400002CC60409
+:1007C00000002CC60400002CC60400002CC6040047
+:1007D000002CC60400002CC60400002CC604000037
+:1007E0002CC60400002CC60400002CC60400002CFB
+:1007F000C60400002CC60400002CC60400002CC651
+:100800000400002CC60400002CC60400002CC60402
+:1008100000002CC60400002CC60400002CC60400F6
+:10082000002CC60400002CC60400002CC6040000E6
+:100830002CC60400002CC60400002CC60400002CAA
+:10084000C60400002CC60400002CC60400002CC600
+:100850000400002CC60400002CC60400002CC604B2
+:1008600000002CC60400002CC60400002CC60400A6
+:10087000002CC60400002CC60400002CC604000096
+:100880002CC60400002CC60400002CC60400002C5A
+:10089000C60400002CC60400002CC60400002CC6B0
+:1008A0000400002CC60400002CC60400002CC60462
+:1008B00000002CC60400002CC60400002CC6040056
+:1008C000002CC60400002CC60400002CC604000046
+:1008D0002CC60400002CC60400002CC60400002C0A
+:1008E000C60400002CC60400002CC60400002CC660
+:1008F0000400002CC60400002CC60400002CC60412
+:1009000000002CC60400002CC60400002CC6040005
+:10091000002CC60400002CC60400002CC6040000F5
+:100920002CC60400002CC60400002CC60400002CB9
+:10093000C60400002CC60400002CC60400002CC60F
+:100940000400002CC60400002CC60400002CC604C1
+:1009500000002CC60400002CC60400002CC60400B5
+:10096000002CC60400002CC60400002CC6040000A5
+:100970002CC60400002CC60400002CC60400002C69
+:10098000C60400002CC60400002CC60400002CC6BF
+:100990000400002CC60400002CC60400002CC60471
+:1009A00000002CC60400002CC60400002CC6040065
+:1009B000002CC60400002CC60400002CC604000055
+:1009C0002CC60400002CC60400002CC60400002C19
+:1009D000C60400002CC60400002CC60400002CC66F
+:1009E0000400002CC60400002CC60400002CC60421
+:1009F00000002CC60400002CC60400002CC6040015
+:040A0000002CC604FC
+:00000001FF
diff --git a/firmware/sxg/saharadbgdownloadB.sys.ihex b/firmware/sxg/saharadbgdownloadB.sys.ihex
new file mode 100644
index 0000000..e3016d3
--- /dev/null
+++ b/firmware/sxg/saharadbgdownloadB.sys.ihex
@@ -0,0 +1,3937 @@
+:1000000002000000DCF500000C0000000000000011
+:10001000FF1F00000100000000000088824D293A07
+:1000200000000404000000800200009000000900AD
+:100030000000008002000090000009000000008025
+:100040000200009000000900000000800200009003
+:10005000000009000000008002000090000009007C
+:1000600000000080020000900000090000000080F5
+:1000700002000090000009000000008002000090D3
+:10008000FEFF0000000000AC020036320000360027
+:10009000000000A80200009200001613000000807B
+:1000A0000200009000001613000000800200009083
+:1000B00000001613000000800200009000001613DC
+:1000C0000000008002000090000016130000008075
+:1000D0000200009000002000000000D80F8028924D
+:1000E00000002100000000D80F80289200002200AC
+:1000F000000000D80F80289200002300000000D8E4
+:100100000F402B9200002400000000D80F8028929E
+:1001100000002500000000D80F8028920000260073
+:10012000000000D80F80289200002700000000D8AF
+:100130000F80289200002800000000D80F8028922D
+:1001400000002900000000D80F80289200002A003B
+:10015000000000D80F8028920000360000000098B0
+:100160001E80E99A00002C00000000D80F80289221
+:1001700000002D00000000D80F80289200002E0003
+:10018000000000D80F80289200002F00000000D847
+:100190000F80289200003000000000D40F00009271
+:1001A00000003000000000D40F400092000030003A
+:1001B000000000D40F80009200003400000000D442
+:1001C0000FC0009200003000000000D40F00019228
+:1001D00000003000000000D40F4001920000300009
+:1001E000000000D40F80019200003000000000D415
+:1001F0000FC0019200003000000000D40F000292F6
+:1002000000003000000000D40F40029200003000D7
+:10021000000000D40F80029200001613000000803E
+:100220000200009000003000000000D40F00039294
+:1002300000003000000000D40F40039200003000A6
+:10024000000000D40F80039200003000000000D4B2
+:100250000FC0039200000000000000D05F3F003498
+:10026000000016130400008042FFFCB000000000F4
+:10027000000000881280FD3A000016130000008084
+:10028000020000901613161302010080828DFDBC3F
+:1002900000000000000000881280FD3A000000000D
+:1002A000000000F803C001323800000000010084A3
+:1002B000824D281A000036000000007409400092A8
+:1002C00000004F00000000FC020000920000480007
+:1002D000000000800200009000004D00000000902F
+:1002E0000E80189200001B030000000008C020923E
+:1002F000000089000000000008002192000019039E
+:10030000000000000840219200008600000000006C
+:100310000885219000009B03000000EC02C022929F
+:1003200000009404000000800200009000005800CB
+:10033000000000FC0240189D00005100000000D0A9
+:10034000020000920000E003000000800200009024
+:100350000000161300000080020000900000000062
+:10036000000100800200007000004C00000000004E
+:1003700009C0219200004A0012010000088522B045
+:1003800018003600000000F8738A029900008E0001
+:100390006A000080020000B008008E00000000F833
+:1003A0002340019900000000000100E80200907263
+:1003B0000000161380010080B200E9B600000204BC
+:1003C0000000007C1EC0E79A08000000000000F852
+:1003D000134001390000F60300000008B801009442
+:1003E000000016130300007809401ABD0000161320
+:1003F00004010080E28097BC00000000000000A023
+:10040000E125003408000000000000F8B340013985
+:1004100000000204B20000D8020000B2000016136F
+:1004200017010080020000B000001F06001001F854
+:1004300002006E9200005B000A0100CC020000B2D4
+:1004400000007000030100FC024019BD0800020416
+:10045000000000F8A34001990000000000000084A3
+:1004600001C02F320000000000000090F1010034B4
+:10047000000000000000009401C02F320000600066
+:10048000800100801281FCB6000016130401008078
+:1004900002C02FBC02006000B00000A0F20B00B947
+:1004A000000063000401008002C0B0BC00006E00C8
+:1004B000A000008002000090000065008001008024
+:1004C000F24BD0B600006E00A00000800200009049
+:1004D00000000000A0000004FD4BD03400006B00C1
+:1004E000800100801281FCB60000C211000000D81B
+:1004F000020000D20000161304000080028092BCAB
+:1005000018000000000000F8730A03396E0036007E
+:10051000000000C00200369200009611000000D8D2
+:10052000020000D20000161304000080028092BC7A
+:1005300018003600000000F8730A03F900005B00A1
+:10054000030100FC024018BD00008500030000FC10
+:10055000024019BD000000000000009401C02F32CD
+:100560000000000000000080F101003400000000E5
+:100570000000008401C02F3200007500800100805F
+:100580001281FCB6000016130401008002C02FBCCB
+:1005900002007500B00000A0F20B00B90000780066
+:1005A0000401008002C0B0BC00008300A0000080F5
+:1005B0000200009000007A0080010080F24BD0B66B
+:1005C00000008300A00000800200009000000000F6
+:1005D000A0000004FD4BD0340000800080010080AA
+:1005E0001281FCB60000C211000000D8020000D247
+:1005F0000000161304000080028092BC1800000066
+:10060000000000F8730A033983003600000000C0C0
+:100610000200369200009611000000D8020000D2BD
+:100620000000161304000080028092BC18003600FF
+:10063000000000F8730A03F900007000030100FCD9
+:10064000024019BD00005B00030100FC024018BD20
+:1006500008000204000000F8A3400199080000000F
+:10066000000000F87340013900008E008001008016
+:10067000E20180B600008B000000008002000090C4
+:10068000080091030C0000F8534001B900008D00F0
+:1006900080010080E20180B600001613120000689D
+:1006A000020580B00000F6030000006C1FC0F69A3F
+:1006B000000000000000000008058030000000007D
+:1006C000000000FC020001320000000000000010E9
+:1006D00008803D3200000000000000CC0200003223
+:1006E00000000000000000100900363200008012F7
+:1006F00000000014090080D2000016138000008062
+:1007000062802FB60000161302010080823A80BC7E
+:100710000000161306010080923A80BC0090161368
+:1007200004010080A20D80B000001613120100BC6D
+:1007300008C021B200000000000000D40200003216
+:1007400002A0000000000000A90D80320000161376
+:100750001200005402A438B2000200800000002CF5
+:100760000800373218003600000000F8730A03F959
+:100770000000000000080004088072320000A2009F
+:100780009F00005C080072B28300A100800100801D
+:1007900082CD85B00000B6000000002CD8C1829444
+:1007A0000000B6000000002C88C1829400001613DF
+:1007B00006010080827D80BC000FAC000401008037
+:1007C00082CD85B00000AC00800000803281FCB694
+:1007D0000000161312000068020580B0000000003F
+:1007E0000000006C1FC0F63A00000000000000FC92
+:1007F000020001320000AA00040100DC43603DB3A6
+:100800000000F603000000FC020000921800000047
+:10081000000000F8738A0339A7003600000000C00A
+:10082000020036920000AE0080010080F2C085B662
+:100830000000BE000000002C98C182941000C3008C
+:1008400087000000792116B80000C30080010078FD
+:10085000390090B08300C3008700007889CD85B04F
+:100860000000B30080000080028097B60000B60050
+:100870000000002C88C182940000B5008000008038
+:1008800022C185B60000B6000000002CD8C18294B9
+:100890000000C3000000002C98C182940000BC003E
+:1008A00080010080D2C182B60000C30080010080B8
+:1008B0007280FCB600000000001800A8423D7230B3
+:1008C00000000000541809FEF2C07C300000EA006D
+:1008D00080010080F2C185B60000C50000000080E4
+:1008E00002000090000016138001008082C182B6D1
+:1008F0000000B800800000808280FCB60900C300C0
+:10090000040000B428BF17B88300C500870000ACFE
+:1009100088CD85B00000C30004000080D2E28AB018
+:1009200000000000001800A8423D72300000C50021
+:10093000541809FEF2C07C9000000000540000FC36
+:100940000200003200000000001800200700003202
+:100950008000802000000080C2CD85300000DA00D9
+:100960000B000080020000B01800000000000078BA
+:1009700079A116382000EA0004000080828D97BC1F
+:100980000000D100800100806280FCB68300D100AD
+:100990008700007889CD85B00000CD008000008000
+:1009A000028097B60000D10080010080128097B6C7
+:1009B0000000D1008001008072C185B610000000E7
+:1009C00000000078796116380000D800040100802A
+:1009D000328097BC0000EA000000002CB8C182946D
+:1009E0000000D800800100805280FCB60000D800D2
+:1009F0008000008072C185B60000D80080010080B0
+:100A000002C185B60000D80080010080D2C185B641
+:100A1000180000000000007879E116380000D800C6
+:100A200004010080328097BC0000EA000000002C26
+:100A3000C8C18294000000000000000408000432D5
+:100A40000000EA000000002CA8C182940800000009
+:100A500000000078792117380000EA0004000080C7
+:100A6000328097BC0000EA0004010080228097BC1D
+:100A70001F0000000012000889CD72300500000040
+:100A800000120000B9DC173800000000000000A8C8
+:100A9000220090370000EA008000868022247CB685
+:100AA00000000000000000780905803000001613E7
+:100AB0000201008082BA97BC000016130601008074
+:100AC00092BA97BC0000161312000068020580B0AD
+:100AD00000000000000000FC020001320000E800FD
+:100AE000040100DC43603DB30000F603000000FC9D
+:100AF0000200009218000000000000F8738A033919
+:100B0000E5003600000000C002003692020000003E
+:100B100000000010090036320000801200000014AE
+:100B2000090080D20000F10012010060084023B2E9
+:100B30003200000000000010090036320000801270
+:100B400000000014090080D20082000000000008AC
+:100B5000088036320000E100000000641F40F69A71
+:100B60000000161312000024080023B20000161320
+:100B70001200002008C023B2000016131200001853
+:100B8000088023B200000000000000FC02000132D7
+:100B90000000F800040000DC43603DB318000000D2
+:100BA000000000F8738A0339F4003600000000C02A
+:100BB0000200369200000000000000FC02008532B6
+:100BC00000000000000000D8028001320000000098
+:100BD000000000D00200003200C007011801000C24
+:100BE000A8CD3EB20000F80012000038028081B2A9
+:100BF000000000000000003C020082320000000003
+:100C0000000000300240823200000000000000348A
+:100C10000200863220800000000000080880363282
+:100C2000000000000000005C1FC0F53A000000005A
+:100C300000000078090580300000161302010080D2
+:100C400082BA97BC000016130601008092BA97BCC6
+:100C50000000F60312010068020580B000001613C0
+:100C600000000080020000900000000000180078E2
+:100C70000900723200230A0104010080A2CD82B073
+:100C800000000B0100000000090000920000161394
+:100C90009F16000029C172BC00000000001800006F
+:100CA000078081320000000000200000070082322F
+:100CB00000000000002800000780973210000000AC
+:100CC00000300000172090390000000000380000BC
+:100CD00007C0823200000000000000D8020000328D
+:100CE00000000000000000000740803200001401F6
+:100CF00080010080A2C182B600001501000800003A
+:100D000057008097050000000008000007A0043984
+:100D10000000161304100000074082B2000000001B
+:100D20000018000007008632000016131200005061
+:100D3000F2C138B418003600000000F8730A03F955
+:100D40000000161312000068020580B000000000C9
+:100D500000000078090580300000161302010080B1
+:100D600082BA97BC000016130601008092BA97BCA5
+:100D7000000016131200004802C080B20000F60303
+:100D8000CA010008E8818094000000000000008093
+:100D9000024590300000161304010080120028BCA8
+:100DA00000001613120100BC08C021B208000000A8
+:100DB000000000F89340013910000000540000FCCE
+:100DC000824D9036000016130200008042C02FBCF6
+:100DD00000002501F00100D8020000B20000000070
+:100DE000620401A802C06E3200000000000401008D
+:100DF00059C06E37000000000004017819C06E3A37
+:100E0000000000004E0401EC06BD97300000000019
+:100E1000E00000F41E40EF3A0000161304190B82A4
+:100E200002C07CBC0000000000180BCE074000325E
+:100E30000000000000000000074009320000161307
+:100E400004010080020036BC000000000008000021
+:100E500077C029370000161304100000173D90BA20
+:100E600000000000001800000780F4320000161394
+:100E700012000040F2C138B40B0000000000001066
+:100E8000090036320000801200000014098083D26D
+:100E900000000000000000FC32C02F300000000005
+:100EA0000000001008803D3218003600000000F8F5
+:100EB000730A03F900000000000000D402000032B1
+:100EC000000016130401008002802DBC0000CE013A
+:100ED0008038008022C072B600003E01120000C8B7
+:100EE000020020B2000045011201005C088020B21F
+:100EF000000016131200006002802CB218000000DF
+:100F0000000000F8738A03393B013600000000C07E
+:100F10000200369200000000000000F81F80FF3A37
+:100F200000000000000000FC320085300000A3013A
+:100F30000400008042603DB318000000000000F88B
+:100F4000738A033941013600000000C00200369266
+:100F5000080000000000000088CD85370000000078
+:100F60000000002008007232000000000008002489
+:100F700008007232000016130410006C080072B2F0
+:100F8000000000000018004C080072320000161328
+:100F900004200018080072B2000000000030002891
+:100FA00008007232000016130200008082BD82BC6D
+:100FB000000000000028003008007232000000002D
+:100FC00000000060088082320000560106000080A8
+:100FD00062A082BC000016139F3C0014288072BCE3
+:100FE00000000000000000000700063207000000BB
+:100FF00000080000774A09390000161304100000A9
+:10100000070082B200000000CA19000007408232C7
+:101010000000161312000040F2C138B400000000B6
+:10102000000000D80240003200007D010438007842
+:10103000D9C572B000005A0180010080028097B6C5
+:1010400000000000000000F882802F3400005C01E6
+:1010500080010080128097B600000000000000F8B8
+:1010600092802F34000016130401008002402DBC32
+:10107000040000000038003CB81C173800000000D5
+:101080000000003C28C0833700000000003A002C1C
+:1010900008C07232000000000000001CB8E0833A73
+:1010A00000000000CB2900200700003200007C0176
+:1010B0000400008002C081BC000000000000003479
+:1010C00078A0813E000000000000001CD8E0813CB8
+:1010D00000006A01063A0080B25C83BC0000000098
+:1010E000003A000089C17237070069012B01000432
+:1010F000790A04B900000000CB00000419419034C3
+:1011000000006D01003A002C070000920000000072
+:10111000003A002CD7E0723C000000000000000004
+:101120000900003200000000000000040900003245
+:10113000000000000000000007648332000000008F
+:1011400000080000070080320000161304100000A1
+:1011500007C086B2000000000018000007C08432FB
+:1011600000008C0104000028D8A082BC00001613E7
+:1011700009010080020000B0000000000000000033
+:10118000D820803A000077010400008072802DBCD6
+:10119000000016131200004412E438B20000780177
+:1011A000000000D812802D9A000075120000000483
+:1011B000F94190F400007A0104000018D8A081BC25
+:1011C000000062010000006CD8E0869A0000201246
+:1011D0000000004408802DF2000062010000003091
+:1011E0000800009200000000CB1900200700003228
+:1011F00007007F012B010004790A02B900000000FA
+:10120000CB00000419419034000000004D000000A4
+:10121000A7A0813E00000000000800000700803207
+:10122000000016130410000007C086B20000000082
+:101230000018000007C0843200008C010400002860
+:10124000D8A082BC0000161304010080626083BC39
+:101250000000000000000000D820803A0000890152
+:101260000400008072802DBC0000161312000044A0
+:1012700012E438B200008A01000000D812802D9AD2
+:101280000000751200000004F94190F400002012E3
+:101290000000004408802DF200007D0100000030B5
+:1012A000080000920000161380000080A2802FB674
+:1012B0000000000000000004F94190340000161303
+:1012C0001200004412E438B218003600000000F8A2
+:1012D000730A03F9000016130400008002802DBC7D
+:1012E00000000000001800040980733200000000B4
+:1012F000002800088980733700000000000000808B
+:1013000007008632410000000006008C07003632DC
+:10131000000098012908008007C085B200009B01E9
+:101320002810008C070000B200009C01001200840D
+:1013300007000092000000000010008CF7E0823AE5
+:1013400000009B0128180080074090B200009C011B
+:1013500000120084070000920000000000120084C8
+:1013600027E4823200000000000000783900853058
+:101370000000161304010080F28B97BC0000A1014D
+:101380000400008042603DB318000000000000F837
+:10139000738A03399C013600000000C002003692B7
+:1013A00000000000000000FC02008532000016135F
+:1013B0001200005C52812CB400000000000000D834
+:1013C00002800132000000000000008002003B3279
+:1013D0000840A501F0010008088036B200000000B6
+:1013E0000004013808C06E3200000000E00000F484
+:1013F0001E40EF3C0000AC010B01008C080000B265
+:101400000000A901F2010080020000B0000000000D
+:10141000000000F00E003A320000BE01E200008041
+:101420000E8083920000AC01F2010078C93B3ABC07
+:101430000000B60102010080828097BC000000001D
+:10144000000000A80200E8320000B10104000080A2
+:1014500022A22ABC0000B50104190B8202C07CBC88
+:10146000000000000000008C18C0883A0000000056
+:10147000000000A812802A3A00000000000000A826
+:1014800002BD2A300000AF0104010080E2A02ABCA6
+:101490000000BB010200008082C088BC0000000088
+:1014A000E20000080800003200000000000000A870
+:1014B000028088320000161304190B8212C07CBC13
+:1014C0000000000000180BCE070000320000F603F9
+:1014D000000000DC03000092000000000000003863
+:1014E00008802A3200000000000000F00E003A32AE
+:1014F00000000000E20000800E802A3200000000A0
+:10150000000000A8028088320000161304190B8224
+:1015100012C07CBC0000000000180BCE0700003297
+:1015200000000000000000DC030000320000161381
+:1015300004000080227AE8BA0000000000000000E9
+:1015400007808332000000000000000079C02937C6
+:101550006020000000000000890D903A00000000AB
+:10156000CA0100D812802D3A0000000000000000DF
+:101570000700013200000000000800000700903260
+:1015800000000000001000000740E83200000000EA
+:10159000001800000780E83200000000000000FC96
+:1015A000020000320000F60312010048F2C138B414
+:1015B00000001613000000800200009000001613C7
+:1015C0000401008002402DBC0000161304010080BD
+:1015D00002802DBC000016138000008072802FB6A0
+:1015E0000000000000300078088072320400000023
+:1015F00000380054A85C16380B0000000038002C9E
+:10160000A8DC1638140000000000001C884D853A44
+:101610002200000000000010090036321000801285
+:1016200000380014A99C87D90000000000000020A9
+:101630000800723200000000000800240800723226
+:10164000000000000010006C080072320000000072
+:101650000018004C08007232000016130420001815
+:10166000080072B20000000000280030080072324A
+:10167000000016139F3C0014188072BC0000E501A6
+:1016800004000080024081BC000000000000001443
+:101690001840813C000000000000000007000632F6
+:1016A0000700000000080000774A093900001613FF
+:1016B00004100000070082B200000000CA190000F8
+:1016C000074082320000161312000040F2C138B405
+:1016D00000000000000000D80240003200000000BE
+:1016E0000000006478C02937021000000000006488
+:1016F000884D863A0000000000000080080000329B
+:10170000000000000000004008000032000000005F
+:101710004D00000077A0813E00000000000800009E
+:1017200007408632000016130410000007C086B27E
+:10173000000000000018000007C084320000000212
+:101740000400001CD8E081BC0000161309010080D1
+:10175000020000B00000000000000064D860863A7B
+:101760000000F4010400008072802DBC00001613FC
+:101770001200004002C038B20000FC01000000D896
+:1017800012802D9A0000161312000040F2C138B4E6
+:1017900018003600000000F8730A03F90000FA018F
+:1017A0000401008002802DBC00001613800100801F
+:1017B000A2802FB60000F501670000F8A2802FB5C7
+:1017C00000001613120000E802C021B20000161338
+:1017D0000401008072802DBC00000000000000D8D1
+:1017E000024000320000FE0104000018D8A081BCB5
+:1017F0000000EA010000006CD8E0869A0000C910E1
+:101800000000004408802DF20000EA0100000030D2
+:10181000080000920000161312000040F2C138B414
+:1018200018003600000000F8730A03F900000602F1
+:101830000401008002802DBC00001613800100808E
+:10184000A2802FB600000102670000F8A2802FB529
+:1018500000001613120000E802C021B200001202BC
+:1018600004010080020084BC00000000000000D4DD
+:101870000240003200000000000000A42240853A2F
+:10188000040000000018004088CD743600000000FD
+:10189000000000402800843700000000000000D451
+:1018A00002000032140012020400001C880D84BCE7
+:1018B0000000161309010080020000B000000000C3
+:1018C000000000780961853A800016130601008047
+:1018D000828D97BC0000000000000064D860863A4A
+:1018E0000000FC01000000D8024000920000140239
+:1018F00004000018D8A081BC000016020000006C93
+:10190000D8E0869A0000C9100000004408802DF23B
+:10191000000000000000003008000032000000005D
+:10192000000000D40240003200000000000000A4CB
+:1019300022C0823A000000000000003CB860853CF4
+:1019400004001C028100006088CD74B60000000015
+:1019500000040028F8A0753C00001D020008007477
+:10196000088075920000000000080028F8A0753C6F
+:10197000000000000000002808A1823C00000000D8
+:10198000000000A4F2602A3A0000000000080048AD
+:1019900008007532000000000020007C08807532CD
+:1019A00009002302041A007088CD74B009000000F9
+:1019B000001A004C87CD74317F00000000000064E5
+:1019C000884D863100000000000000642840863AFF
+:1019D00023000000000000100900363200008012D1
+:1019E00000000014098082D20C00000000000010EA
+:1019F000090036320000801200000014098084D2F1
+:101A000000000000000000D802400032000000008A
+:101A1000001000000740863200000000000000D8DF
+:101A20000280003200000000001000005761863A7A
+:101A300000003002120000C8020020B20000330291
+:101A40001201005C088020B2000016131200006032
+:101A500002802CB2000040012A0100D4020000B232
+:101A600018003600CA0000F8730A03F900004101AB
+:101A7000000000F81F80FF9A00000000000000D462
+:101A800002400032080000000000000088CD8537C9
+:101A9000000000000000001CE8A1823E00000000E1
+:101AA000000000A42240853A000000000008005019
+:101AB0000780843200003A020401008072A082BCD8
+:101AC00000000000001A004CC7E174320000000062
+:101AD0000000006808E1813A00003D0290010078B2
+:101AE000F9A186BA00000000000000781980973A3A
+:101AF000000000000020005807809732000000001E
+:101B0000000000D802800032000000000000000049
+:101B10000700843200000000400800005721803A8E
+:101B2000000041021200004CF2C138B40000000075
+:101B3000000000000821803A0000000000000004BE
+:101B400008C0813200000000510000D802C00032FD
+:101B500000000000000000D402000032000000007D
+:101B6000CB1900200700003200001613020100808C
+:101B700032802DBC07004A022B010084780A02B98A
+:101B800000000000CB0000841841883400000000F1
+:101B90004D00000077A0813E00000000000800001A
+:101BA00007008032000016130410000007C086B240
+:101BB000000000000018000007C084320000161367
+:101BC0009F000028D8A082BC000068020400001C0E
+:101BD000D8E081BC0000161304010080626083BC61
+:101BE000000059022D000000D82080BA00005402E5
+:101BF000120100E802C021B218003600000000F80F
+:101C0000730A03F9000056020401008022802DBCF3
+:101C100000005902CD0100D8024084920000161342
+:101C20000401008002802DBC00001613800100809A
+:101C3000A2802FB600005302000000F8A2802F956A
+:101C400000005C020400008072802DBC00001613AE
+:101C50001200004412E238B200006602000000D810
+:101C600012802D9A0000000000000084F8418834A2
+:101C7000000016131200004412E238B218003600B9
+:101C8000000000F8730A03F90000640206010080F6
+:101C900022802DBC000016130401008002802DBCA0
+:101CA0000000161380010080A2802FB600005E02A3
+:101CB000670000F8A2802FB500005F02000000E876
+:101CC00002C02192000016130401008072802DBC16
+:101CD00000000000000000D802C000320000C9105F
+:101CE0000000004408802DF2000047020000003090
+:101CF000080000920000700280000080D2802FB6A1
+:101D000000006B02120100E802C021B21800360088
+:101D1000000000F8730A03F900006D02040100805E
+:101D200022802DBC00007002000000D80240849286
+:101D3000000016130401008002802DBC0000161361
+:101D400080010080A2802FB600006A02000000F827
+:101D5000A2802F9500000000CD000084F841883457
+:101D6000000016131200004412E238B20000000016
+:101D7000000000D40240003200000000000000A477
+:101D800022C0823A0000790204010080420086BC31
+:101D90000000000000080058074087320000780269
+:101DA0008F010074184087BA000000000000007422
+:101DB0000800003200007B0200040058F7A0869A59
+:101DC0000000000000000078F9A0863A280000001A
+:101DD00000080058878D973C00000000000000D8E4
+:101DE000024000321800000000000000B760853992
+:101DF000080000000008000087CD853700007E0243
+:101E00001200004CF2C138B400000000000000488D
+:101E100018A0843A00000000000000D40200003244
+:101E2000000000000000008057A1863A4100000039
+:101E30000006008C07003632000000000008008019
+:101E400007C08532000000000010008C074085327A
+:101E500000000000000000D80280003200001613CD
+:101E600004000058088071B20000000000000080EB
+:101E70000880003218003600000000F8730A03F9E9
+:101E800000008C020401008002802DBC00001613AB
+:101E900080010080A2802FB600008802000000F8B8
+:101EA000A2802F950000880204010080180088BCE1
+:101EB00000008F0290190058E89C85BA00000000CD
+:101EC000000000581880853A0000000000180080CB
+:101ED000078585300000940204010080420086BC22
+:101EE00000000000000000D80240003200000000A6
+:101EF00000000008898071370000950200120084FC
+:101F000027E48292000000000012008407000032E3
+:101F100000009902270000FC020085B2000099022F
+:101F20000400008042603DB318000000000000F88B
+:101F3000738A033995023600000000C00200369211
+:101F4000000016131200005C52812CB400009D02A8
+:101F500004010080028082BC000016138000008013
+:101F6000A2802FB60000A301000000D4020000925E
+:101F70000000A00204010018D8A081BC0000C91014
+:101F80000000004408802DF200002D02C70100303F
+:101F90000800009200002D02C701006CD8E0869A6C
+:101FA00008000000C60100F8934001391900000044
+:101FB00000000010090036320000801200000014FA
+:101FC000094081D200000000000000140845813063
+:101FD00000001613120100BC08C021B20000161345
+:101FE00080000080A2802FB60000F6038001808070
+:101FF000320B6AB600006A100000003C030038F2A1
+:102000000000AC020406018002C06EBC0000161382
+:10201000870601EC56E06EBA0000F3030000008072
+:102020000200009000001613870601EC56E06EBA1D
+:1020300000000000000000F842802F3408C0161392
+:1020400012000040A2CD39B218003600000000F89E
+:10205000730A03F90000161303B8000009C06EBD2F
+:10206000B202000000000088820D903A2F005E0648
+:102070000000001C080036920000161300000080CB
+:10208000020000902C005E060000001C0800369242
+:1020900000001613000000800200009000001613DC
+:1020A0000000008002000090000016130000008075
+:1020B0000200009038005E060000001C0800369206
+:1020C00039005E060000001C08003692080000007F
+:1020D000000000F89340013900001613120100BC03
+:1020E00008C021B20000161380000080A2802FB625
+:1020F0000000161380008080320B6AB600006A1060
+:102100000000003C030038F20000C102040000801F
+:10211000524082BC0000161304010080624082BC61
+:10212000000016130405018002C06EBC0000000010
+:10213000000000F842802F3408C01613120000403F
+:10214000A2CD39B218003600000000F8730A03F976
+:10215000000000000004017809C06E320000000099
+:10216000006201EC068097320900000000000010B8
+:1021700009003632000080120004011409C06ED23A
+:102180000200CB0204B8008082CD6EBC080016139A
+:1021900004B9008082CD6EBC00000000000601EC96
+:1021A000064000320000CC02B50000D8020000B2A8
+:1021B00000000000A50080A0360B6A34000000007B
+:1021C000003002E806C02C320000000000000000D1
+:1021D000078000320000000000000078A9002D37C1
+:1021E0001805010000080000C78D973A00000000A4
+:1021F0000000007899C02C3718010000000000781A
+:10220000898D973A000016130210000087BF97BA15
+:1022100000000000001800000740FE320000161306
+:1022200012000048F2C138B418003600000000F86F
+:10223000730A03F900000000001801E006000032F4
+:1022400000000000000000F882852F3000006806C2
+:102250000000001C0800369208000000000000F892
+:102260009340013900001613120100BC08C021B2CE
+:102270000000161380000080A2802FB660001613A5
+:10228000040100F8828D2FB007000000000000104C
+:10229000090036320000801200000014094081D28B
+:1022A0000000E50280008080320B6AB61700000053
+:1022B00000000010090036320000801200380014BF
+:1022C00009C06ED20000F6030000008002000090FA
+:1022D00000006A1000000038030038F20000E80235
+:1022E0000402018002C06EBC0000F303000201EC96
+:1022F00056E06E9A00000000C00301EC56E06E3A12
+:10230000000016138001008002802FB600C0161353
+:1023100012000040A28D39B218003600000000F80B
+:10232000730A03F9200016130439008082CD6EBCB5
+:102330001200000000000010090036320000801278
+:102340000030001409006ED21500000000000010DB
+:1023500009003632180000000002011489CD6E37E2
+:102360000000801200200114895B91D21B00F4024E
+:1023700038010010090036B200008012003001144C
+:1023800009006ED21800000000000010090036326B
+:102390000800000000000014790B143810008012AF
+:1023A00000500114A95B91D90000F902042801141E
+:1023B00009006EB21C00801200000010090036D225
+:1023C000000005033828001809006EB20000FD0265
+:1023D0000421010869246EBC000016130901008065
+:1023E000020000B0030068060000001C08003692DE
+:1023F0000000010302300080829B90BC00000003BB
+:102400000603018012C06EBC040068060000001CB8
+:1024100008003692050068060000001C080036928D
+:10242000000016130430008002006EB200000403A6
+:102430000603018012C06EBC0B0068060000001C81
+:10244000080036920C0068060000001C0800369256
+:10245000000008030421010869246EBC0000161363
+:1024600009010080020000B0030068060000001CA3
+:102470000800369200000C0302300080829B90BC62
+:1024800000000B030603018012C06EBC0400680646
+:102490000000001C08003692050068060000001CC1
+:1024A0000800369200000E039F31010C69246EBCB7
+:1024B000000000000000000C0900003200001203C0
+:1024C00004310004899B90BC0000110306030180C5
+:1024D00012C06EBC200068060000001C0800369286
+:1024E000210068060000001C080036920000161348
+:1024F0009F000080024090B200001503040201809A
+:1025000012C06EBC220068060000001C0800369253
+:10251000000017030401000039A490BC23006806E2
+:102520000000001C08003692000016139F00008077
+:10253000020090B2240068060000001C08003692D9
+:10254000080016130C0000F8634001B910001D03C9
+:10255000C50100CC02201598080091030C0000F87A
+:10256000434001B910000000C50100CC022015381D
+:102570000000000000000010090036320000801248
+:1025800000000014090080D200001613120100BCE4
+:1025900008C021B200006A100000003C030038F2BD
+:1025A000000000000000005C0805803000001613E9
+:1025B0000401008002402DBC0000161302010080BF
+:1025C00082FA85BC000016130601008092FA85BCD1
+:1025D0000000270336010080020000B00F006806EB
+:1025E0000000001C0800369210000000002C0200C1
+:1025F000A9DB8539000016131200005402A438B27A
+:10260000000000000008028C08C06E3200000000CC
+:10261000000C029828806E37000000000000009C2B
+:1026200038221437000032030430002808006EB24C
+:10263000000016130410006C08006EB200000000C9
+:102640000018004C08006E32000016130420001819
+:1026500008006EB200000000003C001408806E32DA
+:10266000050035030038020078E16E990000000093
+:10267000510000D80200003200000000003802784B
+:1026800009C06E32050000006808000077A1973984
+:10269000000037031201000009C021B21800360003
+:1026A000000000F8730A03F900000000545401FC14
+:1026B00002C06E3214103B0304000080A20D72B001
+:1026C0000000F3110000002809C002F20E006806A5
+:1026D0000000001C08003692000016130609008056
+:1026E00082BD72BC00004F03331500A402C072B259
+:1026F00000008C0380010080B20172B60101420328
+:1027000004290080828D74BC080A8C03042D00808B
+:10271000828D74BC000000000030007C080075321F
+:1027200000004903003800881800759C080A8C03D3
+:1027300004290080828D74BC10000000002C007CF5
+:10274000888D7537000000000030007C68DD87321E
+:10275000000048039F390088188075BC10000000F5
+:1027600000340088888D7537000049030000008818
+:102770001880889C1000000000340088689D88390B
+:1027800037000000000000100900363200008012FF
+:102790000000001409C087D23B00000000000010B8
+:1027A000090036320000801200000014098088D22F
+:1027B000000050039FF1018082DB87BC00008C0386
+:1027C000000000800200009000008C038000008068
+:1027D000B20172B60000000000080048080075321F
+:1027E00000000000001000700800753200000000BA
+:1027F000001C007438A2753700005503831B007855
+:1028000008C074B200000000000000F8C2802F343D
+:102810002F00000000000010090036320000801276
+:1028200000000014098084D2340000000000001071
+:10283000090036320000801200000014090087D21F
+:1028400000006B039F780180C2216EBC00005D0315
+:102850009F990164881B87BC00006C039F6801641A
+:10286000885B86BA000000000000006408000032A7
+:1028700000000000001600A402C072320000000038
+:10288000003C02A4B25B2A3A00000000003A027841
+:1028900009C06E3200006D0308010004E8A575BC94
+:1028A0003F000000000000100900363210008012C6
+:1028B00000040014695D80D910008C030B01001C1A
+:1028C000080036B200006B0304A10180829B84BC27
+:1028D000000068069F980180C2216EBC0000680657
+:1028E00006B10180825B87BC00008B030B01008076
+:1028F000020000B000006C0304990180C2216EBC8C
+:102900000000890302D4018092FB6EBC16006806A9
+:102910000000001C08003692170068060000001C2A
+:10292000080036921C0068060000001C0800369261
+:102930003F00000000000010090036321000801235
+:1029400000040014695D80D90000710304A10180B6
+:10295000829B84BC0000780306A80180825B80BC57
+:102960000000750304A9018002006EBC00008A0308
+:1029700004A10180829B84BC00008A0304010080C2
+:10298000124080BC140068060000001C080036924B
+:1029900000008A039FA0017829216EBC00008A03F1
+:1029A0000201008012A097BC00006B0300000080B1
+:1029B000020000900000850304000080028082BCB9
+:1029C000000016130402018002C06EBC00007E03EA
+:1029D00002000080A26080BC060068062C01001C7A
+:1029E000080036B200C0820304010080A28D2FB01F
+:1029F000060068060000001C0800369200008203F2
+:102A000004000080A26080BC0000810306030180F6
+:102A100012C06EBC090068060000001C0800369257
+:102A20000A0068060000001C0800369200008403BB
+:102A30000603018012C06EBC070068060000001C7F
+:102A400008003692080068060000001C0800369254
+:102A5000020068063801001C080036B20000880336
+:102A6000020C0280A25B80BC1F0068060000001CF4
+:102A7000080036921E0068060000001C080036920E
+:102A800000008D03000000280940009200008D0323
+:102A9000000000280980009200008D03000000283B
+:102AA00009C0009200008D03000000280900019277
+:102AB00030000000000000100900363200008012D3
+:102AC00000000014098092D20E00F3110000001CD7
+:102AD000080036F200006806000000800200009046
+:102AE000100016132A0000CC022015B80D000000BB
+:102AF00000000010090036320000801200000014AF
+:102B0000090080D200001613120100BC08C021B2D7
+:102B100000006A100000003C030038F21D00990319
+:102B20008001007809E000B800001613040100805D
+:102B3000328097BC1D0068060000001C0800369219
+:102B40000000161304010080228097BC150068065F
+:102B50000000001C08003692000000000000001C6D
+:102B6000A8052830000016130400008002C02CBC09
+:102B700000001613120100BC08C021B20000161399
+:102B800080000080A2802FB660001613040100F8B8
+:102B9000828D2FB008000000000000F8834001394A
+:102BA0003600A4030400008082CD81BC0500000033
+:102BB00000000010090036320000801200000014EE
+:102BC00009C081D20000020480018080320B6AB605
+:102BD00000006A1000000038030038F22C0068067C
+:102BE0000201008082CD81BC00005E0600000080F2
+:102BF0000200009000001613120100BC08C021B2B0
+:102C00000000AB031D41025CF80168B44100F3030E
+:102C1000000000F8A28D2F91350000000000001088
+:102C200009003632000080120000001409C085D26D
+:102C300010000000D02C0200A9DB85390000290318
+:102C40001201005402A438B20000161300000080E4
+:102C5000020000900000B40304B0008002006EBCCB
+:102C60000000B40380B9008082806EB600000013BB
+:102C70000078016008006EF230005E06D700001C8C
+:102C8000080036920000B60380010080D2812FB682
+:102C900031005E06D700001C080036920000B80321
+:102CA0008001008042812FB635005E06D700001CEF
+:102CB000080036920000C50304A8010809006EB29E
+:102CC0000000000000200208899B903E00000000E8
+:102CD00000A00108899B903A0000C5039F88010865
+:102CE000899B90BC000000000034020009C06E3DCA
+:102CF00000000000000C020409A46E370000C103AC
+:102D00000200008012A490BC000000000000000837
+:102D1000198090370000C50302010280829B90BC9D
+:102D200031005E06D700001C080036920000C50383
+:102D300004B0008002006EBC0012C50304010080D4
+:102D4000A28D2FB032005E06D700001C080036921C
+:102D50000000F303000000F872812F9500000000CE
+:102D6000000000F842802F3408C0AF02120100407A
+:102D7000A2CD39B2000016130000008002000090BE
+:102D800008000000000000F893400139080000002E
+:102D9000000000100900363200008012000000140C
+:102DA00009C081D2000016130400008002C02CBCB0
+:102DB0000000161380000080A2802FB6600016135A
+:102DC000040100F8828D2FB0000002048001808091
+:102DD000320B6AB600000000000000140840903278
+:102DE00000006A1000000038030038F22C0068066A
+:102DF0000201008082CD81BC00005E0600000080E0
+:102E00000200009008000000000000F89340013923
+:102E10000800000000000010090036321000801287
+:102E200000000014894D81D70000161304000080B3
+:102E300002C02CBC0000161380000080A2802FB6B8
+:102E400060001613040100F8828D2FB00000020408
+:102E500080018080320B6AB600006A1000000038E2
+:102E6000030038F20000DF030420018052206EBC12
+:102E70000000161309010080020000B02600680659
+:102E80000000001C08003692250068060000001CA7
+:102E9000080036920000E503040100D81E80EDBC56
+:102EA0000000E103B70000D80EC0EDB20000E4035B
+:102EB00004010080423BEEBC00000000000000E086
+:102EC0001E00EE3A00000000A70000D00E00EE3217
+:102ED00000000000007486CC02806C32000000000C
+:102EE000000000000940E7320000E9038001808013
+:102EF000320B6AB6360016131200002C82CD2EB2A9
+:102F00000000EB030401008042C52CBC0000EC0370
+:102F1000000000CC0200009200000000000000CC85
+:102F200012C02C3A0000E70304010000190090BC15
+:102F300000000000007486C806C02C32080002049D
+:102F4000000000F8C34001990000F1030400008074
+:102F5000028080BC0000161304550180B2DB2FBC38
+:102F6000000054100000002C090000F20000F603DD
+:102F700000000080020000900000F50304000080C3
+:102F8000028080BC0000161304550180B2DB2FBC08
+:102F9000000054100000002CF90100F40000FF03B1
+:102FA00004000028098080B200000000000000D862
+:102FB000020000320000811100000008080000D269
+:102FC0000000FF0304000080028092BC180036005D
+:102FD000000000F8730A03F9000002048001008079
+:102FE000A2802FB6000002041201000009C021B225
+:102FF00018000000000000F8730A033902043600CC
+:10300000000000C00200369200000204800100802F
+:10301000A2802FB6000002041201000009C021B2F4
+:1030200018003600000000F8730A03F900000000E1
+:10303000000000F80200003218003600000000F81E
+:10304000738A029910000000000000E40300363289
+:1030500002000001000000E0030037320000000021
+:10306000000000E40300363204000001000000E02C
+:1030700003003732AA040000000000E403003632E7
+:1030800009000001000000E00300373200000000EA
+:10309000000000CC0F00003200070000000000E438
+:1030A0000300363206000001000000E00300373262
+:1030B00020000000000000E4030036320800000198
+:1030C000000000E00300373200010000000000E4CF
+:1030D0000300363205000001000000E00300373233
+:1030E00030000000000000E4030036320700000159
+:1030F000000000E00300373200A00000000000E400
+:103100000300363208000008000000E003003732F8
+:1031100000000000000000A00200003200000000DB
+:10312000000000000B000032000016048B0100A01C
+:1031300012002ABA00000000000000A802000032BD
+:1031400000000000000000E0070000320000190449
+:103150000601008002802ABC000000000000009CE4
+:103160000200003200000000000000D40200003223
+:1031700000000000000000CC02000032000000004F
+:10318000000000D80200003200000000000000D063
+:103190000200003200000000000000DC02000032EB
+:1031A00000000000000000F80200003200000000F3
+:1031B000000000C80200003200000000000000C44F
+:1031C0000200003200001C048501009C12C029BAD4
+:1031D00000000000000000E4030036320B00000491
+:1031E000000000E00300373280000000000000E42F
+:1031F0000300363213000004000000E00300373201
+:1032000000200000000000E4030036320C0000043F
+:10321000000000E00300373200000000000000E47E
+:10322000030006320F000004000000E00300373204
+:1032300000040100000000E4030037320D00000428
+:10324000000000E00300373200040000000000E44A
+:103250000300363214000004000000E0030037329F
+:103260009F000000000000E4030036321500000457
+:10327000000000E00300373200000000000000E41E
+:103280000300363218000004000000E0030037326B
+:1032900060000000000000E4030036321D0000045E
+:1032A000000000E00300373200000000000000E4EE
+:1032B000030004321E000004000000E00300373267
+:1032C00070000000000000E4030036321F0000041C
+:1032D000000000E00300373200000000000000E4BE
+:1032E0000300003220000004000000E00300373239
+:1032F000A0030000000000E40300363217000004C1
+:10330000000000E00300373240000000000000E44D
+:10331000030036321B000004000000E003003732D7
+:1033200060000000000000E4030036321C000004CE
+:10333000000000E00300373200000000000000E45D
+:103340000340003216000004000000E003003732A2
+:1033500000010000000000E4030036321A000004FF
+:10336000000000E00300373220010000000000E40C
+:103370000300363219000004000000E00300373279
+:1033800080000000000000E4030036320B00000162
+:10339000000000E00300373200010000000000E4FC
+:1033A000030036320C000001000000E00300373259
+:1033B000FEFF0000000000AC0200363200000000FA
+:1033C000000000000900003218000000000000F8B2
+:1033D0000364023900004F0485010000190090BA0F
+:1033E00025260000000000E4030036320100000141
+:1033F000000000E003003732000000000000008001
+:103400000F00003200000000000000840F000032B6
+:1034100008000000000000F8F34001390800000037
+:10342000000000F8E340013908000000000000F847
+:10343000C340013908000000000000F8B340013922
+:1034400008000000000000F8A34001390800000057
+:10345000000000F89340013908000000000000F867
+:103460008340013908000000000000F87340013972
+:1034700008000000000000F8634001390800000067
+:10348000000000F85340013908000000000000F877
+:103490004340013908000000000000F833400139C2
+:1034A00008000000000000F813400139000000008F
+:1034B000000000F80380003200000000000000C897
+:1034C0003F80FC35000000000000009C020000323C
+:1034D0000000000000000000030000323E00000079
+:1034E000000000D00200363200000000000000287A
+:1034F000034038320000161304010080D20130B6B8
+:1035000000006704040100D012002DBCA0040000DC
+:10351000000000E40300363203000001000000E078
+:103520000300373200000000170000D00200003214
+:1035300000000000000000ACE100003400000000CA
+:10354000000001E00600003200000000000801E475
+:103550000600003200000000000E01EC0600003200
+:1035600000000000001001E0060000320000000032
+:10357000000000D012002D3A3E006F0402010080CE
+:10358000820D2DBC020000000000009CAE0D023236
+:1035900000000000000000A802000032300000001F
+:1035A000008886CC0700363200000000008A86CCF6
+:1035B0000700003A002400000000000409803632B1
+:1035C0000000161312000064024090B200000000D8
+:1035D000000000042940903A00007B0412000078AB
+:1035E00009C020B20000161380010080F28197B656
+:1035F0001D00161380010078E9E500B80000000006
+:103600000000007809459030000079040201008034
+:10361000C28297BC0000000000000084020000325B
+:1036200000000000000000CC030000320000810414
+:103630008E010080024028B20000BD10000000D8BA
+:10364000020000D2AA1100000000008C0E003632E9
+:1036500052000000000000740E0036321800000016
+:10366000000000E40300363209000002000000E020
+:1036700003003732FECA0000000000E403003632C7
+:103680000A000002000000E00300373200008C0452
+:1036900012010000094020B200008A0400000080EE
+:1036A0000200009000008C0412000004094020B2C7
+:1036B00000008F049F010080020090B200008E0481
+:1036C00012000008094020B202008A0404010078B8
+:1036D000092417B8060000000000007809641638B5
+:1036E00000008A0404010080028197BCFE000000F3
+:1036F0000000004403003632FE003600000000489F
+:10370000030036920000161312000000094020B298
+:103710000000950412000004094020B20000980443
+:103720009F010080020090B2000097041200000880
+:10373000094020B200000000000000B402009032F6
+:103740000000161300000080020000900000161315
+:1037500000000080020000900000161300000080AE
+:10376000020000900000161300000080020000908C
+:1037700000001613000000800200009000001613E5
+:10378000000000800200009000001613000000807E
+:10379000020000900600AA040000000C09641698BC
+:1037A0000000A10200000014084090920000DB021B
+:1037B00000000014084090923400C9030000001C6F
+:1037C000080036921200C9030000001C080036925F
+:1037D0003A00C9030000001C0800369200001613CE
+:1037E00000000080020000900000BA0200000014F7
+:1037F000084090920000DE0400000080020000906B
+:103800000000D4030000001408409092AB040000B4
+:103810000000008882CD903A0D00CD04000000FC2D
+:1038200002E416980D00DF04000000FC02E4169884
+:103830000D00E804000000FC02E416980000F60405
+:103840000000008002000090000000050000000061
+:103850000940909D000006050000008002000090D5
+:1038600000001005000000800200009000001A0512
+:10387000000000800200009000002405000000000D
+:103880000940909D00002B05000000800200009080
+:1038900000003405000000000940909D00003B0539
+:1038A00000000080020000900000AA050000000057
+:1038B000090000920000AA050000000009400092E3
+:1038C0001D07AC05000000A0020036920000BA05FA
+:1038D000000000800200009000001613000000802D
+:1038E000020000900000DE04000000DC0F40909217
+:1038F00000007E05000000800200009000008305AB
+:10390000000000D40200009210009805000000841E
+:103910001F6414980000DE04000000EC0E4090923A
+:103920000000A40500000080020000900000DE04FA
+:10393000000000D40E4090920000A7050000008017
+:103940000200009000004E06000000DC0E40909245
+:103950000000CB0500000080020000900800D005A8
+:10396000000000501F2416980000E805000000D851
+:10397000020000920D00F305000000FC02E416981E
+:103980000000F405000000D00200009200001F01BA
+:10399000000000D00200009200001513000000801B
+:1039A000020000900000161300000080020000904A
+:1039B00008000000000000F89340013900000000FA
+:1039C00000000078094590300000161306010080C1
+:1039D000228097BC3F00161304010080820D00B0C6
+:1039E0000200D104B00000A0F20B00B900000000FA
+:1039F000A00000046B4190340000020480010080AC
+:103A00000240B0B600000204040000800280B0BC96
+:103A100000000000000000D802000032000000009A
+:103A2000000000A822C02F370000000000000000A6
+:103A3000670100340042000000080000878D2A3A28
+:103A400000001613041000000700B0B200000000D0
+:103A5000001800000700D0320000161312000048C2
+:103A6000F2C138B418000000000000F8730A0339EE
+:103A700002043600000000C0020036920800020472
+:103A8000000000F8934001990000E2049F000080CC
+:103A9000020090B2000000000000000809409032CF
+:103AA000000000000000000409C0FD320200E20432
+:103AB000B00000A0F20B00B9000000000000000000
+:103AC0000B80903200000000000000000D4090329A
+:103AD00000000000A00000043B40B0310000DE0404
+:103AE0000400008002C02FBC8411DE040000008CA2
+:103AF0000E003692000016130200008002C12FBC97
+:103B000008000000000000F8934001390200EA04B8
+:103B1000B00000A0F20B00B90000ED0480010080AD
+:103B20001240B0B600000000000000043B40B0337B
+:103B30000000000000000004FD4BD0350000000034
+:103B4000000000080B00003200000000A000000C84
+:103B50001BE4B032000002040B000080020000B041
+:103B60000000F30404000080024090B21F00020431
+:103B700000000080114000990000F2040400008061
+:103B8000123EF8BA00000000000000800100F83288
+:103B900000000204000000900140F892000016139B
+:103BA000800000800281FCB60000FA049F000080C3
+:103BB000020090B2000000000000000809409032AE
+:103BC000000000000000000409C0FD3200001613D0
+:103BD00004010080428590B000000000000000E475
+:103BE0000380903209000004000000E00300373237
+:103BF00000000000000000E4034090320A000004CE
+:103C0000000000E0030037320000DE04000000C8BE
+:103C10000F81FC940000161302010080724290BCD8
+:103C20000000161306010080E24290BC000016134B
+:103C300004010078096490B500000000000000E471
+:103C40007300903C10000004000000E003003732D5
+:103C50000000DE0400000080020000900000090562
+:103C60009F000080020090B20000000000000008E9
+:103C700009409032000000000000000409C0FD323D
+:103C80000000161304010080428590B0000000007F
+:103C9000000000E40380903201000004000000E016
+:103CA0000300373200000000000000E00F80903277
+:103CB00000000000000000E4034090320200000415
+:103CC000000000E0030037320000DE04000000E4E2
+:103CD0000F409092000013059F000080020090B2F8
+:103CE00000000000000000080940903200000000C1
+:103CF0000000000409C0FD3200001613040100801A
+:103D0000428590B000000000000000E40380903283
+:103D100003000004000000E0030037320000000050
+:103D2000000000A80E80903200000000000000E4B7
+:103D30000340903204000004000000E0030037322A
+:103D40000000DE04000000AC0E40909200001D0553
+:103D50009F000080020090B20000000000000008F8
+:103D600009409032000000000000000409C0FD324C
+:103D70000000161304010080428590B0000000008E
+:103D8000000000E40380903205000004000000E021
+:103D90000300373200000000000000E403409032CE
+:103DA00006000004000000E00300373200000000BD
+:103DB000000000440F8090320000DE040000004844
+:103DC0000F4090920000161306010080824290BCC2
+:103DD0000000161304010078096490B5000028055E
+:103DE00004010080824290BC00000000000000003E
+:103DF0000900003200000000000000E403009032DF
+:103E000012000004000000E0030037320000DE046E
+:103E1000000000401F40909C00002E059F00008085
+:103E2000020090B20000000000000008094090323B
+:103E3000000000000000000409C0FD32000016135D
+:103E400004010080428590B000000000000000E402
+:103E50000380903207000004000000E003003732C6
+:103E600000000000000000E403409032080000045D
+:103E7000000000E0030037320000DE040000008094
+:103E8000020000900000161306010080824290BCE0
+:103E90000000161304010078096490B5000038058D
+:103EA00004010080824290BC00000000000000007D
+:103EB0000900003200000000000000E4030090321E
+:103EC00011000004000000E0030037320000DE04AF
+:103ED000000000FC1F40909C00003E059F000080F9
+:103EE000020090B20000000000000008094090327B
+:103EF000000000000000000409C0FD3203090000BA
+:103F0000000000280800363200005705000000308D
+:103F1000080036D20000610500000044088000D28D
+:103F20000000470504010080020084B2030E000077
+:103F300000000028080036328000570500000030DD
+:103F4000080036D2000061050000004408C000D21D
+:103F50000000470504010080020084B200004E0505
+:103F600000000044080001928002000000000000F0
+:103F7000070036328C0501000008000007003732C8
+:103F80000000161304100000078090B2000000002B
+:103F900000180000074090320000000000000048B8
+:103FA000F2C138340000161312000080020000B085
+:103FB00018003600000000F8730A03F92000000022
+:103FC000000000E40300363209000002000000E0B7
+:103FD0000300373200000000000000E40340843298
+:103FE0000A000002000000E0030037328C050100E7
+:103FF000000000A802003732A0000000000000000E
+:104000000900363200000000000000E00700003226
+:104010000000540506010000190090BC0000DE04F9
+:1040200000000080020000908C050100000000C824
+:1040300002003732800200000000003C08003632E7
+:1040400000000000000000340800013200005C05A0
+:1040500002000080D2E083BC0000000000000034B9
+:1040600008C083320000720500000080020000F0EA
+:1040700000000000000000A0078083320000000064
+:1040800000000030D820833A00005A050401003CAB
+:10409000D8E083BC00000000000100800200005056
+:1040A0000000000000000040080000320000000096
+:1040B00000000048080000328C050100000000C824
+:1040C0000200373200020000000000C8828D2C3A46
+:1040D000800000000000003C0800363200000000B4
+:1040E00000000078098078325A5A000004010080EC
+:1040F000828D975C00006A0502010048A89E84BA80
+:1041000000000000000000481880843A00006805A4
+:104110000601003C28C083BC0000000000000078BD
+:10412000098584301000000000000048888D843626
+:1041300000006F0590010048E8A584BA0000000067
+:10414000000000481880843A000000000000004889
+:104150000885843000000000040100800285845C32
+:104160000000000000010040084000520000000074
+:10417000000000E40300833201000002000000E0C0
+:10418000030037320C0078050000002CD8A082F91B
+:1041900005000002000000E00300373200000000CC
+:1041A0000000008002000030000000000001003824
+:1041B00008403E7200000000000000E403C08232AC
+:1041C00002000002000000E003003732020000029B
+:1041D000000000E003003732000000000000008013
+:1041E0000200003000007A0580000080F2403EB6F8
+:1041F0000000000000010080020000700000810546
+:104200009F000080020090B2000000000000000843
+:1042100009409032000000000000000409C0FD3297
+:1042200000000000000000840E8090320000DE04D8
+:10423000000000880E40909208000000000000F886
+:1042400093400139000087059F000080020090B272
+:10425000000000000000000809409032000000004B
+:104260000000000409C0FD32000000000000002032
+:104270000740F5320000000000080020070000326F
+:10428000000000000010002007C0F5320000000010
+:10429000001800200740F632000000000020002037
+:1042A0000780F632000000000028002007C0F63228
+:1042B00000000000003000200700F732000000007E
+:1042C000003800200780FF3200000000000000D806
+:1042D0000200003200000000000000000740093228
+:1042E000000000000008000077C02937000000002F
+:1042F000001000000780903200000000001800004D
+:10430000074090320000161312000048F2C138B482
+:1043100018003600000000F8730A03F900000000DE
+:1043200000000008C80100340000F603000000FC93
+:104330000200009200009A0580010080F24190B6D0
+:1043400000009B05000000C82F81FC9400000000C5
+:10435000000000C82F81FC35000000000000008034
+:104360000F45903000009E0502000080027EF8BCE0
+:1043700000000000000000840F00F8320000000080
+:10438000000000001940F837000000000000008421
+:104390003F40F83700000000000000840F64F83A46
+:1043A00000000000000000001900F83700000000C5
+:1043B000000000803F00F8370000DE0400000080AD
+:1043C0000F24F89A0000A60580010080F24190B603
+:1043D0000000DE04000000C83F81FC940000DE0401
+:1043E000000000C83F81FC950000A9050401008081
+:1043F000024090BC000000000000000409C0003230
+:104400000000DE04000000E41E40909C000000005C
+:10441000000000A8220090370000DE04000086C0E3
+:104420000740909208000000000000F89340013916
+:104430000D000000000000FC02E41638000000003F
+:1044400000000000090002320000B40504000080F2
+:104450000200B0B200000000000000000B000032BB
+:1044600020000000000000A0820D2A3A0000AF05E5
+:1044700004010000190090BC0000B60500000028EF
+:104480007901009400000000000000C83F80FC3467
+:1044900040800000000000280980363200008111B1
+:1044A000000000D8020000D20000020404000080D6
+:1044B000028092BC18000000000000F8730A033963
+:1044C00002043600000000C002003692EA05C00572
+:1044D00004010080824D90BC00000000000000EC50
+:1044E0000F00153200FE1F00000000F00F003732F1
+:1044F000F0FF0000000000E80F00363298050000D1
+:10450000000000F40F0036320000C605000000C8AD
+:104510004F80FC953623161304010080824D90BC19
+:1045200000000000000000EC0F80143200F81F00B3
+:10453000000000F00F003732C0FF0000000000E86C
+:104540000F00363298270000000000F40F003632CA
+:1045500000000000000000C84F80FC340400000090
+:10456000000000608F4D903A00001613600100803B
+:10457000020000B0000016137A010080020000B0B3
+:104580000000421100000080020000D00000DE04A4
+:1045900000000080020000900000CD058001008036
+:1045A000024090B600000000000000C86F80FC349C
+:1045B0000000CF0580010080124090B6000000008E
+:1045C000000000C85F80FC340000DE0400000080B2
+:1045D000020000900000D20504010080B24190B0BA
+:1045E0008007DE04000000C88F8DFC910000D40518
+:1045F00080000080124090B60000D505000000C881
+:104600007F80FC9500000000000000C87F80FC3423
+:104610000000D70580000080024090B60000D80559
+:10462000000000C88F80FC9500000000000000C85A
+:104630008F80FC340000DA0580000080424090B694
+:104640000000DB05000000C89F80FC950000000012
+:10465000000000C89F80FC340000DD058000008061
+:10466000324090B60000DE05000000C8AF80FC9527
+:1046700000000000000000C8AF80FC340000E1052D
+:1046800080000080224090B6841100000000008C61
+:104690000E0036320000E305000000C81F81FC95C3
+:1046A000AA1100000000008C0E003632000000004D
+:1046B000000000C81F81FC340000161306010080B2
+:1046C0008202F5BC00001613030000780900F5BD56
+:1046D0000000161304010080E225F5B5100000006B
+:1046E0000000004C1F2416380000DE0400000050BB
+:1046F0001F00F59C8007161304000080828DFCB01B
+:104700000000EC059F000080020090B20000000055
+:104710000000000809409032000000000000000482
+:1047200009C0FD3200000000000000001700F53A4B
+:104730008C04010000080000070037320000161347
+:1047400004100000078090B2000000000018000074
+:10475000074090320000161312000040F2C138B436
+:1047600018003600000000F8730A03F90000DE04A8
+:1047700000000080020000900000DE04000000EC59
+:10478000034090920000161304000080024090BC89
+:104790000000F505B20000D8020000B200000000E1
+:1047A000000201EC16E46E3A08000000000000F878
+:1047B0009340013900001F06171001F802006EB285
+:1047C0000600000604010080828D2FB00300000067
+:1047D000000000F8828D2F3200C061100000002818
+:1047E000098036D200000000000201EC16C06E3CC9
+:1047F00000000000001886C80600003218003600CD
+:10480000000000F8730A03F900000106000000D060
+:1048100002000092000007060419868002806CBC2A
+:10482000000016138001008012802FB600000000E7
+:104830000000000009006E3200000000C108000402
+:1048400009006E3200000000C01586780FC06C327F
+:1048500000000D068001008022802FB600000D06AA
+:10486000001886C8064000920000161380010080E0
+:1048700022802FB6000000000040000009006E32C8
+:1048800000000000C248000409006E320000000071
+:10489000C01686780FC06C3200000D0680010080C3
+:1048A00012802FB600000000001886C806000032F3
+:1048B0000040000000000028098036320000150684
+:1048C0000402018002C06EBC00006110000201EC15
+:1048D00016C06EDC000013068000008002802FB638
+:1048E00000001506810000F822802FB40000150694
+:1048F000001886C80640009200001506820000F8E5
+:1049000012802FB400000000001886C80600003294
+:10491000000016130401008002002DBC00001613D5
+:104920000401008002802DBC00000000001086C839
+:1049300006000032000000000000000007C00A323C
+:10494000003800000008000007003632000016138F
+:1049500004100000070090B20000000000180000E2
+:10496000074090320000161312000040F2C138B424
+:1049700018003600000000F8730A03F90000000078
+:10498000170100F8A2802F34000016130210868051
+:1049900072826CBC00000000001086A842806C3758
+:1049A00000002A061200703802007EB200001613C2
+:1049B0001200703C02007EB200001613120070302C
+:1049C00002007EB2000016131200703402007EB2A4
+:1049D0000000210602010080B2822ABC0000000013
+:1049E000170000D00200003206000006040100801B
+:1049F000828D2FB00000FA050403018002C06EBC56
+:104A000000003506000000800200009000002C0627
+:104A10000403018002C06EBC00003506001086C889
+:104A200046802A9600000000001086C846802A367C
+:104A3000000030068000008012802FB6030032068E
+:104A4000220000F8828D2FB200003206001886C8BE
+:104A500006000092000035068000008022802FB6FC
+:104A600000000000C20100F802802F3500C0611074
+:104A700000000028098036D200000000000201EC8E
+:104A800016C06E3C18003600000000F8730A03F9E7
+:104A900000000000001001E006802F32000000003E
+:104AA000000000A8E100003400000000A20000FCAB
+:104AB000020000320000F60380010080A2802FB6C1
+:104AC00000003B06B90100D8028001B20000F603E5
+:104AD000000000F802000092000000000000003812
+:104AE0001880F73A0000000000000038F8BF83305B
+:104AF00000003F0604010080F2BD83BC0000F60305
+:104B0000A90000F80200009200C046061801000C3F
+:104B1000A8CD3EB200004206840000741F40F7BAE0
+:104B20000000F603A90000F8020000920000000057
+:104B3000000000740F00003200C046061801000C8F
+:104B4000A8CD3EB218003600000000F8738A03F9C1
+:104B500000004306000000B00200009200000000C8
+:104B60000000007C0F80833200000000002800005D
+:104B70000700003200000000003000000700003293
+:104B800000010080003800000700373200000000FC
+:104B9000003C000C0780833200001613120000480E
+:104BA00002C080B20000161380010080A2802FB6E0
+:104BB0000000F603A9000008E80100940000540674
+:104BC00004010080A2C0EDBC52000000000000748F
+:104BD0000E00363200000000000000C00E4001321E
+:104BE000407E0500000000B40E00373200000000D7
+:104BF000000000C40E80073264005A06000000CC9A
+:104C00000E003692640016130401008082CDEDBCC4
+:104C100029000000000000740E0036320000000081
+:104C2000000000C00E400032A08C0000000000B464
+:104C30000E00363200000000000000C40EC000323A
+:104C400000000000000000CC0E80023210000000C6
+:104C5000000000E4337BEC391E000001000000E09E
+:104C60000300373200000000000000C86EC0EC37BF
+:104C70000000DE04000000D80EC0ED920000161304
+:104C800004310280A2DB2CBC00001613040100805A
+:104C9000028080B200001613021C018052C06EBC5C
+:104CA0002C0016130201008082CD81BC3F00161338
+:104CB0000200008082CD81BC3600670604000080BF
+:104CC00082CD81BC0F0000000000001009003632C8
+:104CD0002C0000000000001489CD813C10008012DF
+:104CE000001C011459E46ED96F0600000000008812
+:104CF00082CD813A0000161304010080028080B248
+:104D00000000161304310280A2DB2CBC0000161335
+:104D10000218018092C06EBC2C00161302000080A5
+:104D200082CD81BC10000000000000100900363266
+:104D3000100080120018011479E06ED96F0600008F
+:104D40000000008882CD813AAE060000001801887C
+:104D500082CD6E3AB70600000018018882CD6E3A07
+:104D6000C00600000018018882CD6E3AC906000016
+:104D70000018018882CD6E3AD20600000018018822
+:104D800082CD6E3ADB0600000018018882CD6E3AB3
+:104D9000E40600000018018882CD6E3AED0600009E
+:104DA0000018018882CD6E3AF606000000180188CE
+:104DB00082CD6E3AFF0600000018018882CD6E3A5F
+:104DC000080700000018018882CD6E3A1107000024
+:104DD0000018018882CD6E3A1A0700000018018879
+:104DE00082CD6E3A230700000018018882CD6E3A0A
+:104DF0002C0700000018018882CD6E3A35070000AC
+:104E00000018018882CD6E3A3E0700000018018824
+:104E100082CD6E3A470700000018018882CD6E3AB5
+:104E2000500700000018018882CD6E3A5907000033
+:104E30000018018882CD6E3A6207000000180188D0
+:104E400082CD6E3A6B0700000018018882CD6E3A61
+:104E5000740700000018018882CD6E3A7D070000BB
+:104E60000018018882CD6E3A86070000001801887C
+:104E700082CD6E3A8F0700000018018882CD6E3A0D
+:104E8000980700000018018882CD6E3AA107000043
+:104E90000018018882CD6E3AAA0700000018018828
+:104EA00082CD6E3AB30700000018018882CD6E3AB9
+:104EB000BC0700000018018882CD6E3AC5070000CB
+:104EC0000018018882CD6E3ACE07000000180188D4
+:104ED00082CD6E3AD70700000018018882CD6E3A65
+:104EE000E00700000018018882CD6E3AE907000053
+:104EF0000018018882CD6E3AF20700000018018880
+:104F000082CD6E3AFB0700000018018882CD6E3A10
+:104F1000040800000018018882CD6E3A0D080000D8
+:104F20000018018882CD6E3A16080000001801882A
+:104F300082CD6E3A1F0800000018018882CD6E3ABB
+:104F40000000A803000000D4020000920000EC0260
+:104F5000000000800200009028080000001C01886A
+:104F600082CD6E3A2D080000001C018882CD6E3A79
+:104F700032080000001C018882CD6E3A370800001C
+:104F8000001C018882CD6E3A3C080000001C01889C
+:104F900082CD6E3A41080000001C018882CD6E3A35
+:104FA00046080000001C018882CD6E3A4B080000C4
+:104FB000001C018882CD6E3A50080000001C018858
+:104FC00082CD6E3A55080000001C018882CD6E3AF1
+:104FD0005A080000001C018882CD6E3A5F0800006C
+:104FE000001C018882CD6E3A64080000001C018814
+:104FF00082CD6E3A69080000001C018882CD6E3AAD
+:105000006E080000001C018882CD6E3A7308000013
+:10501000001C018882CD6E3A78080000001C0188CF
+:1050200082CD6E3A0000B003000000D4020000926E
+:105030000000C603000000D4020000920000710AC4
+:10504000000000100880019200001613000000808C
+:105050000200009000001613000000800200009083
+:1050600000001613000000800200009000001613DC
+:105070000000008002000090000016130000008075
+:105080000200009000001613000000800200009053
+:1050900000001613000000800200009000001613AC
+:1050A0000000008002000090000016130000008045
+:1050B000020000900000B10A000000100880009279
+:1050C000000016130000008002000090000016137C
+:1050D0000000008002000090000016130000008015
+:1050E00002000090000016130000008002000090F3
+:1050F000000016130000008002000090000016134C
+:1051000000000080020000900000161300000080E4
+:1051100002000090000016130000008002000090C2
+:105120000000161300000080020000900000C00A7A
+:10513000000000100880009200001613000000809C
+:105140000200009000001613000000800200009092
+:105150000000130B0000001008400192000016131D
+:105160000000008002000090000016130000008084
+:105170000200009000001613000000800200009062
+:1051800000001613000000800200009000001613BB
+:10519000000000800200009000001B0B00000010C7
+:1051A00008C000920000161300000080020000906A
+:1051B00000001B0B0000001008C000920000220E2F
+:1051C000000000100840019200001613000000804B
+:1051D0000200009000001B0B0000001008C00092AD
+:1051E000000016130000008002000090000016135B
+:1051F00000000080020000900000161300000080F4
+:105200000200009000002E0B0000001008C0009269
+:1052100000001613000000800200009000002E0B1A
+:105220000000001008C000920000220E00000010D4
+:105230000840019200001613000000800200009058
+:1052400000002E0B0000001008C000920000161392
+:105250000000008002000090000016130000008093
+:105260000200009000001613000000800200009071
+:1052700000002C0B0000001008C000920000161364
+:10528000000000800200009000002C0B00000010C5
+:1052900008C000920000220E000000100840019299
+:1052A00000001613000000800200009000002C0B8C
+:1052B0000000001008C000920000161300000080DB
+:1052C0000200009000001613000000800200009011
+:1052D000000016130000008002000090000016136A
+:1052E00000000080020000900000F50B000000109C
+:1052F00008C000920000180B000000100800019286
+:105300000000130B0000001008400192000016136B
+:1053100000000080020000900000161300000080D2
+:1053200002000090000016130000008002000090B0
+:105330000000161300000080020000900000161309
+:1053400000000080020000900000161300000080A2
+:10535000020000900000EB0B00000010088000929B
+:105360000000180B00000010080001920000130B51
+:105370000000001008400192000016130000008099
+:105380000200009000001613000000800200009050
+:1053900000001613000000800200009000001613A9
+:1053A0000000008002000090000016130000008042
+:1053B0000200009000001613000000800200009020
+:1053C0000000EB0B00000010080001920000180B19
+:1053D00000000010080001920000130B00000010F4
+:1053E00008400192000016130000008002000090A7
+:1053F0000000161300000080020000900000161349
+:1054000000000080020000900000161300000080E1
+:1054100002000090000016130000008002000090BF
+:105420000000161300000080020000900000790CBC
+:1054300000000010088000920000180B000000100F
+:10544000080001920000130B0000001008400192B8
+:1054500000001613000000800200009000001613E8
+:105460000000008002000090000016130000008081
+:10547000020000900000161300000080020000905F
+:1054800000001613000000800200009000001613B8
+:1054900000000080020000900000790C0000001065
+:1054A000080001920000180B000000100800019293
+:1054B0000000130B000000100840019200001613BA
+:1054C0000000008002000090000016130000008021
+:1054D00002000090000016130000008002000090FF
+:1054E0000000161300000080020000900000161358
+:1054F000000000800200009000002D0B0000001052
+:105500000880009200001613000000800200009046
+:1055100000002D0B00000010088000920000220EF9
+:1055200000000010084001920000161300000080E7
+:10553000020000900000161300000080020000909E
+:1055400000001613000000800200009000001613F7
+:105550000000008002000090000016130000008090
+:105560000200009000002D0B0000001008000192C6
+:1055700000001613000000800200009000002D0BB8
+:1055800000000010080001920000220E0000001030
+:1055900008400192000016130000008002000090F5
+:1055A0000000161300000080020000900000161397
+:1055B0000000008002000090000016130000008030
+:1055C000020000900000161300000080020000900E
+:1055D00000001613000000800200009000007D080B
+:1055E0000000001008000192000016130000008067
+:1055F0000200009000007D080000001008400192A9
+:105600000000161300000080020000900000161336
+:1056100000000080020000900000161300000080CF
+:1056200002000090000016130000008002000090AD
+:105630000000161300000080020000900000430EDE
+:1056400000000010084001920000390E0000001018
+:10565000084001920000430E000000100840019233
+:105660000000130B00000010084001920000161308
+:1056700000000080020000900000430E00000010B7
+:105680000840019200001613000000800200009004
+:105690000000161300000080020000900000B90A0C
+:1056A00000000010084000920000B90A000000103D
+:1056B000088000920000B90A0000001008C00092A3
+:1056C0000000B90A00000010080001920000BE0AA4
+:1056D00000000010084001920000B90A000000100C
+:1056E000088001920000B90A0000001008C0019271
+:1056F0000000161300000080020000900000161346
+:1057000000000080020000900000161300000080DE
+:10571000020000900000F60C0000001008800092CB
+:105720000000F60C0000001008C000920000F60C0B
+:1057300000000010080001920000130B0000001090
+:105740000840019200001613000000800200009043
+:105750000000F60C0000001008C0019200001613B3
+:10576000000000800200009000001613000000807E
+:10577000020000900000161300000080020000905C
+:1057800000001613000000800200009000001613B5
+:10579000000000800200009000001613000000804E
+:1057A0000200009000004D0E000000100840019221
+:1057B0000000161300000080020000900000161385
+:1057C000000000800200009000001613000000801E
+:1057D00002000090000016130000008002000090FC
+:1057E0000000CB0E00000010084001920000CF0E18
+:1057F00000000010084001920000310E000000106F
+:10580000084001920000CF0E0000001008400192F5
+:1058100000007D08000000100840019200001613EF
+:1058200000000080020000900000CF0E0000001079
+:105830000840019200007E0800000010080002925B
+:1058400000001613000000800200009000001613F4
+:1058500000000080020000900000D00E0000001048
+:10586000084001920000310E000000100840019233
+:105870000000D00E000000100840019200007D08DA
+:105880000000001008400192000016130000008084
+:10589000020000900000D00E0000001008400192AD
+:1058A0000000161300000080020000900000161394
+:1058B000000000800200009000001613000000802D
+:1058C000020000900000D50E000000100880009239
+:1058D0000000D50E0000001008C000920000D50E98
+:1058E00000000010080001920000130B00000010DF
+:1058F0000840019200001613000000800200009092
+:105900000000D50E0000001008C001920000161320
+:1059100000000080020000900000161300000080CC
+:1059200002000090000016130000008002000090AA
+:105930000000161300000080020000900000161303
+:10594000000000800200009000001613000000809C
+:10595000020000900000161300000080020000907A
+:105960000000A00A0000001008400092000016137A
+:10597000000000800200009000001613000000806C
+:10598000020000900000161300000080020000904A
+:105990000000161300000080020000900000EA0ED4
+:1059A00000000010088000920000EA0E00000010C5
+:1059B00008C000920000EA0E0000001008000192EA
+:1059C0000000130B000000100840019200001613A5
+:1059D00000000080020000900000EA0E00000010AD
+:1059E00008C0019200001613000000800200009021
+:1059F0000000161300000080020000900000161343
+:105A000000000080020000900000030F0000001062
+:105A1000088000920000030F0000001008C00092F0
+:105A20000000030F00000010080001920000130B9B
+:105A300000000010084001920000161300000080D2
+:105A4000020000900000030F0000001008C0019247
+:105A500000001613000000800200009000007D0886
+:105A600000000010080000920000161300000080E3
+:105A70000200009000007D080000001008800092E5
+:105A80000000150F0000001008C0009200007D0803
+:105A9000000000100800019200007D0800000010C6
+:105AA00008400192000016130000008002000090E0
+:105AB0000000161300000080020000900000161382
+:105AC000000000800200009000001613000000801B
+:105AD00002000090000016130000008002000090F9
+:105AE00000007D0800000010088000920000260FD2
+:105AF000000000100880009200007D0800000010E7
+:105B00000800019200007D0800000010084001928A
+:105B10000000161300000080020000900000161321
+:105B200000000080020000900000161300000080BA
+:105B30000200009000001613000000800200009098
+:105B400000001613000000800200009000007D0895
+:105B500000000010088000920000260F00000010D6
+:105B60000800019200007D0800000010080001926A
+:105B700000007D080000001008400192000016138C
+:105B8000000000800200009000001613000000805A
+:105B90000200009000001613000000800200009038
+:105BA0000000161300000080020000900000161391
+:105BB000000000800200009000001613000000802A
+:105BC0000200009000007D08000000100880009294
+:105BD00000001613000000800200009000007D0805
+:105BE0000000001008400192000016130000008021
+:105BF00002000090000016130000008002000090D8
+:105C00000000161300000080020000900000161330
+:105C100000000080020000900000161300000080C9
+:105C2000020000900000FA0E0000001008800092B0
+:105C30000000FA0E0000001008C000920000FA0EEA
+:105C400000000010080001920000130B000000107B
+:105C5000084001920000161300000080020000902E
+:105C60000000FA0E0000001008C001920000161398
+:105C70000000008002000090000016130000008069
+:105C80000200009000001613000000800200009047
+:105C900000001613000000800200009000001613A0
+:105CA0000000008002000090000016130000008039
+:105CB000020000900000390F00000010080002925E
+:105CC0000000161300000080020000900000161370
+:105CD0000000008002000090000016130000008009
+:105CE00002000090000016130000008002000090E7
+:105CF0000000161300000080020000900000C00A9F
+:105D00000000001008C0019200001613000000807F
+:105D100002000090000016130000008002000090B6
+:105D20000000130B00000010084001920000161341
+:105D300000000080020000900000010B0000001035
+:105D400008C00192000016130000008002000090BD
+:105D500000001613000000800200009000001613DF
+:105D600000000080020000900000C00A0000001047
+:105D700008800092000016130000008002000090CE
+:105D80000000161300000080020000900000130BBA
+:105D9000000000100840019200001613000000806F
+:105DA000020000900000010B0000001008C00192EA
+:105DB000000016130000008002000090000016137F
+:105DC0000000008002000090000016130000008018
+:105DD000020000900000260D0000001008800092D4
+:105DE0000000161300000080020000900000260D45
+:105DF00000000010088000920000220E0000001039
+:105E0000084001920000161300000080020000907C
+:105E10000000260D000000100880009200001613FC
+:105E200000000080020000900000161300000080B7
+:105E30000200009000001613000000800200009095
+:105E40000000260D0000001008000192000016134B
+:105E500000000080020000900000260D00000010ED
+:105E6000080001920000220E00000010084001927C
+:105E70000000161300000080020000900000260DB4
+:105E800000000010080001920000161300000080BE
+:105E90000200009000001613000000800200009035
+:105EA0000000161300000080020000900000260D84
+:105EB000000000100800019200001613000000808E
+:105EC000020000900000260D000000100800019262
+:105ED0000000220E0000001008400192000016137E
+:105EE00000000080020000900000260D000000105D
+:105EF00008000192000016130000008002000090CC
+:105F0000000016130000008002000090000016132D
+:105F100000000080020000900000260D000000102C
+:105F2000088000920000161300000080020000901C
+:105F30000000260D00000010088000920000220ED4
+:105F400000000010084001920000161300000080BD
+:105F5000020000900000260D000000100880009252
+:105F600000001613000000800200009000001613CD
+:105F70000000008002000090000016130000008066
+:105F80000200009000001613000000800200009044
+:105F90000000161300000080020000900000260D93
+:105FA0000000001008C001920000220E0000001046
+:105FB00008400192000016130000008002000090CB
+:105FC0000000260D0000001008C00192000016130A
+:105FD0000000008002000090000016130000008006
+:105FE00002000090000016130000008002000090E4
+:105FF0000000AB0D00000010088000920000161396
+:1060000000000080020000900000161300000080D5
+:106010000200009000007D0800000010084001927E
+:106020000000161300000080020000900000AB0D7D
+:10603000000000100880009200001613000000808D
+:106040000200009000001613000000800200009083
+:106050000000161300000080020000900000AB0D4D
+:10606000000000100880009200001613000000805D
+:106070000200009000001613000000800200009053
+:1060800000007D0800000010084001920000161377
+:1060900000000080020000900000AB0D0000001026
+:1060A00008C001920000161300000080020000905A
+:1060B000000016130000008002000090000016137C
+:1060C0000000008002000090000016130000008015
+:1060D00002000090000016130000008002000090F3
+:1060E00000001613000000800200009000007D08F0
+:1060F000000000100840019200001613000000800C
+:10610000020000900000B50D0000001008C00192D0
+:10611000000016130000008002000090000016131B
+:1061200000000080020000900000161300000080B4
+:106130000200009000001613000000800200009092
+:1061400000001613000000800200009000001613EB
+:10615000000000800200009000007D080000001098
+:106160000840019200001613000000800200009019
+:106170000000B50D0000001008800092000016130A
+:106180000000008002000090000016130000008054
+:106190000200009000001613000000800200009032
+:1061A000000016130000008002000090000016138B
+:1061B0000000008002000090000016130000008024
+:1061C000020000900000B30E000000100840019291
+:1061D000000016130000008002000090000016135B
+:1061E00000000080020000900000161300000080F4
+:1061F0000200009000008608000000100840009295
+:10620000000016130000008002000090000016132A
+:1062100000000080020000900000161300000080C3
+:1062200002000090000016130000008002000090A1
+:106230000000161300000080020000900000DD083E
+:10624000000000100880009200001613000000807B
+:106250000200009000001613000000800200009071
+:106260000000C6090000001008000192000016138B
+:10627000000000800200009000008508000000106F
+:10628000080001920000D0090000001008000192EF
+:106290000000D00900000010080001920000D009A1
+:1062A000000000100800019200001613000000809A
+:1062B0000200009000001613000000800200009011
+:1062C0000000EF0800000010088000920000161384
+:1062D000000000800200009000008508000000100F
+:1062E00008000192000016130000008002000090D8
+:1062F000000016130000008002000090000000095A
+:1063000000000010088000920000C4090000001086
+:10631000088000920000850800000010080001922B
+:106320000000161300000080020000900000E60943
+:1063300000000010084000920000E6090000001074
+:10634000088000920000E6090000001008C00092DA
+:1063500000008508000000100800019200001613DC
+:106360000000008002000090000016130000008072
+:106370000200009000000C0A0000001008C000920B
+:106380000000161300000080020000900000850845
+:1063900000000010080001920000161300000080A9
+:1063A0000200009000001613000000800200009020
+:1063B00000000F0A000000100800019200000F0A00
+:1063C0000000001008000192000085080000001085
+:1063D00008000192000016130000008002000090E7
+:1063E0000000161300000080020000900000110A57
+:1063F00000000010088000920000110A0000001048
+:1064000008C00092000085080000001008000192FA
+:1064100000001613000000800200009000008508B4
+:1064200000000010084000920000DC09000000108D
+:10643000088000920000DC090000001008C00092F3
+:106440000000850800000010080001920000850887
+:1064500000000010080000920000850800000010F5
+:10646000084000920000250A0000001008800092F9
+:106470000000250A0000001008C0009200008508F6
+:1064800000000010080001920000161300000080B8
+:10649000020000900000161300000080020000902F
+:1064A0000000600A000000100880009200008508CB
+:1064B0000000001008C000920000850800000010D5
+:1064C00008000192000016130000008002000090F6
+:1064D00000001613000000800200009000003F0A38
+:1064E00000000010088000920000161300000080D9
+:1064F00002000090000085080000001008000192D2
+:106500000000161300000080020000900000161327
+:1065100000000080020000900000EC080000001065
+:106520000880009200001613000000800200009016
+:1065300000008508000000100800019200001613FA
+:106540000000008002000090000016130000008090
+:10655000020000900000540A000000100880009221
+:106560000000540A0000001008C0009200008508D6
+:1065700000000010080001920000161300000080C7
+:10658000020000900000161300000080020000903E
+:1065900000001C0A000000100880009200001C0A85
+:1065A0000000001008C000920000850800000010E4
+:1065B0000800019200001613000000800200009005
+:1065C00000001613000000800200009000006D0A19
+:1065D000000000100880009200006D0A000000100A
+:1065E00008C0009200008508000000100800019219
+:1065F0000800F303001801E8762081990800EF03F2
+:10660000001801E87620819900004B1200000080FC
+:10661000020000F0080082081D1901E8762081B907
+:106620000000F303000000F862812F950000F303DF
+:106630008000008002812FB62A0016131200002C61
+:1066400082CD2EB20000F303000000F802812F94E7
+:106650000800F303001C01E876208199000016135E
+:10666000800F018002C06EB600000000000000D85C
+:106670000200003200000000000E01EC06C06E3582
+:106680005400000000000000070036320000000047
+:10669000000000BCA8002D37B40401000008000071
+:1066A000C7CD8B3A000000000000007899C02C375D
+:1066B000B400000000000078898D973A000016139E
+:1066C0000210000087BF97BA000000000018000009
+:1066D0000740FE320000161312000040F2C138B429
+:1066E000000000000090007809006E3200001613D0
+:1066F00004A0000009806EB20000950804A5000403
+:1067000009806EB200000000000000040900903211
+:106710000000161302010080026490BC000098087B
+:1067200004010004096490BC0000000000000004A3
+:1067300009400032080000006E3402E81624903947
+:1067400000009908B71002E0068097B200009C088C
+:1067500080000080F280FCB600009D08000000C8A8
+:10676000FF80FC9400009E089F990080821BEEBC75
+:1067700000000000009800E00E006E3200000000F3
+:10678000A70000800200003018003600000000F86A
+:10679000730A03F9000000000010021C09006E32A9
+:1067A0004000A3080601008082CD91BC00C0A4086F
+:1067B000001802E00680369200E00000001802E0B7
+:1067C00006803632000000000000002009800332FD
+:1067D0000000A70880D7018032C06EB6000000001C
+:1067E000000000204900923A0000000000980118C3
+:1067F00009006E3200000000000A022409C06E3257
+:106800000000000000C0012809806E320000B508B9
+:10681000800E018012C06EB602000000003C02EC47
+:106820000600363200000000000000004901923AE4
+:106830000000B10880D6018042C06EB60082000020
+:10684000001002E0A6CD913200A00000002C02E86A
+:10685000060036322800BF08003A02EC06003692E5
+:1068600000000000D301001CD9C191340082000057
+:10687000001002E0A6CD913200A00000002C02E83A
+:10688000060036323400BF08003A02EC06003692A9
+:1068900004000000003C02EC060036322800000034
+:1068A00000000000890D923A0000BB0880D60180EC
+:1068B00042C06EB600860000001002E0A6CD913204
+:1068C00004A00000002C02E8060036321400BF08C5
+:1068D000003A02EC0600369200000000D301001CD2
+:1068E000D9C1913400860000001002E0A6CD91329B
+:1068F00004A00000002C02E8060036322000BF0889
+:10690000003A02EC0600369212000000003802EC59
+:1069100086CD913A08000000002802E886249039CC
+:1069200000000000002002E0962414370000000060
+:10693000004001E0068091320000C508040100809B
+:10694000028092BC0000000000C001E0060000329E
+:1069500000000000003000E00600003200000000EF
+:1069600000B000E00600003220000000000000003F
+:10697000070036320000000000000078A9002D3723
+:106980000005010000080000C78D973A00000000D4
+:106990000000007899C02C3700010000000000784A
+:1069A000898D973A000016130210000087BF97BA2E
+:1069B00000000000001800000740FE32000016131F
+:1069C00012000048F2C138B40000D20880D7012C70
+:1069D00009C06EB200000000DAD701EC06C06E35C7
+:1069E00000000000005A01EC0640ED32AE0000004D
+:1069F000000000781900363AAF0016130401008039
+:106A0000828D97BC00000000005C01E806808B329C
+:106A10000000D7088001008062C092B6000000002C
+:106A2000000000F882812F3418003600000000F8C2
+:106A3000730A03F9000000000004013808C06E3238
+:106A40000000161304C9018002806EBC0000000023
+:106A5000006201EC06808332010085081201002CDF
+:106A600082CD2EB2000016130000008002000090BC
+:106A700000000000005401FC02C06E320000000063
+:106A8000000000D80280013200C0E3081801000CA9
+:106A9000A8CD3EB2208000000000000808803632F9
+:106AA0002D00EF031201002C82CD2EB20000161330
+:106AB0000000008002000090000000000062013829
+:106AC00008C06E320008008000000028090037323C
+:106AD0000060EB1100000008088036F20000161379
+:106AE000870601EC16C06EBC000085080B00008014
+:106AF000020000B0000085088000008072812FB67F
+:106B000000000000000000F872812F343D0085086D
+:106B10001201002C82CD2EB200001613000000805E
+:106B200002000090000016130407018012C06EBC22
+:106B30000000161380000080B2812FB60000EF081D
+:106B4000000000F8B2812F940000161304A0001872
+:106B500008006EB2000016130406018002C06EBC6D
+:106B600000009E1200000080020000F000000013F0
+:106B70000078016008006EF20000F508120100C8FC
+:106B8000020020B20000F80800000080020000901F
+:106B9000000005091201005C088020B20000F8081E
+:106BA0001201006002802CB2000016130000008069
+:106BB000020000900000FA0804000080024080BC3F
+:106BC00000000000000000F81F80FF3A0000FD08F0
+:106BD00080010080A2802FB618003600CA0000F89D
+:106BE000730A03F9000016130401008002802DBC13
+:106BF000000085088000008072812FB63D001613CA
+:106C00001200002C82CD2EB200008508000000F892
+:106C100072812F94000016130406018002C06EBC1E
+:106C20000000000000BC001408806E320000F8086C
+:106C3000120000C8020020B20000F6081200005C3A
+:106C4000088020B20000161304A0001808006EB2DD
+:106C5000000000000000007879613832000016134F
+:106C60001218024CE2256EB20000161304010080D7
+:106C700002402DBC080000000010020078E16E39CF
+:106C8000000000000018002007000032070000008C
+:106C90000000003878CAE939000016130400003CEF
+:106CA000084080B2000000000090006C08006E32C6
+:106CB000000000000098004C08006E32000016131F
+:106CC0000400008032E186B200000000510000D8CC
+:106CD00002000032000000004D00000067E0833E2B
+:106CE00000000000000800000700803200000000E3
+:106CF0000010000007C086320000000000180000ED
+:106D000007C084320000000000000018D8A0813CB9
+:106D10000000840904B000E0D6206EBC0000161309
+:106D200009010080020000B0000043090400003C9B
+:106D3000D8E083BC0000161304010080028081BCEF
+:106D4000000024098000008092802FB600001C09FA
+:106D50001201000009C021B218003600000000F83E
+:106D6000730A03F91D0000000000007809A4173819
+:106D70000000210904010080128097BC0000161356
+:106D800080010080A2802FB600001B09670000F878
+:106D9000A2802FB500001C090000000009C021924C
+:106DA0000000230904000080228097BC0000161315
+:106DB00004010080328097BC00000000C90100D8A7
+:106DC00002408432000027090400008072802DBC3C
+:106DD0000000161312000044E2E038B2000034094B
+:106DE000510000D812802D9A0000000000000078A9
+:106DF000F98183340000161312000044E2E538B232
+:106E000000002C098000008082802FB60000F7115E
+:106E100000A0015008006EF20000000000F801E040
+:106E20000600853200002E09120100E802C021B2DE
+:106E300018003600000000F8730A03F90000320958
+:106E40000401008002802DBC000016138001008028
+:106E5000A2802FB600002D09670000F8A2802FB590
+:106E600000001613120000E802C021B20000161341
+:106E70000401008072802DBC00000000510000D889
+:106E800002000032000039092A010000D82080BA2F
+:106E9000000038091201000009C021B218003600B4
+:106EA000000000F8730A03F900000000000000D899
+:106EB000024084321D0016130400008002A417B89B
+:106EC00000000000CAE0006C08006E320000000004
+:106ED00000E8004C08006E320000161304F00018A1
+:106EE00008006EB2000000000000003818818335F1
+:106EF0000000100904B00080829B81BC00001613C2
+:106F00000D010080020000B0000016139F00001465
+:106F1000184081BC00000000CA0100F842802F35F3
+:106F200008A0100912010040A2CD39B200001613CA
+:106F3000000000800200009000004E09293402B8D1
+:106F400008806EB2000046091201000009C021B29B
+:106F500018003600000000F8730A03F91D00000055
+:106F60000000007809A4173800004B0904010080D4
+:106F7000128097BC0000161380010080A2802FB6FB
+:106F800000004509670000F8A2802FB500004609FF
+:106F90000000000009C0219200004D09040000809B
+:106FA000228097BC0000161304010080328097BC39
+:106FB00000000000C90100D8024084320000000037
+:106FC00000000078F9818334000016131200004499
+:106FD000E2E538B2000056092800006CD8E086BA15
+:106FE0000000F61100A0015008006EF200005609E2
+:106FF0001DF801E0060085B20000560980000080FF
+:1070000002812FB62A0016131200002C82CD2EB258
+:1070100000000000000000F802812F3400005C092D
+:1070200004A000E0068081B20000000000BC00E87F
+:107030000640813200000000009000E006C0863269
+:1070400000000000009800E006C084320000161323
+:107050000400008032E186B2000070090000008068
+:10706000020000900000620980010080A2802FB61B
+:1070700000005F091201000009C021B218003600AB
+:10708000000000F8730A03F91D0062090401008082
+:1070900002A417B80000161380000080E2802FB60B
+:1070A00000005E09000000F8E2802F94000000005C
+:1070B00000E0006C08006E3200000000CAE8004CDE
+:1070C00008006E32000016130400008032E186B220
+:1070D0000000161304F0001808006EB200006B09DF
+:1070E00004B00080829B81BC000016130D0100805B
+:1070F000020000B0000016139F000014184081BC6D
+:1071000000000000CA0100F842802F3508A01613C5
+:1071100012000040A2CD39B20000000000A000E043
+:107120000680813200000000009800E006C0843232
+:1071300000000000009000E006C086320000161338
+:107140000400008032E186B20000000000BC00E8CC
+:1071500006408132000076092A5D01E806808BB284
+:10716000000073091201000009C021B218003600A6
+:10717000000000F8730A03F91D007609040100807D
+:1071800002A417B80000161380000080E2802FB61A
+:1071900000007209000000F8E2802F9410247909A1
+:1071A000370000F8A28D2FB13D0016131200002CFD
+:1071B00082CD2EB200000000000000F872812F3452
+:1071C00008000000CA1C01E8762081390000541034
+:1071D0000000002CF90100F400007F09800000800D
+:1071E000E2802FB600007E091201000009C021B222
+:1071F00018003600000000F8730A03F91D0016138A
+:107200000401008002A417B800001613800100805A
+:1072100082802FB60000161304010080C20003BC58
+:10722000100000000018008067A173393000F603D9
+:107230001201005CA28D2CB2000016130000008029
+:107240000200009000008A098000008092802FB622
+:1072500018003600000000F8730A03F91D00161329
+:107260000400007809A417B8000089090400008010
+:10727000228097BC0000161304010080328097BC66
+:1072800000000000C90100D802408432000016133B
+:1072900004010080D2E083BC000016132A000078AD
+:1072A000F98183B40000161312000044E2E538B2FD
+:1072B0000000641100000030030038F20000920961
+:1072C0001D000038188183B50000920980000080FD
+:1072D00002812FB62A0016131200002C82CD2EB286
+:1072E00000000000000000F802812F340000161397
+:1072F000870601EC16C06EBC000096090B000080EA
+:10730000020000B000000000CA0100F842802F34E3
+:1073100008C0161312000040A2CD39B2000099092E
+:107320008000008082802FB60000F71100A001507D
+:1073300008006EF20000000000F801E0060085324F
+:1073400000009B091201000009C021B2180036009C
+:10735000000000F8730A03F90000BD092A3502B8DD
+:1073600008806EB200009E091201000009C021B21F
+:1073700018003600000000F8730A03F9000000004E
+:10738000000000F8A2802F350000B509040000803D
+:10739000026180BC0000AD0980B8000009C06EB277
+:1073A0004000A50904000080820D90BC80001613E7
+:1073B00004010080820D90BC0000A50902B000808D
+:1073C000821B84BC0000AD09000000F8B2812F943C
+:1073D000000016130407018012C06EBC00001613D3
+:1073E00080000080B2812FB60000161380D6018085
+:1073F00052C06EB60000000000D601EC56C06E34DC
+:1074000000000000000000601800863A0000000044
+:1074100000000080B701783400000000007801E02F
+:10742000060086324000BD0904000080820D90BC39
+:107430000000161304A0001808006EB200009E128F
+:1074400000000000D82080FA000016130600003C5F
+:10745000182084BC0000161304B0003C88DB83BEF7
+:107460000000161380010080C20178B60000000001
+:1074700000000080F720783A00000000587801E012
+:10748000F620863A00000C0900000004F860809A9B
+:107490000000B80980B9000009C06EB22F00BD0914
+:1074A0001201002C82CD2EB20000161300000080C5
+:1074B000020000904000BA0904010080820D90BCD7
+:1074C0003800BC09000000780900369280001613CD
+:1074D00004010080820D90BC39000000000000789B
+:1074E00009003632000016131200002CE2E52EB21D
+:1074F000000016138001008082802FB60000161352
+:1075000004010080C20003BC1000000000180080CD
+:1075100067A1733900000000005C01E806808B322F
+:1075200010240000000000F8A28D2F3130008508E3
+:107530001201005CA28D2CB2000016130000008026
+:10754000020000900000161380010080C2812FB657
+:1075500000000009000000F8C2812F950000000023
+:10756000005401FC02C06E3200000000000000D890
+:107570000280013200C0CC091801000CA8CD3EB237
+:107580002080000000000008088036322D00EF0344
+:107590001201002C82CD2EB20000161300000080D4
+:1075A00002000090000000000062013808C06E3246
+:1075B0000008008000000028090037320060EB114D
+:1075C00000000008088036F20000DA0900000080A0
+:1075D000020000900000D20980000080C2812FB616
+:1075E0000000D50900D001E806000092000000006C
+:1075F000000000F8C2812F350000D50904D10180B8
+:1076000002806EBC0000000000D601EC26C06E3483
+:107610000000D7098000008092812FB60000DA09AF
+:1076200000C801E80600009200000000000000F819
+:1076300092812F350000DA0904C9018002806EBCF6
+:107640000000000000D601EC16C06E341100850861
+:107650001201002C82CD2EB2000016130000008013
+:1076600002000090000085089A0100F842812FB5C1
+:107670000000E309120100C8020020B2000000006F
+:10768000005C01EC0640003200008508370000F87D
+:1076900042812FB400000000000000F872812F34F6
+:1076A0003D0085081201002C82CD2EB20000161379
+:1076B00000000080020000900000EE091201005C52
+:1076C000088020B20000DE091201006002802CB2A6
+:1076D0000000161300000080020000900000EB097B
+:1076E000120100C8020020B200008508370000F82F
+:1076F000D2812FB400000000000000F872812F3406
+:107700003D0085081201002C82CD2EB20000161318
+:1077100000000080020000900000EE091201005CF1
+:10772000088020B20000E7091201006002802CB23C
+:10773000000016130000008002000090000000000E
+:107740000000007879613832000016131218024CDC
+:10775000E2256EB200000000003402B808806E32EC
+:107760000000000000A0015008006E320000000080
+:107770000078016008006E320000F5099D110234A6
+:1077800009006EB20000000000F0018808006E32AF
+:107790000000121200A8010809006EF200000000AB
+:1077A000D4F801E00600853200000000DA5C01E850
+:1077B00006808B3200006411DD000030030038F2D7
+:1077C0000000FB092329020409806EB23E00161353
+:1077D0001200002C82CD2EB20800FF091D1C01E80A
+:1077E000762081B90000FF098000008002812FB659
+:1077F0002A0016131200002C82CD2EB200000000C9
+:10780000000000F802812F34000054100000002C0A
+:10781000F90100F40000030A9D010080074093B2C3
+:107820000000000000300080078088320000000067
+:10783000003800800700EE320000000000080080E1
+:1078400007C0853200000000001000800740903221
+:107850001000000000180080878D853700000000B0
+:107860000020008007008632000000000028008011
+:107870000700853200000A0A1201000009C021B287
+:1078800018003600000000F8730A03F93000F60310
+:107890001201005CA28D2CB20000161300000080C3
+:1078A000020000900012161304010080A28D2FB078
+:1078B0000000000000CC017809806E3200008508CD
+:1078C000DCD101E806809792130085081201002C94
+:1078D00082CD2EB20000161300000080020000903E
+:1078E0000000E30F00000018094081F20000C70FFC
+:1078F00000A8012009006EF20000850880010080C8
+:10790000F2802FB60000190A120100C8020020B24E
+:10791000000085088000008072812FB60000000002
+:10792000000000F872812F343D0085081201002C00
+:1079300082CD2EB2000016130000008002000090DD
+:107940000000EE091201005C088020B20000150A58
+:107950001201006002802CB20000161300000080AB
+:107960000200009000008508350100F812812FB553
+:1079700000000000000000D802800132000000007A
+:10798000005401FC02C06E3200C0230A1801000C32
+:10799000A8CD3EB220800000D10100080880363218
+:1079A0003B00F3031201002C82CD2EB2000016130F
+:1079B00000000080020000900000E2110098012801
+:1079C00009006EF2000085080000008002000090AF
+:1079D00000002F0A80010080A2812FB600002F0A2C
+:1079E0008000008042812FB61F00000000000010C0
+:1079F00009003632000080120000001409802FD2E6
+:107A00003C00000000000010090036320000801227
+:107A10000000001409803CD200002F0A085B01EC32
+:107A200006FB6EBC00000000005A01EC06000032AC
+:107A300000002F0A370000F842812FB43D000000FB
+:107A4000D701002C82CD2E320000360A8001008042
+:107A500092812FB60000161380000080C2812FB6DD
+:107A600000003D0A08C901E806BB6EBC000000002A
+:107A700000C801E806000032330016131200002C83
+:107A800082CD2EB20000F31100000028098001F21F
+:107A900000008508000000800200009000003D0A00
+:107AA00080010080C2812FB6000016138000008084
+:107AB00092812FB600003D0A08D101E806BB6EBCDA
+:107AC0000000000000D001E8060000323300161369
+:107AD0001200002C82CD2EB20000F311000000280D
+:107AE00009C001F20000850800000080020000903B
+:107AF0000000850880010080F2812FB618008508FB
+:107B00000000002C82CD2E92000016130407018085
+:107B100012C06EBC0000430A120000C8020020B26E
+:107B20000000460A1201005C088020B20000161313
+:107B30001200006002802CB200000000000000F87B
+:107B40001F80FF3A0000F3031201002C72E02EB2F6
+:107B500000001613000000800200009000000000EA
+:107B60000000007879613832000016131218024CB8
+:107B7000E2256EB200000000003402B808806E32C8
+:107B800000000000D4A0015008006E320000000088
+:107B9000DB79016008006E320000F711DD0000049F
+:107BA000080000F21000000000180080878D853763
+:107BB0000000000000F801E0060085320000500AD5
+:107BC0001201000009C021B218003600000000F8C0
+:107BD000730A03F9300016131200005CA28D2CB258
+:107BE00000001613040701EC16C06EBC0000000074
+:107BF00000B000E00600003200008508DA5C01E811
+:107C000006808B92000085089F41018052206EBC47
+:107C100000005F0A9F98018052206EBC00000000A7
+:107C2000000000D80280013200000000005401FC76
+:107C300002C06E3200C05D0A1801000CA8CD3EB231
+:107C40002080850831000008088036B2000000005E
+:107C5000000000F812812F343B0085081201002C2F
+:107C600082CD2EB2000016130000008002000090AA
+:107C70000000E2110098012809006EF2000085085A
+:107C8000000000800200009000008508D54101E05E
+:107C9000064081920000850804B0008002006EBC9E
+:107CA000000000000090010008006E320000001388
+:107CB0000078016008006EF2000085080000008076
+:107CC0000200009000000000000C027809806E3273
+:107CD0000000670A04D4018012C06EBC00000000DE
+:107CE000000000781980973700000000009001E044
+:107CF000E6256E3A0000001300000080020000F04C
+:107D000000006B0A0000008002000090000085085F
+:107D1000009001E00600809200000000009001E069
+:107D20000600803200000009000000800200009080
+:107D30000000161380000080F2802FB60000C70FED
+:107D400000A8012009006EF20000140A80000080E3
+:107D5000F2802FB60000850800000080020000902D
+:107D600000000000000000D8028001320000000086
+:107D70000000007809006E320200760A04B9008023
+:107D800082CD6EBC0000780A800000807280FCB654
+:107D900000007B0A000000FC020000920000780A4C
+:107DA000800000808280FCB600007B0A000000FC9E
+:107DB0000200009200001613040000800200F5BCCF
+:107DC00000000000000000A842BD97300000000045
+:107DD000541809FEF2C07C3000C0810A1801000C62
+:107DE000A8CD3EB200000000000E01EC06000034F9
+:107DF00000000000005401EC06C02F32208000007B
+:107E000000000008088036320000F3031201002C45
+:107E100082CD2EB2000016130000008002000090F8
+:107E2000000000000062013808C06E3200080080C7
+:107E300000000028090037320000EB1100000008A4
+:107E4000E80100F400001613040701EC16C06EBC34
+:107E500000000000000000A8A2002D370A0000006A
+:107E6000000000780900363200000000001809E226
+:107E7000070000320000870A04010078198097BCCF
+:107E80000200920A04B9008082CD6EBC0000004856
+:107E9000D6010078C9CD2C3200008B0AB6000080D4
+:107EA000020000B00000161312000064028097B2B6
+:107EB00000008D0A1208006402006EB200008E0AF3
+:107EC0001218006402006EB200008F0A12100064E3
+:107ED00002006EB200000000A65401EC06C02F3272
+:107EE00000007D08000E01EC060000940020004C0C
+:107EF000D6010078C9CD2C320000930AB60000806C
+:107F0000020000B00000161312000064028097B255
+:107F10000000950A1208006402006EB20000960A82
+:107F20001230006402006EB20000970A123800643A
+:107F300002006EB20000980A1240006402006EB2A5
+:107F40000000990A1248006402006EB200009A0A0A
+:107F50001210006402006EB200009B0A1218006446
+:107F600002006EB200009C0A1220006402006EB291
+:107F700000009D0A1228006402006EB2000000009A
+:107F8000A65401EC06C02F3203007D08000E01EC60
+:107F90000600369200000000000000FC02000132E2
+:107FA0000000A30A0000001408803D9200000000B9
+:107FB000000000FC020001320000A60A040000DC00
+:107FC00053603DB318000000000000F8738A0339C5
+:107FD000A20A3600000000C0020036920000000035
+:107FE000005401FC02C06E3200000000000000D806
+:107FF0000280013200C0AC0A1801000CA8CD3EB2CC
+:108000002080000000000008088036321500EF03D1
+:108010001201002C82CD2EB2000016130000008049
+:10802000020000900000000000280000070000325D
+:10803000000000000030000007C02C320010008259
+:108040000038000007003732000016131200004805
+:1080500002C080B200007D08CA010008E801009457
+:10806000000016138001008062812FB62D001613C8
+:108070001200002C82CD2EB20000B50A1D01008036
+:10808000020000B000007D08000000F862812F951A
+:10809000000016138000008002812FB6000000004F
+:1080A000000000F802812F342A007D081201002C04
+:1080B00082CD2EB200001613000000800200009056
+:1080C0000000D7110000002C09C085D20000641107
+:1080D00000000030030038F20000F303230100F831
+:1080E00022812FB43E00F3031201002C82CD2EB268
+:1080F0000000161300000080020000900000D7115D
+:108100000000002C09C085D20000F303000000F835
+:1081100022812F940000C50A380100D8028001B2E4
+:108120000000C30A1E000080020000B00000C50A63
+:108130001A010080020000B0000038120000006840
+:108140001F80F6FA0000F303000000800200009098
+:108150000000C90A12010060084023B2008200003A
+:108160000000000808803632000038120000006469
+:108170001F40F6FA0000F3030000008002000090A8
+:108180000000161312000024080023B2000016138A
+:108190001200002008C023B20000161312000018BD
+:1081A000088023B200C0D40A1801000CA8CD3EB24A
+:1081B0000000CC0A12000038028081B200001613C1
+:1081C0001200003C020082B20000161312000030C0
+:1081D000024082B20000161312000034020086B280
+:1081E00020800000000000080880363200003812AD
+:1081F0000000005C1FC0F5FA0000F30300000080DF
+:108200000200009000000000450000D8020000328B
+:108210000000000000000000074080320000000065
+:10822000001000000740823200000000001800002B
+:10823000070086320000161312000050F2C138B455
+:1082400000007A0F003001E016206EFA0000DD0A0F
+:108250003801002CF8010BB40000DD0A020D028089
+:10826000A25B80BC000000000000002CC8C182346A
+:108270000000DF0A8000008042812FB60000B40FAA
+:1082800000000080020000F0000016139FA801E02B
+:1082900016206EBC0000D40F00000080020000F029
+:1082A0000000E50A270100D8028001B200000000AA
+:1082B000C700002CE8C08234000000000000000865
+:1082C000D801003400000000D54001E006008732EC
+:1082D00008004B12001801E8762081F900006411B3
+:1082E00000000030030038F20000E90A2319000002
+:1082F000078081B23E0016131200002C82CD2EB2F0
+:108300000000EB0A1D210000070082B20000EE0A07
+:10831000000000F862812F950000EE0A80000080C6
+:1083200002812FB62A0016131200002C82CD2EB225
+:1083300000000000000000F802812F340000161336
+:1083400080000080A2802FB6000054100000002C96
+:10835000F90100F4000016130401008062802DBCB6
+:108360001000F40A2C30000017E02CB90000F60AC7
+:108370008E39000007C082B20000F60A0008000033
+:10838000070087920000F60A8E390000B7C182B458
+:108390000000000000080000070087320000F80A13
+:1083A000120100E802C021B218003600000000F8F7
+:1083B000730A03F90000F60A9F010014184081BCFB
+:1083C0000000FE0A0400008002C085BC00001613F5
+:1083D0001200006802C585B00000000000000078AF
+:1083E00009C58530000016130201008082BA97BCCF
+:1083F000000016130601008092BA97BC0000161305
+:108400001200004802C080B2000016130401008070
+:10841000D28180B50000F603CA010008E88180948B
+:10842000000016138001008082812FB60000040B2B
+:108430001E000080020000B00000060B1A01008040
+:10844000020000B000003812000000681F80F6FA39
+:108450000000F303000000800200009000001613EB
+:108460009FA801E016206EBC00007A0F00000014E7
+:10847000080000F200000A0B8000008042812FB645
+:108480000000B40F00000080020000F00000D40FD4
+:1084900000000080020000F000007F08040000805F
+:1084A000024081BC00000E0B120100E802C021B2A4
+:1084B00018003600000000F8730A03F900000000FD
+:1084C0000000007809C58530000016130201008005
+:1084D00082BA97BC000016130601008092BA97BCBE
+:1084E00000007F081201006802C585B00000161365
+:1084F000000000800200009000007D0880000080E5
+:10850000F2C185B60000170B1C41028006C085B27F
+:10851000000000000000006802C585300000000077
+:10852000000000701F00F73A00007D08000000F80E
+:1085300022812F9400007D0880000080F2C185B662
+:108540000000D7110000002C09C085D20000F30301
+:10855000D20100941E40E99A00001613042000186E
+:1085600008006EB20000161380000080F2812FB662
+:1085700000008C1200000080020000F000001613C2
+:1085800004010080028080BC0000161304510180A9
+:1085900002806EBC000016130421018002006EBC34
+:1085A00000000000003C00E8064081320000250B7E
+:1085B0001F000080020000B00000220B9E400278E5
+:1085C000094068B20000161300000080020000900D
+:1085D0000000290B8001008082812FB600007F08F7
+:1085E0002A3101E0060000B218000000CA0000F8BD
+:1085F000730A03397F083600000000C0020036927B
+:1086000000007F0880010080A2802FB618000000C3
+:10861000CA0000F8730A03397F083600000000C062
+:10862000020036920D002F0B000000580800369211
+:1086300000002F0B00000058080000921B000000F3
+:1086400000000058080036320000161304200018FD
+:1086500008006EB20000161380000080F2812FB671
+:1086600000008C1200000080020000F000000000FA
+:108670000030002808006E3200000000545401FC55
+:1086800002C06E320000940B380000A4088082B251
+:108690000000940B0428010408006EB200001613B9
+:1086A0009F500104A85B80BC00000000005001E85E
+:1086B0000600003200005E0B0801007819A082BCA1
+:1086C00000000000002801E0A660803C00003C0B98
+:1086D0002A010014080000B200000000CA000014C3
+:1086E0001840813A0000C70F00A80120A9206EFAA7
+:1086F0000000161306010280821B92BC00000000DD
+:10870000002001E0A6206E3C00000000003000E0E8
+:10871000060000320000000000A801E006009232CE
+:1087200000000000000000D80280013200C0500BA1
+:108730001801000CA8CD3EB20000470B04000080D9
+:10874000024081BC0000000000000014080000325C
+:1087500018000000000000F8730A0339410B3600CE
+:10876000000000C0020036922080000000000028B7
+:108770000980363200008111000000D8020000D2CA
+:1087800000004B0B04000080028092BC18003600F1
+:10879000000000F8730A03F900000000000000D890
+:1087A0000280013200C0500B1801000CA8CD3EB26F
+:1087B00018000000000000F8738A03394B0B00001A
+:1087C000000000C0020036320000360000000080C9
+:1087D0000200009000000000DE000008E801003404
+:1087E00000000000DF00013808C06E320000000009
+:1087F0000010000007000032000000000018000018
+:1088000007808232000000000030000007C02C32D8
+:108810000020008000380000070037320000000010
+:10882000CA3D000C078083320000000000000014E5
+:108830001840813A00005C0B040201EC16C06EBCCB
+:1088400000000000C00100141840813A0000000040
+:10885000000000F892802F3400C016131200004070
+:10886000A28D39B20000D70B1201004802C080B2BD
+:1088700000001613000000800200009000000000BD
+:10888000000000280880973200000000000000A4CB
+:1088900008808232000000000010006C18206E3A40
+:1088A000000000000018004C08006E320000C70FE6
+:1088B00000A8012019206EFA00001613060102809C
+:1088C000821B92BC00000000002001E016206E3CDC
+:1088D0000000000000A801E0060092320000690BD1
+:1088E000003801E006408092000000000060006C4B
+:1088F00018206E3A000000000068004C08006E323C
+:1089000000006B0B9F010004686080BC0000740BCA
+:10891000000000181820009C000016138001008041
+:10892000A2802FB600006E0B120100E802C021B237
+:1089300018003600000000F8730A03F90000000078
+:10894000CA70001808006E320000670B0201008038
+:10895000626080BC000016139F000014184081BCA8
+:1089600000000000CA0100F802802F3500A0690B4A
+:1089700012010040A28D39B20000161300000080E1
+:10898000020000900000790B80000080A2802FB6CA
+:1089900000007C0B04000080A2A081BC0000161324
+:1089A0009F000014184081BC00000000CA0100F8BC
+:1089B00002802F3500A0161312000040A28D39B29C
+:1089C00000000000000000F8A2802F3500007C0BA2
+:1089D000120100E802C021B218003600000000F8C1
+:1089E000730A03F900000000002801E006000032CD
+:1089F00000000000003C00E806408132000000005A
+:108A0000003000E00680823200000000002000E01C
+:108A10000680813200000000001000E006C08632AF
+:108A200000000000001800E006C0843200001613A9
+:108A30000400008032E186B20000860B1F010008AE
+:108A4000090000B20000970B0420018002006EBCF8
+:108A500000001613000000800200009010000000CB
+:108A600000000010790B1638080000000000000C10
+:108A7000790B16380000000000000004A9002D3713
+:108A80000004010000000004C94D903A02000000FB
+:108A9000000000A8820D913700000000000000A82F
+:108AA00012A42A3A00008F0B80400280E2017CB6BB
+:108AB0000000161304400278B93F7CB000000000AB
+:108AC00000000008E9A5903A0000910B9F010010FA
+:108AD000190091BC9F000000000000100900363210
+:108AE00000008A0B0401008042E490BC00001613D1
+:108AF00004210180829B90BC0000970B0000008045
+:108B000002000090000000000010006C08006E32AF
+:108B1000000000000018004C08006E320000161320
+:108B20000400008032E186B200003210510000D80B
+:108B3000020000F200009A0B0050013CA85B809CF0
+:108B400000007F08003001E00600009200009F0B4B
+:108B50003E510100A81B80BA00000000DE0000F8B2
+:108B6000F2812F3400000000005801EC06C0EE3204
+:108B700000009F0B80010080328087B6000000005B
+:108B8000000000F8E2802F340000E310603001E0C4
+:108B9000060000F20000E90B0000008002000090D7
+:108BA0000000000000000014080000320000A90BC3
+:108BB000040201EC16C06EBC00000000C9010014E4
+:108BC0001840813A00000000C001013808C06E3230
+:108BD00000000000DF0000A4A8608A3C000016131B
+:108BE0000F000080020000B000C0AD0B1201004079
+:108BF000A28D39B200001613000000800200009020
+:108C000000000000003000E006000032000000001C
+:108C1000DF0000A4A8608A3C000016130F0000804B
+:108C2000020000B0000000000000013808C06E32F1
+:108C300000000000DEA8012099226E3A0000161301
+:108C400006010280821B92BC000016139F2001E0E7
+:108C500096226EBC0000B20B80000080F2802FB61E
+:108C60000000C70F00000080020000F00000B90BF8
+:108C70001F5001E8060000B20000B50B04000080A0
+:108C800002C083BC0000B90B005001E8F660809C74
+:108C90000800000000400278399AFE3800001613E0
+:108CA0000201008082BA97BC000016130601008002
+:108CB00092BA97BC0800000000400268129AFE3881
+:108CC0000000BE0B2AA901E0060092B2180036008F
+:108CD000CA0000F8730A03F91D00BE0B04000080EF
+:108CE00002A417B80000BA0B04000014184081BC9D
+:108CF00000001613000000800200009000006411C4
+:108D000000000030030038F20000C10B8001008039
+:108D100032802FB63E0016131200002C82CD2EB2E8
+:108D200000000000000000D80280013200C0D20B19
+:108D30001801000CA8CD3EB220800000C30000281E
+:108D40000980363200008111000000D8020000D2F4
+:108D50000000C70B04000080028092BC00000000ED
+:108D6000000000141840813A0000CC0B0400008081
+:108D7000024081BC18003600000000F8730A03F9B5
+:108D80000000D00B04000014184081BC0000C80B88
+:108D90001200000009C021B20000C90B00000080D1
+:108DA0000200009018003600000000F8738A03F9F2
+:108DB0000000641100000030030038F20000D00B06
+:108DC0008001008032802FB63E0016131200002C66
+:108DD00082CD2EB200000000C30000D80280013214
+:108DE00000C0CC0B1800000CA8CD3EB2000016133A
+:108DF0008000008072802FB60020008000000028D4
+:108E0000090037320000661200000008E80100F493
+:108E1000000016131200004802C080B200000000DB
+:108E2000000000141840813A0000161380010080F1
+:108E3000A2802FB618003600CA0000F8730A03F9A2
+:108E40001D0016130400008002A417B800001613BA
+:108E50009F000014184081BC0000D80B0B0100805B
+:108E6000020000B000004B1200000080020000F081
+:108E70000000E00B8001008092802FB62B00E60BF3
+:108E80001201002C82CD2EB20000161300000080CB
+:108E9000020000900000E30B1D010080020000B002
+:108EA0000000E60B8001008062812FB600001613DF
+:108EB00000000080020000900000E60B80000080AF
+:108EC00002812FB62A0016131200002C82CD2EB27A
+:108ED00000000000000000F802812F3400007D082F
+:108EE00004000080028085BC00005D12000000804C
+:108EF000020000F0000069060000001C0880859256
+:108F000000007F0880010080A2802FB600001613A9
+:108F10000000008002000090000016138000008016
+:108F2000E2802FB60000EE0B8001008082812FB618
+:108F3000000016130431018002006EBC00001613FD
+:108F400004310080829B82BC000016130201008065
+:108F500012A082BC00000000CE0100D802800132C5
+:108F600000C0F50B1801000CA8CD3EB22080000017
+:108F70000000000808803632000038120000005C53
+:108F80001FC0F5FA0000F30300000080020000900B
+:108F90000000161380000080A2802FB60000161378
+:108FA0008000008082802FB600001613040000802D
+:108FB000028082BC00000000600000D80200003285
+:108FC0000000FD0B3F00003C084080B20000FD0B9C
+:108FD00080010080E2812FB600000000DE0000F872
+:108FE000F2812F3400000000005801EC06C0EE3280
+:108FF000000000004D00000067E0833E000000001C
+:10900000000800000700803200000000001000008F
+:1090100007C08632000000000018000007C084323C
+:109020000000490C04000028D8A082BC00001613E0
+:1090300009010080020000B00000000000000018DC
+:10904000D8A0813C00001F0C0400003CD8E083BC89
+:109050000000161304010080028081BC0000090C8E
+:109060000400008072802DBC000016131200005016
+:1090700002C038B200001D0C510000D812802D9A99
+:109080000000161312000050F2C138B40000160C94
+:10909000280000D8020000B20000130C80010080FC
+:1090A000F2C185B600000F0C1F400284E60100B437
+:1090B0000000130C1D0100F822812FB40000130CD6
+:1090C000000000F862812F950000110C1D01008046
+:1090D000020000B000000000000000F862812F359F
+:1090E00000000000004002800240683200001613B9
+:1090F0001F010080020000B00000150C343000E0B9
+:1091000016206EBC0000B40F00000080020000F0CA
+:109110000000D50FDA5B01EC0640EDF218003600D6
+:10912000000000F8730A03F900001B0C0400008023
+:1091300072802DBC0000161380010080A2802FB623
+:109140000000160C670000F8A2802FB5000016136F
+:10915000120000E802C021B20000161304010080D2
+:1091600072802DBC00000000510000D802000032C7
+:1091700000003E1000000000D82080FA0000FE0B26
+:109180004D00000067E0839E00001613120000509F
+:10919000F2C138B400002C0C28000080084000B256
+:1091A0000000290C80010080F2C185B60000250C6A
+:1091B0001F400284E60100B40000290C1D0100F8E4
+:1091C00022812FB40000290C000000F862812F9545
+:1091D0000000270C1D010080020000B0000000000C
+:1091E000000000F862812F3500000000004002807E
+:1091F00002406832000016131F010080020000B018
+:1092000000002B0C343000E016206EBC0000B40FC0
+:1092100000000080020000F00000D50FDA5B01ECD6
+:109220000640EDF200004F0C80000080E2802FB677
+:109230000000300C042100E0068081B200003E10E6
+:1092400000000034080000F200000000002000E0F0
+:109250000680813200000000003C00E806408132B8
+:109260000000360C2A1100E0D6E086BA180036005D
+:10927000CA0000F8730A03F91D00360C04010080CF
+:1092800002A417B80000320C9F010080180088BCAF
+:1092900000001613000000800200009000004B1236
+:1092A00000000080020000F00000641100000030A7
+:1092B000030038F208003A0C231901E8762081B93E
+:1092C0003E0016131200002C82CD2EB200003E0C80
+:1092D0001D1800E006C084B200003E0C8000008033
+:1092E00002812FB62A0016131200002C82CD2EB256
+:1092F00000000000000000F802812F34000054102C
+:109300000000002CF90100F40000430C0400008070
+:10931000020088BC0000420C1201000009C021B20A
+:1093200018003600000000F8730A03F91D00161338
+:109330000401008002A417B8000016130401008085
+:10934000028080BC000000000000007809C5853064
+:10935000000016130201008082BA97BC00001613A9
+:109360000601008092BA97BC0000F6031201006863
+:1093700002C585B0000016130000008002000090B6
+:10938000000000000030007819206E3C0000161329
+:1093900004010080E2A582BC00001613800000805A
+:1093A000A2802FB60000161304010080020088BCC2
+:1093B0000000161304010080028080BC0000161318
+:1093C00012000050F2C138B400000000C0010138A2
+:1093D00008C06E320000530C040201EC16C06EBCD3
+:1093E00000C0161312000040A28D39B20000540CC8
+:1093F000C90100140800009200000000453000E0A0
+:10940000060000320000600C28000008E80100B4EB
+:1094100000005D0C80010080F2C185B60000590C8F
+:109420001F400284E60100B400005D0C1D0100F83D
+:1094300022812FB400005D0C000000F862812F959E
+:1094400000005B0C1D010080020000B00000000065
+:10945000000000F862812F3500000000004002800B
+:1094600002406832000016131F010080020000B0A5
+:1094700000005F0C8000008042812FB60000B40F16
+:1094800000000080020000F00000D50FDA5B01EC64
+:109490000640EDF200200080DF000028090037328E
+:1094A00000006612DE0000D8028001F208004B12B4
+:1094B000001801E8762081F90000641100000030F6
+:1094C000030038F20000660C8001008032802FB665
+:1094D0003E0016131200002C82CD2EB200006B0C41
+:1094E000290801E406C02DB20000700C1D000080A8
+:1094F000020000B00000700C8000008002812FB6D6
+:109500002A0016131200002C82CD2EB20000700C1F
+:10951000000000F802812F9400006D0C1201000081
+:1095200009C021B218003600000000F8730A03F9E0
+:109530001D006F0C0401008002A417B800006C0C21
+:10954000000000141840819C2B0016131200002C00
+:1095500082CD2EB2000055100000002CF90100F45D
+:109560000000730C04010080024081BC180036002A
+:10957000000000F8730A03F90000161312000048F7
+:1095800002C080B2000000000000007809C58530EC
+:10959000000016130201008082BA97BC0000161367
+:1095A0000601008092BA97BC0000F6031201006821
+:1095B00002C585B000001613000000800200009074
+:1095C000000016138000008082802FB60000161362
+:1095D00004310080829B82BC0000161302000080D0
+:1095E00012A082BC0000161304000080028082BC1E
+:1095F0002500000000000010090036321000801223
+:1096000000000014A96080D900000000000000D80C
+:109610000280013200C0840C1801000CA8CD3EB2BB
+:109620002080000000000008088036320000381258
+:109630000000005C1FC0F5FA0000F303000000808A
+:109640000200009000C00000000000F8A28D2F3141
+:1096500000000000000000D80200003200000000FE
+:1096600000000000078081320000000000080000B8
+:1096700007008032000000000010000007C08632A2
+:10968000000000000018000007C08432000016131C
+:1096900012000050F2C138B40000900C800000802D
+:1096A00082802FB60000000000000068A860803CA7
+:1096B000000000000000003C084080320000D40F91
+:1096C00000000004088082F20000910C12010000EA
+:1096D00009C021B218003600000000F8730A03F92F
+:1096E0001D00940C0400008002A417B8000016139B
+:1096F00080010080A2802FB60000900C000000F8CE
+:10970000A2802F9500000000000000006820803A31
+:1097100000009A0C0400002868A082BC0000161308
+:109720000C000080020000B00000161380000080D2
+:10973000E2802FB600003E1000000080020000F022
+:109740000000860C000000D80200009200001613F2
+:1097500080000080A2802FB600000000000000D82A
+:10976000028001320020008000000028090037320A
+:109770000000621200000008E80100F41800360042
+:10978000CA0000F8730A03F90000A50C040201ECFA
+:1097900016C06EBC00000000C00100F892802F349B
+:1097A00000C0A30C12010040A28D39B200001613B4
+:1097B00000000080020000902B00A50C1201002C7C
+:1097C00082CD2EB20000161300000080020000902F
+:1097D000000016131F010080020000B00000A80C5A
+:1097E0008001008082812FB60000161304310180B1
+:1097F00002006EBC00000000000000D802800132B0
+:109800000000AB0C12010060084023B20082B40CCF
+:1098100000000008A88D809200001613120000249A
+:10982000080023B2000016131200002008C023B263
+:109830000000161312000018088023B200C0C90CE3
+:109840001801000CA8CD3EB20000AE0C120000388A
+:10985000028081B2000016131200003C020082B2A6
+:109860000000161312000030024082B200001613EE
+:1098700012000034020086B22080000000000008C0
+:10988000A88D80320000BC0C80010080F2C185B63A
+:109890000000B80C1F400284E60100B40000BC0CBC
+:1098A0001D0100F822812FB40000BC0C000000F85C
+:1098B00062812F950000BA0C1D010080020000B0EB
+:1098C00000000000000000F862812F350000000059
+:1098D0000040028002406832000016131F01008021
+:1098E000020000B032000000000000100900363213
+:1098F0000000801200000014090080D2000016133E
+:109900001200006802C585B0000000000000007869
+:1099100009C58530000016130201008082BA97BC89
+:10992000000016130601008092BA97BC0000C40C18
+:109930003400005C1FC0F5BA0000B40F00000080C6
+:10994000020000F00000C60C8000008092802FB65C
+:1099500000007F08003000E00600009200007F0851
+:10996000120100E802C021B218000000000000F857
+:10997000730A03397F083600000000C002003692E7
+:1099800000000000450000D8024000320000000046
+:10999000410000000780863200000000000800003F
+:1099A00007008032000000000010000007408232F3
+:1099B00000000000001800000700863200001613A7
+:1099C00012000050F2C138B400000000000000781E
+:1099D000388087350000161380000080728087B6BB
+:1099E0000000000000A001E016206E3A0000000018
+:1099F0000000007809C585300000000000A801E0E3
+:109A000016206E3C08000000D2010078E9E5833999
+:109A1000180016131F410284E6A197B90000D90C63
+:109A2000365101E816E083BC0000D90C1D0100800E
+:109A3000020000B000000000000000F862812F3535
+:109A4000000016139F2001E0064080B20000DC0CED
+:109A50008001008082812FB600000000003001E00C
+:109A60000640803200000000000000D80280013271
+:109A70000000DF0C34180000078081B20000B40F32
+:109A800000000080020000F010004B1200300000C7
+:109A900017E02CF900100080003800000700373272
+:109AA0000000641100000030030038F20000E40CF4
+:109AB0008001008032802FB63E0016131200002C69
+:109AC00082CD2EB20000E90C29210000070082B2ED
+:109AD0000000E70C1201000009C021B21800360096
+:109AE000000000F8730A03F91D00EF0C0401008068
+:109AF00002A417B80000E50C000000140800009252
+:109B00000000EC0C1D3100E0060000B20000EF0C7C
+:109B10008001008062812FB60000161300000080D3
+:109B2000020000900000EF0C8000008002812FB640
+:109B30002A0016131200002C82CD2EB20000000065
+:109B4000000000F802812F3400005D120000002C9C
+:109B5000F90100F400005410000000F8A2802FF476
+:109B60000000F40C04000080024081BC0000F40CF2
+:109B7000120100E802C021B218003600000000F80F
+:109B8000730A03F90000F6031201004802C080B214
+:109B90000000161300000080020000900000FE0C80
+:109BA00080010080F2C185B60000FA0C1F400284DB
+:109BB000E60100B40000FE0C1D0100F822812FB464
+:109BC0000000FE0C000000F862812F950000FC0CE4
+:109BD0001D010080020000B000000000000000F83D
+:109BE00062812F3500000000004002800240683290
+:109BF000000016131F010080020000B00000000DDD
+:109C000004000080024086BC0000AB1200900108F6
+:109C100009006EF20000DF1200000080020000F078
+:109C20000000070D330100D8028001B20000070DCB
+:109C300080010080B20172B60000070D9FF0018024
+:109C400082DB87BC0000070D9FF8018022216EBCDB
+:109C50000000000000E801E00600EE320000000015
+:109C600000F001E006C0873208000000001801E89B
+:109C70007620813900000D0D80010080D2802FB642
+:109C800000000D0D04B0008002006EBC000000005A
+:109C9000CD0000F872812F343D000D0D1201002C13
+:109CA00082CD2EB20000161300000080020000904A
+:109CB00000001C0D270901E406C02DB200C0140DE0
+:109CC0001801000CA8CD3EB2000000000000007892
+:109CD00009C58530000016130201008082BA97BCC6
+:109CE000000016130601008092BA97BC00001613FC
+:109CF0001200006802C585B020807F0800000008BF
+:109D0000088036922C000000000000100900363256
+:109D1000000080120098011409006ED200000000BB
+:109D2000004001E00640883200000000D508000035
+:109D300007408832000000000030000007C02C32CD
+:109D400000400080CA3900000700373200001613B7
+:109D50001200004802C080B200600000000000084D
+:109D6000088036320000200D1D000080020000B087
+:109D70000000200D8000008002812FB62A001613FB
+:109D80001200002C82CD2EB200000000000000F86E
+:109D900002812F34000055100000002CF90100F45E
+:109DA000000000000000007809C58530000016138F
+:109DB0000201008082BA97BC0000161306010080E1
+:109DC00092BA97BC0000F6031201006802C585B084
+:109DD0000000161300000080020000900000000048
+:109DE000545401FC02C06E3200000000000000D894
+:109DF0000280013200C02C0D1801000CA8CD3EB22B
+:109E00002080000000000008088036320000F303C4
+:109E10001201002C72E02EB2000016130000008028
+:109E200002000090000016138001008082812FB68E
+:109E300000008C120020001808006EF200001613BB
+:109E40001F30002808006EB200000000000000A4CF
+:109E500008808232000000000010006C08006E32A2
+:109E6000000000000018004C08006E3200001613BD
+:109E70000400008032E186B2000032100000008051
+:109E8000020000F00000360D0050013CA85B809CF1
+:109E90000000161300000080020000900000000087
+:109EA00000500100A81B803A000000000000008064
+:109EB0000800003200000000510000D8020000320B
+:109EC000000000004D00000067E0833E000000003D
+:109ED00000080000070080320000000000100000B1
+:109EE00007C08632000000000018000007C084325E
+:109EF00000006D0D04000028D8A082BC00001613DD
+:109F000009010080020000B00000000000000018FD
+:109F1000D8A0813C0000540D0400003CD8E083BC74
+:109F20000000161304010080028081BC0000450D72
+:109F30000400008072802DBC000016131200005037
+:109F400002C038B200004D0D510000D812802D9A89
+:109F50000000161312000050F2C138B41800360089
+:109F6000000000F8730A03F900004B0D04000080A4
+:109F700072802DBC0000161380010080A2802FB6D5
+:109F80000000460D670000F8A2802FB500001613F0
+:109F9000120000E802C021B2000016130401008084
+:109FA00072802DBC00000000510000D80200003279
+:109FB0000000520D2A010000D82080BA0000510D87
+:109FC0001201000009C021B218003600000000F89C
+:109FD000730A03F900000000000000D80240843238
+:109FE0001D0016130400008002A417B800004610DC
+:109FF0000060006C08006EF200003A0D4D00000099
+:10A0000067E0839E0000161312000050F2C138B4BE
+:10A0100018003600000000F8730A03F91D005B0DFC
+:10A020000400008002A417B800001613800100800D
+:10A03000A2802FB60000550D670000F8A2802FB552
+:10A04000000016131200000009C021B21D001613F3
+:10A050000401008002A417B8080000000040027844
+:10A06000399AFE38000016130201008082BA97BCAC
+:10A07000000016130601008092BA97BC0800161360
+:10A0800012400268129AFEB8000016130B000080FE
+:10A09000020000B00000641100000030030038F23C
+:10A0A000000016131F00006CD8E086BA00003210C2
+:10A0B000510000D8020000F20000650D0000003CD5
+:10A0C00008408092000016130000008002000090FB
+:10A0D0000000390D04010080028081BC00006B0D7E
+:10A0E00080010080A2802FB600006A0D12010000DE
+:10A0F00009C021B218003600000000F8730A03F905
+:10A1000000000000000000D8024084321D00161339
+:10A110000400008002A417B8000046100060006C24
+:10A1200008006EF200003A0D4D00000067E0839ECB
+:10A130000000161380000080A2802FB600000000EF
+:10A14000C001013808C06E3200000000453000E058
+:10A15000060000320000161312000050F2C138B49D
+:10A160000000750D040201EC16C06EBC000000007A
+:10A17000C90100141840813A00C0750D1201004059
+:10A18000A28D39B20000161300000080020000907A
+:10A1900000C00000000000F8A28D2F310000000078
+:10A1A00000A8012099226E3A0000161306010280D1
+:10A1B000821B92BC000016139F2001E096226EBC09
+:10A1C00000007B0D80000080F2802FB60000C70FDA
+:10A1D00000000080020000F000007F0D0400003C41
+:10A1E000D8E083BC00007E0D9F3101E096226EBC5A
+:10A1F00000000000003001E0060000320000860D83
+:10A20000005001E8F660809C0800000000400278E1
+:10A21000399AFE38000016130201008082BA97BCFA
+:10A22000000016130601008092BA97BC08000000D7
+:10A2300000400268129AFE380000850D9F3101E04F
+:10A2400096226EBC00000000003001E006000032E3
+:10A2500000000000005001E806000032000000008D
+:10A2600000A801E00600923218003600000000F855
+:10A27000730A03F91D008B0D0400008002A417B8B7
+:10A280000000870D04000014184081BC0000161364
+:10A290000000008002000090000016138000008083
+:10A2A00072802FB600000000000000D8028001324A
+:10A2B00000200080000000280900373200006612EC
+:10A2C00000000008E80100F4000016131200004826
+:10A2D00002C080B20000641100000030030038F2B8
+:10A2E0000000930D23010014184081BA3E0016139C
+:10A2F0001200002C82CD2EB20000161380010080C7
+:10A30000A2802FB618003600CA0000F8730A03F9BD
+:10A310001D0016130400008002A417B800001613D5
+:10A320009F000014184081BC0000940D0B010080B8
+:10A33000020000B000004B1200000080020000F09C
+:10A3400000009C0D2931010C09006EB22B007D0824
+:10A350001201002C82CD2EB20000161300000080E6
+:10A36000020000900000BE0F000C020009806EF297
+:10A370000000A50D000000800200009000005D12AA
+:10A3800000000080020000F0000000000000001C3F
+:10A39000080090320000A40D04000028098080B25B
+:10A3A00000008111000000D8020000D20000A40DBE
+:10A3B00004000080028092BC18003600000000F803
+:10A3C000730A03F900006806000000080800009204
+:10A3D0000000A80D1D010080020000B000007D08F3
+:10A3E0008001008062812FB60000161300000080FB
+:10A3F0000200009000007D088000008002812FB6DE
+:10A400002A0016131200002C82CD2EB200007D0807
+:10A41000000000F802812F940000161380010080D4
+:10A4200082812FB60000161304000018094081B283
+:10A430000000E30F00000080020000F00000C70FE2
+:10A4400000A8012009006EF2000000000030010C9D
+:10A4500009006E320000BE0F000C020009806EF28F
+:10A4600000007F08000000800200009000004B12F6
+:10A4700000000080020000F000005D12000000807B
+:10A48000020000F0000068060000001C0800909226
+:10A4900000000000545401FC02C06E32000016138C
+:10A4A0008001008082812FB6000016131F000080FB
+:10A4B000020000B010000000000000A8780B163861
+:10A4C00008000000000000AC780B16380000000007
+:10A4D000000000B0A8002D3700040100000000B00B
+:10A4E000C80D8B3A00000000005001B408806E32A5
+:10A4F0000000C70D0431019008006EB20200000098
+:10A50000000000C8828D8A3700000000000000C8EB
+:10A51000C2A22C3A1800C50D86410278880D78B683
+:10A520000000161304000080A2E28ABC000016138B
+:10A5300004410280B23F78B00000BE0D9F0100A828
+:10A5400018808ABC9F00BE0D000000A8080036924B
+:10A550000000000000400204B83F78300000DA0D2F
+:10A5600000000004D862809C00001613020C0280D8
+:10A57000A21B89BC000016138000008082802FB6C9
+:10A5800002000000000000C8828D8A370000000031
+:10A59000000000C8C2A22C3A1800D00D86410278F3
+:10A5A000880D78B60000161304000080A2E28ABC71
+:10A5B0000000161304410280B23F78B00000C90DBC
+:10A5C0009F0100A818808ABC9F00C90D000000A848
+:10A5D000080036920000D30D28400204B83F78B03E
+:10A5E00000000000C8010004D862803C000016137F
+:10A5F0009F000080024080B20000D70D0201009051
+:10A60000182089BC00000000000000B408000032DF
+:10A610000000C90D9F0100A818808ABC9F00C90DC9
+:10A62000000000A8080036920000DA0D0400009037
+:10A63000182089BA000016139F000004486280BCED
+:10A6400000001613900000B448628BBA0300161382
+:10A6500004400200081EFFB80000E20D00000000E8
+:10A66000D822809A0000090E04000080A2E28ABC71
+:10A6700002000000000000C8828D8A370000000040
+:10A68000000000C8C2A22C3A1800070E86400278CB
+:10A69000880D78B60000161304400204B83F78B065
+:10A6A0000300161304400200081EFFB83800000023
+:10A6B0000000001009003632000080120000001473
+:10A6C000090080D20000E80D12010060084023B2AA
+:10A6D0000082000000000008088036320000F3030A
+:10A6E0001201002C72E02EB2000016130000008050
+:10A6F000020000900000161312000024080023B28C
+:10A70000000016131200002008C023B20000161328
+:10A7100012000018088023B200000000000000D8DA
+:10A720000280013200C0F20D1801000CA8CD3EB22B
+:10A730000000EC0D12000038028081B200001613F8
+:10A740001200003C020082B200001613120000301A
+:10A75000024082B20000161312000034020086B2DA
+:10A760002080E60D000000080880369200000000FE
+:10A77000000000D802000032000000000038020093
+:10A78000B81B803A00000000643001E016206E3AE9
+:10A7900000000000000000000740803200000000C0
+:10A7A00000080000070080320000000000100000D8
+:10A7B00007408232000000000018000007008632C7
+:10A7C0000000161312000050F2C138B4000000005F
+:10A7D000000000D8028001320000000000180000D4
+:10A7E0000780813200000000002000000700823254
+:10A7F000100000000030000017E02C3900000000BD
+:10A8000000380000F7010B340000010E80010080C9
+:10A81000328087B60000000000380000B7017034B5
+:10A820000000000000000008E80100340000130EE2
+:10A83000020C0280A21B89BC18003600000000F840
+:10A84000730A03F90000641100000030030038F2BD
+:10A85000000016131200004802C080B21800360033
+:10A86000000000F8730A03F90000DC0D9F0100A846
+:10A8700018808ABC9F00DC0D000000A808003692FA
+:10A8800028000C0E0401008082CD81BC0000000075
+:10A890000020017809006E320000161304010080C8
+:10A8A00042A297BC00000E0E8001008032802FB6BD
+:10A8B0003E0016131200002C82CD2EB20000100EA6
+:10A8C0001D010080020000B000007D08000000F8BB
+:10A8D00062812F9500007D088000008002812FB6E4
+:10A8E0002A0016131200002C82CD2EB200007D0823
+:10A8F000000000F802812F940000000000380000E2
+:10A90000C70170340000641100000030030038F209
+:10A910000800170E231901E8762081B93E001613AE
+:10A920001200002C82CD2EB20000190E1D010080F5
+:10A93000020000B000001C0E000000F862812F959C
+:10A9400000001C0E8000008002812FB62A00161322
+:10A950001200002C82CD2EB200000000000000F892
+:10A9600002812F340000161380000080A2802FB6D1
+:10A97000000054100000002CF90100F40000200E2B
+:10A98000120100E802C021B218003600000000F8F1
+:10A99000730A03F9000016131200004802C080B2C7
+:10A9A0000000F603000000F8A2802F9400000000D1
+:10A9B000000000D8028001320000000000300028B2
+:10A9C00008006E3200000000545401FC02C06E32D8
+:10A9D00000C02E0E1801000CA8CD3EB22080000051
+:10A9E000000000280980363200008111000000D8E4
+:10A9F000020000D200002B0E04000080028092BCF6
+:10AA000018000000000000F8730A03392C0E36000D
+:10AA1000000000C00200369218003600000000F866
+:10AA2000738A03F900000000000000D802800132A0
+:10AA300000C02B0E1800000CA8CD3EB200200084F0
+:10AA400000000028090037320000621200000008F0
+:10AA5000E80100F400007D08000000800200009082
+:10AA600000000000000000D8028001320000000059
+:10AA7000545401FC02C06E3200C0370E1801000CA5
+:10AA8000A8CD3EB2208000000000000808803632C9
+:10AA90000000EF031201002C72E02EB2000016132A
+:10AAA00000000080020000900000F3110000002868
+:10AAB000090002F200003F0E0000005C0800009256
+:10AAC00000000000000000D80280013200000000F9
+:10AAD000545401FC02C06E3200C03F0E1801000C3D
+:10AAE000A8CD3EB220800000000000080880363269
+:10AAF000000038120000005C1FC0F5FA0000F303EC
+:10AB000000000080020000900000000000300028DB
+:10AB100008006E320020008400000028090037324F
+:10AB20000000621200000008E80100F40000440E7A
+:10AB300000000080020000900000000000000008FB
+:10AB40000800003200004A0E0400008002C085B2F6
+:10AB500000004A0E80000080F2C185B60000490E58
+:10AB60001C41028006C085B20000000000000068A1
+:10AB700002C5853000000000000000701F00F73A99
+:10AB800000000000000000F822812F340000D00EE9
+:10AB900080010080A2802FB618000000000000F89D
+:10ABA000730A0339D00E3600CA0000C00200369284
+:10ABB0000000990E8001008082812FB60000A10E56
+:10ABC0001F20010809006EB20000990E0430010830
+:10ABD000899B90BC0000560E0431018002006EBCBF
+:10ABE0000000321000000080020000F00000540E4F
+:10ABF0000050014808806E9200001613000000808B
+:10AC00000200009000000000000000042861803C69
+:10AC100000006B0E000000002821809A000016132F
+:10AC20009F000080028090B2000032100030014886
+:10AC300008006EF200005A0E00500104A85B809CD0
+:10AC400000001613000000800200009000000000C9
+:10AC500000500100A81B803A0000680E0700004861
+:10AC600018A084BC0800000000400200189AFE38BA
+:10AC70000000161302010080823A80BC0000161307
+:10AC800006010080923A80BC0000000000000068CD
+:10AC9000020080320000321000000080020000F04C
+:10ACA0000000630E000000800200009000001613F8
+:10ACB00000000080020000900000680E07000048BD
+:10ACC00018A084BC0800000000400200189AFE385A
+:10ACD0000000161302010080823A80BC00001613A7
+:10ACE00006010080923A80BC0000600E00000068FF
+:10ACF0000200809200006B0E0400004818A084BA85
+:10AD0000000016139F000004286180BC00000000B2
+:10AD1000000000002821803A00000000005401FCDF
+:10AD200002C06E320000740E12010060084023B2AF
+:10AD300000820000D6010008088036320300161396
+:10AD400004400200381AFFB8030000000000007839
+:10AD50000960803918000000D241028CE6A19739C1
+:10AD600000000000005001E8068084322900F3034F
+:10AD70001201002C82CD2EB20000161300000080BC
+:10AD8000020000900000161312000024080023B2F5
+:10AD9000000016131200002008C023B20000161392
+:10ADA00012000018088023B200000000000000D844
+:10ADB0000280013200C07F0E1801000CA8CD3EB207
+:10ADC00020800000D6010008088036320000790E8D
+:10ADD00012000038028081B2000016131200003CFD
+:10ADE000020082B20000161312000030024082B24C
+:10ADF00000006E0E12010034020086B2000016132D
+:10AE00000000008002000090080000000040025C8A
+:10AE1000189AFE38000000000000004808000032C8
+:10AE200000000000000000D8020000320000000016
+:10AE30000000000007408032000000000008000011
+:10AE4000070080320000000000100000074082323E
+:10AE500000000000001800000700863200001613F2
+:10AE600012000050F2C138B400000000D60100D832
+:10AE700002800132000000000018000007808132CB
+:10AE800000000000002000000700823210000000D7
+:10AE90000030000017E02C3900008E0E800000808A
+:10AEA000328087B60010008000380000070037327B
+:10AEB00000008F0E0000008002000090001000884B
+:10AEC000003800000700373218003600000000F894
+:10AED000730A03F9000000000000006802C0853218
+:10AEE000000016130201008082FA85BC00001613D0
+:10AEF0000601008092FA85BC0000000000000008F6
+:10AF0000E8010034000016131200004802C080B2AD
+:10AF100018003600000000F8730A03F90000321030
+:10AF200000000080020000F000006B0E00000080B6
+:10AF3000020000900000A10E0000008002000090BE
+:10AF40000000321000000080020000F000009C0EA3
+:10AF500000380200B81B809C0000A10E0000008099
+:10AF600002000090050000000000006802A0FE380A
+:10AF7000050000000000007809A0FE38000016134C
+:10AF80000201008082BA97BC0000161306010080FF
+:10AF900092BA97BC0000990E00400280024068926D
+:10AFA00000000000CA0100D8020000320000A50E17
+:10AFB00004B8018002006EBC000016139FB801782F
+:10AFC000891BEEBC0000000000B801E0861BEE3CCF
+:10AFD0004C000000000000000700363200000000B6
+:10AFE00000000078A9002D37B4040100000800001B
+:10AFF000C78D973A000000000000007899C02C37F8
+:10B00000B400000000000078898D973A0000161304
+:10B010000210000087BF97BA00000000001800006F
+:10B020000740FE320000161312000048F2C138B487
+:10B030000000AD0EB6000080020000B00020161324
+:10B0400012000064A2CD2CB200000000A600008017
+:10B05000020000300000B20E80010080A2802FB6F6
+:10B0600018003600CA0000F8730A03F900007D08D2
+:10B07000005401FC02C06E92000016138001008093
+:10B0800062812FB6000016138001008082812FB6E6
+:10B09000000016131F000080020000B00000000036
+:10B0A000005401FC02C06E320000BB0E12010060B1
+:10B0B000084023B2008200000000000808803632F9
+:10B0C0002900F3031201002C82CD2EB200001613CA
+:10B0D00000000080020000900000161312000024FF
+:10B0E000080023B2000016131200002008C023B28B
+:10B0F0000000161312000018088023B200000000A0
+:10B10000000000D80280013200C0C60E1801000CF9
+:10B11000A8CD3EB220800000000000080880363232
+:10B120000000C00E12000038028081B20000161329
+:10B130001200003C020082B2000016131200003020
+:10B14000024082B20000B90E12010034020086B241
+:10B150000000161300000080020000900000321072
+:10B1600000000048080000F20800C90E0040025C20
+:10B17000189AFE980000161300000080020000904C
+:10B180000000000000500100A81B803A0000810E62
+:10B190000000004808000092000016131F01008004
+:10B1A000020000B000000000005401FC02C06E323A
+:10B1B0000000F31100000028098002F20000AD0E2B
+:10B1C00000000080020000900000F3110000002841
+:10B1D000090002F20000D30E9A0100F862812FB438
+:10B1E00010240000000000F8A28D2F3100000000A4
+:10B1F00000D601EC06C06E342E007D081201002C32
+:10B2000082CD2EB2000016130000008002000090D4
+:10B210000000161304A9018002006EB20000DE0EC9
+:10B2200080010080F2C185B60000DA0E1F40028462
+:10B23000E60100B40000DE0E1D0100F822812FB4EB
+:10B240000000DE0E000000F862812F950000DC0E89
+:10B250001D010080020000B000000000000000F8A6
+:10B2600062812F35000000000040028002406832F9
+:10B27000000016131F010080020000B00000E00E65
+:10B2800004980164881B87BC0000AB120090010881
+:10B2900009006EF20000DF1200000080020000F0E2
+:10B2A000000000000000007809C58530000016137A
+:10B2B0000201008082BA97BC0000161306010080CC
+:10B2C00092BA97BC000016131200006802C585B040
+:10B2D00000000000000000F8D2802F3500007F0839
+:10B2E000370000F8D2812FB400000000000000F801
+:10B2F00072812F343D007F081201002C82CD2EB2C6
+:10B300000000161300000080020000900000F20E02
+:10B3100080010080F2C185B60000EE0E1F4002845D
+:10B32000E60100B40000F20E1D0100F822812FB4E6
+:10B330000000F20E000000F862812F950000F00E70
+:10B340001D010080020000B000000000000000F8B5
+:10B3500062812F3500000000004002800240683208
+:10B36000000016131F010080020000B00000000062
+:10B3700000D401EC16C06E3A000000000000007816
+:10B3800009C58530000016130201008082BA97BCFF
+:10B39000000016130601008092BA97BC0000161335
+:10B3A0001200006802C585B000007F0804B000806C
+:10B3B00002006EBC37007F081201002C82CD2EB235
+:10B3C0000000161300000080020000900000020F31
+:10B3D00080010080F2C185B60000FE0E1F4002848D
+:10B3E000E60100B40000020F1D0100F822812FB415
+:10B3F0000000020F000000F862812F950000000F8E
+:10B400001D010080020000B000000000000000F8F4
+:10B4100062812F3500000000004002800240683247
+:10B42000000016131F010080020000B000000F0F83
+:10B43000000000800200009000000B0F80010080DF
+:10B44000F2C185B60000070F1F400284E60100B478
+:10B4500000000B0F1D0100F822812FB400000B0F1C
+:10B46000000000F862812F950000090F1D01008087
+:10B47000020000B000000000000000F862812F35DB
+:10B4800000000000004002800240683200001613F5
+:10B490001F010080020000B000000F0F370000F80D
+:10B4A000D2812FB400000000000000F872812F3418
+:10B4B0003D000F0F1201002C82CD2EB2000016139A
+:10B4C00000000080020000900000000000D401ECA9
+:10B4D00006000032000000000000007809C5853039
+:10B4E000000016130201008082BA97BC00001613F8
+:10B4F0000601008092BA97BC00007F081201006824
+:10B5000002C585B000001613000000800200009004
+:10B5100000007D0880010080F2812FB600007D08C8
+:10B5200080000080E2812FB60000190F80000080AB
+:10B5300002812FB6000016131D010080020000B02A
+:10B54000000016130458018002C06EBC00007D0884
+:10B55000085901EC06FB6EBC00000000000000D89A
+:10B560000280013200000000545401FC02C06E321F
+:10B5700000C0220F1801000CA8CD3EB20000000050
+:10B58000005801EC06FB6E3A208000000000000825
+:10B59000088036320000EF031201002C72E02EB258
+:10B5A00000001613000000800200009000005D12F1
+:10B5B000000000F8E2812FF40000250F060301804F
+:10B5C00012C06EBC190068060000001C080036920C
+:10B5D0001A0068060000001C0800369200001613CE
+:10B5E00080010080F2812FB60000161380010080D8
+:10B5F000E2812FB60000161304550180B2DB2FBC88
+:10B6000000C00000000000F8A28D2F3100000000F3
+:10B61000000000D802800132002000C00000002895
+:10B6200009003732000000000030002808006E32A8
+:10B6300000000000453000E0060000320000621209
+:10B6400000000008E80100F40000340F040201ECDF
+:10B6500016C06EBC00000000C90100141840813AF9
+:10B6600000000000000000F802802F3400C0340FFA
+:10B6700012010040A28D39B20000161300000080B4
+:10B680000200009018003600CA0000F8730A03F99F
+:10B690000000340F9F010014184081BC00007F0897
+:10B6A0008001008092802FB62B007F081201002CB1
+:10B6B00082CD2EB200001613000000800200009020
+:10B6C000000016131F0100D8028001B20000000024
+:10B6D000005401FC02C06E3200C0440F1801000C7F
+:10B6E000A8CD3EB22080000000000028098036323C
+:10B6F00000008111000000D8020000D20000410FBC
+:10B7000004000080028092BC18000000000000F8D5
+:10B71000730A0339420F3600000000C0020036925F
+:10B7200018003600000000F8738A03F900000000DA
+:10B73000000000D80280013200C0410F1800000C48
+:10B74000A8CD3EB200005D12000000D8024000F219
+:10B7500000F04C0F1D400200A80D68B10000161348
+:10B760000B000080020000B0000016131E4002848F
+:10B77000060000B200004A0F12000028020580B047
+:10B780000800450F000000F8234001990000450F14
+:10B7900012010068020580B000001613000000804E
+:10B7A0000200009000004C0FB5000080020000B0C5
+:10B7B00000000000A50080A0360B6A3500000000E4
+:10B7C0000000005009C02932000000000056012886
+:10B7D00008C06E320000000000000078390B2E32E5
+:10B7E0000000000000000020F38197340000560F95
+:10B7F00004000078D90130B600001613040100805F
+:10B80000328097BC0000000000000000B905303015
+:10B8100018000000000000F803A403390000000035
+:10B8200000000034330B2F3200006F0F040000784B
+:10B83000D90130B60000161304010080328097BC95
+:10B840000000000000000078B905303000005D0FF6
+:10B850000400008042E529BC00000000000000F860
+:10B860000200003218000000000000F8738A02395C
+:10B87000000000000000009C028097320A000000D7
+:10B880000000001009003632000080120000001491
+:10B8900009C029D20000690F25010008080000B284
+:10B8A0000000161380000080F20180B60000000046
+:10B8B0000000002C090580300000161302010080F2
+:10B8C00082FA92BC000016130601008092FA92BC24
+:10B8D0000000670F12000028020580B00800690F01
+:10B8E000000000F8234001990000690F1201006870
+:10B8F000020580B0000016130000008002000090D6
+:10B9000000006D0F0400008002402FBC000000000A
+:10B910000000007809002C32210316130400008077
+:10B92000828D97BC9603161304000080828D97BC0D
+:10B930000000161380000080A2802FB60000560F72
+:10B94000000000F4020000920000730F0400008069
+:10B9500042E529BC00000000000000F802000032AF
+:10B9600018000000000000F8738A0239000000008F
+:10B970000000009C0200953200000000CA0100D8BF
+:10B9800002800132000000000030000007C02C32AD
+:10B99000001000A00038000007003732000000004F
+:10B9A000002000000700EE32000000000038000C0C
+:10B9B00007808232000016131200004802C080B2D5
+:10B9C0000000F60300000008E80100940000930F57
+:10B9D00002000080A24280BC0000930F8000008023
+:10B9E000F2C185B60000930F1F400208B9BF68B0CE
+:10B9F0000000830F80410280E28168B608000000E9
+:10BA00000000001079618039000016139F2001E0CA
+:10BA100016206EBA00000000000000F822812F34CA
+:10BA20001800000000400288E62191390000000063
+:10BA30000001005C08000072000000000000000C23
+:10BA400019A0903A0000930F06010080D2FF90BC2D
+:10BA50000000870F2C410278F98168B400000000D3
+:10BA600000000078B9819734010000000000001048
+:10BA700009003632000080120000001459C085D73A
+:10BA80000300000000400200291AFF3800000000F7
+:10BA900000380200B91B903A00000000D241028831
+:10BAA00016A0973A00000000450000D8024000327E
+:10BAB000000016139F2001E016206EBA000000005F
+:10BAC0000000000007408032000000000008000075
+:10BAD0002724903A000000000010000007008A327E
+:10BAE0000000000012010058F2C138740000161363
+:10BAF00000000080020000900800A20F1A0000342D
+:10BB0000796180B90000AE0F1E010080020000B014
+:10BB10000000AE0F1F400200094068B20000950F00
+:10BB200080000080E20190B6000016133800005437
+:10BB30001F40F5BA0000000000000008B93F903037
+:10BB400000000000002801E026246E3A08001613C9
+:10BB50001E00000009A4FEB83D0000000000001017
+:10BB6000090036320000801200000014090090D253
+:10BB70000000000000000078090590300000161356
+:10BB80000201008082BA97BC0000161306010080F3
+:10BB900092BA97BC0000AE0F12010068020590B087
+:10BBA0000000161300000080020000900000AE0F9D
+:10BBB0008000008082812FB60000AC0F1F41020080
+:10BBC000094068B200000000002801E016206E3A2B
+:10BBD0000000A80F80010080F2C185B600000000BF
+:10BBE00000400284E60100340000000000000080F4
+:10BBF0000200003000000000004002800240683275
+:10BC000000001613380000541F40F5BA0000161348
+:10BC10009F2001E016206EBA0000000000010080A5
+:10BC2000020000700000A30F80000080E20190B6C7
+:10BC30000000970F000000541F40F59A000000001C
+:10BC40000000005C08000032000016139F2001E095
+:10BC500016206EBA00000000000000F822812F3488
+:10BC6000180000001E410284E6619379000016135B
+:10BC700000000080020000900000FFFF0000008034
+:10BC8000020000900000B90F1D5D01EC16C06EBCF3
+:10BC9000000000000F010080020000700000161379
+:10BCA000045D018002C06EBC00001613800000809D
+:10BCB00042812FB600000000000100F8B2802F740E
+:10BCC000000000000F010080020000700000B70FAC
+:10BCD000045E01EC16C06EBC00000000005C01ECCC
+:10BCE00006400032000000000001008002000070E9
+:10BCF0000000FFFF00000080020000900000000034
+:10BD00000420018082DB907C000016130420018057
+:10BD100002006EBC000016131F000080020000B07D
+:10BD200000000000020C0280A2DB907C0000C40F27
+:10BD300006210180821B90BC2700C50F0000000077
+:10BD40000900369228000000000000000900363289
+:10BD5000000000000000008812002C3A0000FFFFE5
+:10BD600000000080020000900600000000000010AB
+:10BD7000090036320000801200000014090092D23F
+:10BD80000000161304000080020092BC00000000B6
+:10BD90002FA00178891B927A0000000006880178A4
+:10BDA000899B977C000000000034020409C06E3DAE
+:10BDB00000000000000C020019A46E370000D20F32
+:10BDC0000200008002A497BC0000D20F0200008095
+:10BDD000020000B00100000000000078898D973754
+:10BDE0000000000002010280829B977C000000009E
+:10BDF000000100F8F2802F740000FFFF00000080B7
+:10BE00000200009000000000DA5B01EC0640ED3219
+:10BE10002D000000000000100900363200008012E2
+:10BE2000005C011409806ED20000DA0F040100806A
+:10BE3000024086BC0000000000A001E016206E3A1F
+:10BE40000000DC0F00D401EC060000920000AB12F1
+:10BE50000090010809006EF20000000000A001E05F
+:10BE600016206E3A0000DF12330100F882802FB4F2
+:10BE70000000DF129FF0018082DB87BC0000DF1230
+:10BE80009FF8018022216EBC0000000000E801E064
+:10BE90000600EE320000000000F001E006C087322C
+:10BEA0000000DF1200000080020000900000FFFF91
+:10BEB00000000080020000900000161308000080BF
+:10BEC000028091BC11000000000000100900363211
+:10BED0001000801200500114A99B91D91500000098
+:10BEE000000000100900363210000000002001148C
+:10BEF000890D6E370000801200300114895B91D2E9
+:10BF00001A00000000000010090036320000801204
+:10BF10000000001409C02DD2000016130621018074
+:10BF2000829B91BC0000000000A8017809006E32DD
+:10BF30000000161306010280829B97BC00000110CE
+:10BF40000421013069246EBC000000000050010093
+:10BF5000A99B913A0000F90F1F400224094068B2E2
+:10BF60000000F00F80000080E24192B60000000067
+:10BF700000000008B97F92300000000000000000BF
+:10BF80002924903C080000000000007899A4FE38A5
+:10BF9000000016130201008082BA97BC000016133D
+:10BFA0000601008092BA97BC0800F00F12010068E9
+:10BFB00092A4FEB80000161300000080020000905A
+:10BFC0000000161304290180821B90BC00000000B1
+:10BFD00000A801E066246E3A000016139F2001E0DD
+:10BFE000060093B20000FE0F8000008082812FB611
+:10BFF0000000FF0F002801E0060000920000000092
+:10C00000003001E00600003200000000005001E8AE
+:10C0100006000032000000000001008002000070F5
+:10C020000000071038510100A99B91BA00000510CB
+:10C0300004410208B9FF68B0000016138041028075
+:10C04000E2C168B60000021000400280024068921F
+:10C05000000014109F3101E066246EBC0000141033
+:10C06000003001E0060000920000111004280104D5
+:10C0700009006EB20000161306500180A25B90BC4E
+:10C0800000000F109F010000192490BC0000000068
+:10C0900000A801E066246E3A00000000002801E0DC
+:10C0A0000624003C00000000005001E806000032B9
+:10C0B000000016139F2001E0060093B2000000006C
+:10C0C000000100800200007000000000002801E074
+:10C0D0000600003200001D1004000080020090BC29
+:10C0E0000000141004410208B9FF68B000001613E4
+:10C0F00080410280E2C168B6000011100040028059
+:10C10000024068920000181002000080222490BCB7
+:10C1100000001D1080400280F2C168B600000000DF
+:10C120000040028CB6C1683500001D10000000F808
+:10C1300022812F940800000000400278399AFE38CE
+:10C14000000016130201008082BA97BC000016138B
+:10C150000601008092BA97BC0800161312400268CC
+:10C16000129AFEB80000111004010000292490BCAE
+:10C17000000000000000000809000032100000006C
+:10C1800000000010790B1638080000000000000CB9
+:10C19000790B1638000016130400008042E490BCAE
+:10C1A0000000000000000004A9002D370004010079
+:10C1B00000000004C94D903A02000000000000A8F1
+:10C1C000820D913700000000000000A812A42A3A56
+:10C1D0000000281080400280E2017CB600001613A7
+:10C1E00004400278B93F7CB0000000000000000865
+:10C1F000E9A5903A00002A109F010010190091BC97
+:10C200009F000000000000100900363200002310DB
+:10C210000401008042E490BC0000000000000078AF
+:10C22000C924903A000016130401008022A497BC90
+:10C230000000000000A801E066246E3A0000000043
+:10C24000005001E806009032000016139F2001E024
+:10C25000060093B2000000000001008002000070A0
+:10C260000000FFFF00000080020000901800341062
+:10C270001F41027888CD68B60000000000000088E9
+:10C2800012002C3A0000371080010080628087B6CF
+:10C290000000161304410280B2FF68B000003210A3
+:10C2A000004002800240689203001613044002001E
+:10C2B000381AFFB8000016131F400204B8FF68B018
+:10C2C0000000000000380200B81B803A2E00000079
+:10C2D0000000001009003632000080120000001437
+:10C2E000090080D200000000000100800200007000
+:10C2F0000000FFFF000000800200009000004510D9
+:10C3000080010080A2802FB60000421012010000C0
+:10C3100009C021B218003600000000F8730A03F9C2
+:10C3200000000000000000D8024084321D004510CB
+:10C330000401008002A417B800003F109F01008094
+:10C34000180088BC00001613000000800200009056
+:10C35000000000000060006C08006E320000000069
+:10C36000CA68004C08006E320000161304700018F2
+:10C3700008006EB2200000000000001009003632F4
+:10C380001000801200000014A96081D90000000094
+:10C3900004000080A2A0817C000016130D01008023
+:10C3A000020000B000004F1080010080E2802FB634
+:10C3B00000004F101B000080020000B000000000D1
+:10C3C0000600008062E0837C000016139F000014CA
+:10C3D000184081BC00000000CA0100F802802F351F
+:10C3E00000A0000012010040A28D39720000161357
+:10C3F00000000080020000900000FFFF00000080AD
+:10C400000200009000000000000801E406C02D3288
+:10C41000EEFF0000001001E0868D2F3100000000CB
+:10C420000000001CB3E4393200005B100400007807
+:10C43000D90130B60000161304010080328097BC89
+:10C440000000000000000078B9053030180000003E
+:10C45000000000F8E3A503390000000000000034EC
+:10C46000330B2F320000000004000078D901307631
+:10C470000000161304010080328097BC0000000009
+:10C4800000000078B905303018000000000100F805
+:10C49000E3A503790000FFFF000000800200009088
+:10C4A000000016130401008002002DBC00001613CA
+:10C4B0000401008002802DBC00000000000000CCC0
+:10C4C00002000032000066102000012C09C06EB28C
+:10C4D00000006710001686CC06C092920000000093
+:10C4E000001486CC06C09232000000001201004009
+:10C4F000628E92520000161300000080020000902D
+:10C500000000FFFF000000800200009000006D109E
+:10C5100004000078D90130B6000016130401008031
+:10C52000428097BC6D103600000000C002003692B9
+:10C530006000161304010080828D2FB100000000FE
+:10C54000000000140300383200000000000000E08A
+:10C55000020030320000B91004000024D80130B6C7
+:10C560007210000000000088824D823A000016130D
+:10C570000000008002000090000016130000008000
+:10C5800002000090000016130000008002000090DE
+:10C590000000161300000080020000906D103600AD
+:10C5A000000000C00200369200009E1000000080D3
+:10C5B0000200009000007A10000000204805309032
+:10C5C000000016130000008002000090000086109A
+:10C5D000921101BC08006EB200000000000801DCEE
+:10C5E00002406E3200007E101F1101E026C18BB5A3
+:10C5F000000086101D000080020000B00000000056
+:10C60000000000D80200003280020000000000009C
+:10C61000070036320000000000000078A9002D3726
+:10C620002005010000080000C78D973A0A000000AD
+:10C6300000000078890D8237000000000010000023
+:10C64000A7BA973A000000000018000007C0EA32BD
+:10C65000000016131200004802C038B200008A1011
+:10C66000800E01BC08C06EB2000000000000000097
+:10C67000190E823200E0921012010048A20D90B211
+:10C68000000016130000008002000090000000006F
+:10C69000000000D802400032B4000000000000009A
+:10C6A000070036320000000000000078A9002D3796
+:10C6B0000004010000080000C78D973A0000000048
+:10C6C0000000007899008237000016130210000065
+:10C6D00087BF97BA00000000001800000740FE3234
+:10C6E0000000161312000048F2C138B418003600DA
+:10C6F000000000F8730A03F90000000000000004C5
+:10C70000896038321D0000000000007809A4173845
+:10C71000000098108000008002C08BB600009910C5
+:10C7200004000080328097BC0000161300000080D7
+:10C73000020000900000161304010080028097BCE4
+:10C740000000000000000018F341903400009E102B
+:10C7500004000078D90130B60000161304010080EF
+:10C76000328097BC0000000000000000B9053030A6
+:10C7700018000000000000F803A4033900000000C6
+:10C780000000000019CE2C32006016131200004089
+:10C79000A20D90B200000000000000D8020000329C
+:10C7A00060000000000000000700363200000000BA
+:10C7B000000000BCA8002D37A00701000008000001
+:10C7C000C7CD8B3A0A0000000000007889CD2C37D5
+:10C7D0008002000000000078898D973A0000000078
+:10C7E00000100000A7BA973A0000000000180000EF
+:10C7F00007C0EA320000161312000040F2C138B43C
+:10C8000018003600000000F8730A03F90000000069
+:10C81000000801DC02406E321D00000000000078BC
+:10C8200009A417380000161304010080028097BC89
+:10C83000000016138010018022016EB60A00B010AD
+:10C840001F01007889CD2CB70000B7101D1001F82A
+:10C8500002006EB2800200000000000007003632C5
+:10C860002005010000080000C7CD8B3A0000000041
+:10C8700000100000A7BA973A00000000001800005E
+:10C8800007C0EA320000161312000040F2C138B4AB
+:10C8900018003600000000F8730A03F900000000D9
+:10C8A000001001F802006E32EEFF16130401008042
+:10C8B000828D2FB000000000000100800200007097
+:10C8C000EEFF161304110180820D6EB0000000000F
+:10C8D000001001F802006E3200000000000901DCC7
+:10C8E00002406E720000FFFF000000800200009016
+:10C8F0000000000000000000090000320E000000EF
+:10C9000000000004894D0D3600000000000000000A
+:10C9100007800B3200000000000800000700903282
+:10C920000000000000100000070036320000C210B6
+:10C930001200004CF2C138B400000000000000807A
+:10C94000020000300000C3101200008002C021B2BB
+:10C950000000000000000000E902903A0000BF1053
+:10C9600004010004194090BC000000000001008098
+:10C97000020000500000FFFF000000800200009055
+:10C980000000D21080010080A2802FB60000CC10E1
+:10C99000120100E802C021B218003600000000F8C1
+:10C9A000730A03F90000D1100400008002802DBC3E
+:10C9B000000016130401008022802DBC0000161315
+:10C9C0009F000080180088BC0000CC10120100E815
+:10C9D00002C021B20000CB100000008002000090D5
+:10C9E00000000000CA0000D8024084320000161384
+:10C9F0000401008002402DBC0000161304000080DA
+:10CA000002802DBC000000000040006C881C833AAE
+:10CA1000000000000048004C0800723200001613AD
+:10CA200008500018C82072BC0000000004000080FC
+:10CA30000240817C00000000000000141840813C8E
+:10CA40000000161302000020880182BA00000000D6
+:10CA5000000000D8020000320000000000000000CA
+:10CA6000070006320000161304010080020036BCE5
+:10CA70000700000000080000774A093900000000A4
+:10CA8000001000000700823200000000CA190000F8
+:10CA9000074082320000161312000040F2C138B481
+:10CAA00000000000000100D8024084720000FFFF77
+:10CAB0000000008002000090000000004D00000017
+:10CAC00067E0833E0000000000080000070080329D
+:10CAD000000000000010000007C0863200000000C7
+:10CAE0000018000007C0843200003C110400002838
+:10CAF000D8A082BC0000161309010080020000B01B
+:10CB00000000000000000018D8A0813C0000FE10CA
+:10CB10000400003CD8E083BC000016130401008030
+:10CB2000028081BC0000EF100400008072802DBCE8
+:10CB3000000016131200005002C038B20000F710B7
+:10CB4000510000D812802D9A0000161312000050D8
+:10CB5000F2C138B418003600000000F8730A03F977
+:10CB60000000F5100400008072802DBC0000161338
+:10CB700080010080A2802FB60000F010670000F84E
+:10CB8000A2802FB500001613120000E802C021B2E7
+:10CB9000000016130401008072802DBC000000000C
+:10CBA000510000D8020000320000FC102A010000F1
+:10CBB000D82080BA0000FB101201000009C021B289
+:10CBC00018003600000000F8730A03F900000000A6
+:10CBD000000000D8024084321D00161304000080BB
+:10CBE00002A417B8000046100060006C08006EF246
+:10CBF0000000E4104D00000067E0839E0000161363
+:10CC000012000050F2C138B418003600000000F8DD
+:10CC1000730A03F91D0005110400008002A417B86F
+:10CC20000000161380010080A2802FB60000FF10C4
+:10CC3000670000F8A2802FB5000016131200000054
+:10CC400009C021B21D0016130401008002A417B808
+:10CC50000800000000400278399AFE3800001613E0
+:10CC60000201008082BA97BC000016130601008002
+:10CC700092BA97BC0800161312400268129AFEB8C6
+:10CC8000000016130B000080020000B000006411C9
+:10CC900000000030030038F200001B111F00006C80
+:10CCA000D8E086BA00003210510000D8020000F22D
+:10CCB00000000F110000003C0840809200001B1192
+:10CCC000000000800200009000001311800100802D
+:10CCD000F2812FB60000131180000080E2802FB691
+:10CCE0000000131180010080328087B60000000030
+:10CCF000000000F8E2802F340000E31004010080FF
+:10CD0000028081BC0000191180010080A2802FB632
+:10CD1000000018111201000009C021B218003600ED
+:10CD2000000000F8730A03F900000000000000D8BA
+:10CD3000024084321D0016130400008002A417B8BC
+:10CD4000000046100060006C08006EF20000E41065
+:10CD50004D00000067E0839E0000201180010080EC
+:10CD6000E2802FB60000401180010080A2802FB623
+:10CD700018003600CA0000F8730A03F91D004011BC
+:10CD80000401008002A417B8000016130000008000
+:10CD90000200009000000000000000A4A8608A3C8F
+:10CDA0000000161304210180825B8ABC000024115C
+:10CDB0002FA8012099226EBA0000C70F0000008042
+:10CDC000020000F00000161306010280821B92BCD4
+:10CDD0000000000000A801E0060092320000000000
+:10CDE000005001E80600003200002911232101E073
+:10CDF000060000B23E0016131200002C82CD2EB2A7
+:10CE000000001613043000E0068082B200003311E7
+:10CE1000042100E0068081B200001613800000802B
+:10CE2000E2802FB60000311180010080A2802FB671
+:10CE3000000030111201000009C021B218003600B4
+:10CE4000000000F8730A03F900000000000000D899
+:10CE5000024084321D0016130400008002A417B89B
+:10CE6000000046100060006C08006EF20000000038
+:10CE7000002000E00680813200000000003C00E855
+:10CE80000640813200000000001000E006C086323B
+:10CE900000000000001800E006C0843200001613F5
+:10CEA0000400008032E186B2000000002A01008008
+:10CEB0000200007000003A111201000009C021B206
+:10CEC00018003600000000F8730A03F91D0016135D
+:10CED0000400008002A417B800000000000100F860
+:10CEE000A2802F75000000000000003CD8E0833CC9
+:10CEF0000000161312000050F2C138B400001613DF
+:10CF000080000080A2802FB600000000000000F822
+:10CF1000A2802F34000000000000008812002C3A8C
+:10CF20000000FFFF000000800200009000000000F1
+:10CF3000000000000900003200000000000000783E
+:10CF40000900003200000000000000A802000032CA
+:10CF5000EE05481104010080820DF6BC00060000B9
+:10CF6000000000080900363200004A1100000004E9
+:10CF700009C00992002800000000000809003632AC
+:10CF80000000000000000004098009321E000000BB
+:10CF9000000060C087CD003700000000000860C0BE
+:10CFA000078097320030000000000078898D2A3A0F
+:10CFB000000016131200005C528197B400000000BC
+:10CFC000000000002924903A0800000000000078CA
+:10CFD000890D903600000000000000041940903CCC
+:10CFE00000000000000000A852822A3A00084A11FE
+:10CFF00002010080828D2ABC00005B1106000080C7
+:10D00000024090BC00001613120000A8020020B2DB
+:10D010001E000000000000C087CD003700000000A7
+:10D02000000800C007809732000016131200005C51
+:10D0300052812AB400000000000000002924903A28
+:10D040000800000000000078890D9036000054119F
+:10D0500004010004194090BC0500000000000078A5
+:10D06000890D903600000000000000A00E8097326D
+:10D070000000161312000068028097B20000000042
+:10D08000000000A40E8097320000000000000000A5
+:10D090002924903A000000000000007859009036E2
+:10D0A00000005D1195010080222490BA000000006C
+:10D0B00000010080020000500000FFFF000000801F
+:10D0C0000200009000007E1104010078D90130B602
+:10D0D000000000000000002809C029320000000004
+:10D0E0000000009CB2452830000070118601000845
+:10D0F00009802FB2000000000000002C094081329E
+:10D1000000000000000000F80200003200000000F3
+:10D11000000000F40200003218000000000000F8D7
+:10D12000738A0239000000000000009C02809232E5
+:10D1300000006F110407018002C06EBC000079116D
+:10D14000C30701ECB6E46E9A00007911000601EC09
+:10D15000B6E46E9A0000161380010080528090B6EB
+:10D16000000000000000002C0905803000000000D5
+:10D17000000000F80200003200000000000000F48F
+:10D180000200003218000000000000F8738A023923
+:10D19000000000000000009C028092320000161384
+:10D1A0000201008082FA92BC000016130601008082
+:10D1B00092FA92BC0000D71100000080020000D05B
+:10D1C000210000000000001009003632000080122B
+:10D1D0000000001409C092D20000000000000030DE
+:10D1E0000300383200007E1104010078D90130B606
+:10D1F000000067110000009CB2452890000000006C
+:10D20000040000802280977C00001613000000803C
+:10D21000020000900000FFFF00000080020000906C
+:10D22000000016130400008002C0E8BC00001613C2
+:10D230000200008002C12FBC000000000000008836
+:10D2400002C0E83202008411B00000A0F20B00B965
+:10D25000000000000000000CABE4B03200008911B7
+:10D2600080010080F24BD0B600000000A000002832
+:10D2700009000032000000000001008002000050A0
+:10D2800000008B1104010080123EF8BA00009611D4
+:10D29000A0000004FD4BD09400009211800100809A
+:10D2A000D28192B600009211800100802281FCB6EA
+:10D2B00000000000A0000004FD4BD034000000007E
+:10D2C0000000008401C02F32000000000000008038
+:10D2D000F1010034000000000000009401C02F3272
+:10D2E0000000961100000090F10100940000000081
+:10D2F000A000008401C02F32000000000000008068
+:10D30000F101F83400000000000000900140F83204
+:10D310000000000000010028090000520000161360
+:10D3200080010080F24BD0B600009C11040100285F
+:10D330000934B0BA0000161380010080F24BD0B659
+:10D3400000009911B0000080020000B00000000051
+:10D35000A0000004FD4BD0350000000000010028B3
+:10D360000900005200009C11B00000A822C02FB795
+:10D3700000001613040084C037ACB0B200000000F7
+:10D38000A000000C0B000032FFFF0000000000783E
+:10D39000A94DB0300000A411800000800240B0B65A
+:10D3A00000001613800000801240B0B6000000009C
+:10D3B00000000078698197350000000000008408B3
+:10D3C0000B007C320000000000000000E725013265
+:10D3D0000042000000080000878D2A3A000000008B
+:10D3E000001000000700B03200000000001800002C
+:10D3F0000700D0320000000012010048F2C138548A
+:10D400000000161300000080020000900000AA1126
+:10D41000B00000A0020000B2000000000000000CFC
+:10D42000ABE4B0320000AF11800100800240D0B602
+:10D4300000000000A00000280900003200000000E9
+:10D4400000010080020000500000B11104010080C2
+:10D45000123EF8BA0000C211A00000040D40D094A2
+:10D460000000BB1180010080D28192B60000BB1188
+:10D47000800100802281FCB600000000A0000004B2
+:10D480000D40D034000000000000007809C02F32A9
+:10D4900000000000000000FC02000032000000005C
+:10D4A0000000008401C02F32000000000000008056
+:10D4B000F1010034000000000000009401C02F3290
+:10D4C0000000000000000090F10100340000C211D3
+:10D4D000000000FC0280979200000000A00000788D
+:10D4E00009C02F3200000000000000FC02000032E2
+:10D4F000000000000000008401C02F320000000086
+:10D5000000000080F101F8340000000000000090ED
+:10D510000140F83200000000000000FC0280973259
+:10D52000000000000001002809000052000016134E
+:10D53000800100800240D0B60000C811040100281C
+:10D540000934B0BA00001613800100800240D0B642
+:10D550000000C511B0000080020000B00000000013
+:10D56000A00000040D40D03500000000000100289C
+:10D57000090000520000C811B00000A8020000B26B
+:10D5800000001613040084C037ACB0B200000000E5
+:10D59000A000000C0B000032FFFF0000000000782C
+:10D5A000A94DB0300000D011800000800240B0B61C
+:10D5B00000001613800000801240B0B6000000008A
+:10D5C00000000078698197350000000000008408A1
+:10D5D0000B007C320000000000000000E725013253
+:10D5E0000042000000080000878D2A3A0000000079
+:10D5F000001000000700B03200000000001800001A
+:10D600000700D0320000000012010048F2C1385477
+:10D610000000161300000080020000900000FFFFD1
+:10D6200000000080020000900000D9111C40028020
+:10D6300006C092B244000000000100F8A28D2F52F3
+:10D64000000000000000007809C5923000001613A9
+:10D650000201008082BA97BC000016130601008008
+:10D6600092BA97BC000016131200006802C592B06F
+:10D67000000016130B000080020000B02400000020
+:10D680000000001009003632000080120000001473
+:10D6900009C092D200000000000100701F00F75A7C
+:10D6A0000000FFFF00000080020000902C0000003E
+:10D6B0000000001009003632000080120000001443
+:10D6C000098092D200000000D50800000780923245
+:10D6D000000000000030000007C02C320040008035
+:10D6E000003800000700373200000000CA4101E0A6
+:10D6F00006809232000016131200004802C080B269
+:10D700000060000000010008088036720000FFFF82
+:10D7100000000080020000900000161380000080CE
+:10D72000A2802FB6000016130401008062802DBC79
+:10D730000000000000380000078092320000000066
+:10D740000030000007C02C3200000000CA3D000C71
+:10D7500007808332000000001201004802C080727E
+:10D760000000161300000080020000900000FFFF80
+:10D7700000000080020000900000000004570180BB
+:10D7800002C06E7C00000000005701EC068092721F
+:10D790000000FFFF00000080020000900000641104
+:10D7A00000000030030038F23300000000000010D9
+:10D7B00009003632100080120000001419A02CD984
+:10D7C0000000FB119D11020C09006EB20000FC115B
+:10D7D00000F0011C09006E920000000000B8011C5E
+:10D7E00009006E320000FE112CCD011809806EB2C6
+:10D7F000000000000000000CC9C1903400000212BB
+:10D800003B29020409806EB20000161380D6018005
+:10D8100052C06EB60000000000D601EC56C06E3457
+:10D82000000000000000000CB9C19034000012128A
+:10D8300000A8010809006EF2000006129D01008098
+:10D8400017E090BA000000000030008007C091325D
+:10D8500000000912003800800700EE920000091253
+:10D860000401008002C091BC0000000000B801E08B
+:10D870000600EE3200000000007001E00600863273
+:10D8800000000C123908008007C085B20000161392
+:10D8900080000080C2812FB600000000D9C901E8D5
+:10D8A0000680913200000000C811008007409032CD
+:10D8B00000000F123B210080070086B2000000002C
+:10D8C000DB0000601800863A00000000587801E094
+:10D8D0001620863A000000000029008007008572AB
+:10D8E0000000FFFF00000080020000900000161200
+:10D8F000020C0280A29B90BC000000000000027895
+:10D9000029006E360000161202000080E2A590BCCD
+:10D91000000000000000000809000032000018129A
+:10D920009F89017849216EBC00000000000000784A
+:10D93000090000320000000000000008E9A5903F47
+:10D9400000001E1204200208899B90BE0000000007
+:10D95000000A0258B89B90360000000000000078D2
+:10D9600049A1903A000000009F880180829B977C2B
+:10D9700000000000008901E00680977200000000AE
+:10D98000000B0258B89B90760000FFFF000000805B
+:10D99000020000900000271280010080A2802FB6B4
+:10D9A000000025121201007809C021B218003600CB
+:10D9B000000000F8730A03F9000016130401008048
+:10D9C00002802DBC00002712CA0000D802408492B9
+:10D9D0001500161304010078E96517B8000000006F
+:10D9E000000000F8A2802F3500001613040100800B
+:10D9F00002402DBC000016130400008002802DBCE4
+:10DA0000000000000040006C881C833A0000000009
+:10DA10000048004C0800723200001613085000182D
+:10DA2000C82072BC000000000600008062A0827C5A
+:10DA3000000016139F000014184081BC000016134C
+:10DA400002000020880182BA00000000000000D817
+:10DA50000200003200000000000000000700063253
+:10DA60000000161304010080020036BC070000000D
+:10DA700000080000774A093900000000001000008B
+:10DA80000700823200000000CA19000007408232FD
+:10DA90000000161312000040F2C138B4000000006C
+:10DAA000000100D8024084720000FFFF00000080E7
+:10DAB000020000902B000000000000100900363228
+:10DAC000000080120000001409C085D2000042123C
+:10DAD00080010080F2C185B600003E121F40028422
+:10DAE000E60100B4000042121D0100F822812FB4AB
+:10DAF00000004212000000F862812F9500004012E1
+:10DB00001D010080020000B000000000000000F8CD
+:10DB100062812F3500000000004002800240683220
+:10DB2000000016131F010080020000B00000161351
+:10DB30001200006802C585B00000000000000078F7
+:10DB400009C58530000016130201008082BA97BC17
+:10DB5000000016130601008092BA97BC0000000076
+:10DB60001D00008002000070010000000401008020
+:10DB7000A28D2F702A0016131200002C82CD2EB217
+:10DB800000000000000100F802812F740000FFFF78
+:10DB9000000000800200009080A8000004000080C7
+:10DBA000828D2F700000521280010080D2802FB62B
+:10DBB000000016138000008072812FB60000521200
+:10DBC00004B0008002006EBC00000000000000F8FD
+:10DBD00072812F343D0055121201002C82CD2EB2DD
+:10DBE0000000161300000080020000900000551293
+:10DBF00080010080F2802FB63C0058121201002CE8
+:10DC000082CD2EB2000016130000008002000090AA
+:10DC10000000581280010080B2802FB63500161324
+:10DC20001200002C82CD2EB200000000000000F88F
+:10DC300042812F348000000004000080828D2F700C
+:10DC40000200000004010080A28D2F703B0016131B
+:10DC50001200002C82CD2EB200000000000100F85E
+:10DC600012812F740000FFFF00000080020000906E
+:10DC70000000161380000080A2802FB6000016134B
+:10DC800004310280A2DB2CBC08000000001801E86F
+:10DC900076208139EEFF0000000100F8828D2F719F
+:10DCA0000000FFFF000000800200009000006612EC
+:10DCB0000000013808C06EF20000000012010048A8
+:10DCC00002C0807200001613000000800200009065
+:10DCD0000000FFFF00000080020000900E00000026
+:10DCE00000000010090036320000801200380114D4
+:10DCF00009006ED200006A120438017809006EB281
+:10DD000000000000003801E0060000320000161399
+:10DD100080000080A2802FB600000000CA11000021
+:10DD20000780823200006E122E190000078097B221
+:10DD30000000000000000028E98192340000731206
+:10DD40002731000007C02CB200000000D5080000F9
+:10DD50000700873200000000C7000028E9809234E5
+:10DD600000000000004001E00600873200000000D3
+:10DD700000000008D8818034100000000039000045
+:10DD8000E7A092790000FFFF0000008002000090F1
+:10DD9000140000000000001009003632000080125C
+:10DDA00000000014094090D2000016131200004435
+:10DDB00012E438B218003600000000F8730A03F9C4
+:10DDC00000007D120401008002802DBC00001613AB
+:10DDD00080010080A2802FB600007812670000F852
+:10DDE000A2802FB500001613120000E802C021B275
+:10DDF000000016130401008072802DBC000000009A
+:10DE0000000100D8024000720000FFFF0000008007
+:10DE1000020000901B00000000000010790A9139F8
+:10DE20000F00000000000010390B91390C000000B9
+:10DE300000000010590A913909008312F101001005
+:10DE4000690B91B903000000002486A8828D6C370D
+:10DE500000000000000088E0070091320000000090
+:10DE6000000088E00740913200C089120201008062
+:10DE7000828D2ABC00008A12E12486C80600009226
+:10DE800003000000E12486C8868D2A3600000000C9
+:10DE900000010080020000500000FFFF0000008031
+:10DEA000020000900000921204300080829B81BC2E
+:10DEB000000016130D010080020000B000001613D0
+:10DEC0009F3C001428806EBC000016138000008068
+:10DED000A2802FB600000000CA0100F802802F3592
+:10DEE00000A0161312000040A28D39B20000941257
+:10DEF00080390080E2806EB6000016138038008002
+:10DF0000F2806EB600C0161304010080A28D2FB0FF
+:10DF100000C09A1204380078898D6EB010009A12F1
+:10DF20009F0100F8E2A52FB900001613040000803D
+:10DF300002C0EEBC00000000005801EC06C0EE324A
+:10DF4000000000000000008002000030000000001F
+:10DF50000428001809006E720000E30F0000008022
+:10DF6000020000F00000C70F00A8012009006E9217
+:10DF70000000FFFF00000080020000900000A712D8
+:10DF800004B00080829B81BC000016130D0100804C
+:10DF9000020000B0000016139FBC001428806EBC65
+:10DFA0000000161380000080A2802FB60000161318
+:10DFB00080B8008082806EB60000000000B800E8E3
+:10DFC00086806E3400000000CA0100F842802F35C0
+:10DFD00008A0000012010040A2CD39720000161303
+:10DFE00000000080020000900000161380B800803E
+:10DFF00082806EB60000000000B800E886806E34B3
+:10E000000000000000010080020000700000FFFF1F
+:10E0100000000080020000902800000000000010B6
+:10E02000090036320000801200000014098090D2EE
+:10E030000000B01233CD01BC08806EB20000EE12B9
+:10E04000000000282922EEDC0000B512000000804C
+:10E05000020000900000B51204B8012809006EB259
+:10E060000000B5129F710180C2216EBC0000161322
+:10E070009F000028A924EEBC0000EE12000000283A
+:10E08000198092DF000000000000008002000030D4
+:10E090000000C91202810180829B90BC000016130F
+:10E0A00004000080028090BCEE05C112060C0280C4
+:10E0B000828D6EBC00904C0000000084020037325C
+:10E0C0000000BB12B8010080020000B00000B912CD
+:10E0D000000000800200009000000000000000C46A
+:10E0E000038090320000000000B001E096216E3CF9
+:10E0F00000000000619801E0060087320000000087
+:10E1000000D401EC0600003200000000A8000078F6
+:10E1100049403C370000CE1200000008E9A5909A63
+:10E120006089200000000084020037320000C41221
+:10E13000B8010080020000B00000C21200000080A0
+:10E140000200009000000000000000C40380903234
+:10E150000000000000B001E096216E3C00000000CD
+:10E16000619801E0060087320000000000D401EC55
+:10E17000060000320000CE12A8000008198F909A05
+:10E18000000000000000007899A1893E0000000016
+:10E1900000000008E9A5903A0000000000B001E08E
+:10E1A00096216E3C00000000619801E00600873275
+:10E1B0000000000000D401EC060000320000D11283
+:10E1C0000600008072A290BC00C0FF3F008001E00A
+:10E1D00006003732000000000000000809C0893244
+:10E1E0000000D61204790180821B87BC0000D41283
+:10E1F00004B0008002006EBC0000D912D99001E08A
+:10E20000068090920000DC128000008052812FB6C0
+:10E210000000DC12D54101E0060087920000D9120F
+:10E220003C9001E0068090B200001613800100804F
+:10E2300092812FB60000000000C801E806C08B32B2
+:10E24000000000009501008002802F720000DD12A6
+:10E250009F410180821B87BC0000000000010080FC
+:10E260000200007000000000D99001E006809032AA
+:10E2700000000000000100F872802F740000FFFF12
+:10E280000000008002000090270000000000001045
+:10E29000090036320000801200000014094087D2C5
+:10E2A0000000E7129FD8018022216EBC0000000010
+:10E2B0000B010080020000700000E7129FE0018067
+:10E2C000C2216EBC000000000B0100800200007043
+:10E2D0000000E7129FB00180D2216EBC0000000058
+:10E2E00000010080020000700000E9120668018051
+:10E2F000825B87BC00000000006801E006408732B6
+:10E300000000EB1237B001E0064087B200000000C9
+:10E31000000000F8D2802F340000000000D801E097
+:10E32000068084320000000000E101E006008772F0
+:10E330000000FFFF000000800200009000001613A4
+:10E3400008000080028092BC0000FB1204C101841E
+:10E3500002006EB20500000000C001E8868D923711
+:10E360000300000000C401E8868D92370000000021
+:10E3700000000080020000300300000000C0012CFB
+:10E38000898D6E360000000000C4012CA9DB923A92
+:10E39000000000000000002C29C0923600000000A0
+:10E3A0000000002C19FB923F000000000000002834
+:10E3B0002980923A000000000000002CA9E4923F5E
+:10E3C000000000006FCC01E826FB923E0000000038
+:10E3D00000B901E0060000520000000000000094B7
+:10E3E000028092320000000000C001E006402832A6
+:10E3F000100000006FCC01E886CD2A360000000036
+:10E4000000B901E0060000520000FFFF000000809C
+:10E41000020000900000161304B0008002006EB2EB
+:10E4200000000000009001BC08006E3200000000F7
+:10E4300000B001BC88DB8B3E00000000009801BCEE
+:10E4400088DB8B3A00000C139F0000BC88E18BBC7A
+:10E4500000000C13040C0240A8DB8BBE000000007F
+:10E4600000B00004881B843E0000091304B1008042
+:10E47000825B80BC00000000000100F8C2802F74A5
+:10E4800000000000040C0280A25B807C00000C13E2
+:10E490000468017819006EB60000000002000080D8
+:10E4A000E265807C2900000000000010090036327F
+:10E4B000000080120000001409C08BD20000000090
+:10E4C0000000008812002C3A0000FFFF00000080CE
+:10E4D000020000900000161304310280A2DB2CBC65
+:10E4E0000000161380000080A2802FB608000000F4
+:10E4F000001C01E876208139EEFF0000000100F8E1
+:10E50000828D2F710000FFFF00000080020000904C
+:10E5100000001613000000B40F40FB940000000040
+:10E52000000000880F402B32000000000000009027
+:10E530000F00283200000000000000940F00293274
+:10E5400010000000000000B85F461839FF0000000E
+:10E550000000009C0F003632000000000000009C0C
+:10E560005FCAF935000000000000004403C0F93222
+:10E5700000000000000000E4030000324100001031
+:10E58000000000E00300373200000000000000E45B
+:10E590000300003240000010000000E003003732AA
+:10E5A00000002513670000980F802AB200000000C9
+:10E5B000000000A8020000320000231312C186E010
+:10E5C00007C021B20000000000B886C006802A32D1
+:10E5D0004C420000000000A8020036322713381415
+:10E5E000000000B00F003692000000000000009C08
+:10E5F0000200003200012414000000AC0F0036D2EB
+:10E6000000000000000000AC0F802A320020000053
+:10E61000000000A802003632000000000000009C4C
+:10E620000F007E3200000000000000A00F007E32CC
+:10E6300000000000000000A40F007E320000000077
+:10E64000000000A80F007E3200000000000000A8BB
+:10E6500002C0FA3200000000000000E007C0F932FA
+:10E6600000000000000000E00700FA320000000097
+:10E67000000000E00740FA3200003B13000000E019
+:10E680000780FAD200000000000000E00780FB32A3
+:10E6900001006213040100B48F4DFBB002000000C2
+:10E6A000000000A002000039408000000000000CC3
+:10E6B000ABCDB032100000000000000C5BCAB039D6
+:10E6C000000000000000000C2BFEB03200006114BE
+:10E6D000000000800200009000000000000000F830
+:10E6E0000300013200000000000100E007803F52FB
+:10E6F00018000000000000F8738A023900000000D2
+:10E7000000000044530A1635000000000000009C81
+:10E710000F80963200000000000000A00FC096326B
+:10E7200000000000000000A40F009732A260030068
+:10E730000000005803003732481300000000005C5E
+:10E74000030036320000000000000050830D00344A
+:10E750000000000000000048830D003400000000AD
+:10E7600000000044530A003400003600000000801E
+:10E7700002000090000000000000006809C0F932AB
+:10E78000000000000000006C0900FA3200000000E8
+:10E79000000000700940FA3200005A1300000080A7
+:10E7A0000200009002000000000000A0F20B0039FF
+:10E7B00000004F13800100801240B0B6000000003E
+:10E7C000000000043B40B0330000000000000004E3
+:10E7D000FD4BD035000053130000000C0B00979246
+:10E7E00002000000000000A0F20B003900005313EB
+:10E7F000000000046B01979400005313120000689E
+:10E80000094020B2000054131200006C094020B2ED
+:10E810000D000000000000FCA2E5163800005913AE
+:10E820009F000080028096B200000000000000708F
+:10E8300009C0963200005A130000006C09C0FD9216
+:10E840000000591312000070094020B200000000BF
+:10E850000000009C0200003200000000000000D810
+:10E860000200003202005313040100BCAF2517B8A8
+:10E8700006005113040000BCAF6516B800004C132D
+:10E880000400008022C0FBBC00006A13040000806A
+:10E8900012C1FBBC200053130401008082CDFBBCDD
+:10E8A00002000000000000A0F20B003900006B1312
+:10E8B00000000080020000D0641300000000008807
+:10E8C00082CDF93A00005A14000000800200009046
+:10E8D00000009313000000800200009000009413D9
+:10E8E00000000080020000900000981300000080EB
+:10E8F000020000900000A0130000008002000090C1
+:10E900000000F91300000080020000900000531383
+:10E91000000000DC0F0097920000000000000000E3
+:10E920000700033240420000000000A80200363217
+:10E93000000000000008000007802A3200000000EC
+:10E9400000100000070097320000000000180000CF
+:10E9500007C096320880701312000040028036B261
+:10E960000000000000000080020000300000721370
+:10E970001200009C0FC021B21D007513040000801E
+:10E9800072BE17B800007213000000F81E80EF9AE4
+:10E99000130000000000009C7FBE173800007813B1
+:10E9A0000400008012C0F9BC00007213000000F8DF
+:10E9B0001E80EF9A000000000000009C0F007E32D5
+:10E9C00000000000000000A00F007E3200000000E8
+:10E9D000000000A40F007E320000000000010000D3
+:10E9E0000700FA52000000000000009C0200003204
+:10E9F0004C420000000000A8020036320000000077
+:10EA00000008000007802A3200004E140000008039
+:10EA1000020000D00000521400000080020000D06C
+:10EA2000000000000000000CCBC1B034000000006A
+:10EA30000000009C0200003200000000000000D82E
+:10EA400002000032000081110000002809C0B0D28D
+:10EA50000000821304000080028092B2000086133E
+:10EA60001200009C0FC021B21D0089130400008019
+:10EA700072BE17B800008613000000F81E80EF9ADF
+:10EA8000130000000000009C7FBE173800008C13AC
+:10EA90000400008012C0F9BC00008613000000F8DA
+:10EAA0001E80EF9A02008E13040100B48F4DFBB05C
+:10EAB00000005313000000800200009008000000D6
+:10EAC000000000F89340013900000000000000B48D
+:10EAD0001F40FB35FE0000000000004803003632F6
+:10EAE0000000000000000044030000340000821316
+:10EAF0000000000C8BC1B09400005E140008000000
+:10EB00000740FA9200004E14000800000740FAD2B5
+:10EB10000880951312000050028036B20000531492
+:10EB200000000080020000D000006014000000809F
+:10EB300002000090000800000000009C0F00363228
+:10EB400000040100000000A80200373200000000AD
+:10EB5000000000A00200003200000000000000E001
+:10EB60000700B03200000000000000A012002A3AA6
+:10EB700000009B130401009C1FC0F9BC00040100AD
+:10EB8000000000A80200373202005D14000000A05F
+:10EB9000F20B00990000A813040100800240FAB2B1
+:10EBA00000040100000000A8020037320000AA1390
+:10EBB00000000080020000D00000B71300000084B5
+:10EBC000020000D200000000000000E007C03C325C
+:10EBD0000000A4138E010080024028B2000401004E
+:10EBE000000000A40F0037320000931300000080E3
+:10EBF0000200009000040100000000A4CF4DFA3A8A
+:10EC0000000093130000008002000090000000004C
+:10EC10000000009C0F00003210000001000000AC5A
+:10EC20000F0037320000BC1300000080020000D04B
+:10EC30000800AC130401008082CDF9BC0000000084
+:10EC40000000009C0F0000320E000001000000AC2C
+:10EC50000F0037320000BC1300000080020000D01B
+:10EC60000B00B0130401008082CDF9BC200000002D
+:10EC70000000009C0F0036320F000001000000ACC5
+:10EC80000F0037320000BC1300000080020000D0EB
+:10EC90002700B4130401008082CDF9BC00000000FD
+:10ECA0000001008002000050000000000000009CF5
+:10ECB0000F0000320F000001000000AC0F003732DF
+:10ECC0000000BC1300000080020000D02000B91337
+:10ECD0000401008082CDF9BC00000000000100802A
+:10ECE0000200005000000000000000E403C0F93200
+:10ECF0000D000001000000E00300373200000000BA
+:10ED0000000000E003C0FA3200000000000000E054
+:10ED100007403E32000000000001009C1FC0F95A6D
+:10ED200000000000000000E003C0F9320000000015
+:10ED3000000000E007403E32000000000000009CA0
+:10ED40001FC0F93AFF000000000100AC8FCDF95060
+:10ED5000000000000000009C0FC02F3200000000E7
+:10ED6000000000FC0200003200000000000000E093
+:10ED700007803E3200000000000000FC12C02F3A65
+:10ED80000F00C7130401008082CD2FBC00000000DB
+:10ED9000000000E007803E3200000000000100FC9F
+:10EDA00002C0F95200000000000000E007003A3203
+:10EDB00000000000000000E007403A3200000000C0
+:10EDC000000000E007803A3200000000000000E090
+:10EDD00007C03A32000000000000009C0FC02F3234
+:10EDE00000000000000000FC0200003200000000F3
+:10EDF000000000E007003D3200000000000000E0DD
+:10EE000007403D320000D213830100FC12C02FBA2C
+:10EE100000000000000100FC02C0F95200000000E8
+:10EE20000000009C0F0000320C00000000000008F1
+:10EE3000733E003900000000000000E0070030329F
+:10EE4000000000000000009C1FC0F93A7000D713BA
+:10EE50000401008082CDF9BC000000000000000C1D
+:10EE60000300003200000000000000E00700303224
+:10EE7000000000000000001003000032000000004D
+:10EE8000000000E007003032000000000000009C9D
+:10EE90000F00003200000000000000A00FC0293267
+:10EEA000000000000000009C02C0F93200000000D9
+:10EEB000000000A40FC02C32000000000000009CE5
+:10EEC0000200FA32180000000000002C737EFA39AC
+:10EED00000000000000000E0070030320000E013F6
+:10EEE0008501009C1FC0F9BA0000000000010080ED
+:10EEF00002000050010000010000009C0F003732AA
+:10EF00000000C11300000080020000D00E00EF13CB
+:10EF10000401008082CDFABC00000000000000E087
+:10EF20000700003200000000000000E0070000328F
+:10EF300000000000000000E0070000320000E913BC
+:10EF40000000009C3FC0F99A1C00E91304010080F6
+:10EF500082CDFABC0200C1130000009C8FCDF9DA0B
+:10EF600000000000000100800200005001000002CB
+:10EF70000000009C0F0037320000C1130000008029
+:10EF8000020000D00E00F7130401008082CDFABC0D
+:10EF900000000000000000E0070000320000F31352
+:10EFA0000000009C1FC0F99A2600F31304010080A2
+:10EFB00082CDFABC00000000000100800200005079
+:10EFC00000000000000000A80F40293200040100EA
+:10EFD000000000A8020037320000E81300000080A3
+:10EFE000020000D00000F21300000080020000D0F8
+:10EFF0000000C51300000080020000D000000000E7
+:10F00000000000E00780183200000000000000E06F
+:10F0100007401A3200000000000000E007001A322A
+:10F0200000000000000000E007801A32000000002D
+:10F03000000000E007C01A3200000000000000A03D
+:10F040000F000032A26003000000005803003732B6
+:10F050000B1400000000005C0300363200000000CA
+:10F060000000009C0F802A3200000B140400008076
+:10F07000024029B20000000000000050833E00342E
+:10F080000000000000000048833E00340000000043
+:10F0900000000044530A003400000C1400000088F3
+:10F0A0000F402B9200000000000000900F0028325B
+:10F0B00000000000000000940F0029320000000052
+:10F0C000000000980F802A3200000000000000A815
+:10F0D00002C0F93211143814000000B00F0036924B
+:10F0E0000700141404000080824D29BC00000000B9
+:10F0F000000000A01F00FA3A000008140000009C65
+:10F100000F802A92C0010000000000AC0F003632D0
+:10F11000010000000000009C0200363200002414B0
+:10F1200000000080020000D01F001A1404000080BC
+:10F1300082CD29BCC0000000000000AC8FCDFA3A9F
+:10F14000000016140000009C12C0299A0000D6137B
+:10F1500000000080020000D00000CC1300000080FE
+:10F16000020000D00000221404000080528AFABC81
+:10F17000A260030000000058030037322214000090
+:10F180000000005C03003632000000000000005068
+:10F19000A33E00340000000000000048A33E0034FD
+:10F1A0000000000000000044530A00340004010085
+:10F1B000000000A40F00373200009313000000800D
+:10F1C0000200009000000000000000C402C0FA32FB
+:10F1D000030000000000009C0F0036320000000019
+:10F1E000000000BC0F402F3200002B140400009CD4
+:10F1F0001FC0F9BC00002A140400008002402FB296
+:10F2000000002714000000E007002C9200002714E3
+:10F21000000000E00700369200000000000000E05F
+:10F2200007402C3200000000000000E007802C3274
+:10F2300000000000000000E007C02C3200000000C9
+:10F24000000000E007002D3200000000000000E098
+:10F2500007402D3200000000000000E007802D3242
+:10F2600000000000000000E007C02D320000000098
+:10F27000000000E007C0FB3200000000000000E0DA
+:10F2800007802F3200000000000000E007C02F328E
+:10F2900018000000000000F8730A023900000000A6
+:10F2A000000100E007803F52FF0000000000004422
+:10F2B0000300363200000000000000E00700F932D1
+:10F2C00000000000000000E00740283200000000BD
+:10F2D000000000E00780F832030000000000009CFE
+:10F2E0000F00363200000000000000BC0FC02B32BF
+:10F2F000000041140400009C1FC0F9BC0000401431
+:10F300000400008002C02BB200003D14000000E0A9
+:10F3100007C0289200003D14000000E0070036926C
+:10F3200000000000000000E00740F932000000008B
+:10F33000000000E00740293200000000000000E06B
+:10F340000780293200000000000000E007C02932D9
+:10F3500000000000000000E007002A32000000006A
+:10F36000000000E007402A3200000000000000E03A
+:10F370000780F93200000000000000E007C02A32D8
+:10F3800000000000000000E007C02F320000000075
+:10F39000000000E007402B3200000000000000E009
+:10F3A00007802B3200000000000000E007C0FB32A5
+:10F3B00000000000000000880200FB320000000096
+:10F3C0000000009C0200003200000000000000D895
+:10F3D0000200003200000000001000000700973219
+:10F3E000000000000019000007C096520880521467
+:10F3F00012000048028036B20000000000000080C9
+:10F4000002000030000054141200009C0FC021B212
+:10F410001D0057140400008072BE17B80000541479
+:10F42000000000F81E80EF9A130000000000009C0E
+:10F430007FBE1738000000000400008012C0F95C95
+:10F4400000005414000000F81E80EF9A0000000035
+:10F45000000000B40F40FB35000000000000009CDD
+:10F46000020000324C420000000000A802003632C8
+:10F47000000000000008000007802A3200004E143F
+:10F4800000000080020000D0000052140000008044
+:10F49000020000D0000000000000000CCBC1B0341E
+:10F4A000000000000000009C02000032000000008C
+:10F4B000000000D80200003200006B140000002899
+:10F4C00009C0B0D20000611404000080028092B232
+:10F4D000000065141200009C0FC021B21D006814CA
+:10F4E0000400008072BE17B800006514000000F828
+:10F4F0001E80EF9A130000000000009C7FBE1738AA
+:10F50000000053130400008012C0F9BC0000651411
+:10F51000000000F81E80EF9A00000000000000FCD0
+:10F520000200003202000000000000A0F20B0039CF
+:10F5300000006F14040100280934B0BA0000000074
+:10F54000000100280900005200000000000000A88F
+:10F5500022C02F3700000000000084C037ACB0325A
+:10F56000000000000000000C0B000032FFFF000054
+:10F57000000000C0AF4DB030000075148000008066
+:10F580000240B0B600000000000000C06F01FC3572
+:10F590000000000000000000073F013200420000B0
+:10F5A00000080000878D2A3A0000000000100000CB
+:10F5B0000700B03200000000001800000700D03241
+:10F5C00000000000000000C03FC13834000000000F
+:10F5D00012010048F201FC5400007A14000000807F
+:10F5E000020000900000FFFF000000800200009079
+:0CF5F000000036000000008002000090C7
+:00000001FF
diff --git a/firmware/sxg/saharadownloadB.sys.ihex b/firmware/sxg/saharadownloadB.sys.ihex
new file mode 100644
index 0000000..0309852
--- /dev/null
+++ b/firmware/sxg/saharadownloadB.sys.ihex
@@ -0,0 +1,3385 @@
+:10000000020000005CD300000C00000000000000B3
+:10001000FF1F00000100000000000088824D293A07
+:100020000000400300000080020000900000090072
+:100030000000008002000090000009000000008025
+:100040000200009000000900000000800200009003
+:10005000000009000000008002000090000009007C
+:1000600000000080020000900000090000000080F5
+:1000700002000090000009000000008002000090D3
+:10008000FEFF0000000000AC020036320000360027
+:10009000000000A80200009200003610000000805E
+:1000A0000200009000003610000000800200009066
+:1000B00000003610000000800200009000003610A2
+:1000C0000000008002000090000036100000008058
+:1000D0000200009000002000000000D80F8028924D
+:1000E00000002100000000D80F80289200002200AC
+:1000F000000000D80F80289200002300000000D8E4
+:100100000F402B9200002400000000D80F8028929E
+:1001100000002500000000D80F8028920000260073
+:10012000000000D80F80289200002700000000D8AF
+:100130000F80289200002800000000D80F8028922D
+:1001400000002900000000D80F80289200002A003B
+:10015000000000D80F8028920000360000000098B0
+:100160001E80E99A00002C00000000D80F80289221
+:1001700000002D00000000D80F80289200002E0003
+:10018000000000D80F80289200002F00000000D847
+:100190000F80289200003000000000D40F00009271
+:1001A00000003000000000D40F400092000030003A
+:1001B000000000D40F80009200003400000000D442
+:1001C0000FC0009200003000000000D40F00019228
+:1001D00000003000000000D40F4001920000300009
+:1001E000000000D40F80019200003000000000D415
+:1001F0000FC0019200003000000000D40F000292F6
+:1002000000003000000000D40F40029200003000D7
+:10021000000000D40F800292000036100000008021
+:100220000200009000003000000000D40F00039294
+:1002300000003000000000D40F40039200003000A6
+:10024000000000D40F80039200003000000000D4B2
+:100250000FC0039200000000000000D05F3F003498
+:10026000000036100400008042FFFCB000000000D7
+:10027000000000881280FD3A000036100000008067
+:10028000020000903610361002010080828DFDBC05
+:1002900000000000000000881280FD3A000000000D
+:1002A000000000F803C001323800000000010084A3
+:1002B000824D281A000036000000007409400092A8
+:1002C00000004F00000000FC020000920000480007
+:1002D000000000800200009000004D00000000902F
+:1002E0000E80189200008F020000000008C02092CB
+:1002F00000007F00000000000800219200008D0235
+:10030000000000000840219200007C000000000076
+:10031000088521900000F202000000EC02C0229249
+:100320000000CE0300000080020000900000560094
+:10033000000000FC0240189D00005100000000D0A9
+:1003400002000092000020030000008002000090E4
+:100350000000361000000080020000900000000045
+:10036000000100800200007000004C00000000004E
+:1003700009C0219200004A0012010000088522B045
+:1003800018003600000000F8738A0299000084000B
+:100390006A000080020000B008008400000000F83D
+:1003A0002340019900000000000100E80200907263
+:1003B0000000361080010080B200E9B600003E0364
+:1003C0000000007C1EC0E79A08000000000000F852
+:1003D000134001390000320300000008B801009406
+:1003E000000036100300007809401ABD000000002C
+:1003F000000000A0E125003408000000000000F823
+:10040000B340013900003E03B20000D8020000B240
+:1004100000004005001001F802006E920000590033
+:100420000A0100CC020000B200006A00030100FCD7
+:10043000024019BD08003E03000000F8A3400199E6
+:10044000000000000000008401C02F320000000006
+:1004500000000090F1010034000000000000009452
+:1004600001C02F3202005C00B00000A0F20B00B906
+:1004700000005F000401008002C0B0BC0000680002
+:10048000A000008002000090000061008001008058
+:10049000F24BD0B600006800A0000080020000907F
+:1004A00000000000A0000004FD4BD03400006600F6
+:1004B000800100801281FCB600002D0F000000D8E2
+:1004C000020000D218000000000000F8730A03398F
+:1004D00068003600000000C0020036920000040FE1
+:1004E000000000D8020000D218003600000000F81A
+:1004F000730A03F900005900030100FC024018BD13
+:1005000000007B00030000FC024019BD0000000059
+:100510000000009401C02F320000000000000080A5
+:10052000F1010034000000000000008401C02F32FF
+:1005300002006D00B00000A0F20B00B900007000D6
+:100540000401008002C0B0BC00007900A00000805F
+:10055000020000900000720080010080F24BD0B6D3
+:1005600000007900A0000080020000900000000060
+:10057000A0000004FD4BD034000077008001008013
+:100580001281FCB600002D0F000000D8020000D23E
+:1005900018000000000000F8730A033979003600E3
+:1005A000000000C0020036920000040F000000D8D6
+:1005B000020000D218003600000000F8730A03F9A8
+:1005C00000006A00030100FC024019BD0000590050
+:1005D000030100FC024018BD08003E03000000F8C3
+:1005E000A340019908000000000000F873400139A1
+:1005F0000000840080010080E20180B600008100DC
+:1006000000000080020000900800ED020C0000F8DD
+:10061000534001B90000830080010080E20180B6F0
+:100620000000361012000068020580B0000032039E
+:100630000000006C1FC0F69A0000000000000000DF
+:100640000805803000000000000000FC02000132BC
+:10065000000000000000001008803D320000000093
+:10066000000000D40200003202A0000000000000E0
+:10067000A90D8032000088001200005402A438B294
+:10068000000200800000002C0800373218003600FD
+:10069000000000F8730A03F90000000000080004DD
+:1006A00008807232000090009F00005C080072B267
+:1006B00087008F008001008082CD85B00000A100FE
+:1006C0000000002CD8C182940000A1000000002C82
+:1006D00088C18294000F99000401008082CD85B00A
+:1006E00000009900800000804281FCB600003610B6
+:1006F00012000068020580B0000000000000006CDD
+:100700001FC0F63A00000000000000FC02000132A9
+:1007100000009700040100DC43603DB30000320399
+:10072000000000FC0200009218000000000000F829
+:10073000738A033994003600000000C0020036922C
+:1007400010009F0087000078792116B801009F00F3
+:1007500004010080828D97BC8700A8008700007884
+:1007600089CD85B000009E0004010080128097BCF6
+:100770000000A1000000002CD8C182940000A1005C
+:100780000000002C88C182940000A8008001008035
+:10079000F2C085B60000A8000000002C98C1829429
+:1007A0000000A70080010080D2C182B60000A8002E
+:1007B000800100807280FCB600000000001800A8D4
+:1007C000423D723000000000541889FCF2C07C30B9
+:1007D0000000CB0080010080F2C185B60000A900B6
+:1007E00000000080020000900000A3008000008054
+:1007F0008280FCB600000000540000FC02000032C1
+:100800008000802000000080C2CD85300000BE0046
+:100810000B000080020000B018000000000000780B
+:1008200079A116382000CB0004000080828D97BC8F
+:100830000000B500800100806280FCB68700B50032
+:100840008700007889CD85B00000B10004000080E9
+:10085000128097BC0000B50004010080228097BC84
+:100860000000B5008001008072C185B61000000054
+:1008700000000078796116380000BC000401008097
+:10088000328097BC0000CB000000002CB8C18294DD
+:100890000000BC00800100805280FCB60000BC005B
+:1008A0008000008072C185B60000BC00800100801D
+:1008B00002C185B60000BC0080010080D2C185B6AF
+:1008C000180000000000007879E116380000BC0034
+:1008D00004010080328097BC0000CB000000002C97
+:1008E000C8C1829400000000000000040800043227
+:1008F0000000CB000000002CA8C18294080000007A
+:1009000000000078792117380000CB000400008037
+:10091000328097BC0000CB0004010080228097BC8D
+:100920001F0000000012000889CD72300500000091
+:1009300000120000B9DC173800000000000000A819
+:10094000220090370000CB008000868022247CB6F5
+:100950000000361012000068020580B000000000A0
+:10096000000000FC020001320000C900040100DCAC
+:1009700043603DB300003203000000FC020000921F
+:1009800018000000000000F8738A0339C600360022
+:10099000000000C0020036920000CE00120100608C
+:1009A000084023B2008200000000000808803632B0
+:1009B0000000C500000000641F40F69A00003610D9
+:1009C00012000024080023B200003610120000209C
+:1009D00008C023B20000361012000018088023B2AD
+:1009E00000000000000000FC020001320000D50001
+:1009F000040000DC43603DB318000000000000F874
+:100A0000738A0339D1003600000000C0020036921C
+:100A100000000000000000FC020085320000000021
+:100A2000000000D80280013200000000000000D069
+:100A30000200003200C0E1001801000CA8CD3EB257
+:100A40000000D50012000038028081B200000000D2
+:100A50000000003C02008232000000000000003074
+:100A600002408232000000000000003402008632A2
+:100A700020800000000000080880363200000000DE
+:100A80000000005C1FC0F53A00003203120100684C
+:100A9000020580B0000036100000008002000090C7
+:100AA0000000000000180078090072320023E40002
+:100AB00004010080A2CD82B00000E500000000002B
+:100AC00009000092000036109F16000029C172BC78
+:100AD00000000000001800000780813200000000C4
+:100AE0000020000007008232000000000028000003
+:100AF0000780973210000000003000001720903966
+:100B0000000000000038000007C082320000000032
+:100B1000000000D8020000320000000000000000C9
+:100B2000074080320000EE0080010080A2C182B642
+:100B30000000EF000008000057008097050000004B
+:100B40000008000007A0043900003610041000005F
+:100B5000074082B200000000001800000700863243
+:100B60000000F10012000050F2C138B41800360045
+:100B7000000000F8730A03F9000036101200006844
+:100B8000020580B00000F4001200004802C080B2EC
+:100B900000003203CA010008E881809408000000C8
+:100BA000000000F89340013910000000540000FCE0
+:100BB000824D90360000F800F00100D8020000B22B
+:100BC00000000000620401A802C06E3200000000B4
+:100BD0000004010059C06E370000000000040178D5
+:100BE00019C06E3A000000004E0401EC06BD9730BB
+:100BF00000000000E00000F41E40EF3A000000009A
+:100C000000188BCC074000320000000000000000FC
+:100C100007400932000000000008000077C02937B3
+:100C20000000361004100000173D90BA00000000CC
+:100C3000001800000780F432000003011200004099
+:100C4000F2C138B400000000000000FC32C02F30B8
+:100C5000000000000000001008803D32180036003F
+:100C6000000000F8730A03F900000000000000D43F
+:100C700002000032000090018038008022C072B66D
+:100C800000000C01120000C8020020B20000130195
+:100C90001201005C088020B20000361012000060D3
+:100CA00002802CB218000000000000F8738A03399B
+:100CB00009013600000000C002003692000000006A
+:100CC000000000F81F80FF3A00000000000000FC58
+:100CD00032008530000068010400008042603DB3AE
+:100CE00018000000000000F8738A03390F01360075
+:100CF000000000C002003692080000000000000062
+:100D000088CD853700000000000000200800723206
+:100D100000000000000800240800723200003610B5
+:100D20000410006C080072B2000000000018004CB3
+:100D3000080072320000361004200018080072B259
+:100D4000000000000030002808007232000000009F
+:100D5000002800300800723200000000000000602F
+:100D600008808232000022010600008062A082BC5E
+:100D7000000000000000000007000632070000002D
+:100D800000080000774A09390000361004100000FE
+:100D9000070082B200000000CA190000074082323A
+:100DA0000000210112000040F2C138B40000000030
+:100DB000000000D8024000320000470104380078EB
+:100DC000D9C572B00000260180010080028097B66C
+:100DD00000000000000000F882802F34000028018D
+:100DE00080010080128097B600000000000000F82B
+:100DF00092802F34040000000038003CB81C1738E3
+:100E0000000000000000003C28C083370000000004
+:100E1000003A002C08C07232000000000000001CE4
+:100E2000B8E0833A00000000CB2900200700003220
+:100E3000000046010400008002C081BC00000000E8
+:100E40000000003478A0813E000000000000001C7B
+:100E5000D8E0813C00003501063A0080B25C83BCDA
+:100E600000000000003A000089C172370700340119
+:100E70002B010004790A04B900000000CB00000433
+:100E80001941903400003801003A002C070000920C
+:100E900000000000003A002CD7E0723C0000000087
+:100EA0000000000009000032000000000000000403
+:100EB00009000032000000000000000007648332D7
+:100EC000000000000008000007008032000036101B
+:100ED0000410000007C086B20000000000180000E7
+:100EE00007C084320000550104000028D8A082BC4D
+:100EF0000000000000000000D820803A00004101FE
+:100F00000400008072802DBC00003F0112000044EC
+:100F100012E438B200004201000000D812802D9A7D
+:100F20000000BD0F00000004F94190F400004401EE
+:100F300004000018D8A081BC00002D010000006C46
+:100F4000D8E0869A00007A0F0000004408802DF255
+:100F500000002D0100000030080000920000000099
+:100F6000CB19002007000032070049012B010004C3
+:100F7000790A02B900000000CB0000041941903446
+:100F8000000000004D000000A7A0813E000000000E
+:100F90000008000007008032000036100410000036
+:100FA00007C086B2000000000018000007C08432AD
+:100FB0000000550104000028D8A082BC00000000F9
+:100FC00000000000D820803A000052010400008098
+:100FD00072802DBC000050011200004412E438B2AF
+:100FE00000005301000000D812802D9A0000BD0FB0
+:100FF00000000004F94190F400007A0F0000004462
+:1010000008802DF200004701000000300800009227
+:101010000000000000000004F94190340000560177
+:101020001200004412E438B218003600000000F844
+:10103000730A03F9000000000018000409807332ED
+:1010400000000000002800088980733700000000BD
+:101050000000008007008632410000000006008C7E
+:101060000700363200005F012908008007C085B202
+:10107000000062012810008C070000B2000063012C
+:101080000012008407000092000000000010008C95
+:10109000F7E0823A0000620128180080074090B211
+:1010A00000006301001200840700009200000000AD
+:1010B0000012008427E482320000660104000080F0
+:1010C00042603DB318000000000000F8738A033945
+:1010D00063013600000000C00200369200000000EC
+:1010E000000000FC02008532000036101200005C97
+:1010F00052812CB400000000000000D802800132B0
+:10110000000000000000008002003B3208406A013D
+:10111000F0010008088036B2000000000004013829
+:1011200008C06E3200000000E00000F41E40EF3CFA
+:10113000000071010B01008C080000B200006E017C
+:10114000F2010080020000B000000000000000F08A
+:101150000E003A3200008201E20000800E8083928D
+:1011600000007101F2010078C93B3ABC00007B012C
+:1011700002010080828097BC00000000000000A8EF
+:101180000200E832000076010400008022A22ABC9E
+:1011900000007A0104198B8002C07CBC00000000B2
+:1011A0000000008C18C0883A00000000000000A871
+:1011B00012802A3A00000000000000A802BD2A3078
+:1011C0000000740104010080E2A02ABC00007F013D
+:1011D0000200008082C088BC00000000E20000081D
+:1011E0000800003200000000000000A802808832E1
+:1011F0000000000000188BCC070000320000320312
+:10120000000000DC03000092000000000000003835
+:1012100008802A3200000000000000F00E003A3280
+:1012200000000000E20000800E802A320000000072
+:10123000000000A8028088320000000000188BCC5B
+:101240000700003200000000000000DC0300003254
+:101250000000000000000000078083320000000052
+:101260000000000079C02937602000000000000065
+:10127000890D903A00000000CA0100D812802D3A72
+:101280000000000000000000070001320000000024
+:10129000000800000700903200000000001000006D
+:1012A0000740E83200000000001800000780E83224
+:1012B00000000000000000FC0200003200003203C9
+:1012C00012010048F2C138B400008E010000008015
+:1012D00002000090000000000030007808807232A8
+:1012E0000400000000380054A85C16380B00000011
+:1012F0000038002CA8DC1638140000000000001C88
+:10130000884D853A0000000000000020080072327D
+:1013100000000000000800240800723200000000F5
+:101320000010006C08007232000000000018004C31
+:10133000080072320000361004200018080072B253
+:101340000000000000280030080072320000A101F7
+:10135000083C0014188072BC00000000000000145B
+:101360001840813C00000000000000000700063229
+:101370000700000000080000774A09390000361015
+:1013800004100000070082B200000000CA1900002B
+:10139000074082320000A00112000040F2C138B4C0
+:1013A00000000000000000D80240003200000000F1
+:1013B0000000006478C029370210000000000064BB
+:1013C000884D863A000000000000008008000032CE
+:1013D0000000000000000040080000320000000093
+:1013E0004D00000077A0813E0000000000080000D2
+:1013F00007408632000036100410000007C086B295
+:10140000000000000018000007C084320000B9018D
+:101410000400001CD8E081BC000000000000006453
+:10142000D860863A0000AF010400008072802DBCB5
+:101430000000AD011200004002C038B20000B5014A
+:10144000000000D812802D9A0000AF011200004069
+:10145000F2C138B418003600000000F8730A03F92E
+:101460000000B4010401008002802DBC0000B00126
+:10147000670000F8A2802FB500003610120000E8C7
+:1014800002C021B200000000000000D8024000327B
+:101490000000B70104000018D8A081BC0000A6011C
+:1014A0000000006CD8E0869A00005D0E0000004449
+:1014B00008802DF20000A601000000300800009214
+:1014C0000000B90112000040F2C138B41800360023
+:1014D000000000F8730A03F90000BE010401008057
+:1014E00002802DBC0000BA01670000F8A2802FB571
+:1014F00000003610120000E802C021B20000C9014D
+:1015000004010080020084BC00000000000000D440
+:101510000240003200000000000000A42240853A92
+:10152000040000000018004088CD74360000000060
+:10153000000000402800843700000000000000D4B4
+:10154000020000321400C9010400001C880D84BC94
+:1015500000000000000000780961853A8000361024
+:1015600006010080828D97BC00000000000000642E
+:10157000D860863A0000B501000000D80240009211
+:101580000000CB0104000018D8A081BC0000CD01F0
+:101590000000006CD8E0869A00005D0E0000004458
+:1015A00008802DF20000000000000030080000322A
+:1015B00000000000000000D40240003200000000E3
+:1015C000000000A422C0823A000000000000003C9D
+:1015D000B860853C0400D3018100006088CD74B6FA
+:1015E0000000000000040028F8A0753C0000D401B1
+:1015F00000080074088075920000000000080028B0
+:10160000F8A0753C000000000000002808A1823C02
+:1016100000000000000000A4F2602A3A0000000070
+:101620000008004808007532000000000020007C1F
+:10163000088075320900DA01041A007088CD74B090
+:1016400009000000001A004C87CD74317F000000B3
+:1016500000000064884D8631000000000000006436
+:101660002840863A00000000000000D80240003206
+:10167000000000000010000007408632000000005B
+:10168000000000D8028000320000000000100000BE
+:101690005761863A0000E301120000C8020020B240
+:1016A0000000E6011201005C088020B20000361044
+:1016B0001200006002802CB200000E012A0100D44A
+:1016C000020000B218003600CA0000F8730A03F9DD
+:1016D00000000F01000000F81F80FF9A00000000CA
+:1016E000000000D4024000320800000000000000AA
+:1016F00088CD8537000000000000001CE8A1823E74
+:1017000000000000000000A42240853A0000000014
+:1017100000080050078084320000ED0104010080C1
+:1017200072A082BC00000000001A004CC7E17432B5
+:10173000000000000000006808E1813A0000F001AC
+:1017400090010078F9A186BA00000000000000783E
+:101750001980973A00000000002000580780973257
+:1017600000000000000000D80280003200000000ED
+:101770000000000007008432000000004008000064
+:101780005721803A0000F4011200004CF2C138B435
+:1017900000000000000000000821803A0000000066
+:1017A0000000000408C0813200000000510000D891
+:1017B00002C0003200000000000000D4020000322D
+:1017C00000000000CB190020070000320700FC01D8
+:1017D0002B010084780A02B900000000CB000084CD
+:1017E00018418834000000004D00000077A0813EC1
+:1017F00000000000000800000700803200003610E2
+:101800000410000007C086B20000000000180000AD
+:1018100007C08432000036109F000028D8A082BC88
+:10182000000014020400001CD8E081BC0000080283
+:101830002D000000D82080BA00000502120100E847
+:1018400002C021B218003600000000F8730A03F944
+:10185000000007020401008022802DBC0000080265
+:10186000CD0100D80240849200000402000000F87C
+:10187000A2802F9500000B020400008072802DBC16
+:10188000000009021200004412E238B20000120205
+:10189000000000D812802D9A000000000000008493
+:1018A000F841883400000C021200004412E238B201
+:1018B00018003600000000F8730A03F90000110256
+:1018C0000601008022802DBC00000D02670000F898
+:1018D000A2802FB500000E02000000E802C0219295
+:1018E00000000000000000D802C0003200005D0EC1
+:1018F0000000004408802DF20000FA0100000030D2
+:101900000800009200001A0280000080D2802FB6EA
+:1019100000001702120100E802C021B218003600D0
+:10192000000000F8730A03F90000190204010080A6
+:1019300022802DBC00001A02000000D802408492D0
+:1019400000001602000000F8A2802F9500000000A1
+:10195000CD000084F841883400001B0212000044CE
+:1019600012E238B200000000000000D40240003251
+:1019700000000000000000A422C0823A0000230200
+:1019800004010080420086BC0000000000080058EE
+:1019900007408732000022028F010074184087BA86
+:1019A0000000000000000074080000320000250262
+:1019B00000040058F7A0869A00000000000000789C
+:1019C000F9A0863A2800000000080058878D973C4F
+:1019D00000000000000000D80240003218000000A3
+:1019E00000000000B7608539080000000008000012
+:1019F00087CD8537000028021200004CF2C138B4B0
+:101A0000000000000000004818A0843A0000000018
+:101A1000000000D40200003200000000000000803E
+:101A200057A1863A410000000006008C07003632BC
+:101A3000000000000008008007C0853200000000A0
+:101A40000010008C0740853200000000000000D824
+:101A5000028000320000361004000058088071B285
+:101A600000000000000000800880003218003600EE
+:101A7000000000F8730A03F9000035020401008039
+:101A800002802DBC00003202000000F8A2802F95D9
+:101A90000000320204010080180088BC00003802F7
+:101AA00090190058E89C85BA00000000000000581A
+:101AB0001880853A000000000018008007858530F6
+:101AC00000003D0204010080420086BC00000000CE
+:101AD000000000D8024000320000000000000008B2
+:101AE0008980713700003E020012008427E4829250
+:101AF00000000000001200840700003200004202D3
+:101B0000270000FC020085B20000420204000080B1
+:101B100042603DB318000000000000F8738A0339EA
+:101B20003E023600000000C002003692000036106F
+:101B30001200005C52812CB40000450204010080B8
+:101B4000028082BC00006801000000D40200009204
+:101B50000000480204010018D8A081BC00005D0EFE
+:101B60000000004408802DF20000E001C7010030B1
+:101B7000080000920000E001C701006CD8E0869ADE
+:101B800008000000C60100F893400139000032034C
+:101B900080018080320B6AB600000C0E0000003C11
+:101BA000030038F200004E020406018002C06EBC41
+:101BB00000003103000601EC56E06E9A00000000C0
+:101BC000C40701EC56E06E3A08C04F021200004014
+:101BD000A2CD39B218003600000000F8730A03F9EC
+:101BE0000000361003B8000009C06EBD53020000AB
+:101BF00000000088820D903A2F007C050000001C38
+:101C000008003692000036100000008002000090AC
+:101C10002C007C050000001C0800369200003610E5
+:101C200000000080020000900000361000000080DC
+:101C300002000090000036100000008002000090BA
+:101C400038007C050000001C0800369239007C0535
+:101C50000000001C0800369208000000000000F898
+:101C60009340013900000C0E0000003C030038F2E4
+:101C700000000000000000F842802F3408C05E021F
+:101C800012000040A2CD39B218003600000000F862
+:101C9000730A03F9000000000004017809C06E32E5
+:101CA00000000000006201EC068097320000000096
+:101CB000000601EC0640003200006302B50000D8C7
+:101CC000020000B200000000A50080A0360B6A34BC
+:101CD00000000000003002E806C02C3200000000C6
+:101CE000001801E00600003200000000000000F8CB
+:101CF00082852F3000007D050000001C0800369210
+:101D000008000000000000F89340013900006C0258
+:101D100080008080320B6AB6000032030000008031
+:101D20000200009000000C0E00000038030038F2A2
+:101D300000006F020402018002C06EBC000031038B
+:101D4000000201EC56E06E9A00000000C00301ECB6
+:101D500056E06E3A00C0700212000040A28D39B207
+:101D600018003600000000F8730A03F900007C0236
+:101D70003828001809006EB200007502042101081D
+:101D800069246EBC03007D050000001C080036922B
+:101D90000000790202300080829B90BC0000780233
+:101DA0000603018012C06EBC04007D050000001C0B
+:101DB0000800369205007D050000001C08003692E0
+:101DC00000007B020603018012C06EBC0B007D0583
+:101DD0000000001C080036920C007D050000001C6D
+:101DE0000800369200007E020421010869246EBCBE
+:101DF00003007D050000001C0800369200008202EE
+:101E000002300080829B90BC0000810206030180AA
+:101E100012C06EBC04007D050000001C0800369254
+:101E200005007D050000001C0800369200008402B9
+:101E30009F31010C69246EBC000000000000000C02
+:101E4000090000320000880204310004899B90BC24
+:101E5000000087020603018012C06EBC20007D05D1
+:101E60000000001C0800369221007D050000001CC7
+:101E70000800369200008A020402018012C06EBC83
+:101E800022007D050000001C0800369200008C0234
+:101E90000401000039A490BC23007D050000001C53
+:101EA0000800369224007D050000001C08003692D0
+:101EB000080036100C0000F8634001B910009102D0
+:101EC000C50100CC022015980800ED020C0000F8B6
+:101ED000434001B910000000C50100CC02201538B4
+:101EE00000000C0E0000003C030038F200009402D9
+:101EF0003601005C080580B00F007D050000001C65
+:101F00000800369210000000002C0200A9DB853981
+:101F1000000095021200005402A438B20000000034
+:101F20000008028C08C06E3200000000000C02980D
+:101F300028806E37000000000000009C3822143713
+:101F400000009E020430002808006EB20000361027
+:101F50000410006C08006EB2000000000018004C75
+:101F600008006E32000036100420001808006EB21F
+:101F70000500A1020038020078E16E99000000001F
+:101F8000510000D802000032000000000038027842
+:101F900009C06E32050000006808000077A197397B
+:101FA0000000A3021201000009C021B2180036008F
+:101FB000000000F8730A03F900000000545401FC0B
+:101FC00002C06E321410A70204000080A20D72B08D
+:101FD0000000510F0000002809C002F20E007D052C
+:101FE0000000001C080036920000B602331500A461
+:101FF00002C072B20000EA0280010080B20172B633
+:102000000101AD0204290080828D74BC080AEA0235
+:10201000042D0080828D74BC000000000030007C24
+:10202000080075320000B402003800881800759C62
+:10203000080AEA0204290080828D74BC10000000A6
+:10204000002C007C888D7537000000000030007C7B
+:1020500068DD87320000B3029F390088188075BCA4
+:102060001000000000340088888D75370000B4022D
+:10207000000000881880889C100000000034008850
+:10208000689D88390000B7029FF1018082DB87BC20
+:102090000000EA0200000080020000900000EA0256
+:1020A00080000080B20172B6000000000008004805
+:1020B0000800753200000000001000700800753242
+:1020C00000000000001C007438A275370000BC023C
+:1020D000831B007808C074B200000000000000F804
+:1020E000C2802F340000CC029F780180C2216EBCD8
+:1020F0000000C0029F990164881B87BC0000CD02CC
+:102100009F680164885B86BA0000000000000064DC
+:102110000800003200000000001600A402C0723265
+:1021200000000000003C02A4B25B2A3A000000005C
+:10213000003A027809C06E320000CE0208010004A5
+:10214000E8A575BC1000EA020B01001C080036B2BD
+:102150000000CC0204A10180829B84BC00007D05AC
+:102160009F980180C2216EBC00007D0506B10180F0
+:10217000825B87BC0000E9020B010080020000B016
+:102180000000CD0204990180C2216EBC0000E7026C
+:1021900002D4018092FB6EBC16007D050000001C7D
+:1021A0000800369217007D050000001C08003692DA
+:1021B0001C007D050000001C080036920000D002C3
+:1021C00004A10180829B84BC0000D70206A8018084
+:1021D000825B80BC0000D40204A9018002006EBCB6
+:1021E0000000E80204A10180829B84BC0000E80298
+:1021F00004010080124080BC14007D050000001C1A
+:10220000080036920000E8029FA0017829216EBCE8
+:102210000000E8020201008012A097BC0000CC027E
+:1022200000000080020000900000E3020400008033
+:10223000028082BC0000DC0202000080A26080BC40
+:1022400006007D052C01001C080036B200C0E0022B
+:1022500004010080A28D2FB006007D050000001C47
+:10226000080036920000E00204000080A26080BCFA
+:102270000000DF020603018012C06EBC09007D056C
+:102280000000001C080036920A007D050000001CBA
+:10229000080036920000E2020603018012C06EBC04
+:1022A00007007D050000001C0800369208007D052F
+:1022B0000000001C0800369202007D053801001C59
+:1022C000080036B20000E602020C0280A25B80BC6D
+:1022D0001F007D050000001C080036921E007D05D1
+:1022E0000000001C080036920000EB0200000028ED
+:1022F000094000920000EB020000002809800092D3
+:102300000000EB020000002809C000920000EB0270
+:1023100000000028090001920E00510F0000001C6F
+:10232000080036F200007D050000008002000090E9
+:10233000100036102A0000CC022015B800000C0E48
+:102340000000003C030038F21D00F102800100781B
+:1023500009E000B81D007D050000001C0800369251
+:1023600015007D050000001C0800369200000000EA
+:102370000000001CA805283008000000000000F83C
+:102380008340013900003E0380018080320B6AB631
+:1023900000000C0E00000038030038F27E0500003B
+:1023A0000000008882CD813A0000F9021D41025CE4
+:1023B000F80168B441003103000000F8A28D2F91AC
+:1023C00010000000D02C0200A9DB85390000960225
+:1023D0001201005402A438B20000FA02000000808A
+:1023E000020000900000000304B0008002006EBCF8
+:1023F0000000000380B9008082806EB600002510C6
+:102400000078016008006EF230007C05D700001CE7
+:10241000080036920000020380010080D2812FB6AE
+:1024200031007C05D700001C080036920000040330
+:102430008001008042812FB635007C05D700001C4A
+:10244000080036920000110304A8010809006EB2CA
+:102450000000000000200208899B903E0000000060
+:1024600000A00108899B903A000011039F88010891
+:10247000899B90BC000000000034020009C06E3D42
+:1024800000000000000C020409A46E3700000D03D8
+:102490000200008012A490BC0000000000000008B0
+:1024A000198090370000110302010280829B90BCCA
+:1024B00031007C05D700001C080036920000110393
+:1024C00004B0008002006EBC001211030401008001
+:1024D000A28D2FB032007C05D700001C0800369278
+:1024E00000003103000000F872812F950000000009
+:1024F000000000F842802F3408C050021201004052
+:10250000A2CD39B200001303000000800200009049
+:1025100008000000000000F89340013900003E036D
+:1025200080018080320B6AB60000000000000014B9
+:102530000840903200000C0E00000038030038F212
+:102540007E0500000000008882CD813A080000006E
+:10255000000000F89340013900003E0380018080B4
+:10256000320B6AB600000C0E00000038030038F28F
+:1025700000001F030420018052206EBC26007D0550
+:102580000000001C0800369225007D050000001C9C
+:102590000800369200002503040100D81E80EDBC1F
+:1025A00000002103B70000D80EC0EDB200002403E4
+:1025B00004010080423BEEBC00000000000000E08F
+:1025C0001E00EE3A00000000A70000D00E00EE3220
+:1025D00000000000007486CC02806C320000000015
+:1025E000000000000940E7320000290380018080DC
+:1025F000320B6AB6360028031200002C82CD2EB2B0
+:1026000000002B030401008042C52CBC00002C03F9
+:10261000000000CC0200009200000000000000CC8E
+:1026200012C02C3A0000270304010000190090BCDE
+:1026300000000000007486C806C02C3208003E036B
+:10264000000000F8C34001990000FA0D0000002CC2
+:10265000090000F200003203000000800200009038
+:102660000000FA0D0000002CF90100F400003B030B
+:1026700004000028098080B200000000000000D89B
+:10268000020000320000F10E00000008080000D235
+:1026900000003B0304000080028092BC180036005A
+:1026A000000000F8730A03F900003E038001008077
+:1026B000A2802FB600003E031201000009C021B223
+:1026C00018000000000000F8730A03393E033600CA
+:1026D000000000C00200369200003E03800100802E
+:1026E000A2802FB600003E031201000009C021B2F3
+:1026F00018003600000000F8730A03F9000000001B
+:10270000000000F80200003218003600000000F857
+:10271000738A029910000000000000E403003632C2
+:1027200002000001000000E003003732000000005A
+:10273000000000E40300363204000001000000E065
+:1027400003003732AA040000000000E40300363220
+:1027500009000001000000E0030037320000000023
+:10276000000000CC0F00003200070000000000E471
+:102770000300363206000001000000E0030037329B
+:1027800020000000000000E40300363208000001D1
+:10279000000000E00300373200010000000000E408
+:1027A0000300363205000001000000E0030037326C
+:1027B00030000000000000E4030036320700000192
+:1027C000000000E00300373200A00000000000E439
+:1027D0000300363208000008000000E00300373232
+:1027E00000000000000000A0020000320000000015
+:1027F000000000000B000032000052038B0100A01B
+:1028000012002ABA00000000000000A802000032F6
+:1028100000000000000000E0070000320000550347
+:102820000601008002802ABC000000000000009C1D
+:102830000200003200000000000000D4020000325C
+:1028400000000000000000CC020000320000000088
+:10285000000000D80200003200000000000000D09C
+:102860000200003200000000000000DC0200003224
+:1028700000000000000000F802000032000000002C
+:10288000000000C80200003200000000000000C488
+:1028900002000032000058038501009C12C029BAD2
+:1028A00000000000000000E4030036320B000004CA
+:1028B000000000E00300373280000000000000E468
+:1028C0000300363213000004000000E0030037323A
+:1028D00000200000000000E4030036320C00000479
+:1028E000000000E00300373200000000000000E4B8
+:1028F000030006320F000004000000E0030037323E
+:1029000000440000000000E4030036320D00000423
+:10291000000000E00300373200040000000000E483
+:102920000300363214000004000000E003003732D8
+:102930009F000000000000E4030036321500000490
+:10294000000000E00300373200000000000000E457
+:102950000300363218000004000000E003003732A4
+:1029600060000000000000E4030036321D00000497
+:10297000000000E00300373200000000000000E427
+:10298000030004321E000004000000E003003732A0
+:1029900070000000000000E4030036321F00000455
+:1029A000000000E00300373200000000000000E4F7
+:1029B0000300003220000004000000E00300373272
+:1029C000A0030000000000E40300363217000004FA
+:1029D000000000E00300373240000000000000E487
+:1029E000030036321B000004000000E00300373211
+:1029F00060000000000000E4030036321C00000408
+:102A0000000000E00300373200000000000000E496
+:102A10000340003216000004000000E003003732DB
+:102A200000010000000000E4030036321A00000438
+:102A3000000000E00300373220010000000000E445
+:102A40000300363219000004000000E003003732B2
+:102A500080000000000000E4030036320B0000019B
+:102A6000000000E00300373200010000000000E435
+:102A7000030036320C000001000000E00300373292
+:102A8000FEFF0000000000AC020036320000000033
+:102A9000000000000900003218000000000000F8EB
+:102AA0000364023900008B0385010000190090BA0D
+:102AB00025260000000000E403003632010000017A
+:102AC000000000E00300373200000000000000803A
+:102AD0000F00003200000000000000840F000032F0
+:102AE00008000000000000F8F34001390800000071
+:102AF000000000F8E340013908000000000000F881
+:102B0000C340013908000000000000F8B34001395B
+:102B100008000000000000F8A34001390800000090
+:102B2000000000F89340013908000000000000F8A0
+:102B30008340013908000000000000F873400139AB
+:102B400008000000000000F86340013908000000A0
+:102B5000000000F85340013908000000000000F8B0
+:102B60004340013908000000000000F833400139FB
+:102B700008000000000000F81340013900000000C8
+:102B8000000000F80380003200000000000000C8D0
+:102B90003F80FC35000000000000009C0200003275
+:102BA0000000000000000000030000326E00000082
+:102BB000000000D0020036320000000000000028B3
+:102BC000034038320000361004010080D20130B6D4
+:102BD0000000A303040100D012002DBCE00300009C
+:102BE000000000E40300363203000001000000E0B2
+:102BF0000300373200000000170000D0020000324E
+:102C000000000000000000ACE10000340000000003
+:102C1000000001E00600003200000000000801E4AE
+:102C20000600003200000000000E01EC0600003239
+:102C300000000000001001E006000032000000006B
+:102C4000000000D012002D3A6E00AB03020100809C
+:102C5000820D2DBC020000000000009CAE0D02326F
+:102C600000000000000000A8020000320000000088
+:102C7000008886CC0700363200000000008A86CC2F
+:102C80000700003A002400000000000409803632EA
+:102C90000000361012000064024090B200000000F4
+:102CA000000000042940903A0000B70312000078A9
+:102CB00009C020B2000000000000007809459030F3
+:102CC0000000B50302010080C28297BC0000000032
+:102CD000000000840200003200000000000000CC70
+:102CE000030000320000BB038E010080024028B2C6
+:102CF0000000510E000000D8020000D2150F0000A5
+:102D00000000008C0E0036325200000000000074FB
+:102D10000E00363218000000000000E403003632D6
+:102D200009000002000000E003003732FECA000084
+:102D3000000000E4030036320A000002000000E058
+:102D4000030037320000C60312010000094020B220
+:102D50000000C40300000080020000900000C603D1
+:102D600012000004094020B20000C9039F01008046
+:102D7000020090B20000C80312000008094020B20F
+:102D80000200C40304010078092417B806000000FB
+:102D900000000078096416380000C40304010080B4
+:102DA000028197BCFE0000000000004403003632A0
+:102DB000FE00360000000048030036920000361086
+:102DC00012000000094020B20000CF0312000004EE
+:102DD000094020B20000D2039F010080020090B29F
+:102DE0000000D10312000008094020B200000000DA
+:102DF000000000B402009032000036100000008095
+:102E000002000090000036100000008002000090D8
+:102E10000000361000000080020000900000361014
+:102E200000000080020000900000361000000080CA
+:102E300002000090000036100000008002000090A8
+:102E400000003610000000800200009000003610E4
+:102E5000000000800200009000003610000000809A
+:102E60000200009000003610000000800200009078
+:102E700000003610000000800200009000003610B4
+:102E8000000000800200009000003610000000806A
+:102E9000020000900600EA030000000C0964169886
+:102EA00000004902000000140840909200006902EE
+:102EB0000000001408409092340015030000001C2C
+:102EC00008003692120015030000001C080036921C
+:102ED0003A0015030000001C08003692000036106E
+:102EE000000000800200009000005B02000000145F
+:102EF0000840909200001D04000000800200009035
+:102F000000001A030000001408409092EB03000038
+:102F10000000008882CD903A0D000D04000000FCF6
+:102F200002E416980D001E04000000FC02E416984E
+:102F30000D002704000000FC02E416980000340491
+:102F4000000000800200009000003D04000000002E
+:102F50000940909D000040040000008002000090A5
+:102F600000004904000000800200009000005204AC
+:102F7000000000800200009000005B0400000000E0
+:102F80000940909D00006004000000800200009055
+:102F900000006804000000000940909D00006D04DE
+:102FA00000000080020000900000DC04000000002F
+:102FB000090000920000DC040000000009400092BB
+:102FC0001D07DE04000000A0020036920000EC04A1
+:102FD0000000008002000090000036100000008019
+:102FE0000200009000001D04000000DC0F409092E1
+:102FF0000000B00400000080020000900000B50452
+:10300000000000D4020000921000CA0400000084F6
+:103010001F64149800001D04000000EC0E40909204
+:103020000000D604000000800200009000001D0493
+:10303000000000D40E4090920000D90400000080EF
+:103040000200009000006D05000000DC0E40909230
+:103050000000FB0400000080020000900800000552
+:10306000000000501F24169800000F05000000D833
+:10307000020000920D001905000000FC02E4169801
+:1030800000001A05000000D0020000920000F600C7
+:10309000000000D002000092000035100000008007
+:1030A0000200009000003610000000800200009036
+:1030B00008000000000000F8934001390000000003
+:1030C000000000780945903000003E0306010080B2
+:1030D000228097BC02001004B00000A0F20B00B9DF
+:1030E00000000000A00000046B41903400003E038B
+:1030F000800100800240B0B600003E030400008062
+:103100000280B0BC00000000000000D802000032C5
+:1031100000000000000000A822C02F3700000000BF
+:1031200000000000670100340042000000080000B9
+:10313000878D2A3A00003610041000000700B0B254
+:1031400000000000001800000700D03200001A0440
+:1031500012000048F2C138B418000000000000F866
+:10316000730A03393E033600000000C002003692A5
+:1031700008003E03000000F893400199000021047C
+:103180009F000080020090B20000000000000008D4
+:1031900009409032000000000000000409C0FD3228
+:1031A00002002104B00000A0F20B00B900000000F2
+:1031B000000000000B8090320000000000000000C2
+:1031C0000D40903200000000A00000043B40B031F0
+:1031D00000001D040400008002C02FBCF20E1D047C
+:1031E0000000008C0E00369208000000000000F87D
+:1031F0009340013902002804B00000A0F20B00B98E
+:1032000000002B04800100801240B0B600000000D6
+:10321000000000043B40B033000000000000000448
+:10322000FD4BD03500000000000000080B0000320C
+:1032300000000000A000000C1BE4B03200003E03C0
+:103240000B000080020000B0000031040400008088
+:10325000024090B21F003E03000000801140009920
+:103260000000300404000080123EF8BA00000000A4
+:10327000000000800100F83200003E0300000090D2
+:103280000140F89200003610800000800281FCB6F8
+:10329000000038049F000080020090B2000000008F
+:1032A0000000000809409032000000000000000407
+:1032B00009C0FD3200000000000000E403809032ED
+:1032C00009000004000000E00300373200000000A5
+:1032D000000000E4034090320A000004000000E017
+:1032E0000300373200001D04000000C80F81FC9469
+:1032F00000000000000000E47300903C1000000497
+:10330000000000E00300373200001D0400000080D0
+:1033100002000090000043049F000080020090B271
+:10332000000000000000000809409032000000008A
+:103330000000000409C0FD3200000000000000E4AD
+:103340000380903201000004000000E003003732E7
+:1033500000000000000000E00F809032000000003C
+:10336000000000E40340903202000004000000E08E
+:103370000300373200001D04000000E40F4090926B
+:1033800000004C049F000080020090B2000000008A
+:103390000000000809409032000000000000000416
+:1033A00009C0FD3200000000000000E403809032FC
+:1033B00003000004000000E00300373200000000BA
+:1033C000000000A80E80903200000000000000E421
+:1033D0000340903204000004000000E00300373294
+:1033E00000001D04000000AC0E4090920000550447
+:1033F0009F000080020090B2000000000000000862
+:1034000009409032000000000000000409C0FD32B5
+:1034100000000000000000E403809032050000047A
+:10342000000000E00300373200000000000000E46C
+:103430000340903206000004000000E00300373231
+:1034400000000000000000440F80903200001D04C6
+:10345000000000480F40909200005D0404010080CD
+:10346000824290BC00000000000000000900003211
+:1034700000000000000000E403009032120000048D
+:10348000000000E00300373200001D04000000408F
+:103490001F40909C000063049F000080020090B2D7
+:1034A0000000000000000008094090320000000009
+:1034B0000000000409C0FD3200000000000000E42C
+:1034C0000380903207000004000000E00300373260
+:1034D00000000000000000E40340903208000004F7
+:1034E000000000E00300373200001D0400000080EF
+:1034F0000200009000006A0404010080824290BC37
+:103500000000000000000000090000320000000080
+:10351000000000E40300903211000004000000E00D
+:103520000300373200001D04000000FC1F40909C87
+:10353000000070049F000080020090B200000000B4
+:103540000000000809409032000000000000000464
+:1035500009C0FD32030900000000002808003632CF
+:103560000000890400000030080036D200009304F7
+:1035700000000044088000D20000790404010080AB
+:10358000020084B2030E000000000028080036325A
+:103590008000890400000030080036D20000930447
+:1035A0000000004408C000D200007904040100803B
+:1035B000020084B200008004000000440800019270
+:1035C0008002000000000000070036328C45000039
+:1035D000000800000700363200003610041000001A
+:1035E000078090B2000000000018000007409032F1
+:1035F0000000000000000048F2C1383400007E04E2
+:1036000012000080020000B018003600000000F830
+:10361000730A03F920000000000000E403003632C2
+:1036200009000002000000E0030037320000000043
+:10363000000000E4034084320A000002000000E0C1
+:10364000030037328C450000000000A8020036322B
+:10365000A000000000000000090036320000000059
+:10366000000000E0070000320000860406010000B0
+:10367000190090BC00001D040000008002000090B2
+:103680008C450000000000C80200363280020000B5
+:103690000000003C0800363200000000000000344A
+:1036A0000800013200008E0402000080D2E083BCDA
+:1036B000000000000000003408C083320000A404B1
+:1036C00000000080020000F000000000000000A0E8
+:1036D000078083320000000000000030D820833AC9
+:1036E00000008C040401003CD8E083BC0000000012
+:1036F00000010080020000500000000000000040B7
+:1037000008000032000000000000004808000032FD
+:103710008C450000000000C80200363200020000A4
+:10372000000000C8828D2C3A800000000000003CA0
+:10373000080036320000000000000078098078326E
+:103740005A5A000004010080828D975C00009C049E
+:1037500002010048A89E84BA000000000000004852
+:103760001880843A00009A040601003C28C083BCFB
+:10377000000000000000007809858430100000007F
+:1037800000000048888D84360000A10490010048A4
+:10379000E8A584BA00000000000000481880843AC0
+:1037A0000000000000000048088584300000000090
+:1037B000040100800285845C0000000000010040DC
+:1037C0000840005200000000000000E403008332C3
+:1037D00001000002000000E0030037320C00AA04E0
+:1037E0000000002CD8A082F905000002000000E0D3
+:1037F00003003732000000000000008002000030AB
+:10380000000000000001003808403E720000000087
+:10381000000000E403C0823202000002000000E069
+:103820000300373202000002000000E003003732DC
+:103830000000000000000080020000300000AC0426
+:1038400080000080F2403EB60000000000010080D1
+:10385000020000700000B3049F000080020090B2DC
+:103860000000000000000008094090320000000045
+:103870000000000409C0FD320000000000000084C8
+:103880000E80903200001D04000000880E409092CF
+:1038900008000000000000F8934001390000B9045E
+:1038A0009F000080020090B20000000000000008AD
+:1038B00009409032000000000000000409C0FD3201
+:1038C00000000000000000200740F532000000006A
+:1038D0000008002007000032000000000010002057
+:1038E00007C0F53200000000001800200740F63243
+:1038F00000000000002000200780F63200000000D9
+:103900000028002007C0F632000000000030002030
+:103910000700F73200000000003800200780FF3267
+:1039200000000000000000D802000032000000008B
+:1039300000000000074009320000000000080000FD
+:1039400077C0293700000000001000000780903287
+:103950000000000000180000074090320000C6047C
+:1039600012000048F2C138B418003600000000F818
+:10397000730A03F90000000000000008C8010034C9
+:1039800000003203000000FC020000920000CC04A2
+:1039900080010080F24190B60000CD04000000C814
+:1039A0002F81FC9400000000000000C82F81FC352E
+:1039B00000000000000000800F4590300000D0049F
+:1039C00002000080027EF8BC0000000000000084BD
+:1039D0000F00F83200000000000000001940F83726
+:1039E00000000000000000843F40F83700000000A5
+:1039F000000000840F64F83A00000000000000009E
+:103A00001900F83700000000000000803F00F83780
+:103A100000001D04000000800F24F89A0000D80464
+:103A200080010080F24190B600001D04000000C833
+:103A30004F81FC9400001D04000000C84F81FC95DC
+:103A40000000DB0404010080024090BC0000000084
+:103A50000000000409C0003200001D04000000E462
+:103A60001E40909C00000000000000A8220090373B
+:103A700000001D04000086C007409092080000006E
+:103A8000000000F8934001390D000000000000FC28
+:103A900002E41638000000000000000009000232B5
+:103AA0000000E604040000800200B0B20000000044
+:103AB000000000000B00003220000000000000A009
+:103AC000820D2A3A0000E10404010000190090BCB4
+:103AD0000000E804000000287901009400000000C4
+:103AE000000000C83F80FC34408000000000002837
+:103AF000098036320000F10E000000D8020000D22A
+:103B000000003E0304000080028092BC1800000008
+:103B1000000000F8730A03393E033600000000C0BD
+:103B200002003692EA05F20404010080824D90BC46
+:103B300000000000000000EC0F00153200FE1F0026
+:103B4000000000F00F003732F0FF0000000000E836
+:103B50000F00363298050000000000F40F003632E6
+:103B60000000F804000000C84F80FC953623361092
+:103B700004010080824D90BC00000000000000ECB9
+:103B80000F80143200F81F00000000F00F003732E1
+:103B9000C0FF0000000000E80F0036329827000048
+:103BA000000000F40F00363200000000000000C8E2
+:103BB0004F80FC3404000000000000608F4D903AFC
+:103BC0000000BC0E00000080020000D000001D04B8
+:103BD00000000080020000900000FD0480010080D1
+:103BE000024090B600000000000000C86F80FC3466
+:103BF0000000FF0480010080124090B60000000029
+:103C0000000000C85F80FC3400001D04000000803C
+:103C1000020000900000020504010080324090B0D4
+:103C200080011D04000000C88F8DFC910000040578
+:103C300080000080124090B600000505000000C81A
+:103C40007F80FC9500000000000000C87F80FC34ED
+:103C50000000070580000080024090B600000805C3
+:103C6000000000C88F80FC9500000000000000C824
+:103C70008F80FC3400000B0580000080224090B64D
+:103C8000F20E00000000008C0E00363200000D0520
+:103C9000000000C81F81FC95150F00000000008C7B
+:103CA0000E00363200000000000000C81F81FC3406
+:103CB000100000000000004C1F24163800001D04F6
+:103CC000000000501F00F59C000012059F000080BE
+:103CD000020090B20000000000000008094090328D
+:103CE000000000000000000409C0FD3200000000D8
+:103CF000000000001700F53A8C44000000080000A6
+:103D0000070036320000361004100000078090B221
+:103D10000000000000180000074090320000160567
+:103D200012000040F2C138B418003600000000F85C
+:103D3000730A03F900001D040000008002000090D7
+:103D400000001D04000000EC0340909200001A05E2
+:103D5000B20000D8020000B200000000000201EC36
+:103D600016E46E3A08000000000000F893400139A4
+:103D700000004005171001F802006EB2060025058C
+:103D800004010080828D2FB003000000000000F8C5
+:103D9000828D2F3200C0050E00000028098036D227
+:103DA00000000000000201EC16C06E3C00000000A4
+:103DB000001886C80600003218003600000000F81F
+:103DC000730A03F900002605000000D002000092EB
+:103DD00000002B050419868002806CBC00000000E6
+:103DE0000000000009006E3200000000C10800045D
+:103DF00009006E3200000000C01586780FC06C32DA
+:103E0000000030058001008022802FB600003005C0
+:103E1000001886C806400092000000000040000024
+:103E200009006E3200000000C248000409006E3232
+:103E300000000000C01686780FC06C32000030050C
+:103E40008001008012802FB600000000001886C894
+:103E500006000032004000000000002809803632D1
+:103E6000000038050402018002C06EBC0000050E8F
+:103E7000000201EC16C06EDC0000360580000080F8
+:103E800002802FB600003805810000F822802FB490
+:103E900000003805001886C806400092000038056A
+:103EA000820000F812802FB400000000001886C8BD
+:103EB0000600003200000000001086C80600003234
+:103EC000000000000000000007C00A3200380000B7
+:103ED0000008000007003632000036100410000011
+:103EE000070090B200000000001800000740903268
+:103EF00000003D0512000040F2C138B41800360041
+:103F0000000000F8730A03F900000000170100F830
+:103F1000A2802F3400000000001086A842806C3779
+:103F200000004A051200703802007EB20000361010
+:103F30001200703C02007EB2000036101200703099
+:103F400002007EB2000036101200703402007EB211
+:103F50000000410502010080B2822ABC000000007E
+:103F6000170000D002000032060025050401008081
+:103F7000828D2FB000001F050403018002C06EBCBB
+:103F800000005505000000800200009000004C0574
+:103F90000403018002C06EBC00005505001086C8F5
+:103FA00046802A9600000000001086C846802A3607
+:103FB000000050058000008012802FB603005205DB
+:103FC000220000F8828D2FB200005205001886C82A
+:103FD00006000092000055058000008022802FB668
+:103FE00000000000C20100F802802F3500C0050E5D
+:103FF00000000028098036D200000000000201EC19
+:1040000016C06E3C18003600000000F8730A03F971
+:1040100000000000001001E006802F3200000000C8
+:10402000000000A8E100003400000000A20000FC35
+:10403000020000320000320380010080A2802FB60F
+:1040400000005B05B90100D8028001B20000320314
+:10405000000000F80200009200000000000000389C
+:104060001880F73A0000000000000038F8BF8330E5
+:1040700000005F0504010080F2BD83BC0000320334
+:10408000A90000F80200009200C066051801000CAB
+:10409000A8CD3EB200006205840000741F40F7BA4C
+:1040A00000003203A90000F80200009200000000A6
+:1040B000000000740F00003200C066051801000CFB
+:1040C000A8CD3EB218003600000000F8738A03F94C
+:1040D00000006305000000B0020000920000000034
+:1040E0000000007C0F8083320000000000280000E8
+:1040F000070000320000000000300000070000321E
+:104100000001008000380000070037320000000086
+:10411000003C000C0780833200006B051200004851
+:1041200002C080B200003203A9000008E801009438
+:104130000000730504010080A2C0EDBC5200000025
+:10414000000000740E00363200000000000000C0C5
+:104150000E400132407E0500000000B40E003732F0
+:1041600000000000000000C40E80073264007805E3
+:10417000000000CC0E003692290000000000007400
+:104180000E00363200000000000000C00E40003279
+:10419000A08C0000000000B40E00363200000000C9
+:1041A000000000C40EC0003200000000000000CC7F
+:1041B0000E80023210000000000000E4337BEC3976
+:1041C0001E000001000000E0030037320000000084
+:1041D000000000C86EC0EC3700001D04000000D8CD
+:1041E0000EC0ED927E0500000000008882CD813A6D
+:1041F0007E0500000000008882CD813ABD050000E8
+:104200000018018882CD6E3AC605000000180188AA
+:1042100082CD6E3ACF0500000018018882CD6E3A3B
+:10422000D80500000018018882CD6E3AE105000033
+:104230000018018882CD6E3AEA0500000018018856
+:1042400082CD6E3AF30500000018018882CD6E3AE7
+:10425000FC0500000018018882CD6E3A05060000BA
+:104260000018018882CD6E3A0E0600000018018801
+:1042700082CD6E3A170600000018018882CD6E3A92
+:10428000200600000018018882CD6E3A2906000041
+:104290000018018882CD6E3A3206000000180188AD
+:1042A00082CD6E3A3B0600000018018882CD6E3A3E
+:1042B000440600000018018882CD6E3A4D060000C9
+:1042C0000018018882CD6E3A560600000018018859
+:1042D00082CD6E3A5F0600000018018882CD6E3AEA
+:1042E000680600000018018882CD6E3A7106000051
+:1042F0000018018882CD6E3A7A0600000018018805
+:1043000082CD6E3A830600000018018882CD6E3A95
+:104310008C0600000018018882CD6E3A95060000D8
+:104320000018018882CD6E3A9E06000000180188B0
+:1043300082CD6E3AA70600000018018882CD6E3A41
+:10434000B00600000018018882CD6E3AB906000060
+:104350000018018882CD6E3AC2060000001801885C
+:1043600082CD6E3ACB0600000018018882CD6E3AED
+:10437000D40600000018018882CD6E3ADD060000E8
+:104380000018018882CD6E3AE60600000018018808
+:1043900082CD6E3AEF0600000018018882CD6E3A99
+:1043A000F80600000018018882CD6E3A010700006F
+:1043B0000018018882CD6E3A0A07000000180188B3
+:1043C00082CD6E3A130700000018018882CD6E3A44
+:1043D0001C0700000018018882CD6E3A25070000F6
+:1043E0000018018882CD6E3A2E070000001801885F
+:1043F00082CD6E3A0000F702000000D40200009265
+:1044000000007202000000800200009037070000E8
+:10441000001C018882CD6E3A3C070000001C018818
+:1044200082CD6E3A41070000001C018882CD6E3AB1
+:1044300046070000001C018882CD6E3A4B07000041
+:10444000001C018882CD6E3A50070000001C0188D4
+:1044500082CD6E3A55070000001C018882CD6E3A6D
+:104460005A070000001C018882CD6E3A5F070000E9
+:10447000001C018882CD6E3A64070000001C018890
+:1044800082CD6E3A69070000001C018882CD6E3A29
+:104490006E070000001C018882CD6E3A7307000091
+:1044A000001C018882CD6E3A78070000001C01884C
+:1044B00082CD6E3A7D070000001C018882CD6E3AE5
+:1044C00082070000001C018882CD6E3A8707000039
+:1044D000001C018882CD6E3A0000FC02000000D46E
+:1044E0000200009200001203000000D402000092BB
+:1044F00000003C0900000010088001920000361006
+:1045000000000080020000900000361000000080D3
+:1045100002000090000036100000008002000090B1
+:1045200000003610000000800200009000003610ED
+:1045300000000080020000900000361000000080A3
+:104540000200009000003610000000800200009081
+:1045500000003610000000800200009000003610BD
+:10456000000000800200009000007B0900000010A5
+:1045700008800092000036100000008002000090C9
+:10458000000036100000008002000090000036108D
+:104590000000008002000090000036100000008043
+:1045A0000200009000003610000000800200009021
+:1045B000000036100000008002000090000036105D
+:1045C0000000008002000090000036100000008013
+:1045D00002000090000036100000008002000090F1
+:1045E00000008809000000100880009200003610CA
+:1045F00000000080020000900000361000000080E3
+:10460000020000900000CF09000000100840019255
+:1046100000003610000000800200009000003610FC
+:1046200000000080020000900000361000000080B2
+:104630000200009000003610000000800200009090
+:104640000000361000000080020000900000D70932
+:104650000000001008C0009200003610000000802A
+:10466000020000900000D7090000001008C000926E
+:1046700000003D0C000000100840019200003610C0
+:1046800000000080020000900000D7090000001028
+:1046900008C0009200003610000000800200009068
+:1046A000000036100000008002000090000036106C
+:1046B00000000080020000900000E40900000010EB
+:1046C00008C0009200003610000000800200009038
+:1046D0000000E4090000001008C0009200003D0C3A
+:1046E0000000001008400192000036100000008019
+:1046F000020000900000E4090000001008C00092D1
+:10470000000036100000008002000090000036100B
+:1047100000000080020000900000361000000080C1
+:10472000020000900000E2090000001008C00092A2
+:104730000000361000000080020000900000E20936
+:104740000000001008C0009200003D0C00000010A6
+:104750000840019200003610000000800200009026
+:104760000000E2090000001008C0009200003610AE
+:104770000000008002000090000036100000008061
+:10478000020000900000361000000080020000903F
+:1047900000003610000000800200009000007A0A3D
+:1047A0000000001008C000920000D40900000010B2
+:1047B000080001920000CF0900000010084001929B
+:1047C000000036100000008002000090000036104B
+:1047D0000000008002000090000036100000008001
+:1047E00002000090000036100000008002000090DF
+:1047F000000036100000008002000090000036101B
+:1048000000000080020000900000750A0000001007
+:10481000088000920000D4090000001008000192F6
+:104820000000CF090000001008400192000036107F
+:1048300000000080020000900000361000000080A0
+:10484000020000900000361000000080020000907E
+:1048500000003610000000800200009000003610BA
+:104860000000008002000090000036100000008070
+:10487000020000900000750A00000010080001927C
+:104880000000D40900000010080001920000CF09C8
+:104890000000001008400192000036100000008067
+:1048A000020000900000361000000080020000901E
+:1048B000000036100000008002000090000036105A
+:1048C0000000008002000090000036100000008010
+:1048D00002000090000036100000008002000090EE
+:1048E0000000E40A00000010088000920000D409D3
+:1048F00000000010080001920000CF090000001025
+:104900000840019200003610000000800200009074
+:1049100000003610000000800200009000003610F9
+:1049200000000080020000900000361000000080AF
+:10493000020000900000361000000080020000908D
+:104940000000361000000080020000900000E40A21
+:1049500000000010080001920000D40900000010BF
+:10496000080001920000CF090000001008400192E9
+:104970000000361000000080020000900000361099
+:10498000000000800200009000003610000000804F
+:10499000020000900000361000000080020000902D
+:1049A0000000361000000080020000900000E309C3
+:1049B0000000001008800092000036100000008007
+:1049C000020000900000E30900000010088000923F
+:1049D00000003D0C0000001008400192000036105D
+:1049E00000000080020000900000361000000080EF
+:1049F00002000090000036100000008002000090CD
+:104A00000000361000000080020000900000361008
+:104A100000000080020000900000E3090000001088
+:104A20000800019200003610000000800200009093
+:104A30000000E309000000100800019200003D0C96
+:104A400000000010084001920000361000000080B5
+:104A5000020000900000361000000080020000906C
+:104A600000003610000000800200009000003610A8
+:104A7000000000800200009000003610000000805E
+:104A8000020000900000361000000080020000903C
+:104A900000008C0700000010080001920000361092
+:104AA000000000800200009000008C070000001051
+:104AB00008400192000036100000008002000090C3
+:104AC0000000361000000080020000900000361048
+:104AD00000000080020000900000361000000080FE
+:104AE00002000090000036100000008002000090DC
+:104AF00000005E0C00000010084001920000540C01
+:104B0000000000100840019200005E0C0000001040
+:104B1000084001920000CF090000001008400192F7
+:104B200000003610000000800200009000005E0CC3
+:104B300000000010084001920000361000000080C4
+:104B4000020000900000361000000080020000907B
+:104B50000000810900000010084000920000810957
+:104B60000000001008800092000081090000001081
+:104B700008C00092000081090000001008000192A6
+:104B80000000860900000010084001920000810921
+:104B90000000001008800192000081090000001050
+:104BA00008C0019200003610000000800200009052
+:104BB0000000361000000080020000900000361057
+:104BC00000000080020000900000490B000000106F
+:104BD000088000920000490B0000001008C00092FD
+:104BE0000000490B00000010080001920000CF09EE
+:104BF0000000001008400192000036100000008004
+:104C0000020000900000490B0000001008C0019253
+:104C100000003610000000800200009000003610F6
+:104C200000000080020000900000361000000080AC
+:104C3000020000900000361000000080020000908A
+:104C400000003610000000800200009000003610C6
+:104C500000000080020000900000680C00000010BE
+:104C60000840019200003610000000800200009011
+:104C70000000361000000080020000900000361096
+:104C8000000000800200009000003610000000804C
+:104C9000020000900000D80C0000001008400192B3
+:104CA0000000DB0C000000100840019200004C0CDA
+:104CB00000000010084001920000DB0C0000001012
+:104CC0000840019200008C0700000010084001928B
+:104CD0000000361000000080020000900000DB0C95
+:104CE000000000100840019200008D070000001035
+:104CF00008000292000036100000008002000090C0
+:104D00000000361000000080020000900000DC0C63
+:104D1000000000100840019200004C0C0000001040
+:104D2000084001920000DC0C0000001008400192D5
+:104D300000008C07000000100840019200003610AF
+:104D400000000080020000900000DC0C0000001059
+:104D50000840019200003610000000800200009020
+:104D600000003610000000800200009000003610A5
+:104D700000000080020000900000E10C0000001024
+:104D8000088000920000E10C0000001008C00092B2
+:104D90000000E10C00000010080001920000CF09A3
+:104DA0000000001008400192000036100000008052
+:104DB000020000900000E10C0000001008C0019209
+:104DC0000000361000000080020000900000361045
+:104DD00000000080020000900000361000000080FB
+:104DE00002000090000036100000008002000090D9
+:104DF0000000361000000080020000900000361015
+:104E000000000080020000900000361000000080CA
+:104E10000200009000006A090000001008400092A3
+:104E200000003610000000800200009000003610E4
+:104E3000000000800200009000003610000000809A
+:104E40000200009000003610000000800200009078
+:104E50000000F10C00000010088000920000F10C2E
+:104E60000000001008C000920000F10C00000010CB
+:104E7000080001920000CF090000001008400192D4
+:104E80000000361000000080020000900000F10CCD
+:104E90000000001008C001920000361000000080E1
+:104EA0000200009000003610000000800200009018
+:104EB0000000361000000080020000900000050D88
+:104EC00000000010088000920000050D0000001096
+:104ED00008C000920000050D0000001008000192BB
+:104EE0000000CF09000000100840019200003610B9
+:104EF00000000080020000900000050D000000107E
+:104F000008C00192000036100000008002000090EE
+:104F100000008C070000001008000092000036100E
+:104F2000000000800200009000008C0700000010CC
+:104F3000088000920000130D0000001008C00092CD
+:104F400000008C07000000100800019200008C0790
+:104F500000000010084001920000361000000080A0
+:104F60000200009000003610000000800200009057
+:104F70000000361000000080020000900000361093
+:104F80000000008002000090000036100000008049
+:104F90000200009000008C070000001008800092C2
+:104FA0000000210D000000100880009200008C0716
+:104FB000000000100800019200008C0700000010A3
+:104FC00008400192000036100000008002000090AE
+:104FD0000000361000000080020000900000361033
+:104FE00000000080020000900000361000000080E9
+:104FF00002000090000036100000008002000090C7
+:1050000000008C0700000010088000920000210DB5
+:10501000000000100800019200008C070000001042
+:105020000800019200008C07000000100840019267
+:1050300000003610000000800200009000003610D2
+:105040000000008002000090000036100000008088
+:105050000200009000003610000000800200009066
+:1050600000003610000000800200009000003610A2
+:10507000000000800200009000008C07000000107B
+:1050800008800092000036100000008002000090AE
+:1050900000008C070000001008400192000036104C
+:1050A0000000008002000090000036100000008028
+:1050B0000200009000003610000000800200009006
+:1050C0000000361000000080020000900000361042
+:1050D00000000080020000900000FD0C00000010A5
+:1050E000088000920000FD0C0000001008C0009233
+:1050F0000000FD0C00000010080001920000CF0924
+:1051000000000010084001920000361000000080EE
+:10511000020000900000FD0C0000001008C0019289
+:1051200000003610000000800200009000003610E1
+:105130000000008002000090000036100000008097
+:105140000200009000003610000000800200009075
+:1051500000003610000000800200009000003610B1
+:1051600000000080020000900000310D00000010DF
+:10517000080002920000361000000080020000903B
+:105180000000361000000080020000900000361081
+:105190000000008002000090000036100000008037
+:1051A0000200009000003610000000800200009015
+:1051B000000088090000001008C0019200003610AD
+:1051C0000000008002000090000036100000008007
+:1051D000020000900000CF0900000010084001927A
+:1051E0000000361000000080020000900000C1099D
+:1051F0000000001008C0019200003610000000807E
+:1052000002000090000036100000008002000090B4
+:1052100000003610000000800200009000008809A5
+:10522000000000100880009200003610000000808E
+:105230000200009000003610000000800200009084
+:105240000000CF0900000010084001920000361055
+:1052500000000080020000900000C1090000001062
+:1052600008C001920000361000000080020000908B
+:105270000000361000000080020000900000361090
+:10528000000000800200009000006F0B0000001082
+:10529000088000920000361000000080020000909C
+:1052A00000006F0B000000100880009200003D0C11
+:1052B000000000100840019200003610000000803D
+:1052C0000200009000006F0B0000001008800092A8
+:1052D0000000361000000080020000900000361030
+:1052E00000000080020000900000361000000080E6
+:1052F0000200009000006F0B0000001008000192F7
+:1053000000003610000000800200009000006F0BCB
+:10531000000000100800019200003D0C0000001089
+:10532000084001920000361000000080020000904A
+:1053300000006F0B00000010080001920000361002
+:105340000000008002000090000036100000008085
+:105350000200009000003610000000800200009063
+:1053600000006F0B000000100800019200003610D2
+:10537000000000800200009000006F0B0000001091
+:105380000800019200003D0C00000010084001924E
+:1053900000003610000000800200009000006F0B3B
+:1053A000000000100800019200003610000000808C
+:1053B0000200009000003610000000800200009003
+:1053C00000003610000000800200009000006F0B0B
+:1053D00000000010088000920000361000000080DD
+:1053E0000200009000006F0B000000100880009287
+:1053F00000003D0C00000010084001920000361033
+:10540000000000800200009000006F0B0000001000
+:10541000088000920000361000000080020000901A
+:1054200000003610000000800200009000003610DE
+:105430000000008002000090000036100000008094
+:105440000200009000003610000000800200009072
+:1054500000006F0B0000001008C0019200003D0C1E
+:10546000000000100840019200003610000000808B
+:105470000200009000006F0B0000001008C00192B5
+:10548000000036100000008002000090000036107E
+:105490000000008002000090000036100000008034
+:1054A000020000900000D70B00000010088000925E
+:1054B000000036100000008002000090000036104E
+:1054C000000000800200009000008C070000001027
+:1054D0000840019200003610000000800200009099
+:1054E0000000D70B0000001008800092000036106A
+:1054F00000000080020000900000361000000080D4
+:1055000002000090000036100000008002000090B1
+:105510000000D70B00000010088000920000361039
+:1055200000000080020000900000361000000080A3
+:105530000200009000008C0700000010084001925B
+:105540000000361000000080020000900000D70B21
+:105550000000001008C0019200003610000000801A
+:105560000200009000003610000000800200009051
+:10557000000036100000008002000090000036108D
+:105580000000008002000090000036100000008043
+:105590000200009000003610000000800200009021
+:1055A00000008C0700000010084001920000361037
+:1055B00000000080020000900000DF0B00000010DF
+:1055C00008C0019200003610000000800200009028
+:1055D000000036100000008002000090000036102D
+:1055E00000000080020000900000361000000080E3
+:1055F00002000090000036100000008002000090C1
+:1056000000003610000000800200009000008C07AF
+:1056100000000010084001920000361000000080D9
+:10562000020000900000DF0B0000001008800092D4
+:1056300000003610000000800200009000003610CC
+:105640000000008002000090000036100000008082
+:105650000200009000003610000000800200009060
+:10566000000036100000008002000090000036109C
+:1056700000000080020000900000C30C0000001039
+:1056800008400192000036100000008002000090E7
+:10569000000036100000008002000090000036106C
+:1056A000000000800200009000009407000000103D
+:1056B00008400092000036100000008002000090B8
+:1056C000000036100000008002000090000036103C
+:1056D00000000080020000900000361000000080F2
+:1056E00002000090000036100000008002000090D0
+:1056F0000000E6070000001008800092000036104D
+:1057000000000080020000900000361000000080C1
+:105710000200009000009B080000001008000192A9
+:105720000000361000000080020000900000930787
+:1057300000000010080001920000A5080000001001
+:10574000080001920000A508000000100800019266
+:105750000000A508000000100800019200003610AB
+:105760000000008002000090000036100000008061
+:10577000020000900000F507000000100880009271
+:105780000000361000000080020000900000930727
+:105790000000001008000192000036100000008098
+:1057A000020000900000361000000080020000900F
+:1057B00000000308000000100880009200009A0812
+:1057C0000000001008800092000093070000001005
+:1057D00008000192000036100000008002000090D6
+:1057E0000000BB0800000010084000920000BB0849
+:1057F00000000010088000920000BB0800000010AC
+:1058000008C00092000093070000001008000192F9
+:1058100000003610000000800200009000003610EA
+:1058200000000080020000900000E008000000106E
+:1058300008C00092000036100000008002000090B6
+:1058400000009307000000100800019200003610CD
+:105850000000008002000090000036100000008070
+:10586000020000900000E208000000100800019211
+:105870000000E208000000100800019200009307F9
+:1058800000000010080001920000361000000080A7
+:10589000020000900000361000000080020000901E
+:1058A0000000E40800000010088000920000E408F6
+:1058B0000000001008C000920000930700000010D4
+:1058C00008000192000036100000008002000090E5
+:1058D0000000930700000010084000920000B1088B
+:1058E00000000010088000920000B10800000010C5
+:1058F00008C0009200009307000000100800019209
+:1059000000009307000000100800009200009307B9
+:1059100000000010084000920000F808000000108D
+:10592000088000920000F8080000001008C00092F3
+:1059300000009307000000100800019200003610DC
+:10594000000000800200009000003610000000807F
+:105950000200009000002C09000000100880009256
+:10596000000093070000001008C000920000930799
+:1059700000000010080001920000361000000080B6
+:10598000020000900000361000000080020000902D
+:1059900000000C0900000010088000920000361082
+:1059A000000000800200009000009307000000103B
+:1059B00008000192000036100000008002000090F4
+:1059C0000000361000000080020000900000F40784
+:1059D00000000010088000920000361000000080D7
+:1059E00002000090000093070000001008000192E0
+:1059F0000000361000000080020000900000361009
+:105A0000000000800200009000002009000000104B
+:105A100008800092000020090000001008C00092D9
+:105A200000009307000000100800019200003610EB
+:105A3000000000800200009000003610000000808E
+:105A4000020000900000EF080000001008800092A3
+:105A50000000EF080000001008C00092000093074B
+:105A600000000010080001920000361000000080C5
+:105A7000020000900000361000000080020000903C
+:105A80000000390900000010088000920000390968
+:105A90000000001008C000920000930700000010F2
+:105AA0000800019208003103001801E8762081996E
+:105AB00008002F03001801E8762081990000990F53
+:105AC00000000080020000F0080091071D1901E8A5
+:105AD000762081B900003103000000F862812F9523
+:105AE000000031038000008002812FB62A003103BC
+:105AF000D001002C82CD2E9208003103001C01E859
+:105B00007620819900000000000000D802000032D9
+:105B100000000000000E01EC06C06E3554000000CD
+:105B2000000000000700363200000000000000BC4A
+:105B3000A8002D37B44400000008000087CD8B3A40
+:105B4000000000000000007899C02C37B40000006D
+:105B500000000078898D973A00003610021000008E
+:105B600087BF97BA00000000001800000740FE320F
+:105B700000009D0712000040F2C138B40000000090
+:105B80000090007809006E320000361004A000007A
+:105B900009806EB20000A20704A5000409806EB25D
+:105BA0000000000000000004090090320000A4077B
+:105BB00004010004096490BC00000000000000041F
+:105BC00009400032080000006E3402E816249039C3
+:105BD0000000A507B71002E0068097B20000A807F2
+:105BE00080000080F280FCB60000A907000000C819
+:105BF000FF80FC940000AA079F990080821BEEBCE6
+:105C000000000000009800E00E006E32000000006E
+:105C1000A70000800200003018003600000000F8E5
+:105C2000730A03F9000000000010021C09006E3224
+:105C30004000AF070601008082CD91BC00C0B007D4
+:105C4000001802E00680369200E00000001802E032
+:105C50000680363200000000000000200980033278
+:105C60000000B30780D7018032C06EB6000000008C
+:105C7000000000204900923A00000000009801183E
+:105C800009006E3200000000000A022409C06E32D2
+:105C90000000000000C0012809806E320000C1072A
+:105CA000800E018012C06EB602000000003C02ECC3
+:105CB0000600363200000000000000004901923A60
+:105CC0000000BD0780D6018042C06EB60082000091
+:105CD000001002E0A6CD913200A00000002C02E8E6
+:105CE000060036322800CB07003A02EC0600369256
+:105CF00000000000D301001CD9C1913400820000D3
+:105D0000001002E0A6CD913200A00000002C02E8B5
+:105D1000060036323400CB07003A02EC0600369219
+:105D200004000000003C02EC0600363228000000AF
+:105D300000000000890D923A0000C70780D601805C
+:105D400042C06EB600860000001002E0A6CD91327F
+:105D500004A00000002C02E8060036321400CB0735
+:105D6000003A02EC0600369200000000D301001C4D
+:105D7000D9C1913400860000001002E0A6CD913216
+:105D800004A00000002C02E8060036322000CB07F9
+:105D9000003A02EC0600369212000000003802ECD5
+:105DA00086CD913A08000000002802E88624903948
+:105DB00000000000002002E09624143700000000DC
+:105DC000004001E0068091320000D107040100800C
+:105DD000028092BC0000000000C001E0060000321A
+:105DE00000000000003000E006000032000000006B
+:105DF00000B000E0060000322000000000000000BB
+:105E0000070036320000000000000078A9002D379E
+:105E10000045000000080000878D973A0000000050
+:105E20000000007899C02C370001000000000078C5
+:105E3000898D973A000036100210000087BF97BA8C
+:105E400000000000001800000740FE320000DA07E2
+:105E500012000048F2C138B40000DE0780D7012CE0
+:105E600009C06EB200000000DAD701EC06C06E3542
+:105E700000000000005A01EC0640ED320000000076
+:105E8000005C01E806808B320000E10780010080A1
+:105E900062C092B600000000000000F882812F343A
+:105EA00018003600000000F8730A03F90000000033
+:105EB0000004013808C06E3200000000006201ECEE
+:105EC00006808332010093071201002C82CD2EB28E
+:105ED0000000E407000000800200009000000000C5
+:105EE000005401FC02C06E3200000000000000D827
+:105EF0000280013200C0EC071801000CA8CD3EB2B0
+:105F00002080000000000008088036322D002F039A
+:105F10001201002C82CD2EB20000EA0700000080A2
+:105F200002000090000000000062013808C06E32DC
+:105F300000080080000000280900373200604B0F85
+:105F400000000008088036F200009307040601EC08
+:105F500016C06EBC000093078000008072812FB6CF
+:105F600000000000000000F872812F343D0093070C
+:105F70001201002C82CD2EB20000F207000000803A
+:105F8000020000900000F507000000F8B2812F9495
+:105F90000000CF0F00A0001808006EF200002510CE
+:105FA0000078016008006EF20000F907120100C8D5
+:105FB000020020B20000FC070000008002000090F8
+:105FC000000006081201005C088020B20000FC07F7
+:105FD0001201006002802CB20000FA07000000806D
+:105FE000020000900000FE0704000080024080BC18
+:105FF00000000000000000F81F80FF3A00000008C9
+:1060000080010080A2802FB618003600CA0000F878
+:10601000730A03F9000093078000008072812FB695
+:106020003D0001081200002C82CD2EB20000930723
+:10603000000000F872812F940000FC07120000C8D5
+:10604000020020B20000FA071200005C088020B2B3
+:106050000000361004A0001808006EB20000000016
+:106060000000007879613832000007081218024CED
+:10607000E2256EB2080000000010020078E16E39DF
+:106080000000000000180020070000320700000098
+:106090000000003878CAE939000036100400003CDE
+:1060A000084080B2000036100490006C08006EB208
+:1060B000000000000098004C08006E320000000054
+:1060C000510000D802000032000000004D00000026
+:1060D00067E0833E000000000008000007008032F7
+:1060E000000000000010000007C086320000000021
+:1060F0000018000007C084320000000000000018F3
+:10610000D8A0813C0000680804B000E0D6206EBC36
+:10611000000038080400003CD8E083BC00001E08E2
+:106120008000008092802FB6000019081201000044
+:1061300009C021B218003600000000F8730A03F904
+:106140001D0000000000007809A4173800001D0899
+:1061500004010080128097BC00001808670000F856
+:10616000A2802FB5000019080000000009C021928C
+:1061700000000000C90100D802408432000021085C
+:106180000400008072802DBC00001F081200004433
+:10619000E2E038B200002C08510000D812802D9A9D
+:1061A0000000000000000078F9818334000022081C
+:1061B00012000044E2E538B20000260880000080AA
+:1061C00082802FB60000550F00A0015008006EF22B
+:1061D0000000000000F801E00600853200002808F9
+:1061E000120100E802C021B218003600000000F8D9
+:1061F000730A03F900002B080401008002802DBC03
+:1062000000002708670000F8A2802FB500003610B4
+:10621000120000E802C021B200000000510000D8C6
+:1062200002000032000030082A010000D82080BAA5
+:10623000000030081201000009C021B21800360029
+:10624000000000F8730A03F900000000000000D805
+:106250000240843200000000CAE0006C08006E3288
+:106260000000000000E8004C08006E32000036100C
+:1062700004F0001808006EB20000000000000038B2
+:106280001881833500000F0804B00080829B81BC18
+:1062900000000000CA0100F842802F3508A00F0856
+:1062A00012010040A2CD39B2000036080000008083
+:1062B0000200009000004008293402B808806EB245
+:1062C00000003B081201000009C021B2180036008E
+:1062D000000000F8730A03F91D00000000000078B8
+:1062E00009A4173800003F0804010080128097BC01
+:1062F00000003A08670000F8A2802FB500003B08B4
+:106300000000000009C0219200000000C90100D86F
+:10631000024084320000000000000078F9818334DC
+:106320000000410812000044E2E538B200004708CE
+:106330002800006CD8E086BA0000540F00A001507D
+:1063400008006EF2000047081DF801E0060085B263
+:10635000000047088000008002812FB62A0000005C
+:10636000D001002C82CD2E3200004A0804A000E0AB
+:10637000068081B200003610049000E006C086B2AC
+:1063800000005808009800E006C0849200004F0802
+:1063900080010080A2802FB600004D08120100008D
+:1063A00009C021B218003600000000F8730A03F992
+:1063B0001D004F080401008002A417B800004C081B
+:1063C000000000F8E2802F940000361004E0006C1A
+:1063D00008006EB200000000CAE8004C08006E32EF
+:1063E0000000361004F0001808006EB200005508D6
+:1063F00004B00080829B81BC00000000CA0100F84C
+:1064000042802F3508A0540812000040A2CD39B2B6
+:106410000000000000A000E00680813200000000C3
+:10642000009800E006C0843200003610049000E0BE
+:1064300006C086B200005D082A5D01E806808BB2C6
+:1064400000005B081201000009C021B218003600EC
+:10645000000000F8730A03F91D005D0804010080C4
+:1064600002A417B800005A08000000F8E2802F9438
+:1064700010246008370000F8A28D2FB13D005E089F
+:106480001200002C82CD2EB200000000000000F8A7
+:1064900072812F3408000000CA1C01E8762081397F
+:1064A0000000FA0D0000002CF90100F4000065085E
+:1064B00080000080E2802FB6000065081201000015
+:1064C00009C021B218003600000000F8730A03F971
+:1064D000100000000018008067A1733930003203FB
+:1064E0001201005CA28D2CB200003610000000806A
+:1064F0000200009000006B088000008092802FB6A0
+:1065000018003600000000F8730A03F900000000CC
+:10651000C90100D802408432000036102A000078F9
+:10652000F98183B400006C0812000044E2E538B23F
+:106530000000DC0E00000030030038F2000071089B
+:106540001D000038188183B50000710880000080AC
+:1065500002812FB62A000000D001002C82CD2E32FD
+:1065600000007408040601EC16C06EBC00000000B8
+:10657000CA0100F842802F3408C07308120000409E
+:10658000A2CD39B2000077088000008082802FB64B
+:106590000000550F00A0015008006EF2000000003E
+:1065A00000F801E0060085320000790812010000C1
+:1065B00009C021B218003600000000F8730A03F980
+:1065C000000095082A3502B808806EB200007C08E9
+:1065D0001201000009C021B218003600000000F8C6
+:1065E000730A03F900000000000000F8A2802F35B4
+:1065F00000008E0804000080026180BC0000870853
+:1066000080B8000009C06EB240008208040000801B
+:10661000820D90BC0000820802B00080821B84BC06
+:1066200000008708000000F8B2812F9400000000ED
+:1066300000D601EC56C06E3400000000000000607F
+:106640001800863A0000000000000080B70178348E
+:1066500000000000007801E0060086324000950846
+:1066600004000080820D90BC0000361004A00018C9
+:1066700008006EB20000CF0F00000000D82080FAA2
+:10668000000036100600003C182084BC00003610C4
+:1066900004B0003C88DB83BE0000000000000080E6
+:1066A000F720783A00000000587801E0F620863A9A
+:1066B00000000C0800000004F860809A00009108B7
+:1066C00080B9000009C06EB22F0095081201002C9D
+:1066D00082CD2EB200008F080000008002000090E2
+:1066E0004000930804010080820D90BC380094089B
+:1066F00000000078090036923900000000000078A0
+:1067000009003632000094081200002CE2E52EB297
+:10671000100000000018008067A17339000000001D
+:10672000005C01E806808B3210240000000000F8B5
+:10673000A28D2F31300093071201005CA28D2CB284
+:1067400000003610000000800200009000000308E6
+:10675000000000F8C2812F9500000000005401FCE9
+:1067600002C06E3200000000000000D8028001323A
+:1067700000C0A1081801000CA8CD3EB22080000086
+:1067800000000008088036322D002F031201002C73
+:1067900082CD2EB200009F08000000800200009011
+:1067A000000000000062013808C06E32000800805E
+:1067B000000000280900373200604B0F000000087D
+:1067C000088036F20000AF08000000800200009050
+:1067D0000000A70880000080C2812FB60000AA0830
+:1067E00000D001E80600009200000000000000F860
+:1067F000C2812F350000AA0804D1018002806EBC3E
+:106800000000000000D601EC26C06E340000AC0889
+:106810008000008092812FB60000AF0800C801E818
+:106820000600009200000000000000F892812F3561
+:106830000000AF0804C9018002806EBC00000000A7
+:1068400000D601EC16C06E34110093071201002C23
+:1068500082CD2EB20000AF08000000800200009040
+:10686000000093079A0100F842812FB50000B80894
+:10687000120100C8020020B200000000005C01EC20
+:106880000640003200009307370000F842812FB421
+:1068900000000000000000F872812F343D009307D3
+:1068A0001201002C82CD2EB20000B608000000803C
+:1068B000020000900000C3081201005C088020B2B2
+:1068C0000000B3081201006002802CB200003610F4
+:1068D00000000080020000900000C008120100C803
+:1068E000020020B200009307370000F8D2812FB4D5
+:1068F00000000000000000F872812F343D00930773
+:106900001201002C82CD2EB20000BE0800000080D3
+:10691000020000900000C3081201005C088020B251
+:106920000000BC081201006002802CB2000036108A
+:1069300000000080020000900000000000000078CD
+:10694000796138320000C4081218024CE2256EB298
+:1069500000000000003402B808806E320000000021
+:1069600000A0015008006E320000000000780160B5
+:1069700008006E320000CA089D11023409006EB290
+:106980000000000000F0018808006E3200006C0F6B
+:1069900000A8010809006EF200000000D4F801E030
+:1069A0000600853200000000DA5C01E806808B32C8
+:1069B0000000DC0EDD000030030038F20000D008DB
+:1069C0002329020409806EB23E00CF081200002C79
+:1069D00082CD2EB20800D3081D1C01E8762081B9B3
+:1069E0000000D3088000008002812FB62A0000003A
+:1069F000D001002C82CD2E320000FA0D0000002CB8
+:106A0000F90100F40000D7089D010080074093B20F
+:106A10000000000000300080078088320000000085
+:106A2000003800800700EE320000000000080080FF
+:106A300007C085320000000000100080074090323F
+:106A40001000000000180080878D853700000000CE
+:106A5000002000800700863200000000002800802F
+:106A6000070085320000DE081201000009C021B2D3
+:106A700018003600000000F8730A03F930003203F2
+:106A80001201005CA28D2CB20000361000000080C4
+:106A9000020000900000000000CC017809806E32F6
+:106AA00000009307DCD101E806809792130093075A
+:106AB0001201002C82CD2EB20000E20800000080FE
+:106AC000020000900000BA0D00000018094081F299
+:106AD0000000A30D00A8012009006EF2000093073A
+:106AE00080010080F2802FB60000EC08120100C87F
+:106AF000020020B2000093078000008072812FB650
+:106B000000000000000000F872812F343D00930760
+:106B10001201002C82CD2EB20000EA080000008095
+:106B2000020000900000C3081201005C088020B23F
+:106B30000000E8081201006002802CB2000036104C
+:106B4000000000800200009000009307350100F86B
+:106B500012812FB500000000000000D80280013231
+:106B600000000000005401FC02C06E3200C0F608B4
+:106B70001801000CA8CD3EB220800000D101000811
+:106B8000088036323B0031031201002C82CD2EB238
+:106B90000000F40800000080020000900000440F94
+:106BA0000098012809006EF20000930700000080A1
+:106BB000020000900000FE0880010080A2812FB634
+:106BC0000000FE088000008042812FB60000FE0811
+:106BD000085B01EC06FB6EBC00000000005A01ECF3
+:106BE000060000320000FE08370000F842812FB492
+:106BF0003D000000D701002C82CD2E320000040998
+:106C00008001008092812FB600000A0908C901E8BE
+:106C100006BB6EBC0000000000C801E806000032A0
+:106C2000330001091200002C82CD2EB20000510F5A
+:106C300000000028098001F2000093070000008096
+:106C40000200009000000A0980010080C2812FB676
+:106C500000000A0908D101E806BB6EBC0000000074
+:106C600000D001E806000032330007091200002CB2
+:106C700082CD2EB20000510F0000002809C001F2A1
+:106C800000009307000000800200009000009307BE
+:106C900080010080F2812FB6180093070000002CBD
+:106CA00082CD2E9200000F09120000C8020020B20F
+:106CB000000012091201005C088020B200003610AA
+:106CC0001200006002802CB200000000000000F8FA
+:106CD0001F80FF3A000031031201002C72E02EB237
+:106CE0000000100900000080020000900000000079
+:106CF0000000007879613832000013091218024C44
+:106D0000E2256EB200000000003402B808806E3246
+:106D100000000000D4A0015008006E320000000006
+:106D2000DB79016008006E320000550FDD000004C1
+:106D3000080000F21000000000180080878D8537E1
+:106D40000000000000F801E00600853200001C0988
+:106D50001201000009C021B218003600000000F83E
+:106D6000730A03F9300036101200005CA28D2CB2B9
+:106D700000003610040701EC16C06EBC00000000D5
+:106D800000B000E00600003200009307DA5C01E882
+:106D900006808B92000093079F41018052206EBCB9
+:106DA00000002B099F98018052206EBC000000005B
+:106DB000000000D80280013200000000005401FCF5
+:106DC00002C06E3200C029091801000CA8CD3EB2E5
+:106DD0002080930731000008088036B200000000D0
+:106DE000000000F812812F343B0093071201002CA1
+:106DF00082CD2EB200002709000000800200009022
+:106E00000000440F0098012809006EF2000093076B
+:106E1000000000800200009000009307D54101E0CF
+:106E2000064081920000930704B0008002006EBC0F
+:106E3000000000000090010008006E3200002510E4
+:106E40000078016008006EF20000930700000080E7
+:106E50000200009000000000000C027809806E32F1
+:106E60000000330904D4018012C06EBC0000000091
+:106E7000000000781980973700000000009001E0C2
+:106E8000E6256E3A0000251000000080020000F0A8
+:106E90000000370900000080020000900000930706
+:106EA000009001E00600809200000000009001E0E8
+:106EB00006008032000003080000008002000090FD
+:106EC0000000A30D00A8012009006EF20000E708F1
+:106ED00080000080F2802FB6000093070000008041
+:106EE0000200009000000000000000D80280013283
+:106EF000000000000000007809006E320200410925
+:106F000004B9008082CD6EBC00004309800000807F
+:106F10007280FCB600004509000000FC02000092EF
+:106F200000004309800000808280FCB60000450913
+:106F3000000000FC0200009200000000000000A819
+:106F400042BD973000000000541889FCF2C07C302C
+:106F500000C04B091801000CA8CD3EB20000000093
+:106F6000000E01EC0600003400000000005401ECAB
+:106F700006C02F3220800000000000080880363252
+:106F8000000031031201002C82CD2EB2000049090D
+:106F90000000008002000090000000000062013844
+:106FA00008C06E3200080080000000280900373257
+:106FB00000004B0F00000008E80100F4000036104C
+:106FC000040701EC16C06EBC00000000000000A821
+:106FD000A2002D370A0000000000007809003632B8
+:106FE00000000000001889E007000032000051098D
+:106FF00004010078198097BC02005C0904B9008084
+:1070000082CD6EBC00000048D6010078C9CD2C327C
+:1070100000005509B6000080020000B000005609CB
+:1070200012000064028097B2000057091208006441
+:1070300002006EB2000058091218006402006EB21D
+:10704000000059091210006402006EB20000000036
+:10705000A65401EC06C02F3200008C07000E01EC94
+:10706000060000940020004CD6010078C9CD2C32D7
+:1070700000005D09B6000080020000B000005E095B
+:1070800012000064028097B200005F0912080064D9
+:1070900002006EB2000060091230006402006EB29D
+:1070A000000061091238006402006EB2000062093B
+:1070B0001240006402006EB20000630912480064CE
+:1070C00002006EB2000064091210006402006EB289
+:1070D000000065091218006402006EB20000660923
+:1070E0001220006402006EB20000670912280064DA
+:1070F00002006EB200000000A65401EC06C02F3260
+:1071000003008C07000E01EC060036920000000020
+:10711000000000FC0200013200006D0900000014B4
+:1071200008803D9200000000000000FC02000132D7
+:1071300000007009040000DC53603DB3180000003B
+:10714000000000F8738A03396C093600000000C0A3
+:107150000200369200000000005401FC02C06E32B2
+:1071600000000000000000D80280013200C0760953
+:107170001801000CA8CD3EB22080000000000008DD
+:107180000880363215002F031201002C82CD2EB25A
+:107190000000740900000080020000900000000060
+:1071A000002800000700003200000000003000004E
+:1071B00007C02C3200100082003800000700373270
+:1071C000000079091200004802C080B200008C075C
+:1071D000CA010008E80100942D007B091200002C70
+:1071E00082CD2EB200007E091D010080020000B099
+:1071F00000008C07000000F862812F95000000005D
+:10720000000000F802812F342A008C071201002CA4
+:1072100082CD2EB200007F090000008002000090A5
+:1072200000003F0F0000002C09C085D20000DC0EDA
+:1072300000000030030038F200003103230100F8A1
+:1072400022812FB43E0031031201002C82CD2EB2D8
+:1072500000008409000000800200009000003F0F41
+:107260000000002C09C085D200003103000000F8A6
+:1072700022812F9400008D09380100D8028001B2CC
+:1072800000008B091E000080020000B000008D0984
+:107290001A010080020000B000008C0F000000689E
+:1072A0001F80F6FA00003103000000800200009009
+:1072B0000000910912010060084023B20082000022
+:1072C000000000080880363200008C0F00000064C7
+:1072D0001F40F6FA00003103000000800200009019
+:1072E0000000361012000024080023B200003610FF
+:1072F0001200002008C023B200003610120000184F
+:10730000088023B200C09C091801000CA8CD3EB231
+:107310000000940912000038028081B2000036108B
+:107320001200003C020082B2000036101200003051
+:10733000024082B20000361012000034020086B211
+:1073400020800000000000080880363200008C0F0A
+:107350000000005C1FC0F5FA00003103000000804F
+:107360000200009000000000450000D8020000323A
+:107370000000000000000000074080320000000014
+:1073800000100000074082320000000000180000DA
+:10739000070086320000A00912000050F2C138B484
+:1073A0000000640D003001E016206EFA0000A5090F
+:1073B0003801002CF8010BB40000A509020D028071
+:1073C000A25B80BC000000000000002CC8C1823419
+:1073D0000000A7098000008042812FB60000940DB4
+:1073E00000000080020000F00000AD0D00A801E0E8
+:1073F00016206EFC0000AC09270100D8028001B203
+:1074000000000000C700002CE8C08234000000002B
+:1074100000000008D801003400000000D54001E061
+:10742000060087320800990F001801E8762081F9DC
+:107430000000DC0E00000030030038F20000B0094C
+:1074400023190000078081B23E00AF091200002C12
+:1074500082CD2EB20000B2091D210000070082B2C9
+:107460000000B409000000F862812F950000B40903
+:107470008000008002812FB62A000000D001002C7D
+:1074800082CD2E320000FA0D0000002CF90100F42C
+:107490001000B8092C30000017E02CB90000BA0920
+:1074A0008E39000007C082B20000BA09000800004F
+:1074B000070087920000BA098E390000B7C182B474
+:1074C0000000000000080000070087320000BC092F
+:1074D000120100E802C021B218003600000000F8D6
+:1074E000730A03F90000BA099F010014184081BC17
+:1074F0000000BF090400008002C085BC00003610F7
+:107500001200006802C585B00000BF0912000048E3
+:1075100002C080B200003203CA010008E8818094F2
+:107520000000C3091E000080020000B00000C50971
+:107530001A010080020000B000008C0F00000068FB
+:107540001F80F6FA00003103000000800200009066
+:10755000000036109FA801E016206EBC0000640DEC
+:1075600000000014080000F20000C909800000803B
+:1075700042812FB60000940D00000080020000F050
+:107580000000AD0D00000080020000F000008E073A
+:1075900004000080024081BC0000CD09120100E817
+:1075A00002C021B218003600000000F8730A03F987
+:1075B00000008E071201006802C585B00000361079
+:1075C000000000800200009000008C078000008016
+:1075D000F2C185B60000D3091C41028006C085B205
+:1075E000000000000000006802C5853000000000B7
+:1075F000000000701F00F73A00008C07000000F840
+:1076000022812F9400008C0780000080F2C185B693
+:1076100000003F0F0000002C09C085D2000031039C
+:10762000D20100941E40E99A0000C40F0020001807
+:1076300008006EF20000DB091F000080020000B0AD
+:107640000000D8099E400278094068B20000361058
+:1076500000000080020000900000DF09800100802F
+:1076600082812FB600008E072A3101E0060000B2A9
+:1076700018000000CA0000F8730A03398E073600AC
+:10768000000000C00200369200008E0780010080DA
+:10769000A2802FB618000000CA0000F8730A033950
+:1076A0008E073600000000C0020036920D00E5098A
+:1076B00000000058080036920000E509000000585C
+:1076C000080000921B00000000000058080036323D
+:1076D0000000C40F0020001808006EF20000000037
+:1076E0000030002808006E3200000000545401FCF5
+:1076F00002C06E320000300A380000A4088082B256
+:107700000000300A0428010408006EB200003610A0
+:107710009F500104A85B80BC00000000005001E8FD
+:10772000060000320000110A0801007819A082BC8E
+:1077300000000000002801E0A660803C0000F00985
+:107740002A010014080000B200000000CA00001462
+:107750001840813A0000A30D00A80120A9206EFA6C
+:1077600000000000002001E0A6206E3C00000000A8
+:10777000003000E0060000320000000000A801E038
+:107780000600923200000000000000D802800132A2
+:1077900000C0030A1801000CA8CD3EB20000FA098F
+:1077A00004000080024081BC0000000000000014C2
+:1077B0000800003218000000000000F8730A0339C6
+:1077C000F4093600000000C002003692208000005C
+:1077D00000000028098036320000F10E000000D8B9
+:1077E000020000D20000FE0904000080028092BC6A
+:1077F00018003600000000F8730A03F900000000CA
+:10780000000000D80280013200C0030A1801000CF9
+:10781000A8CD3EB218000000000000F8738A0339BA
+:10782000FE090000000000C00200363200003600F1
+:10783000000000800200009000000000DE00000850
+:10784000E801003400000000DF00013808C06E329B
+:1078500000000000001000000700003200000000DF
+:107860000018000007808232000000000030000095
+:1078700007C02C320020008000380000070037329B
+:1078800000000000CA3D000C0780833200000000A9
+:10789000000000141840813A00000F0A040201ECB5
+:1078A00016C06EBC00000000C00100141840813AF0
+:1078B00000000000000000F892802F3400C00E0A83
+:1078C00012000040A28D39B20000690A120100487E
+:1078D00002C080B200000F0A000000800200009089
+:1078E000000000000000002808809732000000001F
+:1078F000000000A408808232000000000010006C2C
+:1079000018206E3A000000000018004C08006E328B
+:107910000000A30D00A8012019206EFA000000004D
+:10792000002001E016206E3C0000000000A801E0ED
+:107930000600923200001B0A003801E006408092E7
+:10794000000000000060006C18206E3A000000008B
+:107950000068004C08006E3200001D0A9F01000400
+:10796000686080BC0000240A000000181820009CF9
+:1079700000001F0A120100E802C021B21800360000
+:10798000000000F8730A03F900000000CA70001834
+:1079900008006E320000190A02010080626080BC9B
+:1079A00000000000CA0100F802802F3500A01B0A69
+:1079B00012010040A28D39B20000220A00000080AE
+:1079C000020000900000280A80000080A2802FB6EC
+:1079D00000002B0A04000080A2A081BC000000006F
+:1079E000CA0100F802802F3500A0270A12000040CB
+:1079F000A28D39B200000000000000F8A2802F35EF
+:107A000000002B0A120100E802C021B21800360063
+:107A1000000000F8730A03F900000000002801E0EC
+:107A20000600003200000000003000E006808232D4
+:107A300000000000002000E00680813200003610C7
+:107A4000041000E006C086B20000320A001800E010
+:107A500006C08492000036100410006C08006EB25C
+:107A6000000000000018004C08006E320000E00D1D
+:107A7000510000D8020000F20000350A0050013C1D
+:107A8000A85B809C00008E07003001E00600009299
+:107A900000003A0A3E510100A81B80BA0000000015
+:107AA000DE0000F8F2812F3400000000005801ECE5
+:107AB00006C0EE3200003A0A80010080328087B6AC
+:107AC00000000000000000F8E2802F340000730E78
+:107AD000603001E0060000F200008E070000008028
+:107AE00002000090000000000000001408000032B6
+:107AF0000000430A040201EC16C06EBC0000000046
+:107B0000C90100141840813A00000000C00101388A
+:107B100008C06E3200000000DF0000A4A8608A3CAC
+:107B200000C0460A12010040A28D39B20000410A8D
+:107B3000000000800200009000000000003000E023
+:107B40000600003200000000DF0000A4A8608A3CAC
+:107B5000000000000000013808C06E320000000084
+:107B6000DEA8012099226E3A0000490A2F2001E088
+:107B700096226EBC0000A30D00000080020000F001
+:107B800000004D0A1F5001E8060000B200004C0A38
+:107B90000400008002C083BC00004D0A005001E8D0
+:107BA000F660809C0800000000400268129AFE38CF
+:107BB0000000510A2AA901E0060092B2180036001E
+:107BC000CA0000F8730A03F91D00510A040000807E
+:107BD00002A417B800004E0A000000141840819C4F
+:107BE0000000DC0E00000030030038F20000540AF0
+:107BF0008001008032802FB63E00530A1200002C14
+:107C000082CD2EB200000000000000D802800132B8
+:107C100000C0650A1801000CA8CD3EB2208000000B
+:107C2000C3000028098036320000F10E000000D8A1
+:107C3000020000D200005A0A04000080028092BCB8
+:107C400000000000000000141840813A00005F0AA4
+:107C500004000080024081BC18003600000000F8DB
+:107C6000730A03F90000630A04000014184081BC81
+:107C700000005B0A1200000009C021B200005C0A8B
+:107C8000000000800200009018003600000000F89C
+:107C9000738A03F90000DC0E00000030030038F2A4
+:107CA0000000630A8001008032802FB63E00620A25
+:107CB0001200002C82CD2EB200000000C30000D8BC
+:107CC0000280013200C05F0A1800000CA8CD3EB24D
+:107CD0000020008000000028090037320000B10FAA
+:107CE00000000008E80100F40000670A12000048E4
+:107CF00002C080B200000000000000141840813A69
+:107D000018003600CA0000F8730A03F90000690A77
+:107D100004010014184081BC0000990F000000808D
+:107D2000020000F000006F0A8001008092802FB6F0
+:107D30002B00720A1201002C82CD2EB200006D0AB7
+:107D400000000080020000900000720A1D00008008
+:107D5000020000B00000720A8000008002812FB68D
+:107D60002A000000D001002C82CD2E3200008C07AA
+:107D700004000080028085BC0000AA0F0000008083
+:107D8000020000F000007D050000001C08808592C4
+:107D900000000000CE0100D80280013200C07A0A43
+:107DA0001801000CA8CD3EB22080000000000008A1
+:107DB0000880363200008C0F0000005C1FC0F5FA0E
+:107DC000000031030000008002000090000000006D
+:107DD000600000D80200003200007F0A3F00003C33
+:107DE000084080B200007F0A80010080E2812FB647
+:107DF00000000000DE0000F8F2812F3400000000D7
+:107E0000005801EC06C0EE32000000004D000000FA
+:107E100067E0833E00000000000800000700803299
+:107E2000000000000010000007C0863200000000C3
+:107E30000018000007C084320000BE0A04000028B9
+:107E4000D8A082BC0000000000000018D8A0813C2F
+:107E500000009C0A0400003CD8E083BC0000890AB2
+:107E60000400008072802DBC0000870A12000050C0
+:107E700002C038B200009A0A510000D812802D9A30
+:107E80000000890A12000050F2C138B40000950ABF
+:107E9000280000D8020000B20000920A8001008091
+:107EA000F2C185B600008F0A1F400284E60100B4CB
+:107EB0000000920A1D0100F822812FB40000920AEE
+:107EC000000000F862812F950000910A1D010080DA
+:107ED000020000B000000000000000F862812F35B1
+:107EE0000000000000400280024068320000940A56
+:107EF000343000E016206EBC0000940D00000080BD
+:107F0000020000F00000AE0DDA5B01EC0640EDF27D
+:107F100018003600000000F8730A03F90000990AFF
+:107F20000400008072802DBC0000950A670000F8F4
+:107F3000A2802FB500003610120000E802C021B266
+:107F400000000000510000D8020000320000E80DDF
+:107F500000000000D82080FA0000800A4D000000D8
+:107F600067E0839E00009C0A12000050F2C138B402
+:107F70000000A80A28000080084000B20000A50AFE
+:107F800080010080F2C185B60000A20A1F40028471
+:107F9000E60100B40000A50A1D0100F822812FB4FB
+:107FA0000000A50A000000F862812F950000A40AD5
+:107FB0001D010080020000B000000000000000F879
+:107FC00062812F35000000000040028002406832CC
+:107FD0000000A70A343000E016206EBC0000940DAB
+:107FE00000000080020000F00000AE0DDA5B01EC42
+:107FF0000640EDF20000BF0A80000080E2802FB64C
+:108000000000AC0A042100E0068081B20000E80D07
+:1080100000000034080000F200000000002000E032
+:10802000068081320000B10A2A1100E0D6E086BA4B
+:1080300018003600CA0000F8730A03F91D00B10ADF
+:108040000401008002A417B80000AD0A9F0100805F
+:10805000180088BC0000361000000080020000906C
+:108060000000990F00000080020000F00000DC0E0C
+:1080700000000030030038F20800B50A231901E8B7
+:10808000762081B93E00B40A1200002C82CD2EB2B7
+:108090000000B80A1D1800E006C084B20000B80A4B
+:1080A0008000008002812FB62A000000D001002C41
+:1080B00082CD2E320000FA0D0000002CF90100F4F0
+:1080C0000000BC0A04000080020088BC0000BC0A5A
+:1080D0001201000009C021B218003600000000F8AB
+:1080E000730A03F9000032031201006802C585B06B
+:1080F0000000361000000080020000900000BE0A60
+:1081000012000050F2C138B400000000C001013874
+:1081100008C06E320000C30A040201EC16C06EBC37
+:1081200000C0C10A12000040A28D39B20000C40A8A
+:10813000C90100140800009200000000453000E072
+:10814000060000320000CF0A28000008E80100B451
+:108150000000CC0A80010080F2C185B60000C90A87
+:108160001F400284E60100B40000CC0A1D0100F8A3
+:1081700022812FB40000CC0A000000F862812F9504
+:108180000000CB0A1D010080020000B000000000CA
+:10819000000000F862812F350000000000400280DE
+:1081A000024068320000CE0A8000008042812FB673
+:1081B0000000940D00000080020000F00000AE0DF1
+:1081C000DA5B01EC0640EDF200200080DF000028C1
+:1081D000090037320000B10FDE0000D8028001F242
+:1081E0000800990F001801E8762081F90000DC0EE4
+:1081F00000000030030038F20000D50A8001008042
+:1082000032802FB63E00D40A1200002C82CD2EB24E
+:108210000000D90A290801E406C02DB20000DE0AD8
+:108220001D000080020000B00000DE0A8000008017
+:1082300002812FB62A00DE0AD001002C82CD2E92B8
+:108240000000DB0A1201000009C021B2180036004C
+:10825000000000F8730A03F91D00DD0A0401008024
+:1082600002A417B80000DA0A000000141840819C2C
+:108270002B00DD0A1200002C82CD2EB20000FB0D77
+:108280000000002CF90100F40000E10A0401008064
+:10829000024081BC18003600000000F8730A03F9A0
+:1082A0000000E10A1200004802C080B20000320360
+:1082B0001201006802C585B00000E20A00000080DB
+:1082C0000200009000000000000000D8028001328F
+:1082D00000C0E90A1801000CA8CD3EB220800000C1
+:1082E000000000080880363200008C0F0000005C9F
+:1082F0001FC0F5FA0000310300000080020000906A
+:1083000000C00000000000F8A28D2F310000000026
+:10831000000000D802000032000000000000000051
+:108320000780813200000000000800000700803252
+:10833000000000000010000007C0863200000000AE
+:108340000018000007C084320000EF0A120000503D
+:10835000F2C138B40000F50A8000008082802FB698
+:108360000000000000000068A860803C00000000E1
+:108370000000003C084080320000AD0D0000000409
+:10838000088082F20000F60A1201000009C021B242
+:1083900018003600000000F8730A03F91D00F80AFF
+:1083A0000400008002A417B80000F50A000000F8DD
+:1083B000A2802F9500000000000000006820803A95
+:1083C0000000FC0A0400002868A082BC0000E80D40
+:1083D00000000080020000F00000EB0A000000D85E
+:1083E0000200009200000000000000D8028001326C
+:1083F0000020008000000028090037320000AD0F87
+:1084000000000008E80100F418003600CA0000F877
+:10841000730A03F90000060B040201EC16C06EBCDF
+:1084200000000000C00100F892802F3400C0040B4F
+:1084300012010040A28D39B20000020B0000008042
+:10844000020000902B00060B1201002C82CD2EB2F0
+:108450000000040B000000800200009000000000FB
+:10846000000000D8028001320000090B12010060F8
+:10847000084023B20082120B00000008A88D8092F1
+:108480000000361012000024080023B2000036104D
+:108490001200002008C023B200003610120000189D
+:1084A000088023B200C0210B1801000CA8CD3EB2F9
+:1084B00000000C0B12000038028081B20000361060
+:1084C0001200003C020082B20000361012000030A0
+:1084D000024082B20000361012000034020086B260
+:1084E0002080000000000008A88D80320000190BD9
+:1084F00080010080F2C185B60000160B1F40028487
+:10850000E60100B40000190B1D0100F822812FB410
+:108510000000190B000000F862812F950000180B75
+:108520001D010080020000B000000000000000F803
+:1085300062812F3500000000004002800240683256
+:10854000000036101200006802C585B000001C0B48
+:108550003400005C1FC0F5BA0000940D00000080DC
+:10856000020000F000001E0B8000008092802FB6F9
+:1085700000008E07003000E00600009200008E0729
+:10858000120100E802C021B218000000000000F84B
+:10859000730A03398E073600000000C002003692CD
+:1085A00000000000450000D802400032000000003A
+:1085B0004100000007808632000000000008000033
+:1085C00007008032000000000010000007408232E7
+:1085D0000000000000180000070086320000260B93
+:1085E00012000050F2C138B4000000000000007812
+:1085F000388087350000000000A001E016206E3AA8
+:10860000000000000000007809C58530000000006F
+:1086100000A801E016206E3C08000000D20100789E
+:10862000E9E58339180036101F410284E6A197B9A5
+:108630000000300B365101E816E083BC0000300B1F
+:108640001D010080020000B000000000000000F8E2
+:1086500062812F350000320B382101E0064080B2E4
+:1086600000000000003001E0064080320000000001
+:10867000000000D8028001320000350B34180000E1
+:10868000078081B20000940D00000080020000F01D
+:108690001000990F0030000017E02CF90010008046
+:1086A00000380000070037320000DC0E0000003008
+:1086B000030038F200003A0B8001008032802FB6B0
+:1086C0003E00390B1200002C82CD2EB200003F0B71
+:1086D00029210000070082B200003D0B12010000BA
+:1086E00009C021B218003600000000F8730A03F92F
+:1086F0001D00420B0401008002A417B800003B0BD0
+:1087000000000014080000920000420B1D3000E041
+:10871000060000B20000420B8000008002812FB6EC
+:108720002A000000D001002C82CD2E320000AA0FBA
+:108730000000002CF90100F40000FA0D000000F820
+:10874000A2802FF40000470B04000080024081BC8F
+:108750000000470B120100E802C021B218003600E9
+:10876000000000F8730A03F9000032031201004808
+:1087700002C080B20000470B0000008002000090A1
+:108780000000500B80010080F2C185B600004D0B47
+:108790001F400284E60100B40000500B1D0100F8E8
+:1087A00022812FB40000500B000000F862812F9549
+:1087B00000004F0B1D010080020000B0000000000F
+:1087C000000000F862812F350000000000400280A8
+:1087D000024068320000520B04000080024086BC58
+:1087E0000000D70F0090010809006EF2000007108A
+:1087F00000000080020000F00000590B330100D897
+:10880000028001B20000590B80010080B20172B6F3
+:108810000000590B9FF0018082DB87BC0000590BE0
+:108820009FF8018022216EBC0000000000E801E0FA
+:108830000600EE320000000000F001E006C08732C2
+:1088400008000000001801E87620813900005F0B65
+:1088500080010080D2802FB600005F0B04B0008042
+:1088600002006EBC00000000CD0000F872812F34C1
+:108870003D005F0B1201002C82CD2EB200005D0B7B
+:1088800000000080020000900000690B270901E44D
+:1088900006C02DB200C0630B1801000CA8CD3EB27B
+:1088A000000036101200006802C585B020808E07D7
+:1088B000000000080880369200000000004001E03F
+:1088C0000640883200000000D508000007408832CA
+:1088D000000000000030000007C02C320040008083
+:1088E000CA390000070037320000670B1200004849
+:1088F00002C080B20060000000000008088036322C
+:1089000000006C0B1D000080020000B000006C0B2A
+:108910008000008002812FB62A000000D001002CC8
+:1089200082CD2E320000FB0D0000002CF90100F476
+:10893000000032031201006802C585B00000361045
+:10894000000000800200009000000000545401FC70
+:1089500002C06E3200000000000000D80280013228
+:1089600000C0750B1801000CA8CD3EB2208000009D
+:108970000000000808803632000031031201002C8C
+:1089800072E02EB20000730B000000800200009025
+:108990000000C40F0020001808006EF2000036101E
+:1089A0001F30002808006EB200000000000000A484
+:1089B00008808232000036100410006C08006EB28D
+:1089C0000000E00D0018004C08006EF200007C0B67
+:1089D0000050013CA85B809C000036100000008025
+:1089E000020000900000000000500100A81B803A27
+:1089F00000000000510000D802000032000000001A
+:108A00004D00000067E0833E000000000008000009
+:108A100007008032000000000010000007C086320E
+:108A2000000000000018000007C084320000A60B00
+:108A300004000028D8A082BC00000000000000183C
+:108A4000D8A0813C0000940B0400003CD8E083BC1B
+:108A50000000880B0400008072802DBC0000860B93
+:108A60001200005002C038B200008E0B510000D836
+:108A700012802D9A0000880B12000050F2C138B409
+:108A800018003600000000F8730A03F900008D0B8F
+:108A90000400008072802DBC0000890B670000F884
+:108AA000A2802FB500003610120000E802C021B2EB
+:108AB00000000000510000D8020000320000920BBC
+:108AC0002A010000D82080BA0000920B1201000099
+:108AD00009C021B218003600000000F8730A03F93B
+:108AE00000000000000000D8024084320000F00DB9
+:108AF0000060006C08006EF200007F0B4D0000006B
+:108B000067E0839E0000940B12000050F2C138B45D
+:108B100018003600000000F8730A03F91D00990BD5
+:108B20000400008002A417B80000950B670000F84D
+:108B3000A2802FB5000036101200000009C021B23B
+:108B40000800361012400268129AFEB80000DC0ECF
+:108B500000000030030038F2000036101F00006CE7
+:108B6000D8E086BA0000E00D510000D8020000F203
+:108B700000009F0B0000003C08408092000036106F
+:108B8000000000800200009000007E0B04010080C5
+:108B9000028081BC0000A40B80010080A2802FB65F
+:108BA0000000A40B1201000009C021B21800360019
+:108BB000000000F8730A03F900000000000000D86C
+:108BC000024084320000F00D0060006C08006EF27C
+:108BD00000007F0B4D00000067E0839E0000000056
+:108BE000C001013808C06E3200000000453000E0CE
+:108BF000060000320000A80B12000050F2C138B489
+:108C00000000AD0B040201EC16C06EBC00000000B9
+:108C1000C90100141840813A00C0AD0B1201004098
+:108C2000A28D39B20000AB0B000000800200009062
+:108C300000C00000000000F8A28D2F3100000000ED
+:108C400000A8012099226E3A0000B10B2F2001E00C
+:108C500096226EBC0000A30D00000080020000F010
+:108C60000000B50B0400003CD8E083BC0000B40B4E
+:108C70009F3101E096226EBC00000000003001E050
+:108C8000060000320000B90B005001E8F660809C3D
+:108C90000800000000400268129AFE380000B80B7D
+:108CA0009F3101E096226EBC00000000003001E020
+:108CB0000600003200000000005001E8060000320B
+:108CC0000000000000A801E0060092321800360003
+:108CD000000000F8730A03F91D00BD0B04000080BA
+:108CE00002A417B80000BA0B000000141840819CC1
+:108CF00000000000000000D8028001320020008047
+:108D000000000028090037320000B10F0000000801
+:108D1000E80100F40000C00B1200004802C080B25D
+:108D20000000DC0E00000030030038F20000C40B2D
+:108D300023010014184081BA3E00C30B1200002C1E
+:108D400082CD2EB218003600CA0000F8730A03F96B
+:108D50000000C40B04010014184081BC0000990FEE
+:108D600000000080020000F00000CA0B2931010C55
+:108D700009006EB22B008C071201002C82CD2EB29E
+:108D80000000C80B000000800200009000009C0D55
+:108D9000000C020009806EF20000D30B000000807E
+:108DA000020000900000AA0F00000080020000F006
+:108DB000000000000000001C080090320000D20BF0
+:108DC00004000028098080B20000F10E000000D8E5
+:108DD000020000D20000D20B04000080028092BC8E
+:108DE00018003600000000F8730A03F900007D0542
+:108DF000000000080800009200008C071D000080A1
+:108E0000020000B000008C078000008002812FB6B5
+:108E10002A00D50B1200002C82CD2EB200008C0748
+:108E2000000000F802812F940000BA0D0000001825
+:108E3000094081F20000A30D00A8012009006EF294
+:108E4000000000000030010C09006E3200009C0D93
+:108E5000000C020009806EF200008E070000008006
+:108E6000020000900000990F00000080020000F056
+:108E70000000AA0F00000080020000F000007D0545
+:108E80000000001C0800909200000000545401FCF7
+:108E900002C06E3210000000000000A8780B1638E7
+:108EA00008000000000000AC780B1638000000003D
+:108EB000000000B0A8002D3700440000000000B002
+:108EC000880D8B3A00000000005001B408806E321B
+:108ED0000000ED0B0431019008006EB202000000AA
+:108EE000000000C8828D8A3700000000000000C822
+:108EF000C2A22C3A1800EB0B86410278880D78B696
+:108F00000000E60B9F0100A818808ABC9F00E60BBA
+:108F1000000000A808003692000000000040020493
+:108F2000B83F78300000FB0B00000004D862809C42
+:108F300002000000000000C8828D8A370000000097
+:108F4000000000C8C2A22C3A1800F20B8641027839
+:108F5000880D78B60000ED0B9F0100A818808ABC30
+:108F60009F00ED0B000000A8080036920000F40BF3
+:108F700028400204B83F78B000000000C801000497
+:108F8000D862803C0000F80B02010090182089BCD8
+:108F900000000000000000B4080000320000ED0BEB
+:108FA0009F0100A818808ABC9F00ED0B000000A85C
+:108FB000080036920000FB0B04000090182089BACC
+:108FC000000036109F000004486280BC000036108C
+:108FD000900000B448628BBA0300361004400200CF
+:108FE000081EFFB80000030C00000000D822809A81
+:108FF0000000280C04000080A2E28ABC02000000ED
+:10900000000000C8828D8A3700000000000000C800
+:10901000C2A22C3A1800260C86400278880D78B639
+:109020000000361004400204B83F78B00300361048
+:1090300004400200081EFFB80000070C1201006087
+:10904000084023B200820000000000080880363289
+:10905000000031031201002C72E02EB20000050C5A
+:109060000000008002000090000036101200002472
+:10907000080023B2000036101200002008C023B2FE
+:109080000000361012000018088023B20000000013
+:10909000000000D80280013200C0110C1801000C41
+:1090A000A8CD3EB200000B0C12000038028081B245
+:1090B000000036101200003C020082B200003610A0
+:1090C00012000030024082B200003610120000345C
+:1090D000020086B22080050C00000008088036924D
+:1090E00000000000000000D8020000320000000074
+:1090F00000380200B81B803A00000000643001E034
+:1091000016206E3A00000000000000000740803288
+:10911000000000000008000007008032000000008E
+:10912000001000000740823200000000001800001C
+:10913000070086320000180C12000050F2C138B44B
+:1091400000000000000000D8028001320000000092
+:10915000001800000780813200000000002000009D
+:1091600007008232100000000030000017E02C39A8
+:109170000000000000380000F7010B340000200C54
+:1091800080010080328087B60000000000380000B7
+:10919000B70170340000000000000008E80100344E
+:1091A00000002F0C020C0280A21B89BC18003600A4
+:1091B000000000F8730A03F90000DC0E0000003024
+:1091C000030038F20000240C1200004802C080B2F4
+:1091D00018003600000000F8730A03F90000FD0BC8
+:1091E0009F0100A818808ABC9F00FD0B000000A80A
+:1091F0000800369200002A0C8001008032802FB6D1
+:109200003E00290C1200002C82CD2EB200002C0C46
+:109210001D010080020000B000008C07000000F873
+:1092200062812F9500008C078000008002812FB69C
+:109230002A002D0C1200002C82CD2EB200008C07CB
+:10924000000000F802812F940000000000380000A8
+:10925000C70170340000DC0E00000030030038F25B
+:109260000800330C231901E8762081B93E00320C46
+:109270001200002C82CD2EB20000350C1D010080A2
+:10928000020000B00000380C000000F862812F9549
+:109290000000380C8000008002812FB62A00360CB6
+:1092A0001200002C82CD2EB200000000000000F859
+:1092B00002812F340000FA0D0000002CF90100F4A7
+:1092C00000003B0C120100E802C021B21800360079
+:1092D000000000F8730A03F900003B0C120000487C
+:1092E00002C080B200003203000000F8A2802F9478
+:1092F00000000000000000D80280013200000000E1
+:109300000030002808006E3200000000545401FCB8
+:1093100002C06E3200C0490C1801000CA8CD3EB24C
+:109320002080000000000028098036320000F10E85
+:10933000000000D8020000D20000460C04000080AB
+:10934000028092BC18000000000000F8730A033984
+:10935000470C3600000000C00200369218003600AC
+:10936000000000F8738A03F900000000000000D834
+:109370000280013200C0460C1800000CA8CD3EB29D
+:109380000020008400000028090037320000AD0FE3
+:1093900000000008E80100F400008C0700000080D5
+:1093A0000200009000000000000000D8028001329E
+:1093B00000000000545401FC02C06E3200C0520C88
+:1093C0001801000CA8CD3EB220800000000000086B
+:1093D0000880363200002F031201002C72E02EB2FA
+:1093E0000000500C00000080020000900000510FAF
+:1093F00000000028090002F200005A0C0000005C86
+:109400000800009200000000000000D80280013235
+:1094100000000000545401FC02C06E3200C05A0C1F
+:109420001801000CA8CD3EB220800000000000080A
+:109430000880363200008C0F0000005C1FC0F5FA77
+:1094400000003103000000800200009000000000D6
+:109450000030002808006E32002000840000002840
+:10946000090037320000AD0F00000008E80100F4E9
+:1094700000005F0C0000008002000090000000006F
+:1094800000000008080000320000650C04000080A5
+:1094900002C085B20000650C80000080F2C185B674
+:1094A0000000640C1C41028006C085B20000000070
+:1094B0000000006802C58530000000000000007058
+:1094C0001F00F73A00000000000000F822812F344E
+:1094D0000000DC0C80010080A2802FB61800000084
+:1094E000000000F8730A0339DC0C3600CA0000C023
+:1094F000020036920000AD0C8001008082812FB600
+:109500000000B20C1F20010809006EB20000AD0C73
+:1095100004300108899B90BC0000710C043101806B
+:1095200002006EBC0000E00D00000080020000F0B0
+:1095300000006F0C0050014808806E920000361049
+:109540000000008002000090000000000000000405
+:109550002861803C0000810C000000002821809AD6
+:109560000000E00D0030014808006EF20000740CAD
+:1095700000500104A85B809C0000361000000080B1
+:10958000020000900000000000500100A81B803A7B
+:1095900000007E0C0700004818A084BC08000000F2
+:1095A00000400200189AFE38000000000000006829
+:1095B000020080320000E00D00000080020000F098
+:1095C00000007B0C000000800200009000003610BC
+:1095D000000000800200009000007E0C07000048A0
+:1095E00018A084BC0800000000400200189AFE3851
+:1095F0000000780C00000068020080920000810CDE
+:109600000400004818A084BA000036109F0000042F
+:10961000286180BC00000000000000002821803A82
+:1096200000000000005401FC02C06E3200008A0CF1
+:1096300012010060084023B200820000D601000839
+:10964000088036320300361004400200381AFFB892
+:109650000300000000000078096080391800000055
+:10966000D241028CE6A1973900000000005001E8C9
+:1096700006808432290031031201002C82CD2EB2E3
+:109680000000880C000000800200009000003610EE
+:1096900012000024080023B200003610120000203F
+:1096A00008C023B20000361012000018088023B250
+:1096B00000000000000000D80280013200C0950CBC
+:1096C0001801000CA8CD3EB220800000D601000891
+:1096D0000880363200008F0C12000038028081B200
+:1096E000000036101200003C020082B2000036106A
+:1096F00012000030024082B20000840C12010034DB
+:10970000020086B2000036100000008002000090C7
+:10971000080000000040025C189AFE3800000000BB
+:10972000000000480800003200000000000000D8DF
+:1097300002000032000000000000000007408032FC
+:109740000000000000080000070080320000000058
+:1097500000100000074082320000000000180000E6
+:109760000700863200009C0C12000050F2C138B491
+:1097700000000000D60100D8028001320000000085
+:109780000018000007808132000000000020000067
+:1097900007008232100000000030000017E02C3972
+:1097A0000000A40C80000080328087B6001000808A
+:1097B00000380000070037320000A50C00000080D0
+:1097C00002000090001000880038000007003732C7
+:1097D00018003600000000F8730A03F900000000CA
+:1097E0000000006802C08532000000000000000890
+:1097F000E80100340000A80C1200004802C080B24A
+:1098000018003600000000F8730A03F90000E00DAC
+:1098100000000080020000F00000810C00000080C9
+:10982000020000900000B20C0000008002000090D6
+:109830000000E00D00000080020000F00000B00C0D
+:1098400000380200B81B809C0000B20C00000080B1
+:1098500002000090050000000000006802A0FE3831
+:109860000000AD0C00400280024068920000000041
+:10987000CA0100D8020000320000B50C04B8018013
+:1098800002006EBC0000000000B801E0861BEE3C48
+:109890004C0000000000000007003632000000000D
+:1098A00000000078A9002D37B44400000008000033
+:1098B000878D973A000000000000007899C02C378F
+:1098C000B400000000000078898D973A000036103F
+:1098D0000210000087BF97BA0000000000180000C7
+:1098E0000740FE320000BC0C12000048F2C138B440
+:1098F0000000BD0CB6000080020000B00020BE0CCD
+:1099000012000064A2CD2CB200000000A60000806E
+:10991000020000300000C20C80010080A2802FB63F
+:1099200018003600CA0000F8730A03F900008C071B
+:10993000005401FC02C06E9200000000005401FCC3
+:1099400002C06E320000C80C12010060084023B251
+:109950000082000000000008088036322900310330
+:109960001201002C82CD2EB20000C60C0000008037
+:10997000020000900000361012000024080023B2FC
+:10998000000036101200002008C023B2000036107C
+:1099900012000018088023B200000000000000D868
+:1099A0000280013200C0D30C1801000CA8CD3EB2D9
+:1099B0002080000000000008088036320000CD0C36
+:1099C00012000038028081B2000036101200003C04
+:1099D000020082B20000361012000030024082B253
+:1099E0000000C60C12010034020086B200003610DE
+:1099F00000000080020000900000E00D0000004820
+:109A0000080000F20800D60C0040025C189AFE988C
+:109A100000003610000000800200009000000000EE
+:109A200000500100A81B803A0000970C000000487D
+:109A30000800009200000000005401FC02C06E32D9
+:109A40000000510F00000028098002F20000BD0C48
+:109A500000000080020000900000510F000000286C
+:109A6000090002F20000DF0C9A0100F862812FB4B5
+:109A700010240000000000F8A28D2F31000000002B
+:109A800000D601EC06C06E342E008C071201002CAB
+:109A900082CD2EB20000DF0C00000080020000909A
+:109AA0000000E80C80010080F2C185B60000E50CE2
+:109AB0001F400284E60100B40000E80C1D0100F81C
+:109AC00022812FB40000E80C000000F862812F957D
+:109AD0000000E70C1D010080020000B00000000043
+:109AE000000000F862812F35000000000040028075
+:109AF000024068320000EA0C04980164881B87BCAD
+:109B00000000D70F0090010809006EF20000071056
+:109B100000000080020000F0000036101200006813
+:109B200002C585B000000000000000F8D2802F358B
+:109B300000008E07370000F8D2812FB4000000002B
+:109B4000000000F872812F343D008E071201002CB6
+:109B500082CD2EB20000EF0C0000008002000090C9
+:109B60000000F80C80010080F2C185B60000F50C01
+:109B70001F400284E60100B40000F80C1D0100F84B
+:109B800022812FB40000F80C000000F862812F95AC
+:109B90000000F70C1D010080020000B00000000072
+:109BA000000000F862812F350000000000400280B4
+:109BB000024068320000000000D401EC16C06E3A8A
+:109BC000000036101200006802C585B000008E0744
+:109BD00004B0008002006EBC37008E071201002C1A
+:109BE00082CD2EB20000FB0C00000080020000902D
+:109BF0000000040D80010080F2C185B60000010D57
+:109C00001F400284E60100B40000040D1D0100F8AD
+:109C100022812FB40000040D000000F862812F950E
+:109C20000000030D1D010080020000B000000000D4
+:109C3000000000F862812F35000000000040028023
+:109C4000024068320000100D000000800200009009
+:109C500000000C0D80010080F2C185B60000090DE6
+:109C60001F400284E60100B400000C0D1D0100F845
+:109C700022812FB400000C0D000000F862812F95A6
+:109C800000000B0D1D010080020000B0000000006C
+:109C9000000000F862812F350000000000400280C3
+:109CA000024068320000100D370000F8D2812FB456
+:109CB00000000000000000F872812F343D00100DFC
+:109CC0001201002C82CD2EB200000E0D000000808B
+:109CD000020000900000000000D401EC06000032F9
+:109CE00000008E071201006802C585B00000361022
+:109CF000000000800200009000008C0780010080BE
+:109D0000F2812FB600008C0780000080E2812FB620
+:109D100000008C07085901EC06FB6EBC0000000037
+:109D2000000000D80280013200000000545401FC01
+:109D300002C06E3200C01D0D1801000CA8CD3EB24D
+:109D400000000000005801EC06FB6E3A2080000085
+:109D5000000000080880363200002F031201002C9A
+:109D600072E02EB200001B0D000000800200009087
+:109D70000000AA0F000000F8E2812FF40000200D7F
+:109D80000603018012C06EBC19007D050000001C96
+:109D9000080036921A007D050000001C080036926B
+:109DA00000C00000000000F8A28D2F31000000006C
+:109DB000000000D802800132002000C0000000280E
+:109DC00009003732000000000030002808006E3221
+:109DD00000000000453000E0060000320000AD0F3A
+:109DE00000000008E80100F400002C0D040201EC62
+:109DF00016C06EBC00000000C90100141840813A72
+:109E000000000000000000F802802F3400C02C0D7C
+:109E100012010040A28D39B200002A0D000000801E
+:109E20000200009018003600CA0000F8730A03F917
+:109E300000002C0D9F010014184081BC00008E070B
+:109E40008001008092802FB62B008E071201002C1B
+:109E500082CD2EB200002F0D000000800200009085
+:109E6000000036101F0100D8028001B2000000007F
+:109E7000005401FC02C06E3200C03C0D1801000C01
+:109E8000A8CD3EB2208000000000002809803632B4
+:109E90000000F10E000000D8020000D20000390DD1
+:109EA00004000080028092BC18000000000000F84E
+:109EB000730A03393A0D3600000000C002003692E2
+:109EC00018003600000000F8738A03F90000000053
+:109ED000000000D80280013200C0390D1800000CCB
+:109EE000A8CD3EB20000AA0F000000D8024000F248
+:109EF00000F0430D1D400200A80D68B100003610AF
+:109F00001E400284060000B20000410D120000282D
+:109F1000020580B008003D0D000000F823400199C3
+:109F200000003D0D12010068020580B000003610EF
+:109F300000000080020000900000430DB50000808A
+:109F4000020000B000000000A50080A0360B6A35BA
+:109F5000000000000000005009C02932000000008D
+:109F60000056012808C06E32000000000000007892
+:109F7000390B2E320000000000000020F3819734DE
+:109F800000004C0D04000078D90130B6000000003C
+:109F900000000000B905303018000000000000F893
+:109FA00003A403390000000000000034330B2F32FB
+:109FB0000000590D04000078D90130B600000000FF
+:109FC00000000078B90530300000520D0400008018
+:109FD00042E529BC00000000000000F80200003249
+:109FE00018000000000000F8738A02390000000029
+:109FF0000000009C028097320000580D25010008E7
+:10A00000080000B20000560D12000028020580B0C2
+:10A010000800580D000000F8234001990000580D79
+:10A0200012010068020580B00000361000000080B8
+:10A030000200009000004C0D000000F402000092AD
+:10A0400000005D0D0400008042E529BC0000000016
+:10A05000000000F80200003218000000000000F8C4
+:10A06000738A0239000000000000009C0200953253
+:10A0700000000000CA0100D8028001320000000088
+:10A080000030000007C02C32001000A00038000093
+:10A090000700373200000000002000000700EE3209
+:10A0A000000000000038000C078082320000620DC2
+:10A0B0001200004802C080B2000032030000000815
+:10A0C000E801009400007A0D02000080A24280BCEA
+:10A0D00000007A0D80000080F2C185B600007A0D84
+:10A0E0001F400208B9BF68B000006C0D80410280BB
+:10A0F000E28168B608000000000000107961803934
+:10A1000000000000D22101E016206E3A1800000085
+:10A1100000400288E6219139000000000001005C47
+:10A1200008000072000000000000000C19A0903A26
+:10A1300000007A0D06010080D2FF90BC0000700D77
+:10A140002C410278F98168B400000000000000781A
+:10A15000B98197340300000000400200291AFF383B
+:10A160000000000000380200B91B903A0000000017
+:10A17000D241028816A0973A00000000450000D89E
+:10A1800002400032000036109F2001E016206EBA17
+:10A1900000000000000000000740803200000000C6
+:10A1A000000800002724903A000000000010000082
+:10A1B00007008A320000000012010058F2C1387412
+:10A1C0000000780D00000080020000900800840D5F
+:10A1D0001A000034796180B900008F0D1E010080E3
+:10A1E000020000B000008F0D1F400200094068B25D
+:10A1F00000007C0D80000080E20190B60000361067
+:10A20000380000541F40F5BA0000000000000008AC
+:10A21000B93F903000000000002801E026246E3A8B
+:10A22000080036101E00000009A4FEB800008F0DC3
+:10A2300012010068020590B0000036100000008096
+:10A240000200009000008F0D8000008082812FB6F8
+:10A2500000008D0D1F410200094068B2000000009F
+:10A26000002801E016206E3A00008A0D800100806F
+:10A27000F2C185B60000000000400284E60100340F
+:10A28000000000000000008002000030000000001C
+:10A29000004002800240683200003610380000544E
+:10A2A0001F40F5BA00000000002101E016206E7A80
+:10A2B0000000850D80000080E20190B600007E0D58
+:10A2C000000000541F40F59A000000000000005CF0
+:10A2D0000800003200000000D22101E016206E3A92
+:10A2E000180000001E410284E661937900003610D8
+:10A2F00000000080020000900000FFFF00000080CE
+:10A30000020000900000970D1D5D01EC16C06EBCB0
+:10A31000000000000F01008002000070000000003B
+:10A32000000100F8B2802F74000000000F010080CF
+:10A33000020000700000960D045E01EC16C06EBCB9
+:10A3400000000000005C01EC06400032000000004C
+:10A3500000010080020000700000FFFF000000808C
+:10A3600002000090000000000420018082DB907C4D
+:10A3700000000000020C0280A2DB907C0000A00D17
+:10A3800006210180821B90BC2700A10D0000000067
+:10A390000900369228000000000000000900363253
+:10A3A000000000000000008812002C3A0000FFFFAF
+:10A3B0000000008002000090000000002FA0017843
+:10A3C000891B927A0000000006880178899B977C9F
+:10A3D000000000000034020409C06E3D00000000CF
+:10A3E000000C020019A46E370000AB0D02000080C3
+:10A3F00002A497BC0000AB0D02000080020000B078
+:10A400000100000000000078898D973700000000EF
+:10A4100002010280829B977C00000000000100F88E
+:10A42000F2802F740000FFFF000000800200009007
+:10A4300000000000DA5B01EC0640ED320000B10DD7
+:10A4400004010080024086BC0000000000A001E082
+:10A4500016206E3A0000B30D00D401EC0600009205
+:10A460000000D70F0090010809006EF20000000004
+:10A4700000A001E016206E3A00000710330100F83A
+:10A4800082802FB4000007109FF0018082DB87BC20
+:10A49000000007109FF8018022216EBC0000000020
+:10A4A00000E801E00600EE320000000000F001E0EC
+:10A4B00006C08732000007100000008002000090F4
+:10A4C0000000FFFF00000080020000900000C50DAA
+:10A4D0000421013069246EBC0000BF0D1F4002241E
+:10A4E000094068B20000BB0D80000080E24192B6D6
+:10A4F0000800BB0D1201006892A4FEB800003610DF
+:10A5000000000080020000900000000000A801E0B0
+:10A5100066246E3A0000C20D382001E0060093B2B6
+:10A520000000C30D002801E00600009200000000BA
+:10A53000003001E00600003200000000005001E899
+:10A5400006000032000000000001008002000070E0
+:10A550000000CA0D38510100A99B91BA0000C80D36
+:10A5600004410208B9FF68B00000C60D0040028037
+:10A57000024068920000D50D9F3101E066246EBC58
+:10A580000000D50D003001E0060000920000D30D60
+:10A590000428010409006EB20000D10D9F010000E3
+:10A5A000192490BC0000000000A801E066246E3A67
+:10A5B00000000000002801E00624003C000000002C
+:10A5C000005001E806000032000036109F2001E034
+:10A5D000060093B20000000000010080020000703D
+:10A5E00000000000002801E0060000320000DB0D42
+:10A5F00004000080020090BC0000D50D0441020858
+:10A60000B9FF68B00000D30D00400280024068929C
+:10A610000000D90D02000080222490BC0000DB0D58
+:10A6200080400280F2C168B6000000000040028C49
+:10A63000B6C168350000DB0D000000F822812F94C0
+:10A640000800361012400268129AFEB80000D30DBE
+:10A6500004010000292490BC0000000000A801E0D3
+:10A6600066246E3A00000000005001E806009032B7
+:10A67000000036109F2001E0060093B200000000A9
+:10A6800000010080020000700000FFFF0000008059
+:10A69000020000901800E20D1F41027888CD68B6D4
+:10A6A000000000000000008812002C3A0000E40DB9
+:10A6B00080010080628087B60000E00D00400280CB
+:10A6C000024068920300361004400200381AFFB8B6
+:10A6D000000036101F400204B8FF68B00000000000
+:10A6E00000390200B81B807A0000FFFF00000080E4
+:10A6F000020000900000EF0D80010080A2802FB6C4
+:10A700000000EC0D1201000009C021B21800360053
+:10A71000000000F8730A03F900000000000000D8F0
+:10A72000024084321D00EF0D0401008002A417B81E
+:10A730000000E90D9F010080180088BC0000361061
+:10A740000000008002000090000000000060006C2B
+:10A7500008006E3200000000CA68004C08006E322B
+:10A76000000036100470001808006EB200000000EF
+:10A7700004000080A2A0817C0000F60D8001008012
+:10A78000E2802FB60000F60D1B000080020000B032
+:10A79000000000000600008062E0837C00000000F2
+:10A7A000CA0100F802802F3500A00000120100400D
+:10A7B000A28D39720000F70D0000008002000090A9
+:10A7C0000000FFFF00000080020000900000000079
+:10A7D000000801E406C02D32EEFF0000001001E089
+:10A7E000868D2F31000000000000001CB3E43932D8
+:10A7F0000000000E04000078D90130B6000000000F
+:10A8000000000078B905303018000000000000F8A2
+:10A81000E3A503390000000000000034330B2F32A1
+:10A820000000000004000078D9013076000000002C
+:10A8300000000078B905303018000000000100F871
+:10A84000E3A503790000FFFF0000008002000090F4
+:10A8500000000000000000CC020000320000080EE2
+:10A860002000012C09C06EB20000090E001686CC33
+:10A8700006C0929200000000001486CC06C09232FE
+:10A880000000000012010040628E92520000090E8A
+:10A8900000000080020000900000FFFF0000008028
+:10A8A0000200009000000E0E04000078D90130B6BE
+:10A8B0000E0E3600000000C00200369200000000BC
+:10A8C000000000140300383200000000000000E027
+:10A8D0000200303200004E0E04000024D80130B6D1
+:10A8E000120E000000000088824D823A00003610EF
+:10A8F0000000008002000090000036100000008080
+:10A90000020000900000361000000080020000905D
+:10A910000000361000000080020000900E0E36008D
+:10A92000000000C0020036920000380E00000080D7
+:10A930000200009000001A0E000000204805309030
+:10A940000000361000000080020000900000260E7B
+:10A95000921101BC08006EB200000000000801DC8A
+:10A9600002406E3200001E0E1F1101E026C18BB5A1
+:10A970000000260E1D000080020000B00000000054
+:10A98000000000D802000032800200000000000039
+:10A99000070036320000000000000078A9002D37C3
+:10A9A0002045000000080000878D973A0A0000004B
+:10A9B00000000078890D82370000000000100000C0
+:10A9C000A7BA973A000000000018000007C0EA325A
+:10A9D0000000250E1200004802C038B200002A0E06
+:10A9E000800E01BC08C06EB2000000000000000034
+:10A9F000190E823200E0320E12010048A20D90B210
+:10AA00000000280E000000800200009000000000FE
+:10AA1000000000D802400032B40000000000000036
+:10AA2000070036320000000000000078A9002D3732
+:10AA30000044000000080000878D973A00000000E5
+:10AA400000000078990082370000361002100000E4
+:10AA500087BF97BA00000000001800000740FE32D0
+:10AA60000000310E12000048F2C138B41800360060
+:10AA7000000000F8730A03F9000000000000000461
+:10AA8000896038320000000000000018F341903463
+:10AA90000000380E04000078D90130B60000000034
+:10AAA00000000000B905303018000000000000F878
+:10AAB00003A40339000000000000000019CE2C326E
+:10AAC0000060390E12000040A20D90B2000000009C
+:10AAD000000000D80200003260000000000000000A
+:10AAE0000700363200000000000000BCA8002D372F
+:10AAF000A04700000008000087CD8B3A0A00000044
+:10AB00000000007889CD2C3780020000000000781A
+:10AB1000898D973A0000000000100000A7BA973A0C
+:10AB2000000000000018000007C0EA320000420EDA
+:10AB300012000040F2C138B418003600000000F8DE
+:10AB4000730A03F900000000000801DC02406E32C5
+:10AB50000A00470E1F01007889CD2CB700000000C5
+:10AB60001D1001F802006E7280020000000000005B
+:10AB700007003632204500000008000087CD8B3AE0
+:10AB80000000000000100000A7BA973A0000000083
+:10AB90000018000007C0EA3200004B0E120000400F
+:10ABA000F2C138B418003600000000F8730A03F947
+:10ABB00000000000001101F802006E7200000000A9
+:10ABC000001001F802006E3200000000000901DCF4
+:10ABD00002406E720000FFFF000000800200009043
+:10ABE0000000000000000000090000320E0000001C
+:10ABF00000000004894D0D36000000000000000038
+:10AC000007800B32000000000008000007009032AF
+:10AC10000000000000100000070036320000560E51
+:10AC20001200004CF2C138B40000000000000080A7
+:10AC3000020000300000570E1200008002C021B256
+:10AC40000000000000000000E902903A0000530EEE
+:10AC500004010004194090BC0000000000010080C5
+:10AC6000020000500000FFFF000000800200009082
+:10AC70000000650E80010080A2802FB60000600EEB
+:10AC8000120100E802C021B218003600000000F8EE
+:10AC9000730A03F90000640E0400008002802DBCDA
+:10ACA000000036109F000080180088BC0000600E75
+:10ACB000120100E802C021B200005F0E0000008017
+:10ACC0000200009000000000CA0000D80240843258
+:10ACD000000000000040006C881C833A0000000067
+:10ACE0000048004C0800723200003610085000186E
+:10ACF000C82072BC00000000040000800240817C7B
+:10AD000000000000000000141840813C00003610D4
+:10AD100002000020880182BA00000000000000D874
+:10AD200002000032000000000000000007000632B0
+:10AD30000700000000080000774A09390000000001
+:10AD4000001000000700823200000000CA19000055
+:10AD5000074082320000700E12000040F2C138B489
+:10AD600000000000000100D8024084720000FFFFD4
+:10AD70000000008002000090000000004D00000074
+:10AD800067E0833E000000000008000007008032FA
+:10AD9000000000000010000007C086320000000024
+:10ADA0000018000007C084320000B70E040000281D
+:10ADB000D8A082BC0000000000000018D8A0813C90
+:10ADC0000000890E0400003CD8E083BC00007D0E2A
+:10ADD0000400008072802DBC00007B0E1200005029
+:10ADE00002C038B20000830E510000D812802D9AA4
+:10ADF00000007D0E12000050F2C138B41800360079
+:10AE0000000000F8730A03F90000820E04000080BD
+:10AE100072802DBC00007E0E670000F8A2802FB566
+:10AE200000003610120000E802C021B2000000004D
+:10AE3000510000D8020000320000870E2A010000F5
+:10AE4000D82080BA0000870E1201000009C021B28C
+:10AE500018003600000000F8730A03F90000000033
+:10AE6000000000D8024084320000F00D0060006C49
+:10AE700008006EF20000740E4D00000067E0839E33
+:10AE80000000890E12000050F2C138B418003600DC
+:10AE9000000000F8730A03F91D008E0E0400008004
+:10AEA00002A417B800008A0E670000F8A2802FB530
+:10AEB000000036101200000009C021B20800361050
+:10AEC00012400268129AFEB80000DC0E000000304A
+:10AED000030038F200009F0E1F00006CD8E086BA15
+:10AEE0000000E00D510000D8020000F20000940EB6
+:10AEF0000000003C0840809200009F0E000000808F
+:10AF0000020000900000980E80010080F2812FB6B0
+:10AF10000000980E80000080E2802FB60000980E9E
+:10AF200080010080328087B600000000000000F839
+:10AF3000E2802F340000730E04010080028081BC87
+:10AF400000009D0E80010080A2802FB600009D0EA3
+:10AF50001201000009C021B218003600000000F8FC
+:10AF6000730A03F900000000000000D80240843298
+:10AF70000000F00D0060006C08006EF20000740E1E
+:10AF80004D00000067E0839E0000A30E800100805A
+:10AF9000E2802FB60000BA0E80010080A2802FB69A
+:10AFA00018000000CA0000F8730A0339BA0E360010
+:10AFB000000000C00200369200000000000000A463
+:10AFC000A8608A3C0000A60E2FA8012099226EBA24
+:10AFD0000000A30D00000080020000F0000000004F
+:10AFE00000A801E00600923200000000005001E8D5
+:10AFF000060000320000AA0E232101E0060000B284
+:10B000003E00A90E1200002C82CD2EB20000361098
+:10B01000043000E0068082B20000B20E042100E09D
+:10B02000068081B20000B00E80010080A2802FB6A1
+:10B030000000B00E1201000009C021B21800360055
+:10B04000000000F8730A03F900000000000000D8B7
+:10B05000024084320000F00D0060006C08006EF2C7
+:10B0600000000000002000E0068081320000361061
+:10B07000041000E006C086B2000000002A1900E0BB
+:10B0800006C0847200000000000000F8A2802F3586
+:10B09000000000001201000009C0217218003600F3
+:10B0A000000000F8730A0399000000000000003C53
+:10B0B000D8E0833C0000B80E12000050F2C138B452
+:10B0C00000000000000000F8A2802F340000000003
+:10B0D0000000008812002C3A0000FFFF00000080F2
+:10B0E0000200009000000000000000000900003293
+:10B0F000000000000000007809000032000000009D
+:10B10000000000A802000032EE05C20E040100801B
+:10B11000820DF6BC0006000000000008090036326F
+:10B120000000C40E0000000409C0099200280000BD
+:10B130000000000809003632000000000000000492
+:10B14000098009321E000000000060C087CD003772
+:10B1500000000000000860C0078097320030000047
+:10B1600000000078898D2A3A000036101200005C39
+:10B17000528197B400000000000000002924903A9A
+:10B180000800000000000078890D903600000000E3
+:10B19000000000041940903C00000000000000A8DE
+:10B1A00052822A3A0008C40E02010080828D2ABC15
+:10B1B0000000D50E06000080024090BC0000361052
+:10B1C000120000A8020020B21E000000000000C013
+:10B1D00087CD003700000000000800C007809732CC
+:10B1E000000036101200005C52812AB400000000FA
+:10B1F000000000002924903A0800000000000078B8
+:10B20000890D90360000CE0E04010004194090BC58
+:10B210000500000000000078890D9036000036100F
+:10B2200012000068028097B20000000000000000D9
+:10B230002924903A00000000000000785900903660
+:10B240000000D60E95010080222490BA0000000074
+:10B2500000010080020000500000FFFF000000809D
+:10B26000020000900000000004010078D90130764F
+:10B27000000000000000002809C029320000000082
+:10B280000000009CB24528300000E80E860100084E
+:10B2900009802FB2000000000000002C094081321C
+:10B2A00000000000000000F8020000320000000072
+:10B2B000000000F40200003218000000000000F856
+:10B2C000738A0239000000000000009C0280923264
+:10B2D0000000E70E0407018002C06EBC0000ED0E06
+:10B2E000C30701ECB6E46E9A0000ED0E000601EC17
+:10B2F000B6E46E9A000000000000002C09058030C2
+:10B3000000000000000000F8020000320000000011
+:10B31000000000F40200003218000000000000F8F5
+:10B32000738A023900003F0F0000009C028092D215
+:10B330000000000000000030030038320000000070
+:10B3400004010078D90130760000DF0E0000009C77
+:10B35000B24528900000FFFF00000080020000902E
+:10B36000000000000000008802C0E8320200F20E77
+:10B37000B00000A0F20B00B9000000000000000CBB
+:10B38000ABE4B0320000F70E80010080F24BD0B683
+:10B3900000000000A00000280900003200000000AA
+:10B3A00000010080020000500000F90E040100803E
+:10B3B000123EF8BA0000040FA0000004FD4BD09428
+:10B3C0000000000F80010080D28192B60000000FC3
+:10B3D000800100802281FCB600000000A000000473
+:10B3E000FD4BD034000000000000008401C02F326B
+:10B3F0000000000000000080F101003400000000A7
+:10B400000000009401C02F320000040F00000090E3
+:10B41000F101009400000000A000008401C02F3260
+:10B420000000000000000080F101F834000000007E
+:10B43000000000900140F8320000000000010028E8
+:10B44000090000520000080F040100280934B0BAB6
+:10B450000000050FB0000080020000B000000000F6
+:10B46000A0000004FD4BD0350000000000010028C2
+:10B47000090000520000080FB00000A822C02FB73A
+:10B480000000060F040084C037ACB0B2000000001A
+:10B49000A000000C0B000032FFFF0000000000784D
+:10B4A000A94DB03000000F0F800000800240B0B600
+:10B4B000000000000000007869819735000000005E
+:10B4C000000084080B007C32000000000000000037
+:10B4D000E72501320042000000080000878D2A3A6B
+:10B4E00000000000001000000700B0320000000063
+:10B4F000001800000700D0320000000012010048D0
+:10B50000F2C138540000130F0000008002000090C8
+:10B510000000150FB00000A0020000B20000000003
+:10B520000000000CABE4B03200001A0F8001008074
+:10B530000240D0B600000000A00000280900003240
+:10B5400000000000000100800200005000001C0FFD
+:10B5500004010080123EF8BA00002D0FA000000484
+:10B560000D40D0940000260F80010080D28192B659
+:10B570000000260F800100802281FCB60000000040
+:10B58000A00000040D40D03400000000000000784E
+:10B5900009C02F3200000000000000FC0200003251
+:10B5A000000000000000008401C02F3200000000F5
+:10B5B00000000080F1010034000000000000009451
+:10B5C00001C02F320000000000000090F1010034A3
+:10B5D00000002D0F000000FC028097920000000088
+:10B5E000A000007809C02F3200000000000000FC1D
+:10B5F00002000032000000000000008401C02F3271
+:10B600000000000000000080F101F834000000009C
+:10B61000000000900140F83200000000000000FC33
+:10B62000028097320000000000010028090000524B
+:10B630000000310F040100280934B0BA00002E0FB9
+:10B64000B0000080020000B000000000A000000474
+:10B650000D40D03500000000000100280900005214
+:10B660000000310FB00000A8020000B200002F0F50
+:10B67000040084C037ACB0B200000000A000000C91
+:10B680000B000032FFFF000000000078A94DB03031
+:10B690000000380F800000800240B0B600000000BB
+:10B6A00000000078698197350000000000008408E0
+:10B6B0000B007C320000000000000000E725013292
+:10B6C0000042000000080000878D2A3A00000000B8
+:10B6D000001000000700B032000000000018000059
+:10B6E0000700D0320000000012010048F2C13854B7
+:10B6F00000003C0F00000080020000900000FFFFEF
+:10B7000000000080020000900000410F1C400280F9
+:10B7100006C092B244000000000100F8A28D2F5232
+:10B72000000036101200006802C592B00000000050
+:10B73000000100701F00F75A0000FFFF00000080AA
+:10B740000200009000000000D5080000078092323F
+:10B75000000000000030000007C02C3200400080D4
+:10B76000003800000700373200000000CA4101E045
+:10B77000068092320000480F1200004802C080B2DA
+:10B780000060000000010008088036720000FFFF22
+:10B79000000000800200009000000000003800005F
+:10B7A00007809232000000000030000007C02C32F9
+:10B7B00000000000CA3D000C07808332000000003A
+:10B7C0001201004802C0807200004E0F000000808D
+:10B7D000020000900000FFFF0000008002000090C7
+:10B7E000000000000457018002C06E7C00000000D1
+:10B7F000005701EC068092720000FFFF00000080FD
+:10B80000020000900000DC0E00000030030038F25F
+:10B810000000570F9D11020C09006EB20000580F76
+:10B8200000F0011C09006E920000000000B8011C2D
+:10B8300009006E3200005A0F2CCD011809806EB23B
+:10B84000000000000000000CC9C1903400005D0F32
+:10B850003B29020409806EB20000000000D601EC12
+:10B8600056C06E34000000000000000CB9C19034D6
+:10B8700000006C0F00A8010809006EF20000610FC3
+:10B880009D01008017E090BA0000000000300080A9
+:10B8900007C091320000640F003800800700EE926C
+:10B8A0000000640F0401008002C091BC0000000091
+:10B8B00000B801E00600EE3200000000007001E078
+:10B8C000060086320000660F3908008007C085B286
+:10B8D00000000000D9C901E8068091320000000094
+:10B8E000C8110080074090320000690F3B210080A2
+:10B8F000070086B200000000DB0000601800863AF6
+:10B9000000000000587801E01620863A0000000090
+:10B9100000290080070085720000FFFF0000008002
+:10B92000020000900000700F020C0280A29B90BCED
+:10B93000000000000000027829006E360000700F41
+:10B9400002000080E2A590BC00000000000000089A
+:10B95000090000320000720F9F89017849216EBCF6
+:10B960000000000000000078090000320000000024
+:10B9700000000008E9A5903F0000780F04200208AD
+:10B98000899B90BE00000000000A0258B89B9036C8
+:10B99000000000000000007849A1903A000000007B
+:10B9A0009F880180829B977C00000000008901E055
+:10B9B0000680977200000000000B0258B89B90763A
+:10B9C0000000FFFF000000800200009000007F0FD9
+:10B9D00080010080A2802FB600007E0F1201007847
+:10B9E00009C021B218003600000000F8730A03F9FC
+:10B9F00000007F0FCA0000D80240849200000000BF
+:10BA0000000000F8A2802F35000000000040006C0C
+:10BA1000881C833A000000000048004C0800723285
+:10BA20000000361008500018C82072BC000000004A
+:10BA30000600008062A0827C000036100200002018
+:10BA4000880182BA00000000000000D80200003225
+:10BA500000000000000000000700063207000000A0
+:10BA600000080000774A09390000000000100000BB
+:10BA70000700823200000000CA190000074082322D
+:10BA80000000890F12000040F2C138B4000000002D
+:10BA9000000100D8024084720000FFFF0000008017
+:10BAA000020000900000930F80010080F2C185B673
+:10BAB0000000900F1F400284E60100B40000930FC5
+:10BAC0001D0100F822812FB40000930F000000F840
+:10BAD00062812F950000920F1D010080020000B0CE
+:10BAE00000000000000000F862812F350000000017
+:10BAF00000400280024068320000361012000068E8
+:10BB000002C585B0000000001D000080020000702A
+:10BB10000100000004010080A28D2F702A00960F02
+:10BB20001200002C82CD2EB200000000000100F8AF
+:10BB300002812F740000FFFF0000008002000090CF
+:10BB400080A8000004000080828D2F7000009F0FED
+:10BB500080010080D2802FB600009F0F04B00080CB
+:10BB600002006EBC00000000000000F872812F345B
+:10BB70003D00A20F1201002C82CD2EB200009D0FBD
+:10BB800000000080020000900000A20F80010080F1
+:10BB9000F2802FB63C00A50F1201002C82CD2EB2F0
+:10BBA0000000A00F00000080020000900000A50F20
+:10BBB00080010080B2802FB63500A30F1200002C48
+:10BBC00082CD2EB200000000000000F842812F3428
+:10BBD0008000000004000080828D2F7002000000B1
+:10BBE00004010080A28D2F703B00A70F1200002CD3
+:10BBF00082CD2EB200000000000100F812812F74E7
+:10BC00000000FFFF0000008002000090080000001C
+:10BC1000001801E876208139EEFF0000000100F8ED
+:10BC2000828D2F710000FFFF000000800200009055
+:10BC30000000B10F0000013808C06EF200000000E3
+:10BC40001201004802C080720000AE0F00000080A8
+:10BC5000020000900000FFFF000000800200009042
+:10BC60000000B30F0438017809006EB20000000034
+:10BC7000003801E00600003200000000CA11000098
+:10BC8000078082320000B60F2E190000078097B29D
+:10BC90000000000000000028E98192340000BB0F82
+:10BCA0002731000007C02CB200000000D5080000BA
+:10BCB0000700873200000000C7000028E9809234A6
+:10BCC00000000000004001E0060087320000000094
+:10BCD00000000008D8818034100000000039000006
+:10BCE000E7A092790000FFFF0000008002000090B2
+:10BCF0000000BD0F1200004412E438B218003600F4
+:10BD0000000000F8730A03F90000C20F040100806C
+:10BD100002802DBC0000BE0F670000F8A2802FB586
+:10BD200000003610120000E802C021B2000000003E
+:10BD3000000100D8024000720000FFFF00000080F8
+:10BD4000020000900000C70F04300080829B81BC7D
+:10BD500000000000CA0100F802802F3500A0C60FC5
+:10BD600012000040A28D39B200C0CB0F0438007819
+:10BD7000898D6EB01000CB0F9F0100F8E2A52FB99E
+:10BD800000000000005801EC06C0EE320000000088
+:10BD900000000080020000300000000004280018AD
+:10BDA00009006E720000BA0D00000080020000F071
+:10BDB0000000A30D00A8012009006E920000FFFF03
+:10BDC00000000080020000900000D40F04B000804A
+:10BDD000829B81BC0000000000B800E886806E34C1
+:10BDE00000000000CA0100F842802F3508A00000C2
+:10BDF00012010040A2CD39720000D20F0000008075
+:10BE0000020000900000000000B800E886806E3458
+:10BE10000000000000010080020000700000FFFF31
+:10BE200000000080020000900000DA0F33CD01BC5A
+:10BE300008806EB200001410000000282922EEDCF9
+:10BE40000000DF0F00000080020000900000DF0F04
+:10BE500004B8012809006EB20000DF0F9F71018055
+:10BE6000C2216EBC000036109F000028A924EEBC41
+:10BE70000000141000000028198092DF000000006C
+:10BE800000000080020000300000F20F02810180FB
+:10BE9000829B90BCEE05EA0F060C0280828D6EBC80
+:10BEA00000904C0000000084020037320000E40FD4
+:10BEB000B8010080020000B00000E20F0000008026
+:10BEC0000200009000000000000000C403809032D7
+:10BED0000000000000B001E096216E3C0000000070
+:10BEE000619801E0060087320000000000D401ECF8
+:10BEF0000600003200000000A800007849403C37EE
+:10BF00000000F70F00000008E9A5909A6089200062
+:10BF100000000084020037320000ED0FB8010080FD
+:10BF2000020000B00000EB0F000000800200009053
+:10BF300000000000000000C40380903200000000F8
+:10BF400000B001E096216E3C00000000619801E025
+:10BF5000060087320000000000D401EC0600003229
+:10BF60000000F70FA8000008198F909A0000000049
+:10BF70000000007899A1893E000000000000000840
+:10BF8000E9A5903A0000000000B001E096216E3C67
+:10BF900000000000619801E0060087320000000008
+:10BFA00000D401EC060000320000FA0F0600008009
+:10BFB00072A290BC00C0FF3F008001E00600373253
+:10BFC000000000000000000809C089320000FF0FD7
+:10BFD00004790180821B87BC0000FD0F04B0008043
+:10BFE00002006EBC00000110D99001E00680909222
+:10BFF000000004108000008052812FB60000041061
+:10C00000D54101E006008792000001103C9001E05C
+:10C01000068090B20000000000C801E806C08B3224
+:10C02000000000009501008002802F7200000510C2
+:10C030009F410180821B87BC00000000000100803E
+:10C040000200007000000000D99001E006809032EC
+:10C0500000000000000100F872802F740000FFFF54
+:10C06000000000800200009000000D109FD80180A9
+:10C0700022216EBC000000000B0100800200007055
+:10C0800000000D109FE00180C2216EBC0000000086
+:10C090000B0100800200007000000D109FB00180B5
+:10C0A000D2216EBC00000000000100800200007080
+:10C0B00000000F1006680180825B87BC0000000052
+:10C0C000006801E0064087320000111037B001E03F
+:10C0D000064087B200000000000000F8D2802F3434
+:10C0E0000000000000D801E006808432000000005B
+:10C0F00000E101E0060087720000FFFF0000008001
+:10C10000020000900000201004C1018402006EB201
+:10C110000500000000C001E8868D92370300000092
+:10C1200000C401E8868D9237000000000000008006
+:10C13000020000300300000000C0012C898D6E3623
+:10C140000000000000C4012CA9DB923A00000000AE
+:10C150000000002C29C09236000000000000002CD6
+:10C1600019FB923F00000000000000282980923A4D
+:10C17000000000000000002CA9E4923F0000000035
+:10C180006FCC01E826FB923E0000000000B901E000
+:10C19000060000520000000000000094028092326D
+:10C1A0000000000000C001E006402832100000003E
+:10C1B0006FCC01E886CD2A360000000000B901E00E
+:10C1C000060000520000FFFF000000800200009007
+:10C1D00000000000009001BC08006E32000000006A
+:10C1E00000B001BC88DB8B3E00000000009801BC61
+:10C1F00088DB8B3A000030109F0000BC88E18BBCCC
+:10C2000000003010040C0240A8DB8BBE00000000D0
+:10C2100000B00004881B843E00002D1004B1008093
+:10C22000825B80BC00000000000100F8C2802F7417
+:10C2300000000000040C0280A25B807C0000301033
+:10C240000468017819006EB600000000020000804A
+:10C25000E265807C000000000000008812002C3A9B
+:10C260000000FFFF000000800200009008000000B6
+:10C27000001C01E876208139EEFF0000000100F883
+:10C28000828D2F710000FFFF0000008002000090EF
+:10C2900000003610000000B40F40FB9400000000C6
+:10C2A000000000880F402B320000000000000090CA
+:10C2B0000F00283200000000000000940F00293217
+:10C2C00010000000000000B85F461839FF000000B1
+:10C2D0000000009C0F003632000000000000009CAF
+:10C2E0005FCAF935000000000000004403C0F932C5
+:10C2F00000000000000000E40300003241000010D4
+:10C30000000000E00300373200000000000000E4FD
+:10C310000300003240000010000000E0030037324C
+:10C3200000004510670000980F802AB2000000004E
+:10C33000000000A8020000320000431012C186E095
+:10C3400007C021B20000000000B886C006802A3273
+:10C350004C420000000000A802003632471058117D
+:10C36000000000B00F003692000000000000009CAA
+:10C370000200003200014411000000AC0F0036D270
+:10C3800000000000000000AC0F802A3200200000F6
+:10C39000000000A802003632000000000000009CEF
+:10C3A0000F007E3200000000000000A00F007E326F
+:10C3B00000000000000000A40F007E32000000001A
+:10C3C000000000A80F007E3200000000000000A85E
+:10C3D00002C0FA3200000000000000E007C0F9329D
+:10C3E00000000000000000E00700FA32000000003A
+:10C3F000000000E00740FA3200005B10000000E09F
+:10C400000780FAD200000000000000E00780FB3245
+:10C4100001008210040100B48F4DFBB00200000047
+:10C42000000000A002000039408000000000000C65
+:10C43000ABCDB032100000000000000C5BCAB03978
+:10C44000000000000000000C2BFEB0320000811143
+:10C45000000000800200009000000000000000F8D2
+:10C460000300013200000000000100E007803F529D
+:10C4700018000000000000F8738A02390000000074
+:10C4800000000044530A1635000000000000009C24
+:10C490000F80963200000000000000A00FC096320E
+:10C4A00000000000000000A40F009732A26003000B
+:10C4B0000000005803003732681000000000005CE4
+:10C4C000030036320000000000000050830D0034ED
+:10C4D0000000000000000048830D00340000000050
+:10C4E00000000044530A00340000360000000080C1
+:10C4F00002000090000000000000006809C0F9324E
+:10C50000000000000000006C0900FA32000000008A
+:10C51000000000700940FA3200007A10000000802C
+:10C520000200009002000000000000A0F20B0039A1
+:10C5300000006F10800100801240B0B600000000C3
+:10C54000000000043B40B033000000000000000485
+:10C55000FD4BD035000073100000000C0B009792CB
+:10C5600002000000000000A0F20B00390000731070
+:10C57000000000046B019794000073101200006823
+:10C58000094020B2000074101200006C094020B273
+:10C590000D000000000000FCA2E516380000791034
+:10C5A0009F000080028096B2000000000000007032
+:10C5B00009C0963200007A100000006C09C0FD929C
+:10C5C0000000791012000070094020B20000000045
+:10C5D0000000009C0200003200000000000000D8B3
+:10C5E0000200003202007310040100BCAF2517B82E
+:10C5F00006007110040000BCAF6516B800006C1096
+:10C600000400008022C0FBBC00008A1004000080EF
+:10C6100012C1FBBC200073100401008082CDFBBC62
+:10C6200002000000000000A0F20B003900008B1097
+:10C6300000000080020000D084100000000000888C
+:10C6400082CDF93A00007A110000008002000090CB
+:10C650000000B31000000080020000900000B41041
+:10C6600000000080020000900000B8100000008070
+:10C67000020000900000C010000000800200009046
+:10C6800000001911000000800200009000007310EB
+:10C69000000000DC0F009792000000000000000086
+:10C6A0000700033240420000000000A802003632BA
+:10C6B000000000000008000007802A32000000008F
+:10C6C0000010000007009732000000000018000072
+:10C6D00007C096320880901012000040028036B2E7
+:10C6E00000000000000000800200003000009210F6
+:10C6F0001200009C0FC021B21D00951004000080A4
+:10C7000072BE17B800009210000000F81E80EF9A69
+:10C71000130000000000009C7FBE17380000981036
+:10C720000400008012C0F9BC00009210000000F864
+:10C730001E80EF9A000000000000009C0F007E3277
+:10C7400000000000000000A00F007E32000000008A
+:10C75000000000A40F007E32000000000001000075
+:10C760000700FA52000000000000009C02000032A6
+:10C770004C420000000000A8020036320000000019
+:10C780000008000007802A3200006E1100000080BF
+:10C79000020000D00000721100000080020000D0F2
+:10C7A000000000000000000CCBC1B034000000000D
+:10C7B0000000009C0200003200000000000000D8D1
+:10C7C000020000320000F10E0000002809C0B0D2C3
+:10C7D0000000A21004000080028092B20000A610A7
+:10C7E0001200009C0FC021B21D00A910040000809F
+:10C7F00072BE17B80000A610000000F81E80EF9A65
+:10C80000130000000000009C7FBE17380000AC1031
+:10C810000400008012C0F9BC0000A610000000F85F
+:10C820001E80EF9A0200AE10040100B48F4DFBB0E1
+:10C83000000073100000008002000090080000005B
+:10C84000000000F89340013900000000000000B42F
+:10C850001F40FB35FE000000000000480300363298
+:10C860000000000000000044030000340000A2109B
+:10C870000000000C8BC1B09400007E110008000085
+:10C880000740FA9200006E11000800000740FAD23B
+:10C890000880B51012000050028036B200007311FB
+:10C8A00000000080020000D0000080110000008025
+:10C8B00002000090000800000000009C0F003632CB
+:10C8C00000440000000000A8020036320000000012
+:10C8D000000000A00200003200000000000000E0A4
+:10C8E0000700B03200000000000000A012002A3A49
+:10C8F0000000BB100401009C1FC0F9BC00440000F4
+:10C90000000000A80200363202007D11000000A0E5
+:10C91000F20B00990000C810040100800240FAB236
+:10C9200000440000000000A8020036320000CA10D7
+:10C9300000000080020000D00000D710000000843A
+:10C94000020000D200000000000000E007C03C32FE
+:10C950000000C4108E010080024028B20044000094
+:10C96000000000A40F0036320000B3100000008069
+:10C970000200009000440000000000A48F4DFA3A2D
+:10C980000000B310000000800200009000000000D2
+:10C990000000009C0F00003210000001000000ACFD
+:10C9A0000F0037320000DC1000000080020000D0D1
+:10C9B0000800CC100401008082CDF9BC000000000A
+:10C9C0000000009C0F0000320E000001000000ACCF
+:10C9D0000F0037320000DC1000000080020000D0A1
+:10C9E0000B00D0100401008082CDF9BC20000000B3
+:10C9F0000000009C0F0036320F000001000000AC68
+:10CA00000F0037320000DC1000000080020000D070
+:10CA10002700D4100401008082CDF9BC0000000082
+:10CA20000001008002000050000000000000009C97
+:10CA30000F0000320F000001000000AC0F00373281
+:10CA40000000DC1000000080020000D02000D9109F
+:10CA50000401008082CDF9BC0000000000010080CC
+:10CA60000200005000000000000000E403C0F932A2
+:10CA70000D000001000000E003003732000000005C
+:10CA8000000000E003C0FA3200000000000000E0F7
+:10CA900007403E32000000000001009C1FC0F95A10
+:10CAA00000000000000000E003C0F93200000000B8
+:10CAB000000000E007403E32000000000000009C43
+:10CAC0001FC0F93AFF000000000100AC8FCDF95003
+:10CAD000000000000000009C0FC02F32000000008A
+:10CAE000000000FC0200003200000000000000E036
+:10CAF00007803E3200000000000000FC12C02F3A08
+:10CB00000F00E7100401008082CD2FBC0000000060
+:10CB1000000000E007803E3200000000000100FC41
+:10CB200002C0F95200000000000000E007003A32A5
+:10CB300000000000000000E007403A320000000062
+:10CB4000000000E007803A3200000000000000E032
+:10CB500007C03A32000000000000009C0FC02F32D6
+:10CB600000000000000000FC020000320000000095
+:10CB7000000000E007003D3200000000000000E07F
+:10CB800007403D320000F210830100FC12C02FBAB2
+:10CB900000000000000100FC02C0F952000000008B
+:10CBA0000000009C0F0000320C0000000000000894
+:10CBB000733E003900000000000000E00700303242
+:10CBC000000000000000009C1FC0F93A7000F71040
+:10CBD0000401008082CDF9BC000000000000000CC0
+:10CBE0000300003200000000000000E007003032C7
+:10CBF00000000000000000100300003200000000F0
+:10CC0000000000E007003032000000000000009C3F
+:10CC10000F00003200000000000000A00FC0293209
+:10CC2000000000000000009C02C0F932000000007B
+:10CC3000000000A40FC02C32000000000000009C87
+:10CC40000200FA32180000000000002C737EFA394E
+:10CC500000000000000000E007003032000000117A
+:10CC60008501009C1FC0F9BA00000000000100808F
+:10CC700002000050010000010000009C0F0037324C
+:10CC80000000E11000000080020000D00E000F1133
+:10CC90000401008082CDFABC00000000000000E02A
+:10CCA0000700003200000000000000E00700003232
+:10CCB00000000000000000E0070000320000091141
+:10CCC0000000009C3FC0F99A1C000911040100807B
+:10CCD00082CDFABC0200E1100000009C8FCDF9DA91
+:10CCE000000000000001008002000050010000026E
+:10CCF0000000009C0F0037320000E11000000080AF
+:10CD0000020000D00E0017110401008082CDFABC91
+:10CD100000000000000000E00700003200001311D6
+:10CD20000000009C1FC0F99A260013110401008026
+:10CD300082CDFABC0000000000010080020000501B
+:10CD400000000000000000A80F402932004400004D
+:10CD5000000000A802003632000008110000008028
+:10CD6000020000D00000121100000080020000D07C
+:10CD70000000E51000000080020000D0000000006C
+:10CD8000000000E00780183200000000000000E012
+:10CD900007401A3200000000000000E007001A32CD
+:10CDA00000000000000000E007801A3200000000D0
+:10CDB000000000E007C01A3200000000000000A0E0
+:10CDC0000F000032A2600300000000580300373259
+:10CDD0002B1100000000005C030036320000000050
+:10CDE0000000009C0F802A3200002B1104000080FC
+:10CDF000024029B20000000000000050833E0034D1
+:10CE00000000000000000048833E003400000000E5
+:10CE100000000044530A003400002C110000008878
+:10CE20000F402B9200000000000000900F002832FD
+:10CE300000000000000000940F00293200000000F4
+:10CE4000000000980F802A3200000000000000A8B7
+:10CE500002C0F93231115811000000B00F003692B3
+:10CE60000700341104000080824D29BC000000003E
+:10CE7000000000A01F00FA3A000028110000009CEA
+:10CE80000F802A92C0010000000000AC0F00363273
+:10CE9000010000000000009C020036320000441136
+:10CEA00000000080020000D01F003A110400008042
+:10CEB00082CD29BCC0000000000000AC8FCDFA3A42
+:10CEC000000036110000009C12C0299A0000F610E4
+:10CED00000000080020000D00000EC100000008084
+:10CEE000020000D00000421104000080528AFABC07
+:10CEF000A260030000000058030037324211000016
+:10CF00000000005C0300363200000000000000500A
+:10CF1000A33E00340000000000000048A33E00349F
+:10CF20000000000000000044530A003400440000E8
+:10CF3000000000A40F0036320000B3100000008093
+:10CF40000200009000000000000000C402C0FA329D
+:10CF5000030000000000009C0F00363200000000BB
+:10CF6000000000BC0F402F3200004B110400009C59
+:10CF70001FC0F9BC00004A110400008002402FB21B
+:10CF800000004711000000E007002C92000047114C
+:10CF9000000000E00700369200000000000000E002
+:10CFA00007402C3200000000000000E007802C3217
+:10CFB00000000000000000E007C02C32000000006C
+:10CFC000000000E007002D3200000000000000E03B
+:10CFD00007402D3200000000000000E007802D32E5
+:10CFE00000000000000000E007C02D32000000003B
+:10CFF000000000E007C0FB3200000000000000E07D
+:10D0000007802F3200000000000000E007C02F3230
+:10D0100018000000000000F8730A02390000000048
+:10D02000000100E007803F52FF00000000000044C4
+:10D030000300363200000000000000E00700F93273
+:10D0400000000000000000E007402832000000005F
+:10D05000000000E00780F832030000000000009CA0
+:10D060000F00363200000000000000BC0FC02B3261
+:10D07000000061110400009C1FC0F9BC0000601199
+:10D080000400008002C02BB200005D11000000E02F
+:10D0900007C0289200005D11000000E007003692F2
+:10D0A00000000000000000E00740F932000000002E
+:10D0B000000000E00740293200000000000000E00E
+:10D0C0000780293200000000000000E007C029327C
+:10D0D00000000000000000E007002A32000000000D
+:10D0E000000000E007402A3200000000000000E0DD
+:10D0F0000780F93200000000000000E007C02A327B
+:10D1000000000000000000E007C02F320000000017
+:10D11000000000E007402B3200000000000000E0AB
+:10D1200007802B3200000000000000E007C0FB3247
+:10D1300000000000000000880200FB320000000038
+:10D140000000009C0200003200000000000000D837
+:10D1500002000032000000000010000007009732BB
+:10D16000000000000019000007C0965208807211EC
+:10D1700012000048028036B200000000000000806B
+:10D1800002000030000074111200009C0FC021B298
+:10D190001D0077110400008072BE17B800007411E2
+:10D1A000000000F81E80EF9A130000000000009CB1
+:10D1B0007FBE1738000000000400008012C0F95C38
+:10D1C00000007411000000F81E80EF9A00000000BB
+:10D1D000000000B40F40FB35000000000000009C80
+:10D1E000020000324C420000000000A8020036326B
+:10D1F000000000000008000007802A3200006E11C5
+:10D2000000000080020000D00000721100000080C9
+:10D21000020000D0000000000000000CCBC1B034C0
+:10D22000000000000000009C02000032000000002E
+:10D23000000000D80200003200008B11000000281E
+:10D2400009C0B0D20000811104000080028092B2B7
+:10D25000000085111200009C0FC021B21D00881132
+:10D260000400008072BE17B800008511000000F8AD
+:10D270001E80EF9A130000000000009C7FBE17384C
+:10D28000000073100400008012C0F9BC000085117A
+:10D29000000000F81E80EF9A00000000000000FC73
+:10D2A0000200003202000000000000A0F20B003972
+:10D2B00000008F11040100280934B0BA00000000FA
+:10D2C000000100280900005200000000000000A832
+:10D2D00022C02F3700000000000084C037ACB032FD
+:10D2E000000000000000000C0B000032FFFF0000F7
+:10D2F000000000C0AF4DB0300000951180000080EC
+:10D300000240B0B600000000000000C06F01FC3514
+:10D310000000000000000000073F01320042000052
+:10D3200000080000878D2A3A00000000001000006D
+:10D330000700B03200000000001800000700D032E3
+:10D3400000000000000000C03FC1383400000000B1
+:10D3500012010048F201FC5400009A110000008004
+:10D36000020000900000FFFF00000080020000901B
+:0CD3700000003600000000800200009069
+:00000001FF
diff --git a/fs/Kconfig b/fs/Kconfig
index cef8b18..86b203f 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -66,6 +66,13 @@
 	bool
 	select FS_POSIX_ACL
 
+menu "Caches"
+
+source "fs/fscache/Kconfig"
+source "fs/cachefiles/Kconfig"
+
+endmenu
+
 if BLOCK
 menu "CD-ROM/DVD Filesystems"
 
@@ -169,6 +176,8 @@
 source "fs/sysv/Kconfig"
 source "fs/ufs/Kconfig"
 
+source "fs/exofs/Kconfig"
+
 endif # MISC_FILESYSTEMS
 
 menuconfig NETWORK_FILESYSTEMS
diff --git a/fs/Makefile b/fs/Makefile
index b5cd8e1..70b2aed 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -63,6 +63,7 @@
 obj-$(CONFIG_DLM)		+= dlm/
  
 # Do not add any filesystems before this line
+obj-$(CONFIG_FSCACHE)		+= fscache/
 obj-$(CONFIG_REISERFS_FS)	+= reiserfs/
 obj-$(CONFIG_EXT3_FS)		+= ext3/ # Before ext2 so root fs can be ext3
 obj-$(CONFIG_EXT2_FS)		+= ext2/
@@ -116,7 +117,9 @@
 obj-$(CONFIG_BEFS_FS)		+= befs/
 obj-$(CONFIG_HOSTFS)		+= hostfs/
 obj-$(CONFIG_HPPFS)		+= hppfs/
+obj-$(CONFIG_CACHEFILES)	+= cachefiles/
 obj-$(CONFIG_DEBUG_FS)		+= debugfs/
 obj-$(CONFIG_OCFS2_FS)		+= ocfs2/
 obj-$(CONFIG_BTRFS_FS)		+= btrfs/
 obj-$(CONFIG_GFS2_FS)           += gfs2/
+obj-$(CONFIG_EXOFS_FS)          += exofs/
diff --git a/fs/afs/Kconfig b/fs/afs/Kconfig
index e7b522f..5c4e61d 100644
--- a/fs/afs/Kconfig
+++ b/fs/afs/Kconfig
@@ -19,3 +19,11 @@
 	  See <file:Documentation/filesystems/afs.txt> for more information.
 
 	  If unsure, say N.
+
+config AFS_FSCACHE
+	bool "Provide AFS client caching support (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	depends on AFS_FS=m && FSCACHE || AFS_FS=y && FSCACHE=y
+	help
+	  Say Y here if you want AFS data to be cached locally on disk through
+	  the generic filesystem cache manager
diff --git a/fs/afs/Makefile b/fs/afs/Makefile
index a6667108..4f64b95 100644
--- a/fs/afs/Makefile
+++ b/fs/afs/Makefile
@@ -2,7 +2,10 @@
 # Makefile for Red Hat Linux AFS client.
 #
 
+afs-cache-$(CONFIG_AFS_FSCACHE) := cache.o
+
 kafs-objs := \
+	$(afs-cache-y) \
 	callback.o \
 	cell.o \
 	cmservice.o \
diff --git a/fs/afs/cache.c b/fs/afs/cache.c
index de0d7de..e2b1d3f 100644
--- a/fs/afs/cache.c
+++ b/fs/afs/cache.c
@@ -1,6 +1,6 @@
 /* AFS caching stuff
  *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
  * Written by David Howells (dhowells@redhat.com)
  *
  * This program is free software; you can redistribute it and/or
@@ -9,248 +9,395 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-#ifdef AFS_CACHING_SUPPORT
-static cachefs_match_val_t afs_cell_cache_match(void *target,
-						const void *entry);
-static void afs_cell_cache_update(void *source, void *entry);
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include "internal.h"
 
-struct cachefs_index_def afs_cache_cell_index_def = {
-	.name			= "cell_ix",
-	.data_size		= sizeof(struct afs_cache_cell),
-	.keys[0]		= { CACHEFS_INDEX_KEYS_ASCIIZ, 64 },
-	.match			= afs_cell_cache_match,
-	.update			= afs_cell_cache_update,
+static uint16_t afs_cell_cache_get_key(const void *cookie_netfs_data,
+				       void *buffer, uint16_t buflen);
+static uint16_t afs_cell_cache_get_aux(const void *cookie_netfs_data,
+				       void *buffer, uint16_t buflen);
+static enum fscache_checkaux afs_cell_cache_check_aux(void *cookie_netfs_data,
+						      const void *buffer,
+						      uint16_t buflen);
+
+static uint16_t afs_vlocation_cache_get_key(const void *cookie_netfs_data,
+					    void *buffer, uint16_t buflen);
+static uint16_t afs_vlocation_cache_get_aux(const void *cookie_netfs_data,
+					    void *buffer, uint16_t buflen);
+static enum fscache_checkaux afs_vlocation_cache_check_aux(
+	void *cookie_netfs_data, const void *buffer, uint16_t buflen);
+
+static uint16_t afs_volume_cache_get_key(const void *cookie_netfs_data,
+					 void *buffer, uint16_t buflen);
+
+static uint16_t afs_vnode_cache_get_key(const void *cookie_netfs_data,
+					void *buffer, uint16_t buflen);
+static void afs_vnode_cache_get_attr(const void *cookie_netfs_data,
+				     uint64_t *size);
+static uint16_t afs_vnode_cache_get_aux(const void *cookie_netfs_data,
+					void *buffer, uint16_t buflen);
+static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data,
+						       const void *buffer,
+						       uint16_t buflen);
+static void afs_vnode_cache_now_uncached(void *cookie_netfs_data);
+
+struct fscache_netfs afs_cache_netfs = {
+	.name			= "afs",
+	.version		= 0,
 };
-#endif
+
+struct fscache_cookie_def afs_cell_cache_index_def = {
+	.name		= "AFS.cell",
+	.type		= FSCACHE_COOKIE_TYPE_INDEX,
+	.get_key	= afs_cell_cache_get_key,
+	.get_aux	= afs_cell_cache_get_aux,
+	.check_aux	= afs_cell_cache_check_aux,
+};
+
+struct fscache_cookie_def afs_vlocation_cache_index_def = {
+	.name			= "AFS.vldb",
+	.type			= FSCACHE_COOKIE_TYPE_INDEX,
+	.get_key		= afs_vlocation_cache_get_key,
+	.get_aux		= afs_vlocation_cache_get_aux,
+	.check_aux		= afs_vlocation_cache_check_aux,
+};
+
+struct fscache_cookie_def afs_volume_cache_index_def = {
+	.name		= "AFS.volume",
+	.type		= FSCACHE_COOKIE_TYPE_INDEX,
+	.get_key	= afs_volume_cache_get_key,
+};
+
+struct fscache_cookie_def afs_vnode_cache_index_def = {
+	.name			= "AFS.vnode",
+	.type			= FSCACHE_COOKIE_TYPE_DATAFILE,
+	.get_key		= afs_vnode_cache_get_key,
+	.get_attr		= afs_vnode_cache_get_attr,
+	.get_aux		= afs_vnode_cache_get_aux,
+	.check_aux		= afs_vnode_cache_check_aux,
+	.now_uncached		= afs_vnode_cache_now_uncached,
+};
 
 /*
- * match a cell record obtained from the cache
+ * set the key for the index entry
  */
-#ifdef AFS_CACHING_SUPPORT
-static cachefs_match_val_t afs_cell_cache_match(void *target,
-						const void *entry)
+static uint16_t afs_cell_cache_get_key(const void *cookie_netfs_data,
+				       void *buffer, uint16_t bufmax)
 {
-	const struct afs_cache_cell *ccell = entry;
-	struct afs_cell *cell = target;
+	const struct afs_cell *cell = cookie_netfs_data;
+	uint16_t klen;
 
-	_enter("{%s},{%s}", ccell->name, cell->name);
+	_enter("%p,%p,%u", cell, buffer, bufmax);
 
-	if (strncmp(ccell->name, cell->name, sizeof(ccell->name)) == 0) {
-		_leave(" = SUCCESS");
-		return CACHEFS_MATCH_SUCCESS;
+	klen = strlen(cell->name);
+	if (klen > bufmax)
+		return 0;
+
+	memcpy(buffer, cell->name, klen);
+	return klen;
+}
+
+/*
+ * provide new auxilliary cache data
+ */
+static uint16_t afs_cell_cache_get_aux(const void *cookie_netfs_data,
+				       void *buffer, uint16_t bufmax)
+{
+	const struct afs_cell *cell = cookie_netfs_data;
+	uint16_t dlen;
+
+	_enter("%p,%p,%u", cell, buffer, bufmax);
+
+	dlen = cell->vl_naddrs * sizeof(cell->vl_addrs[0]);
+	dlen = min(dlen, bufmax);
+	dlen &= ~(sizeof(cell->vl_addrs[0]) - 1);
+
+	memcpy(buffer, cell->vl_addrs, dlen);
+	return dlen;
+}
+
+/*
+ * check that the auxilliary data indicates that the entry is still valid
+ */
+static enum fscache_checkaux afs_cell_cache_check_aux(void *cookie_netfs_data,
+						      const void *buffer,
+						      uint16_t buflen)
+{
+	_leave(" = OKAY");
+	return FSCACHE_CHECKAUX_OKAY;
+}
+
+/*****************************************************************************/
+/*
+ * set the key for the index entry
+ */
+static uint16_t afs_vlocation_cache_get_key(const void *cookie_netfs_data,
+					    void *buffer, uint16_t bufmax)
+{
+	const struct afs_vlocation *vlocation = cookie_netfs_data;
+	uint16_t klen;
+
+	_enter("{%s},%p,%u", vlocation->vldb.name, buffer, bufmax);
+
+	klen = strnlen(vlocation->vldb.name, sizeof(vlocation->vldb.name));
+	if (klen > bufmax)
+		return 0;
+
+	memcpy(buffer, vlocation->vldb.name, klen);
+
+	_leave(" = %u", klen);
+	return klen;
+}
+
+/*
+ * provide new auxilliary cache data
+ */
+static uint16_t afs_vlocation_cache_get_aux(const void *cookie_netfs_data,
+					    void *buffer, uint16_t bufmax)
+{
+	const struct afs_vlocation *vlocation = cookie_netfs_data;
+	uint16_t dlen;
+
+	_enter("{%s},%p,%u", vlocation->vldb.name, buffer, bufmax);
+
+	dlen = sizeof(struct afs_cache_vlocation);
+	dlen -= offsetof(struct afs_cache_vlocation, nservers);
+	if (dlen > bufmax)
+		return 0;
+
+	memcpy(buffer, (uint8_t *)&vlocation->vldb.nservers, dlen);
+
+	_leave(" = %u", dlen);
+	return dlen;
+}
+
+/*
+ * check that the auxilliary data indicates that the entry is still valid
+ */
+static
+enum fscache_checkaux afs_vlocation_cache_check_aux(void *cookie_netfs_data,
+						    const void *buffer,
+						    uint16_t buflen)
+{
+	const struct afs_cache_vlocation *cvldb;
+	struct afs_vlocation *vlocation = cookie_netfs_data;
+	uint16_t dlen;
+
+	_enter("{%s},%p,%u", vlocation->vldb.name, buffer, buflen);
+
+	/* check the size of the data is what we're expecting */
+	dlen = sizeof(struct afs_cache_vlocation);
+	dlen -= offsetof(struct afs_cache_vlocation, nservers);
+	if (dlen != buflen)
+		return FSCACHE_CHECKAUX_OBSOLETE;
+
+	cvldb = container_of(buffer, struct afs_cache_vlocation, nservers);
+
+	/* if what's on disk is more valid than what's in memory, then use the
+	 * VL record from the cache */
+	if (!vlocation->valid || vlocation->vldb.rtime == cvldb->rtime) {
+		memcpy((uint8_t *)&vlocation->vldb.nservers, buffer, dlen);
+		vlocation->valid = 1;
+		_leave(" = SUCCESS [c->m]");
+		return FSCACHE_CHECKAUX_OKAY;
 	}
 
-	_leave(" = FAILED");
-	return CACHEFS_MATCH_FAILED;
-}
-#endif
-
-/*
- * update a cell record in the cache
- */
-#ifdef AFS_CACHING_SUPPORT
-static void afs_cell_cache_update(void *source, void *entry)
-{
-	struct afs_cache_cell *ccell = entry;
-	struct afs_cell *cell = source;
-
-	_enter("%p,%p", source, entry);
-
-	strncpy(ccell->name, cell->name, sizeof(ccell->name));
-
-	memcpy(ccell->vl_servers,
-	       cell->vl_addrs,
-	       min(sizeof(ccell->vl_servers), sizeof(cell->vl_addrs)));
-
-}
-#endif
-
-#ifdef AFS_CACHING_SUPPORT
-static cachefs_match_val_t afs_vlocation_cache_match(void *target,
-						     const void *entry);
-static void afs_vlocation_cache_update(void *source, void *entry);
-
-struct cachefs_index_def afs_vlocation_cache_index_def = {
-	.name		= "vldb",
-	.data_size	= sizeof(struct afs_cache_vlocation),
-	.keys[0]	= { CACHEFS_INDEX_KEYS_ASCIIZ, 64 },
-	.match		= afs_vlocation_cache_match,
-	.update		= afs_vlocation_cache_update,
-};
-#endif
-
-/*
- * match a VLDB record stored in the cache
- * - may also load target from entry
- */
-#ifdef AFS_CACHING_SUPPORT
-static cachefs_match_val_t afs_vlocation_cache_match(void *target,
-						     const void *entry)
-{
-	const struct afs_cache_vlocation *vldb = entry;
-	struct afs_vlocation *vlocation = target;
-
-	_enter("{%s},{%s}", vlocation->vldb.name, vldb->name);
-
-	if (strncmp(vlocation->vldb.name, vldb->name, sizeof(vldb->name)) == 0
-	    ) {
-		if (!vlocation->valid ||
-		    vlocation->vldb.rtime == vldb->rtime
+	/* need to update the cache if the cached info differs */
+	if (memcmp(&vlocation->vldb, buffer, dlen) != 0) {
+		/* delete if the volume IDs for this name differ */
+		if (memcmp(&vlocation->vldb.vid, &cvldb->vid,
+			   sizeof(cvldb->vid)) != 0
 		    ) {
-			vlocation->vldb = *vldb;
-			vlocation->valid = 1;
-			_leave(" = SUCCESS [c->m]");
-			return CACHEFS_MATCH_SUCCESS;
-		} else if (memcmp(&vlocation->vldb, vldb, sizeof(*vldb)) != 0) {
-			/* delete if VIDs for this name differ */
-			if (memcmp(&vlocation->vldb.vid,
-				   &vldb->vid,
-				   sizeof(vldb->vid)) != 0) {
-				_leave(" = DELETE");
-				return CACHEFS_MATCH_SUCCESS_DELETE;
-			}
-
-			_leave(" = UPDATE");
-			return CACHEFS_MATCH_SUCCESS_UPDATE;
-		} else {
-			_leave(" = SUCCESS");
-			return CACHEFS_MATCH_SUCCESS;
+			_leave(" = OBSOLETE");
+			return FSCACHE_CHECKAUX_OBSOLETE;
 		}
+
+		_leave(" = UPDATE");
+		return FSCACHE_CHECKAUX_NEEDS_UPDATE;
 	}
 
-	_leave(" = FAILED");
-	return CACHEFS_MATCH_FAILED;
+	_leave(" = OKAY");
+	return FSCACHE_CHECKAUX_OKAY;
 }
-#endif
+
+/*****************************************************************************/
+/*
+ * set the key for the volume index entry
+ */
+static uint16_t afs_volume_cache_get_key(const void *cookie_netfs_data,
+					void *buffer, uint16_t bufmax)
+{
+	const struct afs_volume *volume = cookie_netfs_data;
+	uint16_t klen;
+
+	_enter("{%u},%p,%u", volume->type, buffer, bufmax);
+
+	klen = sizeof(volume->type);
+	if (klen > bufmax)
+		return 0;
+
+	memcpy(buffer, &volume->type, sizeof(volume->type));
+
+	_leave(" = %u", klen);
+	return klen;
+
+}
+
+/*****************************************************************************/
+/*
+ * set the key for the index entry
+ */
+static uint16_t afs_vnode_cache_get_key(const void *cookie_netfs_data,
+					void *buffer, uint16_t bufmax)
+{
+	const struct afs_vnode *vnode = cookie_netfs_data;
+	uint16_t klen;
+
+	_enter("{%x,%x,%llx},%p,%u",
+	       vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version,
+	       buffer, bufmax);
+
+	klen = sizeof(vnode->fid.vnode);
+	if (klen > bufmax)
+		return 0;
+
+	memcpy(buffer, &vnode->fid.vnode, sizeof(vnode->fid.vnode));
+
+	_leave(" = %u", klen);
+	return klen;
+}
 
 /*
- * update a VLDB record stored in the cache
+ * provide updated file attributes
  */
-#ifdef AFS_CACHING_SUPPORT
-static void afs_vlocation_cache_update(void *source, void *entry)
+static void afs_vnode_cache_get_attr(const void *cookie_netfs_data,
+				     uint64_t *size)
 {
-	struct afs_cache_vlocation *vldb = entry;
-	struct afs_vlocation *vlocation = source;
+	const struct afs_vnode *vnode = cookie_netfs_data;
 
-	_enter("");
+	_enter("{%x,%x,%llx},",
+	       vnode->fid.vnode, vnode->fid.unique,
+	       vnode->status.data_version);
 
-	*vldb = vlocation->vldb;
+	*size = vnode->status.size;
 }
-#endif
-
-#ifdef AFS_CACHING_SUPPORT
-static cachefs_match_val_t afs_volume_cache_match(void *target,
-						  const void *entry);
-static void afs_volume_cache_update(void *source, void *entry);
-
-struct cachefs_index_def afs_volume_cache_index_def = {
-	.name		= "volume",
-	.data_size	= sizeof(struct afs_cache_vhash),
-	.keys[0]	= { CACHEFS_INDEX_KEYS_BIN, 1 },
-	.keys[1]	= { CACHEFS_INDEX_KEYS_BIN, 1 },
-	.match		= afs_volume_cache_match,
-	.update		= afs_volume_cache_update,
-};
-#endif
 
 /*
- * match a volume hash record stored in the cache
+ * provide new auxilliary cache data
  */
-#ifdef AFS_CACHING_SUPPORT
-static cachefs_match_val_t afs_volume_cache_match(void *target,
-						  const void *entry)
+static uint16_t afs_vnode_cache_get_aux(const void *cookie_netfs_data,
+					void *buffer, uint16_t bufmax)
 {
-	const struct afs_cache_vhash *vhash = entry;
-	struct afs_volume *volume = target;
+	const struct afs_vnode *vnode = cookie_netfs_data;
+	uint16_t dlen;
 
-	_enter("{%u},{%u}", volume->type, vhash->vtype);
+	_enter("{%x,%x,%Lx},%p,%u",
+	       vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version,
+	       buffer, bufmax);
 
-	if (volume->type == vhash->vtype) {
-		_leave(" = SUCCESS");
-		return CACHEFS_MATCH_SUCCESS;
+	dlen = sizeof(vnode->fid.unique) + sizeof(vnode->status.data_version);
+	if (dlen > bufmax)
+		return 0;
+
+	memcpy(buffer, &vnode->fid.unique, sizeof(vnode->fid.unique));
+	buffer += sizeof(vnode->fid.unique);
+	memcpy(buffer, &vnode->status.data_version,
+	       sizeof(vnode->status.data_version));
+
+	_leave(" = %u", dlen);
+	return dlen;
+}
+
+/*
+ * check that the auxilliary data indicates that the entry is still valid
+ */
+static enum fscache_checkaux afs_vnode_cache_check_aux(void *cookie_netfs_data,
+						       const void *buffer,
+						       uint16_t buflen)
+{
+	struct afs_vnode *vnode = cookie_netfs_data;
+	uint16_t dlen;
+
+	_enter("{%x,%x,%llx},%p,%u",
+	       vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version,
+	       buffer, buflen);
+
+	/* check the size of the data is what we're expecting */
+	dlen = sizeof(vnode->fid.unique) + sizeof(vnode->status.data_version);
+	if (dlen != buflen) {
+		_leave(" = OBSOLETE [len %hx != %hx]", dlen, buflen);
+		return FSCACHE_CHECKAUX_OBSOLETE;
 	}
 
-	_leave(" = FAILED");
-	return CACHEFS_MATCH_FAILED;
-}
-#endif
+	if (memcmp(buffer,
+		   &vnode->fid.unique,
+		   sizeof(vnode->fid.unique)
+		   ) != 0) {
+		unsigned unique;
 
-/*
- * update a volume hash record stored in the cache
- */
-#ifdef AFS_CACHING_SUPPORT
-static void afs_volume_cache_update(void *source, void *entry)
-{
-	struct afs_cache_vhash *vhash = entry;
-	struct afs_volume *volume = source;
+		memcpy(&unique, buffer, sizeof(unique));
 
-	_enter("");
-
-	vhash->vtype = volume->type;
-}
-#endif
-
-#ifdef AFS_CACHING_SUPPORT
-static cachefs_match_val_t afs_vnode_cache_match(void *target,
-						 const void *entry);
-static void afs_vnode_cache_update(void *source, void *entry);
-
-struct cachefs_index_def afs_vnode_cache_index_def = {
-	.name		= "vnode",
-	.data_size	= sizeof(struct afs_cache_vnode),
-	.keys[0]	= { CACHEFS_INDEX_KEYS_BIN, 4 },
-	.match		= afs_vnode_cache_match,
-	.update		= afs_vnode_cache_update,
-};
-#endif
-
-/*
- * match a vnode record stored in the cache
- */
-#ifdef AFS_CACHING_SUPPORT
-static cachefs_match_val_t afs_vnode_cache_match(void *target,
-						 const void *entry)
-{
-	const struct afs_cache_vnode *cvnode = entry;
-	struct afs_vnode *vnode = target;
-
-	_enter("{%x,%x,%Lx},{%x,%x,%Lx}",
-	       vnode->fid.vnode,
-	       vnode->fid.unique,
-	       vnode->status.version,
-	       cvnode->vnode_id,
-	       cvnode->vnode_unique,
-	       cvnode->data_version);
-
-	if (vnode->fid.vnode != cvnode->vnode_id) {
-		_leave(" = FAILED");
-		return CACHEFS_MATCH_FAILED;
+		_leave(" = OBSOLETE [uniq %x != %x]",
+		       unique, vnode->fid.unique);
+		return FSCACHE_CHECKAUX_OBSOLETE;
 	}
 
-	if (vnode->fid.unique != cvnode->vnode_unique ||
-	    vnode->status.version != cvnode->data_version) {
-		_leave(" = DELETE");
-		return CACHEFS_MATCH_SUCCESS_DELETE;
+	if (memcmp(buffer + sizeof(vnode->fid.unique),
+		   &vnode->status.data_version,
+		   sizeof(vnode->status.data_version)
+		   ) != 0) {
+		afs_dataversion_t version;
+
+		memcpy(&version, buffer + sizeof(vnode->fid.unique),
+		       sizeof(version));
+
+		_leave(" = OBSOLETE [vers %llx != %llx]",
+		       version, vnode->status.data_version);
+		return FSCACHE_CHECKAUX_OBSOLETE;
 	}
 
 	_leave(" = SUCCESS");
-	return CACHEFS_MATCH_SUCCESS;
+	return FSCACHE_CHECKAUX_OKAY;
 }
-#endif
 
 /*
- * update a vnode record stored in the cache
+ * indication the cookie is no longer uncached
+ * - this function is called when the backing store currently caching a cookie
+ *   is removed
+ * - the netfs should use this to clean up any markers indicating cached pages
+ * - this is mandatory for any object that may have data
  */
-#ifdef AFS_CACHING_SUPPORT
-static void afs_vnode_cache_update(void *source, void *entry)
+static void afs_vnode_cache_now_uncached(void *cookie_netfs_data)
 {
-	struct afs_cache_vnode *cvnode = entry;
-	struct afs_vnode *vnode = source;
+	struct afs_vnode *vnode = cookie_netfs_data;
+	struct pagevec pvec;
+	pgoff_t first;
+	int loop, nr_pages;
 
-	_enter("");
+	_enter("{%x,%x,%Lx}",
+	       vnode->fid.vnode, vnode->fid.unique, vnode->status.data_version);
 
-	cvnode->vnode_id	= vnode->fid.vnode;
-	cvnode->vnode_unique	= vnode->fid.unique;
-	cvnode->data_version	= vnode->status.version;
+	pagevec_init(&pvec, 0);
+	first = 0;
+
+	for (;;) {
+		/* grab a bunch of pages to clean */
+		nr_pages = pagevec_lookup(&pvec, vnode->vfs_inode.i_mapping,
+					  first,
+					  PAGEVEC_SIZE - pagevec_count(&pvec));
+		if (!nr_pages)
+			break;
+
+		for (loop = 0; loop < nr_pages; loop++)
+			ClearPageFsCache(pvec.pages[loop]);
+
+		first = pvec.pages[nr_pages - 1]->index + 1;
+
+		pvec.nr = nr_pages;
+		pagevec_release(&pvec);
+		cond_resched();
+	}
+
+	_leave("");
 }
-#endif
diff --git a/fs/afs/cache.h b/fs/afs/cache.h
index 36a3642..5c4f6b4 100644
--- a/fs/afs/cache.h
+++ b/fs/afs/cache.h
@@ -1,6 +1,6 @@
 /* AFS local cache management interface
  *
- * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
  * Written by David Howells (dhowells@redhat.com)
  *
  * This program is free software; you can redistribute it and/or
@@ -9,15 +9,4 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-#ifndef AFS_CACHE_H
-#define AFS_CACHE_H
-
-#undef AFS_CACHING_SUPPORT
-
-#include <linux/mm.h>
-#ifdef AFS_CACHING_SUPPORT
-#include <linux/cachefs.h>
-#endif
-#include "types.h"
-
-#endif /* AFS_CACHE_H */
+#include <linux/fscache.h>
diff --git a/fs/afs/cell.c b/fs/afs/cell.c
index 5e1df14..e19c13f 100644
--- a/fs/afs/cell.c
+++ b/fs/afs/cell.c
@@ -147,12 +147,11 @@
 	if (ret < 0)
 		goto error;
 
-#ifdef AFS_CACHING_SUPPORT
-	/* put it up for caching */
-	cachefs_acquire_cookie(afs_cache_netfs.primary_index,
-			       &afs_vlocation_cache_index_def,
-			       cell,
-			       &cell->cache);
+#ifdef CONFIG_AFS_FSCACHE
+	/* put it up for caching (this never returns an error) */
+	cell->cache = fscache_acquire_cookie(afs_cache_netfs.primary_index,
+					     &afs_cell_cache_index_def,
+					     cell);
 #endif
 
 	/* add to the cell lists */
@@ -362,10 +361,9 @@
 	list_del_init(&cell->proc_link);
 	up_write(&afs_proc_cells_sem);
 
-#ifdef AFS_CACHING_SUPPORT
-	cachefs_relinquish_cookie(cell->cache, 0);
+#ifdef CONFIG_AFS_FSCACHE
+	fscache_relinquish_cookie(cell->cache, 0);
 #endif
-
 	key_put(cell->anonymous_key);
 	kfree(cell);
 
diff --git a/fs/afs/file.c b/fs/afs/file.c
index a390176..7a1d942 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -23,6 +23,9 @@
 static int afs_releasepage(struct page *page, gfp_t gfp_flags);
 static int afs_launder_page(struct page *page);
 
+static int afs_readpages(struct file *filp, struct address_space *mapping,
+			 struct list_head *pages, unsigned nr_pages);
+
 const struct file_operations afs_file_operations = {
 	.open		= afs_open,
 	.release	= afs_release,
@@ -46,6 +49,7 @@
 
 const struct address_space_operations afs_fs_aops = {
 	.readpage	= afs_readpage,
+	.readpages	= afs_readpages,
 	.set_page_dirty	= afs_set_page_dirty,
 	.launder_page	= afs_launder_page,
 	.releasepage	= afs_releasepage,
@@ -101,37 +105,18 @@
 /*
  * deal with notification that a page was read from the cache
  */
-#ifdef AFS_CACHING_SUPPORT
-static void afs_readpage_read_complete(void *cookie_data,
-				       struct page *page,
-				       void *data,
-				       int error)
+static void afs_file_readpage_read_complete(struct page *page,
+					    void *data,
+					    int error)
 {
-	_enter("%p,%p,%p,%d", cookie_data, page, data, error);
+	_enter("%p,%p,%d", page, data, error);
 
-	if (error)
-		SetPageError(page);
-	else
+	/* if the read completes with an error, we just unlock the page and let
+	 * the VM reissue the readpage */
+	if (!error)
 		SetPageUptodate(page);
 	unlock_page(page);
-
 }
-#endif
-
-/*
- * deal with notification that a page was written to the cache
- */
-#ifdef AFS_CACHING_SUPPORT
-static void afs_readpage_write_complete(void *cookie_data,
-					struct page *page,
-					void *data,
-					int error)
-{
-	_enter("%p,%p,%p,%d", cookie_data, page, data, error);
-
-	unlock_page(page);
-}
-#endif
 
 /*
  * AFS read page from file, directory or symlink
@@ -161,9 +146,9 @@
 	if (test_bit(AFS_VNODE_DELETED, &vnode->flags))
 		goto error;
 
-#ifdef AFS_CACHING_SUPPORT
 	/* is it cached? */
-	ret = cachefs_read_or_alloc_page(vnode->cache,
+#ifdef CONFIG_AFS_FSCACHE
+	ret = fscache_read_or_alloc_page(vnode->cache,
 					 page,
 					 afs_file_readpage_read_complete,
 					 NULL,
@@ -171,20 +156,21 @@
 #else
 	ret = -ENOBUFS;
 #endif
-
 	switch (ret) {
-		/* read BIO submitted and wb-journal entry found */
-	case 1:
-		BUG(); // TODO - handle wb-journal match
-
 		/* read BIO submitted (page in cache) */
 	case 0:
 		break;
 
-		/* no page available in cache */
-	case -ENOBUFS:
+		/* page not yet cached */
 	case -ENODATA:
+		_debug("cache said ENODATA");
+		goto go_on;
+
+		/* page will not be cached */
+	case -ENOBUFS:
+		_debug("cache said ENOBUFS");
 	default:
+	go_on:
 		offset = page->index << PAGE_CACHE_SHIFT;
 		len = min_t(size_t, i_size_read(inode) - offset, PAGE_SIZE);
 
@@ -198,27 +184,25 @@
 				set_bit(AFS_VNODE_DELETED, &vnode->flags);
 				ret = -ESTALE;
 			}
-#ifdef AFS_CACHING_SUPPORT
-			cachefs_uncache_page(vnode->cache, page);
+
+#ifdef CONFIG_AFS_FSCACHE
+			fscache_uncache_page(vnode->cache, page);
 #endif
+			BUG_ON(PageFsCache(page));
 			goto error;
 		}
 
 		SetPageUptodate(page);
 
-#ifdef AFS_CACHING_SUPPORT
-		if (cachefs_write_page(vnode->cache,
-				       page,
-				       afs_file_readpage_write_complete,
-				       NULL,
-				       GFP_KERNEL) != 0
-		    ) {
-			cachefs_uncache_page(vnode->cache, page);
-			unlock_page(page);
+		/* send the page to the cache */
+#ifdef CONFIG_AFS_FSCACHE
+		if (PageFsCache(page) &&
+		    fscache_write_page(vnode->cache, page, GFP_KERNEL) != 0) {
+			fscache_uncache_page(vnode->cache, page);
+			BUG_ON(PageFsCache(page));
 		}
-#else
-		unlock_page(page);
 #endif
+		unlock_page(page);
 	}
 
 	_leave(" = 0");
@@ -232,34 +216,59 @@
 }
 
 /*
- * invalidate part or all of a page
+ * read a set of pages
  */
-static void afs_invalidatepage(struct page *page, unsigned long offset)
+static int afs_readpages(struct file *file, struct address_space *mapping,
+			 struct list_head *pages, unsigned nr_pages)
 {
-	int ret = 1;
+	struct afs_vnode *vnode;
+	int ret = 0;
 
-	_enter("{%lu},%lu", page->index, offset);
+	_enter(",{%lu},,%d", mapping->host->i_ino, nr_pages);
 
-	BUG_ON(!PageLocked(page));
-
-	if (PagePrivate(page)) {
-		/* We release buffers only if the entire page is being
-		 * invalidated.
-		 * The get_block cached value has been unconditionally
-		 * invalidated, so real IO is not possible anymore.
-		 */
-		if (offset == 0) {
-			BUG_ON(!PageLocked(page));
-
-			ret = 0;
-			if (!PageWriteback(page))
-				ret = page->mapping->a_ops->releasepage(page,
-									0);
-			/* possibly should BUG_ON(!ret); - neilb */
-		}
+	vnode = AFS_FS_I(mapping->host);
+	if (vnode->flags & AFS_VNODE_DELETED) {
+		_leave(" = -ESTALE");
+		return -ESTALE;
 	}
 
-	_leave(" = %d", ret);
+	/* attempt to read as many of the pages as possible */
+#ifdef CONFIG_AFS_FSCACHE
+	ret = fscache_read_or_alloc_pages(vnode->cache,
+					  mapping,
+					  pages,
+					  &nr_pages,
+					  afs_file_readpage_read_complete,
+					  NULL,
+					  mapping_gfp_mask(mapping));
+#else
+	ret = -ENOBUFS;
+#endif
+
+	switch (ret) {
+		/* all pages are being read from the cache */
+	case 0:
+		BUG_ON(!list_empty(pages));
+		BUG_ON(nr_pages != 0);
+		_leave(" = 0 [reading all]");
+		return 0;
+
+		/* there were pages that couldn't be read from the cache */
+	case -ENODATA:
+	case -ENOBUFS:
+		break;
+
+		/* other error */
+	default:
+		_leave(" = %d", ret);
+		return ret;
+	}
+
+	/* load the missing pages from the network */
+	ret = read_cache_pages(mapping, pages, (void *) afs_readpage, file);
+
+	_leave(" = %d [netting]", ret);
+	return ret;
 }
 
 /*
@@ -273,25 +282,82 @@
 }
 
 /*
- * release a page and cleanup its private data
+ * invalidate part or all of a page
+ * - release a page and clean up its private data if offset is 0 (indicating
+ *   the entire page)
+ */
+static void afs_invalidatepage(struct page *page, unsigned long offset)
+{
+	struct afs_writeback *wb = (struct afs_writeback *) page_private(page);
+
+	_enter("{%lu},%lu", page->index, offset);
+
+	BUG_ON(!PageLocked(page));
+
+	/* we clean up only if the entire page is being invalidated */
+	if (offset == 0) {
+#ifdef CONFIG_AFS_FSCACHE
+		if (PageFsCache(page)) {
+			struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
+			fscache_wait_on_page_write(vnode->cache, page);
+			fscache_uncache_page(vnode->cache, page);
+			ClearPageFsCache(page);
+		}
+#endif
+
+		if (PagePrivate(page)) {
+			if (wb && !PageWriteback(page)) {
+				set_page_private(page, 0);
+				afs_put_writeback(wb);
+			}
+
+			if (!page_private(page))
+				ClearPagePrivate(page);
+		}
+	}
+
+	_leave("");
+}
+
+/*
+ * release a page and clean up its private state if it's not busy
+ * - return true if the page can now be released, false if not
  */
 static int afs_releasepage(struct page *page, gfp_t gfp_flags)
 {
+	struct afs_writeback *wb = (struct afs_writeback *) page_private(page);
 	struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
-	struct afs_writeback *wb;
 
 	_enter("{{%x:%u}[%lu],%lx},%x",
 	       vnode->fid.vid, vnode->fid.vnode, page->index, page->flags,
 	       gfp_flags);
 
+	/* deny if page is being written to the cache and the caller hasn't
+	 * elected to wait */
+#ifdef CONFIG_AFS_FSCACHE
+	if (PageFsCache(page)) {
+		if (fscache_check_page_write(vnode->cache, page)) {
+			if (!(gfp_flags & __GFP_WAIT)) {
+				_leave(" = F [cache busy]");
+				return 0;
+			}
+			fscache_wait_on_page_write(vnode->cache, page);
+		}
+
+		fscache_uncache_page(vnode->cache, page);
+		ClearPageFsCache(page);
+	}
+#endif
+
 	if (PagePrivate(page)) {
-		wb = (struct afs_writeback *) page_private(page);
-		ASSERT(wb != NULL);
-		set_page_private(page, 0);
+		if (wb) {
+			set_page_private(page, 0);
+			afs_put_writeback(wb);
+		}
 		ClearPagePrivate(page);
-		afs_put_writeback(wb);
 	}
 
-	_leave(" = 0");
-	return 0;
+	/* indicate that the page can be released */
+	_leave(" = T");
+	return 1;
 }
diff --git a/fs/afs/inode.c b/fs/afs/inode.c
index bb47217..c048f06 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
@@ -61,6 +61,11 @@
 		return -EBADMSG;
 	}
 
+#ifdef CONFIG_AFS_FSCACHE
+	if (vnode->status.size != inode->i_size)
+		fscache_attr_changed(vnode->cache);
+#endif
+
 	inode->i_nlink		= vnode->status.nlink;
 	inode->i_uid		= vnode->status.owner;
 	inode->i_gid		= 0;
@@ -149,15 +154,6 @@
 		return inode;
 	}
 
-#ifdef AFS_CACHING_SUPPORT
-	/* set up caching before reading the status, as fetch-status reads the
-	 * first page of symlinks to see if they're really mntpts */
-	cachefs_acquire_cookie(vnode->volume->cache,
-			       NULL,
-			       vnode,
-			       &vnode->cache);
-#endif
-
 	if (!status) {
 		/* it's a remotely extant inode */
 		set_bit(AFS_VNODE_CB_BROKEN, &vnode->flags);
@@ -183,6 +179,15 @@
 		}
 	}
 
+	/* set up caching before mapping the status, as map-status reads the
+	 * first page of symlinks to see if they're really mountpoints */
+	inode->i_size = vnode->status.size;
+#ifdef CONFIG_AFS_FSCACHE
+	vnode->cache = fscache_acquire_cookie(vnode->volume->cache,
+					      &afs_vnode_cache_index_def,
+					      vnode);
+#endif
+
 	ret = afs_inode_map_status(vnode, key);
 	if (ret < 0)
 		goto bad_inode;
@@ -196,6 +201,10 @@
 
 	/* failure */
 bad_inode:
+#ifdef CONFIG_AFS_FSCACHE
+	fscache_relinquish_cookie(vnode->cache, 0);
+	vnode->cache = NULL;
+#endif
 	iget_failed(inode);
 	_leave(" = %d [bad]", ret);
 	return ERR_PTR(ret);
@@ -340,8 +349,8 @@
 	ASSERT(list_empty(&vnode->writebacks));
 	ASSERT(!vnode->cb_promised);
 
-#ifdef AFS_CACHING_SUPPORT
-	cachefs_relinquish_cookie(vnode->cache, 0);
+#ifdef CONFIG_AFS_FSCACHE
+	fscache_relinquish_cookie(vnode->cache, 0);
 	vnode->cache = NULL;
 #endif
 
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index 67f259d..106be66 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -21,6 +21,7 @@
 
 #include "afs.h"
 #include "afs_vl.h"
+#include "cache.h"
 
 #define AFS_CELL_MAX_ADDRS 15
 
@@ -193,8 +194,8 @@
 	struct key		*anonymous_key;	/* anonymous user key for this cell */
 	struct list_head	proc_link;	/* /proc cell list link */
 	struct proc_dir_entry	*proc_dir;	/* /proc dir for this cell */
-#ifdef AFS_CACHING_SUPPORT
-	struct cachefs_cookie	*cache;		/* caching cookie */
+#ifdef CONFIG_AFS_FSCACHE
+	struct fscache_cookie	*cache;		/* caching cookie */
 #endif
 
 	/* server record management */
@@ -249,8 +250,8 @@
 	struct list_head	grave;		/* link in master graveyard list */
 	struct list_head	update;		/* link in master update list */
 	struct afs_cell		*cell;		/* cell to which volume belongs */
-#ifdef AFS_CACHING_SUPPORT
-	struct cachefs_cookie	*cache;		/* caching cookie */
+#ifdef CONFIG_AFS_FSCACHE
+	struct fscache_cookie	*cache;		/* caching cookie */
 #endif
 	struct afs_cache_vlocation vldb;	/* volume information DB record */
 	struct afs_volume	*vols[3];	/* volume access record pointer (index by type) */
@@ -302,8 +303,8 @@
 	atomic_t		usage;
 	struct afs_cell		*cell;		/* cell to which belongs (unrefd ptr) */
 	struct afs_vlocation	*vlocation;	/* volume location */
-#ifdef AFS_CACHING_SUPPORT
-	struct cachefs_cookie	*cache;		/* caching cookie */
+#ifdef CONFIG_AFS_FSCACHE
+	struct fscache_cookie	*cache;		/* caching cookie */
 #endif
 	afs_volid_t		vid;		/* volume ID */
 	afs_voltype_t		type;		/* type of volume */
@@ -333,8 +334,8 @@
 	struct afs_server	*server;	/* server currently supplying this file */
 	struct afs_fid		fid;		/* the file identifier for this inode */
 	struct afs_file_status	status;		/* AFS status info for this file */
-#ifdef AFS_CACHING_SUPPORT
-	struct cachefs_cookie	*cache;		/* caching cookie */
+#ifdef CONFIG_AFS_FSCACHE
+	struct fscache_cookie	*cache;		/* caching cookie */
 #endif
 	struct afs_permits	*permits;	/* cache of permits so far obtained */
 	struct mutex		permits_lock;	/* lock for altering permits list */
@@ -428,6 +429,22 @@
 
 /*****************************************************************************/
 /*
+ * cache.c
+ */
+#ifdef CONFIG_AFS_FSCACHE
+extern struct fscache_netfs afs_cache_netfs;
+extern struct fscache_cookie_def afs_cell_cache_index_def;
+extern struct fscache_cookie_def afs_vlocation_cache_index_def;
+extern struct fscache_cookie_def afs_volume_cache_index_def;
+extern struct fscache_cookie_def afs_vnode_cache_index_def;
+#else
+#define afs_cell_cache_index_def	(*(struct fscache_cookie_def *) NULL)
+#define afs_vlocation_cache_index_def	(*(struct fscache_cookie_def *) NULL)
+#define afs_volume_cache_index_def	(*(struct fscache_cookie_def *) NULL)
+#define afs_vnode_cache_index_def	(*(struct fscache_cookie_def *) NULL)
+#endif
+
+/*
  * callback.c
  */
 extern void afs_init_callback_state(struct afs_server *);
@@ -446,9 +463,6 @@
  */
 extern struct rw_semaphore afs_proc_cells_sem;
 extern struct list_head afs_proc_cells;
-#ifdef AFS_CACHING_SUPPORT
-extern struct cachefs_index_def afs_cache_cell_index_def;
-#endif
 
 #define afs_get_cell(C) do { atomic_inc(&(C)->usage); } while(0)
 extern int afs_cell_init(char *);
@@ -554,9 +568,6 @@
  * main.c
  */
 extern struct afs_uuid afs_uuid;
-#ifdef AFS_CACHING_SUPPORT
-extern struct cachefs_netfs afs_cache_netfs;
-#endif
 
 /*
  * misc.c
@@ -637,10 +648,6 @@
 /*
  * vlclient.c
  */
-#ifdef AFS_CACHING_SUPPORT
-extern struct cachefs_index_def afs_vlocation_cache_index_def;
-#endif
-
 extern int afs_vl_get_entry_by_name(struct in_addr *, struct key *,
 				    const char *, struct afs_cache_vlocation *,
 				    const struct afs_wait_mode *);
@@ -664,12 +671,6 @@
 /*
  * vnode.c
  */
-#ifdef AFS_CACHING_SUPPORT
-extern struct cachefs_index_def afs_vnode_cache_index_def;
-#endif
-
-extern struct afs_timer_ops afs_vnode_cb_timed_out_ops;
-
 static inline struct afs_vnode *AFS_FS_I(struct inode *inode)
 {
 	return container_of(inode, struct afs_vnode, vfs_inode);
@@ -711,10 +712,6 @@
 /*
  * volume.c
  */
-#ifdef AFS_CACHING_SUPPORT
-extern struct cachefs_index_def afs_volume_cache_index_def;
-#endif
-
 #define afs_get_volume(V) do { atomic_inc(&(V)->usage); } while(0)
 
 extern void afs_put_volume(struct afs_volume *);
diff --git a/fs/afs/main.c b/fs/afs/main.c
index 2d3e5d4..66d54d3 100644
--- a/fs/afs/main.c
+++ b/fs/afs/main.c
@@ -1,6 +1,6 @@
 /* AFS client file system
  *
- * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2002,5 Red Hat, Inc. All Rights Reserved.
  * Written by David Howells (dhowells@redhat.com)
  *
  * This program is free software; you can redistribute it and/or
@@ -29,18 +29,6 @@
 module_param(rootcell, charp, 0);
 MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list");
 
-#ifdef AFS_CACHING_SUPPORT
-static struct cachefs_netfs_operations afs_cache_ops = {
-	.get_page_cookie	= afs_cache_get_page_cookie,
-};
-
-struct cachefs_netfs afs_cache_netfs = {
-	.name			= "afs",
-	.version		= 0,
-	.ops			= &afs_cache_ops,
-};
-#endif
-
 struct afs_uuid afs_uuid;
 
 /*
@@ -104,10 +92,9 @@
 	if (ret < 0)
 		return ret;
 
-#ifdef AFS_CACHING_SUPPORT
+#ifdef CONFIG_AFS_FSCACHE
 	/* we want to be able to cache */
-	ret = cachefs_register_netfs(&afs_cache_netfs,
-				     &afs_cache_cell_index_def);
+	ret = fscache_register_netfs(&afs_cache_netfs);
 	if (ret < 0)
 		goto error_cache;
 #endif
@@ -142,8 +129,8 @@
 error_open_socket:
 error_vl_update_init:
 error_cell_init:
-#ifdef AFS_CACHING_SUPPORT
-	cachefs_unregister_netfs(&afs_cache_netfs);
+#ifdef CONFIG_AFS_FSCACHE
+	fscache_unregister_netfs(&afs_cache_netfs);
 error_cache:
 #endif
 	afs_callback_update_kill();
@@ -175,8 +162,8 @@
 	afs_vlocation_purge();
 	flush_scheduled_work();
 	afs_cell_purge();
-#ifdef AFS_CACHING_SUPPORT
-	cachefs_unregister_netfs(&afs_cache_netfs);
+#ifdef CONFIG_AFS_FSCACHE
+	fscache_unregister_netfs(&afs_cache_netfs);
 #endif
 	afs_proc_cleanup();
 	rcu_barrier();
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c
index 78db495..2b9e2d0 100644
--- a/fs/afs/mntpt.c
+++ b/fs/afs/mntpt.c
@@ -173,9 +173,9 @@
 	if (PageError(page))
 		goto error;
 
-	buf = kmap(page);
+	buf = kmap_atomic(page, KM_USER0);
 	memcpy(devname, buf, size);
-	kunmap(page);
+	kunmap_atomic(buf, KM_USER0);
 	page_cache_release(page);
 	page = NULL;
 
diff --git a/fs/afs/vlocation.c b/fs/afs/vlocation.c
index 849fc31..ec2a743 100644
--- a/fs/afs/vlocation.c
+++ b/fs/afs/vlocation.c
@@ -281,9 +281,8 @@
 
 	vl->vldb = *vldb;
 
-#ifdef AFS_CACHING_SUPPORT
-	/* update volume entry in local cache */
-	cachefs_update_cookie(vl->cache);
+#ifdef CONFIG_AFS_FSCACHE
+	fscache_update_cookie(vl->cache);
 #endif
 }
 
@@ -304,11 +303,9 @@
 	memset(&vldb, 0, sizeof(vldb));
 
 	/* see if we have an in-cache copy (will set vl->valid if there is) */
-#ifdef AFS_CACHING_SUPPORT
-	cachefs_acquire_cookie(cell->cache,
-			       &afs_volume_cache_index_def,
-			       vlocation,
-			       &vl->cache);
+#ifdef CONFIG_AFS_FSCACHE
+	vl->cache = fscache_acquire_cookie(vl->cell->cache,
+					   &afs_vlocation_cache_index_def, vl);
 #endif
 
 	if (vl->valid) {
@@ -420,6 +417,11 @@
 	spin_unlock(&vl->lock);
 	wake_up(&vl->waitq);
 
+	/* update volume entry in local cache */
+#ifdef CONFIG_AFS_FSCACHE
+	fscache_update_cookie(vl->cache);
+#endif
+
 	/* schedule for regular updates */
 	afs_vlocation_queue_for_updates(vl);
 	goto success;
@@ -465,7 +467,7 @@
 	spin_unlock(&vl->lock);
 
 success:
-	_leave(" = %p",vl);
+	_leave(" = %p", vl);
 	return vl;
 
 error_abandon:
@@ -523,10 +525,9 @@
 {
 	_enter("%p", vl);
 
-#ifdef AFS_CACHING_SUPPORT
-	cachefs_relinquish_cookie(vl->cache, 0);
+#ifdef CONFIG_AFS_FSCACHE
+	fscache_relinquish_cookie(vl->cache, 0);
 #endif
-
 	afs_put_cell(vl->cell);
 	kfree(vl);
 }
diff --git a/fs/afs/volume.c b/fs/afs/volume.c
index 8bab0e3..a353e69 100644
--- a/fs/afs/volume.c
+++ b/fs/afs/volume.c
@@ -124,13 +124,11 @@
 	}
 
 	/* attach the cache and volume location */
-#ifdef AFS_CACHING_SUPPORT
-	cachefs_acquire_cookie(vlocation->cache,
-			       &afs_vnode_cache_index_def,
-			       volume,
-			       &volume->cache);
+#ifdef CONFIG_AFS_FSCACHE
+	volume->cache = fscache_acquire_cookie(vlocation->cache,
+					       &afs_volume_cache_index_def,
+					       volume);
 #endif
-
 	afs_get_vlocation(vlocation);
 	volume->vlocation = vlocation;
 
@@ -194,8 +192,8 @@
 	up_write(&vlocation->cell->vl_sem);
 
 	/* finish cleaning up the volume */
-#ifdef AFS_CACHING_SUPPORT
-	cachefs_relinquish_cookie(volume->cache, 0);
+#ifdef CONFIG_AFS_FSCACHE
+	fscache_relinquish_cookie(volume->cache, 0);
 #endif
 	afs_put_vlocation(vlocation);
 
diff --git a/fs/afs/write.c b/fs/afs/write.c
index 3fb36d4..c2e7a7f 100644
--- a/fs/afs/write.c
+++ b/fs/afs/write.c
@@ -780,3 +780,24 @@
 	_leave(" = %d", ret);
 	return ret;
 }
+
+/*
+ * notification that a previously read-only page is about to become writable
+ * - if it returns an error, the caller will deliver a bus error signal
+ */
+int afs_page_mkwrite(struct vm_area_struct *vma, struct page *page)
+{
+	struct afs_vnode *vnode = AFS_FS_I(vma->vm_file->f_mapping->host);
+
+	_enter("{{%x:%u}},{%lx}",
+	       vnode->fid.vid, vnode->fid.vnode, page->index);
+
+	/* wait for the page to be written to the cache before we allow it to
+	 * be modified */
+#ifdef CONFIG_AFS_FSCACHE
+	fscache_wait_on_page_write(vnode->cache, page);
+#endif
+
+	_leave(" = 0");
+	return 0;
+}
diff --git a/fs/bio.c b/fs/bio.c
index a040cde..e0c9e54 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -1420,8 +1420,7 @@
 }
 
 /*
- * split a bio - only worry about a bio with a single page
- * in it's iovec
+ * split a bio - only worry about a bio with a single page in its iovec
  */
 struct bio_pair *bio_split(struct bio *bi, int first_sectors)
 {
diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c
index c84ca1f..51bfdfc 100644
--- a/fs/btrfs/async-thread.c
+++ b/fs/btrfs/async-thread.c
@@ -20,7 +20,6 @@
 #include <linux/list.h>
 #include <linux/spinlock.h>
 #include <linux/freezer.h>
-#include <linux/ftrace.h>
 #include "async-thread.h"
 
 #define WORK_QUEUED_BIT 0
@@ -195,6 +194,9 @@
 				if (!list_empty(&worker->pending))
 					continue;
 
+				if (kthread_should_stop())
+					break;
+
 				/* still no more work?, sleep for real */
 				spin_lock_irq(&worker->lock);
 				set_current_state(TASK_INTERRUPTIBLE);
@@ -208,7 +210,8 @@
 				worker->working = 0;
 				spin_unlock_irq(&worker->lock);
 
-				schedule();
+				if (!kthread_should_stop())
+					schedule();
 			}
 			__set_current_state(TASK_RUNNING);
 		}
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index dbb7241..e5b2533 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -1244,9 +1244,9 @@
  * readahead one full node of leaves, finding things that are close
  * to the block in 'slot', and triggering ra on them.
  */
-static noinline void reada_for_search(struct btrfs_root *root,
-				      struct btrfs_path *path,
-				      int level, int slot, u64 objectid)
+static void reada_for_search(struct btrfs_root *root,
+			     struct btrfs_path *path,
+			     int level, int slot, u64 objectid)
 {
 	struct extent_buffer *node;
 	struct btrfs_disk_key disk_key;
@@ -1447,6 +1447,117 @@
 }
 
 /*
+ * helper function for btrfs_search_slot.  The goal is to find a block
+ * in cache without setting the path to blocking.  If we find the block
+ * we return zero and the path is unchanged.
+ *
+ * If we can't find the block, we set the path blocking and do some
+ * reada.  -EAGAIN is returned and the search must be repeated.
+ */
+static int
+read_block_for_search(struct btrfs_trans_handle *trans,
+		       struct btrfs_root *root, struct btrfs_path *p,
+		       struct extent_buffer **eb_ret, int level, int slot,
+		       struct btrfs_key *key)
+{
+	u64 blocknr;
+	u64 gen;
+	u32 blocksize;
+	struct extent_buffer *b = *eb_ret;
+	struct extent_buffer *tmp;
+
+	blocknr = btrfs_node_blockptr(b, slot);
+	gen = btrfs_node_ptr_generation(b, slot);
+	blocksize = btrfs_level_size(root, level - 1);
+
+	tmp = btrfs_find_tree_block(root, blocknr, blocksize);
+	if (tmp && btrfs_buffer_uptodate(tmp, gen)) {
+		*eb_ret = tmp;
+		return 0;
+	}
+
+	/*
+	 * reduce lock contention at high levels
+	 * of the btree by dropping locks before
+	 * we read.
+	 */
+	btrfs_release_path(NULL, p);
+	if (tmp)
+		free_extent_buffer(tmp);
+	if (p->reada)
+		reada_for_search(root, p, level, slot, key->objectid);
+
+	tmp = read_tree_block(root, blocknr, blocksize, gen);
+	if (tmp)
+		free_extent_buffer(tmp);
+	return -EAGAIN;
+}
+
+/*
+ * helper function for btrfs_search_slot.  This does all of the checks
+ * for node-level blocks and does any balancing required based on
+ * the ins_len.
+ *
+ * If no extra work was required, zero is returned.  If we had to
+ * drop the path, -EAGAIN is returned and btrfs_search_slot must
+ * start over
+ */
+static int
+setup_nodes_for_search(struct btrfs_trans_handle *trans,
+		       struct btrfs_root *root, struct btrfs_path *p,
+		       struct extent_buffer *b, int level, int ins_len)
+{
+	int ret;
+	if ((p->search_for_split || ins_len > 0) && btrfs_header_nritems(b) >=
+	    BTRFS_NODEPTRS_PER_BLOCK(root) - 3) {
+		int sret;
+
+		sret = reada_for_balance(root, p, level);
+		if (sret)
+			goto again;
+
+		btrfs_set_path_blocking(p);
+		sret = split_node(trans, root, p, level);
+		btrfs_clear_path_blocking(p, NULL);
+
+		BUG_ON(sret > 0);
+		if (sret) {
+			ret = sret;
+			goto done;
+		}
+		b = p->nodes[level];
+	} else if (ins_len < 0 && btrfs_header_nritems(b) <
+		   BTRFS_NODEPTRS_PER_BLOCK(root) / 4) {
+		int sret;
+
+		sret = reada_for_balance(root, p, level);
+		if (sret)
+			goto again;
+
+		btrfs_set_path_blocking(p);
+		sret = balance_level(trans, root, p, level);
+		btrfs_clear_path_blocking(p, NULL);
+
+		if (sret) {
+			ret = sret;
+			goto done;
+		}
+		b = p->nodes[level];
+		if (!b) {
+			btrfs_release_path(NULL, p);
+			goto again;
+		}
+		BUG_ON(btrfs_header_nritems(b) == 1);
+	}
+	return 0;
+
+again:
+	ret = -EAGAIN;
+done:
+	return ret;
+}
+
+/*
  * look for key in the tree.  path is filled in with nodes along the way
  * if key is found, we return zero and you can find the item in the leaf
  * level of the path (level 0)
@@ -1464,16 +1575,11 @@
 		      ins_len, int cow)
 {
 	struct extent_buffer *b;
-	struct extent_buffer *tmp;
 	int slot;
 	int ret;
 	int level;
-	int should_reada = p->reada;
 	int lowest_unlock = 1;
-	int blocksize;
 	u8 lowest_level = 0;
-	u64 blocknr;
-	u64 gen;
 
 	lowest_level = p->lowest_level;
 	WARN_ON(lowest_level && ins_len > 0);
@@ -1502,7 +1608,11 @@
 		if (cow) {
 			int wret;
 
-			/* is a cow on this block not required */
+			/*
+			 * if we don't really need to cow this block
+			 * then we don't want to set the path blocking,
+			 * so we test it here
+			 */
 			if (btrfs_header_generation(b) == trans->transid &&
 			    btrfs_header_owner(b) == root->root_key.objectid &&
 			    !btrfs_header_flag(b, BTRFS_HEADER_FLAG_WRITTEN)) {
@@ -1557,51 +1667,15 @@
 			if (ret && slot > 0)
 				slot -= 1;
 			p->slots[level] = slot;
-			if ((p->search_for_split || ins_len > 0) &&
-			    btrfs_header_nritems(b) >=
-			    BTRFS_NODEPTRS_PER_BLOCK(root) - 3) {
-				int sret;
+			ret = setup_nodes_for_search(trans, root, p, b, level,
+						     ins_len);
+			if (ret == -EAGAIN)
+				goto again;
+			else if (ret)
+				goto done;
+			b = p->nodes[level];
+			slot = p->slots[level];
 
-				sret = reada_for_balance(root, p, level);
-				if (sret)
-					goto again;
-
-				btrfs_set_path_blocking(p);
-				sret = split_node(trans, root, p, level);
-				btrfs_clear_path_blocking(p, NULL);
-
-				BUG_ON(sret > 0);
-				if (sret) {
-					ret = sret;
-					goto done;
-				}
-				b = p->nodes[level];
-				slot = p->slots[level];
-			} else if (ins_len < 0 &&
-				   btrfs_header_nritems(b) <
-				   BTRFS_NODEPTRS_PER_BLOCK(root) / 4) {
-				int sret;
-
-				sret = reada_for_balance(root, p, level);
-				if (sret)
-					goto again;
-
-				btrfs_set_path_blocking(p);
-				sret = balance_level(trans, root, p, level);
-				btrfs_clear_path_blocking(p, NULL);
-
-				if (sret) {
-					ret = sret;
-					goto done;
-				}
-				b = p->nodes[level];
-				if (!b) {
-					btrfs_release_path(NULL, p);
-					goto again;
-				}
-				slot = p->slots[level];
-				BUG_ON(btrfs_header_nritems(b) == 1);
-			}
 			unlock_up(p, level, lowest_unlock);
 
 			/* this is only true while dropping a snapshot */
@@ -1610,44 +1684,11 @@
 				goto done;
 			}
 
-			blocknr = btrfs_node_blockptr(b, slot);
-			gen = btrfs_node_ptr_generation(b, slot);
-			blocksize = btrfs_level_size(root, level - 1);
+			ret = read_block_for_search(trans, root, p,
+						    &b, level, slot, key);
+			if (ret == -EAGAIN)
+				goto again;
 
-			tmp = btrfs_find_tree_block(root, blocknr, blocksize);
-			if (tmp && btrfs_buffer_uptodate(tmp, gen)) {
-				b = tmp;
-			} else {
-				/*
-				 * reduce lock contention at high levels
-				 * of the btree by dropping locks before
-				 * we read.
-				 */
-				if (level > 0) {
-					btrfs_release_path(NULL, p);
-					if (tmp)
-						free_extent_buffer(tmp);
-					if (should_reada)
-						reada_for_search(root, p,
-								 level, slot,
-								 key->objectid);
-
-					tmp = read_tree_block(root, blocknr,
-							 blocksize, gen);
-					if (tmp)
-						free_extent_buffer(tmp);
-					goto again;
-				} else {
-					btrfs_set_path_blocking(p);
-					if (tmp)
-						free_extent_buffer(tmp);
-					if (should_reada)
-						reada_for_search(root, p,
-								 level, slot,
-								 key->objectid);
-					b = read_node_slot(root, b, slot);
-				}
-			}
 			if (!p->skip_locking) {
 				int lret;
 
@@ -2116,8 +2157,7 @@
 	BUG_ON(!path->nodes[level]);
 	lower = path->nodes[level];
 	nritems = btrfs_header_nritems(lower);
-	if (slot > nritems)
-		BUG();
+	BUG_ON(slot > nritems);
 	if (nritems == BTRFS_NODEPTRS_PER_BLOCK(root))
 		BUG();
 	if (slot != nritems) {
@@ -4086,28 +4126,44 @@
 int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
 {
 	int slot;
-	int level = 1;
+	int level;
 	struct extent_buffer *c;
-	struct extent_buffer *next = NULL;
+	struct extent_buffer *next;
 	struct btrfs_key key;
 	u32 nritems;
 	int ret;
+	int old_spinning = path->leave_spinning;
+	int force_blocking = 0;
 
 	nritems = btrfs_header_nritems(path->nodes[0]);
 	if (nritems == 0)
 		return 1;
 
-	btrfs_item_key_to_cpu(path->nodes[0], &key, nritems - 1);
+	/*
+	 * we take the blocks in an order that upsets lockdep.  Using
+	 * blocking mode is the only way around it.
+	 */
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+	force_blocking = 1;
+#endif
 
+	btrfs_item_key_to_cpu(path->nodes[0], &key, nritems - 1);
+again:
+	level = 1;
+	next = NULL;
 	btrfs_release_path(root, path);
+
 	path->keep_locks = 1;
+
+	if (!force_blocking)
+		path->leave_spinning = 1;
+
 	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
 	path->keep_locks = 0;
 
 	if (ret < 0)
 		return ret;
 
-	btrfs_set_path_blocking(path);
 	nritems = btrfs_header_nritems(path->nodes[0]);
 	/*
 	 * by releasing the path above we dropped all our locks.  A balance
@@ -4117,19 +4173,24 @@
 	 */
 	if (nritems > 0 && path->slots[0] < nritems - 1) {
 		path->slots[0]++;
+		ret = 0;
 		goto done;
 	}
 
 	while (level < BTRFS_MAX_LEVEL) {
-		if (!path->nodes[level])
-			return 1;
+		if (!path->nodes[level]) {
+			ret = 1;
+			goto done;
+		}
 
 		slot = path->slots[level] + 1;
 		c = path->nodes[level];
 		if (slot >= btrfs_header_nritems(c)) {
 			level++;
-			if (level == BTRFS_MAX_LEVEL)
-				return 1;
+			if (level == BTRFS_MAX_LEVEL) {
+				ret = 1;
+				goto done;
+			}
 			continue;
 		}
 
@@ -4138,16 +4199,22 @@
 			free_extent_buffer(next);
 		}
 
-		/* the path was set to blocking above */
-		if (level == 1 && (path->locks[1] || path->skip_locking) &&
-		    path->reada)
-			reada_for_search(root, path, level, slot, 0);
+		next = c;
+		ret = read_block_for_search(NULL, root, path, &next, level,
+					    slot, &key);
+		if (ret == -EAGAIN)
+			goto again;
 
-		next = read_node_slot(root, c, slot);
 		if (!path->skip_locking) {
-			btrfs_assert_tree_locked(c);
-			btrfs_tree_lock(next);
-			btrfs_set_lock_blocking(next);
+			ret = btrfs_try_spin_lock(next);
+			if (!ret) {
+				btrfs_set_path_blocking(path);
+				btrfs_tree_lock(next);
+				if (!force_blocking)
+					btrfs_clear_path_blocking(path, next);
+			}
+			if (force_blocking)
+				btrfs_set_lock_blocking(next);
 		}
 		break;
 	}
@@ -4157,27 +4224,42 @@
 		c = path->nodes[level];
 		if (path->locks[level])
 			btrfs_tree_unlock(c);
+
 		free_extent_buffer(c);
 		path->nodes[level] = next;
 		path->slots[level] = 0;
 		if (!path->skip_locking)
 			path->locks[level] = 1;
+
 		if (!level)
 			break;
 
-		btrfs_set_path_blocking(path);
-		if (level == 1 && path->locks[1] && path->reada)
-			reada_for_search(root, path, level, slot, 0);
-		next = read_node_slot(root, next, 0);
+		ret = read_block_for_search(NULL, root, path, &next, level,
+					    0, &key);
+		if (ret == -EAGAIN)
+			goto again;
+
 		if (!path->skip_locking) {
 			btrfs_assert_tree_locked(path->nodes[level]);
-			btrfs_tree_lock(next);
-			btrfs_set_lock_blocking(next);
+			ret = btrfs_try_spin_lock(next);
+			if (!ret) {
+				btrfs_set_path_blocking(path);
+				btrfs_tree_lock(next);
+				if (!force_blocking)
+					btrfs_clear_path_blocking(path, next);
+			}
+			if (force_blocking)
+				btrfs_set_lock_blocking(next);
 		}
 	}
+	ret = 0;
 done:
 	unlock_up(path, 0, 1);
-	return 0;
+	path->leave_spinning = old_spinning;
+	if (!old_spinning)
+		btrfs_set_path_blocking(path);
+
+	return ret;
 }
 
 /*
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 9417713..ad96495 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -143,12 +143,15 @@
 #define BTRFS_FT_MAX		9
 
 /*
- * the key defines the order in the tree, and so it also defines (optimal)
- * block layout.  objectid corresonds to the inode number.  The flags
- * tells us things about the object, and is a kind of stream selector.
- * so for a given inode, keys with flags of 1 might refer to the inode
- * data, flags of 2 may point to file data in the btree and flags == 3
- * may point to extents.
+ * The key defines the order in the tree, and so it also defines (optimal)
+ * block layout.
+ *
+ * objectid corresponds to the inode number.
+ *
+ * type tells us things about the object, and is a kind of stream selector.
+ * so for a given inode, keys with type of 1 might refer to the inode data,
+ * type of 2 may point to file data in the btree and type == 3 may point to
+ * extents.
  *
  * offset is the starting byte offset for this key in the stream.
  *
@@ -200,7 +203,7 @@
 
 	/*
 	 * starting byte of this partition on the device,
-	 * to allowr for stripe alignment in the future
+	 * to allow for stripe alignment in the future
 	 */
 	__le64 start_offset;
 
@@ -633,18 +636,35 @@
 	struct rw_semaphore groups_sem;
 };
 
-struct btrfs_free_space {
-	struct rb_node bytes_index;
-	struct rb_node offset_index;
-	u64 offset;
-	u64 bytes;
+/*
+ * free clusters are used to claim free space in relatively large chunks,
+ * allowing us to do less seeky writes.  They are used for all metadata
+ * allocations and data allocations in ssd mode.
+ */
+struct btrfs_free_cluster {
+	spinlock_t lock;
+	spinlock_t refill_lock;
+	struct rb_root root;
+
+	/* largest extent in this cluster */
+	u64 max_size;
+
+	/* first extent starting offset */
+	u64 window_start;
+
+	struct btrfs_block_group_cache *block_group;
+	/*
+	 * when a cluster is allocated from a block group, we put the
+	 * cluster onto a list in the block group so that it can
+	 * be freed before the block group is freed.
+	 */
+	struct list_head block_group_list;
 };
 
 struct btrfs_block_group_cache {
 	struct btrfs_key key;
 	struct btrfs_block_group_item item;
 	spinlock_t lock;
-	struct mutex alloc_mutex;
 	struct mutex cache_mutex;
 	u64 pinned;
 	u64 reserved;
@@ -656,6 +676,7 @@
 	struct btrfs_space_info *space_info;
 
 	/* free space cache stuff */
+	spinlock_t tree_lock;
 	struct rb_root free_space_bytes;
 	struct rb_root free_space_offset;
 
@@ -667,6 +688,11 @@
 
 	/* usage count */
 	atomic_t count;
+
+	/* List of struct btrfs_free_clusters for this block group.
+	 * Today it will only have one thing on it, but that may change
+	 */
+	struct list_head cluster_list;
 };
 
 struct btrfs_leaf_ref_tree {
@@ -728,7 +754,6 @@
 	struct mutex tree_log_mutex;
 	struct mutex transaction_kthread_mutex;
 	struct mutex cleaner_mutex;
-	struct mutex pinned_mutex;
 	struct mutex chunk_mutex;
 	struct mutex drop_mutex;
 	struct mutex volume_mutex;
@@ -839,8 +864,12 @@
 	spinlock_t delalloc_lock;
 	spinlock_t new_trans_lock;
 	u64 delalloc_bytes;
-	u64 last_alloc;
-	u64 last_data_alloc;
+
+	/* data_alloc_cluster is only used in ssd mode */
+	struct btrfs_free_cluster data_alloc_cluster;
+
+	/* all metadata allocations go through this cluster */
+	struct btrfs_free_cluster meta_alloc_cluster;
 
 	spinlock_t ref_cache_lock;
 	u64 total_ref_cache_size;
@@ -932,7 +961,6 @@
 };
 
 /*
-
  * inode items have the data typically returned from stat and store other
  * info about object characteristics.  There is one for every file and dir in
  * the FS
@@ -963,7 +991,7 @@
 #define BTRFS_EXTENT_CSUM_KEY	128
 
 /*
- * root items point to tree roots.  There are typically in the root
+ * root items point to tree roots.  They are typically in the root
  * tree used by the super block to find all the other trees
  */
 #define BTRFS_ROOT_ITEM_KEY	132
@@ -1010,6 +1038,8 @@
 #define BTRFS_MOUNT_SSD			(1 << 3)
 #define BTRFS_MOUNT_DEGRADED		(1 << 4)
 #define BTRFS_MOUNT_COMPRESS		(1 << 5)
+#define BTRFS_MOUNT_NOTREELOG           (1 << 6)
+#define BTRFS_MOUNT_FLUSHONCOMMIT       (1 << 7)
 
 #define btrfs_clear_opt(o, opt)		((o) &= ~BTRFS_MOUNT_##opt)
 #define btrfs_set_opt(o, opt)		((o) |= BTRFS_MOUNT_##opt)
@@ -1748,6 +1778,7 @@
 }
 
 /* extent-tree.c */
+void btrfs_put_block_group(struct btrfs_block_group_cache *cache);
 int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
 			   struct btrfs_root *root, unsigned long count);
 int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len);
@@ -2174,21 +2205,4 @@
 int btrfs_init_acl(struct inode *inode, struct inode *dir);
 int btrfs_acl_chmod(struct inode *inode);
 
-/* free-space-cache.c */
-int btrfs_add_free_space(struct btrfs_block_group_cache *block_group,
-			 u64 bytenr, u64 size);
-int btrfs_add_free_space_lock(struct btrfs_block_group_cache *block_group,
-			      u64 offset, u64 bytes);
-int btrfs_remove_free_space(struct btrfs_block_group_cache *block_group,
-			    u64 bytenr, u64 size);
-int btrfs_remove_free_space_lock(struct btrfs_block_group_cache *block_group,
-				 u64 offset, u64 bytes);
-void btrfs_remove_free_space_cache(struct btrfs_block_group_cache
-				   *block_group);
-struct btrfs_free_space *btrfs_find_free_space(struct btrfs_block_group_cache
-					       *block_group, u64 offset,
-					       u64 bytes);
-void btrfs_dump_free_space(struct btrfs_block_group_cache *block_group,
-			   u64 bytes);
-u64 btrfs_block_group_free_space(struct btrfs_block_group_cache *block_group);
 #endif
diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c
index cbf7dc8a..d6c01c0 100644
--- a/fs/btrfs/delayed-ref.c
+++ b/fs/btrfs/delayed-ref.c
@@ -18,7 +18,6 @@
 
 #include <linux/sched.h>
 #include <linux/sort.h>
-#include <linux/ftrace.h>
 #include "ctree.h"
 #include "delayed-ref.h"
 #include "transaction.h"
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 92d7392..92caa80 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -38,6 +38,7 @@
 #include "locking.h"
 #include "ref-cache.h"
 #include "tree-log.h"
+#include "free-space-cache.h"
 
 static struct extent_io_ops btree_extent_io_ops;
 static void end_workqueue_fn(struct btrfs_work *work);
@@ -1412,8 +1413,6 @@
 
 	ret = extent_range_uptodate(io_tree, start + length,
 				    start + buf_len - 1);
-	if (ret == 1)
-		return ret;
 	return ret;
 }
 
@@ -1647,12 +1646,15 @@
 	mutex_init(&fs_info->ordered_operations_mutex);
 	mutex_init(&fs_info->tree_log_mutex);
 	mutex_init(&fs_info->drop_mutex);
-	mutex_init(&fs_info->pinned_mutex);
 	mutex_init(&fs_info->chunk_mutex);
 	mutex_init(&fs_info->transaction_kthread_mutex);
 	mutex_init(&fs_info->cleaner_mutex);
 	mutex_init(&fs_info->volume_mutex);
 	mutex_init(&fs_info->tree_reloc_mutex);
+
+	btrfs_init_free_cluster(&fs_info->meta_alloc_cluster);
+	btrfs_init_free_cluster(&fs_info->data_alloc_cluster);
+
 	init_waitqueue_head(&fs_info->transaction_throttle);
 	init_waitqueue_head(&fs_info->transaction_wait);
 	init_waitqueue_head(&fs_info->async_submit_wait);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index f5e7cae..178df4c 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -31,6 +31,7 @@
 #include "volumes.h"
 #include "locking.h"
 #include "ref-cache.h"
+#include "free-space-cache.h"
 
 #define PENDING_EXTENT_INSERT 0
 #define PENDING_EXTENT_DELETE 1
@@ -166,7 +167,6 @@
 	u64 extent_start, extent_end, size;
 	int ret;
 
-	mutex_lock(&info->pinned_mutex);
 	while (start < end) {
 		ret = find_first_extent_bit(&info->pinned_extents, start,
 					    &extent_start, &extent_end,
@@ -192,7 +192,6 @@
 		ret = btrfs_add_free_space(block_group, start, size);
 		BUG_ON(ret);
 	}
-	mutex_unlock(&info->pinned_mutex);
 
 	return 0;
 }
@@ -291,8 +290,8 @@
 			   block_group->key.objectid +
 			   block_group->key.offset);
 
-	remove_sb_from_cache(root, block_group);
 	block_group->cached = 1;
+	remove_sb_from_cache(root, block_group);
 	ret = 0;
 err:
 	btrfs_free_path(path);
@@ -326,7 +325,7 @@
 	return cache;
 }
 
-static inline void put_block_group(struct btrfs_block_group_cache *cache)
+void btrfs_put_block_group(struct btrfs_block_group_cache *cache)
 {
 	if (atomic_dec_and_test(&cache->count))
 		kfree(cache);
@@ -399,12 +398,12 @@
 			    div_factor(cache->key.offset, factor)) {
 				group_start = cache->key.objectid;
 				spin_unlock(&cache->lock);
-				put_block_group(cache);
+				btrfs_put_block_group(cache);
 				goto found;
 			}
 		}
 		spin_unlock(&cache->lock);
-		put_block_group(cache);
+		btrfs_put_block_group(cache);
 		cond_resched();
 	}
 	if (!wrapped) {
@@ -1594,7 +1593,7 @@
 	if (!block_group || block_group->ro)
 		readonly = 1;
 	if (block_group)
-		put_block_group(block_group);
+		btrfs_put_block_group(block_group);
 	return readonly;
 }
 
@@ -2018,7 +2017,7 @@
 				WARN_ON(ret);
 			}
 		}
-		put_block_group(cache);
+		btrfs_put_block_group(cache);
 		total -= num_bytes;
 		bytenr += num_bytes;
 	}
@@ -2035,7 +2034,7 @@
 		return 0;
 
 	bytenr = cache->key.objectid;
-	put_block_group(cache);
+	btrfs_put_block_group(cache);
 
 	return bytenr;
 }
@@ -2047,7 +2046,6 @@
 	struct btrfs_block_group_cache *cache;
 	struct btrfs_fs_info *fs_info = root->fs_info;
 
-	WARN_ON(!mutex_is_locked(&root->fs_info->pinned_mutex));
 	if (pin) {
 		set_extent_dirty(&fs_info->pinned_extents,
 				bytenr, bytenr + num - 1, GFP_NOFS);
@@ -2055,7 +2053,6 @@
 		clear_extent_dirty(&fs_info->pinned_extents,
 				bytenr, bytenr + num - 1, GFP_NOFS);
 	}
-	mutex_unlock(&root->fs_info->pinned_mutex);
 
 	while (num > 0) {
 		cache = btrfs_lookup_block_group(fs_info, bytenr);
@@ -2081,7 +2078,7 @@
 			if (cache->cached)
 				btrfs_add_free_space(cache, bytenr, len);
 		}
-		put_block_group(cache);
+		btrfs_put_block_group(cache);
 		bytenr += len;
 		num -= len;
 	}
@@ -2112,7 +2109,7 @@
 		}
 		spin_unlock(&cache->lock);
 		spin_unlock(&cache->space_info->lock);
-		put_block_group(cache);
+		btrfs_put_block_group(cache);
 		bytenr += len;
 		num -= len;
 	}
@@ -2127,7 +2124,6 @@
 	struct extent_io_tree *pinned_extents = &root->fs_info->pinned_extents;
 	int ret;
 
-	mutex_lock(&root->fs_info->pinned_mutex);
 	while (1) {
 		ret = find_first_extent_bit(pinned_extents, last,
 					    &start, &end, EXTENT_DIRTY);
@@ -2136,7 +2132,6 @@
 		set_extent_dirty(copy, start, end, GFP_NOFS);
 		last = end + 1;
 	}
-	mutex_unlock(&root->fs_info->pinned_mutex);
 	return 0;
 }
 
@@ -2149,7 +2144,6 @@
 	int ret;
 
 	while (1) {
-		mutex_lock(&root->fs_info->pinned_mutex);
 		ret = find_first_extent_bit(unpin, 0, &start, &end,
 					    EXTENT_DIRTY);
 		if (ret)
@@ -2163,7 +2157,6 @@
 
 		cond_resched();
 	}
-	mutex_unlock(&root->fs_info->pinned_mutex);
 	return ret;
 }
 
@@ -2205,7 +2198,6 @@
 	free_extent_buffer(buf);
 pinit:
 	btrfs_set_path_blocking(path);
-	mutex_lock(&root->fs_info->pinned_mutex);
 	/* unlocks the pinned mutex */
 	btrfs_update_pinned_extents(root, bytenr, num_bytes, 1);
 
@@ -2511,8 +2503,6 @@
 	 */
 	if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID &&
 	    owner_objectid < BTRFS_FIRST_FREE_OBJECTID) {
-		mutex_lock(&root->fs_info->pinned_mutex);
-
 		/* unlocks the pinned mutex */
 		btrfs_update_pinned_extents(root, bytenr, num_bytes, 1);
 		update_reserved_extents(root, bytenr, num_bytes, 0);
@@ -2554,228 +2544,237 @@
 {
 	int ret = 0;
 	struct btrfs_root *root = orig_root->fs_info->extent_root;
-	u64 total_needed = num_bytes;
-	u64 *last_ptr = NULL;
-	u64 last_wanted = 0;
+	struct btrfs_free_cluster *last_ptr = NULL;
 	struct btrfs_block_group_cache *block_group = NULL;
-	int chunk_alloc_done = 0;
 	int empty_cluster = 2 * 1024 * 1024;
 	int allowed_chunk_alloc = 0;
-	struct list_head *head = NULL, *cur = NULL;
-	int loop = 0;
-	int extra_loop = 0;
 	struct btrfs_space_info *space_info;
+	int last_ptr_loop = 0;
+	int loop = 0;
 
 	WARN_ON(num_bytes < root->sectorsize);
 	btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY);
 	ins->objectid = 0;
 	ins->offset = 0;
 
+	space_info = __find_space_info(root->fs_info, data);
+
 	if (orig_root->ref_cows || empty_size)
 		allowed_chunk_alloc = 1;
 
 	if (data & BTRFS_BLOCK_GROUP_METADATA) {
-		last_ptr = &root->fs_info->last_alloc;
+		last_ptr = &root->fs_info->meta_alloc_cluster;
 		if (!btrfs_test_opt(root, SSD))
 			empty_cluster = 64 * 1024;
 	}
 
-	if ((data & BTRFS_BLOCK_GROUP_DATA) && btrfs_test_opt(root, SSD))
-		last_ptr = &root->fs_info->last_data_alloc;
+	if ((data & BTRFS_BLOCK_GROUP_DATA) && btrfs_test_opt(root, SSD)) {
+		last_ptr = &root->fs_info->data_alloc_cluster;
+	}
 
 	if (last_ptr) {
-		if (*last_ptr) {
-			hint_byte = *last_ptr;
-			last_wanted = *last_ptr;
-		} else
-			empty_size += empty_cluster;
-	} else {
-		empty_cluster = 0;
+		spin_lock(&last_ptr->lock);
+		if (last_ptr->block_group)
+			hint_byte = last_ptr->window_start;
+		spin_unlock(&last_ptr->lock);
 	}
+
 	search_start = max(search_start, first_logical_byte(root, 0));
 	search_start = max(search_start, hint_byte);
 
-	if (last_wanted && search_start != last_wanted) {
-		last_wanted = 0;
-		empty_size += empty_cluster;
+	if (!last_ptr) {
+		empty_cluster = 0;
+		loop = 1;
 	}
 
-	total_needed += empty_size;
-	block_group = btrfs_lookup_block_group(root->fs_info, search_start);
-	if (!block_group)
-		block_group = btrfs_lookup_first_block_group(root->fs_info,
-							     search_start);
-	space_info = __find_space_info(root->fs_info, data);
+	if (search_start == hint_byte) {
+		block_group = btrfs_lookup_block_group(root->fs_info,
+						       search_start);
+		if (block_group && block_group_bits(block_group, data)) {
+			down_read(&space_info->groups_sem);
+			goto have_block_group;
+		} else if (block_group) {
+			btrfs_put_block_group(block_group);
+		}
+	}
 
+search:
 	down_read(&space_info->groups_sem);
-	while (1) {
-		struct btrfs_free_space *free_space;
-		/*
-		 * the only way this happens if our hint points to a block
-		 * group thats not of the proper type, while looping this
-		 * should never happen
-		 */
-		if (empty_size)
-			extra_loop = 1;
+	list_for_each_entry(block_group, &space_info->block_groups, list) {
+		u64 offset;
 
-		if (!block_group)
-			goto new_group_no_lock;
+		atomic_inc(&block_group->count);
+		search_start = block_group->key.objectid;
 
+have_block_group:
 		if (unlikely(!block_group->cached)) {
 			mutex_lock(&block_group->cache_mutex);
 			ret = cache_block_group(root, block_group);
 			mutex_unlock(&block_group->cache_mutex);
-			if (ret)
+			if (ret) {
+				btrfs_put_block_group(block_group);
 				break;
+			}
 		}
 
-		mutex_lock(&block_group->alloc_mutex);
-		if (unlikely(!block_group_bits(block_group, data)))
-			goto new_group;
-
 		if (unlikely(block_group->ro))
-			goto new_group;
+			goto loop;
 
-		free_space = btrfs_find_free_space(block_group, search_start,
-						   total_needed);
-		if (free_space) {
-			u64 start = block_group->key.objectid;
-			u64 end = block_group->key.objectid +
-				block_group->key.offset;
-
-			search_start = stripe_align(root, free_space->offset);
-
-			/* move on to the next group */
-			if (search_start + num_bytes >= search_end)
-				goto new_group;
-
-			/* move on to the next group */
-			if (search_start + num_bytes > end)
-				goto new_group;
-
-			if (last_wanted && search_start != last_wanted) {
-				total_needed += empty_cluster;
-				empty_size += empty_cluster;
-				last_wanted = 0;
-				/*
-				 * if search_start is still in this block group
-				 * then we just re-search this block group
-				 */
-				if (search_start >= start &&
-				    search_start < end) {
-					mutex_unlock(&block_group->alloc_mutex);
-					continue;
-				}
-
-				/* else we go to the next block group */
-				goto new_group;
-			}
-
-			if (exclude_nr > 0 &&
-			    (search_start + num_bytes > exclude_start &&
-			     search_start < exclude_start + exclude_nr)) {
-				search_start = exclude_start + exclude_nr;
-				/*
-				 * if search_start is still in this block group
-				 * then we just re-search this block group
-				 */
-				if (search_start >= start &&
-				    search_start < end) {
-					mutex_unlock(&block_group->alloc_mutex);
-					last_wanted = 0;
-					continue;
-				}
-
-				/* else we go to the next block group */
-				goto new_group;
-			}
-
-			ins->objectid = search_start;
-			ins->offset = num_bytes;
-
-			btrfs_remove_free_space_lock(block_group, search_start,
-						     num_bytes);
-			/* we are all good, lets return */
-			mutex_unlock(&block_group->alloc_mutex);
-			break;
-		}
-new_group:
-		mutex_unlock(&block_group->alloc_mutex);
-		put_block_group(block_group);
-		block_group = NULL;
-new_group_no_lock:
-		/* don't try to compare new allocations against the
-		 * last allocation any more
-		 */
-		last_wanted = 0;
-
-		/*
-		 * Here's how this works.
-		 * loop == 0: we were searching a block group via a hint
-		 *		and didn't find anything, so we start at
-		 *		the head of the block groups and keep searching
-		 * loop == 1: we're searching through all of the block groups
-		 *		if we hit the head again we have searched
-		 *		all of the block groups for this space and we
-		 *		need to try and allocate, if we cant error out.
-		 * loop == 2: we allocated more space and are looping through
-		 *		all of the block groups again.
-		 */
-		if (loop == 0) {
-			head = &space_info->block_groups;
-			cur = head->next;
-			loop++;
-		} else if (loop == 1 && cur == head) {
-			int keep_going;
-
-			/* at this point we give up on the empty_size
-			 * allocations and just try to allocate the min
-			 * space.
-			 *
-			 * The extra_loop field was set if an empty_size
-			 * allocation was attempted above, and if this
-			 * is try we need to try the loop again without
-			 * the additional empty_size.
+		if (last_ptr) {
+			/*
+			 * the refill lock keeps out other
+			 * people trying to start a new cluster
 			 */
-			total_needed -= empty_size;
-			empty_size = 0;
-			keep_going = extra_loop;
-			loop++;
+			spin_lock(&last_ptr->refill_lock);
+			offset = btrfs_alloc_from_cluster(block_group, last_ptr,
+						 num_bytes, search_start);
+			if (offset) {
+				/* we have a block, we're done */
+				spin_unlock(&last_ptr->refill_lock);
+				goto checks;
+			}
 
-			if (allowed_chunk_alloc && !chunk_alloc_done) {
-				up_read(&space_info->groups_sem);
-				ret = do_chunk_alloc(trans, root, num_bytes +
-						     2 * 1024 * 1024, data, 1);
-				down_read(&space_info->groups_sem);
-				if (ret < 0)
-					goto loop_check;
-				head = &space_info->block_groups;
+			spin_lock(&last_ptr->lock);
+			/*
+			 * whoops, this cluster doesn't actually point to
+			 * this block group.  Get a ref on the block
+			 * group is does point to and try again
+			 */
+			if (!last_ptr_loop && last_ptr->block_group &&
+			    last_ptr->block_group != block_group) {
+
+				btrfs_put_block_group(block_group);
+				block_group = last_ptr->block_group;
+				atomic_inc(&block_group->count);
+				spin_unlock(&last_ptr->lock);
+				spin_unlock(&last_ptr->refill_lock);
+
+				last_ptr_loop = 1;
+				search_start = block_group->key.objectid;
+				goto have_block_group;
+			}
+			spin_unlock(&last_ptr->lock);
+
+			/*
+			 * this cluster didn't work out, free it and
+			 * start over
+			 */
+			btrfs_return_cluster_to_free_space(NULL, last_ptr);
+
+			last_ptr_loop = 0;
+
+			/* allocate a cluster in this block group */
+			ret = btrfs_find_space_cluster(trans,
+					       block_group, last_ptr,
+					       offset, num_bytes,
+					       empty_cluster + empty_size);
+			if (ret == 0) {
 				/*
-				 * we've allocated a new chunk, keep
-				 * trying
+				 * now pull our allocation out of this
+				 * cluster
 				 */
-				keep_going = 1;
-				chunk_alloc_done = 1;
-			} else if (!allowed_chunk_alloc) {
-				space_info->force_alloc = 1;
+				offset = btrfs_alloc_from_cluster(block_group,
+						  last_ptr, num_bytes,
+						  search_start);
+				if (offset) {
+					/* we found one, proceed */
+					spin_unlock(&last_ptr->refill_lock);
+					goto checks;
+				}
 			}
-loop_check:
-			if (keep_going) {
-				cur = head->next;
-				extra_loop = 0;
-			} else {
-				break;
+			/*
+			 * at this point we either didn't find a cluster
+			 * or we weren't able to allocate a block from our
+			 * cluster.  Free the cluster we've been trying
+			 * to use, and go to the next block group
+			 */
+			if (loop < 2) {
+				btrfs_return_cluster_to_free_space(NULL,
+								   last_ptr);
+				spin_unlock(&last_ptr->refill_lock);
+				goto loop;
 			}
-		} else if (cur == head) {
-			break;
+			spin_unlock(&last_ptr->refill_lock);
 		}
 
-		block_group = list_entry(cur, struct btrfs_block_group_cache,
-					 list);
-		atomic_inc(&block_group->count);
+		offset = btrfs_find_space_for_alloc(block_group, search_start,
+						    num_bytes, empty_size);
+		if (!offset)
+			goto loop;
+checks:
+		search_start = stripe_align(root, offset);
 
-		search_start = block_group->key.objectid;
-		cur = cur->next;
+		/* move on to the next group */
+		if (search_start + num_bytes >= search_end) {
+			btrfs_add_free_space(block_group, offset, num_bytes);
+			goto loop;
+		}
+
+		/* move on to the next group */
+		if (search_start + num_bytes >
+		    block_group->key.objectid + block_group->key.offset) {
+			btrfs_add_free_space(block_group, offset, num_bytes);
+			goto loop;
+		}
+
+		if (exclude_nr > 0 &&
+		    (search_start + num_bytes > exclude_start &&
+		     search_start < exclude_start + exclude_nr)) {
+			search_start = exclude_start + exclude_nr;
+
+			btrfs_add_free_space(block_group, offset, num_bytes);
+			/*
+			 * if search_start is still in this block group
+			 * then we just re-search this block group
+			 */
+			if (search_start >= block_group->key.objectid &&
+			    search_start < (block_group->key.objectid +
+					    block_group->key.offset))
+				goto have_block_group;
+			goto loop;
+		}
+
+		ins->objectid = search_start;
+		ins->offset = num_bytes;
+
+		if (offset < search_start)
+			btrfs_add_free_space(block_group, offset,
+					     search_start - offset);
+		BUG_ON(offset > search_start);
+
+		/* we are all good, lets return */
+		break;
+loop:
+		btrfs_put_block_group(block_group);
+	}
+	up_read(&space_info->groups_sem);
+
+	/* loop == 0, try to find a clustered alloc in every block group
+	 * loop == 1, try again after forcing a chunk allocation
+	 * loop == 2, set empty_size and empty_cluster to 0 and try again
+	 */
+	if (!ins->objectid && loop < 3 &&
+	    (empty_size || empty_cluster || allowed_chunk_alloc)) {
+		if (loop >= 2) {
+			empty_size = 0;
+			empty_cluster = 0;
+		}
+
+		if (allowed_chunk_alloc) {
+			ret = do_chunk_alloc(trans, root, num_bytes +
+					     2 * 1024 * 1024, data, 1);
+			allowed_chunk_alloc = 0;
+		} else {
+			space_info->force_alloc = 1;
+		}
+
+		if (loop < 3) {
+			loop++;
+			goto search;
+		}
+		ret = -ENOSPC;
+	} else if (!ins->objectid) {
+		ret = -ENOSPC;
 	}
 
 	/* we found what we needed */
@@ -2783,21 +2782,10 @@
 		if (!(data & BTRFS_BLOCK_GROUP_DATA))
 			trans->block_group = block_group->key.objectid;
 
-		if (last_ptr)
-			*last_ptr = ins->objectid + ins->offset;
+		btrfs_put_block_group(block_group);
 		ret = 0;
-	} else if (!ret) {
-		printk(KERN_ERR "btrfs searching for %llu bytes, "
-		       "num_bytes %llu, loop %d, allowed_alloc %d\n",
-		       (unsigned long long)total_needed,
-		       (unsigned long long)num_bytes,
-		       loop, allowed_chunk_alloc);
-		ret = -ENOSPC;
 	}
-	if (block_group)
-		put_block_group(block_group);
 
-	up_read(&space_info->groups_sem);
 	return ret;
 }
 
@@ -2902,7 +2890,7 @@
 	ret = btrfs_discard_extent(root, start, len);
 
 	btrfs_add_free_space(cache, start, len);
-	put_block_group(cache);
+	btrfs_put_block_group(cache);
 	update_reserved_extents(root, start, len, 0);
 
 	return ret;
@@ -3040,7 +3028,7 @@
 	ret = btrfs_remove_free_space(block_group, ins->objectid,
 				      ins->offset);
 	BUG_ON(ret);
-	put_block_group(block_group);
+	btrfs_put_block_group(block_group);
 	ret = __btrfs_alloc_reserved_extent(trans, root, parent, root_objectid,
 					    ref_generation, owner, ins, 1);
 	return ret;
@@ -5729,7 +5717,7 @@
 	WARN_ON(block_group->reserved > 0);
 	WARN_ON(btrfs_block_group_used(&block_group->item) > 0);
 	spin_unlock(&block_group->lock);
-	put_block_group(block_group);
+	btrfs_put_block_group(block_group);
 	ret = 0;
 out:
 	btrfs_free_path(path);
@@ -5856,9 +5844,10 @@
 
 		atomic_set(&cache->count, 1);
 		spin_lock_init(&cache->lock);
-		mutex_init(&cache->alloc_mutex);
+		spin_lock_init(&cache->tree_lock);
 		mutex_init(&cache->cache_mutex);
 		INIT_LIST_HEAD(&cache->list);
+		INIT_LIST_HEAD(&cache->cluster_list);
 		read_extent_buffer(leaf, &cache->item,
 				   btrfs_item_ptr_offset(leaf, path->slots[0]),
 				   sizeof(cache->item));
@@ -5912,9 +5901,10 @@
 	cache->key.type = BTRFS_BLOCK_GROUP_ITEM_KEY;
 	atomic_set(&cache->count, 1);
 	spin_lock_init(&cache->lock);
-	mutex_init(&cache->alloc_mutex);
+	spin_lock_init(&cache->tree_lock);
 	mutex_init(&cache->cache_mutex);
 	INIT_LIST_HEAD(&cache->list);
+	INIT_LIST_HEAD(&cache->cluster_list);
 
 	btrfs_set_block_group_used(&cache->item, bytes_used);
 	btrfs_set_block_group_chunk_objectid(&cache->item, chunk_objectid);
@@ -5974,8 +5964,8 @@
 	spin_unlock(&block_group->space_info->lock);
 	block_group->space_info->full = 0;
 
-	put_block_group(block_group);
-	put_block_group(block_group);
+	btrfs_put_block_group(block_group);
+	btrfs_put_block_group(block_group);
 
 	ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
 	if (ret > 0)
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 08085af..eb2bee8 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -2884,25 +2884,19 @@
 		disko = 0;
 		flags = 0;
 
-		switch (em->block_start) {
-		case EXTENT_MAP_LAST_BYTE:
+		if (em->block_start == EXTENT_MAP_LAST_BYTE) {
 			end = 1;
 			flags |= FIEMAP_EXTENT_LAST;
-			break;
-		case EXTENT_MAP_HOLE:
+		} else if (em->block_start == EXTENT_MAP_HOLE) {
 			flags |= FIEMAP_EXTENT_UNWRITTEN;
-			break;
-		case EXTENT_MAP_INLINE:
+		} else if (em->block_start == EXTENT_MAP_INLINE) {
 			flags |= (FIEMAP_EXTENT_DATA_INLINE |
 				  FIEMAP_EXTENT_NOT_ALIGNED);
-			break;
-		case EXTENT_MAP_DELALLOC:
+		} else if (em->block_start == EXTENT_MAP_DELALLOC) {
 			flags |= (FIEMAP_EXTENT_DELALLOC |
 				  FIEMAP_EXTENT_UNKNOWN);
-			break;
-		default:
+		} else {
 			disko = em->block_start;
-			break;
 		}
 		if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags))
 			flags |= FIEMAP_EXTENT_ENCODED;
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index 50da69d..b187917 100644
--- a/fs/btrfs/extent_map.c
+++ b/fs/btrfs/extent_map.c
@@ -234,7 +234,6 @@
 	rb = tree_insert(&tree->map, em->start, &em->rb_node);
 	if (rb) {
 		ret = -EEXIST;
-		free_extent_map(merge);
 		goto out;
 	}
 	atomic_inc(&em->refs);
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index d1e5f0e..768b952 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -18,6 +18,15 @@
 
 #include <linux/sched.h>
 #include "ctree.h"
+#include "free-space-cache.h"
+#include "transaction.h"
+
+struct btrfs_free_space {
+	struct rb_node bytes_index;
+	struct rb_node offset_index;
+	u64 offset;
+	u64 bytes;
+};
 
 static int tree_insert_offset(struct rb_root *root, u64 offset,
 			      struct rb_node *node)
@@ -68,14 +77,24 @@
 }
 
 /*
- * searches the tree for the given offset.  If contains is set we will return
- * the free space that contains the given offset.  If contains is not set we
- * will return the free space that starts at or after the given offset and is
- * at least bytes long.
+ * searches the tree for the given offset.
+ *
+ * fuzzy == 1: this is used for allocations where we are given a hint of where
+ * to look for free space.  Because the hint may not be completely on an offset
+ * mark, or the hint may no longer point to free space we need to fudge our
+ * results a bit.  So we look for free space starting at or after offset with at
+ * least bytes size.  We prefer to find as close to the given offset as we can.
+ * Also if the offset is within a free space range, then we will return the free
+ * space that contains the given offset, which means we can return a free space
+ * chunk with an offset before the provided offset.
+ *
+ * fuzzy == 0: this is just a normal tree search.  Give us the free space that
+ * starts at the given offset which is at least bytes size, and if its not there
+ * return NULL.
  */
 static struct btrfs_free_space *tree_search_offset(struct rb_root *root,
 						   u64 offset, u64 bytes,
-						   int contains)
+						   int fuzzy)
 {
 	struct rb_node *n = root->rb_node;
 	struct btrfs_free_space *entry, *ret = NULL;
@@ -84,13 +103,14 @@
 		entry = rb_entry(n, struct btrfs_free_space, offset_index);
 
 		if (offset < entry->offset) {
-			if (!contains &&
+			if (fuzzy &&
 			    (!ret || entry->offset < ret->offset) &&
 			    (bytes <= entry->bytes))
 				ret = entry;
 			n = n->rb_left;
 		} else if (offset > entry->offset) {
-			if ((entry->offset + entry->bytes - 1) >= offset &&
+			if (fuzzy &&
+			    (entry->offset + entry->bytes - 1) >= offset &&
 			    bytes <= entry->bytes) {
 				ret = entry;
 				break;
@@ -171,6 +191,7 @@
 	int ret = 0;
 
 
+	BUG_ON(!info->bytes);
 	ret = tree_insert_offset(&block_group->free_space_offset, info->offset,
 				 &info->offset_index);
 	if (ret)
@@ -184,108 +205,70 @@
 	return ret;
 }
 
-static int __btrfs_add_free_space(struct btrfs_block_group_cache *block_group,
-				  u64 offset, u64 bytes)
+int btrfs_add_free_space(struct btrfs_block_group_cache *block_group,
+			 u64 offset, u64 bytes)
 {
 	struct btrfs_free_space *right_info;
 	struct btrfs_free_space *left_info;
 	struct btrfs_free_space *info = NULL;
-	struct btrfs_free_space *alloc_info;
 	int ret = 0;
 
-	alloc_info = kzalloc(sizeof(struct btrfs_free_space), GFP_NOFS);
-	if (!alloc_info)
+	info = kzalloc(sizeof(struct btrfs_free_space), GFP_NOFS);
+	if (!info)
 		return -ENOMEM;
 
+	info->offset = offset;
+	info->bytes = bytes;
+
+	spin_lock(&block_group->tree_lock);
+
 	/*
 	 * first we want to see if there is free space adjacent to the range we
 	 * are adding, if there is remove that struct and add a new one to
 	 * cover the entire range
 	 */
 	right_info = tree_search_offset(&block_group->free_space_offset,
-					offset+bytes, 0, 1);
+					offset+bytes, 0, 0);
 	left_info = tree_search_offset(&block_group->free_space_offset,
 				       offset-1, 0, 1);
 
-	if (right_info && right_info->offset == offset+bytes) {
+	if (right_info) {
 		unlink_free_space(block_group, right_info);
-		info = right_info;
-		info->offset = offset;
-		info->bytes += bytes;
-	} else if (right_info && right_info->offset != offset+bytes) {
-		printk(KERN_ERR "btrfs adding space in the middle of an "
-		       "existing free space area. existing: "
-		       "offset=%llu, bytes=%llu. new: offset=%llu, "
-		       "bytes=%llu\n", (unsigned long long)right_info->offset,
-		       (unsigned long long)right_info->bytes,
-		       (unsigned long long)offset,
-		       (unsigned long long)bytes);
-		BUG();
+		info->bytes += right_info->bytes;
+		kfree(right_info);
 	}
 
-	if (left_info) {
+	if (left_info && left_info->offset + left_info->bytes == offset) {
 		unlink_free_space(block_group, left_info);
-
-		if (unlikely((left_info->offset + left_info->bytes) !=
-			     offset)) {
-			printk(KERN_ERR "btrfs free space to the left "
-			       "of new free space isn't "
-			       "quite right. existing: offset=%llu, "
-			       "bytes=%llu. new: offset=%llu, bytes=%llu\n",
-			       (unsigned long long)left_info->offset,
-			       (unsigned long long)left_info->bytes,
-			       (unsigned long long)offset,
-			       (unsigned long long)bytes);
-			BUG();
-		}
-
-		if (info) {
-			info->offset = left_info->offset;
-			info->bytes += left_info->bytes;
-			kfree(left_info);
-		} else {
-			info = left_info;
-			info->bytes += bytes;
-		}
+		info->offset = left_info->offset;
+		info->bytes += left_info->bytes;
+		kfree(left_info);
 	}
 
-	if (info) {
-		ret = link_free_space(block_group, info);
-		if (!ret)
-			info = NULL;
-		goto out;
-	}
-
-	info = alloc_info;
-	alloc_info = NULL;
-	info->offset = offset;
-	info->bytes = bytes;
-
 	ret = link_free_space(block_group, info);
 	if (ret)
 		kfree(info);
-out:
+
+	spin_unlock(&block_group->tree_lock);
+
 	if (ret) {
 		printk(KERN_ERR "btrfs: unable to add free space :%d\n", ret);
-		if (ret == -EEXIST)
-			BUG();
+		BUG_ON(ret == -EEXIST);
 	}
 
-	kfree(alloc_info);
-
 	return ret;
 }
 
-static int
-__btrfs_remove_free_space(struct btrfs_block_group_cache *block_group,
-			  u64 offset, u64 bytes)
+int btrfs_remove_free_space(struct btrfs_block_group_cache *block_group,
+			    u64 offset, u64 bytes)
 {
 	struct btrfs_free_space *info;
 	int ret = 0;
 
+	spin_lock(&block_group->tree_lock);
+
 	info = tree_search_offset(&block_group->free_space_offset, offset, 0,
 				  1);
-
 	if (info && info->offset == offset) {
 		if (info->bytes < bytes) {
 			printk(KERN_ERR "Found free space at %llu, size %llu,"
@@ -295,12 +278,14 @@
 			       (unsigned long long)bytes);
 			WARN_ON(1);
 			ret = -EINVAL;
+			spin_unlock(&block_group->tree_lock);
 			goto out;
 		}
 		unlink_free_space(block_group, info);
 
 		if (info->bytes == bytes) {
 			kfree(info);
+			spin_unlock(&block_group->tree_lock);
 			goto out;
 		}
 
@@ -308,6 +293,7 @@
 		info->bytes -= bytes;
 
 		ret = link_free_space(block_group, info);
+		spin_unlock(&block_group->tree_lock);
 		BUG_ON(ret);
 	} else if (info && info->offset < offset &&
 		   info->offset + info->bytes >= offset + bytes) {
@@ -333,70 +319,33 @@
 			 */
 			kfree(info);
 		}
-
+		spin_unlock(&block_group->tree_lock);
 		/* step two, insert a new info struct to cover anything
 		 * before the hole
 		 */
-		ret = __btrfs_add_free_space(block_group, old_start,
-					     offset - old_start);
+		ret = btrfs_add_free_space(block_group, old_start,
+					   offset - old_start);
 		BUG_ON(ret);
 	} else {
+		spin_unlock(&block_group->tree_lock);
+		if (!info) {
+			printk(KERN_ERR "couldn't find space %llu to free\n",
+			       (unsigned long long)offset);
+			printk(KERN_ERR "cached is %d, offset %llu bytes %llu\n",
+			       block_group->cached, block_group->key.objectid,
+			       block_group->key.offset);
+			btrfs_dump_free_space(block_group, bytes);
+		} else if (info) {
+			printk(KERN_ERR "hmm, found offset=%llu bytes=%llu, "
+			       "but wanted offset=%llu bytes=%llu\n",
+			       info->offset, info->bytes, offset, bytes);
+		}
 		WARN_ON(1);
 	}
 out:
 	return ret;
 }
 
-int btrfs_add_free_space(struct btrfs_block_group_cache *block_group,
-			 u64 offset, u64 bytes)
-{
-	int ret;
-	struct btrfs_free_space *sp;
-
-	mutex_lock(&block_group->alloc_mutex);
-	ret = __btrfs_add_free_space(block_group, offset, bytes);
-	sp = tree_search_offset(&block_group->free_space_offset, offset, 0, 1);
-	BUG_ON(!sp);
-	mutex_unlock(&block_group->alloc_mutex);
-
-	return ret;
-}
-
-int btrfs_add_free_space_lock(struct btrfs_block_group_cache *block_group,
-			      u64 offset, u64 bytes)
-{
-	int ret;
-	struct btrfs_free_space *sp;
-
-	ret = __btrfs_add_free_space(block_group, offset, bytes);
-	sp = tree_search_offset(&block_group->free_space_offset, offset, 0, 1);
-	BUG_ON(!sp);
-
-	return ret;
-}
-
-int btrfs_remove_free_space(struct btrfs_block_group_cache *block_group,
-			    u64 offset, u64 bytes)
-{
-	int ret = 0;
-
-	mutex_lock(&block_group->alloc_mutex);
-	ret = __btrfs_remove_free_space(block_group, offset, bytes);
-	mutex_unlock(&block_group->alloc_mutex);
-
-	return ret;
-}
-
-int btrfs_remove_free_space_lock(struct btrfs_block_group_cache *block_group,
-				 u64 offset, u64 bytes)
-{
-	int ret;
-
-	ret = __btrfs_remove_free_space(block_group, offset, bytes);
-
-	return ret;
-}
-
 void btrfs_dump_free_space(struct btrfs_block_group_cache *block_group,
 			   u64 bytes)
 {
@@ -408,6 +357,8 @@
 		info = rb_entry(n, struct btrfs_free_space, offset_index);
 		if (info->bytes >= bytes)
 			count++;
+		printk(KERN_ERR "entry offset %llu, bytes %llu\n", info->offset,
+		       info->bytes);
 	}
 	printk(KERN_INFO "%d blocks of free space at or bigger than bytes is"
 	       "\n", count);
@@ -428,68 +379,337 @@
 	return ret;
 }
 
+/*
+ * for a given cluster, put all of its extents back into the free
+ * space cache.  If the block group passed doesn't match the block group
+ * pointed to by the cluster, someone else raced in and freed the
+ * cluster already.  In that case, we just return without changing anything
+ */
+static int
+__btrfs_return_cluster_to_free_space(
+			     struct btrfs_block_group_cache *block_group,
+			     struct btrfs_free_cluster *cluster)
+{
+	struct btrfs_free_space *entry;
+	struct rb_node *node;
+
+	spin_lock(&cluster->lock);
+	if (cluster->block_group != block_group)
+		goto out;
+
+	cluster->window_start = 0;
+	node = rb_first(&cluster->root);
+	while(node) {
+		entry = rb_entry(node, struct btrfs_free_space, offset_index);
+		node = rb_next(&entry->offset_index);
+		rb_erase(&entry->offset_index, &cluster->root);
+		link_free_space(block_group, entry);
+	}
+	list_del_init(&cluster->block_group_list);
+
+	btrfs_put_block_group(cluster->block_group);
+	cluster->block_group = NULL;
+	cluster->root.rb_node = NULL;
+out:
+	spin_unlock(&cluster->lock);
+	return 0;
+}
+
 void btrfs_remove_free_space_cache(struct btrfs_block_group_cache *block_group)
 {
 	struct btrfs_free_space *info;
 	struct rb_node *node;
+	struct btrfs_free_cluster *cluster;
+	struct btrfs_free_cluster *safe;
 
-	mutex_lock(&block_group->alloc_mutex);
+	spin_lock(&block_group->tree_lock);
+
+	list_for_each_entry_safe(cluster, safe, &block_group->cluster_list,
+				 block_group_list) {
+
+		WARN_ON(cluster->block_group != block_group);
+		__btrfs_return_cluster_to_free_space(block_group, cluster);
+	}
+
 	while ((node = rb_last(&block_group->free_space_bytes)) != NULL) {
 		info = rb_entry(node, struct btrfs_free_space, bytes_index);
 		unlink_free_space(block_group, info);
 		kfree(info);
 		if (need_resched()) {
-			mutex_unlock(&block_group->alloc_mutex);
+			spin_unlock(&block_group->tree_lock);
 			cond_resched();
-			mutex_lock(&block_group->alloc_mutex);
+			spin_lock(&block_group->tree_lock);
 		}
 	}
-	mutex_unlock(&block_group->alloc_mutex);
+	spin_unlock(&block_group->tree_lock);
 }
 
-#if 0
-static struct btrfs_free_space *btrfs_find_free_space_offset(struct
-						      btrfs_block_group_cache
-						      *block_group, u64 offset,
-						      u64 bytes)
+u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group,
+			       u64 offset, u64 bytes, u64 empty_size)
 {
-	struct btrfs_free_space *ret;
+	struct btrfs_free_space *entry = NULL;
+	u64 ret = 0;
 
-	mutex_lock(&block_group->alloc_mutex);
-	ret = tree_search_offset(&block_group->free_space_offset, offset,
-				 bytes, 0);
-	mutex_unlock(&block_group->alloc_mutex);
+	spin_lock(&block_group->tree_lock);
+	entry = tree_search_offset(&block_group->free_space_offset, offset,
+				   bytes + empty_size, 1);
+	if (!entry)
+		entry = tree_search_bytes(&block_group->free_space_bytes,
+					  offset, bytes + empty_size);
+	if (entry) {
+		unlink_free_space(block_group, entry);
+		ret = entry->offset;
+		entry->offset += bytes;
+		entry->bytes -= bytes;
+
+		if (!entry->bytes)
+			kfree(entry);
+		else
+			link_free_space(block_group, entry);
+	}
+	spin_unlock(&block_group->tree_lock);
 
 	return ret;
 }
 
-static struct btrfs_free_space *btrfs_find_free_space_bytes(struct
-						     btrfs_block_group_cache
-						     *block_group, u64 offset,
-						     u64 bytes)
+/*
+ * given a cluster, put all of its extents back into the free space
+ * cache.  If a block group is passed, this function will only free
+ * a cluster that belongs to the passed block group.
+ *
+ * Otherwise, it'll get a reference on the block group pointed to by the
+ * cluster and remove the cluster from it.
+ */
+int btrfs_return_cluster_to_free_space(
+			       struct btrfs_block_group_cache *block_group,
+			       struct btrfs_free_cluster *cluster)
 {
-	struct btrfs_free_space *ret;
+	int ret;
 
-	mutex_lock(&block_group->alloc_mutex);
+	/* first, get a safe pointer to the block group */
+	spin_lock(&cluster->lock);
+	if (!block_group) {
+		block_group = cluster->block_group;
+		if (!block_group) {
+			spin_unlock(&cluster->lock);
+			return 0;
+		}
+	} else if (cluster->block_group != block_group) {
+		/* someone else has already freed it don't redo their work */
+		spin_unlock(&cluster->lock);
+		return 0;
+	}
+	atomic_inc(&block_group->count);
+	spin_unlock(&cluster->lock);
 
-	ret = tree_search_bytes(&block_group->free_space_bytes, offset, bytes);
-	mutex_unlock(&block_group->alloc_mutex);
+	/* now return any extents the cluster had on it */
+	spin_lock(&block_group->tree_lock);
+	ret = __btrfs_return_cluster_to_free_space(block_group, cluster);
+	spin_unlock(&block_group->tree_lock);
+
+	/* finally drop our ref */
+	btrfs_put_block_group(block_group);
+	return ret;
+}
+
+/*
+ * given a cluster, try to allocate 'bytes' from it, returns 0
+ * if it couldn't find anything suitably large, or a logical disk offset
+ * if things worked out
+ */
+u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group,
+			     struct btrfs_free_cluster *cluster, u64 bytes,
+			     u64 min_start)
+{
+	struct btrfs_free_space *entry = NULL;
+	struct rb_node *node;
+	u64 ret = 0;
+
+	spin_lock(&cluster->lock);
+	if (bytes > cluster->max_size)
+		goto out;
+
+	if (cluster->block_group != block_group)
+		goto out;
+
+	node = rb_first(&cluster->root);
+	if (!node)
+		goto out;
+
+	entry = rb_entry(node, struct btrfs_free_space, offset_index);
+
+	while(1) {
+		if (entry->bytes < bytes || entry->offset < min_start) {
+			struct rb_node *node;
+
+			node = rb_next(&entry->offset_index);
+			if (!node)
+				break;
+			entry = rb_entry(node, struct btrfs_free_space,
+					 offset_index);
+			continue;
+		}
+		ret = entry->offset;
+
+		entry->offset += bytes;
+		entry->bytes -= bytes;
+
+		if (entry->bytes == 0) {
+			rb_erase(&entry->offset_index, &cluster->root);
+			kfree(entry);
+		}
+		break;
+	}
+out:
+	spin_unlock(&cluster->lock);
+	return ret;
+}
+
+/*
+ * here we try to find a cluster of blocks in a block group.  The goal
+ * is to find at least bytes free and up to empty_size + bytes free.
+ * We might not find them all in one contiguous area.
+ *
+ * returns zero and sets up cluster if things worked out, otherwise
+ * it returns -enospc
+ */
+int btrfs_find_space_cluster(struct btrfs_trans_handle *trans,
+			     struct btrfs_block_group_cache *block_group,
+			     struct btrfs_free_cluster *cluster,
+			     u64 offset, u64 bytes, u64 empty_size)
+{
+	struct btrfs_free_space *entry = NULL;
+	struct rb_node *node;
+	struct btrfs_free_space *next;
+	struct btrfs_free_space *last;
+	u64 min_bytes;
+	u64 window_start;
+	u64 window_free;
+	u64 max_extent = 0;
+	int total_retries = 0;
+	int ret;
+
+	/* for metadata, allow allocates with more holes */
+	if (block_group->flags & BTRFS_BLOCK_GROUP_METADATA) {
+		/*
+		 * we want to do larger allocations when we are
+		 * flushing out the delayed refs, it helps prevent
+		 * making more work as we go along.
+		 */
+		if (trans->transaction->delayed_refs.flushing)
+			min_bytes = max(bytes, (bytes + empty_size) >> 1);
+		else
+			min_bytes = max(bytes, (bytes + empty_size) >> 4);
+	} else
+		min_bytes = max(bytes, (bytes + empty_size) >> 2);
+
+	spin_lock(&block_group->tree_lock);
+	spin_lock(&cluster->lock);
+
+	/* someone already found a cluster, hooray */
+	if (cluster->block_group) {
+		ret = 0;
+		goto out;
+	}
+again:
+	min_bytes = min(min_bytes, bytes + empty_size);
+	entry = tree_search_bytes(&block_group->free_space_bytes,
+				  offset, min_bytes);
+	if (!entry) {
+		ret = -ENOSPC;
+		goto out;
+	}
+	window_start = entry->offset;
+	window_free = entry->bytes;
+	last = entry;
+	max_extent = entry->bytes;
+
+	while(1) {
+		/* out window is just right, lets fill it */
+		if (window_free >= bytes + empty_size)
+			break;
+
+		node = rb_next(&last->offset_index);
+		if (!node) {
+			ret = -ENOSPC;
+			goto out;
+		}
+		next = rb_entry(node, struct btrfs_free_space, offset_index);
+
+		/*
+		 * we haven't filled the empty size and the window is
+		 * very large.  reset and try again
+		 */
+		if (next->offset - window_start > (bytes + empty_size) * 2) {
+			entry = next;
+			window_start = entry->offset;
+			window_free = entry->bytes;
+			last = entry;
+			max_extent = 0;
+			total_retries++;
+			if (total_retries % 256 == 0) {
+				if (min_bytes >= (bytes + empty_size)) {
+					ret = -ENOSPC;
+					goto out;
+				}
+				/*
+				 * grow our allocation a bit, we're not having
+				 * much luck
+				 */
+				min_bytes *= 2;
+				goto again;
+			}
+		} else {
+			last = next;
+			window_free += next->bytes;
+			if (entry->bytes > max_extent)
+				max_extent = entry->bytes;
+		}
+	}
+
+	cluster->window_start = entry->offset;
+
+	/*
+	 * now we've found our entries, pull them out of the free space
+	 * cache and put them into the cluster rbtree
+	 *
+	 * The cluster includes an rbtree, but only uses the offset index
+	 * of each free space cache entry.
+	 */
+	while(1) {
+		node = rb_next(&entry->offset_index);
+		unlink_free_space(block_group, entry);
+		ret = tree_insert_offset(&cluster->root, entry->offset,
+					 &entry->offset_index);
+		BUG_ON(ret);
+
+		if (!node || entry == last)
+			break;
+
+		entry = rb_entry(node, struct btrfs_free_space, offset_index);
+	}
+	ret = 0;
+	cluster->max_size = max_extent;
+	atomic_inc(&block_group->count);
+	list_add_tail(&cluster->block_group_list, &block_group->cluster_list);
+	cluster->block_group = block_group;
+out:
+	spin_unlock(&cluster->lock);
+	spin_unlock(&block_group->tree_lock);
 
 	return ret;
 }
-#endif
 
-struct btrfs_free_space *btrfs_find_free_space(struct btrfs_block_group_cache
-					       *block_group, u64 offset,
-					       u64 bytes)
+/*
+ * simple code to zero out a cluster
+ */
+void btrfs_init_free_cluster(struct btrfs_free_cluster *cluster)
 {
-	struct btrfs_free_space *ret = NULL;
-
-	ret = tree_search_offset(&block_group->free_space_offset, offset,
-				 bytes, 0);
-	if (!ret)
-		ret = tree_search_bytes(&block_group->free_space_bytes,
-					offset, bytes);
-
-	return ret;
+	spin_lock_init(&cluster->lock);
+	spin_lock_init(&cluster->refill_lock);
+	cluster->root.rb_node = NULL;
+	cluster->max_size = 0;
+	INIT_LIST_HEAD(&cluster->block_group_list);
+	cluster->block_group = NULL;
 }
+
diff --git a/fs/btrfs/free-space-cache.h b/fs/btrfs/free-space-cache.h
new file mode 100644
index 0000000..ab0bdc0
--- /dev/null
+++ b/fs/btrfs/free-space-cache.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009 Oracle.  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 v2 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, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+
+#ifndef __BTRFS_FREE_SPACE_CACHE
+#define __BTRFS_FREE_SPACE_CACHE
+
+int btrfs_add_free_space(struct btrfs_block_group_cache *block_group,
+			 u64 bytenr, u64 size);
+int btrfs_remove_free_space(struct btrfs_block_group_cache *block_group,
+			    u64 bytenr, u64 size);
+void btrfs_remove_free_space_cache(struct btrfs_block_group_cache
+				   *block_group);
+u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group,
+			       u64 offset, u64 bytes, u64 empty_size);
+void btrfs_dump_free_space(struct btrfs_block_group_cache *block_group,
+			   u64 bytes);
+u64 btrfs_block_group_free_space(struct btrfs_block_group_cache *block_group);
+int btrfs_find_space_cluster(struct btrfs_trans_handle *trans,
+			     struct btrfs_block_group_cache *block_group,
+			     struct btrfs_free_cluster *cluster,
+			     u64 offset, u64 bytes, u64 empty_size);
+void btrfs_init_free_cluster(struct btrfs_free_cluster *cluster);
+u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group,
+			     struct btrfs_free_cluster *cluster, u64 bytes,
+			     u64 min_start);
+int btrfs_return_cluster_to_free_space(
+			       struct btrfs_block_group_cache *block_group,
+			       struct btrfs_free_cluster *cluster);
+#endif
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 06d8db5..a0d1dd4 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3481,8 +3481,10 @@
 
 	if (dir) {
 		ret = btrfs_set_inode_index(dir, index);
-		if (ret)
+		if (ret) {
+			iput(inode);
 			return ERR_PTR(ret);
+		}
 	}
 	/*
 	 * index_cnt is ignored for everything but a dir,
@@ -3565,6 +3567,7 @@
 	if (dir)
 		BTRFS_I(dir)->index_cnt--;
 	btrfs_free_path(path);
+	iput(inode);
 	return ERR_PTR(ret);
 }
 
diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c
index a5310c0..1c36e5c 100644
--- a/fs/btrfs/locking.c
+++ b/fs/btrfs/locking.c
@@ -60,8 +60,8 @@
 
 /*
  * unfortunately, many of the places that currently set a lock to blocking
- * don't end up blocking for every long, and often they don't block
- * at all.  For a dbench 50 run, if we don't spin one the blocking bit
+ * don't end up blocking for very long, and often they don't block
+ * at all.  For a dbench 50 run, if we don't spin on the blocking bit
  * at all, the context switch rate can jump up to 400,000/sec or more.
  *
  * So, we're still stuck with this crummy spin on the blocking bit,
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 19a4daf..9744af9 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -24,6 +24,7 @@
 #include <linux/highmem.h>
 #include <linux/time.h>
 #include <linux/init.h>
+#include <linux/seq_file.h>
 #include <linux/string.h>
 #include <linux/smp_lock.h>
 #include <linux/backing-dev.h>
@@ -66,7 +67,8 @@
 enum {
 	Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow,
 	Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier,
-	Opt_ssd, Opt_thread_pool, Opt_noacl,  Opt_compress, Opt_err,
+	Opt_ssd, Opt_thread_pool, Opt_noacl,  Opt_compress, Opt_notreelog,
+	Opt_flushoncommit, Opt_err,
 };
 
 static match_table_t tokens = {
@@ -83,6 +85,8 @@
 	{Opt_compress, "compress"},
 	{Opt_ssd, "ssd"},
 	{Opt_noacl, "noacl"},
+	{Opt_notreelog, "notreelog"},
+	{Opt_flushoncommit, "flushoncommit"},
 	{Opt_err, NULL},
 };
 
@@ -222,6 +226,14 @@
 		case Opt_noacl:
 			root->fs_info->sb->s_flags &= ~MS_POSIXACL;
 			break;
+		case Opt_notreelog:
+			printk(KERN_INFO "btrfs: disabling tree log\n");
+			btrfs_set_opt(info->mount_opt, NOTREELOG);
+			break;
+		case Opt_flushoncommit:
+			printk(KERN_INFO "btrfs: turning on flush-on-commit\n");
+			btrfs_set_opt(info->mount_opt, FLUSHONCOMMIT);
+			break;
 		default:
 			break;
 		}
@@ -363,9 +375,8 @@
 int btrfs_sync_fs(struct super_block *sb, int wait)
 {
 	struct btrfs_trans_handle *trans;
-	struct btrfs_root *root;
+	struct btrfs_root *root = btrfs_sb(sb);
 	int ret;
-	root = btrfs_sb(sb);
 
 	if (sb->s_flags & MS_RDONLY)
 		return 0;
@@ -385,6 +396,41 @@
 	return ret;
 }
 
+static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
+{
+	struct btrfs_root *root = btrfs_sb(vfs->mnt_sb);
+	struct btrfs_fs_info *info = root->fs_info;
+
+	if (btrfs_test_opt(root, DEGRADED))
+		seq_puts(seq, ",degraded");
+	if (btrfs_test_opt(root, NODATASUM))
+		seq_puts(seq, ",nodatasum");
+	if (btrfs_test_opt(root, NODATACOW))
+		seq_puts(seq, ",nodatacow");
+	if (btrfs_test_opt(root, NOBARRIER))
+		seq_puts(seq, ",nobarrier");
+	if (info->max_extent != (u64)-1)
+		seq_printf(seq, ",max_extent=%llu", info->max_extent);
+	if (info->max_inline != 8192 * 1024)
+		seq_printf(seq, ",max_inline=%llu", info->max_inline);
+	if (info->alloc_start != 0)
+		seq_printf(seq, ",alloc_start=%llu", info->alloc_start);
+	if (info->thread_pool_size !=  min_t(unsigned long,
+					     num_online_cpus() + 2, 8))
+		seq_printf(seq, ",thread_pool=%d", info->thread_pool_size);
+	if (btrfs_test_opt(root, COMPRESS))
+		seq_puts(seq, ",compress");
+	if (btrfs_test_opt(root, SSD))
+		seq_puts(seq, ",ssd");
+	if (btrfs_test_opt(root, NOTREELOG))
+		seq_puts(seq, ",no-treelog");
+	if (btrfs_test_opt(root, FLUSHONCOMMIT))
+		seq_puts(seq, ",flush-on-commit");
+	if (!(root->fs_info->sb->s_flags & MS_POSIXACL))
+		seq_puts(seq, ",noacl");
+	return 0;
+}
+
 static void btrfs_write_super(struct super_block *sb)
 {
 	sb->s_dirt = 0;
@@ -630,7 +676,7 @@
 	.put_super	= btrfs_put_super,
 	.write_super	= btrfs_write_super,
 	.sync_fs	= btrfs_sync_fs,
-	.show_options	= generic_show_options,
+	.show_options	= btrfs_show_options,
 	.write_inode	= btrfs_write_inode,
 	.dirty_inode	= btrfs_dirty_inode,
 	.alloc_inode	= btrfs_alloc_inode,
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 664782c..2869b33 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -53,8 +53,6 @@
 					     GFP_NOFS);
 		BUG_ON(!cur_trans);
 		root->fs_info->generation++;
-		root->fs_info->last_alloc = 0;
-		root->fs_info->last_data_alloc = 0;
 		cur_trans->num_writers = 1;
 		cur_trans->num_joined = 0;
 		cur_trans->transid = root->fs_info->generation;
@@ -974,6 +972,7 @@
 	int ret;
 	int should_grow = 0;
 	unsigned long now = get_seconds();
+	int flush_on_commit = btrfs_test_opt(root, FLUSHONCOMMIT);
 
 	btrfs_run_ordered_operations(root, 0);
 
@@ -1053,7 +1052,9 @@
 
 		mutex_unlock(&root->fs_info->trans_mutex);
 
-		if (snap_pending) {
+		if (flush_on_commit || snap_pending) {
+			if (flush_on_commit)
+				btrfs_start_delalloc_inodes(root);
 			ret = btrfs_wait_ordered_extents(root, 1);
 			BUG_ON(ret);
 		}
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index fc9b87a..25f20ea 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -262,11 +262,9 @@
 			      struct extent_buffer *eb,
 			      struct walk_control *wc, u64 gen)
 {
-	if (wc->pin) {
-		mutex_lock(&log->fs_info->pinned_mutex);
+	if (wc->pin)
 		btrfs_update_pinned_extents(log->fs_info->extent_root,
 					    eb->start, eb->len, 1);
-	}
 
 	if (btrfs_buffer_uptodate(eb, gen)) {
 		if (wc->write)
@@ -1224,8 +1222,7 @@
 	ret = insert_one_name(trans, root, path, key->objectid, key->offset,
 			      name, name_len, log_type, &log_key);
 
-	if (ret && ret != -ENOENT)
-		BUG();
+	BUG_ON(ret && ret != -ENOENT);
 	goto out;
 }
 
@@ -2900,6 +2897,11 @@
 
 	sb = inode->i_sb;
 
+	if (btrfs_test_opt(root, NOTREELOG)) {
+		ret = 1;
+		goto end_no_trans;
+	}
+
 	if (root->fs_info->last_trans_log_full_commit >
 	    root->fs_info->last_trans_committed) {
 		ret = 1;
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index dd06e18..e0913e4 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -20,6 +20,7 @@
 #include <linux/buffer_head.h>
 #include <linux/blkdev.h>
 #include <linux/random.h>
+#include <linux/iocontext.h>
 #include <asm/div64.h>
 #include "compat.h"
 #include "ctree.h"
@@ -145,8 +146,9 @@
 	int again = 0;
 	unsigned long num_run = 0;
 	unsigned long limit;
+	unsigned long last_waited = 0;
 
-	bdi = device->bdev->bd_inode->i_mapping->backing_dev_info;
+	bdi = blk_get_backing_dev_info(device->bdev);
 	fs_info = device->dev_root->fs_info;
 	limit = btrfs_async_submit_limit(fs_info);
 	limit = limit * 2 / 3;
@@ -207,7 +209,32 @@
 		if (pending && bdi_write_congested(bdi) && num_run > 16 &&
 		    fs_info->fs_devices->open_devices > 1) {
 			struct bio *old_head;
+			struct io_context *ioc;
 
+			ioc = current->io_context;
+
+			/*
+			 * the main goal here is that we don't want to
+			 * block if we're going to be able to submit
+			 * more requests without blocking.
+			 *
+			 * This code does two great things, it pokes into
+			 * the elevator code from a filesystem _and_
+			 * it makes assumptions about how batching works.
+			 */
+			if (ioc && ioc->nr_batch_requests > 0 &&
+			    time_before(jiffies, ioc->last_waited + HZ/50UL) &&
+			    (last_waited == 0 ||
+			     ioc->last_waited == last_waited)) {
+				/*
+				 * we want to go through our batch of
+				 * requests and stop.  So, we copy out
+				 * the ioc->last_waited time and test
+				 * against it before looping
+				 */
+				last_waited = ioc->last_waited;
+				continue;
+			}
 			spin_lock(&device->io_lock);
 
 			old_head = device->pending_bios;
@@ -231,6 +258,18 @@
 	if (device->pending_bios)
 		goto loop_lock;
 	spin_unlock(&device->io_lock);
+
+	/*
+	 * IO has already been through a long path to get here.  Checksumming,
+	 * async helper threads, perhaps compression.  We've done a pretty
+	 * good job of collecting a batch of IO and should just unplug
+	 * the device right away.
+	 *
+	 * This will help anyone who is waiting on the IO, they might have
+	 * already unplugged, but managed to do so before the bio they
+	 * cared about found its way down here.
+	 */
+	blk_run_backing_dev(bdi, NULL);
 done:
 	return 0;
 }
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index 86c44e9..2185de7 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -76,7 +76,7 @@
 struct btrfs_fs_devices {
 	u8 fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */
 
-	/* the device with this id has the most recent coyp of the super */
+	/* the device with this id has the most recent copy of the super */
 	u64 latest_devid;
 	u64 latest_trans;
 	u64 num_devices;
diff --git a/fs/buffer.c b/fs/buffer.c
index c2fa1be..6e35762 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -737,7 +737,7 @@
 {
 	struct buffer_head *bh;
 	struct list_head tmp;
-	struct address_space *mapping;
+	struct address_space *mapping, *prev_mapping = NULL;
 	int err = 0, err2;
 
 	INIT_LIST_HEAD(&tmp);
@@ -762,7 +762,18 @@
 				 * contents - it is a noop if I/O is still in
 				 * flight on potentially older contents.
 				 */
-				ll_rw_block(SWRITE_SYNC, 1, &bh);
+				ll_rw_block(SWRITE_SYNC_PLUG, 1, &bh);
+
+				/*
+				 * Kick off IO for the previous mapping. Note
+				 * that we will not run the very last mapping,
+				 * wait_on_buffer() will do that for us
+				 * through sync_buffer().
+				 */
+				if (prev_mapping && prev_mapping != mapping)
+					blk_run_address_space(prev_mapping);
+				prev_mapping = mapping;
+
 				brelse(bh);
 				spin_lock(lock);
 			}
@@ -1595,6 +1606,7 @@
 	struct buffer_head *bh, *head;
 	const unsigned blocksize = 1 << inode->i_blkbits;
 	int nr_underway = 0;
+	int write_op = (wbc->sync_mode == WB_SYNC_ALL ? WRITE_SYNC : WRITE);
 
 	BUG_ON(!PageLocked(page));
 
@@ -1686,7 +1698,7 @@
 	do {
 		struct buffer_head *next = bh->b_this_page;
 		if (buffer_async_write(bh)) {
-			submit_bh(WRITE, bh);
+			submit_bh(write_op, bh);
 			nr_underway++;
 		}
 		bh = next;
@@ -1740,7 +1752,7 @@
 		struct buffer_head *next = bh->b_this_page;
 		if (buffer_async_write(bh)) {
 			clear_buffer_dirty(bh);
-			submit_bh(WRITE, bh);
+			submit_bh(write_op, bh);
 			nr_underway++;
 		}
 		bh = next;
@@ -2956,12 +2968,13 @@
 	for (i = 0; i < nr; i++) {
 		struct buffer_head *bh = bhs[i];
 
-		if (rw == SWRITE || rw == SWRITE_SYNC)
+		if (rw == SWRITE || rw == SWRITE_SYNC || rw == SWRITE_SYNC_PLUG)
 			lock_buffer(bh);
 		else if (!trylock_buffer(bh))
 			continue;
 
-		if (rw == WRITE || rw == SWRITE || rw == SWRITE_SYNC) {
+		if (rw == WRITE || rw == SWRITE || rw == SWRITE_SYNC ||
+		    rw == SWRITE_SYNC_PLUG) {
 			if (test_clear_buffer_dirty(bh)) {
 				bh->b_end_io = end_buffer_write_sync;
 				get_bh(bh);
@@ -2997,7 +3010,7 @@
 	if (test_clear_buffer_dirty(bh)) {
 		get_bh(bh);
 		bh->b_end_io = end_buffer_write_sync;
-		ret = submit_bh(WRITE, bh);
+		ret = submit_bh(WRITE_SYNC, bh);
 		wait_on_buffer(bh);
 		if (buffer_eopnotsupp(bh)) {
 			clear_buffer_eopnotsupp(bh);
diff --git a/fs/cachefiles/Kconfig b/fs/cachefiles/Kconfig
new file mode 100644
index 0000000..80e9c61
--- /dev/null
+++ b/fs/cachefiles/Kconfig
@@ -0,0 +1,39 @@
+
+config CACHEFILES
+	tristate "Filesystem caching on files"
+	depends on FSCACHE && BLOCK
+	help
+	  This permits use of a mounted filesystem as a cache for other
+	  filesystems - primarily networking filesystems - thus allowing fast
+	  local disk to enhance the speed of slower devices.
+
+	  See Documentation/filesystems/caching/cachefiles.txt for more
+	  information.
+
+config CACHEFILES_DEBUG
+	bool "Debug CacheFiles"
+	depends on CACHEFILES
+	help
+	  This permits debugging to be dynamically enabled in the filesystem
+	  caching on files module.  If this is set, the debugging output may be
+	  enabled by setting bits in /sys/modules/cachefiles/parameter/debug or
+	  by including a debugging specifier in /etc/cachefilesd.conf.
+
+config CACHEFILES_HISTOGRAM
+	bool "Gather latency information on CacheFiles"
+	depends on CACHEFILES && PROC_FS
+	help
+
+	  This option causes latency information to be gathered on CacheFiles
+	  operation and exported through file:
+
+		/proc/fs/cachefiles/histogram
+
+	  The generation of this histogram adds a certain amount of overhead to
+	  execution as there are a number of points at which data is gathered,
+	  and on a multi-CPU system these may be on cachelines that keep
+	  bouncing between CPUs.  On the other hand, the histogram may be
+	  useful for debugging purposes.  Saying 'N' here is recommended.
+
+	  See Documentation/filesystems/caching/cachefiles.txt for more
+	  information.
diff --git a/fs/cachefiles/Makefile b/fs/cachefiles/Makefile
new file mode 100644
index 0000000..32cbab0
--- /dev/null
+++ b/fs/cachefiles/Makefile
@@ -0,0 +1,18 @@
+#
+# Makefile for caching in a mounted filesystem
+#
+
+cachefiles-y := \
+	bind.o \
+	daemon.o \
+	interface.o \
+	key.o \
+	main.o \
+	namei.o \
+	rdwr.o \
+	security.o \
+	xattr.o
+
+cachefiles-$(CONFIG_CACHEFILES_HISTOGRAM) += proc.o
+
+obj-$(CONFIG_CACHEFILES) := cachefiles.o
diff --git a/fs/cachefiles/bind.c b/fs/cachefiles/bind.c
new file mode 100644
index 0000000..3797e00
--- /dev/null
+++ b/fs/cachefiles/bind.c
@@ -0,0 +1,286 @@
+/* Bind and unbind a cache from the filesystem backing it
+ *
+ * Copyright (C) 2007 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 <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/completion.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/namei.h>
+#include <linux/mount.h>
+#include <linux/statfs.h>
+#include <linux/ctype.h>
+#include "internal.h"
+
+static int cachefiles_daemon_add_cache(struct cachefiles_cache *caches);
+
+/*
+ * bind a directory as a cache
+ */
+int cachefiles_daemon_bind(struct cachefiles_cache *cache, char *args)
+{
+	_enter("{%u,%u,%u,%u,%u,%u},%s",
+	       cache->frun_percent,
+	       cache->fcull_percent,
+	       cache->fstop_percent,
+	       cache->brun_percent,
+	       cache->bcull_percent,
+	       cache->bstop_percent,
+	       args);
+
+	/* start by checking things over */
+	ASSERT(cache->fstop_percent >= 0 &&
+	       cache->fstop_percent < cache->fcull_percent &&
+	       cache->fcull_percent < cache->frun_percent &&
+	       cache->frun_percent  < 100);
+
+	ASSERT(cache->bstop_percent >= 0 &&
+	       cache->bstop_percent < cache->bcull_percent &&
+	       cache->bcull_percent < cache->brun_percent &&
+	       cache->brun_percent  < 100);
+
+	if (*args) {
+		kerror("'bind' command doesn't take an argument");
+		return -EINVAL;
+	}
+
+	if (!cache->rootdirname) {
+		kerror("No cache directory specified");
+		return -EINVAL;
+	}
+
+	/* don't permit already bound caches to be re-bound */
+	if (test_bit(CACHEFILES_READY, &cache->flags)) {
+		kerror("Cache already bound");
+		return -EBUSY;
+	}
+
+	/* make sure we have copies of the tag and dirname strings */
+	if (!cache->tag) {
+		/* the tag string is released by the fops->release()
+		 * function, so we don't release it on error here */
+		cache->tag = kstrdup("CacheFiles", GFP_KERNEL);
+		if (!cache->tag)
+			return -ENOMEM;
+	}
+
+	/* add the cache */
+	return cachefiles_daemon_add_cache(cache);
+}
+
+/*
+ * add a cache
+ */
+static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache)
+{
+	struct cachefiles_object *fsdef;
+	struct nameidata nd;
+	struct kstatfs stats;
+	struct dentry *graveyard, *cachedir, *root;
+	const struct cred *saved_cred;
+	int ret;
+
+	_enter("");
+
+	/* we want to work under the module's security ID */
+	ret = cachefiles_get_security_ID(cache);
+	if (ret < 0)
+		return ret;
+
+	cachefiles_begin_secure(cache, &saved_cred);
+
+	/* allocate the root index object */
+	ret = -ENOMEM;
+
+	fsdef = kmem_cache_alloc(cachefiles_object_jar, GFP_KERNEL);
+	if (!fsdef)
+		goto error_root_object;
+
+	ASSERTCMP(fsdef->backer, ==, NULL);
+
+	atomic_set(&fsdef->usage, 1);
+	fsdef->type = FSCACHE_COOKIE_TYPE_INDEX;
+
+	_debug("- fsdef %p", fsdef);
+
+	/* look up the directory at the root of the cache */
+	memset(&nd, 0, sizeof(nd));
+
+	ret = path_lookup(cache->rootdirname, LOOKUP_DIRECTORY, &nd);
+	if (ret < 0)
+		goto error_open_root;
+
+	cache->mnt = mntget(nd.path.mnt);
+	root = dget(nd.path.dentry);
+	path_put(&nd.path);
+
+	/* check parameters */
+	ret = -EOPNOTSUPP;
+	if (!root->d_inode ||
+	    !root->d_inode->i_op ||
+	    !root->d_inode->i_op->lookup ||
+	    !root->d_inode->i_op->mkdir ||
+	    !root->d_inode->i_op->setxattr ||
+	    !root->d_inode->i_op->getxattr ||
+	    !root->d_sb ||
+	    !root->d_sb->s_op ||
+	    !root->d_sb->s_op->statfs ||
+	    !root->d_sb->s_op->sync_fs)
+		goto error_unsupported;
+
+	ret = -EROFS;
+	if (root->d_sb->s_flags & MS_RDONLY)
+		goto error_unsupported;
+
+	/* determine the security of the on-disk cache as this governs
+	 * security ID of files we create */
+	ret = cachefiles_determine_cache_security(cache, root, &saved_cred);
+	if (ret < 0)
+		goto error_unsupported;
+
+	/* get the cache size and blocksize */
+	ret = vfs_statfs(root, &stats);
+	if (ret < 0)
+		goto error_unsupported;
+
+	ret = -ERANGE;
+	if (stats.f_bsize <= 0)
+		goto error_unsupported;
+
+	ret = -EOPNOTSUPP;
+	if (stats.f_bsize > PAGE_SIZE)
+		goto error_unsupported;
+
+	cache->bsize = stats.f_bsize;
+	cache->bshift = 0;
+	if (stats.f_bsize < PAGE_SIZE)
+		cache->bshift = PAGE_SHIFT - ilog2(stats.f_bsize);
+
+	_debug("blksize %u (shift %u)",
+	       cache->bsize, cache->bshift);
+
+	_debug("size %llu, avail %llu",
+	       (unsigned long long) stats.f_blocks,
+	       (unsigned long long) stats.f_bavail);
+
+	/* set up caching limits */
+	do_div(stats.f_files, 100);
+	cache->fstop = stats.f_files * cache->fstop_percent;
+	cache->fcull = stats.f_files * cache->fcull_percent;
+	cache->frun  = stats.f_files * cache->frun_percent;
+
+	_debug("limits {%llu,%llu,%llu} files",
+	       (unsigned long long) cache->frun,
+	       (unsigned long long) cache->fcull,
+	       (unsigned long long) cache->fstop);
+
+	stats.f_blocks >>= cache->bshift;
+	do_div(stats.f_blocks, 100);
+	cache->bstop = stats.f_blocks * cache->bstop_percent;
+	cache->bcull = stats.f_blocks * cache->bcull_percent;
+	cache->brun  = stats.f_blocks * cache->brun_percent;
+
+	_debug("limits {%llu,%llu,%llu} blocks",
+	       (unsigned long long) cache->brun,
+	       (unsigned long long) cache->bcull,
+	       (unsigned long long) cache->bstop);
+
+	/* get the cache directory and check its type */
+	cachedir = cachefiles_get_directory(cache, root, "cache");
+	if (IS_ERR(cachedir)) {
+		ret = PTR_ERR(cachedir);
+		goto error_unsupported;
+	}
+
+	fsdef->dentry = cachedir;
+	fsdef->fscache.cookie = NULL;
+
+	ret = cachefiles_check_object_type(fsdef);
+	if (ret < 0)
+		goto error_unsupported;
+
+	/* get the graveyard directory */
+	graveyard = cachefiles_get_directory(cache, root, "graveyard");
+	if (IS_ERR(graveyard)) {
+		ret = PTR_ERR(graveyard);
+		goto error_unsupported;
+	}
+
+	cache->graveyard = graveyard;
+
+	/* publish the cache */
+	fscache_init_cache(&cache->cache,
+			   &cachefiles_cache_ops,
+			   "%s",
+			   fsdef->dentry->d_sb->s_id);
+
+	fscache_object_init(&fsdef->fscache, NULL, &cache->cache);
+
+	ret = fscache_add_cache(&cache->cache, &fsdef->fscache, cache->tag);
+	if (ret < 0)
+		goto error_add_cache;
+
+	/* done */
+	set_bit(CACHEFILES_READY, &cache->flags);
+	dput(root);
+
+	printk(KERN_INFO "CacheFiles:"
+	       " File cache on %s registered\n",
+	       cache->cache.identifier);
+
+	/* check how much space the cache has */
+	cachefiles_has_space(cache, 0, 0);
+	cachefiles_end_secure(cache, saved_cred);
+	return 0;
+
+error_add_cache:
+	dput(cache->graveyard);
+	cache->graveyard = NULL;
+error_unsupported:
+	mntput(cache->mnt);
+	cache->mnt = NULL;
+	dput(fsdef->dentry);
+	fsdef->dentry = NULL;
+	dput(root);
+error_open_root:
+	kmem_cache_free(cachefiles_object_jar, fsdef);
+error_root_object:
+	cachefiles_end_secure(cache, saved_cred);
+	kerror("Failed to register: %d", ret);
+	return ret;
+}
+
+/*
+ * unbind a cache on fd release
+ */
+void cachefiles_daemon_unbind(struct cachefiles_cache *cache)
+{
+	_enter("");
+
+	if (test_bit(CACHEFILES_READY, &cache->flags)) {
+		printk(KERN_INFO "CacheFiles:"
+		       " File cache on %s unregistering\n",
+		       cache->cache.identifier);
+
+		fscache_withdraw_cache(&cache->cache);
+	}
+
+	dput(cache->graveyard);
+	mntput(cache->mnt);
+
+	kfree(cache->rootdirname);
+	kfree(cache->secctx);
+	kfree(cache->tag);
+
+	_leave("");
+}
diff --git a/fs/cachefiles/daemon.c b/fs/cachefiles/daemon.c
new file mode 100644
index 0000000..4618516
--- /dev/null
+++ b/fs/cachefiles/daemon.c
@@ -0,0 +1,755 @@
+/* Daemon interface
+ *
+ * Copyright (C) 2007 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 <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/completion.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/namei.h>
+#include <linux/poll.h>
+#include <linux/mount.h>
+#include <linux/statfs.h>
+#include <linux/ctype.h>
+#include <linux/fs_struct.h>
+#include "internal.h"
+
+static int cachefiles_daemon_open(struct inode *, struct file *);
+static int cachefiles_daemon_release(struct inode *, struct file *);
+static ssize_t cachefiles_daemon_read(struct file *, char __user *, size_t,
+				      loff_t *);
+static ssize_t cachefiles_daemon_write(struct file *, const char __user *,
+				       size_t, loff_t *);
+static unsigned int cachefiles_daemon_poll(struct file *,
+					   struct poll_table_struct *);
+static int cachefiles_daemon_frun(struct cachefiles_cache *, char *);
+static int cachefiles_daemon_fcull(struct cachefiles_cache *, char *);
+static int cachefiles_daemon_fstop(struct cachefiles_cache *, char *);
+static int cachefiles_daemon_brun(struct cachefiles_cache *, char *);
+static int cachefiles_daemon_bcull(struct cachefiles_cache *, char *);
+static int cachefiles_daemon_bstop(struct cachefiles_cache *, char *);
+static int cachefiles_daemon_cull(struct cachefiles_cache *, char *);
+static int cachefiles_daemon_debug(struct cachefiles_cache *, char *);
+static int cachefiles_daemon_dir(struct cachefiles_cache *, char *);
+static int cachefiles_daemon_inuse(struct cachefiles_cache *, char *);
+static int cachefiles_daemon_secctx(struct cachefiles_cache *, char *);
+static int cachefiles_daemon_tag(struct cachefiles_cache *, char *);
+
+static unsigned long cachefiles_open;
+
+const struct file_operations cachefiles_daemon_fops = {
+	.owner		= THIS_MODULE,
+	.open		= cachefiles_daemon_open,
+	.release	= cachefiles_daemon_release,
+	.read		= cachefiles_daemon_read,
+	.write		= cachefiles_daemon_write,
+	.poll		= cachefiles_daemon_poll,
+};
+
+struct cachefiles_daemon_cmd {
+	char name[8];
+	int (*handler)(struct cachefiles_cache *cache, char *args);
+};
+
+static const struct cachefiles_daemon_cmd cachefiles_daemon_cmds[] = {
+	{ "bind",	cachefiles_daemon_bind		},
+	{ "brun",	cachefiles_daemon_brun		},
+	{ "bcull",	cachefiles_daemon_bcull		},
+	{ "bstop",	cachefiles_daemon_bstop		},
+	{ "cull",	cachefiles_daemon_cull		},
+	{ "debug",	cachefiles_daemon_debug		},
+	{ "dir",	cachefiles_daemon_dir		},
+	{ "frun",	cachefiles_daemon_frun		},
+	{ "fcull",	cachefiles_daemon_fcull		},
+	{ "fstop",	cachefiles_daemon_fstop		},
+	{ "inuse",	cachefiles_daemon_inuse		},
+	{ "secctx",	cachefiles_daemon_secctx	},
+	{ "tag",	cachefiles_daemon_tag		},
+	{ "",		NULL				}
+};
+
+
+/*
+ * do various checks
+ */
+static int cachefiles_daemon_open(struct inode *inode, struct file *file)
+{
+	struct cachefiles_cache *cache;
+
+	_enter("");
+
+	/* only the superuser may do this */
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	/* the cachefiles device may only be open once at a time */
+	if (xchg(&cachefiles_open, 1) == 1)
+		return -EBUSY;
+
+	/* allocate a cache record */
+	cache = kzalloc(sizeof(struct cachefiles_cache), GFP_KERNEL);
+	if (!cache) {
+		cachefiles_open = 0;
+		return -ENOMEM;
+	}
+
+	mutex_init(&cache->daemon_mutex);
+	cache->active_nodes = RB_ROOT;
+	rwlock_init(&cache->active_lock);
+	init_waitqueue_head(&cache->daemon_pollwq);
+
+	/* set default caching limits
+	 * - limit at 1% free space and/or free files
+	 * - cull below 5% free space and/or free files
+	 * - cease culling above 7% free space and/or free files
+	 */
+	cache->frun_percent = 7;
+	cache->fcull_percent = 5;
+	cache->fstop_percent = 1;
+	cache->brun_percent = 7;
+	cache->bcull_percent = 5;
+	cache->bstop_percent = 1;
+
+	file->private_data = cache;
+	cache->cachefilesd = file;
+	return 0;
+}
+
+/*
+ * release a cache
+ */
+static int cachefiles_daemon_release(struct inode *inode, struct file *file)
+{
+	struct cachefiles_cache *cache = file->private_data;
+
+	_enter("");
+
+	ASSERT(cache);
+
+	set_bit(CACHEFILES_DEAD, &cache->flags);
+
+	cachefiles_daemon_unbind(cache);
+
+	ASSERT(!cache->active_nodes.rb_node);
+
+	/* clean up the control file interface */
+	cache->cachefilesd = NULL;
+	file->private_data = NULL;
+	cachefiles_open = 0;
+
+	kfree(cache);
+
+	_leave("");
+	return 0;
+}
+
+/*
+ * read the cache state
+ */
+static ssize_t cachefiles_daemon_read(struct file *file, char __user *_buffer,
+				      size_t buflen, loff_t *pos)
+{
+	struct cachefiles_cache *cache = file->private_data;
+	char buffer[256];
+	int n;
+
+	//_enter(",,%zu,", buflen);
+
+	if (!test_bit(CACHEFILES_READY, &cache->flags))
+		return 0;
+
+	/* check how much space the cache has */
+	cachefiles_has_space(cache, 0, 0);
+
+	/* summarise */
+	clear_bit(CACHEFILES_STATE_CHANGED, &cache->flags);
+
+	n = snprintf(buffer, sizeof(buffer),
+		     "cull=%c"
+		     " frun=%llx"
+		     " fcull=%llx"
+		     " fstop=%llx"
+		     " brun=%llx"
+		     " bcull=%llx"
+		     " bstop=%llx",
+		     test_bit(CACHEFILES_CULLING, &cache->flags) ? '1' : '0',
+		     (unsigned long long) cache->frun,
+		     (unsigned long long) cache->fcull,
+		     (unsigned long long) cache->fstop,
+		     (unsigned long long) cache->brun,
+		     (unsigned long long) cache->bcull,
+		     (unsigned long long) cache->bstop
+		     );
+
+	if (n > buflen)
+		return -EMSGSIZE;
+
+	if (copy_to_user(_buffer, buffer, n) != 0)
+		return -EFAULT;
+
+	return n;
+}
+
+/*
+ * command the cache
+ */
+static ssize_t cachefiles_daemon_write(struct file *file,
+				       const char __user *_data,
+				       size_t datalen,
+				       loff_t *pos)
+{
+	const struct cachefiles_daemon_cmd *cmd;
+	struct cachefiles_cache *cache = file->private_data;
+	ssize_t ret;
+	char *data, *args, *cp;
+
+	//_enter(",,%zu,", datalen);
+
+	ASSERT(cache);
+
+	if (test_bit(CACHEFILES_DEAD, &cache->flags))
+		return -EIO;
+
+	if (datalen < 0 || datalen > PAGE_SIZE - 1)
+		return -EOPNOTSUPP;
+
+	/* drag the command string into the kernel so we can parse it */
+	data = kmalloc(datalen + 1, GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	ret = -EFAULT;
+	if (copy_from_user(data, _data, datalen) != 0)
+		goto error;
+
+	data[datalen] = '\0';
+
+	ret = -EINVAL;
+	if (memchr(data, '\0', datalen))
+		goto error;
+
+	/* strip any newline */
+	cp = memchr(data, '\n', datalen);
+	if (cp) {
+		if (cp == data)
+			goto error;
+
+		*cp = '\0';
+	}
+
+	/* parse the command */
+	ret = -EOPNOTSUPP;
+
+	for (args = data; *args; args++)
+		if (isspace(*args))
+			break;
+	if (*args) {
+		if (args == data)
+			goto error;
+		*args = '\0';
+		for (args++; isspace(*args); args++)
+			continue;
+	}
+
+	/* run the appropriate command handler */
+	for (cmd = cachefiles_daemon_cmds; cmd->name[0]; cmd++)
+		if (strcmp(cmd->name, data) == 0)
+			goto found_command;
+
+error:
+	kfree(data);
+	//_leave(" = %zd", ret);
+	return ret;
+
+found_command:
+	mutex_lock(&cache->daemon_mutex);
+
+	ret = -EIO;
+	if (!test_bit(CACHEFILES_DEAD, &cache->flags))
+		ret = cmd->handler(cache, args);
+
+	mutex_unlock(&cache->daemon_mutex);
+
+	if (ret == 0)
+		ret = datalen;
+	goto error;
+}
+
+/*
+ * poll for culling state
+ * - use POLLOUT to indicate culling state
+ */
+static unsigned int cachefiles_daemon_poll(struct file *file,
+					   struct poll_table_struct *poll)
+{
+	struct cachefiles_cache *cache = file->private_data;
+	unsigned int mask;
+
+	poll_wait(file, &cache->daemon_pollwq, poll);
+	mask = 0;
+
+	if (test_bit(CACHEFILES_STATE_CHANGED, &cache->flags))
+		mask |= POLLIN;
+
+	if (test_bit(CACHEFILES_CULLING, &cache->flags))
+		mask |= POLLOUT;
+
+	return mask;
+}
+
+/*
+ * give a range error for cache space constraints
+ * - can be tail-called
+ */
+static int cachefiles_daemon_range_error(struct cachefiles_cache *cache,
+					 char *args)
+{
+	kerror("Free space limits must be in range"
+	       " 0%%<=stop<cull<run<100%%");
+
+	return -EINVAL;
+}
+
+/*
+ * set the percentage of files at which to stop culling
+ * - command: "frun <N>%"
+ */
+static int cachefiles_daemon_frun(struct cachefiles_cache *cache, char *args)
+{
+	unsigned long frun;
+
+	_enter(",%s", args);
+
+	if (!*args)
+		return -EINVAL;
+
+	frun = simple_strtoul(args, &args, 10);
+	if (args[0] != '%' || args[1] != '\0')
+		return -EINVAL;
+
+	if (frun <= cache->fcull_percent || frun >= 100)
+		return cachefiles_daemon_range_error(cache, args);
+
+	cache->frun_percent = frun;
+	return 0;
+}
+
+/*
+ * set the percentage of files at which to start culling
+ * - command: "fcull <N>%"
+ */
+static int cachefiles_daemon_fcull(struct cachefiles_cache *cache, char *args)
+{
+	unsigned long fcull;
+
+	_enter(",%s", args);
+
+	if (!*args)
+		return -EINVAL;
+
+	fcull = simple_strtoul(args, &args, 10);
+	if (args[0] != '%' || args[1] != '\0')
+		return -EINVAL;
+
+	if (fcull <= cache->fstop_percent || fcull >= cache->frun_percent)
+		return cachefiles_daemon_range_error(cache, args);
+
+	cache->fcull_percent = fcull;
+	return 0;
+}
+
+/*
+ * set the percentage of files at which to stop allocating
+ * - command: "fstop <N>%"
+ */
+static int cachefiles_daemon_fstop(struct cachefiles_cache *cache, char *args)
+{
+	unsigned long fstop;
+
+	_enter(",%s", args);
+
+	if (!*args)
+		return -EINVAL;
+
+	fstop = simple_strtoul(args, &args, 10);
+	if (args[0] != '%' || args[1] != '\0')
+		return -EINVAL;
+
+	if (fstop < 0 || fstop >= cache->fcull_percent)
+		return cachefiles_daemon_range_error(cache, args);
+
+	cache->fstop_percent = fstop;
+	return 0;
+}
+
+/*
+ * set the percentage of blocks at which to stop culling
+ * - command: "brun <N>%"
+ */
+static int cachefiles_daemon_brun(struct cachefiles_cache *cache, char *args)
+{
+	unsigned long brun;
+
+	_enter(",%s", args);
+
+	if (!*args)
+		return -EINVAL;
+
+	brun = simple_strtoul(args, &args, 10);
+	if (args[0] != '%' || args[1] != '\0')
+		return -EINVAL;
+
+	if (brun <= cache->bcull_percent || brun >= 100)
+		return cachefiles_daemon_range_error(cache, args);
+
+	cache->brun_percent = brun;
+	return 0;
+}
+
+/*
+ * set the percentage of blocks at which to start culling
+ * - command: "bcull <N>%"
+ */
+static int cachefiles_daemon_bcull(struct cachefiles_cache *cache, char *args)
+{
+	unsigned long bcull;
+
+	_enter(",%s", args);
+
+	if (!*args)
+		return -EINVAL;
+
+	bcull = simple_strtoul(args, &args, 10);
+	if (args[0] != '%' || args[1] != '\0')
+		return -EINVAL;
+
+	if (bcull <= cache->bstop_percent || bcull >= cache->brun_percent)
+		return cachefiles_daemon_range_error(cache, args);
+
+	cache->bcull_percent = bcull;
+	return 0;
+}
+
+/*
+ * set the percentage of blocks at which to stop allocating
+ * - command: "bstop <N>%"
+ */
+static int cachefiles_daemon_bstop(struct cachefiles_cache *cache, char *args)
+{
+	unsigned long bstop;
+
+	_enter(",%s", args);
+
+	if (!*args)
+		return -EINVAL;
+
+	bstop = simple_strtoul(args, &args, 10);
+	if (args[0] != '%' || args[1] != '\0')
+		return -EINVAL;
+
+	if (bstop < 0 || bstop >= cache->bcull_percent)
+		return cachefiles_daemon_range_error(cache, args);
+
+	cache->bstop_percent = bstop;
+	return 0;
+}
+
+/*
+ * set the cache directory
+ * - command: "dir <name>"
+ */
+static int cachefiles_daemon_dir(struct cachefiles_cache *cache, char *args)
+{
+	char *dir;
+
+	_enter(",%s", args);
+
+	if (!*args) {
+		kerror("Empty directory specified");
+		return -EINVAL;
+	}
+
+	if (cache->rootdirname) {
+		kerror("Second cache directory specified");
+		return -EEXIST;
+	}
+
+	dir = kstrdup(args, GFP_KERNEL);
+	if (!dir)
+		return -ENOMEM;
+
+	cache->rootdirname = dir;
+	return 0;
+}
+
+/*
+ * set the cache security context
+ * - command: "secctx <ctx>"
+ */
+static int cachefiles_daemon_secctx(struct cachefiles_cache *cache, char *args)
+{
+	char *secctx;
+
+	_enter(",%s", args);
+
+	if (!*args) {
+		kerror("Empty security context specified");
+		return -EINVAL;
+	}
+
+	if (cache->secctx) {
+		kerror("Second security context specified");
+		return -EINVAL;
+	}
+
+	secctx = kstrdup(args, GFP_KERNEL);
+	if (!secctx)
+		return -ENOMEM;
+
+	cache->secctx = secctx;
+	return 0;
+}
+
+/*
+ * set the cache tag
+ * - command: "tag <name>"
+ */
+static int cachefiles_daemon_tag(struct cachefiles_cache *cache, char *args)
+{
+	char *tag;
+
+	_enter(",%s", args);
+
+	if (!*args) {
+		kerror("Empty tag specified");
+		return -EINVAL;
+	}
+
+	if (cache->tag)
+		return -EEXIST;
+
+	tag = kstrdup(args, GFP_KERNEL);
+	if (!tag)
+		return -ENOMEM;
+
+	cache->tag = tag;
+	return 0;
+}
+
+/*
+ * request a node in the cache be culled from the current working directory
+ * - command: "cull <name>"
+ */
+static int cachefiles_daemon_cull(struct cachefiles_cache *cache, char *args)
+{
+	struct fs_struct *fs;
+	struct dentry *dir;
+	const struct cred *saved_cred;
+	int ret;
+
+	_enter(",%s", args);
+
+	if (strchr(args, '/'))
+		goto inval;
+
+	if (!test_bit(CACHEFILES_READY, &cache->flags)) {
+		kerror("cull applied to unready cache");
+		return -EIO;
+	}
+
+	if (test_bit(CACHEFILES_DEAD, &cache->flags)) {
+		kerror("cull applied to dead cache");
+		return -EIO;
+	}
+
+	/* extract the directory dentry from the cwd */
+	fs = current->fs;
+	read_lock(&fs->lock);
+	dir = dget(fs->pwd.dentry);
+	read_unlock(&fs->lock);
+
+	if (!S_ISDIR(dir->d_inode->i_mode))
+		goto notdir;
+
+	cachefiles_begin_secure(cache, &saved_cred);
+	ret = cachefiles_cull(cache, dir, args);
+	cachefiles_end_secure(cache, saved_cred);
+
+	dput(dir);
+	_leave(" = %d", ret);
+	return ret;
+
+notdir:
+	dput(dir);
+	kerror("cull command requires dirfd to be a directory");
+	return -ENOTDIR;
+
+inval:
+	kerror("cull command requires dirfd and filename");
+	return -EINVAL;
+}
+
+/*
+ * set debugging mode
+ * - command: "debug <mask>"
+ */
+static int cachefiles_daemon_debug(struct cachefiles_cache *cache, char *args)
+{
+	unsigned long mask;
+
+	_enter(",%s", args);
+
+	mask = simple_strtoul(args, &args, 0);
+	if (args[0] != '\0')
+		goto inval;
+
+	cachefiles_debug = mask;
+	_leave(" = 0");
+	return 0;
+
+inval:
+	kerror("debug command requires mask");
+	return -EINVAL;
+}
+
+/*
+ * find out whether an object in the current working directory is in use or not
+ * - command: "inuse <name>"
+ */
+static int cachefiles_daemon_inuse(struct cachefiles_cache *cache, char *args)
+{
+	struct fs_struct *fs;
+	struct dentry *dir;
+	const struct cred *saved_cred;
+	int ret;
+
+	//_enter(",%s", args);
+
+	if (strchr(args, '/'))
+		goto inval;
+
+	if (!test_bit(CACHEFILES_READY, &cache->flags)) {
+		kerror("inuse applied to unready cache");
+		return -EIO;
+	}
+
+	if (test_bit(CACHEFILES_DEAD, &cache->flags)) {
+		kerror("inuse applied to dead cache");
+		return -EIO;
+	}
+
+	/* extract the directory dentry from the cwd */
+	fs = current->fs;
+	read_lock(&fs->lock);
+	dir = dget(fs->pwd.dentry);
+	read_unlock(&fs->lock);
+
+	if (!S_ISDIR(dir->d_inode->i_mode))
+		goto notdir;
+
+	cachefiles_begin_secure(cache, &saved_cred);
+	ret = cachefiles_check_in_use(cache, dir, args);
+	cachefiles_end_secure(cache, saved_cred);
+
+	dput(dir);
+	//_leave(" = %d", ret);
+	return ret;
+
+notdir:
+	dput(dir);
+	kerror("inuse command requires dirfd to be a directory");
+	return -ENOTDIR;
+
+inval:
+	kerror("inuse command requires dirfd and filename");
+	return -EINVAL;
+}
+
+/*
+ * see if we have space for a number of pages and/or a number of files in the
+ * cache
+ */
+int cachefiles_has_space(struct cachefiles_cache *cache,
+			 unsigned fnr, unsigned bnr)
+{
+	struct kstatfs stats;
+	int ret;
+
+	//_enter("{%llu,%llu,%llu,%llu,%llu,%llu},%u,%u",
+	//       (unsigned long long) cache->frun,
+	//       (unsigned long long) cache->fcull,
+	//       (unsigned long long) cache->fstop,
+	//       (unsigned long long) cache->brun,
+	//       (unsigned long long) cache->bcull,
+	//       (unsigned long long) cache->bstop,
+	//       fnr, bnr);
+
+	/* find out how many pages of blockdev are available */
+	memset(&stats, 0, sizeof(stats));
+
+	ret = vfs_statfs(cache->mnt->mnt_root, &stats);
+	if (ret < 0) {
+		if (ret == -EIO)
+			cachefiles_io_error(cache, "statfs failed");
+		_leave(" = %d", ret);
+		return ret;
+	}
+
+	stats.f_bavail >>= cache->bshift;
+
+	//_debug("avail %llu,%llu",
+	//       (unsigned long long) stats.f_ffree,
+	//       (unsigned long long) stats.f_bavail);
+
+	/* see if there is sufficient space */
+	if (stats.f_ffree > fnr)
+		stats.f_ffree -= fnr;
+	else
+		stats.f_ffree = 0;
+
+	if (stats.f_bavail > bnr)
+		stats.f_bavail -= bnr;
+	else
+		stats.f_bavail = 0;
+
+	ret = -ENOBUFS;
+	if (stats.f_ffree < cache->fstop ||
+	    stats.f_bavail < cache->bstop)
+		goto begin_cull;
+
+	ret = 0;
+	if (stats.f_ffree < cache->fcull ||
+	    stats.f_bavail < cache->bcull)
+		goto begin_cull;
+
+	if (test_bit(CACHEFILES_CULLING, &cache->flags) &&
+	    stats.f_ffree >= cache->frun &&
+	    stats.f_bavail >= cache->brun &&
+	    test_and_clear_bit(CACHEFILES_CULLING, &cache->flags)
+	    ) {
+		_debug("cease culling");
+		cachefiles_state_changed(cache);
+	}
+
+	//_leave(" = 0");
+	return 0;
+
+begin_cull:
+	if (!test_and_set_bit(CACHEFILES_CULLING, &cache->flags)) {
+		_debug("### CULL CACHE ###");
+		cachefiles_state_changed(cache);
+	}
+
+	_leave(" = %d", ret);
+	return ret;
+}
diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c
new file mode 100644
index 0000000..1e96234
--- /dev/null
+++ b/fs/cachefiles/interface.c
@@ -0,0 +1,449 @@
+/* FS-Cache interface to CacheFiles
+ *
+ * Copyright (C) 2007 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 <linux/mount.h>
+#include <linux/buffer_head.h>
+#include "internal.h"
+
+#define list_to_page(head) (list_entry((head)->prev, struct page, lru))
+
+struct cachefiles_lookup_data {
+	struct cachefiles_xattr	*auxdata;	/* auxiliary data */
+	char			*key;		/* key path */
+};
+
+static int cachefiles_attr_changed(struct fscache_object *_object);
+
+/*
+ * allocate an object record for a cookie lookup and prepare the lookup data
+ */
+static struct fscache_object *cachefiles_alloc_object(
+	struct fscache_cache *_cache,
+	struct fscache_cookie *cookie)
+{
+	struct cachefiles_lookup_data *lookup_data;
+	struct cachefiles_object *object;
+	struct cachefiles_cache *cache;
+	struct cachefiles_xattr *auxdata;
+	unsigned keylen, auxlen;
+	void *buffer;
+	char *key;
+
+	cache = container_of(_cache, struct cachefiles_cache, cache);
+
+	_enter("{%s},%p,", cache->cache.identifier, cookie);
+
+	lookup_data = kmalloc(sizeof(*lookup_data), GFP_KERNEL);
+	if (!lookup_data)
+		goto nomem_lookup_data;
+
+	/* create a new object record and a temporary leaf image */
+	object = kmem_cache_alloc(cachefiles_object_jar, GFP_KERNEL);
+	if (!object)
+		goto nomem_object;
+
+	ASSERTCMP(object->backer, ==, NULL);
+
+	BUG_ON(test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags));
+	atomic_set(&object->usage, 1);
+
+	fscache_object_init(&object->fscache, cookie, &cache->cache);
+
+	object->type = cookie->def->type;
+
+	/* get hold of the raw key
+	 * - stick the length on the front and leave space on the back for the
+	 *   encoder
+	 */
+	buffer = kmalloc((2 + 512) + 3, GFP_KERNEL);
+	if (!buffer)
+		goto nomem_buffer;
+
+	keylen = cookie->def->get_key(cookie->netfs_data, buffer + 2, 512);
+	ASSERTCMP(keylen, <, 512);
+
+	*(uint16_t *)buffer = keylen;
+	((char *)buffer)[keylen + 2] = 0;
+	((char *)buffer)[keylen + 3] = 0;
+	((char *)buffer)[keylen + 4] = 0;
+
+	/* turn the raw key into something that can work with as a filename */
+	key = cachefiles_cook_key(buffer, keylen + 2, object->type);
+	if (!key)
+		goto nomem_key;
+
+	/* get hold of the auxiliary data and prepend the object type */
+	auxdata = buffer;
+	auxlen = 0;
+	if (cookie->def->get_aux) {
+		auxlen = cookie->def->get_aux(cookie->netfs_data,
+					      auxdata->data, 511);
+		ASSERTCMP(auxlen, <, 511);
+	}
+
+	auxdata->len = auxlen + 1;
+	auxdata->type = cookie->def->type;
+
+	lookup_data->auxdata = auxdata;
+	lookup_data->key = key;
+	object->lookup_data = lookup_data;
+
+	_leave(" = %p [%p]", &object->fscache, lookup_data);
+	return &object->fscache;
+
+nomem_key:
+	kfree(buffer);
+nomem_buffer:
+	BUG_ON(test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags));
+	kmem_cache_free(cachefiles_object_jar, object);
+	fscache_object_destroyed(&cache->cache);
+nomem_object:
+	kfree(lookup_data);
+nomem_lookup_data:
+	_leave(" = -ENOMEM");
+	return ERR_PTR(-ENOMEM);
+}
+
+/*
+ * attempt to look up the nominated node in this cache
+ */
+static void cachefiles_lookup_object(struct fscache_object *_object)
+{
+	struct cachefiles_lookup_data *lookup_data;
+	struct cachefiles_object *parent, *object;
+	struct cachefiles_cache *cache;
+	const struct cred *saved_cred;
+	int ret;
+
+	_enter("{OBJ%x}", _object->debug_id);
+
+	cache = container_of(_object->cache, struct cachefiles_cache, cache);
+	parent = container_of(_object->parent,
+			      struct cachefiles_object, fscache);
+	object = container_of(_object, struct cachefiles_object, fscache);
+	lookup_data = object->lookup_data;
+
+	ASSERTCMP(lookup_data, !=, NULL);
+
+	/* look up the key, creating any missing bits */
+	cachefiles_begin_secure(cache, &saved_cred);
+	ret = cachefiles_walk_to_object(parent, object,
+					lookup_data->key,
+					lookup_data->auxdata);
+	cachefiles_end_secure(cache, saved_cred);
+
+	/* polish off by setting the attributes of non-index files */
+	if (ret == 0 &&
+	    object->fscache.cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX)
+		cachefiles_attr_changed(&object->fscache);
+
+	if (ret < 0) {
+		printk(KERN_WARNING "CacheFiles: Lookup failed error %d\n",
+		       ret);
+		fscache_object_lookup_error(&object->fscache);
+	}
+
+	_leave(" [%d]", ret);
+}
+
+/*
+ * indication of lookup completion
+ */
+static void cachefiles_lookup_complete(struct fscache_object *_object)
+{
+	struct cachefiles_object *object;
+
+	object = container_of(_object, struct cachefiles_object, fscache);
+
+	_enter("{OBJ%x,%p}", object->fscache.debug_id, object->lookup_data);
+
+	if (object->lookup_data) {
+		kfree(object->lookup_data->key);
+		kfree(object->lookup_data->auxdata);
+		kfree(object->lookup_data);
+		object->lookup_data = NULL;
+	}
+}
+
+/*
+ * increment the usage count on an inode object (may fail if unmounting)
+ */
+static
+struct fscache_object *cachefiles_grab_object(struct fscache_object *_object)
+{
+	struct cachefiles_object *object =
+		container_of(_object, struct cachefiles_object, fscache);
+
+	_enter("{OBJ%x,%d}", _object->debug_id, atomic_read(&object->usage));
+
+#ifdef CACHEFILES_DEBUG_SLAB
+	ASSERT((atomic_read(&object->usage) & 0xffff0000) != 0x6b6b0000);
+#endif
+
+	atomic_inc(&object->usage);
+	return &object->fscache;
+}
+
+/*
+ * update the auxilliary data for an object object on disk
+ */
+static void cachefiles_update_object(struct fscache_object *_object)
+{
+	struct cachefiles_object *object;
+	struct cachefiles_xattr *auxdata;
+	struct cachefiles_cache *cache;
+	struct fscache_cookie *cookie;
+	const struct cred *saved_cred;
+	unsigned auxlen;
+
+	_enter("{OBJ%x}", _object->debug_id);
+
+	object = container_of(_object, struct cachefiles_object, fscache);
+	cache = container_of(object->fscache.cache, struct cachefiles_cache,
+			     cache);
+	cookie = object->fscache.cookie;
+
+	if (!cookie->def->get_aux) {
+		_leave(" [no aux]");
+		return;
+	}
+
+	auxdata = kmalloc(2 + 512 + 3, GFP_KERNEL);
+	if (!auxdata) {
+		_leave(" [nomem]");
+		return;
+	}
+
+	auxlen = cookie->def->get_aux(cookie->netfs_data, auxdata->data, 511);
+	ASSERTCMP(auxlen, <, 511);
+
+	auxdata->len = auxlen + 1;
+	auxdata->type = cookie->def->type;
+
+	cachefiles_begin_secure(cache, &saved_cred);
+	cachefiles_update_object_xattr(object, auxdata);
+	cachefiles_end_secure(cache, saved_cred);
+	kfree(auxdata);
+	_leave("");
+}
+
+/*
+ * discard the resources pinned by an object and effect retirement if
+ * requested
+ */
+static void cachefiles_drop_object(struct fscache_object *_object)
+{
+	struct cachefiles_object *object;
+	struct cachefiles_cache *cache;
+	const struct cred *saved_cred;
+
+	ASSERT(_object);
+
+	object = container_of(_object, struct cachefiles_object, fscache);
+
+	_enter("{OBJ%x,%d}",
+	       object->fscache.debug_id, atomic_read(&object->usage));
+
+	cache = container_of(object->fscache.cache,
+			     struct cachefiles_cache, cache);
+
+#ifdef CACHEFILES_DEBUG_SLAB
+	ASSERT((atomic_read(&object->usage) & 0xffff0000) != 0x6b6b0000);
+#endif
+
+	/* delete retired objects */
+	if (object->fscache.state == FSCACHE_OBJECT_RECYCLING &&
+	    _object != cache->cache.fsdef
+	    ) {
+		_debug("- retire object OBJ%x", object->fscache.debug_id);
+		cachefiles_begin_secure(cache, &saved_cred);
+		cachefiles_delete_object(cache, object);
+		cachefiles_end_secure(cache, saved_cred);
+	}
+
+	/* close the filesystem stuff attached to the object */
+	if (object->backer != object->dentry)
+		dput(object->backer);
+	object->backer = NULL;
+
+	/* note that the object is now inactive */
+	if (test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) {
+		write_lock(&cache->active_lock);
+		if (!test_and_clear_bit(CACHEFILES_OBJECT_ACTIVE,
+					&object->flags))
+			BUG();
+		rb_erase(&object->active_node, &cache->active_nodes);
+		wake_up_bit(&object->flags, CACHEFILES_OBJECT_ACTIVE);
+		write_unlock(&cache->active_lock);
+	}
+
+	dput(object->dentry);
+	object->dentry = NULL;
+
+	_leave("");
+}
+
+/*
+ * dispose of a reference to an object
+ */
+static void cachefiles_put_object(struct fscache_object *_object)
+{
+	struct cachefiles_object *object;
+	struct fscache_cache *cache;
+
+	ASSERT(_object);
+
+	object = container_of(_object, struct cachefiles_object, fscache);
+
+	_enter("{OBJ%x,%d}",
+	       object->fscache.debug_id, atomic_read(&object->usage));
+
+#ifdef CACHEFILES_DEBUG_SLAB
+	ASSERT((atomic_read(&object->usage) & 0xffff0000) != 0x6b6b0000);
+#endif
+
+	ASSERTIFCMP(object->fscache.parent,
+		    object->fscache.parent->n_children, >, 0);
+
+	if (atomic_dec_and_test(&object->usage)) {
+		_debug("- kill object OBJ%x", object->fscache.debug_id);
+
+		ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags));
+		ASSERTCMP(object->fscache.parent, ==, NULL);
+		ASSERTCMP(object->backer, ==, NULL);
+		ASSERTCMP(object->dentry, ==, NULL);
+		ASSERTCMP(object->fscache.n_ops, ==, 0);
+		ASSERTCMP(object->fscache.n_children, ==, 0);
+
+		if (object->lookup_data) {
+			kfree(object->lookup_data->key);
+			kfree(object->lookup_data->auxdata);
+			kfree(object->lookup_data);
+			object->lookup_data = NULL;
+		}
+
+		cache = object->fscache.cache;
+		kmem_cache_free(cachefiles_object_jar, object);
+		fscache_object_destroyed(cache);
+	}
+
+	_leave("");
+}
+
+/*
+ * sync a cache
+ */
+static void cachefiles_sync_cache(struct fscache_cache *_cache)
+{
+	struct cachefiles_cache *cache;
+	const struct cred *saved_cred;
+	int ret;
+
+	_enter("%p", _cache);
+
+	cache = container_of(_cache, struct cachefiles_cache, cache);
+
+	/* make sure all pages pinned by operations on behalf of the netfs are
+	 * written to disc */
+	cachefiles_begin_secure(cache, &saved_cred);
+	ret = fsync_super(cache->mnt->mnt_sb);
+	cachefiles_end_secure(cache, saved_cred);
+
+	if (ret == -EIO)
+		cachefiles_io_error(cache,
+				    "Attempt to sync backing fs superblock"
+				    " returned error %d",
+				    ret);
+}
+
+/*
+ * notification the attributes on an object have changed
+ * - called with reads/writes excluded by FS-Cache
+ */
+static int cachefiles_attr_changed(struct fscache_object *_object)
+{
+	struct cachefiles_object *object;
+	struct cachefiles_cache *cache;
+	const struct cred *saved_cred;
+	struct iattr newattrs;
+	uint64_t ni_size;
+	loff_t oi_size;
+	int ret;
+
+	_object->cookie->def->get_attr(_object->cookie->netfs_data, &ni_size);
+
+	_enter("{OBJ%x},[%llu]",
+	       _object->debug_id, (unsigned long long) ni_size);
+
+	object = container_of(_object, struct cachefiles_object, fscache);
+	cache = container_of(object->fscache.cache,
+			     struct cachefiles_cache, cache);
+
+	if (ni_size == object->i_size)
+		return 0;
+
+	if (!object->backer)
+		return -ENOBUFS;
+
+	ASSERT(S_ISREG(object->backer->d_inode->i_mode));
+
+	fscache_set_store_limit(&object->fscache, ni_size);
+
+	oi_size = i_size_read(object->backer->d_inode);
+	if (oi_size == ni_size)
+		return 0;
+
+	newattrs.ia_size = ni_size;
+	newattrs.ia_valid = ATTR_SIZE;
+
+	cachefiles_begin_secure(cache, &saved_cred);
+	mutex_lock(&object->backer->d_inode->i_mutex);
+	ret = notify_change(object->backer, &newattrs);
+	mutex_unlock(&object->backer->d_inode->i_mutex);
+	cachefiles_end_secure(cache, saved_cred);
+
+	if (ret == -EIO) {
+		fscache_set_store_limit(&object->fscache, 0);
+		cachefiles_io_error_obj(object, "Size set failed");
+		ret = -ENOBUFS;
+	}
+
+	_leave(" = %d", ret);
+	return ret;
+}
+
+/*
+ * dissociate a cache from all the pages it was backing
+ */
+static void cachefiles_dissociate_pages(struct fscache_cache *cache)
+{
+	_enter("");
+}
+
+const struct fscache_cache_ops cachefiles_cache_ops = {
+	.name			= "cachefiles",
+	.alloc_object		= cachefiles_alloc_object,
+	.lookup_object		= cachefiles_lookup_object,
+	.lookup_complete	= cachefiles_lookup_complete,
+	.grab_object		= cachefiles_grab_object,
+	.update_object		= cachefiles_update_object,
+	.drop_object		= cachefiles_drop_object,
+	.put_object		= cachefiles_put_object,
+	.sync_cache		= cachefiles_sync_cache,
+	.attr_changed		= cachefiles_attr_changed,
+	.read_or_alloc_page	= cachefiles_read_or_alloc_page,
+	.read_or_alloc_pages	= cachefiles_read_or_alloc_pages,
+	.allocate_page		= cachefiles_allocate_page,
+	.allocate_pages		= cachefiles_allocate_pages,
+	.write_page		= cachefiles_write_page,
+	.uncache_page		= cachefiles_uncache_page,
+	.dissociate_pages	= cachefiles_dissociate_pages,
+};
diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h
new file mode 100644
index 0000000..19218e1
--- /dev/null
+++ b/fs/cachefiles/internal.h
@@ -0,0 +1,360 @@
+/* General netfs cache on cache files internal defs
+ *
+ * Copyright (C) 2007 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 <linux/fscache-cache.h>
+#include <linux/timer.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+#include <linux/security.h>
+
+struct cachefiles_cache;
+struct cachefiles_object;
+
+extern unsigned cachefiles_debug;
+#define CACHEFILES_DEBUG_KENTER	1
+#define CACHEFILES_DEBUG_KLEAVE	2
+#define CACHEFILES_DEBUG_KDEBUG	4
+
+/*
+ * node records
+ */
+struct cachefiles_object {
+	struct fscache_object		fscache;	/* fscache handle */
+	struct cachefiles_lookup_data	*lookup_data;	/* cached lookup data */
+	struct dentry			*dentry;	/* the file/dir representing this object */
+	struct dentry			*backer;	/* backing file */
+	loff_t				i_size;		/* object size */
+	unsigned long			flags;
+#define CACHEFILES_OBJECT_ACTIVE	0		/* T if marked active */
+	atomic_t			usage;		/* object usage count */
+	uint8_t				type;		/* object type */
+	uint8_t				new;		/* T if object new */
+	spinlock_t			work_lock;
+	struct rb_node			active_node;	/* link in active tree (dentry is key) */
+};
+
+extern struct kmem_cache *cachefiles_object_jar;
+
+/*
+ * Cache files cache definition
+ */
+struct cachefiles_cache {
+	struct fscache_cache		cache;		/* FS-Cache record */
+	struct vfsmount			*mnt;		/* mountpoint holding the cache */
+	struct dentry			*graveyard;	/* directory into which dead objects go */
+	struct file			*cachefilesd;	/* manager daemon handle */
+	const struct cred		*cache_cred;	/* security override for accessing cache */
+	struct mutex			daemon_mutex;	/* command serialisation mutex */
+	wait_queue_head_t		daemon_pollwq;	/* poll waitqueue for daemon */
+	struct rb_root			active_nodes;	/* active nodes (can't be culled) */
+	rwlock_t			active_lock;	/* lock for active_nodes */
+	atomic_t			gravecounter;	/* graveyard uniquifier */
+	unsigned			frun_percent;	/* when to stop culling (% files) */
+	unsigned			fcull_percent;	/* when to start culling (% files) */
+	unsigned			fstop_percent;	/* when to stop allocating (% files) */
+	unsigned			brun_percent;	/* when to stop culling (% blocks) */
+	unsigned			bcull_percent;	/* when to start culling (% blocks) */
+	unsigned			bstop_percent;	/* when to stop allocating (% blocks) */
+	unsigned			bsize;		/* cache's block size */
+	unsigned			bshift;		/* min(ilog2(PAGE_SIZE / bsize), 0) */
+	uint64_t			frun;		/* when to stop culling */
+	uint64_t			fcull;		/* when to start culling */
+	uint64_t			fstop;		/* when to stop allocating */
+	sector_t			brun;		/* when to stop culling */
+	sector_t			bcull;		/* when to start culling */
+	sector_t			bstop;		/* when to stop allocating */
+	unsigned long			flags;
+#define CACHEFILES_READY		0	/* T if cache prepared */
+#define CACHEFILES_DEAD			1	/* T if cache dead */
+#define CACHEFILES_CULLING		2	/* T if cull engaged */
+#define CACHEFILES_STATE_CHANGED	3	/* T if state changed (poll trigger) */
+	char				*rootdirname;	/* name of cache root directory */
+	char				*secctx;	/* LSM security context */
+	char				*tag;		/* cache binding tag */
+};
+
+/*
+ * backing file read tracking
+ */
+struct cachefiles_one_read {
+	wait_queue_t			monitor;	/* link into monitored waitqueue */
+	struct page			*back_page;	/* backing file page we're waiting for */
+	struct page			*netfs_page;	/* netfs page we're going to fill */
+	struct fscache_retrieval	*op;		/* retrieval op covering this */
+	struct list_head		op_link;	/* link in op's todo list */
+};
+
+/*
+ * backing file write tracking
+ */
+struct cachefiles_one_write {
+	struct page			*netfs_page;	/* netfs page to copy */
+	struct cachefiles_object	*object;
+	struct list_head		obj_link;	/* link in object's lists */
+	fscache_rw_complete_t		end_io_func;
+	void				*context;
+};
+
+/*
+ * auxiliary data xattr buffer
+ */
+struct cachefiles_xattr {
+	uint16_t			len;
+	uint8_t				type;
+	uint8_t				data[];
+};
+
+/*
+ * note change of state for daemon
+ */
+static inline void cachefiles_state_changed(struct cachefiles_cache *cache)
+{
+	set_bit(CACHEFILES_STATE_CHANGED, &cache->flags);
+	wake_up_all(&cache->daemon_pollwq);
+}
+
+/*
+ * cf-bind.c
+ */
+extern int cachefiles_daemon_bind(struct cachefiles_cache *cache, char *args);
+extern void cachefiles_daemon_unbind(struct cachefiles_cache *cache);
+
+/*
+ * cf-daemon.c
+ */
+extern const struct file_operations cachefiles_daemon_fops;
+
+extern int cachefiles_has_space(struct cachefiles_cache *cache,
+				unsigned fnr, unsigned bnr);
+
+/*
+ * cf-interface.c
+ */
+extern const struct fscache_cache_ops cachefiles_cache_ops;
+
+/*
+ * cf-key.c
+ */
+extern char *cachefiles_cook_key(const u8 *raw, int keylen, uint8_t type);
+
+/*
+ * cf-namei.c
+ */
+extern int cachefiles_delete_object(struct cachefiles_cache *cache,
+				    struct cachefiles_object *object);
+extern int cachefiles_walk_to_object(struct cachefiles_object *parent,
+				     struct cachefiles_object *object,
+				     const char *key,
+				     struct cachefiles_xattr *auxdata);
+extern struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
+					       struct dentry *dir,
+					       const char *name);
+
+extern int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir,
+			   char *filename);
+
+extern int cachefiles_check_in_use(struct cachefiles_cache *cache,
+				   struct dentry *dir, char *filename);
+
+/*
+ * cf-proc.c
+ */
+#ifdef CONFIG_CACHEFILES_HISTOGRAM
+extern atomic_t cachefiles_lookup_histogram[HZ];
+extern atomic_t cachefiles_mkdir_histogram[HZ];
+extern atomic_t cachefiles_create_histogram[HZ];
+
+extern int __init cachefiles_proc_init(void);
+extern void cachefiles_proc_cleanup(void);
+static inline
+void cachefiles_hist(atomic_t histogram[], unsigned long start_jif)
+{
+	unsigned long jif = jiffies - start_jif;
+	if (jif >= HZ)
+		jif = HZ - 1;
+	atomic_inc(&histogram[jif]);
+}
+
+#else
+#define cachefiles_proc_init()		(0)
+#define cachefiles_proc_cleanup()	do {} while (0)
+#define cachefiles_hist(hist, start_jif) do {} while (0)
+#endif
+
+/*
+ * cf-rdwr.c
+ */
+extern int cachefiles_read_or_alloc_page(struct fscache_retrieval *,
+					 struct page *, gfp_t);
+extern int cachefiles_read_or_alloc_pages(struct fscache_retrieval *,
+					  struct list_head *, unsigned *,
+					  gfp_t);
+extern int cachefiles_allocate_page(struct fscache_retrieval *, struct page *,
+				    gfp_t);
+extern int cachefiles_allocate_pages(struct fscache_retrieval *,
+				     struct list_head *, unsigned *, gfp_t);
+extern int cachefiles_write_page(struct fscache_storage *, struct page *);
+extern void cachefiles_uncache_page(struct fscache_object *, struct page *);
+
+/*
+ * cf-security.c
+ */
+extern int cachefiles_get_security_ID(struct cachefiles_cache *cache);
+extern int cachefiles_determine_cache_security(struct cachefiles_cache *cache,
+					       struct dentry *root,
+					       const struct cred **_saved_cred);
+
+static inline void cachefiles_begin_secure(struct cachefiles_cache *cache,
+					   const struct cred **_saved_cred)
+{
+	*_saved_cred = override_creds(cache->cache_cred);
+}
+
+static inline void cachefiles_end_secure(struct cachefiles_cache *cache,
+					 const struct cred *saved_cred)
+{
+	revert_creds(saved_cred);
+}
+
+/*
+ * cf-xattr.c
+ */
+extern int cachefiles_check_object_type(struct cachefiles_object *object);
+extern int cachefiles_set_object_xattr(struct cachefiles_object *object,
+				       struct cachefiles_xattr *auxdata);
+extern int cachefiles_update_object_xattr(struct cachefiles_object *object,
+					  struct cachefiles_xattr *auxdata);
+extern int cachefiles_check_object_xattr(struct cachefiles_object *object,
+					 struct cachefiles_xattr *auxdata);
+extern int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
+					  struct dentry *dentry);
+
+
+/*
+ * error handling
+ */
+#define kerror(FMT, ...) printk(KERN_ERR "CacheFiles: "FMT"\n", ##__VA_ARGS__)
+
+#define cachefiles_io_error(___cache, FMT, ...)		\
+do {							\
+	kerror("I/O Error: " FMT, ##__VA_ARGS__);	\
+	fscache_io_error(&(___cache)->cache);		\
+	set_bit(CACHEFILES_DEAD, &(___cache)->flags);	\
+} while (0)
+
+#define cachefiles_io_error_obj(object, FMT, ...)			\
+do {									\
+	struct cachefiles_cache *___cache;				\
+									\
+	___cache = container_of((object)->fscache.cache,		\
+				struct cachefiles_cache, cache);	\
+	cachefiles_io_error(___cache, FMT, ##__VA_ARGS__);		\
+} while (0)
+
+
+/*
+ * debug tracing
+ */
+#define dbgprintk(FMT, ...) \
+	printk(KERN_DEBUG "[%-6.6s] "FMT"\n", current->comm, ##__VA_ARGS__)
+
+/* make sure we maintain the format strings, even when debugging is disabled */
+static inline void _dbprintk(const char *fmt, ...)
+	__attribute__((format(printf, 1, 2)));
+static inline void _dbprintk(const char *fmt, ...)
+{
+}
+
+#define kenter(FMT, ...) dbgprintk("==> %s("FMT")", __func__, ##__VA_ARGS__)
+#define kleave(FMT, ...) dbgprintk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
+#define kdebug(FMT, ...) dbgprintk(FMT, ##__VA_ARGS__)
+
+
+#if defined(__KDEBUG)
+#define _enter(FMT, ...) kenter(FMT, ##__VA_ARGS__)
+#define _leave(FMT, ...) kleave(FMT, ##__VA_ARGS__)
+#define _debug(FMT, ...) kdebug(FMT, ##__VA_ARGS__)
+
+#elif defined(CONFIG_CACHEFILES_DEBUG)
+#define _enter(FMT, ...)				\
+do {							\
+	if (cachefiles_debug & CACHEFILES_DEBUG_KENTER)	\
+		kenter(FMT, ##__VA_ARGS__);		\
+} while (0)
+
+#define _leave(FMT, ...)				\
+do {							\
+	if (cachefiles_debug & CACHEFILES_DEBUG_KLEAVE)	\
+		kleave(FMT, ##__VA_ARGS__);		\
+} while (0)
+
+#define _debug(FMT, ...)				\
+do {							\
+	if (cachefiles_debug & CACHEFILES_DEBUG_KDEBUG)	\
+		kdebug(FMT, ##__VA_ARGS__);		\
+} while (0)
+
+#else
+#define _enter(FMT, ...) _dbprintk("==> %s("FMT")", __func__, ##__VA_ARGS__)
+#define _leave(FMT, ...) _dbprintk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
+#define _debug(FMT, ...) _dbprintk(FMT, ##__VA_ARGS__)
+#endif
+
+#if 1 /* defined(__KDEBUGALL) */
+
+#define ASSERT(X)							\
+do {									\
+	if (unlikely(!(X))) {						\
+		printk(KERN_ERR "\n");					\
+		printk(KERN_ERR "CacheFiles: Assertion failed\n");	\
+		BUG();							\
+	}								\
+} while (0)
+
+#define ASSERTCMP(X, OP, Y)						\
+do {									\
+	if (unlikely(!((X) OP (Y)))) {					\
+		printk(KERN_ERR "\n");					\
+		printk(KERN_ERR "CacheFiles: Assertion failed\n");	\
+		printk(KERN_ERR "%lx " #OP " %lx is false\n",		\
+		       (unsigned long)(X), (unsigned long)(Y));		\
+		BUG();							\
+	}								\
+} while (0)
+
+#define ASSERTIF(C, X)							\
+do {									\
+	if (unlikely((C) && !(X))) {					\
+		printk(KERN_ERR "\n");					\
+		printk(KERN_ERR "CacheFiles: Assertion failed\n");	\
+		BUG();							\
+	}								\
+} while (0)
+
+#define ASSERTIFCMP(C, X, OP, Y)					\
+do {									\
+	if (unlikely((C) && !((X) OP (Y)))) {				\
+		printk(KERN_ERR "\n");					\
+		printk(KERN_ERR "CacheFiles: Assertion failed\n");	\
+		printk(KERN_ERR "%lx " #OP " %lx is false\n",		\
+		       (unsigned long)(X), (unsigned long)(Y));		\
+		BUG();							\
+	}								\
+} while (0)
+
+#else
+
+#define ASSERT(X)			do {} while (0)
+#define ASSERTCMP(X, OP, Y)		do {} while (0)
+#define ASSERTIF(C, X)			do {} while (0)
+#define ASSERTIFCMP(C, X, OP, Y)	do {} while (0)
+
+#endif
diff --git a/fs/cachefiles/key.c b/fs/cachefiles/key.c
new file mode 100644
index 0000000..81b8b2b
--- /dev/null
+++ b/fs/cachefiles/key.c
@@ -0,0 +1,159 @@
+/* Key to pathname encoder
+ *
+ * Copyright (C) 2007 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 <linux/slab.h>
+#include "internal.h"
+
+static const char cachefiles_charmap[64] =
+	"0123456789"			/* 0 - 9 */
+	"abcdefghijklmnopqrstuvwxyz"	/* 10 - 35 */
+	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"	/* 36 - 61 */
+	"_-"				/* 62 - 63 */
+	;
+
+static const char cachefiles_filecharmap[256] = {
+	/* we skip space and tab and control chars */
+	[33 ... 46] = 1,		/* '!' -> '.' */
+	/* we skip '/' as it's significant to pathwalk */
+	[48 ... 127] = 1,		/* '0' -> '~' */
+};
+
+/*
+ * turn the raw key into something cooked
+ * - the raw key should include the length in the two bytes at the front
+ * - the key may be up to 514 bytes in length (including the length word)
+ *   - "base64" encode the strange keys, mapping 3 bytes of raw to four of
+ *     cooked
+ *   - need to cut the cooked key into 252 char lengths (189 raw bytes)
+ */
+char *cachefiles_cook_key(const u8 *raw, int keylen, uint8_t type)
+{
+	unsigned char csum, ch;
+	unsigned int acc;
+	char *key;
+	int loop, len, max, seg, mark, print;
+
+	_enter(",%d", keylen);
+
+	BUG_ON(keylen < 2 || keylen > 514);
+
+	csum = raw[0] + raw[1];
+	print = 1;
+	for (loop = 2; loop < keylen; loop++) {
+		ch = raw[loop];
+		csum += ch;
+		print &= cachefiles_filecharmap[ch];
+	}
+
+	if (print) {
+		/* if the path is usable ASCII, then we render it directly */
+		max = keylen - 2;
+		max += 2;	/* two base64'd length chars on the front */
+		max += 5;	/* @checksum/M */
+		max += 3 * 2;	/* maximum number of segment dividers (".../M")
+				 * is ((514 + 251) / 252) = 3
+				 */
+		max += 1;	/* NUL on end */
+	} else {
+		/* calculate the maximum length of the cooked key */
+		keylen = (keylen + 2) / 3;
+
+		max = keylen * 4;
+		max += 5;	/* @checksum/M */
+		max += 3 * 2;	/* maximum number of segment dividers (".../M")
+				 * is ((514 + 188) / 189) = 3
+				 */
+		max += 1;	/* NUL on end */
+	}
+
+	max += 1;	/* 2nd NUL on end */
+
+	_debug("max: %d", max);
+
+	key = kmalloc(max, GFP_KERNEL);
+	if (!key)
+		return NULL;
+
+	len = 0;
+
+	/* build the cooked key */
+	sprintf(key, "@%02x%c+", (unsigned) csum, 0);
+	len = 5;
+	mark = len - 1;
+
+	if (print) {
+		acc = *(uint16_t *) raw;
+		raw += 2;
+
+		key[len + 1] = cachefiles_charmap[acc & 63];
+		acc >>= 6;
+		key[len] = cachefiles_charmap[acc & 63];
+		len += 2;
+
+		seg = 250;
+		for (loop = keylen; loop > 0; loop--) {
+			if (seg <= 0) {
+				key[len++] = '\0';
+				mark = len;
+				key[len++] = '+';
+				seg = 252;
+			}
+
+			key[len++] = *raw++;
+			ASSERT(len < max);
+		}
+
+		switch (type) {
+		case FSCACHE_COOKIE_TYPE_INDEX:		type = 'I';	break;
+		case FSCACHE_COOKIE_TYPE_DATAFILE:	type = 'D';	break;
+		default:				type = 'S';	break;
+		}
+	} else {
+		seg = 252;
+		for (loop = keylen; loop > 0; loop--) {
+			if (seg <= 0) {
+				key[len++] = '\0';
+				mark = len;
+				key[len++] = '+';
+				seg = 252;
+			}
+
+			acc = *raw++;
+			acc |= *raw++ << 8;
+			acc |= *raw++ << 16;
+
+			_debug("acc: %06x", acc);
+
+			key[len++] = cachefiles_charmap[acc & 63];
+			acc >>= 6;
+			key[len++] = cachefiles_charmap[acc & 63];
+			acc >>= 6;
+			key[len++] = cachefiles_charmap[acc & 63];
+			acc >>= 6;
+			key[len++] = cachefiles_charmap[acc & 63];
+
+			ASSERT(len < max);
+		}
+
+		switch (type) {
+		case FSCACHE_COOKIE_TYPE_INDEX:		type = 'J';	break;
+		case FSCACHE_COOKIE_TYPE_DATAFILE:	type = 'E';	break;
+		default:				type = 'T';	break;
+		}
+	}
+
+	key[mark] = type;
+	key[len++] = 0;
+	key[len] = 0;
+
+	_leave(" = %p %d", key, len);
+	return key;
+}
diff --git a/fs/cachefiles/main.c b/fs/cachefiles/main.c
new file mode 100644
index 0000000..4bfa8cf
--- /dev/null
+++ b/fs/cachefiles/main.c
@@ -0,0 +1,106 @@
+/* Network filesystem caching backend to use cache files on a premounted
+ * filesystem
+ *
+ * Copyright (C) 2007 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 <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/completion.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/namei.h>
+#include <linux/mount.h>
+#include <linux/statfs.h>
+#include <linux/sysctl.h>
+#include <linux/miscdevice.h>
+#include "internal.h"
+
+unsigned cachefiles_debug;
+module_param_named(debug, cachefiles_debug, uint, S_IWUSR | S_IRUGO);
+MODULE_PARM_DESC(cachefiles_debug, "CacheFiles debugging mask");
+
+MODULE_DESCRIPTION("Mounted-filesystem based cache");
+MODULE_AUTHOR("Red Hat, Inc.");
+MODULE_LICENSE("GPL");
+
+struct kmem_cache *cachefiles_object_jar;
+
+static struct miscdevice cachefiles_dev = {
+	.minor	= MISC_DYNAMIC_MINOR,
+	.name	= "cachefiles",
+	.fops	= &cachefiles_daemon_fops,
+};
+
+static void cachefiles_object_init_once(void *_object)
+{
+	struct cachefiles_object *object = _object;
+
+	memset(object, 0, sizeof(*object));
+	spin_lock_init(&object->work_lock);
+}
+
+/*
+ * initialise the fs caching module
+ */
+static int __init cachefiles_init(void)
+{
+	int ret;
+
+	ret = misc_register(&cachefiles_dev);
+	if (ret < 0)
+		goto error_dev;
+
+	/* create an object jar */
+	ret = -ENOMEM;
+	cachefiles_object_jar =
+		kmem_cache_create("cachefiles_object_jar",
+				  sizeof(struct cachefiles_object),
+				  0,
+				  SLAB_HWCACHE_ALIGN,
+				  cachefiles_object_init_once);
+	if (!cachefiles_object_jar) {
+		printk(KERN_NOTICE
+		       "CacheFiles: Failed to allocate an object jar\n");
+		goto error_object_jar;
+	}
+
+	ret = cachefiles_proc_init();
+	if (ret < 0)
+		goto error_proc;
+
+	printk(KERN_INFO "CacheFiles: Loaded\n");
+	return 0;
+
+error_proc:
+	kmem_cache_destroy(cachefiles_object_jar);
+error_object_jar:
+	misc_deregister(&cachefiles_dev);
+error_dev:
+	kerror("failed to register: %d", ret);
+	return ret;
+}
+
+fs_initcall(cachefiles_init);
+
+/*
+ * clean up on module removal
+ */
+static void __exit cachefiles_exit(void)
+{
+	printk(KERN_INFO "CacheFiles: Unloading\n");
+
+	cachefiles_proc_cleanup();
+	kmem_cache_destroy(cachefiles_object_jar);
+	misc_deregister(&cachefiles_dev);
+}
+
+module_exit(cachefiles_exit);
diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c
new file mode 100644
index 0000000..4ce818a
--- /dev/null
+++ b/fs/cachefiles/namei.c
@@ -0,0 +1,771 @@
+/* CacheFiles path walking and related routines
+ *
+ * Copyright (C) 2007 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 <linux/module.h>
+#include <linux/sched.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/fsnotify.h>
+#include <linux/quotaops.h>
+#include <linux/xattr.h>
+#include <linux/mount.h>
+#include <linux/namei.h>
+#include <linux/security.h>
+#include "internal.h"
+
+static int cachefiles_wait_bit(void *flags)
+{
+	schedule();
+	return 0;
+}
+
+/*
+ * record the fact that an object is now active
+ */
+static void cachefiles_mark_object_active(struct cachefiles_cache *cache,
+					  struct cachefiles_object *object)
+{
+	struct cachefiles_object *xobject;
+	struct rb_node **_p, *_parent = NULL;
+	struct dentry *dentry;
+
+	_enter(",%p", object);
+
+try_again:
+	write_lock(&cache->active_lock);
+
+	if (test_and_set_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags))
+		BUG();
+
+	dentry = object->dentry;
+	_p = &cache->active_nodes.rb_node;
+	while (*_p) {
+		_parent = *_p;
+		xobject = rb_entry(_parent,
+				   struct cachefiles_object, active_node);
+
+		ASSERT(xobject != object);
+
+		if (xobject->dentry > dentry)
+			_p = &(*_p)->rb_left;
+		else if (xobject->dentry < dentry)
+			_p = &(*_p)->rb_right;
+		else
+			goto wait_for_old_object;
+	}
+
+	rb_link_node(&object->active_node, _parent, _p);
+	rb_insert_color(&object->active_node, &cache->active_nodes);
+
+	write_unlock(&cache->active_lock);
+	_leave("");
+	return;
+
+	/* an old object from a previous incarnation is hogging the slot - we
+	 * need to wait for it to be destroyed */
+wait_for_old_object:
+	if (xobject->fscache.state < FSCACHE_OBJECT_DYING) {
+		printk(KERN_ERR "\n");
+		printk(KERN_ERR "CacheFiles: Error:"
+		       " Unexpected object collision\n");
+		printk(KERN_ERR "xobject: OBJ%x\n",
+		       xobject->fscache.debug_id);
+		printk(KERN_ERR "xobjstate=%s\n",
+		       fscache_object_states[xobject->fscache.state]);
+		printk(KERN_ERR "xobjflags=%lx\n", xobject->fscache.flags);
+		printk(KERN_ERR "xobjevent=%lx [%lx]\n",
+		       xobject->fscache.events, xobject->fscache.event_mask);
+		printk(KERN_ERR "xops=%u inp=%u exc=%u\n",
+		       xobject->fscache.n_ops, xobject->fscache.n_in_progress,
+		       xobject->fscache.n_exclusive);
+		printk(KERN_ERR "xcookie=%p [pr=%p nd=%p fl=%lx]\n",
+		       xobject->fscache.cookie,
+		       xobject->fscache.cookie->parent,
+		       xobject->fscache.cookie->netfs_data,
+		       xobject->fscache.cookie->flags);
+		printk(KERN_ERR "xparent=%p\n",
+		       xobject->fscache.parent);
+		printk(KERN_ERR "object: OBJ%x\n",
+		       object->fscache.debug_id);
+		printk(KERN_ERR "cookie=%p [pr=%p nd=%p fl=%lx]\n",
+		       object->fscache.cookie,
+		       object->fscache.cookie->parent,
+		       object->fscache.cookie->netfs_data,
+		       object->fscache.cookie->flags);
+		printk(KERN_ERR "parent=%p\n",
+		       object->fscache.parent);
+		BUG();
+	}
+	atomic_inc(&xobject->usage);
+	write_unlock(&cache->active_lock);
+
+	_debug(">>> wait");
+	wait_on_bit(&xobject->flags, CACHEFILES_OBJECT_ACTIVE,
+		    cachefiles_wait_bit, TASK_UNINTERRUPTIBLE);
+	_debug("<<< waited");
+
+	cache->cache.ops->put_object(&xobject->fscache);
+	goto try_again;
+}
+
+/*
+ * delete an object representation from the cache
+ * - file backed objects are unlinked
+ * - directory backed objects are stuffed into the graveyard for userspace to
+ *   delete
+ * - unlocks the directory mutex
+ */
+static int cachefiles_bury_object(struct cachefiles_cache *cache,
+				  struct dentry *dir,
+				  struct dentry *rep)
+{
+	struct dentry *grave, *trap;
+	char nbuffer[8 + 8 + 1];
+	int ret;
+
+	_enter(",'%*.*s','%*.*s'",
+	       dir->d_name.len, dir->d_name.len, dir->d_name.name,
+	       rep->d_name.len, rep->d_name.len, rep->d_name.name);
+
+	/* non-directories can just be unlinked */
+	if (!S_ISDIR(rep->d_inode->i_mode)) {
+		_debug("unlink stale object");
+		ret = vfs_unlink(dir->d_inode, rep);
+
+		mutex_unlock(&dir->d_inode->i_mutex);
+
+		if (ret == -EIO)
+			cachefiles_io_error(cache, "Unlink failed");
+
+		_leave(" = %d", ret);
+		return ret;
+	}
+
+	/* directories have to be moved to the graveyard */
+	_debug("move stale object to graveyard");
+	mutex_unlock(&dir->d_inode->i_mutex);
+
+try_again:
+	/* first step is to make up a grave dentry in the graveyard */
+	sprintf(nbuffer, "%08x%08x",
+		(uint32_t) get_seconds(),
+		(uint32_t) atomic_inc_return(&cache->gravecounter));
+
+	/* do the multiway lock magic */
+	trap = lock_rename(cache->graveyard, dir);
+
+	/* do some checks before getting the grave dentry */
+	if (rep->d_parent != dir) {
+		/* the entry was probably culled when we dropped the parent dir
+		 * lock */
+		unlock_rename(cache->graveyard, dir);
+		_leave(" = 0 [culled?]");
+		return 0;
+	}
+
+	if (!S_ISDIR(cache->graveyard->d_inode->i_mode)) {
+		unlock_rename(cache->graveyard, dir);
+		cachefiles_io_error(cache, "Graveyard no longer a directory");
+		return -EIO;
+	}
+
+	if (trap == rep) {
+		unlock_rename(cache->graveyard, dir);
+		cachefiles_io_error(cache, "May not make directory loop");
+		return -EIO;
+	}
+
+	if (d_mountpoint(rep)) {
+		unlock_rename(cache->graveyard, dir);
+		cachefiles_io_error(cache, "Mountpoint in cache");
+		return -EIO;
+	}
+
+	grave = lookup_one_len(nbuffer, cache->graveyard, strlen(nbuffer));
+	if (IS_ERR(grave)) {
+		unlock_rename(cache->graveyard, dir);
+
+		if (PTR_ERR(grave) == -ENOMEM) {
+			_leave(" = -ENOMEM");
+			return -ENOMEM;
+		}
+
+		cachefiles_io_error(cache, "Lookup error %ld",
+				    PTR_ERR(grave));
+		return -EIO;
+	}
+
+	if (grave->d_inode) {
+		unlock_rename(cache->graveyard, dir);
+		dput(grave);
+		grave = NULL;
+		cond_resched();
+		goto try_again;
+	}
+
+	if (d_mountpoint(grave)) {
+		unlock_rename(cache->graveyard, dir);
+		dput(grave);
+		cachefiles_io_error(cache, "Mountpoint in graveyard");
+		return -EIO;
+	}
+
+	/* target should not be an ancestor of source */
+	if (trap == grave) {
+		unlock_rename(cache->graveyard, dir);
+		dput(grave);
+		cachefiles_io_error(cache, "May not make directory loop");
+		return -EIO;
+	}
+
+	/* attempt the rename */
+	ret = vfs_rename(dir->d_inode, rep, cache->graveyard->d_inode, grave);
+	if (ret != 0 && ret != -ENOMEM)
+		cachefiles_io_error(cache, "Rename failed with error %d", ret);
+
+	unlock_rename(cache->graveyard, dir);
+	dput(grave);
+	_leave(" = 0");
+	return 0;
+}
+
+/*
+ * delete an object representation from the cache
+ */
+int cachefiles_delete_object(struct cachefiles_cache *cache,
+			     struct cachefiles_object *object)
+{
+	struct dentry *dir;
+	int ret;
+
+	_enter(",{%p}", object->dentry);
+
+	ASSERT(object->dentry);
+	ASSERT(object->dentry->d_inode);
+	ASSERT(object->dentry->d_parent);
+
+	dir = dget_parent(object->dentry);
+
+	mutex_lock(&dir->d_inode->i_mutex);
+	ret = cachefiles_bury_object(cache, dir, object->dentry);
+
+	dput(dir);
+	_leave(" = %d", ret);
+	return ret;
+}
+
+/*
+ * walk from the parent object to the child object through the backing
+ * filesystem, creating directories as we go
+ */
+int cachefiles_walk_to_object(struct cachefiles_object *parent,
+			      struct cachefiles_object *object,
+			      const char *key,
+			      struct cachefiles_xattr *auxdata)
+{
+	struct cachefiles_cache *cache;
+	struct dentry *dir, *next = NULL;
+	unsigned long start;
+	const char *name;
+	int ret, nlen;
+
+	_enter("{%p},,%s,", parent->dentry, key);
+
+	cache = container_of(parent->fscache.cache,
+			     struct cachefiles_cache, cache);
+
+	ASSERT(parent->dentry);
+	ASSERT(parent->dentry->d_inode);
+
+	if (!(S_ISDIR(parent->dentry->d_inode->i_mode))) {
+		// TODO: convert file to dir
+		_leave("looking up in none directory");
+		return -ENOBUFS;
+	}
+
+	dir = dget(parent->dentry);
+
+advance:
+	/* attempt to transit the first directory component */
+	name = key;
+	nlen = strlen(key);
+
+	/* key ends in a double NUL */
+	key = key + nlen + 1;
+	if (!*key)
+		key = NULL;
+
+lookup_again:
+	/* search the current directory for the element name */
+	_debug("lookup '%s'", name);
+
+	mutex_lock(&dir->d_inode->i_mutex);
+
+	start = jiffies;
+	next = lookup_one_len(name, dir, nlen);
+	cachefiles_hist(cachefiles_lookup_histogram, start);
+	if (IS_ERR(next))
+		goto lookup_error;
+
+	_debug("next -> %p %s", next, next->d_inode ? "positive" : "negative");
+
+	if (!key)
+		object->new = !next->d_inode;
+
+	/* if this element of the path doesn't exist, then the lookup phase
+	 * failed, and we can release any readers in the certain knowledge that
+	 * there's nothing for them to actually read */
+	if (!next->d_inode)
+		fscache_object_lookup_negative(&object->fscache);
+
+	/* we need to create the object if it's negative */
+	if (key || object->type == FSCACHE_COOKIE_TYPE_INDEX) {
+		/* index objects and intervening tree levels must be subdirs */
+		if (!next->d_inode) {
+			ret = cachefiles_has_space(cache, 1, 0);
+			if (ret < 0)
+				goto create_error;
+
+			start = jiffies;
+			ret = vfs_mkdir(dir->d_inode, next, 0);
+			cachefiles_hist(cachefiles_mkdir_histogram, start);
+			if (ret < 0)
+				goto create_error;
+
+			ASSERT(next->d_inode);
+
+			_debug("mkdir -> %p{%p{ino=%lu}}",
+			       next, next->d_inode, next->d_inode->i_ino);
+
+		} else if (!S_ISDIR(next->d_inode->i_mode)) {
+			kerror("inode %lu is not a directory",
+			       next->d_inode->i_ino);
+			ret = -ENOBUFS;
+			goto error;
+		}
+
+	} else {
+		/* non-index objects start out life as files */
+		if (!next->d_inode) {
+			ret = cachefiles_has_space(cache, 1, 0);
+			if (ret < 0)
+				goto create_error;
+
+			start = jiffies;
+			ret = vfs_create(dir->d_inode, next, S_IFREG, NULL);
+			cachefiles_hist(cachefiles_create_histogram, start);
+			if (ret < 0)
+				goto create_error;
+
+			ASSERT(next->d_inode);
+
+			_debug("create -> %p{%p{ino=%lu}}",
+			       next, next->d_inode, next->d_inode->i_ino);
+
+		} else if (!S_ISDIR(next->d_inode->i_mode) &&
+			   !S_ISREG(next->d_inode->i_mode)
+			   ) {
+			kerror("inode %lu is not a file or directory",
+			       next->d_inode->i_ino);
+			ret = -ENOBUFS;
+			goto error;
+		}
+	}
+
+	/* process the next component */
+	if (key) {
+		_debug("advance");
+		mutex_unlock(&dir->d_inode->i_mutex);
+		dput(dir);
+		dir = next;
+		next = NULL;
+		goto advance;
+	}
+
+	/* we've found the object we were looking for */
+	object->dentry = next;
+
+	/* if we've found that the terminal object exists, then we need to
+	 * check its attributes and delete it if it's out of date */
+	if (!object->new) {
+		_debug("validate '%*.*s'",
+		       next->d_name.len, next->d_name.len, next->d_name.name);
+
+		ret = cachefiles_check_object_xattr(object, auxdata);
+		if (ret == -ESTALE) {
+			/* delete the object (the deleter drops the directory
+			 * mutex) */
+			object->dentry = NULL;
+
+			ret = cachefiles_bury_object(cache, dir, next);
+			dput(next);
+			next = NULL;
+
+			if (ret < 0)
+				goto delete_error;
+
+			_debug("redo lookup");
+			goto lookup_again;
+		}
+	}
+
+	/* note that we're now using this object */
+	cachefiles_mark_object_active(cache, object);
+
+	mutex_unlock(&dir->d_inode->i_mutex);
+	dput(dir);
+	dir = NULL;
+
+	_debug("=== OBTAINED_OBJECT ===");
+
+	if (object->new) {
+		/* attach data to a newly constructed terminal object */
+		ret = cachefiles_set_object_xattr(object, auxdata);
+		if (ret < 0)
+			goto check_error;
+	} else {
+		/* always update the atime on an object we've just looked up
+		 * (this is used to keep track of culling, and atimes are only
+		 * updated by read, write and readdir but not lookup or
+		 * open) */
+		touch_atime(cache->mnt, next);
+	}
+
+	/* open a file interface onto a data file */
+	if (object->type != FSCACHE_COOKIE_TYPE_INDEX) {
+		if (S_ISREG(object->dentry->d_inode->i_mode)) {
+			const struct address_space_operations *aops;
+
+			ret = -EPERM;
+			aops = object->dentry->d_inode->i_mapping->a_ops;
+			if (!aops->bmap)
+				goto check_error;
+
+			object->backer = object->dentry;
+		} else {
+			BUG(); // TODO: open file in data-class subdir
+		}
+	}
+
+	object->new = 0;
+	fscache_obtained_object(&object->fscache);
+
+	_leave(" = 0 [%lu]", object->dentry->d_inode->i_ino);
+	return 0;
+
+create_error:
+	_debug("create error %d", ret);
+	if (ret == -EIO)
+		cachefiles_io_error(cache, "Create/mkdir failed");
+	goto error;
+
+check_error:
+	_debug("check error %d", ret);
+	write_lock(&cache->active_lock);
+	rb_erase(&object->active_node, &cache->active_nodes);
+	clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags);
+	wake_up_bit(&object->flags, CACHEFILES_OBJECT_ACTIVE);
+	write_unlock(&cache->active_lock);
+
+	dput(object->dentry);
+	object->dentry = NULL;
+	goto error_out;
+
+delete_error:
+	_debug("delete error %d", ret);
+	goto error_out2;
+
+lookup_error:
+	_debug("lookup error %ld", PTR_ERR(next));
+	ret = PTR_ERR(next);
+	if (ret == -EIO)
+		cachefiles_io_error(cache, "Lookup failed");
+	next = NULL;
+error:
+	mutex_unlock(&dir->d_inode->i_mutex);
+	dput(next);
+error_out2:
+	dput(dir);
+error_out:
+	if (ret == -ENOSPC)
+		ret = -ENOBUFS;
+
+	_leave(" = error %d", -ret);
+	return ret;
+}
+
+/*
+ * get a subdirectory
+ */
+struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
+					struct dentry *dir,
+					const char *dirname)
+{
+	struct dentry *subdir;
+	unsigned long start;
+	int ret;
+
+	_enter(",,%s", dirname);
+
+	/* search the current directory for the element name */
+	mutex_lock(&dir->d_inode->i_mutex);
+
+	start = jiffies;
+	subdir = lookup_one_len(dirname, dir, strlen(dirname));
+	cachefiles_hist(cachefiles_lookup_histogram, start);
+	if (IS_ERR(subdir)) {
+		if (PTR_ERR(subdir) == -ENOMEM)
+			goto nomem_d_alloc;
+		goto lookup_error;
+	}
+
+	_debug("subdir -> %p %s",
+	       subdir, subdir->d_inode ? "positive" : "negative");
+
+	/* we need to create the subdir if it doesn't exist yet */
+	if (!subdir->d_inode) {
+		ret = cachefiles_has_space(cache, 1, 0);
+		if (ret < 0)
+			goto mkdir_error;
+
+		_debug("attempt mkdir");
+
+		ret = vfs_mkdir(dir->d_inode, subdir, 0700);
+		if (ret < 0)
+			goto mkdir_error;
+
+		ASSERT(subdir->d_inode);
+
+		_debug("mkdir -> %p{%p{ino=%lu}}",
+		       subdir,
+		       subdir->d_inode,
+		       subdir->d_inode->i_ino);
+	}
+
+	mutex_unlock(&dir->d_inode->i_mutex);
+
+	/* we need to make sure the subdir is a directory */
+	ASSERT(subdir->d_inode);
+
+	if (!S_ISDIR(subdir->d_inode->i_mode)) {
+		kerror("%s is not a directory", dirname);
+		ret = -EIO;
+		goto check_error;
+	}
+
+	ret = -EPERM;
+	if (!subdir->d_inode->i_op ||
+	    !subdir->d_inode->i_op->setxattr ||
+	    !subdir->d_inode->i_op->getxattr ||
+	    !subdir->d_inode->i_op->lookup ||
+	    !subdir->d_inode->i_op->mkdir ||
+	    !subdir->d_inode->i_op->create ||
+	    !subdir->d_inode->i_op->rename ||
+	    !subdir->d_inode->i_op->rmdir ||
+	    !subdir->d_inode->i_op->unlink)
+		goto check_error;
+
+	_leave(" = [%lu]", subdir->d_inode->i_ino);
+	return subdir;
+
+check_error:
+	dput(subdir);
+	_leave(" = %d [check]", ret);
+	return ERR_PTR(ret);
+
+mkdir_error:
+	mutex_unlock(&dir->d_inode->i_mutex);
+	dput(subdir);
+	kerror("mkdir %s failed with error %d", dirname, ret);
+	return ERR_PTR(ret);
+
+lookup_error:
+	mutex_unlock(&dir->d_inode->i_mutex);
+	ret = PTR_ERR(subdir);
+	kerror("Lookup %s failed with error %d", dirname, ret);
+	return ERR_PTR(ret);
+
+nomem_d_alloc:
+	mutex_unlock(&dir->d_inode->i_mutex);
+	_leave(" = -ENOMEM");
+	return ERR_PTR(-ENOMEM);
+}
+
+/*
+ * find out if an object is in use or not
+ * - if finds object and it's not in use:
+ *   - returns a pointer to the object and a reference on it
+ *   - returns with the directory locked
+ */
+static struct dentry *cachefiles_check_active(struct cachefiles_cache *cache,
+					      struct dentry *dir,
+					      char *filename)
+{
+	struct cachefiles_object *object;
+	struct rb_node *_n;
+	struct dentry *victim;
+	unsigned long start;
+	int ret;
+
+	//_enter(",%*.*s/,%s",
+	//       dir->d_name.len, dir->d_name.len, dir->d_name.name, filename);
+
+	/* look up the victim */
+	mutex_lock_nested(&dir->d_inode->i_mutex, 1);
+
+	start = jiffies;
+	victim = lookup_one_len(filename, dir, strlen(filename));
+	cachefiles_hist(cachefiles_lookup_histogram, start);
+	if (IS_ERR(victim))
+		goto lookup_error;
+
+	//_debug("victim -> %p %s",
+	//       victim, victim->d_inode ? "positive" : "negative");
+
+	/* if the object is no longer there then we probably retired the object
+	 * at the netfs's request whilst the cull was in progress
+	 */
+	if (!victim->d_inode) {
+		mutex_unlock(&dir->d_inode->i_mutex);
+		dput(victim);
+		_leave(" = -ENOENT [absent]");
+		return ERR_PTR(-ENOENT);
+	}
+
+	/* check to see if we're using this object */
+	read_lock(&cache->active_lock);
+
+	_n = cache->active_nodes.rb_node;
+
+	while (_n) {
+		object = rb_entry(_n, struct cachefiles_object, active_node);
+
+		if (object->dentry > victim)
+			_n = _n->rb_left;
+		else if (object->dentry < victim)
+			_n = _n->rb_right;
+		else
+			goto object_in_use;
+	}
+
+	read_unlock(&cache->active_lock);
+
+	//_leave(" = %p", victim);
+	return victim;
+
+object_in_use:
+	read_unlock(&cache->active_lock);
+	mutex_unlock(&dir->d_inode->i_mutex);
+	dput(victim);
+	//_leave(" = -EBUSY [in use]");
+	return ERR_PTR(-EBUSY);
+
+lookup_error:
+	mutex_unlock(&dir->d_inode->i_mutex);
+	ret = PTR_ERR(victim);
+	if (ret == -ENOENT) {
+		/* file or dir now absent - probably retired by netfs */
+		_leave(" = -ESTALE [absent]");
+		return ERR_PTR(-ESTALE);
+	}
+
+	if (ret == -EIO) {
+		cachefiles_io_error(cache, "Lookup failed");
+	} else if (ret != -ENOMEM) {
+		kerror("Internal error: %d", ret);
+		ret = -EIO;
+	}
+
+	_leave(" = %d", ret);
+	return ERR_PTR(ret);
+}
+
+/*
+ * cull an object if it's not in use
+ * - called only by cache manager daemon
+ */
+int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir,
+		    char *filename)
+{
+	struct dentry *victim;
+	int ret;
+
+	_enter(",%*.*s/,%s",
+	       dir->d_name.len, dir->d_name.len, dir->d_name.name, filename);
+
+	victim = cachefiles_check_active(cache, dir, filename);
+	if (IS_ERR(victim))
+		return PTR_ERR(victim);
+
+	_debug("victim -> %p %s",
+	       victim, victim->d_inode ? "positive" : "negative");
+
+	/* okay... the victim is not being used so we can cull it
+	 * - start by marking it as stale
+	 */
+	_debug("victim is cullable");
+
+	ret = cachefiles_remove_object_xattr(cache, victim);
+	if (ret < 0)
+		goto error_unlock;
+
+	/*  actually remove the victim (drops the dir mutex) */
+	_debug("bury");
+
+	ret = cachefiles_bury_object(cache, dir, victim);
+	if (ret < 0)
+		goto error;
+
+	dput(victim);
+	_leave(" = 0");
+	return 0;
+
+error_unlock:
+	mutex_unlock(&dir->d_inode->i_mutex);
+error:
+	dput(victim);
+	if (ret == -ENOENT) {
+		/* file or dir now absent - probably retired by netfs */
+		_leave(" = -ESTALE [absent]");
+		return -ESTALE;
+	}
+
+	if (ret != -ENOMEM) {
+		kerror("Internal error: %d", ret);
+		ret = -EIO;
+	}
+
+	_leave(" = %d", ret);
+	return ret;
+}
+
+/*
+ * find out if an object is in use or not
+ * - called only by cache manager daemon
+ * - returns -EBUSY or 0 to indicate whether an object is in use or not
+ */
+int cachefiles_check_in_use(struct cachefiles_cache *cache, struct dentry *dir,
+			    char *filename)
+{
+	struct dentry *victim;
+
+	//_enter(",%*.*s/,%s",
+	//       dir->d_name.len, dir->d_name.len, dir->d_name.name, filename);
+
+	victim = cachefiles_check_active(cache, dir, filename);
+	if (IS_ERR(victim))
+		return PTR_ERR(victim);
+
+	mutex_unlock(&dir->d_inode->i_mutex);
+	dput(victim);
+	//_leave(" = 0");
+	return 0;
+}
diff --git a/fs/cachefiles/proc.c b/fs/cachefiles/proc.c
new file mode 100644
index 0000000..eccd339
--- /dev/null
+++ b/fs/cachefiles/proc.c
@@ -0,0 +1,134 @@
+/* CacheFiles statistics
+ *
+ * Copyright (C) 2007 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 <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include "internal.h"
+
+atomic_t cachefiles_lookup_histogram[HZ];
+atomic_t cachefiles_mkdir_histogram[HZ];
+atomic_t cachefiles_create_histogram[HZ];
+
+/*
+ * display the latency histogram
+ */
+static int cachefiles_histogram_show(struct seq_file *m, void *v)
+{
+	unsigned long index;
+	unsigned x, y, z, t;
+
+	switch ((unsigned long) v) {
+	case 1:
+		seq_puts(m, "JIFS  SECS  LOOKUPS   MKDIRS    CREATES\n");
+		return 0;
+	case 2:
+		seq_puts(m, "===== ===== ========= ========= =========\n");
+		return 0;
+	default:
+		index = (unsigned long) v - 3;
+		x = atomic_read(&cachefiles_lookup_histogram[index]);
+		y = atomic_read(&cachefiles_mkdir_histogram[index]);
+		z = atomic_read(&cachefiles_create_histogram[index]);
+		if (x == 0 && y == 0 && z == 0)
+			return 0;
+
+		t = (index * 1000) / HZ;
+
+		seq_printf(m, "%4lu  0.%03u %9u %9u %9u\n", index, t, x, y, z);
+		return 0;
+	}
+}
+
+/*
+ * set up the iterator to start reading from the first line
+ */
+static void *cachefiles_histogram_start(struct seq_file *m, loff_t *_pos)
+{
+	if ((unsigned long long)*_pos >= HZ + 2)
+		return NULL;
+	if (*_pos == 0)
+		*_pos = 1;
+	return (void *)(unsigned long) *_pos;
+}
+
+/*
+ * move to the next line
+ */
+static void *cachefiles_histogram_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	(*pos)++;
+	return (unsigned long long)*pos > HZ + 2 ?
+		NULL : (void *)(unsigned long) *pos;
+}
+
+/*
+ * clean up after reading
+ */
+static void cachefiles_histogram_stop(struct seq_file *m, void *v)
+{
+}
+
+static const struct seq_operations cachefiles_histogram_ops = {
+	.start		= cachefiles_histogram_start,
+	.stop		= cachefiles_histogram_stop,
+	.next		= cachefiles_histogram_next,
+	.show		= cachefiles_histogram_show,
+};
+
+/*
+ * open "/proc/fs/cachefiles/XXX" which provide statistics summaries
+ */
+static int cachefiles_histogram_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &cachefiles_histogram_ops);
+}
+
+static const struct file_operations cachefiles_histogram_fops = {
+	.owner		= THIS_MODULE,
+	.open		= cachefiles_histogram_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release,
+};
+
+/*
+ * initialise the /proc/fs/cachefiles/ directory
+ */
+int __init cachefiles_proc_init(void)
+{
+	_enter("");
+
+	if (!proc_mkdir("fs/cachefiles", NULL))
+		goto error_dir;
+
+	if (!proc_create("fs/cachefiles/histogram", S_IFREG | 0444, NULL,
+			 &cachefiles_histogram_fops))
+		goto error_histogram;
+
+	_leave(" = 0");
+	return 0;
+
+error_histogram:
+	remove_proc_entry("fs/cachefiles", NULL);
+error_dir:
+	_leave(" = -ENOMEM");
+	return -ENOMEM;
+}
+
+/*
+ * clean up the /proc/fs/cachefiles/ directory
+ */
+void cachefiles_proc_cleanup(void)
+{
+	remove_proc_entry("fs/cachefiles/histogram", NULL);
+	remove_proc_entry("fs/cachefiles", NULL);
+}
diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c
new file mode 100644
index 0000000..a69787e
--- /dev/null
+++ b/fs/cachefiles/rdwr.c
@@ -0,0 +1,879 @@
+/* Storage object read/write
+ *
+ * Copyright (C) 2007 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 <linux/mount.h>
+#include <linux/file.h>
+#include "internal.h"
+
+/*
+ * detect wake up events generated by the unlocking of pages in which we're
+ * interested
+ * - we use this to detect read completion of backing pages
+ * - the caller holds the waitqueue lock
+ */
+static int cachefiles_read_waiter(wait_queue_t *wait, unsigned mode,
+				  int sync, void *_key)
+{
+	struct cachefiles_one_read *monitor =
+		container_of(wait, struct cachefiles_one_read, monitor);
+	struct cachefiles_object *object;
+	struct wait_bit_key *key = _key;
+	struct page *page = wait->private;
+
+	ASSERT(key);
+
+	_enter("{%lu},%u,%d,{%p,%u}",
+	       monitor->netfs_page->index, mode, sync,
+	       key->flags, key->bit_nr);
+
+	if (key->flags != &page->flags ||
+	    key->bit_nr != PG_locked)
+		return 0;
+
+	_debug("--- monitor %p %lx ---", page, page->flags);
+
+	if (!PageUptodate(page) && !PageError(page))
+		dump_stack();
+
+	/* remove from the waitqueue */
+	list_del(&wait->task_list);
+
+	/* move onto the action list and queue for FS-Cache thread pool */
+	ASSERT(monitor->op);
+
+	object = container_of(monitor->op->op.object,
+			      struct cachefiles_object, fscache);
+
+	spin_lock(&object->work_lock);
+	list_add_tail(&monitor->op_link, &monitor->op->to_do);
+	spin_unlock(&object->work_lock);
+
+	fscache_enqueue_retrieval(monitor->op);
+	return 0;
+}
+
+/*
+ * copy data from backing pages to netfs pages to complete a read operation
+ * - driven by FS-Cache's thread pool
+ */
+static void cachefiles_read_copier(struct fscache_operation *_op)
+{
+	struct cachefiles_one_read *monitor;
+	struct cachefiles_object *object;
+	struct fscache_retrieval *op;
+	struct pagevec pagevec;
+	int error, max;
+
+	op = container_of(_op, struct fscache_retrieval, op);
+	object = container_of(op->op.object,
+			      struct cachefiles_object, fscache);
+
+	_enter("{ino=%lu}", object->backer->d_inode->i_ino);
+
+	pagevec_init(&pagevec, 0);
+
+	max = 8;
+	spin_lock_irq(&object->work_lock);
+
+	while (!list_empty(&op->to_do)) {
+		monitor = list_entry(op->to_do.next,
+				     struct cachefiles_one_read, op_link);
+		list_del(&monitor->op_link);
+
+		spin_unlock_irq(&object->work_lock);
+
+		_debug("- copy {%lu}", monitor->back_page->index);
+
+		error = -EIO;
+		if (PageUptodate(monitor->back_page)) {
+			copy_highpage(monitor->netfs_page, monitor->back_page);
+
+			pagevec_add(&pagevec, monitor->netfs_page);
+			fscache_mark_pages_cached(monitor->op, &pagevec);
+			error = 0;
+		}
+
+		if (error)
+			cachefiles_io_error_obj(
+				object,
+				"Readpage failed on backing file %lx",
+				(unsigned long) monitor->back_page->flags);
+
+		page_cache_release(monitor->back_page);
+
+		fscache_end_io(op, monitor->netfs_page, error);
+		page_cache_release(monitor->netfs_page);
+		fscache_put_retrieval(op);
+		kfree(monitor);
+
+		/* let the thread pool have some air occasionally */
+		max--;
+		if (max < 0 || need_resched()) {
+			if (!list_empty(&op->to_do))
+				fscache_enqueue_retrieval(op);
+			_leave(" [maxed out]");
+			return;
+		}
+
+		spin_lock_irq(&object->work_lock);
+	}
+
+	spin_unlock_irq(&object->work_lock);
+	_leave("");
+}
+
+/*
+ * read the corresponding page to the given set from the backing file
+ * - an uncertain page is simply discarded, to be tried again another time
+ */
+static int cachefiles_read_backing_file_one(struct cachefiles_object *object,
+					    struct fscache_retrieval *op,
+					    struct page *netpage,
+					    struct pagevec *pagevec)
+{
+	struct cachefiles_one_read *monitor;
+	struct address_space *bmapping;
+	struct page *newpage, *backpage;
+	int ret;
+
+	_enter("");
+
+	pagevec_reinit(pagevec);
+
+	_debug("read back %p{%lu,%d}",
+	       netpage, netpage->index, page_count(netpage));
+
+	monitor = kzalloc(sizeof(*monitor), GFP_KERNEL);
+	if (!monitor)
+		goto nomem;
+
+	monitor->netfs_page = netpage;
+	monitor->op = fscache_get_retrieval(op);
+
+	init_waitqueue_func_entry(&monitor->monitor, cachefiles_read_waiter);
+
+	/* attempt to get hold of the backing page */
+	bmapping = object->backer->d_inode->i_mapping;
+	newpage = NULL;
+
+	for (;;) {
+		backpage = find_get_page(bmapping, netpage->index);
+		if (backpage)
+			goto backing_page_already_present;
+
+		if (!newpage) {
+			newpage = page_cache_alloc_cold(bmapping);
+			if (!newpage)
+				goto nomem_monitor;
+		}
+
+		ret = add_to_page_cache(newpage, bmapping,
+					netpage->index, GFP_KERNEL);
+		if (ret == 0)
+			goto installed_new_backing_page;
+		if (ret != -EEXIST)
+			goto nomem_page;
+	}
+
+	/* we've installed a new backing page, so now we need to add it
+	 * to the LRU list and start it reading */
+installed_new_backing_page:
+	_debug("- new %p", newpage);
+
+	backpage = newpage;
+	newpage = NULL;
+
+	page_cache_get(backpage);
+	pagevec_add(pagevec, backpage);
+	__pagevec_lru_add_file(pagevec);
+
+read_backing_page:
+	ret = bmapping->a_ops->readpage(NULL, backpage);
+	if (ret < 0)
+		goto read_error;
+
+	/* set the monitor to transfer the data across */
+monitor_backing_page:
+	_debug("- monitor add");
+
+	/* install the monitor */
+	page_cache_get(monitor->netfs_page);
+	page_cache_get(backpage);
+	monitor->back_page = backpage;
+	monitor->monitor.private = backpage;
+	add_page_wait_queue(backpage, &monitor->monitor);
+	monitor = NULL;
+
+	/* but the page may have been read before the monitor was installed, so
+	 * the monitor may miss the event - so we have to ensure that we do get
+	 * one in such a case */
+	if (trylock_page(backpage)) {
+		_debug("jumpstart %p {%lx}", backpage, backpage->flags);
+		unlock_page(backpage);
+	}
+	goto success;
+
+	/* if the backing page is already present, it can be in one of
+	 * three states: read in progress, read failed or read okay */
+backing_page_already_present:
+	_debug("- present");
+
+	if (newpage) {
+		page_cache_release(newpage);
+		newpage = NULL;
+	}
+
+	if (PageError(backpage))
+		goto io_error;
+
+	if (PageUptodate(backpage))
+		goto backing_page_already_uptodate;
+
+	if (!trylock_page(backpage))
+		goto monitor_backing_page;
+	_debug("read %p {%lx}", backpage, backpage->flags);
+	goto read_backing_page;
+
+	/* the backing page is already up to date, attach the netfs
+	 * page to the pagecache and LRU and copy the data across */
+backing_page_already_uptodate:
+	_debug("- uptodate");
+
+	pagevec_add(pagevec, netpage);
+	fscache_mark_pages_cached(op, pagevec);
+
+	copy_highpage(netpage, backpage);
+	fscache_end_io(op, netpage, 0);
+
+success:
+	_debug("success");
+	ret = 0;
+
+out:
+	if (backpage)
+		page_cache_release(backpage);
+	if (monitor) {
+		fscache_put_retrieval(monitor->op);
+		kfree(monitor);
+	}
+	_leave(" = %d", ret);
+	return ret;
+
+read_error:
+	_debug("read error %d", ret);
+	if (ret == -ENOMEM)
+		goto out;
+io_error:
+	cachefiles_io_error_obj(object, "Page read error on backing file");
+	ret = -ENOBUFS;
+	goto out;
+
+nomem_page:
+	page_cache_release(newpage);
+nomem_monitor:
+	fscache_put_retrieval(monitor->op);
+	kfree(monitor);
+nomem:
+	_leave(" = -ENOMEM");
+	return -ENOMEM;
+}
+
+/*
+ * read a page from the cache or allocate a block in which to store it
+ * - cache withdrawal is prevented by the caller
+ * - returns -EINTR if interrupted
+ * - returns -ENOMEM if ran out of memory
+ * - returns -ENOBUFS if no buffers can be made available
+ * - returns -ENOBUFS if page is beyond EOF
+ * - if the page is backed by a block in the cache:
+ *   - a read will be started which will call the callback on completion
+ *   - 0 will be returned
+ * - else if the page is unbacked:
+ *   - the metadata will be retained
+ *   - -ENODATA will be returned
+ */
+int cachefiles_read_or_alloc_page(struct fscache_retrieval *op,
+				  struct page *page,
+				  gfp_t gfp)
+{
+	struct cachefiles_object *object;
+	struct cachefiles_cache *cache;
+	struct pagevec pagevec;
+	struct inode *inode;
+	sector_t block0, block;
+	unsigned shift;
+	int ret;
+
+	object = container_of(op->op.object,
+			      struct cachefiles_object, fscache);
+	cache = container_of(object->fscache.cache,
+			     struct cachefiles_cache, cache);
+
+	_enter("{%p},{%lx},,,", object, page->index);
+
+	if (!object->backer)
+		return -ENOBUFS;
+
+	inode = object->backer->d_inode;
+	ASSERT(S_ISREG(inode->i_mode));
+	ASSERT(inode->i_mapping->a_ops->bmap);
+	ASSERT(inode->i_mapping->a_ops->readpages);
+
+	/* calculate the shift required to use bmap */
+	if (inode->i_sb->s_blocksize > PAGE_SIZE)
+		return -ENOBUFS;
+
+	shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits;
+
+	op->op.flags = FSCACHE_OP_FAST;
+	op->op.processor = cachefiles_read_copier;
+
+	pagevec_init(&pagevec, 0);
+
+	/* we assume the absence or presence of the first block is a good
+	 * enough indication for the page as a whole
+	 * - TODO: don't use bmap() for this as it is _not_ actually good
+	 *   enough for this as it doesn't indicate errors, but it's all we've
+	 *   got for the moment
+	 */
+	block0 = page->index;
+	block0 <<= shift;
+
+	block = inode->i_mapping->a_ops->bmap(inode->i_mapping, block0);
+	_debug("%llx -> %llx",
+	       (unsigned long long) block0,
+	       (unsigned long long) block);
+
+	if (block) {
+		/* submit the apparently valid page to the backing fs to be
+		 * read from disk */
+		ret = cachefiles_read_backing_file_one(object, op, page,
+						       &pagevec);
+	} else if (cachefiles_has_space(cache, 0, 1) == 0) {
+		/* there's space in the cache we can use */
+		pagevec_add(&pagevec, page);
+		fscache_mark_pages_cached(op, &pagevec);
+		ret = -ENODATA;
+	} else {
+		ret = -ENOBUFS;
+	}
+
+	_leave(" = %d", ret);
+	return ret;
+}
+
+/*
+ * read the corresponding pages to the given set from the backing file
+ * - any uncertain pages are simply discarded, to be tried again another time
+ */
+static int cachefiles_read_backing_file(struct cachefiles_object *object,
+					struct fscache_retrieval *op,
+					struct list_head *list,
+					struct pagevec *mark_pvec)
+{
+	struct cachefiles_one_read *monitor = NULL;
+	struct address_space *bmapping = object->backer->d_inode->i_mapping;
+	struct pagevec lru_pvec;
+	struct page *newpage = NULL, *netpage, *_n, *backpage = NULL;
+	int ret = 0;
+
+	_enter("");
+
+	pagevec_init(&lru_pvec, 0);
+
+	list_for_each_entry_safe(netpage, _n, list, lru) {
+		list_del(&netpage->lru);
+
+		_debug("read back %p{%lu,%d}",
+		       netpage, netpage->index, page_count(netpage));
+
+		if (!monitor) {
+			monitor = kzalloc(sizeof(*monitor), GFP_KERNEL);
+			if (!monitor)
+				goto nomem;
+
+			monitor->op = fscache_get_retrieval(op);
+			init_waitqueue_func_entry(&monitor->monitor,
+						  cachefiles_read_waiter);
+		}
+
+		for (;;) {
+			backpage = find_get_page(bmapping, netpage->index);
+			if (backpage)
+				goto backing_page_already_present;
+
+			if (!newpage) {
+				newpage = page_cache_alloc_cold(bmapping);
+				if (!newpage)
+					goto nomem;
+			}
+
+			ret = add_to_page_cache(newpage, bmapping,
+						netpage->index, GFP_KERNEL);
+			if (ret == 0)
+				goto installed_new_backing_page;
+			if (ret != -EEXIST)
+				goto nomem;
+		}
+
+		/* we've installed a new backing page, so now we need to add it
+		 * to the LRU list and start it reading */
+	installed_new_backing_page:
+		_debug("- new %p", newpage);
+
+		backpage = newpage;
+		newpage = NULL;
+
+		page_cache_get(backpage);
+		if (!pagevec_add(&lru_pvec, backpage))
+			__pagevec_lru_add_file(&lru_pvec);
+
+	reread_backing_page:
+		ret = bmapping->a_ops->readpage(NULL, backpage);
+		if (ret < 0)
+			goto read_error;
+
+		/* add the netfs page to the pagecache and LRU, and set the
+		 * monitor to transfer the data across */
+	monitor_backing_page:
+		_debug("- monitor add");
+
+		ret = add_to_page_cache(netpage, op->mapping, netpage->index,
+					GFP_KERNEL);
+		if (ret < 0) {
+			if (ret == -EEXIST) {
+				page_cache_release(netpage);
+				continue;
+			}
+			goto nomem;
+		}
+
+		page_cache_get(netpage);
+		if (!pagevec_add(&lru_pvec, netpage))
+			__pagevec_lru_add_file(&lru_pvec);
+
+		/* install a monitor */
+		page_cache_get(netpage);
+		monitor->netfs_page = netpage;
+
+		page_cache_get(backpage);
+		monitor->back_page = backpage;
+		monitor->monitor.private = backpage;
+		add_page_wait_queue(backpage, &monitor->monitor);
+		monitor = NULL;
+
+		/* but the page may have been read before the monitor was
+		 * installed, so the monitor may miss the event - so we have to
+		 * ensure that we do get one in such a case */
+		if (trylock_page(backpage)) {
+			_debug("2unlock %p {%lx}", backpage, backpage->flags);
+			unlock_page(backpage);
+		}
+
+		page_cache_release(backpage);
+		backpage = NULL;
+
+		page_cache_release(netpage);
+		netpage = NULL;
+		continue;
+
+		/* if the backing page is already present, it can be in one of
+		 * three states: read in progress, read failed or read okay */
+	backing_page_already_present:
+		_debug("- present %p", backpage);
+
+		if (PageError(backpage))
+			goto io_error;
+
+		if (PageUptodate(backpage))
+			goto backing_page_already_uptodate;
+
+		_debug("- not ready %p{%lx}", backpage, backpage->flags);
+
+		if (!trylock_page(backpage))
+			goto monitor_backing_page;
+
+		if (PageError(backpage)) {
+			_debug("error %lx", backpage->flags);
+			unlock_page(backpage);
+			goto io_error;
+		}
+
+		if (PageUptodate(backpage))
+			goto backing_page_already_uptodate_unlock;
+
+		/* we've locked a page that's neither up to date nor erroneous,
+		 * so we need to attempt to read it again */
+		goto reread_backing_page;
+
+		/* the backing page is already up to date, attach the netfs
+		 * page to the pagecache and LRU and copy the data across */
+	backing_page_already_uptodate_unlock:
+		_debug("uptodate %lx", backpage->flags);
+		unlock_page(backpage);
+	backing_page_already_uptodate:
+		_debug("- uptodate");
+
+		ret = add_to_page_cache(netpage, op->mapping, netpage->index,
+					GFP_KERNEL);
+		if (ret < 0) {
+			if (ret == -EEXIST) {
+				page_cache_release(netpage);
+				continue;
+			}
+			goto nomem;
+		}
+
+		copy_highpage(netpage, backpage);
+
+		page_cache_release(backpage);
+		backpage = NULL;
+
+		if (!pagevec_add(mark_pvec, netpage))
+			fscache_mark_pages_cached(op, mark_pvec);
+
+		page_cache_get(netpage);
+		if (!pagevec_add(&lru_pvec, netpage))
+			__pagevec_lru_add_file(&lru_pvec);
+
+		fscache_end_io(op, netpage, 0);
+		page_cache_release(netpage);
+		netpage = NULL;
+		continue;
+	}
+
+	netpage = NULL;
+
+	_debug("out");
+
+out:
+	/* tidy up */
+	pagevec_lru_add_file(&lru_pvec);
+
+	if (newpage)
+		page_cache_release(newpage);
+	if (netpage)
+		page_cache_release(netpage);
+	if (backpage)
+		page_cache_release(backpage);
+	if (monitor) {
+		fscache_put_retrieval(op);
+		kfree(monitor);
+	}
+
+	list_for_each_entry_safe(netpage, _n, list, lru) {
+		list_del(&netpage->lru);
+		page_cache_release(netpage);
+	}
+
+	_leave(" = %d", ret);
+	return ret;
+
+nomem:
+	_debug("nomem");
+	ret = -ENOMEM;
+	goto out;
+
+read_error:
+	_debug("read error %d", ret);
+	if (ret == -ENOMEM)
+		goto out;
+io_error:
+	cachefiles_io_error_obj(object, "Page read error on backing file");
+	ret = -ENOBUFS;
+	goto out;
+}
+
+/*
+ * read a list of pages from the cache or allocate blocks in which to store
+ * them
+ */
+int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op,
+				   struct list_head *pages,
+				   unsigned *nr_pages,
+				   gfp_t gfp)
+{
+	struct cachefiles_object *object;
+	struct cachefiles_cache *cache;
+	struct list_head backpages;
+	struct pagevec pagevec;
+	struct inode *inode;
+	struct page *page, *_n;
+	unsigned shift, nrbackpages;
+	int ret, ret2, space;
+
+	object = container_of(op->op.object,
+			      struct cachefiles_object, fscache);
+	cache = container_of(object->fscache.cache,
+			     struct cachefiles_cache, cache);
+
+	_enter("{OBJ%x,%d},,%d,,",
+	       object->fscache.debug_id, atomic_read(&op->op.usage),
+	       *nr_pages);
+
+	if (!object->backer)
+		return -ENOBUFS;
+
+	space = 1;
+	if (cachefiles_has_space(cache, 0, *nr_pages) < 0)
+		space = 0;
+
+	inode = object->backer->d_inode;
+	ASSERT(S_ISREG(inode->i_mode));
+	ASSERT(inode->i_mapping->a_ops->bmap);
+	ASSERT(inode->i_mapping->a_ops->readpages);
+
+	/* calculate the shift required to use bmap */
+	if (inode->i_sb->s_blocksize > PAGE_SIZE)
+		return -ENOBUFS;
+
+	shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits;
+
+	pagevec_init(&pagevec, 0);
+
+	op->op.flags = FSCACHE_OP_FAST;
+	op->op.processor = cachefiles_read_copier;
+
+	INIT_LIST_HEAD(&backpages);
+	nrbackpages = 0;
+
+	ret = space ? -ENODATA : -ENOBUFS;
+	list_for_each_entry_safe(page, _n, pages, lru) {
+		sector_t block0, block;
+
+		/* we assume the absence or presence of the first block is a
+		 * good enough indication for the page as a whole
+		 * - TODO: don't use bmap() for this as it is _not_ actually
+		 *   good enough for this as it doesn't indicate errors, but
+		 *   it's all we've got for the moment
+		 */
+		block0 = page->index;
+		block0 <<= shift;
+
+		block = inode->i_mapping->a_ops->bmap(inode->i_mapping,
+						      block0);
+		_debug("%llx -> %llx",
+		       (unsigned long long) block0,
+		       (unsigned long long) block);
+
+		if (block) {
+			/* we have data - add it to the list to give to the
+			 * backing fs */
+			list_move(&page->lru, &backpages);
+			(*nr_pages)--;
+			nrbackpages++;
+		} else if (space && pagevec_add(&pagevec, page) == 0) {
+			fscache_mark_pages_cached(op, &pagevec);
+			ret = -ENODATA;
+		}
+	}
+
+	if (pagevec_count(&pagevec) > 0)
+		fscache_mark_pages_cached(op, &pagevec);
+
+	if (list_empty(pages))
+		ret = 0;
+
+	/* submit the apparently valid pages to the backing fs to be read from
+	 * disk */
+	if (nrbackpages > 0) {
+		ret2 = cachefiles_read_backing_file(object, op, &backpages,
+						    &pagevec);
+		if (ret2 == -ENOMEM || ret2 == -EINTR)
+			ret = ret2;
+	}
+
+	if (pagevec_count(&pagevec) > 0)
+		fscache_mark_pages_cached(op, &pagevec);
+
+	_leave(" = %d [nr=%u%s]",
+	       ret, *nr_pages, list_empty(pages) ? " empty" : "");
+	return ret;
+}
+
+/*
+ * allocate a block in the cache in which to store a page
+ * - cache withdrawal is prevented by the caller
+ * - returns -EINTR if interrupted
+ * - returns -ENOMEM if ran out of memory
+ * - returns -ENOBUFS if no buffers can be made available
+ * - returns -ENOBUFS if page is beyond EOF
+ * - otherwise:
+ *   - the metadata will be retained
+ *   - 0 will be returned
+ */
+int cachefiles_allocate_page(struct fscache_retrieval *op,
+			     struct page *page,
+			     gfp_t gfp)
+{
+	struct cachefiles_object *object;
+	struct cachefiles_cache *cache;
+	struct pagevec pagevec;
+	int ret;
+
+	object = container_of(op->op.object,
+			      struct cachefiles_object, fscache);
+	cache = container_of(object->fscache.cache,
+			     struct cachefiles_cache, cache);
+
+	_enter("%p,{%lx},", object, page->index);
+
+	ret = cachefiles_has_space(cache, 0, 1);
+	if (ret == 0) {
+		pagevec_init(&pagevec, 0);
+		pagevec_add(&pagevec, page);
+		fscache_mark_pages_cached(op, &pagevec);
+	} else {
+		ret = -ENOBUFS;
+	}
+
+	_leave(" = %d", ret);
+	return ret;
+}
+
+/*
+ * allocate blocks in the cache in which to store a set of pages
+ * - cache withdrawal is prevented by the caller
+ * - returns -EINTR if interrupted
+ * - returns -ENOMEM if ran out of memory
+ * - returns -ENOBUFS if some buffers couldn't be made available
+ * - returns -ENOBUFS if some pages are beyond EOF
+ * - otherwise:
+ *   - -ENODATA will be returned
+ * - metadata will be retained for any page marked
+ */
+int cachefiles_allocate_pages(struct fscache_retrieval *op,
+			      struct list_head *pages,
+			      unsigned *nr_pages,
+			      gfp_t gfp)
+{
+	struct cachefiles_object *object;
+	struct cachefiles_cache *cache;
+	struct pagevec pagevec;
+	struct page *page;
+	int ret;
+
+	object = container_of(op->op.object,
+			      struct cachefiles_object, fscache);
+	cache = container_of(object->fscache.cache,
+			     struct cachefiles_cache, cache);
+
+	_enter("%p,,,%d,", object, *nr_pages);
+
+	ret = cachefiles_has_space(cache, 0, *nr_pages);
+	if (ret == 0) {
+		pagevec_init(&pagevec, 0);
+
+		list_for_each_entry(page, pages, lru) {
+			if (pagevec_add(&pagevec, page) == 0)
+				fscache_mark_pages_cached(op, &pagevec);
+		}
+
+		if (pagevec_count(&pagevec) > 0)
+			fscache_mark_pages_cached(op, &pagevec);
+		ret = -ENODATA;
+	} else {
+		ret = -ENOBUFS;
+	}
+
+	_leave(" = %d", ret);
+	return ret;
+}
+
+/*
+ * request a page be stored in the cache
+ * - cache withdrawal is prevented by the caller
+ * - this request may be ignored if there's no cache block available, in which
+ *   case -ENOBUFS will be returned
+ * - if the op is in progress, 0 will be returned
+ */
+int cachefiles_write_page(struct fscache_storage *op, struct page *page)
+{
+	struct cachefiles_object *object;
+	struct cachefiles_cache *cache;
+	mm_segment_t old_fs;
+	struct file *file;
+	loff_t pos;
+	void *data;
+	int ret;
+
+	ASSERT(op != NULL);
+	ASSERT(page != NULL);
+
+	object = container_of(op->op.object,
+			      struct cachefiles_object, fscache);
+
+	_enter("%p,%p{%lx},,,", object, page, page->index);
+
+	if (!object->backer) {
+		_leave(" = -ENOBUFS");
+		return -ENOBUFS;
+	}
+
+	ASSERT(S_ISREG(object->backer->d_inode->i_mode));
+
+	cache = container_of(object->fscache.cache,
+			     struct cachefiles_cache, cache);
+
+	/* write the page to the backing filesystem and let it store it in its
+	 * own time */
+	dget(object->backer);
+	mntget(cache->mnt);
+	file = dentry_open(object->backer, cache->mnt, O_RDWR,
+			   cache->cache_cred);
+	if (IS_ERR(file)) {
+		ret = PTR_ERR(file);
+	} else {
+		ret = -EIO;
+		if (file->f_op->write) {
+			pos = (loff_t) page->index << PAGE_SHIFT;
+			data = kmap(page);
+			old_fs = get_fs();
+			set_fs(KERNEL_DS);
+			ret = file->f_op->write(
+				file, (const void __user *) data, PAGE_SIZE,
+				&pos);
+			set_fs(old_fs);
+			kunmap(page);
+			if (ret != PAGE_SIZE)
+				ret = -EIO;
+		}
+		fput(file);
+	}
+
+	if (ret < 0) {
+		if (ret == -EIO)
+			cachefiles_io_error_obj(
+				object, "Write page to backing file failed");
+		ret = -ENOBUFS;
+	}
+
+	_leave(" = %d", ret);
+	return ret;
+}
+
+/*
+ * detach a backing block from a page
+ * - cache withdrawal is prevented by the caller
+ */
+void cachefiles_uncache_page(struct fscache_object *_object, struct page *page)
+{
+	struct cachefiles_object *object;
+	struct cachefiles_cache *cache;
+
+	object = container_of(_object, struct cachefiles_object, fscache);
+	cache = container_of(object->fscache.cache,
+			     struct cachefiles_cache, cache);
+
+	_enter("%p,{%lu}", object, page->index);
+
+	spin_unlock(&object->fscache.cookie->lock);
+}
diff --git a/fs/cachefiles/security.c b/fs/cachefiles/security.c
new file mode 100644
index 0000000..b5808cd
--- /dev/null
+++ b/fs/cachefiles/security.c
@@ -0,0 +1,116 @@
+/* CacheFiles security management
+ *
+ * Copyright (C) 2007 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 <linux/fs.h>
+#include <linux/cred.h>
+#include "internal.h"
+
+/*
+ * determine the security context within which we access the cache from within
+ * the kernel
+ */
+int cachefiles_get_security_ID(struct cachefiles_cache *cache)
+{
+	struct cred *new;
+	int ret;
+
+	_enter("{%s}", cache->secctx);
+
+	new = prepare_kernel_cred(current);
+	if (!new) {
+		ret = -ENOMEM;
+		goto error;
+	}
+
+	if (cache->secctx) {
+		ret = set_security_override_from_ctx(new, cache->secctx);
+		if (ret < 0) {
+			put_cred(new);
+			printk(KERN_ERR "CacheFiles:"
+			       " Security denies permission to nominate"
+			       " security context: error %d\n",
+			       ret);
+			goto error;
+		}
+	}
+
+	cache->cache_cred = new;
+	ret = 0;
+error:
+	_leave(" = %d", ret);
+	return ret;
+}
+
+/*
+ * see if mkdir and create can be performed in the root directory
+ */
+static int cachefiles_check_cache_dir(struct cachefiles_cache *cache,
+				      struct dentry *root)
+{
+	int ret;
+
+	ret = security_inode_mkdir(root->d_inode, root, 0);
+	if (ret < 0) {
+		printk(KERN_ERR "CacheFiles:"
+		       " Security denies permission to make dirs: error %d",
+		       ret);
+		return ret;
+	}
+
+	ret = security_inode_create(root->d_inode, root, 0);
+	if (ret < 0)
+		printk(KERN_ERR "CacheFiles:"
+		       " Security denies permission to create files: error %d",
+		       ret);
+
+	return ret;
+}
+
+/*
+ * check the security details of the on-disk cache
+ * - must be called with security override in force
+ */
+int cachefiles_determine_cache_security(struct cachefiles_cache *cache,
+					struct dentry *root,
+					const struct cred **_saved_cred)
+{
+	struct cred *new;
+	int ret;
+
+	_enter("");
+
+	/* duplicate the cache creds for COW (the override is currently in
+	 * force, so we can use prepare_creds() to do this) */
+	new = prepare_creds();
+	if (!new)
+		return -ENOMEM;
+
+	cachefiles_end_secure(cache, *_saved_cred);
+
+	/* use the cache root dir's security context as the basis with
+	 * which create files */
+	ret = set_create_files_as(new, root->d_inode);
+	if (ret < 0) {
+		_leave(" = %d [cfa]", ret);
+		return ret;
+	}
+
+	put_cred(cache->cache_cred);
+	cache->cache_cred = new;
+
+	cachefiles_begin_secure(cache, _saved_cred);
+	ret = cachefiles_check_cache_dir(cache, root);
+
+	if (ret == -EOPNOTSUPP)
+		ret = 0;
+	_leave(" = %d", ret);
+	return ret;
+}
diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c
new file mode 100644
index 0000000..f3e7a0b
--- /dev/null
+++ b/fs/cachefiles/xattr.c
@@ -0,0 +1,291 @@
+/* CacheFiles extended attribute management
+ *
+ * Copyright (C) 2007 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 <linux/module.h>
+#include <linux/sched.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/fsnotify.h>
+#include <linux/quotaops.h>
+#include <linux/xattr.h>
+#include "internal.h"
+
+static const char cachefiles_xattr_cache[] =
+	XATTR_USER_PREFIX "CacheFiles.cache";
+
+/*
+ * check the type label on an object
+ * - done using xattrs
+ */
+int cachefiles_check_object_type(struct cachefiles_object *object)
+{
+	struct dentry *dentry = object->dentry;
+	char type[3], xtype[3];
+	int ret;
+
+	ASSERT(dentry);
+	ASSERT(dentry->d_inode);
+
+	if (!object->fscache.cookie)
+		strcpy(type, "C3");
+	else
+		snprintf(type, 3, "%02x", object->fscache.cookie->def->type);
+
+	_enter("%p{%s}", object, type);
+
+	/* attempt to install a type label directly */
+	ret = vfs_setxattr(dentry, cachefiles_xattr_cache, type, 2,
+			   XATTR_CREATE);
+	if (ret == 0) {
+		_debug("SET"); /* we succeeded */
+		goto error;
+	}
+
+	if (ret != -EEXIST) {
+		kerror("Can't set xattr on %*.*s [%lu] (err %d)",
+		       dentry->d_name.len, dentry->d_name.len,
+		       dentry->d_name.name, dentry->d_inode->i_ino,
+		       -ret);
+		goto error;
+	}
+
+	/* read the current type label */
+	ret = vfs_getxattr(dentry, cachefiles_xattr_cache, xtype, 3);
+	if (ret < 0) {
+		if (ret == -ERANGE)
+			goto bad_type_length;
+
+		kerror("Can't read xattr on %*.*s [%lu] (err %d)",
+		       dentry->d_name.len, dentry->d_name.len,
+		       dentry->d_name.name, dentry->d_inode->i_ino,
+		       -ret);
+		goto error;
+	}
+
+	/* check the type is what we're expecting */
+	if (ret != 2)
+		goto bad_type_length;
+
+	if (xtype[0] != type[0] || xtype[1] != type[1])
+		goto bad_type;
+
+	ret = 0;
+
+error:
+	_leave(" = %d", ret);
+	return ret;
+
+bad_type_length:
+	kerror("Cache object %lu type xattr length incorrect",
+	       dentry->d_inode->i_ino);
+	ret = -EIO;
+	goto error;
+
+bad_type:
+	xtype[2] = 0;
+	kerror("Cache object %*.*s [%lu] type %s not %s",
+	       dentry->d_name.len, dentry->d_name.len,
+	       dentry->d_name.name, dentry->d_inode->i_ino,
+	       xtype, type);
+	ret = -EIO;
+	goto error;
+}
+
+/*
+ * set the state xattr on a cache file
+ */
+int cachefiles_set_object_xattr(struct cachefiles_object *object,
+				struct cachefiles_xattr *auxdata)
+{
+	struct dentry *dentry = object->dentry;
+	int ret;
+
+	ASSERT(object->fscache.cookie);
+	ASSERT(dentry);
+
+	_enter("%p,#%d", object, auxdata->len);
+
+	/* attempt to install the cache metadata directly */
+	_debug("SET %s #%u", object->fscache.cookie->def->name, auxdata->len);
+
+	ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
+			   &auxdata->type, auxdata->len,
+			   XATTR_CREATE);
+	if (ret < 0 && ret != -ENOMEM)
+		cachefiles_io_error_obj(
+			object,
+			"Failed to set xattr with error %d", ret);
+
+	_leave(" = %d", ret);
+	return ret;
+}
+
+/*
+ * update the state xattr on a cache file
+ */
+int cachefiles_update_object_xattr(struct cachefiles_object *object,
+				   struct cachefiles_xattr *auxdata)
+{
+	struct dentry *dentry = object->dentry;
+	int ret;
+
+	ASSERT(object->fscache.cookie);
+	ASSERT(dentry);
+
+	_enter("%p,#%d", object, auxdata->len);
+
+	/* attempt to install the cache metadata directly */
+	_debug("SET %s #%u", object->fscache.cookie->def->name, auxdata->len);
+
+	ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
+			   &auxdata->type, auxdata->len,
+			   XATTR_REPLACE);
+	if (ret < 0 && ret != -ENOMEM)
+		cachefiles_io_error_obj(
+			object,
+			"Failed to update xattr with error %d", ret);
+
+	_leave(" = %d", ret);
+	return ret;
+}
+
+/*
+ * check the state xattr on a cache file
+ * - return -ESTALE if the object should be deleted
+ */
+int cachefiles_check_object_xattr(struct cachefiles_object *object,
+				  struct cachefiles_xattr *auxdata)
+{
+	struct cachefiles_xattr *auxbuf;
+	struct dentry *dentry = object->dentry;
+	int ret;
+
+	_enter("%p,#%d", object, auxdata->len);
+
+	ASSERT(dentry);
+	ASSERT(dentry->d_inode);
+
+	auxbuf = kmalloc(sizeof(struct cachefiles_xattr) + 512, GFP_KERNEL);
+	if (!auxbuf) {
+		_leave(" = -ENOMEM");
+		return -ENOMEM;
+	}
+
+	/* read the current type label */
+	ret = vfs_getxattr(dentry, cachefiles_xattr_cache,
+			   &auxbuf->type, 512 + 1);
+	if (ret < 0) {
+		if (ret == -ENODATA)
+			goto stale; /* no attribute - power went off
+				     * mid-cull? */
+
+		if (ret == -ERANGE)
+			goto bad_type_length;
+
+		cachefiles_io_error_obj(object,
+					"Can't read xattr on %lu (err %d)",
+					dentry->d_inode->i_ino, -ret);
+		goto error;
+	}
+
+	/* check the on-disk object */
+	if (ret < 1)
+		goto bad_type_length;
+
+	if (auxbuf->type != auxdata->type)
+		goto stale;
+
+	auxbuf->len = ret;
+
+	/* consult the netfs */
+	if (object->fscache.cookie->def->check_aux) {
+		enum fscache_checkaux result;
+		unsigned int dlen;
+
+		dlen = auxbuf->len - 1;
+
+		_debug("checkaux %s #%u",
+		       object->fscache.cookie->def->name, dlen);
+
+		result = fscache_check_aux(&object->fscache,
+					   &auxbuf->data, dlen);
+
+		switch (result) {
+			/* entry okay as is */
+		case FSCACHE_CHECKAUX_OKAY:
+			goto okay;
+
+			/* entry requires update */
+		case FSCACHE_CHECKAUX_NEEDS_UPDATE:
+			break;
+
+			/* entry requires deletion */
+		case FSCACHE_CHECKAUX_OBSOLETE:
+			goto stale;
+
+		default:
+			BUG();
+		}
+
+		/* update the current label */
+		ret = vfs_setxattr(dentry, cachefiles_xattr_cache,
+				   &auxdata->type, auxdata->len,
+				   XATTR_REPLACE);
+		if (ret < 0) {
+			cachefiles_io_error_obj(object,
+						"Can't update xattr on %lu"
+						" (error %d)",
+						dentry->d_inode->i_ino, -ret);
+			goto error;
+		}
+	}
+
+okay:
+	ret = 0;
+
+error:
+	kfree(auxbuf);
+	_leave(" = %d", ret);
+	return ret;
+
+bad_type_length:
+	kerror("Cache object %lu xattr length incorrect",
+	       dentry->d_inode->i_ino);
+	ret = -EIO;
+	goto error;
+
+stale:
+	ret = -ESTALE;
+	goto error;
+}
+
+/*
+ * remove the object's xattr to mark it stale
+ */
+int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
+				   struct dentry *dentry)
+{
+	int ret;
+
+	ret = vfs_removexattr(dentry, cachefiles_xattr_cache);
+	if (ret < 0) {
+		if (ret == -ENOENT || ret == -ENODATA)
+			ret = 0;
+		else if (ret != -ENOMEM)
+			cachefiles_io_error(cache,
+					    "Can't remove xattr from %lu"
+					    " (error %d)",
+					    dentry->d_inode->i_ino, -ret);
+	}
+
+	_leave(" = %d", ret);
+	return ret;
+}
diff --git a/fs/compat.c b/fs/compat.c
index 1c859da..3f84d5f 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1236,7 +1236,7 @@
 
 asmlinkage ssize_t
 compat_sys_preadv(unsigned long fd, const struct compat_iovec __user *vec,
-		  unsigned long vlen, u32 pos_high, u32 pos_low)
+		  unsigned long vlen, u32 pos_low, u32 pos_high)
 {
 	loff_t pos = ((loff_t)pos_high << 32) | pos_low;
 	struct file *file;
@@ -1293,7 +1293,7 @@
 
 asmlinkage ssize_t
 compat_sys_pwritev(unsigned long fd, const struct compat_iovec __user *vec,
-		   unsigned long vlen, u32 pos_high, u32 pos_low)
+		   unsigned long vlen, u32 pos_low, u32 pos_high)
 {
 	loff_t pos = ((loff_t)pos_high << 32) | pos_low;
 	struct file *file;
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index ff78668..3e87ce4 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -23,7 +23,7 @@
 #include <linux/if.h>
 #include <linux/if_bridge.h>
 #include <linux/slab.h>
-#include <linux/raid/md.h>
+#include <linux/raid/md_u.h>
 #include <linux/kd.h>
 #include <linux/route.h>
 #include <linux/in6.h>
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 81ae9ea..0662ba6 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -30,6 +30,7 @@
 
 static struct vfsmount *debugfs_mount;
 static int debugfs_mount_count;
+static bool debugfs_registered;
 
 static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t dev)
 {
@@ -496,6 +497,16 @@
 }
 EXPORT_SYMBOL_GPL(debugfs_rename);
 
+/**
+ * debugfs_initialized - Tells whether debugfs has been registered
+ */
+bool debugfs_initialized(void)
+{
+	return debugfs_registered;
+}
+EXPORT_SYMBOL_GPL(debugfs_initialized);
+
+
 static struct kobject *debug_kobj;
 
 static int __init debugfs_init(void)
@@ -509,11 +520,16 @@
 	retval = register_filesystem(&debug_fs_type);
 	if (retval)
 		kobject_put(debug_kobj);
+	else
+		debugfs_registered = true;
+
 	return retval;
 }
 
 static void __exit debugfs_exit(void)
 {
+	debugfs_registered = false;
+
 	simple_release_fs(&debugfs_mount, &debugfs_mount_count);
 	unregister_filesystem(&debug_fs_type);
 	kobject_put(debug_kobj);
diff --git a/fs/direct-io.c b/fs/direct-io.c
index b6d4390..da258e7 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -1126,7 +1126,7 @@
 	int acquire_i_mutex = 0;
 
 	if (rw & WRITE)
-		rw = WRITE_SYNC;
+		rw = WRITE_ODIRECT;
 
 	if (bdev)
 		bdev_blkbits = blksize_bits(bdev_hardsect_size(bdev));
diff --git a/fs/exofs/BUGS b/fs/exofs/BUGS
new file mode 100644
index 0000000..1b2d4c6
--- /dev/null
+++ b/fs/exofs/BUGS
@@ -0,0 +1,3 @@
+- Out-of-space may cause a severe problem if the object (and directory entry)
+  were written, but the inode attributes failed. Then if the filesystem was
+  unmounted and mounted the kernel can get into an endless loop doing a readdir.
diff --git a/fs/exofs/Kbuild b/fs/exofs/Kbuild
new file mode 100644
index 0000000..cc2d22d
--- /dev/null
+++ b/fs/exofs/Kbuild
@@ -0,0 +1,16 @@
+#
+# Kbuild for the EXOFS module
+#
+# Copyright (C) 2008 Panasas Inc.  All rights reserved.
+#
+# Authors:
+#   Boaz Harrosh <bharrosh@panasas.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
+#
+# Kbuild - Gets included from the Kernels Makefile and build system
+#
+
+exofs-y := osd.o inode.o file.o symlink.o namei.o dir.o super.o
+obj-$(CONFIG_EXOFS_FS) += exofs.o
diff --git a/fs/exofs/Kconfig b/fs/exofs/Kconfig
new file mode 100644
index 0000000..86194b2
--- /dev/null
+++ b/fs/exofs/Kconfig
@@ -0,0 +1,13 @@
+config EXOFS_FS
+	tristate "exofs: OSD based file system support"
+	depends on SCSI_OSD_ULD
+	help
+	  EXOFS is a file system that uses an OSD storage device,
+	  as its backing storage.
+
+# Debugging-related stuff
+config EXOFS_DEBUG
+	bool "Enable debugging"
+	depends on EXOFS_FS
+	help
+	  This option enables EXOFS debug prints.
diff --git a/fs/exofs/common.h b/fs/exofs/common.h
new file mode 100644
index 0000000..b1512c4
--- /dev/null
+++ b/fs/exofs/common.h
@@ -0,0 +1,184 @@
+/*
+ * common.h - Common definitions for both Kernel and user-mode utilities
+ *
+ * Copyright (C) 2005, 2006
+ * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com)
+ * Copyright (C) 2005, 2006
+ * International Business Machines
+ * Copyright (C) 2008, 2009
+ * Boaz Harrosh <bharrosh@panasas.com>
+ *
+ * Copyrights for code taken from ext2:
+ *     Copyright (C) 1992, 1993, 1994, 1995
+ *     Remy Card (card@masi.ibp.fr)
+ *     Laboratoire MASI - Institut Blaise Pascal
+ *     Universite Pierre et Marie Curie (Paris VI)
+ *     from
+ *     linux/fs/minix/inode.c
+ *     Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This file is part of exofs.
+ *
+ * exofs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.  Since it is based on ext2, and the only
+ * valid version of GPL for the Linux kernel is version 2, the only valid
+ * version of GPL for exofs is version 2.
+ *
+ * exofs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with exofs; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __EXOFS_COM_H__
+#define __EXOFS_COM_H__
+
+#include <linux/types.h>
+
+#include <scsi/osd_attributes.h>
+#include <scsi/osd_initiator.h>
+#include <scsi/osd_sec.h>
+
+/****************************************************************************
+ * Object ID related defines
+ * NOTE: inode# = object ID - EXOFS_OBJ_OFF
+ ****************************************************************************/
+#define EXOFS_MIN_PID   0x10000	/* Smallest partition ID */
+#define EXOFS_OBJ_OFF	0x10000	/* offset for objects */
+#define EXOFS_SUPER_ID	0x10000	/* object ID for on-disk superblock */
+#define EXOFS_ROOT_ID	0x10002	/* object ID for root directory */
+
+/* exofs Application specific page/attribute */
+# define EXOFS_APAGE_FS_DATA	(OSD_APAGE_APP_DEFINED_FIRST + 3)
+# define EXOFS_ATTR_INODE_DATA	1
+
+/*
+ * The maximum number of files we can have is limited by the size of the
+ * inode number.  This is the largest object ID that the file system supports.
+ * Object IDs 0, 1, and 2 are always in use (see above defines).
+ */
+enum {
+	EXOFS_MAX_INO_ID = (sizeof(ino_t) * 8 == 64) ? ULLONG_MAX :
+					(1ULL << (sizeof(ino_t) * 8ULL - 1ULL)),
+	EXOFS_MAX_ID	 = (EXOFS_MAX_INO_ID - 1 - EXOFS_OBJ_OFF),
+};
+
+/****************************************************************************
+ * Misc.
+ ****************************************************************************/
+#define EXOFS_BLKSHIFT	12
+#define EXOFS_BLKSIZE	(1UL << EXOFS_BLKSHIFT)
+
+/****************************************************************************
+ * superblock-related things
+ ****************************************************************************/
+#define EXOFS_SUPER_MAGIC	0x5DF5
+
+/*
+ * The file system control block - stored in an object's data (mainly, the one
+ * with ID EXOFS_SUPER_ID).  This is where the in-memory superblock is stored
+ * on disk.  Right now it just has a magic value, which is basically a sanity
+ * check on our ability to communicate with the object store.
+ */
+struct exofs_fscb {
+	__le64  s_nextid;	/* Highest object ID used */
+	__le32  s_numfiles;	/* Number of files on fs */
+	__le16  s_magic;	/* Magic signature */
+	__le16  s_newfs;	/* Non-zero if this is a new fs */
+};
+
+/****************************************************************************
+ * inode-related things
+ ****************************************************************************/
+#define EXOFS_IDATA		5
+
+/*
+ * The file control block - stored in an object's attributes.  This is where
+ * the in-memory inode is stored on disk.
+ */
+struct exofs_fcb {
+	__le64  i_size;			/* Size of the file */
+	__le16  i_mode;         	/* File mode */
+	__le16  i_links_count;  	/* Links count */
+	__le32  i_uid;          	/* Owner Uid */
+	__le32  i_gid;          	/* Group Id */
+	__le32  i_atime;        	/* Access time */
+	__le32  i_ctime;        	/* Creation time */
+	__le32  i_mtime;        	/* Modification time */
+	__le32  i_flags;        	/* File flags (unused for now)*/
+	__le32  i_generation;   	/* File version (for NFS) */
+	__le32  i_data[EXOFS_IDATA];	/* Short symlink names and device #s */
+};
+
+#define EXOFS_INO_ATTR_SIZE	sizeof(struct exofs_fcb)
+
+/* This is the Attribute the fcb is stored in */
+static const struct __weak osd_attr g_attr_inode_data = ATTR_DEF(
+	EXOFS_APAGE_FS_DATA,
+	EXOFS_ATTR_INODE_DATA,
+	EXOFS_INO_ATTR_SIZE);
+
+/****************************************************************************
+ * dentry-related things
+ ****************************************************************************/
+#define EXOFS_NAME_LEN	255
+
+/*
+ * The on-disk directory entry
+ */
+struct exofs_dir_entry {
+	__le64		inode_no;		/* inode number           */
+	__le16		rec_len;		/* directory entry length */
+	u8		name_len;		/* name length            */
+	u8		file_type;		/* umm...file type        */
+	char		name[EXOFS_NAME_LEN];	/* file name              */
+};
+
+enum {
+	EXOFS_FT_UNKNOWN,
+	EXOFS_FT_REG_FILE,
+	EXOFS_FT_DIR,
+	EXOFS_FT_CHRDEV,
+	EXOFS_FT_BLKDEV,
+	EXOFS_FT_FIFO,
+	EXOFS_FT_SOCK,
+	EXOFS_FT_SYMLINK,
+	EXOFS_FT_MAX
+};
+
+#define EXOFS_DIR_PAD			4
+#define EXOFS_DIR_ROUND			(EXOFS_DIR_PAD - 1)
+#define EXOFS_DIR_REC_LEN(name_len) \
+	(((name_len) + offsetof(struct exofs_dir_entry, name)  + \
+	  EXOFS_DIR_ROUND) & ~EXOFS_DIR_ROUND)
+
+/*************************
+ * function declarations *
+ *************************/
+/* osd.c                 */
+void exofs_make_credential(u8 cred_a[OSD_CAP_LEN],
+			   const struct osd_obj_id *obj);
+
+int exofs_check_ok_resid(struct osd_request *or, u64 *in_resid, u64 *out_resid);
+static inline int exofs_check_ok(struct osd_request *or)
+{
+	return exofs_check_ok_resid(or, NULL, NULL);
+}
+int exofs_sync_op(struct osd_request *or, int timeout, u8 *cred);
+int exofs_async_op(struct osd_request *or,
+	osd_req_done_fn *async_done, void *caller_context, u8 *cred);
+
+int extract_attr_from_req(struct osd_request *or, struct osd_attr *attr);
+
+int osd_req_read_kern(struct osd_request *or,
+	const struct osd_obj_id *obj, u64 offset, void *buff, u64 len);
+
+int osd_req_write_kern(struct osd_request *or,
+	const struct osd_obj_id *obj, u64 offset, void *buff, u64 len);
+
+#endif /*ifndef __EXOFS_COM_H__*/
diff --git a/fs/exofs/dir.c b/fs/exofs/dir.c
new file mode 100644
index 0000000..65b0c8c
--- /dev/null
+++ b/fs/exofs/dir.c
@@ -0,0 +1,672 @@
+/*
+ * Copyright (C) 2005, 2006
+ * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com)
+ * Copyright (C) 2005, 2006
+ * International Business Machines
+ * Copyright (C) 2008, 2009
+ * Boaz Harrosh <bharrosh@panasas.com>
+ *
+ * Copyrights for code taken from ext2:
+ *     Copyright (C) 1992, 1993, 1994, 1995
+ *     Remy Card (card@masi.ibp.fr)
+ *     Laboratoire MASI - Institut Blaise Pascal
+ *     Universite Pierre et Marie Curie (Paris VI)
+ *     from
+ *     linux/fs/minix/inode.c
+ *     Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This file is part of exofs.
+ *
+ * exofs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.  Since it is based on ext2, and the only
+ * valid version of GPL for the Linux kernel is version 2, the only valid
+ * version of GPL for exofs is version 2.
+ *
+ * exofs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with exofs; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "exofs.h"
+
+static inline unsigned exofs_chunk_size(struct inode *inode)
+{
+	return inode->i_sb->s_blocksize;
+}
+
+static inline void exofs_put_page(struct page *page)
+{
+	kunmap(page);
+	page_cache_release(page);
+}
+
+/* Accesses dir's inode->i_size must be called under inode lock */
+static inline unsigned long dir_pages(struct inode *inode)
+{
+	return (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+}
+
+static unsigned exofs_last_byte(struct inode *inode, unsigned long page_nr)
+{
+	loff_t last_byte = inode->i_size;
+
+	last_byte -= page_nr << PAGE_CACHE_SHIFT;
+	if (last_byte > PAGE_CACHE_SIZE)
+		last_byte = PAGE_CACHE_SIZE;
+	return last_byte;
+}
+
+static int exofs_commit_chunk(struct page *page, loff_t pos, unsigned len)
+{
+	struct address_space *mapping = page->mapping;
+	struct inode *dir = mapping->host;
+	int err = 0;
+
+	dir->i_version++;
+
+	if (!PageUptodate(page))
+		SetPageUptodate(page);
+
+	if (pos+len > dir->i_size) {
+		i_size_write(dir, pos+len);
+		mark_inode_dirty(dir);
+	}
+	set_page_dirty(page);
+
+	if (IS_DIRSYNC(dir))
+		err = write_one_page(page, 1);
+	else
+		unlock_page(page);
+
+	return err;
+}
+
+static void exofs_check_page(struct page *page)
+{
+	struct inode *dir = page->mapping->host;
+	unsigned chunk_size = exofs_chunk_size(dir);
+	char *kaddr = page_address(page);
+	unsigned offs, rec_len;
+	unsigned limit = PAGE_CACHE_SIZE;
+	struct exofs_dir_entry *p;
+	char *error;
+
+	/* if the page is the last one in the directory */
+	if ((dir->i_size >> PAGE_CACHE_SHIFT) == page->index) {
+		limit = dir->i_size & ~PAGE_CACHE_MASK;
+		if (limit & (chunk_size - 1))
+			goto Ebadsize;
+		if (!limit)
+			goto out;
+	}
+	for (offs = 0; offs <= limit - EXOFS_DIR_REC_LEN(1); offs += rec_len) {
+		p = (struct exofs_dir_entry *)(kaddr + offs);
+		rec_len = le16_to_cpu(p->rec_len);
+
+		if (rec_len < EXOFS_DIR_REC_LEN(1))
+			goto Eshort;
+		if (rec_len & 3)
+			goto Ealign;
+		if (rec_len < EXOFS_DIR_REC_LEN(p->name_len))
+			goto Enamelen;
+		if (((offs + rec_len - 1) ^ offs) & ~(chunk_size-1))
+			goto Espan;
+	}
+	if (offs != limit)
+		goto Eend;
+out:
+	SetPageChecked(page);
+	return;
+
+Ebadsize:
+	EXOFS_ERR("ERROR [exofs_check_page]: "
+		"size of directory #%lu is not a multiple of chunk size",
+		dir->i_ino
+	);
+	goto fail;
+Eshort:
+	error = "rec_len is smaller than minimal";
+	goto bad_entry;
+Ealign:
+	error = "unaligned directory entry";
+	goto bad_entry;
+Enamelen:
+	error = "rec_len is too small for name_len";
+	goto bad_entry;
+Espan:
+	error = "directory entry across blocks";
+	goto bad_entry;
+bad_entry:
+	EXOFS_ERR(
+		"ERROR [exofs_check_page]: bad entry in directory #%lu: %s - "
+		"offset=%lu, inode=%llu, rec_len=%d, name_len=%d",
+		dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
+		_LLU(le64_to_cpu(p->inode_no)),
+		rec_len, p->name_len);
+	goto fail;
+Eend:
+	p = (struct exofs_dir_entry *)(kaddr + offs);
+	EXOFS_ERR("ERROR [exofs_check_page]: "
+		"entry in directory #%lu spans the page boundary"
+		"offset=%lu, inode=%llu",
+		dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
+		_LLU(le64_to_cpu(p->inode_no)));
+fail:
+	SetPageChecked(page);
+	SetPageError(page);
+}
+
+static struct page *exofs_get_page(struct inode *dir, unsigned long n)
+{
+	struct address_space *mapping = dir->i_mapping;
+	struct page *page = read_mapping_page(mapping, n, NULL);
+
+	if (!IS_ERR(page)) {
+		kmap(page);
+		if (!PageChecked(page))
+			exofs_check_page(page);
+		if (PageError(page))
+			goto fail;
+	}
+	return page;
+
+fail:
+	exofs_put_page(page);
+	return ERR_PTR(-EIO);
+}
+
+static inline int exofs_match(int len, const unsigned char *name,
+					struct exofs_dir_entry *de)
+{
+	if (len != de->name_len)
+		return 0;
+	if (!de->inode_no)
+		return 0;
+	return !memcmp(name, de->name, len);
+}
+
+static inline
+struct exofs_dir_entry *exofs_next_entry(struct exofs_dir_entry *p)
+{
+	return (struct exofs_dir_entry *)((char *)p + le16_to_cpu(p->rec_len));
+}
+
+static inline unsigned
+exofs_validate_entry(char *base, unsigned offset, unsigned mask)
+{
+	struct exofs_dir_entry *de = (struct exofs_dir_entry *)(base + offset);
+	struct exofs_dir_entry *p =
+			(struct exofs_dir_entry *)(base + (offset&mask));
+	while ((char *)p < (char *)de) {
+		if (p->rec_len == 0)
+			break;
+		p = exofs_next_entry(p);
+	}
+	return (char *)p - base;
+}
+
+static unsigned char exofs_filetype_table[EXOFS_FT_MAX] = {
+	[EXOFS_FT_UNKNOWN]	= DT_UNKNOWN,
+	[EXOFS_FT_REG_FILE]	= DT_REG,
+	[EXOFS_FT_DIR]		= DT_DIR,
+	[EXOFS_FT_CHRDEV]	= DT_CHR,
+	[EXOFS_FT_BLKDEV]	= DT_BLK,
+	[EXOFS_FT_FIFO]		= DT_FIFO,
+	[EXOFS_FT_SOCK]		= DT_SOCK,
+	[EXOFS_FT_SYMLINK]	= DT_LNK,
+};
+
+#define S_SHIFT 12
+static unsigned char exofs_type_by_mode[S_IFMT >> S_SHIFT] = {
+	[S_IFREG >> S_SHIFT]	= EXOFS_FT_REG_FILE,
+	[S_IFDIR >> S_SHIFT]	= EXOFS_FT_DIR,
+	[S_IFCHR >> S_SHIFT]	= EXOFS_FT_CHRDEV,
+	[S_IFBLK >> S_SHIFT]	= EXOFS_FT_BLKDEV,
+	[S_IFIFO >> S_SHIFT]	= EXOFS_FT_FIFO,
+	[S_IFSOCK >> S_SHIFT]	= EXOFS_FT_SOCK,
+	[S_IFLNK >> S_SHIFT]	= EXOFS_FT_SYMLINK,
+};
+
+static inline
+void exofs_set_de_type(struct exofs_dir_entry *de, struct inode *inode)
+{
+	mode_t mode = inode->i_mode;
+	de->file_type = exofs_type_by_mode[(mode & S_IFMT) >> S_SHIFT];
+}
+
+static int
+exofs_readdir(struct file *filp, void *dirent, filldir_t filldir)
+{
+	loff_t pos = filp->f_pos;
+	struct inode *inode = filp->f_path.dentry->d_inode;
+	unsigned int offset = pos & ~PAGE_CACHE_MASK;
+	unsigned long n = pos >> PAGE_CACHE_SHIFT;
+	unsigned long npages = dir_pages(inode);
+	unsigned chunk_mask = ~(exofs_chunk_size(inode)-1);
+	unsigned char *types = NULL;
+	int need_revalidate = (filp->f_version != inode->i_version);
+
+	if (pos > inode->i_size - EXOFS_DIR_REC_LEN(1))
+		return 0;
+
+	types = exofs_filetype_table;
+
+	for ( ; n < npages; n++, offset = 0) {
+		char *kaddr, *limit;
+		struct exofs_dir_entry *de;
+		struct page *page = exofs_get_page(inode, n);
+
+		if (IS_ERR(page)) {
+			EXOFS_ERR("ERROR: "
+				   "bad page in #%lu",
+				   inode->i_ino);
+			filp->f_pos += PAGE_CACHE_SIZE - offset;
+			return PTR_ERR(page);
+		}
+		kaddr = page_address(page);
+		if (unlikely(need_revalidate)) {
+			if (offset) {
+				offset = exofs_validate_entry(kaddr, offset,
+								chunk_mask);
+				filp->f_pos = (n<<PAGE_CACHE_SHIFT) + offset;
+			}
+			filp->f_version = inode->i_version;
+			need_revalidate = 0;
+		}
+		de = (struct exofs_dir_entry *)(kaddr + offset);
+		limit = kaddr + exofs_last_byte(inode, n) -
+							EXOFS_DIR_REC_LEN(1);
+		for (; (char *)de <= limit; de = exofs_next_entry(de)) {
+			if (de->rec_len == 0) {
+				EXOFS_ERR("ERROR: "
+					"zero-length directory entry");
+				exofs_put_page(page);
+				return -EIO;
+			}
+			if (de->inode_no) {
+				int over;
+				unsigned char d_type = DT_UNKNOWN;
+
+				if (types && de->file_type < EXOFS_FT_MAX)
+					d_type = types[de->file_type];
+
+				offset = (char *)de - kaddr;
+				over = filldir(dirent, de->name, de->name_len,
+						(n<<PAGE_CACHE_SHIFT) | offset,
+						le64_to_cpu(de->inode_no),
+						d_type);
+				if (over) {
+					exofs_put_page(page);
+					return 0;
+				}
+			}
+			filp->f_pos += le16_to_cpu(de->rec_len);
+		}
+		exofs_put_page(page);
+	}
+
+	return 0;
+}
+
+struct exofs_dir_entry *exofs_find_entry(struct inode *dir,
+			struct dentry *dentry, struct page **res_page)
+{
+	const unsigned char *name = dentry->d_name.name;
+	int namelen = dentry->d_name.len;
+	unsigned reclen = EXOFS_DIR_REC_LEN(namelen);
+	unsigned long start, n;
+	unsigned long npages = dir_pages(dir);
+	struct page *page = NULL;
+	struct exofs_i_info *oi = exofs_i(dir);
+	struct exofs_dir_entry *de;
+
+	if (npages == 0)
+		goto out;
+
+	*res_page = NULL;
+
+	start = oi->i_dir_start_lookup;
+	if (start >= npages)
+		start = 0;
+	n = start;
+	do {
+		char *kaddr;
+		page = exofs_get_page(dir, n);
+		if (!IS_ERR(page)) {
+			kaddr = page_address(page);
+			de = (struct exofs_dir_entry *) kaddr;
+			kaddr += exofs_last_byte(dir, n) - reclen;
+			while ((char *) de <= kaddr) {
+				if (de->rec_len == 0) {
+					EXOFS_ERR(
+						"ERROR: exofs_find_entry: "
+						"zero-length directory entry");
+					exofs_put_page(page);
+					goto out;
+				}
+				if (exofs_match(namelen, name, de))
+					goto found;
+				de = exofs_next_entry(de);
+			}
+			exofs_put_page(page);
+		}
+		if (++n >= npages)
+			n = 0;
+	} while (n != start);
+out:
+	return NULL;
+
+found:
+	*res_page = page;
+	oi->i_dir_start_lookup = n;
+	return de;
+}
+
+struct exofs_dir_entry *exofs_dotdot(struct inode *dir, struct page **p)
+{
+	struct page *page = exofs_get_page(dir, 0);
+	struct exofs_dir_entry *de = NULL;
+
+	if (!IS_ERR(page)) {
+		de = exofs_next_entry(
+				(struct exofs_dir_entry *)page_address(page));
+		*p = page;
+	}
+	return de;
+}
+
+ino_t exofs_parent_ino(struct dentry *child)
+{
+	struct page *page;
+	struct exofs_dir_entry *de;
+	ino_t ino;
+
+	de = exofs_dotdot(child->d_inode, &page);
+	if (!de)
+		return 0;
+
+	ino = le64_to_cpu(de->inode_no);
+	exofs_put_page(page);
+	return ino;
+}
+
+ino_t exofs_inode_by_name(struct inode *dir, struct dentry *dentry)
+{
+	ino_t res = 0;
+	struct exofs_dir_entry *de;
+	struct page *page;
+
+	de = exofs_find_entry(dir, dentry, &page);
+	if (de) {
+		res = le64_to_cpu(de->inode_no);
+		exofs_put_page(page);
+	}
+	return res;
+}
+
+int exofs_set_link(struct inode *dir, struct exofs_dir_entry *de,
+			struct page *page, struct inode *inode)
+{
+	loff_t pos = page_offset(page) +
+			(char *) de - (char *) page_address(page);
+	unsigned len = le16_to_cpu(de->rec_len);
+	int err;
+
+	lock_page(page);
+	err = exofs_write_begin(NULL, page->mapping, pos, len,
+				AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
+	if (err)
+		EXOFS_ERR("exofs_set_link: exofs_write_begin FAILD => %d\n",
+			  err);
+
+	de->inode_no = cpu_to_le64(inode->i_ino);
+	exofs_set_de_type(de, inode);
+	if (likely(!err))
+		err = exofs_commit_chunk(page, pos, len);
+	exofs_put_page(page);
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	mark_inode_dirty(dir);
+	return err;
+}
+
+int exofs_add_link(struct dentry *dentry, struct inode *inode)
+{
+	struct inode *dir = dentry->d_parent->d_inode;
+	const unsigned char *name = dentry->d_name.name;
+	int namelen = dentry->d_name.len;
+	unsigned chunk_size = exofs_chunk_size(dir);
+	unsigned reclen = EXOFS_DIR_REC_LEN(namelen);
+	unsigned short rec_len, name_len;
+	struct page *page = NULL;
+	struct exofs_sb_info *sbi = inode->i_sb->s_fs_info;
+	struct exofs_dir_entry *de;
+	unsigned long npages = dir_pages(dir);
+	unsigned long n;
+	char *kaddr;
+	loff_t pos;
+	int err;
+
+	for (n = 0; n <= npages; n++) {
+		char *dir_end;
+
+		page = exofs_get_page(dir, n);
+		err = PTR_ERR(page);
+		if (IS_ERR(page))
+			goto out;
+		lock_page(page);
+		kaddr = page_address(page);
+		dir_end = kaddr + exofs_last_byte(dir, n);
+		de = (struct exofs_dir_entry *)kaddr;
+		kaddr += PAGE_CACHE_SIZE - reclen;
+		while ((char *)de <= kaddr) {
+			if ((char *)de == dir_end) {
+				name_len = 0;
+				rec_len = chunk_size;
+				de->rec_len = cpu_to_le16(chunk_size);
+				de->inode_no = 0;
+				goto got_it;
+			}
+			if (de->rec_len == 0) {
+				EXOFS_ERR("ERROR: exofs_add_link: "
+					"zero-length directory entry");
+				err = -EIO;
+				goto out_unlock;
+			}
+			err = -EEXIST;
+			if (exofs_match(namelen, name, de))
+				goto out_unlock;
+			name_len = EXOFS_DIR_REC_LEN(de->name_len);
+			rec_len = le16_to_cpu(de->rec_len);
+			if (!de->inode_no && rec_len >= reclen)
+				goto got_it;
+			if (rec_len >= name_len + reclen)
+				goto got_it;
+			de = (struct exofs_dir_entry *) ((char *) de + rec_len);
+		}
+		unlock_page(page);
+		exofs_put_page(page);
+	}
+
+	EXOFS_ERR("exofs_add_link: BAD dentry=%p or inode=%p", dentry, inode);
+	return -EINVAL;
+
+got_it:
+	pos = page_offset(page) +
+		(char *)de - (char *)page_address(page);
+	err = exofs_write_begin(NULL, page->mapping, pos, rec_len, 0,
+							&page, NULL);
+	if (err)
+		goto out_unlock;
+	if (de->inode_no) {
+		struct exofs_dir_entry *de1 =
+			(struct exofs_dir_entry *)((char *)de + name_len);
+		de1->rec_len = cpu_to_le16(rec_len - name_len);
+		de->rec_len = cpu_to_le16(name_len);
+		de = de1;
+	}
+	de->name_len = namelen;
+	memcpy(de->name, name, namelen);
+	de->inode_no = cpu_to_le64(inode->i_ino);
+	exofs_set_de_type(de, inode);
+	err = exofs_commit_chunk(page, pos, rec_len);
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	mark_inode_dirty(dir);
+	sbi->s_numfiles++;
+
+out_put:
+	exofs_put_page(page);
+out:
+	return err;
+out_unlock:
+	unlock_page(page);
+	goto out_put;
+}
+
+int exofs_delete_entry(struct exofs_dir_entry *dir, struct page *page)
+{
+	struct address_space *mapping = page->mapping;
+	struct inode *inode = mapping->host;
+	struct exofs_sb_info *sbi = inode->i_sb->s_fs_info;
+	char *kaddr = page_address(page);
+	unsigned from = ((char *)dir - kaddr) & ~(exofs_chunk_size(inode)-1);
+	unsigned to = ((char *)dir - kaddr) + le16_to_cpu(dir->rec_len);
+	loff_t pos;
+	struct exofs_dir_entry *pde = NULL;
+	struct exofs_dir_entry *de = (struct exofs_dir_entry *) (kaddr + from);
+	int err;
+
+	while (de < dir) {
+		if (de->rec_len == 0) {
+			EXOFS_ERR("ERROR: exofs_delete_entry:"
+				"zero-length directory entry");
+			err = -EIO;
+			goto out;
+		}
+		pde = de;
+		de = exofs_next_entry(de);
+	}
+	if (pde)
+		from = (char *)pde - (char *)page_address(page);
+	pos = page_offset(page) + from;
+	lock_page(page);
+	err = exofs_write_begin(NULL, page->mapping, pos, to - from, 0,
+							&page, NULL);
+	if (err)
+		EXOFS_ERR("exofs_delete_entry: exofs_write_begin FAILD => %d\n",
+			  err);
+	if (pde)
+		pde->rec_len = cpu_to_le16(to - from);
+	dir->inode_no = 0;
+	if (likely(!err))
+		err = exofs_commit_chunk(page, pos, to - from);
+	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	mark_inode_dirty(inode);
+	sbi->s_numfiles--;
+out:
+	exofs_put_page(page);
+	return err;
+}
+
+/* kept aligned on 4 bytes */
+#define THIS_DIR ".\0\0"
+#define PARENT_DIR "..\0"
+
+int exofs_make_empty(struct inode *inode, struct inode *parent)
+{
+	struct address_space *mapping = inode->i_mapping;
+	struct page *page = grab_cache_page(mapping, 0);
+	unsigned chunk_size = exofs_chunk_size(inode);
+	struct exofs_dir_entry *de;
+	int err;
+	void *kaddr;
+
+	if (!page)
+		return -ENOMEM;
+
+	err = exofs_write_begin(NULL, page->mapping, 0, chunk_size, 0,
+							&page, NULL);
+	if (err) {
+		unlock_page(page);
+		goto fail;
+	}
+
+	kaddr = kmap_atomic(page, KM_USER0);
+	de = (struct exofs_dir_entry *)kaddr;
+	de->name_len = 1;
+	de->rec_len = cpu_to_le16(EXOFS_DIR_REC_LEN(1));
+	memcpy(de->name, THIS_DIR, sizeof(THIS_DIR));
+	de->inode_no = cpu_to_le64(inode->i_ino);
+	exofs_set_de_type(de, inode);
+
+	de = (struct exofs_dir_entry *)(kaddr + EXOFS_DIR_REC_LEN(1));
+	de->name_len = 2;
+	de->rec_len = cpu_to_le16(chunk_size - EXOFS_DIR_REC_LEN(1));
+	de->inode_no = cpu_to_le64(parent->i_ino);
+	memcpy(de->name, PARENT_DIR, sizeof(PARENT_DIR));
+	exofs_set_de_type(de, inode);
+	kunmap_atomic(page, KM_USER0);
+	err = exofs_commit_chunk(page, 0, chunk_size);
+fail:
+	page_cache_release(page);
+	return err;
+}
+
+int exofs_empty_dir(struct inode *inode)
+{
+	struct page *page = NULL;
+	unsigned long i, npages = dir_pages(inode);
+
+	for (i = 0; i < npages; i++) {
+		char *kaddr;
+		struct exofs_dir_entry *de;
+		page = exofs_get_page(inode, i);
+
+		if (IS_ERR(page))
+			continue;
+
+		kaddr = page_address(page);
+		de = (struct exofs_dir_entry *)kaddr;
+		kaddr += exofs_last_byte(inode, i) - EXOFS_DIR_REC_LEN(1);
+
+		while ((char *)de <= kaddr) {
+			if (de->rec_len == 0) {
+				EXOFS_ERR("ERROR: exofs_empty_dir: "
+					  "zero-length directory entry"
+					  "kaddr=%p, de=%p\n", kaddr, de);
+				goto not_empty;
+			}
+			if (de->inode_no != 0) {
+				/* check for . and .. */
+				if (de->name[0] != '.')
+					goto not_empty;
+				if (de->name_len > 2)
+					goto not_empty;
+				if (de->name_len < 2) {
+					if (le64_to_cpu(de->inode_no) !=
+					    inode->i_ino)
+						goto not_empty;
+				} else if (de->name[1] != '.')
+					goto not_empty;
+			}
+			de = exofs_next_entry(de);
+		}
+		exofs_put_page(page);
+	}
+	return 1;
+
+not_empty:
+	exofs_put_page(page);
+	return 0;
+}
+
+const struct file_operations exofs_dir_operations = {
+	.llseek		= generic_file_llseek,
+	.read		= generic_read_dir,
+	.readdir	= exofs_readdir,
+};
diff --git a/fs/exofs/exofs.h b/fs/exofs/exofs.h
new file mode 100644
index 0000000..0fd4c785
--- /dev/null
+++ b/fs/exofs/exofs.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2005, 2006
+ * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com)
+ * Copyright (C) 2005, 2006
+ * International Business Machines
+ * Copyright (C) 2008, 2009
+ * Boaz Harrosh <bharrosh@panasas.com>
+ *
+ * Copyrights for code taken from ext2:
+ *     Copyright (C) 1992, 1993, 1994, 1995
+ *     Remy Card (card@masi.ibp.fr)
+ *     Laboratoire MASI - Institut Blaise Pascal
+ *     Universite Pierre et Marie Curie (Paris VI)
+ *     from
+ *     linux/fs/minix/inode.c
+ *     Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This file is part of exofs.
+ *
+ * exofs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.  Since it is based on ext2, and the only
+ * valid version of GPL for the Linux kernel is version 2, the only valid
+ * version of GPL for exofs is version 2.
+ *
+ * exofs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with exofs; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/fs.h>
+#include <linux/time.h>
+#include "common.h"
+
+#ifndef __EXOFS_H__
+#define __EXOFS_H__
+
+#define EXOFS_ERR(fmt, a...) printk(KERN_ERR "exofs: " fmt, ##a)
+
+#ifdef CONFIG_EXOFS_DEBUG
+#define EXOFS_DBGMSG(fmt, a...) \
+	printk(KERN_NOTICE "exofs @%s:%d: " fmt, __func__, __LINE__, ##a)
+#else
+#define EXOFS_DBGMSG(fmt, a...) \
+	do { if (0) printk(fmt, ##a); } while (0)
+#endif
+
+/* u64 has problems with printk this will cast it to unsigned long long */
+#define _LLU(x) (unsigned long long)(x)
+
+/*
+ * our extension to the in-memory superblock
+ */
+struct exofs_sb_info {
+	struct osd_dev	*s_dev;			/* returned by get_osd_dev    */
+	osd_id		s_pid;			/* partition ID of file system*/
+	int		s_timeout;		/* timeout for OSD operations */
+	uint64_t	s_nextid;		/* highest object ID used     */
+	uint32_t	s_numfiles;		/* number of files on fs      */
+	spinlock_t	s_next_gen_lock;	/* spinlock for gen # update  */
+	u32		s_next_generation;	/* next gen # to use          */
+	atomic_t	s_curr_pending;		/* number of pending commands */
+	uint8_t		s_cred[OSD_CAP_LEN];	/* all-powerful credential    */
+};
+
+/*
+ * our extension to the in-memory inode
+ */
+struct exofs_i_info {
+	unsigned long  i_flags;            /* various atomic flags            */
+	uint32_t       i_data[EXOFS_IDATA];/*short symlink names and device #s*/
+	uint32_t       i_dir_start_lookup; /* which page to start lookup      */
+	wait_queue_head_t i_wq;            /* wait queue for inode            */
+	uint64_t       i_commit_size;      /* the object's written length     */
+	uint8_t        i_cred[OSD_CAP_LEN];/* all-powerful credential         */
+	struct inode   vfs_inode;          /* normal in-memory inode          */
+};
+
+/*
+ * our inode flags
+ */
+#define OBJ_2BCREATED	0	/* object will be created soon*/
+#define OBJ_CREATED	1	/* object has been created on the osd*/
+
+static inline int obj_2bcreated(struct exofs_i_info *oi)
+{
+	return test_bit(OBJ_2BCREATED, &oi->i_flags);
+}
+
+static inline void set_obj_2bcreated(struct exofs_i_info *oi)
+{
+	set_bit(OBJ_2BCREATED, &oi->i_flags);
+}
+
+static inline int obj_created(struct exofs_i_info *oi)
+{
+	return test_bit(OBJ_CREATED, &oi->i_flags);
+}
+
+static inline void set_obj_created(struct exofs_i_info *oi)
+{
+	set_bit(OBJ_CREATED, &oi->i_flags);
+}
+
+int __exofs_wait_obj_created(struct exofs_i_info *oi);
+static inline int wait_obj_created(struct exofs_i_info *oi)
+{
+	if (likely(obj_created(oi)))
+		return 0;
+
+	return __exofs_wait_obj_created(oi);
+}
+
+/*
+ * get to our inode from the vfs inode
+ */
+static inline struct exofs_i_info *exofs_i(struct inode *inode)
+{
+	return container_of(inode, struct exofs_i_info, vfs_inode);
+}
+
+/*
+ * Maximum count of links to a file
+ */
+#define EXOFS_LINK_MAX           32000
+
+/*************************
+ * function declarations *
+ *************************/
+/* inode.c               */
+void exofs_truncate(struct inode *inode);
+int exofs_setattr(struct dentry *, struct iattr *);
+int exofs_write_begin(struct file *file, struct address_space *mapping,
+		loff_t pos, unsigned len, unsigned flags,
+		struct page **pagep, void **fsdata);
+extern struct inode *exofs_iget(struct super_block *, unsigned long);
+struct inode *exofs_new_inode(struct inode *, int);
+extern int exofs_write_inode(struct inode *, int);
+extern void exofs_delete_inode(struct inode *);
+
+/* dir.c:                */
+int exofs_add_link(struct dentry *, struct inode *);
+ino_t exofs_inode_by_name(struct inode *, struct dentry *);
+int exofs_delete_entry(struct exofs_dir_entry *, struct page *);
+int exofs_make_empty(struct inode *, struct inode *);
+struct exofs_dir_entry *exofs_find_entry(struct inode *, struct dentry *,
+					 struct page **);
+int exofs_empty_dir(struct inode *);
+struct exofs_dir_entry *exofs_dotdot(struct inode *, struct page **);
+ino_t exofs_parent_ino(struct dentry *child);
+int exofs_set_link(struct inode *, struct exofs_dir_entry *, struct page *,
+		    struct inode *);
+
+/*********************
+ * operation vectors *
+ *********************/
+/* dir.c:            */
+extern const struct file_operations exofs_dir_operations;
+
+/* file.c            */
+extern const struct inode_operations exofs_file_inode_operations;
+extern const struct file_operations exofs_file_operations;
+
+/* inode.c           */
+extern const struct address_space_operations exofs_aops;
+
+/* namei.c           */
+extern const struct inode_operations exofs_dir_inode_operations;
+extern const struct inode_operations exofs_special_inode_operations;
+
+/* symlink.c         */
+extern const struct inode_operations exofs_symlink_inode_operations;
+extern const struct inode_operations exofs_fast_symlink_inode_operations;
+
+#endif
diff --git a/fs/exofs/file.c b/fs/exofs/file.c
new file mode 100644
index 0000000..6ed7fe4
--- /dev/null
+++ b/fs/exofs/file.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2005, 2006
+ * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com)
+ * Copyright (C) 2005, 2006
+ * International Business Machines
+ * Copyright (C) 2008, 2009
+ * Boaz Harrosh <bharrosh@panasas.com>
+ *
+ * Copyrights for code taken from ext2:
+ *     Copyright (C) 1992, 1993, 1994, 1995
+ *     Remy Card (card@masi.ibp.fr)
+ *     Laboratoire MASI - Institut Blaise Pascal
+ *     Universite Pierre et Marie Curie (Paris VI)
+ *     from
+ *     linux/fs/minix/inode.c
+ *     Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This file is part of exofs.
+ *
+ * exofs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.  Since it is based on ext2, and the only
+ * valid version of GPL for the Linux kernel is version 2, the only valid
+ * version of GPL for exofs is version 2.
+ *
+ * exofs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with exofs; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/buffer_head.h>
+
+#include "exofs.h"
+
+static int exofs_release_file(struct inode *inode, struct file *filp)
+{
+	return 0;
+}
+
+static int exofs_file_fsync(struct file *filp, struct dentry *dentry,
+			    int datasync)
+{
+	int ret;
+	struct address_space *mapping = filp->f_mapping;
+
+	ret = filemap_write_and_wait(mapping);
+	if (ret)
+		return ret;
+
+	/*Note: file_fsync below also calles sync_blockdev, which is a no-op
+	 *      for exofs, but other then that it does sync_inode and
+	 *      sync_superblock which is what we need here.
+	 */
+	return file_fsync(filp, dentry, datasync);
+}
+
+static int exofs_flush(struct file *file, fl_owner_t id)
+{
+	exofs_file_fsync(file, file->f_path.dentry, 1);
+	/* TODO: Flush the OSD target */
+	return 0;
+}
+
+const struct file_operations exofs_file_operations = {
+	.llseek		= generic_file_llseek,
+	.read		= do_sync_read,
+	.write		= do_sync_write,
+	.aio_read	= generic_file_aio_read,
+	.aio_write	= generic_file_aio_write,
+	.mmap		= generic_file_mmap,
+	.open		= generic_file_open,
+	.release	= exofs_release_file,
+	.fsync		= exofs_file_fsync,
+	.flush		= exofs_flush,
+	.splice_read	= generic_file_splice_read,
+	.splice_write	= generic_file_splice_write,
+};
+
+const struct inode_operations exofs_file_inode_operations = {
+	.truncate	= exofs_truncate,
+	.setattr	= exofs_setattr,
+};
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c
new file mode 100644
index 0000000..ba8d9fa
--- /dev/null
+++ b/fs/exofs/inode.c
@@ -0,0 +1,1303 @@
+/*
+ * Copyright (C) 2005, 2006
+ * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com)
+ * Copyright (C) 2005, 2006
+ * International Business Machines
+ * Copyright (C) 2008, 2009
+ * Boaz Harrosh <bharrosh@panasas.com>
+ *
+ * Copyrights for code taken from ext2:
+ *     Copyright (C) 1992, 1993, 1994, 1995
+ *     Remy Card (card@masi.ibp.fr)
+ *     Laboratoire MASI - Institut Blaise Pascal
+ *     Universite Pierre et Marie Curie (Paris VI)
+ *     from
+ *     linux/fs/minix/inode.c
+ *     Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This file is part of exofs.
+ *
+ * exofs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.  Since it is based on ext2, and the only
+ * valid version of GPL for the Linux kernel is version 2, the only valid
+ * version of GPL for exofs is version 2.
+ *
+ * exofs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with exofs; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/writeback.h>
+#include <linux/buffer_head.h>
+#include <scsi/scsi_device.h>
+
+#include "exofs.h"
+
+#ifdef CONFIG_EXOFS_DEBUG
+#  define EXOFS_DEBUG_OBJ_ISIZE 1
+#endif
+
+struct page_collect {
+	struct exofs_sb_info *sbi;
+	struct request_queue *req_q;
+	struct inode *inode;
+	unsigned expected_pages;
+
+	struct bio *bio;
+	unsigned nr_pages;
+	unsigned long length;
+	loff_t pg_first; /* keep 64bit also in 32-arches */
+};
+
+static void _pcol_init(struct page_collect *pcol, unsigned expected_pages,
+		struct inode *inode)
+{
+	struct exofs_sb_info *sbi = inode->i_sb->s_fs_info;
+	struct request_queue *req_q = sbi->s_dev->scsi_device->request_queue;
+
+	pcol->sbi = sbi;
+	pcol->req_q = req_q;
+	pcol->inode = inode;
+	pcol->expected_pages = expected_pages;
+
+	pcol->bio = NULL;
+	pcol->nr_pages = 0;
+	pcol->length = 0;
+	pcol->pg_first = -1;
+
+	EXOFS_DBGMSG("_pcol_init ino=0x%lx expected_pages=%u\n", inode->i_ino,
+		     expected_pages);
+}
+
+static void _pcol_reset(struct page_collect *pcol)
+{
+	pcol->expected_pages -= min(pcol->nr_pages, pcol->expected_pages);
+
+	pcol->bio = NULL;
+	pcol->nr_pages = 0;
+	pcol->length = 0;
+	pcol->pg_first = -1;
+	EXOFS_DBGMSG("_pcol_reset ino=0x%lx expected_pages=%u\n",
+		     pcol->inode->i_ino, pcol->expected_pages);
+
+	/* this is probably the end of the loop but in writes
+	 * it might not end here. don't be left with nothing
+	 */
+	if (!pcol->expected_pages)
+		pcol->expected_pages = 128;
+}
+
+static int pcol_try_alloc(struct page_collect *pcol)
+{
+	int pages = min_t(unsigned, pcol->expected_pages, BIO_MAX_PAGES);
+
+	for (; pages; pages >>= 1) {
+		pcol->bio = bio_alloc(GFP_KERNEL, pages);
+		if (likely(pcol->bio))
+			return 0;
+	}
+
+	EXOFS_ERR("Failed to kcalloc expected_pages=%u\n",
+		  pcol->expected_pages);
+	return -ENOMEM;
+}
+
+static void pcol_free(struct page_collect *pcol)
+{
+	bio_put(pcol->bio);
+	pcol->bio = NULL;
+}
+
+static int pcol_add_page(struct page_collect *pcol, struct page *page,
+			 unsigned len)
+{
+	int added_len = bio_add_pc_page(pcol->req_q, pcol->bio, page, len, 0);
+	if (unlikely(len != added_len))
+		return -ENOMEM;
+
+	++pcol->nr_pages;
+	pcol->length += len;
+	return 0;
+}
+
+static int update_read_page(struct page *page, int ret)
+{
+	if (ret == 0) {
+		/* Everything is OK */
+		SetPageUptodate(page);
+		if (PageError(page))
+			ClearPageError(page);
+	} else if (ret == -EFAULT) {
+		/* In this case we were trying to read something that wasn't on
+		 * disk yet - return a page full of zeroes.  This should be OK,
+		 * because the object should be empty (if there was a write
+		 * before this read, the read would be waiting with the page
+		 * locked */
+		clear_highpage(page);
+
+		SetPageUptodate(page);
+		if (PageError(page))
+			ClearPageError(page);
+		ret = 0; /* recovered error */
+		EXOFS_DBGMSG("recovered read error\n");
+	} else /* Error */
+		SetPageError(page);
+
+	return ret;
+}
+
+static void update_write_page(struct page *page, int ret)
+{
+	if (ret) {
+		mapping_set_error(page->mapping, ret);
+		SetPageError(page);
+	}
+	end_page_writeback(page);
+}
+
+/* Called at the end of reads, to optionally unlock pages and update their
+ * status.
+ */
+static int __readpages_done(struct osd_request *or, struct page_collect *pcol,
+			    bool do_unlock)
+{
+	struct bio_vec *bvec;
+	int i;
+	u64 resid;
+	u64 good_bytes;
+	u64 length = 0;
+	int ret = exofs_check_ok_resid(or, &resid, NULL);
+
+	osd_end_request(or);
+
+	if (likely(!ret))
+		good_bytes = pcol->length;
+	else if (!resid)
+		good_bytes = 0;
+	else
+		good_bytes = pcol->length - resid;
+
+	EXOFS_DBGMSG("readpages_done(0x%lx) good_bytes=0x%llx"
+		     " length=0x%lx nr_pages=%u\n",
+		     pcol->inode->i_ino, _LLU(good_bytes), pcol->length,
+		     pcol->nr_pages);
+
+	__bio_for_each_segment(bvec, pcol->bio, i, 0) {
+		struct page *page = bvec->bv_page;
+		struct inode *inode = page->mapping->host;
+		int page_stat;
+
+		if (inode != pcol->inode)
+			continue; /* osd might add more pages at end */
+
+		if (likely(length < good_bytes))
+			page_stat = 0;
+		else
+			page_stat = ret;
+
+		EXOFS_DBGMSG("    readpages_done(0x%lx, 0x%lx) %s\n",
+			  inode->i_ino, page->index,
+			  page_stat ? "bad_bytes" : "good_bytes");
+
+		ret = update_read_page(page, page_stat);
+		if (do_unlock)
+			unlock_page(page);
+		length += bvec->bv_len;
+	}
+
+	pcol_free(pcol);
+	EXOFS_DBGMSG("readpages_done END\n");
+	return ret;
+}
+
+/* callback of async reads */
+static void readpages_done(struct osd_request *or, void *p)
+{
+	struct page_collect *pcol = p;
+
+	__readpages_done(or, pcol, true);
+	atomic_dec(&pcol->sbi->s_curr_pending);
+	kfree(p);
+}
+
+static void _unlock_pcol_pages(struct page_collect *pcol, int ret, int rw)
+{
+	struct bio_vec *bvec;
+	int i;
+
+	__bio_for_each_segment(bvec, pcol->bio, i, 0) {
+		struct page *page = bvec->bv_page;
+
+		if (rw == READ)
+			update_read_page(page, ret);
+		else
+			update_write_page(page, ret);
+
+		unlock_page(page);
+	}
+	pcol_free(pcol);
+}
+
+static int read_exec(struct page_collect *pcol, bool is_sync)
+{
+	struct exofs_i_info *oi = exofs_i(pcol->inode);
+	struct osd_obj_id obj = {pcol->sbi->s_pid,
+					pcol->inode->i_ino + EXOFS_OBJ_OFF};
+	struct osd_request *or = NULL;
+	struct page_collect *pcol_copy = NULL;
+	loff_t i_start = pcol->pg_first << PAGE_CACHE_SHIFT;
+	int ret;
+
+	if (!pcol->bio)
+		return 0;
+
+	/* see comment in _readpage() about sync reads */
+	WARN_ON(is_sync && (pcol->nr_pages != 1));
+
+	or = osd_start_request(pcol->sbi->s_dev, GFP_KERNEL);
+	if (unlikely(!or)) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	osd_req_read(or, &obj, pcol->bio, i_start);
+
+	if (is_sync) {
+		exofs_sync_op(or, pcol->sbi->s_timeout, oi->i_cred);
+		return __readpages_done(or, pcol, false);
+	}
+
+	pcol_copy = kmalloc(sizeof(*pcol_copy), GFP_KERNEL);
+	if (!pcol_copy) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	*pcol_copy = *pcol;
+	ret = exofs_async_op(or, readpages_done, pcol_copy, oi->i_cred);
+	if (unlikely(ret))
+		goto err;
+
+	atomic_inc(&pcol->sbi->s_curr_pending);
+
+	EXOFS_DBGMSG("read_exec obj=0x%llx start=0x%llx length=0x%lx\n",
+		  obj.id, _LLU(i_start), pcol->length);
+
+	/* pages ownership was passed to pcol_copy */
+	_pcol_reset(pcol);
+	return 0;
+
+err:
+	if (!is_sync)
+		_unlock_pcol_pages(pcol, ret, READ);
+	kfree(pcol_copy);
+	if (or)
+		osd_end_request(or);
+	return ret;
+}
+
+/* readpage_strip is called either directly from readpage() or by the VFS from
+ * within read_cache_pages(), to add one more page to be read. It will try to
+ * collect as many contiguous pages as posible. If a discontinuity is
+ * encountered, or it runs out of resources, it will submit the previous segment
+ * and will start a new collection. Eventually caller must submit the last
+ * segment if present.
+ */
+static int readpage_strip(void *data, struct page *page)
+{
+	struct page_collect *pcol = data;
+	struct inode *inode = pcol->inode;
+	struct exofs_i_info *oi = exofs_i(inode);
+	loff_t i_size = i_size_read(inode);
+	pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT;
+	size_t len;
+	int ret;
+
+	/* FIXME: Just for debugging, will be removed */
+	if (PageUptodate(page))
+		EXOFS_ERR("PageUptodate(0x%lx, 0x%lx)\n", pcol->inode->i_ino,
+			  page->index);
+
+	if (page->index < end_index)
+		len = PAGE_CACHE_SIZE;
+	else if (page->index == end_index)
+		len = i_size & ~PAGE_CACHE_MASK;
+	else
+		len = 0;
+
+	if (!len || !obj_created(oi)) {
+		/* this will be out of bounds, or doesn't exist yet.
+		 * Current page is cleared and the request is split
+		 */
+		clear_highpage(page);
+
+		SetPageUptodate(page);
+		if (PageError(page))
+			ClearPageError(page);
+
+		unlock_page(page);
+		EXOFS_DBGMSG("readpage_strip(0x%lx, 0x%lx) empty page,"
+			     " splitting\n", inode->i_ino, page->index);
+
+		return read_exec(pcol, false);
+	}
+
+try_again:
+
+	if (unlikely(pcol->pg_first == -1)) {
+		pcol->pg_first = page->index;
+	} else if (unlikely((pcol->pg_first + pcol->nr_pages) !=
+		   page->index)) {
+		/* Discontinuity detected, split the request */
+		ret = read_exec(pcol, false);
+		if (unlikely(ret))
+			goto fail;
+		goto try_again;
+	}
+
+	if (!pcol->bio) {
+		ret = pcol_try_alloc(pcol);
+		if (unlikely(ret))
+			goto fail;
+	}
+
+	if (len != PAGE_CACHE_SIZE)
+		zero_user(page, len, PAGE_CACHE_SIZE - len);
+
+	EXOFS_DBGMSG("    readpage_strip(0x%lx, 0x%lx) len=0x%zx\n",
+		     inode->i_ino, page->index, len);
+
+	ret = pcol_add_page(pcol, page, len);
+	if (ret) {
+		EXOFS_DBGMSG("Failed pcol_add_page pages[i]=%p "
+			  "this_len=0x%zx nr_pages=%u length=0x%lx\n",
+			  page, len, pcol->nr_pages, pcol->length);
+
+		/* split the request, and start again with current page */
+		ret = read_exec(pcol, false);
+		if (unlikely(ret))
+			goto fail;
+
+		goto try_again;
+	}
+
+	return 0;
+
+fail:
+	/* SetPageError(page); ??? */
+	unlock_page(page);
+	return ret;
+}
+
+static int exofs_readpages(struct file *file, struct address_space *mapping,
+			   struct list_head *pages, unsigned nr_pages)
+{
+	struct page_collect pcol;
+	int ret;
+
+	_pcol_init(&pcol, nr_pages, mapping->host);
+
+	ret = read_cache_pages(mapping, pages, readpage_strip, &pcol);
+	if (ret) {
+		EXOFS_ERR("read_cache_pages => %d\n", ret);
+		return ret;
+	}
+
+	return read_exec(&pcol, false);
+}
+
+static int _readpage(struct page *page, bool is_sync)
+{
+	struct page_collect pcol;
+	int ret;
+
+	_pcol_init(&pcol, 1, page->mapping->host);
+
+	/* readpage_strip might call read_exec(,async) inside at several places
+	 * but this is safe for is_async=0 since read_exec will not do anything
+	 * when we have a single page.
+	 */
+	ret = readpage_strip(&pcol, page);
+	if (ret) {
+		EXOFS_ERR("_readpage => %d\n", ret);
+		return ret;
+	}
+
+	return read_exec(&pcol, is_sync);
+}
+
+/*
+ * We don't need the file
+ */
+static int exofs_readpage(struct file *file, struct page *page)
+{
+	return _readpage(page, false);
+}
+
+/* Callback for osd_write. All writes are asynchronouse */
+static void writepages_done(struct osd_request *or, void *p)
+{
+	struct page_collect *pcol = p;
+	struct bio_vec *bvec;
+	int i;
+	u64 resid;
+	u64  good_bytes;
+	u64  length = 0;
+
+	int ret = exofs_check_ok_resid(or, NULL, &resid);
+
+	osd_end_request(or);
+	atomic_dec(&pcol->sbi->s_curr_pending);
+
+	if (likely(!ret))
+		good_bytes = pcol->length;
+	else if (!resid)
+		good_bytes = 0;
+	else
+		good_bytes = pcol->length - resid;
+
+	EXOFS_DBGMSG("writepages_done(0x%lx) good_bytes=0x%llx"
+		     " length=0x%lx nr_pages=%u\n",
+		     pcol->inode->i_ino, _LLU(good_bytes), pcol->length,
+		     pcol->nr_pages);
+
+	__bio_for_each_segment(bvec, pcol->bio, i, 0) {
+		struct page *page = bvec->bv_page;
+		struct inode *inode = page->mapping->host;
+		int page_stat;
+
+		if (inode != pcol->inode)
+			continue; /* osd might add more pages to a bio */
+
+		if (likely(length < good_bytes))
+			page_stat = 0;
+		else
+			page_stat = ret;
+
+		update_write_page(page, page_stat);
+		unlock_page(page);
+		EXOFS_DBGMSG("    writepages_done(0x%lx, 0x%lx) status=%d\n",
+			     inode->i_ino, page->index, page_stat);
+
+		length += bvec->bv_len;
+	}
+
+	pcol_free(pcol);
+	kfree(pcol);
+	EXOFS_DBGMSG("writepages_done END\n");
+}
+
+static int write_exec(struct page_collect *pcol)
+{
+	struct exofs_i_info *oi = exofs_i(pcol->inode);
+	struct osd_obj_id obj = {pcol->sbi->s_pid,
+					pcol->inode->i_ino + EXOFS_OBJ_OFF};
+	struct osd_request *or = NULL;
+	struct page_collect *pcol_copy = NULL;
+	loff_t i_start = pcol->pg_first << PAGE_CACHE_SHIFT;
+	int ret;
+
+	if (!pcol->bio)
+		return 0;
+
+	or = osd_start_request(pcol->sbi->s_dev, GFP_KERNEL);
+	if (unlikely(!or)) {
+		EXOFS_ERR("write_exec: Faild to osd_start_request()\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	pcol_copy = kmalloc(sizeof(*pcol_copy), GFP_KERNEL);
+	if (!pcol_copy) {
+		EXOFS_ERR("write_exec: Faild to kmalloc(pcol)\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	*pcol_copy = *pcol;
+
+	osd_req_write(or, &obj, pcol_copy->bio, i_start);
+	ret = exofs_async_op(or, writepages_done, pcol_copy, oi->i_cred);
+	if (unlikely(ret)) {
+		EXOFS_ERR("write_exec: exofs_async_op() Faild\n");
+		goto err;
+	}
+
+	atomic_inc(&pcol->sbi->s_curr_pending);
+	EXOFS_DBGMSG("write_exec(0x%lx, 0x%llx) start=0x%llx length=0x%lx\n",
+		  pcol->inode->i_ino, pcol->pg_first, _LLU(i_start),
+		  pcol->length);
+	/* pages ownership was passed to pcol_copy */
+	_pcol_reset(pcol);
+	return 0;
+
+err:
+	_unlock_pcol_pages(pcol, ret, WRITE);
+	kfree(pcol_copy);
+	if (or)
+		osd_end_request(or);
+	return ret;
+}
+
+/* writepage_strip is called either directly from writepage() or by the VFS from
+ * within write_cache_pages(), to add one more page to be written to storage.
+ * It will try to collect as many contiguous pages as possible. If a
+ * discontinuity is encountered or it runs out of resources it will submit the
+ * previous segment and will start a new collection.
+ * Eventually caller must submit the last segment if present.
+ */
+static int writepage_strip(struct page *page,
+			   struct writeback_control *wbc_unused, void *data)
+{
+	struct page_collect *pcol = data;
+	struct inode *inode = pcol->inode;
+	struct exofs_i_info *oi = exofs_i(inode);
+	loff_t i_size = i_size_read(inode);
+	pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT;
+	size_t len;
+	int ret;
+
+	BUG_ON(!PageLocked(page));
+
+	ret = wait_obj_created(oi);
+	if (unlikely(ret))
+		goto fail;
+
+	if (page->index < end_index)
+		/* in this case, the page is within the limits of the file */
+		len = PAGE_CACHE_SIZE;
+	else {
+		len = i_size & ~PAGE_CACHE_MASK;
+
+		if (page->index > end_index || !len) {
+			/* in this case, the page is outside the limits
+			 * (truncate in progress)
+			 */
+			ret = write_exec(pcol);
+			if (unlikely(ret))
+				goto fail;
+			if (PageError(page))
+				ClearPageError(page);
+			unlock_page(page);
+			return 0;
+		}
+	}
+
+try_again:
+
+	if (unlikely(pcol->pg_first == -1)) {
+		pcol->pg_first = page->index;
+	} else if (unlikely((pcol->pg_first + pcol->nr_pages) !=
+		   page->index)) {
+		/* Discontinuity detected, split the request */
+		ret = write_exec(pcol);
+		if (unlikely(ret))
+			goto fail;
+		goto try_again;
+	}
+
+	if (!pcol->bio) {
+		ret = pcol_try_alloc(pcol);
+		if (unlikely(ret))
+			goto fail;
+	}
+
+	EXOFS_DBGMSG("    writepage_strip(0x%lx, 0x%lx) len=0x%zx\n",
+		     inode->i_ino, page->index, len);
+
+	ret = pcol_add_page(pcol, page, len);
+	if (unlikely(ret)) {
+		EXOFS_DBGMSG("Failed pcol_add_page "
+			     "nr_pages=%u total_length=0x%lx\n",
+			     pcol->nr_pages, pcol->length);
+
+		/* split the request, next loop will start again */
+		ret = write_exec(pcol);
+		if (unlikely(ret)) {
+			EXOFS_DBGMSG("write_exec faild => %d", ret);
+			goto fail;
+		}
+
+		goto try_again;
+	}
+
+	BUG_ON(PageWriteback(page));
+	set_page_writeback(page);
+
+	return 0;
+
+fail:
+	set_bit(AS_EIO, &page->mapping->flags);
+	unlock_page(page);
+	return ret;
+}
+
+static int exofs_writepages(struct address_space *mapping,
+		       struct writeback_control *wbc)
+{
+	struct page_collect pcol;
+	long start, end, expected_pages;
+	int ret;
+
+	start = wbc->range_start >> PAGE_CACHE_SHIFT;
+	end = (wbc->range_end == LLONG_MAX) ?
+			start + mapping->nrpages :
+			wbc->range_end >> PAGE_CACHE_SHIFT;
+
+	if (start || end)
+		expected_pages = min(end - start + 1, 32L);
+	else
+		expected_pages = mapping->nrpages;
+
+	EXOFS_DBGMSG("inode(0x%lx) wbc->start=0x%llx wbc->end=0x%llx"
+		     " m->nrpages=%lu start=0x%lx end=0x%lx\n",
+		     mapping->host->i_ino, wbc->range_start, wbc->range_end,
+		     mapping->nrpages, start, end);
+
+	_pcol_init(&pcol, expected_pages, mapping->host);
+
+	ret = write_cache_pages(mapping, wbc, writepage_strip, &pcol);
+	if (ret) {
+		EXOFS_ERR("write_cache_pages => %d\n", ret);
+		return ret;
+	}
+
+	return write_exec(&pcol);
+}
+
+static int exofs_writepage(struct page *page, struct writeback_control *wbc)
+{
+	struct page_collect pcol;
+	int ret;
+
+	_pcol_init(&pcol, 1, page->mapping->host);
+
+	ret = writepage_strip(page, NULL, &pcol);
+	if (ret) {
+		EXOFS_ERR("exofs_writepage => %d\n", ret);
+		return ret;
+	}
+
+	return write_exec(&pcol);
+}
+
+int exofs_write_begin(struct file *file, struct address_space *mapping,
+		loff_t pos, unsigned len, unsigned flags,
+		struct page **pagep, void **fsdata)
+{
+	int ret = 0;
+	struct page *page;
+
+	page = *pagep;
+	if (page == NULL) {
+		ret = simple_write_begin(file, mapping, pos, len, flags, pagep,
+					 fsdata);
+		if (ret) {
+			EXOFS_DBGMSG("simple_write_begin faild\n");
+			return ret;
+		}
+
+		page = *pagep;
+	}
+
+	 /* read modify write */
+	if (!PageUptodate(page) && (len != PAGE_CACHE_SIZE)) {
+		ret = _readpage(page, true);
+		if (ret) {
+			/*SetPageError was done by _readpage. Is it ok?*/
+			unlock_page(page);
+			EXOFS_DBGMSG("__readpage_filler faild\n");
+		}
+	}
+
+	return ret;
+}
+
+static int exofs_write_begin_export(struct file *file,
+		struct address_space *mapping,
+		loff_t pos, unsigned len, unsigned flags,
+		struct page **pagep, void **fsdata)
+{
+	*pagep = NULL;
+
+	return exofs_write_begin(file, mapping, pos, len, flags, pagep,
+					fsdata);
+}
+
+const struct address_space_operations exofs_aops = {
+	.readpage	= exofs_readpage,
+	.readpages	= exofs_readpages,
+	.writepage	= exofs_writepage,
+	.writepages	= exofs_writepages,
+	.write_begin	= exofs_write_begin_export,
+	.write_end	= simple_write_end,
+};
+
+/******************************************************************************
+ * INODE OPERATIONS
+ *****************************************************************************/
+
+/*
+ * Test whether an inode is a fast symlink.
+ */
+static inline int exofs_inode_is_fast_symlink(struct inode *inode)
+{
+	struct exofs_i_info *oi = exofs_i(inode);
+
+	return S_ISLNK(inode->i_mode) && (oi->i_data[0] != 0);
+}
+
+/*
+ * get_block_t - Fill in a buffer_head
+ * An OSD takes care of block allocation so we just fake an allocation by
+ * putting in the inode's sector_t in the buffer_head.
+ * TODO: What about the case of create==0 and @iblock does not exist in the
+ * object?
+ */
+static int exofs_get_block(struct inode *inode, sector_t iblock,
+		    struct buffer_head *bh_result, int create)
+{
+	map_bh(bh_result, inode->i_sb, iblock);
+	return 0;
+}
+
+const struct osd_attr g_attr_logical_length = ATTR_DEF(
+	OSD_APAGE_OBJECT_INFORMATION, OSD_ATTR_OI_LOGICAL_LENGTH, 8);
+
+/*
+ * Truncate a file to the specified size - all we have to do is set the size
+ * attribute.  We make sure the object exists first.
+ */
+void exofs_truncate(struct inode *inode)
+{
+	struct exofs_sb_info *sbi = inode->i_sb->s_fs_info;
+	struct exofs_i_info *oi = exofs_i(inode);
+	struct osd_obj_id obj = {sbi->s_pid, inode->i_ino + EXOFS_OBJ_OFF};
+	struct osd_request *or;
+	struct osd_attr attr;
+	loff_t isize = i_size_read(inode);
+	__be64 newsize;
+	int ret;
+
+	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)
+	     || S_ISLNK(inode->i_mode)))
+		return;
+	if (exofs_inode_is_fast_symlink(inode))
+		return;
+	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+		return;
+	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+
+	nobh_truncate_page(inode->i_mapping, isize, exofs_get_block);
+
+	or = osd_start_request(sbi->s_dev, GFP_KERNEL);
+	if (unlikely(!or)) {
+		EXOFS_ERR("ERROR: exofs_truncate: osd_start_request failed\n");
+		goto fail;
+	}
+
+	osd_req_set_attributes(or, &obj);
+
+	newsize = cpu_to_be64((u64)isize);
+	attr = g_attr_logical_length;
+	attr.val_ptr = &newsize;
+	osd_req_add_set_attr_list(or, &attr, 1);
+
+	/* if we are about to truncate an object, and it hasn't been
+	 * created yet, wait
+	 */
+	if (unlikely(wait_obj_created(oi)))
+		goto fail;
+
+	ret = exofs_sync_op(or, sbi->s_timeout, oi->i_cred);
+	osd_end_request(or);
+	if (ret)
+		goto fail;
+
+out:
+	mark_inode_dirty(inode);
+	return;
+fail:
+	make_bad_inode(inode);
+	goto out;
+}
+
+/*
+ * Set inode attributes - just call generic functions.
+ */
+int exofs_setattr(struct dentry *dentry, struct iattr *iattr)
+{
+	struct inode *inode = dentry->d_inode;
+	int error;
+
+	error = inode_change_ok(inode, iattr);
+	if (error)
+		return error;
+
+	error = inode_setattr(inode, iattr);
+	return error;
+}
+
+/*
+ * Read an inode from the OSD, and return it as is.  We also return the size
+ * attribute in the 'sanity' argument if we got compiled with debugging turned
+ * on.
+ */
+static int exofs_get_inode(struct super_block *sb, struct exofs_i_info *oi,
+		    struct exofs_fcb *inode, uint64_t *sanity)
+{
+	struct exofs_sb_info *sbi = sb->s_fs_info;
+	struct osd_request *or;
+	struct osd_attr attr;
+	struct osd_obj_id obj = {sbi->s_pid,
+				 oi->vfs_inode.i_ino + EXOFS_OBJ_OFF};
+	int ret;
+
+	exofs_make_credential(oi->i_cred, &obj);
+
+	or = osd_start_request(sbi->s_dev, GFP_KERNEL);
+	if (unlikely(!or)) {
+		EXOFS_ERR("exofs_get_inode: osd_start_request failed.\n");
+		return -ENOMEM;
+	}
+	osd_req_get_attributes(or, &obj);
+
+	/* we need the inode attribute */
+	osd_req_add_get_attr_list(or, &g_attr_inode_data, 1);
+
+#ifdef EXOFS_DEBUG_OBJ_ISIZE
+	/* we get the size attributes to do a sanity check */
+	osd_req_add_get_attr_list(or, &g_attr_logical_length, 1);
+#endif
+
+	ret = exofs_sync_op(or, sbi->s_timeout, oi->i_cred);
+	if (ret)
+		goto out;
+
+	attr = g_attr_inode_data;
+	ret = extract_attr_from_req(or, &attr);
+	if (ret) {
+		EXOFS_ERR("exofs_get_inode: extract_attr_from_req failed\n");
+		goto out;
+	}
+
+	WARN_ON(attr.len != EXOFS_INO_ATTR_SIZE);
+	memcpy(inode, attr.val_ptr, EXOFS_INO_ATTR_SIZE);
+
+#ifdef EXOFS_DEBUG_OBJ_ISIZE
+	attr = g_attr_logical_length;
+	ret = extract_attr_from_req(or, &attr);
+	if (ret) {
+		EXOFS_ERR("ERROR: extract attr from or failed\n");
+		goto out;
+	}
+	*sanity = get_unaligned_be64(attr.val_ptr);
+#endif
+
+out:
+	osd_end_request(or);
+	return ret;
+}
+
+/*
+ * Fill in an inode read from the OSD and set it up for use
+ */
+struct inode *exofs_iget(struct super_block *sb, unsigned long ino)
+{
+	struct exofs_i_info *oi;
+	struct exofs_fcb fcb;
+	struct inode *inode;
+	uint64_t uninitialized_var(sanity);
+	int ret;
+
+	inode = iget_locked(sb, ino);
+	if (!inode)
+		return ERR_PTR(-ENOMEM);
+	if (!(inode->i_state & I_NEW))
+		return inode;
+	oi = exofs_i(inode);
+
+	/* read the inode from the osd */
+	ret = exofs_get_inode(sb, oi, &fcb, &sanity);
+	if (ret)
+		goto bad_inode;
+
+	init_waitqueue_head(&oi->i_wq);
+	set_obj_created(oi);
+
+	/* copy stuff from on-disk struct to in-memory struct */
+	inode->i_mode = le16_to_cpu(fcb.i_mode);
+	inode->i_uid = le32_to_cpu(fcb.i_uid);
+	inode->i_gid = le32_to_cpu(fcb.i_gid);
+	inode->i_nlink = le16_to_cpu(fcb.i_links_count);
+	inode->i_ctime.tv_sec = (signed)le32_to_cpu(fcb.i_ctime);
+	inode->i_atime.tv_sec = (signed)le32_to_cpu(fcb.i_atime);
+	inode->i_mtime.tv_sec = (signed)le32_to_cpu(fcb.i_mtime);
+	inode->i_ctime.tv_nsec =
+		inode->i_atime.tv_nsec = inode->i_mtime.tv_nsec = 0;
+	oi->i_commit_size = le64_to_cpu(fcb.i_size);
+	i_size_write(inode, oi->i_commit_size);
+	inode->i_blkbits = EXOFS_BLKSHIFT;
+	inode->i_generation = le32_to_cpu(fcb.i_generation);
+
+#ifdef EXOFS_DEBUG_OBJ_ISIZE
+	if ((inode->i_size != sanity) &&
+		(!exofs_inode_is_fast_symlink(inode))) {
+		EXOFS_ERR("WARNING: Size of object from inode and "
+			  "attributes differ (%lld != %llu)\n",
+			  inode->i_size, _LLU(sanity));
+	}
+#endif
+
+	oi->i_dir_start_lookup = 0;
+
+	if ((inode->i_nlink == 0) && (inode->i_mode == 0)) {
+		ret = -ESTALE;
+		goto bad_inode;
+	}
+
+	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
+		if (fcb.i_data[0])
+			inode->i_rdev =
+				old_decode_dev(le32_to_cpu(fcb.i_data[0]));
+		else
+			inode->i_rdev =
+				new_decode_dev(le32_to_cpu(fcb.i_data[1]));
+	} else {
+		memcpy(oi->i_data, fcb.i_data, sizeof(fcb.i_data));
+	}
+
+	if (S_ISREG(inode->i_mode)) {
+		inode->i_op = &exofs_file_inode_operations;
+		inode->i_fop = &exofs_file_operations;
+		inode->i_mapping->a_ops = &exofs_aops;
+	} else if (S_ISDIR(inode->i_mode)) {
+		inode->i_op = &exofs_dir_inode_operations;
+		inode->i_fop = &exofs_dir_operations;
+		inode->i_mapping->a_ops = &exofs_aops;
+	} else if (S_ISLNK(inode->i_mode)) {
+		if (exofs_inode_is_fast_symlink(inode))
+			inode->i_op = &exofs_fast_symlink_inode_operations;
+		else {
+			inode->i_op = &exofs_symlink_inode_operations;
+			inode->i_mapping->a_ops = &exofs_aops;
+		}
+	} else {
+		inode->i_op = &exofs_special_inode_operations;
+		if (fcb.i_data[0])
+			init_special_inode(inode, inode->i_mode,
+			   old_decode_dev(le32_to_cpu(fcb.i_data[0])));
+		else
+			init_special_inode(inode, inode->i_mode,
+			   new_decode_dev(le32_to_cpu(fcb.i_data[1])));
+	}
+
+	unlock_new_inode(inode);
+	return inode;
+
+bad_inode:
+	iget_failed(inode);
+	return ERR_PTR(ret);
+}
+
+int __exofs_wait_obj_created(struct exofs_i_info *oi)
+{
+	if (!obj_created(oi)) {
+		BUG_ON(!obj_2bcreated(oi));
+		wait_event(oi->i_wq, obj_created(oi));
+	}
+	return unlikely(is_bad_inode(&oi->vfs_inode)) ? -EIO : 0;
+}
+/*
+ * Callback function from exofs_new_inode().  The important thing is that we
+ * set the obj_created flag so that other methods know that the object exists on
+ * the OSD.
+ */
+static void create_done(struct osd_request *or, void *p)
+{
+	struct inode *inode = p;
+	struct exofs_i_info *oi = exofs_i(inode);
+	struct exofs_sb_info *sbi = inode->i_sb->s_fs_info;
+	int ret;
+
+	ret = exofs_check_ok(or);
+	osd_end_request(or);
+	atomic_dec(&sbi->s_curr_pending);
+
+	if (unlikely(ret)) {
+		EXOFS_ERR("object=0x%llx creation faild in pid=0x%llx",
+			  _LLU(sbi->s_pid), _LLU(inode->i_ino + EXOFS_OBJ_OFF));
+		make_bad_inode(inode);
+	} else
+		set_obj_created(oi);
+
+	atomic_dec(&inode->i_count);
+	wake_up(&oi->i_wq);
+}
+
+/*
+ * Set up a new inode and create an object for it on the OSD
+ */
+struct inode *exofs_new_inode(struct inode *dir, int mode)
+{
+	struct super_block *sb;
+	struct inode *inode;
+	struct exofs_i_info *oi;
+	struct exofs_sb_info *sbi;
+	struct osd_request *or;
+	struct osd_obj_id obj;
+	int ret;
+
+	sb = dir->i_sb;
+	inode = new_inode(sb);
+	if (!inode)
+		return ERR_PTR(-ENOMEM);
+
+	oi = exofs_i(inode);
+
+	init_waitqueue_head(&oi->i_wq);
+	set_obj_2bcreated(oi);
+
+	sbi = sb->s_fs_info;
+
+	sb->s_dirt = 1;
+	inode->i_uid = current->cred->fsuid;
+	if (dir->i_mode & S_ISGID) {
+		inode->i_gid = dir->i_gid;
+		if (S_ISDIR(mode))
+			mode |= S_ISGID;
+	} else {
+		inode->i_gid = current->cred->fsgid;
+	}
+	inode->i_mode = mode;
+
+	inode->i_ino = sbi->s_nextid++;
+	inode->i_blkbits = EXOFS_BLKSHIFT;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	oi->i_commit_size = inode->i_size = 0;
+	spin_lock(&sbi->s_next_gen_lock);
+	inode->i_generation = sbi->s_next_generation++;
+	spin_unlock(&sbi->s_next_gen_lock);
+	insert_inode_hash(inode);
+
+	mark_inode_dirty(inode);
+
+	obj.partition = sbi->s_pid;
+	obj.id = inode->i_ino + EXOFS_OBJ_OFF;
+	exofs_make_credential(oi->i_cred, &obj);
+
+	or = osd_start_request(sbi->s_dev, GFP_KERNEL);
+	if (unlikely(!or)) {
+		EXOFS_ERR("exofs_new_inode: osd_start_request failed\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	osd_req_create_object(or, &obj);
+
+	/* increment the refcount so that the inode will still be around when we
+	 * reach the callback
+	 */
+	atomic_inc(&inode->i_count);
+
+	ret = exofs_async_op(or, create_done, inode, oi->i_cred);
+	if (ret) {
+		atomic_dec(&inode->i_count);
+		osd_end_request(or);
+		return ERR_PTR(-EIO);
+	}
+	atomic_inc(&sbi->s_curr_pending);
+
+	return inode;
+}
+
+/*
+ * struct to pass two arguments to update_inode's callback
+ */
+struct updatei_args {
+	struct exofs_sb_info	*sbi;
+	struct exofs_fcb	fcb;
+};
+
+/*
+ * Callback function from exofs_update_inode().
+ */
+static void updatei_done(struct osd_request *or, void *p)
+{
+	struct updatei_args *args = p;
+
+	osd_end_request(or);
+
+	atomic_dec(&args->sbi->s_curr_pending);
+
+	kfree(args);
+}
+
+/*
+ * Write the inode to the OSD.  Just fill up the struct, and set the attribute
+ * synchronously or asynchronously depending on the do_sync flag.
+ */
+static int exofs_update_inode(struct inode *inode, int do_sync)
+{
+	struct exofs_i_info *oi = exofs_i(inode);
+	struct super_block *sb = inode->i_sb;
+	struct exofs_sb_info *sbi = sb->s_fs_info;
+	struct osd_obj_id obj = {sbi->s_pid, inode->i_ino + EXOFS_OBJ_OFF};
+	struct osd_request *or;
+	struct osd_attr attr;
+	struct exofs_fcb *fcb;
+	struct updatei_args *args;
+	int ret;
+
+	args = kzalloc(sizeof(*args), GFP_KERNEL);
+	if (!args)
+		return -ENOMEM;
+
+	fcb = &args->fcb;
+
+	fcb->i_mode = cpu_to_le16(inode->i_mode);
+	fcb->i_uid = cpu_to_le32(inode->i_uid);
+	fcb->i_gid = cpu_to_le32(inode->i_gid);
+	fcb->i_links_count = cpu_to_le16(inode->i_nlink);
+	fcb->i_ctime = cpu_to_le32(inode->i_ctime.tv_sec);
+	fcb->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
+	fcb->i_mtime = cpu_to_le32(inode->i_mtime.tv_sec);
+	oi->i_commit_size = i_size_read(inode);
+	fcb->i_size = cpu_to_le64(oi->i_commit_size);
+	fcb->i_generation = cpu_to_le32(inode->i_generation);
+
+	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
+		if (old_valid_dev(inode->i_rdev)) {
+			fcb->i_data[0] =
+				cpu_to_le32(old_encode_dev(inode->i_rdev));
+			fcb->i_data[1] = 0;
+		} else {
+			fcb->i_data[0] = 0;
+			fcb->i_data[1] =
+				cpu_to_le32(new_encode_dev(inode->i_rdev));
+			fcb->i_data[2] = 0;
+		}
+	} else
+		memcpy(fcb->i_data, oi->i_data, sizeof(fcb->i_data));
+
+	or = osd_start_request(sbi->s_dev, GFP_KERNEL);
+	if (unlikely(!or)) {
+		EXOFS_ERR("exofs_update_inode: osd_start_request failed.\n");
+		ret = -ENOMEM;
+		goto free_args;
+	}
+
+	osd_req_set_attributes(or, &obj);
+
+	attr = g_attr_inode_data;
+	attr.val_ptr = fcb;
+	osd_req_add_set_attr_list(or, &attr, 1);
+
+	if (!obj_created(oi)) {
+		EXOFS_DBGMSG("!obj_created\n");
+		BUG_ON(!obj_2bcreated(oi));
+		wait_event(oi->i_wq, obj_created(oi));
+		EXOFS_DBGMSG("wait_event done\n");
+	}
+
+	if (do_sync) {
+		ret = exofs_sync_op(or, sbi->s_timeout, oi->i_cred);
+		osd_end_request(or);
+		goto free_args;
+	} else {
+		args->sbi = sbi;
+
+		ret = exofs_async_op(or, updatei_done, args, oi->i_cred);
+		if (ret) {
+			osd_end_request(or);
+			goto free_args;
+		}
+		atomic_inc(&sbi->s_curr_pending);
+		goto out; /* deallocation in updatei_done */
+	}
+
+free_args:
+	kfree(args);
+out:
+	EXOFS_DBGMSG("ret=>%d\n", ret);
+	return ret;
+}
+
+int exofs_write_inode(struct inode *inode, int wait)
+{
+	return exofs_update_inode(inode, wait);
+}
+
+/*
+ * Callback function from exofs_delete_inode() - don't have much cleaning up to
+ * do.
+ */
+static void delete_done(struct osd_request *or, void *p)
+{
+	struct exofs_sb_info *sbi;
+	osd_end_request(or);
+	sbi = p;
+	atomic_dec(&sbi->s_curr_pending);
+}
+
+/*
+ * Called when the refcount of an inode reaches zero.  We remove the object
+ * from the OSD here.  We make sure the object was created before we try and
+ * delete it.
+ */
+void exofs_delete_inode(struct inode *inode)
+{
+	struct exofs_i_info *oi = exofs_i(inode);
+	struct super_block *sb = inode->i_sb;
+	struct exofs_sb_info *sbi = sb->s_fs_info;
+	struct osd_obj_id obj = {sbi->s_pid, inode->i_ino + EXOFS_OBJ_OFF};
+	struct osd_request *or;
+	int ret;
+
+	truncate_inode_pages(&inode->i_data, 0);
+
+	if (is_bad_inode(inode))
+		goto no_delete;
+
+	mark_inode_dirty(inode);
+	exofs_update_inode(inode, inode_needs_sync(inode));
+
+	inode->i_size = 0;
+	if (inode->i_blocks)
+		exofs_truncate(inode);
+
+	clear_inode(inode);
+
+	or = osd_start_request(sbi->s_dev, GFP_KERNEL);
+	if (unlikely(!or)) {
+		EXOFS_ERR("exofs_delete_inode: osd_start_request failed\n");
+		return;
+	}
+
+	osd_req_remove_object(or, &obj);
+
+	/* if we are deleting an obj that hasn't been created yet, wait */
+	if (!obj_created(oi)) {
+		BUG_ON(!obj_2bcreated(oi));
+		wait_event(oi->i_wq, obj_created(oi));
+	}
+
+	ret = exofs_async_op(or, delete_done, sbi, oi->i_cred);
+	if (ret) {
+		EXOFS_ERR(
+		       "ERROR: @exofs_delete_inode exofs_async_op failed\n");
+		osd_end_request(or);
+		return;
+	}
+	atomic_inc(&sbi->s_curr_pending);
+
+	return;
+
+no_delete:
+	clear_inode(inode);
+}
diff --git a/fs/exofs/namei.c b/fs/exofs/namei.c
new file mode 100644
index 0000000..77fdd76
--- /dev/null
+++ b/fs/exofs/namei.c
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2005, 2006
+ * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com)
+ * Copyright (C) 2005, 2006
+ * International Business Machines
+ * Copyright (C) 2008, 2009
+ * Boaz Harrosh <bharrosh@panasas.com>
+ *
+ * Copyrights for code taken from ext2:
+ *     Copyright (C) 1992, 1993, 1994, 1995
+ *     Remy Card (card@masi.ibp.fr)
+ *     Laboratoire MASI - Institut Blaise Pascal
+ *     Universite Pierre et Marie Curie (Paris VI)
+ *     from
+ *     linux/fs/minix/inode.c
+ *     Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This file is part of exofs.
+ *
+ * exofs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.  Since it is based on ext2, and the only
+ * valid version of GPL for the Linux kernel is version 2, the only valid
+ * version of GPL for exofs is version 2.
+ *
+ * exofs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with exofs; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "exofs.h"
+
+static inline int exofs_add_nondir(struct dentry *dentry, struct inode *inode)
+{
+	int err = exofs_add_link(dentry, inode);
+	if (!err) {
+		d_instantiate(dentry, inode);
+		return 0;
+	}
+	inode_dec_link_count(inode);
+	iput(inode);
+	return err;
+}
+
+static struct dentry *exofs_lookup(struct inode *dir, struct dentry *dentry,
+				   struct nameidata *nd)
+{
+	struct inode *inode;
+	ino_t ino;
+
+	if (dentry->d_name.len > EXOFS_NAME_LEN)
+		return ERR_PTR(-ENAMETOOLONG);
+
+	ino = exofs_inode_by_name(dir, dentry);
+	inode = NULL;
+	if (ino) {
+		inode = exofs_iget(dir->i_sb, ino);
+		if (IS_ERR(inode))
+			return ERR_CAST(inode);
+	}
+	return d_splice_alias(inode, dentry);
+}
+
+static int exofs_create(struct inode *dir, struct dentry *dentry, int mode,
+			 struct nameidata *nd)
+{
+	struct inode *inode = exofs_new_inode(dir, mode);
+	int err = PTR_ERR(inode);
+	if (!IS_ERR(inode)) {
+		inode->i_op = &exofs_file_inode_operations;
+		inode->i_fop = &exofs_file_operations;
+		inode->i_mapping->a_ops = &exofs_aops;
+		mark_inode_dirty(inode);
+		err = exofs_add_nondir(dentry, inode);
+	}
+	return err;
+}
+
+static int exofs_mknod(struct inode *dir, struct dentry *dentry, int mode,
+		       dev_t rdev)
+{
+	struct inode *inode;
+	int err;
+
+	if (!new_valid_dev(rdev))
+		return -EINVAL;
+
+	inode = exofs_new_inode(dir, mode);
+	err = PTR_ERR(inode);
+	if (!IS_ERR(inode)) {
+		init_special_inode(inode, inode->i_mode, rdev);
+		mark_inode_dirty(inode);
+		err = exofs_add_nondir(dentry, inode);
+	}
+	return err;
+}
+
+static int exofs_symlink(struct inode *dir, struct dentry *dentry,
+			  const char *symname)
+{
+	struct super_block *sb = dir->i_sb;
+	int err = -ENAMETOOLONG;
+	unsigned l = strlen(symname)+1;
+	struct inode *inode;
+	struct exofs_i_info *oi;
+
+	if (l > sb->s_blocksize)
+		goto out;
+
+	inode = exofs_new_inode(dir, S_IFLNK | S_IRWXUGO);
+	err = PTR_ERR(inode);
+	if (IS_ERR(inode))
+		goto out;
+
+	oi = exofs_i(inode);
+	if (l > sizeof(oi->i_data)) {
+		/* slow symlink */
+		inode->i_op = &exofs_symlink_inode_operations;
+		inode->i_mapping->a_ops = &exofs_aops;
+		memset(oi->i_data, 0, sizeof(oi->i_data));
+
+		err = page_symlink(inode, symname, l);
+		if (err)
+			goto out_fail;
+	} else {
+		/* fast symlink */
+		inode->i_op = &exofs_fast_symlink_inode_operations;
+		memcpy(oi->i_data, symname, l);
+		inode->i_size = l-1;
+	}
+	mark_inode_dirty(inode);
+
+	err = exofs_add_nondir(dentry, inode);
+out:
+	return err;
+
+out_fail:
+	inode_dec_link_count(inode);
+	iput(inode);
+	goto out;
+}
+
+static int exofs_link(struct dentry *old_dentry, struct inode *dir,
+		struct dentry *dentry)
+{
+	struct inode *inode = old_dentry->d_inode;
+
+	if (inode->i_nlink >= EXOFS_LINK_MAX)
+		return -EMLINK;
+
+	inode->i_ctime = CURRENT_TIME;
+	inode_inc_link_count(inode);
+	atomic_inc(&inode->i_count);
+
+	return exofs_add_nondir(dentry, inode);
+}
+
+static int exofs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+	struct inode *inode;
+	int err = -EMLINK;
+
+	if (dir->i_nlink >= EXOFS_LINK_MAX)
+		goto out;
+
+	inode_inc_link_count(dir);
+
+	inode = exofs_new_inode(dir, S_IFDIR | mode);
+	err = PTR_ERR(inode);
+	if (IS_ERR(inode))
+		goto out_dir;
+
+	inode->i_op = &exofs_dir_inode_operations;
+	inode->i_fop = &exofs_dir_operations;
+	inode->i_mapping->a_ops = &exofs_aops;
+
+	inode_inc_link_count(inode);
+
+	err = exofs_make_empty(inode, dir);
+	if (err)
+		goto out_fail;
+
+	err = exofs_add_link(dentry, inode);
+	if (err)
+		goto out_fail;
+
+	d_instantiate(dentry, inode);
+out:
+	return err;
+
+out_fail:
+	inode_dec_link_count(inode);
+	inode_dec_link_count(inode);
+	iput(inode);
+out_dir:
+	inode_dec_link_count(dir);
+	goto out;
+}
+
+static int exofs_unlink(struct inode *dir, struct dentry *dentry)
+{
+	struct inode *inode = dentry->d_inode;
+	struct exofs_dir_entry *de;
+	struct page *page;
+	int err = -ENOENT;
+
+	de = exofs_find_entry(dir, dentry, &page);
+	if (!de)
+		goto out;
+
+	err = exofs_delete_entry(de, page);
+	if (err)
+		goto out;
+
+	inode->i_ctime = dir->i_ctime;
+	inode_dec_link_count(inode);
+	err = 0;
+out:
+	return err;
+}
+
+static int exofs_rmdir(struct inode *dir, struct dentry *dentry)
+{
+	struct inode *inode = dentry->d_inode;
+	int err = -ENOTEMPTY;
+
+	if (exofs_empty_dir(inode)) {
+		err = exofs_unlink(dir, dentry);
+		if (!err) {
+			inode->i_size = 0;
+			inode_dec_link_count(inode);
+			inode_dec_link_count(dir);
+		}
+	}
+	return err;
+}
+
+static int exofs_rename(struct inode *old_dir, struct dentry *old_dentry,
+		struct inode *new_dir, struct dentry *new_dentry)
+{
+	struct inode *old_inode = old_dentry->d_inode;
+	struct inode *new_inode = new_dentry->d_inode;
+	struct page *dir_page = NULL;
+	struct exofs_dir_entry *dir_de = NULL;
+	struct page *old_page;
+	struct exofs_dir_entry *old_de;
+	int err = -ENOENT;
+
+	old_de = exofs_find_entry(old_dir, old_dentry, &old_page);
+	if (!old_de)
+		goto out;
+
+	if (S_ISDIR(old_inode->i_mode)) {
+		err = -EIO;
+		dir_de = exofs_dotdot(old_inode, &dir_page);
+		if (!dir_de)
+			goto out_old;
+	}
+
+	if (new_inode) {
+		struct page *new_page;
+		struct exofs_dir_entry *new_de;
+
+		err = -ENOTEMPTY;
+		if (dir_de && !exofs_empty_dir(new_inode))
+			goto out_dir;
+
+		err = -ENOENT;
+		new_de = exofs_find_entry(new_dir, new_dentry, &new_page);
+		if (!new_de)
+			goto out_dir;
+		inode_inc_link_count(old_inode);
+		err = exofs_set_link(new_dir, new_de, new_page, old_inode);
+		new_inode->i_ctime = CURRENT_TIME;
+		if (dir_de)
+			drop_nlink(new_inode);
+		inode_dec_link_count(new_inode);
+		if (err)
+			goto out_dir;
+	} else {
+		if (dir_de) {
+			err = -EMLINK;
+			if (new_dir->i_nlink >= EXOFS_LINK_MAX)
+				goto out_dir;
+		}
+		inode_inc_link_count(old_inode);
+		err = exofs_add_link(new_dentry, old_inode);
+		if (err) {
+			inode_dec_link_count(old_inode);
+			goto out_dir;
+		}
+		if (dir_de)
+			inode_inc_link_count(new_dir);
+	}
+
+	old_inode->i_ctime = CURRENT_TIME;
+
+	exofs_delete_entry(old_de, old_page);
+	inode_dec_link_count(old_inode);
+
+	if (dir_de) {
+		err = exofs_set_link(old_inode, dir_de, dir_page, new_dir);
+		inode_dec_link_count(old_dir);
+		if (err)
+			goto out_dir;
+	}
+	return 0;
+
+
+out_dir:
+	if (dir_de) {
+		kunmap(dir_page);
+		page_cache_release(dir_page);
+	}
+out_old:
+	kunmap(old_page);
+	page_cache_release(old_page);
+out:
+	return err;
+}
+
+const struct inode_operations exofs_dir_inode_operations = {
+	.create 	= exofs_create,
+	.lookup 	= exofs_lookup,
+	.link   	= exofs_link,
+	.unlink 	= exofs_unlink,
+	.symlink	= exofs_symlink,
+	.mkdir  	= exofs_mkdir,
+	.rmdir  	= exofs_rmdir,
+	.mknod  	= exofs_mknod,
+	.rename 	= exofs_rename,
+	.setattr	= exofs_setattr,
+};
+
+const struct inode_operations exofs_special_inode_operations = {
+	.setattr	= exofs_setattr,
+};
diff --git a/fs/exofs/osd.c b/fs/exofs/osd.c
new file mode 100644
index 0000000..b249ae9
--- /dev/null
+++ b/fs/exofs/osd.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2005, 2006
+ * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com)
+ * Copyright (C) 2005, 2006
+ * International Business Machines
+ * Copyright (C) 2008, 2009
+ * Boaz Harrosh <bharrosh@panasas.com>
+ *
+ * This file is part of exofs.
+ *
+ * exofs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.  Since it is based on ext2, and the only
+ * valid version of GPL for the Linux kernel is version 2, the only valid
+ * version of GPL for exofs is version 2.
+ *
+ * exofs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with exofs; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <scsi/scsi_device.h>
+#include <scsi/osd_sense.h>
+
+#include "exofs.h"
+
+int exofs_check_ok_resid(struct osd_request *or, u64 *in_resid, u64 *out_resid)
+{
+	struct osd_sense_info osi;
+	int ret = osd_req_decode_sense(or, &osi);
+
+	if (ret) { /* translate to Linux codes */
+		if (osi.additional_code == scsi_invalid_field_in_cdb) {
+			if (osi.cdb_field_offset == OSD_CFO_STARTING_BYTE)
+				ret = -EFAULT;
+			if (osi.cdb_field_offset == OSD_CFO_OBJECT_ID)
+				ret = -ENOENT;
+			else
+				ret = -EINVAL;
+		} else if (osi.additional_code == osd_quota_error)
+			ret = -ENOSPC;
+		else
+			ret = -EIO;
+	}
+
+	/* FIXME: should be include in osd_sense_info */
+	if (in_resid)
+		*in_resid = or->in.req ? or->in.req->data_len : 0;
+
+	if (out_resid)
+		*out_resid = or->out.req ? or->out.req->data_len : 0;
+
+	return ret;
+}
+
+void exofs_make_credential(u8 cred_a[OSD_CAP_LEN], const struct osd_obj_id *obj)
+{
+	osd_sec_init_nosec_doall_caps(cred_a, obj, false, true);
+}
+
+/*
+ * Perform a synchronous OSD operation.
+ */
+int exofs_sync_op(struct osd_request *or, int timeout, uint8_t *credential)
+{
+	int ret;
+
+	or->timeout = timeout;
+	ret = osd_finalize_request(or, 0, credential, NULL);
+	if (ret) {
+		EXOFS_DBGMSG("Faild to osd_finalize_request() => %d\n", ret);
+		return ret;
+	}
+
+	ret = osd_execute_request(or);
+
+	if (ret)
+		EXOFS_DBGMSG("osd_execute_request() => %d\n", ret);
+	/* osd_req_decode_sense(or, ret); */
+	return ret;
+}
+
+/*
+ * Perform an asynchronous OSD operation.
+ */
+int exofs_async_op(struct osd_request *or, osd_req_done_fn *async_done,
+		   void *caller_context, u8 *cred)
+{
+	int ret;
+
+	ret = osd_finalize_request(or, 0, cred, NULL);
+	if (ret) {
+		EXOFS_DBGMSG("Faild to osd_finalize_request() => %d\n", ret);
+		return ret;
+	}
+
+	ret = osd_execute_request_async(or, async_done, caller_context);
+
+	if (ret)
+		EXOFS_DBGMSG("osd_execute_request_async() => %d\n", ret);
+	return ret;
+}
+
+int extract_attr_from_req(struct osd_request *or, struct osd_attr *attr)
+{
+	struct osd_attr cur_attr = {.attr_page = 0}; /* start with zeros */
+	void *iter = NULL;
+	int nelem;
+
+	do {
+		nelem = 1;
+		osd_req_decode_get_attr_list(or, &cur_attr, &nelem, &iter);
+		if ((cur_attr.attr_page == attr->attr_page) &&
+		    (cur_attr.attr_id == attr->attr_id)) {
+			attr->len = cur_attr.len;
+			attr->val_ptr = cur_attr.val_ptr;
+			return 0;
+		}
+	} while (iter);
+
+	return -EIO;
+}
+
+int osd_req_read_kern(struct osd_request *or,
+	const struct osd_obj_id *obj, u64 offset, void* buff, u64 len)
+{
+	struct request_queue *req_q = or->osd_dev->scsi_device->request_queue;
+	struct bio *bio = bio_map_kern(req_q, buff, len, GFP_KERNEL);
+
+	if (!bio)
+		return -ENOMEM;
+
+	osd_req_read(or, obj, bio, offset);
+	return 0;
+}
+
+int osd_req_write_kern(struct osd_request *or,
+	const struct osd_obj_id *obj, u64 offset, void* buff, u64 len)
+{
+	struct request_queue *req_q = or->osd_dev->scsi_device->request_queue;
+	struct bio *bio = bio_map_kern(req_q, buff, len, GFP_KERNEL);
+
+	if (!bio)
+		return -ENOMEM;
+
+	osd_req_write(or, obj, bio, offset);
+	return 0;
+}
diff --git a/fs/exofs/super.c b/fs/exofs/super.c
new file mode 100644
index 0000000..9f1985e
--- /dev/null
+++ b/fs/exofs/super.c
@@ -0,0 +1,584 @@
+/*
+ * Copyright (C) 2005, 2006
+ * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com)
+ * Copyright (C) 2005, 2006
+ * International Business Machines
+ * Copyright (C) 2008, 2009
+ * Boaz Harrosh <bharrosh@panasas.com>
+ *
+ * Copyrights for code taken from ext2:
+ *     Copyright (C) 1992, 1993, 1994, 1995
+ *     Remy Card (card@masi.ibp.fr)
+ *     Laboratoire MASI - Institut Blaise Pascal
+ *     Universite Pierre et Marie Curie (Paris VI)
+ *     from
+ *     linux/fs/minix/inode.c
+ *     Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This file is part of exofs.
+ *
+ * exofs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.  Since it is based on ext2, and the only
+ * valid version of GPL for the Linux kernel is version 2, the only valid
+ * version of GPL for exofs is version 2.
+ *
+ * exofs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with exofs; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/string.h>
+#include <linux/parser.h>
+#include <linux/vfs.h>
+#include <linux/random.h>
+#include <linux/exportfs.h>
+
+#include "exofs.h"
+
+/******************************************************************************
+ * MOUNT OPTIONS
+ *****************************************************************************/
+
+/*
+ * struct to hold what we get from mount options
+ */
+struct exofs_mountopt {
+	const char *dev_name;
+	uint64_t pid;
+	int timeout;
+};
+
+/*
+ * exofs-specific mount-time options.
+ */
+enum { Opt_pid, Opt_to, Opt_mkfs, Opt_format, Opt_err };
+
+/*
+ * Our mount-time options.  These should ideally be 64-bit unsigned, but the
+ * kernel's parsing functions do not currently support that.  32-bit should be
+ * sufficient for most applications now.
+ */
+static match_table_t tokens = {
+	{Opt_pid, "pid=%u"},
+	{Opt_to, "to=%u"},
+	{Opt_err, NULL}
+};
+
+/*
+ * The main option parsing method.  Also makes sure that all of the mandatory
+ * mount options were set.
+ */
+static int parse_options(char *options, struct exofs_mountopt *opts)
+{
+	char *p;
+	substring_t args[MAX_OPT_ARGS];
+	int option;
+	bool s_pid = false;
+
+	EXOFS_DBGMSG("parse_options %s\n", options);
+	/* defaults */
+	memset(opts, 0, sizeof(*opts));
+	opts->timeout = BLK_DEFAULT_SG_TIMEOUT;
+
+	while ((p = strsep(&options, ",")) != NULL) {
+		int token;
+		char str[32];
+
+		if (!*p)
+			continue;
+
+		token = match_token(p, tokens, args);
+		switch (token) {
+		case Opt_pid:
+			if (0 == match_strlcpy(str, &args[0], sizeof(str)))
+				return -EINVAL;
+			opts->pid = simple_strtoull(str, NULL, 0);
+			if (opts->pid < EXOFS_MIN_PID) {
+				EXOFS_ERR("Partition ID must be >= %u",
+					  EXOFS_MIN_PID);
+				return -EINVAL;
+			}
+			s_pid = 1;
+			break;
+		case Opt_to:
+			if (match_int(&args[0], &option))
+				return -EINVAL;
+			if (option <= 0) {
+				EXOFS_ERR("Timout must be > 0");
+				return -EINVAL;
+			}
+			opts->timeout = option * HZ;
+			break;
+		}
+	}
+
+	if (!s_pid) {
+		EXOFS_ERR("Need to specify the following options:\n");
+		EXOFS_ERR("    -o pid=pid_no_to_use\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/******************************************************************************
+ * INODE CACHE
+ *****************************************************************************/
+
+/*
+ * Our inode cache.  Isn't it pretty?
+ */
+static struct kmem_cache *exofs_inode_cachep;
+
+/*
+ * Allocate an inode in the cache
+ */
+static struct inode *exofs_alloc_inode(struct super_block *sb)
+{
+	struct exofs_i_info *oi;
+
+	oi = kmem_cache_alloc(exofs_inode_cachep, GFP_KERNEL);
+	if (!oi)
+		return NULL;
+
+	oi->vfs_inode.i_version = 1;
+	return &oi->vfs_inode;
+}
+
+/*
+ * Remove an inode from the cache
+ */
+static void exofs_destroy_inode(struct inode *inode)
+{
+	kmem_cache_free(exofs_inode_cachep, exofs_i(inode));
+}
+
+/*
+ * Initialize the inode
+ */
+static void exofs_init_once(void *foo)
+{
+	struct exofs_i_info *oi = foo;
+
+	inode_init_once(&oi->vfs_inode);
+}
+
+/*
+ * Create and initialize the inode cache
+ */
+static int init_inodecache(void)
+{
+	exofs_inode_cachep = kmem_cache_create("exofs_inode_cache",
+				sizeof(struct exofs_i_info), 0,
+				SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD,
+				exofs_init_once);
+	if (exofs_inode_cachep == NULL)
+		return -ENOMEM;
+	return 0;
+}
+
+/*
+ * Destroy the inode cache
+ */
+static void destroy_inodecache(void)
+{
+	kmem_cache_destroy(exofs_inode_cachep);
+}
+
+/******************************************************************************
+ * SUPERBLOCK FUNCTIONS
+ *****************************************************************************/
+static const struct super_operations exofs_sops;
+static const struct export_operations exofs_export_ops;
+
+/*
+ * Write the superblock to the OSD
+ */
+static void exofs_write_super(struct super_block *sb)
+{
+	struct exofs_sb_info *sbi;
+	struct exofs_fscb *fscb;
+	struct osd_request *or;
+	struct osd_obj_id obj;
+	int ret;
+
+	fscb = kzalloc(sizeof(struct exofs_fscb), GFP_KERNEL);
+	if (!fscb) {
+		EXOFS_ERR("exofs_write_super: memory allocation failed.\n");
+		return;
+	}
+
+	lock_kernel();
+	sbi = sb->s_fs_info;
+	fscb->s_nextid = cpu_to_le64(sbi->s_nextid);
+	fscb->s_numfiles = cpu_to_le32(sbi->s_numfiles);
+	fscb->s_magic = cpu_to_le16(sb->s_magic);
+	fscb->s_newfs = 0;
+
+	or = osd_start_request(sbi->s_dev, GFP_KERNEL);
+	if (unlikely(!or)) {
+		EXOFS_ERR("exofs_write_super: osd_start_request failed.\n");
+		goto out;
+	}
+
+	obj.partition = sbi->s_pid;
+	obj.id = EXOFS_SUPER_ID;
+	ret = osd_req_write_kern(or, &obj, 0, fscb, sizeof(*fscb));
+	if (unlikely(ret)) {
+		EXOFS_ERR("exofs_write_super: osd_req_write_kern failed.\n");
+		goto out;
+	}
+
+	ret = exofs_sync_op(or, sbi->s_timeout, sbi->s_cred);
+	if (unlikely(ret)) {
+		EXOFS_ERR("exofs_write_super: exofs_sync_op failed.\n");
+		goto out;
+	}
+	sb->s_dirt = 0;
+
+out:
+	if (or)
+		osd_end_request(or);
+	unlock_kernel();
+	kfree(fscb);
+}
+
+/*
+ * This function is called when the vfs is freeing the superblock.  We just
+ * need to free our own part.
+ */
+static void exofs_put_super(struct super_block *sb)
+{
+	int num_pend;
+	struct exofs_sb_info *sbi = sb->s_fs_info;
+
+	/* make sure there are no pending commands */
+	for (num_pend = atomic_read(&sbi->s_curr_pending); num_pend > 0;
+	     num_pend = atomic_read(&sbi->s_curr_pending)) {
+		wait_queue_head_t wq;
+		init_waitqueue_head(&wq);
+		wait_event_timeout(wq,
+				  (atomic_read(&sbi->s_curr_pending) == 0),
+				  msecs_to_jiffies(100));
+	}
+
+	osduld_put_device(sbi->s_dev);
+	kfree(sb->s_fs_info);
+	sb->s_fs_info = NULL;
+}
+
+/*
+ * Read the superblock from the OSD and fill in the fields
+ */
+static int exofs_fill_super(struct super_block *sb, void *data, int silent)
+{
+	struct inode *root;
+	struct exofs_mountopt *opts = data;
+	struct exofs_sb_info *sbi;	/*extended info                  */
+	struct exofs_fscb fscb;		/*on-disk superblock info        */
+	struct osd_request *or = NULL;
+	struct osd_obj_id obj;
+	int ret;
+
+	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
+	if (!sbi)
+		return -ENOMEM;
+	sb->s_fs_info = sbi;
+
+	/* use mount options to fill superblock */
+	sbi->s_dev = osduld_path_lookup(opts->dev_name);
+	if (IS_ERR(sbi->s_dev)) {
+		ret = PTR_ERR(sbi->s_dev);
+		sbi->s_dev = NULL;
+		goto free_sbi;
+	}
+
+	sbi->s_pid = opts->pid;
+	sbi->s_timeout = opts->timeout;
+
+	/* fill in some other data by hand */
+	memset(sb->s_id, 0, sizeof(sb->s_id));
+	strcpy(sb->s_id, "exofs");
+	sb->s_blocksize = EXOFS_BLKSIZE;
+	sb->s_blocksize_bits = EXOFS_BLKSHIFT;
+	sb->s_maxbytes = MAX_LFS_FILESIZE;
+	atomic_set(&sbi->s_curr_pending, 0);
+	sb->s_bdev = NULL;
+	sb->s_dev = 0;
+
+	/* read data from on-disk superblock object */
+	obj.partition = sbi->s_pid;
+	obj.id = EXOFS_SUPER_ID;
+	exofs_make_credential(sbi->s_cred, &obj);
+
+	or = osd_start_request(sbi->s_dev, GFP_KERNEL);
+	if (unlikely(!or)) {
+		if (!silent)
+			EXOFS_ERR(
+			       "exofs_fill_super: osd_start_request failed.\n");
+		ret = -ENOMEM;
+		goto free_sbi;
+	}
+	ret = osd_req_read_kern(or, &obj, 0, &fscb, sizeof(fscb));
+	if (unlikely(ret)) {
+		if (!silent)
+			EXOFS_ERR(
+			       "exofs_fill_super: osd_req_read_kern failed.\n");
+		ret = -ENOMEM;
+		goto free_sbi;
+	}
+
+	ret = exofs_sync_op(or, sbi->s_timeout, sbi->s_cred);
+	if (unlikely(ret)) {
+		if (!silent)
+			EXOFS_ERR("exofs_fill_super: exofs_sync_op failed.\n");
+		ret = -EIO;
+		goto free_sbi;
+	}
+
+	sb->s_magic = le16_to_cpu(fscb.s_magic);
+	sbi->s_nextid = le64_to_cpu(fscb.s_nextid);
+	sbi->s_numfiles = le32_to_cpu(fscb.s_numfiles);
+
+	/* make sure what we read from the object store is correct */
+	if (sb->s_magic != EXOFS_SUPER_MAGIC) {
+		if (!silent)
+			EXOFS_ERR("ERROR: Bad magic value\n");
+		ret = -EINVAL;
+		goto free_sbi;
+	}
+
+	/* start generation numbers from a random point */
+	get_random_bytes(&sbi->s_next_generation, sizeof(u32));
+	spin_lock_init(&sbi->s_next_gen_lock);
+
+	/* set up operation vectors */
+	sb->s_op = &exofs_sops;
+	sb->s_export_op = &exofs_export_ops;
+	root = exofs_iget(sb, EXOFS_ROOT_ID - EXOFS_OBJ_OFF);
+	if (IS_ERR(root)) {
+		EXOFS_ERR("ERROR: exofs_iget failed\n");
+		ret = PTR_ERR(root);
+		goto free_sbi;
+	}
+	sb->s_root = d_alloc_root(root);
+	if (!sb->s_root) {
+		iput(root);
+		EXOFS_ERR("ERROR: get root inode failed\n");
+		ret = -ENOMEM;
+		goto free_sbi;
+	}
+
+	if (!S_ISDIR(root->i_mode)) {
+		dput(sb->s_root);
+		sb->s_root = NULL;
+		EXOFS_ERR("ERROR: corrupt root inode (mode = %hd)\n",
+		       root->i_mode);
+		ret = -EINVAL;
+		goto free_sbi;
+	}
+
+	ret = 0;
+out:
+	if (or)
+		osd_end_request(or);
+	return ret;
+
+free_sbi:
+	osduld_put_device(sbi->s_dev); /* NULL safe */
+	kfree(sbi);
+	goto out;
+}
+
+/*
+ * Set up the superblock (calls exofs_fill_super eventually)
+ */
+static int exofs_get_sb(struct file_system_type *type,
+			  int flags, const char *dev_name,
+			  void *data, struct vfsmount *mnt)
+{
+	struct exofs_mountopt opts;
+	int ret;
+
+	ret = parse_options(data, &opts);
+	if (ret)
+		return ret;
+
+	opts.dev_name = dev_name;
+	return get_sb_nodev(type, flags, &opts, exofs_fill_super, mnt);
+}
+
+/*
+ * Return information about the file system state in the buffer.  This is used
+ * by the 'df' command, for example.
+ */
+static int exofs_statfs(struct dentry *dentry, struct kstatfs *buf)
+{
+	struct super_block *sb = dentry->d_sb;
+	struct exofs_sb_info *sbi = sb->s_fs_info;
+	struct osd_obj_id obj = {sbi->s_pid, 0};
+	struct osd_attr attrs[] = {
+		ATTR_DEF(OSD_APAGE_PARTITION_QUOTAS,
+			OSD_ATTR_PQ_CAPACITY_QUOTA, sizeof(__be64)),
+		ATTR_DEF(OSD_APAGE_PARTITION_INFORMATION,
+			OSD_ATTR_PI_USED_CAPACITY, sizeof(__be64)),
+	};
+	uint64_t capacity = ULLONG_MAX;
+	uint64_t used = ULLONG_MAX;
+	struct osd_request *or;
+	uint8_t cred_a[OSD_CAP_LEN];
+	int ret;
+
+	/* get used/capacity attributes */
+	exofs_make_credential(cred_a, &obj);
+
+	or = osd_start_request(sbi->s_dev, GFP_KERNEL);
+	if (unlikely(!or)) {
+		EXOFS_DBGMSG("exofs_statfs: osd_start_request failed.\n");
+		return -ENOMEM;
+	}
+
+	osd_req_get_attributes(or, &obj);
+	osd_req_add_get_attr_list(or, attrs, ARRAY_SIZE(attrs));
+	ret = exofs_sync_op(or, sbi->s_timeout, cred_a);
+	if (unlikely(ret))
+		goto out;
+
+	ret = extract_attr_from_req(or, &attrs[0]);
+	if (likely(!ret))
+		capacity = get_unaligned_be64(attrs[0].val_ptr);
+	else
+		EXOFS_DBGMSG("exofs_statfs: get capacity failed.\n");
+
+	ret = extract_attr_from_req(or, &attrs[1]);
+	if (likely(!ret))
+		used = get_unaligned_be64(attrs[1].val_ptr);
+	else
+		EXOFS_DBGMSG("exofs_statfs: get used-space failed.\n");
+
+	/* fill in the stats buffer */
+	buf->f_type = EXOFS_SUPER_MAGIC;
+	buf->f_bsize = EXOFS_BLKSIZE;
+	buf->f_blocks = (capacity >> EXOFS_BLKSHIFT);
+	buf->f_bfree = ((capacity - used) >> EXOFS_BLKSHIFT);
+	buf->f_bavail = buf->f_bfree;
+	buf->f_files = sbi->s_numfiles;
+	buf->f_ffree = EXOFS_MAX_ID - sbi->s_numfiles;
+	buf->f_namelen = EXOFS_NAME_LEN;
+
+out:
+	osd_end_request(or);
+	return ret;
+}
+
+static const struct super_operations exofs_sops = {
+	.alloc_inode    = exofs_alloc_inode,
+	.destroy_inode  = exofs_destroy_inode,
+	.write_inode    = exofs_write_inode,
+	.delete_inode   = exofs_delete_inode,
+	.put_super      = exofs_put_super,
+	.write_super    = exofs_write_super,
+	.statfs         = exofs_statfs,
+};
+
+/******************************************************************************
+ * EXPORT OPERATIONS
+ *****************************************************************************/
+
+struct dentry *exofs_get_parent(struct dentry *child)
+{
+	unsigned long ino = exofs_parent_ino(child);
+
+	if (!ino)
+		return NULL;
+
+	return d_obtain_alias(exofs_iget(child->d_inode->i_sb, ino));
+}
+
+static struct inode *exofs_nfs_get_inode(struct super_block *sb,
+		u64 ino, u32 generation)
+{
+	struct inode *inode;
+
+	inode = exofs_iget(sb, ino);
+	if (IS_ERR(inode))
+		return ERR_CAST(inode);
+	if (generation && inode->i_generation != generation) {
+		/* we didn't find the right inode.. */
+		iput(inode);
+		return ERR_PTR(-ESTALE);
+	}
+	return inode;
+}
+
+static struct dentry *exofs_fh_to_dentry(struct super_block *sb,
+				struct fid *fid, int fh_len, int fh_type)
+{
+	return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
+				    exofs_nfs_get_inode);
+}
+
+static struct dentry *exofs_fh_to_parent(struct super_block *sb,
+				struct fid *fid, int fh_len, int fh_type)
+{
+	return generic_fh_to_parent(sb, fid, fh_len, fh_type,
+				    exofs_nfs_get_inode);
+}
+
+static const struct export_operations exofs_export_ops = {
+	.fh_to_dentry = exofs_fh_to_dentry,
+	.fh_to_parent = exofs_fh_to_parent,
+	.get_parent = exofs_get_parent,
+};
+
+/******************************************************************************
+ * INSMOD/RMMOD
+ *****************************************************************************/
+
+/*
+ * struct that describes this file system
+ */
+static struct file_system_type exofs_type = {
+	.owner          = THIS_MODULE,
+	.name           = "exofs",
+	.get_sb         = exofs_get_sb,
+	.kill_sb        = generic_shutdown_super,
+};
+
+static int __init init_exofs(void)
+{
+	int err;
+
+	err = init_inodecache();
+	if (err)
+		goto out;
+
+	err = register_filesystem(&exofs_type);
+	if (err)
+		goto out_d;
+
+	return 0;
+out_d:
+	destroy_inodecache();
+out:
+	return err;
+}
+
+static void __exit exit_exofs(void)
+{
+	unregister_filesystem(&exofs_type);
+	destroy_inodecache();
+}
+
+MODULE_AUTHOR("Avishay Traeger <avishay@gmail.com>");
+MODULE_DESCRIPTION("exofs");
+MODULE_LICENSE("GPL");
+
+module_init(init_exofs)
+module_exit(exit_exofs)
diff --git a/fs/exofs/symlink.c b/fs/exofs/symlink.c
new file mode 100644
index 0000000..36e2d7b
--- /dev/null
+++ b/fs/exofs/symlink.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2005, 2006
+ * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com)
+ * Copyright (C) 2005, 2006
+ * International Business Machines
+ * Copyright (C) 2008, 2009
+ * Boaz Harrosh <bharrosh@panasas.com>
+ *
+ * Copyrights for code taken from ext2:
+ *     Copyright (C) 1992, 1993, 1994, 1995
+ *     Remy Card (card@masi.ibp.fr)
+ *     Laboratoire MASI - Institut Blaise Pascal
+ *     Universite Pierre et Marie Curie (Paris VI)
+ *     from
+ *     linux/fs/minix/inode.c
+ *     Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This file is part of exofs.
+ *
+ * exofs is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.  Since it is based on ext2, and the only
+ * valid version of GPL for the Linux kernel is version 2, the only valid
+ * version of GPL for exofs is version 2.
+ *
+ * exofs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with exofs; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/namei.h>
+
+#include "exofs.h"
+
+static void *exofs_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+	struct exofs_i_info *oi = exofs_i(dentry->d_inode);
+
+	nd_set_link(nd, (char *)oi->i_data);
+	return NULL;
+}
+
+const struct inode_operations exofs_symlink_inode_operations = {
+	.readlink	= generic_readlink,
+	.follow_link	= page_follow_link_light,
+	.put_link	= page_put_link,
+};
+
+const struct inode_operations exofs_fast_symlink_inode_operations = {
+	.readlink	= generic_readlink,
+	.follow_link	= exofs_follow_link,
+};
diff --git a/fs/ext3/file.c b/fs/ext3/file.c
index 521f823..5b49704 100644
--- a/fs/ext3/file.c
+++ b/fs/ext3/file.c
@@ -33,6 +33,10 @@
  */
 static int ext3_release_file (struct inode * inode, struct file * filp)
 {
+	if (EXT3_I(inode)->i_state & EXT3_STATE_FLUSH_ON_CLOSE) {
+		filemap_flush(inode->i_mapping);
+		EXT3_I(inode)->i_state &= ~EXT3_STATE_FLUSH_ON_CLOSE;
+	}
 	/* if we are the last writer on the inode, drop the block reservation */
 	if ((filp->f_mode & FMODE_WRITE) &&
 			(atomic_read(&inode->i_writecount) == 1))
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index d3ef6566b..466a332 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -2363,6 +2363,9 @@
 	if (!ext3_can_truncate(inode))
 		return;
 
+	if (inode->i_size == 0 && ext3_should_writeback_data(inode))
+		ei->i_state |= EXT3_STATE_FLUSH_ON_CLOSE;
+
 	/*
 	 * We have to lock the EOF page here, because lock_page() nests
 	 * outside journal_start().
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index 6ddaa0a..6ff7b97 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -2274,7 +2274,7 @@
 	struct inode * old_inode, * new_inode;
 	struct buffer_head * old_bh, * new_bh, * dir_bh;
 	struct ext3_dir_entry_2 * old_de, * new_de;
-	int retval;
+	int retval, flush_file = 0;
 
 	old_bh = new_bh = dir_bh = NULL;
 
@@ -2410,6 +2410,8 @@
 		ext3_mark_inode_dirty(handle, new_inode);
 		if (!new_inode->i_nlink)
 			ext3_orphan_add(handle, new_inode);
+		if (ext3_should_writeback_data(new_inode))
+			flush_file = 1;
 	}
 	retval = 0;
 
@@ -2418,6 +2420,8 @@
 	brelse (old_bh);
 	brelse (new_bh);
 	ext3_journal_stop(handle);
+	if (retval == 0 && flush_file)
+		filemap_flush(old_inode->i_mapping);
 	return retval;
 }
 
diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig
index 7505482..418b6f3 100644
--- a/fs/ext4/Kconfig
+++ b/fs/ext4/Kconfig
@@ -18,7 +18,7 @@
 	  filesystem; while there will be some performance gains from
 	  the delayed allocation and inode table readahead, the best
 	  performance gains will require enabling ext4 features in the
-	  filesystem, or formating a new filesystem as an ext4
+	  filesystem, or formatting a new filesystem as an ext4
 	  filesystem initially.
 
 	  To compile this file system support as a module, choose M here. The
diff --git a/fs/file_table.c b/fs/file_table.c
index b74a8e1..54018fe 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -169,7 +169,6 @@
 		fmode_t mode, const struct file_operations *fop)
 {
 	struct file *file;
-	struct path;
 
 	file = get_empty_filp();
 	if (!file)
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index eed4806..91013ff 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -435,7 +435,7 @@
  * If older_than_this is non-NULL, then only write out inodes which
  * had their first dirtying at a time earlier than *older_than_this.
  *
- * If we're a pdlfush thread, then implement pdflush collision avoidance
+ * If we're a pdflush thread, then implement pdflush collision avoidance
  * against the entire list.
  *
  * If `bdi' is non-zero then we're being asked to writeback a specific queue.
diff --git a/fs/fscache/Kconfig b/fs/fscache/Kconfig
new file mode 100644
index 0000000..9bbb8ce
--- /dev/null
+++ b/fs/fscache/Kconfig
@@ -0,0 +1,56 @@
+
+config FSCACHE
+	tristate "General filesystem local caching manager"
+	depends on EXPERIMENTAL
+	select SLOW_WORK
+	help
+	  This option enables a generic filesystem caching manager that can be
+	  used by various network and other filesystems to cache data locally.
+	  Different sorts of caches can be plugged in, depending on the
+	  resources available.
+
+	  See Documentation/filesystems/caching/fscache.txt for more information.
+
+config FSCACHE_STATS
+	bool "Gather statistical information on local caching"
+	depends on FSCACHE && PROC_FS
+	help
+	  This option causes statistical information to be gathered on local
+	  caching and exported through file:
+
+		/proc/fs/fscache/stats
+
+	  The gathering of statistics adds a certain amount of overhead to
+	  execution as there are a quite a few stats gathered, and on a
+	  multi-CPU system these may be on cachelines that keep bouncing
+	  between CPUs.  On the other hand, the stats are very useful for
+	  debugging purposes.  Saying 'Y' here is recommended.
+
+	  See Documentation/filesystems/caching/fscache.txt for more information.
+
+config FSCACHE_HISTOGRAM
+	bool "Gather latency information on local caching"
+	depends on FSCACHE && PROC_FS
+	help
+	  This option causes latency information to be gathered on local
+	  caching and exported through file:
+
+		/proc/fs/fscache/histogram
+
+	  The generation of this histogram adds a certain amount of overhead to
+	  execution as there are a number of points at which data is gathered,
+	  and on a multi-CPU system these may be on cachelines that keep
+	  bouncing between CPUs.  On the other hand, the histogram may be
+	  useful for debugging purposes.  Saying 'N' here is recommended.
+
+	  See Documentation/filesystems/caching/fscache.txt for more information.
+
+config FSCACHE_DEBUG
+	bool "Debug FS-Cache"
+	depends on FSCACHE
+	help
+	  This permits debugging to be dynamically enabled in the local caching
+	  management module.  If this is set, the debugging output may be
+	  enabled by setting bits in /sys/modules/fscache/parameter/debug.
+
+	  See Documentation/filesystems/caching/fscache.txt for more information.
diff --git a/fs/fscache/Makefile b/fs/fscache/Makefile
new file mode 100644
index 0000000..91571b9
--- /dev/null
+++ b/fs/fscache/Makefile
@@ -0,0 +1,19 @@
+#
+# Makefile for general filesystem caching code
+#
+
+fscache-y := \
+	cache.o \
+	cookie.o \
+	fsdef.o \
+	main.o \
+	netfs.o \
+	object.o \
+	operation.o \
+	page.o
+
+fscache-$(CONFIG_PROC_FS) += proc.o
+fscache-$(CONFIG_FSCACHE_STATS) += stats.o
+fscache-$(CONFIG_FSCACHE_HISTOGRAM) += histogram.o
+
+obj-$(CONFIG_FSCACHE) := fscache.o
diff --git a/fs/fscache/cache.c b/fs/fscache/cache.c
new file mode 100644
index 0000000..e21985b
--- /dev/null
+++ b/fs/fscache/cache.c
@@ -0,0 +1,415 @@
+/* FS-Cache cache handling
+ *
+ * Copyright (C) 2007 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define FSCACHE_DEBUG_LEVEL CACHE
+#include <linux/module.h>
+#include <linux/slab.h>
+#include "internal.h"
+
+LIST_HEAD(fscache_cache_list);
+DECLARE_RWSEM(fscache_addremove_sem);
+DECLARE_WAIT_QUEUE_HEAD(fscache_cache_cleared_wq);
+EXPORT_SYMBOL(fscache_cache_cleared_wq);
+
+static LIST_HEAD(fscache_cache_tag_list);
+
+/*
+ * look up a cache tag
+ */
+struct fscache_cache_tag *__fscache_lookup_cache_tag(const char *name)
+{
+	struct fscache_cache_tag *tag, *xtag;
+
+	/* firstly check for the existence of the tag under read lock */
+	down_read(&fscache_addremove_sem);
+
+	list_for_each_entry(tag, &fscache_cache_tag_list, link) {
+		if (strcmp(tag->name, name) == 0) {
+			atomic_inc(&tag->usage);
+			up_read(&fscache_addremove_sem);
+			return tag;
+		}
+	}
+
+	up_read(&fscache_addremove_sem);
+
+	/* the tag does not exist - create a candidate */
+	xtag = kzalloc(sizeof(*xtag) + strlen(name) + 1, GFP_KERNEL);
+	if (!xtag)
+		/* return a dummy tag if out of memory */
+		return ERR_PTR(-ENOMEM);
+
+	atomic_set(&xtag->usage, 1);
+	strcpy(xtag->name, name);
+
+	/* write lock, search again and add if still not present */
+	down_write(&fscache_addremove_sem);
+
+	list_for_each_entry(tag, &fscache_cache_tag_list, link) {
+		if (strcmp(tag->name, name) == 0) {
+			atomic_inc(&tag->usage);
+			up_write(&fscache_addremove_sem);
+			kfree(xtag);
+			return tag;
+		}
+	}
+
+	list_add_tail(&xtag->link, &fscache_cache_tag_list);
+	up_write(&fscache_addremove_sem);
+	return xtag;
+}
+
+/*
+ * release a reference to a cache tag
+ */
+void __fscache_release_cache_tag(struct fscache_cache_tag *tag)
+{
+	if (tag != ERR_PTR(-ENOMEM)) {
+		down_write(&fscache_addremove_sem);
+
+		if (atomic_dec_and_test(&tag->usage))
+			list_del_init(&tag->link);
+		else
+			tag = NULL;
+
+		up_write(&fscache_addremove_sem);
+
+		kfree(tag);
+	}
+}
+
+/*
+ * select a cache in which to store an object
+ * - the cache addremove semaphore must be at least read-locked by the caller
+ * - the object will never be an index
+ */
+struct fscache_cache *fscache_select_cache_for_object(
+	struct fscache_cookie *cookie)
+{
+	struct fscache_cache_tag *tag;
+	struct fscache_object *object;
+	struct fscache_cache *cache;
+
+	_enter("");
+
+	if (list_empty(&fscache_cache_list)) {
+		_leave(" = NULL [no cache]");
+		return NULL;
+	}
+
+	/* we check the parent to determine the cache to use */
+	spin_lock(&cookie->lock);
+
+	/* the first in the parent's backing list should be the preferred
+	 * cache */
+	if (!hlist_empty(&cookie->backing_objects)) {
+		object = hlist_entry(cookie->backing_objects.first,
+				     struct fscache_object, cookie_link);
+
+		cache = object->cache;
+		if (object->state >= FSCACHE_OBJECT_DYING ||
+		    test_bit(FSCACHE_IOERROR, &cache->flags))
+			cache = NULL;
+
+		spin_unlock(&cookie->lock);
+		_leave(" = %p [parent]", cache);
+		return cache;
+	}
+
+	/* the parent is unbacked */
+	if (cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) {
+		/* cookie not an index and is unbacked */
+		spin_unlock(&cookie->lock);
+		_leave(" = NULL [cookie ub,ni]");
+		return NULL;
+	}
+
+	spin_unlock(&cookie->lock);
+
+	if (!cookie->def->select_cache)
+		goto no_preference;
+
+	/* ask the netfs for its preference */
+	tag = cookie->def->select_cache(cookie->parent->netfs_data,
+					cookie->netfs_data);
+	if (!tag)
+		goto no_preference;
+
+	if (tag == ERR_PTR(-ENOMEM)) {
+		_leave(" = NULL [nomem tag]");
+		return NULL;
+	}
+
+	if (!tag->cache) {
+		_leave(" = NULL [unbacked tag]");
+		return NULL;
+	}
+
+	if (test_bit(FSCACHE_IOERROR, &tag->cache->flags))
+		return NULL;
+
+	_leave(" = %p [specific]", tag->cache);
+	return tag->cache;
+
+no_preference:
+	/* netfs has no preference - just select first cache */
+	cache = list_entry(fscache_cache_list.next,
+			   struct fscache_cache, link);
+	_leave(" = %p [first]", cache);
+	return cache;
+}
+
+/**
+ * fscache_init_cache - Initialise a cache record
+ * @cache: The cache record to be initialised
+ * @ops: The cache operations to be installed in that record
+ * @idfmt: Format string to define identifier
+ * @...: sprintf-style arguments
+ *
+ * Initialise a record of a cache and fill in the name.
+ *
+ * See Documentation/filesystems/caching/backend-api.txt for a complete
+ * description.
+ */
+void fscache_init_cache(struct fscache_cache *cache,
+			const struct fscache_cache_ops *ops,
+			const char *idfmt,
+			...)
+{
+	va_list va;
+
+	memset(cache, 0, sizeof(*cache));
+
+	cache->ops = ops;
+
+	va_start(va, idfmt);
+	vsnprintf(cache->identifier, sizeof(cache->identifier), idfmt, va);
+	va_end(va);
+
+	INIT_WORK(&cache->op_gc, fscache_operation_gc);
+	INIT_LIST_HEAD(&cache->link);
+	INIT_LIST_HEAD(&cache->object_list);
+	INIT_LIST_HEAD(&cache->op_gc_list);
+	spin_lock_init(&cache->object_list_lock);
+	spin_lock_init(&cache->op_gc_list_lock);
+}
+EXPORT_SYMBOL(fscache_init_cache);
+
+/**
+ * fscache_add_cache - Declare a cache as being open for business
+ * @cache: The record describing the cache
+ * @ifsdef: The record of the cache object describing the top-level index
+ * @tagname: The tag describing this cache
+ *
+ * Add a cache to the system, making it available for netfs's to use.
+ *
+ * See Documentation/filesystems/caching/backend-api.txt for a complete
+ * description.
+ */
+int fscache_add_cache(struct fscache_cache *cache,
+		      struct fscache_object *ifsdef,
+		      const char *tagname)
+{
+	struct fscache_cache_tag *tag;
+
+	BUG_ON(!cache->ops);
+	BUG_ON(!ifsdef);
+
+	cache->flags = 0;
+	ifsdef->event_mask = ULONG_MAX & ~(1 << FSCACHE_OBJECT_EV_CLEARED);
+	ifsdef->state = FSCACHE_OBJECT_ACTIVE;
+
+	if (!tagname)
+		tagname = cache->identifier;
+
+	BUG_ON(!tagname[0]);
+
+	_enter("{%s.%s},,%s", cache->ops->name, cache->identifier, tagname);
+
+	/* we use the cache tag to uniquely identify caches */
+	tag = __fscache_lookup_cache_tag(tagname);
+	if (IS_ERR(tag))
+		goto nomem;
+
+	if (test_and_set_bit(FSCACHE_TAG_RESERVED, &tag->flags))
+		goto tag_in_use;
+
+	cache->kobj = kobject_create_and_add(tagname, fscache_root);
+	if (!cache->kobj)
+		goto error;
+
+	ifsdef->cookie = &fscache_fsdef_index;
+	ifsdef->cache = cache;
+	cache->fsdef = ifsdef;
+
+	down_write(&fscache_addremove_sem);
+
+	tag->cache = cache;
+	cache->tag = tag;
+
+	/* add the cache to the list */
+	list_add(&cache->link, &fscache_cache_list);
+
+	/* add the cache's netfs definition index object to the cache's
+	 * list */
+	spin_lock(&cache->object_list_lock);
+	list_add_tail(&ifsdef->cache_link, &cache->object_list);
+	spin_unlock(&cache->object_list_lock);
+
+	/* add the cache's netfs definition index object to the top level index
+	 * cookie as a known backing object */
+	spin_lock(&fscache_fsdef_index.lock);
+
+	hlist_add_head(&ifsdef->cookie_link,
+		       &fscache_fsdef_index.backing_objects);
+
+	atomic_inc(&fscache_fsdef_index.usage);
+
+	/* done */
+	spin_unlock(&fscache_fsdef_index.lock);
+	up_write(&fscache_addremove_sem);
+
+	printk(KERN_NOTICE "FS-Cache: Cache \"%s\" added (type %s)\n",
+	       cache->tag->name, cache->ops->name);
+	kobject_uevent(cache->kobj, KOBJ_ADD);
+
+	_leave(" = 0 [%s]", cache->identifier);
+	return 0;
+
+tag_in_use:
+	printk(KERN_ERR "FS-Cache: Cache tag '%s' already in use\n", tagname);
+	__fscache_release_cache_tag(tag);
+	_leave(" = -EXIST");
+	return -EEXIST;
+
+error:
+	__fscache_release_cache_tag(tag);
+	_leave(" = -EINVAL");
+	return -EINVAL;
+
+nomem:
+	_leave(" = -ENOMEM");
+	return -ENOMEM;
+}
+EXPORT_SYMBOL(fscache_add_cache);
+
+/**
+ * fscache_io_error - Note a cache I/O error
+ * @cache: The record describing the cache
+ *
+ * Note that an I/O error occurred in a cache and that it should no longer be
+ * used for anything.  This also reports the error into the kernel log.
+ *
+ * See Documentation/filesystems/caching/backend-api.txt for a complete
+ * description.
+ */
+void fscache_io_error(struct fscache_cache *cache)
+{
+	set_bit(FSCACHE_IOERROR, &cache->flags);
+
+	printk(KERN_ERR "FS-Cache: Cache %s stopped due to I/O error\n",
+	       cache->ops->name);
+}
+EXPORT_SYMBOL(fscache_io_error);
+
+/*
+ * request withdrawal of all the objects in a cache
+ * - all the objects being withdrawn are moved onto the supplied list
+ */
+static void fscache_withdraw_all_objects(struct fscache_cache *cache,
+					 struct list_head *dying_objects)
+{
+	struct fscache_object *object;
+
+	spin_lock(&cache->object_list_lock);
+
+	while (!list_empty(&cache->object_list)) {
+		object = list_entry(cache->object_list.next,
+				    struct fscache_object, cache_link);
+		list_move_tail(&object->cache_link, dying_objects);
+
+		_debug("withdraw %p", object->cookie);
+
+		spin_lock(&object->lock);
+		spin_unlock(&cache->object_list_lock);
+		fscache_raise_event(object, FSCACHE_OBJECT_EV_WITHDRAW);
+		spin_unlock(&object->lock);
+
+		cond_resched();
+		spin_lock(&cache->object_list_lock);
+	}
+
+	spin_unlock(&cache->object_list_lock);
+}
+
+/**
+ * fscache_withdraw_cache - Withdraw a cache from the active service
+ * @cache: The record describing the cache
+ *
+ * Withdraw a cache from service, unbinding all its cache objects from the
+ * netfs cookies they're currently representing.
+ *
+ * See Documentation/filesystems/caching/backend-api.txt for a complete
+ * description.
+ */
+void fscache_withdraw_cache(struct fscache_cache *cache)
+{
+	LIST_HEAD(dying_objects);
+
+	_enter("");
+
+	printk(KERN_NOTICE "FS-Cache: Withdrawing cache \"%s\"\n",
+	       cache->tag->name);
+
+	/* make the cache unavailable for cookie acquisition */
+	if (test_and_set_bit(FSCACHE_CACHE_WITHDRAWN, &cache->flags))
+		BUG();
+
+	down_write(&fscache_addremove_sem);
+	list_del_init(&cache->link);
+	cache->tag->cache = NULL;
+	up_write(&fscache_addremove_sem);
+
+	/* make sure all pages pinned by operations on behalf of the netfs are
+	 * written to disk */
+	cache->ops->sync_cache(cache);
+
+	/* dissociate all the netfs pages backed by this cache from the block
+	 * mappings in the cache */
+	cache->ops->dissociate_pages(cache);
+
+	/* we now have to destroy all the active objects pertaining to this
+	 * cache - which we do by passing them off to thread pool to be
+	 * disposed of */
+	_debug("destroy");
+
+	fscache_withdraw_all_objects(cache, &dying_objects);
+
+	/* wait for all extant objects to finish their outstanding operations
+	 * and go away */
+	_debug("wait for finish");
+	wait_event(fscache_cache_cleared_wq,
+		   atomic_read(&cache->object_count) == 0);
+	_debug("wait for clearance");
+	wait_event(fscache_cache_cleared_wq,
+		   list_empty(&cache->object_list));
+	_debug("cleared");
+	ASSERT(list_empty(&dying_objects));
+
+	kobject_put(cache->kobj);
+
+	clear_bit(FSCACHE_TAG_RESERVED, &cache->tag->flags);
+	fscache_release_cache_tag(cache->tag);
+	cache->tag = NULL;
+
+	_leave("");
+}
+EXPORT_SYMBOL(fscache_withdraw_cache);
diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c
new file mode 100644
index 0000000..72fd18f
--- /dev/null
+++ b/fs/fscache/cookie.c
@@ -0,0 +1,500 @@
+/* netfs cookie management
+ *
+ * Copyright (C) 2004-2007 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for more information on
+ * the netfs API.
+ */
+
+#define FSCACHE_DEBUG_LEVEL COOKIE
+#include <linux/module.h>
+#include <linux/slab.h>
+#include "internal.h"
+
+struct kmem_cache *fscache_cookie_jar;
+
+static atomic_t fscache_object_debug_id = ATOMIC_INIT(0);
+
+static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie);
+static int fscache_alloc_object(struct fscache_cache *cache,
+				struct fscache_cookie *cookie);
+static int fscache_attach_object(struct fscache_cookie *cookie,
+				 struct fscache_object *object);
+
+/*
+ * initialise an cookie jar slab element prior to any use
+ */
+void fscache_cookie_init_once(void *_cookie)
+{
+	struct fscache_cookie *cookie = _cookie;
+
+	memset(cookie, 0, sizeof(*cookie));
+	spin_lock_init(&cookie->lock);
+	INIT_HLIST_HEAD(&cookie->backing_objects);
+}
+
+/*
+ * request a cookie to represent an object (index, datafile, xattr, etc)
+ * - parent specifies the parent object
+ *   - the top level index cookie for each netfs is stored in the fscache_netfs
+ *     struct upon registration
+ * - def points to the definition
+ * - the netfs_data will be passed to the functions pointed to in *def
+ * - all attached caches will be searched to see if they contain this object
+ * - index objects aren't stored on disk until there's a dependent file that
+ *   needs storing
+ * - other objects are stored in a selected cache immediately, and all the
+ *   indices forming the path to it are instantiated if necessary
+ * - we never let on to the netfs about errors
+ *   - we may set a negative cookie pointer, but that's okay
+ */
+struct fscache_cookie *__fscache_acquire_cookie(
+	struct fscache_cookie *parent,
+	const struct fscache_cookie_def *def,
+	void *netfs_data)
+{
+	struct fscache_cookie *cookie;
+
+	BUG_ON(!def);
+
+	_enter("{%s},{%s},%p",
+	       parent ? (char *) parent->def->name : "<no-parent>",
+	       def->name, netfs_data);
+
+	fscache_stat(&fscache_n_acquires);
+
+	/* if there's no parent cookie, then we don't create one here either */
+	if (!parent) {
+		fscache_stat(&fscache_n_acquires_null);
+		_leave(" [no parent]");
+		return NULL;
+	}
+
+	/* validate the definition */
+	BUG_ON(!def->get_key);
+	BUG_ON(!def->name[0]);
+
+	BUG_ON(def->type == FSCACHE_COOKIE_TYPE_INDEX &&
+	       parent->def->type != FSCACHE_COOKIE_TYPE_INDEX);
+
+	/* allocate and initialise a cookie */
+	cookie = kmem_cache_alloc(fscache_cookie_jar, GFP_KERNEL);
+	if (!cookie) {
+		fscache_stat(&fscache_n_acquires_oom);
+		_leave(" [ENOMEM]");
+		return NULL;
+	}
+
+	atomic_set(&cookie->usage, 1);
+	atomic_set(&cookie->n_children, 0);
+
+	atomic_inc(&parent->usage);
+	atomic_inc(&parent->n_children);
+
+	cookie->def		= def;
+	cookie->parent		= parent;
+	cookie->netfs_data	= netfs_data;
+	cookie->flags		= 0;
+
+	INIT_RADIX_TREE(&cookie->stores, GFP_NOFS);
+
+	switch (cookie->def->type) {
+	case FSCACHE_COOKIE_TYPE_INDEX:
+		fscache_stat(&fscache_n_cookie_index);
+		break;
+	case FSCACHE_COOKIE_TYPE_DATAFILE:
+		fscache_stat(&fscache_n_cookie_data);
+		break;
+	default:
+		fscache_stat(&fscache_n_cookie_special);
+		break;
+	}
+
+	/* if the object is an index then we need do nothing more here - we
+	 * create indices on disk when we need them as an index may exist in
+	 * multiple caches */
+	if (cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) {
+		if (fscache_acquire_non_index_cookie(cookie) < 0) {
+			atomic_dec(&parent->n_children);
+			__fscache_cookie_put(cookie);
+			fscache_stat(&fscache_n_acquires_nobufs);
+			_leave(" = NULL");
+			return NULL;
+		}
+	}
+
+	fscache_stat(&fscache_n_acquires_ok);
+	_leave(" = %p", cookie);
+	return cookie;
+}
+EXPORT_SYMBOL(__fscache_acquire_cookie);
+
+/*
+ * acquire a non-index cookie
+ * - this must make sure the index chain is instantiated and instantiate the
+ *   object representation too
+ */
+static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie)
+{
+	struct fscache_object *object;
+	struct fscache_cache *cache;
+	uint64_t i_size;
+	int ret;
+
+	_enter("");
+
+	cookie->flags = 1 << FSCACHE_COOKIE_UNAVAILABLE;
+
+	/* now we need to see whether the backing objects for this cookie yet
+	 * exist, if not there'll be nothing to search */
+	down_read(&fscache_addremove_sem);
+
+	if (list_empty(&fscache_cache_list)) {
+		up_read(&fscache_addremove_sem);
+		_leave(" = 0 [no caches]");
+		return 0;
+	}
+
+	/* select a cache in which to store the object */
+	cache = fscache_select_cache_for_object(cookie->parent);
+	if (!cache) {
+		up_read(&fscache_addremove_sem);
+		fscache_stat(&fscache_n_acquires_no_cache);
+		_leave(" = -ENOMEDIUM [no cache]");
+		return -ENOMEDIUM;
+	}
+
+	_debug("cache %s", cache->tag->name);
+
+	cookie->flags =
+		(1 << FSCACHE_COOKIE_LOOKING_UP) |
+		(1 << FSCACHE_COOKIE_CREATING) |
+		(1 << FSCACHE_COOKIE_NO_DATA_YET);
+
+	/* ask the cache to allocate objects for this cookie and its parent
+	 * chain */
+	ret = fscache_alloc_object(cache, cookie);
+	if (ret < 0) {
+		up_read(&fscache_addremove_sem);
+		_leave(" = %d", ret);
+		return ret;
+	}
+
+	/* pass on how big the object we're caching is supposed to be */
+	cookie->def->get_attr(cookie->netfs_data, &i_size);
+
+	spin_lock(&cookie->lock);
+	if (hlist_empty(&cookie->backing_objects)) {
+		spin_unlock(&cookie->lock);
+		goto unavailable;
+	}
+
+	object = hlist_entry(cookie->backing_objects.first,
+			     struct fscache_object, cookie_link);
+
+	fscache_set_store_limit(object, i_size);
+
+	/* initiate the process of looking up all the objects in the chain
+	 * (done by fscache_initialise_object()) */
+	fscache_enqueue_object(object);
+
+	spin_unlock(&cookie->lock);
+
+	/* we may be required to wait for lookup to complete at this point */
+	if (!fscache_defer_lookup) {
+		_debug("non-deferred lookup %p", &cookie->flags);
+		wait_on_bit(&cookie->flags, FSCACHE_COOKIE_LOOKING_UP,
+			    fscache_wait_bit, TASK_UNINTERRUPTIBLE);
+		_debug("complete");
+		if (test_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags))
+			goto unavailable;
+	}
+
+	up_read(&fscache_addremove_sem);
+	_leave(" = 0 [deferred]");
+	return 0;
+
+unavailable:
+	up_read(&fscache_addremove_sem);
+	_leave(" = -ENOBUFS");
+	return -ENOBUFS;
+}
+
+/*
+ * recursively allocate cache object records for a cookie/cache combination
+ * - caller must be holding the addremove sem
+ */
+static int fscache_alloc_object(struct fscache_cache *cache,
+				struct fscache_cookie *cookie)
+{
+	struct fscache_object *object;
+	struct hlist_node *_n;
+	int ret;
+
+	_enter("%p,%p{%s}", cache, cookie, cookie->def->name);
+
+	spin_lock(&cookie->lock);
+	hlist_for_each_entry(object, _n, &cookie->backing_objects,
+			     cookie_link) {
+		if (object->cache == cache)
+			goto object_already_extant;
+	}
+	spin_unlock(&cookie->lock);
+
+	/* ask the cache to allocate an object (we may end up with duplicate
+	 * objects at this stage, but we sort that out later) */
+	object = cache->ops->alloc_object(cache, cookie);
+	if (IS_ERR(object)) {
+		fscache_stat(&fscache_n_object_no_alloc);
+		ret = PTR_ERR(object);
+		goto error;
+	}
+
+	fscache_stat(&fscache_n_object_alloc);
+
+	object->debug_id = atomic_inc_return(&fscache_object_debug_id);
+
+	_debug("ALLOC OBJ%x: %s {%lx}",
+	       object->debug_id, cookie->def->name, object->events);
+
+	ret = fscache_alloc_object(cache, cookie->parent);
+	if (ret < 0)
+		goto error_put;
+
+	/* only attach if we managed to allocate all we needed, otherwise
+	 * discard the object we just allocated and instead use the one
+	 * attached to the cookie */
+	if (fscache_attach_object(cookie, object) < 0)
+		cache->ops->put_object(object);
+
+	_leave(" = 0");
+	return 0;
+
+object_already_extant:
+	ret = -ENOBUFS;
+	if (object->state >= FSCACHE_OBJECT_DYING) {
+		spin_unlock(&cookie->lock);
+		goto error;
+	}
+	spin_unlock(&cookie->lock);
+	_leave(" = 0 [found]");
+	return 0;
+
+error_put:
+	cache->ops->put_object(object);
+error:
+	_leave(" = %d", ret);
+	return ret;
+}
+
+/*
+ * attach a cache object to a cookie
+ */
+static int fscache_attach_object(struct fscache_cookie *cookie,
+				 struct fscache_object *object)
+{
+	struct fscache_object *p;
+	struct fscache_cache *cache = object->cache;
+	struct hlist_node *_n;
+	int ret;
+
+	_enter("{%s},{OBJ%x}", cookie->def->name, object->debug_id);
+
+	spin_lock(&cookie->lock);
+
+	/* there may be multiple initial creations of this object, but we only
+	 * want one */
+	ret = -EEXIST;
+	hlist_for_each_entry(p, _n, &cookie->backing_objects, cookie_link) {
+		if (p->cache == object->cache) {
+			if (p->state >= FSCACHE_OBJECT_DYING)
+				ret = -ENOBUFS;
+			goto cant_attach_object;
+		}
+	}
+
+	/* pin the parent object */
+	spin_lock_nested(&cookie->parent->lock, 1);
+	hlist_for_each_entry(p, _n, &cookie->parent->backing_objects,
+			     cookie_link) {
+		if (p->cache == object->cache) {
+			if (p->state >= FSCACHE_OBJECT_DYING) {
+				ret = -ENOBUFS;
+				spin_unlock(&cookie->parent->lock);
+				goto cant_attach_object;
+			}
+			object->parent = p;
+			spin_lock(&p->lock);
+			p->n_children++;
+			spin_unlock(&p->lock);
+			break;
+		}
+	}
+	spin_unlock(&cookie->parent->lock);
+
+	/* attach to the cache's object list */
+	if (list_empty(&object->cache_link)) {
+		spin_lock(&cache->object_list_lock);
+		list_add(&object->cache_link, &cache->object_list);
+		spin_unlock(&cache->object_list_lock);
+	}
+
+	/* attach to the cookie */
+	object->cookie = cookie;
+	atomic_inc(&cookie->usage);
+	hlist_add_head(&object->cookie_link, &cookie->backing_objects);
+	ret = 0;
+
+cant_attach_object:
+	spin_unlock(&cookie->lock);
+	_leave(" = %d", ret);
+	return ret;
+}
+
+/*
+ * update the index entries backing a cookie
+ */
+void __fscache_update_cookie(struct fscache_cookie *cookie)
+{
+	struct fscache_object *object;
+	struct hlist_node *_p;
+
+	fscache_stat(&fscache_n_updates);
+
+	if (!cookie) {
+		fscache_stat(&fscache_n_updates_null);
+		_leave(" [no cookie]");
+		return;
+	}
+
+	_enter("{%s}", cookie->def->name);
+
+	BUG_ON(!cookie->def->get_aux);
+
+	spin_lock(&cookie->lock);
+
+	/* update the index entry on disk in each cache backing this cookie */
+	hlist_for_each_entry(object, _p,
+			     &cookie->backing_objects, cookie_link) {
+		fscache_raise_event(object, FSCACHE_OBJECT_EV_UPDATE);
+	}
+
+	spin_unlock(&cookie->lock);
+	_leave("");
+}
+EXPORT_SYMBOL(__fscache_update_cookie);
+
+/*
+ * release a cookie back to the cache
+ * - the object will be marked as recyclable on disk if retire is true
+ * - all dependents of this cookie must have already been unregistered
+ *   (indices/files/pages)
+ */
+void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
+{
+	struct fscache_cache *cache;
+	struct fscache_object *object;
+	unsigned long event;
+
+	fscache_stat(&fscache_n_relinquishes);
+
+	if (!cookie) {
+		fscache_stat(&fscache_n_relinquishes_null);
+		_leave(" [no cookie]");
+		return;
+	}
+
+	_enter("%p{%s,%p},%d",
+	       cookie, cookie->def->name, cookie->netfs_data, retire);
+
+	if (atomic_read(&cookie->n_children) != 0) {
+		printk(KERN_ERR "FS-Cache: Cookie '%s' still has children\n",
+		       cookie->def->name);
+		BUG();
+	}
+
+	/* wait for the cookie to finish being instantiated (or to fail) */
+	if (test_bit(FSCACHE_COOKIE_CREATING, &cookie->flags)) {
+		fscache_stat(&fscache_n_relinquishes_waitcrt);
+		wait_on_bit(&cookie->flags, FSCACHE_COOKIE_CREATING,
+			    fscache_wait_bit, TASK_UNINTERRUPTIBLE);
+	}
+
+	event = retire ? FSCACHE_OBJECT_EV_RETIRE : FSCACHE_OBJECT_EV_RELEASE;
+
+	/* detach pointers back to the netfs */
+	spin_lock(&cookie->lock);
+
+	cookie->netfs_data	= NULL;
+	cookie->def		= NULL;
+
+	/* break links with all the active objects */
+	while (!hlist_empty(&cookie->backing_objects)) {
+		object = hlist_entry(cookie->backing_objects.first,
+				     struct fscache_object,
+				     cookie_link);
+
+		_debug("RELEASE OBJ%x", object->debug_id);
+
+		/* detach each cache object from the object cookie */
+		spin_lock(&object->lock);
+		hlist_del_init(&object->cookie_link);
+
+		cache = object->cache;
+		object->cookie = NULL;
+		fscache_raise_event(object, event);
+		spin_unlock(&object->lock);
+
+		if (atomic_dec_and_test(&cookie->usage))
+			/* the cookie refcount shouldn't be reduced to 0 yet */
+			BUG();
+	}
+
+	spin_unlock(&cookie->lock);
+
+	if (cookie->parent) {
+		ASSERTCMP(atomic_read(&cookie->parent->usage), >, 0);
+		ASSERTCMP(atomic_read(&cookie->parent->n_children), >, 0);
+		atomic_dec(&cookie->parent->n_children);
+	}
+
+	/* finally dispose of the cookie */
+	ASSERTCMP(atomic_read(&cookie->usage), >, 0);
+	fscache_cookie_put(cookie);
+
+	_leave("");
+}
+EXPORT_SYMBOL(__fscache_relinquish_cookie);
+
+/*
+ * destroy a cookie
+ */
+void __fscache_cookie_put(struct fscache_cookie *cookie)
+{
+	struct fscache_cookie *parent;
+
+	_enter("%p", cookie);
+
+	for (;;) {
+		_debug("FREE COOKIE %p", cookie);
+		parent = cookie->parent;
+		BUG_ON(!hlist_empty(&cookie->backing_objects));
+		kmem_cache_free(fscache_cookie_jar, cookie);
+
+		if (!parent)
+			break;
+
+		cookie = parent;
+		BUG_ON(atomic_read(&cookie->usage) <= 0);
+		if (!atomic_dec_and_test(&cookie->usage))
+			break;
+	}
+
+	_leave("");
+}
diff --git a/fs/fscache/fsdef.c b/fs/fscache/fsdef.c
new file mode 100644
index 0000000..f5b4bae
--- /dev/null
+++ b/fs/fscache/fsdef.c
@@ -0,0 +1,144 @@
+/* Filesystem index definition
+ *
+ * Copyright (C) 2004-2007 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define FSCACHE_DEBUG_LEVEL CACHE
+#include <linux/module.h>
+#include "internal.h"
+
+static uint16_t fscache_fsdef_netfs_get_key(const void *cookie_netfs_data,
+					    void *buffer, uint16_t bufmax);
+
+static uint16_t fscache_fsdef_netfs_get_aux(const void *cookie_netfs_data,
+					    void *buffer, uint16_t bufmax);
+
+static
+enum fscache_checkaux fscache_fsdef_netfs_check_aux(void *cookie_netfs_data,
+						    const void *data,
+						    uint16_t datalen);
+
+/*
+ * The root index is owned by FS-Cache itself.
+ *
+ * When a netfs requests caching facilities, FS-Cache will, if one doesn't
+ * already exist, create an entry in the root index with the key being the name
+ * of the netfs ("AFS" for example), and the auxiliary data holding the index
+ * structure version supplied by the netfs:
+ *
+ *				     FSDEF
+ *				       |
+ *				 +-----------+
+ *				 |           |
+ *				NFS         AFS
+ *			       [v=1]       [v=1]
+ *
+ * If an entry with the appropriate name does already exist, the version is
+ * compared.  If the version is different, the entire subtree from that entry
+ * will be discarded and a new entry created.
+ *
+ * The new entry will be an index, and a cookie referring to it will be passed
+ * to the netfs.  This is then the root handle by which the netfs accesses the
+ * cache.  It can create whatever objects it likes in that index, including
+ * further indices.
+ */
+static struct fscache_cookie_def fscache_fsdef_index_def = {
+	.name		= ".FS-Cache",
+	.type		= FSCACHE_COOKIE_TYPE_INDEX,
+};
+
+struct fscache_cookie fscache_fsdef_index = {
+	.usage		= ATOMIC_INIT(1),
+	.lock		= __SPIN_LOCK_UNLOCKED(fscache_fsdef_index.lock),
+	.backing_objects = HLIST_HEAD_INIT,
+	.def		= &fscache_fsdef_index_def,
+};
+EXPORT_SYMBOL(fscache_fsdef_index);
+
+/*
+ * Definition of an entry in the root index.  Each entry is an index, keyed to
+ * a specific netfs and only applicable to a particular version of the index
+ * structure used by that netfs.
+ */
+struct fscache_cookie_def fscache_fsdef_netfs_def = {
+	.name		= "FSDEF.netfs",
+	.type		= FSCACHE_COOKIE_TYPE_INDEX,
+	.get_key	= fscache_fsdef_netfs_get_key,
+	.get_aux	= fscache_fsdef_netfs_get_aux,
+	.check_aux	= fscache_fsdef_netfs_check_aux,
+};
+
+/*
+ * get the key data for an FSDEF index record - this is the name of the netfs
+ * for which this entry is created
+ */
+static uint16_t fscache_fsdef_netfs_get_key(const void *cookie_netfs_data,
+					    void *buffer, uint16_t bufmax)
+{
+	const struct fscache_netfs *netfs = cookie_netfs_data;
+	unsigned klen;
+
+	_enter("{%s.%u},", netfs->name, netfs->version);
+
+	klen = strlen(netfs->name);
+	if (klen > bufmax)
+		return 0;
+
+	memcpy(buffer, netfs->name, klen);
+	return klen;
+}
+
+/*
+ * get the auxiliary data for an FSDEF index record - this is the index
+ * structure version number of the netfs for which this version is created
+ */
+static uint16_t fscache_fsdef_netfs_get_aux(const void *cookie_netfs_data,
+					    void *buffer, uint16_t bufmax)
+{
+	const struct fscache_netfs *netfs = cookie_netfs_data;
+	unsigned dlen;
+
+	_enter("{%s.%u},", netfs->name, netfs->version);
+
+	dlen = sizeof(uint32_t);
+	if (dlen > bufmax)
+		return 0;
+
+	memcpy(buffer, &netfs->version, dlen);
+	return dlen;
+}
+
+/*
+ * check that the index structure version number stored in the auxiliary data
+ * matches the one the netfs gave us
+ */
+static enum fscache_checkaux fscache_fsdef_netfs_check_aux(
+	void *cookie_netfs_data,
+	const void *data,
+	uint16_t datalen)
+{
+	struct fscache_netfs *netfs = cookie_netfs_data;
+	uint32_t version;
+
+	_enter("{%s},,%hu", netfs->name, datalen);
+
+	if (datalen != sizeof(version)) {
+		_leave(" = OBSOLETE [dl=%d v=%zu]", datalen, sizeof(version));
+		return FSCACHE_CHECKAUX_OBSOLETE;
+	}
+
+	memcpy(&version, data, sizeof(version));
+	if (version != netfs->version) {
+		_leave(" = OBSOLETE [ver=%x net=%x]", version, netfs->version);
+		return FSCACHE_CHECKAUX_OBSOLETE;
+	}
+
+	_leave(" = OKAY");
+	return FSCACHE_CHECKAUX_OKAY;
+}
diff --git a/fs/fscache/histogram.c b/fs/fscache/histogram.c
new file mode 100644
index 0000000..bad4967
--- /dev/null
+++ b/fs/fscache/histogram.c
@@ -0,0 +1,109 @@
+/* FS-Cache latency histogram
+ *
+ * Copyright (C) 2008 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 FSCACHE_DEBUG_LEVEL THREAD
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include "internal.h"
+
+atomic_t fscache_obj_instantiate_histogram[HZ];
+atomic_t fscache_objs_histogram[HZ];
+atomic_t fscache_ops_histogram[HZ];
+atomic_t fscache_retrieval_delay_histogram[HZ];
+atomic_t fscache_retrieval_histogram[HZ];
+
+/*
+ * display the time-taken histogram
+ */
+static int fscache_histogram_show(struct seq_file *m, void *v)
+{
+	unsigned long index;
+	unsigned n[5], t;
+
+	switch ((unsigned long) v) {
+	case 1:
+		seq_puts(m, "JIFS  SECS  OBJ INST  OP RUNS   OBJ RUNS "
+			 " RETRV DLY RETRIEVLS\n");
+		return 0;
+	case 2:
+		seq_puts(m, "===== ===== ========= ========= ========="
+			 " ========= =========\n");
+		return 0;
+	default:
+		index = (unsigned long) v - 3;
+		n[0] = atomic_read(&fscache_obj_instantiate_histogram[index]);
+		n[1] = atomic_read(&fscache_ops_histogram[index]);
+		n[2] = atomic_read(&fscache_objs_histogram[index]);
+		n[3] = atomic_read(&fscache_retrieval_delay_histogram[index]);
+		n[4] = atomic_read(&fscache_retrieval_histogram[index]);
+		if (!(n[0] | n[1] | n[2] | n[3] | n[4]))
+			return 0;
+
+		t = (index * 1000) / HZ;
+
+		seq_printf(m, "%4lu  0.%03u %9u %9u %9u %9u %9u\n",
+			   index, t, n[0], n[1], n[2], n[3], n[4]);
+		return 0;
+	}
+}
+
+/*
+ * set up the iterator to start reading from the first line
+ */
+static void *fscache_histogram_start(struct seq_file *m, loff_t *_pos)
+{
+	if ((unsigned long long)*_pos >= HZ + 2)
+		return NULL;
+	if (*_pos == 0)
+		*_pos = 1;
+	return (void *)(unsigned long) *_pos;
+}
+
+/*
+ * move to the next line
+ */
+static void *fscache_histogram_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	(*pos)++;
+	return (unsigned long long)*pos > HZ + 2 ?
+		NULL : (void *)(unsigned long) *pos;
+}
+
+/*
+ * clean up after reading
+ */
+static void fscache_histogram_stop(struct seq_file *m, void *v)
+{
+}
+
+static const struct seq_operations fscache_histogram_ops = {
+	.start		= fscache_histogram_start,
+	.stop		= fscache_histogram_stop,
+	.next		= fscache_histogram_next,
+	.show		= fscache_histogram_show,
+};
+
+/*
+ * open "/proc/fs/fscache/histogram" to provide latency data
+ */
+static int fscache_histogram_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &fscache_histogram_ops);
+}
+
+const struct file_operations fscache_histogram_fops = {
+	.owner		= THIS_MODULE,
+	.open		= fscache_histogram_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release,
+};
diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h
new file mode 100644
index 0000000..e0cbd16
--- /dev/null
+++ b/fs/fscache/internal.h
@@ -0,0 +1,380 @@
+/* Internal definitions for FS-Cache
+ *
+ * Copyright (C) 2004-2007 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/*
+ * Lock order, in the order in which multiple locks should be obtained:
+ * - fscache_addremove_sem
+ * - cookie->lock
+ * - cookie->parent->lock
+ * - cache->object_list_lock
+ * - object->lock
+ * - object->parent->lock
+ * - fscache_thread_lock
+ *
+ */
+
+#include <linux/fscache-cache.h>
+#include <linux/sched.h>
+
+#define FSCACHE_MIN_THREADS	4
+#define FSCACHE_MAX_THREADS	32
+
+/*
+ * fsc-cache.c
+ */
+extern struct list_head fscache_cache_list;
+extern struct rw_semaphore fscache_addremove_sem;
+
+extern struct fscache_cache *fscache_select_cache_for_object(
+	struct fscache_cookie *);
+
+/*
+ * fsc-cookie.c
+ */
+extern struct kmem_cache *fscache_cookie_jar;
+
+extern void fscache_cookie_init_once(void *);
+extern void __fscache_cookie_put(struct fscache_cookie *);
+
+/*
+ * fsc-fsdef.c
+ */
+extern struct fscache_cookie fscache_fsdef_index;
+extern struct fscache_cookie_def fscache_fsdef_netfs_def;
+
+/*
+ * fsc-histogram.c
+ */
+#ifdef CONFIG_FSCACHE_HISTOGRAM
+extern atomic_t fscache_obj_instantiate_histogram[HZ];
+extern atomic_t fscache_objs_histogram[HZ];
+extern atomic_t fscache_ops_histogram[HZ];
+extern atomic_t fscache_retrieval_delay_histogram[HZ];
+extern atomic_t fscache_retrieval_histogram[HZ];
+
+static inline void fscache_hist(atomic_t histogram[], unsigned long start_jif)
+{
+	unsigned long jif = jiffies - start_jif;
+	if (jif >= HZ)
+		jif = HZ - 1;
+	atomic_inc(&histogram[jif]);
+}
+
+extern const struct file_operations fscache_histogram_fops;
+
+#else
+#define fscache_hist(hist, start_jif) do {} while (0)
+#endif
+
+/*
+ * fsc-main.c
+ */
+extern unsigned fscache_defer_lookup;
+extern unsigned fscache_defer_create;
+extern unsigned fscache_debug;
+extern struct kobject *fscache_root;
+
+extern int fscache_wait_bit(void *);
+extern int fscache_wait_bit_interruptible(void *);
+
+/*
+ * fsc-object.c
+ */
+extern void fscache_withdrawing_object(struct fscache_cache *,
+				       struct fscache_object *);
+extern void fscache_enqueue_object(struct fscache_object *);
+
+/*
+ * fsc-operation.c
+ */
+extern int fscache_submit_exclusive_op(struct fscache_object *,
+				       struct fscache_operation *);
+extern int fscache_submit_op(struct fscache_object *,
+			     struct fscache_operation *);
+extern void fscache_abort_object(struct fscache_object *);
+extern void fscache_start_operations(struct fscache_object *);
+extern void fscache_operation_gc(struct work_struct *);
+
+/*
+ * fsc-proc.c
+ */
+#ifdef CONFIG_PROC_FS
+extern int __init fscache_proc_init(void);
+extern void fscache_proc_cleanup(void);
+#else
+#define fscache_proc_init()	(0)
+#define fscache_proc_cleanup()	do {} while (0)
+#endif
+
+/*
+ * fsc-stats.c
+ */
+#ifdef CONFIG_FSCACHE_STATS
+extern atomic_t fscache_n_ops_processed[FSCACHE_MAX_THREADS];
+extern atomic_t fscache_n_objs_processed[FSCACHE_MAX_THREADS];
+
+extern atomic_t fscache_n_op_pend;
+extern atomic_t fscache_n_op_run;
+extern atomic_t fscache_n_op_enqueue;
+extern atomic_t fscache_n_op_deferred_release;
+extern atomic_t fscache_n_op_release;
+extern atomic_t fscache_n_op_gc;
+
+extern atomic_t fscache_n_attr_changed;
+extern atomic_t fscache_n_attr_changed_ok;
+extern atomic_t fscache_n_attr_changed_nobufs;
+extern atomic_t fscache_n_attr_changed_nomem;
+extern atomic_t fscache_n_attr_changed_calls;
+
+extern atomic_t fscache_n_allocs;
+extern atomic_t fscache_n_allocs_ok;
+extern atomic_t fscache_n_allocs_wait;
+extern atomic_t fscache_n_allocs_nobufs;
+extern atomic_t fscache_n_alloc_ops;
+extern atomic_t fscache_n_alloc_op_waits;
+
+extern atomic_t fscache_n_retrievals;
+extern atomic_t fscache_n_retrievals_ok;
+extern atomic_t fscache_n_retrievals_wait;
+extern atomic_t fscache_n_retrievals_nodata;
+extern atomic_t fscache_n_retrievals_nobufs;
+extern atomic_t fscache_n_retrievals_intr;
+extern atomic_t fscache_n_retrievals_nomem;
+extern atomic_t fscache_n_retrieval_ops;
+extern atomic_t fscache_n_retrieval_op_waits;
+
+extern atomic_t fscache_n_stores;
+extern atomic_t fscache_n_stores_ok;
+extern atomic_t fscache_n_stores_again;
+extern atomic_t fscache_n_stores_nobufs;
+extern atomic_t fscache_n_stores_oom;
+extern atomic_t fscache_n_store_ops;
+extern atomic_t fscache_n_store_calls;
+
+extern atomic_t fscache_n_marks;
+extern atomic_t fscache_n_uncaches;
+
+extern atomic_t fscache_n_acquires;
+extern atomic_t fscache_n_acquires_null;
+extern atomic_t fscache_n_acquires_no_cache;
+extern atomic_t fscache_n_acquires_ok;
+extern atomic_t fscache_n_acquires_nobufs;
+extern atomic_t fscache_n_acquires_oom;
+
+extern atomic_t fscache_n_updates;
+extern atomic_t fscache_n_updates_null;
+extern atomic_t fscache_n_updates_run;
+
+extern atomic_t fscache_n_relinquishes;
+extern atomic_t fscache_n_relinquishes_null;
+extern atomic_t fscache_n_relinquishes_waitcrt;
+
+extern atomic_t fscache_n_cookie_index;
+extern atomic_t fscache_n_cookie_data;
+extern atomic_t fscache_n_cookie_special;
+
+extern atomic_t fscache_n_object_alloc;
+extern atomic_t fscache_n_object_no_alloc;
+extern atomic_t fscache_n_object_lookups;
+extern atomic_t fscache_n_object_lookups_negative;
+extern atomic_t fscache_n_object_lookups_positive;
+extern atomic_t fscache_n_object_created;
+extern atomic_t fscache_n_object_avail;
+extern atomic_t fscache_n_object_dead;
+
+extern atomic_t fscache_n_checkaux_none;
+extern atomic_t fscache_n_checkaux_okay;
+extern atomic_t fscache_n_checkaux_update;
+extern atomic_t fscache_n_checkaux_obsolete;
+
+static inline void fscache_stat(atomic_t *stat)
+{
+	atomic_inc(stat);
+}
+
+extern const struct file_operations fscache_stats_fops;
+#else
+
+#define fscache_stat(stat) do {} while (0)
+#endif
+
+/*
+ * raise an event on an object
+ * - if the event is not masked for that object, then the object is
+ *   queued for attention by the thread pool.
+ */
+static inline void fscache_raise_event(struct fscache_object *object,
+				       unsigned event)
+{
+	if (!test_and_set_bit(event, &object->events) &&
+	    test_bit(event, &object->event_mask))
+		fscache_enqueue_object(object);
+}
+
+/*
+ * drop a reference to a cookie
+ */
+static inline void fscache_cookie_put(struct fscache_cookie *cookie)
+{
+	BUG_ON(atomic_read(&cookie->usage) <= 0);
+	if (atomic_dec_and_test(&cookie->usage))
+		__fscache_cookie_put(cookie);
+}
+
+/*
+ * get an extra reference to a netfs retrieval context
+ */
+static inline
+void *fscache_get_context(struct fscache_cookie *cookie, void *context)
+{
+	if (cookie->def->get_context)
+		cookie->def->get_context(cookie->netfs_data, context);
+	return context;
+}
+
+/*
+ * release a reference to a netfs retrieval context
+ */
+static inline
+void fscache_put_context(struct fscache_cookie *cookie, void *context)
+{
+	if (cookie->def->put_context)
+		cookie->def->put_context(cookie->netfs_data, context);
+}
+
+/*****************************************************************************/
+/*
+ * debug tracing
+ */
+#define dbgprintk(FMT, ...) \
+	printk(KERN_DEBUG "[%-6.6s] "FMT"\n", current->comm, ##__VA_ARGS__)
+
+/* make sure we maintain the format strings, even when debugging is disabled */
+static inline __attribute__((format(printf, 1, 2)))
+void _dbprintk(const char *fmt, ...)
+{
+}
+
+#define kenter(FMT, ...) dbgprintk("==> %s("FMT")", __func__, ##__VA_ARGS__)
+#define kleave(FMT, ...) dbgprintk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
+#define kdebug(FMT, ...) dbgprintk(FMT, ##__VA_ARGS__)
+
+#define kjournal(FMT, ...) _dbprintk(FMT, ##__VA_ARGS__)
+
+#ifdef __KDEBUG
+#define _enter(FMT, ...) kenter(FMT, ##__VA_ARGS__)
+#define _leave(FMT, ...) kleave(FMT, ##__VA_ARGS__)
+#define _debug(FMT, ...) kdebug(FMT, ##__VA_ARGS__)
+
+#elif defined(CONFIG_FSCACHE_DEBUG)
+#define _enter(FMT, ...)			\
+do {						\
+	if (__do_kdebug(ENTER))			\
+		kenter(FMT, ##__VA_ARGS__);	\
+} while (0)
+
+#define _leave(FMT, ...)			\
+do {						\
+	if (__do_kdebug(LEAVE))			\
+		kleave(FMT, ##__VA_ARGS__);	\
+} while (0)
+
+#define _debug(FMT, ...)			\
+do {						\
+	if (__do_kdebug(DEBUG))			\
+		kdebug(FMT, ##__VA_ARGS__);	\
+} while (0)
+
+#else
+#define _enter(FMT, ...) _dbprintk("==> %s("FMT")", __func__, ##__VA_ARGS__)
+#define _leave(FMT, ...) _dbprintk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
+#define _debug(FMT, ...) _dbprintk(FMT, ##__VA_ARGS__)
+#endif
+
+/*
+ * determine whether a particular optional debugging point should be logged
+ * - we need to go through three steps to persuade cpp to correctly join the
+ *   shorthand in FSCACHE_DEBUG_LEVEL with its prefix
+ */
+#define ____do_kdebug(LEVEL, POINT) \
+	unlikely((fscache_debug & \
+		  (FSCACHE_POINT_##POINT << (FSCACHE_DEBUG_ ## LEVEL * 3))))
+#define ___do_kdebug(LEVEL, POINT) \
+	____do_kdebug(LEVEL, POINT)
+#define __do_kdebug(POINT) \
+	___do_kdebug(FSCACHE_DEBUG_LEVEL, POINT)
+
+#define FSCACHE_DEBUG_CACHE	0
+#define FSCACHE_DEBUG_COOKIE	1
+#define FSCACHE_DEBUG_PAGE	2
+#define FSCACHE_DEBUG_OPERATION	3
+
+#define FSCACHE_POINT_ENTER	1
+#define FSCACHE_POINT_LEAVE	2
+#define FSCACHE_POINT_DEBUG	4
+
+#ifndef FSCACHE_DEBUG_LEVEL
+#define FSCACHE_DEBUG_LEVEL CACHE
+#endif
+
+/*
+ * assertions
+ */
+#if 1 /* defined(__KDEBUGALL) */
+
+#define ASSERT(X)							\
+do {									\
+	if (unlikely(!(X))) {						\
+		printk(KERN_ERR "\n");					\
+		printk(KERN_ERR "FS-Cache: Assertion failed\n");	\
+		BUG();							\
+	}								\
+} while (0)
+
+#define ASSERTCMP(X, OP, Y)						\
+do {									\
+	if (unlikely(!((X) OP (Y)))) {					\
+		printk(KERN_ERR "\n");					\
+		printk(KERN_ERR "FS-Cache: Assertion failed\n");	\
+		printk(KERN_ERR "%lx " #OP " %lx is false\n",		\
+		       (unsigned long)(X), (unsigned long)(Y));		\
+		BUG();							\
+	}								\
+} while (0)
+
+#define ASSERTIF(C, X)							\
+do {									\
+	if (unlikely((C) && !(X))) {					\
+		printk(KERN_ERR "\n");					\
+		printk(KERN_ERR "FS-Cache: Assertion failed\n");	\
+		BUG();							\
+	}								\
+} while (0)
+
+#define ASSERTIFCMP(C, X, OP, Y)					\
+do {									\
+	if (unlikely((C) && !((X) OP (Y)))) {				\
+		printk(KERN_ERR "\n");					\
+		printk(KERN_ERR "FS-Cache: Assertion failed\n");	\
+		printk(KERN_ERR "%lx " #OP " %lx is false\n",		\
+		       (unsigned long)(X), (unsigned long)(Y));		\
+		BUG();							\
+	}								\
+} while (0)
+
+#else
+
+#define ASSERT(X)			do {} while (0)
+#define ASSERTCMP(X, OP, Y)		do {} while (0)
+#define ASSERTIF(C, X)			do {} while (0)
+#define ASSERTIFCMP(C, X, OP, Y)	do {} while (0)
+
+#endif /* assert or not */
diff --git a/fs/fscache/main.c b/fs/fscache/main.c
new file mode 100644
index 0000000..4de41b5
--- /dev/null
+++ b/fs/fscache/main.c
@@ -0,0 +1,124 @@
+/* General filesystem local caching manager
+ *
+ * Copyright (C) 2004-2007 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define FSCACHE_DEBUG_LEVEL CACHE
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/completion.h>
+#include <linux/slab.h>
+#include "internal.h"
+
+MODULE_DESCRIPTION("FS Cache Manager");
+MODULE_AUTHOR("Red Hat, Inc.");
+MODULE_LICENSE("GPL");
+
+unsigned fscache_defer_lookup = 1;
+module_param_named(defer_lookup, fscache_defer_lookup, uint,
+		   S_IWUSR | S_IRUGO);
+MODULE_PARM_DESC(fscache_defer_lookup,
+		 "Defer cookie lookup to background thread");
+
+unsigned fscache_defer_create = 1;
+module_param_named(defer_create, fscache_defer_create, uint,
+		   S_IWUSR | S_IRUGO);
+MODULE_PARM_DESC(fscache_defer_create,
+		 "Defer cookie creation to background thread");
+
+unsigned fscache_debug;
+module_param_named(debug, fscache_debug, uint,
+		   S_IWUSR | S_IRUGO);
+MODULE_PARM_DESC(fscache_debug,
+		 "FS-Cache debugging mask");
+
+struct kobject *fscache_root;
+
+/*
+ * initialise the fs caching module
+ */
+static int __init fscache_init(void)
+{
+	int ret;
+
+	ret = slow_work_register_user();
+	if (ret < 0)
+		goto error_slow_work;
+
+	ret = fscache_proc_init();
+	if (ret < 0)
+		goto error_proc;
+
+	fscache_cookie_jar = kmem_cache_create("fscache_cookie_jar",
+					       sizeof(struct fscache_cookie),
+					       0,
+					       0,
+					       fscache_cookie_init_once);
+	if (!fscache_cookie_jar) {
+		printk(KERN_NOTICE
+		       "FS-Cache: Failed to allocate a cookie jar\n");
+		ret = -ENOMEM;
+		goto error_cookie_jar;
+	}
+
+	fscache_root = kobject_create_and_add("fscache", kernel_kobj);
+	if (!fscache_root)
+		goto error_kobj;
+
+	printk(KERN_NOTICE "FS-Cache: Loaded\n");
+	return 0;
+
+error_kobj:
+	kmem_cache_destroy(fscache_cookie_jar);
+error_cookie_jar:
+	fscache_proc_cleanup();
+error_proc:
+	slow_work_unregister_user();
+error_slow_work:
+	return ret;
+}
+
+fs_initcall(fscache_init);
+
+/*
+ * clean up on module removal
+ */
+static void __exit fscache_exit(void)
+{
+	_enter("");
+
+	kobject_put(fscache_root);
+	kmem_cache_destroy(fscache_cookie_jar);
+	fscache_proc_cleanup();
+	slow_work_unregister_user();
+	printk(KERN_NOTICE "FS-Cache: Unloaded\n");
+}
+
+module_exit(fscache_exit);
+
+/*
+ * wait_on_bit() sleep function for uninterruptible waiting
+ */
+int fscache_wait_bit(void *flags)
+{
+	schedule();
+	return 0;
+}
+EXPORT_SYMBOL(fscache_wait_bit);
+
+/*
+ * wait_on_bit() sleep function for interruptible waiting
+ */
+int fscache_wait_bit_interruptible(void *flags)
+{
+	schedule();
+	return signal_pending(current);
+}
+EXPORT_SYMBOL(fscache_wait_bit_interruptible);
diff --git a/fs/fscache/netfs.c b/fs/fscache/netfs.c
new file mode 100644
index 0000000..e028b8e
--- /dev/null
+++ b/fs/fscache/netfs.c
@@ -0,0 +1,103 @@
+/* FS-Cache netfs (client) registration
+ *
+ * Copyright (C) 2008 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 FSCACHE_DEBUG_LEVEL COOKIE
+#include <linux/module.h>
+#include <linux/slab.h>
+#include "internal.h"
+
+static LIST_HEAD(fscache_netfs_list);
+
+/*
+ * register a network filesystem for caching
+ */
+int __fscache_register_netfs(struct fscache_netfs *netfs)
+{
+	struct fscache_netfs *ptr;
+	int ret;
+
+	_enter("{%s}", netfs->name);
+
+	INIT_LIST_HEAD(&netfs->link);
+
+	/* allocate a cookie for the primary index */
+	netfs->primary_index =
+		kmem_cache_zalloc(fscache_cookie_jar, GFP_KERNEL);
+
+	if (!netfs->primary_index) {
+		_leave(" = -ENOMEM");
+		return -ENOMEM;
+	}
+
+	/* initialise the primary index cookie */
+	atomic_set(&netfs->primary_index->usage, 1);
+	atomic_set(&netfs->primary_index->n_children, 0);
+
+	netfs->primary_index->def		= &fscache_fsdef_netfs_def;
+	netfs->primary_index->parent		= &fscache_fsdef_index;
+	netfs->primary_index->netfs_data	= netfs;
+
+	atomic_inc(&netfs->primary_index->parent->usage);
+	atomic_inc(&netfs->primary_index->parent->n_children);
+
+	spin_lock_init(&netfs->primary_index->lock);
+	INIT_HLIST_HEAD(&netfs->primary_index->backing_objects);
+
+	/* check the netfs type is not already present */
+	down_write(&fscache_addremove_sem);
+
+	ret = -EEXIST;
+	list_for_each_entry(ptr, &fscache_netfs_list, link) {
+		if (strcmp(ptr->name, netfs->name) == 0)
+			goto already_registered;
+	}
+
+	list_add(&netfs->link, &fscache_netfs_list);
+	ret = 0;
+
+	printk(KERN_NOTICE "FS-Cache: Netfs '%s' registered for caching\n",
+	       netfs->name);
+
+already_registered:
+	up_write(&fscache_addremove_sem);
+
+	if (ret < 0) {
+		netfs->primary_index->parent = NULL;
+		__fscache_cookie_put(netfs->primary_index);
+		netfs->primary_index = NULL;
+	}
+
+	_leave(" = %d", ret);
+	return ret;
+}
+EXPORT_SYMBOL(__fscache_register_netfs);
+
+/*
+ * unregister a network filesystem from the cache
+ * - all cookies must have been released first
+ */
+void __fscache_unregister_netfs(struct fscache_netfs *netfs)
+{
+	_enter("{%s.%u}", netfs->name, netfs->version);
+
+	down_write(&fscache_addremove_sem);
+
+	list_del(&netfs->link);
+	fscache_relinquish_cookie(netfs->primary_index, 0);
+
+	up_write(&fscache_addremove_sem);
+
+	printk(KERN_NOTICE "FS-Cache: Netfs '%s' unregistered from caching\n",
+	       netfs->name);
+
+	_leave("");
+}
+EXPORT_SYMBOL(__fscache_unregister_netfs);
diff --git a/fs/fscache/object.c b/fs/fscache/object.c
new file mode 100644
index 0000000..392a41b
--- /dev/null
+++ b/fs/fscache/object.c
@@ -0,0 +1,810 @@
+/* FS-Cache object state machine handler
+ *
+ * Copyright (C) 2007 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * See Documentation/filesystems/caching/object.txt for a description of the
+ * object state machine and the in-kernel representations.
+ */
+
+#define FSCACHE_DEBUG_LEVEL COOKIE
+#include <linux/module.h>
+#include "internal.h"
+
+const char *fscache_object_states[] = {
+	[FSCACHE_OBJECT_INIT]		= "OBJECT_INIT",
+	[FSCACHE_OBJECT_LOOKING_UP]	= "OBJECT_LOOKING_UP",
+	[FSCACHE_OBJECT_CREATING]	= "OBJECT_CREATING",
+	[FSCACHE_OBJECT_AVAILABLE]	= "OBJECT_AVAILABLE",
+	[FSCACHE_OBJECT_ACTIVE]		= "OBJECT_ACTIVE",
+	[FSCACHE_OBJECT_UPDATING]	= "OBJECT_UPDATING",
+	[FSCACHE_OBJECT_DYING]		= "OBJECT_DYING",
+	[FSCACHE_OBJECT_LC_DYING]	= "OBJECT_LC_DYING",
+	[FSCACHE_OBJECT_ABORT_INIT]	= "OBJECT_ABORT_INIT",
+	[FSCACHE_OBJECT_RELEASING]	= "OBJECT_RELEASING",
+	[FSCACHE_OBJECT_RECYCLING]	= "OBJECT_RECYCLING",
+	[FSCACHE_OBJECT_WITHDRAWING]	= "OBJECT_WITHDRAWING",
+	[FSCACHE_OBJECT_DEAD]		= "OBJECT_DEAD",
+};
+EXPORT_SYMBOL(fscache_object_states);
+
+static void fscache_object_slow_work_put_ref(struct slow_work *);
+static int  fscache_object_slow_work_get_ref(struct slow_work *);
+static void fscache_object_slow_work_execute(struct slow_work *);
+static void fscache_initialise_object(struct fscache_object *);
+static void fscache_lookup_object(struct fscache_object *);
+static void fscache_object_available(struct fscache_object *);
+static void fscache_release_object(struct fscache_object *);
+static void fscache_withdraw_object(struct fscache_object *);
+static void fscache_enqueue_dependents(struct fscache_object *);
+static void fscache_dequeue_object(struct fscache_object *);
+
+const struct slow_work_ops fscache_object_slow_work_ops = {
+	.get_ref	= fscache_object_slow_work_get_ref,
+	.put_ref	= fscache_object_slow_work_put_ref,
+	.execute	= fscache_object_slow_work_execute,
+};
+EXPORT_SYMBOL(fscache_object_slow_work_ops);
+
+/*
+ * we need to notify the parent when an op completes that we had outstanding
+ * upon it
+ */
+static inline void fscache_done_parent_op(struct fscache_object *object)
+{
+	struct fscache_object *parent = object->parent;
+
+	_enter("OBJ%x {OBJ%x,%x}",
+	       object->debug_id, parent->debug_id, parent->n_ops);
+
+	spin_lock_nested(&parent->lock, 1);
+	parent->n_ops--;
+	parent->n_obj_ops--;
+	if (parent->n_ops == 0)
+		fscache_raise_event(parent, FSCACHE_OBJECT_EV_CLEARED);
+	spin_unlock(&parent->lock);
+}
+
+/*
+ * process events that have been sent to an object's state machine
+ * - initiates parent lookup
+ * - does object lookup
+ * - does object creation
+ * - does object recycling and retirement
+ * - does object withdrawal
+ */
+static void fscache_object_state_machine(struct fscache_object *object)
+{
+	enum fscache_object_state new_state;
+
+	ASSERT(object != NULL);
+
+	_enter("{OBJ%x,%s,%lx}",
+	       object->debug_id, fscache_object_states[object->state],
+	       object->events);
+
+	switch (object->state) {
+		/* wait for the parent object to become ready */
+	case FSCACHE_OBJECT_INIT:
+		object->event_mask =
+			ULONG_MAX & ~(1 << FSCACHE_OBJECT_EV_CLEARED);
+		fscache_initialise_object(object);
+		goto done;
+
+		/* look up the object metadata on disk */
+	case FSCACHE_OBJECT_LOOKING_UP:
+		fscache_lookup_object(object);
+		goto lookup_transit;
+
+		/* create the object metadata on disk */
+	case FSCACHE_OBJECT_CREATING:
+		fscache_lookup_object(object);
+		goto lookup_transit;
+
+		/* handle an object becoming available; start pending
+		 * operations and queue dependent operations for processing */
+	case FSCACHE_OBJECT_AVAILABLE:
+		fscache_object_available(object);
+		goto active_transit;
+
+		/* normal running state */
+	case FSCACHE_OBJECT_ACTIVE:
+		goto active_transit;
+
+		/* update the object metadata on disk */
+	case FSCACHE_OBJECT_UPDATING:
+		clear_bit(FSCACHE_OBJECT_EV_UPDATE, &object->events);
+		fscache_stat(&fscache_n_updates_run);
+		object->cache->ops->update_object(object);
+		goto active_transit;
+
+		/* handle an object dying during lookup or creation */
+	case FSCACHE_OBJECT_LC_DYING:
+		object->event_mask &= ~(1 << FSCACHE_OBJECT_EV_UPDATE);
+		object->cache->ops->lookup_complete(object);
+
+		spin_lock(&object->lock);
+		object->state = FSCACHE_OBJECT_DYING;
+		if (test_and_clear_bit(FSCACHE_COOKIE_CREATING,
+				       &object->cookie->flags))
+			wake_up_bit(&object->cookie->flags,
+				    FSCACHE_COOKIE_CREATING);
+		spin_unlock(&object->lock);
+
+		fscache_done_parent_op(object);
+
+		/* wait for completion of all active operations on this object
+		 * and the death of all child objects of this object */
+	case FSCACHE_OBJECT_DYING:
+	dying:
+		clear_bit(FSCACHE_OBJECT_EV_CLEARED, &object->events);
+		spin_lock(&object->lock);
+		_debug("dying OBJ%x {%d,%d}",
+		       object->debug_id, object->n_ops, object->n_children);
+		if (object->n_ops == 0 && object->n_children == 0) {
+			object->event_mask &=
+				~(1 << FSCACHE_OBJECT_EV_CLEARED);
+			object->event_mask |=
+				(1 << FSCACHE_OBJECT_EV_WITHDRAW) |
+				(1 << FSCACHE_OBJECT_EV_RETIRE) |
+				(1 << FSCACHE_OBJECT_EV_RELEASE) |
+				(1 << FSCACHE_OBJECT_EV_ERROR);
+		} else {
+			object->event_mask &=
+				~((1 << FSCACHE_OBJECT_EV_WITHDRAW) |
+				  (1 << FSCACHE_OBJECT_EV_RETIRE) |
+				  (1 << FSCACHE_OBJECT_EV_RELEASE) |
+				  (1 << FSCACHE_OBJECT_EV_ERROR));
+			object->event_mask |=
+				1 << FSCACHE_OBJECT_EV_CLEARED;
+		}
+		spin_unlock(&object->lock);
+		fscache_enqueue_dependents(object);
+		goto terminal_transit;
+
+		/* handle an abort during initialisation */
+	case FSCACHE_OBJECT_ABORT_INIT:
+		_debug("handle abort init %lx", object->events);
+		object->event_mask &= ~(1 << FSCACHE_OBJECT_EV_UPDATE);
+
+		spin_lock(&object->lock);
+		fscache_dequeue_object(object);
+
+		object->state = FSCACHE_OBJECT_DYING;
+		if (test_and_clear_bit(FSCACHE_COOKIE_CREATING,
+				       &object->cookie->flags))
+			wake_up_bit(&object->cookie->flags,
+				    FSCACHE_COOKIE_CREATING);
+		spin_unlock(&object->lock);
+		goto dying;
+
+		/* handle the netfs releasing an object and possibly marking it
+		 * obsolete too */
+	case FSCACHE_OBJECT_RELEASING:
+	case FSCACHE_OBJECT_RECYCLING:
+		object->event_mask &=
+			~((1 << FSCACHE_OBJECT_EV_WITHDRAW) |
+			  (1 << FSCACHE_OBJECT_EV_RETIRE) |
+			  (1 << FSCACHE_OBJECT_EV_RELEASE) |
+			  (1 << FSCACHE_OBJECT_EV_ERROR));
+		fscache_release_object(object);
+		spin_lock(&object->lock);
+		object->state = FSCACHE_OBJECT_DEAD;
+		spin_unlock(&object->lock);
+		fscache_stat(&fscache_n_object_dead);
+		goto terminal_transit;
+
+		/* handle the parent cache of this object being withdrawn from
+		 * active service */
+	case FSCACHE_OBJECT_WITHDRAWING:
+		object->event_mask &=
+			~((1 << FSCACHE_OBJECT_EV_WITHDRAW) |
+			  (1 << FSCACHE_OBJECT_EV_RETIRE) |
+			  (1 << FSCACHE_OBJECT_EV_RELEASE) |
+			  (1 << FSCACHE_OBJECT_EV_ERROR));
+		fscache_withdraw_object(object);
+		spin_lock(&object->lock);
+		object->state = FSCACHE_OBJECT_DEAD;
+		spin_unlock(&object->lock);
+		fscache_stat(&fscache_n_object_dead);
+		goto terminal_transit;
+
+		/* complain about the object being woken up once it is
+		 * deceased */
+	case FSCACHE_OBJECT_DEAD:
+		printk(KERN_ERR "FS-Cache:"
+		       " Unexpected event in dead state %lx\n",
+		       object->events & object->event_mask);
+		BUG();
+
+	default:
+		printk(KERN_ERR "FS-Cache: Unknown object state %u\n",
+		       object->state);
+		BUG();
+	}
+
+	/* determine the transition from a lookup state */
+lookup_transit:
+	switch (fls(object->events & object->event_mask) - 1) {
+	case FSCACHE_OBJECT_EV_WITHDRAW:
+	case FSCACHE_OBJECT_EV_RETIRE:
+	case FSCACHE_OBJECT_EV_RELEASE:
+	case FSCACHE_OBJECT_EV_ERROR:
+		new_state = FSCACHE_OBJECT_LC_DYING;
+		goto change_state;
+	case FSCACHE_OBJECT_EV_REQUEUE:
+		goto done;
+	case -1:
+		goto done; /* sleep until event */
+	default:
+		goto unsupported_event;
+	}
+
+	/* determine the transition from an active state */
+active_transit:
+	switch (fls(object->events & object->event_mask) - 1) {
+	case FSCACHE_OBJECT_EV_WITHDRAW:
+	case FSCACHE_OBJECT_EV_RETIRE:
+	case FSCACHE_OBJECT_EV_RELEASE:
+	case FSCACHE_OBJECT_EV_ERROR:
+		new_state = FSCACHE_OBJECT_DYING;
+		goto change_state;
+	case FSCACHE_OBJECT_EV_UPDATE:
+		new_state = FSCACHE_OBJECT_UPDATING;
+		goto change_state;
+	case -1:
+		new_state = FSCACHE_OBJECT_ACTIVE;
+		goto change_state; /* sleep until event */
+	default:
+		goto unsupported_event;
+	}
+
+	/* determine the transition from a terminal state */
+terminal_transit:
+	switch (fls(object->events & object->event_mask) - 1) {
+	case FSCACHE_OBJECT_EV_WITHDRAW:
+		new_state = FSCACHE_OBJECT_WITHDRAWING;
+		goto change_state;
+	case FSCACHE_OBJECT_EV_RETIRE:
+		new_state = FSCACHE_OBJECT_RECYCLING;
+		goto change_state;
+	case FSCACHE_OBJECT_EV_RELEASE:
+		new_state = FSCACHE_OBJECT_RELEASING;
+		goto change_state;
+	case FSCACHE_OBJECT_EV_ERROR:
+		new_state = FSCACHE_OBJECT_WITHDRAWING;
+		goto change_state;
+	case FSCACHE_OBJECT_EV_CLEARED:
+		new_state = FSCACHE_OBJECT_DYING;
+		goto change_state;
+	case -1:
+		goto done; /* sleep until event */
+	default:
+		goto unsupported_event;
+	}
+
+change_state:
+	spin_lock(&object->lock);
+	object->state = new_state;
+	spin_unlock(&object->lock);
+
+done:
+	_leave(" [->%s]", fscache_object_states[object->state]);
+	return;
+
+unsupported_event:
+	printk(KERN_ERR "FS-Cache:"
+	       " Unsupported event %lx [mask %lx] in state %s\n",
+	       object->events, object->event_mask,
+	       fscache_object_states[object->state]);
+	BUG();
+}
+
+/*
+ * execute an object
+ */
+static void fscache_object_slow_work_execute(struct slow_work *work)
+{
+	struct fscache_object *object =
+		container_of(work, struct fscache_object, work);
+	unsigned long start;
+
+	_enter("{OBJ%x}", object->debug_id);
+
+	clear_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
+
+	start = jiffies;
+	fscache_object_state_machine(object);
+	fscache_hist(fscache_objs_histogram, start);
+	if (object->events & object->event_mask)
+		fscache_enqueue_object(object);
+}
+
+/*
+ * initialise an object
+ * - check the specified object's parent to see if we can make use of it
+ *   immediately to do a creation
+ * - we may need to start the process of creating a parent and we need to wait
+ *   for the parent's lookup and creation to complete if it's not there yet
+ * - an object's cookie is pinned until we clear FSCACHE_COOKIE_CREATING on the
+ *   leaf-most cookies of the object and all its children
+ */
+static void fscache_initialise_object(struct fscache_object *object)
+{
+	struct fscache_object *parent;
+
+	_enter("");
+	ASSERT(object->cookie != NULL);
+	ASSERT(object->cookie->parent != NULL);
+	ASSERT(list_empty(&object->work.link));
+
+	if (object->events & ((1 << FSCACHE_OBJECT_EV_ERROR) |
+			      (1 << FSCACHE_OBJECT_EV_RELEASE) |
+			      (1 << FSCACHE_OBJECT_EV_RETIRE) |
+			      (1 << FSCACHE_OBJECT_EV_WITHDRAW))) {
+		_debug("abort init %lx", object->events);
+		spin_lock(&object->lock);
+		object->state = FSCACHE_OBJECT_ABORT_INIT;
+		spin_unlock(&object->lock);
+		return;
+	}
+
+	spin_lock(&object->cookie->lock);
+	spin_lock_nested(&object->cookie->parent->lock, 1);
+
+	parent = object->parent;
+	if (!parent) {
+		_debug("no parent");
+		set_bit(FSCACHE_OBJECT_EV_WITHDRAW, &object->events);
+	} else {
+		spin_lock(&object->lock);
+		spin_lock_nested(&parent->lock, 1);
+		_debug("parent %s", fscache_object_states[parent->state]);
+
+		if (parent->state >= FSCACHE_OBJECT_DYING) {
+			_debug("bad parent");
+			set_bit(FSCACHE_OBJECT_EV_WITHDRAW, &object->events);
+		} else if (parent->state < FSCACHE_OBJECT_AVAILABLE) {
+			_debug("wait");
+
+			/* we may get woken up in this state by child objects
+			 * binding on to us, so we need to make sure we don't
+			 * add ourself to the list multiple times */
+			if (list_empty(&object->dep_link)) {
+				object->cache->ops->grab_object(object);
+				list_add(&object->dep_link,
+					 &parent->dependents);
+
+				/* fscache_acquire_non_index_cookie() uses this
+				 * to wake the chain up */
+				if (parent->state == FSCACHE_OBJECT_INIT)
+					fscache_enqueue_object(parent);
+			}
+		} else {
+			_debug("go");
+			parent->n_ops++;
+			parent->n_obj_ops++;
+			object->lookup_jif = jiffies;
+			object->state = FSCACHE_OBJECT_LOOKING_UP;
+			set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
+		}
+
+		spin_unlock(&parent->lock);
+		spin_unlock(&object->lock);
+	}
+
+	spin_unlock(&object->cookie->parent->lock);
+	spin_unlock(&object->cookie->lock);
+	_leave("");
+}
+
+/*
+ * look an object up in the cache from which it was allocated
+ * - we hold an "access lock" on the parent object, so the parent object cannot
+ *   be withdrawn by either party till we've finished
+ * - an object's cookie is pinned until we clear FSCACHE_COOKIE_CREATING on the
+ *   leaf-most cookies of the object and all its children
+ */
+static void fscache_lookup_object(struct fscache_object *object)
+{
+	struct fscache_cookie *cookie = object->cookie;
+	struct fscache_object *parent;
+
+	_enter("");
+
+	parent = object->parent;
+	ASSERT(parent != NULL);
+	ASSERTCMP(parent->n_ops, >, 0);
+	ASSERTCMP(parent->n_obj_ops, >, 0);
+
+	/* make sure the parent is still available */
+	ASSERTCMP(parent->state, >=, FSCACHE_OBJECT_AVAILABLE);
+
+	if (parent->state >= FSCACHE_OBJECT_DYING ||
+	    test_bit(FSCACHE_IOERROR, &object->cache->flags)) {
+		_debug("unavailable");
+		set_bit(FSCACHE_OBJECT_EV_WITHDRAW, &object->events);
+		_leave("");
+		return;
+	}
+
+	_debug("LOOKUP \"%s/%s\" in \"%s\"",
+	       parent->cookie->def->name, cookie->def->name,
+	       object->cache->tag->name);
+
+	fscache_stat(&fscache_n_object_lookups);
+	object->cache->ops->lookup_object(object);
+
+	if (test_bit(FSCACHE_OBJECT_EV_ERROR, &object->events))
+		set_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags);
+
+	_leave("");
+}
+
+/**
+ * fscache_object_lookup_negative - Note negative cookie lookup
+ * @object: Object pointing to cookie to mark
+ *
+ * Note negative lookup, permitting those waiting to read data from an already
+ * existing backing object to continue as there's no data for them to read.
+ */
+void fscache_object_lookup_negative(struct fscache_object *object)
+{
+	struct fscache_cookie *cookie = object->cookie;
+
+	_enter("{OBJ%x,%s}",
+	       object->debug_id, fscache_object_states[object->state]);
+
+	spin_lock(&object->lock);
+	if (object->state == FSCACHE_OBJECT_LOOKING_UP) {
+		fscache_stat(&fscache_n_object_lookups_negative);
+
+		/* transit here to allow write requests to begin stacking up
+		 * and read requests to begin returning ENODATA */
+		object->state = FSCACHE_OBJECT_CREATING;
+		spin_unlock(&object->lock);
+
+		set_bit(FSCACHE_COOKIE_PENDING_FILL, &cookie->flags);
+		set_bit(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags);
+
+		_debug("wake up lookup %p", &cookie->flags);
+		smp_mb__before_clear_bit();
+		clear_bit(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags);
+		smp_mb__after_clear_bit();
+		wake_up_bit(&cookie->flags, FSCACHE_COOKIE_LOOKING_UP);
+		set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
+	} else {
+		ASSERTCMP(object->state, ==, FSCACHE_OBJECT_CREATING);
+		spin_unlock(&object->lock);
+	}
+
+	_leave("");
+}
+EXPORT_SYMBOL(fscache_object_lookup_negative);
+
+/**
+ * fscache_obtained_object - Note successful object lookup or creation
+ * @object: Object pointing to cookie to mark
+ *
+ * Note successful lookup and/or creation, permitting those waiting to write
+ * data to a backing object to continue.
+ *
+ * Note that after calling this, an object's cookie may be relinquished by the
+ * netfs, and so must be accessed with object lock held.
+ */
+void fscache_obtained_object(struct fscache_object *object)
+{
+	struct fscache_cookie *cookie = object->cookie;
+
+	_enter("{OBJ%x,%s}",
+	       object->debug_id, fscache_object_states[object->state]);
+
+	/* if we were still looking up, then we must have a positive lookup
+	 * result, in which case there may be data available */
+	spin_lock(&object->lock);
+	if (object->state == FSCACHE_OBJECT_LOOKING_UP) {
+		fscache_stat(&fscache_n_object_lookups_positive);
+
+		clear_bit(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags);
+
+		object->state = FSCACHE_OBJECT_AVAILABLE;
+		spin_unlock(&object->lock);
+
+		smp_mb__before_clear_bit();
+		clear_bit(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags);
+		smp_mb__after_clear_bit();
+		wake_up_bit(&cookie->flags, FSCACHE_COOKIE_LOOKING_UP);
+		set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
+	} else {
+		ASSERTCMP(object->state, ==, FSCACHE_OBJECT_CREATING);
+		fscache_stat(&fscache_n_object_created);
+
+		object->state = FSCACHE_OBJECT_AVAILABLE;
+		spin_unlock(&object->lock);
+		set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
+		smp_wmb();
+	}
+
+	if (test_and_clear_bit(FSCACHE_COOKIE_CREATING, &cookie->flags))
+		wake_up_bit(&cookie->flags, FSCACHE_COOKIE_CREATING);
+
+	_leave("");
+}
+EXPORT_SYMBOL(fscache_obtained_object);
+
+/*
+ * handle an object that has just become available
+ */
+static void fscache_object_available(struct fscache_object *object)
+{
+	_enter("{OBJ%x}", object->debug_id);
+
+	spin_lock(&object->lock);
+
+	if (test_and_clear_bit(FSCACHE_COOKIE_CREATING, &object->cookie->flags))
+		wake_up_bit(&object->cookie->flags, FSCACHE_COOKIE_CREATING);
+
+	fscache_done_parent_op(object);
+	if (object->n_in_progress == 0) {
+		if (object->n_ops > 0) {
+			ASSERTCMP(object->n_ops, >=, object->n_obj_ops);
+			ASSERTIF(object->n_ops > object->n_obj_ops,
+				 !list_empty(&object->pending_ops));
+			fscache_start_operations(object);
+		} else {
+			ASSERT(list_empty(&object->pending_ops));
+		}
+	}
+	spin_unlock(&object->lock);
+
+	object->cache->ops->lookup_complete(object);
+	fscache_enqueue_dependents(object);
+
+	fscache_hist(fscache_obj_instantiate_histogram, object->lookup_jif);
+	fscache_stat(&fscache_n_object_avail);
+
+	_leave("");
+}
+
+/*
+ * drop an object's attachments
+ */
+static void fscache_drop_object(struct fscache_object *object)
+{
+	struct fscache_object *parent = object->parent;
+	struct fscache_cache *cache = object->cache;
+
+	_enter("{OBJ%x,%d}", object->debug_id, object->n_children);
+
+	spin_lock(&cache->object_list_lock);
+	list_del_init(&object->cache_link);
+	spin_unlock(&cache->object_list_lock);
+
+	cache->ops->drop_object(object);
+
+	if (parent) {
+		_debug("release parent OBJ%x {%d}",
+		       parent->debug_id, parent->n_children);
+
+		spin_lock(&parent->lock);
+		parent->n_children--;
+		if (parent->n_children == 0)
+			fscache_raise_event(parent, FSCACHE_OBJECT_EV_CLEARED);
+		spin_unlock(&parent->lock);
+		object->parent = NULL;
+	}
+
+	/* this just shifts the object release to the slow work processor */
+	object->cache->ops->put_object(object);
+
+	_leave("");
+}
+
+/*
+ * release or recycle an object that the netfs has discarded
+ */
+static void fscache_release_object(struct fscache_object *object)
+{
+	_enter("");
+
+	fscache_drop_object(object);
+}
+
+/*
+ * withdraw an object from active service
+ */
+static void fscache_withdraw_object(struct fscache_object *object)
+{
+	struct fscache_cookie *cookie;
+	bool detached;
+
+	_enter("");
+
+	spin_lock(&object->lock);
+	cookie = object->cookie;
+	if (cookie) {
+		/* need to get the cookie lock before the object lock, starting
+		 * from the object pointer */
+		atomic_inc(&cookie->usage);
+		spin_unlock(&object->lock);
+
+		detached = false;
+		spin_lock(&cookie->lock);
+		spin_lock(&object->lock);
+
+		if (object->cookie == cookie) {
+			hlist_del_init(&object->cookie_link);
+			object->cookie = NULL;
+			detached = true;
+		}
+		spin_unlock(&cookie->lock);
+		fscache_cookie_put(cookie);
+		if (detached)
+			fscache_cookie_put(cookie);
+	}
+
+	spin_unlock(&object->lock);
+
+	fscache_drop_object(object);
+}
+
+/*
+ * withdraw an object from active service at the behest of the cache
+ * - need break the links to a cached object cookie
+ * - called under two situations:
+ *   (1) recycler decides to reclaim an in-use object
+ *   (2) a cache is unmounted
+ * - have to take care as the cookie can be being relinquished by the netfs
+ *   simultaneously
+ * - the object is pinned by the caller holding a refcount on it
+ */
+void fscache_withdrawing_object(struct fscache_cache *cache,
+				struct fscache_object *object)
+{
+	bool enqueue = false;
+
+	_enter(",OBJ%x", object->debug_id);
+
+	spin_lock(&object->lock);
+	if (object->state < FSCACHE_OBJECT_WITHDRAWING) {
+		object->state = FSCACHE_OBJECT_WITHDRAWING;
+		enqueue = true;
+	}
+	spin_unlock(&object->lock);
+
+	if (enqueue)
+		fscache_enqueue_object(object);
+
+	_leave("");
+}
+
+/*
+ * allow the slow work item processor to get a ref on an object
+ */
+static int fscache_object_slow_work_get_ref(struct slow_work *work)
+{
+	struct fscache_object *object =
+		container_of(work, struct fscache_object, work);
+
+	return object->cache->ops->grab_object(object) ? 0 : -EAGAIN;
+}
+
+/*
+ * allow the slow work item processor to discard a ref on a work item
+ */
+static void fscache_object_slow_work_put_ref(struct slow_work *work)
+{
+	struct fscache_object *object =
+		container_of(work, struct fscache_object, work);
+
+	return object->cache->ops->put_object(object);
+}
+
+/*
+ * enqueue an object for metadata-type processing
+ */
+void fscache_enqueue_object(struct fscache_object *object)
+{
+	_enter("{OBJ%x}", object->debug_id);
+
+	slow_work_enqueue(&object->work);
+}
+
+/*
+ * enqueue the dependents of an object for metadata-type processing
+ * - the caller must hold the object's lock
+ * - this may cause an already locked object to wind up being processed again
+ */
+static void fscache_enqueue_dependents(struct fscache_object *object)
+{
+	struct fscache_object *dep;
+
+	_enter("{OBJ%x}", object->debug_id);
+
+	if (list_empty(&object->dependents))
+		return;
+
+	spin_lock(&object->lock);
+
+	while (!list_empty(&object->dependents)) {
+		dep = list_entry(object->dependents.next,
+				 struct fscache_object, dep_link);
+		list_del_init(&dep->dep_link);
+
+
+		/* sort onto appropriate lists */
+		fscache_enqueue_object(dep);
+		dep->cache->ops->put_object(dep);
+
+		if (!list_empty(&object->dependents))
+			cond_resched_lock(&object->lock);
+	}
+
+	spin_unlock(&object->lock);
+}
+
+/*
+ * remove an object from whatever queue it's waiting on
+ * - the caller must hold object->lock
+ */
+void fscache_dequeue_object(struct fscache_object *object)
+{
+	_enter("{OBJ%x}", object->debug_id);
+
+	if (!list_empty(&object->dep_link)) {
+		spin_lock(&object->parent->lock);
+		list_del_init(&object->dep_link);
+		spin_unlock(&object->parent->lock);
+	}
+
+	_leave("");
+}
+
+/**
+ * fscache_check_aux - Ask the netfs whether an object on disk is still valid
+ * @object: The object to ask about
+ * @data: The auxiliary data for the object
+ * @datalen: The size of the auxiliary data
+ *
+ * This function consults the netfs about the coherency state of an object
+ */
+enum fscache_checkaux fscache_check_aux(struct fscache_object *object,
+					const void *data, uint16_t datalen)
+{
+	enum fscache_checkaux result;
+
+	if (!object->cookie->def->check_aux) {
+		fscache_stat(&fscache_n_checkaux_none);
+		return FSCACHE_CHECKAUX_OKAY;
+	}
+
+	result = object->cookie->def->check_aux(object->cookie->netfs_data,
+						data, datalen);
+	switch (result) {
+		/* entry okay as is */
+	case FSCACHE_CHECKAUX_OKAY:
+		fscache_stat(&fscache_n_checkaux_okay);
+		break;
+
+		/* entry requires update */
+	case FSCACHE_CHECKAUX_NEEDS_UPDATE:
+		fscache_stat(&fscache_n_checkaux_update);
+		break;
+
+		/* entry requires deletion */
+	case FSCACHE_CHECKAUX_OBSOLETE:
+		fscache_stat(&fscache_n_checkaux_obsolete);
+		break;
+
+	default:
+		BUG();
+	}
+
+	return result;
+}
+EXPORT_SYMBOL(fscache_check_aux);
diff --git a/fs/fscache/operation.c b/fs/fscache/operation.c
new file mode 100644
index 0000000..e7f8d53
--- /dev/null
+++ b/fs/fscache/operation.c
@@ -0,0 +1,459 @@
+/* FS-Cache worker operation management routines
+ *
+ * Copyright (C) 2008 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * See Documentation/filesystems/caching/operations.txt
+ */
+
+#define FSCACHE_DEBUG_LEVEL OPERATION
+#include <linux/module.h>
+#include "internal.h"
+
+atomic_t fscache_op_debug_id;
+EXPORT_SYMBOL(fscache_op_debug_id);
+
+/**
+ * fscache_enqueue_operation - Enqueue an operation for processing
+ * @op: The operation to enqueue
+ *
+ * Enqueue an operation for processing by the FS-Cache thread pool.
+ *
+ * This will get its own ref on the object.
+ */
+void fscache_enqueue_operation(struct fscache_operation *op)
+{
+	_enter("{OBJ%x OP%x,%u}",
+	       op->object->debug_id, op->debug_id, atomic_read(&op->usage));
+
+	ASSERT(op->processor != NULL);
+	ASSERTCMP(op->object->state, >=, FSCACHE_OBJECT_AVAILABLE);
+	ASSERTCMP(atomic_read(&op->usage), >, 0);
+
+	if (list_empty(&op->pend_link)) {
+		switch (op->flags & FSCACHE_OP_TYPE) {
+		case FSCACHE_OP_FAST:
+			_debug("queue fast");
+			atomic_inc(&op->usage);
+			if (!schedule_work(&op->fast_work))
+				fscache_put_operation(op);
+			break;
+		case FSCACHE_OP_SLOW:
+			_debug("queue slow");
+			slow_work_enqueue(&op->slow_work);
+			break;
+		case FSCACHE_OP_MYTHREAD:
+			_debug("queue for caller's attention");
+			break;
+		default:
+			printk(KERN_ERR "FS-Cache: Unexpected op type %lx",
+			       op->flags);
+			BUG();
+			break;
+		}
+		fscache_stat(&fscache_n_op_enqueue);
+	}
+}
+EXPORT_SYMBOL(fscache_enqueue_operation);
+
+/*
+ * start an op running
+ */
+static void fscache_run_op(struct fscache_object *object,
+			   struct fscache_operation *op)
+{
+	object->n_in_progress++;
+	if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags))
+		wake_up_bit(&op->flags, FSCACHE_OP_WAITING);
+	if (op->processor)
+		fscache_enqueue_operation(op);
+	fscache_stat(&fscache_n_op_run);
+}
+
+/*
+ * submit an exclusive operation for an object
+ * - other ops are excluded from running simultaneously with this one
+ * - this gets any extra refs it needs on an op
+ */
+int fscache_submit_exclusive_op(struct fscache_object *object,
+				struct fscache_operation *op)
+{
+	int ret;
+
+	_enter("{OBJ%x OP%x},", object->debug_id, op->debug_id);
+
+	spin_lock(&object->lock);
+	ASSERTCMP(object->n_ops, >=, object->n_in_progress);
+	ASSERTCMP(object->n_ops, >=, object->n_exclusive);
+
+	ret = -ENOBUFS;
+	if (fscache_object_is_active(object)) {
+		op->object = object;
+		object->n_ops++;
+		object->n_exclusive++;	/* reads and writes must wait */
+
+		if (object->n_ops > 0) {
+			atomic_inc(&op->usage);
+			list_add_tail(&op->pend_link, &object->pending_ops);
+			fscache_stat(&fscache_n_op_pend);
+		} else if (!list_empty(&object->pending_ops)) {
+			atomic_inc(&op->usage);
+			list_add_tail(&op->pend_link, &object->pending_ops);
+			fscache_stat(&fscache_n_op_pend);
+			fscache_start_operations(object);
+		} else {
+			ASSERTCMP(object->n_in_progress, ==, 0);
+			fscache_run_op(object, op);
+		}
+
+		/* need to issue a new write op after this */
+		clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags);
+		ret = 0;
+	} else if (object->state == FSCACHE_OBJECT_CREATING) {
+		op->object = object;
+		object->n_ops++;
+		object->n_exclusive++;	/* reads and writes must wait */
+		atomic_inc(&op->usage);
+		list_add_tail(&op->pend_link, &object->pending_ops);
+		fscache_stat(&fscache_n_op_pend);
+		ret = 0;
+	} else {
+		/* not allowed to submit ops in any other state */
+		BUG();
+	}
+
+	spin_unlock(&object->lock);
+	return ret;
+}
+
+/*
+ * report an unexpected submission
+ */
+static void fscache_report_unexpected_submission(struct fscache_object *object,
+						 struct fscache_operation *op,
+						 unsigned long ostate)
+{
+	static bool once_only;
+	struct fscache_operation *p;
+	unsigned n;
+
+	if (once_only)
+		return;
+	once_only = true;
+
+	kdebug("unexpected submission OP%x [OBJ%x %s]",
+	       op->debug_id, object->debug_id,
+	       fscache_object_states[object->state]);
+	kdebug("objstate=%s [%s]",
+	       fscache_object_states[object->state],
+	       fscache_object_states[ostate]);
+	kdebug("objflags=%lx", object->flags);
+	kdebug("objevent=%lx [%lx]", object->events, object->event_mask);
+	kdebug("ops=%u inp=%u exc=%u",
+	       object->n_ops, object->n_in_progress, object->n_exclusive);
+
+	if (!list_empty(&object->pending_ops)) {
+		n = 0;
+		list_for_each_entry(p, &object->pending_ops, pend_link) {
+			ASSERTCMP(p->object, ==, object);
+			kdebug("%p %p", op->processor, op->release);
+			n++;
+		}
+
+		kdebug("n=%u", n);
+	}
+
+	dump_stack();
+}
+
+/*
+ * submit an operation for an object
+ * - objects may be submitted only in the following states:
+ *   - during object creation (write ops may be submitted)
+ *   - whilst the object is active
+ *   - after an I/O error incurred in one of the two above states (op rejected)
+ * - this gets any extra refs it needs on an op
+ */
+int fscache_submit_op(struct fscache_object *object,
+		      struct fscache_operation *op)
+{
+	unsigned long ostate;
+	int ret;
+
+	_enter("{OBJ%x OP%x},{%u}",
+	       object->debug_id, op->debug_id, atomic_read(&op->usage));
+
+	ASSERTCMP(atomic_read(&op->usage), >, 0);
+
+	spin_lock(&object->lock);
+	ASSERTCMP(object->n_ops, >=, object->n_in_progress);
+	ASSERTCMP(object->n_ops, >=, object->n_exclusive);
+
+	ostate = object->state;
+	smp_rmb();
+
+	if (fscache_object_is_active(object)) {
+		op->object = object;
+		object->n_ops++;
+
+		if (object->n_exclusive > 0) {
+			atomic_inc(&op->usage);
+			list_add_tail(&op->pend_link, &object->pending_ops);
+			fscache_stat(&fscache_n_op_pend);
+		} else if (!list_empty(&object->pending_ops)) {
+			atomic_inc(&op->usage);
+			list_add_tail(&op->pend_link, &object->pending_ops);
+			fscache_stat(&fscache_n_op_pend);
+			fscache_start_operations(object);
+		} else {
+			ASSERTCMP(object->n_exclusive, ==, 0);
+			fscache_run_op(object, op);
+		}
+		ret = 0;
+	} else if (object->state == FSCACHE_OBJECT_CREATING) {
+		op->object = object;
+		object->n_ops++;
+		atomic_inc(&op->usage);
+		list_add_tail(&op->pend_link, &object->pending_ops);
+		fscache_stat(&fscache_n_op_pend);
+		ret = 0;
+	} else if (!test_bit(FSCACHE_IOERROR, &object->cache->flags)) {
+		fscache_report_unexpected_submission(object, op, ostate);
+		ASSERT(!fscache_object_is_active(object));
+		ret = -ENOBUFS;
+	} else {
+		ret = -ENOBUFS;
+	}
+
+	spin_unlock(&object->lock);
+	return ret;
+}
+
+/*
+ * queue an object for withdrawal on error, aborting all following asynchronous
+ * operations
+ */
+void fscache_abort_object(struct fscache_object *object)
+{
+	_enter("{OBJ%x}", object->debug_id);
+
+	fscache_raise_event(object, FSCACHE_OBJECT_EV_ERROR);
+}
+
+/*
+ * jump start the operation processing on an object
+ * - caller must hold object->lock
+ */
+void fscache_start_operations(struct fscache_object *object)
+{
+	struct fscache_operation *op;
+	bool stop = false;
+
+	while (!list_empty(&object->pending_ops) && !stop) {
+		op = list_entry(object->pending_ops.next,
+				struct fscache_operation, pend_link);
+
+		if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags)) {
+			if (object->n_in_progress > 0)
+				break;
+			stop = true;
+		}
+		list_del_init(&op->pend_link);
+		object->n_in_progress++;
+
+		if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags))
+			wake_up_bit(&op->flags, FSCACHE_OP_WAITING);
+		if (op->processor)
+			fscache_enqueue_operation(op);
+
+		/* the pending queue was holding a ref on the object */
+		fscache_put_operation(op);
+	}
+
+	ASSERTCMP(object->n_in_progress, <=, object->n_ops);
+
+	_debug("woke %d ops on OBJ%x",
+	       object->n_in_progress, object->debug_id);
+}
+
+/*
+ * release an operation
+ * - queues pending ops if this is the last in-progress op
+ */
+void fscache_put_operation(struct fscache_operation *op)
+{
+	struct fscache_object *object;
+	struct fscache_cache *cache;
+
+	_enter("{OBJ%x OP%x,%d}",
+	       op->object->debug_id, op->debug_id, atomic_read(&op->usage));
+
+	ASSERTCMP(atomic_read(&op->usage), >, 0);
+
+	if (!atomic_dec_and_test(&op->usage))
+		return;
+
+	_debug("PUT OP");
+	if (test_and_set_bit(FSCACHE_OP_DEAD, &op->flags))
+		BUG();
+
+	fscache_stat(&fscache_n_op_release);
+
+	if (op->release) {
+		op->release(op);
+		op->release = NULL;
+	}
+
+	object = op->object;
+
+	/* now... we may get called with the object spinlock held, so we
+	 * complete the cleanup here only if we can immediately acquire the
+	 * lock, and defer it otherwise */
+	if (!spin_trylock(&object->lock)) {
+		_debug("defer put");
+		fscache_stat(&fscache_n_op_deferred_release);
+
+		cache = object->cache;
+		spin_lock(&cache->op_gc_list_lock);
+		list_add_tail(&op->pend_link, &cache->op_gc_list);
+		spin_unlock(&cache->op_gc_list_lock);
+		schedule_work(&cache->op_gc);
+		_leave(" [defer]");
+		return;
+	}
+
+	if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags)) {
+		ASSERTCMP(object->n_exclusive, >, 0);
+		object->n_exclusive--;
+	}
+
+	ASSERTCMP(object->n_in_progress, >, 0);
+	object->n_in_progress--;
+	if (object->n_in_progress == 0)
+		fscache_start_operations(object);
+
+	ASSERTCMP(object->n_ops, >, 0);
+	object->n_ops--;
+	if (object->n_ops == 0)
+		fscache_raise_event(object, FSCACHE_OBJECT_EV_CLEARED);
+
+	spin_unlock(&object->lock);
+
+	kfree(op);
+	_leave(" [done]");
+}
+EXPORT_SYMBOL(fscache_put_operation);
+
+/*
+ * garbage collect operations that have had their release deferred
+ */
+void fscache_operation_gc(struct work_struct *work)
+{
+	struct fscache_operation *op;
+	struct fscache_object *object;
+	struct fscache_cache *cache =
+		container_of(work, struct fscache_cache, op_gc);
+	int count = 0;
+
+	_enter("");
+
+	do {
+		spin_lock(&cache->op_gc_list_lock);
+		if (list_empty(&cache->op_gc_list)) {
+			spin_unlock(&cache->op_gc_list_lock);
+			break;
+		}
+
+		op = list_entry(cache->op_gc_list.next,
+				struct fscache_operation, pend_link);
+		list_del(&op->pend_link);
+		spin_unlock(&cache->op_gc_list_lock);
+
+		object = op->object;
+
+		_debug("GC DEFERRED REL OBJ%x OP%x",
+		       object->debug_id, op->debug_id);
+		fscache_stat(&fscache_n_op_gc);
+
+		ASSERTCMP(atomic_read(&op->usage), ==, 0);
+
+		spin_lock(&object->lock);
+		if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags)) {
+			ASSERTCMP(object->n_exclusive, >, 0);
+			object->n_exclusive--;
+		}
+
+		ASSERTCMP(object->n_in_progress, >, 0);
+		object->n_in_progress--;
+		if (object->n_in_progress == 0)
+			fscache_start_operations(object);
+
+		ASSERTCMP(object->n_ops, >, 0);
+		object->n_ops--;
+		if (object->n_ops == 0)
+			fscache_raise_event(object, FSCACHE_OBJECT_EV_CLEARED);
+
+		spin_unlock(&object->lock);
+
+	} while (count++ < 20);
+
+	if (!list_empty(&cache->op_gc_list))
+		schedule_work(&cache->op_gc);
+
+	_leave("");
+}
+
+/*
+ * allow the slow work item processor to get a ref on an operation
+ */
+static int fscache_op_get_ref(struct slow_work *work)
+{
+	struct fscache_operation *op =
+		container_of(work, struct fscache_operation, slow_work);
+
+	atomic_inc(&op->usage);
+	return 0;
+}
+
+/*
+ * allow the slow work item processor to discard a ref on an operation
+ */
+static void fscache_op_put_ref(struct slow_work *work)
+{
+	struct fscache_operation *op =
+		container_of(work, struct fscache_operation, slow_work);
+
+	fscache_put_operation(op);
+}
+
+/*
+ * execute an operation using the slow thread pool to provide processing context
+ * - the caller holds a ref to this object, so we don't need to hold one
+ */
+static void fscache_op_execute(struct slow_work *work)
+{
+	struct fscache_operation *op =
+		container_of(work, struct fscache_operation, slow_work);
+	unsigned long start;
+
+	_enter("{OBJ%x OP%x,%d}",
+	       op->object->debug_id, op->debug_id, atomic_read(&op->usage));
+
+	ASSERT(op->processor != NULL);
+	start = jiffies;
+	op->processor(op);
+	fscache_hist(fscache_ops_histogram, start);
+
+	_leave("");
+}
+
+const struct slow_work_ops fscache_op_slow_work_ops = {
+	.get_ref	= fscache_op_get_ref,
+	.put_ref	= fscache_op_put_ref,
+	.execute	= fscache_op_execute,
+};
diff --git a/fs/fscache/page.c b/fs/fscache/page.c
new file mode 100644
index 0000000..2568e0e
--- /dev/null
+++ b/fs/fscache/page.c
@@ -0,0 +1,816 @@
+/* Cache page management and data I/O routines
+ *
+ * Copyright (C) 2004-2008 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define FSCACHE_DEBUG_LEVEL PAGE
+#include <linux/module.h>
+#include <linux/fscache-cache.h>
+#include <linux/buffer_head.h>
+#include <linux/pagevec.h>
+#include "internal.h"
+
+/*
+ * check to see if a page is being written to the cache
+ */
+bool __fscache_check_page_write(struct fscache_cookie *cookie, struct page *page)
+{
+	void *val;
+
+	rcu_read_lock();
+	val = radix_tree_lookup(&cookie->stores, page->index);
+	rcu_read_unlock();
+
+	return val != NULL;
+}
+EXPORT_SYMBOL(__fscache_check_page_write);
+
+/*
+ * wait for a page to finish being written to the cache
+ */
+void __fscache_wait_on_page_write(struct fscache_cookie *cookie, struct page *page)
+{
+	wait_queue_head_t *wq = bit_waitqueue(&cookie->flags, 0);
+
+	wait_event(*wq, !__fscache_check_page_write(cookie, page));
+}
+EXPORT_SYMBOL(__fscache_wait_on_page_write);
+
+/*
+ * note that a page has finished being written to the cache
+ */
+static void fscache_end_page_write(struct fscache_cookie *cookie, struct page *page)
+{
+	struct page *xpage;
+
+	spin_lock(&cookie->lock);
+	xpage = radix_tree_delete(&cookie->stores, page->index);
+	spin_unlock(&cookie->lock);
+	ASSERT(xpage != NULL);
+
+	wake_up_bit(&cookie->flags, 0);
+}
+
+/*
+ * actually apply the changed attributes to a cache object
+ */
+static void fscache_attr_changed_op(struct fscache_operation *op)
+{
+	struct fscache_object *object = op->object;
+
+	_enter("{OBJ%x OP%x}", object->debug_id, op->debug_id);
+
+	fscache_stat(&fscache_n_attr_changed_calls);
+
+	if (fscache_object_is_active(object) &&
+	    object->cache->ops->attr_changed(object) < 0)
+		fscache_abort_object(object);
+
+	_leave("");
+}
+
+/*
+ * notification that the attributes on an object have changed
+ */
+int __fscache_attr_changed(struct fscache_cookie *cookie)
+{
+	struct fscache_operation *op;
+	struct fscache_object *object;
+
+	_enter("%p", cookie);
+
+	ASSERTCMP(cookie->def->type, !=, FSCACHE_COOKIE_TYPE_INDEX);
+
+	fscache_stat(&fscache_n_attr_changed);
+
+	op = kzalloc(sizeof(*op), GFP_KERNEL);
+	if (!op) {
+		fscache_stat(&fscache_n_attr_changed_nomem);
+		_leave(" = -ENOMEM");
+		return -ENOMEM;
+	}
+
+	fscache_operation_init(op, NULL);
+	fscache_operation_init_slow(op, fscache_attr_changed_op);
+	op->flags = FSCACHE_OP_SLOW | (1 << FSCACHE_OP_EXCLUSIVE);
+
+	spin_lock(&cookie->lock);
+
+	if (hlist_empty(&cookie->backing_objects))
+		goto nobufs;
+	object = hlist_entry(cookie->backing_objects.first,
+			     struct fscache_object, cookie_link);
+
+	if (fscache_submit_exclusive_op(object, op) < 0)
+		goto nobufs;
+	spin_unlock(&cookie->lock);
+	fscache_stat(&fscache_n_attr_changed_ok);
+	fscache_put_operation(op);
+	_leave(" = 0");
+	return 0;
+
+nobufs:
+	spin_unlock(&cookie->lock);
+	kfree(op);
+	fscache_stat(&fscache_n_attr_changed_nobufs);
+	_leave(" = %d", -ENOBUFS);
+	return -ENOBUFS;
+}
+EXPORT_SYMBOL(__fscache_attr_changed);
+
+/*
+ * handle secondary execution given to a retrieval op on behalf of the
+ * cache
+ */
+static void fscache_retrieval_work(struct work_struct *work)
+{
+	struct fscache_retrieval *op =
+		container_of(work, struct fscache_retrieval, op.fast_work);
+	unsigned long start;
+
+	_enter("{OP%x}", op->op.debug_id);
+
+	start = jiffies;
+	op->op.processor(&op->op);
+	fscache_hist(fscache_ops_histogram, start);
+	fscache_put_operation(&op->op);
+}
+
+/*
+ * release a retrieval op reference
+ */
+static void fscache_release_retrieval_op(struct fscache_operation *_op)
+{
+	struct fscache_retrieval *op =
+		container_of(_op, struct fscache_retrieval, op);
+
+	_enter("{OP%x}", op->op.debug_id);
+
+	fscache_hist(fscache_retrieval_histogram, op->start_time);
+	if (op->context)
+		fscache_put_context(op->op.object->cookie, op->context);
+
+	_leave("");
+}
+
+/*
+ * allocate a retrieval op
+ */
+static struct fscache_retrieval *fscache_alloc_retrieval(
+	struct address_space *mapping,
+	fscache_rw_complete_t end_io_func,
+	void *context)
+{
+	struct fscache_retrieval *op;
+
+	/* allocate a retrieval operation and attempt to submit it */
+	op = kzalloc(sizeof(*op), GFP_NOIO);
+	if (!op) {
+		fscache_stat(&fscache_n_retrievals_nomem);
+		return NULL;
+	}
+
+	fscache_operation_init(&op->op, fscache_release_retrieval_op);
+	op->op.flags	= FSCACHE_OP_MYTHREAD | (1 << FSCACHE_OP_WAITING);
+	op->mapping	= mapping;
+	op->end_io_func	= end_io_func;
+	op->context	= context;
+	op->start_time	= jiffies;
+	INIT_WORK(&op->op.fast_work, fscache_retrieval_work);
+	INIT_LIST_HEAD(&op->to_do);
+	return op;
+}
+
+/*
+ * wait for a deferred lookup to complete
+ */
+static int fscache_wait_for_deferred_lookup(struct fscache_cookie *cookie)
+{
+	unsigned long jif;
+
+	_enter("");
+
+	if (!test_bit(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags)) {
+		_leave(" = 0 [imm]");
+		return 0;
+	}
+
+	fscache_stat(&fscache_n_retrievals_wait);
+
+	jif = jiffies;
+	if (wait_on_bit(&cookie->flags, FSCACHE_COOKIE_LOOKING_UP,
+			fscache_wait_bit_interruptible,
+			TASK_INTERRUPTIBLE) != 0) {
+		fscache_stat(&fscache_n_retrievals_intr);
+		_leave(" = -ERESTARTSYS");
+		return -ERESTARTSYS;
+	}
+
+	ASSERT(!test_bit(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags));
+
+	smp_rmb();
+	fscache_hist(fscache_retrieval_delay_histogram, jif);
+	_leave(" = 0 [dly]");
+	return 0;
+}
+
+/*
+ * read a page from the cache or allocate a block in which to store it
+ * - we return:
+ *   -ENOMEM	- out of memory, nothing done
+ *   -ERESTARTSYS - interrupted
+ *   -ENOBUFS	- no backing object available in which to cache the block
+ *   -ENODATA	- no data available in the backing object for this block
+ *   0		- dispatched a read - it'll call end_io_func() when finished
+ */
+int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
+				 struct page *page,
+				 fscache_rw_complete_t end_io_func,
+				 void *context,
+				 gfp_t gfp)
+{
+	struct fscache_retrieval *op;
+	struct fscache_object *object;
+	int ret;
+
+	_enter("%p,%p,,,", cookie, page);
+
+	fscache_stat(&fscache_n_retrievals);
+
+	if (hlist_empty(&cookie->backing_objects))
+		goto nobufs;
+
+	ASSERTCMP(cookie->def->type, !=, FSCACHE_COOKIE_TYPE_INDEX);
+	ASSERTCMP(page, !=, NULL);
+
+	if (fscache_wait_for_deferred_lookup(cookie) < 0)
+		return -ERESTARTSYS;
+
+	op = fscache_alloc_retrieval(page->mapping, end_io_func, context);
+	if (!op) {
+		_leave(" = -ENOMEM");
+		return -ENOMEM;
+	}
+
+	spin_lock(&cookie->lock);
+
+	if (hlist_empty(&cookie->backing_objects))
+		goto nobufs_unlock;
+	object = hlist_entry(cookie->backing_objects.first,
+			     struct fscache_object, cookie_link);
+
+	ASSERTCMP(object->state, >, FSCACHE_OBJECT_LOOKING_UP);
+
+	if (fscache_submit_op(object, &op->op) < 0)
+		goto nobufs_unlock;
+	spin_unlock(&cookie->lock);
+
+	fscache_stat(&fscache_n_retrieval_ops);
+
+	/* pin the netfs read context in case we need to do the actual netfs
+	 * read because we've encountered a cache read failure */
+	fscache_get_context(object->cookie, op->context);
+
+	/* we wait for the operation to become active, and then process it
+	 * *here*, in this thread, and not in the thread pool */
+	if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) {
+		_debug(">>> WT");
+		fscache_stat(&fscache_n_retrieval_op_waits);
+		wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
+			    fscache_wait_bit, TASK_UNINTERRUPTIBLE);
+		_debug("<<< GO");
+	}
+
+	/* ask the cache to honour the operation */
+	if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags)) {
+		ret = object->cache->ops->allocate_page(op, page, gfp);
+		if (ret == 0)
+			ret = -ENODATA;
+	} else {
+		ret = object->cache->ops->read_or_alloc_page(op, page, gfp);
+	}
+
+	if (ret == -ENOMEM)
+		fscache_stat(&fscache_n_retrievals_nomem);
+	else if (ret == -ERESTARTSYS)
+		fscache_stat(&fscache_n_retrievals_intr);
+	else if (ret == -ENODATA)
+		fscache_stat(&fscache_n_retrievals_nodata);
+	else if (ret < 0)
+		fscache_stat(&fscache_n_retrievals_nobufs);
+	else
+		fscache_stat(&fscache_n_retrievals_ok);
+
+	fscache_put_retrieval(op);
+	_leave(" = %d", ret);
+	return ret;
+
+nobufs_unlock:
+	spin_unlock(&cookie->lock);
+	kfree(op);
+nobufs:
+	fscache_stat(&fscache_n_retrievals_nobufs);
+	_leave(" = -ENOBUFS");
+	return -ENOBUFS;
+}
+EXPORT_SYMBOL(__fscache_read_or_alloc_page);
+
+/*
+ * read a list of page from the cache or allocate a block in which to store
+ * them
+ * - we return:
+ *   -ENOMEM	- out of memory, some pages may be being read
+ *   -ERESTARTSYS - interrupted, some pages may be being read
+ *   -ENOBUFS	- no backing object or space available in which to cache any
+ *                pages not being read
+ *   -ENODATA	- no data available in the backing object for some or all of
+ *                the pages
+ *   0		- dispatched a read on all pages
+ *
+ * end_io_func() will be called for each page read from the cache as it is
+ * finishes being read
+ *
+ * any pages for which a read is dispatched will be removed from pages and
+ * nr_pages
+ */
+int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
+				  struct address_space *mapping,
+				  struct list_head *pages,
+				  unsigned *nr_pages,
+				  fscache_rw_complete_t end_io_func,
+				  void *context,
+				  gfp_t gfp)
+{
+	fscache_pages_retrieval_func_t func;
+	struct fscache_retrieval *op;
+	struct fscache_object *object;
+	int ret;
+
+	_enter("%p,,%d,,,", cookie, *nr_pages);
+
+	fscache_stat(&fscache_n_retrievals);
+
+	if (hlist_empty(&cookie->backing_objects))
+		goto nobufs;
+
+	ASSERTCMP(cookie->def->type, !=, FSCACHE_COOKIE_TYPE_INDEX);
+	ASSERTCMP(*nr_pages, >, 0);
+	ASSERT(!list_empty(pages));
+
+	if (fscache_wait_for_deferred_lookup(cookie) < 0)
+		return -ERESTARTSYS;
+
+	op = fscache_alloc_retrieval(mapping, end_io_func, context);
+	if (!op)
+		return -ENOMEM;
+
+	spin_lock(&cookie->lock);
+
+	if (hlist_empty(&cookie->backing_objects))
+		goto nobufs_unlock;
+	object = hlist_entry(cookie->backing_objects.first,
+			     struct fscache_object, cookie_link);
+
+	if (fscache_submit_op(object, &op->op) < 0)
+		goto nobufs_unlock;
+	spin_unlock(&cookie->lock);
+
+	fscache_stat(&fscache_n_retrieval_ops);
+
+	/* pin the netfs read context in case we need to do the actual netfs
+	 * read because we've encountered a cache read failure */
+	fscache_get_context(object->cookie, op->context);
+
+	/* we wait for the operation to become active, and then process it
+	 * *here*, in this thread, and not in the thread pool */
+	if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) {
+		_debug(">>> WT");
+		fscache_stat(&fscache_n_retrieval_op_waits);
+		wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
+			    fscache_wait_bit, TASK_UNINTERRUPTIBLE);
+		_debug("<<< GO");
+	}
+
+	/* ask the cache to honour the operation */
+	if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags))
+		func = object->cache->ops->allocate_pages;
+	else
+		func = object->cache->ops->read_or_alloc_pages;
+	ret = func(op, pages, nr_pages, gfp);
+
+	if (ret == -ENOMEM)
+		fscache_stat(&fscache_n_retrievals_nomem);
+	else if (ret == -ERESTARTSYS)
+		fscache_stat(&fscache_n_retrievals_intr);
+	else if (ret == -ENODATA)
+		fscache_stat(&fscache_n_retrievals_nodata);
+	else if (ret < 0)
+		fscache_stat(&fscache_n_retrievals_nobufs);
+	else
+		fscache_stat(&fscache_n_retrievals_ok);
+
+	fscache_put_retrieval(op);
+	_leave(" = %d", ret);
+	return ret;
+
+nobufs_unlock:
+	spin_unlock(&cookie->lock);
+	kfree(op);
+nobufs:
+	fscache_stat(&fscache_n_retrievals_nobufs);
+	_leave(" = -ENOBUFS");
+	return -ENOBUFS;
+}
+EXPORT_SYMBOL(__fscache_read_or_alloc_pages);
+
+/*
+ * allocate a block in the cache on which to store a page
+ * - we return:
+ *   -ENOMEM	- out of memory, nothing done
+ *   -ERESTARTSYS - interrupted
+ *   -ENOBUFS	- no backing object available in which to cache the block
+ *   0		- block allocated
+ */
+int __fscache_alloc_page(struct fscache_cookie *cookie,
+			 struct page *page,
+			 gfp_t gfp)
+{
+	struct fscache_retrieval *op;
+	struct fscache_object *object;
+	int ret;
+
+	_enter("%p,%p,,,", cookie, page);
+
+	fscache_stat(&fscache_n_allocs);
+
+	if (hlist_empty(&cookie->backing_objects))
+		goto nobufs;
+
+	ASSERTCMP(cookie->def->type, !=, FSCACHE_COOKIE_TYPE_INDEX);
+	ASSERTCMP(page, !=, NULL);
+
+	if (fscache_wait_for_deferred_lookup(cookie) < 0)
+		return -ERESTARTSYS;
+
+	op = fscache_alloc_retrieval(page->mapping, NULL, NULL);
+	if (!op)
+		return -ENOMEM;
+
+	spin_lock(&cookie->lock);
+
+	if (hlist_empty(&cookie->backing_objects))
+		goto nobufs_unlock;
+	object = hlist_entry(cookie->backing_objects.first,
+			     struct fscache_object, cookie_link);
+
+	if (fscache_submit_op(object, &op->op) < 0)
+		goto nobufs_unlock;
+	spin_unlock(&cookie->lock);
+
+	fscache_stat(&fscache_n_alloc_ops);
+
+	if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) {
+		_debug(">>> WT");
+		fscache_stat(&fscache_n_alloc_op_waits);
+		wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
+			    fscache_wait_bit, TASK_UNINTERRUPTIBLE);
+		_debug("<<< GO");
+	}
+
+	/* ask the cache to honour the operation */
+	ret = object->cache->ops->allocate_page(op, page, gfp);
+
+	if (ret < 0)
+		fscache_stat(&fscache_n_allocs_nobufs);
+	else
+		fscache_stat(&fscache_n_allocs_ok);
+
+	fscache_put_retrieval(op);
+	_leave(" = %d", ret);
+	return ret;
+
+nobufs_unlock:
+	spin_unlock(&cookie->lock);
+	kfree(op);
+nobufs:
+	fscache_stat(&fscache_n_allocs_nobufs);
+	_leave(" = -ENOBUFS");
+	return -ENOBUFS;
+}
+EXPORT_SYMBOL(__fscache_alloc_page);
+
+/*
+ * release a write op reference
+ */
+static void fscache_release_write_op(struct fscache_operation *_op)
+{
+	_enter("{OP%x}", _op->debug_id);
+}
+
+/*
+ * perform the background storage of a page into the cache
+ */
+static void fscache_write_op(struct fscache_operation *_op)
+{
+	struct fscache_storage *op =
+		container_of(_op, struct fscache_storage, op);
+	struct fscache_object *object = op->op.object;
+	struct fscache_cookie *cookie = object->cookie;
+	struct page *page;
+	unsigned n;
+	void *results[1];
+	int ret;
+
+	_enter("{OP%x,%d}", op->op.debug_id, atomic_read(&op->op.usage));
+
+	spin_lock(&cookie->lock);
+	spin_lock(&object->lock);
+
+	if (!fscache_object_is_active(object)) {
+		spin_unlock(&object->lock);
+		spin_unlock(&cookie->lock);
+		_leave("");
+		return;
+	}
+
+	fscache_stat(&fscache_n_store_calls);
+
+	/* find a page to store */
+	page = NULL;
+	n = radix_tree_gang_lookup_tag(&cookie->stores, results, 0, 1,
+				       FSCACHE_COOKIE_PENDING_TAG);
+	if (n != 1)
+		goto superseded;
+	page = results[0];
+	_debug("gang %d [%lx]", n, page->index);
+	if (page->index > op->store_limit)
+		goto superseded;
+
+	radix_tree_tag_clear(&cookie->stores, page->index,
+			     FSCACHE_COOKIE_PENDING_TAG);
+
+	spin_unlock(&object->lock);
+	spin_unlock(&cookie->lock);
+
+	if (page) {
+		ret = object->cache->ops->write_page(op, page);
+		fscache_end_page_write(cookie, page);
+		page_cache_release(page);
+		if (ret < 0)
+			fscache_abort_object(object);
+		else
+			fscache_enqueue_operation(&op->op);
+	}
+
+	_leave("");
+	return;
+
+superseded:
+	/* this writer is going away and there aren't any more things to
+	 * write */
+	_debug("cease");
+	clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags);
+	spin_unlock(&object->lock);
+	spin_unlock(&cookie->lock);
+	_leave("");
+}
+
+/*
+ * request a page be stored in the cache
+ * - returns:
+ *   -ENOMEM	- out of memory, nothing done
+ *   -ENOBUFS	- no backing object available in which to cache the page
+ *   0		- dispatched a write - it'll call end_io_func() when finished
+ *
+ * if the cookie still has a backing object at this point, that object can be
+ * in one of a few states with respect to storage processing:
+ *
+ *  (1) negative lookup, object not yet created (FSCACHE_COOKIE_CREATING is
+ *      set)
+ *
+ *	(a) no writes yet (set FSCACHE_COOKIE_PENDING_FILL and queue deferred
+ *	    fill op)
+ *
+ *	(b) writes deferred till post-creation (mark page for writing and
+ *	    return immediately)
+ *
+ *  (2) negative lookup, object created, initial fill being made from netfs
+ *      (FSCACHE_COOKIE_INITIAL_FILL is set)
+ *
+ *	(a) fill point not yet reached this page (mark page for writing and
+ *          return)
+ *
+ *	(b) fill point passed this page (queue op to store this page)
+ *
+ *  (3) object extant (queue op to store this page)
+ *
+ * any other state is invalid
+ */
+int __fscache_write_page(struct fscache_cookie *cookie,
+			 struct page *page,
+			 gfp_t gfp)
+{
+	struct fscache_storage *op;
+	struct fscache_object *object;
+	int ret;
+
+	_enter("%p,%x,", cookie, (u32) page->flags);
+
+	ASSERTCMP(cookie->def->type, !=, FSCACHE_COOKIE_TYPE_INDEX);
+	ASSERT(PageFsCache(page));
+
+	fscache_stat(&fscache_n_stores);
+
+	op = kzalloc(sizeof(*op), GFP_NOIO);
+	if (!op)
+		goto nomem;
+
+	fscache_operation_init(&op->op, fscache_release_write_op);
+	fscache_operation_init_slow(&op->op, fscache_write_op);
+	op->op.flags = FSCACHE_OP_SLOW | (1 << FSCACHE_OP_WAITING);
+
+	ret = radix_tree_preload(gfp & ~__GFP_HIGHMEM);
+	if (ret < 0)
+		goto nomem_free;
+
+	ret = -ENOBUFS;
+	spin_lock(&cookie->lock);
+
+	if (hlist_empty(&cookie->backing_objects))
+		goto nobufs;
+	object = hlist_entry(cookie->backing_objects.first,
+			     struct fscache_object, cookie_link);
+	if (test_bit(FSCACHE_IOERROR, &object->cache->flags))
+		goto nobufs;
+
+	/* add the page to the pending-storage radix tree on the backing
+	 * object */
+	spin_lock(&object->lock);
+
+	_debug("store limit %llx", (unsigned long long) object->store_limit);
+
+	ret = radix_tree_insert(&cookie->stores, page->index, page);
+	if (ret < 0) {
+		if (ret == -EEXIST)
+			goto already_queued;
+		_debug("insert failed %d", ret);
+		goto nobufs_unlock_obj;
+	}
+
+	radix_tree_tag_set(&cookie->stores, page->index,
+			   FSCACHE_COOKIE_PENDING_TAG);
+	page_cache_get(page);
+
+	/* we only want one writer at a time, but we do need to queue new
+	 * writers after exclusive ops */
+	if (test_and_set_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags))
+		goto already_pending;
+
+	spin_unlock(&object->lock);
+
+	op->op.debug_id	= atomic_inc_return(&fscache_op_debug_id);
+	op->store_limit = object->store_limit;
+
+	if (fscache_submit_op(object, &op->op) < 0)
+		goto submit_failed;
+
+	spin_unlock(&cookie->lock);
+	radix_tree_preload_end();
+	fscache_stat(&fscache_n_store_ops);
+	fscache_stat(&fscache_n_stores_ok);
+
+	/* the slow work queue now carries its own ref on the object */
+	fscache_put_operation(&op->op);
+	_leave(" = 0");
+	return 0;
+
+already_queued:
+	fscache_stat(&fscache_n_stores_again);
+already_pending:
+	spin_unlock(&object->lock);
+	spin_unlock(&cookie->lock);
+	radix_tree_preload_end();
+	kfree(op);
+	fscache_stat(&fscache_n_stores_ok);
+	_leave(" = 0");
+	return 0;
+
+submit_failed:
+	radix_tree_delete(&cookie->stores, page->index);
+	page_cache_release(page);
+	ret = -ENOBUFS;
+	goto nobufs;
+
+nobufs_unlock_obj:
+	spin_unlock(&object->lock);
+nobufs:
+	spin_unlock(&cookie->lock);
+	radix_tree_preload_end();
+	kfree(op);
+	fscache_stat(&fscache_n_stores_nobufs);
+	_leave(" = -ENOBUFS");
+	return -ENOBUFS;
+
+nomem_free:
+	kfree(op);
+nomem:
+	fscache_stat(&fscache_n_stores_oom);
+	_leave(" = -ENOMEM");
+	return -ENOMEM;
+}
+EXPORT_SYMBOL(__fscache_write_page);
+
+/*
+ * remove a page from the cache
+ */
+void __fscache_uncache_page(struct fscache_cookie *cookie, struct page *page)
+{
+	struct fscache_object *object;
+
+	_enter(",%p", page);
+
+	ASSERTCMP(cookie->def->type, !=, FSCACHE_COOKIE_TYPE_INDEX);
+	ASSERTCMP(page, !=, NULL);
+
+	fscache_stat(&fscache_n_uncaches);
+
+	/* cache withdrawal may beat us to it */
+	if (!PageFsCache(page))
+		goto done;
+
+	/* get the object */
+	spin_lock(&cookie->lock);
+
+	if (hlist_empty(&cookie->backing_objects)) {
+		ClearPageFsCache(page);
+		goto done_unlock;
+	}
+
+	object = hlist_entry(cookie->backing_objects.first,
+			     struct fscache_object, cookie_link);
+
+	/* there might now be stuff on disk we could read */
+	clear_bit(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags);
+
+	/* only invoke the cache backend if we managed to mark the page
+	 * uncached here; this deals with synchronisation vs withdrawal */
+	if (TestClearPageFsCache(page) &&
+	    object->cache->ops->uncache_page) {
+		/* the cache backend releases the cookie lock */
+		object->cache->ops->uncache_page(object, page);
+		goto done;
+	}
+
+done_unlock:
+	spin_unlock(&cookie->lock);
+done:
+	_leave("");
+}
+EXPORT_SYMBOL(__fscache_uncache_page);
+
+/**
+ * fscache_mark_pages_cached - Mark pages as being cached
+ * @op: The retrieval op pages are being marked for
+ * @pagevec: The pages to be marked
+ *
+ * Mark a bunch of netfs pages as being cached.  After this is called,
+ * the netfs must call fscache_uncache_page() to remove the mark.
+ */
+void fscache_mark_pages_cached(struct fscache_retrieval *op,
+			       struct pagevec *pagevec)
+{
+	struct fscache_cookie *cookie = op->op.object->cookie;
+	unsigned long loop;
+
+#ifdef CONFIG_FSCACHE_STATS
+	atomic_add(pagevec->nr, &fscache_n_marks);
+#endif
+
+	for (loop = 0; loop < pagevec->nr; loop++) {
+		struct page *page = pagevec->pages[loop];
+
+		_debug("- mark %p{%lx}", page, page->index);
+		if (TestSetPageFsCache(page)) {
+			static bool once_only;
+			if (!once_only) {
+				once_only = true;
+				printk(KERN_WARNING "FS-Cache:"
+				       " Cookie type %s marked page %lx"
+				       " multiple times\n",
+				       cookie->def->name, page->index);
+			}
+		}
+	}
+
+	if (cookie->def->mark_pages_cached)
+		cookie->def->mark_pages_cached(cookie->netfs_data,
+					       op->mapping, pagevec);
+	pagevec_reinit(pagevec);
+}
+EXPORT_SYMBOL(fscache_mark_pages_cached);
diff --git a/fs/fscache/proc.c b/fs/fscache/proc.c
new file mode 100644
index 0000000..beeab44
--- /dev/null
+++ b/fs/fscache/proc.c
@@ -0,0 +1,68 @@
+/* FS-Cache statistics viewing interface
+ *
+ * Copyright (C) 2007 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define FSCACHE_DEBUG_LEVEL OPERATION
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include "internal.h"
+
+/*
+ * initialise the /proc/fs/fscache/ directory
+ */
+int __init fscache_proc_init(void)
+{
+	_enter("");
+
+	if (!proc_mkdir("fs/fscache", NULL))
+		goto error_dir;
+
+#ifdef CONFIG_FSCACHE_STATS
+	if (!proc_create("fs/fscache/stats", S_IFREG | 0444, NULL,
+			 &fscache_stats_fops))
+		goto error_stats;
+#endif
+
+#ifdef CONFIG_FSCACHE_HISTOGRAM
+	if (!proc_create("fs/fscache/histogram", S_IFREG | 0444, NULL,
+			 &fscache_histogram_fops))
+		goto error_histogram;
+#endif
+
+	_leave(" = 0");
+	return 0;
+
+#ifdef CONFIG_FSCACHE_HISTOGRAM
+error_histogram:
+#endif
+#ifdef CONFIG_FSCACHE_STATS
+	remove_proc_entry("fs/fscache/stats", NULL);
+error_stats:
+#endif
+	remove_proc_entry("fs/fscache", NULL);
+error_dir:
+	_leave(" = -ENOMEM");
+	return -ENOMEM;
+}
+
+/*
+ * clean up the /proc/fs/fscache/ directory
+ */
+void fscache_proc_cleanup(void)
+{
+#ifdef CONFIG_FSCACHE_HISTOGRAM
+	remove_proc_entry("fs/fscache/histogram", NULL);
+#endif
+#ifdef CONFIG_FSCACHE_STATS
+	remove_proc_entry("fs/fscache/stats", NULL);
+#endif
+	remove_proc_entry("fs/fscache", NULL);
+}
diff --git a/fs/fscache/stats.c b/fs/fscache/stats.c
new file mode 100644
index 0000000..65deb99
--- /dev/null
+++ b/fs/fscache/stats.c
@@ -0,0 +1,212 @@
+/* FS-Cache statistics
+ *
+ * Copyright (C) 2007 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define FSCACHE_DEBUG_LEVEL THREAD
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include "internal.h"
+
+/*
+ * operation counters
+ */
+atomic_t fscache_n_op_pend;
+atomic_t fscache_n_op_run;
+atomic_t fscache_n_op_enqueue;
+atomic_t fscache_n_op_requeue;
+atomic_t fscache_n_op_deferred_release;
+atomic_t fscache_n_op_release;
+atomic_t fscache_n_op_gc;
+
+atomic_t fscache_n_attr_changed;
+atomic_t fscache_n_attr_changed_ok;
+atomic_t fscache_n_attr_changed_nobufs;
+atomic_t fscache_n_attr_changed_nomem;
+atomic_t fscache_n_attr_changed_calls;
+
+atomic_t fscache_n_allocs;
+atomic_t fscache_n_allocs_ok;
+atomic_t fscache_n_allocs_wait;
+atomic_t fscache_n_allocs_nobufs;
+atomic_t fscache_n_alloc_ops;
+atomic_t fscache_n_alloc_op_waits;
+
+atomic_t fscache_n_retrievals;
+atomic_t fscache_n_retrievals_ok;
+atomic_t fscache_n_retrievals_wait;
+atomic_t fscache_n_retrievals_nodata;
+atomic_t fscache_n_retrievals_nobufs;
+atomic_t fscache_n_retrievals_intr;
+atomic_t fscache_n_retrievals_nomem;
+atomic_t fscache_n_retrieval_ops;
+atomic_t fscache_n_retrieval_op_waits;
+
+atomic_t fscache_n_stores;
+atomic_t fscache_n_stores_ok;
+atomic_t fscache_n_stores_again;
+atomic_t fscache_n_stores_nobufs;
+atomic_t fscache_n_stores_oom;
+atomic_t fscache_n_store_ops;
+atomic_t fscache_n_store_calls;
+
+atomic_t fscache_n_marks;
+atomic_t fscache_n_uncaches;
+
+atomic_t fscache_n_acquires;
+atomic_t fscache_n_acquires_null;
+atomic_t fscache_n_acquires_no_cache;
+atomic_t fscache_n_acquires_ok;
+atomic_t fscache_n_acquires_nobufs;
+atomic_t fscache_n_acquires_oom;
+
+atomic_t fscache_n_updates;
+atomic_t fscache_n_updates_null;
+atomic_t fscache_n_updates_run;
+
+atomic_t fscache_n_relinquishes;
+atomic_t fscache_n_relinquishes_null;
+atomic_t fscache_n_relinquishes_waitcrt;
+
+atomic_t fscache_n_cookie_index;
+atomic_t fscache_n_cookie_data;
+atomic_t fscache_n_cookie_special;
+
+atomic_t fscache_n_object_alloc;
+atomic_t fscache_n_object_no_alloc;
+atomic_t fscache_n_object_lookups;
+atomic_t fscache_n_object_lookups_negative;
+atomic_t fscache_n_object_lookups_positive;
+atomic_t fscache_n_object_created;
+atomic_t fscache_n_object_avail;
+atomic_t fscache_n_object_dead;
+
+atomic_t fscache_n_checkaux_none;
+atomic_t fscache_n_checkaux_okay;
+atomic_t fscache_n_checkaux_update;
+atomic_t fscache_n_checkaux_obsolete;
+
+/*
+ * display the general statistics
+ */
+static int fscache_stats_show(struct seq_file *m, void *v)
+{
+	seq_puts(m, "FS-Cache statistics\n");
+
+	seq_printf(m, "Cookies: idx=%u dat=%u spc=%u\n",
+		   atomic_read(&fscache_n_cookie_index),
+		   atomic_read(&fscache_n_cookie_data),
+		   atomic_read(&fscache_n_cookie_special));
+
+	seq_printf(m, "Objects: alc=%u nal=%u avl=%u ded=%u\n",
+		   atomic_read(&fscache_n_object_alloc),
+		   atomic_read(&fscache_n_object_no_alloc),
+		   atomic_read(&fscache_n_object_avail),
+		   atomic_read(&fscache_n_object_dead));
+	seq_printf(m, "ChkAux : non=%u ok=%u upd=%u obs=%u\n",
+		   atomic_read(&fscache_n_checkaux_none),
+		   atomic_read(&fscache_n_checkaux_okay),
+		   atomic_read(&fscache_n_checkaux_update),
+		   atomic_read(&fscache_n_checkaux_obsolete));
+
+	seq_printf(m, "Pages  : mrk=%u unc=%u\n",
+		   atomic_read(&fscache_n_marks),
+		   atomic_read(&fscache_n_uncaches));
+
+	seq_printf(m, "Acquire: n=%u nul=%u noc=%u ok=%u nbf=%u"
+		   " oom=%u\n",
+		   atomic_read(&fscache_n_acquires),
+		   atomic_read(&fscache_n_acquires_null),
+		   atomic_read(&fscache_n_acquires_no_cache),
+		   atomic_read(&fscache_n_acquires_ok),
+		   atomic_read(&fscache_n_acquires_nobufs),
+		   atomic_read(&fscache_n_acquires_oom));
+
+	seq_printf(m, "Lookups: n=%u neg=%u pos=%u crt=%u\n",
+		   atomic_read(&fscache_n_object_lookups),
+		   atomic_read(&fscache_n_object_lookups_negative),
+		   atomic_read(&fscache_n_object_lookups_positive),
+		   atomic_read(&fscache_n_object_created));
+
+	seq_printf(m, "Updates: n=%u nul=%u run=%u\n",
+		   atomic_read(&fscache_n_updates),
+		   atomic_read(&fscache_n_updates_null),
+		   atomic_read(&fscache_n_updates_run));
+
+	seq_printf(m, "Relinqs: n=%u nul=%u wcr=%u\n",
+		   atomic_read(&fscache_n_relinquishes),
+		   atomic_read(&fscache_n_relinquishes_null),
+		   atomic_read(&fscache_n_relinquishes_waitcrt));
+
+	seq_printf(m, "AttrChg: n=%u ok=%u nbf=%u oom=%u run=%u\n",
+		   atomic_read(&fscache_n_attr_changed),
+		   atomic_read(&fscache_n_attr_changed_ok),
+		   atomic_read(&fscache_n_attr_changed_nobufs),
+		   atomic_read(&fscache_n_attr_changed_nomem),
+		   atomic_read(&fscache_n_attr_changed_calls));
+
+	seq_printf(m, "Allocs : n=%u ok=%u wt=%u nbf=%u\n",
+		   atomic_read(&fscache_n_allocs),
+		   atomic_read(&fscache_n_allocs_ok),
+		   atomic_read(&fscache_n_allocs_wait),
+		   atomic_read(&fscache_n_allocs_nobufs));
+	seq_printf(m, "Allocs : ops=%u owt=%u\n",
+		   atomic_read(&fscache_n_alloc_ops),
+		   atomic_read(&fscache_n_alloc_op_waits));
+
+	seq_printf(m, "Retrvls: n=%u ok=%u wt=%u nod=%u nbf=%u"
+		   " int=%u oom=%u\n",
+		   atomic_read(&fscache_n_retrievals),
+		   atomic_read(&fscache_n_retrievals_ok),
+		   atomic_read(&fscache_n_retrievals_wait),
+		   atomic_read(&fscache_n_retrievals_nodata),
+		   atomic_read(&fscache_n_retrievals_nobufs),
+		   atomic_read(&fscache_n_retrievals_intr),
+		   atomic_read(&fscache_n_retrievals_nomem));
+	seq_printf(m, "Retrvls: ops=%u owt=%u\n",
+		   atomic_read(&fscache_n_retrieval_ops),
+		   atomic_read(&fscache_n_retrieval_op_waits));
+
+	seq_printf(m, "Stores : n=%u ok=%u agn=%u nbf=%u oom=%u\n",
+		   atomic_read(&fscache_n_stores),
+		   atomic_read(&fscache_n_stores_ok),
+		   atomic_read(&fscache_n_stores_again),
+		   atomic_read(&fscache_n_stores_nobufs),
+		   atomic_read(&fscache_n_stores_oom));
+	seq_printf(m, "Stores : ops=%u run=%u\n",
+		   atomic_read(&fscache_n_store_ops),
+		   atomic_read(&fscache_n_store_calls));
+
+	seq_printf(m, "Ops    : pend=%u run=%u enq=%u\n",
+		   atomic_read(&fscache_n_op_pend),
+		   atomic_read(&fscache_n_op_run),
+		   atomic_read(&fscache_n_op_enqueue));
+	seq_printf(m, "Ops    : dfr=%u rel=%u gc=%u\n",
+		   atomic_read(&fscache_n_op_deferred_release),
+		   atomic_read(&fscache_n_op_release),
+		   atomic_read(&fscache_n_op_gc));
+	return 0;
+}
+
+/*
+ * open "/proc/fs/fscache/stats" allowing provision of a statistical summary
+ */
+static int fscache_stats_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, fscache_stats_show, NULL);
+}
+
+const struct file_operations fscache_stats_fops = {
+	.owner		= THIS_MODULE,
+	.open		= fscache_stats_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release,
+};
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 06da052..8b8eebc 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1032,6 +1032,7 @@
 		fuse_put_request(fc, req);
 		return -ENOMEM;
 	}
+	req->out.argpages = 1;
 	req->num_pages = 1;
 	req->pages[0] = page;
 	fuse_read_fill(req, file, inode, file->f_pos, PAGE_SIZE, FUSE_READDIR);
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 4e340fe..2b25133 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -386,7 +386,6 @@
 	req->in.numargs = 1;
 	req->in.args[0].size = sizeof(struct fuse_read_in);
 	req->in.args[0].value = inarg;
-	req->out.argpages = 1;
 	req->out.argvar = 1;
 	req->out.numargs = 1;
 	req->out.args[0].size = count;
@@ -453,6 +452,7 @@
 	attr_ver = fuse_get_attr_version(fc);
 
 	req->out.page_zeroing = 1;
+	req->out.argpages = 1;
 	req->num_pages = 1;
 	req->pages[0] = page;
 	num_read = fuse_send_read(req, file, inode, pos, count, NULL);
@@ -510,6 +510,8 @@
 	struct fuse_conn *fc = get_fuse_conn(inode);
 	loff_t pos = page_offset(req->pages[0]);
 	size_t count = req->num_pages << PAGE_CACHE_SHIFT;
+
+	req->out.argpages = 1;
 	req->out.page_zeroing = 1;
 	fuse_read_fill(req, file, inode, pos, count, FUSE_READ);
 	req->misc.read.attr_ver = fuse_get_attr_version(fc);
@@ -621,7 +623,6 @@
 	inarg->flags = file ? file->f_flags : 0;
 	req->in.h.opcode = FUSE_WRITE;
 	req->in.h.nodeid = get_node_id(inode);
-	req->in.argpages = 1;
 	req->in.numargs = 2;
 	if (fc->minor < 9)
 		req->in.args[0].size = FUSE_COMPAT_WRITE_IN_SIZE;
@@ -695,6 +696,7 @@
 	if (IS_ERR(req))
 		return PTR_ERR(req);
 
+	req->in.argpages = 1;
 	req->num_pages = 1;
 	req->pages[0] = page;
 	req->page_offset = offset;
@@ -771,6 +773,7 @@
 	size_t count = 0;
 	int err;
 
+	req->in.argpages = 1;
 	req->page_offset = offset;
 
 	do {
@@ -935,21 +938,28 @@
 }
 
 static int fuse_get_user_pages(struct fuse_req *req, const char __user *buf,
-			       unsigned nbytes, int write)
+			       unsigned *nbytesp, int write)
 {
+	unsigned nbytes = *nbytesp;
 	unsigned long user_addr = (unsigned long) buf;
 	unsigned offset = user_addr & ~PAGE_MASK;
 	int npages;
 
-	/* This doesn't work with nfsd */
-	if (!current->mm)
-		return -EPERM;
+	/* Special case for kernel I/O: can copy directly into the buffer */
+	if (segment_eq(get_fs(), KERNEL_DS)) {
+		if (write)
+			req->in.args[1].value = (void *) user_addr;
+		else
+			req->out.args[0].value = (void *) user_addr;
+
+		return 0;
+	}
 
 	nbytes = min(nbytes, (unsigned) FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT);
 	npages = (nbytes + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
 	npages = clamp(npages, 1, FUSE_MAX_PAGES_PER_REQ);
 	down_read(&current->mm->mmap_sem);
-	npages = get_user_pages(current, current->mm, user_addr, npages, write,
+	npages = get_user_pages(current, current->mm, user_addr, npages, !write,
 				0, req->pages, NULL);
 	up_read(&current->mm->mmap_sem);
 	if (npages < 0)
@@ -957,6 +967,15 @@
 
 	req->num_pages = npages;
 	req->page_offset = offset;
+
+	if (write)
+		req->in.argpages = 1;
+	else
+		req->out.argpages = 1;
+
+	nbytes = (req->num_pages << PAGE_SHIFT) - req->page_offset;
+	*nbytesp = min(*nbytesp, nbytes);
+
 	return 0;
 }
 
@@ -979,15 +998,13 @@
 
 	while (count) {
 		size_t nres;
-		size_t nbytes_limit = min(count, nmax);
-		size_t nbytes;
-		int err = fuse_get_user_pages(req, buf, nbytes_limit, !write);
+		size_t nbytes = min(count, nmax);
+		int err = fuse_get_user_pages(req, buf, &nbytes, write);
 		if (err) {
 			res = err;
 			break;
 		}
-		nbytes = (req->num_pages << PAGE_SHIFT) - req->page_offset;
-		nbytes = min(nbytes_limit, nbytes);
+
 		if (write)
 			nres = fuse_send_write(req, file, inode, pos, nbytes,
 					       current->files);
@@ -1163,6 +1180,7 @@
 	fuse_write_fill(req, NULL, ff, inode, page_offset(page), 0, 1);
 
 	copy_highpage(tmp_page, page);
+	req->in.argpages = 1;
 	req->num_pages = 1;
 	req->pages[0] = tmp_page;
 	req->page_offset = 0;
@@ -1274,6 +1292,15 @@
 	return 0;
 }
 
+static int fuse_direct_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	/* Can't provide the coherency needed for MAP_SHARED */
+	if (vma->vm_flags & VM_MAYSHARE)
+		return -ENODEV;
+
+	return generic_file_mmap(file, vma);
+}
+
 static int convert_fuse_file_lock(const struct fuse_file_lock *ffl,
 				  struct file_lock *fl)
 {
@@ -1908,6 +1935,7 @@
 	.llseek		= fuse_file_llseek,
 	.read		= fuse_direct_read,
 	.write		= fuse_direct_write,
+	.mmap		= fuse_direct_mmap,
 	.open		= fuse_open,
 	.flush		= fuse_flush,
 	.release	= fuse_release,
@@ -1917,7 +1945,7 @@
 	.unlocked_ioctl	= fuse_file_ioctl,
 	.compat_ioctl	= fuse_file_compat_ioctl,
 	.poll		= fuse_file_poll,
-	/* no mmap and splice_read */
+	/* no splice_read */
 };
 
 static const struct address_space_operations fuse_file_aops  = {
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index 3fbffb1..a8e8513 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -20,6 +20,7 @@
 #include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/pagemap.h>
+#include <linux/bio.h>
 
 /*
  * Default IO end handler for temporary BJ_IO buffer_heads.
@@ -171,14 +172,15 @@
 	return (ret == -EIO);
 }
 
-static void journal_do_submit_data(struct buffer_head **wbuf, int bufs)
+static void journal_do_submit_data(struct buffer_head **wbuf, int bufs,
+				   int write_op)
 {
 	int i;
 
 	for (i = 0; i < bufs; i++) {
 		wbuf[i]->b_end_io = end_buffer_write_sync;
 		/* We use-up our safety reference in submit_bh() */
-		submit_bh(WRITE, wbuf[i]);
+		submit_bh(write_op, wbuf[i]);
 	}
 }
 
@@ -186,7 +188,8 @@
  *  Submit all the data buffers to disk
  */
 static int journal_submit_data_buffers(journal_t *journal,
-				transaction_t *commit_transaction)
+				       transaction_t *commit_transaction,
+				       int write_op)
 {
 	struct journal_head *jh;
 	struct buffer_head *bh;
@@ -225,7 +228,7 @@
 				BUFFER_TRACE(bh, "needs blocking lock");
 				spin_unlock(&journal->j_list_lock);
 				/* Write out all data to prevent deadlocks */
-				journal_do_submit_data(wbuf, bufs);
+				journal_do_submit_data(wbuf, bufs, write_op);
 				bufs = 0;
 				lock_buffer(bh);
 				spin_lock(&journal->j_list_lock);
@@ -256,7 +259,7 @@
 			jbd_unlock_bh_state(bh);
 			if (bufs == journal->j_wbufsize) {
 				spin_unlock(&journal->j_list_lock);
-				journal_do_submit_data(wbuf, bufs);
+				journal_do_submit_data(wbuf, bufs, write_op);
 				bufs = 0;
 				goto write_out_data;
 			}
@@ -286,7 +289,7 @@
 		}
 	}
 	spin_unlock(&journal->j_list_lock);
-	journal_do_submit_data(wbuf, bufs);
+	journal_do_submit_data(wbuf, bufs, write_op);
 
 	return err;
 }
@@ -315,6 +318,7 @@
 	int first_tag = 0;
 	int tag_flag;
 	int i;
+	int write_op = WRITE;
 
 	/*
 	 * First job: lock down the current transaction and wait for
@@ -347,6 +351,13 @@
 	spin_lock(&journal->j_state_lock);
 	commit_transaction->t_state = T_LOCKED;
 
+	/*
+	 * Use plugged writes here, since we want to submit several before
+	 * we unplug the device. We don't do explicit unplugging in here,
+	 * instead we rely on sync_buffer() doing the unplug for us.
+	 */
+	if (commit_transaction->t_synchronous_commit)
+		write_op = WRITE_SYNC_PLUG;
 	spin_lock(&commit_transaction->t_handle_lock);
 	while (commit_transaction->t_updates) {
 		DEFINE_WAIT(wait);
@@ -431,7 +442,8 @@
 	 * Now start flushing things to disk, in the order they appear
 	 * on the transaction lists.  Data blocks go first.
 	 */
-	err = journal_submit_data_buffers(journal, commit_transaction);
+	err = journal_submit_data_buffers(journal, commit_transaction,
+					  write_op);
 
 	/*
 	 * Wait for all previously submitted IO to complete.
@@ -660,7 +672,7 @@
 				clear_buffer_dirty(bh);
 				set_buffer_uptodate(bh);
 				bh->b_end_io = journal_end_buffer_io_sync;
-				submit_bh(WRITE, bh);
+				submit_bh(write_op, bh);
 			}
 			cond_resched();
 
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index e6a1174..ed886e6 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -1440,6 +1440,8 @@
 		}
 	}
 
+	if (handle->h_sync)
+		transaction->t_synchronous_commit = 1;
 	current->journal_info = NULL;
 	spin_lock(&journal->j_state_lock);
 	spin_lock(&transaction->t_handle_lock);
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index 4ea7237..073c8c3 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -138,7 +138,7 @@
 		set_buffer_ordered(bh);
 		barrier_done = 1;
 	}
-	ret = submit_bh(WRITE_SYNC, bh);
+	ret = submit_bh(WRITE_SYNC_PLUG, bh);
 	if (barrier_done)
 		clear_buffer_ordered(bh);
 
@@ -159,7 +159,7 @@
 		lock_buffer(bh);
 		set_buffer_uptodate(bh);
 		clear_buffer_dirty(bh);
-		ret = submit_bh(WRITE_SYNC, bh);
+		ret = submit_bh(WRITE_SYNC_PLUG, bh);
 	}
 	*cbh = bh;
 	return ret;
@@ -190,7 +190,7 @@
 		set_buffer_uptodate(bh);
 		bh->b_end_io = journal_end_buffer_io_sync;
 
-		ret = submit_bh(WRITE_SYNC, bh);
+		ret = submit_bh(WRITE_SYNC_PLUG, bh);
 		if (ret) {
 			unlock_buffer(bh);
 			return ret;
@@ -402,8 +402,13 @@
 	spin_lock(&journal->j_state_lock);
 	commit_transaction->t_state = T_LOCKED;
 
+	/*
+	 * Use plugged writes here, since we want to submit several before
+	 * we unplug the device. We don't do explicit unplugging in here,
+	 * instead we rely on sync_buffer() doing the unplug for us.
+	 */
 	if (commit_transaction->t_synchronous_commit)
-		write_op = WRITE_SYNC;
+		write_op = WRITE_SYNC_PLUG;
 	stats.u.run.rs_wait = commit_transaction->t_max_wait;
 	stats.u.run.rs_locked = jiffies;
 	stats.u.run.rs_running = jbd2_time_diff(commit_transaction->t_start,
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
index 36fe20d..e67f3ec 100644
--- a/fs/nfs/Kconfig
+++ b/fs/nfs/Kconfig
@@ -84,3 +84,11 @@
 	  <file:Documentation/filesystems/nfsroot.txt>.
 
 	  Most people say N here.
+
+config NFS_FSCACHE
+	bool "Provide NFS client caching support (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	depends on NFS_FS=m && FSCACHE || NFS_FS=y && FSCACHE=y
+	help
+	  Say Y here if you want NFS data to be cached locally on disc through
+	  the general filesystem cache manager
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index ac6170c..8451598 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -15,3 +15,4 @@
 			   callback.o callback_xdr.o callback_proc.o \
 			   nfs4namespace.o
 nfs-$(CONFIG_SYSCTL) += sysctl.o
+nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index aba3801..75c9cd2 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -45,6 +45,7 @@
 #include "delegation.h"
 #include "iostat.h"
 #include "internal.h"
+#include "fscache.h"
 
 #define NFSDBG_FACILITY		NFSDBG_CLIENT
 
@@ -154,6 +155,8 @@
 	if (!IS_ERR(cred))
 		clp->cl_machine_cred = cred;
 
+	nfs_fscache_get_client_cookie(clp);
+
 	return clp;
 
 error_3:
@@ -187,6 +190,8 @@
 
 	nfs4_shutdown_client(clp);
 
+	nfs_fscache_release_client_cookie(clp);
+
 	/* -EIO all pending I/O */
 	if (!IS_ERR(clp->cl_rpcclient))
 		rpc_shutdown_client(clp->cl_rpcclient);
@@ -760,6 +765,7 @@
 
 	/* Initialise the client representation from the mount data */
 	server->flags = data->flags;
+	server->options = data->options;
 
 	if (data->rsize)
 		server->rsize = nfs_block_size(data->rsize, NULL);
@@ -1148,6 +1154,7 @@
 	/* Initialise the client representation from the mount data */
 	server->flags = data->flags;
 	server->caps |= NFS_CAP_ATOMIC_OPEN;
+	server->options = data->options;
 
 	/* Get a client record */
 	error = nfs4_set_client(server,
@@ -1559,7 +1566,7 @@
 
 	/* display header on line 1 */
 	if (v == &nfs_volume_list) {
-		seq_puts(m, "NV SERVER   PORT DEV     FSID\n");
+		seq_puts(m, "NV SERVER   PORT DEV     FSID              FSC\n");
 		return 0;
 	}
 	/* display one transport per line on subsequent lines */
@@ -1573,12 +1580,13 @@
 		 (unsigned long long) server->fsid.major,
 		 (unsigned long long) server->fsid.minor);
 
-	seq_printf(m, "v%u %s %s %-7s %-17s\n",
+	seq_printf(m, "v%u %s %s %-7s %-17s %s\n",
 		   clp->rpc_ops->version,
 		   rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_ADDR),
 		   rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_HEX_PORT),
 		   dev,
-		   fsid);
+		   fsid,
+		   nfs_server_fscache_state(server));
 
 	return 0;
 }
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 0abf3f3..3523b89 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -35,6 +35,7 @@
 #include "delegation.h"
 #include "internal.h"
 #include "iostat.h"
+#include "fscache.h"
 
 #define NFSDBG_FACILITY		NFSDBG_FILE
 
@@ -409,6 +410,13 @@
 	return copied;
 }
 
+/*
+ * Partially or wholly invalidate a page
+ * - Release the private state associated with a page if undergoing complete
+ *   page invalidation
+ * - Called if either PG_private or PG_fscache is set on the page
+ * - Caller holds page lock
+ */
 static void nfs_invalidate_page(struct page *page, unsigned long offset)
 {
 	dfprintk(PAGECACHE, "NFS: invalidate_page(%p, %lu)\n", page, offset);
@@ -417,23 +425,43 @@
 		return;
 	/* Cancel any unstarted writes on this page */
 	nfs_wb_page_cancel(page->mapping->host, page);
+
+	nfs_fscache_invalidate_page(page, page->mapping->host);
 }
 
+/*
+ * Attempt to release the private state associated with a page
+ * - Called if either PG_private or PG_fscache is set on the page
+ * - Caller holds page lock
+ * - Return true (may release page) or false (may not)
+ */
 static int nfs_release_page(struct page *page, gfp_t gfp)
 {
 	dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page);
 
 	/* If PagePrivate() is set, then the page is not freeable */
-	return 0;
+	if (PagePrivate(page))
+		return 0;
+	return nfs_fscache_release_page(page, gfp);
 }
 
+/*
+ * Attempt to clear the private state associated with a page when an error
+ * occurs that requires the cached contents of an inode to be written back or
+ * destroyed
+ * - Called if either PG_private or fscache is set on the page
+ * - Caller holds page lock
+ * - Return 0 if successful, -error otherwise
+ */
 static int nfs_launder_page(struct page *page)
 {
 	struct inode *inode = page->mapping->host;
+	struct nfs_inode *nfsi = NFS_I(inode);
 
 	dfprintk(PAGECACHE, "NFS: launder_page(%ld, %llu)\n",
 		inode->i_ino, (long long)page_offset(page));
 
+	nfs_fscache_wait_on_page_write(nfsi, page);
 	return nfs_wb_page(inode, page);
 }
 
@@ -451,6 +479,11 @@
 	.launder_page = nfs_launder_page,
 };
 
+/*
+ * Notification that a PTE pointing to an NFS page is about to be made
+ * writable, implying that someone is about to modify the page through a
+ * shared-writable mapping
+ */
 static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
 	struct page *page = vmf->page;
@@ -465,6 +498,9 @@
 		filp->f_mapping->host->i_ino,
 		(long long)page_offset(page));
 
+	/* make sure the cache has finished storing the page */
+	nfs_fscache_wait_on_page_write(NFS_I(dentry->d_inode), page);
+
 	lock_page(page);
 	mapping = page->mapping;
 	if (mapping != dentry->d_inode->i_mapping)
diff --git a/fs/nfs/fscache-index.c b/fs/nfs/fscache-index.c
new file mode 100644
index 0000000..5b10064
--- /dev/null
+++ b/fs/nfs/fscache-index.c
@@ -0,0 +1,337 @@
+/* NFS FS-Cache index structure definition
+ *
+ * Copyright (C) 2008 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 <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/nfs_fs.h>
+#include <linux/nfs_fs_sb.h>
+#include <linux/in6.h>
+
+#include "internal.h"
+#include "fscache.h"
+
+#define NFSDBG_FACILITY		NFSDBG_FSCACHE
+
+/*
+ * Define the NFS filesystem for FS-Cache.  Upon registration FS-Cache sticks
+ * the cookie for the top-level index object for NFS into here.  The top-level
+ * index can than have other cache objects inserted into it.
+ */
+struct fscache_netfs nfs_fscache_netfs = {
+	.name		= "nfs",
+	.version	= 0,
+};
+
+/*
+ * Register NFS for caching
+ */
+int nfs_fscache_register(void)
+{
+	return fscache_register_netfs(&nfs_fscache_netfs);
+}
+
+/*
+ * Unregister NFS for caching
+ */
+void nfs_fscache_unregister(void)
+{
+	fscache_unregister_netfs(&nfs_fscache_netfs);
+}
+
+/*
+ * Layout of the key for an NFS server cache object.
+ */
+struct nfs_server_key {
+	uint16_t	nfsversion;		/* NFS protocol version */
+	uint16_t	family;			/* address family */
+	uint16_t	port;			/* IP port */
+	union {
+		struct in_addr	ipv4_addr;	/* IPv4 address */
+		struct in6_addr ipv6_addr;	/* IPv6 address */
+	} addr[0];
+};
+
+/*
+ * Generate a key to describe a server in the main NFS index
+ * - We return the length of the key, or 0 if we can't generate one
+ */
+static uint16_t nfs_server_get_key(const void *cookie_netfs_data,
+				   void *buffer, uint16_t bufmax)
+{
+	const struct nfs_client *clp = cookie_netfs_data;
+	const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &clp->cl_addr;
+	const struct sockaddr_in *sin = (struct sockaddr_in *) &clp->cl_addr;
+	struct nfs_server_key *key = buffer;
+	uint16_t len = sizeof(struct nfs_server_key);
+
+	key->nfsversion = clp->rpc_ops->version;
+	key->family = clp->cl_addr.ss_family;
+
+	memset(key, 0, len);
+
+	switch (clp->cl_addr.ss_family) {
+	case AF_INET:
+		key->port = sin->sin_port;
+		key->addr[0].ipv4_addr = sin->sin_addr;
+		len += sizeof(key->addr[0].ipv4_addr);
+		break;
+
+	case AF_INET6:
+		key->port = sin6->sin6_port;
+		key->addr[0].ipv6_addr = sin6->sin6_addr;
+		len += sizeof(key->addr[0].ipv6_addr);
+		break;
+
+	default:
+		printk(KERN_WARNING "NFS: Unknown network family '%d'\n",
+		       clp->cl_addr.ss_family);
+		len = 0;
+		break;
+	}
+
+	return len;
+}
+
+/*
+ * Define the server object for FS-Cache.  This is used to describe a server
+ * object to fscache_acquire_cookie().  It is keyed by the NFS protocol and
+ * server address parameters.
+ */
+const struct fscache_cookie_def nfs_fscache_server_index_def = {
+	.name		= "NFS.server",
+	.type 		= FSCACHE_COOKIE_TYPE_INDEX,
+	.get_key	= nfs_server_get_key,
+};
+
+/*
+ * Generate a key to describe a superblock key in the main NFS index
+ */
+static uint16_t nfs_super_get_key(const void *cookie_netfs_data,
+				  void *buffer, uint16_t bufmax)
+{
+	const struct nfs_fscache_key *key;
+	const struct nfs_server *nfss = cookie_netfs_data;
+	uint16_t len;
+
+	key = nfss->fscache_key;
+	len = sizeof(key->key) + key->key.uniq_len;
+	if (len > bufmax) {
+		len = 0;
+	} else {
+		memcpy(buffer, &key->key, sizeof(key->key));
+		memcpy(buffer + sizeof(key->key),
+		       key->key.uniquifier, key->key.uniq_len);
+	}
+
+	return len;
+}
+
+/*
+ * Define the superblock object for FS-Cache.  This is used to describe a
+ * superblock object to fscache_acquire_cookie().  It is keyed by all the NFS
+ * parameters that might cause a separate superblock.
+ */
+const struct fscache_cookie_def nfs_fscache_super_index_def = {
+	.name		= "NFS.super",
+	.type 		= FSCACHE_COOKIE_TYPE_INDEX,
+	.get_key	= nfs_super_get_key,
+};
+
+/*
+ * Definition of the auxiliary data attached to NFS inode storage objects
+ * within the cache.
+ *
+ * The contents of this struct are recorded in the on-disk local cache in the
+ * auxiliary data attached to the data storage object backing an inode.  This
+ * permits coherency to be managed when a new inode binds to an already extant
+ * cache object.
+ */
+struct nfs_fscache_inode_auxdata {
+	struct timespec	mtime;
+	struct timespec	ctime;
+	loff_t		size;
+	u64		change_attr;
+};
+
+/*
+ * Generate a key to describe an NFS inode in an NFS server's index
+ */
+static uint16_t nfs_fscache_inode_get_key(const void *cookie_netfs_data,
+					  void *buffer, uint16_t bufmax)
+{
+	const struct nfs_inode *nfsi = cookie_netfs_data;
+	uint16_t nsize;
+
+	/* use the inode's NFS filehandle as the key */
+	nsize = nfsi->fh.size;
+	memcpy(buffer, nfsi->fh.data, nsize);
+	return nsize;
+}
+
+/*
+ * Get certain file attributes from the netfs data
+ * - This function can be absent for an index
+ * - Not permitted to return an error
+ * - The netfs data from the cookie being used as the source is presented
+ */
+static void nfs_fscache_inode_get_attr(const void *cookie_netfs_data,
+				       uint64_t *size)
+{
+	const struct nfs_inode *nfsi = cookie_netfs_data;
+
+	*size = nfsi->vfs_inode.i_size;
+}
+
+/*
+ * Get the auxiliary data from netfs data
+ * - This function can be absent if the index carries no state data
+ * - Should store the auxiliary data in the buffer
+ * - Should return the amount of amount stored
+ * - Not permitted to return an error
+ * - The netfs data from the cookie being used as the source is presented
+ */
+static uint16_t nfs_fscache_inode_get_aux(const void *cookie_netfs_data,
+					  void *buffer, uint16_t bufmax)
+{
+	struct nfs_fscache_inode_auxdata auxdata;
+	const struct nfs_inode *nfsi = cookie_netfs_data;
+
+	memset(&auxdata, 0, sizeof(auxdata));
+	auxdata.size = nfsi->vfs_inode.i_size;
+	auxdata.mtime = nfsi->vfs_inode.i_mtime;
+	auxdata.ctime = nfsi->vfs_inode.i_ctime;
+
+	if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4)
+		auxdata.change_attr = nfsi->change_attr;
+
+	if (bufmax > sizeof(auxdata))
+		bufmax = sizeof(auxdata);
+
+	memcpy(buffer, &auxdata, bufmax);
+	return bufmax;
+}
+
+/*
+ * Consult the netfs about the state of an object
+ * - This function can be absent if the index carries no state data
+ * - The netfs data from the cookie being used as the target is
+ *   presented, as is the auxiliary data
+ */
+static
+enum fscache_checkaux nfs_fscache_inode_check_aux(void *cookie_netfs_data,
+						  const void *data,
+						  uint16_t datalen)
+{
+	struct nfs_fscache_inode_auxdata auxdata;
+	struct nfs_inode *nfsi = cookie_netfs_data;
+
+	if (datalen != sizeof(auxdata))
+		return FSCACHE_CHECKAUX_OBSOLETE;
+
+	memset(&auxdata, 0, sizeof(auxdata));
+	auxdata.size = nfsi->vfs_inode.i_size;
+	auxdata.mtime = nfsi->vfs_inode.i_mtime;
+	auxdata.ctime = nfsi->vfs_inode.i_ctime;
+
+	if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4)
+		auxdata.change_attr = nfsi->change_attr;
+
+	if (memcmp(data, &auxdata, datalen) != 0)
+		return FSCACHE_CHECKAUX_OBSOLETE;
+
+	return FSCACHE_CHECKAUX_OKAY;
+}
+
+/*
+ * Indication from FS-Cache that the cookie is no longer cached
+ * - This function is called when the backing store currently caching a cookie
+ *   is removed
+ * - The netfs should use this to clean up any markers indicating cached pages
+ * - This is mandatory for any object that may have data
+ */
+static void nfs_fscache_inode_now_uncached(void *cookie_netfs_data)
+{
+	struct nfs_inode *nfsi = cookie_netfs_data;
+	struct pagevec pvec;
+	pgoff_t first;
+	int loop, nr_pages;
+
+	pagevec_init(&pvec, 0);
+	first = 0;
+
+	dprintk("NFS: nfs_inode_now_uncached: nfs_inode 0x%p\n", nfsi);
+
+	for (;;) {
+		/* grab a bunch of pages to unmark */
+		nr_pages = pagevec_lookup(&pvec,
+					  nfsi->vfs_inode.i_mapping,
+					  first,
+					  PAGEVEC_SIZE - pagevec_count(&pvec));
+		if (!nr_pages)
+			break;
+
+		for (loop = 0; loop < nr_pages; loop++)
+			ClearPageFsCache(pvec.pages[loop]);
+
+		first = pvec.pages[nr_pages - 1]->index + 1;
+
+		pvec.nr = nr_pages;
+		pagevec_release(&pvec);
+		cond_resched();
+	}
+}
+
+/*
+ * Get an extra reference on a read context.
+ * - This function can be absent if the completion function doesn't require a
+ *   context.
+ * - The read context is passed back to NFS in the event that a data read on the
+ *   cache fails with EIO - in which case the server must be contacted to
+ *   retrieve the data, which requires the read context for security.
+ */
+static void nfs_fh_get_context(void *cookie_netfs_data, void *context)
+{
+	get_nfs_open_context(context);
+}
+
+/*
+ * Release an extra reference on a read context.
+ * - This function can be absent if the completion function doesn't require a
+ *   context.
+ */
+static void nfs_fh_put_context(void *cookie_netfs_data, void *context)
+{
+	if (context)
+		put_nfs_open_context(context);
+}
+
+/*
+ * Define the inode object for FS-Cache.  This is used to describe an inode
+ * object to fscache_acquire_cookie().  It is keyed by the NFS file handle for
+ * an inode.
+ *
+ * Coherency is managed by comparing the copies of i_size, i_mtime and i_ctime
+ * held in the cache auxiliary data for the data storage object with those in
+ * the inode struct in memory.
+ */
+const struct fscache_cookie_def nfs_fscache_inode_object_def = {
+	.name		= "NFS.fh",
+	.type		= FSCACHE_COOKIE_TYPE_DATAFILE,
+	.get_key	= nfs_fscache_inode_get_key,
+	.get_attr	= nfs_fscache_inode_get_attr,
+	.get_aux	= nfs_fscache_inode_get_aux,
+	.check_aux	= nfs_fscache_inode_check_aux,
+	.now_uncached	= nfs_fscache_inode_now_uncached,
+	.get_context	= nfs_fh_get_context,
+	.put_context	= nfs_fh_put_context,
+};
diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c
new file mode 100644
index 0000000..379be67
--- /dev/null
+++ b/fs/nfs/fscache.c
@@ -0,0 +1,523 @@
+/* NFS filesystem cache interface
+ *
+ * Copyright (C) 2008 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 <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/nfs_fs.h>
+#include <linux/nfs_fs_sb.h>
+#include <linux/in6.h>
+#include <linux/seq_file.h>
+
+#include "internal.h"
+#include "iostat.h"
+#include "fscache.h"
+
+#define NFSDBG_FACILITY		NFSDBG_FSCACHE
+
+static struct rb_root nfs_fscache_keys = RB_ROOT;
+static DEFINE_SPINLOCK(nfs_fscache_keys_lock);
+
+/*
+ * Get the per-client index cookie for an NFS client if the appropriate mount
+ * flag was set
+ * - We always try and get an index cookie for the client, but get filehandle
+ *   cookies on a per-superblock basis, depending on the mount flags
+ */
+void nfs_fscache_get_client_cookie(struct nfs_client *clp)
+{
+	/* create a cache index for looking up filehandles */
+	clp->fscache = fscache_acquire_cookie(nfs_fscache_netfs.primary_index,
+					      &nfs_fscache_server_index_def,
+					      clp);
+	dfprintk(FSCACHE, "NFS: get client cookie (0x%p/0x%p)\n",
+		 clp, clp->fscache);
+}
+
+/*
+ * Dispose of a per-client cookie
+ */
+void nfs_fscache_release_client_cookie(struct nfs_client *clp)
+{
+	dfprintk(FSCACHE, "NFS: releasing client cookie (0x%p/0x%p)\n",
+		 clp, clp->fscache);
+
+	fscache_relinquish_cookie(clp->fscache, 0);
+	clp->fscache = NULL;
+}
+
+/*
+ * Get the cache cookie for an NFS superblock.  We have to handle
+ * uniquification here because the cache doesn't do it for us.
+ */
+void nfs_fscache_get_super_cookie(struct super_block *sb,
+				  struct nfs_parsed_mount_data *data)
+{
+	struct nfs_fscache_key *key, *xkey;
+	struct nfs_server *nfss = NFS_SB(sb);
+	struct rb_node **p, *parent;
+	const char *uniq = data->fscache_uniq ?: "";
+	int diff, ulen;
+
+	ulen = strlen(uniq);
+	key = kzalloc(sizeof(*key) + ulen, GFP_KERNEL);
+	if (!key)
+		return;
+
+	key->nfs_client = nfss->nfs_client;
+	key->key.super.s_flags = sb->s_flags & NFS_MS_MASK;
+	key->key.nfs_server.flags = nfss->flags;
+	key->key.nfs_server.rsize = nfss->rsize;
+	key->key.nfs_server.wsize = nfss->wsize;
+	key->key.nfs_server.acregmin = nfss->acregmin;
+	key->key.nfs_server.acregmax = nfss->acregmax;
+	key->key.nfs_server.acdirmin = nfss->acdirmin;
+	key->key.nfs_server.acdirmax = nfss->acdirmax;
+	key->key.nfs_server.fsid = nfss->fsid;
+	key->key.rpc_auth.au_flavor = nfss->client->cl_auth->au_flavor;
+
+	key->key.uniq_len = ulen;
+	memcpy(key->key.uniquifier, uniq, ulen);
+
+	spin_lock(&nfs_fscache_keys_lock);
+	p = &nfs_fscache_keys.rb_node;
+	parent = NULL;
+	while (*p) {
+		parent = *p;
+		xkey = rb_entry(parent, struct nfs_fscache_key, node);
+
+		if (key->nfs_client < xkey->nfs_client)
+			goto go_left;
+		if (key->nfs_client > xkey->nfs_client)
+			goto go_right;
+
+		diff = memcmp(&key->key, &xkey->key, sizeof(key->key));
+		if (diff < 0)
+			goto go_left;
+		if (diff > 0)
+			goto go_right;
+
+		if (key->key.uniq_len == 0)
+			goto non_unique;
+		diff = memcmp(key->key.uniquifier,
+			      xkey->key.uniquifier,
+			      key->key.uniq_len);
+		if (diff < 0)
+			goto go_left;
+		if (diff > 0)
+			goto go_right;
+		goto non_unique;
+
+	go_left:
+		p = &(*p)->rb_left;
+		continue;
+	go_right:
+		p = &(*p)->rb_right;
+	}
+
+	rb_link_node(&key->node, parent, p);
+	rb_insert_color(&key->node, &nfs_fscache_keys);
+	spin_unlock(&nfs_fscache_keys_lock);
+	nfss->fscache_key = key;
+
+	/* create a cache index for looking up filehandles */
+	nfss->fscache = fscache_acquire_cookie(nfss->nfs_client->fscache,
+					       &nfs_fscache_super_index_def,
+					       nfss);
+	dfprintk(FSCACHE, "NFS: get superblock cookie (0x%p/0x%p)\n",
+		 nfss, nfss->fscache);
+	return;
+
+non_unique:
+	spin_unlock(&nfs_fscache_keys_lock);
+	kfree(key);
+	nfss->fscache_key = NULL;
+	nfss->fscache = NULL;
+	printk(KERN_WARNING "NFS:"
+	       " Cache request denied due to non-unique superblock keys\n");
+}
+
+/*
+ * release a per-superblock cookie
+ */
+void nfs_fscache_release_super_cookie(struct super_block *sb)
+{
+	struct nfs_server *nfss = NFS_SB(sb);
+
+	dfprintk(FSCACHE, "NFS: releasing superblock cookie (0x%p/0x%p)\n",
+		 nfss, nfss->fscache);
+
+	fscache_relinquish_cookie(nfss->fscache, 0);
+	nfss->fscache = NULL;
+
+	if (nfss->fscache_key) {
+		spin_lock(&nfs_fscache_keys_lock);
+		rb_erase(&nfss->fscache_key->node, &nfs_fscache_keys);
+		spin_unlock(&nfs_fscache_keys_lock);
+		kfree(nfss->fscache_key);
+		nfss->fscache_key = NULL;
+	}
+}
+
+/*
+ * Initialise the per-inode cache cookie pointer for an NFS inode.
+ */
+void nfs_fscache_init_inode_cookie(struct inode *inode)
+{
+	NFS_I(inode)->fscache = NULL;
+	if (S_ISREG(inode->i_mode))
+		set_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags);
+}
+
+/*
+ * Get the per-inode cache cookie for an NFS inode.
+ */
+static void nfs_fscache_enable_inode_cookie(struct inode *inode)
+{
+	struct super_block *sb = inode->i_sb;
+	struct nfs_inode *nfsi = NFS_I(inode);
+
+	if (nfsi->fscache || !NFS_FSCACHE(inode))
+		return;
+
+	if ((NFS_SB(sb)->options & NFS_OPTION_FSCACHE)) {
+		nfsi->fscache = fscache_acquire_cookie(
+			NFS_SB(sb)->fscache,
+			&nfs_fscache_inode_object_def,
+			nfsi);
+
+		dfprintk(FSCACHE, "NFS: get FH cookie (0x%p/0x%p/0x%p)\n",
+			 sb, nfsi, nfsi->fscache);
+	}
+}
+
+/*
+ * Release a per-inode cookie.
+ */
+void nfs_fscache_release_inode_cookie(struct inode *inode)
+{
+	struct nfs_inode *nfsi = NFS_I(inode);
+
+	dfprintk(FSCACHE, "NFS: clear cookie (0x%p/0x%p)\n",
+		 nfsi, nfsi->fscache);
+
+	fscache_relinquish_cookie(nfsi->fscache, 0);
+	nfsi->fscache = NULL;
+}
+
+/*
+ * Retire a per-inode cookie, destroying the data attached to it.
+ */
+void nfs_fscache_zap_inode_cookie(struct inode *inode)
+{
+	struct nfs_inode *nfsi = NFS_I(inode);
+
+	dfprintk(FSCACHE, "NFS: zapping cookie (0x%p/0x%p)\n",
+		 nfsi, nfsi->fscache);
+
+	fscache_relinquish_cookie(nfsi->fscache, 1);
+	nfsi->fscache = NULL;
+}
+
+/*
+ * Turn off the cache with regard to a per-inode cookie if opened for writing,
+ * invalidating all the pages in the page cache relating to the associated
+ * inode to clear the per-page caching.
+ */
+static void nfs_fscache_disable_inode_cookie(struct inode *inode)
+{
+	clear_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags);
+
+	if (NFS_I(inode)->fscache) {
+		dfprintk(FSCACHE,
+			 "NFS: nfsi 0x%p turning cache off\n", NFS_I(inode));
+
+		/* Need to invalidate any mapped pages that were read in before
+		 * turning off the cache.
+		 */
+		if (inode->i_mapping && inode->i_mapping->nrpages)
+			invalidate_inode_pages2(inode->i_mapping);
+
+		nfs_fscache_zap_inode_cookie(inode);
+	}
+}
+
+/*
+ * wait_on_bit() sleep function for uninterruptible waiting
+ */
+static int nfs_fscache_wait_bit(void *flags)
+{
+	schedule();
+	return 0;
+}
+
+/*
+ * Lock against someone else trying to also acquire or relinquish a cookie
+ */
+static inline void nfs_fscache_inode_lock(struct inode *inode)
+{
+	struct nfs_inode *nfsi = NFS_I(inode);
+
+	while (test_and_set_bit(NFS_INO_FSCACHE_LOCK, &nfsi->flags))
+		wait_on_bit(&nfsi->flags, NFS_INO_FSCACHE_LOCK,
+			    nfs_fscache_wait_bit, TASK_UNINTERRUPTIBLE);
+}
+
+/*
+ * Unlock cookie management lock
+ */
+static inline void nfs_fscache_inode_unlock(struct inode *inode)
+{
+	struct nfs_inode *nfsi = NFS_I(inode);
+
+	smp_mb__before_clear_bit();
+	clear_bit(NFS_INO_FSCACHE_LOCK, &nfsi->flags);
+	smp_mb__after_clear_bit();
+	wake_up_bit(&nfsi->flags, NFS_INO_FSCACHE_LOCK);
+}
+
+/*
+ * Decide if we should enable or disable local caching for this inode.
+ * - For now, with NFS, only regular files that are open read-only will be able
+ *   to use the cache.
+ * - May be invoked multiple times in parallel by parallel nfs_open() functions.
+ */
+void nfs_fscache_set_inode_cookie(struct inode *inode, struct file *filp)
+{
+	if (NFS_FSCACHE(inode)) {
+		nfs_fscache_inode_lock(inode);
+		if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
+			nfs_fscache_disable_inode_cookie(inode);
+		else
+			nfs_fscache_enable_inode_cookie(inode);
+		nfs_fscache_inode_unlock(inode);
+	}
+}
+
+/*
+ * Replace a per-inode cookie due to revalidation detecting a file having
+ * changed on the server.
+ */
+void nfs_fscache_reset_inode_cookie(struct inode *inode)
+{
+	struct nfs_inode *nfsi = NFS_I(inode);
+	struct nfs_server *nfss = NFS_SERVER(inode);
+	struct fscache_cookie *old = nfsi->fscache;
+
+	nfs_fscache_inode_lock(inode);
+	if (nfsi->fscache) {
+		/* retire the current fscache cache and get a new one */
+		fscache_relinquish_cookie(nfsi->fscache, 1);
+
+		nfsi->fscache = fscache_acquire_cookie(
+			nfss->nfs_client->fscache,
+			&nfs_fscache_inode_object_def,
+			nfsi);
+
+		dfprintk(FSCACHE,
+			 "NFS: revalidation new cookie (0x%p/0x%p/0x%p/0x%p)\n",
+			 nfss, nfsi, old, nfsi->fscache);
+	}
+	nfs_fscache_inode_unlock(inode);
+}
+
+/*
+ * Release the caching state associated with a page, if the page isn't busy
+ * interacting with the cache.
+ * - Returns true (can release page) or false (page busy).
+ */
+int nfs_fscache_release_page(struct page *page, gfp_t gfp)
+{
+	struct nfs_inode *nfsi = NFS_I(page->mapping->host);
+	struct fscache_cookie *cookie = nfsi->fscache;
+
+	BUG_ON(!cookie);
+
+	if (fscache_check_page_write(cookie, page)) {
+		if (!(gfp & __GFP_WAIT))
+			return 0;
+		fscache_wait_on_page_write(cookie, page);
+	}
+
+	if (PageFsCache(page)) {
+		dfprintk(FSCACHE, "NFS: fscache releasepage (0x%p/0x%p/0x%p)\n",
+			 cookie, page, nfsi);
+
+		fscache_uncache_page(cookie, page);
+		nfs_add_fscache_stats(page->mapping->host,
+				      NFSIOS_FSCACHE_PAGES_UNCACHED, 1);
+	}
+
+	return 1;
+}
+
+/*
+ * Release the caching state associated with a page if undergoing complete page
+ * invalidation.
+ */
+void __nfs_fscache_invalidate_page(struct page *page, struct inode *inode)
+{
+	struct nfs_inode *nfsi = NFS_I(inode);
+	struct fscache_cookie *cookie = nfsi->fscache;
+
+	BUG_ON(!cookie);
+
+	dfprintk(FSCACHE, "NFS: fscache invalidatepage (0x%p/0x%p/0x%p)\n",
+		 cookie, page, nfsi);
+
+	fscache_wait_on_page_write(cookie, page);
+
+	BUG_ON(!PageLocked(page));
+	fscache_uncache_page(cookie, page);
+	nfs_add_fscache_stats(page->mapping->host,
+			      NFSIOS_FSCACHE_PAGES_UNCACHED, 1);
+}
+
+/*
+ * Handle completion of a page being read from the cache.
+ * - Called in process (keventd) context.
+ */
+static void nfs_readpage_from_fscache_complete(struct page *page,
+					       void *context,
+					       int error)
+{
+	dfprintk(FSCACHE,
+		 "NFS: readpage_from_fscache_complete (0x%p/0x%p/%d)\n",
+		 page, context, error);
+
+	/* if the read completes with an error, we just unlock the page and let
+	 * the VM reissue the readpage */
+	if (!error) {
+		SetPageUptodate(page);
+		unlock_page(page);
+	} else {
+		error = nfs_readpage_async(context, page->mapping->host, page);
+		if (error)
+			unlock_page(page);
+	}
+}
+
+/*
+ * Retrieve a page from fscache
+ */
+int __nfs_readpage_from_fscache(struct nfs_open_context *ctx,
+				struct inode *inode, struct page *page)
+{
+	int ret;
+
+	dfprintk(FSCACHE,
+		 "NFS: readpage_from_fscache(fsc:%p/p:%p(i:%lx f:%lx)/0x%p)\n",
+		 NFS_I(inode)->fscache, page, page->index, page->flags, inode);
+
+	ret = fscache_read_or_alloc_page(NFS_I(inode)->fscache,
+					 page,
+					 nfs_readpage_from_fscache_complete,
+					 ctx,
+					 GFP_KERNEL);
+
+	switch (ret) {
+	case 0: /* read BIO submitted (page in fscache) */
+		dfprintk(FSCACHE,
+			 "NFS:    readpage_from_fscache: BIO submitted\n");
+		nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_OK, 1);
+		return ret;
+
+	case -ENOBUFS: /* inode not in cache */
+	case -ENODATA: /* page not in cache */
+		nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_FAIL, 1);
+		dfprintk(FSCACHE,
+			 "NFS:    readpage_from_fscache %d\n", ret);
+		return 1;
+
+	default:
+		dfprintk(FSCACHE, "NFS:    readpage_from_fscache %d\n", ret);
+		nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_FAIL, 1);
+	}
+	return ret;
+}
+
+/*
+ * Retrieve a set of pages from fscache
+ */
+int __nfs_readpages_from_fscache(struct nfs_open_context *ctx,
+				 struct inode *inode,
+				 struct address_space *mapping,
+				 struct list_head *pages,
+				 unsigned *nr_pages)
+{
+	int ret, npages = *nr_pages;
+
+	dfprintk(FSCACHE, "NFS: nfs_getpages_from_fscache (0x%p/%u/0x%p)\n",
+		 NFS_I(inode)->fscache, npages, inode);
+
+	ret = fscache_read_or_alloc_pages(NFS_I(inode)->fscache,
+					  mapping, pages, nr_pages,
+					  nfs_readpage_from_fscache_complete,
+					  ctx,
+					  mapping_gfp_mask(mapping));
+	if (*nr_pages < npages)
+		nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_OK,
+				      npages);
+	if (*nr_pages > 0)
+		nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_READ_FAIL,
+				      *nr_pages);
+
+	switch (ret) {
+	case 0: /* read submitted to the cache for all pages */
+		BUG_ON(!list_empty(pages));
+		BUG_ON(*nr_pages != 0);
+		dfprintk(FSCACHE,
+			 "NFS: nfs_getpages_from_fscache: submitted\n");
+
+		return ret;
+
+	case -ENOBUFS: /* some pages aren't cached and can't be */
+	case -ENODATA: /* some pages aren't cached */
+		dfprintk(FSCACHE,
+			 "NFS: nfs_getpages_from_fscache: no page: %d\n", ret);
+		return 1;
+
+	default:
+		dfprintk(FSCACHE,
+			 "NFS: nfs_getpages_from_fscache: ret  %d\n", ret);
+	}
+
+	return ret;
+}
+
+/*
+ * Store a newly fetched page in fscache
+ * - PG_fscache must be set on the page
+ */
+void __nfs_readpage_to_fscache(struct inode *inode, struct page *page, int sync)
+{
+	int ret;
+
+	dfprintk(FSCACHE,
+		 "NFS: readpage_to_fscache(fsc:%p/p:%p(i:%lx f:%lx)/%d)\n",
+		 NFS_I(inode)->fscache, page, page->index, page->flags, sync);
+
+	ret = fscache_write_page(NFS_I(inode)->fscache, page, GFP_KERNEL);
+	dfprintk(FSCACHE,
+		 "NFS:     readpage_to_fscache: p:%p(i:%lu f:%lx) ret %d\n",
+		 page, page->index, page->flags, ret);
+
+	if (ret != 0) {
+		fscache_uncache_page(NFS_I(inode)->fscache, page);
+		nfs_add_fscache_stats(inode,
+				      NFSIOS_FSCACHE_PAGES_WRITTEN_FAIL, 1);
+		nfs_add_fscache_stats(inode, NFSIOS_FSCACHE_PAGES_UNCACHED, 1);
+	} else {
+		nfs_add_fscache_stats(inode,
+				      NFSIOS_FSCACHE_PAGES_WRITTEN_OK, 1);
+	}
+}
diff --git a/fs/nfs/fscache.h b/fs/nfs/fscache.h
new file mode 100644
index 0000000..6e809bb
--- /dev/null
+++ b/fs/nfs/fscache.h
@@ -0,0 +1,220 @@
+/* NFS filesystem cache interface definitions
+ *
+ * Copyright (C) 2008 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.
+ */
+
+#ifndef _NFS_FSCACHE_H
+#define _NFS_FSCACHE_H
+
+#include <linux/nfs_fs.h>
+#include <linux/nfs_mount.h>
+#include <linux/nfs4_mount.h>
+#include <linux/fscache.h>
+
+#ifdef CONFIG_NFS_FSCACHE
+
+/*
+ * set of NFS FS-Cache objects that form a superblock key
+ */
+struct nfs_fscache_key {
+	struct rb_node		node;
+	struct nfs_client	*nfs_client;	/* the server */
+
+	/* the elements of the unique key - as used by nfs_compare_super() and
+	 * nfs_compare_mount_options() to distinguish superblocks */
+	struct {
+		struct {
+			unsigned long	s_flags;	/* various flags
+							 * (& NFS_MS_MASK) */
+		} super;
+
+		struct {
+			struct nfs_fsid fsid;
+			int		flags;
+			unsigned int	rsize;		/* read size */
+			unsigned int	wsize;		/* write size */
+			unsigned int	acregmin;	/* attr cache timeouts */
+			unsigned int	acregmax;
+			unsigned int	acdirmin;
+			unsigned int	acdirmax;
+		} nfs_server;
+
+		struct {
+			rpc_authflavor_t au_flavor;
+		} rpc_auth;
+
+		/* uniquifier - can be used if nfs_server.flags includes
+		 * NFS_MOUNT_UNSHARED  */
+		u8 uniq_len;
+		char uniquifier[0];
+	} key;
+};
+
+/*
+ * fscache-index.c
+ */
+extern struct fscache_netfs nfs_fscache_netfs;
+extern const struct fscache_cookie_def nfs_fscache_server_index_def;
+extern const struct fscache_cookie_def nfs_fscache_super_index_def;
+extern const struct fscache_cookie_def nfs_fscache_inode_object_def;
+
+extern int nfs_fscache_register(void);
+extern void nfs_fscache_unregister(void);
+
+/*
+ * fscache.c
+ */
+extern void nfs_fscache_get_client_cookie(struct nfs_client *);
+extern void nfs_fscache_release_client_cookie(struct nfs_client *);
+
+extern void nfs_fscache_get_super_cookie(struct super_block *,
+					 struct nfs_parsed_mount_data *);
+extern void nfs_fscache_release_super_cookie(struct super_block *);
+
+extern void nfs_fscache_init_inode_cookie(struct inode *);
+extern void nfs_fscache_release_inode_cookie(struct inode *);
+extern void nfs_fscache_zap_inode_cookie(struct inode *);
+extern void nfs_fscache_set_inode_cookie(struct inode *, struct file *);
+extern void nfs_fscache_reset_inode_cookie(struct inode *);
+
+extern void __nfs_fscache_invalidate_page(struct page *, struct inode *);
+extern int nfs_fscache_release_page(struct page *, gfp_t);
+
+extern int __nfs_readpage_from_fscache(struct nfs_open_context *,
+				       struct inode *, struct page *);
+extern int __nfs_readpages_from_fscache(struct nfs_open_context *,
+					struct inode *, struct address_space *,
+					struct list_head *, unsigned *);
+extern void __nfs_readpage_to_fscache(struct inode *, struct page *, int);
+
+/*
+ * wait for a page to complete writing to the cache
+ */
+static inline void nfs_fscache_wait_on_page_write(struct nfs_inode *nfsi,
+						  struct page *page)
+{
+	if (PageFsCache(page))
+		fscache_wait_on_page_write(nfsi->fscache, page);
+}
+
+/*
+ * release the caching state associated with a page if undergoing complete page
+ * invalidation
+ */
+static inline void nfs_fscache_invalidate_page(struct page *page,
+					       struct inode *inode)
+{
+	if (PageFsCache(page))
+		__nfs_fscache_invalidate_page(page, inode);
+}
+
+/*
+ * Retrieve a page from an inode data storage object.
+ */
+static inline int nfs_readpage_from_fscache(struct nfs_open_context *ctx,
+					    struct inode *inode,
+					    struct page *page)
+{
+	if (NFS_I(inode)->fscache)
+		return __nfs_readpage_from_fscache(ctx, inode, page);
+	return -ENOBUFS;
+}
+
+/*
+ * Retrieve a set of pages from an inode data storage object.
+ */
+static inline int nfs_readpages_from_fscache(struct nfs_open_context *ctx,
+					     struct inode *inode,
+					     struct address_space *mapping,
+					     struct list_head *pages,
+					     unsigned *nr_pages)
+{
+	if (NFS_I(inode)->fscache)
+		return __nfs_readpages_from_fscache(ctx, inode, mapping, pages,
+						    nr_pages);
+	return -ENOBUFS;
+}
+
+/*
+ * Store a page newly fetched from the server in an inode data storage object
+ * in the cache.
+ */
+static inline void nfs_readpage_to_fscache(struct inode *inode,
+					   struct page *page,
+					   int sync)
+{
+	if (PageFsCache(page))
+		__nfs_readpage_to_fscache(inode, page, sync);
+}
+
+/*
+ * indicate the client caching state as readable text
+ */
+static inline const char *nfs_server_fscache_state(struct nfs_server *server)
+{
+	if (server->fscache && (server->options & NFS_OPTION_FSCACHE))
+		return "yes";
+	return "no ";
+}
+
+
+#else /* CONFIG_NFS_FSCACHE */
+static inline int nfs_fscache_register(void) { return 0; }
+static inline void nfs_fscache_unregister(void) {}
+
+static inline void nfs_fscache_get_client_cookie(struct nfs_client *clp) {}
+static inline void nfs_fscache_release_client_cookie(struct nfs_client *clp) {}
+
+static inline void nfs_fscache_get_super_cookie(
+	struct super_block *sb,
+	struct nfs_parsed_mount_data *data)
+{
+}
+static inline void nfs_fscache_release_super_cookie(struct super_block *sb) {}
+
+static inline void nfs_fscache_init_inode_cookie(struct inode *inode) {}
+static inline void nfs_fscache_release_inode_cookie(struct inode *inode) {}
+static inline void nfs_fscache_zap_inode_cookie(struct inode *inode) {}
+static inline void nfs_fscache_set_inode_cookie(struct inode *inode,
+						struct file *filp) {}
+static inline void nfs_fscache_reset_inode_cookie(struct inode *inode) {}
+
+static inline int nfs_fscache_release_page(struct page *page, gfp_t gfp)
+{
+	return 1; /* True: may release page */
+}
+static inline void nfs_fscache_invalidate_page(struct page *page,
+					       struct inode *inode) {}
+static inline void nfs_fscache_wait_on_page_write(struct nfs_inode *nfsi,
+						  struct page *page) {}
+
+static inline int nfs_readpage_from_fscache(struct nfs_open_context *ctx,
+					    struct inode *inode,
+					    struct page *page)
+{
+	return -ENOBUFS;
+}
+static inline int nfs_readpages_from_fscache(struct nfs_open_context *ctx,
+					     struct inode *inode,
+					     struct address_space *mapping,
+					     struct list_head *pages,
+					     unsigned *nr_pages)
+{
+	return -ENOBUFS;
+}
+static inline void nfs_readpage_to_fscache(struct inode *inode,
+					   struct page *page, int sync) {}
+
+static inline const char *nfs_server_fscache_state(struct nfs_server *server)
+{
+	return "no ";
+}
+
+#endif /* CONFIG_NFS_FSCACHE */
+#endif /* _NFS_FSCACHE_H */
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index a834d1d..64f87194d 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -46,6 +46,7 @@
 #include "delegation.h"
 #include "iostat.h"
 #include "internal.h"
+#include "fscache.h"
 
 #define NFSDBG_FACILITY		NFSDBG_VFS
 
@@ -121,6 +122,7 @@
 	BUG_ON(!list_empty(&NFS_I(inode)->open_files));
 	nfs_zap_acl_cache(inode);
 	nfs_access_zap_cache(inode);
+	nfs_fscache_release_inode_cookie(inode);
 }
 
 /**
@@ -355,6 +357,8 @@
 		nfsi->attrtimeo_timestamp = now;
 		nfsi->access_cache = RB_ROOT;
 
+		nfs_fscache_init_inode_cookie(inode);
+
 		unlock_new_inode(inode);
 	} else
 		nfs_refresh_inode(inode, fattr);
@@ -686,6 +690,7 @@
 	ctx->mode = filp->f_mode;
 	nfs_file_set_open_context(filp, ctx);
 	put_nfs_open_context(ctx);
+	nfs_fscache_set_inode_cookie(inode, filp);
 	return 0;
 }
 
@@ -786,6 +791,7 @@
 		memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
 	spin_unlock(&inode->i_lock);
 	nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE);
+	nfs_fscache_reset_inode_cookie(inode);
 	dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n",
 			inode->i_sb->s_id, (long long)NFS_FILEID(inode));
 	return 0;
@@ -1030,6 +1036,7 @@
 	spin_lock(&inode->i_lock);
 	status = nfs_refresh_inode_locked(inode, fattr);
 	spin_unlock(&inode->i_lock);
+
 	return status;
 }
 
@@ -1436,6 +1443,10 @@
 {
 	int err;
 
+	err = nfs_fscache_register();
+	if (err < 0)
+		goto out7;
+
 	err = nfsiod_start();
 	if (err)
 		goto out6;
@@ -1488,6 +1499,8 @@
 out5:
 	nfsiod_stop();
 out6:
+	nfs_fscache_unregister();
+out7:
 	return err;
 }
 
@@ -1498,6 +1511,7 @@
 	nfs_destroy_readpagecache();
 	nfs_destroy_inodecache();
 	nfs_destroy_nfspagecache();
+	nfs_fscache_unregister();
 #ifdef CONFIG_PROC_FS
 	rpc_proc_unregister("nfs");
 #endif
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 2041f68..e4d6a83 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -5,6 +5,8 @@
 #include <linux/mount.h>
 #include <linux/security.h>
 
+#define NFS_MS_MASK (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_SYNCHRONOUS)
+
 struct nfs_string;
 
 /* Maximum number of readahead requests
@@ -37,10 +39,12 @@
 	int			acregmin, acregmax,
 				acdirmin, acdirmax;
 	int			namlen;
+	unsigned int		options;
 	unsigned int		bsize;
 	unsigned int		auth_flavor_len;
 	rpc_authflavor_t	auth_flavors[1];
 	char			*client_address;
+	char			*fscache_uniq;
 
 	struct {
 		struct sockaddr_storage	address;
diff --git a/fs/nfs/iostat.h b/fs/nfs/iostat.h
index a369528..a2ab252 100644
--- a/fs/nfs/iostat.h
+++ b/fs/nfs/iostat.h
@@ -16,6 +16,9 @@
 
 struct nfs_iostats {
 	unsigned long long	bytes[__NFSIOS_BYTESMAX];
+#ifdef CONFIG_NFS_FSCACHE
+	unsigned long long	fscache[__NFSIOS_FSCACHEMAX];
+#endif
 	unsigned long		events[__NFSIOS_COUNTSMAX];
 } ____cacheline_aligned;
 
@@ -57,6 +60,21 @@
 	nfs_add_server_stats(NFS_SERVER(inode), stat, addend);
 }
 
+#ifdef CONFIG_NFS_FSCACHE
+static inline void nfs_add_fscache_stats(struct inode *inode,
+					 enum nfs_stat_fscachecounters stat,
+					 unsigned long addend)
+{
+	struct nfs_iostats *iostats;
+	int cpu;
+
+	cpu = get_cpu();
+	iostats = per_cpu_ptr(NFS_SERVER(inode)->io_stats, cpu);
+	iostats->fscache[stat] += addend;
+	put_cpu_no_resched();
+}
+#endif
+
 static inline struct nfs_iostats *nfs_alloc_iostats(void)
 {
 	return alloc_percpu(struct nfs_iostats);
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index f856004..4ace3c5 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -24,6 +24,7 @@
 
 #include "internal.h"
 #include "iostat.h"
+#include "fscache.h"
 
 #define NFSDBG_FACILITY		NFSDBG_PAGECACHE
 
@@ -111,8 +112,8 @@
 	}
 }
 
-static int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode,
-		struct page *page)
+int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode,
+		       struct page *page)
 {
 	LIST_HEAD(one_request);
 	struct nfs_page	*new;
@@ -139,6 +140,11 @@
 
 static void nfs_readpage_release(struct nfs_page *req)
 {
+	struct inode *d_inode = req->wb_context->path.dentry->d_inode;
+
+	if (PageUptodate(req->wb_page))
+		nfs_readpage_to_fscache(d_inode, req->wb_page, 0);
+
 	unlock_page(req->wb_page);
 
 	dprintk("NFS: read done (%s/%Ld %d@%Ld)\n",
@@ -510,8 +516,15 @@
 	} else
 		ctx = get_nfs_open_context(nfs_file_open_context(file));
 
+	if (!IS_SYNC(inode)) {
+		error = nfs_readpage_from_fscache(ctx, inode, page);
+		if (error == 0)
+			goto out;
+	}
+
 	error = nfs_readpage_async(ctx, inode, page);
 
+out:
 	put_nfs_open_context(ctx);
 	return error;
 out_unlock:
@@ -584,6 +597,15 @@
 			return -EBADF;
 	} else
 		desc.ctx = get_nfs_open_context(nfs_file_open_context(filp));
+
+	/* attempt to read as many of the pages as possible from the cache
+	 * - this returns -ENOBUFS immediately if the cookie is negative
+	 */
+	ret = nfs_readpages_from_fscache(desc.ctx, inode, mapping,
+					 pages, &nr_pages);
+	if (ret == 0)
+		goto read_complete; /* all pages were read */
+
 	if (rsize < PAGE_CACHE_SIZE)
 		nfs_pageio_init(&pgio, inode, nfs_pagein_multi, rsize, 0);
 	else
@@ -594,6 +616,7 @@
 	nfs_pageio_complete(&pgio);
 	npages = (pgio.pg_bytes_written + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
 	nfs_add_stats(inode, NFSIOS_READPAGES, npages);
+read_complete:
 	put_nfs_open_context(desc.ctx);
 out:
 	return ret;
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 0942fcb..82eaadb 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -60,6 +60,7 @@
 #include "delegation.h"
 #include "iostat.h"
 #include "internal.h"
+#include "fscache.h"
 
 #define NFSDBG_FACILITY		NFSDBG_VFS
 
@@ -76,6 +77,7 @@
 	Opt_rdirplus, Opt_nordirplus,
 	Opt_sharecache, Opt_nosharecache,
 	Opt_resvport, Opt_noresvport,
+	Opt_fscache, Opt_nofscache,
 
 	/* Mount options that take integer arguments */
 	Opt_port,
@@ -93,6 +95,7 @@
 	Opt_sec, Opt_proto, Opt_mountproto, Opt_mounthost,
 	Opt_addr, Opt_mountaddr, Opt_clientaddr,
 	Opt_lookupcache,
+	Opt_fscache_uniq,
 
 	/* Special mount options */
 	Opt_userspace, Opt_deprecated, Opt_sloppy,
@@ -132,6 +135,9 @@
 	{ Opt_nosharecache, "nosharecache" },
 	{ Opt_resvport, "resvport" },
 	{ Opt_noresvport, "noresvport" },
+	{ Opt_fscache, "fsc" },
+	{ Opt_fscache_uniq, "fsc=%s" },
+	{ Opt_nofscache, "nofsc" },
 
 	{ Opt_port, "port=%u" },
 	{ Opt_rsize, "rsize=%u" },
@@ -563,6 +569,8 @@
 	if (clp->rpc_ops->version == 4)
 		seq_printf(m, ",clientaddr=%s", clp->cl_ipaddr);
 #endif
+	if (nfss->options & NFS_OPTION_FSCACHE)
+		seq_printf(m, ",fsc");
 }
 
 /*
@@ -641,6 +649,10 @@
 			totals.events[i] += stats->events[i];
 		for (i = 0; i < __NFSIOS_BYTESMAX; i++)
 			totals.bytes[i] += stats->bytes[i];
+#ifdef CONFIG_NFS_FSCACHE
+		for (i = 0; i < __NFSIOS_FSCACHEMAX; i++)
+			totals.fscache[i] += stats->fscache[i];
+#endif
 
 		preempt_enable();
 	}
@@ -651,6 +663,13 @@
 	seq_printf(m, "\n\tbytes:\t");
 	for (i = 0; i < __NFSIOS_BYTESMAX; i++)
 		seq_printf(m, "%Lu ", totals.bytes[i]);
+#ifdef CONFIG_NFS_FSCACHE
+	if (nfss->options & NFS_OPTION_FSCACHE) {
+		seq_printf(m, "\n\tfsc:\t");
+		for (i = 0; i < __NFSIOS_FSCACHEMAX; i++)
+			seq_printf(m, "%Lu ", totals.bytes[i]);
+	}
+#endif
 	seq_printf(m, "\n");
 
 	rpc_print_iostats(m, nfss->client);
@@ -1044,6 +1063,24 @@
 		case Opt_noresvport:
 			mnt->flags |= NFS_MOUNT_NORESVPORT;
 			break;
+		case Opt_fscache:
+			mnt->options |= NFS_OPTION_FSCACHE;
+			kfree(mnt->fscache_uniq);
+			mnt->fscache_uniq = NULL;
+			break;
+		case Opt_nofscache:
+			mnt->options &= ~NFS_OPTION_FSCACHE;
+			kfree(mnt->fscache_uniq);
+			mnt->fscache_uniq = NULL;
+			break;
+		case Opt_fscache_uniq:
+			string = match_strdup(args);
+			if (!string)
+				goto out_nomem;
+			kfree(mnt->fscache_uniq);
+			mnt->fscache_uniq = string;
+			mnt->options |= NFS_OPTION_FSCACHE;
+			break;
 
 		/*
 		 * options that take numeric values
@@ -1870,8 +1907,6 @@
  	nfs_initialise_sb(sb);
 }
 
-#define NFS_MS_MASK (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_SYNCHRONOUS)
-
 static int nfs_compare_mount_options(const struct super_block *s, const struct nfs_server *b, int flags)
 {
 	const struct nfs_server *a = s->s_fs_info;
@@ -2036,6 +2071,7 @@
 	if (!s->s_root) {
 		/* initial superblock/root creation */
 		nfs_fill_super(s, data);
+		nfs_fscache_get_super_cookie(s, data);
 	}
 
 	mntroot = nfs_get_root(s, mntfh);
@@ -2056,6 +2092,7 @@
 out:
 	kfree(data->nfs_server.hostname);
 	kfree(data->mount_server.hostname);
+	kfree(data->fscache_uniq);
 	security_free_mnt_opts(&data->lsm_opts);
 out_free_fh:
 	kfree(mntfh);
@@ -2083,6 +2120,7 @@
 
 	bdi_unregister(&server->backing_dev_info);
 	kill_anon_super(s);
+	nfs_fscache_release_super_cookie(s);
 	nfs_free_server(server);
 }
 
@@ -2390,6 +2428,7 @@
 	if (!s->s_root) {
 		/* initial superblock/root creation */
 		nfs4_fill_super(s);
+		nfs_fscache_get_super_cookie(s, data);
 	}
 
 	mntroot = nfs4_get_root(s, mntfh);
@@ -2411,6 +2450,7 @@
 	kfree(data->client_address);
 	kfree(data->nfs_server.export_path);
 	kfree(data->nfs_server.hostname);
+	kfree(data->fscache_uniq);
 	security_free_mnt_opts(&data->lsm_opts);
 out_free_fh:
 	kfree(mntfh);
@@ -2437,6 +2477,7 @@
 	kill_anon_super(sb);
 
 	nfs4_renewd_prepare_shutdown(server);
+	nfs_fscache_release_super_cookie(sb);
 	nfs_free_server(server);
 }
 
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index 19e3a96..678a067 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -294,6 +294,55 @@
 	.eo_fill_max_leaf_clusters = ocfs2_xattr_tree_fill_max_leaf_clusters,
 };
 
+static void ocfs2_dx_root_set_last_eb_blk(struct ocfs2_extent_tree *et,
+					  u64 blkno)
+{
+	struct ocfs2_dx_root_block *dx_root = et->et_object;
+
+	dx_root->dr_last_eb_blk = cpu_to_le64(blkno);
+}
+
+static u64 ocfs2_dx_root_get_last_eb_blk(struct ocfs2_extent_tree *et)
+{
+	struct ocfs2_dx_root_block *dx_root = et->et_object;
+
+	return le64_to_cpu(dx_root->dr_last_eb_blk);
+}
+
+static void ocfs2_dx_root_update_clusters(struct inode *inode,
+					  struct ocfs2_extent_tree *et,
+					  u32 clusters)
+{
+	struct ocfs2_dx_root_block *dx_root = et->et_object;
+
+	le32_add_cpu(&dx_root->dr_clusters, clusters);
+}
+
+static int ocfs2_dx_root_sanity_check(struct inode *inode,
+				      struct ocfs2_extent_tree *et)
+{
+	struct ocfs2_dx_root_block *dx_root = et->et_object;
+
+	BUG_ON(!OCFS2_IS_VALID_DX_ROOT(dx_root));
+
+	return 0;
+}
+
+static void ocfs2_dx_root_fill_root_el(struct ocfs2_extent_tree *et)
+{
+	struct ocfs2_dx_root_block *dx_root = et->et_object;
+
+	et->et_root_el = &dx_root->dr_list;
+}
+
+static struct ocfs2_extent_tree_operations ocfs2_dx_root_et_ops = {
+	.eo_set_last_eb_blk	= ocfs2_dx_root_set_last_eb_blk,
+	.eo_get_last_eb_blk	= ocfs2_dx_root_get_last_eb_blk,
+	.eo_update_clusters	= ocfs2_dx_root_update_clusters,
+	.eo_sanity_check	= ocfs2_dx_root_sanity_check,
+	.eo_fill_root_el	= ocfs2_dx_root_fill_root_el,
+};
+
 static void __ocfs2_init_extent_tree(struct ocfs2_extent_tree *et,
 				     struct inode *inode,
 				     struct buffer_head *bh,
@@ -339,6 +388,14 @@
 				 &ocfs2_xattr_value_et_ops);
 }
 
+void ocfs2_init_dx_root_extent_tree(struct ocfs2_extent_tree *et,
+				    struct inode *inode,
+				    struct buffer_head *bh)
+{
+	__ocfs2_init_extent_tree(et, inode, bh, ocfs2_journal_access_dr,
+				 NULL, &ocfs2_dx_root_et_ops);
+}
+
 static inline void ocfs2_et_set_last_eb_blk(struct ocfs2_extent_tree *et,
 					    u64 new_last_eb_blk)
 {
diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h
index cceff5c..353254b 100644
--- a/fs/ocfs2/alloc.h
+++ b/fs/ocfs2/alloc.h
@@ -75,6 +75,9 @@
 void ocfs2_init_xattr_value_extent_tree(struct ocfs2_extent_tree *et,
 					struct inode *inode,
 					struct ocfs2_xattr_value_buf *vb);
+void ocfs2_init_dx_root_extent_tree(struct ocfs2_extent_tree *et,
+				    struct inode *inode,
+				    struct buffer_head *bh);
 
 /*
  * Read an extent block into *bh.  If *bh is NULL, a bh will be
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 8e1709a..b2c52b3 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -1956,15 +1956,16 @@
 }
 
 const struct address_space_operations ocfs2_aops = {
-	.readpage	= ocfs2_readpage,
-	.readpages	= ocfs2_readpages,
-	.writepage	= ocfs2_writepage,
-	.write_begin	= ocfs2_write_begin,
-	.write_end	= ocfs2_write_end,
-	.bmap		= ocfs2_bmap,
-	.sync_page	= block_sync_page,
-	.direct_IO	= ocfs2_direct_IO,
-	.invalidatepage	= ocfs2_invalidatepage,
-	.releasepage	= ocfs2_releasepage,
-	.migratepage	= buffer_migrate_page,
+	.readpage		= ocfs2_readpage,
+	.readpages		= ocfs2_readpages,
+	.writepage		= ocfs2_writepage,
+	.write_begin		= ocfs2_write_begin,
+	.write_end		= ocfs2_write_end,
+	.bmap			= ocfs2_bmap,
+	.sync_page		= block_sync_page,
+	.direct_IO		= ocfs2_direct_IO,
+	.invalidatepage		= ocfs2_invalidatepage,
+	.releasepage		= ocfs2_releasepage,
+	.migratepage		= buffer_migrate_page,
+	.is_partially_uptodate	= block_is_partially_uptodate,
 };
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index 04697ba..4f85ece 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -33,6 +33,7 @@
 #include <linux/random.h>
 #include <linux/crc32.h>
 #include <linux/time.h>
+#include <linux/debugfs.h>
 
 #include "heartbeat.h"
 #include "tcp.h"
@@ -60,6 +61,11 @@
 static LIST_HEAD(o2hb_node_events);
 static DECLARE_WAIT_QUEUE_HEAD(o2hb_steady_queue);
 
+#define O2HB_DEBUG_DIR			"o2hb"
+#define O2HB_DEBUG_LIVENODES		"livenodes"
+static struct dentry *o2hb_debug_dir;
+static struct dentry *o2hb_debug_livenodes;
+
 static LIST_HEAD(o2hb_all_regions);
 
 static struct o2hb_callback {
@@ -905,7 +911,77 @@
 	return 0;
 }
 
-void o2hb_init(void)
+#ifdef CONFIG_DEBUG_FS
+static int o2hb_debug_open(struct inode *inode, struct file *file)
+{
+	unsigned long map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+	char *buf = NULL;
+	int i = -1;
+	int out = 0;
+
+	buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!buf)
+		goto bail;
+
+	o2hb_fill_node_map(map, sizeof(map));
+
+	while ((i = find_next_bit(map, O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES)
+		out += snprintf(buf + out, PAGE_SIZE - out, "%d ", i);
+	out += snprintf(buf + out, PAGE_SIZE - out, "\n");
+
+	i_size_write(inode, out);
+
+	file->private_data = buf;
+
+	return 0;
+bail:
+	return -ENOMEM;
+}
+
+static int o2hb_debug_release(struct inode *inode, struct file *file)
+{
+	kfree(file->private_data);
+	return 0;
+}
+
+static ssize_t o2hb_debug_read(struct file *file, char __user *buf,
+				 size_t nbytes, loff_t *ppos)
+{
+	return simple_read_from_buffer(buf, nbytes, ppos, file->private_data,
+				       i_size_read(file->f_mapping->host));
+}
+#else
+static int o2hb_debug_open(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+static int o2hb_debug_release(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+static ssize_t o2hb_debug_read(struct file *file, char __user *buf,
+			       size_t nbytes, loff_t *ppos)
+{
+	return 0;
+}
+#endif  /* CONFIG_DEBUG_FS */
+
+static struct file_operations o2hb_debug_fops = {
+	.open =		o2hb_debug_open,
+	.release =	o2hb_debug_release,
+	.read =		o2hb_debug_read,
+	.llseek =	generic_file_llseek,
+};
+
+void o2hb_exit(void)
+{
+	if (o2hb_debug_livenodes)
+		debugfs_remove(o2hb_debug_livenodes);
+	if (o2hb_debug_dir)
+		debugfs_remove(o2hb_debug_dir);
+}
+
+int o2hb_init(void)
 {
 	int i;
 
@@ -918,6 +994,24 @@
 	INIT_LIST_HEAD(&o2hb_node_events);
 
 	memset(o2hb_live_node_bitmap, 0, sizeof(o2hb_live_node_bitmap));
+
+	o2hb_debug_dir = debugfs_create_dir(O2HB_DEBUG_DIR, NULL);
+	if (!o2hb_debug_dir) {
+		mlog_errno(-ENOMEM);
+		return -ENOMEM;
+	}
+
+	o2hb_debug_livenodes = debugfs_create_file(O2HB_DEBUG_LIVENODES,
+						   S_IFREG|S_IRUSR,
+						   o2hb_debug_dir, NULL,
+						   &o2hb_debug_fops);
+	if (!o2hb_debug_livenodes) {
+		mlog_errno(-ENOMEM);
+		debugfs_remove(o2hb_debug_dir);
+		return -ENOMEM;
+	}
+
+	return 0;
 }
 
 /* if we're already in a callback then we're already serialized by the sem */
diff --git a/fs/ocfs2/cluster/heartbeat.h b/fs/ocfs2/cluster/heartbeat.h
index e511339..2f16492 100644
--- a/fs/ocfs2/cluster/heartbeat.h
+++ b/fs/ocfs2/cluster/heartbeat.h
@@ -75,7 +75,8 @@
 			      struct o2hb_callback_func *hc);
 void o2hb_fill_node_map(unsigned long *map,
 			unsigned bytes);
-void o2hb_init(void);
+void o2hb_exit(void);
+int o2hb_init(void);
 int o2hb_check_node_heartbeating(u8 node_num);
 int o2hb_check_node_heartbeating_from_callback(u8 node_num);
 int o2hb_check_local_node_heartbeating(void);
diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c
index 70e8fa9..7ee6188 100644
--- a/fs/ocfs2/cluster/nodemanager.c
+++ b/fs/ocfs2/cluster/nodemanager.c
@@ -881,6 +881,7 @@
 	o2cb_sys_shutdown();
 
 	o2net_exit();
+	o2hb_exit();
 }
 
 static int __init init_o2nm(void)
@@ -889,11 +890,13 @@
 
 	cluster_print_version();
 
-	o2hb_init();
+	ret = o2hb_init();
+	if (ret)
+		goto out;
 
 	ret = o2net_init();
 	if (ret)
-		goto out;
+		goto out_o2hb;
 
 	ret = o2net_register_hb_callbacks();
 	if (ret)
@@ -916,6 +919,8 @@
 	o2net_unregister_hb_callbacks();
 out_o2net:
 	o2net_exit();
+out_o2hb:
+	o2hb_exit();
 out:
 	return ret;
 }
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index f2c4098..e71160c 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -41,6 +41,7 @@
 #include <linux/slab.h>
 #include <linux/highmem.h>
 #include <linux/quotaops.h>
+#include <linux/sort.h>
 
 #define MLOG_MASK_PREFIX ML_NAMEI
 #include <cluster/masklog.h>
@@ -58,6 +59,7 @@
 #include "namei.h"
 #include "suballoc.h"
 #include "super.h"
+#include "sysfile.h"
 #include "uptodate.h"
 
 #include "buffer_head_io.h"
@@ -71,11 +73,6 @@
 	DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
 };
 
-static int ocfs2_extend_dir(struct ocfs2_super *osb,
-			    struct inode *dir,
-			    struct buffer_head *parent_fe_bh,
-			    unsigned int blocks_wanted,
-			    struct buffer_head **new_de_bh);
 static int ocfs2_do_extend_dir(struct super_block *sb,
 			       handle_t *handle,
 			       struct inode *dir,
@@ -83,22 +80,36 @@
 			       struct ocfs2_alloc_context *data_ac,
 			       struct ocfs2_alloc_context *meta_ac,
 			       struct buffer_head **new_bh);
+static int ocfs2_dir_indexed(struct inode *inode);
 
 /*
  * These are distinct checks because future versions of the file system will
  * want to have a trailing dirent structure independent of indexing.
  */
-static int ocfs2_dir_has_trailer(struct inode *dir)
+static int ocfs2_supports_dir_trailer(struct inode *dir)
 {
+	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
+
 	if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL)
 		return 0;
 
-	return ocfs2_meta_ecc(OCFS2_SB(dir->i_sb));
+	return ocfs2_meta_ecc(osb) || ocfs2_dir_indexed(dir);
 }
 
-static int ocfs2_supports_dir_trailer(struct ocfs2_super *osb)
+/*
+ * "new' here refers to the point at which we're creating a new
+ * directory via "mkdir()", but also when we're expanding an inline
+ * directory. In either case, we don't yet have the indexing bit set
+ * on the directory, so the standard checks will fail in when metaecc
+ * is turned off. Only directory-initialization type functions should
+ * use this then. Everything else wants ocfs2_supports_dir_trailer()
+ */
+static int ocfs2_new_dir_wants_trailer(struct inode *dir)
 {
-	return ocfs2_meta_ecc(osb);
+	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
+
+	return ocfs2_meta_ecc(osb) ||
+		ocfs2_supports_indexed_dirs(osb);
 }
 
 static inline unsigned int ocfs2_dir_trailer_blk_off(struct super_block *sb)
@@ -130,7 +141,7 @@
 {
 	unsigned long toff = blklen - sizeof(struct ocfs2_dir_block_trailer);
 
-	if (!ocfs2_dir_has_trailer(dir))
+	if (!ocfs2_supports_dir_trailer(dir))
 		return 0;
 
 	if (offset != toff)
@@ -140,7 +151,7 @@
 }
 
 static void ocfs2_init_dir_trailer(struct inode *inode,
-				   struct buffer_head *bh)
+				   struct buffer_head *bh, u16 rec_len)
 {
 	struct ocfs2_dir_block_trailer *trailer;
 
@@ -150,6 +161,153 @@
 			cpu_to_le16(sizeof(struct ocfs2_dir_block_trailer));
 	trailer->db_parent_dinode = cpu_to_le64(OCFS2_I(inode)->ip_blkno);
 	trailer->db_blkno = cpu_to_le64(bh->b_blocknr);
+	trailer->db_free_rec_len = cpu_to_le16(rec_len);
+}
+/*
+ * Link an unindexed block with a dir trailer structure into the index free
+ * list. This function will modify dirdata_bh, but assumes you've already
+ * passed it to the journal.
+ */
+static int ocfs2_dx_dir_link_trailer(struct inode *dir, handle_t *handle,
+				     struct buffer_head *dx_root_bh,
+				     struct buffer_head *dirdata_bh)
+{
+	int ret;
+	struct ocfs2_dx_root_block *dx_root;
+	struct ocfs2_dir_block_trailer *trailer;
+
+	ret = ocfs2_journal_access_dr(handle, dir, dx_root_bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+	trailer = ocfs2_trailer_from_bh(dirdata_bh, dir->i_sb);
+	dx_root = (struct ocfs2_dx_root_block *)dx_root_bh->b_data;
+
+	trailer->db_free_next = dx_root->dr_free_blk;
+	dx_root->dr_free_blk = cpu_to_le64(dirdata_bh->b_blocknr);
+
+	ocfs2_journal_dirty(handle, dx_root_bh);
+
+out:
+	return ret;
+}
+
+static int ocfs2_free_list_at_root(struct ocfs2_dir_lookup_result *res)
+{
+	return res->dl_prev_leaf_bh == NULL;
+}
+
+void ocfs2_free_dir_lookup_result(struct ocfs2_dir_lookup_result *res)
+{
+	brelse(res->dl_dx_root_bh);
+	brelse(res->dl_leaf_bh);
+	brelse(res->dl_dx_leaf_bh);
+	brelse(res->dl_prev_leaf_bh);
+}
+
+static int ocfs2_dir_indexed(struct inode *inode)
+{
+	if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INDEXED_DIR_FL)
+		return 1;
+	return 0;
+}
+
+static inline int ocfs2_dx_root_inline(struct ocfs2_dx_root_block *dx_root)
+{
+	return dx_root->dr_flags & OCFS2_DX_FLAG_INLINE;
+}
+
+/*
+ * Hashing code adapted from ext3
+ */
+#define DELTA 0x9E3779B9
+
+static void TEA_transform(__u32 buf[4], __u32 const in[])
+{
+	__u32	sum = 0;
+	__u32	b0 = buf[0], b1 = buf[1];
+	__u32	a = in[0], b = in[1], c = in[2], d = in[3];
+	int	n = 16;
+
+	do {
+		sum += DELTA;
+		b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);
+		b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);
+	} while (--n);
+
+	buf[0] += b0;
+	buf[1] += b1;
+}
+
+static void str2hashbuf(const char *msg, int len, __u32 *buf, int num)
+{
+	__u32	pad, val;
+	int	i;
+
+	pad = (__u32)len | ((__u32)len << 8);
+	pad |= pad << 16;
+
+	val = pad;
+	if (len > num*4)
+		len = num * 4;
+	for (i = 0; i < len; i++) {
+		if ((i % 4) == 0)
+			val = pad;
+		val = msg[i] + (val << 8);
+		if ((i % 4) == 3) {
+			*buf++ = val;
+			val = pad;
+			num--;
+		}
+	}
+	if (--num >= 0)
+		*buf++ = val;
+	while (--num >= 0)
+		*buf++ = pad;
+}
+
+static void ocfs2_dx_dir_name_hash(struct inode *dir, const char *name, int len,
+				   struct ocfs2_dx_hinfo *hinfo)
+{
+	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
+	const char	*p;
+	__u32		in[8], buf[4];
+
+	/*
+	 * XXX: Is this really necessary, if the index is never looked
+	 * at by readdir? Is a hash value of '0' a bad idea?
+	 */
+	if ((len == 1 && !strncmp(".", name, 1)) ||
+	    (len == 2 && !strncmp("..", name, 2))) {
+		buf[0] = buf[1] = 0;
+		goto out;
+	}
+
+#ifdef OCFS2_DEBUG_DX_DIRS
+	/*
+	 * This makes it very easy to debug indexing problems. We
+	 * should never allow this to be selected without hand editing
+	 * this file though.
+	 */
+	buf[0] = buf[1] = len;
+	goto out;
+#endif
+
+	memcpy(buf, osb->osb_dx_seed, sizeof(buf));
+
+	p = name;
+	while (len > 0) {
+		str2hashbuf(p, len, in, 4);
+		TEA_transform(buf, in);
+		len -= 16;
+		p += 16;
+	}
+
+out:
+	hinfo->major_hash = buf[0];
+	hinfo->minor_hash = buf[1];
 }
 
 /*
@@ -312,6 +470,52 @@
 }
 
 /*
+ * Validate a directory trailer.
+ *
+ * We check the trailer here rather than in ocfs2_validate_dir_block()
+ * because that function doesn't have the inode to test.
+ */
+static int ocfs2_check_dir_trailer(struct inode *dir, struct buffer_head *bh)
+{
+	int rc = 0;
+	struct ocfs2_dir_block_trailer *trailer;
+
+	trailer = ocfs2_trailer_from_bh(bh, dir->i_sb);
+	if (!OCFS2_IS_VALID_DIR_TRAILER(trailer)) {
+		rc = -EINVAL;
+		ocfs2_error(dir->i_sb,
+			    "Invalid dirblock #%llu: "
+			    "signature = %.*s\n",
+			    (unsigned long long)bh->b_blocknr, 7,
+			    trailer->db_signature);
+		goto out;
+	}
+	if (le64_to_cpu(trailer->db_blkno) != bh->b_blocknr) {
+		rc = -EINVAL;
+		ocfs2_error(dir->i_sb,
+			    "Directory block #%llu has an invalid "
+			    "db_blkno of %llu",
+			    (unsigned long long)bh->b_blocknr,
+			    (unsigned long long)le64_to_cpu(trailer->db_blkno));
+		goto out;
+	}
+	if (le64_to_cpu(trailer->db_parent_dinode) !=
+	    OCFS2_I(dir)->ip_blkno) {
+		rc = -EINVAL;
+		ocfs2_error(dir->i_sb,
+			    "Directory block #%llu on dinode "
+			    "#%llu has an invalid parent_dinode "
+			    "of %llu",
+			    (unsigned long long)bh->b_blocknr,
+			    (unsigned long long)OCFS2_I(dir)->ip_blkno,
+			    (unsigned long long)le64_to_cpu(trailer->db_blkno));
+		goto out;
+	}
+out:
+	return rc;
+}
+
+/*
  * This function forces all errors to -EIO for consistency with its
  * predecessor, ocfs2_bread().  We haven't audited what returning the
  * real error codes would do to callers.  We log the real codes with
@@ -322,7 +526,6 @@
 {
 	int rc = 0;
 	struct buffer_head *tmp = *bh;
-	struct ocfs2_dir_block_trailer *trailer;
 
 	rc = ocfs2_read_virt_blocks(inode, v_block, 1, &tmp, flags,
 				    ocfs2_validate_dir_block);
@@ -331,42 +534,13 @@
 		goto out;
 	}
 
-	/*
-	 * We check the trailer here rather than in
-	 * ocfs2_validate_dir_block() because that function doesn't have
-	 * the inode to test.
-	 */
 	if (!(flags & OCFS2_BH_READAHEAD) &&
-	    ocfs2_dir_has_trailer(inode)) {
-		trailer = ocfs2_trailer_from_bh(tmp, inode->i_sb);
-		if (!OCFS2_IS_VALID_DIR_TRAILER(trailer)) {
-			rc = -EINVAL;
-			ocfs2_error(inode->i_sb,
-				    "Invalid dirblock #%llu: "
-				    "signature = %.*s\n",
-				    (unsigned long long)tmp->b_blocknr, 7,
-				    trailer->db_signature);
-			goto out;
-		}
-		if (le64_to_cpu(trailer->db_blkno) != tmp->b_blocknr) {
-			rc = -EINVAL;
-			ocfs2_error(inode->i_sb,
-				    "Directory block #%llu has an invalid "
-				    "db_blkno of %llu",
-				    (unsigned long long)tmp->b_blocknr,
-				    (unsigned long long)le64_to_cpu(trailer->db_blkno));
-			goto out;
-		}
-		if (le64_to_cpu(trailer->db_parent_dinode) !=
-		    OCFS2_I(inode)->ip_blkno) {
-			rc = -EINVAL;
-			ocfs2_error(inode->i_sb,
-				    "Directory block #%llu on dinode "
-				    "#%llu has an invalid parent_dinode "
-				    "of %llu",
-				    (unsigned long long)tmp->b_blocknr,
-				    (unsigned long long)OCFS2_I(inode)->ip_blkno,
-				    (unsigned long long)le64_to_cpu(trailer->db_blkno));
+	    ocfs2_supports_dir_trailer(inode)) {
+		rc = ocfs2_check_dir_trailer(inode, tmp);
+		if (rc) {
+			if (!*bh)
+				brelse(tmp);
+			mlog_errno(rc);
 			goto out;
 		}
 	}
@@ -379,6 +553,141 @@
 	return rc ? -EIO : 0;
 }
 
+/*
+ * Read the block at 'phys' which belongs to this directory
+ * inode. This function does no virtual->physical block translation -
+ * what's passed in is assumed to be a valid directory block.
+ */
+static int ocfs2_read_dir_block_direct(struct inode *dir, u64 phys,
+				       struct buffer_head **bh)
+{
+	int ret;
+	struct buffer_head *tmp = *bh;
+
+	ret = ocfs2_read_block(dir, phys, &tmp, ocfs2_validate_dir_block);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	if (ocfs2_supports_dir_trailer(dir)) {
+		ret = ocfs2_check_dir_trailer(dir, tmp);
+		if (ret) {
+			if (!*bh)
+				brelse(tmp);
+			mlog_errno(ret);
+			goto out;
+		}
+	}
+
+	if (!ret && !*bh)
+		*bh = tmp;
+out:
+	return ret;
+}
+
+static int ocfs2_validate_dx_root(struct super_block *sb,
+				  struct buffer_head *bh)
+{
+	int ret;
+	struct ocfs2_dx_root_block *dx_root;
+
+	BUG_ON(!buffer_uptodate(bh));
+
+	dx_root = (struct ocfs2_dx_root_block *) bh->b_data;
+
+	ret = ocfs2_validate_meta_ecc(sb, bh->b_data, &dx_root->dr_check);
+	if (ret) {
+		mlog(ML_ERROR,
+		     "Checksum failed for dir index root block %llu\n",
+		     (unsigned long long)bh->b_blocknr);
+		return ret;
+	}
+
+	if (!OCFS2_IS_VALID_DX_ROOT(dx_root)) {
+		ocfs2_error(sb,
+			    "Dir Index Root # %llu has bad signature %.*s",
+			    (unsigned long long)le64_to_cpu(dx_root->dr_blkno),
+			    7, dx_root->dr_signature);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int ocfs2_read_dx_root(struct inode *dir, struct ocfs2_dinode *di,
+			      struct buffer_head **dx_root_bh)
+{
+	int ret;
+	u64 blkno = le64_to_cpu(di->i_dx_root);
+	struct buffer_head *tmp = *dx_root_bh;
+
+	ret = ocfs2_read_block(dir, blkno, &tmp, ocfs2_validate_dx_root);
+
+	/* If ocfs2_read_block() got us a new bh, pass it up. */
+	if (!ret && !*dx_root_bh)
+		*dx_root_bh = tmp;
+
+	return ret;
+}
+
+static int ocfs2_validate_dx_leaf(struct super_block *sb,
+				  struct buffer_head *bh)
+{
+	int ret;
+	struct ocfs2_dx_leaf *dx_leaf = (struct ocfs2_dx_leaf *)bh->b_data;
+
+	BUG_ON(!buffer_uptodate(bh));
+
+	ret = ocfs2_validate_meta_ecc(sb, bh->b_data, &dx_leaf->dl_check);
+	if (ret) {
+		mlog(ML_ERROR,
+		     "Checksum failed for dir index leaf block %llu\n",
+		     (unsigned long long)bh->b_blocknr);
+		return ret;
+	}
+
+	if (!OCFS2_IS_VALID_DX_LEAF(dx_leaf)) {
+		ocfs2_error(sb, "Dir Index Leaf has bad signature %.*s",
+			    7, dx_leaf->dl_signature);
+		return -EROFS;
+	}
+
+	return 0;
+}
+
+static int ocfs2_read_dx_leaf(struct inode *dir, u64 blkno,
+			      struct buffer_head **dx_leaf_bh)
+{
+	int ret;
+	struct buffer_head *tmp = *dx_leaf_bh;
+
+	ret = ocfs2_read_block(dir, blkno, &tmp, ocfs2_validate_dx_leaf);
+
+	/* If ocfs2_read_block() got us a new bh, pass it up. */
+	if (!ret && !*dx_leaf_bh)
+		*dx_leaf_bh = tmp;
+
+	return ret;
+}
+
+/*
+ * Read a series of dx_leaf blocks. This expects all buffer_head
+ * pointers to be NULL on function entry.
+ */
+static int ocfs2_read_dx_leaves(struct inode *dir, u64 start, int num,
+				struct buffer_head **dx_leaf_bhs)
+{
+	int ret;
+
+	ret = ocfs2_read_blocks(dir, start, num, dx_leaf_bhs, 0,
+				ocfs2_validate_dx_leaf);
+	if (ret)
+		mlog_errno(ret);
+
+	return ret;
+}
+
 static struct buffer_head *ocfs2_find_entry_el(const char *name, int namelen,
 					       struct inode *dir,
 					       struct ocfs2_dir_entry **res_dir)
@@ -480,39 +789,340 @@
 	return ret;
 }
 
+static int ocfs2_dx_dir_lookup_rec(struct inode *inode,
+				   struct ocfs2_extent_list *el,
+				   u32 major_hash,
+				   u32 *ret_cpos,
+				   u64 *ret_phys_blkno,
+				   unsigned int *ret_clen)
+{
+	int ret = 0, i, found;
+	struct buffer_head *eb_bh = NULL;
+	struct ocfs2_extent_block *eb;
+	struct ocfs2_extent_rec *rec = NULL;
+
+	if (el->l_tree_depth) {
+		ret = ocfs2_find_leaf(inode, el, major_hash, &eb_bh);
+		if (ret) {
+			mlog_errno(ret);
+			goto out;
+		}
+
+		eb = (struct ocfs2_extent_block *) eb_bh->b_data;
+		el = &eb->h_list;
+
+		if (el->l_tree_depth) {
+			ocfs2_error(inode->i_sb,
+				    "Inode %lu has non zero tree depth in "
+				    "btree tree block %llu\n", inode->i_ino,
+				    (unsigned long long)eb_bh->b_blocknr);
+			ret = -EROFS;
+			goto out;
+		}
+	}
+
+	found = 0;
+	for (i = le16_to_cpu(el->l_next_free_rec) - 1; i >= 0; i--) {
+		rec = &el->l_recs[i];
+
+		if (le32_to_cpu(rec->e_cpos) <= major_hash) {
+			found = 1;
+			break;
+		}
+	}
+
+	if (!found) {
+		ocfs2_error(inode->i_sb, "Inode %lu has bad extent "
+			    "record (%u, %u, 0) in btree", inode->i_ino,
+			    le32_to_cpu(rec->e_cpos),
+			    ocfs2_rec_clusters(el, rec));
+		ret = -EROFS;
+		goto out;
+	}
+
+	if (ret_phys_blkno)
+		*ret_phys_blkno = le64_to_cpu(rec->e_blkno);
+	if (ret_cpos)
+		*ret_cpos = le32_to_cpu(rec->e_cpos);
+	if (ret_clen)
+		*ret_clen = le16_to_cpu(rec->e_leaf_clusters);
+
+out:
+	brelse(eb_bh);
+	return ret;
+}
+
+/*
+ * Returns the block index, from the start of the cluster which this
+ * hash belongs too.
+ */
+static inline unsigned int __ocfs2_dx_dir_hash_idx(struct ocfs2_super *osb,
+						   u32 minor_hash)
+{
+	return minor_hash & osb->osb_dx_mask;
+}
+
+static inline unsigned int ocfs2_dx_dir_hash_idx(struct ocfs2_super *osb,
+					  struct ocfs2_dx_hinfo *hinfo)
+{
+	return __ocfs2_dx_dir_hash_idx(osb, hinfo->minor_hash);
+}
+
+static int ocfs2_dx_dir_lookup(struct inode *inode,
+			       struct ocfs2_extent_list *el,
+			       struct ocfs2_dx_hinfo *hinfo,
+			       u32 *ret_cpos,
+			       u64 *ret_phys_blkno)
+{
+	int ret = 0;
+	unsigned int cend, uninitialized_var(clen);
+	u32 uninitialized_var(cpos);
+	u64 uninitialized_var(blkno);
+	u32 name_hash = hinfo->major_hash;
+
+	ret = ocfs2_dx_dir_lookup_rec(inode, el, name_hash, &cpos, &blkno,
+				      &clen);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	cend = cpos + clen;
+	if (name_hash >= cend) {
+		/* We want the last cluster */
+		blkno += ocfs2_clusters_to_blocks(inode->i_sb, clen - 1);
+		cpos += clen - 1;
+	} else {
+		blkno += ocfs2_clusters_to_blocks(inode->i_sb,
+						  name_hash - cpos);
+		cpos = name_hash;
+	}
+
+	/*
+	 * We now have the cluster which should hold our entry. To
+	 * find the exact block from the start of the cluster to
+	 * search, we take the lower bits of the hash.
+	 */
+	blkno += ocfs2_dx_dir_hash_idx(OCFS2_SB(inode->i_sb), hinfo);
+
+	if (ret_phys_blkno)
+		*ret_phys_blkno = blkno;
+	if (ret_cpos)
+		*ret_cpos = cpos;
+
+out:
+
+	return ret;
+}
+
+static int ocfs2_dx_dir_search(const char *name, int namelen,
+			       struct inode *dir,
+			       struct ocfs2_dx_root_block *dx_root,
+			       struct ocfs2_dir_lookup_result *res)
+{
+	int ret, i, found;
+	u64 uninitialized_var(phys);
+	struct buffer_head *dx_leaf_bh = NULL;
+	struct ocfs2_dx_leaf *dx_leaf;
+	struct ocfs2_dx_entry *dx_entry = NULL;
+	struct buffer_head *dir_ent_bh = NULL;
+	struct ocfs2_dir_entry *dir_ent = NULL;
+	struct ocfs2_dx_hinfo *hinfo = &res->dl_hinfo;
+	struct ocfs2_extent_list *dr_el;
+	struct ocfs2_dx_entry_list *entry_list;
+
+	ocfs2_dx_dir_name_hash(dir, name, namelen, &res->dl_hinfo);
+
+	if (ocfs2_dx_root_inline(dx_root)) {
+		entry_list = &dx_root->dr_entries;
+		goto search;
+	}
+
+	dr_el = &dx_root->dr_list;
+
+	ret = ocfs2_dx_dir_lookup(dir, dr_el, hinfo, NULL, &phys);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	mlog(0, "Dir %llu: name: \"%.*s\", lookup of hash: %u.0x%x "
+	     "returns: %llu\n",
+	     (unsigned long long)OCFS2_I(dir)->ip_blkno,
+	     namelen, name, hinfo->major_hash, hinfo->minor_hash,
+	     (unsigned long long)phys);
+
+	ret = ocfs2_read_dx_leaf(dir, phys, &dx_leaf_bh);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	dx_leaf = (struct ocfs2_dx_leaf *) dx_leaf_bh->b_data;
+
+	mlog(0, "leaf info: num_used: %d, count: %d\n",
+	     le16_to_cpu(dx_leaf->dl_list.de_num_used),
+	     le16_to_cpu(dx_leaf->dl_list.de_count));
+
+	entry_list = &dx_leaf->dl_list;
+
+search:
+	/*
+	 * Empty leaf is legal, so no need to check for that.
+	 */
+	found = 0;
+	for (i = 0; i < le16_to_cpu(entry_list->de_num_used); i++) {
+		dx_entry = &entry_list->de_entries[i];
+
+		if (hinfo->major_hash != le32_to_cpu(dx_entry->dx_major_hash)
+		    || hinfo->minor_hash != le32_to_cpu(dx_entry->dx_minor_hash))
+			continue;
+
+		/*
+		 * Search unindexed leaf block now. We're not
+		 * guaranteed to find anything.
+		 */
+		ret = ocfs2_read_dir_block_direct(dir,
+					  le64_to_cpu(dx_entry->dx_dirent_blk),
+					  &dir_ent_bh);
+		if (ret) {
+			mlog_errno(ret);
+			goto out;
+		}
+
+		/*
+		 * XXX: We should check the unindexed block here,
+		 * before using it.
+		 */
+
+		found = ocfs2_search_dirblock(dir_ent_bh, dir, name, namelen,
+					      0, dir_ent_bh->b_data,
+					      dir->i_sb->s_blocksize, &dir_ent);
+		if (found == 1)
+			break;
+
+		if (found == -1) {
+			/* This means we found a bad directory entry. */
+			ret = -EIO;
+			mlog_errno(ret);
+			goto out;
+		}
+
+		brelse(dir_ent_bh);
+		dir_ent_bh = NULL;
+	}
+
+	if (found <= 0) {
+		ret = -ENOENT;
+		goto out;
+	}
+
+	res->dl_leaf_bh = dir_ent_bh;
+	res->dl_entry = dir_ent;
+	res->dl_dx_leaf_bh = dx_leaf_bh;
+	res->dl_dx_entry = dx_entry;
+
+	ret = 0;
+out:
+	if (ret) {
+		brelse(dx_leaf_bh);
+		brelse(dir_ent_bh);
+	}
+	return ret;
+}
+
+static int ocfs2_find_entry_dx(const char *name, int namelen,
+			       struct inode *dir,
+			       struct ocfs2_dir_lookup_result *lookup)
+{
+	int ret;
+	struct buffer_head *di_bh = NULL;
+	struct ocfs2_dinode *di;
+	struct buffer_head *dx_root_bh = NULL;
+	struct ocfs2_dx_root_block *dx_root;
+
+	ret = ocfs2_read_inode_block(dir, &di_bh);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	di = (struct ocfs2_dinode *)di_bh->b_data;
+
+	ret = ocfs2_read_dx_root(dir, di, &dx_root_bh);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+	dx_root = (struct ocfs2_dx_root_block *) dx_root_bh->b_data;
+
+	ret = ocfs2_dx_dir_search(name, namelen, dir, dx_root, lookup);
+	if (ret) {
+		if (ret != -ENOENT)
+			mlog_errno(ret);
+		goto out;
+	}
+
+	lookup->dl_dx_root_bh = dx_root_bh;
+	dx_root_bh = NULL;
+out:
+	brelse(di_bh);
+	brelse(dx_root_bh);
+	return ret;
+}
+
 /*
  * Try to find an entry of the provided name within 'dir'.
  *
- * If nothing was found, NULL is returned. Otherwise, a buffer_head
- * and pointer to the dir entry are passed back.
+ * If nothing was found, -ENOENT is returned. Otherwise, zero is
+ * returned and the struct 'res' will contain information useful to
+ * other directory manipulation functions.
  *
  * Caller can NOT assume anything about the contents of the
- * buffer_head - it is passed back only so that it can be passed into
- * any one of the manipulation functions (add entry, delete entry,
- * etc). As an example, bh in the extent directory case is a data
- * block, in the inline-data case it actually points to an inode.
+ * buffer_heads - they are passed back only so that it can be passed
+ * into any one of the manipulation functions (add entry, delete
+ * entry, etc). As an example, bh in the extent directory case is a
+ * data block, in the inline-data case it actually points to an inode,
+ * in the indexed directory case, multiple buffers are involved.
  */
-struct buffer_head *ocfs2_find_entry(const char *name, int namelen,
-				     struct inode *dir,
-				     struct ocfs2_dir_entry **res_dir)
+int ocfs2_find_entry(const char *name, int namelen,
+		     struct inode *dir, struct ocfs2_dir_lookup_result *lookup)
 {
-	*res_dir = NULL;
+	struct buffer_head *bh;
+	struct ocfs2_dir_entry *res_dir = NULL;
 
+	if (ocfs2_dir_indexed(dir))
+		return ocfs2_find_entry_dx(name, namelen, dir, lookup);
+
+	/*
+	 * The unindexed dir code only uses part of the lookup
+	 * structure, so there's no reason to push it down further
+	 * than this.
+	 */
 	if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL)
-		return ocfs2_find_entry_id(name, namelen, dir, res_dir);
+		bh = ocfs2_find_entry_id(name, namelen, dir, &res_dir);
+	else
+		bh = ocfs2_find_entry_el(name, namelen, dir, &res_dir);
 
-	return ocfs2_find_entry_el(name, namelen, dir, res_dir);
+	if (bh == NULL)
+		return -ENOENT;
+
+	lookup->dl_leaf_bh = bh;
+	lookup->dl_entry = res_dir;
+	return 0;
 }
 
 /*
  * Update inode number and type of a previously found directory entry.
  */
 int ocfs2_update_entry(struct inode *dir, handle_t *handle,
-		       struct buffer_head *de_bh, struct ocfs2_dir_entry *de,
+		       struct ocfs2_dir_lookup_result *res,
 		       struct inode *new_entry_inode)
 {
 	int ret;
 	ocfs2_journal_access_func access = ocfs2_journal_access_db;
+	struct ocfs2_dir_entry *de = res->dl_entry;
+	struct buffer_head *de_bh = res->dl_leaf_bh;
 
 	/*
 	 * The same code works fine for both inline-data and extent
@@ -538,6 +1148,10 @@
 	return ret;
 }
 
+/*
+ * __ocfs2_delete_entry deletes a directory entry by merging it with the
+ * previous entry
+ */
 static int __ocfs2_delete_entry(handle_t *handle, struct inode *dir,
 				struct ocfs2_dir_entry *de_del,
 				struct buffer_head *bh, char *first_de,
@@ -587,6 +1201,181 @@
 	return status;
 }
 
+static unsigned int ocfs2_figure_dirent_hole(struct ocfs2_dir_entry *de)
+{
+	unsigned int hole;
+
+	if (le64_to_cpu(de->inode) == 0)
+		hole = le16_to_cpu(de->rec_len);
+	else
+		hole = le16_to_cpu(de->rec_len) -
+			OCFS2_DIR_REC_LEN(de->name_len);
+
+	return hole;
+}
+
+static int ocfs2_find_max_rec_len(struct super_block *sb,
+				  struct buffer_head *dirblock_bh)
+{
+	int size, this_hole, largest_hole = 0;
+	char *trailer, *de_buf, *limit, *start = dirblock_bh->b_data;
+	struct ocfs2_dir_entry *de;
+
+	trailer = (char *)ocfs2_trailer_from_bh(dirblock_bh, sb);
+	size = ocfs2_dir_trailer_blk_off(sb);
+	limit = start + size;
+	de_buf = start;
+	de = (struct ocfs2_dir_entry *)de_buf;
+	do {
+		if (de_buf != trailer) {
+			this_hole = ocfs2_figure_dirent_hole(de);
+			if (this_hole > largest_hole)
+				largest_hole = this_hole;
+		}
+
+		de_buf += le16_to_cpu(de->rec_len);
+		de = (struct ocfs2_dir_entry *)de_buf;
+	} while (de_buf < limit);
+
+	if (largest_hole >= OCFS2_DIR_MIN_REC_LEN)
+		return largest_hole;
+	return 0;
+}
+
+static void ocfs2_dx_list_remove_entry(struct ocfs2_dx_entry_list *entry_list,
+				       int index)
+{
+	int num_used = le16_to_cpu(entry_list->de_num_used);
+
+	if (num_used == 1 || index == (num_used - 1))
+		goto clear;
+
+	memmove(&entry_list->de_entries[index],
+		&entry_list->de_entries[index + 1],
+		(num_used - index - 1)*sizeof(struct ocfs2_dx_entry));
+clear:
+	num_used--;
+	memset(&entry_list->de_entries[num_used], 0,
+	       sizeof(struct ocfs2_dx_entry));
+	entry_list->de_num_used = cpu_to_le16(num_used);
+}
+
+static int ocfs2_delete_entry_dx(handle_t *handle, struct inode *dir,
+				 struct ocfs2_dir_lookup_result *lookup)
+{
+	int ret, index, max_rec_len, add_to_free_list = 0;
+	struct buffer_head *dx_root_bh = lookup->dl_dx_root_bh;
+	struct buffer_head *leaf_bh = lookup->dl_leaf_bh;
+	struct ocfs2_dx_leaf *dx_leaf;
+	struct ocfs2_dx_entry *dx_entry = lookup->dl_dx_entry;
+	struct ocfs2_dir_block_trailer *trailer;
+	struct ocfs2_dx_root_block *dx_root;
+	struct ocfs2_dx_entry_list *entry_list;
+
+	/*
+	 * This function gets a bit messy because we might have to
+	 * modify the root block, regardless of whether the indexed
+	 * entries are stored inline.
+	 */
+
+	/*
+	 * *Only* set 'entry_list' here, based on where we're looking
+	 * for the indexed entries. Later, we might still want to
+	 * journal both blocks, based on free list state.
+	 */
+	dx_root = (struct ocfs2_dx_root_block *)dx_root_bh->b_data;
+	if (ocfs2_dx_root_inline(dx_root)) {
+		entry_list = &dx_root->dr_entries;
+	} else {
+		dx_leaf = (struct ocfs2_dx_leaf *) lookup->dl_dx_leaf_bh->b_data;
+		entry_list = &dx_leaf->dl_list;
+	}
+
+	/* Neither of these are a disk corruption - that should have
+	 * been caught by lookup, before we got here. */
+	BUG_ON(le16_to_cpu(entry_list->de_count) <= 0);
+	BUG_ON(le16_to_cpu(entry_list->de_num_used) <= 0);
+
+	index = (char *)dx_entry - (char *)entry_list->de_entries;
+	index /= sizeof(*dx_entry);
+
+	if (index >= le16_to_cpu(entry_list->de_num_used)) {
+		mlog(ML_ERROR, "Dir %llu: Bad dx_entry ptr idx %d, (%p, %p)\n",
+		     (unsigned long long)OCFS2_I(dir)->ip_blkno, index,
+		     entry_list, dx_entry);
+		return -EIO;
+	}
+
+	/*
+	 * We know that removal of this dirent will leave enough room
+	 * for a new one, so add this block to the free list if it
+	 * isn't already there.
+	 */
+	trailer = ocfs2_trailer_from_bh(leaf_bh, dir->i_sb);
+	if (trailer->db_free_rec_len == 0)
+		add_to_free_list = 1;
+
+	/*
+	 * Add the block holding our index into the journal before
+	 * removing the unindexed entry. If we get an error return
+	 * from __ocfs2_delete_entry(), then it hasn't removed the
+	 * entry yet. Likewise, successful return means we *must*
+	 * remove the indexed entry.
+	 *
+	 * We're also careful to journal the root tree block here as
+	 * the entry count needs to be updated. Also, we might be
+	 * adding to the start of the free list.
+	 */
+	ret = ocfs2_journal_access_dr(handle, dir, dx_root_bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	if (!ocfs2_dx_root_inline(dx_root)) {
+		ret = ocfs2_journal_access_dl(handle, dir,
+					      lookup->dl_dx_leaf_bh,
+					      OCFS2_JOURNAL_ACCESS_WRITE);
+		if (ret) {
+			mlog_errno(ret);
+			goto out;
+		}
+	}
+
+	mlog(0, "Dir %llu: delete entry at index: %d\n",
+	     (unsigned long long)OCFS2_I(dir)->ip_blkno, index);
+
+	ret = __ocfs2_delete_entry(handle, dir, lookup->dl_entry,
+				   leaf_bh, leaf_bh->b_data, leaf_bh->b_size);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	max_rec_len = ocfs2_find_max_rec_len(dir->i_sb, leaf_bh);
+	trailer->db_free_rec_len = cpu_to_le16(max_rec_len);
+	if (add_to_free_list) {
+		trailer->db_free_next = dx_root->dr_free_blk;
+		dx_root->dr_free_blk = cpu_to_le64(leaf_bh->b_blocknr);
+		ocfs2_journal_dirty(handle, dx_root_bh);
+	}
+
+	/* leaf_bh was journal_accessed for us in __ocfs2_delete_entry */
+	ocfs2_journal_dirty(handle, leaf_bh);
+
+	le32_add_cpu(&dx_root->dr_num_entries, -1);
+	ocfs2_journal_dirty(handle, dx_root_bh);
+
+	ocfs2_dx_list_remove_entry(entry_list, index);
+
+	if (!ocfs2_dx_root_inline(dx_root))
+		ocfs2_journal_dirty(handle, lookup->dl_dx_leaf_bh);
+
+out:
+	return ret;
+}
+
 static inline int ocfs2_delete_entry_id(handle_t *handle,
 					struct inode *dir,
 					struct ocfs2_dir_entry *de_del,
@@ -624,18 +1413,22 @@
 }
 
 /*
- * ocfs2_delete_entry deletes a directory entry by merging it with the
- * previous entry
+ * Delete a directory entry. Hide the details of directory
+ * implementation from the caller.
  */
 int ocfs2_delete_entry(handle_t *handle,
 		       struct inode *dir,
-		       struct ocfs2_dir_entry *de_del,
-		       struct buffer_head *bh)
+		       struct ocfs2_dir_lookup_result *res)
 {
-	if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL)
-		return ocfs2_delete_entry_id(handle, dir, de_del, bh);
+	if (ocfs2_dir_indexed(dir))
+		return ocfs2_delete_entry_dx(handle, dir, res);
 
-	return ocfs2_delete_entry_el(handle, dir, de_del, bh);
+	if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL)
+		return ocfs2_delete_entry_id(handle, dir, res->dl_entry,
+					     res->dl_leaf_bh);
+
+	return ocfs2_delete_entry_el(handle, dir, res->dl_entry,
+				     res->dl_leaf_bh);
 }
 
 /*
@@ -663,18 +1456,166 @@
 	return 0;
 }
 
+static void ocfs2_dx_dir_leaf_insert_tail(struct ocfs2_dx_leaf *dx_leaf,
+					  struct ocfs2_dx_entry *dx_new_entry)
+{
+	int i;
+
+	i = le16_to_cpu(dx_leaf->dl_list.de_num_used);
+	dx_leaf->dl_list.de_entries[i] = *dx_new_entry;
+
+	le16_add_cpu(&dx_leaf->dl_list.de_num_used, 1);
+}
+
+static void ocfs2_dx_entry_list_insert(struct ocfs2_dx_entry_list *entry_list,
+				       struct ocfs2_dx_hinfo *hinfo,
+				       u64 dirent_blk)
+{
+	int i;
+	struct ocfs2_dx_entry *dx_entry;
+
+	i = le16_to_cpu(entry_list->de_num_used);
+	dx_entry = &entry_list->de_entries[i];
+
+	memset(dx_entry, 0, sizeof(*dx_entry));
+	dx_entry->dx_major_hash = cpu_to_le32(hinfo->major_hash);
+	dx_entry->dx_minor_hash = cpu_to_le32(hinfo->minor_hash);
+	dx_entry->dx_dirent_blk = cpu_to_le64(dirent_blk);
+
+	le16_add_cpu(&entry_list->de_num_used, 1);
+}
+
+static int __ocfs2_dx_dir_leaf_insert(struct inode *dir, handle_t *handle,
+				      struct ocfs2_dx_hinfo *hinfo,
+				      u64 dirent_blk,
+				      struct buffer_head *dx_leaf_bh)
+{
+	int ret;
+	struct ocfs2_dx_leaf *dx_leaf;
+
+	ret = ocfs2_journal_access_dl(handle, dir, dx_leaf_bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	dx_leaf = (struct ocfs2_dx_leaf *)dx_leaf_bh->b_data;
+	ocfs2_dx_entry_list_insert(&dx_leaf->dl_list, hinfo, dirent_blk);
+	ocfs2_journal_dirty(handle, dx_leaf_bh);
+
+out:
+	return ret;
+}
+
+static void ocfs2_dx_inline_root_insert(struct inode *dir, handle_t *handle,
+					struct ocfs2_dx_hinfo *hinfo,
+					u64 dirent_blk,
+					struct ocfs2_dx_root_block *dx_root)
+{
+	ocfs2_dx_entry_list_insert(&dx_root->dr_entries, hinfo, dirent_blk);
+}
+
+static int ocfs2_dx_dir_insert(struct inode *dir, handle_t *handle,
+			       struct ocfs2_dir_lookup_result *lookup)
+{
+	int ret = 0;
+	struct ocfs2_dx_root_block *dx_root;
+	struct buffer_head *dx_root_bh = lookup->dl_dx_root_bh;
+
+	ret = ocfs2_journal_access_dr(handle, dir, dx_root_bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	dx_root = (struct ocfs2_dx_root_block *)lookup->dl_dx_root_bh->b_data;
+	if (ocfs2_dx_root_inline(dx_root)) {
+		ocfs2_dx_inline_root_insert(dir, handle,
+					    &lookup->dl_hinfo,
+					    lookup->dl_leaf_bh->b_blocknr,
+					    dx_root);
+	} else {
+		ret = __ocfs2_dx_dir_leaf_insert(dir, handle, &lookup->dl_hinfo,
+						 lookup->dl_leaf_bh->b_blocknr,
+						 lookup->dl_dx_leaf_bh);
+		if (ret)
+			goto out;
+	}
+
+	le32_add_cpu(&dx_root->dr_num_entries, 1);
+	ocfs2_journal_dirty(handle, dx_root_bh);
+
+out:
+	return ret;
+}
+
+static void ocfs2_remove_block_from_free_list(struct inode *dir,
+				       handle_t *handle,
+				       struct ocfs2_dir_lookup_result *lookup)
+{
+	struct ocfs2_dir_block_trailer *trailer, *prev;
+	struct ocfs2_dx_root_block *dx_root;
+	struct buffer_head *bh;
+
+	trailer = ocfs2_trailer_from_bh(lookup->dl_leaf_bh, dir->i_sb);
+
+	if (ocfs2_free_list_at_root(lookup)) {
+		bh = lookup->dl_dx_root_bh;
+		dx_root = (struct ocfs2_dx_root_block *)bh->b_data;
+		dx_root->dr_free_blk = trailer->db_free_next;
+	} else {
+		bh = lookup->dl_prev_leaf_bh;
+		prev = ocfs2_trailer_from_bh(bh, dir->i_sb);
+		prev->db_free_next = trailer->db_free_next;
+	}
+
+	trailer->db_free_rec_len = cpu_to_le16(0);
+	trailer->db_free_next = cpu_to_le64(0);
+
+	ocfs2_journal_dirty(handle, bh);
+	ocfs2_journal_dirty(handle, lookup->dl_leaf_bh);
+}
+
+/*
+ * This expects that a journal write has been reserved on
+ * lookup->dl_prev_leaf_bh or lookup->dl_dx_root_bh
+ */
+static void ocfs2_recalc_free_list(struct inode *dir, handle_t *handle,
+				   struct ocfs2_dir_lookup_result *lookup)
+{
+	int max_rec_len;
+	struct ocfs2_dir_block_trailer *trailer;
+
+	/* Walk dl_leaf_bh to figure out what the new free rec_len is. */
+	max_rec_len = ocfs2_find_max_rec_len(dir->i_sb, lookup->dl_leaf_bh);
+	if (max_rec_len) {
+		/*
+		 * There's still room in this block, so no need to remove it
+		 * from the free list. In this case, we just want to update
+		 * the rec len accounting.
+		 */
+		trailer = ocfs2_trailer_from_bh(lookup->dl_leaf_bh, dir->i_sb);
+		trailer->db_free_rec_len = cpu_to_le16(max_rec_len);
+		ocfs2_journal_dirty(handle, lookup->dl_leaf_bh);
+	} else {
+		ocfs2_remove_block_from_free_list(dir, handle, lookup);
+	}
+}
+
 /* we don't always have a dentry for what we want to add, so people
  * like orphan dir can call this instead.
  *
- * If you pass me insert_bh, I'll skip the search of the other dir
- * blocks and put the record in there.
+ * The lookup context must have been filled from
+ * ocfs2_prepare_dir_for_insert.
  */
 int __ocfs2_add_entry(handle_t *handle,
 		      struct inode *dir,
 		      const char *name, int namelen,
 		      struct inode *inode, u64 blkno,
 		      struct buffer_head *parent_fe_bh,
-		      struct buffer_head *insert_bh)
+		      struct ocfs2_dir_lookup_result *lookup)
 {
 	unsigned long offset;
 	unsigned short rec_len;
@@ -683,6 +1624,7 @@
 	struct super_block *sb = dir->i_sb;
 	int retval, status;
 	unsigned int size = sb->s_blocksize;
+	struct buffer_head *insert_bh = lookup->dl_leaf_bh;
 	char *data_start = insert_bh->b_data;
 
 	mlog_entry_void();
@@ -690,7 +1632,31 @@
 	if (!namelen)
 		return -EINVAL;
 
-	if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
+	if (ocfs2_dir_indexed(dir)) {
+		struct buffer_head *bh;
+
+		/*
+		 * An indexed dir may require that we update the free space
+		 * list. Reserve a write to the previous node in the list so
+		 * that we don't fail later.
+		 *
+		 * XXX: This can be either a dx_root_block, or an unindexed
+		 * directory tree leaf block.
+		 */
+		if (ocfs2_free_list_at_root(lookup)) {
+			bh = lookup->dl_dx_root_bh;
+			retval = ocfs2_journal_access_dr(handle, dir, bh,
+						 OCFS2_JOURNAL_ACCESS_WRITE);
+		} else {
+			bh = lookup->dl_prev_leaf_bh;
+			retval = ocfs2_journal_access_db(handle, dir, bh,
+						 OCFS2_JOURNAL_ACCESS_WRITE);
+		}
+		if (retval) {
+			mlog_errno(retval);
+			return retval;
+		}
+	} else if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
 		data_start = di->id2.i_data.id_data;
 		size = i_size_read(dir);
 
@@ -737,10 +1703,22 @@
 				status = ocfs2_journal_access_di(handle, dir,
 								 insert_bh,
 								 OCFS2_JOURNAL_ACCESS_WRITE);
-			else
+			else {
 				status = ocfs2_journal_access_db(handle, dir,
 								 insert_bh,
-								 OCFS2_JOURNAL_ACCESS_WRITE);
+					      OCFS2_JOURNAL_ACCESS_WRITE);
+
+				if (ocfs2_dir_indexed(dir)) {
+					status = ocfs2_dx_dir_insert(dir,
+								handle,
+								lookup);
+					if (status) {
+						mlog_errno(status);
+						goto bail;
+					}
+				}
+			}
+
 			/* By now the buffer is marked for journaling */
 			offset += le16_to_cpu(de->rec_len);
 			if (le64_to_cpu(de->inode)) {
@@ -761,6 +1739,9 @@
 			de->name_len = namelen;
 			memcpy(de->name, name, namelen);
 
+			if (ocfs2_dir_indexed(dir))
+				ocfs2_recalc_free_list(dir, handle, lookup);
+
 			dir->i_version++;
 			status = ocfs2_journal_dirty(handle, insert_bh);
 			retval = 0;
@@ -870,6 +1851,10 @@
 	return 0;
 }
 
+/*
+ * NOTE: This function can be called against unindexed directories,
+ * and indexed ones.
+ */
 static int ocfs2_dir_foreach_blk_el(struct inode *inode,
 				    u64 *f_version,
 				    loff_t *f_pos, void *priv,
@@ -1071,31 +2056,22 @@
 			     int namelen,
 			     u64 *blkno,
 			     struct inode *inode,
-			     struct buffer_head **dirent_bh,
-			     struct ocfs2_dir_entry **dirent)
+			     struct ocfs2_dir_lookup_result *lookup)
 {
 	int status = -ENOENT;
 
-	mlog_entry("(name=%.*s, blkno=%p, inode=%p, dirent_bh=%p, dirent=%p)\n",
-		   namelen, name, blkno, inode, dirent_bh, dirent);
+	mlog(0, "name=%.*s, blkno=%p, inode=%llu\n", namelen, name, blkno,
+	     (unsigned long long)OCFS2_I(inode)->ip_blkno);
 
-	*dirent_bh = ocfs2_find_entry(name, namelen, inode, dirent);
-	if (!*dirent_bh || !*dirent) {
-		status = -ENOENT;
+	status = ocfs2_find_entry(name, namelen, inode, lookup);
+	if (status)
 		goto leave;
-	}
 
-	*blkno = le64_to_cpu((*dirent)->inode);
+	*blkno = le64_to_cpu(lookup->dl_entry->inode);
 
 	status = 0;
 leave:
-	if (status < 0) {
-		*dirent = NULL;
-		brelse(*dirent_bh);
-		*dirent_bh = NULL;
-	}
 
-	mlog_exit(status);
 	return status;
 }
 
@@ -1107,11 +2083,10 @@
 			       int namelen, u64 *blkno)
 {
 	int ret;
-	struct buffer_head *bh = NULL;
-	struct ocfs2_dir_entry *dirent = NULL;
+	struct ocfs2_dir_lookup_result lookup = { NULL, };
 
-	ret = ocfs2_find_files_on_disk(name, namelen, blkno, dir, &bh, &dirent);
-	brelse(bh);
+	ret = ocfs2_find_files_on_disk(name, namelen, blkno, dir, &lookup);
+	ocfs2_free_dir_lookup_result(&lookup);
 
 	return ret;
 }
@@ -1128,20 +2103,18 @@
 			      int namelen)
 {
 	int ret;
-	struct buffer_head *dirent_bh = NULL;
-	struct ocfs2_dir_entry *dirent = NULL;
+	struct ocfs2_dir_lookup_result lookup = { NULL, };
 
 	mlog_entry("dir %llu, name '%.*s'\n",
 		   (unsigned long long)OCFS2_I(dir)->ip_blkno, namelen, name);
 
 	ret = -EEXIST;
-	dirent_bh = ocfs2_find_entry(name, namelen, dir, &dirent);
-	if (dirent_bh)
+	if (ocfs2_find_entry(name, namelen, dir, &lookup) == 0)
 		goto bail;
 
 	ret = 0;
 bail:
-	brelse(dirent_bh);
+	ocfs2_free_dir_lookup_result(&lookup);
 
 	mlog_exit(ret);
 	return ret;
@@ -1151,6 +2124,7 @@
 	unsigned seen_dot;
 	unsigned seen_dot_dot;
 	unsigned seen_other;
+	unsigned dx_dir;
 };
 static int ocfs2_empty_dir_filldir(void *priv, const char *name, int name_len,
 				   loff_t pos, u64 ino, unsigned type)
@@ -1160,6 +2134,13 @@
 	/*
 	 * Check the positions of "." and ".." records to be sure
 	 * they're in the correct place.
+	 *
+	 * Indexed directories don't need to proceed past the first
+	 * two entries, so we end the scan after seeing '..'. Despite
+	 * that, we allow the scan to proceed In the event that we
+	 * have a corrupted indexed directory (no dot or dot dot
+	 * entries). This allows us to double check for existing
+	 * entries which might not have been found in the index.
 	 */
 	if (name_len == 1 && !strncmp(".", name, 1) && pos == 0) {
 		p->seen_dot = 1;
@@ -1169,16 +2150,57 @@
 	if (name_len == 2 && !strncmp("..", name, 2) &&
 	    pos == OCFS2_DIR_REC_LEN(1)) {
 		p->seen_dot_dot = 1;
+
+		if (p->dx_dir && p->seen_dot)
+			return 1;
+
 		return 0;
 	}
 
 	p->seen_other = 1;
 	return 1;
 }
+
+static int ocfs2_empty_dir_dx(struct inode *inode,
+			      struct ocfs2_empty_dir_priv *priv)
+{
+	int ret;
+	struct buffer_head *di_bh = NULL;
+	struct buffer_head *dx_root_bh = NULL;
+	struct ocfs2_dinode *di;
+	struct ocfs2_dx_root_block *dx_root;
+
+	priv->dx_dir = 1;
+
+	ret = ocfs2_read_inode_block(inode, &di_bh);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+	di = (struct ocfs2_dinode *)di_bh->b_data;
+
+	ret = ocfs2_read_dx_root(inode, di, &dx_root_bh);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+	dx_root = (struct ocfs2_dx_root_block *)dx_root_bh->b_data;
+
+	if (le32_to_cpu(dx_root->dr_num_entries) != 2)
+		priv->seen_other = 1;
+
+out:
+	brelse(di_bh);
+	brelse(dx_root_bh);
+	return ret;
+}
+
 /*
  * routine to check that the specified directory is empty (for rmdir)
  *
  * Returns 1 if dir is empty, zero otherwise.
+ *
+ * XXX: This is a performance problem for unindexed directories.
  */
 int ocfs2_empty_dir(struct inode *inode)
 {
@@ -1188,6 +2210,16 @@
 
 	memset(&priv, 0, sizeof(priv));
 
+	if (ocfs2_dir_indexed(inode)) {
+		ret = ocfs2_empty_dir_dx(inode, &priv);
+		if (ret)
+			mlog_errno(ret);
+		/*
+		 * We still run ocfs2_dir_foreach to get the checks
+		 * for "." and "..".
+		 */
+	}
+
 	ret = ocfs2_dir_foreach(inode, &start, &priv, ocfs2_empty_dir_filldir);
 	if (ret)
 		mlog_errno(ret);
@@ -1280,7 +2312,8 @@
 				 struct inode *parent,
 				 struct inode *inode,
 				 struct buffer_head *fe_bh,
-				 struct ocfs2_alloc_context *data_ac)
+				 struct ocfs2_alloc_context *data_ac,
+				 struct buffer_head **ret_new_bh)
 {
 	int status;
 	unsigned int size = osb->sb->s_blocksize;
@@ -1289,7 +2322,7 @@
 
 	mlog_entry_void();
 
-	if (ocfs2_supports_dir_trailer(osb))
+	if (ocfs2_new_dir_wants_trailer(inode))
 		size = ocfs2_dir_trailer_blk_off(parent->i_sb);
 
 	status = ocfs2_do_extend_dir(osb->sb, handle, inode, fe_bh,
@@ -1310,8 +2343,19 @@
 	memset(new_bh->b_data, 0, osb->sb->s_blocksize);
 
 	de = ocfs2_fill_initial_dirents(inode, parent, new_bh->b_data, size);
-	if (ocfs2_supports_dir_trailer(osb))
-		ocfs2_init_dir_trailer(inode, new_bh);
+	if (ocfs2_new_dir_wants_trailer(inode)) {
+		int size = le16_to_cpu(de->rec_len);
+
+		/*
+		 * Figure out the size of the hole left over after
+		 * insertion of '.' and '..'. The trailer wants this
+		 * information.
+		 */
+		size -= OCFS2_DIR_REC_LEN(2);
+		size -= sizeof(struct ocfs2_dir_block_trailer);
+
+		ocfs2_init_dir_trailer(inode, new_bh, size);
+	}
 
 	status = ocfs2_journal_dirty(handle, new_bh);
 	if (status < 0) {
@@ -1329,6 +2373,10 @@
 	}
 
 	status = 0;
+	if (ret_new_bh) {
+		*ret_new_bh = new_bh;
+		new_bh = NULL;
+	}
 bail:
 	brelse(new_bh);
 
@@ -1336,20 +2384,427 @@
 	return status;
 }
 
+static int ocfs2_dx_dir_attach_index(struct ocfs2_super *osb,
+				     handle_t *handle, struct inode *dir,
+				     struct buffer_head *di_bh,
+				     struct buffer_head *dirdata_bh,
+				     struct ocfs2_alloc_context *meta_ac,
+				     int dx_inline, u32 num_entries,
+				     struct buffer_head **ret_dx_root_bh)
+{
+	int ret;
+	struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data;
+	u16 dr_suballoc_bit;
+	u64 dr_blkno;
+	unsigned int num_bits;
+	struct buffer_head *dx_root_bh = NULL;
+	struct ocfs2_dx_root_block *dx_root;
+	struct ocfs2_dir_block_trailer *trailer =
+		ocfs2_trailer_from_bh(dirdata_bh, dir->i_sb);
+
+	ret = ocfs2_claim_metadata(osb, handle, meta_ac, 1, &dr_suballoc_bit,
+				   &num_bits, &dr_blkno);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	mlog(0, "Dir %llu, attach new index block: %llu\n",
+	     (unsigned long long)OCFS2_I(dir)->ip_blkno,
+	     (unsigned long long)dr_blkno);
+
+	dx_root_bh = sb_getblk(osb->sb, dr_blkno);
+	if (dx_root_bh == NULL) {
+		ret = -EIO;
+		goto out;
+	}
+	ocfs2_set_new_buffer_uptodate(dir, dx_root_bh);
+
+	ret = ocfs2_journal_access_dr(handle, dir, dx_root_bh,
+				      OCFS2_JOURNAL_ACCESS_CREATE);
+	if (ret < 0) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	dx_root = (struct ocfs2_dx_root_block *)dx_root_bh->b_data;
+	memset(dx_root, 0, osb->sb->s_blocksize);
+	strcpy(dx_root->dr_signature, OCFS2_DX_ROOT_SIGNATURE);
+	dx_root->dr_suballoc_slot = cpu_to_le16(osb->slot_num);
+	dx_root->dr_suballoc_bit = cpu_to_le16(dr_suballoc_bit);
+	dx_root->dr_fs_generation = cpu_to_le32(osb->fs_generation);
+	dx_root->dr_blkno = cpu_to_le64(dr_blkno);
+	dx_root->dr_dir_blkno = cpu_to_le64(OCFS2_I(dir)->ip_blkno);
+	dx_root->dr_num_entries = cpu_to_le32(num_entries);
+	if (le16_to_cpu(trailer->db_free_rec_len))
+		dx_root->dr_free_blk = cpu_to_le64(dirdata_bh->b_blocknr);
+	else
+		dx_root->dr_free_blk = cpu_to_le64(0);
+
+	if (dx_inline) {
+		dx_root->dr_flags |= OCFS2_DX_FLAG_INLINE;
+		dx_root->dr_entries.de_count =
+			cpu_to_le16(ocfs2_dx_entries_per_root(osb->sb));
+	} else {
+		dx_root->dr_list.l_count =
+			cpu_to_le16(ocfs2_extent_recs_per_dx_root(osb->sb));
+	}
+
+	ret = ocfs2_journal_dirty(handle, dx_root_bh);
+	if (ret)
+		mlog_errno(ret);
+
+	ret = ocfs2_journal_access_di(handle, dir, di_bh,
+				      OCFS2_JOURNAL_ACCESS_CREATE);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	di->i_dx_root = cpu_to_le64(dr_blkno);
+
+	OCFS2_I(dir)->ip_dyn_features |= OCFS2_INDEXED_DIR_FL;
+	di->i_dyn_features = cpu_to_le16(OCFS2_I(dir)->ip_dyn_features);
+
+	ret = ocfs2_journal_dirty(handle, di_bh);
+	if (ret)
+		mlog_errno(ret);
+
+	*ret_dx_root_bh = dx_root_bh;
+	dx_root_bh = NULL;
+
+out:
+	brelse(dx_root_bh);
+	return ret;
+}
+
+static int ocfs2_dx_dir_format_cluster(struct ocfs2_super *osb,
+				       handle_t *handle, struct inode *dir,
+				       struct buffer_head **dx_leaves,
+				       int num_dx_leaves, u64 start_blk)
+{
+	int ret, i;
+	struct ocfs2_dx_leaf *dx_leaf;
+	struct buffer_head *bh;
+
+	for (i = 0; i < num_dx_leaves; i++) {
+		bh = sb_getblk(osb->sb, start_blk + i);
+		if (bh == NULL) {
+			ret = -EIO;
+			goto out;
+		}
+		dx_leaves[i] = bh;
+
+		ocfs2_set_new_buffer_uptodate(dir, bh);
+
+		ret = ocfs2_journal_access_dl(handle, dir, bh,
+					      OCFS2_JOURNAL_ACCESS_CREATE);
+		if (ret < 0) {
+			mlog_errno(ret);
+			goto out;
+		}
+
+		dx_leaf = (struct ocfs2_dx_leaf *) bh->b_data;
+
+		memset(dx_leaf, 0, osb->sb->s_blocksize);
+		strcpy(dx_leaf->dl_signature, OCFS2_DX_LEAF_SIGNATURE);
+		dx_leaf->dl_fs_generation = cpu_to_le32(osb->fs_generation);
+		dx_leaf->dl_blkno = cpu_to_le64(bh->b_blocknr);
+		dx_leaf->dl_list.de_count =
+			cpu_to_le16(ocfs2_dx_entries_per_leaf(osb->sb));
+
+		mlog(0,
+		     "Dir %llu, format dx_leaf: %llu, entry count: %u\n",
+		     (unsigned long long)OCFS2_I(dir)->ip_blkno,
+		     (unsigned long long)bh->b_blocknr,
+		     le16_to_cpu(dx_leaf->dl_list.de_count));
+
+		ocfs2_journal_dirty(handle, bh);
+	}
+
+	ret = 0;
+out:
+	return ret;
+}
+
+/*
+ * Allocates and formats a new cluster for use in an indexed dir
+ * leaf. This version will not do the extent insert, so that it can be
+ * used by operations which need careful ordering.
+ */
+static int __ocfs2_dx_dir_new_cluster(struct inode *dir,
+				      u32 cpos, handle_t *handle,
+				      struct ocfs2_alloc_context *data_ac,
+				      struct buffer_head **dx_leaves,
+				      int num_dx_leaves, u64 *ret_phys_blkno)
+{
+	int ret;
+	u32 phys, num;
+	u64 phys_blkno;
+	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
+
+	/*
+	 * XXX: For create, this should claim cluster for the index
+	 * *before* the unindexed insert so that we have a better
+	 * chance of contiguousness as the directory grows in number
+	 * of entries.
+	 */
+	ret = __ocfs2_claim_clusters(osb, handle, data_ac, 1, 1, &phys, &num);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	/*
+	 * Format the new cluster first. That way, we're inserting
+	 * valid data.
+	 */
+	phys_blkno = ocfs2_clusters_to_blocks(osb->sb, phys);
+	ret = ocfs2_dx_dir_format_cluster(osb, handle, dir, dx_leaves,
+					  num_dx_leaves, phys_blkno);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	*ret_phys_blkno = phys_blkno;
+out:
+	return ret;
+}
+
+static int ocfs2_dx_dir_new_cluster(struct inode *dir,
+				    struct ocfs2_extent_tree *et,
+				    u32 cpos, handle_t *handle,
+				    struct ocfs2_alloc_context *data_ac,
+				    struct ocfs2_alloc_context *meta_ac,
+				    struct buffer_head **dx_leaves,
+				    int num_dx_leaves)
+{
+	int ret;
+	u64 phys_blkno;
+	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
+
+	ret = __ocfs2_dx_dir_new_cluster(dir, cpos, handle, data_ac, dx_leaves,
+					 num_dx_leaves, &phys_blkno);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	ret = ocfs2_insert_extent(osb, handle, dir, et, cpos, phys_blkno, 1, 0,
+				  meta_ac);
+	if (ret)
+		mlog_errno(ret);
+out:
+	return ret;
+}
+
+static struct buffer_head **ocfs2_dx_dir_kmalloc_leaves(struct super_block *sb,
+							int *ret_num_leaves)
+{
+	int num_dx_leaves = ocfs2_clusters_to_blocks(sb, 1);
+	struct buffer_head **dx_leaves;
+
+	dx_leaves = kcalloc(num_dx_leaves, sizeof(struct buffer_head *),
+			    GFP_NOFS);
+	if (dx_leaves && ret_num_leaves)
+		*ret_num_leaves = num_dx_leaves;
+
+	return dx_leaves;
+}
+
+static int ocfs2_fill_new_dir_dx(struct ocfs2_super *osb,
+				 handle_t *handle,
+				 struct inode *parent,
+				 struct inode *inode,
+				 struct buffer_head *di_bh,
+				 struct ocfs2_alloc_context *data_ac,
+				 struct ocfs2_alloc_context *meta_ac)
+{
+	int ret;
+	struct buffer_head *leaf_bh = NULL;
+	struct buffer_head *dx_root_bh = NULL;
+	struct ocfs2_dx_hinfo hinfo;
+	struct ocfs2_dx_root_block *dx_root;
+	struct ocfs2_dx_entry_list *entry_list;
+
+	/*
+	 * Our strategy is to create the directory as though it were
+	 * unindexed, then add the index block. This works with very
+	 * little complication since the state of a new directory is a
+	 * very well known quantity.
+	 *
+	 * Essentially, we have two dirents ("." and ".."), in the 1st
+	 * block which need indexing. These are easily inserted into
+	 * the index block.
+	 */
+
+	ret = ocfs2_fill_new_dir_el(osb, handle, parent, inode, di_bh,
+				    data_ac, &leaf_bh);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	ret = ocfs2_dx_dir_attach_index(osb, handle, inode, di_bh, leaf_bh,
+					meta_ac, 1, 2, &dx_root_bh);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+	dx_root = (struct ocfs2_dx_root_block *)dx_root_bh->b_data;
+	entry_list = &dx_root->dr_entries;
+
+	/* Buffer has been journaled for us by ocfs2_dx_dir_attach_index */
+	ocfs2_dx_dir_name_hash(inode, ".", 1, &hinfo);
+	ocfs2_dx_entry_list_insert(entry_list, &hinfo, leaf_bh->b_blocknr);
+
+	ocfs2_dx_dir_name_hash(inode, "..", 2, &hinfo);
+	ocfs2_dx_entry_list_insert(entry_list, &hinfo, leaf_bh->b_blocknr);
+
+out:
+	brelse(dx_root_bh);
+	brelse(leaf_bh);
+	return ret;
+}
+
 int ocfs2_fill_new_dir(struct ocfs2_super *osb,
 		       handle_t *handle,
 		       struct inode *parent,
 		       struct inode *inode,
 		       struct buffer_head *fe_bh,
-		       struct ocfs2_alloc_context *data_ac)
+		       struct ocfs2_alloc_context *data_ac,
+		       struct ocfs2_alloc_context *meta_ac)
+
 {
 	BUG_ON(!ocfs2_supports_inline_data(osb) && data_ac == NULL);
 
 	if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL)
 		return ocfs2_fill_new_dir_id(osb, handle, parent, inode, fe_bh);
 
+	if (ocfs2_supports_indexed_dirs(osb))
+		return ocfs2_fill_new_dir_dx(osb, handle, parent, inode, fe_bh,
+					     data_ac, meta_ac);
+
 	return ocfs2_fill_new_dir_el(osb, handle, parent, inode, fe_bh,
-				     data_ac);
+				     data_ac, NULL);
+}
+
+static int ocfs2_dx_dir_index_block(struct inode *dir,
+				    handle_t *handle,
+				    struct buffer_head **dx_leaves,
+				    int num_dx_leaves,
+				    u32 *num_dx_entries,
+				    struct buffer_head *dirent_bh)
+{
+	int ret, namelen, i;
+	char *de_buf, *limit;
+	struct ocfs2_dir_entry *de;
+	struct buffer_head *dx_leaf_bh;
+	struct ocfs2_dx_hinfo hinfo;
+	u64 dirent_blk = dirent_bh->b_blocknr;
+
+	de_buf = dirent_bh->b_data;
+	limit = de_buf + dir->i_sb->s_blocksize;
+
+	while (de_buf < limit) {
+		de = (struct ocfs2_dir_entry *)de_buf;
+
+		namelen = de->name_len;
+		if (!namelen || !de->inode)
+			goto inc;
+
+		ocfs2_dx_dir_name_hash(dir, de->name, namelen, &hinfo);
+
+		i = ocfs2_dx_dir_hash_idx(OCFS2_SB(dir->i_sb), &hinfo);
+		dx_leaf_bh = dx_leaves[i];
+
+		ret = __ocfs2_dx_dir_leaf_insert(dir, handle, &hinfo,
+						 dirent_blk, dx_leaf_bh);
+		if (ret) {
+			mlog_errno(ret);
+			goto out;
+		}
+
+		*num_dx_entries = *num_dx_entries + 1;
+
+inc:
+		de_buf += le16_to_cpu(de->rec_len);
+	}
+
+out:
+	return ret;
+}
+
+/*
+ * XXX: This expects dx_root_bh to already be part of the transaction.
+ */
+static void ocfs2_dx_dir_index_root_block(struct inode *dir,
+					 struct buffer_head *dx_root_bh,
+					 struct buffer_head *dirent_bh)
+{
+	char *de_buf, *limit;
+	struct ocfs2_dx_root_block *dx_root;
+	struct ocfs2_dir_entry *de;
+	struct ocfs2_dx_hinfo hinfo;
+	u64 dirent_blk = dirent_bh->b_blocknr;
+
+	dx_root = (struct ocfs2_dx_root_block *)dx_root_bh->b_data;
+
+	de_buf = dirent_bh->b_data;
+	limit = de_buf + dir->i_sb->s_blocksize;
+
+	while (de_buf < limit) {
+		de = (struct ocfs2_dir_entry *)de_buf;
+
+		if (!de->name_len || !de->inode)
+			goto inc;
+
+		ocfs2_dx_dir_name_hash(dir, de->name, de->name_len, &hinfo);
+
+		mlog(0,
+		     "dir: %llu, major: 0x%x minor: 0x%x, index: %u, name: %.*s\n",
+		     (unsigned long long)dir->i_ino, hinfo.major_hash,
+		     hinfo.minor_hash,
+		     le16_to_cpu(dx_root->dr_entries.de_num_used),
+		     de->name_len, de->name);
+
+		ocfs2_dx_entry_list_insert(&dx_root->dr_entries, &hinfo,
+					   dirent_blk);
+
+		le32_add_cpu(&dx_root->dr_num_entries, 1);
+inc:
+		de_buf += le16_to_cpu(de->rec_len);
+	}
+}
+
+/*
+ * Count the number of inline directory entries in di_bh and compare
+ * them against the number of entries we can hold in an inline dx root
+ * block.
+ */
+static int ocfs2_new_dx_should_be_inline(struct inode *dir,
+					 struct buffer_head *di_bh)
+{
+	int dirent_count = 0;
+	char *de_buf, *limit;
+	struct ocfs2_dir_entry *de;
+	struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
+
+	de_buf = di->id2.i_data.id_data;
+	limit = de_buf + i_size_read(dir);
+
+	while (de_buf < limit) {
+		de = (struct ocfs2_dir_entry *)de_buf;
+
+		if (de->name_len && de->inode)
+			dirent_count++;
+
+		de_buf += le16_to_cpu(de->rec_len);
+	}
+
+	/* We are careful to leave room for one extra record. */
+	return dirent_count < ocfs2_dx_entries_per_root(dir->i_sb);
 }
 
 /*
@@ -1358,18 +2813,26 @@
  * expansion from an inline directory to one with extents. The first dir block
  * in that case is taken from the inline data portion of the inode block.
  *
+ * This will also return the largest amount of contiguous space for a dirent
+ * in the block. That value is *not* necessarily the last dirent, even after
+ * expansion. The directory indexing code wants this value for free space
+ * accounting. We do this here since we're already walking the entire dir
+ * block.
+ *
  * We add the dir trailer if this filesystem wants it.
  */
-static void ocfs2_expand_last_dirent(char *start, unsigned int old_size,
-				     struct super_block *sb)
+static unsigned int ocfs2_expand_last_dirent(char *start, unsigned int old_size,
+					     struct inode *dir)
 {
+	struct super_block *sb = dir->i_sb;
 	struct ocfs2_dir_entry *de;
 	struct ocfs2_dir_entry *prev_de;
 	char *de_buf, *limit;
 	unsigned int new_size = sb->s_blocksize;
-	unsigned int bytes;
+	unsigned int bytes, this_hole;
+	unsigned int largest_hole = 0;
 
-	if (ocfs2_supports_dir_trailer(OCFS2_SB(sb)))
+	if (ocfs2_new_dir_wants_trailer(dir))
 		new_size = ocfs2_dir_trailer_blk_off(sb);
 
 	bytes = new_size - old_size;
@@ -1378,12 +2841,26 @@
 	de_buf = start;
 	de = (struct ocfs2_dir_entry *)de_buf;
 	do {
+		this_hole = ocfs2_figure_dirent_hole(de);
+		if (this_hole > largest_hole)
+			largest_hole = this_hole;
+
 		prev_de = de;
 		de_buf += le16_to_cpu(de->rec_len);
 		de = (struct ocfs2_dir_entry *)de_buf;
 	} while (de_buf < limit);
 
 	le16_add_cpu(&prev_de->rec_len, bytes);
+
+	/* We need to double check this after modification of the final
+	 * dirent. */
+	this_hole = ocfs2_figure_dirent_hole(prev_de);
+	if (this_hole > largest_hole)
+		largest_hole = this_hole;
+
+	if (largest_hole >= OCFS2_DIR_MIN_REC_LEN)
+		return largest_hole;
+	return 0;
 }
 
 /*
@@ -1396,29 +2873,61 @@
  */
 static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh,
 				   unsigned int blocks_wanted,
+				   struct ocfs2_dir_lookup_result *lookup,
 				   struct buffer_head **first_block_bh)
 {
-	u32 alloc, bit_off, len;
+	u32 alloc, dx_alloc, bit_off, len, num_dx_entries = 0;
 	struct super_block *sb = dir->i_sb;
-	int ret, credits = ocfs2_inline_to_extents_credits(sb);
-	u64 blkno, bytes = blocks_wanted << sb->s_blocksize_bits;
+	int ret, i, num_dx_leaves = 0, dx_inline = 0,
+		credits = ocfs2_inline_to_extents_credits(sb);
+	u64 dx_insert_blkno, blkno,
+		bytes = blocks_wanted << sb->s_blocksize_bits;
 	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
 	struct ocfs2_inode_info *oi = OCFS2_I(dir);
 	struct ocfs2_alloc_context *data_ac;
+	struct ocfs2_alloc_context *meta_ac = NULL;
 	struct buffer_head *dirdata_bh = NULL;
+	struct buffer_head *dx_root_bh = NULL;
+	struct buffer_head **dx_leaves = NULL;
 	struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
 	handle_t *handle;
 	struct ocfs2_extent_tree et;
-	int did_quota = 0;
+	struct ocfs2_extent_tree dx_et;
+	int did_quota = 0, bytes_allocated = 0;
 
 	ocfs2_init_dinode_extent_tree(&et, dir, di_bh);
 
 	alloc = ocfs2_clusters_for_bytes(sb, bytes);
+	dx_alloc = 0;
+
+	if (ocfs2_supports_indexed_dirs(osb)) {
+		credits += ocfs2_add_dir_index_credits(sb);
+
+		dx_inline = ocfs2_new_dx_should_be_inline(dir, di_bh);
+		if (!dx_inline) {
+			/* Add one more cluster for an index leaf */
+			dx_alloc++;
+			dx_leaves = ocfs2_dx_dir_kmalloc_leaves(sb,
+								&num_dx_leaves);
+			if (!dx_leaves) {
+				ret = -ENOMEM;
+				mlog_errno(ret);
+				goto out;
+			}
+		}
+
+		/* This gets us the dx_root */
+		ret = ocfs2_reserve_new_metadata_blocks(osb, 1, &meta_ac);
+		if (ret) {
+			mlog_errno(ret);
+			goto out;
+		}
+	}
 
 	/*
-	 * We should never need more than 2 clusters for this -
-	 * maximum dirent size is far less than one block. In fact,
-	 * the only time we'd need more than one cluster is if
+	 * We should never need more than 2 clusters for the unindexed
+	 * tree - maximum dirent size is far less than one block. In
+	 * fact, the only time we'd need more than one cluster is if
 	 * blocksize == clustersize and the dirent won't fit in the
 	 * extra space that the expansion to a single block gives. As
 	 * of today, that only happens on 4k/4k file systems.
@@ -1435,7 +2944,7 @@
 
 	/*
 	 * Prepare for worst case allocation scenario of two separate
-	 * extents.
+	 * extents in the unindexed tree.
 	 */
 	if (alloc == 2)
 		credits += OCFS2_SUBALLOC_ALLOC;
@@ -1448,11 +2957,29 @@
 	}
 
 	if (vfs_dq_alloc_space_nodirty(dir,
-				ocfs2_clusters_to_bytes(osb->sb, alloc))) {
+				ocfs2_clusters_to_bytes(osb->sb,
+							alloc + dx_alloc))) {
 		ret = -EDQUOT;
 		goto out_commit;
 	}
 	did_quota = 1;
+
+	if (ocfs2_supports_indexed_dirs(osb) && !dx_inline) {
+		/*
+		 * Allocate our index cluster first, to maximize the
+		 * possibility that unindexed leaves grow
+		 * contiguously.
+		 */
+		ret = __ocfs2_dx_dir_new_cluster(dir, 0, handle, data_ac,
+						 dx_leaves, num_dx_leaves,
+						 &dx_insert_blkno);
+		if (ret) {
+			mlog_errno(ret);
+			goto out_commit;
+		}
+		bytes_allocated += ocfs2_clusters_to_bytes(dir->i_sb, 1);
+	}
+
 	/*
 	 * Try to claim as many clusters as the bitmap can give though
 	 * if we only get one now, that's enough to continue. The rest
@@ -1463,6 +2990,7 @@
 		mlog_errno(ret);
 		goto out_commit;
 	}
+	bytes_allocated += ocfs2_clusters_to_bytes(dir->i_sb, 1);
 
 	/*
 	 * Operations are carefully ordered so that we set up the new
@@ -1489,9 +3017,16 @@
 	memcpy(dirdata_bh->b_data, di->id2.i_data.id_data, i_size_read(dir));
 	memset(dirdata_bh->b_data + i_size_read(dir), 0,
 	       sb->s_blocksize - i_size_read(dir));
-	ocfs2_expand_last_dirent(dirdata_bh->b_data, i_size_read(dir), sb);
-	if (ocfs2_supports_dir_trailer(osb))
-		ocfs2_init_dir_trailer(dir, dirdata_bh);
+	i = ocfs2_expand_last_dirent(dirdata_bh->b_data, i_size_read(dir), dir);
+	if (ocfs2_new_dir_wants_trailer(dir)) {
+		/*
+		 * Prepare the dir trailer up front. It will otherwise look
+		 * like a valid dirent. Even if inserting the index fails
+		 * (unlikely), then all we'll have done is given first dir
+		 * block a small amount of fragmentation.
+		 */
+		ocfs2_init_dir_trailer(dir, dirdata_bh, i);
+	}
 
 	ret = ocfs2_journal_dirty(handle, dirdata_bh);
 	if (ret) {
@@ -1499,6 +3034,24 @@
 		goto out_commit;
 	}
 
+	if (ocfs2_supports_indexed_dirs(osb) && !dx_inline) {
+		/*
+		 * Dx dirs with an external cluster need to do this up
+		 * front. Inline dx root's get handled later, after
+		 * we've allocated our root block. We get passed back
+		 * a total number of items so that dr_num_entries can
+		 * be correctly set once the dx_root has been
+		 * allocated.
+		 */
+		ret = ocfs2_dx_dir_index_block(dir, handle, dx_leaves,
+					       num_dx_leaves, &num_dx_entries,
+					       dirdata_bh);
+		if (ret) {
+			mlog_errno(ret);
+			goto out_commit;
+		}
+	}
+
 	/*
 	 * Set extent, i_size, etc on the directory. After this, the
 	 * inode should contain the same exact dirents as before and
@@ -1551,6 +3104,27 @@
 		goto out_commit;
 	}
 
+	if (ocfs2_supports_indexed_dirs(osb)) {
+		ret = ocfs2_dx_dir_attach_index(osb, handle, dir, di_bh,
+						dirdata_bh, meta_ac, dx_inline,
+						num_dx_entries, &dx_root_bh);
+		if (ret) {
+			mlog_errno(ret);
+			goto out_commit;
+		}
+
+		if (dx_inline) {
+			ocfs2_dx_dir_index_root_block(dir, dx_root_bh,
+						      dirdata_bh);
+		} else {
+			ocfs2_init_dx_root_extent_tree(&dx_et, dir, dx_root_bh);
+			ret = ocfs2_insert_extent(osb, handle, dir, &dx_et, 0,
+						  dx_insert_blkno, 1, 0, NULL);
+			if (ret)
+				mlog_errno(ret);
+		}
+	}
+
 	/*
 	 * We asked for two clusters, but only got one in the 1st
 	 * pass. Claim the 2nd cluster as a separate extent.
@@ -1570,15 +3144,32 @@
 			mlog_errno(ret);
 			goto out_commit;
 		}
+		bytes_allocated += ocfs2_clusters_to_bytes(dir->i_sb, 1);
 	}
 
 	*first_block_bh = dirdata_bh;
 	dirdata_bh = NULL;
+	if (ocfs2_supports_indexed_dirs(osb)) {
+		unsigned int off;
+
+		if (!dx_inline) {
+			/*
+			 * We need to return the correct block within the
+			 * cluster which should hold our entry.
+			 */
+			off = ocfs2_dx_dir_hash_idx(OCFS2_SB(dir->i_sb),
+						    &lookup->dl_hinfo);
+			get_bh(dx_leaves[off]);
+			lookup->dl_dx_leaf_bh = dx_leaves[off];
+		}
+		lookup->dl_dx_root_bh = dx_root_bh;
+		dx_root_bh = NULL;
+	}
 
 out_commit:
 	if (ret < 0 && did_quota)
-		vfs_dq_free_space_nodirty(dir,
-			ocfs2_clusters_to_bytes(osb->sb, 2));
+		vfs_dq_free_space_nodirty(dir, bytes_allocated);
+
 	ocfs2_commit_trans(osb, handle);
 
 out_sem:
@@ -1587,8 +3178,17 @@
 out:
 	if (data_ac)
 		ocfs2_free_alloc_context(data_ac);
+	if (meta_ac)
+		ocfs2_free_alloc_context(meta_ac);
+
+	if (dx_leaves) {
+		for (i = 0; i < num_dx_leaves; i++)
+			brelse(dx_leaves[i]);
+		kfree(dx_leaves);
+	}
 
 	brelse(dirdata_bh);
+	brelse(dx_root_bh);
 
 	return ret;
 }
@@ -1658,11 +3258,14 @@
  * is to be turned into an extent based one. The size of the dirent to
  * insert might be larger than the space gained by growing to just one
  * block, so we may have to grow the inode by two blocks in that case.
+ *
+ * If the directory is already indexed, dx_root_bh must be provided.
  */
 static int ocfs2_extend_dir(struct ocfs2_super *osb,
 			    struct inode *dir,
 			    struct buffer_head *parent_fe_bh,
 			    unsigned int blocks_wanted,
+			    struct ocfs2_dir_lookup_result *lookup,
 			    struct buffer_head **new_de_bh)
 {
 	int status = 0;
@@ -1677,17 +3280,29 @@
 	struct ocfs2_dir_entry * de;
 	struct super_block *sb = osb->sb;
 	struct ocfs2_extent_tree et;
+	struct buffer_head *dx_root_bh = lookup->dl_dx_root_bh;
 
 	mlog_entry_void();
 
 	if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
+		/*
+		 * This would be a code error as an inline directory should
+		 * never have an index root.
+		 */
+		BUG_ON(dx_root_bh);
+
 		status = ocfs2_expand_inline_dir(dir, parent_fe_bh,
-						 blocks_wanted, &new_bh);
+						 blocks_wanted, lookup,
+						 &new_bh);
 		if (status) {
 			mlog_errno(status);
 			goto bail;
 		}
 
+		/* Expansion from inline to an indexed directory will
+		 * have given us this. */
+		dx_root_bh = lookup->dl_dx_root_bh;
+
 		if (blocks_wanted == 1) {
 			/*
 			 * If the new dirent will fit inside the space
@@ -1751,6 +3366,10 @@
 	}
 
 do_extend:
+	if (ocfs2_dir_indexed(dir))
+		credits++; /* For attaching the new dirent block to the
+			    * dx_root */
+
 	down_write(&OCFS2_I(dir)->ip_alloc_sem);
 	drop_alloc_sem = 1;
 
@@ -1781,9 +3400,19 @@
 
 	de = (struct ocfs2_dir_entry *) new_bh->b_data;
 	de->inode = 0;
-	if (ocfs2_dir_has_trailer(dir)) {
+	if (ocfs2_supports_dir_trailer(dir)) {
 		de->rec_len = cpu_to_le16(ocfs2_dir_trailer_blk_off(sb));
-		ocfs2_init_dir_trailer(dir, new_bh);
+
+		ocfs2_init_dir_trailer(dir, new_bh, le16_to_cpu(de->rec_len));
+
+		if (ocfs2_dir_indexed(dir)) {
+			status = ocfs2_dx_dir_link_trailer(dir, handle,
+							   dx_root_bh, new_bh);
+			if (status) {
+				mlog_errno(status);
+				goto bail;
+			}
+		}
 	} else {
 		de->rec_len = cpu_to_le16(sb->s_blocksize);
 	}
@@ -1839,7 +3468,7 @@
 	 * This calculates how many free bytes we'd have in block zero, should
 	 * this function force expansion to an extent tree.
 	 */
-	if (ocfs2_supports_dir_trailer(OCFS2_SB(sb)))
+	if (ocfs2_new_dir_wants_trailer(dir))
 		free_space = ocfs2_dir_trailer_blk_off(sb) - i_size_read(dir);
 	else
 		free_space = dir->i_sb->s_blocksize - i_size_read(dir);
@@ -1970,12 +3599,766 @@
 	return status;
 }
 
+static int dx_leaf_sort_cmp(const void *a, const void *b)
+{
+	const struct ocfs2_dx_entry *entry1 = a;
+	const struct ocfs2_dx_entry *entry2 = b;
+	u32 major_hash1 = le32_to_cpu(entry1->dx_major_hash);
+	u32 major_hash2 = le32_to_cpu(entry2->dx_major_hash);
+	u32 minor_hash1 = le32_to_cpu(entry1->dx_minor_hash);
+	u32 minor_hash2 = le32_to_cpu(entry2->dx_minor_hash);
+
+	if (major_hash1 > major_hash2)
+		return 1;
+	if (major_hash1 < major_hash2)
+		return -1;
+
+	/*
+	 * It is not strictly necessary to sort by minor
+	 */
+	if (minor_hash1 > minor_hash2)
+		return 1;
+	if (minor_hash1 < minor_hash2)
+		return -1;
+	return 0;
+}
+
+static void dx_leaf_sort_swap(void *a, void *b, int size)
+{
+	struct ocfs2_dx_entry *entry1 = a;
+	struct ocfs2_dx_entry *entry2 = b;
+	struct ocfs2_dx_entry tmp;
+
+	BUG_ON(size != sizeof(*entry1));
+
+	tmp = *entry1;
+	*entry1 = *entry2;
+	*entry2 = tmp;
+}
+
+static int ocfs2_dx_leaf_same_major(struct ocfs2_dx_leaf *dx_leaf)
+{
+	struct ocfs2_dx_entry_list *dl_list = &dx_leaf->dl_list;
+	int i, num = le16_to_cpu(dl_list->de_num_used);
+
+	for (i = 0; i < (num - 1); i++) {
+		if (le32_to_cpu(dl_list->de_entries[i].dx_major_hash) !=
+		    le32_to_cpu(dl_list->de_entries[i + 1].dx_major_hash))
+			return 0;
+	}
+
+	return 1;
+}
+
+/*
+ * Find the optimal value to split this leaf on. This expects the leaf
+ * entries to be in sorted order.
+ *
+ * leaf_cpos is the cpos of the leaf we're splitting. insert_hash is
+ * the hash we want to insert.
+ *
+ * This function is only concerned with the major hash - that which
+ * determines which cluster an item belongs to.
+ */
+static int ocfs2_dx_dir_find_leaf_split(struct ocfs2_dx_leaf *dx_leaf,
+					u32 leaf_cpos, u32 insert_hash,
+					u32 *split_hash)
+{
+	struct ocfs2_dx_entry_list *dl_list = &dx_leaf->dl_list;
+	int i, num_used = le16_to_cpu(dl_list->de_num_used);
+	int allsame;
+
+	/*
+	 * There's a couple rare, but nasty corner cases we have to
+	 * check for here. All of them involve a leaf where all value
+	 * have the same hash, which is what we look for first.
+	 *
+	 * Most of the time, all of the above is false, and we simply
+	 * pick the median value for a split.
+	 */
+	allsame = ocfs2_dx_leaf_same_major(dx_leaf);
+	if (allsame) {
+		u32 val = le32_to_cpu(dl_list->de_entries[0].dx_major_hash);
+
+		if (val == insert_hash) {
+			/*
+			 * No matter where we would choose to split,
+			 * the new entry would want to occupy the same
+			 * block as these. Since there's no space left
+			 * in their existing block, we know there
+			 * won't be space after the split.
+			 */
+			return -ENOSPC;
+		}
+
+		if (val == leaf_cpos) {
+			/*
+			 * Because val is the same as leaf_cpos (which
+			 * is the smallest value this leaf can have),
+			 * yet is not equal to insert_hash, then we
+			 * know that insert_hash *must* be larger than
+			 * val (and leaf_cpos). At least cpos+1 in value.
+			 *
+			 * We also know then, that there cannot be an
+			 * adjacent extent (otherwise we'd be looking
+			 * at it). Choosing this value gives us a
+			 * chance to get some contiguousness.
+			 */
+			*split_hash = leaf_cpos + 1;
+			return 0;
+		}
+
+		if (val > insert_hash) {
+			/*
+			 * val can not be the same as insert hash, and
+			 * also must be larger than leaf_cpos. Also,
+			 * we know that there can't be a leaf between
+			 * cpos and val, otherwise the entries with
+			 * hash 'val' would be there.
+			 */
+			*split_hash = val;
+			return 0;
+		}
+
+		*split_hash = insert_hash;
+		return 0;
+	}
+
+	/*
+	 * Since the records are sorted and the checks above
+	 * guaranteed that not all records in this block are the same,
+	 * we simple travel forward, from the median, and pick the 1st
+	 * record whose value is larger than leaf_cpos.
+	 */
+	for (i = (num_used / 2); i < num_used; i++)
+		if (le32_to_cpu(dl_list->de_entries[i].dx_major_hash) >
+		    leaf_cpos)
+			break;
+
+	BUG_ON(i == num_used); /* Should be impossible */
+	*split_hash = le32_to_cpu(dl_list->de_entries[i].dx_major_hash);
+	return 0;
+}
+
+/*
+ * Transfer all entries in orig_dx_leaves whose major hash is equal to or
+ * larger than split_hash into new_dx_leaves. We use a temporary
+ * buffer (tmp_dx_leaf) to make the changes to the original leaf blocks.
+ *
+ * Since the block offset inside a leaf (cluster) is a constant mask
+ * of minor_hash, we can optimize - an item at block offset X within
+ * the original cluster, will be at offset X within the new cluster.
+ */
+static void ocfs2_dx_dir_transfer_leaf(struct inode *dir, u32 split_hash,
+				       handle_t *handle,
+				       struct ocfs2_dx_leaf *tmp_dx_leaf,
+				       struct buffer_head **orig_dx_leaves,
+				       struct buffer_head **new_dx_leaves,
+				       int num_dx_leaves)
+{
+	int i, j, num_used;
+	u32 major_hash;
+	struct ocfs2_dx_leaf *orig_dx_leaf, *new_dx_leaf;
+	struct ocfs2_dx_entry_list *orig_list, *new_list, *tmp_list;
+	struct ocfs2_dx_entry *dx_entry;
+
+	tmp_list = &tmp_dx_leaf->dl_list;
+
+	for (i = 0; i < num_dx_leaves; i++) {
+		orig_dx_leaf = (struct ocfs2_dx_leaf *) orig_dx_leaves[i]->b_data;
+		orig_list = &orig_dx_leaf->dl_list;
+		new_dx_leaf = (struct ocfs2_dx_leaf *) new_dx_leaves[i]->b_data;
+		new_list = &new_dx_leaf->dl_list;
+
+		num_used = le16_to_cpu(orig_list->de_num_used);
+
+		memcpy(tmp_dx_leaf, orig_dx_leaf, dir->i_sb->s_blocksize);
+		tmp_list->de_num_used = cpu_to_le16(0);
+		memset(&tmp_list->de_entries, 0, sizeof(*dx_entry)*num_used);
+
+		for (j = 0; j < num_used; j++) {
+			dx_entry = &orig_list->de_entries[j];
+			major_hash = le32_to_cpu(dx_entry->dx_major_hash);
+			if (major_hash >= split_hash)
+				ocfs2_dx_dir_leaf_insert_tail(new_dx_leaf,
+							      dx_entry);
+			else
+				ocfs2_dx_dir_leaf_insert_tail(tmp_dx_leaf,
+							      dx_entry);
+		}
+		memcpy(orig_dx_leaf, tmp_dx_leaf, dir->i_sb->s_blocksize);
+
+		ocfs2_journal_dirty(handle, orig_dx_leaves[i]);
+		ocfs2_journal_dirty(handle, new_dx_leaves[i]);
+	}
+}
+
+static int ocfs2_dx_dir_rebalance_credits(struct ocfs2_super *osb,
+					  struct ocfs2_dx_root_block *dx_root)
+{
+	int credits = ocfs2_clusters_to_blocks(osb->sb, 2);
+
+	credits += ocfs2_calc_extend_credits(osb->sb, &dx_root->dr_list, 1);
+	credits += ocfs2_quota_trans_credits(osb->sb);
+	return credits;
+}
+
+/*
+ * Find the median value in dx_leaf_bh and allocate a new leaf to move
+ * half our entries into.
+ */
+static int ocfs2_dx_dir_rebalance(struct ocfs2_super *osb, struct inode *dir,
+				  struct buffer_head *dx_root_bh,
+				  struct buffer_head *dx_leaf_bh,
+				  struct ocfs2_dx_hinfo *hinfo, u32 leaf_cpos,
+				  u64 leaf_blkno)
+{
+	struct ocfs2_dx_leaf *dx_leaf = (struct ocfs2_dx_leaf *)dx_leaf_bh->b_data;
+	int credits, ret, i, num_used, did_quota = 0;
+	u32 cpos, split_hash, insert_hash = hinfo->major_hash;
+	u64 orig_leaves_start;
+	int num_dx_leaves;
+	struct buffer_head **orig_dx_leaves = NULL;
+	struct buffer_head **new_dx_leaves = NULL;
+	struct ocfs2_alloc_context *data_ac = NULL, *meta_ac = NULL;
+	struct ocfs2_extent_tree et;
+	handle_t *handle = NULL;
+	struct ocfs2_dx_root_block *dx_root;
+	struct ocfs2_dx_leaf *tmp_dx_leaf = NULL;
+
+	mlog(0, "DX Dir: %llu, rebalance leaf leaf_blkno: %llu insert: %u\n",
+	     (unsigned long long)OCFS2_I(dir)->ip_blkno,
+	     (unsigned long long)leaf_blkno, insert_hash);
+
+	ocfs2_init_dx_root_extent_tree(&et, dir, dx_root_bh);
+
+	dx_root = (struct ocfs2_dx_root_block *)dx_root_bh->b_data;
+	/*
+	 * XXX: This is a rather large limit. We should use a more
+	 * realistic value.
+	 */
+	if (le32_to_cpu(dx_root->dr_clusters) == UINT_MAX)
+		return -ENOSPC;
+
+	num_used = le16_to_cpu(dx_leaf->dl_list.de_num_used);
+	if (num_used < le16_to_cpu(dx_leaf->dl_list.de_count)) {
+		mlog(ML_ERROR, "DX Dir: %llu, Asked to rebalance empty leaf: "
+		     "%llu, %d\n", (unsigned long long)OCFS2_I(dir)->ip_blkno,
+		     (unsigned long long)leaf_blkno, num_used);
+		ret = -EIO;
+		goto out;
+	}
+
+	orig_dx_leaves = ocfs2_dx_dir_kmalloc_leaves(osb->sb, &num_dx_leaves);
+	if (!orig_dx_leaves) {
+		ret = -ENOMEM;
+		mlog_errno(ret);
+		goto out;
+	}
+
+	new_dx_leaves = ocfs2_dx_dir_kmalloc_leaves(osb->sb, NULL);
+	if (!new_dx_leaves) {
+		ret = -ENOMEM;
+		mlog_errno(ret);
+		goto out;
+	}
+
+	ret = ocfs2_lock_allocators(dir, &et, 1, 0, &data_ac, &meta_ac);
+	if (ret) {
+		if (ret != -ENOSPC)
+			mlog_errno(ret);
+		goto out;
+	}
+
+	credits = ocfs2_dx_dir_rebalance_credits(osb, dx_root);
+	handle = ocfs2_start_trans(osb, credits);
+	if (IS_ERR(handle)) {
+		ret = PTR_ERR(handle);
+		handle = NULL;
+		mlog_errno(ret);
+		goto out;
+	}
+
+	if (vfs_dq_alloc_space_nodirty(dir,
+				       ocfs2_clusters_to_bytes(dir->i_sb, 1))) {
+		ret = -EDQUOT;
+		goto out_commit;
+	}
+	did_quota = 1;
+
+	ret = ocfs2_journal_access_dl(handle, dir, dx_leaf_bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (ret) {
+		mlog_errno(ret);
+		goto out_commit;
+	}
+
+	/*
+	 * This block is changing anyway, so we can sort it in place.
+	 */
+	sort(dx_leaf->dl_list.de_entries, num_used,
+	     sizeof(struct ocfs2_dx_entry), dx_leaf_sort_cmp,
+	     dx_leaf_sort_swap);
+
+	ret = ocfs2_journal_dirty(handle, dx_leaf_bh);
+	if (ret) {
+		mlog_errno(ret);
+		goto out_commit;
+	}
+
+	ret = ocfs2_dx_dir_find_leaf_split(dx_leaf, leaf_cpos, insert_hash,
+					   &split_hash);
+	if (ret) {
+		mlog_errno(ret);
+		goto  out_commit;
+	}
+
+	mlog(0, "Split leaf (%u) at %u, insert major hash is %u\n",
+	     leaf_cpos, split_hash, insert_hash);
+
+	/*
+	 * We have to carefully order operations here. There are items
+	 * which want to be in the new cluster before insert, but in
+	 * order to put those items in the new cluster, we alter the
+	 * old cluster. A failure to insert gets nasty.
+	 *
+	 * So, start by reserving writes to the old
+	 * cluster. ocfs2_dx_dir_new_cluster will reserve writes on
+	 * the new cluster for us, before inserting it. The insert
+	 * won't happen if there's an error before that. Once the
+	 * insert is done then, we can transfer from one leaf into the
+	 * other without fear of hitting any error.
+	 */
+
+	/*
+	 * The leaf transfer wants some scratch space so that we don't
+	 * wind up doing a bunch of expensive memmove().
+	 */
+	tmp_dx_leaf = kmalloc(osb->sb->s_blocksize, GFP_NOFS);
+	if (!tmp_dx_leaf) {
+		ret = -ENOMEM;
+		mlog_errno(ret);
+		goto out_commit;
+	}
+
+	orig_leaves_start = ocfs2_block_to_cluster_start(dir->i_sb, leaf_blkno);
+	ret = ocfs2_read_dx_leaves(dir, orig_leaves_start, num_dx_leaves,
+				   orig_dx_leaves);
+	if (ret) {
+		mlog_errno(ret);
+		goto out_commit;
+	}
+
+	for (i = 0; i < num_dx_leaves; i++) {
+		ret = ocfs2_journal_access_dl(handle, dir, orig_dx_leaves[i],
+					      OCFS2_JOURNAL_ACCESS_WRITE);
+		if (ret) {
+			mlog_errno(ret);
+			goto out_commit;
+		}
+	}
+
+	cpos = split_hash;
+	ret = ocfs2_dx_dir_new_cluster(dir, &et, cpos, handle,
+				       data_ac, meta_ac, new_dx_leaves,
+				       num_dx_leaves);
+	if (ret) {
+		mlog_errno(ret);
+		goto out_commit;
+	}
+
+	ocfs2_dx_dir_transfer_leaf(dir, split_hash, handle, tmp_dx_leaf,
+				   orig_dx_leaves, new_dx_leaves, num_dx_leaves);
+
+out_commit:
+	if (ret < 0 && did_quota)
+		vfs_dq_free_space_nodirty(dir,
+				ocfs2_clusters_to_bytes(dir->i_sb, 1));
+
+	ocfs2_commit_trans(osb, handle);
+
+out:
+	if (orig_dx_leaves || new_dx_leaves) {
+		for (i = 0; i < num_dx_leaves; i++) {
+			if (orig_dx_leaves)
+				brelse(orig_dx_leaves[i]);
+			if (new_dx_leaves)
+				brelse(new_dx_leaves[i]);
+		}
+		kfree(orig_dx_leaves);
+		kfree(new_dx_leaves);
+	}
+
+	if (meta_ac)
+		ocfs2_free_alloc_context(meta_ac);
+	if (data_ac)
+		ocfs2_free_alloc_context(data_ac);
+
+	kfree(tmp_dx_leaf);
+	return ret;
+}
+
+static int ocfs2_find_dir_space_dx(struct ocfs2_super *osb, struct inode *dir,
+				   struct buffer_head *di_bh,
+				   struct buffer_head *dx_root_bh,
+				   const char *name, int namelen,
+				   struct ocfs2_dir_lookup_result *lookup)
+{
+	int ret, rebalanced = 0;
+	struct ocfs2_dx_root_block *dx_root;
+	struct buffer_head *dx_leaf_bh = NULL;
+	struct ocfs2_dx_leaf *dx_leaf;
+	u64 blkno;
+	u32 leaf_cpos;
+
+	dx_root = (struct ocfs2_dx_root_block *)dx_root_bh->b_data;
+
+restart_search:
+	ret = ocfs2_dx_dir_lookup(dir, &dx_root->dr_list, &lookup->dl_hinfo,
+				  &leaf_cpos, &blkno);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	ret = ocfs2_read_dx_leaf(dir, blkno, &dx_leaf_bh);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	dx_leaf = (struct ocfs2_dx_leaf *)dx_leaf_bh->b_data;
+
+	if (le16_to_cpu(dx_leaf->dl_list.de_num_used) >=
+	    le16_to_cpu(dx_leaf->dl_list.de_count)) {
+		if (rebalanced) {
+			/*
+			 * Rebalancing should have provided us with
+			 * space in an appropriate leaf.
+			 *
+			 * XXX: Is this an abnormal condition then?
+			 * Should we print a message here?
+			 */
+			ret = -ENOSPC;
+			goto out;
+		}
+
+		ret = ocfs2_dx_dir_rebalance(osb, dir, dx_root_bh, dx_leaf_bh,
+					     &lookup->dl_hinfo, leaf_cpos,
+					     blkno);
+		if (ret) {
+			if (ret != -ENOSPC)
+				mlog_errno(ret);
+			goto out;
+		}
+
+		/*
+		 * Restart the lookup. The rebalance might have
+		 * changed which block our item fits into. Mark our
+		 * progress, so we only execute this once.
+		 */
+		brelse(dx_leaf_bh);
+		dx_leaf_bh = NULL;
+		rebalanced = 1;
+		goto restart_search;
+	}
+
+	lookup->dl_dx_leaf_bh = dx_leaf_bh;
+	dx_leaf_bh = NULL;
+
+out:
+	brelse(dx_leaf_bh);
+	return ret;
+}
+
+static int ocfs2_search_dx_free_list(struct inode *dir,
+				     struct buffer_head *dx_root_bh,
+				     int namelen,
+				     struct ocfs2_dir_lookup_result *lookup)
+{
+	int ret = -ENOSPC;
+	struct buffer_head *leaf_bh = NULL, *prev_leaf_bh = NULL;
+	struct ocfs2_dir_block_trailer *db;
+	u64 next_block;
+	int rec_len = OCFS2_DIR_REC_LEN(namelen);
+	struct ocfs2_dx_root_block *dx_root;
+
+	dx_root = (struct ocfs2_dx_root_block *)dx_root_bh->b_data;
+	next_block = le64_to_cpu(dx_root->dr_free_blk);
+
+	while (next_block) {
+		brelse(prev_leaf_bh);
+		prev_leaf_bh = leaf_bh;
+		leaf_bh = NULL;
+
+		ret = ocfs2_read_dir_block_direct(dir, next_block, &leaf_bh);
+		if (ret) {
+			mlog_errno(ret);
+			goto out;
+		}
+
+		db = ocfs2_trailer_from_bh(leaf_bh, dir->i_sb);
+		if (rec_len <= le16_to_cpu(db->db_free_rec_len)) {
+			lookup->dl_leaf_bh = leaf_bh;
+			lookup->dl_prev_leaf_bh = prev_leaf_bh;
+			leaf_bh = NULL;
+			prev_leaf_bh = NULL;
+			break;
+		}
+
+		next_block = le64_to_cpu(db->db_free_next);
+	}
+
+	if (!next_block)
+		ret = -ENOSPC;
+
+out:
+
+	brelse(leaf_bh);
+	brelse(prev_leaf_bh);
+	return ret;
+}
+
+static int ocfs2_expand_inline_dx_root(struct inode *dir,
+				       struct buffer_head *dx_root_bh)
+{
+	int ret, num_dx_leaves, i, j, did_quota = 0;
+	struct buffer_head **dx_leaves = NULL;
+	struct ocfs2_extent_tree et;
+	u64 insert_blkno;
+	struct ocfs2_alloc_context *data_ac = NULL;
+	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
+	handle_t *handle = NULL;
+	struct ocfs2_dx_root_block *dx_root;
+	struct ocfs2_dx_entry_list *entry_list;
+	struct ocfs2_dx_entry *dx_entry;
+	struct ocfs2_dx_leaf *target_leaf;
+
+	ret = ocfs2_reserve_clusters(osb, 1, &data_ac);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	dx_leaves = ocfs2_dx_dir_kmalloc_leaves(osb->sb, &num_dx_leaves);
+	if (!dx_leaves) {
+		ret = -ENOMEM;
+		mlog_errno(ret);
+		goto out;
+	}
+
+	handle = ocfs2_start_trans(osb, ocfs2_calc_dxi_expand_credits(osb->sb));
+	if (IS_ERR(handle)) {
+		ret = PTR_ERR(handle);
+		mlog_errno(ret);
+		goto out;
+	}
+
+	if (vfs_dq_alloc_space_nodirty(dir,
+				       ocfs2_clusters_to_bytes(osb->sb, 1))) {
+		ret = -EDQUOT;
+		goto out_commit;
+	}
+	did_quota = 1;
+
+	/*
+	 * We do this up front, before the allocation, so that a
+	 * failure to add the dx_root_bh to the journal won't result
+	 * us losing clusters.
+	 */
+	ret = ocfs2_journal_access_dr(handle, dir, dx_root_bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (ret) {
+		mlog_errno(ret);
+		goto out_commit;
+	}
+
+	ret = __ocfs2_dx_dir_new_cluster(dir, 0, handle, data_ac, dx_leaves,
+					 num_dx_leaves, &insert_blkno);
+	if (ret) {
+		mlog_errno(ret);
+		goto out_commit;
+	}
+
+	/*
+	 * Transfer the entries from our dx_root into the appropriate
+	 * block
+	 */
+	dx_root = (struct ocfs2_dx_root_block *) dx_root_bh->b_data;
+	entry_list = &dx_root->dr_entries;
+
+	for (i = 0; i < le16_to_cpu(entry_list->de_num_used); i++) {
+		dx_entry = &entry_list->de_entries[i];
+
+		j = __ocfs2_dx_dir_hash_idx(osb,
+					    le32_to_cpu(dx_entry->dx_minor_hash));
+		target_leaf = (struct ocfs2_dx_leaf *)dx_leaves[j]->b_data;
+
+		ocfs2_dx_dir_leaf_insert_tail(target_leaf, dx_entry);
+
+		/* Each leaf has been passed to the journal already
+		 * via __ocfs2_dx_dir_new_cluster() */
+	}
+
+	dx_root->dr_flags &= ~OCFS2_DX_FLAG_INLINE;
+	memset(&dx_root->dr_list, 0, osb->sb->s_blocksize -
+	       offsetof(struct ocfs2_dx_root_block, dr_list));
+	dx_root->dr_list.l_count =
+		cpu_to_le16(ocfs2_extent_recs_per_dx_root(osb->sb));
+
+	/* This should never fail considering we start with an empty
+	 * dx_root. */
+	ocfs2_init_dx_root_extent_tree(&et, dir, dx_root_bh);
+	ret = ocfs2_insert_extent(osb, handle, dir, &et, 0,
+				  insert_blkno, 1, 0, NULL);
+	if (ret)
+		mlog_errno(ret);
+	did_quota = 0;
+
+	ocfs2_journal_dirty(handle, dx_root_bh);
+
+out_commit:
+	if (ret < 0 && did_quota)
+		vfs_dq_free_space_nodirty(dir,
+					  ocfs2_clusters_to_bytes(dir->i_sb, 1));
+
+	ocfs2_commit_trans(osb, handle);
+
+out:
+	if (data_ac)
+		ocfs2_free_alloc_context(data_ac);
+
+	if (dx_leaves) {
+		for (i = 0; i < num_dx_leaves; i++)
+			brelse(dx_leaves[i]);
+		kfree(dx_leaves);
+	}
+	return ret;
+}
+
+static int ocfs2_inline_dx_has_space(struct buffer_head *dx_root_bh)
+{
+	struct ocfs2_dx_root_block *dx_root;
+	struct ocfs2_dx_entry_list *entry_list;
+
+	dx_root = (struct ocfs2_dx_root_block *) dx_root_bh->b_data;
+	entry_list = &dx_root->dr_entries;
+
+	if (le16_to_cpu(entry_list->de_num_used) >=
+	    le16_to_cpu(entry_list->de_count))
+		return -ENOSPC;
+
+	return 0;
+}
+
+static int ocfs2_prepare_dx_dir_for_insert(struct inode *dir,
+					   struct buffer_head *di_bh,
+					   const char *name,
+					   int namelen,
+					   struct ocfs2_dir_lookup_result *lookup)
+{
+	int ret, free_dx_root = 1;
+	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
+	struct buffer_head *dx_root_bh = NULL;
+	struct buffer_head *leaf_bh = NULL;
+	struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
+	struct ocfs2_dx_root_block *dx_root;
+
+	ret = ocfs2_read_dx_root(dir, di, &dx_root_bh);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	dx_root = (struct ocfs2_dx_root_block *)dx_root_bh->b_data;
+	if (le32_to_cpu(dx_root->dr_num_entries) == OCFS2_DX_ENTRIES_MAX) {
+		ret = -ENOSPC;
+		mlog_errno(ret);
+		goto out;
+	}
+
+	if (ocfs2_dx_root_inline(dx_root)) {
+		ret = ocfs2_inline_dx_has_space(dx_root_bh);
+
+		if (ret == 0)
+			goto search_el;
+
+		/*
+		 * We ran out of room in the root block. Expand it to
+		 * an extent, then allow ocfs2_find_dir_space_dx to do
+		 * the rest.
+		 */
+		ret = ocfs2_expand_inline_dx_root(dir, dx_root_bh);
+		if (ret) {
+			mlog_errno(ret);
+			goto out;
+		}
+	}
+
+	/*
+	 * Insert preparation for an indexed directory is split into two
+	 * steps. The call to find_dir_space_dx reserves room in the index for
+	 * an additional item. If we run out of space there, it's a real error
+	 * we can't continue on.
+	 */
+	ret = ocfs2_find_dir_space_dx(osb, dir, di_bh, dx_root_bh, name,
+				      namelen, lookup);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+search_el:
+	/*
+	 * Next, we need to find space in the unindexed tree. This call
+	 * searches using the free space linked list. If the unindexed tree
+	 * lacks sufficient space, we'll expand it below. The expansion code
+	 * is smart enough to add any new blocks to the free space list.
+	 */
+	ret = ocfs2_search_dx_free_list(dir, dx_root_bh, namelen, lookup);
+	if (ret && ret != -ENOSPC) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	/* Do this up here - ocfs2_extend_dir might need the dx_root */
+	lookup->dl_dx_root_bh = dx_root_bh;
+	free_dx_root = 0;
+
+	if (ret == -ENOSPC) {
+		ret = ocfs2_extend_dir(osb, dir, di_bh, 1, lookup, &leaf_bh);
+
+		if (ret) {
+			mlog_errno(ret);
+			goto out;
+		}
+
+		/*
+		 * We make the assumption here that new leaf blocks are added
+		 * to the front of our free list.
+		 */
+		lookup->dl_prev_leaf_bh = NULL;
+		lookup->dl_leaf_bh = leaf_bh;
+	}
+
+out:
+	if (free_dx_root)
+		brelse(dx_root_bh);
+	return ret;
+}
+
+/*
+ * Get a directory ready for insert. Any directory allocation required
+ * happens here. Success returns zero, and enough context in the dir
+ * lookup result that ocfs2_add_entry() will be able complete the task
+ * with minimal performance impact.
+ */
 int ocfs2_prepare_dir_for_insert(struct ocfs2_super *osb,
 				 struct inode *dir,
 				 struct buffer_head *parent_fe_bh,
 				 const char *name,
 				 int namelen,
-				 struct buffer_head **ret_de_bh)
+				 struct ocfs2_dir_lookup_result *lookup)
 {
 	int ret;
 	unsigned int blocks_wanted = 1;
@@ -1984,14 +4367,34 @@
 	mlog(0, "getting ready to insert namelen %d into dir %llu\n",
 	     namelen, (unsigned long long)OCFS2_I(dir)->ip_blkno);
 
-	*ret_de_bh = NULL;
-
 	if (!namelen) {
 		ret = -EINVAL;
 		mlog_errno(ret);
 		goto out;
 	}
 
+	/*
+	 * Do this up front to reduce confusion.
+	 *
+	 * The directory might start inline, then be turned into an
+	 * indexed one, in which case we'd need to hash deep inside
+	 * ocfs2_find_dir_space_id(). Since
+	 * ocfs2_prepare_dx_dir_for_insert() also needs this hash
+	 * done, there seems no point in spreading out the calls. We
+	 * can optimize away the case where the file system doesn't
+	 * support indexing.
+	 */
+	if (ocfs2_supports_indexed_dirs(osb))
+		ocfs2_dx_dir_name_hash(dir, name, namelen, &lookup->dl_hinfo);
+
+	if (ocfs2_dir_indexed(dir)) {
+		ret = ocfs2_prepare_dx_dir_for_insert(dir, parent_fe_bh,
+						      name, namelen, lookup);
+		if (ret)
+			mlog_errno(ret);
+		goto out;
+	}
+
 	if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
 		ret = ocfs2_find_dir_space_id(dir, parent_fe_bh, name,
 					      namelen, &bh, &blocks_wanted);
@@ -2010,7 +4413,7 @@
 		BUG_ON(bh);
 
 		ret = ocfs2_extend_dir(osb, dir, parent_fe_bh, blocks_wanted,
-				       &bh);
+				       lookup, &bh);
 		if (ret) {
 			if (ret != -ENOSPC)
 				mlog_errno(ret);
@@ -2020,9 +4423,154 @@
 		BUG_ON(!bh);
 	}
 
-	*ret_de_bh = bh;
+	lookup->dl_leaf_bh = bh;
 	bh = NULL;
 out:
 	brelse(bh);
 	return ret;
 }
+
+static int ocfs2_dx_dir_remove_index(struct inode *dir,
+				     struct buffer_head *di_bh,
+				     struct buffer_head *dx_root_bh)
+{
+	int ret;
+	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
+	struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
+	struct ocfs2_dx_root_block *dx_root;
+	struct inode *dx_alloc_inode = NULL;
+	struct buffer_head *dx_alloc_bh = NULL;
+	handle_t *handle;
+	u64 blk;
+	u16 bit;
+	u64 bg_blkno;
+
+	dx_root = (struct ocfs2_dx_root_block *) dx_root_bh->b_data;
+
+	dx_alloc_inode = ocfs2_get_system_file_inode(osb,
+					EXTENT_ALLOC_SYSTEM_INODE,
+					le16_to_cpu(dx_root->dr_suballoc_slot));
+	if (!dx_alloc_inode) {
+		ret = -ENOMEM;
+		mlog_errno(ret);
+		goto out;
+	}
+	mutex_lock(&dx_alloc_inode->i_mutex);
+
+	ret = ocfs2_inode_lock(dx_alloc_inode, &dx_alloc_bh, 1);
+	if (ret) {
+		mlog_errno(ret);
+		goto out_mutex;
+	}
+
+	handle = ocfs2_start_trans(osb, OCFS2_DX_ROOT_REMOVE_CREDITS);
+	if (IS_ERR(handle)) {
+		ret = PTR_ERR(handle);
+		mlog_errno(ret);
+		goto out_unlock;
+	}
+
+	ret = ocfs2_journal_access_di(handle, dir, di_bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (ret) {
+		mlog_errno(ret);
+		goto out_commit;
+	}
+
+	OCFS2_I(dir)->ip_dyn_features &= ~OCFS2_INDEXED_DIR_FL;
+	di->i_dyn_features = cpu_to_le16(OCFS2_I(dir)->ip_dyn_features);
+	di->i_dx_root = cpu_to_le64(0ULL);
+
+	ocfs2_journal_dirty(handle, di_bh);
+
+	blk = le64_to_cpu(dx_root->dr_blkno);
+	bit = le16_to_cpu(dx_root->dr_suballoc_bit);
+	bg_blkno = ocfs2_which_suballoc_group(blk, bit);
+	ret = ocfs2_free_suballoc_bits(handle, dx_alloc_inode, dx_alloc_bh,
+				       bit, bg_blkno, 1);
+	if (ret)
+		mlog_errno(ret);
+
+out_commit:
+	ocfs2_commit_trans(osb, handle);
+
+out_unlock:
+	ocfs2_inode_unlock(dx_alloc_inode, 1);
+
+out_mutex:
+	mutex_unlock(&dx_alloc_inode->i_mutex);
+	brelse(dx_alloc_bh);
+out:
+	iput(dx_alloc_inode);
+	return ret;
+}
+
+int ocfs2_dx_dir_truncate(struct inode *dir, struct buffer_head *di_bh)
+{
+	int ret;
+	unsigned int uninitialized_var(clen);
+	u32 major_hash = UINT_MAX, p_cpos, uninitialized_var(cpos);
+	u64 uninitialized_var(blkno);
+	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
+	struct buffer_head *dx_root_bh = NULL;
+	struct ocfs2_dx_root_block *dx_root;
+	struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
+	struct ocfs2_cached_dealloc_ctxt dealloc;
+	struct ocfs2_extent_tree et;
+
+	ocfs2_init_dealloc_ctxt(&dealloc);
+
+	if (!ocfs2_dir_indexed(dir))
+		return 0;
+
+	ret = ocfs2_read_dx_root(dir, di, &dx_root_bh);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+	dx_root = (struct ocfs2_dx_root_block *)dx_root_bh->b_data;
+
+	if (ocfs2_dx_root_inline(dx_root))
+		goto remove_index;
+
+	ocfs2_init_dx_root_extent_tree(&et, dir, dx_root_bh);
+
+	/* XXX: What if dr_clusters is too large? */
+	while (le32_to_cpu(dx_root->dr_clusters)) {
+		ret = ocfs2_dx_dir_lookup_rec(dir, &dx_root->dr_list,
+					      major_hash, &cpos, &blkno, &clen);
+		if (ret) {
+			mlog_errno(ret);
+			goto out;
+		}
+
+		p_cpos = ocfs2_blocks_to_clusters(dir->i_sb, blkno);
+
+		ret = ocfs2_remove_btree_range(dir, &et, cpos, p_cpos, clen,
+					       &dealloc);
+		if (ret) {
+			mlog_errno(ret);
+			goto out;
+		}
+
+		if (cpos == 0)
+			break;
+
+		major_hash = cpos - 1;
+	}
+
+remove_index:
+	ret = ocfs2_dx_dir_remove_index(dir, di_bh, dx_root_bh);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	ocfs2_remove_from_cache(dir, dx_root_bh);
+out:
+	ocfs2_schedule_truncate_log_flush(osb, 1);
+	ocfs2_run_deallocs(osb, &dealloc);
+
+	brelse(dx_root_bh);
+	return ret;
+}
diff --git a/fs/ocfs2/dir.h b/fs/ocfs2/dir.h
index c511e2e..e683f3d 100644
--- a/fs/ocfs2/dir.h
+++ b/fs/ocfs2/dir.h
@@ -26,44 +26,70 @@
 #ifndef OCFS2_DIR_H
 #define OCFS2_DIR_H
 
-struct buffer_head *ocfs2_find_entry(const char *name,
-				     int namelen,
-				     struct inode *dir,
-				     struct ocfs2_dir_entry **res_dir);
+struct ocfs2_dx_hinfo {
+	u32	major_hash;
+	u32	minor_hash;
+};
+
+struct ocfs2_dir_lookup_result {
+	struct buffer_head		*dl_leaf_bh;	/* Unindexed leaf
+							 * block */
+	struct ocfs2_dir_entry		*dl_entry;	/* Target dirent in
+							 * unindexed leaf */
+
+	struct buffer_head		*dl_dx_root_bh;	/* Root of indexed
+							 * tree */
+
+	struct buffer_head		*dl_dx_leaf_bh;	/* Indexed leaf block */
+	struct ocfs2_dx_entry		*dl_dx_entry;	/* Target dx_entry in
+							 * indexed leaf */
+	struct ocfs2_dx_hinfo		dl_hinfo;	/* Name hash results */
+
+	struct buffer_head		*dl_prev_leaf_bh;/* Previous entry in
+							  * dir free space
+							  * list. NULL if
+							  * previous entry is
+							  * dx root block. */
+};
+
+void ocfs2_free_dir_lookup_result(struct ocfs2_dir_lookup_result *res);
+
+int ocfs2_find_entry(const char *name, int namelen,
+		     struct inode *dir,
+		     struct ocfs2_dir_lookup_result *lookup);
 int ocfs2_delete_entry(handle_t *handle,
 		       struct inode *dir,
-		       struct ocfs2_dir_entry *de_del,
-		       struct buffer_head *bh);
+		       struct ocfs2_dir_lookup_result *res);
 int __ocfs2_add_entry(handle_t *handle,
 		      struct inode *dir,
 		      const char *name, int namelen,
 		      struct inode *inode, u64 blkno,
 		      struct buffer_head *parent_fe_bh,
-		      struct buffer_head *insert_bh);
+		      struct ocfs2_dir_lookup_result *lookup);
 static inline int ocfs2_add_entry(handle_t *handle,
 				  struct dentry *dentry,
 				  struct inode *inode, u64 blkno,
 				  struct buffer_head *parent_fe_bh,
-				  struct buffer_head *insert_bh)
+				  struct ocfs2_dir_lookup_result *lookup)
 {
 	return __ocfs2_add_entry(handle, dentry->d_parent->d_inode,
 				 dentry->d_name.name, dentry->d_name.len,
-				 inode, blkno, parent_fe_bh, insert_bh);
+				 inode, blkno, parent_fe_bh, lookup);
 }
 int ocfs2_update_entry(struct inode *dir, handle_t *handle,
-		       struct buffer_head *de_bh, struct ocfs2_dir_entry *de,
+		       struct ocfs2_dir_lookup_result *res,
 		       struct inode *new_entry_inode);
 
 int ocfs2_check_dir_for_entry(struct inode *dir,
 			      const char *name,
 			      int namelen);
 int ocfs2_empty_dir(struct inode *inode);
+
 int ocfs2_find_files_on_disk(const char *name,
 			     int namelen,
 			     u64 *blkno,
 			     struct inode *inode,
-			     struct buffer_head **dirent_bh,
-			     struct ocfs2_dir_entry **dirent);
+			     struct ocfs2_dir_lookup_result *res);
 int ocfs2_lookup_ino_from_name(struct inode *dir, const char *name,
 			       int namelen, u64 *blkno);
 int ocfs2_readdir(struct file *filp, void *dirent, filldir_t filldir);
@@ -74,14 +100,17 @@
 				 struct buffer_head *parent_fe_bh,
 				 const char *name,
 				 int namelen,
-				 struct buffer_head **ret_de_bh);
+				 struct ocfs2_dir_lookup_result *lookup);
 struct ocfs2_alloc_context;
 int ocfs2_fill_new_dir(struct ocfs2_super *osb,
 		       handle_t *handle,
 		       struct inode *parent,
 		       struct inode *inode,
 		       struct buffer_head *fe_bh,
-		       struct ocfs2_alloc_context *data_ac);
+		       struct ocfs2_alloc_context *data_ac,
+		       struct ocfs2_alloc_context *meta_ac);
+
+int ocfs2_dx_dir_truncate(struct inode *dir, struct buffer_head *di_bh);
 
 struct ocfs2_dir_block_trailer *ocfs2_dir_trailer_from_size(int blocksize,
 							    void *data);
diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h
index bb53714..0102be3 100644
--- a/fs/ocfs2/dlm/dlmcommon.h
+++ b/fs/ocfs2/dlm/dlmcommon.h
@@ -52,16 +52,12 @@
 enum dlm_mle_type {
 	DLM_MLE_BLOCK,
 	DLM_MLE_MASTER,
-	DLM_MLE_MIGRATION
-};
-
-struct dlm_lock_name {
-	u8 len;
-	u8 name[DLM_LOCKID_NAME_MAX];
+	DLM_MLE_MIGRATION,
+	DLM_MLE_NUM_TYPES
 };
 
 struct dlm_master_list_entry {
-	struct list_head list;
+	struct hlist_node master_hash_node;
 	struct list_head hb_events;
 	struct dlm_ctxt *dlm;
 	spinlock_t spinlock;
@@ -78,10 +74,10 @@
 	enum dlm_mle_type type;
 	struct o2hb_callback_func mle_hb_up;
 	struct o2hb_callback_func mle_hb_down;
-	union {
-		struct dlm_lock_resource *res;
-		struct dlm_lock_name name;
-	} u;
+	struct dlm_lock_resource *mleres;
+	unsigned char mname[DLM_LOCKID_NAME_MAX];
+	unsigned int mnamelen;
+	unsigned int mnamehash;
 };
 
 enum dlm_ast_type {
@@ -151,13 +147,14 @@
 	unsigned long recovery_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
 	struct dlm_recovery_ctxt reco;
 	spinlock_t master_lock;
-	struct list_head master_list;
+	struct hlist_head **master_hash;
 	struct list_head mle_hb_events;
 
 	/* these give a really vague idea of the system load */
-	atomic_t local_resources;
-	atomic_t remote_resources;
-	atomic_t unknown_resources;
+	atomic_t mle_tot_count[DLM_MLE_NUM_TYPES];
+	atomic_t mle_cur_count[DLM_MLE_NUM_TYPES];
+	atomic_t res_tot_count;
+	atomic_t res_cur_count;
 
 	struct dlm_debug_ctxt *dlm_debug_ctxt;
 	struct dentry *dlm_debugfs_subroot;
@@ -195,6 +192,13 @@
 	return dlm->lockres_hash[(i / DLM_BUCKETS_PER_PAGE) % DLM_HASH_PAGES] + (i % DLM_BUCKETS_PER_PAGE);
 }
 
+static inline struct hlist_head *dlm_master_hash(struct dlm_ctxt *dlm,
+						 unsigned i)
+{
+	return dlm->master_hash[(i / DLM_BUCKETS_PER_PAGE) % DLM_HASH_PAGES] +
+			(i % DLM_BUCKETS_PER_PAGE);
+}
+
 /* these keventd work queue items are for less-frequently
  * called functions that cannot be directly called from the
  * net message handlers for some reason, usually because
@@ -848,9 +852,7 @@
 					      unsigned int len);
 
 int dlm_is_host_down(int errno);
-void dlm_change_lockres_owner(struct dlm_ctxt *dlm,
-			      struct dlm_lock_resource *res,
-			      u8 owner);
+
 struct dlm_lock_resource * dlm_get_lock_resource(struct dlm_ctxt *dlm,
 						 const char *lockid,
 						 int namelen,
@@ -1008,6 +1010,9 @@
 					  DLM_LOCK_RES_MIGRATING));
 }
 
+void __dlm_unlink_mle(struct dlm_ctxt *dlm, struct dlm_master_list_entry *mle);
+void __dlm_insert_mle(struct dlm_ctxt *dlm, struct dlm_master_list_entry *mle);
+
 /* create/destroy slab caches */
 int dlm_init_master_caches(void);
 void dlm_destroy_master_caches(void);
@@ -1110,6 +1115,23 @@
 	return bit;
 }
 
+static inline void dlm_set_lockres_owner(struct dlm_ctxt *dlm,
+					 struct dlm_lock_resource *res,
+					 u8 owner)
+{
+	assert_spin_locked(&res->spinlock);
 
+	res->owner = owner;
+}
+
+static inline void dlm_change_lockres_owner(struct dlm_ctxt *dlm,
+					    struct dlm_lock_resource *res,
+					    u8 owner)
+{
+	assert_spin_locked(&res->spinlock);
+
+	if (owner != res->owner)
+		dlm_set_lockres_owner(dlm, res, owner);
+}
 
 #endif /* DLMCOMMON_H */
diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c
index b32f60a..df52f70 100644
--- a/fs/ocfs2/dlm/dlmdebug.c
+++ b/fs/ocfs2/dlm/dlmdebug.c
@@ -287,18 +287,8 @@
 static int dump_mle(struct dlm_master_list_entry *mle, char *buf, int len)
 {
 	int out = 0;
-	unsigned int namelen;
-	const char *name;
 	char *mle_type;
 
-	if (mle->type != DLM_MLE_MASTER) {
-		namelen = mle->u.name.len;
-		name = mle->u.name.name;
-	} else {
-		namelen = mle->u.res->lockname.len;
-		name = mle->u.res->lockname.name;
-	}
-
 	if (mle->type == DLM_MLE_BLOCK)
 		mle_type = "BLK";
 	else if (mle->type == DLM_MLE_MASTER)
@@ -306,7 +296,7 @@
 	else
 		mle_type = "MIG";
 
-	out += stringify_lockname(name, namelen, buf + out, len - out);
+	out += stringify_lockname(mle->mname, mle->mnamelen, buf + out, len - out);
 	out += snprintf(buf + out, len - out,
 			"\t%3s\tmas=%3u\tnew=%3u\tevt=%1d\tuse=%1d\tref=%3d\n",
 			mle_type, mle->master, mle->new_master,
@@ -501,23 +491,33 @@
 static int debug_mle_print(struct dlm_ctxt *dlm, struct debug_buffer *db)
 {
 	struct dlm_master_list_entry *mle;
-	int out = 0;
-	unsigned long total = 0;
+	struct hlist_head *bucket;
+	struct hlist_node *list;
+	int i, out = 0;
+	unsigned long total = 0, longest = 0, bktcnt;
 
 	out += snprintf(db->buf + out, db->len - out,
 			"Dumping MLEs for Domain: %s\n", dlm->name);
 
 	spin_lock(&dlm->master_lock);
-	list_for_each_entry(mle, &dlm->master_list, list) {
-		++total;
-		if (db->len - out < 200)
-			continue;
-		out += dump_mle(mle, db->buf + out, db->len - out);
+	for (i = 0; i < DLM_HASH_BUCKETS; i++) {
+		bucket = dlm_master_hash(dlm, i);
+		hlist_for_each(list, bucket) {
+			mle = hlist_entry(list, struct dlm_master_list_entry,
+					  master_hash_node);
+			++total;
+			++bktcnt;
+			if (db->len - out < 200)
+				continue;
+			out += dump_mle(mle, db->buf + out, db->len - out);
+		}
+		longest = max(longest, bktcnt);
+		bktcnt = 0;
 	}
 	spin_unlock(&dlm->master_lock);
 
 	out += snprintf(db->buf + out, db->len - out,
-			"Total on list: %ld\n", total);
+			"Total: %ld, Longest: %ld\n", total, longest);
 	return out;
 }
 
@@ -756,12 +756,8 @@
 	int out = 0;
 	struct dlm_reco_node_data *node;
 	char *state;
-	int lres, rres, ures, tres;
-
-	lres = atomic_read(&dlm->local_resources);
-	rres = atomic_read(&dlm->remote_resources);
-	ures = atomic_read(&dlm->unknown_resources);
-	tres = lres + rres + ures;
+	int cur_mles = 0, tot_mles = 0;
+	int i;
 
 	spin_lock(&dlm->spinlock);
 
@@ -804,21 +800,48 @@
 				 db->buf + out, db->len - out);
 	out += snprintf(db->buf + out, db->len - out, "\n");
 
-	/* Mastered Resources Total: xxx  Locally: xxx  Remotely: ... */
+	/* Lock Resources: xxx (xxx) */
 	out += snprintf(db->buf + out, db->len - out,
-			"Mastered Resources Total: %d  Locally: %d  "
-			"Remotely: %d  Unknown: %d\n",
-			tres, lres, rres, ures);
+			"Lock Resources: %d (%d)\n",
+			atomic_read(&dlm->res_cur_count),
+			atomic_read(&dlm->res_tot_count));
+
+	for (i = 0; i < DLM_MLE_NUM_TYPES; ++i)
+		tot_mles += atomic_read(&dlm->mle_tot_count[i]);
+
+	for (i = 0; i < DLM_MLE_NUM_TYPES; ++i)
+		cur_mles += atomic_read(&dlm->mle_cur_count[i]);
+
+	/* MLEs: xxx (xxx) */
+	out += snprintf(db->buf + out, db->len - out,
+			"MLEs: %d (%d)\n", cur_mles, tot_mles);
+
+	/*  Blocking: xxx (xxx) */
+	out += snprintf(db->buf + out, db->len - out,
+			"  Blocking: %d (%d)\n",
+			atomic_read(&dlm->mle_cur_count[DLM_MLE_BLOCK]),
+			atomic_read(&dlm->mle_tot_count[DLM_MLE_BLOCK]));
+
+	/*  Mastery: xxx (xxx) */
+	out += snprintf(db->buf + out, db->len - out,
+			"  Mastery: %d (%d)\n",
+			atomic_read(&dlm->mle_cur_count[DLM_MLE_MASTER]),
+			atomic_read(&dlm->mle_tot_count[DLM_MLE_MASTER]));
+
+	/*  Migration: xxx (xxx) */
+	out += snprintf(db->buf + out, db->len - out,
+			"  Migration: %d (%d)\n",
+			atomic_read(&dlm->mle_cur_count[DLM_MLE_MIGRATION]),
+			atomic_read(&dlm->mle_tot_count[DLM_MLE_MIGRATION]));
 
 	/* Lists: Dirty=Empty  Purge=InUse  PendingASTs=Empty  ... */
 	out += snprintf(db->buf + out, db->len - out,
 			"Lists: Dirty=%s  Purge=%s  PendingASTs=%s  "
-			"PendingBASTs=%s  Master=%s\n",
+			"PendingBASTs=%s\n",
 			(list_empty(&dlm->dirty_list) ? "Empty" : "InUse"),
 			(list_empty(&dlm->purge_list) ? "Empty" : "InUse"),
 			(list_empty(&dlm->pending_asts) ? "Empty" : "InUse"),
-			(list_empty(&dlm->pending_basts) ? "Empty" : "InUse"),
-			(list_empty(&dlm->master_list) ? "Empty" : "InUse"));
+			(list_empty(&dlm->pending_basts) ? "Empty" : "InUse"));
 
 	/* Purge Count: xxx  Refs: xxx */
 	out += snprintf(db->buf + out, db->len - out,
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c
index d8d578f..4d9e6b2 100644
--- a/fs/ocfs2/dlm/dlmdomain.c
+++ b/fs/ocfs2/dlm/dlmdomain.c
@@ -304,6 +304,9 @@
 	if (dlm->lockres_hash)
 		dlm_free_pagevec((void **)dlm->lockres_hash, DLM_HASH_PAGES);
 
+	if (dlm->master_hash)
+		dlm_free_pagevec((void **)dlm->master_hash, DLM_HASH_PAGES);
+
 	if (dlm->name)
 		kfree(dlm->name);
 
@@ -1534,12 +1537,27 @@
 	for (i = 0; i < DLM_HASH_BUCKETS; i++)
 		INIT_HLIST_HEAD(dlm_lockres_hash(dlm, i));
 
+	dlm->master_hash = (struct hlist_head **)
+				dlm_alloc_pagevec(DLM_HASH_PAGES);
+	if (!dlm->master_hash) {
+		mlog_errno(-ENOMEM);
+		dlm_free_pagevec((void **)dlm->lockres_hash, DLM_HASH_PAGES);
+		kfree(dlm->name);
+		kfree(dlm);
+		dlm = NULL;
+		goto leave;
+	}
+
+	for (i = 0; i < DLM_HASH_BUCKETS; i++)
+		INIT_HLIST_HEAD(dlm_master_hash(dlm, i));
+
 	strcpy(dlm->name, domain);
 	dlm->key = key;
 	dlm->node_num = o2nm_this_node();
 
 	ret = dlm_create_debugfs_subroot(dlm);
 	if (ret < 0) {
+		dlm_free_pagevec((void **)dlm->master_hash, DLM_HASH_PAGES);
 		dlm_free_pagevec((void **)dlm->lockres_hash, DLM_HASH_PAGES);
 		kfree(dlm->name);
 		kfree(dlm);
@@ -1579,7 +1597,6 @@
 	init_waitqueue_head(&dlm->reco.event);
 	init_waitqueue_head(&dlm->ast_wq);
 	init_waitqueue_head(&dlm->migration_wq);
-	INIT_LIST_HEAD(&dlm->master_list);
 	INIT_LIST_HEAD(&dlm->mle_hb_events);
 
 	dlm->joining_node = DLM_LOCK_RES_OWNER_UNKNOWN;
@@ -1587,9 +1604,13 @@
 
 	dlm->reco.new_master = O2NM_INVALID_NODE_NUM;
 	dlm->reco.dead_node = O2NM_INVALID_NODE_NUM;
-	atomic_set(&dlm->local_resources, 0);
-	atomic_set(&dlm->remote_resources, 0);
-	atomic_set(&dlm->unknown_resources, 0);
+
+	atomic_set(&dlm->res_tot_count, 0);
+	atomic_set(&dlm->res_cur_count, 0);
+	for (i = 0; i < DLM_MLE_NUM_TYPES; ++i) {
+		atomic_set(&dlm->mle_tot_count[i], 0);
+		atomic_set(&dlm->mle_cur_count[i], 0);
+	}
 
 	spin_lock_init(&dlm->work_lock);
 	INIT_LIST_HEAD(&dlm->work_list);
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
index 0a28139..f8b653f 100644
--- a/fs/ocfs2/dlm/dlmmaster.c
+++ b/fs/ocfs2/dlm/dlmmaster.c
@@ -73,22 +73,13 @@
 				const char *name,
 				unsigned int namelen)
 {
-	struct dlm_lock_resource *res;
-
 	if (dlm != mle->dlm)
 		return 0;
 
-	if (mle->type == DLM_MLE_BLOCK ||
-	    mle->type == DLM_MLE_MIGRATION) {
-		if (namelen != mle->u.name.len ||
-    	    	    memcmp(name, mle->u.name.name, namelen)!=0)
-			return 0;
-	} else {
-		res = mle->u.res;
-		if (namelen != res->lockname.len ||
-		    memcmp(res->lockname.name, name, namelen) != 0)
-			return 0;
-	}
+	if (namelen != mle->mnamelen ||
+	    memcmp(name, mle->mname, namelen) != 0)
+		return 0;
+
 	return 1;
 }
 
@@ -283,7 +274,7 @@
 
 	mle->dlm = dlm;
 	mle->type = type;
-	INIT_LIST_HEAD(&mle->list);
+	INIT_HLIST_NODE(&mle->master_hash_node);
 	INIT_LIST_HEAD(&mle->hb_events);
 	memset(mle->maybe_map, 0, sizeof(mle->maybe_map));
 	spin_lock_init(&mle->spinlock);
@@ -295,19 +286,27 @@
 	mle->new_master = O2NM_MAX_NODES;
 	mle->inuse = 0;
 
+	BUG_ON(mle->type != DLM_MLE_BLOCK &&
+	       mle->type != DLM_MLE_MASTER &&
+	       mle->type != DLM_MLE_MIGRATION);
+
 	if (mle->type == DLM_MLE_MASTER) {
 		BUG_ON(!res);
-		mle->u.res = res;
-	} else if (mle->type == DLM_MLE_BLOCK) {
+		mle->mleres = res;
+		memcpy(mle->mname, res->lockname.name, res->lockname.len);
+		mle->mnamelen = res->lockname.len;
+		mle->mnamehash = res->lockname.hash;
+	} else {
 		BUG_ON(!name);
-		memcpy(mle->u.name.name, name, namelen);
-		mle->u.name.len = namelen;
-	} else /* DLM_MLE_MIGRATION */ {
-		BUG_ON(!name);
-		memcpy(mle->u.name.name, name, namelen);
-		mle->u.name.len = namelen;
+		mle->mleres = NULL;
+		memcpy(mle->mname, name, namelen);
+		mle->mnamelen = namelen;
+		mle->mnamehash = dlm_lockid_hash(name, namelen);
 	}
 
+	atomic_inc(&dlm->mle_tot_count[mle->type]);
+	atomic_inc(&dlm->mle_cur_count[mle->type]);
+
 	/* copy off the node_map and register hb callbacks on our copy */
 	memcpy(mle->node_map, dlm->domain_map, sizeof(mle->node_map));
 	memcpy(mle->vote_map, dlm->domain_map, sizeof(mle->vote_map));
@@ -318,6 +317,24 @@
 	__dlm_mle_attach_hb_events(dlm, mle);
 }
 
+void __dlm_unlink_mle(struct dlm_ctxt *dlm, struct dlm_master_list_entry *mle)
+{
+	assert_spin_locked(&dlm->spinlock);
+	assert_spin_locked(&dlm->master_lock);
+
+	if (!hlist_unhashed(&mle->master_hash_node))
+		hlist_del_init(&mle->master_hash_node);
+}
+
+void __dlm_insert_mle(struct dlm_ctxt *dlm, struct dlm_master_list_entry *mle)
+{
+	struct hlist_head *bucket;
+
+	assert_spin_locked(&dlm->master_lock);
+
+	bucket = dlm_master_hash(dlm, mle->mnamehash);
+	hlist_add_head(&mle->master_hash_node, bucket);
+}
 
 /* returns 1 if found, 0 if not */
 static int dlm_find_mle(struct dlm_ctxt *dlm,
@@ -325,10 +342,17 @@
 			char *name, unsigned int namelen)
 {
 	struct dlm_master_list_entry *tmpmle;
+	struct hlist_head *bucket;
+	struct hlist_node *list;
+	unsigned int hash;
 
 	assert_spin_locked(&dlm->master_lock);
 
-	list_for_each_entry(tmpmle, &dlm->master_list, list) {
+	hash = dlm_lockid_hash(name, namelen);
+	bucket = dlm_master_hash(dlm, hash);
+	hlist_for_each(list, bucket) {
+		tmpmle = hlist_entry(list, struct dlm_master_list_entry,
+				     master_hash_node);
 		if (!dlm_mle_equal(dlm, tmpmle, name, namelen))
 			continue;
 		dlm_get_mle(tmpmle);
@@ -408,24 +432,20 @@
 	mle = container_of(kref, struct dlm_master_list_entry, mle_refs);
 	dlm = mle->dlm;
 
-	if (mle->type != DLM_MLE_MASTER) {
-		mlog(0, "calling mle_release for %.*s, type %d\n",
-		     mle->u.name.len, mle->u.name.name, mle->type);
-	} else {
-		mlog(0, "calling mle_release for %.*s, type %d\n",
-		     mle->u.res->lockname.len,
-		     mle->u.res->lockname.name, mle->type);
-	}
 	assert_spin_locked(&dlm->spinlock);
 	assert_spin_locked(&dlm->master_lock);
 
+	mlog(0, "Releasing mle for %.*s, type %d\n", mle->mnamelen, mle->mname,
+	     mle->type);
+
 	/* remove from list if not already */
-	if (!list_empty(&mle->list))
-		list_del_init(&mle->list);
+	__dlm_unlink_mle(dlm, mle);
 
 	/* detach the mle from the domain node up/down events */
 	__dlm_mle_detach_hb_events(dlm, mle);
 
+	atomic_dec(&dlm->mle_cur_count[mle->type]);
+
 	/* NOTE: kfree under spinlock here.
 	 * if this is bad, we can move this to a freelist. */
 	kmem_cache_free(dlm_mle_cache, mle);
@@ -465,43 +485,6 @@
 		kmem_cache_destroy(dlm_lockres_cache);
 }
 
-static void dlm_set_lockres_owner(struct dlm_ctxt *dlm,
-				  struct dlm_lock_resource *res,
-				  u8 owner)
-{
-	assert_spin_locked(&res->spinlock);
-
-	mlog_entry("%.*s, %u\n", res->lockname.len, res->lockname.name, owner);
-
-	if (owner == dlm->node_num)
-		atomic_inc(&dlm->local_resources);
-	else if (owner == DLM_LOCK_RES_OWNER_UNKNOWN)
-		atomic_inc(&dlm->unknown_resources);
-	else
-		atomic_inc(&dlm->remote_resources);
-
-	res->owner = owner;
-}
-
-void dlm_change_lockres_owner(struct dlm_ctxt *dlm,
-			      struct dlm_lock_resource *res, u8 owner)
-{
-	assert_spin_locked(&res->spinlock);
-
-	if (owner == res->owner)
-		return;
-
-	if (res->owner == dlm->node_num)
-		atomic_dec(&dlm->local_resources);
-	else if (res->owner == DLM_LOCK_RES_OWNER_UNKNOWN)
-		atomic_dec(&dlm->unknown_resources);
-	else
-		atomic_dec(&dlm->remote_resources);
-
-	dlm_set_lockres_owner(dlm, res, owner);
-}
-
-
 static void dlm_lockres_release(struct kref *kref)
 {
 	struct dlm_lock_resource *res;
@@ -527,6 +510,8 @@
 	}
 	spin_unlock(&dlm->track_lock);
 
+	atomic_dec(&dlm->res_cur_count);
+
 	dlm_put(dlm);
 
 	if (!hlist_unhashed(&res->hash_node) ||
@@ -607,6 +592,9 @@
 
 	kref_init(&res->refs);
 
+	atomic_inc(&dlm->res_tot_count);
+	atomic_inc(&dlm->res_cur_count);
+
 	/* just for consistency */
 	spin_lock(&res->spinlock);
 	dlm_set_lockres_owner(dlm, res, DLM_LOCK_RES_OWNER_UNKNOWN);
@@ -843,7 +831,7 @@
 		alloc_mle = NULL;
 		dlm_init_mle(mle, DLM_MLE_MASTER, dlm, res, NULL, 0);
 		set_bit(dlm->node_num, mle->maybe_map);
-		list_add(&mle->list, &dlm->master_list);
+		__dlm_insert_mle(dlm, mle);
 
 		/* still holding the dlm spinlock, check the recovery map
 		 * to see if there are any nodes that still need to be 
@@ -1270,7 +1258,7 @@
 						     res->lockname.len,
 						     res->lockname.name);
 						mle->type = DLM_MLE_MASTER;
-						mle->u.res = res;
+						mle->mleres = res;
 					}
 				}
 			}
@@ -1315,14 +1303,8 @@
 
 	BUG_ON(mle->type == DLM_MLE_MIGRATION);
 
-	if (mle->type != DLM_MLE_MASTER) {
-		request.namelen = mle->u.name.len;
-		memcpy(request.name, mle->u.name.name, request.namelen);
-	} else {
-		request.namelen = mle->u.res->lockname.len;
-		memcpy(request.name, mle->u.res->lockname.name,
-			request.namelen);
-	}
+	request.namelen = (u8)mle->mnamelen;
+	memcpy(request.name, mle->mname, request.namelen);
 
 again:
 	ret = o2net_send_message(DLM_MASTER_REQUEST_MSG, dlm->key, &request,
@@ -1575,7 +1557,7 @@
 		// "add the block.\n");
 		dlm_init_mle(mle, DLM_MLE_BLOCK, dlm, NULL, name, namelen);
 		set_bit(request->node_idx, mle->maybe_map);
-		list_add(&mle->list, &dlm->master_list);
+		__dlm_insert_mle(dlm, mle);
 		response = DLM_MASTER_RESP_NO;
 	} else {
 		// mlog(0, "mle was found\n");
@@ -1967,7 +1949,7 @@
 			     assert->node_idx, rr, extra_ref, mle->inuse);
 			dlm_print_one_mle(mle);
 		}
-		list_del_init(&mle->list);
+		__dlm_unlink_mle(dlm, mle);
 		__dlm_mle_detach_hb_events(dlm, mle);
 		__dlm_put_mle(mle);
 		if (extra_ref) {
@@ -3159,10 +3141,8 @@
 			tmp->master = master;
 			atomic_set(&tmp->woken, 1);
 			wake_up(&tmp->wq);
-			/* remove it from the list so that only one
-			 * mle will be found */
-			list_del_init(&tmp->list);
-			/* this was obviously WRONG.  mle is uninited here.  should be tmp. */
+			/* remove it so that only one mle will be found */
+			__dlm_unlink_mle(dlm, tmp);
 			__dlm_mle_detach_hb_events(dlm, tmp);
 			ret = DLM_MIGRATE_RESPONSE_MASTERY_REF;
 			mlog(0, "%s:%.*s: master=%u, newmaster=%u, "
@@ -3181,17 +3161,93 @@
 	mle->master = master;
 	/* do this for consistency with other mle types */
 	set_bit(new_master, mle->maybe_map);
-	list_add(&mle->list, &dlm->master_list);
+	__dlm_insert_mle(dlm, mle);
 
 	return ret;
 }
 
+/*
+ * Sets the owner of the lockres, associated to the mle, to UNKNOWN
+ */
+static struct dlm_lock_resource *dlm_reset_mleres_owner(struct dlm_ctxt *dlm,
+					struct dlm_master_list_entry *mle)
+{
+	struct dlm_lock_resource *res;
+
+	/* Find the lockres associated to the mle and set its owner to UNK */
+	res = __dlm_lookup_lockres(dlm, mle->mname, mle->mnamelen,
+				   mle->mnamehash);
+	if (res) {
+		spin_unlock(&dlm->master_lock);
+
+		/* move lockres onto recovery list */
+		spin_lock(&res->spinlock);
+		dlm_set_lockres_owner(dlm, res, DLM_LOCK_RES_OWNER_UNKNOWN);
+		dlm_move_lockres_to_recovery_list(dlm, res);
+		spin_unlock(&res->spinlock);
+		dlm_lockres_put(res);
+
+		/* about to get rid of mle, detach from heartbeat */
+		__dlm_mle_detach_hb_events(dlm, mle);
+
+		/* dump the mle */
+		spin_lock(&dlm->master_lock);
+		__dlm_put_mle(mle);
+		spin_unlock(&dlm->master_lock);
+	}
+
+	return res;
+}
+
+static void dlm_clean_migration_mle(struct dlm_ctxt *dlm,
+				    struct dlm_master_list_entry *mle)
+{
+	__dlm_mle_detach_hb_events(dlm, mle);
+
+	spin_lock(&mle->spinlock);
+	__dlm_unlink_mle(dlm, mle);
+	atomic_set(&mle->woken, 1);
+	spin_unlock(&mle->spinlock);
+
+	wake_up(&mle->wq);
+}
+
+static void dlm_clean_block_mle(struct dlm_ctxt *dlm,
+				struct dlm_master_list_entry *mle, u8 dead_node)
+{
+	int bit;
+
+	BUG_ON(mle->type != DLM_MLE_BLOCK);
+
+	spin_lock(&mle->spinlock);
+	bit = find_next_bit(mle->maybe_map, O2NM_MAX_NODES, 0);
+	if (bit != dead_node) {
+		mlog(0, "mle found, but dead node %u would not have been "
+		     "master\n", dead_node);
+		spin_unlock(&mle->spinlock);
+	} else {
+		/* Must drop the refcount by one since the assert_master will
+		 * never arrive. This may result in the mle being unlinked and
+		 * freed, but there may still be a process waiting in the
+		 * dlmlock path which is fine. */
+		mlog(0, "node %u was expected master\n", dead_node);
+		atomic_set(&mle->woken, 1);
+		spin_unlock(&mle->spinlock);
+		wake_up(&mle->wq);
+
+		/* Do not need events any longer, so detach from heartbeat */
+		__dlm_mle_detach_hb_events(dlm, mle);
+		__dlm_put_mle(mle);
+	}
+}
 
 void dlm_clean_master_list(struct dlm_ctxt *dlm, u8 dead_node)
 {
-	struct dlm_master_list_entry *mle, *next;
+	struct dlm_master_list_entry *mle;
 	struct dlm_lock_resource *res;
-	unsigned int hash;
+	struct hlist_head *bucket;
+	struct hlist_node *list;
+	unsigned int i;
 
 	mlog_entry("dlm=%s, dead node=%u\n", dlm->name, dead_node);
 top:
@@ -3199,119 +3255,70 @@
 
 	/* clean the master list */
 	spin_lock(&dlm->master_lock);
-	list_for_each_entry_safe(mle, next, &dlm->master_list, list) {
-		BUG_ON(mle->type != DLM_MLE_BLOCK &&
-		       mle->type != DLM_MLE_MASTER &&
-		       mle->type != DLM_MLE_MIGRATION);
+	for (i = 0; i < DLM_HASH_BUCKETS; i++) {
+		bucket = dlm_master_hash(dlm, i);
+		hlist_for_each(list, bucket) {
+			mle = hlist_entry(list, struct dlm_master_list_entry,
+					  master_hash_node);
 
-		/* MASTER mles are initiated locally.  the waiting
-		 * process will notice the node map change
-		 * shortly.  let that happen as normal. */
-		if (mle->type == DLM_MLE_MASTER)
-			continue;
+			BUG_ON(mle->type != DLM_MLE_BLOCK &&
+			       mle->type != DLM_MLE_MASTER &&
+			       mle->type != DLM_MLE_MIGRATION);
 
+			/* MASTER mles are initiated locally. The waiting
+			 * process will notice the node map change shortly.
+			 * Let that happen as normal. */
+			if (mle->type == DLM_MLE_MASTER)
+				continue;
 
-		/* BLOCK mles are initiated by other nodes.
-		 * need to clean up if the dead node would have
-		 * been the master. */
-		if (mle->type == DLM_MLE_BLOCK) {
-			int bit;
-
-			spin_lock(&mle->spinlock);
-			bit = find_next_bit(mle->maybe_map, O2NM_MAX_NODES, 0);
-			if (bit != dead_node) {
-				mlog(0, "mle found, but dead node %u would "
-				     "not have been master\n", dead_node);
-				spin_unlock(&mle->spinlock);
-			} else {
-				/* must drop the refcount by one since the
-				 * assert_master will never arrive.  this
-				 * may result in the mle being unlinked and
-				 * freed, but there may still be a process
-				 * waiting in the dlmlock path which is fine. */
-				mlog(0, "node %u was expected master\n",
-				     dead_node);
-				atomic_set(&mle->woken, 1);
-				spin_unlock(&mle->spinlock);
-				wake_up(&mle->wq);
-				/* do not need events any longer, so detach 
-				 * from heartbeat */
-				__dlm_mle_detach_hb_events(dlm, mle);
-				__dlm_put_mle(mle);
+			/* BLOCK mles are initiated by other nodes. Need to
+			 * clean up if the dead node would have been the
+			 * master. */
+			if (mle->type == DLM_MLE_BLOCK) {
+				dlm_clean_block_mle(dlm, mle, dead_node);
+				continue;
 			}
-			continue;
-		}
 
-		/* everything else is a MIGRATION mle */
+			/* Everything else is a MIGRATION mle */
 
-		/* the rule for MIGRATION mles is that the master
-		 * becomes UNKNOWN if *either* the original or
-		 * the new master dies.  all UNKNOWN lockreses
-		 * are sent to whichever node becomes the recovery
-		 * master.  the new master is responsible for
-		 * determining if there is still a master for
-		 * this lockres, or if he needs to take over
-		 * mastery.  either way, this node should expect
-		 * another message to resolve this. */
-		if (mle->master != dead_node &&
-		    mle->new_master != dead_node)
-			continue;
+			/* The rule for MIGRATION mles is that the master
+			 * becomes UNKNOWN if *either* the original or the new
+			 * master dies. All UNKNOWN lockres' are sent to
+			 * whichever node becomes the recovery master. The new
+			 * master is responsible for determining if there is
+			 * still a master for this lockres, or if he needs to
+			 * take over mastery. Either way, this node should
+			 * expect another message to resolve this. */
 
-		/* if we have reached this point, this mle needs to
-		 * be removed from the list and freed. */
+			if (mle->master != dead_node &&
+			    mle->new_master != dead_node)
+				continue;
 
-		/* remove from the list early.  NOTE: unlinking
-		 * list_head while in list_for_each_safe */
-		__dlm_mle_detach_hb_events(dlm, mle);
-		spin_lock(&mle->spinlock);
-		list_del_init(&mle->list);
-		atomic_set(&mle->woken, 1);
-		spin_unlock(&mle->spinlock);
-		wake_up(&mle->wq);
+			/* If we have reached this point, this mle needs to be
+			 * removed from the list and freed. */
+			dlm_clean_migration_mle(dlm, mle);
 
-		mlog(0, "%s: node %u died during migration from "
-		     "%u to %u!\n", dlm->name, dead_node,
-		     mle->master, mle->new_master);
-		/* if there is a lockres associated with this
-	 	 * mle, find it and set its owner to UNKNOWN */
-		hash = dlm_lockid_hash(mle->u.name.name, mle->u.name.len);
-		res = __dlm_lookup_lockres(dlm, mle->u.name.name,
-					   mle->u.name.len, hash);
-		if (res) {
-			/* unfortunately if we hit this rare case, our
-		 	 * lock ordering is messed.  we need to drop
-		 	 * the master lock so that we can take the
-		  	 * lockres lock, meaning that we will have to
+			mlog(0, "%s: node %u died during migration from "
+			     "%u to %u!\n", dlm->name, dead_node, mle->master,
+			     mle->new_master);
+
+			/* If we find a lockres associated with the mle, we've
+			 * hit this rare case that messes up our lock ordering.
+			 * If so, we need to drop the master lock so that we can
+			 * take the lockres lock, meaning that we will have to
 			 * restart from the head of list. */
-			spin_unlock(&dlm->master_lock);
+			res = dlm_reset_mleres_owner(dlm, mle);
+			if (res)
+				/* restart */
+				goto top;
 
-			/* move lockres onto recovery list */
-			spin_lock(&res->spinlock);
-			dlm_set_lockres_owner(dlm, res,
-				      	DLM_LOCK_RES_OWNER_UNKNOWN);
-			dlm_move_lockres_to_recovery_list(dlm, res);
-			spin_unlock(&res->spinlock);
-			dlm_lockres_put(res);
-
-			/* about to get rid of mle, detach from heartbeat */
-			__dlm_mle_detach_hb_events(dlm, mle);
-
-			/* dump the mle */
-			spin_lock(&dlm->master_lock);
+			/* This may be the last reference */
 			__dlm_put_mle(mle);
-			spin_unlock(&dlm->master_lock);
-
-			/* restart */
-			goto top;
 		}
-
-		/* this may be the last reference */
-		__dlm_put_mle(mle);
 	}
 	spin_unlock(&dlm->master_lock);
 }
 
-
 int dlm_finish_migration(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
 			 u8 old_master)
 {
diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c
index 4060bb3..d490b66 100644
--- a/fs/ocfs2/dlm/dlmthread.c
+++ b/fs/ocfs2/dlm/dlmthread.c
@@ -162,12 +162,28 @@
 
 	spin_lock(&res->spinlock);
 	if (!__dlm_lockres_unused(res)) {
-		spin_unlock(&res->spinlock);
 		mlog(0, "%s:%.*s: tried to purge but not unused\n",
 		     dlm->name, res->lockname.len, res->lockname.name);
-		return -ENOTEMPTY;
+		__dlm_print_one_lock_resource(res);
+		spin_unlock(&res->spinlock);
+		BUG();
 	}
+
+	if (res->state & DLM_LOCK_RES_MIGRATING) {
+		mlog(0, "%s:%.*s: Delay dropref as this lockres is "
+		     "being remastered\n", dlm->name, res->lockname.len,
+		     res->lockname.name);
+		/* Re-add the lockres to the end of the purge list */
+		if (!list_empty(&res->purge)) {
+			list_del_init(&res->purge);
+			list_add_tail(&res->purge, &dlm->purge_list);
+		}
+		spin_unlock(&res->spinlock);
+		return 0;
+	}
+
 	master = (res->owner == dlm->node_num);
+
 	if (!master)
 		res->state |= DLM_LOCK_RES_DROPPING_REF;
 	spin_unlock(&res->spinlock);
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 7219a86..e15fc7d 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -244,6 +244,10 @@
 	.flags		= 0,
 };
 
+static struct ocfs2_lock_res_ops ocfs2_nfs_sync_lops = {
+	.flags		= 0,
+};
+
 static struct ocfs2_lock_res_ops ocfs2_dentry_lops = {
 	.get_osb	= ocfs2_get_dentry_osb,
 	.post_unlock	= ocfs2_dentry_post_unlock,
@@ -622,6 +626,17 @@
 				   &ocfs2_rename_lops, osb);
 }
 
+static void ocfs2_nfs_sync_lock_res_init(struct ocfs2_lock_res *res,
+					 struct ocfs2_super *osb)
+{
+	/* nfs_sync lockres doesn't come from a slab so we call init
+	 * once on it manually.  */
+	ocfs2_lock_res_init_once(res);
+	ocfs2_build_lock_name(OCFS2_LOCK_TYPE_NFS_SYNC, 0, 0, res->l_name);
+	ocfs2_lock_res_init_common(osb, res, OCFS2_LOCK_TYPE_NFS_SYNC,
+				   &ocfs2_nfs_sync_lops, osb);
+}
+
 void ocfs2_file_lock_res_init(struct ocfs2_lock_res *lockres,
 			      struct ocfs2_file_private *fp)
 {
@@ -2417,6 +2432,34 @@
 		ocfs2_cluster_unlock(osb, lockres, DLM_LOCK_EX);
 }
 
+int ocfs2_nfs_sync_lock(struct ocfs2_super *osb, int ex)
+{
+	int status;
+	struct ocfs2_lock_res *lockres = &osb->osb_nfs_sync_lockres;
+
+	if (ocfs2_is_hard_readonly(osb))
+		return -EROFS;
+
+	if (ocfs2_mount_local(osb))
+		return 0;
+
+	status = ocfs2_cluster_lock(osb, lockres, ex ? LKM_EXMODE : LKM_PRMODE,
+				    0, 0);
+	if (status < 0)
+		mlog(ML_ERROR, "lock on nfs sync lock failed %d\n", status);
+
+	return status;
+}
+
+void ocfs2_nfs_sync_unlock(struct ocfs2_super *osb, int ex)
+{
+	struct ocfs2_lock_res *lockres = &osb->osb_nfs_sync_lockres;
+
+	if (!ocfs2_mount_local(osb))
+		ocfs2_cluster_unlock(osb, lockres,
+				     ex ? LKM_EXMODE : LKM_PRMODE);
+}
+
 int ocfs2_dentry_lock(struct dentry *dentry, int ex)
 {
 	int ret;
@@ -2798,6 +2841,7 @@
 local:
 	ocfs2_super_lock_res_init(&osb->osb_super_lockres, osb);
 	ocfs2_rename_lock_res_init(&osb->osb_rename_lockres, osb);
+	ocfs2_nfs_sync_lock_res_init(&osb->osb_nfs_sync_lockres, osb);
 
 	osb->cconn = conn;
 
@@ -2833,6 +2877,7 @@
 
 	ocfs2_lock_res_free(&osb->osb_super_lockres);
 	ocfs2_lock_res_free(&osb->osb_rename_lockres);
+	ocfs2_lock_res_free(&osb->osb_nfs_sync_lockres);
 
 	ocfs2_cluster_disconnect(osb->cconn, hangup_pending);
 	osb->cconn = NULL;
@@ -3015,6 +3060,7 @@
 {
 	ocfs2_simple_drop_lockres(osb, &osb->osb_super_lockres);
 	ocfs2_simple_drop_lockres(osb, &osb->osb_rename_lockres);
+	ocfs2_simple_drop_lockres(osb, &osb->osb_nfs_sync_lockres);
 }
 
 int ocfs2_drop_inode_locks(struct inode *inode)
diff --git a/fs/ocfs2/dlmglue.h b/fs/ocfs2/dlmglue.h
index 3f8d998..e1fd572 100644
--- a/fs/ocfs2/dlmglue.h
+++ b/fs/ocfs2/dlmglue.h
@@ -115,6 +115,8 @@
 			int ex);
 int ocfs2_rename_lock(struct ocfs2_super *osb);
 void ocfs2_rename_unlock(struct ocfs2_super *osb);
+int ocfs2_nfs_sync_lock(struct ocfs2_super *osb, int ex);
+void ocfs2_nfs_sync_unlock(struct ocfs2_super *osb, int ex);
 int ocfs2_dentry_lock(struct dentry *dentry, int ex);
 void ocfs2_dentry_unlock(struct dentry *dentry, int ex);
 int ocfs2_file_lock(struct file *file, int ex, int trylock);
diff --git a/fs/ocfs2/export.c b/fs/ocfs2/export.c
index 2f27b33..de3da8e 100644
--- a/fs/ocfs2/export.c
+++ b/fs/ocfs2/export.c
@@ -31,6 +31,7 @@
 
 #include "ocfs2.h"
 
+#include "alloc.h"
 #include "dir.h"
 #include "dlmglue.h"
 #include "dcache.h"
@@ -38,6 +39,7 @@
 #include "inode.h"
 
 #include "buffer_head_io.h"
+#include "suballoc.h"
 
 struct ocfs2_inode_handle
 {
@@ -49,29 +51,97 @@
 		struct ocfs2_inode_handle *handle)
 {
 	struct inode *inode;
+	struct ocfs2_super *osb = OCFS2_SB(sb);
+	u64 blkno = handle->ih_blkno;
+	int status, set;
 	struct dentry *result;
 
 	mlog_entry("(0x%p, 0x%p)\n", sb, handle);
 
-	if (handle->ih_blkno == 0) {
-		mlog_errno(-ESTALE);
-		return ERR_PTR(-ESTALE);
+	if (blkno == 0) {
+		mlog(0, "nfs wants inode with blkno: 0\n");
+		result = ERR_PTR(-ESTALE);
+		goto bail;
 	}
 
-	inode = ocfs2_iget(OCFS2_SB(sb), handle->ih_blkno, 0, 0);
+	inode = ocfs2_ilookup(sb, blkno);
+	/*
+	 * If the inode exists in memory, we only need to check it's
+	 * generation number
+	 */
+	if (inode)
+		goto check_gen;
 
-	if (IS_ERR(inode))
-		return (void *)inode;
+	/*
+	 * This will synchronize us against ocfs2_delete_inode() on
+	 * all nodes
+	 */
+	status = ocfs2_nfs_sync_lock(osb, 1);
+	if (status < 0) {
+		mlog(ML_ERROR, "getting nfs sync lock(EX) failed %d\n", status);
+		goto check_err;
+	}
 
+	status = ocfs2_test_inode_bit(osb, blkno, &set);
+	if (status < 0) {
+		if (status == -EINVAL) {
+			/*
+			 * The blkno NFS gave us doesn't even show up
+			 * as an inode, we return -ESTALE to be
+			 * nice
+			 */
+			mlog(0, "test inode bit failed %d\n", status);
+			status = -ESTALE;
+		} else {
+			mlog(ML_ERROR, "test inode bit failed %d\n", status);
+		}
+		goto unlock_nfs_sync;
+	}
+
+	/* If the inode allocator bit is clear, this inode must be stale */
+	if (!set) {
+		mlog(0, "inode %llu suballoc bit is clear\n", blkno);
+		status = -ESTALE;
+		goto unlock_nfs_sync;
+	}
+
+	inode = ocfs2_iget(osb, blkno, 0, 0);
+
+unlock_nfs_sync:
+	ocfs2_nfs_sync_unlock(osb, 1);
+
+check_err:
+	if (status < 0) {
+		if (status == -ESTALE) {
+			mlog(0, "stale inode ino: %llu generation: %u\n",
+			     blkno, handle->ih_generation);
+		}
+		result = ERR_PTR(status);
+		goto bail;
+	}
+
+	if (IS_ERR(inode)) {
+		mlog_errno(PTR_ERR(inode));
+		result = (void *)inode;
+		goto bail;
+	}
+
+check_gen:
 	if (handle->ih_generation != inode->i_generation) {
 		iput(inode);
-		return ERR_PTR(-ESTALE);
+		mlog(0, "stale inode ino: %llu generation: %u\n", blkno,
+		     handle->ih_generation);
+		result = ERR_PTR(-ESTALE);
+		goto bail;
 	}
 
 	result = d_obtain_alias(inode);
 	if (!IS_ERR(result))
 		result->d_op = &ocfs2_dentry_ops;
+	else
+		mlog_errno(PTR_ERR(result));
 
+bail:
 	mlog_exit_ptr(result);
 	return result;
 }
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index 229e707..10e1fa87 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -38,6 +38,7 @@
 #include "ocfs2.h"
 
 #include "alloc.h"
+#include "dir.h"
 #include "blockcheck.h"
 #include "dlmglue.h"
 #include "extent_map.h"
@@ -112,6 +113,17 @@
 		oi->ip_attr |= OCFS2_DIRSYNC_FL;
 }
 
+struct inode *ocfs2_ilookup(struct super_block *sb, u64 blkno)
+{
+	struct ocfs2_find_inode_args args;
+
+	args.fi_blkno = blkno;
+	args.fi_flags = 0;
+	args.fi_ino = ino_from_blkno(sb, blkno);
+	args.fi_sysfile_type = 0;
+
+	return ilookup5(sb, blkno, ocfs2_find_actor, &args);
+}
 struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno, unsigned flags,
 			 int sysfile_type)
 {
@@ -275,7 +287,7 @@
 		     (unsigned long long)OCFS2_I(inode)->ip_blkno,
 		     (unsigned long long)le64_to_cpu(fe->i_blkno));
 
-	inode->i_nlink = le16_to_cpu(fe->i_links_count);
+	inode->i_nlink = ocfs2_read_links_count(fe);
 
 	if (fe->i_flags & cpu_to_le32(OCFS2_SYSTEM_FL)) {
 		OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SYSTEM_FILE;
@@ -351,6 +363,8 @@
 
 	ocfs2_set_inode_flags(inode);
 
+	OCFS2_I(inode)->ip_last_used_slot = 0;
+	OCFS2_I(inode)->ip_last_used_group = 0;
 	mlog_exit_void();
 }
 
@@ -606,7 +620,7 @@
 	}
 
 	handle = ocfs2_start_trans(osb, OCFS2_DELETE_INODE_CREDITS +
-					ocfs2_quota_trans_credits(inode->i_sb));
+				   ocfs2_quota_trans_credits(inode->i_sb));
 	if (IS_ERR(handle)) {
 		status = PTR_ERR(handle);
 		mlog_errno(status);
@@ -740,6 +754,15 @@
 		goto bail_unlock_dir;
 	}
 
+	/* Remove any dir index tree */
+	if (S_ISDIR(inode->i_mode)) {
+		status = ocfs2_dx_dir_truncate(inode, di_bh);
+		if (status) {
+			mlog_errno(status);
+			goto bail_unlock_dir;
+		}
+	}
+
 	/*Free extended attribute resources associated with this inode.*/
 	status = ocfs2_xattr_remove(inode, di_bh);
 	if (status < 0) {
@@ -949,6 +972,17 @@
 		goto bail;
 	}
 
+	/*
+	 * Synchronize us against ocfs2_get_dentry. We take this in
+	 * shared mode so that all nodes can still concurrently
+	 * process deletes.
+	 */
+	status = ocfs2_nfs_sync_lock(OCFS2_SB(inode->i_sb), 0);
+	if (status < 0) {
+		mlog(ML_ERROR, "getting nfs sync lock(PR) failed %d\n", status);
+		ocfs2_cleanup_delete_inode(inode, 0);
+		goto bail_unblock;
+	}
 	/* Lock down the inode. This gives us an up to date view of
 	 * it's metadata (for verification), and allows us to
 	 * serialize delete_inode on multiple nodes.
@@ -962,7 +996,7 @@
 		if (status != -ENOENT)
 			mlog_errno(status);
 		ocfs2_cleanup_delete_inode(inode, 0);
-		goto bail_unblock;
+		goto bail_unlock_nfs_sync;
 	}
 
 	/* Query the cluster. This will be the final decision made
@@ -1005,6 +1039,10 @@
 bail_unlock_inode:
 	ocfs2_inode_unlock(inode, 1);
 	brelse(di_bh);
+
+bail_unlock_nfs_sync:
+	ocfs2_nfs_sync_unlock(OCFS2_SB(inode->i_sb), 0);
+
 bail_unblock:
 	status = sigprocmask(SIG_SETMASK, &oldset, NULL);
 	if (status < 0)
@@ -1205,7 +1243,7 @@
 	spin_unlock(&OCFS2_I(inode)->ip_lock);
 
 	fe->i_size = cpu_to_le64(i_size_read(inode));
-	fe->i_links_count = cpu_to_le16(inode->i_nlink);
+	ocfs2_set_links_count(fe, inode->i_nlink);
 	fe->i_uid = cpu_to_le32(inode->i_uid);
 	fe->i_gid = cpu_to_le32(inode->i_gid);
 	fe->i_mode = cpu_to_le16(inode->i_mode);
@@ -1242,7 +1280,7 @@
 	OCFS2_I(inode)->ip_dyn_features = le16_to_cpu(fe->i_dyn_features);
 	ocfs2_set_inode_flags(inode);
 	i_size_write(inode, le64_to_cpu(fe->i_size));
-	inode->i_nlink = le16_to_cpu(fe->i_links_count);
+	inode->i_nlink = ocfs2_read_links_count(fe);
 	inode->i_uid = le32_to_cpu(fe->i_uid);
 	inode->i_gid = le32_to_cpu(fe->i_gid);
 	inode->i_mode = le16_to_cpu(fe->i_mode);
diff --git a/fs/ocfs2/inode.h b/fs/ocfs2/inode.h
index eb3c302..ea71525 100644
--- a/fs/ocfs2/inode.h
+++ b/fs/ocfs2/inode.h
@@ -72,6 +72,10 @@
 
 	struct inode			vfs_inode;
 	struct jbd2_inode		ip_jinode;
+
+	/* Only valid if the inode is the dir. */
+	u32				ip_last_used_slot;
+	u64				ip_last_used_group;
 };
 
 /*
@@ -124,6 +128,7 @@
 /* Flags for ocfs2_iget() */
 #define OCFS2_FI_FLAG_SYSFILE		0x1
 #define OCFS2_FI_FLAG_ORPHAN_RECOVERY	0x2
+struct inode *ocfs2_ilookup(struct super_block *sb, u64 feoff);
 struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 feoff, unsigned flags,
 			 int sysfile_type);
 int ocfs2_inode_init_private(struct inode *inode);
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
index 57d7d25..a20a0f1 100644
--- a/fs/ocfs2/journal.c
+++ b/fs/ocfs2/journal.c
@@ -65,6 +65,11 @@
 static int ocfs2_recover_orphans(struct ocfs2_super *osb,
 				 int slot);
 static int ocfs2_commit_thread(void *arg);
+static void ocfs2_queue_recovery_completion(struct ocfs2_journal *journal,
+					    int slot_num,
+					    struct ocfs2_dinode *la_dinode,
+					    struct ocfs2_dinode *tl_dinode,
+					    struct ocfs2_quota_recovery *qrec);
 
 static inline int ocfs2_wait_on_mount(struct ocfs2_super *osb)
 {
@@ -76,18 +81,97 @@
 	return __ocfs2_wait_on_mount(osb, 1);
 }
 
-
-
 /*
- * The recovery_list is a simple linked list of node numbers to recover.
- * It is protected by the recovery_lock.
+ * This replay_map is to track online/offline slots, so we could recover
+ * offline slots during recovery and mount
  */
 
-struct ocfs2_recovery_map {
-	unsigned int rm_used;
-	unsigned int *rm_entries;
+enum ocfs2_replay_state {
+	REPLAY_UNNEEDED = 0,	/* Replay is not needed, so ignore this map */
+	REPLAY_NEEDED, 		/* Replay slots marked in rm_replay_slots */
+	REPLAY_DONE 		/* Replay was already queued */
 };
 
+struct ocfs2_replay_map {
+	unsigned int rm_slots;
+	enum ocfs2_replay_state rm_state;
+	unsigned char rm_replay_slots[0];
+};
+
+void ocfs2_replay_map_set_state(struct ocfs2_super *osb, int state)
+{
+	if (!osb->replay_map)
+		return;
+
+	/* If we've already queued the replay, we don't have any more to do */
+	if (osb->replay_map->rm_state == REPLAY_DONE)
+		return;
+
+	osb->replay_map->rm_state = state;
+}
+
+int ocfs2_compute_replay_slots(struct ocfs2_super *osb)
+{
+	struct ocfs2_replay_map *replay_map;
+	int i, node_num;
+
+	/* If replay map is already set, we don't do it again */
+	if (osb->replay_map)
+		return 0;
+
+	replay_map = kzalloc(sizeof(struct ocfs2_replay_map) +
+			     (osb->max_slots * sizeof(char)), GFP_KERNEL);
+
+	if (!replay_map) {
+		mlog_errno(-ENOMEM);
+		return -ENOMEM;
+	}
+
+	spin_lock(&osb->osb_lock);
+
+	replay_map->rm_slots = osb->max_slots;
+	replay_map->rm_state = REPLAY_UNNEEDED;
+
+	/* set rm_replay_slots for offline slot(s) */
+	for (i = 0; i < replay_map->rm_slots; i++) {
+		if (ocfs2_slot_to_node_num_locked(osb, i, &node_num) == -ENOENT)
+			replay_map->rm_replay_slots[i] = 1;
+	}
+
+	osb->replay_map = replay_map;
+	spin_unlock(&osb->osb_lock);
+	return 0;
+}
+
+void ocfs2_queue_replay_slots(struct ocfs2_super *osb)
+{
+	struct ocfs2_replay_map *replay_map = osb->replay_map;
+	int i;
+
+	if (!replay_map)
+		return;
+
+	if (replay_map->rm_state != REPLAY_NEEDED)
+		return;
+
+	for (i = 0; i < replay_map->rm_slots; i++)
+		if (replay_map->rm_replay_slots[i])
+			ocfs2_queue_recovery_completion(osb->journal, i, NULL,
+							NULL, NULL);
+	replay_map->rm_state = REPLAY_DONE;
+}
+
+void ocfs2_free_replay_slots(struct ocfs2_super *osb)
+{
+	struct ocfs2_replay_map *replay_map = osb->replay_map;
+
+	if (!osb->replay_map)
+		return;
+
+	kfree(replay_map);
+	osb->replay_map = NULL;
+}
+
 int ocfs2_recovery_init(struct ocfs2_super *osb)
 {
 	struct ocfs2_recovery_map *rm;
@@ -496,6 +580,22 @@
 	},
 };
 
+static struct ocfs2_triggers dr_triggers = {
+	.ot_triggers = {
+		.t_commit = ocfs2_commit_trigger,
+		.t_abort = ocfs2_abort_trigger,
+	},
+	.ot_offset	= offsetof(struct ocfs2_dx_root_block, dr_check),
+};
+
+static struct ocfs2_triggers dl_triggers = {
+	.ot_triggers = {
+		.t_commit = ocfs2_commit_trigger,
+		.t_abort = ocfs2_abort_trigger,
+	},
+	.ot_offset	= offsetof(struct ocfs2_dx_leaf, dl_check),
+};
+
 static int __ocfs2_journal_access(handle_t *handle,
 				  struct inode *inode,
 				  struct buffer_head *bh,
@@ -600,6 +700,20 @@
 				      type);
 }
 
+int ocfs2_journal_access_dr(handle_t *handle, struct inode *inode,
+			    struct buffer_head *bh, int type)
+{
+	return __ocfs2_journal_access(handle, inode, bh, &dr_triggers,
+				      type);
+}
+
+int ocfs2_journal_access_dl(handle_t *handle, struct inode *inode,
+			    struct buffer_head *bh, int type)
+{
+	return __ocfs2_journal_access(handle, inode, bh, &dl_triggers,
+				      type);
+}
+
 int ocfs2_journal_access(handle_t *handle, struct inode *inode,
 			 struct buffer_head *bh, int type)
 {
@@ -1176,24 +1290,24 @@
 }
 
 /* Called by the mount code to queue recovery the last part of
- * recovery for it's own slot. */
+ * recovery for it's own and offline slot(s). */
 void ocfs2_complete_mount_recovery(struct ocfs2_super *osb)
 {
 	struct ocfs2_journal *journal = osb->journal;
 
-	if (osb->dirty) {
-		/* No need to queue up our truncate_log as regular
-		 * cleanup will catch that. */
-		ocfs2_queue_recovery_completion(journal,
-						osb->slot_num,
-						osb->local_alloc_copy,
-						NULL,
-						NULL);
-		ocfs2_schedule_truncate_log_flush(osb, 0);
+	/* No need to queue up our truncate_log as regular cleanup will catch
+	 * that */
+	ocfs2_queue_recovery_completion(journal, osb->slot_num,
+					osb->local_alloc_copy, NULL, NULL);
+	ocfs2_schedule_truncate_log_flush(osb, 0);
 
-		osb->local_alloc_copy = NULL;
-		osb->dirty = 0;
-	}
+	osb->local_alloc_copy = NULL;
+	osb->dirty = 0;
+
+	/* queue to recover orphan slots for all offline slots */
+	ocfs2_replay_map_set_state(osb, REPLAY_NEEDED);
+	ocfs2_queue_replay_slots(osb);
+	ocfs2_free_replay_slots(osb);
 }
 
 void ocfs2_complete_quota_recovery(struct ocfs2_super *osb)
@@ -1236,6 +1350,14 @@
 		goto bail;
 	}
 
+	status = ocfs2_compute_replay_slots(osb);
+	if (status < 0)
+		mlog_errno(status);
+
+	/* queue recovery for our own slot */
+	ocfs2_queue_recovery_completion(osb->journal, osb->slot_num, NULL,
+					NULL, NULL);
+
 	spin_lock(&osb->osb_lock);
 	while (rm->rm_used) {
 		/* It's always safe to remove entry zero, as we won't
@@ -1301,11 +1423,8 @@
 
 	ocfs2_super_unlock(osb, 1);
 
-	/* We always run recovery on our own orphan dir - the dead
-	 * node(s) may have disallowd a previos inode delete. Re-processing
-	 * is therefore required. */
-	ocfs2_queue_recovery_completion(osb->journal, osb->slot_num, NULL,
-					NULL, NULL);
+	/* queue recovery for offline slots */
+	ocfs2_queue_replay_slots(osb);
 
 bail:
 	mutex_lock(&osb->recovery_lock);
@@ -1314,6 +1433,7 @@
 		goto restart;
 	}
 
+	ocfs2_free_replay_slots(osb);
 	osb->recovery_thread_task = NULL;
 	mb(); /* sync with ocfs2_recovery_thread_running */
 	wake_up(&osb->recovery_event);
@@ -1465,6 +1585,9 @@
 		goto done;
 	}
 
+	/* we need to run complete recovery for offline orphan slots */
+	ocfs2_replay_map_set_state(osb, REPLAY_NEEDED);
+
 	mlog(ML_NOTICE, "Recovering node %d from slot %d on device (%u,%u)\n",
 	     node_num, slot_num,
 	     MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev));
diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h
index 172850a..619dd7f6 100644
--- a/fs/ocfs2/journal.h
+++ b/fs/ocfs2/journal.h
@@ -38,6 +38,17 @@
 struct ocfs2_super;
 struct ocfs2_dinode;
 
+/*
+ * The recovery_list is a simple linked list of node numbers to recover.
+ * It is protected by the recovery_lock.
+ */
+
+struct ocfs2_recovery_map {
+	unsigned int rm_used;
+	unsigned int *rm_entries;
+};
+
+
 struct ocfs2_journal {
 	enum ocfs2_journal_state   j_state;    /* Journals current state   */
 
@@ -139,6 +150,7 @@
 int ocfs2_recovery_init(struct ocfs2_super *osb);
 void ocfs2_recovery_exit(struct ocfs2_super *osb);
 
+int ocfs2_compute_replay_slots(struct ocfs2_super *osb);
 /*
  *  Journal Control:
  *  Initialize, Load, Shutdown, Wipe a journal.
@@ -266,6 +278,12 @@
 /* dirblock */
 int ocfs2_journal_access_db(handle_t *handle, struct inode *inode,
 			    struct buffer_head *bh, int type);
+/* ocfs2_dx_root_block */
+int ocfs2_journal_access_dr(handle_t *handle, struct inode *inode,
+			    struct buffer_head *bh, int type);
+/* ocfs2_dx_leaf */
+int ocfs2_journal_access_dl(handle_t *handle, struct inode *inode,
+			    struct buffer_head *bh, int type);
 /* Anything that has no ecc */
 int ocfs2_journal_access(handle_t *handle, struct inode *inode,
 			 struct buffer_head *bh, int type);
@@ -368,14 +386,29 @@
 }
 
 /* data block for new dir/symlink, 2 for bitmap updates (bitmap fe +
- * bitmap block for the new bit) */
-#define OCFS2_DIR_LINK_ADDITIONAL_CREDITS (1 + 2)
+ * bitmap block for the new bit) dx_root update for free list */
+#define OCFS2_DIR_LINK_ADDITIONAL_CREDITS (1 + 2 + 1)
 
-/* parent fe, parent block, new file entry, inode alloc fe, inode alloc
- * group descriptor + mkdir/symlink blocks + quota update */
-static inline int ocfs2_mknod_credits(struct super_block *sb)
+static inline int ocfs2_add_dir_index_credits(struct super_block *sb)
 {
-	return 3 + OCFS2_SUBALLOC_ALLOC + OCFS2_DIR_LINK_ADDITIONAL_CREDITS +
+	/* 1 block for index, 2 allocs (data, metadata), 1 clusters
+	 * worth of blocks for initial extent. */
+	return 1 + 2 * OCFS2_SUBALLOC_ALLOC +
+		ocfs2_clusters_to_blocks(sb, 1);
+}
+
+/* parent fe, parent block, new file entry, index leaf, inode alloc fe, inode
+ * alloc group descriptor + mkdir/symlink blocks + dir blocks + xattr
+ * blocks + quota update */
+static inline int ocfs2_mknod_credits(struct super_block *sb, int is_dir,
+				      int xattr_credits)
+{
+	int dir_credits = OCFS2_DIR_LINK_ADDITIONAL_CREDITS;
+
+	if (is_dir)
+		dir_credits += ocfs2_add_dir_index_credits(sb);
+
+	return 4 + OCFS2_SUBALLOC_ALLOC + dir_credits + xattr_credits +
 	       ocfs2_quota_trans_credits(sb);
 }
 
@@ -388,31 +421,31 @@
 #define OCFS2_SIMPLE_DIR_EXTEND_CREDITS (2)
 
 /* file update (nlink, etc) + directory mtime/ctime + dir entry block + quota
- * update on dir */
+ * update on dir + index leaf + dx root update for free list */
 static inline int ocfs2_link_credits(struct super_block *sb)
 {
-	return 2*OCFS2_INODE_UPDATE_CREDITS + 1 +
+	return 2*OCFS2_INODE_UPDATE_CREDITS + 3 +
 	       ocfs2_quota_trans_credits(sb);
 }
 
 /* inode + dir inode (if we unlink a dir), + dir entry block + orphan
- * dir inode link */
+ * dir inode link + dir inode index leaf + dir index root */
 static inline int ocfs2_unlink_credits(struct super_block *sb)
 {
 	/* The quota update from ocfs2_link_credits is unused here... */
-	return 2 * OCFS2_INODE_UPDATE_CREDITS + 1 + ocfs2_link_credits(sb);
+	return 2 * OCFS2_INODE_UPDATE_CREDITS + 3 + ocfs2_link_credits(sb);
 }
 
 /* dinode + orphan dir dinode + inode alloc dinode + orphan dir entry +
- * inode alloc group descriptor */
-#define OCFS2_DELETE_INODE_CREDITS (3 * OCFS2_INODE_UPDATE_CREDITS + 1 + 1)
+ * inode alloc group descriptor + orphan dir index leaf */
+#define OCFS2_DELETE_INODE_CREDITS (3 * OCFS2_INODE_UPDATE_CREDITS + 3)
 
 /* dinode update, old dir dinode update, new dir dinode update, old
  * dir dir entry, new dir dir entry, dir entry update for renaming
- * directory + target unlink */
+ * directory + target unlink + 3 x dir index leaves */
 static inline int ocfs2_rename_credits(struct super_block *sb)
 {
-	return 3 * OCFS2_INODE_UPDATE_CREDITS + 3 + ocfs2_unlink_credits(sb);
+	return 3 * OCFS2_INODE_UPDATE_CREDITS + 6 + ocfs2_unlink_credits(sb);
 }
 
 /* global bitmap dinode, group desc., relinked group,
@@ -422,6 +455,20 @@
 					  + OCFS2_INODE_UPDATE_CREDITS \
 					  + OCFS2_XATTR_BLOCK_UPDATE_CREDITS)
 
+/* inode update, removal of dx root block from allocator */
+#define OCFS2_DX_ROOT_REMOVE_CREDITS (OCFS2_INODE_UPDATE_CREDITS +	\
+				      OCFS2_SUBALLOC_FREE)
+
+static inline int ocfs2_calc_dxi_expand_credits(struct super_block *sb)
+{
+	int credits = 1 + OCFS2_SUBALLOC_ALLOC;
+
+	credits += ocfs2_clusters_to_blocks(sb, 1);
+	credits += ocfs2_quota_trans_credits(sb);
+
+	return credits;
+}
+
 /*
  * Please note that the caller must make sure that root_el is the root
  * of extent tree. So for an inode, it should be &fe->id2.i_list. Otherwise
@@ -457,7 +504,7 @@
 
 static inline int ocfs2_calc_symlink_credits(struct super_block *sb)
 {
-	int blocks = ocfs2_mknod_credits(sb);
+	int blocks = ocfs2_mknod_credits(sb, 0, 0);
 
 	/* links can be longer than one block so we may update many
 	 * within our single allocated extent. */
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c
index ec70cdb..bac7e6a 100644
--- a/fs/ocfs2/localalloc.c
+++ b/fs/ocfs2/localalloc.c
@@ -28,7 +28,6 @@
 #include <linux/slab.h>
 #include <linux/highmem.h>
 #include <linux/bitops.h>
-#include <linux/debugfs.h>
 
 #define MLOG_MASK_PREFIX ML_DISK_ALLOC
 #include <cluster/masklog.h>
@@ -75,84 +74,6 @@
 static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb,
 					  struct inode *local_alloc_inode);
 
-#ifdef CONFIG_OCFS2_FS_STATS
-
-static int ocfs2_la_debug_open(struct inode *inode, struct file *file)
-{
-	file->private_data = inode->i_private;
-	return 0;
-}
-
-#define LA_DEBUG_BUF_SZ	PAGE_CACHE_SIZE
-#define LA_DEBUG_VER	1
-static ssize_t ocfs2_la_debug_read(struct file *file, char __user *userbuf,
-				   size_t count, loff_t *ppos)
-{
-	static DEFINE_MUTEX(la_debug_mutex);
-	struct ocfs2_super *osb = file->private_data;
-	int written, ret;
-	char *buf = osb->local_alloc_debug_buf;
-
-	mutex_lock(&la_debug_mutex);
-	memset(buf, 0, LA_DEBUG_BUF_SZ);
-
-	written = snprintf(buf, LA_DEBUG_BUF_SZ,
-			   "0x%x\t0x%llx\t%u\t%u\t0x%x\n",
-			   LA_DEBUG_VER,
-			   (unsigned long long)osb->la_last_gd,
-			   osb->local_alloc_default_bits,
-			   osb->local_alloc_bits, osb->local_alloc_state);
-
-	ret = simple_read_from_buffer(userbuf, count, ppos, buf, written);
-
-	mutex_unlock(&la_debug_mutex);
-	return ret;
-}
-
-static const struct file_operations ocfs2_la_debug_fops = {
-	.open =		ocfs2_la_debug_open,
-	.read =		ocfs2_la_debug_read,
-};
-
-static void ocfs2_init_la_debug(struct ocfs2_super *osb)
-{
-	osb->local_alloc_debug_buf = kmalloc(LA_DEBUG_BUF_SZ, GFP_NOFS);
-	if (!osb->local_alloc_debug_buf)
-		return;
-
-	osb->local_alloc_debug = debugfs_create_file("local_alloc_stats",
-						     S_IFREG|S_IRUSR,
-						     osb->osb_debug_root,
-						     osb,
-						     &ocfs2_la_debug_fops);
-	if (!osb->local_alloc_debug) {
-		kfree(osb->local_alloc_debug_buf);
-		osb->local_alloc_debug_buf = NULL;
-	}
-}
-
-static void ocfs2_shutdown_la_debug(struct ocfs2_super *osb)
-{
-	if (osb->local_alloc_debug)
-		debugfs_remove(osb->local_alloc_debug);
-
-	if (osb->local_alloc_debug_buf)
-		kfree(osb->local_alloc_debug_buf);
-
-	osb->local_alloc_debug_buf = NULL;
-	osb->local_alloc_debug = NULL;
-}
-#else	/* CONFIG_OCFS2_FS_STATS */
-static void ocfs2_init_la_debug(struct ocfs2_super *osb)
-{
-	return;
-}
-static void ocfs2_shutdown_la_debug(struct ocfs2_super *osb)
-{
-	return;
-}
-#endif
-
 static inline int ocfs2_la_state_enabled(struct ocfs2_super *osb)
 {
 	return (osb->local_alloc_state == OCFS2_LA_THROTTLED ||
@@ -226,8 +147,6 @@
 
 	mlog_entry_void();
 
-	ocfs2_init_la_debug(osb);
-
 	if (osb->local_alloc_bits == 0)
 		goto bail;
 
@@ -299,9 +218,6 @@
 	if (inode)
 		iput(inode);
 
-	if (status < 0)
-		ocfs2_shutdown_la_debug(osb);
-
 	mlog(0, "Local alloc window bits = %d\n", osb->local_alloc_bits);
 
 	mlog_exit(status);
@@ -331,8 +247,6 @@
 	cancel_delayed_work(&osb->la_enable_wq);
 	flush_workqueue(ocfs2_wq);
 
-	ocfs2_shutdown_la_debug(osb);
-
 	if (osb->local_alloc_state == OCFS2_LA_UNUSED)
 		goto out;
 
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index 4b11762..2220f93 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -80,14 +80,14 @@
 				    struct inode **ret_orphan_dir,
 				    struct inode *inode,
 				    char *name,
-				    struct buffer_head **de_bh);
+				    struct ocfs2_dir_lookup_result *lookup);
 
 static int ocfs2_orphan_add(struct ocfs2_super *osb,
 			    handle_t *handle,
 			    struct inode *inode,
 			    struct ocfs2_dinode *fe,
 			    char *name,
-			    struct buffer_head *de_bh,
+			    struct ocfs2_dir_lookup_result *lookup,
 			    struct inode *orphan_dir_inode);
 
 static int ocfs2_create_symlink_data(struct ocfs2_super *osb,
@@ -228,17 +228,18 @@
 	struct ocfs2_super *osb;
 	struct ocfs2_dinode *dirfe;
 	struct buffer_head *new_fe_bh = NULL;
-	struct buffer_head *de_bh = NULL;
 	struct inode *inode = NULL;
 	struct ocfs2_alloc_context *inode_ac = NULL;
 	struct ocfs2_alloc_context *data_ac = NULL;
-	struct ocfs2_alloc_context *xattr_ac = NULL;
+	struct ocfs2_alloc_context *meta_ac = NULL;
 	int want_clusters = 0;
+	int want_meta = 0;
 	int xattr_credits = 0;
 	struct ocfs2_security_xattr_info si = {
 		.enable = 1,
 	};
 	int did_quota_inode = 0;
+	struct ocfs2_dir_lookup_result lookup = { NULL, };
 
 	mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, mode,
 		   (unsigned long)dev, dentry->d_name.len,
@@ -254,13 +255,13 @@
 		return status;
 	}
 
-	if (S_ISDIR(mode) && (dir->i_nlink >= OCFS2_LINK_MAX)) {
+	if (S_ISDIR(mode) && (dir->i_nlink >= ocfs2_link_max(osb))) {
 		status = -EMLINK;
 		goto leave;
 	}
 
 	dirfe = (struct ocfs2_dinode *) parent_fe_bh->b_data;
-	if (!dirfe->i_links_count) {
+	if (!ocfs2_read_links_count(dirfe)) {
 		/* can't make a file in a deleted directory. */
 		status = -ENOENT;
 		goto leave;
@@ -274,7 +275,7 @@
 	/* get a spot inside the dir. */
 	status = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh,
 					      dentry->d_name.name,
-					      dentry->d_name.len, &de_bh);
+					      dentry->d_name.len, &lookup);
 	if (status < 0) {
 		mlog_errno(status);
 		goto leave;
@@ -308,17 +309,29 @@
 
 	/* calculate meta data/clusters for setting security and acl xattr */
 	status = ocfs2_calc_xattr_init(dir, parent_fe_bh, mode,
-					&si, &want_clusters,
-					&xattr_credits, &xattr_ac);
+				       &si, &want_clusters,
+				       &xattr_credits, &want_meta);
 	if (status < 0) {
 		mlog_errno(status);
 		goto leave;
 	}
 
 	/* Reserve a cluster if creating an extent based directory. */
-	if (S_ISDIR(mode) && !ocfs2_supports_inline_data(osb))
+	if (S_ISDIR(mode) && !ocfs2_supports_inline_data(osb)) {
 		want_clusters += 1;
 
+		/* Dir indexing requires extra space as well */
+		if (ocfs2_supports_indexed_dirs(osb))
+			want_meta++;
+	}
+
+	status = ocfs2_reserve_new_metadata_blocks(osb, want_meta, &meta_ac);
+	if (status < 0) {
+		if (status != -ENOSPC)
+			mlog_errno(status);
+		goto leave;
+	}
+
 	status = ocfs2_reserve_clusters(osb, want_clusters, &data_ac);
 	if (status < 0) {
 		if (status != -ENOSPC)
@@ -326,8 +339,9 @@
 		goto leave;
 	}
 
-	handle = ocfs2_start_trans(osb, ocfs2_mknod_credits(osb->sb) +
-				   xattr_credits);
+	handle = ocfs2_start_trans(osb, ocfs2_mknod_credits(osb->sb,
+							    S_ISDIR(mode),
+							    xattr_credits));
 	if (IS_ERR(handle)) {
 		status = PTR_ERR(handle);
 		handle = NULL;
@@ -355,7 +369,7 @@
 
 	if (S_ISDIR(mode)) {
 		status = ocfs2_fill_new_dir(osb, handle, dir, inode,
-					    new_fe_bh, data_ac);
+					    new_fe_bh, data_ac, meta_ac);
 		if (status < 0) {
 			mlog_errno(status);
 			goto leave;
@@ -367,7 +381,7 @@
 			mlog_errno(status);
 			goto leave;
 		}
-		le16_add_cpu(&dirfe->i_links_count, 1);
+		ocfs2_add_links_count(dirfe, 1);
 		status = ocfs2_journal_dirty(handle, parent_fe_bh);
 		if (status < 0) {
 			mlog_errno(status);
@@ -377,7 +391,7 @@
 	}
 
 	status = ocfs2_init_acl(handle, inode, dir, new_fe_bh, parent_fe_bh,
-				xattr_ac, data_ac);
+				meta_ac, data_ac);
 	if (status < 0) {
 		mlog_errno(status);
 		goto leave;
@@ -385,7 +399,7 @@
 
 	if (si.enable) {
 		status = ocfs2_init_security_set(handle, inode, new_fe_bh, &si,
-						 xattr_ac, data_ac);
+						 meta_ac, data_ac);
 		if (status < 0) {
 			mlog_errno(status);
 			goto leave;
@@ -394,7 +408,7 @@
 
 	status = ocfs2_add_entry(handle, dentry, inode,
 				 OCFS2_I(inode)->ip_blkno, parent_fe_bh,
-				 de_bh);
+				 &lookup);
 	if (status < 0) {
 		mlog_errno(status);
 		goto leave;
@@ -423,11 +437,12 @@
 		mlog(0, "Disk is full\n");
 
 	brelse(new_fe_bh);
-	brelse(de_bh);
 	brelse(parent_fe_bh);
 	kfree(si.name);
 	kfree(si.value);
 
+	ocfs2_free_dir_lookup_result(&lookup);
+
 	if ((status < 0) && inode) {
 		clear_nlink(inode);
 		iput(inode);
@@ -439,8 +454,8 @@
 	if (data_ac)
 		ocfs2_free_alloc_context(data_ac);
 
-	if (xattr_ac)
-		ocfs2_free_alloc_context(xattr_ac);
+	if (meta_ac)
+		ocfs2_free_alloc_context(meta_ac);
 
 	mlog_exit(status);
 
@@ -462,6 +477,7 @@
 	struct ocfs2_extent_list *fel;
 	u64 fe_blkno = 0;
 	u16 suballoc_bit;
+	u16 feat;
 
 	mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry,
 		   inode->i_mode, (unsigned long)dev, dentry->d_name.len,
@@ -469,8 +485,8 @@
 
 	*new_fe_bh = NULL;
 
-	status = ocfs2_claim_new_inode(osb, handle, inode_ac, &suballoc_bit,
-				       &fe_blkno);
+	status = ocfs2_claim_new_inode(osb, handle, dir, parent_fe_bh,
+				       inode_ac, &suballoc_bit, &fe_blkno);
 	if (status < 0) {
 		mlog_errno(status);
 		goto leave;
@@ -513,7 +529,8 @@
 	fe->i_mode = cpu_to_le16(inode->i_mode);
 	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
 		fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev));
-	fe->i_links_count = cpu_to_le16(inode->i_nlink);
+
+	ocfs2_set_links_count(fe, inode->i_nlink);
 
 	fe->i_last_eb_blk = 0;
 	strcpy(fe->i_signature, OCFS2_INODE_SIGNATURE);
@@ -525,11 +542,11 @@
 	fe->i_dtime = 0;
 
 	/*
-	 * If supported, directories start with inline data.
+	 * If supported, directories start with inline data. If inline
+	 * isn't supported, but indexing is, we start them as indexed.
 	 */
+	feat = le16_to_cpu(fe->i_dyn_features);
 	if (S_ISDIR(inode->i_mode) && ocfs2_supports_inline_data(osb)) {
-		u16 feat = le16_to_cpu(fe->i_dyn_features);
-
 		fe->i_dyn_features = cpu_to_le16(feat | OCFS2_INLINE_DATA_FL);
 
 		fe->id2.i_data.id_count = cpu_to_le16(
@@ -608,9 +625,9 @@
 	int err;
 	struct buffer_head *fe_bh = NULL;
 	struct buffer_head *parent_fe_bh = NULL;
-	struct buffer_head *de_bh = NULL;
 	struct ocfs2_dinode *fe = NULL;
 	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
+	struct ocfs2_dir_lookup_result lookup = { NULL, };
 
 	mlog_entry("(inode=%lu, old='%.*s' new='%.*s')\n", inode->i_ino,
 		   old_dentry->d_name.len, old_dentry->d_name.name,
@@ -638,7 +655,7 @@
 
 	err = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh,
 					   dentry->d_name.name,
-					   dentry->d_name.len, &de_bh);
+					   dentry->d_name.len, &lookup);
 	if (err < 0) {
 		mlog_errno(err);
 		goto out;
@@ -652,7 +669,7 @@
 	}
 
 	fe = (struct ocfs2_dinode *) fe_bh->b_data;
-	if (le16_to_cpu(fe->i_links_count) >= OCFS2_LINK_MAX) {
+	if (ocfs2_read_links_count(fe) >= ocfs2_link_max(osb)) {
 		err = -EMLINK;
 		goto out_unlock_inode;
 	}
@@ -674,13 +691,13 @@
 
 	inc_nlink(inode);
 	inode->i_ctime = CURRENT_TIME;
-	fe->i_links_count = cpu_to_le16(inode->i_nlink);
+	ocfs2_set_links_count(fe, inode->i_nlink);
 	fe->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec);
 	fe->i_ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec);
 
 	err = ocfs2_journal_dirty(handle, fe_bh);
 	if (err < 0) {
-		le16_add_cpu(&fe->i_links_count, -1);
+		ocfs2_add_links_count(fe, -1);
 		drop_nlink(inode);
 		mlog_errno(err);
 		goto out_commit;
@@ -688,9 +705,9 @@
 
 	err = ocfs2_add_entry(handle, dentry, inode,
 			      OCFS2_I(inode)->ip_blkno,
-			      parent_fe_bh, de_bh);
+			      parent_fe_bh, &lookup);
 	if (err) {
-		le16_add_cpu(&fe->i_links_count, -1);
+		ocfs2_add_links_count(fe, -1);
 		drop_nlink(inode);
 		mlog_errno(err);
 		goto out_commit;
@@ -714,10 +731,11 @@
 out:
 	ocfs2_inode_unlock(dir, 1);
 
-	brelse(de_bh);
 	brelse(fe_bh);
 	brelse(parent_fe_bh);
 
+	ocfs2_free_dir_lookup_result(&lookup);
+
 	mlog_exit(err);
 
 	return err;
@@ -766,10 +784,9 @@
 	struct buffer_head *fe_bh = NULL;
 	struct buffer_head *parent_node_bh = NULL;
 	handle_t *handle = NULL;
-	struct ocfs2_dir_entry *dirent = NULL;
-	struct buffer_head *dirent_bh = NULL;
 	char orphan_name[OCFS2_ORPHAN_NAMELEN + 1];
-	struct buffer_head *orphan_entry_bh = NULL;
+	struct ocfs2_dir_lookup_result lookup = { NULL, };
+	struct ocfs2_dir_lookup_result orphan_insert = { NULL, };
 
 	mlog_entry("(0x%p, 0x%p, '%.*s')\n", dir, dentry,
 		   dentry->d_name.len, dentry->d_name.name);
@@ -791,8 +808,8 @@
 	}
 
 	status = ocfs2_find_files_on_disk(dentry->d_name.name,
-					  dentry->d_name.len, &blkno,
-					  dir, &dirent_bh, &dirent);
+					  dentry->d_name.len, &blkno, dir,
+					  &lookup);
 	if (status < 0) {
 		if (status != -ENOENT)
 			mlog_errno(status);
@@ -817,10 +834,7 @@
 	child_locked = 1;
 
 	if (S_ISDIR(inode->i_mode)) {
-	       	if (!ocfs2_empty_dir(inode)) {
-			status = -ENOTEMPTY;
-			goto leave;
-		} else if (inode->i_nlink != 2) {
+		if (inode->i_nlink != 2 || !ocfs2_empty_dir(inode)) {
 			status = -ENOTEMPTY;
 			goto leave;
 		}
@@ -836,8 +850,7 @@
 
 	if (inode_is_unlinkable(inode)) {
 		status = ocfs2_prepare_orphan_dir(osb, &orphan_dir, inode,
-						  orphan_name,
-						  &orphan_entry_bh);
+						  orphan_name, &orphan_insert);
 		if (status < 0) {
 			mlog_errno(status);
 			goto leave;
@@ -863,7 +876,7 @@
 
 	if (inode_is_unlinkable(inode)) {
 		status = ocfs2_orphan_add(osb, handle, inode, fe, orphan_name,
-					  orphan_entry_bh, orphan_dir);
+					  &orphan_insert, orphan_dir);
 		if (status < 0) {
 			mlog_errno(status);
 			goto leave;
@@ -871,7 +884,7 @@
 	}
 
 	/* delete the name from the parent dir */
-	status = ocfs2_delete_entry(handle, dir, dirent, dirent_bh);
+	status = ocfs2_delete_entry(handle, dir, &lookup);
 	if (status < 0) {
 		mlog_errno(status);
 		goto leave;
@@ -880,7 +893,7 @@
 	if (S_ISDIR(inode->i_mode))
 		drop_nlink(inode);
 	drop_nlink(inode);
-	fe->i_links_count = cpu_to_le16(inode->i_nlink);
+	ocfs2_set_links_count(fe, inode->i_nlink);
 
 	status = ocfs2_journal_dirty(handle, fe_bh);
 	if (status < 0) {
@@ -916,9 +929,10 @@
 	}
 
 	brelse(fe_bh);
-	brelse(dirent_bh);
 	brelse(parent_node_bh);
-	brelse(orphan_entry_bh);
+
+	ocfs2_free_dir_lookup_result(&orphan_insert);
+	ocfs2_free_dir_lookup_result(&lookup);
 
 	mlog_exit(status);
 
@@ -1004,8 +1018,8 @@
 			struct inode *new_dir,
 			struct dentry *new_dentry)
 {
-	int status = 0, rename_lock = 0, parents_locked = 0;
-	int old_child_locked = 0, new_child_locked = 0;
+	int status = 0, rename_lock = 0, parents_locked = 0, target_exists = 0;
+	int old_child_locked = 0, new_child_locked = 0, update_dot_dot = 0;
 	struct inode *old_inode = old_dentry->d_inode;
 	struct inode *new_inode = new_dentry->d_inode;
 	struct inode *orphan_dir = NULL;
@@ -1020,13 +1034,13 @@
 	handle_t *handle = NULL;
 	struct buffer_head *old_dir_bh = NULL;
 	struct buffer_head *new_dir_bh = NULL;
-	struct ocfs2_dir_entry *old_inode_dot_dot_de = NULL, *old_de = NULL,
-		*new_de = NULL;
-	struct buffer_head *new_de_bh = NULL, *old_de_bh = NULL; // bhs for above
-	struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir,
-						    // this is the 1st dirent bh
 	nlink_t old_dir_nlink = old_dir->i_nlink;
 	struct ocfs2_dinode *old_di;
+	struct ocfs2_dir_lookup_result old_inode_dot_dot_res = { NULL, };
+	struct ocfs2_dir_lookup_result target_lookup_res = { NULL, };
+	struct ocfs2_dir_lookup_result old_entry_lookup = { NULL, };
+	struct ocfs2_dir_lookup_result orphan_insert = { NULL, };
+	struct ocfs2_dir_lookup_result target_insert = { NULL, };
 
 	/* At some point it might be nice to break this function up a
 	 * bit. */
@@ -1108,9 +1122,10 @@
 	if (S_ISDIR(old_inode->i_mode)) {
 		u64 old_inode_parent;
 
+		update_dot_dot = 1;
 		status = ocfs2_find_files_on_disk("..", 2, &old_inode_parent,
-						  old_inode, &old_inode_de_bh,
-						  &old_inode_dot_dot_de);
+						  old_inode,
+						  &old_inode_dot_dot_res);
 		if (status) {
 			status = -EIO;
 			goto bail;
@@ -1122,7 +1137,7 @@
 		}
 
 		if (!new_inode && new_dir != old_dir &&
-		    new_dir->i_nlink >= OCFS2_LINK_MAX) {
+		    new_dir->i_nlink >= ocfs2_link_max(osb)) {
 			status = -EMLINK;
 			goto bail;
 		}
@@ -1151,8 +1166,8 @@
 	 * to delete it */
 	status = ocfs2_find_files_on_disk(new_dentry->d_name.name,
 					  new_dentry->d_name.len,
-					  &newfe_blkno, new_dir, &new_de_bh,
-					  &new_de);
+					  &newfe_blkno, new_dir,
+					  &target_lookup_res);
 	/* The only error we allow here is -ENOENT because the new
 	 * file not existing is perfectly valid. */
 	if ((status < 0) && (status != -ENOENT)) {
@@ -1161,8 +1176,10 @@
 		mlog_errno(status);
 		goto bail;
 	}
+	if (status == 0)
+		target_exists = 1;
 
-	if (!new_de && new_inode) {
+	if (!target_exists && new_inode) {
 		/*
 		 * Target was unlinked by another node while we were
 		 * waiting to get to ocfs2_rename(). There isn't
@@ -1175,7 +1192,7 @@
 
 	/* In case we need to overwrite an existing file, we blow it
 	 * away first */
-	if (new_de) {
+	if (target_exists) {
 		/* VFS didn't think there existed an inode here, but
 		 * someone else in the cluster must have raced our
 		 * rename to create one. Today we error cleanly, in
@@ -1216,8 +1233,8 @@
 
 		newfe = (struct ocfs2_dinode *) newfe_bh->b_data;
 
-		mlog(0, "aha rename over existing... new_de=%p new_blkno=%llu "
-		     "newfebh=%p bhblocknr=%llu\n", new_de,
+		mlog(0, "aha rename over existing... new_blkno=%llu "
+		     "newfebh=%p bhblocknr=%llu\n",
 		     (unsigned long long)newfe_blkno, newfe_bh, newfe_bh ?
 		     (unsigned long long)newfe_bh->b_blocknr : 0ULL);
 
@@ -1225,7 +1242,7 @@
 			status = ocfs2_prepare_orphan_dir(osb, &orphan_dir,
 							  new_inode,
 							  orphan_name,
-							  &orphan_entry_bh);
+							  &orphan_insert);
 			if (status < 0) {
 				mlog_errno(status);
 				goto bail;
@@ -1243,7 +1260,7 @@
 		status = ocfs2_prepare_dir_for_insert(osb, new_dir, new_dir_bh,
 						      new_dentry->d_name.name,
 						      new_dentry->d_name.len,
-						      &insert_entry_bh);
+						      &target_insert);
 		if (status < 0) {
 			mlog_errno(status);
 			goto bail;
@@ -1258,10 +1275,10 @@
 		goto bail;
 	}
 
-	if (new_de) {
+	if (target_exists) {
 		if (S_ISDIR(new_inode->i_mode)) {
-			if (!ocfs2_empty_dir(new_inode) ||
-			    new_inode->i_nlink != 2) {
+			if (new_inode->i_nlink != 2 ||
+			    !ocfs2_empty_dir(new_inode)) {
 				status = -ENOTEMPTY;
 				goto bail;
 			}
@@ -1274,10 +1291,10 @@
 		}
 
 		if (S_ISDIR(new_inode->i_mode) ||
-		    (newfe->i_links_count == cpu_to_le16(1))){
+		    (ocfs2_read_links_count(newfe) == 1)) {
 			status = ocfs2_orphan_add(osb, handle, new_inode,
 						  newfe, orphan_name,
-						  orphan_entry_bh, orphan_dir);
+						  &orphan_insert, orphan_dir);
 			if (status < 0) {
 				mlog_errno(status);
 				goto bail;
@@ -1285,8 +1302,8 @@
 		}
 
 		/* change the dirent to point to the correct inode */
-		status = ocfs2_update_entry(new_dir, handle, new_de_bh,
-					    new_de, old_inode);
+		status = ocfs2_update_entry(new_dir, handle, &target_lookup_res,
+					    old_inode);
 		if (status < 0) {
 			mlog_errno(status);
 			goto bail;
@@ -1294,9 +1311,9 @@
 		new_dir->i_version++;
 
 		if (S_ISDIR(new_inode->i_mode))
-			newfe->i_links_count = 0;
+			ocfs2_set_links_count(newfe, 0);
 		else
-			le16_add_cpu(&newfe->i_links_count, -1);
+			ocfs2_add_links_count(newfe, -1);
 
 		status = ocfs2_journal_dirty(handle, newfe_bh);
 		if (status < 0) {
@@ -1307,7 +1324,7 @@
 		/* if the name was not found in new_dir, add it now */
 		status = ocfs2_add_entry(handle, new_dentry, old_inode,
 					 OCFS2_I(old_inode)->ip_blkno,
-					 new_dir_bh, insert_entry_bh);
+					 new_dir_bh, &target_insert);
 	}
 
 	old_inode->i_ctime = CURRENT_TIME;
@@ -1334,15 +1351,13 @@
 	 * because the insert might have changed the type of directory
 	 * we're dealing with.
 	 */
-	old_de_bh = ocfs2_find_entry(old_dentry->d_name.name,
-				     old_dentry->d_name.len,
-				     old_dir, &old_de);
-	if (!old_de_bh) {
-		status = -EIO;
+	status = ocfs2_find_entry(old_dentry->d_name.name,
+				  old_dentry->d_name.len, old_dir,
+				  &old_entry_lookup);
+	if (status)
 		goto bail;
-	}
 
-	status = ocfs2_delete_entry(handle, old_dir, old_de, old_de_bh);
+	status = ocfs2_delete_entry(handle, old_dir, &old_entry_lookup);
 	if (status < 0) {
 		mlog_errno(status);
 		goto bail;
@@ -1353,9 +1368,10 @@
 		new_inode->i_ctime = CURRENT_TIME;
 	}
 	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
-	if (old_inode_de_bh) {
-		status = ocfs2_update_entry(old_inode, handle, old_inode_de_bh,
-					    old_inode_dot_dot_de, new_dir);
+
+	if (update_dot_dot) {
+		status = ocfs2_update_entry(old_inode, handle,
+					    &old_inode_dot_dot_res, new_dir);
 		old_dir->i_nlink--;
 		if (new_inode) {
 			new_inode->i_nlink--;
@@ -1391,14 +1407,13 @@
 		} else {
 			struct ocfs2_dinode *fe;
 			status = ocfs2_journal_access_di(handle, old_dir,
-							 old_dir_bh,
-							 OCFS2_JOURNAL_ACCESS_WRITE);
+						      old_dir_bh,
+						      OCFS2_JOURNAL_ACCESS_WRITE);
 			fe = (struct ocfs2_dinode *) old_dir_bh->b_data;
-			fe->i_links_count = cpu_to_le16(old_dir->i_nlink);
+			ocfs2_set_links_count(fe, old_dir->i_nlink);
 			status = ocfs2_journal_dirty(handle, old_dir_bh);
 		}
 	}
-
 	ocfs2_dentry_move(old_dentry, new_dentry, old_dir, new_dir);
 	status = 0;
 bail:
@@ -1429,13 +1444,17 @@
 
 	if (new_inode)
 		iput(new_inode);
+
+	ocfs2_free_dir_lookup_result(&target_lookup_res);
+	ocfs2_free_dir_lookup_result(&old_entry_lookup);
+	ocfs2_free_dir_lookup_result(&old_inode_dot_dot_res);
+	ocfs2_free_dir_lookup_result(&orphan_insert);
+	ocfs2_free_dir_lookup_result(&target_insert);
+
 	brelse(newfe_bh);
 	brelse(old_inode_bh);
 	brelse(old_dir_bh);
 	brelse(new_dir_bh);
-	brelse(new_de_bh);
-	brelse(old_de_bh);
-	brelse(old_inode_de_bh);
 	brelse(orphan_entry_bh);
 	brelse(insert_entry_bh);
 
@@ -1558,7 +1577,6 @@
 	struct inode *inode = NULL;
 	struct super_block *sb;
 	struct buffer_head *new_fe_bh = NULL;
-	struct buffer_head *de_bh = NULL;
 	struct buffer_head *parent_fe_bh = NULL;
 	struct ocfs2_dinode *fe = NULL;
 	struct ocfs2_dinode *dirfe;
@@ -1572,6 +1590,7 @@
 		.enable = 1,
 	};
 	int did_quota = 0, did_quota_inode = 0;
+	struct ocfs2_dir_lookup_result lookup = { NULL, };
 
 	mlog_entry("(0x%p, 0x%p, symname='%s' actual='%.*s')\n", dir,
 		   dentry, symname, dentry->d_name.len, dentry->d_name.name);
@@ -1592,7 +1611,7 @@
 	}
 
 	dirfe = (struct ocfs2_dinode *) parent_fe_bh->b_data;
-	if (!dirfe->i_links_count) {
+	if (!ocfs2_read_links_count(dirfe)) {
 		/* can't make a file in a deleted directory. */
 		status = -ENOENT;
 		goto bail;
@@ -1605,7 +1624,7 @@
 
 	status = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh,
 					      dentry->d_name.name,
-					      dentry->d_name.len, &de_bh);
+					      dentry->d_name.len, &lookup);
 	if (status < 0) {
 		mlog_errno(status);
 		goto bail;
@@ -1744,7 +1763,7 @@
 
 	status = ocfs2_add_entry(handle, dentry, inode,
 				 le64_to_cpu(fe->i_blkno), parent_fe_bh,
-				 de_bh);
+				 &lookup);
 	if (status < 0) {
 		mlog_errno(status);
 		goto bail;
@@ -1772,9 +1791,9 @@
 
 	brelse(new_fe_bh);
 	brelse(parent_fe_bh);
-	brelse(de_bh);
 	kfree(si.name);
 	kfree(si.value);
+	ocfs2_free_dir_lookup_result(&lookup);
 	if (inode_ac)
 		ocfs2_free_alloc_context(inode_ac);
 	if (data_ac)
@@ -1826,7 +1845,7 @@
 				    struct inode **ret_orphan_dir,
 				    struct inode *inode,
 				    char *name,
-				    struct buffer_head **de_bh)
+				    struct ocfs2_dir_lookup_result *lookup)
 {
 	struct inode *orphan_dir_inode;
 	struct buffer_head *orphan_dir_bh = NULL;
@@ -1857,7 +1876,7 @@
 
 	status = ocfs2_prepare_dir_for_insert(osb, orphan_dir_inode,
 					      orphan_dir_bh, name,
-					      OCFS2_ORPHAN_NAMELEN, de_bh);
+					      OCFS2_ORPHAN_NAMELEN, lookup);
 	if (status < 0) {
 		ocfs2_inode_unlock(orphan_dir_inode, 1);
 
@@ -1884,7 +1903,7 @@
 			    struct inode *inode,
 			    struct ocfs2_dinode *fe,
 			    char *name,
-			    struct buffer_head *de_bh,
+			    struct ocfs2_dir_lookup_result *lookup,
 			    struct inode *orphan_dir_inode)
 {
 	struct buffer_head *orphan_dir_bh = NULL;
@@ -1910,8 +1929,8 @@
 	 * underneath us... */
 	orphan_fe = (struct ocfs2_dinode *) orphan_dir_bh->b_data;
 	if (S_ISDIR(inode->i_mode))
-		le16_add_cpu(&orphan_fe->i_links_count, 1);
-	orphan_dir_inode->i_nlink = le16_to_cpu(orphan_fe->i_links_count);
+		ocfs2_add_links_count(orphan_fe, 1);
+	orphan_dir_inode->i_nlink = ocfs2_read_links_count(orphan_fe);
 
 	status = ocfs2_journal_dirty(handle, orphan_dir_bh);
 	if (status < 0) {
@@ -1922,7 +1941,7 @@
 	status = __ocfs2_add_entry(handle, orphan_dir_inode, name,
 				   OCFS2_ORPHAN_NAMELEN, inode,
 				   OCFS2_I(inode)->ip_blkno,
-				   orphan_dir_bh, de_bh);
+				   orphan_dir_bh, lookup);
 	if (status < 0) {
 		mlog_errno(status);
 		goto leave;
@@ -1955,8 +1974,7 @@
 	char name[OCFS2_ORPHAN_NAMELEN + 1];
 	struct ocfs2_dinode *orphan_fe;
 	int status = 0;
-	struct buffer_head *target_de_bh = NULL;
-	struct ocfs2_dir_entry *target_de = NULL;
+	struct ocfs2_dir_lookup_result lookup = { NULL, };
 
 	mlog_entry_void();
 
@@ -1971,17 +1989,15 @@
 	     OCFS2_ORPHAN_NAMELEN);
 
 	/* find it's spot in the orphan directory */
-	target_de_bh = ocfs2_find_entry(name, OCFS2_ORPHAN_NAMELEN,
-					orphan_dir_inode, &target_de);
-	if (!target_de_bh) {
-		status = -ENOENT;
+	status = ocfs2_find_entry(name, OCFS2_ORPHAN_NAMELEN, orphan_dir_inode,
+				  &lookup);
+	if (status) {
 		mlog_errno(status);
 		goto leave;
 	}
 
 	/* remove it from the orphan directory */
-	status = ocfs2_delete_entry(handle, orphan_dir_inode, target_de,
-				    target_de_bh);
+	status = ocfs2_delete_entry(handle, orphan_dir_inode, &lookup);
 	if (status < 0) {
 		mlog_errno(status);
 		goto leave;
@@ -1997,8 +2013,8 @@
 	/* do the i_nlink dance! :) */
 	orphan_fe = (struct ocfs2_dinode *) orphan_dir_bh->b_data;
 	if (S_ISDIR(inode->i_mode))
-		le16_add_cpu(&orphan_fe->i_links_count, -1);
-	orphan_dir_inode->i_nlink = le16_to_cpu(orphan_fe->i_links_count);
+		ocfs2_add_links_count(orphan_fe, -1);
+	orphan_dir_inode->i_nlink = ocfs2_read_links_count(orphan_fe);
 
 	status = ocfs2_journal_dirty(handle, orphan_dir_bh);
 	if (status < 0) {
@@ -2007,7 +2023,7 @@
 	}
 
 leave:
-	brelse(target_de_bh);
+	ocfs2_free_dir_lookup_result(&lookup);
 
 	mlog_exit(status);
 	return status;
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
index 946d3c3..1386281 100644
--- a/fs/ocfs2/ocfs2.h
+++ b/fs/ocfs2/ocfs2.h
@@ -209,6 +209,7 @@
 struct ocfs2_journal;
 struct ocfs2_slot_info;
 struct ocfs2_recovery_map;
+struct ocfs2_replay_map;
 struct ocfs2_quota_recovery;
 struct ocfs2_dentry_lock;
 struct ocfs2_super
@@ -264,6 +265,7 @@
 	atomic_t vol_state;
 	struct mutex recovery_lock;
 	struct ocfs2_recovery_map *recovery_map;
+	struct ocfs2_replay_map *replay_map;
 	struct task_struct *recovery_thread_task;
 	int disable_recovery;
 	wait_queue_head_t checkpoint_event;
@@ -287,11 +289,6 @@
 
 	u64 la_last_gd;
 
-#ifdef CONFIG_OCFS2_FS_STATS
-	struct dentry *local_alloc_debug;
-	char *local_alloc_debug_buf;
-#endif
-
 	/* Next three fields are for local node slot recovery during
 	 * mount. */
 	int dirty;
@@ -305,9 +302,11 @@
 	struct ocfs2_cluster_connection *cconn;
 	struct ocfs2_lock_res osb_super_lockres;
 	struct ocfs2_lock_res osb_rename_lockres;
+	struct ocfs2_lock_res osb_nfs_sync_lockres;
 	struct ocfs2_dlm_debug *osb_dlm_debug;
 
 	struct dentry *osb_debug_root;
+	struct dentry *osb_ctxt;
 
 	wait_queue_head_t recovery_event;
 
@@ -344,6 +343,12 @@
 
 	/* used to protect metaecc calculation check of xattr. */
 	spinlock_t osb_xattr_lock;
+
+	unsigned int			osb_dx_mask;
+	u32				osb_dx_seed[4];
+
+	/* the group we used to allocate inodes. */
+	u64				osb_inode_alloc_group;
 };
 
 #define OCFS2_SB(sb)	    ((struct ocfs2_super *)(sb)->s_fs_info)
@@ -402,6 +407,51 @@
 	return 0;
 }
 
+static inline int ocfs2_supports_indexed_dirs(struct ocfs2_super *osb)
+{
+	if (osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS)
+		return 1;
+	return 0;
+}
+
+static inline unsigned int ocfs2_link_max(struct ocfs2_super *osb)
+{
+	if (ocfs2_supports_indexed_dirs(osb))
+		return OCFS2_DX_LINK_MAX;
+	return OCFS2_LINK_MAX;
+}
+
+static inline unsigned int ocfs2_read_links_count(struct ocfs2_dinode *di)
+{
+	u32 nlink = le16_to_cpu(di->i_links_count);
+	u32 hi = le16_to_cpu(di->i_links_count_hi);
+
+	if (di->i_dyn_features & cpu_to_le16(OCFS2_INDEXED_DIR_FL))
+		nlink |= (hi << OCFS2_LINKS_HI_SHIFT);
+
+	return nlink;
+}
+
+static inline void ocfs2_set_links_count(struct ocfs2_dinode *di, u32 nlink)
+{
+	u16 lo, hi;
+
+	lo = nlink;
+	hi = nlink >> OCFS2_LINKS_HI_SHIFT;
+
+	di->i_links_count = cpu_to_le16(lo);
+	di->i_links_count_hi = cpu_to_le16(hi);
+}
+
+static inline void ocfs2_add_links_count(struct ocfs2_dinode *di, int n)
+{
+	u32 links = ocfs2_read_links_count(di);
+
+	links += n;
+
+	ocfs2_set_links_count(di, links);
+}
+
 /* set / clear functions because cluster events can make these happen
  * in parallel so we want the transitions to be atomic. this also
  * means that any future flags osb_flags must be protected by spinlock
@@ -482,6 +532,12 @@
 #define OCFS2_IS_VALID_DIR_TRAILER(ptr)					\
 	(!strcmp((ptr)->db_signature, OCFS2_DIR_TRAILER_SIGNATURE))
 
+#define OCFS2_IS_VALID_DX_ROOT(ptr)					\
+	(!strcmp((ptr)->dr_signature, OCFS2_DX_ROOT_SIGNATURE))
+
+#define OCFS2_IS_VALID_DX_LEAF(ptr)					\
+	(!strcmp((ptr)->dl_signature, OCFS2_DX_LEAF_SIGNATURE))
+
 static inline unsigned long ino_from_blkno(struct super_block *sb,
 					   u64 blkno)
 {
@@ -532,6 +588,16 @@
 	return (u64)clusters << OCFS2_SB(sb)->s_clustersize_bits;
 }
 
+static inline u64 ocfs2_block_to_cluster_start(struct super_block *sb,
+					       u64 blocks)
+{
+	int bits = OCFS2_SB(sb)->s_clustersize_bits - sb->s_blocksize_bits;
+	unsigned int clusters;
+
+	clusters = ocfs2_blocks_to_clusters(sb, blocks);
+	return (u64)clusters << bits;
+}
+
 static inline u64 ocfs2_align_bytes_to_clusters(struct super_block *sb,
 						u64 bytes)
 {
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h
index 2332ef7..7ab6e9e 100644
--- a/fs/ocfs2/ocfs2_fs.h
+++ b/fs/ocfs2/ocfs2_fs.h
@@ -66,6 +66,8 @@
 #define OCFS2_GROUP_DESC_SIGNATURE      "GROUP01"
 #define OCFS2_XATTR_BLOCK_SIGNATURE	"XATTR01"
 #define OCFS2_DIR_TRAILER_SIGNATURE	"DIRTRL1"
+#define OCFS2_DX_ROOT_SIGNATURE		"DXDIR01"
+#define OCFS2_DX_LEAF_SIGNATURE		"DXLEAF1"
 
 /* Compatibility flags */
 #define OCFS2_HAS_COMPAT_FEATURE(sb,mask)			\
@@ -95,7 +97,8 @@
 					 | OCFS2_FEATURE_INCOMPAT_EXTENDED_SLOT_MAP \
 					 | OCFS2_FEATURE_INCOMPAT_USERSPACE_STACK \
 					 | OCFS2_FEATURE_INCOMPAT_XATTR \
-					 | OCFS2_FEATURE_INCOMPAT_META_ECC)
+					 | OCFS2_FEATURE_INCOMPAT_META_ECC \
+					 | OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS)
 #define OCFS2_FEATURE_RO_COMPAT_SUPP	(OCFS2_FEATURE_RO_COMPAT_UNWRITTEN \
 					 | OCFS2_FEATURE_RO_COMPAT_USRQUOTA \
 					 | OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)
@@ -151,6 +154,9 @@
 /* Support for extended attributes */
 #define OCFS2_FEATURE_INCOMPAT_XATTR		0x0200
 
+/* Support for indexed directores */
+#define OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS	0x0400
+
 /* Metadata checksum and error correction */
 #define OCFS2_FEATURE_INCOMPAT_META_ECC		0x0800
 
@@ -411,8 +417,12 @@
 #define OCFS2_DIR_REC_LEN(name_len)	(((name_len) + OCFS2_DIR_MEMBER_LEN + \
                                           OCFS2_DIR_ROUND) & \
 					 ~OCFS2_DIR_ROUND)
+#define OCFS2_DIR_MIN_REC_LEN	OCFS2_DIR_REC_LEN(1)
 
 #define OCFS2_LINK_MAX		32000
+#define	OCFS2_DX_LINK_MAX	((1U << 31) - 1U)
+#define	OCFS2_LINKS_HI_SHIFT	16
+#define	OCFS2_DX_ENTRIES_MAX	(0xffffffffU)
 
 #define S_SHIFT			12
 static unsigned char ocfs2_type_by_mode[S_IFMT >> S_SHIFT] = {
@@ -628,8 +638,9 @@
 /*B8*/	__le16 s_xattr_inline_size;	/* extended attribute inline size
 					   for this fs*/
 	__le16 s_reserved0;
-	__le32 s_reserved1;
-/*C0*/  __le64 s_reserved2[16];		/* Fill out superblock */
+	__le32 s_dx_seed[3];		/* seed[0-2] for dx dir hash.
+					 * s_uuid_hash serves as seed[3]. */
+/*C0*/  __le64 s_reserved2[15];		/* Fill out superblock */
 /*140*/
 
 	/*
@@ -679,7 +690,7 @@
 					   belongs to */
 	__le16 i_suballoc_bit;		/* Bit offset in suballocator
 					   block group */
-/*10*/	__le16 i_reserved0;
+/*10*/	__le16 i_links_count_hi;	/* High 16 bits of links count */
 	__le16 i_xattr_inline_size;
 	__le32 i_clusters;		/* Cluster count */
 	__le32 i_uid;			/* Owner UID */
@@ -705,7 +716,8 @@
 	__le16 i_dyn_features;
 	__le64 i_xattr_loc;
 /*80*/	struct ocfs2_block_check i_check;	/* Error checking */
-/*88*/	__le64 i_reserved2[6];
+/*88*/	__le64 i_dx_root;		/* Pointer to dir index root block */
+	__le64 i_reserved2[5];
 /*B8*/	union {
 		__le64 i_pad1;		/* Generic way to refer to this
 					   64bit union */
@@ -781,6 +793,90 @@
 /*40*/
 };
 
+ /*
+ * A directory entry in the indexed tree. We don't store the full name here,
+ * but instead provide a pointer to the full dirent in the unindexed tree.
+ *
+ * We also store name_len here so as to reduce the number of leaf blocks we
+ * need to search in case of collisions.
+ */
+struct ocfs2_dx_entry {
+	__le32		dx_major_hash;	/* Used to find logical
+					 * cluster in index */
+	__le32		dx_minor_hash;	/* Lower bits used to find
+					 * block in cluster */
+	__le64		dx_dirent_blk;	/* Physical block in unindexed
+					 * tree holding this dirent. */
+};
+
+struct ocfs2_dx_entry_list {
+	__le32		de_reserved;
+	__le16		de_count;	/* Maximum number of entries
+					 * possible in de_entries */
+	__le16		de_num_used;	/* Current number of
+					 * de_entries entries */
+	struct	ocfs2_dx_entry		de_entries[0];	/* Indexed dir entries
+							 * in a packed array of
+							 * length de_num_used */
+};
+
+#define OCFS2_DX_FLAG_INLINE	0x01
+
+/*
+ * A directory indexing block. Each indexed directory has one of these,
+ * pointed to by ocfs2_dinode.
+ *
+ * This block stores an indexed btree root, and a set of free space
+ * start-of-list pointers.
+ */
+struct ocfs2_dx_root_block {
+	__u8		dr_signature[8];	/* Signature for verification */
+	struct ocfs2_block_check dr_check;	/* Error checking */
+	__le16		dr_suballoc_slot;	/* Slot suballocator this
+						 * block belongs to. */
+	__le16		dr_suballoc_bit;	/* Bit offset in suballocator
+						 * block group */
+	__le32		dr_fs_generation;	/* Must match super block */
+	__le64		dr_blkno;		/* Offset on disk, in blocks */
+	__le64		dr_last_eb_blk;		/* Pointer to last
+						 * extent block */
+	__le32		dr_clusters;		/* Clusters allocated
+						 * to the indexed tree. */
+	__u8		dr_flags;		/* OCFS2_DX_FLAG_* flags */
+	__u8		dr_reserved0;
+	__le16		dr_reserved1;
+	__le64		dr_dir_blkno;		/* Pointer to parent inode */
+	__le32		dr_num_entries;		/* Total number of
+						 * names stored in
+						 * this directory.*/
+	__le32		dr_reserved2;
+	__le64		dr_free_blk;		/* Pointer to head of free
+						 * unindexed block list. */
+	__le64		dr_reserved3[15];
+	union {
+		struct ocfs2_extent_list dr_list; /* Keep this aligned to 128
+						   * bits for maximum space
+						   * efficiency. */
+		struct ocfs2_dx_entry_list dr_entries; /* In-root-block list of
+							* entries. We grow out
+							* to extents if this
+							* gets too big. */
+	};
+};
+
+/*
+ * The header of a leaf block in the indexed tree.
+ */
+struct ocfs2_dx_leaf {
+	__u8		dl_signature[8];/* Signature for verification */
+	struct ocfs2_block_check dl_check;	/* Error checking */
+	__le64		dl_blkno;	/* Offset on disk, in blocks */
+	__le32		dl_fs_generation;/* Must match super block */
+	__le32		dl_reserved0;
+	__le64		dl_reserved1;
+	struct ocfs2_dx_entry_list	dl_list;
+};
+
 /*
  * On disk allocator group structure for OCFS2
  */
@@ -1112,6 +1208,16 @@
 	return size / sizeof(struct ocfs2_extent_rec);
 }
 
+static inline int ocfs2_extent_recs_per_dx_root(struct super_block *sb)
+{
+	int size;
+
+	size = sb->s_blocksize -
+		offsetof(struct ocfs2_dx_root_block, dr_list.l_recs);
+
+	return size / sizeof(struct ocfs2_extent_rec);
+}
+
 static inline int ocfs2_chain_recs_per_inode(struct super_block *sb)
 {
 	int size;
@@ -1132,6 +1238,26 @@
 	return size / sizeof(struct ocfs2_extent_rec);
 }
 
+static inline int ocfs2_dx_entries_per_leaf(struct super_block *sb)
+{
+	int size;
+
+	size = sb->s_blocksize -
+		offsetof(struct ocfs2_dx_leaf, dl_list.de_entries);
+
+	return size / sizeof(struct ocfs2_dx_entry);
+}
+
+static inline int ocfs2_dx_entries_per_root(struct super_block *sb)
+{
+	int size;
+
+	size = sb->s_blocksize -
+		offsetof(struct ocfs2_dx_root_block, dr_entries.de_entries);
+
+	return size / sizeof(struct ocfs2_dx_entry);
+}
+
 static inline u16 ocfs2_local_alloc_size(struct super_block *sb)
 {
 	u16 size;
diff --git a/fs/ocfs2/ocfs2_lockid.h b/fs/ocfs2/ocfs2_lockid.h
index eb6f50c..a53ce87 100644
--- a/fs/ocfs2/ocfs2_lockid.h
+++ b/fs/ocfs2/ocfs2_lockid.h
@@ -47,6 +47,7 @@
 	OCFS2_LOCK_TYPE_OPEN,
 	OCFS2_LOCK_TYPE_FLOCK,
 	OCFS2_LOCK_TYPE_QINFO,
+	OCFS2_LOCK_TYPE_NFS_SYNC,
 	OCFS2_NUM_LOCK_TYPES
 };
 
@@ -81,6 +82,9 @@
 		case OCFS2_LOCK_TYPE_QINFO:
 			c = 'Q';
 			break;
+		case OCFS2_LOCK_TYPE_NFS_SYNC:
+			c = 'Y';
+			break;
 		default:
 			c = '\0';
 	}
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c
index a696286..b4ca591 100644
--- a/fs/ocfs2/suballoc.c
+++ b/fs/ocfs2/suballoc.c
@@ -48,7 +48,8 @@
 #include "buffer_head_io.h"
 
 #define NOT_ALLOC_NEW_GROUP		0
-#define ALLOC_NEW_GROUP			1
+#define ALLOC_NEW_GROUP			0x1
+#define ALLOC_GROUPS_FROM_GLOBAL	0x2
 
 #define OCFS2_MAX_INODES_TO_STEAL	1024
 
@@ -64,7 +65,9 @@
 static int ocfs2_block_group_alloc(struct ocfs2_super *osb,
 				   struct inode *alloc_inode,
 				   struct buffer_head *bh,
-				   u64 max_block);
+				   u64 max_block,
+				   u64 *last_alloc_group,
+				   int flags);
 
 static int ocfs2_cluster_group_search(struct inode *inode,
 				      struct buffer_head *group_bh,
@@ -116,6 +119,7 @@
 						u16 *bg_bit_off);
 static int ocfs2_reserve_clusters_with_limit(struct ocfs2_super *osb,
 					     u32 bits_wanted, u64 max_block,
+					     int flags,
 					     struct ocfs2_alloc_context **ac);
 
 void ocfs2_free_ac_resource(struct ocfs2_alloc_context *ac)
@@ -403,7 +407,9 @@
 static int ocfs2_block_group_alloc(struct ocfs2_super *osb,
 				   struct inode *alloc_inode,
 				   struct buffer_head *bh,
-				   u64 max_block)
+				   u64 max_block,
+				   u64 *last_alloc_group,
+				   int flags)
 {
 	int status, credits;
 	struct ocfs2_dinode *fe = (struct ocfs2_dinode *) bh->b_data;
@@ -423,7 +429,7 @@
 	cl = &fe->id2.i_chain;
 	status = ocfs2_reserve_clusters_with_limit(osb,
 						   le16_to_cpu(cl->cl_cpg),
-						   max_block, &ac);
+						   max_block, flags, &ac);
 	if (status < 0) {
 		if (status != -ENOSPC)
 			mlog_errno(status);
@@ -440,6 +446,11 @@
 		goto bail;
 	}
 
+	if (last_alloc_group && *last_alloc_group != 0) {
+		mlog(0, "use old allocation group %llu for block group alloc\n",
+		     (unsigned long long)*last_alloc_group);
+		ac->ac_last_group = *last_alloc_group;
+	}
 	status = ocfs2_claim_clusters(osb,
 				      handle,
 				      ac,
@@ -514,6 +525,11 @@
 	alloc_inode->i_blocks = ocfs2_inode_sector_count(alloc_inode);
 
 	status = 0;
+
+	/* save the new last alloc group so that the caller can cache it. */
+	if (last_alloc_group)
+		*last_alloc_group = ac->ac_last_group;
+
 bail:
 	if (handle)
 		ocfs2_commit_trans(osb, handle);
@@ -531,7 +547,8 @@
 				       struct ocfs2_alloc_context *ac,
 				       int type,
 				       u32 slot,
-				       int alloc_new_group)
+				       u64 *last_alloc_group,
+				       int flags)
 {
 	int status;
 	u32 bits_wanted = ac->ac_bits_wanted;
@@ -587,7 +604,7 @@
 			goto bail;
 		}
 
-		if (alloc_new_group != ALLOC_NEW_GROUP) {
+		if (!(flags & ALLOC_NEW_GROUP)) {
 			mlog(0, "Alloc File %u Full: wanted=%u, free_bits=%u, "
 			     "and we don't alloc a new group for it.\n",
 			     slot, bits_wanted, free_bits);
@@ -596,7 +613,8 @@
 		}
 
 		status = ocfs2_block_group_alloc(osb, alloc_inode, bh,
-						 ac->ac_max_block);
+						 ac->ac_max_block,
+						 last_alloc_group, flags);
 		if (status < 0) {
 			if (status != -ENOSPC)
 				mlog_errno(status);
@@ -640,7 +658,7 @@
 
 	status = ocfs2_reserve_suballoc_bits(osb, (*ac),
 					     EXTENT_ALLOC_SYSTEM_INODE,
-					     slot, ALLOC_NEW_GROUP);
+					     slot, NULL, ALLOC_NEW_GROUP);
 	if (status < 0) {
 		if (status != -ENOSPC)
 			mlog_errno(status);
@@ -686,7 +704,8 @@
 
 		status = ocfs2_reserve_suballoc_bits(osb, ac,
 						     INODE_ALLOC_SYSTEM_INODE,
-						     slot, NOT_ALLOC_NEW_GROUP);
+						     slot, NULL,
+						     NOT_ALLOC_NEW_GROUP);
 		if (status >= 0) {
 			ocfs2_set_inode_steal_slot(osb, slot);
 			break;
@@ -703,6 +722,7 @@
 {
 	int status;
 	s16 slot = ocfs2_get_inode_steal_slot(osb);
+	u64 alloc_group;
 
 	*ac = kzalloc(sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
 	if (!(*ac)) {
@@ -738,12 +758,22 @@
 		goto inode_steal;
 
 	atomic_set(&osb->s_num_inodes_stolen, 0);
+	alloc_group = osb->osb_inode_alloc_group;
 	status = ocfs2_reserve_suballoc_bits(osb, *ac,
 					     INODE_ALLOC_SYSTEM_INODE,
-					     osb->slot_num, ALLOC_NEW_GROUP);
+					     osb->slot_num,
+					     &alloc_group,
+					     ALLOC_NEW_GROUP |
+					     ALLOC_GROUPS_FROM_GLOBAL);
 	if (status >= 0) {
 		status = 0;
 
+		spin_lock(&osb->osb_lock);
+		osb->osb_inode_alloc_group = alloc_group;
+		spin_unlock(&osb->osb_lock);
+		mlog(0, "after reservation, new allocation group is "
+		     "%llu\n", (unsigned long long)alloc_group);
+
 		/*
 		 * Some inodes must be freed by us, so try to allocate
 		 * from our own next time.
@@ -790,7 +820,7 @@
 
 	status = ocfs2_reserve_suballoc_bits(osb, ac,
 					     GLOBAL_BITMAP_SYSTEM_INODE,
-					     OCFS2_INVALID_SLOT,
+					     OCFS2_INVALID_SLOT, NULL,
 					     ALLOC_NEW_GROUP);
 	if (status < 0 && status != -ENOSPC) {
 		mlog_errno(status);
@@ -806,6 +836,7 @@
  * things a bit. */
 static int ocfs2_reserve_clusters_with_limit(struct ocfs2_super *osb,
 					     u32 bits_wanted, u64 max_block,
+					     int flags,
 					     struct ocfs2_alloc_context **ac)
 {
 	int status;
@@ -823,7 +854,8 @@
 	(*ac)->ac_max_block = max_block;
 
 	status = -ENOSPC;
-	if (ocfs2_alloc_should_use_local(osb, bits_wanted)) {
+	if (!(flags & ALLOC_GROUPS_FROM_GLOBAL) &&
+	    ocfs2_alloc_should_use_local(osb, bits_wanted)) {
 		status = ocfs2_reserve_local_alloc_bits(osb,
 							bits_wanted,
 							*ac);
@@ -861,7 +893,8 @@
 			   u32 bits_wanted,
 			   struct ocfs2_alloc_context **ac)
 {
-	return ocfs2_reserve_clusters_with_limit(osb, bits_wanted, 0, ac);
+	return ocfs2_reserve_clusters_with_limit(osb, bits_wanted, 0,
+						 ALLOC_NEW_GROUP, ac);
 }
 
 /*
@@ -1618,8 +1651,41 @@
 	return status;
 }
 
+static void ocfs2_init_inode_ac_group(struct inode *dir,
+				      struct buffer_head *parent_fe_bh,
+				      struct ocfs2_alloc_context *ac)
+{
+	struct ocfs2_dinode *fe = (struct ocfs2_dinode *)parent_fe_bh->b_data;
+	/*
+	 * Try to allocate inodes from some specific group.
+	 *
+	 * If the parent dir has recorded the last group used in allocation,
+	 * cool, use it. Otherwise if we try to allocate new inode from the
+	 * same slot the parent dir belongs to, use the same chunk.
+	 *
+	 * We are very careful here to avoid the mistake of setting
+	 * ac_last_group to a group descriptor from a different (unlocked) slot.
+	 */
+	if (OCFS2_I(dir)->ip_last_used_group &&
+	    OCFS2_I(dir)->ip_last_used_slot == ac->ac_alloc_slot)
+		ac->ac_last_group = OCFS2_I(dir)->ip_last_used_group;
+	else if (le16_to_cpu(fe->i_suballoc_slot) == ac->ac_alloc_slot)
+		ac->ac_last_group = ocfs2_which_suballoc_group(
+					le64_to_cpu(fe->i_blkno),
+					le16_to_cpu(fe->i_suballoc_bit));
+}
+
+static inline void ocfs2_save_inode_ac_group(struct inode *dir,
+					     struct ocfs2_alloc_context *ac)
+{
+	OCFS2_I(dir)->ip_last_used_group = ac->ac_last_group;
+	OCFS2_I(dir)->ip_last_used_slot = ac->ac_alloc_slot;
+}
+
 int ocfs2_claim_new_inode(struct ocfs2_super *osb,
 			  handle_t *handle,
+			  struct inode *dir,
+			  struct buffer_head *parent_fe_bh,
 			  struct ocfs2_alloc_context *ac,
 			  u16 *suballoc_bit,
 			  u64 *fe_blkno)
@@ -1635,6 +1701,8 @@
 	BUG_ON(ac->ac_bits_wanted != 1);
 	BUG_ON(ac->ac_which != OCFS2_AC_USE_INODE);
 
+	ocfs2_init_inode_ac_group(dir, parent_fe_bh, ac);
+
 	status = ocfs2_claim_suballoc_bits(osb,
 					   ac,
 					   handle,
@@ -1653,6 +1721,7 @@
 
 	*fe_blkno = bg_blkno + (u64) (*suballoc_bit);
 	ac->ac_bits_given++;
+	ocfs2_save_inode_ac_group(dir, ac);
 	status = 0;
 bail:
 	mlog_exit(status);
@@ -2116,3 +2185,162 @@
 
 	return ret;
 }
+
+/*
+ * Read the inode specified by blkno to get suballoc_slot and
+ * suballoc_bit.
+ */
+static int ocfs2_get_suballoc_slot_bit(struct ocfs2_super *osb, u64 blkno,
+				       u16 *suballoc_slot, u16 *suballoc_bit)
+{
+	int status;
+	struct buffer_head *inode_bh = NULL;
+	struct ocfs2_dinode *inode_fe;
+
+	mlog_entry("blkno: %llu\n", blkno);
+
+	/* dirty read disk */
+	status = ocfs2_read_blocks_sync(osb, blkno, 1, &inode_bh);
+	if (status < 0) {
+		mlog(ML_ERROR, "read block %llu failed %d\n", blkno, status);
+		goto bail;
+	}
+
+	inode_fe = (struct ocfs2_dinode *) inode_bh->b_data;
+	if (!OCFS2_IS_VALID_DINODE(inode_fe)) {
+		mlog(ML_ERROR, "invalid inode %llu requested\n", blkno);
+		status = -EINVAL;
+		goto bail;
+	}
+
+	if (le16_to_cpu(inode_fe->i_suballoc_slot) != OCFS2_INVALID_SLOT &&
+	    (u32)le16_to_cpu(inode_fe->i_suballoc_slot) > osb->max_slots - 1) {
+		mlog(ML_ERROR, "inode %llu has invalid suballoc slot %u\n",
+		     blkno, (u32)le16_to_cpu(inode_fe->i_suballoc_slot));
+		status = -EINVAL;
+		goto bail;
+	}
+
+	if (suballoc_slot)
+		*suballoc_slot = le16_to_cpu(inode_fe->i_suballoc_slot);
+	if (suballoc_bit)
+		*suballoc_bit = le16_to_cpu(inode_fe->i_suballoc_bit);
+
+bail:
+	brelse(inode_bh);
+
+	mlog_exit(status);
+	return status;
+}
+
+/*
+ * test whether bit is SET in allocator bitmap or not.  on success, 0
+ * is returned and *res is 1 for SET; 0 otherwise.  when fails, errno
+ * is returned and *res is meaningless.  Call this after you have
+ * cluster locked against suballoc, or you may get a result based on
+ * non-up2date contents
+ */
+static int ocfs2_test_suballoc_bit(struct ocfs2_super *osb,
+				   struct inode *suballoc,
+				   struct buffer_head *alloc_bh, u64 blkno,
+				   u16 bit, int *res)
+{
+	struct ocfs2_dinode *alloc_fe;
+	struct ocfs2_group_desc *group;
+	struct buffer_head *group_bh = NULL;
+	u64 bg_blkno;
+	int status;
+
+	mlog_entry("blkno: %llu bit: %u\n", blkno, (unsigned int)bit);
+
+	alloc_fe = (struct ocfs2_dinode *)alloc_bh->b_data;
+	if ((bit + 1) > ocfs2_bits_per_group(&alloc_fe->id2.i_chain)) {
+		mlog(ML_ERROR, "suballoc bit %u out of range of %u\n",
+		     (unsigned int)bit,
+		     ocfs2_bits_per_group(&alloc_fe->id2.i_chain));
+		status = -EINVAL;
+		goto bail;
+	}
+
+	bg_blkno = ocfs2_which_suballoc_group(blkno, bit);
+	status = ocfs2_read_group_descriptor(suballoc, alloc_fe, bg_blkno,
+					     &group_bh);
+	if (status < 0) {
+		mlog(ML_ERROR, "read group %llu failed %d\n", bg_blkno, status);
+		goto bail;
+	}
+
+	group = (struct ocfs2_group_desc *) group_bh->b_data;
+	*res = ocfs2_test_bit(bit, (unsigned long *)group->bg_bitmap);
+
+bail:
+	brelse(group_bh);
+
+	mlog_exit(status);
+	return status;
+}
+
+/*
+ * Test if the bit representing this inode (blkno) is set in the
+ * suballocator.
+ *
+ * On success, 0 is returned and *res is 1 for SET; 0 otherwise.
+ *
+ * In the event of failure, a negative value is returned and *res is
+ * meaningless.
+ *
+ * Callers must make sure to hold nfs_sync_lock to prevent
+ * ocfs2_delete_inode() on another node from accessing the same
+ * suballocator concurrently.
+ */
+int ocfs2_test_inode_bit(struct ocfs2_super *osb, u64 blkno, int *res)
+{
+	int status;
+	u16 suballoc_bit = 0, suballoc_slot = 0;
+	struct inode *inode_alloc_inode;
+	struct buffer_head *alloc_bh = NULL;
+
+	mlog_entry("blkno: %llu", blkno);
+
+	status = ocfs2_get_suballoc_slot_bit(osb, blkno, &suballoc_slot,
+					     &suballoc_bit);
+	if (status < 0) {
+		mlog(ML_ERROR, "get alloc slot and bit failed %d\n", status);
+		goto bail;
+	}
+
+	inode_alloc_inode =
+		ocfs2_get_system_file_inode(osb, INODE_ALLOC_SYSTEM_INODE,
+					    suballoc_slot);
+	if (!inode_alloc_inode) {
+		/* the error code could be inaccurate, but we are not able to
+		 * get the correct one. */
+		status = -EINVAL;
+		mlog(ML_ERROR, "unable to get alloc inode in slot %u\n",
+		     (u32)suballoc_slot);
+		goto bail;
+	}
+
+	mutex_lock(&inode_alloc_inode->i_mutex);
+	status = ocfs2_inode_lock(inode_alloc_inode, &alloc_bh, 0);
+	if (status < 0) {
+		mutex_unlock(&inode_alloc_inode->i_mutex);
+		mlog(ML_ERROR, "lock on alloc inode on slot %u failed %d\n",
+		     (u32)suballoc_slot, status);
+		goto bail;
+	}
+
+	status = ocfs2_test_suballoc_bit(osb, inode_alloc_inode, alloc_bh,
+					 blkno, suballoc_bit, res);
+	if (status < 0)
+		mlog(ML_ERROR, "test suballoc bit failed %d\n", status);
+
+	ocfs2_inode_unlock(inode_alloc_inode, 0);
+	mutex_unlock(&inode_alloc_inode->i_mutex);
+
+	iput(inode_alloc_inode);
+	brelse(alloc_bh);
+bail:
+	mlog_exit(status);
+	return status;
+}
diff --git a/fs/ocfs2/suballoc.h b/fs/ocfs2/suballoc.h
index e3c13c7..8c9a78a 100644
--- a/fs/ocfs2/suballoc.h
+++ b/fs/ocfs2/suballoc.h
@@ -88,6 +88,8 @@
 			 u64 *blkno_start);
 int ocfs2_claim_new_inode(struct ocfs2_super *osb,
 			  handle_t *handle,
+			  struct inode *dir,
+			  struct buffer_head *parent_fe_bh,
 			  struct ocfs2_alloc_context *ac,
 			  u16 *suballoc_bit,
 			  u64 *fe_blkno);
@@ -186,4 +188,6 @@
 			  u32 clusters_to_add, u32 extents_to_split,
 			  struct ocfs2_alloc_context **data_ac,
 			  struct ocfs2_alloc_context **meta_ac);
+
+int ocfs2_test_inode_bit(struct ocfs2_super *osb, u64 blkno, int *res);
 #endif /* _CHAINALLOC_H_ */
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 7ac83a8..79ff8d9 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -201,6 +201,170 @@
 	{Opt_err, NULL}
 };
 
+#ifdef CONFIG_DEBUG_FS
+static int ocfs2_osb_dump(struct ocfs2_super *osb, char *buf, int len)
+{
+	int out = 0;
+	int i;
+	struct ocfs2_cluster_connection *cconn = osb->cconn;
+	struct ocfs2_recovery_map *rm = osb->recovery_map;
+
+	out += snprintf(buf + out, len - out,
+			"%10s => Id: %-s  Uuid: %-s  Gen: 0x%X  Label: %-s\n",
+			"Device", osb->dev_str, osb->uuid_str,
+			osb->fs_generation, osb->vol_label);
+
+	out += snprintf(buf + out, len - out,
+			"%10s => State: %d  Flags: 0x%lX\n", "Volume",
+			atomic_read(&osb->vol_state), osb->osb_flags);
+
+	out += snprintf(buf + out, len - out,
+			"%10s => Block: %lu  Cluster: %d\n", "Sizes",
+			osb->sb->s_blocksize, osb->s_clustersize);
+
+	out += snprintf(buf + out, len - out,
+			"%10s => Compat: 0x%X  Incompat: 0x%X  "
+			"ROcompat: 0x%X\n",
+			"Features", osb->s_feature_compat,
+			osb->s_feature_incompat, osb->s_feature_ro_compat);
+
+	out += snprintf(buf + out, len - out,
+			"%10s => Opts: 0x%lX  AtimeQuanta: %u\n", "Mount",
+			osb->s_mount_opt, osb->s_atime_quantum);
+
+	out += snprintf(buf + out, len - out,
+			"%10s => Stack: %s  Name: %*s  Version: %d.%d\n",
+			"Cluster",
+			(*osb->osb_cluster_stack == '\0' ?
+			 "o2cb" : osb->osb_cluster_stack),
+			cconn->cc_namelen, cconn->cc_name,
+			cconn->cc_version.pv_major, cconn->cc_version.pv_minor);
+
+	spin_lock(&osb->dc_task_lock);
+	out += snprintf(buf + out, len - out,
+			"%10s => Pid: %d  Count: %lu  WakeSeq: %lu  "
+			"WorkSeq: %lu\n", "DownCnvt",
+			task_pid_nr(osb->dc_task), osb->blocked_lock_count,
+			osb->dc_wake_sequence, osb->dc_work_sequence);
+	spin_unlock(&osb->dc_task_lock);
+
+	spin_lock(&osb->osb_lock);
+	out += snprintf(buf + out, len - out, "%10s => Pid: %d  Nodes:",
+			"Recovery",
+			(osb->recovery_thread_task ?
+			 task_pid_nr(osb->recovery_thread_task) : -1));
+	if (rm->rm_used == 0)
+		out += snprintf(buf + out, len - out, " None\n");
+	else {
+		for (i = 0; i < rm->rm_used; i++)
+			out += snprintf(buf + out, len - out, " %d",
+					rm->rm_entries[i]);
+		out += snprintf(buf + out, len - out, "\n");
+	}
+	spin_unlock(&osb->osb_lock);
+
+	out += snprintf(buf + out, len - out,
+			"%10s => Pid: %d  Interval: %lu  Needs: %d\n", "Commit",
+			task_pid_nr(osb->commit_task), osb->osb_commit_interval,
+			atomic_read(&osb->needs_checkpoint));
+
+	out += snprintf(buf + out, len - out,
+			"%10s => State: %d  NumTxns: %d  TxnId: %lu\n",
+			"Journal", osb->journal->j_state,
+			atomic_read(&osb->journal->j_num_trans),
+			osb->journal->j_trans_id);
+
+	out += snprintf(buf + out, len - out,
+			"%10s => GlobalAllocs: %d  LocalAllocs: %d  "
+			"SubAllocs: %d  LAWinMoves: %d  SAExtends: %d\n",
+			"Stats",
+			atomic_read(&osb->alloc_stats.bitmap_data),
+			atomic_read(&osb->alloc_stats.local_data),
+			atomic_read(&osb->alloc_stats.bg_allocs),
+			atomic_read(&osb->alloc_stats.moves),
+			atomic_read(&osb->alloc_stats.bg_extends));
+
+	out += snprintf(buf + out, len - out,
+			"%10s => State: %u  Descriptor: %llu  Size: %u bits  "
+			"Default: %u bits\n",
+			"LocalAlloc", osb->local_alloc_state,
+			(unsigned long long)osb->la_last_gd,
+			osb->local_alloc_bits, osb->local_alloc_default_bits);
+
+	spin_lock(&osb->osb_lock);
+	out += snprintf(buf + out, len - out,
+			"%10s => Slot: %d  NumStolen: %d\n", "Steal",
+			osb->s_inode_steal_slot,
+			atomic_read(&osb->s_num_inodes_stolen));
+	spin_unlock(&osb->osb_lock);
+
+	out += snprintf(buf + out, len - out, "%10s => %3s  %10s\n",
+			"Slots", "Num", "RecoGen");
+
+	for (i = 0; i < osb->max_slots; ++i) {
+		out += snprintf(buf + out, len - out,
+				"%10s  %c %3d  %10d\n",
+				" ",
+				(i == osb->slot_num ? '*' : ' '),
+				i, osb->slot_recovery_generations[i]);
+	}
+
+	return out;
+}
+
+static int ocfs2_osb_debug_open(struct inode *inode, struct file *file)
+{
+	struct ocfs2_super *osb = inode->i_private;
+	char *buf = NULL;
+
+	buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!buf)
+		goto bail;
+
+	i_size_write(inode, ocfs2_osb_dump(osb, buf, PAGE_SIZE));
+
+	file->private_data = buf;
+
+	return 0;
+bail:
+	return -ENOMEM;
+}
+
+static int ocfs2_debug_release(struct inode *inode, struct file *file)
+{
+	kfree(file->private_data);
+	return 0;
+}
+
+static ssize_t ocfs2_debug_read(struct file *file, char __user *buf,
+				size_t nbytes, loff_t *ppos)
+{
+	return simple_read_from_buffer(buf, nbytes, ppos, file->private_data,
+				       i_size_read(file->f_mapping->host));
+}
+#else
+static int ocfs2_osb_debug_open(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+static int ocfs2_debug_release(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+static ssize_t ocfs2_debug_read(struct file *file, char __user *buf,
+				size_t nbytes, loff_t *ppos)
+{
+	return 0;
+}
+#endif	/* CONFIG_DEBUG_FS */
+
+static struct file_operations ocfs2_osb_debug_fops = {
+	.open =		ocfs2_osb_debug_open,
+	.release =	ocfs2_debug_release,
+	.read =		ocfs2_debug_read,
+	.llseek =	generic_file_llseek,
+};
+
 /*
  * write_super and sync_fs ripped right out of ext3.
  */
@@ -926,6 +1090,16 @@
 		goto read_super_error;
 	}
 
+	osb->osb_ctxt = debugfs_create_file("fs_state", S_IFREG|S_IRUSR,
+					    osb->osb_debug_root,
+					    osb,
+					    &ocfs2_osb_debug_fops);
+	if (!osb->osb_ctxt) {
+		status = -EINVAL;
+		mlog_errno(status);
+		goto read_super_error;
+	}
+
 	status = ocfs2_mount_volume(sb);
 	if (osb->root_inode)
 		inode = igrab(osb->root_inode);
@@ -1620,6 +1794,8 @@
 	osb = OCFS2_SB(sb);
 	BUG_ON(!osb);
 
+	debugfs_remove(osb->osb_ctxt);
+
 	ocfs2_disable_quotas(osb);
 
 	ocfs2_shutdown_local_alloc(osb);
@@ -1742,6 +1918,12 @@
 	bbits = le32_to_cpu(di->id2.i_super.s_blocksize_bits);
 	sb->s_maxbytes = ocfs2_max_file_offset(bbits, cbits);
 
+	osb->osb_dx_mask = (1 << (cbits - bbits)) - 1;
+
+	for (i = 0; i < 3; i++)
+		osb->osb_dx_seed[i] = le32_to_cpu(di->id2.i_super.s_dx_seed[i]);
+	osb->osb_dx_seed[3] = le32_to_cpu(di->id2.i_super.s_uuid_hash);
+
 	osb->sb = sb;
 	/* Save off for ocfs2_rw_direct */
 	osb->s_sectsize_bits = blksize_bits(sector_size);
@@ -2130,6 +2312,12 @@
 	 * lock, and it's marked as dirty, set the bit in the recover
 	 * map and launch a recovery thread for it. */
 	status = ocfs2_mark_dead_nodes(osb);
+	if (status < 0) {
+		mlog_errno(status);
+		goto finally;
+	}
+
+	status = ocfs2_compute_replay_slots(osb);
 	if (status < 0)
 		mlog_errno(status);
 
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 2563df8..1563101 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -512,7 +512,7 @@
 			  struct ocfs2_security_xattr_info *si,
 			  int *want_clusters,
 			  int *xattr_credits,
-			  struct ocfs2_alloc_context **xattr_ac)
+			  int *want_meta)
 {
 	int ret = 0;
 	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
@@ -554,11 +554,7 @@
 	if (dir->i_sb->s_blocksize == OCFS2_MIN_BLOCKSIZE ||
 	    (S_ISDIR(mode) && ocfs2_supports_inline_data(osb)) ||
 	    (s_size + a_size) > OCFS2_XATTR_FREE_IN_IBODY) {
-		ret = ocfs2_reserve_new_metadata_blocks(osb, 1, xattr_ac);
-		if (ret) {
-			mlog_errno(ret);
-			return ret;
-		}
+		*want_meta = *want_meta + 1;
 		*xattr_credits += OCFS2_XATTR_BLOCK_CREATE_CREDITS;
 	}
 
diff --git a/fs/ocfs2/xattr.h b/fs/ocfs2/xattr.h
index 5a1ebc7..1ca7e9a 100644
--- a/fs/ocfs2/xattr.h
+++ b/fs/ocfs2/xattr.h
@@ -68,7 +68,7 @@
 			     int *, int *, struct ocfs2_alloc_context **);
 int ocfs2_calc_xattr_init(struct inode *, struct buffer_head *,
 			  int, struct ocfs2_security_xattr_info *,
-			  int *, int *, struct ocfs2_alloc_context **);
+			  int *, int *, int *);
 
 /*
  * xattrs can live inside an inode, as part of an external xattr block,
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 38e337d..99e33ef 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -19,6 +19,7 @@
 #include <linux/kmod.h>
 #include <linux/ctype.h>
 #include <linux/genhd.h>
+#include <linux/blktrace_api.h>
 
 #include "check.h"
 
@@ -294,6 +295,9 @@
 
 static struct attribute_group *part_attr_groups[] = {
 	&part_attr_group,
+#ifdef CONFIG_BLK_DEV_IO_TRACE
+	&blk_trace_attr_group,
+#endif
 	NULL
 };
 
diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c
index b446d7a..7e14d1a 100644
--- a/fs/proc/nommu.c
+++ b/fs/proc/nommu.c
@@ -76,7 +76,7 @@
 
 /*
  * display a list of all the REGIONs the kernel knows about
- * - nommu kernals have a single flat list
+ * - nommu kernels have a single flat list
  */
 static int nommu_region_list_show(struct seq_file *m, void *_p)
 {
diff --git a/fs/read_write.c b/fs/read_write.c
index 6d5d8ff..9d1e76b 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -731,10 +731,16 @@
 	return ret;
 }
 
-SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec,
-		unsigned long, vlen, u32, pos_high, u32, pos_low)
+static inline loff_t pos_from_hilo(unsigned long high, unsigned long low)
 {
-	loff_t pos = ((loff_t)pos_high << 32) | pos_low;
+#define HALF_LONG_BITS (BITS_PER_LONG / 2)
+	return (((loff_t)high << HALF_LONG_BITS) << HALF_LONG_BITS) | low;
+}
+
+SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec,
+		unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h)
+{
+	loff_t pos = pos_from_hilo(pos_h, pos_l);
 	struct file *file;
 	ssize_t ret = -EBADF;
 	int fput_needed;
@@ -757,9 +763,9 @@
 }
 
 SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec,
-		unsigned long, vlen, u32, pos_high, u32, pos_low)
+		unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h)
 {
-	loff_t pos = ((loff_t)pos_high << 32) | pos_low;
+	loff_t pos = pos_from_hilo(pos_h, pos_l);
 	struct file *file;
 	ssize_t ret = -EBADF;
 	int fput_needed;
diff --git a/fs/splice.c b/fs/splice.c
index 4ed0ba4..dd727d4 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -59,7 +59,8 @@
 		 */
 		wait_on_page_writeback(page);
 
-		if (PagePrivate(page) && !try_to_release_page(page, GFP_KERNEL))
+		if (page_has_private(page) &&
+		    !try_to_release_page(page, GFP_KERNEL))
 			goto out_unlock;
 
 		/*
diff --git a/fs/super.c b/fs/super.c
index 2ba4815..77cb4ec 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -287,6 +287,7 @@
 	__fsync_super(sb);
 	return sync_blockdev(sb->s_bdev);
 }
+EXPORT_SYMBOL_GPL(fsync_super);
 
 /**
  *	generic_shutdown_super	-	common helper for ->kill_sb()
diff --git a/fs/ubifs/Kconfig b/fs/ubifs/Kconfig
index e35b54d..830e3f7 100644
--- a/fs/ubifs/Kconfig
+++ b/fs/ubifs/Kconfig
@@ -22,7 +22,7 @@
 	depends on UBIFS_FS
 	help
 	  This option allows to explicitly choose which compressions, if any,
-	  are enabled in UBIFS. Removing compressors means inbility to read
+	  are enabled in UBIFS. Removing compressors means inability to read
 	  existing file systems.
 
 	  If unsure, say 'N'.
@@ -32,7 +32,7 @@
 	depends on UBIFS_FS
 	default y
 	help
-	   LZO compressor is generally faster then zlib but compresses worse.
+	   LZO compressor is generally faster than zlib but compresses worse.
 	   Say 'Y' if unsure.
 
 config UBIFS_FS_ZLIB
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c
index 2bb788a..e48e9a3 100644
--- a/fs/udf/balloc.c
+++ b/fs/udf/balloc.c
@@ -87,12 +87,12 @@
 {
 	struct buffer_head *bh = NULL;
 	int retval = 0;
-	kernel_lb_addr loc;
+	struct kernel_lb_addr loc;
 
 	loc.logicalBlockNum = bitmap->s_extPosition;
 	loc.partitionReferenceNum = UDF_SB(sb)->s_partition;
 
-	bh = udf_tread(sb, udf_get_lb_pblock(sb, loc, block));
+	bh = udf_tread(sb, udf_get_lb_pblock(sb, &loc, block));
 	if (!bh)
 		retval = -EIO;
 
@@ -140,27 +140,29 @@
 	return slot;
 }
 
-static bool udf_add_free_space(struct udf_sb_info *sbi,
-				u16 partition, u32 cnt)
+static void udf_add_free_space(struct super_block *sb, u16 partition, u32 cnt)
 {
+	struct udf_sb_info *sbi = UDF_SB(sb);
 	struct logicalVolIntegrityDesc *lvid;
 
-	if (sbi->s_lvid_bh == NULL)
-		return false;
+	if (!sbi->s_lvid_bh)
+		return;
 
 	lvid = (struct logicalVolIntegrityDesc *)sbi->s_lvid_bh->b_data;
 	le32_add_cpu(&lvid->freeSpaceTable[partition], cnt);
-	return true;
+	udf_updated_lvid(sb);
 }
 
 static void udf_bitmap_free_blocks(struct super_block *sb,
 				   struct inode *inode,
 				   struct udf_bitmap *bitmap,
-				   kernel_lb_addr bloc, uint32_t offset,
+				   struct kernel_lb_addr *bloc,
+				   uint32_t offset,
 				   uint32_t count)
 {
 	struct udf_sb_info *sbi = UDF_SB(sb);
 	struct buffer_head *bh = NULL;
+	struct udf_part_map *partmap;
 	unsigned long block;
 	unsigned long block_group;
 	unsigned long bit;
@@ -169,17 +171,17 @@
 	unsigned long overflow;
 
 	mutex_lock(&sbi->s_alloc_mutex);
-	if (bloc.logicalBlockNum < 0 ||
-	    (bloc.logicalBlockNum + count) >
-		sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
+	partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
+	if (bloc->logicalBlockNum < 0 ||
+	    (bloc->logicalBlockNum + count) >
+		partmap->s_partition_len) {
 		udf_debug("%d < %d || %d + %d > %d\n",
-			  bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
-			  sbi->s_partmaps[bloc.partitionReferenceNum].
-							s_partition_len);
+			  bloc->logicalBlockNum, 0, bloc->logicalBlockNum,
+			  count, partmap->s_partition_len);
 		goto error_return;
 	}
 
-	block = bloc.logicalBlockNum + offset +
+	block = bloc->logicalBlockNum + offset +
 		(sizeof(struct spaceBitmapDesc) << 3);
 
 	do {
@@ -207,7 +209,7 @@
 			} else {
 				if (inode)
 					vfs_dq_free_block(inode, 1);
-				udf_add_free_space(sbi, sbi->s_partition, 1);
+				udf_add_free_space(sb, sbi->s_partition, 1);
 			}
 		}
 		mark_buffer_dirty(bh);
@@ -218,9 +220,6 @@
 	} while (overflow);
 
 error_return:
-	sb->s_dirt = 1;
-	if (sbi->s_lvid_bh)
-		mark_buffer_dirty(sbi->s_lvid_bh);
 	mutex_unlock(&sbi->s_alloc_mutex);
 }
 
@@ -277,9 +276,7 @@
 	} while (block_count > 0);
 
 out:
-	if (udf_add_free_space(sbi, partition, -alloc_count))
-		mark_buffer_dirty(sbi->s_lvid_bh);
-	sb->s_dirt = 1;
+	udf_add_free_space(sb, partition, -alloc_count);
 	mutex_unlock(&sbi->s_alloc_mutex);
 	return alloc_count;
 }
@@ -409,9 +406,7 @@
 
 	mark_buffer_dirty(bh);
 
-	if (udf_add_free_space(sbi, partition, -1))
-		mark_buffer_dirty(sbi->s_lvid_bh);
-	sb->s_dirt = 1;
+	udf_add_free_space(sb, partition, -1);
 	mutex_unlock(&sbi->s_alloc_mutex);
 	*err = 0;
 	return newblock;
@@ -425,26 +420,28 @@
 static void udf_table_free_blocks(struct super_block *sb,
 				  struct inode *inode,
 				  struct inode *table,
-				  kernel_lb_addr bloc, uint32_t offset,
+				  struct kernel_lb_addr *bloc,
+				  uint32_t offset,
 				  uint32_t count)
 {
 	struct udf_sb_info *sbi = UDF_SB(sb);
+	struct udf_part_map *partmap;
 	uint32_t start, end;
 	uint32_t elen;
-	kernel_lb_addr eloc;
+	struct kernel_lb_addr eloc;
 	struct extent_position oepos, epos;
 	int8_t etype;
 	int i;
 	struct udf_inode_info *iinfo;
 
 	mutex_lock(&sbi->s_alloc_mutex);
-	if (bloc.logicalBlockNum < 0 ||
-	    (bloc.logicalBlockNum + count) >
-		sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
+	partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
+	if (bloc->logicalBlockNum < 0 ||
+	    (bloc->logicalBlockNum + count) >
+		partmap->s_partition_len) {
 		udf_debug("%d < %d || %d + %d > %d\n",
 			  bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
-			  sbi->s_partmaps[bloc.partitionReferenceNum].
-							s_partition_len);
+			  partmap->s_partition_len);
 		goto error_return;
 	}
 
@@ -453,11 +450,10 @@
 	   could occure, but.. oh well */
 	if (inode)
 		vfs_dq_free_block(inode, count);
-	if (udf_add_free_space(sbi, sbi->s_partition, count))
-		mark_buffer_dirty(sbi->s_lvid_bh);
+	udf_add_free_space(sb, sbi->s_partition, count);
 
-	start = bloc.logicalBlockNum + offset;
-	end = bloc.logicalBlockNum + offset + count - 1;
+	start = bloc->logicalBlockNum + offset;
+	end = bloc->logicalBlockNum + offset + count - 1;
 
 	epos.offset = oepos.offset = sizeof(struct unallocSpaceEntry);
 	elen = 0;
@@ -483,7 +479,7 @@
 				start += count;
 				count = 0;
 			}
-			udf_write_aext(table, &oepos, eloc, elen, 1);
+			udf_write_aext(table, &oepos, &eloc, elen, 1);
 		} else if (eloc.logicalBlockNum == (end + 1)) {
 			if ((0x3FFFFFFF - elen) <
 					(count << sb->s_blocksize_bits)) {
@@ -502,7 +498,7 @@
 				end -= count;
 				count = 0;
 			}
-			udf_write_aext(table, &oepos, eloc, elen, 1);
+			udf_write_aext(table, &oepos, &eloc, elen, 1);
 		}
 
 		if (epos.bh != oepos.bh) {
@@ -532,8 +528,8 @@
 		 */
 
 		int adsize;
-		short_ad *sad = NULL;
-		long_ad *lad = NULL;
+		struct short_ad *sad = NULL;
+		struct long_ad *lad = NULL;
 		struct allocExtDesc *aed;
 
 		eloc.logicalBlockNum = start;
@@ -541,9 +537,9 @@
 			(count << sb->s_blocksize_bits);
 
 		if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
-			adsize = sizeof(short_ad);
+			adsize = sizeof(struct short_ad);
 		else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
-			adsize = sizeof(long_ad);
+			adsize = sizeof(struct long_ad);
 		else {
 			brelse(oepos.bh);
 			brelse(epos.bh);
@@ -563,7 +559,7 @@
 			elen -= sb->s_blocksize;
 
 			epos.bh = udf_tread(sb,
-					udf_get_lb_pblock(sb, epos.block, 0));
+					udf_get_lb_pblock(sb, &epos.block, 0));
 			if (!epos.bh) {
 				brelse(oepos.bh);
 				goto error_return;
@@ -601,15 +597,15 @@
 			if (sbi->s_udfrev >= 0x0200)
 				udf_new_tag(epos.bh->b_data, TAG_IDENT_AED,
 					    3, 1, epos.block.logicalBlockNum,
-					    sizeof(tag));
+					    sizeof(struct tag));
 			else
 				udf_new_tag(epos.bh->b_data, TAG_IDENT_AED,
 					    2, 1, epos.block.logicalBlockNum,
-					    sizeof(tag));
+					    sizeof(struct tag));
 
 			switch (iinfo->i_alloc_type) {
 			case ICBTAG_FLAG_AD_SHORT:
-				sad = (short_ad *)sptr;
+				sad = (struct short_ad *)sptr;
 				sad->extLength = cpu_to_le32(
 					EXT_NEXT_EXTENT_ALLOCDECS |
 					sb->s_blocksize);
@@ -617,7 +613,7 @@
 					cpu_to_le32(epos.block.logicalBlockNum);
 				break;
 			case ICBTAG_FLAG_AD_LONG:
-				lad = (long_ad *)sptr;
+				lad = (struct long_ad *)sptr;
 				lad->extLength = cpu_to_le32(
 					EXT_NEXT_EXTENT_ALLOCDECS |
 					sb->s_blocksize);
@@ -635,7 +631,7 @@
 
 		/* It's possible that stealing the block emptied the extent */
 		if (elen) {
-			udf_write_aext(table, &epos, eloc, elen, 1);
+			udf_write_aext(table, &epos, &eloc, elen, 1);
 
 			if (!epos.bh) {
 				iinfo->i_lenAlloc += adsize;
@@ -653,7 +649,6 @@
 	brelse(oepos.bh);
 
 error_return:
-	sb->s_dirt = 1;
 	mutex_unlock(&sbi->s_alloc_mutex);
 	return;
 }
@@ -666,7 +661,7 @@
 	struct udf_sb_info *sbi = UDF_SB(sb);
 	int alloc_count = 0;
 	uint32_t elen, adsize;
-	kernel_lb_addr eloc;
+	struct kernel_lb_addr eloc;
 	struct extent_position epos;
 	int8_t etype = -1;
 	struct udf_inode_info *iinfo;
@@ -677,9 +672,9 @@
 
 	iinfo = UDF_I(table);
 	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
-		adsize = sizeof(short_ad);
+		adsize = sizeof(struct short_ad);
 	else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
-		adsize = sizeof(long_ad);
+		adsize = sizeof(struct long_ad);
 	else
 		return 0;
 
@@ -707,7 +702,7 @@
 			alloc_count = block_count;
 			eloc.logicalBlockNum += alloc_count;
 			elen -= (alloc_count << sb->s_blocksize_bits);
-			udf_write_aext(table, &epos, eloc,
+			udf_write_aext(table, &epos, &eloc,
 					(etype << 30) | elen, 1);
 		} else
 			udf_delete_aext(table, epos, eloc,
@@ -718,10 +713,8 @@
 
 	brelse(epos.bh);
 
-	if (alloc_count && udf_add_free_space(sbi, partition, -alloc_count)) {
-		mark_buffer_dirty(sbi->s_lvid_bh);
-		sb->s_dirt = 1;
-	}
+	if (alloc_count)
+		udf_add_free_space(sb, partition, -alloc_count);
 	mutex_unlock(&sbi->s_alloc_mutex);
 	return alloc_count;
 }
@@ -735,7 +728,7 @@
 	uint32_t spread = 0xFFFFFFFF, nspread = 0xFFFFFFFF;
 	uint32_t newblock = 0, adsize;
 	uint32_t elen, goal_elen = 0;
-	kernel_lb_addr eloc, uninitialized_var(goal_eloc);
+	struct kernel_lb_addr eloc, uninitialized_var(goal_eloc);
 	struct extent_position epos, goal_epos;
 	int8_t etype;
 	struct udf_inode_info *iinfo = UDF_I(table);
@@ -743,9 +736,9 @@
 	*err = -ENOSPC;
 
 	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
-		adsize = sizeof(short_ad);
+		adsize = sizeof(struct short_ad);
 	else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
-		adsize = sizeof(long_ad);
+		adsize = sizeof(struct long_ad);
 	else
 		return newblock;
 
@@ -814,46 +807,37 @@
 	}
 
 	if (goal_elen)
-		udf_write_aext(table, &goal_epos, goal_eloc, goal_elen, 1);
+		udf_write_aext(table, &goal_epos, &goal_eloc, goal_elen, 1);
 	else
 		udf_delete_aext(table, goal_epos, goal_eloc, goal_elen);
 	brelse(goal_epos.bh);
 
-	if (udf_add_free_space(sbi, partition, -1))
-		mark_buffer_dirty(sbi->s_lvid_bh);
+	udf_add_free_space(sb, partition, -1);
 
-	sb->s_dirt = 1;
 	mutex_unlock(&sbi->s_alloc_mutex);
 	*err = 0;
 	return newblock;
 }
 
-inline void udf_free_blocks(struct super_block *sb,
-			    struct inode *inode,
-			    kernel_lb_addr bloc, uint32_t offset,
-			    uint32_t count)
+void udf_free_blocks(struct super_block *sb, struct inode *inode,
+		     struct kernel_lb_addr *bloc, uint32_t offset,
+		     uint32_t count)
 {
-	uint16_t partition = bloc.partitionReferenceNum;
+	uint16_t partition = bloc->partitionReferenceNum;
 	struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition];
 
 	if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) {
-		return udf_bitmap_free_blocks(sb, inode,
-					      map->s_uspace.s_bitmap,
-					      bloc, offset, count);
+		udf_bitmap_free_blocks(sb, inode, map->s_uspace.s_bitmap,
+				       bloc, offset, count);
 	} else if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) {
-		return udf_table_free_blocks(sb, inode,
-					     map->s_uspace.s_table,
-					     bloc, offset, count);
+		udf_table_free_blocks(sb, inode, map->s_uspace.s_table,
+				      bloc, offset, count);
 	} else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) {
-		return udf_bitmap_free_blocks(sb, inode,
-					      map->s_fspace.s_bitmap,
-					      bloc, offset, count);
+		udf_bitmap_free_blocks(sb, inode, map->s_fspace.s_bitmap,
+				       bloc, offset, count);
 	} else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) {
-		return udf_table_free_blocks(sb, inode,
-					     map->s_fspace.s_table,
-					     bloc, offset, count);
-	} else {
-		return;
+		udf_table_free_blocks(sb, inode, map->s_fspace.s_table,
+				      bloc, offset, count);
 	}
 }
 
diff --git a/fs/udf/dir.c b/fs/udf/dir.c
index 62dc270..2efd4d5 100644
--- a/fs/udf/dir.c
+++ b/fs/udf/dir.c
@@ -51,7 +51,7 @@
 	uint8_t lfi;
 	loff_t size = udf_ext0_offset(dir) + dir->i_size;
 	struct buffer_head *tmp, *bha[16];
-	kernel_lb_addr eloc;
+	struct kernel_lb_addr eloc;
 	uint32_t elen;
 	sector_t offset;
 	int i, num, ret = 0;
@@ -80,13 +80,13 @@
 			ret = -ENOENT;
 			goto out;
 		}
-		block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
+		block = udf_get_lb_pblock(dir->i_sb, &eloc, offset);
 		if ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
 			if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
-				epos.offset -= sizeof(short_ad);
+				epos.offset -= sizeof(struct short_ad);
 			else if (iinfo->i_alloc_type ==
 					ICBTAG_FLAG_AD_LONG)
-				epos.offset -= sizeof(long_ad);
+				epos.offset -= sizeof(struct long_ad);
 		} else {
 			offset = 0;
 		}
@@ -101,7 +101,7 @@
 			if (i + offset > (elen >> dir->i_sb->s_blocksize_bits))
 				i = (elen >> dir->i_sb->s_blocksize_bits) - offset;
 			for (num = 0; i > 0; i--) {
-				block = udf_get_lb_pblock(dir->i_sb, eloc, offset + i);
+				block = udf_get_lb_pblock(dir->i_sb, &eloc, offset + i);
 				tmp = udf_tgetblk(dir->i_sb, block);
 				if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp))
 					bha[num++] = tmp;
@@ -161,9 +161,9 @@
 			memcpy(fname, "..", flen);
 			dt_type = DT_DIR;
 		} else {
-			kernel_lb_addr tloc = lelb_to_cpu(cfi.icb.extLocation);
+			struct kernel_lb_addr tloc = lelb_to_cpu(cfi.icb.extLocation);
 
-			iblock = udf_get_lb_pblock(dir->i_sb, tloc, 0);
+			iblock = udf_get_lb_pblock(dir->i_sb, &tloc, 0);
 			flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi);
 			dt_type = DT_UNKNOWN;
 		}
diff --git a/fs/udf/directory.c b/fs/udf/directory.c
index 2820f8f..1d2c570 100644
--- a/fs/udf/directory.c
+++ b/fs/udf/directory.c
@@ -20,7 +20,7 @@
 
 #if 0
 static uint8_t *udf_filead_read(struct inode *dir, uint8_t *tmpad,
-				uint8_t ad_size, kernel_lb_addr fe_loc,
+				uint8_t ad_size, struct kernel_lb_addr fe_loc,
 				int *pos, int *offset, struct buffer_head **bh,
 				int *error)
 {
@@ -75,7 +75,7 @@
 					 struct udf_fileident_bh *fibh,
 					 struct fileIdentDesc *cfi,
 					 struct extent_position *epos,
-					 kernel_lb_addr *eloc, uint32_t *elen,
+					 struct kernel_lb_addr *eloc, uint32_t *elen,
 					 sector_t *offset)
 {
 	struct fileIdentDesc *fi;
@@ -111,7 +111,7 @@
 		    (EXT_RECORDED_ALLOCATED >> 30))
 			return NULL;
 
-		block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset);
+		block = udf_get_lb_pblock(dir->i_sb, eloc, *offset);
 
 		(*offset)++;
 
@@ -131,7 +131,7 @@
 			if (i + *offset > (*elen >> blocksize_bits))
 				i = (*elen >> blocksize_bits)-*offset;
 			for (num = 0; i > 0; i--) {
-				block = udf_get_lb_pblock(dir->i_sb, *eloc,
+				block = udf_get_lb_pblock(dir->i_sb, eloc,
 							  *offset + i);
 				tmp = udf_tgetblk(dir->i_sb, block);
 				if (tmp && !buffer_uptodate(tmp) &&
@@ -169,7 +169,7 @@
 		    (EXT_RECORDED_ALLOCATED >> 30))
 			return NULL;
 
-		block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset);
+		block = udf_get_lb_pblock(dir->i_sb, eloc, *offset);
 
 		(*offset)++;
 
@@ -249,9 +249,9 @@
 }
 
 #if 0
-static extent_ad *udf_get_fileextent(void *buffer, int bufsize, int *offset)
+static struct extent_ad *udf_get_fileextent(void *buffer, int bufsize, int *offset)
 {
-	extent_ad *ext;
+	struct extent_ad *ext;
 	struct fileEntry *fe;
 	uint8_t *ptr;
 
@@ -274,54 +274,54 @@
 	if ((*offset > 0) && (*offset < le32_to_cpu(fe->lengthAllocDescs)))
 		ptr += *offset;
 
-	ext = (extent_ad *)ptr;
+	ext = (struct extent_ad *)ptr;
 
-	*offset = *offset + sizeof(extent_ad);
+	*offset = *offset + sizeof(struct extent_ad);
 	return ext;
 }
 #endif
 
-short_ad *udf_get_fileshortad(uint8_t *ptr, int maxoffset, uint32_t *offset,
+struct short_ad *udf_get_fileshortad(uint8_t *ptr, int maxoffset, uint32_t *offset,
 			      int inc)
 {
-	short_ad *sa;
+	struct short_ad *sa;
 
 	if ((!ptr) || (!offset)) {
 		printk(KERN_ERR "udf: udf_get_fileshortad() invalidparms\n");
 		return NULL;
 	}
 
-	if ((*offset + sizeof(short_ad)) > maxoffset)
+	if ((*offset + sizeof(struct short_ad)) > maxoffset)
 		return NULL;
 	else {
-		sa = (short_ad *)ptr;
+		sa = (struct short_ad *)ptr;
 		if (sa->extLength == 0)
 			return NULL;
 	}
 
 	if (inc)
-		*offset += sizeof(short_ad);
+		*offset += sizeof(struct short_ad);
 	return sa;
 }
 
-long_ad *udf_get_filelongad(uint8_t *ptr, int maxoffset, uint32_t *offset, int inc)
+struct long_ad *udf_get_filelongad(uint8_t *ptr, int maxoffset, uint32_t *offset, int inc)
 {
-	long_ad *la;
+	struct long_ad *la;
 
 	if ((!ptr) || (!offset)) {
 		printk(KERN_ERR "udf: udf_get_filelongad() invalidparms\n");
 		return NULL;
 	}
 
-	if ((*offset + sizeof(long_ad)) > maxoffset)
+	if ((*offset + sizeof(struct long_ad)) > maxoffset)
 		return NULL;
 	else {
-		la = (long_ad *)ptr;
+		la = (struct long_ad *)ptr;
 		if (la->extLength == 0)
 			return NULL;
 	}
 
 	if (inc)
-		*offset += sizeof(long_ad);
+		*offset += sizeof(struct long_ad);
 	return la;
 }
diff --git a/fs/udf/ecma_167.h b/fs/udf/ecma_167.h
index a0974df..4792b77 100644
--- a/fs/udf/ecma_167.h
+++ b/fs/udf/ecma_167.h
@@ -38,10 +38,10 @@
 #define _ECMA_167_H 1
 
 /* Character set specification (ECMA 167r3 1/7.2.1) */
-typedef struct {
+struct charspec {
 	uint8_t		charSetType;
 	uint8_t		charSetInfo[63];
-} __attribute__ ((packed)) charspec;
+} __attribute__ ((packed));
 
 /* Character Set Type (ECMA 167r3 1/7.2.1.1) */
 #define CHARSPEC_TYPE_CS0		0x00	/* (1/7.2.2) */
@@ -57,7 +57,7 @@
 typedef uint8_t		dstring;
 
 /* Timestamp (ECMA 167r3 1/7.3) */
-typedef struct {
+struct timestamp {
 	__le16		typeAndTimezone;
 	__le16		year;
 	uint8_t		month;
@@ -68,7 +68,7 @@
 	uint8_t		centiseconds;
 	uint8_t		hundredsOfMicroseconds;
 	uint8_t		microseconds;
-} __attribute__ ((packed)) timestamp;
+} __attribute__ ((packed));
 
 /* Type and Time Zone (ECMA 167r3 1/7.3.1) */
 #define TIMESTAMP_TYPE_MASK		0xF000
@@ -78,11 +78,11 @@
 #define TIMESTAMP_TIMEZONE_MASK		0x0FFF
 
 /* Entity identifier (ECMA 167r3 1/7.4) */
-typedef struct {
+struct regid {
 	uint8_t		flags;
 	uint8_t		ident[23];
 	uint8_t		identSuffix[8];
-} __attribute__ ((packed)) regid;
+} __attribute__ ((packed));
 
 /* Flags (ECMA 167r3 1/7.4.1) */
 #define ENTITYID_FLAGS_DIRTY		0x00
@@ -126,38 +126,38 @@
 
 /* Boot Descriptor (ECMA 167r3 2/9.4) */
 struct bootDesc {
-	uint8_t		structType;
-	uint8_t		stdIdent[VSD_STD_ID_LEN];
-	uint8_t		structVersion;
-	uint8_t		reserved1;
-	regid		archType;
-	regid		bootIdent;
-	__le32		bootExtLocation;
-	__le32		bootExtLength;
-	__le64		loadAddress;
-	__le64		startAddress;
-	timestamp	descCreationDateAndTime;
-	__le16		flags;
-	uint8_t		reserved2[32];
-	uint8_t		bootUse[1906];
+	uint8_t			structType;
+	uint8_t			stdIdent[VSD_STD_ID_LEN];
+	uint8_t			structVersion;
+	uint8_t			reserved1;
+	struct regid		archType;
+	struct regid		bootIdent;
+	__le32			bootExtLocation;
+	__le32			bootExtLength;
+	__le64			loadAddress;
+	__le64			startAddress;
+	struct timestamp	descCreationDateAndTime;
+	__le16			flags;
+	uint8_t			reserved2[32];
+	uint8_t			bootUse[1906];
 } __attribute__ ((packed));
 
 /* Flags (ECMA 167r3 2/9.4.12) */
 #define BOOT_FLAGS_ERASE		0x01
 
 /* Extent Descriptor (ECMA 167r3 3/7.1) */
-typedef struct {
+struct extent_ad {
 	__le32		extLength;
 	__le32		extLocation;
-} __attribute__ ((packed)) extent_ad;
+} __attribute__ ((packed));
 
-typedef struct {
+struct kernel_extent_ad {
 	uint32_t	extLength;
 	uint32_t	extLocation;
-} kernel_extent_ad;
+};
 
 /* Descriptor Tag (ECMA 167r3 3/7.2) */
-typedef struct {
+struct tag {
 	__le16		tagIdent;
 	__le16		descVersion;
 	uint8_t		tagChecksum;
@@ -166,7 +166,7 @@
 	__le16		descCRC;
 	__le16		descCRCLength;
 	__le32		tagLocation;
-} __attribute__ ((packed)) tag;
+} __attribute__ ((packed));
 
 /* Tag Identifier (ECMA 167r3 3/7.2.1) */
 #define TAG_IDENT_PVD			0x0001
@@ -190,28 +190,28 @@
 
 /* Primary Volume Descriptor (ECMA 167r3 3/10.1) */
 struct primaryVolDesc {
-	tag		descTag;
-	__le32		volDescSeqNum;
-	__le32		primaryVolDescNum;
-	dstring		volIdent[32];
-	__le16		volSeqNum;
-	__le16		maxVolSeqNum;
-	__le16		interchangeLvl;
-	__le16		maxInterchangeLvl;
-	__le32		charSetList;
-	__le32		maxCharSetList;
-	dstring		volSetIdent[128];
-	charspec	descCharSet;
-	charspec	explanatoryCharSet;
-	extent_ad	volAbstract;
-	extent_ad	volCopyright;
-	regid		appIdent;
-	timestamp	recordingDateAndTime;
-	regid		impIdent;
-	uint8_t		impUse[64];
-	__le32		predecessorVolDescSeqLocation;
-	__le16		flags;
-	uint8_t		reserved[22];
+	struct tag		descTag;
+	__le32			volDescSeqNum;
+	__le32			primaryVolDescNum;
+	dstring			volIdent[32];
+	__le16			volSeqNum;
+	__le16			maxVolSeqNum;
+	__le16			interchangeLvl;
+	__le16			maxInterchangeLvl;
+	__le32			charSetList;
+	__le32			maxCharSetList;
+	dstring			volSetIdent[128];
+	struct charspec		descCharSet;
+	struct charspec		explanatoryCharSet;
+	struct extent_ad	volAbstract;
+	struct extent_ad	volCopyright;
+	struct regid		appIdent;
+	struct timestamp	recordingDateAndTime;
+	struct regid		impIdent;
+	uint8_t			impUse[64];
+	__le32			predecessorVolDescSeqLocation;
+	__le16			flags;
+	uint8_t			reserved[22];
 } __attribute__ ((packed));
 
 /* Flags (ECMA 167r3 3/10.1.21) */
@@ -219,40 +219,40 @@
 
 /* Anchor Volume Descriptor Pointer (ECMA 167r3 3/10.2) */
 struct anchorVolDescPtr {
-	tag		descTag;
-	extent_ad	mainVolDescSeqExt;
-	extent_ad	reserveVolDescSeqExt;
-	uint8_t	 	reserved[480];
+	struct tag		descTag;
+	struct extent_ad	mainVolDescSeqExt;
+	struct extent_ad	reserveVolDescSeqExt;
+	uint8_t	 		reserved[480];
 } __attribute__ ((packed));
 
 /* Volume Descriptor Pointer (ECMA 167r3 3/10.3) */
 struct volDescPtr {
-	tag		descTag;
-	__le32		volDescSeqNum;
-	extent_ad	nextVolDescSeqExt;
-	uint8_t		reserved[484];
+	struct tag		descTag;
+	__le32			volDescSeqNum;
+	struct extent_ad	nextVolDescSeqExt;
+	uint8_t			reserved[484];
 } __attribute__ ((packed));
 
 /* Implementation Use Volume Descriptor (ECMA 167r3 3/10.4) */
 struct impUseVolDesc {
-	tag		descTag;
+	struct tag	descTag;
 	__le32		volDescSeqNum;
-	regid		impIdent;
+	struct regid	impIdent;
 	uint8_t		impUse[460];
 } __attribute__ ((packed));
 
 /* Partition Descriptor (ECMA 167r3 3/10.5) */
 struct partitionDesc {
-	tag descTag;
+	struct tag descTag;
 	__le32 volDescSeqNum;
 	__le16 partitionFlags;
 	__le16 partitionNumber;
-	regid partitionContents;
+	struct regid partitionContents;
 	uint8_t partitionContentsUse[128];
 	__le32 accessType;
 	__le32 partitionStartingLocation;
 	__le32 partitionLength;
-	regid impIdent;
+	struct regid impIdent;
 	uint8_t impUse[128];
 	uint8_t reserved[156];
 } __attribute__ ((packed));
@@ -278,19 +278,19 @@
 
 /* Logical Volume Descriptor (ECMA 167r3 3/10.6) */
 struct logicalVolDesc {
-	tag		descTag;
-	__le32		volDescSeqNum;
-	charspec	descCharSet;
-	dstring		logicalVolIdent[128];
-	__le32		logicalBlockSize;
-	regid		domainIdent;
-	uint8_t		logicalVolContentsUse[16];
-	__le32		mapTableLength;
-	__le32		numPartitionMaps;
-	regid		impIdent;
-	uint8_t		impUse[128];
-	extent_ad	integritySeqExt;
-	uint8_t		partitionMaps[0];
+	struct tag		descTag;
+	__le32			volDescSeqNum;
+	struct charspec		descCharSet;
+	dstring			logicalVolIdent[128];
+	__le32			logicalBlockSize;
+	struct regid		domainIdent;
+	uint8_t			logicalVolContentsUse[16];
+	__le32			mapTableLength;
+	__le32			numPartitionMaps;
+	struct regid		impIdent;
+	uint8_t			impUse[128];
+	struct extent_ad	integritySeqExt;
+	uint8_t			partitionMaps[0];
 } __attribute__ ((packed));
 
 /* Generic Partition Map (ECMA 167r3 3/10.7.1) */
@@ -322,30 +322,30 @@
 
 /* Unallocated Space Descriptor (ECMA 167r3 3/10.8) */
 struct unallocSpaceDesc {
-	tag		descTag;
-	__le32		volDescSeqNum;
-	__le32		numAllocDescs;
-	extent_ad	allocDescs[0];
+	struct tag		descTag;
+	__le32			volDescSeqNum;
+	__le32			numAllocDescs;
+	struct extent_ad	allocDescs[0];
 } __attribute__ ((packed));
 
 /* Terminating Descriptor (ECMA 167r3 3/10.9) */
 struct terminatingDesc {
-	tag		descTag;
+	struct tag	descTag;
 	uint8_t		reserved[496];
 } __attribute__ ((packed));
 
 /* Logical Volume Integrity Descriptor (ECMA 167r3 3/10.10) */
 struct logicalVolIntegrityDesc {
-	tag		descTag;
-	timestamp	recordingDateAndTime;
-	__le32		integrityType;
-	extent_ad	nextIntegrityExt;
-	uint8_t		logicalVolContentsUse[32];
-	__le32		numOfPartitions;
-	__le32		lengthOfImpUse;
-	__le32		freeSpaceTable[0];
-	__le32		sizeTable[0];
-	uint8_t		impUse[0];
+	struct tag		descTag;
+	struct timestamp	recordingDateAndTime;
+	__le32			integrityType;
+	struct extent_ad	nextIntegrityExt;
+	uint8_t			logicalVolContentsUse[32];
+	__le32			numOfPartitions;
+	__le32			lengthOfImpUse;
+	__le32			freeSpaceTable[0];
+	__le32			sizeTable[0];
+	uint8_t			impUse[0];
 } __attribute__ ((packed));
 
 /* Integrity Type (ECMA 167r3 3/10.10.3) */
@@ -353,50 +353,50 @@
 #define LVID_INTEGRITY_TYPE_CLOSE	0x00000001
 
 /* Recorded Address (ECMA 167r3 4/7.1) */
-typedef struct {
+struct lb_addr {
 	__le32		logicalBlockNum;
 	__le16	 	partitionReferenceNum;
-} __attribute__ ((packed)) lb_addr;
+} __attribute__ ((packed));
 
 /* ... and its in-core analog */
-typedef struct {
+struct kernel_lb_addr {
 	uint32_t		logicalBlockNum;
 	uint16_t	 	partitionReferenceNum;
-} kernel_lb_addr;
+};
 
 /* Short Allocation Descriptor (ECMA 167r3 4/14.14.1) */
-typedef struct {
+struct short_ad {
         __le32		extLength;
         __le32		extPosition;
-} __attribute__ ((packed)) short_ad;
+} __attribute__ ((packed));
 
 /* Long Allocation Descriptor (ECMA 167r3 4/14.14.2) */
-typedef struct {
+struct long_ad {
 	__le32		extLength;
-	lb_addr		extLocation;
+	struct lb_addr	extLocation;
 	uint8_t		impUse[6];
-} __attribute__ ((packed)) long_ad;
+} __attribute__ ((packed));
 
-typedef struct {
-	uint32_t	extLength;
-	kernel_lb_addr	extLocation;
-	uint8_t		impUse[6];
-} kernel_long_ad;
+struct kernel_long_ad {
+	uint32_t		extLength;
+	struct kernel_lb_addr	extLocation;
+	uint8_t			impUse[6];
+};
 
 /* Extended Allocation Descriptor (ECMA 167r3 4/14.14.3) */
-typedef struct {
+struct ext_ad {
 	__le32		extLength;
 	__le32		recordedLength;
 	__le32		informationLength;
-	lb_addr		extLocation;
-} __attribute__ ((packed)) ext_ad;
+	struct lb_addr	extLocation;
+} __attribute__ ((packed));
 
-typedef struct {
-	uint32_t	extLength;
-	uint32_t	recordedLength;
-	uint32_t	informationLength;
-	kernel_lb_addr	extLocation;
-} kernel_ext_ad;
+struct kernel_ext_ad {
+	uint32_t		extLength;
+	uint32_t		recordedLength;
+	uint32_t		informationLength;
+	struct kernel_lb_addr	extLocation;
+};
 
 /* Descriptor Tag (ECMA 167r3 4/7.2 - See 3/7.2) */
 
@@ -415,44 +415,44 @@
 
 /* File Set Descriptor (ECMA 167r3 4/14.1) */
 struct fileSetDesc {
-	tag		descTag;
-	timestamp	recordingDateAndTime;
-	__le16		interchangeLvl;
-	__le16		maxInterchangeLvl;
-	__le32		charSetList;
-	__le32		maxCharSetList;
-	__le32		fileSetNum;
-	__le32		fileSetDescNum;
-	charspec	logicalVolIdentCharSet;
-	dstring		logicalVolIdent[128];
-	charspec	fileSetCharSet;
-	dstring		fileSetIdent[32];
-	dstring		copyrightFileIdent[32];
-	dstring		abstractFileIdent[32];
-	long_ad		rootDirectoryICB;
-	regid		domainIdent;
-	long_ad		nextExt;
-	long_ad		streamDirectoryICB;
-	uint8_t		reserved[32];
+	struct tag		descTag;
+	struct timestamp	recordingDateAndTime;
+	__le16			interchangeLvl;
+	__le16			maxInterchangeLvl;
+	__le32			charSetList;
+	__le32			maxCharSetList;
+	__le32			fileSetNum;
+	__le32			fileSetDescNum;
+	struct charspec		logicalVolIdentCharSet;
+	dstring			logicalVolIdent[128];
+	struct charspec		fileSetCharSet;
+	dstring			fileSetIdent[32];
+	dstring			copyrightFileIdent[32];
+	dstring			abstractFileIdent[32];
+	struct long_ad		rootDirectoryICB;
+	struct regid		domainIdent;
+	struct long_ad		nextExt;
+	struct long_ad		streamDirectoryICB;
+	uint8_t			reserved[32];
 } __attribute__ ((packed));
 
 /* Partition Header Descriptor (ECMA 167r3 4/14.3) */
 struct partitionHeaderDesc {
-	short_ad	unallocSpaceTable;
-	short_ad	unallocSpaceBitmap;
-	short_ad	partitionIntegrityTable;
-	short_ad	freedSpaceTable;
-	short_ad	freedSpaceBitmap;
+	struct short_ad	unallocSpaceTable;
+	struct short_ad	unallocSpaceBitmap;
+	struct short_ad	partitionIntegrityTable;
+	struct short_ad	freedSpaceTable;
+	struct short_ad	freedSpaceBitmap;
 	uint8_t		reserved[88];
 } __attribute__ ((packed));
 
 /* File Identifier Descriptor (ECMA 167r3 4/14.4) */
 struct fileIdentDesc {
-	tag		descTag;
+	struct tag	descTag;
 	__le16		fileVersionNum;
 	uint8_t		fileCharacteristics;
 	uint8_t		lengthFileIdent;
-	long_ad		icb;
+	struct long_ad	icb;
 	__le16		lengthOfImpUse;
 	uint8_t		impUse[0];
 	uint8_t		fileIdent[0];
@@ -468,22 +468,22 @@
 
 /* Allocation Ext Descriptor (ECMA 167r3 4/14.5) */
 struct allocExtDesc {
-	tag		descTag;
+	struct tag	descTag;
 	__le32		previousAllocExtLocation;
 	__le32		lengthAllocDescs;
 } __attribute__ ((packed));
 
 /* ICB Tag (ECMA 167r3 4/14.6) */
-typedef struct {
+struct icbtag {
 	__le32		priorRecordedNumDirectEntries;
 	__le16		strategyType;
 	__le16		strategyParameter;
 	__le16		numEntries;
 	uint8_t		reserved;
 	uint8_t		fileType;
-	lb_addr		parentICBLocation;
+	struct lb_addr	parentICBLocation;
 	__le16		flags;
-} __attribute__ ((packed)) icbtag;
+} __attribute__ ((packed));
 
 /* Strategy Type (ECMA 167r3 4/14.6.2) */
 #define ICBTAG_STRATEGY_TYPE_UNDEF	0x0000
@@ -528,41 +528,41 @@
 
 /* Indirect Entry (ECMA 167r3 4/14.7) */
 struct indirectEntry {
-	tag		descTag;
-	icbtag		icbTag;
-	long_ad		indirectICB;
+	struct tag	descTag;
+	struct icbtag	icbTag;
+	struct long_ad	indirectICB;
 } __attribute__ ((packed));
 
 /* Terminal Entry (ECMA 167r3 4/14.8) */
 struct terminalEntry {
-	tag		descTag;
-	icbtag		icbTag;
+	struct tag	descTag;
+	struct icbtag	icbTag;
 } __attribute__ ((packed));
 
 /* File Entry (ECMA 167r3 4/14.9) */
 struct fileEntry {
-	tag		descTag;
-	icbtag		icbTag;
-	__le32		uid;
-	__le32		gid;
-	__le32		permissions;
-	__le16		fileLinkCount;
-	uint8_t		recordFormat;
-	uint8_t		recordDisplayAttr;
-	__le32		recordLength;
-	__le64		informationLength;
-	__le64		logicalBlocksRecorded;
-	timestamp	accessTime;
-	timestamp	modificationTime;
-	timestamp	attrTime;
-	__le32		checkpoint;
-	long_ad		extendedAttrICB;
-	regid		impIdent;
-	__le64		uniqueID;
-	__le32		lengthExtendedAttr;
-	__le32		lengthAllocDescs;
-	uint8_t		extendedAttr[0];
-	uint8_t		allocDescs[0];
+	struct tag		descTag;
+	struct icbtag		icbTag;
+	__le32			uid;
+	__le32			gid;
+	__le32			permissions;
+	__le16			fileLinkCount;
+	uint8_t			recordFormat;
+	uint8_t			recordDisplayAttr;
+	__le32			recordLength;
+	__le64			informationLength;
+	__le64			logicalBlocksRecorded;
+	struct timestamp	accessTime;
+	struct timestamp	modificationTime;
+	struct timestamp	attrTime;
+	__le32			checkpoint;
+	struct long_ad		extendedAttrICB;
+	struct regid		impIdent;
+	__le64			uniqueID;
+	__le32			lengthExtendedAttr;
+	__le32			lengthAllocDescs;
+	uint8_t			extendedAttr[0];
+	uint8_t			allocDescs[0];
 } __attribute__ ((packed));
 
 /* Permissions (ECMA 167r3 4/14.9.5) */
@@ -604,7 +604,7 @@
 
 /* Extended Attribute Header Descriptor (ECMA 167r3 4/14.10.1) */
 struct extendedAttrHeaderDesc {
-	tag		descTag;
+	struct tag	descTag;
 	__le32		impAttrLocation;
 	__le32		appAttrLocation;
 } __attribute__ ((packed));
@@ -687,7 +687,7 @@
 	uint8_t		reserved[3];
 	__le32		attrLength;
 	__le32		impUseLength;
-	regid		impIdent;
+	struct regid	impIdent;
 	uint8_t		impUse[0];
 } __attribute__ ((packed));
 
@@ -698,7 +698,7 @@
 	uint8_t		reserved[3];
 	__le32		attrLength;
 	__le32		appUseLength;
-	regid		appIdent;
+	struct regid	appIdent;
 	uint8_t		appUse[0];
 } __attribute__ ((packed));
 
@@ -712,15 +712,15 @@
 
 /* Unallocated Space Entry (ECMA 167r3 4/14.11) */
 struct unallocSpaceEntry {
-	tag		descTag;
-	icbtag		icbTag;
+	struct tag	descTag;
+	struct icbtag	icbTag;
 	__le32		lengthAllocDescs;
 	uint8_t		allocDescs[0];
 } __attribute__ ((packed));
 
 /* Space Bitmap Descriptor (ECMA 167r3 4/14.12) */
 struct spaceBitmapDesc {
-	tag		descTag;
+	struct tag	descTag;
 	__le32		numOfBits;
 	__le32		numOfBytes;
 	uint8_t		bitmap[0];
@@ -728,13 +728,13 @@
 
 /* Partition Integrity Entry (ECMA 167r3 4/14.13) */
 struct partitionIntegrityEntry {
-	tag		descTag;
-	icbtag		icbTag;
-	timestamp	recordingDateAndTime;
-	uint8_t		integrityType;
-	uint8_t		reserved[175];
-	regid		impIdent;
-	uint8_t		impUse[256];
+	struct tag		descTag;
+	struct icbtag		icbTag;
+	struct timestamp	recordingDateAndTime;
+	uint8_t			integrityType;
+	uint8_t			reserved[175];
+	struct regid		impIdent;
+	uint8_t			impUse[256];
 } __attribute__ ((packed));
 
 /* Short Allocation Descriptor (ECMA 167r3 4/14.14.1) */
@@ -765,32 +765,32 @@
 
 /* File Entry (ECMA 167r3 4/14.17) */
 struct extendedFileEntry {
-	tag		descTag;
-	icbtag		icbTag;
-	__le32		uid;
-	__le32		gid;
-	__le32		permissions;
-	__le16		fileLinkCount;
-	uint8_t		recordFormat;
-	uint8_t		recordDisplayAttr;
-	__le32		recordLength;
-	__le64		informationLength;
-	__le64		objectSize;
-	__le64		logicalBlocksRecorded;
-	timestamp	accessTime;
-	timestamp	modificationTime;
-	timestamp	createTime;
-	timestamp	attrTime;
-	__le32		checkpoint;
-	__le32		reserved;
-	long_ad		extendedAttrICB;
-	long_ad		streamDirectoryICB;
-	regid		impIdent;
-	__le64		uniqueID;
-	__le32		lengthExtendedAttr;
-	__le32		lengthAllocDescs;
-	uint8_t		extendedAttr[0];
-	uint8_t		allocDescs[0];
+	struct tag		descTag;
+	struct icbtag		icbTag;
+	__le32			uid;
+	__le32			gid;
+	__le32			permissions;
+	__le16			fileLinkCount;
+	uint8_t			recordFormat;
+	uint8_t			recordDisplayAttr;
+	__le32			recordLength;
+	__le64			informationLength;
+	__le64			objectSize;
+	__le64			logicalBlocksRecorded;
+	struct timestamp	accessTime;
+	struct timestamp	modificationTime;
+	struct timestamp	createTime;
+	struct timestamp	attrTime;
+	__le32			checkpoint;
+	__le32			reserved;
+	struct long_ad		extendedAttrICB;
+	struct long_ad		streamDirectoryICB;
+	struct regid		impIdent;
+	__le64			uniqueID;
+	__le32			lengthExtendedAttr;
+	__le32			lengthAllocDescs;
+	uint8_t			extendedAttr[0];
+	uint8_t			allocDescs[0];
 } __attribute__ ((packed));
 
 #endif /* _ECMA_167_H */
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c
index 47dbe56..c10fa39 100644
--- a/fs/udf/ialloc.c
+++ b/fs/udf/ialloc.c
@@ -49,12 +49,11 @@
 			le32_add_cpu(&lvidiu->numDirs, -1);
 		else
 			le32_add_cpu(&lvidiu->numFiles, -1);
-
-		mark_buffer_dirty(sbi->s_lvid_bh);
+		udf_updated_lvid(sb);
 	}
 	mutex_unlock(&sbi->s_alloc_mutex);
 
-	udf_free_blocks(sb, NULL, UDF_I(inode)->i_location, 0, 1);
+	udf_free_blocks(sb, NULL, &UDF_I(inode)->i_location, 0, 1);
 }
 
 struct inode *udf_new_inode(struct inode *dir, int mode, int *err)
@@ -122,7 +121,7 @@
 		if (!(++uniqueID & 0x00000000FFFFFFFFUL))
 			uniqueID += 16;
 		lvhd->uniqueID = cpu_to_le64(uniqueID);
-		mark_buffer_dirty(sbi->s_lvid_bh);
+		udf_updated_lvid(sb);
 	}
 	mutex_unlock(&sbi->s_alloc_mutex);
 	inode->i_mode = mode;
@@ -138,7 +137,7 @@
 	iinfo->i_location.logicalBlockNum = block;
 	iinfo->i_location.partitionReferenceNum =
 				dinfo->i_location.partitionReferenceNum;
-	inode->i_ino = udf_get_lb_pblock(sb, iinfo->i_location, 0);
+	inode->i_ino = udf_get_lb_pblock(sb, &iinfo->i_location, 0);
 	inode->i_blocks = 0;
 	iinfo->i_lenEAttr = 0;
 	iinfo->i_lenAlloc = 0;
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 30ebde4..e7533f7 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -55,15 +55,15 @@
 static struct buffer_head *inode_getblk(struct inode *, sector_t, int *,
 					sector_t *, int *);
 static int8_t udf_insert_aext(struct inode *, struct extent_position,
-			      kernel_lb_addr, uint32_t);
+			      struct kernel_lb_addr, uint32_t);
 static void udf_split_extents(struct inode *, int *, int, int,
-			      kernel_long_ad[EXTENT_MERGE_SIZE], int *);
+			      struct kernel_long_ad[EXTENT_MERGE_SIZE], int *);
 static void udf_prealloc_extents(struct inode *, int, int,
-				 kernel_long_ad[EXTENT_MERGE_SIZE], int *);
+				 struct kernel_long_ad[EXTENT_MERGE_SIZE], int *);
 static void udf_merge_extents(struct inode *,
-			      kernel_long_ad[EXTENT_MERGE_SIZE], int *);
+			      struct kernel_long_ad[EXTENT_MERGE_SIZE], int *);
 static void udf_update_extents(struct inode *,
-			       kernel_long_ad[EXTENT_MERGE_SIZE], int, int,
+			       struct kernel_long_ad[EXTENT_MERGE_SIZE], int, int,
 			       struct extent_position *);
 static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
 
@@ -200,7 +200,7 @@
 {
 	int newblock;
 	struct buffer_head *dbh = NULL;
-	kernel_lb_addr eloc;
+	struct kernel_lb_addr eloc;
 	uint32_t elen;
 	uint8_t alloctype;
 	struct extent_position epos;
@@ -281,7 +281,7 @@
 	epos.bh = NULL;
 	epos.block = iinfo->i_location;
 	epos.offset = udf_file_entry_alloc_offset(inode);
-	udf_add_aext(inode, &epos, eloc, elen, 0);
+	udf_add_aext(inode, &epos, &eloc, elen, 0);
 	/* UniqueID stuff */
 
 	brelse(epos.bh);
@@ -359,12 +359,12 @@
 
 /* Extend the file by 'blocks' blocks, return the number of extents added */
 int udf_extend_file(struct inode *inode, struct extent_position *last_pos,
-		    kernel_long_ad *last_ext, sector_t blocks)
+		    struct kernel_long_ad *last_ext, sector_t blocks)
 {
 	sector_t add;
 	int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
 	struct super_block *sb = inode->i_sb;
-	kernel_lb_addr prealloc_loc = {};
+	struct kernel_lb_addr prealloc_loc = {};
 	int prealloc_len = 0;
 	struct udf_inode_info *iinfo;
 
@@ -411,11 +411,11 @@
 	}
 
 	if (fake) {
-		udf_add_aext(inode, last_pos, last_ext->extLocation,
+		udf_add_aext(inode, last_pos, &last_ext->extLocation,
 			     last_ext->extLength, 1);
 		count++;
 	} else
-		udf_write_aext(inode, last_pos, last_ext->extLocation,
+		udf_write_aext(inode, last_pos, &last_ext->extLocation,
 				last_ext->extLength, 1);
 
 	/* Managed to do everything necessary? */
@@ -432,7 +432,7 @@
 	/* Create enough extents to cover the whole hole */
 	while (blocks > add) {
 		blocks -= add;
-		if (udf_add_aext(inode, last_pos, last_ext->extLocation,
+		if (udf_add_aext(inode, last_pos, &last_ext->extLocation,
 				 last_ext->extLength, 1) == -1)
 			return -1;
 		count++;
@@ -440,7 +440,7 @@
 	if (blocks) {
 		last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
 			(blocks << sb->s_blocksize_bits);
-		if (udf_add_aext(inode, last_pos, last_ext->extLocation,
+		if (udf_add_aext(inode, last_pos, &last_ext->extLocation,
 				 last_ext->extLength, 1) == -1)
 			return -1;
 		count++;
@@ -449,7 +449,7 @@
 out:
 	/* Do we have some preallocated blocks saved? */
 	if (prealloc_len) {
-		if (udf_add_aext(inode, last_pos, prealloc_loc,
+		if (udf_add_aext(inode, last_pos, &prealloc_loc,
 				 prealloc_len, 1) == -1)
 			return -1;
 		last_ext->extLocation = prealloc_loc;
@@ -459,9 +459,9 @@
 
 	/* last_pos should point to the last written extent... */
 	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
-		last_pos->offset -= sizeof(short_ad);
+		last_pos->offset -= sizeof(struct short_ad);
 	else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
-		last_pos->offset -= sizeof(long_ad);
+		last_pos->offset -= sizeof(struct long_ad);
 	else
 		return -1;
 
@@ -473,11 +473,11 @@
 {
 	static sector_t last_block;
 	struct buffer_head *result = NULL;
-	kernel_long_ad laarr[EXTENT_MERGE_SIZE];
+	struct kernel_long_ad laarr[EXTENT_MERGE_SIZE];
 	struct extent_position prev_epos, cur_epos, next_epos;
 	int count = 0, startnum = 0, endnum = 0;
 	uint32_t elen = 0, tmpelen;
-	kernel_lb_addr eloc, tmpeloc;
+	struct kernel_lb_addr eloc, tmpeloc;
 	int c = 1;
 	loff_t lbcount = 0, b_off = 0;
 	uint32_t newblocknum, newblock;
@@ -550,12 +550,12 @@
 			elen = EXT_RECORDED_ALLOCATED |
 				((elen + inode->i_sb->s_blocksize - 1) &
 				 ~(inode->i_sb->s_blocksize - 1));
-			etype = udf_write_aext(inode, &cur_epos, eloc, elen, 1);
+			etype = udf_write_aext(inode, &cur_epos, &eloc, elen, 1);
 		}
 		brelse(prev_epos.bh);
 		brelse(cur_epos.bh);
 		brelse(next_epos.bh);
-		newblock = udf_get_lb_pblock(inode->i_sb, eloc, offset);
+		newblock = udf_get_lb_pblock(inode->i_sb, &eloc, offset);
 		*phys = newblock;
 		return NULL;
 	}
@@ -572,7 +572,7 @@
 		} else {
 			/* Create a fake extent when there's not one */
 			memset(&laarr[0].extLocation, 0x00,
-				sizeof(kernel_lb_addr));
+				sizeof(struct kernel_lb_addr));
 			laarr[0].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED;
 			/* Will udf_extend_file() create real extent from
 			   a fake one? */
@@ -602,7 +602,7 @@
 			laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
 				inode->i_sb->s_blocksize;
 			memset(&laarr[c].extLocation, 0x00,
-				sizeof(kernel_lb_addr));
+				sizeof(struct kernel_lb_addr));
 			count++;
 			endnum++;
 		}
@@ -699,7 +699,7 @@
 
 static void udf_split_extents(struct inode *inode, int *c, int offset,
 			      int newblocknum,
-			      kernel_long_ad laarr[EXTENT_MERGE_SIZE],
+			      struct kernel_long_ad laarr[EXTENT_MERGE_SIZE],
 			      int *endnum)
 {
 	unsigned long blocksize = inode->i_sb->s_blocksize;
@@ -726,7 +726,7 @@
 		if (offset) {
 			if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
 				udf_free_blocks(inode->i_sb, inode,
-						laarr[curr].extLocation,
+						&laarr[curr].extLocation,
 						0, offset);
 				laarr[curr].extLength =
 					EXT_NOT_RECORDED_NOT_ALLOCATED |
@@ -763,7 +763,7 @@
 }
 
 static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,
-				 kernel_long_ad laarr[EXTENT_MERGE_SIZE],
+				 struct kernel_long_ad laarr[EXTENT_MERGE_SIZE],
 				 int *endnum)
 {
 	int start, length = 0, currlength = 0, i;
@@ -817,7 +817,7 @@
 					 inode->i_sb->s_blocksize_bits);
 			else {
 				memmove(&laarr[c + 2], &laarr[c + 1],
-					sizeof(long_ad) * (*endnum - (c + 1)));
+					sizeof(struct long_ad) * (*endnum - (c + 1)));
 				(*endnum)++;
 				laarr[c + 1].extLocation.logicalBlockNum = next;
 				laarr[c + 1].extLocation.partitionReferenceNum =
@@ -846,7 +846,7 @@
 					if (*endnum > (i + 1))
 						memmove(&laarr[i],
 							&laarr[i + 1],
-							sizeof(long_ad) *
+							sizeof(struct long_ad) *
 							(*endnum - (i + 1)));
 					i--;
 					(*endnum)--;
@@ -859,7 +859,7 @@
 }
 
 static void udf_merge_extents(struct inode *inode,
-			      kernel_long_ad laarr[EXTENT_MERGE_SIZE],
+			      struct kernel_long_ad laarr[EXTENT_MERGE_SIZE],
 			      int *endnum)
 {
 	int i;
@@ -867,8 +867,8 @@
 	unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
 
 	for (i = 0; i < (*endnum - 1); i++) {
-		kernel_long_ad *li /*l[i]*/ = &laarr[i];
-		kernel_long_ad *lip1 /*l[i plus 1]*/ = &laarr[i + 1];
+		struct kernel_long_ad *li /*l[i]*/ = &laarr[i];
+		struct kernel_long_ad *lip1 /*l[i plus 1]*/ = &laarr[i + 1];
 
 		if (((li->extLength >> 30) == (lip1->extLength >> 30)) &&
 			(((li->extLength >> 30) ==
@@ -902,7 +902,7 @@
 					 blocksize - 1) & ~(blocksize - 1));
 				if (*endnum > (i + 2))
 					memmove(&laarr[i + 1], &laarr[i + 2],
-						sizeof(long_ad) *
+						sizeof(struct long_ad) *
 						(*endnum - (i + 2)));
 				i--;
 				(*endnum)--;
@@ -911,7 +911,7 @@
 				(EXT_NOT_RECORDED_ALLOCATED >> 30)) &&
 			   ((lip1->extLength >> 30) ==
 				(EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))) {
-			udf_free_blocks(inode->i_sb, inode, li->extLocation, 0,
+			udf_free_blocks(inode->i_sb, inode, &li->extLocation, 0,
 					((li->extLength &
 					  UDF_EXTENT_LENGTH_MASK) +
 					 blocksize - 1) >> blocksize_bits);
@@ -937,7 +937,7 @@
 					  blocksize - 1) & ~(blocksize - 1));
 				if (*endnum > (i + 2))
 					memmove(&laarr[i + 1], &laarr[i + 2],
-						sizeof(long_ad) *
+						sizeof(struct long_ad) *
 						(*endnum - (i + 2)));
 				i--;
 				(*endnum)--;
@@ -945,7 +945,7 @@
 		} else if ((li->extLength >> 30) ==
 					(EXT_NOT_RECORDED_ALLOCATED >> 30)) {
 			udf_free_blocks(inode->i_sb, inode,
-					li->extLocation, 0,
+					&li->extLocation, 0,
 					((li->extLength &
 						UDF_EXTENT_LENGTH_MASK) +
 					 blocksize - 1) >> blocksize_bits);
@@ -959,12 +959,12 @@
 }
 
 static void udf_update_extents(struct inode *inode,
-			       kernel_long_ad laarr[EXTENT_MERGE_SIZE],
+			       struct kernel_long_ad laarr[EXTENT_MERGE_SIZE],
 			       int startnum, int endnum,
 			       struct extent_position *epos)
 {
 	int start = 0, i;
-	kernel_lb_addr tmploc;
+	struct kernel_lb_addr tmploc;
 	uint32_t tmplen;
 
 	if (startnum > endnum) {
@@ -983,7 +983,7 @@
 
 	for (i = start; i < endnum; i++) {
 		udf_next_aext(inode, epos, &tmploc, &tmplen, 0);
-		udf_write_aext(inode, epos, laarr[i].extLocation,
+		udf_write_aext(inode, epos, &laarr[i].extLocation,
 			       laarr[i].extLength, 1);
 	}
 }
@@ -1076,7 +1076,7 @@
 	 *      i_nlink = 1
 	 *      i_op = NULL;
 	 */
-	bh = udf_read_ptagged(inode->i_sb, iinfo->i_location, 0, &ident);
+	bh = udf_read_ptagged(inode->i_sb, &iinfo->i_location, 0, &ident);
 	if (!bh) {
 		printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed !bh\n",
 		       inode->i_ino);
@@ -1098,24 +1098,24 @@
 	if (fe->icbTag.strategyType == cpu_to_le16(4096)) {
 		struct buffer_head *ibh;
 
-		ibh = udf_read_ptagged(inode->i_sb, iinfo->i_location, 1,
+		ibh = udf_read_ptagged(inode->i_sb, &iinfo->i_location, 1,
 					&ident);
 		if (ident == TAG_IDENT_IE && ibh) {
 			struct buffer_head *nbh = NULL;
-			kernel_lb_addr loc;
+			struct kernel_lb_addr loc;
 			struct indirectEntry *ie;
 
 			ie = (struct indirectEntry *)ibh->b_data;
 			loc = lelb_to_cpu(ie->indirectICB.extLocation);
 
 			if (ie->indirectICB.extLength &&
-				(nbh = udf_read_ptagged(inode->i_sb, loc, 0,
+				(nbh = udf_read_ptagged(inode->i_sb, &loc, 0,
 							&ident))) {
 				if (ident == TAG_IDENT_FE ||
 					ident == TAG_IDENT_EFE) {
 					memcpy(&iinfo->i_location,
 						&loc,
-						sizeof(kernel_lb_addr));
+						sizeof(struct kernel_lb_addr));
 					brelse(bh);
 					brelse(ibh);
 					brelse(nbh);
@@ -1222,8 +1222,15 @@
 	inode->i_size = le64_to_cpu(fe->informationLength);
 	iinfo->i_lenExtents = inode->i_size;
 
-	inode->i_mode = udf_convert_permissions(fe);
-	inode->i_mode &= ~UDF_SB(inode->i_sb)->s_umask;
+	if (fe->icbTag.fileType != ICBTAG_FILE_TYPE_DIRECTORY &&
+			sbi->s_fmode != UDF_INVALID_MODE)
+		inode->i_mode = sbi->s_fmode;
+	else if (fe->icbTag.fileType == ICBTAG_FILE_TYPE_DIRECTORY &&
+			sbi->s_dmode != UDF_INVALID_MODE)
+		inode->i_mode = sbi->s_dmode;
+	else
+		inode->i_mode = udf_convert_permissions(fe);
+	inode->i_mode &= ~sbi->s_umask;
 
 	if (iinfo->i_efe == 0) {
 		inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) <<
@@ -1396,7 +1403,7 @@
 
 	bh = udf_tread(inode->i_sb,
 			udf_get_lb_pblock(inode->i_sb,
-					  iinfo->i_location, 0));
+					  &iinfo->i_location, 0));
 	if (!bh) {
 		udf_debug("bread failure\n");
 		return -EIO;
@@ -1416,13 +1423,13 @@
 		       iinfo->i_ext.i_data, inode->i_sb->s_blocksize -
 					sizeof(struct unallocSpaceEntry));
 		crclen = sizeof(struct unallocSpaceEntry) +
-				iinfo->i_lenAlloc - sizeof(tag);
+				iinfo->i_lenAlloc - sizeof(struct tag);
 		use->descTag.tagLocation = cpu_to_le32(
 						iinfo->i_location.
 							logicalBlockNum);
 		use->descTag.descCRCLength = cpu_to_le16(crclen);
 		use->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)use +
-							   sizeof(tag),
+							   sizeof(struct tag),
 							   crclen));
 		use->descTag.tagChecksum = udf_tag_checksum(&use->descTag);
 
@@ -1459,23 +1466,23 @@
 	fe->informationLength = cpu_to_le64(inode->i_size);
 
 	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
-		regid *eid;
+		struct regid *eid;
 		struct deviceSpec *dsea =
 			(struct deviceSpec *)udf_get_extendedattr(inode, 12, 1);
 		if (!dsea) {
 			dsea = (struct deviceSpec *)
 				udf_add_extendedattr(inode,
 						     sizeof(struct deviceSpec) +
-						     sizeof(regid), 12, 0x3);
+						     sizeof(struct regid), 12, 0x3);
 			dsea->attrType = cpu_to_le32(12);
 			dsea->attrSubtype = 1;
 			dsea->attrLength = cpu_to_le32(
 						sizeof(struct deviceSpec) +
-						sizeof(regid));
-			dsea->impUseLength = cpu_to_le32(sizeof(regid));
+						sizeof(struct regid));
+			dsea->impUseLength = cpu_to_le32(sizeof(struct regid));
 		}
-		eid = (regid *)dsea->impUse;
-		memset(eid, 0, sizeof(regid));
+		eid = (struct regid *)dsea->impUse;
+		memset(eid, 0, sizeof(struct regid));
 		strcpy(eid->ident, UDF_ID_DEVELOPER);
 		eid->identSuffix[0] = UDF_OS_CLASS_UNIX;
 		eid->identSuffix[1] = UDF_OS_ID_LINUX;
@@ -1494,7 +1501,7 @@
 		udf_time_to_disk_stamp(&fe->accessTime, inode->i_atime);
 		udf_time_to_disk_stamp(&fe->modificationTime, inode->i_mtime);
 		udf_time_to_disk_stamp(&fe->attrTime, inode->i_ctime);
-		memset(&(fe->impIdent), 0, sizeof(regid));
+		memset(&(fe->impIdent), 0, sizeof(struct regid));
 		strcpy(fe->impIdent.ident, UDF_ID_DEVELOPER);
 		fe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
 		fe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
@@ -1533,7 +1540,7 @@
 		udf_time_to_disk_stamp(&efe->createTime, iinfo->i_crtime);
 		udf_time_to_disk_stamp(&efe->attrTime, inode->i_ctime);
 
-		memset(&(efe->impIdent), 0, sizeof(regid));
+		memset(&(efe->impIdent), 0, sizeof(struct regid));
 		strcpy(efe->impIdent.ident, UDF_ID_DEVELOPER);
 		efe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
 		efe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
@@ -1584,9 +1591,9 @@
 	fe->descTag.tagLocation = cpu_to_le32(
 					iinfo->i_location.logicalBlockNum);
 	crclen += iinfo->i_lenEAttr + iinfo->i_lenAlloc -
-								sizeof(tag);
+								sizeof(struct tag);
 	fe->descTag.descCRCLength = cpu_to_le16(crclen);
-	fe->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)fe + sizeof(tag),
+	fe->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)fe + sizeof(struct tag),
 						  crclen));
 	fe->descTag.tagChecksum = udf_tag_checksum(&fe->descTag);
 
@@ -1606,7 +1613,7 @@
 	return err;
 }
 
-struct inode *udf_iget(struct super_block *sb, kernel_lb_addr ino)
+struct inode *udf_iget(struct super_block *sb, struct kernel_lb_addr *ino)
 {
 	unsigned long block = udf_get_lb_pblock(sb, ino, 0);
 	struct inode *inode = iget_locked(sb, block);
@@ -1615,7 +1622,7 @@
 		return NULL;
 
 	if (inode->i_state & I_NEW) {
-		memcpy(&UDF_I(inode)->i_location, &ino, sizeof(kernel_lb_addr));
+		memcpy(&UDF_I(inode)->i_location, ino, sizeof(struct kernel_lb_addr));
 		__udf_read_inode(inode);
 		unlock_new_inode(inode);
 	}
@@ -1623,10 +1630,10 @@
 	if (is_bad_inode(inode))
 		goto out_iput;
 
-	if (ino.logicalBlockNum >= UDF_SB(sb)->
-			s_partmaps[ino.partitionReferenceNum].s_partition_len) {
+	if (ino->logicalBlockNum >= UDF_SB(sb)->
+			s_partmaps[ino->partitionReferenceNum].s_partition_len) {
 		udf_debug("block=%d, partition=%d out of range\n",
-			  ino.logicalBlockNum, ino.partitionReferenceNum);
+			  ino->logicalBlockNum, ino->partitionReferenceNum);
 		make_bad_inode(inode);
 		goto out_iput;
 	}
@@ -1639,11 +1646,11 @@
 }
 
 int8_t udf_add_aext(struct inode *inode, struct extent_position *epos,
-		    kernel_lb_addr eloc, uint32_t elen, int inc)
+		    struct kernel_lb_addr *eloc, uint32_t elen, int inc)
 {
 	int adsize;
-	short_ad *sad = NULL;
-	long_ad *lad = NULL;
+	struct short_ad *sad = NULL;
+	struct long_ad *lad = NULL;
 	struct allocExtDesc *aed;
 	int8_t etype;
 	uint8_t *ptr;
@@ -1657,9 +1664,9 @@
 		ptr = epos->bh->b_data + epos->offset;
 
 	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
-		adsize = sizeof(short_ad);
+		adsize = sizeof(struct short_ad);
 	else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
-		adsize = sizeof(long_ad);
+		adsize = sizeof(struct long_ad);
 	else
 		return -1;
 
@@ -1667,7 +1674,7 @@
 		char *sptr, *dptr;
 		struct buffer_head *nbh;
 		int err, loffset;
-		kernel_lb_addr obloc = epos->block;
+		struct kernel_lb_addr obloc = epos->block;
 
 		epos->block.logicalBlockNum = udf_new_block(inode->i_sb, NULL,
 						obloc.partitionReferenceNum,
@@ -1675,7 +1682,7 @@
 		if (!epos->block.logicalBlockNum)
 			return -1;
 		nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb,
-								 epos->block,
+								 &epos->block,
 								 0));
 		if (!nbh)
 			return -1;
@@ -1712,20 +1719,20 @@
 		}
 		if (UDF_SB(inode->i_sb)->s_udfrev >= 0x0200)
 			udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1,
-				    epos->block.logicalBlockNum, sizeof(tag));
+				    epos->block.logicalBlockNum, sizeof(struct tag));
 		else
 			udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1,
-				    epos->block.logicalBlockNum, sizeof(tag));
+				    epos->block.logicalBlockNum, sizeof(struct tag));
 		switch (iinfo->i_alloc_type) {
 		case ICBTAG_FLAG_AD_SHORT:
-			sad = (short_ad *)sptr;
+			sad = (struct short_ad *)sptr;
 			sad->extLength = cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS |
 						     inode->i_sb->s_blocksize);
 			sad->extPosition =
 				cpu_to_le32(epos->block.logicalBlockNum);
 			break;
 		case ICBTAG_FLAG_AD_LONG:
-			lad = (long_ad *)sptr;
+			lad = (struct long_ad *)sptr;
 			lad->extLength = cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS |
 						     inode->i_sb->s_blocksize);
 			lad->extLocation = cpu_to_lelb(epos->block);
@@ -1769,12 +1776,12 @@
 }
 
 int8_t udf_write_aext(struct inode *inode, struct extent_position *epos,
-		      kernel_lb_addr eloc, uint32_t elen, int inc)
+		      struct kernel_lb_addr *eloc, uint32_t elen, int inc)
 {
 	int adsize;
 	uint8_t *ptr;
-	short_ad *sad;
-	long_ad *lad;
+	struct short_ad *sad;
+	struct long_ad *lad;
 	struct udf_inode_info *iinfo = UDF_I(inode);
 
 	if (!epos->bh)
@@ -1786,17 +1793,17 @@
 
 	switch (iinfo->i_alloc_type) {
 	case ICBTAG_FLAG_AD_SHORT:
-		sad = (short_ad *)ptr;
+		sad = (struct short_ad *)ptr;
 		sad->extLength = cpu_to_le32(elen);
-		sad->extPosition = cpu_to_le32(eloc.logicalBlockNum);
-		adsize = sizeof(short_ad);
+		sad->extPosition = cpu_to_le32(eloc->logicalBlockNum);
+		adsize = sizeof(struct short_ad);
 		break;
 	case ICBTAG_FLAG_AD_LONG:
-		lad = (long_ad *)ptr;
+		lad = (struct long_ad *)ptr;
 		lad->extLength = cpu_to_le32(elen);
-		lad->extLocation = cpu_to_lelb(eloc);
+		lad->extLocation = cpu_to_lelb(*eloc);
 		memset(lad->impUse, 0x00, sizeof(lad->impUse));
-		adsize = sizeof(long_ad);
+		adsize = sizeof(struct long_ad);
 		break;
 	default:
 		return -1;
@@ -1823,7 +1830,7 @@
 }
 
 int8_t udf_next_aext(struct inode *inode, struct extent_position *epos,
-		     kernel_lb_addr *eloc, uint32_t *elen, int inc)
+		     struct kernel_lb_addr *eloc, uint32_t *elen, int inc)
 {
 	int8_t etype;
 
@@ -1833,7 +1840,7 @@
 		epos->block = *eloc;
 		epos->offset = sizeof(struct allocExtDesc);
 		brelse(epos->bh);
-		block = udf_get_lb_pblock(inode->i_sb, epos->block, 0);
+		block = udf_get_lb_pblock(inode->i_sb, &epos->block, 0);
 		epos->bh = udf_tread(inode->i_sb, block);
 		if (!epos->bh) {
 			udf_debug("reading block %d failed!\n", block);
@@ -1845,13 +1852,13 @@
 }
 
 int8_t udf_current_aext(struct inode *inode, struct extent_position *epos,
-			kernel_lb_addr *eloc, uint32_t *elen, int inc)
+			struct kernel_lb_addr *eloc, uint32_t *elen, int inc)
 {
 	int alen;
 	int8_t etype;
 	uint8_t *ptr;
-	short_ad *sad;
-	long_ad *lad;
+	struct short_ad *sad;
+	struct long_ad *lad;
 	struct udf_inode_info *iinfo = UDF_I(inode);
 
 	if (!epos->bh) {
@@ -1900,9 +1907,9 @@
 }
 
 static int8_t udf_insert_aext(struct inode *inode, struct extent_position epos,
-			      kernel_lb_addr neloc, uint32_t nelen)
+			      struct kernel_lb_addr neloc, uint32_t nelen)
 {
-	kernel_lb_addr oeloc;
+	struct kernel_lb_addr oeloc;
 	uint32_t oelen;
 	int8_t etype;
 
@@ -1910,18 +1917,18 @@
 		get_bh(epos.bh);
 
 	while ((etype = udf_next_aext(inode, &epos, &oeloc, &oelen, 0)) != -1) {
-		udf_write_aext(inode, &epos, neloc, nelen, 1);
+		udf_write_aext(inode, &epos, &neloc, nelen, 1);
 		neloc = oeloc;
 		nelen = (etype << 30) | oelen;
 	}
-	udf_add_aext(inode, &epos, neloc, nelen, 1);
+	udf_add_aext(inode, &epos, &neloc, nelen, 1);
 	brelse(epos.bh);
 
 	return (nelen >> 30);
 }
 
 int8_t udf_delete_aext(struct inode *inode, struct extent_position epos,
-		       kernel_lb_addr eloc, uint32_t elen)
+		       struct kernel_lb_addr eloc, uint32_t elen)
 {
 	struct extent_position oepos;
 	int adsize;
@@ -1936,9 +1943,9 @@
 
 	iinfo = UDF_I(inode);
 	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
-		adsize = sizeof(short_ad);
+		adsize = sizeof(struct short_ad);
 	else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
-		adsize = sizeof(long_ad);
+		adsize = sizeof(struct long_ad);
 	else
 		adsize = 0;
 
@@ -1947,7 +1954,7 @@
 		return -1;
 
 	while ((etype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) {
-		udf_write_aext(inode, &oepos, eloc, (etype << 30) | elen, 1);
+		udf_write_aext(inode, &oepos, &eloc, (etype << 30) | elen, 1);
 		if (oepos.bh != epos.bh) {
 			oepos.block = epos.block;
 			brelse(oepos.bh);
@@ -1956,13 +1963,13 @@
 			oepos.offset = epos.offset - adsize;
 		}
 	}
-	memset(&eloc, 0x00, sizeof(kernel_lb_addr));
+	memset(&eloc, 0x00, sizeof(struct kernel_lb_addr));
 	elen = 0;
 
 	if (epos.bh != oepos.bh) {
-		udf_free_blocks(inode->i_sb, inode, epos.block, 0, 1);
-		udf_write_aext(inode, &oepos, eloc, elen, 1);
-		udf_write_aext(inode, &oepos, eloc, elen, 1);
+		udf_free_blocks(inode->i_sb, inode, &epos.block, 0, 1);
+		udf_write_aext(inode, &oepos, &eloc, elen, 1);
+		udf_write_aext(inode, &oepos, &eloc, elen, 1);
 		if (!oepos.bh) {
 			iinfo->i_lenAlloc -= (adsize * 2);
 			mark_inode_dirty(inode);
@@ -1979,7 +1986,7 @@
 			mark_buffer_dirty_inode(oepos.bh, inode);
 		}
 	} else {
-		udf_write_aext(inode, &oepos, eloc, elen, 1);
+		udf_write_aext(inode, &oepos, &eloc, elen, 1);
 		if (!oepos.bh) {
 			iinfo->i_lenAlloc -= adsize;
 			mark_inode_dirty(inode);
@@ -2004,7 +2011,7 @@
 }
 
 int8_t inode_bmap(struct inode *inode, sector_t block,
-		  struct extent_position *pos, kernel_lb_addr *eloc,
+		  struct extent_position *pos, struct kernel_lb_addr *eloc,
 		  uint32_t *elen, sector_t *offset)
 {
 	unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
@@ -2036,7 +2043,7 @@
 
 long udf_block_map(struct inode *inode, sector_t block)
 {
-	kernel_lb_addr eloc;
+	struct kernel_lb_addr eloc;
 	uint32_t elen;
 	sector_t offset;
 	struct extent_position epos = {};
@@ -2046,7 +2053,7 @@
 
 	if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) ==
 						(EXT_RECORDED_ALLOCATED >> 30))
-		ret = udf_get_lb_pblock(inode->i_sb, eloc, offset);
+		ret = udf_get_lb_pblock(inode->i_sb, &eloc, offset);
 	else
 		ret = 0;
 
diff --git a/fs/udf/misc.c b/fs/udf/misc.c
index 84bf0fd..9215700 100644
--- a/fs/udf/misc.c
+++ b/fs/udf/misc.c
@@ -134,10 +134,10 @@
 			}
 		}
 		/* rewrite CRC + checksum of eahd */
-		crclen = sizeof(struct extendedAttrHeaderDesc) - sizeof(tag);
+		crclen = sizeof(struct extendedAttrHeaderDesc) - sizeof(struct tag);
 		eahd->descTag.descCRCLength = cpu_to_le16(crclen);
 		eahd->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)eahd +
-						sizeof(tag), crclen));
+						sizeof(struct tag), crclen));
 		eahd->descTag.tagChecksum = udf_tag_checksum(&eahd->descTag);
 		iinfo->i_lenEAttr += size;
 		return (struct genericFormat *)&ea[offset];
@@ -202,7 +202,7 @@
 struct buffer_head *udf_read_tagged(struct super_block *sb, uint32_t block,
 				    uint32_t location, uint16_t *ident)
 {
-	tag *tag_p;
+	struct tag *tag_p;
 	struct buffer_head *bh = NULL;
 
 	/* Read the block */
@@ -216,7 +216,7 @@
 		return NULL;
 	}
 
-	tag_p = (tag *)(bh->b_data);
+	tag_p = (struct tag *)(bh->b_data);
 
 	*ident = le16_to_cpu(tag_p->tagIdent);
 
@@ -241,9 +241,9 @@
 	}
 
 	/* Verify the descriptor CRC */
-	if (le16_to_cpu(tag_p->descCRCLength) + sizeof(tag) > sb->s_blocksize ||
+	if (le16_to_cpu(tag_p->descCRCLength) + sizeof(struct tag) > sb->s_blocksize ||
 	    le16_to_cpu(tag_p->descCRC) == crc_itu_t(0,
-					bh->b_data + sizeof(tag),
+					bh->b_data + sizeof(struct tag),
 					le16_to_cpu(tag_p->descCRCLength)))
 		return bh;
 
@@ -255,27 +255,28 @@
 	return NULL;
 }
 
-struct buffer_head *udf_read_ptagged(struct super_block *sb, kernel_lb_addr loc,
+struct buffer_head *udf_read_ptagged(struct super_block *sb,
+				     struct kernel_lb_addr *loc,
 				     uint32_t offset, uint16_t *ident)
 {
 	return udf_read_tagged(sb, udf_get_lb_pblock(sb, loc, offset),
-			       loc.logicalBlockNum + offset, ident);
+			       loc->logicalBlockNum + offset, ident);
 }
 
 void udf_update_tag(char *data, int length)
 {
-	tag *tptr = (tag *)data;
-	length -= sizeof(tag);
+	struct tag *tptr = (struct tag *)data;
+	length -= sizeof(struct tag);
 
 	tptr->descCRCLength = cpu_to_le16(length);
-	tptr->descCRC = cpu_to_le16(crc_itu_t(0, data + sizeof(tag), length));
+	tptr->descCRC = cpu_to_le16(crc_itu_t(0, data + sizeof(struct tag), length));
 	tptr->tagChecksum = udf_tag_checksum(tptr);
 }
 
 void udf_new_tag(char *data, uint16_t ident, uint16_t version, uint16_t snum,
 		 uint32_t loc, int length)
 {
-	tag *tptr = (tag *)data;
+	struct tag *tptr = (struct tag *)data;
 	tptr->tagIdent = cpu_to_le16(ident);
 	tptr->descVersion = cpu_to_le16(version);
 	tptr->tagSerialNum = cpu_to_le16(snum);
@@ -283,12 +284,12 @@
 	udf_update_tag(data, length);
 }
 
-u8 udf_tag_checksum(const tag *t)
+u8 udf_tag_checksum(const struct tag *t)
 {
 	u8 *data = (u8 *)t;
 	u8 checksum = 0;
 	int i;
-	for (i = 0; i < sizeof(tag); ++i)
+	for (i = 0; i < sizeof(struct tag); ++i)
 		if (i != 4) /* position of checksum */
 			checksum += data[i];
 	return checksum;
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index f84bfaa..6a29fa34 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -47,7 +47,7 @@
 		 struct fileIdentDesc *sfi, struct udf_fileident_bh *fibh,
 		 uint8_t *impuse, uint8_t *fileident)
 {
-	uint16_t crclen = fibh->eoffset - fibh->soffset - sizeof(tag);
+	uint16_t crclen = fibh->eoffset - fibh->soffset - sizeof(struct tag);
 	uint16_t crc;
 	int offset;
 	uint16_t liu = le16_to_cpu(cfi->lengthOfImpUse);
@@ -99,18 +99,18 @@
 		memset(fibh->ebh->b_data, 0x00, padlen + offset);
 	}
 
-	crc = crc_itu_t(0, (uint8_t *)cfi + sizeof(tag),
-		      sizeof(struct fileIdentDesc) - sizeof(tag));
+	crc = crc_itu_t(0, (uint8_t *)cfi + sizeof(struct tag),
+		      sizeof(struct fileIdentDesc) - sizeof(struct tag));
 
 	if (fibh->sbh == fibh->ebh) {
 		crc = crc_itu_t(crc, (uint8_t *)sfi->impUse,
-			      crclen + sizeof(tag) -
+			      crclen + sizeof(struct tag) -
 			      sizeof(struct fileIdentDesc));
 	} else if (sizeof(struct fileIdentDesc) >= -fibh->soffset) {
 		crc = crc_itu_t(crc, fibh->ebh->b_data +
 					sizeof(struct fileIdentDesc) +
 					fibh->soffset,
-			      crclen + sizeof(tag) -
+			      crclen + sizeof(struct tag) -
 					sizeof(struct fileIdentDesc));
 	} else {
 		crc = crc_itu_t(crc, (uint8_t *)sfi->impUse,
@@ -154,7 +154,7 @@
 	uint8_t lfi;
 	uint16_t liu;
 	loff_t size;
-	kernel_lb_addr eloc;
+	struct kernel_lb_addr eloc;
 	uint32_t elen;
 	sector_t offset;
 	struct extent_position epos = {};
@@ -171,12 +171,12 @@
 		if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits, &epos,
 		    &eloc, &elen, &offset) != (EXT_RECORDED_ALLOCATED >> 30))
 			goto out_err;
-		block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
+		block = udf_get_lb_pblock(dir->i_sb, &eloc, offset);
 		if ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
 			if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
-				epos.offset -= sizeof(short_ad);
+				epos.offset -= sizeof(struct short_ad);
 			else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
-				epos.offset -= sizeof(long_ad);
+				epos.offset -= sizeof(struct long_ad);
 		} else
 			offset = 0;
 
@@ -268,7 +268,7 @@
 #ifdef UDF_RECOVERY
 	/* temporary shorthand for specifying files by inode number */
 	if (!strncmp(dentry->d_name.name, ".B=", 3)) {
-		kernel_lb_addr lb = {
+		struct kernel_lb_addr lb = {
 			.logicalBlockNum = 0,
 			.partitionReferenceNum =
 				simple_strtoul(dentry->d_name.name + 3,
@@ -283,11 +283,14 @@
 #endif /* UDF_RECOVERY */
 
 	if (udf_find_entry(dir, &dentry->d_name, &fibh, &cfi)) {
+		struct kernel_lb_addr loc;
+
 		if (fibh.sbh != fibh.ebh)
 			brelse(fibh.ebh);
 		brelse(fibh.sbh);
 
-		inode = udf_iget(dir->i_sb, lelb_to_cpu(cfi.icb.extLocation));
+		loc = lelb_to_cpu(cfi.icb.extLocation);
+		inode = udf_iget(dir->i_sb, &loc);
 		if (!inode) {
 			unlock_kernel();
 			return ERR_PTR(-EACCES);
@@ -313,7 +316,7 @@
 	uint8_t lfi;
 	uint16_t liu;
 	int block;
-	kernel_lb_addr eloc;
+	struct kernel_lb_addr eloc;
 	uint32_t elen = 0;
 	sector_t offset;
 	struct extent_position epos = {};
@@ -351,16 +354,16 @@
 		if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits, &epos,
 		    &eloc, &elen, &offset) != (EXT_RECORDED_ALLOCATED >> 30)) {
 			block = udf_get_lb_pblock(dir->i_sb,
-					dinfo->i_location, 0);
+					&dinfo->i_location, 0);
 			fibh->soffset = fibh->eoffset = sb->s_blocksize;
 			goto add;
 		}
-		block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
+		block = udf_get_lb_pblock(dir->i_sb, &eloc, offset);
 		if ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
 			if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
-				epos.offset -= sizeof(short_ad);
+				epos.offset -= sizeof(struct short_ad);
 			else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
-				epos.offset -= sizeof(long_ad);
+				epos.offset -= sizeof(struct long_ad);
 		} else
 			offset = 0;
 
@@ -409,10 +412,10 @@
 	if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB && elen) {
 		elen = (elen + sb->s_blocksize - 1) & ~(sb->s_blocksize - 1);
 		if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
-			epos.offset -= sizeof(short_ad);
+			epos.offset -= sizeof(struct short_ad);
 		else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
-			epos.offset -= sizeof(long_ad);
-		udf_write_aext(dir, &epos, eloc, elen, 1);
+			epos.offset -= sizeof(struct long_ad);
+		udf_write_aext(dir, &epos, &eloc, elen, 1);
 	}
 	f_pos += nfidlen;
 
@@ -494,10 +497,10 @@
 	memset(cfi, 0, sizeof(struct fileIdentDesc));
 	if (UDF_SB(sb)->s_udfrev >= 0x0200)
 		udf_new_tag((char *)cfi, TAG_IDENT_FID, 3, 1, block,
-			    sizeof(tag));
+			    sizeof(struct tag));
 	else
 		udf_new_tag((char *)cfi, TAG_IDENT_FID, 2, 1, block,
-			    sizeof(tag));
+			    sizeof(struct tag));
 	cfi->fileVersionNum = cpu_to_le16(1);
 	cfi->lengthFileIdent = namelen;
 	cfi->lengthOfImpUse = cpu_to_le16(0);
@@ -530,7 +533,7 @@
 	cfi->fileCharacteristics |= FID_FILE_CHAR_DELETED;
 
 	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT))
-		memset(&(cfi->icb), 0x00, sizeof(long_ad));
+		memset(&(cfi->icb), 0x00, sizeof(struct long_ad));
 
 	return udf_write_fi(inode, cfi, fi, fibh, NULL, NULL);
 }
@@ -710,7 +713,7 @@
 	loff_t f_pos;
 	loff_t size = udf_ext0_offset(dir) + dir->i_size;
 	int block;
-	kernel_lb_addr eloc;
+	struct kernel_lb_addr eloc;
 	uint32_t elen;
 	sector_t offset;
 	struct extent_position epos = {};
@@ -724,12 +727,12 @@
 	else if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits,
 			      &epos, &eloc, &elen, &offset) ==
 					(EXT_RECORDED_ALLOCATED >> 30)) {
-		block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
+		block = udf_get_lb_pblock(dir->i_sb, &eloc, offset);
 		if ((++offset << dir->i_sb->s_blocksize_bits) < elen) {
 			if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
-				epos.offset -= sizeof(short_ad);
+				epos.offset -= sizeof(struct short_ad);
 			else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
-				epos.offset -= sizeof(long_ad);
+				epos.offset -= sizeof(struct long_ad);
 		} else
 			offset = 0;
 
@@ -778,7 +781,7 @@
 	struct inode *inode = dentry->d_inode;
 	struct udf_fileident_bh fibh;
 	struct fileIdentDesc *fi, cfi;
-	kernel_lb_addr tloc;
+	struct kernel_lb_addr tloc;
 
 	retval = -ENOENT;
 	lock_kernel();
@@ -788,7 +791,7 @@
 
 	retval = -EIO;
 	tloc = lelb_to_cpu(cfi.icb.extLocation);
-	if (udf_get_lb_pblock(dir->i_sb, tloc, 0) != inode->i_ino)
+	if (udf_get_lb_pblock(dir->i_sb, &tloc, 0) != inode->i_ino)
 		goto end_rmdir;
 	retval = -ENOTEMPTY;
 	if (!empty_dir(inode))
@@ -824,7 +827,7 @@
 	struct udf_fileident_bh fibh;
 	struct fileIdentDesc *fi;
 	struct fileIdentDesc cfi;
-	kernel_lb_addr tloc;
+	struct kernel_lb_addr tloc;
 
 	retval = -ENOENT;
 	lock_kernel();
@@ -834,7 +837,7 @@
 
 	retval = -EIO;
 	tloc = lelb_to_cpu(cfi.icb.extLocation);
-	if (udf_get_lb_pblock(dir->i_sb, tloc, 0) != inode->i_ino)
+	if (udf_get_lb_pblock(dir->i_sb, &tloc, 0) != inode->i_ino)
 		goto end_unlink;
 
 	if (!inode->i_nlink) {
@@ -897,7 +900,7 @@
 	inode->i_op = &page_symlink_inode_operations;
 
 	if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
-		kernel_lb_addr eloc;
+		struct kernel_lb_addr eloc;
 		uint32_t bsize;
 
 		block = udf_new_block(inode->i_sb, inode,
@@ -913,7 +916,7 @@
 				iinfo->i_location.partitionReferenceNum;
 		bsize = inode->i_sb->s_blocksize;
 		iinfo->i_lenExtents = bsize;
-		udf_add_aext(inode, &epos, eloc, bsize, 0);
+		udf_add_aext(inode, &epos, &eloc, bsize, 0);
 		brelse(epos.bh);
 
 		block = udf_get_pblock(inode->i_sb, block,
@@ -1108,7 +1111,7 @@
 	struct fileIdentDesc ocfi, ncfi;
 	struct buffer_head *dir_bh = NULL;
 	int retval = -ENOENT;
-	kernel_lb_addr tloc;
+	struct kernel_lb_addr tloc;
 	struct udf_inode_info *old_iinfo = UDF_I(old_inode);
 
 	lock_kernel();
@@ -1119,7 +1122,7 @@
 		brelse(ofibh.sbh);
 	}
 	tloc = lelb_to_cpu(ocfi.icb.extLocation);
-	if (!ofi || udf_get_lb_pblock(old_dir->i_sb, tloc, 0)
+	if (!ofi || udf_get_lb_pblock(old_dir->i_sb, &tloc, 0)
 	    != old_inode->i_ino)
 		goto end_rename;
 
@@ -1158,7 +1161,7 @@
 		if (!dir_fi)
 			goto end_rename;
 		tloc = lelb_to_cpu(dir_fi->icb.extLocation);
-		if (udf_get_lb_pblock(old_inode->i_sb, tloc, 0) !=
+		if (udf_get_lb_pblock(old_inode->i_sb, &tloc, 0) !=
 				old_dir->i_ino)
 			goto end_rename;
 
@@ -1187,7 +1190,7 @@
 	 */
 	ncfi.fileVersionNum = ocfi.fileVersionNum;
 	ncfi.fileCharacteristics = ocfi.fileCharacteristics;
-	memcpy(&(ncfi.icb), &(ocfi.icb), sizeof(long_ad));
+	memcpy(&(ncfi.icb), &(ocfi.icb), sizeof(struct long_ad));
 	udf_write_fi(new_dir, &ncfi, nfi, &nfibh, NULL, NULL);
 
 	/* The old fid may have moved - find it again */
@@ -1242,6 +1245,7 @@
 
 static struct dentry *udf_get_parent(struct dentry *child)
 {
+	struct kernel_lb_addr tloc;
 	struct inode *inode = NULL;
 	struct qstr dotdot = {.name = "..", .len = 2};
 	struct fileIdentDesc cfi;
@@ -1255,8 +1259,8 @@
 		brelse(fibh.ebh);
 	brelse(fibh.sbh);
 
-	inode = udf_iget(child->d_inode->i_sb,
-			 lelb_to_cpu(cfi.icb.extLocation));
+	tloc = lelb_to_cpu(cfi.icb.extLocation);
+	inode = udf_iget(child->d_inode->i_sb, &tloc);
 	if (!inode)
 		goto out_unlock;
 	unlock_kernel();
@@ -1272,14 +1276,14 @@
 					u16 partref, __u32 generation)
 {
 	struct inode *inode;
-	kernel_lb_addr loc;
+	struct kernel_lb_addr loc;
 
 	if (block == 0)
 		return ERR_PTR(-ESTALE);
 
 	loc.logicalBlockNum = block;
 	loc.partitionReferenceNum = partref;
-	inode = udf_iget(sb, loc);
+	inode = udf_iget(sb, &loc);
 
 	if (inode == NULL)
 		return ERR_PTR(-ENOMEM);
@@ -1318,7 +1322,7 @@
 {
 	int len = *lenp;
 	struct inode *inode =  de->d_inode;
-	kernel_lb_addr location = UDF_I(inode)->i_location;
+	struct kernel_lb_addr location = UDF_I(inode)->i_location;
 	struct fid *fid = (struct fid *)fh;
 	int type = FILEID_UDF_WITHOUT_PARENT;
 
diff --git a/fs/udf/osta_udf.h b/fs/udf/osta_udf.h
index 65ff479..fbff746 100644
--- a/fs/udf/osta_udf.h
+++ b/fs/udf/osta_udf.h
@@ -85,7 +85,7 @@
 /* Logical Volume Integrity Descriptor (UDF 2.50 2.2.6) */
 /* Implementation Use (UDF 2.50 2.2.6.4) */
 struct logicalVolIntegrityDescImpUse {
-	regid		impIdent;
+	struct regid	impIdent;
 	__le32		numFiles;
 	__le32		numDirs;
 	__le16		minUDFReadRev;
@@ -97,12 +97,12 @@
 /* Implementation Use Volume Descriptor (UDF 2.50 2.2.7) */
 /* Implementation Use (UDF 2.50 2.2.7.2) */
 struct impUseVolDescImpUse {
-	charspec	LVICharset;
+	struct charspec	LVICharset;
 	dstring		logicalVolIdent[128];
 	dstring		LVInfo1[36];
 	dstring		LVInfo2[36];
 	dstring		LVInfo3[36];
-	regid		impIdent;
+	struct regid	impIdent;
 	uint8_t		impUse[128];
 } __attribute__ ((packed));
 
@@ -110,7 +110,7 @@
 	uint8_t		partitionMapType;
 	uint8_t		partitionMapLength;
 	uint8_t		reserved1[2];
-	regid		partIdent;
+	struct regid	partIdent;
 	__le16		volSeqNum;
 	__le16		partitionNum;
 } __attribute__ ((packed));
@@ -120,7 +120,7 @@
 	uint8_t		partitionMapType;
 	uint8_t		partitionMapLength;
 	uint8_t		reserved1[2];
-	regid		partIdent;
+	struct regid	partIdent;
 	__le16		volSeqNum;
 	__le16		partitionNum;
 	uint8_t		reserved2[24];
@@ -131,7 +131,7 @@
 	uint8_t partitionMapType;
 	uint8_t partitionMapLength;
 	uint8_t reserved1[2];
-	regid partIdent;
+	struct regid partIdent;
 	__le16 volSeqNum;
 	__le16 partitionNum;
 	__le16 packetLength;
@@ -146,7 +146,7 @@
 	uint8_t		partitionMapType;
 	uint8_t		partitionMapLength;
 	uint8_t		reserved1[2];
-	regid		partIdent;
+	struct regid	partIdent;
 	__le16		volSeqNum;
 	__le16		partitionNum;
 	__le32		metadataFileLoc;
@@ -161,7 +161,7 @@
 /* Virtual Allocation Table (UDF 1.5 2.2.10) */
 struct virtualAllocationTable15 {
 	__le32		VirtualSector[0];
-	regid		vatIdent;
+	struct regid	vatIdent;
 	__le32		previousVATICBLoc;
 } __attribute__ ((packed));
 
@@ -192,8 +192,8 @@
 } __attribute__ ((packed));
 
 struct sparingTable {
-	tag 		descTag;
-	regid		sparingIdent;
+	struct tag	descTag;
+	struct regid	sparingIdent;
 	__le16		reallocationTableLen;
 	__le16		reserved;
 	__le32		sequenceNum;
@@ -206,7 +206,7 @@
 #define ICBTAG_FILE_TYPE_MIRROR		0xFB
 #define ICBTAG_FILE_TYPE_BITMAP		0xFC
 
-/* struct long_ad ICB - ADImpUse (UDF 2.50 2.2.4.3) */
+/* struct struct long_ad ICB - ADImpUse (UDF 2.50 2.2.4.3) */
 struct allocDescImpUse {
 	__le16		flags;
 	uint8_t		impUse[4];
diff --git a/fs/udf/partition.c b/fs/udf/partition.c
index 96dfd20..4b540ee 100644
--- a/fs/udf/partition.c
+++ b/fs/udf/partition.c
@@ -273,7 +273,7 @@
 {
 	struct super_block *sb = inode->i_sb;
 	struct udf_part_map *map;
-	kernel_lb_addr eloc;
+	struct kernel_lb_addr eloc;
 	uint32_t elen;
 	sector_t ext_offset;
 	struct extent_position epos = {};
diff --git a/fs/udf/super.c b/fs/udf/super.c
index e25e701..72348cc 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -81,16 +81,13 @@
 /* These are the "meat" - everything else is stuffing */
 static int udf_fill_super(struct super_block *, void *, int);
 static void udf_put_super(struct super_block *);
-static void udf_write_super(struct super_block *);
+static int udf_sync_fs(struct super_block *, int);
 static int udf_remount_fs(struct super_block *, int *, char *);
-static int udf_check_valid(struct super_block *, int, int);
-static int udf_vrs(struct super_block *sb, int silent);
-static void udf_load_logicalvolint(struct super_block *, kernel_extent_ad);
-static void udf_find_anchor(struct super_block *);
-static int udf_find_fileset(struct super_block *, kernel_lb_addr *,
-			    kernel_lb_addr *);
+static void udf_load_logicalvolint(struct super_block *, struct kernel_extent_ad);
+static int udf_find_fileset(struct super_block *, struct kernel_lb_addr *,
+			    struct kernel_lb_addr *);
 static void udf_load_fileset(struct super_block *, struct buffer_head *,
-			     kernel_lb_addr *);
+			     struct kernel_lb_addr *);
 static void udf_open_lvid(struct super_block *);
 static void udf_close_lvid(struct super_block *);
 static unsigned int udf_count_free(struct super_block *);
@@ -181,7 +178,7 @@
 	.delete_inode	= udf_delete_inode,
 	.clear_inode	= udf_clear_inode,
 	.put_super	= udf_put_super,
-	.write_super	= udf_write_super,
+	.sync_fs	= udf_sync_fs,
 	.statfs		= udf_statfs,
 	.remount_fs	= udf_remount_fs,
 	.show_options	= udf_show_options,
@@ -201,6 +198,8 @@
 	mode_t umask;
 	gid_t gid;
 	uid_t uid;
+	mode_t fmode;
+	mode_t dmode;
 	struct nls_table *nls_map;
 };
 
@@ -258,7 +257,7 @@
 
 	if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT))
 		seq_puts(seq, ",nostrict");
-	if (sb->s_blocksize != UDF_DEFAULT_BLOCKSIZE)
+	if (UDF_QUERY_FLAG(sb, UDF_FLAG_BLOCKSIZE_SET))
 		seq_printf(seq, ",bs=%lu", sb->s_blocksize);
 	if (UDF_QUERY_FLAG(sb, UDF_FLAG_UNHIDE))
 		seq_puts(seq, ",unhide");
@@ -282,18 +281,16 @@
 		seq_printf(seq, ",gid=%u", sbi->s_gid);
 	if (sbi->s_umask != 0)
 		seq_printf(seq, ",umask=%o", sbi->s_umask);
+	if (sbi->s_fmode != UDF_INVALID_MODE)
+		seq_printf(seq, ",mode=%o", sbi->s_fmode);
+	if (sbi->s_dmode != UDF_INVALID_MODE)
+		seq_printf(seq, ",dmode=%o", sbi->s_dmode);
 	if (UDF_QUERY_FLAG(sb, UDF_FLAG_SESSION_SET))
 		seq_printf(seq, ",session=%u", sbi->s_session);
 	if (UDF_QUERY_FLAG(sb, UDF_FLAG_LASTBLOCK_SET))
 		seq_printf(seq, ",lastblock=%u", sbi->s_last_block);
-	/*
-	 * s_anchor[2] could be zeroed out in case there is no anchor
-	 * in the specified block, but then the "anchor=N" option
-	 * originally given by the user wasn't effective, so it's OK
-	 * if we don't show it.
-	 */
-	if (sbi->s_anchor[2] != 0)
-		seq_printf(seq, ",anchor=%u", sbi->s_anchor[2]);
+	if (sbi->s_anchor != 0)
+		seq_printf(seq, ",anchor=%u", sbi->s_anchor);
 	/*
 	 * volume, partition, fileset and rootdir seem to be ignored
 	 * currently
@@ -317,6 +314,8 @@
  *
  *	gid=		Set the default group.
  *	umask=		Set the default umask.
+ *	mode=		Set the default file permissions.
+ *	dmode=		Set the default directory permissions.
  *	uid=		Set the default user.
  *	bs=		Set the block size.
  *	unhide		Show otherwise hidden files.
@@ -366,7 +365,8 @@
 	Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock,
 	Opt_anchor, Opt_volume, Opt_partition, Opt_fileset,
 	Opt_rootdir, Opt_utf8, Opt_iocharset,
-	Opt_err, Opt_uforget, Opt_uignore, Opt_gforget, Opt_gignore
+	Opt_err, Opt_uforget, Opt_uignore, Opt_gforget, Opt_gignore,
+	Opt_fmode, Opt_dmode
 };
 
 static const match_table_t tokens = {
@@ -395,6 +395,8 @@
 	{Opt_rootdir,	"rootdir=%u"},
 	{Opt_utf8,	"utf8"},
 	{Opt_iocharset,	"iocharset=%s"},
+	{Opt_fmode,     "mode=%o"},
+	{Opt_dmode,     "dmode=%o"},
 	{Opt_err,	NULL}
 };
 
@@ -405,7 +407,6 @@
 	int option;
 
 	uopt->novrs = 0;
-	uopt->blocksize = UDF_DEFAULT_BLOCKSIZE;
 	uopt->partition = 0xFFFF;
 	uopt->session = 0xFFFFFFFF;
 	uopt->lastblock = 0;
@@ -428,10 +429,12 @@
 		switch (token) {
 		case Opt_novrs:
 			uopt->novrs = 1;
+			break;
 		case Opt_bs:
 			if (match_int(&args[0], &option))
 				return 0;
 			uopt->blocksize = option;
+			uopt->flags |= (1 << UDF_FLAG_BLOCKSIZE_SET);
 			break;
 		case Opt_unhide:
 			uopt->flags |= (1 << UDF_FLAG_UNHIDE);
@@ -531,6 +534,16 @@
 		case Opt_gforget:
 			uopt->flags |= (1 << UDF_FLAG_GID_FORGET);
 			break;
+		case Opt_fmode:
+			if (match_octal(args, &option))
+				return 0;
+			uopt->fmode = option & 0777;
+			break;
+		case Opt_dmode:
+			if (match_octal(args, &option))
+				return 0;
+			uopt->dmode = option & 0777;
+			break;
 		default:
 			printk(KERN_ERR "udf: bad mount option \"%s\" "
 			       "or missing value\n", p);
@@ -540,17 +553,6 @@
 	return 1;
 }
 
-static void udf_write_super(struct super_block *sb)
-{
-	lock_kernel();
-
-	if (!(sb->s_flags & MS_RDONLY))
-		udf_open_lvid(sb);
-	sb->s_dirt = 0;
-
-	unlock_kernel();
-}
-
 static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
 {
 	struct udf_options uopt;
@@ -560,6 +562,8 @@
 	uopt.uid   = sbi->s_uid;
 	uopt.gid   = sbi->s_gid;
 	uopt.umask = sbi->s_umask;
+	uopt.fmode = sbi->s_fmode;
+	uopt.dmode = sbi->s_dmode;
 
 	if (!udf_parse_options(options, &uopt, true))
 		return -EINVAL;
@@ -568,6 +572,8 @@
 	sbi->s_uid   = uopt.uid;
 	sbi->s_gid   = uopt.gid;
 	sbi->s_umask = uopt.umask;
+	sbi->s_fmode = uopt.fmode;
+	sbi->s_dmode = uopt.dmode;
 
 	if (sbi->s_lvid_bh) {
 		int write_rev = le16_to_cpu(udf_sb_lvidiu(sbi)->minUDFWriteRev);
@@ -585,22 +591,19 @@
 	return 0;
 }
 
-static int udf_vrs(struct super_block *sb, int silent)
+/* Check Volume Structure Descriptors (ECMA 167 2/9.1) */
+/* We also check any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) */
+static loff_t udf_check_vsd(struct super_block *sb)
 {
 	struct volStructDesc *vsd = NULL;
 	loff_t sector = 32768;
 	int sectorsize;
 	struct buffer_head *bh = NULL;
-	int iso9660 = 0;
 	int nsr02 = 0;
 	int nsr03 = 0;
 	struct udf_sb_info *sbi;
 
-	/* Block size must be a multiple of 512 */
-	if (sb->s_blocksize & 511)
-		return 0;
 	sbi = UDF_SB(sb);
-
 	if (sb->s_blocksize < sizeof(struct volStructDesc))
 		sectorsize = sizeof(struct volStructDesc);
 	else
@@ -627,7 +630,6 @@
 			break;
 		} else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001,
 				    VSD_STD_ID_LEN)) {
-			iso9660 = sector;
 			switch (vsd->structType) {
 			case 0:
 				udf_debug("ISO9660 Boot Record found\n");
@@ -679,139 +681,9 @@
 		return 0;
 }
 
-/*
- * Check whether there is an anchor block in the given block
- */
-static int udf_check_anchor_block(struct super_block *sb, sector_t block)
-{
-	struct buffer_head *bh;
-	uint16_t ident;
-
-	if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV) &&
-	    udf_fixed_to_variable(block) >=
-	    sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits)
-		return 0;
-
-	bh = udf_read_tagged(sb, block, block, &ident);
-	if (!bh)
-		return 0;
-	brelse(bh);
-
-	return ident == TAG_IDENT_AVDP;
-}
-
-/* Search for an anchor volume descriptor pointer */
-static sector_t udf_scan_anchors(struct super_block *sb, sector_t lastblock)
-{
-	sector_t last[6];
-	int i;
-	struct udf_sb_info *sbi = UDF_SB(sb);
-
-	last[0] = lastblock;
-	last[1] = last[0] - 1;
-	last[2] = last[0] + 1;
-	last[3] = last[0] - 2;
-	last[4] = last[0] - 150;
-	last[5] = last[0] - 152;
-
-	/*  according to spec, anchor is in either:
-	 *     block 256
-	 *     lastblock-256
-	 *     lastblock
-	 *  however, if the disc isn't closed, it could be 512 */
-
-	for (i = 0; i < ARRAY_SIZE(last); i++) {
-		if (last[i] < 0)
-			continue;
-		if (last[i] >= sb->s_bdev->bd_inode->i_size >>
-				sb->s_blocksize_bits)
-			continue;
-
-		if (udf_check_anchor_block(sb, last[i])) {
-			sbi->s_anchor[0] = last[i];
-			sbi->s_anchor[1] = last[i] - 256;
-			return last[i];
-		}
-
-		if (last[i] < 256)
-			continue;
-
-		if (udf_check_anchor_block(sb, last[i] - 256)) {
-			sbi->s_anchor[1] = last[i] - 256;
-			return last[i];
-		}
-	}
-
-	if (udf_check_anchor_block(sb, sbi->s_session + 256)) {
-		sbi->s_anchor[0] = sbi->s_session + 256;
-		return last[0];
-	}
-	if (udf_check_anchor_block(sb, sbi->s_session + 512)) {
-		sbi->s_anchor[0] = sbi->s_session + 512;
-		return last[0];
-	}
-	return 0;
-}
-
-/*
- * Find an anchor volume descriptor. The function expects sbi->s_lastblock to
- * be the last block on the media.
- *
- * Return 1 if not found, 0 if ok
- *
- */
-static void udf_find_anchor(struct super_block *sb)
-{
-	sector_t lastblock;
-	struct buffer_head *bh = NULL;
-	uint16_t ident;
-	int i;
-	struct udf_sb_info *sbi = UDF_SB(sb);
-
-	lastblock = udf_scan_anchors(sb, sbi->s_last_block);
-	if (lastblock)
-		goto check_anchor;
-
-	/* No anchor found? Try VARCONV conversion of block numbers */
-	UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
-	/* Firstly, we try to not convert number of the last block */
-	lastblock = udf_scan_anchors(sb,
-				udf_variable_to_fixed(sbi->s_last_block));
-	if (lastblock)
-		goto check_anchor;
-
-	/* Secondly, we try with converted number of the last block */
-	lastblock = udf_scan_anchors(sb, sbi->s_last_block);
-	if (!lastblock) {
-		/* VARCONV didn't help. Clear it. */
-		UDF_CLEAR_FLAG(sb, UDF_FLAG_VARCONV);
-	}
-
-check_anchor:
-	/*
-	 * Check located anchors and the anchor block supplied via
-	 * mount options
-	 */
-	for (i = 0; i < ARRAY_SIZE(sbi->s_anchor); i++) {
-		if (!sbi->s_anchor[i])
-			continue;
-		bh = udf_read_tagged(sb, sbi->s_anchor[i],
-					sbi->s_anchor[i], &ident);
-		if (!bh)
-			sbi->s_anchor[i] = 0;
-		else {
-			brelse(bh);
-			if (ident != TAG_IDENT_AVDP)
-				sbi->s_anchor[i] = 0;
-		}
-	}
-
-	sbi->s_last_block = lastblock;
-}
-
 static int udf_find_fileset(struct super_block *sb,
-			    kernel_lb_addr *fileset,
-			    kernel_lb_addr *root)
+			    struct kernel_lb_addr *fileset,
+			    struct kernel_lb_addr *root)
 {
 	struct buffer_head *bh = NULL;
 	long lastblock;
@@ -820,7 +692,7 @@
 
 	if (fileset->logicalBlockNum != 0xFFFFFFFF ||
 	    fileset->partitionReferenceNum != 0xFFFF) {
-		bh = udf_read_ptagged(sb, *fileset, 0, &ident);
+		bh = udf_read_ptagged(sb, fileset, 0, &ident);
 
 		if (!bh) {
 			return 1;
@@ -834,7 +706,7 @@
 	sbi = UDF_SB(sb);
 	if (!bh) {
 		/* Search backwards through the partitions */
-		kernel_lb_addr newfileset;
+		struct kernel_lb_addr newfileset;
 
 /* --> cvg: FIXME - is it reasonable? */
 		return 1;
@@ -850,7 +722,7 @@
 			newfileset.logicalBlockNum = 0;
 
 			do {
-				bh = udf_read_ptagged(sb, newfileset, 0,
+				bh = udf_read_ptagged(sb, &newfileset, 0,
 						      &ident);
 				if (!bh) {
 					newfileset.logicalBlockNum++;
@@ -902,14 +774,23 @@
 static int udf_load_pvoldesc(struct super_block *sb, sector_t block)
 {
 	struct primaryVolDesc *pvoldesc;
-	struct ustr instr;
-	struct ustr outstr;
+	struct ustr *instr, *outstr;
 	struct buffer_head *bh;
 	uint16_t ident;
+	int ret = 1;
+
+	instr = kmalloc(sizeof(struct ustr), GFP_NOFS);
+	if (!instr)
+		return 1;
+
+	outstr = kmalloc(sizeof(struct ustr), GFP_NOFS);
+	if (!outstr)
+		goto out1;
 
 	bh = udf_read_tagged(sb, block, block, &ident);
 	if (!bh)
-		return 1;
+		goto out2;
+
 	BUG_ON(ident != TAG_IDENT_PVD);
 
 	pvoldesc = (struct primaryVolDesc *)bh->b_data;
@@ -917,7 +798,7 @@
 	if (udf_disk_stamp_to_time(&UDF_SB(sb)->s_record_time,
 			      pvoldesc->recordingDateAndTime)) {
 #ifdef UDFFS_DEBUG
-		timestamp *ts = &pvoldesc->recordingDateAndTime;
+		struct timestamp *ts = &pvoldesc->recordingDateAndTime;
 		udf_debug("recording time %04u/%02u/%02u"
 			  " %02u:%02u (%x)\n",
 			  le16_to_cpu(ts->year), ts->month, ts->day, ts->hour,
@@ -925,20 +806,25 @@
 #endif
 	}
 
-	if (!udf_build_ustr(&instr, pvoldesc->volIdent, 32))
-		if (udf_CS0toUTF8(&outstr, &instr)) {
-			strncpy(UDF_SB(sb)->s_volume_ident, outstr.u_name,
-				outstr.u_len > 31 ? 31 : outstr.u_len);
+	if (!udf_build_ustr(instr, pvoldesc->volIdent, 32))
+		if (udf_CS0toUTF8(outstr, instr)) {
+			strncpy(UDF_SB(sb)->s_volume_ident, outstr->u_name,
+				outstr->u_len > 31 ? 31 : outstr->u_len);
 			udf_debug("volIdent[] = '%s'\n",
 					UDF_SB(sb)->s_volume_ident);
 		}
 
-	if (!udf_build_ustr(&instr, pvoldesc->volSetIdent, 128))
-		if (udf_CS0toUTF8(&outstr, &instr))
-			udf_debug("volSetIdent[] = '%s'\n", outstr.u_name);
+	if (!udf_build_ustr(instr, pvoldesc->volSetIdent, 128))
+		if (udf_CS0toUTF8(outstr, instr))
+			udf_debug("volSetIdent[] = '%s'\n", outstr->u_name);
 
 	brelse(bh);
-	return 0;
+	ret = 0;
+out2:
+	kfree(outstr);
+out1:
+	kfree(instr);
+	return ret;
 }
 
 static int udf_load_metadata_files(struct super_block *sb, int partition)
@@ -946,7 +832,7 @@
 	struct udf_sb_info *sbi = UDF_SB(sb);
 	struct udf_part_map *map;
 	struct udf_meta_data *mdata;
-	kernel_lb_addr addr;
+	struct kernel_lb_addr addr;
 	int fe_error = 0;
 
 	map = &sbi->s_partmaps[partition];
@@ -959,7 +845,7 @@
 	udf_debug("Metadata file location: block = %d part = %d\n",
 			  addr.logicalBlockNum, addr.partitionReferenceNum);
 
-	mdata->s_metadata_fe = udf_iget(sb, addr);
+	mdata->s_metadata_fe = udf_iget(sb, &addr);
 
 	if (mdata->s_metadata_fe == NULL) {
 		udf_warning(sb, __func__, "metadata inode efe not found, "
@@ -981,7 +867,7 @@
 	udf_debug("Mirror metadata file location: block = %d part = %d\n",
 			  addr.logicalBlockNum, addr.partitionReferenceNum);
 
-	mdata->s_mirror_fe = udf_iget(sb, addr);
+	mdata->s_mirror_fe = udf_iget(sb, &addr);
 
 	if (mdata->s_mirror_fe == NULL) {
 		if (fe_error) {
@@ -1013,7 +899,7 @@
 		udf_debug("Bitmap file location: block = %d part = %d\n",
 			addr.logicalBlockNum, addr.partitionReferenceNum);
 
-		mdata->s_bitmap_fe = udf_iget(sb, addr);
+		mdata->s_bitmap_fe = udf_iget(sb, &addr);
 
 		if (mdata->s_bitmap_fe == NULL) {
 			if (sb->s_flags & MS_RDONLY)
@@ -1037,7 +923,7 @@
 }
 
 static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh,
-			     kernel_lb_addr *root)
+			     struct kernel_lb_addr *root)
 {
 	struct fileSetDesc *fset;
 
@@ -1119,13 +1005,13 @@
 
 	phd = (struct partitionHeaderDesc *)p->partitionContentsUse;
 	if (phd->unallocSpaceTable.extLength) {
-		kernel_lb_addr loc = {
+		struct kernel_lb_addr loc = {
 			.logicalBlockNum = le32_to_cpu(
 				phd->unallocSpaceTable.extPosition),
 			.partitionReferenceNum = p_index,
 		};
 
-		map->s_uspace.s_table = udf_iget(sb, loc);
+		map->s_uspace.s_table = udf_iget(sb, &loc);
 		if (!map->s_uspace.s_table) {
 			udf_debug("cannot load unallocSpaceTable (part %d)\n",
 					p_index);
@@ -1154,13 +1040,13 @@
 		udf_debug("partitionIntegrityTable (part %d)\n", p_index);
 
 	if (phd->freedSpaceTable.extLength) {
-		kernel_lb_addr loc = {
+		struct kernel_lb_addr loc = {
 			.logicalBlockNum = le32_to_cpu(
 				phd->freedSpaceTable.extPosition),
 			.partitionReferenceNum = p_index,
 		};
 
-		map->s_fspace.s_table = udf_iget(sb, loc);
+		map->s_fspace.s_table = udf_iget(sb, &loc);
 		if (!map->s_fspace.s_table) {
 			udf_debug("cannot load freedSpaceTable (part %d)\n",
 				p_index);
@@ -1192,7 +1078,7 @@
 {
 	struct udf_sb_info *sbi = UDF_SB(sb);
 	struct udf_part_map *map = &sbi->s_partmaps[p_index];
-	kernel_lb_addr ino;
+	struct kernel_lb_addr ino;
 	struct buffer_head *bh = NULL;
 	struct udf_inode_info *vati;
 	uint32_t pos;
@@ -1201,7 +1087,7 @@
 	/* VAT file entry is in the last recorded block */
 	ino.partitionReferenceNum = type1_index;
 	ino.logicalBlockNum = sbi->s_last_block - map->s_partition_root;
-	sbi->s_vat_inode = udf_iget(sb, ino);
+	sbi->s_vat_inode = udf_iget(sb, &ino);
 	if (!sbi->s_vat_inode)
 		return 1;
 
@@ -1322,7 +1208,7 @@
 }
 
 static int udf_load_logicalvol(struct super_block *sb, sector_t block,
-			       kernel_lb_addr *fileset)
+			       struct kernel_lb_addr *fileset)
 {
 	struct logicalVolDesc *lvd;
 	int i, j, offset;
@@ -1471,7 +1357,7 @@
 	}
 
 	if (fileset) {
-		long_ad *la = (long_ad *)&(lvd->logicalVolContentsUse[0]);
+		struct long_ad *la = (struct long_ad *)&(lvd->logicalVolContentsUse[0]);
 
 		*fileset = lelb_to_cpu(la->extLocation);
 		udf_debug("FileSet found in LogicalVolDesc at block=%d, "
@@ -1490,7 +1376,7 @@
  * udf_load_logicalvolint
  *
  */
-static void udf_load_logicalvolint(struct super_block *sb, kernel_extent_ad loc)
+static void udf_load_logicalvolint(struct super_block *sb, struct kernel_extent_ad loc)
 {
 	struct buffer_head *bh = NULL;
 	uint16_t ident;
@@ -1533,7 +1419,7 @@
  *	Written, tested, and released.
  */
 static noinline int udf_process_sequence(struct super_block *sb, long block,
-				long lastblock, kernel_lb_addr *fileset)
+				long lastblock, struct kernel_lb_addr *fileset)
 {
 	struct buffer_head *bh = NULL;
 	struct udf_vds_record vds[VDS_POS_LENGTH];
@@ -1655,96 +1541,210 @@
 	return 0;
 }
 
-/*
- * udf_check_valid()
- */
-static int udf_check_valid(struct super_block *sb, int novrs, int silent)
-{
-	long block;
-	struct udf_sb_info *sbi = UDF_SB(sb);
-
-	if (novrs) {
-		udf_debug("Validity check skipped because of novrs option\n");
-		return 0;
-	}
-	/* Check that it is NSR02 compliant */
-	/* Process any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) */
-	block = udf_vrs(sb, silent);
-	if (block == -1)
-		udf_debug("Failed to read byte 32768. Assuming open "
-			  "disc. Skipping validity check\n");
-	if (block && !sbi->s_last_block)
-		sbi->s_last_block = udf_get_last_block(sb);
-	return !block;
-}
-
-static int udf_load_sequence(struct super_block *sb, kernel_lb_addr *fileset)
+static int udf_load_sequence(struct super_block *sb, struct buffer_head *bh,
+			     struct kernel_lb_addr *fileset)
 {
 	struct anchorVolDescPtr *anchor;
-	uint16_t ident;
-	struct buffer_head *bh;
 	long main_s, main_e, reserve_s, reserve_e;
-	int i;
 	struct udf_sb_info *sbi;
 
-	if (!sb)
-		return 1;
 	sbi = UDF_SB(sb);
+	anchor = (struct anchorVolDescPtr *)bh->b_data;
 
-	for (i = 0; i < ARRAY_SIZE(sbi->s_anchor); i++) {
-		if (!sbi->s_anchor[i])
-			continue;
+	/* Locate the main sequence */
+	main_s = le32_to_cpu(anchor->mainVolDescSeqExt.extLocation);
+	main_e = le32_to_cpu(anchor->mainVolDescSeqExt.extLength);
+	main_e = main_e >> sb->s_blocksize_bits;
+	main_e += main_s;
 
-		bh = udf_read_tagged(sb, sbi->s_anchor[i], sbi->s_anchor[i],
-				     &ident);
-		if (!bh)
-			continue;
+	/* Locate the reserve sequence */
+	reserve_s = le32_to_cpu(anchor->reserveVolDescSeqExt.extLocation);
+	reserve_e = le32_to_cpu(anchor->reserveVolDescSeqExt.extLength);
+	reserve_e = reserve_e >> sb->s_blocksize_bits;
+	reserve_e += reserve_s;
 
-		anchor = (struct anchorVolDescPtr *)bh->b_data;
-
-		/* Locate the main sequence */
-		main_s = le32_to_cpu(anchor->mainVolDescSeqExt.extLocation);
-		main_e = le32_to_cpu(anchor->mainVolDescSeqExt.extLength);
-		main_e = main_e >> sb->s_blocksize_bits;
-		main_e += main_s;
-
-		/* Locate the reserve sequence */
-		reserve_s = le32_to_cpu(
-				anchor->reserveVolDescSeqExt.extLocation);
-		reserve_e = le32_to_cpu(
-				anchor->reserveVolDescSeqExt.extLength);
-		reserve_e = reserve_e >> sb->s_blocksize_bits;
-		reserve_e += reserve_s;
-
-		brelse(bh);
-
-		/* Process the main & reserve sequences */
-		/* responsible for finding the PartitionDesc(s) */
-		if (!(udf_process_sequence(sb, main_s, main_e,
-					   fileset) &&
-		      udf_process_sequence(sb, reserve_s, reserve_e,
-					   fileset)))
-			break;
-	}
-
-	if (i == ARRAY_SIZE(sbi->s_anchor)) {
-		udf_debug("No Anchor block found\n");
+	/* Process the main & reserve sequences */
+	/* responsible for finding the PartitionDesc(s) */
+	if (!udf_process_sequence(sb, main_s, main_e, fileset))
 		return 1;
-	}
-	udf_debug("Using anchor in block %d\n", sbi->s_anchor[i]);
+	return !udf_process_sequence(sb, reserve_s, reserve_e, fileset);
+}
 
+/*
+ * Check whether there is an anchor block in the given block and
+ * load Volume Descriptor Sequence if so.
+ */
+static int udf_check_anchor_block(struct super_block *sb, sector_t block,
+				  struct kernel_lb_addr *fileset)
+{
+	struct buffer_head *bh;
+	uint16_t ident;
+	int ret;
+
+	if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV) &&
+	    udf_fixed_to_variable(block) >=
+	    sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits)
+		return 0;
+
+	bh = udf_read_tagged(sb, block, block, &ident);
+	if (!bh)
+		return 0;
+	if (ident != TAG_IDENT_AVDP) {
+		brelse(bh);
+		return 0;
+	}
+	ret = udf_load_sequence(sb, bh, fileset);
+	brelse(bh);
+	return ret;
+}
+
+/* Search for an anchor volume descriptor pointer */
+static sector_t udf_scan_anchors(struct super_block *sb, sector_t lastblock,
+				 struct kernel_lb_addr *fileset)
+{
+	sector_t last[6];
+	int i;
+	struct udf_sb_info *sbi = UDF_SB(sb);
+	int last_count = 0;
+
+	/* First try user provided anchor */
+	if (sbi->s_anchor) {
+		if (udf_check_anchor_block(sb, sbi->s_anchor, fileset))
+			return lastblock;
+	}
+	/*
+	 * according to spec, anchor is in either:
+	 *     block 256
+	 *     lastblock-256
+	 *     lastblock
+	 *  however, if the disc isn't closed, it could be 512.
+	 */
+	if (udf_check_anchor_block(sb, sbi->s_session + 256, fileset))
+		return lastblock;
+	/*
+	 * The trouble is which block is the last one. Drives often misreport
+	 * this so we try various possibilities.
+	 */
+	last[last_count++] = lastblock;
+	if (lastblock >= 1)
+		last[last_count++] = lastblock - 1;
+	last[last_count++] = lastblock + 1;
+	if (lastblock >= 2)
+		last[last_count++] = lastblock - 2;
+	if (lastblock >= 150)
+		last[last_count++] = lastblock - 150;
+	if (lastblock >= 152)
+		last[last_count++] = lastblock - 152;
+
+	for (i = 0; i < last_count; i++) {
+		if (last[i] >= sb->s_bdev->bd_inode->i_size >>
+				sb->s_blocksize_bits)
+			continue;
+		if (udf_check_anchor_block(sb, last[i], fileset))
+			return last[i];
+		if (last[i] < 256)
+			continue;
+		if (udf_check_anchor_block(sb, last[i] - 256, fileset))
+			return last[i];
+	}
+
+	/* Finally try block 512 in case media is open */
+	if (udf_check_anchor_block(sb, sbi->s_session + 512, fileset))
+		return last[0];
 	return 0;
 }
 
+/*
+ * Find an anchor volume descriptor and load Volume Descriptor Sequence from
+ * area specified by it. The function expects sbi->s_lastblock to be the last
+ * block on the media.
+ *
+ * Return 1 if ok, 0 if not found.
+ *
+ */
+static int udf_find_anchor(struct super_block *sb,
+			   struct kernel_lb_addr *fileset)
+{
+	sector_t lastblock;
+	struct udf_sb_info *sbi = UDF_SB(sb);
+
+	lastblock = udf_scan_anchors(sb, sbi->s_last_block, fileset);
+	if (lastblock)
+		goto out;
+
+	/* No anchor found? Try VARCONV conversion of block numbers */
+	UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
+	/* Firstly, we try to not convert number of the last block */
+	lastblock = udf_scan_anchors(sb,
+				udf_variable_to_fixed(sbi->s_last_block),
+				fileset);
+	if (lastblock)
+		goto out;
+
+	/* Secondly, we try with converted number of the last block */
+	lastblock = udf_scan_anchors(sb, sbi->s_last_block, fileset);
+	if (!lastblock) {
+		/* VARCONV didn't help. Clear it. */
+		UDF_CLEAR_FLAG(sb, UDF_FLAG_VARCONV);
+		return 0;
+	}
+out:
+	sbi->s_last_block = lastblock;
+	return 1;
+}
+
+/*
+ * Check Volume Structure Descriptor, find Anchor block and load Volume
+ * Descriptor Sequence
+ */
+static int udf_load_vrs(struct super_block *sb, struct udf_options *uopt,
+			int silent, struct kernel_lb_addr *fileset)
+{
+	struct udf_sb_info *sbi = UDF_SB(sb);
+	loff_t nsr_off;
+
+	if (!sb_set_blocksize(sb, uopt->blocksize)) {
+		if (!silent)
+			printk(KERN_WARNING "UDF-fs: Bad block size\n");
+		return 0;
+	}
+	sbi->s_last_block = uopt->lastblock;
+	if (!uopt->novrs) {
+		/* Check that it is NSR02 compliant */
+		nsr_off = udf_check_vsd(sb);
+		if (!nsr_off) {
+			if (!silent)
+				printk(KERN_WARNING "UDF-fs: No VRS found\n");
+			return 0;
+		}
+		if (nsr_off == -1)
+			udf_debug("Failed to read byte 32768. Assuming open "
+				  "disc. Skipping validity check\n");
+		if (!sbi->s_last_block)
+			sbi->s_last_block = udf_get_last_block(sb);
+	} else {
+		udf_debug("Validity check skipped because of novrs option\n");
+	}
+
+	/* Look for anchor block and load Volume Descriptor Sequence */
+	sbi->s_anchor = uopt->anchor;
+	if (!udf_find_anchor(sb, fileset)) {
+		if (!silent)
+			printk(KERN_WARNING "UDF-fs: No anchor found\n");
+		return 0;
+	}
+	return 1;
+}
+
 static void udf_open_lvid(struct super_block *sb)
 {
 	struct udf_sb_info *sbi = UDF_SB(sb);
 	struct buffer_head *bh = sbi->s_lvid_bh;
 	struct logicalVolIntegrityDesc *lvid;
 	struct logicalVolIntegrityDescImpUse *lvidiu;
+
 	if (!bh)
 		return;
-
 	lvid = (struct logicalVolIntegrityDesc *)bh->b_data;
 	lvidiu = udf_sb_lvidiu(sbi);
 
@@ -1752,14 +1752,15 @@
 	lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
 	udf_time_to_disk_stamp(&lvid->recordingDateAndTime,
 				CURRENT_TIME);
-	lvid->integrityType = LVID_INTEGRITY_TYPE_OPEN;
+	lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN);
 
 	lvid->descTag.descCRC = cpu_to_le16(
-		crc_itu_t(0, (char *)lvid + sizeof(tag),
+		crc_itu_t(0, (char *)lvid + sizeof(struct tag),
 			le16_to_cpu(lvid->descTag.descCRCLength)));
 
 	lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag);
 	mark_buffer_dirty(bh);
+	sbi->s_lvid_dirty = 0;
 }
 
 static void udf_close_lvid(struct super_block *sb)
@@ -1773,10 +1774,6 @@
 		return;
 
 	lvid = (struct logicalVolIntegrityDesc *)bh->b_data;
-
-	if (lvid->integrityType != LVID_INTEGRITY_TYPE_OPEN)
-		return;
-
 	lvidiu = udf_sb_lvidiu(sbi);
 	lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
 	lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
@@ -1790,11 +1787,12 @@
 	lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE);
 
 	lvid->descTag.descCRC = cpu_to_le16(
-			crc_itu_t(0, (char *)lvid + sizeof(tag),
+			crc_itu_t(0, (char *)lvid + sizeof(struct tag),
 				le16_to_cpu(lvid->descTag.descCRCLength)));
 
 	lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag);
 	mark_buffer_dirty(bh);
+	sbi->s_lvid_dirty = 0;
 }
 
 static void udf_sb_free_bitmap(struct udf_bitmap *bitmap)
@@ -1846,15 +1844,18 @@
 static int udf_fill_super(struct super_block *sb, void *options, int silent)
 {
 	int i;
+	int ret;
 	struct inode *inode = NULL;
 	struct udf_options uopt;
-	kernel_lb_addr rootdir, fileset;
+	struct kernel_lb_addr rootdir, fileset;
 	struct udf_sb_info *sbi;
 
 	uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT);
 	uopt.uid = -1;
 	uopt.gid = -1;
 	uopt.umask = 0;
+	uopt.fmode = UDF_INVALID_MODE;
+	uopt.dmode = UDF_INVALID_MODE;
 
 	sbi = kzalloc(sizeof(struct udf_sb_info), GFP_KERNEL);
 	if (!sbi)
@@ -1892,15 +1893,10 @@
 	sbi->s_uid = uopt.uid;
 	sbi->s_gid = uopt.gid;
 	sbi->s_umask = uopt.umask;
+	sbi->s_fmode = uopt.fmode;
+	sbi->s_dmode = uopt.dmode;
 	sbi->s_nls_map = uopt.nls_map;
 
-	/* Set the block size for all transfers */
-	if (!sb_min_blocksize(sb, uopt.blocksize)) {
-		udf_debug("Bad block size (%d)\n", uopt.blocksize);
-		printk(KERN_ERR "udf: bad block size (%d)\n", uopt.blocksize);
-		goto error_out;
-	}
-
 	if (uopt.session == 0xFFFFFFFF)
 		sbi->s_session = udf_get_last_session(sb);
 	else
@@ -1908,18 +1904,6 @@
 
 	udf_debug("Multi-session=%d\n", sbi->s_session);
 
-	sbi->s_last_block = uopt.lastblock;
-	sbi->s_anchor[0] = sbi->s_anchor[1] = 0;
-	sbi->s_anchor[2] = uopt.anchor;
-
-	if (udf_check_valid(sb, uopt.novrs, silent)) {
-		/* read volume recognition sequences */
-		printk(KERN_WARNING "UDF-fs: No VRS found\n");
-		goto error_out;
-	}
-
-	udf_find_anchor(sb);
-
 	/* Fill in the rest of the superblock */
 	sb->s_op = &udf_sb_ops;
 	sb->s_export_op = &udf_export_ops;
@@ -1928,7 +1912,21 @@
 	sb->s_magic = UDF_SUPER_MAGIC;
 	sb->s_time_gran = 1000;
 
-	if (udf_load_sequence(sb, &fileset)) {
+	if (uopt.flags & (1 << UDF_FLAG_BLOCKSIZE_SET)) {
+		ret = udf_load_vrs(sb, &uopt, silent, &fileset);
+	} else {
+		uopt.blocksize = bdev_hardsect_size(sb->s_bdev);
+		ret = udf_load_vrs(sb, &uopt, silent, &fileset);
+		if (!ret && uopt.blocksize != UDF_DEFAULT_BLOCKSIZE) {
+			if (!silent)
+				printk(KERN_NOTICE
+				       "UDF-fs: Rescanning with blocksize "
+				       "%d\n", UDF_DEFAULT_BLOCKSIZE);
+			uopt.blocksize = UDF_DEFAULT_BLOCKSIZE;
+			ret = udf_load_vrs(sb, &uopt, silent, &fileset);
+		}
+	}
+	if (!ret) {
 		printk(KERN_WARNING "UDF-fs: No partition found (1)\n");
 		goto error_out;
 	}
@@ -1978,7 +1976,7 @@
 	}
 
 	if (!silent) {
-		timestamp ts;
+		struct timestamp ts;
 		udf_time_to_disk_stamp(&ts, sbi->s_record_time);
 		udf_info("UDF: Mounting volume '%s', "
 			 "timestamp %04u/%02u/%02u %02u:%02u (%x)\n",
@@ -1991,7 +1989,7 @@
 	/* Assign the root inode */
 	/* assign inodes by physical block number */
 	/* perhaps it's not extensible enough, but for now ... */
-	inode = udf_iget(sb, rootdir);
+	inode = udf_iget(sb, &rootdir);
 	if (!inode) {
 		printk(KERN_ERR "UDF-fs: Error in udf_iget, block=%d, "
 				"partition=%d\n",
@@ -2081,11 +2079,31 @@
 	sb->s_fs_info = NULL;
 }
 
+static int udf_sync_fs(struct super_block *sb, int wait)
+{
+	struct udf_sb_info *sbi = UDF_SB(sb);
+
+	mutex_lock(&sbi->s_alloc_mutex);
+	if (sbi->s_lvid_dirty) {
+		/*
+		 * Blockdevice will be synced later so we don't have to submit
+		 * the buffer for IO
+		 */
+		mark_buffer_dirty(sbi->s_lvid_bh);
+		sb->s_dirt = 0;
+		sbi->s_lvid_dirty = 0;
+	}
+	mutex_unlock(&sbi->s_alloc_mutex);
+
+	return 0;
+}
+
 static int udf_statfs(struct dentry *dentry, struct kstatfs *buf)
 {
 	struct super_block *sb = dentry->d_sb;
 	struct udf_sb_info *sbi = UDF_SB(sb);
 	struct logicalVolIntegrityDescImpUse *lvidiu;
+	u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
 
 	if (sbi->s_lvid_bh != NULL)
 		lvidiu = udf_sb_lvidiu(sbi);
@@ -2101,8 +2119,9 @@
 					  le32_to_cpu(lvidiu->numDirs)) : 0)
 			+ buf->f_bfree;
 	buf->f_ffree = buf->f_bfree;
-	/* __kernel_fsid_t f_fsid */
 	buf->f_namelen = UDF_NAME_LEN - 2;
+	buf->f_fsid.val[0] = (u32)id;
+	buf->f_fsid.val[1] = (u32)(id >> 32);
 
 	return 0;
 }
@@ -2114,7 +2133,7 @@
 	unsigned int accum = 0;
 	int index;
 	int block = 0, newblock;
-	kernel_lb_addr loc;
+	struct kernel_lb_addr loc;
 	uint32_t bytes;
 	uint8_t *ptr;
 	uint16_t ident;
@@ -2124,7 +2143,7 @@
 
 	loc.logicalBlockNum = bitmap->s_extPosition;
 	loc.partitionReferenceNum = UDF_SB(sb)->s_partition;
-	bh = udf_read_ptagged(sb, loc, 0, &ident);
+	bh = udf_read_ptagged(sb, &loc, 0, &ident);
 
 	if (!bh) {
 		printk(KERN_ERR "udf: udf_count_free failed\n");
@@ -2147,7 +2166,7 @@
 		bytes -= cur_bytes;
 		if (bytes) {
 			brelse(bh);
-			newblock = udf_get_lb_pblock(sb, loc, ++block);
+			newblock = udf_get_lb_pblock(sb, &loc, ++block);
 			bh = udf_tread(sb, newblock);
 			if (!bh) {
 				udf_debug("read failed\n");
@@ -2170,7 +2189,7 @@
 {
 	unsigned int accum = 0;
 	uint32_t elen;
-	kernel_lb_addr eloc;
+	struct kernel_lb_addr eloc;
 	int8_t etype;
 	struct extent_position epos;
 
diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c
index 65e19b4..225527c 100644
--- a/fs/udf/truncate.c
+++ b/fs/udf/truncate.c
@@ -28,10 +28,10 @@
 #include "udf_sb.h"
 
 static void extent_trunc(struct inode *inode, struct extent_position *epos,
-			 kernel_lb_addr eloc, int8_t etype, uint32_t elen,
+			 struct kernel_lb_addr *eloc, int8_t etype, uint32_t elen,
 			 uint32_t nelen)
 {
-	kernel_lb_addr neloc = {};
+	struct kernel_lb_addr neloc = {};
 	int last_block = (elen + inode->i_sb->s_blocksize - 1) >>
 		inode->i_sb->s_blocksize_bits;
 	int first_block = (nelen + inode->i_sb->s_blocksize - 1) >>
@@ -43,12 +43,12 @@
 					last_block);
 			etype = (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30);
 		} else
-			neloc = eloc;
+			neloc = *eloc;
 		nelen = (etype << 30) | nelen;
 	}
 
 	if (elen != nelen) {
-		udf_write_aext(inode, epos, neloc, nelen, 0);
+		udf_write_aext(inode, epos, &neloc, nelen, 0);
 		if (last_block - first_block > 0) {
 			if (etype == (EXT_RECORDED_ALLOCATED >> 30))
 				mark_inode_dirty(inode);
@@ -68,7 +68,7 @@
 void udf_truncate_tail_extent(struct inode *inode)
 {
 	struct extent_position epos = {};
-	kernel_lb_addr eloc;
+	struct kernel_lb_addr eloc;
 	uint32_t elen, nelen;
 	uint64_t lbcount = 0;
 	int8_t etype = -1, netype;
@@ -83,9 +83,9 @@
 		return;
 
 	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
-		adsize = sizeof(short_ad);
+		adsize = sizeof(struct short_ad);
 	else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
-		adsize = sizeof(long_ad);
+		adsize = sizeof(struct long_ad);
 	else
 		BUG();
 
@@ -106,7 +106,7 @@
 				       (unsigned)elen);
 			nelen = elen - (lbcount - inode->i_size);
 			epos.offset -= adsize;
-			extent_trunc(inode, &epos, eloc, etype, elen, nelen);
+			extent_trunc(inode, &epos, &eloc, etype, elen, nelen);
 			epos.offset += adsize;
 			if (udf_next_aext(inode, &epos, &eloc, &elen, 1) != -1)
 				printk(KERN_ERR "udf_truncate_tail_extent(): "
@@ -124,7 +124,7 @@
 void udf_discard_prealloc(struct inode *inode)
 {
 	struct extent_position epos = { NULL, 0, {0, 0} };
-	kernel_lb_addr eloc;
+	struct kernel_lb_addr eloc;
 	uint32_t elen;
 	uint64_t lbcount = 0;
 	int8_t etype = -1, netype;
@@ -136,9 +136,9 @@
 		return;
 
 	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
-		adsize = sizeof(short_ad);
+		adsize = sizeof(struct short_ad);
 	else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
-		adsize = sizeof(long_ad);
+		adsize = sizeof(struct long_ad);
 	else
 		adsize = 0;
 
@@ -152,7 +152,7 @@
 	if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
 		epos.offset -= adsize;
 		lbcount -= elen;
-		extent_trunc(inode, &epos, eloc, etype, elen, 0);
+		extent_trunc(inode, &epos, &eloc, etype, elen, 0);
 		if (!epos.bh) {
 			iinfo->i_lenAlloc =
 				epos.offset -
@@ -200,7 +200,7 @@
 void udf_truncate_extents(struct inode *inode)
 {
 	struct extent_position epos;
-	kernel_lb_addr eloc, neloc = {};
+	struct kernel_lb_addr eloc, neloc = {};
 	uint32_t elen, nelen = 0, indirect_ext_len = 0, lenalloc;
 	int8_t etype;
 	struct super_block *sb = inode->i_sb;
@@ -210,9 +210,9 @@
 	struct udf_inode_info *iinfo = UDF_I(inode);
 
 	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
-		adsize = sizeof(short_ad);
+		adsize = sizeof(struct short_ad);
 	else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
-		adsize = sizeof(long_ad);
+		adsize = sizeof(struct long_ad);
 	else
 		BUG();
 
@@ -221,7 +221,7 @@
 		(inode->i_size & (sb->s_blocksize - 1));
 	if (etype != -1) {
 		epos.offset -= adsize;
-		extent_trunc(inode, &epos, eloc, etype, elen, byte_offset);
+		extent_trunc(inode, &epos, &eloc, etype, elen, byte_offset);
 		epos.offset += adsize;
 		if (byte_offset)
 			lenalloc = epos.offset;
@@ -236,12 +236,12 @@
 		while ((etype = udf_current_aext(inode, &epos, &eloc,
 						 &elen, 0)) != -1) {
 			if (etype == (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) {
-				udf_write_aext(inode, &epos, neloc, nelen, 0);
+				udf_write_aext(inode, &epos, &neloc, nelen, 0);
 				if (indirect_ext_len) {
 					/* We managed to free all extents in the
 					 * indirect extent - free it too */
 					BUG_ON(!epos.bh);
-					udf_free_blocks(sb, inode, epos.block,
+					udf_free_blocks(sb, inode, &epos.block,
 							0, indirect_ext_len);
 				} else if (!epos.bh) {
 					iinfo->i_lenAlloc = lenalloc;
@@ -253,7 +253,7 @@
 				epos.offset = sizeof(struct allocExtDesc);
 				epos.block = eloc;
 				epos.bh = udf_tread(sb,
-						udf_get_lb_pblock(sb, eloc, 0));
+						udf_get_lb_pblock(sb, &eloc, 0));
 				if (elen)
 					indirect_ext_len =
 						(elen + sb->s_blocksize - 1) >>
@@ -261,7 +261,7 @@
 				else
 					indirect_ext_len = 1;
 			} else {
-				extent_trunc(inode, &epos, eloc, etype,
+				extent_trunc(inode, &epos, &eloc, etype,
 					     elen, 0);
 				epos.offset += adsize;
 			}
@@ -269,7 +269,7 @@
 
 		if (indirect_ext_len) {
 			BUG_ON(!epos.bh);
-			udf_free_blocks(sb, inode, epos.block, 0,
+			udf_free_blocks(sb, inode, &epos.block, 0,
 					indirect_ext_len);
 		} else if (!epos.bh) {
 			iinfo->i_lenAlloc = lenalloc;
@@ -278,7 +278,7 @@
 			udf_update_alloc_ext_desc(inode, &epos, lenalloc);
 	} else if (inode->i_size) {
 		if (byte_offset) {
-			kernel_long_ad extent;
+			struct kernel_long_ad extent;
 
 			/*
 			 *  OK, there is not extent covering inode->i_size and
diff --git a/fs/udf/udf_i.h b/fs/udf/udf_i.h
index 4f86b1d..e58d1de 100644
--- a/fs/udf/udf_i.h
+++ b/fs/udf/udf_i.h
@@ -4,7 +4,7 @@
 struct udf_inode_info {
 	struct timespec		i_crtime;
 	/* Physical address of inode */
-	kernel_lb_addr		i_location;
+	struct kernel_lb_addr		i_location;
 	__u64			i_unique;
 	__u32			i_lenEAttr;
 	__u32			i_lenAlloc;
@@ -17,8 +17,8 @@
 	unsigned		i_strat4096 : 1;
 	unsigned		reserved : 26;
 	union {
-		short_ad	*i_sad;
-		long_ad		*i_lad;
+		struct short_ad	*i_sad;
+		struct long_ad		*i_lad;
 		__u8		*i_data;
 	} i_ext;
 	struct inode vfs_inode;
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h
index 1c1c514..d113b72 100644
--- a/fs/udf/udf_sb.h
+++ b/fs/udf/udf_sb.h
@@ -30,6 +30,7 @@
 #define UDF_FLAG_GID_SET	16
 #define UDF_FLAG_SESSION_SET	17
 #define UDF_FLAG_LASTBLOCK_SET	18
+#define UDF_FLAG_BLOCKSIZE_SET	19
 
 #define UDF_PART_FLAG_UNALLOC_BITMAP	0x0001
 #define UDF_PART_FLAG_UNALLOC_TABLE	0x0002
@@ -48,6 +49,8 @@
 #define UDF_SPARABLE_MAP15		0x1522U
 #define UDF_METADATA_MAP25		0x2511U
 
+#define UDF_INVALID_MODE		((mode_t)-1)
+
 #pragma pack(1) /* XXX(hch): Why?  This file just defines in-core structures */
 
 struct udf_meta_data {
@@ -114,7 +117,7 @@
 
 	/* Sector headers */
 	__s32			s_session;
-	__u32			s_anchor[3];
+	__u32			s_anchor;
 	__u32			s_last_block;
 
 	struct buffer_head	*s_lvid_bh;
@@ -123,6 +126,8 @@
 	mode_t			s_umask;
 	gid_t			s_gid;
 	uid_t			s_uid;
+	mode_t			s_fmode;
+	mode_t			s_dmode;
 
 	/* Root Info */
 	struct timespec		s_record_time;
@@ -143,6 +148,8 @@
 	struct inode		*s_vat_inode;
 
 	struct mutex		s_alloc_mutex;
+	/* Protected by s_alloc_mutex */
+	unsigned int		s_lvid_dirty;
 };
 
 static inline struct udf_sb_info *UDF_SB(struct super_block *sb)
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index 8ec865d..cac51b7 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -62,10 +62,8 @@
 		return 0;
 }
 
-#define udf_get_lb_pblock(sb,loc,offset) udf_get_pblock((sb), (loc).logicalBlockNum, (loc).partitionReferenceNum, (offset))
-
 /* computes tag checksum */
-u8 udf_tag_checksum(const tag *t);
+u8 udf_tag_checksum(const struct tag *t);
 
 struct dentry;
 struct inode;
@@ -95,7 +93,7 @@
 };
 
 struct generic_desc {
-	tag		descTag;
+	struct tag	descTag;
 	__le32		volDescSeqNum;
 };
 
@@ -108,11 +106,22 @@
 struct extent_position {
 	struct buffer_head *bh;
 	uint32_t offset;
-	kernel_lb_addr block;
+	struct kernel_lb_addr block;
 };
 
 /* super.c */
 extern void udf_warning(struct super_block *, const char *, const char *, ...);
+static inline void udf_updated_lvid(struct super_block *sb)
+{
+	struct buffer_head *bh = UDF_SB(sb)->s_lvid_bh;
+
+	BUG_ON(!bh);
+	WARN_ON_ONCE(((struct logicalVolIntegrityDesc *)
+		     bh->b_data)->integrityType !=
+		     cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN));
+	sb->s_dirt = 1;
+	UDF_SB(sb)->s_lvid_dirty = 1;
+}
 
 /* namei.c */
 extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *,
@@ -124,7 +133,7 @@
 		     unsigned long);
 
 /* inode.c */
-extern struct inode *udf_iget(struct super_block *, kernel_lb_addr);
+extern struct inode *udf_iget(struct super_block *, struct kernel_lb_addr *);
 extern int udf_sync_inode(struct inode *);
 extern void udf_expand_file_adinicb(struct inode *, int, int *);
 extern struct buffer_head *udf_expand_dir_adinicb(struct inode *, int *, int *);
@@ -136,19 +145,19 @@
 extern int udf_write_inode(struct inode *, int);
 extern long udf_block_map(struct inode *, sector_t);
 extern int udf_extend_file(struct inode *, struct extent_position *,
-			   kernel_long_ad *, sector_t);
+			   struct kernel_long_ad *, sector_t);
 extern int8_t inode_bmap(struct inode *, sector_t, struct extent_position *,
-			 kernel_lb_addr *, uint32_t *, sector_t *);
+			 struct kernel_lb_addr *, uint32_t *, sector_t *);
 extern int8_t udf_add_aext(struct inode *, struct extent_position *,
-			   kernel_lb_addr, uint32_t, int);
+			   struct kernel_lb_addr *, uint32_t, int);
 extern int8_t udf_write_aext(struct inode *, struct extent_position *,
-			     kernel_lb_addr, uint32_t, int);
+			     struct kernel_lb_addr *, uint32_t, int);
 extern int8_t udf_delete_aext(struct inode *, struct extent_position,
-			      kernel_lb_addr, uint32_t);
+			      struct kernel_lb_addr, uint32_t);
 extern int8_t udf_next_aext(struct inode *, struct extent_position *,
-			    kernel_lb_addr *, uint32_t *, int);
+			    struct kernel_lb_addr *, uint32_t *, int);
 extern int8_t udf_current_aext(struct inode *, struct extent_position *,
-			       kernel_lb_addr *, uint32_t *, int);
+			       struct kernel_lb_addr *, uint32_t *, int);
 
 /* misc.c */
 extern struct buffer_head *udf_tgetblk(struct super_block *, int);
@@ -160,7 +169,7 @@
 extern struct buffer_head *udf_read_tagged(struct super_block *, uint32_t,
 					   uint32_t, uint16_t *);
 extern struct buffer_head *udf_read_ptagged(struct super_block *,
-					    kernel_lb_addr, uint32_t,
+					    struct kernel_lb_addr *, uint32_t,
 					    uint16_t *);
 extern void udf_update_tag(char *, int);
 extern void udf_new_tag(char *, uint16_t, uint16_t, uint16_t, uint32_t, int);
@@ -182,6 +191,14 @@
 					  uint32_t);
 extern int udf_relocate_blocks(struct super_block *, long, long *);
 
+static inline uint32_t
+udf_get_lb_pblock(struct super_block *sb, struct kernel_lb_addr *loc,
+		  uint32_t offset)
+{
+	return udf_get_pblock(sb, loc->logicalBlockNum,
+			loc->partitionReferenceNum, offset);
+}
+
 /* unicode.c */
 extern int udf_get_filename(struct super_block *, uint8_t *, uint8_t *, int);
 extern int udf_put_filename(struct super_block *, const uint8_t *, uint8_t *,
@@ -200,7 +217,7 @@
 
 /* balloc.c */
 extern void udf_free_blocks(struct super_block *, struct inode *,
-			    kernel_lb_addr, uint32_t, uint32_t);
+			    struct kernel_lb_addr *, uint32_t, uint32_t);
 extern int udf_prealloc_blocks(struct super_block *, struct inode *, uint16_t,
 			       uint32_t, uint32_t);
 extern int udf_new_block(struct super_block *, struct inode *, uint16_t,
@@ -214,16 +231,16 @@
 						struct udf_fileident_bh *,
 						struct fileIdentDesc *,
 						struct extent_position *,
-						kernel_lb_addr *, uint32_t *,
+						struct kernel_lb_addr *, uint32_t *,
 						sector_t *);
 extern struct fileIdentDesc *udf_get_fileident(void *buffer, int bufsize,
 					       int *offset);
-extern long_ad *udf_get_filelongad(uint8_t *, int, uint32_t *, int);
-extern short_ad *udf_get_fileshortad(uint8_t *, int, uint32_t *, int);
+extern struct long_ad *udf_get_filelongad(uint8_t *, int, uint32_t *, int);
+extern struct short_ad *udf_get_fileshortad(uint8_t *, int, uint32_t *, int);
 
 /* udftime.c */
 extern struct timespec *udf_disk_stamp_to_time(struct timespec *dest,
-						timestamp src);
-extern timestamp *udf_time_to_disk_stamp(timestamp *dest, struct timespec src);
+						struct timestamp src);
+extern struct timestamp *udf_time_to_disk_stamp(struct timestamp *dest, struct timespec src);
 
 #endif				/* __UDF_DECL_H */
diff --git a/fs/udf/udfend.h b/fs/udf/udfend.h
index 489f52f..6a9f3a9 100644
--- a/fs/udf/udfend.h
+++ b/fs/udf/udfend.h
@@ -4,9 +4,9 @@
 #include <asm/byteorder.h>
 #include <linux/string.h>
 
-static inline kernel_lb_addr lelb_to_cpu(lb_addr in)
+static inline struct kernel_lb_addr lelb_to_cpu(struct lb_addr in)
 {
-	kernel_lb_addr out;
+	struct kernel_lb_addr out;
 
 	out.logicalBlockNum = le32_to_cpu(in.logicalBlockNum);
 	out.partitionReferenceNum = le16_to_cpu(in.partitionReferenceNum);
@@ -14,9 +14,9 @@
 	return out;
 }
 
-static inline lb_addr cpu_to_lelb(kernel_lb_addr in)
+static inline struct lb_addr cpu_to_lelb(struct kernel_lb_addr in)
 {
-	lb_addr out;
+	struct lb_addr out;
 
 	out.logicalBlockNum = cpu_to_le32(in.logicalBlockNum);
 	out.partitionReferenceNum = cpu_to_le16(in.partitionReferenceNum);
@@ -24,9 +24,9 @@
 	return out;
 }
 
-static inline short_ad lesa_to_cpu(short_ad in)
+static inline struct short_ad lesa_to_cpu(struct short_ad in)
 {
-	short_ad out;
+	struct short_ad out;
 
 	out.extLength = le32_to_cpu(in.extLength);
 	out.extPosition = le32_to_cpu(in.extPosition);
@@ -34,9 +34,9 @@
 	return out;
 }
 
-static inline short_ad cpu_to_lesa(short_ad in)
+static inline struct short_ad cpu_to_lesa(struct short_ad in)
 {
-	short_ad out;
+	struct short_ad out;
 
 	out.extLength = cpu_to_le32(in.extLength);
 	out.extPosition = cpu_to_le32(in.extPosition);
@@ -44,9 +44,9 @@
 	return out;
 }
 
-static inline kernel_long_ad lela_to_cpu(long_ad in)
+static inline struct kernel_long_ad lela_to_cpu(struct long_ad in)
 {
-	kernel_long_ad out;
+	struct kernel_long_ad out;
 
 	out.extLength = le32_to_cpu(in.extLength);
 	out.extLocation = lelb_to_cpu(in.extLocation);
@@ -54,9 +54,9 @@
 	return out;
 }
 
-static inline long_ad cpu_to_lela(kernel_long_ad in)
+static inline struct long_ad cpu_to_lela(struct kernel_long_ad in)
 {
-	long_ad out;
+	struct long_ad out;
 
 	out.extLength = cpu_to_le32(in.extLength);
 	out.extLocation = cpu_to_lelb(in.extLocation);
@@ -64,9 +64,9 @@
 	return out;
 }
 
-static inline kernel_extent_ad leea_to_cpu(extent_ad in)
+static inline struct kernel_extent_ad leea_to_cpu(struct extent_ad in)
 {
-	kernel_extent_ad out;
+	struct kernel_extent_ad out;
 
 	out.extLength = le32_to_cpu(in.extLength);
 	out.extLocation = le32_to_cpu(in.extLocation);
diff --git a/fs/udf/udftime.c b/fs/udf/udftime.c
index 5f811655..b8c828c 100644
--- a/fs/udf/udftime.c
+++ b/fs/udf/udftime.c
@@ -85,7 +85,8 @@
 #define SECS_PER_HOUR	(60 * 60)
 #define SECS_PER_DAY	(SECS_PER_HOUR * 24)
 
-struct timespec *udf_disk_stamp_to_time(struct timespec *dest, timestamp src)
+struct timespec *
+udf_disk_stamp_to_time(struct timespec *dest, struct timestamp src)
 {
 	int yday;
 	u16 typeAndTimezone = le16_to_cpu(src.typeAndTimezone);
@@ -116,7 +117,8 @@
 	return dest;
 }
 
-timestamp *udf_time_to_disk_stamp(timestamp *dest, struct timespec ts)
+struct timestamp *
+udf_time_to_disk_stamp(struct timestamp *dest, struct timespec ts)
 {
 	long int days, rem, y;
 	const unsigned short int *ip;
diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c
index 9fdf8c9..cefa8c8 100644
--- a/fs/udf/unicode.c
+++ b/fs/udf/unicode.c
@@ -254,7 +254,7 @@
 {
 	const uint8_t *ocu;
 	uint8_t cmp_id, ocu_len;
-	int i;
+	int i, len;
 
 
 	ocu_len = ocu_i->u_len;
@@ -279,8 +279,13 @@
 		if (cmp_id == 16)
 			c = (c << 8) | ocu[i++];
 
-		utf_o->u_len += nls->uni2char(c, &utf_o->u_name[utf_o->u_len],
-					      UDF_NAME_LEN - utf_o->u_len);
+		len = nls->uni2char(c, &utf_o->u_name[utf_o->u_len],
+				    UDF_NAME_LEN - utf_o->u_len);
+		/* Valid character? */
+		if (len >= 0)
+			utf_o->u_len += len;
+		else
+			utf_o->u_name[utf_o->u_len++] = '?';
 	}
 	utf_o->u_cmpID = 8;
 
@@ -290,7 +295,8 @@
 static int udf_NLStoCS0(struct nls_table *nls, dstring *ocu, struct ustr *uni,
 			int length)
 {
-	unsigned len, i, max_val;
+	int len;
+	unsigned i, max_val;
 	uint16_t uni_char;
 	int u_len;
 
@@ -302,8 +308,13 @@
 	u_len = 0U;
 	for (i = 0U; i < uni->u_len; i++) {
 		len = nls->char2uni(&uni->u_name[i], uni->u_len - i, &uni_char);
-		if (len <= 0)
+		if (!len)
 			continue;
+		/* Invalid character, deal with it */
+		if (len < 0) {
+			len = 1;
+			uni_char = '?';
+		}
 
 		if (uni_char > max_val) {
 			max_val = 0xffffU;
@@ -324,34 +335,43 @@
 int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname,
 		     int flen)
 {
-	struct ustr filename, unifilename;
-	int len;
+	struct ustr *filename, *unifilename;
+	int len = 0;
 
-	if (udf_build_ustr_exact(&unifilename, sname, flen))
+	filename = kmalloc(sizeof(struct ustr), GFP_NOFS);
+	if (!filename)
 		return 0;
 
+	unifilename = kmalloc(sizeof(struct ustr), GFP_NOFS);
+	if (!unifilename)
+		goto out1;
+
+	if (udf_build_ustr_exact(unifilename, sname, flen))
+		goto out2;
+
 	if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) {
-		if (!udf_CS0toUTF8(&filename, &unifilename)) {
+		if (!udf_CS0toUTF8(filename, unifilename)) {
 			udf_debug("Failed in udf_get_filename: sname = %s\n",
 				  sname);
-			return 0;
+			goto out2;
 		}
 	} else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) {
-		if (!udf_CS0toNLS(UDF_SB(sb)->s_nls_map, &filename,
-				  &unifilename)) {
+		if (!udf_CS0toNLS(UDF_SB(sb)->s_nls_map, filename,
+				  unifilename)) {
 			udf_debug("Failed in udf_get_filename: sname = %s\n",
 				  sname);
-			return 0;
+			goto out2;
 		}
 	} else
-		return 0;
+		goto out2;
 
-	len = udf_translate_to_linux(dname, filename.u_name, filename.u_len,
-				     unifilename.u_name, unifilename.u_len);
-	if (len)
-		return len;
-
-	return 0;
+	len = udf_translate_to_linux(dname, filename->u_name, filename->u_len,
+				     unifilename->u_name, unifilename->u_len);
+out2:
+	kfree(unifilename);
+out1:
+	kfree(filename);
+	return len;
 }
 
 int udf_put_filename(struct super_block *sb, const uint8_t *sname,
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
index c3dc491..60f107e 100644
--- a/fs/xfs/Makefile
+++ b/fs/xfs/Makefile
@@ -33,6 +33,7 @@
 				   xfs_qm_syscalls.o \
 				   xfs_qm_bhv.o \
 				   xfs_qm.o)
+xfs-$(CONFIG_XFS_QUOTA)		+= linux-2.6/xfs_quotaops.o
 
 ifeq ($(CONFIG_XFS_QUOTA),y)
 xfs-$(CONFIG_PROC_FS)		+= quota/xfs_qm_stats.o
diff --git a/fs/xfs/linux-2.6/mutex.h b/fs/xfs/linux-2.6/mutex.h
deleted file mode 100644
index 2a88d56..0000000
--- a/fs/xfs/linux-2.6/mutex.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * 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.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 the Free Software Foundation,
- * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-#ifndef __XFS_SUPPORT_MUTEX_H__
-#define __XFS_SUPPORT_MUTEX_H__
-
-#include <linux/mutex.h>
-
-typedef struct mutex mutex_t;
-
-#endif /* __XFS_SUPPORT_MUTEX_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index de3a198..c13f673 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -1623,4 +1623,5 @@
 	.bmap			= xfs_vm_bmap,
 	.direct_IO		= xfs_vm_direct_IO,
 	.migratepage		= buffer_migrate_page,
+	.is_partially_uptodate  = block_is_partially_uptodate,
 };
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index 4bd1123..d0b4994 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -34,6 +34,7 @@
 #include "xfs_dir2_sf.h"
 #include "xfs_dinode.h"
 #include "xfs_inode.h"
+#include "xfs_ioctl.h"
 #include "xfs_btree.h"
 #include "xfs_ialloc.h"
 #include "xfs_rtalloc.h"
@@ -78,92 +79,74 @@
 	int			hsize;
 	xfs_handle_t		handle;
 	struct inode		*inode;
+	struct file		*file = NULL;
+	struct path		path;
+	int			error;
+	struct xfs_inode	*ip;
 
-	memset((char *)&handle, 0, sizeof(handle));
-
-	switch (cmd) {
-	case XFS_IOC_PATH_TO_FSHANDLE:
-	case XFS_IOC_PATH_TO_HANDLE: {
-		struct path path;
-		int error = user_lpath((const char __user *)hreq->path, &path);
-		if (error)
-			return error;
-
-		ASSERT(path.dentry);
-		ASSERT(path.dentry->d_inode);
-		inode = igrab(path.dentry->d_inode);
-		path_put(&path);
-		break;
-	}
-
-	case XFS_IOC_FD_TO_HANDLE: {
-		struct file	*file;
-
+	if (cmd == XFS_IOC_FD_TO_HANDLE) {
 		file = fget(hreq->fd);
 		if (!file)
-		    return -EBADF;
-
-		ASSERT(file->f_path.dentry);
-		ASSERT(file->f_path.dentry->d_inode);
-		inode = igrab(file->f_path.dentry->d_inode);
-		fput(file);
-		break;
+			return -EBADF;
+		inode = file->f_path.dentry->d_inode;
+	} else {
+		error = user_lpath((const char __user *)hreq->path, &path);
+		if (error)
+			return error;
+		inode = path.dentry->d_inode;
 	}
+	ip = XFS_I(inode);
 
-	default:
-		ASSERT(0);
-		return -XFS_ERROR(EINVAL);
-	}
+	/*
+	 * We can only generate handles for inodes residing on a XFS filesystem,
+	 * and only for regular files, directories or symbolic links.
+	 */
+	error = -EINVAL;
+	if (inode->i_sb->s_magic != XFS_SB_MAGIC)
+		goto out_put;
 
-	if (inode->i_sb->s_magic != XFS_SB_MAGIC) {
-		/* we're not in XFS anymore, Toto */
-		iput(inode);
-		return -XFS_ERROR(EINVAL);
-	}
+	error = -EBADF;
+	if (!S_ISREG(inode->i_mode) &&
+	    !S_ISDIR(inode->i_mode) &&
+	    !S_ISLNK(inode->i_mode))
+		goto out_put;
 
-	switch (inode->i_mode & S_IFMT) {
-	case S_IFREG:
-	case S_IFDIR:
-	case S_IFLNK:
-		break;
-	default:
-		iput(inode);
-		return -XFS_ERROR(EBADF);
-	}
 
-	/* now we can grab the fsid */
-	memcpy(&handle.ha_fsid, XFS_I(inode)->i_mount->m_fixedfsid,
-			sizeof(xfs_fsid_t));
-	hsize = sizeof(xfs_fsid_t);
+	memcpy(&handle.ha_fsid, ip->i_mount->m_fixedfsid, sizeof(xfs_fsid_t));
 
-	if (cmd != XFS_IOC_PATH_TO_FSHANDLE) {
-		xfs_inode_t	*ip = XFS_I(inode);
+	if (cmd == XFS_IOC_PATH_TO_FSHANDLE) {
+		/*
+		 * This handle only contains an fsid, zero the rest.
+		 */
+		memset(&handle.ha_fid, 0, sizeof(handle.ha_fid));
+		hsize = sizeof(xfs_fsid_t);
+	} else {
 		int		lock_mode;
 
-		/* need to get access to the xfs_inode to read the generation */
 		lock_mode = xfs_ilock_map_shared(ip);
-
-		/* fill in fid section of handle from inode */
 		handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
 					sizeof(handle.ha_fid.fid_len);
 		handle.ha_fid.fid_pad = 0;
 		handle.ha_fid.fid_gen = ip->i_d.di_gen;
 		handle.ha_fid.fid_ino = ip->i_ino;
-
 		xfs_iunlock_map_shared(ip, lock_mode);
 
 		hsize = XFS_HSIZE(handle);
 	}
 
-	/* now copy our handle into the user buffer & write out the size */
+	error = -EFAULT;
 	if (copy_to_user(hreq->ohandle, &handle, hsize) ||
-	    copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32))) {
-		iput(inode);
-		return -XFS_ERROR(EFAULT);
-	}
+	    copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32)))
+		goto out_put;
 
-	iput(inode);
-	return 0;
+	error = 0;
+
+ out_put:
+	if (cmd == XFS_IOC_FD_TO_HANDLE)
+		fput(file);
+	else
+		path_put(&path);
+	return error;
 }
 
 /*
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 2940612..6075382 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -211,8 +211,13 @@
 	 * Irix uses Missed'em'V split, but doesn't want to see
 	 * the upper 5 bits of (14bit) major.
 	 */
-	if (unlikely(!sysv_valid_dev(rdev) || MAJOR(rdev) & ~0x1ff))
-		return -EINVAL;
+	if (S_ISCHR(mode) || S_ISBLK(mode)) {
+		if (unlikely(!sysv_valid_dev(rdev) || MAJOR(rdev) & ~0x1ff))
+			return -EINVAL;
+		rdev = sysv_encode_dev(rdev);
+	} else {
+		rdev = 0;
+	}
 
 	if (test_default_acl && test_default_acl(dir)) {
 		if (!_ACL_ALLOC(default_acl)) {
@@ -224,28 +229,11 @@
 		}
 	}
 
-	xfs_dentry_to_name(&name, dentry);
-
 	if (IS_POSIXACL(dir) && !default_acl)
 		mode &= ~current_umask();
 
-	switch (mode & S_IFMT) {
-	case S_IFCHR:
-	case S_IFBLK:
-	case S_IFIFO:
-	case S_IFSOCK:
-		rdev = sysv_encode_dev(rdev);
-	case S_IFREG:
-		error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip, NULL);
-		break;
-	case S_IFDIR:
-		error = xfs_mkdir(XFS_I(dir), &name, mode, &ip, NULL);
-		break;
-	default:
-		error = EINVAL;
-		break;
-	}
-
+	xfs_dentry_to_name(&name, dentry);
+	error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip, NULL);
 	if (unlikely(error))
 		goto out_free_acl;
 
@@ -553,9 +541,6 @@
 	stat->uid = ip->i_d.di_uid;
 	stat->gid = ip->i_d.di_gid;
 	stat->ino = ip->i_ino;
-#if XFS_BIG_INUMS
-	stat->ino += mp->m_inoadd;
-#endif
 	stat->atime = inode->i_atime;
 	stat->mtime.tv_sec = ip->i_d.di_mtime.t_sec;
 	stat->mtime.tv_nsec = ip->i_d.di_mtime.t_nsec;
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
index 507492d..f65a53f 100644
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/linux-2.6/xfs_linux.h
@@ -38,7 +38,6 @@
 #include <kmem.h>
 #include <mrlock.h>
 #include <sv.h>
-#include <mutex.h>
 #include <time.h>
 
 #include <support/ktrace.h>
@@ -51,6 +50,7 @@
 #include <linux/blkdev.h>
 #include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/mutex.h>
 #include <linux/file.h>
 #include <linux/swap.h>
 #include <linux/errno.h>
@@ -147,17 +147,6 @@
 #define SYNCHRONIZE()	barrier()
 #define __return_address __builtin_return_address(0)
 
-/*
- * IRIX (BSD) quotactl makes use of separate commands for user/group,
- * whereas on Linux the syscall encodes this information into the cmd
- * field (see the QCMD macro in quota.h).  These macros help keep the
- * code portable - they are not visible from the syscall interface.
- */
-#define Q_XSETGQLIM	XQM_CMD(8)	/* set groups disk limits */
-#define Q_XGETGQUOTA	XQM_CMD(9)	/* get groups disk limits */
-#define Q_XSETPQLIM	XQM_CMD(10)	/* set projects disk limits */
-#define Q_XGETPQUOTA	XQM_CMD(11)	/* get projects disk limits */
-
 #define dfltprid	0
 #define MAXPATHLEN	1024
 
diff --git a/fs/xfs/linux-2.6/xfs_quotaops.c b/fs/xfs/linux-2.6/xfs_quotaops.c
new file mode 100644
index 0000000..94d9a63
--- /dev/null
+++ b/fs/xfs/linux-2.6/xfs_quotaops.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2008, Christoph Hellwig
+ * 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.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR 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 the Free Software Foundation,
+ * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include "xfs.h"
+#include "xfs_dmapi.h"
+#include "xfs_sb.h"
+#include "xfs_inum.h"
+#include "xfs_ag.h"
+#include "xfs_mount.h"
+#include "xfs_quota.h"
+#include "xfs_log.h"
+#include "xfs_trans.h"
+#include "xfs_bmap_btree.h"
+#include "xfs_inode.h"
+#include "quota/xfs_qm.h"
+#include <linux/quota.h>
+
+
+STATIC int
+xfs_quota_type(int type)
+{
+	switch (type) {
+	case USRQUOTA:
+		return XFS_DQ_USER;
+	case GRPQUOTA:
+		return XFS_DQ_GROUP;
+	default:
+		return XFS_DQ_PROJ;
+	}
+}
+
+STATIC int
+xfs_fs_quota_sync(
+	struct super_block	*sb,
+	int			type)
+{
+	struct xfs_mount	*mp = XFS_M(sb);
+
+	if (!XFS_IS_QUOTA_RUNNING(mp))
+		return -ENOSYS;
+	return -xfs_sync_inodes(mp, SYNC_DELWRI);
+}
+
+STATIC int
+xfs_fs_get_xstate(
+	struct super_block	*sb,
+	struct fs_quota_stat	*fqs)
+{
+	struct xfs_mount	*mp = XFS_M(sb);
+
+	if (!XFS_IS_QUOTA_RUNNING(mp))
+		return -ENOSYS;
+	return -xfs_qm_scall_getqstat(mp, fqs);
+}
+
+STATIC int
+xfs_fs_set_xstate(
+	struct super_block	*sb,
+	unsigned int		uflags,
+	int			op)
+{
+	struct xfs_mount	*mp = XFS_M(sb);
+	unsigned int		flags = 0;
+
+	if (sb->s_flags & MS_RDONLY)
+		return -EROFS;
+	if (!XFS_IS_QUOTA_RUNNING(mp))
+		return -ENOSYS;
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	if (uflags & XFS_QUOTA_UDQ_ACCT)
+		flags |= XFS_UQUOTA_ACCT;
+	if (uflags & XFS_QUOTA_PDQ_ACCT)
+		flags |= XFS_PQUOTA_ACCT;
+	if (uflags & XFS_QUOTA_GDQ_ACCT)
+		flags |= XFS_GQUOTA_ACCT;
+	if (uflags & XFS_QUOTA_UDQ_ENFD)
+		flags |= XFS_UQUOTA_ENFD;
+	if (uflags & (XFS_QUOTA_PDQ_ENFD|XFS_QUOTA_GDQ_ENFD))
+		flags |= XFS_OQUOTA_ENFD;
+
+	switch (op) {
+	case Q_XQUOTAON:
+		return -xfs_qm_scall_quotaon(mp, flags);
+	case Q_XQUOTAOFF:
+		if (!XFS_IS_QUOTA_ON(mp))
+			return -EINVAL;
+		return -xfs_qm_scall_quotaoff(mp, flags);
+	case Q_XQUOTARM:
+		if (XFS_IS_QUOTA_ON(mp))
+			return -EINVAL;
+		return -xfs_qm_scall_trunc_qfiles(mp, flags);
+	}
+
+	return -EINVAL;
+}
+
+STATIC int
+xfs_fs_get_xquota(
+	struct super_block	*sb,
+	int			type,
+	qid_t			id,
+	struct fs_disk_quota	*fdq)
+{
+	struct xfs_mount	*mp = XFS_M(sb);
+
+	if (!XFS_IS_QUOTA_RUNNING(mp))
+		return -ENOSYS;
+	if (!XFS_IS_QUOTA_ON(mp))
+		return -ESRCH;
+
+	return -xfs_qm_scall_getquota(mp, id, xfs_quota_type(type), fdq);
+}
+
+STATIC int
+xfs_fs_set_xquota(
+	struct super_block	*sb,
+	int			type,
+	qid_t			id,
+	struct fs_disk_quota	*fdq)
+{
+	struct xfs_mount	*mp = XFS_M(sb);
+
+	if (sb->s_flags & MS_RDONLY)
+		return -EROFS;
+	if (!XFS_IS_QUOTA_RUNNING(mp))
+		return -ENOSYS;
+	if (!XFS_IS_QUOTA_ON(mp))
+		return -ESRCH;
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	return -xfs_qm_scall_setqlim(mp, id, xfs_quota_type(type), fdq);
+}
+
+struct quotactl_ops xfs_quotactl_operations = {
+	.quota_sync		= xfs_fs_quota_sync,
+	.get_xstate		= xfs_fs_get_xstate,
+	.set_xstate		= xfs_fs_set_xstate,
+	.get_xquota		= xfs_fs_get_xquota,
+	.set_xquota		= xfs_fs_set_xquota,
+};
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 32ae502..bb68526 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -68,7 +68,6 @@
 #include <linux/freezer.h>
 #include <linux/parser.h>
 
-static struct quotactl_ops xfs_quotactl_operations;
 static struct super_operations xfs_super_operations;
 static kmem_zone_t *xfs_ioend_zone;
 mempool_t *xfs_ioend_pool;
@@ -79,7 +78,6 @@
 #define MNTOPT_RTDEV	"rtdev"		/* realtime I/O device */
 #define MNTOPT_BIOSIZE	"biosize"	/* log2 of preferred buffered io size */
 #define MNTOPT_WSYNC	"wsync"		/* safe-mode nfs compatible mount */
-#define MNTOPT_INO64	"ino64"		/* force inodes into 64-bit range */
 #define MNTOPT_NOALIGN	"noalign"	/* turn off stripe alignment */
 #define MNTOPT_SWALLOC	"swalloc"	/* turn on stripe width allocation */
 #define MNTOPT_SUNIT	"sunit"		/* data volume stripe unit */
@@ -180,7 +178,7 @@
 	int			dswidth = 0;
 	int			iosize = 0;
 	int			dmapi_implies_ikeep = 1;
-	uchar_t			iosizelog = 0;
+	__uint8_t		iosizelog = 0;
 
 	/*
 	 * Copy binary VFS mount flags we are interested in.
@@ -291,16 +289,6 @@
 			mp->m_flags |= XFS_MOUNT_OSYNCISOSYNC;
 		} else if (!strcmp(this_char, MNTOPT_NORECOVERY)) {
 			mp->m_flags |= XFS_MOUNT_NORECOVERY;
-		} else if (!strcmp(this_char, MNTOPT_INO64)) {
-#if XFS_BIG_INUMS
-			mp->m_flags |= XFS_MOUNT_INO64;
-			mp->m_inoadd = XFS_INO64_OFFSET;
-#else
-			cmn_err(CE_WARN,
-				"XFS: %s option not allowed on this system",
-				this_char);
-			return EINVAL;
-#endif
 		} else if (!strcmp(this_char, MNTOPT_NOALIGN)) {
 			mp->m_flags |= XFS_MOUNT_NOALIGN;
 		} else if (!strcmp(this_char, MNTOPT_SWALLOC)) {
@@ -529,7 +517,6 @@
 		/* the few simple ones we can get from the mount struct */
 		{ XFS_MOUNT_IKEEP,		"," MNTOPT_IKEEP },
 		{ XFS_MOUNT_WSYNC,		"," MNTOPT_WSYNC },
-		{ XFS_MOUNT_INO64,		"," MNTOPT_INO64 },
 		{ XFS_MOUNT_NOALIGN,		"," MNTOPT_NOALIGN },
 		{ XFS_MOUNT_SWALLOC,		"," MNTOPT_SWALLOC },
 		{ XFS_MOUNT_NOUUID,		"," MNTOPT_NOUUID },
@@ -634,7 +621,7 @@
 	return (((__uint64_t)pagefactor) << bitshift) - 1;
 }
 
-int
+STATIC int
 xfs_blkdev_get(
 	xfs_mount_t		*mp,
 	const char		*name,
@@ -651,7 +638,7 @@
 	return -error;
 }
 
-void
+STATIC void
 xfs_blkdev_put(
 	struct block_device	*bdev)
 {
@@ -872,7 +859,7 @@
 	wake_up_process(ailp->xa_task);
 }
 
-int
+STATIC int
 xfsaild(
 	void	*data)
 {
@@ -990,26 +977,57 @@
 	int			sync)
 {
 	struct xfs_inode	*ip = XFS_I(inode);
+	struct xfs_mount	*mp = ip->i_mount;
 	int			error = 0;
-	int			flags = 0;
 
 	xfs_itrace_entry(ip);
+
+	if (XFS_FORCED_SHUTDOWN(mp))
+		return XFS_ERROR(EIO);
+
 	if (sync) {
 		error = xfs_wait_on_pages(ip, 0, -1);
 		if (error)
-			goto out_error;
-		flags |= FLUSH_SYNC;
+			goto out;
 	}
-	error = xfs_inode_flush(ip, flags);
 
-out_error:
+	/*
+	 * Bypass inodes which have already been cleaned by
+	 * the inode flush clustering code inside xfs_iflush
+	 */
+	if (xfs_inode_clean(ip))
+		goto out;
+
+	/*
+	 * We make this non-blocking if the inode is contended, return
+	 * EAGAIN to indicate to the caller that they did not succeed.
+	 * This prevents the flush path from blocking on inodes inside
+	 * another operation right now, they get caught later by xfs_sync.
+	 */
+	if (sync) {
+		xfs_ilock(ip, XFS_ILOCK_SHARED);
+		xfs_iflock(ip);
+
+		error = xfs_iflush(ip, XFS_IFLUSH_SYNC);
+	} else {
+		error = EAGAIN;
+		if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED))
+			goto out;
+		if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip))
+			goto out_unlock;
+
+		error = xfs_iflush(ip, XFS_IFLUSH_ASYNC_NOBLOCK);
+	}
+
+ out_unlock:
+	xfs_iunlock(ip, XFS_ILOCK_SHARED);
+ out:
 	/*
 	 * if we failed to write out the inode then mark
 	 * it dirty again so we'll try again later.
 	 */
 	if (error)
 		xfs_mark_inode_dirty_sync(ip);
-
 	return -error;
 }
 
@@ -1169,18 +1187,12 @@
 	statp->f_bfree = statp->f_bavail =
 				sbp->sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp);
 	fakeinos = statp->f_bfree << sbp->sb_inopblog;
-#if XFS_BIG_INUMS
-	fakeinos += mp->m_inoadd;
-#endif
 	statp->f_files =
 	    MIN(sbp->sb_icount + fakeinos, (__uint64_t)XFS_MAXINUMBER);
 	if (mp->m_maxicount)
-#if XFS_BIG_INUMS
-		if (!mp->m_inoadd)
-#endif
-			statp->f_files = min_t(typeof(statp->f_files),
-						statp->f_files,
-						mp->m_maxicount);
+		statp->f_files = min_t(typeof(statp->f_files),
+					statp->f_files,
+					mp->m_maxicount);
 	statp->f_ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree);
 	spin_unlock(&mp->m_sb_lock);
 
@@ -1302,57 +1314,6 @@
 	return -xfs_showargs(XFS_M(mnt->mnt_sb), m);
 }
 
-STATIC int
-xfs_fs_quotasync(
-	struct super_block	*sb,
-	int			type)
-{
-	return -XFS_QM_QUOTACTL(XFS_M(sb), Q_XQUOTASYNC, 0, NULL);
-}
-
-STATIC int
-xfs_fs_getxstate(
-	struct super_block	*sb,
-	struct fs_quota_stat	*fqs)
-{
-	return -XFS_QM_QUOTACTL(XFS_M(sb), Q_XGETQSTAT, 0, (caddr_t)fqs);
-}
-
-STATIC int
-xfs_fs_setxstate(
-	struct super_block	*sb,
-	unsigned int		flags,
-	int			op)
-{
-	return -XFS_QM_QUOTACTL(XFS_M(sb), op, 0, (caddr_t)&flags);
-}
-
-STATIC int
-xfs_fs_getxquota(
-	struct super_block	*sb,
-	int			type,
-	qid_t			id,
-	struct fs_disk_quota	*fdq)
-{
-	return -XFS_QM_QUOTACTL(XFS_M(sb),
-				 (type == USRQUOTA) ? Q_XGETQUOTA :
-				  ((type == GRPQUOTA) ? Q_XGETGQUOTA :
-				   Q_XGETPQUOTA), id, (caddr_t)fdq);
-}
-
-STATIC int
-xfs_fs_setxquota(
-	struct super_block	*sb,
-	int			type,
-	qid_t			id,
-	struct fs_disk_quota	*fdq)
-{
-	return -XFS_QM_QUOTACTL(XFS_M(sb),
-				 (type == USRQUOTA) ? Q_XSETQLIM :
-				  ((type == GRPQUOTA) ? Q_XSETGQLIM :
-				   Q_XSETPQLIM), id, (caddr_t)fdq);
-}
-
 /*
  * This function fills in xfs_mount_t fields based on mount args.
  * Note: the superblock _has_ now been read in.
@@ -1435,7 +1396,9 @@
 	sb_min_blocksize(sb, BBSIZE);
 	sb->s_xattr = xfs_xattr_handlers;
 	sb->s_export_op = &xfs_export_operations;
+#ifdef CONFIG_XFS_QUOTA
 	sb->s_qcop = &xfs_quotactl_operations;
+#endif
 	sb->s_op = &xfs_super_operations;
 
 	error = xfs_dmops_get(mp);
@@ -1578,14 +1541,6 @@
 	.show_options		= xfs_fs_show_options,
 };
 
-static struct quotactl_ops xfs_quotactl_operations = {
-	.quota_sync		= xfs_fs_quotasync,
-	.get_xstate		= xfs_fs_getxstate,
-	.set_xstate		= xfs_fs_setxstate,
-	.get_xquota		= xfs_fs_getxquota,
-	.set_xquota		= xfs_fs_setxquota,
-};
-
 static struct file_system_type xfs_fs_type = {
 	.owner			= THIS_MODULE,
 	.name			= "xfs",
diff --git a/fs/xfs/linux-2.6/xfs_super.h b/fs/xfs/linux-2.6/xfs_super.h
index d5d776d..5a2ea3a 100644
--- a/fs/xfs/linux-2.6/xfs_super.h
+++ b/fs/xfs/linux-2.6/xfs_super.h
@@ -93,6 +93,7 @@
 
 extern const struct export_operations xfs_export_operations;
 extern struct xattr_handler *xfs_xattr_handlers[];
+extern struct quotactl_ops xfs_quotactl_operations;
 
 #define XFS_M(sb)		((struct xfs_mount *)((sb)->s_fs_info))
 
diff --git a/fs/xfs/linux-2.6/xfs_sync.h b/fs/xfs/linux-2.6/xfs_sync.h
index 5f6de1e..04f058c 100644
--- a/fs/xfs/linux-2.6/xfs_sync.h
+++ b/fs/xfs/linux-2.6/xfs_sync.h
@@ -19,6 +19,7 @@
 #define XFS_SYNC_H 1
 
 struct xfs_mount;
+struct xfs_perag;
 
 typedef struct bhv_vfs_sync_work {
 	struct list_head	w_list;
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index f65983a..ad7fbea 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -41,11 +41,6 @@
 #define IO_INVIS	0x00020		/* don't update inode timestamps */
 
 /*
- * Flags for xfs_inode_flush
- */
-#define FLUSH_SYNC		1	/* wait for flush to complete	*/
-
-/*
  * Flush/Invalidate options for vop_toss/flush/flushinval_pages.
  */
 #define FI_NONE			0	/* none */
@@ -55,33 +50,6 @@
 					   the operation completes. */
 
 /*
- * Dealing with bad inodes
- */
-static inline int VN_BAD(struct inode *vp)
-{
-	return is_bad_inode(vp);
-}
-
-/*
- * Extracting atime values in various formats
- */
-static inline void vn_atime_to_bstime(struct inode *vp, xfs_bstime_t *bs_atime)
-{
-	bs_atime->tv_sec = vp->i_atime.tv_sec;
-	bs_atime->tv_nsec = vp->i_atime.tv_nsec;
-}
-
-static inline void vn_atime_to_timespec(struct inode *vp, struct timespec *ts)
-{
-	*ts = vp->i_atime;
-}
-
-static inline void vn_atime_to_time_t(struct inode *vp, time_t *tt)
-{
-	*tt = vp->i_atime.tv_sec;
-}
-
-/*
  * Some useful predicates.
  */
 #define VN_MAPPED(vp)	mapping_mapped(vp->i_mapping)
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c
index 6543c0b..e4babcc 100644
--- a/fs/xfs/quota/xfs_dquot.c
+++ b/fs/xfs/quota/xfs_dquot.c
@@ -804,7 +804,7 @@
 	uint			flist_locked;
 	xfs_dquot_t		*d;
 
-	ASSERT(XFS_DQ_IS_HASH_LOCKED(qh));
+	ASSERT(mutex_is_locked(&qh->qh_lock));
 
 	flist_locked = B_FALSE;
 
@@ -877,7 +877,7 @@
 			/*
 			 * move the dquot to the front of the hashchain
 			 */
-			ASSERT(XFS_DQ_IS_HASH_LOCKED(qh));
+			ASSERT(mutex_is_locked(&qh->qh_lock));
 			if (dqp->HL_PREVP != &qh->qh_next) {
 				xfs_dqtrace_entry(dqp,
 						  "DQLOOKUP: HASH MOVETOFRONT");
@@ -892,13 +892,13 @@
 			}
 			xfs_dqtrace_entry(dqp, "LOOKUP END");
 			*O_dqpp = dqp;
-			ASSERT(XFS_DQ_IS_HASH_LOCKED(qh));
+			ASSERT(mutex_is_locked(&qh->qh_lock));
 			return (0);
 		}
 	}
 
 	*O_dqpp = NULL;
-	ASSERT(XFS_DQ_IS_HASH_LOCKED(qh));
+	ASSERT(mutex_is_locked(&qh->qh_lock));
 	return (1);
 }
 
@@ -956,7 +956,7 @@
 			ASSERT(ip->i_gdquot == NULL);
 	}
 #endif
-	XFS_DQ_HASH_LOCK(h);
+	mutex_lock(&h->qh_lock);
 
 	/*
 	 * Look in the cache (hashtable).
@@ -971,7 +971,7 @@
 		 */
 		ASSERT(*O_dqpp);
 		ASSERT(XFS_DQ_IS_LOCKED(*O_dqpp));
-		XFS_DQ_HASH_UNLOCK(h);
+		mutex_unlock(&h->qh_lock);
 		xfs_dqtrace_entry(*O_dqpp, "DQGET DONE (FROM CACHE)");
 		return (0);	/* success */
 	}
@@ -991,7 +991,7 @@
 	 * we don't keep the lock across a disk read
 	 */
 	version = h->qh_version;
-	XFS_DQ_HASH_UNLOCK(h);
+	mutex_unlock(&h->qh_lock);
 
 	/*
 	 * Allocate the dquot on the kernel heap, and read the ondisk
@@ -1056,7 +1056,7 @@
 	/*
 	 * Hashlock comes after ilock in lock order
 	 */
-	XFS_DQ_HASH_LOCK(h);
+	mutex_lock(&h->qh_lock);
 	if (version != h->qh_version) {
 		xfs_dquot_t *tmpdqp;
 		/*
@@ -1072,7 +1072,7 @@
 			 * and start over.
 			 */
 			xfs_qm_dqput(tmpdqp);
-			XFS_DQ_HASH_UNLOCK(h);
+			mutex_unlock(&h->qh_lock);
 			xfs_qm_dqdestroy(dqp);
 			XQM_STATS_INC(xqmstats.xs_qm_dquot_dups);
 			goto again;
@@ -1083,7 +1083,7 @@
 	 * Put the dquot at the beginning of the hash-chain and mp's list
 	 * LOCK ORDER: hashlock, freelistlock, mplistlock, udqlock, gdqlock ..
 	 */
-	ASSERT(XFS_DQ_IS_HASH_LOCKED(h));
+	ASSERT(mutex_is_locked(&h->qh_lock));
 	dqp->q_hash = h;
 	XQM_HASHLIST_INSERT(h, dqp);
 
@@ -1102,7 +1102,7 @@
 	XQM_MPLIST_INSERT(&(XFS_QI_MPL_LIST(mp)), dqp);
 
 	xfs_qm_mplist_unlock(mp);
-	XFS_DQ_HASH_UNLOCK(h);
+	mutex_unlock(&h->qh_lock);
  dqret:
 	ASSERT((ip == NULL) || xfs_isilocked(ip, XFS_ILOCK_EXCL));
 	xfs_dqtrace_entry(dqp, "DQGET DONE");
@@ -1440,7 +1440,7 @@
 	xfs_mount_t	*mp = dqp->q_mount;
 
 	ASSERT(XFS_QM_IS_MPLIST_LOCKED(mp));
-	ASSERT(XFS_DQ_IS_HASH_LOCKED(dqp->q_hash));
+	ASSERT(mutex_is_locked(&dqp->q_hash->qh_lock));
 
 	xfs_dqlock(dqp);
 	/*
@@ -1453,7 +1453,7 @@
 	 */
 	if (dqp->q_nrefs != 0) {
 		xfs_dqunlock(dqp);
-		XFS_DQ_HASH_UNLOCK(dqp->q_hash);
+		mutex_unlock(&dqp->q_hash->qh_lock);
 		return (1);
 	}
 
@@ -1517,7 +1517,7 @@
 	memset(&dqp->q_core, 0, sizeof(dqp->q_core));
 	xfs_dqfunlock(dqp);
 	xfs_dqunlock(dqp);
-	XFS_DQ_HASH_UNLOCK(thishash);
+	mutex_unlock(&thishash->qh_lock);
 	return (0);
 }
 
diff --git a/fs/xfs/quota/xfs_dquot.h b/fs/xfs/quota/xfs_dquot.h
index d443e93..de0f402 100644
--- a/fs/xfs/quota/xfs_dquot.h
+++ b/fs/xfs/quota/xfs_dquot.h
@@ -34,7 +34,7 @@
  */
 typedef struct xfs_dqhash {
 	struct xfs_dquot *qh_next;
-	mutex_t		  qh_lock;
+	struct mutex	  qh_lock;
 	uint		  qh_version;	/* ever increasing version */
 	uint		  qh_nelems;	/* number of dquots on the list */
 } xfs_dqhash_t;
@@ -81,7 +81,7 @@
 	xfs_qcnt_t	 q_res_bcount;	/* total regular nblks used+reserved */
 	xfs_qcnt_t	 q_res_icount;	/* total inos allocd+reserved */
 	xfs_qcnt_t	 q_res_rtbcount;/* total realtime blks used+reserved */
-	mutex_t		 q_qlock;	/* quota lock */
+	struct mutex	 q_qlock;	/* quota lock */
 	struct completion q_flush;	/* flush completion queue */
 	atomic_t          q_pincount;	/* dquot pin count */
 	wait_queue_head_t q_pinwait;	/* dquot pinning wait queue */
@@ -109,19 +109,6 @@
 
 #define XFS_DQHOLD(dqp)		((dqp)->q_nrefs++)
 
-#ifdef DEBUG
-static inline int
-XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
-{
-	if (mutex_trylock(&dqp->q_qlock)) {
-		mutex_unlock(&dqp->q_qlock);
-		return 0;
-	}
-	return 1;
-}
-#endif
-
-
 /*
  * Manage the q_flush completion queue embedded in the dquot.  This completion
  * queue synchronizes processes attempting to flush the in-core dquot back to
@@ -142,6 +129,7 @@
 	complete(&dqp->q_flush);
 }
 
+#define XFS_DQ_IS_LOCKED(dqp)	(mutex_is_locked(&((dqp)->q_qlock)))
 #define XFS_DQ_IS_ON_FREELIST(dqp)  ((dqp)->dq_flnext != (dqp))
 #define XFS_DQ_IS_DIRTY(dqp)	((dqp)->dq_flags & XFS_DQ_DIRTY)
 #define XFS_QM_ISUDQ(dqp)	((dqp)->dq_flags & XFS_DQ_USER)
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 7a2beb6..5b66950 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -55,7 +55,7 @@
  * quota functionality, including maintaining the freelist and hash
  * tables of dquots.
  */
-mutex_t		xfs_Gqm_lock;
+struct mutex	xfs_Gqm_lock;
 struct xfs_qm	*xfs_Gqm;
 uint		ndquot;
 
@@ -69,8 +69,6 @@
 
 STATIC void	xfs_qm_freelist_init(xfs_frlist_t *);
 STATIC void	xfs_qm_freelist_destroy(xfs_frlist_t *);
-STATIC int	xfs_qm_mplist_nowait(xfs_mount_t *);
-STATIC int	xfs_qm_dqhashlock_nowait(xfs_dquot_t *);
 
 STATIC int	xfs_qm_init_quotainos(xfs_mount_t *);
 STATIC int	xfs_qm_init_quotainfo(xfs_mount_t *);
@@ -82,7 +80,7 @@
 };
 
 #ifdef DEBUG
-extern mutex_t	qcheck_lock;
+extern struct mutex	qcheck_lock;
 #endif
 
 #ifdef QUOTADEBUG
@@ -219,7 +217,7 @@
 	 * the structure could disappear between the entry to this routine and
 	 * a HOLD operation if not locked.
 	 */
-	XFS_QM_LOCK(xfs_Gqm);
+	mutex_lock(&xfs_Gqm_lock);
 
 	if (xfs_Gqm == NULL)
 		xfs_Gqm = xfs_Gqm_init();
@@ -228,8 +226,8 @@
 	 * debugging and statistical purposes, but ...
 	 * Just take a reference and get out.
 	 */
-	XFS_QM_HOLD(xfs_Gqm);
-	XFS_QM_UNLOCK(xfs_Gqm);
+	xfs_Gqm->qm_nrefs++;
+	mutex_unlock(&xfs_Gqm_lock);
 
 	return 0;
 }
@@ -277,13 +275,12 @@
 	 * Destroy the entire XQM. If somebody mounts with quotaon, this'll
 	 * be restarted.
 	 */
-	XFS_QM_LOCK(xfs_Gqm);
-	XFS_QM_RELE(xfs_Gqm);
-	if (xfs_Gqm->qm_nrefs == 0) {
+	mutex_lock(&xfs_Gqm_lock);
+	if (--xfs_Gqm->qm_nrefs == 0) {
 		xfs_qm_destroy(xfs_Gqm);
 		xfs_Gqm = NULL;
 	}
-	XFS_QM_UNLOCK(xfs_Gqm);
+	mutex_unlock(&xfs_Gqm_lock);
 }
 
 /*
@@ -577,10 +574,10 @@
 			continue;
 		}
 
-		if (! xfs_qm_dqhashlock_nowait(dqp)) {
+		if (!mutex_trylock(&dqp->q_hash->qh_lock)) {
 			nrecl = XFS_QI_MPLRECLAIMS(mp);
 			xfs_qm_mplist_unlock(mp);
-			XFS_DQ_HASH_LOCK(dqp->q_hash);
+			mutex_lock(&dqp->q_hash->qh_lock);
 			xfs_qm_mplist_lock(mp);
 
 			/*
@@ -590,7 +587,7 @@
 			 * this point, but somebody might be taking things off.
 			 */
 			if (nrecl != XFS_QI_MPLRECLAIMS(mp)) {
-				XFS_DQ_HASH_UNLOCK(dqp->q_hash);
+				mutex_unlock(&dqp->q_hash->qh_lock);
 				goto again;
 			}
 		}
@@ -632,7 +629,6 @@
 	xfs_dqid_t	id,
 	uint		type,
 	uint		doalloc,
-	uint		dolock,
 	xfs_dquot_t	*udqhint, /* hint */
 	xfs_dquot_t	**IO_idqpp)
 {
@@ -641,16 +637,16 @@
 
 	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
 	error = 0;
+
 	/*
 	 * See if we already have it in the inode itself. IO_idqpp is
 	 * &i_udquot or &i_gdquot. This made the code look weird, but
 	 * made the logic a lot simpler.
 	 */
-	if ((dqp = *IO_idqpp)) {
-		if (dolock)
-			xfs_dqlock(dqp);
+	dqp = *IO_idqpp;
+	if (dqp) {
 		xfs_dqtrace_entry(dqp, "DQATTACH: found in ip");
-		goto done;
+		return 0;
 	}
 
 	/*
@@ -659,38 +655,38 @@
 	 * lookup by dqid (xfs_qm_dqget) by caching a group dquot inside
 	 * the user dquot.
 	 */
-	ASSERT(!udqhint || type == XFS_DQ_GROUP || type == XFS_DQ_PROJ);
-	if (udqhint && !dolock)
+	if (udqhint) {
+		ASSERT(type == XFS_DQ_GROUP || type == XFS_DQ_PROJ);
 		xfs_dqlock(udqhint);
 
-	/*
-	 * No need to take dqlock to look at the id.
-	 * The ID can't change until it gets reclaimed, and it won't
-	 * be reclaimed as long as we have a ref from inode and we hold
-	 * the ilock.
-	 */
-	if (udqhint &&
-	    (dqp = udqhint->q_gdquot) &&
-	    (be32_to_cpu(dqp->q_core.d_id) == id)) {
-		ASSERT(XFS_DQ_IS_LOCKED(udqhint));
-		xfs_dqlock(dqp);
-		XFS_DQHOLD(dqp);
-		ASSERT(*IO_idqpp == NULL);
-		*IO_idqpp = dqp;
-		if (!dolock) {
+		/*
+		 * No need to take dqlock to look at the id.
+		 *
+		 * The ID can't change until it gets reclaimed, and it won't
+		 * be reclaimed as long as we have a ref from inode and we
+		 * hold the ilock.
+		 */
+		dqp = udqhint->q_gdquot;
+		if (dqp && be32_to_cpu(dqp->q_core.d_id) == id) {
+			xfs_dqlock(dqp);
+			XFS_DQHOLD(dqp);
+			ASSERT(*IO_idqpp == NULL);
+			*IO_idqpp = dqp;
+
 			xfs_dqunlock(dqp);
 			xfs_dqunlock(udqhint);
+			return 0;
 		}
-		goto done;
-	}
-	/*
-	 * We can't hold a dquot lock when we call the dqget code.
-	 * We'll deadlock in no time, because of (not conforming to)
-	 * lock ordering - the inodelock comes before any dquot lock,
-	 * and we may drop and reacquire the ilock in xfs_qm_dqget().
-	 */
-	if (udqhint)
+
+		/*
+		 * We can't hold a dquot lock when we call the dqget code.
+		 * We'll deadlock in no time, because of (not conforming to)
+		 * lock ordering - the inodelock comes before any dquot lock,
+		 * and we may drop and reacquire the ilock in xfs_qm_dqget().
+		 */
 		xfs_dqunlock(udqhint);
+	}
+
 	/*
 	 * Find the dquot from somewhere. This bumps the
 	 * reference count of dquot and returns it locked.
@@ -698,48 +694,19 @@
 	 * disk and we didn't ask it to allocate;
 	 * ESRCH if quotas got turned off suddenly.
 	 */
-	if ((error = xfs_qm_dqget(ip->i_mount, ip, id, type,
-				 doalloc|XFS_QMOPT_DOWARN, &dqp))) {
-		if (udqhint && dolock)
-			xfs_dqlock(udqhint);
-		goto done;
-	}
+	error = xfs_qm_dqget(ip->i_mount, ip, id, type, XFS_QMOPT_DOWARN, &dqp);
+	if (error)
+		return error;
 
 	xfs_dqtrace_entry(dqp, "DQATTACH: found by dqget");
+
 	/*
 	 * dqget may have dropped and re-acquired the ilock, but it guarantees
 	 * that the dquot returned is the one that should go in the inode.
 	 */
 	*IO_idqpp = dqp;
-	ASSERT(dqp);
-	ASSERT(XFS_DQ_IS_LOCKED(dqp));
-	if (! dolock) {
-		xfs_dqunlock(dqp);
-		goto done;
-	}
-	if (! udqhint)
-		goto done;
-
-	ASSERT(udqhint);
-	ASSERT(dolock);
-	ASSERT(XFS_DQ_IS_LOCKED(dqp));
-	if (! xfs_qm_dqlock_nowait(udqhint)) {
-		xfs_dqunlock(dqp);
-		xfs_dqlock(udqhint);
-		xfs_dqlock(dqp);
-	}
-      done:
-#ifdef QUOTADEBUG
-	if (udqhint) {
-		if (dolock)
-			ASSERT(XFS_DQ_IS_LOCKED(udqhint));
-	}
-	if (! error) {
-		if (dolock)
-			ASSERT(XFS_DQ_IS_LOCKED(dqp));
-	}
-#endif
-	return error;
+	xfs_dqunlock(dqp);
+	return 0;
 }
 
 
@@ -754,24 +721,15 @@
 STATIC void
 xfs_qm_dqattach_grouphint(
 	xfs_dquot_t	*udq,
-	xfs_dquot_t	*gdq,
-	uint		locked)
+	xfs_dquot_t	*gdq)
 {
 	xfs_dquot_t	*tmp;
 
-#ifdef QUOTADEBUG
-	if (locked) {
-		ASSERT(XFS_DQ_IS_LOCKED(udq));
-		ASSERT(XFS_DQ_IS_LOCKED(gdq));
-	}
-#endif
-	if (! locked)
-		xfs_dqlock(udq);
+	xfs_dqlock(udq);
 
 	if ((tmp = udq->q_gdquot)) {
 		if (tmp == gdq) {
-			if (! locked)
-				xfs_dqunlock(udq);
+			xfs_dqunlock(udq);
 			return;
 		}
 
@@ -781,8 +739,6 @@
 		 * because the freelist lock comes before dqlocks.
 		 */
 		xfs_dqunlock(udq);
-		if (locked)
-			xfs_dqunlock(gdq);
 		/*
 		 * we took a hard reference once upon a time in dqget,
 		 * so give it back when the udquot no longer points at it
@@ -795,9 +751,7 @@
 
 	} else {
 		ASSERT(XFS_DQ_IS_LOCKED(udq));
-		if (! locked) {
-			xfs_dqlock(gdq);
-		}
+		xfs_dqlock(gdq);
 	}
 
 	ASSERT(XFS_DQ_IS_LOCKED(udq));
@@ -810,10 +764,9 @@
 		XFS_DQHOLD(gdq);
 		udq->q_gdquot = gdq;
 	}
-	if (! locked) {
-		xfs_dqunlock(gdq);
-		xfs_dqunlock(udq);
-	}
+
+	xfs_dqunlock(gdq);
+	xfs_dqunlock(udq);
 }
 
 
@@ -821,8 +774,6 @@
  * Given a locked inode, attach dquot(s) to it, taking U/G/P-QUOTAON
  * into account.
  * If XFS_QMOPT_DQALLOC, the dquot(s) will be allocated if needed.
- * If XFS_QMOPT_DQLOCK, the dquot(s) will be returned locked. This option pretty
- * much made this code a complete mess, but it has been pretty useful.
  * If XFS_QMOPT_ILOCKED, then inode sent is already locked EXCL.
  * Inode may get unlocked and relocked in here, and the caller must deal with
  * the consequences.
@@ -851,7 +802,6 @@
 	if (XFS_IS_UQUOTA_ON(mp)) {
 		error = xfs_qm_dqattach_one(ip, ip->i_d.di_uid, XFS_DQ_USER,
 						flags & XFS_QMOPT_DQALLOC,
-						flags & XFS_QMOPT_DQLOCK,
 						NULL, &ip->i_udquot);
 		if (error)
 			goto done;
@@ -863,11 +813,9 @@
 		error = XFS_IS_GQUOTA_ON(mp) ?
 			xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
 						flags & XFS_QMOPT_DQALLOC,
-						flags & XFS_QMOPT_DQLOCK,
 						ip->i_udquot, &ip->i_gdquot) :
 			xfs_qm_dqattach_one(ip, ip->i_d.di_projid, XFS_DQ_PROJ,
 						flags & XFS_QMOPT_DQALLOC,
-						flags & XFS_QMOPT_DQLOCK,
 						ip->i_udquot, &ip->i_gdquot);
 		/*
 		 * Don't worry about the udquot that we may have
@@ -898,22 +846,13 @@
 		/*
 		 * Attach i_gdquot to the gdquot hint inside the i_udquot.
 		 */
-		xfs_qm_dqattach_grouphint(ip->i_udquot, ip->i_gdquot,
-					 flags & XFS_QMOPT_DQLOCK);
+		xfs_qm_dqattach_grouphint(ip->i_udquot, ip->i_gdquot);
 	}
 
       done:
 
 #ifdef QUOTADEBUG
 	if (! error) {
-		if (ip->i_udquot) {
-			if (flags & XFS_QMOPT_DQLOCK)
-				ASSERT(XFS_DQ_IS_LOCKED(ip->i_udquot));
-		}
-		if (ip->i_gdquot) {
-			if (flags & XFS_QMOPT_DQLOCK)
-				ASSERT(XFS_DQ_IS_LOCKED(ip->i_gdquot));
-		}
 		if (XFS_IS_UQUOTA_ON(mp))
 			ASSERT(ip->i_udquot);
 		if (XFS_IS_OQUOTA_ON(mp))
@@ -2086,7 +2025,7 @@
 		 * a dqlookup process that holds the hashlock that is
 		 * waiting for the freelist lock.
 		 */
-		if (! xfs_qm_dqhashlock_nowait(dqp)) {
+		if (!mutex_trylock(&dqp->q_hash->qh_lock)) {
 			xfs_dqfunlock(dqp);
 			xfs_dqunlock(dqp);
 			dqp = dqp->dq_flnext;
@@ -2103,7 +2042,7 @@
 			/* XXX put a sentinel so that we can come back here */
 			xfs_dqfunlock(dqp);
 			xfs_dqunlock(dqp);
-			XFS_DQ_HASH_UNLOCK(hash);
+			mutex_unlock(&hash->qh_lock);
 			xfs_qm_freelist_unlock(xfs_Gqm);
 			if (++restarts >= XFS_QM_RECLAIM_MAX_RESTARTS)
 				return nreclaimed;
@@ -2120,7 +2059,7 @@
 		XQM_HASHLIST_REMOVE(hash, dqp);
 		xfs_dqfunlock(dqp);
 		xfs_qm_mplist_unlock(dqp->q_mount);
-		XFS_DQ_HASH_UNLOCK(hash);
+		mutex_unlock(&hash->qh_lock);
 
  off_freelist:
 		XQM_FREELIST_REMOVE(dqp);
@@ -2262,7 +2201,7 @@
 			continue;
 		}
 
-		if (! xfs_qm_dqhashlock_nowait(dqp))
+		if (!mutex_trylock(&dqp->q_hash->qh_lock))
 			goto mplistunlock;
 
 		ASSERT(dqp->q_nrefs == 0);
@@ -2271,7 +2210,7 @@
 		XQM_HASHLIST_REMOVE(dqp->q_hash, dqp);
 		XQM_FREELIST_REMOVE(dqp);
 		dqpout = dqp;
-		XFS_DQ_HASH_UNLOCK(dqp->q_hash);
+		mutex_unlock(&dqp->q_hash->qh_lock);
  mplistunlock:
 		xfs_qm_mplist_unlock(dqp->q_mount);
 		xfs_dqfunlock(dqp);
@@ -2774,34 +2713,3 @@
 {
 	xfs_qm_freelist_insert((xfs_frlist_t *)ql->qh_prev, dq);
 }
-
-STATIC int
-xfs_qm_dqhashlock_nowait(
-	xfs_dquot_t *dqp)
-{
-	int locked;
-
-	locked = mutex_trylock(&((dqp)->q_hash->qh_lock));
-	return locked;
-}
-
-int
-xfs_qm_freelist_lock_nowait(
-	xfs_qm_t *xqm)
-{
-	int locked;
-
-	locked = mutex_trylock(&(xqm->qm_dqfreelist.qh_lock));
-	return locked;
-}
-
-STATIC int
-xfs_qm_mplist_nowait(
-	xfs_mount_t	*mp)
-{
-	int locked;
-
-	ASSERT(mp->m_quotainfo);
-	locked = mutex_trylock(&(XFS_QI_MPLLOCK(mp)));
-	return locked;
-}
diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h
index ddf0916..a371954 100644
--- a/fs/xfs/quota/xfs_qm.h
+++ b/fs/xfs/quota/xfs_qm.h
@@ -27,7 +27,7 @@
 struct xfs_inode;
 
 extern uint		ndquot;
-extern mutex_t		xfs_Gqm_lock;
+extern struct mutex	xfs_Gqm_lock;
 extern struct xfs_qm	*xfs_Gqm;
 extern kmem_zone_t	*qm_dqzone;
 extern kmem_zone_t	*qm_dqtrxzone;
@@ -79,7 +79,7 @@
 typedef struct xfs_frlist {
        struct xfs_dquot *qh_next;
        struct xfs_dquot *qh_prev;
-       mutex_t		 qh_lock;
+       struct mutex	 qh_lock;
        uint		 qh_version;
        uint		 qh_nelems;
 } xfs_frlist_t;
@@ -115,7 +115,7 @@
 	xfs_qwarncnt_t	 qi_bwarnlimit;	 /* limit for blks warnings */
 	xfs_qwarncnt_t	 qi_iwarnlimit;	 /* limit for inodes warnings */
 	xfs_qwarncnt_t	 qi_rtbwarnlimit;/* limit for rt blks warnings */
-	mutex_t		 qi_quotaofflock;/* to serialize quotaoff */
+	struct mutex	 qi_quotaofflock;/* to serialize quotaoff */
 	xfs_filblks_t	 qi_dqchunklen;	 /* # BBs in a chunk of dqs */
 	uint		 qi_dqperchunk;	 /* # ondisk dqs in above chunk */
 	xfs_qcnt_t	 qi_bhardlimit;	 /* default data blk hard limit */
@@ -158,11 +158,6 @@
 #define XFS_QM_IWARNLIMIT	5
 #define XFS_QM_RTBWARNLIMIT	5
 
-#define XFS_QM_LOCK(xqm)	(mutex_lock(&xqm##_lock))
-#define XFS_QM_UNLOCK(xqm)	(mutex_unlock(&xqm##_lock))
-#define XFS_QM_HOLD(xqm)	((xqm)->qm_nrefs++)
-#define XFS_QM_RELE(xqm)	((xqm)->qm_nrefs--)
-
 extern void		xfs_qm_destroy_quotainfo(xfs_mount_t *);
 extern void		xfs_qm_mount_quotas(xfs_mount_t *);
 extern int		xfs_qm_quotacheck(xfs_mount_t *);
@@ -178,6 +173,16 @@
 extern int		xfs_qm_dqpurge_all(xfs_mount_t *, uint);
 extern void		xfs_qm_dqrele_all_inodes(xfs_mount_t *, uint);
 
+/* quota ops */
+extern int		xfs_qm_scall_trunc_qfiles(xfs_mount_t *, uint);
+extern int		xfs_qm_scall_getquota(xfs_mount_t *, xfs_dqid_t, uint,
+					fs_disk_quota_t *);
+extern int		xfs_qm_scall_setqlim(xfs_mount_t *, xfs_dqid_t, uint,
+					fs_disk_quota_t *);
+extern int		xfs_qm_scall_getqstat(xfs_mount_t *, fs_quota_stat_t *);
+extern int		xfs_qm_scall_quotaon(xfs_mount_t *, uint);
+extern int		xfs_qm_scall_quotaoff(xfs_mount_t *, uint);
+
 /* vop stuff */
 extern int		xfs_qm_vop_dqalloc(xfs_mount_t *, xfs_inode_t *,
 					uid_t, gid_t, prid_t, uint,
@@ -194,11 +199,6 @@
 /* list stuff */
 extern void		xfs_qm_freelist_append(xfs_frlist_t *, xfs_dquot_t *);
 extern void		xfs_qm_freelist_unlink(xfs_dquot_t *);
-extern int		xfs_qm_freelist_lock_nowait(xfs_qm_t *);
-
-/* system call interface */
-extern int		xfs_qm_quotactl(struct xfs_mount *, int, int,
-				xfs_caddr_t);
 
 #ifdef DEBUG
 extern int		xfs_qm_internalqcheck(xfs_mount_t *);
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c
index bc6c5cc..63037c6 100644
--- a/fs/xfs/quota/xfs_qm_bhv.c
+++ b/fs/xfs/quota/xfs_qm_bhv.c
@@ -235,7 +235,6 @@
 	.xfs_dqvopchownresv	= xfs_qm_vop_chown_reserve,
 	.xfs_dqstatvfs		= xfs_qm_statvfs,
 	.xfs_dqsync		= xfs_qm_sync,
-	.xfs_quotactl		= xfs_qm_quotactl,
 	.xfs_dqtrxops		= &xfs_trans_dquot_ops,
 };
 EXPORT_SYMBOL(xfs_qmcore_xfs);
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c
index 68139b3..c7b66f6 100644
--- a/fs/xfs/quota/xfs_qm_syscalls.c
+++ b/fs/xfs/quota/xfs_qm_syscalls.c
@@ -57,135 +57,16 @@
 # define qdprintk(s, args...)	do { } while (0)
 #endif
 
-STATIC int	xfs_qm_scall_trunc_qfiles(xfs_mount_t *, uint);
-STATIC int	xfs_qm_scall_getquota(xfs_mount_t *, xfs_dqid_t, uint,
-					fs_disk_quota_t *);
-STATIC int	xfs_qm_scall_getqstat(xfs_mount_t *, fs_quota_stat_t *);
-STATIC int	xfs_qm_scall_setqlim(xfs_mount_t *, xfs_dqid_t, uint,
-					fs_disk_quota_t *);
-STATIC int	xfs_qm_scall_quotaon(xfs_mount_t *, uint);
-STATIC int	xfs_qm_scall_quotaoff(xfs_mount_t *, uint, boolean_t);
 STATIC int	xfs_qm_log_quotaoff(xfs_mount_t *, xfs_qoff_logitem_t **, uint);
 STATIC int	xfs_qm_log_quotaoff_end(xfs_mount_t *, xfs_qoff_logitem_t *,
 					uint);
-STATIC uint	xfs_qm_import_flags(uint);
 STATIC uint	xfs_qm_export_flags(uint);
-STATIC uint	xfs_qm_import_qtype_flags(uint);
 STATIC uint	xfs_qm_export_qtype_flags(uint);
 STATIC void	xfs_qm_export_dquot(xfs_mount_t *, xfs_disk_dquot_t *,
 					fs_disk_quota_t *);
 
 
 /*
- * The main distribution switch of all XFS quotactl system calls.
- */
-int
-xfs_qm_quotactl(
-	xfs_mount_t	*mp,
-	int		cmd,
-	int		id,
-	xfs_caddr_t	addr)
-{
-	int		error;
-
-	ASSERT(addr != NULL || cmd == Q_XQUOTASYNC);
-
-	/*
-	 * The following commands are valid even when quotaoff.
-	 */
-	switch (cmd) {
-	case Q_XQUOTARM:
-		/*
-		 * Truncate quota files. quota must be off.
-		 */
-		if (XFS_IS_QUOTA_ON(mp))
-			return XFS_ERROR(EINVAL);
-		if (mp->m_flags & XFS_MOUNT_RDONLY)
-			return XFS_ERROR(EROFS);
-		return (xfs_qm_scall_trunc_qfiles(mp,
-			       xfs_qm_import_qtype_flags(*(uint *)addr)));
-
-	case Q_XGETQSTAT:
-		/*
-		 * Get quota status information.
-		 */
-		return (xfs_qm_scall_getqstat(mp, (fs_quota_stat_t *)addr));
-
-	case Q_XQUOTAON:
-		/*
-		 * QUOTAON - enabling quota enforcement.
-		 * Quota accounting must be turned on at mount time.
-		 */
-		if (mp->m_flags & XFS_MOUNT_RDONLY)
-			return XFS_ERROR(EROFS);
-		return (xfs_qm_scall_quotaon(mp,
-					  xfs_qm_import_flags(*(uint *)addr)));
-
-	case Q_XQUOTAOFF:
-		if (mp->m_flags & XFS_MOUNT_RDONLY)
-			return XFS_ERROR(EROFS);
-		break;
-
-	case Q_XQUOTASYNC:
-		return xfs_sync_inodes(mp, SYNC_DELWRI);
-
-	default:
-		break;
-	}
-
-	if (! XFS_IS_QUOTA_ON(mp))
-		return XFS_ERROR(ESRCH);
-
-	switch (cmd) {
-	case Q_XQUOTAOFF:
-		if (mp->m_flags & XFS_MOUNT_RDONLY)
-			return XFS_ERROR(EROFS);
-		error = xfs_qm_scall_quotaoff(mp,
-					    xfs_qm_import_flags(*(uint *)addr),
-					    B_FALSE);
-		break;
-
-	case Q_XGETQUOTA:
-		error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_USER,
-					(fs_disk_quota_t *)addr);
-		break;
-	case Q_XGETGQUOTA:
-		error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
-					(fs_disk_quota_t *)addr);
-		break;
-	case Q_XGETPQUOTA:
-		error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_PROJ,
-					(fs_disk_quota_t *)addr);
-		break;
-
-	case Q_XSETQLIM:
-		if (mp->m_flags & XFS_MOUNT_RDONLY)
-			return XFS_ERROR(EROFS);
-		error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_USER,
-					     (fs_disk_quota_t *)addr);
-		break;
-	case Q_XSETGQLIM:
-		if (mp->m_flags & XFS_MOUNT_RDONLY)
-			return XFS_ERROR(EROFS);
-		error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
-					     (fs_disk_quota_t *)addr);
-		break;
-	case Q_XSETPQLIM:
-		if (mp->m_flags & XFS_MOUNT_RDONLY)
-			return XFS_ERROR(EROFS);
-		error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_PROJ,
-					     (fs_disk_quota_t *)addr);
-		break;
-
-	default:
-		error = XFS_ERROR(EINVAL);
-		break;
-	}
-
-	return (error);
-}
-
-/*
  * Turn off quota accounting and/or enforcement for all udquots and/or
  * gdquots. Called only at unmount time.
  *
@@ -193,11 +74,10 @@
  * incore, and modifies the ondisk dquot directly. Therefore, for example,
  * it is an error to call this twice, without purging the cache.
  */
-STATIC int
+int
 xfs_qm_scall_quotaoff(
 	xfs_mount_t		*mp,
-	uint			flags,
-	boolean_t		force)
+	uint			flags)
 {
 	uint			dqtype;
 	int			error;
@@ -205,8 +85,6 @@
 	xfs_qoff_logitem_t	*qoffstart;
 	int			nculprits;
 
-	if (!force && !capable(CAP_SYS_ADMIN))
-		return XFS_ERROR(EPERM);
 	/*
 	 * No file system can have quotas enabled on disk but not in core.
 	 * Note that quota utilities (like quotaoff) _expect_
@@ -375,7 +253,7 @@
 	return (error);
 }
 
-STATIC int
+int
 xfs_qm_scall_trunc_qfiles(
 	xfs_mount_t	*mp,
 	uint		flags)
@@ -383,8 +261,6 @@
 	int		error = 0, error2 = 0;
 	xfs_inode_t	*qip;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return XFS_ERROR(EPERM);
 	if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0) {
 		qdprintk("qtrunc flags=%x m_qflags=%x\n", flags, mp->m_qflags);
 		return XFS_ERROR(EINVAL);
@@ -416,7 +292,7 @@
  * effect immediately.
  * (Switching on quota accounting must be done at mount time.)
  */
-STATIC int
+int
 xfs_qm_scall_quotaon(
 	xfs_mount_t	*mp,
 	uint		flags)
@@ -426,9 +302,6 @@
 	uint		accflags;
 	__int64_t	sbflags;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return XFS_ERROR(EPERM);
-
 	flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD);
 	/*
 	 * Switching on quota accounting must be done at mount time.
@@ -517,7 +390,7 @@
 /*
  * Return quota status information, such as uquota-off, enforcements, etc.
  */
-STATIC int
+int
 xfs_qm_scall_getqstat(
 	xfs_mount_t	*mp,
 	fs_quota_stat_t *out)
@@ -582,7 +455,7 @@
 /*
  * Adjust quota limits, and start/stop timers accordingly.
  */
-STATIC int
+int
 xfs_qm_scall_setqlim(
 	xfs_mount_t		*mp,
 	xfs_dqid_t		id,
@@ -595,9 +468,6 @@
 	int			error;
 	xfs_qcnt_t		hard, soft;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return XFS_ERROR(EPERM);
-
 	if ((newlim->d_fieldmask &
 	    (FS_DQ_LIMIT_MASK|FS_DQ_TIMER_MASK|FS_DQ_WARNS_MASK)) == 0)
 		return (0);
@@ -742,7 +612,7 @@
 	return error;
 }
 
-STATIC int
+int
 xfs_qm_scall_getquota(
 	xfs_mount_t	*mp,
 	xfs_dqid_t	id,
@@ -935,30 +805,6 @@
 }
 
 STATIC uint
-xfs_qm_import_qtype_flags(
-	uint		uflags)
-{
-	uint		oflags = 0;
-
-	/*
-	 * Can't be more than one, or none.
-	 */
-	if (((uflags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) ==
-			(XFS_GROUP_QUOTA | XFS_USER_QUOTA)) ||
-	    ((uflags & (XFS_GROUP_QUOTA | XFS_PROJ_QUOTA)) ==
-			(XFS_GROUP_QUOTA | XFS_PROJ_QUOTA)) ||
-	    ((uflags & (XFS_USER_QUOTA | XFS_PROJ_QUOTA)) ==
-			(XFS_USER_QUOTA | XFS_PROJ_QUOTA)) ||
-	    ((uflags & (XFS_GROUP_QUOTA|XFS_USER_QUOTA|XFS_PROJ_QUOTA)) == 0))
-		return (0);
-
-	oflags |= (uflags & XFS_USER_QUOTA) ? XFS_DQ_USER : 0;
-	oflags |= (uflags & XFS_PROJ_QUOTA) ? XFS_DQ_PROJ : 0;
-	oflags |= (uflags & XFS_GROUP_QUOTA) ? XFS_DQ_GROUP: 0;
-	return oflags;
-}
-
-STATIC uint
 xfs_qm_export_qtype_flags(
 	uint flags)
 {
@@ -979,26 +825,6 @@
 }
 
 STATIC uint
-xfs_qm_import_flags(
-	uint uflags)
-{
-	uint flags = 0;
-
-	if (uflags & XFS_QUOTA_UDQ_ACCT)
-		flags |= XFS_UQUOTA_ACCT;
-	if (uflags & XFS_QUOTA_PDQ_ACCT)
-		flags |= XFS_PQUOTA_ACCT;
-	if (uflags & XFS_QUOTA_GDQ_ACCT)
-		flags |= XFS_GQUOTA_ACCT;
-	if (uflags & XFS_QUOTA_UDQ_ENFD)
-		flags |= XFS_UQUOTA_ENFD;
-	if (uflags & (XFS_QUOTA_PDQ_ENFD|XFS_QUOTA_GDQ_ENFD))
-		flags |= XFS_OQUOTA_ENFD;
-	return (flags);
-}
-
-
-STATIC uint
 xfs_qm_export_flags(
 	uint flags)
 {
@@ -1134,7 +960,7 @@
 xfs_dqhash_t *qmtest_gdqtab;
 int	      qmtest_hashmask;
 int	      qmtest_nfails;
-mutex_t	      qcheck_lock;
+struct mutex  qcheck_lock;
 
 #define DQTEST_HASHVAL(mp, id) (((__psunsigned_t)(mp) + \
 				 (__psunsigned_t)(id)) & \
diff --git a/fs/xfs/quota/xfs_quota_priv.h b/fs/xfs/quota/xfs_quota_priv.h
index c4fcea6..8286b28 100644
--- a/fs/xfs/quota/xfs_quota_priv.h
+++ b/fs/xfs/quota/xfs_quota_priv.h
@@ -42,34 +42,24 @@
 #define XFS_QI_QOFFLOCK(mp)	((mp)->m_quotainfo->qi_quotaofflock)
 
 #define XFS_QI_MPL_LIST(mp)	((mp)->m_quotainfo->qi_dqlist)
-#define XFS_QI_MPLLOCK(mp)	((mp)->m_quotainfo->qi_dqlist.qh_lock)
 #define XFS_QI_MPLNEXT(mp)	((mp)->m_quotainfo->qi_dqlist.qh_next)
 #define XFS_QI_MPLNDQUOTS(mp)	((mp)->m_quotainfo->qi_dqlist.qh_nelems)
 
-#define XQMLCK(h)			(mutex_lock(&((h)->qh_lock)))
-#define XQMUNLCK(h)			(mutex_unlock(&((h)->qh_lock)))
-#ifdef DEBUG
-struct xfs_dqhash;
-static inline int XQMISLCKD(struct xfs_dqhash *h)
-{
-	if (mutex_trylock(&h->qh_lock)) {
-		mutex_unlock(&h->qh_lock);
-		return 0;
-	}
-	return 1;
-}
-#endif
+#define xfs_qm_mplist_lock(mp) \
+	mutex_lock(&(XFS_QI_MPL_LIST(mp).qh_lock))
+#define xfs_qm_mplist_nowait(mp) \
+	mutex_trylock(&(XFS_QI_MPL_LIST(mp).qh_lock))
+#define xfs_qm_mplist_unlock(mp) \
+	mutex_unlock(&(XFS_QI_MPL_LIST(mp).qh_lock))
+#define XFS_QM_IS_MPLIST_LOCKED(mp) \
+	mutex_is_locked(&(XFS_QI_MPL_LIST(mp).qh_lock))
 
-#define XFS_DQ_HASH_LOCK(h)		XQMLCK(h)
-#define XFS_DQ_HASH_UNLOCK(h)		XQMUNLCK(h)
-#define XFS_DQ_IS_HASH_LOCKED(h)	XQMISLCKD(h)
-
-#define xfs_qm_mplist_lock(mp)		XQMLCK(&(XFS_QI_MPL_LIST(mp)))
-#define xfs_qm_mplist_unlock(mp)	XQMUNLCK(&(XFS_QI_MPL_LIST(mp)))
-#define XFS_QM_IS_MPLIST_LOCKED(mp)	XQMISLCKD(&(XFS_QI_MPL_LIST(mp)))
-
-#define xfs_qm_freelist_lock(qm)	XQMLCK(&((qm)->qm_dqfreelist))
-#define xfs_qm_freelist_unlock(qm)	XQMUNLCK(&((qm)->qm_dqfreelist))
+#define xfs_qm_freelist_lock(qm) \
+	mutex_lock(&((qm)->qm_dqfreelist.qh_lock))
+#define xfs_qm_freelist_lock_nowait(qm) \
+	mutex_trylock(&((qm)->qm_dqfreelist.qh_lock))
+#define xfs_qm_freelist_unlock(qm) \
+	mutex_unlock(&((qm)->qm_dqfreelist.qh_lock))
 
 /*
  * Hash into a bucket in the dquot hash table, based on <mp, id>.
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c
index 9961138..447173b 100644
--- a/fs/xfs/quota/xfs_trans_dquot.c
+++ b/fs/xfs/quota/xfs_trans_dquot.c
@@ -624,10 +624,9 @@
 	xfs_qcnt_t	*resbcountp;
 	xfs_quotainfo_t	*q = mp->m_quotainfo;
 
-	if (! (flags & XFS_QMOPT_DQLOCK)) {
-		xfs_dqlock(dqp);
-	}
-	ASSERT(XFS_DQ_IS_LOCKED(dqp));
+
+	xfs_dqlock(dqp);
+
 	if (flags & XFS_TRANS_DQ_RES_BLKS) {
 		hardlimit = be64_to_cpu(dqp->q_core.d_blk_hardlimit);
 		if (!hardlimit)
@@ -740,10 +739,8 @@
 	ASSERT(dqp->q_res_icount >= be64_to_cpu(dqp->q_core.d_icount));
 
 error_return:
-	if (! (flags & XFS_QMOPT_DQLOCK)) {
-		xfs_dqunlock(dqp);
-	}
-	return (error);
+	xfs_dqunlock(dqp);
+	return error;
 }
 
 
@@ -753,8 +750,7 @@
  * grp/prj quotas is important, because this follows a both-or-nothing
  * approach.
  *
- * flags = XFS_QMOPT_DQLOCK indicate if dquot(s) need to be locked.
- *	   XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown.
+ * flags = XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown.
  *	   XFS_QMOPT_ENOSPC returns ENOSPC not EDQUOT.  Used by pquota.
  *	   XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks
  *	   XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks
diff --git a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c
index ae54829..3f3610a 100644
--- a/fs/xfs/support/debug.c
+++ b/fs/xfs/support/debug.c
@@ -24,6 +24,7 @@
 #include "xfs_ag.h"
 #include "xfs_dmapi.h"
 #include "xfs_mount.h"
+#include "xfs_error.h"
 
 static char		message[1024];	/* keep it off the stack */
 static DEFINE_SPINLOCK(xfs_err_lock);
diff --git a/fs/xfs/support/uuid.c b/fs/xfs/support/uuid.c
index 5830c04..b83f76b 100644
--- a/fs/xfs/support/uuid.c
+++ b/fs/xfs/support/uuid.c
@@ -17,10 +17,6 @@
  */
 #include <xfs.h>
 
-static DEFINE_MUTEX(uuid_monitor);
-static int	uuid_table_size;
-static uuid_t	*uuid_table;
-
 /* IRIX interpretation of an uuid_t */
 typedef struct {
 	__be32	uu_timelow;
@@ -46,12 +42,6 @@
 	fsid[1] = be32_to_cpu(uup->uu_timelow);
 }
 
-void
-uuid_create_nil(uuid_t *uuid)
-{
-	memset(uuid, 0, sizeof(*uuid));
-}
-
 int
 uuid_is_nil(uuid_t *uuid)
 {
@@ -71,64 +61,3 @@
 {
 	return memcmp(uuid1, uuid2, sizeof(uuid_t)) ? 0 : 1;
 }
-
-/*
- * Given a 128-bit uuid, return a 64-bit value by adding the top and bottom
- * 64-bit words.  NOTE: This function can not be changed EVER.  Although
- * brain-dead, some applications depend on this 64-bit value remaining
- * persistent.  Specifically, DMI vendors store the value as a persistent
- * filehandle.
- */
-__uint64_t
-uuid_hash64(uuid_t *uuid)
-{
-	__uint64_t	*sp = (__uint64_t *)uuid;
-
-	return sp[0] + sp[1];
-}
-
-int
-uuid_table_insert(uuid_t *uuid)
-{
-	int	i, hole;
-
-	mutex_lock(&uuid_monitor);
-	for (i = 0, hole = -1; i < uuid_table_size; i++) {
-		if (uuid_is_nil(&uuid_table[i])) {
-			hole = i;
-			continue;
-		}
-		if (uuid_equal(uuid, &uuid_table[i])) {
-			mutex_unlock(&uuid_monitor);
-			return 0;
-		}
-	}
-	if (hole < 0) {
-		uuid_table = kmem_realloc(uuid_table,
-			(uuid_table_size + 1) * sizeof(*uuid_table),
-			uuid_table_size  * sizeof(*uuid_table),
-			KM_SLEEP);
-		hole = uuid_table_size++;
-	}
-	uuid_table[hole] = *uuid;
-	mutex_unlock(&uuid_monitor);
-	return 1;
-}
-
-void
-uuid_table_remove(uuid_t *uuid)
-{
-	int	i;
-
-	mutex_lock(&uuid_monitor);
-	for (i = 0; i < uuid_table_size; i++) {
-		if (uuid_is_nil(&uuid_table[i]))
-			continue;
-		if (!uuid_equal(uuid, &uuid_table[i]))
-			continue;
-		uuid_create_nil(&uuid_table[i]);
-		break;
-	}
-	ASSERT(i < uuid_table_size);
-	mutex_unlock(&uuid_monitor);
-}
diff --git a/fs/xfs/support/uuid.h b/fs/xfs/support/uuid.h
index cff5b60..4732d71 100644
--- a/fs/xfs/support/uuid.h
+++ b/fs/xfs/support/uuid.h
@@ -22,12 +22,8 @@
 	unsigned char	__u_bits[16];
 } uuid_t;
 
-extern void uuid_create_nil(uuid_t *uuid);
 extern int uuid_is_nil(uuid_t *uuid);
 extern int uuid_equal(uuid_t *uuid1, uuid_t *uuid2);
 extern void uuid_getnodeuniq(uuid_t *uuid, int fsid [2]);
-extern __uint64_t uuid_hash64(uuid_t *uuid);
-extern int uuid_table_insert(uuid_t *uuid);
-extern void uuid_table_remove(uuid_t *uuid);
 
 #endif	/* __XFS_SUPPORT_UUID_H__ */
diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h
index 143d63e..c8641f7 100644
--- a/fs/xfs/xfs_ag.h
+++ b/fs/xfs/xfs_ag.h
@@ -223,8 +223,8 @@
 		be32_to_cpu((a)->agf_levels[XFS_BTNUM_CNTi]), mp))
 #define	XFS_MIN_FREELIST_PAG(pag,mp)	\
 	(XFS_MIN_FREELIST_RAW(		\
-		(uint_t)(pag)->pagf_levels[XFS_BTNUM_BNOi], \
-		(uint_t)(pag)->pagf_levels[XFS_BTNUM_CNTi], mp))
+		(unsigned int)(pag)->pagf_levels[XFS_BTNUM_BNOi], \
+		(unsigned int)(pag)->pagf_levels[XFS_BTNUM_CNTi], mp))
 
 #define XFS_AGB_TO_FSB(mp,agno,agbno)	\
 	(((xfs_fsblock_t)(agno) << (mp)->m_sb.sb_agblklog) | (agbno))
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index 028e44e..2cf944e 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -1872,6 +1872,25 @@
 }
 
 /*
+ * Find the length of the longest extent in an AG.
+ */
+xfs_extlen_t
+xfs_alloc_longest_free_extent(
+	struct xfs_mount	*mp,
+	struct xfs_perag	*pag)
+{
+	xfs_extlen_t		need, delta = 0;
+
+	need = XFS_MIN_FREELIST_PAG(pag, mp);
+	if (need > pag->pagf_flcount)
+		delta = need - pag->pagf_flcount;
+
+	if (pag->pagf_longest > delta)
+		return pag->pagf_longest - delta;
+	return pag->pagf_flcount > 0 || pag->pagf_longest > 0;
+}
+
+/*
  * Decide whether to use this allocation group for this allocation.
  * If so, fix up the btree freelist's size.
  */
@@ -1923,15 +1942,12 @@
 	}
 
 	if (!(flags & XFS_ALLOC_FLAG_FREEING)) {
-		need = XFS_MIN_FREELIST_PAG(pag, mp);
-		delta = need > pag->pagf_flcount ? need - pag->pagf_flcount : 0;
 		/*
 		 * If it looks like there isn't a long enough extent, or enough
 		 * total blocks, reject it.
 		 */
-		longest = (pag->pagf_longest > delta) ?
-			(pag->pagf_longest - delta) :
-			(pag->pagf_flcount > 0 || pag->pagf_longest > 0);
+		need = XFS_MIN_FREELIST_PAG(pag, mp);
+		longest = xfs_alloc_longest_free_extent(mp, pag);
 		if ((args->minlen + args->alignment + args->minalignslop - 1) >
 				longest ||
 		    ((int)(pag->pagf_freeblks + pag->pagf_flcount -
diff --git a/fs/xfs/xfs_alloc.h b/fs/xfs/xfs_alloc.h
index 5881727..e704caee 100644
--- a/fs/xfs/xfs_alloc.h
+++ b/fs/xfs/xfs_alloc.h
@@ -100,6 +100,12 @@
 #define XFS_ALLOC_USERDATA		1	/* allocation is for user data*/
 #define XFS_ALLOC_INITIAL_USER_DATA	2	/* special case start of file */
 
+/*
+ * Find the length of the longest extent in an AG.
+ */
+xfs_extlen_t
+xfs_alloc_longest_free_extent(struct xfs_mount *mp,
+		struct xfs_perag *pag);
 
 #ifdef __KERNEL__
 
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index 6c323f8..afdc891 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -155,7 +155,8 @@
 		 * minimum offset only needs to be the space required for 
 		 * the btree root.
 		 */ 
-		if (!dp->i_d.di_forkoff && dp->i_df.if_bytes > mp->m_attroffset)
+		if (!dp->i_d.di_forkoff && dp->i_df.if_bytes >
+		    xfs_default_attroffset(dp))
 			dsize = XFS_BMDR_SPACE_CALC(MINDBTPTRS);
 		break;
 		
@@ -298,6 +299,26 @@
 }
 
 /*
+ * After the last attribute is removed revert to original inode format,
+ * making all literal area available to the data fork once more.
+ */
+STATIC void
+xfs_attr_fork_reset(
+	struct xfs_inode	*ip,
+	struct xfs_trans	*tp)
+{
+	xfs_idestroy_fork(ip, XFS_ATTR_FORK);
+	ip->i_d.di_forkoff = 0;
+	ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
+
+	ASSERT(ip->i_d.di_anextents == 0);
+	ASSERT(ip->i_afp == NULL);
+
+	ip->i_df.if_ext_max = XFS_IFORK_DSIZE(ip) / sizeof(xfs_bmbt_rec_t);
+	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+}
+
+/*
  * Remove an attribute from the shortform attribute list structure.
  */
 int
@@ -344,22 +365,10 @@
 	 */
 	totsize -= size;
 	if (totsize == sizeof(xfs_attr_sf_hdr_t) &&
-				!(args->op_flags & XFS_DA_OP_ADDNAME) &&
-				(mp->m_flags & XFS_MOUNT_ATTR2) &&
-				(dp->i_d.di_format != XFS_DINODE_FMT_BTREE)) {
-		/*
-		 * Last attribute now removed, revert to original
-		 * inode format making all literal area available
-		 * to the data fork once more.
-		 */
-		xfs_idestroy_fork(dp, XFS_ATTR_FORK);
-		dp->i_d.di_forkoff = 0;
-		dp->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
-		ASSERT(dp->i_d.di_anextents == 0);
-		ASSERT(dp->i_afp == NULL);
-		dp->i_df.if_ext_max =
-			XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
-		xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
+	    (mp->m_flags & XFS_MOUNT_ATTR2) &&
+	    (dp->i_d.di_format != XFS_DINODE_FMT_BTREE) &&
+	    !(args->op_flags & XFS_DA_OP_ADDNAME)) {
+		xfs_attr_fork_reset(dp, args->trans);
 	} else {
 		xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
 		dp->i_d.di_forkoff = xfs_attr_shortform_bytesfit(dp, totsize);
@@ -786,20 +795,7 @@
 	if (forkoff == -1) {
 		ASSERT(dp->i_mount->m_flags & XFS_MOUNT_ATTR2);
 		ASSERT(dp->i_d.di_format != XFS_DINODE_FMT_BTREE);
-
-		/*
-		 * Last attribute was removed, revert to original
-		 * inode format making all literal area available
-		 * to the data fork once more.
-		 */
-		xfs_idestroy_fork(dp, XFS_ATTR_FORK);
-		dp->i_d.di_forkoff = 0;
-		dp->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
-		ASSERT(dp->i_d.di_anextents == 0);
-		ASSERT(dp->i_afp == NULL);
-		dp->i_df.if_ext_max =
-			XFS_IFORK_DSIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
-		xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
+		xfs_attr_fork_reset(dp, args->trans);
 		goto out;
 	}
 
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index c852cd6..3a6ed42 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -2479,7 +2479,7 @@
 	fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock);
 	/*
 	 * If allocating at eof, and there's a previous real block,
-	 * try to use it's last block as our starting point.
+	 * try to use its last block as our starting point.
 	 */
 	if (ap->eof && ap->prevp->br_startoff != NULLFILEOFF &&
 	    !isnullstartblock(ap->prevp->br_startblock) &&
@@ -2712,9 +2712,6 @@
 	xfs_agnumber_t	startag;
 	xfs_alloc_arg_t	args;
 	xfs_extlen_t	blen;
-	xfs_extlen_t	delta;
-	xfs_extlen_t	longest;
-	xfs_extlen_t	need;
 	xfs_extlen_t	nextminlen = 0;
 	xfs_perag_t	*pag;
 	int		nullfb;		/* true if ap->firstblock isn't set */
@@ -2796,13 +2793,8 @@
 			 * See xfs_alloc_fix_freelist...
 			 */
 			if (pag->pagf_init) {
-				need = XFS_MIN_FREELIST_PAG(pag, mp);
-				delta = need > pag->pagf_flcount ?
-					need - pag->pagf_flcount : 0;
-				longest = (pag->pagf_longest > delta) ?
-					(pag->pagf_longest - delta) :
-					(pag->pagf_flcount > 0 ||
-					 pag->pagf_longest > 0);
+				xfs_extlen_t	longest;
+				longest = xfs_alloc_longest_free_extent(mp, pag);
 				if (blen < longest)
 					blen = longest;
 			} else
@@ -3577,6 +3569,27 @@
 }
 
 /*
+ * Calculate the default attribute fork offset for newly created inodes.
+ */
+uint
+xfs_default_attroffset(
+	struct xfs_inode	*ip)
+{
+	struct xfs_mount	*mp = ip->i_mount;
+	uint			offset;
+
+	if (mp->m_sb.sb_inodesize == 256) {
+		offset = XFS_LITINO(mp) -
+				XFS_BMDR_SPACE_CALC(MINABTPTRS);
+	} else {
+		offset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS);
+	}
+
+	ASSERT(offset < XFS_LITINO(mp));
+	return offset;
+}
+
+/*
  * Helper routine to reset inode di_forkoff field when switching
  * attribute fork from local to extent format - we reset it where
  * possible to make space available for inline data fork extents.
@@ -3588,15 +3601,18 @@
 	int		whichfork)
 {
 	if (whichfork == XFS_ATTR_FORK &&
-	    (ip->i_d.di_format != XFS_DINODE_FMT_DEV) &&
-	    (ip->i_d.di_format != XFS_DINODE_FMT_UUID) &&
-	    (ip->i_d.di_format != XFS_DINODE_FMT_BTREE) &&
-	    ((mp->m_attroffset >> 3) > ip->i_d.di_forkoff)) {
-		ip->i_d.di_forkoff = mp->m_attroffset >> 3;
-		ip->i_df.if_ext_max = XFS_IFORK_DSIZE(ip) /
-					(uint)sizeof(xfs_bmbt_rec_t);
-		ip->i_afp->if_ext_max = XFS_IFORK_ASIZE(ip) /
-					(uint)sizeof(xfs_bmbt_rec_t);
+	    ip->i_d.di_format != XFS_DINODE_FMT_DEV &&
+	    ip->i_d.di_format != XFS_DINODE_FMT_UUID &&
+	    ip->i_d.di_format != XFS_DINODE_FMT_BTREE) {
+		uint	dfl_forkoff = xfs_default_attroffset(ip) >> 3;
+
+		if (dfl_forkoff > ip->i_d.di_forkoff) {
+			ip->i_d.di_forkoff = dfl_forkoff;
+			ip->i_df.if_ext_max =
+				XFS_IFORK_DSIZE(ip) / sizeof(xfs_bmbt_rec_t);
+			ip->i_afp->if_ext_max =
+				XFS_IFORK_ASIZE(ip) / sizeof(xfs_bmbt_rec_t);
+		}
 	}
 }
 
@@ -4065,7 +4081,7 @@
 	case XFS_DINODE_FMT_BTREE:
 		ip->i_d.di_forkoff = xfs_attr_shortform_bytesfit(ip, size);
 		if (!ip->i_d.di_forkoff)
-			ip->i_d.di_forkoff = mp->m_attroffset >> 3;
+			ip->i_d.di_forkoff = xfs_default_attroffset(ip) >> 3;
 		else if (mp->m_flags & XFS_MOUNT_ATTR2)
 			version = 2;
 		break;
@@ -4212,12 +4228,12 @@
 	 * (a signed 16-bit number, xfs_aextnum_t).
 	 *
 	 * Note that we can no longer assume that if we are in ATTR1 that
-	 * the fork offset of all the inodes will be (m_attroffset >> 3)
-	 * because we could have mounted with ATTR2 and then mounted back
-	 * with ATTR1, keeping the di_forkoff's fixed but probably at
-	 * various positions. Therefore, for both ATTR1 and ATTR2
-	 * we have to assume the worst case scenario of a minimum size
-	 * available.
+	 * the fork offset of all the inodes will be
+	 * (xfs_default_attroffset(ip) >> 3) because we could have mounted
+	 * with ATTR2 and then mounted back with ATTR1, keeping the
+	 * di_forkoff's fixed but probably at various positions. Therefore,
+	 * for both ATTR1 and ATTR2 we have to assume the worst case scenario
+	 * of a minimum size available.
 	 */
 	if (whichfork == XFS_DATA_FORK) {
 		maxleafents = MAXEXTNUM;
@@ -4804,7 +4820,7 @@
 	xfs_extlen_t	minlen;		/* min allocation size */
 	xfs_mount_t	*mp;		/* xfs mount structure */
 	int		n;		/* current extent index */
-	int		nallocs;	/* number of extents alloc\'d */
+	int		nallocs;	/* number of extents alloc'd */
 	xfs_extnum_t	nextents;	/* number of extents in file */
 	xfs_fileoff_t	obno;		/* old block number (offset) */
 	xfs_bmbt_irec_t	prev;		/* previous file extent record */
@@ -6204,7 +6220,7 @@
 	return(bp);
 }
 
-void
+STATIC void
 xfs_check_block(
 	struct xfs_btree_block	*block,
 	xfs_mount_t		*mp,
@@ -6494,7 +6510,7 @@
 	block = XFS_BUF_TO_BLOCK(bp);
 
 	if (--level) {
-		/* Not at node above leafs, count this level of nodes */
+		/* Not at node above leaves, count this level of nodes */
 		nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib);
 		while (nextbno != NULLFSBLOCK) {
 			if ((error = xfs_btree_read_bufl(mp, tp, nextbno,
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index be2979d..1b8ff92 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -125,7 +125,7 @@
 	struct xfs_bmbt_irec	*gotp;	/* extent after, or delayed */
 	xfs_extlen_t		alen;	/* i/o length asked/allocated */
 	xfs_extlen_t		total;	/* total blocks needed for xaction */
-	xfs_extlen_t		minlen;	/* mininum allocation size (blocks) */
+	xfs_extlen_t		minlen;	/* minimum allocation size (blocks) */
 	xfs_extlen_t		minleft; /* amount must be left after alloc */
 	char			eof;	/* set if allocating past last extent */
 	char			wasdel;	/* replacing a delayed allocation */
@@ -338,6 +338,10 @@
 	xfs_extnum_t		idx,
 	xfs_extnum_t		num);
 
+uint
+xfs_default_attroffset(
+	struct xfs_inode	*ip);
+
 #ifdef __KERNEL__
 
 /*
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c
index e73c332..e9df995 100644
--- a/fs/xfs/xfs_btree.c
+++ b/fs/xfs/xfs_btree.c
@@ -1883,7 +1883,7 @@
 
 	/*
 	 * We add one entry to the left side and remove one for the right side.
-	 * Accout for it here, the changes will be updated on disk and logged
+	 * Account for it here, the changes will be updated on disk and logged
 	 * later.
 	 */
 	lrecs++;
@@ -3535,7 +3535,7 @@
 	XFS_BTREE_STATS_INC(cur, join);
 
 	/*
-	 * Fix up the the number of records and right block pointer in the
+	 * Fix up the number of records and right block pointer in the
 	 * surviving block, and log it.
 	 */
 	xfs_btree_set_numrecs(left, lrecs + rrecs);
diff --git a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h
index 789fffd..4f852b7 100644
--- a/fs/xfs/xfs_btree.h
+++ b/fs/xfs/xfs_btree.h
@@ -41,7 +41,7 @@
 /*
  * Generic btree header.
  *
- * This is a comination of the actual format used on disk for short and long
+ * This is a combination of the actual format used on disk for short and long
  * format btrees.  The first three fields are shared by both format, but
  * the pointers are different and should be used with care.
  *
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
index c45f74f..9ff6e57 100644
--- a/fs/xfs/xfs_da_btree.c
+++ b/fs/xfs/xfs_da_btree.c
@@ -1503,7 +1503,7 @@
  * This is implemented with some source-level loop unrolling.
  */
 xfs_dahash_t
-xfs_da_hashname(const uchar_t *name, int namelen)
+xfs_da_hashname(const __uint8_t *name, int namelen)
 {
 	xfs_dahash_t hash;
 
diff --git a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h
index 70b710c..8c53616 100644
--- a/fs/xfs/xfs_da_btree.h
+++ b/fs/xfs/xfs_da_btree.h
@@ -91,9 +91,9 @@
  * Structure to ease passing around component names.
  */
 typedef struct xfs_da_args {
-	const uchar_t	*name;		/* string (maybe not NULL terminated) */
+	const __uint8_t	*name;		/* string (maybe not NULL terminated) */
 	int		namelen;	/* length of string (maybe no NULL) */
-	uchar_t		*value;		/* set of bytes (maybe contain NULLs) */
+	__uint8_t	*value;		/* set of bytes (maybe contain NULLs) */
 	int		valuelen;	/* length of value */
 	int		flags;		/* argument flags (eg: ATTR_NOCREATE) */
 	xfs_dahash_t	hashval;	/* hash value of name */
@@ -185,7 +185,7 @@
 	unsigned char		inleaf;		/* insert into 1->lf, 0->splf */
 	unsigned char		extravalid;	/* T/F: extrablk is in use */
 	unsigned char		extraafter;	/* T/F: extrablk is after new */
-	xfs_da_state_blk_t	extrablk;	/* for double-splits on leafs */
+	xfs_da_state_blk_t	extrablk;	/* for double-splits on leaves */
 						/* for dirv2 extrablk is data */
 } xfs_da_state_t;
 
@@ -251,7 +251,7 @@
 int	xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
 					  xfs_dabuf_t *dead_buf);
 
-uint xfs_da_hashname(const uchar_t *name_string, int name_length);
+uint xfs_da_hashname(const __uint8_t *name_string, int name_length);
 enum xfs_dacmp xfs_da_compname(struct xfs_da_args *args,
 				const char *name, int len);
 
@@ -268,5 +268,6 @@
 
 extern struct kmem_zone *xfs_da_state_zone;
 extern struct kmem_zone *xfs_dabuf_zone;
+extern const struct xfs_nameops xfs_default_nameops;
 
 #endif	/* __XFS_DA_BTREE_H__ */
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index f8278cf..e6d839b 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -79,6 +79,12 @@
 		goto out_put_target_file;
 	}
 
+	if (IS_SWAPFILE(file->f_path.dentry->d_inode) ||
+	    IS_SWAPFILE(target_file->f_path.dentry->d_inode)) {
+		error = XFS_ERROR(EINVAL);
+		goto out_put_target_file;
+	}
+
 	ip = XFS_I(file->f_path.dentry->d_inode);
 	tip = XFS_I(target_file->f_path.dentry->d_inode);
 
@@ -118,19 +124,17 @@
 	xfs_bstat_t	*sbp = &sxp->sx_stat;
 	xfs_ifork_t	*tempifp, *ifp, *tifp;
 	int		ilf_fields, tilf_fields;
-	static uint	lock_flags = XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL;
 	int		error = 0;
 	int		aforkblks = 0;
 	int		taforkblks = 0;
 	__uint64_t	tmp;
-	char		locked = 0;
 
 	mp = ip->i_mount;
 
 	tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL);
 	if (!tempifp) {
 		error = XFS_ERROR(ENOMEM);
-		goto error0;
+		goto out;
 	}
 
 	sbp = &sxp->sx_stat;
@@ -143,25 +147,24 @@
 	 */
 	xfs_lock_two_inodes(ip, tip, XFS_IOLOCK_EXCL);
 	xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL);
-	locked = 1;
 
 	/* Verify that both files have the same format */
 	if ((ip->i_d.di_mode & S_IFMT) != (tip->i_d.di_mode & S_IFMT)) {
 		error = XFS_ERROR(EINVAL);
-		goto error0;
+		goto out_unlock;
 	}
 
 	/* Verify both files are either real-time or non-realtime */
 	if (XFS_IS_REALTIME_INODE(ip) != XFS_IS_REALTIME_INODE(tip)) {
 		error = XFS_ERROR(EINVAL);
-		goto error0;
+		goto out_unlock;
 	}
 
 	/* Should never get a local format */
 	if (ip->i_d.di_format == XFS_DINODE_FMT_LOCAL ||
 	    tip->i_d.di_format == XFS_DINODE_FMT_LOCAL) {
 		error = XFS_ERROR(EINVAL);
-		goto error0;
+		goto out_unlock;
 	}
 
 	if (VN_CACHED(VFS_I(tip)) != 0) {
@@ -169,13 +172,13 @@
 		error = xfs_flushinval_pages(tip, 0, -1,
 				FI_REMAPF_LOCKED);
 		if (error)
-			goto error0;
+			goto out_unlock;
 	}
 
 	/* Verify O_DIRECT for ftmp */
 	if (VN_CACHED(VFS_I(tip)) != 0) {
 		error = XFS_ERROR(EINVAL);
-		goto error0;
+		goto out_unlock;
 	}
 
 	/* Verify all data are being swapped */
@@ -183,7 +186,7 @@
 	    sxp->sx_length != ip->i_d.di_size ||
 	    sxp->sx_length != tip->i_d.di_size) {
 		error = XFS_ERROR(EFAULT);
-		goto error0;
+		goto out_unlock;
 	}
 
 	/*
@@ -193,7 +196,7 @@
 	 */
 	if ( XFS_IFORK_Q(ip) != XFS_IFORK_Q(tip) ) {
 		error = XFS_ERROR(EINVAL);
-		goto error0;
+		goto out_unlock;
 	}
 
 	/*
@@ -208,7 +211,7 @@
 	    (sbp->bs_mtime.tv_sec != ip->i_d.di_mtime.t_sec) ||
 	    (sbp->bs_mtime.tv_nsec != ip->i_d.di_mtime.t_nsec)) {
 		error = XFS_ERROR(EBUSY);
-		goto error0;
+		goto out_unlock;
 	}
 
 	/* We need to fail if the file is memory mapped.  Once we have tossed
@@ -219,7 +222,7 @@
 	 */
 	if (VN_MAPPED(VFS_I(ip))) {
 		error = XFS_ERROR(EBUSY);
-		goto error0;
+		goto out_unlock;
 	}
 
 	xfs_iunlock(ip, XFS_ILOCK_EXCL);
@@ -242,8 +245,7 @@
 		xfs_iunlock(ip,  XFS_IOLOCK_EXCL);
 		xfs_iunlock(tip, XFS_IOLOCK_EXCL);
 		xfs_trans_cancel(tp, 0);
-		locked = 0;
-		goto error0;
+		goto out;
 	}
 	xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL);
 
@@ -253,19 +255,15 @@
 	if ( ((XFS_IFORK_Q(ip) != 0) && (ip->i_d.di_anextents > 0)) &&
 	     (ip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) {
 		error = xfs_bmap_count_blocks(tp, ip, XFS_ATTR_FORK, &aforkblks);
-		if (error) {
-			xfs_trans_cancel(tp, 0);
-			goto error0;
-		}
+		if (error)
+			goto out_trans_cancel;
 	}
 	if ( ((XFS_IFORK_Q(tip) != 0) && (tip->i_d.di_anextents > 0)) &&
 	     (tip->i_d.di_aformat != XFS_DINODE_FMT_LOCAL)) {
 		error = xfs_bmap_count_blocks(tp, tip, XFS_ATTR_FORK,
 			&taforkblks);
-		if (error) {
-			xfs_trans_cancel(tp, 0);
-			goto error0;
-		}
+		if (error)
+			goto out_trans_cancel;
 	}
 
 	/*
@@ -332,10 +330,10 @@
 
 
 	IHOLD(ip);
-	xfs_trans_ijoin(tp, ip, lock_flags);
+	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
 
 	IHOLD(tip);
-	xfs_trans_ijoin(tp, tip, lock_flags);
+	xfs_trans_ijoin(tp, tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
 
 	xfs_trans_log_inode(tp, ip,  ilf_fields);
 	xfs_trans_log_inode(tp, tip, tilf_fields);
@@ -344,19 +342,19 @@
 	 * If this is a synchronous mount, make sure that the
 	 * transaction goes to disk before returning to the user.
 	 */
-	if (mp->m_flags & XFS_MOUNT_WSYNC) {
+	if (mp->m_flags & XFS_MOUNT_WSYNC)
 		xfs_trans_set_sync(tp);
-	}
 
 	error = xfs_trans_commit(tp, XFS_TRANS_SWAPEXT);
-	locked = 0;
 
- error0:
-	if (locked) {
-		xfs_iunlock(ip,  lock_flags);
-		xfs_iunlock(tip, lock_flags);
-	}
-	if (tempifp != NULL)
-		kmem_free(tempifp);
+out_unlock:
+	xfs_iunlock(ip,  XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
+	xfs_iunlock(tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
+out:
+	kmem_free(tempifp);
 	return error;
+
+out_trans_cancel:
+	xfs_trans_cancel(tp, 0);
+	goto out_unlock;
 }
diff --git a/fs/xfs/xfs_dinode.h b/fs/xfs/xfs_dinode.h
index 162e872..e5b153b 100644
--- a/fs/xfs/xfs_dinode.h
+++ b/fs/xfs/xfs_dinode.h
@@ -103,7 +103,9 @@
 /*
  * Inode size for given fs.
  */
-#define	XFS_LITINO(mp)	((mp)->m_litino)
+#define XFS_LITINO(mp) \
+	((int)(((mp)->m_sb.sb_inodesize) - sizeof(struct xfs_dinode)))
+
 #define	XFS_BROOT_SIZE_ADJ	\
 	(XFS_BTREE_LBLOCK_LEN - sizeof(xfs_bmdr_block_t))
 
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c
index 1afb122..c657bec 100644
--- a/fs/xfs/xfs_dir2.c
+++ b/fs/xfs/xfs_dir2.c
@@ -46,8 +46,6 @@
 
 struct xfs_name xfs_name_dotdot = {"..", 2};
 
-extern const struct xfs_nameops xfs_default_nameops;
-
 /*
  * ASCII case-insensitive (ie. A-Z) support for directories that was
  * used in IRIX.
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c
index e1f0a06..ab52e9e 100644
--- a/fs/xfs/xfs_dir2_block.c
+++ b/fs/xfs/xfs_dir2_block.c
@@ -448,7 +448,6 @@
 	xfs_mount_t		*mp;		/* filesystem mount point */
 	char			*ptr;		/* current data entry */
 	int			wantoff;	/* starting block offset */
-	xfs_ino_t		ino;
 	xfs_off_t		cook;
 
 	mp = dp->i_mount;
@@ -509,16 +508,12 @@
 
 		cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
 					    (char *)dep - (char *)block);
-		ino = be64_to_cpu(dep->inumber);
-#if XFS_BIG_INUMS
-		ino += mp->m_inoadd;
-#endif
 
 		/*
 		 * If it didn't fit, set the final offset to here & return.
 		 */
 		if (filldir(dirent, dep->name, dep->namelen, cook & 0x7fffffff,
-			    ino, DT_UNKNOWN)) {
+			    be64_to_cpu(dep->inumber), DT_UNKNOWN)) {
 			*offset = cook & 0x7fffffff;
 			xfs_da_brelse(NULL, bp);
 			return 0;
diff --git a/fs/xfs/xfs_dir2_data.h b/fs/xfs/xfs_dir2_data.h
index b816e02..efbc290 100644
--- a/fs/xfs/xfs_dir2_data.h
+++ b/fs/xfs/xfs_dir2_data.h
@@ -38,7 +38,7 @@
 
 /*
  * Directory address space divided into sections,
- * spaces separated by 32gb.
+ * spaces separated by 32GB.
  */
 #define	XFS_DIR2_SPACE_SIZE	(1ULL << (32 + XFS_DIR2_DATA_ALIGN_LOG))
 #define	XFS_DIR2_DATA_SPACE	0
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index ef805a3..fa913e45 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -549,7 +549,7 @@
  * Check the internal consistency of a leaf1 block.
  * Pop an assert if something is wrong.
  */
-void
+STATIC void
 xfs_dir2_leaf_check(
 	xfs_inode_t		*dp,		/* incore directory inode */
 	xfs_dabuf_t		*bp)		/* leaf's buffer */
@@ -780,7 +780,6 @@
 	int			ra_index;	/* *map index for read-ahead */
 	int			ra_offset;	/* map entry offset for ra */
 	int			ra_want;	/* readahead count wanted */
-	xfs_ino_t		ino;
 
 	/*
 	 * If the offset is at or past the largest allowed value,
@@ -1076,24 +1075,12 @@
 			continue;
 		}
 
-		/*
-		 * Copy the entry into the putargs, and try formatting it.
-		 */
 		dep = (xfs_dir2_data_entry_t *)ptr;
-
 		length = xfs_dir2_data_entsize(dep->namelen);
 
-		ino = be64_to_cpu(dep->inumber);
-#if XFS_BIG_INUMS
-		ino += mp->m_inoadd;
-#endif
-
-		/*
-		 * Won't fit.  Return to caller.
-		 */
 		if (filldir(dirent, dep->name, dep->namelen,
 			    xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff,
-			    ino, DT_UNKNOWN))
+			    be64_to_cpu(dep->inumber), DT_UNKNOWN))
 			break;
 
 		/*
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c
index fa6c3a5..5a81ccd 100644
--- a/fs/xfs/xfs_dir2_node.c
+++ b/fs/xfs/xfs_dir2_node.c
@@ -1104,7 +1104,7 @@
 	}
 	xfs_dir2_leafn_check(dp, bp);
 	/*
-	 * Return indication of whether this leaf block is emtpy enough
+	 * Return indication of whether this leaf block is empty enough
 	 * to justify trying to join it with a neighbor.
 	 */
 	*rval =
diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c
index a8a8a6e..e89734e 100644
--- a/fs/xfs/xfs_dir2_sf.c
+++ b/fs/xfs/xfs_dir2_sf.c
@@ -748,11 +748,7 @@
 	 * Put . entry unless we're starting past it.
 	 */
 	if (*offset <= dot_offset) {
-		ino = dp->i_ino;
-#if XFS_BIG_INUMS
-		ino += mp->m_inoadd;
-#endif
-		if (filldir(dirent, ".", 1, dot_offset & 0x7fffffff, ino, DT_DIR)) {
+		if (filldir(dirent, ".", 1, dot_offset & 0x7fffffff, dp->i_ino, DT_DIR)) {
 			*offset = dot_offset & 0x7fffffff;
 			return 0;
 		}
@@ -763,9 +759,6 @@
 	 */
 	if (*offset <= dotdot_offset) {
 		ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent);
-#if XFS_BIG_INUMS
-		ino += mp->m_inoadd;
-#endif
 		if (filldir(dirent, "..", 2, dotdot_offset & 0x7fffffff, ino, DT_DIR)) {
 			*offset = dotdot_offset & 0x7fffffff;
 			return 0;
@@ -786,10 +779,6 @@
 		}
 
 		ino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep));
-#if XFS_BIG_INUMS
-		ino += mp->m_inoadd;
-#endif
-
 		if (filldir(dirent, sfep->name, sfep->namelen,
 			    off & 0x7fffffff, ino, DT_UNKNOWN)) {
 			*offset = off & 0x7fffffff;
diff --git a/fs/xfs/xfs_extfree_item.h b/fs/xfs/xfs_extfree_item.h
index 2f049f6..0d22c56 100644
--- a/fs/xfs/xfs_extfree_item.h
+++ b/fs/xfs/xfs_extfree_item.h
@@ -33,12 +33,10 @@
  * conversion routine.
  */
 
-#ifndef HAVE_FORMAT32
 typedef struct xfs_extent_32 {
 	__uint64_t	ext_start;
 	__uint32_t	ext_len;
 } __attribute__((packed)) xfs_extent_32_t;
-#endif
 
 typedef struct xfs_extent_64 {
 	__uint64_t	ext_start;
@@ -59,7 +57,6 @@
 	xfs_extent_t		efi_extents[1];	/* array of extents to free */
 } xfs_efi_log_format_t;
 
-#ifndef HAVE_FORMAT32
 typedef struct xfs_efi_log_format_32 {
 	__uint16_t		efi_type;	/* efi log item type */
 	__uint16_t		efi_size;	/* size of this item */
@@ -67,7 +64,6 @@
 	__uint64_t		efi_id;		/* efi identifier */
 	xfs_extent_32_t		efi_extents[1];	/* array of extents to free */
 } __attribute__((packed)) xfs_efi_log_format_32_t;
-#endif
 
 typedef struct xfs_efi_log_format_64 {
 	__uint16_t		efi_type;	/* efi log item type */
@@ -90,7 +86,6 @@
 	xfs_extent_t		efd_extents[1];	/* array of extents freed */
 } xfs_efd_log_format_t;
 
-#ifndef HAVE_FORMAT32
 typedef struct xfs_efd_log_format_32 {
 	__uint16_t		efd_type;	/* efd log item type */
 	__uint16_t		efd_size;	/* size of this item */
@@ -98,7 +93,6 @@
 	__uint64_t		efd_efi_id;	/* id of corresponding efi */
 	xfs_extent_32_t		efd_extents[1];	/* array of extents freed */
 } __attribute__((packed)) xfs_efd_log_format_32_t;
-#endif
 
 typedef struct xfs_efd_log_format_64 {
 	__uint16_t		efd_type;	/* efd log item type */
diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c
index f3bb75d..6c87c8f 100644
--- a/fs/xfs/xfs_filestream.c
+++ b/fs/xfs/xfs_filestream.c
@@ -140,7 +140,7 @@
 	xfs_extlen_t	minlen)
 {
 	int		err, trylock, nscan;
-	xfs_extlen_t	delta, longest, need, free, minfree, maxfree = 0;
+	xfs_extlen_t	longest, free, minfree, maxfree = 0;
 	xfs_agnumber_t	ag, max_ag = NULLAGNUMBER;
 	struct xfs_perag *pag;
 
@@ -186,12 +186,7 @@
 			goto next_ag;
 		}
 
-		need = XFS_MIN_FREELIST_PAG(pag, mp);
-		delta = need > pag->pagf_flcount ? need - pag->pagf_flcount : 0;
-		longest = (pag->pagf_longest > delta) ?
-		          (pag->pagf_longest - delta) :
-		          (pag->pagf_flcount > 0 || pag->pagf_longest > 0);
-
+		longest = xfs_alloc_longest_free_extent(mp, pag);
 		if (((minlen && longest >= minlen) ||
 		     (!minlen && pag->pagf_freeblks >= minfree)) &&
 		    (!pag->pagf_metadata || !(flags & XFS_PICK_USERDATA) ||
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 680d0e0..8379e3b 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -576,7 +576,7 @@
 	if (fdblks_delta) {
 		/*
 		 * If we are putting blocks back here, m_resblks_avail is
-		 * already at it's max so this will put it in the free pool.
+		 * already at its max so this will put it in the free pool.
 		 *
 		 * If we need space, we'll either succeed in getting it
 		 * from the free block count or we'll get an enospc. If
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index ab016e5..3120a3a 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -230,7 +230,7 @@
 		args.minalignslop = xfs_ialloc_cluster_alignment(&args) - 1;
 
 		/* Allow space for the inode btree to split. */
-		args.minleft = XFS_IN_MAXLEVELS(args.mp) - 1;
+		args.minleft = args.mp->m_in_maxlevels - 1;
 		if ((error = xfs_alloc_vextent(&args)))
 			return error;
 	} else
@@ -270,7 +270,7 @@
 		/*
 		 * Allow space for the inode btree to split.
 		 */
-		args.minleft = XFS_IN_MAXLEVELS(args.mp) - 1;
+		args.minleft = args.mp->m_in_maxlevels - 1;
 		if ((error = xfs_alloc_vextent(&args)))
 			return error;
 	}
@@ -349,7 +349,7 @@
 		 * Initialize all inodes in this buffer and then log them.
 		 *
 		 * XXX: It would be much better if we had just one transaction to
-		 *      log a whole cluster of inodes instead of all the indivdual
+		 *      log a whole cluster of inodes instead of all the individual
 		 *      transactions causing a lot of log traffic.
 		 */
 		xfs_biozero(fbuf, 0, ninodes << args.mp->m_sb.sb_inodelog);
@@ -943,7 +943,7 @@
 	ASSERT((XFS_AGINO_TO_OFFSET(mp, rec.ir_startino) %
 				   XFS_INODES_PER_CHUNK) == 0);
 	ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino + offset);
-	XFS_INOBT_CLR_FREE(&rec, offset);
+	rec.ir_free &= ~XFS_INOBT_MASK(offset);
 	rec.ir_freecount--;
 	if ((error = xfs_inobt_update(cur, rec.ir_startino, rec.ir_freecount,
 			rec.ir_free)))
@@ -1105,11 +1105,11 @@
 	 */
 	off = agino - rec.ir_startino;
 	ASSERT(off >= 0 && off < XFS_INODES_PER_CHUNK);
-	ASSERT(!XFS_INOBT_IS_FREE(&rec, off));
+	ASSERT(!(rec.ir_free & XFS_INOBT_MASK(off)));
 	/*
 	 * Mark the inode free & increment the count.
 	 */
-	XFS_INOBT_SET_FREE(&rec, off);
+	rec.ir_free |= XFS_INOBT_MASK(off);
 	rec.ir_freecount++;
 
 	/*
diff --git a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c
index 99f2408..c282a9a 100644
--- a/fs/xfs/xfs_ialloc_btree.c
+++ b/fs/xfs/xfs_ialloc_btree.c
@@ -164,7 +164,7 @@
 }
 
 /*
- * intial value of ptr for lookup
+ * initial value of ptr for lookup
  */
 STATIC void
 xfs_inobt_init_ptr_from_cur(
diff --git a/fs/xfs/xfs_ialloc_btree.h b/fs/xfs/xfs_ialloc_btree.h
index 5580e25..f782ad0 100644
--- a/fs/xfs/xfs_ialloc_btree.h
+++ b/fs/xfs/xfs_ialloc_btree.h
@@ -32,14 +32,14 @@
 #define	XFS_IBT_MAGIC	0x49414254	/* 'IABT' */
 
 typedef	__uint64_t	xfs_inofree_t;
-#define	XFS_INODES_PER_CHUNK	(NBBY * sizeof(xfs_inofree_t))
+#define	XFS_INODES_PER_CHUNK		(NBBY * sizeof(xfs_inofree_t))
 #define	XFS_INODES_PER_CHUNK_LOG	(XFS_NBBYLOG + 3)
-#define	XFS_INOBT_ALL_FREE	((xfs_inofree_t)-1)
+#define	XFS_INOBT_ALL_FREE		((xfs_inofree_t)-1)
+#define	XFS_INOBT_MASK(i)		((xfs_inofree_t)1 << (i))
 
 static inline xfs_inofree_t xfs_inobt_maskn(int i, int n)
 {
-	return (((n) >= XFS_INODES_PER_CHUNK ? \
-		(xfs_inofree_t)0 : ((xfs_inofree_t)1 << (n))) - 1) << (i);
+	return ((n >= XFS_INODES_PER_CHUNK ? 0 : XFS_INOBT_MASK(n)) - 1) << i;
 }
 
 /*
@@ -69,20 +69,6 @@
 typedef __be32 xfs_inobt_ptr_t;
 
 /*
- * Bit manipulations for ir_free.
- */
-#define	XFS_INOBT_MASK(i)		((xfs_inofree_t)1 << (i))
-#define	XFS_INOBT_IS_FREE(rp,i)		\
-		(((rp)->ir_free & XFS_INOBT_MASK(i)) != 0)
-#define	XFS_INOBT_SET_FREE(rp,i)	((rp)->ir_free |= XFS_INOBT_MASK(i))
-#define	XFS_INOBT_CLR_FREE(rp,i)	((rp)->ir_free &= ~XFS_INOBT_MASK(i))
-
-/*
- * Maximum number of inode btree levels.
- */
-#define	XFS_IN_MAXLEVELS(mp)		((mp)->m_in_maxlevels)
-
-/*
  * block numbers in the AG.
  */
 #define	XFS_IBT_BLOCK(mp)		((xfs_agblock_t)(XFS_CNT_BLOCK(mp) + 1))
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 1f175fa..f879c1b 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -122,7 +122,7 @@
 
 /*
  * NOTE:  This structure must be kept identical to struct xfs_dinode
- * 	  in xfs_dinode.h except for the endianess annotations.
+ * 	  in xfs_dinode.h except for the endianness annotations.
  */
 typedef struct xfs_icdinode {
 	__uint16_t	di_magic;	/* inode magic # = XFS_DINODE_MAGIC */
diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h
index 9957d06..a52ac12 100644
--- a/fs/xfs/xfs_inode_item.h
+++ b/fs/xfs/xfs_inode_item.h
@@ -40,7 +40,6 @@
 	__int32_t		ilf_boffset;	/* off of inode in buffer */
 } xfs_inode_log_format_t;
 
-#ifndef HAVE_FORMAT32
 typedef struct xfs_inode_log_format_32 {
 	__uint16_t		ilf_type;	/* inode log item type */
 	__uint16_t		ilf_size;	/* size of this item */
@@ -56,7 +55,6 @@
 	__int32_t		ilf_len;	/* len of inode buffer */
 	__int32_t		ilf_boffset;	/* off of inode in buffer */
 } __attribute__((packed)) xfs_inode_log_format_32_t;
-#endif
 
 typedef struct xfs_inode_log_format_64 {
 	__uint16_t		ilf_type;	/* inode log item type */
diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h
index ee1a0c1..a1cc132 100644
--- a/fs/xfs/xfs_iomap.h
+++ b/fs/xfs/xfs_iomap.h
@@ -63,7 +63,7 @@
  */
 
 typedef struct xfs_iomap {
-	xfs_daddr_t		iomap_bn;	/* first 512b blk of mapping */
+	xfs_daddr_t		iomap_bn;	/* first 512B blk of mapping */
 	xfs_buftarg_t		*iomap_target;
 	xfs_off_t		iomap_offset;	/* offset of mapping, bytes */
 	xfs_off_t		iomap_bsize;	/* size of mapping, bytes */
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index cf98a805..aeb2d22 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -83,7 +83,12 @@
 	buf->bs_uid = dic->di_uid;
 	buf->bs_gid = dic->di_gid;
 	buf->bs_size = dic->di_size;
-	vn_atime_to_bstime(VFS_I(ip), &buf->bs_atime);
+	/*
+	 * We are reading the atime from the Linux inode because the
+	 * dinode might not be uptodate.
+	 */
+	buf->bs_atime.tv_sec = VFS_I(ip)->i_atime.tv_sec;
+	buf->bs_atime.tv_nsec = VFS_I(ip)->i_atime.tv_nsec;
 	buf->bs_mtime.tv_sec = dic->di_mtime.t_sec;
 	buf->bs_mtime.tv_nsec = dic->di_mtime.t_nsec;
 	buf->bs_ctime.tv_sec = dic->di_ctime.t_sec;
@@ -579,7 +584,7 @@
 				 * first inode of the cluster.
 				 *
 				 * Careful with clustidx.   There can be
-				 * multple clusters per chunk, a single
+				 * multiple clusters per chunk, a single
 				 * cluster per chunk or a cluster that has
 				 * inodes represented from several different
 				 * chunks (if blocksize is large).
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index f4726f70..f76c6d7 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -574,7 +574,7 @@
 	error = xfs_trans_ail_init(mp);
 	if (error) {
 		cmn_err(CE_WARN, "XFS: AIL initialisation failed: error %d", error);
-		goto error;
+		goto out_free_log;
 	}
 	mp->m_log->l_ailp = mp->m_ail;
 
@@ -594,20 +594,22 @@
 			mp->m_flags |= XFS_MOUNT_RDONLY;
 		if (error) {
 			cmn_err(CE_WARN, "XFS: log mount/recovery failed: error %d", error);
-			goto error;
+			goto out_destroy_ail;
 		}
 	}
 
 	/* Normal transactions can now occur */
 	mp->m_log->l_flags &= ~XLOG_ACTIVE_RECOVERY;
 
-	/* End mounting message in xfs_log_mount_finish */
 	return 0;
-error:
-	xfs_log_unmount_dealloc(mp);
+
+out_destroy_ail:
+	xfs_trans_ail_destroy(mp);
+out_free_log:
+	xlog_dealloc_log(mp->m_log);
 out:
 	return error;
-}	/* xfs_log_mount */
+}
 
 /*
  * Finish the recovery of the file system.  This is separate from
@@ -633,19 +635,6 @@
 }
 
 /*
- * Unmount processing for the log.
- */
-int
-xfs_log_unmount(xfs_mount_t *mp)
-{
-	int		error;
-
-	error = xfs_log_unmount_write(mp);
-	xfs_log_unmount_dealloc(mp);
-	return error;
-}
-
-/*
  * Final log writes as part of unmount.
  *
  * Mark the filesystem clean as unmount happens.  Note that during relocation
@@ -795,7 +784,7 @@
  * and deallocate the log as the aild references the log.
  */
 void
-xfs_log_unmount_dealloc(xfs_mount_t *mp)
+xfs_log_unmount(xfs_mount_t *mp)
 {
 	xfs_trans_ail_destroy(mp);
 	xlog_dealloc_log(mp->m_log);
@@ -1109,7 +1098,7 @@
 /*
  * Return size of each in-core log record buffer.
  *
- * All machines get 8 x 32KB buffers by default, unless tuned otherwise.
+ * All machines get 8 x 32kB buffers by default, unless tuned otherwise.
  *
  * If the filesystem blocksize is too large, we may need to choose a
  * larger size since the directory code currently logs entire blocks.
@@ -1139,8 +1128,8 @@
 		}
 
 		if (xfs_sb_version_haslogv2(&mp->m_sb)) {
-			/* # headers = size / 32K
-			 * one header holds cycles from 32K of data
+			/* # headers = size / 32k
+			 * one header holds cycles from 32k of data
 			 */
 
 			xhdrs = mp->m_logbsize / XLOG_HEADER_CYCLE_SIZE;
@@ -1156,7 +1145,7 @@
 		goto done;
 	}
 
-	/* All machines use 32KB buffers by default. */
+	/* All machines use 32kB buffers by default. */
 	log->l_iclog_size = XLOG_BIG_RECORD_BSIZE;
 	log->l_iclog_size_log = XLOG_BIG_RECORD_BSHIFT;
 
@@ -1164,32 +1153,8 @@
 	log->l_iclog_hsize = BBSIZE;
 	log->l_iclog_heads = 1;
 
-	/*
-	 * For 16KB, we use 3 32KB buffers.  For 32KB block sizes, we use
-	 * 4 32KB buffers.  For 64KB block sizes, we use 8 32KB buffers.
-	 */
-	if (mp->m_sb.sb_blocksize >= 16*1024) {
-		log->l_iclog_size = XLOG_BIG_RECORD_BSIZE;
-		log->l_iclog_size_log = XLOG_BIG_RECORD_BSHIFT;
-		if (mp->m_logbufs <= 0) {
-			switch (mp->m_sb.sb_blocksize) {
-			    case 16*1024:			/* 16 KB */
-				log->l_iclog_bufs = 3;
-				break;
-			    case 32*1024:			/* 32 KB */
-				log->l_iclog_bufs = 4;
-				break;
-			    case 64*1024:			/* 64 KB */
-				log->l_iclog_bufs = 8;
-				break;
-			    default:
-				xlog_panic("XFS: Invalid blocksize");
-				break;
-			}
-		}
-	}
-
-done:	/* are we being asked to make the sizes selected above visible? */
+done:
+	/* are we being asked to make the sizes selected above visible? */
 	if (mp->m_logbufs == 0)
 		mp->m_logbufs = log->l_iclog_bufs;
 	if (mp->m_logbsize == 0)
@@ -3214,7 +3179,7 @@
  */
 
 /*
- * Free a used ticket when it's refcount falls to zero.
+ * Free a used ticket when its refcount falls to zero.
  */
 void
 xfs_log_ticket_put(
diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h
index 8a3e84e..d0c9baa 100644
--- a/fs/xfs/xfs_log.h
+++ b/fs/xfs/xfs_log.h
@@ -170,9 +170,8 @@
 			int		 nentries,
 			xfs_log_ticket_t ticket,
 			xfs_lsn_t	 *start_lsn);
-int	  xfs_log_unmount(struct xfs_mount *mp);
 int	  xfs_log_unmount_write(struct xfs_mount *mp);
-void      xfs_log_unmount_dealloc(struct xfs_mount *mp);
+void      xfs_log_unmount(struct xfs_mount *mp);
 int	  xfs_log_force_umount(struct xfs_mount *mp, int logerror);
 int	  xfs_log_need_covered(struct xfs_mount *mp);
 
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h
index 654167b..bcad5f4 100644
--- a/fs/xfs/xfs_log_priv.h
+++ b/fs/xfs/xfs_log_priv.h
@@ -359,7 +359,7 @@
 	int			ic_size;
 	int			ic_offset;
 	int			ic_bwritecnt;
-	ushort_t		ic_state;
+	unsigned short		ic_state;
 	char			*ic_datap;	/* pointer to iclog data */
 #ifdef XFS_LOG_TRACE
 	struct ktrace		*ic_trace;
@@ -455,7 +455,6 @@
 
 extern struct xfs_buf *xlog_get_bp(xlog_t *, int);
 extern void	 xlog_put_bp(struct xfs_buf *);
-extern int	 xlog_bread(xlog_t *, xfs_daddr_t, int, struct xfs_buf *);
 
 extern kmem_zone_t	*xfs_log_ticket_zone;
 
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 61af610..7ba4501 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -94,12 +94,30 @@
 	xfs_buf_free(bp);
 }
 
+STATIC xfs_caddr_t
+xlog_align(
+	xlog_t		*log,
+	xfs_daddr_t	blk_no,
+	int		nbblks,
+	xfs_buf_t	*bp)
+{
+	xfs_caddr_t	ptr;
+
+	if (!log->l_sectbb_log)
+		return XFS_BUF_PTR(bp);
+
+	ptr = XFS_BUF_PTR(bp) + BBTOB((int)blk_no & log->l_sectbb_mask);
+	ASSERT(XFS_BUF_SIZE(bp) >=
+		BBTOB(nbblks + (blk_no & log->l_sectbb_mask)));
+	return ptr;
+}
+
 
 /*
  * nbblks should be uint, but oh well.  Just want to catch that 32-bit length.
  */
-int
-xlog_bread(
+STATIC int
+xlog_bread_noalign(
 	xlog_t		*log,
 	xfs_daddr_t	blk_no,
 	int		nbblks,
@@ -137,6 +155,24 @@
 	return error;
 }
 
+STATIC int
+xlog_bread(
+	xlog_t		*log,
+	xfs_daddr_t	blk_no,
+	int		nbblks,
+	xfs_buf_t	*bp,
+	xfs_caddr_t	*offset)
+{
+	int		error;
+
+	error = xlog_bread_noalign(log, blk_no, nbblks, bp);
+	if (error)
+		return error;
+
+	*offset = xlog_align(log, blk_no, nbblks, bp);
+	return 0;
+}
+
 /*
  * Write out the buffer at the given block for the given number of blocks.
  * The buffer is kept locked across the write and is returned locked.
@@ -180,24 +216,6 @@
 	return error;
 }
 
-STATIC xfs_caddr_t
-xlog_align(
-	xlog_t		*log,
-	xfs_daddr_t	blk_no,
-	int		nbblks,
-	xfs_buf_t	*bp)
-{
-	xfs_caddr_t	ptr;
-
-	if (!log->l_sectbb_log)
-		return XFS_BUF_PTR(bp);
-
-	ptr = XFS_BUF_PTR(bp) + BBTOB((int)blk_no & log->l_sectbb_mask);
-	ASSERT(XFS_BUF_SIZE(bp) >=
-		BBTOB(nbblks + (blk_no & log->l_sectbb_mask)));
-	return ptr;
-}
-
 #ifdef DEBUG
 /*
  * dump debug superblock and log record information
@@ -211,11 +229,11 @@
 
 	cmn_err(CE_DEBUG, "%s:  SB : uuid = ", __func__);
 	for (b = 0; b < 16; b++)
-		cmn_err(CE_DEBUG, "%02x", ((uchar_t *)&mp->m_sb.sb_uuid)[b]);
+		cmn_err(CE_DEBUG, "%02x", ((__uint8_t *)&mp->m_sb.sb_uuid)[b]);
 	cmn_err(CE_DEBUG, ", fmt = %d\n", XLOG_FMT);
 	cmn_err(CE_DEBUG, "    log : uuid = ");
 	for (b = 0; b < 16; b++)
-		cmn_err(CE_DEBUG, "%02x",((uchar_t *)&head->h_fs_uuid)[b]);
+		cmn_err(CE_DEBUG, "%02x", ((__uint8_t *)&head->h_fs_uuid)[b]);
 	cmn_err(CE_DEBUG, ", fmt = %d\n", be32_to_cpu(head->h_fmt));
 }
 #else
@@ -321,9 +339,9 @@
 
 	mid_blk = BLK_AVG(first_blk, *last_blk);
 	while (mid_blk != first_blk && mid_blk != *last_blk) {
-		if ((error = xlog_bread(log, mid_blk, 1, bp)))
+		error = xlog_bread(log, mid_blk, 1, bp, &offset);
+		if (error)
 			return error;
-		offset = xlog_align(log, mid_blk, 1, bp);
 		mid_cycle = xlog_get_cycle(offset);
 		if (mid_cycle == cycle) {
 			*last_blk = mid_blk;
@@ -379,10 +397,10 @@
 
 		bcount = min(bufblks, (start_blk + nbblks - i));
 
-		if ((error = xlog_bread(log, i, bcount, bp)))
+		error = xlog_bread(log, i, bcount, bp, &buf);
+		if (error)
 			goto out;
 
-		buf = xlog_align(log, i, bcount, bp);
 		for (j = 0; j < bcount; j++) {
 			cycle = xlog_get_cycle(buf);
 			if (cycle == stop_on_cycle_no) {
@@ -436,9 +454,9 @@
 			return ENOMEM;
 		smallmem = 1;
 	} else {
-		if ((error = xlog_bread(log, start_blk, num_blks, bp)))
+		error = xlog_bread(log, start_blk, num_blks, bp, &offset);
+		if (error)
 			goto out;
-		offset = xlog_align(log, start_blk, num_blks, bp);
 		offset += ((num_blks - 1) << BBSHIFT);
 	}
 
@@ -453,9 +471,9 @@
 		}
 
 		if (smallmem) {
-			if ((error = xlog_bread(log, i, 1, bp)))
+			error = xlog_bread(log, i, 1, bp, &offset);
+			if (error)
 				goto out;
-			offset = xlog_align(log, i, 1, bp);
 		}
 
 		head = (xlog_rec_header_t *)offset;
@@ -559,15 +577,18 @@
 	bp = xlog_get_bp(log, 1);
 	if (!bp)
 		return ENOMEM;
-	if ((error = xlog_bread(log, 0, 1, bp)))
+
+	error = xlog_bread(log, 0, 1, bp, &offset);
+	if (error)
 		goto bp_err;
-	offset = xlog_align(log, 0, 1, bp);
+
 	first_half_cycle = xlog_get_cycle(offset);
 
 	last_blk = head_blk = log_bbnum - 1;	/* get cycle # of last block */
-	if ((error = xlog_bread(log, last_blk, 1, bp)))
+	error = xlog_bread(log, last_blk, 1, bp, &offset);
+	if (error)
 		goto bp_err;
-	offset = xlog_align(log, last_blk, 1, bp);
+
 	last_half_cycle = xlog_get_cycle(offset);
 	ASSERT(last_half_cycle != 0);
 
@@ -817,9 +838,10 @@
 	if (!bp)
 		return ENOMEM;
 	if (*head_blk == 0) {				/* special case */
-		if ((error = xlog_bread(log, 0, 1, bp)))
+		error = xlog_bread(log, 0, 1, bp, &offset);
+		if (error)
 			goto bread_err;
-		offset = xlog_align(log, 0, 1, bp);
+
 		if (xlog_get_cycle(offset) == 0) {
 			*tail_blk = 0;
 			/* leave all other log inited values alone */
@@ -832,9 +854,10 @@
 	 */
 	ASSERT(*head_blk < INT_MAX);
 	for (i = (int)(*head_blk) - 1; i >= 0; i--) {
-		if ((error = xlog_bread(log, i, 1, bp)))
+		error = xlog_bread(log, i, 1, bp, &offset);
+		if (error)
 			goto bread_err;
-		offset = xlog_align(log, i, 1, bp);
+
 		if (XLOG_HEADER_MAGIC_NUM == be32_to_cpu(*(__be32 *)offset)) {
 			found = 1;
 			break;
@@ -848,9 +871,10 @@
 	 */
 	if (!found) {
 		for (i = log->l_logBBsize - 1; i >= (int)(*head_blk); i--) {
-			if ((error = xlog_bread(log, i, 1, bp)))
+			error = xlog_bread(log, i, 1, bp, &offset);
+			if (error)
 				goto bread_err;
-			offset = xlog_align(log, i, 1, bp);
+
 			if (XLOG_HEADER_MAGIC_NUM ==
 			    be32_to_cpu(*(__be32 *)offset)) {
 				found = 2;
@@ -922,10 +946,10 @@
 	if (*head_blk == after_umount_blk &&
 	    be32_to_cpu(rhead->h_num_logops) == 1) {
 		umount_data_blk = (i + hblks) % log->l_logBBsize;
-		if ((error = xlog_bread(log, umount_data_blk, 1, bp))) {
+		error = xlog_bread(log, umount_data_blk, 1, bp, &offset);
+		if (error)
 			goto bread_err;
-		}
-		offset = xlog_align(log, umount_data_blk, 1, bp);
+
 		op_head = (xlog_op_header_t *)offset;
 		if (op_head->oh_flags & XLOG_UNMOUNT_TRANS) {
 			/*
@@ -1017,9 +1041,10 @@
 	bp = xlog_get_bp(log, 1);
 	if (!bp)
 		return ENOMEM;
-	if ((error = xlog_bread(log, 0, 1, bp)))
+	error = xlog_bread(log, 0, 1, bp, &offset);
+	if (error)
 		goto bp_err;
-	offset = xlog_align(log, 0, 1, bp);
+
 	first_cycle = xlog_get_cycle(offset);
 	if (first_cycle == 0) {		/* completely zeroed log */
 		*blk_no = 0;
@@ -1028,9 +1053,10 @@
 	}
 
 	/* check partially zeroed log */
-	if ((error = xlog_bread(log, log_bbnum-1, 1, bp)))
+	error = xlog_bread(log, log_bbnum-1, 1, bp, &offset);
+	if (error)
 		goto bp_err;
-	offset = xlog_align(log, log_bbnum-1, 1, bp);
+
 	last_cycle = xlog_get_cycle(offset);
 	if (last_cycle != 0) {		/* log completely written to */
 		xlog_put_bp(bp);
@@ -1152,10 +1178,10 @@
 	 */
 	balign = XLOG_SECTOR_ROUNDDOWN_BLKNO(log, start_block);
 	if (balign != start_block) {
-		if ((error = xlog_bread(log, start_block, 1, bp))) {
-			xlog_put_bp(bp);
-			return error;
-		}
+		error = xlog_bread_noalign(log, start_block, 1, bp);
+		if (error)
+			goto out_put_bp;
+
 		j = start_block - balign;
 	}
 
@@ -1175,10 +1201,14 @@
 			balign = BBTOB(ealign - start_block);
 			error = XFS_BUF_SET_PTR(bp, offset + balign,
 						BBTOB(sectbb));
-			if (!error)
-				error = xlog_bread(log, ealign, sectbb, bp);
-			if (!error)
-				error = XFS_BUF_SET_PTR(bp, offset, bufblks);
+			if (error)
+				break;
+
+			error = xlog_bread_noalign(log, ealign, sectbb, bp);
+			if (error)
+				break;
+
+			error = XFS_BUF_SET_PTR(bp, offset, bufblks);
 			if (error)
 				break;
 		}
@@ -1195,6 +1225,8 @@
 		start_block += endcount;
 		j = 0;
 	}
+
+ out_put_bp:
 	xlog_put_bp(bp);
 	return error;
 }
@@ -2511,16 +2543,10 @@
 	}
 
 write_inode_buffer:
-	if (ITEM_TYPE(item) == XFS_LI_INODE) {
-		ASSERT(bp->b_mount == NULL || bp->b_mount == mp);
-		bp->b_mount = mp;
-		XFS_BUF_SET_IODONE_FUNC(bp, xlog_recover_iodone);
-		xfs_bdwrite(mp, bp);
-	} else {
-		XFS_BUF_STALE(bp);
-		error = xfs_bwrite(mp, bp);
-	}
-
+	ASSERT(bp->b_mount == NULL || bp->b_mount == mp);
+	bp->b_mount = mp;
+	XFS_BUF_SET_IODONE_FUNC(bp, xlog_recover_iodone);
+	xfs_bdwrite(mp, bp);
 error:
 	if (need_free)
 		kmem_free(in_f);
@@ -2769,51 +2795,48 @@
 	int			error = 0;
 	xlog_recover_item_t	*item, *first_item;
 
-	if ((error = xlog_recover_reorder_trans(trans)))
+	error = xlog_recover_reorder_trans(trans);
+	if (error)
 		return error;
+
 	first_item = item = trans->r_itemq;
 	do {
-		/*
-		 * we don't need to worry about the block number being
-		 * truncated in > 1 TB buffers because in user-land,
-		 * we're now n32 or 64-bit so xfs_daddr_t is 64-bits so
-		 * the blknos will get through the user-mode buffer
-		 * cache properly.  The only bad case is o32 kernels
-		 * where xfs_daddr_t is 32-bits but mount will warn us
-		 * off a > 1 TB filesystem before we get here.
-		 */
-		if ((ITEM_TYPE(item) == XFS_LI_BUF)) {
-			if  ((error = xlog_recover_do_buffer_trans(log, item,
-								 pass)))
-				break;
-		} else if ((ITEM_TYPE(item) == XFS_LI_INODE)) {
-			if ((error = xlog_recover_do_inode_trans(log, item,
-								pass)))
-				break;
-		} else if (ITEM_TYPE(item) == XFS_LI_EFI) {
-			if ((error = xlog_recover_do_efi_trans(log, item, trans->r_lsn,
-						  pass)))
-				break;
-		} else if (ITEM_TYPE(item) == XFS_LI_EFD) {
+		switch (ITEM_TYPE(item)) {
+		case XFS_LI_BUF:
+			error = xlog_recover_do_buffer_trans(log, item, pass);
+			break;
+		case XFS_LI_INODE:
+			error = xlog_recover_do_inode_trans(log, item, pass);
+			break;
+		case XFS_LI_EFI:
+			error = xlog_recover_do_efi_trans(log, item,
+							  trans->r_lsn, pass);
+			break;
+		case XFS_LI_EFD:
 			xlog_recover_do_efd_trans(log, item, pass);
-		} else if (ITEM_TYPE(item) == XFS_LI_DQUOT) {
-			if ((error = xlog_recover_do_dquot_trans(log, item,
-								   pass)))
-					break;
-		} else if ((ITEM_TYPE(item) == XFS_LI_QUOTAOFF)) {
-			if ((error = xlog_recover_do_quotaoff_trans(log, item,
-								   pass)))
-					break;
-		} else {
-			xlog_warn("XFS: xlog_recover_do_trans");
+			error = 0;
+			break;
+		case XFS_LI_DQUOT:
+			error = xlog_recover_do_dquot_trans(log, item, pass);
+			break;
+		case XFS_LI_QUOTAOFF:
+			error = xlog_recover_do_quotaoff_trans(log, item,
+							       pass);
+			break;
+		default:
+			xlog_warn(
+	"XFS: invalid item type (%d) xlog_recover_do_trans", ITEM_TYPE(item));
 			ASSERT(0);
 			error = XFS_ERROR(EIO);
 			break;
 		}
+
+		if (error)
+			return error;
 		item = item->ri_next;
 	} while (first_item != item);
 
-	return error;
+	return 0;
 }
 
 /*
@@ -3490,9 +3513,11 @@
 		hbp = xlog_get_bp(log, 1);
 		if (!hbp)
 			return ENOMEM;
-		if ((error = xlog_bread(log, tail_blk, 1, hbp)))
+
+		error = xlog_bread(log, tail_blk, 1, hbp, &offset);
+		if (error)
 			goto bread_err1;
-		offset = xlog_align(log, tail_blk, 1, hbp);
+
 		rhead = (xlog_rec_header_t *)offset;
 		error = xlog_valid_rec_header(log, rhead, tail_blk);
 		if (error)
@@ -3526,9 +3551,10 @@
 	memset(rhash, 0, sizeof(rhash));
 	if (tail_blk <= head_blk) {
 		for (blk_no = tail_blk; blk_no < head_blk; ) {
-			if ((error = xlog_bread(log, blk_no, hblks, hbp)))
+			error = xlog_bread(log, blk_no, hblks, hbp, &offset);
+			if (error)
 				goto bread_err2;
-			offset = xlog_align(log, blk_no, hblks, hbp);
+
 			rhead = (xlog_rec_header_t *)offset;
 			error = xlog_valid_rec_header(log, rhead, blk_no);
 			if (error)
@@ -3536,10 +3562,11 @@
 
 			/* blocks in data section */
 			bblks = (int)BTOBB(be32_to_cpu(rhead->h_len));
-			error = xlog_bread(log, blk_no + hblks, bblks, dbp);
+			error = xlog_bread(log, blk_no + hblks, bblks, dbp,
+					   &offset);
 			if (error)
 				goto bread_err2;
-			offset = xlog_align(log, blk_no + hblks, bblks, dbp);
+
 			xlog_unpack_data(rhead, offset, log);
 			if ((error = xlog_recover_process_data(log,
 						rhash, rhead, offset, pass)))
@@ -3562,10 +3589,10 @@
 			wrapped_hblks = 0;
 			if (blk_no + hblks <= log->l_logBBsize) {
 				/* Read header in one read */
-				error = xlog_bread(log, blk_no, hblks, hbp);
+				error = xlog_bread(log, blk_no, hblks, hbp,
+						   &offset);
 				if (error)
 					goto bread_err2;
-				offset = xlog_align(log, blk_no, hblks, hbp);
 			} else {
 				/* This LR is split across physical log end */
 				if (blk_no != log->l_logBBsize) {
@@ -3573,12 +3600,13 @@
 					ASSERT(blk_no <= INT_MAX);
 					split_hblks = log->l_logBBsize - (int)blk_no;
 					ASSERT(split_hblks > 0);
-					if ((error = xlog_bread(log, blk_no,
-							split_hblks, hbp)))
+					error = xlog_bread(log, blk_no,
+							   split_hblks, hbp,
+							   &offset);
+					if (error)
 						goto bread_err2;
-					offset = xlog_align(log, blk_no,
-							split_hblks, hbp);
 				}
+
 				/*
 				 * Note: this black magic still works with
 				 * large sector sizes (non-512) only because:
@@ -3596,14 +3624,19 @@
 				error = XFS_BUF_SET_PTR(hbp,
 						bufaddr + BBTOB(split_hblks),
 						BBTOB(hblks - split_hblks));
-				if (!error)
-					error = xlog_bread(log, 0,
-							wrapped_hblks, hbp);
-				if (!error)
-					error = XFS_BUF_SET_PTR(hbp, bufaddr,
+				if (error)
+					goto bread_err2;
+
+				error = xlog_bread_noalign(log, 0,
+							   wrapped_hblks, hbp);
+				if (error)
+					goto bread_err2;
+
+				error = XFS_BUF_SET_PTR(hbp, bufaddr,
 							BBTOB(hblks));
 				if (error)
 					goto bread_err2;
+
 				if (!offset)
 					offset = xlog_align(log, 0,
 							wrapped_hblks, hbp);
@@ -3619,10 +3652,10 @@
 
 			/* Read in data for log record */
 			if (blk_no + bblks <= log->l_logBBsize) {
-				error = xlog_bread(log, blk_no, bblks, dbp);
+				error = xlog_bread(log, blk_no, bblks, dbp,
+						   &offset);
 				if (error)
 					goto bread_err2;
-				offset = xlog_align(log, blk_no, bblks, dbp);
 			} else {
 				/* This log record is split across the
 				 * physical end of log */
@@ -3636,12 +3669,13 @@
 					split_bblks =
 						log->l_logBBsize - (int)blk_no;
 					ASSERT(split_bblks > 0);
-					if ((error = xlog_bread(log, blk_no,
-							split_bblks, dbp)))
+					error = xlog_bread(log, blk_no,
+							split_bblks, dbp,
+							&offset);
+					if (error)
 						goto bread_err2;
-					offset = xlog_align(log, blk_no,
-							split_bblks, dbp);
 				}
+
 				/*
 				 * Note: this black magic still works with
 				 * large sector sizes (non-512) only because:
@@ -3658,15 +3692,19 @@
 				error = XFS_BUF_SET_PTR(dbp,
 						bufaddr + BBTOB(split_bblks),
 						BBTOB(bblks - split_bblks));
-				if (!error)
-					error = xlog_bread(log, wrapped_hblks,
-							bblks - split_bblks,
-							dbp);
-				if (!error)
-					error = XFS_BUF_SET_PTR(dbp, bufaddr,
-							h_size);
 				if (error)
 					goto bread_err2;
+
+				error = xlog_bread_noalign(log, wrapped_hblks,
+						bblks - split_bblks,
+						dbp);
+				if (error)
+					goto bread_err2;
+
+				error = XFS_BUF_SET_PTR(dbp, bufaddr, h_size);
+				if (error)
+					goto bread_err2;
+
 				if (!offset)
 					offset = xlog_align(log, wrapped_hblks,
 						bblks - split_bblks, dbp);
@@ -3683,17 +3721,21 @@
 
 		/* read first part of physical log */
 		while (blk_no < head_blk) {
-			if ((error = xlog_bread(log, blk_no, hblks, hbp)))
+			error = xlog_bread(log, blk_no, hblks, hbp, &offset);
+			if (error)
 				goto bread_err2;
-			offset = xlog_align(log, blk_no, hblks, hbp);
+
 			rhead = (xlog_rec_header_t *)offset;
 			error = xlog_valid_rec_header(log, rhead, blk_no);
 			if (error)
 				goto bread_err2;
+
 			bblks = (int)BTOBB(be32_to_cpu(rhead->h_len));
-			if ((error = xlog_bread(log, blk_no+hblks, bblks, dbp)))
+			error = xlog_bread(log, blk_no+hblks, bblks, dbp,
+					   &offset);
+			if (error)
 				goto bread_err2;
-			offset = xlog_align(log, blk_no+hblks, bblks, dbp);
+
 			xlog_unpack_data(rhead, offset, log);
 			if ((error = xlog_recover_process_data(log, rhash,
 							rhead, offset, pass)))
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 3530025..b101990 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -45,7 +45,6 @@
 #include "xfs_fsops.h"
 #include "xfs_utils.h"
 
-STATIC int	xfs_uuid_mount(xfs_mount_t *);
 STATIC void	xfs_unmountfs_wait(xfs_mount_t *);
 
 
@@ -121,6 +120,84 @@
     { sizeof(xfs_sb_t),			 0 }
 };
 
+static DEFINE_MUTEX(xfs_uuid_table_mutex);
+static int xfs_uuid_table_size;
+static uuid_t *xfs_uuid_table;
+
+/*
+ * See if the UUID is unique among mounted XFS filesystems.
+ * Mount fails if UUID is nil or a FS with the same UUID is already mounted.
+ */
+STATIC int
+xfs_uuid_mount(
+	struct xfs_mount	*mp)
+{
+	uuid_t			*uuid = &mp->m_sb.sb_uuid;
+	int			hole, i;
+
+	if (mp->m_flags & XFS_MOUNT_NOUUID)
+		return 0;
+
+	if (uuid_is_nil(uuid)) {
+		cmn_err(CE_WARN,
+			"XFS: Filesystem %s has nil UUID - can't mount",
+			mp->m_fsname);
+		return XFS_ERROR(EINVAL);
+	}
+
+	mutex_lock(&xfs_uuid_table_mutex);
+	for (i = 0, hole = -1; i < xfs_uuid_table_size; i++) {
+		if (uuid_is_nil(&xfs_uuid_table[i])) {
+			hole = i;
+			continue;
+		}
+		if (uuid_equal(uuid, &xfs_uuid_table[i]))
+			goto out_duplicate;
+	}
+
+	if (hole < 0) {
+		xfs_uuid_table = kmem_realloc(xfs_uuid_table,
+			(xfs_uuid_table_size + 1) * sizeof(*xfs_uuid_table),
+			xfs_uuid_table_size  * sizeof(*xfs_uuid_table),
+			KM_SLEEP);
+		hole = xfs_uuid_table_size++;
+	}
+	xfs_uuid_table[hole] = *uuid;
+	mutex_unlock(&xfs_uuid_table_mutex);
+
+	return 0;
+
+ out_duplicate:
+	mutex_unlock(&xfs_uuid_table_mutex);
+	cmn_err(CE_WARN, "XFS: Filesystem %s has duplicate UUID - can't mount",
+			 mp->m_fsname);
+	return XFS_ERROR(EINVAL);
+}
+
+STATIC void
+xfs_uuid_unmount(
+	struct xfs_mount	*mp)
+{
+	uuid_t			*uuid = &mp->m_sb.sb_uuid;
+	int			i;
+
+	if (mp->m_flags & XFS_MOUNT_NOUUID)
+		return;
+
+	mutex_lock(&xfs_uuid_table_mutex);
+	for (i = 0; i < xfs_uuid_table_size; i++) {
+		if (uuid_is_nil(&xfs_uuid_table[i]))
+			continue;
+		if (!uuid_equal(uuid, &xfs_uuid_table[i]))
+			continue;
+		memset(&xfs_uuid_table[i], 0, sizeof(uuid_t));
+		break;
+	}
+	ASSERT(i < xfs_uuid_table_size);
+	mutex_unlock(&xfs_uuid_table_mutex);
+}
+
+
 /*
  * Free up the resources associated with a mount structure.  Assume that
  * the structure was initially zeroed, so we can tell which fields got
@@ -256,6 +333,22 @@
 		return XFS_ERROR(ENOSYS);
 	}
 
+	/*
+	 * Currently only very few inode sizes are supported.
+	 */
+	switch (sbp->sb_inodesize) {
+	case 256:
+	case 512:
+	case 1024:
+	case 2048:
+		break;
+	default:
+		xfs_fs_mount_cmn_err(flags,
+			"inode size of %d bytes not supported",
+			sbp->sb_inodesize);
+		return XFS_ERROR(ENOSYS);
+	}
+
 	if (xfs_sb_validate_fsb_count(sbp, sbp->sb_dblocks) ||
 	    xfs_sb_validate_fsb_count(sbp, sbp->sb_rblocks)) {
 		xfs_fs_mount_cmn_err(flags,
@@ -574,32 +667,10 @@
 	mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
 	mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1;
 	mp->m_agino_log = sbp->sb_inopblog + sbp->sb_agblklog;
-	mp->m_litino = sbp->sb_inodesize - sizeof(struct xfs_dinode);
 	mp->m_blockmask = sbp->sb_blocksize - 1;
 	mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG;
 	mp->m_blockwmask = mp->m_blockwsize - 1;
 
-	/*
-	 * Setup for attributes, in case they get created.
-	 * This value is for inodes getting attributes for the first time,
-	 * the per-inode value is for old attribute values.
-	 */
-	ASSERT(sbp->sb_inodesize >= 256 && sbp->sb_inodesize <= 2048);
-	switch (sbp->sb_inodesize) {
-	case 256:
-		mp->m_attroffset = XFS_LITINO(mp) -
-				   XFS_BMDR_SPACE_CALC(MINABTPTRS);
-		break;
-	case 512:
-	case 1024:
-	case 2048:
-		mp->m_attroffset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS);
-		break;
-	default:
-		ASSERT(0);
-	}
-	ASSERT(mp->m_attroffset < XFS_LITINO(mp));
-
 	mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 1);
 	mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0);
 	mp->m_alloc_mnr[0] = mp->m_alloc_mxr[0] / 2;
@@ -645,7 +716,7 @@
 	for (index = 0; index < agcount; index++) {
 		/*
 		 * read the agf, then the agi. This gets us
-		 * all the inforamtion we need and populates the
+		 * all the information we need and populates the
 		 * per-ag structures for us.
 		 */
 		error = xfs_alloc_pagf_init(mp, NULL, index, 0);
@@ -886,8 +957,6 @@
 }
 
 /*
- * xfs_mountfs
- *
  * This function does the following on an initial mount of a file system:
  *	- reads the superblock from disk and init the mount struct
  *	- if we're a 32-bit kernel, do a size check on the superblock
@@ -905,7 +974,6 @@
 	xfs_inode_t	*rip;
 	__uint64_t	resblks;
 	uint		quotamount, quotaflags;
-	int		uuid_mounted = 0;
 	int		error = 0;
 
 	xfs_mount_common(mp, sbp);
@@ -960,7 +1028,7 @@
 	 */
 	error = xfs_update_alignment(mp);
 	if (error)
-		goto error1;
+		goto out;
 
 	xfs_alloc_compute_maxlevels(mp);
 	xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK);
@@ -971,19 +1039,9 @@
 
 	mp->m_maxioffset = xfs_max_file_offset(sbp->sb_blocklog);
 
-	/*
-	 * XFS uses the uuid from the superblock as the unique
-	 * identifier for fsid.  We can not use the uuid from the volume
-	 * since a single partition filesystem is identical to a single
-	 * partition volume/filesystem.
-	 */
-	if ((mp->m_flags & XFS_MOUNT_NOUUID) == 0) {
-		if (xfs_uuid_mount(mp)) {
-			error = XFS_ERROR(EINVAL);
-			goto error1;
-		}
-		uuid_mounted=1;
-	}
+	error = xfs_uuid_mount(mp);
+	if (error)
+		goto out;
 
 	/*
 	 * Set the minimum read and write sizes
@@ -1007,7 +1065,7 @@
 	 */
 	error = xfs_check_sizes(mp);
 	if (error)
-		goto error1;
+		goto out_remove_uuid;
 
 	/*
 	 * Initialize realtime fields in the mount structure
@@ -1015,7 +1073,7 @@
 	error = xfs_rtmount_init(mp);
 	if (error) {
 		cmn_err(CE_WARN, "XFS: RT mount failed");
-		goto error1;
+		goto out_remove_uuid;
 	}
 
 	/*
@@ -1045,26 +1103,26 @@
 	mp->m_perag = kmem_zalloc(sbp->sb_agcount * sizeof(xfs_perag_t),
 				  KM_MAYFAIL);
 	if (!mp->m_perag)
-		goto error1;
+		goto out_remove_uuid;
 
 	mp->m_maxagi = xfs_initialize_perag(mp, sbp->sb_agcount);
 
+	if (!sbp->sb_logblocks) {
+		cmn_err(CE_WARN, "XFS: no log defined");
+		XFS_ERROR_REPORT("xfs_mountfs", XFS_ERRLEVEL_LOW, mp);
+		error = XFS_ERROR(EFSCORRUPTED);
+		goto out_free_perag;
+	}
+
 	/*
 	 * log's mount-time initialization. Perform 1st part recovery if needed
 	 */
-	if (likely(sbp->sb_logblocks > 0)) {	/* check for volume case */
-		error = xfs_log_mount(mp, mp->m_logdev_targp,
-				      XFS_FSB_TO_DADDR(mp, sbp->sb_logstart),
-				      XFS_FSB_TO_BB(mp, sbp->sb_logblocks));
-		if (error) {
-			cmn_err(CE_WARN, "XFS: log mount failed");
-			goto error2;
-		}
-	} else {	/* No log has been defined */
-		cmn_err(CE_WARN, "XFS: no log defined");
-		XFS_ERROR_REPORT("xfs_mountfs_int(1)", XFS_ERRLEVEL_LOW, mp);
-		error = XFS_ERROR(EFSCORRUPTED);
-		goto error2;
+	error = xfs_log_mount(mp, mp->m_logdev_targp,
+			      XFS_FSB_TO_DADDR(mp, sbp->sb_logstart),
+			      XFS_FSB_TO_BB(mp, sbp->sb_logblocks));
+	if (error) {
+		cmn_err(CE_WARN, "XFS: log mount failed");
+		goto out_free_perag;
 	}
 
 	/*
@@ -1086,15 +1144,14 @@
 	 * If we are currently making the filesystem, the initialisation will
 	 * fail as the perag data is in an undefined state.
 	 */
-
 	if (xfs_sb_version_haslazysbcount(&mp->m_sb) &&
 	    !XFS_LAST_UNMOUNT_WAS_CLEAN(mp) &&
 	     !mp->m_sb.sb_inprogress) {
 		error = xfs_initialize_perag_data(mp, sbp->sb_agcount);
-		if (error) {
-			goto error2;
-		}
+		if (error)
+			goto out_free_perag;
 	}
+
 	/*
 	 * Get and sanity-check the root inode.
 	 * Save the pointer to it in the mount structure.
@@ -1102,7 +1159,7 @@
 	error = xfs_iget(mp, NULL, sbp->sb_rootino, 0, XFS_ILOCK_EXCL, &rip, 0);
 	if (error) {
 		cmn_err(CE_WARN, "XFS: failed to read root inode");
-		goto error3;
+		goto out_log_dealloc;
 	}
 
 	ASSERT(rip != NULL);
@@ -1116,7 +1173,7 @@
 		XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW,
 				 mp);
 		error = XFS_ERROR(EFSCORRUPTED);
-		goto error4;
+		goto out_rele_rip;
 	}
 	mp->m_rootip = rip;	/* save it */
 
@@ -1131,7 +1188,7 @@
 		 * Free up the root inode.
 		 */
 		cmn_err(CE_WARN, "XFS: failed to read RT inodes");
-		goto error4;
+		goto out_rele_rip;
 	}
 
 	/*
@@ -1143,7 +1200,7 @@
 		error = xfs_mount_log_sb(mp, mp->m_update_flags);
 		if (error) {
 			cmn_err(CE_WARN, "XFS: failed to write sb changes");
-			goto error4;
+			goto out_rtunmount;
 		}
 	}
 
@@ -1152,7 +1209,7 @@
 	 */
 	error = XFS_QM_INIT(mp, &quotamount, &quotaflags);
 	if (error)
-		goto error4;
+		goto out_rtunmount;
 
 	/*
 	 * Finish recovering the file system.  This part needed to be
@@ -1162,7 +1219,7 @@
 	error = xfs_log_mount_finish(mp);
 	if (error) {
 		cmn_err(CE_WARN, "XFS: log mount finish failed");
-		goto error4;
+		goto out_rtunmount;
 	}
 
 	/*
@@ -1170,7 +1227,7 @@
 	 */
 	error = XFS_QM_MOUNT(mp, quotamount, quotaflags);
 	if (error)
-		goto error4;
+		goto out_rtunmount;
 
 	/*
 	 * Now we are mounted, reserve a small amount of unused space for
@@ -1194,18 +1251,17 @@
 
 	return 0;
 
- error4:
-	/*
-	 * Free up the root inode.
-	 */
+ out_rtunmount:
+	xfs_rtunmount_inodes(mp);
+ out_rele_rip:
 	IRELE(rip);
- error3:
-	xfs_log_unmount_dealloc(mp);
- error2:
+ out_log_dealloc:
+	xfs_log_unmount(mp);
+ out_free_perag:
 	xfs_free_perag(mp);
- error1:
-	if (uuid_mounted)
-		uuid_table_remove(&mp->m_sb.sb_uuid);
+ out_remove_uuid:
+	xfs_uuid_unmount(mp);
+ out:
 	return error;
 }
 
@@ -1226,15 +1282,12 @@
 	 */
 	XFS_QM_UNMOUNT(mp);
 
-	if (mp->m_rbmip)
-		IRELE(mp->m_rbmip);
-	if (mp->m_rsumip)
-		IRELE(mp->m_rsumip);
+	xfs_rtunmount_inodes(mp);
 	IRELE(mp->m_rootip);
 
 	/*
 	 * We can potentially deadlock here if we have an inode cluster
-	 * that has been freed has it's buffer still pinned in memory because
+	 * that has been freed has its buffer still pinned in memory because
 	 * the transaction is still sitting in a iclog. The stale inodes
 	 * on that buffer will have their flush locks held until the
 	 * transaction hits the disk and the callbacks run. the inode
@@ -1266,7 +1319,7 @@
 	 * Unreserve any blocks we have so that when we unmount we don't account
 	 * the reserved free space as used. This is really only necessary for
 	 * lazy superblock counting because it trusts the incore superblock
-	 * counters to be aboslutely correct on clean unmount.
+	 * counters to be absolutely correct on clean unmount.
 	 *
 	 * We don't bother correcting this elsewhere for lazy superblock
 	 * counting because on mount of an unclean filesystem we reconstruct the
@@ -1288,10 +1341,9 @@
 				"Freespace may not be correct on next mount.");
 	xfs_unmountfs_writesb(mp);
 	xfs_unmountfs_wait(mp); 		/* wait for async bufs */
-	xfs_log_unmount(mp);			/* Done! No more fs ops. */
-
-	if ((mp->m_flags & XFS_MOUNT_NOUUID) == 0)
-		uuid_table_remove(&mp->m_sb.sb_uuid);
+	xfs_log_unmount_write(mp);
+	xfs_log_unmount(mp);
+	xfs_uuid_unmount(mp);
 
 #if defined(DEBUG)
 	xfs_errortag_clearall(mp, 0);
@@ -1793,29 +1845,6 @@
 }
 
 /*
- * See if the UUID is unique among mounted XFS filesystems.
- * Mount fails if UUID is nil or a FS with the same UUID is already mounted.
- */
-STATIC int
-xfs_uuid_mount(
-	xfs_mount_t	*mp)
-{
-	if (uuid_is_nil(&mp->m_sb.sb_uuid)) {
-		cmn_err(CE_WARN,
-			"XFS: Filesystem %s has nil UUID - can't mount",
-			mp->m_fsname);
-		return -1;
-	}
-	if (!uuid_table_insert(&mp->m_sb.sb_uuid)) {
-		cmn_err(CE_WARN,
-			"XFS: Filesystem %s has duplicate UUID - can't mount",
-			mp->m_fsname);
-		return -1;
-	}
-	return 0;
-}
-
-/*
  * Used to log changes to the superblock unit and width fields which could
  * be altered by the mount options, as well as any potential sb_features2
  * fixup. Only the first superblock is updated.
@@ -1868,7 +1897,7 @@
  * we disable the per-cpu counter and go through the slow path.
  *
  * The slow path is the current xfs_mod_incore_sb() function.  This means that
- * when we disable a per-cpu counter, we need to drain it's resources back to
+ * when we disable a per-cpu counter, we need to drain its resources back to
  * the global superblock. We do this after disabling the counter to prevent
  * more threads from queueing up on the counter.
  *
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index f5e9937..7af44ad 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -136,7 +136,6 @@
 			struct xfs_dquot *, struct xfs_dquot *, uint);
 typedef void	(*xfs_dqstatvfs_t)(struct xfs_inode *, struct kstatfs *);
 typedef int	(*xfs_dqsync_t)(struct xfs_mount *, int flags);
-typedef int	(*xfs_quotactl_t)(struct xfs_mount *, int, int, xfs_caddr_t);
 
 typedef struct xfs_qmops {
 	xfs_qminit_t		xfs_qminit;
@@ -154,7 +153,6 @@
 	xfs_dqvopchownresv_t	xfs_dqvopchownresv;
 	xfs_dqstatvfs_t		xfs_dqstatvfs;
 	xfs_dqsync_t		xfs_dqsync;
-	xfs_quotactl_t		xfs_quotactl;
 	struct xfs_dqtrxops	*xfs_dqtrxops;
 } xfs_qmops_t;
 
@@ -188,8 +186,6 @@
 	(*(ip)->i_mount->m_qm_ops->xfs_dqstatvfs)(ip, statp)
 #define XFS_QM_DQSYNC(mp, flags) \
 	(*(mp)->m_qm_ops->xfs_dqsync)(mp, flags)
-#define XFS_QM_QUOTACTL(mp, cmd, id, addr) \
-	(*(mp)->m_qm_ops->xfs_quotactl)(mp, cmd, id, addr)
 
 #ifdef HAVE_PERCPU_SB
 
@@ -273,19 +269,17 @@
 	uint			m_inobt_mnr[2];	/* min inobt btree records */
 	uint			m_ag_maxlevels;	/* XFS_AG_MAXLEVELS */
 	uint			m_bm_maxlevels[2]; /* XFS_BM_MAXLEVELS */
-	uint			m_in_maxlevels;	/* XFS_IN_MAXLEVELS */
+	uint			m_in_maxlevels;	/* max inobt btree levels. */
 	struct xfs_perag	*m_perag;	/* per-ag accounting info */
 	struct rw_semaphore	m_peraglock;	/* lock for m_perag (pointer) */
 	struct mutex		m_growlock;	/* growfs mutex */
 	int			m_fixedfsid[2];	/* unchanged for life of FS */
 	uint			m_dmevmask;	/* DMI events for this FS */
 	__uint64_t		m_flags;	/* global mount flags */
-	uint			m_attroffset;	/* inode attribute offset */
 	uint			m_dir_node_ents; /* #entries in a dir danode */
 	uint			m_attr_node_ents; /* #entries in attr danode */
 	int			m_ialloc_inos;	/* inodes in inode allocation */
 	int			m_ialloc_blks;	/* blocks in inode allocation */
-	int			m_litino;	/* size of inode union area */
 	int			m_inoalign_mask;/* mask sb_inoalignmt if used */
 	uint			m_qflags;	/* quota status flags */
 	xfs_trans_reservations_t m_reservations;/* precomputed res values */
@@ -293,9 +287,6 @@
 	__uint64_t		m_maxioffset;	/* maximum inode offset */
 	__uint64_t		m_resblks;	/* total reserved blocks */
 	__uint64_t		m_resblks_avail;/* available reserved blocks */
-#if XFS_BIG_INUMS
-	xfs_ino_t		m_inoadd;	/* add value for ino64_offset */
-#endif
 	int			m_dalign;	/* stripe unit */
 	int			m_swidth;	/* stripe width */
 	int			m_sinoalign;	/* stripe unit inode alignment */
@@ -337,7 +328,6 @@
 #define XFS_MOUNT_WSYNC		(1ULL << 0)	/* for nfs - all metadata ops
 						   must be synchronous except
 						   for space allocations */
-#define XFS_MOUNT_INO64		(1ULL << 1)
 #define XFS_MOUNT_DMAPI		(1ULL << 2)	/* dmapi is enabled */
 #define XFS_MOUNT_WAS_CLEAN	(1ULL << 3)
 #define XFS_MOUNT_FS_SHUTDOWN	(1ULL << 4)	/* atomic stop of all filesystem
@@ -389,8 +379,8 @@
  * Synchronous read and write sizes.  This should be
  * better for NFSv2 wsync filesystems.
  */
-#define	XFS_WSYNC_READIO_LOG	15	/* 32K */
-#define	XFS_WSYNC_WRITEIO_LOG	14	/* 16K */
+#define	XFS_WSYNC_READIO_LOG	15	/* 32k */
+#define	XFS_WSYNC_WRITEIO_LOG	14	/* 16k */
 
 /*
  * Allow large block sizes to be reported to userspace programs if the
@@ -500,9 +490,6 @@
 	int64_t		msb_delta;	/* Change to make to specified field */
 } xfs_mod_sb_t;
 
-#define	XFS_MOUNT_ILOCK(mp)	mutex_lock(&((mp)->m_ilock))
-#define	XFS_MOUNT_IUNLOCK(mp)	mutex_unlock(&((mp)->m_ilock))
-
 extern int	xfs_log_sbcount(xfs_mount_t *, uint);
 extern int	xfs_mountfs(xfs_mount_t *mp);
 extern void	xfs_mountfs_check_barriers(xfs_mount_t *mp);
diff --git a/fs/xfs/xfs_qmops.c b/fs/xfs/xfs_qmops.c
index 27f8058..e101790 100644
--- a/fs/xfs/xfs_qmops.c
+++ b/fs/xfs/xfs_qmops.c
@@ -126,7 +126,6 @@
 	.xfs_dqvopchownresv	= (xfs_dqvopchownresv_t) fs_noerr,
 	.xfs_dqstatvfs		= (xfs_dqstatvfs_t) fs_noval,
 	.xfs_dqsync		= (xfs_dqsync_t) fs_noerr,
-	.xfs_quotactl		= (xfs_quotactl_t) fs_nosys,
 };
 
 int
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
index 48965ec..f5d1202 100644
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -18,6 +18,8 @@
 #ifndef __XFS_QUOTA_H__
 #define __XFS_QUOTA_H__
 
+struct xfs_trans;
+
 /*
  * The ondisk form of a dquot structure.
  */
@@ -185,7 +187,6 @@
  * to a single function. None of these XFS_QMOPT_* flags are meant to have
  * persistent values (ie. their values can and will change between versions)
  */
-#define XFS_QMOPT_DQLOCK	0x0000001 /* dqlock */
 #define XFS_QMOPT_DQALLOC	0x0000002 /* alloc dquot ondisk if needed */
 #define XFS_QMOPT_UQUOTA	0x0000004 /* user dquot requested */
 #define XFS_QMOPT_PQUOTA	0x0000008 /* project dquot requested */
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index c5bb86f..385f6dc 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -2288,6 +2288,16 @@
 	return 0;
 }
 
+void
+xfs_rtunmount_inodes(
+	struct xfs_mount	*mp)
+{
+	if (mp->m_rbmip)
+		IRELE(mp->m_rbmip);
+	if (mp->m_rsumip)
+		IRELE(mp->m_rsumip);
+}
+
 /*
  * Pick an extent for allocation at the start of a new realtime file.
  * Use the sequence number stored in the atime field of the bitmap inode.
diff --git a/fs/xfs/xfs_rtalloc.h b/fs/xfs/xfs_rtalloc.h
index 8d8dcd2..b2d67ad 100644
--- a/fs/xfs/xfs_rtalloc.h
+++ b/fs/xfs/xfs_rtalloc.h
@@ -23,8 +23,8 @@
 
 /* Min and max rt extent sizes, specified in bytes */
 #define	XFS_MAX_RTEXTSIZE	(1024 * 1024 * 1024)	/* 1GB */
-#define	XFS_DFL_RTEXTSIZE	(64 * 1024)	        /* 64KB */
-#define	XFS_MIN_RTEXTSIZE	(4 * 1024)		/* 4KB */
+#define	XFS_DFL_RTEXTSIZE	(64 * 1024)	        /* 64kB */
+#define	XFS_MIN_RTEXTSIZE	(4 * 1024)		/* 4kB */
 
 /*
  * Constants for bit manipulations.
@@ -108,6 +108,9 @@
 int					/* error */
 xfs_rtmount_init(
 	struct xfs_mount	*mp);	/* file system mount structure */
+void
+xfs_rtunmount_inodes(
+	struct xfs_mount	*mp);
 
 /*
  * Get the bitmap and summary inodes into the mount structure
@@ -146,6 +149,7 @@
 # define xfs_growfs_rt(mp,in)                           (ENOSYS)
 # define xfs_rtmount_init(m)    (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS))
 # define xfs_rtmount_inodes(m)  (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS))
+# define xfs_rtunmount_inodes(m)
 #endif	/* CONFIG_XFS_RT */
 
 #endif	/* __KERNEL__ */
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index d6fe4a8..775249a 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -292,7 +292,7 @@
  * In a write transaction we can allocate a maximum of 2
  * extents.  This gives:
  *    the inode getting the new extents: inode size
- *    the inode\'s bmap btree: max depth * block size
+ *    the inode's bmap btree: max depth * block size
  *    the agfs of the ags from which the extents are allocated: 2 * sector
  *    the superblock free block counter: sector size
  *    the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size
@@ -321,7 +321,7 @@
 /*
  * In truncating a file we free up to two extents at once.  We can modify:
  *    the inode being truncated: inode size
- *    the inode\'s bmap btree: (max depth + 1) * block size
+ *    the inode's bmap btree: (max depth + 1) * block size
  * And the bmap_finish transaction can free the blocks and bmap blocks:
  *    the agf for each of the ags: 4 * sector size
  *    the agfl for each of the ags: 4 * sector size
@@ -343,7 +343,7 @@
 	  (128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4))) + \
 	  (128 * 5) + \
 	  XFS_ALLOCFREE_LOG_RES(mp, 1) + \
-	   (128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \
+	   (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \
 	    XFS_ALLOCFREE_LOG_COUNT(mp, 1))))))
 
 #define	XFS_ITRUNCATE_LOG_RES(mp)   ((mp)->m_reservations.tr_itruncate)
@@ -431,8 +431,8 @@
  *    the new inode: inode size
  *    the inode btree entry: 1 block
  *    the directory btree: (max depth + v2) * dir block size
- *    the directory inode\'s bmap btree: (max depth + v2) * block size
- *    the blocks for the symlink: 1 KB
+ *    the directory inode's bmap btree: (max depth + v2) * block size
+ *    the blocks for the symlink: 1 kB
  * Or in the first xact we allocate some inodes giving:
  *    the agi and agf of the ag getting the new inodes: 2 * sectorsize
  *    the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize
@@ -449,9 +449,9 @@
 	  (128 * (4 + XFS_DIROP_LOG_COUNT(mp)))), \
 	 (2 * (mp)->m_sb.sb_sectsize + \
 	  XFS_FSB_TO_B((mp), XFS_IALLOC_BLOCKS((mp))) + \
-	  XFS_FSB_TO_B((mp), XFS_IN_MAXLEVELS(mp)) + \
+	  XFS_FSB_TO_B((mp), (mp)->m_in_maxlevels) + \
 	  XFS_ALLOCFREE_LOG_RES(mp, 1) + \
-	  (128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \
+	  (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \
 	   XFS_ALLOCFREE_LOG_COUNT(mp, 1))))))
 
 #define	XFS_SYMLINK_LOG_RES(mp)	((mp)->m_reservations.tr_symlink)
@@ -463,7 +463,7 @@
  *    the inode btree entry: block size
  *    the superblock for the nlink flag: sector size
  *    the directory btree: (max depth + v2) * dir block size
- *    the directory inode\'s bmap btree: (max depth + v2) * block size
+ *    the directory inode's bmap btree: (max depth + v2) * block size
  * Or in the first xact we allocate some inodes giving:
  *    the agi and agf of the ag getting the new inodes: 2 * sectorsize
  *    the superblock for the nlink flag: sector size
@@ -481,9 +481,9 @@
 	  (128 * (3 + XFS_DIROP_LOG_COUNT(mp)))), \
 	 (3 * (mp)->m_sb.sb_sectsize + \
 	  XFS_FSB_TO_B((mp), XFS_IALLOC_BLOCKS((mp))) + \
-	  XFS_FSB_TO_B((mp), XFS_IN_MAXLEVELS(mp)) + \
+	  XFS_FSB_TO_B((mp), (mp)->m_in_maxlevels) + \
 	  XFS_ALLOCFREE_LOG_RES(mp, 1) + \
-	  (128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \
+	  (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \
 	   XFS_ALLOCFREE_LOG_COUNT(mp, 1))))))
 
 #define	XFS_CREATE_LOG_RES(mp)	((mp)->m_reservations.tr_create)
@@ -513,7 +513,7 @@
 	 MAX((__uint16_t)XFS_FSB_TO_B((mp), 1), XFS_INODE_CLUSTER_SIZE(mp)) + \
 	 (128 * 5) + \
 	  XFS_ALLOCFREE_LOG_RES(mp, 1) + \
-	  (128 * (2 + XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp) + \
+	  (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \
 	   XFS_ALLOCFREE_LOG_COUNT(mp, 1))))
 
 
@@ -637,7 +637,7 @@
 /*
  * Removing the attribute fork of a file
  *    the inode being truncated: inode size
- *    the inode\'s bmap btree: max depth * block size
+ *    the inode's bmap btree: max depth * block size
  * And the bmap_finish transaction can free the blocks and bmap blocks:
  *    the agf for each of the ags: 4 * sector size
  *    the agfl for each of the ags: 4 * sector size
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index 2d47f10..f31271c 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -79,7 +79,7 @@
  * the push is run asynchronously in a separate thread, so we return the tail
  * of the log right now instead of the tail after the push. This means we will
  * either continue right away, or we will sleep waiting on the async thread to
- * do it's work.
+ * do its work.
  *
  * We do this unlocked - we only need to know whether there is anything in the
  * AIL at the time we are called. We don't need to access the contents of
@@ -160,7 +160,7 @@
 /*
  * Now that the traversal is complete, we need to remove the cursor
  * from the list of traversing cursors. Avoid removing the embedded
- * push cursor, but use the fact it is alway present to make the
+ * push cursor, but use the fact it is always present to make the
  * list deletion simple.
  */
 void
diff --git a/fs/xfs/xfs_trans_item.c b/fs/xfs/xfs_trans_item.c
index e110bf5..eb3fc57 100644
--- a/fs/xfs/xfs_trans_item.c
+++ b/fs/xfs/xfs_trans_item.c
@@ -22,7 +22,7 @@
 #include "xfs_inum.h"
 #include "xfs_trans.h"
 #include "xfs_trans_priv.h"
-/* XXX: from here down needed until struct xfs_trans has it's own ailp */
+/* XXX: from here down needed until struct xfs_trans has its own ailp */
 #include "xfs_bit.h"
 #include "xfs_buf_item.h"
 #include "xfs_sb.h"
diff --git a/fs/xfs/xfs_trans_space.h b/fs/xfs/xfs_trans_space.h
index 4ea2e50..7d2c920 100644
--- a/fs/xfs/xfs_trans_space.h
+++ b/fs/xfs/xfs_trans_space.h
@@ -47,7 +47,7 @@
 #define	XFS_DIRREMOVE_SPACE_RES(mp)	\
 	XFS_DAREMOVE_SPACE_RES(mp, XFS_DATA_FORK)
 #define	XFS_IALLOC_SPACE_RES(mp)	\
-	(XFS_IALLOC_BLOCKS(mp) + XFS_IN_MAXLEVELS(mp)-1)
+	(XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels - 1)
 
 /*
  * Space reservation values for various transactions.
diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h
index b2f7245..d725428 100644
--- a/fs/xfs/xfs_types.h
+++ b/fs/xfs/xfs_types.h
@@ -21,14 +21,6 @@
 #ifdef __KERNEL__
 
 /*
- * POSIX Extensions
- */
-typedef unsigned char		uchar_t;
-typedef unsigned short		ushort_t;
-typedef unsigned int		uint_t;
-typedef unsigned long		ulong_t;
-
-/*
  * Additional type declarations for XFS
  */
 typedef signed char		__int8_t;
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
index fcc2285..79b9e5e 100644
--- a/fs/xfs/xfs_utils.c
+++ b/fs/xfs/xfs_utils.c
@@ -374,7 +374,7 @@
 
 	/*
 	 * Follow the normal truncate locking protocol.  Since we
-	 * hold the inode in the transaction, we know that it's number
+	 * hold the inode in the transaction, we know that its number
 	 * of references will stay constant.
 	 */
 	xfs_ilock(ip, XFS_ILOCK_EXCL);
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 0e55c5d..7394c7a 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -1136,7 +1136,7 @@
 	 * If the inode is already free, then there can be nothing
 	 * to clean up here.
 	 */
-	if (ip->i_d.di_mode == 0 || VN_BAD(VFS_I(ip))) {
+	if (ip->i_d.di_mode == 0 || is_bad_inode(VFS_I(ip))) {
 		ASSERT(ip->i_df.if_real_bytes == 0);
 		ASSERT(ip->i_df.if_broot_bytes == 0);
 		return VN_INACTIVE_CACHE;
@@ -1387,23 +1387,28 @@
 	xfs_inode_t		**ipp,
 	cred_t			*credp)
 {
-	xfs_mount_t		*mp = dp->i_mount;
-	xfs_inode_t		*ip;
-	xfs_trans_t		*tp;
+	int			is_dir = S_ISDIR(mode);
+	struct xfs_mount	*mp = dp->i_mount;
+	struct xfs_inode	*ip = NULL;
+	struct xfs_trans	*tp = NULL;
 	int			error;
 	xfs_bmap_free_t		free_list;
 	xfs_fsblock_t		first_block;
 	boolean_t		unlock_dp_on_error = B_FALSE;
-	int			dm_event_sent = 0;
 	uint			cancel_flags;
 	int			committed;
 	xfs_prid_t		prid;
-	struct xfs_dquot	*udqp, *gdqp;
+	struct xfs_dquot	*udqp = NULL;
+	struct xfs_dquot	*gdqp = NULL;
 	uint			resblks;
+	uint			log_res;
+	uint			log_count;
 
-	ASSERT(!*ipp);
 	xfs_itrace_entry(dp);
 
+	if (XFS_FORCED_SHUTDOWN(mp))
+		return XFS_ERROR(EIO);
+
 	if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) {
 		error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE,
 				dp, DM_RIGHT_NULL, NULL,
@@ -1412,84 +1417,97 @@
 
 		if (error)
 			return error;
-		dm_event_sent = 1;
 	}
 
-	if (XFS_FORCED_SHUTDOWN(mp))
-		return XFS_ERROR(EIO);
-
-	/* Return through std_return after this point. */
-
-	udqp = gdqp = NULL;
 	if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
 		prid = dp->i_d.di_projid;
 	else
-		prid = (xfs_prid_t)dfltprid;
+		prid = dfltprid;
 
 	/*
 	 * Make sure that we have allocated dquot(s) on disk.
 	 */
 	error = XFS_QM_DQVOPALLOC(mp, dp,
 			current_fsuid(), current_fsgid(), prid,
-			XFS_QMOPT_QUOTALL|XFS_QMOPT_INHERIT, &udqp, &gdqp);
+			XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
 	if (error)
 		goto std_return;
 
-	ip = NULL;
+	if (is_dir) {
+		rdev = 0;
+		resblks = XFS_MKDIR_SPACE_RES(mp, name->len);
+		log_res = XFS_MKDIR_LOG_RES(mp);
+		log_count = XFS_MKDIR_LOG_COUNT;
+		tp = xfs_trans_alloc(mp, XFS_TRANS_MKDIR);
+	} else {
+		resblks = XFS_CREATE_SPACE_RES(mp, name->len);
+		log_res = XFS_CREATE_LOG_RES(mp);
+		log_count = XFS_CREATE_LOG_COUNT;
+		tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE);
+	}
 
-	tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE);
 	cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
-	resblks = XFS_CREATE_SPACE_RES(mp, name->len);
+
 	/*
 	 * Initially assume that the file does not exist and
 	 * reserve the resources for that case.  If that is not
 	 * the case we'll drop the one we have and get a more
 	 * appropriate transaction later.
 	 */
-	error = xfs_trans_reserve(tp, resblks, XFS_CREATE_LOG_RES(mp), 0,
-			XFS_TRANS_PERM_LOG_RES, XFS_CREATE_LOG_COUNT);
+	error = xfs_trans_reserve(tp, resblks, log_res, 0,
+			XFS_TRANS_PERM_LOG_RES, log_count);
 	if (error == ENOSPC) {
 		resblks = 0;
-		error = xfs_trans_reserve(tp, 0, XFS_CREATE_LOG_RES(mp), 0,
-				XFS_TRANS_PERM_LOG_RES, XFS_CREATE_LOG_COUNT);
+		error = xfs_trans_reserve(tp, 0, log_res, 0,
+				XFS_TRANS_PERM_LOG_RES, log_count);
 	}
 	if (error) {
 		cancel_flags = 0;
-		goto error_return;
+		goto out_trans_cancel;
 	}
 
 	xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
 	unlock_dp_on_error = B_TRUE;
 
-	xfs_bmap_init(&free_list, &first_block);
+	/*
+	 * Check for directory link count overflow.
+	 */
+	if (is_dir && dp->i_d.di_nlink >= XFS_MAXLINK) {
+		error = XFS_ERROR(EMLINK);
+		goto out_trans_cancel;
+	}
 
-	ASSERT(ip == NULL);
+	xfs_bmap_init(&free_list, &first_block);
 
 	/*
 	 * Reserve disk quota and the inode.
 	 */
 	error = XFS_TRANS_RESERVE_QUOTA(mp, tp, udqp, gdqp, resblks, 1, 0);
 	if (error)
-		goto error_return;
+		goto out_trans_cancel;
 
 	error = xfs_dir_canenter(tp, dp, name, resblks);
 	if (error)
-		goto error_return;
-	error = xfs_dir_ialloc(&tp, dp, mode, 1,
-			rdev, credp, prid, resblks > 0,
-			&ip, &committed);
+		goto out_trans_cancel;
+
+	/*
+	 * A newly created regular or special file just has one directory
+	 * entry pointing to them, but a directory also the "." entry
+	 * pointing to itself.
+	 */
+	error = xfs_dir_ialloc(&tp, dp, mode, is_dir ? 2 : 1, rdev, credp,
+			       prid, resblks > 0, &ip, &committed);
 	if (error) {
 		if (error == ENOSPC)
-			goto error_return;
-		goto abort_return;
+			goto out_trans_cancel;
+		goto out_trans_abort;
 	}
-	xfs_itrace_ref(ip);
 
 	/*
 	 * At this point, we've gotten a newly allocated inode.
 	 * It is locked (and joined to the transaction).
 	 */
-
+	xfs_itrace_ref(ip);
 	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
 
 	/*
@@ -1508,19 +1526,28 @@
 					resblks - XFS_IALLOC_SPACE_RES(mp) : 0);
 	if (error) {
 		ASSERT(error != ENOSPC);
-		goto abort_return;
+		goto out_trans_abort;
 	}
 	xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
 	xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
 
+	if (is_dir) {
+		error = xfs_dir_init(tp, ip, dp);
+		if (error)
+			goto out_bmap_cancel;
+
+		error = xfs_bumplink(tp, dp);
+		if (error)
+			goto out_bmap_cancel;
+	}
+
 	/*
 	 * If this is a synchronous mount, make sure that the
 	 * create transaction goes to disk before returning to
 	 * the user.
 	 */
-	if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) {
+	if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC))
 		xfs_trans_set_sync(tp);
-	}
 
 	/*
 	 * Attach the dquot(s) to the inodes and modify them incore.
@@ -1537,16 +1564,13 @@
 	IHOLD(ip);
 
 	error = xfs_bmap_finish(&tp, &free_list, &committed);
-	if (error) {
-		xfs_bmap_cancel(&free_list);
-		goto abort_rele;
-	}
+	if (error)
+		goto out_abort_rele;
 
 	error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
 	if (error) {
 		IRELE(ip);
-		tp = NULL;
-		goto error_return;
+		goto out_dqrele;
 	}
 
 	XFS_QM_DQRELE(mp, udqp);
@@ -1555,26 +1579,22 @@
 	*ipp = ip;
 
 	/* Fallthrough to std_return with error = 0  */
-
-std_return:
-	if ((*ipp || (error != 0 && dm_event_sent != 0)) &&
-	    DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) {
-		(void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE,
-			dp, DM_RIGHT_NULL,
-			*ipp ? ip : NULL,
-			DM_RIGHT_NULL, name->name, NULL,
-			mode, error, 0);
+ std_return:
+	if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) {
+		XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, dp, DM_RIGHT_NULL,
+				ip, DM_RIGHT_NULL, name->name, NULL, mode,
+				error, 0);
 	}
+
 	return error;
 
- abort_return:
+ out_bmap_cancel:
+	xfs_bmap_cancel(&free_list);
+ out_trans_abort:
 	cancel_flags |= XFS_TRANS_ABORT;
-	/* FALLTHROUGH */
-
- error_return:
-	if (tp != NULL)
-		xfs_trans_cancel(tp, cancel_flags);
-
+ out_trans_cancel:
+	xfs_trans_cancel(tp, cancel_flags);
+ out_dqrele:
 	XFS_QM_DQRELE(mp, udqp);
 	XFS_QM_DQRELE(mp, gdqp);
 
@@ -1583,20 +1603,18 @@
 
 	goto std_return;
 
- abort_rele:
+ out_abort_rele:
 	/*
 	 * Wait until after the current transaction is aborted to
 	 * release the inode.  This prevents recursive transactions
 	 * and deadlocks from xfs_inactive.
 	 */
+	xfs_bmap_cancel(&free_list);
 	cancel_flags |= XFS_TRANS_ABORT;
 	xfs_trans_cancel(tp, cancel_flags);
 	IRELE(ip);
-
-	XFS_QM_DQRELE(mp, udqp);
-	XFS_QM_DQRELE(mp, gdqp);
-
-	goto std_return;
+	unlock_dp_on_error = B_FALSE;
+	goto out_dqrele;
 }
 
 #ifdef DEBUG
@@ -2004,8 +2022,10 @@
 	/* Return through std_return after this point. */
 
 	error = XFS_QM_DQATTACH(mp, sip, 0);
-	if (!error && sip != tdp)
-		error = XFS_QM_DQATTACH(mp, tdp, 0);
+	if (error)
+		goto std_return;
+
+	error = XFS_QM_DQATTACH(mp, tdp, 0);
 	if (error)
 		goto std_return;
 
@@ -2110,209 +2130,6 @@
 	goto std_return;
 }
 
-
-int
-xfs_mkdir(
-	xfs_inode_t             *dp,
-	struct xfs_name		*dir_name,
-	mode_t			mode,
-	xfs_inode_t		**ipp,
-	cred_t			*credp)
-{
-	xfs_mount_t		*mp = dp->i_mount;
-	xfs_inode_t		*cdp;	/* inode of created dir */
-	xfs_trans_t		*tp;
-	int			cancel_flags;
-	int			error;
-	int			committed;
-	xfs_bmap_free_t         free_list;
-	xfs_fsblock_t           first_block;
-	boolean_t		unlock_dp_on_error = B_FALSE;
-	boolean_t		created = B_FALSE;
-	int			dm_event_sent = 0;
-	xfs_prid_t		prid;
-	struct xfs_dquot	*udqp, *gdqp;
-	uint			resblks;
-
-	if (XFS_FORCED_SHUTDOWN(mp))
-		return XFS_ERROR(EIO);
-
-	tp = NULL;
-
-	if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) {
-		error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE,
-					dp, DM_RIGHT_NULL, NULL,
-					DM_RIGHT_NULL, dir_name->name, NULL,
-					mode, 0, 0);
-		if (error)
-			return error;
-		dm_event_sent = 1;
-	}
-
-	/* Return through std_return after this point. */
-
-	xfs_itrace_entry(dp);
-
-	mp = dp->i_mount;
-	udqp = gdqp = NULL;
-	if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
-		prid = dp->i_d.di_projid;
-	else
-		prid = (xfs_prid_t)dfltprid;
-
-	/*
-	 * Make sure that we have allocated dquot(s) on disk.
-	 */
-	error = XFS_QM_DQVOPALLOC(mp, dp,
-			current_fsuid(), current_fsgid(), prid,
-			XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
-	if (error)
-		goto std_return;
-
-	tp = xfs_trans_alloc(mp, XFS_TRANS_MKDIR);
-	cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
-	resblks = XFS_MKDIR_SPACE_RES(mp, dir_name->len);
-	error = xfs_trans_reserve(tp, resblks, XFS_MKDIR_LOG_RES(mp), 0,
-				  XFS_TRANS_PERM_LOG_RES, XFS_MKDIR_LOG_COUNT);
-	if (error == ENOSPC) {
-		resblks = 0;
-		error = xfs_trans_reserve(tp, 0, XFS_MKDIR_LOG_RES(mp), 0,
-					  XFS_TRANS_PERM_LOG_RES,
-					  XFS_MKDIR_LOG_COUNT);
-	}
-	if (error) {
-		cancel_flags = 0;
-		goto error_return;
-	}
-
-	xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
-	unlock_dp_on_error = B_TRUE;
-
-	/*
-	 * Check for directory link count overflow.
-	 */
-	if (dp->i_d.di_nlink >= XFS_MAXLINK) {
-		error = XFS_ERROR(EMLINK);
-		goto error_return;
-	}
-
-	/*
-	 * Reserve disk quota and the inode.
-	 */
-	error = XFS_TRANS_RESERVE_QUOTA(mp, tp, udqp, gdqp, resblks, 1, 0);
-	if (error)
-		goto error_return;
-
-	error = xfs_dir_canenter(tp, dp, dir_name, resblks);
-	if (error)
-		goto error_return;
-	/*
-	 * create the directory inode.
-	 */
-	error = xfs_dir_ialloc(&tp, dp, mode, 2,
-			0, credp, prid, resblks > 0,
-		&cdp, NULL);
-	if (error) {
-		if (error == ENOSPC)
-			goto error_return;
-		goto abort_return;
-	}
-	xfs_itrace_ref(cdp);
-
-	/*
-	 * Now we add the directory inode to the transaction.
-	 * We waited until now since xfs_dir_ialloc might start
-	 * a new transaction.  Had we joined the transaction
-	 * earlier, the locks might have gotten released. An error
-	 * from here on will result in the transaction cancel
-	 * unlocking dp so don't do it explicitly in the error path.
-	 */
-	IHOLD(dp);
-	xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
-	unlock_dp_on_error = B_FALSE;
-
-	xfs_bmap_init(&free_list, &first_block);
-
-	error = xfs_dir_createname(tp, dp, dir_name, cdp->i_ino,
-					&first_block, &free_list, resblks ?
-					resblks - XFS_IALLOC_SPACE_RES(mp) : 0);
-	if (error) {
-		ASSERT(error != ENOSPC);
-		goto error1;
-	}
-	xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
-
-	error = xfs_dir_init(tp, cdp, dp);
-	if (error)
-		goto error2;
-
-	error = xfs_bumplink(tp, dp);
-	if (error)
-		goto error2;
-
-	created = B_TRUE;
-
-	*ipp = cdp;
-	IHOLD(cdp);
-
-	/*
-	 * Attach the dquots to the new inode and modify the icount incore.
-	 */
-	XFS_QM_DQVOPCREATE(mp, tp, cdp, udqp, gdqp);
-
-	/*
-	 * If this is a synchronous mount, make sure that the
-	 * mkdir transaction goes to disk before returning to
-	 * the user.
-	 */
-	if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) {
-		xfs_trans_set_sync(tp);
-	}
-
-	error = xfs_bmap_finish(&tp, &free_list, &committed);
-	if (error) {
-		IRELE(cdp);
-		goto error2;
-	}
-
-	error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
-	XFS_QM_DQRELE(mp, udqp);
-	XFS_QM_DQRELE(mp, gdqp);
-	if (error) {
-		IRELE(cdp);
-	}
-
-	/* Fall through to std_return with error = 0 or errno from
-	 * xfs_trans_commit. */
-
-std_return:
-	if ((created || (error != 0 && dm_event_sent != 0)) &&
-	    DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) {
-		(void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE,
-					dp, DM_RIGHT_NULL,
-					created ? cdp : NULL,
-					DM_RIGHT_NULL,
-					dir_name->name, NULL,
-					mode, error, 0);
-	}
-	return error;
-
- error2:
- error1:
-	xfs_bmap_cancel(&free_list);
- abort_return:
-	cancel_flags |= XFS_TRANS_ABORT;
- error_return:
-	xfs_trans_cancel(tp, cancel_flags);
-	XFS_QM_DQRELE(mp, udqp);
-	XFS_QM_DQRELE(mp, gdqp);
-
-	if (unlock_dp_on_error)
-		xfs_iunlock(dp, XFS_ILOCK_EXCL);
-
-	goto std_return;
-}
-
 int
 xfs_symlink(
 	xfs_inode_t		*dp,
@@ -2587,51 +2404,6 @@
 }
 
 int
-xfs_inode_flush(
-	xfs_inode_t	*ip,
-	int		flags)
-{
-	xfs_mount_t	*mp = ip->i_mount;
-	int		error = 0;
-
-	if (XFS_FORCED_SHUTDOWN(mp))
-		return XFS_ERROR(EIO);
-
-	/*
-	 * Bypass inodes which have already been cleaned by
-	 * the inode flush clustering code inside xfs_iflush
-	 */
-	if (xfs_inode_clean(ip))
-		return 0;
-
-	/*
-	 * We make this non-blocking if the inode is contended,
-	 * return EAGAIN to indicate to the caller that they
-	 * did not succeed. This prevents the flush path from
-	 * blocking on inodes inside another operation right
-	 * now, they get caught later by xfs_sync.
-	 */
-	if (flags & FLUSH_SYNC) {
-		xfs_ilock(ip, XFS_ILOCK_SHARED);
-		xfs_iflock(ip);
-	} else if (xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) {
-		if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip)) {
-			xfs_iunlock(ip, XFS_ILOCK_SHARED);
-			return EAGAIN;
-		}
-	} else {
-		return EAGAIN;
-	}
-
-	error = xfs_iflush(ip, (flags & FLUSH_SYNC) ? XFS_IFLUSH_SYNC
-						    : XFS_IFLUSH_ASYNC_NOBLOCK);
-	xfs_iunlock(ip, XFS_ILOCK_SHARED);
-
-	return error;
-}
-
-
-int
 xfs_set_dmattrs(
 	xfs_inode_t     *ip,
 	u_int		evmask,
@@ -2676,7 +2448,7 @@
 	ASSERT(!VN_MAPPED(VFS_I(ip)));
 
 	/* bad inode, get out here ASAP */
-	if (VN_BAD(VFS_I(ip))) {
+	if (is_bad_inode(VFS_I(ip))) {
 		xfs_ireclaim(ip);
 		return 0;
 	}
@@ -3090,7 +2862,7 @@
 
 	/*
 	 * Need to zero the stuff we're not freeing, on disk.
-	 * If its a realtime file & can't use unwritten extents then we
+	 * If it's a realtime file & can't use unwritten extents then we
 	 * actually need to zero the extent edges.  Otherwise xfs_bunmapi
 	 * will take care of it for us.
 	 */
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h
index 76df328..04373c6 100644
--- a/fs/xfs/xfs_vnodeops.h
+++ b/fs/xfs/xfs_vnodeops.h
@@ -31,14 +31,11 @@
 		struct xfs_inode *ip);
 int xfs_link(struct xfs_inode *tdp, struct xfs_inode *sip,
 		struct xfs_name *target_name);
-int xfs_mkdir(struct xfs_inode *dp, struct xfs_name *dir_name,
-		mode_t mode, struct xfs_inode **ipp, cred_t *credp);
 int xfs_readdir(struct xfs_inode	*dp, void *dirent, size_t bufsize,
 		       xfs_off_t *offset, filldir_t filldir);
 int xfs_symlink(struct xfs_inode *dp, struct xfs_name *link_name,
 		const char *target_path, mode_t mode, struct xfs_inode **ipp,
 		cred_t *credp);
-int xfs_inode_flush(struct xfs_inode *ip, int flags);
 int xfs_set_dmattrs(struct xfs_inode *ip, u_int evmask, u_int16_t state);
 int xfs_reclaim(struct xfs_inode *ip);
 int xfs_change_file_space(struct xfs_inode *ip, int cmd,
diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h
index eda0454..473d584 100644
--- a/include/acpi/acexcep.h
+++ b/include/acpi/acexcep.h
@@ -103,8 +103,9 @@
 #define AE_BAD_OCTAL_CONSTANT           (acpi_status) (0x0006 | AE_CODE_PROGRAMMER)
 #define AE_BAD_DECIMAL_CONSTANT         (acpi_status) (0x0007 | AE_CODE_PROGRAMMER)
 #define AE_MISSING_ARGUMENTS            (acpi_status) (0x0008 | AE_CODE_PROGRAMMER)
+#define AE_BAD_ADDRESS                  (acpi_status) (0x0009 | AE_CODE_PROGRAMMER)
 
-#define AE_CODE_PGM_MAX                 0x0008
+#define AE_CODE_PGM_MAX                 0x0009
 
 /*
  * Acpi table exceptions
@@ -224,7 +225,8 @@
 	"AE_BAD_HEX_CONSTANT",
 	"AE_BAD_OCTAL_CONSTANT",
 	"AE_BAD_DECIMAL_CONSTANT",
-	"AE_MISSING_ARGUMENTS"
+	"AE_MISSING_ARGUMENTS",
+	"AE_BAD_ADDRESS"
 };
 
 char const *acpi_gbl_exception_names_tbl[] = {
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index e9f6574..a222851 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -88,44 +88,30 @@
 
 typedef int (*acpi_op_add) (struct acpi_device * device);
 typedef int (*acpi_op_remove) (struct acpi_device * device, int type);
-typedef int (*acpi_op_lock) (struct acpi_device * device, int type);
 typedef int (*acpi_op_start) (struct acpi_device * device);
 typedef int (*acpi_op_stop) (struct acpi_device * device, int type);
 typedef int (*acpi_op_suspend) (struct acpi_device * device,
 				pm_message_t state);
 typedef int (*acpi_op_resume) (struct acpi_device * device);
-typedef int (*acpi_op_scan) (struct acpi_device * device);
 typedef int (*acpi_op_bind) (struct acpi_device * device);
 typedef int (*acpi_op_unbind) (struct acpi_device * device);
-typedef int (*acpi_op_shutdown) (struct acpi_device * device);
+typedef void (*acpi_op_notify) (struct acpi_device * device, u32 event);
 
 struct acpi_bus_ops {
 	u32 acpi_op_add:1;
-	u32 acpi_op_remove:1;
-	u32 acpi_op_lock:1;
 	u32 acpi_op_start:1;
-	u32 acpi_op_stop:1;
-	u32 acpi_op_suspend:1;
-	u32 acpi_op_resume:1;
-	u32 acpi_op_scan:1;
-	u32 acpi_op_bind:1;
-	u32 acpi_op_unbind:1;
-	u32 acpi_op_shutdown:1;
-	u32 reserved:21;
 };
 
 struct acpi_device_ops {
 	acpi_op_add add;
 	acpi_op_remove remove;
-	acpi_op_lock lock;
 	acpi_op_start start;
 	acpi_op_stop stop;
 	acpi_op_suspend suspend;
 	acpi_op_resume resume;
-	acpi_op_scan scan;
 	acpi_op_bind bind;
 	acpi_op_unbind unbind;
-	acpi_op_shutdown shutdown;
+	acpi_op_notify notify;
 };
 
 struct acpi_driver {
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
index 5fc1bb0..0352c8f 100644
--- a/include/acpi/acpi_drivers.h
+++ b/include/acpi/acpi_drivers.h
@@ -67,6 +67,16 @@
 #define ACPI_BAY_HID			"LNXIOBAY"
 #define ACPI_DOCK_HID			"LNXDOCK"
 
+/*
+ * For fixed hardware buttons, we fabricate acpi_devices with HID
+ * ACPI_BUTTON_HID_POWERF or ACPI_BUTTON_HID_SLEEPF.  Fixed hardware
+ * signals only an event; it doesn't supply a notification value.
+ * To allow drivers to treat notifications from fixed hardware the
+ * same as those from real devices, we turn the events into this
+ * notification value.
+ */
+#define ACPI_FIXED_HARDWARE_EVENT	0x100
+
 /* --------------------------------------------------------------------------
                                        PCI
    -------------------------------------------------------------------------- */
@@ -99,24 +109,6 @@
 				   int bus);
 
 /* --------------------------------------------------------------------------
-                                  Power Resource
-   -------------------------------------------------------------------------- */
-
-int acpi_device_sleep_wake(struct acpi_device *dev,
-                           int enable, int sleep_state, int dev_state);
-int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state);
-int acpi_disable_wakeup_device_power(struct acpi_device *dev);
-int acpi_power_get_inferred_state(struct acpi_device *device);
-int acpi_power_transition(struct acpi_device *device, int state);
-extern int acpi_power_nocheck;
-
-/* --------------------------------------------------------------------------
-                                  Embedded Controller
-   -------------------------------------------------------------------------- */
-int acpi_ec_ecdt_probe(void);
-int acpi_boot_ec_enable(void);
-
-/* --------------------------------------------------------------------------
                                     Processor
    -------------------------------------------------------------------------- */
 
@@ -165,9 +157,4 @@
 }
 #endif
 
-/*--------------------------------------------------------------------------
-                                  Suspend/Resume
-  -------------------------------------------------------------------------- */
-extern int acpi_sleep_init(void);
-
 #endif /*__ACPI_DRIVERS_H__*/
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
index ab0b85c..3e798593b 100644
--- a/include/acpi/acpiosxf.h
+++ b/include/acpi/acpiosxf.h
@@ -242,10 +242,6 @@
 acpi_status acpi_os_validate_interface(char *interface);
 acpi_status acpi_osi_invalidate(char* interface);
 
-acpi_status
-acpi_os_validate_address(u8 space_id, acpi_physical_address address,
-			 acpi_size length, char *name);
-
 u64 acpi_os_get_timer(void);
 
 acpi_status acpi_os_signal(u32 function, void *info);
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index cc40102..aeaf7cd 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -47,7 +47,7 @@
 
 /* Current ACPICA subsystem version in YYYYMMDD format */
 
-#define ACPI_CA_VERSION                 0x20081204
+#define ACPI_CA_VERSION                 0x20090320
 
 #include "actypes.h"
 #include "actbl.h"
@@ -349,17 +349,15 @@
  */
 acpi_status acpi_reset(void);
 
-acpi_status acpi_get_register(u32 register_id, u32 * return_value);
+acpi_status acpi_read_bit_register(u32 register_id, u32 *return_value);
 
-acpi_status acpi_get_register_unlocked(u32 register_id, u32 *return_value);
+acpi_status acpi_write_bit_register(u32 register_id, u32 value);
 
-acpi_status acpi_set_register(u32 register_id, u32 value);
+acpi_status acpi_set_firmware_waking_vector(u32 physical_address);
 
-acpi_status
-acpi_set_firmware_waking_vector(u32 physical_address);
-
-acpi_status
-acpi_set_firmware_waking_vector64(u64 physical_address);
+#if ACPI_MACHINE_WIDTH == 64
+acpi_status acpi_set_firmware_waking_vector64(u64 physical_address);
+#endif
 
 acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg);
 
diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h
index bf8d4cf..222733d 100644
--- a/include/acpi/actbl.h
+++ b/include/acpi/actbl.h
@@ -214,11 +214,11 @@
 	u16 flush_size;		/* Processor's memory cache line width, in bytes */
 	u16 flush_stride;	/* Number of flush strides that need to be read */
 	u8 duty_offset;		/* Processor duty cycle index in processor's P_CNT reg */
-	u8 duty_width;		/* Processor duty cycle value bit width in P_CNT register. */
+	u8 duty_width;		/* Processor duty cycle value bit width in P_CNT register */
 	u8 day_alarm;		/* Index to day-of-month alarm in RTC CMOS RAM */
 	u8 month_alarm;		/* Index to month-of-year alarm in RTC CMOS RAM */
 	u8 century;		/* Index to century in RTC CMOS RAM */
-	u16 boot_flags;		/* IA-PC Boot Architecture Flags. See Table 5-10 for description */
+	u16 boot_flags;		/* IA-PC Boot Architecture Flags (see below for individual flags) */
 	u8 reserved;		/* Reserved, must be zero */
 	u32 flags;		/* Miscellaneous flag bits (see below for individual flags) */
 	struct acpi_generic_address reset_register;	/* 64-bit address of the Reset register */
@@ -236,32 +236,41 @@
 	struct acpi_generic_address xgpe1_block;	/* 64-bit Extended General Purpose Event 1 Reg Blk address */
 };
 
+/* FADT Boot Architecture Flags (boot_flags) */
+
+#define ACPI_FADT_LEGACY_DEVICES    (1)  	/* 00: [V2] System has LPC or ISA bus devices */
+#define ACPI_FADT_8042              (1<<1)	/* 01: [V3] System has an 8042 controller on port 60/64 */
+#define ACPI_FADT_NO_VGA            (1<<2)	/* 02: [V4] It is not safe to probe for VGA hardware */
+#define ACPI_FADT_NO_MSI            (1<<3)	/* 03: [V4] Message Signaled Interrupts (MSI) must not be enabled */
+#define ACPI_FADT_NO_ASPM           (1<<4)	/* 04: [V4] PCIe ASPM control must not be enabled */
+
+#define FADT2_REVISION_ID               3
+
 /* FADT flags */
 
-#define ACPI_FADT_WBINVD            (1)	/* 00: The wbinvd instruction works properly */
-#define ACPI_FADT_WBINVD_FLUSH      (1<<1)	/* 01: The wbinvd flushes but does not invalidate */
-#define ACPI_FADT_C1_SUPPORTED      (1<<2)	/* 02: All processors support C1 state */
-#define ACPI_FADT_C2_MP_SUPPORTED   (1<<3)	/* 03: C2 state works on MP system */
-#define ACPI_FADT_POWER_BUTTON      (1<<4)	/* 04: Power button is handled as a generic feature */
-#define ACPI_FADT_SLEEP_BUTTON      (1<<5)	/* 05: Sleep button is handled as a generic feature, or  not present */
-#define ACPI_FADT_FIXED_RTC         (1<<6)	/* 06: RTC wakeup stat not in fixed register space */
-#define ACPI_FADT_S4_RTC_WAKE       (1<<7)	/* 07: RTC wakeup possible from S4 */
-#define ACPI_FADT_32BIT_TIMER       (1<<8)	/* 08: tmr_val is 32 bits 0=24-bits */
-#define ACPI_FADT_DOCKING_SUPPORTED (1<<9)	/* 09: Docking supported */
-#define ACPI_FADT_RESET_REGISTER    (1<<10)	/* 10: System reset via the FADT RESET_REG supported */
-#define ACPI_FADT_SEALED_CASE       (1<<11)	/* 11: No internal expansion capabilities and case is sealed */
-#define ACPI_FADT_HEADLESS          (1<<12)	/* 12: No local video capabilities or local input devices */
-#define ACPI_FADT_SLEEP_TYPE        (1<<13)	/* 13: Must execute native instruction after writing  SLP_TYPx register */
-#define ACPI_FADT_PCI_EXPRESS_WAKE  (1<<14)	/* 14: System supports PCIEXP_WAKE (STS/EN) bits (ACPI 3.0) */
-#define ACPI_FADT_PLATFORM_CLOCK    (1<<15)	/* 15: OSPM should use platform-provided timer (ACPI 3.0) */
-#define ACPI_FADT_S4_RTC_VALID      (1<<16)	/* 16: Contents of RTC_STS valid after S4 wake (ACPI 3.0) */
-#define ACPI_FADT_REMOTE_POWER_ON   (1<<17)	/* 17: System is compatible with remote power on (ACPI 3.0) */
-#define ACPI_FADT_APIC_CLUSTER      (1<<18)	/* 18: All local APICs must use cluster model (ACPI 3.0) */
-#define ACPI_FADT_APIC_PHYSICAL     (1<<19)	/* 19: All local x_aPICs must use physical dest mode (ACPI 3.0) */
+#define ACPI_FADT_WBINVD            (1)	/* 00: [V1] The wbinvd instruction works properly */
+#define ACPI_FADT_WBINVD_FLUSH      (1<<1)	/* 01: [V1] wbinvd flushes but does not invalidate caches */
+#define ACPI_FADT_C1_SUPPORTED      (1<<2)	/* 02: [V1] All processors support C1 state */
+#define ACPI_FADT_C2_MP_SUPPORTED   (1<<3)	/* 03: [V1] C2 state works on MP system */
+#define ACPI_FADT_POWER_BUTTON      (1<<4)	/* 04: [V1] Power button is handled as a control method device */
+#define ACPI_FADT_SLEEP_BUTTON      (1<<5)	/* 05: [V1] Sleep button is handled as a control method device */
+#define ACPI_FADT_FIXED_RTC         (1<<6)	/* 06: [V1] RTC wakeup status not in fixed register space */
+#define ACPI_FADT_S4_RTC_WAKE       (1<<7)	/* 07: [V1] RTC alarm can wake system from S4 */
+#define ACPI_FADT_32BIT_TIMER       (1<<8)	/* 08: [V1] ACPI timer width is 32-bit (0=24-bit) */
+#define ACPI_FADT_DOCKING_SUPPORTED (1<<9)	/* 09: [V1] Docking supported */
+#define ACPI_FADT_RESET_REGISTER    (1<<10)	/* 10: [V2] System reset via the FADT RESET_REG supported */
+#define ACPI_FADT_SEALED_CASE       (1<<11)	/* 11: [V3] No internal expansion capabilities and case is sealed */
+#define ACPI_FADT_HEADLESS          (1<<12)	/* 12: [V3] No local video capabilities or local input devices */
+#define ACPI_FADT_SLEEP_TYPE        (1<<13)	/* 13: [V3] Must execute native instruction after writing  SLP_TYPx register */
+#define ACPI_FADT_PCI_EXPRESS_WAKE  (1<<14)	/* 14: [V4] System supports PCIEXP_WAKE (STS/EN) bits (ACPI 3.0) */
+#define ACPI_FADT_PLATFORM_CLOCK    (1<<15)	/* 15: [V4] OSPM should use platform-provided timer (ACPI 3.0) */
+#define ACPI_FADT_S4_RTC_VALID      (1<<16)	/* 16: [V4] Contents of RTC_STS valid after S4 wake (ACPI 3.0) */
+#define ACPI_FADT_REMOTE_POWER_ON   (1<<17)	/* 17: [V4] System is compatible with remote power on (ACPI 3.0) */
+#define ACPI_FADT_APIC_CLUSTER      (1<<18)	/* 18: [V4] All local APICs must use cluster model (ACPI 3.0) */
+#define ACPI_FADT_APIC_PHYSICAL     (1<<19)	/* 19: [V4] All local x_aPICs must use physical dest mode (ACPI 3.0) */
 
-/*
- * FADT Prefered Power Management Profiles
- */
+/* FADT Prefered Power Management Profiles */
+
 enum acpi_prefered_pm_profiles {
 	PM_UNSPECIFIED = 0,
 	PM_DESKTOP = 1,
@@ -272,16 +281,6 @@
 	PM_APPLIANCE_PC = 6
 };
 
-/* FADT Boot Arch Flags */
-
-#define BAF_LEGACY_DEVICES              0x0001
-#define BAF_8042_KEYBOARD_CONTROLLER    0x0002
-#define BAF_MSI_NOT_SUPPORTED           0x0008
-#define BAF_PCIE_ASPM_CONTROL           0x0010
-
-#define FADT2_REVISION_ID               3
-#define FADT2_MINUS_REVISION_ID         2
-
 /* Reset to default packing */
 
 #pragma pack()
@@ -310,8 +309,9 @@
 #define ACPI_TABLE_ORIGIN_UNKNOWN       (0)
 #define ACPI_TABLE_ORIGIN_MAPPED        (1)
 #define ACPI_TABLE_ORIGIN_ALLOCATED     (2)
-#define ACPI_TABLE_ORIGIN_MASK          (3)
-#define ACPI_TABLE_IS_LOADED            (4)
+#define ACPI_TABLE_ORIGIN_OVERRIDE      (4)
+#define ACPI_TABLE_ORIGIN_MASK          (7)
+#define ACPI_TABLE_IS_LOADED            (8)
 
 /*
  * Get the remaining ACPI tables
diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h
index 18963b9..59ade07 100644
--- a/include/acpi/actbl1.h
+++ b/include/acpi/actbl1.h
@@ -1016,9 +1016,9 @@
 struct acpi_madt_local_x2apic {
 	struct acpi_subtable_header header;
 	u16 reserved;		/* Reserved - must be zero */
-	u32 local_apic_id;	/* Processor X2_APIC ID  */
+	u32 local_apic_id;	/* Processor x2APIC ID  */
 	u32 lapic_flags;
-	u32 uid;		/* Extended X2_APIC processor ID */
+	u32 uid;		/* ACPI processor UID */
 };
 
 /* 10: Local X2APIC NMI (07/2008) */
@@ -1026,7 +1026,7 @@
 struct acpi_madt_local_x2apic_nmi {
 	struct acpi_subtable_header header;
 	u16 inti_flags;
-	u32 uid;		/* Processor X2_APIC ID */
+	u32 uid;		/* ACPI processor UID */
 	u8 lint;		/* LINTn to which NMI is connected */
 	u8 reserved[3];
 };
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index a20aab5..f555d927 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -777,17 +777,25 @@
 #define ACPI_BITREG_SCI_ENABLE                  0x0E
 #define ACPI_BITREG_BUS_MASTER_RLD              0x0F
 #define ACPI_BITREG_GLOBAL_LOCK_RELEASE         0x10
-#define ACPI_BITREG_SLEEP_TYPE_A                0x11
-#define ACPI_BITREG_SLEEP_TYPE_B                0x12
-#define ACPI_BITREG_SLEEP_ENABLE                0x13
+#define ACPI_BITREG_SLEEP_TYPE                  0x11
+#define ACPI_BITREG_SLEEP_ENABLE                0x12
 
 /* PM2 Control register */
 
-#define ACPI_BITREG_ARB_DISABLE                 0x14
+#define ACPI_BITREG_ARB_DISABLE                 0x13
 
-#define ACPI_BITREG_MAX                         0x14
+#define ACPI_BITREG_MAX                         0x13
 #define ACPI_NUM_BITREG                         ACPI_BITREG_MAX + 1
 
+/* Status register values. A 1 clears a status bit. 0 = no effect */
+
+#define ACPI_CLEAR_STATUS                       1
+
+/* Enable and Control register values */
+
+#define ACPI_ENABLE_EVENT                       1
+#define ACPI_DISABLE_EVENT                      0
+
 /*
  * External ACPI object definition
  */
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 0574add..b09c4fd 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -322,7 +322,7 @@
 int acpi_processor_tstate_has_changed(struct acpi_processor *pr);
 int acpi_processor_get_throttling_info(struct acpi_processor *pr);
 extern int acpi_processor_set_throttling(struct acpi_processor *pr, int state);
-extern struct file_operations acpi_processor_throttling_fops;
+extern const struct file_operations acpi_processor_throttling_fops;
 extern void acpi_processor_throttling_init(void);
 /* in processor_idle.c */
 int acpi_processor_power_init(struct acpi_processor *pr,
@@ -336,7 +336,7 @@
 
 /* in processor_thermal.c */
 int acpi_processor_get_limit_info(struct acpi_processor *pr);
-extern struct file_operations acpi_processor_limit_fops;
+extern const struct file_operations acpi_processor_limit_fops;
 extern struct thermal_cooling_device_ops processor_cooling_ops;
 #ifdef CONFIG_CPU_FREQ
 void acpi_thermal_cpufreq_init(void);
diff --git a/include/acpi/video.h b/include/acpi/video.h
new file mode 100644
index 0000000..f0275bb
--- /dev/null
+++ b/include/acpi/video.h
@@ -0,0 +1,11 @@
+#ifndef __ACPI_VIDEO_H
+#define __ACPI_VIDEO_H
+
+#if (defined CONFIG_ACPI_VIDEO || defined CONFIG_ACPI_VIDEO_MODULE)
+extern int acpi_video_register(void);
+#else
+static inline int acpi_video_register(void) { return 0; }
+#endif
+
+#endif
+
diff --git a/include/asm-frv/ftrace.h b/include/asm-frv/ftrace.h
new file mode 100644
index 0000000..40a8c17
--- /dev/null
+++ b/include/asm-frv/ftrace.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index a654d72..7fa660f 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -61,6 +61,30 @@
 #define BRANCH_PROFILE()
 #endif
 
+#ifdef CONFIG_EVENT_TRACER
+#define FTRACE_EVENTS()	VMLINUX_SYMBOL(__start_ftrace_events) = .;	\
+			*(_ftrace_events)				\
+			VMLINUX_SYMBOL(__stop_ftrace_events) = .;
+#else
+#define FTRACE_EVENTS()
+#endif
+
+#ifdef CONFIG_TRACING
+#define TRACE_PRINTKS() VMLINUX_SYMBOL(__start___trace_bprintk_fmt) = .;      \
+			 *(__trace_printk_fmt) /* Trace_printk fmt' pointer */ \
+			 VMLINUX_SYMBOL(__stop___trace_bprintk_fmt) = .;
+#else
+#define TRACE_PRINTKS()
+#endif
+
+#ifdef CONFIG_FTRACE_SYSCALLS
+#define TRACE_SYSCALLS() VMLINUX_SYMBOL(__start_syscalls_metadata) = .;	\
+			 *(__syscalls_metadata)				\
+			 VMLINUX_SYMBOL(__stop_syscalls_metadata) = .;
+#else
+#define TRACE_SYSCALLS()
+#endif
+
 /* .data section */
 #define DATA_DATA							\
 	*(.data)							\
@@ -86,7 +110,10 @@
 	*(__verbose)                                                    \
 	VMLINUX_SYMBOL(__stop___verbose) = .;				\
 	LIKELY_PROFILE()		       				\
-	BRANCH_PROFILE()
+	BRANCH_PROFILE()						\
+	TRACE_PRINTKS()							\
+	FTRACE_EVENTS()							\
+	TRACE_SYSCALLS()
 
 #define RO_DATA(align)							\
 	. = ALIGN((align));						\
diff --git a/include/asm-m32r/ftrace.h b/include/asm-m32r/ftrace.h
new file mode 100644
index 0000000..40a8c17
--- /dev/null
+++ b/include/asm-m32r/ftrace.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/include/asm-mn10300/ftrace.h b/include/asm-mn10300/ftrace.h
new file mode 100644
index 0000000..40a8c17
--- /dev/null
+++ b/include/asm-mn10300/ftrace.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index d047f84..6586cbd 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -97,6 +97,7 @@
 /* the following four functions are architecture-dependent */
 void acpi_numa_slit_init (struct acpi_table_slit *slit);
 void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa);
+void acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa);
 void acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma);
 void acpi_numa_arch_fixup(void);
 
diff --git a/include/linux/async_tx.h b/include/linux/async_tx.h
index 45f6297..5fc2ef8 100644
--- a/include/linux/async_tx.h
+++ b/include/linux/async_tx.h
@@ -21,6 +21,15 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 
+/* on architectures without dma-mapping capabilities we need to ensure
+ * that the asynchronous path compiles away
+ */
+#ifdef CONFIG_HAS_DMA
+#define __async_inline
+#else
+#define __async_inline __always_inline
+#endif
+
 /**
  * dma_chan_ref - object used to manage dma channels received from the
  *   dmaengine core.
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index bee52ab..0ec2c59 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -24,8 +24,8 @@
  */
 enum bdi_state {
 	BDI_pdflush,		/* A pdflush thread is working this device */
-	BDI_write_congested,	/* The write queue is getting full */
-	BDI_read_congested,	/* The read queue is getting full */
+	BDI_async_congested,	/* The async (write) queue is getting full */
+	BDI_sync_congested,	/* The sync queue is getting full */
 	BDI_unused,		/* Available bits start here */
 };
 
@@ -215,18 +215,18 @@
 
 static inline int bdi_read_congested(struct backing_dev_info *bdi)
 {
-	return bdi_congested(bdi, 1 << BDI_read_congested);
+	return bdi_congested(bdi, 1 << BDI_sync_congested);
 }
 
 static inline int bdi_write_congested(struct backing_dev_info *bdi)
 {
-	return bdi_congested(bdi, 1 << BDI_write_congested);
+	return bdi_congested(bdi, 1 << BDI_async_congested);
 }
 
 static inline int bdi_rw_congested(struct backing_dev_info *bdi)
 {
-	return bdi_congested(bdi, (1 << BDI_read_congested)|
-				  (1 << BDI_write_congested));
+	return bdi_congested(bdi, (1 << BDI_sync_congested) |
+				  (1 << BDI_async_congested));
 }
 
 void clear_bdi_congested(struct backing_dev_info *bdi, int rw);
diff --git a/include/linux/bio.h b/include/linux/bio.h
index b05b1d4..b900d2c6 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -145,20 +145,21 @@
  * bit 2 -- barrier
  *	Insert a serialization point in the IO queue, forcing previously
  *	submitted IO to be completed before this one is issued.
- * bit 3 -- synchronous I/O hint: the block layer will unplug immediately
- *	Note that this does NOT indicate that the IO itself is sync, just
- *	that the block layer will not postpone issue of this IO by plugging.
- * bit 4 -- metadata request
+ * bit 3 -- synchronous I/O hint.
+ * bit 4 -- Unplug the device immediately after submitting this bio.
+ * bit 5 -- metadata request
  *	Used for tracing to differentiate metadata and data IO. May also
  *	get some preferential treatment in the IO scheduler
- * bit 5 -- discard sectors
+ * bit 6 -- discard sectors
  *	Informs the lower level device that this range of sectors is no longer
  *	used by the file system and may thus be freed by the device. Used
  *	for flash based storage.
- * bit 6 -- fail fast device errors
- * bit 7 -- fail fast transport errors
- * bit 8 -- fail fast driver errors
+ * bit 7 -- fail fast device errors
+ * bit 8 -- fail fast transport errors
+ * bit 9 -- fail fast driver errors
  *	Don't want driver retries for any fast fail whatever the reason.
+ * bit 10 -- Tell the IO scheduler not to wait for more requests after this
+	one has been submitted, even if it is a SYNC request.
  */
 #define BIO_RW		0	/* Must match RW in req flags (blkdev.h) */
 #define BIO_RW_AHEAD	1	/* Must match FAILFAST in req flags */
@@ -170,6 +171,7 @@
 #define BIO_RW_FAILFAST_DEV		7
 #define BIO_RW_FAILFAST_TRANSPORT	8
 #define BIO_RW_FAILFAST_DRIVER		9
+#define BIO_RW_NOIDLE	10
 
 #define bio_rw_flagged(bio, flag)	((bio)->bi_rw & (1 << (flag)))
 
@@ -188,6 +190,7 @@
 #define bio_rw_ahead(bio)	bio_rw_flagged(bio, BIO_RW_AHEAD)
 #define bio_rw_meta(bio)	bio_rw_flagged(bio, BIO_RW_META)
 #define bio_discard(bio)	bio_rw_flagged(bio, BIO_RW_DISCARD)
+#define bio_noidle(bio)		bio_rw_flagged(bio, BIO_RW_NOIDLE)
 
 /*
  * upper 16 bits of bi_rw define the io priority of this bio
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 465d6ba..e036609 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -38,6 +38,10 @@
 typedef void (rq_end_io_fn)(struct request *, int);
 
 struct request_list {
+	/*
+	 * count[], starved[], and wait[] are indexed by
+	 * BLK_RW_SYNC/BLK_RW_ASYNC
+	 */
 	int count[2];
 	int starved[2];
 	int elvpriv;
@@ -66,6 +70,11 @@
 	REQ_TYPE_ATA_PC,
 };
 
+enum {
+	BLK_RW_ASYNC	= 0,
+	BLK_RW_SYNC	= 1,
+};
+
 /*
  * For request of type REQ_TYPE_LINUX_BLOCK, rq->cmd[0] is the opcode being
  * sent down (similar to how REQ_TYPE_BLOCK_PC means that ->cmd[] holds a
@@ -103,12 +112,13 @@
 	__REQ_QUIET,		/* don't worry about errors */
 	__REQ_PREEMPT,		/* set for "ide_preempt" requests */
 	__REQ_ORDERED_COLOR,	/* is before or after barrier */
-	__REQ_RW_SYNC,		/* request is sync (O_DIRECT) */
+	__REQ_RW_SYNC,		/* request is sync (sync write or read) */
 	__REQ_ALLOCED,		/* request came from our alloc pool */
 	__REQ_RW_META,		/* metadata io request */
 	__REQ_COPY_USER,	/* contains copies of user pages */
 	__REQ_INTEGRITY,	/* integrity metadata has been remapped */
 	__REQ_UNPLUG,		/* unplug queue on submission */
+	__REQ_NOIDLE,		/* Don't anticipate more IO after this one */
 	__REQ_NR_BITS,		/* stops here */
 };
 
@@ -136,6 +146,7 @@
 #define REQ_COPY_USER	(1 << __REQ_COPY_USER)
 #define REQ_INTEGRITY	(1 << __REQ_INTEGRITY)
 #define REQ_UNPLUG	(1 << __REQ_UNPLUG)
+#define REQ_NOIDLE	(1 << __REQ_NOIDLE)
 
 #define BLK_MAX_CDB	16
 
@@ -438,8 +449,8 @@
 #define QUEUE_FLAG_CLUSTER	0	/* cluster several segments into 1 */
 #define QUEUE_FLAG_QUEUED	1	/* uses generic tag queueing */
 #define QUEUE_FLAG_STOPPED	2	/* queue is stopped */
-#define	QUEUE_FLAG_READFULL	3	/* read queue has been filled */
-#define QUEUE_FLAG_WRITEFULL	4	/* write queue has been filled */
+#define	QUEUE_FLAG_SYNCFULL	3	/* read queue has been filled */
+#define QUEUE_FLAG_ASYNCFULL	4	/* write queue has been filled */
 #define QUEUE_FLAG_DEAD		5	/* queue being torn down */
 #define QUEUE_FLAG_REENTER	6	/* Re-entrancy avoidance */
 #define QUEUE_FLAG_PLUGGED	7	/* queue is plugged */
@@ -611,32 +622,42 @@
 #define rq_data_dir(rq)		((rq)->cmd_flags & 1)
 
 /*
- * We regard a request as sync, if it's a READ or a SYNC write.
+ * We regard a request as sync, if either a read or a sync write
  */
-#define rq_is_sync(rq)		(rq_data_dir((rq)) == READ || (rq)->cmd_flags & REQ_RW_SYNC)
+static inline bool rw_is_sync(unsigned int rw_flags)
+{
+	return !(rw_flags & REQ_RW) || (rw_flags & REQ_RW_SYNC);
+}
+
+static inline bool rq_is_sync(struct request *rq)
+{
+	return rw_is_sync(rq->cmd_flags);
+}
+
 #define rq_is_meta(rq)		((rq)->cmd_flags & REQ_RW_META)
+#define rq_noidle(rq)		((rq)->cmd_flags & REQ_NOIDLE)
 
-static inline int blk_queue_full(struct request_queue *q, int rw)
+static inline int blk_queue_full(struct request_queue *q, int sync)
 {
-	if (rw == READ)
-		return test_bit(QUEUE_FLAG_READFULL, &q->queue_flags);
-	return test_bit(QUEUE_FLAG_WRITEFULL, &q->queue_flags);
+	if (sync)
+		return test_bit(QUEUE_FLAG_SYNCFULL, &q->queue_flags);
+	return test_bit(QUEUE_FLAG_ASYNCFULL, &q->queue_flags);
 }
 
-static inline void blk_set_queue_full(struct request_queue *q, int rw)
+static inline void blk_set_queue_full(struct request_queue *q, int sync)
 {
-	if (rw == READ)
-		queue_flag_set(QUEUE_FLAG_READFULL, q);
+	if (sync)
+		queue_flag_set(QUEUE_FLAG_SYNCFULL, q);
 	else
-		queue_flag_set(QUEUE_FLAG_WRITEFULL, q);
+		queue_flag_set(QUEUE_FLAG_ASYNCFULL, q);
 }
 
-static inline void blk_clear_queue_full(struct request_queue *q, int rw)
+static inline void blk_clear_queue_full(struct request_queue *q, int sync)
 {
-	if (rw == READ)
-		queue_flag_clear(QUEUE_FLAG_READFULL, q);
+	if (sync)
+		queue_flag_clear(QUEUE_FLAG_SYNCFULL, q);
 	else
-		queue_flag_clear(QUEUE_FLAG_WRITEFULL, q);
+		queue_flag_clear(QUEUE_FLAG_ASYNCFULL, q);
 }
 
 
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h
index 6e91587..d960889 100644
--- a/include/linux/blktrace_api.h
+++ b/include/linux/blktrace_api.h
@@ -144,6 +144,9 @@
 
 #ifdef __KERNEL__
 #if defined(CONFIG_BLK_DEV_IO_TRACE)
+
+#include <linux/sysfs.h>
+
 struct blk_trace {
 	int trace_state;
 	struct rchan *rchan;
@@ -194,6 +197,8 @@
 extern int blk_trace_startstop(struct request_queue *q, int start);
 extern int blk_trace_remove(struct request_queue *q);
 
+extern struct attribute_group blk_trace_attr_group;
+
 #else /* !CONFIG_BLK_DEV_IO_TRACE */
 #define blk_trace_ioctl(bdev, cmd, arg)		(-ENOTTY)
 #define blk_trace_shutdown(q)			do { } while (0)
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 4316a54..665fa70 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -365,7 +365,10 @@
 /* Return true if cgrp is a descendant of the task's cgroup */
 int cgroup_is_descendant(const struct cgroup *cgrp, struct task_struct *task);
 
-/* Control Group subsystem type. See Documentation/cgroups.txt for details */
+/*
+ * Control Group subsystem type.
+ * See Documentation/cgroups/cgroups.txt for details
+ */
 
 struct cgroup_subsys {
 	struct cgroup_subsys_state *(*create)(struct cgroup_subsys *ss,
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 9723edd..f2ded21 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -193,10 +193,10 @@
 		const struct compat_iovec __user *vec, unsigned long vlen);
 asmlinkage ssize_t compat_sys_preadv(unsigned long fd,
 		const struct compat_iovec __user *vec,
-		unsigned long vlen, u32 pos_high, u32 pos_low);
+		unsigned long vlen, u32 pos_low, u32 pos_high);
 asmlinkage ssize_t compat_sys_pwritev(unsigned long fd,
 		const struct compat_iovec __user *vec,
-		unsigned long vlen, u32 pos_high, u32 pos_low);
+		unsigned long vlen, u32 pos_low, u32 pos_high);
 
 int compat_do_execve(char * filename, compat_uptr_t __user *argv,
 	        compat_uptr_t __user *envp, struct pt_regs * regs);
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index d95da10..6faa7e54 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -68,6 +68,7 @@
 			unsigned long miss;
 			unsigned long hit;
 		};
+		unsigned long miss_hit[2];
 	};
 };
 
@@ -125,10 +126,7 @@
 				.line = __LINE__,			\
 			};						\
 		______r = !!(cond);					\
-		if (______r)						\
-			______f.hit++;					\
-		else							\
-			______f.miss++;					\
+		______f.miss_hit[______r]++;					\
 		______r;						\
 	}))
 #endif /* CONFIG_PROFILE_ALL_BRANCHES */
diff --git a/include/linux/connector.h b/include/linux/connector.h
index fc65d21..b9966e6 100644
--- a/include/linux/connector.h
+++ b/include/linux/connector.h
@@ -39,8 +39,10 @@
 #define CN_IDX_V86D			0x4
 #define CN_VAL_V86D_UVESAFB		0x1
 #define CN_IDX_BB			0x5	/* BlackBoard, from the TSP GPL sampling framework */
+#define CN_DST_IDX			0x6
+#define CN_DST_VAL			0x1
 
-#define CN_NETLINK_USERS		6
+#define CN_NETLINK_USERS		7
 
 /*
  * Maximum connector's message size.
diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h
index af0e01d..eb5c2ba 100644
--- a/include/linux/debugfs.h
+++ b/include/linux/debugfs.h
@@ -71,6 +71,9 @@
 struct dentry *debugfs_create_blob(const char *name, mode_t mode,
 				  struct dentry *parent,
 				  struct debugfs_blob_wrapper *blob);
+
+bool debugfs_initialized(void);
+
 #else
 
 #include <linux/err.h>
@@ -183,6 +186,11 @@
 	return ERR_PTR(-ENODEV);
 }
 
+static inline bool debugfs_initialized(void)
+{
+	return false;
+}
+
 #endif
 
 #endif
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index 8209e08..66ec05a 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -139,6 +139,9 @@
 	dm_ioctl_fn ioctl;
 	dm_merge_fn merge;
 	dm_busy_fn busy;
+
+	/* For internal device-mapper use. */
+	struct list_head list;
 };
 
 struct io_restrictions {
diff --git a/include/linux/dm-dirty-log.h b/include/linux/dm-dirty-log.h
index 600c5fb..5e8b11d 100644
--- a/include/linux/dm-dirty-log.h
+++ b/include/linux/dm-dirty-log.h
@@ -28,6 +28,9 @@
 	const char *name;
 	struct module *module;
 
+	/* For internal device-mapper use */
+	struct list_head list;
+
 	int (*ctr)(struct dm_dirty_log *log, struct dm_target *ti,
 		   unsigned argc, char **argv);
 	void (*dtr)(struct dm_dirty_log *log);
@@ -113,6 +116,16 @@
 	 */
 	int (*status)(struct dm_dirty_log *log, status_type_t status_type,
 		      char *result, unsigned maxlen);
+
+	/*
+	 * is_remote_recovering is necessary for cluster mirroring. It provides
+	 * a way to detect recovery on another node, so we aren't writing
+	 * concurrently.  This function is likely to block (when a cluster log
+	 * is used).
+	 *
+	 * Returns: 0, 1
+	 */
+	int (*is_remote_recovering)(struct dm_dirty_log *log, region_t region);
 };
 
 int dm_dirty_log_type_register(struct dm_dirty_log_type *type);
diff --git a/include/linux/dma_remapping.h b/include/linux/dma_remapping.h
index af1dab4..1a455f1 100644
--- a/include/linux/dma_remapping.h
+++ b/include/linux/dma_remapping.h
@@ -11,6 +11,7 @@
 
 #define DMA_PTE_READ (1)
 #define DMA_PTE_WRITE (2)
+#define DMA_PTE_SNP (1 << 11)
 
 struct intel_iommu;
 struct dmar_domain;
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 1956c8d..2e2aa3d 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -23,9 +23,6 @@
 
 #include <linux/device.h>
 #include <linux/uio.h>
-#include <linux/kref.h>
-#include <linux/completion.h>
-#include <linux/rcupdate.h>
 #include <linux/dma-mapping.h>
 
 /**
@@ -205,6 +202,7 @@
 /**
  * struct dma_device - info on the entity supplying DMA services
  * @chancnt: how many DMA channels are supported
+ * @privatecnt: how many DMA channels are requested by dma_request_channel
  * @channels: the list of struct dma_chan
  * @global_node: list_head for global dma_device_list
  * @cap_mask: one or more dma_capability flags
@@ -227,6 +225,7 @@
 struct dma_device {
 
 	unsigned int chancnt;
+	unsigned int privatecnt;
 	struct list_head channels;
 	struct list_head global_node;
 	dma_cap_mask_t  cap_mask;
@@ -291,6 +290,24 @@
 }
 #endif
 
+#ifdef CONFIG_ASYNC_TX_DMA
+#define async_dmaengine_get()	dmaengine_get()
+#define async_dmaengine_put()	dmaengine_put()
+#define async_dma_find_channel(type) dma_find_channel(type)
+#else
+static inline void async_dmaengine_get(void)
+{
+}
+static inline void async_dmaengine_put(void)
+{
+}
+static inline struct dma_chan *
+async_dma_find_channel(enum dma_transaction_type type)
+{
+	return NULL;
+}
+#endif
+
 dma_cookie_t dma_async_memcpy_buf_to_buf(struct dma_chan *chan,
 	void *dest, void *src, size_t len);
 dma_cookie_t dma_async_memcpy_buf_to_pg(struct dma_chan *chan,
@@ -337,6 +354,13 @@
 	set_bit(tx_type, dstp->bits);
 }
 
+#define dma_cap_clear(tx, mask) __dma_cap_clear((tx), &(mask))
+static inline void
+__dma_cap_clear(enum dma_transaction_type tx_type, dma_cap_mask_t *dstp)
+{
+	clear_bit(tx_type, dstp->bits);
+}
+
 #define dma_cap_zero(mask) __dma_cap_zero(&(mask))
 static inline void __dma_cap_zero(dma_cap_mask_t *dstp)
 {
diff --git a/include/linux/ds1wm.h b/include/linux/ds1wm.h
deleted file mode 100644
index d3c65e4..0000000
--- a/include/linux/ds1wm.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* platform data for the DS1WM driver */
-
-struct ds1wm_platform_data {
-	int bus_shift;	    /* number of shifts needed to calculate the
-			     * offset between DS1WM registers;
-			     * e.g. on h5xxx and h2200 this is 2
-			     * (registers aligned to 4-byte boundaries),
-			     * while on hx4700 this is 1 */
-	int active_high;
-	void (*enable)(struct platform_device *pdev);
-	void (*disable)(struct platform_device *pdev);
-};
diff --git a/include/linux/dst.h b/include/linux/dst.h
new file mode 100644
index 0000000..e26fed8
--- /dev/null
+++ b/include/linux/dst.h
@@ -0,0 +1,587 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru>
+ * 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.
+ *
+ * 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 __DST_H
+#define __DST_H
+
+#include <linux/types.h>
+#include <linux/connector.h>
+
+#define DST_NAMELEN		32
+#define DST_NAME		"dst"
+
+enum {
+	/* Remove node with given id from storage */
+	DST_DEL_NODE	= 0,
+	/* Add remote node with given id to the storage */
+	DST_ADD_REMOTE,
+	/* Add local node with given id to the storage to be exported and used by remote peers */
+	DST_ADD_EXPORT,
+	/* Crypto initialization command (hash/cipher used to protect the connection) */
+	DST_CRYPTO,
+	/* Security attributes for given connection (permissions for example) */
+	DST_SECURITY,
+	/* Register given node in the block layer subsystem */
+	DST_START,
+	DST_CMD_MAX
+};
+
+struct dst_ctl
+{
+	/* Storage name */
+	char			name[DST_NAMELEN];
+	/* Command flags */
+	__u32			flags;
+	/* Command itself (see above) */
+	__u32			cmd;
+	/* Maximum number of pages per single request in this device */
+	__u32			max_pages;
+	/* Stale/error transaction scanning timeout in milliseconds */
+	__u32			trans_scan_timeout;
+	/* Maximum number of retry sends before completing transaction as broken */
+	__u32			trans_max_retries;
+	/* Storage size */
+	__u64			size;
+};
+
+/* Reply command carries completion status */
+struct dst_ctl_ack
+{
+	struct cn_msg		msg;
+	int			error;
+	int			unused[3];
+};
+
+/*
+ * Unfortunaltely socket address structure is not exported to userspace
+ * and is redefined there.
+ */
+#define SADDR_MAX_DATA	128
+
+struct saddr {
+	/* address family, AF_xxx	*/
+	unsigned short		sa_family;
+	/* 14 bytes of protocol address	*/
+	char			sa_data[SADDR_MAX_DATA];
+	/* Number of bytes used in sa_data */
+	unsigned short		sa_data_len;
+};
+
+/* Address structure */
+struct dst_network_ctl
+{
+	/* Socket type: datagram, stream...*/
+	unsigned int		type;
+	/* Let me guess, is it a Jupiter diameter? */
+	unsigned int		proto;
+	/* Peer's address */
+	struct saddr		addr;
+};
+
+struct dst_crypto_ctl
+{
+	/* Cipher and hash names */
+	char			cipher_algo[DST_NAMELEN];
+	char			hash_algo[DST_NAMELEN];
+
+	/* Key sizes. Can be zero for digest for example */
+	unsigned int		cipher_keysize, hash_keysize;
+	/* Alignment. Calculated by the DST itself. */
+	unsigned int		crypto_attached_size;
+	/* Number of threads to perform crypto operations */
+	int			thread_num;
+};
+
+/* Export security attributes have this bits checked in when client connects */
+#define DST_PERM_READ		(1<<0)
+#define DST_PERM_WRITE		(1<<1)
+
+/*
+ * Right now it is simple model, where each remote address
+ * is assigned to set of permissions it is allowed to perform.
+ * In real world block device does not know anything but
+ * reading and writing, so it should be more than enough.
+ */
+struct dst_secure_user
+{
+	unsigned int		permissions;
+	struct saddr		addr;
+};
+
+/*
+ * Export control command: device to export and network address to accept
+ * clients to work with given device
+ */
+struct dst_export_ctl
+{
+	char			device[DST_NAMELEN];
+	struct dst_network_ctl	ctl;
+};
+
+enum {
+	DST_CFG	= 1, 		/* Request remote configuration */
+	DST_IO,			/* IO command */
+	DST_IO_RESPONSE,	/* IO response */
+	DST_PING,		/* Keepalive message */
+	DST_NCMD_MAX,
+};
+
+struct dst_cmd
+{
+	/* Network command itself, see above */
+	__u32			cmd;
+	/*
+	 * Size of the attached data
+	 * (in most cases, for READ command it means how many bytes were requested)
+	 */
+	__u32			size;
+	/* Crypto size: number of attached bytes with digest/hmac */
+	__u32			csize;
+	/* Here we can carry secret data */
+	__u32			reserved;
+	/* Read/write bits, see how they are encoded in bio structure */
+	__u64			rw;
+	/* BIO flags */
+	__u64			flags;
+	/* Unique command id (like transaction ID) */
+	__u64			id;
+	/* Sector to start IO from */
+	__u64			sector;
+	/* Hash data is placed after this header */
+	__u8			hash[0];
+};
+
+/*
+ * Convert command to/from network byte order.
+ * We do not use hton*() functions, since there is
+ * no 64-bit implementation.
+ */
+static inline void dst_convert_cmd(struct dst_cmd *c)
+{
+	c->cmd = __cpu_to_be32(c->cmd);
+	c->csize = __cpu_to_be32(c->csize);
+	c->size = __cpu_to_be32(c->size);
+	c->sector = __cpu_to_be64(c->sector);
+	c->id = __cpu_to_be64(c->id);
+	c->flags = __cpu_to_be64(c->flags);
+	c->rw = __cpu_to_be64(c->rw);
+}
+
+/* Transaction id */
+typedef __u64 dst_gen_t;
+
+#ifdef __KERNEL__
+
+#include <linux/blkdev.h>
+#include <linux/bio.h>
+#include <linux/device.h>
+#include <linux/mempool.h>
+#include <linux/net.h>
+#include <linux/poll.h>
+#include <linux/rbtree.h>
+
+#ifdef CONFIG_DST_DEBUG
+#define dprintk(f, a...) printk(KERN_NOTICE f, ##a)
+#else
+static inline void __attribute__ ((format (printf, 1, 2)))
+	dprintk(const char *fmt, ...) {}
+#endif
+
+struct dst_node;
+
+struct dst_trans
+{
+	/* DST node we are working with */
+	struct dst_node		*n;
+
+	/* Entry inside transaction tree */
+	struct rb_node		trans_entry;
+
+	/* Merlin kills this transaction when this memory cell equals zero */
+	atomic_t		refcnt;
+
+	/* How this transaction should be processed by crypto engine */
+	short			enc;
+	/* How many times this transaction was resent */
+	short			retries;
+	/* Completion status */
+	int			error;
+
+	/* When did we send it to the remote peer */
+	long			send_time;
+
+	/* My name is...
+	 * Well, computers does not speak, they have unique id instead */
+	dst_gen_t		gen;
+
+	/* Block IO we are working with */
+	struct bio		*bio;
+
+	/* Network command for above block IO request */
+	struct dst_cmd		cmd;
+};
+
+struct dst_crypto_engine
+{
+	/* What should we do with all block requests */
+	struct crypto_hash	*hash;
+	struct crypto_ablkcipher	*cipher;
+
+	/* Pool of pages used to encrypt data into before sending */
+	int			page_num;
+	struct page		**pages;
+
+	/* What to do with current request */
+	int			enc;
+	/* Who we are and where do we go */
+	struct scatterlist	*src, *dst;
+
+	/* Maximum timeout waiting for encryption to be completed */
+	long			timeout;
+	/* IV is a 64-bit sequential counter */
+	u64			iv;
+
+	/* Secret data */
+	void			*private;
+
+	/* Cached temporary data lives here */
+	int			size;
+	void			*data;
+};
+
+struct dst_state
+{
+	/* The main state protection */
+	struct mutex		state_lock;
+
+	/* Polling machinery for sockets */
+	wait_queue_t 		wait;
+	wait_queue_head_t 	*whead;
+	/* Most of events are being waited here */
+	wait_queue_head_t 	thread_wait;
+
+	/* Who owns this? */
+	struct dst_node		*node;
+
+	/* Network address for this state */
+	struct dst_network_ctl	ctl;
+
+	/* Permissions to work with: read-only or rw connection */
+	u32			permissions;
+
+	/* Called when we need to clean private data */
+	void			(* cleanup)(struct dst_state *st);
+
+	/* Used by the server: BIO completion queues BIOs here */
+	struct list_head	request_list;
+	spinlock_t		request_lock;
+
+	/* Guess what? No, it is not number of planets */
+	atomic_t		refcnt;
+
+	/* This flags is set when connection should be dropped */
+	int			need_exit;
+
+	/*
+	 * Socket to work with. Second pointer is used for
+	 * lockless check if socket was changed before performing
+	 * next action (like working with cached polling result)
+	 */
+	struct socket		*socket, *read_socket;
+
+	/* Cached preallocated data */
+	void			*data;
+	unsigned int		size;
+
+	/* Currently processed command */
+	struct dst_cmd		cmd;
+};
+
+struct dst_info
+{
+	/* Device size */
+	u64			size;
+
+	/* Local device name for export devices */
+	char			local[DST_NAMELEN];
+
+	/* Network setup */
+	struct dst_network_ctl	net;
+
+	/* Sysfs bits use this */
+	struct device		device;
+};
+
+struct dst_node
+{
+	struct list_head	node_entry;
+
+	/* Hi, my name is stored here */
+	char			name[DST_NAMELEN];
+	/* My cache name is stored here */
+	char			cache_name[DST_NAMELEN];
+
+	/* Block device attached to given node.
+	 * Only valid for exporting nodes */
+	struct block_device 	*bdev;
+	/* Network state machine for given peer */
+	struct dst_state	*state;
+
+	/* Block IO machinery */
+	struct request_queue	*queue;
+	struct gendisk		*disk;
+
+	/* Number of threads in processing pool */
+	int			thread_num;
+	/* Maximum number of pages in single IO */
+	int			max_pages;
+
+	/* I'm that big in bytes */
+	loff_t			size;
+
+	/* Exported to userspace node information */
+	struct dst_info		*info;
+
+	/*
+	 * Security attribute list.
+	 * Used only by exporting node currently.
+	 */
+	struct list_head	security_list;
+	struct mutex		security_lock;
+
+	/*
+	 * When this unerflows below zero, university collapses.
+	 * But this will not happen, since node will be freed,
+	 * when reference counter reaches zero.
+	 */
+	atomic_t		refcnt;
+
+	/* How precisely should I be started? */
+	int 			(*start)(struct dst_node *);
+
+	/* Crypto capabilities */
+	struct dst_crypto_ctl	crypto;
+	u8			*hash_key;
+	u8			*cipher_key;
+
+	/* Pool of processing thread */
+	struct thread_pool	*pool;
+
+	/* Transaction IDs live here */
+	atomic_long_t		gen;
+
+	/*
+	 * How frequently and how many times transaction
+	 * tree should be scanned to drop stale objects.
+	 */
+	long			trans_scan_timeout;
+	int			trans_max_retries;
+
+	/* Small gnomes live here */
+	struct rb_root		trans_root;
+	struct mutex		trans_lock;
+
+	/*
+	 * Transaction cache/memory pool.
+	 * It is big enough to contain not only transaction
+	 * itself, but additional crypto data (digest/hmac).
+	 */
+	struct kmem_cache	*trans_cache;
+	mempool_t		*trans_pool;
+
+	/* This entity scans transaction tree */
+	struct delayed_work 	trans_work;
+
+	wait_queue_head_t	wait;
+};
+
+/* Kernel representation of the security attribute */
+struct dst_secure
+{
+	struct list_head	sec_entry;
+	struct dst_secure_user	sec;
+};
+
+int dst_process_bio(struct dst_node *n, struct bio *bio);
+
+int dst_node_init_connected(struct dst_node *n, struct dst_network_ctl *r);
+int dst_node_init_listened(struct dst_node *n, struct dst_export_ctl *le);
+
+static inline struct dst_state *dst_state_get(struct dst_state *st)
+{
+	BUG_ON(atomic_read(&st->refcnt) == 0);
+	atomic_inc(&st->refcnt);
+	return st;
+}
+
+void dst_state_put(struct dst_state *st);
+
+struct dst_state *dst_state_alloc(struct dst_node *n);
+int dst_state_socket_create(struct dst_state *st);
+void dst_state_socket_release(struct dst_state *st);
+
+void dst_state_exit_connected(struct dst_state *st);
+
+int dst_state_schedule_receiver(struct dst_state *st);
+
+void dst_dump_addr(struct socket *sk, struct sockaddr *sa, char *str);
+
+static inline void dst_state_lock(struct dst_state *st)
+{
+	mutex_lock(&st->state_lock);
+}
+
+static inline void dst_state_unlock(struct dst_state *st)
+{
+	mutex_unlock(&st->state_lock);
+}
+
+void dst_poll_exit(struct dst_state *st);
+int dst_poll_init(struct dst_state *st);
+
+static inline unsigned int dst_state_poll(struct dst_state *st)
+{
+	unsigned int revents = POLLHUP | POLLERR;
+
+	dst_state_lock(st);
+	if (st->socket)
+		revents = st->socket->ops->poll(NULL, st->socket, NULL);
+	dst_state_unlock(st);
+
+	return revents;
+}
+
+static inline int dst_thread_setup(void *private, void *data)
+{
+	return 0;
+}
+
+void dst_node_put(struct dst_node *n);
+
+static inline struct dst_node *dst_node_get(struct dst_node *n)
+{
+	atomic_inc(&n->refcnt);
+	return n;
+}
+
+int dst_data_recv(struct dst_state *st, void *data, unsigned int size);
+int dst_recv_cdata(struct dst_state *st, void *cdata);
+int dst_data_send_header(struct socket *sock,
+		void *data, unsigned int size, int more);
+
+int dst_send_bio(struct dst_state *st, struct dst_cmd *cmd, struct bio *bio);
+
+int dst_process_io(struct dst_state *st);
+int dst_export_crypto(struct dst_node *n, struct bio *bio);
+int dst_export_send_bio(struct bio *bio);
+int dst_start_export(struct dst_node *n);
+
+int __init dst_export_init(void);
+void dst_export_exit(void);
+
+/* Private structure for export block IO requests */
+struct dst_export_priv
+{
+	struct list_head		request_entry;
+	struct dst_state		*state;
+	struct bio			*bio;
+	struct dst_cmd			cmd;
+};
+
+static inline void dst_trans_get(struct dst_trans *t)
+{
+	atomic_inc(&t->refcnt);
+}
+
+struct dst_trans *dst_trans_search(struct dst_node *node, dst_gen_t gen);
+int dst_trans_remove(struct dst_trans *t);
+int dst_trans_remove_nolock(struct dst_trans *t);
+void dst_trans_put(struct dst_trans *t);
+
+/*
+ * Convert bio into network command.
+ */
+static inline void dst_bio_to_cmd(struct bio *bio, struct dst_cmd *cmd,
+		u32 command, u64 id)
+{
+	cmd->cmd = command;
+	cmd->flags = (bio->bi_flags << BIO_POOL_BITS) >> BIO_POOL_BITS;
+	cmd->rw = bio->bi_rw;
+	cmd->size = bio->bi_size;
+	cmd->csize = 0;
+	cmd->id = id;
+	cmd->sector = bio->bi_sector;
+};
+
+int dst_trans_send(struct dst_trans *t);
+int dst_trans_crypto(struct dst_trans *t);
+
+int dst_node_crypto_init(struct dst_node *n, struct dst_crypto_ctl *ctl);
+void dst_node_crypto_exit(struct dst_node *n);
+
+static inline int dst_need_crypto(struct dst_node *n)
+{
+	struct dst_crypto_ctl *c = &n->crypto;
+	/*
+	 * Logical OR is appropriate here, but boolean one produces
+	 * more optimal code, so it is used instead.
+	 */
+	return (c->hash_algo[0] | c->cipher_algo[0]);
+}
+
+int dst_node_trans_init(struct dst_node *n, unsigned int size);
+void dst_node_trans_exit(struct dst_node *n);
+
+/*
+ * Pool of threads.
+ * Ready list contains threads currently free to be used,
+ * active one contains threads with some work scheduled for them.
+ * Caller can wait in given queue when thread is ready.
+ */
+struct thread_pool
+{
+	int			thread_num;
+	struct mutex		thread_lock;
+	struct list_head	ready_list, active_list;
+
+	wait_queue_head_t	wait;
+};
+
+void thread_pool_del_worker(struct thread_pool *p);
+void thread_pool_del_worker_id(struct thread_pool *p, unsigned int id);
+int thread_pool_add_worker(struct thread_pool *p,
+		char *name,
+		unsigned int id,
+		void *(* init)(void *data),
+		void (* cleanup)(void *data),
+		void *data);
+
+void thread_pool_destroy(struct thread_pool *p);
+struct thread_pool *thread_pool_create(int num, char *name,
+		void *(* init)(void *data),
+		void (* cleanup)(void *data),
+		void *data);
+
+int thread_pool_schedule(struct thread_pool *p,
+		int (* setup)(void *stored_private, void *setup_data),
+		int (* action)(void *stored_private, void *setup_data),
+		void *setup_data, long timeout);
+int thread_pool_schedule_private(struct thread_pool *p,
+		int (* setup)(void *private, void *data),
+		int (* action)(void *private, void *data),
+		void *data, long timeout, void *id);
+
+#endif /* __KERNEL__ */
+#endif /* __DST_H */
diff --git a/include/linux/dw_dmac.h b/include/linux/dw_dmac.h
index d797dde..c8aad71 100644
--- a/include/linux/dw_dmac.h
+++ b/include/linux/dw_dmac.h
@@ -74,4 +74,23 @@
 #define DWC_CFGL_HS_DST_POL	(1 << 18)	/* dst handshake active low */
 #define DWC_CFGL_HS_SRC_POL	(1 << 19)	/* src handshake active low */
 
+/* DMA API extensions */
+struct dw_cyclic_desc {
+	struct dw_desc	**desc;
+	unsigned long	periods;
+	void		(*period_callback)(void *param);
+	void		*period_callback_param;
+};
+
+struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan,
+		dma_addr_t buf_addr, size_t buf_len, size_t period_len,
+		enum dma_data_direction direction);
+void dw_dma_cyclic_free(struct dma_chan *chan);
+int dw_dma_cyclic_start(struct dma_chan *chan);
+void dw_dma_cyclic_stop(struct dma_chan *chan);
+
+dma_addr_t dw_dma_get_src_addr(struct dma_chan *chan);
+
+dma_addr_t dw_dma_get_dst_addr(struct dma_chan *chan);
+
 #endif /* DW_DMAC_H */
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
index e263aca..634a5e5 100644
--- a/include/linux/ext3_fs.h
+++ b/include/linux/ext3_fs.h
@@ -208,6 +208,7 @@
 #define EXT3_STATE_JDATA		0x00000001 /* journaled data exists */
 #define EXT3_STATE_NEW			0x00000002 /* inode is newly created */
 #define EXT3_STATE_XATTR		0x00000004 /* has in-inode xattrs */
+#define EXT3_STATE_FLUSH_ON_CLOSE	0x00000008
 
 /* Used to pass group descriptor data when online resize is done */
 struct ext3_new_group_input {
diff --git a/include/linux/fs.h b/include/linux/fs.h
index a09e17c..cae5720 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -95,8 +95,12 @@
 #define SWRITE 3	/* for ll_rw_block() - wait for buffer lock */
 #define READ_SYNC	(READ | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG))
 #define READ_META	(READ | (1 << BIO_RW_META))
-#define WRITE_SYNC	(WRITE | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG))
-#define SWRITE_SYNC	(SWRITE | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG))
+#define WRITE_SYNC_PLUG	(WRITE | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_NOIDLE))
+#define WRITE_SYNC	(WRITE_SYNC_PLUG | (1 << BIO_RW_UNPLUG))
+#define WRITE_ODIRECT	(WRITE | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG))
+#define SWRITE_SYNC_PLUG	\
+			(SWRITE | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_NOIDLE))
+#define SWRITE_SYNC	(SWRITE_SYNC_PLUG | (1 << BIO_RW_UNPLUG))
 #define WRITE_BARRIER	(WRITE | (1 << BIO_RW_BARRIER))
 #define DISCARD_NOBARRIER (1 << BIO_RW_DISCARD)
 #define DISCARD_BARRIER ((1 << BIO_RW_DISCARD) | (1 << BIO_RW_BARRIER))
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h
new file mode 100644
index 0000000..84d3532
--- /dev/null
+++ b/include/linux/fscache-cache.h
@@ -0,0 +1,505 @@
+/* General filesystem caching backing cache interface
+ *
+ * Copyright (C) 2004-2007 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * NOTE!!! See:
+ *
+ *	Documentation/filesystems/caching/backend-api.txt
+ *
+ * for a description of the cache backend interface declared here.
+ */
+
+#ifndef _LINUX_FSCACHE_CACHE_H
+#define _LINUX_FSCACHE_CACHE_H
+
+#include <linux/fscache.h>
+#include <linux/sched.h>
+#include <linux/slow-work.h>
+
+#define NR_MAXCACHES BITS_PER_LONG
+
+struct fscache_cache;
+struct fscache_cache_ops;
+struct fscache_object;
+struct fscache_operation;
+
+/*
+ * cache tag definition
+ */
+struct fscache_cache_tag {
+	struct list_head	link;
+	struct fscache_cache	*cache;		/* cache referred to by this tag */
+	unsigned long		flags;
+#define FSCACHE_TAG_RESERVED	0		/* T if tag is reserved for a cache */
+	atomic_t		usage;
+	char			name[0];	/* tag name */
+};
+
+/*
+ * cache definition
+ */
+struct fscache_cache {
+	const struct fscache_cache_ops *ops;
+	struct fscache_cache_tag *tag;		/* tag representing this cache */
+	struct kobject		*kobj;		/* system representation of this cache */
+	struct list_head	link;		/* link in list of caches */
+	size_t			max_index_size;	/* maximum size of index data */
+	char			identifier[36];	/* cache label */
+
+	/* node management */
+	struct work_struct	op_gc;		/* operation garbage collector */
+	struct list_head	object_list;	/* list of data/index objects */
+	struct list_head	op_gc_list;	/* list of ops to be deleted */
+	spinlock_t		object_list_lock;
+	spinlock_t		op_gc_list_lock;
+	atomic_t		object_count;	/* no. of live objects in this cache */
+	struct fscache_object	*fsdef;		/* object for the fsdef index */
+	unsigned long		flags;
+#define FSCACHE_IOERROR		0	/* cache stopped on I/O error */
+#define FSCACHE_CACHE_WITHDRAWN	1	/* cache has been withdrawn */
+};
+
+extern wait_queue_head_t fscache_cache_cleared_wq;
+
+/*
+ * operation to be applied to a cache object
+ * - retrieval initiation operations are done in the context of the process
+ *   that issued them, and not in an async thread pool
+ */
+typedef void (*fscache_operation_release_t)(struct fscache_operation *op);
+typedef void (*fscache_operation_processor_t)(struct fscache_operation *op);
+
+struct fscache_operation {
+	union {
+		struct work_struct fast_work;	/* record for fast ops */
+		struct slow_work slow_work;	/* record for (very) slow ops */
+	};
+	struct list_head	pend_link;	/* link in object->pending_ops */
+	struct fscache_object	*object;	/* object to be operated upon */
+
+	unsigned long		flags;
+#define FSCACHE_OP_TYPE		0x000f	/* operation type */
+#define FSCACHE_OP_FAST		0x0001	/* - fast op, processor may not sleep for disk */
+#define FSCACHE_OP_SLOW		0x0002	/* - (very) slow op, processor may sleep for disk */
+#define FSCACHE_OP_MYTHREAD	0x0003	/* - processing is done be issuing thread, not pool */
+#define FSCACHE_OP_WAITING	4	/* cleared when op is woken */
+#define FSCACHE_OP_EXCLUSIVE	5	/* exclusive op, other ops must wait */
+#define FSCACHE_OP_DEAD		6	/* op is now dead */
+
+	atomic_t		usage;
+	unsigned		debug_id;	/* debugging ID */
+
+	/* operation processor callback
+	 * - can be NULL if FSCACHE_OP_WAITING is going to be used to perform
+	 *   the op in a non-pool thread */
+	fscache_operation_processor_t processor;
+
+	/* operation releaser */
+	fscache_operation_release_t release;
+};
+
+extern atomic_t fscache_op_debug_id;
+extern const struct slow_work_ops fscache_op_slow_work_ops;
+
+extern void fscache_enqueue_operation(struct fscache_operation *);
+extern void fscache_put_operation(struct fscache_operation *);
+
+/**
+ * fscache_operation_init - Do basic initialisation of an operation
+ * @op: The operation to initialise
+ * @release: The release function to assign
+ *
+ * Do basic initialisation of an operation.  The caller must still set flags,
+ * object, either fast_work or slow_work if necessary, and processor if needed.
+ */
+static inline void fscache_operation_init(struct fscache_operation *op,
+					  fscache_operation_release_t release)
+{
+	atomic_set(&op->usage, 1);
+	op->debug_id = atomic_inc_return(&fscache_op_debug_id);
+	op->release = release;
+	INIT_LIST_HEAD(&op->pend_link);
+}
+
+/**
+ * fscache_operation_init_slow - Do additional initialisation of a slow op
+ * @op: The operation to initialise
+ * @processor: The processor function to assign
+ *
+ * Do additional initialisation of an operation as required for slow work.
+ */
+static inline
+void fscache_operation_init_slow(struct fscache_operation *op,
+				 fscache_operation_processor_t processor)
+{
+	op->processor = processor;
+	slow_work_init(&op->slow_work, &fscache_op_slow_work_ops);
+}
+
+/*
+ * data read operation
+ */
+struct fscache_retrieval {
+	struct fscache_operation op;
+	struct address_space	*mapping;	/* netfs pages */
+	fscache_rw_complete_t	end_io_func;	/* function to call on I/O completion */
+	void			*context;	/* netfs read context (pinned) */
+	struct list_head	to_do;		/* list of things to be done by the backend */
+	unsigned long		start_time;	/* time at which retrieval started */
+};
+
+typedef int (*fscache_page_retrieval_func_t)(struct fscache_retrieval *op,
+					     struct page *page,
+					     gfp_t gfp);
+
+typedef int (*fscache_pages_retrieval_func_t)(struct fscache_retrieval *op,
+					      struct list_head *pages,
+					      unsigned *nr_pages,
+					      gfp_t gfp);
+
+/**
+ * fscache_get_retrieval - Get an extra reference on a retrieval operation
+ * @op: The retrieval operation to get a reference on
+ *
+ * Get an extra reference on a retrieval operation.
+ */
+static inline
+struct fscache_retrieval *fscache_get_retrieval(struct fscache_retrieval *op)
+{
+	atomic_inc(&op->op.usage);
+	return op;
+}
+
+/**
+ * fscache_enqueue_retrieval - Enqueue a retrieval operation for processing
+ * @op: The retrieval operation affected
+ *
+ * Enqueue a retrieval operation for processing by the FS-Cache thread pool.
+ */
+static inline void fscache_enqueue_retrieval(struct fscache_retrieval *op)
+{
+	fscache_enqueue_operation(&op->op);
+}
+
+/**
+ * fscache_put_retrieval - Drop a reference to a retrieval operation
+ * @op: The retrieval operation affected
+ *
+ * Drop a reference to a retrieval operation.
+ */
+static inline void fscache_put_retrieval(struct fscache_retrieval *op)
+{
+	fscache_put_operation(&op->op);
+}
+
+/*
+ * cached page storage work item
+ * - used to do three things:
+ *   - batch writes to the cache
+ *   - do cache writes asynchronously
+ *   - defer writes until cache object lookup completion
+ */
+struct fscache_storage {
+	struct fscache_operation op;
+	pgoff_t			store_limit;	/* don't write more than this */
+};
+
+/*
+ * cache operations
+ */
+struct fscache_cache_ops {
+	/* name of cache provider */
+	const char *name;
+
+	/* allocate an object record for a cookie */
+	struct fscache_object *(*alloc_object)(struct fscache_cache *cache,
+					       struct fscache_cookie *cookie);
+
+	/* look up the object for a cookie */
+	void (*lookup_object)(struct fscache_object *object);
+
+	/* finished looking up */
+	void (*lookup_complete)(struct fscache_object *object);
+
+	/* increment the usage count on this object (may fail if unmounting) */
+	struct fscache_object *(*grab_object)(struct fscache_object *object);
+
+	/* pin an object in the cache */
+	int (*pin_object)(struct fscache_object *object);
+
+	/* unpin an object in the cache */
+	void (*unpin_object)(struct fscache_object *object);
+
+	/* store the updated auxilliary data on an object */
+	void (*update_object)(struct fscache_object *object);
+
+	/* discard the resources pinned by an object and effect retirement if
+	 * necessary */
+	void (*drop_object)(struct fscache_object *object);
+
+	/* dispose of a reference to an object */
+	void (*put_object)(struct fscache_object *object);
+
+	/* sync a cache */
+	void (*sync_cache)(struct fscache_cache *cache);
+
+	/* notification that the attributes of a non-index object (such as
+	 * i_size) have changed */
+	int (*attr_changed)(struct fscache_object *object);
+
+	/* reserve space for an object's data and associated metadata */
+	int (*reserve_space)(struct fscache_object *object, loff_t i_size);
+
+	/* request a backing block for a page be read or allocated in the
+	 * cache */
+	fscache_page_retrieval_func_t read_or_alloc_page;
+
+	/* request backing blocks for a list of pages be read or allocated in
+	 * the cache */
+	fscache_pages_retrieval_func_t read_or_alloc_pages;
+
+	/* request a backing block for a page be allocated in the cache so that
+	 * it can be written directly */
+	fscache_page_retrieval_func_t allocate_page;
+
+	/* request backing blocks for pages be allocated in the cache so that
+	 * they can be written directly */
+	fscache_pages_retrieval_func_t allocate_pages;
+
+	/* write a page to its backing block in the cache */
+	int (*write_page)(struct fscache_storage *op, struct page *page);
+
+	/* detach backing block from a page (optional)
+	 * - must release the cookie lock before returning
+	 * - may sleep
+	 */
+	void (*uncache_page)(struct fscache_object *object,
+			     struct page *page);
+
+	/* dissociate a cache from all the pages it was backing */
+	void (*dissociate_pages)(struct fscache_cache *cache);
+};
+
+/*
+ * data file or index object cookie
+ * - a file will only appear in one cache
+ * - a request to cache a file may or may not be honoured, subject to
+ *   constraints such as disk space
+ * - indices are created on disk just-in-time
+ */
+struct fscache_cookie {
+	atomic_t			usage;		/* number of users of this cookie */
+	atomic_t			n_children;	/* number of children of this cookie */
+	spinlock_t			lock;
+	struct hlist_head		backing_objects; /* object(s) backing this file/index */
+	const struct fscache_cookie_def	*def;		/* definition */
+	struct fscache_cookie		*parent;	/* parent of this entry */
+	void				*netfs_data;	/* back pointer to netfs */
+	struct radix_tree_root		stores;		/* pages to be stored on this cookie */
+#define FSCACHE_COOKIE_PENDING_TAG	0		/* pages tag: pending write to cache */
+
+	unsigned long			flags;
+#define FSCACHE_COOKIE_LOOKING_UP	0	/* T if non-index cookie being looked up still */
+#define FSCACHE_COOKIE_CREATING		1	/* T if non-index object being created still */
+#define FSCACHE_COOKIE_NO_DATA_YET	2	/* T if new object with no cached data yet */
+#define FSCACHE_COOKIE_PENDING_FILL	3	/* T if pending initial fill on object */
+#define FSCACHE_COOKIE_FILLING		4	/* T if filling object incrementally */
+#define FSCACHE_COOKIE_UNAVAILABLE	5	/* T if cookie is unavailable (error, etc) */
+};
+
+extern struct fscache_cookie fscache_fsdef_index;
+
+/*
+ * on-disk cache file or index handle
+ */
+struct fscache_object {
+	enum fscache_object_state {
+		FSCACHE_OBJECT_INIT,		/* object in initial unbound state */
+		FSCACHE_OBJECT_LOOKING_UP,	/* looking up object */
+		FSCACHE_OBJECT_CREATING,	/* creating object */
+
+		/* active states */
+		FSCACHE_OBJECT_AVAILABLE,	/* cleaning up object after creation */
+		FSCACHE_OBJECT_ACTIVE,		/* object is usable */
+		FSCACHE_OBJECT_UPDATING,	/* object is updating */
+
+		/* terminal states */
+		FSCACHE_OBJECT_DYING,		/* object waiting for accessors to finish */
+		FSCACHE_OBJECT_LC_DYING,	/* object cleaning up after lookup/create */
+		FSCACHE_OBJECT_ABORT_INIT,	/* abort the init state */
+		FSCACHE_OBJECT_RELEASING,	/* releasing object */
+		FSCACHE_OBJECT_RECYCLING,	/* retiring object */
+		FSCACHE_OBJECT_WITHDRAWING,	/* withdrawing object */
+		FSCACHE_OBJECT_DEAD,		/* object is now dead */
+	} state;
+
+	int			debug_id;	/* debugging ID */
+	int			n_children;	/* number of child objects */
+	int			n_ops;		/* number of ops outstanding on object */
+	int			n_obj_ops;	/* number of object ops outstanding on object */
+	int			n_in_progress;	/* number of ops in progress */
+	int			n_exclusive;	/* number of exclusive ops queued */
+	spinlock_t		lock;		/* state and operations lock */
+
+	unsigned long		lookup_jif;	/* time at which lookup started */
+	unsigned long		event_mask;	/* events this object is interested in */
+	unsigned long		events;		/* events to be processed by this object
+						 * (order is important - using fls) */
+#define FSCACHE_OBJECT_EV_REQUEUE	0	/* T if object should be requeued */
+#define FSCACHE_OBJECT_EV_UPDATE	1	/* T if object should be updated */
+#define FSCACHE_OBJECT_EV_CLEARED	2	/* T if accessors all gone */
+#define FSCACHE_OBJECT_EV_ERROR		3	/* T if fatal error occurred during processing */
+#define FSCACHE_OBJECT_EV_RELEASE	4	/* T if netfs requested object release */
+#define FSCACHE_OBJECT_EV_RETIRE	5	/* T if netfs requested object retirement */
+#define FSCACHE_OBJECT_EV_WITHDRAW	6	/* T if cache requested object withdrawal */
+
+	unsigned long		flags;
+#define FSCACHE_OBJECT_LOCK		0	/* T if object is busy being processed */
+#define FSCACHE_OBJECT_PENDING_WRITE	1	/* T if object has pending write */
+#define FSCACHE_OBJECT_WAITING		2	/* T if object is waiting on its parent */
+
+	struct list_head	cache_link;	/* link in cache->object_list */
+	struct hlist_node	cookie_link;	/* link in cookie->backing_objects */
+	struct fscache_cache	*cache;		/* cache that supplied this object */
+	struct fscache_cookie	*cookie;	/* netfs's file/index object */
+	struct fscache_object	*parent;	/* parent object */
+	struct slow_work	work;		/* attention scheduling record */
+	struct list_head	dependents;	/* FIFO of dependent objects */
+	struct list_head	dep_link;	/* link in parent's dependents list */
+	struct list_head	pending_ops;	/* unstarted operations on this object */
+	pgoff_t			store_limit;	/* current storage limit */
+};
+
+extern const char *fscache_object_states[];
+
+#define fscache_object_is_active(obj)			      \
+	(!test_bit(FSCACHE_IOERROR, &(obj)->cache->flags) &&  \
+	 (obj)->state >= FSCACHE_OBJECT_AVAILABLE &&	      \
+	 (obj)->state < FSCACHE_OBJECT_DYING)
+
+extern const struct slow_work_ops fscache_object_slow_work_ops;
+
+/**
+ * fscache_object_init - Initialise a cache object description
+ * @object: Object description
+ *
+ * Initialise a cache object description to its basic values.
+ *
+ * See Documentation/filesystems/caching/backend-api.txt for a complete
+ * description.
+ */
+static inline
+void fscache_object_init(struct fscache_object *object,
+			 struct fscache_cookie *cookie,
+			 struct fscache_cache *cache)
+{
+	atomic_inc(&cache->object_count);
+
+	object->state = FSCACHE_OBJECT_INIT;
+	spin_lock_init(&object->lock);
+	INIT_LIST_HEAD(&object->cache_link);
+	INIT_HLIST_NODE(&object->cookie_link);
+	vslow_work_init(&object->work, &fscache_object_slow_work_ops);
+	INIT_LIST_HEAD(&object->dependents);
+	INIT_LIST_HEAD(&object->dep_link);
+	INIT_LIST_HEAD(&object->pending_ops);
+	object->n_children = 0;
+	object->n_ops = object->n_in_progress = object->n_exclusive = 0;
+	object->events = object->event_mask = 0;
+	object->flags = 0;
+	object->store_limit = 0;
+	object->cache = cache;
+	object->cookie = cookie;
+	object->parent = NULL;
+}
+
+extern void fscache_object_lookup_negative(struct fscache_object *object);
+extern void fscache_obtained_object(struct fscache_object *object);
+
+/**
+ * fscache_object_destroyed - Note destruction of an object in a cache
+ * @cache: The cache from which the object came
+ *
+ * Note the destruction and deallocation of an object record in a cache.
+ */
+static inline void fscache_object_destroyed(struct fscache_cache *cache)
+{
+	if (atomic_dec_and_test(&cache->object_count))
+		wake_up_all(&fscache_cache_cleared_wq);
+}
+
+/**
+ * fscache_object_lookup_error - Note an object encountered an error
+ * @object: The object on which the error was encountered
+ *
+ * Note that an object encountered a fatal error (usually an I/O error) and
+ * that it should be withdrawn as soon as possible.
+ */
+static inline void fscache_object_lookup_error(struct fscache_object *object)
+{
+	set_bit(FSCACHE_OBJECT_EV_ERROR, &object->events);
+}
+
+/**
+ * fscache_set_store_limit - Set the maximum size to be stored in an object
+ * @object: The object to set the maximum on
+ * @i_size: The limit to set in bytes
+ *
+ * Set the maximum size an object is permitted to reach, implying the highest
+ * byte that may be written.  Intended to be called by the attr_changed() op.
+ *
+ * See Documentation/filesystems/caching/backend-api.txt for a complete
+ * description.
+ */
+static inline
+void fscache_set_store_limit(struct fscache_object *object, loff_t i_size)
+{
+	object->store_limit = i_size >> PAGE_SHIFT;
+	if (i_size & ~PAGE_MASK)
+		object->store_limit++;
+}
+
+/**
+ * fscache_end_io - End a retrieval operation on a page
+ * @op: The FS-Cache operation covering the retrieval
+ * @page: The page that was to be fetched
+ * @error: The error code (0 if successful)
+ *
+ * Note the end of an operation to retrieve a page, as covered by a particular
+ * operation record.
+ */
+static inline void fscache_end_io(struct fscache_retrieval *op,
+				  struct page *page, int error)
+{
+	op->end_io_func(page, op->context, error);
+}
+
+/*
+ * out-of-line cache backend functions
+ */
+extern void fscache_init_cache(struct fscache_cache *cache,
+			       const struct fscache_cache_ops *ops,
+			       const char *idfmt,
+			       ...) __attribute__ ((format (printf, 3, 4)));
+
+extern int fscache_add_cache(struct fscache_cache *cache,
+			     struct fscache_object *fsdef,
+			     const char *tagname);
+extern void fscache_withdraw_cache(struct fscache_cache *cache);
+
+extern void fscache_io_error(struct fscache_cache *cache);
+
+extern void fscache_mark_pages_cached(struct fscache_retrieval *op,
+				      struct pagevec *pagevec);
+
+extern enum fscache_checkaux fscache_check_aux(struct fscache_object *object,
+					       const void *data,
+					       uint16_t datalen);
+
+#endif /* _LINUX_FSCACHE_CACHE_H */
diff --git a/include/linux/fscache.h b/include/linux/fscache.h
new file mode 100644
index 0000000..6d8ee46
--- /dev/null
+++ b/include/linux/fscache.h
@@ -0,0 +1,618 @@
+/* General filesystem caching interface
+ *
+ * Copyright (C) 2004-2007 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * NOTE!!! See:
+ *
+ *	Documentation/filesystems/caching/netfs-api.txt
+ *
+ * for a description of the network filesystem interface declared here.
+ */
+
+#ifndef _LINUX_FSCACHE_H
+#define _LINUX_FSCACHE_H
+
+#include <linux/fs.h>
+#include <linux/list.h>
+#include <linux/pagemap.h>
+#include <linux/pagevec.h>
+
+#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
+#define fscache_available() (1)
+#define fscache_cookie_valid(cookie) (cookie)
+#else
+#define fscache_available() (0)
+#define fscache_cookie_valid(cookie) (0)
+#endif
+
+
+/*
+ * overload PG_private_2 to give us PG_fscache - this is used to indicate that
+ * a page is currently backed by a local disk cache
+ */
+#define PageFsCache(page)		PagePrivate2((page))
+#define SetPageFsCache(page)		SetPagePrivate2((page))
+#define ClearPageFsCache(page)		ClearPagePrivate2((page))
+#define TestSetPageFsCache(page)	TestSetPagePrivate2((page))
+#define TestClearPageFsCache(page)	TestClearPagePrivate2((page))
+
+/* pattern used to fill dead space in an index entry */
+#define FSCACHE_INDEX_DEADFILL_PATTERN 0x79
+
+struct pagevec;
+struct fscache_cache_tag;
+struct fscache_cookie;
+struct fscache_netfs;
+
+typedef void (*fscache_rw_complete_t)(struct page *page,
+				      void *context,
+				      int error);
+
+/* result of index entry consultation */
+enum fscache_checkaux {
+	FSCACHE_CHECKAUX_OKAY,		/* entry okay as is */
+	FSCACHE_CHECKAUX_NEEDS_UPDATE,	/* entry requires update */
+	FSCACHE_CHECKAUX_OBSOLETE,	/* entry requires deletion */
+};
+
+/*
+ * fscache cookie definition
+ */
+struct fscache_cookie_def {
+	/* name of cookie type */
+	char name[16];
+
+	/* cookie type */
+	uint8_t type;
+#define FSCACHE_COOKIE_TYPE_INDEX	0
+#define FSCACHE_COOKIE_TYPE_DATAFILE	1
+
+	/* select the cache into which to insert an entry in this index
+	 * - optional
+	 * - should return a cache identifier or NULL to cause the cache to be
+	 *   inherited from the parent if possible or the first cache picked
+	 *   for a non-index file if not
+	 */
+	struct fscache_cache_tag *(*select_cache)(
+		const void *parent_netfs_data,
+		const void *cookie_netfs_data);
+
+	/* get an index key
+	 * - should store the key data in the buffer
+	 * - should return the amount of amount stored
+	 * - not permitted to return an error
+	 * - the netfs data from the cookie being used as the source is
+	 *   presented
+	 */
+	uint16_t (*get_key)(const void *cookie_netfs_data,
+			    void *buffer,
+			    uint16_t bufmax);
+
+	/* get certain file attributes from the netfs data
+	 * - this function can be absent for an index
+	 * - not permitted to return an error
+	 * - the netfs data from the cookie being used as the source is
+	 *   presented
+	 */
+	void (*get_attr)(const void *cookie_netfs_data, uint64_t *size);
+
+	/* get the auxilliary data from netfs data
+	 * - this function can be absent if the index carries no state data
+	 * - should store the auxilliary data in the buffer
+	 * - should return the amount of amount stored
+	 * - not permitted to return an error
+	 * - the netfs data from the cookie being used as the source is
+	 *   presented
+	 */
+	uint16_t (*get_aux)(const void *cookie_netfs_data,
+			    void *buffer,
+			    uint16_t bufmax);
+
+	/* consult the netfs about the state of an object
+	 * - this function can be absent if the index carries no state data
+	 * - the netfs data from the cookie being used as the target is
+	 *   presented, as is the auxilliary data
+	 */
+	enum fscache_checkaux (*check_aux)(void *cookie_netfs_data,
+					   const void *data,
+					   uint16_t datalen);
+
+	/* get an extra reference on a read context
+	 * - this function can be absent if the completion function doesn't
+	 *   require a context
+	 */
+	void (*get_context)(void *cookie_netfs_data, void *context);
+
+	/* release an extra reference on a read context
+	 * - this function can be absent if the completion function doesn't
+	 *   require a context
+	 */
+	void (*put_context)(void *cookie_netfs_data, void *context);
+
+	/* indicate pages that now have cache metadata retained
+	 * - this function should mark the specified pages as now being cached
+	 * - the pages will have been marked with PG_fscache before this is
+	 *   called, so this is optional
+	 */
+	void (*mark_pages_cached)(void *cookie_netfs_data,
+				  struct address_space *mapping,
+				  struct pagevec *cached_pvec);
+
+	/* indicate the cookie is no longer cached
+	 * - this function is called when the backing store currently caching
+	 *   a cookie is removed
+	 * - the netfs should use this to clean up any markers indicating
+	 *   cached pages
+	 * - this is mandatory for any object that may have data
+	 */
+	void (*now_uncached)(void *cookie_netfs_data);
+};
+
+/*
+ * fscache cached network filesystem type
+ * - name, version and ops must be filled in before registration
+ * - all other fields will be set during registration
+ */
+struct fscache_netfs {
+	uint32_t			version;	/* indexing version */
+	const char			*name;		/* filesystem name */
+	struct fscache_cookie		*primary_index;
+	struct list_head		link;		/* internal link */
+};
+
+/*
+ * slow-path functions for when there is actually caching available, and the
+ * netfs does actually have a valid token
+ * - these are not to be called directly
+ * - these are undefined symbols when FS-Cache is not configured and the
+ *   optimiser takes care of not using them
+ */
+extern int __fscache_register_netfs(struct fscache_netfs *);
+extern void __fscache_unregister_netfs(struct fscache_netfs *);
+extern struct fscache_cache_tag *__fscache_lookup_cache_tag(const char *);
+extern void __fscache_release_cache_tag(struct fscache_cache_tag *);
+
+extern struct fscache_cookie *__fscache_acquire_cookie(
+	struct fscache_cookie *,
+	const struct fscache_cookie_def *,
+	void *);
+extern void __fscache_relinquish_cookie(struct fscache_cookie *, int);
+extern void __fscache_update_cookie(struct fscache_cookie *);
+extern int __fscache_attr_changed(struct fscache_cookie *);
+extern int __fscache_read_or_alloc_page(struct fscache_cookie *,
+					struct page *,
+					fscache_rw_complete_t,
+					void *,
+					gfp_t);
+extern int __fscache_read_or_alloc_pages(struct fscache_cookie *,
+					 struct address_space *,
+					 struct list_head *,
+					 unsigned *,
+					 fscache_rw_complete_t,
+					 void *,
+					 gfp_t);
+extern int __fscache_alloc_page(struct fscache_cookie *, struct page *, gfp_t);
+extern int __fscache_write_page(struct fscache_cookie *, struct page *, gfp_t);
+extern void __fscache_uncache_page(struct fscache_cookie *, struct page *);
+extern bool __fscache_check_page_write(struct fscache_cookie *, struct page *);
+extern void __fscache_wait_on_page_write(struct fscache_cookie *, struct page *);
+
+/**
+ * fscache_register_netfs - Register a filesystem as desiring caching services
+ * @netfs: The description of the filesystem
+ *
+ * Register a filesystem as desiring caching services if they're available.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+int fscache_register_netfs(struct fscache_netfs *netfs)
+{
+	if (fscache_available())
+		return __fscache_register_netfs(netfs);
+	else
+		return 0;
+}
+
+/**
+ * fscache_unregister_netfs - Indicate that a filesystem no longer desires
+ * caching services
+ * @netfs: The description of the filesystem
+ *
+ * Indicate that a filesystem no longer desires caching services for the
+ * moment.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+void fscache_unregister_netfs(struct fscache_netfs *netfs)
+{
+	if (fscache_available())
+		__fscache_unregister_netfs(netfs);
+}
+
+/**
+ * fscache_lookup_cache_tag - Look up a cache tag
+ * @name: The name of the tag to search for
+ *
+ * Acquire a specific cache referral tag that can be used to select a specific
+ * cache in which to cache an index.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+struct fscache_cache_tag *fscache_lookup_cache_tag(const char *name)
+{
+	if (fscache_available())
+		return __fscache_lookup_cache_tag(name);
+	else
+		return NULL;
+}
+
+/**
+ * fscache_release_cache_tag - Release a cache tag
+ * @tag: The tag to release
+ *
+ * Release a reference to a cache referral tag previously looked up.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+void fscache_release_cache_tag(struct fscache_cache_tag *tag)
+{
+	if (fscache_available())
+		__fscache_release_cache_tag(tag);
+}
+
+/**
+ * fscache_acquire_cookie - Acquire a cookie to represent a cache object
+ * @parent: The cookie that's to be the parent of this one
+ * @def: A description of the cache object, including callback operations
+ * @netfs_data: An arbitrary piece of data to be kept in the cookie to
+ * represent the cache object to the netfs
+ *
+ * This function is used to inform FS-Cache about part of an index hierarchy
+ * that can be used to locate files.  This is done by requesting a cookie for
+ * each index in the path to the file.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+struct fscache_cookie *fscache_acquire_cookie(
+	struct fscache_cookie *parent,
+	const struct fscache_cookie_def *def,
+	void *netfs_data)
+{
+	if (fscache_cookie_valid(parent))
+		return __fscache_acquire_cookie(parent, def, netfs_data);
+	else
+		return NULL;
+}
+
+/**
+ * fscache_relinquish_cookie - Return the cookie to the cache, maybe discarding
+ * it
+ * @cookie: The cookie being returned
+ * @retire: True if the cache object the cookie represents is to be discarded
+ *
+ * This function returns a cookie to the cache, forcibly discarding the
+ * associated cache object if retire is set to true.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+void fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
+{
+	if (fscache_cookie_valid(cookie))
+		__fscache_relinquish_cookie(cookie, retire);
+}
+
+/**
+ * fscache_update_cookie - Request that a cache object be updated
+ * @cookie: The cookie representing the cache object
+ *
+ * Request an update of the index data for the cache object associated with the
+ * cookie.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+void fscache_update_cookie(struct fscache_cookie *cookie)
+{
+	if (fscache_cookie_valid(cookie))
+		__fscache_update_cookie(cookie);
+}
+
+/**
+ * fscache_pin_cookie - Pin a data-storage cache object in its cache
+ * @cookie: The cookie representing the cache object
+ *
+ * Permit data-storage cache objects to be pinned in the cache.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+int fscache_pin_cookie(struct fscache_cookie *cookie)
+{
+	return -ENOBUFS;
+}
+
+/**
+ * fscache_pin_cookie - Unpin a data-storage cache object in its cache
+ * @cookie: The cookie representing the cache object
+ *
+ * Permit data-storage cache objects to be unpinned from the cache.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+void fscache_unpin_cookie(struct fscache_cookie *cookie)
+{
+}
+
+/**
+ * fscache_attr_changed - Notify cache that an object's attributes changed
+ * @cookie: The cookie representing the cache object
+ *
+ * Send a notification to the cache indicating that an object's attributes have
+ * changed.  This includes the data size.  These attributes will be obtained
+ * through the get_attr() cookie definition op.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+int fscache_attr_changed(struct fscache_cookie *cookie)
+{
+	if (fscache_cookie_valid(cookie))
+		return __fscache_attr_changed(cookie);
+	else
+		return -ENOBUFS;
+}
+
+/**
+ * fscache_reserve_space - Reserve data space for a cached object
+ * @cookie: The cookie representing the cache object
+ * @i_size: The amount of space to be reserved
+ *
+ * Reserve an amount of space in the cache for the cache object attached to a
+ * cookie so that a write to that object within the space can always be
+ * honoured.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+int fscache_reserve_space(struct fscache_cookie *cookie, loff_t size)
+{
+	return -ENOBUFS;
+}
+
+/**
+ * fscache_read_or_alloc_page - Read a page from the cache or allocate a block
+ * in which to store it
+ * @cookie: The cookie representing the cache object
+ * @page: The netfs page to fill if possible
+ * @end_io_func: The callback to invoke when and if the page is filled
+ * @context: An arbitrary piece of data to pass on to end_io_func()
+ * @gfp: The conditions under which memory allocation should be made
+ *
+ * Read a page from the cache, or if that's not possible make a potential
+ * one-block reservation in the cache into which the page may be stored once
+ * fetched from the server.
+ *
+ * If the page is not backed by the cache object, or if it there's some reason
+ * it can't be, -ENOBUFS will be returned and nothing more will be done for
+ * that page.
+ *
+ * Else, if that page is backed by the cache, a read will be initiated directly
+ * to the netfs's page and 0 will be returned by this function.  The
+ * end_io_func() callback will be invoked when the operation terminates on a
+ * completion or failure.  Note that the callback may be invoked before the
+ * return.
+ *
+ * Else, if the page is unbacked, -ENODATA is returned and a block may have
+ * been allocated in the cache.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+int fscache_read_or_alloc_page(struct fscache_cookie *cookie,
+			       struct page *page,
+			       fscache_rw_complete_t end_io_func,
+			       void *context,
+			       gfp_t gfp)
+{
+	if (fscache_cookie_valid(cookie))
+		return __fscache_read_or_alloc_page(cookie, page, end_io_func,
+						    context, gfp);
+	else
+		return -ENOBUFS;
+}
+
+/**
+ * fscache_read_or_alloc_pages - Read pages from the cache and/or allocate
+ * blocks in which to store them
+ * @cookie: The cookie representing the cache object
+ * @mapping: The netfs inode mapping to which the pages will be attached
+ * @pages: A list of potential netfs pages to be filled
+ * @end_io_func: The callback to invoke when and if each page is filled
+ * @context: An arbitrary piece of data to pass on to end_io_func()
+ * @gfp: The conditions under which memory allocation should be made
+ *
+ * Read a set of pages from the cache, or if that's not possible, attempt to
+ * make a potential one-block reservation for each page in the cache into which
+ * that page may be stored once fetched from the server.
+ *
+ * If some pages are not backed by the cache object, or if it there's some
+ * reason they can't be, -ENOBUFS will be returned and nothing more will be
+ * done for that pages.
+ *
+ * Else, if some of the pages are backed by the cache, a read will be initiated
+ * directly to the netfs's page and 0 will be returned by this function.  The
+ * end_io_func() callback will be invoked when the operation terminates on a
+ * completion or failure.  Note that the callback may be invoked before the
+ * return.
+ *
+ * Else, if a page is unbacked, -ENODATA is returned and a block may have
+ * been allocated in the cache.
+ *
+ * Because the function may want to return all of -ENOBUFS, -ENODATA and 0 in
+ * regard to different pages, the return values are prioritised in that order.
+ * Any pages submitted for reading are removed from the pages list.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+int fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
+				struct address_space *mapping,
+				struct list_head *pages,
+				unsigned *nr_pages,
+				fscache_rw_complete_t end_io_func,
+				void *context,
+				gfp_t gfp)
+{
+	if (fscache_cookie_valid(cookie))
+		return __fscache_read_or_alloc_pages(cookie, mapping, pages,
+						     nr_pages, end_io_func,
+						     context, gfp);
+	else
+		return -ENOBUFS;
+}
+
+/**
+ * fscache_alloc_page - Allocate a block in which to store a page
+ * @cookie: The cookie representing the cache object
+ * @page: The netfs page to allocate a page for
+ * @gfp: The conditions under which memory allocation should be made
+ *
+ * Request Allocation a block in the cache in which to store a netfs page
+ * without retrieving any contents from the cache.
+ *
+ * If the page is not backed by a file then -ENOBUFS will be returned and
+ * nothing more will be done, and no reservation will be made.
+ *
+ * Else, a block will be allocated if one wasn't already, and 0 will be
+ * returned
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+int fscache_alloc_page(struct fscache_cookie *cookie,
+		       struct page *page,
+		       gfp_t gfp)
+{
+	if (fscache_cookie_valid(cookie))
+		return __fscache_alloc_page(cookie, page, gfp);
+	else
+		return -ENOBUFS;
+}
+
+/**
+ * fscache_write_page - Request storage of a page in the cache
+ * @cookie: The cookie representing the cache object
+ * @page: The netfs page to store
+ * @gfp: The conditions under which memory allocation should be made
+ *
+ * Request the contents of the netfs page be written into the cache.  This
+ * request may be ignored if no cache block is currently allocated, in which
+ * case it will return -ENOBUFS.
+ *
+ * If a cache block was already allocated, a write will be initiated and 0 will
+ * be returned.  The PG_fscache_write page bit is set immediately and will then
+ * be cleared at the completion of the write to indicate the success or failure
+ * of the operation.  Note that the completion may happen before the return.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+int fscache_write_page(struct fscache_cookie *cookie,
+		       struct page *page,
+		       gfp_t gfp)
+{
+	if (fscache_cookie_valid(cookie))
+		return __fscache_write_page(cookie, page, gfp);
+	else
+		return -ENOBUFS;
+}
+
+/**
+ * fscache_uncache_page - Indicate that caching is no longer required on a page
+ * @cookie: The cookie representing the cache object
+ * @page: The netfs page that was being cached.
+ *
+ * Tell the cache that we no longer want a page to be cached and that it should
+ * remove any knowledge of the netfs page it may have.
+ *
+ * Note that this cannot cancel any outstanding I/O operations between this
+ * page and the cache.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+void fscache_uncache_page(struct fscache_cookie *cookie,
+			  struct page *page)
+{
+	if (fscache_cookie_valid(cookie))
+		__fscache_uncache_page(cookie, page);
+}
+
+/**
+ * fscache_check_page_write - Ask if a page is being writing to the cache
+ * @cookie: The cookie representing the cache object
+ * @page: The netfs page that is being cached.
+ *
+ * Ask the cache if a page is being written to the cache.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+bool fscache_check_page_write(struct fscache_cookie *cookie,
+			      struct page *page)
+{
+	if (fscache_cookie_valid(cookie))
+		return __fscache_check_page_write(cookie, page);
+	return false;
+}
+
+/**
+ * fscache_wait_on_page_write - Wait for a page to complete writing to the cache
+ * @cookie: The cookie representing the cache object
+ * @page: The netfs page that is being cached.
+ *
+ * Ask the cache to wake us up when a page is no longer being written to the
+ * cache.
+ *
+ * See Documentation/filesystems/caching/netfs-api.txt for a complete
+ * description.
+ */
+static inline
+void fscache_wait_on_page_write(struct fscache_cookie *cookie,
+				struct page *page)
+{
+	if (fscache_cookie_valid(cookie))
+		__fscache_wait_on_page_write(cookie, page);
+}
+
+#endif /* _LINUX_FSCACHE_H */
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index a7f8134..015a3d2 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -1,15 +1,18 @@
 #ifndef _LINUX_FTRACE_H
 #define _LINUX_FTRACE_H
 
-#include <linux/linkage.h>
-#include <linux/fs.h>
-#include <linux/ktime.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/module.h>
+#include <linux/trace_clock.h>
 #include <linux/kallsyms.h>
+#include <linux/linkage.h>
 #include <linux/bitops.h>
+#include <linux/module.h>
+#include <linux/ktime.h>
 #include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+
+#include <asm/ftrace.h>
 
 #ifdef CONFIG_FUNCTION_TRACER
 
@@ -95,9 +98,41 @@
 		   loff_t *ppos);
 #endif
 
+struct ftrace_func_command {
+	struct list_head	list;
+	char			*name;
+	int			(*func)(char *func, char *cmd,
+					char *params, int enable);
+};
+
 #ifdef CONFIG_DYNAMIC_FTRACE
-/* asm/ftrace.h must be defined for archs supporting dynamic ftrace */
-#include <asm/ftrace.h>
+
+int ftrace_arch_code_modify_prepare(void);
+int ftrace_arch_code_modify_post_process(void);
+
+struct seq_file;
+
+struct ftrace_probe_ops {
+	void			(*func)(unsigned long ip,
+					unsigned long parent_ip,
+					void **data);
+	int			(*callback)(unsigned long ip, void **data);
+	void			(*free)(void **data);
+	int			(*print)(struct seq_file *m,
+					 unsigned long ip,
+					 struct ftrace_probe_ops *ops,
+					 void *data);
+};
+
+extern int
+register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
+			      void *data);
+extern void
+unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
+				void *data);
+extern void
+unregister_ftrace_function_probe_func(char *glob, struct ftrace_probe_ops *ops);
+extern void unregister_ftrace_function_probe_all(char *glob);
 
 enum {
 	FTRACE_FL_FREE		= (1 << 0),
@@ -110,15 +145,23 @@
 };
 
 struct dyn_ftrace {
-	struct list_head	list;
-	unsigned long		ip; /* address of mcount call-site */
-	unsigned long		flags;
-	struct dyn_arch_ftrace	arch;
+	union {
+		unsigned long		ip; /* address of mcount call-site */
+		struct dyn_ftrace	*freelist;
+	};
+	union {
+		unsigned long		flags;
+		struct dyn_ftrace	*newlist;
+	};
+	struct dyn_arch_ftrace		arch;
 };
 
 int ftrace_force_update(void);
 void ftrace_set_filter(unsigned char *buf, int len, int reset);
 
+int register_ftrace_command(struct ftrace_func_command *cmd);
+int unregister_ftrace_command(struct ftrace_func_command *cmd);
+
 /* defined in arch */
 extern int ftrace_ip_converted(unsigned long ip);
 extern int ftrace_dyn_arch_init(void *data);
@@ -126,6 +169,10 @@
 extern void ftrace_caller(void);
 extern void ftrace_call(void);
 extern void mcount_call(void);
+
+#ifndef FTRACE_ADDR
+#define FTRACE_ADDR ((unsigned long)ftrace_caller)
+#endif
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 extern void ftrace_graph_caller(void);
 extern int ftrace_enable_ftrace_graph_caller(void);
@@ -136,7 +183,7 @@
 #endif
 
 /**
- * ftrace_make_nop - convert code into top
+ * ftrace_make_nop - convert code into nop
  * @mod: module structure if called by module load initialization
  * @rec: the mcount call site record
  * @addr: the address that the call site should be calling
@@ -181,7 +228,6 @@
  */
 extern int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr);
 
-
 /* May be defined in arch */
 extern int ftrace_arch_read_dyn_info(char *buf, int size);
 
@@ -198,6 +244,14 @@
 # define ftrace_disable_daemon()		do { } while (0)
 # define ftrace_enable_daemon()			do { } while (0)
 static inline void ftrace_release(void *start, unsigned long size) { }
+static inline int register_ftrace_command(struct ftrace_func_command *cmd)
+{
+	return -EINVAL;
+}
+static inline int unregister_ftrace_command(char *cmd_name)
+{
+	return -EINVAL;
+}
 #endif /* CONFIG_DYNAMIC_FTRACE */
 
 /* totally disable ftrace - can not re-enable after this */
@@ -233,24 +287,25 @@
 #endif
 }
 
-#ifdef CONFIG_FRAME_POINTER
-/* TODO: need to fix this for ARM */
-# define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
-# define CALLER_ADDR1 ((unsigned long)__builtin_return_address(1))
-# define CALLER_ADDR2 ((unsigned long)__builtin_return_address(2))
-# define CALLER_ADDR3 ((unsigned long)__builtin_return_address(3))
-# define CALLER_ADDR4 ((unsigned long)__builtin_return_address(4))
-# define CALLER_ADDR5 ((unsigned long)__builtin_return_address(5))
-# define CALLER_ADDR6 ((unsigned long)__builtin_return_address(6))
-#else
-# define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
-# define CALLER_ADDR1 0UL
-# define CALLER_ADDR2 0UL
-# define CALLER_ADDR3 0UL
-# define CALLER_ADDR4 0UL
-# define CALLER_ADDR5 0UL
-# define CALLER_ADDR6 0UL
-#endif
+#ifndef HAVE_ARCH_CALLER_ADDR
+# ifdef CONFIG_FRAME_POINTER
+#  define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+#  define CALLER_ADDR1 ((unsigned long)__builtin_return_address(1))
+#  define CALLER_ADDR2 ((unsigned long)__builtin_return_address(2))
+#  define CALLER_ADDR3 ((unsigned long)__builtin_return_address(3))
+#  define CALLER_ADDR4 ((unsigned long)__builtin_return_address(4))
+#  define CALLER_ADDR5 ((unsigned long)__builtin_return_address(5))
+#  define CALLER_ADDR6 ((unsigned long)__builtin_return_address(6))
+# else
+#  define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+#  define CALLER_ADDR1 0UL
+#  define CALLER_ADDR2 0UL
+#  define CALLER_ADDR3 0UL
+#  define CALLER_ADDR4 0UL
+#  define CALLER_ADDR5 0UL
+#  define CALLER_ADDR6 0UL
+# endif
+#endif /* ifndef HAVE_ARCH_CALLER_ADDR */
 
 #ifdef CONFIG_IRQSOFF_TRACER
   extern void time_hardirqs_on(unsigned long a0, unsigned long a1);
@@ -268,54 +323,6 @@
 # define trace_preempt_off(a0, a1)		do { } while (0)
 #endif
 
-#ifdef CONFIG_TRACING
-extern int ftrace_dump_on_oops;
-
-extern void tracing_start(void);
-extern void tracing_stop(void);
-extern void ftrace_off_permanent(void);
-
-extern void
-ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3);
-
-/**
- * ftrace_printk - printf formatting in the ftrace buffer
- * @fmt: the printf format for printing
- *
- * Note: __ftrace_printk is an internal function for ftrace_printk and
- *       the @ip is passed in via the ftrace_printk macro.
- *
- * This function allows a kernel developer to debug fast path sections
- * that printk is not appropriate for. By scattering in various
- * printk like tracing in the code, a developer can quickly see
- * where problems are occurring.
- *
- * This is intended as a debugging tool for the developer only.
- * Please refrain from leaving ftrace_printks scattered around in
- * your code.
- */
-# define ftrace_printk(fmt...) __ftrace_printk(_THIS_IP_, fmt)
-extern int
-__ftrace_printk(unsigned long ip, const char *fmt, ...)
-	__attribute__ ((format (printf, 2, 3)));
-extern void ftrace_dump(void);
-#else
-static inline void
-ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { }
-static inline int
-ftrace_printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
-
-static inline void tracing_start(void) { }
-static inline void tracing_stop(void) { }
-static inline void ftrace_off_permanent(void) { }
-static inline int
-ftrace_printk(const char *fmt, ...)
-{
-	return 0;
-}
-static inline void ftrace_dump(void) { }
-#endif
-
 #ifdef CONFIG_FTRACE_MCOUNT_RECORD
 extern void ftrace_init(void);
 extern void ftrace_init_module(struct module *mod,
@@ -327,36 +334,6 @@
 		   unsigned long *start, unsigned long *end) { }
 #endif
 
-enum {
-	POWER_NONE = 0,
-	POWER_CSTATE = 1,
-	POWER_PSTATE = 2,
-};
-
-struct power_trace {
-#ifdef CONFIG_POWER_TRACER
-	ktime_t			stamp;
-	ktime_t			end;
-	int			type;
-	int			state;
-#endif
-};
-
-#ifdef CONFIG_POWER_TRACER
-extern void trace_power_start(struct power_trace *it, unsigned int type,
-					unsigned int state);
-extern void trace_power_mark(struct power_trace *it, unsigned int type,
-					unsigned int state);
-extern void trace_power_end(struct power_trace *it);
-#else
-static inline void trace_power_start(struct power_trace *it, unsigned int type,
-					unsigned int state) { }
-static inline void trace_power_mark(struct power_trace *it, unsigned int type,
-					unsigned int state) { }
-static inline void trace_power_end(struct power_trace *it) { }
-#endif
-
-
 /*
  * Structure that defines an entry function trace.
  */
@@ -398,8 +375,7 @@
 extern void return_to_handler(void);
 
 extern int
-ftrace_push_return_trace(unsigned long ret, unsigned long long time,
-			 unsigned long func, int *depth);
+ftrace_push_return_trace(unsigned long ret, unsigned long func, int *depth);
 extern void
 ftrace_pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret);
 
@@ -514,6 +490,50 @@
 	return tsk->trace & TSK_TRACE_FL_GRAPH;
 }
 
+extern int ftrace_dump_on_oops;
+
 #endif /* CONFIG_TRACING */
 
+
+#ifdef CONFIG_HW_BRANCH_TRACER
+
+void trace_hw_branch(u64 from, u64 to);
+void trace_hw_branch_oops(void);
+
+#else /* CONFIG_HW_BRANCH_TRACER */
+
+static inline void trace_hw_branch(u64 from, u64 to) {}
+static inline void trace_hw_branch_oops(void) {}
+
+#endif /* CONFIG_HW_BRANCH_TRACER */
+
+/*
+ * A syscall entry in the ftrace syscalls array.
+ *
+ * @name: name of the syscall
+ * @nb_args: number of parameters it takes
+ * @types: list of types as strings
+ * @args: list of args as strings (args[i] matches types[i])
+ */
+struct syscall_metadata {
+	const char	*name;
+	int		nb_args;
+	const char	**types;
+	const char	**args;
+};
+
+#ifdef CONFIG_FTRACE_SYSCALLS
+extern void arch_init_ftrace_syscalls(void);
+extern struct syscall_metadata *syscall_nr_to_meta(int nr);
+extern void start_ftrace_syscalls(void);
+extern void stop_ftrace_syscalls(void);
+extern void ftrace_syscall_enter(struct pt_regs *regs);
+extern void ftrace_syscall_exit(struct pt_regs *regs);
+#else
+static inline void start_ftrace_syscalls(void) { }
+static inline void stop_ftrace_syscalls(void) { }
+static inline void ftrace_syscall_enter(struct pt_regs *regs) { }
+static inline void ftrace_syscall_exit(struct pt_regs *regs) { }
+#endif
+
 #endif /* _LINUX_FTRACE_H */
diff --git a/include/linux/ftrace_irq.h b/include/linux/ftrace_irq.h
index 366a054..dca7bf8 100644
--- a/include/linux/ftrace_irq.h
+++ b/include/linux/ftrace_irq.h
@@ -2,7 +2,7 @@
 #define _LINUX_FTRACE_IRQ_H
 
 
-#if defined(CONFIG_DYNAMIC_FTRACE) || defined(CONFIG_FUNCTION_GRAPH_TRACER)
+#ifdef CONFIG_FTRACE_NMI_ENTER
 extern void ftrace_nmi_enter(void);
 extern void ftrace_nmi_exit(void);
 #else
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index dd20cd7..0bbc15f 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -4,6 +4,7 @@
 #include <linux/mmzone.h>
 #include <linux/stddef.h>
 #include <linux/linkage.h>
+#include <linux/topology.h>
 
 struct vm_area_struct;
 
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
index f8328834..faa1cf8 100644
--- a/include/linux/hardirq.h
+++ b/include/linux/hardirq.h
@@ -15,55 +15,61 @@
  * - bits 0-7 are the preemption count (max preemption depth: 256)
  * - bits 8-15 are the softirq count (max # of softirqs: 256)
  *
- * The hardirq count can be overridden per architecture, the default is:
+ * The hardirq count can in theory reach the same as NR_IRQS.
+ * In reality, the number of nested IRQS is limited to the stack
+ * size as well. For archs with over 1000 IRQS it is not practical
+ * to expect that they will all nest. We give a max of 10 bits for
+ * hardirq nesting. An arch may choose to give less than 10 bits.
+ * m68k expects it to be 8.
  *
- * - bits 16-27 are the hardirq count (max # of hardirqs: 4096)
- * - ( bit 28 is the PREEMPT_ACTIVE flag. )
+ * - bits 16-25 are the hardirq count (max # of nested hardirqs: 1024)
+ * - bit 26 is the NMI_MASK
+ * - bit 28 is the PREEMPT_ACTIVE flag
  *
  * PREEMPT_MASK: 0x000000ff
  * SOFTIRQ_MASK: 0x0000ff00
- * HARDIRQ_MASK: 0x0fff0000
+ * HARDIRQ_MASK: 0x03ff0000
+ *     NMI_MASK: 0x04000000
  */
 #define PREEMPT_BITS	8
 #define SOFTIRQ_BITS	8
+#define NMI_BITS	1
+
+#define MAX_HARDIRQ_BITS 10
 
 #ifndef HARDIRQ_BITS
-#define HARDIRQ_BITS	12
-
-#ifndef MAX_HARDIRQS_PER_CPU
-#define MAX_HARDIRQS_PER_CPU NR_IRQS
+# define HARDIRQ_BITS	MAX_HARDIRQ_BITS
 #endif
 
-/*
- * The hardirq mask has to be large enough to have space for potentially
- * all IRQ sources in the system nesting on a single CPU.
- */
-#if (1 << HARDIRQ_BITS) < MAX_HARDIRQS_PER_CPU
-# error HARDIRQ_BITS is too low!
-#endif
+#if HARDIRQ_BITS > MAX_HARDIRQ_BITS
+#error HARDIRQ_BITS too high!
 #endif
 
 #define PREEMPT_SHIFT	0
 #define SOFTIRQ_SHIFT	(PREEMPT_SHIFT + PREEMPT_BITS)
 #define HARDIRQ_SHIFT	(SOFTIRQ_SHIFT + SOFTIRQ_BITS)
+#define NMI_SHIFT	(HARDIRQ_SHIFT + HARDIRQ_BITS)
 
 #define __IRQ_MASK(x)	((1UL << (x))-1)
 
 #define PREEMPT_MASK	(__IRQ_MASK(PREEMPT_BITS) << PREEMPT_SHIFT)
 #define SOFTIRQ_MASK	(__IRQ_MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT)
 #define HARDIRQ_MASK	(__IRQ_MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT)
+#define NMI_MASK	(__IRQ_MASK(NMI_BITS)     << NMI_SHIFT)
 
 #define PREEMPT_OFFSET	(1UL << PREEMPT_SHIFT)
 #define SOFTIRQ_OFFSET	(1UL << SOFTIRQ_SHIFT)
 #define HARDIRQ_OFFSET	(1UL << HARDIRQ_SHIFT)
+#define NMI_OFFSET	(1UL << NMI_SHIFT)
 
-#if PREEMPT_ACTIVE < (1 << (HARDIRQ_SHIFT + HARDIRQ_BITS))
+#if PREEMPT_ACTIVE < (1 << (NMI_SHIFT + NMI_BITS))
 #error PREEMPT_ACTIVE is too low!
 #endif
 
 #define hardirq_count()	(preempt_count() & HARDIRQ_MASK)
 #define softirq_count()	(preempt_count() & SOFTIRQ_MASK)
-#define irq_count()	(preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK))
+#define irq_count()	(preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK \
+				 | NMI_MASK))
 
 /*
  * Are we doing bottom half or hardware interrupt processing?
@@ -73,6 +79,11 @@
 #define in_softirq()		(softirq_count())
 #define in_interrupt()		(irq_count())
 
+/*
+ * Are we in NMI context?
+ */
+#define in_nmi()	(preempt_count() & NMI_MASK)
+
 #if defined(CONFIG_PREEMPT)
 # define PREEMPT_INATOMIC_BASE kernel_locked()
 # define PREEMPT_CHECK_OFFSET 1
@@ -164,20 +175,24 @@
  */
 extern void irq_exit(void);
 
-#define nmi_enter()				\
-	do {					\
-		ftrace_nmi_enter();		\
-		lockdep_off();			\
-		rcu_nmi_enter();		\
-		__irq_enter();			\
+#define nmi_enter()						\
+	do {							\
+		ftrace_nmi_enter();				\
+		BUG_ON(in_nmi());				\
+		add_preempt_count(NMI_OFFSET + HARDIRQ_OFFSET);	\
+		lockdep_off();					\
+		rcu_nmi_enter();				\
+		trace_hardirq_enter();				\
 	} while (0)
 
-#define nmi_exit()				\
-	do {					\
-		__irq_exit();			\
-		rcu_nmi_exit();			\
-		lockdep_on();			\
-		ftrace_nmi_exit();		\
+#define nmi_exit()						\
+	do {							\
+		trace_hardirq_exit();				\
+		rcu_nmi_exit();					\
+		lockdep_on();					\
+		BUG_ON(!in_nmi());				\
+		sub_preempt_count(NMI_OFFSET + HARDIRQ_OFFSET);	\
+		ftrace_nmi_exit();				\
 	} while (0)
 
 #endif /* LINUX_HARDIRQ_H */
diff --git a/include/linux/hdreg.h b/include/linux/hdreg.h
index ed21bd3..29ee287 100644
--- a/include/linux/hdreg.h
+++ b/include/linux/hdreg.h
@@ -1,68 +1,6 @@
 #ifndef _LINUX_HDREG_H
 #define _LINUX_HDREG_H
 
-#ifdef __KERNEL__
-#include <linux/ata.h>
-
-/*
- * This file contains some defines for the AT-hd-controller.
- * Various sources.
- */
-
-/* ide.c has its own port definitions in "ide.h" */
-
-#define HD_IRQ		14
-
-/* Hd controller regs. Ref: IBM AT Bios-listing */
-#define HD_DATA		0x1f0		/* _CTL when writing */
-#define HD_ERROR	0x1f1		/* see err-bits */
-#define HD_NSECTOR	0x1f2		/* nr of sectors to read/write */
-#define HD_SECTOR	0x1f3		/* starting sector */
-#define HD_LCYL		0x1f4		/* starting cylinder */
-#define HD_HCYL		0x1f5		/* high byte of starting cyl */
-#define HD_CURRENT	0x1f6		/* 101dhhhh , d=drive, hhhh=head */
-#define HD_STATUS	0x1f7		/* see status-bits */
-#define HD_FEATURE	HD_ERROR	/* same io address, read=error, write=feature */
-#define HD_PRECOMP	HD_FEATURE	/* obsolete use of this port - predates IDE */
-#define HD_COMMAND	HD_STATUS	/* same io address, read=status, write=cmd */
-
-#define HD_CMD		0x3f6		/* used for resets */
-#define HD_ALTSTATUS	0x3f6		/* same as HD_STATUS but doesn't clear irq */
-
-/* remainder is shared between hd.c, ide.c, ide-cd.c, and the hdparm utility */
-
-/* Bits of HD_STATUS */
-#define ERR_STAT		0x01
-#define INDEX_STAT		0x02
-#define ECC_STAT		0x04	/* Corrected error */
-#define DRQ_STAT		0x08
-#define SEEK_STAT		0x10
-#define SRV_STAT		0x10
-#define WRERR_STAT		0x20
-#define READY_STAT		0x40
-#define BUSY_STAT		0x80
-
-/* Bits for HD_ERROR */
-#define MARK_ERR		0x01	/* Bad address mark */
-#define ILI_ERR			0x01	/* Illegal Length Indication (ATAPI) */
-#define TRK0_ERR		0x02	/* couldn't find track 0 */
-#define EOM_ERR			0x02	/* End Of Media (ATAPI) */
-#define ABRT_ERR		0x04	/* Command aborted */
-#define MCR_ERR			0x08	/* media change request */
-#define ID_ERR			0x10	/* ID field not found */
-#define MC_ERR			0x20	/* media changed */
-#define ECC_ERR			0x40	/* Uncorrectable ECC error */
-#define BBD_ERR			0x80	/* pre-EIDE meaning:  block marked bad */
-#define ICRC_ERR		0x80	/* new meaning:  CRC error during transfer */
-#define LFS_ERR			0xf0	/* Last Failed Sense (ATAPI) */
-
-/* Bits of HD_NSECTOR */
-#define CD			0x01
-#define IO			0x02
-#define REL			0x04
-#define TAG_MASK		0xf8
-#endif /* __KERNEL__ */
-
 #include <linux/types.h>
 
 /*
@@ -191,6 +129,7 @@
 #define TASKFILE_INVALID		0x7fff
 #endif
 
+#ifndef __KERNEL__
 /* ATA/ATAPI Commands pre T13 Spec */
 #define WIN_NOP				0x00
 /*
@@ -379,6 +318,7 @@
 #define SECURITY_ERASE_UNIT		0xBD
 #define SECURITY_FREEZE_LOCK		0xBE
 #define SECURITY_DISABLE_PASSWORD	0xBF
+#endif /* __KERNEL__ */
 
 struct hd_geometry {
       unsigned char heads;
@@ -448,6 +388,7 @@
 
 #define __NEW_HD_DRIVE_ID
 
+#ifndef __KERNEL__
 /*
  * Structure returned by HDIO_GET_IDENTITY, as per ANSI NCITS ATA6 rev.1b spec.
  *
@@ -699,6 +640,7 @@
 					 *  7:0 Signature
 					 */
 };
+#endif /* __KERNEL__ */
 
 /*
  * IDE "nice" flags. These are used on a per drive basis to determine
diff --git a/include/linux/hid.h b/include/linux/hid.h
index fa8ee9c..a72876e 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -270,6 +270,7 @@
 
 #define HID_QUIRK_INVERT			0x00000001
 #define HID_QUIRK_NOTOUCH			0x00000002
+#define HID_QUIRK_IGNORE			0x00000004
 #define HID_QUIRK_NOGET				0x00000008
 #define HID_QUIRK_BADPAD			0x00000020
 #define HID_QUIRK_MULTI_INPUT			0x00000040
@@ -603,12 +604,17 @@
 	int (*open)(struct hid_device *hdev);
 	void (*close)(struct hid_device *hdev);
 
+	int (*power)(struct hid_device *hdev, int level);
+
 	int (*hidinput_input_event) (struct input_dev *idev, unsigned int type,
 			unsigned int code, int value);
 
 	int (*parse)(struct hid_device *hdev);
 };
 
+#define	PM_HINT_FULLON	1<<5
+#define PM_HINT_NORMAL	1<<1
+
 /* Applications from HID Usage Tables 4/8/99 Version 1.1 */
 /* We ignore a few input applications that are not widely used */
 #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001) || (a == 0x000d0002))
@@ -641,6 +647,7 @@
 void hid_output_report(struct hid_report *report, __u8 *data);
 struct hid_device *hid_allocate_device(void);
 int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size);
+int hid_check_keys_pressed(struct hid_device *hid);
 int hid_connect(struct hid_device *hid, unsigned int connect_mask);
 
 /**
@@ -791,21 +798,5 @@
 		__FILE__ , ## arg)
 #endif /* HID_FF */
 
-#ifdef __KERNEL__
-#ifdef CONFIG_HID_COMPAT
-#define HID_COMPAT_LOAD_DRIVER(name)	\
-/* prototype to avoid sparse warning */	\
-extern void hid_compat_##name(void);	\
-void hid_compat_##name(void) { }	\
-EXPORT_SYMBOL(hid_compat_##name)
-#else
-#define HID_COMPAT_LOAD_DRIVER(name)
-#endif /* HID_COMPAT */
-#define HID_COMPAT_CALL_DRIVER(name)	do {	\
-	extern void hid_compat_##name(void);	\
-	hid_compat_##name();			\
-} while (0)
-#endif /* __KERNEL__ */
-
 #endif
 
diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index 7ff5c55..1fcb712 100644
--- a/include/linux/highmem.h
+++ b/include/linux/highmem.h
@@ -19,8 +19,21 @@
 }
 #endif
 
-#ifdef CONFIG_HIGHMEM
+#include <asm/kmap_types.h>
 
+#if defined(CONFIG_DEBUG_HIGHMEM) && defined(CONFIG_TRACE_IRQFLAGS_SUPPORT)
+
+void debug_kmap_atomic(enum km_type type);
+
+#else
+
+static inline void debug_kmap_atomic(enum km_type type)
+{
+}
+
+#endif
+
+#ifdef CONFIG_HIGHMEM
 #include <asm/highmem.h>
 
 /* declarations for linux/mm/highmem.c */
@@ -44,8 +57,6 @@
 
 #define kunmap(page) do { (void) (page); } while (0)
 
-#include <asm/kmap_types.h>
-
 static inline void *kmap_atomic(struct page *page, enum km_type idx)
 {
 	pagefault_disable();
@@ -187,16 +198,4 @@
 	kunmap_atomic(vto, KM_USER1);
 }
 
-#if defined(CONFIG_DEBUG_HIGHMEM) && defined(CONFIG_TRACE_IRQFLAGS_SUPPORT)
-
-void debug_kmap_atomic(enum km_type type);
-
-#else
-
-static inline void debug_kmap_atomic(enum km_type type)
-{
-}
-
-#endif
-
 #endif /* _LINUX_HIGHMEM_H */
diff --git a/include/linux/i2c/twl4030.h b/include/linux/i2c/twl4030.h
index 8137f66..0dc80ef 100644
--- a/include/linux/i2c/twl4030.h
+++ b/include/linux/i2c/twl4030.h
@@ -218,6 +218,53 @@
 
 /*----------------------------------------------------------------------*/
 
+/* Power bus message definitions */
+
+#define DEV_GRP_NULL		0x0
+#define DEV_GRP_P1		0x1
+#define DEV_GRP_P2		0x2
+#define DEV_GRP_P3		0x4
+
+#define RES_GRP_RES		0x0
+#define RES_GRP_PP		0x1
+#define RES_GRP_RC		0x2
+#define RES_GRP_PP_RC		0x3
+#define RES_GRP_PR		0x4
+#define RES_GRP_PP_PR		0x5
+#define RES_GRP_RC_PR		0x6
+#define RES_GRP_ALL		0x7
+
+#define RES_TYPE2_R0		0x0
+
+#define RES_TYPE_ALL		0x7
+
+#define RES_STATE_WRST		0xF
+#define RES_STATE_ACTIVE	0xE
+#define RES_STATE_SLEEP		0x8
+#define RES_STATE_OFF		0x0
+
+/*
+ * Power Bus Message Format ... these can be sent individually by Linux,
+ * but are usually part of downloaded scripts that are run when various
+ * power events are triggered.
+ *
+ *  Broadcast Message (16 Bits):
+ *    DEV_GRP[15:13] MT[12]  RES_GRP[11:9]  RES_TYPE2[8:7] RES_TYPE[6:4]
+ *    RES_STATE[3:0]
+ *
+ *  Singular Message (16 Bits):
+ *    DEV_GRP[15:13] MT[12]  RES_ID[11:4]  RES_STATE[3:0]
+ */
+
+#define MSG_BROADCAST(devgrp, grp, type, type2, state) \
+	( (devgrp) << 13 | 1 << 12 | (grp) << 9 | (type2) << 7 \
+	| (type) << 4 | (state))
+
+#define MSG_SINGULAR(devgrp, id, state) \
+	((devgrp) << 13 | 0 << 12 | (id) << 4 | (state))
+
+/*----------------------------------------------------------------------*/
+
 struct twl4030_bci_platform_data {
 	int *battery_tmp_tbl;
 	unsigned int tblsize;
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index 1d6c71d..77214ea 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -123,7 +123,7 @@
 #define ecap_eim_support(e)	((e >> 4) & 0x1)
 #define ecap_ir_support(e)	((e >> 3) & 0x1)
 #define ecap_max_handle_mask(e) ((e >> 20) & 0xf)
-
+#define ecap_sc_support(e)	((e >> 7) & 0x1) /* Snooping Control */
 
 /* IOTLB_REG */
 #define DMA_TLB_FLUSH_GRANU_OFFSET  60
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index c68bffd..ce2c07d 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -278,6 +278,11 @@
 	NR_SOFTIRQS
 };
 
+/* map softirq index to softirq name. update 'softirq_to_name' in
+ * kernel/softirq.c when adding a new softirq.
+ */
+extern char *softirq_to_name[NR_SOFTIRQS];
+
 /* softirq mask and active fields moved to irq_cpustat_t in
  * asm/hardirq.h to get better cache usage.  KAO
  */
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 8a7bfb1..3af4ffd 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -21,6 +21,7 @@
 
 #define IOMMU_READ	(1)
 #define IOMMU_WRITE	(2)
+#define IOMMU_CACHE	(4) /* DMA cache coherency */
 
 struct device;
 
@@ -28,6 +29,8 @@
 	void *priv;
 };
 
+#define IOMMU_CAP_CACHE_COHERENCY	0x1
+
 struct iommu_ops {
 	int (*domain_init)(struct iommu_domain *domain);
 	void (*domain_destroy)(struct iommu_domain *domain);
@@ -39,6 +42,8 @@
 		      size_t size);
 	phys_addr_t (*iova_to_phys)(struct iommu_domain *domain,
 				    unsigned long iova);
+	int (*domain_has_cap)(struct iommu_domain *domain,
+			      unsigned long cap);
 };
 
 #ifdef CONFIG_IOMMU_API
@@ -57,6 +62,8 @@
 			      size_t size);
 extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain,
 				      unsigned long iova);
+extern int iommu_domain_has_cap(struct iommu_domain *domain,
+				unsigned long cap);
 
 #else /* CONFIG_IOMMU_API */
 
@@ -107,6 +114,12 @@
 	return 0;
 }
 
+static inline int domain_has_cap(struct iommu_domain *domain,
+				 unsigned long cap)
+{
+	return 0;
+}
+
 #endif /* CONFIG_IOMMU_API */
 
 #endif /* __LINUX_IOMMU_H */
diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h
index 74bde13..b02a3f1 100644
--- a/include/linux/irqflags.h
+++ b/include/linux/irqflags.h
@@ -24,8 +24,8 @@
 # define trace_softirqs_enabled(p)	((p)->softirqs_enabled)
 # define trace_hardirq_enter()	do { current->hardirq_context++; } while (0)
 # define trace_hardirq_exit()	do { current->hardirq_context--; } while (0)
-# define trace_softirq_enter()	do { current->softirq_context++; } while (0)
-# define trace_softirq_exit()	do { current->softirq_context--; } while (0)
+# define lockdep_softirq_enter()	do { current->softirq_context++; } while (0)
+# define lockdep_softirq_exit()	do { current->softirq_context--; } while (0)
 # define INIT_TRACE_IRQFLAGS	.softirqs_enabled = 1,
 #else
 # define trace_hardirqs_on()		do { } while (0)
@@ -38,8 +38,8 @@
 # define trace_softirqs_enabled(p)	0
 # define trace_hardirq_enter()		do { } while (0)
 # define trace_hardirq_exit()		do { } while (0)
-# define trace_softirq_enter()		do { } while (0)
-# define trace_softirq_exit()		do { } while (0)
+# define lockdep_softirq_enter()	do { } while (0)
+# define lockdep_softirq_exit()		do { } while (0)
 # define INIT_TRACE_IRQFLAGS
 #endif
 
diff --git a/include/linux/jbd.h b/include/linux/jbd.h
index 64246dc..53ae439 100644
--- a/include/linux/jbd.h
+++ b/include/linux/jbd.h
@@ -35,7 +35,7 @@
 #define journal_oom_retry 1
 
 /*
- * Define JBD_PARANIOD_IOFAIL to cause a kernel BUG() if ext3 finds
+ * Define JBD_PARANOID_IOFAIL to cause a kernel BUG() if ext3 finds
  * certain classes of error which can occur due to failed IOs.  Under
  * normal use we want ext3 to continue after such errors, because
  * hardware _can_ fail, but for debugging purposes when running tests on
@@ -552,6 +552,11 @@
 	 */
 	int t_handle_count;
 
+	/*
+	 * This transaction is being forced and some process is
+	 * waiting for it to finish.
+	 */
+	int t_synchronous_commit:1;
 };
 
 /**
diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h
index f3fe343..7922742 100644
--- a/include/linux/kallsyms.h
+++ b/include/linux/kallsyms.h
@@ -13,10 +13,17 @@
 #define KSYM_SYMBOL_LEN (sizeof("%s+%#lx/%#lx [%s]") + (KSYM_NAME_LEN - 1) + \
 			 2*(BITS_PER_LONG*3/10) + (MODULE_NAME_LEN - 1) + 1)
 
+struct module;
+
 #ifdef CONFIG_KALLSYMS
 /* Lookup the address for a symbol. Returns 0 if not found. */
 unsigned long kallsyms_lookup_name(const char *name);
 
+/* Call a function on each kallsyms symbol in the core kernel */
+int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
+				      unsigned long),
+			    void *data);
+
 extern int kallsyms_lookup_size_offset(unsigned long addr,
 				  unsigned long *symbolsize,
 				  unsigned long *offset);
@@ -43,6 +50,14 @@
 	return 0;
 }
 
+static inline int kallsyms_on_each_symbol(int (*fn)(void *, const char *,
+						    struct module *,
+						    unsigned long),
+					  void *data)
+{
+	return 0;
+}
+
 static inline int kallsyms_lookup_size_offset(unsigned long addr,
 					      unsigned long *symbolsize,
 					      unsigned long *offset)
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 556d781..d9e75ec 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -242,6 +242,19 @@
 extern int printk_ratelimit(void);
 extern bool printk_timed_ratelimit(unsigned long *caller_jiffies,
 				   unsigned int interval_msec);
+
+/*
+ * Print a one-time message (analogous to WARN_ONCE() et al):
+ */
+#define printk_once(x...) ({			\
+	static int __print_once = 1;		\
+						\
+	if (__print_once) {			\
+		__print_once = 0;		\
+		printk(x);			\
+	}					\
+})
+
 void log_buf_kexec_setup(void);
 #else
 static inline int vprintk(const char *s, va_list args)
@@ -254,6 +267,10 @@
 static inline bool printk_timed_ratelimit(unsigned long *caller_jiffies, \
 					  unsigned int interval_msec)	\
 		{ return false; }
+
+/* No effect, but we still get type checking even in the !PRINTK case: */
+#define printk_once(x...) printk(x)
+
 static inline void log_buf_kexec_setup(void)
 {
 }
@@ -375,6 +392,139 @@
 #endif
 
 /*
+ * General tracing related utility functions - trace_printk(),
+ * tracing_on/tracing_off and tracing_start()/tracing_stop
+ *
+ * Use tracing_on/tracing_off when you want to quickly turn on or off
+ * tracing. It simply enables or disables the recording of the trace events.
+ * This also corresponds to the user space debugfs/tracing/tracing_on
+ * file, which gives a means for the kernel and userspace to interact.
+ * Place a tracing_off() in the kernel where you want tracing to end.
+ * From user space, examine the trace, and then echo 1 > tracing_on
+ * to continue tracing.
+ *
+ * tracing_stop/tracing_start has slightly more overhead. It is used
+ * by things like suspend to ram where disabling the recording of the
+ * trace is not enough, but tracing must actually stop because things
+ * like calling smp_processor_id() may crash the system.
+ *
+ * Most likely, you want to use tracing_on/tracing_off.
+ */
+#ifdef CONFIG_RING_BUFFER
+void tracing_on(void);
+void tracing_off(void);
+/* trace_off_permanent stops recording with no way to bring it back */
+void tracing_off_permanent(void);
+int tracing_is_on(void);
+#else
+static inline void tracing_on(void) { }
+static inline void tracing_off(void) { }
+static inline void tracing_off_permanent(void) { }
+static inline int tracing_is_on(void) { return 0; }
+#endif
+#ifdef CONFIG_TRACING
+extern void tracing_start(void);
+extern void tracing_stop(void);
+extern void ftrace_off_permanent(void);
+
+extern void
+ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3);
+
+static inline void __attribute__ ((format (printf, 1, 2)))
+____trace_printk_check_format(const char *fmt, ...)
+{
+}
+#define __trace_printk_check_format(fmt, args...)			\
+do {									\
+	if (0)								\
+		____trace_printk_check_format(fmt, ##args);		\
+} while (0)
+
+/**
+ * trace_printk - printf formatting in the ftrace buffer
+ * @fmt: the printf format for printing
+ *
+ * Note: __trace_printk is an internal function for trace_printk and
+ *       the @ip is passed in via the trace_printk macro.
+ *
+ * This function allows a kernel developer to debug fast path sections
+ * that printk is not appropriate for. By scattering in various
+ * printk like tracing in the code, a developer can quickly see
+ * where problems are occurring.
+ *
+ * This is intended as a debugging tool for the developer only.
+ * Please refrain from leaving trace_printks scattered around in
+ * your code.
+ */
+
+#define trace_printk(fmt, args...)					\
+do {									\
+	__trace_printk_check_format(fmt, ##args);			\
+	if (__builtin_constant_p(fmt)) {				\
+		static const char *trace_printk_fmt			\
+		  __attribute__((section("__trace_printk_fmt"))) =	\
+			__builtin_constant_p(fmt) ? fmt : NULL;		\
+									\
+		__trace_bprintk(_THIS_IP_, trace_printk_fmt, ##args);	\
+	} else								\
+		__trace_printk(_THIS_IP_, fmt, ##args);		\
+} while (0)
+
+extern int
+__trace_bprintk(unsigned long ip, const char *fmt, ...)
+	__attribute__ ((format (printf, 2, 3)));
+
+extern int
+__trace_printk(unsigned long ip, const char *fmt, ...)
+	__attribute__ ((format (printf, 2, 3)));
+
+/*
+ * The double __builtin_constant_p is because gcc will give us an error
+ * if we try to allocate the static variable to fmt if it is not a
+ * constant. Even with the outer if statement.
+ */
+#define ftrace_vprintk(fmt, vargs)					\
+do {									\
+	if (__builtin_constant_p(fmt)) {				\
+		static const char *trace_printk_fmt			\
+		  __attribute__((section("__trace_printk_fmt"))) =	\
+			__builtin_constant_p(fmt) ? fmt : NULL;		\
+									\
+		__ftrace_vbprintk(_THIS_IP_, trace_printk_fmt, vargs);	\
+	} else								\
+		__ftrace_vprintk(_THIS_IP_, fmt, vargs);		\
+} while (0)
+
+extern int
+__ftrace_vbprintk(unsigned long ip, const char *fmt, va_list ap);
+
+extern int
+__ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap);
+
+extern void ftrace_dump(void);
+#else
+static inline void
+ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { }
+static inline int
+trace_printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
+
+static inline void tracing_start(void) { }
+static inline void tracing_stop(void) { }
+static inline void ftrace_off_permanent(void) { }
+static inline int
+trace_printk(const char *fmt, ...)
+{
+	return 0;
+}
+static inline int
+ftrace_vprintk(const char *fmt, va_list ap)
+{
+	return 0;
+}
+static inline void ftrace_dump(void) { }
+#endif /* CONFIG_TRACING */
+
+/*
  *      Display an IP address in readable format.
  */
 
diff --git a/include/linux/kmod.h b/include/linux/kmod.h
index 92213a9..d5fa565 100644
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -29,10 +29,15 @@
 #ifdef CONFIG_MODULES
 /* modprobe exit status on success, -ve on error.  Return value
  * usually useless though. */
-extern int request_module(const char * name, ...) __attribute__ ((format (printf, 1, 2)));
-#define try_then_request_module(x, mod...) ((x) ?: (request_module(mod), (x)))
+extern int __request_module(bool wait, const char *name, ...) \
+	__attribute__((format(printf, 2, 3)));
+#define request_module(mod...) __request_module(true, mod)
+#define request_module_nowait(mod...) __request_module(false, mod)
+#define try_then_request_module(x, mod...) \
+	((x) ?: (__request_module(false, mod), (x)))
 #else
-static inline int request_module(const char * name, ...) { return -ENOSYS; }
+static inline int request_module(const char *name, ...) { return -ENOSYS; }
+static inline int request_module_nowait(const char *name, ...) { return -ENOSYS; }
 #define try_then_request_module(x, mod...) (x)
 #endif
 
diff --git a/include/linux/leds-bd2802.h b/include/linux/leds-bd2802.h
new file mode 100644
index 0000000..42f854a
--- /dev/null
+++ b/include/linux/leds-bd2802.h
@@ -0,0 +1,26 @@
+/*
+ * leds-bd2802.h - RGB LED Driver
+ *
+ * Copyright (C) 2009 Samsung Electronics
+ * Kim Kyuwon <q1.kim@samsung.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.
+ *
+ * Datasheet: http://www.rohm.com/products/databook/driver/pdf/bd2802gu-e.pdf
+ *
+ */
+#ifndef _LEDS_BD2802_H_
+#define _LEDS_BD2802_H_
+
+struct bd2802_led_platform_data{
+	int	reset_gpio;
+	u8	rgb_time;
+};
+
+#define RGB_TIME(slopedown, slopeup, waveform) \
+	((slopedown) << 6 | (slopeup) << 4 | (waveform))
+
+#endif /* _LEDS_BD2802_H_ */
+
diff --git a/include/linux/leds.h b/include/linux/leds.h
index 24489da..376fe07 100644
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -30,6 +30,7 @@
 struct led_classdev {
 	const char		*name;
 	int			 brightness;
+	int			 max_brightness;
 	int			 flags;
 
 	/* Lower 16 bits reflect status */
@@ -140,7 +141,8 @@
 	const char *name;
 	const char *default_trigger;
 	unsigned 	gpio;
-	u8 		active_low;
+	u8 		active_low : 1;
+	u8		retain_state_suspended : 1;
 };
 
 struct gpio_led_platform_data {
diff --git a/include/linux/leds_pwm.h b/include/linux/leds_pwm.h
new file mode 100644
index 0000000..33a0711
--- /dev/null
+++ b/include/linux/leds_pwm.h
@@ -0,0 +1,21 @@
+/*
+ * PWM LED driver data - see drivers/leds/leds-pwm.c
+ */
+#ifndef __LINUX_LEDS_PWM_H
+#define __LINUX_LEDS_PWM_H
+
+struct led_pwm {
+	const char	*name;
+	const char	*default_trigger;
+	unsigned	pwm_id;
+	u8 		active_low;
+	unsigned 	max_brightness;
+	unsigned	pwm_period_ns;
+};
+
+struct led_pwm_platform_data {
+	int			num_leds;
+	struct led_pwm	*leds;
+};
+
+#endif
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 76262d8..b450a26 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -379,7 +379,7 @@
 	ATA_HORKAGE_BRIDGE_OK	= (1 << 10),	/* no bridge limits */
 	ATA_HORKAGE_ATAPI_MOD16_DMA = (1 << 11), /* use ATAPI DMA for commands
 						    not multiple of 16 bytes */
-	ATA_HORKAGE_FIRMWARE_WARN = (1 << 12),	/* firwmare update warning */
+	ATA_HORKAGE_FIRMWARE_WARN = (1 << 12),	/* firmware update warning */
 	ATA_HORKAGE_1_5_GBPS	= (1 << 13),	/* force 1.5 Gbps */
 
 	 /* DMA mask for user DMA control: User visible values; DO NOT
diff --git a/include/linux/memory.h b/include/linux/memory.h
index 42767d1..37fa19b 100644
--- a/include/linux/memory.h
+++ b/include/linux/memory.h
@@ -110,4 +110,10 @@
 			 off_t offset, size_t count);
 };
 
+/*
+ * Kernel text modification mutex, used for code patching. Users of this lock
+ * can sleep.
+ */
+extern struct mutex text_mutex;
+
 #endif /* _LINUX_MEMORY_H_ */
diff --git a/include/linux/mfd/ds1wm.h b/include/linux/mfd/ds1wm.h
new file mode 100644
index 0000000..be469a3
--- /dev/null
+++ b/include/linux/mfd/ds1wm.h
@@ -0,0 +1,6 @@
+/* MFD cell driver data for the DS1WM driver */
+
+struct ds1wm_driver_data {
+	int active_high;
+	int clock_rate;
+};
diff --git a/include/linux/mfd/htc-pasic3.h b/include/linux/mfd/htc-pasic3.h
index b4294f1..3d3ed67 100644
--- a/include/linux/mfd/htc-pasic3.h
+++ b/include/linux/mfd/htc-pasic3.h
@@ -48,7 +48,6 @@
 
 struct pasic3_platform_data {
 	struct pasic3_leds_machinfo *led_pdata;
-	unsigned int                 bus_shift;
 	unsigned int                 clock_rate;
 };
 
diff --git a/include/linux/mfd/wm8350/core.h b/include/linux/mfd/wm8350/core.h
index 980669d..42cca67 100644
--- a/include/linux/mfd/wm8350/core.h
+++ b/include/linux/mfd/wm8350/core.h
@@ -640,9 +640,11 @@
  *
  * @init: Function called during driver initialisation.  Should be
  *        used by the platform to configure GPIO functions and similar.
+ * @irq_high: Set if WM8350 IRQ is active high.
  */
 struct wm8350_platform_data {
 	int (*init)(struct wm8350 *wm8350);
+	int irq_high;
 };
 
 
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 4e45725..3e7615e 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -192,5 +192,10 @@
 	wake_up_process(host->sdio_irq_thread);
 }
 
+struct regulator;
+
+int mmc_regulator_get_ocrmask(struct regulator *supply);
+int mmc_regulator_set_ocr(struct regulator *supply, unsigned short vdd_bit);
+
 #endif
 
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 26ef240..186ec6a 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -764,12 +764,6 @@
 extern char numa_zonelist_order[];
 #define NUMA_ZONELIST_ORDER_LEN 16	/* string buffer size */
 
-#include <linux/topology.h>
-/* Returns the number of the current Node. */
-#ifndef numa_node_id
-#define numa_node_id()		(cpu_to_node(raw_smp_processor_id()))
-#endif
-
 #ifndef CONFIG_NEED_MULTIPLE_NODES
 
 extern struct pglist_data contig_page_data;
diff --git a/include/linux/module.h b/include/linux/module.h
index 145a755..627ac08 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -248,6 +248,10 @@
 	const unsigned long *crcs;
 	unsigned int num_syms;
 
+	/* Kernel parameters. */
+	struct kernel_param *kp;
+	unsigned int num_kp;
+
 	/* GPL-only exported symbols. */
 	unsigned int num_gpl_syms;
 	const struct kernel_symbol *gpl_syms;
@@ -329,6 +333,11 @@
 	unsigned int num_tracepoints;
 #endif
 
+#ifdef CONFIG_TRACING
+	const char **trace_bprintk_fmt_start;
+	unsigned int num_trace_bprintk_fmt;
+#endif
+
 #ifdef CONFIG_MODULE_UNLOAD
 	/* What modules depend on me? */
 	struct list_head modules_which_use_me;
@@ -350,6 +359,8 @@
 #define MODULE_ARCH_INIT {}
 #endif
 
+extern struct mutex module_mutex;
+
 /* FIXME: It'd be nice to isolate modules during init, too, so they
    aren't used before they (may) fail.  But presently too much code
    (IDE & SCSI) require entry into the module during init.*/
@@ -358,10 +369,10 @@
 	return mod->state != MODULE_STATE_GOING;
 }
 
-/* Is this address in a module? (second is with no locks, for oops) */
-struct module *module_text_address(unsigned long addr);
 struct module *__module_text_address(unsigned long addr);
-int is_module_address(unsigned long addr);
+struct module *__module_address(unsigned long addr);
+bool is_module_address(unsigned long addr);
+bool is_module_text_address(unsigned long addr);
 
 static inline int within_module_core(unsigned long addr, struct module *mod)
 {
@@ -375,6 +386,31 @@
 	       addr < (unsigned long)mod->module_init + mod->init_size;
 }
 
+/* Search for module by name: must hold module_mutex. */
+struct module *find_module(const char *name);
+
+struct symsearch {
+	const struct kernel_symbol *start, *stop;
+	const unsigned long *crcs;
+	enum {
+		NOT_GPL_ONLY,
+		GPL_ONLY,
+		WILL_BE_GPL_ONLY,
+	} licence;
+	bool unused;
+};
+
+/* Search for an exported symbol by name. */
+const struct kernel_symbol *find_symbol(const char *name,
+					struct module **owner,
+					const unsigned long **crc,
+					bool gplok,
+					bool warn);
+
+/* Walk the exported symbol table */
+bool each_symbol(bool (*fn)(const struct symsearch *arr, struct module *owner,
+			    unsigned int symnum, void *data), void *data);
+
 /* Returns 0 and fills in value, defined and namebuf, or -ERANGE if
    symnum out of range. */
 int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
@@ -383,6 +419,10 @@
 /* Look for this name: can be of form module:name. */
 unsigned long module_kallsyms_lookup_name(const char *name);
 
+int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
+					     struct module *, unsigned long),
+				   void *data);
+
 extern void __module_put_and_exit(struct module *mod, long code)
 	__attribute__((noreturn));
 #define module_put_and_exit(code) __module_put_and_exit(THIS_MODULE, code);
@@ -444,6 +484,7 @@
 #define symbol_put_addr(p) do { } while(0)
 
 #endif /* CONFIG_MODULE_UNLOAD */
+int use_module(struct module *a, struct module *b);
 
 /* This is a #define so the string doesn't get put in every .o file */
 #define module_name(mod)			\
@@ -490,21 +531,24 @@
 	return NULL;
 }
 
-/* Is this address in a module? */
-static inline struct module *module_text_address(unsigned long addr)
+static inline struct module *__module_address(unsigned long addr)
 {
 	return NULL;
 }
 
-/* Is this address in a module? (don't take a lock, we're oopsing) */
 static inline struct module *__module_text_address(unsigned long addr)
 {
 	return NULL;
 }
 
-static inline int is_module_address(unsigned long addr)
+static inline bool is_module_address(unsigned long addr)
 {
-	return 0;
+	return false;
+}
+
+static inline bool is_module_text_address(unsigned long addr)
+{
+	return false;
 }
 
 /* Get/put a kernel symbol (calls should be symmetric) */
@@ -559,6 +603,14 @@
 	return 0;
 }
 
+static inline int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
+							   struct module *,
+							   unsigned long),
+						 void *data)
+{
+	return 0;
+}
+
 static inline int register_module_notifier(struct notifier_block * nb)
 {
 	/* no events will happen anyway, so this can always succeed */
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
index e4af339..a4f0b93 100644
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -138,6 +138,16 @@
 		      unsigned num,
 		      int (*unknown)(char *param, char *val));
 
+/* Called by module remove. */
+#ifdef CONFIG_SYSFS
+extern void destroy_params(const struct kernel_param *params, unsigned num);
+#else
+static inline void destroy_params(const struct kernel_param *params,
+				  unsigned num)
+{
+}
+#endif /* !CONFIG_SYSFS */
+
 /* All the helper functions */
 /* The macros to do compile-time type checking stolen from Jakub
    Jelinek, who IIRC came up with this idea for the 2.4 module init code. */
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index bde2557..fdffb41 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -185,6 +185,9 @@
 	fmode_t			 delegation_state;
 	struct rw_semaphore	rwsem;
 #endif /* CONFIG_NFS_V4*/
+#ifdef CONFIG_NFS_FSCACHE
+	struct fscache_cookie	*fscache;
+#endif
 	struct inode		vfs_inode;
 };
 
@@ -207,6 +210,8 @@
 #define NFS_INO_ACL_LRU_SET	(2)		/* Inode is on the LRU list */
 #define NFS_INO_MOUNTPOINT	(3)		/* inode is remote mountpoint */
 #define NFS_INO_FLUSHING	(4)		/* inode is flushing out data */
+#define NFS_INO_FSCACHE		(5)		/* inode can be cached by FS-Cache */
+#define NFS_INO_FSCACHE_LOCK	(6)		/* FS-Cache cookie management lock */
 
 static inline struct nfs_inode *NFS_I(const struct inode *inode)
 {
@@ -260,6 +265,11 @@
 	return test_bit(NFS_INO_STALE, &NFS_I(inode)->flags);
 }
 
+static inline int NFS_FSCACHE(const struct inode *inode)
+{
+	return test_bit(NFS_INO_FSCACHE, &NFS_I(inode)->flags);
+}
+
 static inline __u64 NFS_FILEID(const struct inode *inode)
 {
 	return NFS_I(inode)->fileid;
@@ -506,6 +516,8 @@
 		struct list_head *, unsigned);
 extern int  nfs_readpage_result(struct rpc_task *, struct nfs_read_data *);
 extern void nfs_readdata_release(void *data);
+extern int  nfs_readpage_async(struct nfs_open_context *, struct inode *,
+			       struct page *);
 
 /*
  * Allocate nfs_read_data structures
@@ -583,6 +595,7 @@
 #define NFSDBG_CALLBACK		0x0100
 #define NFSDBG_CLIENT		0x0200
 #define NFSDBG_MOUNT		0x0400
+#define NFSDBG_FSCACHE		0x0800
 #define NFSDBG_ALL		0xFFFF
 
 #ifdef __KERNEL__
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 29b1e40..6ad7594 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -64,6 +64,10 @@
 	char			cl_ipaddr[48];
 	unsigned char		cl_id_uniquifier;
 #endif
+
+#ifdef CONFIG_NFS_FSCACHE
+	struct fscache_cookie	*fscache;	/* client index cache cookie */
+#endif
 };
 
 /*
@@ -96,12 +100,19 @@
 	unsigned int		acdirmin;
 	unsigned int		acdirmax;
 	unsigned int		namelen;
+	unsigned int		options;	/* extra options enabled by mount */
+#define NFS_OPTION_FSCACHE	0x00000001	/* - local caching enabled */
 
 	struct nfs_fsid		fsid;
 	__u64			maxfilesize;	/* maximum file size */
 	unsigned long		mount_time;	/* when this fs was mounted */
 	dev_t			s_dev;		/* superblock dev numbers */
 
+#ifdef CONFIG_NFS_FSCACHE
+	struct nfs_fscache_key	*fscache_key;	/* unique key for superblock */
+	struct fscache_cookie	*fscache;	/* superblock cookie */
+#endif
+
 #ifdef CONFIG_NFS_V4
 	u32			attr_bitmask[2];/* V4 bitmask representing the set
 						   of attributes supported on this
diff --git a/include/linux/nfs_iostat.h b/include/linux/nfs_iostat.h
index 1cb9a3f..68b10f5 100644
--- a/include/linux/nfs_iostat.h
+++ b/include/linux/nfs_iostat.h
@@ -116,4 +116,16 @@
 	__NFSIOS_COUNTSMAX,
 };
 
+/*
+ * NFS local caching servicing counters
+ */
+enum nfs_stat_fscachecounters {
+	NFSIOS_FSCACHE_PAGES_READ_OK,
+	NFSIOS_FSCACHE_PAGES_READ_FAIL,
+	NFSIOS_FSCACHE_PAGES_WRITTEN_OK,
+	NFSIOS_FSCACHE_PAGES_WRITTEN_FAIL,
+	NFSIOS_FSCACHE_PAGES_UNCACHED,
+	__NFSIOS_FSCACHEMAX,
+};
+
 #endif	/* _LINUX_NFS_IOSTAT */
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 61df177..62214c7 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -82,6 +82,7 @@
 	PG_arch_1,
 	PG_reserved,
 	PG_private,		/* If pagecache, has fs-private data */
+	PG_private_2,		/* If pagecache, has fs aux data */
 	PG_writeback,		/* Page is under writeback */
 #ifdef CONFIG_PAGEFLAGS_EXTENDED
 	PG_head,		/* A head page */
@@ -108,6 +109,12 @@
 	/* Filesystems */
 	PG_checked = PG_owner_priv_1,
 
+	/* Two page bits are conscripted by FS-Cache to maintain local caching
+	 * state.  These bits are set on pages belonging to the netfs's inodes
+	 * when those inodes are being locally cached.
+	 */
+	PG_fscache = PG_private_2,	/* page backed by cache */
+
 	/* XEN */
 	PG_pinned = PG_owner_priv_1,
 	PG_savepinned = PG_dirty,
@@ -182,7 +189,7 @@
 
 struct page;	/* forward declaration */
 
-TESTPAGEFLAG(Locked, locked)
+TESTPAGEFLAG(Locked, locked) TESTSETFLAG(Locked, locked)
 PAGEFLAG(Error, error)
 PAGEFLAG(Referenced, referenced) TESTCLEARFLAG(Referenced, referenced)
 PAGEFLAG(Dirty, dirty) TESTSCFLAG(Dirty, dirty) __CLEARPAGEFLAG(Dirty, dirty)
@@ -194,8 +201,6 @@
 PAGEFLAG(Pinned, pinned) TESTSCFLAG(Pinned, pinned)	/* Xen */
 PAGEFLAG(SavePinned, savepinned);			/* Xen */
 PAGEFLAG(Reserved, reserved) __CLEARPAGEFLAG(Reserved, reserved)
-PAGEFLAG(Private, private) __CLEARPAGEFLAG(Private, private)
-	__SETPAGEFLAG(Private, private)
 PAGEFLAG(SwapBacked, swapbacked) __CLEARPAGEFLAG(SwapBacked, swapbacked)
 
 __PAGEFLAG(SlobPage, slob_page)
@@ -205,6 +210,16 @@
 __PAGEFLAG(SlubDebug, slub_debug)
 
 /*
+ * Private page markings that may be used by the filesystem that owns the page
+ * for its own purposes.
+ * - PG_private and PG_private_2 cause releasepage() and co to be invoked
+ */
+PAGEFLAG(Private, private) __SETPAGEFLAG(Private, private)
+	__CLEARPAGEFLAG(Private, private)
+PAGEFLAG(Private2, private_2) TESTSCFLAG(Private2, private_2)
+PAGEFLAG(OwnerPriv1, owner_priv_1) TESTCLEARFLAG(OwnerPriv1, owner_priv_1)
+
+/*
  * Only test-and-set exist for PG_writeback.  The unconditional operators are
  * risky: they bypass page accounting.
  */
@@ -384,9 +399,10 @@
  * these flags set.  It they are, there is a problem.
  */
 #define PAGE_FLAGS_CHECK_AT_FREE \
-	(1 << PG_lru   | 1 << PG_private   | 1 << PG_locked | \
-	 1 << PG_buddy | 1 << PG_writeback | 1 << PG_reserved | \
-	 1 << PG_slab  | 1 << PG_swapcache | 1 << PG_active | \
+	(1 << PG_lru	 | 1 << PG_locked    | \
+	 1 << PG_private | 1 << PG_private_2 | \
+	 1 << PG_buddy	 | 1 << PG_writeback | 1 << PG_reserved | \
+	 1 << PG_slab	 | 1 << PG_swapcache | 1 << PG_active | \
 	 __PG_UNEVICTABLE | __PG_MLOCKED)
 
 /*
@@ -397,4 +413,16 @@
 #define PAGE_FLAGS_CHECK_AT_PREP	((1 << NR_PAGEFLAGS) - 1)
 
 #endif /* !__GENERATING_BOUNDS_H */
+
+/**
+ * page_has_private - Determine if page has private stuff
+ * @page: The page to be checked
+ *
+ * Determine if a page has private stuff, indicating that release routines
+ * should be invoked upon it.
+ */
+#define page_has_private(page)			\
+	((page)->flags & ((1 << PG_private) |	\
+			  (1 << PG_private_2)))
+
 #endif	/* PAGE_FLAGS_H */
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 076a7dc6..34da523 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -384,6 +384,11 @@
 extern void end_page_writeback(struct page *page);
 
 /*
+ * Add an arbitrary waiter to a page's wait queue
+ */
+extern void add_page_wait_queue(struct page *page, wait_queue_t *waiter);
+
+/*
  * Fault a userspace page into pagetables.  Return non-zero on a fault.
  *
  * This assumes that two userspace pages are always sufficient.  That's
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 8ff25e0..594c494 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -73,6 +73,8 @@
 	POWER_SUPPLY_PROP_VOLTAGE_AVG,
 	POWER_SUPPLY_PROP_CURRENT_NOW,
 	POWER_SUPPLY_PROP_CURRENT_AVG,
+	POWER_SUPPLY_PROP_POWER_NOW,
+	POWER_SUPPLY_PROP_POWER_AVG,
 	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
 	POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN,
 	POWER_SUPPLY_PROP_CHARGE_FULL,
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index 3945f80..7c77575 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -28,4 +28,4 @@
  */
 void pwm_disable(struct pwm_device *pwm);
 
-#endif /* __ASM_ARCH_PWM_H */
+#endif /* __LINUX_PWM_H */
diff --git a/include/linux/raid/linear.h b/include/linux/raid/linear.h
deleted file mode 100644
index f38b9c5..0000000
--- a/include/linux/raid/linear.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef _LINEAR_H
-#define _LINEAR_H
-
-#include <linux/raid/md.h>
-
-struct dev_info {
-	mdk_rdev_t	*rdev;
-	sector_t	num_sectors;
-	sector_t	start_sector;
-};
-
-typedef struct dev_info dev_info_t;
-
-struct linear_private_data
-{
-	struct linear_private_data *prev;	/* earlier version */
-	dev_info_t		**hash_table;
-	sector_t		spacing;
-	sector_t		array_sectors;
-	int			sector_shift;	/* shift before dividing
-						 * by spacing
-						 */
-	dev_info_t		disks[0];
-};
-
-
-typedef struct linear_private_data linear_conf_t;
-
-#define mddev_to_conf(mddev) ((linear_conf_t *) mddev->private)
-
-#endif
diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h
deleted file mode 100644
index 82bea14..0000000
--- a/include/linux/raid/md.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
-   md.h : Multiple Devices driver for Linux
-          Copyright (C) 1996-98 Ingo Molnar, Gadi Oxman
-          Copyright (C) 1994-96 Marc ZYNGIER
-	  <zyngier@ufr-info-p7.ibp.fr> or
-	  <maz@gloups.fdn.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, or (at your option)
-   any later version.
-   
-   You should have received a copy of the GNU General Public License
-   (for example /usr/src/linux/COPYING); if not, write to the Free
-   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
-*/
-
-#ifndef _MD_H
-#define _MD_H
-
-#include <linux/blkdev.h>
-#include <linux/seq_file.h>
-
-/*
- * 'md_p.h' holds the 'physical' layout of RAID devices
- * 'md_u.h' holds the user <=> kernel API
- *
- * 'md_k.h' holds kernel internal definitions
- */
-
-#include <linux/raid/md_p.h>
-#include <linux/raid/md_u.h>
-#include <linux/raid/md_k.h>
-
-#ifdef CONFIG_MD
-
-/*
- * Different major versions are not compatible.
- * Different minor versions are only downward compatible.
- * Different patchlevel versions are downward and upward compatible.
- */
-#define MD_MAJOR_VERSION                0
-#define MD_MINOR_VERSION                90
-/*
- * MD_PATCHLEVEL_VERSION indicates kernel functionality.
- * >=1 means different superblock formats are selectable using SET_ARRAY_INFO
- *     and major_version/minor_version accordingly
- * >=2 means that Internal bitmaps are supported by setting MD_SB_BITMAP_PRESENT
- *     in the super status byte
- * >=3 means that bitmap superblock version 4 is supported, which uses
- *     little-ending representation rather than host-endian
- */
-#define MD_PATCHLEVEL_VERSION           3
-
-extern int mdp_major;
-
-extern int register_md_personality(struct mdk_personality *p);
-extern int unregister_md_personality(struct mdk_personality *p);
-extern mdk_thread_t * md_register_thread(void (*run) (mddev_t *mddev),
-				mddev_t *mddev, const char *name);
-extern void md_unregister_thread(mdk_thread_t *thread);
-extern void md_wakeup_thread(mdk_thread_t *thread);
-extern void md_check_recovery(mddev_t *mddev);
-extern void md_write_start(mddev_t *mddev, struct bio *bi);
-extern void md_write_end(mddev_t *mddev);
-extern void md_done_sync(mddev_t *mddev, int blocks, int ok);
-extern void md_error(mddev_t *mddev, mdk_rdev_t *rdev);
-
-extern void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
-			   sector_t sector, int size, struct page *page);
-extern void md_super_wait(mddev_t *mddev);
-extern int sync_page_io(struct block_device *bdev, sector_t sector, int size,
-			struct page *page, int rw);
-extern void md_do_sync(mddev_t *mddev);
-extern void md_new_event(mddev_t *mddev);
-extern int md_allow_write(mddev_t *mddev);
-extern void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev);
-
-#endif /* CONFIG_MD */
-#endif 
-
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h
deleted file mode 100644
index 9743e4d..0000000
--- a/include/linux/raid/md_k.h
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
-   md_k.h : kernel internal structure of the Linux MD driver
-          Copyright (C) 1996-98 Ingo Molnar, Gadi Oxman
-	  
-   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.
-   
-   You should have received a copy of the GNU General Public License
-   (for example /usr/src/linux/COPYING); if not, write to the Free
-   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
-*/
-
-#ifndef _MD_K_H
-#define _MD_K_H
-
-/* and dm-bio-list.h is not under include/linux because.... ??? */
-#include "../../../drivers/md/dm-bio-list.h"
-
-#ifdef CONFIG_BLOCK
-
-#define	LEVEL_MULTIPATH		(-4)
-#define	LEVEL_LINEAR		(-1)
-#define	LEVEL_FAULTY		(-5)
-
-/* we need a value for 'no level specified' and 0
- * means 'raid0', so we need something else.  This is
- * for internal use only
- */
-#define	LEVEL_NONE		(-1000000)
-
-#define MaxSector (~(sector_t)0)
-
-typedef struct mddev_s mddev_t;
-typedef struct mdk_rdev_s mdk_rdev_t;
-
-/*
- * options passed in raidrun:
- */
-
-/* Currently this must fit in an 'int' */
-#define MAX_CHUNK_SIZE (1<<30)
-
-/*
- * MD's 'extended' device
- */
-struct mdk_rdev_s
-{
-	struct list_head same_set;	/* RAID devices within the same set */
-
-	sector_t size;			/* Device size (in blocks) */
-	mddev_t *mddev;			/* RAID array if running */
-	long last_events;		/* IO event timestamp */
-
-	struct block_device *bdev;	/* block device handle */
-
-	struct page	*sb_page;
-	int		sb_loaded;
-	__u64		sb_events;
-	sector_t	data_offset;	/* start of data in array */
-	sector_t 	sb_start;	/* offset of the super block (in 512byte sectors) */
-	int		sb_size;	/* bytes in the superblock */
-	int		preferred_minor;	/* autorun support */
-
-	struct kobject	kobj;
-
-	/* A device can be in one of three states based on two flags:
-	 * Not working:   faulty==1 in_sync==0
-	 * Fully working: faulty==0 in_sync==1
-	 * Working, but not
-	 * in sync with array
-	 *                faulty==0 in_sync==0
-	 *
-	 * It can never have faulty==1, in_sync==1
-	 * This reduces the burden of testing multiple flags in many cases
-	 */
-
-	unsigned long	flags;
-#define	Faulty		1		/* device is known to have a fault */
-#define	In_sync		2		/* device is in_sync with rest of array */
-#define	WriteMostly	4		/* Avoid reading if at all possible */
-#define	BarriersNotsupp	5		/* BIO_RW_BARRIER is not supported */
-#define	AllReserved	6		/* If whole device is reserved for
-					 * one array */
-#define	AutoDetected	7		/* added by auto-detect */
-#define Blocked		8		/* An error occured on an externally
-					 * managed array, don't allow writes
-					 * until it is cleared */
-#define StateChanged	9		/* Faulty or Blocked has changed during
-					 * interrupt, so it needs to be
-					 * notified by the thread */
-	wait_queue_head_t blocked_wait;
-
-	int desc_nr;			/* descriptor index in the superblock */
-	int raid_disk;			/* role of device in array */
-	int saved_raid_disk;		/* role that device used to have in the
-					 * array and could again if we did a partial
-					 * resync from the bitmap
-					 */
-	sector_t	recovery_offset;/* If this device has been partially
-					 * recovered, this is where we were
-					 * up to.
-					 */
-
-	atomic_t	nr_pending;	/* number of pending requests.
-					 * only maintained for arrays that
-					 * support hot removal
-					 */
-	atomic_t	read_errors;	/* number of consecutive read errors that
-					 * we have tried to ignore.
-					 */
-	atomic_t	corrected_errors; /* number of corrected read errors,
-					   * for reporting to userspace and storing
-					   * in superblock.
-					   */
-	struct work_struct del_work;	/* used for delayed sysfs removal */
-
-	struct sysfs_dirent *sysfs_state; /* handle for 'state'
-					   * sysfs entry */
-};
-
-struct mddev_s
-{
-	void				*private;
-	struct mdk_personality		*pers;
-	dev_t				unit;
-	int				md_minor;
-	struct list_head 		disks;
-	unsigned long			flags;
-#define MD_CHANGE_DEVS	0	/* Some device status has changed */
-#define MD_CHANGE_CLEAN 1	/* transition to or from 'clean' */
-#define MD_CHANGE_PENDING 2	/* superblock update in progress */
-
-	int				ro;
-
-	struct gendisk			*gendisk;
-
-	struct kobject			kobj;
-	int				hold_active;
-#define	UNTIL_IOCTL	1
-#define	UNTIL_STOP	2
-
-	/* Superblock information */
-	int				major_version,
-					minor_version,
-					patch_version;
-	int				persistent;
-	int 				external;	/* metadata is
-							 * managed externally */
-	char				metadata_type[17]; /* externally set*/
-	int				chunk_size;
-	time_t				ctime, utime;
-	int				level, layout;
-	char				clevel[16];
-	int				raid_disks;
-	int				max_disks;
-	sector_t			size; /* used size of component devices */
-	sector_t			array_sectors; /* exported array size */
-	__u64				events;
-
-	char				uuid[16];
-
-	/* If the array is being reshaped, we need to record the
-	 * new shape and an indication of where we are up to.
-	 * This is written to the superblock.
-	 * If reshape_position is MaxSector, then no reshape is happening (yet).
-	 */
-	sector_t			reshape_position;
-	int				delta_disks, new_level, new_layout, new_chunk;
-
-	struct mdk_thread_s		*thread;	/* management thread */
-	struct mdk_thread_s		*sync_thread;	/* doing resync or reconstruct */
-	sector_t			curr_resync;	/* last block scheduled */
-	unsigned long			resync_mark;	/* a recent timestamp */
-	sector_t			resync_mark_cnt;/* blocks written at resync_mark */
-	sector_t			curr_mark_cnt; /* blocks scheduled now */
-
-	sector_t			resync_max_sectors; /* may be set by personality */
-
-	sector_t			resync_mismatches; /* count of sectors where
-							    * parity/replica mismatch found
-							    */
-
-	/* allow user-space to request suspension of IO to regions of the array */
-	sector_t			suspend_lo;
-	sector_t			suspend_hi;
-	/* if zero, use the system-wide default */
-	int				sync_speed_min;
-	int				sync_speed_max;
-
-	/* resync even though the same disks are shared among md-devices */
-	int				parallel_resync;
-
-	int				ok_start_degraded;
-	/* recovery/resync flags 
-	 * NEEDED:   we might need to start a resync/recover
-	 * RUNNING:  a thread is running, or about to be started
-	 * SYNC:     actually doing a resync, not a recovery
-	 * RECOVER:  doing recovery, or need to try it.
-	 * INTR:     resync needs to be aborted for some reason
-	 * DONE:     thread is done and is waiting to be reaped
-	 * REQUEST:  user-space has requested a sync (used with SYNC)
-	 * CHECK:    user-space request for for check-only, no repair
-	 * RESHAPE:  A reshape is happening
-	 *
-	 * If neither SYNC or RESHAPE are set, then it is a recovery.
-	 */
-#define	MD_RECOVERY_RUNNING	0
-#define	MD_RECOVERY_SYNC	1
-#define	MD_RECOVERY_RECOVER	2
-#define	MD_RECOVERY_INTR	3
-#define	MD_RECOVERY_DONE	4
-#define	MD_RECOVERY_NEEDED	5
-#define	MD_RECOVERY_REQUESTED	6
-#define	MD_RECOVERY_CHECK	7
-#define MD_RECOVERY_RESHAPE	8
-#define	MD_RECOVERY_FROZEN	9
-
-	unsigned long			recovery;
-	int				recovery_disabled; /* if we detect that recovery
-							    * will always fail, set this
-							    * so we don't loop trying */
-
-	int				in_sync;	/* know to not need resync */
-	struct mutex			reconfig_mutex;
-	atomic_t			active;		/* general refcount */
-	atomic_t			openers;	/* number of active opens */
-
-	int				changed;	/* true if we might need to reread partition info */
-	int				degraded;	/* whether md should consider
-							 * adding a spare
-							 */
-	int				barriers_work;	/* initialised to true, cleared as soon
-							 * as a barrier request to slave
-							 * fails.  Only supported
-							 */
-	struct bio			*biolist; 	/* bios that need to be retried
-							 * because BIO_RW_BARRIER is not supported
-							 */
-
-	atomic_t			recovery_active; /* blocks scheduled, but not written */
-	wait_queue_head_t		recovery_wait;
-	sector_t			recovery_cp;
-	sector_t			resync_min;	/* user requested sync
-							 * starts here */
-	sector_t			resync_max;	/* resync should pause
-							 * when it gets here */
-
-	struct sysfs_dirent		*sysfs_state;	/* handle for 'array_state'
-							 * file in sysfs.
-							 */
-	struct sysfs_dirent		*sysfs_action;  /* handle for 'sync_action' */
-
-	struct work_struct del_work;	/* used for delayed sysfs removal */
-
-	spinlock_t			write_lock;
-	wait_queue_head_t		sb_wait;	/* for waiting on superblock updates */
-	atomic_t			pending_writes;	/* number of active superblock writes */
-
-	unsigned int			safemode;	/* if set, update "clean" superblock
-							 * when no writes pending.
-							 */ 
-	unsigned int			safemode_delay;
-	struct timer_list		safemode_timer;
-	atomic_t			writes_pending; 
-	struct request_queue		*queue;	/* for plugging ... */
-
-	atomic_t                        write_behind; /* outstanding async IO */
-	unsigned int                    max_write_behind; /* 0 = sync */
-
-	struct bitmap                   *bitmap; /* the bitmap for the device */
-	struct file			*bitmap_file; /* the bitmap file */
-	long				bitmap_offset; /* offset from superblock of
-							* start of bitmap. May be
-							* negative, but not '0'
-							*/
-	long				default_bitmap_offset; /* this is the offset to use when
-								* hot-adding a bitmap.  It should
-								* eventually be settable by sysfs.
-								*/
-
-	struct list_head		all_mddevs;
-};
-
-
-static inline void rdev_dec_pending(mdk_rdev_t *rdev, mddev_t *mddev)
-{
-	int faulty = test_bit(Faulty, &rdev->flags);
-	if (atomic_dec_and_test(&rdev->nr_pending) && faulty)
-		set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
-}
-
-static inline void md_sync_acct(struct block_device *bdev, unsigned long nr_sectors)
-{
-        atomic_add(nr_sectors, &bdev->bd_contains->bd_disk->sync_io);
-}
-
-struct mdk_personality
-{
-	char *name;
-	int level;
-	struct list_head list;
-	struct module *owner;
-	int (*make_request)(struct request_queue *q, struct bio *bio);
-	int (*run)(mddev_t *mddev);
-	int (*stop)(mddev_t *mddev);
-	void (*status)(struct seq_file *seq, mddev_t *mddev);
-	/* error_handler must set ->faulty and clear ->in_sync
-	 * if appropriate, and should abort recovery if needed 
-	 */
-	void (*error_handler)(mddev_t *mddev, mdk_rdev_t *rdev);
-	int (*hot_add_disk) (mddev_t *mddev, mdk_rdev_t *rdev);
-	int (*hot_remove_disk) (mddev_t *mddev, int number);
-	int (*spare_active) (mddev_t *mddev);
-	sector_t (*sync_request)(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster);
-	int (*resize) (mddev_t *mddev, sector_t sectors);
-	int (*check_reshape) (mddev_t *mddev);
-	int (*start_reshape) (mddev_t *mddev);
-	int (*reconfig) (mddev_t *mddev, int layout, int chunk_size);
-	/* quiesce moves between quiescence states
-	 * 0 - fully active
-	 * 1 - no new requests allowed
-	 * others - reserved
-	 */
-	void (*quiesce) (mddev_t *mddev, int state);
-};
-
-
-struct md_sysfs_entry {
-	struct attribute attr;
-	ssize_t (*show)(mddev_t *, char *);
-	ssize_t (*store)(mddev_t *, const char *, size_t);
-};
-
-
-static inline char * mdname (mddev_t * mddev)
-{
-	return mddev->gendisk ? mddev->gendisk->disk_name : "mdX";
-}
-
-/*
- * iterates through some rdev ringlist. It's safe to remove the
- * current 'rdev'. Dont touch 'tmp' though.
- */
-#define rdev_for_each_list(rdev, tmp, head)				\
-	list_for_each_entry_safe(rdev, tmp, head, same_set)
-
-/*
- * iterates through the 'same array disks' ringlist
- */
-#define rdev_for_each(rdev, tmp, mddev)				\
-	list_for_each_entry_safe(rdev, tmp, &((mddev)->disks), same_set)
-
-#define rdev_for_each_rcu(rdev, mddev)				\
-	list_for_each_entry_rcu(rdev, &((mddev)->disks), same_set)
-
-typedef struct mdk_thread_s {
-	void			(*run) (mddev_t *mddev);
-	mddev_t			*mddev;
-	wait_queue_head_t	wqueue;
-	unsigned long           flags;
-	struct task_struct	*tsk;
-	unsigned long		timeout;
-} mdk_thread_t;
-
-#define THREAD_WAKEUP  0
-
-#define __wait_event_lock_irq(wq, condition, lock, cmd) 		\
-do {									\
-	wait_queue_t __wait;						\
-	init_waitqueue_entry(&__wait, current);				\
-									\
-	add_wait_queue(&wq, &__wait);					\
-	for (;;) {							\
-		set_current_state(TASK_UNINTERRUPTIBLE);		\
-		if (condition)						\
-			break;						\
-		spin_unlock_irq(&lock);					\
-		cmd;							\
-		schedule();						\
-		spin_lock_irq(&lock);					\
-	}								\
-	current->state = TASK_RUNNING;					\
-	remove_wait_queue(&wq, &__wait);				\
-} while (0)
-
-#define wait_event_lock_irq(wq, condition, lock, cmd) 			\
-do {									\
-	if (condition)	 						\
-		break;							\
-	__wait_event_lock_irq(wq, condition, lock, cmd);		\
-} while (0)
-
-static inline void safe_put_page(struct page *p)
-{
-	if (p) put_page(p);
-}
-
-#endif /* CONFIG_BLOCK */
-#endif
-
diff --git a/include/linux/raid/md_u.h b/include/linux/raid/md_u.h
index 7192035..fb1abb3 100644
--- a/include/linux/raid/md_u.h
+++ b/include/linux/raid/md_u.h
@@ -15,6 +15,24 @@
 #ifndef _MD_U_H
 #define _MD_U_H
 
+/*
+ * Different major versions are not compatible.
+ * Different minor versions are only downward compatible.
+ * Different patchlevel versions are downward and upward compatible.
+ */
+#define MD_MAJOR_VERSION                0
+#define MD_MINOR_VERSION                90
+/*
+ * MD_PATCHLEVEL_VERSION indicates kernel functionality.
+ * >=1 means different superblock formats are selectable using SET_ARRAY_INFO
+ *     and major_version/minor_version accordingly
+ * >=2 means that Internal bitmaps are supported by setting MD_SB_BITMAP_PRESENT
+ *     in the super status byte
+ * >=3 means that bitmap superblock version 4 is supported, which uses
+ *     little-ending representation rather than host-endian
+ */
+#define MD_PATCHLEVEL_VERSION           3
+
 /* ioctls */
 
 /* status */
@@ -46,6 +64,12 @@
 #define STOP_ARRAY_RO		_IO (MD_MAJOR, 0x33)
 #define RESTART_ARRAY_RW	_IO (MD_MAJOR, 0x34)
 
+/* 63 partitions with the alternate major number (mdp) */
+#define MdpMinorShift 6
+#ifdef __KERNEL__
+extern int mdp_major;
+#endif
+
 typedef struct mdu_version_s {
 	int major;
 	int minor;
@@ -85,6 +109,17 @@
 
 } mdu_array_info_t;
 
+/* non-obvious values for 'level' */
+#define	LEVEL_MULTIPATH		(-4)
+#define	LEVEL_LINEAR		(-1)
+#define	LEVEL_FAULTY		(-5)
+
+/* we need a value for 'no level specified' and 0
+ * means 'raid0', so we need something else.  This is
+ * for internal use only
+ */
+#define	LEVEL_NONE		(-1000000)
+
 typedef struct mdu_disk_info_s {
 	/*
 	 * configuration/status of one particular disk
diff --git a/include/linux/raid/multipath.h b/include/linux/raid/multipath.h
deleted file mode 100644
index 6f53fc1..0000000
--- a/include/linux/raid/multipath.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef _MULTIPATH_H
-#define _MULTIPATH_H
-
-#include <linux/raid/md.h>
-
-struct multipath_info {
-	mdk_rdev_t	*rdev;
-};
-
-struct multipath_private_data {
-	mddev_t			*mddev;
-	struct multipath_info	*multipaths;
-	int			raid_disks;
-	int			working_disks;
-	spinlock_t		device_lock;
-	struct list_head	retry_list;
-
-	mempool_t		*pool;
-};
-
-typedef struct multipath_private_data multipath_conf_t;
-
-/*
- * this is the only point in the RAID code where we violate
- * C type safety. mddev->private is an 'opaque' pointer.
- */
-#define mddev_to_conf(mddev) ((multipath_conf_t *) mddev->private)
-
-/*
- * this is our 'private' 'collective' MULTIPATH buffer head.
- * it contains information about what kind of IO operations were started
- * for this MULTIPATH operation, and about their status:
- */
-
-struct multipath_bh {
-	mddev_t			*mddev;
-	struct bio		*master_bio;
-	struct bio		bio;
-	int			path;
-	struct list_head	retry_list;
-};
-#endif
diff --git a/include/linux/raid/pq.h b/include/linux/raid/pq.h
new file mode 100644
index 0000000..d92480f
--- /dev/null
+++ b/include/linux/raid/pq.h
@@ -0,0 +1,132 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright 2003 H. Peter Anvin - 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, Inc., 53 Temple Place Ste 330,
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef LINUX_RAID_RAID6_H
+#define LINUX_RAID_RAID6_H
+
+#ifdef __KERNEL__
+
+/* Set to 1 to use kernel-wide empty_zero_page */
+#define RAID6_USE_EMPTY_ZERO_PAGE 0
+#include <linux/blkdev.h>
+
+/* We need a pre-zeroed page... if we don't want to use the kernel-provided
+   one define it here */
+#if RAID6_USE_EMPTY_ZERO_PAGE
+# define raid6_empty_zero_page empty_zero_page
+#else
+extern const char raid6_empty_zero_page[PAGE_SIZE];
+#endif
+
+#else /* ! __KERNEL__ */
+/* Used for testing in user space */
+
+#include <errno.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <stddef.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+
+/* Not standard, but glibc defines it */
+#define BITS_PER_LONG __WORDSIZE
+
+typedef uint8_t  u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+
+#ifndef PAGE_SIZE
+# define PAGE_SIZE 4096
+#endif
+extern const char raid6_empty_zero_page[PAGE_SIZE];
+
+#define __init
+#define __exit
+#define __attribute_const__ __attribute__((const))
+#define noinline __attribute__((noinline))
+
+#define preempt_enable()
+#define preempt_disable()
+#define cpu_has_feature(x) 1
+#define enable_kernel_altivec()
+#define disable_kernel_altivec()
+
+#define EXPORT_SYMBOL(sym)
+#define MODULE_LICENSE(licence)
+#define subsys_initcall(x)
+#define module_exit(x)
+#endif /* __KERNEL__ */
+
+/* Routine choices */
+struct raid6_calls {
+	void (*gen_syndrome)(int, size_t, void **);
+	int  (*valid)(void);	/* Returns 1 if this routine set is usable */
+	const char *name;	/* Name of this routine set */
+	int prefer;		/* Has special performance attribute */
+};
+
+/* Selected algorithm */
+extern struct raid6_calls raid6_call;
+
+/* Algorithm list */
+extern const struct raid6_calls * const raid6_algos[];
+int raid6_select_algo(void);
+
+/* Return values from chk_syndrome */
+#define RAID6_OK	0
+#define RAID6_P_BAD	1
+#define RAID6_Q_BAD	2
+#define RAID6_PQ_BAD	3
+
+/* Galois field tables */
+extern const u8 raid6_gfmul[256][256] __attribute__((aligned(256)));
+extern const u8 raid6_gfexp[256]      __attribute__((aligned(256)));
+extern const u8 raid6_gfinv[256]      __attribute__((aligned(256)));
+extern const u8 raid6_gfexi[256]      __attribute__((aligned(256)));
+
+/* Recovery routines */
+void raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
+		       void **ptrs);
+void raid6_datap_recov(int disks, size_t bytes, int faila, void **ptrs);
+void raid6_dual_recov(int disks, size_t bytes, int faila, int failb,
+		      void **ptrs);
+
+/* Some definitions to allow code to be compiled for testing in userspace */
+#ifndef __KERNEL__
+
+# define jiffies	raid6_jiffies()
+# define printk 	printf
+# define GFP_KERNEL	0
+# define __get_free_pages(x, y)	((unsigned long)mmap(NULL, PAGE_SIZE << (y), \
+						     PROT_READ|PROT_WRITE,   \
+						     MAP_PRIVATE|MAP_ANONYMOUS,\
+						     0, 0))
+# define free_pages(x, y)	munmap((void *)(x), (y)*PAGE_SIZE)
+
+static inline void cpu_relax(void)
+{
+	/* Nothing */
+}
+
+#undef  HZ
+#define HZ 1000
+static inline uint32_t raid6_jiffies(void)
+{
+	struct timeval tv;
+	gettimeofday(&tv, NULL);
+	return tv.tv_sec*1000 + tv.tv_usec/1000;
+}
+
+#endif /* ! __KERNEL__ */
+
+#endif /* LINUX_RAID_RAID6_H */
diff --git a/include/linux/raid/raid0.h b/include/linux/raid/raid0.h
deleted file mode 100644
index fd42aa8..0000000
--- a/include/linux/raid/raid0.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef _RAID0_H
-#define _RAID0_H
-
-#include <linux/raid/md.h>
-
-struct strip_zone
-{
-	sector_t zone_start;	/* Zone offset in md_dev (in sectors) */
-	sector_t dev_start;	/* Zone offset in real dev (in sectors) */
-	sector_t sectors;	/* Zone size in sectors */
-	int nb_dev;		/* # of devices attached to the zone */
-	mdk_rdev_t **dev;	/* Devices attached to the zone */
-};
-
-struct raid0_private_data
-{
-	struct strip_zone **hash_table; /* Table of indexes into strip_zone */
-	struct strip_zone *strip_zone;
-	mdk_rdev_t **devlist; /* lists of rdevs, pointed to by strip_zone->dev */
-	int nr_strip_zones;
-
-	sector_t spacing;
-	int sector_shift; /* shift this before divide by spacing */
-};
-
-typedef struct raid0_private_data raid0_conf_t;
-
-#define mddev_to_conf(mddev) ((raid0_conf_t *) mddev->private)
-
-#endif
diff --git a/include/linux/raid/raid1.h b/include/linux/raid/raid1.h
deleted file mode 100644
index 0a9ba7c..0000000
--- a/include/linux/raid/raid1.h
+++ /dev/null
@@ -1,134 +0,0 @@
-#ifndef _RAID1_H
-#define _RAID1_H
-
-#include <linux/raid/md.h>
-
-typedef struct mirror_info mirror_info_t;
-
-struct mirror_info {
-	mdk_rdev_t	*rdev;
-	sector_t	head_position;
-};
-
-/*
- * memory pools need a pointer to the mddev, so they can force an unplug
- * when memory is tight, and a count of the number of drives that the
- * pool was allocated for, so they know how much to allocate and free.
- * mddev->raid_disks cannot be used, as it can change while a pool is active
- * These two datums are stored in a kmalloced struct.
- */
-
-struct pool_info {
-	mddev_t *mddev;
-	int	raid_disks;
-};
-
-
-typedef struct r1bio_s r1bio_t;
-
-struct r1_private_data_s {
-	mddev_t			*mddev;
-	mirror_info_t		*mirrors;
-	int			raid_disks;
-	int			last_used;
-	sector_t		next_seq_sect;
-	spinlock_t		device_lock;
-
-	struct list_head	retry_list;
-	/* queue pending writes and submit them on unplug */
-	struct bio_list		pending_bio_list;
-	/* queue of writes that have been unplugged */
-	struct bio_list		flushing_bio_list;
-
-	/* for use when syncing mirrors: */
-
-	spinlock_t		resync_lock;
-	int			nr_pending;
-	int			nr_waiting;
-	int			nr_queued;
-	int			barrier;
-	sector_t		next_resync;
-	int			fullsync;  /* set to 1 if a full sync is needed,
-					    * (fresh device added).
-					    * Cleared when a sync completes.
-					    */
-
-	wait_queue_head_t	wait_barrier;
-
-	struct pool_info	*poolinfo;
-
-	struct page		*tmppage;
-
-	mempool_t *r1bio_pool;
-	mempool_t *r1buf_pool;
-};
-
-typedef struct r1_private_data_s conf_t;
-
-/*
- * this is the only point in the RAID code where we violate
- * C type safety. mddev->private is an 'opaque' pointer.
- */
-#define mddev_to_conf(mddev) ((conf_t *) mddev->private)
-
-/*
- * this is our 'private' RAID1 bio.
- *
- * it contains information about what kind of IO operations were started
- * for this RAID1 operation, and about their status:
- */
-
-struct r1bio_s {
-	atomic_t		remaining; /* 'have we finished' count,
-					    * used from IRQ handlers
-					    */
-	atomic_t		behind_remaining; /* number of write-behind ios remaining
-						 * in this BehindIO request
-						 */
-	sector_t		sector;
-	int			sectors;
-	unsigned long		state;
-	mddev_t			*mddev;
-	/*
-	 * original bio going to /dev/mdx
-	 */
-	struct bio		*master_bio;
-	/*
-	 * if the IO is in READ direction, then this is where we read
-	 */
-	int			read_disk;
-
-	struct list_head	retry_list;
-	struct bitmap_update	*bitmap_update;
-	/*
-	 * if the IO is in WRITE direction, then multiple bios are used.
-	 * We choose the number when they are allocated.
-	 */
-	struct bio		*bios[0];
-	/* DO NOT PUT ANY NEW FIELDS HERE - bios array is contiguously alloced*/
-};
-
-/* when we get a read error on a read-only array, we redirect to another
- * device without failing the first device, or trying to over-write to
- * correct the read error.  To keep track of bad blocks on a per-bio
- * level, we store IO_BLOCKED in the appropriate 'bios' pointer
- */
-#define IO_BLOCKED ((struct bio*)1)
-
-/* bits for r1bio.state */
-#define	R1BIO_Uptodate	0
-#define	R1BIO_IsSync	1
-#define	R1BIO_Degraded	2
-#define	R1BIO_BehindIO	3
-#define	R1BIO_Barrier	4
-#define R1BIO_BarrierRetry 5
-/* For write-behind requests, we call bi_end_io when
- * the last non-write-behind device completes, providing
- * any write was successful.  Otherwise we call when
- * any write-behind write succeeds, otherwise we call
- * with failure when last write completes (and all failed).
- * Record that bi_end_io was called with this flag...
- */
-#define	R1BIO_Returned 6
-
-#endif
diff --git a/include/linux/raid/raid10.h b/include/linux/raid/raid10.h
deleted file mode 100644
index e9091cf..0000000
--- a/include/linux/raid/raid10.h
+++ /dev/null
@@ -1,123 +0,0 @@
-#ifndef _RAID10_H
-#define _RAID10_H
-
-#include <linux/raid/md.h>
-
-typedef struct mirror_info mirror_info_t;
-
-struct mirror_info {
-	mdk_rdev_t	*rdev;
-	sector_t	head_position;
-};
-
-typedef struct r10bio_s r10bio_t;
-
-struct r10_private_data_s {
-	mddev_t			*mddev;
-	mirror_info_t		*mirrors;
-	int			raid_disks;
-	spinlock_t		device_lock;
-
-	/* geometry */
-	int			near_copies;  /* number of copies layed out raid0 style */
-	int 			far_copies;   /* number of copies layed out
-					       * at large strides across drives
-					       */
-	int			far_offset;   /* far_copies are offset by 1 stripe
-					       * instead of many
-					       */
-	int			copies;	      /* near_copies * far_copies.
-					       * must be <= raid_disks
-					       */
-	sector_t		stride;	      /* distance between far copies.
-					       * This is size / far_copies unless
-					       * far_offset, in which case it is
-					       * 1 stripe.
-					       */
-
-	int chunk_shift; /* shift from chunks to sectors */
-	sector_t chunk_mask;
-
-	struct list_head	retry_list;
-	/* queue pending writes and submit them on unplug */
-	struct bio_list		pending_bio_list;
-
-
-	spinlock_t		resync_lock;
-	int nr_pending;
-	int nr_waiting;
-	int nr_queued;
-	int barrier;
-	sector_t		next_resync;
-	int			fullsync;  /* set to 1 if a full sync is needed,
-					    * (fresh device added).
-					    * Cleared when a sync completes.
-					    */
-
-	wait_queue_head_t	wait_barrier;
-
-	mempool_t *r10bio_pool;
-	mempool_t *r10buf_pool;
-	struct page		*tmppage;
-};
-
-typedef struct r10_private_data_s conf_t;
-
-/*
- * this is the only point in the RAID code where we violate
- * C type safety. mddev->private is an 'opaque' pointer.
- */
-#define mddev_to_conf(mddev) ((conf_t *) mddev->private)
-
-/*
- * this is our 'private' RAID10 bio.
- *
- * it contains information about what kind of IO operations were started
- * for this RAID10 operation, and about their status:
- */
-
-struct r10bio_s {
-	atomic_t		remaining; /* 'have we finished' count,
-					    * used from IRQ handlers
-					    */
-	sector_t		sector;	/* virtual sector number */
-	int			sectors;
-	unsigned long		state;
-	mddev_t			*mddev;
-	/*
-	 * original bio going to /dev/mdx
-	 */
-	struct bio		*master_bio;
-	/*
-	 * if the IO is in READ direction, then this is where we read
-	 */
-	int			read_slot;
-
-	struct list_head	retry_list;
-	/*
-	 * if the IO is in WRITE direction, then multiple bios are used,
-	 * one for each copy.
-	 * When resyncing we also use one for each copy.
-	 * When reconstructing, we use 2 bios, one for read, one for write.
-	 * We choose the number when they are allocated.
-	 */
-	struct {
-		struct bio		*bio;
-		sector_t addr;
-		int devnum;
-	} devs[0];
-};
-
-/* when we get a read error on a read-only array, we redirect to another
- * device without failing the first device, or trying to over-write to
- * correct the read error.  To keep track of bad blocks on a per-bio
- * level, we store IO_BLOCKED in the appropriate 'bios' pointer
- */
-#define IO_BLOCKED ((struct bio*)1)
-
-/* bits for r10bio.state */
-#define	R10BIO_Uptodate	0
-#define	R10BIO_IsSync	1
-#define	R10BIO_IsRecover 2
-#define	R10BIO_Degraded 3
-#endif
diff --git a/include/linux/raid/raid5.h b/include/linux/raid/raid5.h
deleted file mode 100644
index 3b26727..0000000
--- a/include/linux/raid/raid5.h
+++ /dev/null
@@ -1,402 +0,0 @@
-#ifndef _RAID5_H
-#define _RAID5_H
-
-#include <linux/raid/md.h>
-#include <linux/raid/xor.h>
-
-/*
- *
- * Each stripe contains one buffer per disc.  Each buffer can be in
- * one of a number of states stored in "flags".  Changes between
- * these states happen *almost* exclusively under a per-stripe
- * spinlock.  Some very specific changes can happen in bi_end_io, and
- * these are not protected by the spin lock.
- *
- * The flag bits that are used to represent these states are:
- *   R5_UPTODATE and R5_LOCKED
- *
- * State Empty == !UPTODATE, !LOCK
- *        We have no data, and there is no active request
- * State Want == !UPTODATE, LOCK
- *        A read request is being submitted for this block
- * State Dirty == UPTODATE, LOCK
- *        Some new data is in this buffer, and it is being written out
- * State Clean == UPTODATE, !LOCK
- *        We have valid data which is the same as on disc
- *
- * The possible state transitions are:
- *
- *  Empty -> Want   - on read or write to get old data for  parity calc
- *  Empty -> Dirty  - on compute_parity to satisfy write/sync request.(RECONSTRUCT_WRITE)
- *  Empty -> Clean  - on compute_block when computing a block for failed drive
- *  Want  -> Empty  - on failed read
- *  Want  -> Clean  - on successful completion of read request
- *  Dirty -> Clean  - on successful completion of write request
- *  Dirty -> Clean  - on failed write
- *  Clean -> Dirty  - on compute_parity to satisfy write/sync (RECONSTRUCT or RMW)
- *
- * The Want->Empty, Want->Clean, Dirty->Clean, transitions
- * all happen in b_end_io at interrupt time.
- * Each sets the Uptodate bit before releasing the Lock bit.
- * This leaves one multi-stage transition:
- *    Want->Dirty->Clean
- * This is safe because thinking that a Clean buffer is actually dirty
- * will at worst delay some action, and the stripe will be scheduled
- * for attention after the transition is complete.
- *
- * There is one possibility that is not covered by these states.  That
- * is if one drive has failed and there is a spare being rebuilt.  We
- * can't distinguish between a clean block that has been generated
- * from parity calculations, and a clean block that has been
- * successfully written to the spare ( or to parity when resyncing).
- * To distingush these states we have a stripe bit STRIPE_INSYNC that
- * is set whenever a write is scheduled to the spare, or to the parity
- * disc if there is no spare.  A sync request clears this bit, and
- * when we find it set with no buffers locked, we know the sync is
- * complete.
- *
- * Buffers for the md device that arrive via make_request are attached
- * to the appropriate stripe in one of two lists linked on b_reqnext.
- * One list (bh_read) for read requests, one (bh_write) for write.
- * There should never be more than one buffer on the two lists
- * together, but we are not guaranteed of that so we allow for more.
- *
- * If a buffer is on the read list when the associated cache buffer is
- * Uptodate, the data is copied into the read buffer and it's b_end_io
- * routine is called.  This may happen in the end_request routine only
- * if the buffer has just successfully been read.  end_request should
- * remove the buffers from the list and then set the Uptodate bit on
- * the buffer.  Other threads may do this only if they first check
- * that the Uptodate bit is set.  Once they have checked that they may
- * take buffers off the read queue.
- *
- * When a buffer on the write list is committed for write it is copied
- * into the cache buffer, which is then marked dirty, and moved onto a
- * third list, the written list (bh_written).  Once both the parity
- * block and the cached buffer are successfully written, any buffer on
- * a written list can be returned with b_end_io.
- *
- * The write list and read list both act as fifos.  The read list is
- * protected by the device_lock.  The write and written lists are
- * protected by the stripe lock.  The device_lock, which can be
- * claimed while the stipe lock is held, is only for list
- * manipulations and will only be held for a very short time.  It can
- * be claimed from interrupts.
- *
- *
- * Stripes in the stripe cache can be on one of two lists (or on
- * neither).  The "inactive_list" contains stripes which are not
- * currently being used for any request.  They can freely be reused
- * for another stripe.  The "handle_list" contains stripes that need
- * to be handled in some way.  Both of these are fifo queues.  Each
- * stripe is also (potentially) linked to a hash bucket in the hash
- * table so that it can be found by sector number.  Stripes that are
- * not hashed must be on the inactive_list, and will normally be at
- * the front.  All stripes start life this way.
- *
- * The inactive_list, handle_list and hash bucket lists are all protected by the
- * device_lock.
- *  - stripes on the inactive_list never have their stripe_lock held.
- *  - stripes have a reference counter. If count==0, they are on a list.
- *  - If a stripe might need handling, STRIPE_HANDLE is set.
- *  - When refcount reaches zero, then if STRIPE_HANDLE it is put on
- *    handle_list else inactive_list
- *
- * This, combined with the fact that STRIPE_HANDLE is only ever
- * cleared while a stripe has a non-zero count means that if the
- * refcount is 0 and STRIPE_HANDLE is set, then it is on the
- * handle_list and if recount is 0 and STRIPE_HANDLE is not set, then
- * the stripe is on inactive_list.
- *
- * The possible transitions are:
- *  activate an unhashed/inactive stripe (get_active_stripe())
- *     lockdev check-hash unlink-stripe cnt++ clean-stripe hash-stripe unlockdev
- *  activate a hashed, possibly active stripe (get_active_stripe())
- *     lockdev check-hash if(!cnt++)unlink-stripe unlockdev
- *  attach a request to an active stripe (add_stripe_bh())
- *     lockdev attach-buffer unlockdev
- *  handle a stripe (handle_stripe())
- *     lockstripe clrSTRIPE_HANDLE ...
- *		(lockdev check-buffers unlockdev) ..
- *		change-state ..
- *		record io/ops needed unlockstripe schedule io/ops
- *  release an active stripe (release_stripe())
- *     lockdev if (!--cnt) { if  STRIPE_HANDLE, add to handle_list else add to inactive-list } unlockdev
- *
- * The refcount counts each thread that have activated the stripe,
- * plus raid5d if it is handling it, plus one for each active request
- * on a cached buffer, and plus one if the stripe is undergoing stripe
- * operations.
- *
- * Stripe operations are performed outside the stripe lock,
- * the stripe operations are:
- * -copying data between the stripe cache and user application buffers
- * -computing blocks to save a disk access, or to recover a missing block
- * -updating the parity on a write operation (reconstruct write and
- *  read-modify-write)
- * -checking parity correctness
- * -running i/o to disk
- * These operations are carried out by raid5_run_ops which uses the async_tx
- * api to (optionally) offload operations to dedicated hardware engines.
- * When requesting an operation handle_stripe sets the pending bit for the
- * operation and increments the count.  raid5_run_ops is then run whenever
- * the count is non-zero.
- * There are some critical dependencies between the operations that prevent some
- * from being requested while another is in flight.
- * 1/ Parity check operations destroy the in cache version of the parity block,
- *    so we prevent parity dependent operations like writes and compute_blocks
- *    from starting while a check is in progress.  Some dma engines can perform
- *    the check without damaging the parity block, in these cases the parity
- *    block is re-marked up to date (assuming the check was successful) and is
- *    not re-read from disk.
- * 2/ When a write operation is requested we immediately lock the affected
- *    blocks, and mark them as not up to date.  This causes new read requests
- *    to be held off, as well as parity checks and compute block operations.
- * 3/ Once a compute block operation has been requested handle_stripe treats
- *    that block as if it is up to date.  raid5_run_ops guaruntees that any
- *    operation that is dependent on the compute block result is initiated after
- *    the compute block completes.
- */
-
-/*
- * Operations state - intermediate states that are visible outside of sh->lock
- * In general _idle indicates nothing is running, _run indicates a data
- * processing operation is active, and _result means the data processing result
- * is stable and can be acted upon.  For simple operations like biofill and
- * compute that only have an _idle and _run state they are indicated with
- * sh->state flags (STRIPE_BIOFILL_RUN and STRIPE_COMPUTE_RUN)
- */
-/**
- * enum check_states - handles syncing / repairing a stripe
- * @check_state_idle - check operations are quiesced
- * @check_state_run - check operation is running
- * @check_state_result - set outside lock when check result is valid
- * @check_state_compute_run - check failed and we are repairing
- * @check_state_compute_result - set outside lock when compute result is valid
- */
-enum check_states {
-	check_state_idle = 0,
-	check_state_run, /* parity check */
-	check_state_check_result,
-	check_state_compute_run, /* parity repair */
-	check_state_compute_result,
-};
-
-/**
- * enum reconstruct_states - handles writing or expanding a stripe
- */
-enum reconstruct_states {
-	reconstruct_state_idle = 0,
-	reconstruct_state_prexor_drain_run,	/* prexor-write */
-	reconstruct_state_drain_run,		/* write */
-	reconstruct_state_run,			/* expand */
-	reconstruct_state_prexor_drain_result,
-	reconstruct_state_drain_result,
-	reconstruct_state_result,
-};
-
-struct stripe_head {
-	struct hlist_node	hash;
-	struct list_head	lru;			/* inactive_list or handle_list */
-	struct raid5_private_data	*raid_conf;
-	sector_t		sector;			/* sector of this row */
-	int			pd_idx;			/* parity disk index */
-	unsigned long		state;			/* state flags */
-	atomic_t		count;			/* nr of active thread/requests */
-	spinlock_t		lock;
-	int			bm_seq;	/* sequence number for bitmap flushes */
-	int			disks;			/* disks in stripe */
-	enum check_states	check_state;
-	enum reconstruct_states reconstruct_state;
-	/* stripe_operations
-	 * @target - STRIPE_OP_COMPUTE_BLK target
-	 */
-	struct stripe_operations {
-		int		   target;
-		u32		   zero_sum_result;
-	} ops;
-	struct r5dev {
-		struct bio	req;
-		struct bio_vec	vec;
-		struct page	*page;
-		struct bio	*toread, *read, *towrite, *written;
-		sector_t	sector;			/* sector of this page */
-		unsigned long	flags;
-	} dev[1]; /* allocated with extra space depending of RAID geometry */
-};
-
-/* stripe_head_state - collects and tracks the dynamic state of a stripe_head
- *     for handle_stripe.  It is only valid under spin_lock(sh->lock);
- */
-struct stripe_head_state {
-	int syncing, expanding, expanded;
-	int locked, uptodate, to_read, to_write, failed, written;
-	int to_fill, compute, req_compute, non_overwrite;
-	int failed_num;
-	unsigned long ops_request;
-};
-
-/* r6_state - extra state data only relevant to r6 */
-struct r6_state {
-	int p_failed, q_failed, qd_idx, failed_num[2];
-};
-
-/* Flags */
-#define	R5_UPTODATE	0	/* page contains current data */
-#define	R5_LOCKED	1	/* IO has been submitted on "req" */
-#define	R5_OVERWRITE	2	/* towrite covers whole page */
-/* and some that are internal to handle_stripe */
-#define	R5_Insync	3	/* rdev && rdev->in_sync at start */
-#define	R5_Wantread	4	/* want to schedule a read */
-#define	R5_Wantwrite	5
-#define	R5_Overlap	7	/* There is a pending overlapping request on this block */
-#define	R5_ReadError	8	/* seen a read error here recently */
-#define	R5_ReWrite	9	/* have tried to over-write the readerror */
-
-#define	R5_Expanded	10	/* This block now has post-expand data */
-#define	R5_Wantcompute	11 /* compute_block in progress treat as
-				    * uptodate
-				    */
-#define	R5_Wantfill	12 /* dev->toread contains a bio that needs
-				    * filling
-				    */
-#define R5_Wantdrain	13 /* dev->towrite needs to be drained */
-/*
- * Write method
- */
-#define RECONSTRUCT_WRITE	1
-#define READ_MODIFY_WRITE	2
-/* not a write method, but a compute_parity mode */
-#define	CHECK_PARITY		3
-
-/*
- * Stripe state
- */
-#define STRIPE_HANDLE		2
-#define	STRIPE_SYNCING		3
-#define	STRIPE_INSYNC		4
-#define	STRIPE_PREREAD_ACTIVE	5
-#define	STRIPE_DELAYED		6
-#define	STRIPE_DEGRADED		7
-#define	STRIPE_BIT_DELAY	8
-#define	STRIPE_EXPANDING	9
-#define	STRIPE_EXPAND_SOURCE	10
-#define	STRIPE_EXPAND_READY	11
-#define	STRIPE_IO_STARTED	12 /* do not count towards 'bypass_count' */
-#define	STRIPE_FULL_WRITE	13 /* all blocks are set to be overwritten */
-#define	STRIPE_BIOFILL_RUN	14
-#define	STRIPE_COMPUTE_RUN	15
-/*
- * Operation request flags
- */
-#define STRIPE_OP_BIOFILL	0
-#define STRIPE_OP_COMPUTE_BLK	1
-#define STRIPE_OP_PREXOR	2
-#define STRIPE_OP_BIODRAIN	3
-#define STRIPE_OP_POSTXOR	4
-#define STRIPE_OP_CHECK	5
-
-/*
- * Plugging:
- *
- * To improve write throughput, we need to delay the handling of some
- * stripes until there has been a chance that several write requests
- * for the one stripe have all been collected.
- * In particular, any write request that would require pre-reading
- * is put on a "delayed" queue until there are no stripes currently
- * in a pre-read phase.  Further, if the "delayed" queue is empty when
- * a stripe is put on it then we "plug" the queue and do not process it
- * until an unplug call is made. (the unplug_io_fn() is called).
- *
- * When preread is initiated on a stripe, we set PREREAD_ACTIVE and add
- * it to the count of prereading stripes.
- * When write is initiated, or the stripe refcnt == 0 (just in case) we
- * clear the PREREAD_ACTIVE flag and decrement the count
- * Whenever the 'handle' queue is empty and the device is not plugged, we
- * move any strips from delayed to handle and clear the DELAYED flag and set
- * PREREAD_ACTIVE.
- * In stripe_handle, if we find pre-reading is necessary, we do it if
- * PREREAD_ACTIVE is set, else we set DELAYED which will send it to the delayed queue.
- * HANDLE gets cleared if stripe_handle leave nothing locked.
- */
- 
-
-struct disk_info {
-	mdk_rdev_t	*rdev;
-};
-
-struct raid5_private_data {
-	struct hlist_head	*stripe_hashtbl;
-	mddev_t			*mddev;
-	struct disk_info	*spare;
-	int			chunk_size, level, algorithm;
-	int			max_degraded;
-	int			raid_disks;
-	int			max_nr_stripes;
-
-	/* used during an expand */
-	sector_t		expand_progress;	/* MaxSector when no expand happening */
-	sector_t		expand_lo; /* from here up to expand_progress it out-of-bounds
-					    * as we haven't flushed the metadata yet
-					    */
-	int			previous_raid_disks;
-
-	struct list_head	handle_list; /* stripes needing handling */
-	struct list_head	hold_list; /* preread ready stripes */
-	struct list_head	delayed_list; /* stripes that have plugged requests */
-	struct list_head	bitmap_list; /* stripes delaying awaiting bitmap update */
-	struct bio		*retry_read_aligned; /* currently retrying aligned bios   */
-	struct bio		*retry_read_aligned_list; /* aligned bios retry list  */
-	atomic_t		preread_active_stripes; /* stripes with scheduled io */
-	atomic_t		active_aligned_reads;
-	atomic_t		pending_full_writes; /* full write backlog */
-	int			bypass_count; /* bypassed prereads */
-	int			bypass_threshold; /* preread nice */
-	struct list_head	*last_hold; /* detect hold_list promotions */
-
-	atomic_t		reshape_stripes; /* stripes with pending writes for reshape */
-	/* unfortunately we need two cache names as we temporarily have
-	 * two caches.
-	 */
-	int			active_name;
-	char			cache_name[2][20];
-	struct kmem_cache		*slab_cache; /* for allocating stripes */
-
-	int			seq_flush, seq_write;
-	int			quiesce;
-
-	int			fullsync;  /* set to 1 if a full sync is needed,
-					    * (fresh device added).
-					    * Cleared when a sync completes.
-					    */
-
-	struct page 		*spare_page; /* Used when checking P/Q in raid6 */
-
-	/*
-	 * Free stripes pool
-	 */
-	atomic_t		active_stripes;
-	struct list_head	inactive_list;
-	wait_queue_head_t	wait_for_stripe;
-	wait_queue_head_t	wait_for_overlap;
-	int			inactive_blocked;	/* release of inactive stripes blocked,
-							 * waiting for 25% to be free
-							 */
-	int			pool_size; /* number of disks in stripeheads in pool */
-	spinlock_t		device_lock;
-	struct disk_info	*disks;
-};
-
-typedef struct raid5_private_data raid5_conf_t;
-
-#define mddev_to_conf(mddev) ((raid5_conf_t *) mddev->private)
-
-/*
- * Our supported algorithms
- */
-#define ALGORITHM_LEFT_ASYMMETRIC	0
-#define ALGORITHM_RIGHT_ASYMMETRIC	1
-#define ALGORITHM_LEFT_SYMMETRIC	2
-#define ALGORITHM_RIGHT_SYMMETRIC	3
-
-#endif
diff --git a/include/linux/raid/xor.h b/include/linux/raid/xor.h
index 3e12058..5a21095 100644
--- a/include/linux/raid/xor.h
+++ b/include/linux/raid/xor.h
@@ -1,8 +1,6 @@
 #ifndef _XOR_H
 #define _XOR_H
 
-#include <linux/raid/md.h>
-
 #define MAX_XOR_BLOCKS 4
 
 extern void xor_blocks(unsigned int count, unsigned int bytes,
diff --git a/include/linux/regulator/bq24022.h b/include/linux/regulator/bq24022.h
index e84b0a9..a6d0140 100644
--- a/include/linux/regulator/bq24022.h
+++ b/include/linux/regulator/bq24022.h
@@ -10,6 +10,8 @@
  *
  */
 
+struct regulator_init_data;
+
 /**
  * bq24022_mach_info - platform data for bq24022
  * @gpio_nce: GPIO line connected to the nCE pin, used to enable / disable charging
@@ -18,4 +20,5 @@
 struct bq24022_mach_info {
 	int gpio_nce;
 	int gpio_iset2;
+	struct regulator_init_data *init_data;
 };
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
index 801bf77..277f4b9 100644
--- a/include/linux/regulator/consumer.h
+++ b/include/linux/regulator/consumer.h
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC.
  *
- * Author: Liam Girdwood <lg@opensource.wolfsonmicro.com>
+ * Author: Liam Girdwood <lrg@slimlogic.co.uk>
  *
  * 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
@@ -88,6 +88,7 @@
  * FAIL           Regulator output has failed.
  * OVER_TEMP      Regulator over temp.
  * FORCE_DISABLE  Regulator shut down by software.
+ * VOLTAGE_CHANGE Regulator voltage changed.
  *
  * NOTE: These events can be OR'ed together when passed into handler.
  */
@@ -98,6 +99,7 @@
 #define REGULATOR_EVENT_FAIL			0x08
 #define REGULATOR_EVENT_OVER_TEMP		0x10
 #define REGULATOR_EVENT_FORCE_DISABLE		0x20
+#define REGULATOR_EVENT_VOLTAGE_CHANGE		0x40
 
 struct regulator;
 
@@ -140,6 +142,8 @@
 void regulator_bulk_free(int num_consumers,
 			 struct regulator_bulk_data *consumers);
 
+int regulator_count_voltages(struct regulator *regulator);
+int regulator_list_voltage(struct regulator *regulator, unsigned selector);
 int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV);
 int regulator_get_voltage(struct regulator *regulator);
 int regulator_set_current_limit(struct regulator *regulator,
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index 2dae057..4848d8d 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC.
  *
- * Author: Liam Girdwood <lg@opensource.wolfsonmicro.com>
+ * Author: Liam Girdwood <lrg@slimlogic.co.uk>
  *
  * 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
@@ -21,25 +21,38 @@
 struct regulator_dev;
 struct regulator_init_data;
 
+enum regulator_status {
+	REGULATOR_STATUS_OFF,
+	REGULATOR_STATUS_ON,
+	REGULATOR_STATUS_ERROR,
+	/* fast/normal/idle/standby are flavors of "on" */
+	REGULATOR_STATUS_FAST,
+	REGULATOR_STATUS_NORMAL,
+	REGULATOR_STATUS_IDLE,
+	REGULATOR_STATUS_STANDBY,
+};
+
 /**
  * struct regulator_ops - regulator operations.
  *
- * This struct describes regulator operations which can be implemented by
- * regulator chip drivers.
- *
- * @enable: Enable the regulator.
- * @disable: Disable the regulator.
+ * @enable: Configure the regulator as enabled.
+ * @disable: Configure the regulator as disabled.
  * @is_enabled: Return 1 if the regulator is enabled, 0 otherwise.
  *
  * @set_voltage: Set the voltage for the regulator within the range specified.
  *               The driver should select the voltage closest to min_uV.
  * @get_voltage: Return the currently configured voltage for the regulator.
+ * @list_voltage: Return one of the supported voltages, in microvolts; zero
+ *	if the selector indicates a voltage that is unusable on this system;
+ *	or negative errno.  Selectors range from zero to one less than
+ *	regulator_desc.n_voltages.  Voltages may be reported in any order.
  *
  * @set_current_limit: Configure a limit for a current-limited regulator.
- * @get_current_limit: Get the limit for a current-limited regulator.
+ * @get_current_limit: Get the configured limit for a current-limited regulator.
  *
- * @set_mode: Set the operating mode for the regulator.
- * @get_mode: Get the current operating mode for the regulator.
+ * @get_mode: Get the configured operating mode for the regulator.
+ * @get_status: Return actual (not as-configured) status of regulator, as a
+ *	REGULATOR_STATUS value (or negative errno)
  * @get_optimum_mode: Get the most efficient operating mode for the regulator
  *                    when running with the specified parameters.
  *
@@ -51,9 +64,15 @@
  *                       suspended.
  * @set_suspend_mode: Set the operating mode for the regulator when the
  *                    system is suspended.
+ *
+ * This struct describes regulator operations which can be implemented by
+ * regulator chip drivers.
  */
 struct regulator_ops {
 
+	/* enumerate supported voltages */
+	int (*list_voltage) (struct regulator_dev *, unsigned selector);
+
 	/* get/set regulator voltage */
 	int (*set_voltage) (struct regulator_dev *, int min_uV, int max_uV);
 	int (*get_voltage) (struct regulator_dev *);
@@ -72,6 +91,13 @@
 	int (*set_mode) (struct regulator_dev *, unsigned int mode);
 	unsigned int (*get_mode) (struct regulator_dev *);
 
+	/* report regulator status ... most other accessors report
+	 * control inputs, this reports results of combining inputs
+	 * from Linux (and other sources) with the actual load.
+	 * returns REGULATOR_STATUS_* or negative errno.
+	 */
+	int (*get_status)(struct regulator_dev *);
+
 	/* get most efficient regulator operating mode for load */
 	unsigned int (*get_optimum_mode) (struct regulator_dev *, int input_uV,
 					  int output_uV, int load_uA);
@@ -106,6 +132,7 @@
  *
  * @name: Identifying name for the regulator.
  * @id: Numerical identifier for the regulator.
+ * @n_voltages: Number of selectors available for ops.list_voltage().
  * @ops: Regulator operations table.
  * @irq: Interrupt number for the regulator.
  * @type: Indicates if the regulator is a voltage or current regulator.
@@ -114,14 +141,48 @@
 struct regulator_desc {
 	const char *name;
 	int id;
+	unsigned n_voltages;
 	struct regulator_ops *ops;
 	int irq;
 	enum regulator_type type;
 	struct module *owner;
 };
 
+/*
+ * struct regulator_dev
+ *
+ * Voltage / Current regulator class device. One for each
+ * regulator.
+ *
+ * This should *not* be used directly by anything except the regulator
+ * core and notification injection (which should take the mutex and do
+ * no other direct access).
+ */
+struct regulator_dev {
+	struct regulator_desc *desc;
+	int use_count;
+
+	/* lists we belong to */
+	struct list_head list; /* list of all regulators */
+	struct list_head slist; /* list of supplied regulators */
+
+	/* lists we own */
+	struct list_head consumer_list; /* consumers we supply */
+	struct list_head supply_list; /* regulators we supply */
+
+	struct blocking_notifier_head notifier;
+	struct mutex mutex; /* consumer lock */
+	struct module *owner;
+	struct device dev;
+	struct regulation_constraints *constraints;
+	struct regulator_dev *supply;	/* for tree */
+
+	void *reg_data;		/* regulator_dev data */
+};
+
 struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
-	struct device *dev, void *driver_data);
+	struct device *dev, struct regulator_init_data *init_data,
+	void *driver_data);
 void regulator_unregister(struct regulator_dev *rdev);
 
 int regulator_notifier_call_chain(struct regulator_dev *rdev,
diff --git a/include/linux/regulator/fixed.h b/include/linux/regulator/fixed.h
index 1387a5d..91b4da3 100644
--- a/include/linux/regulator/fixed.h
+++ b/include/linux/regulator/fixed.h
@@ -14,9 +14,12 @@
 #ifndef __REGULATOR_FIXED_H
 #define __REGULATOR_FIXED_H
 
+struct regulator_init_data;
+
 struct fixed_voltage_config {
 	const char *supply_name;
 	int microvolts;
+	struct regulator_init_data *init_data;
 };
 
 #endif
diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h
index 3794773..bac64fa 100644
--- a/include/linux/regulator/machine.h
+++ b/include/linux/regulator/machine.h
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC.
  *
- * Author: Liam Girdwood <lg@opensource.wolfsonmicro.com>
+ * Author: Liam Girdwood <lrg@slimlogic.co.uk>
  *
  * 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
@@ -73,7 +73,9 @@
  *
  * @always_on: Set if the regulator should never be disabled.
  * @boot_on: Set if the regulator is enabled when the system is initially
- *           started.
+ *           started.  If the regulator is not enabled by the hardware or
+ *           bootloader then it will be enabled when the constraints are
+ *           applied.
  * @apply_uV: Apply the voltage constraint when initialising.
  *
  * @input_uV: Input voltage for regulator when supplied by another regulator.
@@ -83,6 +85,7 @@
  * @state_standby: State for regulator when system is suspended in standby
  *                 mode.
  * @initial_state: Suspend state to set by default.
+ * @initial_mode: Mode to set at startup.
  */
 struct regulation_constraints {
 
@@ -111,6 +114,9 @@
 	struct regulator_state state_standby;
 	suspend_state_t initial_state; /* suspend state to set at init */
 
+	/* mode to set on startup */
+	unsigned int initial_mode;
+
 	/* constriant flags */
 	unsigned always_on:1;	/* regulator never off when system is on */
 	unsigned boot_on:1;	/* bootloader/firmware enabled regulator */
@@ -160,4 +166,6 @@
 
 int regulator_suspend_prepare(suspend_state_t state);
 
+void regulator_has_full_constraints(void);
+
 #endif
diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h
index b3b3596..e1b7b21 100644
--- a/include/linux/ring_buffer.h
+++ b/include/linux/ring_buffer.h
@@ -8,7 +8,7 @@
 struct ring_buffer_iter;
 
 /*
- * Don't reference this struct directly, use functions below.
+ * Don't refer to this struct directly, use functions below.
  */
 struct ring_buffer_event {
 	u32		type:2, len:3, time_delta:27;
@@ -18,10 +18,13 @@
 /**
  * enum ring_buffer_type - internal ring buffer types
  *
- * @RINGBUF_TYPE_PADDING:	Left over page padding
- *				 array is ignored
- *				 size is variable depending on how much
+ * @RINGBUF_TYPE_PADDING:	Left over page padding or discarded event
+ *				 If time_delta is 0:
+ *				  array is ignored
+ *				  size is variable depending on how much
  *				  padding is needed
+ *				 If time_delta is non zero:
+ *				  everything else same as RINGBUF_TYPE_DATA
  *
  * @RINGBUF_TYPE_TIME_EXTEND:	Extend the time delta
  *				 array[0] = time delta (28 .. 59)
@@ -65,6 +68,8 @@
 	return event->time_delta;
 }
 
+void ring_buffer_event_discard(struct ring_buffer_event *event);
+
 /*
  * size is in bytes for each per CPU buffer.
  */
@@ -74,13 +79,10 @@
 
 int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size);
 
-struct ring_buffer_event *
-ring_buffer_lock_reserve(struct ring_buffer *buffer,
-			 unsigned long length,
-			 unsigned long *flags);
+struct ring_buffer_event *ring_buffer_lock_reserve(struct ring_buffer *buffer,
+						   unsigned long length);
 int ring_buffer_unlock_commit(struct ring_buffer *buffer,
-			      struct ring_buffer_event *event,
-			      unsigned long flags);
+			      struct ring_buffer_event *event);
 int ring_buffer_write(struct ring_buffer *buffer,
 		      unsigned long length, void *data);
 
@@ -121,17 +123,19 @@
 unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu);
 unsigned long ring_buffer_overrun_cpu(struct ring_buffer *buffer, int cpu);
 
-u64 ring_buffer_time_stamp(int cpu);
-void ring_buffer_normalize_time_stamp(int cpu, u64 *ts);
+u64 ring_buffer_time_stamp(struct ring_buffer *buffer, int cpu);
+void ring_buffer_normalize_time_stamp(struct ring_buffer *buffer,
+				      int cpu, u64 *ts);
+void ring_buffer_set_clock(struct ring_buffer *buffer,
+			   u64 (*clock)(void));
 
-void tracing_on(void);
-void tracing_off(void);
-void tracing_off_permanent(void);
+size_t ring_buffer_page_len(void *page);
+
 
 void *ring_buffer_alloc_read_page(struct ring_buffer *buffer);
 void ring_buffer_free_read_page(struct ring_buffer *buffer, void *data);
-int ring_buffer_read_page(struct ring_buffer *buffer,
-			  void **data_page, int cpu, int full);
+int ring_buffer_read_page(struct ring_buffer *buffer, void **data_page,
+			  size_t len, int cpu, int full);
 
 enum ring_buffer_flags {
 	RB_FL_OVERWRITE		= 1 << 0,
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 9da5aa0..b94f354 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -138,6 +138,8 @@
 extern unsigned long nr_active(void);
 extern unsigned long nr_iowait(void);
 
+extern unsigned long get_parent_ip(unsigned long addr);
+
 struct seq_file;
 struct cfs_rq;
 struct task_group;
@@ -1405,6 +1407,8 @@
 	int curr_ret_stack;
 	/* Stack of return addresses for return function tracing */
 	struct ftrace_ret_stack	*ret_stack;
+	/* time stamp for last schedule */
+	unsigned long long ftrace_timestamp;
 	/*
 	 * Number of functions that haven't been traced
 	 * because of depth overrun.
diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h
index 6ca6a7b..f452365 100644
--- a/include/linux/slab_def.h
+++ b/include/linux/slab_def.h
@@ -14,6 +14,7 @@
 #include <asm/page.h>		/* kmalloc_sizes.h needs PAGE_SIZE */
 #include <asm/cache.h>		/* kmalloc_sizes.h needs L1_CACHE_BYTES */
 #include <linux/compiler.h>
+#include <trace/kmemtrace.h>
 
 /* Size description struct for general caches. */
 struct cache_sizes {
@@ -28,8 +29,26 @@
 void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
 void *__kmalloc(size_t size, gfp_t flags);
 
-static inline void *kmalloc(size_t size, gfp_t flags)
+#ifdef CONFIG_KMEMTRACE
+extern void *kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags);
+extern size_t slab_buffer_size(struct kmem_cache *cachep);
+#else
+static __always_inline void *
+kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags)
 {
+	return kmem_cache_alloc(cachep, flags);
+}
+static inline size_t slab_buffer_size(struct kmem_cache *cachep)
+{
+	return 0;
+}
+#endif
+
+static __always_inline void *kmalloc(size_t size, gfp_t flags)
+{
+	struct kmem_cache *cachep;
+	void *ret;
+
 	if (__builtin_constant_p(size)) {
 		int i = 0;
 
@@ -47,10 +66,17 @@
 found:
 #ifdef CONFIG_ZONE_DMA
 		if (flags & GFP_DMA)
-			return kmem_cache_alloc(malloc_sizes[i].cs_dmacachep,
-						flags);
+			cachep = malloc_sizes[i].cs_dmacachep;
+		else
 #endif
-		return kmem_cache_alloc(malloc_sizes[i].cs_cachep, flags);
+			cachep = malloc_sizes[i].cs_cachep;
+
+		ret = kmem_cache_alloc_notrace(cachep, flags);
+
+		kmemtrace_mark_alloc(KMEMTRACE_TYPE_KMALLOC, _THIS_IP_, ret,
+				     size, slab_buffer_size(cachep), flags);
+
+		return ret;
 	}
 	return __kmalloc(size, flags);
 }
@@ -59,8 +85,25 @@
 extern void *__kmalloc_node(size_t size, gfp_t flags, int node);
 extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
 
-static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
+#ifdef CONFIG_KMEMTRACE
+extern void *kmem_cache_alloc_node_notrace(struct kmem_cache *cachep,
+					   gfp_t flags,
+					   int nodeid);
+#else
+static __always_inline void *
+kmem_cache_alloc_node_notrace(struct kmem_cache *cachep,
+			      gfp_t flags,
+			      int nodeid)
 {
+	return kmem_cache_alloc_node(cachep, flags, nodeid);
+}
+#endif
+
+static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node)
+{
+	struct kmem_cache *cachep;
+	void *ret;
+
 	if (__builtin_constant_p(size)) {
 		int i = 0;
 
@@ -78,11 +121,18 @@
 found:
 #ifdef CONFIG_ZONE_DMA
 		if (flags & GFP_DMA)
-			return kmem_cache_alloc_node(malloc_sizes[i].cs_dmacachep,
-						flags, node);
+			cachep = malloc_sizes[i].cs_dmacachep;
+		else
 #endif
-		return kmem_cache_alloc_node(malloc_sizes[i].cs_cachep,
-						flags, node);
+			cachep = malloc_sizes[i].cs_cachep;
+
+		ret = kmem_cache_alloc_node_notrace(cachep, flags, node);
+
+		kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_KMALLOC, _THIS_IP_,
+					  ret, size, slab_buffer_size(cachep),
+					  flags, node);
+
+		return ret;
 	}
 	return __kmalloc_node(size, flags, node);
 }
diff --git a/include/linux/slob_def.h b/include/linux/slob_def.h
index 59a3fa4..0ec00b3 100644
--- a/include/linux/slob_def.h
+++ b/include/linux/slob_def.h
@@ -3,14 +3,15 @@
 
 void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
 
-static inline void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags)
+static __always_inline void *kmem_cache_alloc(struct kmem_cache *cachep,
+					      gfp_t flags)
 {
 	return kmem_cache_alloc_node(cachep, flags, -1);
 }
 
 void *__kmalloc_node(size_t size, gfp_t flags, int node);
 
-static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
+static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node)
 {
 	return __kmalloc_node(size, flags, node);
 }
@@ -23,12 +24,12 @@
  * kmalloc is the normal method of allocating memory
  * in the kernel.
  */
-static inline void *kmalloc(size_t size, gfp_t flags)
+static __always_inline void *kmalloc(size_t size, gfp_t flags)
 {
 	return __kmalloc_node(size, flags, -1);
 }
 
-static inline void *__kmalloc(size_t size, gfp_t flags)
+static __always_inline void *__kmalloc(size_t size, gfp_t flags)
 {
 	return kmalloc(size, flags);
 }
diff --git a/include/linux/slow-work.h b/include/linux/slow-work.h
new file mode 100644
index 0000000..8595827
--- /dev/null
+++ b/include/linux/slow-work.h
@@ -0,0 +1,95 @@
+/* Worker thread pool for slow items, such as filesystem lookups or mkdirs
+ *
+ * Copyright (C) 2008 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.
+ *
+ * See Documentation/slow-work.txt
+ */
+
+#ifndef _LINUX_SLOW_WORK_H
+#define _LINUX_SLOW_WORK_H
+
+#ifdef CONFIG_SLOW_WORK
+
+#include <linux/sysctl.h>
+
+struct slow_work;
+
+/*
+ * The operations used to support slow work items
+ */
+struct slow_work_ops {
+	/* get a ref on a work item
+	 * - return 0 if successful, -ve if not
+	 */
+	int (*get_ref)(struct slow_work *work);
+
+	/* discard a ref to a work item */
+	void (*put_ref)(struct slow_work *work);
+
+	/* execute a work item */
+	void (*execute)(struct slow_work *work);
+};
+
+/*
+ * A slow work item
+ * - A reference is held on the parent object by the thread pool when it is
+ *   queued
+ */
+struct slow_work {
+	unsigned long		flags;
+#define SLOW_WORK_PENDING	0	/* item pending (further) execution */
+#define SLOW_WORK_EXECUTING	1	/* item currently executing */
+#define SLOW_WORK_ENQ_DEFERRED	2	/* item enqueue deferred */
+#define SLOW_WORK_VERY_SLOW	3	/* item is very slow */
+	const struct slow_work_ops *ops; /* operations table for this item */
+	struct list_head	link;	/* link in queue */
+};
+
+/**
+ * slow_work_init - Initialise a slow work item
+ * @work: The work item to initialise
+ * @ops: The operations to use to handle the slow work item
+ *
+ * Initialise a slow work item.
+ */
+static inline void slow_work_init(struct slow_work *work,
+				  const struct slow_work_ops *ops)
+{
+	work->flags = 0;
+	work->ops = ops;
+	INIT_LIST_HEAD(&work->link);
+}
+
+/**
+ * slow_work_init - Initialise a very slow work item
+ * @work: The work item to initialise
+ * @ops: The operations to use to handle the slow work item
+ *
+ * Initialise a very slow work item.  This item will be restricted such that
+ * only a certain number of the pool threads will be able to execute items of
+ * this type.
+ */
+static inline void vslow_work_init(struct slow_work *work,
+				   const struct slow_work_ops *ops)
+{
+	work->flags = 1 << SLOW_WORK_VERY_SLOW;
+	work->ops = ops;
+	INIT_LIST_HEAD(&work->link);
+}
+
+extern int slow_work_enqueue(struct slow_work *work);
+extern int slow_work_register_user(void);
+extern void slow_work_unregister_user(void);
+
+#ifdef CONFIG_SYSCTL
+extern ctl_table slow_work_sysctls[];
+#endif
+
+#endif /* CONFIG_SLOW_WORK */
+#endif /* _LINUX_SLOW_WORK_H */
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
index e37b6aa..a1f9052 100644
--- a/include/linux/slub_def.h
+++ b/include/linux/slub_def.h
@@ -10,6 +10,7 @@
 #include <linux/gfp.h>
 #include <linux/workqueue.h>
 #include <linux/kobject.h>
+#include <trace/kmemtrace.h>
 
 enum stat_item {
 	ALLOC_FASTPATH,		/* Allocation from cpu slab */
@@ -217,13 +218,31 @@
 void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
 void *__kmalloc(size_t size, gfp_t flags);
 
+#ifdef CONFIG_KMEMTRACE
+extern void *kmem_cache_alloc_notrace(struct kmem_cache *s, gfp_t gfpflags);
+#else
+static __always_inline void *
+kmem_cache_alloc_notrace(struct kmem_cache *s, gfp_t gfpflags)
+{
+	return kmem_cache_alloc(s, gfpflags);
+}
+#endif
+
 static __always_inline void *kmalloc_large(size_t size, gfp_t flags)
 {
-	return (void *)__get_free_pages(flags | __GFP_COMP, get_order(size));
+	unsigned int order = get_order(size);
+	void *ret = (void *) __get_free_pages(flags | __GFP_COMP, order);
+
+	kmemtrace_mark_alloc(KMEMTRACE_TYPE_KMALLOC, _THIS_IP_, ret,
+			     size, PAGE_SIZE << order, flags);
+
+	return ret;
 }
 
 static __always_inline void *kmalloc(size_t size, gfp_t flags)
 {
+	void *ret;
+
 	if (__builtin_constant_p(size)) {
 		if (size > SLUB_MAX_SIZE)
 			return kmalloc_large(size, flags);
@@ -234,7 +253,13 @@
 			if (!s)
 				return ZERO_SIZE_PTR;
 
-			return kmem_cache_alloc(s, flags);
+			ret = kmem_cache_alloc_notrace(s, flags);
+
+			kmemtrace_mark_alloc(KMEMTRACE_TYPE_KMALLOC,
+					     _THIS_IP_, ret,
+					     size, s->size, flags);
+
+			return ret;
 		}
 	}
 	return __kmalloc(size, flags);
@@ -244,8 +269,24 @@
 void *__kmalloc_node(size_t size, gfp_t flags, int node);
 void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
 
+#ifdef CONFIG_KMEMTRACE
+extern void *kmem_cache_alloc_node_notrace(struct kmem_cache *s,
+					   gfp_t gfpflags,
+					   int node);
+#else
+static __always_inline void *
+kmem_cache_alloc_node_notrace(struct kmem_cache *s,
+			      gfp_t gfpflags,
+			      int node)
+{
+	return kmem_cache_alloc_node(s, gfpflags, node);
+}
+#endif
+
 static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node)
 {
+	void *ret;
+
 	if (__builtin_constant_p(size) &&
 		size <= SLUB_MAX_SIZE && !(flags & SLUB_DMA)) {
 			struct kmem_cache *s = kmalloc_slab(size);
@@ -253,7 +294,13 @@
 		if (!s)
 			return ZERO_SIZE_PTR;
 
-		return kmem_cache_alloc_node(s, flags, node);
+		ret = kmem_cache_alloc_node_notrace(s, flags, node);
+
+		kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_KMALLOC,
+					  _THIS_IP_, ret,
+					  size, s->size, flags, node);
+
+		return ret;
 	}
 	return __kmalloc_node(size, flags, node);
 }
diff --git a/include/linux/smp.h b/include/linux/smp.h
index bbacb7b..a69db82 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -38,7 +38,7 @@
 /*
  * main cross-CPU interfaces, handles INIT, TLB flush, STOP, etc.
  * (defined in asm header):
- */ 
+ */
 
 /*
  * stops all CPUs but the current one:
@@ -82,7 +82,8 @@
 	return 0;
 }
 
-void __smp_call_function_single(int cpuid, struct call_single_data *data);
+void __smp_call_function_single(int cpuid, struct call_single_data *data,
+				int wait);
 
 /*
  * Generic and arch helpers
@@ -121,6 +122,8 @@
 
 #else /* !SMP */
 
+static inline void smp_send_stop(void) { }
+
 /*
  *	These macros fold the SMP functionality into a single CPU system
  */
diff --git a/include/linux/sonypi.h b/include/linux/sonypi.h
index f41ffd7..34c4475 100644
--- a/include/linux/sonypi.h
+++ b/include/linux/sonypi.h
@@ -103,6 +103,14 @@
 #define SONYPI_EVENT_WIRELESS_OFF		61
 #define SONYPI_EVENT_ZOOM_IN_PRESSED		62
 #define SONYPI_EVENT_ZOOM_OUT_PRESSED		63
+#define SONYPI_EVENT_CD_EJECT_PRESSED		64
+#define SONYPI_EVENT_MODEKEY_PRESSED		65
+#define SONYPI_EVENT_PKEY_P4			66
+#define SONYPI_EVENT_PKEY_P5			67
+#define SONYPI_EVENT_SETTINGKEY_PRESSED		68
+#define SONYPI_EVENT_VOLUME_INC_PRESSED		69
+#define SONYPI_EVENT_VOLUME_DEC_PRESSED		70
+#define SONYPI_EVENT_BRIGHTNESS_PRESSED		71
 
 /* get/set brightness */
 #define SONYPI_IOCGBRT		_IOR('v', 0, __u8)
diff --git a/include/linux/string.h b/include/linux/string.h
index 8852739..489019e 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -10,6 +10,7 @@
 #include <linux/compiler.h>	/* for inline */
 #include <linux/types.h>	/* for size_t */
 #include <linux/stddef.h>	/* for NULL */
+#include <stdarg.h>
 
 extern char *strndup_user(const char __user *, long);
 extern void *memdup_user(const void __user *, size_t);
@@ -112,8 +113,23 @@
 
 extern bool sysfs_streq(const char *s1, const char *s2);
 
+#ifdef CONFIG_BINARY_PRINTF
+int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args);
+int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf);
+int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...) __printf(3, 4);
+#endif
+
 extern ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos,
 			const void *from, size_t available);
 
+/**
+ * strstarts - does @str start with @prefix?
+ * @str: string to examine
+ * @prefix: prefix to look for.
+ */
+static inline bool strstarts(const char *str, const char *prefix)
+{
+	return strncmp(str, prefix, strlen(prefix)) == 0;
+}
 #endif
 #endif /* _LINUX_STRING_H_ */
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index b299a82..6470f74 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -65,6 +65,7 @@
 #include <asm/signal.h>
 #include <linux/quota.h>
 #include <linux/key.h>
+#include <linux/ftrace.h>
 
 #define __SC_DECL1(t1, a1)	t1 a1
 #define __SC_DECL2(t2, a2, ...) t2 a2, __SC_DECL1(__VA_ARGS__)
@@ -95,7 +96,46 @@
 #define __SC_TEST5(t5, a5, ...)	__SC_TEST(t5); __SC_TEST4(__VA_ARGS__)
 #define __SC_TEST6(t6, a6, ...)	__SC_TEST(t6); __SC_TEST5(__VA_ARGS__)
 
+#ifdef CONFIG_FTRACE_SYSCALLS
+#define __SC_STR_ADECL1(t, a)		#a
+#define __SC_STR_ADECL2(t, a, ...)	#a, __SC_STR_ADECL1(__VA_ARGS__)
+#define __SC_STR_ADECL3(t, a, ...)	#a, __SC_STR_ADECL2(__VA_ARGS__)
+#define __SC_STR_ADECL4(t, a, ...)	#a, __SC_STR_ADECL3(__VA_ARGS__)
+#define __SC_STR_ADECL5(t, a, ...)	#a, __SC_STR_ADECL4(__VA_ARGS__)
+#define __SC_STR_ADECL6(t, a, ...)	#a, __SC_STR_ADECL5(__VA_ARGS__)
+
+#define __SC_STR_TDECL1(t, a)		#t
+#define __SC_STR_TDECL2(t, a, ...)	#t, __SC_STR_TDECL1(__VA_ARGS__)
+#define __SC_STR_TDECL3(t, a, ...)	#t, __SC_STR_TDECL2(__VA_ARGS__)
+#define __SC_STR_TDECL4(t, a, ...)	#t, __SC_STR_TDECL3(__VA_ARGS__)
+#define __SC_STR_TDECL5(t, a, ...)	#t, __SC_STR_TDECL4(__VA_ARGS__)
+#define __SC_STR_TDECL6(t, a, ...)	#t, __SC_STR_TDECL5(__VA_ARGS__)
+
+#define SYSCALL_METADATA(sname, nb)				\
+	static const struct syscall_metadata __used		\
+	  __attribute__((__aligned__(4)))			\
+	  __attribute__((section("__syscalls_metadata")))	\
+	  __syscall_meta_##sname = {				\
+		.name 		= "sys"#sname,			\
+		.nb_args 	= nb,				\
+		.types		= types_##sname,		\
+		.args		= args_##sname,			\
+	}
+
+#define SYSCALL_DEFINE0(sname)					\
+	static const struct syscall_metadata __used		\
+	  __attribute__((__aligned__(4)))			\
+	  __attribute__((section("__syscalls_metadata")))	\
+	  __syscall_meta_##sname = {				\
+		.name 		= "sys_"#sname,			\
+		.nb_args 	= 0,				\
+	};							\
+	asmlinkage long sys_##sname(void)
+
+#else
 #define SYSCALL_DEFINE0(name)	   asmlinkage long sys_##name(void)
+#endif
+
 #define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__)
 #define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__)
 #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
@@ -117,10 +157,26 @@
 #endif
 #endif
 
+#ifdef CONFIG_FTRACE_SYSCALLS
+#define SYSCALL_DEFINEx(x, sname, ...)				\
+	static const char *types_##sname[] = {			\
+		__SC_STR_TDECL##x(__VA_ARGS__)			\
+	};							\
+	static const char *args_##sname[] = {			\
+		__SC_STR_ADECL##x(__VA_ARGS__)			\
+	};							\
+	SYSCALL_METADATA(sname, x);				\
+	__SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
+#else
+#define SYSCALL_DEFINEx(x, sname, ...)				\
+	__SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
+#endif
+
 #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
 
 #define SYSCALL_DEFINE(name) static inline long SYSC_##name
-#define SYSCALL_DEFINEx(x, name, ...)					\
+
+#define __SYSCALL_DEFINEx(x, name, ...)					\
 	asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__));		\
 	static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__));	\
 	asmlinkage long SyS##name(__SC_LONG##x(__VA_ARGS__))		\
@@ -134,7 +190,7 @@
 #else /* CONFIG_HAVE_SYSCALL_WRAPPERS */
 
 #define SYSCALL_DEFINE(name) asmlinkage long sys_##name
-#define SYSCALL_DEFINEx(x, name, ...)					\
+#define __SYSCALL_DEFINEx(x, name, ...)					\
 	asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__))
 
 #endif /* CONFIG_HAVE_SYSCALL_WRAPPERS */
@@ -462,9 +518,9 @@
 asmlinkage long sys_pwrite64(unsigned int fd, const char __user *buf,
 			     size_t count, loff_t pos);
 asmlinkage long sys_preadv(unsigned long fd, const struct iovec __user *vec,
-			   unsigned long vlen, u32 pos_high, u32 pos_low);
+			   unsigned long vlen, unsigned long pos_l, unsigned long pos_h);
 asmlinkage long sys_pwritev(unsigned long fd, const struct iovec __user *vec,
-			    unsigned long vlen, u32 pos_high, u32 pos_low);
+			    unsigned long vlen, unsigned long pos_l, unsigned long pos_h);
 asmlinkage long sys_getcwd(char __user *buf, unsigned long size);
 asmlinkage long sys_mkdir(const char __user *pathname, int mode);
 asmlinkage long sys_chdir(const char __user *filename);
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 917707e..1de8b9eb 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -27,27 +27,46 @@
 
 #include <linux/idr.h>
 #include <linux/device.h>
+#include <linux/workqueue.h>
 
 struct thermal_zone_device;
 struct thermal_cooling_device;
 
+enum thermal_device_mode {
+	THERMAL_DEVICE_DISABLED = 0,
+	THERMAL_DEVICE_ENABLED,
+};
+
+enum thermal_trip_type {
+	THERMAL_TRIP_ACTIVE = 0,
+	THERMAL_TRIP_PASSIVE,
+	THERMAL_TRIP_HOT,
+	THERMAL_TRIP_CRITICAL,
+};
+
 struct thermal_zone_device_ops {
 	int (*bind) (struct thermal_zone_device *,
 		     struct thermal_cooling_device *);
 	int (*unbind) (struct thermal_zone_device *,
 		       struct thermal_cooling_device *);
-	int (*get_temp) (struct thermal_zone_device *, char *);
-	int (*get_mode) (struct thermal_zone_device *, char *);
-	int (*set_mode) (struct thermal_zone_device *, const char *);
-	int (*get_trip_type) (struct thermal_zone_device *, int, char *);
-	int (*get_trip_temp) (struct thermal_zone_device *, int, char *);
+	int (*get_temp) (struct thermal_zone_device *, unsigned long *);
+	int (*get_mode) (struct thermal_zone_device *,
+			 enum thermal_device_mode *);
+	int (*set_mode) (struct thermal_zone_device *,
+		enum thermal_device_mode);
+	int (*get_trip_type) (struct thermal_zone_device *, int,
+		enum thermal_trip_type *);
+	int (*get_trip_temp) (struct thermal_zone_device *, int,
+			      unsigned long *);
 	int (*get_crit_temp) (struct thermal_zone_device *, unsigned long *);
+	int (*notify) (struct thermal_zone_device *, int,
+		       enum thermal_trip_type);
 };
 
 struct thermal_cooling_device_ops {
-	int (*get_max_state) (struct thermal_cooling_device *, char *);
-	int (*get_cur_state) (struct thermal_cooling_device *, char *);
-	int (*set_cur_state) (struct thermal_cooling_device *, unsigned int);
+	int (*get_max_state) (struct thermal_cooling_device *, unsigned long *);
+	int (*get_cur_state) (struct thermal_cooling_device *, unsigned long *);
+	int (*set_cur_state) (struct thermal_cooling_device *, unsigned long);
 };
 
 #define THERMAL_TRIPS_NONE -1
@@ -88,11 +107,19 @@
 	struct device device;
 	void *devdata;
 	int trips;
+	int tc1;
+	int tc2;
+	int passive_delay;
+	int polling_delay;
+	int last_temperature;
+	bool passive;
+	unsigned int forced_passive;
 	struct thermal_zone_device_ops *ops;
 	struct list_head cooling_devices;
 	struct idr idr;
 	struct mutex lock;	/* protect cooling devices list */
 	struct list_head node;
+	struct delayed_work poll_queue;
 #if defined(CONFIG_THERMAL_HWMON)
 	struct list_head hwmon_node;
 	struct thermal_hwmon_device *hwmon;
@@ -104,13 +131,16 @@
 struct thermal_zone_device *thermal_zone_device_register(char *, int, void *,
 							 struct
 							 thermal_zone_device_ops
-							 *);
+							 *, int tc1, int tc2,
+							 int passive_freq,
+							 int polling_freq);
 void thermal_zone_device_unregister(struct thermal_zone_device *);
 
 int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int,
 				     struct thermal_cooling_device *);
 int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int,
 				       struct thermal_cooling_device *);
+void thermal_zone_device_update(struct thermal_zone_device *);
 struct thermal_cooling_device *thermal_cooling_device_register(char *, void *,
 							       struct
 							       thermal_cooling_device_ops
diff --git a/include/linux/timeriomem-rng.h b/include/linux/timeriomem-rng.h
index dd25317..3e08a1c 100644
--- a/include/linux/timeriomem-rng.h
+++ b/include/linux/timeriomem-rng.h
@@ -14,7 +14,7 @@
 	struct completion	completion;
 	unsigned int		present:1;
 
-	u32 __iomem		*address;
+	void __iomem		*address;
 
 	/* measures in usecs */
 	unsigned int		period;
diff --git a/include/linux/topology.h b/include/linux/topology.h
index a16b9e0..7402c1a 100644
--- a/include/linux/topology.h
+++ b/include/linux/topology.h
@@ -38,11 +38,7 @@
 #endif
 
 #ifndef nr_cpus_node
-#define nr_cpus_node(node)				\
-	({						\
-		node_to_cpumask_ptr(__tmp__, node);	\
-		cpus_weight(*__tmp__);			\
-	})
+#define nr_cpus_node(node) cpumask_weight(cpumask_of_node(node))
 #endif
 
 #define for_each_node_with_cpus(node)			\
@@ -200,4 +196,9 @@
 #define topology_core_cpumask(cpu)		cpumask_of(cpu)
 #endif
 
+/* Returns the number of the current Node. */
+#ifndef numa_node_id
+#define numa_node_id()		(cpu_to_node(raw_smp_processor_id()))
+#endif
+
 #endif /* _LINUX_TOPOLOGY_H */
diff --git a/include/linux/trace_clock.h b/include/linux/trace_clock.h
new file mode 100644
index 0000000..7a81303
--- /dev/null
+++ b/include/linux/trace_clock.h
@@ -0,0 +1,19 @@
+#ifndef _LINUX_TRACE_CLOCK_H
+#define _LINUX_TRACE_CLOCK_H
+
+/*
+ * 3 trace clock variants, with differing scalability/precision
+ * tradeoffs:
+ *
+ *  -   local: CPU-local trace clock
+ *  -  medium: scalable global clock with some jitter
+ *  -  global: globally monotonic, serialized clock
+ */
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+extern u64 notrace trace_clock_local(void);
+extern u64 notrace trace_clock(void);
+extern u64 notrace trace_clock_global(void);
+
+#endif /* _LINUX_TRACE_CLOCK_H */
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index 7570054..d35a7ee 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -31,8 +31,8 @@
 					 * Keep in sync with vmlinux.lds.h.
 					 */
 
-#define TPPROTO(args...)	args
-#define TPARGS(args...)		args
+#define TP_PROTO(args...)	args
+#define TP_ARGS(args...)		args
 
 #ifdef CONFIG_TRACEPOINTS
 
@@ -65,7 +65,7 @@
 	{								\
 		if (unlikely(__tracepoint_##name.state))		\
 			__DO_TRACE(&__tracepoint_##name,		\
-				TPPROTO(proto), TPARGS(args));		\
+				TP_PROTO(proto), TP_ARGS(args));	\
 	}								\
 	static inline int register_trace_##name(void (*probe)(proto))	\
 	{								\
@@ -153,4 +153,114 @@
 	synchronize_sched();
 }
 
+#define PARAMS(args...) args
+#define TRACE_FORMAT(name, proto, args, fmt)		\
+	DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
+
+
+/*
+ * For use with the TRACE_EVENT macro:
+ *
+ * We define a tracepoint, its arguments, its printk format
+ * and its 'fast binay record' layout.
+ *
+ * Firstly, name your tracepoint via TRACE_EVENT(name : the
+ * 'subsystem_event' notation is fine.
+ *
+ * Think about this whole construct as the
+ * 'trace_sched_switch() function' from now on.
+ *
+ *
+ *  TRACE_EVENT(sched_switch,
+ *
+ *	*
+ *	* A function has a regular function arguments
+ *	* prototype, declare it via TP_PROTO():
+ *	*
+ *
+ *	TP_PROTO(struct rq *rq, struct task_struct *prev,
+ *		 struct task_struct *next),
+ *
+ *	*
+ *	* Define the call signature of the 'function'.
+ *	* (Design sidenote: we use this instead of a
+ *	*  TP_PROTO1/TP_PROTO2/TP_PROTO3 ugliness.)
+ *	*
+ *
+ *	TP_ARGS(rq, prev, next),
+ *
+ *	*
+ *	* Fast binary tracing: define the trace record via
+ *	* TP_STRUCT__entry(). You can think about it like a
+ *	* regular C structure local variable definition.
+ *	*
+ *	* This is how the trace record is structured and will
+ *	* be saved into the ring buffer. These are the fields
+ *	* that will be exposed to user-space in
+ *	* /debug/tracing/events/<*>/format.
+ *	*
+ *	* The declared 'local variable' is called '__entry'
+ *	*
+ *	* __field(pid_t, prev_prid) is equivalent to a standard declariton:
+ *	*
+ *	*	pid_t	prev_pid;
+ *	*
+ *	* __array(char, prev_comm, TASK_COMM_LEN) is equivalent to:
+ *	*
+ *	*	char	prev_comm[TASK_COMM_LEN];
+ *	*
+ *
+ *	TP_STRUCT__entry(
+ *		__array(	char,	prev_comm,	TASK_COMM_LEN	)
+ *		__field(	pid_t,	prev_pid			)
+ *		__field(	int,	prev_prio			)
+ *		__array(	char,	next_comm,	TASK_COMM_LEN	)
+ *		__field(	pid_t,	next_pid			)
+ *		__field(	int,	next_prio			)
+ *	),
+ *
+ *	*
+ *	* Assign the entry into the trace record, by embedding
+ *	* a full C statement block into TP_fast_assign(). You
+ *	* can refer to the trace record as '__entry' -
+ *	* otherwise you can put arbitrary C code in here.
+ *	*
+ *	* Note: this C code will execute every time a trace event
+ *	* happens, on an active tracepoint.
+ *	*
+ *
+ *	TP_fast_assign(
+ *		memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN);
+ *		__entry->prev_pid	= prev->pid;
+ *		__entry->prev_prio	= prev->prio;
+ *		memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN);
+ *		__entry->next_pid	= next->pid;
+ *		__entry->next_prio	= next->prio;
+ *	)
+ *
+ *	*
+ *	* Formatted output of a trace record via TP_printk().
+ *	* This is how the tracepoint will appear under ftrace
+ *	* plugins that make use of this tracepoint.
+ *	*
+ *	* (raw-binary tracing wont actually perform this step.)
+ *	*
+ *
+ *	TP_printk("task %s:%d [%d] ==> %s:%d [%d]",
+ *		__entry->prev_comm, __entry->prev_pid, __entry->prev_prio,
+ *		__entry->next_comm, __entry->next_pid, __entry->next_prio),
+ *
+ * );
+ *
+ * This macro construct is thus used for the regular printk format
+ * tracing setup, it is used to construct a function pointer based
+ * tracepoint callback (this is used by programmatic plugins and
+ * can also by used by generic instrumentation like SystemTap), and
+ * it is also used to expose a structured trace record in
+ * /debug/tracing/events/.
+ */
+
+#define TRACE_EVENT(name, proto, args, struct, assign, print)	\
+	DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
+
 #endif
diff --git a/include/linux/usb/wusb.h b/include/linux/usb/wusb.h
index 5f401b6..429c631 100644
--- a/include/linux/usb/wusb.h
+++ b/include/linux/usb/wusb.h
@@ -80,8 +80,7 @@
 	u8 data[16];
 } __attribute__((packed));
 
-const static
-struct wusb_ckhdid wusb_ckhdid_zero = { .data = { 0 } };
+static const struct wusb_ckhdid wusb_ckhdid_zero = { .data = { 0 } };
 
 #define WUSB_CKHDID_STRSIZE (3 * sizeof(struct wusb_ckhdid) + 1)
 
diff --git a/include/trace/block.h b/include/trace/block.h
index 25c6a1f..25b7068 100644
--- a/include/trace/block.h
+++ b/include/trace/block.h
@@ -5,72 +5,72 @@
 #include <linux/tracepoint.h>
 
 DECLARE_TRACE(block_rq_abort,
-	TPPROTO(struct request_queue *q, struct request *rq),
-		TPARGS(q, rq));
+	TP_PROTO(struct request_queue *q, struct request *rq),
+	      TP_ARGS(q, rq));
 
 DECLARE_TRACE(block_rq_insert,
-	TPPROTO(struct request_queue *q, struct request *rq),
-		TPARGS(q, rq));
+	TP_PROTO(struct request_queue *q, struct request *rq),
+	      TP_ARGS(q, rq));
 
 DECLARE_TRACE(block_rq_issue,
-	TPPROTO(struct request_queue *q, struct request *rq),
-		TPARGS(q, rq));
+	TP_PROTO(struct request_queue *q, struct request *rq),
+	      TP_ARGS(q, rq));
 
 DECLARE_TRACE(block_rq_requeue,
-	TPPROTO(struct request_queue *q, struct request *rq),
-		TPARGS(q, rq));
+	TP_PROTO(struct request_queue *q, struct request *rq),
+	      TP_ARGS(q, rq));
 
 DECLARE_TRACE(block_rq_complete,
-	TPPROTO(struct request_queue *q, struct request *rq),
-		TPARGS(q, rq));
+	TP_PROTO(struct request_queue *q, struct request *rq),
+	      TP_ARGS(q, rq));
 
 DECLARE_TRACE(block_bio_bounce,
-	TPPROTO(struct request_queue *q, struct bio *bio),
-		TPARGS(q, bio));
+	TP_PROTO(struct request_queue *q, struct bio *bio),
+	      TP_ARGS(q, bio));
 
 DECLARE_TRACE(block_bio_complete,
-	TPPROTO(struct request_queue *q, struct bio *bio),
-		TPARGS(q, bio));
+	TP_PROTO(struct request_queue *q, struct bio *bio),
+	      TP_ARGS(q, bio));
 
 DECLARE_TRACE(block_bio_backmerge,
-	TPPROTO(struct request_queue *q, struct bio *bio),
-		TPARGS(q, bio));
+	TP_PROTO(struct request_queue *q, struct bio *bio),
+	      TP_ARGS(q, bio));
 
 DECLARE_TRACE(block_bio_frontmerge,
-	TPPROTO(struct request_queue *q, struct bio *bio),
-		TPARGS(q, bio));
+	TP_PROTO(struct request_queue *q, struct bio *bio),
+	      TP_ARGS(q, bio));
 
 DECLARE_TRACE(block_bio_queue,
-	TPPROTO(struct request_queue *q, struct bio *bio),
-		TPARGS(q, bio));
+	TP_PROTO(struct request_queue *q, struct bio *bio),
+	      TP_ARGS(q, bio));
 
 DECLARE_TRACE(block_getrq,
-	TPPROTO(struct request_queue *q, struct bio *bio, int rw),
-		TPARGS(q, bio, rw));
+	TP_PROTO(struct request_queue *q, struct bio *bio, int rw),
+	      TP_ARGS(q, bio, rw));
 
 DECLARE_TRACE(block_sleeprq,
-	TPPROTO(struct request_queue *q, struct bio *bio, int rw),
-		TPARGS(q, bio, rw));
+	TP_PROTO(struct request_queue *q, struct bio *bio, int rw),
+	      TP_ARGS(q, bio, rw));
 
 DECLARE_TRACE(block_plug,
-	TPPROTO(struct request_queue *q),
-		TPARGS(q));
+	TP_PROTO(struct request_queue *q),
+	      TP_ARGS(q));
 
 DECLARE_TRACE(block_unplug_timer,
-	TPPROTO(struct request_queue *q),
-		TPARGS(q));
+	TP_PROTO(struct request_queue *q),
+	      TP_ARGS(q));
 
 DECLARE_TRACE(block_unplug_io,
-	TPPROTO(struct request_queue *q),
-		TPARGS(q));
+	TP_PROTO(struct request_queue *q),
+	      TP_ARGS(q));
 
 DECLARE_TRACE(block_split,
-	TPPROTO(struct request_queue *q, struct bio *bio, unsigned int pdu),
-		TPARGS(q, bio, pdu));
+	TP_PROTO(struct request_queue *q, struct bio *bio, unsigned int pdu),
+	      TP_ARGS(q, bio, pdu));
 
 DECLARE_TRACE(block_remap,
-	TPPROTO(struct request_queue *q, struct bio *bio, dev_t dev,
-		sector_t from, sector_t to),
-		TPARGS(q, bio, dev, from, to));
+	TP_PROTO(struct request_queue *q, struct bio *bio, dev_t dev,
+		 sector_t from, sector_t to),
+	      TP_ARGS(q, bio, dev, from, to));
 
 #endif
diff --git a/include/trace/irq.h b/include/trace/irq.h
new file mode 100644
index 0000000..ff5d449
--- /dev/null
+++ b/include/trace/irq.h
@@ -0,0 +1,9 @@
+#ifndef _TRACE_IRQ_H
+#define _TRACE_IRQ_H
+
+#include <linux/interrupt.h>
+#include <linux/tracepoint.h>
+
+#include <trace/irq_event_types.h>
+
+#endif
diff --git a/include/trace/irq_event_types.h b/include/trace/irq_event_types.h
new file mode 100644
index 0000000..85964eb
--- /dev/null
+++ b/include/trace/irq_event_types.h
@@ -0,0 +1,55 @@
+
+/* use <trace/irq.h> instead */
+#ifndef TRACE_FORMAT
+# error Do not include this file directly.
+# error Unless you know what you are doing.
+#endif
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM irq
+
+/*
+ * Tracepoint for entry of interrupt handler:
+ */
+TRACE_FORMAT(irq_handler_entry,
+	TP_PROTO(int irq, struct irqaction *action),
+	TP_ARGS(irq, action),
+	TP_FMT("irq=%d handler=%s", irq, action->name)
+	);
+
+/*
+ * Tracepoint for return of an interrupt handler:
+ */
+TRACE_EVENT(irq_handler_exit,
+
+	TP_PROTO(int irq, struct irqaction *action, int ret),
+
+	TP_ARGS(irq, action, ret),
+
+	TP_STRUCT__entry(
+		__field(	int,	irq	)
+		__field(	int,	ret	)
+	),
+
+	TP_fast_assign(
+		__entry->irq	= irq;
+		__entry->ret	= ret;
+	),
+
+	TP_printk("irq=%d return=%s",
+		  __entry->irq, __entry->ret ? "handled" : "unhandled")
+);
+
+TRACE_FORMAT(softirq_entry,
+	TP_PROTO(struct softirq_action *h, struct softirq_action *vec),
+	TP_ARGS(h, vec),
+	TP_FMT("softirq=%d action=%s", (int)(h - vec), softirq_to_name[h-vec])
+	);
+
+TRACE_FORMAT(softirq_exit,
+	TP_PROTO(struct softirq_action *h, struct softirq_action *vec),
+	TP_ARGS(h, vec),
+	TP_FMT("softirq=%d action=%s", (int)(h - vec), softirq_to_name[h-vec])
+	);
+
+#undef TRACE_SYSTEM
diff --git a/include/trace/kmemtrace.h b/include/trace/kmemtrace.h
new file mode 100644
index 0000000..ad8b785
--- /dev/null
+++ b/include/trace/kmemtrace.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2008 Eduard - Gabriel Munteanu
+ *
+ * This file is released under GPL version 2.
+ */
+
+#ifndef _LINUX_KMEMTRACE_H
+#define _LINUX_KMEMTRACE_H
+
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/marker.h>
+
+enum kmemtrace_type_id {
+	KMEMTRACE_TYPE_KMALLOC = 0,	/* kmalloc() or kfree(). */
+	KMEMTRACE_TYPE_CACHE,		/* kmem_cache_*(). */
+	KMEMTRACE_TYPE_PAGES,		/* __get_free_pages() and friends. */
+};
+
+#ifdef CONFIG_KMEMTRACE
+
+extern void kmemtrace_init(void);
+
+extern void kmemtrace_mark_alloc_node(enum kmemtrace_type_id type_id,
+					     unsigned long call_site,
+					     const void *ptr,
+					     size_t bytes_req,
+					     size_t bytes_alloc,
+					     gfp_t gfp_flags,
+					     int node);
+
+extern void kmemtrace_mark_free(enum kmemtrace_type_id type_id,
+				       unsigned long call_site,
+				       const void *ptr);
+
+#else /* CONFIG_KMEMTRACE */
+
+static inline void kmemtrace_init(void)
+{
+}
+
+static inline void kmemtrace_mark_alloc_node(enum kmemtrace_type_id type_id,
+					     unsigned long call_site,
+					     const void *ptr,
+					     size_t bytes_req,
+					     size_t bytes_alloc,
+					     gfp_t gfp_flags,
+					     int node)
+{
+}
+
+static inline void kmemtrace_mark_free(enum kmemtrace_type_id type_id,
+				       unsigned long call_site,
+				       const void *ptr)
+{
+}
+
+#endif /* CONFIG_KMEMTRACE */
+
+static inline void kmemtrace_mark_alloc(enum kmemtrace_type_id type_id,
+					unsigned long call_site,
+					const void *ptr,
+					size_t bytes_req,
+					size_t bytes_alloc,
+					gfp_t gfp_flags)
+{
+	kmemtrace_mark_alloc_node(type_id, call_site, ptr,
+				  bytes_req, bytes_alloc, gfp_flags, -1);
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_KMEMTRACE_H */
+
diff --git a/include/trace/lockdep.h b/include/trace/lockdep.h
new file mode 100644
index 0000000..5ca67df
--- /dev/null
+++ b/include/trace/lockdep.h
@@ -0,0 +1,9 @@
+#ifndef _TRACE_LOCKDEP_H
+#define _TRACE_LOCKDEP_H
+
+#include <linux/lockdep.h>
+#include <linux/tracepoint.h>
+
+#include <trace/lockdep_event_types.h>
+
+#endif
diff --git a/include/trace/lockdep_event_types.h b/include/trace/lockdep_event_types.h
new file mode 100644
index 0000000..adccfcd
--- /dev/null
+++ b/include/trace/lockdep_event_types.h
@@ -0,0 +1,44 @@
+
+#ifndef TRACE_FORMAT
+# error Do not include this file directly.
+# error Unless you know what you are doing.
+#endif
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM lock
+
+#ifdef CONFIG_LOCKDEP
+
+TRACE_FORMAT(lock_acquire,
+	TP_PROTO(struct lockdep_map *lock, unsigned int subclass,
+		int trylock, int read, int check,
+		struct lockdep_map *next_lock, unsigned long ip),
+	TP_ARGS(lock, subclass, trylock, read, check, next_lock, ip),
+	TP_FMT("%s%s%s", trylock ? "try " : "",
+		read ? "read " : "", lock->name)
+	);
+
+TRACE_FORMAT(lock_release,
+	TP_PROTO(struct lockdep_map *lock, int nested, unsigned long ip),
+	TP_ARGS(lock, nested, ip),
+	TP_FMT("%s", lock->name)
+	);
+
+#ifdef CONFIG_LOCK_STAT
+
+TRACE_FORMAT(lock_contended,
+	TP_PROTO(struct lockdep_map *lock, unsigned long ip),
+	TP_ARGS(lock, ip),
+	TP_FMT("%s", lock->name)
+	);
+
+TRACE_FORMAT(lock_acquired,
+	TP_PROTO(struct lockdep_map *lock, unsigned long ip),
+	TP_ARGS(lock, ip),
+	TP_FMT("%s", lock->name)
+	);
+
+#endif
+#endif
+
+#undef TRACE_SYSTEM
diff --git a/include/trace/power.h b/include/trace/power.h
new file mode 100644
index 0000000..ef20466
--- /dev/null
+++ b/include/trace/power.h
@@ -0,0 +1,32 @@
+#ifndef _TRACE_POWER_H
+#define _TRACE_POWER_H
+
+#include <linux/ktime.h>
+#include <linux/tracepoint.h>
+
+enum {
+	POWER_NONE = 0,
+	POWER_CSTATE = 1,
+	POWER_PSTATE = 2,
+};
+
+struct power_trace {
+	ktime_t			stamp;
+	ktime_t			end;
+	int			type;
+	int			state;
+};
+
+DECLARE_TRACE(power_start,
+	TP_PROTO(struct power_trace *it, unsigned int type, unsigned int state),
+	      TP_ARGS(it, type, state));
+
+DECLARE_TRACE(power_mark,
+	TP_PROTO(struct power_trace *it, unsigned int type, unsigned int state),
+	      TP_ARGS(it, type, state));
+
+DECLARE_TRACE(power_end,
+	TP_PROTO(struct power_trace *it),
+	      TP_ARGS(it));
+
+#endif /* _TRACE_POWER_H */
diff --git a/include/trace/sched.h b/include/trace/sched.h
index 0d81098e..4e372a1 100644
--- a/include/trace/sched.h
+++ b/include/trace/sched.h
@@ -4,53 +4,6 @@
 #include <linux/sched.h>
 #include <linux/tracepoint.h>
 
-DECLARE_TRACE(sched_kthread_stop,
-	TPPROTO(struct task_struct *t),
-		TPARGS(t));
-
-DECLARE_TRACE(sched_kthread_stop_ret,
-	TPPROTO(int ret),
-		TPARGS(ret));
-
-DECLARE_TRACE(sched_wait_task,
-	TPPROTO(struct rq *rq, struct task_struct *p),
-		TPARGS(rq, p));
-
-DECLARE_TRACE(sched_wakeup,
-	TPPROTO(struct rq *rq, struct task_struct *p, int success),
-		TPARGS(rq, p, success));
-
-DECLARE_TRACE(sched_wakeup_new,
-	TPPROTO(struct rq *rq, struct task_struct *p, int success),
-		TPARGS(rq, p, success));
-
-DECLARE_TRACE(sched_switch,
-	TPPROTO(struct rq *rq, struct task_struct *prev,
-		struct task_struct *next),
-		TPARGS(rq, prev, next));
-
-DECLARE_TRACE(sched_migrate_task,
-	TPPROTO(struct task_struct *p, int orig_cpu, int dest_cpu),
-		TPARGS(p, orig_cpu, dest_cpu));
-
-DECLARE_TRACE(sched_process_free,
-	TPPROTO(struct task_struct *p),
-		TPARGS(p));
-
-DECLARE_TRACE(sched_process_exit,
-	TPPROTO(struct task_struct *p),
-		TPARGS(p));
-
-DECLARE_TRACE(sched_process_wait,
-	TPPROTO(struct pid *pid),
-		TPARGS(pid));
-
-DECLARE_TRACE(sched_process_fork,
-	TPPROTO(struct task_struct *parent, struct task_struct *child),
-		TPARGS(parent, child));
-
-DECLARE_TRACE(sched_signal_send,
-	TPPROTO(int sig, struct task_struct *p),
-		TPARGS(sig, p));
+#include <trace/sched_event_types.h>
 
 #endif
diff --git a/include/trace/sched_event_types.h b/include/trace/sched_event_types.h
new file mode 100644
index 0000000..63547dc
--- /dev/null
+++ b/include/trace/sched_event_types.h
@@ -0,0 +1,337 @@
+
+/* use <trace/sched.h> instead */
+#ifndef TRACE_EVENT
+# error Do not include this file directly.
+# error Unless you know what you are doing.
+#endif
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM sched
+
+/*
+ * Tracepoint for calling kthread_stop, performed to end a kthread:
+ */
+TRACE_EVENT(sched_kthread_stop,
+
+	TP_PROTO(struct task_struct *t),
+
+	TP_ARGS(t),
+
+	TP_STRUCT__entry(
+		__array(	char,	comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	pid			)
+	),
+
+	TP_fast_assign(
+		memcpy(__entry->comm, t->comm, TASK_COMM_LEN);
+		__entry->pid	= t->pid;
+	),
+
+	TP_printk("task %s:%d", __entry->comm, __entry->pid)
+);
+
+/*
+ * Tracepoint for the return value of the kthread stopping:
+ */
+TRACE_EVENT(sched_kthread_stop_ret,
+
+	TP_PROTO(int ret),
+
+	TP_ARGS(ret),
+
+	TP_STRUCT__entry(
+		__field(	int,	ret	)
+	),
+
+	TP_fast_assign(
+		__entry->ret	= ret;
+	),
+
+	TP_printk("ret %d", __entry->ret)
+);
+
+/*
+ * Tracepoint for waiting on task to unschedule:
+ *
+ * (NOTE: the 'rq' argument is not used by generic trace events,
+ *        but used by the latency tracer plugin. )
+ */
+TRACE_EVENT(sched_wait_task,
+
+	TP_PROTO(struct rq *rq, struct task_struct *p),
+
+	TP_ARGS(rq, p),
+
+	TP_STRUCT__entry(
+		__array(	char,	comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	pid			)
+		__field(	int,	prio			)
+	),
+
+	TP_fast_assign(
+		memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+		__entry->pid	= p->pid;
+		__entry->prio	= p->prio;
+	),
+
+	TP_printk("task %s:%d [%d]",
+		  __entry->comm, __entry->pid, __entry->prio)
+);
+
+/*
+ * Tracepoint for waking up a task:
+ *
+ * (NOTE: the 'rq' argument is not used by generic trace events,
+ *        but used by the latency tracer plugin. )
+ */
+TRACE_EVENT(sched_wakeup,
+
+	TP_PROTO(struct rq *rq, struct task_struct *p, int success),
+
+	TP_ARGS(rq, p, success),
+
+	TP_STRUCT__entry(
+		__array(	char,	comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	pid			)
+		__field(	int,	prio			)
+		__field(	int,	success			)
+	),
+
+	TP_fast_assign(
+		memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+		__entry->pid		= p->pid;
+		__entry->prio		= p->prio;
+		__entry->success	= success;
+	),
+
+	TP_printk("task %s:%d [%d] success=%d",
+		  __entry->comm, __entry->pid, __entry->prio,
+		  __entry->success)
+);
+
+/*
+ * Tracepoint for waking up a new task:
+ *
+ * (NOTE: the 'rq' argument is not used by generic trace events,
+ *        but used by the latency tracer plugin. )
+ */
+TRACE_EVENT(sched_wakeup_new,
+
+	TP_PROTO(struct rq *rq, struct task_struct *p, int success),
+
+	TP_ARGS(rq, p, success),
+
+	TP_STRUCT__entry(
+		__array(	char,	comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	pid			)
+		__field(	int,	prio			)
+		__field(	int,	success			)
+	),
+
+	TP_fast_assign(
+		memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+		__entry->pid		= p->pid;
+		__entry->prio		= p->prio;
+		__entry->success	= success;
+	),
+
+	TP_printk("task %s:%d [%d] success=%d",
+		  __entry->comm, __entry->pid, __entry->prio,
+		  __entry->success)
+);
+
+/*
+ * Tracepoint for task switches, performed by the scheduler:
+ *
+ * (NOTE: the 'rq' argument is not used by generic trace events,
+ *        but used by the latency tracer plugin. )
+ */
+TRACE_EVENT(sched_switch,
+
+	TP_PROTO(struct rq *rq, struct task_struct *prev,
+		 struct task_struct *next),
+
+	TP_ARGS(rq, prev, next),
+
+	TP_STRUCT__entry(
+		__array(	char,	prev_comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	prev_pid			)
+		__field(	int,	prev_prio			)
+		__array(	char,	next_comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	next_pid			)
+		__field(	int,	next_prio			)
+	),
+
+	TP_fast_assign(
+		memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN);
+		__entry->prev_pid	= prev->pid;
+		__entry->prev_prio	= prev->prio;
+		memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN);
+		__entry->next_pid	= next->pid;
+		__entry->next_prio	= next->prio;
+	),
+
+	TP_printk("task %s:%d [%d] ==> %s:%d [%d]",
+		__entry->prev_comm, __entry->prev_pid, __entry->prev_prio,
+		__entry->next_comm, __entry->next_pid, __entry->next_prio)
+);
+
+/*
+ * Tracepoint for a task being migrated:
+ */
+TRACE_EVENT(sched_migrate_task,
+
+	TP_PROTO(struct task_struct *p, int orig_cpu, int dest_cpu),
+
+	TP_ARGS(p, orig_cpu, dest_cpu),
+
+	TP_STRUCT__entry(
+		__array(	char,	comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	pid			)
+		__field(	int,	prio			)
+		__field(	int,	orig_cpu		)
+		__field(	int,	dest_cpu		)
+	),
+
+	TP_fast_assign(
+		memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+		__entry->pid		= p->pid;
+		__entry->prio		= p->prio;
+		__entry->orig_cpu	= orig_cpu;
+		__entry->dest_cpu	= dest_cpu;
+	),
+
+	TP_printk("task %s:%d [%d] from: %d  to: %d",
+		  __entry->comm, __entry->pid, __entry->prio,
+		  __entry->orig_cpu, __entry->dest_cpu)
+);
+
+/*
+ * Tracepoint for freeing a task:
+ */
+TRACE_EVENT(sched_process_free,
+
+	TP_PROTO(struct task_struct *p),
+
+	TP_ARGS(p),
+
+	TP_STRUCT__entry(
+		__array(	char,	comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	pid			)
+		__field(	int,	prio			)
+	),
+
+	TP_fast_assign(
+		memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+		__entry->pid		= p->pid;
+		__entry->prio		= p->prio;
+	),
+
+	TP_printk("task %s:%d [%d]",
+		  __entry->comm, __entry->pid, __entry->prio)
+);
+
+/*
+ * Tracepoint for a task exiting:
+ */
+TRACE_EVENT(sched_process_exit,
+
+	TP_PROTO(struct task_struct *p),
+
+	TP_ARGS(p),
+
+	TP_STRUCT__entry(
+		__array(	char,	comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	pid			)
+		__field(	int,	prio			)
+	),
+
+	TP_fast_assign(
+		memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+		__entry->pid		= p->pid;
+		__entry->prio		= p->prio;
+	),
+
+	TP_printk("task %s:%d [%d]",
+		  __entry->comm, __entry->pid, __entry->prio)
+);
+
+/*
+ * Tracepoint for a waiting task:
+ */
+TRACE_EVENT(sched_process_wait,
+
+	TP_PROTO(struct pid *pid),
+
+	TP_ARGS(pid),
+
+	TP_STRUCT__entry(
+		__array(	char,	comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	pid			)
+		__field(	int,	prio			)
+	),
+
+	TP_fast_assign(
+		memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
+		__entry->pid		= pid_nr(pid);
+		__entry->prio		= current->prio;
+	),
+
+	TP_printk("task %s:%d [%d]",
+		  __entry->comm, __entry->pid, __entry->prio)
+);
+
+/*
+ * Tracepoint for do_fork:
+ */
+TRACE_EVENT(sched_process_fork,
+
+	TP_PROTO(struct task_struct *parent, struct task_struct *child),
+
+	TP_ARGS(parent, child),
+
+	TP_STRUCT__entry(
+		__array(	char,	parent_comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	parent_pid			)
+		__array(	char,	child_comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	child_pid			)
+	),
+
+	TP_fast_assign(
+		memcpy(__entry->parent_comm, parent->comm, TASK_COMM_LEN);
+		__entry->parent_pid	= parent->pid;
+		memcpy(__entry->child_comm, child->comm, TASK_COMM_LEN);
+		__entry->child_pid	= child->pid;
+	),
+
+	TP_printk("parent %s:%d  child %s:%d",
+		__entry->parent_comm, __entry->parent_pid,
+		__entry->child_comm, __entry->child_pid)
+);
+
+/*
+ * Tracepoint for sending a signal:
+ */
+TRACE_EVENT(sched_signal_send,
+
+	TP_PROTO(int sig, struct task_struct *p),
+
+	TP_ARGS(sig, p),
+
+	TP_STRUCT__entry(
+		__field(	int,	sig			)
+		__array(	char,	comm,	TASK_COMM_LEN	)
+		__field(	pid_t,	pid			)
+	),
+
+	TP_fast_assign(
+		memcpy(__entry->comm, p->comm, TASK_COMM_LEN);
+		__entry->pid	= p->pid;
+		__entry->sig	= sig;
+	),
+
+	TP_printk("sig: %d  task %s:%d",
+		  __entry->sig, __entry->comm, __entry->pid)
+);
+
+#undef TRACE_SYSTEM
diff --git a/include/trace/skb.h b/include/trace/skb.h
index a96610f9..b66206d 100644
--- a/include/trace/skb.h
+++ b/include/trace/skb.h
@@ -5,7 +5,7 @@
 #include <linux/tracepoint.h>
 
 DECLARE_TRACE(kfree_skb,
-	TPPROTO(struct sk_buff *skb, void *location),
-	TPARGS(skb, location));
+	TP_PROTO(struct sk_buff *skb, void *location),
+	TP_ARGS(skb, location));
 
 #endif
diff --git a/include/trace/trace_event_types.h b/include/trace/trace_event_types.h
new file mode 100644
index 0000000..df56f56
--- /dev/null
+++ b/include/trace/trace_event_types.h
@@ -0,0 +1,5 @@
+/* trace/<type>_event_types.h here */
+
+#include <trace/sched_event_types.h>
+#include <trace/irq_event_types.h>
+#include <trace/lockdep_event_types.h>
diff --git a/include/trace/trace_events.h b/include/trace/trace_events.h
new file mode 100644
index 0000000..fd13750
--- /dev/null
+++ b/include/trace/trace_events.h
@@ -0,0 +1,5 @@
+/* trace/<type>.h here */
+
+#include <trace/sched.h>
+#include <trace/irq.h>
+#include <trace/lockdep.h>
diff --git a/include/trace/workqueue.h b/include/trace/workqueue.h
new file mode 100644
index 0000000..7626523
--- /dev/null
+++ b/include/trace/workqueue.h
@@ -0,0 +1,25 @@
+#ifndef __TRACE_WORKQUEUE_H
+#define __TRACE_WORKQUEUE_H
+
+#include <linux/tracepoint.h>
+#include <linux/workqueue.h>
+#include <linux/sched.h>
+
+DECLARE_TRACE(workqueue_insertion,
+	   TP_PROTO(struct task_struct *wq_thread, struct work_struct *work),
+	   TP_ARGS(wq_thread, work));
+
+DECLARE_TRACE(workqueue_execution,
+	   TP_PROTO(struct task_struct *wq_thread, struct work_struct *work),
+	   TP_ARGS(wq_thread, work));
+
+/* Trace the creation of one workqueue thread on a cpu */
+DECLARE_TRACE(workqueue_creation,
+	   TP_PROTO(struct task_struct *wq_thread, int cpu),
+	   TP_ARGS(wq_thread, cpu));
+
+DECLARE_TRACE(workqueue_destruction,
+	   TP_PROTO(struct task_struct *wq_thread),
+	   TP_ARGS(wq_thread));
+
+#endif /* __TRACE_WORKQUEUE_H */
diff --git a/init/Kconfig b/init/Kconfig
index 1398a14..09c7953 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -565,7 +565,7 @@
 	select MM_OWNER
 	help
 	  Provides a memory resource controller that manages both anonymous
-	  memory and page cache. (See Documentation/controllers/memory.txt)
+	  memory and page cache. (See Documentation/cgroups/memory.txt)
 
 	  Note that setting this option increases fixed memory overhead
 	  associated with each page of memory in the system. By this,
@@ -689,7 +689,7 @@
 	depends on NAMESPACES && EXPERIMENTAL
 	help
 	  Support process id namespaces.  This allows having multiple
-	  process with the same pid as long as they are in different
+	  processes with the same pid as long as they are in different
 	  pid namespaces.  This is a building block of containers.
 
 	  Unless you want to work with an experimental feature
@@ -954,7 +954,7 @@
 	  Randomizing heap placement makes heap exploits harder, but it
 	  also breaks ancient binaries (including anything libc5 based).
 	  This option changes the bootup default to heap randomization
-	  disabled, and can be overriden runtime by setting
+	  disabled, and can be overridden at runtime by setting
 	  /proc/sys/kernel/randomize_va_space to 2.
 
 	  On non-ancient distros (post-2000 ones) N is usually a safe choice.
@@ -1007,13 +1007,25 @@
 
 config MARKERS
 	bool "Activate markers"
-	depends on TRACEPOINTS
+	select TRACEPOINTS
 	help
 	  Place an empty function call at each marker site. Can be
 	  dynamically changed for a probe function.
 
 source "arch/Kconfig"
 
+config SLOW_WORK
+	default n
+	bool "Enable slow work thread pool"
+	help
+	  The slow work thread pool provides a number of dynamically allocated
+	  threads that can be used by the kernel to perform operations that
+	  take a relatively long time.
+
+	  An example of this would be CacheFiles doing a path lookup followed
+	  by a series of mkdirs and a create call, all of which have to touch
+	  disk.
+
 endmenu		# General setup
 
 config HAVE_GENERIC_DMA_COHERENT
@@ -1112,7 +1124,7 @@
 	  cpu_possible_map, some of them chose to initialize cpu_possible_map
 	  with all 1s, and others with all 0s.  When they were centralised,
 	  it was better to provide this option than to break all the archs
-	  and have several arch maintainers persuing me down dark alleys.
+	  and have several arch maintainers pursuing me down dark alleys.
 
 config STOP_MACHINE
 	bool
diff --git a/init/do_mounts.h b/init/do_mounts.h
index 9aa968d..f5b978a 100644
--- a/init/do_mounts.h
+++ b/init/do_mounts.h
@@ -1,4 +1,5 @@
 #include <linux/kernel.h>
+#include <linux/blkdev.h>
 #include <linux/init.h>
 #include <linux/syscalls.h>
 #include <linux/unistd.h>
diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c
index 9bdddbc..69aebbf 100644
--- a/init/do_mounts_md.c
+++ b/init/do_mounts_md.c
@@ -1,5 +1,6 @@
 #include <linux/delay.h>
-#include <linux/raid/md.h>
+#include <linux/raid/md_u.h>
+#include <linux/raid/md_p.h>
 
 #include "do_mounts.h"
 
@@ -112,8 +113,6 @@
 	return 1;
 }
 
-#define MdpMinorShift 6
-
 static void __init md_setup_drive(void)
 {
 	int minor, i, ent, partitioned;
diff --git a/init/main.c b/init/main.c
index 07c8658..3585f07 100644
--- a/init/main.c
+++ b/init/main.c
@@ -71,6 +71,7 @@
 #include <asm/setup.h>
 #include <asm/sections.h>
 #include <asm/cacheflush.h>
+#include <trace/kmemtrace.h>
 
 #ifdef CONFIG_X86_LOCAL_APIC
 #include <asm/smp.h>
@@ -648,6 +649,7 @@
 	enable_debug_pagealloc();
 	cpu_hotplug_init();
 	kmem_cache_init();
+	kmemtrace_init();
 	debug_objects_mem_init();
 	idr_init_cache();
 	setup_per_cpu_pageset();
@@ -769,6 +771,7 @@
 {
 	rcu_init_sched(); /* needed by module_init stage. */
 	init_workqueues();
+	cpuset_init_smp();
 	usermodehelper_init();
 	driver_init();
 	init_irq_proc();
@@ -863,8 +866,6 @@
 	smp_init();
 	sched_init_smp();
 
-	cpuset_init_smp();
-
 	do_basic_setup();
 
 	/*
diff --git a/kernel/Makefile b/kernel/Makefile
index e4791b3..bab1dff 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -93,6 +93,7 @@
 obj-$(CONFIG_FUNCTION_TRACER) += trace/
 obj-$(CONFIG_TRACING) += trace/
 obj-$(CONFIG_SMP) += sched_cpupri.o
+obj-$(CONFIG_SLOW_WORK) += slow-work.o
 
 ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y)
 # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
diff --git a/kernel/audit.c b/kernel/audit.c
index ce6d8ea..9442c35 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -766,6 +766,9 @@
 
 				audit_log_format(ab, " msg=");
 				size = nlmsg_len(nlh);
+				if (size > 0 &&
+				    ((unsigned char *)data)[size - 1] == '\0')
+					size--;
 				audit_log_n_untrustedstring(ab, data, size);
 			}
 			audit_set_pid(ab, pid);
@@ -1382,7 +1385,7 @@
 int audit_string_contains_control(const char *string, size_t len)
 {
 	const unsigned char *p;
-	for (p = string; p < (const unsigned char *)string + len && *p; p++) {
+	for (p = string; p < (const unsigned char *)string + len; p++) {
 		if (*p == '"' || *p < 0x21 || *p > 0x7e)
 			return 1;
 	}
@@ -1437,13 +1440,13 @@
 	/* We will allow 11 spaces for ' (deleted)' to be appended */
 	pathname = kmalloc(PATH_MAX+11, ab->gfp_mask);
 	if (!pathname) {
-		audit_log_format(ab, "<no memory>");
+		audit_log_string(ab, "<no_memory>");
 		return;
 	}
 	p = d_path(path, pathname, PATH_MAX+11);
 	if (IS_ERR(p)) { /* Should never happen since we send PATH_MAX */
 		/* FIXME: can we save some information here? */
-		audit_log_format(ab, "<too long>");
+		audit_log_string(ab, "<too_long>");
 	} else
 		audit_log_untrustedstring(ab, p);
 	kfree(pathname);
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
index 8ad9545..917ab95 100644
--- a/kernel/audit_tree.c
+++ b/kernel/audit_tree.c
@@ -385,6 +385,7 @@
 	mutex_lock(&inode->inotify_mutex);
 	if (inotify_clone_watch(&old->watch, &chunk->watch) < 0) {
 		mutex_unlock(&inode->inotify_mutex);
+		put_inotify_watch(&old->watch);
 		free_chunk(chunk);
 		return -ENOSPC;
 	}
@@ -394,6 +395,7 @@
 		chunk->dead = 1;
 		inotify_evict_watch(&chunk->watch);
 		mutex_unlock(&inode->inotify_mutex);
+		put_inotify_watch(&old->watch);
 		put_inotify_watch(&chunk->watch);
 		return 0;
 	}
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index fbf24d1..a6fe71f 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -135,18 +135,18 @@
 static inline void audit_free_rule(struct audit_entry *e)
 {
 	int i;
-
+	struct audit_krule *erule = &e->rule;
 	/* some rules don't have associated watches */
-	if (e->rule.watch)
-		audit_put_watch(e->rule.watch);
-	if (e->rule.fields)
-		for (i = 0; i < e->rule.field_count; i++) {
-			struct audit_field *f = &e->rule.fields[i];
+	if (erule->watch)
+		audit_put_watch(erule->watch);
+	if (erule->fields)
+		for (i = 0; i < erule->field_count; i++) {
+			struct audit_field *f = &erule->fields[i];
 			kfree(f->lsm_str);
 			security_audit_rule_free(f->lsm_rule);
 		}
-	kfree(e->rule.fields);
-	kfree(e->rule.filterkey);
+	kfree(erule->fields);
+	kfree(erule->filterkey);
 	kfree(e);
 }
 
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 2bfc647..7d6ac7c 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -329,6 +329,14 @@
  */
 
 #ifdef CONFIG_AUDIT_TREE
+static void audit_set_auditable(struct audit_context *ctx)
+{
+	if (!ctx->prio) {
+		ctx->prio = 1;
+		ctx->current_state = AUDIT_RECORD_CONTEXT;
+	}
+}
+
 static int put_tree_ref(struct audit_context *ctx, struct audit_chunk *chunk)
 {
 	struct audit_tree_refs *p = ctx->trees;
@@ -742,17 +750,9 @@
 	rcu_read_unlock();
 }
 
-static void audit_set_auditable(struct audit_context *ctx)
-{
-	if (!ctx->prio) {
-		ctx->prio = 1;
-		ctx->current_state = AUDIT_RECORD_CONTEXT;
-	}
-}
-
 static inline struct audit_context *audit_get_context(struct task_struct *tsk,
 						      int return_valid,
-						      int return_code)
+						      long return_code)
 {
 	struct audit_context *context = tsk->audit_context;
 
@@ -1024,7 +1024,7 @@
 {
 	char arg_num_len_buf[12];
 	const char __user *tmp_p = p;
-	/* how many digits are in arg_num? 3 is the length of a=\n */
+	/* how many digits are in arg_num? 3 is the length of " a=" */
 	size_t arg_num_len = snprintf(arg_num_len_buf, 12, "%d", arg_num) + 3;
 	size_t len, len_left, to_send;
 	size_t max_execve_audit_len = MAX_EXECVE_AUDIT_LEN;
@@ -1110,7 +1110,7 @@
 		 * so we can be sure nothing was lost.
 		 */
 		if ((i == 0) && (too_long))
-			audit_log_format(*ab, "a%d_len=%zu ", arg_num,
+			audit_log_format(*ab, " a%d_len=%zu", arg_num,
 					 has_cntl ? 2*len : len);
 
 		/*
@@ -1130,7 +1130,7 @@
 		buf[to_send] = '\0';
 
 		/* actually log it */
-		audit_log_format(*ab, "a%d", arg_num);
+		audit_log_format(*ab, " a%d", arg_num);
 		if (too_long)
 			audit_log_format(*ab, "[%d]", i);
 		audit_log_format(*ab, "=");
@@ -1138,7 +1138,6 @@
 			audit_log_n_hex(*ab, buf, to_send);
 		else
 			audit_log_format(*ab, "\"%s\"", buf);
-		audit_log_format(*ab, "\n");
 
 		p += to_send;
 		len_left -= to_send;
@@ -1166,7 +1165,7 @@
 
 	p = (const char __user *)axi->mm->arg_start;
 
-	audit_log_format(*ab, "argc=%d ", axi->argc);
+	audit_log_format(*ab, "argc=%d", axi->argc);
 
 	/*
 	 * we need some kernel buffer to hold the userspace args.  Just
@@ -1479,7 +1478,7 @@
 			case 0:
 				/* name was specified as a relative path and the
 				 * directory component is the cwd */
-				audit_log_d_path(ab, " name=", &context->pwd);
+				audit_log_d_path(ab, "name=", &context->pwd);
 				break;
 			default:
 				/* log the name's directory component */
@@ -2150,7 +2149,7 @@
  * __audit_mq_open - record audit data for a POSIX MQ open
  * @oflag: open flag
  * @mode: mode bits
- * @u_attr: queue attributes
+ * @attr: queue attributes
  *
  */
 void __audit_mq_open(int oflag, mode_t mode, struct mq_attr *attr)
@@ -2197,7 +2196,7 @@
 /**
  * __audit_mq_notify - record audit data for a POSIX MQ notify
  * @mqdes: MQ descriptor
- * @u_notification: Notification event
+ * @notification: Notification event
  *
  */
 
diff --git a/kernel/extable.c b/kernel/extable.c
index e136ed8..7f8f263 100644
--- a/kernel/extable.c
+++ b/kernel/extable.c
@@ -15,11 +15,22 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
-#include <linux/module.h>
-#include <linux/init.h>
 #include <linux/ftrace.h>
-#include <asm/uaccess.h>
+#include <linux/memory.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/init.h>
+
 #include <asm/sections.h>
+#include <asm/uaccess.h>
+
+/*
+ * mutex protecting text section modification (dynamic code patching).
+ * some users need to sleep (allocating memory...) while they hold this lock.
+ *
+ * NOT exported to modules - patching kernel text is a really delicate matter.
+ */
+DEFINE_MUTEX(text_mutex);
 
 extern struct exception_table_entry __start___ex_table[];
 extern struct exception_table_entry __stop___ex_table[];
@@ -41,31 +52,50 @@
 	return e;
 }
 
-__notrace_funcgraph int core_kernel_text(unsigned long addr)
+static inline int init_kernel_text(unsigned long addr)
+{
+	if (addr >= (unsigned long)_sinittext &&
+	    addr <= (unsigned long)_einittext)
+		return 1;
+	return 0;
+}
+
+int core_kernel_text(unsigned long addr)
 {
 	if (addr >= (unsigned long)_stext &&
 	    addr <= (unsigned long)_etext)
 		return 1;
 
 	if (system_state == SYSTEM_BOOTING &&
-	    addr >= (unsigned long)_sinittext &&
-	    addr <= (unsigned long)_einittext)
+	    init_kernel_text(addr))
 		return 1;
 	return 0;
 }
 
-__notrace_funcgraph int __kernel_text_address(unsigned long addr)
+int __kernel_text_address(unsigned long addr)
 {
 	if (core_kernel_text(addr))
 		return 1;
-	return __module_text_address(addr) != NULL;
+	if (is_module_text_address(addr))
+		return 1;
+	/*
+	 * There might be init symbols in saved stacktraces.
+	 * Give those symbols a chance to be printed in
+	 * backtraces (such as lockdep traces).
+	 *
+	 * Since we are after the module-symbols check, there's
+	 * no danger of address overlap:
+	 */
+	if (init_kernel_text(addr))
+		return 1;
+	return 0;
 }
 
 int kernel_text_address(unsigned long addr)
 {
 	if (core_kernel_text(addr))
 		return 1;
-	return module_text_address(addr) != NULL;
+	return is_module_text_address(addr);
 }
 
 /*
@@ -81,5 +111,5 @@
 	addr = (unsigned long) dereference_function_descriptor(ptr);
 	if (core_kernel_text(addr))
 		return 1;
-	return module_text_address(addr) != NULL;
+	return is_module_text_address(addr);
 }
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 9ebf779..343acec 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -17,6 +17,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/rculist.h>
 #include <linux/hash.h>
+#include <trace/irq.h>
 #include <linux/bootmem.h>
 
 #include "internals.h"
@@ -338,6 +339,9 @@
 	return IRQ_NONE;
 }
 
+DEFINE_TRACE(irq_handler_entry);
+DEFINE_TRACE(irq_handler_exit);
+
 /**
  * handle_IRQ_event - irq action chain handler
  * @irq:	the interrupt number
@@ -356,7 +360,9 @@
 		local_irq_enable_in_hardirq();
 
 	do {
+		trace_irq_handler_entry(irq, action);
 		ret = action->handler(irq, action->dev_id);
+		trace_irq_handler_exit(irq, action, ret);
 		if (ret == IRQ_HANDLED)
 			status |= action->flags;
 		retval |= ret;
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index 7b8b0f2..374faf9 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -161,6 +161,25 @@
 	return module_kallsyms_lookup_name(name);
 }
 
+int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
+				      unsigned long),
+			    void *data)
+{
+	char namebuf[KSYM_NAME_LEN];
+	unsigned long i;
+	unsigned int off;
+	int ret;
+
+	for (i = 0, off = 0; i < kallsyms_num_syms; i++) {
+		off = kallsyms_expand_symbol(off, namebuf);
+		ret = fn(data, namebuf, NULL, kallsyms_addresses[i]);
+		if (ret != 0)
+			return ret;
+	}
+	return module_kallsyms_on_each_symbol(fn, data);
+}
+EXPORT_SYMBOL_GPL(kallsyms_on_each_symbol);
+
 static unsigned long get_symbol_pos(unsigned long addr,
 				    unsigned long *symbolsize,
 				    unsigned long *offset)
diff --git a/kernel/kmod.c b/kernel/kmod.c
index f0c8f54..b750675 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -50,7 +50,8 @@
 char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe";
 
 /**
- * request_module - try to load a kernel module
+ * __request_module - try to load a kernel module
+ * @wait: wait (or not) for the operation to complete
  * @fmt: printf style format string for the name of the module
  * @...: arguments as specified in the format string
  *
@@ -63,7 +64,7 @@
  * If module auto-loading support is disabled then this function
  * becomes a no-operation.
  */
-int request_module(const char *fmt, ...)
+int __request_module(bool wait, const char *fmt, ...)
 {
 	va_list args;
 	char module_name[MODULE_NAME_LEN];
@@ -108,11 +109,12 @@
 		return -ENOMEM;
 	}
 
-	ret = call_usermodehelper(modprobe_path, argv, envp, 1);
+	ret = call_usermodehelper(modprobe_path, argv, envp,
+			wait ? UMH_WAIT_PROC : UMH_WAIT_EXEC);
 	atomic_dec(&kmod_concurrent);
 	return ret;
 }
-EXPORT_SYMBOL(request_module);
+EXPORT_SYMBOL(__request_module);
 #endif /* CONFIG_MODULES */
 
 struct subprocess_info {
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 7ba8cd9..5016bfb 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -43,6 +43,7 @@
 #include <linux/seq_file.h>
 #include <linux/debugfs.h>
 #include <linux/kdebug.h>
+#include <linux/memory.h>
 
 #include <asm-generic/sections.h>
 #include <asm/cacheflush.h>
@@ -699,9 +700,10 @@
 		goto out;
 	}
 
+	mutex_lock(&text_mutex);
 	ret = arch_prepare_kprobe(p);
 	if (ret)
-		goto out;
+		goto out_unlock_text;
 
 	INIT_HLIST_NODE(&p->hlist);
 	hlist_add_head_rcu(&p->hlist,
@@ -710,6 +712,8 @@
 	if (kprobe_enabled)
 		arch_arm_kprobe(p);
 
+out_unlock_text:
+	mutex_unlock(&text_mutex);
 out:
 	mutex_unlock(&kprobe_mutex);
 
@@ -746,8 +750,11 @@
 		 * enabled and not gone - otherwise, the breakpoint would
 		 * already have been removed. We save on flushing icache.
 		 */
-		if (kprobe_enabled && !kprobe_gone(old_p))
+		if (kprobe_enabled && !kprobe_gone(old_p)) {
+			mutex_lock(&text_mutex);
 			arch_disarm_kprobe(p);
+			mutex_unlock(&text_mutex);
+		}
 		hlist_del_rcu(&old_p->hlist);
 	} else {
 		if (p->break_handler && !kprobe_gone(p))
@@ -912,10 +919,8 @@
 		ri->rp = rp;
 		ri->task = current;
 
-		if (rp->entry_handler && rp->entry_handler(ri, regs)) {
-			spin_unlock_irqrestore(&rp->lock, flags);
+		if (rp->entry_handler && rp->entry_handler(ri, regs))
 			return 0;
-		}
 
 		arch_prepare_kretprobe(ri, regs);
 
@@ -1280,12 +1285,14 @@
 	if (kprobe_enabled)
 		goto already_enabled;
 
+	mutex_lock(&text_mutex);
 	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
 		head = &kprobe_table[i];
 		hlist_for_each_entry_rcu(p, node, head, hlist)
 			if (!kprobe_gone(p))
 				arch_arm_kprobe(p);
 	}
+	mutex_unlock(&text_mutex);
 
 	kprobe_enabled = true;
 	printk(KERN_INFO "Kprobes globally enabled\n");
@@ -1310,6 +1317,7 @@
 
 	kprobe_enabled = false;
 	printk(KERN_INFO "Kprobes globally disabled\n");
+	mutex_lock(&text_mutex);
 	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
 		head = &kprobe_table[i];
 		hlist_for_each_entry_rcu(p, node, head, hlist) {
@@ -1318,6 +1326,7 @@
 		}
 	}
 
+	mutex_unlock(&text_mutex);
 	mutex_unlock(&kprobe_mutex);
 	/* Allow all currently running kprobes to complete */
 	synchronize_sched();
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 3673a3f..81b5f33 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -42,6 +42,7 @@
 #include <linux/hash.h>
 #include <linux/ftrace.h>
 #include <linux/stringify.h>
+#include <trace/lockdep.h>
 
 #include <asm/sections.h>
 
@@ -433,13 +434,6 @@
 atomic_t nr_find_usage_forwards_recursions;
 atomic_t nr_find_usage_backwards_checks;
 atomic_t nr_find_usage_backwards_recursions;
-# define debug_atomic_inc(ptr)		atomic_inc(ptr)
-# define debug_atomic_dec(ptr)		atomic_dec(ptr)
-# define debug_atomic_read(ptr)		atomic_read(ptr)
-#else
-# define debug_atomic_inc(ptr)		do { } while (0)
-# define debug_atomic_dec(ptr)		do { } while (0)
-# define debug_atomic_read(ptr)		0
 #endif
 
 /*
@@ -1900,9 +1894,9 @@
 		curr->comm, task_pid_nr(curr));
 	print_lock(this);
 	if (forwards)
-		printk("but this lock took another, %s-irq-unsafe lock in the past:\n", irqclass);
+		printk("but this lock took another, %s-unsafe lock in the past:\n", irqclass);
 	else
-		printk("but this lock was taken by another, %s-irq-safe lock in the past:\n", irqclass);
+		printk("but this lock was taken by another, %s-safe lock in the past:\n", irqclass);
 	print_lock_name(other);
 	printk("\n\nand interrupts could create inverse lock ordering between them.\n\n");
 
@@ -2015,7 +2009,8 @@
 			     enum lock_usage_bit bit, const char *name);
 
 static int
-mark_lock_irq(struct task_struct *curr, struct held_lock *this, int new_bit)
+mark_lock_irq(struct task_struct *curr, struct held_lock *this,
+		enum lock_usage_bit new_bit)
 {
 	int excl_bit = exclusive_bit(new_bit);
 	int read = new_bit & 1;
@@ -2043,7 +2038,7 @@
 	 * states.
 	 */
 	if ((!read || !dir || STRICT_READ_CHECKS) &&
-			!usage(curr, this, excl_bit, state_name(new_bit)))
+			!usage(curr, this, excl_bit, state_name(new_bit & ~1)))
 		return 0;
 
 	/*
@@ -2929,6 +2924,8 @@
 }
 EXPORT_SYMBOL_GPL(lock_set_class);
 
+DEFINE_TRACE(lock_acquire);
+
 /*
  * We are not always called with irqs disabled - do that here,
  * and also avoid lockdep recursion:
@@ -2939,6 +2936,8 @@
 {
 	unsigned long flags;
 
+	trace_lock_acquire(lock, subclass, trylock, read, check, nest_lock, ip);
+
 	if (unlikely(current->lockdep_recursion))
 		return;
 
@@ -2953,11 +2952,15 @@
 }
 EXPORT_SYMBOL_GPL(lock_acquire);
 
+DEFINE_TRACE(lock_release);
+
 void lock_release(struct lockdep_map *lock, int nested,
 			  unsigned long ip)
 {
 	unsigned long flags;
 
+	trace_lock_release(lock, nested, ip);
+
 	if (unlikely(current->lockdep_recursion))
 		return;
 
@@ -3106,10 +3109,14 @@
 	lock->ip = ip;
 }
 
+DEFINE_TRACE(lock_contended);
+
 void lock_contended(struct lockdep_map *lock, unsigned long ip)
 {
 	unsigned long flags;
 
+	trace_lock_contended(lock, ip);
+
 	if (unlikely(!lock_stat))
 		return;
 
@@ -3125,10 +3132,14 @@
 }
 EXPORT_SYMBOL_GPL(lock_contended);
 
+DEFINE_TRACE(lock_acquired);
+
 void lock_acquired(struct lockdep_map *lock, unsigned long ip)
 {
 	unsigned long flags;
 
+	trace_lock_acquired(lock, ip);
+
 	if (unlikely(!lock_stat))
 		return;
 
diff --git a/kernel/module.c b/kernel/module.c
index f77ac32..c268a77 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -68,7 +68,8 @@
 
 /* List of modules, protected by module_mutex or preempt_disable
  * (delete uses stop_machine/add uses RCU list operations). */
-static DEFINE_MUTEX(module_mutex);
+DEFINE_MUTEX(module_mutex);
+EXPORT_SYMBOL_GPL(module_mutex);
 static LIST_HEAD(modules);
 
 /* Waiting for a module to finish initializing? */
@@ -76,7 +77,7 @@
 
 static BLOCKING_NOTIFIER_HEAD(module_notify_list);
 
-/* Bounds of module allocation, for speeding __module_text_address */
+/* Bounds of module allocation, for speeding __module_address */
 static unsigned long module_addr_min = -1UL, module_addr_max = 0;
 
 int register_module_notifier(struct notifier_block * nb)
@@ -186,17 +187,6 @@
 #define symversion(base, idx) ((base != NULL) ? ((base) + (idx)) : NULL)
 #endif
 
-struct symsearch {
-	const struct kernel_symbol *start, *stop;
-	const unsigned long *crcs;
-	enum {
-		NOT_GPL_ONLY,
-		GPL_ONLY,
-		WILL_BE_GPL_ONLY,
-	} licence;
-	bool unused;
-};
-
 static bool each_symbol_in_section(const struct symsearch *arr,
 				   unsigned int arrsize,
 				   struct module *owner,
@@ -217,10 +207,8 @@
 }
 
 /* Returns true as soon as fn returns true, otherwise false. */
-static bool each_symbol(bool (*fn)(const struct symsearch *arr,
-				   struct module *owner,
-				   unsigned int symnum, void *data),
-			void *data)
+bool each_symbol(bool (*fn)(const struct symsearch *arr, struct module *owner,
+			    unsigned int symnum, void *data), void *data)
 {
 	struct module *mod;
 	const struct symsearch arr[] = {
@@ -273,6 +261,7 @@
 	}
 	return false;
 }
+EXPORT_SYMBOL_GPL(each_symbol);
 
 struct find_symbol_arg {
 	/* Input */
@@ -283,7 +272,7 @@
 	/* Output */
 	struct module *owner;
 	const unsigned long *crc;
-	unsigned long value;
+	const struct kernel_symbol *sym;
 };
 
 static bool find_symbol_in_section(const struct symsearch *syms,
@@ -324,17 +313,17 @@
 
 	fsa->owner = owner;
 	fsa->crc = symversion(syms->crcs, symnum);
-	fsa->value = syms->start[symnum].value;
+	fsa->sym = &syms->start[symnum];
 	return true;
 }
 
-/* Find a symbol, return value, (optional) crc and (optional) module
- * which owns it */
-static unsigned long find_symbol(const char *name,
-				 struct module **owner,
-				 const unsigned long **crc,
-				 bool gplok,
-				 bool warn)
+/* Find a symbol and return it, along with, (optional) crc and
+ * (optional) module which owns it */
+const struct kernel_symbol *find_symbol(const char *name,
+					struct module **owner,
+					const unsigned long **crc,
+					bool gplok,
+					bool warn)
 {
 	struct find_symbol_arg fsa;
 
@@ -347,15 +336,16 @@
 			*owner = fsa.owner;
 		if (crc)
 			*crc = fsa.crc;
-		return fsa.value;
+		return fsa.sym;
 	}
 
 	DEBUGP("Failed to find symbol %s\n", name);
-	return -ENOENT;
+	return NULL;
 }
+EXPORT_SYMBOL_GPL(find_symbol);
 
 /* Search for module by name: must hold module_mutex. */
-static struct module *find_module(const char *name)
+struct module *find_module(const char *name)
 {
 	struct module *mod;
 
@@ -365,6 +355,7 @@
 	}
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(find_module);
 
 #ifdef CONFIG_SMP
 
@@ -641,7 +632,7 @@
 }
 
 /* Module a uses b */
-static int use_module(struct module *a, struct module *b)
+int use_module(struct module *a, struct module *b)
 {
 	struct module_use *use;
 	int no_warn, err;
@@ -674,6 +665,7 @@
 	no_warn = sysfs_create_link(b->holders_dir, &a->mkobj.kobj, a->name);
 	return 1;
 }
+EXPORT_SYMBOL_GPL(use_module);
 
 /* Clear the unload stuff of the module. */
 static void module_unload_free(struct module *mod)
@@ -894,7 +886,7 @@
 	struct module *owner;
 
 	preempt_disable();
-	if (IS_ERR_VALUE(find_symbol(symbol, &owner, NULL, true, false)))
+	if (!find_symbol(symbol, &owner, NULL, true, false))
 		BUG();
 	module_put(owner);
 	preempt_enable();
@@ -908,8 +900,10 @@
 	if (core_kernel_text((unsigned long)addr))
 		return;
 
-	if (!(modaddr = module_text_address((unsigned long)addr)))
-		BUG();
+	/* module_text_address is safe here: we're supposed to have reference
+	 * to module from symbol_get, so it can't go away. */
+	modaddr = __module_text_address((unsigned long)addr);
+	BUG_ON(!modaddr);
 	module_put(modaddr);
 }
 EXPORT_SYMBOL_GPL(symbol_put_addr);
@@ -949,10 +943,11 @@
 {
 }
 
-static inline int use_module(struct module *a, struct module *b)
+int use_module(struct module *a, struct module *b)
 {
 	return strong_try_module_get(b) == 0;
 }
+EXPORT_SYMBOL_GPL(use_module);
 
 static inline void module_unload_init(struct module *mod)
 {
@@ -995,12 +990,12 @@
 
 static const char vermagic[] = VERMAGIC_STRING;
 
-static int try_to_force_load(struct module *mod, const char *symname)
+static int try_to_force_load(struct module *mod, const char *reason)
 {
 #ifdef CONFIG_MODULE_FORCE_LOAD
 	if (!test_taint(TAINT_FORCED_MODULE))
-		printk("%s: no version for \"%s\" found: kernel tainted.\n",
-		       mod->name, symname);
+		printk(KERN_WARNING "%s: %s: kernel tainted.\n",
+		       mod->name, reason);
 	add_taint_module(mod, TAINT_FORCED_MODULE);
 	return 0;
 #else
@@ -1057,9 +1052,9 @@
 {
 	const unsigned long *crc;
 
-	if (IS_ERR_VALUE(find_symbol("struct_module", NULL, &crc, true, false)))
+	if (!find_symbol("module_layout", NULL, &crc, true, false))
 		BUG();
-	return check_version(sechdrs, versindex, "struct_module", mod, crc);
+	return check_version(sechdrs, versindex, "module_layout", mod, crc);
 }
 
 /* First part is kernel version, which we ignore if module has crcs. */
@@ -1098,25 +1093,25 @@
 
 /* Resolve a symbol for this module.  I.e. if we find one, record usage.
    Must be holding module_mutex. */
-static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
-				    unsigned int versindex,
-				    const char *name,
-				    struct module *mod)
+static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs,
+						  unsigned int versindex,
+						  const char *name,
+						  struct module *mod)
 {
 	struct module *owner;
-	unsigned long ret;
+	const struct kernel_symbol *sym;
 	const unsigned long *crc;
 
-	ret = find_symbol(name, &owner, &crc,
+	sym = find_symbol(name, &owner, &crc,
 			  !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true);
-	if (!IS_ERR_VALUE(ret)) {
-		/* use_module can fail due to OOM,
-		   or module initialization or unloading */
+	/* use_module can fail due to OOM,
+	   or module initialization or unloading */
+	if (sym) {
 		if (!check_version(sechdrs, versindex, name, mod, crc) ||
 		    !use_module(mod, owner))
-			ret = -EINVAL;
+			sym = NULL;
 	}
-	return ret;
+	return sym;
 }
 
 /*
@@ -1491,6 +1486,9 @@
 	/* Module unload stuff */
 	module_unload_free(mod);
 
+	/* Free any allocated parameters. */
+	destroy_params(mod->kp, mod->num_kp);
+
 	/* release any pointers to mcount in this module */
 	ftrace_release(mod->module_core, mod->core_size);
 
@@ -1513,17 +1511,15 @@
 void *__symbol_get(const char *symbol)
 {
 	struct module *owner;
-	unsigned long value;
+	const struct kernel_symbol *sym;
 
 	preempt_disable();
-	value = find_symbol(symbol, &owner, NULL, true, true);
-	if (IS_ERR_VALUE(value))
-		value = 0;
-	else if (strong_try_module_get(owner))
-		value = 0;
+	sym = find_symbol(symbol, &owner, NULL, true, true);
+	if (sym && strong_try_module_get(owner))
+		sym = NULL;
 	preempt_enable();
 
-	return (void *)value;
+	return sym ? (void *)sym->value : NULL;
 }
 EXPORT_SYMBOL_GPL(__symbol_get);
 
@@ -1551,8 +1547,7 @@
 
 	for (i = 0; i < ARRAY_SIZE(arr); i++) {
 		for (s = arr[i].sym; s < arr[i].sym + arr[i].num; s++) {
-			if (!IS_ERR_VALUE(find_symbol(s->name, &owner,
-						      NULL, true, false))) {
+			if (find_symbol(s->name, &owner, NULL, true, false)) {
 				printk(KERN_ERR
 				       "%s: exports duplicate symbol %s"
 				       " (owned by %s)\n",
@@ -1576,6 +1571,7 @@
 	unsigned long secbase;
 	unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
 	int ret = 0;
+	const struct kernel_symbol *ksym;
 
 	for (i = 1; i < n; i++) {
 		switch (sym[i].st_shndx) {
@@ -1595,13 +1591,14 @@
 			break;
 
 		case SHN_UNDEF:
-			sym[i].st_value
-			  = resolve_symbol(sechdrs, versindex,
-					   strtab + sym[i].st_name, mod);
-
+			ksym = resolve_symbol(sechdrs, versindex,
+					      strtab + sym[i].st_name, mod);
 			/* Ok if resolved.  */
-			if (!IS_ERR_VALUE(sym[i].st_value))
+			if (ksym) {
+				sym[i].st_value = ksym->value;
 				break;
+			}
+
 			/* Ok if weak.  */
 			if (ELF_ST_BIND(sym[i].st_info) == STB_WEAK)
 				break;
@@ -1676,8 +1673,7 @@
 			if ((s->sh_flags & masks[m][0]) != masks[m][0]
 			    || (s->sh_flags & masks[m][1])
 			    || s->sh_entsize != ~0UL
-			    || strncmp(secstrings + s->sh_name,
-				       ".init", 5) == 0)
+			    || strstarts(secstrings + s->sh_name, ".init"))
 				continue;
 			s->sh_entsize = get_offset(mod, &mod->core_size, s, i);
 			DEBUGP("\t%s\n", secstrings + s->sh_name);
@@ -1694,8 +1690,7 @@
 			if ((s->sh_flags & masks[m][0]) != masks[m][0]
 			    || (s->sh_flags & masks[m][1])
 			    || s->sh_entsize != ~0UL
-			    || strncmp(secstrings + s->sh_name,
-				       ".init", 5) != 0)
+			    || !strstarts(secstrings + s->sh_name, ".init"))
 				continue;
 			s->sh_entsize = (get_offset(mod, &mod->init_size, s, i)
 					 | INIT_OFFSET_MASK);
@@ -1828,8 +1823,7 @@
 		else
 			return 'b';
 	}
-	if (strncmp(secstrings + sechdrs[sym->st_shndx].sh_name,
-		    ".debug", strlen(".debug")) == 0)
+	if (strstarts(secstrings + sechdrs[sym->st_shndx].sh_name, ".debug"))
 		return 'n';
 	return '?';
 }
@@ -1898,8 +1892,7 @@
 	unsigned int symindex = 0;
 	unsigned int strindex = 0;
 	unsigned int modindex, versindex, infoindex, pcpuindex;
-	unsigned int num_kp, num_mcount;
-	struct kernel_param *kp;
+	unsigned int num_mcount;
 	struct module *mod;
 	long err = 0;
 	void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
@@ -1916,12 +1909,6 @@
 	if (len > 64 * 1024 * 1024 || (hdr = vmalloc(len)) == NULL)
 		return ERR_PTR(-ENOMEM);
 
-	/* Create stop_machine threads since the error path relies on
-	 * a non-failing stop_machine call. */
-	err = stop_machine_create();
-	if (err)
-		goto free_hdr;
-
 	if (copy_from_user(hdr, umod, len) != 0) {
 		err = -EFAULT;
 		goto free_hdr;
@@ -1962,9 +1949,12 @@
 		}
 #ifndef CONFIG_MODULE_UNLOAD
 		/* Don't load .exit sections */
-		if (strncmp(secstrings+sechdrs[i].sh_name, ".exit", 5) == 0)
+		if (strstarts(secstrings+sechdrs[i].sh_name, ".exit"))
 			sechdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC;
 #endif
+		/* Don't keep __versions around; it's just for loading. */
+		if (strcmp(secstrings + sechdrs[i].sh_name, "__versions") == 0)
+			sechdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC;
 	}
 
 	modindex = find_sec(hdr, sechdrs, secstrings,
@@ -2006,7 +1996,7 @@
 	modmagic = get_modinfo(sechdrs, infoindex, "vermagic");
 	/* This is allowed: modprobe --force will invalidate it. */
 	if (!modmagic) {
-		err = try_to_force_load(mod, "magic");
+		err = try_to_force_load(mod, "bad vermagic");
 		if (err)
 			goto free_hdr;
 	} else if (!same_magic(modmagic, vermagic, versindex)) {
@@ -2144,8 +2134,8 @@
 
 	/* Now we've got everything in the final locations, we can
 	 * find optional sections. */
-	kp = section_objs(hdr, sechdrs, secstrings, "__param", sizeof(*kp),
-			  &num_kp);
+	mod->kp = section_objs(hdr, sechdrs, secstrings, "__param",
+			       sizeof(*mod->kp), &mod->num_kp);
 	mod->syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab",
 				 sizeof(*mod->syms), &mod->num_syms);
 	mod->crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab");
@@ -2195,8 +2185,8 @@
 	    || (mod->num_unused_gpl_syms && !mod->unused_gpl_crcs)
 #endif
 		) {
-		printk(KERN_WARNING "%s: No versions for exported symbols.\n", mod->name);
-		err = try_to_force_load(mod, "nocrc");
+		err = try_to_force_load(mod,
+					"no versions for exported symbols");
 		if (err)
 			goto cleanup;
 	}
@@ -2291,11 +2281,11 @@
 	 */
 	list_add_rcu(&mod->list, &modules);
 
-	err = parse_args(mod->name, mod->args, kp, num_kp, NULL);
+	err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp, NULL);
 	if (err < 0)
 		goto unlink;
 
-	err = mod_sysfs_setup(mod, kp, num_kp);
+	err = mod_sysfs_setup(mod, mod->kp, mod->num_kp);
 	if (err < 0)
 		goto unlink;
 	add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
@@ -2304,12 +2294,13 @@
 	/* Get rid of temporary copy */
 	vfree(hdr);
 
-	stop_machine_destroy();
 	/* Done! */
 	return mod;
 
  unlink:
-	stop_machine(__unlink_module, mod, NULL);
+	/* Unlink carefully: kallsyms could be walking list. */
+	list_del_rcu(&mod->list);
+	synchronize_sched();
 	module_arch_cleanup(mod);
  cleanup:
 	kobject_del(&mod->mkobj.kobj);
@@ -2317,8 +2308,8 @@
 	ftrace_release(mod->module_core, mod->core_size);
  free_unload:
 	module_unload_free(mod);
- free_init:
 #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP)
+ free_init:
 	percpu_modfree(mod->refptr);
 #endif
 	module_free(mod, mod->module_init);
@@ -2332,7 +2323,6 @@
 	kfree(args);
  free_hdr:
 	vfree(hdr);
-	stop_machine_destroy();
 	return ERR_PTR(err);
 
  truncated:
@@ -2609,6 +2599,25 @@
 	preempt_enable();
 	return ret;
 }
+
+int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
+					     struct module *, unsigned long),
+				   void *data)
+{
+	struct module *mod;
+	unsigned int i;
+	int ret;
+
+	list_for_each_entry(mod, &modules, list) {
+		for (i = 0; i < mod->num_symtab; i++) {
+			ret = fn(data, mod->strtab + mod->symtab[i].st_name,
+				 mod, mod->symtab[i].st_value);
+			if (ret != 0)
+				return ret;
+		}
+	}
+	return 0;
+}
 #endif /* CONFIG_KALLSYMS */
 
 static char *module_flags(struct module *mod, char *buf)
@@ -2744,29 +2753,31 @@
 }
 
 /*
- * Is this a valid module address?
+ * is_module_address - is this address inside a module?
+ * @addr: the address to check.
+ *
+ * See is_module_text_address() if you simply want to see if the address
+ * is code (not data).
  */
-int is_module_address(unsigned long addr)
+bool is_module_address(unsigned long addr)
 {
-	struct module *mod;
+	bool ret;
 
 	preempt_disable();
-
-	list_for_each_entry_rcu(mod, &modules, list) {
-		if (within_module_core(addr, mod)) {
-			preempt_enable();
-			return 1;
-		}
-	}
-
+	ret = __module_address(addr) != NULL;
 	preempt_enable();
 
-	return 0;
+	return ret;
 }
 
-
-/* Is this a valid kernel address? */
-__notrace_funcgraph struct module *__module_text_address(unsigned long addr)
+/*
+ * __module_address - get the module which contains an address.
+ * @addr: the address.
+ *
+ * Must be called with preempt disabled or module mutex held so that
+ * module doesn't get freed during this.
+ */
+struct module *__module_address(unsigned long addr)
 {
 	struct module *mod;
 
@@ -2774,22 +2785,51 @@
 		return NULL;
 
 	list_for_each_entry_rcu(mod, &modules, list)
-		if (within(addr, mod->module_init, mod->init_text_size)
-		    || within(addr, mod->module_core, mod->core_text_size))
+		if (within_module_core(addr, mod)
+		    || within_module_init(addr, mod))
 			return mod;
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(__module_address);
 
-struct module *module_text_address(unsigned long addr)
+/*
+ * is_module_text_address - is this address inside module code?
+ * @addr: the address to check.
+ *
+ * See is_module_address() if you simply want to see if the address is
+ * anywhere in a module.  See kernel_text_address() for testing if an
+ * address corresponds to kernel or module code.
+ */
+bool is_module_text_address(unsigned long addr)
 {
-	struct module *mod;
+	bool ret;
 
 	preempt_disable();
-	mod = __module_text_address(addr);
+	ret = __module_text_address(addr) != NULL;
 	preempt_enable();
 
+	return ret;
+}
+
+/*
+ * __module_text_address - get the module whose code contains an address.
+ * @addr: the address.
+ *
+ * Must be called with preempt disabled or module mutex held so that
+ * module doesn't get freed during this.
+ */
+struct module *__module_text_address(unsigned long addr)
+{
+	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))
+			mod = NULL;
+	}
 	return mod;
 }
+EXPORT_SYMBOL_GPL(__module_text_address);
 
 /* Don't grab lock, we're oopsing. */
 void print_modules(void)
@@ -2809,9 +2849,17 @@
 }
 
 #ifdef CONFIG_MODVERSIONS
-/* Generate the signature for struct module here, too, for modversions. */
-void struct_module(struct module *mod) { return; }
-EXPORT_SYMBOL(struct_module);
+/* Generate the signature for all relevant module structures here.
+ * If these change, we don't want to try to parse the module. */
+void module_layout(struct module *mod,
+		   struct modversion_info *ver,
+		   struct kernel_param *kp,
+		   struct kernel_symbol *ks,
+		   struct marker *marker,
+		   struct tracepoint *tp)
+{
+}
+EXPORT_SYMBOL(module_layout);
 #endif
 
 #ifdef CONFIG_MARKERS
diff --git a/kernel/panic.c b/kernel/panic.c
index 32fe4ef..3fd8c5b 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -8,19 +8,19 @@
  * This function is used through-out the kernel (including mm and fs)
  * to indicate a major problem.
  */
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/reboot.h>
-#include <linux/notifier.h>
-#include <linux/init.h>
-#include <linux/sysrq.h>
-#include <linux/interrupt.h>
-#include <linux/nmi.h>
-#include <linux/kexec.h>
 #include <linux/debug_locks.h>
-#include <linux/random.h>
+#include <linux/interrupt.h>
 #include <linux/kallsyms.h>
+#include <linux/notifier.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/reboot.h>
+#include <linux/delay.h>
+#include <linux/kexec.h>
+#include <linux/sched.h>
+#include <linux/sysrq.h>
+#include <linux/init.h>
+#include <linux/nmi.h>
 #include <linux/dmi.h>
 
 int panic_on_oops;
@@ -52,19 +52,15 @@
  *
  *	This function never returns.
  */
-
 NORET_TYPE void panic(const char * fmt, ...)
 {
-	long i;
 	static char buf[1024];
 	va_list args;
-#if defined(CONFIG_S390)
-	unsigned long caller = (unsigned long) __builtin_return_address(0);
-#endif
+	long i;
 
 	/*
-	 * It's possible to come here directly from a panic-assertion and not
-	 * have preempt disabled. Some functions called from here want
+	 * It's possible to come here directly from a panic-assertion and
+	 * not have preempt disabled. Some functions called from here want
 	 * preempt to be disabled. No point enabling it later though...
 	 */
 	preempt_disable();
@@ -77,7 +73,6 @@
 #ifdef CONFIG_DEBUG_BUGVERBOSE
 	dump_stack();
 #endif
-	bust_spinlocks(0);
 
 	/*
 	 * If we have crashed and we have a crash kernel loaded let it handle
@@ -86,14 +81,12 @@
 	 */
 	crash_kexec(NULL);
 
-#ifdef CONFIG_SMP
 	/*
 	 * Note smp_send_stop is the usual smp shutdown function, which
 	 * unfortunately means it may not be hardened to work in a panic
 	 * situation.
 	 */
 	smp_send_stop();
-#endif
 
 	atomic_notifier_call_chain(&panic_notifier_list, 0, buf);
 
@@ -102,19 +95,21 @@
 
 	if (panic_timeout > 0) {
 		/*
-	 	 * Delay timeout seconds before rebooting the machine. 
-		 * We can't use the "normal" timers since we just panicked..
-	 	 */
-		printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout);
+		 * Delay timeout seconds before rebooting the machine.
+		 * We can't use the "normal" timers since we just panicked.
+		 */
+		printk(KERN_EMERG "Rebooting in %d seconds..", panic_timeout);
+
 		for (i = 0; i < panic_timeout*1000; ) {
 			touch_nmi_watchdog();
 			i += panic_blink(i);
 			mdelay(1);
 			i++;
 		}
-		/*	This will not be a clean reboot, with everything
-		 *	shutting down.  But if there is a chance of
-		 *	rebooting the system it will be rebooted.
+		/*
+		 * This will not be a clean reboot, with everything
+		 * shutting down.  But if there is a chance of
+		 * rebooting the system it will be rebooted.
 		 */
 		emergency_restart();
 	}
@@ -127,38 +122,44 @@
 	}
 #endif
 #if defined(CONFIG_S390)
-	disabled_wait(caller);
+	{
+		unsigned long caller;
+
+		caller = (unsigned long)__builtin_return_address(0);
+		disabled_wait(caller);
+	}
 #endif
 	local_irq_enable();
-	for (i = 0;;) {
+	for (i = 0; ; ) {
 		touch_softlockup_watchdog();
 		i += panic_blink(i);
 		mdelay(1);
 		i++;
 	}
+	bust_spinlocks(0);
 }
 
 EXPORT_SYMBOL(panic);
 
 
 struct tnt {
-	u8 bit;
-	char true;
-	char false;
+	u8	bit;
+	char	true;
+	char	false;
 };
 
 static const struct tnt tnts[] = {
-	{ TAINT_PROPRIETARY_MODULE, 'P', 'G' },
-	{ TAINT_FORCED_MODULE, 'F', ' ' },
-	{ TAINT_UNSAFE_SMP, 'S', ' ' },
-	{ TAINT_FORCED_RMMOD, 'R', ' ' },
-	{ TAINT_MACHINE_CHECK, 'M', ' ' },
-	{ TAINT_BAD_PAGE, 'B', ' ' },
-	{ TAINT_USER, 'U', ' ' },
-	{ TAINT_DIE, 'D', ' ' },
-	{ TAINT_OVERRIDDEN_ACPI_TABLE, 'A', ' ' },
-	{ TAINT_WARN, 'W', ' ' },
-	{ TAINT_CRAP, 'C', ' ' },
+	{ TAINT_PROPRIETARY_MODULE,	'P', 'G' },
+	{ TAINT_FORCED_MODULE,		'F', ' ' },
+	{ TAINT_UNSAFE_SMP,		'S', ' ' },
+	{ TAINT_FORCED_RMMOD,		'R', ' ' },
+	{ TAINT_MACHINE_CHECK,		'M', ' ' },
+	{ TAINT_BAD_PAGE,		'B', ' ' },
+	{ TAINT_USER,			'U', ' ' },
+	{ TAINT_DIE,			'D', ' ' },
+	{ TAINT_OVERRIDDEN_ACPI_TABLE,	'A', ' ' },
+	{ TAINT_WARN,			'W', ' ' },
+	{ TAINT_CRAP,			'C', ' ' },
 };
 
 /**
@@ -195,7 +196,8 @@
 		*s = 0;
 	} else
 		snprintf(buf, sizeof(buf), "Not tainted");
-	return(buf);
+
+	return buf;
 }
 
 int test_taint(unsigned flag)
@@ -211,7 +213,8 @@
 
 void add_taint(unsigned flag)
 {
-	debug_locks = 0; /* can't trust the integrity of the kernel anymore */
+	/* can't trust the integrity of the kernel anymore: */
+	debug_locks = 0;
 	set_bit(flag, &tainted_mask);
 }
 EXPORT_SYMBOL(add_taint);
@@ -266,8 +269,8 @@
 }
 
 /*
- * Return true if the calling CPU is allowed to print oops-related info.  This
- * is a bit racy..
+ * Return true if the calling CPU is allowed to print oops-related info.
+ * This is a bit racy..
  */
 int oops_may_print(void)
 {
@@ -276,20 +279,22 @@
 
 /*
  * Called when the architecture enters its oops handler, before it prints
- * anything.  If this is the first CPU to oops, and it's oopsing the first time
- * then let it proceed.
+ * anything.  If this is the first CPU to oops, and it's oopsing the first
+ * time then let it proceed.
  *
- * This is all enabled by the pause_on_oops kernel boot option.  We do all this
- * to ensure that oopses don't scroll off the screen.  It has the side-effect
- * of preventing later-oopsing CPUs from mucking up the display, too.
+ * This is all enabled by the pause_on_oops kernel boot option.  We do all
+ * this to ensure that oopses don't scroll off the screen.  It has the
+ * side-effect of preventing later-oopsing CPUs from mucking up the display,
+ * too.
  *
- * It turns out that the CPU which is allowed to print ends up pausing for the
- * right duration, whereas all the other CPUs pause for twice as long: once in
- * oops_enter(), once in oops_exit().
+ * It turns out that the CPU which is allowed to print ends up pausing for
+ * the right duration, whereas all the other CPUs pause for twice as long:
+ * once in oops_enter(), once in oops_exit().
  */
 void oops_enter(void)
 {
-	debug_locks_off(); /* can't trust the integrity of the kernel anymore */
+	/* can't trust the integrity of the kernel anymore: */
+	debug_locks_off();
 	do_oops_enter_exit();
 }
 
diff --git a/kernel/params.c b/kernel/params.c
index a1e3025..de273ec 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -24,6 +24,9 @@
 #include <linux/err.h>
 #include <linux/slab.h>
 
+/* We abuse the high bits of "perm" to record whether we kmalloc'ed. */
+#define KPARAM_KMALLOCED	0x80000000
+
 #if 0
 #define DEBUGP printk
 #else
@@ -217,7 +220,19 @@
 		return -ENOSPC;
 	}
 
-	*(char **)kp->arg = (char *)val;
+	if (kp->perm & KPARAM_KMALLOCED)
+		kfree(*(char **)kp->arg);
+
+	/* This is a hack.  We can't need to strdup in early boot, and we
+	 * don't need to; this mangled commandline is preserved. */
+	if (slab_is_available()) {
+		kp->perm |= KPARAM_KMALLOCED;
+		*(char **)kp->arg = kstrdup(val, GFP_KERNEL);
+		if (!kp->arg)
+			return -ENOMEM;
+	} else
+		*(const char **)kp->arg = val;
+
 	return 0;
 }
 
@@ -571,6 +586,15 @@
 }
 #endif
 
+void destroy_params(const struct kernel_param *params, unsigned num)
+{
+	unsigned int i;
+
+	for (i = 0; i < num; i++)
+		if (params[i].perm & KPARAM_KMALLOCED)
+			kfree(*(char **)params[i].arg);
+}
+
 static void __init kernel_add_sysfs_param(const char *name,
 					  struct kernel_param *kparam,
 					  unsigned int name_skip)
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index f3db382..5f21ab2 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -289,7 +289,7 @@
  *	hibernation_snapshot - quiesce devices and create the hibernation
  *	snapshot image.
  *	@platform_mode - if set, use the platform driver, if available, to
- *			 prepare the platform frimware for the power transition.
+ *			 prepare the platform firmware for the power transition.
  *
  *	Must be called with pm_mutex held
  */
@@ -412,7 +412,7 @@
  *	hibernation_restore - quiesce devices and restore the hibernation
  *	snapshot image.  If successful, control returns in hibernation_snaphot()
  *	@platform_mode - if set, use the platform driver, if available, to
- *			 prepare the platform frimware for the transition.
+ *			 prepare the platform firmware for the transition.
  *
  *	Must be called with pm_mutex held
  */
diff --git a/kernel/printk.c b/kernel/printk.c
index a5f61a9..5052b54 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -1311,8 +1311,11 @@
 bool printk_timed_ratelimit(unsigned long *caller_jiffies,
 			unsigned int interval_msecs)
 {
-	if (*caller_jiffies == 0 || time_after(jiffies, *caller_jiffies)) {
-		*caller_jiffies = jiffies + msecs_to_jiffies(interval_msecs);
+	if (*caller_jiffies == 0
+			|| !time_in_range(jiffies, *caller_jiffies,
+					*caller_jiffies
+					+ msecs_to_jiffies(interval_msecs))) {
+		*caller_jiffies = jiffies;
 		return true;
 	}
 	return false;
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 5105f5a..aaad0ec 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -687,8 +687,6 @@
 		goto out_put_task_struct;
 
 	ret = arch_ptrace(child, request, addr, data);
-	if (ret < 0)
-		goto out_put_task_struct;
 
  out_put_task_struct:
 	put_task_struct(child);
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index cae8a05..2c7b845 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -122,6 +122,8 @@
 	}
 }
 
+static inline void wait_migrated_callbacks(void);
+
 /*
  * Orchestrate the specified type of RCU barrier, waiting for all
  * RCU callbacks of the specified type to complete.
@@ -147,6 +149,7 @@
 		complete(&rcu_barrier_completion);
 	wait_for_completion(&rcu_barrier_completion);
 	mutex_unlock(&rcu_barrier_mutex);
+	wait_migrated_callbacks();
 }
 
 /**
@@ -176,9 +179,50 @@
 }
 EXPORT_SYMBOL_GPL(rcu_barrier_sched);
 
+static atomic_t rcu_migrate_type_count = ATOMIC_INIT(0);
+static struct rcu_head rcu_migrate_head[3];
+static DECLARE_WAIT_QUEUE_HEAD(rcu_migrate_wq);
+
+static void rcu_migrate_callback(struct rcu_head *notused)
+{
+	if (atomic_dec_and_test(&rcu_migrate_type_count))
+		wake_up(&rcu_migrate_wq);
+}
+
+static inline void wait_migrated_callbacks(void)
+{
+	wait_event(rcu_migrate_wq, !atomic_read(&rcu_migrate_type_count));
+}
+
+static int __cpuinit rcu_barrier_cpu_hotplug(struct notifier_block *self,
+		unsigned long action, void *hcpu)
+{
+	if (action == CPU_DYING) {
+		/*
+		 * preempt_disable() in on_each_cpu() prevents stop_machine(),
+		 * so when "on_each_cpu(rcu_barrier_func, (void *)type, 1);"
+		 * returns, all online cpus have queued rcu_barrier_func(),
+		 * and the dead cpu(if it exist) queues rcu_migrate_callback()s.
+		 *
+		 * These callbacks ensure _rcu_barrier() waits for all
+		 * RCU callbacks of the specified type to complete.
+		 */
+		atomic_set(&rcu_migrate_type_count, 3);
+		call_rcu_bh(rcu_migrate_head, rcu_migrate_callback);
+		call_rcu_sched(rcu_migrate_head + 1, rcu_migrate_callback);
+		call_rcu(rcu_migrate_head + 2, rcu_migrate_callback);
+	} else if (action == CPU_POST_DEAD) {
+		/* rcu_migrate_head is protected by cpu_add_remove_lock */
+		wait_migrated_callbacks();
+	}
+
+	return NOTIFY_OK;
+}
+
 void __init rcu_init(void)
 {
 	__rcu_init();
+	hotcpu_notifier(rcu_barrier_cpu_hotplug, 0);
 }
 
 void rcu_scheduler_starting(void)
diff --git a/kernel/relay.c b/kernel/relay.c
index e92db8c..bc18854 100644
--- a/kernel/relay.c
+++ b/kernel/relay.c
@@ -677,9 +677,7 @@
 	 */
 	for_each_online_cpu(i) {
 		if (unlikely(!chan->buf[i])) {
-			printk(KERN_ERR "relay_late_setup_files: CPU %u "
-					"has no buffer, it must have!\n", i);
-			BUG();
+			WARN_ONCE(1, KERN_ERR "CPU has no buffer!\n");
 			err = -EINVAL;
 			break;
 		}
diff --git a/kernel/sched.c b/kernel/sched.c
index 73513f4..bec2498 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -1110,7 +1110,7 @@
 	if (rq == this_rq()) {
 		hrtimer_restart(timer);
 	} else if (!rq->hrtick_csd_pending) {
-		__smp_call_function_single(cpu_of(rq), &rq->hrtick_csd);
+		__smp_call_function_single(cpu_of(rq), &rq->hrtick_csd, 0);
 		rq->hrtick_csd_pending = 1;
 	}
 }
@@ -3818,19 +3818,23 @@
  */
 #define MAX_PINNED_INTERVAL	512
 
+/* Working cpumask for load_balance and load_balance_newidle. */
+static DEFINE_PER_CPU(cpumask_var_t, load_balance_tmpmask);
+
 /*
  * Check this_cpu to ensure it is balanced within domain. Attempt to move
  * tasks if there is an imbalance.
  */
 static int load_balance(int this_cpu, struct rq *this_rq,
 			struct sched_domain *sd, enum cpu_idle_type idle,
-			int *balance, struct cpumask *cpus)
+			int *balance)
 {
 	int ld_moved, all_pinned = 0, active_balance = 0, sd_idle = 0;
 	struct sched_group *group;
 	unsigned long imbalance;
 	struct rq *busiest;
 	unsigned long flags;
+	struct cpumask *cpus = __get_cpu_var(load_balance_tmpmask);
 
 	cpumask_setall(cpus);
 
@@ -3985,8 +3989,7 @@
  * this_rq is locked.
  */
 static int
-load_balance_newidle(int this_cpu, struct rq *this_rq, struct sched_domain *sd,
-			struct cpumask *cpus)
+load_balance_newidle(int this_cpu, struct rq *this_rq, struct sched_domain *sd)
 {
 	struct sched_group *group;
 	struct rq *busiest = NULL;
@@ -3994,6 +3997,7 @@
 	int ld_moved = 0;
 	int sd_idle = 0;
 	int all_pinned = 0;
+	struct cpumask *cpus = __get_cpu_var(load_balance_tmpmask);
 
 	cpumask_setall(cpus);
 
@@ -4134,10 +4138,6 @@
 	struct sched_domain *sd;
 	int pulled_task = 0;
 	unsigned long next_balance = jiffies + HZ;
-	cpumask_var_t tmpmask;
-
-	if (!alloc_cpumask_var(&tmpmask, GFP_ATOMIC))
-		return;
 
 	for_each_domain(this_cpu, sd) {
 		unsigned long interval;
@@ -4148,7 +4148,7 @@
 		if (sd->flags & SD_BALANCE_NEWIDLE)
 			/* If we've pulled tasks over stop searching: */
 			pulled_task = load_balance_newidle(this_cpu, this_rq,
-							   sd, tmpmask);
+							   sd);
 
 		interval = msecs_to_jiffies(sd->balance_interval);
 		if (time_after(next_balance, sd->last_balance + interval))
@@ -4163,7 +4163,6 @@
 		 */
 		this_rq->next_balance = next_balance;
 	}
-	free_cpumask_var(tmpmask);
 }
 
 /*
@@ -4313,11 +4312,6 @@
 	unsigned long next_balance = jiffies + 60*HZ;
 	int update_next_balance = 0;
 	int need_serialize;
-	cpumask_var_t tmp;
-
-	/* Fails alloc?  Rebalancing probably not a priority right now. */
-	if (!alloc_cpumask_var(&tmp, GFP_ATOMIC))
-		return;
 
 	for_each_domain(cpu, sd) {
 		if (!(sd->flags & SD_LOAD_BALANCE))
@@ -4342,7 +4336,7 @@
 		}
 
 		if (time_after_eq(jiffies, sd->last_balance + interval)) {
-			if (load_balance(cpu, rq, sd, idle, &balance, tmp)) {
+			if (load_balance(cpu, rq, sd, idle, &balance)) {
 				/*
 				 * We've pulled tasks over so either we're no
 				 * longer idle, or one of our SMT siblings is
@@ -4376,8 +4370,6 @@
 	 */
 	if (likely(update_next_balance))
 		rq->next_balance = next_balance;
-
-	free_cpumask_var(tmp);
 }
 
 /*
@@ -4781,10 +4773,7 @@
 #endif
 }
 
-#if defined(CONFIG_PREEMPT) && (defined(CONFIG_DEBUG_PREEMPT) || \
-				defined(CONFIG_PREEMPT_TRACER))
-
-static inline unsigned long get_parent_ip(unsigned long addr)
+unsigned long get_parent_ip(unsigned long addr)
 {
 	if (in_lock_functions(addr)) {
 		addr = CALLER_ADDR2;
@@ -4794,6 +4783,9 @@
 	return addr;
 }
 
+#if defined(CONFIG_PREEMPT) && (defined(CONFIG_DEBUG_PREEMPT) || \
+				defined(CONFIG_PREEMPT_TRACER))
+
 void __kprobes add_preempt_count(int val)
 {
 #ifdef CONFIG_DEBUG_PREEMPT
@@ -7728,7 +7720,7 @@
 {
 	int group;
 
-	cpumask_and(mask, &per_cpu(cpu_sibling_map, cpu), cpu_map);
+	cpumask_and(mask, topology_thread_cpumask(cpu), cpu_map);
 	group = cpumask_first(mask);
 	if (sg)
 		*sg = &per_cpu(sched_group_core, group).sg;
@@ -7757,7 +7749,7 @@
 	cpumask_and(mask, cpu_coregroup_mask(cpu), cpu_map);
 	group = cpumask_first(mask);
 #elif defined(CONFIG_SCHED_SMT)
-	cpumask_and(mask, &per_cpu(cpu_sibling_map, cpu), cpu_map);
+	cpumask_and(mask, topology_thread_cpumask(cpu), cpu_map);
 	group = cpumask_first(mask);
 #else
 	group = cpu;
@@ -8100,7 +8092,7 @@
 		SD_INIT(sd, SIBLING);
 		set_domain_attribute(sd, attr);
 		cpumask_and(sched_domain_span(sd),
-			    &per_cpu(cpu_sibling_map, i), cpu_map);
+			    topology_thread_cpumask(i), cpu_map);
 		sd->parent = p;
 		p->child = sd;
 		cpu_to_cpu_group(i, cpu_map, &sd->groups, tmpmask);
@@ -8111,7 +8103,7 @@
 	/* Set up CPU (sibling) groups */
 	for_each_cpu(i, cpu_map) {
 		cpumask_and(this_sibling_map,
-			    &per_cpu(cpu_sibling_map, i), cpu_map);
+			    topology_thread_cpumask(i), cpu_map);
 		if (i != cpumask_first(this_sibling_map))
 			continue;
 
@@ -8787,6 +8779,9 @@
 #ifdef CONFIG_USER_SCHED
 	alloc_size *= 2;
 #endif
+#ifdef CONFIG_CPUMASK_OFFSTACK
+	alloc_size += num_possible_cpus() * cpumask_size();
+#endif
 	/*
 	 * As sched_init() is called before page_alloc is setup,
 	 * we use alloc_bootmem().
@@ -8824,6 +8819,12 @@
 		ptr += nr_cpu_ids * sizeof(void **);
 #endif /* CONFIG_USER_SCHED */
 #endif /* CONFIG_RT_GROUP_SCHED */
+#ifdef CONFIG_CPUMASK_OFFSTACK
+		for_each_possible_cpu(i) {
+			per_cpu(load_balance_tmpmask, i) = (void *)ptr;
+			ptr += cpumask_size();
+		}
+#endif /* CONFIG_CPUMASK_OFFSTACK */
 	}
 
 #ifdef CONFIG_SMP
diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c
index 390f332..819f17a 100644
--- a/kernel/sched_clock.c
+++ b/kernel/sched_clock.c
@@ -25,6 +25,7 @@
  * consistent between cpus (never more than 2 jiffies difference).
  */
 #include <linux/spinlock.h>
+#include <linux/hardirq.h>
 #include <linux/module.h>
 #include <linux/percpu.h>
 #include <linux/ktime.h>
@@ -154,6 +155,17 @@
 		return sched_clock();
 
 	scd = cpu_sdc(cpu);
+
+	/*
+	 * Normally this is not called in NMI context - but if it is,
+	 * trying to do any locking here is totally lethal.
+	 */
+	if (unlikely(in_nmi()))
+		return scd->clock;
+
+	if (unlikely(!sched_clock_running))
+		return 0ull;
+
 	WARN_ON_ONCE(!irqs_disabled());
 	now = sched_clock();
 
diff --git a/kernel/slow-work.c b/kernel/slow-work.c
new file mode 100644
index 0000000..cf2bc01
--- /dev/null
+++ b/kernel/slow-work.c
@@ -0,0 +1,640 @@
+/* Worker thread pool for slow items, such as filesystem lookups or mkdirs
+ *
+ * Copyright (C) 2008 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.
+ *
+ * See Documentation/slow-work.txt
+ */
+
+#include <linux/module.h>
+#include <linux/slow-work.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+#include <linux/wait.h>
+
+#define SLOW_WORK_CULL_TIMEOUT (5 * HZ)	/* cull threads 5s after running out of
+					 * things to do */
+#define SLOW_WORK_OOM_TIMEOUT (5 * HZ)	/* can't start new threads for 5s after
+					 * OOM */
+
+static void slow_work_cull_timeout(unsigned long);
+static void slow_work_oom_timeout(unsigned long);
+
+#ifdef CONFIG_SYSCTL
+static int slow_work_min_threads_sysctl(struct ctl_table *, int, struct file *,
+					void __user *, size_t *, loff_t *);
+
+static int slow_work_max_threads_sysctl(struct ctl_table *, int , struct file *,
+					void __user *, size_t *, loff_t *);
+#endif
+
+/*
+ * The pool of threads has at least min threads in it as long as someone is
+ * using the facility, and may have as many as max.
+ *
+ * A portion of the pool may be processing very slow operations.
+ */
+static unsigned slow_work_min_threads = 2;
+static unsigned slow_work_max_threads = 4;
+static unsigned vslow_work_proportion = 50; /* % of threads that may process
+					     * very slow work */
+
+#ifdef CONFIG_SYSCTL
+static const int slow_work_min_min_threads = 2;
+static int slow_work_max_max_threads = 255;
+static const int slow_work_min_vslow = 1;
+static const int slow_work_max_vslow = 99;
+
+ctl_table slow_work_sysctls[] = {
+	{
+		.ctl_name	= CTL_UNNUMBERED,
+		.procname	= "min-threads",
+		.data		= &slow_work_min_threads,
+		.maxlen		= sizeof(unsigned),
+		.mode		= 0644,
+		.proc_handler	= slow_work_min_threads_sysctl,
+		.extra1		= (void *) &slow_work_min_min_threads,
+		.extra2		= &slow_work_max_threads,
+	},
+	{
+		.ctl_name	= CTL_UNNUMBERED,
+		.procname	= "max-threads",
+		.data		= &slow_work_max_threads,
+		.maxlen		= sizeof(unsigned),
+		.mode		= 0644,
+		.proc_handler	= slow_work_max_threads_sysctl,
+		.extra1		= &slow_work_min_threads,
+		.extra2		= (void *) &slow_work_max_max_threads,
+	},
+	{
+		.ctl_name	= CTL_UNNUMBERED,
+		.procname	= "vslow-percentage",
+		.data		= &vslow_work_proportion,
+		.maxlen		= sizeof(unsigned),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.extra1		= (void *) &slow_work_min_vslow,
+		.extra2		= (void *) &slow_work_max_vslow,
+	},
+	{ .ctl_name = 0 }
+};
+#endif
+
+/*
+ * The active state of the thread pool
+ */
+static atomic_t slow_work_thread_count;
+static atomic_t vslow_work_executing_count;
+
+static bool slow_work_may_not_start_new_thread;
+static bool slow_work_cull; /* cull a thread due to lack of activity */
+static DEFINE_TIMER(slow_work_cull_timer, slow_work_cull_timeout, 0, 0);
+static DEFINE_TIMER(slow_work_oom_timer, slow_work_oom_timeout, 0, 0);
+static struct slow_work slow_work_new_thread; /* new thread starter */
+
+/*
+ * The queues of work items and the lock governing access to them.  These are
+ * shared between all the CPUs.  It doesn't make sense to have per-CPU queues
+ * as the number of threads bears no relation to the number of CPUs.
+ *
+ * There are two queues of work items: one for slow work items, and one for
+ * very slow work items.
+ */
+static LIST_HEAD(slow_work_queue);
+static LIST_HEAD(vslow_work_queue);
+static DEFINE_SPINLOCK(slow_work_queue_lock);
+
+/*
+ * The thread controls.  A variable used to signal to the threads that they
+ * should exit when the queue is empty, a waitqueue used by the threads to wait
+ * for signals, and a completion set by the last thread to exit.
+ */
+static bool slow_work_threads_should_exit;
+static DECLARE_WAIT_QUEUE_HEAD(slow_work_thread_wq);
+static DECLARE_COMPLETION(slow_work_last_thread_exited);
+
+/*
+ * The number of users of the thread pool and its lock.  Whilst this is zero we
+ * have no threads hanging around, and when this reaches zero, we wait for all
+ * active or queued work items to complete and kill all the threads we do have.
+ */
+static int slow_work_user_count;
+static DEFINE_MUTEX(slow_work_user_lock);
+
+/*
+ * Calculate the maximum number of active threads in the pool that are
+ * permitted to process very slow work items.
+ *
+ * The answer is rounded up to at least 1, but may not equal or exceed the
+ * maximum number of the threads in the pool.  This means we always have at
+ * least one thread that can process slow work items, and we always have at
+ * least one thread that won't get tied up doing so.
+ */
+static unsigned slow_work_calc_vsmax(void)
+{
+	unsigned vsmax;
+
+	vsmax = atomic_read(&slow_work_thread_count) * vslow_work_proportion;
+	vsmax /= 100;
+	vsmax = max(vsmax, 1U);
+	return min(vsmax, slow_work_max_threads - 1);
+}
+
+/*
+ * Attempt to execute stuff queued on a slow thread.  Return true if we managed
+ * it, false if there was nothing to do.
+ */
+static bool slow_work_execute(void)
+{
+	struct slow_work *work = NULL;
+	unsigned vsmax;
+	bool very_slow;
+
+	vsmax = slow_work_calc_vsmax();
+
+	/* see if we can schedule a new thread to be started if we're not
+	 * keeping up with the work */
+	if (!waitqueue_active(&slow_work_thread_wq) &&
+	    (!list_empty(&slow_work_queue) || !list_empty(&vslow_work_queue)) &&
+	    atomic_read(&slow_work_thread_count) < slow_work_max_threads &&
+	    !slow_work_may_not_start_new_thread)
+		slow_work_enqueue(&slow_work_new_thread);
+
+	/* find something to execute */
+	spin_lock_irq(&slow_work_queue_lock);
+	if (!list_empty(&vslow_work_queue) &&
+	    atomic_read(&vslow_work_executing_count) < vsmax) {
+		work = list_entry(vslow_work_queue.next,
+				  struct slow_work, link);
+		if (test_and_set_bit_lock(SLOW_WORK_EXECUTING, &work->flags))
+			BUG();
+		list_del_init(&work->link);
+		atomic_inc(&vslow_work_executing_count);
+		very_slow = true;
+	} else if (!list_empty(&slow_work_queue)) {
+		work = list_entry(slow_work_queue.next,
+				  struct slow_work, link);
+		if (test_and_set_bit_lock(SLOW_WORK_EXECUTING, &work->flags))
+			BUG();
+		list_del_init(&work->link);
+		very_slow = false;
+	} else {
+		very_slow = false; /* avoid the compiler warning */
+	}
+	spin_unlock_irq(&slow_work_queue_lock);
+
+	if (!work)
+		return false;
+
+	if (!test_and_clear_bit(SLOW_WORK_PENDING, &work->flags))
+		BUG();
+
+	work->ops->execute(work);
+
+	if (very_slow)
+		atomic_dec(&vslow_work_executing_count);
+	clear_bit_unlock(SLOW_WORK_EXECUTING, &work->flags);
+
+	/* if someone tried to enqueue the item whilst we were executing it,
+	 * then it'll be left unenqueued to avoid multiple threads trying to
+	 * execute it simultaneously
+	 *
+	 * there is, however, a race between us testing the pending flag and
+	 * getting the spinlock, and between the enqueuer setting the pending
+	 * flag and getting the spinlock, so we use a deferral bit to tell us
+	 * if the enqueuer got there first
+	 */
+	if (test_bit(SLOW_WORK_PENDING, &work->flags)) {
+		spin_lock_irq(&slow_work_queue_lock);
+
+		if (!test_bit(SLOW_WORK_EXECUTING, &work->flags) &&
+		    test_and_clear_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags))
+			goto auto_requeue;
+
+		spin_unlock_irq(&slow_work_queue_lock);
+	}
+
+	work->ops->put_ref(work);
+	return true;
+
+auto_requeue:
+	/* we must complete the enqueue operation
+	 * - we transfer our ref on the item back to the appropriate queue
+	 * - don't wake another thread up as we're awake already
+	 */
+	if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags))
+		list_add_tail(&work->link, &vslow_work_queue);
+	else
+		list_add_tail(&work->link, &slow_work_queue);
+	spin_unlock_irq(&slow_work_queue_lock);
+	return true;
+}
+
+/**
+ * slow_work_enqueue - Schedule a slow work item for processing
+ * @work: The work item to queue
+ *
+ * Schedule a slow work item for processing.  If the item is already undergoing
+ * execution, this guarantees not to re-enter the execution routine until the
+ * first execution finishes.
+ *
+ * The item is pinned by this function as it retains a reference to it, managed
+ * through the item operations.  The item is unpinned once it has been
+ * executed.
+ *
+ * An item may hog the thread that is running it for a relatively large amount
+ * of time, sufficient, for example, to perform several lookup, mkdir, create
+ * and setxattr operations.  It may sleep on I/O and may sleep to obtain locks.
+ *
+ * Conversely, if a number of items are awaiting processing, it may take some
+ * time before any given item is given attention.  The number of threads in the
+ * pool may be increased to deal with demand, but only up to a limit.
+ *
+ * If SLOW_WORK_VERY_SLOW is set on the work item, then it will be placed in
+ * the very slow queue, from which only a portion of the threads will be
+ * allowed to pick items to execute.  This ensures that very slow items won't
+ * overly block ones that are just ordinarily slow.
+ *
+ * Returns 0 if successful, -EAGAIN if not.
+ */
+int slow_work_enqueue(struct slow_work *work)
+{
+	unsigned long flags;
+
+	BUG_ON(slow_work_user_count <= 0);
+	BUG_ON(!work);
+	BUG_ON(!work->ops);
+	BUG_ON(!work->ops->get_ref);
+
+	/* when honouring an enqueue request, we only promise that we will run
+	 * the work function in the future; we do not promise to run it once
+	 * per enqueue request
+	 *
+	 * we use the PENDING bit to merge together repeat requests without
+	 * having to disable IRQs and take the spinlock, whilst still
+	 * maintaining our promise
+	 */
+	if (!test_and_set_bit_lock(SLOW_WORK_PENDING, &work->flags)) {
+		spin_lock_irqsave(&slow_work_queue_lock, flags);
+
+		/* we promise that we will not attempt to execute the work
+		 * function in more than one thread simultaneously
+		 *
+		 * this, however, leaves us with a problem if we're asked to
+		 * enqueue the work whilst someone is executing the work
+		 * function as simply queueing the work immediately means that
+		 * another thread may try executing it whilst it is already
+		 * under execution
+		 *
+		 * to deal with this, we set the ENQ_DEFERRED bit instead of
+		 * enqueueing, and the thread currently executing the work
+		 * function will enqueue the work item when the work function
+		 * returns and it has cleared the EXECUTING bit
+		 */
+		if (test_bit(SLOW_WORK_EXECUTING, &work->flags)) {
+			set_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags);
+		} else {
+			if (work->ops->get_ref(work) < 0)
+				goto cant_get_ref;
+			if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags))
+				list_add_tail(&work->link, &vslow_work_queue);
+			else
+				list_add_tail(&work->link, &slow_work_queue);
+			wake_up(&slow_work_thread_wq);
+		}
+
+		spin_unlock_irqrestore(&slow_work_queue_lock, flags);
+	}
+	return 0;
+
+cant_get_ref:
+	spin_unlock_irqrestore(&slow_work_queue_lock, flags);
+	return -EAGAIN;
+}
+EXPORT_SYMBOL(slow_work_enqueue);
+
+/*
+ * Worker thread culling algorithm
+ */
+static bool slow_work_cull_thread(void)
+{
+	unsigned long flags;
+	bool do_cull = false;
+
+	spin_lock_irqsave(&slow_work_queue_lock, flags);
+
+	if (slow_work_cull) {
+		slow_work_cull = false;
+
+		if (list_empty(&slow_work_queue) &&
+		    list_empty(&vslow_work_queue) &&
+		    atomic_read(&slow_work_thread_count) >
+		    slow_work_min_threads) {
+			mod_timer(&slow_work_cull_timer,
+				  jiffies + SLOW_WORK_CULL_TIMEOUT);
+			do_cull = true;
+		}
+	}
+
+	spin_unlock_irqrestore(&slow_work_queue_lock, flags);
+	return do_cull;
+}
+
+/*
+ * Determine if there is slow work available for dispatch
+ */
+static inline bool slow_work_available(int vsmax)
+{
+	return !list_empty(&slow_work_queue) ||
+		(!list_empty(&vslow_work_queue) &&
+		 atomic_read(&vslow_work_executing_count) < vsmax);
+}
+
+/*
+ * Worker thread dispatcher
+ */
+static int slow_work_thread(void *_data)
+{
+	int vsmax;
+
+	DEFINE_WAIT(wait);
+
+	set_freezable();
+	set_user_nice(current, -5);
+
+	for (;;) {
+		vsmax = vslow_work_proportion;
+		vsmax *= atomic_read(&slow_work_thread_count);
+		vsmax /= 100;
+
+		prepare_to_wait(&slow_work_thread_wq, &wait,
+				TASK_INTERRUPTIBLE);
+		if (!freezing(current) &&
+		    !slow_work_threads_should_exit &&
+		    !slow_work_available(vsmax) &&
+		    !slow_work_cull)
+			schedule();
+		finish_wait(&slow_work_thread_wq, &wait);
+
+		try_to_freeze();
+
+		vsmax = vslow_work_proportion;
+		vsmax *= atomic_read(&slow_work_thread_count);
+		vsmax /= 100;
+
+		if (slow_work_available(vsmax) && slow_work_execute()) {
+			cond_resched();
+			if (list_empty(&slow_work_queue) &&
+			    list_empty(&vslow_work_queue) &&
+			    atomic_read(&slow_work_thread_count) >
+			    slow_work_min_threads)
+				mod_timer(&slow_work_cull_timer,
+					  jiffies + SLOW_WORK_CULL_TIMEOUT);
+			continue;
+		}
+
+		if (slow_work_threads_should_exit)
+			break;
+
+		if (slow_work_cull && slow_work_cull_thread())
+			break;
+	}
+
+	if (atomic_dec_and_test(&slow_work_thread_count))
+		complete_and_exit(&slow_work_last_thread_exited, 0);
+	return 0;
+}
+
+/*
+ * Handle thread cull timer expiration
+ */
+static void slow_work_cull_timeout(unsigned long data)
+{
+	slow_work_cull = true;
+	wake_up(&slow_work_thread_wq);
+}
+
+/*
+ * Get a reference on slow work thread starter
+ */
+static int slow_work_new_thread_get_ref(struct slow_work *work)
+{
+	return 0;
+}
+
+/*
+ * Drop a reference on slow work thread starter
+ */
+static void slow_work_new_thread_put_ref(struct slow_work *work)
+{
+}
+
+/*
+ * Start a new slow work thread
+ */
+static void slow_work_new_thread_execute(struct slow_work *work)
+{
+	struct task_struct *p;
+
+	if (slow_work_threads_should_exit)
+		return;
+
+	if (atomic_read(&slow_work_thread_count) >= slow_work_max_threads)
+		return;
+
+	if (!mutex_trylock(&slow_work_user_lock))
+		return;
+
+	slow_work_may_not_start_new_thread = true;
+	atomic_inc(&slow_work_thread_count);
+	p = kthread_run(slow_work_thread, NULL, "kslowd");
+	if (IS_ERR(p)) {
+		printk(KERN_DEBUG "Slow work thread pool: OOM\n");
+		if (atomic_dec_and_test(&slow_work_thread_count))
+			BUG(); /* we're running on a slow work thread... */
+		mod_timer(&slow_work_oom_timer,
+			  jiffies + SLOW_WORK_OOM_TIMEOUT);
+	} else {
+		/* ratelimit the starting of new threads */
+		mod_timer(&slow_work_oom_timer, jiffies + 1);
+	}
+
+	mutex_unlock(&slow_work_user_lock);
+}
+
+static const struct slow_work_ops slow_work_new_thread_ops = {
+	.get_ref	= slow_work_new_thread_get_ref,
+	.put_ref	= slow_work_new_thread_put_ref,
+	.execute	= slow_work_new_thread_execute,
+};
+
+/*
+ * post-OOM new thread start suppression expiration
+ */
+static void slow_work_oom_timeout(unsigned long data)
+{
+	slow_work_may_not_start_new_thread = false;
+}
+
+#ifdef CONFIG_SYSCTL
+/*
+ * Handle adjustment of the minimum number of threads
+ */
+static int slow_work_min_threads_sysctl(struct ctl_table *table, int write,
+					struct file *filp, void __user *buffer,
+					size_t *lenp, loff_t *ppos)
+{
+	int ret = proc_dointvec_minmax(table, write, filp, buffer, lenp, ppos);
+	int n;
+
+	if (ret == 0) {
+		mutex_lock(&slow_work_user_lock);
+		if (slow_work_user_count > 0) {
+			/* see if we need to start or stop threads */
+			n = atomic_read(&slow_work_thread_count) -
+				slow_work_min_threads;
+
+			if (n < 0 && !slow_work_may_not_start_new_thread)
+				slow_work_enqueue(&slow_work_new_thread);
+			else if (n > 0)
+				mod_timer(&slow_work_cull_timer,
+					  jiffies + SLOW_WORK_CULL_TIMEOUT);
+		}
+		mutex_unlock(&slow_work_user_lock);
+	}
+
+	return ret;
+}
+
+/*
+ * Handle adjustment of the maximum number of threads
+ */
+static int slow_work_max_threads_sysctl(struct ctl_table *table, int write,
+					struct file *filp, void __user *buffer,
+					size_t *lenp, loff_t *ppos)
+{
+	int ret = proc_dointvec_minmax(table, write, filp, buffer, lenp, ppos);
+	int n;
+
+	if (ret == 0) {
+		mutex_lock(&slow_work_user_lock);
+		if (slow_work_user_count > 0) {
+			/* see if we need to stop threads */
+			n = slow_work_max_threads -
+				atomic_read(&slow_work_thread_count);
+
+			if (n < 0)
+				mod_timer(&slow_work_cull_timer,
+					  jiffies + SLOW_WORK_CULL_TIMEOUT);
+		}
+		mutex_unlock(&slow_work_user_lock);
+	}
+
+	return ret;
+}
+#endif /* CONFIG_SYSCTL */
+
+/**
+ * slow_work_register_user - Register a user of the facility
+ *
+ * Register a user of the facility, starting up the initial threads if there
+ * aren't any other users at this point.  This will return 0 if successful, or
+ * an error if not.
+ */
+int slow_work_register_user(void)
+{
+	struct task_struct *p;
+	int loop;
+
+	mutex_lock(&slow_work_user_lock);
+
+	if (slow_work_user_count == 0) {
+		printk(KERN_NOTICE "Slow work thread pool: Starting up\n");
+		init_completion(&slow_work_last_thread_exited);
+
+		slow_work_threads_should_exit = false;
+		slow_work_init(&slow_work_new_thread,
+			       &slow_work_new_thread_ops);
+		slow_work_may_not_start_new_thread = false;
+		slow_work_cull = false;
+
+		/* start the minimum number of threads */
+		for (loop = 0; loop < slow_work_min_threads; loop++) {
+			atomic_inc(&slow_work_thread_count);
+			p = kthread_run(slow_work_thread, NULL, "kslowd");
+			if (IS_ERR(p))
+				goto error;
+		}
+		printk(KERN_NOTICE "Slow work thread pool: Ready\n");
+	}
+
+	slow_work_user_count++;
+	mutex_unlock(&slow_work_user_lock);
+	return 0;
+
+error:
+	if (atomic_dec_and_test(&slow_work_thread_count))
+		complete(&slow_work_last_thread_exited);
+	if (loop > 0) {
+		printk(KERN_ERR "Slow work thread pool:"
+		       " Aborting startup on ENOMEM\n");
+		slow_work_threads_should_exit = true;
+		wake_up_all(&slow_work_thread_wq);
+		wait_for_completion(&slow_work_last_thread_exited);
+		printk(KERN_ERR "Slow work thread pool: Aborted\n");
+	}
+	mutex_unlock(&slow_work_user_lock);
+	return PTR_ERR(p);
+}
+EXPORT_SYMBOL(slow_work_register_user);
+
+/**
+ * slow_work_unregister_user - Unregister a user of the facility
+ *
+ * Unregister a user of the facility, killing all the threads if this was the
+ * last one.
+ */
+void slow_work_unregister_user(void)
+{
+	mutex_lock(&slow_work_user_lock);
+
+	BUG_ON(slow_work_user_count <= 0);
+
+	slow_work_user_count--;
+	if (slow_work_user_count == 0) {
+		printk(KERN_NOTICE "Slow work thread pool: Shutting down\n");
+		slow_work_threads_should_exit = true;
+		wake_up_all(&slow_work_thread_wq);
+		wait_for_completion(&slow_work_last_thread_exited);
+		printk(KERN_NOTICE "Slow work thread pool:"
+		       " Shut down complete\n");
+	}
+
+	del_timer_sync(&slow_work_cull_timer);
+
+	mutex_unlock(&slow_work_user_lock);
+}
+EXPORT_SYMBOL(slow_work_unregister_user);
+
+/*
+ * Initialise the slow work facility
+ */
+static int __init init_slow_work(void)
+{
+	unsigned nr_cpus = num_possible_cpus();
+
+	if (slow_work_max_threads < nr_cpus)
+		slow_work_max_threads = nr_cpus;
+#ifdef CONFIG_SYSCTL
+	if (slow_work_max_max_threads < nr_cpus * 2)
+		slow_work_max_max_threads = nr_cpus * 2;
+#endif
+	return 0;
+}
+
+subsys_initcall(init_slow_work);
diff --git a/kernel/smp.c b/kernel/smp.c
index bbedbb7..858baac 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -2,40 +2,82 @@
  * Generic helpers for smp ipi calls
  *
  * (C) Jens Axboe <jens.axboe@oracle.com> 2008
- *
  */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/percpu.h>
 #include <linux/rcupdate.h>
 #include <linux/rculist.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/percpu.h>
+#include <linux/init.h>
 #include <linux/smp.h>
+#include <linux/cpu.h>
 
 static DEFINE_PER_CPU(struct call_single_queue, call_single_queue);
-static LIST_HEAD(call_function_queue);
-__cacheline_aligned_in_smp DEFINE_SPINLOCK(call_function_lock);
+
+static struct {
+	struct list_head	queue;
+	spinlock_t		lock;
+} call_function __cacheline_aligned_in_smp =
+	{
+		.queue		= LIST_HEAD_INIT(call_function.queue),
+		.lock		= __SPIN_LOCK_UNLOCKED(call_function.lock),
+	};
 
 enum {
-	CSD_FLAG_WAIT		= 0x01,
-	CSD_FLAG_ALLOC		= 0x02,
-	CSD_FLAG_LOCK		= 0x04,
+	CSD_FLAG_LOCK		= 0x01,
 };
 
 struct call_function_data {
-	struct call_single_data csd;
-	spinlock_t lock;
-	unsigned int refs;
-	struct rcu_head rcu_head;
-	unsigned long cpumask_bits[];
+	struct call_single_data	csd;
+	spinlock_t		lock;
+	unsigned int		refs;
+	cpumask_var_t		cpumask;
 };
 
 struct call_single_queue {
-	struct list_head list;
-	spinlock_t lock;
+	struct list_head	list;
+	spinlock_t		lock;
+};
+
+static DEFINE_PER_CPU(struct call_function_data, cfd_data) = {
+	.lock			= __SPIN_LOCK_UNLOCKED(cfd_data.lock),
+};
+
+static int
+hotplug_cfd(struct notifier_block *nfb, unsigned long action, void *hcpu)
+{
+	long cpu = (long)hcpu;
+	struct call_function_data *cfd = &per_cpu(cfd_data, cpu);
+
+	switch (action) {
+	case CPU_UP_PREPARE:
+	case CPU_UP_PREPARE_FROZEN:
+		if (!alloc_cpumask_var_node(&cfd->cpumask, GFP_KERNEL,
+				cpu_to_node(cpu)))
+			return NOTIFY_BAD;
+		break;
+
+#ifdef CONFIG_CPU_HOTPLUG
+	case CPU_UP_CANCELED:
+	case CPU_UP_CANCELED_FROZEN:
+
+	case CPU_DEAD:
+	case CPU_DEAD_FROZEN:
+		free_cpumask_var(cfd->cpumask);
+		break;
+#endif
+	};
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block __cpuinitdata hotplug_cfd_notifier = {
+	.notifier_call		= hotplug_cfd,
 };
 
 static int __cpuinit init_call_single_data(void)
 {
+	void *cpu = (void *)(long)smp_processor_id();
 	int i;
 
 	for_each_possible_cpu(i) {
@@ -44,29 +86,63 @@
 		spin_lock_init(&q->lock);
 		INIT_LIST_HEAD(&q->list);
 	}
+
+	hotplug_cfd(&hotplug_cfd_notifier, CPU_UP_PREPARE, cpu);
+	register_cpu_notifier(&hotplug_cfd_notifier);
+
 	return 0;
 }
 early_initcall(init_call_single_data);
 
-static void csd_flag_wait(struct call_single_data *data)
+/*
+ * csd_lock/csd_unlock used to serialize access to per-cpu csd resources
+ *
+ * For non-synchronous ipi calls the csd can still be in use by the
+ * previous function call. For multi-cpu calls its even more interesting
+ * as we'll have to ensure no other cpu is observing our csd.
+ */
+static void csd_lock_wait(struct call_single_data *data)
 {
-	/* Wait for response */
-	do {
-		if (!(data->flags & CSD_FLAG_WAIT))
-			break;
+	while (data->flags & CSD_FLAG_LOCK)
 		cpu_relax();
-	} while (1);
+}
+
+static void csd_lock(struct call_single_data *data)
+{
+	csd_lock_wait(data);
+	data->flags = CSD_FLAG_LOCK;
+
+	/*
+	 * prevent CPU from reordering the above assignment
+	 * to ->flags with any subsequent assignments to other
+	 * fields of the specified call_single_data structure:
+	 */
+	smp_mb();
+}
+
+static void csd_unlock(struct call_single_data *data)
+{
+	WARN_ON(!(data->flags & CSD_FLAG_LOCK));
+
+	/*
+	 * ensure we're all done before releasing data:
+	 */
+	smp_mb();
+
+	data->flags &= ~CSD_FLAG_LOCK;
 }
 
 /*
- * Insert a previously allocated call_single_data element for execution
- * on the given CPU. data must already have ->func, ->info, and ->flags set.
+ * Insert a previously allocated call_single_data element
+ * for execution on the given CPU. data must already have
+ * ->func, ->info, and ->flags set.
  */
-static void generic_exec_single(int cpu, struct call_single_data *data)
+static
+void generic_exec_single(int cpu, struct call_single_data *data, int wait)
 {
 	struct call_single_queue *dst = &per_cpu(call_single_queue, cpu);
-	int wait = data->flags & CSD_FLAG_WAIT, ipi;
 	unsigned long flags;
+	int ipi;
 
 	spin_lock_irqsave(&dst->lock, flags);
 	ipi = list_empty(&dst->list);
@@ -74,24 +150,21 @@
 	spin_unlock_irqrestore(&dst->lock, flags);
 
 	/*
-	 * Make the list addition visible before sending the ipi.
+	 * The list addition should be visible before sending the IPI
+	 * handler locks the list to pull the entry off it because of
+	 * normal cache coherency rules implied by spinlocks.
+	 *
+	 * If IPIs can go out of order to the cache coherency protocol
+	 * in an architecture, sufficient synchronisation should be added
+	 * to arch code to make it appear to obey cache coherency WRT
+	 * locking and barrier primitives. Generic code isn't really
+	 * equipped to do the right thing...
 	 */
-	smp_mb();
-
 	if (ipi)
 		arch_send_call_function_single_ipi(cpu);
 
 	if (wait)
-		csd_flag_wait(data);
-}
-
-static void rcu_free_call_data(struct rcu_head *head)
-{
-	struct call_function_data *data;
-
-	data = container_of(head, struct call_function_data, rcu_head);
-
-	kfree(data);
+		csd_lock_wait(data);
 }
 
 /*
@@ -104,99 +177,83 @@
 	int cpu = get_cpu();
 
 	/*
-	 * It's ok to use list_for_each_rcu() here even though we may delete
-	 * 'pos', since list_del_rcu() doesn't clear ->next
+	 * Ensure entry is visible on call_function_queue after we have
+	 * entered the IPI. See comment in smp_call_function_many.
+	 * If we don't have this, then we may miss an entry on the list
+	 * and never get another IPI to process it.
 	 */
-	rcu_read_lock();
-	list_for_each_entry_rcu(data, &call_function_queue, csd.list) {
+	smp_mb();
+
+	/*
+	 * It's ok to use list_for_each_rcu() here even though we may
+	 * delete 'pos', since list_del_rcu() doesn't clear ->next
+	 */
+	list_for_each_entry_rcu(data, &call_function.queue, csd.list) {
 		int refs;
 
-		if (!cpumask_test_cpu(cpu, to_cpumask(data->cpumask_bits)))
+		spin_lock(&data->lock);
+		if (!cpumask_test_cpu(cpu, data->cpumask)) {
+			spin_unlock(&data->lock);
 			continue;
+		}
+		cpumask_clear_cpu(cpu, data->cpumask);
+		spin_unlock(&data->lock);
 
 		data->csd.func(data->csd.info);
 
 		spin_lock(&data->lock);
-		cpumask_clear_cpu(cpu, to_cpumask(data->cpumask_bits));
 		WARN_ON(data->refs == 0);
-		data->refs--;
-		refs = data->refs;
+		refs = --data->refs;
+		if (!refs) {
+			spin_lock(&call_function.lock);
+			list_del_rcu(&data->csd.list);
+			spin_unlock(&call_function.lock);
+		}
 		spin_unlock(&data->lock);
 
 		if (refs)
 			continue;
 
-		spin_lock(&call_function_lock);
-		list_del_rcu(&data->csd.list);
-		spin_unlock(&call_function_lock);
-
-		if (data->csd.flags & CSD_FLAG_WAIT) {
-			/*
-			 * serialize stores to data with the flag clear
-			 * and wakeup
-			 */
-			smp_wmb();
-			data->csd.flags &= ~CSD_FLAG_WAIT;
-		}
-		if (data->csd.flags & CSD_FLAG_ALLOC)
-			call_rcu(&data->rcu_head, rcu_free_call_data);
+		csd_unlock(&data->csd);
 	}
-	rcu_read_unlock();
 
 	put_cpu();
 }
 
 /*
- * Invoked by arch to handle an IPI for call function single. Must be called
- * from the arch with interrupts disabled.
+ * Invoked by arch to handle an IPI for call function single. Must be
+ * called from the arch with interrupts disabled.
  */
 void generic_smp_call_function_single_interrupt(void)
 {
 	struct call_single_queue *q = &__get_cpu_var(call_single_queue);
+	unsigned int data_flags;
 	LIST_HEAD(list);
 
-	/*
-	 * Need to see other stores to list head for checking whether
-	 * list is empty without holding q->lock
-	 */
-	smp_read_barrier_depends();
-	while (!list_empty(&q->list)) {
-		unsigned int data_flags;
+	spin_lock(&q->lock);
+	list_replace_init(&q->list, &list);
+	spin_unlock(&q->lock);
 
-		spin_lock(&q->lock);
-		list_replace_init(&q->list, &list);
-		spin_unlock(&q->lock);
+	while (!list_empty(&list)) {
+		struct call_single_data *data;
 
-		while (!list_empty(&list)) {
-			struct call_single_data *data;
+		data = list_entry(list.next, struct call_single_data, list);
+		list_del(&data->list);
 
-			data = list_entry(list.next, struct call_single_data,
-						list);
-			list_del(&data->list);
-
-			/*
-			 * 'data' can be invalid after this call if
-			 * flags == 0 (when called through
-			 * generic_exec_single(), so save them away before
-			 * making the call.
-			 */
-			data_flags = data->flags;
-
-			data->func(data->info);
-
-			if (data_flags & CSD_FLAG_WAIT) {
-				smp_wmb();
-				data->flags &= ~CSD_FLAG_WAIT;
-			} else if (data_flags & CSD_FLAG_LOCK) {
-				smp_wmb();
-				data->flags &= ~CSD_FLAG_LOCK;
-			} else if (data_flags & CSD_FLAG_ALLOC)
-				kfree(data);
-		}
 		/*
-		 * See comment on outer loop
+		 * 'data' can be invalid after this call if flags == 0
+		 * (when called through generic_exec_single()),
+		 * so save them away before making the call:
 		 */
-		smp_read_barrier_depends();
+		data_flags = data->flags;
+
+		data->func(data->info);
+
+		/*
+		 * Unlocked CSDs are valid through generic_exec_single():
+		 */
+		if (data_flags & CSD_FLAG_LOCK)
+			csd_unlock(data);
 	}
 }
 
@@ -215,65 +272,45 @@
 int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
 			     int wait)
 {
-	struct call_single_data d;
+	struct call_single_data d = {
+		.flags = 0,
+	};
 	unsigned long flags;
-	/* prevent preemption and reschedule on another processor,
-	   as well as CPU removal */
-	int me = get_cpu();
+	int this_cpu;
 	int err = 0;
 
-	/* Can deadlock when called with interrupts disabled */
-	WARN_ON(irqs_disabled());
+	/*
+	 * prevent preemption and reschedule on another processor,
+	 * as well as CPU removal
+	 */
+	this_cpu = get_cpu();
 
-	if (cpu == me) {
+	/* Can deadlock when called with interrupts disabled */
+	WARN_ON_ONCE(irqs_disabled() && !oops_in_progress);
+
+	if (cpu == this_cpu) {
 		local_irq_save(flags);
 		func(info);
 		local_irq_restore(flags);
-	} else if ((unsigned)cpu < nr_cpu_ids && cpu_online(cpu)) {
-		struct call_single_data *data;
-
-		if (!wait) {
-			/*
-			 * We are calling a function on a single CPU
-			 * and we are not going to wait for it to finish.
-			 * We first try to allocate the data, but if we
-			 * fail, we fall back to use a per cpu data to pass
-			 * the information to that CPU. Since all callers
-			 * of this code will use the same data, we must
-			 * synchronize the callers to prevent a new caller
-			 * from corrupting the data before the callee
-			 * can access it.
-			 *
-			 * The CSD_FLAG_LOCK is used to let us know when
-			 * the IPI handler is done with the data.
-			 * The first caller will set it, and the callee
-			 * will clear it. The next caller must wait for
-			 * it to clear before we set it again. This
-			 * will make sure the callee is done with the
-			 * data before a new caller will use it.
-			 */
-			data = kmalloc(sizeof(*data), GFP_ATOMIC);
-			if (data)
-				data->flags = CSD_FLAG_ALLOC;
-			else {
-				data = &per_cpu(csd_data, me);
-				while (data->flags & CSD_FLAG_LOCK)
-					cpu_relax();
-				data->flags = CSD_FLAG_LOCK;
-			}
-		} else {
-			data = &d;
-			data->flags = CSD_FLAG_WAIT;
-		}
-
-		data->func = func;
-		data->info = info;
-		generic_exec_single(cpu, data);
 	} else {
-		err = -ENXIO;	/* CPU not online */
+		if ((unsigned)cpu < nr_cpu_ids && cpu_online(cpu)) {
+			struct call_single_data *data = &d;
+
+			if (!wait)
+				data = &__get_cpu_var(csd_data);
+
+			csd_lock(data);
+
+			data->func = func;
+			data->info = info;
+			generic_exec_single(cpu, data, wait);
+		} else {
+			err = -ENXIO;	/* CPU not online */
+		}
 	}
 
 	put_cpu();
+
 	return err;
 }
 EXPORT_SYMBOL(smp_call_function_single);
@@ -283,23 +320,26 @@
  * @cpu: The CPU to run on.
  * @data: Pre-allocated and setup data structure
  *
- * Like smp_call_function_single(), but allow caller to pass in a pre-allocated
- * data structure. Useful for embedding @data inside other structures, for
- * instance.
- *
+ * Like smp_call_function_single(), but allow caller to pass in a
+ * pre-allocated data structure. Useful for embedding @data inside
+ * other structures, for instance.
  */
-void __smp_call_function_single(int cpu, struct call_single_data *data)
+void __smp_call_function_single(int cpu, struct call_single_data *data,
+				int wait)
 {
-	/* Can deadlock when called with interrupts disabled */
-	WARN_ON((data->flags & CSD_FLAG_WAIT) && irqs_disabled());
+	csd_lock(data);
 
-	generic_exec_single(cpu, data);
+	/* Can deadlock when called with interrupts disabled */
+	WARN_ON_ONCE(wait && irqs_disabled() && !oops_in_progress);
+
+	generic_exec_single(cpu, data, wait);
 }
 
-/* FIXME: Shim for archs using old arch_send_call_function_ipi API. */
+/* Deprecated: shim for archs using old arch_send_call_function_ipi API. */
+
 #ifndef arch_send_call_function_ipi_mask
-#define arch_send_call_function_ipi_mask(maskp) \
-	arch_send_call_function_ipi(*(maskp))
+# define arch_send_call_function_ipi_mask(maskp) \
+	 arch_send_call_function_ipi(*(maskp))
 #endif
 
 /**
@@ -307,7 +347,8 @@
  * @mask: The set of cpus to run on (only runs on online subset).
  * @func: The function to run. This must be fast and non-blocking.
  * @info: An arbitrary pointer to pass to the function.
- * @wait: If true, wait (atomically) until function has completed on other CPUs.
+ * @wait: If true, wait (atomically) until function has completed
+ *        on other CPUs.
  *
  * If @wait is true, then returns once @func has returned. Note that @wait
  * will be implicitly turned on in case of allocation failures, since
@@ -318,27 +359,27 @@
  * must be disabled when calling this function.
  */
 void smp_call_function_many(const struct cpumask *mask,
-			    void (*func)(void *), void *info,
-			    bool wait)
+			    void (*func)(void *), void *info, bool wait)
 {
 	struct call_function_data *data;
 	unsigned long flags;
-	int cpu, next_cpu;
+	int cpu, next_cpu, this_cpu = smp_processor_id();
 
 	/* Can deadlock when called with interrupts disabled */
-	WARN_ON(irqs_disabled());
+	WARN_ON_ONCE(irqs_disabled() && !oops_in_progress);
 
-	/* So, what's a CPU they want?  Ignoring this one. */
+	/* So, what's a CPU they want? Ignoring this one. */
 	cpu = cpumask_first_and(mask, cpu_online_mask);
-	if (cpu == smp_processor_id())
+	if (cpu == this_cpu)
 		cpu = cpumask_next_and(cpu, mask, cpu_online_mask);
+
 	/* No online cpus?  We're done. */
 	if (cpu >= nr_cpu_ids)
 		return;
 
 	/* Do we have another CPU which isn't us? */
 	next_cpu = cpumask_next_and(cpu, mask, cpu_online_mask);
-	if (next_cpu == smp_processor_id())
+	if (next_cpu == this_cpu)
 		next_cpu = cpumask_next_and(next_cpu, mask, cpu_online_mask);
 
 	/* Fastpath: do that cpu by itself. */
@@ -347,43 +388,40 @@
 		return;
 	}
 
-	data = kmalloc(sizeof(*data) + cpumask_size(), GFP_ATOMIC);
-	if (unlikely(!data)) {
-		/* Slow path. */
-		for_each_online_cpu(cpu) {
-			if (cpu == smp_processor_id())
-				continue;
-			if (cpumask_test_cpu(cpu, mask))
-				smp_call_function_single(cpu, func, info, wait);
-		}
-		return;
-	}
+	data = &__get_cpu_var(cfd_data);
+	csd_lock(&data->csd);
 
-	spin_lock_init(&data->lock);
-	data->csd.flags = CSD_FLAG_ALLOC;
-	if (wait)
-		data->csd.flags |= CSD_FLAG_WAIT;
+	spin_lock_irqsave(&data->lock, flags);
 	data->csd.func = func;
 	data->csd.info = info;
-	cpumask_and(to_cpumask(data->cpumask_bits), mask, cpu_online_mask);
-	cpumask_clear_cpu(smp_processor_id(), to_cpumask(data->cpumask_bits));
-	data->refs = cpumask_weight(to_cpumask(data->cpumask_bits));
+	cpumask_and(data->cpumask, mask, cpu_online_mask);
+	cpumask_clear_cpu(this_cpu, data->cpumask);
+	data->refs = cpumask_weight(data->cpumask);
 
-	spin_lock_irqsave(&call_function_lock, flags);
-	list_add_tail_rcu(&data->csd.list, &call_function_queue);
-	spin_unlock_irqrestore(&call_function_lock, flags);
+	spin_lock(&call_function.lock);
+	/*
+	 * Place entry at the _HEAD_ of the list, so that any cpu still
+	 * observing the entry in generic_smp_call_function_interrupt()
+	 * will not miss any other list entries:
+	 */
+	list_add_rcu(&data->csd.list, &call_function.queue);
+	spin_unlock(&call_function.lock);
+
+	spin_unlock_irqrestore(&data->lock, flags);
 
 	/*
 	 * Make the list addition visible before sending the ipi.
+	 * (IPIs must obey or appear to obey normal Linux cache
+	 * coherency rules -- see comment in generic_exec_single).
 	 */
 	smp_mb();
 
 	/* Send a message to all CPUs in the map */
-	arch_send_call_function_ipi_mask(to_cpumask(data->cpumask_bits));
+	arch_send_call_function_ipi_mask(data->cpumask);
 
-	/* optionally wait for the CPUs to complete */
+	/* Optionally wait for the CPUs to complete */
 	if (wait)
-		csd_flag_wait(&data->csd);
+		csd_lock_wait(&data->csd);
 }
 EXPORT_SYMBOL(smp_call_function_many);
 
@@ -391,7 +429,8 @@
  * smp_call_function(): Run a function on all other CPUs.
  * @func: The function to run. This must be fast and non-blocking.
  * @info: An arbitrary pointer to pass to the function.
- * @wait: If true, wait (atomically) until function has completed on other CPUs.
+ * @wait: If true, wait (atomically) until function has completed
+ *        on other CPUs.
  *
  * Returns 0.
  *
@@ -407,26 +446,27 @@
 	preempt_disable();
 	smp_call_function_many(cpu_online_mask, func, info, wait);
 	preempt_enable();
+
 	return 0;
 }
 EXPORT_SYMBOL(smp_call_function);
 
 void ipi_call_lock(void)
 {
-	spin_lock(&call_function_lock);
+	spin_lock(&call_function.lock);
 }
 
 void ipi_call_unlock(void)
 {
-	spin_unlock(&call_function_lock);
+	spin_unlock(&call_function.lock);
 }
 
 void ipi_call_lock_irq(void)
 {
-	spin_lock_irq(&call_function_lock);
+	spin_lock_irq(&call_function.lock);
 }
 
 void ipi_call_unlock_irq(void)
 {
-	spin_unlock_irq(&call_function_lock);
+	spin_unlock_irq(&call_function.lock);
 }
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 57d3f67..d105a82 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -21,8 +21,10 @@
 #include <linux/freezer.h>
 #include <linux/kthread.h>
 #include <linux/rcupdate.h>
+#include <linux/ftrace.h>
 #include <linux/smp.h>
 #include <linux/tick.h>
+#include <trace/irq.h>
 
 #include <asm/irq.h>
 /*
@@ -52,6 +54,11 @@
 
 static DEFINE_PER_CPU(struct task_struct *, ksoftirqd);
 
+char *softirq_to_name[NR_SOFTIRQS] = {
+	"HI", "TIMER", "NET_TX", "NET_RX", "BLOCK",
+	"TASKLET", "SCHED", "HRTIMER",	"RCU"
+};
+
 /*
  * we cannot loop indefinitely here to avoid userspace starvation,
  * but we also don't want to introduce a worst case 1/HZ latency
@@ -79,13 +86,23 @@
 	WARN_ON_ONCE(in_irq());
 
 	raw_local_irq_save(flags);
-	add_preempt_count(SOFTIRQ_OFFSET);
+	/*
+	 * The preempt tracer hooks into add_preempt_count and will break
+	 * lockdep because it calls back into lockdep after SOFTIRQ_OFFSET
+	 * is set and before current->softirq_enabled is cleared.
+	 * We must manually increment preempt_count here and manually
+	 * call the trace_preempt_off later.
+	 */
+	preempt_count() += SOFTIRQ_OFFSET;
 	/*
 	 * Were softirqs turned off above:
 	 */
 	if (softirq_count() == SOFTIRQ_OFFSET)
 		trace_softirqs_off(ip);
 	raw_local_irq_restore(flags);
+
+	if (preempt_count() == SOFTIRQ_OFFSET)
+		trace_preempt_off(CALLER_ADDR0, get_parent_ip(CALLER_ADDR1));
 }
 #else /* !CONFIG_TRACE_IRQFLAGS */
 static inline void __local_bh_disable(unsigned long ip)
@@ -169,6 +186,9 @@
  */
 #define MAX_SOFTIRQ_RESTART 10
 
+DEFINE_TRACE(softirq_entry);
+DEFINE_TRACE(softirq_exit);
+
 asmlinkage void __do_softirq(void)
 {
 	struct softirq_action *h;
@@ -180,7 +200,7 @@
 	account_system_vtime(current);
 
 	__local_bh_disable((unsigned long)__builtin_return_address(0));
-	trace_softirq_enter();
+	lockdep_softirq_enter();
 
 	cpu = smp_processor_id();
 restart:
@@ -195,12 +215,14 @@
 		if (pending & 1) {
 			int prev_count = preempt_count();
 
+			trace_softirq_entry(h, softirq_vec);
 			h->action(h);
-
+			trace_softirq_exit(h, softirq_vec);
 			if (unlikely(prev_count != preempt_count())) {
-				printk(KERN_ERR "huh, entered softirq %td %p"
+				printk(KERN_ERR "huh, entered softirq %td %s %p"
 				       "with preempt_count %08x,"
 				       " exited with %08x?\n", h - softirq_vec,
+				       softirq_to_name[h - softirq_vec],
 				       h->action, prev_count, preempt_count());
 				preempt_count() = prev_count;
 			}
@@ -220,7 +242,7 @@
 	if (pending)
 		wakeup_softirqd();
 
-	trace_softirq_exit();
+	lockdep_softirq_exit();
 
 	account_system_vtime(current);
 	_local_bh_enable();
@@ -496,7 +518,7 @@
 		cp->flags = 0;
 		cp->priv = softirq;
 
-		__smp_call_function_single(cpu, cp);
+		__smp_call_function_single(cpu, cp, 0);
 		return 0;
 	}
 	return 1;
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 5ec4543..82350f8 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -48,6 +48,7 @@
 #include <linux/acpi.h>
 #include <linux/reboot.h>
 #include <linux/ftrace.h>
+#include <linux/slow-work.h>
 
 #include <asm/uaccess.h>
 #include <asm/processor.h>
@@ -897,6 +898,14 @@
 		.proc_handler	= &scan_unevictable_handler,
 	},
 #endif
+#ifdef CONFIG_SLOW_WORK
+	{
+		.ctl_name	= CTL_UNNUMBERED,
+		.procname	= "slow-work",
+		.mode		= 0555,
+		.child		= slow_work_sysctls,
+	},
+#endif
 /*
  * NOTE: do not add new entries to this table unless you have read
  * Documentation/sysctl/ctl_unnumbered.txt
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index 34e707e5..2246141 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -9,6 +9,9 @@
 config NOP_TRACER
 	bool
 
+config HAVE_FTRACE_NMI_ENTER
+	bool
+
 config HAVE_FUNCTION_TRACER
 	bool
 
@@ -31,12 +34,20 @@
 config HAVE_HW_BRANCH_TRACER
 	bool
 
+config HAVE_FTRACE_SYSCALLS
+	bool
+
 config TRACER_MAX_TRACE
 	bool
 
 config RING_BUFFER
 	bool
 
+config FTRACE_NMI_ENTER
+       bool
+       depends on HAVE_FTRACE_NMI_ENTER
+       default y
+
 config TRACING
 	bool
 	select DEBUG_FS
@@ -44,13 +55,29 @@
 	select STACKTRACE if STACKTRACE_SUPPORT
 	select TRACEPOINTS
 	select NOP_TRACER
+	select BINARY_PRINTF
+
+#
+# Minimum requirements an architecture has to meet for us to
+# be able to offer generic tracing facilities:
+#
+config TRACING_SUPPORT
+	bool
+	# PPC32 has no irqflags tracing support, but it can use most of the
+	# tracers anyway, they were tested to build and work. Note that new
+	# exceptions to this list aren't welcomed, better implement the
+	# irqflags tracing for your architecture.
+	depends on TRACE_IRQFLAGS_SUPPORT || PPC32
+	depends on STACKTRACE_SUPPORT
+	default y
+
+if TRACING_SUPPORT
 
 menu "Tracers"
 
 config FUNCTION_TRACER
 	bool "Kernel Function Tracer"
 	depends on HAVE_FUNCTION_TRACER
-	depends on DEBUG_KERNEL
 	select FRAME_POINTER
 	select KALLSYMS
 	select TRACING
@@ -72,18 +99,16 @@
 	help
 	  Enable the kernel to trace a function at both its return
 	  and its entry.
-	  It's first purpose is to trace the duration of functions and
-	  draw a call graph for each thread with some informations like
-	  the return value.
-	  This is done by setting the current return address on the current
-	  task structure into a stack of calls.
+	  Its first purpose is to trace the duration of functions and
+	  draw a call graph for each thread with some information like
+	  the return value. This is done by setting the current return 
+	  address on the current task structure into a stack of calls.
 
 config IRQSOFF_TRACER
 	bool "Interrupts-off Latency Tracer"
 	default n
 	depends on TRACE_IRQFLAGS_SUPPORT
 	depends on GENERIC_TIME
-	depends on DEBUG_KERNEL
 	select TRACE_IRQFLAGS
 	select TRACING
 	select TRACER_MAX_TRACE
@@ -106,7 +131,6 @@
 	default n
 	depends on GENERIC_TIME
 	depends on PREEMPT
-	depends on DEBUG_KERNEL
 	select TRACING
 	select TRACER_MAX_TRACE
 	help
@@ -127,13 +151,13 @@
 	bool "Sysprof Tracer"
 	depends on X86
 	select TRACING
+	select CONTEXT_SWITCH_TRACER
 	help
 	  This tracer provides the trace needed by the 'Sysprof' userspace
 	  tool.
 
 config SCHED_TRACER
 	bool "Scheduling Latency Tracer"
-	depends on DEBUG_KERNEL
 	select TRACING
 	select CONTEXT_SWITCH_TRACER
 	select TRACER_MAX_TRACE
@@ -143,16 +167,30 @@
 
 config CONTEXT_SWITCH_TRACER
 	bool "Trace process context switches"
-	depends on DEBUG_KERNEL
 	select TRACING
 	select MARKERS
 	help
 	  This tracer gets called from the context switch and records
 	  all switching of tasks.
 
+config EVENT_TRACER
+	bool "Trace various events in the kernel"
+	select TRACING
+	help
+	  This tracer hooks to various trace points in the kernel
+	  allowing the user to pick and choose which trace point they
+	  want to trace.
+
+config FTRACE_SYSCALLS
+	bool "Trace syscalls"
+	depends on HAVE_FTRACE_SYSCALLS
+	select TRACING
+	select KALLSYMS
+	help
+	  Basic tracer to catch the syscall entry and exit events.
+
 config BOOT_TRACER
 	bool "Trace boot initcalls"
-	depends on DEBUG_KERNEL
 	select TRACING
 	select CONTEXT_SWITCH_TRACER
 	help
@@ -165,13 +203,11 @@
 	  representation of the delays during initcalls - but the raw
 	  /debug/tracing/trace text output is readable too.
 
-	  ( Note that tracing self tests can't be enabled if this tracer is
-	    selected, because the self-tests are an initcall as well and that
-	    would invalidate the boot trace. )
+	  You must pass in ftrace=initcall to the kernel command line
+	  to enable this on bootup.
 
 config TRACE_BRANCH_PROFILING
 	bool "Trace likely/unlikely profiler"
-	depends on DEBUG_KERNEL
 	select TRACING
 	help
 	  This tracer profiles all the the likely and unlikely macros
@@ -224,7 +260,6 @@
 
 config POWER_TRACER
 	bool "Trace power consumption behavior"
-	depends on DEBUG_KERNEL
 	depends on X86
 	select TRACING
 	help
@@ -236,7 +271,6 @@
 config STACK_TRACER
 	bool "Trace max stack"
 	depends on HAVE_FUNCTION_TRACER
-	depends on DEBUG_KERNEL
 	select FUNCTION_TRACER
 	select STACKTRACE
 	select KALLSYMS
@@ -266,11 +300,66 @@
 	  This tracer records all branches on the system in a circular
 	  buffer giving access to the last N branches for each cpu.
 
+config KMEMTRACE
+	bool "Trace SLAB allocations"
+	select TRACING
+	help
+	  kmemtrace provides tracing for slab allocator functions, such as
+	  kmalloc, kfree, kmem_cache_alloc, kmem_cache_free etc.. Collected
+	  data is then fed to the userspace application in order to analyse
+	  allocation hotspots, internal fragmentation and so on, making it
+	  possible to see how well an allocator performs, as well as debug
+	  and profile kernel code.
+
+	  This requires an userspace application to use. See
+	  Documentation/vm/kmemtrace.txt for more information.
+
+	  Saying Y will make the kernel somewhat larger and slower. However,
+	  if you disable kmemtrace at run-time or boot-time, the performance
+	  impact is minimal (depending on the arch the kernel is built for).
+
+	  If unsure, say N.
+
+config WORKQUEUE_TRACER
+	bool "Trace workqueues"
+	select TRACING
+	help
+	  The workqueue tracer provides some statistical informations
+          about each cpu workqueue thread such as the number of the
+          works inserted and executed since their creation. It can help
+          to evaluate the amount of work each of them have to perform.
+          For example it can help a developer to decide whether he should
+          choose a per cpu workqueue instead of a singlethreaded one.
+
+config BLK_DEV_IO_TRACE
+	bool "Support for tracing block io actions"
+	depends on SYSFS
+	depends on BLOCK
+	select RELAY
+	select DEBUG_FS
+	select TRACEPOINTS
+	select TRACING
+	select STACKTRACE
+	help
+	  Say Y here if you want to be able to trace the block layer actions
+	  on a given queue. Tracing allows you to see any traffic happening
+	  on a block device queue. For more information (and the userspace
+	  support tools needed), fetch the blktrace tools from:
+
+	  git://git.kernel.dk/blktrace.git
+
+	  Tracing also is possible using the ftrace interface, e.g.:
+
+	    echo 1 > /sys/block/sda/sda1/trace/enable
+	    echo blk > /sys/kernel/debug/tracing/current_tracer
+	    cat /sys/kernel/debug/tracing/trace_pipe
+
+	  If unsure, say N.
+
 config DYNAMIC_FTRACE
 	bool "enable/disable ftrace tracepoints dynamically"
 	depends on FUNCTION_TRACER
 	depends on HAVE_DYNAMIC_FTRACE
-	depends on DEBUG_KERNEL
 	default y
 	help
          This option will modify all the calls to ftrace dynamically
@@ -296,7 +385,7 @@
 
 config FTRACE_STARTUP_TEST
 	bool "Perform a startup test on ftrace"
-	depends on TRACING && DEBUG_KERNEL && !BOOT_TRACER
+	depends on TRACING
 	select FTRACE_SELFTEST
 	help
 	  This option performs a series of startup tests on ftrace. On bootup
@@ -306,7 +395,7 @@
 
 config MMIOTRACE
 	bool "Memory mapped IO tracing"
-	depends on HAVE_MMIOTRACE_SUPPORT && DEBUG_KERNEL && PCI
+	depends on HAVE_MMIOTRACE_SUPPORT && PCI
 	select TRACING
 	help
 	  Mmiotrace traces Memory Mapped I/O access and is meant for
@@ -328,3 +417,6 @@
 	  Say N, unless you absolutely know what you are doing.
 
 endmenu
+
+endif # TRACING_SUPPORT
+
diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
index 349d5a9..2630f51 100644
--- a/kernel/trace/Makefile
+++ b/kernel/trace/Makefile
@@ -19,6 +19,10 @@
 obj-$(CONFIG_RING_BUFFER) += ring_buffer.o
 
 obj-$(CONFIG_TRACING) += trace.o
+obj-$(CONFIG_TRACING) += trace_clock.o
+obj-$(CONFIG_TRACING) += trace_output.o
+obj-$(CONFIG_TRACING) += trace_stat.o
+obj-$(CONFIG_TRACING) += trace_printk.o
 obj-$(CONFIG_CONTEXT_SWITCH_TRACER) += trace_sched_switch.o
 obj-$(CONFIG_SYSPROF_TRACER) += trace_sysprof.o
 obj-$(CONFIG_FUNCTION_TRACER) += trace_functions.o
@@ -33,5 +37,14 @@
 obj-$(CONFIG_TRACE_BRANCH_PROFILING) += trace_branch.o
 obj-$(CONFIG_HW_BRANCH_TRACER) += trace_hw_branches.o
 obj-$(CONFIG_POWER_TRACER) += trace_power.o
+obj-$(CONFIG_KMEMTRACE) += kmemtrace.o
+obj-$(CONFIG_WORKQUEUE_TRACER) += trace_workqueue.o
+obj-$(CONFIG_BLK_DEV_IO_TRACE)	+= blktrace.o
+obj-$(CONFIG_EVENT_TRACER) += trace_events.o
+obj-$(CONFIG_EVENT_TRACER) += events.o
+obj-$(CONFIG_EVENT_TRACER) += trace_export.o
+obj-$(CONFIG_FTRACE_SYSCALLS) += trace_syscalls.o
+obj-$(CONFIG_EVENT_PROFILE) += trace_event_profile.o
+obj-$(CONFIG_EVENT_TRACER) += trace_events_filter.o
 
 libftrace-y := ftrace.o
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
new file mode 100644
index 0000000..947c5b3
--- /dev/null
+++ b/kernel/trace/blktrace.c
@@ -0,0 +1,1549 @@
+/*
+ * Copyright (C) 2006 Jens Axboe <axboe@kernel.dk>
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/blkdev.h>
+#include <linux/blktrace_api.h>
+#include <linux/percpu.h>
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/debugfs.h>
+#include <linux/time.h>
+#include <trace/block.h>
+#include <linux/uaccess.h>
+#include "trace_output.h"
+
+static unsigned int blktrace_seq __read_mostly = 1;
+
+static struct trace_array *blk_tr;
+static bool blk_tracer_enabled __read_mostly;
+
+/* Select an alternative, minimalistic output than the original one */
+#define TRACE_BLK_OPT_CLASSIC	0x1
+
+static struct tracer_opt blk_tracer_opts[] = {
+	/* Default disable the minimalistic output */
+	{ TRACER_OPT(blk_classic, TRACE_BLK_OPT_CLASSIC) },
+	{ }
+};
+
+static struct tracer_flags blk_tracer_flags = {
+	.val  = 0,
+	.opts = blk_tracer_opts,
+};
+
+/* Global reference count of probes */
+static atomic_t blk_probes_ref = ATOMIC_INIT(0);
+
+static void blk_register_tracepoints(void);
+static void blk_unregister_tracepoints(void);
+
+/*
+ * Send out a notify message.
+ */
+static void trace_note(struct blk_trace *bt, pid_t pid, int action,
+		       const void *data, size_t len)
+{
+	struct blk_io_trace *t;
+	struct ring_buffer_event *event = NULL;
+	int pc = 0;
+	int cpu = smp_processor_id();
+	bool blk_tracer = blk_tracer_enabled;
+
+	if (blk_tracer) {
+		pc = preempt_count();
+		event = trace_buffer_lock_reserve(blk_tr, TRACE_BLK,
+						  sizeof(*t) + len,
+						  0, pc);
+		if (!event)
+			return;
+		t = ring_buffer_event_data(event);
+		goto record_it;
+	}
+
+	if (!bt->rchan)
+		return;
+
+	t = relay_reserve(bt->rchan, sizeof(*t) + len);
+	if (t) {
+		t->magic = BLK_IO_TRACE_MAGIC | BLK_IO_TRACE_VERSION;
+		t->time = ktime_to_ns(ktime_get());
+record_it:
+		t->device = bt->dev;
+		t->action = action;
+		t->pid = pid;
+		t->cpu = cpu;
+		t->pdu_len = len;
+		memcpy((void *) t + sizeof(*t), data, len);
+
+		if (blk_tracer)
+			trace_buffer_unlock_commit(blk_tr, event, 0, pc);
+	}
+}
+
+/*
+ * Send out a notify for this process, if we haven't done so since a trace
+ * started
+ */
+static void trace_note_tsk(struct blk_trace *bt, struct task_struct *tsk)
+{
+	tsk->btrace_seq = blktrace_seq;
+	trace_note(bt, tsk->pid, BLK_TN_PROCESS, tsk->comm, sizeof(tsk->comm));
+}
+
+static void trace_note_time(struct blk_trace *bt)
+{
+	struct timespec now;
+	unsigned long flags;
+	u32 words[2];
+
+	getnstimeofday(&now);
+	words[0] = now.tv_sec;
+	words[1] = now.tv_nsec;
+
+	local_irq_save(flags);
+	trace_note(bt, 0, BLK_TN_TIMESTAMP, words, sizeof(words));
+	local_irq_restore(flags);
+}
+
+void __trace_note_message(struct blk_trace *bt, const char *fmt, ...)
+{
+	int n;
+	va_list args;
+	unsigned long flags;
+	char *buf;
+
+	if (unlikely(bt->trace_state != Blktrace_running &&
+		     !blk_tracer_enabled))
+		return;
+
+	local_irq_save(flags);
+	buf = per_cpu_ptr(bt->msg_data, smp_processor_id());
+	va_start(args, fmt);
+	n = vscnprintf(buf, BLK_TN_MAX_MSG, fmt, args);
+	va_end(args);
+
+	trace_note(bt, 0, BLK_TN_MESSAGE, buf, n);
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL_GPL(__trace_note_message);
+
+static int act_log_check(struct blk_trace *bt, u32 what, sector_t sector,
+			 pid_t pid)
+{
+	if (((bt->act_mask << BLK_TC_SHIFT) & what) == 0)
+		return 1;
+	if (sector < bt->start_lba || sector > bt->end_lba)
+		return 1;
+	if (bt->pid && pid != bt->pid)
+		return 1;
+
+	return 0;
+}
+
+/*
+ * Data direction bit lookup
+ */
+static const u32 ddir_act[2] = { BLK_TC_ACT(BLK_TC_READ),
+				 BLK_TC_ACT(BLK_TC_WRITE) };
+
+/* The ilog2() calls fall out because they're constant */
+#define MASK_TC_BIT(rw, __name) ((rw & (1 << BIO_RW_ ## __name)) << \
+	  (ilog2(BLK_TC_ ## __name) + BLK_TC_SHIFT - BIO_RW_ ## __name))
+
+/*
+ * The worker for the various blk_add_trace*() types. Fills out a
+ * blk_io_trace structure and places it in a per-cpu subbuffer.
+ */
+static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
+		     int rw, u32 what, int error, int pdu_len, void *pdu_data)
+{
+	struct task_struct *tsk = current;
+	struct ring_buffer_event *event = NULL;
+	struct blk_io_trace *t;
+	unsigned long flags = 0;
+	unsigned long *sequence;
+	pid_t pid;
+	int cpu, pc = 0;
+	bool blk_tracer = blk_tracer_enabled;
+
+	if (unlikely(bt->trace_state != Blktrace_running && !blk_tracer))
+		return;
+
+	what |= ddir_act[rw & WRITE];
+	what |= MASK_TC_BIT(rw, BARRIER);
+	what |= MASK_TC_BIT(rw, SYNCIO);
+	what |= MASK_TC_BIT(rw, AHEAD);
+	what |= MASK_TC_BIT(rw, META);
+	what |= MASK_TC_BIT(rw, DISCARD);
+
+	pid = tsk->pid;
+	if (unlikely(act_log_check(bt, what, sector, pid)))
+		return;
+	cpu = raw_smp_processor_id();
+
+	if (blk_tracer) {
+		tracing_record_cmdline(current);
+
+		pc = preempt_count();
+		event = trace_buffer_lock_reserve(blk_tr, TRACE_BLK,
+						  sizeof(*t) + pdu_len,
+						  0, pc);
+		if (!event)
+			return;
+		t = ring_buffer_event_data(event);
+		goto record_it;
+	}
+
+	/*
+	 * A word about the locking here - we disable interrupts to reserve
+	 * some space in the relay per-cpu buffer, to prevent an irq
+	 * from coming in and stepping on our toes.
+	 */
+	local_irq_save(flags);
+
+	if (unlikely(tsk->btrace_seq != blktrace_seq))
+		trace_note_tsk(bt, tsk);
+
+	t = relay_reserve(bt->rchan, sizeof(*t) + pdu_len);
+	if (t) {
+		sequence = per_cpu_ptr(bt->sequence, cpu);
+
+		t->magic = BLK_IO_TRACE_MAGIC | BLK_IO_TRACE_VERSION;
+		t->sequence = ++(*sequence);
+		t->time = ktime_to_ns(ktime_get());
+record_it:
+		/*
+		 * These two are not needed in ftrace as they are in the
+		 * generic trace_entry, filled by tracing_generic_entry_update,
+		 * but for the trace_event->bin() synthesizer benefit we do it
+		 * here too.
+		 */
+		t->cpu = cpu;
+		t->pid = pid;
+
+		t->sector = sector;
+		t->bytes = bytes;
+		t->action = what;
+		t->device = bt->dev;
+		t->error = error;
+		t->pdu_len = pdu_len;
+
+		if (pdu_len)
+			memcpy((void *) t + sizeof(*t), pdu_data, pdu_len);
+
+		if (blk_tracer) {
+			trace_buffer_unlock_commit(blk_tr, event, 0, pc);
+			return;
+		}
+	}
+
+	local_irq_restore(flags);
+}
+
+static struct dentry *blk_tree_root;
+static DEFINE_MUTEX(blk_tree_mutex);
+
+static void blk_trace_free(struct blk_trace *bt)
+{
+	debugfs_remove(bt->msg_file);
+	debugfs_remove(bt->dropped_file);
+	relay_close(bt->rchan);
+	free_percpu(bt->sequence);
+	free_percpu(bt->msg_data);
+	kfree(bt);
+}
+
+static void blk_trace_cleanup(struct blk_trace *bt)
+{
+	blk_trace_free(bt);
+	if (atomic_dec_and_test(&blk_probes_ref))
+		blk_unregister_tracepoints();
+}
+
+int blk_trace_remove(struct request_queue *q)
+{
+	struct blk_trace *bt;
+
+	bt = xchg(&q->blk_trace, NULL);
+	if (!bt)
+		return -EINVAL;
+
+	if (bt->trace_state != Blktrace_running)
+		blk_trace_cleanup(bt);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(blk_trace_remove);
+
+static int blk_dropped_open(struct inode *inode, struct file *filp)
+{
+	filp->private_data = inode->i_private;
+
+	return 0;
+}
+
+static ssize_t blk_dropped_read(struct file *filp, char __user *buffer,
+				size_t count, loff_t *ppos)
+{
+	struct blk_trace *bt = filp->private_data;
+	char buf[16];
+
+	snprintf(buf, sizeof(buf), "%u\n", atomic_read(&bt->dropped));
+
+	return simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf));
+}
+
+static const struct file_operations blk_dropped_fops = {
+	.owner =	THIS_MODULE,
+	.open =		blk_dropped_open,
+	.read =		blk_dropped_read,
+};
+
+static int blk_msg_open(struct inode *inode, struct file *filp)
+{
+	filp->private_data = inode->i_private;
+
+	return 0;
+}
+
+static ssize_t blk_msg_write(struct file *filp, const char __user *buffer,
+				size_t count, loff_t *ppos)
+{
+	char *msg;
+	struct blk_trace *bt;
+
+	if (count > BLK_TN_MAX_MSG)
+		return -EINVAL;
+
+	msg = kmalloc(count, GFP_KERNEL);
+	if (msg == NULL)
+		return -ENOMEM;
+
+	if (copy_from_user(msg, buffer, count)) {
+		kfree(msg);
+		return -EFAULT;
+	}
+
+	bt = filp->private_data;
+	__trace_note_message(bt, "%s", msg);
+	kfree(msg);
+
+	return count;
+}
+
+static const struct file_operations blk_msg_fops = {
+	.owner =	THIS_MODULE,
+	.open =		blk_msg_open,
+	.write =	blk_msg_write,
+};
+
+/*
+ * Keep track of how many times we encountered a full subbuffer, to aid
+ * the user space app in telling how many lost events there were.
+ */
+static int blk_subbuf_start_callback(struct rchan_buf *buf, void *subbuf,
+				     void *prev_subbuf, size_t prev_padding)
+{
+	struct blk_trace *bt;
+
+	if (!relay_buf_full(buf))
+		return 1;
+
+	bt = buf->chan->private_data;
+	atomic_inc(&bt->dropped);
+	return 0;
+}
+
+static int blk_remove_buf_file_callback(struct dentry *dentry)
+{
+	struct dentry *parent = dentry->d_parent;
+	debugfs_remove(dentry);
+
+	/*
+	* this will fail for all but the last file, but that is ok. what we
+	* care about is the top level buts->name directory going away, when
+	* the last trace file is gone. Then we don't have to rmdir() that
+	* manually on trace stop, so it nicely solves the issue with
+	* force killing of running traces.
+	*/
+
+	debugfs_remove(parent);
+	return 0;
+}
+
+static struct dentry *blk_create_buf_file_callback(const char *filename,
+						   struct dentry *parent,
+						   int mode,
+						   struct rchan_buf *buf,
+						   int *is_global)
+{
+	return debugfs_create_file(filename, mode, parent, buf,
+					&relay_file_operations);
+}
+
+static struct rchan_callbacks blk_relay_callbacks = {
+	.subbuf_start		= blk_subbuf_start_callback,
+	.create_buf_file	= blk_create_buf_file_callback,
+	.remove_buf_file	= blk_remove_buf_file_callback,
+};
+
+/*
+ * Setup everything required to start tracing
+ */
+int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
+			struct blk_user_trace_setup *buts)
+{
+	struct blk_trace *old_bt, *bt = NULL;
+	struct dentry *dir = NULL;
+	int ret, i;
+
+	if (!buts->buf_size || !buts->buf_nr)
+		return -EINVAL;
+
+	strncpy(buts->name, name, BLKTRACE_BDEV_SIZE);
+	buts->name[BLKTRACE_BDEV_SIZE - 1] = '\0';
+
+	/*
+	 * some device names have larger paths - convert the slashes
+	 * to underscores for this to work as expected
+	 */
+	for (i = 0; i < strlen(buts->name); i++)
+		if (buts->name[i] == '/')
+			buts->name[i] = '_';
+
+	bt = kzalloc(sizeof(*bt), GFP_KERNEL);
+	if (!bt)
+		return -ENOMEM;
+
+	ret = -ENOMEM;
+	bt->sequence = alloc_percpu(unsigned long);
+	if (!bt->sequence)
+		goto err;
+
+	bt->msg_data = __alloc_percpu(BLK_TN_MAX_MSG, __alignof__(char));
+	if (!bt->msg_data)
+		goto err;
+
+	ret = -ENOENT;
+
+	mutex_lock(&blk_tree_mutex);
+	if (!blk_tree_root) {
+		blk_tree_root = debugfs_create_dir("block", NULL);
+		if (!blk_tree_root) {
+			mutex_unlock(&blk_tree_mutex);
+			goto err;
+		}
+	}
+	mutex_unlock(&blk_tree_mutex);
+
+	dir = debugfs_create_dir(buts->name, blk_tree_root);
+
+	if (!dir)
+		goto err;
+
+	bt->dir = dir;
+	bt->dev = dev;
+	atomic_set(&bt->dropped, 0);
+
+	ret = -EIO;
+	bt->dropped_file = debugfs_create_file("dropped", 0444, dir, bt,
+					       &blk_dropped_fops);
+	if (!bt->dropped_file)
+		goto err;
+
+	bt->msg_file = debugfs_create_file("msg", 0222, dir, bt, &blk_msg_fops);
+	if (!bt->msg_file)
+		goto err;
+
+	bt->rchan = relay_open("trace", dir, buts->buf_size,
+				buts->buf_nr, &blk_relay_callbacks, bt);
+	if (!bt->rchan)
+		goto err;
+
+	bt->act_mask = buts->act_mask;
+	if (!bt->act_mask)
+		bt->act_mask = (u16) -1;
+
+	bt->start_lba = buts->start_lba;
+	bt->end_lba = buts->end_lba;
+	if (!bt->end_lba)
+		bt->end_lba = -1ULL;
+
+	bt->pid = buts->pid;
+	bt->trace_state = Blktrace_setup;
+
+	ret = -EBUSY;
+	old_bt = xchg(&q->blk_trace, bt);
+	if (old_bt) {
+		(void) xchg(&q->blk_trace, old_bt);
+		goto err;
+	}
+
+	if (atomic_inc_return(&blk_probes_ref) == 1)
+		blk_register_tracepoints();
+
+	return 0;
+err:
+	blk_trace_free(bt);
+	return ret;
+}
+
+int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
+		    char __user *arg)
+{
+	struct blk_user_trace_setup buts;
+	int ret;
+
+	ret = copy_from_user(&buts, arg, sizeof(buts));
+	if (ret)
+		return -EFAULT;
+
+	ret = do_blk_trace_setup(q, name, dev, &buts);
+	if (ret)
+		return ret;
+
+	if (copy_to_user(arg, &buts, sizeof(buts)))
+		return -EFAULT;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(blk_trace_setup);
+
+int blk_trace_startstop(struct request_queue *q, int start)
+{
+	int ret;
+	struct blk_trace *bt = q->blk_trace;
+
+	if (bt == NULL)
+		return -EINVAL;
+
+	/*
+	 * For starting a trace, we can transition from a setup or stopped
+	 * trace. For stopping a trace, the state must be running
+	 */
+	ret = -EINVAL;
+	if (start) {
+		if (bt->trace_state == Blktrace_setup ||
+		    bt->trace_state == Blktrace_stopped) {
+			blktrace_seq++;
+			smp_mb();
+			bt->trace_state = Blktrace_running;
+
+			trace_note_time(bt);
+			ret = 0;
+		}
+	} else {
+		if (bt->trace_state == Blktrace_running) {
+			bt->trace_state = Blktrace_stopped;
+			relay_flush(bt->rchan);
+			ret = 0;
+		}
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(blk_trace_startstop);
+
+/**
+ * blk_trace_ioctl: - handle the ioctls associated with tracing
+ * @bdev:	the block device
+ * @cmd:	the ioctl cmd
+ * @arg:	the argument data, if any
+ *
+ **/
+int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
+{
+	struct request_queue *q;
+	int ret, start = 0;
+	char b[BDEVNAME_SIZE];
+
+	q = bdev_get_queue(bdev);
+	if (!q)
+		return -ENXIO;
+
+	mutex_lock(&bdev->bd_mutex);
+
+	switch (cmd) {
+	case BLKTRACESETUP:
+		bdevname(bdev, b);
+		ret = blk_trace_setup(q, b, bdev->bd_dev, arg);
+		break;
+	case BLKTRACESTART:
+		start = 1;
+	case BLKTRACESTOP:
+		ret = blk_trace_startstop(q, start);
+		break;
+	case BLKTRACETEARDOWN:
+		ret = blk_trace_remove(q);
+		break;
+	default:
+		ret = -ENOTTY;
+		break;
+	}
+
+	mutex_unlock(&bdev->bd_mutex);
+	return ret;
+}
+
+/**
+ * blk_trace_shutdown: - stop and cleanup trace structures
+ * @q:    the request queue associated with the device
+ *
+ **/
+void blk_trace_shutdown(struct request_queue *q)
+{
+	if (q->blk_trace) {
+		blk_trace_startstop(q, 0);
+		blk_trace_remove(q);
+	}
+}
+
+/*
+ * blktrace probes
+ */
+
+/**
+ * blk_add_trace_rq - Add a trace for a request oriented action
+ * @q:		queue the io is for
+ * @rq:		the source request
+ * @what:	the action
+ *
+ * Description:
+ *     Records an action against a request. Will log the bio offset + size.
+ *
+ **/
+static void blk_add_trace_rq(struct request_queue *q, struct request *rq,
+				    u32 what)
+{
+	struct blk_trace *bt = q->blk_trace;
+	int rw = rq->cmd_flags & 0x03;
+
+	if (likely(!bt))
+		return;
+
+	if (blk_discard_rq(rq))
+		rw |= (1 << BIO_RW_DISCARD);
+
+	if (blk_pc_request(rq)) {
+		what |= BLK_TC_ACT(BLK_TC_PC);
+		__blk_add_trace(bt, 0, rq->data_len, rw, what, rq->errors,
+				sizeof(rq->cmd), rq->cmd);
+	} else  {
+		what |= BLK_TC_ACT(BLK_TC_FS);
+		__blk_add_trace(bt, rq->hard_sector, rq->hard_nr_sectors << 9,
+				rw, what, rq->errors, 0, NULL);
+	}
+}
+
+static void blk_add_trace_rq_abort(struct request_queue *q, struct request *rq)
+{
+	blk_add_trace_rq(q, rq, BLK_TA_ABORT);
+}
+
+static void blk_add_trace_rq_insert(struct request_queue *q, struct request *rq)
+{
+	blk_add_trace_rq(q, rq, BLK_TA_INSERT);
+}
+
+static void blk_add_trace_rq_issue(struct request_queue *q, struct request *rq)
+{
+	blk_add_trace_rq(q, rq, BLK_TA_ISSUE);
+}
+
+static void blk_add_trace_rq_requeue(struct request_queue *q,
+				     struct request *rq)
+{
+	blk_add_trace_rq(q, rq, BLK_TA_REQUEUE);
+}
+
+static void blk_add_trace_rq_complete(struct request_queue *q,
+				      struct request *rq)
+{
+	blk_add_trace_rq(q, rq, BLK_TA_COMPLETE);
+}
+
+/**
+ * blk_add_trace_bio - Add a trace for a bio oriented action
+ * @q:		queue the io is for
+ * @bio:	the source bio
+ * @what:	the action
+ *
+ * Description:
+ *     Records an action against a bio. Will log the bio offset + size.
+ *
+ **/
+static void blk_add_trace_bio(struct request_queue *q, struct bio *bio,
+				     u32 what)
+{
+	struct blk_trace *bt = q->blk_trace;
+
+	if (likely(!bt))
+		return;
+
+	__blk_add_trace(bt, bio->bi_sector, bio->bi_size, bio->bi_rw, what,
+			!bio_flagged(bio, BIO_UPTODATE), 0, NULL);
+}
+
+static void blk_add_trace_bio_bounce(struct request_queue *q, struct bio *bio)
+{
+	blk_add_trace_bio(q, bio, BLK_TA_BOUNCE);
+}
+
+static void blk_add_trace_bio_complete(struct request_queue *q, struct bio *bio)
+{
+	blk_add_trace_bio(q, bio, BLK_TA_COMPLETE);
+}
+
+static void blk_add_trace_bio_backmerge(struct request_queue *q,
+					struct bio *bio)
+{
+	blk_add_trace_bio(q, bio, BLK_TA_BACKMERGE);
+}
+
+static void blk_add_trace_bio_frontmerge(struct request_queue *q,
+					 struct bio *bio)
+{
+	blk_add_trace_bio(q, bio, BLK_TA_FRONTMERGE);
+}
+
+static void blk_add_trace_bio_queue(struct request_queue *q, struct bio *bio)
+{
+	blk_add_trace_bio(q, bio, BLK_TA_QUEUE);
+}
+
+static void blk_add_trace_getrq(struct request_queue *q,
+				struct bio *bio, int rw)
+{
+	if (bio)
+		blk_add_trace_bio(q, bio, BLK_TA_GETRQ);
+	else {
+		struct blk_trace *bt = q->blk_trace;
+
+		if (bt)
+			__blk_add_trace(bt, 0, 0, rw, BLK_TA_GETRQ, 0, 0, NULL);
+	}
+}
+
+
+static void blk_add_trace_sleeprq(struct request_queue *q,
+				  struct bio *bio, int rw)
+{
+	if (bio)
+		blk_add_trace_bio(q, bio, BLK_TA_SLEEPRQ);
+	else {
+		struct blk_trace *bt = q->blk_trace;
+
+		if (bt)
+			__blk_add_trace(bt, 0, 0, rw, BLK_TA_SLEEPRQ,
+					0, 0, NULL);
+	}
+}
+
+static void blk_add_trace_plug(struct request_queue *q)
+{
+	struct blk_trace *bt = q->blk_trace;
+
+	if (bt)
+		__blk_add_trace(bt, 0, 0, 0, BLK_TA_PLUG, 0, 0, NULL);
+}
+
+static void blk_add_trace_unplug_io(struct request_queue *q)
+{
+	struct blk_trace *bt = q->blk_trace;
+
+	if (bt) {
+		unsigned int pdu = q->rq.count[READ] + q->rq.count[WRITE];
+		__be64 rpdu = cpu_to_be64(pdu);
+
+		__blk_add_trace(bt, 0, 0, 0, BLK_TA_UNPLUG_IO, 0,
+				sizeof(rpdu), &rpdu);
+	}
+}
+
+static void blk_add_trace_unplug_timer(struct request_queue *q)
+{
+	struct blk_trace *bt = q->blk_trace;
+
+	if (bt) {
+		unsigned int pdu = q->rq.count[READ] + q->rq.count[WRITE];
+		__be64 rpdu = cpu_to_be64(pdu);
+
+		__blk_add_trace(bt, 0, 0, 0, BLK_TA_UNPLUG_TIMER, 0,
+				sizeof(rpdu), &rpdu);
+	}
+}
+
+static void blk_add_trace_split(struct request_queue *q, struct bio *bio,
+				unsigned int pdu)
+{
+	struct blk_trace *bt = q->blk_trace;
+
+	if (bt) {
+		__be64 rpdu = cpu_to_be64(pdu);
+
+		__blk_add_trace(bt, bio->bi_sector, bio->bi_size, bio->bi_rw,
+				BLK_TA_SPLIT, !bio_flagged(bio, BIO_UPTODATE),
+				sizeof(rpdu), &rpdu);
+	}
+}
+
+/**
+ * blk_add_trace_remap - Add a trace for a remap operation
+ * @q:		queue the io is for
+ * @bio:	the source bio
+ * @dev:	target device
+ * @from:	source sector
+ * @to:		target sector
+ *
+ * Description:
+ *     Device mapper or raid target sometimes need to split a bio because
+ *     it spans a stripe (or similar). Add a trace for that action.
+ *
+ **/
+static void blk_add_trace_remap(struct request_queue *q, struct bio *bio,
+				       dev_t dev, sector_t from, sector_t to)
+{
+	struct blk_trace *bt = q->blk_trace;
+	struct blk_io_trace_remap r;
+
+	if (likely(!bt))
+		return;
+
+	r.device = cpu_to_be32(dev);
+	r.device_from = cpu_to_be32(bio->bi_bdev->bd_dev);
+	r.sector = cpu_to_be64(to);
+
+	__blk_add_trace(bt, from, bio->bi_size, bio->bi_rw, BLK_TA_REMAP,
+			!bio_flagged(bio, BIO_UPTODATE), sizeof(r), &r);
+}
+
+/**
+ * blk_add_driver_data - Add binary message with driver-specific data
+ * @q:		queue the io is for
+ * @rq:		io request
+ * @data:	driver-specific data
+ * @len:	length of driver-specific data
+ *
+ * Description:
+ *     Some drivers might want to write driver-specific data per request.
+ *
+ **/
+void blk_add_driver_data(struct request_queue *q,
+			 struct request *rq,
+			 void *data, size_t len)
+{
+	struct blk_trace *bt = q->blk_trace;
+
+	if (likely(!bt))
+		return;
+
+	if (blk_pc_request(rq))
+		__blk_add_trace(bt, 0, rq->data_len, 0, BLK_TA_DRV_DATA,
+				rq->errors, len, data);
+	else
+		__blk_add_trace(bt, rq->hard_sector, rq->hard_nr_sectors << 9,
+				0, BLK_TA_DRV_DATA, rq->errors, len, data);
+}
+EXPORT_SYMBOL_GPL(blk_add_driver_data);
+
+static void blk_register_tracepoints(void)
+{
+	int ret;
+
+	ret = register_trace_block_rq_abort(blk_add_trace_rq_abort);
+	WARN_ON(ret);
+	ret = register_trace_block_rq_insert(blk_add_trace_rq_insert);
+	WARN_ON(ret);
+	ret = register_trace_block_rq_issue(blk_add_trace_rq_issue);
+	WARN_ON(ret);
+	ret = register_trace_block_rq_requeue(blk_add_trace_rq_requeue);
+	WARN_ON(ret);
+	ret = register_trace_block_rq_complete(blk_add_trace_rq_complete);
+	WARN_ON(ret);
+	ret = register_trace_block_bio_bounce(blk_add_trace_bio_bounce);
+	WARN_ON(ret);
+	ret = register_trace_block_bio_complete(blk_add_trace_bio_complete);
+	WARN_ON(ret);
+	ret = register_trace_block_bio_backmerge(blk_add_trace_bio_backmerge);
+	WARN_ON(ret);
+	ret = register_trace_block_bio_frontmerge(blk_add_trace_bio_frontmerge);
+	WARN_ON(ret);
+	ret = register_trace_block_bio_queue(blk_add_trace_bio_queue);
+	WARN_ON(ret);
+	ret = register_trace_block_getrq(blk_add_trace_getrq);
+	WARN_ON(ret);
+	ret = register_trace_block_sleeprq(blk_add_trace_sleeprq);
+	WARN_ON(ret);
+	ret = register_trace_block_plug(blk_add_trace_plug);
+	WARN_ON(ret);
+	ret = register_trace_block_unplug_timer(blk_add_trace_unplug_timer);
+	WARN_ON(ret);
+	ret = register_trace_block_unplug_io(blk_add_trace_unplug_io);
+	WARN_ON(ret);
+	ret = register_trace_block_split(blk_add_trace_split);
+	WARN_ON(ret);
+	ret = register_trace_block_remap(blk_add_trace_remap);
+	WARN_ON(ret);
+}
+
+static void blk_unregister_tracepoints(void)
+{
+	unregister_trace_block_remap(blk_add_trace_remap);
+	unregister_trace_block_split(blk_add_trace_split);
+	unregister_trace_block_unplug_io(blk_add_trace_unplug_io);
+	unregister_trace_block_unplug_timer(blk_add_trace_unplug_timer);
+	unregister_trace_block_plug(blk_add_trace_plug);
+	unregister_trace_block_sleeprq(blk_add_trace_sleeprq);
+	unregister_trace_block_getrq(blk_add_trace_getrq);
+	unregister_trace_block_bio_queue(blk_add_trace_bio_queue);
+	unregister_trace_block_bio_frontmerge(blk_add_trace_bio_frontmerge);
+	unregister_trace_block_bio_backmerge(blk_add_trace_bio_backmerge);
+	unregister_trace_block_bio_complete(blk_add_trace_bio_complete);
+	unregister_trace_block_bio_bounce(blk_add_trace_bio_bounce);
+	unregister_trace_block_rq_complete(blk_add_trace_rq_complete);
+	unregister_trace_block_rq_requeue(blk_add_trace_rq_requeue);
+	unregister_trace_block_rq_issue(blk_add_trace_rq_issue);
+	unregister_trace_block_rq_insert(blk_add_trace_rq_insert);
+	unregister_trace_block_rq_abort(blk_add_trace_rq_abort);
+
+	tracepoint_synchronize_unregister();
+}
+
+/*
+ * struct blk_io_tracer formatting routines
+ */
+
+static void fill_rwbs(char *rwbs, const struct blk_io_trace *t)
+{
+	int i = 0;
+	int tc = t->action >> BLK_TC_SHIFT;
+
+	if (t->action == BLK_TN_MESSAGE) {
+		rwbs[i++] = 'N';
+		goto out;
+	}
+
+	if (tc & BLK_TC_DISCARD)
+		rwbs[i++] = 'D';
+	else if (tc & BLK_TC_WRITE)
+		rwbs[i++] = 'W';
+	else if (t->bytes)
+		rwbs[i++] = 'R';
+	else
+		rwbs[i++] = 'N';
+
+	if (tc & BLK_TC_AHEAD)
+		rwbs[i++] = 'A';
+	if (tc & BLK_TC_BARRIER)
+		rwbs[i++] = 'B';
+	if (tc & BLK_TC_SYNC)
+		rwbs[i++] = 'S';
+	if (tc & BLK_TC_META)
+		rwbs[i++] = 'M';
+out:
+	rwbs[i] = '\0';
+}
+
+static inline
+const struct blk_io_trace *te_blk_io_trace(const struct trace_entry *ent)
+{
+	return (const struct blk_io_trace *)ent;
+}
+
+static inline const void *pdu_start(const struct trace_entry *ent)
+{
+	return te_blk_io_trace(ent) + 1;
+}
+
+static inline u32 t_sec(const struct trace_entry *ent)
+{
+	return te_blk_io_trace(ent)->bytes >> 9;
+}
+
+static inline unsigned long long t_sector(const struct trace_entry *ent)
+{
+	return te_blk_io_trace(ent)->sector;
+}
+
+static inline __u16 t_error(const struct trace_entry *ent)
+{
+	return te_blk_io_trace(ent)->error;
+}
+
+static __u64 get_pdu_int(const struct trace_entry *ent)
+{
+	const __u64 *val = pdu_start(ent);
+	return be64_to_cpu(*val);
+}
+
+static void get_pdu_remap(const struct trace_entry *ent,
+			  struct blk_io_trace_remap *r)
+{
+	const struct blk_io_trace_remap *__r = pdu_start(ent);
+	__u64 sector = __r->sector;
+
+	r->device = be32_to_cpu(__r->device);
+	r->device_from = be32_to_cpu(__r->device_from);
+	r->sector = be64_to_cpu(sector);
+}
+
+typedef int (blk_log_action_t) (struct trace_iterator *iter, const char *act);
+
+static int blk_log_action_classic(struct trace_iterator *iter, const char *act)
+{
+	char rwbs[6];
+	unsigned long long ts  = iter->ts;
+	unsigned long nsec_rem = do_div(ts, NSEC_PER_SEC);
+	unsigned secs	       = (unsigned long)ts;
+	const struct blk_io_trace *t = te_blk_io_trace(iter->ent);
+
+	fill_rwbs(rwbs, t);
+
+	return trace_seq_printf(&iter->seq,
+				"%3d,%-3d %2d %5d.%09lu %5u %2s %3s ",
+				MAJOR(t->device), MINOR(t->device), iter->cpu,
+				secs, nsec_rem, iter->ent->pid, act, rwbs);
+}
+
+static int blk_log_action(struct trace_iterator *iter, const char *act)
+{
+	char rwbs[6];
+	const struct blk_io_trace *t = te_blk_io_trace(iter->ent);
+
+	fill_rwbs(rwbs, t);
+	return trace_seq_printf(&iter->seq, "%3d,%-3d %2s %3s ",
+				MAJOR(t->device), MINOR(t->device), act, rwbs);
+}
+
+static int blk_log_generic(struct trace_seq *s, const struct trace_entry *ent)
+{
+	char cmd[TASK_COMM_LEN];
+
+	trace_find_cmdline(ent->pid, cmd);
+
+	if (t_sec(ent))
+		return trace_seq_printf(s, "%llu + %u [%s]\n",
+					t_sector(ent), t_sec(ent), cmd);
+	return trace_seq_printf(s, "[%s]\n", cmd);
+}
+
+static int blk_log_with_error(struct trace_seq *s,
+			      const struct trace_entry *ent)
+{
+	if (t_sec(ent))
+		return trace_seq_printf(s, "%llu + %u [%d]\n", t_sector(ent),
+					t_sec(ent), t_error(ent));
+	return trace_seq_printf(s, "%llu [%d]\n", t_sector(ent), t_error(ent));
+}
+
+static int blk_log_remap(struct trace_seq *s, const struct trace_entry *ent)
+{
+	struct blk_io_trace_remap r = { .device = 0, };
+
+	get_pdu_remap(ent, &r);
+	return trace_seq_printf(s, "%llu + %u <- (%d,%d) %llu\n",
+			       t_sector(ent),
+			       t_sec(ent), MAJOR(r.device), MINOR(r.device),
+			       (unsigned long long)r.sector);
+}
+
+static int blk_log_plug(struct trace_seq *s, const struct trace_entry *ent)
+{
+	char cmd[TASK_COMM_LEN];
+
+	trace_find_cmdline(ent->pid, cmd);
+
+	return trace_seq_printf(s, "[%s]\n", cmd);
+}
+
+static int blk_log_unplug(struct trace_seq *s, const struct trace_entry *ent)
+{
+	char cmd[TASK_COMM_LEN];
+
+	trace_find_cmdline(ent->pid, cmd);
+
+	return trace_seq_printf(s, "[%s] %llu\n", cmd, get_pdu_int(ent));
+}
+
+static int blk_log_split(struct trace_seq *s, const struct trace_entry *ent)
+{
+	char cmd[TASK_COMM_LEN];
+
+	trace_find_cmdline(ent->pid, cmd);
+
+	return trace_seq_printf(s, "%llu / %llu [%s]\n", t_sector(ent),
+				get_pdu_int(ent), cmd);
+}
+
+static int blk_log_msg(struct trace_seq *s, const struct trace_entry *ent)
+{
+	int ret;
+	const struct blk_io_trace *t = te_blk_io_trace(ent);
+
+	ret = trace_seq_putmem(s, t + 1, t->pdu_len);
+	if (ret)
+		return trace_seq_putc(s, '\n');
+	return ret;
+}
+
+/*
+ * struct tracer operations
+ */
+
+static void blk_tracer_print_header(struct seq_file *m)
+{
+	if (!(blk_tracer_flags.val & TRACE_BLK_OPT_CLASSIC))
+		return;
+	seq_puts(m, "# DEV   CPU TIMESTAMP     PID ACT FLG\n"
+		    "#  |     |     |           |   |   |\n");
+}
+
+static void blk_tracer_start(struct trace_array *tr)
+{
+	blk_tracer_enabled = true;
+	trace_flags &= ~TRACE_ITER_CONTEXT_INFO;
+}
+
+static int blk_tracer_init(struct trace_array *tr)
+{
+	blk_tr = tr;
+	blk_tracer_start(tr);
+	return 0;
+}
+
+static void blk_tracer_stop(struct trace_array *tr)
+{
+	blk_tracer_enabled = false;
+	trace_flags |= TRACE_ITER_CONTEXT_INFO;
+}
+
+static void blk_tracer_reset(struct trace_array *tr)
+{
+	blk_tracer_stop(tr);
+}
+
+static const struct {
+	const char *act[2];
+	int	   (*print)(struct trace_seq *s, const struct trace_entry *ent);
+} what2act[] = {
+	[__BLK_TA_QUEUE]	= {{  "Q", "queue" },	   blk_log_generic },
+	[__BLK_TA_BACKMERGE]	= {{  "M", "backmerge" },  blk_log_generic },
+	[__BLK_TA_FRONTMERGE]	= {{  "F", "frontmerge" }, blk_log_generic },
+	[__BLK_TA_GETRQ]	= {{  "G", "getrq" },	   blk_log_generic },
+	[__BLK_TA_SLEEPRQ]	= {{  "S", "sleeprq" },	   blk_log_generic },
+	[__BLK_TA_REQUEUE]	= {{  "R", "requeue" },	   blk_log_with_error },
+	[__BLK_TA_ISSUE]	= {{  "D", "issue" },	   blk_log_generic },
+	[__BLK_TA_COMPLETE]	= {{  "C", "complete" },   blk_log_with_error },
+	[__BLK_TA_PLUG]		= {{  "P", "plug" },	   blk_log_plug },
+	[__BLK_TA_UNPLUG_IO]	= {{  "U", "unplug_io" },  blk_log_unplug },
+	[__BLK_TA_UNPLUG_TIMER]	= {{ "UT", "unplug_timer" }, blk_log_unplug },
+	[__BLK_TA_INSERT]	= {{  "I", "insert" },	   blk_log_generic },
+	[__BLK_TA_SPLIT]	= {{  "X", "split" },	   blk_log_split },
+	[__BLK_TA_BOUNCE]	= {{  "B", "bounce" },	   blk_log_generic },
+	[__BLK_TA_REMAP]	= {{  "A", "remap" },	   blk_log_remap },
+};
+
+static enum print_line_t print_one_line(struct trace_iterator *iter,
+					bool classic)
+{
+	struct trace_seq *s = &iter->seq;
+	const struct blk_io_trace *t;
+	u16 what;
+	int ret;
+	bool long_act;
+	blk_log_action_t *log_action;
+
+	t	   = te_blk_io_trace(iter->ent);
+	what	   = t->action & ((1 << BLK_TC_SHIFT) - 1);
+	long_act   = !!(trace_flags & TRACE_ITER_VERBOSE);
+	log_action = classic ? &blk_log_action_classic : &blk_log_action;
+
+	if (t->action == BLK_TN_MESSAGE) {
+		ret = log_action(iter, long_act ? "message" : "m");
+		if (ret)
+			ret = blk_log_msg(s, iter->ent);
+		goto out;
+	}
+
+	if (unlikely(what == 0 || what >= ARRAY_SIZE(what2act)))
+		ret = trace_seq_printf(s, "Bad pc action %x\n", what);
+	else {
+		ret = log_action(iter, what2act[what].act[long_act]);
+		if (ret)
+			ret = what2act[what].print(s, iter->ent);
+	}
+out:
+	return ret ? TRACE_TYPE_HANDLED : TRACE_TYPE_PARTIAL_LINE;
+}
+
+static enum print_line_t blk_trace_event_print(struct trace_iterator *iter,
+					       int flags)
+{
+	if (!trace_print_context(iter))
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	return print_one_line(iter, false);
+}
+
+static int blk_trace_synthesize_old_trace(struct trace_iterator *iter)
+{
+	struct trace_seq *s = &iter->seq;
+	struct blk_io_trace *t = (struct blk_io_trace *)iter->ent;
+	const int offset = offsetof(struct blk_io_trace, sector);
+	struct blk_io_trace old = {
+		.magic	  = BLK_IO_TRACE_MAGIC | BLK_IO_TRACE_VERSION,
+		.time     = iter->ts,
+	};
+
+	if (!trace_seq_putmem(s, &old, offset))
+		return 0;
+	return trace_seq_putmem(s, &t->sector,
+				sizeof(old) - offset + t->pdu_len);
+}
+
+static enum print_line_t
+blk_trace_event_print_binary(struct trace_iterator *iter, int flags)
+{
+	return blk_trace_synthesize_old_trace(iter) ?
+			TRACE_TYPE_HANDLED : TRACE_TYPE_PARTIAL_LINE;
+}
+
+static enum print_line_t blk_tracer_print_line(struct trace_iterator *iter)
+{
+	if (!(blk_tracer_flags.val & TRACE_BLK_OPT_CLASSIC))
+		return TRACE_TYPE_UNHANDLED;
+
+	return print_one_line(iter, true);
+}
+
+static struct tracer blk_tracer __read_mostly = {
+	.name		= "blk",
+	.init		= blk_tracer_init,
+	.reset		= blk_tracer_reset,
+	.start		= blk_tracer_start,
+	.stop		= blk_tracer_stop,
+	.print_header	= blk_tracer_print_header,
+	.print_line	= blk_tracer_print_line,
+	.flags		= &blk_tracer_flags,
+};
+
+static struct trace_event trace_blk_event = {
+	.type		= TRACE_BLK,
+	.trace		= blk_trace_event_print,
+	.binary		= blk_trace_event_print_binary,
+};
+
+static int __init init_blk_tracer(void)
+{
+	if (!register_ftrace_event(&trace_blk_event)) {
+		pr_warning("Warning: could not register block events\n");
+		return 1;
+	}
+
+	if (register_tracer(&blk_tracer) != 0) {
+		pr_warning("Warning: could not register the block tracer\n");
+		unregister_ftrace_event(&trace_blk_event);
+		return 1;
+	}
+
+	return 0;
+}
+
+device_initcall(init_blk_tracer);
+
+static int blk_trace_remove_queue(struct request_queue *q)
+{
+	struct blk_trace *bt;
+
+	bt = xchg(&q->blk_trace, NULL);
+	if (bt == NULL)
+		return -EINVAL;
+
+	if (atomic_dec_and_test(&blk_probes_ref))
+		blk_unregister_tracepoints();
+
+	blk_trace_free(bt);
+	return 0;
+}
+
+/*
+ * Setup everything required to start tracing
+ */
+static int blk_trace_setup_queue(struct request_queue *q, dev_t dev)
+{
+	struct blk_trace *old_bt, *bt = NULL;
+	int ret = -ENOMEM;
+
+	bt = kzalloc(sizeof(*bt), GFP_KERNEL);
+	if (!bt)
+		return -ENOMEM;
+
+	bt->msg_data = __alloc_percpu(BLK_TN_MAX_MSG, __alignof__(char));
+	if (!bt->msg_data)
+		goto free_bt;
+
+	bt->dev = dev;
+	bt->act_mask = (u16)-1;
+	bt->end_lba = -1ULL;
+
+	old_bt = xchg(&q->blk_trace, bt);
+	if (old_bt != NULL) {
+		(void)xchg(&q->blk_trace, old_bt);
+		ret = -EBUSY;
+		goto free_bt;
+	}
+
+	if (atomic_inc_return(&blk_probes_ref) == 1)
+		blk_register_tracepoints();
+	return 0;
+
+free_bt:
+	blk_trace_free(bt);
+	return ret;
+}
+
+/*
+ * sysfs interface to enable and configure tracing
+ */
+
+static ssize_t sysfs_blk_trace_attr_show(struct device *dev,
+					 struct device_attribute *attr,
+					 char *buf);
+static ssize_t sysfs_blk_trace_attr_store(struct device *dev,
+					  struct device_attribute *attr,
+					  const char *buf, size_t count);
+#define BLK_TRACE_DEVICE_ATTR(_name) \
+	DEVICE_ATTR(_name, S_IRUGO | S_IWUSR, \
+		    sysfs_blk_trace_attr_show, \
+		    sysfs_blk_trace_attr_store)
+
+static BLK_TRACE_DEVICE_ATTR(enable);
+static BLK_TRACE_DEVICE_ATTR(act_mask);
+static BLK_TRACE_DEVICE_ATTR(pid);
+static BLK_TRACE_DEVICE_ATTR(start_lba);
+static BLK_TRACE_DEVICE_ATTR(end_lba);
+
+static struct attribute *blk_trace_attrs[] = {
+	&dev_attr_enable.attr,
+	&dev_attr_act_mask.attr,
+	&dev_attr_pid.attr,
+	&dev_attr_start_lba.attr,
+	&dev_attr_end_lba.attr,
+	NULL
+};
+
+struct attribute_group blk_trace_attr_group = {
+	.name  = "trace",
+	.attrs = blk_trace_attrs,
+};
+
+static const struct {
+	int mask;
+	const char *str;
+} mask_maps[] = {
+	{ BLK_TC_READ,		"read"		},
+	{ BLK_TC_WRITE,		"write"		},
+	{ BLK_TC_BARRIER,	"barrier"	},
+	{ BLK_TC_SYNC,		"sync"		},
+	{ BLK_TC_QUEUE,		"queue"		},
+	{ BLK_TC_REQUEUE,	"requeue"	},
+	{ BLK_TC_ISSUE,		"issue"		},
+	{ BLK_TC_COMPLETE,	"complete"	},
+	{ BLK_TC_FS,		"fs"		},
+	{ BLK_TC_PC,		"pc"		},
+	{ BLK_TC_AHEAD,		"ahead"		},
+	{ BLK_TC_META,		"meta"		},
+	{ BLK_TC_DISCARD,	"discard"	},
+	{ BLK_TC_DRV_DATA,	"drv_data"	},
+};
+
+static int blk_trace_str2mask(const char *str)
+{
+	int i;
+	int mask = 0;
+	char *s, *token;
+
+	s = kstrdup(str, GFP_KERNEL);
+	if (s == NULL)
+		return -ENOMEM;
+	s = strstrip(s);
+
+	while (1) {
+		token = strsep(&s, ",");
+		if (token == NULL)
+			break;
+
+		if (*token == '\0')
+			continue;
+
+		for (i = 0; i < ARRAY_SIZE(mask_maps); i++) {
+			if (strcasecmp(token, mask_maps[i].str) == 0) {
+				mask |= mask_maps[i].mask;
+				break;
+			}
+		}
+		if (i == ARRAY_SIZE(mask_maps)) {
+			mask = -EINVAL;
+			break;
+		}
+	}
+	kfree(s);
+
+	return mask;
+}
+
+static ssize_t blk_trace_mask2str(char *buf, int mask)
+{
+	int i;
+	char *p = buf;
+
+	for (i = 0; i < ARRAY_SIZE(mask_maps); i++) {
+		if (mask & mask_maps[i].mask) {
+			p += sprintf(p, "%s%s",
+				    (p == buf) ? "" : ",", mask_maps[i].str);
+		}
+	}
+	*p++ = '\n';
+
+	return p - buf;
+}
+
+static struct request_queue *blk_trace_get_queue(struct block_device *bdev)
+{
+	if (bdev->bd_disk == NULL)
+		return NULL;
+
+	return bdev_get_queue(bdev);
+}
+
+static ssize_t sysfs_blk_trace_attr_show(struct device *dev,
+					 struct device_attribute *attr,
+					 char *buf)
+{
+	struct hd_struct *p = dev_to_part(dev);
+	struct request_queue *q;
+	struct block_device *bdev;
+	ssize_t ret = -ENXIO;
+
+	lock_kernel();
+	bdev = bdget(part_devt(p));
+	if (bdev == NULL)
+		goto out_unlock_kernel;
+
+	q = blk_trace_get_queue(bdev);
+	if (q == NULL)
+		goto out_bdput;
+
+	mutex_lock(&bdev->bd_mutex);
+
+	if (attr == &dev_attr_enable) {
+		ret = sprintf(buf, "%u\n", !!q->blk_trace);
+		goto out_unlock_bdev;
+	}
+
+	if (q->blk_trace == NULL)
+		ret = sprintf(buf, "disabled\n");
+	else if (attr == &dev_attr_act_mask)
+		ret = blk_trace_mask2str(buf, q->blk_trace->act_mask);
+	else if (attr == &dev_attr_pid)
+		ret = sprintf(buf, "%u\n", q->blk_trace->pid);
+	else if (attr == &dev_attr_start_lba)
+		ret = sprintf(buf, "%llu\n", q->blk_trace->start_lba);
+	else if (attr == &dev_attr_end_lba)
+		ret = sprintf(buf, "%llu\n", q->blk_trace->end_lba);
+
+out_unlock_bdev:
+	mutex_unlock(&bdev->bd_mutex);
+out_bdput:
+	bdput(bdev);
+out_unlock_kernel:
+	unlock_kernel();
+	return ret;
+}
+
+static ssize_t sysfs_blk_trace_attr_store(struct device *dev,
+					  struct device_attribute *attr,
+					  const char *buf, size_t count)
+{
+	struct block_device *bdev;
+	struct request_queue *q;
+	struct hd_struct *p;
+	u64 value;
+	ssize_t ret = -EINVAL;
+
+	if (count == 0)
+		goto out;
+
+	if (attr == &dev_attr_act_mask) {
+		if (sscanf(buf, "%llx", &value) != 1) {
+			/* Assume it is a list of trace category names */
+			ret = blk_trace_str2mask(buf);
+			if (ret < 0)
+				goto out;
+			value = ret;
+		}
+	} else if (sscanf(buf, "%llu", &value) != 1)
+		goto out;
+
+	ret = -ENXIO;
+
+	lock_kernel();
+	p = dev_to_part(dev);
+	bdev = bdget(part_devt(p));
+	if (bdev == NULL)
+		goto out_unlock_kernel;
+
+	q = blk_trace_get_queue(bdev);
+	if (q == NULL)
+		goto out_bdput;
+
+	mutex_lock(&bdev->bd_mutex);
+
+	if (attr == &dev_attr_enable) {
+		if (value)
+			ret = blk_trace_setup_queue(q, bdev->bd_dev);
+		else
+			ret = blk_trace_remove_queue(q);
+		goto out_unlock_bdev;
+	}
+
+	ret = 0;
+	if (q->blk_trace == NULL)
+		ret = blk_trace_setup_queue(q, bdev->bd_dev);
+
+	if (ret == 0) {
+		if (attr == &dev_attr_act_mask)
+			q->blk_trace->act_mask = value;
+		else if (attr == &dev_attr_pid)
+			q->blk_trace->pid = value;
+		else if (attr == &dev_attr_start_lba)
+			q->blk_trace->start_lba = value;
+		else if (attr == &dev_attr_end_lba)
+			q->blk_trace->end_lba = value;
+	}
+
+out_unlock_bdev:
+	mutex_unlock(&bdev->bd_mutex);
+out_bdput:
+	bdput(bdev);
+out_unlock_kernel:
+	unlock_kernel();
+out:
+	return ret ? ret : count;
+}
+
diff --git a/kernel/trace/events.c b/kernel/trace/events.c
new file mode 100644
index 0000000..246f2aa
--- /dev/null
+++ b/kernel/trace/events.c
@@ -0,0 +1,14 @@
+/*
+ * This is the place to register all trace points as events.
+ */
+
+#include <linux/stringify.h>
+
+#include <trace/trace_events.h>
+
+#include "trace_output.h"
+
+#include "trace_events_stage_1.h"
+#include "trace_events_stage_2.h"
+#include "trace_events_stage_3.h"
+
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index fdf913d..f1ed080 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -27,6 +27,9 @@
 #include <linux/sysctl.h>
 #include <linux/ctype.h>
 #include <linux/list.h>
+#include <linux/hash.h>
+
+#include <trace/sched.h>
 
 #include <asm/ftrace.h>
 
@@ -44,14 +47,14 @@
 			ftrace_kill();		\
 	} while (0)
 
+/* hash bits for specific function selection */
+#define FTRACE_HASH_BITS 7
+#define FTRACE_FUNC_HASHSIZE (1 << FTRACE_HASH_BITS)
+
 /* ftrace_enabled is a method to turn ftrace on or off */
 int ftrace_enabled __read_mostly;
 static int last_ftrace_enabled;
 
-/* set when tracing only a pid */
-struct pid *ftrace_pid_trace;
-static struct pid * const ftrace_swapper_pid = &init_struct_pid;
-
 /* Quick disabling of function tracer. */
 int function_trace_stop;
 
@@ -61,9 +64,7 @@
  */
 static int ftrace_disabled __read_mostly;
 
-static DEFINE_SPINLOCK(ftrace_lock);
-static DEFINE_MUTEX(ftrace_sysctl_lock);
-static DEFINE_MUTEX(ftrace_start_lock);
+static DEFINE_MUTEX(ftrace_lock);
 
 static struct ftrace_ops ftrace_list_end __read_mostly =
 {
@@ -134,9 +135,6 @@
 
 static int __register_ftrace_function(struct ftrace_ops *ops)
 {
-	/* should not be called from interrupt context */
-	spin_lock(&ftrace_lock);
-
 	ops->next = ftrace_list;
 	/*
 	 * We are entering ops into the ftrace_list but another
@@ -172,18 +170,12 @@
 #endif
 	}
 
-	spin_unlock(&ftrace_lock);
-
 	return 0;
 }
 
 static int __unregister_ftrace_function(struct ftrace_ops *ops)
 {
 	struct ftrace_ops **p;
-	int ret = 0;
-
-	/* should not be called from interrupt context */
-	spin_lock(&ftrace_lock);
 
 	/*
 	 * If we are removing the last function, then simply point
@@ -192,17 +184,15 @@
 	if (ftrace_list == ops && ops->next == &ftrace_list_end) {
 		ftrace_trace_function = ftrace_stub;
 		ftrace_list = &ftrace_list_end;
-		goto out;
+		return 0;
 	}
 
 	for (p = &ftrace_list; *p != &ftrace_list_end; p = &(*p)->next)
 		if (*p == ops)
 			break;
 
-	if (*p != ops) {
-		ret = -1;
-		goto out;
-	}
+	if (*p != ops)
+		return -1;
 
 	*p = (*p)->next;
 
@@ -223,21 +213,15 @@
 		}
 	}
 
- out:
-	spin_unlock(&ftrace_lock);
-
-	return ret;
+	return 0;
 }
 
 static void ftrace_update_pid_func(void)
 {
 	ftrace_func_t func;
 
-	/* should not be called from interrupt context */
-	spin_lock(&ftrace_lock);
-
 	if (ftrace_trace_function == ftrace_stub)
-		goto out;
+		return;
 
 	func = ftrace_trace_function;
 
@@ -254,23 +238,29 @@
 #else
 	__ftrace_trace_function = func;
 #endif
-
- out:
-	spin_unlock(&ftrace_lock);
 }
 
+/* set when tracing only a pid */
+struct pid *ftrace_pid_trace;
+static struct pid * const ftrace_swapper_pid = &init_struct_pid;
+
 #ifdef CONFIG_DYNAMIC_FTRACE
+
 #ifndef CONFIG_FTRACE_MCOUNT_RECORD
 # error Dynamic ftrace depends on MCOUNT_RECORD
 #endif
 
-/*
- * Since MCOUNT_ADDR may point to mcount itself, we do not want
- * to get it confused by reading a reference in the code as we
- * are parsing on objcopy output of text. Use a variable for
- * it instead.
- */
-static unsigned long mcount_addr = MCOUNT_ADDR;
+static struct hlist_head ftrace_func_hash[FTRACE_FUNC_HASHSIZE] __read_mostly;
+
+struct ftrace_func_probe {
+	struct hlist_node	node;
+	struct ftrace_probe_ops	*ops;
+	unsigned long		flags;
+	unsigned long		ip;
+	void			*data;
+	struct rcu_head		rcu;
+};
+
 
 enum {
 	FTRACE_ENABLE_CALLS		= (1 << 0),
@@ -284,13 +274,13 @@
 
 static int ftrace_filtered;
 
-static LIST_HEAD(ftrace_new_addrs);
+static struct dyn_ftrace *ftrace_new_addrs;
 
 static DEFINE_MUTEX(ftrace_regex_lock);
 
 struct ftrace_page {
 	struct ftrace_page	*next;
-	unsigned long		index;
+	int			index;
 	struct dyn_ftrace	records[];
 };
 
@@ -305,6 +295,19 @@
 
 static struct dyn_ftrace *ftrace_free_records;
 
+/*
+ * This is a double for. Do not use 'break' to break out of the loop,
+ * you must use a goto.
+ */
+#define do_for_each_ftrace_rec(pg, rec)					\
+	for (pg = ftrace_pages_start; pg; pg = pg->next) {		\
+		int _____i;						\
+		for (_____i = 0; _____i < pg->index; _____i++) {	\
+			rec = &pg->records[_____i];
+
+#define while_for_each_ftrace_rec()		\
+		}				\
+	}
 
 #ifdef CONFIG_KPROBES
 
@@ -338,7 +341,7 @@
 
 static void ftrace_free_rec(struct dyn_ftrace *rec)
 {
-	rec->ip = (unsigned long)ftrace_free_records;
+	rec->freelist = ftrace_free_records;
 	ftrace_free_records = rec;
 	rec->flags |= FTRACE_FL_FREE;
 }
@@ -349,23 +352,22 @@
 	struct ftrace_page *pg;
 	unsigned long s = (unsigned long)start;
 	unsigned long e = s + size;
-	int i;
 
 	if (ftrace_disabled || !start)
 		return;
 
-	/* should not be called from interrupt context */
-	spin_lock(&ftrace_lock);
-
-	for (pg = ftrace_pages_start; pg; pg = pg->next) {
-		for (i = 0; i < pg->index; i++) {
-			rec = &pg->records[i];
-
-			if ((rec->ip >= s) && (rec->ip < e))
-				ftrace_free_rec(rec);
+	mutex_lock(&ftrace_lock);
+	do_for_each_ftrace_rec(pg, rec) {
+		if ((rec->ip >= s) && (rec->ip < e)) {
+			/*
+			 * rec->ip is changed in ftrace_free_rec()
+			 * It should not between s and e if record was freed.
+			 */
+			FTRACE_WARN_ON(rec->flags & FTRACE_FL_FREE);
+			ftrace_free_rec(rec);
 		}
-	}
-	spin_unlock(&ftrace_lock);
+	} while_for_each_ftrace_rec();
+	mutex_unlock(&ftrace_lock);
 }
 
 static struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip)
@@ -382,7 +384,7 @@
 			return NULL;
 		}
 
-		ftrace_free_records = (void *)rec->ip;
+		ftrace_free_records = rec->freelist;
 		memset(rec, 0, sizeof(*rec));
 		return rec;
 	}
@@ -414,8 +416,8 @@
 		return NULL;
 
 	rec->ip = ip;
-
-	list_add(&rec->list, &ftrace_new_addrs);
+	rec->newlist = ftrace_new_addrs;
+	ftrace_new_addrs = rec;
 
 	return rec;
 }
@@ -461,10 +463,10 @@
 static int
 __ftrace_replace_code(struct dyn_ftrace *rec, int enable)
 {
-	unsigned long ip, fl;
 	unsigned long ftrace_addr;
+	unsigned long ip, fl;
 
-	ftrace_addr = (unsigned long)ftrace_caller;
+	ftrace_addr = (unsigned long)FTRACE_ADDR;
 
 	ip = rec->ip;
 
@@ -473,7 +475,7 @@
 	 * it is not enabled then do nothing.
 	 *
 	 * If this record is not to be traced and
-	 * it is enabled then disabled it.
+	 * it is enabled then disable it.
 	 *
 	 */
 	if (rec->flags & FTRACE_FL_NOTRACE) {
@@ -493,7 +495,7 @@
 		if (fl == (FTRACE_FL_FILTER | FTRACE_FL_ENABLED))
 			return 0;
 
-		/* Record is not filtered and is not enabled do nothing */
+		/* Record is not filtered or enabled, do nothing */
 		if (!fl)
 			return 0;
 
@@ -515,7 +517,7 @@
 
 		} else {
 
-			/* if record is not enabled do nothing */
+			/* if record is not enabled, do nothing */
 			if (!(rec->flags & FTRACE_FL_ENABLED))
 				return 0;
 
@@ -531,41 +533,41 @@
 
 static void ftrace_replace_code(int enable)
 {
-	int i, failed;
 	struct dyn_ftrace *rec;
 	struct ftrace_page *pg;
+	int failed;
 
-	for (pg = ftrace_pages_start; pg; pg = pg->next) {
-		for (i = 0; i < pg->index; i++) {
-			rec = &pg->records[i];
+	do_for_each_ftrace_rec(pg, rec) {
+		/*
+		 * Skip over free records, records that have
+		 * failed and not converted.
+		 */
+		if (rec->flags & FTRACE_FL_FREE ||
+		    rec->flags & FTRACE_FL_FAILED ||
+		    !(rec->flags & FTRACE_FL_CONVERTED))
+			continue;
 
-			/*
-			 * Skip over free records and records that have
-			 * failed.
-			 */
-			if (rec->flags & FTRACE_FL_FREE ||
-			    rec->flags & FTRACE_FL_FAILED)
-				continue;
-
-			/* ignore updates to this record's mcount site */
-			if (get_kprobe((void *)rec->ip)) {
-				freeze_record(rec);
-				continue;
-			} else {
-				unfreeze_record(rec);
-			}
-
-			failed = __ftrace_replace_code(rec, enable);
-			if (failed && (rec->flags & FTRACE_FL_CONVERTED)) {
-				rec->flags |= FTRACE_FL_FAILED;
-				if ((system_state == SYSTEM_BOOTING) ||
-				    !core_kernel_text(rec->ip)) {
-					ftrace_free_rec(rec);
-				} else
-					ftrace_bug(failed, rec->ip);
-			}
+		/* ignore updates to this record's mcount site */
+		if (get_kprobe((void *)rec->ip)) {
+			freeze_record(rec);
+			continue;
+		} else {
+			unfreeze_record(rec);
 		}
-	}
+
+		failed = __ftrace_replace_code(rec, enable);
+		if (failed) {
+			rec->flags |= FTRACE_FL_FAILED;
+			if ((system_state == SYSTEM_BOOTING) ||
+			    !core_kernel_text(rec->ip)) {
+				ftrace_free_rec(rec);
+				} else {
+				ftrace_bug(failed, rec->ip);
+					/* Stop processing */
+					return;
+				}
+		}
+	} while_for_each_ftrace_rec();
 }
 
 static int
@@ -576,7 +578,7 @@
 
 	ip = rec->ip;
 
-	ret = ftrace_make_nop(mod, rec, mcount_addr);
+	ret = ftrace_make_nop(mod, rec, MCOUNT_ADDR);
 	if (ret) {
 		ftrace_bug(ret, ip);
 		rec->flags |= FTRACE_FL_FAILED;
@@ -585,6 +587,24 @@
 	return 1;
 }
 
+/*
+ * archs can override this function if they must do something
+ * before the modifying code is performed.
+ */
+int __weak ftrace_arch_code_modify_prepare(void)
+{
+	return 0;
+}
+
+/*
+ * archs can override this function if they must do something
+ * after the modifying code is performed.
+ */
+int __weak ftrace_arch_code_modify_post_process(void)
+{
+	return 0;
+}
+
 static int __ftrace_modify_code(void *data)
 {
 	int *command = data;
@@ -607,7 +627,17 @@
 
 static void ftrace_run_update_code(int command)
 {
+	int ret;
+
+	ret = ftrace_arch_code_modify_prepare();
+	FTRACE_WARN_ON(ret);
+	if (ret)
+		return;
+
 	stop_machine(__ftrace_modify_code, &command, NULL);
+
+	ret = ftrace_arch_code_modify_post_process();
+	FTRACE_WARN_ON(ret);
 }
 
 static ftrace_func_t saved_ftrace_func;
@@ -631,13 +661,10 @@
 	if (unlikely(ftrace_disabled))
 		return;
 
-	mutex_lock(&ftrace_start_lock);
 	ftrace_start_up++;
 	command |= FTRACE_ENABLE_CALLS;
 
 	ftrace_startup_enable(command);
-
-	mutex_unlock(&ftrace_start_lock);
 }
 
 static void ftrace_shutdown(int command)
@@ -645,7 +672,6 @@
 	if (unlikely(ftrace_disabled))
 		return;
 
-	mutex_lock(&ftrace_start_lock);
 	ftrace_start_up--;
 	if (!ftrace_start_up)
 		command |= FTRACE_DISABLE_CALLS;
@@ -656,11 +682,9 @@
 	}
 
 	if (!command || !ftrace_enabled)
-		goto out;
+		return;
 
 	ftrace_run_update_code(command);
- out:
-	mutex_unlock(&ftrace_start_lock);
 }
 
 static void ftrace_startup_sysctl(void)
@@ -670,7 +694,6 @@
 	if (unlikely(ftrace_disabled))
 		return;
 
-	mutex_lock(&ftrace_start_lock);
 	/* Force update next time */
 	saved_ftrace_func = NULL;
 	/* ftrace_start_up is true if we want ftrace running */
@@ -678,7 +701,6 @@
 		command |= FTRACE_ENABLE_CALLS;
 
 	ftrace_run_update_code(command);
-	mutex_unlock(&ftrace_start_lock);
 }
 
 static void ftrace_shutdown_sysctl(void)
@@ -688,13 +710,11 @@
 	if (unlikely(ftrace_disabled))
 		return;
 
-	mutex_lock(&ftrace_start_lock);
 	/* ftrace_start_up is true if ftrace is running */
 	if (ftrace_start_up)
 		command |= FTRACE_DISABLE_CALLS;
 
 	ftrace_run_update_code(command);
-	mutex_unlock(&ftrace_start_lock);
 }
 
 static cycle_t		ftrace_update_time;
@@ -703,19 +723,21 @@
 
 static int ftrace_update_code(struct module *mod)
 {
-	struct dyn_ftrace *p, *t;
+	struct dyn_ftrace *p;
 	cycle_t start, stop;
 
 	start = ftrace_now(raw_smp_processor_id());
 	ftrace_update_cnt = 0;
 
-	list_for_each_entry_safe(p, t, &ftrace_new_addrs, list) {
+	while (ftrace_new_addrs) {
 
 		/* If something went wrong, bail without enabling anything */
 		if (unlikely(ftrace_disabled))
 			return -1;
 
-		list_del_init(&p->list);
+		p = ftrace_new_addrs;
+		ftrace_new_addrs = p->newlist;
+		p->flags = 0L;
 
 		/* convert record (i.e, patch mcount-call with NOP) */
 		if (ftrace_code_disable(mod, p)) {
@@ -781,13 +803,16 @@
 	FTRACE_ITER_CONT	= (1 << 1),
 	FTRACE_ITER_NOTRACE	= (1 << 2),
 	FTRACE_ITER_FAILURES	= (1 << 3),
+	FTRACE_ITER_PRINTALL	= (1 << 4),
+	FTRACE_ITER_HASH	= (1 << 5),
 };
 
 #define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */
 
 struct ftrace_iterator {
 	struct ftrace_page	*pg;
-	unsigned		idx;
+	int			hidx;
+	int			idx;
 	unsigned		flags;
 	unsigned char		buffer[FTRACE_BUFF_MAX+1];
 	unsigned		buffer_idx;
@@ -795,15 +820,89 @@
 };
 
 static void *
+t_hash_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	struct ftrace_iterator *iter = m->private;
+	struct hlist_node *hnd = v;
+	struct hlist_head *hhd;
+
+	WARN_ON(!(iter->flags & FTRACE_ITER_HASH));
+
+	(*pos)++;
+
+ retry:
+	if (iter->hidx >= FTRACE_FUNC_HASHSIZE)
+		return NULL;
+
+	hhd = &ftrace_func_hash[iter->hidx];
+
+	if (hlist_empty(hhd)) {
+		iter->hidx++;
+		hnd = NULL;
+		goto retry;
+	}
+
+	if (!hnd)
+		hnd = hhd->first;
+	else {
+		hnd = hnd->next;
+		if (!hnd) {
+			iter->hidx++;
+			goto retry;
+		}
+	}
+
+	return hnd;
+}
+
+static void *t_hash_start(struct seq_file *m, loff_t *pos)
+{
+	struct ftrace_iterator *iter = m->private;
+	void *p = NULL;
+
+	iter->flags |= FTRACE_ITER_HASH;
+
+	return t_hash_next(m, p, pos);
+}
+
+static int t_hash_show(struct seq_file *m, void *v)
+{
+	struct ftrace_func_probe *rec;
+	struct hlist_node *hnd = v;
+	char str[KSYM_SYMBOL_LEN];
+
+	rec = hlist_entry(hnd, struct ftrace_func_probe, node);
+
+	if (rec->ops->print)
+		return rec->ops->print(m, rec->ip, rec->ops, rec->data);
+
+	kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
+	seq_printf(m, "%s:", str);
+
+	kallsyms_lookup((unsigned long)rec->ops->func, NULL, NULL, NULL, str);
+	seq_printf(m, "%s", str);
+
+	if (rec->data)
+		seq_printf(m, ":%p", rec->data);
+	seq_putc(m, '\n');
+
+	return 0;
+}
+
+static void *
 t_next(struct seq_file *m, void *v, loff_t *pos)
 {
 	struct ftrace_iterator *iter = m->private;
 	struct dyn_ftrace *rec = NULL;
 
+	if (iter->flags & FTRACE_ITER_HASH)
+		return t_hash_next(m, v, pos);
+
 	(*pos)++;
 
-	/* should not be called from interrupt context */
-	spin_lock(&ftrace_lock);
+	if (iter->flags & FTRACE_ITER_PRINTALL)
+		return NULL;
+
  retry:
 	if (iter->idx >= iter->pg->index) {
 		if (iter->pg->next) {
@@ -832,7 +931,6 @@
 			goto retry;
 		}
 	}
-	spin_unlock(&ftrace_lock);
 
 	return rec;
 }
@@ -842,6 +940,23 @@
 	struct ftrace_iterator *iter = m->private;
 	void *p = NULL;
 
+	mutex_lock(&ftrace_lock);
+	/*
+	 * For set_ftrace_filter reading, if we have the filter
+	 * off, we can short cut and just print out that all
+	 * functions are enabled.
+	 */
+	if (iter->flags & FTRACE_ITER_FILTER && !ftrace_filtered) {
+		if (*pos > 0)
+			return t_hash_start(m, pos);
+		iter->flags |= FTRACE_ITER_PRINTALL;
+		(*pos)++;
+		return iter;
+	}
+
+	if (iter->flags & FTRACE_ITER_HASH)
+		return t_hash_start(m, pos);
+
 	if (*pos > 0) {
 		if (iter->idx < 0)
 			return p;
@@ -851,18 +966,31 @@
 
 	p = t_next(m, p, pos);
 
+	if (!p)
+		return t_hash_start(m, pos);
+
 	return p;
 }
 
 static void t_stop(struct seq_file *m, void *p)
 {
+	mutex_unlock(&ftrace_lock);
 }
 
 static int t_show(struct seq_file *m, void *v)
 {
+	struct ftrace_iterator *iter = m->private;
 	struct dyn_ftrace *rec = v;
 	char str[KSYM_SYMBOL_LEN];
 
+	if (iter->flags & FTRACE_ITER_HASH)
+		return t_hash_show(m, v);
+
+	if (iter->flags & FTRACE_ITER_PRINTALL) {
+		seq_printf(m, "#### all functions enabled ####\n");
+		return 0;
+	}
+
 	if (!rec)
 		return 0;
 
@@ -941,23 +1069,16 @@
 	struct ftrace_page *pg;
 	struct dyn_ftrace *rec;
 	unsigned long type = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
-	unsigned i;
 
-	/* should not be called from interrupt context */
-	spin_lock(&ftrace_lock);
+	mutex_lock(&ftrace_lock);
 	if (enable)
 		ftrace_filtered = 0;
-	pg = ftrace_pages_start;
-	while (pg) {
-		for (i = 0; i < pg->index; i++) {
-			rec = &pg->records[i];
-			if (rec->flags & FTRACE_FL_FAILED)
-				continue;
-			rec->flags &= ~type;
-		}
-		pg = pg->next;
-	}
-	spin_unlock(&ftrace_lock);
+	do_for_each_ftrace_rec(pg, rec) {
+		if (rec->flags & FTRACE_FL_FAILED)
+			continue;
+		rec->flags &= ~type;
+	} while_for_each_ftrace_rec();
+	mutex_unlock(&ftrace_lock);
 }
 
 static int
@@ -1008,16 +1129,6 @@
 	return ftrace_regex_open(inode, file, 0);
 }
 
-static ssize_t
-ftrace_regex_read(struct file *file, char __user *ubuf,
-		       size_t cnt, loff_t *ppos)
-{
-	if (file->f_mode & FMODE_READ)
-		return seq_read(file, ubuf, cnt, ppos);
-	else
-		return -EPERM;
-}
-
 static loff_t
 ftrace_regex_lseek(struct file *file, loff_t offset, int origin)
 {
@@ -1038,86 +1149,536 @@
 	MATCH_END_ONLY,
 };
 
-static void
-ftrace_match(unsigned char *buff, int len, int enable)
+/*
+ * (static function - no need for kernel doc)
+ *
+ * Pass in a buffer containing a glob and this function will
+ * set search to point to the search part of the buffer and
+ * return the type of search it is (see enum above).
+ * This does modify buff.
+ *
+ * Returns enum type.
+ *  search returns the pointer to use for comparison.
+ *  not returns 1 if buff started with a '!'
+ *     0 otherwise.
+ */
+static int
+ftrace_setup_glob(char *buff, int len, char **search, int *not)
 {
-	char str[KSYM_SYMBOL_LEN];
-	char *search = NULL;
-	struct ftrace_page *pg;
-	struct dyn_ftrace *rec;
 	int type = MATCH_FULL;
-	unsigned long flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
-	unsigned i, match = 0, search_len = 0;
-	int not = 0;
+	int i;
 
 	if (buff[0] == '!') {
-		not = 1;
+		*not = 1;
 		buff++;
 		len--;
-	}
+	} else
+		*not = 0;
+
+	*search = buff;
 
 	for (i = 0; i < len; i++) {
 		if (buff[i] == '*') {
 			if (!i) {
-				search = buff + i + 1;
+				*search = buff + 1;
 				type = MATCH_END_ONLY;
-				search_len = len - (i + 1);
 			} else {
-				if (type == MATCH_END_ONLY) {
+				if (type == MATCH_END_ONLY)
 					type = MATCH_MIDDLE_ONLY;
-				} else {
-					match = i;
+				else
 					type = MATCH_FRONT_ONLY;
-				}
 				buff[i] = 0;
 				break;
 			}
 		}
 	}
 
-	/* should not be called from interrupt context */
-	spin_lock(&ftrace_lock);
-	if (enable)
-		ftrace_filtered = 1;
-	pg = ftrace_pages_start;
-	while (pg) {
-		for (i = 0; i < pg->index; i++) {
-			int matched = 0;
-			char *ptr;
+	return type;
+}
 
-			rec = &pg->records[i];
-			if (rec->flags & FTRACE_FL_FAILED)
+static int ftrace_match(char *str, char *regex, int len, int type)
+{
+	int matched = 0;
+	char *ptr;
+
+	switch (type) {
+	case MATCH_FULL:
+		if (strcmp(str, regex) == 0)
+			matched = 1;
+		break;
+	case MATCH_FRONT_ONLY:
+		if (strncmp(str, regex, len) == 0)
+			matched = 1;
+		break;
+	case MATCH_MIDDLE_ONLY:
+		if (strstr(str, regex))
+			matched = 1;
+		break;
+	case MATCH_END_ONLY:
+		ptr = strstr(str, regex);
+		if (ptr && (ptr[len] == 0))
+			matched = 1;
+		break;
+	}
+
+	return matched;
+}
+
+static int
+ftrace_match_record(struct dyn_ftrace *rec, char *regex, int len, int type)
+{
+	char str[KSYM_SYMBOL_LEN];
+
+	kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
+	return ftrace_match(str, regex, len, type);
+}
+
+static void ftrace_match_records(char *buff, int len, int enable)
+{
+	unsigned int search_len;
+	struct ftrace_page *pg;
+	struct dyn_ftrace *rec;
+	unsigned long flag;
+	char *search;
+	int type;
+	int not;
+
+	flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
+	type = ftrace_setup_glob(buff, len, &search, &not);
+
+	search_len = strlen(search);
+
+	mutex_lock(&ftrace_lock);
+	do_for_each_ftrace_rec(pg, rec) {
+
+		if (rec->flags & FTRACE_FL_FAILED)
+			continue;
+
+		if (ftrace_match_record(rec, search, search_len, type)) {
+			if (not)
+				rec->flags &= ~flag;
+			else
+				rec->flags |= flag;
+		}
+		/*
+		 * Only enable filtering if we have a function that
+		 * is filtered on.
+		 */
+		if (enable && (rec->flags & FTRACE_FL_FILTER))
+			ftrace_filtered = 1;
+	} while_for_each_ftrace_rec();
+	mutex_unlock(&ftrace_lock);
+}
+
+static int
+ftrace_match_module_record(struct dyn_ftrace *rec, char *mod,
+			   char *regex, int len, int type)
+{
+	char str[KSYM_SYMBOL_LEN];
+	char *modname;
+
+	kallsyms_lookup(rec->ip, NULL, NULL, &modname, str);
+
+	if (!modname || strcmp(modname, mod))
+		return 0;
+
+	/* blank search means to match all funcs in the mod */
+	if (len)
+		return ftrace_match(str, regex, len, type);
+	else
+		return 1;
+}
+
+static void ftrace_match_module_records(char *buff, char *mod, int enable)
+{
+	unsigned search_len = 0;
+	struct ftrace_page *pg;
+	struct dyn_ftrace *rec;
+	int type = MATCH_FULL;
+	char *search = buff;
+	unsigned long flag;
+	int not = 0;
+
+	flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
+
+	/* blank or '*' mean the same */
+	if (strcmp(buff, "*") == 0)
+		buff[0] = 0;
+
+	/* handle the case of 'dont filter this module' */
+	if (strcmp(buff, "!") == 0 || strcmp(buff, "!*") == 0) {
+		buff[0] = 0;
+		not = 1;
+	}
+
+	if (strlen(buff)) {
+		type = ftrace_setup_glob(buff, strlen(buff), &search, &not);
+		search_len = strlen(search);
+	}
+
+	mutex_lock(&ftrace_lock);
+	do_for_each_ftrace_rec(pg, rec) {
+
+		if (rec->flags & FTRACE_FL_FAILED)
+			continue;
+
+		if (ftrace_match_module_record(rec, mod,
+					       search, search_len, type)) {
+			if (not)
+				rec->flags &= ~flag;
+			else
+				rec->flags |= flag;
+		}
+		if (enable && (rec->flags & FTRACE_FL_FILTER))
+			ftrace_filtered = 1;
+
+	} while_for_each_ftrace_rec();
+	mutex_unlock(&ftrace_lock);
+}
+
+/*
+ * We register the module command as a template to show others how
+ * to register the a command as well.
+ */
+
+static int
+ftrace_mod_callback(char *func, char *cmd, char *param, int enable)
+{
+	char *mod;
+
+	/*
+	 * cmd == 'mod' because we only registered this func
+	 * for the 'mod' ftrace_func_command.
+	 * But if you register one func with multiple commands,
+	 * you can tell which command was used by the cmd
+	 * parameter.
+	 */
+
+	/* we must have a module name */
+	if (!param)
+		return -EINVAL;
+
+	mod = strsep(&param, ":");
+	if (!strlen(mod))
+		return -EINVAL;
+
+	ftrace_match_module_records(func, mod, enable);
+	return 0;
+}
+
+static struct ftrace_func_command ftrace_mod_cmd = {
+	.name			= "mod",
+	.func			= ftrace_mod_callback,
+};
+
+static int __init ftrace_mod_cmd_init(void)
+{
+	return register_ftrace_command(&ftrace_mod_cmd);
+}
+device_initcall(ftrace_mod_cmd_init);
+
+static void
+function_trace_probe_call(unsigned long ip, unsigned long parent_ip)
+{
+	struct ftrace_func_probe *entry;
+	struct hlist_head *hhd;
+	struct hlist_node *n;
+	unsigned long key;
+	int resched;
+
+	key = hash_long(ip, FTRACE_HASH_BITS);
+
+	hhd = &ftrace_func_hash[key];
+
+	if (hlist_empty(hhd))
+		return;
+
+	/*
+	 * Disable preemption for these calls to prevent a RCU grace
+	 * period. This syncs the hash iteration and freeing of items
+	 * on the hash. rcu_read_lock is too dangerous here.
+	 */
+	resched = ftrace_preempt_disable();
+	hlist_for_each_entry_rcu(entry, n, hhd, node) {
+		if (entry->ip == ip)
+			entry->ops->func(ip, parent_ip, &entry->data);
+	}
+	ftrace_preempt_enable(resched);
+}
+
+static struct ftrace_ops trace_probe_ops __read_mostly =
+{
+	.func = function_trace_probe_call,
+};
+
+static int ftrace_probe_registered;
+
+static void __enable_ftrace_function_probe(void)
+{
+	int i;
+
+	if (ftrace_probe_registered)
+		return;
+
+	for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) {
+		struct hlist_head *hhd = &ftrace_func_hash[i];
+		if (hhd->first)
+			break;
+	}
+	/* Nothing registered? */
+	if (i == FTRACE_FUNC_HASHSIZE)
+		return;
+
+	__register_ftrace_function(&trace_probe_ops);
+	ftrace_startup(0);
+	ftrace_probe_registered = 1;
+}
+
+static void __disable_ftrace_function_probe(void)
+{
+	int i;
+
+	if (!ftrace_probe_registered)
+		return;
+
+	for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) {
+		struct hlist_head *hhd = &ftrace_func_hash[i];
+		if (hhd->first)
+			return;
+	}
+
+	/* no more funcs left */
+	__unregister_ftrace_function(&trace_probe_ops);
+	ftrace_shutdown(0);
+	ftrace_probe_registered = 0;
+}
+
+
+static void ftrace_free_entry_rcu(struct rcu_head *rhp)
+{
+	struct ftrace_func_probe *entry =
+		container_of(rhp, struct ftrace_func_probe, rcu);
+
+	if (entry->ops->free)
+		entry->ops->free(&entry->data);
+	kfree(entry);
+}
+
+
+int
+register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
+			      void *data)
+{
+	struct ftrace_func_probe *entry;
+	struct ftrace_page *pg;
+	struct dyn_ftrace *rec;
+	int type, len, not;
+	unsigned long key;
+	int count = 0;
+	char *search;
+
+	type = ftrace_setup_glob(glob, strlen(glob), &search, &not);
+	len = strlen(search);
+
+	/* we do not support '!' for function probes */
+	if (WARN_ON(not))
+		return -EINVAL;
+
+	mutex_lock(&ftrace_lock);
+	do_for_each_ftrace_rec(pg, rec) {
+
+		if (rec->flags & FTRACE_FL_FAILED)
+			continue;
+
+		if (!ftrace_match_record(rec, search, len, type))
+			continue;
+
+		entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+		if (!entry) {
+			/* If we did not process any, then return error */
+			if (!count)
+				count = -ENOMEM;
+			goto out_unlock;
+		}
+
+		count++;
+
+		entry->data = data;
+
+		/*
+		 * The caller might want to do something special
+		 * for each function we find. We call the callback
+		 * to give the caller an opportunity to do so.
+		 */
+		if (ops->callback) {
+			if (ops->callback(rec->ip, &entry->data) < 0) {
+				/* caller does not like this func */
+				kfree(entry);
 				continue;
-			kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
-			switch (type) {
-			case MATCH_FULL:
-				if (strcmp(str, buff) == 0)
-					matched = 1;
-				break;
-			case MATCH_FRONT_ONLY:
-				if (memcmp(str, buff, match) == 0)
-					matched = 1;
-				break;
-			case MATCH_MIDDLE_ONLY:
-				if (strstr(str, search))
-					matched = 1;
-				break;
-			case MATCH_END_ONLY:
-				ptr = strstr(str, search);
-				if (ptr && (ptr[search_len] == 0))
-					matched = 1;
-				break;
-			}
-			if (matched) {
-				if (not)
-					rec->flags &= ~flag;
-				else
-					rec->flags |= flag;
 			}
 		}
-		pg = pg->next;
+
+		entry->ops = ops;
+		entry->ip = rec->ip;
+
+		key = hash_long(entry->ip, FTRACE_HASH_BITS);
+		hlist_add_head_rcu(&entry->node, &ftrace_func_hash[key]);
+
+	} while_for_each_ftrace_rec();
+	__enable_ftrace_function_probe();
+
+ out_unlock:
+	mutex_unlock(&ftrace_lock);
+
+	return count;
+}
+
+enum {
+	PROBE_TEST_FUNC		= 1,
+	PROBE_TEST_DATA		= 2
+};
+
+static void
+__unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
+				  void *data, int flags)
+{
+	struct ftrace_func_probe *entry;
+	struct hlist_node *n, *tmp;
+	char str[KSYM_SYMBOL_LEN];
+	int type = MATCH_FULL;
+	int i, len = 0;
+	char *search;
+
+	if (glob && (strcmp(glob, "*") || !strlen(glob)))
+		glob = NULL;
+	else {
+		int not;
+
+		type = ftrace_setup_glob(glob, strlen(glob), &search, &not);
+		len = strlen(search);
+
+		/* we do not support '!' for function probes */
+		if (WARN_ON(not))
+			return;
 	}
-	spin_unlock(&ftrace_lock);
+
+	mutex_lock(&ftrace_lock);
+	for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) {
+		struct hlist_head *hhd = &ftrace_func_hash[i];
+
+		hlist_for_each_entry_safe(entry, n, tmp, hhd, node) {
+
+			/* break up if statements for readability */
+			if ((flags & PROBE_TEST_FUNC) && entry->ops != ops)
+				continue;
+
+			if ((flags & PROBE_TEST_DATA) && entry->data != data)
+				continue;
+
+			/* do this last, since it is the most expensive */
+			if (glob) {
+				kallsyms_lookup(entry->ip, NULL, NULL,
+						NULL, str);
+				if (!ftrace_match(str, glob, len, type))
+					continue;
+			}
+
+			hlist_del(&entry->node);
+			call_rcu(&entry->rcu, ftrace_free_entry_rcu);
+		}
+	}
+	__disable_ftrace_function_probe();
+	mutex_unlock(&ftrace_lock);
+}
+
+void
+unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
+				void *data)
+{
+	__unregister_ftrace_function_probe(glob, ops, data,
+					  PROBE_TEST_FUNC | PROBE_TEST_DATA);
+}
+
+void
+unregister_ftrace_function_probe_func(char *glob, struct ftrace_probe_ops *ops)
+{
+	__unregister_ftrace_function_probe(glob, ops, NULL, PROBE_TEST_FUNC);
+}
+
+void unregister_ftrace_function_probe_all(char *glob)
+{
+	__unregister_ftrace_function_probe(glob, NULL, NULL, 0);
+}
+
+static LIST_HEAD(ftrace_commands);
+static DEFINE_MUTEX(ftrace_cmd_mutex);
+
+int register_ftrace_command(struct ftrace_func_command *cmd)
+{
+	struct ftrace_func_command *p;
+	int ret = 0;
+
+	mutex_lock(&ftrace_cmd_mutex);
+	list_for_each_entry(p, &ftrace_commands, list) {
+		if (strcmp(cmd->name, p->name) == 0) {
+			ret = -EBUSY;
+			goto out_unlock;
+		}
+	}
+	list_add(&cmd->list, &ftrace_commands);
+ out_unlock:
+	mutex_unlock(&ftrace_cmd_mutex);
+
+	return ret;
+}
+
+int unregister_ftrace_command(struct ftrace_func_command *cmd)
+{
+	struct ftrace_func_command *p, *n;
+	int ret = -ENODEV;
+
+	mutex_lock(&ftrace_cmd_mutex);
+	list_for_each_entry_safe(p, n, &ftrace_commands, list) {
+		if (strcmp(cmd->name, p->name) == 0) {
+			ret = 0;
+			list_del_init(&p->list);
+			goto out_unlock;
+		}
+	}
+ out_unlock:
+	mutex_unlock(&ftrace_cmd_mutex);
+
+	return ret;
+}
+
+static int ftrace_process_regex(char *buff, int len, int enable)
+{
+	char *func, *command, *next = buff;
+	struct ftrace_func_command *p;
+	int ret = -EINVAL;
+
+	func = strsep(&next, ":");
+
+	if (!next) {
+		ftrace_match_records(func, len, enable);
+		return 0;
+	}
+
+	/* command found */
+
+	command = strsep(&next, ":");
+
+	mutex_lock(&ftrace_cmd_mutex);
+	list_for_each_entry(p, &ftrace_commands, list) {
+		if (strcmp(p->name, command) == 0) {
+			ret = p->func(func, command, next, enable);
+			goto out_unlock;
+		}
+	}
+ out_unlock:
+	mutex_unlock(&ftrace_cmd_mutex);
+
+	return ret;
 }
 
 static ssize_t
@@ -1187,7 +1748,10 @@
 	if (isspace(ch)) {
 		iter->filtered++;
 		iter->buffer[iter->buffer_idx] = 0;
-		ftrace_match(iter->buffer, iter->buffer_idx, enable);
+		ret = ftrace_process_regex(iter->buffer,
+					   iter->buffer_idx, enable);
+		if (ret)
+			goto out;
 		iter->buffer_idx = 0;
 	} else
 		iter->flags |= FTRACE_ITER_CONT;
@@ -1226,7 +1790,7 @@
 	if (reset)
 		ftrace_filter_reset(enable);
 	if (buf)
-		ftrace_match(buf, len, enable);
+		ftrace_match_records(buf, len, enable);
 	mutex_unlock(&ftrace_regex_lock);
 }
 
@@ -1276,15 +1840,13 @@
 	if (iter->buffer_idx) {
 		iter->filtered++;
 		iter->buffer[iter->buffer_idx] = 0;
-		ftrace_match(iter->buffer, iter->buffer_idx, enable);
+		ftrace_match_records(iter->buffer, iter->buffer_idx, enable);
 	}
 
-	mutex_lock(&ftrace_sysctl_lock);
-	mutex_lock(&ftrace_start_lock);
+	mutex_lock(&ftrace_lock);
 	if (ftrace_start_up && ftrace_enabled)
 		ftrace_run_update_code(FTRACE_ENABLE_CALLS);
-	mutex_unlock(&ftrace_start_lock);
-	mutex_unlock(&ftrace_sysctl_lock);
+	mutex_unlock(&ftrace_lock);
 
 	kfree(iter);
 	mutex_unlock(&ftrace_regex_lock);
@@ -1303,31 +1865,31 @@
 	return ftrace_regex_release(inode, file, 0);
 }
 
-static struct file_operations ftrace_avail_fops = {
+static const struct file_operations ftrace_avail_fops = {
 	.open = ftrace_avail_open,
 	.read = seq_read,
 	.llseek = seq_lseek,
 	.release = ftrace_avail_release,
 };
 
-static struct file_operations ftrace_failures_fops = {
+static const struct file_operations ftrace_failures_fops = {
 	.open = ftrace_failures_open,
 	.read = seq_read,
 	.llseek = seq_lseek,
 	.release = ftrace_avail_release,
 };
 
-static struct file_operations ftrace_filter_fops = {
+static const struct file_operations ftrace_filter_fops = {
 	.open = ftrace_filter_open,
-	.read = ftrace_regex_read,
+	.read = seq_read,
 	.write = ftrace_filter_write,
 	.llseek = ftrace_regex_lseek,
 	.release = ftrace_filter_release,
 };
 
-static struct file_operations ftrace_notrace_fops = {
+static const struct file_operations ftrace_notrace_fops = {
 	.open = ftrace_notrace_open,
-	.read = ftrace_regex_read,
+	.read = seq_read,
 	.write = ftrace_notrace_write,
 	.llseek = ftrace_regex_lseek,
 	.release = ftrace_notrace_release,
@@ -1360,6 +1922,10 @@
 
 	mutex_lock(&graph_lock);
 
+	/* Nothing, tell g_show to print all functions are enabled */
+	if (!ftrace_graph_count && !*pos)
+		return (void *)1;
+
 	p = g_next(m, p, pos);
 
 	return p;
@@ -1378,6 +1944,11 @@
 	if (!ptr)
 		return 0;
 
+	if (ptr == (unsigned long *)1) {
+		seq_printf(m, "#### all functions enabled ####\n");
+		return 0;
+	}
+
 	kallsyms_lookup(*ptr, NULL, NULL, NULL, str);
 
 	seq_printf(m, "%s\n", str);
@@ -1420,53 +1991,53 @@
 	return ret;
 }
 
-static ssize_t
-ftrace_graph_read(struct file *file, char __user *ubuf,
-		       size_t cnt, loff_t *ppos)
-{
-	if (file->f_mode & FMODE_READ)
-		return seq_read(file, ubuf, cnt, ppos);
-	else
-		return -EPERM;
-}
-
 static int
-ftrace_set_func(unsigned long *array, int idx, char *buffer)
+ftrace_set_func(unsigned long *array, int *idx, char *buffer)
 {
-	char str[KSYM_SYMBOL_LEN];
 	struct dyn_ftrace *rec;
 	struct ftrace_page *pg;
+	int search_len;
 	int found = 0;
-	int i, j;
+	int type, not;
+	char *search;
+	bool exists;
+	int i;
 
 	if (ftrace_disabled)
 		return -ENODEV;
 
-	/* should not be called from interrupt context */
-	spin_lock(&ftrace_lock);
+	/* decode regex */
+	type = ftrace_setup_glob(buffer, strlen(buffer), &search, &not);
+	if (not)
+		return -EINVAL;
 
-	for (pg = ftrace_pages_start; pg; pg = pg->next) {
-		for (i = 0; i < pg->index; i++) {
-			rec = &pg->records[i];
+	search_len = strlen(search);
 
-			if (rec->flags & (FTRACE_FL_FAILED | FTRACE_FL_FREE))
-				continue;
+	mutex_lock(&ftrace_lock);
+	do_for_each_ftrace_rec(pg, rec) {
 
-			kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
-			if (strcmp(str, buffer) == 0) {
+		if (*idx >= FTRACE_GRAPH_MAX_FUNCS)
+			break;
+
+		if (rec->flags & (FTRACE_FL_FAILED | FTRACE_FL_FREE))
+			continue;
+
+		if (ftrace_match_record(rec, search, search_len, type)) {
+			/* ensure it is not already in the array */
+			exists = false;
+			for (i = 0; i < *idx; i++)
+				if (array[i] == rec->ip) {
+					exists = true;
+					break;
+				}
+			if (!exists) {
+				array[(*idx)++] = rec->ip;
 				found = 1;
-				for (j = 0; j < idx; j++)
-					if (array[j] == rec->ip) {
-						found = 0;
-						break;
-					}
-				if (found)
-					array[idx] = rec->ip;
-				break;
 			}
 		}
-	}
-	spin_unlock(&ftrace_lock);
+	} while_for_each_ftrace_rec();
+
+	mutex_unlock(&ftrace_lock);
 
 	return found ? 0 : -EINVAL;
 }
@@ -1534,13 +2105,11 @@
 	}
 	buffer[index] = 0;
 
-	/* we allow only one at a time */
-	ret = ftrace_set_func(array, ftrace_graph_count, buffer);
+	/* we allow only one expression at a time */
+	ret = ftrace_set_func(array, &ftrace_graph_count, buffer);
 	if (ret)
 		goto out;
 
-	ftrace_graph_count++;
-
 	file->f_pos += read;
 
 	ret = read;
@@ -1552,7 +2121,7 @@
 
 static const struct file_operations ftrace_graph_fops = {
 	.open = ftrace_graph_open,
-	.read = ftrace_graph_read,
+	.read = seq_read,
 	.write = ftrace_graph_write,
 };
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
@@ -1604,7 +2173,7 @@
 	unsigned long addr;
 	unsigned long flags;
 
-	mutex_lock(&ftrace_start_lock);
+	mutex_lock(&ftrace_lock);
 	p = start;
 	while (p < end) {
 		addr = ftrace_call_adjust(*p++);
@@ -1623,7 +2192,7 @@
 	local_irq_save(flags);
 	ftrace_update_code(mod);
 	local_irq_restore(flags);
-	mutex_unlock(&ftrace_start_lock);
+	mutex_unlock(&ftrace_lock);
 
 	return 0;
 }
@@ -1700,7 +2269,7 @@
 	if (ftrace_pid_trace == ftrace_swapper_pid)
 		r = sprintf(buf, "swapper tasks\n");
 	else if (ftrace_pid_trace)
-		r = sprintf(buf, "%u\n", pid_nr(ftrace_pid_trace));
+		r = sprintf(buf, "%u\n", pid_vnr(ftrace_pid_trace));
 	else
 		r = sprintf(buf, "no pid\n");
 
@@ -1796,7 +2365,7 @@
 	if (ret < 0)
 		return ret;
 
-	mutex_lock(&ftrace_start_lock);
+	mutex_lock(&ftrace_lock);
 	if (val < 0) {
 		/* disable pid tracing */
 		if (!ftrace_pid_trace)
@@ -1835,12 +2404,12 @@
 	ftrace_startup_enable(0);
 
  out:
-	mutex_unlock(&ftrace_start_lock);
+	mutex_unlock(&ftrace_lock);
 
 	return cnt;
 }
 
-static struct file_operations ftrace_pid_fops = {
+static const struct file_operations ftrace_pid_fops = {
 	.read = ftrace_pid_read,
 	.write = ftrace_pid_write,
 };
@@ -1863,7 +2432,6 @@
 			   "'set_ftrace_pid' entry\n");
 	return 0;
 }
-
 fs_initcall(ftrace_init_debugfs);
 
 /**
@@ -1898,17 +2466,17 @@
 	if (unlikely(ftrace_disabled))
 		return -1;
 
-	mutex_lock(&ftrace_sysctl_lock);
+	mutex_lock(&ftrace_lock);
 
 	ret = __register_ftrace_function(ops);
 	ftrace_startup(0);
 
-	mutex_unlock(&ftrace_sysctl_lock);
+	mutex_unlock(&ftrace_lock);
 	return ret;
 }
 
 /**
- * unregister_ftrace_function - unresgister a function for profiling.
+ * unregister_ftrace_function - unregister a function for profiling.
  * @ops - ops structure that holds the function to unregister
  *
  * Unregister a function that was added to be called by ftrace profiling.
@@ -1917,10 +2485,10 @@
 {
 	int ret;
 
-	mutex_lock(&ftrace_sysctl_lock);
+	mutex_lock(&ftrace_lock);
 	ret = __unregister_ftrace_function(ops);
 	ftrace_shutdown(0);
-	mutex_unlock(&ftrace_sysctl_lock);
+	mutex_unlock(&ftrace_lock);
 
 	return ret;
 }
@@ -1935,7 +2503,7 @@
 	if (unlikely(ftrace_disabled))
 		return -ENODEV;
 
-	mutex_lock(&ftrace_sysctl_lock);
+	mutex_lock(&ftrace_lock);
 
 	ret  = proc_dointvec(table, write, file, buffer, lenp, ppos);
 
@@ -1964,7 +2532,7 @@
 	}
 
  out:
-	mutex_unlock(&ftrace_sysctl_lock);
+	mutex_unlock(&ftrace_lock);
 	return ret;
 }
 
@@ -2029,6 +2597,38 @@
 	return ret;
 }
 
+static void
+ftrace_graph_probe_sched_switch(struct rq *__rq, struct task_struct *prev,
+				struct task_struct *next)
+{
+	unsigned long long timestamp;
+	int index;
+
+	/*
+	 * Does the user want to count the time a function was asleep.
+	 * If so, do not update the time stamps.
+	 */
+	if (trace_flags & TRACE_ITER_SLEEP_TIME)
+		return;
+
+	timestamp = trace_clock_local();
+
+	prev->ftrace_timestamp = timestamp;
+
+	/* only process tasks that we timestamped */
+	if (!next->ftrace_timestamp)
+		return;
+
+	/*
+	 * Update all the counters in next to make up for the
+	 * time next was sleeping.
+	 */
+	timestamp -= next->ftrace_timestamp;
+
+	for (index = next->curr_ret_stack; index >= 0; index--)
+		next->ret_stack[index].calltime += timestamp;
+}
+
 /* Allocate a return stack for each task */
 static int start_graph_tracing(void)
 {
@@ -2050,6 +2650,13 @@
 		ret = alloc_retstack_tasklist(ret_stack_list);
 	} while (ret == -EAGAIN);
 
+	if (!ret) {
+		ret = register_trace_sched_switch(ftrace_graph_probe_sched_switch);
+		if (ret)
+			pr_info("ftrace_graph: Couldn't activate tracepoint"
+				" probe to kernel_sched_switch\n");
+	}
+
 	kfree(ret_stack_list);
 	return ret;
 }
@@ -2080,7 +2687,13 @@
 {
 	int ret = 0;
 
-	mutex_lock(&ftrace_sysctl_lock);
+	mutex_lock(&ftrace_lock);
+
+	/* we currently allow only one tracer registered at a time */
+	if (atomic_read(&ftrace_graph_active)) {
+		ret = -EBUSY;
+		goto out;
+	}
 
 	ftrace_suspend_notifier.notifier_call = ftrace_suspend_notifier_call;
 	register_pm_notifier(&ftrace_suspend_notifier);
@@ -2098,21 +2711,26 @@
 	ftrace_startup(FTRACE_START_FUNC_RET);
 
 out:
-	mutex_unlock(&ftrace_sysctl_lock);
+	mutex_unlock(&ftrace_lock);
 	return ret;
 }
 
 void unregister_ftrace_graph(void)
 {
-	mutex_lock(&ftrace_sysctl_lock);
+	mutex_lock(&ftrace_lock);
+
+	if (!unlikely(atomic_read(&ftrace_graph_active)))
+		goto out;
 
 	atomic_dec(&ftrace_graph_active);
+	unregister_trace_sched_switch(ftrace_graph_probe_sched_switch);
 	ftrace_graph_return = (trace_func_graph_ret_t)ftrace_stub;
 	ftrace_graph_entry = ftrace_graph_entry_stub;
 	ftrace_shutdown(FTRACE_STOP_FUNC_RET);
 	unregister_pm_notifier(&ftrace_suspend_notifier);
 
-	mutex_unlock(&ftrace_sysctl_lock);
+ out:
+	mutex_unlock(&ftrace_lock);
 }
 
 /* Allocate a return stack for newly created task */
@@ -2127,6 +2745,7 @@
 		t->curr_ret_stack = -1;
 		atomic_set(&t->tracing_graph_pause, 0);
 		atomic_set(&t->trace_overrun, 0);
+		t->ftrace_timestamp = 0;
 	} else
 		t->ret_stack = NULL;
 }
diff --git a/kernel/trace/kmemtrace.c b/kernel/trace/kmemtrace.c
new file mode 100644
index 0000000..ae201b3
--- /dev/null
+++ b/kernel/trace/kmemtrace.c
@@ -0,0 +1,339 @@
+/*
+ * Memory allocator tracing
+ *
+ * Copyright (C) 2008 Eduard - Gabriel Munteanu
+ * Copyright (C) 2008 Pekka Enberg <penberg@cs.helsinki.fi>
+ * Copyright (C) 2008 Frederic Weisbecker <fweisbec@gmail.com>
+ */
+
+#include <linux/dcache.h>
+#include <linux/debugfs.h>
+#include <linux/fs.h>
+#include <linux/seq_file.h>
+#include <trace/kmemtrace.h>
+
+#include "trace.h"
+#include "trace_output.h"
+
+/* Select an alternative, minimalistic output than the original one */
+#define TRACE_KMEM_OPT_MINIMAL	0x1
+
+static struct tracer_opt kmem_opts[] = {
+	/* Default disable the minimalistic output */
+	{ TRACER_OPT(kmem_minimalistic, TRACE_KMEM_OPT_MINIMAL) },
+	{ }
+};
+
+static struct tracer_flags kmem_tracer_flags = {
+	.val = 0,
+	.opts = kmem_opts
+};
+
+
+static bool kmem_tracing_enabled __read_mostly;
+static struct trace_array *kmemtrace_array;
+
+static int kmem_trace_init(struct trace_array *tr)
+{
+	int cpu;
+	kmemtrace_array = tr;
+
+	for_each_cpu_mask(cpu, cpu_possible_map)
+		tracing_reset(tr, cpu);
+
+	kmem_tracing_enabled = true;
+
+	return 0;
+}
+
+static void kmem_trace_reset(struct trace_array *tr)
+{
+	kmem_tracing_enabled = false;
+}
+
+static void kmemtrace_headers(struct seq_file *s)
+{
+	/* Don't need headers for the original kmemtrace output */
+	if (!(kmem_tracer_flags.val & TRACE_KMEM_OPT_MINIMAL))
+		return;
+
+	seq_printf(s, "#\n");
+	seq_printf(s, "# ALLOC  TYPE  REQ   GIVEN  FLAGS     "
+			"      POINTER         NODE    CALLER\n");
+	seq_printf(s, "# FREE   |      |     |       |       "
+			"       |   |            |        |\n");
+	seq_printf(s, "# |\n\n");
+}
+
+/*
+ * The two following functions give the original output from kmemtrace,
+ * or something close to....perhaps they need some missing things
+ */
+static enum print_line_t
+kmemtrace_print_alloc_original(struct trace_iterator *iter,
+				struct kmemtrace_alloc_entry *entry)
+{
+	struct trace_seq *s = &iter->seq;
+	int ret;
+
+	/* Taken from the old linux/kmemtrace.h */
+	ret = trace_seq_printf(s, "type_id %d call_site %lu ptr %lu "
+	  "bytes_req %lu bytes_alloc %lu gfp_flags %lu node %d\n",
+	   entry->type_id, entry->call_site, (unsigned long) entry->ptr,
+	   (unsigned long) entry->bytes_req, (unsigned long) entry->bytes_alloc,
+	   (unsigned long) entry->gfp_flags, entry->node);
+
+	if (!ret)
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	return TRACE_TYPE_HANDLED;
+}
+
+static enum print_line_t
+kmemtrace_print_free_original(struct trace_iterator *iter,
+				struct kmemtrace_free_entry *entry)
+{
+	struct trace_seq *s = &iter->seq;
+	int ret;
+
+	/* Taken from the old linux/kmemtrace.h */
+	ret = trace_seq_printf(s, "type_id %d call_site %lu ptr %lu\n",
+	   entry->type_id, entry->call_site, (unsigned long) entry->ptr);
+
+	if (!ret)
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	return TRACE_TYPE_HANDLED;
+}
+
+
+/* The two other following provide a more minimalistic output */
+static enum print_line_t
+kmemtrace_print_alloc_compress(struct trace_iterator *iter,
+					struct kmemtrace_alloc_entry *entry)
+{
+	struct trace_seq *s = &iter->seq;
+	int ret;
+
+	/* Alloc entry */
+	ret = trace_seq_printf(s, "  +      ");
+	if (!ret)
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	/* Type */
+	switch (entry->type_id) {
+	case KMEMTRACE_TYPE_KMALLOC:
+		ret = trace_seq_printf(s, "K   ");
+		break;
+	case KMEMTRACE_TYPE_CACHE:
+		ret = trace_seq_printf(s, "C   ");
+		break;
+	case KMEMTRACE_TYPE_PAGES:
+		ret = trace_seq_printf(s, "P   ");
+		break;
+	default:
+		ret = trace_seq_printf(s, "?   ");
+	}
+
+	if (!ret)
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	/* Requested */
+	ret = trace_seq_printf(s, "%4zu   ", entry->bytes_req);
+	if (!ret)
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	/* Allocated */
+	ret = trace_seq_printf(s, "%4zu   ", entry->bytes_alloc);
+	if (!ret)
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	/* Flags
+	 * TODO: would be better to see the name of the GFP flag names
+	 */
+	ret = trace_seq_printf(s, "%08x   ", entry->gfp_flags);
+	if (!ret)
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	/* Pointer to allocated */
+	ret = trace_seq_printf(s, "0x%tx   ", (ptrdiff_t)entry->ptr);
+	if (!ret)
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	/* Node */
+	ret = trace_seq_printf(s, "%4d   ", entry->node);
+	if (!ret)
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	/* Call site */
+	ret = seq_print_ip_sym(s, entry->call_site, 0);
+	if (!ret)
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	if (!trace_seq_printf(s, "\n"))
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	return TRACE_TYPE_HANDLED;
+}
+
+static enum print_line_t
+kmemtrace_print_free_compress(struct trace_iterator *iter,
+				struct kmemtrace_free_entry *entry)
+{
+	struct trace_seq *s = &iter->seq;
+	int ret;
+
+	/* Free entry */
+	ret = trace_seq_printf(s, "  -      ");
+	if (!ret)
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	/* Type */
+	switch (entry->type_id) {
+	case KMEMTRACE_TYPE_KMALLOC:
+		ret = trace_seq_printf(s, "K     ");
+		break;
+	case KMEMTRACE_TYPE_CACHE:
+		ret = trace_seq_printf(s, "C     ");
+		break;
+	case KMEMTRACE_TYPE_PAGES:
+		ret = trace_seq_printf(s, "P     ");
+		break;
+	default:
+		ret = trace_seq_printf(s, "?     ");
+	}
+
+	if (!ret)
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	/* Skip requested/allocated/flags */
+	ret = trace_seq_printf(s, "                       ");
+	if (!ret)
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	/* Pointer to allocated */
+	ret = trace_seq_printf(s, "0x%tx   ", (ptrdiff_t)entry->ptr);
+	if (!ret)
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	/* Skip node */
+	ret = trace_seq_printf(s, "       ");
+	if (!ret)
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	/* Call site */
+	ret = seq_print_ip_sym(s, entry->call_site, 0);
+	if (!ret)
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	if (!trace_seq_printf(s, "\n"))
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	return TRACE_TYPE_HANDLED;
+}
+
+static enum print_line_t kmemtrace_print_line(struct trace_iterator *iter)
+{
+	struct trace_entry *entry = iter->ent;
+
+	switch (entry->type) {
+	case TRACE_KMEM_ALLOC: {
+		struct kmemtrace_alloc_entry *field;
+		trace_assign_type(field, entry);
+		if (kmem_tracer_flags.val & TRACE_KMEM_OPT_MINIMAL)
+			return kmemtrace_print_alloc_compress(iter, field);
+		else
+			return kmemtrace_print_alloc_original(iter, field);
+	}
+
+	case TRACE_KMEM_FREE: {
+		struct kmemtrace_free_entry *field;
+		trace_assign_type(field, entry);
+		if (kmem_tracer_flags.val & TRACE_KMEM_OPT_MINIMAL)
+			return kmemtrace_print_free_compress(iter, field);
+		else
+			return kmemtrace_print_free_original(iter, field);
+	}
+
+	default:
+		return TRACE_TYPE_UNHANDLED;
+	}
+}
+
+/* Trace allocations */
+void kmemtrace_mark_alloc_node(enum kmemtrace_type_id type_id,
+			     unsigned long call_site,
+			     const void *ptr,
+			     size_t bytes_req,
+			     size_t bytes_alloc,
+			     gfp_t gfp_flags,
+			     int node)
+{
+	struct ring_buffer_event *event;
+	struct kmemtrace_alloc_entry *entry;
+	struct trace_array *tr = kmemtrace_array;
+
+	if (!kmem_tracing_enabled)
+		return;
+
+	event = trace_buffer_lock_reserve(tr, TRACE_KMEM_ALLOC,
+					  sizeof(*entry), 0, 0);
+	if (!event)
+		return;
+	entry	= ring_buffer_event_data(event);
+
+	entry->call_site = call_site;
+	entry->ptr = ptr;
+	entry->bytes_req = bytes_req;
+	entry->bytes_alloc = bytes_alloc;
+	entry->gfp_flags = gfp_flags;
+	entry->node	=	node;
+
+	trace_buffer_unlock_commit(tr, event, 0, 0);
+}
+EXPORT_SYMBOL(kmemtrace_mark_alloc_node);
+
+void kmemtrace_mark_free(enum kmemtrace_type_id type_id,
+		       unsigned long call_site,
+		       const void *ptr)
+{
+	struct ring_buffer_event *event;
+	struct kmemtrace_free_entry *entry;
+	struct trace_array *tr = kmemtrace_array;
+
+	if (!kmem_tracing_enabled)
+		return;
+
+	event = trace_buffer_lock_reserve(tr, TRACE_KMEM_FREE,
+					  sizeof(*entry), 0, 0);
+	if (!event)
+		return;
+	entry	= ring_buffer_event_data(event);
+	entry->type_id	= type_id;
+	entry->call_site = call_site;
+	entry->ptr = ptr;
+
+	trace_buffer_unlock_commit(tr, event, 0, 0);
+}
+EXPORT_SYMBOL(kmemtrace_mark_free);
+
+static struct tracer kmem_tracer __read_mostly = {
+	.name		= "kmemtrace",
+	.init		= kmem_trace_init,
+	.reset		= kmem_trace_reset,
+	.print_line	= kmemtrace_print_line,
+	.print_header = kmemtrace_headers,
+	.flags		= &kmem_tracer_flags
+};
+
+void kmemtrace_init(void)
+{
+	/* earliest opportunity to start kmem tracing */
+}
+
+static int __init init_kmem_tracer(void)
+{
+	return register_tracer(&kmem_tracer);
+}
+
+device_initcall(init_kmem_tracer);
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index bd38c5c..960cbf4 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -4,21 +4,92 @@
  * Copyright (C) 2008 Steven Rostedt <srostedt@redhat.com>
  */
 #include <linux/ring_buffer.h>
+#include <linux/trace_clock.h>
+#include <linux/ftrace_irq.h>
 #include <linux/spinlock.h>
 #include <linux/debugfs.h>
 #include <linux/uaccess.h>
+#include <linux/hardirq.h>
 #include <linux/module.h>
 #include <linux/percpu.h>
 #include <linux/mutex.h>
-#include <linux/sched.h>	/* used for sched_clock() (for now) */
 #include <linux/init.h>
 #include <linux/hash.h>
 #include <linux/list.h>
+#include <linux/cpu.h>
 #include <linux/fs.h>
 
 #include "trace.h"
 
 /*
+ * The ring buffer is made up of a list of pages. A separate list of pages is
+ * allocated for each CPU. A writer may only write to a buffer that is
+ * associated with the CPU it is currently executing on.  A reader may read
+ * from any per cpu buffer.
+ *
+ * The reader is special. For each per cpu buffer, the reader has its own
+ * reader page. When a reader has read the entire reader page, this reader
+ * page is swapped with another page in the ring buffer.
+ *
+ * Now, as long as the writer is off the reader page, the reader can do what
+ * ever it wants with that page. The writer will never write to that page
+ * again (as long as it is out of the ring buffer).
+ *
+ * Here's some silly ASCII art.
+ *
+ *   +------+
+ *   |reader|          RING BUFFER
+ *   |page  |
+ *   +------+        +---+   +---+   +---+
+ *                   |   |-->|   |-->|   |
+ *                   +---+   +---+   +---+
+ *                     ^               |
+ *                     |               |
+ *                     +---------------+
+ *
+ *
+ *   +------+
+ *   |reader|          RING BUFFER
+ *   |page  |------------------v
+ *   +------+        +---+   +---+   +---+
+ *                   |   |-->|   |-->|   |
+ *                   +---+   +---+   +---+
+ *                     ^               |
+ *                     |               |
+ *                     +---------------+
+ *
+ *
+ *   +------+
+ *   |reader|          RING BUFFER
+ *   |page  |------------------v
+ *   +------+        +---+   +---+   +---+
+ *      ^            |   |-->|   |-->|   |
+ *      |            +---+   +---+   +---+
+ *      |                              |
+ *      |                              |
+ *      +------------------------------+
+ *
+ *
+ *   +------+
+ *   |buffer|          RING BUFFER
+ *   |page  |------------------v
+ *   +------+        +---+   +---+   +---+
+ *      ^            |   |   |   |-->|   |
+ *      |   New      +---+   +---+   +---+
+ *      |  Reader------^               |
+ *      |   page                       |
+ *      +------------------------------+
+ *
+ *
+ * After we make this swap, the reader can hand this page off to the splice
+ * code and be done with it. It can even allocate a new page if it needs to
+ * and swap that into the ring buffer.
+ *
+ * We will be using cmpxchg soon to make all this lockless.
+ *
+ */
+
+/*
  * A fast way to enable or disable all ring buffers is to
  * call tracing_on or tracing_off. Turning off the ring buffers
  * prevents all ring buffers from being recorded to.
@@ -57,7 +128,9 @@
 	RB_BUFFERS_DISABLED	= 1 << RB_BUFFERS_DISABLED_BIT,
 };
 
-static long ring_buffer_flags __read_mostly = RB_BUFFERS_ON;
+static unsigned long ring_buffer_flags __read_mostly = RB_BUFFERS_ON;
+
+#define BUF_PAGE_HDR_SIZE offsetof(struct buffer_data_page, data)
 
 /**
  * tracing_on - enable all tracing buffers
@@ -89,42 +162,26 @@
  * tracing_off_permanent - permanently disable ring buffers
  *
  * This function, once called, will disable all ring buffers
- * permanenty.
+ * permanently.
  */
 void tracing_off_permanent(void)
 {
 	set_bit(RB_BUFFERS_DISABLED_BIT, &ring_buffer_flags);
 }
 
+/**
+ * tracing_is_on - show state of ring buffers enabled
+ */
+int tracing_is_on(void)
+{
+	return ring_buffer_flags == RB_BUFFERS_ON;
+}
+EXPORT_SYMBOL_GPL(tracing_is_on);
+
 #include "trace.h"
 
-/* Up this if you want to test the TIME_EXTENTS and normalization */
-#define DEBUG_SHIFT 0
-
-/* FIXME!!! */
-u64 ring_buffer_time_stamp(int cpu)
-{
-	u64 time;
-
-	preempt_disable_notrace();
-	/* shift to debug/test normalization and TIME_EXTENTS */
-	time = sched_clock() << DEBUG_SHIFT;
-	preempt_enable_no_resched_notrace();
-
-	return time;
-}
-EXPORT_SYMBOL_GPL(ring_buffer_time_stamp);
-
-void ring_buffer_normalize_time_stamp(int cpu, u64 *ts)
-{
-	/* Just stupid testing the normalize function and deltas */
-	*ts >>= DEBUG_SHIFT;
-}
-EXPORT_SYMBOL_GPL(ring_buffer_normalize_time_stamp);
-
-#define RB_EVNT_HDR_SIZE (sizeof(struct ring_buffer_event))
-#define RB_ALIGNMENT_SHIFT	2
-#define RB_ALIGNMENT		(1 << RB_ALIGNMENT_SHIFT)
+#define RB_EVNT_HDR_SIZE (offsetof(struct ring_buffer_event, array))
+#define RB_ALIGNMENT		4U
 #define RB_MAX_SMALL_DATA	28
 
 enum {
@@ -132,16 +189,65 @@
 	RB_LEN_TIME_STAMP = 16,
 };
 
-/* inline for ring buffer fast paths */
-static inline unsigned
-rb_event_length(struct ring_buffer_event *event)
+static inline int rb_null_event(struct ring_buffer_event *event)
+{
+	return event->type == RINGBUF_TYPE_PADDING && event->time_delta == 0;
+}
+
+static inline int rb_discarded_event(struct ring_buffer_event *event)
+{
+	return event->type == RINGBUF_TYPE_PADDING && event->time_delta;
+}
+
+static void rb_event_set_padding(struct ring_buffer_event *event)
+{
+	event->type = RINGBUF_TYPE_PADDING;
+	event->time_delta = 0;
+}
+
+/**
+ * ring_buffer_event_discard - discard an event in the ring buffer
+ * @buffer: the ring buffer
+ * @event: the event to discard
+ *
+ * Sometimes a event that is in the ring buffer needs to be ignored.
+ * This function lets the user discard an event in the ring buffer
+ * and then that event will not be read later.
+ *
+ * Note, it is up to the user to be careful with this, and protect
+ * against races. If the user discards an event that has been consumed
+ * it is possible that it could corrupt the ring buffer.
+ */
+void ring_buffer_event_discard(struct ring_buffer_event *event)
+{
+	event->type = RINGBUF_TYPE_PADDING;
+	/* time delta must be non zero */
+	if (!event->time_delta)
+		event->time_delta = 1;
+}
+
+static unsigned
+rb_event_data_length(struct ring_buffer_event *event)
 {
 	unsigned length;
 
+	if (event->len)
+		length = event->len * RB_ALIGNMENT;
+	else
+		length = event->array[0];
+	return length + RB_EVNT_HDR_SIZE;
+}
+
+/* inline for ring buffer fast paths */
+static unsigned
+rb_event_length(struct ring_buffer_event *event)
+{
 	switch (event->type) {
 	case RINGBUF_TYPE_PADDING:
-		/* undefined */
-		return -1;
+		if (rb_null_event(event))
+			/* undefined */
+			return -1;
+		return rb_event_data_length(event);
 
 	case RINGBUF_TYPE_TIME_EXTEND:
 		return RB_LEN_TIME_EXTEND;
@@ -150,11 +256,7 @@
 		return RB_LEN_TIME_STAMP;
 
 	case RINGBUF_TYPE_DATA:
-		if (event->len)
-			length = event->len << RB_ALIGNMENT_SHIFT;
-		else
-			length = event->array[0];
-		return length + RB_EVNT_HDR_SIZE;
+		return rb_event_data_length(event);
 	default:
 		BUG();
 	}
@@ -179,7 +281,7 @@
 EXPORT_SYMBOL_GPL(ring_buffer_event_length);
 
 /* inline for ring buffer fast paths */
-static inline void *
+static void *
 rb_event_data(struct ring_buffer_event *event)
 {
 	BUG_ON(event->type != RINGBUF_TYPE_DATA);
@@ -209,7 +311,7 @@
 
 struct buffer_data_page {
 	u64		 time_stamp;	/* page time stamp */
-	local_t		 commit;	/* write commited index */
+	local_t		 commit;	/* write committed index */
 	unsigned char	 data[];	/* data of buffer page */
 };
 
@@ -225,14 +327,25 @@
 	local_set(&bpage->commit, 0);
 }
 
+/**
+ * ring_buffer_page_len - the size of data on the page.
+ * @page: The page to read
+ *
+ * Returns the amount of data on the page, including buffer page header.
+ */
+size_t ring_buffer_page_len(void *page)
+{
+	return local_read(&((struct buffer_data_page *)page)->commit)
+		+ BUF_PAGE_HDR_SIZE;
+}
+
 /*
  * Also stolen from mm/slob.c. Thanks to Mathieu Desnoyers for pointing
  * this issue out.
  */
-static inline void free_buffer_page(struct buffer_page *bpage)
+static void free_buffer_page(struct buffer_page *bpage)
 {
-	if (bpage->page)
-		free_page((unsigned long)bpage->page);
+	free_page((unsigned long)bpage->page);
 	kfree(bpage);
 }
 
@@ -246,7 +359,7 @@
 	return 0;
 }
 
-#define BUF_PAGE_SIZE (PAGE_SIZE - offsetof(struct buffer_data_page, data))
+#define BUF_PAGE_SIZE (PAGE_SIZE - BUF_PAGE_HDR_SIZE)
 
 /*
  * head_page == tail_page && head == tail then buffer is empty.
@@ -260,7 +373,7 @@
 	struct list_head		pages;
 	struct buffer_page		*head_page;	/* read from head */
 	struct buffer_page		*tail_page;	/* write to tail */
-	struct buffer_page		*commit_page;	/* commited pages */
+	struct buffer_page		*commit_page;	/* committed pages */
 	struct buffer_page		*reader_page;
 	unsigned long			overrun;
 	unsigned long			entries;
@@ -273,12 +386,17 @@
 	unsigned			pages;
 	unsigned			flags;
 	int				cpus;
-	cpumask_var_t			cpumask;
 	atomic_t			record_disabled;
+	cpumask_var_t			cpumask;
 
 	struct mutex			mutex;
 
 	struct ring_buffer_per_cpu	**buffers;
+
+#ifdef CONFIG_HOTPLUG_CPU
+	struct notifier_block		cpu_notify;
+#endif
+	u64				(*clock)(void);
 };
 
 struct ring_buffer_iter {
@@ -299,11 +417,35 @@
 		_____ret;					\
 	})
 
+/* Up this if you want to test the TIME_EXTENTS and normalization */
+#define DEBUG_SHIFT 0
+
+u64 ring_buffer_time_stamp(struct ring_buffer *buffer, int cpu)
+{
+	u64 time;
+
+	preempt_disable_notrace();
+	/* shift to debug/test normalization and TIME_EXTENTS */
+	time = buffer->clock() << DEBUG_SHIFT;
+	preempt_enable_no_resched_notrace();
+
+	return time;
+}
+EXPORT_SYMBOL_GPL(ring_buffer_time_stamp);
+
+void ring_buffer_normalize_time_stamp(struct ring_buffer *buffer,
+				      int cpu, u64 *ts)
+{
+	/* Just stupid testing the normalize function and deltas */
+	*ts >>= DEBUG_SHIFT;
+}
+EXPORT_SYMBOL_GPL(ring_buffer_normalize_time_stamp);
+
 /**
  * check_pages - integrity check of buffer pages
  * @cpu_buffer: CPU buffer with pages to test
  *
- * As a safty measure we check to make sure the data pages have not
+ * As a safety measure we check to make sure the data pages have not
  * been corrupted.
  */
 static int rb_check_pages(struct ring_buffer_per_cpu *cpu_buffer)
@@ -421,7 +563,6 @@
 	struct list_head *head = &cpu_buffer->pages;
 	struct buffer_page *bpage, *tmp;
 
-	list_del_init(&cpu_buffer->reader_page->list);
 	free_buffer_page(cpu_buffer->reader_page);
 
 	list_for_each_entry_safe(bpage, tmp, head, list) {
@@ -437,6 +578,11 @@
  */
 extern int ring_buffer_page_too_big(void);
 
+#ifdef CONFIG_HOTPLUG_CPU
+static int rb_cpu_notify(struct notifier_block *self,
+			 unsigned long action, void *hcpu);
+#endif
+
 /**
  * ring_buffer_alloc - allocate a new ring_buffer
  * @size: the size in bytes per cpu that is needed.
@@ -469,12 +615,23 @@
 
 	buffer->pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE);
 	buffer->flags = flags;
+	buffer->clock = trace_clock_local;
 
 	/* need at least two pages */
 	if (buffer->pages == 1)
 		buffer->pages++;
 
+	/*
+	 * In case of non-hotplug cpu, if the ring-buffer is allocated
+	 * in early initcall, it will not be notified of secondary cpus.
+	 * In that off case, we need to allocate for all possible cpus.
+	 */
+#ifdef CONFIG_HOTPLUG_CPU
+	get_online_cpus();
+	cpumask_copy(buffer->cpumask, cpu_online_mask);
+#else
 	cpumask_copy(buffer->cpumask, cpu_possible_mask);
+#endif
 	buffer->cpus = nr_cpu_ids;
 
 	bsize = sizeof(void *) * nr_cpu_ids;
@@ -490,6 +647,13 @@
 			goto fail_free_buffers;
 	}
 
+#ifdef CONFIG_HOTPLUG_CPU
+	buffer->cpu_notify.notifier_call = rb_cpu_notify;
+	buffer->cpu_notify.priority = 0;
+	register_cpu_notifier(&buffer->cpu_notify);
+#endif
+
+	put_online_cpus();
 	mutex_init(&buffer->mutex);
 
 	return buffer;
@@ -503,6 +667,7 @@
 
  fail_free_cpumask:
 	free_cpumask_var(buffer->cpumask);
+	put_online_cpus();
 
  fail_free_buffer:
 	kfree(buffer);
@@ -519,15 +684,29 @@
 {
 	int cpu;
 
+	get_online_cpus();
+
+#ifdef CONFIG_HOTPLUG_CPU
+	unregister_cpu_notifier(&buffer->cpu_notify);
+#endif
+
 	for_each_buffer_cpu(buffer, cpu)
 		rb_free_cpu_buffer(buffer->buffers[cpu]);
 
+	put_online_cpus();
+
 	free_cpumask_var(buffer->cpumask);
 
 	kfree(buffer);
 }
 EXPORT_SYMBOL_GPL(ring_buffer_free);
 
+void ring_buffer_set_clock(struct ring_buffer *buffer,
+			   u64 (*clock)(void))
+{
+	buffer->clock = clock;
+}
+
 static void rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer);
 
 static void
@@ -627,16 +806,15 @@
 		return size;
 
 	mutex_lock(&buffer->mutex);
+	get_online_cpus();
 
 	nr_pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE);
 
 	if (size < buffer_size) {
 
 		/* easy case, just free pages */
-		if (RB_WARN_ON(buffer, nr_pages >= buffer->pages)) {
-			mutex_unlock(&buffer->mutex);
-			return -1;
-		}
+		if (RB_WARN_ON(buffer, nr_pages >= buffer->pages))
+			goto out_fail;
 
 		rm_pages = buffer->pages - nr_pages;
 
@@ -655,10 +833,8 @@
 	 * add these pages to the cpu_buffers. Otherwise we just free
 	 * them all and return -ENOMEM;
 	 */
-	if (RB_WARN_ON(buffer, nr_pages <= buffer->pages)) {
-		mutex_unlock(&buffer->mutex);
-		return -1;
-	}
+	if (RB_WARN_ON(buffer, nr_pages <= buffer->pages))
+		goto out_fail;
 
 	new_pages = nr_pages - buffer->pages;
 
@@ -683,13 +859,12 @@
 		rb_insert_pages(cpu_buffer, &pages, new_pages);
 	}
 
-	if (RB_WARN_ON(buffer, !list_empty(&pages))) {
-		mutex_unlock(&buffer->mutex);
-		return -1;
-	}
+	if (RB_WARN_ON(buffer, !list_empty(&pages)))
+		goto out_fail;
 
  out:
 	buffer->pages = nr_pages;
+	put_online_cpus();
 	mutex_unlock(&buffer->mutex);
 
 	return size;
@@ -699,16 +874,21 @@
 		list_del_init(&bpage->list);
 		free_buffer_page(bpage);
 	}
+	put_online_cpus();
 	mutex_unlock(&buffer->mutex);
 	return -ENOMEM;
+
+	/*
+	 * Something went totally wrong, and we are too paranoid
+	 * to even clean up the mess.
+	 */
+ out_fail:
+	put_online_cpus();
+	mutex_unlock(&buffer->mutex);
+	return -1;
 }
 EXPORT_SYMBOL_GPL(ring_buffer_resize);
 
-static inline int rb_null_event(struct ring_buffer_event *event)
-{
-	return event->type == RINGBUF_TYPE_PADDING;
-}
-
 static inline void *
 __rb_data_page_index(struct buffer_data_page *bpage, unsigned index)
 {
@@ -811,7 +991,7 @@
 	return (addr & ~PAGE_MASK) - (PAGE_SIZE - BUF_PAGE_SIZE);
 }
 
-static inline int
+static int
 rb_is_commit(struct ring_buffer_per_cpu *cpu_buffer,
 	     struct ring_buffer_event *event)
 {
@@ -825,7 +1005,7 @@
 		rb_commit_index(cpu_buffer) == index;
 }
 
-static inline void
+static void
 rb_set_commit_event(struct ring_buffer_per_cpu *cpu_buffer,
 		    struct ring_buffer_event *event)
 {
@@ -850,7 +1030,7 @@
 	local_set(&cpu_buffer->commit_page->page->commit, index);
 }
 
-static inline void
+static void
 rb_set_commit_to_write(struct ring_buffer_per_cpu *cpu_buffer)
 {
 	/*
@@ -896,7 +1076,7 @@
 	cpu_buffer->reader_page->read = 0;
 }
 
-static inline void rb_inc_iter(struct ring_buffer_iter *iter)
+static void rb_inc_iter(struct ring_buffer_iter *iter)
 {
 	struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer;
 
@@ -926,7 +1106,7 @@
  * and with this, we can determine what to place into the
  * data field.
  */
-static inline void
+static void
 rb_update_event(struct ring_buffer_event *event,
 			 unsigned type, unsigned length)
 {
@@ -938,15 +1118,11 @@
 		break;
 
 	case RINGBUF_TYPE_TIME_EXTEND:
-		event->len =
-			(RB_LEN_TIME_EXTEND + (RB_ALIGNMENT-1))
-			>> RB_ALIGNMENT_SHIFT;
+		event->len = DIV_ROUND_UP(RB_LEN_TIME_EXTEND, RB_ALIGNMENT);
 		break;
 
 	case RINGBUF_TYPE_TIME_STAMP:
-		event->len =
-			(RB_LEN_TIME_STAMP + (RB_ALIGNMENT-1))
-			>> RB_ALIGNMENT_SHIFT;
+		event->len = DIV_ROUND_UP(RB_LEN_TIME_STAMP, RB_ALIGNMENT);
 		break;
 
 	case RINGBUF_TYPE_DATA:
@@ -955,16 +1131,14 @@
 			event->len = 0;
 			event->array[0] = length;
 		} else
-			event->len =
-				(length + (RB_ALIGNMENT-1))
-				>> RB_ALIGNMENT_SHIFT;
+			event->len = DIV_ROUND_UP(length, RB_ALIGNMENT);
 		break;
 	default:
 		BUG();
 	}
 }
 
-static inline unsigned rb_calculate_event_length(unsigned length)
+static unsigned rb_calculate_event_length(unsigned length)
 {
 	struct ring_buffer_event event; /* Used only for sizeof array */
 
@@ -990,6 +1164,7 @@
 	struct ring_buffer *buffer = cpu_buffer->buffer;
 	struct ring_buffer_event *event;
 	unsigned long flags;
+	bool lock_taken = false;
 
 	commit_page = cpu_buffer->commit_page;
 	/* we just need to protect against interrupts */
@@ -1003,7 +1178,30 @@
 		struct buffer_page *next_page = tail_page;
 
 		local_irq_save(flags);
-		__raw_spin_lock(&cpu_buffer->lock);
+		/*
+		 * Since the write to the buffer is still not
+		 * fully lockless, we must be careful with NMIs.
+		 * The locks in the writers are taken when a write
+		 * crosses to a new page. The locks protect against
+		 * races with the readers (this will soon be fixed
+		 * with a lockless solution).
+		 *
+		 * Because we can not protect against NMIs, and we
+		 * want to keep traces reentrant, we need to manage
+		 * what happens when we are in an NMI.
+		 *
+		 * NMIs can happen after we take the lock.
+		 * If we are in an NMI, only take the lock
+		 * if it is not already taken. Otherwise
+		 * simply fail.
+		 */
+		if (unlikely(in_nmi())) {
+			if (!__raw_spin_trylock(&cpu_buffer->lock))
+				goto out_reset;
+		} else
+			__raw_spin_lock(&cpu_buffer->lock);
+
+		lock_taken = true;
 
 		rb_inc_page(cpu_buffer, &next_page);
 
@@ -1012,7 +1210,7 @@
 
 		/* we grabbed the lock before incrementing */
 		if (RB_WARN_ON(cpu_buffer, next_page == reader_page))
-			goto out_unlock;
+			goto out_reset;
 
 		/*
 		 * If for some reason, we had an interrupt storm that made
@@ -1021,12 +1219,12 @@
 		 */
 		if (unlikely(next_page == commit_page)) {
 			WARN_ON_ONCE(1);
-			goto out_unlock;
+			goto out_reset;
 		}
 
 		if (next_page == head_page) {
 			if (!(buffer->flags & RB_FL_OVERWRITE))
-				goto out_unlock;
+				goto out_reset;
 
 			/* tail_page has not moved yet? */
 			if (tail_page == cpu_buffer->tail_page) {
@@ -1050,7 +1248,7 @@
 			cpu_buffer->tail_page = next_page;
 
 			/* reread the time stamp */
-			*ts = ring_buffer_time_stamp(cpu_buffer->cpu);
+			*ts = ring_buffer_time_stamp(buffer, cpu_buffer->cpu);
 			cpu_buffer->tail_page->page->time_stamp = *ts;
 		}
 
@@ -1060,7 +1258,7 @@
 		if (tail < BUF_PAGE_SIZE) {
 			/* Mark the rest of the page with padding */
 			event = __rb_page_index(tail_page, tail);
-			event->type = RINGBUF_TYPE_PADDING;
+			rb_event_set_padding(event);
 		}
 
 		if (tail <= BUF_PAGE_SIZE)
@@ -1100,12 +1298,13 @@
 
 	return event;
 
- out_unlock:
+ out_reset:
 	/* reset write */
 	if (tail <= BUF_PAGE_SIZE)
 		local_set(&tail_page->write, tail);
 
-	__raw_spin_unlock(&cpu_buffer->lock);
+	if (likely(lock_taken))
+		__raw_spin_unlock(&cpu_buffer->lock);
 	local_irq_restore(flags);
 	return NULL;
 }
@@ -1192,7 +1391,7 @@
 	if (RB_WARN_ON(cpu_buffer, ++nr_loops > 1000))
 		return NULL;
 
-	ts = ring_buffer_time_stamp(cpu_buffer->cpu);
+	ts = ring_buffer_time_stamp(cpu_buffer->buffer, cpu_buffer->cpu);
 
 	/*
 	 * Only the first commit can update the timestamp.
@@ -1265,7 +1464,6 @@
  * ring_buffer_lock_reserve - reserve a part of the buffer
  * @buffer: the ring buffer to reserve from
  * @length: the length of the data to reserve (excluding event header)
- * @flags: a pointer to save the interrupt flags
  *
  * Returns a reseverd event on the ring buffer to copy directly to.
  * The user of this interface will need to get the body to write into
@@ -1278,9 +1476,7 @@
  * If NULL is returned, then nothing has been allocated or locked.
  */
 struct ring_buffer_event *
-ring_buffer_lock_reserve(struct ring_buffer *buffer,
-			 unsigned long length,
-			 unsigned long *flags)
+ring_buffer_lock_reserve(struct ring_buffer *buffer, unsigned long length)
 {
 	struct ring_buffer_per_cpu *cpu_buffer;
 	struct ring_buffer_event *event;
@@ -1347,15 +1543,13 @@
  * ring_buffer_unlock_commit - commit a reserved
  * @buffer: The buffer to commit to
  * @event: The event pointer to commit.
- * @flags: the interrupt flags received from ring_buffer_lock_reserve.
  *
  * This commits the data to the ring buffer, and releases any locks held.
  *
  * Must be paired with ring_buffer_lock_reserve.
  */
 int ring_buffer_unlock_commit(struct ring_buffer *buffer,
-			      struct ring_buffer_event *event,
-			      unsigned long flags)
+			      struct ring_buffer_event *event)
 {
 	struct ring_buffer_per_cpu *cpu_buffer;
 	int cpu = raw_smp_processor_id();
@@ -1438,7 +1632,7 @@
 }
 EXPORT_SYMBOL_GPL(ring_buffer_write);
 
-static inline int rb_per_cpu_empty(struct ring_buffer_per_cpu *cpu_buffer)
+static int rb_per_cpu_empty(struct ring_buffer_per_cpu *cpu_buffer)
 {
 	struct buffer_page *reader = cpu_buffer->reader_page;
 	struct buffer_page *head = cpu_buffer->head_page;
@@ -1528,12 +1722,15 @@
 unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu)
 {
 	struct ring_buffer_per_cpu *cpu_buffer;
+	unsigned long ret;
 
 	if (!cpumask_test_cpu(cpu, buffer->cpumask))
 		return 0;
 
 	cpu_buffer = buffer->buffers[cpu];
-	return cpu_buffer->entries;
+	ret = cpu_buffer->entries;
+
+	return ret;
 }
 EXPORT_SYMBOL_GPL(ring_buffer_entries_cpu);
 
@@ -1545,12 +1742,15 @@
 unsigned long ring_buffer_overrun_cpu(struct ring_buffer *buffer, int cpu)
 {
 	struct ring_buffer_per_cpu *cpu_buffer;
+	unsigned long ret;
 
 	if (!cpumask_test_cpu(cpu, buffer->cpumask))
 		return 0;
 
 	cpu_buffer = buffer->buffers[cpu];
-	return cpu_buffer->overrun;
+	ret = cpu_buffer->overrun;
+
+	return ret;
 }
 EXPORT_SYMBOL_GPL(ring_buffer_overrun_cpu);
 
@@ -1627,9 +1827,14 @@
  */
 void ring_buffer_iter_reset(struct ring_buffer_iter *iter)
 {
-	struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer;
+	struct ring_buffer_per_cpu *cpu_buffer;
 	unsigned long flags;
 
+	if (!iter)
+		return;
+
+	cpu_buffer = iter->cpu_buffer;
+
 	spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
 	rb_iter_reset(iter);
 	spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
@@ -1803,7 +2008,7 @@
 
 	event = rb_reader_event(cpu_buffer);
 
-	if (event->type == RINGBUF_TYPE_DATA)
+	if (event->type == RINGBUF_TYPE_DATA || rb_discarded_event(event))
 		cpu_buffer->entries--;
 
 	rb_update_read_stamp(cpu_buffer, event);
@@ -1864,9 +2069,6 @@
 	struct buffer_page *reader;
 	int nr_loops = 0;
 
-	if (!cpumask_test_cpu(cpu, buffer->cpumask))
-		return NULL;
-
 	cpu_buffer = buffer->buffers[cpu];
 
  again:
@@ -1889,9 +2091,18 @@
 
 	switch (event->type) {
 	case RINGBUF_TYPE_PADDING:
-		RB_WARN_ON(cpu_buffer, 1);
+		if (rb_null_event(event))
+			RB_WARN_ON(cpu_buffer, 1);
+		/*
+		 * Because the writer could be discarding every
+		 * event it creates (which would probably be bad)
+		 * if we were to go back to "again" then we may never
+		 * catch up, and will trigger the warn on, or lock
+		 * the box. Return the padding, and we will release
+		 * the current locks, and try again.
+		 */
 		rb_advance_reader(cpu_buffer);
-		return NULL;
+		return event;
 
 	case RINGBUF_TYPE_TIME_EXTEND:
 		/* Internal data, OK to advance */
@@ -1906,7 +2117,8 @@
 	case RINGBUF_TYPE_DATA:
 		if (ts) {
 			*ts = cpu_buffer->read_stamp + event->time_delta;
-			ring_buffer_normalize_time_stamp(cpu_buffer->cpu, ts);
+			ring_buffer_normalize_time_stamp(buffer,
+							 cpu_buffer->cpu, ts);
 		}
 		return event;
 
@@ -1951,8 +2163,12 @@
 
 	switch (event->type) {
 	case RINGBUF_TYPE_PADDING:
-		rb_inc_iter(iter);
-		goto again;
+		if (rb_null_event(event)) {
+			rb_inc_iter(iter);
+			goto again;
+		}
+		rb_advance_iter(iter);
+		return event;
 
 	case RINGBUF_TYPE_TIME_EXTEND:
 		/* Internal data, OK to advance */
@@ -1967,7 +2183,8 @@
 	case RINGBUF_TYPE_DATA:
 		if (ts) {
 			*ts = iter->read_stamp + event->time_delta;
-			ring_buffer_normalize_time_stamp(cpu_buffer->cpu, ts);
+			ring_buffer_normalize_time_stamp(buffer,
+							 cpu_buffer->cpu, ts);
 		}
 		return event;
 
@@ -1995,10 +2212,19 @@
 	struct ring_buffer_event *event;
 	unsigned long flags;
 
+	if (!cpumask_test_cpu(cpu, buffer->cpumask))
+		return NULL;
+
+ again:
 	spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
 	event = rb_buffer_peek(buffer, cpu, ts);
 	spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
 
+	if (event && event->type == RINGBUF_TYPE_PADDING) {
+		cpu_relax();
+		goto again;
+	}
+
 	return event;
 }
 
@@ -2017,10 +2243,16 @@
 	struct ring_buffer_event *event;
 	unsigned long flags;
 
+ again:
 	spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
 	event = rb_iter_peek(iter, ts);
 	spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
 
+	if (event && event->type == RINGBUF_TYPE_PADDING) {
+		cpu_relax();
+		goto again;
+	}
+
 	return event;
 }
 
@@ -2035,24 +2267,37 @@
 struct ring_buffer_event *
 ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts)
 {
-	struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
-	struct ring_buffer_event *event;
+	struct ring_buffer_per_cpu *cpu_buffer;
+	struct ring_buffer_event *event = NULL;
 	unsigned long flags;
 
-	if (!cpumask_test_cpu(cpu, buffer->cpumask))
-		return NULL;
+ again:
+	/* might be called in atomic */
+	preempt_disable();
 
+	if (!cpumask_test_cpu(cpu, buffer->cpumask))
+		goto out;
+
+	cpu_buffer = buffer->buffers[cpu];
 	spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
 
 	event = rb_buffer_peek(buffer, cpu, ts);
 	if (!event)
-		goto out;
+		goto out_unlock;
 
 	rb_advance_reader(cpu_buffer);
 
- out:
+ out_unlock:
 	spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
 
+ out:
+	preempt_enable();
+
+	if (event && event->type == RINGBUF_TYPE_PADDING) {
+		cpu_relax();
+		goto again;
+	}
+
 	return event;
 }
 EXPORT_SYMBOL_GPL(ring_buffer_consume);
@@ -2131,6 +2376,7 @@
 	struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer;
 	unsigned long flags;
 
+ again:
 	spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
 	event = rb_iter_peek(iter, ts);
 	if (!event)
@@ -2140,6 +2386,11 @@
  out:
 	spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
 
+	if (event && event->type == RINGBUF_TYPE_PADDING) {
+		cpu_relax();
+		goto again;
+	}
+
 	return event;
 }
 EXPORT_SYMBOL_GPL(ring_buffer_read);
@@ -2232,6 +2483,7 @@
 		if (!rb_per_cpu_empty(cpu_buffer))
 			return 0;
 	}
+
 	return 1;
 }
 EXPORT_SYMBOL_GPL(ring_buffer_empty);
@@ -2244,12 +2496,16 @@
 int ring_buffer_empty_cpu(struct ring_buffer *buffer, int cpu)
 {
 	struct ring_buffer_per_cpu *cpu_buffer;
+	int ret;
 
 	if (!cpumask_test_cpu(cpu, buffer->cpumask))
 		return 1;
 
 	cpu_buffer = buffer->buffers[cpu];
-	return rb_per_cpu_empty(cpu_buffer);
+	ret = rb_per_cpu_empty(cpu_buffer);
+
+
+	return ret;
 }
 EXPORT_SYMBOL_GPL(ring_buffer_empty_cpu);
 
@@ -2268,18 +2524,36 @@
 {
 	struct ring_buffer_per_cpu *cpu_buffer_a;
 	struct ring_buffer_per_cpu *cpu_buffer_b;
+	int ret = -EINVAL;
 
 	if (!cpumask_test_cpu(cpu, buffer_a->cpumask) ||
 	    !cpumask_test_cpu(cpu, buffer_b->cpumask))
-		return -EINVAL;
+		goto out;
 
 	/* At least make sure the two buffers are somewhat the same */
 	if (buffer_a->pages != buffer_b->pages)
-		return -EINVAL;
+		goto out;
+
+	ret = -EAGAIN;
+
+	if (ring_buffer_flags != RB_BUFFERS_ON)
+		goto out;
+
+	if (atomic_read(&buffer_a->record_disabled))
+		goto out;
+
+	if (atomic_read(&buffer_b->record_disabled))
+		goto out;
 
 	cpu_buffer_a = buffer_a->buffers[cpu];
 	cpu_buffer_b = buffer_b->buffers[cpu];
 
+	if (atomic_read(&cpu_buffer_a->record_disabled))
+		goto out;
+
+	if (atomic_read(&cpu_buffer_b->record_disabled))
+		goto out;
+
 	/*
 	 * We can't do a synchronize_sched here because this
 	 * function can be called in atomic context.
@@ -2298,18 +2572,21 @@
 	atomic_dec(&cpu_buffer_a->record_disabled);
 	atomic_dec(&cpu_buffer_b->record_disabled);
 
-	return 0;
+	ret = 0;
+out:
+	return ret;
 }
 EXPORT_SYMBOL_GPL(ring_buffer_swap_cpu);
 
 static void rb_remove_entries(struct ring_buffer_per_cpu *cpu_buffer,
-			      struct buffer_data_page *bpage)
+			      struct buffer_data_page *bpage,
+			      unsigned int offset)
 {
 	struct ring_buffer_event *event;
 	unsigned long head;
 
 	__raw_spin_lock(&cpu_buffer->lock);
-	for (head = 0; head < local_read(&bpage->commit);
+	for (head = offset; head < local_read(&bpage->commit);
 	     head += rb_event_length(event)) {
 
 		event = __rb_data_page_index(bpage, head);
@@ -2340,8 +2617,8 @@
  */
 void *ring_buffer_alloc_read_page(struct ring_buffer *buffer)
 {
-	unsigned long addr;
 	struct buffer_data_page *bpage;
+	unsigned long addr;
 
 	addr = __get_free_page(GFP_KERNEL);
 	if (!addr)
@@ -2349,6 +2626,8 @@
 
 	bpage = (void *)addr;
 
+	rb_init_page(bpage);
+
 	return bpage;
 }
 
@@ -2368,6 +2647,7 @@
  * ring_buffer_read_page - extract a page from the ring buffer
  * @buffer: buffer to extract from
  * @data_page: the page to use allocated from ring_buffer_alloc_read_page
+ * @len: amount to extract
  * @cpu: the cpu of the buffer to extract
  * @full: should the extraction only happen when the page is full.
  *
@@ -2377,12 +2657,12 @@
  * to swap with a page in the ring buffer.
  *
  * for example:
- *	rpage = ring_buffer_alloc_page(buffer);
+ *	rpage = ring_buffer_alloc_read_page(buffer);
  *	if (!rpage)
  *		return error;
- *	ret = ring_buffer_read_page(buffer, &rpage, cpu, 0);
- *	if (ret)
- *		process_page(rpage);
+ *	ret = ring_buffer_read_page(buffer, &rpage, len, cpu, 0);
+ *	if (ret >= 0)
+ *		process_page(rpage, ret);
  *
  * When @full is set, the function will not return true unless
  * the writer is off the reader page.
@@ -2393,72 +2673,118 @@
  *  responsible for that.
  *
  * Returns:
- *  1 if data has been transferred
- *  0 if no data has been transferred.
+ *  >=0 if data has been transferred, returns the offset of consumed data.
+ *  <0 if no data has been transferred.
  */
 int ring_buffer_read_page(struct ring_buffer *buffer,
-			    void **data_page, int cpu, int full)
+			  void **data_page, size_t len, int cpu, int full)
 {
 	struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
 	struct ring_buffer_event *event;
 	struct buffer_data_page *bpage;
+	struct buffer_page *reader;
 	unsigned long flags;
-	int ret = 0;
+	unsigned int commit;
+	unsigned int read;
+	u64 save_timestamp;
+	int ret = -1;
+
+	if (!cpumask_test_cpu(cpu, buffer->cpumask))
+		goto out;
+
+	/*
+	 * If len is not big enough to hold the page header, then
+	 * we can not copy anything.
+	 */
+	if (len <= BUF_PAGE_HDR_SIZE)
+		goto out;
+
+	len -= BUF_PAGE_HDR_SIZE;
 
 	if (!data_page)
-		return 0;
+		goto out;
 
 	bpage = *data_page;
 	if (!bpage)
-		return 0;
+		goto out;
 
 	spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
 
-	/*
-	 * rb_buffer_peek will get the next ring buffer if
-	 * the current reader page is empty.
-	 */
-	event = rb_buffer_peek(buffer, cpu, NULL);
-	if (!event)
-		goto out;
+	reader = rb_get_reader_page(cpu_buffer);
+	if (!reader)
+		goto out_unlock;
 
-	/* check for data */
-	if (!local_read(&cpu_buffer->reader_page->page->commit))
-		goto out;
+	event = rb_reader_event(cpu_buffer);
+
+	read = reader->read;
+	commit = rb_page_commit(reader);
+
 	/*
-	 * If the writer is already off of the read page, then simply
-	 * switch the read page with the given page. Otherwise
-	 * we need to copy the data from the reader to the writer.
+	 * If this page has been partially read or
+	 * if len is not big enough to read the rest of the page or
+	 * a writer is still on the page, then
+	 * we must copy the data from the page to the buffer.
+	 * Otherwise, we can simply swap the page with the one passed in.
 	 */
-	if (cpu_buffer->reader_page == cpu_buffer->commit_page) {
-		unsigned int read = cpu_buffer->reader_page->read;
+	if (read || (len < (commit - read)) ||
+	    cpu_buffer->reader_page == cpu_buffer->commit_page) {
+		struct buffer_data_page *rpage = cpu_buffer->reader_page->page;
+		unsigned int rpos = read;
+		unsigned int pos = 0;
+		unsigned int size;
 
 		if (full)
-			goto out;
-		/* The writer is still on the reader page, we must copy */
-		bpage = cpu_buffer->reader_page->page;
-		memcpy(bpage->data,
-		       cpu_buffer->reader_page->page->data + read,
-		       local_read(&bpage->commit) - read);
+			goto out_unlock;
 
-		/* consume what was read */
-		cpu_buffer->reader_page += read;
+		if (len > (commit - read))
+			len = (commit - read);
 
+		size = rb_event_length(event);
+
+		if (len < size)
+			goto out_unlock;
+
+		/* save the current timestamp, since the user will need it */
+		save_timestamp = cpu_buffer->read_stamp;
+
+		/* Need to copy one event at a time */
+		do {
+			memcpy(bpage->data + pos, rpage->data + rpos, size);
+
+			len -= size;
+
+			rb_advance_reader(cpu_buffer);
+			rpos = reader->read;
+			pos += size;
+
+			event = rb_reader_event(cpu_buffer);
+			size = rb_event_length(event);
+		} while (len > size);
+
+		/* update bpage */
+		local_set(&bpage->commit, pos);
+		bpage->time_stamp = save_timestamp;
+
+		/* we copied everything to the beginning */
+		read = 0;
 	} else {
 		/* swap the pages */
 		rb_init_page(bpage);
-		bpage = cpu_buffer->reader_page->page;
-		cpu_buffer->reader_page->page = *data_page;
-		cpu_buffer->reader_page->read = 0;
+		bpage = reader->page;
+		reader->page = *data_page;
+		local_set(&reader->write, 0);
+		reader->read = 0;
 		*data_page = bpage;
-	}
-	ret = 1;
 
-	/* update the entry counter */
-	rb_remove_entries(cpu_buffer, bpage);
- out:
+		/* update the entry counter */
+		rb_remove_entries(cpu_buffer, bpage, read);
+	}
+	ret = read;
+
+ out_unlock:
 	spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
 
+ out:
 	return ret;
 }
 
@@ -2466,7 +2792,7 @@
 rb_simple_read(struct file *filp, char __user *ubuf,
 	       size_t cnt, loff_t *ppos)
 {
-	long *p = filp->private_data;
+	unsigned long *p = filp->private_data;
 	char buf[64];
 	int r;
 
@@ -2482,9 +2808,9 @@
 rb_simple_write(struct file *filp, const char __user *ubuf,
 		size_t cnt, loff_t *ppos)
 {
-	long *p = filp->private_data;
+	unsigned long *p = filp->private_data;
 	char buf[64];
-	long val;
+	unsigned long val;
 	int ret;
 
 	if (cnt >= sizeof(buf))
@@ -2509,7 +2835,7 @@
 	return cnt;
 }
 
-static struct file_operations rb_simple_fops = {
+static const struct file_operations rb_simple_fops = {
 	.open		= tracing_open_generic,
 	.read		= rb_simple_read,
 	.write		= rb_simple_write,
@@ -2532,3 +2858,42 @@
 }
 
 fs_initcall(rb_init_debugfs);
+
+#ifdef CONFIG_HOTPLUG_CPU
+static int rb_cpu_notify(struct notifier_block *self,
+			 unsigned long action, void *hcpu)
+{
+	struct ring_buffer *buffer =
+		container_of(self, struct ring_buffer, cpu_notify);
+	long cpu = (long)hcpu;
+
+	switch (action) {
+	case CPU_UP_PREPARE:
+	case CPU_UP_PREPARE_FROZEN:
+		if (cpu_isset(cpu, *buffer->cpumask))
+			return NOTIFY_OK;
+
+		buffer->buffers[cpu] =
+			rb_allocate_cpu_buffer(buffer, cpu);
+		if (!buffer->buffers[cpu]) {
+			WARN(1, "failed to allocate ring buffer on CPU %ld\n",
+			     cpu);
+			return NOTIFY_OK;
+		}
+		smp_wmb();
+		cpu_set(cpu, *buffer->cpumask);
+		break;
+	case CPU_DOWN_PREPARE:
+	case CPU_DOWN_PREPARE_FROZEN:
+		/*
+		 * Do nothing.
+		 *  If we were to free the buffer, then the user would
+		 *  lose any trace that was in the buffer.
+		 */
+		break;
+	default:
+		break;
+	}
+	return NOTIFY_OK;
+}
+#endif
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 17bb88d..a0174a4 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -11,32 +11,33 @@
  *  Copyright (C) 2004-2006 Ingo Molnar
  *  Copyright (C) 2004 William Lee Irwin III
  */
+#include <linux/ring_buffer.h>
 #include <linux/utsrelease.h>
+#include <linux/stacktrace.h>
+#include <linux/writeback.h>
 #include <linux/kallsyms.h>
 #include <linux/seq_file.h>
 #include <linux/notifier.h>
+#include <linux/irqflags.h>
 #include <linux/debugfs.h>
 #include <linux/pagemap.h>
 #include <linux/hardirq.h>
 #include <linux/linkage.h>
 #include <linux/uaccess.h>
+#include <linux/kprobes.h>
 #include <linux/ftrace.h>
 #include <linux/module.h>
 #include <linux/percpu.h>
+#include <linux/splice.h>
 #include <linux/kdebug.h>
 #include <linux/ctype.h>
 #include <linux/init.h>
 #include <linux/poll.h>
 #include <linux/gfp.h>
 #include <linux/fs.h>
-#include <linux/kprobes.h>
-#include <linux/writeback.h>
-
-#include <linux/stacktrace.h>
-#include <linux/ring_buffer.h>
-#include <linux/irqflags.h>
 
 #include "trace.h"
+#include "trace_output.h"
 
 #define TRACE_BUFFER_FLAGS	(RB_FL_OVERWRITE)
 
@@ -44,14 +45,25 @@
 unsigned long __read_mostly	tracing_thresh;
 
 /*
+ * On boot up, the ring buffer is set to the minimum size, so that
+ * we do not waste memory on systems that are not using tracing.
+ */
+static int ring_buffer_expanded;
+
+/*
  * We need to change this state when a selftest is running.
  * A selftest will lurk into the ring-buffer to count the
  * entries inserted during the selftest although some concurrent
- * insertions into the ring-buffer such as ftrace_printk could occurred
+ * insertions into the ring-buffer such as trace_printk could occurred
  * at the same time, giving false positive or negative results.
  */
 static bool __read_mostly tracing_selftest_running;
 
+/*
+ * If a tracer is running, we do not want to run SELFTEST.
+ */
+static bool __read_mostly tracing_selftest_disabled;
+
 /* For tracers that don't implement custom flags */
 static struct tracer_opt dummy_tracer_opt[] = {
 	{ }
@@ -73,7 +85,7 @@
  * of the tracer is successful. But that is the only place that sets
  * this back to zero.
  */
-int tracing_disabled = 1;
+static int tracing_disabled = 1;
 
 static DEFINE_PER_CPU(local_t, ftrace_cpu_disabled);
 
@@ -91,6 +103,9 @@
 
 static cpumask_var_t __read_mostly	tracing_buffer_mask;
 
+/* Define which cpu buffers are currently read in trace_pipe */
+static cpumask_var_t			tracing_reader_cpumask;
+
 #define for_each_tracing_cpu(cpu)	\
 	for_each_cpu(cpu, tracing_buffer_mask)
 
@@ -109,14 +124,21 @@
  */
 int ftrace_dump_on_oops;
 
-static int tracing_set_tracer(char *buf);
+static int tracing_set_tracer(const char *buf);
+
+#define BOOTUP_TRACER_SIZE		100
+static char bootup_tracer_buf[BOOTUP_TRACER_SIZE] __initdata;
+static char *default_bootup_tracer;
 
 static int __init set_ftrace(char *str)
 {
-	tracing_set_tracer(str);
+	strncpy(bootup_tracer_buf, str, BOOTUP_TRACER_SIZE);
+	default_bootup_tracer = bootup_tracer_buf;
+	/* We are using ftrace early, expand it */
+	ring_buffer_expanded = 1;
 	return 1;
 }
-__setup("ftrace", set_ftrace);
+__setup("ftrace=", set_ftrace);
 
 static int __init set_ftrace_dump_on_oops(char *str)
 {
@@ -133,13 +155,6 @@
 	return nsec;
 }
 
-cycle_t ftrace_now(int cpu)
-{
-	u64 ts = ring_buffer_time_stamp(cpu);
-	ring_buffer_normalize_time_stamp(cpu, &ts);
-	return ts;
-}
-
 /*
  * The global_trace is the descriptor that holds the tracing
  * buffers for the live tracing. For each CPU, it contains
@@ -156,6 +171,20 @@
 
 static DEFINE_PER_CPU(struct trace_array_cpu, global_trace_cpu);
 
+cycle_t ftrace_now(int cpu)
+{
+	u64 ts;
+
+	/* Early boot up does not have a buffer yet */
+	if (!global_trace.buffer)
+		return trace_clock_local();
+
+	ts = ring_buffer_time_stamp(global_trace.buffer, cpu);
+	ring_buffer_normalize_time_stamp(global_trace.buffer, cpu, &ts);
+
+	return ts;
+}
+
 /*
  * The max_tr is used to snapshot the global_trace when a maximum
  * latency is reached. Some tracers will use this to store a maximum
@@ -186,9 +215,6 @@
 	return tracer_enabled;
 }
 
-/* function tracing enabled */
-int				ftrace_function_enabled;
-
 /*
  * trace_buf_size is the size in bytes that is allocated
  * for a buffer. Note, the number of bytes is always rounded
@@ -229,7 +255,7 @@
 
 /* trace_flags holds trace_options default values */
 unsigned long trace_flags = TRACE_ITER_PRINT_PARENT | TRACE_ITER_PRINTK |
-	TRACE_ITER_ANNOTATE;
+	TRACE_ITER_ANNOTATE | TRACE_ITER_CONTEXT_INFO | TRACE_ITER_SLEEP_TIME;
 
 /**
  * trace_wake_up - wake up tasks waiting for trace input
@@ -280,13 +306,17 @@
 	"block",
 	"stacktrace",
 	"sched-tree",
-	"ftrace_printk",
+	"trace_printk",
 	"ftrace_preempt",
 	"branch",
 	"annotate",
 	"userstacktrace",
 	"sym-userobj",
 	"printk-msg-only",
+	"context-info",
+	"latency-format",
+	"global-clock",
+	"sleep-time",
 	NULL
 };
 
@@ -326,140 +356,7 @@
 	data->rt_priority = tsk->rt_priority;
 
 	/* record this tasks comm */
-	tracing_record_cmdline(current);
-}
-
-/**
- * trace_seq_printf - sequence printing of trace information
- * @s: trace sequence descriptor
- * @fmt: printf format string
- *
- * The tracer may use either sequence operations or its own
- * copy to user routines. To simplify formating of a trace
- * trace_seq_printf is used to store strings into a special
- * buffer (@s). Then the output may be either used by
- * the sequencer or pulled into another buffer.
- */
-int
-trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
-{
-	int len = (PAGE_SIZE - 1) - s->len;
-	va_list ap;
-	int ret;
-
-	if (!len)
-		return 0;
-
-	va_start(ap, fmt);
-	ret = vsnprintf(s->buffer + s->len, len, fmt, ap);
-	va_end(ap);
-
-	/* If we can't write it all, don't bother writing anything */
-	if (ret >= len)
-		return 0;
-
-	s->len += ret;
-
-	return len;
-}
-
-/**
- * trace_seq_puts - trace sequence printing of simple string
- * @s: trace sequence descriptor
- * @str: simple string to record
- *
- * The tracer may use either the sequence operations or its own
- * copy to user routines. This function records a simple string
- * into a special buffer (@s) for later retrieval by a sequencer
- * or other mechanism.
- */
-static int
-trace_seq_puts(struct trace_seq *s, const char *str)
-{
-	int len = strlen(str);
-
-	if (len > ((PAGE_SIZE - 1) - s->len))
-		return 0;
-
-	memcpy(s->buffer + s->len, str, len);
-	s->len += len;
-
-	return len;
-}
-
-static int
-trace_seq_putc(struct trace_seq *s, unsigned char c)
-{
-	if (s->len >= (PAGE_SIZE - 1))
-		return 0;
-
-	s->buffer[s->len++] = c;
-
-	return 1;
-}
-
-static int
-trace_seq_putmem(struct trace_seq *s, void *mem, size_t len)
-{
-	if (len > ((PAGE_SIZE - 1) - s->len))
-		return 0;
-
-	memcpy(s->buffer + s->len, mem, len);
-	s->len += len;
-
-	return len;
-}
-
-#define MAX_MEMHEX_BYTES	8
-#define HEX_CHARS		(MAX_MEMHEX_BYTES*2 + 1)
-
-static int
-trace_seq_putmem_hex(struct trace_seq *s, void *mem, size_t len)
-{
-	unsigned char hex[HEX_CHARS];
-	unsigned char *data = mem;
-	int i, j;
-
-#ifdef __BIG_ENDIAN
-	for (i = 0, j = 0; i < len; i++) {
-#else
-	for (i = len-1, j = 0; i >= 0; i--) {
-#endif
-		hex[j++] = hex_asc_hi(data[i]);
-		hex[j++] = hex_asc_lo(data[i]);
-	}
-	hex[j++] = ' ';
-
-	return trace_seq_putmem(s, hex, j);
-}
-
-static int
-trace_seq_path(struct trace_seq *s, struct path *path)
-{
-	unsigned char *p;
-
-	if (s->len >= (PAGE_SIZE - 1))
-		return 0;
-	p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len);
-	if (!IS_ERR(p)) {
-		p = mangle_path(s->buffer + s->len, p, "\n");
-		if (p) {
-			s->len = p - s->buffer;
-			return 1;
-		}
-	} else {
-		s->buffer[s->len++] = '?';
-		return 1;
-	}
-
-	return 0;
-}
-
-static void
-trace_seq_reset(struct trace_seq *s)
-{
-	s->len = 0;
-	s->readpos = 0;
+	tracing_record_cmdline(tsk);
 }
 
 ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, size_t cnt)
@@ -467,6 +364,9 @@
 	int len;
 	int ret;
 
+	if (!cnt)
+		return 0;
+
 	if (s->len <= s->readpos)
 		return -EBUSY;
 
@@ -474,10 +374,31 @@
 	if (cnt > len)
 		cnt = len;
 	ret = copy_to_user(ubuf, s->buffer + s->readpos, cnt);
-	if (ret)
+	if (ret == cnt)
 		return -EFAULT;
 
-	s->readpos += len;
+	cnt -= ret;
+
+	s->readpos += cnt;
+	return cnt;
+}
+
+static ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt)
+{
+	int len;
+	void *ret;
+
+	if (s->len <= s->readpos)
+		return -EBUSY;
+
+	len = s->len - s->readpos;
+	if (cnt > len)
+		cnt = len;
+	ret = memcpy(buf, s->buffer + s->readpos, cnt);
+	if (!ret)
+		return -EFAULT;
+
+	s->readpos += cnt;
 	return cnt;
 }
 
@@ -489,7 +410,7 @@
 	s->buffer[len] = 0;
 	seq_puts(m, s->buffer);
 
-	trace_seq_reset(s);
+	trace_seq_init(s);
 }
 
 /**
@@ -543,7 +464,7 @@
 
 	ftrace_enable_cpu();
 
-	WARN_ON_ONCE(ret);
+	WARN_ON_ONCE(ret && ret != -EAGAIN);
 
 	__update_max_tr(tr, tsk, cpu);
 	__raw_spin_unlock(&ftrace_max_lock);
@@ -556,6 +477,8 @@
  * Register a new plugin tracer.
  */
 int register_tracer(struct tracer *type)
+__releases(kernel_lock)
+__acquires(kernel_lock)
 {
 	struct tracer *t;
 	int len;
@@ -594,9 +517,12 @@
 	else
 		if (!type->flags->opts)
 			type->flags->opts = dummy_tracer_opt;
+	if (!type->wait_pipe)
+		type->wait_pipe = default_wait_pipe;
+
 
 #ifdef CONFIG_FTRACE_STARTUP_TEST
-	if (type->selftest) {
+	if (type->selftest && !tracing_selftest_disabled) {
 		struct tracer *saved_tracer = current_trace;
 		struct trace_array *tr = &global_trace;
 		int i;
@@ -638,8 +564,26 @@
  out:
 	tracing_selftest_running = false;
 	mutex_unlock(&trace_types_lock);
-	lock_kernel();
 
+	if (ret || !default_bootup_tracer)
+		goto out_unlock;
+
+	if (strncmp(default_bootup_tracer, type->name, BOOTUP_TRACER_SIZE))
+		goto out_unlock;
+
+	printk(KERN_INFO "Starting tracer '%s'\n", type->name);
+	/* Do we want this tracer to start on bootup? */
+	tracing_set_tracer(type->name);
+	default_bootup_tracer = NULL;
+	/* disable other selftests, since this will break it. */
+	tracing_selftest_disabled = 1;
+#ifdef CONFIG_FTRACE_STARTUP_TEST
+	printk(KERN_INFO "Disabling FTRACE selftests due to running tracer '%s'\n",
+	       type->name);
+#endif
+
+ out_unlock:
+	lock_kernel();
 	return ret;
 }
 
@@ -658,6 +602,15 @@
 
  found:
 	*t = (*t)->next;
+
+	if (type == current_trace && tracer_enabled) {
+		tracer_enabled = 0;
+		tracing_stop();
+		if (current_trace->stop)
+			current_trace->stop(&global_trace);
+		current_trace = &nop_trace;
+	}
+
 	if (strlen(type->name) != max_tracer_type_len)
 		goto out;
 
@@ -689,19 +642,20 @@
 }
 
 #define SAVED_CMDLINES 128
+#define NO_CMDLINE_MAP UINT_MAX
 static unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
 static unsigned map_cmdline_to_pid[SAVED_CMDLINES];
 static char saved_cmdlines[SAVED_CMDLINES][TASK_COMM_LEN];
 static int cmdline_idx;
-static DEFINE_SPINLOCK(trace_cmdline_lock);
+static raw_spinlock_t trace_cmdline_lock = __RAW_SPIN_LOCK_UNLOCKED;
 
 /* temporary disable recording */
-atomic_t trace_record_cmdline_disabled __read_mostly;
+static atomic_t trace_record_cmdline_disabled __read_mostly;
 
 static void trace_init_cmdlines(void)
 {
-	memset(&map_pid_to_cmdline, -1, sizeof(map_pid_to_cmdline));
-	memset(&map_cmdline_to_pid, -1, sizeof(map_cmdline_to_pid));
+	memset(&map_pid_to_cmdline, NO_CMDLINE_MAP, sizeof(map_pid_to_cmdline));
+	memset(&map_cmdline_to_pid, NO_CMDLINE_MAP, sizeof(map_cmdline_to_pid));
 	cmdline_idx = 0;
 }
 
@@ -738,13 +692,12 @@
 		return;
 
 	spin_lock_irqsave(&tracing_start_lock, flags);
-	if (--trace_stop_count)
-		goto out;
-
-	if (trace_stop_count < 0) {
-		/* Someone screwed up their debugging */
-		WARN_ON_ONCE(1);
-		trace_stop_count = 0;
+	if (--trace_stop_count) {
+		if (trace_stop_count < 0) {
+			/* Someone screwed up their debugging */
+			WARN_ON_ONCE(1);
+			trace_stop_count = 0;
+		}
 		goto out;
 	}
 
@@ -794,8 +747,7 @@
 
 static void trace_save_cmdline(struct task_struct *tsk)
 {
-	unsigned map;
-	unsigned idx;
+	unsigned pid, idx;
 
 	if (!tsk->pid || unlikely(tsk->pid > PID_MAX_DEFAULT))
 		return;
@@ -806,17 +758,24 @@
 	 * nor do we want to disable interrupts,
 	 * so if we miss here, then better luck next time.
 	 */
-	if (!spin_trylock(&trace_cmdline_lock))
+	if (!__raw_spin_trylock(&trace_cmdline_lock))
 		return;
 
 	idx = map_pid_to_cmdline[tsk->pid];
-	if (idx >= SAVED_CMDLINES) {
+	if (idx == NO_CMDLINE_MAP) {
 		idx = (cmdline_idx + 1) % SAVED_CMDLINES;
 
-		map = map_cmdline_to_pid[idx];
-		if (map <= PID_MAX_DEFAULT)
-			map_pid_to_cmdline[map] = (unsigned)-1;
+		/*
+		 * Check whether the cmdline buffer at idx has a pid
+		 * mapped. We are going to overwrite that entry so we
+		 * need to clear the map_pid_to_cmdline. Otherwise we
+		 * would read the new comm for the old pid.
+		 */
+		pid = map_cmdline_to_pid[idx];
+		if (pid != NO_CMDLINE_MAP)
+			map_pid_to_cmdline[pid] = NO_CMDLINE_MAP;
 
+		map_cmdline_to_pid[idx] = tsk->pid;
 		map_pid_to_cmdline[tsk->pid] = idx;
 
 		cmdline_idx = idx;
@@ -824,33 +783,37 @@
 
 	memcpy(&saved_cmdlines[idx], tsk->comm, TASK_COMM_LEN);
 
-	spin_unlock(&trace_cmdline_lock);
+	__raw_spin_unlock(&trace_cmdline_lock);
 }
 
-char *trace_find_cmdline(int pid)
+void trace_find_cmdline(int pid, char comm[])
 {
-	char *cmdline = "<...>";
 	unsigned map;
 
-	if (!pid)
-		return "<idle>";
+	if (!pid) {
+		strcpy(comm, "<idle>");
+		return;
+	}
 
-	if (pid > PID_MAX_DEFAULT)
-		goto out;
+	if (pid > PID_MAX_DEFAULT) {
+		strcpy(comm, "<...>");
+		return;
+	}
 
+	__raw_spin_lock(&trace_cmdline_lock);
 	map = map_pid_to_cmdline[pid];
-	if (map >= SAVED_CMDLINES)
-		goto out;
+	if (map != NO_CMDLINE_MAP)
+		strcpy(comm, saved_cmdlines[map]);
+	else
+		strcpy(comm, "<...>");
 
-	cmdline = saved_cmdlines[map];
-
- out:
-	return cmdline;
+	__raw_spin_unlock(&trace_cmdline_lock);
 }
 
 void tracing_record_cmdline(struct task_struct *tsk)
 {
-	if (atomic_read(&trace_record_cmdline_disabled))
+	if (atomic_read(&trace_record_cmdline_disabled) || !tracer_enabled ||
+	    !tracing_is_on())
 		return;
 
 	trace_save_cmdline(tsk);
@@ -864,7 +827,7 @@
 
 	entry->preempt_count		= pc & 0xff;
 	entry->pid			= (tsk) ? tsk->pid : 0;
-	entry->tgid               	= (tsk) ? tsk->tgid : 0;
+	entry->tgid			= (tsk) ? tsk->tgid : 0;
 	entry->flags =
 #ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT
 		(irqs_disabled_flags(flags) ? TRACE_FLAG_IRQS_OFF : 0) |
@@ -876,78 +839,132 @@
 		(need_resched() ? TRACE_FLAG_NEED_RESCHED : 0);
 }
 
+struct ring_buffer_event *trace_buffer_lock_reserve(struct trace_array *tr,
+						    unsigned char type,
+						    unsigned long len,
+						    unsigned long flags, int pc)
+{
+	struct ring_buffer_event *event;
+
+	event = ring_buffer_lock_reserve(tr->buffer, len);
+	if (event != NULL) {
+		struct trace_entry *ent = ring_buffer_event_data(event);
+
+		tracing_generic_entry_update(ent, flags, pc);
+		ent->type = type;
+	}
+
+	return event;
+}
+static void ftrace_trace_stack(struct trace_array *tr,
+			       unsigned long flags, int skip, int pc);
+static void ftrace_trace_userstack(struct trace_array *tr,
+				   unsigned long flags, int pc);
+
+static inline void __trace_buffer_unlock_commit(struct trace_array *tr,
+					struct ring_buffer_event *event,
+					unsigned long flags, int pc,
+					int wake)
+{
+	ring_buffer_unlock_commit(tr->buffer, event);
+
+	ftrace_trace_stack(tr, flags, 6, pc);
+	ftrace_trace_userstack(tr, flags, pc);
+
+	if (wake)
+		trace_wake_up();
+}
+
+void trace_buffer_unlock_commit(struct trace_array *tr,
+					struct ring_buffer_event *event,
+					unsigned long flags, int pc)
+{
+	__trace_buffer_unlock_commit(tr, event, flags, pc, 1);
+}
+
+struct ring_buffer_event *
+trace_current_buffer_lock_reserve(unsigned char type, unsigned long len,
+				  unsigned long flags, int pc)
+{
+	return trace_buffer_lock_reserve(&global_trace,
+					 type, len, flags, pc);
+}
+
+void trace_current_buffer_unlock_commit(struct ring_buffer_event *event,
+					unsigned long flags, int pc)
+{
+	return __trace_buffer_unlock_commit(&global_trace, event, flags, pc, 1);
+}
+
+void trace_nowake_buffer_unlock_commit(struct ring_buffer_event *event,
+					unsigned long flags, int pc)
+{
+	return __trace_buffer_unlock_commit(&global_trace, event, flags, pc, 0);
+}
+
 void
-trace_function(struct trace_array *tr, struct trace_array_cpu *data,
+trace_function(struct trace_array *tr,
 	       unsigned long ip, unsigned long parent_ip, unsigned long flags,
 	       int pc)
 {
 	struct ring_buffer_event *event;
 	struct ftrace_entry *entry;
-	unsigned long irq_flags;
 
 	/* If we are reading the ring buffer, don't trace */
 	if (unlikely(local_read(&__get_cpu_var(ftrace_cpu_disabled))))
 		return;
 
-	event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
-					 &irq_flags);
+	event = trace_buffer_lock_reserve(tr, TRACE_FN, sizeof(*entry),
+					  flags, pc);
 	if (!event)
 		return;
 	entry	= ring_buffer_event_data(event);
-	tracing_generic_entry_update(&entry->ent, flags, pc);
-	entry->ent.type			= TRACE_FN;
 	entry->ip			= ip;
 	entry->parent_ip		= parent_ip;
-	ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
+	ring_buffer_unlock_commit(tr->buffer, event);
 }
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
-static void __trace_graph_entry(struct trace_array *tr,
-				struct trace_array_cpu *data,
+static int __trace_graph_entry(struct trace_array *tr,
 				struct ftrace_graph_ent *trace,
 				unsigned long flags,
 				int pc)
 {
 	struct ring_buffer_event *event;
 	struct ftrace_graph_ent_entry *entry;
-	unsigned long irq_flags;
 
 	if (unlikely(local_read(&__get_cpu_var(ftrace_cpu_disabled))))
-		return;
+		return 0;
 
-	event = ring_buffer_lock_reserve(global_trace.buffer, sizeof(*entry),
-					 &irq_flags);
+	event = trace_buffer_lock_reserve(&global_trace, TRACE_GRAPH_ENT,
+					  sizeof(*entry), flags, pc);
 	if (!event)
-		return;
+		return 0;
 	entry	= ring_buffer_event_data(event);
-	tracing_generic_entry_update(&entry->ent, flags, pc);
-	entry->ent.type			= TRACE_GRAPH_ENT;
 	entry->graph_ent			= *trace;
-	ring_buffer_unlock_commit(global_trace.buffer, event, irq_flags);
+	ring_buffer_unlock_commit(global_trace.buffer, event);
+
+	return 1;
 }
 
 static void __trace_graph_return(struct trace_array *tr,
-				struct trace_array_cpu *data,
 				struct ftrace_graph_ret *trace,
 				unsigned long flags,
 				int pc)
 {
 	struct ring_buffer_event *event;
 	struct ftrace_graph_ret_entry *entry;
-	unsigned long irq_flags;
 
 	if (unlikely(local_read(&__get_cpu_var(ftrace_cpu_disabled))))
 		return;
 
-	event = ring_buffer_lock_reserve(global_trace.buffer, sizeof(*entry),
-					 &irq_flags);
+	event = trace_buffer_lock_reserve(&global_trace, TRACE_GRAPH_RET,
+					  sizeof(*entry), flags, pc);
 	if (!event)
 		return;
 	entry	= ring_buffer_event_data(event);
-	tracing_generic_entry_update(&entry->ent, flags, pc);
-	entry->ent.type			= TRACE_GRAPH_RET;
 	entry->ret				= *trace;
-	ring_buffer_unlock_commit(global_trace.buffer, event, irq_flags);
+	ring_buffer_unlock_commit(global_trace.buffer, event);
 }
 #endif
 
@@ -957,31 +974,23 @@
        int pc)
 {
 	if (likely(!atomic_read(&data->disabled)))
-		trace_function(tr, data, ip, parent_ip, flags, pc);
+		trace_function(tr, ip, parent_ip, flags, pc);
 }
 
-static void ftrace_trace_stack(struct trace_array *tr,
-			       struct trace_array_cpu *data,
-			       unsigned long flags,
-			       int skip, int pc)
+static void __ftrace_trace_stack(struct trace_array *tr,
+				 unsigned long flags,
+				 int skip, int pc)
 {
 #ifdef CONFIG_STACKTRACE
 	struct ring_buffer_event *event;
 	struct stack_entry *entry;
 	struct stack_trace trace;
-	unsigned long irq_flags;
 
-	if (!(trace_flags & TRACE_ITER_STACKTRACE))
-		return;
-
-	event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
-					 &irq_flags);
+	event = trace_buffer_lock_reserve(tr, TRACE_STACK,
+					  sizeof(*entry), flags, pc);
 	if (!event)
 		return;
 	entry	= ring_buffer_event_data(event);
-	tracing_generic_entry_update(&entry->ent, flags, pc);
-	entry->ent.type		= TRACE_STACK;
-
 	memset(&entry->caller, 0, sizeof(entry->caller));
 
 	trace.nr_entries	= 0;
@@ -990,38 +999,43 @@
 	trace.entries		= entry->caller;
 
 	save_stack_trace(&trace);
-	ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
+	ring_buffer_unlock_commit(tr->buffer, event);
 #endif
 }
 
-void __trace_stack(struct trace_array *tr,
-		   struct trace_array_cpu *data,
-		   unsigned long flags,
-		   int skip)
+static void ftrace_trace_stack(struct trace_array *tr,
+			       unsigned long flags,
+			       int skip, int pc)
 {
-	ftrace_trace_stack(tr, data, flags, skip, preempt_count());
+	if (!(trace_flags & TRACE_ITER_STACKTRACE))
+		return;
+
+	__ftrace_trace_stack(tr, flags, skip, pc);
+}
+
+void __trace_stack(struct trace_array *tr,
+		   unsigned long flags,
+		   int skip, int pc)
+{
+	__ftrace_trace_stack(tr, flags, skip, pc);
 }
 
 static void ftrace_trace_userstack(struct trace_array *tr,
-		   struct trace_array_cpu *data,
-		   unsigned long flags, int pc)
+				   unsigned long flags, int pc)
 {
 #ifdef CONFIG_STACKTRACE
 	struct ring_buffer_event *event;
 	struct userstack_entry *entry;
 	struct stack_trace trace;
-	unsigned long irq_flags;
 
 	if (!(trace_flags & TRACE_ITER_USERSTACKTRACE))
 		return;
 
-	event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
-					 &irq_flags);
+	event = trace_buffer_lock_reserve(tr, TRACE_USER_STACK,
+					  sizeof(*entry), flags, pc);
 	if (!event)
 		return;
 	entry	= ring_buffer_event_data(event);
-	tracing_generic_entry_update(&entry->ent, flags, pc);
-	entry->ent.type		= TRACE_USER_STACK;
 
 	memset(&entry->caller, 0, sizeof(entry->caller));
 
@@ -1031,70 +1045,58 @@
 	trace.entries		= entry->caller;
 
 	save_stack_trace_user(&trace);
-	ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
+	ring_buffer_unlock_commit(tr->buffer, event);
 #endif
 }
 
-void __trace_userstack(struct trace_array *tr,
-		   struct trace_array_cpu *data,
-		   unsigned long flags)
+#ifdef UNUSED
+static void __trace_userstack(struct trace_array *tr, unsigned long flags)
 {
-	ftrace_trace_userstack(tr, data, flags, preempt_count());
+	ftrace_trace_userstack(tr, flags, preempt_count());
 }
+#endif /* UNUSED */
 
 static void
-ftrace_trace_special(void *__tr, void *__data,
+ftrace_trace_special(void *__tr,
 		     unsigned long arg1, unsigned long arg2, unsigned long arg3,
 		     int pc)
 {
 	struct ring_buffer_event *event;
-	struct trace_array_cpu *data = __data;
 	struct trace_array *tr = __tr;
 	struct special_entry *entry;
-	unsigned long irq_flags;
 
-	event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
-					 &irq_flags);
+	event = trace_buffer_lock_reserve(tr, TRACE_SPECIAL,
+					  sizeof(*entry), 0, pc);
 	if (!event)
 		return;
 	entry	= ring_buffer_event_data(event);
-	tracing_generic_entry_update(&entry->ent, 0, pc);
-	entry->ent.type			= TRACE_SPECIAL;
 	entry->arg1			= arg1;
 	entry->arg2			= arg2;
 	entry->arg3			= arg3;
-	ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
-	ftrace_trace_stack(tr, data, irq_flags, 4, pc);
-	ftrace_trace_userstack(tr, data, irq_flags, pc);
-
-	trace_wake_up();
+	trace_buffer_unlock_commit(tr, event, 0, pc);
 }
 
 void
 __trace_special(void *__tr, void *__data,
 		unsigned long arg1, unsigned long arg2, unsigned long arg3)
 {
-	ftrace_trace_special(__tr, __data, arg1, arg2, arg3, preempt_count());
+	ftrace_trace_special(__tr, arg1, arg2, arg3, preempt_count());
 }
 
 void
 tracing_sched_switch_trace(struct trace_array *tr,
-			   struct trace_array_cpu *data,
 			   struct task_struct *prev,
 			   struct task_struct *next,
 			   unsigned long flags, int pc)
 {
 	struct ring_buffer_event *event;
 	struct ctx_switch_entry *entry;
-	unsigned long irq_flags;
 
-	event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
-					   &irq_flags);
+	event = trace_buffer_lock_reserve(tr, TRACE_CTX,
+					  sizeof(*entry), flags, pc);
 	if (!event)
 		return;
 	entry	= ring_buffer_event_data(event);
-	tracing_generic_entry_update(&entry->ent, flags, pc);
-	entry->ent.type			= TRACE_CTX;
 	entry->prev_pid			= prev->pid;
 	entry->prev_prio		= prev->prio;
 	entry->prev_state		= prev->state;
@@ -1102,29 +1104,23 @@
 	entry->next_prio		= next->prio;
 	entry->next_state		= next->state;
 	entry->next_cpu	= task_cpu(next);
-	ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
-	ftrace_trace_stack(tr, data, flags, 5, pc);
-	ftrace_trace_userstack(tr, data, flags, pc);
+	trace_buffer_unlock_commit(tr, event, flags, pc);
 }
 
 void
 tracing_sched_wakeup_trace(struct trace_array *tr,
-			   struct trace_array_cpu *data,
 			   struct task_struct *wakee,
 			   struct task_struct *curr,
 			   unsigned long flags, int pc)
 {
 	struct ring_buffer_event *event;
 	struct ctx_switch_entry *entry;
-	unsigned long irq_flags;
 
-	event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
-					   &irq_flags);
+	event = trace_buffer_lock_reserve(tr, TRACE_WAKE,
+					  sizeof(*entry), flags, pc);
 	if (!event)
 		return;
 	entry	= ring_buffer_event_data(event);
-	tracing_generic_entry_update(&entry->ent, flags, pc);
-	entry->ent.type			= TRACE_WAKE;
 	entry->prev_pid			= curr->pid;
 	entry->prev_prio		= curr->prio;
 	entry->prev_state		= curr->state;
@@ -1132,11 +1128,10 @@
 	entry->next_prio		= wakee->prio;
 	entry->next_state		= wakee->state;
 	entry->next_cpu			= task_cpu(wakee);
-	ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
-	ftrace_trace_stack(tr, data, flags, 6, pc);
-	ftrace_trace_userstack(tr, data, flags, pc);
 
-	trace_wake_up();
+	ring_buffer_unlock_commit(tr->buffer, event);
+	ftrace_trace_stack(tr, flags, 6, pc);
+	ftrace_trace_userstack(tr, flags, pc);
 }
 
 void
@@ -1157,66 +1152,7 @@
 	data = tr->data[cpu];
 
 	if (likely(atomic_inc_return(&data->disabled) == 1))
-		ftrace_trace_special(tr, data, arg1, arg2, arg3, pc);
-
-	atomic_dec(&data->disabled);
-	local_irq_restore(flags);
-}
-
-#ifdef CONFIG_FUNCTION_TRACER
-static void
-function_trace_call_preempt_only(unsigned long ip, unsigned long parent_ip)
-{
-	struct trace_array *tr = &global_trace;
-	struct trace_array_cpu *data;
-	unsigned long flags;
-	long disabled;
-	int cpu, resched;
-	int pc;
-
-	if (unlikely(!ftrace_function_enabled))
-		return;
-
-	pc = preempt_count();
-	resched = ftrace_preempt_disable();
-	local_save_flags(flags);
-	cpu = raw_smp_processor_id();
-	data = tr->data[cpu];
-	disabled = atomic_inc_return(&data->disabled);
-
-	if (likely(disabled == 1))
-		trace_function(tr, data, ip, parent_ip, flags, pc);
-
-	atomic_dec(&data->disabled);
-	ftrace_preempt_enable(resched);
-}
-
-static void
-function_trace_call(unsigned long ip, unsigned long parent_ip)
-{
-	struct trace_array *tr = &global_trace;
-	struct trace_array_cpu *data;
-	unsigned long flags;
-	long disabled;
-	int cpu;
-	int pc;
-
-	if (unlikely(!ftrace_function_enabled))
-		return;
-
-	/*
-	 * Need to use raw, since this must be called before the
-	 * recursive protection is performed.
-	 */
-	local_irq_save(flags);
-	cpu = raw_smp_processor_id();
-	data = tr->data[cpu];
-	disabled = atomic_inc_return(&data->disabled);
-
-	if (likely(disabled == 1)) {
-		pc = preempt_count();
-		trace_function(tr, data, ip, parent_ip, flags, pc);
-	}
+		ftrace_trace_special(tr, arg1, arg2, arg3, pc);
 
 	atomic_dec(&data->disabled);
 	local_irq_restore(flags);
@@ -1229,6 +1165,7 @@
 	struct trace_array_cpu *data;
 	unsigned long flags;
 	long disabled;
+	int ret;
 	int cpu;
 	int pc;
 
@@ -1244,15 +1181,18 @@
 	disabled = atomic_inc_return(&data->disabled);
 	if (likely(disabled == 1)) {
 		pc = preempt_count();
-		__trace_graph_entry(tr, data, trace, flags, pc);
+		ret = __trace_graph_entry(tr, trace, flags, pc);
+	} else {
+		ret = 0;
 	}
 	/* Only do the atomic if it is not already set */
 	if (!test_tsk_trace_graph(current))
 		set_tsk_trace_graph(current);
+
 	atomic_dec(&data->disabled);
 	local_irq_restore(flags);
 
-	return 1;
+	return ret;
 }
 
 void trace_graph_return(struct ftrace_graph_ret *trace)
@@ -1270,7 +1210,7 @@
 	disabled = atomic_inc_return(&data->disabled);
 	if (likely(disabled == 1)) {
 		pc = preempt_count();
-		__trace_graph_return(tr, data, trace, flags, pc);
+		__trace_graph_return(tr, trace, flags, pc);
 	}
 	if (!trace->depth)
 		clear_tsk_trace_graph(current);
@@ -1279,30 +1219,122 @@
 }
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
 
-static struct ftrace_ops trace_ops __read_mostly =
+
+/**
+ * trace_vbprintk - write binary msg to tracing buffer
+ *
+ */
+int trace_vbprintk(unsigned long ip, const char *fmt, va_list args)
 {
-	.func = function_trace_call,
-};
+	static raw_spinlock_t trace_buf_lock =
+		(raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
+	static u32 trace_buf[TRACE_BUF_SIZE];
 
-void tracing_start_function_trace(void)
-{
-	ftrace_function_enabled = 0;
+	struct ring_buffer_event *event;
+	struct trace_array *tr = &global_trace;
+	struct trace_array_cpu *data;
+	struct bprint_entry *entry;
+	unsigned long flags;
+	int resched;
+	int cpu, len = 0, size, pc;
 
-	if (trace_flags & TRACE_ITER_PREEMPTONLY)
-		trace_ops.func = function_trace_call_preempt_only;
-	else
-		trace_ops.func = function_trace_call;
+	if (unlikely(tracing_selftest_running || tracing_disabled))
+		return 0;
 
-	register_ftrace_function(&trace_ops);
-	ftrace_function_enabled = 1;
+	/* Don't pollute graph traces with trace_vprintk internals */
+	pause_graph_tracing();
+
+	pc = preempt_count();
+	resched = ftrace_preempt_disable();
+	cpu = raw_smp_processor_id();
+	data = tr->data[cpu];
+
+	if (unlikely(atomic_read(&data->disabled)))
+		goto out;
+
+	/* Lockdep uses trace_printk for lock tracing */
+	local_irq_save(flags);
+	__raw_spin_lock(&trace_buf_lock);
+	len = vbin_printf(trace_buf, TRACE_BUF_SIZE, fmt, args);
+
+	if (len > TRACE_BUF_SIZE || len < 0)
+		goto out_unlock;
+
+	size = sizeof(*entry) + sizeof(u32) * len;
+	event = trace_buffer_lock_reserve(tr, TRACE_BPRINT, size, flags, pc);
+	if (!event)
+		goto out_unlock;
+	entry = ring_buffer_event_data(event);
+	entry->ip			= ip;
+	entry->fmt			= fmt;
+
+	memcpy(entry->buf, trace_buf, sizeof(u32) * len);
+	ring_buffer_unlock_commit(tr->buffer, event);
+
+out_unlock:
+	__raw_spin_unlock(&trace_buf_lock);
+	local_irq_restore(flags);
+
+out:
+	ftrace_preempt_enable(resched);
+	unpause_graph_tracing();
+
+	return len;
 }
+EXPORT_SYMBOL_GPL(trace_vbprintk);
 
-void tracing_stop_function_trace(void)
+int trace_vprintk(unsigned long ip, const char *fmt, va_list args)
 {
-	ftrace_function_enabled = 0;
-	unregister_ftrace_function(&trace_ops);
+	static raw_spinlock_t trace_buf_lock = __RAW_SPIN_LOCK_UNLOCKED;
+	static char trace_buf[TRACE_BUF_SIZE];
+
+	struct ring_buffer_event *event;
+	struct trace_array *tr = &global_trace;
+	struct trace_array_cpu *data;
+	int cpu, len = 0, size, pc;
+	struct print_entry *entry;
+	unsigned long irq_flags;
+
+	if (tracing_disabled || tracing_selftest_running)
+		return 0;
+
+	pc = preempt_count();
+	preempt_disable_notrace();
+	cpu = raw_smp_processor_id();
+	data = tr->data[cpu];
+
+	if (unlikely(atomic_read(&data->disabled)))
+		goto out;
+
+	pause_graph_tracing();
+	raw_local_irq_save(irq_flags);
+	__raw_spin_lock(&trace_buf_lock);
+	len = vsnprintf(trace_buf, TRACE_BUF_SIZE, fmt, args);
+
+	len = min(len, TRACE_BUF_SIZE-1);
+	trace_buf[len] = 0;
+
+	size = sizeof(*entry) + len + 1;
+	event = trace_buffer_lock_reserve(tr, TRACE_PRINT, size, irq_flags, pc);
+	if (!event)
+		goto out_unlock;
+	entry = ring_buffer_event_data(event);
+	entry->ip			= ip;
+
+	memcpy(&entry->buf, trace_buf, len);
+	entry->buf[len] = 0;
+	ring_buffer_unlock_commit(tr->buffer, event);
+
+ out_unlock:
+	__raw_spin_unlock(&trace_buf_lock);
+	raw_local_irq_restore(irq_flags);
+	unpause_graph_tracing();
+ out:
+	preempt_enable_notrace();
+
+	return len;
 }
-#endif
+EXPORT_SYMBOL_GPL(trace_vprintk);
 
 enum trace_file_type {
 	TRACE_FILE_LAT_FMT	= 1,
@@ -1345,10 +1377,25 @@
 {
 	struct ring_buffer *buffer = iter->tr->buffer;
 	struct trace_entry *ent, *next = NULL;
+	int cpu_file = iter->cpu_file;
 	u64 next_ts = 0, ts;
 	int next_cpu = -1;
 	int cpu;
 
+	/*
+	 * If we are in a per_cpu trace file, don't bother by iterating over
+	 * all cpu and peek directly.
+	 */
+	if (cpu_file > TRACE_PIPE_ALL_CPU) {
+		if (ring_buffer_empty_cpu(buffer, cpu_file))
+			return NULL;
+		ent = peek_next_entry(iter, cpu_file, ent_ts);
+		if (ent_cpu)
+			*ent_cpu = cpu_file;
+
+		return ent;
+	}
+
 	for_each_tracing_cpu(cpu) {
 
 		if (ring_buffer_empty_cpu(buffer, cpu))
@@ -1376,8 +1423,8 @@
 }
 
 /* Find the next real entry, without updating the iterator itself */
-static struct trace_entry *
-find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts)
+struct trace_entry *trace_find_next_entry(struct trace_iterator *iter,
+					  int *ent_cpu, u64 *ent_ts)
 {
 	return __find_next_entry(iter, ent_cpu, ent_ts);
 }
@@ -1426,19 +1473,32 @@
 	return ent;
 }
 
+/*
+ * No necessary locking here. The worst thing which can
+ * happen is loosing events consumed at the same time
+ * by a trace_pipe reader.
+ * Other than that, we don't risk to crash the ring buffer
+ * because it serializes the readers.
+ *
+ * The current tracer is copied to avoid a global locking
+ * all around.
+ */
 static void *s_start(struct seq_file *m, loff_t *pos)
 {
 	struct trace_iterator *iter = m->private;
+	static struct tracer *old_tracer;
+	int cpu_file = iter->cpu_file;
 	void *p = NULL;
 	loff_t l = 0;
 	int cpu;
 
+	/* copy the tracer to avoid using a global lock all around */
 	mutex_lock(&trace_types_lock);
-
-	if (!current_trace || current_trace != iter->trace) {
-		mutex_unlock(&trace_types_lock);
-		return NULL;
+	if (unlikely(old_tracer != current_trace && current_trace)) {
+		old_tracer = current_trace;
+		*iter->trace = *current_trace;
 	}
+	mutex_unlock(&trace_types_lock);
 
 	atomic_inc(&trace_record_cmdline_disabled);
 
@@ -1449,9 +1509,12 @@
 
 		ftrace_disable_cpu();
 
-		for_each_tracing_cpu(cpu) {
-			ring_buffer_iter_reset(iter->buffer_iter[cpu]);
-		}
+		if (cpu_file == TRACE_PIPE_ALL_CPU) {
+			for_each_tracing_cpu(cpu)
+				ring_buffer_iter_reset(iter->buffer_iter[cpu]);
+		} else
+			ring_buffer_iter_reset(iter->buffer_iter[cpu_file]);
+
 
 		ftrace_enable_cpu();
 
@@ -1469,155 +1532,6 @@
 static void s_stop(struct seq_file *m, void *p)
 {
 	atomic_dec(&trace_record_cmdline_disabled);
-	mutex_unlock(&trace_types_lock);
-}
-
-#ifdef CONFIG_KRETPROBES
-static inline const char *kretprobed(const char *name)
-{
-	static const char tramp_name[] = "kretprobe_trampoline";
-	int size = sizeof(tramp_name);
-
-	if (strncmp(tramp_name, name, size) == 0)
-		return "[unknown/kretprobe'd]";
-	return name;
-}
-#else
-static inline const char *kretprobed(const char *name)
-{
-	return name;
-}
-#endif /* CONFIG_KRETPROBES */
-
-static int
-seq_print_sym_short(struct trace_seq *s, const char *fmt, unsigned long address)
-{
-#ifdef CONFIG_KALLSYMS
-	char str[KSYM_SYMBOL_LEN];
-	const char *name;
-
-	kallsyms_lookup(address, NULL, NULL, NULL, str);
-
-	name = kretprobed(str);
-
-	return trace_seq_printf(s, fmt, name);
-#endif
-	return 1;
-}
-
-static int
-seq_print_sym_offset(struct trace_seq *s, const char *fmt,
-		     unsigned long address)
-{
-#ifdef CONFIG_KALLSYMS
-	char str[KSYM_SYMBOL_LEN];
-	const char *name;
-
-	sprint_symbol(str, address);
-	name = kretprobed(str);
-
-	return trace_seq_printf(s, fmt, name);
-#endif
-	return 1;
-}
-
-#ifndef CONFIG_64BIT
-# define IP_FMT "%08lx"
-#else
-# define IP_FMT "%016lx"
-#endif
-
-int
-seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags)
-{
-	int ret;
-
-	if (!ip)
-		return trace_seq_printf(s, "0");
-
-	if (sym_flags & TRACE_ITER_SYM_OFFSET)
-		ret = seq_print_sym_offset(s, "%s", ip);
-	else
-		ret = seq_print_sym_short(s, "%s", ip);
-
-	if (!ret)
-		return 0;
-
-	if (sym_flags & TRACE_ITER_SYM_ADDR)
-		ret = trace_seq_printf(s, " <" IP_FMT ">", ip);
-	return ret;
-}
-
-static inline int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm,
-				    unsigned long ip, unsigned long sym_flags)
-{
-	struct file *file = NULL;
-	unsigned long vmstart = 0;
-	int ret = 1;
-
-	if (mm) {
-		const struct vm_area_struct *vma;
-
-		down_read(&mm->mmap_sem);
-		vma = find_vma(mm, ip);
-		if (vma) {
-			file = vma->vm_file;
-			vmstart = vma->vm_start;
-		}
-		if (file) {
-			ret = trace_seq_path(s, &file->f_path);
-			if (ret)
-				ret = trace_seq_printf(s, "[+0x%lx]", ip - vmstart);
-		}
-		up_read(&mm->mmap_sem);
-	}
-	if (ret && ((sym_flags & TRACE_ITER_SYM_ADDR) || !file))
-		ret = trace_seq_printf(s, " <" IP_FMT ">", ip);
-	return ret;
-}
-
-static int
-seq_print_userip_objs(const struct userstack_entry *entry, struct trace_seq *s,
-		      unsigned long sym_flags)
-{
-	struct mm_struct *mm = NULL;
-	int ret = 1;
-	unsigned int i;
-
-	if (trace_flags & TRACE_ITER_SYM_USEROBJ) {
-		struct task_struct *task;
-		/*
-		 * we do the lookup on the thread group leader,
-		 * since individual threads might have already quit!
-		 */
-		rcu_read_lock();
-		task = find_task_by_vpid(entry->ent.tgid);
-		if (task)
-			mm = get_task_mm(task);
-		rcu_read_unlock();
-	}
-
-	for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
-		unsigned long ip = entry->caller[i];
-
-		if (ip == ULONG_MAX || !ret)
-			break;
-		if (i && ret)
-			ret = trace_seq_puts(s, " <- ");
-		if (!ip) {
-			if (ret)
-				ret = trace_seq_puts(s, "??");
-			continue;
-		}
-		if (!ret)
-			break;
-		if (ret)
-			ret = seq_print_user_ip(s, mm, ip, sym_flags);
-	}
-
-	if (mm)
-		mmput(mm);
-	return ret;
 }
 
 static void print_lat_help_header(struct seq_file *m)
@@ -1658,11 +1572,11 @@
 	total = entries +
 		ring_buffer_overruns(iter->tr->buffer);
 
-	seq_printf(m, "%s latency trace v1.1.5 on %s\n",
+	seq_printf(m, "# %s latency trace v1.1.5 on %s\n",
 		   name, UTS_RELEASE);
-	seq_puts(m, "-----------------------------------"
+	seq_puts(m, "# -----------------------------------"
 		 "---------------------------------\n");
-	seq_printf(m, " latency: %lu us, #%lu/%lu, CPU#%d |"
+	seq_printf(m, "# latency: %lu us, #%lu/%lu, CPU#%d |"
 		   " (M:%s VP:%d, KP:%d, SP:%d HP:%d",
 		   nsecs_to_usecs(data->saved_latency),
 		   entries,
@@ -1684,121 +1598,24 @@
 #else
 	seq_puts(m, ")\n");
 #endif
-	seq_puts(m, "    -----------------\n");
-	seq_printf(m, "    | task: %.16s-%d "
+	seq_puts(m, "#    -----------------\n");
+	seq_printf(m, "#    | task: %.16s-%d "
 		   "(uid:%d nice:%ld policy:%ld rt_prio:%ld)\n",
 		   data->comm, data->pid, data->uid, data->nice,
 		   data->policy, data->rt_priority);
-	seq_puts(m, "    -----------------\n");
+	seq_puts(m, "#    -----------------\n");
 
 	if (data->critical_start) {
-		seq_puts(m, " => started at: ");
+		seq_puts(m, "#  => started at: ");
 		seq_print_ip_sym(&iter->seq, data->critical_start, sym_flags);
 		trace_print_seq(m, &iter->seq);
-		seq_puts(m, "\n => ended at:   ");
+		seq_puts(m, "\n#  => ended at:   ");
 		seq_print_ip_sym(&iter->seq, data->critical_end, sym_flags);
 		trace_print_seq(m, &iter->seq);
-		seq_puts(m, "\n");
+		seq_puts(m, "#\n");
 	}
 
-	seq_puts(m, "\n");
-}
-
-static void
-lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
-{
-	int hardirq, softirq;
-	char *comm;
-
-	comm = trace_find_cmdline(entry->pid);
-
-	trace_seq_printf(s, "%8.8s-%-5d ", comm, entry->pid);
-	trace_seq_printf(s, "%3d", cpu);
-	trace_seq_printf(s, "%c%c",
-			(entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
-			 (entry->flags & TRACE_FLAG_IRQS_NOSUPPORT) ? 'X' : '.',
-			((entry->flags & TRACE_FLAG_NEED_RESCHED) ? 'N' : '.'));
-
-	hardirq = entry->flags & TRACE_FLAG_HARDIRQ;
-	softirq = entry->flags & TRACE_FLAG_SOFTIRQ;
-	if (hardirq && softirq) {
-		trace_seq_putc(s, 'H');
-	} else {
-		if (hardirq) {
-			trace_seq_putc(s, 'h');
-		} else {
-			if (softirq)
-				trace_seq_putc(s, 's');
-			else
-				trace_seq_putc(s, '.');
-		}
-	}
-
-	if (entry->preempt_count)
-		trace_seq_printf(s, "%x", entry->preempt_count);
-	else
-		trace_seq_puts(s, ".");
-}
-
-unsigned long preempt_mark_thresh = 100;
-
-static void
-lat_print_timestamp(struct trace_seq *s, u64 abs_usecs,
-		    unsigned long rel_usecs)
-{
-	trace_seq_printf(s, " %4lldus", abs_usecs);
-	if (rel_usecs > preempt_mark_thresh)
-		trace_seq_puts(s, "!: ");
-	else if (rel_usecs > 1)
-		trace_seq_puts(s, "+: ");
-	else
-		trace_seq_puts(s, " : ");
-}
-
-static const char state_to_char[] = TASK_STATE_TO_CHAR_STR;
-
-static int task_state_char(unsigned long state)
-{
-	int bit = state ? __ffs(state) + 1 : 0;
-
-	return bit < sizeof(state_to_char) - 1 ? state_to_char[bit] : '?';
-}
-
-/*
- * The message is supposed to contain an ending newline.
- * If the printing stops prematurely, try to add a newline of our own.
- */
-void trace_seq_print_cont(struct trace_seq *s, struct trace_iterator *iter)
-{
-	struct trace_entry *ent;
-	struct trace_field_cont *cont;
-	bool ok = true;
-
-	ent = peek_next_entry(iter, iter->cpu, NULL);
-	if (!ent || ent->type != TRACE_CONT) {
-		trace_seq_putc(s, '\n');
-		return;
-	}
-
-	do {
-		cont = (struct trace_field_cont *)ent;
-		if (ok)
-			ok = (trace_seq_printf(s, "%s", cont->buf) > 0);
-
-		ftrace_disable_cpu();
-
-		if (iter->buffer_iter[iter->cpu])
-			ring_buffer_read(iter->buffer_iter[iter->cpu], NULL);
-		else
-			ring_buffer_consume(iter->tr->buffer, iter->cpu, NULL);
-
-		ftrace_enable_cpu();
-
-		ent = peek_next_entry(iter, iter->cpu, NULL);
-	} while (ent && ent->type == TRACE_CONT);
-
-	if (!ok)
-		trace_seq_putc(s, '\n');
+	seq_puts(m, "#\n");
 }
 
 static void test_cpu_buff_start(struct trace_iterator *iter)
@@ -1818,533 +1635,128 @@
 	trace_seq_printf(s, "##### CPU %u buffer started ####\n", iter->cpu);
 }
 
-static enum print_line_t
-print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu)
-{
-	struct trace_seq *s = &iter->seq;
-	unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK);
-	struct trace_entry *next_entry;
-	unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE);
-	struct trace_entry *entry = iter->ent;
-	unsigned long abs_usecs;
-	unsigned long rel_usecs;
-	u64 next_ts;
-	char *comm;
-	int S, T;
-	int i;
-
-	if (entry->type == TRACE_CONT)
-		return TRACE_TYPE_HANDLED;
-
-	test_cpu_buff_start(iter);
-
-	next_entry = find_next_entry(iter, NULL, &next_ts);
-	if (!next_entry)
-		next_ts = iter->ts;
-	rel_usecs = ns2usecs(next_ts - iter->ts);
-	abs_usecs = ns2usecs(iter->ts - iter->tr->time_start);
-
-	if (verbose) {
-		comm = trace_find_cmdline(entry->pid);
-		trace_seq_printf(s, "%16s %5d %3d %d %08x %08x [%08lx]"
-				 " %ld.%03ldms (+%ld.%03ldms): ",
-				 comm,
-				 entry->pid, cpu, entry->flags,
-				 entry->preempt_count, trace_idx,
-				 ns2usecs(iter->ts),
-				 abs_usecs/1000,
-				 abs_usecs % 1000, rel_usecs/1000,
-				 rel_usecs % 1000);
-	} else {
-		lat_print_generic(s, entry, cpu);
-		lat_print_timestamp(s, abs_usecs, rel_usecs);
-	}
-	switch (entry->type) {
-	case TRACE_FN: {
-		struct ftrace_entry *field;
-
-		trace_assign_type(field, entry);
-
-		seq_print_ip_sym(s, field->ip, sym_flags);
-		trace_seq_puts(s, " (");
-		seq_print_ip_sym(s, field->parent_ip, sym_flags);
-		trace_seq_puts(s, ")\n");
-		break;
-	}
-	case TRACE_CTX:
-	case TRACE_WAKE: {
-		struct ctx_switch_entry *field;
-
-		trace_assign_type(field, entry);
-
-		T = task_state_char(field->next_state);
-		S = task_state_char(field->prev_state);
-		comm = trace_find_cmdline(field->next_pid);
-		trace_seq_printf(s, " %5d:%3d:%c %s [%03d] %5d:%3d:%c %s\n",
-				 field->prev_pid,
-				 field->prev_prio,
-				 S, entry->type == TRACE_CTX ? "==>" : "  +",
-				 field->next_cpu,
-				 field->next_pid,
-				 field->next_prio,
-				 T, comm);
-		break;
-	}
-	case TRACE_SPECIAL: {
-		struct special_entry *field;
-
-		trace_assign_type(field, entry);
-
-		trace_seq_printf(s, "# %ld %ld %ld\n",
-				 field->arg1,
-				 field->arg2,
-				 field->arg3);
-		break;
-	}
-	case TRACE_STACK: {
-		struct stack_entry *field;
-
-		trace_assign_type(field, entry);
-
-		for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
-			if (i)
-				trace_seq_puts(s, " <= ");
-			seq_print_ip_sym(s, field->caller[i], sym_flags);
-		}
-		trace_seq_puts(s, "\n");
-		break;
-	}
-	case TRACE_PRINT: {
-		struct print_entry *field;
-
-		trace_assign_type(field, entry);
-
-		seq_print_ip_sym(s, field->ip, sym_flags);
-		trace_seq_printf(s, ": %s", field->buf);
-		if (entry->flags & TRACE_FLAG_CONT)
-			trace_seq_print_cont(s, iter);
-		break;
-	}
-	case TRACE_BRANCH: {
-		struct trace_branch *field;
-
-		trace_assign_type(field, entry);
-
-		trace_seq_printf(s, "[%s] %s:%s:%d\n",
-				 field->correct ? "  ok  " : " MISS ",
-				 field->func,
-				 field->file,
-				 field->line);
-		break;
-	}
-	case TRACE_USER_STACK: {
-		struct userstack_entry *field;
-
-		trace_assign_type(field, entry);
-
-		seq_print_userip_objs(field, s, sym_flags);
-		trace_seq_putc(s, '\n');
-		break;
-	}
-	default:
-		trace_seq_printf(s, "Unknown type %d\n", entry->type);
-	}
-	return TRACE_TYPE_HANDLED;
-}
-
 static enum print_line_t print_trace_fmt(struct trace_iterator *iter)
 {
 	struct trace_seq *s = &iter->seq;
 	unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK);
 	struct trace_entry *entry;
-	unsigned long usec_rem;
-	unsigned long long t;
-	unsigned long secs;
-	char *comm;
-	int ret;
-	int S, T;
-	int i;
+	struct trace_event *event;
 
 	entry = iter->ent;
 
-	if (entry->type == TRACE_CONT)
-		return TRACE_TYPE_HANDLED;
-
 	test_cpu_buff_start(iter);
 
-	comm = trace_find_cmdline(iter->ent->pid);
+	event = ftrace_find_event(entry->type);
 
-	t = ns2usecs(iter->ts);
-	usec_rem = do_div(t, 1000000ULL);
-	secs = (unsigned long)t;
-
-	ret = trace_seq_printf(s, "%16s-%-5d ", comm, entry->pid);
-	if (!ret)
-		return TRACE_TYPE_PARTIAL_LINE;
-	ret = trace_seq_printf(s, "[%03d] ", iter->cpu);
-	if (!ret)
-		return TRACE_TYPE_PARTIAL_LINE;
-	ret = trace_seq_printf(s, "%5lu.%06lu: ", secs, usec_rem);
-	if (!ret)
-		return TRACE_TYPE_PARTIAL_LINE;
-
-	switch (entry->type) {
-	case TRACE_FN: {
-		struct ftrace_entry *field;
-
-		trace_assign_type(field, entry);
-
-		ret = seq_print_ip_sym(s, field->ip, sym_flags);
-		if (!ret)
-			return TRACE_TYPE_PARTIAL_LINE;
-		if ((sym_flags & TRACE_ITER_PRINT_PARENT) &&
-						field->parent_ip) {
-			ret = trace_seq_printf(s, " <-");
-			if (!ret)
-				return TRACE_TYPE_PARTIAL_LINE;
-			ret = seq_print_ip_sym(s,
-					       field->parent_ip,
-					       sym_flags);
-			if (!ret)
-				return TRACE_TYPE_PARTIAL_LINE;
+	if (trace_flags & TRACE_ITER_CONTEXT_INFO) {
+		if (iter->iter_flags & TRACE_FILE_LAT_FMT) {
+			if (!trace_print_lat_context(iter))
+				goto partial;
+		} else {
+			if (!trace_print_context(iter))
+				goto partial;
 		}
-		ret = trace_seq_printf(s, "\n");
-		if (!ret)
-			return TRACE_TYPE_PARTIAL_LINE;
-		break;
 	}
-	case TRACE_CTX:
-	case TRACE_WAKE: {
-		struct ctx_switch_entry *field;
 
-		trace_assign_type(field, entry);
+	if (event)
+		return event->trace(iter, sym_flags);
 
-		T = task_state_char(field->next_state);
-		S = task_state_char(field->prev_state);
-		ret = trace_seq_printf(s, " %5d:%3d:%c %s [%03d] %5d:%3d:%c\n",
-				       field->prev_pid,
-				       field->prev_prio,
-				       S,
-				       entry->type == TRACE_CTX ? "==>" : "  +",
-				       field->next_cpu,
-				       field->next_pid,
-				       field->next_prio,
-				       T);
-		if (!ret)
-			return TRACE_TYPE_PARTIAL_LINE;
-		break;
-	}
-	case TRACE_SPECIAL: {
-		struct special_entry *field;
+	if (!trace_seq_printf(s, "Unknown type %d\n", entry->type))
+		goto partial;
 
-		trace_assign_type(field, entry);
-
-		ret = trace_seq_printf(s, "# %ld %ld %ld\n",
-				 field->arg1,
-				 field->arg2,
-				 field->arg3);
-		if (!ret)
-			return TRACE_TYPE_PARTIAL_LINE;
-		break;
-	}
-	case TRACE_STACK: {
-		struct stack_entry *field;
-
-		trace_assign_type(field, entry);
-
-		for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
-			if (i) {
-				ret = trace_seq_puts(s, " <= ");
-				if (!ret)
-					return TRACE_TYPE_PARTIAL_LINE;
-			}
-			ret = seq_print_ip_sym(s, field->caller[i],
-					       sym_flags);
-			if (!ret)
-				return TRACE_TYPE_PARTIAL_LINE;
-		}
-		ret = trace_seq_puts(s, "\n");
-		if (!ret)
-			return TRACE_TYPE_PARTIAL_LINE;
-		break;
-	}
-	case TRACE_PRINT: {
-		struct print_entry *field;
-
-		trace_assign_type(field, entry);
-
-		seq_print_ip_sym(s, field->ip, sym_flags);
-		trace_seq_printf(s, ": %s", field->buf);
-		if (entry->flags & TRACE_FLAG_CONT)
-			trace_seq_print_cont(s, iter);
-		break;
-	}
-	case TRACE_GRAPH_RET: {
-		return print_graph_function(iter);
-	}
-	case TRACE_GRAPH_ENT: {
-		return print_graph_function(iter);
-	}
-	case TRACE_BRANCH: {
-		struct trace_branch *field;
-
-		trace_assign_type(field, entry);
-
-		trace_seq_printf(s, "[%s] %s:%s:%d\n",
-				 field->correct ? "  ok  " : " MISS ",
-				 field->func,
-				 field->file,
-				 field->line);
-		break;
-	}
-	case TRACE_USER_STACK: {
-		struct userstack_entry *field;
-
-		trace_assign_type(field, entry);
-
-		ret = seq_print_userip_objs(field, s, sym_flags);
-		if (!ret)
-			return TRACE_TYPE_PARTIAL_LINE;
-		ret = trace_seq_putc(s, '\n');
-		if (!ret)
-			return TRACE_TYPE_PARTIAL_LINE;
-		break;
-	}
-	}
 	return TRACE_TYPE_HANDLED;
+partial:
+	return TRACE_TYPE_PARTIAL_LINE;
 }
 
 static enum print_line_t print_raw_fmt(struct trace_iterator *iter)
 {
 	struct trace_seq *s = &iter->seq;
 	struct trace_entry *entry;
-	int ret;
-	int S, T;
+	struct trace_event *event;
 
 	entry = iter->ent;
 
-	if (entry->type == TRACE_CONT)
-		return TRACE_TYPE_HANDLED;
-
-	ret = trace_seq_printf(s, "%d %d %llu ",
-		entry->pid, iter->cpu, iter->ts);
-	if (!ret)
-		return TRACE_TYPE_PARTIAL_LINE;
-
-	switch (entry->type) {
-	case TRACE_FN: {
-		struct ftrace_entry *field;
-
-		trace_assign_type(field, entry);
-
-		ret = trace_seq_printf(s, "%x %x\n",
-					field->ip,
-					field->parent_ip);
-		if (!ret)
-			return TRACE_TYPE_PARTIAL_LINE;
-		break;
+	if (trace_flags & TRACE_ITER_CONTEXT_INFO) {
+		if (!trace_seq_printf(s, "%d %d %llu ",
+				      entry->pid, iter->cpu, iter->ts))
+			goto partial;
 	}
-	case TRACE_CTX:
-	case TRACE_WAKE: {
-		struct ctx_switch_entry *field;
 
-		trace_assign_type(field, entry);
+	event = ftrace_find_event(entry->type);
+	if (event)
+		return event->raw(iter, 0);
 
-		T = task_state_char(field->next_state);
-		S = entry->type == TRACE_WAKE ? '+' :
-			task_state_char(field->prev_state);
-		ret = trace_seq_printf(s, "%d %d %c %d %d %d %c\n",
-				       field->prev_pid,
-				       field->prev_prio,
-				       S,
-				       field->next_cpu,
-				       field->next_pid,
-				       field->next_prio,
-				       T);
-		if (!ret)
-			return TRACE_TYPE_PARTIAL_LINE;
-		break;
-	}
-	case TRACE_SPECIAL:
-	case TRACE_USER_STACK:
-	case TRACE_STACK: {
-		struct special_entry *field;
+	if (!trace_seq_printf(s, "%d ?\n", entry->type))
+		goto partial;
 
-		trace_assign_type(field, entry);
-
-		ret = trace_seq_printf(s, "# %ld %ld %ld\n",
-				 field->arg1,
-				 field->arg2,
-				 field->arg3);
-		if (!ret)
-			return TRACE_TYPE_PARTIAL_LINE;
-		break;
-	}
-	case TRACE_PRINT: {
-		struct print_entry *field;
-
-		trace_assign_type(field, entry);
-
-		trace_seq_printf(s, "# %lx %s", field->ip, field->buf);
-		if (entry->flags & TRACE_FLAG_CONT)
-			trace_seq_print_cont(s, iter);
-		break;
-	}
-	}
 	return TRACE_TYPE_HANDLED;
+partial:
+	return TRACE_TYPE_PARTIAL_LINE;
 }
 
-#define SEQ_PUT_FIELD_RET(s, x)				\
-do {							\
-	if (!trace_seq_putmem(s, &(x), sizeof(x)))	\
-		return 0;				\
-} while (0)
-
-#define SEQ_PUT_HEX_FIELD_RET(s, x)			\
-do {							\
-	BUILD_BUG_ON(sizeof(x) > MAX_MEMHEX_BYTES);	\
-	if (!trace_seq_putmem_hex(s, &(x), sizeof(x)))	\
-		return 0;				\
-} while (0)
-
 static enum print_line_t print_hex_fmt(struct trace_iterator *iter)
 {
 	struct trace_seq *s = &iter->seq;
 	unsigned char newline = '\n';
 	struct trace_entry *entry;
-	int S, T;
+	struct trace_event *event;
 
 	entry = iter->ent;
 
-	if (entry->type == TRACE_CONT)
-		return TRACE_TYPE_HANDLED;
-
-	SEQ_PUT_HEX_FIELD_RET(s, entry->pid);
-	SEQ_PUT_HEX_FIELD_RET(s, iter->cpu);
-	SEQ_PUT_HEX_FIELD_RET(s, iter->ts);
-
-	switch (entry->type) {
-	case TRACE_FN: {
-		struct ftrace_entry *field;
-
-		trace_assign_type(field, entry);
-
-		SEQ_PUT_HEX_FIELD_RET(s, field->ip);
-		SEQ_PUT_HEX_FIELD_RET(s, field->parent_ip);
-		break;
+	if (trace_flags & TRACE_ITER_CONTEXT_INFO) {
+		SEQ_PUT_HEX_FIELD_RET(s, entry->pid);
+		SEQ_PUT_HEX_FIELD_RET(s, iter->cpu);
+		SEQ_PUT_HEX_FIELD_RET(s, iter->ts);
 	}
-	case TRACE_CTX:
-	case TRACE_WAKE: {
-		struct ctx_switch_entry *field;
 
-		trace_assign_type(field, entry);
-
-		T = task_state_char(field->next_state);
-		S = entry->type == TRACE_WAKE ? '+' :
-			task_state_char(field->prev_state);
-		SEQ_PUT_HEX_FIELD_RET(s, field->prev_pid);
-		SEQ_PUT_HEX_FIELD_RET(s, field->prev_prio);
-		SEQ_PUT_HEX_FIELD_RET(s, S);
-		SEQ_PUT_HEX_FIELD_RET(s, field->next_cpu);
-		SEQ_PUT_HEX_FIELD_RET(s, field->next_pid);
-		SEQ_PUT_HEX_FIELD_RET(s, field->next_prio);
-		SEQ_PUT_HEX_FIELD_RET(s, T);
-		break;
+	event = ftrace_find_event(entry->type);
+	if (event) {
+		enum print_line_t ret = event->hex(iter, 0);
+		if (ret != TRACE_TYPE_HANDLED)
+			return ret;
 	}
-	case TRACE_SPECIAL:
-	case TRACE_USER_STACK:
-	case TRACE_STACK: {
-		struct special_entry *field;
 
-		trace_assign_type(field, entry);
-
-		SEQ_PUT_HEX_FIELD_RET(s, field->arg1);
-		SEQ_PUT_HEX_FIELD_RET(s, field->arg2);
-		SEQ_PUT_HEX_FIELD_RET(s, field->arg3);
-		break;
-	}
-	}
 	SEQ_PUT_FIELD_RET(s, newline);
 
 	return TRACE_TYPE_HANDLED;
 }
 
-static enum print_line_t print_printk_msg_only(struct trace_iterator *iter)
-{
-	struct trace_seq *s = &iter->seq;
-	struct trace_entry *entry = iter->ent;
-	struct print_entry *field;
-	int ret;
-
-	trace_assign_type(field, entry);
-
-	ret = trace_seq_printf(s, field->buf);
-	if (!ret)
-		return TRACE_TYPE_PARTIAL_LINE;
-
-	if (entry->flags & TRACE_FLAG_CONT)
-		trace_seq_print_cont(s, iter);
-
-	return TRACE_TYPE_HANDLED;
-}
-
 static enum print_line_t print_bin_fmt(struct trace_iterator *iter)
 {
 	struct trace_seq *s = &iter->seq;
 	struct trace_entry *entry;
+	struct trace_event *event;
 
 	entry = iter->ent;
 
-	if (entry->type == TRACE_CONT)
-		return TRACE_TYPE_HANDLED;
-
-	SEQ_PUT_FIELD_RET(s, entry->pid);
-	SEQ_PUT_FIELD_RET(s, entry->cpu);
-	SEQ_PUT_FIELD_RET(s, iter->ts);
-
-	switch (entry->type) {
-	case TRACE_FN: {
-		struct ftrace_entry *field;
-
-		trace_assign_type(field, entry);
-
-		SEQ_PUT_FIELD_RET(s, field->ip);
-		SEQ_PUT_FIELD_RET(s, field->parent_ip);
-		break;
+	if (trace_flags & TRACE_ITER_CONTEXT_INFO) {
+		SEQ_PUT_FIELD_RET(s, entry->pid);
+		SEQ_PUT_FIELD_RET(s, iter->cpu);
+		SEQ_PUT_FIELD_RET(s, iter->ts);
 	}
-	case TRACE_CTX: {
-		struct ctx_switch_entry *field;
 
-		trace_assign_type(field, entry);
-
-		SEQ_PUT_FIELD_RET(s, field->prev_pid);
-		SEQ_PUT_FIELD_RET(s, field->prev_prio);
-		SEQ_PUT_FIELD_RET(s, field->prev_state);
-		SEQ_PUT_FIELD_RET(s, field->next_pid);
-		SEQ_PUT_FIELD_RET(s, field->next_prio);
-		SEQ_PUT_FIELD_RET(s, field->next_state);
-		break;
-	}
-	case TRACE_SPECIAL:
-	case TRACE_USER_STACK:
-	case TRACE_STACK: {
-		struct special_entry *field;
-
-		trace_assign_type(field, entry);
-
-		SEQ_PUT_FIELD_RET(s, field->arg1);
-		SEQ_PUT_FIELD_RET(s, field->arg2);
-		SEQ_PUT_FIELD_RET(s, field->arg3);
-		break;
-	}
-	}
-	return 1;
+	event = ftrace_find_event(entry->type);
+	return event ? event->binary(iter, 0) : TRACE_TYPE_HANDLED;
 }
 
 static int trace_empty(struct trace_iterator *iter)
 {
 	int cpu;
 
+	/* If we are looking at one CPU buffer, only check that one */
+	if (iter->cpu_file != TRACE_PIPE_ALL_CPU) {
+		cpu = iter->cpu_file;
+		if (iter->buffer_iter[cpu]) {
+			if (!ring_buffer_iter_empty(iter->buffer_iter[cpu]))
+				return 0;
+		} else {
+			if (!ring_buffer_empty_cpu(iter->tr->buffer, cpu))
+				return 0;
+		}
+		return 1;
+	}
+
 	for_each_tracing_cpu(cpu) {
 		if (iter->buffer_iter[cpu]) {
 			if (!ring_buffer_iter_empty(iter->buffer_iter[cpu]))
@@ -2368,10 +1780,15 @@
 			return ret;
 	}
 
+	if (iter->ent->type == TRACE_BPRINT &&
+			trace_flags & TRACE_ITER_PRINTK &&
+			trace_flags & TRACE_ITER_PRINTK_MSGONLY)
+		return trace_print_bprintk_msg_only(iter);
+
 	if (iter->ent->type == TRACE_PRINT &&
 			trace_flags & TRACE_ITER_PRINTK &&
 			trace_flags & TRACE_ITER_PRINTK_MSGONLY)
-		return print_printk_msg_only(iter);
+		return trace_print_printk_msg_only(iter);
 
 	if (trace_flags & TRACE_ITER_BIN)
 		return print_bin_fmt(iter);
@@ -2382,9 +1799,6 @@
 	if (trace_flags & TRACE_ITER_RAW)
 		return print_raw_fmt(iter);
 
-	if (iter->iter_flags & TRACE_FILE_LAT_FMT)
-		return print_lat_fmt(iter, iter->idx, iter->cpu);
-
 	return print_trace_fmt(iter);
 }
 
@@ -2426,30 +1840,40 @@
 };
 
 static struct trace_iterator *
-__tracing_open(struct inode *inode, struct file *file, int *ret)
+__tracing_open(struct inode *inode, struct file *file)
 {
+	long cpu_file = (long) inode->i_private;
+	void *fail_ret = ERR_PTR(-ENOMEM);
 	struct trace_iterator *iter;
 	struct seq_file *m;
-	int cpu;
+	int cpu, ret;
 
-	if (tracing_disabled) {
-		*ret = -ENODEV;
-		return NULL;
-	}
+	if (tracing_disabled)
+		return ERR_PTR(-ENODEV);
 
 	iter = kzalloc(sizeof(*iter), GFP_KERNEL);
-	if (!iter) {
-		*ret = -ENOMEM;
-		goto out;
-	}
+	if (!iter)
+		return ERR_PTR(-ENOMEM);
 
+	/*
+	 * We make a copy of the current tracer to avoid concurrent
+	 * changes on it while we are reading.
+	 */
 	mutex_lock(&trace_types_lock);
+	iter->trace = kzalloc(sizeof(*iter->trace), GFP_KERNEL);
+	if (!iter->trace)
+		goto fail;
+
+	if (current_trace)
+		*iter->trace = *current_trace;
+
 	if (current_trace && current_trace->print_max)
 		iter->tr = &max_tr;
 	else
-		iter->tr = inode->i_private;
-	iter->trace = current_trace;
+		iter->tr = &global_trace;
 	iter->pos = -1;
+	mutex_init(&iter->mutex);
+	iter->cpu_file = cpu_file;
 
 	/* Notify the tracer early; before we stop tracing. */
 	if (iter->trace && iter->trace->open)
@@ -2459,20 +1883,24 @@
 	if (ring_buffer_overruns(iter->tr->buffer))
 		iter->iter_flags |= TRACE_FILE_ANNOTATE;
 
+	if (iter->cpu_file == TRACE_PIPE_ALL_CPU) {
+		for_each_tracing_cpu(cpu) {
 
-	for_each_tracing_cpu(cpu) {
-
+			iter->buffer_iter[cpu] =
+				ring_buffer_read_start(iter->tr->buffer, cpu);
+		}
+	} else {
+		cpu = iter->cpu_file;
 		iter->buffer_iter[cpu] =
-			ring_buffer_read_start(iter->tr->buffer, cpu);
-
-		if (!iter->buffer_iter[cpu])
-			goto fail_buffer;
+				ring_buffer_read_start(iter->tr->buffer, cpu);
 	}
 
 	/* TODO stop tracer */
-	*ret = seq_open(file, &tracer_seq_ops);
-	if (*ret)
+	ret = seq_open(file, &tracer_seq_ops);
+	if (ret < 0) {
+		fail_ret = ERR_PTR(ret);
 		goto fail_buffer;
+	}
 
 	m = file->private_data;
 	m->private = iter;
@@ -2482,7 +1910,6 @@
 
 	mutex_unlock(&trace_types_lock);
 
- out:
 	return iter;
 
  fail_buffer:
@@ -2490,10 +1917,12 @@
 		if (iter->buffer_iter[cpu])
 			ring_buffer_read_finish(iter->buffer_iter[cpu]);
 	}
+ fail:
 	mutex_unlock(&trace_types_lock);
+	kfree(iter->trace);
 	kfree(iter);
 
-	return ERR_PTR(-ENOMEM);
+	return fail_ret;
 }
 
 int tracing_open_generic(struct inode *inode, struct file *filp)
@@ -2505,12 +1934,17 @@
 	return 0;
 }
 
-int tracing_release(struct inode *inode, struct file *file)
+static int tracing_release(struct inode *inode, struct file *file)
 {
 	struct seq_file *m = (struct seq_file *)file->private_data;
-	struct trace_iterator *iter = m->private;
+	struct trace_iterator *iter;
 	int cpu;
 
+	if (!(file->f_mode & FMODE_READ))
+		return 0;
+
+	iter = m->private;
+
 	mutex_lock(&trace_types_lock);
 	for_each_tracing_cpu(cpu) {
 		if (iter->buffer_iter[cpu])
@@ -2525,33 +1959,38 @@
 	mutex_unlock(&trace_types_lock);
 
 	seq_release(inode, file);
+	mutex_destroy(&iter->mutex);
+	kfree(iter->trace);
 	kfree(iter);
 	return 0;
 }
 
 static int tracing_open(struct inode *inode, struct file *file)
 {
-	int ret;
-
-	__tracing_open(inode, file, &ret);
-
-	return ret;
-}
-
-static int tracing_lt_open(struct inode *inode, struct file *file)
-{
 	struct trace_iterator *iter;
-	int ret;
+	int ret = 0;
 
-	iter = __tracing_open(inode, file, &ret);
+	/* If this file was open for write, then erase contents */
+	if ((file->f_mode & FMODE_WRITE) &&
+	    !(file->f_flags & O_APPEND)) {
+		long cpu = (long) inode->i_private;
 
-	if (!ret)
-		iter->iter_flags |= TRACE_FILE_LAT_FMT;
+		if (cpu == TRACE_PIPE_ALL_CPU)
+			tracing_reset_online_cpus(&global_trace);
+		else
+			tracing_reset(&global_trace, cpu);
+	}
 
+	if (file->f_mode & FMODE_READ) {
+		iter = __tracing_open(inode, file);
+		if (IS_ERR(iter))
+			ret = PTR_ERR(iter);
+		else if (trace_flags & TRACE_ITER_LATENCY_FMT)
+			iter->iter_flags |= TRACE_FILE_LAT_FMT;
+	}
 	return ret;
 }
 
-
 static void *
 t_next(struct seq_file *m, void *v, loff_t *pos)
 {
@@ -2623,21 +2062,22 @@
 	return ret;
 }
 
-static struct file_operations tracing_fops = {
+static ssize_t
+tracing_write_stub(struct file *filp, const char __user *ubuf,
+		   size_t count, loff_t *ppos)
+{
+	return count;
+}
+
+static const struct file_operations tracing_fops = {
 	.open		= tracing_open,
 	.read		= seq_read,
+	.write		= tracing_write_stub,
 	.llseek		= seq_lseek,
 	.release	= tracing_release,
 };
 
-static struct file_operations tracing_lt_fops = {
-	.open		= tracing_lt_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= tracing_release,
-};
-
-static struct file_operations show_traces_fops = {
+static const struct file_operations show_traces_fops = {
 	.open		= show_traces_open,
 	.read		= seq_read,
 	.release	= seq_release,
@@ -2730,7 +2170,7 @@
 	return err;
 }
 
-static struct file_operations tracing_cpumask_fops = {
+static const struct file_operations tracing_cpumask_fops = {
 	.open		= tracing_open_generic,
 	.read		= tracing_cpumask_read,
 	.write		= tracing_cpumask_write,
@@ -2740,57 +2180,62 @@
 tracing_trace_options_read(struct file *filp, char __user *ubuf,
 		       size_t cnt, loff_t *ppos)
 {
-	int i;
+	struct tracer_opt *trace_opts;
+	u32 tracer_flags;
+	int len = 0;
 	char *buf;
 	int r = 0;
-	int len = 0;
-	u32 tracer_flags = current_trace->flags->val;
-	struct tracer_opt *trace_opts = current_trace->flags->opts;
+	int i;
 
 
-	/* calulate max size */
+	/* calculate max size */
 	for (i = 0; trace_options[i]; i++) {
 		len += strlen(trace_options[i]);
-		len += 3; /* "no" and space */
+		len += 3; /* "no" and newline */
 	}
 
+	mutex_lock(&trace_types_lock);
+	tracer_flags = current_trace->flags->val;
+	trace_opts = current_trace->flags->opts;
+
 	/*
 	 * Increase the size with names of options specific
 	 * of the current tracer.
 	 */
 	for (i = 0; trace_opts[i].name; i++) {
 		len += strlen(trace_opts[i].name);
-		len += 3; /* "no" and space */
+		len += 3; /* "no" and newline */
 	}
 
 	/* +2 for \n and \0 */
 	buf = kmalloc(len + 2, GFP_KERNEL);
-	if (!buf)
+	if (!buf) {
+		mutex_unlock(&trace_types_lock);
 		return -ENOMEM;
+	}
 
 	for (i = 0; trace_options[i]; i++) {
 		if (trace_flags & (1 << i))
-			r += sprintf(buf + r, "%s ", trace_options[i]);
+			r += sprintf(buf + r, "%s\n", trace_options[i]);
 		else
-			r += sprintf(buf + r, "no%s ", trace_options[i]);
+			r += sprintf(buf + r, "no%s\n", trace_options[i]);
 	}
 
 	for (i = 0; trace_opts[i].name; i++) {
 		if (tracer_flags & trace_opts[i].bit)
-			r += sprintf(buf + r, "%s ",
+			r += sprintf(buf + r, "%s\n",
 				trace_opts[i].name);
 		else
-			r += sprintf(buf + r, "no%s ",
+			r += sprintf(buf + r, "no%s\n",
 				trace_opts[i].name);
 	}
+	mutex_unlock(&trace_types_lock);
 
-	r += sprintf(buf + r, "\n");
 	WARN_ON(r >= len + 2);
 
 	r = simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
 
 	kfree(buf);
-
 	return r;
 }
 
@@ -2828,6 +2273,34 @@
 	return 0;
 }
 
+static void set_tracer_flags(unsigned int mask, int enabled)
+{
+	/* do nothing if flag is already set */
+	if (!!(trace_flags & mask) == !!enabled)
+		return;
+
+	if (enabled)
+		trace_flags |= mask;
+	else
+		trace_flags &= ~mask;
+
+	if (mask == TRACE_ITER_GLOBAL_CLK) {
+		u64 (*func)(void);
+
+		if (enabled)
+			func = trace_clock_global;
+		else
+			func = trace_clock_local;
+
+		mutex_lock(&trace_types_lock);
+		ring_buffer_set_clock(global_trace.buffer, func);
+
+		if (max_tr.buffer)
+			ring_buffer_set_clock(max_tr.buffer, func);
+		mutex_unlock(&trace_types_lock);
+	}
+}
+
 static ssize_t
 tracing_trace_options_write(struct file *filp, const char __user *ubuf,
 			size_t cnt, loff_t *ppos)
@@ -2855,17 +2328,16 @@
 		int len = strlen(trace_options[i]);
 
 		if (strncmp(cmp, trace_options[i], len) == 0) {
-			if (neg)
-				trace_flags &= ~(1 << i);
-			else
-				trace_flags |= (1 << i);
+			set_tracer_flags(1 << i, !neg);
 			break;
 		}
 	}
 
 	/* If no option could be set, test the specific tracer options */
 	if (!trace_options[i]) {
+		mutex_lock(&trace_types_lock);
 		ret = set_tracer_option(current_trace, cmp, neg);
+		mutex_unlock(&trace_types_lock);
 		if (ret)
 			return ret;
 	}
@@ -2875,7 +2347,7 @@
 	return cnt;
 }
 
-static struct file_operations tracing_iter_fops = {
+static const struct file_operations tracing_iter_fops = {
 	.open		= tracing_open_generic,
 	.read		= tracing_trace_options_read,
 	.write		= tracing_trace_options_write,
@@ -2908,7 +2380,7 @@
 					readme_msg, strlen(readme_msg));
 }
 
-static struct file_operations tracing_readme_fops = {
+static const struct file_operations tracing_readme_fops = {
 	.open		= tracing_open_generic,
 	.read		= tracing_readme_read,
 };
@@ -2930,7 +2402,7 @@
 {
 	struct trace_array *tr = filp->private_data;
 	char buf[64];
-	long val;
+	unsigned long val;
 	int ret;
 
 	if (cnt >= sizeof(buf))
@@ -2985,13 +2457,105 @@
 	return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
 }
 
-static int tracing_set_tracer(char *buf)
+int tracer_init(struct tracer *t, struct trace_array *tr)
 {
+	tracing_reset_online_cpus(tr);
+	return t->init(tr);
+}
+
+static int tracing_resize_ring_buffer(unsigned long size)
+{
+	int ret;
+
+	/*
+	 * If kernel or user changes the size of the ring buffer
+	 * we use the size that was given, and we can forget about
+	 * expanding it later.
+	 */
+	ring_buffer_expanded = 1;
+
+	ret = ring_buffer_resize(global_trace.buffer, size);
+	if (ret < 0)
+		return ret;
+
+	ret = ring_buffer_resize(max_tr.buffer, size);
+	if (ret < 0) {
+		int r;
+
+		r = ring_buffer_resize(global_trace.buffer,
+				       global_trace.entries);
+		if (r < 0) {
+			/*
+			 * AARGH! We are left with different
+			 * size max buffer!!!!
+			 * The max buffer is our "snapshot" buffer.
+			 * When a tracer needs a snapshot (one of the
+			 * latency tracers), it swaps the max buffer
+			 * with the saved snap shot. We succeeded to
+			 * update the size of the main buffer, but failed to
+			 * update the size of the max buffer. But when we tried
+			 * to reset the main buffer to the original size, we
+			 * failed there too. This is very unlikely to
+			 * happen, but if it does, warn and kill all
+			 * tracing.
+			 */
+			WARN_ON(1);
+			tracing_disabled = 1;
+		}
+		return ret;
+	}
+
+	global_trace.entries = size;
+
+	return ret;
+}
+
+/**
+ * tracing_update_buffers - used by tracing facility to expand ring buffers
+ *
+ * To save on memory when the tracing is never used on a system with it
+ * configured in. The ring buffers are set to a minimum size. But once
+ * a user starts to use the tracing facility, then they need to grow
+ * to their default size.
+ *
+ * This function is to be called when a tracer is about to be used.
+ */
+int tracing_update_buffers(void)
+{
+	int ret = 0;
+
+	mutex_lock(&trace_types_lock);
+	if (!ring_buffer_expanded)
+		ret = tracing_resize_ring_buffer(trace_buf_size);
+	mutex_unlock(&trace_types_lock);
+
+	return ret;
+}
+
+struct trace_option_dentry;
+
+static struct trace_option_dentry *
+create_trace_option_files(struct tracer *tracer);
+
+static void
+destroy_trace_option_files(struct trace_option_dentry *topts);
+
+static int tracing_set_tracer(const char *buf)
+{
+	static struct trace_option_dentry *topts;
 	struct trace_array *tr = &global_trace;
 	struct tracer *t;
 	int ret = 0;
 
 	mutex_lock(&trace_types_lock);
+
+	if (!ring_buffer_expanded) {
+		ret = tracing_resize_ring_buffer(trace_buf_size);
+		if (ret < 0)
+			goto out;
+		ret = 0;
+	}
+
 	for (t = trace_types; t; t = t->next) {
 		if (strcmp(t->name, buf) == 0)
 			break;
@@ -3007,9 +2571,14 @@
 	if (current_trace && current_trace->reset)
 		current_trace->reset(tr);
 
+	destroy_trace_option_files(topts);
+
 	current_trace = t;
+
+	topts = create_trace_option_files(current_trace);
+
 	if (t->init) {
-		ret = t->init(tr);
+		ret = tracer_init(t, tr);
 		if (ret)
 			goto out;
 	}
@@ -3072,9 +2641,9 @@
 tracing_max_lat_write(struct file *filp, const char __user *ubuf,
 		      size_t cnt, loff_t *ppos)
 {
-	long *ptr = filp->private_data;
+	unsigned long *ptr = filp->private_data;
 	char buf[64];
-	long val;
+	unsigned long val;
 	int ret;
 
 	if (cnt >= sizeof(buf))
@@ -3094,54 +2663,96 @@
 	return cnt;
 }
 
-static atomic_t tracing_reader;
-
 static int tracing_open_pipe(struct inode *inode, struct file *filp)
 {
+	long cpu_file = (long) inode->i_private;
 	struct trace_iterator *iter;
+	int ret = 0;
 
 	if (tracing_disabled)
 		return -ENODEV;
 
-	/* We only allow for reader of the pipe */
-	if (atomic_inc_return(&tracing_reader) != 1) {
-		atomic_dec(&tracing_reader);
-		return -EBUSY;
+	mutex_lock(&trace_types_lock);
+
+	/* We only allow one reader per cpu */
+	if (cpu_file == TRACE_PIPE_ALL_CPU) {
+		if (!cpumask_empty(tracing_reader_cpumask)) {
+			ret = -EBUSY;
+			goto out;
+		}
+		cpumask_setall(tracing_reader_cpumask);
+	} else {
+		if (!cpumask_test_cpu(cpu_file, tracing_reader_cpumask))
+			cpumask_set_cpu(cpu_file, tracing_reader_cpumask);
+		else {
+			ret = -EBUSY;
+			goto out;
+		}
 	}
 
 	/* create a buffer to store the information to pass to userspace */
 	iter = kzalloc(sizeof(*iter), GFP_KERNEL);
-	if (!iter)
-		return -ENOMEM;
-
-	if (!alloc_cpumask_var(&iter->started, GFP_KERNEL)) {
-		kfree(iter);
-		return -ENOMEM;
+	if (!iter) {
+		ret = -ENOMEM;
+		goto out;
 	}
 
-	mutex_lock(&trace_types_lock);
+	/*
+	 * We make a copy of the current tracer to avoid concurrent
+	 * changes on it while we are reading.
+	 */
+	iter->trace = kmalloc(sizeof(*iter->trace), GFP_KERNEL);
+	if (!iter->trace) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+	if (current_trace)
+		*iter->trace = *current_trace;
+
+	if (!alloc_cpumask_var(&iter->started, GFP_KERNEL)) {
+		ret = -ENOMEM;
+		goto fail;
+	}
 
 	/* trace pipe does not show start of buffer */
 	cpumask_setall(iter->started);
 
+	iter->cpu_file = cpu_file;
 	iter->tr = &global_trace;
-	iter->trace = current_trace;
+	mutex_init(&iter->mutex);
 	filp->private_data = iter;
 
 	if (iter->trace->pipe_open)
 		iter->trace->pipe_open(iter);
-	mutex_unlock(&trace_types_lock);
 
-	return 0;
+out:
+	mutex_unlock(&trace_types_lock);
+	return ret;
+
+fail:
+	kfree(iter->trace);
+	kfree(iter);
+	mutex_unlock(&trace_types_lock);
+	return ret;
 }
 
 static int tracing_release_pipe(struct inode *inode, struct file *file)
 {
 	struct trace_iterator *iter = file->private_data;
 
+	mutex_lock(&trace_types_lock);
+
+	if (iter->cpu_file == TRACE_PIPE_ALL_CPU)
+		cpumask_clear(tracing_reader_cpumask);
+	else
+		cpumask_clear_cpu(iter->cpu_file, tracing_reader_cpumask);
+
+	mutex_unlock(&trace_types_lock);
+
 	free_cpumask_var(iter->started);
+	mutex_destroy(&iter->mutex);
+	kfree(iter->trace);
 	kfree(iter);
-	atomic_dec(&tracing_reader);
 
 	return 0;
 }
@@ -3167,67 +2778,57 @@
 	}
 }
 
+
+void default_wait_pipe(struct trace_iterator *iter)
+{
+	DEFINE_WAIT(wait);
+
+	prepare_to_wait(&trace_wait, &wait, TASK_INTERRUPTIBLE);
+
+	if (trace_empty(iter))
+		schedule();
+
+	finish_wait(&trace_wait, &wait);
+}
+
 /*
- * Consumer reader.
+ * This is a make-shift waitqueue.
+ * A tracer might use this callback on some rare cases:
+ *
+ *  1) the current tracer might hold the runqueue lock when it wakes up
+ *     a reader, hence a deadlock (sched, function, and function graph tracers)
+ *  2) the function tracers, trace all functions, we don't want
+ *     the overhead of calling wake_up and friends
+ *     (and tracing them too)
+ *
+ *     Anyway, this is really very primitive wakeup.
  */
-static ssize_t
-tracing_read_pipe(struct file *filp, char __user *ubuf,
-		  size_t cnt, loff_t *ppos)
+void poll_wait_pipe(struct trace_iterator *iter)
+{
+	set_current_state(TASK_INTERRUPTIBLE);
+	/* sleep for 100 msecs, and try again. */
+	schedule_timeout(HZ / 10);
+}
+
+/* Must be called with trace_types_lock mutex held. */
+static int tracing_wait_pipe(struct file *filp)
 {
 	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_reset(&iter->seq);
-
-	mutex_lock(&trace_types_lock);
-	if (iter->trace->read) {
-		sret = iter->trace->read(iter, filp, ubuf, cnt, ppos);
-		if (sret)
-			goto out;
-	}
-
-waitagain:
-	sret = 0;
 	while (trace_empty(iter)) {
 
 		if ((filp->f_flags & O_NONBLOCK)) {
-			sret = -EAGAIN;
-			goto out;
+			return -EAGAIN;
 		}
 
-		/*
-		 * This is a make-shift waitqueue. The reason we don't use
-		 * an actual wait queue is because:
-		 *  1) we only ever have one waiter
-		 *  2) the tracing, traces all functions, we don't want
-		 *     the overhead of calling wake_up and friends
-		 *     (and tracing them too)
-		 *     Anyway, this is really very primitive wakeup.
-		 */
-		set_current_state(TASK_INTERRUPTIBLE);
-		iter->tr->waiter = current;
+		mutex_unlock(&iter->mutex);
 
-		mutex_unlock(&trace_types_lock);
+		iter->trace->wait_pipe(iter);
 
-		/* sleep for 100 msecs, and try again. */
-		schedule_timeout(HZ/10);
+		mutex_lock(&iter->mutex);
 
-		mutex_lock(&trace_types_lock);
-
-		iter->tr->waiter = NULL;
-
-		if (signal_pending(current)) {
-			sret = -EINTR;
-			goto out;
-		}
-
-		if (iter->trace != current_trace)
-			goto out;
+		if (signal_pending(current))
+			return -EINTR;
 
 		/*
 		 * We block until we read something and tracing is disabled.
@@ -3240,14 +2841,60 @@
 		 */
 		if (!tracer_enabled && iter->pos)
 			break;
-
-		continue;
 	}
 
-	/* stop when tracing is finished */
-	if (trace_empty(iter))
+	return 1;
+}
+
+/*
+ * Consumer reader.
+ */
+static ssize_t
+tracing_read_pipe(struct file *filp, char __user *ubuf,
+		  size_t cnt, loff_t *ppos)
+{
+	struct trace_iterator *iter = filp->private_data;
+	static struct tracer *old_tracer;
+	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);
+
+	/* copy the tracer to avoid using a global lock all around */
+	mutex_lock(&trace_types_lock);
+	if (unlikely(old_tracer != current_trace && current_trace)) {
+		old_tracer = current_trace;
+		*iter->trace = *current_trace;
+	}
+	mutex_unlock(&trace_types_lock);
+
+	/*
+	 * 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);
+	if (iter->trace->read) {
+		sret = iter->trace->read(iter, filp, ubuf, cnt, ppos);
+		if (sret)
+			goto out;
+	}
+
+waitagain:
+	sret = tracing_wait_pipe(filp);
+	if (sret <= 0)
 		goto out;
 
+	/* stop when tracing is finished */
+	if (trace_empty(iter)) {
+		sret = 0;
+		goto out;
+	}
+
 	if (cnt >= PAGE_SIZE)
 		cnt = PAGE_SIZE - 1;
 
@@ -3267,8 +2914,8 @@
 			iter->seq.len = len;
 			break;
 		}
-
-		trace_consume(iter);
+		if (ret != TRACE_TYPE_NO_CONSUME)
+			trace_consume(iter);
 
 		if (iter->seq.len >= cnt)
 			break;
@@ -3277,7 +2924,7 @@
 	/* Now copy what we have to the user */
 	sret = trace_seq_to_user(&iter->seq, ubuf, cnt);
 	if (iter->seq.readpos >= iter->seq.len)
-		trace_seq_reset(&iter->seq);
+		trace_seq_init(&iter->seq);
 
 	/*
 	 * If there was nothing to send to user, inspite of consuming trace
@@ -3287,20 +2934,165 @@
 		goto waitagain;
 
 out:
-	mutex_unlock(&trace_types_lock);
+	mutex_unlock(&iter->mutex);
 
 	return sret;
 }
 
+static void tracing_pipe_buf_release(struct pipe_inode_info *pipe,
+				     struct pipe_buffer *buf)
+{
+	__free_page(buf->page);
+}
+
+static void tracing_spd_release_pipe(struct splice_pipe_desc *spd,
+				     unsigned int idx)
+{
+	__free_page(spd->pages[idx]);
+}
+
+static struct pipe_buf_operations tracing_pipe_buf_ops = {
+	.can_merge		= 0,
+	.map			= generic_pipe_buf_map,
+	.unmap			= generic_pipe_buf_unmap,
+	.confirm		= generic_pipe_buf_confirm,
+	.release		= tracing_pipe_buf_release,
+	.steal			= generic_pipe_buf_steal,
+	.get			= generic_pipe_buf_get,
+};
+
+static size_t
+tracing_fill_pipe_page(size_t rem, struct trace_iterator *iter)
+{
+	size_t count;
+	int ret;
+
+	/* Seq buffer is page-sized, exactly what we need. */
+	for (;;) {
+		count = iter->seq.len;
+		ret = print_trace_line(iter);
+		count = iter->seq.len - count;
+		if (rem < count) {
+			rem = 0;
+			iter->seq.len -= count;
+			break;
+		}
+		if (ret == TRACE_TYPE_PARTIAL_LINE) {
+			iter->seq.len -= count;
+			break;
+		}
+
+		trace_consume(iter);
+		rem -= count;
+		if (!find_next_entry_inc(iter))	{
+			rem = 0;
+			iter->ent = NULL;
+			break;
+		}
+	}
+
+	return rem;
+}
+
+static ssize_t tracing_splice_read_pipe(struct file *filp,
+					loff_t *ppos,
+					struct pipe_inode_info *pipe,
+					size_t len,
+					unsigned int flags)
+{
+	struct page *pages[PIPE_BUFFERS];
+	struct partial_page partial[PIPE_BUFFERS];
+	struct trace_iterator *iter = filp->private_data;
+	struct splice_pipe_desc spd = {
+		.pages		= pages,
+		.partial	= partial,
+		.nr_pages	= 0, /* This gets updated below. */
+		.flags		= flags,
+		.ops		= &tracing_pipe_buf_ops,
+		.spd_release	= tracing_spd_release_pipe,
+	};
+	static struct tracer *old_tracer;
+	ssize_t ret;
+	size_t rem;
+	unsigned int i;
+
+	/* copy the tracer to avoid using a global lock all around */
+	mutex_lock(&trace_types_lock);
+	if (unlikely(old_tracer != current_trace && current_trace)) {
+		old_tracer = current_trace;
+		*iter->trace = *current_trace;
+	}
+	mutex_unlock(&trace_types_lock);
+
+	mutex_lock(&iter->mutex);
+
+	if (iter->trace->splice_read) {
+		ret = iter->trace->splice_read(iter, filp,
+					       ppos, pipe, len, flags);
+		if (ret)
+			goto out_err;
+	}
+
+	ret = tracing_wait_pipe(filp);
+	if (ret <= 0)
+		goto out_err;
+
+	if (!iter->ent && !find_next_entry_inc(iter)) {
+		ret = -EFAULT;
+		goto out_err;
+	}
+
+	/* Fill as many pages as possible. */
+	for (i = 0, rem = len; i < PIPE_BUFFERS && rem; i++) {
+		pages[i] = alloc_page(GFP_KERNEL);
+		if (!pages[i])
+			break;
+
+		rem = tracing_fill_pipe_page(rem, iter);
+
+		/* Copy the data into the page, so we can start over. */
+		ret = trace_seq_to_buffer(&iter->seq,
+					  page_address(pages[i]),
+					  iter->seq.len);
+		if (ret < 0) {
+			__free_page(pages[i]);
+			break;
+		}
+		partial[i].offset = 0;
+		partial[i].len = iter->seq.len;
+
+		trace_seq_init(&iter->seq);
+	}
+
+	mutex_unlock(&iter->mutex);
+
+	spd.nr_pages = i;
+
+	return splice_to_pipe(pipe, &spd);
+
+out_err:
+	mutex_unlock(&iter->mutex);
+
+	return ret;
+}
+
 static ssize_t
 tracing_entries_read(struct file *filp, char __user *ubuf,
 		     size_t cnt, loff_t *ppos)
 {
 	struct trace_array *tr = filp->private_data;
-	char buf[64];
+	char buf[96];
 	int r;
 
-	r = sprintf(buf, "%lu\n", tr->entries >> 10);
+	mutex_lock(&trace_types_lock);
+	if (!ring_buffer_expanded)
+		r = sprintf(buf, "%lu (expanded: %lu)\n",
+			    tr->entries >> 10,
+			    trace_buf_size >> 10);
+	else
+		r = sprintf(buf, "%lu\n", tr->entries >> 10);
+	mutex_unlock(&trace_types_lock);
+
 	return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
 }
 
@@ -3344,28 +3136,11 @@
 	val <<= 10;
 
 	if (val != global_trace.entries) {
-		ret = ring_buffer_resize(global_trace.buffer, val);
+		ret = tracing_resize_ring_buffer(val);
 		if (ret < 0) {
 			cnt = ret;
 			goto out;
 		}
-
-		ret = ring_buffer_resize(max_tr.buffer, val);
-		if (ret < 0) {
-			int r;
-			cnt = ret;
-			r = ring_buffer_resize(global_trace.buffer,
-					       global_trace.entries);
-			if (r < 0) {
-				/* AARGH! We are left with different
-				 * size max buffer!!!! */
-				WARN_ON(1);
-				tracing_disabled = 1;
-			}
-			goto out;
-		}
-
-		global_trace.entries = val;
 	}
 
 	filp->f_pos += cnt;
@@ -3393,7 +3168,7 @@
 	int ret;
 	va_list args;
 	va_start(args, fmt);
-	ret = trace_vprintk(0, -1, fmt, args);
+	ret = trace_vprintk(0, fmt, args);
 	va_end(args);
 	return ret;
 }
@@ -3433,42 +3208,288 @@
 	return cnt;
 }
 
-static struct file_operations tracing_max_lat_fops = {
+static const struct file_operations tracing_max_lat_fops = {
 	.open		= tracing_open_generic,
 	.read		= tracing_max_lat_read,
 	.write		= tracing_max_lat_write,
 };
 
-static struct file_operations tracing_ctrl_fops = {
+static const struct file_operations tracing_ctrl_fops = {
 	.open		= tracing_open_generic,
 	.read		= tracing_ctrl_read,
 	.write		= tracing_ctrl_write,
 };
 
-static struct file_operations set_tracer_fops = {
+static const struct file_operations set_tracer_fops = {
 	.open		= tracing_open_generic,
 	.read		= tracing_set_trace_read,
 	.write		= tracing_set_trace_write,
 };
 
-static struct file_operations tracing_pipe_fops = {
+static const struct file_operations tracing_pipe_fops = {
 	.open		= tracing_open_pipe,
 	.poll		= tracing_poll_pipe,
 	.read		= tracing_read_pipe,
+	.splice_read	= tracing_splice_read_pipe,
 	.release	= tracing_release_pipe,
 };
 
-static struct file_operations tracing_entries_fops = {
+static const struct file_operations tracing_entries_fops = {
 	.open		= tracing_open_generic,
 	.read		= tracing_entries_read,
 	.write		= tracing_entries_write,
 };
 
-static struct file_operations tracing_mark_fops = {
+static const struct file_operations tracing_mark_fops = {
 	.open		= tracing_open_generic,
 	.write		= tracing_mark_write,
 };
 
+struct ftrace_buffer_info {
+	struct trace_array	*tr;
+	void			*spare;
+	int			cpu;
+	unsigned int		read;
+};
+
+static int tracing_buffers_open(struct inode *inode, struct file *filp)
+{
+	int cpu = (int)(long)inode->i_private;
+	struct ftrace_buffer_info *info;
+
+	if (tracing_disabled)
+		return -ENODEV;
+
+	info = kzalloc(sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	info->tr	= &global_trace;
+	info->cpu	= cpu;
+	info->spare	= ring_buffer_alloc_read_page(info->tr->buffer);
+	/* Force reading ring buffer for first read */
+	info->read	= (unsigned int)-1;
+	if (!info->spare)
+		goto out;
+
+	filp->private_data = info;
+
+	return 0;
+
+ out:
+	kfree(info);
+	return -ENOMEM;
+}
+
+static ssize_t
+tracing_buffers_read(struct file *filp, char __user *ubuf,
+		     size_t count, loff_t *ppos)
+{
+	struct ftrace_buffer_info *info = filp->private_data;
+	unsigned int pos;
+	ssize_t ret;
+	size_t size;
+
+	if (!count)
+		return 0;
+
+	/* Do we have previous read data to read? */
+	if (info->read < PAGE_SIZE)
+		goto read;
+
+	info->read = 0;
+
+	ret = ring_buffer_read_page(info->tr->buffer,
+				    &info->spare,
+				    count,
+				    info->cpu, 0);
+	if (ret < 0)
+		return 0;
+
+	pos = ring_buffer_page_len(info->spare);
+
+	if (pos < PAGE_SIZE)
+		memset(info->spare + pos, 0, PAGE_SIZE - pos);
+
+read:
+	size = PAGE_SIZE - info->read;
+	if (size > count)
+		size = count;
+
+	ret = copy_to_user(ubuf, info->spare + info->read, size);
+	if (ret == size)
+		return -EFAULT;
+	size -= ret;
+
+	*ppos += size;
+	info->read += size;
+
+	return size;
+}
+
+static int tracing_buffers_release(struct inode *inode, struct file *file)
+{
+	struct ftrace_buffer_info *info = file->private_data;
+
+	ring_buffer_free_read_page(info->tr->buffer, info->spare);
+	kfree(info);
+
+	return 0;
+}
+
+struct buffer_ref {
+	struct ring_buffer	*buffer;
+	void			*page;
+	int			ref;
+};
+
+static void buffer_pipe_buf_release(struct pipe_inode_info *pipe,
+				    struct pipe_buffer *buf)
+{
+	struct buffer_ref *ref = (struct buffer_ref *)buf->private;
+
+	if (--ref->ref)
+		return;
+
+	ring_buffer_free_read_page(ref->buffer, ref->page);
+	kfree(ref);
+	buf->private = 0;
+}
+
+static int buffer_pipe_buf_steal(struct pipe_inode_info *pipe,
+				 struct pipe_buffer *buf)
+{
+	return 1;
+}
+
+static void buffer_pipe_buf_get(struct pipe_inode_info *pipe,
+				struct pipe_buffer *buf)
+{
+	struct buffer_ref *ref = (struct buffer_ref *)buf->private;
+
+	ref->ref++;
+}
+
+/* Pipe buffer operations for a buffer. */
+static struct pipe_buf_operations buffer_pipe_buf_ops = {
+	.can_merge		= 0,
+	.map			= generic_pipe_buf_map,
+	.unmap			= generic_pipe_buf_unmap,
+	.confirm		= generic_pipe_buf_confirm,
+	.release		= buffer_pipe_buf_release,
+	.steal			= buffer_pipe_buf_steal,
+	.get			= buffer_pipe_buf_get,
+};
+
+/*
+ * Callback from splice_to_pipe(), if we need to release some pages
+ * at the end of the spd in case we error'ed out in filling the pipe.
+ */
+static void buffer_spd_release(struct splice_pipe_desc *spd, unsigned int i)
+{
+	struct buffer_ref *ref =
+		(struct buffer_ref *)spd->partial[i].private;
+
+	if (--ref->ref)
+		return;
+
+	ring_buffer_free_read_page(ref->buffer, ref->page);
+	kfree(ref);
+	spd->partial[i].private = 0;
+}
+
+static ssize_t
+tracing_buffers_splice_read(struct file *file, loff_t *ppos,
+			    struct pipe_inode_info *pipe, size_t len,
+			    unsigned int flags)
+{
+	struct ftrace_buffer_info *info = file->private_data;
+	struct partial_page partial[PIPE_BUFFERS];
+	struct page *pages[PIPE_BUFFERS];
+	struct splice_pipe_desc spd = {
+		.pages		= pages,
+		.partial	= partial,
+		.flags		= flags,
+		.ops		= &buffer_pipe_buf_ops,
+		.spd_release	= buffer_spd_release,
+	};
+	struct buffer_ref *ref;
+	int size, i;
+	size_t ret;
+
+	/*
+	 * We can't seek on a buffer input
+	 */
+	if (unlikely(*ppos))
+		return -ESPIPE;
+
+
+	for (i = 0; i < PIPE_BUFFERS && len; i++, len -= size) {
+		struct page *page;
+		int r;
+
+		ref = kzalloc(sizeof(*ref), GFP_KERNEL);
+		if (!ref)
+			break;
+
+		ref->buffer = info->tr->buffer;
+		ref->page = ring_buffer_alloc_read_page(ref->buffer);
+		if (!ref->page) {
+			kfree(ref);
+			break;
+		}
+
+		r = ring_buffer_read_page(ref->buffer, &ref->page,
+					  len, info->cpu, 0);
+		if (r < 0) {
+			ring_buffer_free_read_page(ref->buffer,
+						   ref->page);
+			kfree(ref);
+			break;
+		}
+
+		/*
+		 * zero out any left over data, this is going to
+		 * user land.
+		 */
+		size = ring_buffer_page_len(ref->page);
+		if (size < PAGE_SIZE)
+			memset(ref->page + size, 0, PAGE_SIZE - size);
+
+		page = virt_to_page(ref->page);
+
+		spd.pages[i] = page;
+		spd.partial[i].len = PAGE_SIZE;
+		spd.partial[i].offset = 0;
+		spd.partial[i].private = (unsigned long)ref;
+		spd.nr_pages++;
+	}
+
+	spd.nr_pages = i;
+
+	/* did we read anything? */
+	if (!spd.nr_pages) {
+		if (flags & SPLICE_F_NONBLOCK)
+			ret = -EAGAIN;
+		else
+			ret = 0;
+		/* TODO: block */
+		return ret;
+	}
+
+	ret = splice_to_pipe(pipe, &spd);
+
+	return ret;
+}
+
+static const struct file_operations tracing_buffers_fops = {
+	.open		= tracing_buffers_open,
+	.read		= tracing_buffers_read,
+	.release	= tracing_buffers_release,
+	.splice_read	= tracing_buffers_splice_read,
+	.llseek		= no_llseek,
+};
+
 #ifdef CONFIG_DYNAMIC_FTRACE
 
 int __weak ftrace_arch_read_dyn_info(char *buf, int size)
@@ -3500,7 +3521,7 @@
 	return r;
 }
 
-static struct file_operations tracing_dyn_info_fops = {
+static const struct file_operations tracing_dyn_info_fops = {
 	.open		= tracing_open_generic,
 	.read		= tracing_read_dyn_info,
 };
@@ -3515,6 +3536,9 @@
 	if (d_tracer)
 		return d_tracer;
 
+	if (!debugfs_initialized())
+		return NULL;
+
 	d_tracer = debugfs_create_dir("tracing", NULL);
 
 	if (!d_tracer && !once) {
@@ -3526,15 +3550,350 @@
 	return d_tracer;
 }
 
+static struct dentry *d_percpu;
+
+struct dentry *tracing_dentry_percpu(void)
+{
+	static int once;
+	struct dentry *d_tracer;
+
+	if (d_percpu)
+		return d_percpu;
+
+	d_tracer = tracing_init_dentry();
+
+	if (!d_tracer)
+		return NULL;
+
+	d_percpu = debugfs_create_dir("per_cpu", d_tracer);
+
+	if (!d_percpu && !once) {
+		once = 1;
+		pr_warning("Could not create debugfs directory 'per_cpu'\n");
+		return NULL;
+	}
+
+	return d_percpu;
+}
+
+static void tracing_init_debugfs_percpu(long cpu)
+{
+	struct dentry *d_percpu = tracing_dentry_percpu();
+	struct dentry *entry, *d_cpu;
+	/* strlen(cpu) + MAX(log10(cpu)) + '\0' */
+	char cpu_dir[7];
+
+	if (cpu > 999 || cpu < 0)
+		return;
+
+	sprintf(cpu_dir, "cpu%ld", cpu);
+	d_cpu = debugfs_create_dir(cpu_dir, d_percpu);
+	if (!d_cpu) {
+		pr_warning("Could not create debugfs '%s' entry\n", cpu_dir);
+		return;
+	}
+
+	/* per cpu trace_pipe */
+	entry = debugfs_create_file("trace_pipe", 0444, d_cpu,
+				(void *) cpu, &tracing_pipe_fops);
+	if (!entry)
+		pr_warning("Could not create debugfs 'trace_pipe' entry\n");
+
+	/* per cpu trace */
+	entry = debugfs_create_file("trace", 0644, d_cpu,
+				(void *) cpu, &tracing_fops);
+	if (!entry)
+		pr_warning("Could not create debugfs 'trace' entry\n");
+
+	entry = debugfs_create_file("trace_pipe_raw", 0444, d_cpu,
+				    (void *) cpu, &tracing_buffers_fops);
+	if (!entry)
+		pr_warning("Could not create debugfs 'trace_pipe_raw' entry\n");
+}
+
 #ifdef CONFIG_FTRACE_SELFTEST
 /* Let selftest have access to static functions in this file */
 #include "trace_selftest.c"
 #endif
 
+struct trace_option_dentry {
+	struct tracer_opt		*opt;
+	struct tracer_flags		*flags;
+	struct dentry			*entry;
+};
+
+static ssize_t
+trace_options_read(struct file *filp, char __user *ubuf, size_t cnt,
+			loff_t *ppos)
+{
+	struct trace_option_dentry *topt = filp->private_data;
+	char *buf;
+
+	if (topt->flags->val & topt->opt->bit)
+		buf = "1\n";
+	else
+		buf = "0\n";
+
+	return simple_read_from_buffer(ubuf, cnt, ppos, buf, 2);
+}
+
+static ssize_t
+trace_options_write(struct file *filp, const char __user *ubuf, size_t cnt,
+			 loff_t *ppos)
+{
+	struct trace_option_dentry *topt = filp->private_data;
+	unsigned long val;
+	char buf[64];
+	int ret;
+
+	if (cnt >= sizeof(buf))
+		return -EINVAL;
+
+	if (copy_from_user(&buf, ubuf, cnt))
+		return -EFAULT;
+
+	buf[cnt] = 0;
+
+	ret = strict_strtoul(buf, 10, &val);
+	if (ret < 0)
+		return ret;
+
+	ret = 0;
+	switch (val) {
+	case 0:
+		/* do nothing if already cleared */
+		if (!(topt->flags->val & topt->opt->bit))
+			break;
+
+		mutex_lock(&trace_types_lock);
+		if (current_trace->set_flag)
+			ret = current_trace->set_flag(topt->flags->val,
+						      topt->opt->bit, 0);
+		mutex_unlock(&trace_types_lock);
+		if (ret)
+			return ret;
+		topt->flags->val &= ~topt->opt->bit;
+		break;
+	case 1:
+		/* do nothing if already set */
+		if (topt->flags->val & topt->opt->bit)
+			break;
+
+		mutex_lock(&trace_types_lock);
+		if (current_trace->set_flag)
+			ret = current_trace->set_flag(topt->flags->val,
+						      topt->opt->bit, 1);
+		mutex_unlock(&trace_types_lock);
+		if (ret)
+			return ret;
+		topt->flags->val |= topt->opt->bit;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	*ppos += cnt;
+
+	return cnt;
+}
+
+
+static const struct file_operations trace_options_fops = {
+	.open = tracing_open_generic,
+	.read = trace_options_read,
+	.write = trace_options_write,
+};
+
+static ssize_t
+trace_options_core_read(struct file *filp, char __user *ubuf, size_t cnt,
+			loff_t *ppos)
+{
+	long index = (long)filp->private_data;
+	char *buf;
+
+	if (trace_flags & (1 << index))
+		buf = "1\n";
+	else
+		buf = "0\n";
+
+	return simple_read_from_buffer(ubuf, cnt, ppos, buf, 2);
+}
+
+static ssize_t
+trace_options_core_write(struct file *filp, const char __user *ubuf, size_t cnt,
+			 loff_t *ppos)
+{
+	long index = (long)filp->private_data;
+	char buf[64];
+	unsigned long val;
+	int ret;
+
+	if (cnt >= sizeof(buf))
+		return -EINVAL;
+
+	if (copy_from_user(&buf, ubuf, cnt))
+		return -EFAULT;
+
+	buf[cnt] = 0;
+
+	ret = strict_strtoul(buf, 10, &val);
+	if (ret < 0)
+		return ret;
+
+	switch (val) {
+	case 0:
+		trace_flags &= ~(1 << index);
+		break;
+	case 1:
+		trace_flags |= 1 << index;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	*ppos += cnt;
+
+	return cnt;
+}
+
+static const struct file_operations trace_options_core_fops = {
+	.open = tracing_open_generic,
+	.read = trace_options_core_read,
+	.write = trace_options_core_write,
+};
+
+static struct dentry *trace_options_init_dentry(void)
+{
+	struct dentry *d_tracer;
+	static struct dentry *t_options;
+
+	if (t_options)
+		return t_options;
+
+	d_tracer = tracing_init_dentry();
+	if (!d_tracer)
+		return NULL;
+
+	t_options = debugfs_create_dir("options", d_tracer);
+	if (!t_options) {
+		pr_warning("Could not create debugfs directory 'options'\n");
+		return NULL;
+	}
+
+	return t_options;
+}
+
+static void
+create_trace_option_file(struct trace_option_dentry *topt,
+			 struct tracer_flags *flags,
+			 struct tracer_opt *opt)
+{
+	struct dentry *t_options;
+	struct dentry *entry;
+
+	t_options = trace_options_init_dentry();
+	if (!t_options)
+		return;
+
+	topt->flags = flags;
+	topt->opt = opt;
+
+	entry = debugfs_create_file(opt->name, 0644, t_options, topt,
+				    &trace_options_fops);
+
+	topt->entry = entry;
+
+}
+
+static struct trace_option_dentry *
+create_trace_option_files(struct tracer *tracer)
+{
+	struct trace_option_dentry *topts;
+	struct tracer_flags *flags;
+	struct tracer_opt *opts;
+	int cnt;
+
+	if (!tracer)
+		return NULL;
+
+	flags = tracer->flags;
+
+	if (!flags || !flags->opts)
+		return NULL;
+
+	opts = flags->opts;
+
+	for (cnt = 0; opts[cnt].name; cnt++)
+		;
+
+	topts = kcalloc(cnt + 1, sizeof(*topts), GFP_KERNEL);
+	if (!topts)
+		return NULL;
+
+	for (cnt = 0; opts[cnt].name; cnt++)
+		create_trace_option_file(&topts[cnt], flags,
+					 &opts[cnt]);
+
+	return topts;
+}
+
+static void
+destroy_trace_option_files(struct trace_option_dentry *topts)
+{
+	int cnt;
+
+	if (!topts)
+		return;
+
+	for (cnt = 0; topts[cnt].opt; cnt++) {
+		if (topts[cnt].entry)
+			debugfs_remove(topts[cnt].entry);
+	}
+
+	kfree(topts);
+}
+
+static struct dentry *
+create_trace_option_core_file(const char *option, long index)
+{
+	struct dentry *t_options;
+	struct dentry *entry;
+
+	t_options = trace_options_init_dentry();
+	if (!t_options)
+		return NULL;
+
+	entry = debugfs_create_file(option, 0644, t_options, (void *)index,
+				    &trace_options_core_fops);
+
+	return entry;
+}
+
+static __init void create_trace_options_dir(void)
+{
+	struct dentry *t_options;
+	struct dentry *entry;
+	int i;
+
+	t_options = trace_options_init_dentry();
+	if (!t_options)
+		return;
+
+	for (i = 0; trace_options[i]; i++) {
+		entry = create_trace_option_core_file(trace_options[i], i);
+		if (!entry)
+			pr_warning("Could not create debugfs %s entry\n",
+				   trace_options[i]);
+	}
+}
+
 static __init int tracer_init_debugfs(void)
 {
 	struct dentry *d_tracer;
 	struct dentry *entry;
+	int cpu;
 
 	d_tracer = tracing_init_dentry();
 
@@ -3548,18 +3907,15 @@
 	if (!entry)
 		pr_warning("Could not create debugfs 'trace_options' entry\n");
 
+	create_trace_options_dir();
+
 	entry = debugfs_create_file("tracing_cpumask", 0644, d_tracer,
 				    NULL, &tracing_cpumask_fops);
 	if (!entry)
 		pr_warning("Could not create debugfs 'tracing_cpumask' entry\n");
 
-	entry = debugfs_create_file("latency_trace", 0444, d_tracer,
-				    &global_trace, &tracing_lt_fops);
-	if (!entry)
-		pr_warning("Could not create debugfs 'latency_trace' entry\n");
-
-	entry = debugfs_create_file("trace", 0444, d_tracer,
-				    &global_trace, &tracing_fops);
+	entry = debugfs_create_file("trace", 0644, d_tracer,
+				 (void *) TRACE_PIPE_ALL_CPU, &tracing_fops);
 	if (!entry)
 		pr_warning("Could not create debugfs 'trace' entry\n");
 
@@ -3590,8 +3946,8 @@
 	if (!entry)
 		pr_warning("Could not create debugfs 'README' entry\n");
 
-	entry = debugfs_create_file("trace_pipe", 0644, d_tracer,
-				    NULL, &tracing_pipe_fops);
+	entry = debugfs_create_file("trace_pipe", 0444, d_tracer,
+			(void *) TRACE_PIPE_ALL_CPU, &tracing_pipe_fops);
 	if (!entry)
 		pr_warning("Could not create debugfs "
 			   "'trace_pipe' entry\n");
@@ -3619,78 +3975,13 @@
 #ifdef CONFIG_SYSPROF_TRACER
 	init_tracer_sysprof_debugfs(d_tracer);
 #endif
+
+	for_each_tracing_cpu(cpu)
+		tracing_init_debugfs_percpu(cpu);
+
 	return 0;
 }
 
-int trace_vprintk(unsigned long ip, int depth, const char *fmt, va_list args)
-{
-	static DEFINE_SPINLOCK(trace_buf_lock);
-	static char trace_buf[TRACE_BUF_SIZE];
-
-	struct ring_buffer_event *event;
-	struct trace_array *tr = &global_trace;
-	struct trace_array_cpu *data;
-	int cpu, len = 0, size, pc;
-	struct print_entry *entry;
-	unsigned long irq_flags;
-
-	if (tracing_disabled || tracing_selftest_running)
-		return 0;
-
-	pc = preempt_count();
-	preempt_disable_notrace();
-	cpu = raw_smp_processor_id();
-	data = tr->data[cpu];
-
-	if (unlikely(atomic_read(&data->disabled)))
-		goto out;
-
-	pause_graph_tracing();
-	spin_lock_irqsave(&trace_buf_lock, irq_flags);
-	len = vsnprintf(trace_buf, TRACE_BUF_SIZE, fmt, args);
-
-	len = min(len, TRACE_BUF_SIZE-1);
-	trace_buf[len] = 0;
-
-	size = sizeof(*entry) + len + 1;
-	event = ring_buffer_lock_reserve(tr->buffer, size, &irq_flags);
-	if (!event)
-		goto out_unlock;
-	entry = ring_buffer_event_data(event);
-	tracing_generic_entry_update(&entry->ent, irq_flags, pc);
-	entry->ent.type			= TRACE_PRINT;
-	entry->ip			= ip;
-	entry->depth			= depth;
-
-	memcpy(&entry->buf, trace_buf, len);
-	entry->buf[len] = 0;
-	ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
-
- out_unlock:
-	spin_unlock_irqrestore(&trace_buf_lock, irq_flags);
-	unpause_graph_tracing();
- out:
-	preempt_enable_notrace();
-
-	return len;
-}
-EXPORT_SYMBOL_GPL(trace_vprintk);
-
-int __ftrace_printk(unsigned long ip, const char *fmt, ...)
-{
-	int ret;
-	va_list ap;
-
-	if (!(trace_flags & TRACE_ITER_PRINTK))
-		return 0;
-
-	va_start(ap, fmt);
-	ret = trace_vprintk(ip, task_curr_ret_stack(current), fmt, ap);
-	va_end(ap);
-	return ret;
-}
-EXPORT_SYMBOL_GPL(__ftrace_printk);
-
 static int trace_panic_handler(struct notifier_block *this,
 			       unsigned long event, void *unused)
 {
@@ -3750,14 +4041,15 @@
 
 	printk(KERN_TRACE "%s", s->buffer);
 
-	trace_seq_reset(s);
+	trace_seq_init(s);
 }
 
-void ftrace_dump(void)
+static void __ftrace_dump(bool disable_tracing)
 {
 	static DEFINE_SPINLOCK(ftrace_dump_lock);
 	/* use static because iter can be a bit big for the stack */
 	static struct trace_iterator iter;
+	unsigned int old_userobj;
 	static int dump_ran;
 	unsigned long flags;
 	int cnt = 0, cpu;
@@ -3769,21 +4061,26 @@
 
 	dump_ran = 1;
 
-	/* No turning back! */
 	tracing_off();
-	ftrace_kill();
+
+	if (disable_tracing)
+		ftrace_kill();
 
 	for_each_tracing_cpu(cpu) {
 		atomic_inc(&global_trace.data[cpu]->disabled);
 	}
 
+	old_userobj = trace_flags & TRACE_ITER_SYM_USEROBJ;
+
 	/* don't look at user memory in panic mode */
 	trace_flags &= ~TRACE_ITER_SYM_USEROBJ;
 
 	printk(KERN_TRACE "Dumping ftrace buffer:\n");
 
+	/* Simulate the iterator */
 	iter.tr = &global_trace;
 	iter.trace = current_trace;
+	iter.cpu_file = TRACE_PIPE_ALL_CPU;
 
 	/*
 	 * We need to stop all tracing on all CPUS to read the
@@ -3819,13 +4116,30 @@
 	else
 		printk(KERN_TRACE "---------------------------------\n");
 
+	/* Re-enable tracing if requested */
+	if (!disable_tracing) {
+		trace_flags |= old_userobj;
+
+		for_each_tracing_cpu(cpu) {
+			atomic_dec(&global_trace.data[cpu]->disabled);
+		}
+		tracing_on();
+	}
+
  out:
 	spin_unlock_irqrestore(&ftrace_dump_lock, flags);
 }
 
+/* By default: disable tracing after the dump */
+void ftrace_dump(void)
+{
+	__ftrace_dump(true);
+}
+
 __init static int tracer_alloc_buffers(void)
 {
 	struct trace_array_cpu *data;
+	int ring_buf_size;
 	int i;
 	int ret = -ENOMEM;
 
@@ -3835,11 +4149,21 @@
 	if (!alloc_cpumask_var(&tracing_cpumask, GFP_KERNEL))
 		goto out_free_buffer_mask;
 
+	if (!alloc_cpumask_var(&tracing_reader_cpumask, GFP_KERNEL))
+		goto out_free_tracing_cpumask;
+
+	/* To save memory, keep the ring buffer size to its minimum */
+	if (ring_buffer_expanded)
+		ring_buf_size = trace_buf_size;
+	else
+		ring_buf_size = 1;
+
 	cpumask_copy(tracing_buffer_mask, cpu_possible_mask);
 	cpumask_copy(tracing_cpumask, cpu_all_mask);
+	cpumask_clear(tracing_reader_cpumask);
 
 	/* TODO: make the number of buffers hot pluggable with CPUS */
-	global_trace.buffer = ring_buffer_alloc(trace_buf_size,
+	global_trace.buffer = ring_buffer_alloc(ring_buf_size,
 						   TRACE_BUFFER_FLAGS);
 	if (!global_trace.buffer) {
 		printk(KERN_ERR "tracer: failed to allocate ring buffer!\n");
@@ -3850,7 +4174,7 @@
 
 
 #ifdef CONFIG_TRACER_MAX_TRACE
-	max_tr.buffer = ring_buffer_alloc(trace_buf_size,
+	max_tr.buffer = ring_buffer_alloc(ring_buf_size,
 					     TRACE_BUFFER_FLAGS);
 	if (!max_tr.buffer) {
 		printk(KERN_ERR "tracer: failed to allocate max ring buffer!\n");
@@ -3871,14 +4195,10 @@
 	trace_init_cmdlines();
 
 	register_tracer(&nop_trace);
+	current_trace = &nop_trace;
 #ifdef CONFIG_BOOT_TRACER
 	register_tracer(&boot_tracer);
-	current_trace = &boot_tracer;
-	current_trace->init(&global_trace);
-#else
-	current_trace = &nop_trace;
 #endif
-
 	/* All seems OK, enable tracing */
 	tracing_disabled = 0;
 
@@ -3886,14 +4206,38 @@
 				       &trace_panic_notifier);
 
 	register_die_notifier(&trace_die_notifier);
-	ret = 0;
+
+	return 0;
 
 out_free_cpumask:
+	free_cpumask_var(tracing_reader_cpumask);
+out_free_tracing_cpumask:
 	free_cpumask_var(tracing_cpumask);
 out_free_buffer_mask:
 	free_cpumask_var(tracing_buffer_mask);
 out:
 	return ret;
 }
+
+__init static int clear_boot_tracer(void)
+{
+	/*
+	 * The default tracer at boot buffer is an init section.
+	 * This function is called in lateinit. If we did not
+	 * find the boot tracer, then clear it out, to prevent
+	 * later registration from accessing the buffer that is
+	 * about to be freed.
+	 */
+	if (!default_bootup_tracer)
+		return 0;
+
+	printk(KERN_INFO "ftrace bootup tracer '%s' not registered.\n",
+	       default_bootup_tracer);
+	default_bootup_tracer = NULL;
+
+	return 0;
+}
+
 early_initcall(tracer_alloc_buffers);
 fs_initcall(tracer_init_debugfs);
+late_initcall(clear_boot_tracer);
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 4d3d381..cb0ce3f 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -9,6 +9,8 @@
 #include <linux/mmiotrace.h>
 #include <linux/ftrace.h>
 #include <trace/boot.h>
+#include <trace/kmemtrace.h>
+#include <trace/power.h>
 
 enum trace_type {
 	__TRACE_FIRST_TYPE = 0,
@@ -16,9 +18,9 @@
 	TRACE_FN,
 	TRACE_CTX,
 	TRACE_WAKE,
-	TRACE_CONT,
 	TRACE_STACK,
 	TRACE_PRINT,
+	TRACE_BPRINT,
 	TRACE_SPECIAL,
 	TRACE_MMIO_RW,
 	TRACE_MMIO_MAP,
@@ -29,9 +31,14 @@
 	TRACE_GRAPH_ENT,
 	TRACE_USER_STACK,
 	TRACE_HW_BRANCHES,
+	TRACE_SYSCALL_ENTER,
+	TRACE_SYSCALL_EXIT,
+	TRACE_KMEM_ALLOC,
+	TRACE_KMEM_FREE,
 	TRACE_POWER,
+	TRACE_BLK,
 
-	__TRACE_LAST_TYPE
+	__TRACE_LAST_TYPE,
 };
 
 /*
@@ -42,7 +49,6 @@
  */
 struct trace_entry {
 	unsigned char		type;
-	unsigned char		cpu;
 	unsigned char		flags;
 	unsigned char		preempt_count;
 	int			pid;
@@ -60,13 +66,13 @@
 
 /* Function call entry */
 struct ftrace_graph_ent_entry {
-	struct trace_entry			ent;
+	struct trace_entry		ent;
 	struct ftrace_graph_ent		graph_ent;
 };
 
 /* Function return entry */
 struct ftrace_graph_ret_entry {
-	struct trace_entry			ent;
+	struct trace_entry		ent;
 	struct ftrace_graph_ret		ret;
 };
 extern struct tracer boot_tracer;
@@ -112,12 +118,18 @@
 };
 
 /*
- * ftrace_printk entry:
+ * trace_printk entry:
  */
+struct bprint_entry {
+	struct trace_entry	ent;
+	unsigned long		ip;
+	const char		*fmt;
+	u32			buf[];
+};
+
 struct print_entry {
 	struct trace_entry	ent;
 	unsigned long		ip;
-	int			depth;
 	char			buf[];
 };
 
@@ -170,15 +182,45 @@
 	struct power_trace	state_data;
 };
 
+struct kmemtrace_alloc_entry {
+	struct trace_entry	ent;
+	enum kmemtrace_type_id type_id;
+	unsigned long call_site;
+	const void *ptr;
+	size_t bytes_req;
+	size_t bytes_alloc;
+	gfp_t gfp_flags;
+	int node;
+};
+
+struct kmemtrace_free_entry {
+	struct trace_entry	ent;
+	enum kmemtrace_type_id type_id;
+	unsigned long call_site;
+	const void *ptr;
+};
+
+struct syscall_trace_enter {
+	struct trace_entry	ent;
+	int			nr;
+	unsigned long		args[];
+};
+
+struct syscall_trace_exit {
+	struct trace_entry	ent;
+	int			nr;
+	unsigned long		ret;
+};
+
+
 /*
  * trace_flag_type is an enumeration that holds different
  * states when a trace occurs. These are:
  *  IRQS_OFF		- interrupts were disabled
- *  IRQS_NOSUPPORT 	- arch does not support irqs_disabled_flags
+ *  IRQS_NOSUPPORT	- arch does not support irqs_disabled_flags
  *  NEED_RESCED		- reschedule is requested
  *  HARDIRQ		- inside an interrupt handler
  *  SOFTIRQ		- inside a softirq handler
- *  CONT		- multiple entries hold the trace item
  */
 enum trace_flag_type {
 	TRACE_FLAG_IRQS_OFF		= 0x01,
@@ -186,7 +228,6 @@
 	TRACE_FLAG_NEED_RESCHED		= 0x04,
 	TRACE_FLAG_HARDIRQ		= 0x08,
 	TRACE_FLAG_SOFTIRQ		= 0x10,
-	TRACE_FLAG_CONT			= 0x20,
 };
 
 #define TRACE_BUF_SIZE		1024
@@ -198,6 +239,7 @@
  */
 struct trace_array_cpu {
 	atomic_t		disabled;
+	void			*buffer_page;	/* ring buffer spare */
 
 	/* these fields get copied into max-trace: */
 	unsigned long		trace_idx;
@@ -262,10 +304,10 @@
 	do {								\
 		IF_ASSIGN(var, ent, struct ftrace_entry, TRACE_FN);	\
 		IF_ASSIGN(var, ent, struct ctx_switch_entry, 0);	\
-		IF_ASSIGN(var, ent, struct trace_field_cont, TRACE_CONT); \
 		IF_ASSIGN(var, ent, struct stack_entry, TRACE_STACK);	\
 		IF_ASSIGN(var, ent, struct userstack_entry, TRACE_USER_STACK);\
 		IF_ASSIGN(var, ent, struct print_entry, TRACE_PRINT);	\
+		IF_ASSIGN(var, ent, struct bprint_entry, TRACE_BPRINT);	\
 		IF_ASSIGN(var, ent, struct special_entry, 0);		\
 		IF_ASSIGN(var, ent, struct trace_mmiotrace_rw,		\
 			  TRACE_MMIO_RW);				\
@@ -279,7 +321,15 @@
 		IF_ASSIGN(var, ent, struct ftrace_graph_ret_entry,	\
 			  TRACE_GRAPH_RET);		\
 		IF_ASSIGN(var, ent, struct hw_branch_entry, TRACE_HW_BRANCHES);\
- 		IF_ASSIGN(var, ent, struct trace_power, TRACE_POWER); \
+		IF_ASSIGN(var, ent, struct trace_power, TRACE_POWER); \
+		IF_ASSIGN(var, ent, struct kmemtrace_alloc_entry,	\
+			  TRACE_KMEM_ALLOC);	\
+		IF_ASSIGN(var, ent, struct kmemtrace_free_entry,	\
+			  TRACE_KMEM_FREE);	\
+		IF_ASSIGN(var, ent, struct syscall_trace_enter,		\
+			  TRACE_SYSCALL_ENTER);				\
+		IF_ASSIGN(var, ent, struct syscall_trace_exit,		\
+			  TRACE_SYSCALL_EXIT);				\
 		__ftrace_bad_type();					\
 	} while (0)
 
@@ -287,7 +337,8 @@
 enum print_line_t {
 	TRACE_TYPE_PARTIAL_LINE	= 0,	/* Retry after flushing the seq */
 	TRACE_TYPE_HANDLED	= 1,
-	TRACE_TYPE_UNHANDLED	= 2	/* Relay to other output functions */
+	TRACE_TYPE_UNHANDLED	= 2,	/* Relay to other output functions */
+	TRACE_TYPE_NO_CONSUME	= 3	/* Handled but ask to not consume */
 };
 
 
@@ -297,8 +348,8 @@
  * flags value in struct tracer_flags.
  */
 struct tracer_opt {
-	const char 	*name; /* Will appear on the trace_options file */
-	u32 		bit; /* Mask assigned in val field in tracer_flags */
+	const char	*name; /* Will appear on the trace_options file */
+	u32		bit; /* Mask assigned in val field in tracer_flags */
 };
 
 /*
@@ -307,28 +358,51 @@
  */
 struct tracer_flags {
 	u32			val;
-	struct tracer_opt 	*opts;
+	struct tracer_opt	*opts;
 };
 
 /* Makes more easy to define a tracer opt */
 #define TRACER_OPT(s, b)	.name = #s, .bit = b
 
-/*
- * A specific tracer, represented by methods that operate on a trace array:
+
+/**
+ * struct tracer - a specific tracer and its callbacks to interact with debugfs
+ * @name: the name chosen to select it on the available_tracers file
+ * @init: called when one switches to this tracer (echo name > current_tracer)
+ * @reset: called when one switches to another tracer
+ * @start: called when tracing is unpaused (echo 1 > tracing_enabled)
+ * @stop: called when tracing is paused (echo 0 > tracing_enabled)
+ * @open: called when the trace file is opened
+ * @pipe_open: called when the trace_pipe file is opened
+ * @wait_pipe: override how the user waits for traces on trace_pipe
+ * @close: called when the trace file is released
+ * @read: override the default read callback on trace_pipe
+ * @splice_read: override the default splice_read callback on trace_pipe
+ * @selftest: selftest to run on boot (see trace_selftest.c)
+ * @print_headers: override the first lines that describe your columns
+ * @print_line: callback that prints a trace
+ * @set_flag: signals one of your private flags changed (trace_options file)
+ * @flags: your private flags
  */
 struct tracer {
 	const char		*name;
-	/* Your tracer should raise a warning if init fails */
 	int			(*init)(struct trace_array *tr);
 	void			(*reset)(struct trace_array *tr);
 	void			(*start)(struct trace_array *tr);
 	void			(*stop)(struct trace_array *tr);
 	void			(*open)(struct trace_iterator *iter);
 	void			(*pipe_open)(struct trace_iterator *iter);
+	void			(*wait_pipe)(struct trace_iterator *iter);
 	void			(*close)(struct trace_iterator *iter);
 	ssize_t			(*read)(struct trace_iterator *iter,
 					struct file *filp, char __user *ubuf,
 					size_t cnt, loff_t *ppos);
+	ssize_t			(*splice_read)(struct trace_iterator *iter,
+					       struct file *filp,
+					       loff_t *ppos,
+					       struct pipe_inode_info *pipe,
+					       size_t len,
+					       unsigned int flags);
 #ifdef CONFIG_FTRACE_STARTUP_TEST
 	int			(*selftest)(struct tracer *trace,
 					    struct trace_array *tr);
@@ -339,7 +413,8 @@
 	int			(*set_flag)(u32 old_flags, u32 bit, int set);
 	struct tracer		*next;
 	int			print_max;
-	struct tracer_flags 	*flags;
+	struct tracer_flags	*flags;
+	struct tracer_stat	*stats;
 };
 
 struct trace_seq {
@@ -348,6 +423,16 @@
 	unsigned int		readpos;
 };
 
+static inline void
+trace_seq_init(struct trace_seq *s)
+{
+	s->len = 0;
+	s->readpos = 0;
+}
+
+
+#define TRACE_PIPE_ALL_CPU	-1
+
 /*
  * Trace iterator - used by printout routines who present trace
  * results to users and which routines might sleep, etc:
@@ -356,6 +441,8 @@
 	struct trace_array	*tr;
 	struct tracer		*trace;
 	void			*private;
+	int			cpu_file;
+	struct mutex		mutex;
 	struct ring_buffer_iter	*buffer_iter[NR_CPUS];
 
 	/* The below is zeroed out in pipe_read */
@@ -371,6 +458,7 @@
 	cpumask_var_t		started;
 };
 
+int tracer_init(struct tracer *t, struct trace_array *tr);
 int tracing_is_enabled(void);
 void trace_wake_up(void);
 void tracing_reset(struct trace_array *tr, int cpu);
@@ -379,26 +467,50 @@
 struct dentry *tracing_init_dentry(void);
 void init_tracer_sysprof_debugfs(struct dentry *d_tracer);
 
+struct ring_buffer_event;
+
+struct ring_buffer_event *trace_buffer_lock_reserve(struct trace_array *tr,
+						    unsigned char type,
+						    unsigned long len,
+						    unsigned long flags,
+						    int pc);
+void trace_buffer_unlock_commit(struct trace_array *tr,
+				struct ring_buffer_event *event,
+				unsigned long flags, int pc);
+
+struct ring_buffer_event *
+trace_current_buffer_lock_reserve(unsigned char type, unsigned long len,
+				  unsigned long flags, int pc);
+void trace_current_buffer_unlock_commit(struct ring_buffer_event *event,
+					unsigned long flags, int pc);
+void trace_nowake_buffer_unlock_commit(struct ring_buffer_event *event,
+					unsigned long flags, int pc);
+
 struct trace_entry *tracing_get_trace_entry(struct trace_array *tr,
 						struct trace_array_cpu *data);
+
+struct trace_entry *trace_find_next_entry(struct trace_iterator *iter,
+					  int *ent_cpu, u64 *ent_ts);
+
 void tracing_generic_entry_update(struct trace_entry *entry,
 				  unsigned long flags,
 				  int pc);
 
+void default_wait_pipe(struct trace_iterator *iter);
+void poll_wait_pipe(struct trace_iterator *iter);
+
 void ftrace(struct trace_array *tr,
 			    struct trace_array_cpu *data,
 			    unsigned long ip,
 			    unsigned long parent_ip,
 			    unsigned long flags, int pc);
 void tracing_sched_switch_trace(struct trace_array *tr,
-				struct trace_array_cpu *data,
 				struct task_struct *prev,
 				struct task_struct *next,
 				unsigned long flags, int pc);
 void tracing_record_cmdline(struct task_struct *tsk);
 
 void tracing_sched_wakeup_trace(struct trace_array *tr,
-				struct trace_array_cpu *data,
 				struct task_struct *wakee,
 				struct task_struct *cur,
 				unsigned long flags, int pc);
@@ -408,14 +520,12 @@
 		   unsigned long arg2,
 		   unsigned long arg3, int pc);
 void trace_function(struct trace_array *tr,
-		    struct trace_array_cpu *data,
 		    unsigned long ip,
 		    unsigned long parent_ip,
 		    unsigned long flags, int pc);
 
 void trace_graph_return(struct ftrace_graph_ret *trace);
 int trace_graph_entry(struct ftrace_graph_ent *trace);
-void trace_hw_branch(struct trace_array *tr, u64 from, u64 to);
 
 void tracing_start_cmdline_record(void);
 void tracing_stop_cmdline_record(void);
@@ -434,15 +544,11 @@
 void update_max_tr_single(struct trace_array *tr,
 			  struct task_struct *tsk, int cpu);
 
-extern cycle_t ftrace_now(int cpu);
+void __trace_stack(struct trace_array *tr,
+		   unsigned long flags,
+		   int skip, int pc);
 
-#ifdef CONFIG_FUNCTION_TRACER
-void tracing_start_function_trace(void);
-void tracing_stop_function_trace(void);
-#else
-# define tracing_start_function_trace()		do { } while (0)
-# define tracing_stop_function_trace()		do { } while (0)
-#endif
+extern cycle_t ftrace_now(int cpu);
 
 #ifdef CONFIG_CONTEXT_SWITCH_TRACER
 typedef void
@@ -456,10 +562,10 @@
 	void				*private;
 	struct tracer_switch_ops	*next;
 };
-
-char *trace_find_cmdline(int pid);
 #endif /* CONFIG_CONTEXT_SWITCH_TRACER */
 
+extern void trace_find_cmdline(int pid, char comm[]);
+
 #ifdef CONFIG_DYNAMIC_FTRACE
 extern unsigned long ftrace_update_tot_cnt;
 #define DYN_FTRACE_TEST_NAME trace_selftest_dynamic_test_func
@@ -469,6 +575,8 @@
 #ifdef CONFIG_FTRACE_STARTUP_TEST
 extern int trace_selftest_startup_function(struct tracer *trace,
 					   struct trace_array *tr);
+extern int trace_selftest_startup_function_graph(struct tracer *trace,
+						 struct trace_array *tr);
 extern int trace_selftest_startup_irqsoff(struct tracer *trace,
 					  struct trace_array *tr);
 extern int trace_selftest_startup_preemptoff(struct tracer *trace,
@@ -488,18 +596,11 @@
 #endif /* CONFIG_FTRACE_STARTUP_TEST */
 
 extern void *head_page(struct trace_array_cpu *data);
-extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...);
-extern void trace_seq_print_cont(struct trace_seq *s,
-				 struct trace_iterator *iter);
-
-extern int
-seq_print_ip_sym(struct trace_seq *s, unsigned long ip,
-		unsigned long sym_flags);
-extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf,
-				 size_t cnt);
 extern long ns2usecs(cycle_t nsec);
 extern int
-trace_vprintk(unsigned long ip, int depth, const char *fmt, va_list args);
+trace_vbprintk(unsigned long ip, const char *fmt, va_list args);
+extern int
+trace_vprintk(unsigned long ip, const char *fmt, va_list args);
 
 extern unsigned long trace_flags;
 
@@ -580,7 +681,11 @@
 	TRACE_ITER_ANNOTATE		= 0x2000,
 	TRACE_ITER_USERSTACKTRACE       = 0x4000,
 	TRACE_ITER_SYM_USEROBJ          = 0x8000,
-	TRACE_ITER_PRINTK_MSGONLY	= 0x10000
+	TRACE_ITER_PRINTK_MSGONLY	= 0x10000,
+	TRACE_ITER_CONTEXT_INFO		= 0x20000, /* Print pid/cpu/time */
+	TRACE_ITER_LATENCY_FMT		= 0x40000,
+	TRACE_ITER_GLOBAL_CLK		= 0x80000,
+	TRACE_ITER_SLEEP_TIME		= 0x100000,
 };
 
 /*
@@ -601,12 +706,12 @@
  * preempt_enable (after a disable), a schedule might take place
  * causing an infinite recursion.
  *
- * To prevent this, we read the need_recshed flag before
+ * To prevent this, we read the need_resched flag before
  * disabling preemption. When we want to enable preemption we
  * check the flag, if it is set, then we call preempt_enable_no_resched.
  * Otherwise, we call preempt_enable.
  *
- * The rational for doing the above is that if need resched is set
+ * The rational for doing the above is that if need_resched is set
  * and we have yet to reschedule, we are either in an atomic location
  * (where we do not need to check for scheduling) or we are inside
  * the scheduler and do not want to resched.
@@ -627,7 +732,7 @@
  *
  * This is a scheduler safe way to enable preemption and not miss
  * any preemption checks. The disabled saved the state of preemption.
- * If resched is set, then we were either inside an atomic or
+ * If resched is set, then we are either inside an atomic or
  * are inside the scheduler (we would have already scheduled
  * otherwise). In this case, we do not want to call normal
  * preempt_enable, but preempt_enable_no_resched instead.
@@ -664,4 +769,118 @@
 }
 #endif /* CONFIG_BRANCH_TRACER */
 
+/* set ring buffers to default size if not already done so */
+int tracing_update_buffers(void);
+
+/* trace event type bit fields, not numeric */
+enum {
+	TRACE_EVENT_TYPE_PRINTF		= 1,
+	TRACE_EVENT_TYPE_RAW		= 2,
+};
+
+struct ftrace_event_field {
+	struct list_head	link;
+	char			*name;
+	char			*type;
+	int			offset;
+	int			size;
+};
+
+struct ftrace_event_call {
+	char			*name;
+	char			*system;
+	struct dentry		*dir;
+	int			enabled;
+	int			(*regfunc)(void);
+	void			(*unregfunc)(void);
+	int			id;
+	int			(*raw_init)(void);
+	int			(*show_format)(struct trace_seq *s);
+	int			(*define_fields)(void);
+	struct list_head	fields;
+	struct filter_pred	**preds;
+
+#ifdef CONFIG_EVENT_PROFILE
+	atomic_t	profile_count;
+	int		(*profile_enable)(struct ftrace_event_call *);
+	void		(*profile_disable)(struct ftrace_event_call *);
+#endif
+};
+
+struct event_subsystem {
+	struct list_head	list;
+	const char		*name;
+	struct dentry		*entry;
+	struct filter_pred	**preds;
+};
+
+#define events_for_each(event)						\
+	for (event = __start_ftrace_events;				\
+	     (unsigned long)event < (unsigned long)__stop_ftrace_events; \
+	     event++)
+
+#define MAX_FILTER_PRED 8
+
+struct filter_pred;
+
+typedef int (*filter_pred_fn_t) (struct filter_pred *pred, void *event);
+
+struct filter_pred {
+	filter_pred_fn_t fn;
+	u64 val;
+	char *str_val;
+	int str_len;
+	char *field_name;
+	int offset;
+	int not;
+	int or;
+	int compound;
+	int clear;
+};
+
+int trace_define_field(struct ftrace_event_call *call, char *type,
+		       char *name, int offset, int size);
+extern void filter_free_pred(struct filter_pred *pred);
+extern void filter_print_preds(struct filter_pred **preds,
+			       struct trace_seq *s);
+extern int filter_parse(char **pbuf, struct filter_pred *pred);
+extern int filter_add_pred(struct ftrace_event_call *call,
+			   struct filter_pred *pred);
+extern void filter_free_preds(struct ftrace_event_call *call);
+extern int filter_match_preds(struct ftrace_event_call *call, void *rec);
+extern void filter_free_subsystem_preds(struct event_subsystem *system);
+extern int filter_add_subsystem_pred(struct event_subsystem *system,
+				     struct filter_pred *pred);
+
+void event_trace_printk(unsigned long ip, const char *fmt, ...);
+extern struct ftrace_event_call __start_ftrace_events[];
+extern struct ftrace_event_call __stop_ftrace_events[];
+
+#define for_each_event(event)						\
+	for (event = __start_ftrace_events;				\
+	     (unsigned long)event < (unsigned long)__stop_ftrace_events; \
+	     event++)
+
+extern const char *__start___trace_bprintk_fmt[];
+extern const char *__stop___trace_bprintk_fmt[];
+
+/*
+ * The double __builtin_constant_p is because gcc will give us an error
+ * if we try to allocate the static variable to fmt if it is not a
+ * constant. Even with the outer if statement optimizing out.
+ */
+#define event_trace_printk(ip, fmt, args...)				\
+do {									\
+	__trace_printk_check_format(fmt, ##args);			\
+	tracing_record_cmdline(current);				\
+	if (__builtin_constant_p(fmt)) {				\
+		static const char *trace_printk_fmt			\
+		  __attribute__((section("__trace_printk_fmt"))) =	\
+			__builtin_constant_p(fmt) ? fmt : NULL;		\
+									\
+		__trace_bprintk(ip, trace_printk_fmt, ##args);		\
+	} else								\
+		__trace_printk(ip, fmt, ##args);			\
+} while (0)
+
 #endif /* _LINUX_KERNEL_TRACE_H */
diff --git a/kernel/trace/trace_boot.c b/kernel/trace/trace_boot.c
index 366c8c3..7a30fc4 100644
--- a/kernel/trace/trace_boot.c
+++ b/kernel/trace/trace_boot.c
@@ -11,6 +11,7 @@
 #include <linux/kallsyms.h>
 
 #include "trace.h"
+#include "trace_output.h"
 
 static struct trace_array *boot_trace;
 static bool pre_initcalls_finished;
@@ -27,13 +28,13 @@
 
 void enable_boot_trace(void)
 {
-	if (pre_initcalls_finished)
+	if (boot_trace && pre_initcalls_finished)
 		tracing_start_sched_switch_record();
 }
 
 void disable_boot_trace(void)
 {
-	if (pre_initcalls_finished)
+	if (boot_trace && pre_initcalls_finished)
 		tracing_stop_sched_switch_record();
 }
 
@@ -42,6 +43,9 @@
 	int cpu;
 	boot_trace = tr;
 
+	if (!tr)
+		return 0;
+
 	for_each_cpu(cpu, cpu_possible_mask)
 		tracing_reset(tr, cpu);
 
@@ -128,10 +132,9 @@
 {
 	struct ring_buffer_event *event;
 	struct trace_boot_call *entry;
-	unsigned long irq_flags;
 	struct trace_array *tr = boot_trace;
 
-	if (!pre_initcalls_finished)
+	if (!tr || !pre_initcalls_finished)
 		return;
 
 	/* Get its name now since this function could
@@ -140,18 +143,13 @@
 	sprint_symbol(bt->func, (unsigned long)fn);
 	preempt_disable();
 
-	event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
-					 &irq_flags);
+	event = trace_buffer_lock_reserve(tr, TRACE_BOOT_CALL,
+					  sizeof(*entry), 0, 0);
 	if (!event)
 		goto out;
 	entry	= ring_buffer_event_data(event);
-	tracing_generic_entry_update(&entry->ent, 0, 0);
-	entry->ent.type = TRACE_BOOT_CALL;
 	entry->boot_call = *bt;
-	ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
-
-	trace_wake_up();
-
+	trace_buffer_unlock_commit(tr, event, 0, 0);
  out:
 	preempt_enable();
 }
@@ -160,27 +158,21 @@
 {
 	struct ring_buffer_event *event;
 	struct trace_boot_ret *entry;
-	unsigned long irq_flags;
 	struct trace_array *tr = boot_trace;
 
-	if (!pre_initcalls_finished)
+	if (!tr || !pre_initcalls_finished)
 		return;
 
 	sprint_symbol(bt->func, (unsigned long)fn);
 	preempt_disable();
 
-	event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
-					 &irq_flags);
+	event = trace_buffer_lock_reserve(tr, TRACE_BOOT_RET,
+					  sizeof(*entry), 0, 0);
 	if (!event)
 		goto out;
 	entry	= ring_buffer_event_data(event);
-	tracing_generic_entry_update(&entry->ent, 0, 0);
-	entry->ent.type = TRACE_BOOT_RET;
 	entry->boot_ret = *bt;
-	ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
-
-	trace_wake_up();
-
+	trace_buffer_unlock_commit(tr, event, 0, 0);
  out:
 	preempt_enable();
 }
diff --git a/kernel/trace/trace_branch.c b/kernel/trace/trace_branch.c
index 6c00feb..ad8c22e 100644
--- a/kernel/trace/trace_branch.c
+++ b/kernel/trace/trace_branch.c
@@ -14,12 +14,17 @@
 #include <linux/hash.h>
 #include <linux/fs.h>
 #include <asm/local.h>
+
 #include "trace.h"
+#include "trace_stat.h"
+#include "trace_output.h"
 
 #ifdef CONFIG_BRANCH_TRACER
 
+static struct tracer branch_trace;
 static int branch_tracing_enabled __read_mostly;
 static DEFINE_MUTEX(branch_tracing_mutex);
+
 static struct trace_array *branch_tracer;
 
 static void
@@ -28,7 +33,7 @@
 	struct trace_array *tr = branch_tracer;
 	struct ring_buffer_event *event;
 	struct trace_branch *entry;
-	unsigned long flags, irq_flags;
+	unsigned long flags;
 	int cpu, pc;
 	const char *p;
 
@@ -47,15 +52,13 @@
 	if (atomic_inc_return(&tr->data[cpu]->disabled) != 1)
 		goto out;
 
-	event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
-					 &irq_flags);
+	pc = preempt_count();
+	event = trace_buffer_lock_reserve(tr, TRACE_BRANCH,
+					  sizeof(*entry), flags, pc);
 	if (!event)
 		goto out;
 
-	pc = preempt_count();
 	entry	= ring_buffer_event_data(event);
-	tracing_generic_entry_update(&entry->ent, flags, pc);
-	entry->ent.type		= TRACE_BRANCH;
 
 	/* Strip off the path, only save the file */
 	p = f->file + strlen(f->file);
@@ -70,7 +73,7 @@
 	entry->line = f->line;
 	entry->correct = val == expect;
 
-	ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
+	ring_buffer_unlock_commit(tr->buffer, event);
 
  out:
 	atomic_dec(&tr->data[cpu]->disabled);
@@ -88,8 +91,6 @@
 
 int enable_branch_tracing(struct trace_array *tr)
 {
-	int ret = 0;
-
 	mutex_lock(&branch_tracing_mutex);
 	branch_tracer = tr;
 	/*
@@ -100,7 +101,7 @@
 	branch_tracing_enabled++;
 	mutex_unlock(&branch_tracing_mutex);
 
-	return ret;
+	return 0;
 }
 
 void disable_branch_tracing(void)
@@ -128,11 +129,6 @@
 
 static int branch_trace_init(struct trace_array *tr)
 {
-	int cpu;
-
-	for_each_online_cpu(cpu)
-		tracing_reset(tr, cpu);
-
 	start_branch_trace(tr);
 	return 0;
 }
@@ -142,22 +138,53 @@
 	stop_branch_trace(tr);
 }
 
-struct tracer branch_trace __read_mostly =
+static enum print_line_t trace_branch_print(struct trace_iterator *iter,
+					    int flags)
+{
+	struct trace_branch *field;
+
+	trace_assign_type(field, iter->ent);
+
+	if (trace_seq_printf(&iter->seq, "[%s] %s:%s:%d\n",
+			     field->correct ? "  ok  " : " MISS ",
+			     field->func,
+			     field->file,
+			     field->line))
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	return TRACE_TYPE_HANDLED;
+}
+
+
+static struct trace_event trace_branch_event = {
+	.type		= TRACE_BRANCH,
+	.trace		= trace_branch_print,
+};
+
+static struct tracer branch_trace __read_mostly =
 {
 	.name		= "branch",
 	.init		= branch_trace_init,
 	.reset		= branch_trace_reset,
 #ifdef CONFIG_FTRACE_SELFTEST
 	.selftest	= trace_selftest_startup_branch,
-#endif
+#endif /* CONFIG_FTRACE_SELFTEST */
 };
 
-__init static int init_branch_trace(void)
+__init static int init_branch_tracer(void)
 {
+	int ret;
+
+	ret = register_ftrace_event(&trace_branch_event);
+	if (!ret) {
+		printk(KERN_WARNING "Warning: could not register "
+				    "branch events\n");
+		return 1;
+	}
 	return register_tracer(&branch_trace);
 }
+device_initcall(init_branch_tracer);
 
-device_initcall(init_branch_trace);
 #else
 static inline
 void trace_likely_condition(struct ftrace_branch_data *f, int val, int expect)
@@ -183,65 +210,38 @@
 }
 EXPORT_SYMBOL(ftrace_likely_update);
 
-struct ftrace_pointer {
-	void		*start;
-	void		*stop;
-	int		hit;
-};
+extern unsigned long __start_annotated_branch_profile[];
+extern unsigned long __stop_annotated_branch_profile[];
 
-static void *
-t_next(struct seq_file *m, void *v, loff_t *pos)
+static int annotated_branch_stat_headers(struct seq_file *m)
 {
-	const struct ftrace_pointer *f = m->private;
-	struct ftrace_branch_data *p = v;
-
-	(*pos)++;
-
-	if (v == (void *)1)
-		return f->start;
-
-	++p;
-
-	if ((void *)p >= (void *)f->stop)
-		return NULL;
-
-	return p;
-}
-
-static void *t_start(struct seq_file *m, loff_t *pos)
-{
-	void *t = (void *)1;
-	loff_t l = 0;
-
-	for (; t && l < *pos; t = t_next(m, t, &l))
-		;
-
-	return t;
-}
-
-static void t_stop(struct seq_file *m, void *p)
-{
-}
-
-static int t_show(struct seq_file *m, void *v)
-{
-	const struct ftrace_pointer *fp = m->private;
-	struct ftrace_branch_data *p = v;
-	const char *f;
-	long percent;
-
-	if (v == (void *)1) {
-		if (fp->hit)
-			seq_printf(m, "   miss      hit    %% ");
-		else
-			seq_printf(m, " correct incorrect  %% ");
-		seq_printf(m, "       Function                "
+	seq_printf(m, " correct incorrect  %% ");
+	seq_printf(m, "       Function                "
 			      "  File              Line\n"
 			      " ------- ---------  - "
 			      "       --------                "
 			      "  ----              ----\n");
-		return 0;
-	}
+	return 0;
+}
+
+static inline long get_incorrect_percent(struct ftrace_branch_data *p)
+{
+	long percent;
+
+	if (p->correct) {
+		percent = p->incorrect * 100;
+		percent /= p->correct + p->incorrect;
+	} else
+		percent = p->incorrect ? 100 : -1;
+
+	return percent;
+}
+
+static int branch_stat_show(struct seq_file *m, void *v)
+{
+	struct ftrace_branch_data *p = v;
+	const char *f;
+	long percent;
 
 	/* Only print the file, not the path */
 	f = p->file + strlen(p->file);
@@ -252,11 +252,7 @@
 	/*
 	 * The miss is overlayed on correct, and hit on incorrect.
 	 */
-	if (p->correct) {
-		percent = p->incorrect * 100;
-		percent /= p->correct + p->incorrect;
-	} else
-		percent = p->incorrect ? 100 : -1;
+	percent = get_incorrect_percent(p);
 
 	seq_printf(m, "%8lu %8lu ",  p->correct, p->incorrect);
 	if (percent < 0)
@@ -267,76 +263,118 @@
 	return 0;
 }
 
-static struct seq_operations tracing_likely_seq_ops = {
-	.start		= t_start,
-	.next		= t_next,
-	.stop		= t_stop,
-	.show		= t_show,
+static void *annotated_branch_stat_start(void)
+{
+	return __start_annotated_branch_profile;
+}
+
+static void *
+annotated_branch_stat_next(void *v, int idx)
+{
+	struct ftrace_branch_data *p = v;
+
+	++p;
+
+	if ((void *)p >= (void *)__stop_annotated_branch_profile)
+		return NULL;
+
+	return p;
+}
+
+static int annotated_branch_stat_cmp(void *p1, void *p2)
+{
+	struct ftrace_branch_data *a = p1;
+	struct ftrace_branch_data *b = p2;
+
+	long percent_a, percent_b;
+
+	percent_a = get_incorrect_percent(a);
+	percent_b = get_incorrect_percent(b);
+
+	if (percent_a < percent_b)
+		return -1;
+	if (percent_a > percent_b)
+		return 1;
+	else
+		return 0;
+}
+
+static struct tracer_stat annotated_branch_stats = {
+	.name = "branch_annotated",
+	.stat_start = annotated_branch_stat_start,
+	.stat_next = annotated_branch_stat_next,
+	.stat_cmp = annotated_branch_stat_cmp,
+	.stat_headers = annotated_branch_stat_headers,
+	.stat_show = branch_stat_show
 };
 
-static int tracing_branch_open(struct inode *inode, struct file *file)
+__init static int init_annotated_branch_stats(void)
 {
 	int ret;
 
-	ret = seq_open(file, &tracing_likely_seq_ops);
+	ret = register_stat_tracer(&annotated_branch_stats);
 	if (!ret) {
-		struct seq_file *m = file->private_data;
-		m->private = (void *)inode->i_private;
+		printk(KERN_WARNING "Warning: could not register "
+				    "annotated branches stats\n");
+		return 1;
 	}
-
-	return ret;
+	return 0;
 }
-
-static const struct file_operations tracing_branch_fops = {
-	.open		= tracing_branch_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-};
+fs_initcall(init_annotated_branch_stats);
 
 #ifdef CONFIG_PROFILE_ALL_BRANCHES
+
 extern unsigned long __start_branch_profile[];
 extern unsigned long __stop_branch_profile[];
 
-static const struct ftrace_pointer ftrace_branch_pos = {
-	.start			= __start_branch_profile,
-	.stop			= __stop_branch_profile,
-	.hit			= 1,
-};
-
-#endif /* CONFIG_PROFILE_ALL_BRANCHES */
-
-extern unsigned long __start_annotated_branch_profile[];
-extern unsigned long __stop_annotated_branch_profile[];
-
-static const struct ftrace_pointer ftrace_annotated_branch_pos = {
-	.start			= __start_annotated_branch_profile,
-	.stop			= __stop_annotated_branch_profile,
-};
-
-static __init int ftrace_branch_init(void)
+static int all_branch_stat_headers(struct seq_file *m)
 {
-	struct dentry *d_tracer;
-	struct dentry *entry;
-
-	d_tracer = tracing_init_dentry();
-
-	entry = debugfs_create_file("profile_annotated_branch", 0444, d_tracer,
-				    (void *)&ftrace_annotated_branch_pos,
-				    &tracing_branch_fops);
-	if (!entry)
-		pr_warning("Could not create debugfs "
-			   "'profile_annotatet_branch' entry\n");
-
-#ifdef CONFIG_PROFILE_ALL_BRANCHES
-	entry = debugfs_create_file("profile_branch", 0444, d_tracer,
-				    (void *)&ftrace_branch_pos,
-				    &tracing_branch_fops);
-	if (!entry)
-		pr_warning("Could not create debugfs"
-			   " 'profile_branch' entry\n");
-#endif
-
+	seq_printf(m, "   miss      hit    %% ");
+	seq_printf(m, "       Function                "
+			      "  File              Line\n"
+			      " ------- ---------  - "
+			      "       --------                "
+			      "  ----              ----\n");
 	return 0;
 }
 
-device_initcall(ftrace_branch_init);
+static void *all_branch_stat_start(void)
+{
+	return __start_branch_profile;
+}
+
+static void *
+all_branch_stat_next(void *v, int idx)
+{
+	struct ftrace_branch_data *p = v;
+
+	++p;
+
+	if ((void *)p >= (void *)__stop_branch_profile)
+		return NULL;
+
+	return p;
+}
+
+static struct tracer_stat all_branch_stats = {
+	.name = "branch_all",
+	.stat_start = all_branch_stat_start,
+	.stat_next = all_branch_stat_next,
+	.stat_headers = all_branch_stat_headers,
+	.stat_show = branch_stat_show
+};
+
+__init static int all_annotated_branch_stats(void)
+{
+	int ret;
+
+	ret = register_stat_tracer(&all_branch_stats);
+	if (!ret) {
+		printk(KERN_WARNING "Warning: could not register "
+				    "all branches stats\n");
+		return 1;
+	}
+	return 0;
+}
+fs_initcall(all_annotated_branch_stats);
+#endif /* CONFIG_PROFILE_ALL_BRANCHES */
diff --git a/kernel/trace/trace_clock.c b/kernel/trace/trace_clock.c
new file mode 100644
index 0000000..b588fd8
--- /dev/null
+++ b/kernel/trace/trace_clock.c
@@ -0,0 +1,109 @@
+/*
+ * tracing clocks
+ *
+ *  Copyright (C) 2009 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ *
+ * Implements 3 trace clock variants, with differing scalability/precision
+ * tradeoffs:
+ *
+ *  -   local: CPU-local trace clock
+ *  -  medium: scalable global clock with some jitter
+ *  -  global: globally monotonic, serialized clock
+ *
+ * Tracer plugins will chose a default from these clocks.
+ */
+#include <linux/spinlock.h>
+#include <linux/hardirq.h>
+#include <linux/module.h>
+#include <linux/percpu.h>
+#include <linux/sched.h>
+#include <linux/ktime.h>
+#include <linux/trace_clock.h>
+
+/*
+ * trace_clock_local(): the simplest and least coherent tracing clock.
+ *
+ * Useful for tracing that does not cross to other CPUs nor
+ * does it go through idle events.
+ */
+u64 notrace trace_clock_local(void)
+{
+	unsigned long flags;
+	u64 clock;
+
+	/*
+	 * sched_clock() is an architecture implemented, fast, scalable,
+	 * lockless clock. It is not guaranteed to be coherent across
+	 * CPUs, nor across CPU idle events.
+	 */
+	raw_local_irq_save(flags);
+	clock = sched_clock();
+	raw_local_irq_restore(flags);
+
+	return clock;
+}
+
+/*
+ * trace_clock(): 'inbetween' trace clock. Not completely serialized,
+ * but not completely incorrect when crossing CPUs either.
+ *
+ * This is based on cpu_clock(), which will allow at most ~1 jiffy of
+ * jitter between CPUs. So it's a pretty scalable clock, but there
+ * can be offsets in the trace data.
+ */
+u64 notrace trace_clock(void)
+{
+	return cpu_clock(raw_smp_processor_id());
+}
+
+
+/*
+ * trace_clock_global(): special globally coherent trace clock
+ *
+ * It has higher overhead than the other trace clocks but is still
+ * an order of magnitude faster than GTOD derived hardware clocks.
+ *
+ * Used by plugins that need globally coherent timestamps.
+ */
+
+static u64 prev_trace_clock_time;
+
+static raw_spinlock_t trace_clock_lock ____cacheline_aligned_in_smp =
+	(raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
+
+u64 notrace trace_clock_global(void)
+{
+	unsigned long flags;
+	int this_cpu;
+	u64 now;
+
+	raw_local_irq_save(flags);
+
+	this_cpu = raw_smp_processor_id();
+	now = cpu_clock(this_cpu);
+	/*
+	 * If in an NMI context then dont risk lockups and return the
+	 * cpu_clock() time:
+	 */
+	if (unlikely(in_nmi()))
+		goto out;
+
+	__raw_spin_lock(&trace_clock_lock);
+
+	/*
+	 * TODO: if this happens often then maybe we should reset
+	 * my_scd->clock to prev_trace_clock_time+1, to make sure
+	 * we start ticking with the local clock from now on?
+	 */
+	if ((s64)(now - prev_trace_clock_time) < 0)
+		now = prev_trace_clock_time + 1;
+
+	prev_trace_clock_time = now;
+
+	__raw_spin_unlock(&trace_clock_lock);
+
+ out:
+	raw_local_irq_restore(flags);
+
+	return now;
+}
diff --git a/kernel/trace/trace_event_profile.c b/kernel/trace/trace_event_profile.c
new file mode 100644
index 0000000..22cba99
--- /dev/null
+++ b/kernel/trace/trace_event_profile.c
@@ -0,0 +1,31 @@
+/*
+ * trace event based perf counter profiling
+ *
+ * Copyright (C) 2009 Red Hat Inc, Peter Zijlstra <pzijlstr@redhat.com>
+ *
+ */
+
+#include "trace.h"
+
+int ftrace_profile_enable(int event_id)
+{
+	struct ftrace_event_call *event;
+
+	for_each_event(event) {
+		if (event->id == event_id)
+			return event->profile_enable(event);
+	}
+
+	return -EINVAL;
+}
+
+void ftrace_profile_disable(int event_id)
+{
+	struct ftrace_event_call *event;
+
+	for_each_event(event) {
+		if (event->id == event_id)
+			return event->profile_disable(event);
+	}
+}
+
diff --git a/kernel/trace/trace_event_types.h b/kernel/trace/trace_event_types.h
new file mode 100644
index 0000000..fd78bee
--- /dev/null
+++ b/kernel/trace/trace_event_types.h
@@ -0,0 +1,173 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM	ftrace
+
+/*
+ * We cheat and use the proto type field as the ID
+ * and args as the entry type (minus 'struct')
+ */
+TRACE_EVENT_FORMAT(function, TRACE_FN, ftrace_entry, ignore,
+	TRACE_STRUCT(
+		TRACE_FIELD(unsigned long, ip, ip)
+		TRACE_FIELD(unsigned long, parent_ip, parent_ip)
+	),
+	TP_RAW_FMT(" %lx <-- %lx")
+);
+
+TRACE_EVENT_FORMAT(funcgraph_entry, TRACE_GRAPH_ENT,
+		   ftrace_graph_ent_entry, ignore,
+	TRACE_STRUCT(
+		TRACE_FIELD(unsigned long, graph_ent.func, func)
+		TRACE_FIELD(int, graph_ent.depth, depth)
+	),
+	TP_RAW_FMT("--> %lx (%d)")
+);
+
+TRACE_EVENT_FORMAT(funcgraph_exit, TRACE_GRAPH_RET,
+		   ftrace_graph_ret_entry, ignore,
+	TRACE_STRUCT(
+		TRACE_FIELD(unsigned long, ret.func, func)
+		TRACE_FIELD(int, ret.depth, depth)
+	),
+	TP_RAW_FMT("<-- %lx (%d)")
+);
+
+TRACE_EVENT_FORMAT(wakeup, TRACE_WAKE, ctx_switch_entry, ignore,
+	TRACE_STRUCT(
+		TRACE_FIELD(unsigned int, prev_pid, prev_pid)
+		TRACE_FIELD(unsigned char, prev_prio, prev_prio)
+		TRACE_FIELD(unsigned char, prev_state, prev_state)
+		TRACE_FIELD(unsigned int, next_pid, next_pid)
+		TRACE_FIELD(unsigned char, next_prio, next_prio)
+		TRACE_FIELD(unsigned char, next_state, next_state)
+		TRACE_FIELD(unsigned int, next_cpu, next_cpu)
+	),
+	TP_RAW_FMT("%u:%u:%u  ==+ %u:%u:%u [%03u]")
+);
+
+TRACE_EVENT_FORMAT(context_switch, TRACE_CTX, ctx_switch_entry, ignore,
+	TRACE_STRUCT(
+		TRACE_FIELD(unsigned int, prev_pid, prev_pid)
+		TRACE_FIELD(unsigned char, prev_prio, prev_prio)
+		TRACE_FIELD(unsigned char, prev_state, prev_state)
+		TRACE_FIELD(unsigned int, next_pid, next_pid)
+		TRACE_FIELD(unsigned char, next_prio, next_prio)
+		TRACE_FIELD(unsigned char, next_state, next_state)
+		TRACE_FIELD(unsigned int, next_cpu, next_cpu)
+	),
+	TP_RAW_FMT("%u:%u:%u  ==+ %u:%u:%u [%03u]")
+);
+
+TRACE_EVENT_FORMAT(special, TRACE_SPECIAL, special_entry, ignore,
+	TRACE_STRUCT(
+		TRACE_FIELD(unsigned long, arg1, arg1)
+		TRACE_FIELD(unsigned long, arg2, arg2)
+		TRACE_FIELD(unsigned long, arg3, arg3)
+	),
+	TP_RAW_FMT("(%08lx) (%08lx) (%08lx)")
+);
+
+/*
+ * Stack-trace entry:
+ */
+
+/* #define FTRACE_STACK_ENTRIES   8 */
+
+TRACE_EVENT_FORMAT(kernel_stack, TRACE_STACK, stack_entry, ignore,
+	TRACE_STRUCT(
+		TRACE_FIELD(unsigned long, caller[0], stack0)
+		TRACE_FIELD(unsigned long, caller[1], stack1)
+		TRACE_FIELD(unsigned long, caller[2], stack2)
+		TRACE_FIELD(unsigned long, caller[3], stack3)
+		TRACE_FIELD(unsigned long, caller[4], stack4)
+		TRACE_FIELD(unsigned long, caller[5], stack5)
+		TRACE_FIELD(unsigned long, caller[6], stack6)
+		TRACE_FIELD(unsigned long, caller[7], stack7)
+	),
+	TP_RAW_FMT("\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n"
+		 "\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n")
+);
+
+TRACE_EVENT_FORMAT(user_stack, TRACE_USER_STACK, userstack_entry, ignore,
+	TRACE_STRUCT(
+		TRACE_FIELD(unsigned long, caller[0], stack0)
+		TRACE_FIELD(unsigned long, caller[1], stack1)
+		TRACE_FIELD(unsigned long, caller[2], stack2)
+		TRACE_FIELD(unsigned long, caller[3], stack3)
+		TRACE_FIELD(unsigned long, caller[4], stack4)
+		TRACE_FIELD(unsigned long, caller[5], stack5)
+		TRACE_FIELD(unsigned long, caller[6], stack6)
+		TRACE_FIELD(unsigned long, caller[7], stack7)
+	),
+	TP_RAW_FMT("\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n"
+		 "\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n")
+);
+
+TRACE_EVENT_FORMAT(bprint, TRACE_BPRINT, bprint_entry, ignore,
+	TRACE_STRUCT(
+		TRACE_FIELD(unsigned long, ip, ip)
+		TRACE_FIELD(char *, fmt, fmt)
+		TRACE_FIELD_ZERO_CHAR(buf)
+	),
+	TP_RAW_FMT("%08lx (%d) fmt:%p %s")
+);
+
+TRACE_EVENT_FORMAT(print, TRACE_PRINT, print_entry, ignore,
+	TRACE_STRUCT(
+		TRACE_FIELD(unsigned long, ip, ip)
+		TRACE_FIELD_ZERO_CHAR(buf)
+	),
+	TP_RAW_FMT("%08lx (%d) fmt:%p %s")
+);
+
+TRACE_EVENT_FORMAT(branch, TRACE_BRANCH, trace_branch, ignore,
+	TRACE_STRUCT(
+		TRACE_FIELD(unsigned int, line, line)
+		TRACE_FIELD_SPECIAL(char func[TRACE_FUNC_SIZE+1], func, func)
+		TRACE_FIELD_SPECIAL(char file[TRACE_FUNC_SIZE+1], file, file)
+		TRACE_FIELD(char, correct, correct)
+	),
+	TP_RAW_FMT("%u:%s:%s (%u)")
+);
+
+TRACE_EVENT_FORMAT(hw_branch, TRACE_HW_BRANCHES, hw_branch_entry, ignore,
+	TRACE_STRUCT(
+		TRACE_FIELD(u64, from, from)
+		TRACE_FIELD(u64, to, to)
+	),
+	TP_RAW_FMT("from: %llx to: %llx")
+);
+
+TRACE_EVENT_FORMAT(power, TRACE_POWER, trace_power, ignore,
+	TRACE_STRUCT(
+		TRACE_FIELD(ktime_t, state_data.stamp, stamp)
+		TRACE_FIELD(ktime_t, state_data.end, end)
+		TRACE_FIELD(int, state_data.type, type)
+		TRACE_FIELD(int, state_data.state, state)
+	),
+	TP_RAW_FMT("%llx->%llx type:%u state:%u")
+);
+
+TRACE_EVENT_FORMAT(kmem_alloc, TRACE_KMEM_ALLOC, kmemtrace_alloc_entry, ignore,
+	TRACE_STRUCT(
+		TRACE_FIELD(enum kmemtrace_type_id, type_id, type_id)
+		TRACE_FIELD(unsigned long, call_site, call_site)
+		TRACE_FIELD(const void *, ptr, ptr)
+		TRACE_FIELD(size_t, bytes_req, bytes_req)
+		TRACE_FIELD(size_t, bytes_alloc, bytes_alloc)
+		TRACE_FIELD(gfp_t, gfp_flags, gfp_flags)
+		TRACE_FIELD(int, node, node)
+	),
+	TP_RAW_FMT("type:%u call_site:%lx ptr:%p req:%lu alloc:%lu"
+		 " flags:%x node:%d")
+);
+
+TRACE_EVENT_FORMAT(kmem_free, TRACE_KMEM_FREE, kmemtrace_free_entry, ignore,
+	TRACE_STRUCT(
+		TRACE_FIELD(enum kmemtrace_type_id, type_id, type_id)
+		TRACE_FIELD(unsigned long, call_site, call_site)
+		TRACE_FIELD(const void *, ptr, ptr)
+	),
+	TP_RAW_FMT("type:%u call_site:%lx ptr:%p")
+);
+
+#undef TRACE_SYSTEM
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
new file mode 100644
index 0000000..64ec4d2
--- /dev/null
+++ b/kernel/trace/trace_events.c
@@ -0,0 +1,824 @@
+/*
+ * event tracer
+ *
+ * Copyright (C) 2008 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
+ *
+ *  - Added format output of fields of the trace point.
+ *    This was based off of work by Tom Zanussi <tzanussi@gmail.com>.
+ *
+ */
+
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+#include <linux/module.h>
+#include <linux/ctype.h>
+
+#include "trace_output.h"
+
+#define TRACE_SYSTEM "TRACE_SYSTEM"
+
+static DEFINE_MUTEX(event_mutex);
+
+int trace_define_field(struct ftrace_event_call *call, char *type,
+		       char *name, int offset, int size)
+{
+	struct ftrace_event_field *field;
+
+	field = kzalloc(sizeof(*field), GFP_KERNEL);
+	if (!field)
+		goto err;
+
+	field->name = kstrdup(name, GFP_KERNEL);
+	if (!field->name)
+		goto err;
+
+	field->type = kstrdup(type, GFP_KERNEL);
+	if (!field->type)
+		goto err;
+
+	field->offset = offset;
+	field->size = size;
+	list_add(&field->link, &call->fields);
+
+	return 0;
+
+err:
+	if (field) {
+		kfree(field->name);
+		kfree(field->type);
+	}
+	kfree(field);
+
+	return -ENOMEM;
+}
+
+static void ftrace_clear_events(void)
+{
+	struct ftrace_event_call *call = (void *)__start_ftrace_events;
+
+
+	while ((unsigned long)call < (unsigned long)__stop_ftrace_events) {
+
+		if (call->enabled) {
+			call->enabled = 0;
+			call->unregfunc();
+		}
+		call++;
+	}
+}
+
+static void ftrace_event_enable_disable(struct ftrace_event_call *call,
+					int enable)
+{
+
+	switch (enable) {
+	case 0:
+		if (call->enabled) {
+			call->enabled = 0;
+			call->unregfunc();
+		}
+		break;
+	case 1:
+		if (!call->enabled) {
+			call->enabled = 1;
+			call->regfunc();
+		}
+		break;
+	}
+}
+
+static int ftrace_set_clr_event(char *buf, int set)
+{
+	struct ftrace_event_call *call = __start_ftrace_events;
+	char *event = NULL, *sub = NULL, *match;
+	int ret = -EINVAL;
+
+	/*
+	 * The buf format can be <subsystem>:<event-name>
+	 *  *:<event-name> means any event by that name.
+	 *  :<event-name> is the same.
+	 *
+	 *  <subsystem>:* means all events in that subsystem
+	 *  <subsystem>: means the same.
+	 *
+	 *  <name> (no ':') means all events in a subsystem with
+	 *  the name <name> or any event that matches <name>
+	 */
+
+	match = strsep(&buf, ":");
+	if (buf) {
+		sub = match;
+		event = buf;
+		match = NULL;
+
+		if (!strlen(sub) || strcmp(sub, "*") == 0)
+			sub = NULL;
+		if (!strlen(event) || strcmp(event, "*") == 0)
+			event = NULL;
+	}
+
+	mutex_lock(&event_mutex);
+	for_each_event(call) {
+
+		if (!call->name || !call->regfunc)
+			continue;
+
+		if (match &&
+		    strcmp(match, call->name) != 0 &&
+		    strcmp(match, call->system) != 0)
+			continue;
+
+		if (sub && strcmp(sub, call->system) != 0)
+			continue;
+
+		if (event && strcmp(event, call->name) != 0)
+			continue;
+
+		ftrace_event_enable_disable(call, set);
+
+		ret = 0;
+	}
+	mutex_unlock(&event_mutex);
+
+	return ret;
+}
+
+/* 128 should be much more than enough */
+#define EVENT_BUF_SIZE		127
+
+static ssize_t
+ftrace_event_write(struct file *file, const char __user *ubuf,
+		   size_t cnt, loff_t *ppos)
+{
+	size_t read = 0;
+	int i, set = 1;
+	ssize_t ret;
+	char *buf;
+	char ch;
+
+	if (!cnt || cnt < 0)
+		return 0;
+
+	ret = tracing_update_buffers();
+	if (ret < 0)
+		return ret;
+
+	ret = get_user(ch, ubuf++);
+	if (ret)
+		return ret;
+	read++;
+	cnt--;
+
+	/* skip white space */
+	while (cnt && isspace(ch)) {
+		ret = get_user(ch, ubuf++);
+		if (ret)
+			return ret;
+		read++;
+		cnt--;
+	}
+
+	/* Only white space found? */
+	if (isspace(ch)) {
+		file->f_pos += read;
+		ret = read;
+		return ret;
+	}
+
+	buf = kmalloc(EVENT_BUF_SIZE+1, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	if (cnt > EVENT_BUF_SIZE)
+		cnt = EVENT_BUF_SIZE;
+
+	i = 0;
+	while (cnt && !isspace(ch)) {
+		if (!i && ch == '!')
+			set = 0;
+		else
+			buf[i++] = ch;
+
+		ret = get_user(ch, ubuf++);
+		if (ret)
+			goto out_free;
+		read++;
+		cnt--;
+	}
+	buf[i] = 0;
+
+	file->f_pos += read;
+
+	ret = ftrace_set_clr_event(buf, set);
+	if (ret)
+		goto out_free;
+
+	ret = read;
+
+ out_free:
+	kfree(buf);
+
+	return ret;
+}
+
+static void *
+t_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	struct ftrace_event_call *call = m->private;
+	struct ftrace_event_call *next = call;
+
+	(*pos)++;
+
+	for (;;) {
+		if ((unsigned long)call >= (unsigned long)__stop_ftrace_events)
+			return NULL;
+
+		/*
+		 * The ftrace subsystem is for showing formats only.
+		 * They can not be enabled or disabled via the event files.
+		 */
+		if (call->regfunc)
+			break;
+
+		call++;
+		next = call;
+	}
+
+	m->private = ++next;
+
+	return call;
+}
+
+static void *t_start(struct seq_file *m, loff_t *pos)
+{
+	return t_next(m, NULL, pos);
+}
+
+static void *
+s_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	struct ftrace_event_call *call = m->private;
+	struct ftrace_event_call *next;
+
+	(*pos)++;
+
+ retry:
+	if ((unsigned long)call >= (unsigned long)__stop_ftrace_events)
+		return NULL;
+
+	if (!call->enabled) {
+		call++;
+		goto retry;
+	}
+
+	next = call;
+	m->private = ++next;
+
+	return call;
+}
+
+static void *s_start(struct seq_file *m, loff_t *pos)
+{
+	return s_next(m, NULL, pos);
+}
+
+static int t_show(struct seq_file *m, void *v)
+{
+	struct ftrace_event_call *call = v;
+
+	if (strcmp(call->system, TRACE_SYSTEM) != 0)
+		seq_printf(m, "%s:", call->system);
+	seq_printf(m, "%s\n", call->name);
+
+	return 0;
+}
+
+static void t_stop(struct seq_file *m, void *p)
+{
+}
+
+static int
+ftrace_event_seq_open(struct inode *inode, struct file *file)
+{
+	int ret;
+	const struct seq_operations *seq_ops;
+
+	if ((file->f_mode & FMODE_WRITE) &&
+	    !(file->f_flags & O_APPEND))
+		ftrace_clear_events();
+
+	seq_ops = inode->i_private;
+	ret = seq_open(file, seq_ops);
+	if (!ret) {
+		struct seq_file *m = file->private_data;
+
+		m->private = __start_ftrace_events;
+	}
+	return ret;
+}
+
+static ssize_t
+event_enable_read(struct file *filp, char __user *ubuf, size_t cnt,
+		  loff_t *ppos)
+{
+	struct ftrace_event_call *call = filp->private_data;
+	char *buf;
+
+	if (call->enabled)
+		buf = "1\n";
+	else
+		buf = "0\n";
+
+	return simple_read_from_buffer(ubuf, cnt, ppos, buf, 2);
+}
+
+static ssize_t
+event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
+		   loff_t *ppos)
+{
+	struct ftrace_event_call *call = filp->private_data;
+	char buf[64];
+	unsigned long val;
+	int ret;
+
+	if (cnt >= sizeof(buf))
+		return -EINVAL;
+
+	if (copy_from_user(&buf, ubuf, cnt))
+		return -EFAULT;
+
+	buf[cnt] = 0;
+
+	ret = strict_strtoul(buf, 10, &val);
+	if (ret < 0)
+		return ret;
+
+	ret = tracing_update_buffers();
+	if (ret < 0)
+		return ret;
+
+	switch (val) {
+	case 0:
+	case 1:
+		mutex_lock(&event_mutex);
+		ftrace_event_enable_disable(call, val);
+		mutex_unlock(&event_mutex);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	*ppos += cnt;
+
+	return cnt;
+}
+
+#undef FIELD
+#define FIELD(type, name)						\
+	#type, "common_" #name, offsetof(typeof(field), name),		\
+		sizeof(field.name)
+
+static int trace_write_header(struct trace_seq *s)
+{
+	struct trace_entry field;
+
+	/* struct trace_entry */
+	return trace_seq_printf(s,
+				"\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
+				"\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
+				"\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
+				"\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
+				"\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
+				"\n",
+				FIELD(unsigned char, type),
+				FIELD(unsigned char, flags),
+				FIELD(unsigned char, preempt_count),
+				FIELD(int, pid),
+				FIELD(int, tgid));
+}
+
+static ssize_t
+event_format_read(struct file *filp, char __user *ubuf, size_t cnt,
+		  loff_t *ppos)
+{
+	struct ftrace_event_call *call = filp->private_data;
+	struct trace_seq *s;
+	char *buf;
+	int r;
+
+	if (*ppos)
+		return 0;
+
+	s = kmalloc(sizeof(*s), GFP_KERNEL);
+	if (!s)
+		return -ENOMEM;
+
+	trace_seq_init(s);
+
+	/* If any of the first writes fail, so will the show_format. */
+
+	trace_seq_printf(s, "name: %s\n", call->name);
+	trace_seq_printf(s, "ID: %d\n", call->id);
+	trace_seq_printf(s, "format:\n");
+	trace_write_header(s);
+
+	r = call->show_format(s);
+	if (!r) {
+		/*
+		 * ug!  The format output is bigger than a PAGE!!
+		 */
+		buf = "FORMAT TOO BIG\n";
+		r = simple_read_from_buffer(ubuf, cnt, ppos,
+					      buf, strlen(buf));
+		goto out;
+	}
+
+	r = simple_read_from_buffer(ubuf, cnt, ppos,
+				    s->buffer, s->len);
+ out:
+	kfree(s);
+	return r;
+}
+
+static ssize_t
+event_id_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+	struct ftrace_event_call *call = filp->private_data;
+	struct trace_seq *s;
+	int r;
+
+	if (*ppos)
+		return 0;
+
+	s = kmalloc(sizeof(*s), GFP_KERNEL);
+	if (!s)
+		return -ENOMEM;
+
+	trace_seq_init(s);
+	trace_seq_printf(s, "%d\n", call->id);
+
+	r = simple_read_from_buffer(ubuf, cnt, ppos,
+				    s->buffer, s->len);
+	kfree(s);
+	return r;
+}
+
+static ssize_t
+event_filter_read(struct file *filp, char __user *ubuf, size_t cnt,
+		  loff_t *ppos)
+{
+	struct ftrace_event_call *call = filp->private_data;
+	struct trace_seq *s;
+	int r;
+
+	if (*ppos)
+		return 0;
+
+	s = kmalloc(sizeof(*s), GFP_KERNEL);
+	if (!s)
+		return -ENOMEM;
+
+	trace_seq_init(s);
+
+	filter_print_preds(call->preds, s);
+	r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len);
+
+	kfree(s);
+
+	return r;
+}
+
+static ssize_t
+event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
+		   loff_t *ppos)
+{
+	struct ftrace_event_call *call = filp->private_data;
+	char buf[64], *pbuf = buf;
+	struct filter_pred *pred;
+	int err;
+
+	if (cnt >= sizeof(buf))
+		return -EINVAL;
+
+	if (copy_from_user(&buf, ubuf, cnt))
+		return -EFAULT;
+
+	pred = kzalloc(sizeof(*pred), GFP_KERNEL);
+	if (!pred)
+		return -ENOMEM;
+
+	err = filter_parse(&pbuf, pred);
+	if (err < 0) {
+		filter_free_pred(pred);
+		return err;
+	}
+
+	if (pred->clear) {
+		filter_free_preds(call);
+		filter_free_pred(pred);
+		return cnt;
+	}
+
+	if (filter_add_pred(call, pred)) {
+		filter_free_pred(pred);
+		return -EINVAL;
+	}
+
+	*ppos += cnt;
+
+	return cnt;
+}
+
+static ssize_t
+subsystem_filter_read(struct file *filp, char __user *ubuf, size_t cnt,
+		      loff_t *ppos)
+{
+	struct event_subsystem *system = filp->private_data;
+	struct trace_seq *s;
+	int r;
+
+	if (*ppos)
+		return 0;
+
+	s = kmalloc(sizeof(*s), GFP_KERNEL);
+	if (!s)
+		return -ENOMEM;
+
+	trace_seq_init(s);
+
+	filter_print_preds(system->preds, s);
+	r = simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, s->len);
+
+	kfree(s);
+
+	return r;
+}
+
+static ssize_t
+subsystem_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
+		       loff_t *ppos)
+{
+	struct event_subsystem *system = filp->private_data;
+	char buf[64], *pbuf = buf;
+	struct filter_pred *pred;
+	int err;
+
+	if (cnt >= sizeof(buf))
+		return -EINVAL;
+
+	if (copy_from_user(&buf, ubuf, cnt))
+		return -EFAULT;
+
+	pred = kzalloc(sizeof(*pred), GFP_KERNEL);
+	if (!pred)
+		return -ENOMEM;
+
+	err = filter_parse(&pbuf, pred);
+	if (err < 0) {
+		filter_free_pred(pred);
+		return err;
+	}
+
+	if (pred->clear) {
+		filter_free_subsystem_preds(system);
+		filter_free_pred(pred);
+		return cnt;
+	}
+
+	if (filter_add_subsystem_pred(system, pred)) {
+		filter_free_subsystem_preds(system);
+		filter_free_pred(pred);
+		return -EINVAL;
+	}
+
+	*ppos += cnt;
+
+	return cnt;
+}
+
+static const struct seq_operations show_event_seq_ops = {
+	.start = t_start,
+	.next = t_next,
+	.show = t_show,
+	.stop = t_stop,
+};
+
+static const struct seq_operations show_set_event_seq_ops = {
+	.start = s_start,
+	.next = s_next,
+	.show = t_show,
+	.stop = t_stop,
+};
+
+static const struct file_operations ftrace_avail_fops = {
+	.open = ftrace_event_seq_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = seq_release,
+};
+
+static const struct file_operations ftrace_set_event_fops = {
+	.open = ftrace_event_seq_open,
+	.read = seq_read,
+	.write = ftrace_event_write,
+	.llseek = seq_lseek,
+	.release = seq_release,
+};
+
+static const struct file_operations ftrace_enable_fops = {
+	.open = tracing_open_generic,
+	.read = event_enable_read,
+	.write = event_enable_write,
+};
+
+static const struct file_operations ftrace_event_format_fops = {
+	.open = tracing_open_generic,
+	.read = event_format_read,
+};
+
+static const struct file_operations ftrace_event_id_fops = {
+	.open = tracing_open_generic,
+	.read = event_id_read,
+};
+
+static const struct file_operations ftrace_event_filter_fops = {
+	.open = tracing_open_generic,
+	.read = event_filter_read,
+	.write = event_filter_write,
+};
+
+static const struct file_operations ftrace_subsystem_filter_fops = {
+	.open = tracing_open_generic,
+	.read = subsystem_filter_read,
+	.write = subsystem_filter_write,
+};
+
+static struct dentry *event_trace_events_dir(void)
+{
+	static struct dentry *d_tracer;
+	static struct dentry *d_events;
+
+	if (d_events)
+		return d_events;
+
+	d_tracer = tracing_init_dentry();
+	if (!d_tracer)
+		return NULL;
+
+	d_events = debugfs_create_dir("events", d_tracer);
+	if (!d_events)
+		pr_warning("Could not create debugfs "
+			   "'events' directory\n");
+
+	return d_events;
+}
+
+static LIST_HEAD(event_subsystems);
+
+static struct dentry *
+event_subsystem_dir(const char *name, struct dentry *d_events)
+{
+	struct event_subsystem *system;
+
+	/* First see if we did not already create this dir */
+	list_for_each_entry(system, &event_subsystems, list) {
+		if (strcmp(system->name, name) == 0)
+			return system->entry;
+	}
+
+	/* need to create new entry */
+	system = kmalloc(sizeof(*system), GFP_KERNEL);
+	if (!system) {
+		pr_warning("No memory to create event subsystem %s\n",
+			   name);
+		return d_events;
+	}
+
+	system->entry = debugfs_create_dir(name, d_events);
+	if (!system->entry) {
+		pr_warning("Could not create event subsystem %s\n",
+			   name);
+		kfree(system);
+		return d_events;
+	}
+
+	system->name = name;
+	list_add(&system->list, &event_subsystems);
+
+	system->preds = NULL;
+
+	return system->entry;
+}
+
+static int
+event_create_dir(struct ftrace_event_call *call, struct dentry *d_events)
+{
+	struct dentry *entry;
+	int ret;
+
+	/*
+	 * If the trace point header did not define TRACE_SYSTEM
+	 * then the system would be called "TRACE_SYSTEM".
+	 */
+	if (strcmp(call->system, "TRACE_SYSTEM") != 0)
+		d_events = event_subsystem_dir(call->system, d_events);
+
+	if (call->raw_init) {
+		ret = call->raw_init();
+		if (ret < 0) {
+			pr_warning("Could not initialize trace point"
+				   " events/%s\n", call->name);
+			return ret;
+		}
+	}
+
+	call->dir = debugfs_create_dir(call->name, d_events);
+	if (!call->dir) {
+		pr_warning("Could not create debugfs "
+			   "'%s' directory\n", call->name);
+		return -1;
+	}
+
+	if (call->regfunc) {
+		entry = debugfs_create_file("enable", 0644, call->dir, call,
+					    &ftrace_enable_fops);
+		if (!entry)
+			pr_warning("Could not create debugfs "
+				   "'%s/enable' entry\n", call->name);
+	}
+
+	if (call->id) {
+		entry = debugfs_create_file("id", 0444, call->dir, call,
+				&ftrace_event_id_fops);
+		if (!entry)
+			pr_warning("Could not create debugfs '%s/id' entry\n",
+					call->name);
+	}
+
+	if (call->define_fields) {
+		ret = call->define_fields();
+		if (ret < 0) {
+			pr_warning("Could not initialize trace point"
+				   " events/%s\n", call->name);
+			return ret;
+		}
+		entry = debugfs_create_file("filter", 0644, call->dir, call,
+					    &ftrace_event_filter_fops);
+		if (!entry)
+			pr_warning("Could not create debugfs "
+				   "'%s/filter' entry\n", call->name);
+	}
+
+	/* A trace may not want to export its format */
+	if (!call->show_format)
+		return 0;
+
+	entry = debugfs_create_file("format", 0444, call->dir, call,
+				    &ftrace_event_format_fops);
+	if (!entry)
+		pr_warning("Could not create debugfs "
+			   "'%s/format' entry\n", call->name);
+
+	return 0;
+}
+
+static __init int event_trace_init(void)
+{
+	struct ftrace_event_call *call = __start_ftrace_events;
+	struct dentry *d_tracer;
+	struct dentry *entry;
+	struct dentry *d_events;
+
+	d_tracer = tracing_init_dentry();
+	if (!d_tracer)
+		return 0;
+
+	entry = debugfs_create_file("available_events", 0444, d_tracer,
+				    (void *)&show_event_seq_ops,
+				    &ftrace_avail_fops);
+	if (!entry)
+		pr_warning("Could not create debugfs "
+			   "'available_events' entry\n");
+
+	entry = debugfs_create_file("set_event", 0644, d_tracer,
+				    (void *)&show_set_event_seq_ops,
+				    &ftrace_set_event_fops);
+	if (!entry)
+		pr_warning("Could not create debugfs "
+			   "'set_event' entry\n");
+
+	d_events = event_trace_events_dir();
+	if (!d_events)
+		return 0;
+
+	for_each_event(call) {
+		/* The linker may leave blanks */
+		if (!call->name)
+			continue;
+		event_create_dir(call, d_events);
+	}
+
+	return 0;
+}
+fs_initcall(event_trace_init);
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
new file mode 100644
index 0000000..026be41
--- /dev/null
+++ b/kernel/trace/trace_events_filter.c
@@ -0,0 +1,427 @@
+/*
+ * trace_events_filter - generic event filtering
+ *
+ * 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.
+ *
+ * Copyright (C) 2009 Tom Zanussi <tzanussi@gmail.com>
+ */
+
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+#include <linux/module.h>
+#include <linux/ctype.h>
+
+#include "trace.h"
+#include "trace_output.h"
+
+static int filter_pred_64(struct filter_pred *pred, void *event)
+{
+	u64 *addr = (u64 *)(event + pred->offset);
+	u64 val = (u64)pred->val;
+	int match;
+
+	match = (val == *addr) ^ pred->not;
+
+	return match;
+}
+
+static int filter_pred_32(struct filter_pred *pred, void *event)
+{
+	u32 *addr = (u32 *)(event + pred->offset);
+	u32 val = (u32)pred->val;
+	int match;
+
+	match = (val == *addr) ^ pred->not;
+
+	return match;
+}
+
+static int filter_pred_16(struct filter_pred *pred, void *event)
+{
+	u16 *addr = (u16 *)(event + pred->offset);
+	u16 val = (u16)pred->val;
+	int match;
+
+	match = (val == *addr) ^ pred->not;
+
+	return match;
+}
+
+static int filter_pred_8(struct filter_pred *pred, void *event)
+{
+	u8 *addr = (u8 *)(event + pred->offset);
+	u8 val = (u8)pred->val;
+	int match;
+
+	match = (val == *addr) ^ pred->not;
+
+	return match;
+}
+
+static int filter_pred_string(struct filter_pred *pred, void *event)
+{
+	char *addr = (char *)(event + pred->offset);
+	int cmp, match;
+
+	cmp = strncmp(addr, pred->str_val, pred->str_len);
+
+	match = (!cmp) ^ pred->not;
+
+	return match;
+}
+
+/* return 1 if event matches, 0 otherwise (discard) */
+int filter_match_preds(struct ftrace_event_call *call, void *rec)
+{
+	int i, matched, and_failed = 0;
+	struct filter_pred *pred;
+
+	for (i = 0; i < MAX_FILTER_PRED; i++) {
+		if (call->preds[i]) {
+			pred = call->preds[i];
+			if (and_failed && !pred->or)
+				continue;
+			matched = pred->fn(pred, rec);
+			if (!matched && !pred->or) {
+				and_failed = 1;
+				continue;
+			} else if (matched && pred->or)
+				return 1;
+		} else
+			break;
+	}
+
+	if (and_failed)
+		return 0;
+
+	return 1;
+}
+
+void filter_print_preds(struct filter_pred **preds, struct trace_seq *s)
+{
+	char *field_name;
+	struct filter_pred *pred;
+	int i;
+
+	if (!preds) {
+		trace_seq_printf(s, "none\n");
+		return;
+	}
+
+	for (i = 0; i < MAX_FILTER_PRED; i++) {
+		if (preds[i]) {
+			pred = preds[i];
+			field_name = pred->field_name;
+			if (i)
+				trace_seq_printf(s, pred->or ? "|| " : "&& ");
+			trace_seq_printf(s, "%s ", field_name);
+			trace_seq_printf(s, pred->not ? "!= " : "== ");
+			if (pred->str_val)
+				trace_seq_printf(s, "%s\n", pred->str_val);
+			else
+				trace_seq_printf(s, "%llu\n", pred->val);
+		} else
+			break;
+	}
+}
+
+static struct ftrace_event_field *
+find_event_field(struct ftrace_event_call *call, char *name)
+{
+	struct ftrace_event_field *field;
+
+	list_for_each_entry(field, &call->fields, link) {
+		if (!strcmp(field->name, name))
+			return field;
+	}
+
+	return NULL;
+}
+
+void filter_free_pred(struct filter_pred *pred)
+{
+	if (!pred)
+		return;
+
+	kfree(pred->field_name);
+	kfree(pred->str_val);
+	kfree(pred);
+}
+
+void filter_free_preds(struct ftrace_event_call *call)
+{
+	int i;
+
+	if (call->preds) {
+		for (i = 0; i < MAX_FILTER_PRED; i++)
+			filter_free_pred(call->preds[i]);
+		kfree(call->preds);
+		call->preds = NULL;
+	}
+}
+
+void filter_free_subsystem_preds(struct event_subsystem *system)
+{
+	struct ftrace_event_call *call = __start_ftrace_events;
+	int i;
+
+	if (system->preds) {
+		for (i = 0; i < MAX_FILTER_PRED; i++)
+			filter_free_pred(system->preds[i]);
+		kfree(system->preds);
+		system->preds = NULL;
+	}
+
+	events_for_each(call) {
+		if (!call->name || !call->regfunc)
+			continue;
+
+		if (!strcmp(call->system, system->name))
+			filter_free_preds(call);
+	}
+}
+
+static int __filter_add_pred(struct ftrace_event_call *call,
+			     struct filter_pred *pred)
+{
+	int i;
+
+	if (call->preds && !pred->compound)
+		filter_free_preds(call);
+
+	if (!call->preds) {
+		call->preds = kzalloc(MAX_FILTER_PRED * sizeof(pred),
+				      GFP_KERNEL);
+		if (!call->preds)
+			return -ENOMEM;
+	}
+
+	for (i = 0; i < MAX_FILTER_PRED; i++) {
+		if (!call->preds[i]) {
+			call->preds[i] = pred;
+			return 0;
+		}
+	}
+
+	return -ENOMEM;
+}
+
+static int is_string_field(const char *type)
+{
+	if (strchr(type, '[') && strstr(type, "char"))
+		return 1;
+
+	return 0;
+}
+
+int filter_add_pred(struct ftrace_event_call *call, struct filter_pred *pred)
+{
+	struct ftrace_event_field *field;
+
+	field = find_event_field(call, pred->field_name);
+	if (!field)
+		return -EINVAL;
+
+	pred->offset = field->offset;
+
+	if (is_string_field(field->type)) {
+		if (!pred->str_val)
+			return -EINVAL;
+		pred->fn = filter_pred_string;
+		pred->str_len = field->size;
+		return __filter_add_pred(call, pred);
+	} else {
+		if (pred->str_val)
+			return -EINVAL;
+	}
+
+	switch (field->size) {
+	case 8:
+		pred->fn = filter_pred_64;
+		break;
+	case 4:
+		pred->fn = filter_pred_32;
+		break;
+	case 2:
+		pred->fn = filter_pred_16;
+		break;
+	case 1:
+		pred->fn = filter_pred_8;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return __filter_add_pred(call, pred);
+}
+
+static struct filter_pred *copy_pred(struct filter_pred *pred)
+{
+	struct filter_pred *new_pred = kmalloc(sizeof(*pred), GFP_KERNEL);
+	if (!new_pred)
+		return NULL;
+
+	memcpy(new_pred, pred, sizeof(*pred));
+
+	if (pred->field_name) {
+		new_pred->field_name = kstrdup(pred->field_name, GFP_KERNEL);
+		if (!new_pred->field_name) {
+			kfree(new_pred);
+			return NULL;
+		}
+	}
+
+	if (pred->str_val) {
+		new_pred->str_val = kstrdup(pred->str_val, GFP_KERNEL);
+		if (!new_pred->str_val) {
+			filter_free_pred(new_pred);
+			return NULL;
+		}
+	}
+
+	return new_pred;
+}
+
+int filter_add_subsystem_pred(struct event_subsystem *system,
+			      struct filter_pred *pred)
+{
+	struct ftrace_event_call *call = __start_ftrace_events;
+	struct filter_pred *event_pred;
+	int i;
+
+	if (system->preds && !pred->compound)
+		filter_free_subsystem_preds(system);
+
+	if (!system->preds) {
+		system->preds = kzalloc(MAX_FILTER_PRED * sizeof(pred),
+					GFP_KERNEL);
+		if (!system->preds)
+			return -ENOMEM;
+	}
+
+	for (i = 0; i < MAX_FILTER_PRED; i++) {
+		if (!system->preds[i]) {
+			system->preds[i] = pred;
+			break;
+		}
+	}
+
+	if (i == MAX_FILTER_PRED)
+		return -EINVAL;
+
+	events_for_each(call) {
+		int err;
+
+		if (!call->name || !call->regfunc)
+			continue;
+
+		if (strcmp(call->system, system->name))
+			continue;
+
+		if (!find_event_field(call, pred->field_name))
+			continue;
+
+		event_pred = copy_pred(pred);
+		if (!event_pred)
+			goto oom;
+
+		err = filter_add_pred(call, event_pred);
+		if (err)
+			filter_free_pred(event_pred);
+		if (err == -ENOMEM)
+			goto oom;
+	}
+
+	return 0;
+
+oom:
+	system->preds[i] = NULL;
+	return -ENOMEM;
+}
+
+int filter_parse(char **pbuf, struct filter_pred *pred)
+{
+	char *tmp, *tok, *val_str = NULL;
+	int tok_n = 0;
+
+	/* field ==/!= number, or/and field ==/!= number, number */
+	while ((tok = strsep(pbuf, " \n"))) {
+		if (tok_n == 0) {
+			if (!strcmp(tok, "0")) {
+				pred->clear = 1;
+				return 0;
+			} else if (!strcmp(tok, "&&")) {
+				pred->or = 0;
+				pred->compound = 1;
+			} else if (!strcmp(tok, "||")) {
+				pred->or = 1;
+				pred->compound = 1;
+			} else
+				pred->field_name = tok;
+			tok_n = 1;
+			continue;
+		}
+		if (tok_n == 1) {
+			if (!pred->field_name)
+				pred->field_name = tok;
+			else if (!strcmp(tok, "!="))
+				pred->not = 1;
+			else if (!strcmp(tok, "=="))
+				pred->not = 0;
+			else {
+				pred->field_name = NULL;
+				return -EINVAL;
+			}
+			tok_n = 2;
+			continue;
+		}
+		if (tok_n == 2) {
+			if (pred->compound) {
+				if (!strcmp(tok, "!="))
+					pred->not = 1;
+				else if (!strcmp(tok, "=="))
+					pred->not = 0;
+				else {
+					pred->field_name = NULL;
+					return -EINVAL;
+				}
+			} else {
+				val_str = tok;
+				break; /* done */
+			}
+			tok_n = 3;
+			continue;
+		}
+		if (tok_n == 3) {
+			val_str = tok;
+			break; /* done */
+		}
+	}
+
+	pred->field_name = kstrdup(pred->field_name, GFP_KERNEL);
+	if (!pred->field_name)
+		return -ENOMEM;
+
+	pred->val = simple_strtoull(val_str, &tmp, 10);
+	if (tmp == val_str) {
+		pred->str_val = kstrdup(val_str, GFP_KERNEL);
+		if (!pred->str_val)
+			return -ENOMEM;
+	}
+
+	return 0;
+}
+
+
diff --git a/kernel/trace/trace_events_stage_1.h b/kernel/trace/trace_events_stage_1.h
new file mode 100644
index 0000000..38985f9
--- /dev/null
+++ b/kernel/trace/trace_events_stage_1.h
@@ -0,0 +1,39 @@
+/*
+ * Stage 1 of the trace events.
+ *
+ * Override the macros in <trace/trace_event_types.h> to include the following:
+ *
+ * struct ftrace_raw_<call> {
+ *	struct trace_entry		ent;
+ *	<type>				<item>;
+ *	<type2>				<item2>[<len>];
+ *	[...]
+ * };
+ *
+ * The <type> <item> is created by the __field(type, item) macro or
+ * the __array(type2, item2, len) macro.
+ * We simply do "type item;", and that will create the fields
+ * in the structure.
+ */
+
+#undef TRACE_FORMAT
+#define TRACE_FORMAT(call, proto, args, fmt)
+
+#undef __array
+#define __array(type, item, len)	type	item[len];
+
+#undef __field
+#define __field(type, item)		type	item;
+
+#undef TP_STRUCT__entry
+#define TP_STRUCT__entry(args...) args
+
+#undef TRACE_EVENT
+#define TRACE_EVENT(name, proto, args, tstruct, assign, print)	\
+	struct ftrace_raw_##name {				\
+		struct trace_entry	ent;			\
+		tstruct						\
+	};							\
+	static struct ftrace_event_call event_##name
+
+#include <trace/trace_event_types.h>
diff --git a/kernel/trace/trace_events_stage_2.h b/kernel/trace/trace_events_stage_2.h
new file mode 100644
index 0000000..30743f7
--- /dev/null
+++ b/kernel/trace/trace_events_stage_2.h
@@ -0,0 +1,176 @@
+/*
+ * Stage 2 of the trace events.
+ *
+ * Override the macros in <trace/trace_event_types.h> to include the following:
+ *
+ * enum print_line_t
+ * ftrace_raw_output_<call>(struct trace_iterator *iter, int flags)
+ * {
+ *	struct trace_seq *s = &iter->seq;
+ *	struct ftrace_raw_<call> *field; <-- defined in stage 1
+ *	struct trace_entry *entry;
+ *	int ret;
+ *
+ *	entry = iter->ent;
+ *
+ *	if (entry->type != event_<call>.id) {
+ *		WARN_ON_ONCE(1);
+ *		return TRACE_TYPE_UNHANDLED;
+ *	}
+ *
+ *	field = (typeof(field))entry;
+ *
+ *	ret = trace_seq_printf(s, <TP_printk> "\n");
+ *	if (!ret)
+ *		return TRACE_TYPE_PARTIAL_LINE;
+ *
+ *	return TRACE_TYPE_HANDLED;
+ * }
+ *
+ * This is the method used to print the raw event to the trace
+ * output format. Note, this is not needed if the data is read
+ * in binary.
+ */
+
+#undef __entry
+#define __entry field
+
+#undef TP_printk
+#define TP_printk(fmt, args...) fmt "\n", args
+
+#undef TRACE_EVENT
+#define TRACE_EVENT(call, proto, args, tstruct, assign, print)		\
+enum print_line_t							\
+ftrace_raw_output_##call(struct trace_iterator *iter, int flags)	\
+{									\
+	struct trace_seq *s = &iter->seq;				\
+	struct ftrace_raw_##call *field;				\
+	struct trace_entry *entry;					\
+	int ret;							\
+									\
+	entry = iter->ent;						\
+									\
+	if (entry->type != event_##call.id) {				\
+		WARN_ON_ONCE(1);					\
+		return TRACE_TYPE_UNHANDLED;				\
+	}								\
+									\
+	field = (typeof(field))entry;					\
+									\
+	ret = trace_seq_printf(s, #call ": " print);			\
+	if (!ret)							\
+		return TRACE_TYPE_PARTIAL_LINE;				\
+									\
+	return TRACE_TYPE_HANDLED;					\
+}
+	
+#include <trace/trace_event_types.h>
+
+/*
+ * Setup the showing format of trace point.
+ *
+ * int
+ * ftrace_format_##call(struct trace_seq *s)
+ * {
+ *	struct ftrace_raw_##call field;
+ *	int ret;
+ *
+ *	ret = trace_seq_printf(s, #type " " #item ";"
+ *			       " offset:%u; size:%u;\n",
+ *			       offsetof(struct ftrace_raw_##call, item),
+ *			       sizeof(field.type));
+ *
+ * }
+ */
+
+#undef TP_STRUCT__entry
+#define TP_STRUCT__entry(args...) args
+
+#undef __field
+#define __field(type, item)					\
+	ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t"	\
+			       "offset:%u;\tsize:%u;\n",		\
+			       (unsigned int)offsetof(typeof(field), item), \
+			       (unsigned int)sizeof(field.item));	\
+	if (!ret)							\
+		return 0;
+
+#undef __array
+#define __array(type, item, len)						\
+	ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t"	\
+			       "offset:%u;\tsize:%u;\n",		\
+			       (unsigned int)offsetof(typeof(field), item), \
+			       (unsigned int)sizeof(field.item));	\
+	if (!ret)							\
+		return 0;
+
+#undef __entry
+#define __entry "REC"
+
+#undef TP_printk
+#define TP_printk(fmt, args...) "%s, %s\n", #fmt, #args
+
+#undef TP_fast_assign
+#define TP_fast_assign(args...) args
+
+#undef TRACE_EVENT
+#define TRACE_EVENT(call, proto, args, tstruct, func, print)		\
+static int								\
+ftrace_format_##call(struct trace_seq *s)				\
+{									\
+	struct ftrace_raw_##call field;					\
+	int ret;							\
+									\
+	tstruct;							\
+									\
+	trace_seq_printf(s, "\nprint fmt: " print);			\
+									\
+	return ret;							\
+}
+
+#include <trace/trace_event_types.h>
+
+#undef __field
+#define __field(type, item)						\
+	ret = trace_define_field(event_call, #type, #item,		\
+				 offsetof(typeof(field), item),		\
+				 sizeof(field.item));			\
+	if (ret)							\
+		return ret;
+
+#undef __array
+#define __array(type, item, len)					\
+	ret = trace_define_field(event_call, #type "[" #len "]", #item,	\
+				 offsetof(typeof(field), item),		\
+				 sizeof(field.item));			\
+	if (ret)							\
+		return ret;
+
+#define __common_field(type, item)					\
+	ret = trace_define_field(event_call, #type, "common_" #item,	\
+				 offsetof(typeof(field.ent), item),	\
+				 sizeof(field.ent.item));		\
+	if (ret)							\
+		return ret;
+
+#undef TRACE_EVENT
+#define TRACE_EVENT(call, proto, args, tstruct, func, print)		\
+int									\
+ftrace_define_fields_##call(void)					\
+{									\
+	struct ftrace_raw_##call field;					\
+	struct ftrace_event_call *event_call = &event_##call;		\
+	int ret;							\
+									\
+	__common_field(unsigned char, type);				\
+	__common_field(unsigned char, flags);				\
+	__common_field(unsigned char, preempt_count);			\
+	__common_field(int, pid);					\
+	__common_field(int, tgid);					\
+									\
+	tstruct;							\
+									\
+	return ret;							\
+}
+
+#include <trace/trace_event_types.h>
diff --git a/kernel/trace/trace_events_stage_3.h b/kernel/trace/trace_events_stage_3.h
new file mode 100644
index 0000000..9d2fa78
--- /dev/null
+++ b/kernel/trace/trace_events_stage_3.h
@@ -0,0 +1,281 @@
+/*
+ * Stage 3 of the trace events.
+ *
+ * Override the macros in <trace/trace_event_types.h> to include the following:
+ *
+ * static void ftrace_event_<call>(proto)
+ * {
+ *	event_trace_printk(_RET_IP_, "<call>: " <fmt>);
+ * }
+ *
+ * static int ftrace_reg_event_<call>(void)
+ * {
+ *	int ret;
+ *
+ *	ret = register_trace_<call>(ftrace_event_<call>);
+ *	if (!ret)
+ *		pr_info("event trace: Could not activate trace point "
+ *			"probe to  <call>");
+ *	return ret;
+ * }
+ *
+ * static void ftrace_unreg_event_<call>(void)
+ * {
+ *	unregister_trace_<call>(ftrace_event_<call>);
+ * }
+ *
+ * For those macros defined with TRACE_FORMAT:
+ *
+ * static struct ftrace_event_call __used
+ * __attribute__((__aligned__(4)))
+ * __attribute__((section("_ftrace_events"))) event_<call> = {
+ *	.name			= "<call>",
+ *	.regfunc		= ftrace_reg_event_<call>,
+ *	.unregfunc		= ftrace_unreg_event_<call>,
+ * }
+ *
+ *
+ * For those macros defined with TRACE_EVENT:
+ *
+ * static struct ftrace_event_call event_<call>;
+ *
+ * static void ftrace_raw_event_<call>(proto)
+ * {
+ *	struct ring_buffer_event *event;
+ *	struct ftrace_raw_<call> *entry; <-- defined in stage 1
+ *	unsigned long irq_flags;
+ *	int pc;
+ *
+ *	local_save_flags(irq_flags);
+ *	pc = preempt_count();
+ *
+ *	event = trace_current_buffer_lock_reserve(event_<call>.id,
+ *				  sizeof(struct ftrace_raw_<call>),
+ *				  irq_flags, pc);
+ *	if (!event)
+ *		return;
+ *	entry	= ring_buffer_event_data(event);
+ *
+ *	<assign>;  <-- Here we assign the entries by the __field and
+ *			__array macros.
+ *
+ *	trace_current_buffer_unlock_commit(event, irq_flags, pc);
+ * }
+ *
+ * static int ftrace_raw_reg_event_<call>(void)
+ * {
+ *	int ret;
+ *
+ *	ret = register_trace_<call>(ftrace_raw_event_<call>);
+ *	if (!ret)
+ *		pr_info("event trace: Could not activate trace point "
+ *			"probe to <call>");
+ *	return ret;
+ * }
+ *
+ * static void ftrace_unreg_event_<call>(void)
+ * {
+ *	unregister_trace_<call>(ftrace_raw_event_<call>);
+ * }
+ *
+ * static struct trace_event ftrace_event_type_<call> = {
+ *	.trace			= ftrace_raw_output_<call>, <-- stage 2
+ * };
+ *
+ * static int ftrace_raw_init_event_<call>(void)
+ * {
+ *	int id;
+ *
+ *	id = register_ftrace_event(&ftrace_event_type_<call>);
+ *	if (!id)
+ *		return -ENODEV;
+ *	event_<call>.id = id;
+ *	return 0;
+ * }
+ *
+ * static struct ftrace_event_call __used
+ * __attribute__((__aligned__(4)))
+ * __attribute__((section("_ftrace_events"))) event_<call> = {
+ *	.name			= "<call>",
+ *	.system			= "<system>",
+ *	.raw_init		= ftrace_raw_init_event_<call>,
+ *	.regfunc		= ftrace_reg_event_<call>,
+ *	.unregfunc		= ftrace_unreg_event_<call>,
+ *	.show_format		= ftrace_format_<call>,
+ * }
+ *
+ */
+
+#undef TP_FMT
+#define TP_FMT(fmt, args...)	fmt "\n", ##args
+
+#ifdef CONFIG_EVENT_PROFILE
+#define _TRACE_PROFILE(call, proto, args)				\
+static void ftrace_profile_##call(proto)				\
+{									\
+	extern void perf_tpcounter_event(int);				\
+	perf_tpcounter_event(event_##call.id);				\
+}									\
+									\
+static int ftrace_profile_enable_##call(struct ftrace_event_call *call) \
+{									\
+	int ret = 0;							\
+									\
+	if (!atomic_inc_return(&call->profile_count))			\
+		ret = register_trace_##call(ftrace_profile_##call);	\
+									\
+	return ret;							\
+}									\
+									\
+static void ftrace_profile_disable_##call(struct ftrace_event_call *call) \
+{									\
+	if (atomic_add_negative(-1, &call->profile_count))		\
+		unregister_trace_##call(ftrace_profile_##call);		\
+}
+
+#define _TRACE_PROFILE_INIT(call)					\
+	.profile_count = ATOMIC_INIT(-1),				\
+	.profile_enable = ftrace_profile_enable_##call,			\
+	.profile_disable = ftrace_profile_disable_##call,
+
+#else
+#define _TRACE_PROFILE(call, proto, args)
+#define _TRACE_PROFILE_INIT(call)
+#endif
+
+#define _TRACE_FORMAT(call, proto, args, fmt)				\
+static void ftrace_event_##call(proto)					\
+{									\
+	event_trace_printk(_RET_IP_, #call ": " fmt);			\
+}									\
+									\
+static int ftrace_reg_event_##call(void)				\
+{									\
+	int ret;							\
+									\
+	ret = register_trace_##call(ftrace_event_##call);		\
+	if (ret)							\
+		pr_info("event trace: Could not activate trace point "	\
+			"probe to " #call "\n");			\
+	return ret;							\
+}									\
+									\
+static void ftrace_unreg_event_##call(void)				\
+{									\
+	unregister_trace_##call(ftrace_event_##call);			\
+}									\
+									\
+static struct ftrace_event_call event_##call;				\
+									\
+static int ftrace_init_event_##call(void)				\
+{									\
+	int id;								\
+									\
+	id = register_ftrace_event(NULL);				\
+	if (!id)							\
+		return -ENODEV;						\
+	event_##call.id = id;						\
+	return 0;							\
+}
+
+#undef TRACE_FORMAT
+#define TRACE_FORMAT(call, proto, args, fmt)				\
+_TRACE_FORMAT(call, PARAMS(proto), PARAMS(args), PARAMS(fmt))		\
+_TRACE_PROFILE(call, PARAMS(proto), PARAMS(args))			\
+static struct ftrace_event_call __used					\
+__attribute__((__aligned__(4)))						\
+__attribute__((section("_ftrace_events"))) event_##call = {		\
+	.name			= #call,				\
+	.system			= __stringify(TRACE_SYSTEM),		\
+	.raw_init		= ftrace_init_event_##call,		\
+	.regfunc		= ftrace_reg_event_##call,		\
+	.unregfunc		= ftrace_unreg_event_##call,		\
+	_TRACE_PROFILE_INIT(call)					\
+}
+
+#undef __entry
+#define __entry entry
+
+#undef TRACE_EVENT
+#define TRACE_EVENT(call, proto, args, tstruct, assign, print)		\
+_TRACE_PROFILE(call, PARAMS(proto), PARAMS(args))			\
+									\
+static struct ftrace_event_call event_##call;				\
+									\
+static void ftrace_raw_event_##call(proto)				\
+{									\
+	struct ftrace_event_call *call = &event_##call;			\
+	struct ring_buffer_event *event;				\
+	struct ftrace_raw_##call *entry;				\
+	unsigned long irq_flags;					\
+	int pc;								\
+									\
+	local_save_flags(irq_flags);					\
+	pc = preempt_count();						\
+									\
+	event = trace_current_buffer_lock_reserve(event_##call.id,	\
+				  sizeof(struct ftrace_raw_##call),	\
+				  irq_flags, pc);			\
+	if (!event)							\
+		return;							\
+	entry	= ring_buffer_event_data(event);			\
+									\
+	assign;								\
+									\
+	if (call->preds && !filter_match_preds(call, entry))		\
+		ring_buffer_event_discard(event);			\
+									\
+	trace_nowake_buffer_unlock_commit(event, irq_flags, pc);	\
+									\
+}									\
+									\
+static int ftrace_raw_reg_event_##call(void)				\
+{									\
+	int ret;							\
+									\
+	ret = register_trace_##call(ftrace_raw_event_##call);		\
+	if (ret)							\
+		pr_info("event trace: Could not activate trace point "	\
+			"probe to " #call "\n");			\
+	return ret;							\
+}									\
+									\
+static void ftrace_raw_unreg_event_##call(void)				\
+{									\
+	unregister_trace_##call(ftrace_raw_event_##call);		\
+}									\
+									\
+static struct trace_event ftrace_event_type_##call = {			\
+	.trace			= ftrace_raw_output_##call,		\
+};									\
+									\
+static int ftrace_raw_init_event_##call(void)				\
+{									\
+	int id;								\
+									\
+	id = register_ftrace_event(&ftrace_event_type_##call);		\
+	if (!id)							\
+		return -ENODEV;						\
+	event_##call.id = id;						\
+	INIT_LIST_HEAD(&event_##call.fields);				\
+	return 0;							\
+}									\
+									\
+static struct ftrace_event_call __used					\
+__attribute__((__aligned__(4)))						\
+__attribute__((section("_ftrace_events"))) event_##call = {		\
+	.name			= #call,				\
+	.system			= __stringify(TRACE_SYSTEM),		\
+	.raw_init		= ftrace_raw_init_event_##call,		\
+	.regfunc		= ftrace_raw_reg_event_##call,		\
+	.unregfunc		= ftrace_raw_unreg_event_##call,	\
+	.show_format		= ftrace_format_##call,			\
+	.define_fields		= ftrace_define_fields_##call,		\
+	_TRACE_PROFILE_INIT(call)					\
+}
+
+#include <trace/trace_event_types.h>
+
+#undef _TRACE_PROFILE
+#undef _TRACE_PROFILE_INIT
+
diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c
new file mode 100644
index 0000000..4d9952d
--- /dev/null
+++ b/kernel/trace/trace_export.c
@@ -0,0 +1,102 @@
+/*
+ * trace_export.c - export basic ftrace utilities to user space
+ *
+ * Copyright (C) 2009 Steven Rostedt <srostedt@redhat.com>
+ */
+#include <linux/stringify.h>
+#include <linux/kallsyms.h>
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+#include <linux/ftrace.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+
+#include "trace_output.h"
+
+
+#undef TRACE_STRUCT
+#define TRACE_STRUCT(args...) args
+
+#undef TRACE_FIELD
+#define TRACE_FIELD(type, item, assign)					\
+	ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t"	\
+			       "offset:%u;\tsize:%u;\n",		\
+			       (unsigned int)offsetof(typeof(field), item), \
+			       (unsigned int)sizeof(field.item));	\
+	if (!ret)							\
+		return 0;
+
+
+#undef TRACE_FIELD_SPECIAL
+#define TRACE_FIELD_SPECIAL(type_item, item, cmd)			\
+	ret = trace_seq_printf(s, "\tfield special:" #type_item ";\t"	\
+			       "offset:%u;\tsize:%u;\n",		\
+			       (unsigned int)offsetof(typeof(field), item), \
+			       (unsigned int)sizeof(field.item));	\
+	if (!ret)							\
+		return 0;
+
+#undef TRACE_FIELD_ZERO_CHAR
+#define TRACE_FIELD_ZERO_CHAR(item)					\
+	ret = trace_seq_printf(s, "\tfield: char " #item ";\t"		\
+			       "offset:%u;\tsize:0;\n",			\
+			       (unsigned int)offsetof(typeof(field), item)); \
+	if (!ret)							\
+		return 0;
+
+
+#undef TP_RAW_FMT
+#define TP_RAW_FMT(args...) args
+
+#undef TRACE_EVENT_FORMAT
+#define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt)	\
+static int								\
+ftrace_format_##call(struct trace_seq *s)				\
+{									\
+	struct args field;						\
+	int ret;							\
+									\
+	tstruct;							\
+									\
+	trace_seq_printf(s, "\nprint fmt: \"%s\"\n", tpfmt);		\
+									\
+	return ret;							\
+}
+
+#include "trace_event_types.h"
+
+#undef TRACE_ZERO_CHAR
+#define TRACE_ZERO_CHAR(arg)
+
+#undef TRACE_FIELD
+#define TRACE_FIELD(type, item, assign)\
+	entry->item = assign;
+
+#undef TRACE_FIELD
+#define TRACE_FIELD(type, item, assign)\
+	entry->item = assign;
+
+#undef TP_CMD
+#define TP_CMD(cmd...)	cmd
+
+#undef TRACE_ENTRY
+#define TRACE_ENTRY	entry
+
+#undef TRACE_FIELD_SPECIAL
+#define TRACE_FIELD_SPECIAL(type_item, item, cmd) \
+	cmd;
+
+#undef TRACE_EVENT_FORMAT
+#define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt)	\
+									\
+static struct ftrace_event_call __used					\
+__attribute__((__aligned__(4)))						\
+__attribute__((section("_ftrace_events"))) event_##call = {		\
+	.name			= #call,				\
+	.id			= proto,				\
+	.system			= __stringify(TRACE_SYSTEM),		\
+	.show_format		= ftrace_format_##call,			\
+}
+#include "trace_event_types.h"
diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c
index 9236d7e..c9a0b7d 100644
--- a/kernel/trace/trace_functions.c
+++ b/kernel/trace/trace_functions.c
@@ -9,6 +9,7 @@
  *  Copyright (C) 2004-2006 Ingo Molnar
  *  Copyright (C) 2004 William Lee Irwin III
  */
+#include <linux/ring_buffer.h>
 #include <linux/debugfs.h>
 #include <linux/uaccess.h>
 #include <linux/ftrace.h>
@@ -16,31 +17,29 @@
 
 #include "trace.h"
 
-static void start_function_trace(struct trace_array *tr)
+/* function tracing enabled */
+static int			ftrace_function_enabled;
+
+static struct trace_array	*func_trace;
+
+static void tracing_start_function_trace(void);
+static void tracing_stop_function_trace(void);
+
+static int function_trace_init(struct trace_array *tr)
 {
+	func_trace = tr;
 	tr->cpu = get_cpu();
-	tracing_reset_online_cpus(tr);
 	put_cpu();
 
 	tracing_start_cmdline_record();
 	tracing_start_function_trace();
-}
-
-static void stop_function_trace(struct trace_array *tr)
-{
-	tracing_stop_function_trace();
-	tracing_stop_cmdline_record();
-}
-
-static int function_trace_init(struct trace_array *tr)
-{
-	start_function_trace(tr);
 	return 0;
 }
 
 static void function_trace_reset(struct trace_array *tr)
 {
-	stop_function_trace(tr);
+	tracing_stop_function_trace();
+	tracing_stop_cmdline_record();
 }
 
 static void function_trace_start(struct trace_array *tr)
@@ -48,20 +47,358 @@
 	tracing_reset_online_cpus(tr);
 }
 
+static void
+function_trace_call_preempt_only(unsigned long ip, unsigned long parent_ip)
+{
+	struct trace_array *tr = func_trace;
+	struct trace_array_cpu *data;
+	unsigned long flags;
+	long disabled;
+	int cpu, resched;
+	int pc;
+
+	if (unlikely(!ftrace_function_enabled))
+		return;
+
+	pc = preempt_count();
+	resched = ftrace_preempt_disable();
+	local_save_flags(flags);
+	cpu = raw_smp_processor_id();
+	data = tr->data[cpu];
+	disabled = atomic_inc_return(&data->disabled);
+
+	if (likely(disabled == 1))
+		trace_function(tr, ip, parent_ip, flags, pc);
+
+	atomic_dec(&data->disabled);
+	ftrace_preempt_enable(resched);
+}
+
+static void
+function_trace_call(unsigned long ip, unsigned long parent_ip)
+{
+	struct trace_array *tr = func_trace;
+	struct trace_array_cpu *data;
+	unsigned long flags;
+	long disabled;
+	int cpu;
+	int pc;
+
+	if (unlikely(!ftrace_function_enabled))
+		return;
+
+	/*
+	 * Need to use raw, since this must be called before the
+	 * recursive protection is performed.
+	 */
+	local_irq_save(flags);
+	cpu = raw_smp_processor_id();
+	data = tr->data[cpu];
+	disabled = atomic_inc_return(&data->disabled);
+
+	if (likely(disabled == 1)) {
+		pc = preempt_count();
+		trace_function(tr, ip, parent_ip, flags, pc);
+	}
+
+	atomic_dec(&data->disabled);
+	local_irq_restore(flags);
+}
+
+static void
+function_stack_trace_call(unsigned long ip, unsigned long parent_ip)
+{
+	struct trace_array *tr = func_trace;
+	struct trace_array_cpu *data;
+	unsigned long flags;
+	long disabled;
+	int cpu;
+	int pc;
+
+	if (unlikely(!ftrace_function_enabled))
+		return;
+
+	/*
+	 * Need to use raw, since this must be called before the
+	 * recursive protection is performed.
+	 */
+	local_irq_save(flags);
+	cpu = raw_smp_processor_id();
+	data = tr->data[cpu];
+	disabled = atomic_inc_return(&data->disabled);
+
+	if (likely(disabled == 1)) {
+		pc = preempt_count();
+		trace_function(tr, ip, parent_ip, flags, pc);
+		/*
+		 * skip over 5 funcs:
+		 *    __ftrace_trace_stack,
+		 *    __trace_stack,
+		 *    function_stack_trace_call
+		 *    ftrace_list_func
+		 *    ftrace_call
+		 */
+		__trace_stack(tr, flags, 5, pc);
+	}
+
+	atomic_dec(&data->disabled);
+	local_irq_restore(flags);
+}
+
+
+static struct ftrace_ops trace_ops __read_mostly =
+{
+	.func = function_trace_call,
+};
+
+static struct ftrace_ops trace_stack_ops __read_mostly =
+{
+	.func = function_stack_trace_call,
+};
+
+/* Our two options */
+enum {
+	TRACE_FUNC_OPT_STACK = 0x1,
+};
+
+static struct tracer_opt func_opts[] = {
+#ifdef CONFIG_STACKTRACE
+	{ TRACER_OPT(func_stack_trace, TRACE_FUNC_OPT_STACK) },
+#endif
+	{ } /* Always set a last empty entry */
+};
+
+static struct tracer_flags func_flags = {
+	.val = 0, /* By default: all flags disabled */
+	.opts = func_opts
+};
+
+static void tracing_start_function_trace(void)
+{
+	ftrace_function_enabled = 0;
+
+	if (trace_flags & TRACE_ITER_PREEMPTONLY)
+		trace_ops.func = function_trace_call_preempt_only;
+	else
+		trace_ops.func = function_trace_call;
+
+	if (func_flags.val & TRACE_FUNC_OPT_STACK)
+		register_ftrace_function(&trace_stack_ops);
+	else
+		register_ftrace_function(&trace_ops);
+
+	ftrace_function_enabled = 1;
+}
+
+static void tracing_stop_function_trace(void)
+{
+	ftrace_function_enabled = 0;
+	/* OK if they are not registered */
+	unregister_ftrace_function(&trace_stack_ops);
+	unregister_ftrace_function(&trace_ops);
+}
+
+static int func_set_flag(u32 old_flags, u32 bit, int set)
+{
+	if (bit == TRACE_FUNC_OPT_STACK) {
+		/* do nothing if already set */
+		if (!!set == !!(func_flags.val & TRACE_FUNC_OPT_STACK))
+			return 0;
+
+		if (set) {
+			unregister_ftrace_function(&trace_ops);
+			register_ftrace_function(&trace_stack_ops);
+		} else {
+			unregister_ftrace_function(&trace_stack_ops);
+			register_ftrace_function(&trace_ops);
+		}
+
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
 static struct tracer function_trace __read_mostly =
 {
-	.name	     = "function",
-	.init	     = function_trace_init,
-	.reset	     = function_trace_reset,
-	.start	     = function_trace_start,
+	.name		= "function",
+	.init		= function_trace_init,
+	.reset		= function_trace_reset,
+	.start		= function_trace_start,
+	.wait_pipe	= poll_wait_pipe,
+	.flags		= &func_flags,
+	.set_flag	= func_set_flag,
 #ifdef CONFIG_FTRACE_SELFTEST
-	.selftest    = trace_selftest_startup_function,
+	.selftest	= trace_selftest_startup_function,
 #endif
 };
 
-static __init int init_function_trace(void)
+#ifdef CONFIG_DYNAMIC_FTRACE
+static void
+ftrace_traceon(unsigned long ip, unsigned long parent_ip, void **data)
 {
-	return register_tracer(&function_trace);
+	long *count = (long *)data;
+
+	if (tracing_is_on())
+		return;
+
+	if (!*count)
+		return;
+
+	if (*count != -1)
+		(*count)--;
+
+	tracing_on();
 }
 
+static void
+ftrace_traceoff(unsigned long ip, unsigned long parent_ip, void **data)
+{
+	long *count = (long *)data;
+
+	if (!tracing_is_on())
+		return;
+
+	if (!*count)
+		return;
+
+	if (*count != -1)
+		(*count)--;
+
+	tracing_off();
+}
+
+static int
+ftrace_trace_onoff_print(struct seq_file *m, unsigned long ip,
+			 struct ftrace_probe_ops *ops, void *data);
+
+static struct ftrace_probe_ops traceon_probe_ops = {
+	.func			= ftrace_traceon,
+	.print			= ftrace_trace_onoff_print,
+};
+
+static struct ftrace_probe_ops traceoff_probe_ops = {
+	.func			= ftrace_traceoff,
+	.print			= ftrace_trace_onoff_print,
+};
+
+static int
+ftrace_trace_onoff_print(struct seq_file *m, unsigned long ip,
+			 struct ftrace_probe_ops *ops, void *data)
+{
+	char str[KSYM_SYMBOL_LEN];
+	long count = (long)data;
+
+	kallsyms_lookup(ip, NULL, NULL, NULL, str);
+	seq_printf(m, "%s:", str);
+
+	if (ops == &traceon_probe_ops)
+		seq_printf(m, "traceon");
+	else
+		seq_printf(m, "traceoff");
+
+	if (count == -1)
+		seq_printf(m, ":unlimited\n");
+	else
+		seq_printf(m, ":count=%ld", count);
+	seq_putc(m, '\n');
+
+	return 0;
+}
+
+static int
+ftrace_trace_onoff_unreg(char *glob, char *cmd, char *param)
+{
+	struct ftrace_probe_ops *ops;
+
+	/* we register both traceon and traceoff to this callback */
+	if (strcmp(cmd, "traceon") == 0)
+		ops = &traceon_probe_ops;
+	else
+		ops = &traceoff_probe_ops;
+
+	unregister_ftrace_function_probe_func(glob, ops);
+
+	return 0;
+}
+
+static int
+ftrace_trace_onoff_callback(char *glob, char *cmd, char *param, int enable)
+{
+	struct ftrace_probe_ops *ops;
+	void *count = (void *)-1;
+	char *number;
+	int ret;
+
+	/* hash funcs only work with set_ftrace_filter */
+	if (!enable)
+		return -EINVAL;
+
+	if (glob[0] == '!')
+		return ftrace_trace_onoff_unreg(glob+1, cmd, param);
+
+	/* we register both traceon and traceoff to this callback */
+	if (strcmp(cmd, "traceon") == 0)
+		ops = &traceon_probe_ops;
+	else
+		ops = &traceoff_probe_ops;
+
+	if (!param)
+		goto out_reg;
+
+	number = strsep(&param, ":");
+
+	if (!strlen(number))
+		goto out_reg;
+
+	/*
+	 * We use the callback data field (which is a pointer)
+	 * as our counter.
+	 */
+	ret = strict_strtoul(number, 0, (unsigned long *)&count);
+	if (ret)
+		return ret;
+
+ out_reg:
+	ret = register_ftrace_function_probe(glob, ops, count);
+
+	return ret;
+}
+
+static struct ftrace_func_command ftrace_traceon_cmd = {
+	.name			= "traceon",
+	.func			= ftrace_trace_onoff_callback,
+};
+
+static struct ftrace_func_command ftrace_traceoff_cmd = {
+	.name			= "traceoff",
+	.func			= ftrace_trace_onoff_callback,
+};
+
+static int __init init_func_cmd_traceon(void)
+{
+	int ret;
+
+	ret = register_ftrace_command(&ftrace_traceoff_cmd);
+	if (ret)
+		return ret;
+
+	ret = register_ftrace_command(&ftrace_traceon_cmd);
+	if (ret)
+		unregister_ftrace_command(&ftrace_traceoff_cmd);
+	return ret;
+}
+#else
+static inline int init_func_cmd_traceon(void)
+{
+	return 0;
+}
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
+static __init int init_function_trace(void)
+{
+	init_func_cmd_traceon();
+	return register_tracer(&function_trace);
+}
 device_initcall(init_function_trace);
+
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
index dce71a5b..d28687e 100644
--- a/kernel/trace/trace_functions_graph.c
+++ b/kernel/trace/trace_functions_graph.c
@@ -1,7 +1,7 @@
 /*
  *
  * Function graph tracer.
- * Copyright (c) 2008 Frederic Weisbecker <fweisbec@gmail.com>
+ * Copyright (c) 2008-2009 Frederic Weisbecker <fweisbec@gmail.com>
  * Mostly borrowed from function tracer which
  * is Copyright (c) Steven Rostedt <srostedt@redhat.com>
  *
@@ -12,6 +12,12 @@
 #include <linux/fs.h>
 
 #include "trace.h"
+#include "trace_output.h"
+
+struct fgraph_data {
+	pid_t		last_pid;
+	int		depth;
+};
 
 #define TRACE_GRAPH_INDENT	2
 
@@ -20,9 +26,11 @@
 #define TRACE_GRAPH_PRINT_CPU		0x2
 #define TRACE_GRAPH_PRINT_OVERHEAD	0x4
 #define TRACE_GRAPH_PRINT_PROC		0x8
+#define TRACE_GRAPH_PRINT_DURATION	0x10
+#define TRACE_GRAPH_PRINT_ABS_TIME	0X20
 
 static struct tracer_opt trace_opts[] = {
-	/* Display overruns ? */
+	/* Display overruns? (for self-debug purpose) */
 	{ TRACER_OPT(funcgraph-overrun, TRACE_GRAPH_PRINT_OVERRUN) },
 	/* Display CPU ? */
 	{ TRACER_OPT(funcgraph-cpu, TRACE_GRAPH_PRINT_CPU) },
@@ -30,23 +38,28 @@
 	{ TRACER_OPT(funcgraph-overhead, TRACE_GRAPH_PRINT_OVERHEAD) },
 	/* Display proc name/pid */
 	{ TRACER_OPT(funcgraph-proc, TRACE_GRAPH_PRINT_PROC) },
+	/* Display duration of execution */
+	{ TRACER_OPT(funcgraph-duration, TRACE_GRAPH_PRINT_DURATION) },
+	/* Display absolute time of an entry */
+	{ TRACER_OPT(funcgraph-abstime, TRACE_GRAPH_PRINT_ABS_TIME) },
 	{ } /* Empty entry */
 };
 
 static struct tracer_flags tracer_flags = {
 	/* Don't display overruns and proc by default */
-	.val = TRACE_GRAPH_PRINT_CPU | TRACE_GRAPH_PRINT_OVERHEAD,
+	.val = TRACE_GRAPH_PRINT_CPU | TRACE_GRAPH_PRINT_OVERHEAD |
+	       TRACE_GRAPH_PRINT_DURATION,
 	.opts = trace_opts
 };
 
 /* pid on the last trace processed */
-static pid_t last_pid[NR_CPUS] = { [0 ... NR_CPUS-1] = -1 };
+
 
 /* Add a function return address to the trace stack on thread info.*/
 int
-ftrace_push_return_trace(unsigned long ret, unsigned long long time,
-			 unsigned long func, int *depth)
+ftrace_push_return_trace(unsigned long ret, unsigned long func, int *depth)
 {
+	unsigned long long calltime;
 	int index;
 
 	if (!current->ret_stack)
@@ -58,11 +71,13 @@
 		return -EBUSY;
 	}
 
+	calltime = trace_clock_local();
+
 	index = ++current->curr_ret_stack;
 	barrier();
 	current->ret_stack[index].ret = ret;
 	current->ret_stack[index].func = func;
-	current->ret_stack[index].calltime = time;
+	current->ret_stack[index].calltime = calltime;
 	*depth = index;
 
 	return 0;
@@ -104,7 +119,7 @@
 	unsigned long ret;
 
 	ftrace_pop_return_trace(&trace, &ret);
-	trace.rettime = cpu_clock(raw_smp_processor_id());
+	trace.rettime = trace_clock_local();
 	ftrace_graph_return(&trace);
 
 	if (unlikely(!ret)) {
@@ -119,12 +134,7 @@
 
 static int graph_trace_init(struct trace_array *tr)
 {
-	int cpu, ret;
-
-	for_each_online_cpu(cpu)
-		tracing_reset(tr, cpu);
-
-	ret = register_ftrace_graph(&trace_graph_return,
+	int ret = register_ftrace_graph(&trace_graph_return,
 					&trace_graph_entry);
 	if (ret)
 		return ret;
@@ -187,15 +197,15 @@
 static enum print_line_t
 print_graph_proc(struct trace_seq *s, pid_t pid)
 {
-	int i;
-	int ret;
-	int len;
-	char comm[8];
-	int spaces = 0;
+	char comm[TASK_COMM_LEN];
 	/* sign + log10(MAX_INT) + '\0' */
 	char pid_str[11];
+	int spaces = 0;
+	int ret;
+	int len;
+	int i;
 
-	strncpy(comm, trace_find_cmdline(pid), 7);
+	trace_find_cmdline(pid, comm);
 	comm[7] = '\0';
 	sprintf(pid_str, "%d", pid);
 
@@ -228,17 +238,25 @@
 
 /* If the pid changed since the last trace, output this event */
 static enum print_line_t
-verif_pid(struct trace_seq *s, pid_t pid, int cpu)
+verif_pid(struct trace_seq *s, pid_t pid, int cpu, struct fgraph_data *data)
 {
 	pid_t prev_pid;
+	pid_t *last_pid;
 	int ret;
 
-	if (last_pid[cpu] != -1 && last_pid[cpu] == pid)
+	if (!data)
 		return TRACE_TYPE_HANDLED;
 
-	prev_pid = last_pid[cpu];
-	last_pid[cpu] = pid;
+	last_pid = &(per_cpu_ptr(data, cpu)->last_pid);
 
+	if (*last_pid == pid)
+		return TRACE_TYPE_HANDLED;
+
+	prev_pid = *last_pid;
+	*last_pid = pid;
+
+	if (prev_pid == -1)
+		return TRACE_TYPE_HANDLED;
 /*
  * Context-switch trace line:
 
@@ -250,34 +268,34 @@
 	ret = trace_seq_printf(s,
 		" ------------------------------------------\n");
 	if (!ret)
-		TRACE_TYPE_PARTIAL_LINE;
+		return TRACE_TYPE_PARTIAL_LINE;
 
 	ret = print_graph_cpu(s, cpu);
 	if (ret == TRACE_TYPE_PARTIAL_LINE)
-		TRACE_TYPE_PARTIAL_LINE;
+		return TRACE_TYPE_PARTIAL_LINE;
 
 	ret = print_graph_proc(s, prev_pid);
 	if (ret == TRACE_TYPE_PARTIAL_LINE)
-		TRACE_TYPE_PARTIAL_LINE;
+		return TRACE_TYPE_PARTIAL_LINE;
 
 	ret = trace_seq_printf(s, " => ");
 	if (!ret)
-		TRACE_TYPE_PARTIAL_LINE;
+		return TRACE_TYPE_PARTIAL_LINE;
 
 	ret = print_graph_proc(s, pid);
 	if (ret == TRACE_TYPE_PARTIAL_LINE)
-		TRACE_TYPE_PARTIAL_LINE;
+		return TRACE_TYPE_PARTIAL_LINE;
 
 	ret = trace_seq_printf(s,
 		"\n ------------------------------------------\n\n");
 	if (!ret)
-		TRACE_TYPE_PARTIAL_LINE;
+		return TRACE_TYPE_PARTIAL_LINE;
 
-	return ret;
+	return TRACE_TYPE_HANDLED;
 }
 
-static bool
-trace_branch_is_leaf(struct trace_iterator *iter,
+static struct ftrace_graph_ret_entry *
+get_return_for_leaf(struct trace_iterator *iter,
 		struct ftrace_graph_ent_entry *curr)
 {
 	struct ring_buffer_iter *ring_iter;
@@ -286,65 +304,123 @@
 
 	ring_iter = iter->buffer_iter[iter->cpu];
 
-	if (!ring_iter)
-		return false;
-
-	event = ring_buffer_iter_peek(ring_iter, NULL);
+	/* First peek to compare current entry and the next one */
+	if (ring_iter)
+		event = ring_buffer_iter_peek(ring_iter, NULL);
+	else {
+	/* We need to consume the current entry to see the next one */
+		ring_buffer_consume(iter->tr->buffer, iter->cpu, NULL);
+		event = ring_buffer_peek(iter->tr->buffer, iter->cpu,
+					NULL);
+	}
 
 	if (!event)
-		return false;
+		return NULL;
 
 	next = ring_buffer_event_data(event);
 
 	if (next->ent.type != TRACE_GRAPH_RET)
-		return false;
+		return NULL;
 
 	if (curr->ent.pid != next->ent.pid ||
 			curr->graph_ent.func != next->ret.func)
-		return false;
+		return NULL;
 
-	return true;
+	/* this is a leaf, now advance the iterator */
+	if (ring_iter)
+		ring_buffer_read(ring_iter, NULL);
+
+	return next;
+}
+
+/* Signal a overhead of time execution to the output */
+static int
+print_graph_overhead(unsigned long long duration, struct trace_seq *s)
+{
+	/* If duration disappear, we don't need anything */
+	if (!(tracer_flags.val & TRACE_GRAPH_PRINT_DURATION))
+		return 1;
+
+	/* Non nested entry or return */
+	if (duration == -1)
+		return trace_seq_printf(s, "  ");
+
+	if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERHEAD) {
+		/* Duration exceeded 100 msecs */
+		if (duration > 100000ULL)
+			return trace_seq_printf(s, "! ");
+
+		/* Duration exceeded 10 msecs */
+		if (duration > 10000ULL)
+			return trace_seq_printf(s, "+ ");
+	}
+
+	return trace_seq_printf(s, "  ");
+}
+
+static int print_graph_abs_time(u64 t, struct trace_seq *s)
+{
+	unsigned long usecs_rem;
+
+	usecs_rem = do_div(t, NSEC_PER_SEC);
+	usecs_rem /= 1000;
+
+	return trace_seq_printf(s, "%5lu.%06lu |  ",
+			(unsigned long)t, usecs_rem);
 }
 
 static enum print_line_t
-print_graph_irq(struct trace_seq *s, unsigned long addr,
-				enum trace_type type, int cpu, pid_t pid)
+print_graph_irq(struct trace_iterator *iter, unsigned long addr,
+		enum trace_type type, int cpu, pid_t pid)
 {
 	int ret;
+	struct trace_seq *s = &iter->seq;
 
 	if (addr < (unsigned long)__irqentry_text_start ||
 		addr >= (unsigned long)__irqentry_text_end)
 		return TRACE_TYPE_UNHANDLED;
 
-	if (type == TRACE_GRAPH_ENT) {
-		ret = trace_seq_printf(s, "==========> |  ");
-	} else {
-		/* Cpu */
-		if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) {
-			ret = print_graph_cpu(s, cpu);
-			if (ret == TRACE_TYPE_PARTIAL_LINE)
-				return TRACE_TYPE_PARTIAL_LINE;
-		}
-		/* Proc */
-		if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) {
-			ret = print_graph_proc(s, pid);
-			if (ret == TRACE_TYPE_PARTIAL_LINE)
-				return TRACE_TYPE_PARTIAL_LINE;
-
-			ret = trace_seq_printf(s, " | ");
-			if (!ret)
-				return TRACE_TYPE_PARTIAL_LINE;
-		}
-
-		/* No overhead */
-		if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERHEAD) {
-			ret = trace_seq_printf(s, "  ");
-			if (!ret)
-				return TRACE_TYPE_PARTIAL_LINE;
-		}
-
-		ret = trace_seq_printf(s, "<========== |\n");
+	/* Absolute time */
+	if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME) {
+		ret = print_graph_abs_time(iter->ts, s);
+		if (!ret)
+			return TRACE_TYPE_PARTIAL_LINE;
 	}
+
+	/* Cpu */
+	if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) {
+		ret = print_graph_cpu(s, cpu);
+		if (ret == TRACE_TYPE_PARTIAL_LINE)
+			return TRACE_TYPE_PARTIAL_LINE;
+	}
+	/* Proc */
+	if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) {
+		ret = print_graph_proc(s, pid);
+		if (ret == TRACE_TYPE_PARTIAL_LINE)
+			return TRACE_TYPE_PARTIAL_LINE;
+		ret = trace_seq_printf(s, " | ");
+		if (!ret)
+			return TRACE_TYPE_PARTIAL_LINE;
+	}
+
+	/* No overhead */
+	ret = print_graph_overhead(-1, s);
+	if (!ret)
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	if (type == TRACE_GRAPH_ENT)
+		ret = trace_seq_printf(s, "==========>");
+	else
+		ret = trace_seq_printf(s, "<==========");
+
+	if (!ret)
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	/* Don't close the duration column if haven't one */
+	if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
+		trace_seq_printf(s, " |");
+	ret = trace_seq_printf(s, "\n");
+
 	if (!ret)
 		return TRACE_TYPE_PARTIAL_LINE;
 	return TRACE_TYPE_HANDLED;
@@ -363,7 +439,7 @@
 	sprintf(msecs_str, "%lu", (unsigned long) duration);
 
 	/* Print msecs */
-	ret = trace_seq_printf(s, msecs_str);
+	ret = trace_seq_printf(s, "%s", msecs_str);
 	if (!ret)
 		return TRACE_TYPE_PARTIAL_LINE;
 
@@ -396,52 +472,47 @@
 
 }
 
-/* Signal a overhead of time execution to the output */
-static int
-print_graph_overhead(unsigned long long duration, struct trace_seq *s)
-{
-	/* Duration exceeded 100 msecs */
-	if (duration > 100000ULL)
-		return trace_seq_printf(s, "! ");
-
-	/* Duration exceeded 10 msecs */
-	if (duration > 10000ULL)
-		return trace_seq_printf(s, "+ ");
-
-	return trace_seq_printf(s, "  ");
-}
-
 /* Case of a leaf function on its call entry */
 static enum print_line_t
 print_graph_entry_leaf(struct trace_iterator *iter,
-		struct ftrace_graph_ent_entry *entry, struct trace_seq *s)
+		struct ftrace_graph_ent_entry *entry,
+		struct ftrace_graph_ret_entry *ret_entry, struct trace_seq *s)
 {
-	struct ftrace_graph_ret_entry *ret_entry;
+	struct fgraph_data *data = iter->private;
 	struct ftrace_graph_ret *graph_ret;
-	struct ring_buffer_event *event;
 	struct ftrace_graph_ent *call;
 	unsigned long long duration;
 	int ret;
 	int i;
 
-	event = ring_buffer_read(iter->buffer_iter[iter->cpu], NULL);
-	ret_entry = ring_buffer_event_data(event);
 	graph_ret = &ret_entry->ret;
 	call = &entry->graph_ent;
 	duration = graph_ret->rettime - graph_ret->calltime;
 
-	/* Overhead */
-	if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERHEAD) {
-		ret = print_graph_overhead(duration, s);
-		if (!ret)
-			return TRACE_TYPE_PARTIAL_LINE;
+	if (data) {
+		int cpu = iter->cpu;
+		int *depth = &(per_cpu_ptr(data, cpu)->depth);
+
+		/*
+		 * Comments display at + 1 to depth. Since
+		 * this is a leaf function, keep the comments
+		 * equal to this depth.
+		 */
+		*depth = call->depth - 1;
 	}
 
-	/* Duration */
-	ret = print_graph_duration(duration, s);
-	if (ret == TRACE_TYPE_PARTIAL_LINE)
+	/* Overhead */
+	ret = print_graph_overhead(duration, s);
+	if (!ret)
 		return TRACE_TYPE_PARTIAL_LINE;
 
+	/* Duration */
+	if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) {
+		ret = print_graph_duration(duration, s);
+		if (ret == TRACE_TYPE_PARTIAL_LINE)
+			return TRACE_TYPE_PARTIAL_LINE;
+	}
+
 	/* Function */
 	for (i = 0; i < call->depth * TRACE_GRAPH_INDENT; i++) {
 		ret = trace_seq_printf(s, " ");
@@ -461,33 +532,34 @@
 }
 
 static enum print_line_t
-print_graph_entry_nested(struct ftrace_graph_ent_entry *entry,
-			struct trace_seq *s, pid_t pid, int cpu)
+print_graph_entry_nested(struct trace_iterator *iter,
+			 struct ftrace_graph_ent_entry *entry,
+			 struct trace_seq *s, int cpu)
 {
-	int i;
-	int ret;
 	struct ftrace_graph_ent *call = &entry->graph_ent;
+	struct fgraph_data *data = iter->private;
+	int ret;
+	int i;
 
-	/* No overhead */
-	if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERHEAD) {
-		ret = trace_seq_printf(s, "  ");
-		if (!ret)
-			return TRACE_TYPE_PARTIAL_LINE;
+	if (data) {
+		int cpu = iter->cpu;
+		int *depth = &(per_cpu_ptr(data, cpu)->depth);
+
+		*depth = call->depth;
 	}
 
-	/* Interrupt */
-	ret = print_graph_irq(s, call->func, TRACE_GRAPH_ENT, cpu, pid);
-	if (ret == TRACE_TYPE_UNHANDLED) {
-		/* No time */
+	/* No overhead */
+	ret = print_graph_overhead(-1, s);
+	if (!ret)
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	/* No time */
+	if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) {
 		ret = trace_seq_printf(s, "            |  ");
 		if (!ret)
 			return TRACE_TYPE_PARTIAL_LINE;
-	} else {
-		if (ret == TRACE_TYPE_PARTIAL_LINE)
-			return TRACE_TYPE_PARTIAL_LINE;
 	}
 
-
 	/* Function */
 	for (i = 0; i < call->depth * TRACE_GRAPH_INDENT; i++) {
 		ret = trace_seq_printf(s, " ");
@@ -503,20 +575,40 @@
 	if (!ret)
 		return TRACE_TYPE_PARTIAL_LINE;
 
-	return TRACE_TYPE_HANDLED;
+	/*
+	 * we already consumed the current entry to check the next one
+	 * and see if this is a leaf.
+	 */
+	return TRACE_TYPE_NO_CONSUME;
 }
 
 static enum print_line_t
-print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s,
-			struct trace_iterator *iter, int cpu)
+print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s,
+		     int type, unsigned long addr)
 {
-	int ret;
+	struct fgraph_data *data = iter->private;
 	struct trace_entry *ent = iter->ent;
+	int cpu = iter->cpu;
+	int ret;
 
 	/* Pid */
-	if (verif_pid(s, ent->pid, cpu) == TRACE_TYPE_PARTIAL_LINE)
+	if (verif_pid(s, ent->pid, cpu, data) == TRACE_TYPE_PARTIAL_LINE)
 		return TRACE_TYPE_PARTIAL_LINE;
 
+	if (type) {
+		/* Interrupt */
+		ret = print_graph_irq(iter, addr, type, cpu, ent->pid);
+		if (ret == TRACE_TYPE_PARTIAL_LINE)
+			return TRACE_TYPE_PARTIAL_LINE;
+	}
+
+	/* Absolute time */
+	if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME) {
+		ret = print_graph_abs_time(iter->ts, s);
+		if (!ret)
+			return TRACE_TYPE_PARTIAL_LINE;
+	}
+
 	/* Cpu */
 	if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) {
 		ret = print_graph_cpu(s, cpu);
@@ -535,54 +627,65 @@
 			return TRACE_TYPE_PARTIAL_LINE;
 	}
 
-	if (trace_branch_is_leaf(iter, field))
-		return print_graph_entry_leaf(iter, field, s);
+	return 0;
+}
+
+static enum print_line_t
+print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s,
+			struct trace_iterator *iter)
+{
+	int cpu = iter->cpu;
+	struct ftrace_graph_ent *call = &field->graph_ent;
+	struct ftrace_graph_ret_entry *leaf_ret;
+
+	if (print_graph_prologue(iter, s, TRACE_GRAPH_ENT, call->func))
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	leaf_ret = get_return_for_leaf(iter, field);
+	if (leaf_ret)
+		return print_graph_entry_leaf(iter, field, leaf_ret, s);
 	else
-		return print_graph_entry_nested(field, s, iter->ent->pid, cpu);
+		return print_graph_entry_nested(iter, field, s, cpu);
 
 }
 
 static enum print_line_t
 print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
-		   struct trace_entry *ent, int cpu)
+		   struct trace_entry *ent, struct trace_iterator *iter)
 {
-	int i;
-	int ret;
 	unsigned long long duration = trace->rettime - trace->calltime;
+	struct fgraph_data *data = iter->private;
+	pid_t pid = ent->pid;
+	int cpu = iter->cpu;
+	int ret;
+	int i;
 
-	/* Pid */
-	if (verif_pid(s, ent->pid, cpu) == TRACE_TYPE_PARTIAL_LINE)
+	if (data) {
+		int cpu = iter->cpu;
+		int *depth = &(per_cpu_ptr(data, cpu)->depth);
+
+		/*
+		 * Comments display at + 1 to depth. This is the
+		 * return from a function, we now want the comments
+		 * to display at the same level of the bracket.
+		 */
+		*depth = trace->depth - 1;
+	}
+
+	if (print_graph_prologue(iter, s, 0, 0))
 		return TRACE_TYPE_PARTIAL_LINE;
 
-	/* Cpu */
-	if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) {
-		ret = print_graph_cpu(s, cpu);
-		if (ret == TRACE_TYPE_PARTIAL_LINE)
-			return TRACE_TYPE_PARTIAL_LINE;
-	}
-
-	/* Proc */
-	if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) {
-		ret = print_graph_proc(s, ent->pid);
-		if (ret == TRACE_TYPE_PARTIAL_LINE)
-			return TRACE_TYPE_PARTIAL_LINE;
-
-		ret = trace_seq_printf(s, " | ");
-		if (!ret)
-			return TRACE_TYPE_PARTIAL_LINE;
-	}
-
 	/* Overhead */
-	if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERHEAD) {
-		ret = print_graph_overhead(duration, s);
-		if (!ret)
-			return TRACE_TYPE_PARTIAL_LINE;
-	}
+	ret = print_graph_overhead(duration, s);
+	if (!ret)
+		return TRACE_TYPE_PARTIAL_LINE;
 
 	/* Duration */
-	ret = print_graph_duration(duration, s);
-	if (ret == TRACE_TYPE_PARTIAL_LINE)
-		return TRACE_TYPE_PARTIAL_LINE;
+	if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) {
+		ret = print_graph_duration(duration, s);
+		if (ret == TRACE_TYPE_PARTIAL_LINE)
+			return TRACE_TYPE_PARTIAL_LINE;
+	}
 
 	/* Closing brace */
 	for (i = 0; i < trace->depth * TRACE_GRAPH_INDENT; i++) {
@@ -603,7 +706,7 @@
 			return TRACE_TYPE_PARTIAL_LINE;
 	}
 
-	ret = print_graph_irq(s, trace->func, TRACE_GRAPH_RET, cpu, ent->pid);
+	ret = print_graph_irq(iter, trace->func, TRACE_GRAPH_RET, cpu, pid);
 	if (ret == TRACE_TYPE_PARTIAL_LINE)
 		return TRACE_TYPE_PARTIAL_LINE;
 
@@ -611,61 +714,73 @@
 }
 
 static enum print_line_t
-print_graph_comment(struct print_entry *trace, struct trace_seq *s,
-		   struct trace_entry *ent, struct trace_iterator *iter)
+print_graph_comment(struct trace_seq *s,  struct trace_entry *ent,
+		    struct trace_iterator *iter)
 {
-	int i;
+	unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK);
+	struct fgraph_data *data = iter->private;
+	struct trace_event *event;
+	int depth = 0;
 	int ret;
+	int i;
 
-	/* Pid */
-	if (verif_pid(s, ent->pid, iter->cpu) == TRACE_TYPE_PARTIAL_LINE)
+	if (data)
+		depth = per_cpu_ptr(data, iter->cpu)->depth;
+
+	if (print_graph_prologue(iter, s, 0, 0))
 		return TRACE_TYPE_PARTIAL_LINE;
 
-	/* Cpu */
-	if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) {
-		ret = print_graph_cpu(s, iter->cpu);
-		if (ret == TRACE_TYPE_PARTIAL_LINE)
-			return TRACE_TYPE_PARTIAL_LINE;
-	}
-
-	/* Proc */
-	if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) {
-		ret = print_graph_proc(s, ent->pid);
-		if (ret == TRACE_TYPE_PARTIAL_LINE)
-			return TRACE_TYPE_PARTIAL_LINE;
-
-		ret = trace_seq_printf(s, " | ");
-		if (!ret)
-			return TRACE_TYPE_PARTIAL_LINE;
-	}
-
 	/* No overhead */
-	if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERHEAD) {
-		ret = trace_seq_printf(s, "  ");
-		if (!ret)
-			return TRACE_TYPE_PARTIAL_LINE;
-	}
-
-	/* No time */
-	ret = trace_seq_printf(s, "            |  ");
+	ret = print_graph_overhead(-1, s);
 	if (!ret)
 		return TRACE_TYPE_PARTIAL_LINE;
 
+	/* No time */
+	if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) {
+		ret = trace_seq_printf(s, "            |  ");
+		if (!ret)
+			return TRACE_TYPE_PARTIAL_LINE;
+	}
+
 	/* Indentation */
-	if (trace->depth > 0)
-		for (i = 0; i < (trace->depth + 1) * TRACE_GRAPH_INDENT; i++) {
+	if (depth > 0)
+		for (i = 0; i < (depth + 1) * TRACE_GRAPH_INDENT; i++) {
 			ret = trace_seq_printf(s, " ");
 			if (!ret)
 				return TRACE_TYPE_PARTIAL_LINE;
 		}
 
 	/* The comment */
-	ret = trace_seq_printf(s, "/* %s", trace->buf);
+	ret = trace_seq_printf(s, "/* ");
 	if (!ret)
 		return TRACE_TYPE_PARTIAL_LINE;
 
-	if (ent->flags & TRACE_FLAG_CONT)
-		trace_seq_print_cont(s, iter);
+	switch (iter->ent->type) {
+	case TRACE_BPRINT:
+		ret = trace_print_bprintk_msg_only(iter);
+		if (ret != TRACE_TYPE_HANDLED)
+			return ret;
+		break;
+	case TRACE_PRINT:
+		ret = trace_print_printk_msg_only(iter);
+		if (ret != TRACE_TYPE_HANDLED)
+			return ret;
+		break;
+	default:
+		event = ftrace_find_event(ent->type);
+		if (!event)
+			return TRACE_TYPE_UNHANDLED;
+
+		ret = event->trace(iter, sym_flags);
+		if (ret != TRACE_TYPE_HANDLED)
+			return ret;
+	}
+
+	/* Strip ending newline */
+	if (s->buffer[s->len - 1] == '\n') {
+		s->buffer[s->len - 1] = '\0';
+		s->len--;
+	}
 
 	ret = trace_seq_printf(s, " */\n");
 	if (!ret)
@@ -678,62 +793,91 @@
 enum print_line_t
 print_graph_function(struct trace_iterator *iter)
 {
-	struct trace_seq *s = &iter->seq;
 	struct trace_entry *entry = iter->ent;
+	struct trace_seq *s = &iter->seq;
 
 	switch (entry->type) {
 	case TRACE_GRAPH_ENT: {
 		struct ftrace_graph_ent_entry *field;
 		trace_assign_type(field, entry);
-		return print_graph_entry(field, s, iter,
-					 iter->cpu);
+		return print_graph_entry(field, s, iter);
 	}
 	case TRACE_GRAPH_RET: {
 		struct ftrace_graph_ret_entry *field;
 		trace_assign_type(field, entry);
-		return print_graph_return(&field->ret, s, entry, iter->cpu);
-	}
-	case TRACE_PRINT: {
-		struct print_entry *field;
-		trace_assign_type(field, entry);
-		return print_graph_comment(field, s, entry, iter);
+		return print_graph_return(&field->ret, s, entry, iter);
 	}
 	default:
-		return TRACE_TYPE_UNHANDLED;
+		return print_graph_comment(s, entry, iter);
 	}
+
+	return TRACE_TYPE_HANDLED;
 }
 
 static void print_graph_headers(struct seq_file *s)
 {
 	/* 1st line */
 	seq_printf(s, "# ");
+	if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME)
+		seq_printf(s, "     TIME       ");
 	if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU)
-		seq_printf(s, "CPU ");
+		seq_printf(s, "CPU");
 	if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC)
-		seq_printf(s, "TASK/PID     ");
-	if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERHEAD)
-		seq_printf(s, "OVERHEAD/");
-	seq_printf(s, "DURATION            FUNCTION CALLS\n");
+		seq_printf(s, "  TASK/PID      ");
+	if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
+		seq_printf(s, "  DURATION   ");
+	seq_printf(s, "               FUNCTION CALLS\n");
 
 	/* 2nd line */
 	seq_printf(s, "# ");
+	if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME)
+		seq_printf(s, "      |         ");
 	if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU)
-		seq_printf(s, "|   ");
+		seq_printf(s, "|  ");
 	if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC)
-		seq_printf(s, "|      |     ");
-	if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERHEAD) {
-		seq_printf(s, "|        ");
-		seq_printf(s, "|                   |   |   |   |\n");
-	} else
-		seq_printf(s, "    |               |   |   |   |\n");
+		seq_printf(s, "  |    |        ");
+	if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
+		seq_printf(s, "   |   |      ");
+	seq_printf(s, "               |   |   |   |\n");
 }
+
+static void graph_trace_open(struct trace_iterator *iter)
+{
+	/* pid and depth on the last trace processed */
+	struct fgraph_data *data = alloc_percpu(struct fgraph_data);
+	int cpu;
+
+	if (!data)
+		pr_warning("function graph tracer: not enough memory\n");
+	else
+		for_each_possible_cpu(cpu) {
+			pid_t *pid = &(per_cpu_ptr(data, cpu)->last_pid);
+			int *depth = &(per_cpu_ptr(data, cpu)->depth);
+			*pid = -1;
+			*depth = 0;
+		}
+
+	iter->private = data;
+}
+
+static void graph_trace_close(struct trace_iterator *iter)
+{
+	free_percpu(iter->private);
+}
+
 static struct tracer graph_trace __read_mostly = {
-	.name	     	= "function_graph",
-	.init	     	= graph_trace_init,
-	.reset	     	= graph_trace_reset,
+	.name		= "function_graph",
+	.open		= graph_trace_open,
+	.close		= graph_trace_close,
+	.wait_pipe	= poll_wait_pipe,
+	.init		= graph_trace_init,
+	.reset		= graph_trace_reset,
 	.print_line	= print_graph_function,
 	.print_header	= print_graph_headers,
 	.flags		= &tracer_flags,
+#ifdef CONFIG_FTRACE_SELFTEST
+	.selftest	= trace_selftest_startup_function_graph,
+#endif
 };
 
 static __init int init_graph_trace(void)
diff --git a/kernel/trace/trace_hw_branches.c b/kernel/trace/trace_hw_branches.c
index 649df22..7bfdf4c 100644
--- a/kernel/trace/trace_hw_branches.c
+++ b/kernel/trace/trace_hw_branches.c
@@ -1,30 +1,53 @@
 /*
  * h/w branch tracer for x86 based on bts
  *
- * Copyright (C) 2008 Markus Metzger <markus.t.metzger@gmail.com>
- *
+ * Copyright (C) 2008-2009 Intel Corporation.
+ * Markus Metzger <markus.t.metzger@gmail.com>, 2008-2009
  */
-
-#include <linux/module.h>
-#include <linux/fs.h>
+#include <linux/spinlock.h>
+#include <linux/kallsyms.h>
 #include <linux/debugfs.h>
 #include <linux/ftrace.h>
-#include <linux/kallsyms.h>
+#include <linux/module.h>
+#include <linux/cpu.h>
+#include <linux/smp.h>
+#include <linux/fs.h>
 
 #include <asm/ds.h>
 
 #include "trace.h"
+#include "trace_output.h"
 
 
 #define SIZEOF_BTS (1 << 13)
 
+/*
+ * The tracer lock protects the below per-cpu tracer array.
+ * It needs to be held to:
+ * - start tracing on all cpus
+ * - stop tracing on all cpus
+ * - start tracing on a single hotplug cpu
+ * - stop tracing on a single hotplug cpu
+ * - read the trace from all cpus
+ * - read the trace from a single cpu
+ */
+static DEFINE_SPINLOCK(bts_tracer_lock);
 static DEFINE_PER_CPU(struct bts_tracer *, tracer);
 static DEFINE_PER_CPU(unsigned char[SIZEOF_BTS], buffer);
 
 #define this_tracer per_cpu(tracer, smp_processor_id())
 #define this_buffer per_cpu(buffer, smp_processor_id())
 
+static int __read_mostly trace_hw_branches_enabled;
+static struct trace_array *hw_branch_trace __read_mostly;
 
+
+/*
+ * Start tracing on the current cpu.
+ * The argument is ignored.
+ *
+ * pre: bts_tracer_lock must be locked.
+ */
 static void bts_trace_start_cpu(void *arg)
 {
 	if (this_tracer)
@@ -42,14 +65,20 @@
 
 static void bts_trace_start(struct trace_array *tr)
 {
-	int cpu;
+	spin_lock(&bts_tracer_lock);
 
-	tracing_reset_online_cpus(tr);
+	on_each_cpu(bts_trace_start_cpu, NULL, 1);
+	trace_hw_branches_enabled = 1;
 
-	for_each_cpu(cpu, cpu_possible_mask)
-		smp_call_function_single(cpu, bts_trace_start_cpu, NULL, 1);
+	spin_unlock(&bts_tracer_lock);
 }
 
+/*
+ * Stop tracing on the current cpu.
+ * The argument is ignored.
+ *
+ * pre: bts_tracer_lock must be locked.
+ */
 static void bts_trace_stop_cpu(void *arg)
 {
 	if (this_tracer) {
@@ -60,26 +89,60 @@
 
 static void bts_trace_stop(struct trace_array *tr)
 {
-	int cpu;
+	spin_lock(&bts_tracer_lock);
 
-	for_each_cpu(cpu, cpu_possible_mask)
-		smp_call_function_single(cpu, bts_trace_stop_cpu, NULL, 1);
+	trace_hw_branches_enabled = 0;
+	on_each_cpu(bts_trace_stop_cpu, NULL, 1);
+
+	spin_unlock(&bts_tracer_lock);
 }
 
+static int __cpuinit bts_hotcpu_handler(struct notifier_block *nfb,
+				     unsigned long action, void *hcpu)
+{
+	unsigned int cpu = (unsigned long)hcpu;
+
+	spin_lock(&bts_tracer_lock);
+
+	if (!trace_hw_branches_enabled)
+		goto out;
+
+	switch (action) {
+	case CPU_ONLINE:
+	case CPU_DOWN_FAILED:
+		smp_call_function_single(cpu, bts_trace_start_cpu, NULL, 1);
+		break;
+	case CPU_DOWN_PREPARE:
+		smp_call_function_single(cpu, bts_trace_stop_cpu, NULL, 1);
+		break;
+	}
+
+ out:
+	spin_unlock(&bts_tracer_lock);
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block bts_hotcpu_notifier __cpuinitdata = {
+	.notifier_call = bts_hotcpu_handler
+};
+
 static int bts_trace_init(struct trace_array *tr)
 {
-	tracing_reset_online_cpus(tr);
+	hw_branch_trace = tr;
+
 	bts_trace_start(tr);
 
 	return 0;
 }
 
+static void bts_trace_reset(struct trace_array *tr)
+{
+	bts_trace_stop(tr);
+}
+
 static void bts_trace_print_header(struct seq_file *m)
 {
-	seq_puts(m,
-		 "# CPU#        FROM                   TO         FUNCTION\n");
-	seq_puts(m,
-		 "#  |           |                     |             |\n");
+	seq_puts(m, "# CPU#        TO  <-  FROM\n");
 }
 
 static enum print_line_t bts_trace_print_line(struct trace_iterator *iter)
@@ -87,15 +150,15 @@
 	struct trace_entry *entry = iter->ent;
 	struct trace_seq *seq = &iter->seq;
 	struct hw_branch_entry *it;
+	unsigned long symflags = TRACE_ITER_SYM_OFFSET;
 
 	trace_assign_type(it, entry);
 
 	if (entry->type == TRACE_HW_BRANCHES) {
-		if (trace_seq_printf(seq, "%4d  ", entry->cpu) &&
-		    trace_seq_printf(seq, "0x%016llx -> 0x%016llx ",
-				     it->from, it->to) &&
-		    (!it->from ||
-		     seq_print_ip_sym(seq, it->from, /* sym_flags = */ 0)) &&
+		if (trace_seq_printf(seq, "%4d  ", iter->cpu) &&
+		    seq_print_ip_sym(seq, it->to, symflags) &&
+		    trace_seq_printf(seq, "\t  <-  ") &&
+		    seq_print_ip_sym(seq, it->from, symflags) &&
 		    trace_seq_printf(seq, "\n"))
 			return TRACE_TYPE_HANDLED;
 		return TRACE_TYPE_PARTIAL_LINE;;
@@ -103,26 +166,42 @@
 	return TRACE_TYPE_UNHANDLED;
 }
 
-void trace_hw_branch(struct trace_array *tr, u64 from, u64 to)
+void trace_hw_branch(u64 from, u64 to)
 {
+	struct trace_array *tr = hw_branch_trace;
 	struct ring_buffer_event *event;
 	struct hw_branch_entry *entry;
-	unsigned long irq;
+	unsigned long irq1;
+	int cpu;
 
-	event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry), &irq);
-	if (!event)
+	if (unlikely(!tr))
 		return;
+
+	if (unlikely(!trace_hw_branches_enabled))
+		return;
+
+	local_irq_save(irq1);
+	cpu = raw_smp_processor_id();
+	if (atomic_inc_return(&tr->data[cpu]->disabled) != 1)
+		goto out;
+
+	event = trace_buffer_lock_reserve(tr, TRACE_HW_BRANCHES,
+					  sizeof(*entry), 0, 0);
+	if (!event)
+		goto out;
 	entry	= ring_buffer_event_data(event);
 	tracing_generic_entry_update(&entry->ent, 0, from);
 	entry->ent.type = TRACE_HW_BRANCHES;
-	entry->ent.cpu = smp_processor_id();
 	entry->from = from;
 	entry->to   = to;
-	ring_buffer_unlock_commit(tr->buffer, event, irq);
+	trace_buffer_unlock_commit(tr, event, 0, 0);
+
+ out:
+	atomic_dec(&tr->data[cpu]->disabled);
+	local_irq_restore(irq1);
 }
 
-static void trace_bts_at(struct trace_array *tr,
-			 const struct bts_trace *trace, void *at)
+static void trace_bts_at(const struct bts_trace *trace, void *at)
 {
 	struct bts_struct bts;
 	int err = 0;
@@ -137,18 +216,29 @@
 
 	switch (bts.qualifier) {
 	case BTS_BRANCH:
-		trace_hw_branch(tr, bts.variant.lbr.from, bts.variant.lbr.to);
+		trace_hw_branch(bts.variant.lbr.from, bts.variant.lbr.to);
 		break;
 	}
 }
 
+/*
+ * Collect the trace on the current cpu and write it into the ftrace buffer.
+ *
+ * pre: bts_tracer_lock must be locked
+ */
 static void trace_bts_cpu(void *arg)
 {
 	struct trace_array *tr = (struct trace_array *) arg;
 	const struct bts_trace *trace;
 	unsigned char *at;
 
-	if (!this_tracer)
+	if (unlikely(!tr))
+		return;
+
+	if (unlikely(atomic_read(&tr->data[raw_smp_processor_id()]->disabled)))
+		return;
+
+	if (unlikely(!this_tracer))
 		return;
 
 	ds_suspend_bts(this_tracer);
@@ -158,11 +248,11 @@
 
 	for (at = trace->ds.top; (void *)at < trace->ds.end;
 	     at += trace->ds.size)
-		trace_bts_at(tr, trace, at);
+		trace_bts_at(trace, at);
 
 	for (at = trace->ds.begin; (void *)at < trace->ds.top;
 	     at += trace->ds.size)
-		trace_bts_at(tr, trace, at);
+		trace_bts_at(trace, at);
 
 out:
 	ds_resume_bts(this_tracer);
@@ -170,26 +260,43 @@
 
 static void trace_bts_prepare(struct trace_iterator *iter)
 {
-	int cpu;
+	spin_lock(&bts_tracer_lock);
 
-	for_each_cpu(cpu, cpu_possible_mask)
-		smp_call_function_single(cpu, trace_bts_cpu, iter->tr, 1);
+	on_each_cpu(trace_bts_cpu, iter->tr, 1);
+
+	spin_unlock(&bts_tracer_lock);
+}
+
+static void trace_bts_close(struct trace_iterator *iter)
+{
+	tracing_reset_online_cpus(iter->tr);
+}
+
+void trace_hw_branch_oops(void)
+{
+	spin_lock(&bts_tracer_lock);
+
+	trace_bts_cpu(hw_branch_trace);
+
+	spin_unlock(&bts_tracer_lock);
 }
 
 struct tracer bts_tracer __read_mostly =
 {
 	.name		= "hw-branch-tracer",
 	.init		= bts_trace_init,
-	.reset		= bts_trace_stop,
+	.reset		= bts_trace_reset,
 	.print_header	= bts_trace_print_header,
 	.print_line	= bts_trace_print_line,
 	.start		= bts_trace_start,
 	.stop		= bts_trace_stop,
-	.open		= trace_bts_prepare
+	.open		= trace_bts_prepare,
+	.close		= trace_bts_close
 };
 
 __init static int init_bts_trace(void)
 {
+	register_hotcpu_notifier(&bts_hotcpu_notifier);
 	return register_tracer(&bts_tracer);
 }
 device_initcall(init_bts_trace);
diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c
index 62a78d9..b923d13 100644
--- a/kernel/trace/trace_irqsoff.c
+++ b/kernel/trace/trace_irqsoff.c
@@ -1,5 +1,5 @@
 /*
- * trace irqs off criticall timings
+ * trace irqs off critical timings
  *
  * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
  * Copyright (C) 2008 Ingo Molnar <mingo@redhat.com>
@@ -32,6 +32,8 @@
 
 static int trace_type __read_mostly;
 
+static int save_lat_flag;
+
 #ifdef CONFIG_PREEMPT_TRACER
 static inline int
 preempt_trace(void)
@@ -95,7 +97,7 @@
 	disabled = atomic_inc_return(&data->disabled);
 
 	if (likely(disabled == 1))
-		trace_function(tr, data, ip, parent_ip, flags, preempt_count());
+		trace_function(tr, ip, parent_ip, flags, preempt_count());
 
 	atomic_dec(&data->disabled);
 }
@@ -153,7 +155,7 @@
 	if (!report_latency(delta))
 		goto out_unlock;
 
-	trace_function(tr, data, CALLER_ADDR0, parent_ip, flags, pc);
+	trace_function(tr, CALLER_ADDR0, parent_ip, flags, pc);
 
 	latency = nsecs_to_usecs(delta);
 
@@ -177,7 +179,7 @@
 	data->critical_sequence = max_sequence;
 	data->preempt_timestamp = ftrace_now(cpu);
 	tracing_reset(tr, cpu);
-	trace_function(tr, data, CALLER_ADDR0, parent_ip, flags, pc);
+	trace_function(tr, CALLER_ADDR0, parent_ip, flags, pc);
 }
 
 static inline void
@@ -210,7 +212,7 @@
 
 	local_save_flags(flags);
 
-	trace_function(tr, data, ip, parent_ip, flags, preempt_count());
+	trace_function(tr, ip, parent_ip, flags, preempt_count());
 
 	per_cpu(tracing_cpu, cpu) = 1;
 
@@ -244,7 +246,7 @@
 	atomic_inc(&data->disabled);
 
 	local_save_flags(flags);
-	trace_function(tr, data, ip, parent_ip, flags, preempt_count());
+	trace_function(tr, ip, parent_ip, flags, preempt_count());
 	check_critical_timing(tr, data, parent_ip ? : ip, cpu);
 	data->critical_start = 0;
 	atomic_dec(&data->disabled);
@@ -353,33 +355,26 @@
 }
 #endif /* CONFIG_PREEMPT_TRACER */
 
-/*
- * save_tracer_enabled is used to save the state of the tracer_enabled
- * variable when we disable it when we open a trace output file.
- */
-static int save_tracer_enabled;
-
 static void start_irqsoff_tracer(struct trace_array *tr)
 {
 	register_ftrace_function(&trace_ops);
-	if (tracing_is_enabled()) {
+	if (tracing_is_enabled())
 		tracer_enabled = 1;
-		save_tracer_enabled = 1;
-	} else {
+	else
 		tracer_enabled = 0;
-		save_tracer_enabled = 0;
-	}
 }
 
 static void stop_irqsoff_tracer(struct trace_array *tr)
 {
 	tracer_enabled = 0;
-	save_tracer_enabled = 0;
 	unregister_ftrace_function(&trace_ops);
 }
 
 static void __irqsoff_tracer_init(struct trace_array *tr)
 {
+	save_lat_flag = trace_flags & TRACE_ITER_LATENCY_FMT;
+	trace_flags |= TRACE_ITER_LATENCY_FMT;
+
 	tracing_max_latency = 0;
 	irqsoff_trace = tr;
 	/* make sure that the tracer is visible */
@@ -390,30 +385,19 @@
 static void irqsoff_tracer_reset(struct trace_array *tr)
 {
 	stop_irqsoff_tracer(tr);
+
+	if (!save_lat_flag)
+		trace_flags &= ~TRACE_ITER_LATENCY_FMT;
 }
 
 static void irqsoff_tracer_start(struct trace_array *tr)
 {
 	tracer_enabled = 1;
-	save_tracer_enabled = 1;
 }
 
 static void irqsoff_tracer_stop(struct trace_array *tr)
 {
 	tracer_enabled = 0;
-	save_tracer_enabled = 0;
-}
-
-static void irqsoff_tracer_open(struct trace_iterator *iter)
-{
-	/* stop the trace while dumping */
-	tracer_enabled = 0;
-}
-
-static void irqsoff_tracer_close(struct trace_iterator *iter)
-{
-	/* restart tracing */
-	tracer_enabled = save_tracer_enabled;
 }
 
 #ifdef CONFIG_IRQSOFF_TRACER
@@ -431,8 +415,6 @@
 	.reset		= irqsoff_tracer_reset,
 	.start		= irqsoff_tracer_start,
 	.stop		= irqsoff_tracer_stop,
-	.open		= irqsoff_tracer_open,
-	.close		= irqsoff_tracer_close,
 	.print_max	= 1,
 #ifdef CONFIG_FTRACE_SELFTEST
 	.selftest    = trace_selftest_startup_irqsoff,
@@ -459,8 +441,6 @@
 	.reset		= irqsoff_tracer_reset,
 	.start		= irqsoff_tracer_start,
 	.stop		= irqsoff_tracer_stop,
-	.open		= irqsoff_tracer_open,
-	.close		= irqsoff_tracer_close,
 	.print_max	= 1,
 #ifdef CONFIG_FTRACE_SELFTEST
 	.selftest    = trace_selftest_startup_preemptoff,
@@ -489,8 +469,6 @@
 	.reset		= irqsoff_tracer_reset,
 	.start		= irqsoff_tracer_start,
 	.stop		= irqsoff_tracer_stop,
-	.open		= irqsoff_tracer_open,
-	.close		= irqsoff_tracer_close,
 	.print_max	= 1,
 #ifdef CONFIG_FTRACE_SELFTEST
 	.selftest    = trace_selftest_startup_preemptirqsoff,
diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c
index 80e503e..8e37fcd 100644
--- a/kernel/trace/trace_mmiotrace.c
+++ b/kernel/trace/trace_mmiotrace.c
@@ -12,6 +12,7 @@
 #include <asm/atomic.h>
 
 #include "trace.h"
+#include "trace_output.h"
 
 struct header_iter {
 	struct pci_dev *dev;
@@ -183,21 +184,22 @@
 	switch (rw->opcode) {
 	case MMIO_READ:
 		ret = trace_seq_printf(s,
-			"R %d %lu.%06lu %d 0x%llx 0x%lx 0x%lx %d\n",
+			"R %d %u.%06lu %d 0x%llx 0x%lx 0x%lx %d\n",
 			rw->width, secs, usec_rem, rw->map_id,
 			(unsigned long long)rw->phys,
 			rw->value, rw->pc, 0);
 		break;
 	case MMIO_WRITE:
 		ret = trace_seq_printf(s,
-			"W %d %lu.%06lu %d 0x%llx 0x%lx 0x%lx %d\n",
+			"W %d %u.%06lu %d 0x%llx 0x%lx 0x%lx %d\n",
 			rw->width, secs, usec_rem, rw->map_id,
 			(unsigned long long)rw->phys,
 			rw->value, rw->pc, 0);
 		break;
 	case MMIO_UNKNOWN_OP:
 		ret = trace_seq_printf(s,
-			"UNKNOWN %lu.%06lu %d 0x%llx %02x,%02x,%02x 0x%lx %d\n",
+			"UNKNOWN %u.%06lu %d 0x%llx %02lx,%02lx,"
+			"%02lx 0x%lx %d\n",
 			secs, usec_rem, rw->map_id,
 			(unsigned long long)rw->phys,
 			(rw->value >> 16) & 0xff, (rw->value >> 8) & 0xff,
@@ -229,14 +231,14 @@
 	switch (m->opcode) {
 	case MMIO_PROBE:
 		ret = trace_seq_printf(s,
-			"MAP %lu.%06lu %d 0x%llx 0x%lx 0x%lx 0x%lx %d\n",
+			"MAP %u.%06lu %d 0x%llx 0x%lx 0x%lx 0x%lx %d\n",
 			secs, usec_rem, m->map_id,
 			(unsigned long long)m->phys, m->virt, m->len,
 			0UL, 0);
 		break;
 	case MMIO_UNPROBE:
 		ret = trace_seq_printf(s,
-			"UNMAP %lu.%06lu %d 0x%lx %d\n",
+			"UNMAP %u.%06lu %d 0x%lx %d\n",
 			secs, usec_rem, m->map_id, 0UL, 0);
 		break;
 	default:
@@ -255,18 +257,15 @@
 	const char *msg		= print->buf;
 	struct trace_seq *s	= &iter->seq;
 	unsigned long long t	= ns2usecs(iter->ts);
-	unsigned long usec_rem	= do_div(t, 1000000ULL);
+	unsigned long usec_rem	= do_div(t, USEC_PER_SEC);
 	unsigned secs		= (unsigned long)t;
 	int ret;
 
 	/* The trailing newline must be in the message. */
-	ret = trace_seq_printf(s, "MARK %lu.%06lu %s", secs, usec_rem, msg);
+	ret = trace_seq_printf(s, "MARK %u.%06lu %s", secs, usec_rem, msg);
 	if (!ret)
 		return TRACE_TYPE_PARTIAL_LINE;
 
-	if (entry->flags & TRACE_FLAG_CONT)
-		trace_seq_print_cont(s, iter);
-
 	return TRACE_TYPE_HANDLED;
 }
 
@@ -308,21 +307,17 @@
 {
 	struct ring_buffer_event *event;
 	struct trace_mmiotrace_rw *entry;
-	unsigned long irq_flags;
+	int pc = preempt_count();
 
-	event	= ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
-					   &irq_flags);
+	event = trace_buffer_lock_reserve(tr, TRACE_MMIO_RW,
+					  sizeof(*entry), 0, pc);
 	if (!event) {
 		atomic_inc(&dropped_count);
 		return;
 	}
 	entry	= ring_buffer_event_data(event);
-	tracing_generic_entry_update(&entry->ent, 0, preempt_count());
-	entry->ent.type			= TRACE_MMIO_RW;
 	entry->rw			= *rw;
-	ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
-
-	trace_wake_up();
+	trace_buffer_unlock_commit(tr, event, 0, pc);
 }
 
 void mmio_trace_rw(struct mmiotrace_rw *rw)
@@ -338,21 +333,17 @@
 {
 	struct ring_buffer_event *event;
 	struct trace_mmiotrace_map *entry;
-	unsigned long irq_flags;
+	int pc = preempt_count();
 
-	event	= ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
-					   &irq_flags);
+	event = trace_buffer_lock_reserve(tr, TRACE_MMIO_MAP,
+					  sizeof(*entry), 0, pc);
 	if (!event) {
 		atomic_inc(&dropped_count);
 		return;
 	}
 	entry	= ring_buffer_event_data(event);
-	tracing_generic_entry_update(&entry->ent, 0, preempt_count());
-	entry->ent.type			= TRACE_MMIO_MAP;
 	entry->map			= *map;
-	ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
-
-	trace_wake_up();
+	trace_buffer_unlock_commit(tr, event, 0, pc);
 }
 
 void mmio_trace_mapping(struct mmiotrace_map *map)
@@ -368,5 +359,5 @@
 
 int mmio_trace_printk(const char *fmt, va_list args)
 {
-	return trace_vprintk(0, -1, fmt, args);
+	return trace_vprintk(0, fmt, args);
 }
diff --git a/kernel/trace/trace_nop.c b/kernel/trace/trace_nop.c
index b9767ac..394f944 100644
--- a/kernel/trace/trace_nop.c
+++ b/kernel/trace/trace_nop.c
@@ -47,12 +47,7 @@
 
 static int nop_trace_init(struct trace_array *tr)
 {
-	int cpu;
 	ctx_trace = tr;
-
-	for_each_online_cpu(cpu)
-		tracing_reset(tr, cpu);
-
 	start_nop_trace(tr);
 	return 0;
 }
@@ -96,6 +91,7 @@
 	.name		= "nop",
 	.init		= nop_trace_init,
 	.reset		= nop_trace_reset,
+	.wait_pipe	= poll_wait_pipe,
 #ifdef CONFIG_FTRACE_SELFTEST
 	.selftest	= trace_selftest_startup_nop,
 #endif
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c
new file mode 100644
index 0000000..d72b9a63
--- /dev/null
+++ b/kernel/trace/trace_output.c
@@ -0,0 +1,1017 @@
+/*
+ * trace_output.c
+ *
+ * Copyright (C) 2008 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/ftrace.h>
+
+#include "trace_output.h"
+
+/* must be a power of 2 */
+#define EVENT_HASHSIZE	128
+
+static DEFINE_MUTEX(trace_event_mutex);
+static struct hlist_head event_hash[EVENT_HASHSIZE] __read_mostly;
+
+static int next_event_type = __TRACE_LAST_TYPE + 1;
+
+enum print_line_t trace_print_bprintk_msg_only(struct trace_iterator *iter)
+{
+	struct trace_seq *s = &iter->seq;
+	struct trace_entry *entry = iter->ent;
+	struct bprint_entry *field;
+	int ret;
+
+	trace_assign_type(field, entry);
+
+	ret = trace_seq_bprintf(s, field->fmt, field->buf);
+	if (!ret)
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	return TRACE_TYPE_HANDLED;
+}
+
+enum print_line_t trace_print_printk_msg_only(struct trace_iterator *iter)
+{
+	struct trace_seq *s = &iter->seq;
+	struct trace_entry *entry = iter->ent;
+	struct print_entry *field;
+	int ret;
+
+	trace_assign_type(field, entry);
+
+	ret = trace_seq_printf(s, "%s", field->buf);
+	if (!ret)
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	return TRACE_TYPE_HANDLED;
+}
+
+/**
+ * trace_seq_printf - sequence printing of trace information
+ * @s: trace sequence descriptor
+ * @fmt: printf format string
+ *
+ * The tracer may use either sequence operations or its own
+ * copy to user routines. To simplify formating of a trace
+ * trace_seq_printf is used to store strings into a special
+ * buffer (@s). Then the output may be either used by
+ * the sequencer or pulled into another buffer.
+ */
+int
+trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
+{
+	int len = (PAGE_SIZE - 1) - s->len;
+	va_list ap;
+	int ret;
+
+	if (!len)
+		return 0;
+
+	va_start(ap, fmt);
+	ret = vsnprintf(s->buffer + s->len, len, fmt, ap);
+	va_end(ap);
+
+	/* If we can't write it all, don't bother writing anything */
+	if (ret >= len)
+		return 0;
+
+	s->len += ret;
+
+	return len;
+}
+
+int trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary)
+{
+	int len = (PAGE_SIZE - 1) - s->len;
+	int ret;
+
+	if (!len)
+		return 0;
+
+	ret = bstr_printf(s->buffer + s->len, len, fmt, binary);
+
+	/* If we can't write it all, don't bother writing anything */
+	if (ret >= len)
+		return 0;
+
+	s->len += ret;
+
+	return len;
+}
+
+/**
+ * trace_seq_puts - trace sequence printing of simple string
+ * @s: trace sequence descriptor
+ * @str: simple string to record
+ *
+ * The tracer may use either the sequence operations or its own
+ * copy to user routines. This function records a simple string
+ * into a special buffer (@s) for later retrieval by a sequencer
+ * or other mechanism.
+ */
+int trace_seq_puts(struct trace_seq *s, const char *str)
+{
+	int len = strlen(str);
+
+	if (len > ((PAGE_SIZE - 1) - s->len))
+		return 0;
+
+	memcpy(s->buffer + s->len, str, len);
+	s->len += len;
+
+	return len;
+}
+
+int trace_seq_putc(struct trace_seq *s, unsigned char c)
+{
+	if (s->len >= (PAGE_SIZE - 1))
+		return 0;
+
+	s->buffer[s->len++] = c;
+
+	return 1;
+}
+
+int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len)
+{
+	if (len > ((PAGE_SIZE - 1) - s->len))
+		return 0;
+
+	memcpy(s->buffer + s->len, mem, len);
+	s->len += len;
+
+	return len;
+}
+
+int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, size_t len)
+{
+	unsigned char hex[HEX_CHARS];
+	const unsigned char *data = mem;
+	int i, j;
+
+#ifdef __BIG_ENDIAN
+	for (i = 0, j = 0; i < len; i++) {
+#else
+	for (i = len-1, j = 0; i >= 0; i--) {
+#endif
+		hex[j++] = hex_asc_hi(data[i]);
+		hex[j++] = hex_asc_lo(data[i]);
+	}
+	hex[j++] = ' ';
+
+	return trace_seq_putmem(s, hex, j);
+}
+
+void *trace_seq_reserve(struct trace_seq *s, size_t len)
+{
+	void *ret;
+
+	if (len > ((PAGE_SIZE - 1) - s->len))
+		return NULL;
+
+	ret = s->buffer + s->len;
+	s->len += len;
+
+	return ret;
+}
+
+int trace_seq_path(struct trace_seq *s, struct path *path)
+{
+	unsigned char *p;
+
+	if (s->len >= (PAGE_SIZE - 1))
+		return 0;
+	p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len);
+	if (!IS_ERR(p)) {
+		p = mangle_path(s->buffer + s->len, p, "\n");
+		if (p) {
+			s->len = p - s->buffer;
+			return 1;
+		}
+	} else {
+		s->buffer[s->len++] = '?';
+		return 1;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_KRETPROBES
+static inline const char *kretprobed(const char *name)
+{
+	static const char tramp_name[] = "kretprobe_trampoline";
+	int size = sizeof(tramp_name);
+
+	if (strncmp(tramp_name, name, size) == 0)
+		return "[unknown/kretprobe'd]";
+	return name;
+}
+#else
+static inline const char *kretprobed(const char *name)
+{
+	return name;
+}
+#endif /* CONFIG_KRETPROBES */
+
+static int
+seq_print_sym_short(struct trace_seq *s, const char *fmt, unsigned long address)
+{
+#ifdef CONFIG_KALLSYMS
+	char str[KSYM_SYMBOL_LEN];
+	const char *name;
+
+	kallsyms_lookup(address, NULL, NULL, NULL, str);
+
+	name = kretprobed(str);
+
+	return trace_seq_printf(s, fmt, name);
+#endif
+	return 1;
+}
+
+static int
+seq_print_sym_offset(struct trace_seq *s, const char *fmt,
+		     unsigned long address)
+{
+#ifdef CONFIG_KALLSYMS
+	char str[KSYM_SYMBOL_LEN];
+	const char *name;
+
+	sprint_symbol(str, address);
+	name = kretprobed(str);
+
+	return trace_seq_printf(s, fmt, name);
+#endif
+	return 1;
+}
+
+#ifndef CONFIG_64BIT
+# define IP_FMT "%08lx"
+#else
+# define IP_FMT "%016lx"
+#endif
+
+int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm,
+		      unsigned long ip, unsigned long sym_flags)
+{
+	struct file *file = NULL;
+	unsigned long vmstart = 0;
+	int ret = 1;
+
+	if (mm) {
+		const struct vm_area_struct *vma;
+
+		down_read(&mm->mmap_sem);
+		vma = find_vma(mm, ip);
+		if (vma) {
+			file = vma->vm_file;
+			vmstart = vma->vm_start;
+		}
+		if (file) {
+			ret = trace_seq_path(s, &file->f_path);
+			if (ret)
+				ret = trace_seq_printf(s, "[+0x%lx]",
+						       ip - vmstart);
+		}
+		up_read(&mm->mmap_sem);
+	}
+	if (ret && ((sym_flags & TRACE_ITER_SYM_ADDR) || !file))
+		ret = trace_seq_printf(s, " <" IP_FMT ">", ip);
+	return ret;
+}
+
+int
+seq_print_userip_objs(const struct userstack_entry *entry, struct trace_seq *s,
+		      unsigned long sym_flags)
+{
+	struct mm_struct *mm = NULL;
+	int ret = 1;
+	unsigned int i;
+
+	if (trace_flags & TRACE_ITER_SYM_USEROBJ) {
+		struct task_struct *task;
+		/*
+		 * we do the lookup on the thread group leader,
+		 * since individual threads might have already quit!
+		 */
+		rcu_read_lock();
+		task = find_task_by_vpid(entry->ent.tgid);
+		if (task)
+			mm = get_task_mm(task);
+		rcu_read_unlock();
+	}
+
+	for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
+		unsigned long ip = entry->caller[i];
+
+		if (ip == ULONG_MAX || !ret)
+			break;
+		if (i && ret)
+			ret = trace_seq_puts(s, " <- ");
+		if (!ip) {
+			if (ret)
+				ret = trace_seq_puts(s, "??");
+			continue;
+		}
+		if (!ret)
+			break;
+		if (ret)
+			ret = seq_print_user_ip(s, mm, ip, sym_flags);
+	}
+
+	if (mm)
+		mmput(mm);
+	return ret;
+}
+
+int
+seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags)
+{
+	int ret;
+
+	if (!ip)
+		return trace_seq_printf(s, "0");
+
+	if (sym_flags & TRACE_ITER_SYM_OFFSET)
+		ret = seq_print_sym_offset(s, "%s", ip);
+	else
+		ret = seq_print_sym_short(s, "%s", ip);
+
+	if (!ret)
+		return 0;
+
+	if (sym_flags & TRACE_ITER_SYM_ADDR)
+		ret = trace_seq_printf(s, " <" IP_FMT ">", ip);
+	return ret;
+}
+
+static int
+lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
+{
+	int hardirq, softirq;
+	char comm[TASK_COMM_LEN];
+
+	trace_find_cmdline(entry->pid, comm);
+	hardirq = entry->flags & TRACE_FLAG_HARDIRQ;
+	softirq = entry->flags & TRACE_FLAG_SOFTIRQ;
+
+	if (!trace_seq_printf(s, "%8.8s-%-5d %3d%c%c%c",
+			      comm, entry->pid, cpu,
+			      (entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
+				(entry->flags & TRACE_FLAG_IRQS_NOSUPPORT) ?
+				  'X' : '.',
+			      (entry->flags & TRACE_FLAG_NEED_RESCHED) ?
+				'N' : '.',
+			      (hardirq && softirq) ? 'H' :
+				hardirq ? 'h' : softirq ? 's' : '.'))
+		return 0;
+
+	if (entry->preempt_count)
+		return trace_seq_printf(s, "%x", entry->preempt_count);
+	return trace_seq_puts(s, ".");
+}
+
+static unsigned long preempt_mark_thresh = 100;
+
+static int
+lat_print_timestamp(struct trace_seq *s, u64 abs_usecs,
+		    unsigned long rel_usecs)
+{
+	return trace_seq_printf(s, " %4lldus%c: ", abs_usecs,
+				rel_usecs > preempt_mark_thresh ? '!' :
+				  rel_usecs > 1 ? '+' : ' ');
+}
+
+int trace_print_context(struct trace_iterator *iter)
+{
+	struct trace_seq *s = &iter->seq;
+	struct trace_entry *entry = iter->ent;
+	unsigned long long t = ns2usecs(iter->ts);
+	unsigned long usec_rem = do_div(t, USEC_PER_SEC);
+	unsigned long secs = (unsigned long)t;
+	char comm[TASK_COMM_LEN];
+
+	trace_find_cmdline(entry->pid, comm);
+
+	return trace_seq_printf(s, "%16s-%-5d [%03d] %5lu.%06lu: ",
+				comm, entry->pid, iter->cpu, secs, usec_rem);
+}
+
+int trace_print_lat_context(struct trace_iterator *iter)
+{
+	u64 next_ts;
+	int ret;
+	struct trace_seq *s = &iter->seq;
+	struct trace_entry *entry = iter->ent,
+			   *next_entry = trace_find_next_entry(iter, NULL,
+							       &next_ts);
+	unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE);
+	unsigned long abs_usecs = ns2usecs(iter->ts - iter->tr->time_start);
+	unsigned long rel_usecs;
+
+	if (!next_entry)
+		next_ts = iter->ts;
+	rel_usecs = ns2usecs(next_ts - iter->ts);
+
+	if (verbose) {
+		char comm[TASK_COMM_LEN];
+
+		trace_find_cmdline(entry->pid, comm);
+
+		ret = trace_seq_printf(s, "%16s %5d %3d %d %08x %08lx [%08lx]"
+				       " %ld.%03ldms (+%ld.%03ldms): ", comm,
+				       entry->pid, iter->cpu, entry->flags,
+				       entry->preempt_count, iter->idx,
+				       ns2usecs(iter->ts),
+				       abs_usecs / USEC_PER_MSEC,
+				       abs_usecs % USEC_PER_MSEC,
+				       rel_usecs / USEC_PER_MSEC,
+				       rel_usecs % USEC_PER_MSEC);
+	} else {
+		ret = lat_print_generic(s, entry, iter->cpu);
+		if (ret)
+			ret = lat_print_timestamp(s, abs_usecs, rel_usecs);
+	}
+
+	return ret;
+}
+
+static const char state_to_char[] = TASK_STATE_TO_CHAR_STR;
+
+static int task_state_char(unsigned long state)
+{
+	int bit = state ? __ffs(state) + 1 : 0;
+
+	return bit < sizeof(state_to_char) - 1 ? state_to_char[bit] : '?';
+}
+
+/**
+ * ftrace_find_event - find a registered event
+ * @type: the type of event to look for
+ *
+ * Returns an event of type @type otherwise NULL
+ */
+struct trace_event *ftrace_find_event(int type)
+{
+	struct trace_event *event;
+	struct hlist_node *n;
+	unsigned key;
+
+	key = type & (EVENT_HASHSIZE - 1);
+
+	hlist_for_each_entry_rcu(event, n, &event_hash[key], node) {
+		if (event->type == type)
+			return event;
+	}
+
+	return NULL;
+}
+
+/**
+ * register_ftrace_event - register output for an event type
+ * @event: the event type to register
+ *
+ * Event types are stored in a hash and this hash is used to
+ * find a way to print an event. If the @event->type is set
+ * then it will use that type, otherwise it will assign a
+ * type to use.
+ *
+ * If you assign your own type, please make sure it is added
+ * to the trace_type enum in trace.h, to avoid collisions
+ * with the dynamic types.
+ *
+ * Returns the event type number or zero on error.
+ */
+int register_ftrace_event(struct trace_event *event)
+{
+	unsigned key;
+	int ret = 0;
+
+	mutex_lock(&trace_event_mutex);
+
+	if (!event) {
+		ret = next_event_type++;
+		goto out;
+	}
+
+	if (!event->type)
+		event->type = next_event_type++;
+	else if (event->type > __TRACE_LAST_TYPE) {
+		printk(KERN_WARNING "Need to add type to trace.h\n");
+		WARN_ON(1);
+	}
+
+	if (ftrace_find_event(event->type))
+		goto out;
+
+	if (event->trace == NULL)
+		event->trace = trace_nop_print;
+	if (event->raw == NULL)
+		event->raw = trace_nop_print;
+	if (event->hex == NULL)
+		event->hex = trace_nop_print;
+	if (event->binary == NULL)
+		event->binary = trace_nop_print;
+
+	key = event->type & (EVENT_HASHSIZE - 1);
+
+	hlist_add_head_rcu(&event->node, &event_hash[key]);
+
+	ret = event->type;
+ out:
+	mutex_unlock(&trace_event_mutex);
+
+	return ret;
+}
+
+/**
+ * unregister_ftrace_event - remove a no longer used event
+ * @event: the event to remove
+ */
+int unregister_ftrace_event(struct trace_event *event)
+{
+	mutex_lock(&trace_event_mutex);
+	hlist_del(&event->node);
+	mutex_unlock(&trace_event_mutex);
+
+	return 0;
+}
+
+/*
+ * Standard events
+ */
+
+enum print_line_t trace_nop_print(struct trace_iterator *iter, int flags)
+{
+	return TRACE_TYPE_HANDLED;
+}
+
+/* TRACE_FN */
+static enum print_line_t trace_fn_trace(struct trace_iterator *iter, int flags)
+{
+	struct ftrace_entry *field;
+	struct trace_seq *s = &iter->seq;
+
+	trace_assign_type(field, iter->ent);
+
+	if (!seq_print_ip_sym(s, field->ip, flags))
+		goto partial;
+
+	if ((flags & TRACE_ITER_PRINT_PARENT) && field->parent_ip) {
+		if (!trace_seq_printf(s, " <-"))
+			goto partial;
+		if (!seq_print_ip_sym(s,
+				      field->parent_ip,
+				      flags))
+			goto partial;
+	}
+	if (!trace_seq_printf(s, "\n"))
+		goto partial;
+
+	return TRACE_TYPE_HANDLED;
+
+ partial:
+	return TRACE_TYPE_PARTIAL_LINE;
+}
+
+static enum print_line_t trace_fn_raw(struct trace_iterator *iter, int flags)
+{
+	struct ftrace_entry *field;
+
+	trace_assign_type(field, iter->ent);
+
+	if (!trace_seq_printf(&iter->seq, "%lx %lx\n",
+			      field->ip,
+			      field->parent_ip))
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	return TRACE_TYPE_HANDLED;
+}
+
+static enum print_line_t trace_fn_hex(struct trace_iterator *iter, int flags)
+{
+	struct ftrace_entry *field;
+	struct trace_seq *s = &iter->seq;
+
+	trace_assign_type(field, iter->ent);
+
+	SEQ_PUT_HEX_FIELD_RET(s, field->ip);
+	SEQ_PUT_HEX_FIELD_RET(s, field->parent_ip);
+
+	return TRACE_TYPE_HANDLED;
+}
+
+static enum print_line_t trace_fn_bin(struct trace_iterator *iter, int flags)
+{
+	struct ftrace_entry *field;
+	struct trace_seq *s = &iter->seq;
+
+	trace_assign_type(field, iter->ent);
+
+	SEQ_PUT_FIELD_RET(s, field->ip);
+	SEQ_PUT_FIELD_RET(s, field->parent_ip);
+
+	return TRACE_TYPE_HANDLED;
+}
+
+static struct trace_event trace_fn_event = {
+	.type		= TRACE_FN,
+	.trace		= trace_fn_trace,
+	.raw		= trace_fn_raw,
+	.hex		= trace_fn_hex,
+	.binary		= trace_fn_bin,
+};
+
+/* TRACE_CTX an TRACE_WAKE */
+static enum print_line_t trace_ctxwake_print(struct trace_iterator *iter,
+					     char *delim)
+{
+	struct ctx_switch_entry *field;
+	char comm[TASK_COMM_LEN];
+	int S, T;
+
+
+	trace_assign_type(field, iter->ent);
+
+	T = task_state_char(field->next_state);
+	S = task_state_char(field->prev_state);
+	trace_find_cmdline(field->next_pid, comm);
+	if (!trace_seq_printf(&iter->seq,
+			      " %5d:%3d:%c %s [%03d] %5d:%3d:%c %s\n",
+			      field->prev_pid,
+			      field->prev_prio,
+			      S, delim,
+			      field->next_cpu,
+			      field->next_pid,
+			      field->next_prio,
+			      T, comm))
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	return TRACE_TYPE_HANDLED;
+}
+
+static enum print_line_t trace_ctx_print(struct trace_iterator *iter, int flags)
+{
+	return trace_ctxwake_print(iter, "==>");
+}
+
+static enum print_line_t trace_wake_print(struct trace_iterator *iter,
+					  int flags)
+{
+	return trace_ctxwake_print(iter, "  +");
+}
+
+static int trace_ctxwake_raw(struct trace_iterator *iter, char S)
+{
+	struct ctx_switch_entry *field;
+	int T;
+
+	trace_assign_type(field, iter->ent);
+
+	if (!S)
+		task_state_char(field->prev_state);
+	T = task_state_char(field->next_state);
+	if (!trace_seq_printf(&iter->seq, "%d %d %c %d %d %d %c\n",
+			      field->prev_pid,
+			      field->prev_prio,
+			      S,
+			      field->next_cpu,
+			      field->next_pid,
+			      field->next_prio,
+			      T))
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	return TRACE_TYPE_HANDLED;
+}
+
+static enum print_line_t trace_ctx_raw(struct trace_iterator *iter, int flags)
+{
+	return trace_ctxwake_raw(iter, 0);
+}
+
+static enum print_line_t trace_wake_raw(struct trace_iterator *iter, int flags)
+{
+	return trace_ctxwake_raw(iter, '+');
+}
+
+
+static int trace_ctxwake_hex(struct trace_iterator *iter, char S)
+{
+	struct ctx_switch_entry *field;
+	struct trace_seq *s = &iter->seq;
+	int T;
+
+	trace_assign_type(field, iter->ent);
+
+	if (!S)
+		task_state_char(field->prev_state);
+	T = task_state_char(field->next_state);
+
+	SEQ_PUT_HEX_FIELD_RET(s, field->prev_pid);
+	SEQ_PUT_HEX_FIELD_RET(s, field->prev_prio);
+	SEQ_PUT_HEX_FIELD_RET(s, S);
+	SEQ_PUT_HEX_FIELD_RET(s, field->next_cpu);
+	SEQ_PUT_HEX_FIELD_RET(s, field->next_pid);
+	SEQ_PUT_HEX_FIELD_RET(s, field->next_prio);
+	SEQ_PUT_HEX_FIELD_RET(s, T);
+
+	return TRACE_TYPE_HANDLED;
+}
+
+static enum print_line_t trace_ctx_hex(struct trace_iterator *iter, int flags)
+{
+	return trace_ctxwake_hex(iter, 0);
+}
+
+static enum print_line_t trace_wake_hex(struct trace_iterator *iter, int flags)
+{
+	return trace_ctxwake_hex(iter, '+');
+}
+
+static enum print_line_t trace_ctxwake_bin(struct trace_iterator *iter,
+					   int flags)
+{
+	struct ctx_switch_entry *field;
+	struct trace_seq *s = &iter->seq;
+
+	trace_assign_type(field, iter->ent);
+
+	SEQ_PUT_FIELD_RET(s, field->prev_pid);
+	SEQ_PUT_FIELD_RET(s, field->prev_prio);
+	SEQ_PUT_FIELD_RET(s, field->prev_state);
+	SEQ_PUT_FIELD_RET(s, field->next_pid);
+	SEQ_PUT_FIELD_RET(s, field->next_prio);
+	SEQ_PUT_FIELD_RET(s, field->next_state);
+
+	return TRACE_TYPE_HANDLED;
+}
+
+static struct trace_event trace_ctx_event = {
+	.type		= TRACE_CTX,
+	.trace		= trace_ctx_print,
+	.raw		= trace_ctx_raw,
+	.hex		= trace_ctx_hex,
+	.binary		= trace_ctxwake_bin,
+};
+
+static struct trace_event trace_wake_event = {
+	.type		= TRACE_WAKE,
+	.trace		= trace_wake_print,
+	.raw		= trace_wake_raw,
+	.hex		= trace_wake_hex,
+	.binary		= trace_ctxwake_bin,
+};
+
+/* TRACE_SPECIAL */
+static enum print_line_t trace_special_print(struct trace_iterator *iter,
+					     int flags)
+{
+	struct special_entry *field;
+
+	trace_assign_type(field, iter->ent);
+
+	if (!trace_seq_printf(&iter->seq, "# %ld %ld %ld\n",
+			      field->arg1,
+			      field->arg2,
+			      field->arg3))
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	return TRACE_TYPE_HANDLED;
+}
+
+static enum print_line_t trace_special_hex(struct trace_iterator *iter,
+					   int flags)
+{
+	struct special_entry *field;
+	struct trace_seq *s = &iter->seq;
+
+	trace_assign_type(field, iter->ent);
+
+	SEQ_PUT_HEX_FIELD_RET(s, field->arg1);
+	SEQ_PUT_HEX_FIELD_RET(s, field->arg2);
+	SEQ_PUT_HEX_FIELD_RET(s, field->arg3);
+
+	return TRACE_TYPE_HANDLED;
+}
+
+static enum print_line_t trace_special_bin(struct trace_iterator *iter,
+					   int flags)
+{
+	struct special_entry *field;
+	struct trace_seq *s = &iter->seq;
+
+	trace_assign_type(field, iter->ent);
+
+	SEQ_PUT_FIELD_RET(s, field->arg1);
+	SEQ_PUT_FIELD_RET(s, field->arg2);
+	SEQ_PUT_FIELD_RET(s, field->arg3);
+
+	return TRACE_TYPE_HANDLED;
+}
+
+static struct trace_event trace_special_event = {
+	.type		= TRACE_SPECIAL,
+	.trace		= trace_special_print,
+	.raw		= trace_special_print,
+	.hex		= trace_special_hex,
+	.binary		= trace_special_bin,
+};
+
+/* TRACE_STACK */
+
+static enum print_line_t trace_stack_print(struct trace_iterator *iter,
+					   int flags)
+{
+	struct stack_entry *field;
+	struct trace_seq *s = &iter->seq;
+	int i;
+
+	trace_assign_type(field, iter->ent);
+
+	for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
+		if (i) {
+			if (!trace_seq_puts(s, " <= "))
+				goto partial;
+
+			if (!seq_print_ip_sym(s, field->caller[i], flags))
+				goto partial;
+		}
+		if (!trace_seq_puts(s, "\n"))
+			goto partial;
+	}
+
+	return TRACE_TYPE_HANDLED;
+
+ partial:
+	return TRACE_TYPE_PARTIAL_LINE;
+}
+
+static struct trace_event trace_stack_event = {
+	.type		= TRACE_STACK,
+	.trace		= trace_stack_print,
+	.raw		= trace_special_print,
+	.hex		= trace_special_hex,
+	.binary		= trace_special_bin,
+};
+
+/* TRACE_USER_STACK */
+static enum print_line_t trace_user_stack_print(struct trace_iterator *iter,
+						int flags)
+{
+	struct userstack_entry *field;
+	struct trace_seq *s = &iter->seq;
+
+	trace_assign_type(field, iter->ent);
+
+	if (!seq_print_userip_objs(field, s, flags))
+		goto partial;
+
+	if (!trace_seq_putc(s, '\n'))
+		goto partial;
+
+	return TRACE_TYPE_HANDLED;
+
+ partial:
+	return TRACE_TYPE_PARTIAL_LINE;
+}
+
+static struct trace_event trace_user_stack_event = {
+	.type		= TRACE_USER_STACK,
+	.trace		= trace_user_stack_print,
+	.raw		= trace_special_print,
+	.hex		= trace_special_hex,
+	.binary		= trace_special_bin,
+};
+
+/* TRACE_BPRINT */
+static enum print_line_t
+trace_bprint_print(struct trace_iterator *iter, int flags)
+{
+	struct trace_entry *entry = iter->ent;
+	struct trace_seq *s = &iter->seq;
+	struct bprint_entry *field;
+
+	trace_assign_type(field, entry);
+
+	if (!seq_print_ip_sym(s, field->ip, flags))
+		goto partial;
+
+	if (!trace_seq_puts(s, ": "))
+		goto partial;
+
+	if (!trace_seq_bprintf(s, field->fmt, field->buf))
+		goto partial;
+
+	return TRACE_TYPE_HANDLED;
+
+ partial:
+	return TRACE_TYPE_PARTIAL_LINE;
+}
+
+
+static enum print_line_t
+trace_bprint_raw(struct trace_iterator *iter, int flags)
+{
+	struct bprint_entry *field;
+	struct trace_seq *s = &iter->seq;
+
+	trace_assign_type(field, iter->ent);
+
+	if (!trace_seq_printf(s, ": %lx : ", field->ip))
+		goto partial;
+
+	if (!trace_seq_bprintf(s, field->fmt, field->buf))
+		goto partial;
+
+	return TRACE_TYPE_HANDLED;
+
+ partial:
+	return TRACE_TYPE_PARTIAL_LINE;
+}
+
+
+static struct trace_event trace_bprint_event = {
+	.type		= TRACE_BPRINT,
+	.trace		= trace_bprint_print,
+	.raw		= trace_bprint_raw,
+};
+
+/* TRACE_PRINT */
+static enum print_line_t trace_print_print(struct trace_iterator *iter,
+					   int flags)
+{
+	struct print_entry *field;
+	struct trace_seq *s = &iter->seq;
+
+	trace_assign_type(field, iter->ent);
+
+	if (!seq_print_ip_sym(s, field->ip, flags))
+		goto partial;
+
+	if (!trace_seq_printf(s, ": %s", field->buf))
+		goto partial;
+
+	return TRACE_TYPE_HANDLED;
+
+ partial:
+	return TRACE_TYPE_PARTIAL_LINE;
+}
+
+static enum print_line_t trace_print_raw(struct trace_iterator *iter, int flags)
+{
+	struct print_entry *field;
+
+	trace_assign_type(field, iter->ent);
+
+	if (!trace_seq_printf(&iter->seq, "# %lx %s", field->ip, field->buf))
+		goto partial;
+
+	return TRACE_TYPE_HANDLED;
+
+ partial:
+	return TRACE_TYPE_PARTIAL_LINE;
+}
+
+static struct trace_event trace_print_event = {
+	.type	 	= TRACE_PRINT,
+	.trace		= trace_print_print,
+	.raw		= trace_print_raw,
+};
+
+
+static struct trace_event *events[] __initdata = {
+	&trace_fn_event,
+	&trace_ctx_event,
+	&trace_wake_event,
+	&trace_special_event,
+	&trace_stack_event,
+	&trace_user_stack_event,
+	&trace_bprint_event,
+	&trace_print_event,
+	NULL
+};
+
+__init static int init_events(void)
+{
+	struct trace_event *event;
+	int i, ret;
+
+	for (i = 0; events[i]; i++) {
+		event = events[i];
+
+		ret = register_ftrace_event(event);
+		if (!ret) {
+			printk(KERN_WARNING "event %d failed to register\n",
+			       event->type);
+			WARN_ON_ONCE(1);
+		}
+	}
+
+	return 0;
+}
+device_initcall(init_events);
diff --git a/kernel/trace/trace_output.h b/kernel/trace/trace_output.h
new file mode 100644
index 0000000..e0bde39
--- /dev/null
+++ b/kernel/trace/trace_output.h
@@ -0,0 +1,71 @@
+#ifndef __TRACE_EVENTS_H
+#define __TRACE_EVENTS_H
+
+#include "trace.h"
+
+typedef enum print_line_t (*trace_print_func)(struct trace_iterator *iter,
+					      int flags);
+
+struct trace_event {
+	struct hlist_node	node;
+	int			type;
+	trace_print_func	trace;
+	trace_print_func	raw;
+	trace_print_func	hex;
+	trace_print_func	binary;
+};
+
+extern enum print_line_t
+trace_print_bprintk_msg_only(struct trace_iterator *iter);
+extern enum print_line_t
+trace_print_printk_msg_only(struct trace_iterator *iter);
+
+extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
+	__attribute__ ((format (printf, 2, 3)));
+extern int
+trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary);
+extern int
+seq_print_ip_sym(struct trace_seq *s, unsigned long ip,
+		unsigned long sym_flags);
+extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf,
+				 size_t cnt);
+extern int trace_seq_puts(struct trace_seq *s, const char *str);
+extern int trace_seq_putc(struct trace_seq *s, unsigned char c);
+extern int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len);
+extern int trace_seq_putmem_hex(struct trace_seq *s, const void *mem,
+				size_t len);
+extern void *trace_seq_reserve(struct trace_seq *s, size_t len);
+extern int trace_seq_path(struct trace_seq *s, struct path *path);
+extern int seq_print_userip_objs(const struct userstack_entry *entry,
+				 struct trace_seq *s, unsigned long sym_flags);
+extern int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm,
+			     unsigned long ip, unsigned long sym_flags);
+
+extern int trace_print_context(struct trace_iterator *iter);
+extern int trace_print_lat_context(struct trace_iterator *iter);
+
+extern struct trace_event *ftrace_find_event(int type);
+extern int register_ftrace_event(struct trace_event *event);
+extern int unregister_ftrace_event(struct trace_event *event);
+
+extern enum print_line_t trace_nop_print(struct trace_iterator *iter,
+					 int flags);
+
+#define MAX_MEMHEX_BYTES	8
+#define HEX_CHARS		(MAX_MEMHEX_BYTES*2 + 1)
+
+#define SEQ_PUT_FIELD_RET(s, x)				\
+do {							\
+	if (!trace_seq_putmem(s, &(x), sizeof(x)))	\
+		return TRACE_TYPE_PARTIAL_LINE;		\
+} while (0)
+
+#define SEQ_PUT_HEX_FIELD_RET(s, x)			\
+do {							\
+	BUILD_BUG_ON(sizeof(x) > MAX_MEMHEX_BYTES);	\
+	if (!trace_seq_putmem_hex(s, &(x), sizeof(x)))	\
+		return TRACE_TYPE_PARTIAL_LINE;		\
+} while (0)
+
+#endif
+
diff --git a/kernel/trace/trace_power.c b/kernel/trace/trace_power.c
index 7bda248..bae791e 100644
--- a/kernel/trace/trace_power.c
+++ b/kernel/trace/trace_power.c
@@ -11,15 +11,113 @@
 
 #include <linux/init.h>
 #include <linux/debugfs.h>
-#include <linux/ftrace.h>
+#include <trace/power.h>
 #include <linux/kallsyms.h>
 #include <linux/module.h>
 
 #include "trace.h"
+#include "trace_output.h"
 
 static struct trace_array *power_trace;
 static int __read_mostly trace_power_enabled;
 
+static void probe_power_start(struct power_trace *it, unsigned int type,
+				unsigned int level)
+{
+	if (!trace_power_enabled)
+		return;
+
+	memset(it, 0, sizeof(struct power_trace));
+	it->state = level;
+	it->type = type;
+	it->stamp = ktime_get();
+}
+
+
+static void probe_power_end(struct power_trace *it)
+{
+	struct ring_buffer_event *event;
+	struct trace_power *entry;
+	struct trace_array_cpu *data;
+	struct trace_array *tr = power_trace;
+
+	if (!trace_power_enabled)
+		return;
+
+	preempt_disable();
+	it->end = ktime_get();
+	data = tr->data[smp_processor_id()];
+
+	event = trace_buffer_lock_reserve(tr, TRACE_POWER,
+					  sizeof(*entry), 0, 0);
+	if (!event)
+		goto out;
+	entry	= ring_buffer_event_data(event);
+	entry->state_data = *it;
+	trace_buffer_unlock_commit(tr, event, 0, 0);
+ out:
+	preempt_enable();
+}
+
+static void probe_power_mark(struct power_trace *it, unsigned int type,
+				unsigned int level)
+{
+	struct ring_buffer_event *event;
+	struct trace_power *entry;
+	struct trace_array_cpu *data;
+	struct trace_array *tr = power_trace;
+
+	if (!trace_power_enabled)
+		return;
+
+	memset(it, 0, sizeof(struct power_trace));
+	it->state = level;
+	it->type = type;
+	it->stamp = ktime_get();
+	preempt_disable();
+	it->end = it->stamp;
+	data = tr->data[smp_processor_id()];
+
+	event = trace_buffer_lock_reserve(tr, TRACE_POWER,
+					  sizeof(*entry), 0, 0);
+	if (!event)
+		goto out;
+	entry	= ring_buffer_event_data(event);
+	entry->state_data = *it;
+	trace_buffer_unlock_commit(tr, event, 0, 0);
+ out:
+	preempt_enable();
+}
+
+static int tracing_power_register(void)
+{
+	int ret;
+
+	ret = register_trace_power_start(probe_power_start);
+	if (ret) {
+		pr_info("power trace: Couldn't activate tracepoint"
+			" probe to trace_power_start\n");
+		return ret;
+	}
+	ret = register_trace_power_end(probe_power_end);
+	if (ret) {
+		pr_info("power trace: Couldn't activate tracepoint"
+			" probe to trace_power_end\n");
+		goto fail_start;
+	}
+	ret = register_trace_power_mark(probe_power_mark);
+	if (ret) {
+		pr_info("power trace: Couldn't activate tracepoint"
+			" probe to trace_power_mark\n");
+		goto fail_end;
+	}
+	return ret;
+fail_end:
+	unregister_trace_power_end(probe_power_end);
+fail_start:
+	unregister_trace_power_start(probe_power_start);
+	return ret;
+}
 
 static void start_power_trace(struct trace_array *tr)
 {
@@ -31,6 +129,14 @@
 	trace_power_enabled = 0;
 }
 
+static void power_trace_reset(struct trace_array *tr)
+{
+	trace_power_enabled = 0;
+	unregister_trace_power_start(probe_power_start);
+	unregister_trace_power_end(probe_power_end);
+	unregister_trace_power_mark(probe_power_mark);
+}
+
 
 static int power_trace_init(struct trace_array *tr)
 {
@@ -38,6 +144,7 @@
 	power_trace = tr;
 
 	trace_power_enabled = 1;
+	tracing_power_register();
 
 	for_each_cpu(cpu, cpu_possible_mask)
 		tracing_reset(tr, cpu);
@@ -85,7 +192,7 @@
 	.init		= power_trace_init,
 	.start		= start_power_trace,
 	.stop		= stop_power_trace,
-	.reset		= stop_power_trace,
+	.reset		= power_trace_reset,
 	.print_line	= power_print_line,
 };
 
@@ -94,86 +201,3 @@
 	return register_tracer(&power_tracer);
 }
 device_initcall(init_power_trace);
-
-void trace_power_start(struct power_trace *it, unsigned int type,
-			 unsigned int level)
-{
-	if (!trace_power_enabled)
-		return;
-
-	memset(it, 0, sizeof(struct power_trace));
-	it->state = level;
-	it->type = type;
-	it->stamp = ktime_get();
-}
-EXPORT_SYMBOL_GPL(trace_power_start);
-
-
-void trace_power_end(struct power_trace *it)
-{
-	struct ring_buffer_event *event;
-	struct trace_power *entry;
-	struct trace_array_cpu *data;
-	unsigned long irq_flags;
-	struct trace_array *tr = power_trace;
-
-	if (!trace_power_enabled)
-		return;
-
-	preempt_disable();
-	it->end = ktime_get();
-	data = tr->data[smp_processor_id()];
-
-	event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
-					 &irq_flags);
-	if (!event)
-		goto out;
-	entry	= ring_buffer_event_data(event);
-	tracing_generic_entry_update(&entry->ent, 0, 0);
-	entry->ent.type = TRACE_POWER;
-	entry->state_data = *it;
-	ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
-
-	trace_wake_up();
-
- out:
-	preempt_enable();
-}
-EXPORT_SYMBOL_GPL(trace_power_end);
-
-void trace_power_mark(struct power_trace *it, unsigned int type,
-			 unsigned int level)
-{
-	struct ring_buffer_event *event;
-	struct trace_power *entry;
-	struct trace_array_cpu *data;
-	unsigned long irq_flags;
-	struct trace_array *tr = power_trace;
-
-	if (!trace_power_enabled)
-		return;
-
-	memset(it, 0, sizeof(struct power_trace));
-	it->state = level;
-	it->type = type;
-	it->stamp = ktime_get();
-	preempt_disable();
-	it->end = it->stamp;
-	data = tr->data[smp_processor_id()];
-
-	event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
-					 &irq_flags);
-	if (!event)
-		goto out;
-	entry	= ring_buffer_event_data(event);
-	tracing_generic_entry_update(&entry->ent, 0, 0);
-	entry->ent.type = TRACE_POWER;
-	entry->state_data = *it;
-	ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
-
-	trace_wake_up();
-
- out:
-	preempt_enable();
-}
-EXPORT_SYMBOL_GPL(trace_power_mark);
diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c
new file mode 100644
index 0000000..eb81556
--- /dev/null
+++ b/kernel/trace/trace_printk.c
@@ -0,0 +1,270 @@
+/*
+ * trace binary printk
+ *
+ * Copyright (C) 2008 Lai Jiangshan <laijs@cn.fujitsu.com>
+ *
+ */
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+#include <linux/kernel.h>
+#include <linux/ftrace.h>
+#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/marker.h>
+#include <linux/mutex.h>
+#include <linux/ctype.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+
+#include "trace.h"
+
+#ifdef CONFIG_MODULES
+
+/*
+ * modules trace_printk()'s formats are autosaved in struct trace_bprintk_fmt
+ * which are queued on trace_bprintk_fmt_list.
+ */
+static LIST_HEAD(trace_bprintk_fmt_list);
+
+/* serialize accesses to trace_bprintk_fmt_list */
+static DEFINE_MUTEX(btrace_mutex);
+
+struct trace_bprintk_fmt {
+	struct list_head list;
+	char fmt[0];
+};
+
+static inline struct trace_bprintk_fmt *lookup_format(const char *fmt)
+{
+	struct trace_bprintk_fmt *pos;
+	list_for_each_entry(pos, &trace_bprintk_fmt_list, list) {
+		if (!strcmp(pos->fmt, fmt))
+			return pos;
+	}
+	return NULL;
+}
+
+static
+void hold_module_trace_bprintk_format(const char **start, const char **end)
+{
+	const char **iter;
+
+	mutex_lock(&btrace_mutex);
+	for (iter = start; iter < end; iter++) {
+		struct trace_bprintk_fmt *tb_fmt = lookup_format(*iter);
+		if (tb_fmt) {
+			*iter = tb_fmt->fmt;
+			continue;
+		}
+
+		tb_fmt = kmalloc(offsetof(struct trace_bprintk_fmt, fmt)
+				+ strlen(*iter) + 1, GFP_KERNEL);
+		if (tb_fmt) {
+			list_add_tail(&tb_fmt->list, &trace_bprintk_fmt_list);
+			strcpy(tb_fmt->fmt, *iter);
+			*iter = tb_fmt->fmt;
+		} else
+			*iter = NULL;
+	}
+	mutex_unlock(&btrace_mutex);
+}
+
+static int module_trace_bprintk_format_notify(struct notifier_block *self,
+		unsigned long val, void *data)
+{
+	struct module *mod = data;
+	if (mod->num_trace_bprintk_fmt) {
+		const char **start = mod->trace_bprintk_fmt_start;
+		const char **end = start + mod->num_trace_bprintk_fmt;
+
+		if (val == MODULE_STATE_COMING)
+			hold_module_trace_bprintk_format(start, end);
+	}
+	return 0;
+}
+
+#else /* !CONFIG_MODULES */
+__init static int
+module_trace_bprintk_format_notify(struct notifier_block *self,
+		unsigned long val, void *data)
+{
+	return 0;
+}
+#endif /* CONFIG_MODULES */
+
+
+__initdata_or_module static
+struct notifier_block module_trace_bprintk_format_nb = {
+	.notifier_call = module_trace_bprintk_format_notify,
+};
+
+int __trace_bprintk(unsigned long ip, const char *fmt, ...)
+ {
+	int ret;
+	va_list ap;
+
+	if (unlikely(!fmt))
+		return 0;
+
+	if (!(trace_flags & TRACE_ITER_PRINTK))
+		return 0;
+
+	va_start(ap, fmt);
+	ret = trace_vbprintk(ip, fmt, ap);
+	va_end(ap);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(__trace_bprintk);
+
+int __ftrace_vbprintk(unsigned long ip, const char *fmt, va_list ap)
+ {
+	if (unlikely(!fmt))
+		return 0;
+
+	if (!(trace_flags & TRACE_ITER_PRINTK))
+		return 0;
+
+	return trace_vbprintk(ip, fmt, ap);
+}
+EXPORT_SYMBOL_GPL(__ftrace_vbprintk);
+
+int __trace_printk(unsigned long ip, const char *fmt, ...)
+{
+	int ret;
+	va_list ap;
+
+	if (!(trace_flags & TRACE_ITER_PRINTK))
+		return 0;
+
+	va_start(ap, fmt);
+	ret = trace_vprintk(ip, fmt, ap);
+	va_end(ap);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(__trace_printk);
+
+int __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap)
+{
+	if (!(trace_flags & TRACE_ITER_PRINTK))
+		return 0;
+
+	return trace_vprintk(ip, fmt, ap);
+}
+EXPORT_SYMBOL_GPL(__ftrace_vprintk);
+
+static void *
+t_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	const char **fmt = m->private;
+	const char **next = fmt;
+
+	(*pos)++;
+
+	if ((unsigned long)fmt >= (unsigned long)__stop___trace_bprintk_fmt)
+		return NULL;
+
+	next = fmt;
+	m->private = ++next;
+
+	return fmt;
+}
+
+static void *t_start(struct seq_file *m, loff_t *pos)
+{
+	return t_next(m, NULL, pos);
+}
+
+static int t_show(struct seq_file *m, void *v)
+{
+	const char **fmt = v;
+	const char *str = *fmt;
+	int i;
+
+	seq_printf(m, "0x%lx : \"", (unsigned long)fmt);
+
+	/*
+	 * Tabs and new lines need to be converted.
+	 */
+	for (i = 0; str[i]; i++) {
+		switch (str[i]) {
+		case '\n':
+			seq_puts(m, "\\n");
+			break;
+		case '\t':
+			seq_puts(m, "\\t");
+			break;
+		case '\\':
+			seq_puts(m, "\\");
+			break;
+		case '"':
+			seq_puts(m, "\\\"");
+			break;
+		default:
+			seq_putc(m, str[i]);
+		}
+	}
+	seq_puts(m, "\"\n");
+
+	return 0;
+}
+
+static void t_stop(struct seq_file *m, void *p)
+{
+}
+
+static const struct seq_operations show_format_seq_ops = {
+	.start = t_start,
+	.next = t_next,
+	.show = t_show,
+	.stop = t_stop,
+};
+
+static int
+ftrace_formats_open(struct inode *inode, struct file *file)
+{
+	int ret;
+
+	ret = seq_open(file, &show_format_seq_ops);
+	if (!ret) {
+		struct seq_file *m = file->private_data;
+
+		m->private = __start___trace_bprintk_fmt;
+	}
+	return ret;
+}
+
+static const struct file_operations ftrace_formats_fops = {
+	.open = ftrace_formats_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = seq_release,
+};
+
+static __init int init_trace_printk_function_export(void)
+{
+	struct dentry *d_tracer;
+	struct dentry *entry;
+
+	d_tracer = tracing_init_dentry();
+	if (!d_tracer)
+		return 0;
+
+	entry = debugfs_create_file("printk_formats", 0444, d_tracer,
+				    NULL, &ftrace_formats_fops);
+	if (!entry)
+		pr_warning("Could not create debugfs "
+			   "'printk_formats' entry\n");
+
+	return 0;
+}
+
+fs_initcall(init_trace_printk_function_export);
+
+static __init int init_trace_printk(void)
+{
+	return register_module_notifier(&module_trace_bprintk_format_nb);
+}
+
+early_initcall(init_trace_printk);
diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c
index df175cb..de35f20 100644
--- a/kernel/trace/trace_sched_switch.c
+++ b/kernel/trace/trace_sched_switch.c
@@ -18,6 +18,7 @@
 static int __read_mostly	tracer_enabled;
 static int			sched_ref;
 static DEFINE_MUTEX(sched_register_mutex);
+static int			sched_stopped;
 
 static void
 probe_sched_switch(struct rq *__rq, struct task_struct *prev,
@@ -28,7 +29,7 @@
 	int cpu;
 	int pc;
 
-	if (!sched_ref)
+	if (!sched_ref || sched_stopped)
 		return;
 
 	tracing_record_cmdline(prev);
@@ -43,7 +44,7 @@
 	data = ctx_trace->data[cpu];
 
 	if (likely(!atomic_read(&data->disabled)))
-		tracing_sched_switch_trace(ctx_trace, data, prev, next, flags, pc);
+		tracing_sched_switch_trace(ctx_trace, prev, next, flags, pc);
 
 	local_irq_restore(flags);
 }
@@ -66,7 +67,7 @@
 	data = ctx_trace->data[cpu];
 
 	if (likely(!atomic_read(&data->disabled)))
-		tracing_sched_wakeup_trace(ctx_trace, data, wakee, current,
+		tracing_sched_wakeup_trace(ctx_trace, wakee, current,
 					   flags, pc);
 
 	local_irq_restore(flags);
@@ -93,7 +94,7 @@
 	ret = register_trace_sched_switch(probe_sched_switch);
 	if (ret) {
 		pr_info("sched trace: Couldn't activate tracepoint"
-			" probe to kernel_sched_schedule\n");
+			" probe to kernel_sched_switch\n");
 		goto fail_deprobe_wake_new;
 	}
 
@@ -185,12 +186,6 @@
 	ctx_trace = tr;
 }
 
-static void start_sched_trace(struct trace_array *tr)
-{
-	tracing_reset_online_cpus(tr);
-	tracing_start_sched_switch_record();
-}
-
 static void stop_sched_trace(struct trace_array *tr)
 {
 	tracing_stop_sched_switch_record();
@@ -199,7 +194,8 @@
 static int sched_switch_trace_init(struct trace_array *tr)
 {
 	ctx_trace = tr;
-	start_sched_trace(tr);
+	tracing_reset_online_cpus(tr);
+	tracing_start_sched_switch_record();
 	return 0;
 }
 
@@ -211,13 +207,12 @@
 
 static void sched_switch_trace_start(struct trace_array *tr)
 {
-	tracing_reset_online_cpus(tr);
-	tracing_start_sched_switch();
+	sched_stopped = 0;
 }
 
 static void sched_switch_trace_stop(struct trace_array *tr)
 {
-	tracing_stop_sched_switch();
+	sched_stopped = 1;
 }
 
 static struct tracer sched_switch_trace __read_mostly =
@@ -227,6 +222,7 @@
 	.reset		= sched_switch_trace_reset,
 	.start		= sched_switch_trace_start,
 	.stop		= sched_switch_trace_stop,
+	.wait_pipe	= poll_wait_pipe,
 #ifdef CONFIG_FTRACE_SELFTEST
 	.selftest    = trace_selftest_startup_sched_switch,
 #endif
diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c
index 42ae1e7..3c5ad6b 100644
--- a/kernel/trace/trace_sched_wakeup.c
+++ b/kernel/trace/trace_sched_wakeup.c
@@ -25,12 +25,15 @@
 static struct task_struct	*wakeup_task;
 static int			wakeup_cpu;
 static unsigned			wakeup_prio = -1;
+static int			wakeup_rt;
 
 static raw_spinlock_t wakeup_lock =
 	(raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
 
 static void __wakeup_reset(struct trace_array *tr);
 
+static int save_lat_flag;
+
 #ifdef CONFIG_FUNCTION_TRACER
 /*
  * irqsoff uses its own tracer function to keep the overhead down:
@@ -71,7 +74,7 @@
 	if (task_cpu(wakeup_task) != cpu)
 		goto unlock;
 
-	trace_function(tr, data, ip, parent_ip, flags, pc);
+	trace_function(tr, ip, parent_ip, flags, pc);
 
  unlock:
 	__raw_spin_unlock(&wakeup_lock);
@@ -151,7 +154,8 @@
 	if (unlikely(!tracer_enabled || next != wakeup_task))
 		goto out_unlock;
 
-	trace_function(wakeup_trace, data, CALLER_ADDR1, CALLER_ADDR2, flags, pc);
+	trace_function(wakeup_trace, CALLER_ADDR1, CALLER_ADDR2, flags, pc);
+	tracing_sched_switch_trace(wakeup_trace, prev, next, flags, pc);
 
 	/*
 	 * usecs conversion is slow so we try to delay the conversion
@@ -182,13 +186,10 @@
 
 static void __wakeup_reset(struct trace_array *tr)
 {
-	struct trace_array_cpu *data;
 	int cpu;
 
-	for_each_possible_cpu(cpu) {
-		data = tr->data[cpu];
+	for_each_possible_cpu(cpu)
 		tracing_reset(tr, cpu);
-	}
 
 	wakeup_cpu = -1;
 	wakeup_prio = -1;
@@ -213,6 +214,7 @@
 static void
 probe_wakeup(struct rq *rq, struct task_struct *p, int success)
 {
+	struct trace_array_cpu *data;
 	int cpu = smp_processor_id();
 	unsigned long flags;
 	long disabled;
@@ -224,7 +226,7 @@
 	tracing_record_cmdline(p);
 	tracing_record_cmdline(current);
 
-	if (likely(!rt_task(p)) ||
+	if ((wakeup_rt && !rt_task(p)) ||
 			p->prio >= wakeup_prio ||
 			p->prio >= current->prio)
 		return;
@@ -252,9 +254,10 @@
 
 	local_save_flags(flags);
 
-	wakeup_trace->data[wakeup_cpu]->preempt_timestamp = ftrace_now(cpu);
-	trace_function(wakeup_trace, wakeup_trace->data[wakeup_cpu],
-		       CALLER_ADDR1, CALLER_ADDR2, flags, pc);
+	data = wakeup_trace->data[wakeup_cpu];
+	data->preempt_timestamp = ftrace_now(cpu);
+	tracing_sched_wakeup_trace(wakeup_trace, p, current, flags, pc);
+	trace_function(wakeup_trace, CALLER_ADDR1, CALLER_ADDR2, flags, pc);
 
 out_locked:
 	__raw_spin_unlock(&wakeup_lock);
@@ -262,12 +265,6 @@
 	atomic_dec(&wakeup_trace->data[cpu]->disabled);
 }
 
-/*
- * save_tracer_enabled is used to save the state of the tracer_enabled
- * variable when we disable it when we open a trace output file.
- */
-static int save_tracer_enabled;
-
 static void start_wakeup_tracer(struct trace_array *tr)
 {
 	int ret;
@@ -289,7 +286,7 @@
 	ret = register_trace_sched_switch(probe_wakeup_sched_switch);
 	if (ret) {
 		pr_info("sched trace: Couldn't activate tracepoint"
-			" probe to kernel_sched_schedule\n");
+			" probe to kernel_sched_switch\n");
 		goto fail_deprobe_wake_new;
 	}
 
@@ -306,13 +303,10 @@
 
 	register_ftrace_function(&trace_ops);
 
-	if (tracing_is_enabled()) {
+	if (tracing_is_enabled())
 		tracer_enabled = 1;
-		save_tracer_enabled = 1;
-	} else {
+	else
 		tracer_enabled = 0;
-		save_tracer_enabled = 0;
-	}
 
 	return;
 fail_deprobe_wake_new:
@@ -324,54 +318,54 @@
 static void stop_wakeup_tracer(struct trace_array *tr)
 {
 	tracer_enabled = 0;
-	save_tracer_enabled = 0;
 	unregister_ftrace_function(&trace_ops);
 	unregister_trace_sched_switch(probe_wakeup_sched_switch);
 	unregister_trace_sched_wakeup_new(probe_wakeup);
 	unregister_trace_sched_wakeup(probe_wakeup);
 }
 
-static int wakeup_tracer_init(struct trace_array *tr)
+static int __wakeup_tracer_init(struct trace_array *tr)
 {
+	save_lat_flag = trace_flags & TRACE_ITER_LATENCY_FMT;
+	trace_flags |= TRACE_ITER_LATENCY_FMT;
+
 	tracing_max_latency = 0;
 	wakeup_trace = tr;
 	start_wakeup_tracer(tr);
 	return 0;
 }
 
+static int wakeup_tracer_init(struct trace_array *tr)
+{
+	wakeup_rt = 0;
+	return __wakeup_tracer_init(tr);
+}
+
+static int wakeup_rt_tracer_init(struct trace_array *tr)
+{
+	wakeup_rt = 1;
+	return __wakeup_tracer_init(tr);
+}
+
 static void wakeup_tracer_reset(struct trace_array *tr)
 {
 	stop_wakeup_tracer(tr);
 	/* make sure we put back any tasks we are tracing */
 	wakeup_reset(tr);
+
+	if (!save_lat_flag)
+		trace_flags &= ~TRACE_ITER_LATENCY_FMT;
 }
 
 static void wakeup_tracer_start(struct trace_array *tr)
 {
 	wakeup_reset(tr);
 	tracer_enabled = 1;
-	save_tracer_enabled = 1;
 }
 
 static void wakeup_tracer_stop(struct trace_array *tr)
 {
 	tracer_enabled = 0;
-	save_tracer_enabled = 0;
-}
-
-static void wakeup_tracer_open(struct trace_iterator *iter)
-{
-	/* stop the trace while dumping */
-	tracer_enabled = 0;
-}
-
-static void wakeup_tracer_close(struct trace_iterator *iter)
-{
-	/* forget about any processes we were recording */
-	if (save_tracer_enabled) {
-		wakeup_reset(iter->tr);
-		tracer_enabled = 1;
-	}
 }
 
 static struct tracer wakeup_tracer __read_mostly =
@@ -381,8 +375,20 @@
 	.reset		= wakeup_tracer_reset,
 	.start		= wakeup_tracer_start,
 	.stop		= wakeup_tracer_stop,
-	.open		= wakeup_tracer_open,
-	.close		= wakeup_tracer_close,
+	.print_max	= 1,
+#ifdef CONFIG_FTRACE_SELFTEST
+	.selftest    = trace_selftest_startup_wakeup,
+#endif
+};
+
+static struct tracer wakeup_rt_tracer __read_mostly =
+{
+	.name		= "wakeup_rt",
+	.init		= wakeup_rt_tracer_init,
+	.reset		= wakeup_tracer_reset,
+	.start		= wakeup_tracer_start,
+	.stop		= wakeup_tracer_stop,
+	.wait_pipe	= poll_wait_pipe,
 	.print_max	= 1,
 #ifdef CONFIG_FTRACE_SELFTEST
 	.selftest    = trace_selftest_startup_wakeup,
@@ -397,6 +403,10 @@
 	if (ret)
 		return ret;
 
+	ret = register_tracer(&wakeup_rt_tracer);
+	if (ret)
+		return ret;
+
 	return 0;
 }
 device_initcall(init_wakeup_tracer);
diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c
index bc8e80a..08f4eb2 100644
--- a/kernel/trace/trace_selftest.c
+++ b/kernel/trace/trace_selftest.c
@@ -1,5 +1,6 @@
 /* Include in trace.c */
 
+#include <linux/stringify.h>
 #include <linux/kthread.h>
 #include <linux/delay.h>
 
@@ -9,11 +10,12 @@
 	case TRACE_FN:
 	case TRACE_CTX:
 	case TRACE_WAKE:
-	case TRACE_CONT:
 	case TRACE_STACK:
 	case TRACE_PRINT:
 	case TRACE_SPECIAL:
 	case TRACE_BRANCH:
+	case TRACE_GRAPH_ENT:
+	case TRACE_GRAPH_RET:
 		return 1;
 	}
 	return 0;
@@ -99,9 +101,6 @@
 
 #ifdef CONFIG_DYNAMIC_FTRACE
 
-#define __STR(x) #x
-#define STR(x) __STR(x)
-
 /* Test dynamic code modification and ftrace filters */
 int trace_selftest_startup_dynamic_tracing(struct tracer *trace,
 					   struct trace_array *tr,
@@ -125,17 +124,17 @@
 	func();
 
 	/*
-	 * Some archs *cough*PowerPC*cough* add charachters to the
+	 * Some archs *cough*PowerPC*cough* add characters to the
 	 * start of the function names. We simply put a '*' to
-	 * accomodate them.
+	 * accommodate them.
 	 */
-	func_name = "*" STR(DYN_FTRACE_TEST_NAME);
+	func_name = "*" __stringify(DYN_FTRACE_TEST_NAME);
 
 	/* filter only on our function */
 	ftrace_set_filter(func_name, strlen(func_name), 1);
 
 	/* enable tracing */
-	ret = trace->init(tr);
+	ret = tracer_init(trace, tr);
 	if (ret) {
 		warn_failed_init_tracer(trace, ret);
 		goto out;
@@ -209,7 +208,7 @@
 	ftrace_enabled = 1;
 	tracer_enabled = 1;
 
-	ret = trace->init(tr);
+	ret = tracer_init(trace, tr);
 	if (ret) {
 		warn_failed_init_tracer(trace, ret);
 		goto out;
@@ -247,6 +246,90 @@
 }
 #endif /* CONFIG_FUNCTION_TRACER */
 
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+
+/* Maximum number of functions to trace before diagnosing a hang */
+#define GRAPH_MAX_FUNC_TEST	100000000
+
+static void __ftrace_dump(bool disable_tracing);
+static unsigned int graph_hang_thresh;
+
+/* Wrap the real function entry probe to avoid possible hanging */
+static int trace_graph_entry_watchdog(struct ftrace_graph_ent *trace)
+{
+	/* This is harmlessly racy, we want to approximately detect a hang */
+	if (unlikely(++graph_hang_thresh > GRAPH_MAX_FUNC_TEST)) {
+		ftrace_graph_stop();
+		printk(KERN_WARNING "BUG: Function graph tracer hang!\n");
+		if (ftrace_dump_on_oops)
+			__ftrace_dump(false);
+		return 0;
+	}
+
+	return trace_graph_entry(trace);
+}
+
+/*
+ * Pretty much the same than for the function tracer from which the selftest
+ * has been borrowed.
+ */
+int
+trace_selftest_startup_function_graph(struct tracer *trace,
+					struct trace_array *tr)
+{
+	int ret;
+	unsigned long count;
+
+	/*
+	 * Simulate the init() callback but we attach a watchdog callback
+	 * to detect and recover from possible hangs
+	 */
+	tracing_reset_online_cpus(tr);
+	ret = register_ftrace_graph(&trace_graph_return,
+				    &trace_graph_entry_watchdog);
+	if (ret) {
+		warn_failed_init_tracer(trace, ret);
+		goto out;
+	}
+	tracing_start_cmdline_record();
+
+	/* Sleep for a 1/10 of a second */
+	msleep(100);
+
+	/* Have we just recovered from a hang? */
+	if (graph_hang_thresh > GRAPH_MAX_FUNC_TEST) {
+		tracing_selftest_disabled = true;
+		ret = -1;
+		goto out;
+	}
+
+	tracing_stop();
+
+	/* check the trace buffer */
+	ret = trace_test_buffer(tr, &count);
+
+	trace->reset(tr);
+	tracing_start();
+
+	if (!ret && !count) {
+		printk(KERN_CONT ".. no entries found ..");
+		ret = -1;
+		goto out;
+	}
+
+	/* Don't test dynamic tracing, the function tracer already did */
+
+out:
+	/* Stop it if we failed */
+	if (ret)
+		ftrace_graph_stop();
+
+	return ret;
+}
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
+
 #ifdef CONFIG_IRQSOFF_TRACER
 int
 trace_selftest_startup_irqsoff(struct tracer *trace, struct trace_array *tr)
@@ -256,7 +339,7 @@
 	int ret;
 
 	/* start the tracing */
-	ret = trace->init(tr);
+	ret = tracer_init(trace, tr);
 	if (ret) {
 		warn_failed_init_tracer(trace, ret);
 		return ret;
@@ -268,6 +351,14 @@
 	local_irq_disable();
 	udelay(100);
 	local_irq_enable();
+
+	/*
+	 * Stop the tracer to avoid a warning subsequent
+	 * to buffer flipping failure because tracing_stop()
+	 * disables the tr and max buffers, making flipping impossible
+	 * in case of parallels max irqs off latencies.
+	 */
+	trace->stop(tr);
 	/* stop the tracing. */
 	tracing_stop();
 	/* check both trace buffers */
@@ -310,7 +401,7 @@
 	}
 
 	/* start the tracing */
-	ret = trace->init(tr);
+	ret = tracer_init(trace, tr);
 	if (ret) {
 		warn_failed_init_tracer(trace, ret);
 		return ret;
@@ -322,6 +413,14 @@
 	preempt_disable();
 	udelay(100);
 	preempt_enable();
+
+	/*
+	 * Stop the tracer to avoid a warning subsequent
+	 * to buffer flipping failure because tracing_stop()
+	 * disables the tr and max buffers, making flipping impossible
+	 * in case of parallels max preempt off latencies.
+	 */
+	trace->stop(tr);
 	/* stop the tracing. */
 	tracing_stop();
 	/* check both trace buffers */
@@ -364,10 +463,10 @@
 	}
 
 	/* start the tracing */
-	ret = trace->init(tr);
+	ret = tracer_init(trace, tr);
 	if (ret) {
 		warn_failed_init_tracer(trace, ret);
-		goto out;
+		goto out_no_start;
 	}
 
 	/* reset the max latency */
@@ -381,31 +480,35 @@
 	/* reverse the order of preempt vs irqs */
 	local_irq_enable();
 
+	/*
+	 * Stop the tracer to avoid a warning subsequent
+	 * to buffer flipping failure because tracing_stop()
+	 * disables the tr and max buffers, making flipping impossible
+	 * in case of parallels max irqs/preempt off latencies.
+	 */
+	trace->stop(tr);
 	/* stop the tracing. */
 	tracing_stop();
 	/* check both trace buffers */
 	ret = trace_test_buffer(tr, NULL);
-	if (ret) {
-		tracing_start();
+	if (ret)
 		goto out;
-	}
 
 	ret = trace_test_buffer(&max_tr, &count);
-	if (ret) {
-		tracing_start();
+	if (ret)
 		goto out;
-	}
 
 	if (!ret && !count) {
 		printk(KERN_CONT ".. no entries found ..");
 		ret = -1;
-		tracing_start();
 		goto out;
 	}
 
 	/* do the test by disabling interrupts first this time */
 	tracing_max_latency = 0;
 	tracing_start();
+	trace->start(tr);
+
 	preempt_disable();
 	local_irq_disable();
 	udelay(100);
@@ -413,6 +516,7 @@
 	/* reverse the order of preempt vs irqs */
 	local_irq_enable();
 
+	trace->stop(tr);
 	/* stop the tracing. */
 	tracing_stop();
 	/* check both trace buffers */
@@ -428,9 +532,10 @@
 		goto out;
 	}
 
- out:
-	trace->reset(tr);
+out:
 	tracing_start();
+out_no_start:
+	trace->reset(tr);
 	tracing_max_latency = save_max;
 
 	return ret;
@@ -496,7 +601,7 @@
 	wait_for_completion(&isrt);
 
 	/* start the tracing */
-	ret = trace->init(tr);
+	ret = tracer_init(trace, tr);
 	if (ret) {
 		warn_failed_init_tracer(trace, ret);
 		return ret;
@@ -557,7 +662,7 @@
 	int ret;
 
 	/* start the tracing */
-	ret = trace->init(tr);
+	ret = tracer_init(trace, tr);
 	if (ret) {
 		warn_failed_init_tracer(trace, ret);
 		return ret;
@@ -589,34 +694,7 @@
 	int ret;
 
 	/* start the tracing */
-	ret = trace->init(tr);
-	if (ret) {
-		warn_failed_init_tracer(trace, ret);
-		return 0;
-	}
-
-	/* Sleep for a 1/10 of a second */
-	msleep(100);
-	/* stop the tracing. */
-	tracing_stop();
-	/* check the trace buffer */
-	ret = trace_test_buffer(tr, &count);
-	trace->reset(tr);
-	tracing_start();
-
-	return ret;
-}
-#endif /* CONFIG_SYSPROF_TRACER */
-
-#ifdef CONFIG_BRANCH_TRACER
-int
-trace_selftest_startup_branch(struct tracer *trace, struct trace_array *tr)
-{
-	unsigned long count;
-	int ret;
-
-	/* start the tracing */
-	ret = trace->init(tr);
+	ret = tracer_init(trace, tr);
 	if (ret) {
 		warn_failed_init_tracer(trace, ret);
 		return ret;
@@ -631,6 +709,43 @@
 	trace->reset(tr);
 	tracing_start();
 
+	if (!ret && !count) {
+		printk(KERN_CONT ".. no entries found ..");
+		ret = -1;
+	}
+
+	return ret;
+}
+#endif /* CONFIG_SYSPROF_TRACER */
+
+#ifdef CONFIG_BRANCH_TRACER
+int
+trace_selftest_startup_branch(struct tracer *trace, struct trace_array *tr)
+{
+	unsigned long count;
+	int ret;
+
+	/* start the tracing */
+	ret = tracer_init(trace, tr);
+	if (ret) {
+		warn_failed_init_tracer(trace, ret);
+		return ret;
+	}
+
+	/* Sleep for a 1/10 of a second */
+	msleep(100);
+	/* stop the tracing. */
+	tracing_stop();
+	/* check the trace buffer */
+	ret = trace_test_buffer(tr, &count);
+	trace->reset(tr);
+	tracing_start();
+
+	if (!ret && !count) {
+		printk(KERN_CONT ".. no entries found ..");
+		ret = -1;
+	}
+
 	return ret;
 }
 #endif /* CONFIG_BRANCH_TRACER */
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c
index d0871bc..c750f65 100644
--- a/kernel/trace/trace_stack.c
+++ b/kernel/trace/trace_stack.c
@@ -245,16 +245,31 @@
 #endif
 }
 
+static void print_disabled(struct seq_file *m)
+{
+	seq_puts(m, "#\n"
+		 "#  Stack tracer disabled\n"
+		 "#\n"
+		 "# To enable the stack tracer, either add 'stacktrace' to the\n"
+		 "# kernel command line\n"
+		 "# or 'echo 1 > /proc/sys/kernel/stack_tracer_enabled'\n"
+		 "#\n");
+}
+
 static int t_show(struct seq_file *m, void *v)
 {
 	long i;
 	int size;
 
 	if (v == SEQ_START_TOKEN) {
-		seq_printf(m, "        Depth   Size      Location"
+		seq_printf(m, "        Depth    Size   Location"
 			   "    (%d entries)\n"
-			   "        -----   ----      --------\n",
+			   "        -----    ----   --------\n",
 			   max_stack_trace.nr_entries);
+
+		if (!stack_tracer_enabled && !max_stack_size)
+			print_disabled(m);
+
 		return 0;
 	}
 
diff --git a/kernel/trace/trace_stat.c b/kernel/trace/trace_stat.c
new file mode 100644
index 0000000..acdebd7
--- /dev/null
+++ b/kernel/trace/trace_stat.c
@@ -0,0 +1,326 @@
+/*
+ * Infrastructure for statistic tracing (histogram output).
+ *
+ * Copyright (C) 2008 Frederic Weisbecker <fweisbec@gmail.com>
+ *
+ * Based on the code from trace_branch.c which is
+ * Copyright (C) 2008 Steven Rostedt <srostedt@redhat.com>
+ *
+ */
+
+
+#include <linux/list.h>
+#include <linux/debugfs.h>
+#include "trace_stat.h"
+#include "trace.h"
+
+
+/* List of stat entries from a tracer */
+struct trace_stat_list {
+	struct list_head	list;
+	void			*stat;
+};
+
+/* A stat session is the stats output in one file */
+struct tracer_stat_session {
+	struct list_head	session_list;
+	struct tracer_stat	*ts;
+	struct list_head	stat_list;
+	struct mutex		stat_mutex;
+	struct dentry		*file;
+};
+
+/* All of the sessions currently in use. Each stat file embed one session */
+static LIST_HEAD(all_stat_sessions);
+static DEFINE_MUTEX(all_stat_sessions_mutex);
+
+/* The root directory for all stat files */
+static struct dentry		*stat_dir;
+
+
+static void reset_stat_session(struct tracer_stat_session *session)
+{
+	struct trace_stat_list *node, *next;
+
+	list_for_each_entry_safe(node, next, &session->stat_list, list)
+		kfree(node);
+
+	INIT_LIST_HEAD(&session->stat_list);
+}
+
+static void destroy_session(struct tracer_stat_session *session)
+{
+	debugfs_remove(session->file);
+	reset_stat_session(session);
+	mutex_destroy(&session->stat_mutex);
+	kfree(session);
+}
+
+/*
+ * For tracers that don't provide a stat_cmp callback.
+ * This one will force an immediate insertion on tail of
+ * the list.
+ */
+static int dummy_cmp(void *p1, void *p2)
+{
+	return 1;
+}
+
+/*
+ * Initialize the stat list at each trace_stat file opening.
+ * All of these copies and sorting are required on all opening
+ * since the stats could have changed between two file sessions.
+ */
+static int stat_seq_init(struct tracer_stat_session *session)
+{
+	struct trace_stat_list *iter_entry, *new_entry;
+	struct tracer_stat *ts = session->ts;
+	void *stat;
+	int ret = 0;
+	int i;
+
+	mutex_lock(&session->stat_mutex);
+	reset_stat_session(session);
+
+	if (!ts->stat_cmp)
+		ts->stat_cmp = dummy_cmp;
+
+	stat = ts->stat_start();
+	if (!stat)
+		goto exit;
+
+	/*
+	 * The first entry. Actually this is the second, but the first
+	 * one (the stat_list head) is pointless.
+	 */
+	new_entry = kmalloc(sizeof(struct trace_stat_list), GFP_KERNEL);
+	if (!new_entry) {
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	INIT_LIST_HEAD(&new_entry->list);
+
+	list_add(&new_entry->list, &session->stat_list);
+
+	new_entry->stat = stat;
+
+	/*
+	 * Iterate over the tracer stat entries and store them in a sorted
+	 * list.
+	 */
+	for (i = 1; ; i++) {
+		stat = ts->stat_next(stat, i);
+
+		/* End of insertion */
+		if (!stat)
+			break;
+
+		new_entry = kmalloc(sizeof(struct trace_stat_list), GFP_KERNEL);
+		if (!new_entry) {
+			ret = -ENOMEM;
+			goto exit_free_list;
+		}
+
+		INIT_LIST_HEAD(&new_entry->list);
+		new_entry->stat = stat;
+
+		list_for_each_entry_reverse(iter_entry, &session->stat_list,
+				list) {
+
+			/* Insertion with a descendent sorting */
+			if (ts->stat_cmp(iter_entry->stat,
+					new_entry->stat) >= 0) {
+
+				list_add(&new_entry->list, &iter_entry->list);
+				break;
+			}
+		}
+
+		/* The current larger value */
+		if (list_empty(&new_entry->list))
+			list_add(&new_entry->list, &session->stat_list);
+	}
+exit:
+	mutex_unlock(&session->stat_mutex);
+	return ret;
+
+exit_free_list:
+	reset_stat_session(session);
+	mutex_unlock(&session->stat_mutex);
+	return ret;
+}
+
+
+static void *stat_seq_start(struct seq_file *s, loff_t *pos)
+{
+	struct tracer_stat_session *session = s->private;
+
+	/* Prevent from tracer switch or stat_list modification */
+	mutex_lock(&session->stat_mutex);
+
+	/* If we are in the beginning of the file, print the headers */
+	if (!*pos && session->ts->stat_headers)
+		return SEQ_START_TOKEN;
+
+	return seq_list_start(&session->stat_list, *pos);
+}
+
+static void *stat_seq_next(struct seq_file *s, void *p, loff_t *pos)
+{
+	struct tracer_stat_session *session = s->private;
+
+	if (p == SEQ_START_TOKEN)
+		return seq_list_start(&session->stat_list, *pos);
+
+	return seq_list_next(p, &session->stat_list, pos);
+}
+
+static void stat_seq_stop(struct seq_file *s, void *p)
+{
+	struct tracer_stat_session *session = s->private;
+	mutex_unlock(&session->stat_mutex);
+}
+
+static int stat_seq_show(struct seq_file *s, void *v)
+{
+	struct tracer_stat_session *session = s->private;
+	struct trace_stat_list *l = list_entry(v, struct trace_stat_list, list);
+
+	if (v == SEQ_START_TOKEN)
+		return session->ts->stat_headers(s);
+
+	return session->ts->stat_show(s, l->stat);
+}
+
+static const struct seq_operations trace_stat_seq_ops = {
+	.start		= stat_seq_start,
+	.next		= stat_seq_next,
+	.stop		= stat_seq_stop,
+	.show		= stat_seq_show
+};
+
+/* The session stat is refilled and resorted at each stat file opening */
+static int tracing_stat_open(struct inode *inode, struct file *file)
+{
+	int ret;
+
+	struct tracer_stat_session *session = inode->i_private;
+
+	ret = seq_open(file, &trace_stat_seq_ops);
+	if (!ret) {
+		struct seq_file *m = file->private_data;
+		m->private = session;
+		ret = stat_seq_init(session);
+	}
+
+	return ret;
+}
+
+/*
+ * Avoid consuming memory with our now useless list.
+ */
+static int tracing_stat_release(struct inode *i, struct file *f)
+{
+	struct tracer_stat_session *session = i->i_private;
+
+	mutex_lock(&session->stat_mutex);
+	reset_stat_session(session);
+	mutex_unlock(&session->stat_mutex);
+
+	return 0;
+}
+
+static const struct file_operations tracing_stat_fops = {
+	.open		= tracing_stat_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= tracing_stat_release
+};
+
+static int tracing_stat_init(void)
+{
+	struct dentry *d_tracing;
+
+	d_tracing = tracing_init_dentry();
+
+	stat_dir = debugfs_create_dir("trace_stat", d_tracing);
+	if (!stat_dir)
+		pr_warning("Could not create debugfs "
+			   "'trace_stat' entry\n");
+	return 0;
+}
+
+static int init_stat_file(struct tracer_stat_session *session)
+{
+	if (!stat_dir && tracing_stat_init())
+		return -ENODEV;
+
+	session->file = debugfs_create_file(session->ts->name, 0644,
+					    stat_dir,
+					    session, &tracing_stat_fops);
+	if (!session->file)
+		return -ENOMEM;
+	return 0;
+}
+
+int register_stat_tracer(struct tracer_stat *trace)
+{
+	struct tracer_stat_session *session, *node, *tmp;
+	int ret;
+
+	if (!trace)
+		return -EINVAL;
+
+	if (!trace->stat_start || !trace->stat_next || !trace->stat_show)
+		return -EINVAL;
+
+	/* Already registered? */
+	mutex_lock(&all_stat_sessions_mutex);
+	list_for_each_entry_safe(node, tmp, &all_stat_sessions, session_list) {
+		if (node->ts == trace) {
+			mutex_unlock(&all_stat_sessions_mutex);
+			return -EINVAL;
+		}
+	}
+	mutex_unlock(&all_stat_sessions_mutex);
+
+	/* Init the session */
+	session = kmalloc(sizeof(struct tracer_stat_session), GFP_KERNEL);
+	if (!session)
+		return -ENOMEM;
+
+	session->ts = trace;
+	INIT_LIST_HEAD(&session->session_list);
+	INIT_LIST_HEAD(&session->stat_list);
+	mutex_init(&session->stat_mutex);
+	session->file = NULL;
+
+	ret = init_stat_file(session);
+	if (ret) {
+		destroy_session(session);
+		return ret;
+	}
+
+	/* Register */
+	mutex_lock(&all_stat_sessions_mutex);
+	list_add_tail(&session->session_list, &all_stat_sessions);
+	mutex_unlock(&all_stat_sessions_mutex);
+
+	return 0;
+}
+
+void unregister_stat_tracer(struct tracer_stat *trace)
+{
+	struct tracer_stat_session *node, *tmp;
+
+	mutex_lock(&all_stat_sessions_mutex);
+	list_for_each_entry_safe(node, tmp, &all_stat_sessions, session_list) {
+		if (node->ts == trace) {
+			list_del(&node->session_list);
+			destroy_session(node);
+			break;
+		}
+	}
+	mutex_unlock(&all_stat_sessions_mutex);
+}
diff --git a/kernel/trace/trace_stat.h b/kernel/trace/trace_stat.h
new file mode 100644
index 0000000..202274c
--- /dev/null
+++ b/kernel/trace/trace_stat.h
@@ -0,0 +1,31 @@
+#ifndef __TRACE_STAT_H
+#define __TRACE_STAT_H
+
+#include <linux/seq_file.h>
+
+/*
+ * If you want to provide a stat file (one-shot statistics), fill
+ * an iterator with stat_start/stat_next and a stat_show callbacks.
+ * The others callbacks are optional.
+ */
+struct tracer_stat {
+	/* The name of your stat file */
+	const char		*name;
+	/* Iteration over statistic entries */
+	void			*(*stat_start)(void);
+	void			*(*stat_next)(void *prev, int idx);
+	/* Compare two entries for stats sorting */
+	int			(*stat_cmp)(void *p1, void *p2);
+	/* Print a stat entry */
+	int			(*stat_show)(struct seq_file *s, void *p);
+	/* Print the headers of your stat entries */
+	int			(*stat_headers)(struct seq_file *s);
+};
+
+/*
+ * Destroy or create a stat file
+ */
+extern int register_stat_tracer(struct tracer_stat *trace);
+extern void unregister_stat_tracer(struct tracer_stat *trace);
+
+#endif /* __TRACE_STAT_H */
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
new file mode 100644
index 0000000..a2a3af2
--- /dev/null
+++ b/kernel/trace/trace_syscalls.c
@@ -0,0 +1,250 @@
+#include <linux/kernel.h>
+#include <linux/ftrace.h>
+#include <asm/syscall.h>
+
+#include "trace_output.h"
+#include "trace.h"
+
+/* Keep a counter of the syscall tracing users */
+static int refcount;
+
+/* Prevent from races on thread flags toggling */
+static DEFINE_MUTEX(syscall_trace_lock);
+
+/* Option to display the parameters types */
+enum {
+	TRACE_SYSCALLS_OPT_TYPES = 0x1,
+};
+
+static struct tracer_opt syscalls_opts[] = {
+	{ TRACER_OPT(syscall_arg_type, TRACE_SYSCALLS_OPT_TYPES) },
+	{ }
+};
+
+static struct tracer_flags syscalls_flags = {
+	.val = 0, /* By default: no parameters types */
+	.opts = syscalls_opts
+};
+
+enum print_line_t
+print_syscall_enter(struct trace_iterator *iter, int flags)
+{
+	struct trace_seq *s = &iter->seq;
+	struct trace_entry *ent = iter->ent;
+	struct syscall_trace_enter *trace;
+	struct syscall_metadata *entry;
+	int i, ret, syscall;
+
+	trace_assign_type(trace, ent);
+
+	syscall = trace->nr;
+
+	entry = syscall_nr_to_meta(syscall);
+	if (!entry)
+		goto end;
+
+	ret = trace_seq_printf(s, "%s(", entry->name);
+	if (!ret)
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	for (i = 0; i < entry->nb_args; i++) {
+		/* parameter types */
+		if (syscalls_flags.val & TRACE_SYSCALLS_OPT_TYPES) {
+			ret = trace_seq_printf(s, "%s ", entry->types[i]);
+			if (!ret)
+				return TRACE_TYPE_PARTIAL_LINE;
+		}
+		/* parameter values */
+		ret = trace_seq_printf(s, "%s: %lx%s ", entry->args[i],
+				       trace->args[i],
+				       i == entry->nb_args - 1 ? ")" : ",");
+		if (!ret)
+			return TRACE_TYPE_PARTIAL_LINE;
+	}
+
+end:
+	trace_seq_printf(s, "\n");
+	return TRACE_TYPE_HANDLED;
+}
+
+enum print_line_t
+print_syscall_exit(struct trace_iterator *iter, int flags)
+{
+	struct trace_seq *s = &iter->seq;
+	struct trace_entry *ent = iter->ent;
+	struct syscall_trace_exit *trace;
+	int syscall;
+	struct syscall_metadata *entry;
+	int ret;
+
+	trace_assign_type(trace, ent);
+
+	syscall = trace->nr;
+
+	entry = syscall_nr_to_meta(syscall);
+	if (!entry) {
+		trace_seq_printf(s, "\n");
+		return TRACE_TYPE_HANDLED;
+	}
+
+	ret = trace_seq_printf(s, "%s -> 0x%lx\n", entry->name,
+				trace->ret);
+	if (!ret)
+		return TRACE_TYPE_PARTIAL_LINE;
+
+	return TRACE_TYPE_HANDLED;
+}
+
+void start_ftrace_syscalls(void)
+{
+	unsigned long flags;
+	struct task_struct *g, *t;
+
+	mutex_lock(&syscall_trace_lock);
+
+	/* Don't enable the flag on the tasks twice */
+	if (++refcount != 1)
+		goto unlock;
+
+	arch_init_ftrace_syscalls();
+	read_lock_irqsave(&tasklist_lock, flags);
+
+	do_each_thread(g, t) {
+		set_tsk_thread_flag(t, TIF_SYSCALL_FTRACE);
+	} while_each_thread(g, t);
+
+	read_unlock_irqrestore(&tasklist_lock, flags);
+
+unlock:
+	mutex_unlock(&syscall_trace_lock);
+}
+
+void stop_ftrace_syscalls(void)
+{
+	unsigned long flags;
+	struct task_struct *g, *t;
+
+	mutex_lock(&syscall_trace_lock);
+
+	/* There are perhaps still some users */
+	if (--refcount)
+		goto unlock;
+
+	read_lock_irqsave(&tasklist_lock, flags);
+
+	do_each_thread(g, t) {
+		clear_tsk_thread_flag(t, TIF_SYSCALL_FTRACE);
+	} while_each_thread(g, t);
+
+	read_unlock_irqrestore(&tasklist_lock, flags);
+
+unlock:
+	mutex_unlock(&syscall_trace_lock);
+}
+
+void ftrace_syscall_enter(struct pt_regs *regs)
+{
+	struct syscall_trace_enter *entry;
+	struct syscall_metadata *sys_data;
+	struct ring_buffer_event *event;
+	int size;
+	int syscall_nr;
+
+	syscall_nr = syscall_get_nr(current, regs);
+
+	sys_data = syscall_nr_to_meta(syscall_nr);
+	if (!sys_data)
+		return;
+
+	size = sizeof(*entry) + sizeof(unsigned long) * sys_data->nb_args;
+
+	event = trace_current_buffer_lock_reserve(TRACE_SYSCALL_ENTER, size,
+							0, 0);
+	if (!event)
+		return;
+
+	entry = ring_buffer_event_data(event);
+	entry->nr = syscall_nr;
+	syscall_get_arguments(current, regs, 0, sys_data->nb_args, entry->args);
+
+	trace_current_buffer_unlock_commit(event, 0, 0);
+	trace_wake_up();
+}
+
+void ftrace_syscall_exit(struct pt_regs *regs)
+{
+	struct syscall_trace_exit *entry;
+	struct syscall_metadata *sys_data;
+	struct ring_buffer_event *event;
+	int syscall_nr;
+
+	syscall_nr = syscall_get_nr(current, regs);
+
+	sys_data = syscall_nr_to_meta(syscall_nr);
+	if (!sys_data)
+		return;
+
+	event = trace_current_buffer_lock_reserve(TRACE_SYSCALL_EXIT,
+				sizeof(*entry), 0, 0);
+	if (!event)
+		return;
+
+	entry = ring_buffer_event_data(event);
+	entry->nr = syscall_nr;
+	entry->ret = syscall_get_return_value(current, regs);
+
+	trace_current_buffer_unlock_commit(event, 0, 0);
+	trace_wake_up();
+}
+
+static int init_syscall_tracer(struct trace_array *tr)
+{
+	start_ftrace_syscalls();
+
+	return 0;
+}
+
+static void reset_syscall_tracer(struct trace_array *tr)
+{
+	stop_ftrace_syscalls();
+	tracing_reset_online_cpus(tr);
+}
+
+static struct trace_event syscall_enter_event = {
+	.type	 	= TRACE_SYSCALL_ENTER,
+	.trace		= print_syscall_enter,
+};
+
+static struct trace_event syscall_exit_event = {
+	.type	 	= TRACE_SYSCALL_EXIT,
+	.trace		= print_syscall_exit,
+};
+
+static struct tracer syscall_tracer __read_mostly = {
+	.name	     	= "syscall",
+	.init		= init_syscall_tracer,
+	.reset		= reset_syscall_tracer,
+	.flags		= &syscalls_flags,
+};
+
+__init int register_ftrace_syscalls(void)
+{
+	int ret;
+
+	ret = register_ftrace_event(&syscall_enter_event);
+	if (!ret) {
+		printk(KERN_WARNING "event %d failed to register\n",
+		       syscall_enter_event.type);
+		WARN_ON_ONCE(1);
+	}
+
+	ret = register_ftrace_event(&syscall_exit_event);
+	if (!ret) {
+		printk(KERN_WARNING "event %d failed to register\n",
+		       syscall_exit_event.type);
+		WARN_ON_ONCE(1);
+	}
+
+	return register_tracer(&syscall_tracer);
+}
+device_initcall(register_ftrace_syscalls);
diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c
index eaca5ad..91fd19c 100644
--- a/kernel/trace/trace_sysprof.c
+++ b/kernel/trace/trace_sysprof.c
@@ -88,7 +88,7 @@
 	}
 }
 
-const static struct stacktrace_ops backtrace_ops = {
+static const struct stacktrace_ops backtrace_ops = {
 	.warning		= backtrace_warning,
 	.warning_symbol		= backtrace_warning_symbol,
 	.stack			= backtrace_stack,
@@ -226,15 +226,6 @@
 		stop_stack_timer(cpu);
 }
 
-static void start_stack_trace(struct trace_array *tr)
-{
-	mutex_lock(&sample_timer_lock);
-	tracing_reset_online_cpus(tr);
-	start_stack_timers();
-	tracer_enabled = 1;
-	mutex_unlock(&sample_timer_lock);
-}
-
 static void stop_stack_trace(struct trace_array *tr)
 {
 	mutex_lock(&sample_timer_lock);
@@ -247,12 +238,18 @@
 {
 	sysprof_trace = tr;
 
-	start_stack_trace(tr);
+	tracing_start_cmdline_record();
+
+	mutex_lock(&sample_timer_lock);
+	start_stack_timers();
+	tracer_enabled = 1;
+	mutex_unlock(&sample_timer_lock);
 	return 0;
 }
 
 static void stack_trace_reset(struct trace_array *tr)
 {
+	tracing_stop_cmdline_record();
 	stop_stack_trace(tr);
 }
 
@@ -317,7 +314,7 @@
 	return cnt;
 }
 
-static struct file_operations sysprof_sample_fops = {
+static const struct file_operations sysprof_sample_fops = {
 	.read		= sysprof_sample_read,
 	.write		= sysprof_sample_write,
 };
@@ -330,5 +327,5 @@
 			d_tracer, NULL, &sysprof_sample_fops);
 	if (entry)
 		return;
-	pr_warning("Could not create debugfs 'dyn_ftrace_total_info' entry\n");
+	pr_warning("Could not create debugfs 'sysprof_sample_period' entry\n");
 }
diff --git a/kernel/trace/trace_workqueue.c b/kernel/trace/trace_workqueue.c
new file mode 100644
index 0000000..797201e
--- /dev/null
+++ b/kernel/trace/trace_workqueue.c
@@ -0,0 +1,288 @@
+/*
+ * Workqueue statistical tracer.
+ *
+ * Copyright (C) 2008 Frederic Weisbecker <fweisbec@gmail.com>
+ *
+ */
+
+
+#include <trace/workqueue.h>
+#include <linux/list.h>
+#include <linux/percpu.h>
+#include "trace_stat.h"
+#include "trace.h"
+
+
+/* A cpu workqueue thread */
+struct cpu_workqueue_stats {
+	struct list_head            list;
+/* Useful to know if we print the cpu headers */
+	bool		            first_entry;
+	int		            cpu;
+	pid_t			    pid;
+/* Can be inserted from interrupt or user context, need to be atomic */
+	atomic_t	            inserted;
+/*
+ *  Don't need to be atomic, works are serialized in a single workqueue thread
+ *  on a single CPU.
+ */
+	unsigned int		    executed;
+};
+
+/* List of workqueue threads on one cpu */
+struct workqueue_global_stats {
+	struct list_head	list;
+	spinlock_t		lock;
+};
+
+/* Don't need a global lock because allocated before the workqueues, and
+ * never freed.
+ */
+static DEFINE_PER_CPU(struct workqueue_global_stats, all_workqueue_stat);
+#define workqueue_cpu_stat(cpu) (&per_cpu(all_workqueue_stat, cpu))
+
+/* Insertion of a work */
+static void
+probe_workqueue_insertion(struct task_struct *wq_thread,
+			  struct work_struct *work)
+{
+	int cpu = cpumask_first(&wq_thread->cpus_allowed);
+	struct cpu_workqueue_stats *node, *next;
+	unsigned long flags;
+
+	spin_lock_irqsave(&workqueue_cpu_stat(cpu)->lock, flags);
+	list_for_each_entry_safe(node, next, &workqueue_cpu_stat(cpu)->list,
+							list) {
+		if (node->pid == wq_thread->pid) {
+			atomic_inc(&node->inserted);
+			goto found;
+		}
+	}
+	pr_debug("trace_workqueue: entry not found\n");
+found:
+	spin_unlock_irqrestore(&workqueue_cpu_stat(cpu)->lock, flags);
+}
+
+/* Execution of a work */
+static void
+probe_workqueue_execution(struct task_struct *wq_thread,
+			  struct work_struct *work)
+{
+	int cpu = cpumask_first(&wq_thread->cpus_allowed);
+	struct cpu_workqueue_stats *node, *next;
+	unsigned long flags;
+
+	spin_lock_irqsave(&workqueue_cpu_stat(cpu)->lock, flags);
+	list_for_each_entry_safe(node, next, &workqueue_cpu_stat(cpu)->list,
+							list) {
+		if (node->pid == wq_thread->pid) {
+			node->executed++;
+			goto found;
+		}
+	}
+	pr_debug("trace_workqueue: entry not found\n");
+found:
+	spin_unlock_irqrestore(&workqueue_cpu_stat(cpu)->lock, flags);
+}
+
+/* Creation of a cpu workqueue thread */
+static void probe_workqueue_creation(struct task_struct *wq_thread, int cpu)
+{
+	struct cpu_workqueue_stats *cws;
+	unsigned long flags;
+
+	WARN_ON(cpu < 0);
+
+	/* Workqueues are sometimes created in atomic context */
+	cws = kzalloc(sizeof(struct cpu_workqueue_stats), GFP_ATOMIC);
+	if (!cws) {
+		pr_warning("trace_workqueue: not enough memory\n");
+		return;
+	}
+	INIT_LIST_HEAD(&cws->list);
+	cws->cpu = cpu;
+
+	cws->pid = wq_thread->pid;
+
+	spin_lock_irqsave(&workqueue_cpu_stat(cpu)->lock, flags);
+	if (list_empty(&workqueue_cpu_stat(cpu)->list))
+		cws->first_entry = true;
+	list_add_tail(&cws->list, &workqueue_cpu_stat(cpu)->list);
+	spin_unlock_irqrestore(&workqueue_cpu_stat(cpu)->lock, flags);
+}
+
+/* Destruction of a cpu workqueue thread */
+static void probe_workqueue_destruction(struct task_struct *wq_thread)
+{
+	/* Workqueue only execute on one cpu */
+	int cpu = cpumask_first(&wq_thread->cpus_allowed);
+	struct cpu_workqueue_stats *node, *next;
+	unsigned long flags;
+
+	spin_lock_irqsave(&workqueue_cpu_stat(cpu)->lock, flags);
+	list_for_each_entry_safe(node, next, &workqueue_cpu_stat(cpu)->list,
+							list) {
+		if (node->pid == wq_thread->pid) {
+			list_del(&node->list);
+			kfree(node);
+			goto found;
+		}
+	}
+
+	pr_debug("trace_workqueue: don't find workqueue to destroy\n");
+found:
+	spin_unlock_irqrestore(&workqueue_cpu_stat(cpu)->lock, flags);
+
+}
+
+static struct cpu_workqueue_stats *workqueue_stat_start_cpu(int cpu)
+{
+	unsigned long flags;
+	struct cpu_workqueue_stats *ret = NULL;
+
+
+	spin_lock_irqsave(&workqueue_cpu_stat(cpu)->lock, flags);
+
+	if (!list_empty(&workqueue_cpu_stat(cpu)->list))
+		ret = list_entry(workqueue_cpu_stat(cpu)->list.next,
+				 struct cpu_workqueue_stats, list);
+
+	spin_unlock_irqrestore(&workqueue_cpu_stat(cpu)->lock, flags);
+
+	return ret;
+}
+
+static void *workqueue_stat_start(void)
+{
+	int cpu;
+	void *ret = NULL;
+
+	for_each_possible_cpu(cpu) {
+		ret = workqueue_stat_start_cpu(cpu);
+		if (ret)
+			return ret;
+	}
+	return NULL;
+}
+
+static void *workqueue_stat_next(void *prev, int idx)
+{
+	struct cpu_workqueue_stats *prev_cws = prev;
+	int cpu = prev_cws->cpu;
+	unsigned long flags;
+	void *ret = NULL;
+
+	spin_lock_irqsave(&workqueue_cpu_stat(cpu)->lock, flags);
+	if (list_is_last(&prev_cws->list, &workqueue_cpu_stat(cpu)->list)) {
+		spin_unlock_irqrestore(&workqueue_cpu_stat(cpu)->lock, flags);
+		do {
+			cpu = cpumask_next(cpu, cpu_possible_mask);
+			if (cpu >= nr_cpu_ids)
+				return NULL;
+		} while (!(ret = workqueue_stat_start_cpu(cpu)));
+		return ret;
+	}
+	spin_unlock_irqrestore(&workqueue_cpu_stat(cpu)->lock, flags);
+
+	return list_entry(prev_cws->list.next, struct cpu_workqueue_stats,
+			  list);
+}
+
+static int workqueue_stat_show(struct seq_file *s, void *p)
+{
+	struct cpu_workqueue_stats *cws = p;
+	unsigned long flags;
+	int cpu = cws->cpu;
+	struct pid *pid;
+	struct task_struct *tsk;
+
+	spin_lock_irqsave(&workqueue_cpu_stat(cpu)->lock, flags);
+	if (&cws->list == workqueue_cpu_stat(cpu)->list.next)
+		seq_printf(s, "\n");
+	spin_unlock_irqrestore(&workqueue_cpu_stat(cpu)->lock, flags);
+
+	pid = find_get_pid(cws->pid);
+	if (pid) {
+		tsk = get_pid_task(pid, PIDTYPE_PID);
+		if (tsk) {
+			seq_printf(s, "%3d %6d     %6u       %s\n", cws->cpu,
+				   atomic_read(&cws->inserted), cws->executed,
+				   tsk->comm);
+			put_task_struct(tsk);
+		}
+		put_pid(pid);
+	}
+
+	return 0;
+}
+
+static int workqueue_stat_headers(struct seq_file *s)
+{
+	seq_printf(s, "# CPU  INSERTED  EXECUTED   NAME\n");
+	seq_printf(s, "# |      |         |          |\n");
+	return 0;
+}
+
+struct tracer_stat workqueue_stats __read_mostly = {
+	.name = "workqueues",
+	.stat_start = workqueue_stat_start,
+	.stat_next = workqueue_stat_next,
+	.stat_show = workqueue_stat_show,
+	.stat_headers = workqueue_stat_headers
+};
+
+
+int __init stat_workqueue_init(void)
+{
+	if (register_stat_tracer(&workqueue_stats)) {
+		pr_warning("Unable to register workqueue stat tracer\n");
+		return 1;
+	}
+
+	return 0;
+}
+fs_initcall(stat_workqueue_init);
+
+/*
+ * Workqueues are created very early, just after pre-smp initcalls.
+ * So we must register our tracepoints at this stage.
+ */
+int __init trace_workqueue_early_init(void)
+{
+	int ret, cpu;
+
+	ret = register_trace_workqueue_insertion(probe_workqueue_insertion);
+	if (ret)
+		goto out;
+
+	ret = register_trace_workqueue_execution(probe_workqueue_execution);
+	if (ret)
+		goto no_insertion;
+
+	ret = register_trace_workqueue_creation(probe_workqueue_creation);
+	if (ret)
+		goto no_execution;
+
+	ret = register_trace_workqueue_destruction(probe_workqueue_destruction);
+	if (ret)
+		goto no_creation;
+
+	for_each_possible_cpu(cpu) {
+		spin_lock_init(&workqueue_cpu_stat(cpu)->lock);
+		INIT_LIST_HEAD(&workqueue_cpu_stat(cpu)->list);
+	}
+
+	return 0;
+
+no_creation:
+	unregister_trace_workqueue_creation(probe_workqueue_creation);
+no_execution:
+	unregister_trace_workqueue_execution(probe_workqueue_execution);
+no_insertion:
+	unregister_trace_workqueue_insertion(probe_workqueue_insertion);
+out:
+	pr_warning("trace_workqueue: unable to trace workqueues\n");
+
+	return 1;
+}
+early_initcall(trace_workqueue_early_init);
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
index 7960274..1ef5d3a 100644
--- a/kernel/tracepoint.c
+++ b/kernel/tracepoint.c
@@ -272,12 +272,15 @@
  *
  * Updates the probe callback corresponding to a range of tracepoints.
  */
-void tracepoint_update_probe_range(struct tracepoint *begin,
-	struct tracepoint *end)
+void
+tracepoint_update_probe_range(struct tracepoint *begin, struct tracepoint *end)
 {
 	struct tracepoint *iter;
 	struct tracepoint_entry *mark_entry;
 
+	if (!begin)
+		return;
+
 	mutex_lock(&tracepoints_mutex);
 	for (iter = begin; iter < end; iter++) {
 		mark_entry = get_tracepoint(iter->name);
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 32f8e0d..b6b966c 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -33,6 +33,7 @@
 #include <linux/kallsyms.h>
 #include <linux/debug_locks.h>
 #include <linux/lockdep.h>
+#include <trace/workqueue.h>
 
 /*
  * The per-CPU workqueue (if single thread, we always use the first
@@ -123,9 +124,13 @@
 	return (void *) (atomic_long_read(&work->data) & WORK_STRUCT_WQ_DATA_MASK);
 }
 
+DEFINE_TRACE(workqueue_insertion);
+
 static void insert_work(struct cpu_workqueue_struct *cwq,
 			struct work_struct *work, struct list_head *head)
 {
+	trace_workqueue_insertion(cwq->thread, work);
+
 	set_wq_data(work, cwq);
 	/*
 	 * Ensure that we get the right work->data if we see the
@@ -257,6 +262,8 @@
 }
 EXPORT_SYMBOL_GPL(queue_delayed_work_on);
 
+DEFINE_TRACE(workqueue_execution);
+
 static void run_workqueue(struct cpu_workqueue_struct *cwq)
 {
 	spin_lock_irq(&cwq->lock);
@@ -275,7 +282,7 @@
 		 */
 		struct lockdep_map lockdep_map = work->lockdep_map;
 #endif
-
+		trace_workqueue_execution(cwq->thread, work);
 		cwq->current_work = work;
 		list_del_init(cwq->worklist.next);
 		spin_unlock_irq(&cwq->lock);
@@ -746,6 +753,8 @@
 	return cwq;
 }
 
+DEFINE_TRACE(workqueue_creation);
+
 static int create_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu)
 {
 	struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
@@ -768,6 +777,8 @@
 		sched_setscheduler_nocheck(p, SCHED_FIFO, &param);
 	cwq->thread = p;
 
+	trace_workqueue_creation(cwq->thread, cpu);
+
 	return 0;
 }
 
@@ -849,6 +860,8 @@
 }
 EXPORT_SYMBOL_GPL(__create_workqueue_key);
 
+DEFINE_TRACE(workqueue_destruction);
+
 static void cleanup_workqueue_thread(struct cpu_workqueue_struct *cwq)
 {
 	/*
@@ -872,6 +885,7 @@
 	 * checks list_empty(), and a "normal" queue_work() can't use
 	 * a dead CPU.
 	 */
+	trace_workqueue_destruction(cwq->thread);
 	kthread_stop(cwq->thread);
 	cwq->thread = NULL;
 }
diff --git a/lib/Kconfig b/lib/Kconfig
index 2a9c69f..8ade0a7 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -2,6 +2,9 @@
 # Library configuration
 #
 
+config BINARY_PRINTF
+	def_bool n
+
 menu "Library routines"
 
 config BITREVERSE
diff --git a/lib/debugobjects.c b/lib/debugobjects.c
index 5d99be1..2755a3b 100644
--- a/lib/debugobjects.c
+++ b/lib/debugobjects.c
@@ -30,7 +30,7 @@
 
 static struct debug_bucket	obj_hash[ODEBUG_HASH_SIZE];
 
-static struct debug_obj		obj_static_pool[ODEBUG_POOL_SIZE];
+static struct debug_obj		obj_static_pool[ODEBUG_POOL_SIZE] __initdata;
 
 static DEFINE_SPINLOCK(pool_lock);
 
@@ -50,12 +50,23 @@
 
 static struct debug_obj_descr	*descr_test  __read_mostly;
 
+static void free_obj_work(struct work_struct *work);
+static DECLARE_WORK(debug_obj_work, free_obj_work);
+
 static int __init enable_object_debug(char *str)
 {
 	debug_objects_enabled = 1;
 	return 0;
 }
+
+static int __init disable_object_debug(char *str)
+{
+	debug_objects_enabled = 0;
+	return 0;
+}
+
 early_param("debug_objects", enable_object_debug);
+early_param("no_debug_objects", disable_object_debug);
 
 static const char *obj_states[ODEBUG_STATE_MAX] = {
 	[ODEBUG_STATE_NONE]		= "none",
@@ -146,25 +157,51 @@
 }
 
 /*
- * Put the object back into the pool or give it back to kmem_cache:
+ * workqueue function to free objects.
+ */
+static void free_obj_work(struct work_struct *work)
+{
+	struct debug_obj *obj;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pool_lock, flags);
+	while (obj_pool_free > ODEBUG_POOL_SIZE) {
+		obj = hlist_entry(obj_pool.first, typeof(*obj), node);
+		hlist_del(&obj->node);
+		obj_pool_free--;
+		/*
+		 * We release pool_lock across kmem_cache_free() to
+		 * avoid contention on pool_lock.
+		 */
+		spin_unlock_irqrestore(&pool_lock, flags);
+		kmem_cache_free(obj_cache, obj);
+		spin_lock_irqsave(&pool_lock, flags);
+	}
+	spin_unlock_irqrestore(&pool_lock, flags);
+}
+
+/*
+ * Put the object back into the pool and schedule work to free objects
+ * if necessary.
  */
 static void free_object(struct debug_obj *obj)
 {
-	unsigned long idx = (unsigned long)(obj - obj_static_pool);
 	unsigned long flags;
+	int sched = 0;
 
-	if (obj_pool_free < ODEBUG_POOL_SIZE || idx < ODEBUG_POOL_SIZE) {
-		spin_lock_irqsave(&pool_lock, flags);
-		hlist_add_head(&obj->node, &obj_pool);
-		obj_pool_free++;
-		obj_pool_used--;
-		spin_unlock_irqrestore(&pool_lock, flags);
-	} else {
-		spin_lock_irqsave(&pool_lock, flags);
-		obj_pool_used--;
-		spin_unlock_irqrestore(&pool_lock, flags);
-		kmem_cache_free(obj_cache, obj);
-	}
+	spin_lock_irqsave(&pool_lock, flags);
+	/*
+	 * schedule work when the pool is filled and the cache is
+	 * initialized:
+	 */
+	if (obj_pool_free > ODEBUG_POOL_SIZE && obj_cache)
+		sched = !work_pending(&debug_obj_work);
+	hlist_add_head(&obj->node, &obj_pool);
+	obj_pool_free++;
+	obj_pool_used--;
+	spin_unlock_irqrestore(&pool_lock, flags);
+	if (sched)
+		schedule_work(&debug_obj_work);
 }
 
 /*
@@ -876,6 +913,63 @@
 }
 
 /*
+ * Convert the statically allocated objects to dynamic ones:
+ */
+static int debug_objects_replace_static_objects(void)
+{
+	struct debug_bucket *db = obj_hash;
+	struct hlist_node *node, *tmp;
+	struct debug_obj *obj, *new;
+	HLIST_HEAD(objects);
+	int i, cnt = 0;
+
+	for (i = 0; i < ODEBUG_POOL_SIZE; i++) {
+		obj = kmem_cache_zalloc(obj_cache, GFP_KERNEL);
+		if (!obj)
+			goto free;
+		hlist_add_head(&obj->node, &objects);
+	}
+
+	/*
+	 * When debug_objects_mem_init() is called we know that only
+	 * one CPU is up, so disabling interrupts is enough
+	 * protection. This avoids the lockdep hell of lock ordering.
+	 */
+	local_irq_disable();
+
+	/* Remove the statically allocated objects from the pool */
+	hlist_for_each_entry_safe(obj, node, tmp, &obj_pool, node)
+		hlist_del(&obj->node);
+	/* Move the allocated objects to the pool */
+	hlist_move_list(&objects, &obj_pool);
+
+	/* Replace the active object references */
+	for (i = 0; i < ODEBUG_HASH_SIZE; i++, db++) {
+		hlist_move_list(&db->list, &objects);
+
+		hlist_for_each_entry(obj, node, &objects, node) {
+			new = hlist_entry(obj_pool.first, typeof(*obj), node);
+			hlist_del(&new->node);
+			/* copy object data */
+			*new = *obj;
+			hlist_add_head(&new->node, &db->list);
+			cnt++;
+		}
+	}
+
+	printk(KERN_DEBUG "ODEBUG: %d of %d active objects replaced\n", cnt,
+	       obj_pool_used);
+	local_irq_enable();
+	return 0;
+free:
+	hlist_for_each_entry_safe(obj, node, tmp, &objects, node) {
+		hlist_del(&obj->node);
+		kmem_cache_free(obj_cache, obj);
+	}
+	return -ENOMEM;
+}
+
+/*
  * Called after the kmem_caches are functional to setup a dedicated
  * cache pool, which has the SLAB_DEBUG_OBJECTS flag set. This flag
  * prevents that the debug code is called on kmem_cache_free() for the
@@ -890,8 +984,11 @@
 				      sizeof (struct debug_obj), 0,
 				      SLAB_DEBUG_OBJECTS, NULL);
 
-	if (!obj_cache)
+	if (!obj_cache || debug_objects_replace_static_objects()) {
 		debug_objects_enabled = 0;
-	else
+		if (obj_cache)
+			kmem_cache_destroy(obj_cache);
+		printk(KERN_WARNING "ODEBUG: out of memory.\n");
+	} else
 		debug_objects_selftest();
 }
diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c
index 280332c..619313e 100644
--- a/lib/locking-selftest.c
+++ b/lib/locking-selftest.c
@@ -157,11 +157,11 @@
 #define SOFTIRQ_ENTER()				\
 		local_bh_disable();		\
 		local_irq_disable();		\
-		trace_softirq_enter();		\
+		lockdep_softirq_enter();	\
 		WARN_ON(!in_softirq());
 
 #define SOFTIRQ_EXIT()				\
-		trace_softirq_exit();		\
+		lockdep_softirq_exit();		\
 		local_irq_enable();		\
 		local_bh_enable();
 
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 0fbd012..be3001f 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -396,7 +396,38 @@
 #define SMALL	32		/* Must be 32 == 0x20 */
 #define SPECIAL	64		/* 0x */
 
-static char *number(char *buf, char *end, unsigned long long num, int base, int size, int precision, int type)
+enum format_type {
+	FORMAT_TYPE_NONE, /* Just a string part */
+	FORMAT_TYPE_WIDTH,
+	FORMAT_TYPE_PRECISION,
+	FORMAT_TYPE_CHAR,
+	FORMAT_TYPE_STR,
+	FORMAT_TYPE_PTR,
+	FORMAT_TYPE_PERCENT_CHAR,
+	FORMAT_TYPE_INVALID,
+	FORMAT_TYPE_LONG_LONG,
+	FORMAT_TYPE_ULONG,
+	FORMAT_TYPE_LONG,
+	FORMAT_TYPE_USHORT,
+	FORMAT_TYPE_SHORT,
+	FORMAT_TYPE_UINT,
+	FORMAT_TYPE_INT,
+	FORMAT_TYPE_NRCHARS,
+	FORMAT_TYPE_SIZE_T,
+	FORMAT_TYPE_PTRDIFF
+};
+
+struct printf_spec {
+	enum format_type	type;
+	int			flags;		/* flags to number() */
+	int			field_width;	/* width of output field */
+	int			base;
+	int			precision;	/* # of digits/chars */
+	int			qualifier;
+};
+
+static char *number(char *buf, char *end, unsigned long long num,
+			struct printf_spec spec)
 {
 	/* we are called with base 8, 10 or 16, only, thus don't need "G..."  */
 	static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */
@@ -404,32 +435,32 @@
 	char tmp[66];
 	char sign;
 	char locase;
-	int need_pfx = ((type & SPECIAL) && base != 10);
+	int need_pfx = ((spec.flags & SPECIAL) && spec.base != 10);
 	int i;
 
 	/* locase = 0 or 0x20. ORing digits or letters with 'locase'
 	 * produces same digits or (maybe lowercased) letters */
-	locase = (type & SMALL);
-	if (type & LEFT)
-		type &= ~ZEROPAD;
+	locase = (spec.flags & SMALL);
+	if (spec.flags & LEFT)
+		spec.flags &= ~ZEROPAD;
 	sign = 0;
-	if (type & SIGN) {
+	if (spec.flags & SIGN) {
 		if ((signed long long) num < 0) {
 			sign = '-';
 			num = - (signed long long) num;
-			size--;
-		} else if (type & PLUS) {
+			spec.field_width--;
+		} else if (spec.flags & PLUS) {
 			sign = '+';
-			size--;
-		} else if (type & SPACE) {
+			spec.field_width--;
+		} else if (spec.flags & SPACE) {
 			sign = ' ';
-			size--;
+			spec.field_width--;
 		}
 	}
 	if (need_pfx) {
-		size--;
-		if (base == 16)
-			size--;
+		spec.field_width--;
+		if (spec.base == 16)
+			spec.field_width--;
 	}
 
 	/* generate full string in tmp[], in reverse order */
@@ -441,10 +472,10 @@
 		tmp[i++] = (digits[do_div(num,base)] | locase);
 	} while (num != 0);
 	*/
-	else if (base != 10) { /* 8 or 16 */
-		int mask = base - 1;
+	else if (spec.base != 10) { /* 8 or 16 */
+		int mask = spec.base - 1;
 		int shift = 3;
-		if (base == 16) shift = 4;
+		if (spec.base == 16) shift = 4;
 		do {
 			tmp[i++] = (digits[((unsigned char)num) & mask] | locase);
 			num >>= shift;
@@ -454,12 +485,12 @@
 	}
 
 	/* printing 100 using %2d gives "100", not "00" */
-	if (i > precision)
-		precision = i;
+	if (i > spec.precision)
+		spec.precision = i;
 	/* leading space padding */
-	size -= precision;
-	if (!(type & (ZEROPAD+LEFT))) {
-		while(--size >= 0) {
+	spec.field_width -= spec.precision;
+	if (!(spec.flags & (ZEROPAD+LEFT))) {
+		while(--spec.field_width >= 0) {
 			if (buf < end)
 				*buf = ' ';
 			++buf;
@@ -476,23 +507,23 @@
 		if (buf < end)
 			*buf = '0';
 		++buf;
-		if (base == 16) {
+		if (spec.base == 16) {
 			if (buf < end)
 				*buf = ('X' | locase);
 			++buf;
 		}
 	}
 	/* zero or space padding */
-	if (!(type & LEFT)) {
-		char c = (type & ZEROPAD) ? '0' : ' ';
-		while (--size >= 0) {
+	if (!(spec.flags & LEFT)) {
+		char c = (spec.flags & ZEROPAD) ? '0' : ' ';
+		while (--spec.field_width >= 0) {
 			if (buf < end)
 				*buf = c;
 			++buf;
 		}
 	}
 	/* hmm even more zero padding? */
-	while (i <= --precision) {
+	while (i <= --spec.precision) {
 		if (buf < end)
 			*buf = '0';
 		++buf;
@@ -504,7 +535,7 @@
 		++buf;
 	}
 	/* trailing space padding */
-	while (--size >= 0) {
+	while (--spec.field_width >= 0) {
 		if (buf < end)
 			*buf = ' ';
 		++buf;
@@ -512,17 +543,17 @@
 	return buf;
 }
 
-static char *string(char *buf, char *end, char *s, int field_width, int precision, int flags)
+static char *string(char *buf, char *end, char *s, struct printf_spec spec)
 {
 	int len, i;
 
 	if ((unsigned long)s < PAGE_SIZE)
 		s = "<NULL>";
 
-	len = strnlen(s, precision);
+	len = strnlen(s, spec.precision);
 
-	if (!(flags & LEFT)) {
-		while (len < field_width--) {
+	if (!(spec.flags & LEFT)) {
+		while (len < spec.field_width--) {
 			if (buf < end)
 				*buf = ' ';
 			++buf;
@@ -533,7 +564,7 @@
 			*buf = *s;
 		++buf; ++s;
 	}
-	while (len < field_width--) {
+	while (len < spec.field_width--) {
 		if (buf < end)
 			*buf = ' ';
 		++buf;
@@ -541,21 +572,24 @@
 	return buf;
 }
 
-static char *symbol_string(char *buf, char *end, void *ptr, int field_width, int precision, int flags)
+static char *symbol_string(char *buf, char *end, void *ptr,
+				struct printf_spec spec)
 {
 	unsigned long value = (unsigned long) ptr;
 #ifdef CONFIG_KALLSYMS
 	char sym[KSYM_SYMBOL_LEN];
 	sprint_symbol(sym, value);
-	return string(buf, end, sym, field_width, precision, flags);
+	return string(buf, end, sym, spec);
 #else
-	field_width = 2*sizeof(void *);
-	flags |= SPECIAL | SMALL | ZEROPAD;
-	return number(buf, end, value, 16, field_width, precision, flags);
+	spec.field_width = 2*sizeof(void *);
+	spec.flags |= SPECIAL | SMALL | ZEROPAD;
+	spec.base = 16;
+	return number(buf, end, value, spec);
 #endif
 }
 
-static char *resource_string(char *buf, char *end, struct resource *res, int field_width, int precision, int flags)
+static char *resource_string(char *buf, char *end, struct resource *res,
+				struct printf_spec spec)
 {
 #ifndef IO_RSRC_PRINTK_SIZE
 #define IO_RSRC_PRINTK_SIZE	4
@@ -564,7 +598,11 @@
 #ifndef MEM_RSRC_PRINTK_SIZE
 #define MEM_RSRC_PRINTK_SIZE	8
 #endif
-
+	struct printf_spec num_spec = {
+		.base = 16,
+		.precision = -1,
+		.flags = SPECIAL | SMALL | ZEROPAD,
+	};
 	/* room for the actual numbers, the two "0x", -, [, ] and the final zero */
 	char sym[4*sizeof(resource_size_t) + 8];
 	char *p = sym, *pend = sym + sizeof(sym);
@@ -576,17 +614,18 @@
 		size = MEM_RSRC_PRINTK_SIZE;
 
 	*p++ = '[';
-	p = number(p, pend, res->start, 16, size, -1, SPECIAL | SMALL | ZEROPAD);
+	num_spec.field_width = size;
+	p = number(p, pend, res->start, num_spec);
 	*p++ = '-';
-	p = number(p, pend, res->end, 16, size, -1, SPECIAL | SMALL | ZEROPAD);
+	p = number(p, pend, res->end, num_spec);
 	*p++ = ']';
 	*p = 0;
 
-	return string(buf, end, sym, field_width, precision, flags);
+	return string(buf, end, sym, spec);
 }
 
-static char *mac_address_string(char *buf, char *end, u8 *addr, int field_width,
-				int precision, int flags)
+static char *mac_address_string(char *buf, char *end, u8 *addr,
+				struct printf_spec spec)
 {
 	char mac_addr[6 * 3]; /* (6 * 2 hex digits), 5 colons and trailing zero */
 	char *p = mac_addr;
@@ -594,16 +633,17 @@
 
 	for (i = 0; i < 6; i++) {
 		p = pack_hex_byte(p, addr[i]);
-		if (!(flags & SPECIAL) && i != 5)
+		if (!(spec.flags & SPECIAL) && i != 5)
 			*p++ = ':';
 	}
 	*p = '\0';
+	spec.flags &= ~SPECIAL;
 
-	return string(buf, end, mac_addr, field_width, precision, flags & ~SPECIAL);
+	return string(buf, end, mac_addr, spec);
 }
 
-static char *ip6_addr_string(char *buf, char *end, u8 *addr, int field_width,
-			 int precision, int flags)
+static char *ip6_addr_string(char *buf, char *end, u8 *addr,
+				struct printf_spec spec)
 {
 	char ip6_addr[8 * 5]; /* (8 * 4 hex digits), 7 colons and trailing zero */
 	char *p = ip6_addr;
@@ -612,16 +652,17 @@
 	for (i = 0; i < 8; i++) {
 		p = pack_hex_byte(p, addr[2 * i]);
 		p = pack_hex_byte(p, addr[2 * i + 1]);
-		if (!(flags & SPECIAL) && i != 7)
+		if (!(spec.flags & SPECIAL) && i != 7)
 			*p++ = ':';
 	}
 	*p = '\0';
+	spec.flags &= ~SPECIAL;
 
-	return string(buf, end, ip6_addr, field_width, precision, flags & ~SPECIAL);
+	return string(buf, end, ip6_addr, spec);
 }
 
-static char *ip4_addr_string(char *buf, char *end, u8 *addr, int field_width,
-			 int precision, int flags)
+static char *ip4_addr_string(char *buf, char *end, u8 *addr,
+				struct printf_spec spec)
 {
 	char ip4_addr[4 * 4]; /* (4 * 3 decimal digits), 3 dots and trailing zero */
 	char temp[3];	/* hold each IP quad in reverse order */
@@ -637,8 +678,9 @@
 			*p++ = '.';
 	}
 	*p = '\0';
+	spec.flags &= ~SPECIAL;
 
-	return string(buf, end, ip4_addr, field_width, precision, flags & ~SPECIAL);
+	return string(buf, end, ip4_addr, spec);
 }
 
 /*
@@ -663,41 +705,233 @@
  * function pointers are really function descriptors, which contain a
  * pointer to the real address.
  */
-static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field_width, int precision, int flags)
+static char *pointer(const char *fmt, char *buf, char *end, void *ptr,
+			struct printf_spec spec)
 {
 	if (!ptr)
-		return string(buf, end, "(null)", field_width, precision, flags);
+		return string(buf, end, "(null)", spec);
 
 	switch (*fmt) {
 	case 'F':
 		ptr = dereference_function_descriptor(ptr);
 		/* Fallthrough */
 	case 'S':
-		return symbol_string(buf, end, ptr, field_width, precision, flags);
+		return symbol_string(buf, end, ptr, spec);
 	case 'R':
-		return resource_string(buf, end, ptr, field_width, precision, flags);
+		return resource_string(buf, end, ptr, spec);
 	case 'm':
-		flags |= SPECIAL;
+		spec.flags |= SPECIAL;
 		/* Fallthrough */
 	case 'M':
-		return mac_address_string(buf, end, ptr, field_width, precision, flags);
+		return mac_address_string(buf, end, ptr, spec);
 	case 'i':
-		flags |= SPECIAL;
+		spec.flags |= SPECIAL;
 		/* Fallthrough */
 	case 'I':
 		if (fmt[1] == '6')
-			return ip6_addr_string(buf, end, ptr, field_width, precision, flags);
+			return ip6_addr_string(buf, end, ptr, spec);
 		if (fmt[1] == '4')
-			return ip4_addr_string(buf, end, ptr, field_width, precision, flags);
-		flags &= ~SPECIAL;
+			return ip4_addr_string(buf, end, ptr, spec);
+		spec.flags &= ~SPECIAL;
 		break;
 	}
-	flags |= SMALL;
-	if (field_width == -1) {
-		field_width = 2*sizeof(void *);
-		flags |= ZEROPAD;
+	spec.flags |= SMALL;
+	if (spec.field_width == -1) {
+		spec.field_width = 2*sizeof(void *);
+		spec.flags |= ZEROPAD;
 	}
-	return number(buf, end, (unsigned long) ptr, 16, field_width, precision, flags);
+	spec.base = 16;
+
+	return number(buf, end, (unsigned long) ptr, spec);
+}
+
+/*
+ * Helper function to decode printf style format.
+ * Each call decode a token from the format and return the
+ * number of characters read (or likely the delta where it wants
+ * to go on the next call).
+ * The decoded token is returned through the parameters
+ *
+ * 'h', 'l', or 'L' for integer fields
+ * 'z' support added 23/7/1999 S.H.
+ * 'z' changed to 'Z' --davidm 1/25/99
+ * 't' added for ptrdiff_t
+ *
+ * @fmt: the format string
+ * @type of the token returned
+ * @flags: various flags such as +, -, # tokens..
+ * @field_width: overwritten width
+ * @base: base of the number (octal, hex, ...)
+ * @precision: precision of a number
+ * @qualifier: qualifier of a number (long, size_t, ...)
+ */
+static int format_decode(const char *fmt, struct printf_spec *spec)
+{
+	const char *start = fmt;
+
+	/* we finished early by reading the field width */
+	if (spec->type == FORMAT_TYPE_WIDTH) {
+		if (spec->field_width < 0) {
+			spec->field_width = -spec->field_width;
+			spec->flags |= LEFT;
+		}
+		spec->type = FORMAT_TYPE_NONE;
+		goto precision;
+	}
+
+	/* we finished early by reading the precision */
+	if (spec->type == FORMAT_TYPE_PRECISION) {
+		if (spec->precision < 0)
+			spec->precision = 0;
+
+		spec->type = FORMAT_TYPE_NONE;
+		goto qualifier;
+	}
+
+	/* By default */
+	spec->type = FORMAT_TYPE_NONE;
+
+	for (; *fmt ; ++fmt) {
+		if (*fmt == '%')
+			break;
+	}
+
+	/* Return the current non-format string */
+	if (fmt != start || !*fmt)
+		return fmt - start;
+
+	/* Process flags */
+	spec->flags = 0;
+
+	while (1) { /* this also skips first '%' */
+		bool found = true;
+
+		++fmt;
+
+		switch (*fmt) {
+		case '-': spec->flags |= LEFT;    break;
+		case '+': spec->flags |= PLUS;    break;
+		case ' ': spec->flags |= SPACE;   break;
+		case '#': spec->flags |= SPECIAL; break;
+		case '0': spec->flags |= ZEROPAD; break;
+		default:  found = false;
+		}
+
+		if (!found)
+			break;
+	}
+
+	/* get field width */
+	spec->field_width = -1;
+
+	if (isdigit(*fmt))
+		spec->field_width = skip_atoi(&fmt);
+	else if (*fmt == '*') {
+		/* it's the next argument */
+		spec->type = FORMAT_TYPE_WIDTH;
+		return ++fmt - start;
+	}
+
+precision:
+	/* get the precision */
+	spec->precision = -1;
+	if (*fmt == '.') {
+		++fmt;
+		if (isdigit(*fmt)) {
+			spec->precision = skip_atoi(&fmt);
+			if (spec->precision < 0)
+				spec->precision = 0;
+		} else if (*fmt == '*') {
+			/* it's the next argument */
+			spec->type = FORMAT_TYPE_PRECISION;
+			return ++fmt - start;
+		}
+	}
+
+qualifier:
+	/* get the conversion qualifier */
+	spec->qualifier = -1;
+	if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
+	    *fmt == 'Z' || *fmt == 'z' || *fmt == 't') {
+		spec->qualifier = *fmt;
+		++fmt;
+		if (spec->qualifier == 'l' && *fmt == 'l') {
+			spec->qualifier = 'L';
+			++fmt;
+		}
+	}
+
+	/* default base */
+	spec->base = 10;
+	switch (*fmt) {
+	case 'c':
+		spec->type = FORMAT_TYPE_CHAR;
+		return ++fmt - start;
+
+	case 's':
+		spec->type = FORMAT_TYPE_STR;
+		return ++fmt - start;
+
+	case 'p':
+		spec->type = FORMAT_TYPE_PTR;
+		return fmt - start;
+		/* skip alnum */
+
+	case 'n':
+		spec->type = FORMAT_TYPE_NRCHARS;
+		return ++fmt - start;
+
+	case '%':
+		spec->type = FORMAT_TYPE_PERCENT_CHAR;
+		return ++fmt - start;
+
+	/* integer number formats - set up the flags and "break" */
+	case 'o':
+		spec->base = 8;
+		break;
+
+	case 'x':
+		spec->flags |= SMALL;
+
+	case 'X':
+		spec->base = 16;
+		break;
+
+	case 'd':
+	case 'i':
+		spec->flags |= SIGN;
+	case 'u':
+		break;
+
+	default:
+		spec->type = FORMAT_TYPE_INVALID;
+		return fmt - start;
+	}
+
+	if (spec->qualifier == 'L')
+		spec->type = FORMAT_TYPE_LONG_LONG;
+	else if (spec->qualifier == 'l') {
+		if (spec->flags & SIGN)
+			spec->type = FORMAT_TYPE_LONG;
+		else
+			spec->type = FORMAT_TYPE_ULONG;
+	} else if (spec->qualifier == 'Z' || spec->qualifier == 'z') {
+		spec->type = FORMAT_TYPE_SIZE_T;
+	} else if (spec->qualifier == 't') {
+		spec->type = FORMAT_TYPE_PTRDIFF;
+	} else if (spec->qualifier == 'h') {
+		if (spec->flags & SIGN)
+			spec->type = FORMAT_TYPE_SHORT;
+		else
+			spec->type = FORMAT_TYPE_USHORT;
+	} else {
+		if (spec->flags & SIGN)
+			spec->type = FORMAT_TYPE_INT;
+		else
+			spec->type = FORMAT_TYPE_UINT;
+	}
+
+	return ++fmt - start;
 }
 
 /**
@@ -726,18 +960,9 @@
 int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
 {
 	unsigned long long num;
-	int base;
 	char *str, *end, c;
-
-	int flags;		/* flags to number() */
-
-	int field_width;	/* width of output field */
-	int precision;		/* min. # of digits for integers; max
-				   number of chars for from string */
-	int qualifier;		/* 'h', 'l', or 'L' for integer fields */
-				/* 'z' support added 23/7/1999 S.H.    */
-				/* 'z' changed to 'Z' --davidm 1/25/99 */
-				/* 't' added for ptrdiff_t */
+	int read;
+	struct printf_spec spec = {0};
 
 	/* Reject out-of-range values early.  Large positive sizes are
 	   used for unknown buffer sizes. */
@@ -758,184 +983,144 @@
 		size = end - buf;
 	}
 
-	for (; *fmt ; ++fmt) {
-		if (*fmt != '%') {
-			if (str < end)
-				*str = *fmt;
-			++str;
-			continue;
+	while (*fmt) {
+		const char *old_fmt = fmt;
+
+		read = format_decode(fmt, &spec);
+
+		fmt += read;
+
+		switch (spec.type) {
+		case FORMAT_TYPE_NONE: {
+			int copy = read;
+			if (str < end) {
+				if (copy > end - str)
+					copy = end - str;
+				memcpy(str, old_fmt, copy);
+			}
+			str += read;
+			break;
 		}
 
-		/* process flags */
-		flags = 0;
-		repeat:
-			++fmt;		/* this also skips first '%' */
-			switch (*fmt) {
-				case '-': flags |= LEFT; goto repeat;
-				case '+': flags |= PLUS; goto repeat;
-				case ' ': flags |= SPACE; goto repeat;
-				case '#': flags |= SPECIAL; goto repeat;
-				case '0': flags |= ZEROPAD; goto repeat;
-			}
+		case FORMAT_TYPE_WIDTH:
+			spec.field_width = va_arg(args, int);
+			break;
 
-		/* get field width */
-		field_width = -1;
-		if (isdigit(*fmt))
-			field_width = skip_atoi(&fmt);
-		else if (*fmt == '*') {
-			++fmt;
-			/* it's the next argument */
-			field_width = va_arg(args, int);
-			if (field_width < 0) {
-				field_width = -field_width;
-				flags |= LEFT;
-			}
-		}
+		case FORMAT_TYPE_PRECISION:
+			spec.precision = va_arg(args, int);
+			break;
 
-		/* get the precision */
-		precision = -1;
-		if (*fmt == '.') {
-			++fmt;	
-			if (isdigit(*fmt))
-				precision = skip_atoi(&fmt);
-			else if (*fmt == '*') {
-				++fmt;
-				/* it's the next argument */
-				precision = va_arg(args, int);
-			}
-			if (precision < 0)
-				precision = 0;
-		}
-
-		/* get the conversion qualifier */
-		qualifier = -1;
-		if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
-		    *fmt =='Z' || *fmt == 'z' || *fmt == 't') {
-			qualifier = *fmt;
-			++fmt;
-			if (qualifier == 'l' && *fmt == 'l') {
-				qualifier = 'L';
-				++fmt;
-			}
-		}
-
-		/* default base */
-		base = 10;
-
-		switch (*fmt) {
-			case 'c':
-				if (!(flags & LEFT)) {
-					while (--field_width > 0) {
-						if (str < end)
-							*str = ' ';
-						++str;
-					}
-				}
-				c = (unsigned char) va_arg(args, int);
-				if (str < end)
-					*str = c;
-				++str;
-				while (--field_width > 0) {
+		case FORMAT_TYPE_CHAR:
+			if (!(spec.flags & LEFT)) {
+				while (--spec.field_width > 0) {
 					if (str < end)
 						*str = ' ';
 					++str;
+
 				}
-				continue;
-
-			case 's':
-				str = string(str, end, va_arg(args, char *), field_width, precision, flags);
-				continue;
-
-			case 'p':
-				str = pointer(fmt+1, str, end,
-						va_arg(args, void *),
-						field_width, precision, flags);
-				/* Skip all alphanumeric pointer suffixes */
-				while (isalnum(fmt[1]))
-					fmt++;
-				continue;
-
-			case 'n':
-				/* FIXME:
-				* What does C99 say about the overflow case here? */
-				if (qualifier == 'l') {
-					long * ip = va_arg(args, long *);
-					*ip = (str - buf);
-				} else if (qualifier == 'Z' || qualifier == 'z') {
-					size_t * ip = va_arg(args, size_t *);
-					*ip = (str - buf);
-				} else {
-					int * ip = va_arg(args, int *);
-					*ip = (str - buf);
-				}
-				continue;
-
-			case '%':
+			}
+			c = (unsigned char) va_arg(args, int);
+			if (str < end)
+				*str = c;
+			++str;
+			while (--spec.field_width > 0) {
 				if (str < end)
-					*str = '%';
+					*str = ' ';
 				++str;
-				continue;
+			}
+			break;
 
-				/* integer number formats - set up the flags and "break" */
-			case 'o':
-				base = 8;
+		case FORMAT_TYPE_STR:
+			str = string(str, end, va_arg(args, char *), spec);
+			break;
+
+		case FORMAT_TYPE_PTR:
+			str = pointer(fmt+1, str, end, va_arg(args, void *),
+				      spec);
+			while (isalnum(*fmt))
+				fmt++;
+			break;
+
+		case FORMAT_TYPE_PERCENT_CHAR:
+			if (str < end)
+				*str = '%';
+			++str;
+			break;
+
+		case FORMAT_TYPE_INVALID:
+			if (str < end)
+				*str = '%';
+			++str;
+			if (*fmt) {
+				if (str < end)
+					*str = *fmt;
+				++str;
+			} else {
+				--fmt;
+			}
+			break;
+
+		case FORMAT_TYPE_NRCHARS: {
+			int qualifier = spec.qualifier;
+
+			if (qualifier == 'l') {
+				long *ip = va_arg(args, long *);
+				*ip = (str - buf);
+			} else if (qualifier == 'Z' ||
+					qualifier == 'z') {
+				size_t *ip = va_arg(args, size_t *);
+				*ip = (str - buf);
+			} else {
+				int *ip = va_arg(args, int *);
+				*ip = (str - buf);
+			}
+			break;
+		}
+
+		default:
+			switch (spec.type) {
+			case FORMAT_TYPE_LONG_LONG:
+				num = va_arg(args, long long);
 				break;
-
-			case 'x':
-				flags |= SMALL;
-			case 'X':
-				base = 16;
+			case FORMAT_TYPE_ULONG:
+				num = va_arg(args, unsigned long);
 				break;
-
-			case 'd':
-			case 'i':
-				flags |= SIGN;
-			case 'u':
+			case FORMAT_TYPE_LONG:
+				num = va_arg(args, long);
 				break;
-
+			case FORMAT_TYPE_SIZE_T:
+				num = va_arg(args, size_t);
+				break;
+			case FORMAT_TYPE_PTRDIFF:
+				num = va_arg(args, ptrdiff_t);
+				break;
+			case FORMAT_TYPE_USHORT:
+				num = (unsigned short) va_arg(args, int);
+				break;
+			case FORMAT_TYPE_SHORT:
+				num = (short) va_arg(args, int);
+				break;
+			case FORMAT_TYPE_INT:
+				num = (int) va_arg(args, int);
+				break;
 			default:
-				if (str < end)
-					*str = '%';
-				++str;
-				if (*fmt) {
-					if (str < end)
-						*str = *fmt;
-					++str;
-				} else {
-					--fmt;
-				}
-				continue;
+				num = va_arg(args, unsigned int);
+			}
+
+			str = number(str, end, num, spec);
 		}
-		if (qualifier == 'L')
-			num = va_arg(args, long long);
-		else if (qualifier == 'l') {
-			num = va_arg(args, unsigned long);
-			if (flags & SIGN)
-				num = (signed long) num;
-		} else if (qualifier == 'Z' || qualifier == 'z') {
-			num = va_arg(args, size_t);
-		} else if (qualifier == 't') {
-			num = va_arg(args, ptrdiff_t);
-		} else if (qualifier == 'h') {
-			num = (unsigned short) va_arg(args, int);
-			if (flags & SIGN)
-				num = (signed short) num;
-		} else {
-			num = va_arg(args, unsigned int);
-			if (flags & SIGN)
-				num = (signed int) num;
-		}
-		str = number(str, end, num, base,
-				field_width, precision, flags);
 	}
+
 	if (size > 0) {
 		if (str < end)
 			*str = '\0';
 		else
 			end[-1] = '\0';
 	}
+
 	/* the trailing null byte doesn't count towards the total */
 	return str-buf;
+
 }
 EXPORT_SYMBOL(vsnprintf);
 
@@ -1058,6 +1243,372 @@
 }
 EXPORT_SYMBOL(sprintf);
 
+#ifdef CONFIG_BINARY_PRINTF
+/*
+ * bprintf service:
+ * vbin_printf() - VA arguments to binary data
+ * bstr_printf() - Binary data to text string
+ */
+
+/**
+ * vbin_printf - Parse a format string and place args' binary value in a buffer
+ * @bin_buf: The buffer to place args' binary value
+ * @size: The size of the buffer(by words(32bits), not characters)
+ * @fmt: The format string to use
+ * @args: Arguments for the format string
+ *
+ * The format follows C99 vsnprintf, except %n is ignored, and its argument
+ * is skiped.
+ *
+ * The return value is the number of words(32bits) which would be generated for
+ * the given input.
+ *
+ * NOTE:
+ * If the return value is greater than @size, the resulting bin_buf is NOT
+ * valid for bstr_printf().
+ */
+int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args)
+{
+	struct printf_spec spec = {0};
+	char *str, *end;
+	int read;
+
+	str = (char *)bin_buf;
+	end = (char *)(bin_buf + size);
+
+#define save_arg(type)							\
+do {									\
+	if (sizeof(type) == 8) {					\
+		unsigned long long value;				\
+		str = PTR_ALIGN(str, sizeof(u32));			\
+		value = va_arg(args, unsigned long long);		\
+		if (str + sizeof(type) <= end) {			\
+			*(u32 *)str = *(u32 *)&value;			\
+			*(u32 *)(str + 4) = *((u32 *)&value + 1);	\
+		}							\
+	} else {							\
+		unsigned long value;					\
+		str = PTR_ALIGN(str, sizeof(type));			\
+		value = va_arg(args, int);				\
+		if (str + sizeof(type) <= end)				\
+			*(typeof(type) *)str = (type)value;		\
+	}								\
+	str += sizeof(type);						\
+} while (0)
+
+
+	while (*fmt) {
+		read = format_decode(fmt, &spec);
+
+		fmt += read;
+
+		switch (spec.type) {
+		case FORMAT_TYPE_NONE:
+			break;
+
+		case FORMAT_TYPE_WIDTH:
+		case FORMAT_TYPE_PRECISION:
+			save_arg(int);
+			break;
+
+		case FORMAT_TYPE_CHAR:
+			save_arg(char);
+			break;
+
+		case FORMAT_TYPE_STR: {
+			const char *save_str = va_arg(args, char *);
+			size_t len;
+			if ((unsigned long)save_str > (unsigned long)-PAGE_SIZE
+					|| (unsigned long)save_str < PAGE_SIZE)
+				save_str = "<NULL>";
+			len = strlen(save_str);
+			if (str + len + 1 < end)
+				memcpy(str, save_str, len + 1);
+			str += len + 1;
+			break;
+		}
+
+		case FORMAT_TYPE_PTR:
+			save_arg(void *);
+			/* skip all alphanumeric pointer suffixes */
+			while (isalnum(*fmt))
+				fmt++;
+			break;
+
+		case FORMAT_TYPE_PERCENT_CHAR:
+			break;
+
+		case FORMAT_TYPE_INVALID:
+			if (!*fmt)
+				--fmt;
+			break;
+
+		case FORMAT_TYPE_NRCHARS: {
+			/* skip %n 's argument */
+			int qualifier = spec.qualifier;
+			void *skip_arg;
+			if (qualifier == 'l')
+				skip_arg = va_arg(args, long *);
+			else if (qualifier == 'Z' || qualifier == 'z')
+				skip_arg = va_arg(args, size_t *);
+			else
+				skip_arg = va_arg(args, int *);
+			break;
+		}
+
+		default:
+			switch (spec.type) {
+
+			case FORMAT_TYPE_LONG_LONG:
+				save_arg(long long);
+				break;
+			case FORMAT_TYPE_ULONG:
+			case FORMAT_TYPE_LONG:
+				save_arg(unsigned long);
+				break;
+			case FORMAT_TYPE_SIZE_T:
+				save_arg(size_t);
+				break;
+			case FORMAT_TYPE_PTRDIFF:
+				save_arg(ptrdiff_t);
+				break;
+			case FORMAT_TYPE_USHORT:
+			case FORMAT_TYPE_SHORT:
+				save_arg(short);
+				break;
+			default:
+				save_arg(int);
+			}
+		}
+	}
+	return (u32 *)(PTR_ALIGN(str, sizeof(u32))) - bin_buf;
+
+#undef save_arg
+}
+EXPORT_SYMBOL_GPL(vbin_printf);
+
+/**
+ * bstr_printf - Format a string from binary arguments and place it in a buffer
+ * @buf: The buffer to place the result into
+ * @size: The size of the buffer, including the trailing null space
+ * @fmt: The format string to use
+ * @bin_buf: Binary arguments for the format string
+ *
+ * This function like C99 vsnprintf, but the difference is that vsnprintf gets
+ * arguments from stack, and bstr_printf gets arguments from @bin_buf which is
+ * a binary buffer that generated by vbin_printf.
+ *
+ * The format follows C99 vsnprintf, but has some extensions:
+ * %pS output the name of a text symbol
+ * %pF output the name of a function pointer
+ * %pR output the address range in a struct resource
+ * %n is ignored
+ *
+ * The return value is the number of characters which would
+ * be generated for the given input, excluding the trailing
+ * '\0', as per ISO C99. If you want to have the exact
+ * number of characters written into @buf as return value
+ * (not including the trailing '\0'), use vscnprintf(). If the
+ * return is greater than or equal to @size, the resulting
+ * string is truncated.
+ */
+int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
+{
+	unsigned long long num;
+	char *str, *end, c;
+	const char *args = (const char *)bin_buf;
+
+	struct printf_spec spec = {0};
+
+	if (unlikely((int) size < 0)) {
+		/* There can be only one.. */
+		static char warn = 1;
+		WARN_ON(warn);
+		warn = 0;
+		return 0;
+	}
+
+	str = buf;
+	end = buf + size;
+
+#define get_arg(type)							\
+({									\
+	typeof(type) value;						\
+	if (sizeof(type) == 8) {					\
+		args = PTR_ALIGN(args, sizeof(u32));			\
+		*(u32 *)&value = *(u32 *)args;				\
+		*((u32 *)&value + 1) = *(u32 *)(args + 4);		\
+	} else {							\
+		args = PTR_ALIGN(args, sizeof(type));			\
+		value = *(typeof(type) *)args;				\
+	}								\
+	args += sizeof(type);						\
+	value;								\
+})
+
+	/* Make sure end is always >= buf */
+	if (end < buf) {
+		end = ((void *)-1);
+		size = end - buf;
+	}
+
+	while (*fmt) {
+		int read;
+		const char *old_fmt = fmt;
+
+		read = format_decode(fmt, &spec);
+
+		fmt += read;
+
+		switch (spec.type) {
+		case FORMAT_TYPE_NONE: {
+			int copy = read;
+			if (str < end) {
+				if (copy > end - str)
+					copy = end - str;
+				memcpy(str, old_fmt, copy);
+			}
+			str += read;
+			break;
+		}
+
+		case FORMAT_TYPE_WIDTH:
+			spec.field_width = get_arg(int);
+			break;
+
+		case FORMAT_TYPE_PRECISION:
+			spec.precision = get_arg(int);
+			break;
+
+		case FORMAT_TYPE_CHAR:
+			if (!(spec.flags & LEFT)) {
+				while (--spec.field_width > 0) {
+					if (str < end)
+						*str = ' ';
+					++str;
+				}
+			}
+			c = (unsigned char) get_arg(char);
+			if (str < end)
+				*str = c;
+			++str;
+			while (--spec.field_width > 0) {
+				if (str < end)
+					*str = ' ';
+				++str;
+			}
+			break;
+
+		case FORMAT_TYPE_STR: {
+			const char *str_arg = args;
+			size_t len = strlen(str_arg);
+			args += len + 1;
+			str = string(str, end, (char *)str_arg, spec);
+			break;
+		}
+
+		case FORMAT_TYPE_PTR:
+			str = pointer(fmt+1, str, end, get_arg(void *), spec);
+			while (isalnum(*fmt))
+				fmt++;
+			break;
+
+		case FORMAT_TYPE_PERCENT_CHAR:
+			if (str < end)
+				*str = '%';
+			++str;
+			break;
+
+		case FORMAT_TYPE_INVALID:
+			if (str < end)
+				*str = '%';
+			++str;
+			if (*fmt) {
+				if (str < end)
+					*str = *fmt;
+				++str;
+			} else {
+				--fmt;
+			}
+			break;
+
+		case FORMAT_TYPE_NRCHARS:
+			/* skip */
+			break;
+
+		default:
+			switch (spec.type) {
+
+			case FORMAT_TYPE_LONG_LONG:
+				num = get_arg(long long);
+				break;
+			case FORMAT_TYPE_ULONG:
+				num = get_arg(unsigned long);
+				break;
+			case FORMAT_TYPE_LONG:
+				num = get_arg(unsigned long);
+				break;
+			case FORMAT_TYPE_SIZE_T:
+				num = get_arg(size_t);
+				break;
+			case FORMAT_TYPE_PTRDIFF:
+				num = get_arg(ptrdiff_t);
+				break;
+			case FORMAT_TYPE_USHORT:
+				num = get_arg(unsigned short);
+				break;
+			case FORMAT_TYPE_SHORT:
+				num = get_arg(short);
+				break;
+			case FORMAT_TYPE_UINT:
+				num = get_arg(unsigned int);
+				break;
+			default:
+				num = get_arg(int);
+			}
+
+			str = number(str, end, num, spec);
+		}
+	}
+
+	if (size > 0) {
+		if (str < end)
+			*str = '\0';
+		else
+			end[-1] = '\0';
+	}
+
+#undef get_arg
+
+	/* the trailing null byte doesn't count towards the total */
+	return str - buf;
+}
+EXPORT_SYMBOL_GPL(bstr_printf);
+
+/**
+ * bprintf - Parse a format string and place args' binary value in a buffer
+ * @bin_buf: The buffer to place args' binary value
+ * @size: The size of the buffer(by words(32bits), not characters)
+ * @fmt: The format string to use
+ * @...: Arguments for the format string
+ *
+ * The function returns the number of words(u32) written
+ * into @bin_buf.
+ */
+int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...)
+{
+	va_list args;
+	int ret;
+
+	va_start(args, fmt);
+	ret = vbin_printf(bin_buf, size, fmt, args);
+	va_end(args);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(bprintf);
+
+#endif /* CONFIG_BINARY_PRINTF */
+
 /**
  * vsscanf - Unformat a buffer into a list of arguments
  * @buf:	input buffer
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index be68c95..493b468 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -284,12 +284,12 @@
 	};
 
 
-void clear_bdi_congested(struct backing_dev_info *bdi, int rw)
+void clear_bdi_congested(struct backing_dev_info *bdi, int sync)
 {
 	enum bdi_state bit;
-	wait_queue_head_t *wqh = &congestion_wqh[rw];
+	wait_queue_head_t *wqh = &congestion_wqh[sync];
 
-	bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested;
+	bit = sync ? BDI_sync_congested : BDI_async_congested;
 	clear_bit(bit, &bdi->state);
 	smp_mb__after_clear_bit();
 	if (waitqueue_active(wqh))
@@ -297,11 +297,11 @@
 }
 EXPORT_SYMBOL(clear_bdi_congested);
 
-void set_bdi_congested(struct backing_dev_info *bdi, int rw)
+void set_bdi_congested(struct backing_dev_info *bdi, int sync)
 {
 	enum bdi_state bit;
 
-	bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested;
+	bit = sync ? BDI_sync_congested : BDI_async_congested;
 	set_bit(bit, &bdi->state);
 }
 EXPORT_SYMBOL(set_bdi_congested);
diff --git a/mm/filemap.c b/mm/filemap.c
index 126d397..2e2d38e 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -513,6 +513,7 @@
 	}
 	return ret;
 }
+EXPORT_SYMBOL_GPL(add_to_page_cache_lru);
 
 #ifdef CONFIG_NUMA
 struct page *__page_cache_alloc(gfp_t gfp)
@@ -565,6 +566,24 @@
 EXPORT_SYMBOL(wait_on_page_bit);
 
 /**
+ * add_page_wait_queue - Add an arbitrary waiter to a page's wait queue
+ * @page - Page defining the wait queue of interest
+ * @waiter - Waiter to add to the queue
+ *
+ * Add an arbitrary @waiter to the wait queue for the nominated @page.
+ */
+void add_page_wait_queue(struct page *page, wait_queue_t *waiter)
+{
+	wait_queue_head_t *q = page_waitqueue(page);
+	unsigned long flags;
+
+	spin_lock_irqsave(&q->lock, flags);
+	__add_wait_queue(q, waiter);
+	spin_unlock_irqrestore(&q->lock, flags);
+}
+EXPORT_SYMBOL_GPL(add_page_wait_queue);
+
+/**
  * unlock_page - unlock a locked page
  * @page: the page
  *
@@ -627,6 +646,7 @@
 	return __wait_on_bit_lock(page_waitqueue(page), &wait,
 					sync_page_killable, TASK_KILLABLE);
 }
+EXPORT_SYMBOL_GPL(__lock_page_killable);
 
 /**
  * __lock_page_nosync - get a lock on the page, without calling sync_page()
@@ -2463,6 +2483,9 @@
  * (presumably at page->private).  If the release was successful, return `1'.
  * Otherwise return zero.
  *
+ * This may also be called if PG_fscache is set on a page, indicating that the
+ * page is known to the local caching routines.
+ *
  * The @gfp_mask argument specifies whether I/O may be performed to release
  * this page (__GFP_IO), and whether the call may block (__GFP_WAIT & __GFP_FS).
  *
diff --git a/mm/migrate.c b/mm/migrate.c
index a9eff3f..068655d8 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -250,7 +250,7 @@
  * The number of remaining references must be:
  * 1 for anonymous pages without a mapping
  * 2 for pages with a mapping
- * 3 for pages with a mapping and PagePrivate set.
+ * 3 for pages with a mapping and PagePrivate/PagePrivate2 set.
  */
 static int migrate_page_move_mapping(struct address_space *mapping,
 		struct page *newpage, struct page *page)
@@ -270,7 +270,7 @@
 	pslot = radix_tree_lookup_slot(&mapping->page_tree,
  					page_index(page));
 
-	expected_count = 2 + !!PagePrivate(page);
+	expected_count = 2 + !!page_has_private(page);
 	if (page_count(page) != expected_count ||
 			(struct page *)radix_tree_deref_slot(pslot) != page) {
 		spin_unlock_irq(&mapping->tree_lock);
@@ -386,7 +386,7 @@
 
 /*
  * Common logic to directly migrate a single page suitable for
- * pages that do not use PagePrivate.
+ * pages that do not use PagePrivate/PagePrivate2.
  *
  * Pages are locked upon entry and exit.
  */
@@ -522,7 +522,7 @@
 	 * Buffers may be managed in a filesystem specific way.
 	 * We must have no buffers or drop them.
 	 */
-	if (PagePrivate(page) &&
+	if (page_has_private(page) &&
 	    !try_to_release_page(page, GFP_KERNEL))
 		return -EAGAIN;
 
@@ -655,7 +655,7 @@
 	 * free the metadata, so the page can be freed.
 	 */
 	if (!page->mapping) {
-		if (!PageAnon(page) && PagePrivate(page)) {
+		if (!PageAnon(page) && page_has_private(page)) {
 			/*
 			 * Go direct to try_to_free_buffers() here because
 			 * a) that's what try_to_release_page() would do anyway
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 0284e52..e2f2699 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -331,7 +331,7 @@
 	for (i = 1; i < nr_pages; i++) {
 		struct page *p = page + i;
 
-		if (unlikely(!PageTail(p) | (p->first_page != page))) {
+		if (unlikely(!PageTail(p) || (p->first_page != page))) {
 			bad_page(page);
 			bad++;
 		}
@@ -2128,7 +2128,7 @@
 	int n, val;
 	int min_val = INT_MAX;
 	int best_node = -1;
-	node_to_cpumask_ptr(tmp, 0);
+	const struct cpumask *tmp = cpumask_of_node(0);
 
 	/* Use the local node if we haven't already */
 	if (!node_isset(node, *used_node_mask)) {
@@ -2149,8 +2149,8 @@
 		val += (n < node);
 
 		/* Give preference to headless and unused nodes */
-		node_to_cpumask_ptr_next(tmp, n);
-		if (!cpus_empty(*tmp))
+		tmp = cpumask_of_node(n);
+		if (!cpumask_empty(tmp))
 			val += PENALTY_FOR_NODE_WITH_CPUS;
 
 		/* Slight preference for less loaded node */
diff --git a/mm/quicklist.c b/mm/quicklist.c
index 8dbb680..e66d07d1 100644
--- a/mm/quicklist.c
+++ b/mm/quicklist.c
@@ -29,7 +29,7 @@
 	int node = numa_node_id();
 	struct zone *zones = NODE_DATA(node)->node_zones;
 	int num_cpus_on_node;
-	node_to_cpumask_ptr(cpumask_on_node, node);
+	const struct cpumask *cpumask_on_node = cpumask_of_node(node);
 
 	node_free_pages =
 #ifdef CONFIG_ZONE_DMA
diff --git a/mm/readahead.c b/mm/readahead.c
index 9ce303d..133b6d5 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -31,6 +31,42 @@
 
 #define list_to_page(head) (list_entry((head)->prev, struct page, lru))
 
+/*
+ * see if a page needs releasing upon read_cache_pages() failure
+ * - the caller of read_cache_pages() may have set PG_private or PG_fscache
+ *   before calling, such as the NFS fs marking pages that are cached locally
+ *   on disk, thus we need to give the fs a chance to clean up in the event of
+ *   an error
+ */
+static void read_cache_pages_invalidate_page(struct address_space *mapping,
+					     struct page *page)
+{
+	if (page_has_private(page)) {
+		if (!trylock_page(page))
+			BUG();
+		page->mapping = mapping;
+		do_invalidatepage(page, 0);
+		page->mapping = NULL;
+		unlock_page(page);
+	}
+	page_cache_release(page);
+}
+
+/*
+ * release a list of pages, invalidating them first if need be
+ */
+static void read_cache_pages_invalidate_pages(struct address_space *mapping,
+					      struct list_head *pages)
+{
+	struct page *victim;
+
+	while (!list_empty(pages)) {
+		victim = list_to_page(pages);
+		list_del(&victim->lru);
+		read_cache_pages_invalidate_page(mapping, victim);
+	}
+}
+
 /**
  * read_cache_pages - populate an address space with some pages & start reads against them
  * @mapping: the address_space
@@ -52,14 +88,14 @@
 		list_del(&page->lru);
 		if (add_to_page_cache_lru(page, mapping,
 					page->index, GFP_KERNEL)) {
-			page_cache_release(page);
+			read_cache_pages_invalidate_page(mapping, page);
 			continue;
 		}
 		page_cache_release(page);
 
 		ret = filler(data, page);
 		if (unlikely(ret)) {
-			put_pages_list(pages);
+			read_cache_pages_invalidate_pages(mapping, pages);
 			break;
 		}
 		task_io_account_read(PAGE_CACHE_SIZE);
diff --git a/mm/slab.c b/mm/slab.c
index 208323f..4fc1761 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -102,6 +102,7 @@
 #include	<linux/cpu.h>
 #include	<linux/sysctl.h>
 #include	<linux/module.h>
+#include	<trace/kmemtrace.h>
 #include	<linux/rcupdate.h>
 #include	<linux/string.h>
 #include	<linux/uaccess.h>
@@ -568,6 +569,14 @@
 
 #endif
 
+#ifdef CONFIG_KMEMTRACE
+size_t slab_buffer_size(struct kmem_cache *cachep)
+{
+	return cachep->buffer_size;
+}
+EXPORT_SYMBOL(slab_buffer_size);
+#endif
+
 /*
  * Do not go above this order unless 0 objects fit into the slab.
  */
@@ -1160,7 +1169,7 @@
 	struct kmem_cache *cachep;
 	struct kmem_list3 *l3 = NULL;
 	int node = cpu_to_node(cpu);
-	node_to_cpumask_ptr(mask, node);
+	const struct cpumask *mask = cpumask_of_node(node);
 
 	list_for_each_entry(cachep, &cache_chain, next) {
 		struct array_cache *nc;
@@ -3554,10 +3563,23 @@
  */
 void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags)
 {
-	return __cache_alloc(cachep, flags, __builtin_return_address(0));
+	void *ret = __cache_alloc(cachep, flags, __builtin_return_address(0));
+
+	kmemtrace_mark_alloc(KMEMTRACE_TYPE_CACHE, _RET_IP_, ret,
+			     obj_size(cachep), cachep->buffer_size, flags);
+
+	return ret;
 }
 EXPORT_SYMBOL(kmem_cache_alloc);
 
+#ifdef CONFIG_KMEMTRACE
+void *kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags)
+{
+	return __cache_alloc(cachep, flags, __builtin_return_address(0));
+}
+EXPORT_SYMBOL(kmem_cache_alloc_notrace);
+#endif
+
 /**
  * kmem_ptr_validate - check if an untrusted pointer might be a slab entry.
  * @cachep: the cache we're checking against
@@ -3602,23 +3624,47 @@
 #ifdef CONFIG_NUMA
 void *kmem_cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid)
 {
-	return __cache_alloc_node(cachep, flags, nodeid,
-			__builtin_return_address(0));
+	void *ret = __cache_alloc_node(cachep, flags, nodeid,
+				       __builtin_return_address(0));
+
+	kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_CACHE, _RET_IP_, ret,
+				  obj_size(cachep), cachep->buffer_size,
+				  flags, nodeid);
+
+	return ret;
 }
 EXPORT_SYMBOL(kmem_cache_alloc_node);
 
+#ifdef CONFIG_KMEMTRACE
+void *kmem_cache_alloc_node_notrace(struct kmem_cache *cachep,
+				    gfp_t flags,
+				    int nodeid)
+{
+	return __cache_alloc_node(cachep, flags, nodeid,
+				  __builtin_return_address(0));
+}
+EXPORT_SYMBOL(kmem_cache_alloc_node_notrace);
+#endif
+
 static __always_inline void *
 __do_kmalloc_node(size_t size, gfp_t flags, int node, void *caller)
 {
 	struct kmem_cache *cachep;
+	void *ret;
 
 	cachep = kmem_find_general_cachep(size, flags);
 	if (unlikely(ZERO_OR_NULL_PTR(cachep)))
 		return cachep;
-	return kmem_cache_alloc_node(cachep, flags, node);
+	ret = kmem_cache_alloc_node_notrace(cachep, flags, node);
+
+	kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_KMALLOC,
+				  (unsigned long) caller, ret,
+				  size, cachep->buffer_size, flags, node);
+
+	return ret;
 }
 
-#ifdef CONFIG_DEBUG_SLAB
+#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_KMEMTRACE)
 void *__kmalloc_node(size_t size, gfp_t flags, int node)
 {
 	return __do_kmalloc_node(size, flags, node,
@@ -3651,6 +3697,7 @@
 					  void *caller)
 {
 	struct kmem_cache *cachep;
+	void *ret;
 
 	/* If you want to save a few bytes .text space: replace
 	 * __ with kmem_.
@@ -3660,11 +3707,17 @@
 	cachep = __find_general_cachep(size, flags);
 	if (unlikely(ZERO_OR_NULL_PTR(cachep)))
 		return cachep;
-	return __cache_alloc(cachep, flags, caller);
+	ret = __cache_alloc(cachep, flags, caller);
+
+	kmemtrace_mark_alloc(KMEMTRACE_TYPE_KMALLOC,
+			     (unsigned long) caller, ret,
+			     size, cachep->buffer_size, flags);
+
+	return ret;
 }
 
 
-#ifdef CONFIG_DEBUG_SLAB
+#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_KMEMTRACE)
 void *__kmalloc(size_t size, gfp_t flags)
 {
 	return __do_kmalloc(size, flags, __builtin_return_address(0));
@@ -3703,6 +3756,8 @@
 		debug_check_no_obj_freed(objp, obj_size(cachep));
 	__cache_free(cachep, objp);
 	local_irq_restore(flags);
+
+	kmemtrace_mark_free(KMEMTRACE_TYPE_CACHE, _RET_IP_, objp);
 }
 EXPORT_SYMBOL(kmem_cache_free);
 
@@ -3729,6 +3784,8 @@
 	debug_check_no_obj_freed(objp, obj_size(c));
 	__cache_free(c, (void *)objp);
 	local_irq_restore(flags);
+
+	kmemtrace_mark_free(KMEMTRACE_TYPE_KMALLOC, _RET_IP_, objp);
 }
 EXPORT_SYMBOL(kfree);
 
diff --git a/mm/slob.c b/mm/slob.c
index 7a34115..4dd6516 100644
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -65,6 +65,7 @@
 #include <linux/module.h>
 #include <linux/rcupdate.h>
 #include <linux/list.h>
+#include <trace/kmemtrace.h>
 #include <asm/atomic.h>
 
 /*
@@ -474,6 +475,7 @@
 {
 	unsigned int *m;
 	int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
+	void *ret;
 
 	lockdep_trace_alloc(gfp);
 
@@ -482,12 +484,17 @@
 			return ZERO_SIZE_PTR;
 
 		m = slob_alloc(size + align, gfp, align, node);
+
 		if (!m)
 			return NULL;
 		*m = size;
-		return (void *)m + align;
+		ret = (void *)m + align;
+
+		kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_KMALLOC,
+					  _RET_IP_, ret,
+					  size, size + align, gfp, node);
 	} else {
-		void *ret;
+		unsigned int order = get_order(size);
 
 		ret = slob_new_pages(gfp | __GFP_COMP, get_order(size), node);
 		if (ret) {
@@ -495,8 +502,13 @@
 			page = virt_to_page(ret);
 			page->private = size;
 		}
-		return ret;
+
+		kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_KMALLOC,
+					  _RET_IP_, ret,
+					  size, PAGE_SIZE << order, gfp, node);
 	}
+
+	return ret;
 }
 EXPORT_SYMBOL(__kmalloc_node);
 
@@ -514,6 +526,8 @@
 		slob_free(m, *m + align);
 	} else
 		put_page(&sp->page);
+
+	kmemtrace_mark_free(KMEMTRACE_TYPE_KMALLOC, _RET_IP_, block);
 }
 EXPORT_SYMBOL(kfree);
 
@@ -583,10 +597,19 @@
 {
 	void *b;
 
-	if (c->size < PAGE_SIZE)
+	if (c->size < PAGE_SIZE) {
 		b = slob_alloc(c->size, flags, c->align, node);
-	else
+		kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_CACHE,
+					  _RET_IP_, b, c->size,
+					  SLOB_UNITS(c->size) * SLOB_UNIT,
+					  flags, node);
+	} else {
 		b = slob_new_pages(flags, get_order(c->size), node);
+		kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_CACHE,
+					  _RET_IP_, b, c->size,
+					  PAGE_SIZE << get_order(c->size),
+					  flags, node);
+	}
 
 	if (c->ctor)
 		c->ctor(b);
@@ -622,6 +645,8 @@
 	} else {
 		__kmem_cache_free(b, c->size);
 	}
+
+	kmemtrace_mark_free(KMEMTRACE_TYPE_CACHE, _RET_IP_, b);
 }
 EXPORT_SYMBOL(kmem_cache_free);
 
diff --git a/mm/slub.c b/mm/slub.c
index c4ea915..7aaa121 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -16,6 +16,7 @@
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <trace/kmemtrace.h>
 #include <linux/cpu.h>
 #include <linux/cpuset.h>
 #include <linux/mempolicy.h>
@@ -1618,18 +1619,46 @@
 
 void *kmem_cache_alloc(struct kmem_cache *s, gfp_t gfpflags)
 {
-	return slab_alloc(s, gfpflags, -1, _RET_IP_);
+	void *ret = slab_alloc(s, gfpflags, -1, _RET_IP_);
+
+	kmemtrace_mark_alloc(KMEMTRACE_TYPE_CACHE, _RET_IP_, ret,
+			     s->objsize, s->size, gfpflags);
+
+	return ret;
 }
 EXPORT_SYMBOL(kmem_cache_alloc);
 
+#ifdef CONFIG_KMEMTRACE
+void *kmem_cache_alloc_notrace(struct kmem_cache *s, gfp_t gfpflags)
+{
+	return slab_alloc(s, gfpflags, -1, _RET_IP_);
+}
+EXPORT_SYMBOL(kmem_cache_alloc_notrace);
+#endif
+
 #ifdef CONFIG_NUMA
 void *kmem_cache_alloc_node(struct kmem_cache *s, gfp_t gfpflags, int node)
 {
-	return slab_alloc(s, gfpflags, node, _RET_IP_);
+	void *ret = slab_alloc(s, gfpflags, node, _RET_IP_);
+
+	kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_CACHE, _RET_IP_, ret,
+				  s->objsize, s->size, gfpflags, node);
+
+	return ret;
 }
 EXPORT_SYMBOL(kmem_cache_alloc_node);
 #endif
 
+#ifdef CONFIG_KMEMTRACE
+void *kmem_cache_alloc_node_notrace(struct kmem_cache *s,
+				    gfp_t gfpflags,
+				    int node)
+{
+	return slab_alloc(s, gfpflags, node, _RET_IP_);
+}
+EXPORT_SYMBOL(kmem_cache_alloc_node_notrace);
+#endif
+
 /*
  * Slow patch handling. This may still be called frequently since objects
  * have a longer lifetime than the cpu slabs in most processing loads.
@@ -1737,6 +1766,8 @@
 	page = virt_to_head_page(x);
 
 	slab_free(s, page, x, _RET_IP_);
+
+	kmemtrace_mark_free(KMEMTRACE_TYPE_CACHE, _RET_IP_, x);
 }
 EXPORT_SYMBOL(kmem_cache_free);
 
@@ -2659,6 +2690,7 @@
 void *__kmalloc(size_t size, gfp_t flags)
 {
 	struct kmem_cache *s;
+	void *ret;
 
 	if (unlikely(size > SLUB_MAX_SIZE))
 		return kmalloc_large(size, flags);
@@ -2668,7 +2700,12 @@
 	if (unlikely(ZERO_OR_NULL_PTR(s)))
 		return s;
 
-	return slab_alloc(s, flags, -1, _RET_IP_);
+	ret = slab_alloc(s, flags, -1, _RET_IP_);
+
+	kmemtrace_mark_alloc(KMEMTRACE_TYPE_KMALLOC, _RET_IP_, ret,
+			     size, s->size, flags);
+
+	return ret;
 }
 EXPORT_SYMBOL(__kmalloc);
 
@@ -2687,16 +2724,30 @@
 void *__kmalloc_node(size_t size, gfp_t flags, int node)
 {
 	struct kmem_cache *s;
+	void *ret;
 
-	if (unlikely(size > SLUB_MAX_SIZE))
-		return kmalloc_large_node(size, flags, node);
+	if (unlikely(size > SLUB_MAX_SIZE)) {
+		ret = kmalloc_large_node(size, flags, node);
+
+		kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_KMALLOC,
+					  _RET_IP_, ret,
+					  size, PAGE_SIZE << get_order(size),
+					  flags, node);
+
+		return ret;
+	}
 
 	s = get_slab(size, flags);
 
 	if (unlikely(ZERO_OR_NULL_PTR(s)))
 		return s;
 
-	return slab_alloc(s, flags, node, _RET_IP_);
+	ret = slab_alloc(s, flags, node, _RET_IP_);
+
+	kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_KMALLOC, _RET_IP_, ret,
+				  size, s->size, flags, node);
+
+	return ret;
 }
 EXPORT_SYMBOL(__kmalloc_node);
 #endif
@@ -2755,6 +2806,8 @@
 		return;
 	}
 	slab_free(page->slab, page, object, _RET_IP_);
+
+	kmemtrace_mark_free(KMEMTRACE_TYPE_KMALLOC, _RET_IP_, x);
 }
 EXPORT_SYMBOL(kfree);
 
@@ -3224,6 +3277,7 @@
 void *__kmalloc_track_caller(size_t size, gfp_t gfpflags, unsigned long caller)
 {
 	struct kmem_cache *s;
+	void *ret;
 
 	if (unlikely(size > SLUB_MAX_SIZE))
 		return kmalloc_large(size, gfpflags);
@@ -3233,13 +3287,20 @@
 	if (unlikely(ZERO_OR_NULL_PTR(s)))
 		return s;
 
-	return slab_alloc(s, gfpflags, -1, caller);
+	ret = slab_alloc(s, gfpflags, -1, caller);
+
+	/* Honor the call site pointer we recieved. */
+	kmemtrace_mark_alloc(KMEMTRACE_TYPE_KMALLOC, caller, ret, size,
+			     s->size, gfpflags);
+
+	return ret;
 }
 
 void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags,
 					int node, unsigned long caller)
 {
 	struct kmem_cache *s;
+	void *ret;
 
 	if (unlikely(size > SLUB_MAX_SIZE))
 		return kmalloc_large_node(size, gfpflags, node);
@@ -3249,7 +3310,13 @@
 	if (unlikely(ZERO_OR_NULL_PTR(s)))
 		return s;
 
-	return slab_alloc(s, gfpflags, node, caller);
+	ret = slab_alloc(s, gfpflags, node, caller);
+
+	/* Honor the call site pointer we recieved. */
+	kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_KMALLOC, caller, ret,
+				  size, s->size, gfpflags, node);
+
+	return ret;
 }
 
 #ifdef CONFIG_SLUB_DEBUG
diff --git a/mm/swap.c b/mm/swap.c
index 6e83084..bede23c 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -448,8 +448,8 @@
 	for (i = 0; i < pagevec_count(pvec); i++) {
 		struct page *page = pvec->pages[i];
 
-		if (PagePrivate(page) && trylock_page(page)) {
-			if (PagePrivate(page))
+		if (page_has_private(page) && trylock_page(page)) {
+			if (page_has_private(page))
 				try_to_release_page(page, 0);
 			unlock_page(page);
 		}
diff --git a/mm/truncate.c b/mm/truncate.c
index 1229211..55206fa 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -50,7 +50,7 @@
 static inline void truncate_partial_page(struct page *page, unsigned partial)
 {
 	zero_user_segment(page, partial, PAGE_CACHE_SIZE);
-	if (PagePrivate(page))
+	if (page_has_private(page))
 		do_invalidatepage(page, partial);
 }
 
@@ -99,7 +99,7 @@
 	if (page->mapping != mapping)
 		return;
 
-	if (PagePrivate(page))
+	if (page_has_private(page))
 		do_invalidatepage(page, 0);
 
 	cancel_dirty_page(page, PAGE_CACHE_SIZE);
@@ -126,7 +126,7 @@
 	if (page->mapping != mapping)
 		return 0;
 
-	if (PagePrivate(page) && !try_to_release_page(page, 0))
+	if (page_has_private(page) && !try_to_release_page(page, 0))
 		return 0;
 
 	clear_page_mlock(page);
@@ -348,7 +348,7 @@
 	if (page->mapping != mapping)
 		return 0;
 
-	if (PagePrivate(page) && !try_to_release_page(page, GFP_KERNEL))
+	if (page_has_private(page) && !try_to_release_page(page, GFP_KERNEL))
 		return 0;
 
 	spin_lock_irq(&mapping->tree_lock);
@@ -356,7 +356,7 @@
 		goto failed;
 
 	clear_page_mlock(page);
-	BUG_ON(PagePrivate(page));
+	BUG_ON(page_has_private(page));
 	__remove_from_page_cache(page);
 	spin_unlock_irq(&mapping->tree_lock);
 	page_cache_release(page);	/* pagecache ref */
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 06e7269..39fdfb1 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -283,7 +283,7 @@
 
 static inline int is_page_cache_freeable(struct page *page)
 {
-	return page_count(page) - !!PagePrivate(page) == 2;
+	return page_count(page) - !!page_has_private(page) == 2;
 }
 
 static int may_write_to_queue(struct backing_dev_info *bdi)
@@ -367,7 +367,7 @@
 		 * Some data journaling orphaned pages can have
 		 * page->mapping == NULL while being dirty with clean buffers.
 		 */
-		if (PagePrivate(page)) {
+		if (page_has_private(page)) {
 			if (try_to_free_buffers(page)) {
 				ClearPageDirty(page);
 				printk("%s: orphaned page\n", __func__);
@@ -727,7 +727,7 @@
 		 * process address space (page_count == 1) it can be freed.
 		 * Otherwise, leave the page on the LRU so it is swappable.
 		 */
-		if (PagePrivate(page)) {
+		if (page_has_private(page)) {
 			if (!try_to_release_page(page, sc->gfp_mask))
 				goto activate_locked;
 			if (!mapping && page_count(page) == 1) {
@@ -1967,7 +1967,7 @@
 	struct reclaim_state reclaim_state = {
 		.reclaimed_slab = 0,
 	};
-	node_to_cpumask_ptr(cpumask, pgdat->node_id);
+	const struct cpumask *cpumask = cpumask_of_node(pgdat->node_id);
 
 	lockdep_set_current_reclaim_state(GFP_KERNEL);
 
@@ -2204,7 +2204,9 @@
 	if (action == CPU_ONLINE || action == CPU_ONLINE_FROZEN) {
 		for_each_node_state(nid, N_HIGH_MEMORY) {
 			pg_data_t *pgdat = NODE_DATA(nid);
-			node_to_cpumask_ptr(mask, pgdat->node_id);
+			const struct cpumask *mask;
+
+			mask = cpumask_of_node(pgdat->node_id);
 
 			if (cpumask_any_and(cpu_online_mask, mask) < nr_cpu_ids)
 				/* One of our CPUs online: restore mask */
diff --git a/net/Kconfig b/net/Kconfig
index ec93e7e..ce77db4fc 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -140,7 +140,7 @@
 	default y
 	help
 	  If you say Y here you can select between all the netfilter modules.
-	  If you say N the more ununsual ones will not be shown and the
+	  If you say N the more unusual ones will not be shown and the
 	  basic ones needed by most people will default to 'M'.
 
 	  If unsure, say Y.
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index ec99215..ca8cb326 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -22,17 +22,17 @@
 if IPV6
 
 config IPV6_PRIVACY
-	bool "IPv6: Privacy Extensions support"
+	bool "IPv6: Privacy Extensions (RFC 3041) support"
 	---help---
 	  Privacy Extensions for Stateless Address Autoconfiguration in IPv6
-	  support.  With this option, additional periodically-alter 
-	  pseudo-random global-scope unicast address(es) will assigned to
+	  support.  With this option, additional periodically-altered
+	  pseudo-random global-scope unicast address(es) will be assigned to
 	  your interface(s).
 	
-	  We use our standard pseudo random algorithm to generate randomized
-	  interface identifier, instead of one described in RFC 3041.
+	  We use our standard pseudo-random algorithm to generate the
+          randomized interface identifier, instead of one described in RFC 3041.
 
-	  By default, kernel do not generate temporary addresses.
+	  By default the kernel does not generate temporary addresses.
 	  To use temporary addresses, do
 	
 	        echo 2 >/proc/sys/net/ipv6/conf/all/use_tempaddr 
@@ -43,9 +43,9 @@
 	bool "IPv6: Router Preference (RFC 4191) support"
 	---help---
 	  Router Preference is an optional extension to the Router
-	  Advertisement message to improve the ability of hosts
-	  to pick more appropriate router, especially when the hosts
-	  is placed in a multi-homed network.
+	  Advertisement message which improves the ability of hosts
+	  to pick an appropriate router, especially when the hosts
+	  are placed in a multi-homed network.
 
 	  If unsure, say N.
 
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index 60c1616..f3d9ae3 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -33,7 +33,7 @@
 	---help---
 	  This option selects the default rate control algorithm
 	  mac80211 will use. Note that this default can still be
-	  overriden through the ieee80211_default_rc_algo module
+	  overridden through the ieee80211_default_rc_algo module
 	  parameter if different algorithms are available.
 
 config MAC80211_RC_DEFAULT_PID
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 2c967e4..bb279bf 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -52,7 +52,7 @@
 
 	  Please note that currently this option only sets a default state.
 	  You may change it at boot time with nf_conntrack.acct=0/1 kernel
-	  paramater or by loading the nf_conntrack module with acct=0/1.
+	  parameter or by loading the nf_conntrack module with acct=0/1.
 
 	  You may also disable/enable it on a running system with:
 	   sysctl net.netfilter.nf_conntrack_acct=0/1
diff --git a/net/phonet/Kconfig b/net/phonet/Kconfig
index 51a5669..6ec7d55 100644
--- a/net/phonet/Kconfig
+++ b/net/phonet/Kconfig
@@ -6,7 +6,7 @@
 	tristate "Phonet protocols family"
 	help
 	  The Phone Network protocol (PhoNet) is a packet-oriented
-	  communication protocol developped by Nokia for use with its modems.
+	  communication protocol developed by Nokia for use with its modems.
 
 	  This is required for Maemo to use cellular data connectivity (if
 	  supported). It can also be used to control Nokia phones
diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig
index afd91c7..443c161 100644
--- a/net/sunrpc/Kconfig
+++ b/net/sunrpc/Kconfig
@@ -47,7 +47,7 @@
 	select CRYPTO_CBC
 	help
 	  Choose Y here to enable Secure RPC using the SPKM3 public key
-	  GSS-API mechansim (RFC 2025).
+	  GSS-API mechanism (RFC 2025).
 
 	  Secure RPC calls with SPKM3 require an auxiliary userspace
 	  daemon which may be found in the Linux nfs-utils package
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 9f2f241..9b49a6ab 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -317,8 +317,7 @@
 	}
 	case SVC_POOL_PERNODE:
 	{
-		node_to_cpumask_ptr(nodecpumask, node);
-		set_cpus_allowed_ptr(task, nodecpumask);
+		set_cpus_allowed_ptr(task, cpumask_of_node(node));
 		break;
 	}
 	}
diff --git a/net/wimax/Kconfig b/net/wimax/Kconfig
index 18495cd..1b46747 100644
--- a/net/wimax/Kconfig
+++ b/net/wimax/Kconfig
@@ -8,7 +8,7 @@
 #
 # As well, enablement of the RFKILL code means we need the INPUT layer
 # support to inject events coming from hw rfkill switches. That
-# dependency could be killed if input.h provided appropiate means to
+# dependency could be killed if input.h provided appropriate means to
 # work when input is disabled.
 
 comment "WiMAX Wireless Broadband support requires CONFIG_INPUT enabled"
diff --git a/samples/tracepoints/tp-samples-trace.h b/samples/tracepoints/tp-samples-trace.h
index 01724e0..dffdc49 100644
--- a/samples/tracepoints/tp-samples-trace.h
+++ b/samples/tracepoints/tp-samples-trace.h
@@ -5,9 +5,9 @@
 #include <linux/tracepoint.h>
 
 DECLARE_TRACE(subsys_event,
-	TPPROTO(struct inode *inode, struct file *file),
-	TPARGS(inode, file));
+	TP_PROTO(struct inode *inode, struct file *file),
+	TP_ARGS(inode, file));
 DECLARE_TRACE(subsys_eventb,
-	TPPROTO(void),
-	TPARGS());
+	TP_PROTO(void),
+	TP_ARGS());
 #endif
diff --git a/samples/tracepoints/tracepoint-sample.c b/samples/tracepoints/tracepoint-sample.c
index 68d5dc0..9cf80a1 100644
--- a/samples/tracepoints/tracepoint-sample.c
+++ b/samples/tracepoints/tracepoint-sample.c
@@ -1,6 +1,6 @@
 /* tracepoint-sample.c
  *
- * Executes a tracepoint when /proc/tracepoint-example is opened.
+ * Executes a tracepoint when /proc/tracepoint-sample is opened.
  *
  * (C) Copyright 2007 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
  *
@@ -16,7 +16,7 @@
 DEFINE_TRACE(subsys_event);
 DEFINE_TRACE(subsys_eventb);
 
-struct proc_dir_entry *pentry_example;
+struct proc_dir_entry *pentry_sample;
 
 static int my_open(struct inode *inode, struct file *file)
 {
@@ -32,25 +32,25 @@
 	.open = my_open,
 };
 
-static int __init example_init(void)
+static int __init sample_init(void)
 {
-	printk(KERN_ALERT "example init\n");
-	pentry_example = proc_create("tracepoint-example", 0444, NULL,
+	printk(KERN_ALERT "sample init\n");
+	pentry_sample = proc_create("tracepoint-sample", 0444, NULL,
 		&mark_ops);
-	if (!pentry_example)
+	if (!pentry_sample)
 		return -EPERM;
 	return 0;
 }
 
-static void __exit example_exit(void)
+static void __exit sample_exit(void)
 {
-	printk(KERN_ALERT "example exit\n");
-	remove_proc_entry("tracepoint-example", NULL);
+	printk(KERN_ALERT "sample exit\n");
+	remove_proc_entry("tracepoint-sample", NULL);
 }
 
-module_init(example_init)
-module_exit(example_exit)
+module_init(sample_init)
+module_exit(sample_exit)
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Mathieu Desnoyers");
-MODULE_DESCRIPTION("Tracepoint example");
+MODULE_DESCRIPTION("Tracepoint sample");
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index c7de8b3..39a9642 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -112,13 +112,13 @@
 # ---------------------------------------------------------------------------
 
 # Default is built-in, unless we know otherwise
-modkern_cflags := $(CFLAGS_KERNEL)
+modkern_cflags = $(if $(part-of-module), $(CFLAGS_MODULE), $(CFLAGS_KERNEL))
 quiet_modtag := $(empty)   $(empty)
 
-$(real-objs-m)        : modkern_cflags := $(CFLAGS_MODULE)
-$(real-objs-m:.o=.i)  : modkern_cflags := $(CFLAGS_MODULE)
-$(real-objs-m:.o=.s)  : modkern_cflags := $(CFLAGS_MODULE)
-$(real-objs-m:.o=.lst): modkern_cflags := $(CFLAGS_MODULE)
+$(real-objs-m)        : part-of-module := y
+$(real-objs-m:.o=.i)  : part-of-module := y
+$(real-objs-m:.o=.s)  : part-of-module := y
+$(real-objs-m:.o=.lst): part-of-module := y
 
 $(real-objs-m)        : quiet_modtag := [M]
 $(real-objs-m:.o=.i)  : quiet_modtag := [M]
@@ -205,7 +205,8 @@
 ifdef CONFIG_FTRACE_MCOUNT_RECORD
 cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \
 	"$(if $(CONFIG_64BIT),64,32)" \
-	"$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" "$(MV)" "$(@)";
+	"$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" "$(MV)" \
+	"$(if $(part-of-module),1,0)" "$(@)";
 endif
 
 define rule_cc_o_c
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
index ad2434b..6654cbed 100644
--- a/scripts/kallsyms.c
+++ b/scripts/kallsyms.c
@@ -500,6 +500,51 @@
 	optimize_result();
 }
 
+/* guess for "linker script provide" symbol */
+static int may_be_linker_script_provide_symbol(const struct sym_entry *se)
+{
+	const char *symbol = (char *)se->sym + 1;
+	int len = se->len - 1;
+
+	if (len < 8)
+		return 0;
+
+	if (symbol[0] != '_' || symbol[1] != '_')
+		return 0;
+
+	/* __start_XXXXX */
+	if (!memcmp(symbol + 2, "start_", 6))
+		return 1;
+
+	/* __stop_XXXXX */
+	if (!memcmp(symbol + 2, "stop_", 5))
+		return 1;
+
+	/* __end_XXXXX */
+	if (!memcmp(symbol + 2, "end_", 4))
+		return 1;
+
+	/* __XXXXX_start */
+	if (!memcmp(symbol + len - 6, "_start", 6))
+		return 1;
+
+	/* __XXXXX_end */
+	if (!memcmp(symbol + len - 4, "_end", 4))
+		return 1;
+
+	return 0;
+}
+
+static int prefix_underscores_count(const char *str)
+{
+	const char *tail = str;
+
+	while (*tail != '_')
+		tail++;
+
+	return tail - str;
+}
+
 static int compare_symbols(const void *a, const void *b)
 {
 	const struct sym_entry *sa;
@@ -521,6 +566,18 @@
 	if (wa != wb)
 		return wa - wb;
 
+	/* sort by "linker script provide" type */
+	wa = may_be_linker_script_provide_symbol(sa);
+	wb = may_be_linker_script_provide_symbol(sb);
+	if (wa != wb)
+		return wa - wb;
+
+	/* sort by the number of prefix underscores */
+	wa = prefix_underscores_count((const char *)sa->sym + 1);
+	wb = prefix_underscores_count((const char *)sb->sym + 1);
+	if (wa != wb)
+		return wa - wb;
+
 	/* sort by initial order, so that other symbols are left undisturbed */
 	return sa->start_pos - sb->start_pos;
 }
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 7e62303..8cc7061 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -1607,12 +1607,12 @@
 
 	parse_elf_finish(&info);
 
-	/* Our trick to get versioning for struct_module - it's
+	/* Our trick to get versioning for module struct etc. - it's
 	 * never passed as an argument to an exported function, so
 	 * the automatic versioning doesn't pick it up, but it's really
 	 * important anyhow */
 	if (modversions)
-		mod->unres = alloc_symbol("struct_module", 0, mod->unres);
+		mod->unres = alloc_symbol("module_layout", 0, mod->unres);
 }
 
 #define SZ 500
diff --git a/scripts/package/buildtar b/scripts/package/buildtar
index 28574ae..b1fd48d 100644
--- a/scripts/package/buildtar
+++ b/scripts/package/buildtar
@@ -75,6 +75,10 @@
 	alpha)
 		[ -f "${objtree}/arch/alpha/boot/vmlinux.gz" ] && cp -v -- "${objtree}/arch/alpha/boot/vmlinux.gz" "${tmpdir}/boot/vmlinuz-${KERNELRELEASE}"
 		;;
+	parisc*)
+		[ -f "${KBUILD_IMAGE}" ] && cp -v -- "${KBUILD_IMAGE}" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}"
+		[ -f "${objtree}/lifimage" ] && cp -v -- "${objtree}/lifimage" "${tmpdir}/boot/lifimage-${KERNELRELEASE}"
+		;;
 	vax)
 		[ -f "${objtree}/vmlinux.SYS" ] && cp -v -- "${objtree}/vmlinux.SYS" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}.SYS"
 		[ -f "${objtree}/vmlinux.dsk" ] && cp -v -- "${objtree}/vmlinux.dsk" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}.dsk"
diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl
index fe83141..409596e 100755
--- a/scripts/recordmcount.pl
+++ b/scripts/recordmcount.pl
@@ -100,14 +100,19 @@
 
 my $V = '0.1';
 
-if ($#ARGV < 6) {
-	print "usage: $P arch objdump objcopy cc ld nm rm mv inputfile\n";
+if ($#ARGV < 7) {
+	print "usage: $P arch bits objdump objcopy cc ld nm rm mv is_module inputfile\n";
 	print "version: $V\n";
 	exit(1);
 }
 
 my ($arch, $bits, $objdump, $objcopy, $cc,
-    $ld, $nm, $rm, $mv, $inputfile) = @ARGV;
+    $ld, $nm, $rm, $mv, $is_module, $inputfile) = @ARGV;
+
+# This file refers to mcount and shouldn't be ftraced, so lets' ignore it
+if ($inputfile eq "kernel/trace/ftrace.o") {
+    exit(0);
+}
 
 # Acceptable sections to record.
 my %text_sections = (
@@ -201,6 +206,13 @@
     $alignment = 2;
     $section_type = '%progbits';
 
+} elsif ($arch eq "ia64") {
+    $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$";
+    $type = "data8";
+
+    if ($is_module eq "0") {
+        $cc .= " -mconstant-gp";
+    }
 } else {
     die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD";
 }
@@ -263,7 +275,6 @@
 	"\tDisabling local function references.\n";
 }
 
-
 #
 # Step 1: find all the local (static functions) and weak symbols.
 #        't' is local, 'w/W' is weak (we never use a weak function)
@@ -331,13 +342,16 @@
 #
 # Step 2: find the sections and mcount call sites
 #
-open(IN, "$objdump -dr $inputfile|") || die "error running $objdump";
+open(IN, "$objdump -hdr $inputfile|") || die "error running $objdump";
 
 my $text;
 
+my $read_headers = 1;
+
 while (<IN>) {
     # is it a section?
     if (/$section_regex/) {
+	$read_headers = 0;
 
 	# Only record text sections that we know are safe
 	if (defined($text_sections{$1})) {
@@ -371,6 +385,19 @@
 		$ref_func = $text;
 	    }
 	}
+    } elsif ($read_headers && /$mcount_section/) {
+	#
+	# Somehow the make process can execute this script on an
+	# object twice. If it does, we would duplicate the mcount
+	# section and it will cause the function tracer self test
+	# to fail. Check if the mcount section exists, and if it does,
+	# warn and exit.
+	#
+	print STDERR "ERROR: $mcount_section already in $inputfile\n" .
+	    "\tThis may be an indication that your build is corrupted.\n" .
+	    "\tDelete $inputfile and try again. If the same object file\n" .
+	    "\tstill causes an issue, then disable CONFIG_DYNAMIC_FTRACE.\n";
+	exit(-1);
     }
 
     # is this a call site to mcount? If so, record it to print later
diff --git a/security/security.c b/security/security.c
index 206e538..5284255 100644
--- a/security/security.c
+++ b/security/security.c
@@ -445,6 +445,7 @@
 		return 0;
 	return security_ops->inode_create(dir, dentry, mode);
 }
+EXPORT_SYMBOL_GPL(security_inode_create);
 
 int security_inode_link(struct dentry *old_dentry, struct inode *dir,
 			 struct dentry *new_dentry)
@@ -475,6 +476,7 @@
 		return 0;
 	return security_ops->inode_mkdir(dir, dentry, mode);
 }
+EXPORT_SYMBOL_GPL(security_inode_mkdir);
 
 int security_inode_rmdir(struct inode *dir, struct dentry *dentry)
 {
diff --git a/sound/oss/pss.c b/sound/oss/pss.c
index 16517a5..83f5ee2 100644
--- a/sound/oss/pss.c
+++ b/sound/oss/pss.c
@@ -46,7 +46,7 @@
  *          load the driver as it did in previous versions.
  * 04-07-1999: Anthony Barbachan <barbcode@xmen.cis.fordham.edu>
  *          Added module parameter pss_firmware to allow the user to tell 
- *          the driver where the fireware file is located.  The default 
+ *          the driver where the firmware file is located.  The default 
  *          setting is the previous hardcoded setting "/etc/sound/pss_synth".
  * 00-03-03: Christoph Hellwig <chhellwig@infradead.org>
  *	    Adapted to module_init/module_exit
diff --git a/sound/sh/aica.c b/sound/sh/aica.c
index f551233..583a369 100644
--- a/sound/sh/aica.c
+++ b/sound/sh/aica.c
@@ -565,7 +565,7 @@
 	err = request_firmware(&fw_entry, "aica_firmware.bin", &pd->dev);
 	if (unlikely(err))
 		return err;
-	/* write firware into memory */
+	/* write firmware into memory */
 	spu_disable();
 	spu_memload(0, fw_entry->data, fw_entry->size);
 	spu_enable();
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig
index 0a2f8f9..811596f 100644
--- a/sound/soc/blackfin/Kconfig
+++ b/sound/soc/blackfin/Kconfig
@@ -42,7 +42,7 @@
 	  You will also need to select the audio interfaces to support below.
 
 	  Note:
-	  AC97 codecs which do not implment the slot-16 mode will not function
+	  AC97 codecs which do not implement the slot-16 mode will not function
 	  properly with this driver. This driver is known to work with the
 	  Analog Devices line of AC97 codecs.
 
diff --git a/usr/Kconfig b/usr/Kconfig
index 588c588..1c3039f 100644
--- a/usr/Kconfig
+++ b/usr/Kconfig
@@ -72,10 +72,8 @@
 	  Support loading of a LZMA encoded initial ramdisk or cpio buffer
 	  If unsure, say N.
 
-if INITRAMFS_SOURCE!=""
-
 choice
-	prompt "Built-in initramfs compression mode"
+	prompt "Built-in initramfs compression mode" if INITRAMFS_SOURCE!=""
 	help
 	  This option decides by which algorithm the builtin initramfs
 	  will be compressed.  Several compression algorithms are
@@ -134,14 +132,3 @@
 	  smaller with LZMA in comparison to gzip.
 
 endchoice
-
-endif
-
-if INITRAMFS_SOURCE=""
-# The builtin initramfs is so small so we don't want to bug the user...
-
-config INITRAMFS_COMPRESSION_NONE
-	bool
-	default y
-
-endif
diff --git a/usr/Makefile b/usr/Makefile
index b84894b..245145a 100644
--- a/usr/Makefile
+++ b/usr/Makefile
@@ -6,9 +6,6 @@
 PHONY += klibcdirs
 
 
-# No compression
-suffix_$(CONFIG_INITRAMFS_COMPRESSION_NONE)   =
-
 # Gzip, but no bzip2
 suffix_$(CONFIG_INITRAMFS_COMPRESSION_GZIP)   = .gz